From c181dab9616cf2c191d2c3f72f176ad16262d89f Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Tue, 14 Mar 2023 13:47:14 +0100 Subject: [PATCH 01/34] opam: update tezos/opam-repository --- .gitlab-ci.yml | 2 +- scripts/version.sh | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index aa14c83a099a..5de1902105ca 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -33,7 +33,7 @@ variables: # /!\ CI_REGISTRY is overriden to use a private Docker registry mirror in AWS ECR # in GitLab namespaces `nomadic-labs` and `tezos` ## This value MUST be the same as `opam_repository_tag` in `scripts/version.sh` - build_deps_image_version: 767a4a489c147f066234bc81ed9a4630c09ddcf3 + build_deps_image_version: b1d78cea14e62e7fe9b3d0e627f3946febf3ef3c build_deps_image_name: "${CI_REGISTRY}/tezos/opam-repository" GIT_STRATEGY: fetch GIT_DEPTH: "1" diff --git a/scripts/version.sh b/scripts/version.sh index 2f3bfa6006cf..1c225cb34f76 100755 --- a/scripts/version.sh +++ b/scripts/version.sh @@ -20,12 +20,12 @@ export recommended_node_version=16.18.1 ## full_opam_repository is a commit hash of the public OPAM repository, i.e. ## https://github.com/ocaml/opam-repository -export full_opam_repository_tag=7f0579750a745ea92dc2fe3869d491902e2c29dd +export full_opam_repository_tag=0dd5c4cf106e79883d0e0b23e67240e0c12ed956 ## opam_repository is an additional, tezos-specific opam repository. ## This value MUST be the same as `build_deps_image_version` in `.gitlab-ci.yml` export opam_repository_url=https://gitlab.com/tezos/opam-repository -export opam_repository_tag="${OPAM_REPOSITORY_TAG:-767a4a489c147f066234bc81ed9a4630c09ddcf3}" +export opam_repository_tag="${OPAM_REPOSITORY_TAG:-b1d78cea14e62e7fe9b3d0e627f3946febf3ef3c}" export opam_repository_git="$opam_repository_url.git" export opam_repository="$opam_repository_git"\#"$opam_repository_tag" -- GitLab From 89b7e082e7276f3dd13d689a1052eb0ae2225342 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Tue, 14 Mar 2023 13:58:31 +0100 Subject: [PATCH 02/34] Manifest: bump up bls12-381 to 6.1.0 --- manifest/main.ml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/manifest/main.ml b/manifest/main.ml index ab8288be45db..d8b8a625d887 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -82,7 +82,7 @@ let bigstringaf = let bisect_ppx = opam_only "bisect_ppx" V.(at_least "2.7.0") let bls12_381 = - let version = V.(at_least "6.0.1" && less_than "6.1.0") in + let version = V.(at_least "6.1.0" && less_than "6.2.0") in external_lib ~js_compatible:true ~npm_deps:[Npm.make "@nomadic-labs/ocaml-bls12-381" version] -- GitLab From 799b1f8ff126de98438e92c5b936a8592fd2700e Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 16 Mar 2023 17:12:39 +0100 Subject: [PATCH 03/34] package-lock.json: update with latest bls12-381 version constraint --- package-lock.json | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index b06373e0e1cd..553c376e9f1d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,15 +6,15 @@ "": { "license": "n/a", "dependencies": { - "@nomadic-labs/ocaml-bls12-381": ">=6.0.1 <6.1.0", + "@nomadic-labs/ocaml-bls12-381": ">=6.1.0 <6.2.0", "@nomadic-labs/secp256k1-wasm": ">=0.4.0", "hacl-wasm": ">=1.2.0 <1.3.0" } }, "node_modules/@nomadic-labs/ocaml-bls12-381": { - "version": "6.0.1", - "resolved": "https://gitlab.com/api/v4/projects/39407453/packages/npm/@nomadic-labs/ocaml-bls12-381/-/@nomadic-labs/ocaml-bls12-381-6.0.1.tgz", - "integrity": "sha1-/oiuThq7E/GAhIWUP9amZBiBRv0=" + "version": "6.1.0", + "resolved": "https://gitlab.com/api/v4/projects/39407453/packages/npm/@nomadic-labs/ocaml-bls12-381/-/@nomadic-labs/ocaml-bls12-381-6.1.0.tgz", + "integrity": "sha1-XtQzkRjvDFxnjaCPSaFtC1jkOeA=" }, "node_modules/@nomadic-labs/secp256k1-wasm": { "version": "0.4.0", @@ -29,9 +29,9 @@ }, "dependencies": { "@nomadic-labs/ocaml-bls12-381": { - "version": "6.0.1", - "resolved": "https://gitlab.com/api/v4/projects/39407453/packages/npm/@nomadic-labs/ocaml-bls12-381/-/@nomadic-labs/ocaml-bls12-381-6.0.1.tgz", - "integrity": "sha1-/oiuThq7E/GAhIWUP9amZBiBRv0=" + "version": "6.1.0", + "resolved": "https://gitlab.com/api/v4/projects/39407453/packages/npm/@nomadic-labs/ocaml-bls12-381/-/@nomadic-labs/ocaml-bls12-381-6.1.0.tgz", + "integrity": "sha1-XtQzkRjvDFxnjaCPSaFtC1jkOeA=" }, "@nomadic-labs/secp256k1-wasm": { "version": "0.4.0", -- GitLab From fbf1e918297ee86271adc201b6a6a0fb79464c3c Mon Sep 17 00:00:00 2001 From: Victor Dumitrescu Date: Tue, 7 Mar 2023 18:08:28 +0100 Subject: [PATCH 04/34] Lib_bls12_381_hash: move from cryptography/ocaml-bls12-381-hash --- .gitlab/ci/jobs/packaging/opam_package.yml | 7 + dune-project | 1 + manifest/main.ml | 37 + opam/octez-bls12-381-hash.opam | 22 + src/lib_bls12_381_hash/anemoi.c | 755 ++++++++++ src/lib_bls12_381_hash/anemoi.h | 49 + src/lib_bls12_381_hash/anemoi.ml | 255 ++++ src/lib_bls12_381_hash/bls12_381_hash.ml | 13 + src/lib_bls12_381_hash/bls12_381_hash.mli | 238 +++ src/lib_bls12_381_hash/caml_anemoi_stubs.c | 177 +++ src/lib_bls12_381_hash/caml_griffin_stubs.c | 130 ++ src/lib_bls12_381_hash/caml_poseidon_stubs.c | 146 ++ src/lib_bls12_381_hash/caml_rescue_stubs.c | 124 ++ src/lib_bls12_381_hash/dune | 22 + src/lib_bls12_381_hash/griffin.c | 597 ++++++++ src/lib_bls12_381_hash/griffin.h | 49 + src/lib_bls12_381_hash/griffin.ml | 272 ++++ src/lib_bls12_381_hash/jive.ml | 26 + src/lib_bls12_381_hash/poseidon.c | 167 +++ src/lib_bls12_381_hash/poseidon.h | 30 + src/lib_bls12_381_hash/poseidon.ml | 1358 ++++++++++++++++++ src/lib_bls12_381_hash/poseidon_utils.ml | 473 ++++++ src/lib_bls12_381_hash/rescue.c | 451 ++++++ src/lib_bls12_381_hash/rescue.h | 26 + src/lib_bls12_381_hash/rescue.ml | 181 +++ src/lib_bls12_381_hash/s.ml | 33 + src/lib_bls12_381_hash/sponge.ml | 0 src/lib_bls12_381_hash/test/dune | 37 + src/lib_bls12_381_hash/test/test_anemoi.ml | 564 ++++++++ src/lib_bls12_381_hash/test/test_griffin.ml | 171 +++ src/lib_bls12_381_hash/test/test_jive.ml | 164 +++ src/lib_bls12_381_hash/test/test_poseidon.ml | 238 +++ src/lib_bls12_381_hash/test/test_rescue.ml | 103 ++ 33 files changed, 6916 insertions(+) create mode 100644 opam/octez-bls12-381-hash.opam create mode 100644 src/lib_bls12_381_hash/anemoi.c create mode 100644 src/lib_bls12_381_hash/anemoi.h create mode 100644 src/lib_bls12_381_hash/anemoi.ml create mode 100644 src/lib_bls12_381_hash/bls12_381_hash.ml create mode 100644 src/lib_bls12_381_hash/bls12_381_hash.mli create mode 100644 src/lib_bls12_381_hash/caml_anemoi_stubs.c create mode 100644 src/lib_bls12_381_hash/caml_griffin_stubs.c create mode 100644 src/lib_bls12_381_hash/caml_poseidon_stubs.c create mode 100644 src/lib_bls12_381_hash/caml_rescue_stubs.c create mode 100644 src/lib_bls12_381_hash/dune create mode 100644 src/lib_bls12_381_hash/griffin.c create mode 100644 src/lib_bls12_381_hash/griffin.h create mode 100644 src/lib_bls12_381_hash/griffin.ml create mode 100644 src/lib_bls12_381_hash/jive.ml create mode 100644 src/lib_bls12_381_hash/poseidon.c create mode 100644 src/lib_bls12_381_hash/poseidon.h create mode 100644 src/lib_bls12_381_hash/poseidon.ml create mode 100644 src/lib_bls12_381_hash/poseidon_utils.ml create mode 100644 src/lib_bls12_381_hash/rescue.c create mode 100644 src/lib_bls12_381_hash/rescue.h create mode 100644 src/lib_bls12_381_hash/rescue.ml create mode 100644 src/lib_bls12_381_hash/s.ml create mode 100644 src/lib_bls12_381_hash/sponge.ml create mode 100644 src/lib_bls12_381_hash/test/dune create mode 100644 src/lib_bls12_381_hash/test/test_anemoi.ml create mode 100644 src/lib_bls12_381_hash/test/test_griffin.ml create mode 100644 src/lib_bls12_381_hash/test/test_jive.ml create mode 100644 src/lib_bls12_381_hash/test/test_poseidon.ml create mode 100644 src/lib_bls12_381_hash/test/test_rescue.ml diff --git a/.gitlab/ci/jobs/packaging/opam_package.yml b/.gitlab/ci/jobs/packaging/opam_package.yml index 5db45cf6494c..9c1558572a27 100644 --- a/.gitlab/ci/jobs/packaging/opam_package.yml +++ b/.gitlab/ci/jobs/packaging/opam_package.yml @@ -238,6 +238,13 @@ opam:octez-baker-PtMumbai: # Ignoring unreleased package octez-baker-alpha. +opam:octez-bls12-381-hash: + extends: + - .opam_template + - .rules_template__trigger_opam_batch_7 + variables: + package: octez-bls12-381-hash + opam:octez-client: extends: - .opam_template diff --git a/dune-project b/dune-project index 900301f7f293..f61ee362d396 100644 --- a/dune-project +++ b/dune-project @@ -10,6 +10,7 @@ (package (name octez-baker-PtLimaPt)) (package (name octez-baker-PtMumbai)) (package (name octez-baker-alpha)) +(package (name octez-bls12-381-hash)) (package (name octez-client)) (package (name octez-codec)) (package (name octez-crawler)) diff --git a/manifest/main.ml b/manifest/main.ml index d8b8a625d887..4a2778be215e 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -914,6 +914,43 @@ let _octez_crypto_tests_unix = octez_test_helpers |> open_; ] +let octez_bls12_381_hash = + public_lib + "octez-bls12-381-hash" + ~path:"src/lib_bls12_381_hash" + ~internal_name:"bls12_381_hash" + ~synopsis: + "Implementation of some cryptographic hash primitives using the scalar \ + field of BLS12-381" + ~c_library_flags:["-Wall"; "-Wextra"; ":standard"; "-lpthread"] + ~deps:[bls12_381; bisect_ppx] + ~js_compatible:false + ~foreign_stubs: + { + language = C; + flags = []; + names = + [ + "caml_rescue_stubs"; + "caml_anemoi_stubs"; + "caml_poseidon_stubs"; + "caml_griffin_stubs"; + "rescue"; + "anemoi"; + "poseidon"; + "griffin"; + ]; + } + ~linkall:true + +let _octez_bls12_381_hash_tests = + tests + ["test_poseidon"; "test_rescue"; "test_anemoi"; "test_griffin"; "test_jive"] + ~path:"src/lib_bls12_381_hash/test" + ~opam:"octez-bls12-381-hash" + ~deps:[alcotest; bls12_381; octez_bls12_381_hash] + ~flags:(Flags.standard ~disable_warnings:[3] ()) + let octez_bls12_381_polynomial_internal = public_lib "tezos-bls12-381-polynomial-internal" diff --git a/opam/octez-bls12-381-hash.opam b/opam/octez-bls12-381-hash.opam new file mode 100644 index 000000000000..dd8b63ab8fae --- /dev/null +++ b/opam/octez-bls12-381-hash.opam @@ -0,0 +1,22 @@ +# This file was automatically generated, do not edit. +# Edit file manifest/main.ml instead. +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: ["Tezos devteam"] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "3.0" } + "ocaml" { >= "4.14" } + "bls12-381" { >= "6.0.1" & < "6.1.0" } + "bisect_ppx" { >= "2.7.0" } + "alcotest" { with-test & >= "1.5.0" } +] +build: [ + ["rm" "-r" "vendors"] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Implementation of some cryptographic hash primitives using the scalar field of BLS12-381" diff --git a/src/lib_bls12_381_hash/anemoi.c b/src/lib_bls12_381_hash/anemoi.c new file mode 100644 index 000000000000..830f86c75016 --- /dev/null +++ b/src/lib_bls12_381_hash/anemoi.c @@ -0,0 +1,755 @@ +#include "anemoi.h" +#include +#include + +int anemoi_get_state_size_from_context(anemoi_ctxt_t *ctxt) { + // shift by state size + return (2 * ctxt->l); +} + +blst_fr *anemoi_get_state_from_context(anemoi_ctxt_t *ctxt) { + // shift by state size + return (ctxt->ctxt); +} + +blst_fr *anemoi_get_mds_from_context(anemoi_ctxt_t *ctxt) { + // shift by state size + return (ctxt->ctxt + 2 * ctxt->l); +} + +blst_fr *anemoi_get_round_constants_from_context(anemoi_ctxt_t *ctxt) { + // shift by state size and MDS + int state_size = anemoi_get_state_size_from_context(ctxt); + return (ctxt->ctxt + state_size + ctxt->l * ctxt->l); +} + +int anemoi_get_number_of_constants(anemoi_ctxt_t *ctxt) { + return (ctxt->l * ctxt->nb_rounds * 2); +} + +blst_fr *anemoi_get_beta_from_context(anemoi_ctxt_t *ctxt) { + int nb_constants = anemoi_get_number_of_constants(ctxt); + int state_size = anemoi_get_state_size_from_context(ctxt); + return (ctxt->ctxt + state_size + ctxt->l * ctxt->l + nb_constants); +} + +blst_fr *anemoi_get_delta_from_context(anemoi_ctxt_t *ctxt) { + int nb_constants = anemoi_get_number_of_constants(ctxt); + int state_size = anemoi_get_state_size_from_context(ctxt); + return (ctxt->ctxt + state_size + ctxt->l * ctxt->l + nb_constants + 1); +} + +void anemoi_fr_multiply_by_g(blst_fr *res, blst_fr *v) { + blst_fr tmp; + + // Compute g * y and save it in tmp. + // multiply by 7 + // y + y + blst_fr_add(&tmp, v, v); + // 2y + y + blst_fr_add(&tmp, &tmp, v); + // 3y + 3y + blst_fr_add(&tmp, &tmp, &tmp); + // 6y + y + blst_fr_add(res, &tmp, v); +} + +void blst_fr_double(blst_fr *r, blst_fr *x) { blst_fr_add(r, x, x); } + +void anemoi_apply_constants_addition(anemoi_ctxt_t *ctxt, int round) { + blst_fr *state = anemoi_get_state_from_context(ctxt); + blst_fr *state_x = state; + blst_fr *state_y = state + ctxt->l; + blst_fr *constants = anemoi_get_round_constants_from_context(ctxt); + blst_fr *constants_x = constants; + blst_fr *constants_y = constants + ctxt->nb_rounds * ctxt->l; + for (int i = 0; i < ctxt->l; i++) { + blst_fr_add(state_x + i, state_x + i, constants_x + ctxt->l * round + i); + blst_fr_add(state_y + i, state_y + i, constants_y + ctxt->l * round + i); + } +} + +void anemoi_apply_shift_state(anemoi_ctxt_t *ctxt) { + blst_fr *state = anemoi_get_state_from_context(ctxt); + blst_fr *state_y = state + ctxt->l; + blst_fr tmp; + + memcpy(&tmp, state_y, sizeof(blst_fr)); + // And we apply the rotation + // y_(i) <- y_(i + 1) + for (int i = 0; i < ctxt->l - 1; i++) { + memcpy(state_y + i, state_y + i + 1, sizeof(blst_fr)); + } + // Put y_0 into y_(l - 1) + memcpy(state_y + ctxt->l - 1, &tmp, sizeof(blst_fr)); +} + +void anemoi_1_apply_linear_layer(anemoi_ctxt_t *ctxt) { + blst_fr tmp; + blst_fr *state = anemoi_get_state_from_context(ctxt); + + // Compute "g * y' and save it in tmp. + anemoi_fr_multiply_by_g(&tmp, state + 1); + // x += g * y. Inplace operation + blst_fr_add(state, state, &tmp); + + // Compute "g * x' and save it in tmp. + anemoi_fr_multiply_by_g(&tmp, state); + + blst_fr_add(state + 1, state + 1, &tmp); +} + +void anemoi_2_apply_linear_layer(anemoi_ctxt_t *ctxt) { + blst_fr *state_x = anemoi_get_state_from_context(ctxt); + blst_fr *state_y = state_x + ctxt->l; + blst_fr tmp; + + // Apply M_x + // Compute "g * y' and save it in tmp. + anemoi_fr_multiply_by_g(&tmp, state_x + 1); + // x += g * y. Inplace operation + blst_fr_add(state_x, state_x, &tmp); + + // Compute "g * x' and save it in tmp. + anemoi_fr_multiply_by_g(&tmp, state_x); + + blst_fr_add(state_x + 1, state_x + 1, &tmp); + + // swap y_1 et y_0 for linear layer + memcpy(&tmp, state_y, sizeof(blst_fr)); + memcpy(state_y, state_y + 1, sizeof(blst_fr)); + memcpy(state_y + 1, &tmp, sizeof(blst_fr)); + + // Apply M_y + // Compute "g * y' and save it in tmp. + anemoi_fr_multiply_by_g(&tmp, state_y + 1); + // x += g * y. Inplace operation + blst_fr_add(state_y, state_y, &tmp); + + // Compute "g * x' and save it in tmp. + anemoi_fr_multiply_by_g(&tmp, state_y); + + blst_fr_add(state_y + 1, state_y + 1, &tmp); +} + +// l = 3 +void anemoi_3_apply_matrix(blst_fr *ctxt) { + blst_fr tmp; + blst_fr g_x0; + + // t = x[0] + g * x[2] + anemoi_fr_multiply_by_g(&tmp, ctxt + 2); + blst_fr_add(&tmp, &tmp, ctxt); + + // x[2] += x[1] + blst_fr_add(ctxt + 2, ctxt + 2, ctxt + 1); + // x[2] += b * x[0] + anemoi_fr_multiply_by_g(&g_x0, ctxt); + blst_fr_add(ctxt + 2, ctxt + 2, &g_x0); + + // x[0] = t + x[2] + blst_fr_add(ctxt, ctxt + 2, &tmp); + // x[1] += t + blst_fr_add(ctxt + 1, ctxt + 1, &tmp); +} + +void anemoi_3_apply_linear_layer(anemoi_ctxt_t *ctxt) { + blst_fr *state = anemoi_get_state_from_context(ctxt); + blst_fr *state_x = state; + blst_fr *state_y = state_x + ctxt->l; + + anemoi_3_apply_matrix(state_x); + anemoi_apply_shift_state(ctxt); + anemoi_3_apply_matrix(state_y); +} + +// l = 4 +void anemoi_4_apply_matrix(blst_fr *ctxt) { + blst_fr tmp; + + // x[0] += x[1] + blst_fr_add(ctxt, ctxt, ctxt + 1); + // x[2] += x[3] + blst_fr_add(ctxt + 2, ctxt + 2, ctxt + 3); + // x[3] += g x[0] + anemoi_fr_multiply_by_g(&tmp, ctxt); + blst_fr_add(ctxt + 3, ctxt + 3, &tmp); + // x[1] = g * (x[1] + x[2]) + blst_fr_add(&tmp, ctxt + 1, ctxt + 2); + anemoi_fr_multiply_by_g(ctxt + 1, &tmp); + // x[0] += x[1] + blst_fr_add(ctxt, ctxt, ctxt + 1); + // x[2] += g x[3] + anemoi_fr_multiply_by_g(&tmp, ctxt + 3); + blst_fr_add(ctxt + 2, ctxt + 2, &tmp); + // x[1] += x[2] + blst_fr_add(ctxt + 1, ctxt + 1, ctxt + 2); + // x[3] += x[0] + blst_fr_add(ctxt + 3, ctxt + 3, ctxt); +} + +void anemoi_4_apply_linear_layer(anemoi_ctxt_t *ctxt) { + blst_fr *state = anemoi_get_state_from_context(ctxt); + blst_fr *state_x = state; + blst_fr *state_y = state_x + ctxt->l; + + anemoi_4_apply_matrix(state_x); + anemoi_apply_shift_state(ctxt); + anemoi_4_apply_matrix(state_y); +} + +void anemoi_addchain_alpha_inv(blst_fr *res, blst_fr *x) { + // Allocating on the stack 32 bytes * 36 (= 1152 bytes) for intermediary + // variables to compute the addition chain. Less values might be required. + // There is still place for improvements. + // Values are allocated in a contiguous array to hope using the CPU cache. + blst_fr tmp[36]; + // _10 = 2*1 + // -> tmp = x * x + blst_fr_sqr(tmp, x); + // _100 = 2*_10 + // -> tmp1 = tmp * tmp + blst_fr_sqr(tmp + 1, tmp); + // _101 = 1 + _100 + // -> tmp2 = x * tmp1 + blst_fr_mul(tmp + 2, x, tmp + 1); + // _111 = _10 + _101 + // -> tmp3 = tmp * tmp2 + blst_fr_mul(tmp + 3, tmp, tmp + 2); + // _1010 = 2*_101 + // -> tmp4 = tmp2 * tmp2 + blst_fr_sqr(tmp + 4, tmp + 2); + // _1011 = 1 + _1010 + // -> tmp5 = x * tmp4 + blst_fr_mul(tmp + 5, x, tmp + 4); + // _1101 = _10 + _1011 + // -> tmp6 = tmp * tmp5 + blst_fr_mul(tmp + 6, tmp, tmp + 5); + // _1111 = _10 + _1101 + // -> tmp7 = tmp * tmp6 + blst_fr_mul(tmp + 7, tmp, tmp + 6); + // _10001 = _10 + _1111 + // -> tmp8 = tmp * tmp7 + blst_fr_mul(tmp + 8, tmp, tmp + 7); + // _10011 = _10 + _10001 + // -> tmp9 = tmp * tmp8 + blst_fr_mul(tmp + 9, tmp, tmp + 8); + // _10111 = _100 + _10011 + // -> tmp10 = tmp1 * tmp9 + blst_fr_mul(tmp + 10, tmp + 1, tmp + 9); + // _100001 = _1010 + _10111 + // -> tmp11 = tmp4 * tmp10 + blst_fr_mul(tmp + 11, tmp + 4, tmp + 10); + // _100011 = _10 + _100001 + // -> tmp12 = tmp * tmp11 + blst_fr_mul(tmp + 12, tmp, tmp + 11); + // _100101 = _10 + _100011 + // -> tmp13 = tmp * tmp12 + blst_fr_mul(tmp + 13, tmp, tmp + 12); + // _100111 = _10 + _100101 + // -> tmp14 = tmp * tmp13 + blst_fr_mul(tmp + 14, tmp, tmp + 13); + // _101011 = _100 + _100111 + // -> tmp15 = tmp1 * tmp14 + blst_fr_mul(tmp + 15, tmp + 1, tmp + 14); + // _101111 = _100 + _101011 + // -> tmp16 = tmp1 * tmp15 + blst_fr_mul(tmp + 16, tmp + 1, tmp + 15); + // _110011 = _100 + _101111 + // -> tmp17 = tmp1 * tmp16 + blst_fr_mul(tmp + 17, tmp + 1, tmp + 16); + // _110101 = _10 + _110011 + // -> tmp18 = tmp * tmp17 + blst_fr_mul(tmp + 18, tmp, tmp + 17); + // _111001 = _100 + _110101 + // -> tmp19 = tmp1 * tmp18 + blst_fr_mul(tmp + 19, tmp + 1, tmp + 18); + // _111101 = _100 + _111001 + // -> tmp20 = tmp1 * tmp19 + blst_fr_mul(tmp + 20, tmp + 1, tmp + 19); + // _1011100 = _100011 + _111001 + // -> tmp21 = tmp12 * tmp19 + blst_fr_mul(tmp + 21, tmp + 12, tmp + 19); + // i42 = ((_1011100 << 6 + _101111) << 6 + _100001) << 6 + // -> _1011100 << 6 + // tmp22 = tmp21^(2^6) + memcpy(tmp + 22, tmp + 21, sizeof(blst_fr)); + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 22, tmp + 22); + } + // -> (_1011100 << 6 + _101111 + // tmp22 = tmp21^(2^6) * tmp16 + // = tmp22 * tmp16 + blst_fr_mul(tmp + 22, tmp + 22, tmp + 16); + // -> (_1011100 << 6 + _101111) << 6 + // tmp22 = (tmp21^(2^6) * tmp16)^(2^6) + // = tmp22^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 22, tmp + 22); + } + // -> ((_1011100 << 6 + _101111) << 6 + _100001) + // tmp22 = ((tmp21^(2^6) * tmp16)^(2^6)) * tmp11 + // = tmp22 * tmp11 + blst_fr_mul(tmp + 22, tmp + 22, tmp + 11); + // -> ((_1011100 << 6 + _101111) << 6 + _100001) << 6 + // tmp22 = (((tmp21^(2^6) * tmp16)^(2^6)) * tmp11)^(2^6) + // = tmp22^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 22, tmp + 22); + } + // i56 = ((_111101 + i42) << 6 + _110101) << 5 + _10111 + // -> (_111101 + i42) + // tmp23 = tmp20 * tmp22 + blst_fr_mul(tmp + 23, tmp + 22, tmp + 20); + // -> (_111101 + i42) << 6 + // tmp23 = (tmp20 * tmp22)^(2^6) + // = tmp22^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 23, tmp + 23); + } + // -> ((_111101 + i42) << 6 + _110101) + // tmp23 = tmp22 * tmp18 + blst_fr_mul(tmp + 23, tmp + 23, tmp + 18); + // -> ((_111101 + i42) << 6 + _110101) << 5 + // tmp23 = tmp22^(2^5) + for (int i = 0; i < 5; i++) { + blst_fr_sqr(tmp + 23, tmp + 23); + } + // -> ((_111101 + i42) << 6 + _110101) << 5 + _10111 + // tmp23 = tmp22 * tmp10 + blst_fr_mul(tmp + 23, tmp + 10, tmp + 23); + // tmp + 24 + // i80 = ((i56 << 6 + _10111) << 8 + _100011) << 8 + memcpy(tmp + 24, tmp + 23, sizeof(blst_fr)); + // -> i56 << 6 + // tmp24 = tmp23^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 24, tmp + 24); + } + // -> (i56 << 6 + _10111) + // tmp24 = tmp24 * tmp10 + blst_fr_mul(tmp + 24, tmp + 24, tmp + 10); + // -> (i56 << 6 + _10111) << 8 + // tmp24 = tmp24^(2^8) + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 24, tmp + 24); + } + // -> (i56 << 6 + _10111) << 8 + _100011 + // tmp24 = tmp24 * tmp12 + blst_fr_mul(tmp + 24, tmp + 24, tmp + 12); + // -> ((i56 << 6 + _10111) << 8 + _100011) << 8 + // tmp24 = tmp24^(2^8) + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 24, tmp + 24); + } + // tmp + 25 + // i95 = ((_100001 + i80) << 6 + _110011) << 6 + _100001 + // -> (_100001 + i80) + // tmp25 = tmp24 * tmp11 + blst_fr_mul(tmp + 25, tmp + 11, tmp + 24); + // -> (_100001 + i80) << 6 + // tmp25 = tmp25^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 25, tmp + 25); + } + // -> (_100001 + i80) << 6 + _110011 + // tmp25 = tmp25 * tmp17 + blst_fr_mul(tmp + 25, tmp + 17, tmp + 25); + // -> ((_100001 + i80) << 6 + _110011) << 6 + // tmp25 = tmp25^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 25, tmp + 25); + } + // -> ((_100001 + i80) << 6 + _110011) << 6 + _100001 + // tmp25 = tmp25 * tmp11 + blst_fr_mul(tmp + 25, tmp + 25, tmp + 11); + // i118 = ((i95 << 7 + _100101) << 8 + _101011) << 6 + // -> i95 << 7 + // tmp26 = tmp25^(2^7) + memcpy(tmp + 26, tmp + 25, sizeof(blst_fr)); + for (int i = 0; i < 7; i++) { + blst_fr_sqr(tmp + 26, tmp + 26); + } + // -> (i95 << 7 + _100101) + // tmp26 = tmp26 * tmp13 + blst_fr_mul(tmp + 26, tmp + 26, tmp + 13); + // -> (i95 << 7 + _100101) << 8 + // tmp26 = tmp26^(2^8) + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 26, tmp + 26); + } + // -> ((i95 << 7 + _100101) << 8 + _101011) + // tmp26 = tmp26 * tmp15 + blst_fr_mul(tmp + 26, tmp + 26, tmp + 15); + // -> ((i95 << 7 + _100101) << 8 + _101011) << 6 + // tmp26 = tmp26^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 26, tmp + 26); + } + // tmp + 27 + // i135 = ((_1101 + i118) << 8 + _110011) << 6 + _101011 + // -> _1101 + i118 + // tmp27 = tmp26 * tmp6 + blst_fr_mul(tmp + 27, tmp + 26, tmp + 6); + // -> (_1101 + i118) << 8 + // tmp27 = tmp27^(2^8) + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 27, tmp + 27); + } + // -> (_1101 + i118) << 8 + _110011 + // tmp27 = tmp27 * tmp17 + blst_fr_mul(tmp + 27, tmp + 27, tmp + 17); + // -> ((_1101 + i118) << 8 + _110011) << 6 + // tmp27 = tmp27^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 27, tmp + 27); + } + // -> ((_1101 + i118) << 8 + _110011) << 6 + _101011 + // tmp27 = tmp27 * tmp15 + blst_fr_mul(tmp + 27, tmp + 27, tmp + 15); + // tmp + 28 + // i161 = ((i135 << 6 + _100111) << 3 + _111) << 15 + // tmp28 = tmp27^(2^6) + memcpy(tmp + 28, tmp + 27, sizeof(blst_fr)); + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 28, tmp + 28); + } + // -> (i135 << 6 + _100111) + // tmp28 = tmp28 * tmp14 + blst_fr_mul(tmp + 28, tmp + 28, tmp + 14); + // -> (i135 << 6 + _100111) << 3 + // tmp28 = tmp28^(2^3) + for (int i = 0; i < 3; i++) { + blst_fr_sqr(tmp + 28, tmp + 28); + } + // -> ((i135 << 6 + _100111) << 3 + _111) + // tmp28 = tmp28 * tmp3 + blst_fr_mul(tmp + 28, tmp + 28, tmp + 3); + // -> ((i135 << 6 + _100111) << 3 + _111) << 15 + // tmp28 = tmp28^(2^15) + for (int i = 0; i < 15; i++) { + blst_fr_sqr(tmp + 28, tmp + 28); + } + // tmp + 29 + // i176 = ((_10001 + i161) << 5 + 1) << 7 + _111101 + // -> _10001 + i161 + // tmp29 = tmp8 * tmp28 + blst_fr_mul(tmp + 29, tmp + 8, tmp + 28); + // -> (_10001 + i161) << 5 + // tmp29 = tmp29^(2^5) + for (int i = 0; i < 5; i++) { + blst_fr_sqr(tmp + 29, tmp + 29); + } + // tmp29 = tmp29 * x + // -> ((_10001 + i161) << 5 + 1) + blst_fr_mul(tmp + 29, tmp + 29, x); + // tmp29 = tmp29^(2^7) + // -> ((_10001 + i161) << 5 + 1) << 7 + for (int i = 0; i < 7; i++) { + blst_fr_sqr(tmp + 29, tmp + 29); + } + // -> ((_10001 + i161) << 5 + 1) << 7 + _111101 + // tmp29 = tmp29 * tmp20 + blst_fr_mul(tmp + 29, tmp + 29, tmp + 20); + // i195 = ((2*i176 + _101) << 10 + _111001) << 6 + // -> 2*i176 + // tmp30 = tmp29^2 + blst_fr_sqr(tmp + 30, tmp + 29); + // -> (2*i176 + _101) + // tmp30 = tmp30 * tmp2 + blst_fr_mul(tmp + 30, tmp + 30, tmp + 2); + // -> (2*i176 + _101) << 10 + for (int i = 0; i < 10; i++) { + blst_fr_sqr(tmp + 30, tmp + 30); + } + // -> ((2*i176 + _101) << 10 + _111001) + blst_fr_mul(tmp + 30, tmp + 30, tmp + 19); + // -> ((2*i176 + _101) << 10 + _111001) << 6 + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 30, tmp + 30); + } + // i211 = ((_100111 + i195) << 5 + _10011) << 8 + _110011 + blst_fr_mul(tmp + 31, tmp + 30, tmp + 14); + // (_100111 + i195) << 5 + for (int i = 0; i < 5; i++) { + blst_fr_sqr(tmp + 31, tmp + 31); + } + // -> ((_100111 + i195) << 5 + _10011) + blst_fr_mul(tmp + 31, tmp + 31, tmp + 9); + // -> ((_100111 + i195) << 5 + _10011) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 31, tmp + 31); + } + // -> ((_100111 + i195) << 5 + _10011) << 8 + _110011 + blst_fr_mul(tmp + 31, tmp + 31, tmp + 17); + // tmp + 32 + // i236 = ((i211 << 7 + _1111) << 9 + _110011) << 7 + memcpy(tmp + 32, tmp + 31, sizeof(blst_fr)); + // -> i211 << 7 + for (int i = 0; i < 7; i++) { + blst_fr_sqr(tmp + 32, tmp + 32); + } + // -> (i211 << 7 + _1111) + blst_fr_mul(tmp + 32, tmp + 32, tmp + 7); + // -> (i211 << 7 + _1111) << 9 + for (int i = 0; i < 9; i++) { + blst_fr_sqr(tmp + 32, tmp + 32); + } + // -> ((i211 << 7 + _1111) << 9 + _110011) + blst_fr_mul(tmp + 32, tmp + 32, tmp + 17); + // -> ((i211 << 7 + _1111) << 9 + _110011) << 7 + for (int i = 0; i < 7; i++) { + blst_fr_sqr(tmp + 32, tmp + 32); + } + // tmp + 33 + // i255 = ((_10011 + i236) << 8 + _110011) << 8 + _110011 + // -> (_10011 + i236) + blst_fr_mul(tmp + 33, tmp + 32, tmp + 9); + // -> (_10011 + i236) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 33, tmp + 33); + } + // -> ((_10011 + i236) << 8 + _110011) + blst_fr_mul(tmp + 33, tmp + 33, tmp + 17); + // -> ((_10011 + i236) << 8 + _110011) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 33, tmp + 33); + } + // -> ((_10011 + i236) << 8 + _110011) << 8 + _110011 + blst_fr_mul(tmp + 33, tmp + 33, tmp + 17); + // tmp + 34 + // i279 = ((i255 << 8 + _110011) << 6 + _1011) << 8 + memcpy(tmp + 34, tmp + 33, sizeof(blst_fr)); + // -> i255 << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 34, tmp + 34); + } + // -> (i255 << 8 + _110011) + blst_fr_mul(tmp + 34, tmp + 34, tmp + 17); + // -> ((i255 << 8 + _110011) << 6 + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 34, tmp + 34); + } + // -> ((i255 << 8 + _110011) << 6 + _1011) + blst_fr_mul(tmp + 34, tmp + 34, tmp + 5); + // -> ((i255 << 8 + _110011) << 6 + _1011) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 34, tmp + 34); + } + // tmp + 35 + // i298 = ((_110011 + i279) << 8 + _110011) << 8 + _110011 + // -> _110011 + i279 + blst_fr_mul(tmp + 35, tmp + 17, tmp + 34); + + // -> (_110011 + i279) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 35, tmp + 35); + } + // -> ((_110011 + i279) << 8 + _110011) + blst_fr_mul(tmp + 35, tmp + 17, tmp + 35); + // -> ((_110011 + i279) << 8 + _110011) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 35, tmp + 35); + } + // -> ((_110011 + i279) << 8 + _110011) << 8 + _110011 + blst_fr_mul(tmp + 35, tmp + 17, tmp + 35); + // return i298 << 6 + _1101 + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 35, tmp + 35); + } + // Put in res + blst_fr_mul(res, tmp + 6, tmp + 35); +} + +void anemoi_apply_s_box(blst_fr *x, blst_fr *y, blst_fr *beta, blst_fr *delta) { + blst_fr tmp; + // First we compute x_i = x_i - beta * y^2 = x_i - Q_i(y_i) + // -- compute y^2 + blst_fr_sqr(&tmp, y); + // -- Compute beta * y^2 + blst_fr_mul(&tmp, &tmp, beta); + // -- Compute x = x - beta * y^2 + blst_fr_sub(x, x, &tmp); + // Computing E(x) + // -- Coppute x^alpha_inv and save it in tmp. + // NB: this is the costly operation. + // IMPROVEME: can be improved using addchain. Would be 21% faster (305 ops + // instead of 384). + // > addchain search + // '20974350070050476191779096203274386335076221000211055129041463479975432473805' + // > addition cost: 305 + anemoi_addchain_alpha_inv(&tmp, x); + /* blst_fr_pow(&tmp, ctxt, ALPHA_INV_BYTES, ALPHA_INV_NUMBITS); */ + // -- Compute y_i = y_i - x^(alpha_inv) = y_i - E(x_i) + blst_fr_sub(y, y, &tmp); + // Computing x_i = x_i + (beta * y^2 + delta) = x_i + Q_f(x_i) + // -- compute y^2 + blst_fr_sqr(&tmp, y); + // -- compute beta * y^2 + blst_fr_mul(&tmp, &tmp, beta); + // -- compute beta * y^2 + delta + blst_fr_add(&tmp, &tmp, delta); + // -- compute x + x + beta * y^2 + delta + blst_fr_add(x, x, &tmp); +} + +void anemoi_1_apply_flystel(anemoi_ctxt_t *ctxt) { + blst_fr *beta = anemoi_get_beta_from_context(ctxt); + blst_fr *delta = anemoi_get_delta_from_context(ctxt); + blst_fr *state = anemoi_get_state_from_context(ctxt); + anemoi_apply_s_box(state, state + 1, beta, delta); +} + +void anemoi_1_apply(anemoi_ctxt_t *ctxt) { + for (int i = 0; i < ctxt->nb_rounds; i++) { + // add cst + anemoi_apply_constants_addition(ctxt, i); + // apply linear layer + anemoi_1_apply_linear_layer(ctxt); + // apply sbox + anemoi_1_apply_flystel(ctxt); + } + + // Final call to linear layer. See page 15, High Level Algorithms + anemoi_1_apply_linear_layer(ctxt); +} + +void anemoi_generic_apply_flystel(anemoi_ctxt_t *ctxt) { + blst_fr *state = anemoi_get_state_from_context(ctxt); + blst_fr *beta = anemoi_get_beta_from_context(ctxt); + blst_fr *delta = anemoi_get_delta_from_context(ctxt); + for (int i = 0; i < ctxt->l; i++) { + anemoi_apply_s_box(state + i, state + ctxt->l + i, beta, delta); + } +} + +void anemoi_generic_apply_linear_layer(anemoi_ctxt_t *ctxt) { + blst_fr *state = anemoi_get_state_from_context(ctxt); + blst_fr *state_x = state; + blst_fr *state_y = state + ctxt->l; + blst_fr *mds = anemoi_get_mds_from_context(ctxt); + + blst_fr buffer[ctxt->l]; + + blst_fr tmp; + + // Applying matrix multiplication + for (int i = 0; i < ctxt->l; i++) { + memset(buffer + i, 0, sizeof(blst_fr)); + for (int j = 0; j < ctxt->l; j++) { + blst_fr_mul(&tmp, state_x + j, mds + j * ctxt->l + i); + blst_fr_add(buffer + i, buffer + i, &tmp); + } + } + + // Copying the buffer into state + for (int i = 0; i < ctxt->l; i++) { + memcpy(state_x + i, buffer + i, sizeof(blst_fr)); + } + + memcpy(&tmp, state_y, sizeof(blst_fr)); + // And we apply the rotation + // y_(i) <- y_(i + 1) + for (int i = 0; i < ctxt->l - 1; i++) { + memcpy(state_y + i, state_y + i + 1, sizeof(blst_fr)); + } + // Put y_0 into y_(l - 1) + memcpy(state_y + ctxt->l - 1, &tmp, sizeof(blst_fr)); + + // Applying matrix multiplication + for (int i = 0; i < ctxt->l; i++) { + memset(buffer + i, 0, sizeof(blst_fr)); + for (int j = 0; j < ctxt->l; j++) { + blst_fr_mul(&tmp, state_y + j, mds + j * ctxt->l + i); + blst_fr_add(buffer + i, buffer + i, &tmp); + } + } + + // Copying the buffer into state + for (int i = 0; i < ctxt->l; i++) { + memcpy(state_y + i, buffer + i, sizeof(blst_fr)); + } +} + +void anemoi_apply_flystel(anemoi_ctxt_t *ctxt) { + if (ctxt->l == 1) { + anemoi_1_apply_flystel(ctxt); + } else + anemoi_generic_apply_flystel(ctxt); +} + +void anemoi_apply_linear_layer(anemoi_ctxt_t *ctxt) { + if (ctxt->l == 1) { + anemoi_1_apply_linear_layer(ctxt); + } + + else if (ctxt->l == 2) { + anemoi_2_apply_linear_layer(ctxt); + } + + else if (ctxt->l == 3) { + anemoi_3_apply_linear_layer(ctxt); + } + + else if (ctxt->l == 4) { + anemoi_4_apply_linear_layer(ctxt); + } + + else { + anemoi_generic_apply_linear_layer(ctxt); + } +} + +void anemoi_apply_one_round(anemoi_ctxt_t *ctxt, int round) { + anemoi_apply_constants_addition(ctxt, round); + anemoi_apply_linear_layer(ctxt); + anemoi_apply_flystel(ctxt); +} + +void anemoi_apply_permutation(anemoi_ctxt_t *ctxt) { + for (int i = 0; i < ctxt->nb_rounds; i++) { + anemoi_apply_one_round(ctxt, i); + } + + anemoi_apply_linear_layer(ctxt); +} + +void anemoi_set_state_from_context(anemoi_ctxt_t *ctxt, blst_fr *state) { + int state_size = anemoi_get_state_size_from_context(ctxt); + blst_fr *ctxt_state = anemoi_get_state_from_context(ctxt); + + for (int i = 0; i < state_size; i++) { + memcpy(ctxt_state + i, state + i, sizeof(blst_fr)); + } +} + +anemoi_ctxt_t *anemoi_allocate_context(int l, int nb_rounds) { + // Returning null because we do not support bigger state size than 8 at the + // moment + if (l > 4 || l < 0) { + return (NULL); + } + + anemoi_ctxt_t *ctxt = malloc(sizeof(anemoi_ctxt_t)); + if (ctxt == NULL) { + return (NULL); + } + blst_fr *state = malloc(sizeof(anemoi_ctxt_t)); + if (state == NULL) { + free(ctxt); + return (NULL); + } + + ctxt->l = l; + ctxt->nb_rounds = nb_rounds; + ctxt->ctxt = state; + + return (ctxt); +} + +void anemoi_free_context(anemoi_ctxt_t *ctxt) { + if (ctxt != NULL) { + free(ctxt->ctxt); + free(ctxt); + } +} diff --git a/src/lib_bls12_381_hash/anemoi.h b/src/lib_bls12_381_hash/anemoi.h new file mode 100644 index 000000000000..b5f4077872c8 --- /dev/null +++ b/src/lib_bls12_381_hash/anemoi.h @@ -0,0 +1,49 @@ +#ifndef ANEMOI_H +#define ANEMOI_H + +#include "blst.h" +#include "blst_misc.h" +#include + +typedef struct anemoi_ctxt_s { + // state_size := m = 2 * l + int l; + int nb_rounds; + // State + MDS + constants + beta + delta + blst_fr *ctxt; +} anemoi_ctxt_t; + +/* Apply n times the SPN construction where [n] is the number of rounds for the + instances */ +void anemoi_apply_permutation(anemoi_ctxt_t *ctxt); + +/* Apply one round of the SPN construction */ +void anemoi_apply_one_round(anemoi_ctxt_t *ctxt, int round); + +/* Building blocks of the SPN permutation */ +void anemoi_apply_constants_addition(anemoi_ctxt_t *ctxt, int round); + +void anemoi_apply_linear_layer(anemoi_ctxt_t *ctxt); + +void anemoi_apply_flystel(anemoi_ctxt_t *ctxt); + +/* Context related functions */ +blst_fr *anemoi_get_state_from_context(anemoi_ctxt_t *ctxt); + +anemoi_ctxt_t *anemoi_allocate_context(int l, int nb_rounds); + +void anemoi_set_state_from_context(anemoi_ctxt_t *ctxt, blst_fr *state); + +int anemoi_get_state_size_from_context(anemoi_ctxt_t *ctxt); + +blst_fr *anemoi_get_mds_from_context(anemoi_ctxt_t *ctxt); + +blst_fr *anemoi_get_round_constants_from_context(anemoi_ctxt_t *ctxt); + +blst_fr *anemoi_get_beta_from_context(anemoi_ctxt_t *ctxt); + +blst_fr *anemoi_get_delta_from_context(anemoi_ctxt_t *ctxt); + +void anemoi_free_context(anemoi_ctxt_t *ctxt); + +#endif diff --git a/src/lib_bls12_381_hash/anemoi.ml b/src/lib_bls12_381_hash/anemoi.ml new file mode 100644 index 000000000000..0d16b6efc4ff --- /dev/null +++ b/src/lib_bls12_381_hash/anemoi.ml @@ -0,0 +1,255 @@ +module Stubs = struct + type ctxt + + external get_state : Bls12_381.Fr.t array -> ctxt -> unit + = "caml_bls12_381_hash_anemoi_get_state_stubs" + + external get_state_size : ctxt -> int + = "caml_bls12_381_hash_anemoi_get_state_size_stubs" + + external set_state : ctxt -> Bls12_381.Fr.t array -> unit + = "caml_bls12_381_hash_anemoi_set_state_stubs" + + external anemoi_apply_flystel : ctxt -> unit + = "caml_bls12_381_hash_anemoi_apply_flystel_stubs" + + external anemoi_apply_linear_layer : ctxt -> unit + = "caml_bls12_381_hash_anemoi_apply_linear_layer_stubs" + + external anemoi_apply_constants_addition : ctxt -> int -> unit + = "caml_bls12_381_hash_anemoi_apply_constants_addition_stubs" + + external anemoi_apply_one_round : ctxt -> int -> unit + = "caml_bls12_381_hash_anemoi_apply_one_round_stubs" + + external anemoi_apply_permutation : ctxt -> unit + = "caml_bls12_381_hash_anemoi_apply_permutation_stubs" + + external anemoi_allocate_ctxt : + mds:Bls12_381.Fr.t array array -> + constants:Bls12_381.Fr.t array -> + beta:Bls12_381.Fr.t -> + delta:Bls12_381.Fr.t -> + int -> + int -> + ctxt + = "caml_bls12_381_hash_anemoi_allocate_ctxt_stubs_bytecode" "caml_bls12_381_hash_anemoi_allocate_ctxt_stubs" +end + +module Parameters = struct + type t = { + security : int; + state_size : int; + nb_rounds : int; + linear_layer : Bls12_381.Fr.t array array; + round_constants : Bls12_381.Fr.t array; + } + + let g = Bls12_381.Fr.of_string "7" + + let beta = Bls12_381.Fr.of_string "7" + + let delta = + Bls12_381.Fr.of_string + "14981678621464625851270783002338847382197300714436467949315331057125308909861" + + let alpha = Bls12_381.Fr.of_string "5" + + let alpha_inv = + Bls12_381.Fr.of_string + "20974350070050476191779096203274386335076221000211055129041463479975432473805" + + let gamma = Bls12_381.Fr.zero + + let pi_0 = + Bls12_381.Fr.of_string + "1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679" + + let pi_1 = + Bls12_381.Fr.of_string + "8214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196" + + let generate_constants nb_rounds l = + let csts_c = + Array.init (l * nb_rounds) (fun _ -> Bls12_381.Fr.(copy zero)) + in + let csts_d = + Array.init (l * nb_rounds) (fun _ -> Bls12_381.Fr.(copy zero)) + in + for i = 0 to nb_rounds - 1 do + let pi_0_i = Bls12_381.Fr.pow pi_0 (Z.of_int i) in + let pi_0_i_square = Bls12_381.Fr.(square pi_0_i) in + for j = 0 to l - 1 do + let pi_1_j = Bls12_381.Fr.pow pi_1 (Z.of_int j) in + let pi_1_j_square = Bls12_381.Fr.square pi_1_j in + csts_c.((i * l) + j) <- + Bls12_381.Fr.( + (g * pi_0_i_square) + + pow (pi_0_i + pi_1_j) (Bls12_381.Fr.to_z alpha)) ; + csts_d.((i * l) + j) <- + Bls12_381.Fr.( + (g * pi_1_j_square) + + pow (pi_0_i + pi_1_j) (Bls12_381.Fr.to_z alpha) + + delta) + done + done ; + Array.concat [csts_c; csts_d] + + let compute_number_of_rounds state_size security = + let l = state_size / 2 in + let security_margin = 1 + l in + let alpha = 5 in + let pow_security_2 = Z.pow (Z.of_int 2) security in + let rec aux r = + let num = (2 * l * r) + alpha + 1 + (2 * ((l * r) - 2)) in + let den = 2 * l * r in + let bin = Z.bin (Z.of_int num) den in + let bin_square = Z.mul bin bin in + if Z.gt bin_square pow_security_2 then r else aux (r + 1) + in + max 10 (security_margin + aux 0) + + let get_number_of_rounds p = p.nb_rounds + + let get_round_constants p = p.round_constants + + let get_matrix p = p.linear_layer + + let get_state_size p = p.state_size + + let create security state_size linear_layer = + if state_size mod 2 = 1 then failwith "State size must be a multiple of 2" ; + if state_size = 2 || state_size = 4 || state_size = 6 || state_size = 8 then + failwith + "Use the value given above. The library enforces users to use the \ + linear layer recommended in the paper" ; + let nb_rounds = compute_number_of_rounds state_size security in + let round_constants = generate_constants nb_rounds (state_size / 2) in + {security; state_size; nb_rounds; round_constants; linear_layer} + + let security_128_state_size_2 = + { + security = 128; + nb_rounds = 19; + state_size = 2; + linear_layer = Bls12_381.Fr.[|[|one; g|]; [|g; square g + one|]|]; + round_constants = generate_constants 19 1; + } + + let security_141_state_size_2 = + { + security = 141; + nb_rounds = 20; + state_size = 2; + linear_layer = Bls12_381.Fr.[|[|one; g|]; [|g; square g + one|]|]; + round_constants = generate_constants 20 1; + } + + let security_128_state_size_4 = + { + security = 128; + nb_rounds = 12; + state_size = 4; + linear_layer = Bls12_381.Fr.[|[|one; g|]; [|g; square g + one|]|]; + round_constants = generate_constants 12 2; + } + + let security_128_state_size_6 = + { + security = 128; + nb_rounds = 10; + state_size = 6; + linear_layer = + Bls12_381.Fr. + [|[|g + one; one; g + one|]; [|one; one; g|]; [|g; one; one|]|]; + round_constants = generate_constants 10 3; + } + + let security_128_state_size_8 = + { + security = 128; + nb_rounds = 10; + state_size = 8; + round_constants = generate_constants 10 4; + linear_layer = + Bls12_381.Fr. + [| + [|one; one + g; g; g|]; + [|square g; g + square g; one + g; one + double g|]; + [|square g; square g; one; one + g|]; + [|one + g; one + double g; g; one + g|]; + |]; + } +end + +type parameters = Parameters.t + +type ctxt = Stubs.ctxt + +let allocate_ctxt parameters = + let state_size = parameters.Parameters.state_size in + if state_size mod 2 = 1 then + failwith "The state size given in parameters must be a multiple of 2" ; + let l = state_size / 2 in + if state_size <= 0 then failwith "State size must be at least 2" ; + let mds = parameters.Parameters.linear_layer in + let constants = parameters.Parameters.round_constants in + let beta = Parameters.beta in + let delta = Parameters.delta in + let ctxt = + Stubs.anemoi_allocate_ctxt + ~mds + ~constants + ~beta + ~delta + l + parameters.nb_rounds + in + ctxt + +let set_state ctxt state = + let exp_state_size = Stubs.get_state_size ctxt in + let state_size = Array.length state in + if state_size <> exp_state_size then + failwith + (Printf.sprintf + "The given array contains %d elements but the expected state size is \ + %d" + state_size + exp_state_size) ; + Stubs.set_state ctxt state + +let get_state_size ctxt = Stubs.get_state_size ctxt + +let get_state ctxt = + let state_size = Stubs.get_state_size ctxt in + let state = Array.init state_size (fun _ -> Bls12_381.Fr.(copy zero)) in + Stubs.get_state state ctxt ; + state + +let apply_constants_addition ctxt round = + Stubs.anemoi_apply_constants_addition ctxt round + +let apply_linear_layer ctxt = Stubs.anemoi_apply_linear_layer ctxt + +let apply_one_round ctxt idx = Stubs.anemoi_apply_one_round ctxt idx + +let apply_flystel ctxt = Stubs.anemoi_apply_flystel ctxt + +let apply_permutation ctxt = Stubs.anemoi_apply_permutation ctxt + +let jive128_1 x y = + let state = [|x; y|] in + let ctxt = allocate_ctxt Parameters.security_128_state_size_2 in + let () = set_state ctxt state in + let () = apply_permutation ctxt in + let state = get_state ctxt in + Bls12_381.Fr.(x + y + state.(0) + state.(1)) + +let jive141_1 x y = + let state = [|x; y|] in + let ctxt = allocate_ctxt Parameters.security_141_state_size_2 in + let () = set_state ctxt state in + let () = apply_permutation ctxt in + let state = get_state ctxt in + Bls12_381.Fr.(x + y + state.(0) + state.(1)) diff --git a/src/lib_bls12_381_hash/bls12_381_hash.ml b/src/lib_bls12_381_hash/bls12_381_hash.ml new file mode 100644 index 000000000000..936f0a380cd5 --- /dev/null +++ b/src/lib_bls12_381_hash/bls12_381_hash.ml @@ -0,0 +1,13 @@ +module type PERMUTATION = S.PERMUTATION + +module Permutation = struct + module Poseidon = Poseidon + module Rescue = Rescue + module Anemoi = Anemoi + module Griffin = Griffin +end + +module Mode = struct + module Jive = Jive + (* module Sponge = Sponge *) +end diff --git a/src/lib_bls12_381_hash/bls12_381_hash.mli b/src/lib_bls12_381_hash/bls12_381_hash.mli new file mode 100644 index 000000000000..05a8df87455d --- /dev/null +++ b/src/lib_bls12_381_hash/bls12_381_hash.mli @@ -0,0 +1,238 @@ +module type PERMUTATION = S.PERMUTATION + +module Permutation : sig + (** Implementation of + {{:https://eprint.iacr.org/2019/458.pdf} Poseidon} over the scalar field of + BLS12-381 for a security with the permutation [x^5]. +*) + module Poseidon : sig + module Parameters : sig + type t = { + state_size : int; + nb_of_partial_rounds : int; + nb_of_full_rounds : int; + batch_size : int; + round_constants : Bls12_381.Fr.t array; + linear_layer : Bls12_381.Fr.t array array; + } + + (** Parameters for Poseidon with a state size of [3] for a security of + 128bits. + FIXME: The linear layer and the round constants are not standard + *) + val security_128_state_size_3 : t + + (** Parameters for Poseidon with a state size of [5] for a security of + 256bits. + FIXME: The linear layer and the round constants are not standard + *) + val security_256_state_size_5 : t + end + + include S.PERMUTATION with type parameters = Parameters.t + end + + (** Implementation of an instantiation of {{: https://eprint.iacr.org/2019/426 } + Rescue } over the scalar field of BLS12-381 for a security of 128 bits and + with the permutation [x^5]. The parameters of the instantiation are: + - state size = 3 + - number of rounds = 14 + + These parameters have been generated using {{: + https://github.com/KULeuven-COSIC/Marvellous/blob/0969ce8a5ebaa0bf45696b44e276d3dd81d2e455/rescue_prime.sage} + this script}. +*) + module Rescue : sig + (** Set of parameters for BLS12-381, and parameters for specific + instantiations given in the reference paper *) + module Parameters : sig + type t = { + linear_layer : Bls12_381.Fr.t array array; + round_constants : Bls12_381.Fr.t array; + state_size : int; + nb_of_rounds : int; + } + + (** Parameters for Rescue with [state_size = 3] and 128 bits of security. + FIXME: The linear layer and the round constants are not standard + *) + val security_128_state_size_3 : t + end + + include S.PERMUTATION with type parameters = Parameters.t + end + + (** Implementation of {{: https://eprint.iacr.org/2022/840} + the permutation Anemoi and the mode of operation Jive} over the scalar field + of BLS12-381. + + The state of the permutation Anemoi is [m], where [m] is a multiple of [2]. + It is commonly refered by [l] such that [m = 2l]. +*) + module Anemoi : sig + (** Set of parameters for BLS12-381, and parameters for specific + instantiations given in the reference paper *) + module Parameters : sig + (** The type representing the set of parameters for a given instance *) + type t + + (** [create security state_size linear_layer] creates a + value of type {!t}. If the [state_size] is [2], [4], [6] or [8], an + exception is raised. The library enforces the user to use the default + security parameters and an optimised implementation is provided in these + cases. Also, an exception is raised if the state size is not a multiple + of [2]. + + @deprecated It is highly recommended to follow the recommandation in the + paper for the choice of security parameters. Please open an issue if you + need support for other instances than the default parameters provided by + the library. + *) + val create : int -> int -> Bls12_381.Fr.t array array -> t + [@@deprecated + "It is highly recommended to follow the recommandation in the paper \ + for the choice of security parameters. Please open an issue if you \ + need support for other instances than the default parameters \ + provided by the library."] + + (** Exponent for the substitution box. For BLS12-381, it is [5] *) + val alpha : Bls12_381.Fr.t + + (** Inverse of the exponent for the substitution box. For BLS12-381, it is + [20974350070050476191779096203274386335076221000211055129041463479975432473805] *) + val alpha_inv : Bls12_381.Fr.t + + (** For BLS12-381, it is + [14981678621464625851270783002338847382197300714436467949315331057125308909861] + *) + val delta : Bls12_381.Fr.t + + (** First generator of the scalar field of BLS12-381, i.e. [7] *) + val g : Bls12_381.Fr.t + + (** Same than {!g} *) + val beta : Bls12_381.Fr.t + + (** Set to [0] for BLS12-381 *) + val gamma : Bls12_381.Fr.t + + (** [compute_number_of_rounds state_size security] computes the minimal + number of rounds for an instance of Anemoi with a state size of + [m = state_size] to reach a security level of [security] bits. The + computation follows the formula given in section 5.2 *) + val compute_number_of_rounds : int -> int -> int + + (** [generate_constants nb_rounds l] generates the constants for the + instance of Anemoi for a state size of [m = 2 * l]. The output contains + the C's followed by the D's as described in the paper in section 5.1 *) + val generate_constants : int -> int -> Bls12_381.Fr.t array + + val get_round_constants : t -> Bls12_381.Fr.t array + + val get_matrix : t -> Bls12_381.Fr.t array array + + val get_number_of_rounds : t -> int + + val get_state_size : t -> int + + (** Parameters for the permutation Anemoi for a state size of [m = 2] (i.e. + [l = 1]) and 128 bits of security given in the paper + *) + val security_128_state_size_2 : t + + (** Parameters for the permutation Anemoi for a state size of [m = 2] (i.e. + [l = 1]) and 141 bits of security + *) + val security_141_state_size_2 : t + + (** Parameters for the permutation Anemoi for a state size of [m = 4] (i.e. + [l = 2]) and 128 bits of security given in the paper + *) + val security_128_state_size_4 : t + + (** Parameters for the permutation Anemoi for a state size of [m = 6] (i.e. + [l = 3]) and 128 bits of security given in the paper + *) + val security_128_state_size_6 : t + + (** Parameters for the permutation Anemoi for a state size of [m = 8] (i.e. + [l = 4]) and 128 bits of security given in the paper + *) + val security_128_state_size_8 : t + end + + include S.PERMUTATION with type parameters = Parameters.t + + (** [apply_linear_layer ctxt] applies the linear layer on the state. The + context is modified *) + val apply_linear_layer : ctxt -> unit + + (** [apply_flystel ctxt] applies the Flystel construction on the context. + The context is modified *) + val apply_flystel : ctxt -> unit + + (** [apply_constants_addition ctxt round] applies the constant addition for the + round [round]. The context is modified *) + val apply_constants_addition : ctxt -> int -> unit + + (** [apply_one_round ctxt round] applies the round [round] on the state. The + context is modified *) + val apply_one_round : ctxt -> int -> unit + + (** [jive128_1 x y] calls the permutation Anemoi for [l = 1] with the state + [S = (x, y)] and apply Jive on the output. Expected security is 128 + bits *) + val jive128_1 : Bls12_381.Fr.t -> Bls12_381.Fr.t -> Bls12_381.Fr.t + + (** [jive141_1 x y] calls the permutation Anemoi for [l = 1] with the state + [S = (x, y)] and apply Jive on the output. Expected security is 141 + bits *) + val jive141_1 : Bls12_381.Fr.t -> Bls12_381.Fr.t -> Bls12_381.Fr.t + end + + (** {{: https://eprint.iacr.org/2022/403.pdf } Griffin } over the scalar field + of BLS12-381 for a security of 128 bits and with the permutation [x^5]. +*) + module Griffin : sig + module Parameters : sig + type t = { + nb_of_rounds : int; + state_size : int; + round_constants : Bls12_381.Fr.t array; + alpha_beta_s : Bls12_381.Fr.t array; + } + + (** Exponent for the substitution box. For BLS12-381, it is [5] *) + val d : Bls12_381.Fr.t + + (** Inverse of the exponent for the substitution box. For BLS12-381, it is + [20974350070050476191779096203274386335076221000211055129041463479975432473805] *) + val d_inv : Bls12_381.Fr.t + + (** Parameters for Griffin with a state size of [3] for a security of + 128bits + *) + val security_128_state_size_3 : t + + (** Parameters for Griffin with a state size of [4] for a security of 128 + bits + *) + val security_128_state_size_4 : t + end + + include S.PERMUTATION with type parameters = Parameters.t + end +end + +module Mode : sig + module Jive : sig + include S.MODE + + val digest_b : + (module S.PERMUTATION with type parameters = 'p) -> + 'p -> + Bls12_381.Fr.t array -> + int -> + Bls12_381.Fr.t array + end +end diff --git a/src/lib_bls12_381_hash/caml_anemoi_stubs.c b/src/lib_bls12_381_hash/caml_anemoi_stubs.c new file mode 100644 index 000000000000..7f5e91c360f7 --- /dev/null +++ b/src/lib_bls12_381_hash/caml_anemoi_stubs.c @@ -0,0 +1,177 @@ +#include "blst.h" +#include "blst_misc.h" + +#include "anemoi.h" +#include "caml_bls12_381_stubs.h" + +#include +#include +#include +#include +#include + +#define Anemoi_ctxt_val(v) (*((anemoi_ctxt_t **)Data_custom_val(v))) + +static void finalize_free_anemoi_ctxt(value vctxt) { + anemoi_ctxt_t *ctxt = Anemoi_ctxt_val(vctxt); + free(ctxt->ctxt); + free(ctxt); +} + +static struct custom_operations anemoi_ctxt_ops = {"anemoi_ctxt_t", + finalize_free_anemoi_ctxt, + custom_compare_default, + custom_hash_default, + custom_serialize_default, + custom_deserialize_default, + custom_compare_ext_default, + custom_fixed_length_default}; + +CAMLprim value caml_bls12_381_hash_anemoi_allocate_ctxt_stubs( + value vmds, value vconstants, value vbeta, value vdelta, value vl, + value vnb_rounds) { + CAMLparam4(vmds, vconstants, vl, vnb_rounds); + CAMLxparam2(vbeta, vdelta); + CAMLlocal1(vblock); + + int l = Int_val(vl); + int state_size = 2 * l; + + int nb_rounds = Int_val(vnb_rounds); + + int mds_size = l * l; + int nb_constants = l * 2 * nb_rounds; + // + 2 for beta and delta + int total_blst_fr_elements = state_size + mds_size + nb_constants + 2; + + // Initialize state. It contains the constants and the MDS + blst_fr *ctxt_internal = malloc(sizeof(blst_fr) * total_blst_fr_elements); + + if (ctxt_internal == NULL) { + caml_raise_out_of_memory(); + } + + blst_fr *state = ctxt_internal; + memset(state, 0, sizeof(blst_fr) * state_size); + + // Copying MDS + blst_fr *mds = ctxt_internal + state_size; + for (int i = 0; i < l; i++) { + for (int j = 0; j < l; j++) { + memcpy(mds + i * l + j, Fr_val_ij(vmds, i, j), sizeof(blst_fr)); + } + } + + // Copying round constants + blst_fr *constants = ctxt_internal + state_size + mds_size; + for (int i = 0; i < nb_constants; i++) { + memcpy(constants + i, Fr_val_k(vconstants, i), sizeof(blst_fr)); + } + + blst_fr *beta = constants + nb_constants; + blst_fr *delta = constants + nb_constants + 1; + memcpy(beta, Blst_fr_val(vbeta), sizeof(blst_fr)); + memcpy(delta, Blst_fr_val(vdelta), sizeof(blst_fr)); + + anemoi_ctxt_t *ctxt = malloc(sizeof(anemoi_ctxt_t)); + if (ctxt == NULL) { + free(ctxt_internal); + caml_raise_out_of_memory(); + } + ctxt->ctxt = ctxt_internal; + ctxt->l = l; + ctxt->nb_rounds = nb_rounds; + + size_t out_of_heap_memory_size = + sizeof(blst_fr) * total_blst_fr_elements + sizeof(anemoi_ctxt_t); + vblock = caml_alloc_custom_mem(&anemoi_ctxt_ops, sizeof(anemoi_ctxt_t *), + out_of_heap_memory_size); + + anemoi_ctxt_t **block = (anemoi_ctxt_t **)Data_custom_val(vblock); + *block = ctxt; + + CAMLreturn(vblock); +} + +CAMLprim value +caml_bls12_381_hash_anemoi_allocate_ctxt_stubs_bytecode(value *argv, int argc) { + if (argc != 6) { + caml_failwith("caml_bls12_381_hash_anemoi_allocate_ctxt_stubs_bytecode: " + "wrong argc value"); + } + return caml_bls12_381_hash_anemoi_allocate_ctxt_stubs( + argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); +} + +CAMLprim value caml_bls12_381_hash_anemoi_get_state_stubs(value vbuffer, + value vctxt) { + CAMLparam2(vbuffer, vctxt); + anemoi_ctxt_t *ctxt = Anemoi_ctxt_val(vctxt); + blst_fr *state = anemoi_get_state_from_context(ctxt); + int state_size = anemoi_get_state_size_from_context(ctxt); + + for (int i = 0; i < state_size; i++) { + memcpy(Fr_val_k(vbuffer, i), state + i, sizeof(blst_fr)); + } + CAMLreturn(Val_unit); +} + +CAMLprim value caml_bls12_381_hash_anemoi_set_state_stubs(value vctxt, + value vstate) { + CAMLparam2(vctxt, vstate); + + anemoi_ctxt_t *ctxt = Anemoi_ctxt_val(vctxt); + blst_fr *state = anemoi_get_state_from_context(ctxt); + int state_size = anemoi_get_state_size_from_context(ctxt); + + for (int i = 0; i < state_size; i++) { + memcpy(state + i, Fr_val_k(vstate, i), sizeof(blst_fr)); + } + CAMLreturn(Val_unit); +} + +CAMLprim value caml_bls12_381_hash_anemoi_get_state_size_stubs(value vctxt) { + CAMLparam1(vctxt); + anemoi_ctxt_t *ctxt = Anemoi_ctxt_val(vctxt); + CAMLreturn(Val_int(anemoi_get_state_size_from_context(ctxt))); +} + +CAMLprim value caml_bls12_381_hash_anemoi_apply_permutation_stubs(value vctxt) { + CAMLparam1(vctxt); + anemoi_ctxt_t *ctxt = Anemoi_ctxt_val(vctxt); + anemoi_apply_permutation(ctxt); + CAMLreturn(Val_unit); +} + +CAMLprim value caml_bls12_381_hash_anemoi_apply_one_round_stubs(value vctxt, + value vround) { + CAMLparam2(vctxt, vround); + anemoi_ctxt_t *ctxt = Anemoi_ctxt_val(vctxt); + int round = Int_val(vround); + anemoi_apply_one_round(ctxt, round); + CAMLreturn(Val_unit); +} + +CAMLprim value caml_bls12_381_hash_anemoi_apply_constants_addition_stubs( + value vctxt, value vround) { + CAMLparam2(vctxt, vround); + anemoi_ctxt_t *ctxt = Anemoi_ctxt_val(vctxt); + int round = Int_val(vround); + anemoi_apply_constants_addition(ctxt, round); + CAMLreturn(Val_unit); +} + +CAMLprim value caml_bls12_381_hash_anemoi_apply_flystel_stubs(value vctxt) { + CAMLparam1(vctxt); + anemoi_ctxt_t *ctxt = Anemoi_ctxt_val(vctxt); + anemoi_apply_flystel(ctxt); + CAMLreturn(Val_unit); +} + +CAMLprim value +caml_bls12_381_hash_anemoi_apply_linear_layer_stubs(value vctxt) { + CAMLparam1(vctxt); + anemoi_ctxt_t *ctxt = Anemoi_ctxt_val(vctxt); + anemoi_apply_linear_layer(ctxt); + CAMLreturn(Val_unit); +} diff --git a/src/lib_bls12_381_hash/caml_griffin_stubs.c b/src/lib_bls12_381_hash/caml_griffin_stubs.c new file mode 100644 index 000000000000..029941230772 --- /dev/null +++ b/src/lib_bls12_381_hash/caml_griffin_stubs.c @@ -0,0 +1,130 @@ +#include "blst.h" +#include "griffin.h" +#include +#include +#include +#include +#include +#include +#include + +#include "caml_bls12_381_stubs.h" + +#define Griffin_ctxt_val(v) (*((griffin_ctxt_t **)Data_custom_val(v))) + +static void finalize_free_griffin_ctxt(value vctxt) { + griffin_ctxt_t *ctxt = Griffin_ctxt_val(vctxt); + free(ctxt->state); + free(ctxt); +} + +static struct custom_operations griffin_ctxt_ops = { + "griffin_ctxt_t", finalize_free_griffin_ctxt, + custom_compare_default, custom_hash_default, + custom_serialize_default, custom_deserialize_default, + custom_compare_ext_default, custom_fixed_length_default}; + +CAMLprim value caml_bls12_381_hash_griffin_allocate_ctxt_stubs( + value vnb_rounds, value vstate_size, value vconstants, + value valpha_beta_s) { + CAMLparam4(vnb_rounds, vstate_size, vconstants, valpha_beta_s); + CAMLlocal1(vblock); + int state_size = Int_val(vstate_size); + int nb_rounds = Int_val(vnb_rounds); + + // state_size + constants + nb alpha_beta_s + int nb_alpha_beta_s = (state_size - 2) * 2; + int nb_constants = nb_rounds * state_size; + int state_full_size = state_size + nb_constants + nb_alpha_beta_s; + + // must be allocated on the heap as we pass the values to functions later + blst_fr *alpha_beta_s = malloc(sizeof(blst_fr) * nb_alpha_beta_s); + if (alpha_beta_s == NULL) { + caml_raise_out_of_memory(); + } + blst_fr *constants = malloc(sizeof(blst_fr) * nb_constants); + if (constants == NULL) { + free(alpha_beta_s); + caml_raise_out_of_memory(); + } + + for (int i = 0; i < nb_alpha_beta_s; i++) { + memcpy(alpha_beta_s + i, Fr_val_k(valpha_beta_s, i), sizeof(blst_fr)); + } + + for (int i = 0; i < nb_constants; i++) { + memcpy(constants + i, Fr_val_k(vconstants, i), sizeof(blst_fr)); + } + + griffin_ctxt_t *ctxt = + griffin_allocate_context(state_size, nb_rounds, constants, alpha_beta_s); + // we don't need it anymore + free(alpha_beta_s); + free(constants); + + if (ctxt == NULL) { + caml_raise_out_of_memory(); + } + + int out_of_heap_size = sizeof(griffin_ctxt_t *) + + state_full_size * sizeof(blst_fr) + + sizeof(griffin_ctxt_t); + + vblock = caml_alloc_custom_mem(&griffin_ctxt_ops, sizeof(griffin_ctxt_t *), + out_of_heap_size); + + griffin_ctxt_t **block = (griffin_ctxt_t **)(Data_custom_val(vblock)); + *block = ctxt; + CAMLreturn(vblock); +} + +CAMLprim value caml_bls12_381_hash_griffin_set_state_stubs(value vctxt, + value vstate) { + CAMLparam2(vctxt, vstate); + + griffin_ctxt_t *ctxt = Griffin_ctxt_val(vctxt); + blst_fr *state = ctxt->state; + int state_size = griffin_get_state_size_from_context(ctxt); + + for (int i = 0; i < state_size; i++) { + memcpy(state + i, Fr_val_k(vstate, i), sizeof(blst_fr)); + } + + CAMLreturn(Val_unit); +} + +CAMLprim value +caml_bls12_381_hash_griffin_apply_permutation_stubs(value vctxt) { + CAMLparam1(vctxt); + griffin_ctxt_t *ctxt = Griffin_ctxt_val(vctxt); + griffin_apply_permutation(ctxt); + CAMLreturn(Val_unit); +} + +CAMLprim value caml_bls12_381_hash_griffin_apply_one_round_stubs( + value vctxt, value vi_round_key) { + CAMLparam2(vctxt, vi_round_key); + griffin_ctxt_t *ctxt = Griffin_ctxt_val(vctxt); + int i_round_key = Int_val(vi_round_key); + griffin_apply_one_round(ctxt, i_round_key); + CAMLreturn(Val_unit); +} + +CAMLprim value caml_bls12_381_hash_griffin_get_state_stubs(value vbuffer, + value vctxt) { + CAMLparam2(vbuffer, vctxt); + griffin_ctxt_t *ctxt = Griffin_ctxt_val(vctxt); + blst_fr *state = griffin_get_state_from_context(ctxt); + int state_size = griffin_get_state_size_from_context(ctxt); + for (int i = 0; i < state_size; i++) { + memcpy(Fr_val_k(vbuffer, i), state + i, sizeof(blst_fr)); + } + CAMLreturn(Val_unit); +} + +CAMLprim value caml_bls12_381_hash_griffin_get_state_size_stubs(value vctxt) { + CAMLparam1(vctxt); + griffin_ctxt_t *ctxt = Griffin_ctxt_val(vctxt); + int state_size = griffin_get_state_size_from_context(ctxt); + CAMLreturn(Val_int(state_size)); +} diff --git a/src/lib_bls12_381_hash/caml_poseidon_stubs.c b/src/lib_bls12_381_hash/caml_poseidon_stubs.c new file mode 100644 index 000000000000..28bc8aaba99f --- /dev/null +++ b/src/lib_bls12_381_hash/caml_poseidon_stubs.c @@ -0,0 +1,146 @@ +#include "blst.h" +#include "blst_misc.h" + +#include "caml_bls12_381_stubs.h" +#include "ocaml_integers.h" +#include "poseidon.h" +#include +#include +#include +#include +#include +#include +#include + +#define Poseidon_ctxt_val(v) (*((poseidon_ctxt_t **)Data_custom_val(v))) + +static void finalize_free_poseidon_ctxt(value vctxt) { + poseidon_ctxt_t *ctxt = Poseidon_ctxt_val(vctxt); + blst_fr *state = poseidon_get_state_from_context(ctxt); + free(state); + free(ctxt); +} + +static struct custom_operations poseidon_ctxt_ops = { + "poseidon_ctxt_t", finalize_free_poseidon_ctxt, + custom_compare_default, custom_hash_default, + custom_serialize_default, custom_deserialize_default, + custom_compare_ext_default, custom_fixed_length_default}; + +/* + A context is a contiguous C piece of memory containing the state, the ark and + the MDS in the following way: + + | state[0] | state[1] | ... | state[W - 1] | ark[0] | ark[1] ... | ark[N] | + MDS[0][0] | MDS[0][1] | ... | MDS[0][W - 1] | ... | MDS[W - 1][W - 1] | + + The goal is to use the CPU cache and use the instance parameters as values on + the stack + */ +CAMLprim value caml_bls12_381_hash_poseidon_allocate_ctxt_stubs( + value vwidth, value vnb_full_rounds, value vnb_partial_rounds, + value vbatch_size, value vark, value vmds) { + // ark and mds are of correct size. We do not perform any check + CAMLparam5(vwidth, vnb_full_rounds, vnb_partial_rounds, vbatch_size, vark); + CAMLxparam1(vmds); + + CAMLlocal1(vblock); + + int width = Int_val(vwidth); + int nb_full_rounds = Int_val(vnb_full_rounds); + int nb_partial_rounds = Int_val(vnb_partial_rounds); + int batch_size = Int_val(vbatch_size); + int nb_constants = poseidon_compute_number_of_constants( + batch_size, nb_partial_rounds, nb_full_rounds, width); + // state + ark length + MDS + int nb_blst_fr_elem = width + nb_constants + width * width; + + blst_fr *state = malloc(sizeof(blst_fr) * nb_blst_fr_elem); + if (state == NULL) { + caml_raise_out_of_memory(); + } + memset(state, 0, sizeof(blst_fr) * width); + + blst_fr *ctxt_mds = state + width; + blst_fr *ctxt_ark = ctxt_mds + width * width; + // Copying ark + for (int i = 0; i < nb_constants; i++) { + memcpy(ctxt_ark + i, Fr_val_k(vark, i), sizeof(blst_fr)); + } + // Copying MDS + for (int i = 0; i < width; i++) { + for (int j = 0; j < width; j++) { + memcpy(ctxt_mds + i * width + j, Fr_val_ij(vmds, i, j), sizeof(blst_fr)); + } + } + + poseidon_ctxt_t *ctxt = malloc(sizeof(poseidon_ctxt_t)); + if (ctxt == NULL) { + free(state); + caml_raise_out_of_memory(); + } + ctxt->state = state; + ctxt->state_size = width; + ctxt->nb_full_rounds = nb_full_rounds; + ctxt->nb_partial_rounds = nb_partial_rounds; + ctxt->batch_size = batch_size; + + size_t out_of_heap_memory_size = + sizeof(blst_fr) * nb_blst_fr_elem + sizeof(poseidon_ctxt_t); + vblock = caml_alloc_custom_mem(&poseidon_ctxt_ops, sizeof(poseidon_ctxt_t *), + out_of_heap_memory_size); + + poseidon_ctxt_t **block = (poseidon_ctxt_t **)Data_custom_val(vblock); + *block = ctxt; + CAMLreturn(vblock); +} + +CAMLprim value caml_bls12_381_hash_poseidon_allocate_ctxt_stubs_bytecode( + value *argv, value argc) { + if (argc != 6) { + caml_failwith("caml_bls12_381_hash_poseidon_allocate_ctxt_stubs_bytecode: " + "wrong argc value"); + } + return caml_bls12_381_hash_poseidon_allocate_ctxt_stubs( + argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); +} + +CAMLprim value caml_bls12_381_hash_poseidon_set_state_stubs(value vctxt, + value vstate) { + CAMLparam2(vctxt, vstate); + + poseidon_ctxt_t *ctxt = Poseidon_ctxt_val(vctxt); + blst_fr *state = poseidon_get_state_from_context(ctxt); + + for (int i = 0; i < ctxt->state_size; i++) { + memcpy(state + i, Fr_val_k(vstate, i), sizeof(blst_fr)); + } + + CAMLreturn(Val_unit); +} + +CAMLprim value +caml_bls12_381_hash_poseidon_apply_permutation_stubs(value vctxt) { + CAMLparam1(vctxt); + poseidon_ctxt_t *ctxt = Poseidon_ctxt_val(vctxt); + poseidon_apply_permutation(ctxt); + CAMLreturn(Val_unit); +} + +CAMLprim value caml_bls12_381_hash_poseidon_get_state_stubs(value vbuffer, + value vctxt) { + CAMLparam2(vbuffer, vctxt); + poseidon_ctxt_t *ctxt = Poseidon_ctxt_val(vctxt); + blst_fr *state = poseidon_get_state_from_context(ctxt); + int state_size = ctxt->state_size; + for (int i = 0; i < state_size; i++) { + memcpy(Fr_val_k(vbuffer, i), state + i, sizeof(blst_fr)); + } + CAMLreturn(Val_unit); +} + +CAMLprim value caml_bls12_381_hash_poseidon_get_state_size_stubs(value vctxt) { + CAMLparam1(vctxt); + poseidon_ctxt_t *ctxt = Poseidon_ctxt_val(vctxt); + CAMLreturn(Val_int(ctxt->state_size)); +} diff --git a/src/lib_bls12_381_hash/caml_rescue_stubs.c b/src/lib_bls12_381_hash/caml_rescue_stubs.c new file mode 100644 index 000000000000..ef65652d1dc0 --- /dev/null +++ b/src/lib_bls12_381_hash/caml_rescue_stubs.c @@ -0,0 +1,124 @@ +#include "blst.h" +#include "rescue.h" +#include +#include +#include +#include +#include +#include +#include + +#include "caml_bls12_381_stubs.h" + +#define Rescue_ctxt_val(v) (*((rescue_ctxt_t **)Data_custom_val(v))) + +static void finalize_free_rescue_ctxt(value vctxt) { + rescue_ctxt_t *ctxt = Rescue_ctxt_val(vctxt); + blst_fr *state = rescue_get_state_from_context(ctxt); + free(state); + free(ctxt); +} + +static struct custom_operations rescue_ctxt_ops = {"rescue_ctxt_t", + finalize_free_rescue_ctxt, + custom_compare_default, + custom_hash_default, + custom_serialize_default, + custom_deserialize_default, + custom_compare_ext_default, + custom_fixed_length_default}; + +CAMLprim value caml_bls12_381_hash_rescue_allocate_ctxt_stubs( + value vmds, value vconstants, value vnb_rounds, value vstate_size) { + CAMLparam4(vmds, vconstants, vnb_rounds, vstate_size); + CAMLlocal1(vblock); + + int state_size = Int_val(vstate_size); + int nb_rounds = Int_val(vnb_rounds); + int mds_size = state_size * state_size; + int nb_constants = state_size * nb_rounds * 2; + + // Initialize state. It contains the constants and the MDS + blst_fr *ctxt_internal = + malloc(sizeof(blst_fr) * (state_size + mds_size + nb_constants)); + + if (ctxt_internal == NULL) { + caml_raise_out_of_memory(); + } + + blst_fr *state = ctxt_internal; + memset(state, 0, sizeof(blst_fr) * state_size); + + blst_fr *mds = ctxt_internal + state_size; + blst_fr *constants = ctxt_internal + state_size + mds_size; + + // Copying MDS + for (int i = 0; i < state_size; i++) { + for (int j = 0; j < state_size; j++) { + memcpy(mds + i * state_size + j, Fr_val_ij(vmds, i, j), sizeof(blst_fr)); + } + } + + // Copying ark + for (int i = 0; i < nb_constants; i++) { + memcpy(constants + i, Fr_val_k(vconstants, i), sizeof(blst_fr)); + } + + rescue_ctxt_t *ctxt = malloc(sizeof(rescue_ctxt_t)); + if (ctxt == NULL) { + free(ctxt_internal); + caml_raise_out_of_memory(); + } + ctxt->state = ctxt_internal; + ctxt->state_size = state_size; + ctxt->nb_rounds = nb_rounds; + + size_t out_of_heap_memory_size = + sizeof(blst_fr) * (state_size + mds_size + nb_constants) + + sizeof(rescue_ctxt_t); + vblock = caml_alloc_custom_mem(&rescue_ctxt_ops, sizeof(rescue_ctxt_t *), + out_of_heap_memory_size); + + rescue_ctxt_t **block = (rescue_ctxt_t **)Data_custom_val(vblock); + *block = ctxt; + + CAMLreturn(vblock); +} + +CAMLprim value caml_bls12_381_hash_rescue_apply_permutation_stubs(value vctxt) { + CAMLparam1(vctxt); + marvellous_apply_permutation(Rescue_ctxt_val(vctxt)); + CAMLreturn(Val_unit); +} + +CAMLprim value caml_bls12_381_hash_rescue_get_state_stubs(value vbuffer, + value vctxt) { + CAMLparam2(vbuffer, vctxt); + rescue_ctxt_t *ctxt = Rescue_ctxt_val(vctxt); + blst_fr *state = rescue_get_state_from_context(ctxt); + int state_size = ctxt->state_size; + for (int i = 0; i < state_size; i++) { + memcpy(Fr_val_k(vbuffer, i), state + i, sizeof(blst_fr)); + } + CAMLreturn(Val_unit); +} + +CAMLprim value caml_bls12_381_hash_rescue_set_state_stubs(value vctxt, + value vstate) { + CAMLparam2(vctxt, vstate); + + rescue_ctxt_t *ctxt = Rescue_ctxt_val(vctxt); + blst_fr *state = rescue_get_state_from_context(ctxt); + + for (int i = 0; i < ctxt->state_size; i++) { + memcpy(state + i, Fr_val_k(vstate, i), sizeof(blst_fr)); + } + + CAMLreturn(Val_unit); +} + +CAMLprim value caml_bls12_381_hash_rescue_get_state_size_stubs(value vctxt) { + CAMLparam1(vctxt); + int state_size = rescue_get_state_size_from_context(Rescue_ctxt_val(vctxt)); + CAMLreturn(Val_int(state_size)); +} diff --git a/src/lib_bls12_381_hash/dune b/src/lib_bls12_381_hash/dune new file mode 100644 index 000000000000..f8a7bd2ef308 --- /dev/null +++ b/src/lib_bls12_381_hash/dune @@ -0,0 +1,22 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name bls12_381_hash) + (public_name octez-bls12-381-hash) + (instrumentation (backend bisect_ppx)) + (libraries + bls12-381) + (library_flags (:standard -linkall)) + (foreign_stubs + (language c) + (names + caml_rescue_stubs + caml_anemoi_stubs + caml_poseidon_stubs + caml_griffin_stubs + rescue + anemoi + poseidon + griffin)) + (c_library_flags (-Wall -Wextra :standard -lpthread))) diff --git a/src/lib_bls12_381_hash/griffin.c b/src/lib_bls12_381_hash/griffin.c new file mode 100644 index 000000000000..254cecde542f --- /dev/null +++ b/src/lib_bls12_381_hash/griffin.c @@ -0,0 +1,597 @@ +#include "griffin.h" + +int griffin_get_state_size_from_context(griffin_ctxt_t *ctxt) { + return (ctxt->state_size); +} + +int griffin_get_number_of_alpha_betas_from_context(griffin_ctxt_t *ctxt) { + int state_size = griffin_get_state_size_from_context(ctxt); + return ((state_size - 2) * 2); +} + +blst_fr *griffin_get_state_from_context(griffin_ctxt_t *ctxt) { + return (ctxt->state); +} + +void griffin_set_state_from_context(griffin_ctxt_t *ctxt, blst_fr *state) { + int state_size = griffin_get_state_size_from_context(ctxt); + blst_fr *ctxt_state = griffin_get_state_from_context(ctxt); + + for (int i = 0; i < state_size; i++) { + memcpy(ctxt_state + i, state + i, sizeof(blst_fr)); + } +} + +blst_fr *griffin_get_alpha_beta_from_context(griffin_ctxt_t *ctxt) { + // alpha_beta starts just after the state + return (ctxt->state + ctxt->state_size); +} + +blst_fr *griffin_get_round_constants_from_context(griffin_ctxt_t *ctxt) { + // contstants stars after alpha_betas and the state + return (ctxt->state + ctxt->state_size + + griffin_get_number_of_alpha_betas_from_context(ctxt)); +} + +void griffin_addchain_alpha_inv(blst_fr *res, blst_fr *x) { + // Allocating on the stack 32 bytes * 36 (= 1152 bytes) for intermediary + // variables to compute the addition chain. Less values might be required. + // There is still place for improvements. + // Values are allocated in a contiguous array to hope using the CPU cache. + blst_fr tmp[36]; + // _10 = 2*1 + // -> tmp = x * x + blst_fr_sqr(tmp, x); + // _100 = 2*_10 + // -> tmp1 = tmp * tmp + blst_fr_sqr(tmp + 1, tmp); + // _101 = 1 + _100 + // -> tmp2 = x * tmp1 + blst_fr_mul(tmp + 2, x, tmp + 1); + // _111 = _10 + _101 + // -> tmp3 = tmp * tmp2 + blst_fr_mul(tmp + 3, tmp, tmp + 2); + // _1010 = 2*_101 + // -> tmp4 = tmp2 * tmp2 + blst_fr_sqr(tmp + 4, tmp + 2); + // _1011 = 1 + _1010 + // -> tmp5 = x * tmp4 + blst_fr_mul(tmp + 5, x, tmp + 4); + // _1101 = _10 + _1011 + // -> tmp6 = tmp * tmp5 + blst_fr_mul(tmp + 6, tmp, tmp + 5); + // _1111 = _10 + _1101 + // -> tmp7 = tmp * tmp6 + blst_fr_mul(tmp + 7, tmp, tmp + 6); + // _10001 = _10 + _1111 + // -> tmp8 = tmp * tmp7 + blst_fr_mul(tmp + 8, tmp, tmp + 7); + // _10011 = _10 + _10001 + // -> tmp9 = tmp * tmp8 + blst_fr_mul(tmp + 9, tmp, tmp + 8); + // _10111 = _100 + _10011 + // -> tmp10 = tmp1 * tmp9 + blst_fr_mul(tmp + 10, tmp + 1, tmp + 9); + // _100001 = _1010 + _10111 + // -> tmp11 = tmp4 * tmp10 + blst_fr_mul(tmp + 11, tmp + 4, tmp + 10); + // _100011 = _10 + _100001 + // -> tmp12 = tmp * tmp11 + blst_fr_mul(tmp + 12, tmp, tmp + 11); + // _100101 = _10 + _100011 + // -> tmp13 = tmp * tmp12 + blst_fr_mul(tmp + 13, tmp, tmp + 12); + // _100111 = _10 + _100101 + // -> tmp14 = tmp * tmp13 + blst_fr_mul(tmp + 14, tmp, tmp + 13); + // _101011 = _100 + _100111 + // -> tmp15 = tmp1 * tmp14 + blst_fr_mul(tmp + 15, tmp + 1, tmp + 14); + // _101111 = _100 + _101011 + // -> tmp16 = tmp1 * tmp15 + blst_fr_mul(tmp + 16, tmp + 1, tmp + 15); + // _110011 = _100 + _101111 + // -> tmp17 = tmp1 * tmp16 + blst_fr_mul(tmp + 17, tmp + 1, tmp + 16); + // _110101 = _10 + _110011 + // -> tmp18 = tmp * tmp17 + blst_fr_mul(tmp + 18, tmp, tmp + 17); + // _111001 = _100 + _110101 + // -> tmp19 = tmp1 * tmp18 + blst_fr_mul(tmp + 19, tmp + 1, tmp + 18); + // _111101 = _100 + _111001 + // -> tmp20 = tmp1 * tmp19 + blst_fr_mul(tmp + 20, tmp + 1, tmp + 19); + // _1011100 = _100011 + _111001 + // -> tmp21 = tmp12 * tmp19 + blst_fr_mul(tmp + 21, tmp + 12, tmp + 19); + // i42 = ((_1011100 << 6 + _101111) << 6 + _100001) << 6 + // -> _1011100 << 6 + // tmp22 = tmp21^(2^6) + memcpy(tmp + 22, tmp + 21, sizeof(blst_fr)); + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 22, tmp + 22); + } + // -> (_1011100 << 6 + _101111 + // tmp22 = tmp21^(2^6) * tmp16 + // = tmp22 * tmp16 + blst_fr_mul(tmp + 22, tmp + 22, tmp + 16); + // -> (_1011100 << 6 + _101111) << 6 + // tmp22 = (tmp21^(2^6) * tmp16)^(2^6) + // = tmp22^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 22, tmp + 22); + } + // -> ((_1011100 << 6 + _101111) << 6 + _100001) + // tmp22 = ((tmp21^(2^6) * tmp16)^(2^6)) * tmp11 + // = tmp22 * tmp11 + blst_fr_mul(tmp + 22, tmp + 22, tmp + 11); + // -> ((_1011100 << 6 + _101111) << 6 + _100001) << 6 + // tmp22 = (((tmp21^(2^6) * tmp16)^(2^6)) * tmp11)^(2^6) + // = tmp22^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 22, tmp + 22); + } + // i56 = ((_111101 + i42) << 6 + _110101) << 5 + _10111 + // -> (_111101 + i42) + // tmp23 = tmp20 * tmp22 + blst_fr_mul(tmp + 23, tmp + 22, tmp + 20); + // -> (_111101 + i42) << 6 + // tmp23 = (tmp20 * tmp22)^(2^6) + // = tmp22^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 23, tmp + 23); + } + // -> ((_111101 + i42) << 6 + _110101) + // tmp23 = tmp22 * tmp18 + blst_fr_mul(tmp + 23, tmp + 23, tmp + 18); + // -> ((_111101 + i42) << 6 + _110101) << 5 + // tmp23 = tmp22^(2^5) + for (int i = 0; i < 5; i++) { + blst_fr_sqr(tmp + 23, tmp + 23); + } + // -> ((_111101 + i42) << 6 + _110101) << 5 + _10111 + // tmp23 = tmp22 * tmp10 + blst_fr_mul(tmp + 23, tmp + 10, tmp + 23); + // tmp + 24 + // i80 = ((i56 << 6 + _10111) << 8 + _100011) << 8 + memcpy(tmp + 24, tmp + 23, sizeof(blst_fr)); + // -> i56 << 6 + // tmp24 = tmp23^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 24, tmp + 24); + } + // -> (i56 << 6 + _10111) + // tmp24 = tmp24 * tmp10 + blst_fr_mul(tmp + 24, tmp + 24, tmp + 10); + // -> (i56 << 6 + _10111) << 8 + // tmp24 = tmp24^(2^8) + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 24, tmp + 24); + } + // -> (i56 << 6 + _10111) << 8 + _100011 + // tmp24 = tmp24 * tmp12 + blst_fr_mul(tmp + 24, tmp + 24, tmp + 12); + // -> ((i56 << 6 + _10111) << 8 + _100011) << 8 + // tmp24 = tmp24^(2^8) + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 24, tmp + 24); + } + // tmp + 25 + // i95 = ((_100001 + i80) << 6 + _110011) << 6 + _100001 + // -> (_100001 + i80) + // tmp25 = tmp24 * tmp11 + blst_fr_mul(tmp + 25, tmp + 11, tmp + 24); + // -> (_100001 + i80) << 6 + // tmp25 = tmp25^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 25, tmp + 25); + } + // -> (_100001 + i80) << 6 + _110011 + // tmp25 = tmp25 * tmp17 + blst_fr_mul(tmp + 25, tmp + 17, tmp + 25); + // -> ((_100001 + i80) << 6 + _110011) << 6 + // tmp25 = tmp25^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 25, tmp + 25); + } + // -> ((_100001 + i80) << 6 + _110011) << 6 + _100001 + // tmp25 = tmp25 * tmp11 + blst_fr_mul(tmp + 25, tmp + 25, tmp + 11); + // i118 = ((i95 << 7 + _100101) << 8 + _101011) << 6 + // -> i95 << 7 + // tmp26 = tmp25^(2^7) + memcpy(tmp + 26, tmp + 25, sizeof(blst_fr)); + for (int i = 0; i < 7; i++) { + blst_fr_sqr(tmp + 26, tmp + 26); + } + // -> (i95 << 7 + _100101) + // tmp26 = tmp26 * tmp13 + blst_fr_mul(tmp + 26, tmp + 26, tmp + 13); + // -> (i95 << 7 + _100101) << 8 + // tmp26 = tmp26^(2^8) + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 26, tmp + 26); + } + // -> ((i95 << 7 + _100101) << 8 + _101011) + // tmp26 = tmp26 * tmp15 + blst_fr_mul(tmp + 26, tmp + 26, tmp + 15); + // -> ((i95 << 7 + _100101) << 8 + _101011) << 6 + // tmp26 = tmp26^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 26, tmp + 26); + } + // tmp + 27 + // i135 = ((_1101 + i118) << 8 + _110011) << 6 + _101011 + // -> _1101 + i118 + // tmp27 = tmp26 * tmp6 + blst_fr_mul(tmp + 27, tmp + 26, tmp + 6); + // -> (_1101 + i118) << 8 + // tmp27 = tmp27^(2^8) + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 27, tmp + 27); + } + // -> (_1101 + i118) << 8 + _110011 + // tmp27 = tmp27 * tmp17 + blst_fr_mul(tmp + 27, tmp + 27, tmp + 17); + // -> ((_1101 + i118) << 8 + _110011) << 6 + // tmp27 = tmp27^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 27, tmp + 27); + } + // -> ((_1101 + i118) << 8 + _110011) << 6 + _101011 + // tmp27 = tmp27 * tmp15 + blst_fr_mul(tmp + 27, tmp + 27, tmp + 15); + // tmp + 28 + // i161 = ((i135 << 6 + _100111) << 3 + _111) << 15 + // tmp28 = tmp27^(2^6) + memcpy(tmp + 28, tmp + 27, sizeof(blst_fr)); + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 28, tmp + 28); + } + // -> (i135 << 6 + _100111) + // tmp28 = tmp28 * tmp14 + blst_fr_mul(tmp + 28, tmp + 28, tmp + 14); + // -> (i135 << 6 + _100111) << 3 + // tmp28 = tmp28^(2^3) + for (int i = 0; i < 3; i++) { + blst_fr_sqr(tmp + 28, tmp + 28); + } + // -> ((i135 << 6 + _100111) << 3 + _111) + // tmp28 = tmp28 * tmp3 + blst_fr_mul(tmp + 28, tmp + 28, tmp + 3); + // -> ((i135 << 6 + _100111) << 3 + _111) << 15 + // tmp28 = tmp28^(2^15) + for (int i = 0; i < 15; i++) { + blst_fr_sqr(tmp + 28, tmp + 28); + } + // tmp + 29 + // i176 = ((_10001 + i161) << 5 + 1) << 7 + _111101 + // -> _10001 + i161 + // tmp29 = tmp8 * tmp28 + blst_fr_mul(tmp + 29, tmp + 8, tmp + 28); + // -> (_10001 + i161) << 5 + // tmp29 = tmp29^(2^5) + for (int i = 0; i < 5; i++) { + blst_fr_sqr(tmp + 29, tmp + 29); + } + // tmp29 = tmp29 * x + // -> ((_10001 + i161) << 5 + 1) + blst_fr_mul(tmp + 29, tmp + 29, x); + // tmp29 = tmp29^(2^7) + // -> ((_10001 + i161) << 5 + 1) << 7 + for (int i = 0; i < 7; i++) { + blst_fr_sqr(tmp + 29, tmp + 29); + } + // -> ((_10001 + i161) << 5 + 1) << 7 + _111101 + // tmp29 = tmp29 * tmp20 + blst_fr_mul(tmp + 29, tmp + 29, tmp + 20); + // i195 = ((2*i176 + _101) << 10 + _111001) << 6 + // -> 2*i176 + // tmp30 = tmp29^2 + blst_fr_sqr(tmp + 30, tmp + 29); + // -> (2*i176 + _101) + // tmp30 = tmp30 * tmp2 + blst_fr_mul(tmp + 30, tmp + 30, tmp + 2); + // -> (2*i176 + _101) << 10 + for (int i = 0; i < 10; i++) { + blst_fr_sqr(tmp + 30, tmp + 30); + } + // -> ((2*i176 + _101) << 10 + _111001) + blst_fr_mul(tmp + 30, tmp + 30, tmp + 19); + // -> ((2*i176 + _101) << 10 + _111001) << 6 + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 30, tmp + 30); + } + // i211 = ((_100111 + i195) << 5 + _10011) << 8 + _110011 + blst_fr_mul(tmp + 31, tmp + 30, tmp + 14); + // (_100111 + i195) << 5 + for (int i = 0; i < 5; i++) { + blst_fr_sqr(tmp + 31, tmp + 31); + } + // -> ((_100111 + i195) << 5 + _10011) + blst_fr_mul(tmp + 31, tmp + 31, tmp + 9); + // -> ((_100111 + i195) << 5 + _10011) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 31, tmp + 31); + } + // -> ((_100111 + i195) << 5 + _10011) << 8 + _110011 + blst_fr_mul(tmp + 31, tmp + 31, tmp + 17); + // tmp + 32 + // i236 = ((i211 << 7 + _1111) << 9 + _110011) << 7 + memcpy(tmp + 32, tmp + 31, sizeof(blst_fr)); + // -> i211 << 7 + for (int i = 0; i < 7; i++) { + blst_fr_sqr(tmp + 32, tmp + 32); + } + // -> (i211 << 7 + _1111) + blst_fr_mul(tmp + 32, tmp + 32, tmp + 7); + // -> (i211 << 7 + _1111) << 9 + for (int i = 0; i < 9; i++) { + blst_fr_sqr(tmp + 32, tmp + 32); + } + // -> ((i211 << 7 + _1111) << 9 + _110011) + blst_fr_mul(tmp + 32, tmp + 32, tmp + 17); + // -> ((i211 << 7 + _1111) << 9 + _110011) << 7 + for (int i = 0; i < 7; i++) { + blst_fr_sqr(tmp + 32, tmp + 32); + } + // tmp + 33 + // i255 = ((_10011 + i236) << 8 + _110011) << 8 + _110011 + // -> (_10011 + i236) + blst_fr_mul(tmp + 33, tmp + 32, tmp + 9); + // -> (_10011 + i236) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 33, tmp + 33); + } + // -> ((_10011 + i236) << 8 + _110011) + blst_fr_mul(tmp + 33, tmp + 33, tmp + 17); + // -> ((_10011 + i236) << 8 + _110011) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 33, tmp + 33); + } + // -> ((_10011 + i236) << 8 + _110011) << 8 + _110011 + blst_fr_mul(tmp + 33, tmp + 33, tmp + 17); + // tmp + 34 + // i279 = ((i255 << 8 + _110011) << 6 + _1011) << 8 + memcpy(tmp + 34, tmp + 33, sizeof(blst_fr)); + // -> i255 << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 34, tmp + 34); + } + // -> (i255 << 8 + _110011) + blst_fr_mul(tmp + 34, tmp + 34, tmp + 17); + // -> ((i255 << 8 + _110011) << 6 + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 34, tmp + 34); + } + // -> ((i255 << 8 + _110011) << 6 + _1011) + blst_fr_mul(tmp + 34, tmp + 34, tmp + 5); + // -> ((i255 << 8 + _110011) << 6 + _1011) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 34, tmp + 34); + } + // tmp + 35 + // i298 = ((_110011 + i279) << 8 + _110011) << 8 + _110011 + // -> _110011 + i279 + blst_fr_mul(tmp + 35, tmp + 17, tmp + 34); + + // -> (_110011 + i279) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 35, tmp + 35); + } + // -> ((_110011 + i279) << 8 + _110011) + blst_fr_mul(tmp + 35, tmp + 17, tmp + 35); + // -> ((_110011 + i279) << 8 + _110011) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 35, tmp + 35); + } + // -> ((_110011 + i279) << 8 + _110011) << 8 + _110011 + blst_fr_mul(tmp + 35, tmp + 17, tmp + 35); + // return i298 << 6 + _1101 + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 35, tmp + 35); + } + // Put in res + blst_fr_mul(res, tmp + 6, tmp + 35); +} + +void griffin_apply_non_linear_layer(griffin_ctxt_t *ctxt) { + blst_fr *state = griffin_get_state_from_context(ctxt); + blst_fr *alpha_beta_s = griffin_get_alpha_beta_from_context(ctxt); + int state_size = griffin_get_state_size_from_context(ctxt); + + blst_fr tmp; + // y_0 = x_0^(1/d) + griffin_addchain_alpha_inv(state, state); + // y_1 = x_1^d + memcpy(&tmp, state + 1, sizeof(blst_fr)); + blst_fr_sqr(&tmp, &tmp); + blst_fr_sqr(&tmp, &tmp); + blst_fr_mul(&tmp, state + 1, &tmp); + memcpy(state + 1, &tmp, sizeof(blst_fr)); + + blst_fr res; + // Initialize the accumulator for L_i to y_i + blst_fr acc_l_i; + memcpy(&acc_l_i, state + 1, sizeof(blst_fr)); + + // y_2 = x_2 * [y_0 + y_1] + + // alpha_2 * [y_0 + y_1] + + // beta_2 + + // Will be x_(i - 1) and also will contain alpha_i * acc_l_i + memset(&tmp, 0, sizeof(blst_fr)); + for (int i = 0; i < state_size - 2; i++) { + // compute (i - 1) y_0 + y_i. The accumulator contains already y_1 + (i - 2) + // * y_0 + blst_fr_add(&acc_l_i, &acc_l_i, state); + // tmp contains either 0 if i = 2 or x_(i - 1) (which is set at the end of + // this loop) + blst_fr_add(&acc_l_i, &acc_l_i, &tmp); + // -> res = (acc_l_i)^2 + blst_fr_sqr(&res, &acc_l_i); + // Computing alpha_i * acc_l_i in a tmp var + // -> tmp = alpha_i * (acc_l_i) + blst_fr_mul(&tmp, &acc_l_i, alpha_beta_s + 2 * i); + // -> res = res + tmp + // = acc_l_i^2 + alpha_i * acc_l_i + blst_fr_add(&res, &res, &tmp); + // -> res = res + beta_i + // = acc_l_i^2 + alpha_i * acc_l_i + beta_i + blst_fr_add(&res, &res, alpha_beta_s + 2 * i + 1); + // -> res = x_i * res + // = x_i * (acc_l_i^2 + alpha_i * acc_l_i + beta_i) + blst_fr_mul(&res, &res, state + 2 + i); + // Copying x_i in tmp for next call + memcpy(&tmp, state + 2 + i, sizeof(blst_fr)); + // Copying into the state the computed value + memcpy(state + 2 + i, &res, sizeof(blst_fr)); + } +} + +void griffin_apply_linear_layer_3(griffin_ctxt_t *ctxt) { + blst_fr *state = griffin_get_state_from_context(ctxt); + blst_fr tmp; + + // We apply the circular matrix Circ(2, 1, 1) + // -> require 5 additions + // Compute sum(state) + blst_fr_add(&tmp, state, state + 1); + blst_fr_add(&tmp, &tmp, state + 2); + + // Compute x_i = x_i + sum(state) + blst_fr_add(state, state, &tmp); + blst_fr_add(state + 1, state + 1, &tmp); + blst_fr_add(state + 2, state + 2, &tmp); +} + +void griffin_apply_linear_layer_4(griffin_ctxt_t *ctxt) { + blst_fr *state = griffin_get_state_from_context(ctxt); + + blst_fr sum; + blst_fr x0_copy; + blst_fr xi_copy; + + blst_fr_add(&sum, state, state + 1); + blst_fr_add(&sum, &sum, state + 2); + blst_fr_add(&sum, &sum, state + 3); + + // y_0 + memcpy(&x0_copy, state, sizeof(blst_fr)); + blst_fr_add(state, state, &sum); + blst_fr_add(state, state, &x0_copy); + blst_fr_add(state, state, state + 1); + + // y_1 + memcpy(&xi_copy, state + 1, sizeof(blst_fr)); + blst_fr_add(state + 1, state + 1, &sum); + blst_fr_add(state + 1, state + 1, &xi_copy); + blst_fr_add(state + 1, state + 1, state + 2); + + // y_2 + memcpy(&xi_copy, state + 2, sizeof(blst_fr)); + blst_fr_add(state + 2, state + 2, &sum); + blst_fr_add(state + 2, state + 2, &xi_copy); + blst_fr_add(state + 2, state + 2, state + 3); + + // y_3 + memcpy(&xi_copy, state + 3, sizeof(blst_fr)); + blst_fr_add(state + 3, state + 3, &sum); + blst_fr_add(state + 3, state + 3, &xi_copy); + blst_fr_add(state + 3, state + 3, &x0_copy); +} + +int griffin_add_constant(griffin_ctxt_t *ctxt, int i_round_key) { + blst_fr *state = griffin_get_state_from_context(ctxt); + blst_fr *constants = griffin_get_round_constants_from_context(ctxt); + int state_size = griffin_get_state_size_from_context(ctxt); + + for (int i = 0; i < state_size; i++) { + blst_fr_add(state + i, state + i, constants + i_round_key++); + } + return (i_round_key); +} + +int griffin_apply_one_round(griffin_ctxt_t *ctxt, int i_round_key) { + // S box + griffin_apply_non_linear_layer(ctxt); + // Apply linear layer + if (ctxt->state_size == 3) { + griffin_apply_linear_layer_3(ctxt); + } else if (ctxt->state_size == 4) { + griffin_apply_linear_layer_4(ctxt); + } else { + // Only 3 and 4 is supported at the moment + assert(1); + } + // Constant + i_round_key = griffin_add_constant(ctxt, i_round_key); + return (i_round_key); +} + +void griffin_apply_permutation(griffin_ctxt_t *ctxt) { + int i_round_key = 0; + + if (ctxt->state_size == 3) { + griffin_apply_linear_layer_3(ctxt); + } else if (ctxt->state_size == 4) { + griffin_apply_linear_layer_4(ctxt); + } else { + // Only 3 and 4 is supported at the moment + assert(1); + } + + for (int i = 0; i < ctxt->nb_rounds; i++) { + i_round_key = griffin_apply_one_round(ctxt, i_round_key); + } +} + +griffin_ctxt_t *griffin_allocate_context(int state_size, int nb_rounds, + blst_fr *constants, + blst_fr *alpha_beta_s) { + // Check state size + if (state_size != 3 && state_size % 4 != 0) { + return (NULL); + } + + griffin_ctxt_t *ctxt = malloc(sizeof(griffin_ctxt_t)); + if (ctxt == NULL) { + return (NULL); + } + ctxt->state_size = state_size; + ctxt->nb_rounds = nb_rounds; + + int nb_alpha_beta_s = (state_size - 2) * 2; + int nb_constants = nb_rounds * state_size; + + int state_full_size = state_size + nb_constants + nb_alpha_beta_s; + + blst_fr *ctxt_state = malloc(sizeof(blst_fr) * state_full_size); + if (ctxt_state == NULL) { + free(ctxt); + return (NULL); + } + ctxt->state = ctxt_state; + blst_fr *ctxt_alpha_beta_s = ctxt_state + state_size; + blst_fr *ctxt_constants = ctxt_alpha_beta_s + nb_alpha_beta_s; + + memset(ctxt_state, 0, state_size * sizeof(blst_fr)); + + for (int i = 0; i < nb_alpha_beta_s; i++) { + memcpy(ctxt_alpha_beta_s + i, alpha_beta_s + i, sizeof(blst_fr)); + } + + for (int i = 0; i < nb_constants; i++) { + memcpy(ctxt_constants + i, constants + i, sizeof(blst_fr)); + } + + return (ctxt); +} + +void griffin_free_context(griffin_ctxt_t *ctxt) { + if (ctxt != NULL) { + free(ctxt->state); + free(ctxt); + } +} diff --git a/src/lib_bls12_381_hash/griffin.h b/src/lib_bls12_381_hash/griffin.h new file mode 100644 index 000000000000..dee1e5468163 --- /dev/null +++ b/src/lib_bls12_381_hash/griffin.h @@ -0,0 +1,49 @@ +#ifndef GRIFFIN_H +#define GRIFFIN_H + +#include "blst.h" +#include +#include +#include + +typedef struct griffin_ctxt_s { + // State. Contains the actual state, the alpha beta and the round constants + blst_fr *state; + // state_size := m = 2 * l + int state_size; + int nb_rounds; +} griffin_ctxt_t; + +/** Apply a permutation on the context */ +void griffin_apply_permutation(griffin_ctxt_t *ctxt); + +/** Apply one round on the context */ +int griffin_apply_one_round(griffin_ctxt_t *ctxt, int i_round_key); + +/** Return a pointer to the state in the context */ +blst_fr *griffin_get_state_from_context(griffin_ctxt_t *ctxt); + +/** Set the state of the context to the given state */ +void griffin_set_state_from_context(griffin_ctxt_t *ctxt, blst_fr *state); + +/** Return the state size of the context */ +int griffin_get_state_size_from_context(griffin_ctxt_t *ctxt); + +/** Return a pointer to the alpha/beta's present in the context */ +blst_fr *griffin_get_alpha_beta_from_context(griffin_ctxt_t *ctxt); + +/** Return a pointer to the round constants present in the context */ +blst_fr *griffin_get_round_constants_from_context(griffin_ctxt_t *ctxt); + +/** + Allocate a new griffin context. + If the state size is not 3 or a multiple of 4, return NULL. + Return NULL if one stack allocation went wrong. +*/ +griffin_ctxt_t *griffin_allocate_context(int state_size, int nb_rounds, + blst_fr *constants, + blst_fr *alpha_beta_s); + +void griffin_free_context(griffin_ctxt_t *ctxt); + +#endif diff --git a/src/lib_bls12_381_hash/griffin.ml b/src/lib_bls12_381_hash/griffin.ml new file mode 100644 index 000000000000..56ef16018e9e --- /dev/null +++ b/src/lib_bls12_381_hash/griffin.ml @@ -0,0 +1,272 @@ +module Stubs = struct + type ctxt + + external allocate_ctxt : + int -> int -> Bls12_381.Fr.t array -> Bls12_381.Fr.t array -> ctxt + = "caml_bls12_381_hash_griffin_allocate_ctxt_stubs" + + external apply_perm : ctxt -> unit + = "caml_bls12_381_hash_griffin_apply_permutation_stubs" + + external apply_one_round : ctxt -> int -> unit + = "caml_bls12_381_hash_griffin_apply_one_round_stubs" + + external get_state : Bls12_381.Fr.t array -> ctxt -> unit + = "caml_bls12_381_hash_griffin_get_state_stubs" + + external set_state : ctxt -> Bls12_381.Fr.t array -> unit + = "caml_bls12_381_hash_griffin_set_state_stubs" + + external get_state_size : ctxt -> int + = "caml_bls12_381_hash_griffin_get_state_size_stubs" +end + +module Parameters = struct + type t = { + nb_of_rounds : int; + state_size : int; + round_constants : Bls12_381.Fr.t array; + alpha_beta_s : Bls12_381.Fr.t array; + } + + let d = Bls12_381.Fr.of_string "5" + + let d_inv = + Bls12_381.Fr.of_string + "20974350070050476191779096203274386335076221000211055129041463479975432473805" + + let security_128_state_size_3 = + { + nb_of_rounds = 12; + state_size = 3; + round_constants = + Bls12_381.Fr. + [| + of_string + "34128550609306794648855049790941029207260430992267281605932459023961690971527"; + of_string + "3266841962043621564976329159669013270493836397698230880922871956509445295589"; + of_string + "3788870321077812693845526449989981219720718862725565790483882416016813364971"; + of_string + "27024891585303786115960806070333703216432373723439881013129899315637778629998"; + of_string + "23010579400464938076910473636770832973813762864914735002621597484262695828622"; + of_string + "27080836131190471291954411865555005238540949310090748858643349925944589708115"; + of_string + "46636255352135029230912367971012168967444546775705654694396288342094186777525"; + of_string + "47133164824570233448088166693080560815816882534409343236711996260986966467741"; + of_string + "9606676225922904172932777687469921750434342743127013317371941417568076740659"; + of_string + "18463500124224312515875567238728244985257614546546778836630989065496961733332"; + of_string + "28472374405620684393423284799834488844243063495131136021015343369044447515728"; + of_string + "35268741564671016498297025103057965141493419622674333513483247896565728148590"; + of_string + "39539585386181717155638123485994910144245090227431714808608221839931008903493"; + of_string + "52380088666150418943399934835814882444841247495734871947668472357102984318486"; + of_string + "19167780327970696990366686602788009806143096819968263495753330062144751042611"; + of_string + "29714551815676515766238911391444505405128697853355881959447373833299714778201"; + of_string + "36137969496642078630737148698387538637943643635849903238148004453205535508419"; + of_string + "43938585519152746565341473691290665049199746016959097846968019008987449858992"; + of_string + "18358508122557898758794573769637081105826061265493116379680758931782412629326"; + of_string + "19946718010959340809909598649820159018638951411545031530449894421301304601041"; + of_string + "31715651356223023397409672475842491549537134647703758287414523885665812932453"; + of_string + "28463446749720890206912367474344537583947071022035116560259967158902287016645"; + of_string + "19352025581521776810257180011278905844311255975757730113854715532000370561248"; + of_string + "23875742116255515995867064853865007839808574907101870889402929799973393348419"; + of_string + "36283757151862211218715445654560253429530321310156361189848584389030038151884"; + of_string + "32575606680762466027769466012933264462659120984156903566848815765316598735927"; + of_string + "47888621950698322446966530449263122446161745917733573449037171624562096639523"; + of_string + "21935782059159444261184801642627906900898586003107206203727898450011376823577"; + of_string + "6658859162075582896934614132443368873283225807004093582364487335761684086353"; + of_string + "25170381415908319602768131022135215671330810111735961551512738905773070633127"; + of_string + "3856579408918104405775510647549098777335403755628729652620891849192253152741"; + of_string + "51071656040623838816910331799254816013392914891920120152037239049697640303362"; + of_string + "35780857593405893371916330187109234255729583537475686449856260508724718012888"; + of_string "0"; + of_string "0"; + of_string "0"; + |]; + alpha_beta_s = + Bls12_381.Fr. + [| + of_string + "20950244155795017333954742965657628047481163604901233004908207073969011285354"; + of_string + "3710185818436319233594998810848289882480745979515096857371562288200759554874"; + |]; + } + + let security_128_state_size_4 = + { + nb_of_rounds = 11; + state_size = 4; + round_constants = + Bls12_381.Fr. + [| + of_string + "34128550609306794648855049790941029207260430992267281605932459023961690971527"; + of_string + "3266841962043621564976329159669013270493836397698230880922871956509445295589"; + of_string + "3788870321077812693845526449989981219720718862725565790483882416016813364971"; + of_string + "27024891585303786115960806070333703216432373723439881013129899315637778629998"; + of_string + "23010579400464938076910473636770832973813762864914735002621597484262695828622"; + of_string + "27080836131190471291954411865555005238540949310090748858643349925944589708115"; + of_string + "46636255352135029230912367971012168967444546775705654694396288342094186777525"; + of_string + "47133164824570233448088166693080560815816882534409343236711996260986966467741"; + of_string + "9606676225922904172932777687469921750434342743127013317371941417568076740659"; + of_string + "18463500124224312515875567238728244985257614546546778836630989065496961733332"; + of_string + "28472374405620684393423284799834488844243063495131136021015343369044447515728"; + of_string + "35268741564671016498297025103057965141493419622674333513483247896565728148590"; + of_string + "39539585386181717155638123485994910144245090227431714808608221839931008903493"; + of_string + "52380088666150418943399934835814882444841247495734871947668472357102984318486"; + of_string + "19167780327970696990366686602788009806143096819968263495753330062144751042611"; + of_string + "29714551815676515766238911391444505405128697853355881959447373833299714778201"; + of_string + "36137969496642078630737148698387538637943643635849903238148004453205535508419"; + of_string + "43938585519152746565341473691290665049199746016959097846968019008987449858992"; + of_string + "18358508122557898758794573769637081105826061265493116379680758931782412629326"; + of_string + "19946718010959340809909598649820159018638951411545031530449894421301304601041"; + of_string + "31715651356223023397409672475842491549537134647703758287414523885665812932453"; + of_string + "28463446749720890206912367474344537583947071022035116560259967158902287016645"; + of_string + "19352025581521776810257180011278905844311255975757730113854715532000370561248"; + of_string + "23875742116255515995867064853865007839808574907101870889402929799973393348419"; + of_string + "36283757151862211218715445654560253429530321310156361189848584389030038151884"; + of_string + "32575606680762466027769466012933264462659120984156903566848815765316598735927"; + of_string + "47888621950698322446966530449263122446161745917733573449037171624562096639523"; + of_string + "21935782059159444261184801642627906900898586003107206203727898450011376823577"; + of_string + "6658859162075582896934614132443368873283225807004093582364487335761684086353"; + of_string + "25170381415908319602768131022135215671330810111735961551512738905773070633127"; + of_string + "3856579408918104405775510647549098777335403755628729652620891849192253152741"; + of_string + "51071656040623838816910331799254816013392914891920120152037239049697640303362"; + of_string + "35780857593405893371916330187109234255729583537475686449856260508724718012888"; + of_string + "20950244155795017333954742965657628047481163604901233004908207073969011285354"; + of_string + "3710185818436319233594998810848289882480745979515096857371562288200759554874"; + of_string + "30288032286013295184960800141577929153144689575967301062487213512439157355972"; + of_string + "481723775804382866461667527988591972945363824626223124260985488775304020142"; + of_string + "24927320031052195697186780138061432837278685332539564079180626150831998848822"; + of_string + "32998900640590419918379784983020973282594314960087846170738034630937198063643"; + of_string + "8631511908740807956134897737056028248340473776882190692861787147243252572174"; + of_string "0"; + of_string "0"; + of_string "0"; + of_string "0"; + |]; + alpha_beta_s = + Bls12_381.Fr. + [| + of_string + "11565587016645966220743989368574475058372014904683361799482031042545234168865"; + of_string + "30671383810635628504609520714468855911284203461969920242344142791585782410006"; + of_string + "23131174033291932441487978737148950116744029809366723598964062085090468337730"; + of_string + "17813784892290133059542601841503491969755708846824405324169253766465967270998"; + |]; + } +end + +type parameters = Parameters.t + +type ctxt = Stubs.ctxt + +let allocate_ctxt parameters = + if + parameters.Parameters.state_size <> 3 + && parameters.Parameters.state_size <> 4 + then failwith "Only state of 3 and 4 are implemented for the moment" ; + let ctxt = + Stubs.allocate_ctxt + parameters.Parameters.nb_of_rounds + parameters.Parameters.state_size + parameters.Parameters.round_constants + parameters.Parameters.alpha_beta_s + in + ctxt + +let apply_permutation ctxt = Stubs.apply_perm ctxt + +let apply_one_round ctxt i_round_key = Stubs.apply_one_round ctxt i_round_key + +let get_state_size ctxt = Stubs.get_state_size ctxt + +let set_state ctxt state = + let exp_state_size = Stubs.get_state_size ctxt in + let state_size = Array.length state in + if state_size <> exp_state_size then + failwith + (Printf.sprintf + "The given array contains %d elements but the expected state size is \ + %d" + state_size + exp_state_size) ; + Stubs.set_state ctxt state + +let get_state ctxt = + let state_size = Stubs.get_state_size ctxt in + let state = Array.init state_size (fun _ -> Bls12_381.Fr.(copy zero)) in + Stubs.get_state state ctxt ; + state diff --git a/src/lib_bls12_381_hash/jive.ml b/src/lib_bls12_381_hash/jive.ml new file mode 100644 index 000000000000..da779cdcc92e --- /dev/null +++ b/src/lib_bls12_381_hash/jive.ml @@ -0,0 +1,26 @@ +let digest_b (type p) (module P : S.PERMUTATION with type parameters = p) + (parameters : p) input b = + let state_size = Array.length input in + if state_size mod b != 0 then failwith "b must divide the state size" ; + let m = state_size / b in + let ctxt = P.allocate_ctxt parameters in + let () = P.set_state ctxt input in + let () = P.apply_permutation ctxt in + let final_state = P.get_state ctxt in + let output = Array.init m (fun _ -> Bls12_381.Fr.(copy zero)) in + let rec aux i j = + if i = m then output + else if j = b then aux (i + 1) 0 + else ( + Bls12_381.Fr.add_inplace + output.(i) + output.(i) + (Bls12_381.Fr.add final_state.(i + (m * j)) input.(i + (m * j))) ; + aux i (j + 1)) + in + aux 0 0 + +let digest (type p) (module P : S.PERMUTATION with type parameters = p) + (parameters : p) input = + let res = digest_b (module P) parameters input (Array.length input) in + res.(0) diff --git a/src/lib_bls12_381_hash/poseidon.c b/src/lib_bls12_381_hash/poseidon.c new file mode 100644 index 000000000000..022f1d1c0ee4 --- /dev/null +++ b/src/lib_bls12_381_hash/poseidon.c @@ -0,0 +1,167 @@ +#include "poseidon.h" + +int poseidon_compute_number_of_constants(int batch_size, int nb_partial_rounds, + int nb_full_rounds, int width) { + int nb_tmp_var = batch_size - 1; + int nb_batched_partial_rounds = nb_partial_rounds / batch_size; + int nb_unbatched_partial_rounds = nb_partial_rounds % batch_size; + int nb_constants_full_rounds = nb_full_rounds * width; + int nb_constants_unbatched_partial_rounds = + nb_unbatched_partial_rounds * width; + int nb_constants_per_batched_partial_rounds_tmp_var = + nb_tmp_var + width * nb_tmp_var + (nb_tmp_var * (nb_tmp_var - 1) / 2); + int nb_constants_per_batched_partial_rounds_final_computation = + (nb_tmp_var + width) * width + width; + int nb_constants_per_batched_partial_rounds = + nb_constants_per_batched_partial_rounds_tmp_var + + nb_constants_per_batched_partial_rounds_final_computation; + int nb_constants_batched_partial_rounds = + nb_batched_partial_rounds * nb_constants_per_batched_partial_rounds; + // we add width zero's at the end + int nb_constants = nb_constants_full_rounds + + nb_constants_batched_partial_rounds + + nb_constants_unbatched_partial_rounds + width; + return (nb_constants); +} + +blst_fr *poseidon_get_state_from_context(poseidon_ctxt_t *ctxt) { + return (ctxt->state); +} + +int poseidon_get_state_size_from_context(poseidon_ctxt_t *ctxt) { + return (ctxt->state_size); +} + +blst_fr *poseidon_get_mds_from_context(poseidon_ctxt_t *ctxt) { + // MDS is after the state + return (ctxt->state + ctxt->state_size); +} + +blst_fr *poseidon_get_round_constants_from_context(poseidon_ctxt_t *ctxt) { + // round constants are after the state and the MDS + return (ctxt->state + ctxt->state_size + ctxt->state_size * ctxt->state_size); +} + +void poseidon_apply_sbox(poseidon_ctxt_t *ctxt, int full) { + blst_fr *state = poseidon_get_state_from_context(ctxt); + int state_size = poseidon_get_state_size_from_context(ctxt); + blst_fr buffer; + int partial_round_idx_sbox = state_size - 1; + int begin_idx = full ? 0 : partial_round_idx_sbox; + int end_idx = state_size; + for (int i = begin_idx; i < end_idx; i++) { + // x * (x^2)^2 + blst_fr_sqr(&buffer, state + i); + blst_fr_sqr(&buffer, &buffer); + blst_fr_mul(state + i, &buffer, state + i); + } +} + +void poseidon_apply_matrix_multiplication(poseidon_ctxt_t *ctxt) { + int state_size = poseidon_get_state_size_from_context(ctxt); + blst_fr buffer; + blst_fr res[state_size]; + blst_fr *state = poseidon_get_state_from_context(ctxt); + blst_fr *mds = poseidon_get_mds_from_context(ctxt); + for (int i = 0; i < state_size; i++) { + for (int j = 0; j < state_size; j++) { + if (j == 0) { + blst_fr_mul(res + i, mds + i * state_size + j, state + j); + } else { + blst_fr_mul(&buffer, mds + i * state_size + j, state + j); + blst_fr_add(res + i, res + i, &buffer); + } + } + } + for (int i = 0; i < state_size; i++) { + memcpy(state + i, res + i, sizeof(blst_fr)); + } +} + +int poseidon_apply_cst(poseidon_ctxt_t *ctxt, int offset) { + int state_size = poseidon_get_state_size_from_context(ctxt); + blst_fr *state = poseidon_get_state_from_context(ctxt); + blst_fr *ark = poseidon_get_round_constants_from_context(ctxt); + for (int i = 0; i < state_size; i++) { + blst_fr_add(state + i, state + i, ark + offset++); + } + return (offset); +} + +int poseidon_apply_batched_partial_round(poseidon_ctxt_t *ctxt, + int offset_ark) { + int batch_size = ctxt->batch_size; + int state_size = poseidon_get_state_size_from_context(ctxt); + // FIXME: if batch_size is 0, fails + int nb_tmp_var = batch_size - 1; + blst_fr buffer; + blst_fr *ark = poseidon_get_round_constants_from_context(ctxt); + blst_fr *state = poseidon_get_state_from_context(ctxt); + blst_fr intermediary_state[state_size + nb_tmp_var]; + for (int i = 0; i < state_size; i++) { + memcpy(intermediary_state + i, state + i, sizeof(blst_fr)); + } + + // Apply sbox on the last element of the state + blst_fr_sqr(&buffer, intermediary_state + state_size - 1); + blst_fr_sqr(&buffer, &buffer); + blst_fr_mul(intermediary_state + state_size - 1, &buffer, + intermediary_state + state_size - 1); + + // Computing the temporary variables + for (int i = 0; i < nb_tmp_var; i++) { + // we start with the first element + blst_fr_mul(intermediary_state + state_size + i, ark + offset_ark++, + intermediary_state); + for (int j = 1; j < state_size + i; j++) { + blst_fr_mul(&buffer, ark + offset_ark++, intermediary_state + j); + blst_fr_add(intermediary_state + state_size + i, + intermediary_state + state_size + i, &buffer); + } + // We add the constant + blst_fr_add(intermediary_state + state_size + i, + intermediary_state + state_size + i, ark + offset_ark++); + + // Applying sbox + blst_fr_sqr(&buffer, intermediary_state + i + state_size); + blst_fr_sqr(&buffer, &buffer); + blst_fr_mul(intermediary_state + i + state_size, &buffer, + intermediary_state + i + state_size); + } + + // Computing the final state + for (int i = 0; i < state_size; i++) { + blst_fr_mul(state + i, ark + offset_ark++, intermediary_state); + for (int j = 1; j < state_size + nb_tmp_var; j++) { + blst_fr_mul(&buffer, intermediary_state + j, ark + offset_ark++); + blst_fr_add(state + i, &buffer, state + i); + } + blst_fr_add(state + i, state + i, ark + offset_ark++); + } + return (offset_ark); +} + +void poseidon_apply_permutation(poseidon_ctxt_t *ctxt) { + int nb_batched_partial_rounds = ctxt->nb_partial_rounds / ctxt->batch_size; + int nb_unbatched_partial_rounds = ctxt->nb_partial_rounds % ctxt->batch_size; + int offset_ark = 0; + offset_ark = poseidon_apply_cst(ctxt, offset_ark); + for (int i = 0; i < ctxt->nb_full_rounds / 2; i++) { + poseidon_apply_sbox(ctxt, 1); + poseidon_apply_matrix_multiplication(ctxt); + offset_ark = poseidon_apply_cst(ctxt, offset_ark); + } + for (int i = 0; i < nb_batched_partial_rounds; i++) { + offset_ark = poseidon_apply_batched_partial_round(ctxt, offset_ark); + } + for (int i = 0; i < nb_unbatched_partial_rounds; i++) { + poseidon_apply_sbox(ctxt, 0); + poseidon_apply_matrix_multiplication(ctxt); + offset_ark = poseidon_apply_cst(ctxt, offset_ark); + } + for (int i = 0; i < ctxt->nb_full_rounds / 2; i++) { + poseidon_apply_sbox(ctxt, 1); + poseidon_apply_matrix_multiplication(ctxt); + offset_ark = poseidon_apply_cst(ctxt, offset_ark); + } +} diff --git a/src/lib_bls12_381_hash/poseidon.h b/src/lib_bls12_381_hash/poseidon.h new file mode 100644 index 000000000000..964bf95e6b00 --- /dev/null +++ b/src/lib_bls12_381_hash/poseidon.h @@ -0,0 +1,30 @@ +#ifndef POSEIDON_H +#define POSEIDON_H + +#include "blst.h" +#include +#include + +typedef struct poseidon_ctxt_s { + // Containts the state, the MDS and the constants + blst_fr *state; + int nb_full_rounds; + int nb_partial_rounds; + int batch_size; + int state_size; +} poseidon_ctxt_t; + +int poseidon_compute_number_of_constants(int batch_size, int nb_partial_rounds, + int nb_full_rounds, int width); + +void poseidon_apply_permutation(poseidon_ctxt_t *ctxt); + +blst_fr *poseidon_get_state_from_context(poseidon_ctxt_t *ctxt); + +int poseidon_get_state_size_from_context(poseidon_ctxt_t *ctxt); + +blst_fr *poseidon_get_mds_from_context(poseidon_ctxt_t *ctxt); + +blst_fr *poseidon_get_round_constants_from_context(poseidon_ctxt_t *ctxt); + +#endif diff --git a/src/lib_bls12_381_hash/poseidon.ml b/src/lib_bls12_381_hash/poseidon.ml new file mode 100644 index 000000000000..b17a39cdd7dd --- /dev/null +++ b/src/lib_bls12_381_hash/poseidon.ml @@ -0,0 +1,1358 @@ +open Poseidon_utils + +module Stubs = struct + type ctxt + + external allocate_ctxt : + state_size:int -> + nb_full_rounds:int -> + nb_partial_rounds:int -> + batch_size:int -> + ark:Bls12_381.Fr.t array -> + mds:Bls12_381.Fr.t array array -> + ctxt + = "caml_bls12_381_hash_poseidon_allocate_ctxt_stubs_bytecode" "caml_bls12_381_hash_poseidon_allocate_ctxt_stubs" + + external get_state : Bls12_381.Fr.t array -> ctxt -> unit + = "caml_bls12_381_hash_poseidon_get_state_stubs" + + external set_state : ctxt -> Bls12_381.Fr.t array -> unit + = "caml_bls12_381_hash_poseidon_set_state_stubs" + + external get_state_size : ctxt -> int + = "caml_bls12_381_hash_poseidon_get_state_size_stubs" + + external apply_permutation : ctxt -> unit + = "caml_bls12_381_hash_poseidon_apply_permutation_stubs" +end + +module Parameters = struct + type t = { + state_size : int; + nb_of_partial_rounds : int; + nb_of_full_rounds : int; + batch_size : int; + round_constants : Bls12_381.Fr.t array; + linear_layer : Bls12_381.Fr.t array array; + } + + (* Generated with the command below from ocaml-ec commit + cd13dd0e984a4eeadd82e0ac4ce792c275bd3b18 [dune exec ./generate_ark.exe 8 56 3 + 52435875175126190479447740508185965837690552500527637822603658699938581184513 + NomadicLabs] *) + + let state_size_3_ark = + [| + "51466596801245350172389236854912648222719187746298709105513845567941180611585"; + "21750751762978437653936573013155607200736969558902465208523342419237410586198"; + "12486517768781903523286807847370218034689963995541894791925792444351839473647"; + "20445718088460789875962943176961386089719184042145123661083866290956184640219"; + "27873160203424299876666416455237485949282512273439804047040763657322096149056"; + "41356063063918478660008355287283031045994439439052675999621074603564345282569"; + "39339901461669097862513996312696398098463519178491001542393778258774347097156"; + "9204042589329629203508256352213922752007565761246017599071231880772962888313"; + "44872792620396140616818721079703154415798612187578057809815607666928058754777"; + "15937726977018206908966109373834056579034465379649731865901151172854062328666"; + "23605712034497375740219228439343452998072299839093594319857450624289690266228"; + "6402638958817972947806346954920050102512724107777426591914400080844084499349"; + "3185239264644999224390913018332891687143438328474986546082170376396564918303"; + "8810128481422180179093610800905689707749830921384041843188605671660723745224"; + "23856254368860098877925830552890800356559853619873956523749705505858453741419"; + "24587049159258135725439557767222187037564112044982562605667614163816312730472"; + "22837536766890438293232796017074642678223630893636795777506185541273623237047"; + "9192015516308615812149895996678356120602200776491327365416854885711899134185"; + "4002652916865493677251257166117182479501804845054999793592382685603350748223"; + "33066348252219459468552045146523238597048287748451612668563453612283148717787"; + "22032405802641325275844419284045173476338377422793990841002770933934147271753"; + "40810499016480900907962993830032852958946905562531549979714594924288595159449"; + "11360048753112901991330610389408512769078774607723790648797196048769123341818"; + "31073120699274505130875191050788584204810084807427992815212547386082177411939"; + "38905424489726634595807315824887707754301482341060164517868666848234609856296"; + "16437589687938886598993201288686198745024640875414943299079721648754955896524"; + "9246415141807177921760679831767807305667023086044867913825908258624135672402"; + "43267134335847210508826260454424281515957785150826503791438907274325277067689"; + "47405994765042204778087426457971662098880376129631959037220571890293893837627"; + "51109501544539159334717344833663305202169784719089645141283241708762847921831"; + "28367352686904931835510258483164340654232741901091990185726515423922311395266"; + "49750106362878302307560487257360445042628424171940583005315598767946030678175"; + "45959469784902653889236043731939532829295000363517367441618551318205534438835"; + "27018375398598043392768159138944903620978890067620474698695220978535490993662"; + "37680060127197925845671480407334293104013784691230898581176604640776871595820"; + "10072365749347322273683640976003223868449058525371389769456254873788829510856"; + "5776958426313577264021166002700070711779258526703552908022966622941040975486"; + "2052552766687385987890760301444512953288614090851121718631539540584797743813"; + "29589973335212398499653074528975769763663217998670026908669929887809390254086"; + "47176517056998440790693968750261830775359488909857950144871025285282622331205"; + "4044841108655017183998683299702141262167457310115051178539772996106040315055"; + "23145769961882962007007503964681965122021931165884937363089732236563915279899"; + "7603705117156652453963281055927587143772971225944827219299824918233735396544"; + "678587461188445034628596985861476825212606316443632929982806452029635142763"; + "43358198653600383869329744766691886425670686115842008451706594321104589073353"; + "29783989749004381558893964246285207519677877370947641650381151227672399441258"; + "46788814117768703246098518443423934593855222525287642802070140820481989754464"; + "47667240567568953271881931068585333300960463653436442752666537199724542862209"; + "36185825409915459203448245743109969343193138020188742950229819419575178293681"; + "10268626031678681962519788038923114866365639923373751230918298280203944789089"; + "22423180878570467317830579782624040309181433514468470079452795926252301501451"; + "27854213599947523969400957712485981554578482677686500615005910306191690675548"; + "32552238758912415934584820719305968737837410579067602670579118065160652867044"; + "27524020150199858721583983985008046355789957344374031640804833804334599991125"; + "11598691035533751109698164453612171297192910953856758972631340412485692367245"; + "19240281692025919244580609351663678384250073443852130798436970816624877123792"; + "19081743524319516787728673230184684387616956386482784328031473187929184929813"; + "13482824733237717061443533817612030042881142888904695925365483772570662398419"; + "24557586779364722370887646696339785224219486745231704250023468368642112077961"; + "49132695885737549819731989839786719093658647324506783818463101428078920152339"; + "47598003338017334595631291432676651103981450315484662200923020856309789617505"; + "29657580775158274893108525946918168971159316368647847989798236676167226124425"; + "2089871173039090298283861039787654594553968107879556266696645874401027551594"; + "17062674176584193145991964541286296980632589397952567044305875706903816798918"; + "39759050960205479940159986279409353005846424612008117451162722701140967479478"; + "22533616828186323521649895181466155821530425549183373709986149684843468562921"; + "11710329771453525931280127059748492796905639784050357470339844149929022650252"; + "28382230089609321965313624834250197889691846195285335974753263997326737343307"; + "17483468269617424580234048407267881623433885539437967900597355348779845904370"; + "15393678108977111939937458813237466536883800502542016725609655847312425800060"; + "35335672469945182745009570081451366206953223954844817103347451918365408472583"; + "18485543557533557196522038987860777539645907448847172084578647917456309932838"; + "35453109551100805378496992884404555281031142908343718145992408005796255932067"; + "26162388899534531304185889785161995414351042512495564813598387581820788701274"; + "30513272868498004256565910019709317337704607470343755267516092336967857454429"; + "7482438077715696595671300257575441576458965352889636767368860652528296466835"; + "4420972756750713378268292139245553512010082345332818480344347760992140415579"; + "45443072118542869094106210430408632401658283491040846320908484790994846489479"; + "4587498519897850005501095589592009810295823998176500983502979737014704428427"; + "20140268669484747984769809200637802968551617462409085249909344252279198873265"; + "29246773006012167464394782413277073922652993569428539217341804135677142314734"; + "2090453766635748262896094182234431405487694916721156619151573559829565285658"; + "28154797511075990999067437210883725325588221412791352016549710458849851400443"; + "7437576051454980648324143413673447321627481635285743115910231258907952681902"; + "47849325109234284589063376275405356989691773872687047237532536232042052359483"; + "12480987611376364480590099596287568108053904335043512585655935306753098846056"; + "35282772152784155873872416038091486728018085424598473101796189937824691931982"; + "44644309599357388823648910637703362148932670809274055496007925095230623381923"; + "40669859985254288073391010054507859022800795198091698303895855303568474914724"; + "49443653278257139506363224578511517450965492260748531903735461532886298470324"; + "28151927370999705099548977210331844092002690574491843105417307465011218883372"; + "1645107825636563552234056692699842524648459238860722695243162269478817742307"; + "20451009040028965353495911802150535366781462589345362185312598771266505204706"; + "27819682514111647266735378995664843430901566567232355462928465778589146617300"; + "9554102125843498587844759244118187314040788045621020914785690475852459244712"; + "19166777550065260996957117606165528594010042113228133002376856047908024628860"; + "26933579719124735456146556120749918059938219375765953757687070745926421730690"; + "43664899352313137143462906778788854871017052765412139294077435721003011363428"; + "36173458814979531375880943417934798141032455281648386700864729797402421147643"; + "11182517313384645430276258135181995604973901045769946685233925860600679925400"; + "18957585496621103259998572202861039692818169581041076732942953590132787413185"; + "990272065387976234207571590743065697998566272630425704533408985373371347703"; + "4566865954002478217870742631824891308061027453183663472158387320791808636718"; + "13275080024861611833879690760787568594881779009163813547717517171800075477326"; + "18280289328587924651942995072338785526297904605272226018248763384856128538194"; + "37393719051038483957290231134622753224758957341736360150179478705995454183736"; + "35471769041551236267108986169916522221022951796087962631717489467967242728989"; + "18313615850921029128115249415256953514199920171298188893865360820700589880640"; + "8649505551495013773478550513798423370916587725243242103915932173300802613836"; + "29426595573001164623970767658482684730540336753851606403197168017465308935012"; + "15800050789941506886367343947552537811144738254935176866599264324633404561668"; + "2388599729796011963372654009792156200311446590133223685676648683498130023426"; + "39710359146943858258478963255479846071237665235335480449874571631729609456656"; + "12539354052138844839668649494440055311612800274194314682724519322900896888667"; + "34775703808689652205221353219074769424059692664878491357308664495453361798542"; + "16602078529355937689782643082006360605957411241022465529030420514355243740084"; + "20279850236027730246187137397861434992518721949131469477063849268012331913542"; + "20700406847766119075096991790226756382972208779794861885683190244345925948772"; + "10767548586122669600841175107605340206307369812479898137983203022752955229420"; + "33780485917217277294437000521052335973598541648381872358473220524753392579944"; + "26053477836690449767759260916263153231466698419416254714069016291032716493795"; + "51075719579296898046678332991810264442802867440545970415662411469944202971572"; + "44425065795172674272025431261784423304992373196100933574446818463450861237636"; + "21673427825228648696679367470878911746787913779734335379612724957949663438503"; + "39500036723407342733895180253912956707996173847799994738506003893694134507820"; + "18814390742264124557923083818518430926773544077233525827507879093955534745943"; + "33285136419882565391925060802949863649369447257963104257237128389534667335431"; + "7242824697084765204242498009056108554791055701454269759053340822841847843590"; + "31173248312673499793759274086904799638353536404479301039538892557122201869326"; + "31186133094427811821728441124091409602329280228993044467507339271468902426067"; + "25737910716320624211587760844165755540380223663083209047341376780006952817951"; + "41007486903540773766178646801963663835738017272207371664092100665995867447476"; + "33733614421653704619906981612465553433605639878071728634533669588152171336923"; + "44508002187727655261274038726582531821774653664912931880913651223618478524203"; + "29308206009053294442851242412693308913204908282227130202504576346803290538114"; + "37195044959073314994498067496758410674853446343706809704471573374824766240756"; + "27750290920151880266415654177442693344449343287594569254432923001134909857161"; + "15765188586172333129026261765507777427830002956246082548695725135386026089531"; + "1723567911352974656239983052419150859691079784042460780666277969900550546629"; + "32624380698163043349452348170080919066187676495607088889037247382764371823304"; + "42332347907545864823851740450059178607636354773434217763190376183475294814740"; + "32851187296571784166842016235453193261263026420621113443940941911613891853263"; + "46515450218610398244495734725817662625773300495752440637456039809680716524335"; + "48802434618714806701215020572358407402163910104929505500552346872970874445024"; + "15041030433764412988626541831537854311766371887970954109236962491586466599144"; + "24914207471851043784197436527940466212674042052967065649457499415892446136159"; + "9071888319763577380151443506898914744736366395870413605185856133895174517345"; + "14324407136483074978482942921602872905704673210914714962854893980450386451889"; + "29042406409942557018444189727617456411092110677398829954434968404039936168367"; + "45298132425441112218235385216467264374863717020516284112024948473015955374084"; + "5848266257013307529285399749765616739303579930676051972945621978827280728485"; + "50258542824814649118248459254788489871100732773736051031417014804244168803608"; + "2211331518382464997157173039326358398024782525487574099479995890254668498248"; + "25495625009683093041292487489064498029388757676050435379647316032736436019034"; + "1673456300079357795623609138015785582077169647352697470259283949067483430156"; + "732875001458000671533092091268384759392197266180901126140125986324726970217"; + "15937486314053418275659636264513684188072392679031027560851186610858143116536"; + "37523979262473761872442642124630377368104280370382009467506872860620420272028"; + "1463301537361190248611634113301833004506917120571380701549297040601288661632"; + "15388046866006485479772795262309796656931214897645470303116977773763549826647"; + "24820458677922696742762859449292673635627885851532245057181102097543570979209"; + "42204379350085294410776773079715228191662735656426212256162333812793552403993"; + "1195814176795714164840835333744966813414161441324551406851397366147530373686"; + "16761973517502055324144398018035682278752429331149035356778515867109688520079"; + "5794935406580257517632452299232288835369749493148532249516641371649010994761"; + "28489054235450115341655557856812811692903805568161190542887091508558194202484"; + "46027667092982098207528356294714952530753544394086856091550981466630371723227"; + "36549545461270844973100848885411892468389487357334958172813302441582453767995"; + "27730798985447029088568033769773024804917434212093202895074054132301610442265"; + "30053494660111523933577748614419372203999341521131288200082766152193752930915"; + "42669519840379176591693261573919152190190830699417113996773900230897690941207"; + "40491463463369636128381274334600090418795787105664137021554873372325496120497"; + "37855317198077808209359933009653152621140711928666934200968394018548493650684"; + "30289339203582770465154470558134566153982220926251521920946038335272057457401"; + "27778690140622310321003540914723670899734999136798303644913768708258653156597"; + "3973394156719142858738591330892034076809261304074876595400530436577715032673"; + "34101414891901169069858357639409485174940075127343413252072373211617833012486"; + "24763874711353584430968413634679742313122411936945926412259875031351381484206"; + "36482519855965638025925823411871352935082631497149119671124638993468289313858"; + "33663960240182462215313666658229034428117630528389633368925326911863733915779"; + "24156616496917756781377614606496469046971000527652456728186486373912788616012"; + "17862377433968409862537980143869608526991820954912158743675488121333401401128"; + "9883166492675772730546061809268489723031153354700278026721716994418744028520"; + "651720966810612228203754272949951577724164458606405611640617175537862475287"; + "45029571820041579599811835408905235857907197206303946042784264756752149312055"; + "15218138019507525985285504884751281493313515412230279354014712290617793064643"; + "7889502179901137713876340968057633612399550484642109442993286207350478652780"; + "51114781021375925510384757787309929484526957562759351412663650152039538436129"; + "49153605396638540179308253872425727518164881509781489770081628829948751933325"; + "39446436805473057234521273352946756590838723177719005850741347955181052035907"; + "32522116151199401996556140465344290516461661003004520182401454275644784968841"; + "35709586671485611381280332540710898003892567989895109778435218770617343891091"; + |] + |> Array.map Bls12_381.Fr.of_string + + (* Generated with the command below from ocaml-ec commit + cd13dd0e984a4eeadd82e0ac4ce792c275bd3b18 [sage generate_mds.sage 3 + NomadicLabs + 52435875175126190479447740508185965837690552500527637822603658699938581184513] *) + let state_size_3_mds = + [| + [| + "48527463322097587091854420767453816291840635874249958396342138881138912067190"; + "11996084473350366483175782359948025962778681837397784970341328014763133439499"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + |]; + [| + "43372445583202124108992832749257195116898314930070456682841601188523728879167"; + "22957843818027924237635625446720638788994914691706001027915412076310000455035"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + |]; + [| + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + |]; + |] + |> Array.map (Array.map Bls12_381.Fr.of_string) + + let security_128_state_size_3 = + { + state_size = 3; + nb_of_full_rounds = 8; + nb_of_partial_rounds = 56; + batch_size = 3; + round_constants = state_size_3_ark; + linear_layer = state_size_3_mds; + } + + let state_size_256_5_ark = + (* Come from https://github.com/dusk-network/Hades252/tree/7a7a255f6cc48f892de5cf8935b5264eb8893852/assets *) + [| + "49485629590707188350627438543790601843164666730832802354167700559078990180805"; + "5252492454239988725999362667606361246537049278449296815482681202241423199030"; + "14618464101860214640501669418913406667488798576646720991952572594257377039502"; + "49620695691812425396881667059975042814057870860951834243048751692229624331677"; + "52370272705607335752267236318243264940083827067691749458235447563501832651257"; + "14710933242610523976995706443397757945742163741677668728466445608487118981880"; + "40295605676867759583334785789872476122167378326657237878145663333439589007156"; + "17275250730668933226474210235642934004873625116556680337206784052264566986455"; + "45633796471806275582583687299302600425559632837704148321307522586100540673964"; + "33681130375233352141656505268473716952957296224087839911967969212184713588195"; + "712629851673255722293534395801485044243728655856788348424319702704859382351"; + "43317142284252827604873495043870647060512975769565878032083607834275571303426"; + "49340354054830215768241644525595586576960916648952093483202539768057155695733"; + "51072133689923992485577335797823140838583096495379330871465525854048879509188"; + "46949696588385743239566882413656461741807666921366097544593880485391490027378"; + "20573821191096550126141597782760949856255209170402036553268647563825526870436"; + "27160407187556206874731839906107055583040719055315009650316032986707542736994"; + "50189849422262643653706645096664834529407274784147778804216234124791624405728"; + "36711845592560022607016872007330968632549815256229219571331231734465570541772"; + "35499690369690524959345453870997264497352033723668303049826986491601092626610"; + "16316511810555998552036883529281049006950270019860246764897773268401228568605"; + "24273505785788709750944619357321960159456240163658175721572690190239573216897"; + "38957445901173225235458499674711464149245486205504890531219786468849422975246"; + "11823467170230054064490275077272871963881914272709655957174399232209364647447"; + "49592360594196231864432308576338740596601726416914181276008583207908643556097"; + "3309012748654570967607135422003010755248166478871582757366403846071939043322"; + "28008997260349091544245311173997512340365040670749744770222988406313503293844"; + "7882946347332999275161185525751330966422116178677196163170258809540423320804"; + "29731010687109400386993771800155774620735785970162866907509352726525420687486"; + "23931998959081617445949503259792788311676984957946834382760056406764899364397"; + "20391484046421688653112911850234570788797563186823093327188237858525889539247"; + "22656719734855634367860470343411809786356929276974263964151006136177227714579"; + "42018013924524453942303746320960679879055521221983992010530880401352394546138"; + "34997396324562296578241314578708220449054628732531003841806342137992978809863"; + "42567292638455246337550117708556510507190278048736836413208545981863780856831"; + "19529288884212474725617121011420109083719176084042307000138428649194091920639"; + "8327938075667211716886168580211869181679628310891241396086663868161241632320"; + "50546778806178535468498887210218810106123307251791580882247524421100294295341"; + "30574977411404820333239918514944667200338902645085529348563130262864324926217"; + "9892903275194545714737750789991423957405171153621887382923972196579113423179"; + "4920577323034891968079586456848977110594227055454553465331672976737322470181"; + "10785473652133501829555600968223966606682909992869608850754498368109405959958"; + "44259656456536904544779434380762383481009668840670964276817234604369847527532"; + "16013602167551971824719708405514957436426476815028708803379542465790908188145"; + "13198374304416209263916195294139003986416471192907786718634040648208496216781"; + "21804530702651053682928092693590400484720275112701610945338033348613546128300"; + "41258400074102294032881307279891022609951591773444936556013171377165772120999"; + "37500410649974720689109041933579952412448029290473291361854784961766576368877"; + "34335673011929272194773705817147158647851634047942272296257858433783818390462"; + "13886304004325070507319308017925418279796532347344964674118255936953984359681"; + "36212245366398184116212011743173706647869616792063869197638400841024375748712"; + "25759006975740081144269794348054803069434307735185793664670622388493509618893"; + "27454141834179019142193646102488261892878322855049554559653828601521710959492"; + "46231413498972598224538743321743754536555738713900369992799611667660505830198"; + "12831308687888044138550325104853798541540822575395885697883589148652582777980"; + "35086901484248977088412788551567969916605411503392381636519644581735135246639"; + "6475115432881146883349186955429401720007995218321780836251063967786164777830"; + "8814580017771885006531117758255250813668411043820855097899546270767102414310"; + "7807296524174932448970457695754749231363157877776562676221113586348272093145"; + "42150072600290314522584934838938619527057217927054115870685066610015126576749"; + "12014531038737162581705520180807422015561278346762069046014491217217393623145"; + "19933331143038021192464408343147972121326092927465949610356498707738693905912"; + "48162370217774420152062014238018799880581373414572553684036906215372618932347"; + "40819852050845908476800605687008690729086125750975079926804162995170273045987"; + "22226594575860551577968163846926724696603097833150589784765199214152339318359"; + "19545194169971732111027157974516008318207647066892354069067261444231038348510"; + "6049836141434740667284236008114543106249641546035952601692539242914716493120"; + "6791353070942758297826333323115522110180828045205749596445149910757953314373"; + "29909049992012855058485881696486638410170793566701289014595505025597038675406"; + "37049050048958384299197228584051152045340884544932681109205219968133691211039"; + "8271317962040216706363322101654508431702987030110073352137002798152913000015"; + "1670774897775895329767148809679299585171850878621026134776642441972236794266"; + "17422031471600536376610034591163807877753208015405398182227178552347096580633"; + "18756624022690204397552680734127650080255894251074233287591407798661854030530"; + "30668115702052736591929919340014079888097509113980964494205188093038881676393"; + "22070300308208791796677976010650187233479496718840088914015812675958670301234"; + "8719223857171626532277312086417428648729460205529882841381547602107666862130"; + "37958249804564731124361955041894134137282950000798272227069902229038293082676"; + "37189467966805221844845186538807960819299637527099935959247421905494814306365"; + "21466607532037915848310355716841895751321958036985554994122512635502114704749"; + "14179699035342293451307513028958516816541083634684431605407839181393476104825"; + "29154847955666596586127425042717506047631050595585497722311215198569277732248"; + "33188642560979777145374528795549704783805148120231153611600332204665631092317"; + "42564521923637471405699083052532506872185646145525237703447984248100308540906"; + "9688958844450335307002049478744008486071252176234867674338843547336023975670"; + "42848254690746470199841780456337093355003554479162355775109612541732121188865"; + "26571650306498172537015187191960172565543217489415394043243003022941239501277"; + "13259263851666023894687861132930820553832823620306352930622248435429243173163"; + "14935311346095148671867793890923330605843422232075508196436807220447844613370"; + "4344538561671100537571115284147321749241294067305664704606142724262115973132"; + "3661287306275145440306213618539663151346918182078062211644897084121048254313"; + "20823698858703001283317436317010639863721597996546476932310242177301854267509"; + "29589286785528202709772071088244026953664280695981877455063175736821781541694"; + "14714810814119711606060345652389090896596349569507164391329166387481498170325"; + "14212678415151015135383112231592717825106807730018994977285657694049579298318"; + "27294817345129277597625121693563352246269025230758913013178562651622515976209"; + "16308958452953063563921495978976808898979645896736092486449459545961496250858"; + "23801416487202359083498068782586588131855222018242538192997207782091276206860"; + "21788204341490442112154345605131469142633618445779895292676418878377458001839"; + "42939889385890003399975992564558390206777324067014435789391978812483943473084"; + "18744379815502146842706137175625169737619118740225857671323003521379145620839"; + "22969419294986037114832463860692313839911009856023995119192316414140491424064"; + "5158048168028926443440685040647048915854092072898670428607816727103222084992"; + "45436514015774807133067927806141304958513041619855877603424280662728885659666"; + "4148575853437187976059844949320814090464120728486411120676443836675361156433"; + "39274458258755370051287444400457797244045933354561090576339386851101477414906"; + "24226038446737669899105084780102219021070008789681262557528873238824761650295"; + "45554128757216009101367584501852978682053416379828133489710853000149481226345"; + "15468212483347652283360923936198282812982215187267560543021929817615478344667"; + "49120785890340968057046175708683790395194430243216223332975263066275757413807"; + "22165820818885004643510856850784071522542800536416499851315809803527220567485"; + "24255417733013943695455694074510916498983472445769012245738544215443095625555"; + "3578717881416756340877516666877448995809041970558865616428083782655188854064"; + "23826341091172689336238927086223180009822950998486138608038032100061694451939"; + "27712967780178175030774348740828282622058332263075474167028713006452109351081"; + "10692520630891410810882731879436263881937079315958040076096859309741666181887"; + "4139611615212690436843419488530338015260675471298926305839949926237319638064"; + "23893117338530655111858176000813570070168939016669641291797989062978619668263"; + "29493430044283825498112780304231954297919106956762292987523773747600907821123"; + "31224696921534136211793606269507101328026664939270273541391154325809905983477"; + "1161990788645954276916059640768435755816955781531340749166719053457102674329"; + "40032672466651019681467480685414198090289911817277735486101335738870038918838"; + "4663929628087510457582572341889343283250798458980128777564503205493248261588"; + "14576003601768386193074498529707218258345393840871241657474970275429765574440"; + "41907905377583342345509053513634246064531351674075011102250846877938645814680"; + "13820230842080821315141850957892243677733920498405615643268916522170002600281"; + "19848873264729615502674527376791162181860225160995619982736986062940458512804"; + "39528445680729025348431669264547519897612726406686606338168880578253680155174"; + "3118432592224748465457531048962416120738464253058324843908920356643714609755"; + "20291688884043804174664313901962915383913038845115296389312218366129420572704"; + "42557007757415638497613471685612090789101153750789304616028486221591259415030"; + "46792197373741062915032927311079971699067950253133746671662212783669451417489"; + "4446326402184357086836436163159453880944166545117770668456616153083342179625"; + "28708468885765405820890561098801183951304364975777439218943183437220558999123"; + "36301422605515541288198992288053820065278318287890213939282985302088469667626"; + "16513700588570500247891971462860214234891585098734807087134948638523417237942"; + "51303521335085563665906206982117421593801796082688254691383972540879029269486"; + "38349748912024833254388160686883390837675515065069293547130880253459258191513"; + "5863602768144479058589215618670066402672112266393989291900873801213554123005"; + "24816851569224726654303407018916136914696378461182187828394888509457202905452"; + "35668217636187023661106024284393036487257457620610684950679976695467857461614"; + "18049157617317886186455739291622755056587311439504905678793914609021791583485"; + "24311184582337406630675921345578587870745539726250911563471149827579208380375"; + "47049171163587328805804625147855798309518236528924756379359079671413806548741"; + "49217441966653616354960566046394237511933307451264416176581197097030607882249"; + "9741440763223308622766088611912800832840447253106863229069648354711337865316"; + "6711970275005184765958920828167320253630591665126522378985833259053410800609"; + "9977417151377590543160871053129520943830884975635063831123262229069994513327"; + "3082837542990263750321290997953667039889961622919749500136642256407112034669"; + "44429448918101910406096079124013269684487142109369137229916801140750864418243"; + "10204944711013435201457808979370927831932282339697033510029454082329887203672"; + "27567961079029968585701667459244395330846299598586490098261597725737547209132"; + "17092282981739153700626134625162471407726486372216667820609932370888878727413"; + "31485584271040282956654226763326588049877825728467428926223647874479701786506"; + "12955442244748326703021715942574723118787276791607410352602368690534050770417"; + "36233598404262020873794741863731429804608939874302234761885447289322137408181"; + "17365032709923238164430981278878270324454980279560841069445448454199643029113"; + "1599308425815788479548362313813963333016792520742870977461515191009005920540"; + "43669871288596037415496023789232130242903264831017218631867709702917757490026"; + "49117721877014812477333148166335201583815489936606800780714317383158496433108"; + "50780218530638944533890976760629911189324354866670913408371520875375844233903"; + "7689428494847004464240529995304510607351514709716679690600711591096978491670"; + "47955977594669526260247931440322469685056949069904259470080759325035295286461"; + "8365512332847242169003328823195689637827840697541204265356337650289585838123"; + "3840401128719370383692078279691168408796656116885154086592491099204611073383"; + "43069581936608602226405255629351890119646172590162211959289288774795830286246"; + "43974189709355209820476462362097537404927792511028786194043940929898183793414"; + "26332351117299179629573047197679883935341765313312089900660919650133476414458"; + "50351703458402831605416039704608408974892592655299422309480445654414527175979"; + "33468607565896128905680223110626886234307943229683243021379890835118051012325"; + "6614565191349098977235002226407314032868555511403717887772191274612517181410"; + "38103056918801597643212870363828947832437506655680421481428698964117403542602"; + "32908423128582779977704279934611177327699184469671505430337832556835115384573"; + "51834951159973764105688866487621285182469090830458796598668031091107941720686"; + "20906443585217694636590360222926761090515273711034774487436003326403616929638"; + "11543128149317521186944038480148089876167062819998754661365448516694779551074"; + "13337387009791879577397425157695857206822652677921492812658909620421271792366"; + "26158663219738110112661733659009555223590055652836643266081611952515633330808"; + "16620288606563676461349358549564125077202861312536356779066223457462338103688"; + "9370353560216700598486832215289311328374345394195634955453105798486005404415"; + "33633718565315235577394971195804503457415899433434050508477479187227057261067"; + "22882449296374811923033442799913069323577656681081909852574042775892111287921"; + "2940185604989639101256714689859475930684457088567484617894462057139075862941"; + "34483194121915222880375114276064125544128032137924712006849489977876279836276"; + "45372384774901078103486078987247871000423060133375498791638103398927924400835"; + "52387604781514376107006295066270649568927674910028459430830457444029012327788"; + "6167869651297502278429690950623450349205119487045648580978208453778184411341"; + "27462497275790959876141507254409980360566911339456621474224385082554805533038"; + "49147087543811949479056383453491986538702256593160239527509029396813090030404"; + "49587001406488557808406328288652991476747338395266693648839878008858484697835"; + "6313958677173548204879553757285379819254567579081576303778677143280554291690"; + "5591468493874061488706454796222404166033712948542307967483439147905003945470"; + "2437221293824201160919193686511276517772539907794390113067425954677677410182"; + "30357986563693269312610963334150804237408332248581737751589214609304706424480"; + "16637601486751396636529759375224983522742599069263721097214299703128247198523"; + "27879534340144216562112405598077066811919674403148810235445326156746715979842"; + "30788313762153313626674963316612595454484683342245093445515009044754566899486"; + "15725387840690796443588540099094119524389569177620500091843845820844320431289"; + "34132295312326003636265296299999208396694730499866986050666477793086157249908"; + "15362934941085533070255910138373084570641154047840765685532551420580152655609"; + "2755137135618857778067513724833509904536351561976592574187101898503219001617"; + "46622911741851631588024639842856120275465416427660592975008281197121795628830"; + "6964635240711037051215022604794208273817621384886657093402502491567294160845"; + "25783574129877826155110663698218382830525380279909999762879880818546978011140"; + "23465315121256052707655414720713957672069185881022798701424890012062179540328"; + "14395053091536499765531983402867839134341617705786295303106179101403117403050"; + "11316253621114442899553787480078181551163062516697851587687844977545722300558"; + "50064661939091922013762459183760659158315803719176946262123119222324910530256"; + "8783665334345037843914454257570704820761444130918358310108843988258662584186"; + "27618475988876729519248024362417979774716550450998439569984942958903150185062"; + "43015769169394210865366119150018957649114200451714812555830871262755495468016"; + "49732426066558397245060256272342911170810452758926457010543502425937044377044"; + "2952797980452813888623715400169643543685112681184348275283000981057872198778"; + "50872740372354623466916457669382604074806324513038750478426891403283893655073"; + "392818184515825854281773563914353854398754713238832910269587407972143774476"; + "50779005954836595097541637958107285799215893016482426373886980746829520936350"; + "25176357246579974791673072598303068538657314197431647903881566730654004596817"; + "20248152184837592885327768689673131083342577141215627095954882454724068067303"; + "30064303728202536588603791400844418739073552658034934314710159102990759896158"; + "21384606984835160613401783081720653002397794837776744119212545320680659814207"; + "22759565228734648282413300371375307271924944352100268152538666537290900864554"; + "39429333593022349595681621998820719879621843929926124877175561019165223081129"; + "12070092883346592852789463918508042095108508741001381953375286128032289075905"; + "33289517265391819899507145162086978987916991654940411189206013329200864859674"; + "7221597429770981330375263241511499043705983470816845272720562845158859285226"; + "16638272235182748474572289194344411365650205299005022442793882687465898549539"; + "36006214239196604148614442091188440583481038594995316939593040856887035358617"; + "25792600705977450864245882132395859611441619832808864344772519627069798329604"; + "4080552845447537437568804141996338888821838801402604114257764603164350512676"; + "11798208445675100720061102611516112959643834415640440909769995293901688418811"; + "19858693043126873191571109475227847243177160525403793202276277722982907002636"; + "51792167109522919038849306964270342579703542020877440269381030774505714185697"; + "11631710203663443472344988456889389622339025983399538662094459108486378805525"; + "2182473716255059033897861691447270412333028850406831066185078223238986325112"; + "761168299106618959837253184610027302352675981172895412789219362344349418506"; + "36857059855189113781134096792662950699742275482770772595919903687711739320818"; + "18213396754699008102047102089506462494549290414412359468656221893099620902008"; + "12599997312887962866854539884234476951913054226022526078890032319964768070561"; + "31295812056319316979171165714902562241023210946259070539368704588259135657855"; + "36028478227374554353553197903612149760893367375462390976595843472968694902073"; + "19755792677313410149868952739127262822852161041591595345565317109808360990362"; + "7604195354962581173699215459157831606985245892932148667568863588427368471328"; + "37402797671729867091958880703368044330554219817351439709435695854279377052968"; + "15021754554199031983119820117039379649754158617595693761803226478334678245252"; + "47490255684408806072434251664743508051420570808132025501451725974827121258687"; + "17058297088100779754668670576690752359201713072728307725116578742664258035812"; + "33177512279709821535209584501483624708734718786595445144375381063910225855217"; + "22722275695407528091691304246968383686239176745361072723538077075588718852746"; + "22523893181902428650174996691790130832371188536502447987063143120257450653772"; + "23308895356450165080771503655705485959702912748685275383709016805561195393730"; + "31027920485628166856312777655247597928527620141623480299311482321440235423250"; + "45061629190945989233993296798591248101958034421473451931174248051572365665596"; + "12635346734022971744529531315542317156695950592572588825637598149329121435602"; + "20943947811812318510797609944365001415379144029156369080552566308035645494236"; + "25272795848989661284291121337868232983504512905079898072787482710703777539907"; + "30267260031722018334657676019133705236740734579176664833600084021013496843546"; + "31517311768361733509846398942976030662400143969686723910638374750883139079149"; + "23179568872539103374642859400181289258494250830556186918556740813443091863672"; + "43764857307902449625975867969146072336127131357517214347103058354083616467535"; + "50986536293458449273154397197499183679036967678265692625380537258000063532144"; + "17739561056178158081098295809388500809247889131390006315905372775593328303174"; + "29288755790242817717621638923197240104295093218759888966129245521028472275230"; + "34134838804483412147238682009351758572433373367047849860439248437388218182820"; + "5678031864698043849290292270505282805363676850706953191264384683006133884965"; + "26520160397861331597785508913058535821999870140894147231231876363158277734288"; + "29240730915918164705120039064238164059586741149554989326639275573958724232530"; + "8343909311567226700622893556200749476532608824719086807691291972160111871498"; + "35422495044092101446713476071226458201086591087201551382952729636451893974060"; + "28788191175818003347220573268922959045830070401915571862444782695818400239985"; + "4964783835867249774083299211014420218490608209476492267659355881364453511847"; + "10216614694145379678113358015463688529998198929758355282726851046519070445194"; + "27803494825843439402691751649293753560989707643490491294838415993813244078970"; + "30748627242627915480476055895904136928510253392793276393732599431460830214019"; + "7751739221008798527034371607783061382972620557894156823243899329549833690423"; + "33136351771438729026535955096064818190694747127577887810498359791738478202735"; + "15487861031051273320246153480621276816764645205006338931216717383286810036662"; + "49842641210693624237669424014970933360600934128562418971602444161937944689815"; + "38080738277407466133634923380952979679353443729179754588489421357109266527740"; + "49835778803230991359657573667412732792328267908571176221265893225909110634684"; + "48979716276201786775168967369617265563190564537859459940775310207730069238772"; + "48115968293689106220270565101906186091927515718072586052159138752415504690487"; + "44974490348051781688152167728748294073951164996734932874793980137333724713822"; + "32723711714533643804223002624655983381445583052702071992248370814287912622753"; + "35770018441385880747665875909685263825335619219990900501758283083700215049177"; + "24462225877284730742182932602961025133445826599619125054636967365951416719552"; + "23783458847678429109975790282720688654564666590790639711956826681143293787773"; + "22347164999197115677368036880715580840867296071947684897983662897368903035923"; + "44436078084173495334203313236158995421334213775491689085750945085639709823274"; + "25531354606207591001503734717276709131788523985002917593279732600020946775257"; + "25684785975858758309831379800021705800796165309307017255796818608524248856681"; + "15689846944752800355408013445547581183295267110737304356038985876510433629593"; + "2954755130869062203053930362449428183522050551079825685966392986029023636700"; + "27701477658173432393740883974255870340912747006748435341251832401519511471276"; + "49144605237971303130051477474500252441736011779691510816968732821261269570968"; + "41339385840143300905581133617960524027180235012107468786212952859173390468514"; + "39648185702412479261241716678418509894559280563465255646156879733379530382617"; + "2941231259680949143593699011623744100174752512729757643099482873601163245575"; + "42912407210638823710182011018928480520340098630346497369618624020054117846676"; + "48149959907456562949390018405936990163864807774773031806196322989123705667163"; + "22688265260172456453339993837459152038039626634400711129266583542220009592074"; + "12000693219442732741816223290743392039668089531561600727937394342995414579134"; + "11903596729989502145549179132986907891593077014729378748826473464861625192683"; + "2687111115125246444031317339291347908971840740015813305558838776418739833086"; + "23449522976975553535812413915796651435793968713230742677655098865139106223667"; + "9127447737910095400860412314688824392136048676974256371522014899566329800277"; + "18470081002802756098187392375443129770425055057517598292932337151147562979415"; + "44570736387423385650881595596783530585778739624944938740374839306088992916739"; + "41506121518765476611532159577026640847942725069679660287546611181740321613803"; + "17879365806603642296154180079678225700598122219887762781358998608195664544974"; + "5797039731182029290044110349162251456412636832186827899836873551225117057673"; + "16295660997252122627187664110946939903408094437070458659338126254215674463605"; + "34524081549397177387160463682322947783604339299199714872938486944639466740633"; + "46792070054974847313209541773010710216925758583669099409416452772447490195997"; + "26758138270863118025378847876443541196713233312489031593470542282276213542370"; + "25932795773661200059482623714428701540382804071390881515116858419823633841821"; + "13321689192715674395770738630438750136066468135694575335309580617698058033117"; + "9707380803157554078082855616156559824492425930465667797574921265494807066314"; + "7456158743057656267196226193273529706797096313758394320439183942428804984716"; + "45355642533698338070691932069661520741557819242118354206922415757362929214681"; + "11678259483364614216163185940141297609599778858679439537001487250711661685168"; + "3518832067902435230725709346836794333454945124555395496274090845504580131455"; + "32945555853640395249820450907965284295734348780933164440399544563294403789630"; + "39144256186074248653430012132977997931891740120897263028206417805470480396128"; + "513475060263080708913788928053965257750752082706905923893128454713255069681"; + "3683049475437575758554728873338252672236374719853531546923396056498941488282"; + "40512995296870597270088595777901813960760477076488920843379483396300135285919"; + "27566780071222822332525446641593709138022329153495927653774019832657393592701"; + "14553386429473594909470688556596424443792788721346677010176123183887024496060"; + "27859920549341120221544363269894592509610202544403757207234685024595167318501"; + "43630799630596017253244467929174687910181739803861346262759350693495295759987"; + "10566905550291524816328331044922050443675986854353663452037665157735899469921"; + "41883294330455662982758134167170988606274464177099964393473215947428373454548"; + "49807615802944289048873232050825447587887207808798093013193396431089336030610"; + "10322165791099655621755425357073963493688332466706230721287522258992803490137"; + "30646173733388488363150064701278686720564910831836411411651976803737973266145"; + "9402643818207936923863049876511905578631103389374441210902427576559340397042"; + "26796903570709220124665459153306887688701095587820014535393806663646332690802"; + "46485326810825309550921448694342993906840425779587939587426865276020325464945"; + "24356907333535237405651241236585413997915979417848569943590616378149521017774"; + "23511169606994309941348827806149481805650274994320980240977267213388100293357"; + "15731023427833496072707128064453862171578629248859961123054184724775612220021"; + "15476157034920561920585064222922712755398556043478554933175489223519135633295"; + "2588249154193062661573385899432005495347251302263070328643388740869671399217"; + "6009738957936176982507178002696621297792591037813275212151400246297074354799"; + "19233332597631491707508807992208382330520636330001528420218682645685589256221"; + "52257447718383093991766497150127369332489778818971489581567733290721167946805"; + "49137177389699894517809095595548850494591743777874595835879738514452528623678"; + "46568408911734306168397184498986706003337923310668800879260860154439924802578"; + "47934768334329838261157101167633276452145498250520979978623243405647174036268"; + "50548985142375412913344898480017599364756597551569943313108030702053373292351"; + "47313547501137846688862600708885501470839439049482542252265318066588835595877"; + "44379141510324834123427106121179013384083052933887649345549024509665387337907"; + "12745350498713174792397397689765109018413448791457948167478567090039244524261"; + "26500864710621301469407121438090857294270092269498670394353899106577395878729"; + "11347414485694636965135491107674675767460314869225865451044094742585314486685"; + "30546797282015374456420465905729920533639220341847643819193401157056239855445"; + "9764420137258539782443919930298504966223551788317773035826893207520127548815"; + "22299459460462072891198481974919074362126418543881491087838369912934426392572"; + "16855285284125844489209514080904609067369163236122279642071700082910563677928"; + "28470684714066956536547171205246920705847552363405765916824456152219308886458"; + "4732461843529436130239807886795100206469260396399272943452254374852516911378"; + "34562136348353570109700872901928872554702381799420513020116701553340267771150"; + "32365558558736606695100598286177066733690579155204608260555923597643725911454"; + "39093274064908662087943844021095101112203783571135735803933668222858746865243"; + "43197629030144295844773883705380449163834899349448680049499938815732794818313"; + "28135261046436067943449704769784602664670169528558709941327602925531279330283"; + "1506102606338525938978917833686468888009362316628110197189912144850886803765"; + "42336701278628501135217154714167575672783514963702875925876272615990289229528"; + "25024620564425776027644674844378116603084237932862382763192286329954441925762"; + "17870721740021152115020062852028651603316820821405634598215292938053122266052"; + "8726154223262675362011088994808023052872330129832279854214301067840970209836"; + "14874402962592699078349928625650239666631999908036706122344921639840279200415"; + "39756319747099752854658342549564553329846048617905492959798860958027344323191"; + "16691128005183566214615852202071092535806876544863611664073120718156966518635"; + "3656641624593787470623179851898501381429958149290052751094306413295906197198"; + "23058535769798180750363501250801625076459404778101435404523789853891253539536"; + "33558816550895409218380886501604904940103012687961987303678839499951905999903"; + "3535320991257296205944099868175259133046387724680729551263894422361251248758"; + "7317061444673855310460676987104314467363507031733135923911471906709732796227"; + "11500894792409448904640700230690380435021471256333652274764744790985040833762"; + "29946587402762992979637543680372942972051576109298571343103906148223476379391"; + "4083115199018558811067305667801506297182902358286795914571961100973484984414"; + "21780845559336370060316195032869693907916051322860704165373540781960864925849"; + "50108406296877211542712950356627343571290344962477533388788483384843943241826"; + "3604194748440975970709176256380189264567204604496059337216505471586505569550"; + "25367520387024971306924473288179691904393907838798350326959612955828936977623"; + "20832698602125152248033711132843527797288526400731772664791124082045251454142"; + "42631062868366746704081529205540353901856777480389910573915817519106326556653"; + "34498285379235908749982034362054765010463122336180289849202738319552611997489"; + "42569303254780782209383769555863500331363619065952722987173481354130829961783"; + "2968398972388390861514824927379622551058313567208592925335792817590639277711"; + "26932822849411517822460887083515713714294971165226156231324226720523884126957"; + "12289852530007884112177675781197310398488340001613130934099944458324157517609"; + "32571394385633728540470223537905763247514888927223219047927568504736330049592"; + "49323371198951330358894217978741100439230061670861277900398849522199063498403"; + "20916227317093555798135256109920923636673315915840710498394615832626002268064"; + "50437846180582211045193594549699682565194393344569259404783034512017335183667"; + "12720868063213131315535911341883761360678170824615477340625750278643114107287"; + "37197243361742872107474934672270277255457140880848614348969979603547286846838"; + "49972563335848604083615943319581538413921258859517393388640982639930301010342"; + "24578514759429435534489548439103508142292694204518742527201734880498761607088"; + "13544000375663478018521907983648192775225634805964564209488796232080592901057"; + "30244906257123439752743184026932532959005248829599515228075497819748836533053"; + "17158480056121611203761622020240364912867157439578870271481544859959963992982"; + "43213708539956730045950791581115215808814156477860100393372067402068523043784"; + "48148048525328038354477853614732455140796148613572766084643376345096272862233"; + "23955550900926153176119256387738001205670821929278609825909043128410785370923"; + "32084112248131778873683184950328740630941915092866433791792196623349700717247"; + "25228735758855933155378400293367847597725487322422339171350380923514466214585"; + "38708924229373547897104118288852039016237551318118836657141457341427167364654"; + "25573420543845971899026547821922148843484281700825584055000279017238479818969"; + "24727047789721276146751871546128337281102901395874275592320129585145360286605"; + "16376363547325397340914349214206199307694252744603372010394026437013197100776"; + "20208836376333578926014682699975542524501761930394685283441636991924627929267"; + "35206301732048412276841356453505638516993236521927454740085319844070799435331"; + "41261166618096608240361379074330395434896879239200007895635788430952244472582"; + "41432219394078727593377645450491483074448807484512488014556070054882946094209"; + "20834236252121597410527416638607520798042160344062107596356735831487842114761"; + "23532139063413819501017120637575271821539320929878848328154727861013760586039"; + "3946253966634265225936238815600554190068564160724890879995534127285456411579"; + "22846690625697257310904779889019761152674142140749605466121380947233821897617"; + "22087213788241393345997830798811611648992098114012713841486529785834041554496"; + "43158723807235728204358654052498829642083060365187988897913589551158805148577"; + "15465863697980742098871467263990006125886103501516872842535870075250801222781"; + "5680194980291197839690960478626830816555317427024014693910787627450289237742"; + "9094058180026172545686171028787053405103676091999366345519984327286409630688"; + "2332670368762680570021571783692863301454064644206808151563000113996159738789"; + "41147800869911993983577010981800974642409890520338080941707731579519543968663"; + "13279894307388819655466420434801883531790954002783939588058497750423667181893"; + "4870460897717989146446912775477927413376391253591063401746677243573570104602"; + "21434150992290282229101961254012913715487714753851223580286820712178569140123"; + "5884699423472479901902447150142507004213890029567299438503194948937225087869"; + "10751322070759878166895822040094727160998828737858183859125132419531492304288"; + "38992650885322951602413869202579221872340599306440561607592984827348058953230"; + "29170379394369260301915803080156002423232616339189492529725305493825816836491"; + "28207328749747479105410685727161242130439891647417887391083580573114642433586"; + "30853455820741483128256761592665063199571831731867607712950643840486915981512"; + "19674757655311695412098014331868801137574968530161273910500977119681828944720"; + "39760311849140484104401541894168574438723197691222319633908463502228900435385"; + "32907700014271836452044581308399924687442165571312547230568158377188973441089"; + "21419616329214777079035587170514020306037526204702975777693989034339440177318"; + "26618360897653828866229525715043321785206978439662756876063444705770873337597"; + "36839328402947719672481705066838749753765029179922670705966460218560367824702"; + "33819865214094561436972297577491830411674255022072017707118420428518277463984"; + "52239226873754505993400788229529834860768913846928108083029668222253331104089"; + "33663514509883297348657719612646437260376060472686074175777529465535219635914"; + "41003879710590127522478830906318116993393243242504050949617603963042321060476"; + "7812617450066867719201142889276223443655576184992693957516680471935511930279"; + "51121304503531803641767527835120763884818550079574319802192969900240584243331"; + "1274612101252555263549693940665575968018149479789118602662813998362863815476"; + "28111554183672061495966203485846707355259261091518108181556420685499275202196"; + "42136394643178945109983278623800719553667430014244921031314292928454177600075"; + "29400787731444232592537985972506449856480774156983480052734223261628825541468"; + "51495741815899207992089872049098533532158347593725999004967104881825150810836"; + "39333115389438061754746792518056897857082090561687954807372914815130461016655"; + "14294336768755739754763672664822083245398240681090554840744022889714341896060"; + "47674122242123052198728676357951860449892667730335860967923060333702419341834"; + "35684666049106444634028920061342458983421529108234610860428488342278162340897"; + "9217271467341686730075876652325145965408071349745719665965491968116132171401"; + "49102996771041826251600275636051473450230724151940234292281582608241970286503"; + "34854604674557982238222418551502188390821202909341038834798601283398583979700"; + "44103714803951799081408903773636811469217830709674983501189338090554583969027"; + "35216265618185969272100001311669741239205828963710925045672291350518816047261"; + "38403524999556193056272637467205416979772986748102914574085083812998622738913"; + "27146144115803706054383284709975278288993223860198708633471683084389321626754"; + "13717875182956004040277399923680066755828211406717894371621241252873305128902"; + "43893363745908782939920493548985641014151424637808957048781989937501374580035"; + "11726253545109081409164353376819469125399426277505280541880391837677360874072"; + "38928083350744149770676864428063336223211502898736165860838144487338522811447"; + "14125823190822219756837975179681223974137829967998184374453263586157382305654"; + "38513876015199093611082189496524624266110546915344263711135739803957351751310"; + "47685229118417094929745561957819690007671043576786068405288351527235450947053"; + "6959539796323704070461146242134806197237474129123359577767978063953427949977"; + "47545452988897685363050245883092979778729706327058096488694175926251841756750"; + "50819854690063046353662942259579520840136358471545216283227859112171763003225"; + "15309201933918541480912493953275686961353315663926344924717901793290472429632"; + "25814701665737234866376372053628534273087781843875343981916301130840793116256"; + "1916844826075222519090392623030931550354624290318063661929274409207762237329"; + "1046514656280512977708818059092759387987165875435181225389723691639677269582"; + "48632931314601925346131427356122727760212316227166299632747707086089052363684"; + "6605181920334239323337807639920607887166441510148481166461711505022421245712"; + "24648729211610178594528829323421440848291736568213484173668007946234312273906"; + "46859494710268538864658299697721145997690895979735714480735923808224531095520"; + "41175929282429829777281847415308245248403968515148043916452754293744702303400"; + "4936300094396586135539485728167289346454991472436633497057899786781957023646"; + "26497056294320821551797856452767310941293845697666592809944450466405074510159"; + "30179755929855617808122588385117490529340524783380573627382420814158046220265"; + "51404155368749455548900426038075050336878399275390882961314989220012144625413"; + "14816852270047203104312028732909159967998906770274196690632931234420725527426"; + "9617752168355609648284058626664682170830718885414476704978109198619947225853"; + "7427964446763934879077123333856010036056226354148572747809815822346855367365"; + "29674872948739147286091273509870908664455349901359630308300510194622261921733"; + "43495676299055671139434544393413803052382814125675363612358978059313789429586"; + "13094408335698611712427781744265395983524687621162836316320830449519959763188"; + "38569497775632608093794125886753456740306226239072882532108501824492224325593"; + "40308698798346304095630271480781739014165493986458798701620020450887376406428"; + "21695323206500389583562384680685981414856167910480068112985112222651637002862"; + "28462792058602339889033620039075559101583339912637364038250676107653835038248"; + "46541024611362968529348952496518032317778604675804472582130971946588321773057"; + "51356043325501315362210916662661650495252901592454120098836536302110199287188"; + "50506579084327411763038002678064865811256717858083039734318534808177330899455"; + "43768274514650675477817361475016698140148452675749491793321899996800017542942"; + "4365130454011506171008828920058285825290911024175299642700028827967669304334"; + "41317071247365873784712926167181757675491093869449596462352859768807347211544"; + "2666773836237810619617948712753874439458872566874729089643359958440020536859"; + "11268787534831056816083083174895755956352873998182091668492218789389708906242"; + "40695329903519172458025898268523734890965958519055359802905784576698941321234"; + "41627365240233602645027028937623461357745612228956394512781214869371540472342"; + "4164478539096095999131892571705567059771712234999653371776917360777549612104"; + "51248727099288674225044422898397396359619826428997072695850613136023953439945"; + "48153799345590764241473716564225186646412111682334808658902588825212784855559"; + "4038288326645960636183384957834655531514058972517268839850385229326514434196"; + "9349746370858115821223769976893823674367044998087780251985518797575566269054"; + "26635144643229156230109683885266832396020379662024410046384058858172974749048"; + "43223596713057491838453489984430963701106626227127004266936175851674881127669"; + "34365304033357616463976462028585280284797223483341370850659338406635297935595"; + "2134516731680789816358678416060804041161035786347309768102559295564927033298"; + "45222140147028755238863517248876975843048731238253735396150896367564901004686"; + "498606925255879431664844628549393158879953298471933183455573478512612767210"; + "31655578397479065559694701010163356160453434259437394629612488741366238826723"; + "44556920347721604505312194713898769297829148630669474738183867182834534512253"; + "41066252220898939528372277962872199592413634363843816853371068676896371450235"; + "17898654860211486557422421879369818443339885864697693239455405713385693412604"; + "32513783099500141673439294633034010193535529791111957913458937240956644750422"; + "39905409111076411206565494347110894882613346677151423254819846790782130025281"; + "34988407687074005102516587752744593627068947572334289485494224614781612900746"; + "49737579529532507611760379505316974983940800332946027442906862839608822441536"; + "40162178377217761341550347366456178201094415946625032846674573547145969502567"; + "19353664035666185668244147626872757644951716514199713218834744622396379021728"; + "47102456478332690688659328489760691845709562508921577866325372829999411432449"; + "12207115819013703533090639097195525814981520405803331543503208389206865838351"; + "49994145749153772801588770229283450802831018859577109122749028671638201340175"; + "11750496117230153414206471040577887902252831603305505401836225613139968743361"; + "39247158472854700135101098114122648755375036565112534510407184246554146458821"; + "34888420087558994696576075863747777609045400754497672888032242287719438881063"; + "36746602810649853608305671227827297524785410557002588877308144918466075161379"; + "35110190469581159095125917772271263108711630576551389559652466237914252519706"; + "17666646113580405089387681323991445813223732839702375394019098767167481113374"; + "49832915191890911296130390700527381380353409264287349518316829690779511940285"; + "24443498466703215427536198609292882343492137081224136946780263563592401049860"; + "9354050407159006695831135953483212990074661420262042032504530886059244184549"; + "43333009983788285821400695240087914486289602002713044560524409547002696507943"; + "18752273838312523782927643189706439976957320321860728910806488085573896888517"; + "17277900024182511146710507398920674498144288099203282562831710644330579267863"; + "37307678413917534108508235735432663978301009388979394911932194936937228116983"; + "28849789673530572936431250397502939284314408030083300337114716226795362105688"; + "50912816147821018549769876876636191732251692688907664846983470977761901142017"; + "30131058343978916976539560634538314390572592064574889352048802922118040591878"; + "3706738172138818078705220133282568519342502151909947908081476774050163705447"; + "45699814681518246744400453094285582701849408763005827286692443508836010669243"; + "18846003060227712054607266173221112847285282616057372060555371817788046689458"; + "22066640520973054711560800705115163615789502002092761843459719025242646197522"; + "23829247396636262290884964425831569678858143545005515755792807616917823372004"; + "48198239185624674941704629705912623499339853704797750011743362965545369705797"; + "14437343003724224631871818628799571960312140411440628694004790267232875166985"; + "9205739813512268504763814673014453677276549572272076135414717042201476484408"; + "39791411423593512268799994379557077985176861512059575297944927863183698039381"; + "35926621231744856494112841579711773281980064124370668225976659404439672270700"; + "44486629680241930770190601741590174294937444204078046665996776098470715578917"; + "12162293378945031764624085071759188374782023105344514611109545726564556675201"; + "36307225704631546442623734392611975648010152587096752396997755313409683740066"; + "41250750058001775370365399976123622596191578857360075239352807587783963966911"; + "27326083632152278734711454453088575834660104218399840842350769848804017390818"; + "21738472712881664490908162471080764510324227185426320378156680732466086006946"; + "48253221985307003164932400584047916688911336639213284074501437919167577474120"; + "31747278632217258576675538435288102373171173881876663185343643389289388474560"; + "5761801194886985126517131550892405530757591539197426021056539623860947947777"; + "25080051431129686333412677366349247249765542691781361133023295276989895785662"; + "44725507017222585824480973320142248615864064267075237276314928012346637335685"; + "2270142730849677751753329523089749032641108434062308390614061733510185159182"; + "29151537587921846263406040946950786214733637455178025270138954283829217507166"; + "51701993706600967882137291998419813154460359807514636008564722369823738880081"; + "27396983310969582762655735423233600814011645446508465877860524193464148646437"; + "47027464785635786821973369345787882857794216687685310972827981582102274085589"; + "8537697526465704802497642132002864572208835642458535053052653228499861354076"; + "33216310879070852920780500139920461536347985311343304758357092362169634432945"; + "39742197294627214520191321293386324944093718559889580220315772412754596333618"; + "33896963789316206258615821504316306436964228772759528417727957697783861669643"; + "25010660153820592469701812125053548417837781371102734874578902256052345209508"; + "36367261405021942429836445456841404357897358255476611125054531559819745708605"; + "52426140434579970656719582674709112782140126494023197627160774284296958026640"; + "17974065625542652257057290211548736634195575643976320857820652175876530118764"; + "37053031019194686166066970377043979546613341770302232565495885535831842113241"; + "13811446176969112541505871240921570152518757388141946244776461129201049000050"; + "15092093442185484653246077567190483143911375332335503262901381196989675075655"; + "30290712242976568484406185485374545475757630659561739950369976270424078249156"; + "42300599090797035681205333143172106725230562804023721865246977451648659325451"; + "23034899362471909543298700478448553281114092027702550350324373720046757230720"; + "48731736718724459302206059867835027581192820404271125436441919516120222347777"; + "38210977651743308949567656032696478385819661205063514163655683061120398680442"; + "31066571830413162458652431971739961248158700618823531207554971312281336740306"; + "38604214043841500037487247628107100072934980241996056096027128810264297729133"; + "42466391101465852203816440495696613849995732468216567393767726715283921987679"; + "7918626562942975338180644093933988817993856782142079793192213031203713419564"; + "49684155517934574637878829138073579948423899014921699823733824485886261361800"; + "1451275366564565438656353212713435069619539370740288657639758022186872783344"; + "4060684572698408855577084852784974870722088774822168823176048676904575595914"; + "2266042413117404820068618979432448191143223638313669085447265538970047743222"; + "30905627074463551844852560969973865864965309523440254426402110555428247986128"; + "44158908912184255345458082216141321324031565774822466208284543424748103990868"; + "46781765007298128451676105938324040827134620337685516847682075321984346802681"; + "14555474190305191329651931092157102989148485771814319545054338444403258212594"; + "16881117240817753666225190901719116414117517568051590769838881684777210471563"; + "2091384128545629176488696135490230680171339008214937873929334100299232999763"; + "42961581958424980887960069029855144961942029721580484171693959065822644239271"; + "37293380196472166233044745617934489446223933790110588175152241706018245409475"; + "50472789792567303044557428917354654330233740880518444155725173737527015380692"; + "26254591932763759021184569941619883521949754828362687682030335425079808014229"; + "17113230459817249275857268126349806861319046074842290127707156305676386386894"; + "24231753369429127358009700702110183480199277263167907099485750041582214965155"; + "32263789144438090923613388538761009896632203008432412115908330894004664953052"; + "12618230980377962991318338064162350506512133151309212471355044610992713035428"; + "44287411811548063431416128186222883697784161373833563087100707769861270222355"; + "12243970408204409993839495395374510961024300896394362315078558518998085218595"; + "44173339028947996046249077532478888110286784422982124321103998220058630129185"; + "4598274292520003424438601799771684670337297603988895001679632082627567473920"; + "32220511643743595369808381786406376653262724588548158227055695474753444711477"; + "35927311526370278156701529193976259428647110571727767928074012487713280141168"; + "33414541138436871747848548210767170259303594301338319380897399124147207142256"; + "10985815035297592042713783076262430811622978337187158511590030541267680813140"; + "47191419930669230163741552576498932288846324126311314824353674932127709343958"; + "22784828163631611768238083672698851077894334504107657128357294425726824989181"; + "49949907206009595584434917818119046546975686520915136028196584050967515480584"; + "26410109194133218506580932937648982507548919566531870050806115243653049366263"; + "49713902702044838319213158273679308025133803584815262572193546155507722324872"; + "23535559504337049461830629174751216364093038300260308135874588247062574403616"; + "2238775094716444052477495313057898840054408997234199224243609623847342839111"; + "24251437981344168177052800972995593868567104302081741438918736451368941030394"; + "27982993433491253628745454998904820434128996322734239523565021212024510217448"; + "50295838517535590686256014994179135654184756295823594187599260917362939655408"; + "20057613369317870978599836560225006632816653691101308330458367154191918881132"; + "39394614248557203761718739642839828701390805742892989071457854079306409260621"; + "47798093889297880302781161190820961988270610469163421109136182280644356165044"; + "44393568357054115404229042885561023580153267137301539458060374049988839557996"; + "33693283919970625185262931602508844386692612080074318597070832534138700238378"; + "39815716493396968613970558873707844074909540436043586091356171795994263694381"; + "46853573174002303039170539308214250609519855889637324611927935851194802547886"; + "40815147595190732687521587437353012947450179162389073327247952677750833108813"; + "26339521409702735393744068131812259633542864885333572967691724944624282632629"; + "29354121099706613567496209577487729580389509912153101367352651455990974641897"; + "13956682594977060215824578428178631751673652949659210522408548576867791213468"; + "21710651844333023404269198169431081997914625130038397009887765719584062563582"; + "34776931503807259527470945396912938849688359577250098809620069934536239444952"; + "30888022057753192523461569966379378071529579974487499148314453535224010075827"; + "50706911026467569615838130915836644196872403584282694942070640728917921207853"; + "46864858442437162961458912480193558760809343578316469752769914636209220922273"; + "13257506406075894433104506959381001454814282265917832054419709339905914092656"; + "748651022964498225720140702853094466861887182520450179370194887763003477434"; + "9928055927827498106046655953164657438589198384956991765511981535095278477147"; + "17282353886786306350464074480326051762770764361308450866796096466478345879680"; + "1031912496796069267128921308084345914023374178989340573752894044339622888592"; + "25926134979442574649058093555286719859705643564478648509775995356905528815887"; + "15964568489522278652756557360367403556214280414131594187699659173938365588488"; + "38050091280410708232976422594473351403153808832581737053257668228216639900422"; + "12030737699352751292766799393553393267232605717122753898023894800120436351283"; + "28481686315014470274923914799086898836504959567797773710778502159442143532873"; + "34854855773809028752393995264841215192998714650018251274814328745684277843700"; + "23177024339262302793601070921104366455941060951873187433549022636746564985947"; + "32706651237059443616796121926868583069846707958453355769010508784973815882902"; + "46999132467290246174738142479599222392723632370675458675293558263299577721042"; + "51658189751923308132217973966348349720258327530023246552822556444736712390623"; + "6849360125712696557397143449526597653234220520772426233279930720210309738320"; + "37750806736224959930132995620486959583722999721579507748526178865808200136556"; + "20596145017860309309979234965966368019102563566006691095290434157503935075151"; + "41254341165403645465348838011157544897177244154415343520886560798681195976471"; + "39958936321623717554709758924074568269853737880198337327309503417601943446557"; + "19195223398318500029787325435183109593313197618937185661501802900443846527922"; + "10629204629388999052909123660165259102503430047516526387386913093894818621559"; + "22392494050571001911742800275551946666157619565710102369399744439030672915709"; + "45789181983557040436379972210390979168574359994520320974901389101449898971667"; + "31993107635680932518045016097850934312675277860051930648249938294616399737203"; + "41394691516688662849678605584944839500777787870042035604148788674531052718761"; + "4260057227269055804184487378356538538091829237564811490140159259203053493365"; + "22755914276797984949384994213736139778684895539493230631683465009788203482529"; + "40041235704216186530314362855470728008875244931687384625262157538702289816794"; + "6239837510956467015853754603670020841591725704614056805052967999814231026644"; + "29458802836337316653464358527714116167816937061907636047906242601994052671860"; + "10495803222616830164930921154664460461646398358336997556169589368662143070925"; + "22898549214190047583215260016577644830295617833670028301698818524286997579532"; + "24393132143758164018011524734233512995814989110864264594937375305003558662082"; + "35599669100699975483818766527498585288817388816371602239888485323895149359158"; + "38006814568801552692257172170653057840209105926496657875471253681231978835474"; + "37543934971882261953367219974994268988229276972094897853703891601912512732069"; + "15638582370101925565491212811912002274875207706665814348068235624071156999370"; + "31580840665375344887237728746628275665874622958061630557939670052080082572146"; + "12367368728174853025325572761705668347969447581862767534739917589252910852407"; + "6431300041535226336752933722639922185807048849346218384550177388163783622203"; + "25253158156291597068997002534648267078756725939239005896820619368973386400618"; + "32407272173038095334116664653948892086910040424886147129262625126739839822771"; + "13280522211524717536348472783270194511863920959394096229476951226643221055230"; + "16772104472116956787783912564859125725251207740620474891039818280005602295238"; + "9380491773071000549418384879702223304167388163133689178789924347338789859850"; + "6740138750908982892458436295989575152579732709412893038486800886922449522370"; + "48314810935891480393270246846320465418304988645667044400639849377044382785493"; + "49525268202538850726708934355964079225214093569356591960731024652251573337974"; + "10491451908415598562758512398208310743863775903122876297029651957513361141458"; + "19406081409800592976259677521739333450025655891055151006357086244687039619147"; + "13796012858975195466491814297891072959260328291852781745607018638427554265885"; + "6485115628027826708347895792986221021092093804047270852634430130894243301376"; + "7032119811712255634773442378987402663863092963351749353790436863005730387277"; + "49570765767525444909530922468492577696342166915419424004169639950326136617057"; + "1285129643807481578340292178367830355589280266621317949423705788259432932006"; + "3441634142357505544306799203411944242234343920049337423233909232710820734846"; + "46025794658354018692379411175175073186560341494151624685587728046975000562010"; + "12106158677633440534700667787331666286230014762373964286877200484724425265456"; + "23852090676446145451864225599736384585160730887606821819365287956188313561217"; + "4645666973599908624611019322719702479503064932117311025810250241310882715612"; + "27973788552235695206305543261730414876912259984347644517174031345462270738555"; + "43025700336074147238459595423479529842575492457031762291142760348199150113491"; + "11114947607987207788072907159327922005689782074310097245997186074333396056216"; + "49687044256007315302113254820386474091495296180003075377414100433265777233121"; + "10121176151471384524101283711923697637725868232114641816445390512389391879025"; + "51330986445125278830864400207324675203699148153035087480401908084977553474061"; + "47310595279963533769585290517718071207229353045922336729470385238771992063949"; + "45470655810089077363013869164914020509319391456872208545345084082605634862224"; + "40929877503242649981348819772838274267223608227057310481110253536393018059255"; + "17372055570115191467281872597379815744802692968021921450248895690511846645695"; + "47678362609779802562177762420543329986622289631981586798104589503720694371775"; + "26411767877298533345027866329803788909747237313956364077530765489692282596278"; + "24229533690702187779130733022119521753205414714542053126286077188979825374531"; + "18497840321762427856624303545987123524462980182393573916022980133186401139409"; + "926339800459865307621110262317592729066835255833528961455819197753330330312"; + "26987605273411980269258666993213102373601884668454325175338172997856347972333"; + "18391274780315164583236795984691281435086666456604388825240216970397471681364"; + "12097832322841410456967729421116714442525972726222297222010623646121128815790"; + "49675177072983404142217920899359528991366227410655512062504000260893530407911"; + "15707135722931316515055649351245978339654864807851241599499601638769193005324"; + "13383342070542016733720366624023776259361772045149591256080689729754658059980"; + "50987374166360059560703430211826736262378937327825787684985599281463601570367"; + "37692333855557499699736644309219454870696030700215486572270708025082781551549"; + "48478650594548719294793600227459643485482841832424895683273572346673969340753"; + "34197000768287613413510926912918063900967585863143579777915396555872696168197"; + "42341791561950739851197883113950655969381083158985137996020454938455824791661"; + "50432013007639406618408631759754993701106347480289482412566889289659098747090"; + "33561349681426358960433818341708626828528089088226844117603110599540730269202"; + "50705077822458966913066394832821751993904360422435901531249988211620289538605"; + "45812150193659057136265559669604043591894801656607121583303377953470442982671"; + "44899405678979175008096051077001310599468936311348170044304489130853662237683"; + "7059127019337779356629411915385107326268136949565987358909106161315155646816"; + "34328690381291138075517043550284055917545629141111757511239996475405290993321"; + "26939654315244001880568035987806732594072719629182278790540271608004202736265"; + "30814725983945874115800588983627465902316483105630339244815320449875682709724"; + "8398481858488384468602034607148505717684965642826928411240604873022038757210"; + "32368995614504469151394179394757902584570432859893345667551706377300971640771"; + "41155627378215384456908425831665893311330630453454498015644998744726313357371"; + "2153340160120049982298930685564703679245036425190525326118018096283043155652"; + "30352448634031048114241985941470924393535967542582997762031027911599426568195"; + "15261716957885212013251887338156359768948744882202708080437574444095163828003"; + "38989413931358185435843776850185009130324946962753359173722889885807098911567"; + "1704331953122835388982301028858718889034690658545952309945645484614333632807"; + "27403750471903172003031534481941256144265878552723731083968505201259043778402"; + "17562955366799954474182871335569462132288297189443997453618631664362553626261"; + "19086162457604934210305997669117786907689549640695600906760353084525692086019"; + "909236720157425570791649582895043242306821976668909162225950852357093705234"; + "2587678208364293762041139325677564169740285152881638284308667606120057681746"; + "35455340013646018884370176867194236432498101681197729616134222175532845188407"; + "10597974015947868971053495476281648442554475914904865903565006092661125167077"; + "3237760185979457517707698614567204490221992393739789914647016856511321085131"; + "36946097031106423588593893994546210486025823406712493196127193878277998127793"; + "1562072353855994226121886801808336494359509412675230144523806046877228821245"; + "19010448428150791333165899594482872847843192038124839342939985299225110393618"; + "21579288013136572427312994291446922214090964937547933878834394360351661124147"; + "27476725675454012862496969681583556164753553840148186542141037944739225011404"; + "12721482754555216902365268649699780762391451537917039204354173116225938906231"; + "17726161376964586155439029895353641881124547308134311074590598308682629739586"; + "21277449426226092595780141778474905944490289128777491654503164263224221094647"; + "8027270477264632862462234106666097274072824365485884960263030432202348123210"; + "41704607970414222533592973837383672465179394179105424582475027116253727832320"; + "24911397878677534717817496400765259525912587429394942164360589864420581372895"; + "28487683264297785882293411974724574939733908335995066450236207591718649511876"; + "9410945672219127372505114826532796375498170564414051544192375021034240158151"; + "41501277216118808186585885765499182580814856188527129455247808366786573543421"; + "10786842188586265560953543650077602380076591787820349469333358966937440803493"; + "27009619599448135465453464435058428424786314448509662877166278927396974389912"; + "24408090401747031528777292030856366914050775066115322946199273876732066533603"; + "27717428010589203122459895369508850795775086801529508808907903171549714517552"; + "43961339117528688303727933814338246842560025117902212123957164184934798616272"; + "23539099267901977681530985543753979115801969780392578671053292012737090359960"; + "29129130787064690115403858309463936784595038310196943453528132510780666740275"; + "11544217335881527838309935861738104229903387666758470620902798348360616219319"; + "33462911116491023898914175915108269500003786821526355903193319352945031002857"; + "42971396791389197300566908724428992708740412328465643262012289069601063353167"; + "11114100576866102546082991452575837001302257906574345014759165856210897893390"; + "10869503142950375121273168986955759969708630281326506993743041491528703068926"; + "10056285389986129969950435124477608942343465496465667661560622683088232566646"; + "34352912333098020699609122066221942402647202729511926372551684177727356125767"; + "48815653149287031584900334425973245208502245603175731919813468058312231051539"; + "27279886970331272055453009825591093815823325722521311734285899406328214417219"; + "30743518328862506788849929078973418258912120322041236148115187319465176865909"; + "23836593777410321994736212695067663874445976812493472680359497431194677069707"; + "14271245249714372701863366640280358937336173352148459212765723706902523416666"; + "44751389477552162369260519320913279071846090137697398153616721749914975209463"; + "50049310530591903842202745108285775951310636397993830164309261859077944727008"; + "31203592346501430398694586706221740358145194595166035656399113862917383342162"; + "37447642270457825605341454299863838011561200065009939824839354876147406554050"; + "10574164763913009315349684560659607328049286937437594137678635676492164664990"; + "38325320802240945919839117157786458966683186777304529608044491498455717130551"; + "40805013056129827384501225380368635414535634360289381317746546936202290112538"; + "48333388268805149543196989643320441803480506998791523089965182033002284368947"; + "5782032582803275485235374665654094879290446054520008831705805183845211898185"; + "39802516355118908351021607643423040697458583372235828229304343199015399090975"; + "30492929460132725992608458300060364368351457395826268799884859998700261205304"; + "1420460004901060161999428487693270028427827250557258348019289211566581365454"; + "44193635056304562477505124994430538128890073548458826363763791536481254794966"; + "50720689419341593983069569011764146978553260482771698590157644701830829402947"; + "8073796990034033964469665366473997793181957677797087439421280810770488925256"; + "11918471565012754466601744707948105395283969402172028499903545447868170529713"; + "20077023346487118481621638270056399928015669807959870935567399723256898313150"; + "17213961046117186209464109755931248173988132541497089384021158920901269721090"; + "40806924151578521440897441275485084726249888295413627153644179743836373627459"; + "48180670522504204627184158154001766027012194162495506518370446939968021666069"; + "42003056523512230201797933267792902549574504149012715622767056620086275745478"; + "45101413241990392158966509799943874633896537344671548489389563011092925383814"; + "50587462404507583069240045742171989746743467775065297737509970837012535861612"; + "47815286514663372521264717191280262614050727424357000042525142008994950651639"; + "17400463065364361454879212497416099212109445911086039739080338012549330324535"; + "18161390929522210528368217943618859674698687969813941340329551243423634163215"; + "14441574882494975584903294130579023104909680031021053889713767896122879098657"; + "21912867184623729582081200571230217079961934918095841057644441114392793081978"; + "45361556540636295590917957481529238741505687644950500354869312727558668766825"; + "49539592650928368969231099603636984862255298622407911855462789343614490745974"; + "33869060934120743008239749284289212363453006243904282220127716668152965210748"; + "25076370715589585424326332620725315977885925199077963714556765297037513234989"; + "8002444064393390123216308842243771494245898705227632990107898963043446382143"; + "1356017732914259689267113844885694824971954414004791084036465384478863651474"; + "18698831976592497490869840317995921745505006029532075513759064786215310313034"; + "48836462159247124316625665463190819813831892402600021151195654650125270340651"; + "44079217861342722911981257144373371771560838079739791623631524927582118528474"; + "7917860632115468421843323257057624091855319060906343969030682698738062187742"; + "15328920775298393985301712443835521222368870056830753657709551066102881234707"; + "40585149282725386186676237190866920474926692908526104716015727560418525066965"; + "22476618951264551734672333363230193505101669500810396582135708891630628995331"; + "22976271519589645590337728787979950618802152541630285510037871742827357400405"; + "26490418622799095788111021654113322288820745026736077183862125058416171724885"; + "38668434553373591212556681994380448212723195862087041826021901890569924770065"; + "15734290460192933229142204966761293110558662629712541767317274191859409979185"; + "50708043312916419002750805838232616804578377791118982931279441695110104859619"; + "25661993114668520552639676665126758448336667422881593126449325707247794604888"; + "27300404692554829310057036397197575379085146250686335589922839236734268293026"; + "16616950908374247513630471498870667771958507881588444010494951003904728142357"; + "780331858290974370698544345229396895975774808594696606255314479320722478183"; + "15356252408972709076003921799298413990129664042289284426790671672668901277378"; + "22195679839447440563352896996056925121555070971714547978827589453261615780585"; + "50055031037344446643661166893394701232488862253278315780297281928041839024491"; + "39853343710092418340651301215898149540667450843137399936276811087705281337915"; + "41234320088350200826168830307183441504603558317128457459369045773720261208509"; + "41026304730141400072631269150112787967137999190332230376064990660056537630883"; + "46270298741623878847116335581496501056187952274321389849457282429215904661001"; + "24229852243440737653059813128440054999089637857670449169075813133344895934250"; + "8424306277967302875586430461180994699747156058101091594395383080190147483624"; + "49672959835707465722916473003774662744770586652374151972176418791640619586394"; + "50953606432923765425047764715621990710996981237692942916850916691445210588986"; + "44233571495113761415664137120393901177879884654356773130439945796774579578083"; + "11574634161412767461102549430739220546934205978274834090884125505175189074069"; + "8645184998607708462451095150206729904754427459024724873922986748255464652029"; + "37128418642109534373362468648382548670038346064741412903988995594256056481978"; + "33355443735171069266537113956815564199390017657125748952951909212993930853609"; + "18346976095151853612362092673379644124598042905694460090917547301686808797968"; + "32646375704171180130330224041820560945074015817182291941815877259349052407072"; + "43225167886161343156931475989059671126108470737009680929793198947446394575937"; + "8816437937287404337360397847635602367292009763466086832728768883240427981891"; + "38366899091948084905344245020593946957409036781563456341174116328327175180679"; + "800298045483712205484307334575942288725541659796453174814416446066185314381"; + "14508830287813168002435636185480014871079716479693496544419639273961439244196"; + "19123558056196698077756824716735733526899307503111963110801154666985150036515"; + "16303389189674597252380274616649999385814924811197807163354356674102789306574"; + "7453668915100625394664770229394717267390236182731660405097681417166662567678"; + "38798071571359045878565848619638213488585154176099273867945877100609620185282"; + "36631959497302172344707808434460251250381882633514089681745071353294520523286"; + "3295651438846461067006904471387575625423106106098387875100629738076787368486"; + "7639968555171428539513522652621621046079902482011709740085444603640503656201"; + "29579395581332007484259733934571852879364872891046795155379474874395906573519"; + "26653656757216667921153411281655535324426792606630320014981412395252223538329"; + "33945142010095644499737879503783227769340995607126548035094938552106092827502"; + "35659738763390756446419442911986047138385980543377566364330341100094367895238"; + "5380796247086464908504473508326895383205443609034527483380059328805596144573"; + "45555109220928268984543580497682265831199280528890734732631782982445734750732"; + "20535285005178766298291665162439441374276729776225027287990176172368474655430"; + "42276900911794446922826515302740555211179964292337862181106694848183792840849"; + "52163438563491625237964145588646657521828399654529930322643039527692977471445"; + "12381085634185465518625170120342681595340115886064341209590250417404145330796"; + "41332854461896499143467401552257229221502912725720917689641824107995364172760"; + "48130816341111135562667996573877686235140742636682402903593978927062615809300"; + "40708352896435303925197058053634288518207618858900910754332784721266337267119"; + "20414673166470607272747811391805104245858774907937409341200492727939746607797"; + "25627294268923401583055123311122337854601831198810692741217863178401731813982"; + "9471796077791050250358831370212483753463358283515022318409978072807223150958"; + "18314066421198133015325418115287580268791041525896152562360347711250600527843"; + "24017014751842644177743018360725989342257842302110775272063931146838823820708"; + "21581200003538126245980521668237719802680919088433705982480735447972766043363"; + "50184800347056048262055270151626286042367002765576087001102590179487127900402"; + "30495886812798520386657837931015291018488945515192090129642139250370928693580"; + "22576369160305502855935040778001809663355224383879666287087499574629468037932"; + "8892650559142637497217516060667987141940174680954367407928503085925759784531"; + "26585722842364766084323735392097803839711029569348840728693523172589688253154"; + "29233945065322679878626700781011757896403829828629855948960912667621036626304"; + "46495499699253457275171950570731129922763854056949062569251813711011602552765"; + "20175726311806847923316241767174947396593584808993154634747567993383544235788"; + "4439738901982759407797641994447539352385040803130129830312569441261131407125"; + "16457982232415810076025629044220925770877965806117341776311181746417552277025"; + "19907475632940820992995770155453308899317289306448422338160567626015082798255"; + "35223042914091176169939921699730780563001221818541154418947974752159293542388"; + "43001533944345692738449547388403626716967932955110192080457393496732555299619"; + "34125500451758985735535246859157148109918522814391361071782479828094264751521"; + "672210927468386341214054725731176563716514412831001669942787056703691451010"; + "11955392088705171556964578398079500139155403309741307240924960466165999666255"; + "15001212103447594119920182143104283078666143755444714277900928289186853558391"; + "12494141652757315459070169705561134159399433995127302554127714989589492762158"; + "12539864421219420825268500409099786634396457699752281899702857644933872397743"; + "43101784081867314199511257387329290804750329977663948322198895874188929154741"; + "27446223298884346343269149146243911653385549792135607763714158002175305061634"; + "1221810201232089129932400022193871837808173942749956359312713538906718836479"; + "27532908760517365244003806543506083069460105424541918130562804937168539380933"; + "15648693309686663323928562339596607937964297674438414931587554610267850089762"; + "51990644901841817393110558619667069965078896715337659449054804464607693143160"; + "33794620192818979295379085241975052389791263016087838781391920545764975674473"; + "101607244559760430212506597577050204264047733826203142005234996733194535803"; + "40666396311706682608077428065814708907526669028006167240560016976036610792591"; + "12093027072881844562446294223504358738044964433607132404028203137662407596800"; + "47855031407689076102071980457490179464098686349841578053656622219683394194927"; + "22887362617646323246137538576383771868750784401107098034751943222440904306549"; + "14772206578599333281746941359370160645118537874167329823865244020069915126081"; + "3526757700545255914615010391053602312122669226422265428284197630347896730651"; + "33007891082396853981232434558524697472333004416828682481099968575992162687374"; + "31988013417414141593906072198372172527694109442594239825489920432494911766933"; + "11191961053993644897418397896972876540611743197344140729636835194462710841804"; + "21880105207814770273563304401112493784911759454461136323535459121487533758411"; + "41486397989964301339068924325783394852002678141033490060445600519554945226014"; + "16498626461620337833657560298722288376309400783422382991374550718050901966642"; + "24943377286264067314569680564276927094588309007929081549392361988305161867433"; + "37986591875971070389212991388767178111861904302329418052260086662061715255565"; + "32017690217798460109067983234755326443554479110662411364776709358644611216536"; + "11268114558872136972649888237328080074799940976672472351727712756343878033991"; + "8553866868885110753717367996095488037219349823019339928639756785019374917125"; + "32329156174505548357975583161085823726178367498919221564757310317285457845069"; + "27211717469524004207872746964920608620364761642576492559180465819096139390446"; + "17951459528837145129192967424193834007781706018124597879528401736511208623124"; + "5641081412497253735686285180366403504609424502347938813022628844058433088254"; + "44149401842640426661188167090997457203149609985845860407845476505741286527400"; + "1131272348428881671180311242049529569730380344899908988923912651593170365621"; + "29408853361809783058473821719041796914748403385269196060920996759386405450822"; + "46397512824547164970111952967961313462600614947138288894235958387784135997027"; + "47516645729584090306484976699637881381716439437813917167035708795500295063993"; + "33055093158354315225697732538526252497152864807143121380155645175831367997411"; + "2483278713512874912077821925021730472549918913537260777217235941375925483743"; + "48815704230612764031863984553515469905544143230929551627072471933945117691529"; + "4328792740667001536219824544300358343992356873304526946361038441974068375040"; + "8936186593485597641227715388671424329734834396891419524831642301555170823192"; + "17951920387101669293331644306482124096994648510679825947980062912137916768437"; + "19375514622607648705471192919423809092605947096218527444759114794843323604399"; + "29610094038370566321951750688045410763551744002173884016718675203262367949199"; + "26412332356216088802741437584182840836365448342900386978712282658982011423028"; + "6857200692997830027964569096279902529051039382386370537664642602910884711585"; + "23793860449672430773141781094420115804950727589006926766592001526772413630888"; + "48757257789712605511132590475466929307721670979642060291457808809543669563707"; + "41645960082452856575583766422864660930176349173234319988174582522281045680944"; + "33000251418643291466811739862781501771791890505914908533407925955048210111449"; + "15394914111369858819577264515844393687512099293048804309053356275657357176587"; + "8206746691969770388090261805798801614135957851585811798250200766530283892894"; + "8853211220347505554369001872046201218026106125304684911336722654414177119527"; + |] + |> Array.map Bls12_381.Fr.of_string + + (* Come from https://github.com/dusk-network/Hades252/tree/7a7a255f6cc48f892de5cf8935b5264eb8893852/assets *) + let state_size_256_5_mds = + [| + [| + "2184067777412762892935100798463195235577775932917057678850053321607193454182"; + "36777306597928096063744411004176639921441848277782639947444150234631715334827"; + "46505084276831565334480278148775967314861742095393016475696031258238207768284"; + "14474011154664524427946373126085988481658748083205070504932198000989141204992"; + "41996829456994127535645520838846415226858083018697639239163986389734003951389"; + |]; + [| + "36777306597928096063744411004176639921441848277782639947444150234631715334827"; + "46505084276831565334480278148775967314861742095393016475696031258238207768284"; + "14474011154664524427946373126085988481658748083205070504932198000989141204992"; + "41996829456994127535645520838846415226858083018697639239163986389734003951389"; + "1092033888706381446467550399231597617788887966458528839425026660803596727091"; + |]; + [| + "46505084276831565334480278148775967314861742095393016475696031258238207768284"; + "14474011154664524427946373126085988481658748083205070504932198000989141204992"; + "41996829456994127535645520838846415226858083018697639239163986389734003951389"; + "1092033888706381446467550399231597617788887966458528839425026660803596727091"; + "20060349053415325125678769638641803593513735424245076334969536491617299273542"; + |]; + [| + "14474011154664524427946373126085988481658748083205070504932198000989141204992"; + "41996829456994127535645520838846415226858083018697639239163986389734003951389"; + "1092033888706381446467550399231597617788887966458528839425026660803596727091"; + "20060349053415325125678769638641803593513735424245076334969536491617299273542"; + "44606590886527143271596075756181302879566200389155138885023904467285148259670"; + |]; + [| + "41996829456994127535645520838846415226858083018697639239163986389734003951389"; + "1092033888706381446467550399231597617788887966458528839425026660803596727091"; + "20060349053415325125678769638641803593513735424245076334969536491617299273542"; + "44606590886527143271596075756181302879566200389155138885023904467285148259670"; + "37141785804861502213823474505076128362854142474564156061360245762114092148579"; + |]; + |] + |> Array.map (Array.map Bls12_381.Fr.of_string) + + let security_256_state_size_5 = + { + state_size = 5; + nb_of_full_rounds = 8; + nb_of_partial_rounds = 59; + batch_size = 1; + round_constants = state_size_256_5_ark; + linear_layer = state_size_256_5_mds; + } +end + +type parameters = Parameters.t + +type ctxt = Stubs.ctxt + +let allocate_ctxt parameters = + let open Parameters in + let modified_ark = + let ( arc_full_round_start_with_first_partial, + arc_intermediate_state, + arc_unbatched, + arc_full_round_end ) = + compute_updated_constants + parameters.nb_of_partial_rounds + parameters.nb_of_full_rounds + parameters.state_size + parameters.batch_size + parameters.round_constants + parameters.linear_layer + in + Array.concat + [ + arc_full_round_start_with_first_partial; + arc_intermediate_state; + arc_unbatched; + arc_full_round_end; + (* Adding dummy constants, zeroes, for the last round as we apply the + round key at the end of a full round. *) + Array.init parameters.state_size (fun _ -> Bls12_381.Fr.(copy zero)); + ] + in + let mds_nb_rows = Array.length parameters.linear_layer in + let mds_nb_cols = Array.length parameters.linear_layer.(0) in + if mds_nb_cols <> mds_nb_rows then + failwith "The parameter MDS must be a square matrix" ; + let ctxt = + Stubs.allocate_ctxt + ~state_size:parameters.state_size + ~nb_full_rounds:parameters.nb_of_full_rounds + ~nb_partial_rounds:parameters.nb_of_partial_rounds + ~batch_size:parameters.batch_size + ~ark:modified_ark + ~mds:parameters.linear_layer + in + ctxt + +let get_state_size ctxt = Stubs.get_state_size ctxt + +let set_state ctxt state = + let exp_state_size = Stubs.get_state_size ctxt in + let state_size = Array.length state in + if state_size <> exp_state_size then + failwith + (Printf.sprintf + "The given array contains %d elements but the expected state size is \ + %d" + state_size + exp_state_size) ; + Stubs.set_state ctxt state + +let get_state ctxt = + let state_size = Stubs.get_state_size ctxt in + let state = Array.init state_size (fun _ -> Bls12_381.Fr.(copy zero)) in + Stubs.get_state state ctxt ; + state + +let apply_permutation ctxt = Stubs.apply_permutation ctxt diff --git a/src/lib_bls12_381_hash/poseidon_utils.ml b/src/lib_bls12_381_hash/poseidon_utils.ml new file mode 100644 index 000000000000..cad4e32117fb --- /dev/null +++ b/src/lib_bls12_381_hash/poseidon_utils.ml @@ -0,0 +1,473 @@ +let array_for_all2 p l1 l2 = + let n1 = Array.length l1 and n2 = Array.length l2 in + if n1 <> n2 then invalid_arg "Array.for_all2" + else + let rec loop i = + if i = n1 then true + else if p (Array.unsafe_get l1 i) (Array.unsafe_get l2 i) then + loop (succ i) + else false + in + loop 0 + +(** Linear algebra module, copied from {{: + https://gitlab.com/nomadic-labs/privacy-team/-/blob/9e4050cb4a304848901c3434d61a8d7f0c7107c4/nuplompiler/linear_algebra.ml + } Nomadic Labs privacy team repository } *) +module type Ring_sig = sig + type t + + val add : t -> t -> t + + val mul : t -> t -> t + + val negate : t -> t + + val zero : t + + val one : t + + val eq : t -> t -> bool +end + +module type Field_sig = sig + include Ring_sig + + val inverse_exn : t -> t +end + +(** This refers to the mathematical generalization of vector space called + "module", where the field of scalars is replaced by a ring *) +module type Module_sig = sig + type t + + type matrix = t array array + + (** [zeros r c] is a matrix with [r] rows and [c] columns filled with zeros *) + val zeros : int -> int -> matrix + + (** [identity n] is the identity matrix of dimension [n] *) + val identity : int -> matrix + + (** matrix equality *) + val equal : matrix -> matrix -> bool + + (** matrix addition *) + val add : matrix -> matrix -> matrix + + (** matrix multiplication *) + val mul : matrix -> matrix -> matrix + + (** matrix transposition *) + val transpose : matrix -> matrix + + (** [row_add ~coeff i j m] adds to the i-th row, the j-th row times coeff in m *) + val row_add : ?coeff:t -> int -> int -> matrix -> unit + + (** [row_swap i j m] swaps the i-th and j-th rows of m *) + val row_swap : int -> int -> matrix -> unit + + (** [row_mul coeff i m] multiplies the i-th row by coeff in m *) + val row_mul : t -> int -> matrix -> unit + + (** [filter_cols f m] removes the columns of [m] whose index does not satisfy [f] *) + val filter_cols : (int -> bool) -> matrix -> matrix + + (** splits matrix [m] into the first n columns and the rest, producing two matrices *) + val split_n : int -> matrix -> matrix * matrix +end + +module type VectorSpace_sig = sig + include Module_sig + + (** reduced row Echelon form of m *) + val reduced_row_echelon_form : matrix -> matrix + + (** [inverse m] is the inverse matrix of m + + @raise [Invalid_argument] if [m] is not invertible *) + val inverse : matrix -> matrix +end + +module Make_Module (Ring : Ring_sig) : Module_sig with type t = Ring.t = struct + type t = Ring.t + + type matrix = t array array + + let zeros r c = Array.make_matrix r c Ring.zero + + let identity n = + Array.(init n (fun i -> init n Ring.(fun j -> if i = j then one else zero))) + + let equal = array_for_all2 (array_for_all2 Ring.eq) + + let add = Array.(map2 (map2 Ring.add)) + + let mul m1 m2 = + let nb_rows = Array.length m1 in + let nb_cols = Array.length m2.(0) in + let n = Array.length m1.(0) in + assert (Array.length m2 = n) ; + let p = zeros nb_rows nb_cols in + for i = 0 to nb_rows - 1 do + for j = 0 to nb_cols - 1 do + for k = 0 to n - 1 do + p.(i).(j) <- Ring.(add p.(i).(j) @@ mul m1.(i).(k) m2.(k).(j)) + done + done + done ; + p + + let transpose m = + let nb_rows = Array.length m in + let nb_cols = Array.length m.(0) in + Array.(init nb_cols (fun i -> init nb_rows (fun j -> m.(j).(i)))) + + let row_add ?(coeff = Ring.one) i j m = + m.(i) <- Array.map2 Ring.(fun a b -> add a (mul coeff b)) m.(i) m.(j) + + let row_swap i j m = + let aux = m.(i) in + m.(i) <- m.(j) ; + m.(j) <- aux + + let row_mul coeff i m = m.(i) <- Array.map (Ring.mul coeff) m.(i) + + let list_filteri p l = + let rec aux i acc = function + | [] -> List.rev acc + | x :: l -> aux (i + 1) (if p i x then x :: acc else acc) l + in + aux 0 [] l + + let filter_cols f = + Array.map (fun row -> + list_filteri (fun i _ -> f i) (Array.to_list row) |> Array.of_list) + + let split_n n m = + (filter_cols (fun i -> i < n) m, filter_cols (fun i -> i >= n) m) +end + +module Make_VectorSpace (Field : Field_sig) : + VectorSpace_sig with type t = Field.t = struct + include Make_Module (Field) + + let reduced_row_echelon_form m = + let n = Array.length m in + (* returns the first non-zero index in the row *) + let find_pivot row = + let rec aux cnt = function + | [] -> None + | x :: xs -> if Field.(eq zero x) then aux (cnt + 1) xs else Some cnt + in + aux 0 (Array.to_list row) + in + let move_zeros_to_bottom m = + let is_non_zero_row = Array.exists (fun a -> not Field.(eq zero a)) in + let rec aux nonzeros zeros = function + | [] -> Array.of_list (List.rev nonzeros @ zeros) + | r :: rs -> + if is_non_zero_row r then aux (r :: nonzeros) zeros rs + else aux nonzeros (r :: zeros) rs + in + aux [] [] (Array.to_list m) + in + let rec aux k = + if k >= Array.length m then m + else + match find_pivot m.(k) with + | Some j when j < n -> + row_mul (Field.inverse_exn m.(k).(j)) k m ; + Array.iteri + (fun i _ -> + if i <> k then row_add ~coeff:Field.(negate @@ m.(i).(j)) i k m) + m ; + row_swap k j m ; + aux (k + 1) + | _ -> aux (k + 1) + in + aux 0 |> move_zeros_to_bottom + + let inverse m = + let n = Array.length m in + let id_n = identity n in + let augmented = Array.(map2 append m id_n) in + let reduced = reduced_row_echelon_form augmented in + let residue, inv = split_n n reduced in + let is_zero_row = Array.for_all Field.(eq zero) in + if Array.exists is_zero_row residue then + raise @@ Invalid_argument "matrix [m] is not invertible" + else inv +end + +(* Partial copy of + https://gitlab.com/dannywillems/ocaml-polynomial/-/blob/950dc70e8c3070918329d1e7e722f8361c25e182/src/polynomial.ml#L233 *) +module MakePoly (R : Bls12_381.Ff_sig.PRIME) = struct + (* We encode the polynomials as a list with decreasing degree. + Invariants to respect for the type: + - all coefficients are non null. + - [a_n * X^n + ... a_1 X + a0] is encoded as [a_n ; ... ; a_1 ; a_0] with [a_i] + non zero for all [i], i.e. the monomials are given in decreasing order. + - the zero polynomial is represented as the empty list. + *) + type t = (R.t * int) list + + let zero = [] + + let one = [(R.one, 0)] + + let of_coefficients l = + (* check if the powers are all positive *) + assert (List.for_all (fun (_e, power) -> power >= 0) l) ; + (* Remove null coefficients *) + let l = List.filter (fun (e, _power) -> not (R.is_zero e)) l in + (* sort by the power, higher power first *) + let l = + List.fast_sort + (fun (_e1, power1) (_e2, power2) -> Int.sub power2 power1) + l + in + l + + let get_dense_polynomial_coefficients polynomial = + match polynomial with + | [] -> [R.zero] + | l -> + let l = List.rev l in + let rec to_dense acc current_i l = + match l with + | [] -> acc + | (e, n) :: xs -> + if n = current_i then to_dense (e :: acc) (current_i + 1) xs + else to_dense (R.zero :: acc) (current_i + 1) l + in + to_dense [] 0 l + + let add p1 p2 = + let rec inner acc l1 l2 = + match (l1, l2) with + | [], l | l, [] -> List.rev_append acc l + | l1, l2 -> + let e1, p1 = List.hd l1 in + let e2, p2 = List.hd l2 in + if p1 = p2 && R.is_zero (R.add e1 e2) then + inner acc (List.tl l1) (List.tl l2) + else if p1 = p2 then + inner ((R.add e1 e2, p1) :: acc) (List.tl l1) (List.tl l2) + else if p1 > p2 then inner ((e1, p1) :: acc) (List.tl l1) l2 + else inner ((e2, p2) :: acc) l1 (List.tl l2) + in + let l = inner [] p1 p2 in + of_coefficients l + + let mul p q = + let mul_by_monom (scalar, int) p = + List.map (fun (scalar_2, int_2) -> (R.mul scalar scalar_2, int + int_2)) p + in + List.fold_left (fun acc monom -> add acc (mul_by_monom monom q)) zero p + + let equal p1 p2 = + if List.compare_lengths p1 p2 != 0 then false + else List.for_all2 (fun (e1, n1) (e2, n2) -> n1 = n2 && R.eq e1 e2) p1 p2 + + let opposite poly = List.(rev (rev_map (fun (a, i) -> (R.negate a, i)) poly)) + + let sub p1 p2 = + let rec inner acc l1 l2 = + match (l1, l2) with + | [], l2 -> List.rev_append acc (opposite l2) + | l1, [] -> List.rev_append acc l1 + | l1, l2 -> + let e1, p1 = List.hd l1 in + let e2, p2 = List.hd l2 in + if p1 = p2 && R.is_zero (R.sub e1 e2) then + inner acc (List.tl l1) (List.tl l2) + else if p1 = p2 then + inner ((R.sub e1 e2, p1) :: acc) (List.tl l1) (List.tl l2) + else if p1 > p2 then inner ((e1, p1) :: acc) (List.tl l1) l2 + else inner ((R.negate e2, p2) :: acc) l1 (List.tl l2) + in + let l = inner [] p1 p2 in + of_coefficients l + + let ( - ) = sub + + let ( * ) = mul +end + +let compute_updated_constants_one_batch width batch_size mds k_cols = + let var_name ?(s2 = "") s1 i = s1 ^ "_" ^ string_of_int i ^ s2 in + (* We will represent the variables with monomials of increasing degree. + For width = 3 and batch = 4, we would have the following matching: + x_0, x_1, x_2^5, a, a^5, b, b^5, c, c^5, y_0, y_1, y_2 + | | | | | | | | | | | | + x^1, x^2, x^3, x^4, x^5, x^6, x^7, x^8, x^9, x^10, x^11, x^12 *) + let module Poly = MakePoly (Bls12_381.Fr) in + let module Poly_Module = Make_Module (struct + include Poly + + type t = Poly.t + + let eq = Poly.equal + + let negate p = Poly.(sub zero p) + + let mul = Poly.( * ) + end) in + (* For convenience, we will store the variables and their degree in a + StringMap: key = variable's name, value = degree. *) + (* We start by create a map for each variables we need *) + let module SMap = Map.Make (String) in + let varsMap = + let vars = + (* The initial state of the batch: x_0, ..., x_{width-2}, x_{width-1}^alpha. *) + let init_state = + List.init width (fun i -> + if i != width - 1 then var_name "x" i + else var_name "x" i ~s2:"^alpha") + in + (* The temporary variables of the batch: + tmp_0 (= a above), tmp_0^5, ..., tmp_{batch-2}, tmp_{batch-2}^5. *) + let tmp = + List.concat + (List.init (batch_size - 1) (fun i -> + [var_name "tmp" i; var_name "tmp" i ~s2:"^alpha"])) + in + (* The final state of the batch: y_0, ..., y_{width-1}. *) + let final_state = List.init width (fun i -> var_name "y" i) in + init_state @ tmp @ final_state + in + SMap.of_seq @@ List.(to_seq @@ mapi (fun i s -> (s, i + 1)) vars) + in + let get_var s = try SMap.find s varsMap with e -> raise e in + let pvar s = Poly.of_coefficients [(Bls12_381.Fr.one, get_var s)] in + + (* We convert the MDS and round constants into matrices of constant polynomials. *) + let to_poly = Array.(map (map (fun c -> Poly.of_coefficients [(c, 0)]))) in + let matrix = to_poly mds in + let k_cols = Array.map to_poly k_cols in + + (* And now, we will compute the coefficients *) + (* We store in variable "state", the state after the first SBox. *) + let state = + (* [| [| pvar "x0" |]; [| pvar "x1" |]; [| pvar "x2_5" |] |] *) + Array.init width (fun i -> + if i != width - 1 then [|pvar (var_name "x" i)|] + else [|pvar (var_name "x" i ~s2:"^alpha")|]) + in + + (* We start by computing the temporary state and saving corresponding polys + for each of them. + a = α_31 x_0 + α_32 x_1 + α_33 x_2^alpha + κ_0 + b = β_1 x_1 + β_2 x_1 + β_3 x_2^alpha + β_a a^5 + κ_b + c = γ_1 x_1 + γ_2 x_1 + γ_3 x_2^alpha + γ_a a^5 + γ_b b^5 + κ_c + *) + let dummy_list = List.init (batch_size - 1) (fun i -> i) in + let state, polys = + List.fold_left + (fun (acc_state, acc_poly) i -> + (* Updating state by applying the MDS matrix and round constants. *) + let state = Poly_Module.(add (mul matrix acc_state) @@ k_cols.(i)) in + (* Updating state by applying SBox, defining the next tmp var + and saving tmp state to retrieve coeffs later. *) + let permuted_var = pvar (var_name "tmp" i) in + let poly = Poly.(state.(Int.pred width).(0) - permuted_var) in + state.(width - 1) <- [|pvar (var_name "tmp" i ~s2:"^alpha")|] ; + (state, poly :: acc_poly)) + (state, []) + dummy_list + in + let polys_tmp_var = List.rev polys in + + (* Computing last state. + y_0 = δ_11 x_0 + δ_12 x_1 + δ_13 x_2^alpha + δ_1a a^alpha + δ_1b b^alpha + δ_1c c^alpha + κ_y1 + y_1 = δ_21 x_0 + δ_22 x_1 + δ_23 x_2^alpha + δ_2a a^alpha + δ_2b b^alpha + δ_2c c^alpha + κ_y2 + y_2 = δ_31 x_0 + δ_32 x_1 + δ_33 x_2^alpha + δ_3a a^alpha + δ_3b b^alpha + δ_3c c^alpha + κ_y3 + *) + let state = Poly_Module.(add (mul matrix state) @@ k_cols.(batch_size - 1)) in + (* Saving final polynomials to retrieve coeffs later. *) + let polys_final = + List.init width (fun i -> Poly.(state.(i).(0) - pvar (var_name "y" i))) + in + + let polys = + let nb_coefs = SMap.cardinal varsMap + 1 in + let row_of_eq eq = + (* This function gives coefficients in decending order of degree *) + let coeffs = Poly.get_dense_polynomial_coefficients eq in + let size = nb_coefs - List.length coeffs in + List.(rev coeffs @ init size (fun _ -> Bls12_381.Fr.zero)) + |> Array.of_list + in + List.map row_of_eq (polys_tmp_var @ polys_final) + in + (* We retrieve the updated coefficients and round constants for each round/poly. *) + let coeffs, _, _ = + (* We list the name of the variables whose coeff need to be retrieved. *) + let vars = + List.init width (fun i -> + if i != width - 1 then var_name "x" i else var_name "x" i ~s2:"^alpha") + in + (* We iterate over each equations/polys in the paper (c.f. page 8 Fig 5). *) + List.fold_left + (fun (coeffs, i, vars) poly -> + (* For each batched round, we retrieve the constants: the coefficients + first followed by the round constant. *) + let coeffs = + coeffs @ List.map (fun s -> poly.(get_var s)) vars @ [poly.(0)] + in + (* We update vars by appending the new tmp variable. *) + let new_var = [var_name "tmp" i ~s2:"^alpha"] in + let vars = if i < batch_size - 1 then vars @ new_var else vars in + (* We retrieve the round constant, which is the polynomial constant. *) + (coeffs, i + 1, vars)) + ([], 0, vars) + polys + in + coeffs + +let compute_updated_constants r_p r_f width batch_size arc mds = + (* We retrieve the partial rounds' round constants by offsetting with the + number of constants used in the first full rounds and the first shifted + partial round. *) + let arc_offset = (r_f * width / 2) + width in + let nb_batch = r_p / batch_size in + let arc_per_batch = batch_size * width in + (* We retrieve the ARC constants for each batch. *) + let batched_arc = + Array.init nb_batch (fun i -> + Array.sub arc (arc_offset + (i * arc_per_batch)) arc_per_batch) + in + (* We retrieve the remaining ARC constants. *) + let unbatched_arc_offset = arc_offset + (arc_per_batch * nb_batch) in + let unbatched_arc_size = r_p mod batch_size * width in + let unbatched_arc = Array.sub arc unbatched_arc_offset unbatched_arc_size in + (* The remaining constants are for the last set of full rounds. As a round ends + with adding the round keys, there are (r_f / 2 - 1) * width constants left. *) + let arc_full_round_end = + Array.sub + arc + (unbatched_arc_offset + unbatched_arc_size) + (((r_f / 2) - 1) * width) + in + let constants = + Array.fold_left + (fun acc ks -> + (* We split the ARC constants per batch in chunks of size width and + format them in a matrix, each batch corresponding to the constants + used in one partial round.*) + let k_cols = + Array.init batch_size (fun i -> + Array.init width (fun j -> [|ks.((i * width) + j)|])) + in + let batch_constants = + compute_updated_constants_one_batch width batch_size mds k_cols + in + acc @ batch_constants) + [] + batched_arc + in + let arc_full_round_start = Array.sub arc 0 arc_offset in + ( arc_full_round_start, + Array.of_list constants, + unbatched_arc, + arc_full_round_end ) diff --git a/src/lib_bls12_381_hash/rescue.c b/src/lib_bls12_381_hash/rescue.c new file mode 100644 index 000000000000..ad7381b68aa2 --- /dev/null +++ b/src/lib_bls12_381_hash/rescue.c @@ -0,0 +1,451 @@ +#include "rescue.h" +#include +#include + +blst_fr *rescue_get_state_from_context(rescue_ctxt_t *ctxt) { + return (ctxt->state); +} + +int rescue_get_state_size_from_context(rescue_ctxt_t *ctxt) { + return (ctxt->state_size); +} + +blst_fr *rescue_get_mds_from_context(rescue_ctxt_t *ctxt) { + // contstants stars after alpha_betas and the state + return (ctxt->state + ctxt->state_size); +} + +blst_fr *rescue_get_round_constants_from_context(rescue_ctxt_t *ctxt) { + // contstants stars after alpha_betas and the state + return (ctxt->state + ctxt->state_size + ctxt->state_size * ctxt->state_size); +} + +int rescue_get_number_of_constants_from_context(rescue_ctxt_t *ctxt) { + return (ctxt->state_size * ctxt->nb_rounds * 2); +} + +void marvellous_apply_nonlinear_alpha(rescue_ctxt_t *ctxt) { + blst_fr *state = rescue_get_state_from_context(ctxt); + + blst_fr buffer; + for (int i = 0; i < ctxt->state_size; i++) { + // x * (x^2)^2 + blst_fr_sqr(&buffer, state + i); + blst_fr_sqr(&buffer, &buffer); + blst_fr_mul(state + i, &buffer, state + i); + } +} + +void marvellous_apply_nonlinear_alphainv_addchain(blst_fr *res, blst_fr *x) { + // Allocating on the stack 32 bytes * 36 (= 1152 bytes) for intermediary + // variables to compute the addition chain. Less values might be required. + // There is still place for improvements. + // Values are allocated in a contiguous array to hope using the CPU cache. + blst_fr tmp[36]; + // _10 = 2*1 + // -> tmp = x * x + blst_fr_sqr(tmp, x); + // _100 = 2*_10 + // -> tmp1 = tmp * tmp + blst_fr_sqr(tmp + 1, tmp); + // _101 = 1 + _100 + // -> tmp2 = x * tmp1 + blst_fr_mul(tmp + 2, x, tmp + 1); + // _111 = _10 + _101 + // -> tmp3 = tmp * tmp2 + blst_fr_mul(tmp + 3, tmp, tmp + 2); + // _1010 = 2*_101 + // -> tmp4 = tmp2 * tmp2 + blst_fr_sqr(tmp + 4, tmp + 2); + // _1011 = 1 + _1010 + // -> tmp5 = x * tmp4 + blst_fr_mul(tmp + 5, x, tmp + 4); + // _1101 = _10 + _1011 + // -> tmp6 = tmp * tmp5 + blst_fr_mul(tmp + 6, tmp, tmp + 5); + // _1111 = _10 + _1101 + // -> tmp7 = tmp * tmp6 + blst_fr_mul(tmp + 7, tmp, tmp + 6); + // _10001 = _10 + _1111 + // -> tmp8 = tmp * tmp7 + blst_fr_mul(tmp + 8, tmp, tmp + 7); + // _10011 = _10 + _10001 + // -> tmp9 = tmp * tmp8 + blst_fr_mul(tmp + 9, tmp, tmp + 8); + // _10111 = _100 + _10011 + // -> tmp10 = tmp1 * tmp9 + blst_fr_mul(tmp + 10, tmp + 1, tmp + 9); + // _100001 = _1010 + _10111 + // -> tmp11 = tmp4 * tmp10 + blst_fr_mul(tmp + 11, tmp + 4, tmp + 10); + // _100011 = _10 + _100001 + // -> tmp12 = tmp * tmp11 + blst_fr_mul(tmp + 12, tmp, tmp + 11); + // _100101 = _10 + _100011 + // -> tmp13 = tmp * tmp12 + blst_fr_mul(tmp + 13, tmp, tmp + 12); + // _100111 = _10 + _100101 + // -> tmp14 = tmp * tmp13 + blst_fr_mul(tmp + 14, tmp, tmp + 13); + // _101011 = _100 + _100111 + // -> tmp15 = tmp1 * tmp14 + blst_fr_mul(tmp + 15, tmp + 1, tmp + 14); + // _101111 = _100 + _101011 + // -> tmp16 = tmp1 * tmp15 + blst_fr_mul(tmp + 16, tmp + 1, tmp + 15); + // _110011 = _100 + _101111 + // -> tmp17 = tmp1 * tmp16 + blst_fr_mul(tmp + 17, tmp + 1, tmp + 16); + // _110101 = _10 + _110011 + // -> tmp18 = tmp * tmp17 + blst_fr_mul(tmp + 18, tmp, tmp + 17); + // _111001 = _100 + _110101 + // -> tmp19 = tmp1 * tmp18 + blst_fr_mul(tmp + 19, tmp + 1, tmp + 18); + // _111101 = _100 + _111001 + // -> tmp20 = tmp1 * tmp19 + blst_fr_mul(tmp + 20, tmp + 1, tmp + 19); + // _1011100 = _100011 + _111001 + // -> tmp21 = tmp12 * tmp19 + blst_fr_mul(tmp + 21, tmp + 12, tmp + 19); + // i42 = ((_1011100 << 6 + _101111) << 6 + _100001) << 6 + // -> _1011100 << 6 + // tmp22 = tmp21^(2^6) + memcpy(tmp + 22, tmp + 21, sizeof(blst_fr)); + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 22, tmp + 22); + } + // -> (_1011100 << 6 + _101111 + // tmp22 = tmp21^(2^6) * tmp16 + // = tmp22 * tmp16 + blst_fr_mul(tmp + 22, tmp + 22, tmp + 16); + // -> (_1011100 << 6 + _101111) << 6 + // tmp22 = (tmp21^(2^6) * tmp16)^(2^6) + // = tmp22^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 22, tmp + 22); + } + // -> ((_1011100 << 6 + _101111) << 6 + _100001) + // tmp22 = ((tmp21^(2^6) * tmp16)^(2^6)) * tmp11 + // = tmp22 * tmp11 + blst_fr_mul(tmp + 22, tmp + 22, tmp + 11); + // -> ((_1011100 << 6 + _101111) << 6 + _100001) << 6 + // tmp22 = (((tmp21^(2^6) * tmp16)^(2^6)) * tmp11)^(2^6) + // = tmp22^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 22, tmp + 22); + } + // i56 = ((_111101 + i42) << 6 + _110101) << 5 + _10111 + // -> (_111101 + i42) + // tmp23 = tmp20 * tmp22 + blst_fr_mul(tmp + 23, tmp + 22, tmp + 20); + // -> (_111101 + i42) << 6 + // tmp23 = (tmp20 * tmp22)^(2^6) + // = tmp22^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 23, tmp + 23); + } + // -> ((_111101 + i42) << 6 + _110101) + // tmp23 = tmp22 * tmp18 + blst_fr_mul(tmp + 23, tmp + 23, tmp + 18); + // -> ((_111101 + i42) << 6 + _110101) << 5 + // tmp23 = tmp22^(2^5) + for (int i = 0; i < 5; i++) { + blst_fr_sqr(tmp + 23, tmp + 23); + } + // -> ((_111101 + i42) << 6 + _110101) << 5 + _10111 + // tmp23 = tmp22 * tmp10 + blst_fr_mul(tmp + 23, tmp + 10, tmp + 23); + // tmp + 24 + // i80 = ((i56 << 6 + _10111) << 8 + _100011) << 8 + memcpy(tmp + 24, tmp + 23, sizeof(blst_fr)); + // -> i56 << 6 + // tmp24 = tmp23^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 24, tmp + 24); + } + // -> (i56 << 6 + _10111) + // tmp24 = tmp24 * tmp10 + blst_fr_mul(tmp + 24, tmp + 24, tmp + 10); + // -> (i56 << 6 + _10111) << 8 + // tmp24 = tmp24^(2^8) + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 24, tmp + 24); + } + // -> (i56 << 6 + _10111) << 8 + _100011 + // tmp24 = tmp24 * tmp12 + blst_fr_mul(tmp + 24, tmp + 24, tmp + 12); + // -> ((i56 << 6 + _10111) << 8 + _100011) << 8 + // tmp24 = tmp24^(2^8) + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 24, tmp + 24); + } + // tmp + 25 + // i95 = ((_100001 + i80) << 6 + _110011) << 6 + _100001 + // -> (_100001 + i80) + // tmp25 = tmp24 * tmp11 + blst_fr_mul(tmp + 25, tmp + 11, tmp + 24); + // -> (_100001 + i80) << 6 + // tmp25 = tmp25^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 25, tmp + 25); + } + // -> (_100001 + i80) << 6 + _110011 + // tmp25 = tmp25 * tmp17 + blst_fr_mul(tmp + 25, tmp + 17, tmp + 25); + // -> ((_100001 + i80) << 6 + _110011) << 6 + // tmp25 = tmp25^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 25, tmp + 25); + } + // -> ((_100001 + i80) << 6 + _110011) << 6 + _100001 + // tmp25 = tmp25 * tmp11 + blst_fr_mul(tmp + 25, tmp + 25, tmp + 11); + // i118 = ((i95 << 7 + _100101) << 8 + _101011) << 6 + // -> i95 << 7 + // tmp26 = tmp25^(2^7) + memcpy(tmp + 26, tmp + 25, sizeof(blst_fr)); + for (int i = 0; i < 7; i++) { + blst_fr_sqr(tmp + 26, tmp + 26); + } + // -> (i95 << 7 + _100101) + // tmp26 = tmp26 * tmp13 + blst_fr_mul(tmp + 26, tmp + 26, tmp + 13); + // -> (i95 << 7 + _100101) << 8 + // tmp26 = tmp26^(2^8) + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 26, tmp + 26); + } + // -> ((i95 << 7 + _100101) << 8 + _101011) + // tmp26 = tmp26 * tmp15 + blst_fr_mul(tmp + 26, tmp + 26, tmp + 15); + // -> ((i95 << 7 + _100101) << 8 + _101011) << 6 + // tmp26 = tmp26^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 26, tmp + 26); + } + // tmp + 27 + // i135 = ((_1101 + i118) << 8 + _110011) << 6 + _101011 + // -> _1101 + i118 + // tmp27 = tmp26 * tmp6 + blst_fr_mul(tmp + 27, tmp + 26, tmp + 6); + // -> (_1101 + i118) << 8 + // tmp27 = tmp27^(2^8) + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 27, tmp + 27); + } + // -> (_1101 + i118) << 8 + _110011 + // tmp27 = tmp27 * tmp17 + blst_fr_mul(tmp + 27, tmp + 27, tmp + 17); + // -> ((_1101 + i118) << 8 + _110011) << 6 + // tmp27 = tmp27^(2^6) + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 27, tmp + 27); + } + // -> ((_1101 + i118) << 8 + _110011) << 6 + _101011 + // tmp27 = tmp27 * tmp15 + blst_fr_mul(tmp + 27, tmp + 27, tmp + 15); + // tmp + 28 + // i161 = ((i135 << 6 + _100111) << 3 + _111) << 15 + // tmp28 = tmp27^(2^6) + memcpy(tmp + 28, tmp + 27, sizeof(blst_fr)); + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 28, tmp + 28); + } + // -> (i135 << 6 + _100111) + // tmp28 = tmp28 * tmp14 + blst_fr_mul(tmp + 28, tmp + 28, tmp + 14); + // -> (i135 << 6 + _100111) << 3 + // tmp28 = tmp28^(2^3) + for (int i = 0; i < 3; i++) { + blst_fr_sqr(tmp + 28, tmp + 28); + } + // -> ((i135 << 6 + _100111) << 3 + _111) + // tmp28 = tmp28 * tmp3 + blst_fr_mul(tmp + 28, tmp + 28, tmp + 3); + // -> ((i135 << 6 + _100111) << 3 + _111) << 15 + // tmp28 = tmp28^(2^15) + for (int i = 0; i < 15; i++) { + blst_fr_sqr(tmp + 28, tmp + 28); + } + // tmp + 29 + // i176 = ((_10001 + i161) << 5 + 1) << 7 + _111101 + // -> _10001 + i161 + // tmp29 = tmp8 * tmp28 + blst_fr_mul(tmp + 29, tmp + 8, tmp + 28); + // -> (_10001 + i161) << 5 + // tmp29 = tmp29^(2^5) + for (int i = 0; i < 5; i++) { + blst_fr_sqr(tmp + 29, tmp + 29); + } + // tmp29 = tmp29 * x + // -> ((_10001 + i161) << 5 + 1) + blst_fr_mul(tmp + 29, tmp + 29, x); + // tmp29 = tmp29^(2^7) + // -> ((_10001 + i161) << 5 + 1) << 7 + for (int i = 0; i < 7; i++) { + blst_fr_sqr(tmp + 29, tmp + 29); + } + // -> ((_10001 + i161) << 5 + 1) << 7 + _111101 + // tmp29 = tmp29 * tmp20 + blst_fr_mul(tmp + 29, tmp + 29, tmp + 20); + // i195 = ((2*i176 + _101) << 10 + _111001) << 6 + // -> 2*i176 + // tmp30 = tmp29^2 + blst_fr_sqr(tmp + 30, tmp + 29); + // -> (2*i176 + _101) + // tmp30 = tmp30 * tmp2 + blst_fr_mul(tmp + 30, tmp + 30, tmp + 2); + // -> (2*i176 + _101) << 10 + for (int i = 0; i < 10; i++) { + blst_fr_sqr(tmp + 30, tmp + 30); + } + // -> ((2*i176 + _101) << 10 + _111001) + blst_fr_mul(tmp + 30, tmp + 30, tmp + 19); + // -> ((2*i176 + _101) << 10 + _111001) << 6 + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 30, tmp + 30); + } + // i211 = ((_100111 + i195) << 5 + _10011) << 8 + _110011 + blst_fr_mul(tmp + 31, tmp + 30, tmp + 14); + // (_100111 + i195) << 5 + for (int i = 0; i < 5; i++) { + blst_fr_sqr(tmp + 31, tmp + 31); + } + // -> ((_100111 + i195) << 5 + _10011) + blst_fr_mul(tmp + 31, tmp + 31, tmp + 9); + // -> ((_100111 + i195) << 5 + _10011) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 31, tmp + 31); + } + // -> ((_100111 + i195) << 5 + _10011) << 8 + _110011 + blst_fr_mul(tmp + 31, tmp + 31, tmp + 17); + // tmp + 32 + // i236 = ((i211 << 7 + _1111) << 9 + _110011) << 7 + memcpy(tmp + 32, tmp + 31, sizeof(blst_fr)); + // -> i211 << 7 + for (int i = 0; i < 7; i++) { + blst_fr_sqr(tmp + 32, tmp + 32); + } + // -> (i211 << 7 + _1111) + blst_fr_mul(tmp + 32, tmp + 32, tmp + 7); + // -> (i211 << 7 + _1111) << 9 + for (int i = 0; i < 9; i++) { + blst_fr_sqr(tmp + 32, tmp + 32); + } + // -> ((i211 << 7 + _1111) << 9 + _110011) + blst_fr_mul(tmp + 32, tmp + 32, tmp + 17); + // -> ((i211 << 7 + _1111) << 9 + _110011) << 7 + for (int i = 0; i < 7; i++) { + blst_fr_sqr(tmp + 32, tmp + 32); + } + // tmp + 33 + // i255 = ((_10011 + i236) << 8 + _110011) << 8 + _110011 + // -> (_10011 + i236) + blst_fr_mul(tmp + 33, tmp + 32, tmp + 9); + // -> (_10011 + i236) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 33, tmp + 33); + } + // -> ((_10011 + i236) << 8 + _110011) + blst_fr_mul(tmp + 33, tmp + 33, tmp + 17); + // -> ((_10011 + i236) << 8 + _110011) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 33, tmp + 33); + } + // -> ((_10011 + i236) << 8 + _110011) << 8 + _110011 + blst_fr_mul(tmp + 33, tmp + 33, tmp + 17); + // tmp + 34 + // i279 = ((i255 << 8 + _110011) << 6 + _1011) << 8 + memcpy(tmp + 34, tmp + 33, sizeof(blst_fr)); + // -> i255 << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 34, tmp + 34); + } + // -> (i255 << 8 + _110011) + blst_fr_mul(tmp + 34, tmp + 34, tmp + 17); + // -> ((i255 << 8 + _110011) << 6 + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 34, tmp + 34); + } + // -> ((i255 << 8 + _110011) << 6 + _1011) + blst_fr_mul(tmp + 34, tmp + 34, tmp + 5); + // -> ((i255 << 8 + _110011) << 6 + _1011) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 34, tmp + 34); + } + // tmp + 35 + // i298 = ((_110011 + i279) << 8 + _110011) << 8 + _110011 + // -> _110011 + i279 + blst_fr_mul(tmp + 35, tmp + 17, tmp + 34); + + // -> (_110011 + i279) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 35, tmp + 35); + } + // -> ((_110011 + i279) << 8 + _110011) + blst_fr_mul(tmp + 35, tmp + 17, tmp + 35); + // -> ((_110011 + i279) << 8 + _110011) << 8 + for (int i = 0; i < 8; i++) { + blst_fr_sqr(tmp + 35, tmp + 35); + } + // -> ((_110011 + i279) << 8 + _110011) << 8 + _110011 + blst_fr_mul(tmp + 35, tmp + 17, tmp + 35); + // return i298 << 6 + _1101 + for (int i = 0; i < 6; i++) { + blst_fr_sqr(tmp + 35, tmp + 35); + } + // Put in res + blst_fr_mul(res, tmp + 6, tmp + 35); +} + +void marvellous_apply_nonlinear_alphainv(rescue_ctxt_t *ctxt) { + blst_fr *state = rescue_get_state_from_context(ctxt); + + for (int i = 0; i < ctxt->state_size; i++) { + marvellous_apply_nonlinear_alphainv_addchain(state + i, state + i); + } +} + +void marvellous_apply_linear(rescue_ctxt_t *ctxt) { + blst_fr *state = rescue_get_state_from_context(ctxt); + blst_fr *mds = rescue_get_mds_from_context(ctxt); + + blst_fr buffer; + blst_fr res[ctxt->state_size]; + for (int i = 0; i < ctxt->state_size; i++) { + for (int j = 0; j < ctxt->state_size; j++) { + if (j == 0) { + blst_fr_mul(res + i, mds + i * ctxt->state_size + j, state + j); + } else { + blst_fr_mul(&buffer, mds + i * ctxt->state_size + j, state + j); + blst_fr_add(res + i, res + i, &buffer); + } + } + } + for (int i = 0; i < ctxt->state_size; i++) { + memcpy(state + i, res + i, sizeof(blst_fr)); + } +} + +int marvellous_apply_cst(rescue_ctxt_t *ctxt, int i_round_key) { + blst_fr *state = rescue_get_state_from_context(ctxt); + blst_fr *round_constants = rescue_get_round_constants_from_context(ctxt); + for (int i = 0; i < ctxt->state_size; i++) { + blst_fr_add(state + i, state + i, round_constants + i_round_key++); + } + return (i_round_key); +} + +void marvellous_apply_permutation(rescue_ctxt_t *ctxt) { + int i_round_key = 0; + + for (int i = 0; i < ctxt->nb_rounds; i++) { + marvellous_apply_nonlinear_alpha(ctxt); + marvellous_apply_linear(ctxt); + i_round_key = marvellous_apply_cst(ctxt, i_round_key); + marvellous_apply_nonlinear_alphainv(ctxt); + marvellous_apply_linear(ctxt); + i_round_key = marvellous_apply_cst(ctxt, i_round_key); + } +} diff --git a/src/lib_bls12_381_hash/rescue.h b/src/lib_bls12_381_hash/rescue.h new file mode 100644 index 000000000000..1f95639128d8 --- /dev/null +++ b/src/lib_bls12_381_hash/rescue.h @@ -0,0 +1,26 @@ +#ifndef RESCUE_H +#define RESCUE_H + +#include "blst.h" +#include "blst_misc.h" + +typedef struct rescue_ctxt_s { + // Containts the state, the MDS and the constants + blst_fr *state; + int nb_rounds; + int state_size; +} rescue_ctxt_t; + +void marvellous_apply_permutation(rescue_ctxt_t *ctxt); + +blst_fr *rescue_get_state_from_context(rescue_ctxt_t *ctxt); + +blst_fr *rescue_get_mds_from_context(rescue_ctxt_t *ctxt); + +blst_fr *rescue_get_round_constants_from_context(rescue_ctxt_t *ctxt); + +int rescue_get_state_size_from_context(rescue_ctxt_t *ctxt); + +int rescue_get_number_of_constants_from_context(rescue_ctxt_t *ctxt); + +#endif diff --git a/src/lib_bls12_381_hash/rescue.ml b/src/lib_bls12_381_hash/rescue.ml new file mode 100644 index 000000000000..ded58a541c8d --- /dev/null +++ b/src/lib_bls12_381_hash/rescue.ml @@ -0,0 +1,181 @@ +module Stubs = struct + type ctxt + + external allocate_ctxt : + Bls12_381.Fr.t array array -> Bls12_381.Fr.t array -> int -> int -> ctxt + = "caml_bls12_381_hash_rescue_allocate_ctxt_stubs" + + external apply_permutation : ctxt -> unit + = "caml_bls12_381_hash_rescue_apply_permutation_stubs" + + external get_state : Bls12_381.Fr.t array -> ctxt -> unit + = "caml_bls12_381_hash_rescue_get_state_stubs" + + external get_state_size : ctxt -> int + = "caml_bls12_381_hash_rescue_get_state_size_stubs" + + external set_state : ctxt -> Bls12_381.Fr.t array -> unit + = "caml_bls12_381_hash_rescue_set_state_stubs" +end + +module Parameters = struct + type t = { + linear_layer : Bls12_381.Fr.t array array; + round_constants : Bls12_381.Fr.t array; + state_size : int; + nb_of_rounds : int; + } + + let state_size_3_mds = + [| + [| + "343"; + "52435875175126190479447740508185965837690552500527637822603658699938581184114"; + "57"; + |]; + [| + "19551"; + "52435875175126190479447740508185965837690552500527637822603658699938581162113"; + "2850"; + |]; + [| + "977550"; + "52435875175126190479447740508185965837690552500527637822603658699938580066914"; + "140050"; + |]; + |] + |> Array.map (Array.map Bls12_381.Fr.of_string) + + let state_size_3_round_constants = + [| + "35495817390819093545263349384941809089491580678942832859579453034368810736263"; + "4734865798690304458175502708216292605326887152358688691882538799996069070938"; + "31271008447681288492961289082649653266089021637020407236527451612237705002107"; + "3752272659749554246987316978069954116630957098620898965749354210894049705204"; + "22641555720019163306763445608116202165619173600682976754848212896631953422071"; + "28122533469631806190969995639553619503758826280316271478360761787725211583550"; + "25847917841495375497002109968427099088777388041775300281757084913772616807196"; + "32694606500120353152300866547101238346520817919199364752958292990138213972843"; + "27286327057691837800467727052167328890802672763096896941933952396730026264130"; + "11421505857991327619183254231367489753132565965114463729904675480639756627135"; + "521411871436069789624101480374109564923458769959324381065745329697883697117"; + "23880784307761253829209017376202022699450440759526482483183942457652656506129"; + "32944735989607121897647886317992117157418889561697480633116336030286723761501"; + "23809168654834556097350366212084670162247725165957937623679460641681583816451"; + "3163860194972429483721954648842733164010713297776971497284575674748141326227"; + "4994154821407041837874226315683255286085207059107827489820229821534877668868"; + "50472710115457611398312524300398743989276776324315737822995925423912734574272"; + "251866835357267652745308982111788504159393069098120092619439598668220537943"; + "29306447221479286209562070090539769526225070913770783266162336064629228514551"; + "29283041777181961494713136804131952798141345310627850728919908467956333015832"; + "28656363295645570828788643827370268834132346888229153863515891780361414296486"; + "25038928963239238795570624926346448459425394096652630785926109997438209703232"; + "8137054880809446884023200631931681550641379823710586899296036975467179806266"; + "40023642373942331790709007028495088784452433159634511649021697266107433596568"; + "35762237949937672281308268151392628513069349315494090383109234785560672634670"; + "30999566811631951689259246295471339743428563889981096112711184113782054324157"; + "20279178450660587763205226449293238908131708902882258115414408411285674682667"; + "7251226788353540177691937542431845975737106489341120571030231114808456476646"; + "52125099959305698802726608420202937507908602874086034970293871469588059526157"; + "36947771116325024965590213964896639663487838999452121836698608133540047510904"; + "6731449362796983987468313257604646517406447849071950000589095424962988643919"; + "46799204329731723451752711923834870677752669570495984560450489328024837708708"; + "35089631385082017128756246668734504606091189119241613702809534617529750689438"; + "48404791586561114467519265925614105026432456534013682923179665391057050944501"; + "25910045457085525717925797997640841840596905619632452927132962053945891631463"; + "1002644049329627578859603332717752156946995816186878866098534634466684910592"; + "27000834541453700882360080348023947440783037764820885196153273422481631245741"; + "12589074081116083610034305532223638886927072126291986576471860562392225733147"; + "42427223203410224646468929039478899902048566366856240877703602702087931641888"; + "13041605696900798404650686538893086909353822453068056131548498883864307018762"; + "7724559080250826493557773439911765324995115520951876421071063545832580076523"; + "2608760983816514764568197126437451665283344192910536302819820213681815485600"; + "4325576551800410431474186754039992813847609089390921236861130833620395142916"; + "28244869281227089786402354774575238327642814071062911402571918173773147690382"; + "52254320812514580546932455788288716956214894268551482805284261007871578815161"; + "44449246366481365934850731985584672122835299278127134772360027315881296465188"; + "38769336262079049280674269301353892930067342680672673045972987208159445324024"; + "42379436704506954159182654240696088598260763773619436089417882065405547940000"; + "22632779538473440042293241998410977359589070603696185849507766111228222504955"; + "15890983544445833013318912933113160561188216234423366865567699135890287302776"; + "42613622386509970285531317746282776785466762852259244468998263414951438072346"; + "3349279328650947992104289938299770603841093392045299702204191673899696292828"; + "24960454956681584943062398789550512391287992748093736571644480050215988836698"; + "31771416517485450527236959099354889665790926800645171236881417310335951093156"; + "6723262288337923380317441046361546981088139618189440979848042063784738198448"; + "34890105450847731125549485970715770779411614440863872580331681887247489622411"; + "11578979089604924419672152758230524155578424562011333797269885929442680042317"; + "50413588594256908654341963895371964591208017449187726872226940257366479794931"; + "25342645262500526730472670090219790271213097305995599586909134601382438580057"; + "8823851208157208211075893000112820438603010547555640271936182343488623715695"; + "48715166069588125017688857080421400882110756555551531562607166243928305121118"; + "457928742693316582022794368629361528074764749146022984852066320975235063636"; + "40784591676918140113004512439228960581998583153376036451231191678625605644121"; + "18433242804842005502998987143284711404363511412515282751547329224013759991670"; + "13389179080347763657382998600872902733061029331254291204270991952891409570918"; + "50192764209384080101272306620889875080455867628520281400927714930481563250325"; + "21188812847528225766555643216406799500549004969671500977130541863203997121380"; + "15467310814359095588985846207322319122950649805677111326687390171860927014900"; + "43568129081901200261103456211527409151200730655566657378341556085992472943958"; + "34271132631203889901701300408318058004416254071247236806623005223769350150039"; + "22173004425756666568314241635854763913339665884248599814793658197582222664954"; + "32975563242070450354147568749607182665869459510325615902750312087436132984686"; + "22696762757124796424578806530049133427552572655901519744413916679979764071390"; + "17763704296411643970998432037239004006015355463277677435659459899409343551392"; + "47107020014905029302099526236973268575042805085389783842994685212684421454488"; + "13304672766482627838923613214260444961210749299235217922669168410578113120633"; + "14336471400558675842362782084319960764287611922882892949544609123042059062824"; + "19303757685423427260649409150012846414071844305131989213305575732858057757894"; + "41105909312432760443399922527873622836019389621682258300053074843930035806751"; + "4449965847617470660026263611722341184463318026296894969809166330782012760219"; + "31939993490530073679397065723723444395703645080257573290017499883874398700446"; + "44612014630702294701797504988969181620837907283197659821551486351788471559337"; + "42992712381319065313644044212157260265940162092852802442073735607198967462282"; + "966835047744911231490794763166379188555949592683359886287393788918898119684"; + |] + |> Array.map Bls12_381.Fr.of_string + + let security_128_state_size_3 = + { + nb_of_rounds = 14; + state_size = 3; + linear_layer = state_size_3_mds; + round_constants = state_size_3_round_constants; + } +end + +type parameters = Parameters.t + +type ctxt = Stubs.ctxt + +let allocate_ctxt parameters = + let open Parameters in + if parameters.state_size <> 3 then + failwith "Only suppporting state size of 3 at the moment" ; + Stubs.allocate_ctxt + parameters.linear_layer + parameters.round_constants + parameters.nb_of_rounds + parameters.state_size + +let apply_permutation ctxt = Stubs.apply_permutation ctxt + +let set_state ctxt state = + let exp_state_size = Stubs.get_state_size ctxt in + let state_size = Array.length state in + if state_size <> exp_state_size then + failwith + (Printf.sprintf + "The given array contains %d elements but the expected state size is \ + %d" + state_size + exp_state_size) ; + Stubs.set_state ctxt state + +let get_state_size ctxt = Stubs.get_state_size ctxt + +let get_state ctxt = + let state_size = Stubs.get_state_size ctxt in + let state = Array.init state_size (fun _ -> Bls12_381.Fr.(copy zero)) in + Stubs.get_state state ctxt ; + state diff --git a/src/lib_bls12_381_hash/s.ml b/src/lib_bls12_381_hash/s.ml new file mode 100644 index 000000000000..3acf5f103124 --- /dev/null +++ b/src/lib_bls12_381_hash/s.ml @@ -0,0 +1,33 @@ +module type PERMUTATION = sig + (** Parameters for a specific instance *) + type parameters + + (** Context of the permutation *) + type ctxt + + (** [allocate_ctxt parameters]. Allocate a context for a specific instance of + the permutation. + *) + val allocate_ctxt : parameters -> ctxt + + (** Return the current state of the context *) + val get_state : ctxt -> Bls12_381.Fr.t array + + (** Return the state size of the context *) + val get_state_size : ctxt -> int + + (** [set_state ctxt state]. Set the context state to the given value. The + value [state] must be of the same size than the expecting state *) + val set_state : ctxt -> Bls12_381.Fr.t array -> unit + + (** Apply a permutation on the current state of the context *) + val apply_permutation : ctxt -> unit +end + +module type MODE = sig + val digest : + (module PERMUTATION with type parameters = 'p) -> + 'p -> + Bls12_381.Fr.t array -> + Bls12_381.Fr.t +end diff --git a/src/lib_bls12_381_hash/sponge.ml b/src/lib_bls12_381_hash/sponge.ml new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/lib_bls12_381_hash/test/dune b/src/lib_bls12_381_hash/test/dune new file mode 100644 index 000000000000..5cbe170e264d --- /dev/null +++ b/src/lib_bls12_381_hash/test/dune @@ -0,0 +1,37 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(executables + (names test_poseidon test_rescue test_anemoi test_griffin test_jive) + (libraries + alcotest + bls12-381 + octez-bls12-381-hash) + (flags + (:standard) + -w -3)) + +(rule + (alias runtest) + (package octez-bls12-381-hash) + (action (run %{dep:./test_poseidon.exe}))) + +(rule + (alias runtest) + (package octez-bls12-381-hash) + (action (run %{dep:./test_rescue.exe}))) + +(rule + (alias runtest) + (package octez-bls12-381-hash) + (action (run %{dep:./test_anemoi.exe}))) + +(rule + (alias runtest) + (package octez-bls12-381-hash) + (action (run %{dep:./test_griffin.exe}))) + +(rule + (alias runtest) + (package octez-bls12-381-hash) + (action (run %{dep:./test_jive.exe}))) diff --git a/src/lib_bls12_381_hash/test/test_anemoi.ml b/src/lib_bls12_381_hash/test/test_anemoi.ml new file mode 100644 index 000000000000..5c08e8ee853a --- /dev/null +++ b/src/lib_bls12_381_hash/test/test_anemoi.ml @@ -0,0 +1,564 @@ +(* Generated using + https://github.com/vesselinux/anemoi-hash/commit/9d9fc2a52e31c5e9379be2856414233e4e780f58 + with: + test_jive( + n_tests=10, + q=52435875175126190479447740508185965837690552500527637822603658699938581184513, + alpha=5, + n_rounds=19, + n_cols=1, + b=2, + security_level=128) +*) + +let test_vectors_anemoi128_1 () = + let vectors = + [ + ( ( "35845669682800269995209049467553751861599775089532198376674489477778357560569", + "28310433413288793552092391706285055875131165883761155923425672020460794794380" + ), + "17700999234906509130159287769741962009709982288860491609792036961305502635098" + ); + ( ( "13880477308466057091493501926554391163288910083198657398974047674796581779693", + "28373522553669637689090633983852091038187643792080489433228018701827926002768" + ), + "12743339877423634016102198261148085947154915493891480470390198918335851344292" + ); + ( ( "38216845839357573472239023564373200263918534132389374505946789120458119648667", + "39487400661842934211797098190376905462917596530484823725006452014098066670694" + ), + "20572002340893814224552312721780888755123139461240945499350006876769919946773" + ); + ( ( "31131499311453094268713009639057190648340672035944963596113874024605484784791", + "43680468547604090714590688733926978605538499294774749079842255618079617105051" + ), + "20569340066597303483907565303221880873948750088343130268109858923675035314078" + ); + ( ( "10924450358499789254279737793602938412226831772739559590509902641736698048741", + "18748800755846695314043868352493820136560550891447333332696158632417495012819" + ), + "26749108456690136523602417383379636205348260403407066884482315588658233098940" + ); + ( ( "46462878845927326448614772124701161417983809741866268465266076023457688715870", + "38375603405434266869135117417290149314037130980580543700755400748014512343979" + ), + "2673364003345693113273421176038865068057650274048787980068125230806361632850" + ); + ( ( "39170732922513369978795230271067076371378632409257775938940964299534787717175", + "2408517610992178001486942104041564424468943886715588829396035415376300986469" + ), + "13310229620063667311431399083462393119055434191991960510670894258662703203975" + ); + ] + in + List.iter + (fun ((x1_s, x2_s), exp_res_s) -> + let x1 = Bls12_381.Fr.of_string x1_s in + let x2 = Bls12_381.Fr.of_string x2_s in + let exp_res = Bls12_381.Fr.of_string exp_res_s in + let res = Bls12_381_hash.Permutation.Anemoi.jive128_1 x1 x2 in + if not (Bls12_381.Fr.eq res exp_res) then + Alcotest.failf + "Expected result = %s, computed result = %s, input = (%s, %s)" + exp_res_s + (Bls12_381.Fr.to_string res) + x1_s + x2_s) + vectors + +let test_vectors_anemoi128_2 () = + let vectors = + [ + ( ("0", "0", "0", "0"), + ( "23506137766702864106501714498337645198425779982503345533323642665774237530743", + "34447732706544914382845425456929395985238811287211171548953979792382042373740", + "38305963246199256223939132687221377996807495295070124114622442403207046030062", + "52085062252809860097055957733590114937197370490476211931083350477393806117621" + ) ); + ( ( "27839080182556610705887939966818701340864145322792715287810357208440914854281", + "41481150764080331637382663225726959872938887013456865948198868284552242708519", + "38189883379737770191491270513853770942621403161576272820058113505808823630900", + "6529435419442382849730797362349015216552820358285062739653681825023447217068" + ), + ( "14473897802199918953583228273316340143396476374899351470678632558263678699877", + "24587633048074155346278630990352810495608304969367523541545168873834143089902", + "47132715740050880437392890948798686584816384888633241850565214056840729624505", + "6606493401694644772471916676579866387417408500033435451518189487740033865747" + ) ); + ( ( "14716987267992449080941609095284865759356382937671116288486258350642247071627", + "13760197033165110695402422952291893734496635277111384162422733902296757710874", + "33294609204786805322854530266028003773787556848644980529869834547261241614105", + "11644531352096195394853594279658462131209985215175335801365205433425048456350" + ), + ( "47737136264857950730454747976524405656326494304978652844311111261281852476501", + "13716019695701301324018899979909121742372906083132069510290774177616830373506", + "19515279450582255760487675881545023135485186764178376441852639052497885578212", + "45847068138243304073707520982719523479147863491193499975734034993479294600685" + ) ); + ( ( "42824693565443175259806687802757821151773600948730449896541161263256961486645", + "31633466755115991202264118192133521021227289162761994770025404887100313415161", + "43223036947018592502360048383150256123208669504194939523196078411285214762463", + "7192257416851768692824129030440632757292330835871601049965097914082460916711" + ), + ( "38660702903297582610177132699877133632374538437943056324961513888350888194086", + "31630694424006989989717484628399682914962426161626133340250479990037519265561", + "13466503268904584668912085977052425437912732123809722793173012874164204852136", + "4471437305484391530147684290538853431954907851628258053432383018741801157611" + ) ); + ] + in + + List.iter + (fun ( (x1_s, x2_s, y1_s, y2_s), + (exp_res_x1_s, exp_res_x2_s, exp_res_y1_s, exp_res_y2_s) ) -> + let x1 = Bls12_381.Fr.of_string x1_s in + let x2 = Bls12_381.Fr.of_string x2_s in + let y1 = Bls12_381.Fr.of_string y1_s in + let y2 = Bls12_381.Fr.of_string y2_s in + let exp_res_x1 = Bls12_381.Fr.of_string exp_res_x1_s in + let exp_res_x2 = Bls12_381.Fr.of_string exp_res_x2_s in + let exp_res_y1 = Bls12_381.Fr.of_string exp_res_y1_s in + let exp_res_y2 = Bls12_381.Fr.of_string exp_res_y2_s in + let state = [|x1; x2; y1; y2|] in + let ctxt = + Bls12_381_hash.Permutation.Anemoi.allocate_ctxt + Bls12_381_hash.Permutation.Anemoi.Parameters.security_128_state_size_4 + in + let () = Bls12_381_hash.Permutation.Anemoi.set_state ctxt state in + let () = Bls12_381_hash.Permutation.Anemoi.apply_permutation ctxt in + let output = Bls12_381_hash.Permutation.Anemoi.get_state ctxt in + let res_x1, res_x2, res_y1, res_y2 = + (output.(0), output.(1), output.(2), output.(3)) + in + let res_x1_s = Bls12_381.Fr.to_string res_x1 in + let res_x2_s = Bls12_381.Fr.to_string res_x2 in + let res_y1_s = Bls12_381.Fr.to_string res_y1 in + let res_y2_s = Bls12_381.Fr.to_string res_y2 in + let is_eq = + Bls12_381.Fr.eq res_x1 exp_res_x1 + && Bls12_381.Fr.eq res_x2 exp_res_x2 + && Bls12_381.Fr.eq res_y1 exp_res_y1 + && Bls12_381.Fr.eq res_y2 exp_res_y2 + in + if not is_eq then + Alcotest.failf + "Expected result = (%s, %s, %s, %s), computed result = (%s, %s, %s, \ + %s), input = (%s, %s, %s, %s)" + exp_res_x1_s + exp_res_x2_s + exp_res_y1_s + exp_res_y2_s + res_x1_s + res_x2_s + res_y1_s + res_y2_s + x1_s + x2_s + y1_s + y2_s) + vectors + +let test_vectors_anemoi128_3 () = + let vectors = + [ + ( ("0", "0", "0", "0", "0", "0"), + ( "33478314834223416808169927398566653899403429754255462666159894772887073320365", + "47176243459522521751687145816065715088321551004033205074244614792181543416010", + "23618281931389771856815846815269641563251679885040985573831869306241272644113", + "31724951276938006062858814692792550537217527277501666853791904466055832323690", + "42647860407630674344335892435289166728294144362723196232677285611394540961425", + "19471638696219074945013770512807270758314299984285699758112364258991389044512" + ) ); + ( ("1", "1", "1", "1", "1", "1"), + ( "35479415329613071429429550675265174289054891063407106141043395424648010771320", + "40306996468472921766576498685266538561364696876140265870598730755251029512891", + "20690705352280971494112435038111871800589215895863022560441462778525416320807", + "46706916210868941572390746709219268688104096455025207646228390693939029609098", + "36997439342487000681405280778882655995987145098763687399724629582578794692794", + "48039916176227764586762930360199537139847085765157498900275563135023139617488" + ) ); + ( ("0", "0", "0", "1", "1", "1"), + ( "37933281578278578226664982565092449003672438365411607042195625975115660158828", + "44753139152867038775378832584199388585565237869691759485112778145882682277556", + "32230208920419839266320424365836626532619521980144779932965733449069428147791", + "49800001876826046352042671365996929335824355383400972887543145110732946379057", + "5180942914719476310821602386486420533986710078522585795533936269418555321952", + "2679906742199435085043898910663175140308975212645374494483508379075336654721" + ) ); + ] + in + + List.iter + (fun ( (x1_s, x2_s, x3_s, y1_s, y2_s, y3_s), + ( exp_res_x1_s, + exp_res_x2_s, + exp_res_x3_s, + exp_res_y1_s, + exp_res_y2_s, + exp_res_y3_s ) ) -> + let x1 = Bls12_381.Fr.of_string x1_s in + let x2 = Bls12_381.Fr.of_string x2_s in + let x3 = Bls12_381.Fr.of_string x3_s in + let y1 = Bls12_381.Fr.of_string y1_s in + let y2 = Bls12_381.Fr.of_string y2_s in + let y3 = Bls12_381.Fr.of_string y3_s in + let exp_res_x1 = Bls12_381.Fr.of_string exp_res_x1_s in + let exp_res_x2 = Bls12_381.Fr.of_string exp_res_x2_s in + let exp_res_x3 = Bls12_381.Fr.of_string exp_res_x3_s in + let exp_res_y1 = Bls12_381.Fr.of_string exp_res_y1_s in + let exp_res_y2 = Bls12_381.Fr.of_string exp_res_y2_s in + let exp_res_y3 = Bls12_381.Fr.of_string exp_res_y3_s in + let state = [|x1; x2; x3; y1; y2; y3|] in + let ctxt = + Bls12_381_hash.Permutation.Anemoi.allocate_ctxt + Bls12_381_hash.Permutation.Anemoi.Parameters.security_128_state_size_6 + in + let () = Bls12_381_hash.Permutation.Anemoi.set_state ctxt state in + let () = Bls12_381_hash.Permutation.Anemoi.apply_permutation ctxt in + let output = Bls12_381_hash.Permutation.Anemoi.get_state ctxt in + let res_x1, res_x2, res_x3, res_y1, res_y2, res_y3 = + (output.(0), output.(1), output.(2), output.(3), output.(4), output.(5)) + in + let res_x1_s = Bls12_381.Fr.to_string res_x1 in + let res_x2_s = Bls12_381.Fr.to_string res_x2 in + let res_x3_s = Bls12_381.Fr.to_string res_x3 in + let res_y1_s = Bls12_381.Fr.to_string res_y1 in + let res_y2_s = Bls12_381.Fr.to_string res_y2 in + let res_y3_s = Bls12_381.Fr.to_string res_y3 in + let is_eq = + Bls12_381.Fr.eq res_x1 exp_res_x1 + && Bls12_381.Fr.eq res_x2 exp_res_x2 + && Bls12_381.Fr.eq res_x3 exp_res_x3 + && Bls12_381.Fr.eq res_y1 exp_res_y1 + && Bls12_381.Fr.eq res_y2 exp_res_y2 + && Bls12_381.Fr.eq res_y3 exp_res_y3 + in + if not is_eq then + Alcotest.failf + "Expected result = (%s, %s, %s, %s, %s, %s), computed result = (%s, \ + %s, %s, %s, %s, %s), input = (%s, %s, %s, %s, %s, %s)" + exp_res_x1_s + exp_res_x2_s + exp_res_x3_s + exp_res_y1_s + exp_res_y2_s + exp_res_y3_s + res_x1_s + res_x2_s + res_x3_s + res_y1_s + res_y2_s + res_y3_s + x1_s + x2_s + x3_s + y1_s + y2_s + y3_s) + vectors + +let test_vectors_anemoi128_4 () = + let vectors = + [ + ( ("0", "0", "0", "0", "0", "0", "0", "0"), + ( "7706460525141057798581274838395425127394178058031335456383676808670282739597", + "7765006946327915662125438952942444007224155128922309040617707265091525101650", + "36678898577444650135514357278510022052240370283820393434444670594528685414542", + "38112460417474206233727356444574986419489443411513333432061688919529220935208", + "32886919269921708859920915140938102703808094739820106011065065407661206427905", + "31957519853632408523793272895865433064889015146894845079565739509711556279655", + "48507819850717925613830013169811675061814439063072799726071757655412038748460", + "12054807835900330617081688019415644583219549287154039455011128765870547430639" + ) ); + ] + in + + List.iter + (fun ( (x1_s, x2_s, x3_s, x4_s, y1_s, y2_s, y3_s, y4_s), + ( exp_res_x1_s, + exp_res_x2_s, + exp_res_x3_s, + exp_res_x4_s, + exp_res_y1_s, + exp_res_y2_s, + exp_res_y3_s, + exp_res_y4_s ) ) -> + let x1 = Bls12_381.Fr.of_string x1_s in + let x2 = Bls12_381.Fr.of_string x2_s in + let x3 = Bls12_381.Fr.of_string x3_s in + let x4 = Bls12_381.Fr.of_string x4_s in + let y1 = Bls12_381.Fr.of_string y1_s in + let y2 = Bls12_381.Fr.of_string y2_s in + let y3 = Bls12_381.Fr.of_string y3_s in + let y4 = Bls12_381.Fr.of_string y4_s in + let exp_res_x1 = Bls12_381.Fr.of_string exp_res_x1_s in + let exp_res_x2 = Bls12_381.Fr.of_string exp_res_x2_s in + let exp_res_x3 = Bls12_381.Fr.of_string exp_res_x3_s in + let exp_res_x4 = Bls12_381.Fr.of_string exp_res_x4_s in + let exp_res_y1 = Bls12_381.Fr.of_string exp_res_y1_s in + let exp_res_y2 = Bls12_381.Fr.of_string exp_res_y2_s in + let exp_res_y3 = Bls12_381.Fr.of_string exp_res_y3_s in + let exp_res_y4 = Bls12_381.Fr.of_string exp_res_y4_s in + let state = [|x1; x2; x3; x4; y1; y2; y3; y4|] in + let ctxt = + Bls12_381_hash.Permutation.Anemoi.( + allocate_ctxt Parameters.security_128_state_size_8) + in + let () = Bls12_381_hash.Permutation.Anemoi.set_state ctxt state in + let () = Bls12_381_hash.Permutation.Anemoi.apply_permutation ctxt in + let output = Bls12_381_hash.Permutation.Anemoi.get_state ctxt in + let res_x1, res_x2, res_x3, res_x4, res_y1, res_y2, res_y3, res_y4 = + ( output.(0), + output.(1), + output.(2), + output.(3), + output.(4), + output.(5), + output.(6), + output.(7) ) + in + let res_x1_s = Bls12_381.Fr.to_string res_x1 in + let res_x2_s = Bls12_381.Fr.to_string res_x2 in + let res_x3_s = Bls12_381.Fr.to_string res_x3 in + let res_x4_s = Bls12_381.Fr.to_string res_x4 in + let res_y1_s = Bls12_381.Fr.to_string res_y1 in + let res_y2_s = Bls12_381.Fr.to_string res_y2 in + let res_y3_s = Bls12_381.Fr.to_string res_y3 in + let res_y4_s = Bls12_381.Fr.to_string res_y4 in + let is_eq = + Bls12_381.Fr.eq res_x1 exp_res_x1 + && Bls12_381.Fr.eq res_x2 exp_res_x2 + && Bls12_381.Fr.eq res_x3 exp_res_x3 + && Bls12_381.Fr.eq res_x4 exp_res_x4 + && Bls12_381.Fr.eq res_y1 exp_res_y1 + && Bls12_381.Fr.eq res_y2 exp_res_y2 + && Bls12_381.Fr.eq res_y3 exp_res_y3 + && Bls12_381.Fr.eq res_y4 exp_res_y4 + in + if not is_eq then + Alcotest.failf + "Expected result = (%s, %s, %s, %s, %s, %s, %s, %s), computed result \ + = (%s, %s, %s, %s, %s, %s, %s, %s), input = (%s, %s, %s, %s, %s, \ + %s, %s, %s)" + exp_res_x1_s + exp_res_x2_s + exp_res_x3_s + exp_res_x4_s + exp_res_y1_s + exp_res_y2_s + exp_res_y3_s + exp_res_y4_s + res_x1_s + res_x2_s + res_x3_s + res_x4_s + res_y1_s + res_y2_s + res_y3_s + res_y4_s + x1_s + x2_s + x3_s + x4_s + y1_s + y2_s + y3_s + y4_s) + vectors + +let test_state_functions () = + let l = 5 + Random.int 10 in + let mds = + Array.init l (fun _ -> Array.init l (fun _ -> Bls12_381.Fr.random ())) + in + let state_size = 2 * l in + let state = Array.init state_size (fun _ -> Bls12_381.Fr.random ()) in + let parameters = + Bls12_381_hash.Permutation.Anemoi.Parameters.create 128 state_size mds + in + let ctxt = Bls12_381_hash.Permutation.Anemoi.allocate_ctxt parameters in + let () = Bls12_381_hash.Permutation.Anemoi.set_state ctxt state in + let output = Bls12_381_hash.Permutation.Anemoi.get_state ctxt in + if not (Array.for_all2 Bls12_381.Fr.eq state output) then + Alcotest.failf + "Exp: [%s], computed: [%s]" + (String.concat + "; " + (List.map Bls12_381.Fr.to_string (Array.to_list state))) + (String.concat + "; " + (List.map Bls12_381.Fr.to_string (Array.to_list output))) + +let test_anemoi_generic_with_l_one_is_anemoi_jive128_1 () = + let state_size = 2 in + let state = Array.init state_size (fun _ -> Bls12_381.Fr.random ()) in + let ctxt = + Bls12_381_hash.Permutation.Anemoi.( + allocate_ctxt Parameters.security_128_state_size_2) + in + let () = Bls12_381_hash.Permutation.Anemoi.set_state ctxt state in + let () = Bls12_381_hash.Permutation.Anemoi.apply_permutation ctxt in + let output = Bls12_381_hash.Permutation.Anemoi.get_state ctxt in + assert ( + Bls12_381.Fr.eq + (Bls12_381_hash.Permutation.Anemoi.jive128_1 state.(0) state.(1)) + Bls12_381.Fr.(state.(0) + state.(1) + output.(0) + output.(1))) + +let test_compute_number_of_rounds () = + assert ( + Bls12_381_hash.Permutation.Anemoi.Parameters.compute_number_of_rounds 2 128 + = 19) ; + assert ( + Bls12_381_hash.Permutation.Anemoi.Parameters.compute_number_of_rounds 4 128 + = 12) ; + assert ( + Bls12_381_hash.Permutation.Anemoi.Parameters.compute_number_of_rounds 6 128 + = 10) ; + assert ( + Bls12_381_hash.Permutation.Anemoi.Parameters.compute_number_of_rounds 8 128 + = 10) ; + assert ( + Bls12_381_hash.Permutation.Anemoi.Parameters.compute_number_of_rounds 2 256 + = 35) ; + assert ( + Bls12_381_hash.Permutation.Anemoi.Parameters.compute_number_of_rounds 4 256 + = 20) ; + assert ( + Bls12_381_hash.Permutation.Anemoi.Parameters.compute_number_of_rounds 6 256 + = 15) ; + assert ( + Bls12_381_hash.Permutation.Anemoi.Parameters.compute_number_of_rounds 8 256 + = 14) + +let test_anemoi_generate_constants () = + let l = 1 in + let nb_rounds = 19 in + let exp_res = + Bls12_381.Fr. + [| + of_string "39"; + of_string + "41362478282768062297187132445775312675360473883834860695283235286481594490621"; + of_string + "9548818195234740988996233204400874453525674173109474205108603996010297049928"; + of_string + "25365440569177822667580105183435418073995888230868180942004497015015045856900"; + of_string + "34023498397393406644117994167986720327178154686105264833093891093045919619309"; + of_string + "38816051319719761886041858113129205506758421478656182868737326994635468402951"; + of_string + "35167418087531820804128377095512663922179887277669504047069913414630376083753"; + of_string + "25885868839756469722325652387535232478219821850603640827385444642154834700231"; + of_string + "8867588811641202981080659274007552529205713737251862066053445622305818871963"; + of_string + "36439756010140137556111047750162544185710881404522379792044818039722752946048"; + of_string + "7788624504122357216765350546787885309160020166693449889975992574536033007374"; + of_string + "3134147137704626983201116226440762775442116005053282329971088789984415999550"; + of_string + "50252287380741824818995733304361249016282047978221591906573165442023106203143"; + of_string + "48434698978712278012409706205559577163572452744833134361195687109159129985373"; + of_string + "32960510617530186159512413633821386297955642598241661044178889571655571939473"; + of_string + "12850897859166761094422335671106280470381427571695744605265713866647560628356"; + of_string + "14578036872634298798382048587794204613583128573535557156943783762854124345644"; + of_string + "21588109842058901916690548710649523388049643745013696896704903154857389904594"; + of_string + "35731638686520516424752846654442973203189295883541072759390882351699754104989"; + of_string + "14981678621464625851270783002338847382197300714436467949315331057125308909900"; + of_string + "28253420209785428420233456008091632509255652343634529984400816700490470131093"; + of_string + "51511939407083344002778208487678590135577660247075600880835916725469990319313"; + of_string + "46291121544435738125248657675097664742296276807186696922340332893747842754587"; + of_string + "3650460179273129580093806058710273018999560093475503119057680216309578390988"; + of_string + "45802223370746268123059159806400152299867771061127345631244786118574025749328"; + of_string + "11798621276624967315721748990709309216351696098813162382053396097866233042733"; + of_string + "42372918959432199162670834641599336326433006968669415662488070504036922966492"; + of_string + "52181371244193189669553521955614617990714056725501643636576377752669773323445"; + of_string + "23791984554824031672195249524658580601428376029501889159059009332107176394097"; + of_string + "33342520831620303764059548442834699069640109058400548818586964467754352720368"; + of_string + "16791548253207744974576845515705461794133799104808996134617754018912057476556"; + of_string + "11087343419860825311828133337767238110556416596687749174422888171911517001265"; + of_string + "11931207770538477937808955037363240956790374856666237106403111503668796872571"; + of_string + "3296943608590459582451043049934874894049468383833500962645016062634514172805"; + of_string + "7080580976521357573320018355401935489220216583936865937104131954142364033647"; + of_string + "25990144965911478244481527888046366474489820502460615136523859419965697796405"; + of_string + "33907313384235729375566529911940467295099705980234607934575786561097199483218"; + of_string + "25996950265608465541351207283024962044374873682152889814392533334239395044136"; + |] + in + let res = + Bls12_381_hash.Permutation.Anemoi.Parameters.generate_constants nb_rounds l + in + assert (Array.for_all2 Bls12_381.Fr.eq exp_res res) + +let () = + let open Alcotest in + run + "The permutation Anemoi and the mode of operation Jive" + [ + ( "From reference implementation", + [ + test_case + "Tests vectors from reference implementation" + `Quick + test_vectors_anemoi128_1; + ] ); + ( "Generic instantiations", + [ + test_case + "l = 1 <==> jive128_1" + `Quick + test_anemoi_generic_with_l_one_is_anemoi_jive128_1; + test_case + "l = 2 -> tests vectors from reference implementation" + `Quick + test_vectors_anemoi128_2; + test_case + "l = 4 -> tests vectors from reference implementation" + `Quick + test_vectors_anemoi128_4; + test_case + "l = 3 -> tests vectors from reference implementation" + `Quick + test_vectors_anemoi128_3; + ] ); + ( "Additional functions", + [ + test_case + "State initialisation and get state" + `Quick + test_state_functions; + test_case "Constant generation" `Quick test_anemoi_generate_constants; + test_case + "Compute number of rounds" + `Quick + test_compute_number_of_rounds; + ] ); + ] diff --git a/src/lib_bls12_381_hash/test/test_griffin.ml b/src/lib_bls12_381_hash/test/test_griffin.ml new file mode 100644 index 000000000000..7585418aa189 --- /dev/null +++ b/src/lib_bls12_381_hash/test/test_griffin.ml @@ -0,0 +1,171 @@ +let test_state_getter_setter () = + let parameters = + Bls12_381_hash.Permutation.Griffin.Parameters.security_128_state_size_3 + in + let ctxt = Bls12_381_hash.Permutation.Griffin.allocate_ctxt parameters in + + let state = + Array.init + parameters.Bls12_381_hash.Permutation.Griffin.Parameters.state_size + (fun _ -> Bls12_381.Fr.random ()) + in + let () = Bls12_381_hash.Permutation.Griffin.set_state ctxt state in + assert ( + Array.for_all2 + Bls12_381.Fr.eq + state + (Bls12_381_hash.Permutation.Griffin.get_state ctxt)) + +let test_vectors_griffin_3 () = + (* Generated from https://extgit.iaik.tugraz.at/krypto/zkfriendlyhashzoo *) + let vectors = + [ + ( ("0", "0", "0"), + ( "841791784119451836895521356553213353441862647772555419706984344393580307020", + "2113910108688023830687972208474679779076805829875515720963977502550499149602", + "39803944790582685391308803209116565255311062071666522256011667391677817204123" + ) ); + ( ( "18463500124224312515875567238728244985257614546546778836630989065496961733332", + "46981865534249059754749826182943352598004016487267289209329045182268251827732", + "281220935108567092124864882450372048777669128036755944610462739083424420854" + ), + ( "312967684503808125264008501181907359079558761116291453411613667947766899516", + "45085022860794304016331869598892373488807386198128958652149726446059364221856", + "3143235844449445682654083063998365970447678809821256700746892060010723945844" + ) ); + ( ( "37430619512013660924725326078209379186383782215505557594723583515547878680657", + "15993191006246128054961715163349476792514546237817331760637228653648805884929", + "586854312443779697715508748423011917816841144091125416169048666119872372790" + ), + ( "17795078392989753588187047645247938619792251973934963507233142728921502730375", + "23947216748739774482602221821766081757111537527154723423518134779107549197638", + "10733328928829291297000046981966971033540811270220965825105168354718419883281" + ) ); + ] + in + List.iter + (fun ((x1_s, x2_s, x3_s), (exp_res1_s, exp_res2_s, exp_res3_s)) -> + let x1 = Bls12_381.Fr.of_string x1_s in + let x2 = Bls12_381.Fr.of_string x2_s in + let x3 = Bls12_381.Fr.of_string x3_s in + let exp_res1 = Bls12_381.Fr.of_string exp_res1_s in + let exp_res2 = Bls12_381.Fr.of_string exp_res2_s in + let exp_res3 = Bls12_381.Fr.of_string exp_res3_s in + let ctxt = + Bls12_381_hash.Permutation.Griffin.allocate_ctxt + Bls12_381_hash.Permutation.Griffin.Parameters + .security_128_state_size_3 + in + let () = + Bls12_381_hash.Permutation.Griffin.set_state ctxt [|x1; x2; x3|] + in + let () = Bls12_381_hash.Permutation.Griffin.apply_permutation ctxt in + let res = Bls12_381_hash.Permutation.Griffin.get_state ctxt in + let res1, res2, res3 = (res.(0), res.(1), res.(2)) in + let b = + Bls12_381.Fr.eq exp_res1 res1 + && Bls12_381.Fr.eq exp_res2 res2 + && Bls12_381.Fr.eq exp_res3 res3 + in + if not b then + Alcotest.failf + "Expected result = (%s, %s, %s), computed result = (%s, %s, %s), \ + input = (%s, %s, %s)" + exp_res1_s + exp_res2_s + exp_res3_s + (Bls12_381.Fr.to_string res1) + (Bls12_381.Fr.to_string res2) + (Bls12_381.Fr.to_string res3) + x1_s + x2_s + x3_s) + vectors + +let test_vectors_griffin_4 () = + (* Generated from https://extgit.iaik.tugraz.at/krypto/zkfriendlyhashzoo *) + let vectors = + [ + ( ("0", "0", "0", "0"), + ( "42055013899249843001963096382529769773374725832883030314842616909329673256554", + "37539438133362431743003153246954584523646613658726962536114018819275530248977", + "48674648934505632020893033170300663189772692405048902597301372423269515724906", + "26051996228945922008001164667516225310485844262139985745397463874220219812431" + ) ); + ] + in + List.iter + (fun ( (x1_s, x2_s, x3_s, x4_s), + (exp_res1_s, exp_res2_s, exp_res3_s, exp_res4_s) ) -> + let x1 = Bls12_381.Fr.of_string x1_s in + let x2 = Bls12_381.Fr.of_string x2_s in + let x3 = Bls12_381.Fr.of_string x3_s in + let x4 = Bls12_381.Fr.of_string x4_s in + let exp_res1 = Bls12_381.Fr.of_string exp_res1_s in + let exp_res2 = Bls12_381.Fr.of_string exp_res2_s in + let exp_res3 = Bls12_381.Fr.of_string exp_res3_s in + let exp_res4 = Bls12_381.Fr.of_string exp_res4_s in + let ctxt = + Bls12_381_hash.Permutation.Griffin.( + allocate_ctxt Parameters.security_128_state_size_4) + in + let () = + Bls12_381_hash.Permutation.Griffin.set_state ctxt [|x1; x2; x3; x4|] + in + let () = Bls12_381_hash.Permutation.Griffin.apply_permutation ctxt in + let res = Bls12_381_hash.Permutation.Griffin.get_state ctxt in + let res1, res2, res3, res4 = (res.(0), res.(1), res.(2), res.(3)) in + let b = + Bls12_381.Fr.eq exp_res1 res1 + && Bls12_381.Fr.eq exp_res2 res2 + && Bls12_381.Fr.eq exp_res3 res3 + && Bls12_381.Fr.eq exp_res4 res4 + in + if not b then + Alcotest.failf + "Expected result = (%s, %s, %s, %s), computed result = (%s, %s, %s, \ + %s), input = (%s, %s, %s, %s)" + exp_res1_s + exp_res2_s + exp_res3_s + exp_res4_s + (Bls12_381.Fr.to_string res1) + (Bls12_381.Fr.to_string res2) + (Bls12_381.Fr.to_string res3) + (Bls12_381.Fr.to_string res4) + x1_s + x2_s + x3_s + x4_s) + vectors + +(* + Bls12_381.Fr. + [| of_string + "42055013899249843001963096382529769773374725832883030314842616909329673256554"; + of_string + "37539438133362431743003153246954584523646613658726962536114018819275530248977"; + of_string + "48674648934505632020893033170300663189772692405048902597301372423269515724906"; + of_string + "26051996228945922008001164667516225310485844262139985745397463874220219812431" + |] + *) +let () = + let open Alcotest in + run + "Griffin" + [ + ( "Test vectors", + [ + test_case + "from reference implementation: Griffin 3" + `Quick + test_vectors_griffin_3; + test_case + "from reference implementation: Griffin 4" + `Quick + test_vectors_griffin_4; + ] ); + ("State", [test_case "get and set" `Quick test_state_getter_setter]); + ] diff --git a/src/lib_bls12_381_hash/test/test_jive.ml b/src/lib_bls12_381_hash/test/test_jive.ml new file mode 100644 index 000000000000..7956c15398dd --- /dev/null +++ b/src/lib_bls12_381_hash/test/test_jive.ml @@ -0,0 +1,164 @@ +let test_fail_input_size_and_parameters_do_not_match () = + (* TODO: add Poseidon state size 2 and Rescue state size 2 *) + let args : + ((module Bls12_381_hash.PERMUTATION with type parameters = 'p) * 'p) list + = + [ + ( (module Bls12_381_hash.Permutation.Anemoi : Bls12_381_hash.PERMUTATION + with type parameters = 'p), + Bls12_381_hash.Permutation.Anemoi.Parameters.security_128_state_size_2 + ); + ] + in + List.iter + (fun ( (module P : Bls12_381_hash.PERMUTATION with type parameters = 'p), + (security_param : 'p) ) -> + let input_size = 3 + Random.int 10 in + let input = Array.init input_size (fun _ -> Bls12_381.Fr.random ()) in + let msg = + Printf.sprintf + "The given array contains %d elements but the expected state size is \ + %d" + input_size + 2 + in + Alcotest.check_raises msg (Failure msg) (fun () -> + ignore + @@ Bls12_381_hash.Mode.Jive.digest (module P) security_param input)) + args + +let test_fail_b_does_not_divide_input_size () = + let args : + ((module Bls12_381_hash.PERMUTATION with type parameters = 'p) * 'p) list + = + [ + ( (module Bls12_381_hash.Permutation.Anemoi : Bls12_381_hash.PERMUTATION + with type parameters = 'p), + Bls12_381_hash.Permutation.Anemoi.Parameters.security_128_state_size_2 + ); + ( (module Bls12_381_hash.Permutation.Anemoi : Bls12_381_hash.PERMUTATION + with type parameters = 'p), + Bls12_381_hash.Permutation.Anemoi.Parameters.security_128_state_size_6 + ); + ] + in + List.iter + (fun ( (module P : Bls12_381_hash.PERMUTATION with type parameters = 'p), + (security_param : 'p) ) -> + let input_size = 2 in + let input = Array.init input_size (fun _ -> Bls12_381.Fr.random ()) in + let msg = "b must divide the state size" in + Alcotest.check_raises msg (Failure msg) (fun () -> + ignore + @@ Bls12_381_hash.Mode.Jive.digest_b (module P) security_param input 4)) + args + +let test_anemoi_state_size_2 () = + let module P = Bls12_381_hash.Permutation.Anemoi in + let x = Bls12_381.Fr.random () in + let y = Bls12_381.Fr.random () in + let b = 2 in + let output = P.jive128_1 x y in + let digest x y = + let exp_output_arr = + Bls12_381_hash.Mode.Jive.digest_b + (module P) + P.Parameters.security_128_state_size_2 + [|x; y|] + b + in + exp_output_arr.(0) + in + assert (Bls12_381.Fr.eq (digest x y) output) + +let test_anemoi_state_size_4 () = + let module P = Bls12_381_hash.Permutation.Anemoi in + let x1 = + Bls12_381.Fr.( + of_string + "39288125054603279103948425330560623804007631364900524838724476048252426591743") + in + let x2 = + Bls12_381.Fr.of_string + "28658687495010692659636508039246286087279814855063761962675596314362063193900" + in + let y1 = + Bls12_381.Fr.of_string + "30521808372563254163692862709213142878392090740378072614276234596069106349049" + in + let y2 = + Bls12_381.Fr.of_string + "51096746034954956708153164168845755025167527045502628092780406829455255679008" + in + let b = 2 in + let exp_output = + [| + Bls12_381.Fr.of_string + "4516709370008583832348307341992110967410468602387451593697260587093413732828"; + Bls12_381.Fr.of_string + "14149364429884734929697042590398920659221729533171735081487592237091711387703"; + |] + in + let output = + Bls12_381_hash.Mode.Jive.digest_b + (module P) + P.Parameters.security_128_state_size_4 + [|x1; x2; y1; y2|] + b + in + assert (Array.for_all2 Bls12_381.Fr.eq exp_output output) + +let test_anemoi_state_size_6 () = + let module P = Bls12_381_hash.Permutation.Anemoi in + let input = + [| + "2217853344865862743970224905327862424255928440839690896678198609345238715844"; + "5525791196634486842168255391147794242214926238565938472128432032027873773706"; + "44942772752843288052775354603866953297252575988652222073377984219849944553443"; + "47812858871832979537950563348730363522160236019100209662344664049338945674257"; + "47796750287196818117833119527878210275558352491668495251261943487827490944733"; + "18675497827065340973313153216602100036674811368886888073398973368357419355615"; + |] + |> Array.map Bls12_381.Fr.of_string + in + let exp_output = + [| + "548157650485778415829789423515724969373531829417488095812227792093458460987"; + "24533101904433261837828489116977348961986591391494245235307669547135189177847"; + "19437683284737987027036084355301136646342868371278755462121209437095736336008"; + |] + |> Array.map Bls12_381.Fr.of_string + in + let b = 2 in + let output = + Bls12_381_hash.Mode.Jive.digest_b + (module P) + P.Parameters.security_128_state_size_6 + input + b + in + assert (Array.for_all2 Bls12_381.Fr.eq exp_output output) + +let () = + let open Alcotest in + run + "The mode of operation Jive" + [ + ( "Exceptions", + [ + test_case + "input size does not correspond to parameters" + `Quick + test_fail_input_size_and_parameters_do_not_match; + test_case + "b does not divide the state size" + `Quick + test_fail_b_does_not_divide_input_size; + ] ); + ( "Anemoi", + [ + test_case "b = 2, state_size = 2" `Quick test_anemoi_state_size_2; + test_case "b = 2, state_size = 4" `Quick test_anemoi_state_size_4; + test_case "b = 2, state_size = 6" `Quick test_anemoi_state_size_6; + ] ); + ] diff --git a/src/lib_bls12_381_hash/test/test_poseidon.ml b/src/lib_bls12_381_hash/test/test_poseidon.ml new file mode 100644 index 000000000000..c459e9e6ae1e --- /dev/null +++ b/src/lib_bls12_381_hash/test/test_poseidon.ml @@ -0,0 +1,238 @@ +let test_state_getter_setter () = + let open Bls12_381_hash.Permutation.Poseidon.Parameters in + let state = + Array.init security_128_state_size_3.state_size (fun _ -> + Bls12_381.Fr.random ()) + in + let ctxt = + Bls12_381_hash.Permutation.Poseidon.allocate_ctxt security_128_state_size_3 + in + let () = Bls12_381_hash.Permutation.Poseidon.set_state ctxt state in + assert ( + Array.for_all2 + Bls12_381.Fr.eq + state + (Bls12_381_hash.Permutation.Poseidon.get_state ctxt)) + +let test_consistent_with_mec () = + let test_vectors = + [ + ( [| + "0"; + "19540886853600136773806888540031779652697522926951761090609474934921975120659"; + "27368034540955591518185075247638312229509481411752400387472688330662143761856"; + |], + [| + "17943489144262435388134690770306545365190731633977654215868012824127324198151"; + "2231754119684576552235072561055622129225837122807214026821170668631716242147"; + "29261523742327067247029179638981197564247814302680832614540814949720900275190"; + |] ); + ( [| + "0"; + "27079498335589470388559429012071885383086029562052523482197446658383111072774"; + "42808036164195249275280963312025828986508786508614910971333518929197538998773"; + |], + [| + "24183560910605453752776639786227559025963231226657372504816371318001117542043"; + "35029299207990307567943227124638286593042324757574009533577874051172424731112"; + "5149101922766693039542544793826724317233738847055587332789635646881987279038"; + |] ); + ( [| + "0"; + "2280773603130921897588628948561054337050485605305725986334019017364524534576"; + "49742584797721038216392695876666332237687899609664289853866233942594829409245"; + |], + [| + "35816535646044617407808534693371034506444808081714503610242949185965092595026"; + "5363956515446161539161780954417765912037041392866393510569016892172498529944"; + "32254025883747625406036521648265940411925032697688307242655649591762898002497"; + |] ); + ( [| + "0"; + "47345255170739768354940339244069904962490289137071838723660628082786560244227"; + "12508134994244913485311518548620293355291296251148491744230743543606532994206"; + |], + [| + "9091234811689308509102172807464454311569090414440587970689563456088495182507"; + "14174922240502925080674757917320110469967806338655989126339180218846318661667"; + "36498938306563858591852167046454653325721089316694704626906932069658540502064"; + |] ); + ( [| + "0"; + "22266149478348354835731057366322705807112053199389518651299197937563769914341"; + "46391019025260596444368872653036215340017923491388854958773789052412558961328"; + |], + [| + "38438670864363407523537730683343143710087993977705604857656216937687834130603"; + "16221205305575053191586076875532883527874413609923551381849833895354625853752"; + "21204380361849499989864581430501306982675221862819264096834120630459940923576"; + |] ); + ] + in + List.iter + (fun (state, expected_output) -> + let open Bls12_381_hash.Permutation.Poseidon.Parameters in + let state = Array.map Bls12_381.Fr.of_string state in + let ctxt = + Bls12_381_hash.Permutation.Poseidon.allocate_ctxt + security_128_state_size_3 + in + let () = Bls12_381_hash.Permutation.Poseidon.set_state ctxt state in + let () = Bls12_381_hash.Permutation.Poseidon.apply_permutation ctxt in + let output = Bls12_381_hash.Permutation.Poseidon.get_state ctxt in + let expected_output = Array.map Bls12_381.Fr.of_string expected_output in + Array.iter2 + (fun a b -> + if not (Bls12_381.Fr.eq a b) then + Alcotest.failf + "Expected output is %s, computed %s\n" + (Bls12_381.Fr.to_string a) + (Bls12_381.Fr.to_string b)) + expected_output + output) + test_vectors + +let test_poseidon128_with_different_batch_size () = + let open Bls12_381_hash.Permutation.Poseidon.Parameters in + let state = + Array.init security_128_state_size_3.state_size (fun _ -> + Bls12_381.Fr.random ()) + in + let compute_output () = + let batch_size' = + 2 + Random.int security_128_state_size_3.nb_of_partial_rounds + in + let parameters = + {security_128_state_size_3 with batch_size = batch_size'} + in + let ctxt = Bls12_381_hash.Permutation.Poseidon.allocate_ctxt parameters in + let () = Bls12_381_hash.Permutation.Poseidon.set_state ctxt state in + let () = Bls12_381_hash.Permutation.Poseidon.apply_permutation ctxt in + let output = Bls12_381_hash.Permutation.Poseidon.get_state ctxt in + output + in + let output = compute_output () in + let output' = compute_output () in + Array.iter2 + (fun a b -> + if not (Bls12_381.Fr.eq a b) then + Alcotest.failf + "Output is %s, output' is %s\n" + (Bls12_381.Fr.to_string a) + (Bls12_381.Fr.to_string b)) + output + output' + +let test_random_instanciations_of_poseidon_with_different_batch_size () = + let open Bls12_381_hash.Permutation.Poseidon.Parameters in + let state_size = 1 + Random.int 10 in + let nb_of_full_rounds = (1 + Random.int 10) * 2 in + let nb_of_partial_rounds = 2 + Random.int 100 in + let ark_length = state_size * (nb_of_full_rounds + nb_of_partial_rounds) in + let ark = Array.init ark_length (fun _ -> Bls12_381.Fr.random ()) in + let mds = + Array.init state_size (fun _ -> + Array.init state_size (fun _ -> Bls12_381.Fr.random ())) + in + let state = Array.init state_size (fun _ -> Bls12_381.Fr.random ()) in + let compute_output () = + let batch_size = 1 + Random.int nb_of_partial_rounds in + let parameters = + { + state_size; + round_constants = ark; + linear_layer = mds; + nb_of_full_rounds; + nb_of_partial_rounds; + batch_size; + } + in + + let ctxt = Bls12_381_hash.Permutation.Poseidon.allocate_ctxt parameters in + let () = Bls12_381_hash.Permutation.Poseidon.set_state ctxt state in + let () = Bls12_381_hash.Permutation.Poseidon.apply_permutation ctxt in + let output = Bls12_381_hash.Permutation.Poseidon.get_state ctxt in + output + in + let output = compute_output () in + let output' = compute_output () in + Array.iter2 + (fun a b -> + if not (Bls12_381.Fr.eq a b) then + Alcotest.failf + "Output is %s, output' is %s\n" + (Bls12_381.Fr.to_string a) + (Bls12_381.Fr.to_string b)) + output + output' + +let test_regression_tests_for_poseidon252 () = + let open Bls12_381_hash.Permutation.Poseidon.Parameters in + let vectors = + [ + ( Array.make + security_256_state_size_5.state_size + (Bls12_381.Fr.of_string "19"), + [| + "2f26f38f20a624eb7ddc58a28f94a868824a320a64a05c7b028be716c3d47938"; + "577a6555ceb8acfcec1024f76a647a63bef97ef490fa875d5d8d640e9c477973"; + "d3c9f03664b22c12a49a428cd13bf60c397105ae18039208598f00270b71472f"; + "968c4eeb53cb2888a565bf27bc7eb23c648c05f595b1a39fbe11a7aaaba57c4a"; + "e6ddc232b1895b132931211f1052df5a9945ef7c62011a45c5509490cf8cb001"; + |] ); + ] + in + List.iter + (fun (state, expected_output) -> + let expected_output = + Array.map + (fun x -> Bls12_381.Fr.of_bytes_exn (Hex.to_bytes (`Hex x))) + expected_output + in + let ctxt = + Bls12_381_hash.Permutation.Poseidon.allocate_ctxt + security_256_state_size_5 + in + let () = Bls12_381_hash.Permutation.Poseidon.set_state ctxt state in + let () = Bls12_381_hash.Permutation.Poseidon.apply_permutation ctxt in + let output = Bls12_381_hash.Permutation.Poseidon.get_state ctxt in + Array.iter2 + (fun a b -> + if not (Bls12_381.Fr.eq a b) then + Alcotest.failf + "Expected output is %s, computed is %s\n" + (Bls12_381.Fr.to_string a) + (Bls12_381.Fr.to_string b)) + expected_output + output) + vectors + +let () = + let open Alcotest in + run + "Poseidon" + [ + ("State", [test_case "get and set" `Quick test_state_getter_setter]); + ( "Batch size consistency", + [ + test_case + "Poseidon128 with random batch sizes" + `Quick + test_poseidon128_with_different_batch_size; + test_case + "Random instance of Poseidon" + `Quick + test_random_instanciations_of_poseidon_with_different_batch_size; + ] ); + ( "Test vectors", + [ + test_case + "Poseidon252 (Dusk)" + `Quick + test_regression_tests_for_poseidon252; + test_case + "Poseidon128 (consistency with MEC)" + `Quick + test_consistent_with_mec; + ] ); + ] diff --git a/src/lib_bls12_381_hash/test/test_rescue.ml b/src/lib_bls12_381_hash/test/test_rescue.ml new file mode 100644 index 000000000000..89e362c9f2b4 --- /dev/null +++ b/src/lib_bls12_381_hash/test/test_rescue.ml @@ -0,0 +1,103 @@ +let test_state_getter_setter () = + let open Bls12_381_hash.Permutation.Rescue.Parameters in + let ctxt = + Bls12_381_hash.Permutation.Rescue.(allocate_ctxt security_128_state_size_3) + in + let state = + Array.init security_128_state_size_3.state_size (fun _ -> + Bls12_381.Fr.random ()) + in + let () = Bls12_381_hash.Permutation.Rescue.set_state ctxt state in + assert ( + Array.for_all2 + Bls12_381.Fr.eq + state + (Bls12_381_hash.Permutation.Rescue.get_state ctxt)) + +let test_consistent_with_mec () = + let test_vectors = + [ + ( [| + "0"; + "19540886853600136773806888540031779652697522926951761090609474934921975120659"; + "27368034540955591518185075247638312229509481411752400387472688330662143761856"; + |], + [| + "44673107086290821414141179286216522882469521449559636868455247005114020114445"; + "36631684854749147804429266824538272650916679166988362643455728142484809981118"; + "6299192490564547343493433393738313689693119470079691921424273466838440224855"; + |] ); + ( [| + "0"; + "27079498335589470388559429012071885383086029562052523482197446658383111072774"; + "42808036164195249275280963312025828986508786508614910971333518929197538998773"; + |], + [| + "33984868849407543137734814872861866351541889998060667955612713996984910605397"; + "4641627185242898456867942643033909448689919023961721348259024082238188176596"; + "713519522119335567984877165818659706904142877478060072511766145209379073275"; + |] ); + ( [| + "0"; + "2280773603130921897588628948561054337050485605305725986334019017364524534576"; + "49742584797721038216392695876666332237687899609664289853866233942594829409245"; + |], + [| + "20077542126429611153881019033799341995311428088869746915924850362129927371289"; + "38547305939988350836972846971113863192807010866171540518921476662284151835220"; + "8478277515116959072250029506006378039116363843044265570742187828912632979438"; + |] ); + ( [| + "0"; + "47345255170739768354940339244069904962490289137071838723660628082786560244227"; + "12508134994244913485311518548620293355291296251148491744230743543606532994206"; + |], + [| + "50927739926931280620422144191479516292814380533564245832950972175783227490582"; + "47903072246991027484665412890156631636069614146568039741296638969334550407630"; + "47491331892735386854365197646017331478438648030708643559209673528669254013444"; + |] ); + ( [| + "0"; + "22266149478348354835731057366322705807112053199389518651299197937563769914341"; + "46391019025260596444368872653036215340017923491388854958773789052412558961328"; + |], + [| + "37498820915193954318343590451968185938009803654297685764064124822117204060828"; + "16239130390180195445652573959561373168694718306164480810197800625237334891866"; + "21507804981211574030250333588537037287147041282903807447161895309722506987102"; + |] ); + ] + in + List.iter + (fun (inputs, expected_output) -> + let open Bls12_381_hash.Permutation.Rescue.Parameters in + let inputs = Array.map Bls12_381.Fr.of_string inputs in + let expected_output = Array.map Bls12_381.Fr.of_string expected_output in + let ctxt = + Bls12_381_hash.Permutation.Rescue.allocate_ctxt + security_128_state_size_3 + in + let () = Bls12_381_hash.Permutation.Rescue.set_state ctxt inputs in + let () = Bls12_381_hash.Permutation.Rescue.apply_permutation ctxt in + let output = Bls12_381_hash.Permutation.Rescue.get_state ctxt in + Array.iter2 + (fun a b -> + if not (Bls12_381.Fr.eq a b) then + Alcotest.failf + "Expected output is %s, computed %s\n" + (Bls12_381.Fr.to_string a) + (Bls12_381.Fr.to_string b)) + expected_output + output) + test_vectors + +let () = + let open Alcotest in + run + "Rescue" + [ + ( "Consistency with MEC", + [test_case "vectors" `Quick test_consistent_with_mec] ); + ("State", [test_case "get and set" `Quick test_state_getter_setter]); + ] -- GitLab From 455a3b5ec0baa3a5dde176483a56bba70c422bb9 Mon Sep 17 00:00:00 2001 From: Victor Dumitrescu Date: Thu, 9 Mar 2023 10:42:40 +0100 Subject: [PATCH 05/34] Lib_mec: import from cryptography/ocaml-ec --- .gitlab/ci/jobs/packaging/opam_package.yml | 7 + dune-project | 1 + manifest/main.ml | 71 + opam/octez-mec.opam | 23 + opam/virtual/octez-deps.opam | 2 + src/lib_mec/ark_neptunus.ml | 190 + src/lib_mec/ark_orchard.ml | 201 + src/lib_mec/ark_poseidon128.ml | 198 + src/lib_mec/ark_poseidon252.ml | 965 ++ src/lib_mec/babyjubjub.ml | 49 + src/lib_mec/babyjubjub.mli | 1 + src/lib_mec/babyjubjub_reduced.ml | 47 + src/lib_mec/babyjubjub_reduced.mli | 1 + src/lib_mec/baijiu_blake2b.ml | 441 + src/lib_mec/baijiu_blake2s.ml | 405 + src/lib_mec/bandersnatch.ml | 148 + src/lib_mec/bandersnatch.mli | 17 + src/lib_mec/bls12_381_ref.ml | 225 + src/lib_mec/bls12_381_ref.mli | 5 + src/lib_mec/bn254.ml | 122 + src/lib_mec/bn254.mli | 13 + src/lib_mec/curve25519.ml | 102 + src/lib_mec/curve25519.mli | 9 + src/lib_mec/curve448.ml | 49 + src/lib_mec/curve448.mli | 1 + src/lib_mec/digestif_bi.ml | 87 + src/lib_mec/digestif_by.ml | 68 + src/lib_mec/digestif_conv.ml | 104 + src/lib_mec/digestif_eq.ml | 10 + src/lib_mec/dune | 12 + src/lib_mec/ec.ml | 1458 +++ src/lib_mec/ec_pbt.ml | 554 ++ src/lib_mec/ec_sig.ml | 340 + src/lib_mec/ff.ml | 347 + src/lib_mec/group_hash.ml | 58 + src/lib_mec/group_hash.mli | 25 + src/lib_mec/hades.ml | 115 + src/lib_mec/hades.mli | 50 + src/lib_mec/hades_linear_optimisation.ml | 512 + src/lib_mec/hades_linear_optimisation.mli | 43 + src/lib_mec/iterator.ml | 54 + src/lib_mec/iterator.mli | 15 + src/lib_mec/jubjub.ml | 207 + src/lib_mec/jubjub.mli | 25 + src/lib_mec/linear_algebra.ml | 181 + src/lib_mec/marvellous.ml | 97 + src/lib_mec/marvellous.mli | 34 + src/lib_mec/mds_orchard.ml | 18 + src/lib_mec/mds_poseidon128.ml | 21 + src/lib_mec/mds_poseidon252.ml | 40 + src/lib_mec/mec.ml | 59 + src/lib_mec/mec_curve_utils.ml | 5 + src/lib_mec/mec_digestif.ml | 410 + src/lib_mec/mec_digestif.mli | 215 + src/lib_mec/neptunus.ml | 17 + src/lib_mec/neptunus.mli | 7 + src/lib_mec/orchard.ml | 16 + src/lib_mec/orchard.mli | 7 + src/lib_mec/pallas.ml | 268 + src/lib_mec/pallas.mli | 21 + src/lib_mec/pedersen_hash.ml | 81 + src/lib_mec/pedersen_hash.mli | 14 + src/lib_mec/poseidon128.ml | 16 + src/lib_mec/poseidon128.mli | 7 + src/lib_mec/poseidon252.ml | 16 + src/lib_mec/poseidon252.mli | 7 + src/lib_mec/poseidon_core.ml | 183 + src/lib_mec/poseidon_core.mli | 60 + src/lib_mec/reddsa.ml | 130 + src/lib_mec/reddsa.mli | 53 + src/lib_mec/redjubjub.ml | 52 + src/lib_mec/redjubjub.mli | 30 + src/lib_mec/secp256k1.ml | 135 + src/lib_mec/secp256k1.mli | 13 + src/lib_mec/secp256r1.ml | 143 + src/lib_mec/secp256r1.mli | 13 + src/lib_mec/sinsemilla.ml | 63 + src/lib_mec/sinsemilla.mli | 30 + src/lib_mec/sinsemilla_zcash_generators.ml | 6155 ++++++++++++ src/lib_mec/test/ark_pobls.ml | 90 + src/lib_mec/test/ark_poseidon128.ml | 198 + src/lib_mec/test/dune | 305 + src/lib_mec/test/mds_pobls.ml | 18 + src/lib_mec/test/mds_poseidon128.ml | 21 + ...oseidon128_linear_trick_expected_output.ml | 507 + src/lib_mec/test/test_babyjubjub.ml | 142 + src/lib_mec/test/test_babyjubjub_reduced.ml | 67 + .../test/test_bandersnatch_affine_edwards.ml | 21 + .../test_bandersnatch_affine_montgomery.ml | 18 + .../test_bandersnatch_affine_weierstrass.ml | 22 + src/lib_mec/test/test_bls12_381_affine.ml | 18 + src/lib_mec/test/test_bls12_381_projective.ml | 16 + src/lib_mec/test/test_bn254_affine.ml | 20 + src/lib_mec/test/test_bn254_jacobian.ml | 17 + src/lib_mec/test/test_bn254_projective.ml | 17 + .../test/test_curve25519_affine_edwards.ml | 21 + ...st_curve25519_conversions_between_forms.ml | 98 + .../test/test_curve25519_montgomery.ml | 17 + src/lib_mec/test/test_curve448.ml | 19 + src/lib_mec/test/test_digestif.ml | 119 + src/lib_mec/test/test_ec_functor.ml | 33 + src/lib_mec/test/test_find_group_hash.ml | 83 + src/lib_mec/test/test_hades_optimised.ml | 91 + src/lib_mec/test/test_iso_pallas_affine.ml | 21 + src/lib_mec/test/test_iterator.ml | 162 + src/lib_mec/test/test_jubjub.ml | 776 ++ .../test_jubjub_conversions_between_forms.ml | 116 + src/lib_mec/test/test_jubjub_weierstrass.ml | 21 + src/lib_mec/test/test_linear_trick.ml | 45 + src/lib_mec/test/test_marvellous.ml | 141 + src/lib_mec/test/test_neptunus.ml | 38 + src/lib_mec/test/test_orchard.ml | 129 + src/lib_mec/test/test_pallas_affine.ml | 20 + src/lib_mec/test/test_pallas_jacobian.ml | 17 + src/lib_mec/test/test_pallas_projective.ml | 17 + src/lib_mec/test/test_pedersen_hash.ml | 69 + src/lib_mec/test/test_poseidon128.ml | 99 + src/lib_mec/test/test_poseidon252.ml | 156 + src/lib_mec/test/test_redjubjub.ml | 185 + src/lib_mec/test/test_secp256k1_affine.ml | 70 + src/lib_mec/test/test_secp256k1_jacobian.ml | 17 + src/lib_mec/test/test_secp256k1_projective.ml | 67 + src/lib_mec/test/test_secp256r1_affine.ml | 23 + src/lib_mec/test/test_secp256r1_jacobian.ml | 17 + src/lib_mec/test/test_secp256r1_projective.ml | 17 + src/lib_mec/test/test_sinsemilla.ml | 238 + src/lib_mec/test/test_tweedledee_affine.ml | 21 + src/lib_mec/test/test_tweedledee_jacobian.ml | 17 + .../test/test_tweedledee_projective.ml | 17 + src/lib_mec/test/test_tweedledum_affine.ml | 21 + src/lib_mec/test/test_tweedledum_jacobian.ml | 17 + .../test/test_tweedledum_projective.ml | 17 + src/lib_mec/test/test_vector_pedersen_hash.ml | 8256 +++++++++++++++++ src/lib_mec/test/test_vesta_affine.ml | 19 + src/lib_mec/test/test_vesta_jacobian.ml | 17 + src/lib_mec/test/test_vesta_projective.ml | 17 + src/lib_mec/tweedledee.ml | 112 + src/lib_mec/tweedledee.mli | 13 + src/lib_mec/tweedledum.ml | 112 + src/lib_mec/tweedledum.mli | 13 + src/lib_mec/vesta.ml | 113 + src/lib_mec/vesta.mli | 13 + src/lib_mec/xor.ml | 65 + 143 files changed, 29293 insertions(+) create mode 100644 opam/octez-mec.opam create mode 100644 src/lib_mec/ark_neptunus.ml create mode 100644 src/lib_mec/ark_orchard.ml create mode 100644 src/lib_mec/ark_poseidon128.ml create mode 100644 src/lib_mec/ark_poseidon252.ml create mode 100644 src/lib_mec/babyjubjub.ml create mode 100644 src/lib_mec/babyjubjub.mli create mode 100644 src/lib_mec/babyjubjub_reduced.ml create mode 100644 src/lib_mec/babyjubjub_reduced.mli create mode 100644 src/lib_mec/baijiu_blake2b.ml create mode 100644 src/lib_mec/baijiu_blake2s.ml create mode 100644 src/lib_mec/bandersnatch.ml create mode 100644 src/lib_mec/bandersnatch.mli create mode 100644 src/lib_mec/bls12_381_ref.ml create mode 100644 src/lib_mec/bls12_381_ref.mli create mode 100644 src/lib_mec/bn254.ml create mode 100644 src/lib_mec/bn254.mli create mode 100644 src/lib_mec/curve25519.ml create mode 100644 src/lib_mec/curve25519.mli create mode 100644 src/lib_mec/curve448.ml create mode 100644 src/lib_mec/curve448.mli create mode 100644 src/lib_mec/digestif_bi.ml create mode 100644 src/lib_mec/digestif_by.ml create mode 100644 src/lib_mec/digestif_conv.ml create mode 100644 src/lib_mec/digestif_eq.ml create mode 100644 src/lib_mec/dune create mode 100644 src/lib_mec/ec.ml create mode 100644 src/lib_mec/ec_pbt.ml create mode 100644 src/lib_mec/ec_sig.ml create mode 100644 src/lib_mec/ff.ml create mode 100644 src/lib_mec/group_hash.ml create mode 100644 src/lib_mec/group_hash.mli create mode 100644 src/lib_mec/hades.ml create mode 100644 src/lib_mec/hades.mli create mode 100644 src/lib_mec/hades_linear_optimisation.ml create mode 100644 src/lib_mec/hades_linear_optimisation.mli create mode 100644 src/lib_mec/iterator.ml create mode 100644 src/lib_mec/iterator.mli create mode 100644 src/lib_mec/jubjub.ml create mode 100644 src/lib_mec/jubjub.mli create mode 100644 src/lib_mec/linear_algebra.ml create mode 100644 src/lib_mec/marvellous.ml create mode 100644 src/lib_mec/marvellous.mli create mode 100644 src/lib_mec/mds_orchard.ml create mode 100644 src/lib_mec/mds_poseidon128.ml create mode 100644 src/lib_mec/mds_poseidon252.ml create mode 100644 src/lib_mec/mec.ml create mode 100644 src/lib_mec/mec_curve_utils.ml create mode 100644 src/lib_mec/mec_digestif.ml create mode 100644 src/lib_mec/mec_digestif.mli create mode 100644 src/lib_mec/neptunus.ml create mode 100644 src/lib_mec/neptunus.mli create mode 100644 src/lib_mec/orchard.ml create mode 100644 src/lib_mec/orchard.mli create mode 100644 src/lib_mec/pallas.ml create mode 100644 src/lib_mec/pallas.mli create mode 100644 src/lib_mec/pedersen_hash.ml create mode 100644 src/lib_mec/pedersen_hash.mli create mode 100644 src/lib_mec/poseidon128.ml create mode 100644 src/lib_mec/poseidon128.mli create mode 100644 src/lib_mec/poseidon252.ml create mode 100644 src/lib_mec/poseidon252.mli create mode 100644 src/lib_mec/poseidon_core.ml create mode 100644 src/lib_mec/poseidon_core.mli create mode 100644 src/lib_mec/reddsa.ml create mode 100644 src/lib_mec/reddsa.mli create mode 100644 src/lib_mec/redjubjub.ml create mode 100644 src/lib_mec/redjubjub.mli create mode 100644 src/lib_mec/secp256k1.ml create mode 100644 src/lib_mec/secp256k1.mli create mode 100644 src/lib_mec/secp256r1.ml create mode 100644 src/lib_mec/secp256r1.mli create mode 100644 src/lib_mec/sinsemilla.ml create mode 100644 src/lib_mec/sinsemilla.mli create mode 100644 src/lib_mec/sinsemilla_zcash_generators.ml create mode 100644 src/lib_mec/test/ark_pobls.ml create mode 100644 src/lib_mec/test/ark_poseidon128.ml create mode 100644 src/lib_mec/test/dune create mode 100644 src/lib_mec/test/mds_pobls.ml create mode 100644 src/lib_mec/test/mds_poseidon128.ml create mode 100644 src/lib_mec/test/poseidon128_linear_trick_expected_output.ml create mode 100644 src/lib_mec/test/test_babyjubjub.ml create mode 100644 src/lib_mec/test/test_babyjubjub_reduced.ml create mode 100644 src/lib_mec/test/test_bandersnatch_affine_edwards.ml create mode 100644 src/lib_mec/test/test_bandersnatch_affine_montgomery.ml create mode 100644 src/lib_mec/test/test_bandersnatch_affine_weierstrass.ml create mode 100644 src/lib_mec/test/test_bls12_381_affine.ml create mode 100644 src/lib_mec/test/test_bls12_381_projective.ml create mode 100644 src/lib_mec/test/test_bn254_affine.ml create mode 100644 src/lib_mec/test/test_bn254_jacobian.ml create mode 100644 src/lib_mec/test/test_bn254_projective.ml create mode 100644 src/lib_mec/test/test_curve25519_affine_edwards.ml create mode 100644 src/lib_mec/test/test_curve25519_conversions_between_forms.ml create mode 100644 src/lib_mec/test/test_curve25519_montgomery.ml create mode 100644 src/lib_mec/test/test_curve448.ml create mode 100644 src/lib_mec/test/test_digestif.ml create mode 100644 src/lib_mec/test/test_ec_functor.ml create mode 100644 src/lib_mec/test/test_find_group_hash.ml create mode 100644 src/lib_mec/test/test_hades_optimised.ml create mode 100644 src/lib_mec/test/test_iso_pallas_affine.ml create mode 100644 src/lib_mec/test/test_iterator.ml create mode 100644 src/lib_mec/test/test_jubjub.ml create mode 100644 src/lib_mec/test/test_jubjub_conversions_between_forms.ml create mode 100644 src/lib_mec/test/test_jubjub_weierstrass.ml create mode 100644 src/lib_mec/test/test_linear_trick.ml create mode 100644 src/lib_mec/test/test_marvellous.ml create mode 100644 src/lib_mec/test/test_neptunus.ml create mode 100644 src/lib_mec/test/test_orchard.ml create mode 100644 src/lib_mec/test/test_pallas_affine.ml create mode 100644 src/lib_mec/test/test_pallas_jacobian.ml create mode 100644 src/lib_mec/test/test_pallas_projective.ml create mode 100644 src/lib_mec/test/test_pedersen_hash.ml create mode 100644 src/lib_mec/test/test_poseidon128.ml create mode 100644 src/lib_mec/test/test_poseidon252.ml create mode 100644 src/lib_mec/test/test_redjubjub.ml create mode 100644 src/lib_mec/test/test_secp256k1_affine.ml create mode 100644 src/lib_mec/test/test_secp256k1_jacobian.ml create mode 100644 src/lib_mec/test/test_secp256k1_projective.ml create mode 100644 src/lib_mec/test/test_secp256r1_affine.ml create mode 100644 src/lib_mec/test/test_secp256r1_jacobian.ml create mode 100644 src/lib_mec/test/test_secp256r1_projective.ml create mode 100644 src/lib_mec/test/test_sinsemilla.ml create mode 100644 src/lib_mec/test/test_tweedledee_affine.ml create mode 100644 src/lib_mec/test/test_tweedledee_jacobian.ml create mode 100644 src/lib_mec/test/test_tweedledee_projective.ml create mode 100644 src/lib_mec/test/test_tweedledum_affine.ml create mode 100644 src/lib_mec/test/test_tweedledum_jacobian.ml create mode 100644 src/lib_mec/test/test_tweedledum_projective.ml create mode 100644 src/lib_mec/test/test_vector_pedersen_hash.ml create mode 100644 src/lib_mec/test/test_vesta_affine.ml create mode 100644 src/lib_mec/test/test_vesta_jacobian.ml create mode 100644 src/lib_mec/test/test_vesta_projective.ml create mode 100644 src/lib_mec/tweedledee.ml create mode 100644 src/lib_mec/tweedledee.mli create mode 100644 src/lib_mec/tweedledum.ml create mode 100644 src/lib_mec/tweedledum.mli create mode 100644 src/lib_mec/vesta.ml create mode 100644 src/lib_mec/vesta.mli create mode 100644 src/lib_mec/xor.ml diff --git a/.gitlab/ci/jobs/packaging/opam_package.yml b/.gitlab/ci/jobs/packaging/opam_package.yml index 9c1558572a27..2399c9823951 100644 --- a/.gitlab/ci/jobs/packaging/opam_package.yml +++ b/.gitlab/ci/jobs/packaging/opam_package.yml @@ -279,6 +279,13 @@ opam:octez-injector: variables: package: octez-injector +opam:octez-mec: + extends: + - .opam_template + - .rules_template__trigger_opam_batch_7 + variables: + package: octez-mec + opam:octez-node: extends: - .opam_template diff --git a/dune-project b/dune-project index f61ee362d396..90ff1f17844c 100644 --- a/dune-project +++ b/dune-project @@ -18,6 +18,7 @@ (package (name octez-dal-node)) (package (name octez-evm-proxy)) (package (name octez-injector)) +(package (name octez-mec)) (package (name octez-node)) (package (name octez-node-config)) (package (name octez-protocol-compiler)) diff --git a/manifest/main.ml b/manifest/main.ml index 4a2778be215e..9753568b0919 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -74,6 +74,8 @@ let alcotest_lwt = external_lib "alcotest-lwt" V.(at_least "1.5.0") let astring = external_lib ~js_compatible:true "astring" V.True +let bigarray_compat = external_lib ~js_compatible:true "bigarray-compat" V.True + let bigstring = external_lib ~js_compatible:true "bigstring" V.True let bigstringaf = @@ -140,6 +142,8 @@ let dune_configurator = external_lib "dune-configurator" V.True let dynlink = external_lib "dynlink" V.True ~opam:"" +let eqaf = external_lib "eqaf" V.True + let ezjsonm = external_lib ~js_compatible:true "ezjsonm" V.(at_least "1.1.0") let fmt = external_lib ~js_compatible:true "fmt" V.(at_least "0.8.7") @@ -951,6 +955,73 @@ let _octez_bls12_381_hash_tests = ~deps:[alcotest; bls12_381; octez_bls12_381_hash] ~flags:(Flags.standard ~disable_warnings:[3] ()) +let octez_mec = + public_lib + "octez-mec" + ~path:"src/lib_mec" + ~internal_name:"mec" + ~synopsis:"Modular Experimental Cryptography library" + ~deps:[alcotest; bls12_381; bigarray_compat; eqaf] + +let _octez_mec_tests = + tests + [ + "test_neptunus"; + "test_orchard"; + "test_pedersen_hash"; + "test_poseidon128"; + "test_poseidon252"; + "test_sinsemilla"; + "test_babyjubjub"; + "test_babyjubjub_reduced"; + "test_bandersnatch_affine_montgomery"; + "test_bandersnatch_affine_weierstrass"; + "test_bandersnatch_affine_edwards"; + (* FIXME: test_bandersnatch_all has been removed from the repository, see + https://gitlab.com/tezos/tezos/-/issues/5147 *) + "test_bls12_381_affine"; + "test_bls12_381_projective"; + "test_bn254_affine"; + "test_bn254_jacobian"; + "test_bn254_projective"; + "test_curve25519_affine_edwards"; + "test_curve25519_conversions_between_forms"; + "test_curve25519_montgomery"; + "test_curve448"; + "test_ec_functor"; + "test_iso_pallas_affine"; + "test_jubjub"; + "test_jubjub_conversions_between_forms"; + "test_jubjub_weierstrass"; + "test_pallas_affine"; + "test_pallas_jacobian"; + "test_pallas_projective"; + "test_secp256k1_affine"; + "test_secp256k1_jacobian"; + "test_secp256k1_projective"; + "test_secp256r1_affine"; + "test_secp256r1_jacobian"; + "test_secp256r1_projective"; + "test_tweedledee_affine"; + "test_tweedledee_jacobian"; + "test_tweedledee_projective"; + "test_tweedledum_affine"; + "test_tweedledum_jacobian"; + "test_tweedledum_projective"; + "test_vesta_affine"; + "test_vesta_jacobian"; + "test_vesta_projective"; + "test_digestif"; + "test_linear_trick"; + "test_marvellous"; + "test_redjubjub"; + "test_find_group_hash"; + "test_iterator"; + ] + ~path:"src/lib_mec/test" + ~opam:"octez-mec" + ~deps:[alcotest; octez_mec |> open_] + let octez_bls12_381_polynomial_internal = public_lib "tezos-bls12-381-polynomial-internal" diff --git a/opam/octez-mec.opam b/opam/octez-mec.opam new file mode 100644 index 000000000000..b734dfc00c3e --- /dev/null +++ b/opam/octez-mec.opam @@ -0,0 +1,23 @@ +# This file was automatically generated, do not edit. +# Edit file manifest/main.ml instead. +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: ["Tezos devteam"] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "3.0" } + "ocaml" { >= "4.14" } + "alcotest" { >= "1.5.0" } + "bls12-381" { >= "6.0.1" & < "6.1.0" } + "bigarray-compat" + "eqaf" +] +build: [ + ["rm" "-r" "vendors"] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Modular Experimental Cryptography library" diff --git a/opam/virtual/octez-deps.opam b/opam/virtual/octez-deps.opam index f53edbd94da4..465a20e6ac62 100644 --- a/opam/virtual/octez-deps.opam +++ b/opam/virtual/octez-deps.opam @@ -14,6 +14,7 @@ depends: [ "alcotest-lwt" { >= "1.5.0" } "astring" "base-unix" + "bigarray-compat" "bigstring" "bigstringaf" { >= "0.5.0" } "bisect_ppx" { >= "2.7.0" } @@ -33,6 +34,7 @@ depends: [ "ctypes_stubs_js" "data-encoding" { >= "0.7.1" & < "1.0.0" } "dune-configurator" + "eqaf" "ezjsonm" { >= "1.1.0" } "fmt" { >= "0.8.7" } "hacl-star" { >= "0.6.1" & < "0.7" } diff --git a/src/lib_mec/ark_neptunus.ml b/src/lib_mec/ark_neptunus.ml new file mode 100644 index 000000000000..4a5fb974ea99 --- /dev/null +++ b/src/lib_mec/ark_neptunus.ml @@ -0,0 +1,190 @@ +(* Come from + ``` + dune exec ./generate_ark.exe 60 0 3 "52435875175126190479447740508185965837690552500527637822603658699938581184513" "tezos_poseidon" + ``` + Commit 6a1e59a2cea4392b04b14f6e7ddd03e5d818e623 +*) + +let v = + [| + "12824693747017958656359741899350387676664089448183168620817941350923622240383"; + "2110512952725741187549618038800597171689376420770588630765413738693257923365"; + "47326464895396585099705735602023752272300355108131773128388570963521922081510"; + "563012381688126180539569880290185949096875479968107613527817326352434592856"; + "20435639598009869993321661794628409935886243780150497184529212840833664449656"; + "196568005014908906943408140878629143505019528204274239329256802017215936683"; + "25962654684949630743270090458873017355613280868787190166613423196385364109406"; + "2902949562437765068560667705637724057704859748759440393767306205627156631635"; + "48765024020816932517496715131525675528890199049120440892483976763745835117858"; + "2521254722031505239112642581694420959196804419239024356676547276184406685162"; + "51021598403923227244919665563608069313986657641358042233506839666746223886174"; + "1054116206618757673158081612917129416032354356767130085800942497760890427733"; + "35527058233191932797057544076619925913363578197567288806107068259245425979761"; + "2634280023212643609442836838440917786416264439095063634117944443782024029279"; + "39421919986269102473005636801607717780949112929566701303040428546494236832142"; + "1108697190209272403800986208961553739614858445125481568510484181910492195628"; + "12045800443981429031896147388217433545754425883946502772543316945784413417019"; + "82604952988294859566853552858162148408810580477764040175328077158180638032"; + "50270776669157712293893033630792805271843351375068235098934380606286868420081"; + "4556699357166547420252702363071964093628547740375189594266494741118120185875"; + "28756618406604627864560204181157146784905823733084273636904787891595217041493"; + "3929061368963303543382708474487773927696676445825720846075125669855529226465"; + "18077432337068904300805913007986258320260964944627469934418526215049004418850"; + "555694305263590606473308840289036435744336132072477475386605456741511841112"; + "19540875247789686897819386841067347406140142379787247556508575750097457102800"; + "1448707275568454674766116478738872398268409443096166848018297610768625046726"; + "1365035359887233236958701559549281683572920146548303300137734899617496459320"; + "296272530549376935987465863345169666107896810662168723956830664953961522362"; + "1222008471833248844130489923076230958939009980056422343699249951036863250406"; + "4645825111751650824509927275187472476744269268030571538472557623136712967534"; + "17367408524064290797098982556349219497014777382389461167580403687601422907744"; + "4067034309108034062368247356825838876451720740358475567436606187615273492134"; + "37464072930817278139129480285443023448384449803554018863125599103193054747940"; + "1154923382618727721537690770667336978399240055012120552776957609043905780309"; + "14761222603381544767861781252566790400337820585000529592970728629846169054074"; + "3913916891269533795763393633333348732307055924078927653872560295421023616912"; + "30551679780389794856358102488913579915189391919966614704474658955963931924601"; + "2623945794554933981603577446997424920433800054981268118099374525963300203599"; + "37553485386488789278771814769828299823440779111850352710838985845411101822259"; + "380971882976374898531171928157843618667556427594941784718505414050004483900"; + "10017112572864832043140346277015863860093483928149059067819681230371941944219"; + "3260482321812695850957645581839558488578671815239403289847780027429591624886"; + "24779434793361163444013176816239053406573251563355730673257372706459004109752"; + "3834722693939583529892160907115156917875416106150610312937809427157623722716"; + "34750922361865676680499065756842369674722176279862565574651223917853132870768"; + "3303719823632917286146798280923324860357977348797342300199305695109156084208"; + "26018601582375751114157841612900668552714749858338434790831374188259468891657"; + "3760594088040850818134137825940561088098655326719629222313979094464767486270"; + "13502450637194424997028192825724613739600481337904104764037861753271786962154"; + "3605680875487475312847246627162938193404148815924719449117458482311523099581"; + "1768114684013685999050765210150692485022620153369626171927007242630684789096"; + "4300220668885208831825911397052406422843855438064865963936061488194010074168"; + "18745557299904421052970946495269579008489037727912355291647391635546797208632"; + "4645457313953861508779197981831082874745930614083957226744023638183119182461"; + "42593678790199145995053663684457815472221401417968114050739948072903660677857"; + "5212185812251048319934415989099832693177800787494715126453056611778087850419"; + "46864418721234297280212054571065932300397971297089783351260370088468371917403"; + "2146862295982450015041164285322066583154859608755785000444681979186258495373"; + "8187097041967453124034221635232536216422982441145700214410051992514734925288"; + "4224999113960856492299018528652331073564580004734510854400184247450883619801"; + "30046896000436459201509816995297597671241771046506201400670561663285639550013"; + "3537680698171566937918232502260485817476747029597018017860969285562087473305"; + "29039230731296834920039750344384481514120570535308392319591127087253572446056"; + "1606438979398798927061442150774687036977037804022029261455207241963834106184"; + "13557605550047888935773187080216193242098120252733035588710110279228568211558"; + "4047232145173403805626574199652440367464599106022640127004814141382369658995"; + "13204459193235673971472938035767571814382424793239200188612833165825728682829"; + "402759581944588848536065968240655767930356875210759037966670648336820844993"; + "5838980428774315696686158048972148098130544622501946984994509263591215395426"; + "212043992009831062312891996009060873100128030094171369513299867713516707664"; + "876830352021192217070586013687495740327679213978361548752554043712663949468"; + "1723482914175782687995738495132376039217305247514006613000060283960703558701"; + "44897949014063901955262183967378762018315399981354658326614944928036171768047"; + "1720524035836460098857648729960831988475356761611522787537468077531871738788"; + "43232942027991143475140536337799285287865381320563382715279532867764648867343"; + "3252643389239528156413547074205644285947056504868291498315445124123379223565"; + "10501927276217087031424106573374495637897264496162726694675925473163376758193"; + "4325213853470237890206153973507029163989200227464401797030473409932385586888"; + "15305409251523914230874353354359535059788180981148256493285783828590358196576"; + "1739088134521595648770955683947418709594948489272099893671540048413474833655"; + "32836121401171582866382562943435811841830890811447454667735502397559445574318"; + "2901016800212051377264230669011255203902656783700704539355895622617107865597"; + "18815036596924530952853517621791049640817225487294772991941444704465338992056"; + "685537555661929777955438314288998219757370937229000935628653593362061097997"; + "26092577718767817009266451734151117734467338290919197691355008501655978991425"; + "4216357646309051699951224324469648916897535233092166120987090957075738738289"; + "31651422971070076111196181838264222722181140435327367724766310272862029937859"; + "629273769938900575895441455920675770217393671083647396550016241217499324566"; + "49724468201334828484280244583213965018137667667628337917834235809476876208008"; + "5210665945744217681330157776482926914045721426907722878216669851069550177848"; + "4935444078547826859305672957116002161830310503792073317090488754376244453724"; + "2370975635708536874252971855221791566193989512753728320307480329583888109494"; + "12657496430857347720763402849538700908097732721541800130804971089165651345439"; + "980832203819443439644734094470578305034581183188994771638665578524209909644"; + "27624504294839473686174359070380877344474774819842315451839377969297427239166"; + "5022587565141243376613052649543532876939784755313934472399483321884982186845"; + "32243500134899591779833917317813896966152474894081029615308055451608309817241"; + "100058643858172952146053373048806069099381607603198359470716853088744003679"; + "43109176463952975009536800326405985839082072267836336547187198583087609692365"; + "3590740318354650377127325932768185673866050589216143382199884746038685039193"; + "18785827894321389879001098955985664874180601797364691363126127039762235438445"; + "13890410008915784125744184986842184782250517952645936447684522270657173623882"; + "457536797603734775438134778206691653593049060998477675514667726182894217912"; + "2551079617981818063329006462059001797540515944940219006428117815680076858166"; + "21472457723313943353708874304761694714619626622980133761654506137648304099225"; + "2369717436916504560495435944043536132023039617669790790048479296810831115432"; + "7031013180680842790541369815824254589599329901607532766080140079583861127670"; + "3186817293579606399172870922861931912987218438361533401014989932520483054661"; + "47464742696121028517360413317566460057783566948463915502216100047989262604494"; + "4477286400678903183321675636378207967509823582920376282336875179455466716185"; + "39603832419325005862317577496738452690938824170495474989446912069120567958633"; + "2298800618215111452558013082674860261853363711292796156530795711139925791857"; + "14989846812350944532382882165944724612680358022683579364797569235893833338786"; + "3142685991363476580093079952421569893866001742073784831979945318714331027416"; + "43769651300419944305850468997800960823562418250967725486604486195418246726438"; + "2903010404487914441440543971760165793498717412157398998979659478200111849610"; + "9127217127088119714695972218791177892622662022240237903196570849597530951732"; + "3027763266097571236073965528146797815724807342368263722325647490051351338620"; + "45161221133645017886711261601412531524039384492647873241614048192451822952596"; + "5202754415287792674027662002817505616467813648816826423072323182431484254763"; + "27242140821789243686202266747999653182843137901581640581966605089789849278720"; + "2486352432460205806125626579336554262523134363643243180816080025739061947057"; + "548204231964608561639273529292263414738211059797673641169135393526364027262"; + "4716993594931512860903097324666779737924835078698720901019262576473692405762"; + "9506462229205667401284173411406418258324116909359296336613315546137690056534"; + "1391686368350831625873076044206727120952405196977265549638557303761750998100"; + "46689858246492672703651527423393431292021158320712191462510792543052803111584"; + "1580620578339082387096281340287752692331082813664818782512432430199720845842"; + "8766399310646135463189410004038455360577767145004053413178639873677861998820"; + "2658879060923784327242573848583806968749526761176482702552450732606621976196"; + "50023792217818549536250470523936352020694495495726497073388852837421457132933"; + "4272193681116672267015435255576813070070642689876644167010407346355080628052"; + "47324445308700031888467261626081375992699772780707953194100484365789882431454"; + "745357856006460333137090209500374787442676746021883329936925355341586796125"; + "49684264081550689554750192283845385456679466775345577580166109490155297289216"; + "2362271878323037569608969923690509680390263526712033638784386254822375382291"; + "18892236458444926391262493369877957647095161647121024401756307555714456905508"; + "5172043182544854738478432023277651888486154164999709997889182042094718363590"; + "47112383745286980490237728644604959772374713243485506526636290531977086233783"; + "2468514109210073002795444989278838981077281022625955381003550228078769970142"; + "10760484429579733150748722744770630969539979733239758562622191462913951088333"; + "2172407928705313709242510853013332534382543340814365168104730638847087842171"; + "6739500805755904550287601060022858357500641732900792528669270754636609260080"; + "1785796504238035894463054840331280673310114293716511701617293846491504923269"; + "9632508482164659471598107352396309307790306866273893677886800050425109716792"; + "3314620184087009191069387298030535408664868853185208251237161964919487311583"; + "24563068966148861590901041758592735266698568871660764465875702639116829646304"; + "3172137675500596733636646012235521148230652144749098341049366473486393549037"; + "15684550895396068515471028729350115969732417905333858769590344727369384081603"; + "700248760062686294999986760567278360019832000799190116197996203737634652720"; + "52307485942779459117858479272884228966231265749455272562573874738583619442420"; + "3883657152867570661880089300888026858157645675554719017373884998602380872572"; + "36723879950613977022517261564575507578807019198561897008776817934657868063385"; + "2024835079941342579887433286943199727995352689418525852979628443261099900191"; + "34307840796460362263279500909803958773744979234069495184913872991803774632950"; + "1194435145355209307254189344049195366662231267173012479411964865421960287667"; + "31014650885457826200510401438820002615957776846470325819050879782587513039513"; + "1948547531889945681084691849162487099956320106182019457285868979225032808870"; + "6993260155372174998814252121448583176110548765257321055692123275495549108628"; + "3628614090784348512068372896311673975933525338121052905825942452210572653989"; + "45808574143983102919560752637917514976543075616407947885927216602050326197313"; + "415726167905886898791646220028599685530282471266098241258736873574263892652"; + "38246990752692475328034119997100943294185371168683274197027902045227898059034"; + "1110392451982987995401832490062981110412534192161968804207082758239406833706"; + "27701822355979751474804532392435063061435232116617771073364561464566348695005"; + "4827132391215463563392983490012590712072004147843077585296803565588789328685"; + "7564632283106849394053909408180466805017839429085275010245344373283947508827"; + "2324327327872781533558464380069138496744200643744710345906001952054490919216"; + "13140798650640322980324706670787476707003590015760438979598890984450151901636"; + "3500199380257986467636891750311499575228052306333324812280355945306510138466"; + "28542459574187611357589932976824304434500408729772997945459318680944578211015"; + "3781610762060567361822388324763082672099242323641256901088184397031508534814"; + "14987021714744452231617911764306940261543565067899914241289807445701754462007"; + "1609241716573434851069322332824879589864503452452228361611682688852939169278"; + "34897051546770181831280754566237511483765525227934927588069926033737344741728"; + "1399786866593207439943434122192779159950880088201666748148964449373614133655"; + "32272666727605419884137989690354170945870520375570572628324661236539945300289"; + "3163147813994452717406281941248221080830294034049663043880208950896403668492"; + "23810679194694574195614528371448302918064916463216895875739808511793511307298"; + "3649117216925272192207726573369494771588983064037158465279599876172844009039"; + |] diff --git a/src/lib_mec/ark_orchard.ml b/src/lib_mec/ark_orchard.ml new file mode 100644 index 000000000000..e48f96c723eb --- /dev/null +++ b/src/lib_mec/ark_orchard.ml @@ -0,0 +1,201 @@ +let v = + [| + "21336748718948341580718806012059296653298749460224313342163758543349174712228"; + "2226557015593502525542713661842795769495413895683027773826554169541499662424"; + "27312453262039982352272012418552728324587451886745192367292926888624194891958"; + "23729558687950231766349788890101543594896827274253918743330804474786427016465"; + "28294703743080216682962810651494296437128630233853153712736452580574861971222"; + "9148652007603769128216324678293090081869096979679161060179430564067855405180"; + "15161101674962274427637729112921450667257861164738439152554709179026962672762"; + "23096402363068010437807380509137849363865901995832664351236397907044094612502"; + "13327888719987643300217238300118785744790694416049840285838492152219279950"; + "25922214782074722917619434680111370109008187645964408368795019247664506691614"; + "17241138599490132266599293148304823957934327002293888979621965820941148870521"; + "16815218361112053616697290571103230900012081741781533480615738826614339417704"; + "1068347997663141476526478303311494547269429531055965923087725631106112159268"; + "13195109308971255825625226605461900200867953970297005748599674613748095524755"; + "5266237842602583800532906895496153714797554892940357774775996959564120501292"; + "20235508160530907730459995047736874736283258161123573751206718597009771568680"; + "16492620479347234121504768616203987368832470892649132261553869485892279639316"; + "12123103398157548959556174111876152920597414994659794934642080770286439510065"; + "23547798006347312867651823112555081015661359812139834373661204983959578386923"; + "1426226816220545544526584434964027832979444047237204416636621580309609980608"; + "13145796603510643584853818731401333031647938155768205180152794998336283611984"; + "6283716086927866531267189015305463647304289021128211691840386422662805955956"; + "24231538904993627987815244526763011173475688924967383047247141986217183827860"; + "18544480786704437149553598554664581004343182277632906438833780056094474666038"; + "6542219697426544075238845727585264088847180733544395179307507465130257115648"; + "10482092263930204387958165801757696831572527169886575327774368177127444928455"; + "8560859973604917398366478939225281619007270518484275887617456309235054942559"; + "5510136301217519617757327477630701759593624518744733062672868974073449337752"; + "7093269891329325656383444743963743270597443036937372651138083483998632318498"; + "12627512932270359369206112374702579295957458714546314823768172605222131493671"; + "24023079158658326980806557904975255089445503843654844424580947026238213629155"; + "19039937228207202916770870884279962246082034800327060167475509558032815771026"; + "28734869984127469659167495182850788655888543200978783295884030710337209004283"; + "22223914513859011301539446821335593935719623857341509907852405893730565818273"; + "9651752176709543862541171982577214873989816781568154861420710363175574909262"; + "26056886613840066134666853590516314178798376968430495615276762183340033438402"; + "25598903052732643664450158100524174796347231874986343545602194243402280698083"; + "6761988583656261357175251897995162582602866304251645242297095635647132316934"; + "13698547323169950562496189029236711071217312089545974583317080723024589855892"; + "20758403177310449369206332187781269327404795456796925555537531840470676605607"; + "8374216676115104982410360274002772454484303870513844760707239978039721142118"; + "11708784485664398651513660648364268564786792762217769047515589417612918940086"; + "18318155538467999588973068171159919133234221128334199897646998112922845874269"; + "17813202652774086830867560760822116559719628352812894150157222532493682916227"; + "21470447007062061613798769304028127946786267260177165129181202919528406650894"; + "1612290583600753297333776900816152627844084956457356775697631635893393497538"; + "9423824706496717881319213250558986992642414874495297885032982205238641187410"; + "18750978313632001125631255422606626400232437900890935663596870966402018830165"; + "24745683120169994310196597675060206719376148966998216338300015462476896595516"; + "21249942951913263343479683206596541494776847296266563802484875995115630574018"; + "14029969993713971428325560420882060241327862385992153219467003977560980242943"; + "17889802712576493747957804521872885736155487163240324689719899849692002782384"; + "11837412974447931937482695325919417094711342392557919764872877207124599972870"; + "6809228199593363228674806146322196178017961187616835621248047117265708359580"; + "26581315198730814325660782120980279360484729338437624916987634335260510228370"; + "14247098926693609459711516650930518635307472601960004219379526622064380518484"; + "16755560685445835976839785519599313947755948708872038179982730023038289775493"; + "3516510691821981353034749148785143281357357359917923075859878619868183584270"; + "16643237884815169116597543775275064762553872729624258871476904964801260551965"; + "14726446542561361648144829701238816676232083379189593538315901317596659208731"; + "28330780133612688515937469615801040650855765319033819361695093356002105809461"; + "24786602876437845960450600739735551495309205897891260556952722114678567021690"; + "3797474685430661117447710856148197960231308032812760672874931776360347091084"; + "19606090528617024278723284183389923427811614456514812679144303399905125144810"; + "7240230692156915114326360592296507061505348299698604751694395400775663983150"; + "8691746632850042459955395763279080978207246782297864898003488493046634691740"; + "19197523769481880529523483521413873686831046188706774021300627196821380311755"; + "1467734758273238288474689992563020726711379412842828974376655350383944669920"; + "7594129381926563276814675472044466081054665187746493034064692287998588943057"; + "3056386416485775903595959203541868251723408752829732550776364793652236347476"; + "12173127676903300528117951011498131216448597506351314759448645238852335813951"; + "24660946510861053472033674541757085998170762172971166463941694476096868005948"; + "1313789954462980630118218511889134981152899673645884116805381530182372314930"; + "11204032155103606316148083706256511699049255446123340571836550069523128635725"; + "11514596399767869265665484655579159126676983514760195057854441190223561910158"; + "17501928567962417149442071593040646347807934304342376347545233573349651497087"; + "6780648897391688532512868322776565947496576715029218440974286583659994938814"; + "17375821876437720404695828729012760080885345279079539680926790529883590220316"; + "23950211652843002044510123652507478288289664353554816414015101187937537524528"; + "21558498046375113565623131886622831710404329665153598778689336433450707500207"; + "14946443983002482231648431568700278465159184045908368646878761880546783907225"; + "23909078183848092802195076881363349705698651065016985944131801953717191548595"; + "17009965988884609826945724430634126599951877587708536803081196162179952834444"; + "7026479634315857994891862225957063259167965019315852726024177713237986989894"; + "22014590875284501387623163802652514507744912191114393992166624757534463631302"; + "22309634156313531043851734669722653508574864176469550769719183026337520960623"; + "334274176994143065201791177519688474340424477126338153949918820230423318069"; + "19956460192934352295076666487329348191241297083528542300585381168663774929150"; + "16068775989576658808816551484952975257936587474541263665870937187807421862579"; + "19436298788036474773903410852426240615065268026116874488406655801247301260633"; + "12377583884515410232800749373561126324349975369869177072147603244635386589322"; + "12874756990231721136751523165786968289501929841223531815380908062848514220677"; + "21415207631549072273513239833638783152583863167779388136148061949499040889215"; + "11791301381481463056637240913710258671949386340733148984699208403355154598947"; + "15694306561804103510246075683085194899760108881936892838660253275594629971982"; + "14223132197384090595907713502611940678877010252567976944742635029137791171498"; + "4019451303783732308371091618164246372147950883875749520112383336842411235425"; + "10500639596379295213285022446636678785073990158250021472209450554786702190102"; + "21708484230185827274440201083524674231019531982477348236527489509794062500950"; + "1332158262651424876449927803464915864158927700851533937418775871167123965048"; + "4601406348677362834823266843799034145824550578558926159098492274142048318407"; + "18743996261838258457661715790472652378391726699508597245869726746551109009731"; + "1810835871673816112670991697137364936725417488974332286518446406640494142913"; + "17072011617783861458022068534747051316467035948043584809032110760553303991909"; + "1770904403650155525880412265247374542765302109864717076926075086064054735481"; + "7364183024696884595493547825870433743877993747031265295968922131685325085775"; + "4762356174833614549857034179393632483746858452080039943888320570568649644460"; + "15899816339927621598532773957198407421679744950597961786457996897102725004614"; + "12259464018395145594075668360927756092585544408096765267372147242465840744962"; + "26759872823668687774599904402849136094010767714360504934806160334544149339380"; + "9709557749446899545506476295666495790390265345770488027573458686737229293043"; + "2796129820988829529661957854119809035228714268005957115192115842901954235391"; + "200738025975805299622310652034246245381840275797469453614198353030057068983"; + "7039280087737792515584875688813620267329347131792451981778683661969898503489"; + "11285927585704605461002434899557718486682637800660490115236081159882466648260"; + "10159429349611496287762818472586655861626135274228065213113335732248973094496"; + "21536453252604300170876850890880522834505594677763486169711617096477422927330"; + "22920020752553052265631696999880458648906989673719789907738056668582597598779"; + "21501325670424351527880093482090563254549457206563014992164755364843502427698"; + "23367882157088472113074408709297158206258865920503491001813754366986050758142"; + "10340442986748861857838173622226296284181748456303450917099752627789985386432"; + "18251011271099872074753649991893099519352403050551972063281628118800680067063"; + "18598641128808128279485544544220293313473942335310490500343996234655310826673"; + "17093695833163685372235272125538619176327489588658725527394967182928463314791"; + "2642080263326052574834388279527351508073667685236152557198875530209607116061"; + "4045502004245232711968680191039663346381273245075742789401956149895414939058"; + "11394297392212337439960242374302727137266902400032389959218101547645103000156"; + "21978555859487192466999346284054578746558689020311694307215083172185354304941"; + "16435861792709564578919173035419336324448200943165782751338247905395340573789"; + "12342115800251569231661365211343584353367603229894533128476534906655998257229"; + "8039495407845487442379065866771404737083639866193100460215829385415324295196"; + "22567569370958709624766969228528434553913807376255144119476680305412589824821"; + "18517901619835208075636357572007670446270753669382689031281159439002425730313"; + "20436857040030783221179256305949344997828216998408988934854143968628160177213"; + "20585211991804941597133285170010894244494369630708397863450608135529007171488"; + "25234815082012683270959546319592840930055079110894004440259911947738855534614"; + "16139527307245980497539691831723000255308436801765861875196815841766003851874"; + "24260887793980147294587511128151696493641770186364742196690953474215170970772"; + "7627861469304801359813801212306211295468448352941675600717881991434668870107"; + "10192166189494610039894666278034674521899806189734527560819983821196011298933"; + "9704461515306307544207653537628606362276111583668379962012879024971354026595"; + "4458475335084298439061147213252406019012452947085007545646984540869718416673"; + "17415066080149509248722003827530688897390510331801081942401314575544326631871"; + "19812972282705602187736903717752784046228380783461588891739694396001955952995"; + "9942918368409378015181584885461008364680969393020365424365872145356838688736"; + "10735994751717144952418315541035892844119567011626702910093804692340495262541"; + "18421557859557652059984311743417752046438932119994496244367401685237094036274"; + "3961463663173490917144785697238316092036621934834819655029388843151372887718"; + "8779421137266595105466602703613370740725544926719807134093867588014762097181"; + "25959449890802678271981933453489328540493452118999177302327852341632855115892"; + "11535468585921128069703378497218670838960304997708618425049277970580295744651"; + "10776141248372604926771491761901874069199059823450836466397587209288373339026"; + "4264854605886258210513665037739569699141530778721644301657484067391745754527"; + "16843834301972016086639966392419290229383077588128295518480119531565971557643"; + "5546355883059414146380589971765921077390569464505057277229732293583759673364"; + "12907577285789407581455235930402952040744515486861645676609280957433228097284"; + "18658834911270203673512938280218183272566601400976629504705713795552188975289"; + "16233858241253362035685566525490093732756883040023539301136704241259331444349"; + "2015900613045808401447144959505269583918632562348256335735585224149330311846"; + "27469077717968790926021210463105109044994359907652408411344092629108484997208"; + "24536936506468801651134230750903252038916464592361909133490681943591870843561"; + "11804353306692265178399394217379839108616871739211998186430576645695790295977"; + "28646010008541140281248642311275851194011400304030645333023353077149931244002"; + "24276783854546812350738407774542188158922018636502595212081243319015774145758"; + "5637179961356886841129871311571360285900409522716195147681437694350921511403"; + "2674159408472831622966179092835503874062763707768055439693701185747094610379"; + "20826811010324286276820024111314251952858997787823387262055812579919552133036"; + "2613929642402076504174291970258282778822053878372692396356742714026960935664"; + "21555081770418702871127666529077835096405503089448112253224571434241130929164"; + "7108717455016614280114708977523554146283432010301532425300626973177229925342"; + "17041618336360692507905735482405929160457077666423361584623032752206699784400"; + "21099855968342043149474412780187364133919998495117579442760406371532621243974"; + "4783258503077567115436509669568853009175558291820509619550350207957856571169"; + "14371779811554645864381234835369708587243732331234853269713475458267223732532"; + "11414183197229916780594011077413501199268307537595087453378336870582892613740"; + "22088709350919700841675024218003418940292338861765712525461483240591270235985"; + "12698668480412257517841260934586423543203387211124280835582166989004954098314"; + "1574177181698543750140347031460800373312373526392502070044417264914064661647"; + "2770014756057717280173171841010684120491589390973203627890619756128626200826"; + "21084468205822542698947967084210848265681820022842475642008429115179877849485"; + "17207813077884787164062207674015569429648793839287155778160873004738377864177"; + "124609730855945092222921107652196656297817448058105400949416670718805818976"; + "23150767027882724048742398292887054259329578597327803034433158898104910436164"; + "781467236872494628786653586819907139017769779065710147866492397648207415808"; + "21110621806613205333963593711782254303891810504796103509592787269418729429906"; + "21817377800326986513054301310397080860220074544226304130700660567244979187438"; + "6383189678075328335368038875585953466163826440770140253849053385174687021926"; + "23076931611202631314179246340948401344156492689626153709228968756129414151806"; + "6635642292195704937265334802420166741940611858307717163443390134017843135216"; + "4978782781279058720980692290776395062960827920161428138820558796516737197654"; + "8706171672068913789487098664140970604030783990221590351531524142808306001524"; + "27474393222184166038654410959808823147577581607410620078117642870412708429266"; + "20454238108201182945893911082972079664447243967697894324767607702720590114055"; + "26641017380131743375664889695099620333281802200317027117774383548684717972773"; + "757784550215223880127030344850629592203481064246246617066634271117558489349"; + "8175162286202210124748159077672814364688792969721023089898528319726206484520"; + "15106933054988902608698470098058667802738461112483415357965796036128125440253"; + "4915828567158613627863422826977324852714104736921378765729790351691591669186"; + |] diff --git a/src/lib_mec/ark_poseidon128.ml b/src/lib_mec/ark_poseidon128.ml new file mode 100644 index 000000000000..96220f7bd83b --- /dev/null +++ b/src/lib_mec/ark_poseidon128.ml @@ -0,0 +1,198 @@ +(* Generated with the command below from commit cd13dd0e984a4eeadd82e0ac4ce792c275bd3b18 + [dune exec ./generate_ark.exe 8 56 3 52435875175126190479447740508185965837690552500527637822603658699938581184513 NomadicLabs] *) + +let v = + [| + "51466596801245350172389236854912648222719187746298709105513845567941180611585"; + "21750751762978437653936573013155607200736969558902465208523342419237410586198"; + "12486517768781903523286807847370218034689963995541894791925792444351839473647"; + "20445718088460789875962943176961386089719184042145123661083866290956184640219"; + "27873160203424299876666416455237485949282512273439804047040763657322096149056"; + "41356063063918478660008355287283031045994439439052675999621074603564345282569"; + "39339901461669097862513996312696398098463519178491001542393778258774347097156"; + "9204042589329629203508256352213922752007565761246017599071231880772962888313"; + "44872792620396140616818721079703154415798612187578057809815607666928058754777"; + "15937726977018206908966109373834056579034465379649731865901151172854062328666"; + "23605712034497375740219228439343452998072299839093594319857450624289690266228"; + "6402638958817972947806346954920050102512724107777426591914400080844084499349"; + "3185239264644999224390913018332891687143438328474986546082170376396564918303"; + "8810128481422180179093610800905689707749830921384041843188605671660723745224"; + "23856254368860098877925830552890800356559853619873956523749705505858453741419"; + "24587049159258135725439557767222187037564112044982562605667614163816312730472"; + "22837536766890438293232796017074642678223630893636795777506185541273623237047"; + "9192015516308615812149895996678356120602200776491327365416854885711899134185"; + "4002652916865493677251257166117182479501804845054999793592382685603350748223"; + "33066348252219459468552045146523238597048287748451612668563453612283148717787"; + "22032405802641325275844419284045173476338377422793990841002770933934147271753"; + "40810499016480900907962993830032852958946905562531549979714594924288595159449"; + "11360048753112901991330610389408512769078774607723790648797196048769123341818"; + "31073120699274505130875191050788584204810084807427992815212547386082177411939"; + "38905424489726634595807315824887707754301482341060164517868666848234609856296"; + "16437589687938886598993201288686198745024640875414943299079721648754955896524"; + "9246415141807177921760679831767807305667023086044867913825908258624135672402"; + "43267134335847210508826260454424281515957785150826503791438907274325277067689"; + "47405994765042204778087426457971662098880376129631959037220571890293893837627"; + "51109501544539159334717344833663305202169784719089645141283241708762847921831"; + "28367352686904931835510258483164340654232741901091990185726515423922311395266"; + "49750106362878302307560487257360445042628424171940583005315598767946030678175"; + "45959469784902653889236043731939532829295000363517367441618551318205534438835"; + "27018375398598043392768159138944903620978890067620474698695220978535490993662"; + "37680060127197925845671480407334293104013784691230898581176604640776871595820"; + "10072365749347322273683640976003223868449058525371389769456254873788829510856"; + "5776958426313577264021166002700070711779258526703552908022966622941040975486"; + "2052552766687385987890760301444512953288614090851121718631539540584797743813"; + "29589973335212398499653074528975769763663217998670026908669929887809390254086"; + "47176517056998440790693968750261830775359488909857950144871025285282622331205"; + "4044841108655017183998683299702141262167457310115051178539772996106040315055"; + "23145769961882962007007503964681965122021931165884937363089732236563915279899"; + "7603705117156652453963281055927587143772971225944827219299824918233735396544"; + "678587461188445034628596985861476825212606316443632929982806452029635142763"; + "43358198653600383869329744766691886425670686115842008451706594321104589073353"; + "29783989749004381558893964246285207519677877370947641650381151227672399441258"; + "46788814117768703246098518443423934593855222525287642802070140820481989754464"; + "47667240567568953271881931068585333300960463653436442752666537199724542862209"; + "36185825409915459203448245743109969343193138020188742950229819419575178293681"; + "10268626031678681962519788038923114866365639923373751230918298280203944789089"; + "22423180878570467317830579782624040309181433514468470079452795926252301501451"; + "27854213599947523969400957712485981554578482677686500615005910306191690675548"; + "32552238758912415934584820719305968737837410579067602670579118065160652867044"; + "27524020150199858721583983985008046355789957344374031640804833804334599991125"; + "11598691035533751109698164453612171297192910953856758972631340412485692367245"; + "19240281692025919244580609351663678384250073443852130798436970816624877123792"; + "19081743524319516787728673230184684387616956386482784328031473187929184929813"; + "13482824733237717061443533817612030042881142888904695925365483772570662398419"; + "24557586779364722370887646696339785224219486745231704250023468368642112077961"; + "49132695885737549819731989839786719093658647324506783818463101428078920152339"; + "47598003338017334595631291432676651103981450315484662200923020856309789617505"; + "29657580775158274893108525946918168971159316368647847989798236676167226124425"; + "2089871173039090298283861039787654594553968107879556266696645874401027551594"; + "17062674176584193145991964541286296980632589397952567044305875706903816798918"; + "39759050960205479940159986279409353005846424612008117451162722701140967479478"; + "22533616828186323521649895181466155821530425549183373709986149684843468562921"; + "11710329771453525931280127059748492796905639784050357470339844149929022650252"; + "28382230089609321965313624834250197889691846195285335974753263997326737343307"; + "17483468269617424580234048407267881623433885539437967900597355348779845904370"; + "15393678108977111939937458813237466536883800502542016725609655847312425800060"; + "35335672469945182745009570081451366206953223954844817103347451918365408472583"; + "18485543557533557196522038987860777539645907448847172084578647917456309932838"; + "35453109551100805378496992884404555281031142908343718145992408005796255932067"; + "26162388899534531304185889785161995414351042512495564813598387581820788701274"; + "30513272868498004256565910019709317337704607470343755267516092336967857454429"; + "7482438077715696595671300257575441576458965352889636767368860652528296466835"; + "4420972756750713378268292139245553512010082345332818480344347760992140415579"; + "45443072118542869094106210430408632401658283491040846320908484790994846489479"; + "4587498519897850005501095589592009810295823998176500983502979737014704428427"; + "20140268669484747984769809200637802968551617462409085249909344252279198873265"; + "29246773006012167464394782413277073922652993569428539217341804135677142314734"; + "2090453766635748262896094182234431405487694916721156619151573559829565285658"; + "28154797511075990999067437210883725325588221412791352016549710458849851400443"; + "7437576051454980648324143413673447321627481635285743115910231258907952681902"; + "47849325109234284589063376275405356989691773872687047237532536232042052359483"; + "12480987611376364480590099596287568108053904335043512585655935306753098846056"; + "35282772152784155873872416038091486728018085424598473101796189937824691931982"; + "44644309599357388823648910637703362148932670809274055496007925095230623381923"; + "40669859985254288073391010054507859022800795198091698303895855303568474914724"; + "49443653278257139506363224578511517450965492260748531903735461532886298470324"; + "28151927370999705099548977210331844092002690574491843105417307465011218883372"; + "1645107825636563552234056692699842524648459238860722695243162269478817742307"; + "20451009040028965353495911802150535366781462589345362185312598771266505204706"; + "27819682514111647266735378995664843430901566567232355462928465778589146617300"; + "9554102125843498587844759244118187314040788045621020914785690475852459244712"; + "19166777550065260996957117606165528594010042113228133002376856047908024628860"; + "26933579719124735456146556120749918059938219375765953757687070745926421730690"; + "43664899352313137143462906778788854871017052765412139294077435721003011363428"; + "36173458814979531375880943417934798141032455281648386700864729797402421147643"; + "11182517313384645430276258135181995604973901045769946685233925860600679925400"; + "18957585496621103259998572202861039692818169581041076732942953590132787413185"; + "990272065387976234207571590743065697998566272630425704533408985373371347703"; + "4566865954002478217870742631824891308061027453183663472158387320791808636718"; + "13275080024861611833879690760787568594881779009163813547717517171800075477326"; + "18280289328587924651942995072338785526297904605272226018248763384856128538194"; + "37393719051038483957290231134622753224758957341736360150179478705995454183736"; + "35471769041551236267108986169916522221022951796087962631717489467967242728989"; + "18313615850921029128115249415256953514199920171298188893865360820700589880640"; + "8649505551495013773478550513798423370916587725243242103915932173300802613836"; + "29426595573001164623970767658482684730540336753851606403197168017465308935012"; + "15800050789941506886367343947552537811144738254935176866599264324633404561668"; + "2388599729796011963372654009792156200311446590133223685676648683498130023426"; + "39710359146943858258478963255479846071237665235335480449874571631729609456656"; + "12539354052138844839668649494440055311612800274194314682724519322900896888667"; + "34775703808689652205221353219074769424059692664878491357308664495453361798542"; + "16602078529355937689782643082006360605957411241022465529030420514355243740084"; + "20279850236027730246187137397861434992518721949131469477063849268012331913542"; + "20700406847766119075096991790226756382972208779794861885683190244345925948772"; + "10767548586122669600841175107605340206307369812479898137983203022752955229420"; + "33780485917217277294437000521052335973598541648381872358473220524753392579944"; + "26053477836690449767759260916263153231466698419416254714069016291032716493795"; + "51075719579296898046678332991810264442802867440545970415662411469944202971572"; + "44425065795172674272025431261784423304992373196100933574446818463450861237636"; + "21673427825228648696679367470878911746787913779734335379612724957949663438503"; + "39500036723407342733895180253912956707996173847799994738506003893694134507820"; + "18814390742264124557923083818518430926773544077233525827507879093955534745943"; + "33285136419882565391925060802949863649369447257963104257237128389534667335431"; + "7242824697084765204242498009056108554791055701454269759053340822841847843590"; + "31173248312673499793759274086904799638353536404479301039538892557122201869326"; + "31186133094427811821728441124091409602329280228993044467507339271468902426067"; + "25737910716320624211587760844165755540380223663083209047341376780006952817951"; + "41007486903540773766178646801963663835738017272207371664092100665995867447476"; + "33733614421653704619906981612465553433605639878071728634533669588152171336923"; + "44508002187727655261274038726582531821774653664912931880913651223618478524203"; + "29308206009053294442851242412693308913204908282227130202504576346803290538114"; + "37195044959073314994498067496758410674853446343706809704471573374824766240756"; + "27750290920151880266415654177442693344449343287594569254432923001134909857161"; + "15765188586172333129026261765507777427830002956246082548695725135386026089531"; + "1723567911352974656239983052419150859691079784042460780666277969900550546629"; + "32624380698163043349452348170080919066187676495607088889037247382764371823304"; + "42332347907545864823851740450059178607636354773434217763190376183475294814740"; + "32851187296571784166842016235453193261263026420621113443940941911613891853263"; + "46515450218610398244495734725817662625773300495752440637456039809680716524335"; + "48802434618714806701215020572358407402163910104929505500552346872970874445024"; + "15041030433764412988626541831537854311766371887970954109236962491586466599144"; + "24914207471851043784197436527940466212674042052967065649457499415892446136159"; + "9071888319763577380151443506898914744736366395870413605185856133895174517345"; + "14324407136483074978482942921602872905704673210914714962854893980450386451889"; + "29042406409942557018444189727617456411092110677398829954434968404039936168367"; + "45298132425441112218235385216467264374863717020516284112024948473015955374084"; + "5848266257013307529285399749765616739303579930676051972945621978827280728485"; + "50258542824814649118248459254788489871100732773736051031417014804244168803608"; + "2211331518382464997157173039326358398024782525487574099479995890254668498248"; + "25495625009683093041292487489064498029388757676050435379647316032736436019034"; + "1673456300079357795623609138015785582077169647352697470259283949067483430156"; + "732875001458000671533092091268384759392197266180901126140125986324726970217"; + "15937486314053418275659636264513684188072392679031027560851186610858143116536"; + "37523979262473761872442642124630377368104280370382009467506872860620420272028"; + "1463301537361190248611634113301833004506917120571380701549297040601288661632"; + "15388046866006485479772795262309796656931214897645470303116977773763549826647"; + "24820458677922696742762859449292673635627885851532245057181102097543570979209"; + "42204379350085294410776773079715228191662735656426212256162333812793552403993"; + "1195814176795714164840835333744966813414161441324551406851397366147530373686"; + "16761973517502055324144398018035682278752429331149035356778515867109688520079"; + "5794935406580257517632452299232288835369749493148532249516641371649010994761"; + "28489054235450115341655557856812811692903805568161190542887091508558194202484"; + "46027667092982098207528356294714952530753544394086856091550981466630371723227"; + "36549545461270844973100848885411892468389487357334958172813302441582453767995"; + "27730798985447029088568033769773024804917434212093202895074054132301610442265"; + "30053494660111523933577748614419372203999341521131288200082766152193752930915"; + "42669519840379176591693261573919152190190830699417113996773900230897690941207"; + "40491463463369636128381274334600090418795787105664137021554873372325496120497"; + "37855317198077808209359933009653152621140711928666934200968394018548493650684"; + "30289339203582770465154470558134566153982220926251521920946038335272057457401"; + "27778690140622310321003540914723670899734999136798303644913768708258653156597"; + "3973394156719142858738591330892034076809261304074876595400530436577715032673"; + "34101414891901169069858357639409485174940075127343413252072373211617833012486"; + "24763874711353584430968413634679742313122411936945926412259875031351381484206"; + "36482519855965638025925823411871352935082631497149119671124638993468289313858"; + "33663960240182462215313666658229034428117630528389633368925326911863733915779"; + "24156616496917756781377614606496469046971000527652456728186486373912788616012"; + "17862377433968409862537980143869608526991820954912158743675488121333401401128"; + "9883166492675772730546061809268489723031153354700278026721716994418744028520"; + "651720966810612228203754272949951577724164458606405611640617175537862475287"; + "45029571820041579599811835408905235857907197206303946042784264756752149312055"; + "15218138019507525985285504884751281493313515412230279354014712290617793064643"; + "7889502179901137713876340968057633612399550484642109442993286207350478652780"; + "51114781021375925510384757787309929484526957562759351412663650152039538436129"; + "49153605396638540179308253872425727518164881509781489770081628829948751933325"; + "39446436805473057234521273352946756590838723177719005850741347955181052035907"; + "32522116151199401996556140465344290516461661003004520182401454275644784968841"; + "35709586671485611381280332540710898003892567989895109778435218770617343891091"; + |] diff --git a/src/lib_mec/ark_poseidon252.ml b/src/lib_mec/ark_poseidon252.ml new file mode 100644 index 000000000000..09cd5e7b20e8 --- /dev/null +++ b/src/lib_mec/ark_poseidon252.ml @@ -0,0 +1,965 @@ +(* Come from https://github.com/dusk-network/Hades252/tree/7a7a255f6cc48f892de5cf8935b5264eb8893852/assets *) + +let v = + [| + "49485629590707188350627438543790601843164666730832802354167700559078990180805"; + "5252492454239988725999362667606361246537049278449296815482681202241423199030"; + "14618464101860214640501669418913406667488798576646720991952572594257377039502"; + "49620695691812425396881667059975042814057870860951834243048751692229624331677"; + "52370272705607335752267236318243264940083827067691749458235447563501832651257"; + "14710933242610523976995706443397757945742163741677668728466445608487118981880"; + "40295605676867759583334785789872476122167378326657237878145663333439589007156"; + "17275250730668933226474210235642934004873625116556680337206784052264566986455"; + "45633796471806275582583687299302600425559632837704148321307522586100540673964"; + "33681130375233352141656505268473716952957296224087839911967969212184713588195"; + "712629851673255722293534395801485044243728655856788348424319702704859382351"; + "43317142284252827604873495043870647060512975769565878032083607834275571303426"; + "49340354054830215768241644525595586576960916648952093483202539768057155695733"; + "51072133689923992485577335797823140838583096495379330871465525854048879509188"; + "46949696588385743239566882413656461741807666921366097544593880485391490027378"; + "20573821191096550126141597782760949856255209170402036553268647563825526870436"; + "27160407187556206874731839906107055583040719055315009650316032986707542736994"; + "50189849422262643653706645096664834529407274784147778804216234124791624405728"; + "36711845592560022607016872007330968632549815256229219571331231734465570541772"; + "35499690369690524959345453870997264497352033723668303049826986491601092626610"; + "16316511810555998552036883529281049006950270019860246764897773268401228568605"; + "24273505785788709750944619357321960159456240163658175721572690190239573216897"; + "38957445901173225235458499674711464149245486205504890531219786468849422975246"; + "11823467170230054064490275077272871963881914272709655957174399232209364647447"; + "49592360594196231864432308576338740596601726416914181276008583207908643556097"; + "3309012748654570967607135422003010755248166478871582757366403846071939043322"; + "28008997260349091544245311173997512340365040670749744770222988406313503293844"; + "7882946347332999275161185525751330966422116178677196163170258809540423320804"; + "29731010687109400386993771800155774620735785970162866907509352726525420687486"; + "23931998959081617445949503259792788311676984957946834382760056406764899364397"; + "20391484046421688653112911850234570788797563186823093327188237858525889539247"; + "22656719734855634367860470343411809786356929276974263964151006136177227714579"; + "42018013924524453942303746320960679879055521221983992010530880401352394546138"; + "34997396324562296578241314578708220449054628732531003841806342137992978809863"; + "42567292638455246337550117708556510507190278048736836413208545981863780856831"; + "19529288884212474725617121011420109083719176084042307000138428649194091920639"; + "8327938075667211716886168580211869181679628310891241396086663868161241632320"; + "50546778806178535468498887210218810106123307251791580882247524421100294295341"; + "30574977411404820333239918514944667200338902645085529348563130262864324926217"; + "9892903275194545714737750789991423957405171153621887382923972196579113423179"; + "4920577323034891968079586456848977110594227055454553465331672976737322470181"; + "10785473652133501829555600968223966606682909992869608850754498368109405959958"; + "44259656456536904544779434380762383481009668840670964276817234604369847527532"; + "16013602167551971824719708405514957436426476815028708803379542465790908188145"; + "13198374304416209263916195294139003986416471192907786718634040648208496216781"; + "21804530702651053682928092693590400484720275112701610945338033348613546128300"; + "41258400074102294032881307279891022609951591773444936556013171377165772120999"; + "37500410649974720689109041933579952412448029290473291361854784961766576368877"; + "34335673011929272194773705817147158647851634047942272296257858433783818390462"; + "13886304004325070507319308017925418279796532347344964674118255936953984359681"; + "36212245366398184116212011743173706647869616792063869197638400841024375748712"; + "25759006975740081144269794348054803069434307735185793664670622388493509618893"; + "27454141834179019142193646102488261892878322855049554559653828601521710959492"; + "46231413498972598224538743321743754536555738713900369992799611667660505830198"; + "12831308687888044138550325104853798541540822575395885697883589148652582777980"; + "35086901484248977088412788551567969916605411503392381636519644581735135246639"; + "6475115432881146883349186955429401720007995218321780836251063967786164777830"; + "8814580017771885006531117758255250813668411043820855097899546270767102414310"; + "7807296524174932448970457695754749231363157877776562676221113586348272093145"; + "42150072600290314522584934838938619527057217927054115870685066610015126576749"; + "12014531038737162581705520180807422015561278346762069046014491217217393623145"; + "19933331143038021192464408343147972121326092927465949610356498707738693905912"; + "48162370217774420152062014238018799880581373414572553684036906215372618932347"; + "40819852050845908476800605687008690729086125750975079926804162995170273045987"; + "22226594575860551577968163846926724696603097833150589784765199214152339318359"; + "19545194169971732111027157974516008318207647066892354069067261444231038348510"; + "6049836141434740667284236008114543106249641546035952601692539242914716493120"; + "6791353070942758297826333323115522110180828045205749596445149910757953314373"; + "29909049992012855058485881696486638410170793566701289014595505025597038675406"; + "37049050048958384299197228584051152045340884544932681109205219968133691211039"; + "8271317962040216706363322101654508431702987030110073352137002798152913000015"; + "1670774897775895329767148809679299585171850878621026134776642441972236794266"; + "17422031471600536376610034591163807877753208015405398182227178552347096580633"; + "18756624022690204397552680734127650080255894251074233287591407798661854030530"; + "30668115702052736591929919340014079888097509113980964494205188093038881676393"; + "22070300308208791796677976010650187233479496718840088914015812675958670301234"; + "8719223857171626532277312086417428648729460205529882841381547602107666862130"; + "37958249804564731124361955041894134137282950000798272227069902229038293082676"; + "37189467966805221844845186538807960819299637527099935959247421905494814306365"; + "21466607532037915848310355716841895751321958036985554994122512635502114704749"; + "14179699035342293451307513028958516816541083634684431605407839181393476104825"; + "29154847955666596586127425042717506047631050595585497722311215198569277732248"; + "33188642560979777145374528795549704783805148120231153611600332204665631092317"; + "42564521923637471405699083052532506872185646145525237703447984248100308540906"; + "9688958844450335307002049478744008486071252176234867674338843547336023975670"; + "42848254690746470199841780456337093355003554479162355775109612541732121188865"; + "26571650306498172537015187191960172565543217489415394043243003022941239501277"; + "13259263851666023894687861132930820553832823620306352930622248435429243173163"; + "14935311346095148671867793890923330605843422232075508196436807220447844613370"; + "4344538561671100537571115284147321749241294067305664704606142724262115973132"; + "3661287306275145440306213618539663151346918182078062211644897084121048254313"; + "20823698858703001283317436317010639863721597996546476932310242177301854267509"; + "29589286785528202709772071088244026953664280695981877455063175736821781541694"; + "14714810814119711606060345652389090896596349569507164391329166387481498170325"; + "14212678415151015135383112231592717825106807730018994977285657694049579298318"; + "27294817345129277597625121693563352246269025230758913013178562651622515976209"; + "16308958452953063563921495978976808898979645896736092486449459545961496250858"; + "23801416487202359083498068782586588131855222018242538192997207782091276206860"; + "21788204341490442112154345605131469142633618445779895292676418878377458001839"; + "42939889385890003399975992564558390206777324067014435789391978812483943473084"; + "18744379815502146842706137175625169737619118740225857671323003521379145620839"; + "22969419294986037114832463860692313839911009856023995119192316414140491424064"; + "5158048168028926443440685040647048915854092072898670428607816727103222084992"; + "45436514015774807133067927806141304958513041619855877603424280662728885659666"; + "4148575853437187976059844949320814090464120728486411120676443836675361156433"; + "39274458258755370051287444400457797244045933354561090576339386851101477414906"; + "24226038446737669899105084780102219021070008789681262557528873238824761650295"; + "45554128757216009101367584501852978682053416379828133489710853000149481226345"; + "15468212483347652283360923936198282812982215187267560543021929817615478344667"; + "49120785890340968057046175708683790395194430243216223332975263066275757413807"; + "22165820818885004643510856850784071522542800536416499851315809803527220567485"; + "24255417733013943695455694074510916498983472445769012245738544215443095625555"; + "3578717881416756340877516666877448995809041970558865616428083782655188854064"; + "23826341091172689336238927086223180009822950998486138608038032100061694451939"; + "27712967780178175030774348740828282622058332263075474167028713006452109351081"; + "10692520630891410810882731879436263881937079315958040076096859309741666181887"; + "4139611615212690436843419488530338015260675471298926305839949926237319638064"; + "23893117338530655111858176000813570070168939016669641291797989062978619668263"; + "29493430044283825498112780304231954297919106956762292987523773747600907821123"; + "31224696921534136211793606269507101328026664939270273541391154325809905983477"; + "1161990788645954276916059640768435755816955781531340749166719053457102674329"; + "40032672466651019681467480685414198090289911817277735486101335738870038918838"; + "4663929628087510457582572341889343283250798458980128777564503205493248261588"; + "14576003601768386193074498529707218258345393840871241657474970275429765574440"; + "41907905377583342345509053513634246064531351674075011102250846877938645814680"; + "13820230842080821315141850957892243677733920498405615643268916522170002600281"; + "19848873264729615502674527376791162181860225160995619982736986062940458512804"; + "39528445680729025348431669264547519897612726406686606338168880578253680155174"; + "3118432592224748465457531048962416120738464253058324843908920356643714609755"; + "20291688884043804174664313901962915383913038845115296389312218366129420572704"; + "42557007757415638497613471685612090789101153750789304616028486221591259415030"; + "46792197373741062915032927311079971699067950253133746671662212783669451417489"; + "4446326402184357086836436163159453880944166545117770668456616153083342179625"; + "28708468885765405820890561098801183951304364975777439218943183437220558999123"; + "36301422605515541288198992288053820065278318287890213939282985302088469667626"; + "16513700588570500247891971462860214234891585098734807087134948638523417237942"; + "51303521335085563665906206982117421593801796082688254691383972540879029269486"; + "38349748912024833254388160686883390837675515065069293547130880253459258191513"; + "5863602768144479058589215618670066402672112266393989291900873801213554123005"; + "24816851569224726654303407018916136914696378461182187828394888509457202905452"; + "35668217636187023661106024284393036487257457620610684950679976695467857461614"; + "18049157617317886186455739291622755056587311439504905678793914609021791583485"; + "24311184582337406630675921345578587870745539726250911563471149827579208380375"; + "47049171163587328805804625147855798309518236528924756379359079671413806548741"; + "49217441966653616354960566046394237511933307451264416176581197097030607882249"; + "9741440763223308622766088611912800832840447253106863229069648354711337865316"; + "6711970275005184765958920828167320253630591665126522378985833259053410800609"; + "9977417151377590543160871053129520943830884975635063831123262229069994513327"; + "3082837542990263750321290997953667039889961622919749500136642256407112034669"; + "44429448918101910406096079124013269684487142109369137229916801140750864418243"; + "10204944711013435201457808979370927831932282339697033510029454082329887203672"; + "27567961079029968585701667459244395330846299598586490098261597725737547209132"; + "17092282981739153700626134625162471407726486372216667820609932370888878727413"; + "31485584271040282956654226763326588049877825728467428926223647874479701786506"; + "12955442244748326703021715942574723118787276791607410352602368690534050770417"; + "36233598404262020873794741863731429804608939874302234761885447289322137408181"; + "17365032709923238164430981278878270324454980279560841069445448454199643029113"; + "1599308425815788479548362313813963333016792520742870977461515191009005920540"; + "43669871288596037415496023789232130242903264831017218631867709702917757490026"; + "49117721877014812477333148166335201583815489936606800780714317383158496433108"; + "50780218530638944533890976760629911189324354866670913408371520875375844233903"; + "7689428494847004464240529995304510607351514709716679690600711591096978491670"; + "47955977594669526260247931440322469685056949069904259470080759325035295286461"; + "8365512332847242169003328823195689637827840697541204265356337650289585838123"; + "3840401128719370383692078279691168408796656116885154086592491099204611073383"; + "43069581936608602226405255629351890119646172590162211959289288774795830286246"; + "43974189709355209820476462362097537404927792511028786194043940929898183793414"; + "26332351117299179629573047197679883935341765313312089900660919650133476414458"; + "50351703458402831605416039704608408974892592655299422309480445654414527175979"; + "33468607565896128905680223110626886234307943229683243021379890835118051012325"; + "6614565191349098977235002226407314032868555511403717887772191274612517181410"; + "38103056918801597643212870363828947832437506655680421481428698964117403542602"; + "32908423128582779977704279934611177327699184469671505430337832556835115384573"; + "51834951159973764105688866487621285182469090830458796598668031091107941720686"; + "20906443585217694636590360222926761090515273711034774487436003326403616929638"; + "11543128149317521186944038480148089876167062819998754661365448516694779551074"; + "13337387009791879577397425157695857206822652677921492812658909620421271792366"; + "26158663219738110112661733659009555223590055652836643266081611952515633330808"; + "16620288606563676461349358549564125077202861312536356779066223457462338103688"; + "9370353560216700598486832215289311328374345394195634955453105798486005404415"; + "33633718565315235577394971195804503457415899433434050508477479187227057261067"; + "22882449296374811923033442799913069323577656681081909852574042775892111287921"; + "2940185604989639101256714689859475930684457088567484617894462057139075862941"; + "34483194121915222880375114276064125544128032137924712006849489977876279836276"; + "45372384774901078103486078987247871000423060133375498791638103398927924400835"; + "52387604781514376107006295066270649568927674910028459430830457444029012327788"; + "6167869651297502278429690950623450349205119487045648580978208453778184411341"; + "27462497275790959876141507254409980360566911339456621474224385082554805533038"; + "49147087543811949479056383453491986538702256593160239527509029396813090030404"; + "49587001406488557808406328288652991476747338395266693648839878008858484697835"; + "6313958677173548204879553757285379819254567579081576303778677143280554291690"; + "5591468493874061488706454796222404166033712948542307967483439147905003945470"; + "2437221293824201160919193686511276517772539907794390113067425954677677410182"; + "30357986563693269312610963334150804237408332248581737751589214609304706424480"; + "16637601486751396636529759375224983522742599069263721097214299703128247198523"; + "27879534340144216562112405598077066811919674403148810235445326156746715979842"; + "30788313762153313626674963316612595454484683342245093445515009044754566899486"; + "15725387840690796443588540099094119524389569177620500091843845820844320431289"; + "34132295312326003636265296299999208396694730499866986050666477793086157249908"; + "15362934941085533070255910138373084570641154047840765685532551420580152655609"; + "2755137135618857778067513724833509904536351561976592574187101898503219001617"; + "46622911741851631588024639842856120275465416427660592975008281197121795628830"; + "6964635240711037051215022604794208273817621384886657093402502491567294160845"; + "25783574129877826155110663698218382830525380279909999762879880818546978011140"; + "23465315121256052707655414720713957672069185881022798701424890012062179540328"; + "14395053091536499765531983402867839134341617705786295303106179101403117403050"; + "11316253621114442899553787480078181551163062516697851587687844977545722300558"; + "50064661939091922013762459183760659158315803719176946262123119222324910530256"; + "8783665334345037843914454257570704820761444130918358310108843988258662584186"; + "27618475988876729519248024362417979774716550450998439569984942958903150185062"; + "43015769169394210865366119150018957649114200451714812555830871262755495468016"; + "49732426066558397245060256272342911170810452758926457010543502425937044377044"; + "2952797980452813888623715400169643543685112681184348275283000981057872198778"; + "50872740372354623466916457669382604074806324513038750478426891403283893655073"; + "392818184515825854281773563914353854398754713238832910269587407972143774476"; + "50779005954836595097541637958107285799215893016482426373886980746829520936350"; + "25176357246579974791673072598303068538657314197431647903881566730654004596817"; + "20248152184837592885327768689673131083342577141215627095954882454724068067303"; + "30064303728202536588603791400844418739073552658034934314710159102990759896158"; + "21384606984835160613401783081720653002397794837776744119212545320680659814207"; + "22759565228734648282413300371375307271924944352100268152538666537290900864554"; + "39429333593022349595681621998820719879621843929926124877175561019165223081129"; + "12070092883346592852789463918508042095108508741001381953375286128032289075905"; + "33289517265391819899507145162086978987916991654940411189206013329200864859674"; + "7221597429770981330375263241511499043705983470816845272720562845158859285226"; + "16638272235182748474572289194344411365650205299005022442793882687465898549539"; + "36006214239196604148614442091188440583481038594995316939593040856887035358617"; + "25792600705977450864245882132395859611441619832808864344772519627069798329604"; + "4080552845447537437568804141996338888821838801402604114257764603164350512676"; + "11798208445675100720061102611516112959643834415640440909769995293901688418811"; + "19858693043126873191571109475227847243177160525403793202276277722982907002636"; + "51792167109522919038849306964270342579703542020877440269381030774505714185697"; + "11631710203663443472344988456889389622339025983399538662094459108486378805525"; + "2182473716255059033897861691447270412333028850406831066185078223238986325112"; + "761168299106618959837253184610027302352675981172895412789219362344349418506"; + "36857059855189113781134096792662950699742275482770772595919903687711739320818"; + "18213396754699008102047102089506462494549290414412359468656221893099620902008"; + "12599997312887962866854539884234476951913054226022526078890032319964768070561"; + "31295812056319316979171165714902562241023210946259070539368704588259135657855"; + "36028478227374554353553197903612149760893367375462390976595843472968694902073"; + "19755792677313410149868952739127262822852161041591595345565317109808360990362"; + "7604195354962581173699215459157831606985245892932148667568863588427368471328"; + "37402797671729867091958880703368044330554219817351439709435695854279377052968"; + "15021754554199031983119820117039379649754158617595693761803226478334678245252"; + "47490255684408806072434251664743508051420570808132025501451725974827121258687"; + "17058297088100779754668670576690752359201713072728307725116578742664258035812"; + "33177512279709821535209584501483624708734718786595445144375381063910225855217"; + "22722275695407528091691304246968383686239176745361072723538077075588718852746"; + "22523893181902428650174996691790130832371188536502447987063143120257450653772"; + "23308895356450165080771503655705485959702912748685275383709016805561195393730"; + "31027920485628166856312777655247597928527620141623480299311482321440235423250"; + "45061629190945989233993296798591248101958034421473451931174248051572365665596"; + "12635346734022971744529531315542317156695950592572588825637598149329121435602"; + "20943947811812318510797609944365001415379144029156369080552566308035645494236"; + "25272795848989661284291121337868232983504512905079898072787482710703777539907"; + "30267260031722018334657676019133705236740734579176664833600084021013496843546"; + "31517311768361733509846398942976030662400143969686723910638374750883139079149"; + "23179568872539103374642859400181289258494250830556186918556740813443091863672"; + "43764857307902449625975867969146072336127131357517214347103058354083616467535"; + "50986536293458449273154397197499183679036967678265692625380537258000063532144"; + "17739561056178158081098295809388500809247889131390006315905372775593328303174"; + "29288755790242817717621638923197240104295093218759888966129245521028472275230"; + "34134838804483412147238682009351758572433373367047849860439248437388218182820"; + "5678031864698043849290292270505282805363676850706953191264384683006133884965"; + "26520160397861331597785508913058535821999870140894147231231876363158277734288"; + "29240730915918164705120039064238164059586741149554989326639275573958724232530"; + "8343909311567226700622893556200749476532608824719086807691291972160111871498"; + "35422495044092101446713476071226458201086591087201551382952729636451893974060"; + "28788191175818003347220573268922959045830070401915571862444782695818400239985"; + "4964783835867249774083299211014420218490608209476492267659355881364453511847"; + "10216614694145379678113358015463688529998198929758355282726851046519070445194"; + "27803494825843439402691751649293753560989707643490491294838415993813244078970"; + "30748627242627915480476055895904136928510253392793276393732599431460830214019"; + "7751739221008798527034371607783061382972620557894156823243899329549833690423"; + "33136351771438729026535955096064818190694747127577887810498359791738478202735"; + "15487861031051273320246153480621276816764645205006338931216717383286810036662"; + "49842641210693624237669424014970933360600934128562418971602444161937944689815"; + "38080738277407466133634923380952979679353443729179754588489421357109266527740"; + "49835778803230991359657573667412732792328267908571176221265893225909110634684"; + "48979716276201786775168967369617265563190564537859459940775310207730069238772"; + "48115968293689106220270565101906186091927515718072586052159138752415504690487"; + "44974490348051781688152167728748294073951164996734932874793980137333724713822"; + "32723711714533643804223002624655983381445583052702071992248370814287912622753"; + "35770018441385880747665875909685263825335619219990900501758283083700215049177"; + "24462225877284730742182932602961025133445826599619125054636967365951416719552"; + "23783458847678429109975790282720688654564666590790639711956826681143293787773"; + "22347164999197115677368036880715580840867296071947684897983662897368903035923"; + "44436078084173495334203313236158995421334213775491689085750945085639709823274"; + "25531354606207591001503734717276709131788523985002917593279732600020946775257"; + "25684785975858758309831379800021705800796165309307017255796818608524248856681"; + "15689846944752800355408013445547581183295267110737304356038985876510433629593"; + "2954755130869062203053930362449428183522050551079825685966392986029023636700"; + "27701477658173432393740883974255870340912747006748435341251832401519511471276"; + "49144605237971303130051477474500252441736011779691510816968732821261269570968"; + "41339385840143300905581133617960524027180235012107468786212952859173390468514"; + "39648185702412479261241716678418509894559280563465255646156879733379530382617"; + "2941231259680949143593699011623744100174752512729757643099482873601163245575"; + "42912407210638823710182011018928480520340098630346497369618624020054117846676"; + "48149959907456562949390018405936990163864807774773031806196322989123705667163"; + "22688265260172456453339993837459152038039626634400711129266583542220009592074"; + "12000693219442732741816223290743392039668089531561600727937394342995414579134"; + "11903596729989502145549179132986907891593077014729378748826473464861625192683"; + "2687111115125246444031317339291347908971840740015813305558838776418739833086"; + "23449522976975553535812413915796651435793968713230742677655098865139106223667"; + "9127447737910095400860412314688824392136048676974256371522014899566329800277"; + "18470081002802756098187392375443129770425055057517598292932337151147562979415"; + "44570736387423385650881595596783530585778739624944938740374839306088992916739"; + "41506121518765476611532159577026640847942725069679660287546611181740321613803"; + "17879365806603642296154180079678225700598122219887762781358998608195664544974"; + "5797039731182029290044110349162251456412636832186827899836873551225117057673"; + "16295660997252122627187664110946939903408094437070458659338126254215674463605"; + "34524081549397177387160463682322947783604339299199714872938486944639466740633"; + "46792070054974847313209541773010710216925758583669099409416452772447490195997"; + "26758138270863118025378847876443541196713233312489031593470542282276213542370"; + "25932795773661200059482623714428701540382804071390881515116858419823633841821"; + "13321689192715674395770738630438750136066468135694575335309580617698058033117"; + "9707380803157554078082855616156559824492425930465667797574921265494807066314"; + "7456158743057656267196226193273529706797096313758394320439183942428804984716"; + "45355642533698338070691932069661520741557819242118354206922415757362929214681"; + "11678259483364614216163185940141297609599778858679439537001487250711661685168"; + "3518832067902435230725709346836794333454945124555395496274090845504580131455"; + "32945555853640395249820450907965284295734348780933164440399544563294403789630"; + "39144256186074248653430012132977997931891740120897263028206417805470480396128"; + "513475060263080708913788928053965257750752082706905923893128454713255069681"; + "3683049475437575758554728873338252672236374719853531546923396056498941488282"; + "40512995296870597270088595777901813960760477076488920843379483396300135285919"; + "27566780071222822332525446641593709138022329153495927653774019832657393592701"; + "14553386429473594909470688556596424443792788721346677010176123183887024496060"; + "27859920549341120221544363269894592509610202544403757207234685024595167318501"; + "43630799630596017253244467929174687910181739803861346262759350693495295759987"; + "10566905550291524816328331044922050443675986854353663452037665157735899469921"; + "41883294330455662982758134167170988606274464177099964393473215947428373454548"; + "49807615802944289048873232050825447587887207808798093013193396431089336030610"; + "10322165791099655621755425357073963493688332466706230721287522258992803490137"; + "30646173733388488363150064701278686720564910831836411411651976803737973266145"; + "9402643818207936923863049876511905578631103389374441210902427576559340397042"; + "26796903570709220124665459153306887688701095587820014535393806663646332690802"; + "46485326810825309550921448694342993906840425779587939587426865276020325464945"; + "24356907333535237405651241236585413997915979417848569943590616378149521017774"; + "23511169606994309941348827806149481805650274994320980240977267213388100293357"; + "15731023427833496072707128064453862171578629248859961123054184724775612220021"; + "15476157034920561920585064222922712755398556043478554933175489223519135633295"; + "2588249154193062661573385899432005495347251302263070328643388740869671399217"; + "6009738957936176982507178002696621297792591037813275212151400246297074354799"; + "19233332597631491707508807992208382330520636330001528420218682645685589256221"; + "52257447718383093991766497150127369332489778818971489581567733290721167946805"; + "49137177389699894517809095595548850494591743777874595835879738514452528623678"; + "46568408911734306168397184498986706003337923310668800879260860154439924802578"; + "47934768334329838261157101167633276452145498250520979978623243405647174036268"; + "50548985142375412913344898480017599364756597551569943313108030702053373292351"; + "47313547501137846688862600708885501470839439049482542252265318066588835595877"; + "44379141510324834123427106121179013384083052933887649345549024509665387337907"; + "12745350498713174792397397689765109018413448791457948167478567090039244524261"; + "26500864710621301469407121438090857294270092269498670394353899106577395878729"; + "11347414485694636965135491107674675767460314869225865451044094742585314486685"; + "30546797282015374456420465905729920533639220341847643819193401157056239855445"; + "9764420137258539782443919930298504966223551788317773035826893207520127548815"; + "22299459460462072891198481974919074362126418543881491087838369912934426392572"; + "16855285284125844489209514080904609067369163236122279642071700082910563677928"; + "28470684714066956536547171205246920705847552363405765916824456152219308886458"; + "4732461843529436130239807886795100206469260396399272943452254374852516911378"; + "34562136348353570109700872901928872554702381799420513020116701553340267771150"; + "32365558558736606695100598286177066733690579155204608260555923597643725911454"; + "39093274064908662087943844021095101112203783571135735803933668222858746865243"; + "43197629030144295844773883705380449163834899349448680049499938815732794818313"; + "28135261046436067943449704769784602664670169528558709941327602925531279330283"; + "1506102606338525938978917833686468888009362316628110197189912144850886803765"; + "42336701278628501135217154714167575672783514963702875925876272615990289229528"; + "25024620564425776027644674844378116603084237932862382763192286329954441925762"; + "17870721740021152115020062852028651603316820821405634598215292938053122266052"; + "8726154223262675362011088994808023052872330129832279854214301067840970209836"; + "14874402962592699078349928625650239666631999908036706122344921639840279200415"; + "39756319747099752854658342549564553329846048617905492959798860958027344323191"; + "16691128005183566214615852202071092535806876544863611664073120718156966518635"; + "3656641624593787470623179851898501381429958149290052751094306413295906197198"; + "23058535769798180750363501250801625076459404778101435404523789853891253539536"; + "33558816550895409218380886501604904940103012687961987303678839499951905999903"; + "3535320991257296205944099868175259133046387724680729551263894422361251248758"; + "7317061444673855310460676987104314467363507031733135923911471906709732796227"; + "11500894792409448904640700230690380435021471256333652274764744790985040833762"; + "29946587402762992979637543680372942972051576109298571343103906148223476379391"; + "4083115199018558811067305667801506297182902358286795914571961100973484984414"; + "21780845559336370060316195032869693907916051322860704165373540781960864925849"; + "50108406296877211542712950356627343571290344962477533388788483384843943241826"; + "3604194748440975970709176256380189264567204604496059337216505471586505569550"; + "25367520387024971306924473288179691904393907838798350326959612955828936977623"; + "20832698602125152248033711132843527797288526400731772664791124082045251454142"; + "42631062868366746704081529205540353901856777480389910573915817519106326556653"; + "34498285379235908749982034362054765010463122336180289849202738319552611997489"; + "42569303254780782209383769555863500331363619065952722987173481354130829961783"; + "2968398972388390861514824927379622551058313567208592925335792817590639277711"; + "26932822849411517822460887083515713714294971165226156231324226720523884126957"; + "12289852530007884112177675781197310398488340001613130934099944458324157517609"; + "32571394385633728540470223537905763247514888927223219047927568504736330049592"; + "49323371198951330358894217978741100439230061670861277900398849522199063498403"; + "20916227317093555798135256109920923636673315915840710498394615832626002268064"; + "50437846180582211045193594549699682565194393344569259404783034512017335183667"; + "12720868063213131315535911341883761360678170824615477340625750278643114107287"; + "37197243361742872107474934672270277255457140880848614348969979603547286846838"; + "49972563335848604083615943319581538413921258859517393388640982639930301010342"; + "24578514759429435534489548439103508142292694204518742527201734880498761607088"; + "13544000375663478018521907983648192775225634805964564209488796232080592901057"; + "30244906257123439752743184026932532959005248829599515228075497819748836533053"; + "17158480056121611203761622020240364912867157439578870271481544859959963992982"; + "43213708539956730045950791581115215808814156477860100393372067402068523043784"; + "48148048525328038354477853614732455140796148613572766084643376345096272862233"; + "23955550900926153176119256387738001205670821929278609825909043128410785370923"; + "32084112248131778873683184950328740630941915092866433791792196623349700717247"; + "25228735758855933155378400293367847597725487322422339171350380923514466214585"; + "38708924229373547897104118288852039016237551318118836657141457341427167364654"; + "25573420543845971899026547821922148843484281700825584055000279017238479818969"; + "24727047789721276146751871546128337281102901395874275592320129585145360286605"; + "16376363547325397340914349214206199307694252744603372010394026437013197100776"; + "20208836376333578926014682699975542524501761930394685283441636991924627929267"; + "35206301732048412276841356453505638516993236521927454740085319844070799435331"; + "41261166618096608240361379074330395434896879239200007895635788430952244472582"; + "41432219394078727593377645450491483074448807484512488014556070054882946094209"; + "20834236252121597410527416638607520798042160344062107596356735831487842114761"; + "23532139063413819501017120637575271821539320929878848328154727861013760586039"; + "3946253966634265225936238815600554190068564160724890879995534127285456411579"; + "22846690625697257310904779889019761152674142140749605466121380947233821897617"; + "22087213788241393345997830798811611648992098114012713841486529785834041554496"; + "43158723807235728204358654052498829642083060365187988897913589551158805148577"; + "15465863697980742098871467263990006125886103501516872842535870075250801222781"; + "5680194980291197839690960478626830816555317427024014693910787627450289237742"; + "9094058180026172545686171028787053405103676091999366345519984327286409630688"; + "2332670368762680570021571783692863301454064644206808151563000113996159738789"; + "41147800869911993983577010981800974642409890520338080941707731579519543968663"; + "13279894307388819655466420434801883531790954002783939588058497750423667181893"; + "4870460897717989146446912775477927413376391253591063401746677243573570104602"; + "21434150992290282229101961254012913715487714753851223580286820712178569140123"; + "5884699423472479901902447150142507004213890029567299438503194948937225087869"; + "10751322070759878166895822040094727160998828737858183859125132419531492304288"; + "38992650885322951602413869202579221872340599306440561607592984827348058953230"; + "29170379394369260301915803080156002423232616339189492529725305493825816836491"; + "28207328749747479105410685727161242130439891647417887391083580573114642433586"; + "30853455820741483128256761592665063199571831731867607712950643840486915981512"; + "19674757655311695412098014331868801137574968530161273910500977119681828944720"; + "39760311849140484104401541894168574438723197691222319633908463502228900435385"; + "32907700014271836452044581308399924687442165571312547230568158377188973441089"; + "21419616329214777079035587170514020306037526204702975777693989034339440177318"; + "26618360897653828866229525715043321785206978439662756876063444705770873337597"; + "36839328402947719672481705066838749753765029179922670705966460218560367824702"; + "33819865214094561436972297577491830411674255022072017707118420428518277463984"; + "52239226873754505993400788229529834860768913846928108083029668222253331104089"; + "33663514509883297348657719612646437260376060472686074175777529465535219635914"; + "41003879710590127522478830906318116993393243242504050949617603963042321060476"; + "7812617450066867719201142889276223443655576184992693957516680471935511930279"; + "51121304503531803641767527835120763884818550079574319802192969900240584243331"; + "1274612101252555263549693940665575968018149479789118602662813998362863815476"; + "28111554183672061495966203485846707355259261091518108181556420685499275202196"; + "42136394643178945109983278623800719553667430014244921031314292928454177600075"; + "29400787731444232592537985972506449856480774156983480052734223261628825541468"; + "51495741815899207992089872049098533532158347593725999004967104881825150810836"; + "39333115389438061754746792518056897857082090561687954807372914815130461016655"; + "14294336768755739754763672664822083245398240681090554840744022889714341896060"; + "47674122242123052198728676357951860449892667730335860967923060333702419341834"; + "35684666049106444634028920061342458983421529108234610860428488342278162340897"; + "9217271467341686730075876652325145965408071349745719665965491968116132171401"; + "49102996771041826251600275636051473450230724151940234292281582608241970286503"; + "34854604674557982238222418551502188390821202909341038834798601283398583979700"; + "44103714803951799081408903773636811469217830709674983501189338090554583969027"; + "35216265618185969272100001311669741239205828963710925045672291350518816047261"; + "38403524999556193056272637467205416979772986748102914574085083812998622738913"; + "27146144115803706054383284709975278288993223860198708633471683084389321626754"; + "13717875182956004040277399923680066755828211406717894371621241252873305128902"; + "43893363745908782939920493548985641014151424637808957048781989937501374580035"; + "11726253545109081409164353376819469125399426277505280541880391837677360874072"; + "38928083350744149770676864428063336223211502898736165860838144487338522811447"; + "14125823190822219756837975179681223974137829967998184374453263586157382305654"; + "38513876015199093611082189496524624266110546915344263711135739803957351751310"; + "47685229118417094929745561957819690007671043576786068405288351527235450947053"; + "6959539796323704070461146242134806197237474129123359577767978063953427949977"; + "47545452988897685363050245883092979778729706327058096488694175926251841756750"; + "50819854690063046353662942259579520840136358471545216283227859112171763003225"; + "15309201933918541480912493953275686961353315663926344924717901793290472429632"; + "25814701665737234866376372053628534273087781843875343981916301130840793116256"; + "1916844826075222519090392623030931550354624290318063661929274409207762237329"; + "1046514656280512977708818059092759387987165875435181225389723691639677269582"; + "48632931314601925346131427356122727760212316227166299632747707086089052363684"; + "6605181920334239323337807639920607887166441510148481166461711505022421245712"; + "24648729211610178594528829323421440848291736568213484173668007946234312273906"; + "46859494710268538864658299697721145997690895979735714480735923808224531095520"; + "41175929282429829777281847415308245248403968515148043916452754293744702303400"; + "4936300094396586135539485728167289346454991472436633497057899786781957023646"; + "26497056294320821551797856452767310941293845697666592809944450466405074510159"; + "30179755929855617808122588385117490529340524783380573627382420814158046220265"; + "51404155368749455548900426038075050336878399275390882961314989220012144625413"; + "14816852270047203104312028732909159967998906770274196690632931234420725527426"; + "9617752168355609648284058626664682170830718885414476704978109198619947225853"; + "7427964446763934879077123333856010036056226354148572747809815822346855367365"; + "29674872948739147286091273509870908664455349901359630308300510194622261921733"; + "43495676299055671139434544393413803052382814125675363612358978059313789429586"; + "13094408335698611712427781744265395983524687621162836316320830449519959763188"; + "38569497775632608093794125886753456740306226239072882532108501824492224325593"; + "40308698798346304095630271480781739014165493986458798701620020450887376406428"; + "21695323206500389583562384680685981414856167910480068112985112222651637002862"; + "28462792058602339889033620039075559101583339912637364038250676107653835038248"; + "46541024611362968529348952496518032317778604675804472582130971946588321773057"; + "51356043325501315362210916662661650495252901592454120098836536302110199287188"; + "50506579084327411763038002678064865811256717858083039734318534808177330899455"; + "43768274514650675477817361475016698140148452675749491793321899996800017542942"; + "4365130454011506171008828920058285825290911024175299642700028827967669304334"; + "41317071247365873784712926167181757675491093869449596462352859768807347211544"; + "2666773836237810619617948712753874439458872566874729089643359958440020536859"; + "11268787534831056816083083174895755956352873998182091668492218789389708906242"; + "40695329903519172458025898268523734890965958519055359802905784576698941321234"; + "41627365240233602645027028937623461357745612228956394512781214869371540472342"; + "4164478539096095999131892571705567059771712234999653371776917360777549612104"; + "51248727099288674225044422898397396359619826428997072695850613136023953439945"; + "48153799345590764241473716564225186646412111682334808658902588825212784855559"; + "4038288326645960636183384957834655531514058972517268839850385229326514434196"; + "9349746370858115821223769976893823674367044998087780251985518797575566269054"; + "26635144643229156230109683885266832396020379662024410046384058858172974749048"; + "43223596713057491838453489984430963701106626227127004266936175851674881127669"; + "34365304033357616463976462028585280284797223483341370850659338406635297935595"; + "2134516731680789816358678416060804041161035786347309768102559295564927033298"; + "45222140147028755238863517248876975843048731238253735396150896367564901004686"; + "498606925255879431664844628549393158879953298471933183455573478512612767210"; + "31655578397479065559694701010163356160453434259437394629612488741366238826723"; + "44556920347721604505312194713898769297829148630669474738183867182834534512253"; + "41066252220898939528372277962872199592413634363843816853371068676896371450235"; + "17898654860211486557422421879369818443339885864697693239455405713385693412604"; + "32513783099500141673439294633034010193535529791111957913458937240956644750422"; + "39905409111076411206565494347110894882613346677151423254819846790782130025281"; + "34988407687074005102516587752744593627068947572334289485494224614781612900746"; + "49737579529532507611760379505316974983940800332946027442906862839608822441536"; + "40162178377217761341550347366456178201094415946625032846674573547145969502567"; + "19353664035666185668244147626872757644951716514199713218834744622396379021728"; + "47102456478332690688659328489760691845709562508921577866325372829999411432449"; + "12207115819013703533090639097195525814981520405803331543503208389206865838351"; + "49994145749153772801588770229283450802831018859577109122749028671638201340175"; + "11750496117230153414206471040577887902252831603305505401836225613139968743361"; + "39247158472854700135101098114122648755375036565112534510407184246554146458821"; + "34888420087558994696576075863747777609045400754497672888032242287719438881063"; + "36746602810649853608305671227827297524785410557002588877308144918466075161379"; + "35110190469581159095125917772271263108711630576551389559652466237914252519706"; + "17666646113580405089387681323991445813223732839702375394019098767167481113374"; + "49832915191890911296130390700527381380353409264287349518316829690779511940285"; + "24443498466703215427536198609292882343492137081224136946780263563592401049860"; + "9354050407159006695831135953483212990074661420262042032504530886059244184549"; + "43333009983788285821400695240087914486289602002713044560524409547002696507943"; + "18752273838312523782927643189706439976957320321860728910806488085573896888517"; + "17277900024182511146710507398920674498144288099203282562831710644330579267863"; + "37307678413917534108508235735432663978301009388979394911932194936937228116983"; + "28849789673530572936431250397502939284314408030083300337114716226795362105688"; + "50912816147821018549769876876636191732251692688907664846983470977761901142017"; + "30131058343978916976539560634538314390572592064574889352048802922118040591878"; + "3706738172138818078705220133282568519342502151909947908081476774050163705447"; + "45699814681518246744400453094285582701849408763005827286692443508836010669243"; + "18846003060227712054607266173221112847285282616057372060555371817788046689458"; + "22066640520973054711560800705115163615789502002092761843459719025242646197522"; + "23829247396636262290884964425831569678858143545005515755792807616917823372004"; + "48198239185624674941704629705912623499339853704797750011743362965545369705797"; + "14437343003724224631871818628799571960312140411440628694004790267232875166985"; + "9205739813512268504763814673014453677276549572272076135414717042201476484408"; + "39791411423593512268799994379557077985176861512059575297944927863183698039381"; + "35926621231744856494112841579711773281980064124370668225976659404439672270700"; + "44486629680241930770190601741590174294937444204078046665996776098470715578917"; + "12162293378945031764624085071759188374782023105344514611109545726564556675201"; + "36307225704631546442623734392611975648010152587096752396997755313409683740066"; + "41250750058001775370365399976123622596191578857360075239352807587783963966911"; + "27326083632152278734711454453088575834660104218399840842350769848804017390818"; + "21738472712881664490908162471080764510324227185426320378156680732466086006946"; + "48253221985307003164932400584047916688911336639213284074501437919167577474120"; + "31747278632217258576675538435288102373171173881876663185343643389289388474560"; + "5761801194886985126517131550892405530757591539197426021056539623860947947777"; + "25080051431129686333412677366349247249765542691781361133023295276989895785662"; + "44725507017222585824480973320142248615864064267075237276314928012346637335685"; + "2270142730849677751753329523089749032641108434062308390614061733510185159182"; + "29151537587921846263406040946950786214733637455178025270138954283829217507166"; + "51701993706600967882137291998419813154460359807514636008564722369823738880081"; + "27396983310969582762655735423233600814011645446508465877860524193464148646437"; + "47027464785635786821973369345787882857794216687685310972827981582102274085589"; + "8537697526465704802497642132002864572208835642458535053052653228499861354076"; + "33216310879070852920780500139920461536347985311343304758357092362169634432945"; + "39742197294627214520191321293386324944093718559889580220315772412754596333618"; + "33896963789316206258615821504316306436964228772759528417727957697783861669643"; + "25010660153820592469701812125053548417837781371102734874578902256052345209508"; + "36367261405021942429836445456841404357897358255476611125054531559819745708605"; + "52426140434579970656719582674709112782140126494023197627160774284296958026640"; + "17974065625542652257057290211548736634195575643976320857820652175876530118764"; + "37053031019194686166066970377043979546613341770302232565495885535831842113241"; + "13811446176969112541505871240921570152518757388141946244776461129201049000050"; + "15092093442185484653246077567190483143911375332335503262901381196989675075655"; + "30290712242976568484406185485374545475757630659561739950369976270424078249156"; + "42300599090797035681205333143172106725230562804023721865246977451648659325451"; + "23034899362471909543298700478448553281114092027702550350324373720046757230720"; + "48731736718724459302206059867835027581192820404271125436441919516120222347777"; + "38210977651743308949567656032696478385819661205063514163655683061120398680442"; + "31066571830413162458652431971739961248158700618823531207554971312281336740306"; + "38604214043841500037487247628107100072934980241996056096027128810264297729133"; + "42466391101465852203816440495696613849995732468216567393767726715283921987679"; + "7918626562942975338180644093933988817993856782142079793192213031203713419564"; + "49684155517934574637878829138073579948423899014921699823733824485886261361800"; + "1451275366564565438656353212713435069619539370740288657639758022186872783344"; + "4060684572698408855577084852784974870722088774822168823176048676904575595914"; + "2266042413117404820068618979432448191143223638313669085447265538970047743222"; + "30905627074463551844852560969973865864965309523440254426402110555428247986128"; + "44158908912184255345458082216141321324031565774822466208284543424748103990868"; + "46781765007298128451676105938324040827134620337685516847682075321984346802681"; + "14555474190305191329651931092157102989148485771814319545054338444403258212594"; + "16881117240817753666225190901719116414117517568051590769838881684777210471563"; + "2091384128545629176488696135490230680171339008214937873929334100299232999763"; + "42961581958424980887960069029855144961942029721580484171693959065822644239271"; + "37293380196472166233044745617934489446223933790110588175152241706018245409475"; + "50472789792567303044557428917354654330233740880518444155725173737527015380692"; + "26254591932763759021184569941619883521949754828362687682030335425079808014229"; + "17113230459817249275857268126349806861319046074842290127707156305676386386894"; + "24231753369429127358009700702110183480199277263167907099485750041582214965155"; + "32263789144438090923613388538761009896632203008432412115908330894004664953052"; + "12618230980377962991318338064162350506512133151309212471355044610992713035428"; + "44287411811548063431416128186222883697784161373833563087100707769861270222355"; + "12243970408204409993839495395374510961024300896394362315078558518998085218595"; + "44173339028947996046249077532478888110286784422982124321103998220058630129185"; + "4598274292520003424438601799771684670337297603988895001679632082627567473920"; + "32220511643743595369808381786406376653262724588548158227055695474753444711477"; + "35927311526370278156701529193976259428647110571727767928074012487713280141168"; + "33414541138436871747848548210767170259303594301338319380897399124147207142256"; + "10985815035297592042713783076262430811622978337187158511590030541267680813140"; + "47191419930669230163741552576498932288846324126311314824353674932127709343958"; + "22784828163631611768238083672698851077894334504107657128357294425726824989181"; + "49949907206009595584434917818119046546975686520915136028196584050967515480584"; + "26410109194133218506580932937648982507548919566531870050806115243653049366263"; + "49713902702044838319213158273679308025133803584815262572193546155507722324872"; + "23535559504337049461830629174751216364093038300260308135874588247062574403616"; + "2238775094716444052477495313057898840054408997234199224243609623847342839111"; + "24251437981344168177052800972995593868567104302081741438918736451368941030394"; + "27982993433491253628745454998904820434128996322734239523565021212024510217448"; + "50295838517535590686256014994179135654184756295823594187599260917362939655408"; + "20057613369317870978599836560225006632816653691101308330458367154191918881132"; + "39394614248557203761718739642839828701390805742892989071457854079306409260621"; + "47798093889297880302781161190820961988270610469163421109136182280644356165044"; + "44393568357054115404229042885561023580153267137301539458060374049988839557996"; + "33693283919970625185262931602508844386692612080074318597070832534138700238378"; + "39815716493396968613970558873707844074909540436043586091356171795994263694381"; + "46853573174002303039170539308214250609519855889637324611927935851194802547886"; + "40815147595190732687521587437353012947450179162389073327247952677750833108813"; + "26339521409702735393744068131812259633542864885333572967691724944624282632629"; + "29354121099706613567496209577487729580389509912153101367352651455990974641897"; + "13956682594977060215824578428178631751673652949659210522408548576867791213468"; + "21710651844333023404269198169431081997914625130038397009887765719584062563582"; + "34776931503807259527470945396912938849688359577250098809620069934536239444952"; + "30888022057753192523461569966379378071529579974487499148314453535224010075827"; + "50706911026467569615838130915836644196872403584282694942070640728917921207853"; + "46864858442437162961458912480193558760809343578316469752769914636209220922273"; + "13257506406075894433104506959381001454814282265917832054419709339905914092656"; + "748651022964498225720140702853094466861887182520450179370194887763003477434"; + "9928055927827498106046655953164657438589198384956991765511981535095278477147"; + "17282353886786306350464074480326051762770764361308450866796096466478345879680"; + "1031912496796069267128921308084345914023374178989340573752894044339622888592"; + "25926134979442574649058093555286719859705643564478648509775995356905528815887"; + "15964568489522278652756557360367403556214280414131594187699659173938365588488"; + "38050091280410708232976422594473351403153808832581737053257668228216639900422"; + "12030737699352751292766799393553393267232605717122753898023894800120436351283"; + "28481686315014470274923914799086898836504959567797773710778502159442143532873"; + "34854855773809028752393995264841215192998714650018251274814328745684277843700"; + "23177024339262302793601070921104366455941060951873187433549022636746564985947"; + "32706651237059443616796121926868583069846707958453355769010508784973815882902"; + "46999132467290246174738142479599222392723632370675458675293558263299577721042"; + "51658189751923308132217973966348349720258327530023246552822556444736712390623"; + "6849360125712696557397143449526597653234220520772426233279930720210309738320"; + "37750806736224959930132995620486959583722999721579507748526178865808200136556"; + "20596145017860309309979234965966368019102563566006691095290434157503935075151"; + "41254341165403645465348838011157544897177244154415343520886560798681195976471"; + "39958936321623717554709758924074568269853737880198337327309503417601943446557"; + "19195223398318500029787325435183109593313197618937185661501802900443846527922"; + "10629204629388999052909123660165259102503430047516526387386913093894818621559"; + "22392494050571001911742800275551946666157619565710102369399744439030672915709"; + "45789181983557040436379972210390979168574359994520320974901389101449898971667"; + "31993107635680932518045016097850934312675277860051930648249938294616399737203"; + "41394691516688662849678605584944839500777787870042035604148788674531052718761"; + "4260057227269055804184487378356538538091829237564811490140159259203053493365"; + "22755914276797984949384994213736139778684895539493230631683465009788203482529"; + "40041235704216186530314362855470728008875244931687384625262157538702289816794"; + "6239837510956467015853754603670020841591725704614056805052967999814231026644"; + "29458802836337316653464358527714116167816937061907636047906242601994052671860"; + "10495803222616830164930921154664460461646398358336997556169589368662143070925"; + "22898549214190047583215260016577644830295617833670028301698818524286997579532"; + "24393132143758164018011524734233512995814989110864264594937375305003558662082"; + "35599669100699975483818766527498585288817388816371602239888485323895149359158"; + "38006814568801552692257172170653057840209105926496657875471253681231978835474"; + "37543934971882261953367219974994268988229276972094897853703891601912512732069"; + "15638582370101925565491212811912002274875207706665814348068235624071156999370"; + "31580840665375344887237728746628275665874622958061630557939670052080082572146"; + "12367368728174853025325572761705668347969447581862767534739917589252910852407"; + "6431300041535226336752933722639922185807048849346218384550177388163783622203"; + "25253158156291597068997002534648267078756725939239005896820619368973386400618"; + "32407272173038095334116664653948892086910040424886147129262625126739839822771"; + "13280522211524717536348472783270194511863920959394096229476951226643221055230"; + "16772104472116956787783912564859125725251207740620474891039818280005602295238"; + "9380491773071000549418384879702223304167388163133689178789924347338789859850"; + "6740138750908982892458436295989575152579732709412893038486800886922449522370"; + "48314810935891480393270246846320465418304988645667044400639849377044382785493"; + "49525268202538850726708934355964079225214093569356591960731024652251573337974"; + "10491451908415598562758512398208310743863775903122876297029651957513361141458"; + "19406081409800592976259677521739333450025655891055151006357086244687039619147"; + "13796012858975195466491814297891072959260328291852781745607018638427554265885"; + "6485115628027826708347895792986221021092093804047270852634430130894243301376"; + "7032119811712255634773442378987402663863092963351749353790436863005730387277"; + "49570765767525444909530922468492577696342166915419424004169639950326136617057"; + "1285129643807481578340292178367830355589280266621317949423705788259432932006"; + "3441634142357505544306799203411944242234343920049337423233909232710820734846"; + "46025794658354018692379411175175073186560341494151624685587728046975000562010"; + "12106158677633440534700667787331666286230014762373964286877200484724425265456"; + "23852090676446145451864225599736384585160730887606821819365287956188313561217"; + "4645666973599908624611019322719702479503064932117311025810250241310882715612"; + "27973788552235695206305543261730414876912259984347644517174031345462270738555"; + "43025700336074147238459595423479529842575492457031762291142760348199150113491"; + "11114947607987207788072907159327922005689782074310097245997186074333396056216"; + "49687044256007315302113254820386474091495296180003075377414100433265777233121"; + "10121176151471384524101283711923697637725868232114641816445390512389391879025"; + "51330986445125278830864400207324675203699148153035087480401908084977553474061"; + "47310595279963533769585290517718071207229353045922336729470385238771992063949"; + "45470655810089077363013869164914020509319391456872208545345084082605634862224"; + "40929877503242649981348819772838274267223608227057310481110253536393018059255"; + "17372055570115191467281872597379815744802692968021921450248895690511846645695"; + "47678362609779802562177762420543329986622289631981586798104589503720694371775"; + "26411767877298533345027866329803788909747237313956364077530765489692282596278"; + "24229533690702187779130733022119521753205414714542053126286077188979825374531"; + "18497840321762427856624303545987123524462980182393573916022980133186401139409"; + "926339800459865307621110262317592729066835255833528961455819197753330330312"; + "26987605273411980269258666993213102373601884668454325175338172997856347972333"; + "18391274780315164583236795984691281435086666456604388825240216970397471681364"; + "12097832322841410456967729421116714442525972726222297222010623646121128815790"; + "49675177072983404142217920899359528991366227410655512062504000260893530407911"; + "15707135722931316515055649351245978339654864807851241599499601638769193005324"; + "13383342070542016733720366624023776259361772045149591256080689729754658059980"; + "50987374166360059560703430211826736262378937327825787684985599281463601570367"; + "37692333855557499699736644309219454870696030700215486572270708025082781551549"; + "48478650594548719294793600227459643485482841832424895683273572346673969340753"; + "34197000768287613413510926912918063900967585863143579777915396555872696168197"; + "42341791561950739851197883113950655969381083158985137996020454938455824791661"; + "50432013007639406618408631759754993701106347480289482412566889289659098747090"; + "33561349681426358960433818341708626828528089088226844117603110599540730269202"; + "50705077822458966913066394832821751993904360422435901531249988211620289538605"; + "45812150193659057136265559669604043591894801656607121583303377953470442982671"; + "44899405678979175008096051077001310599468936311348170044304489130853662237683"; + "7059127019337779356629411915385107326268136949565987358909106161315155646816"; + "34328690381291138075517043550284055917545629141111757511239996475405290993321"; + "26939654315244001880568035987806732594072719629182278790540271608004202736265"; + "30814725983945874115800588983627465902316483105630339244815320449875682709724"; + "8398481858488384468602034607148505717684965642826928411240604873022038757210"; + "32368995614504469151394179394757902584570432859893345667551706377300971640771"; + "41155627378215384456908425831665893311330630453454498015644998744726313357371"; + "2153340160120049982298930685564703679245036425190525326118018096283043155652"; + "30352448634031048114241985941470924393535967542582997762031027911599426568195"; + "15261716957885212013251887338156359768948744882202708080437574444095163828003"; + "38989413931358185435843776850185009130324946962753359173722889885807098911567"; + "1704331953122835388982301028858718889034690658545952309945645484614333632807"; + "27403750471903172003031534481941256144265878552723731083968505201259043778402"; + "17562955366799954474182871335569462132288297189443997453618631664362553626261"; + "19086162457604934210305997669117786907689549640695600906760353084525692086019"; + "909236720157425570791649582895043242306821976668909162225950852357093705234"; + "2587678208364293762041139325677564169740285152881638284308667606120057681746"; + "35455340013646018884370176867194236432498101681197729616134222175532845188407"; + "10597974015947868971053495476281648442554475914904865903565006092661125167077"; + "3237760185979457517707698614567204490221992393739789914647016856511321085131"; + "36946097031106423588593893994546210486025823406712493196127193878277998127793"; + "1562072353855994226121886801808336494359509412675230144523806046877228821245"; + "19010448428150791333165899594482872847843192038124839342939985299225110393618"; + "21579288013136572427312994291446922214090964937547933878834394360351661124147"; + "27476725675454012862496969681583556164753553840148186542141037944739225011404"; + "12721482754555216902365268649699780762391451537917039204354173116225938906231"; + "17726161376964586155439029895353641881124547308134311074590598308682629739586"; + "21277449426226092595780141778474905944490289128777491654503164263224221094647"; + "8027270477264632862462234106666097274072824365485884960263030432202348123210"; + "41704607970414222533592973837383672465179394179105424582475027116253727832320"; + "24911397878677534717817496400765259525912587429394942164360589864420581372895"; + "28487683264297785882293411974724574939733908335995066450236207591718649511876"; + "9410945672219127372505114826532796375498170564414051544192375021034240158151"; + "41501277216118808186585885765499182580814856188527129455247808366786573543421"; + "10786842188586265560953543650077602380076591787820349469333358966937440803493"; + "27009619599448135465453464435058428424786314448509662877166278927396974389912"; + "24408090401747031528777292030856366914050775066115322946199273876732066533603"; + "27717428010589203122459895369508850795775086801529508808907903171549714517552"; + "43961339117528688303727933814338246842560025117902212123957164184934798616272"; + "23539099267901977681530985543753979115801969780392578671053292012737090359960"; + "29129130787064690115403858309463936784595038310196943453528132510780666740275"; + "11544217335881527838309935861738104229903387666758470620902798348360616219319"; + "33462911116491023898914175915108269500003786821526355903193319352945031002857"; + "42971396791389197300566908724428992708740412328465643262012289069601063353167"; + "11114100576866102546082991452575837001302257906574345014759165856210897893390"; + "10869503142950375121273168986955759969708630281326506993743041491528703068926"; + "10056285389986129969950435124477608942343465496465667661560622683088232566646"; + "34352912333098020699609122066221942402647202729511926372551684177727356125767"; + "48815653149287031584900334425973245208502245603175731919813468058312231051539"; + "27279886970331272055453009825591093815823325722521311734285899406328214417219"; + "30743518328862506788849929078973418258912120322041236148115187319465176865909"; + "23836593777410321994736212695067663874445976812493472680359497431194677069707"; + "14271245249714372701863366640280358937336173352148459212765723706902523416666"; + "44751389477552162369260519320913279071846090137697398153616721749914975209463"; + "50049310530591903842202745108285775951310636397993830164309261859077944727008"; + "31203592346501430398694586706221740358145194595166035656399113862917383342162"; + "37447642270457825605341454299863838011561200065009939824839354876147406554050"; + "10574164763913009315349684560659607328049286937437594137678635676492164664990"; + "38325320802240945919839117157786458966683186777304529608044491498455717130551"; + "40805013056129827384501225380368635414535634360289381317746546936202290112538"; + "48333388268805149543196989643320441803480506998791523089965182033002284368947"; + "5782032582803275485235374665654094879290446054520008831705805183845211898185"; + "39802516355118908351021607643423040697458583372235828229304343199015399090975"; + "30492929460132725992608458300060364368351457395826268799884859998700261205304"; + "1420460004901060161999428487693270028427827250557258348019289211566581365454"; + "44193635056304562477505124994430538128890073548458826363763791536481254794966"; + "50720689419341593983069569011764146978553260482771698590157644701830829402947"; + "8073796990034033964469665366473997793181957677797087439421280810770488925256"; + "11918471565012754466601744707948105395283969402172028499903545447868170529713"; + "20077023346487118481621638270056399928015669807959870935567399723256898313150"; + "17213961046117186209464109755931248173988132541497089384021158920901269721090"; + "40806924151578521440897441275485084726249888295413627153644179743836373627459"; + "48180670522504204627184158154001766027012194162495506518370446939968021666069"; + "42003056523512230201797933267792902549574504149012715622767056620086275745478"; + "45101413241990392158966509799943874633896537344671548489389563011092925383814"; + "50587462404507583069240045742171989746743467775065297737509970837012535861612"; + "47815286514663372521264717191280262614050727424357000042525142008994950651639"; + "17400463065364361454879212497416099212109445911086039739080338012549330324535"; + "18161390929522210528368217943618859674698687969813941340329551243423634163215"; + "14441574882494975584903294130579023104909680031021053889713767896122879098657"; + "21912867184623729582081200571230217079961934918095841057644441114392793081978"; + "45361556540636295590917957481529238741505687644950500354869312727558668766825"; + "49539592650928368969231099603636984862255298622407911855462789343614490745974"; + "33869060934120743008239749284289212363453006243904282220127716668152965210748"; + "25076370715589585424326332620725315977885925199077963714556765297037513234989"; + "8002444064393390123216308842243771494245898705227632990107898963043446382143"; + "1356017732914259689267113844885694824971954414004791084036465384478863651474"; + "18698831976592497490869840317995921745505006029532075513759064786215310313034"; + "48836462159247124316625665463190819813831892402600021151195654650125270340651"; + "44079217861342722911981257144373371771560838079739791623631524927582118528474"; + "7917860632115468421843323257057624091855319060906343969030682698738062187742"; + "15328920775298393985301712443835521222368870056830753657709551066102881234707"; + "40585149282725386186676237190866920474926692908526104716015727560418525066965"; + "22476618951264551734672333363230193505101669500810396582135708891630628995331"; + "22976271519589645590337728787979950618802152541630285510037871742827357400405"; + "26490418622799095788111021654113322288820745026736077183862125058416171724885"; + "38668434553373591212556681994380448212723195862087041826021901890569924770065"; + "15734290460192933229142204966761293110558662629712541767317274191859409979185"; + "50708043312916419002750805838232616804578377791118982931279441695110104859619"; + "25661993114668520552639676665126758448336667422881593126449325707247794604888"; + "27300404692554829310057036397197575379085146250686335589922839236734268293026"; + "16616950908374247513630471498870667771958507881588444010494951003904728142357"; + "780331858290974370698544345229396895975774808594696606255314479320722478183"; + "15356252408972709076003921799298413990129664042289284426790671672668901277378"; + "22195679839447440563352896996056925121555070971714547978827589453261615780585"; + "50055031037344446643661166893394701232488862253278315780297281928041839024491"; + "39853343710092418340651301215898149540667450843137399936276811087705281337915"; + "41234320088350200826168830307183441504603558317128457459369045773720261208509"; + "41026304730141400072631269150112787967137999190332230376064990660056537630883"; + "46270298741623878847116335581496501056187952274321389849457282429215904661001"; + "24229852243440737653059813128440054999089637857670449169075813133344895934250"; + "8424306277967302875586430461180994699747156058101091594395383080190147483624"; + "49672959835707465722916473003774662744770586652374151972176418791640619586394"; + "50953606432923765425047764715621990710996981237692942916850916691445210588986"; + "44233571495113761415664137120393901177879884654356773130439945796774579578083"; + "11574634161412767461102549430739220546934205978274834090884125505175189074069"; + "8645184998607708462451095150206729904754427459024724873922986748255464652029"; + "37128418642109534373362468648382548670038346064741412903988995594256056481978"; + "33355443735171069266537113956815564199390017657125748952951909212993930853609"; + "18346976095151853612362092673379644124598042905694460090917547301686808797968"; + "32646375704171180130330224041820560945074015817182291941815877259349052407072"; + "43225167886161343156931475989059671126108470737009680929793198947446394575937"; + "8816437937287404337360397847635602367292009763466086832728768883240427981891"; + "38366899091948084905344245020593946957409036781563456341174116328327175180679"; + "800298045483712205484307334575942288725541659796453174814416446066185314381"; + "14508830287813168002435636185480014871079716479693496544419639273961439244196"; + "19123558056196698077756824716735733526899307503111963110801154666985150036515"; + "16303389189674597252380274616649999385814924811197807163354356674102789306574"; + "7453668915100625394664770229394717267390236182731660405097681417166662567678"; + "38798071571359045878565848619638213488585154176099273867945877100609620185282"; + "36631959497302172344707808434460251250381882633514089681745071353294520523286"; + "3295651438846461067006904471387575625423106106098387875100629738076787368486"; + "7639968555171428539513522652621621046079902482011709740085444603640503656201"; + "29579395581332007484259733934571852879364872891046795155379474874395906573519"; + "26653656757216667921153411281655535324426792606630320014981412395252223538329"; + "33945142010095644499737879503783227769340995607126548035094938552106092827502"; + "35659738763390756446419442911986047138385980543377566364330341100094367895238"; + "5380796247086464908504473508326895383205443609034527483380059328805596144573"; + "45555109220928268984543580497682265831199280528890734732631782982445734750732"; + "20535285005178766298291665162439441374276729776225027287990176172368474655430"; + "42276900911794446922826515302740555211179964292337862181106694848183792840849"; + "52163438563491625237964145588646657521828399654529930322643039527692977471445"; + "12381085634185465518625170120342681595340115886064341209590250417404145330796"; + "41332854461896499143467401552257229221502912725720917689641824107995364172760"; + "48130816341111135562667996573877686235140742636682402903593978927062615809300"; + "40708352896435303925197058053634288518207618858900910754332784721266337267119"; + "20414673166470607272747811391805104245858774907937409341200492727939746607797"; + "25627294268923401583055123311122337854601831198810692741217863178401731813982"; + "9471796077791050250358831370212483753463358283515022318409978072807223150958"; + "18314066421198133015325418115287580268791041525896152562360347711250600527843"; + "24017014751842644177743018360725989342257842302110775272063931146838823820708"; + "21581200003538126245980521668237719802680919088433705982480735447972766043363"; + "50184800347056048262055270151626286042367002765576087001102590179487127900402"; + "30495886812798520386657837931015291018488945515192090129642139250370928693580"; + "22576369160305502855935040778001809663355224383879666287087499574629468037932"; + "8892650559142637497217516060667987141940174680954367407928503085925759784531"; + "26585722842364766084323735392097803839711029569348840728693523172589688253154"; + "29233945065322679878626700781011757896403829828629855948960912667621036626304"; + "46495499699253457275171950570731129922763854056949062569251813711011602552765"; + "20175726311806847923316241767174947396593584808993154634747567993383544235788"; + "4439738901982759407797641994447539352385040803130129830312569441261131407125"; + "16457982232415810076025629044220925770877965806117341776311181746417552277025"; + "19907475632940820992995770155453308899317289306448422338160567626015082798255"; + "35223042914091176169939921699730780563001221818541154418947974752159293542388"; + "43001533944345692738449547388403626716967932955110192080457393496732555299619"; + "34125500451758985735535246859157148109918522814391361071782479828094264751521"; + "672210927468386341214054725731176563716514412831001669942787056703691451010"; + "11955392088705171556964578398079500139155403309741307240924960466165999666255"; + "15001212103447594119920182143104283078666143755444714277900928289186853558391"; + "12494141652757315459070169705561134159399433995127302554127714989589492762158"; + "12539864421219420825268500409099786634396457699752281899702857644933872397743"; + "43101784081867314199511257387329290804750329977663948322198895874188929154741"; + "27446223298884346343269149146243911653385549792135607763714158002175305061634"; + "1221810201232089129932400022193871837808173942749956359312713538906718836479"; + "27532908760517365244003806543506083069460105424541918130562804937168539380933"; + "15648693309686663323928562339596607937964297674438414931587554610267850089762"; + "51990644901841817393110558619667069965078896715337659449054804464607693143160"; + "33794620192818979295379085241975052389791263016087838781391920545764975674473"; + "101607244559760430212506597577050204264047733826203142005234996733194535803"; + "40666396311706682608077428065814708907526669028006167240560016976036610792591"; + "12093027072881844562446294223504358738044964433607132404028203137662407596800"; + "47855031407689076102071980457490179464098686349841578053656622219683394194927"; + "22887362617646323246137538576383771868750784401107098034751943222440904306549"; + "14772206578599333281746941359370160645118537874167329823865244020069915126081"; + "3526757700545255914615010391053602312122669226422265428284197630347896730651"; + "33007891082396853981232434558524697472333004416828682481099968575992162687374"; + "31988013417414141593906072198372172527694109442594239825489920432494911766933"; + "11191961053993644897418397896972876540611743197344140729636835194462710841804"; + "21880105207814770273563304401112493784911759454461136323535459121487533758411"; + "41486397989964301339068924325783394852002678141033490060445600519554945226014"; + "16498626461620337833657560298722288376309400783422382991374550718050901966642"; + "24943377286264067314569680564276927094588309007929081549392361988305161867433"; + "37986591875971070389212991388767178111861904302329418052260086662061715255565"; + "32017690217798460109067983234755326443554479110662411364776709358644611216536"; + "11268114558872136972649888237328080074799940976672472351727712756343878033991"; + "8553866868885110753717367996095488037219349823019339928639756785019374917125"; + "32329156174505548357975583161085823726178367498919221564757310317285457845069"; + "27211717469524004207872746964920608620364761642576492559180465819096139390446"; + "17951459528837145129192967424193834007781706018124597879528401736511208623124"; + "5641081412497253735686285180366403504609424502347938813022628844058433088254"; + "44149401842640426661188167090997457203149609985845860407845476505741286527400"; + "1131272348428881671180311242049529569730380344899908988923912651593170365621"; + "29408853361809783058473821719041796914748403385269196060920996759386405450822"; + "46397512824547164970111952967961313462600614947138288894235958387784135997027"; + "47516645729584090306484976699637881381716439437813917167035708795500295063993"; + "33055093158354315225697732538526252497152864807143121380155645175831367997411"; + "2483278713512874912077821925021730472549918913537260777217235941375925483743"; + "48815704230612764031863984553515469905544143230929551627072471933945117691529"; + "4328792740667001536219824544300358343992356873304526946361038441974068375040"; + "8936186593485597641227715388671424329734834396891419524831642301555170823192"; + "17951920387101669293331644306482124096994648510679825947980062912137916768437"; + "19375514622607648705471192919423809092605947096218527444759114794843323604399"; + "29610094038370566321951750688045410763551744002173884016718675203262367949199"; + "26412332356216088802741437584182840836365448342900386978712282658982011423028"; + "6857200692997830027964569096279902529051039382386370537664642602910884711585"; + "23793860449672430773141781094420115804950727589006926766592001526772413630888"; + "48757257789712605511132590475466929307721670979642060291457808809543669563707"; + "41645960082452856575583766422864660930176349173234319988174582522281045680944"; + "33000251418643291466811739862781501771791890505914908533407925955048210111449"; + "15394914111369858819577264515844393687512099293048804309053356275657357176587"; + "8206746691969770388090261805798801614135957851585811798250200766530283892894"; + "8853211220347505554369001872046201218026106125304684911336722654414177119527"; + |] diff --git a/src/lib_mec/babyjubjub.ml b/src/lib_mec/babyjubjub.ml new file mode 100644 index 000000000000..00f60ae92c8f --- /dev/null +++ b/src/lib_mec/babyjubjub.ml @@ -0,0 +1,49 @@ +(** + https://eips.ethereum.org/EIPS/eip-2494#specification + + Base field: 21888242871839275222246405745257275088548364400416034343698204186575808495617 (253 bits - 32 bytes) + Scalar field: 2736030358979909402780800718157159386076813972158567259200215660948447373041 (250 bits - 32 bytes) + + Base field multiplicative subgroup decomposition: + 2^28 * 3^2 * 13 * 29 * 983 * 11003 * 237073 * 405928799 * 23088226308677670388631582763742451703676949 + Prime field multiplication subgroup decomposition: + 2^4 * 3 * 5 * 11^2 * 17 * 967 * 5731244081299119113329403448958138808514418469011002817495701323359 +*) + +(* Check it is not a small order element *) + +module Base = Ff.MakeFp (struct + let prime_order = + Z.of_string + "21888242871839275222246405745257275088548364400416034343698204186575808495617" +end) + +module Scalar = Ff.MakeFp (struct + let prime_order = + Z.of_string + "2736030358979909402780800718157159386076813972158567259200215660948447373041" +end) + +module Affine = + Ec.MakeAffineEdwards (Base) (Scalar) + (struct + let a = Base.of_string "168700" + + let d = Base.of_string "168696" + + let cofactor = Z.of_string "8" + + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Base.( + to_bytes + (of_string + "5299619240641551281634865583518297030282874472190772894086521144482721001553")); + Base.( + to_bytes + (of_string + "16950150798460657717958625567821834550301663161624707787222815936182638968203")); + ] + end) diff --git a/src/lib_mec/babyjubjub.mli b/src/lib_mec/babyjubjub.mli new file mode 100644 index 000000000000..fa016547ad13 --- /dev/null +++ b/src/lib_mec/babyjubjub.mli @@ -0,0 +1 @@ +module Affine : Ec_sig.AffineEdwardsT diff --git a/src/lib_mec/babyjubjub_reduced.ml b/src/lib_mec/babyjubjub_reduced.ml new file mode 100644 index 000000000000..5d45fd6bf7f8 --- /dev/null +++ b/src/lib_mec/babyjubjub_reduced.ml @@ -0,0 +1,47 @@ +(** + Base field: 21888242871839275222246405745257275088548364400416034343698204186575808495617 (253 bits - 32 bytes) + Scalar field: 2736030358979909402780800718157159386076813972158567259200215660948447373041 (250 bits - 32 bytes) + + Base field multiplicative subgroup decomposition: + 2^28 * 3^2 * 13 * 29 * 983 * 11003 * 237073 * 405928799 * 23088226308677670388631582763742451703676949 + Prime field multiplication subgroup decomposition: + 2^4 * 3 * 5 * 11^2 * 17 * 967 * 5731244081299119113329403448958138808514418469011002817495701323359 +*) + +module Base = Ff.MakeFp (struct + let prime_order = + Z.of_string + "21888242871839275222246405745257275088548364400416034343698204186575808495617" +end) + +module Scalar = Ff.MakeFp (struct + let prime_order = + Z.of_string + "2736030358979909402780800718157159386076813972158567259200215660948447373041" +end) + +module Affine = + Ec.MakeAffineEdwards (Base) (Scalar) + (struct + let a = Base.(negate one) + + let d = + Base.of_string + "12181644023421730124874158521699555681764249180949974110617291017600649128846" + + let cofactor = Z.of_string "8" + + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Base.( + to_bytes + (of_string + "9671717474070082183213120605117400219616337014328744928644933853176787189663")); + Base.( + to_bytes + (of_string + "16950150798460657717958625567821834550301663161624707787222815936182638968203")); + ] + end) diff --git a/src/lib_mec/babyjubjub_reduced.mli b/src/lib_mec/babyjubjub_reduced.mli new file mode 100644 index 000000000000..fa016547ad13 --- /dev/null +++ b/src/lib_mec/babyjubjub_reduced.mli @@ -0,0 +1 @@ +module Affine : Ec_sig.AffineEdwardsT diff --git a/src/lib_mec/baijiu_blake2b.ml b/src/lib_mec/baijiu_blake2b.ml new file mode 100644 index 000000000000..d23986b18dde --- /dev/null +++ b/src/lib_mec/baijiu_blake2b.ml @@ -0,0 +1,441 @@ +module By = Digestif_by +module Bi = Digestif_bi + +let failwith fmt = Format.kasprintf failwith fmt + +module Int32 = struct + include Int32 + + let ( lsl ) = Int32.shift_left + + let ( lsr ) = Int32.shift_right_logical + + let ( asr ) = Int32.shift_right + + let ( lor ) = Int32.logor + + let ( lxor ) = Int32.logxor + + let ( land ) = Int32.logand + + let lnot = Int32.lognot + + let ( + ) = Int32.add + + let rol32 a n = (a lsl n) lor (a lsr (32 - n)) + + let ror32 a n = (a lsr n) lor (a lsl (32 - n)) +end + +module Int64 = struct + include Int64 + + let ( land ) = Int64.logand + + let ( lsl ) = Int64.shift_left + + let ( lsr ) = Int64.shift_right_logical + + let ( lor ) = Int64.logor + + let ( asr ) = Int64.shift_right + + let ( lxor ) = Int64.logxor + + let ( + ) = Int64.add + + let rol64 a n = (a lsl n) lor (a lsr (64 - n)) + + let ror64 a n = (a lsr n) lor (a lsl (64 - n)) +end + +module type S = sig + type ctx + + type kind = [`BLAKE2B] + + val init : ?personalisation:Bytes.t -> unit -> ctx + + val with_outlen_and_bytes_key : + ?personalisation:Bytes.t -> int -> By.t -> int -> int -> ctx + + val with_outlen_and_bigstring_key : + ?personalisation:Bytes.t -> int -> Bi.t -> int -> int -> ctx + + val unsafe_feed_bytes : ctx -> By.t -> int -> int -> unit + + val unsafe_feed_bigstring : ctx -> Bi.t -> int -> int -> unit + + val unsafe_get : ctx -> By.t + + val dup : ctx -> ctx + + val max_outlen : int +end + +module Unsafe : S = struct + type kind = [`BLAKE2B] + + type param = { + digest_length : int; + key_length : int; + fanout : int; + depth : int; + leaf_length : int32; + node_offset : int32; + xof_length : int32; + node_depth : int; + inner_length : int; + reserved : int array; + salt : int array; + personal : int array; + } + + type ctx = { + mutable buflen : int; + outlen : int; + mutable last_node : int; + buf : Bytes.t; + h : int64 array; + t : int64 array; + f : int64 array; + } + + let dup ctx = + { + buflen = ctx.buflen; + outlen = ctx.outlen; + last_node = ctx.last_node; + buf = By.copy ctx.buf; + h = Array.copy ctx.h; + t = Array.copy ctx.t; + f = Array.copy ctx.f; + } + + let param_to_bytes param = + let arr = + [| + param.digest_length land 0xFF; + param.key_length land 0xFF; + param.fanout land 0xFF; + param.depth land 0xFF (* store to little-endian *); + Int32.(to_int ((param.leaf_length lsr 0) land 0xFFl)); + Int32.(to_int ((param.leaf_length lsr 8) land 0xFFl)); + Int32.(to_int ((param.leaf_length lsr 16) land 0xFFl)); + Int32.(to_int ((param.leaf_length lsr 24) land 0xFFl)) + (* store to little-endian *); + Int32.(to_int ((param.node_offset lsr 0) land 0xFFl)); + Int32.(to_int ((param.node_offset lsr 8) land 0xFFl)); + Int32.(to_int ((param.node_offset lsr 16) land 0xFFl)); + Int32.(to_int ((param.node_offset lsr 24) land 0xFFl)) + (* store to little-endian *); + Int32.(to_int ((param.xof_length lsr 0) land 0xFFl)); + Int32.(to_int ((param.xof_length lsr 8) land 0xFFl)); + Int32.(to_int ((param.xof_length lsr 16) land 0xFFl)); + Int32.(to_int ((param.xof_length lsr 24) land 0xFFl)); + param.node_depth land 0xFF; + param.inner_length land 0xFF; + param.reserved.(0) land 0xFF; + param.reserved.(1) land 0xFF; + param.reserved.(2) land 0xFF; + param.reserved.(3) land 0xFF; + param.reserved.(4) land 0xFF; + param.reserved.(5) land 0xFF; + param.reserved.(6) land 0xFF; + param.reserved.(7) land 0xFF; + param.reserved.(8) land 0xFF; + param.reserved.(9) land 0xFF; + param.reserved.(10) land 0xFF; + param.reserved.(11) land 0xFF; + param.reserved.(12) land 0xFF; + param.reserved.(13) land 0xFF; + param.salt.(0) land 0xFF; + param.salt.(1) land 0xFF; + param.salt.(2) land 0xFF; + param.salt.(3) land 0xFF; + param.salt.(4) land 0xFF; + param.salt.(5) land 0xFF; + param.salt.(6) land 0xFF; + param.salt.(7) land 0xFF; + param.salt.(8) land 0xFF; + param.salt.(9) land 0xFF; + param.salt.(10) land 0xFF; + param.salt.(11) land 0xFF; + param.salt.(12) land 0xFF; + param.salt.(13) land 0xFF; + param.salt.(14) land 0xFF; + param.salt.(15) land 0xFF; + param.personal.(0) land 0xFF; + param.personal.(1) land 0xFF; + param.personal.(2) land 0xFF; + param.personal.(3) land 0xFF; + param.personal.(4) land 0xFF; + param.personal.(5) land 0xFF; + param.personal.(6) land 0xFF; + param.personal.(7) land 0xFF; + param.personal.(8) land 0xFF; + param.personal.(9) land 0xFF; + param.personal.(10) land 0xFF; + param.personal.(11) land 0xFF; + param.personal.(12) land 0xFF; + param.personal.(13) land 0xFF; + param.personal.(14) land 0xFF; + param.personal.(15) land 0xFF; + |] + in + By.init 64 (fun i -> Char.unsafe_chr arr.(i)) + + let max_outlen = 64 + + let default_param = + { + digest_length = max_outlen; + key_length = 0; + fanout = 1; + depth = 1; + leaf_length = 0l; + node_offset = 0l; + xof_length = 0l; + node_depth = 0; + inner_length = 0; + reserved = [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0|]; + salt = [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0|]; + personal = [|0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0|]; + } + + let iv = + [| + 0x6a09e667f3bcc908L; + 0xbb67ae8584caa73bL; + 0x3c6ef372fe94f82bL; + 0xa54ff53a5f1d36f1L; + 0x510e527fade682d1L; + 0x9b05688c2b3e6c1fL; + 0x1f83d9abfb41bd6bL; + 0x5be0cd19137e2179L; + |] + + let increment_counter ctx inc = + let open Int64 in + ctx.t.(0) <- ctx.t.(0) + inc ; + ctx.t.(1) <- (ctx.t.(1) + if ctx.t.(0) < inc then 1L else 0L) + + let set_lastnode ctx = ctx.f.(1) <- Int64.minus_one + + let set_lastblock ctx = + if ctx.last_node <> 0 then set_lastnode ctx ; + ctx.f.(0) <- Int64.minus_one + + let init ?personalisation () = + let buf = By.make 128 '\x00' in + By.fill buf 0 128 '\x00' ; + let ctx = + { + buflen = 0; + outlen = default_param.digest_length; + last_node = 0; + buf; + h = Array.make 8 0L; + t = Array.make 2 0L; + f = Array.make 2 0L; + } + in + let personal = + match personalisation with + | None -> Array.make 16 0 + | Some personalisation -> + if Bytes.length personalisation != 16 then + failwith "Personalisation must be of 16 bytes long" ; + Array.init (Bytes.length personalisation) (fun i -> + int_of_char @@ Bytes.get personalisation i) + in + let param = {default_param with personal} in + let param_bytes = param_to_bytes param in + for i = 0 to 7 do + ctx.h.(i) <- Int64.(iv.(i) lxor By.le64_to_cpu param_bytes (i * 8)) + done ; + ctx + + let sigma = + [| + [|0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15|]; + [|14; 10; 4; 8; 9; 15; 13; 6; 1; 12; 0; 2; 11; 7; 5; 3|]; + [|11; 8; 12; 0; 5; 2; 15; 13; 10; 14; 3; 6; 7; 1; 9; 4|]; + [|7; 9; 3; 1; 13; 12; 11; 14; 2; 6; 5; 10; 4; 0; 15; 8|]; + [|9; 0; 5; 7; 2; 4; 10; 15; 14; 1; 11; 12; 6; 8; 3; 13|]; + [|2; 12; 6; 10; 0; 11; 8; 3; 4; 13; 7; 5; 15; 14; 1; 9|]; + [|12; 5; 1; 15; 14; 13; 4; 10; 0; 7; 6; 3; 9; 2; 8; 11|]; + [|13; 11; 7; 14; 12; 1; 3; 9; 5; 0; 15; 4; 8; 6; 2; 10|]; + [|6; 15; 14; 9; 11; 3; 0; 8; 12; 2; 13; 7; 1; 4; 10; 5|]; + [|10; 2; 8; 4; 7; 6; 1; 5; 15; 11; 9; 14; 3; 12; 13; 0|]; + [|0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15|]; + [|14; 10; 4; 8; 9; 15; 13; 6; 1; 12; 0; 2; 11; 7; 5; 3|]; + |] + + let compress : + type a. le64_to_cpu:(a -> int -> int64) -> ctx -> a -> int -> unit = + fun ~le64_to_cpu ctx block off -> + let v = Array.make 16 0L in + let m = Array.make 16 0L in + let g r i a_idx b_idx c_idx d_idx = + let ( ++ ) = ( + ) in + let open Int64 in + v.(a_idx) <- v.(a_idx) + v.(b_idx) + m.(sigma.(r).((2 * i) ++ 0)) ; + v.(d_idx) <- ror64 (v.(d_idx) lxor v.(a_idx)) 32 ; + v.(c_idx) <- v.(c_idx) + v.(d_idx) ; + v.(b_idx) <- ror64 (v.(b_idx) lxor v.(c_idx)) 24 ; + v.(a_idx) <- v.(a_idx) + v.(b_idx) + m.(sigma.(r).((2 * i) ++ 1)) ; + v.(d_idx) <- ror64 (v.(d_idx) lxor v.(a_idx)) 16 ; + v.(c_idx) <- v.(c_idx) + v.(d_idx) ; + v.(b_idx) <- ror64 (v.(b_idx) lxor v.(c_idx)) 63 + in + let r r = + g r 0 0 4 8 12 ; + g r 1 1 5 9 13 ; + g r 2 2 6 10 14 ; + g r 3 3 7 11 15 ; + g r 4 0 5 10 15 ; + g r 5 1 6 11 12 ; + g r 6 2 7 8 13 ; + g r 7 3 4 9 14 + in + for i = 0 to 15 do + m.(i) <- le64_to_cpu block (off + (i * 8)) + done ; + for i = 0 to 7 do + v.(i) <- ctx.h.(i) + done ; + v.(8) <- iv.(0) ; + v.(9) <- iv.(1) ; + v.(10) <- iv.(2) ; + v.(11) <- iv.(3) ; + v.(12) <- Int64.(iv.(4) lxor ctx.t.(0)) ; + v.(13) <- Int64.(iv.(5) lxor ctx.t.(1)) ; + v.(14) <- Int64.(iv.(6) lxor ctx.f.(0)) ; + v.(15) <- Int64.(iv.(7) lxor ctx.f.(1)) ; + r 0 ; + r 1 ; + r 2 ; + r 3 ; + r 4 ; + r 5 ; + r 6 ; + r 7 ; + r 8 ; + r 9 ; + r 10 ; + r 11 ; + let ( ++ ) = ( + ) in + for i = 0 to 7 do + ctx.h.(i) <- Int64.(ctx.h.(i) lxor v.(i) lxor v.(i ++ 8)) + done ; + () + + let feed : + type a. + blit:(a -> int -> By.t -> int -> int -> unit) -> + le64_to_cpu:(a -> int -> int64) -> + ctx -> + a -> + int -> + int -> + unit = + fun ~blit ~le64_to_cpu ctx buf off len -> + let in_off = ref off in + let in_len = ref len in + if !in_len > 0 then ( + let left = ctx.buflen in + let fill = 128 - left in + if !in_len > fill then ( + ctx.buflen <- 0 ; + blit buf !in_off ctx.buf left fill ; + increment_counter ctx 128L ; + compress ~le64_to_cpu:By.le64_to_cpu ctx ctx.buf 0 ; + in_off := !in_off + fill ; + in_len := !in_len - fill ; + while !in_len > 128 do + increment_counter ctx 128L ; + compress ~le64_to_cpu ctx buf !in_off ; + in_off := !in_off + 128 ; + in_len := !in_len - 128 + done) ; + blit buf !in_off ctx.buf ctx.buflen !in_len ; + ctx.buflen <- ctx.buflen + !in_len) ; + () + + let unsafe_feed_bytes = feed ~blit:By.blit ~le64_to_cpu:By.le64_to_cpu + + let unsafe_feed_bigstring = + feed ~blit:By.blit_from_bigstring ~le64_to_cpu:Bi.le64_to_cpu + + let with_outlen_and_key ?personalisation ~blit outlen key off len = + if outlen > max_outlen then + failwith + "out length can not be upper than %d (out length: %d)" + max_outlen + outlen ; + (* XXX(dannywillems): adding personalisation *) + let personalisation = + match personalisation with + | None -> Array.make 16 0 + | Some personalisation -> + if Bytes.length personalisation != 16 then + failwith "Personalisation must be of 16 bytes long" ; + Array.init 16 (fun i -> int_of_char @@ Bytes.get personalisation i) + in + let buf = By.make 128 '\x00' in + let ctx = + { + buflen = 0; + outlen; + last_node = 0; + buf; + h = Array.make 8 0L; + t = Array.make 2 0L; + f = Array.make 2 0L; + } + in + let param_bytes = + param_to_bytes + { + default_param with + digest_length = outlen; + key_length = len; + personal = personalisation; + } + in + for i = 0 to 7 do + ctx.h.(i) <- Int64.(iv.(i) lxor By.le64_to_cpu param_bytes (i * 8)) + done ; + if len > 0 then ( + let block = By.make 128 '\x00' in + blit key off block 0 len ; + unsafe_feed_bytes ctx block 0 128) ; + ctx + + let with_outlen_and_bytes_key ?personalisation outlen key off len = + with_outlen_and_key ?personalisation ~blit:By.blit outlen key off len + + let with_outlen_and_bigstring_key ?personalisation outlen key off len = + with_outlen_and_key + ?personalisation + ~blit:By.blit_from_bigstring + outlen + key + off + len + + let unsafe_get ctx = + let res = By.make default_param.digest_length '\x00' in + increment_counter ctx (Int64.of_int ctx.buflen) ; + set_lastblock ctx ; + By.fill ctx.buf ctx.buflen (128 - ctx.buflen) '\x00' ; + compress ~le64_to_cpu:By.le64_to_cpu ctx ctx.buf 0 ; + for i = 0 to 7 do + By.cpu_to_le64 res (i * 8) ctx.h.(i) + done ; + if ctx.outlen < default_param.digest_length then By.sub res 0 ctx.outlen + else if ctx.outlen > default_param.digest_length then assert false + (* XXX(dinosaure): [ctx] can not be initialized with [outlen > digest_length = max_outlen]. *) + else res +end diff --git a/src/lib_mec/baijiu_blake2s.ml b/src/lib_mec/baijiu_blake2s.ml new file mode 100644 index 000000000000..651401ecb8a4 --- /dev/null +++ b/src/lib_mec/baijiu_blake2s.ml @@ -0,0 +1,405 @@ +module By = Digestif_by +module Bi = Digestif_bi + +let failwith fmt = Format.kasprintf failwith fmt + +module Int32 = struct + include Int32 + + let ( lsl ) = Int32.shift_left + + let ( lsr ) = Int32.shift_right_logical + + let ( asr ) = Int32.shift_right + + let ( lor ) = Int32.logor + + let ( lxor ) = Int32.logxor + + let ( land ) = Int32.logand + + let lnot = Int32.lognot + + let ( + ) = Int32.add + + let rol32 a n = (a lsl n) lor (a lsr (32 - n)) + + let ror32 a n = (a lsr n) lor (a lsl (32 - n)) +end + +module Int64 = struct + include Int64 + + let ( land ) = Int64.logand + + let ( lsl ) = Int64.shift_left + + let ( lsr ) = Int64.shift_right_logical + + let ( lor ) = Int64.logor + + let ( asr ) = Int64.shift_right + + let ( lxor ) = Int64.logxor + + let ( + ) = Int64.add + + let rol64 a n = (a lsl n) lor (a lsr (64 - n)) + + let ror64 a n = (a lsr n) lor (a lsl (64 - n)) +end + +module type S = sig + type ctx + + type kind = [`BLAKE2S] + + val init : ?personalisation:Bytes.t -> unit -> ctx + + val with_outlen_and_bytes_key : + ?personalisation:Bytes.t -> int -> By.t -> int -> int -> ctx + + val with_outlen_and_bigstring_key : + ?personalisation:Bytes.t -> int -> Bi.t -> int -> int -> ctx + + val unsafe_feed_bytes : ctx -> By.t -> int -> int -> unit + + val unsafe_feed_bigstring : ctx -> Bi.t -> int -> int -> unit + + val unsafe_get : ctx -> By.t + + val dup : ctx -> ctx + + val max_outlen : int +end + +module Unsafe : S = struct + type kind = [`BLAKE2S] + + type param = { + digest_length : int; + key_length : int; + fanout : int; + depth : int; + leaf_length : int32; + node_offset : int32; + xof_length : int; + node_depth : int; + inner_length : int; + salt : int array; + personal : int array; + } + + type ctx = { + mutable buflen : int; + outlen : int; + mutable last_node : int; + buf : Bytes.t; + h : int32 array; + t : int32 array; + f : int32 array; + } + + let dup ctx = + { + buflen = ctx.buflen; + outlen = ctx.outlen; + last_node = ctx.last_node; + buf = By.copy ctx.buf; + h = Array.copy ctx.h; + t = Array.copy ctx.t; + f = Array.copy ctx.f; + } + + let param_to_bytes param = + let arr = + [| + param.digest_length land 0xFF; + param.key_length land 0xFF; + param.fanout land 0xFF; + param.depth land 0xFF (* store to little-endian *); + Int32.(to_int ((param.leaf_length lsr 0) land 0xFFl)); + Int32.(to_int ((param.leaf_length lsr 8) land 0xFFl)); + Int32.(to_int ((param.leaf_length lsr 16) land 0xFFl)); + Int32.(to_int ((param.leaf_length lsr 24) land 0xFFl)) + (* store to little-endian *); + Int32.(to_int ((param.node_offset lsr 0) land 0xFFl)); + Int32.(to_int ((param.node_offset lsr 8) land 0xFFl)); + Int32.(to_int ((param.node_offset lsr 16) land 0xFFl)); + Int32.(to_int ((param.node_offset lsr 24) land 0xFFl)) + (* store to little-endian *); + (param.xof_length lsr 0) land 0xFF; + (param.xof_length lsr 8) land 0xFF; + param.node_depth land 0xFF; + param.inner_length land 0xFF; + param.salt.(0) land 0xFF; + param.salt.(1) land 0xFF; + param.salt.(2) land 0xFF; + param.salt.(3) land 0xFF; + param.salt.(4) land 0xFF; + param.salt.(5) land 0xFF; + param.salt.(6) land 0xFF; + param.salt.(7) land 0xFF; + param.personal.(0) land 0xFF; + param.personal.(1) land 0xFF; + param.personal.(2) land 0xFF; + param.personal.(3) land 0xFF; + param.personal.(4) land 0xFF; + param.personal.(5) land 0xFF; + param.personal.(6) land 0xFF; + param.personal.(7) land 0xFF; + |] + in + By.init 32 (fun i -> Char.unsafe_chr arr.(i)) + + let max_outlen = 32 + + let default_param = + { + digest_length = max_outlen; + key_length = 0; + fanout = 1; + depth = 1; + leaf_length = 0l; + node_offset = 0l; + xof_length = 0; + node_depth = 0; + inner_length = 0; + salt = [|0; 0; 0; 0; 0; 0; 0; 0|]; + personal = [|0; 0; 0; 0; 0; 0; 0; 0|]; + } + + let iv = + [| + 0x6A09E667l; + 0xBB67AE85l; + 0x3C6EF372l; + 0xA54FF53Al; + 0x510E527Fl; + 0x9B05688Cl; + 0x1F83D9ABl; + 0x5BE0CD19l; + |] + + let increment_counter ctx inc = + let open Int32 in + ctx.t.(0) <- ctx.t.(0) + inc ; + ctx.t.(1) <- (ctx.t.(1) + if ctx.t.(0) < inc then 1l else 0l) + + let set_lastnode ctx = ctx.f.(1) <- Int32.minus_one + + let set_lastblock ctx = + if ctx.last_node <> 0 then set_lastnode ctx ; + ctx.f.(0) <- Int32.minus_one + + let init ?personalisation () = + let buf = By.make 64 '\x00' in + let ctx = + { + buflen = 0; + outlen = default_param.digest_length; + last_node = 0; + buf; + h = Array.make 8 0l; + t = Array.make 2 0l; + f = Array.make 2 0l; + } + in + let personal = + match personalisation with + | None -> Array.make 8 0 + | Some personalisation -> + if Bytes.length personalisation != 8 then + failwith "Personalisation must be of 8 bytes long" ; + Array.init (Bytes.length personalisation) (fun i -> + int_of_char @@ Bytes.get personalisation i) + in + let param = {default_param with personal} in + let param_bytes = param_to_bytes param in + for i = 0 to 7 do + ctx.h.(i) <- Int32.(iv.(i) lxor By.le32_to_cpu param_bytes (i * 4)) + done ; + ctx + + let sigma = + [| + [|0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15|]; + [|14; 10; 4; 8; 9; 15; 13; 6; 1; 12; 0; 2; 11; 7; 5; 3|]; + [|11; 8; 12; 0; 5; 2; 15; 13; 10; 14; 3; 6; 7; 1; 9; 4|]; + [|7; 9; 3; 1; 13; 12; 11; 14; 2; 6; 5; 10; 4; 0; 15; 8|]; + [|9; 0; 5; 7; 2; 4; 10; 15; 14; 1; 11; 12; 6; 8; 3; 13|]; + [|2; 12; 6; 10; 0; 11; 8; 3; 4; 13; 7; 5; 15; 14; 1; 9|]; + [|12; 5; 1; 15; 14; 13; 4; 10; 0; 7; 6; 3; 9; 2; 8; 11|]; + [|13; 11; 7; 14; 12; 1; 3; 9; 5; 0; 15; 4; 8; 6; 2; 10|]; + [|6; 15; 14; 9; 11; 3; 0; 8; 12; 2; 13; 7; 1; 4; 10; 5|]; + [|10; 2; 8; 4; 7; 6; 1; 5; 15; 11; 9; 14; 3; 12; 13; 0|]; + |] + + let compress : + type a. le32_to_cpu:(a -> int -> int32) -> ctx -> a -> int -> unit = + fun ~le32_to_cpu ctx block off -> + let v = Array.make 16 0l in + let m = Array.make 16 0l in + let g r i a_idx b_idx c_idx d_idx = + let ( ++ ) = ( + ) in + let open Int32 in + v.(a_idx) <- v.(a_idx) + v.(b_idx) + m.(sigma.(r).((2 * i) ++ 0)) ; + v.(d_idx) <- ror32 (v.(d_idx) lxor v.(a_idx)) 16 ; + v.(c_idx) <- v.(c_idx) + v.(d_idx) ; + v.(b_idx) <- ror32 (v.(b_idx) lxor v.(c_idx)) 12 ; + v.(a_idx) <- v.(a_idx) + v.(b_idx) + m.(sigma.(r).((2 * i) ++ 1)) ; + v.(d_idx) <- ror32 (v.(d_idx) lxor v.(a_idx)) 8 ; + v.(c_idx) <- v.(c_idx) + v.(d_idx) ; + v.(b_idx) <- ror32 (v.(b_idx) lxor v.(c_idx)) 7 + in + let r r = + g r 0 0 4 8 12 ; + g r 1 1 5 9 13 ; + g r 2 2 6 10 14 ; + g r 3 3 7 11 15 ; + g r 4 0 5 10 15 ; + g r 5 1 6 11 12 ; + g r 6 2 7 8 13 ; + g r 7 3 4 9 14 + in + for i = 0 to 15 do + m.(i) <- le32_to_cpu block (off + (i * 4)) + done ; + for i = 0 to 7 do + v.(i) <- ctx.h.(i) + done ; + v.(8) <- iv.(0) ; + v.(9) <- iv.(1) ; + v.(10) <- iv.(2) ; + v.(11) <- iv.(3) ; + v.(12) <- Int32.(iv.(4) lxor ctx.t.(0)) ; + v.(13) <- Int32.(iv.(5) lxor ctx.t.(1)) ; + v.(14) <- Int32.(iv.(6) lxor ctx.f.(0)) ; + v.(15) <- Int32.(iv.(7) lxor ctx.f.(1)) ; + r 0 ; + r 1 ; + r 2 ; + r 3 ; + r 4 ; + r 5 ; + r 6 ; + r 7 ; + r 8 ; + r 9 ; + let ( ++ ) = ( + ) in + for i = 0 to 7 do + ctx.h.(i) <- Int32.(ctx.h.(i) lxor v.(i) lxor v.(i ++ 8)) + done ; + () + + let feed : + type a. + blit:(a -> int -> By.t -> int -> int -> unit) -> + le32_to_cpu:(a -> int -> int32) -> + ctx -> + a -> + int -> + int -> + unit = + fun ~blit ~le32_to_cpu ctx buf off len -> + let in_off = ref off in + let in_len = ref len in + if !in_len > 0 then ( + let left = ctx.buflen in + let fill = 64 - left in + if !in_len > fill then ( + ctx.buflen <- 0 ; + blit buf !in_off ctx.buf left fill ; + increment_counter ctx 64l ; + compress ~le32_to_cpu:By.le32_to_cpu ctx ctx.buf 0 ; + in_off := !in_off + fill ; + in_len := !in_len - fill ; + while !in_len > 64 do + increment_counter ctx 64l ; + compress ~le32_to_cpu ctx buf !in_off ; + in_off := !in_off + 64 ; + in_len := !in_len - 64 + done) ; + blit buf !in_off ctx.buf ctx.buflen !in_len ; + ctx.buflen <- ctx.buflen + !in_len) ; + () + + let unsafe_feed_bytes = feed ~blit:By.blit ~le32_to_cpu:By.le32_to_cpu + + let unsafe_feed_bigstring = + feed ~blit:By.blit_from_bigstring ~le32_to_cpu:Bi.le32_to_cpu + + let with_outlen_and_key ?personalisation ~blit outlen key off len = + if outlen > max_outlen then + failwith + "out length can not be upper than %d (out length: %d)" + max_outlen + outlen ; + let buf = By.make 64 '\x00' in + let ctx = + { + buflen = 0; + outlen; + last_node = 0; + buf; + h = Array.make 8 0l; + t = Array.make 2 0l; + f = Array.make 2 0l; + } + in + (* XXX(dannywillems): adding personalisation *) + let personalisation = + match personalisation with + | None -> Array.make 8 0 + | Some personalisation -> + if Bytes.length personalisation != 8 then + failwith "Personalisation must be of 8 bytes long" ; + Array.init 8 (fun i -> int_of_char @@ Bytes.get personalisation i) + in + let param_bytes = + param_to_bytes + { + default_param with + key_length = len; + digest_length = outlen; + (* XXX(dannywillems): adding personalisation *) + personal = personalisation; + } + in + for i = 0 to 7 do + ctx.h.(i) <- Int32.(iv.(i) lxor By.le32_to_cpu param_bytes (i * 4)) + done ; + if len > 0 then ( + let block = By.make 64 '\x00' in + blit key off block 0 len ; + unsafe_feed_bytes ctx block 0 64) ; + ctx + + (* XXX(dannywillems): adding personalisation *) + let with_outlen_and_bytes_key ?personalisation outlen key off len = + with_outlen_and_key ?personalisation ~blit:By.blit outlen key off len + + (* XXX(dannywillems): adding personalisation *) + let with_outlen_and_bigstring_key ?personalisation outlen key off len = + with_outlen_and_key + ?personalisation + ~blit:By.blit_from_bigstring + outlen + key + off + len + + let unsafe_get ctx = + let res = By.make default_param.digest_length '\x00' in + increment_counter ctx (Int32.of_int ctx.buflen) ; + set_lastblock ctx ; + By.fill ctx.buf ctx.buflen (64 - ctx.buflen) '\x00' ; + compress ~le32_to_cpu:By.le32_to_cpu ctx ctx.buf 0 ; + for i = 0 to 7 do + By.cpu_to_le32 res (i * 4) ctx.h.(i) + done ; + if ctx.outlen < default_param.digest_length then By.sub res 0 ctx.outlen + else if ctx.outlen > default_param.digest_length then assert false + (* XXX(dinosaure): [ctx] can not be initialized with [outlen > digest_length = max_outlen]. *) + else res +end diff --git a/src/lib_mec/bandersnatch.ml b/src/lib_mec/bandersnatch.ml new file mode 100644 index 000000000000..3ce5d6af2c8e --- /dev/null +++ b/src/lib_mec/bandersnatch.ml @@ -0,0 +1,148 @@ +(** + https://eprint.iacr.org/2021/1152.pdf + + Base field: 52435875175126190479447740508185965837690552500527637822603658699938581184513 (254 bits - 32 bytes) + Scalar field: 13108968793781547619861935127046491459309155893440570251786403306729687672801 (253 bits - 32 bytes) + + Base field multiplicative subgroup decomposition: + 2^32 * 3 * 11 * 19 * 10177 * 125527 * 859267 * 906349^2 * 2508409 * 2529403 * 52437899 * 254760293^2 + Prime field multiplication subgroup decomposition: + 2^5 * 3 * 5^2 * 5462070330742311508275806302936038108045481622266904271577668044470703197 +*) + +module Base = Ff.MakeFp (struct + let prime_order = + Z.of_string + "52435875175126190479447740508185965837690552500527637822603658699938581184513" +end) + +module Scalar = Ff.MakeFp (struct + let prime_order = + Z.of_string + "13108968793781547619861935127046491459309155893440570251786403306729687672801" +end) + +(* Parameters found here: https://github.com/zhenfeizhang/bandersnatch/blob/65823a69d6c4c7612d2f2d3d21ce87f2b319fcf0/bandersnatch/src/curves/mod.rs *) +module AffineEdwards = + Ec.MakeAffineEdwards (Base) (Scalar) + (struct + let a = Base.(negate (of_string "5")) + + let d = + Base.( + of_string "138827208126141220649022263972958607803" + / of_string "171449701953573178309673572579671231137") + + let cofactor = Z.of_string "4" + + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Base.( + to_bytes + (of_string + "18886178867200960497001835917649091219057080094937609519140440539760939937304")); + Base.( + to_bytes + (of_string + "19188667384257783945677642223292697773471335439753913231509108946878080696678")); + ] + end) + +module AffineMontgomery = + Ec.MakeAffineMontgomery (Base) (Scalar) + (struct + let a = + Base.of_string + "0x4247698f4e32ad45a293959b4ca17afa4a2d2317e4c6ce5023e1fd63d1b5de98" + + let b = + Base.of_string + "0x300c3385d13bedb7c9e229e185c4ce8b1dd3b71366bb97c30855c0aa41d62727" + + let cofactor = Z.of_int 4 + + (* Computing the y-coordinates using + + ```OCaml + let x_m = + B.of_string "0x67c5b5fed18254e8acb66c1e38f33ee0975ae6876f9c5266a883f4604024b3b8" + in + let a = + B.of_string "0x4247698f4e32ad45a293959b4ca17afa4a2d2317e4c6ce5023e1fd63d1b5de98" + in + let b = + B.of_string "0x300c3385d13bedb7c9e229e185c4ce8b1dd3b71366bb97c30855c0aa41d62727" + in + let tmp = + B.(x_m * x_m * x_m + a * x_m * x_m + x_m) + in + let tmp = B.(tmp / b) in + B.to_string (Option.get (B.sqrt_opt tmp)) + ``` + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Base.( + to_bytes + (of_string + "0x67c5b5fed18254e8acb66c1e38f33ee0975ae6876f9c5266a883f4604024b3b8")); + Base.( + to_bytes + (of_string + "16568979071064374131063468616246789985515579410958029861283004835918472727623")); + ] + end) + +module AffineWeierstrass = + Ec.MakeAffineWeierstrass (Base) (Scalar) + (struct + let a = Base.(negate (of_string "3763200000")) + + let b = Base.(negate (of_string "78675968000000")) + + let cofactor = Z.of_int 4 + + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Base.( + to_bytes + (of_string + "0xa76451786f95a802c0982bbd0abd68e41b92adc86c8859b4f44679b21658710")); + Base.( + to_bytes + (of_string + "0x44d150c8b4bd14f79720d021a839e7b7eb4ee43844b30243126a72ac2375490a")); + ] + end) + +let from_affine_edwards_to_affine_montgomery p = + Ec.from_affine_edwards_to_affine_montgomery + (module AffineEdwards) + (module AffineMontgomery) + p + +let from_affine_montgomery_to_affine_edwards p = + Ec.from_affine_montgomery_to_affine_edwards + (module AffineMontgomery) + (module AffineEdwards) + p + +let from_affine_montgomery_to_affine_weierstrass p = + Ec.from_affine_montgomery_to_affine_weierstrass + (module AffineMontgomery) + (module AffineWeierstrass) + p + +let from_affine_edwards_to_affine_weierstrass p = + let p = from_affine_edwards_to_affine_montgomery p in + Option.bind p (fun opt -> + Ec.from_affine_montgomery_to_affine_weierstrass + (module AffineMontgomery) + (module AffineWeierstrass) + opt) diff --git a/src/lib_mec/bandersnatch.mli b/src/lib_mec/bandersnatch.mli new file mode 100644 index 000000000000..6d5c95be6112 --- /dev/null +++ b/src/lib_mec/bandersnatch.mli @@ -0,0 +1,17 @@ +module AffineEdwards : Ec_sig.AffineEdwardsT + +module AffineWeierstrass : Ec_sig.AffineWeierstrassT + +module AffineMontgomery : Ec_sig.AffineMontgomeryT + +val from_affine_edwards_to_affine_montgomery : + AffineEdwards.t -> AffineMontgomery.t option + +val from_affine_montgomery_to_affine_edwards : + AffineMontgomery.t -> AffineEdwards.t option + +val from_affine_montgomery_to_affine_weierstrass : + AffineMontgomery.t -> AffineWeierstrass.t option + +val from_affine_edwards_to_affine_weierstrass : + AffineEdwards.t -> AffineWeierstrass.t option diff --git a/src/lib_mec/bls12_381_ref.ml b/src/lib_mec/bls12_381_ref.ml new file mode 100644 index 000000000000..fcb88c8da16d --- /dev/null +++ b/src/lib_mec/bls12_381_ref.ml @@ -0,0 +1,225 @@ +(** + The equation of G1 is x^3 + 4 = y^2 +*) + +module Fq = Ff.MakeFp (struct + let prime_order = + (* 4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787 in decimal *) + Z.of_string + "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab" +end) + +module Fp = Ff.MakeFp (struct + let prime_order = + Z.of_string + "0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001" +end) + +module G1 = struct + module Projective = + Ec.MakeProjectiveWeierstrass (Fq) (Fp) + (struct + let a = Fq.zero + + let b = Fq.of_string "4" + + (* See https://github.com/zkcrypto/bls12_381/blob/main/src/notes/design.rs + The value has been obtained by running the following code in SAGE + ``` + def g1_h(x): + return ((x-1)**2) // 3 + param = -0xd201000000010000 + g1_h(param) + ``` + *) + let cofactor = Z.of_string "76329603384216526031706109802092473003" + + (* + https://github.com/zkcrypto/bls12_381/blob/main/src/g1.rs#L572 + ``` + x: Fp::from_raw_unchecked([ + 0x5cb3_8790_fd53_0c16, + 0x7817_fc67_9976_fff5, + 0x154f_95c7_143b_a1c1, + 0xf0ae_6acd_f3d0_e747, + 0xedce_6ecc_21db_f440, + 0x1201_7741_9e0b_fb75, + ]), + y: Fp::from_raw_unchecked([ + 0xbaac_93d5_0ce7_2271, + 0x8c22_631a_7918_fd8e, + 0xdd59_5f13_5707_25ce, + 0x51ac_5829_5040_5194, + 0x0e1c_8c3f_ad00_59c0, + 0x0bbc_3efc_5008_a26a, + ]), + z: Fp::one(), + ``` + Using decimal representation, computed using + ``` + Z.(to_string (of_string "0x...")) + ``` + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.( + to_bytes + (of_string + "3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507")); + Fq.( + to_bytes + (of_string + "1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569")); + Fq.(to_bytes one); + ] + end) + + module Affine = + Ec.MakeAffineWeierstrass (Fq) (Fp) + (struct + let a = Fq.zero + + let b = Fq.of_string "4" + + (* See https://github.com/zkcrypto/bls12_381/blob/main/src/notes/design.rs + The value has been obtained by running the following code in SAGE + ``` + def g1_h(x): + return ((x-1)**2) // 3 + param = -0xd201000000010000 + g1_h(param) + ``` + *) + let cofactor = Z.of_string "76329603384216526031706109802092473003" + + (* + https://github.com/zkcrypto/bls12_381/blob/main/src/g1.rs#L572 + ``` + x: Fp::from_raw_unchecked([ + 0x5cb3_8790_fd53_0c16, + 0x7817_fc67_9976_fff5, + 0x154f_95c7_143b_a1c1, + 0xf0ae_6acd_f3d0_e747, + 0xedce_6ecc_21db_f440, + 0x1201_7741_9e0b_fb75, + ]), + y: Fp::from_raw_unchecked([ + 0xbaac_93d5_0ce7_2271, + 0x8c22_631a_7918_fd8e, + 0xdd59_5f13_5707_25ce, + 0x51ac_5829_5040_5194, + 0x0e1c_8c3f_ad00_59c0, + 0x0bbc_3efc_5008_a26a, + ]), + ``` + Using decimal representation, computed using + ``` + Z.(to_string (of_string "0x...")) + ``` + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.( + to_bytes + (of_string + "3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507")); + Fq.( + to_bytes + (of_string + "1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569")); + ] + end) +end + +module Fq2 = + Ff.MakeFp2 + (Fq) + (struct + let nsr = Fq.of_string "4" + end) + +(* TODO: require to implement sqrt_opt for Fq2. Not yet available in ocaml-ff *) + +(* module G2 = struct + * module Projective = + * Ec.MakeProjectiveWeierstrass (Fq2) (Fp) + * (struct + * let a = Fq2.zero + * + * let b = Fq2.of_string "4" + * + * let cofactor = + * Z.of_string_base + * 16 + * "5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5" + * + * (\* + * https://github.com/zkcrypto/bls12_381/blob/main/src/g1.rs#L572 + * ``` + * x: Fp::from_raw_unchecked([ + * 0x5cb3_8790_fd53_0c16, + * 0x7817_fc67_9976_fff5, + * 0x154f_95c7_143b_a1c1, + * 0xf0ae_6acd_f3d0_e747, + * 0xedce_6ecc_21db_f440, + * 0x1201_7741_9e0b_fb75, + * ]), + * y: Fp::from_raw_unchecked([ + * 0xbaac_93d5_0ce7_2271, + * 0x8c22_631a_7918_fd8e, + * 0xdd59_5f13_5707_25ce, + * 0x51ac_5829_5040_5194, + * 0x0e1c_8c3f_ad00_59c0, + * 0x0bbc_3efc_5008_a26a, + * ]), + * z: Fp::one(), + * ``` + * Using decimal representation, computed using + * ``` + * Z.(to_string (of_string "0x...")) + * ``` + * *\) + * let bytes_generator = + * Bytes.concat + * Bytes.empty + * [ Fq.( + * to_bytes + * (of_string + * "3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507")); + * Fq.( + * to_bytes + * (of_string + * "1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569")); + * Fq.(to_bytes one) ] + * end) + * + * module Affine = + * Ec.MakeAffineWeierstrass (Fq2) (Fp) + * (struct + * let a = Fq2.zero + * + * let b = Fq2.of_string "4" + * + * let cofactor = + * Z.of_string_base + * 16 + * "5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5" + * + * let bytes_generator = + * Bytes.concat + * Bytes.empty + * [ Fq.( + * to_bytes + * (of_string + * "3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507")); + * Fq.( + * to_bytes + * (of_string + * "1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569")) + * ] + * end) + * end *) diff --git a/src/lib_mec/bls12_381_ref.mli b/src/lib_mec/bls12_381_ref.mli new file mode 100644 index 000000000000..242d3e4c5806 --- /dev/null +++ b/src/lib_mec/bls12_381_ref.mli @@ -0,0 +1,5 @@ +module G1 : sig + module Projective : Ec_sig.ProjectiveWeierstrassT + + module Affine : Ec_sig.AffineWeierstrassT +end diff --git a/src/lib_mec/bn254.ml b/src/lib_mec/bn254.ml new file mode 100644 index 000000000000..d2a1549abd01 --- /dev/null +++ b/src/lib_mec/bn254.ml @@ -0,0 +1,122 @@ +(** + https://neuromancer.sk/std/bn/bn254 + https://tools.ietf.org/id/draft-yonezawa-pairing-friendly-curves-00.html + + Base field: 16798108731015832284940804142231733909889187121439069848933715426072753864723 (254 bits - 32 bytes) + Scalar field: 16798108731015832284940804142231733909759579603404752749028378864165570215949 (254 bits - 32 bytes) + + Base field multiplicative subgroup decomposition: + TODO + Prime field multiplication subgroup decomposition: + TODO +*) + +module Fq = Ff.MakeFp (struct + let prime_order = + Z.of_string + "0x2523648240000001BA344D80000000086121000000000013A700000000000013" +end) + +module Fp = Ff.MakeFp (struct + let prime_order = + Z.of_string + "0x2523648240000001BA344D8000000007FF9F800000000010A10000000000000D" +end) + +module Projective = + Ec.MakeProjectiveWeierstrass (Fq) (Fp) + (struct + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 2) + + let cofactor = Z.one + + (* x = 0x2523648240000001BA344D80000000086121000000000013A700000000000012 + y = 0x0000000000000000000000000000000000000000000000000000000000000001 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.( + to_bytes + (of_string + "0x2523648240000001BA344D80000000086121000000000013A700000000000012")); + Fq.(to_bytes (of_string "1")); + Fq.(to_bytes one); + ] + end) + +module Jacobian = + Ec.MakeJacobianWeierstrass (Fq) (Fp) + (struct + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 2) + + let cofactor = Z.one + + (* x = 0x2523648240000001BA344D80000000086121000000000013A700000000000012 + y = 0x0000000000000000000000000000000000000000000000000000000000000001 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.( + to_bytes + (of_string + "0x2523648240000001BA344D80000000086121000000000013A700000000000012")); + Fq.(to_bytes (of_string "1")); + Fq.(to_bytes one); + ] + end) + +module Affine = + Ec.MakeAffineWeierstrass (Fq) (Fp) + (struct + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 2) + + let cofactor = Z.one + + (* x = 0x2523648240000001BA344D80000000086121000000000013A700000000000012 + y = 0x0000000000000000000000000000000000000000000000000000000000000001 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.( + to_bytes + (of_string + "0x2523648240000001BA344D80000000086121000000000013A700000000000012")); + Fq.(to_bytes (of_string "1")); + ] + end) + +let from_affine_weierstrass_to_jacobian_weierstrass p = + Ec.from_affine_weierstrass_to_jacobian_weierstrass + (module Affine) + (module Jacobian) + p + +let from_affine_weierstrass_to_projective_weierstrass p = + Ec.from_affine_weierstrass_to_projective_weierstrass + (module Affine) + (module Projective) + p + +let from_jacobian_weierstrass_to_affine_weierstrass p = + Ec.from_jacobian_weierstrass_to_affine_weierstrass + (module Jacobian) + (module Affine) + p + +let from_projective_weierstrass_to_affine_weierstrass p = + Ec.from_projective_weierstrass_to_affine_weierstrass + (module Projective) + (module Affine) + p diff --git a/src/lib_mec/bn254.mli b/src/lib_mec/bn254.mli new file mode 100644 index 000000000000..0d06a0937537 --- /dev/null +++ b/src/lib_mec/bn254.mli @@ -0,0 +1,13 @@ +module Projective : Ec_sig.ProjectiveWeierstrassT + +module Affine : Ec_sig.AffineWeierstrassT + +module Jacobian : Ec_sig.JacobianWeierstrassT + +val from_affine_weierstrass_to_jacobian_weierstrass : Affine.t -> Jacobian.t + +val from_affine_weierstrass_to_projective_weierstrass : Affine.t -> Projective.t + +val from_jacobian_weierstrass_to_affine_weierstrass : Jacobian.t -> Affine.t + +val from_projective_weierstrass_to_affine_weierstrass : Projective.t -> Affine.t diff --git a/src/lib_mec/curve25519.ml b/src/lib_mec/curve25519.ml new file mode 100644 index 000000000000..333114d1ca22 --- /dev/null +++ b/src/lib_mec/curve25519.ml @@ -0,0 +1,102 @@ +(** + https://ed25519.cr.yp.to/ + https://ed25519.cr.yp.to/python/ed25519.py + https://ed25519.cr.yp.to/eddsa-20150704.pdf (page 4, examples) + + + Base field: 2^255 - 19 = 57896044618658097711785492504343953926634992332820282019728792003956564819949 (254 bits - 32 bytes) + Scalar field: 2^252 + 27742317777372353535851937790883648493 = 7237005577332262213973186563042994240857116359379907606001950938285454250989 (252 bits - 32 bytes) + + Base field multiplicative subgroup decomposition: + 2^2 * 3 * 65147 * 74058212732561358302231226437062788676166966415465897661863160754340907 + + Prime field multiplication subgroup decomposition: + 2^2 * 3 * 11 * 54825799828274713742221110326083289703463002722575057621226901047617077659 +*) + +module Base = Ff.MakeFp (struct + let prime_order = Z.(pow (of_int 2) 255 - of_int 19) +end) + +module Scalar = Ff.MakeFp (struct + let prime_order = + Z.(pow (of_int 2) 252 + of_string "27742317777372353535851937790883648493") +end) + +module AffineEdwards = + Ec.MakeAffineEdwards (Base) (Scalar) + (struct + let a = Base.(negate (of_string "1")) + + let d = Base.(negate (of_string "121665" / of_string "121666")) + + (* https://ed25519.cr.yp.to/eddsa-20150704.pdf (page 4, examples). + c = 3 -> cofactor 8 + *) + let cofactor = Z.of_string "8" + + (* https://ed25519.cr.yp.to/eddsa-20150704.pdf (page 4, examples). + > B is the point (... 202, 4/5). Calculed using: + ``` + let f a d x = Base.(sqrt_opt ((one + negate (x * x)) / (a + (negate d) * x * x)));; + ``` + And use the result of: + ``` + Base.to_string @@ Base.negate @@ Option.get @@ f (Base.(negate one)) + (Base.(negate (of_string "121665" / of_string "121666"))) + (Base.(of_string "4" / of_string "5"));; + ``` + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Base.( + to_bytes + (of_string + "15112221349535400772501151409588531511454012693041857206046113283949847762202")); + Base.(to_bytes (of_string "4" / of_string "5")); + ] + + (* 4/5 = 463168356949264781694283940034751631413079938662562256157830336 + 03165251855960 *) + end) + +module AffineMontgomery = + Ec.MakeAffineMontgomery (Base) (Scalar) + (struct + (* Parameters generated with function to_montgomery_curve_parameters (). + The RFC (https://www.rfc-editor.org/rfc/rfc7748#section-4.1) uses a different mapping, + the Montgomery v coordinate being multiplied by sqrt(-486664), to get "Edwards25519" *) + + let a = Base.of_string "486662" + + let b = + Base.of_string + "57896044618658097711785492504343953926634992332820282019728792003956564333285" + + let cofactor = Z.of_string "8" + + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Base.(to_bytes (of_string "9")); + Base.( + to_bytes + (of_string + "46155036877857898950720737868668298259344786430663990124372813544693780678454")); + ] + end) + +let from_affine_edwards_to_affine_montgomery p = + Ec.from_affine_edwards_to_affine_montgomery + (module AffineEdwards) + (module AffineMontgomery) + p + +let from_affine_montgomery_to_affine_edwards p = + Ec.from_affine_montgomery_to_affine_edwards + (module AffineMontgomery) + (module AffineEdwards) + p diff --git a/src/lib_mec/curve25519.mli b/src/lib_mec/curve25519.mli new file mode 100644 index 000000000000..db396b673f5f --- /dev/null +++ b/src/lib_mec/curve25519.mli @@ -0,0 +1,9 @@ +module AffineEdwards : Ec_sig.AffineEdwardsT + +module AffineMontgomery : Ec_sig.AffineMontgomeryT + +val from_affine_edwards_to_affine_montgomery : + AffineEdwards.t -> AffineMontgomery.t option + +val from_affine_montgomery_to_affine_edwards : + AffineMontgomery.t -> AffineEdwards.t option diff --git a/src/lib_mec/curve448.ml b/src/lib_mec/curve448.ml new file mode 100644 index 000000000000..dbfa150cf554 --- /dev/null +++ b/src/lib_mec/curve448.ml @@ -0,0 +1,49 @@ +(** + https://datatracker.ietf.org/doc/html/rfc7748#section-4.2 + + Base field: 2^448 - 2^224 - 1 = 726838724295606890549323807888004534353641360687318060281490199180612328166730772686396383698676545930088884461843637361053498018365439 (447 bits - 57 bytes) + Scalar field: 2^446 - 13818066809895115352007386748515426880336692474882178609894547503885 = 181709681073901722637330951972001133588410340171829515070372549795146003961539585716195755291692375963310293709091662304773755859649779 (445 bits - 56 bytes) + + Base field multiplicative subgroup decomposition: + TODO + + Prime field multiplication subgroup decomposition: + TODO +*) + +module Base = Ff.MakeFp (struct + let prime_order = Z.(pow (of_int 2) 448 - pow (of_int 2) 224 - one) +end) + +module Scalar = Ff.MakeFp (struct + let prime_order = + Z.( + pow (of_int 2) 446 + - of_string "0x8335dc163bb124b65129c96fde933d8d723a70aadc873d6d54a7bb0d") +end) + +module Affine = + Ec.MakeAffineEdwards (Base) (Scalar) + (struct + let a = Base.of_string "1" + + let d = + Base.of_string + "611975850744529176160423220965553317543219696871016626328968936415087860042636474891785599283666020414768678979989378147065462815545017" + + let cofactor = Z.of_string "4" + + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Base.( + to_bytes + (of_string + "345397493039729516374008604150537410266655260075183290216406970281645695073672344430481787759340633221708391583424041788924124567700732")); + Base.( + to_bytes + (of_string + "363419362147803445274661903944002267176820680343659030140745099590306164083365386343198191849338272965044442230921818680526749009182718")); + ] + end) diff --git a/src/lib_mec/curve448.mli b/src/lib_mec/curve448.mli new file mode 100644 index 000000000000..fa016547ad13 --- /dev/null +++ b/src/lib_mec/curve448.mli @@ -0,0 +1 @@ +module Affine : Ec_sig.AffineEdwardsT diff --git a/src/lib_mec/digestif_bi.ml b/src/lib_mec/digestif_bi.ml new file mode 100644 index 000000000000..f57c981a6639 --- /dev/null +++ b/src/lib_mec/digestif_bi.ml @@ -0,0 +1,87 @@ +open Bigarray_compat + +type t = (char, int8_unsigned_elt, c_layout) Array1.t + +let create n = Array1.create Char c_layout n + +let length = Array1.dim + +let sub = Array1.sub + +let empty = Array1.create Char c_layout 0 + +let get = Array1.get + +let copy t = + let r = create (length t) in + Array1.blit t r ; + r + +let init l f = + let v = Array1.create Char c_layout l in + for i = 0 to l - 1 do + Array1.set v i (f i) + done ; + v + +external unsafe_get_32 : t -> int -> int32 = "%caml_bigstring_get32u" + +external unsafe_get_64 : t -> int -> int64 = "%caml_bigstring_get64u" + +let unsafe_get_nat : t -> int -> nativeint = + fun s i -> + if Sys.word_size = 32 then Nativeint.of_int32 @@ unsafe_get_32 s i + else Int64.to_nativeint @@ unsafe_get_64 s i + +external unsafe_set_32 : t -> int -> int32 -> unit = "%caml_bigstring_set32u" + +external unsafe_set_64 : t -> int -> int64 -> unit = "%caml_bigstring_set64u" + +let unsafe_set_nat : t -> int -> nativeint -> unit = + fun s i v -> + if Sys.word_size = 32 then unsafe_set_32 s i (Nativeint.to_int32 v) + else unsafe_set_64 s i (Int64.of_nativeint v) + +let to_string v = String.init (length v) (Array1.get v) + +let blit_from_bytes src src_off dst dst_off len = + for i = 0 to len - 1 do + Array1.set dst (dst_off + i) (Bytes.get src (src_off + i)) + done + +external swap32 : int32 -> int32 = "%bswap_int32" + +external swap64 : int64 -> int64 = "%bswap_int64" + +external swapnat : nativeint -> nativeint = "%bswap_native" + +let cpu_to_be32 s i v = + if Sys.big_endian then unsafe_set_32 s i v else unsafe_set_32 s i (swap32 v) + +let cpu_to_le32 s i v = + if Sys.big_endian then unsafe_set_32 s i (swap32 v) else unsafe_set_32 s i v + +let cpu_to_be64 s i v = + if Sys.big_endian then unsafe_set_64 s i v else unsafe_set_64 s i (swap64 v) + +let cpu_to_le64 s i v = + if Sys.big_endian then unsafe_set_64 s i (swap64 v) else unsafe_set_64 s i v + +let be32_to_cpu s i = + if Sys.big_endian then unsafe_get_32 s i else swap32 @@ unsafe_get_32 s i + +let le32_to_cpu s i = + if Sys.big_endian then swap32 @@ unsafe_get_32 s i else unsafe_get_32 s i + +let be64_to_cpu s i = + if Sys.big_endian then unsafe_get_64 s i else swap64 @@ unsafe_get_64 s i + +let le64_to_cpu s i = + if Sys.big_endian then swap64 @@ unsafe_get_64 s i else unsafe_get_64 s i + +let benat_to_cpu s i = + if Sys.big_endian then unsafe_get_nat s i else swapnat @@ unsafe_get_nat s i + +let cpu_to_benat s i v = + if Sys.big_endian then unsafe_set_nat s i v + else unsafe_set_nat s i (swapnat v) diff --git a/src/lib_mec/digestif_by.ml b/src/lib_mec/digestif_by.ml new file mode 100644 index 000000000000..ea7648eb470e --- /dev/null +++ b/src/lib_mec/digestif_by.ml @@ -0,0 +1,68 @@ +include Bytes + +external unsafe_get_32 : t -> int -> int32 = "%caml_string_get32u" + +external unsafe_get_64 : t -> int -> int64 = "%caml_string_get64u" + +let unsafe_get_nat : t -> int -> nativeint = + fun s i -> + if Sys.word_size = 32 then Nativeint.of_int32 @@ unsafe_get_32 s i + else Int64.to_nativeint @@ unsafe_get_64 s i + +external unsafe_set_32 : t -> int -> int32 -> unit = "%caml_string_set32u" + +external unsafe_set_64 : t -> int -> int64 -> unit = "%caml_string_set64u" + +let unsafe_set_nat : t -> int -> nativeint -> unit = + fun s i v -> + if Sys.word_size = 32 then unsafe_set_32 s i (Nativeint.to_int32 v) + else unsafe_set_64 s i (Int64.of_nativeint v) + +let blit_from_bigstring src src_off dst dst_off len = + for i = 0 to len - 1 do + set dst (dst_off + i) src.{src_off + i} + done + +let rpad a size x = + let l = length a in + let b = create size in + blit a 0 b 0 l ; + fill b l (size - l) x ; + b + +external swap32 : int32 -> int32 = "%bswap_int32" + +external swap64 : int64 -> int64 = "%bswap_int64" + +external swapnat : nativeint -> nativeint = "%bswap_native" + +let cpu_to_be32 s i v = + if Sys.big_endian then unsafe_set_32 s i v else unsafe_set_32 s i (swap32 v) + +let cpu_to_le32 s i v = + if Sys.big_endian then unsafe_set_32 s i (swap32 v) else unsafe_set_32 s i v + +let cpu_to_be64 s i v = + if Sys.big_endian then unsafe_set_64 s i v else unsafe_set_64 s i (swap64 v) + +let cpu_to_le64 s i v = + if Sys.big_endian then unsafe_set_64 s i (swap64 v) else unsafe_set_64 s i v + +let be32_to_cpu s i = + if Sys.big_endian then unsafe_get_32 s i else swap32 @@ unsafe_get_32 s i + +let le32_to_cpu s i = + if Sys.big_endian then swap32 @@ unsafe_get_32 s i else unsafe_get_32 s i + +let be64_to_cpu s i = + if Sys.big_endian then unsafe_get_64 s i else swap64 @@ unsafe_get_64 s i + +let le64_to_cpu s i = + if Sys.big_endian then swap64 @@ unsafe_get_64 s i else unsafe_get_64 s i + +let benat_to_cpu s i = + if Sys.big_endian then unsafe_get_nat s i else swapnat @@ unsafe_get_nat s i + +let cpu_to_benat s i v = + if Sys.big_endian then unsafe_set_nat s i v + else unsafe_set_nat s i (swapnat v) diff --git a/src/lib_mec/digestif_conv.ml b/src/lib_mec/digestif_conv.ml new file mode 100644 index 000000000000..399f134bcc0e --- /dev/null +++ b/src/lib_mec/digestif_conv.ml @@ -0,0 +1,104 @@ +let invalid_arg fmt = Format.ksprintf (fun s -> invalid_arg s) fmt + +module Make (D : sig + val digest_size : int +end) = +struct + let to_hex hash = + let res = Bytes.create (D.digest_size * 2) in + let chr x = + match x with + | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 -> Char.chr (48 + x) + | _ -> Char.chr (97 + (x - 10)) + in + for i = 0 to D.digest_size - 1 do + let v = Char.code hash.[i] in + Bytes.unsafe_set res (i * 2) (chr (v lsr 4)) ; + Bytes.unsafe_set res ((i * 2) + 1) (chr (v land 0x0F)) + done ; + Bytes.unsafe_to_string res + + let code x = + match x with + | '0' .. '9' -> Char.code x - Char.code '0' + | 'A' .. 'F' -> Char.code x - Char.code 'A' + 10 + | 'a' .. 'f' -> Char.code x - Char.code 'a' + 10 + | _ -> invalid_arg "of_hex: %02X" (Char.code x) + + let decode chr1 chr2 = Char.chr ((code chr1 lsl 4) lor code chr2) + + let of_hex hex = + let offset = ref 0 in + let rec go have_first idx = + if !offset + idx >= String.length hex then '\x00' + else + match hex.[!offset + idx] with + | ' ' | '\t' | '\r' | '\n' -> + incr offset ; + go have_first idx + | chr2 when have_first -> chr2 + | chr1 -> + incr offset ; + let chr2 = go true idx in + if chr2 <> '\x00' then decode chr1 chr2 + else invalid_arg "of_hex: odd number of hex characters" + in + String.init D.digest_size (go false) + + let of_hex_opt hex = + match of_hex hex with + | digest -> Some digest + | exception Invalid_argument _ -> None + + let consistent_of_hex str = + let offset = ref 0 in + let rec go have_first idx = + if !offset + idx >= String.length str then + invalid_arg "Not enough hex value" + else + match str.[!offset + idx] with + | ' ' | '\t' | '\r' | '\n' -> + incr offset ; + go have_first idx + | chr2 when have_first -> chr2 + | chr1 -> + incr offset ; + let chr2 = go true idx in + decode chr1 chr2 + in + let res = String.init D.digest_size (go false) in + let is_wsp = function ' ' | '\t' | '\r' | '\n' -> true | _ -> false in + while + D.digest_size + !offset < String.length str + && is_wsp str.[!offset + (D.digest_size * 2)] + do + incr offset + done ; + if !offset + D.digest_size = String.length str then res + else + invalid_arg + "Too much enough bytes (reach: %d, expect: %d)" + (!offset + (D.digest_size * 2)) + (String.length str) + + let consistent_of_hex_opt hex = + match consistent_of_hex hex with + | digest -> Some digest + | exception Invalid_argument _ -> None + + let pp ppf hash = + for i = 0 to D.digest_size - 1 do + Format.fprintf ppf "%02x" (Char.code hash.[i]) + done + + let of_raw_string x = + if String.length x <> D.digest_size then invalid_arg "invalid hash size" + else x + + let of_raw_string_opt x = + match of_raw_string x with + | digest -> Some digest + | exception Invalid_argument _ -> None + + let to_raw_string x = x +end diff --git a/src/lib_mec/digestif_eq.ml b/src/lib_mec/digestif_eq.ml new file mode 100644 index 000000000000..8ac6660c2c4f --- /dev/null +++ b/src/lib_mec/digestif_eq.ml @@ -0,0 +1,10 @@ +module Make (D : sig + val digest_size : int +end) = +struct + let _ = D.digest_size + + let equal a b = Eqaf.equal a b + + let unsafe_compare a b = String.compare a b +end diff --git a/src/lib_mec/dune b/src/lib_mec/dune new file mode 100644 index 000000000000..b0f6523d12e3 --- /dev/null +++ b/src/lib_mec/dune @@ -0,0 +1,12 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name mec) + (public_name octez-mec) + (instrumentation (backend bisect_ppx)) + (libraries + alcotest + bls12-381 + bigarray-compat + eqaf)) diff --git a/src/lib_mec/ec.ml b/src/lib_mec/ec.ml new file mode 100644 index 000000000000..cca415fde543 --- /dev/null +++ b/src/lib_mec/ec.ml @@ -0,0 +1,1458 @@ +(* + For each curve form and each coordinates, an external link MUST be given + pointing to the addition and doubling formulas. The addition MUST support + doubling. It is verified by the ECProperties functor. + + When adding a new curve form/coordinates, it is REQUIRED to add + - the number of additions (A), + - the number of additions with a constant (AC), + - the number of multiplications (M), + - the number of multiplications with a constant (MC), + - the number of negations (N), + - the number of substractions (SU), + - the number of divisions (DI), + - the number of doublings (DO), + - the number of squarings (SQ). + + If there is a requirement for the parameters, it MUST be verified at the + module top level. It is RECOMMENDED, but not required, to use a specific + exception and raise it with a meaningful message. + + When implementing a new form or new coordinates, it MUST be accompanied by + the instantiation of a standard/popular curve and test vectors in addition + to the generic PBT on EC properties. The origin of the test vectors MUST be + documented. + + If any constant are defined at the top level, it MUST be accompanied by an + explanation on where it is used, and why. + + In the case of an optimisation not listed in the associated paper/link + describing the formulas, the author MUST add an explanation. If it reduces + the number of field operations, the "original" and the "optimised" versions + MUST be compared in comments. + + IMPROVEME: + - For the moment, there is no ec.mli. When adding a new form or new + coordinates, the functor signature MUST be added in the interface. If you + read these lines and there is a file ec.mli, please open an issue. + - For the moment, it is only RECOMMENDED to use a particular exception when + verifying the parameters. It must be changed to a REQUIREMENT. + - For the moment, there is no distinction between `not being on the curve` + and `not being in the prime subgroup`. This MUST change. +*) + +open Bls12_381 + +module MakeJacobianWeierstrass + (Fq : Ff_sig.PRIME) + (Fp : Ff_sig.PRIME) (Params : sig + val a : Fq.t + + val b : Fq.t + + val cofactor : Z.t + + val bytes_generator : Bytes.t + end) : + Ec_sig.JacobianWeierstrassT with type Scalar.t = Fp.t and type Base.t = Fq.t = +struct + let () = assert (not (Fq.is_zero Params.b)) + + exception Not_on_curve of Bytes.t + + module Base = Fq + module Scalar = Fp + + let a = Params.a + + let b = Params.b + + (* checking the curve is non-singular *) + let () = + if Base.is_zero Base.((a * square a) + (of_string "27" * square b)) then + failwith "a^3 + 27 * b^2 must be different than zero" + + let cofactor = Params.cofactor + + type t = {x : Fq.t; y : Fq.t; z : Fq.t} + + let size_in_bytes = Fq.size_in_bytes * 3 + + let zero = {x = Fq.zero; y = Fq.one; z = Fq.zero} + + let is_zero t = Fq.(t.x = zero) && Fq.(t.z = zero) + + let eq t1 t2 = + if Fq.(is_zero t1.z) && Fq.(is_zero t2.z) then true + else if Fq.is_zero t1.z || Fq.is_zero t2.z then false + else + let t1z2 = Fq.(square t1.z) in + let t1z3 = Fq.(t1z2 * t1.z) in + let t2z2 = Fq.(square t2.z) in + let t2z3 = Fq.(t2z2 * t2.z) in + let x1 = Fq.(t1.x / t1z2) in + let x2 = Fq.(t2.x / t2z2) in + let y1 = Fq.(t1.y / t1z3) in + let y2 = Fq.(t2.y / t2z3) in + Fq.(x1 = x2 && y1 = y2) + + (* https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl *) + let double t = + if is_zero t then zero + else + let {x; y; z} = t in + let xx = Fq.(square x) in + let yy = Fq.(square y) in + let yyyy = Fq.(square yy) in + let zz = Fq.(square z) in + let s = Fq.(double (square (x + yy) + negate xx + negate yyyy)) in + let m = Fq.(xx + xx + xx + (a * square zz)) in + let t = Fq.(square m + negate (double s)) in + let x3 = t in + let y3 = + Fq.((m * (s + negate t)) + negate (double (double (double yyyy)))) + in + let z3 = Fq.(square (y + z) + negate yy + negate zz) in + {x = x3; y = y3; z = z3} + + (* https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#addition-add-2007-bl *) + let add t1 t2 = + if is_zero t1 then t2 + else if is_zero t2 then t1 + else if eq t1 t2 then double t1 + else + let {x = x1; y = y1; z = z1} = t1 in + let {x = x2; y = y2; z = z2} = t2 in + let z1z1 = Fq.(z1 * z1) in + let z2z2 = Fq.(z2 * z2) in + let u1 = Fq.(x1 * z2z2) in + let u2 = Fq.(x2 * z1z1) in + let s1 = Fq.(y1 * z2 * z2z2) in + let s2 = Fq.(y2 * z1 * z1z1) in + let h = Fq.(u2 + negate u1) in + let i = Fq.(square (double h)) in + let j = Fq.(h * i) in + let r = Fq.(double (s2 + negate s1)) in + let v = Fq.(u1 * i) in + let x3 = Fq.(square r + negate j + negate (double v)) in + let y3 = Fq.((r * (v + negate x3)) + negate (double (s1 * j))) in + let z3 = Fq.((square (z1 + z2) + negate z1z1 + negate z2z2) * h) in + {x = x3; y = y3; z = z3} + + let negate {x; y; z} = {x; y = Fq.negate y; z} + + let mul x n = + let rec aux x n = + let two_z = Z.succ Z.one in + if Z.equal n Z.zero then zero + else if Z.equal n Z.one then x + else + let a, r = Z.ediv_rem n two_z in + if Z.equal r Z.zero then aux (double x) a else add x (aux x (Z.pred n)) + in + aux x (Scalar.to_z n) + + let is_on_curve ~x ~y ~z = + if Fq.is_zero x && Fq.is_zero z then true + else if Fq.is_zero z then false + else + let z2 = Fq.(square z) in + let z3 = Fq.(z * z2) in + let x' = Fq.(x / z2) in + let y' = Fq.(y / z3) in + Fq.((x' * x' * x') + (a * x') + b = y' * y') + + let is_in_prime_subgroup ~x ~y ~z = + let p = {x; y; z} in + if is_zero p then true else not (is_zero (mul p (Scalar.of_z cofactor))) + + let of_bytes_opt bytes = + (* no need to copy the bytes [p] because [Bytes.sub] is used and [Bytes.sub] + creates a new buffer *) + if Bytes.length bytes <> size_in_bytes then None + else + let x_bytes = Bytes.sub bytes 0 Fq.size_in_bytes in + let y_bytes = Bytes.sub bytes Fq.size_in_bytes Fq.size_in_bytes in + let z_bytes = Bytes.sub bytes (2 * Fq.size_in_bytes) Fq.size_in_bytes in + let x = Fq.of_bytes_opt x_bytes in + let y = Fq.of_bytes_opt y_bytes in + let z = Fq.of_bytes_opt z_bytes in + match (x, y, z) with + | None, _, _ | _, None, _ | _, _, None -> None + (* Verify it is on the curve *) + | Some x, Some y, Some z -> + if Fq.is_zero x && Fq.is_zero z then Some zero + else if Fq.is_zero z then None + else if is_on_curve ~x ~y ~z && is_in_prime_subgroup ~x ~y ~z then + Some {x; y; z} + else None + + let check_bytes bytes = + match of_bytes_opt bytes with Some _ -> true | None -> false + + let of_bytes_exn b = + (* no need to copy the bytes [p] because [Bytes.sub] is used and [Bytes.sub] + creates a new buffer *) + match of_bytes_opt b with Some g -> g | None -> raise (Not_on_curve b) + + let to_bytes g = + let buffer = Bytes.make size_in_bytes '\000' in + Bytes.blit (Fq.to_bytes g.x) 0 buffer 0 Fq.size_in_bytes ; + Bytes.blit (Fq.to_bytes g.y) 0 buffer Fq.size_in_bytes Fq.size_in_bytes ; + Bytes.blit + (Fq.to_bytes g.z) + 0 + buffer + (2 * Fq.size_in_bytes) + Fq.size_in_bytes ; + buffer + + let one = of_bytes_exn Params.bytes_generator + + let random ?state () = + (match state with None -> () | Some s -> Random.set_state s) ; + let rec aux () = + let x = Fq.random () in + let y_square = Fq.((x * x * x) + (a * x) + b) in + let y_opt = Fq.sqrt_opt y_square in + match y_opt with + | None -> aux () + | Some y -> mul {x; y; z = Fq.one} (Scalar.of_z cofactor) + in + aux () + + let get_x_coordinate t = t.x + + let get_y_coordinate t = t.y + + let get_z_coordinate t = t.z + + let from_coordinates_exn ~x ~y ~z = + if is_on_curve ~x ~y ~z then {x; y; z} + else + raise + (Not_on_curve + (Bytes.concat + Bytes.empty + [Fq.to_bytes x; Fq.to_bytes y; Fq.to_bytes z])) + + let from_coordinates_opt ~x ~y ~z = + if is_on_curve ~x ~y ~z then Some {x; y; z} else None + + let get_affine_x_coordinate t = + if is_zero t then failwith "Zero" + else + let z2 = Fq.(square t.z) in + Fq.(t.x / z2) + + let get_affine_y_coordinate t = + if is_zero t then failwith "Zero" + else + let z3 = Fq.(square t.z * t.z) in + Fq.(t.y / z3) + + let from_affine_coordinates_exn ~x ~y = from_coordinates_exn ~x ~y ~z:Fq.one + + let from_affine_coordinates_opt ~x ~y = from_coordinates_exn ~x ~y ~z:Fq.one +end + +module MakeAffineWeierstrass + (Fq : Ff_sig.PRIME) + (Fp : Ff_sig.PRIME) (Params : sig + val a : Fq.t + + val b : Fq.t + + val cofactor : Z.t + + val bytes_generator : Bytes.t + end) : + Ec_sig.AffineWeierstrassT with type Scalar.t = Fp.t and type Base.t = Fq.t = +struct + let () = assert (not (Fq.is_zero Params.b)) + + exception Not_on_curve of Bytes.t + + module Base = Fq + module Scalar = Fp + + let a = Params.a + + let b = Params.b + + (* checking the curve is non-singular *) + let () = + if Base.is_zero Base.((a * square a) + (of_string "27" * square b)) then + failwith "a^3 + 27 * b^2 must be different than zero" + + let cofactor = Params.cofactor + + type t = Infinity | P of (Fq.t * Fq.t) + + let size_in_bytes = Fq.size_in_bytes * 2 + + let zero = Infinity + + let buffer_zero = Bytes.make size_in_bytes '\000' + + let is_zero t = match t with Infinity -> true | _ -> false + + let is_on_curve ~x ~y = Fq.((x * x * x) + (a * x) + b = y * y) + + let to_bytes g = + let buffer = Bytes.make size_in_bytes '\000' in + match g with + | Infinity -> buffer + | P (x, y) -> + Bytes.blit (Fq.to_bytes x) 0 buffer 0 Fq.size_in_bytes ; + Bytes.blit (Fq.to_bytes y) 0 buffer Fq.size_in_bytes Fq.size_in_bytes ; + buffer + + let eq t1 t2 = + match (t1, t2) with + | Infinity, Infinity -> true + | Infinity, _ | _, Infinity -> false + | P (x1, y1), P (x2, y2) -> Fq.(x1 = x2 && y1 = y2) + + let double t = + match t with + | Infinity -> Infinity + | P (x, y) -> + let xx = Fq.(square x) in + let xx_3_plus_a = Fq.(double xx + xx + a) in + let double_x = Fq.(double x) in + let double_y = Fq.(double y) in + let square_double_y = Fq.(square double_y) in + let x3 = + Fq.((square xx_3_plus_a / square_double_y) + negate double_x) + in + let triple_x = Fq.(x + double_x) in + let y3 = + Fq.( + (triple_x * xx_3_plus_a / double_y) + + (negate (square xx_3_plus_a * xx_3_plus_a) + / (square_double_y * double_y) + + negate y)) + in + P (x3, y3) + + (* https://hyperelliptic.org/EFD/g1p/auto-shortw.html *) + let add t1 t2 = + match (t1, t2) with + | Infinity, t2 -> t2 + | t1, Infinity -> t1 + | t1, t2 when eq t1 t2 -> double t1 + | P (x1, y1), P (x2, y2) -> + if Fq.(x1 = x2 && y1 = negate y2) then Infinity + else + let y2_min_y1 = Fq.(y2 + negate y1) in + let x2_min_x1 = Fq.(x2 + negate x1) in + let slope = Fq.(y2_min_y1 / x2_min_x1) in + let square_slope = Fq.(square slope) in + let x3 = Fq.(square_slope + negate x1 + negate x2) in + let double_x1 = Fq.(double x1) in + let double_x1_plus_x2 = Fq.(double_x1 + x2) in + let y3 = + Fq.( + (double_x1_plus_x2 * slope) + + negate (square_slope * slope) + + negate y1) + in + P (x3, y3) + + let negate p = + match p with Infinity -> Infinity | P (x, y) -> P (x, Fq.negate y) + + let mul x n = + let rec aux x n = + let two_z = Z.succ Z.one in + if Z.equal n Z.zero then zero + else if Z.equal n Z.one then x + else + let a, r = Z.ediv_rem n two_z in + if Z.equal r Z.zero then aux (double x) a else add x (aux x (Z.pred n)) + in + aux x (Scalar.to_z n) + + let is_in_prime_subgroup ~x ~y = + let p = P (x, y) in + if is_zero p then true else not (is_zero (mul p (Scalar.of_z cofactor))) + + let of_bytes_opt bytes = + (* no need to copy the bytes [p] because [Bytes.sub] is used and [Bytes.sub] + creates a new buffer *) + if Bytes.length bytes <> size_in_bytes then None + else + let x_bytes = Bytes.sub bytes 0 Fq.size_in_bytes in + let y_bytes = Bytes.sub bytes Fq.size_in_bytes Fq.size_in_bytes in + if Bytes.equal buffer_zero bytes then Some Infinity + else + let x = Fq.of_bytes_opt x_bytes in + let y = Fq.of_bytes_opt y_bytes in + match (x, y) with + | None, _ | _, None -> None + (* Verify it is on the curve *) + | Some x, Some y -> + if is_on_curve ~x ~y && is_in_prime_subgroup ~x ~y then + Some (P (x, y)) + else None + + let check_bytes bytes = + match of_bytes_opt bytes with Some _ -> true | None -> false + + let of_bytes_exn b = + (* no need to copy the bytes [p] because [Bytes.sub] is used and [Bytes.sub] + creates a new buffer *) + match of_bytes_opt b with Some g -> g | None -> raise (Not_on_curve b) + + let one = of_bytes_exn Params.bytes_generator + + let random ?state () = + (match state with None -> () | Some s -> Random.set_state s) ; + let rec aux () = + let x = Fq.random () in + let y_square = Fq.((x * x * x) + (a * x) + b) in + let y_opt = Fq.sqrt_opt y_square in + match y_opt with + | None -> aux () + | Some y -> mul (P (x, y)) (Scalar.of_z Params.cofactor) + in + aux () + + let get_x_coordinate t = + match t with Infinity -> raise (Invalid_argument "Zero") | P (x, _y) -> x + + let get_y_coordinate t = + match t with Infinity -> raise (Invalid_argument "Zero") | P (_x, y) -> y + + (* FIXME: + To have functions to Montgomery, we need to be able to compute alpha which + is a root of the equation: z^3 + a*z + b = 0 which requires the cubic root + operation in F_q. + There is an open issue in ocaml-ff: + https://gitlab.com/dannywillems/ocaml-ff/-/issues/21 + + let alpha = + let two = Fq.of_string "2" in + let four = Fq.of_string "4" in + let twenty_seven = Fq.of_string "27" in + let a_cube = Fq.(mul a (square a)) in + let b_square = Fq.square b in + let delta = Fq.( b_square + negate ( (4 * a_cube ) / twenty_seven) ) in + let sqrt_delta = Fq.sqrt_opt delta in + if Option.is_none sqr_delta then assert (1=0); + let sqrt_delta = Option.get sqr_delta in + let u = Fq.(negate ((sqrt_delta + b) / two) ) in + let v = Fq.( (sqrt_delta + negate b) / two) in + let u_cbrt = Fq.cbrt_opt u in + let v_cbrt = Fq.cbrt_opt v in + if Option.(is_none u_cbrt || is_none v_cbrt) then assert (1=0); + Fq.(u_cbrt + v_cbrt) + + let s = + let three = Fq.of_string "3" in + let aux = Fq.(three * (square alpha) + a) + let sqrt_aux = Fq.sqrt_opt aux in + if Option.is_none sqrt_aux then assert (1=0); + Fq.( 1 / (Option.get sqrt_aux) ) + + (* https://en.wikipedia.org/wiki/Montgomery_curve *) + let to_montgomery t = + match t with + | Infinity -> raise (Invalid_argument "Zero") + | P (x, y) -> + Some (Fq.(s * (x - alpha)), Fq.(s*y)) + + let to_montgomery_curve_parameters () = + let three = Fr.of_string "3" in + let cond = Fq.(three * (square alpha) * a) in + if not (Fq.is_quadratic_residue cond) then None + else + let gen = Option.get (to_montgomery one) in + let a = Fq.( three * alpha * s) in + let b = s in + Some (a, b, Params.cofactor, gen) + *) + + let from_coordinates_exn ~x ~y = + if is_on_curve ~x ~y then P (x, y) + else + raise + (Not_on_curve (Bytes.concat Bytes.empty [Fq.to_bytes x; Fq.to_bytes y])) + + let from_coordinates_opt ~x ~y = + if is_on_curve ~x ~y then Some (P (x, y)) else None + + let of_compressed_bytes_opt bs = + (* required to avoid side effect! *) + let bs = Bytes.copy bs in + let length = Bytes.length bs in + if length <> Base.size_in_bytes then None + else if bs = Bytes.make Base.size_in_bytes '\000' then Some Infinity + else + (* We get the last bit of the input, representing the bit of u. We also + remove the last bit from the bytes we received + *) + let last_byte = int_of_char @@ Bytes.get bs (length - 1) in + let sign = last_byte lsr 7 in + let last_byte_without_sign = last_byte land 0b01111111 in + Bytes.set bs (length - 1) (char_of_int last_byte_without_sign) ; + (* We compute u *) + let x = Base.of_bytes_opt bs in + match x with + | None -> None + | Some x -> ( + let yy = Base.((x * x * x) + (a * x) + b) in + let y_opt = Base.sqrt_opt yy in + let y = + match y_opt with + | None -> None + | Some y -> + (* computed before for constant time *) + let negated_y = Base.negate y in + let y_first_byte = Bytes.get (Base.to_bytes y) 0 in + let is_sign_flipped = + int_of_char y_first_byte lxor sign land 1 + in + Some (if is_sign_flipped = 0 then y else negated_y) + in + match y with + | Some y -> + if is_in_prime_subgroup ~x ~y then Some (P (x, y)) else None + | None -> None) + + let of_compressed_bytes_exn b = + match of_compressed_bytes_opt b with + | None -> raise (Not_on_curve b) + | Some p -> p + + let to_compressed_bytes p = + match p with + | Infinity -> Bytes.make Base.size_in_bytes '\000' + | P (x, y) -> + let x_bytes = Base.to_bytes x in + let y_bytes = Base.to_bytes y in + let y_first_byte = int_of_char (Bytes.get y_bytes 0) in + let x_last_byte = + int_of_char (Bytes.get x_bytes (Base.size_in_bytes - 1)) + in + (* Get the first bit of y, i.e. the sign of y *) + let sign_of_y = y_first_byte land 0b00000001 in + (* Set the last bit of the last byte of x to the sign of y *) + let x_last_byte_with_y = x_last_byte lor (sign_of_y lsl 7) in + Bytes.set + x_bytes + (Base.size_in_bytes - 1) + (char_of_int x_last_byte_with_y) ; + x_bytes +end + +module MakeProjectiveWeierstrass + (Fq : Ff_sig.PRIME) + (Fp : Ff_sig.PRIME) (Params : sig + val a : Fq.t + + val b : Fq.t + + val cofactor : Z.t + + val bytes_generator : Bytes.t + end) : + Ec_sig.ProjectiveWeierstrassT with type Scalar.t = Fp.t and type Base.t = Fq.t = +struct + let () = assert (not (Fq.is_zero Params.b)) + + exception Not_on_curve of Bytes.t + + module Base = Fq + module Scalar = Fp + + let a = Params.a + + let b = Params.b + + (* checking the curve is non-singular *) + let () = + if Base.is_zero Base.((a * square a) + (of_string "27" * square b)) then + failwith "a^3 + 27 * b^2 must be different than zero" + + let cofactor = Params.cofactor + + type t = {x : Fq.t; y : Fq.t; z : Fq.t} + + let size_in_bytes = Fq.size_in_bytes * 3 + + let zero = {x = Fq.zero; y = Fq.one; z = Fq.zero} + + let is_zero t = Fq.(t.x = zero) && Fq.(t.z = zero) + + let is_on_curve ~x ~y ~z = + if Fq.is_zero x && Fq.is_zero z then true + else if Fq.is_zero z then false + else + let x' = Fq.(x / z) in + let y' = Fq.(y / z) in + Fq.((x' * x' * x') + (a * x') + b = y' * y') + + let add t1 t2 = + (* See https://github.com/o1-labs/snarky/blob/master/snarkette/elliptic_curve.ml *) + if is_zero t1 then t2 + else if is_zero t2 then t1 + else + let open Fq in + let x1z2 = t1.x * t2.z in + let x2z1 = t1.z * t2.x in + let y1z2 = t1.y * t2.z in + let y2z1 = t1.z * t2.y in + if x1z2 = x2z1 && y1z2 = y2z1 then + (* Double case *) + let xx = square t1.x in + let zz = square t1.z in + let w = (a * zz) + (xx + xx + xx) in + let y1z1 = t1.y * t1.z in + let s = y1z1 + y1z1 in + let ss = square s in + let sss = s * ss in + let r = t1.y * s in + let rr = square r in + let b = square (t1.x + r) + negate xx + negate rr in + let h = square w + negate (b + b) in + let x3 = h * s in + let y3 = (w * (b + negate h)) + negate (rr + rr) in + let z3 = sss in + {x = x3; y = y3; z = z3} + else + (* Generic case *) + let z1z2 = t1.z * t2.z in + let u = y2z1 + negate y1z2 in + let uu = square u in + let v = x2z1 + negate x1z2 in + let vv = square v in + let vvv = v * vv in + let r = vv * x1z2 in + let a = (uu * z1z2) + negate (vvv + r + r) in + let x3 = v * a in + let y3 = (u * (r + negate a)) + negate (vvv * y1z2) in + let z3 = vvv * z1z2 in + {x = x3; y = y3; z = z3} + + let double t = add t t + + let negate {x; y; z} = {x; y = Fq.negate y; z} + + let eq t1 t2 = + if Fq.(is_zero t1.z) && Fq.(is_zero t2.z) then true + else if Fq.is_zero t1.z || Fq.is_zero t2.z then false + else + let x1 = Fq.(t1.x / t1.z) in + let x2 = Fq.(t2.x / t2.z) in + let y1 = Fq.(t1.y / t1.z) in + let y2 = Fq.(t2.y / t2.z) in + Fq.(x1 = x2 && y1 = y2) + + let mul x n = + let rec aux x n = + let two_z = Z.succ Z.one in + if Z.equal n Z.zero then zero + else if Z.equal n Z.one then x + else + let a, r = Z.ediv_rem n two_z in + if Z.equal r Z.zero then aux (double x) a else add x (aux x (Z.pred n)) + in + aux x (Scalar.to_z n) + + let is_in_prime_subgroup ~x ~y ~z = + let p = {x; y; z} in + if is_zero p then true else not (is_zero (mul p (Scalar.of_z cofactor))) + + let of_bytes_opt bytes = + (* no need to copy the bytes [p] because [Bytes.sub] is used and [Bytes.sub] + creates a new buffer *) + if Bytes.length bytes <> size_in_bytes then None + else + let x_bytes = Bytes.sub bytes 0 Fq.size_in_bytes in + let y_bytes = Bytes.sub bytes Fq.size_in_bytes Fq.size_in_bytes in + let z_bytes = Bytes.sub bytes (2 * Fq.size_in_bytes) Fq.size_in_bytes in + let x = Fq.of_bytes_opt x_bytes in + let y = Fq.of_bytes_opt y_bytes in + let z = Fq.of_bytes_opt z_bytes in + match (x, y, z) with + | None, _, _ | _, None, _ | _, _, None -> None + (* Verify it is on the curve *) + | Some x, Some y, Some z -> + if Fq.is_zero x && Fq.is_zero z then Some zero + else if Fq.is_zero z then None + else if is_on_curve ~x ~y ~z && is_in_prime_subgroup ~x ~y ~z then + Some {x; y; z} + else None + + let check_bytes bytes = + match of_bytes_opt bytes with Some _ -> true | None -> false + + let of_bytes_exn b = + (* no need to copy the bytes [p] because [Bytes.sub] is used and [Bytes.sub] + creates a new buffer *) + match of_bytes_opt b with Some g -> g | None -> raise (Not_on_curve b) + + let to_bytes g = + let buffer = Bytes.make size_in_bytes '\000' in + Bytes.blit (Fq.to_bytes g.x) 0 buffer 0 Fq.size_in_bytes ; + Bytes.blit (Fq.to_bytes g.y) 0 buffer Fq.size_in_bytes Fq.size_in_bytes ; + Bytes.blit + (Fq.to_bytes g.z) + 0 + buffer + (2 * Fq.size_in_bytes) + Fq.size_in_bytes ; + buffer + + let one = of_bytes_exn Params.bytes_generator + + let random ?state () = + (match state with None -> () | Some s -> Random.set_state s) ; + let rec aux () = + let x = Fq.random () in + let y_square = Fq.((x * x * x) + (a * x) + b) in + let y_opt = Fq.sqrt_opt y_square in + match y_opt with + | None -> aux () + | Some y -> mul {x; y; z = Fq.one} (Scalar.of_z cofactor) + in + aux () + + let get_x_coordinate t = t.x + + let get_y_coordinate t = t.y + + let get_z_coordinate t = t.z + + let from_coordinates_exn ~x ~y ~z = + if is_on_curve ~x ~y ~z && is_in_prime_subgroup ~x ~y ~z then {x; y; z} + else + raise + (Not_on_curve + (Bytes.concat + Bytes.empty + [Fq.to_bytes x; Fq.to_bytes y; Fq.to_bytes z])) + + let from_coordinates_opt ~x ~y ~z = + if is_on_curve ~x ~y ~z && is_in_prime_subgroup ~x ~y ~z then Some {x; y; z} + else None + + let get_affine_x_coordinate t = + if is_zero t then failwith "Zero" else Fq.(t.x / t.z) + + let get_affine_y_coordinate t = + if is_zero t then failwith "Zero" else Fq.(t.y / t.z) + + let from_affine_coordinates_exn ~x ~y = from_coordinates_exn ~x ~y ~z:Fq.one + + let from_affine_coordinates_opt ~x ~y = from_coordinates_exn ~x ~y ~z:Fq.one +end + +module MakeAffineMontgomery + (Fq : Ff_sig.PRIME) + (Fp : Ff_sig.PRIME) (Params : sig + val a : Fq.t + + val b : Fq.t + + val cofactor : Z.t + + val bytes_generator : Bytes.t + end) : + Ec_sig.AffineMontgomeryT with type Scalar.t = Fp.t and type Base.t = Fq.t = +struct + (* Costello, Craig, and Benjamin Smith. "Montgomery curves and their + arithmetic." + Journal of Cryptographic Engineering 8.3 (2018): 227-240. + (https://arxiv.org/pdf/1703.01863.pdf) *) + + (* Summary for the complexity: + Addition: 6A + 1AC + 1M + 1MC + 4N + 1DI + Doubling: 4A + 2AC + 1M + 4MC + 3N + 1DI + 1DO + 2SQ + *) + + (* Checking non-singularity: + - if b=0 then the Curve is a union of 3 lines; + if a^2=4 then the curve is a nodal cubic. *) + let () = assert (not Fq.(eq (square Params.a) (Fq.of_string "4"))) + + let () = assert (not (Fq.is_zero Params.b)) + + exception Not_on_curve of Bytes.t + + module Base = Fq + module Scalar = Fp + + (* used later in addition and doubling formulas *) + let two = Fq.(one + one) + + let three = Fq.(one + two) + + let a = Params.a + + let two_a = Fq.mul two a + + let b = Params.b + + let two_b = Fq.mul two b + + let three_b = Fq.mul three b + + let cofactor = Params.cofactor + + type t = Infinity | P of (Fq.t * Fq.t) + + let size_in_bytes = Fq.size_in_bytes * 2 + + let zero = Infinity + + let buffer_zero = Bytes.make size_in_bytes '\000' + + let is_zero t = match t with Infinity -> true | _ -> false + + let eq t1 t2 = + match (t1, t2) with + | Infinity, Infinity -> true + | Infinity, _ | _, Infinity -> false + | P (x1, y1), P (x2, y2) -> Fq.(x1 = x2 && y1 = y2) + + (* The operation for adding two points are the same whether we add the same or + distinct points + except for the calculus of the slope. + (https://arxiv.org/pdf/1703.01863.pdf) + + Let P(x_p, y_p) + P(x_q, y_q) = P(x_r, y_r), then + x_r = Params.b * slope^2 - (x_p + x_q) - Params.a + y_r = (2 * x_p + x_ q + Params.a) * slope - Params.b * slope^3 - y_p + = slope * (x_p - x_q) - y_p + *) + (* Complexity (update above summary if any change): + 1SQ + + 1MC + 1MC + 1A + 1AC + 1MC + 1DI -> 3MC + 1A + 1AC + 1DI (SLOPE COMPUTATION) + + 1SQ + 1DO + 1MC + 1AC + 1N + 1A (X COMPUTATION) + + 1N + 1N + 1A + 1M + 1A -> 2N + 2A + 1M (Y COMPUTATION USING X) + Total: + 4A + 2AC + 1M + 4MC + 3N + 1DI + 1DO + 2SQ + *) + let double t = + match t with + | Infinity -> Infinity + | P (x, y) -> + (* Slope computation *) + let xx = Fq.(square x) in + (* slope = (3 * x^2 + 2 * Params.a * x + 1) / (2 * Params.b * y) *) + let three_xx = Fq.(three * xx) in + let two_a_x = Fq.(two_a * x) in + let l_num = Fq.(three_xx + two_a_x) in + let l_num = Fq.(l_num + Fq.one) in + let l_div = Fq.(two_b * y) in + let l = Fq.(l_num / l_div) in + (* x computation *) + let ll = Fq.square l in + let two_x = Fq.double x in + let b_ll = Fq.(b * ll) in + let a_two_x = Fq.(a + two_x) in + let neg_a_two_x = Fq.(negate a_two_x) in + let x3 = Fq.(b_ll + neg_a_two_x) in + (* computing y3 by using x3, see 2.2. There is a typo when giving a + shorter formula for y. It must be x_plus instead of x_q + *) + let neg_x3 = Fq.negate x3 in + let neg_y = Fq.negate y in + let x_plus_neg_x3 = Fq.(x + neg_x3) in + let l_x_plus_neg_x3 = Fq.(l * x_plus_neg_x3) in + let y3 = Fq.(l_x_plus_neg_x3 + neg_y) in + P (x3, y3) + + (* Complexity (update above summary if any change): + (SLOPE COMPUTATION) + 1N + 1N + 1A + 1A + 1DI + -> 2A + 2N + 1DI + (X COMPUTATION) + + 1SQ + 1A + 1MC + 1AC + 1N + 1A + -> 2A + 1AC + 1MC + 1N + 1SQ + (Y COMPUTATION) + + 1N + 1A + 1M + 1A + -> 2A + 1M + 1N + Total: + 6A + 1AC + 1M + 1MC + 4N + 1DI + *) + let add t1 t2 = + match (t1, t2) with + | Infinity, t2 -> t2 + | t1, Infinity -> t1 + | t1, t2 when eq t1 t2 -> double t1 + | P (x1, y1), P (x2, y2) -> + if Fq.(x1 = x2 && y1 = negate y2) then Infinity + else + (* slope = (y2 - y1) / (x2 - x1) *) + let neg_y1 = Fq.(negate y1) in + let neg_x1 = Fq.(negate x1) in + let y2_min_y1 = Fq.(y2 + neg_y1) in + let x2_min_x1 = Fq.(x2 + neg_x1) in + let l = Fq.(y2_min_y1 / x2_min_x1) in + (* x computation *) + let ll = Fq.(square l) in + let x2_plus_x1 = Fq.(x1 + x2) in + let b_ll = Fq.(b * ll) in + let a_plus_x2_plus_x1 = Fq.(a + x2_plus_x1) in + let neg_a_plus_x2_plus_x1 = Fq.(negate a_plus_x2_plus_x1) in + let x3 = Fq.(b_ll + neg_a_plus_x2_plus_x1) in + (* y computation + Cost improvement by using x3 directly: + 3A + 1AC + 2M + 1MC -> 2A + 1M + 1N + Saving 1A, 1AC, 1M, 1MC and costs 1 extra N + *) + let neg_x3 = Fq.(negate x3) in + let x1_min_x3 = Fq.(x1 + neg_x3) in + let l_x1_min_x3 = Fq.(l * x1_min_x3) in + let y3 = Fq.(l_x1_min_x3 + neg_y1) in + P (x3, y3) + + let negate p = + match p with Infinity -> Infinity | P (x, y) -> P (x, Fq.negate y) + + let mul x n = + let rec aux x n = + let two_z = Z.succ Z.one in + if Z.equal n Z.zero then zero + else if Z.equal n Z.one then x + else + let a, r = Z.ediv_rem n two_z in + if Z.equal r Z.zero then aux (double x) a else add x (aux x (Z.pred n)) + in + aux x (Scalar.to_z n) + + let is_on_curve ~x ~y = + let xx = Fq.square x in + let yy = Fq.square y in + Fq.((x * xx) + (a * xx) + x = b * yy) + + let is_in_prime_subgroup ~x ~y = + let p = P (x, y) in + if is_zero p then true else not (is_zero (mul p (Scalar.of_z cofactor))) + + let of_bytes_opt bytes = + (* no need to copy the bytes [p] because [Bytes.sub] is used and [Bytes.sub] + creates a new buffer *) + if Bytes.length bytes <> size_in_bytes then None + else + let x_bytes = Bytes.sub bytes 0 Fq.size_in_bytes in + let y_bytes = Bytes.sub bytes Fq.size_in_bytes Fq.size_in_bytes in + if Bytes.equal buffer_zero bytes then Some Infinity + else + let x = Fq.of_bytes_opt x_bytes in + let y = Fq.of_bytes_opt y_bytes in + match (x, y) with + | None, _ | _, None -> None + (* Verify it is on the curve *) + | Some x, Some y -> + if is_on_curve ~x ~y && is_in_prime_subgroup ~x ~y then + Some (P (x, y)) + else None + + let check_bytes bytes = + match of_bytes_opt bytes with Some _ -> true | None -> false + + let of_bytes_exn b = + (* no need to copy the bytes [p] because [Bytes.sub] is used and [Bytes.sub] + creates a new buffer *) + match of_bytes_opt b with Some g -> g | None -> raise (Not_on_curve b) + + let to_bytes g = + let buffer = Bytes.make size_in_bytes '\000' in + match g with + | Infinity -> buffer + | P (x, y) -> + Bytes.blit (Fq.to_bytes x) 0 buffer 0 Fq.size_in_bytes ; + Bytes.blit (Fq.to_bytes y) 0 buffer Fq.size_in_bytes Fq.size_in_bytes ; + buffer + + let one = of_bytes_exn Params.bytes_generator + + let is_in_prime_subgroup ~x ~y = + let p = P (x, y) in + if is_zero p then true else not (is_zero (mul p (Scalar.of_z cofactor))) + + let random ?state () = + (match state with None -> () | Some s -> Random.set_state s) ; + let rec aux () = + let x = Fq.random () in + let xx = Fq.mul x x in + let y_square = Fq.(((x * xx) + (a * xx) + x) / b) in + let y_opt = Fq.sqrt_opt y_square in + match y_opt with + | None -> aux () + | Some y -> mul (P (x, y)) (Scalar.of_z Params.cofactor) + in + aux () + + let get_x_coordinate t = + match t with Infinity -> raise (Invalid_argument "Zero") | P (x, _y) -> x + + let get_y_coordinate t = + match t with Infinity -> raise (Invalid_argument "Zero") | P (_x, y) -> y + + (* https://en.wikipedia.org/wiki/Montgomery_curve *) + let to_twisted t = + match t with + | Infinity -> raise (Invalid_argument "Zero") + | P (x, y) -> + if Fq.is_zero y || Fq.(is_zero (one + x)) then None + else Some Fq.(x / y, (x + negate one) / (x + one)) + + let to_twisted_curve_parameters () = + let gen = to_twisted one in + if Option.is_none gen then None + else + let a = Fq.((Params.a + two) / Params.b) in + let d = Fq.((Params.a + negate two) / Params.b) in + Some (a, d, Params.cofactor, Option.get gen) + + (* https://en.wikipedia.org/wiki/Montgomery_curve *) + let to_weierstrass t = + match t with + | Infinity -> raise (Invalid_argument "Zero") + | P (x, y) -> + let x = Fq.((x / b) + (a / three_b)) in + let y = Fq.(y / b) in + Some (x, y) + + let to_weierstrass_curve_parameters () = + let gen = to_weierstrass one in + if Option.is_none gen then None + else + let nine = Fq.of_string "9" in + let twenty_seven = Fq.of_string "27" in + let a_square = Fq.square Params.a in + let a_cube = Fq.mul a a_square in + let b_square = Fq.square Params.b in + let b_cube = Fq.mul b b_square in + let d = + Fq.(((two * a_cube) + (negate nine * a)) / (twenty_seven * b_cube)) + in + let a = Fq.((three + negate a_square) / (three * b_square)) in + Some (a, d, Params.cofactor, Option.get gen) + + let from_coordinates_exn ~x ~y = + if is_on_curve ~x ~y && is_in_prime_subgroup ~x ~y then P (x, y) + else + raise + (Not_on_curve (Bytes.concat Bytes.empty [Fq.to_bytes x; Fq.to_bytes y])) + + let from_coordinates_opt ~x ~y = + if is_on_curve ~x ~y && is_in_prime_subgroup ~x ~y then Some (P (x, y)) + else None + + let of_compressed_bytes_opt bs = + (* required to avoid side effect! *) + let bs = Bytes.copy bs in + let length = Bytes.length bs in + if length <> Base.size_in_bytes then None + else if bs = Bytes.make Base.size_in_bytes '\000' then Some Infinity + else + (* We get the last bit of the input, representing the bit of u. We also + remove the last bit from the bytes we received + *) + let last_byte = int_of_char @@ Bytes.get bs (length - 1) in + let sign = last_byte lsr 7 in + let last_byte_without_sign = last_byte land 0b01111111 in + Bytes.set bs (length - 1) (char_of_int last_byte_without_sign) ; + (* We compute u *) + let x = Base.of_bytes_opt bs in + match x with + | None -> None + | Some x -> ( + let xx = Base.mul x x in + let yy = Base.(((x * xx) + (a * xx) + x) / b) in + let y_opt = Base.sqrt_opt yy in + let y = + match y_opt with + | None -> None + | Some y -> + (* computed before for constant time *) + let negated_y = Base.negate y in + let y_first_byte = Bytes.get (Base.to_bytes y) 0 in + let is_sign_flipped = + int_of_char y_first_byte lxor sign land 1 + in + Some (if is_sign_flipped = 0 then y else negated_y) + in + match y with + | Some y -> + let p = P (x, y) in + if is_in_prime_subgroup ~x ~y then Some p else None + | None -> None) + + let of_compressed_bytes_exn b = + match of_compressed_bytes_opt b with + | None -> raise (Not_on_curve b) + | Some p -> p + + let to_compressed_bytes p = + match p with + | Infinity -> Bytes.make Base.size_in_bytes '\000' + | P (x, y) -> + let x_bytes = Base.to_bytes x in + let y_bytes = Base.to_bytes y in + let y_first_byte = int_of_char (Bytes.get y_bytes 0) in + let x_last_byte = + int_of_char (Bytes.get x_bytes (Base.size_in_bytes - 1)) + in + (* Get the first bit of y, i.e. the sign of y *) + let sign_of_y = y_first_byte land 0b00000001 in + (* Set the last bit of the last byte of x to the sign of y *) + let x_last_byte_with_y = x_last_byte lor (sign_of_y lsl 7) in + Bytes.set + x_bytes + (Base.size_in_bytes - 1) + (char_of_int x_last_byte_with_y) ; + x_bytes +end + +module MakeAffineEdwards + (Base : Ff_sig.PRIME) + (Scalar : Ff_sig.PRIME) (Params : sig + val a : Base.t + + val d : Base.t + + val cofactor : Z.t + + val bytes_generator : Bytes.t + end) : + Ec_sig.AffineEdwardsT with type Base.t = Base.t and type Scalar.t = Scalar.t = +struct + (* https://www.hyperelliptic.org/EFD/g1p/auto-twisted.html *) + (* https://en.wikipedia.org/wiki/Twisted_Edwards_curve *) + + (* Summary for the complexity: + Addition: 2A + 2AC + 5M + 2MC + 2N + 2DI + Doubling: 3A + 1AC + 1M + 1MC + 2N + 2DI + 1DO + 2SQ + *) + exception Not_on_curve of Bytes.t + + module Scalar = Scalar + module Base = Base + include Params + + let () = + (* Addition formula is complete if d is a not a square *) + assert (Option.is_none (Base.sqrt_opt d)) + + let size_in_bytes = Base.size_in_bytes * 2 + + type t = {u : Base.t; v : Base.t} + + let zero = {u = Base.zero; v = Base.one} + + let is_zero {u; v} = Base.(u = zero) && Base.(v = one) + + let to_bytes {u; v} = + Bytes.concat Bytes.empty [Base.to_bytes u; Base.to_bytes v] + + (* Complexity (update above summary if any change): + 2A + 2AC + 5M + 2MC + 2N + 2DI + *) + let add {u = u1; v = v1} {u = u2; v = v2} = + let u1v2 = Base.(u1 * v2) in + let v1u2 = Base.(v1 * u2) in + let u1u2v1v2 = Base.(u1v2 * v1u2) in + let v1v2 = Base.(v1 * v2) in + let u1u2 = Base.(u1 * u2) in + let du1u2v1v2 = Base.(d * u1u2v1v2) in + let u = Base.((u1v2 + v1u2) / (Base.one + du1u2v1v2)) in + let v = + Base.( + (v1v2 + Base.negate (a * u1u2)) / (Base.one + Base.negate du1u2v1v2)) + in + {u; v} + + (* used in doubling *) + let two = Base.(one + one) + + (* Complexity (update above summary if any change) + 3A + 1AC + 1M + 1MC + 2N + 2DI + 1DO + 2SQ + *) + let double {u; v} = + let uv = Base.(u * v) in + let uu = Base.square u in + let vv = Base.square v in + let neg_uu = Base.negate uu in + let neg_vv = Base.negate vv in + let a_uu = Base.(a * uu) in + let a_neguu = Base.(a * neg_uu) in + (* a u^2 v^2 = 1 + d u^2 v^2 --> we can skip one multiplication *) + let u' = Base.(double uv / (a_uu + vv)) in + let v' = Base.((vv + a_neguu) / (two + a_neguu + neg_vv)) in + {u = u'; v = v'} + + let negate {u; v} = {u = Base.negate u; v} + + let eq {u = u1; v = v1} {u = u2; v = v2} = Base.(u1 = u2 && v1 = v2) + + let mul x n = + let rec aux x n = + let two_z = Z.succ Z.one in + if Z.equal n Z.zero then zero + else if Z.equal n Z.one then x + else + let q, r = Z.ediv_rem n two_z in + let x_plus_x = double x in + if Z.equal r Z.zero then aux x_plus_x q else add x (aux x_plus_x q) + in + aux x (Scalar.to_z n) + + let is_on_curve ~u ~v = + (* a * u^2 + v^2 = 1 + d u^2 v^2 *) + let uu = Base.square u in + let vv = Base.square v in + let uuvv = Base.(uu * vv) in + Base.((a * uu) + vv = one + (d * uuvv)) + + let is_in_prime_subgroup ~u ~v = + let p = {u; v} in + if is_zero p then true else not (is_zero (mul p (Scalar.of_z cofactor))) + + let of_bytes_opt b = + (* no need to copy the bytes [p] because [Bytes.sub] is used and [Bytes.sub] + creates a new buffer *) + if Bytes.length b <> size_in_bytes then None + else + let u_opt = Base.of_bytes_opt (Bytes.sub b 0 Base.size_in_bytes) in + let v_opt = + Base.of_bytes_opt (Bytes.sub b Base.size_in_bytes Base.size_in_bytes) + in + match (u_opt, v_opt) with + | Some u, Some v -> + if is_on_curve ~u ~v && is_in_prime_subgroup ~u ~v then Some {u; v} + else None + | _ -> None + + let of_bytes_exn b = + (* no need to copy the bytes [p] because [Bytes.sub] is used in + [of_bytes_opt] and [Bytes.sub] creates a new buffer *) + match of_bytes_opt b with None -> raise (Not_on_curve b) | Some p -> p + + let check_bytes b = match of_bytes_opt b with None -> false | Some _ -> true + + let one = of_bytes_exn bytes_generator + + let rec random ?state () = + let () = match state with Some s -> Random.set_state s | None -> () in + let u = Base.random ?state:None () in + let uu = Base.(square u) in + let auu = Base.(a * uu) in + let duu = Base.(d * uu) in + if Base.(is_one duu) then random ?state:None () + else + (* a u^2 + v^2 = 1 + d u^2 v^2 *) + (* <==> a u^2 + v^2 - d u^2 v^2 = 1 *) + (* <==> v^2 - d u^2 v^2 = 1 - a u^2 *) + (* <==> v^2 * (1 - d u^2) = 1 - a u^2 *) + (* <==> v^2 = (1 - a * u^2) / (1 - d * u^2) *) + let tmp = Base.((one + negate auu) / (one + negate duu)) in + let v_sqrt = Base.(sqrt_opt tmp) in + match v_sqrt with + | None -> random ?state:None () + | Some v -> + let p = mul {u; v} (Scalar.of_z cofactor) in + if eq p zero then random ?state:None () else p + + let get_u_coordinate p = p.u + + let get_v_coordinate p = p.v + + (* https://en.wikipedia.org/wiki/Montgomery_curve *) + let to_montgomery p = + match (p.u, p.v) with + | u, v when Base.(is_zero u && is_one v) -> raise (Invalid_argument "Zero") + | u, v -> + assert (not Base.(eq a d)) ; + if Base.is_zero u || Base.(is_zero (one + v)) then None + else + let one_plus_v = Base.(one + v) in + let one_minus_v = Base.(one + negate v) in + let x = Base.(one_plus_v / one_minus_v) in + let y = Base.(x / u) in + Some (x, y) + + let to_montgomery_curve_parameters () = + let gen = to_montgomery one in + if Option.is_none gen then None + else + let gen = Option.get gen in + let two = Base.of_string "2" in + let four = Base.of_string "4" in + let a_min_d = Base.(a + negate d) in + let b = Base.(four / a_min_d) in + let a = Base.(two * (a + d) / a_min_d) in + Some (a, b, Params.cofactor, gen) + + let from_coordinates_opt ~u ~v = + let p = {u; v} in + if is_on_curve ~u ~v && is_in_prime_subgroup ~u ~v then Some p else None + + let from_coordinates_exn ~u ~v = + match from_coordinates_opt ~u ~v with + | None -> + raise + (Not_on_curve + (Bytes.concat Bytes.empty [Base.to_bytes u; Base.to_bytes v])) + | Some p -> p + + let unsafe_from_coordinates ~u ~v = {u; v} +end + +let from_affine_weierstrass_to_jacobian_weierstrass + (type affine jacobian base scalar) + (module Affine : Ec_sig.AffineWeierstrassT + with type t = affine + and type Base.t = base + and type Scalar.t = scalar) + (module Jacobian : Ec_sig.JacobianWeierstrassT + with type t = jacobian + and type Base.t = base + and type Scalar.t = scalar) (p_affine : affine) : jacobian = + if Affine.is_zero p_affine then Jacobian.zero + else + let x = Affine.get_x_coordinate p_affine in + let y = Affine.get_y_coordinate p_affine in + Jacobian.from_affine_coordinates_exn ~x ~y + +let from_jacobian_weierstrass_to_affine_weierstrass + (type affine jacobian base scalar) + (module Jacobian : Ec_sig.JacobianWeierstrassT + with type t = jacobian + and type Base.t = base + and type Scalar.t = scalar) + (module Affine : Ec_sig.AffineWeierstrassT + with type t = affine + and type Base.t = base + and type Scalar.t = scalar) (p_jacobian : jacobian) : affine = + if Jacobian.is_zero p_jacobian then Affine.zero + else + let x = Jacobian.get_x_coordinate p_jacobian in + let y = Jacobian.get_y_coordinate p_jacobian in + let z = Jacobian.get_z_coordinate p_jacobian in + let zz = Jacobian.Base.square z in + let zzz = Jacobian.Base.(z * zz) in + let x' = Jacobian.Base.(x / zz) in + let y' = Jacobian.Base.(y / zzz) in + Affine.from_coordinates_exn ~x:x' ~y:y' + +let from_affine_weierstrass_to_projective_weierstrass + (type affine projective base scalar) + (module Affine : Ec_sig.AffineWeierstrassT + with type t = affine + and type Base.t = base + and type Scalar.t = scalar) + (module Projective : Ec_sig.ProjectiveWeierstrassT + with type t = projective + and type Base.t = base + and type Scalar.t = scalar) (p_affine : affine) : projective = + if Affine.is_zero p_affine then Projective.zero + else + let x = Affine.get_x_coordinate p_affine in + let y = Affine.get_y_coordinate p_affine in + Projective.from_affine_coordinates_exn ~x ~y + +let from_projective_weierstrass_to_affine_weierstrass + (type affine projective base scalar) + (module Projective : Ec_sig.ProjectiveWeierstrassT + with type t = projective + and type Base.t = base + and type Scalar.t = scalar) + (module Affine : Ec_sig.AffineWeierstrassT + with type t = affine + and type Base.t = base + and type Scalar.t = scalar) (p_projective : projective) : affine = + if Projective.is_zero p_projective then Affine.zero + else + let x = Projective.get_x_coordinate p_projective in + let y = Projective.get_y_coordinate p_projective in + let z = Projective.get_z_coordinate p_projective in + let x' = Projective.Base.(x / z) in + let y' = Projective.Base.(y / z) in + Affine.from_coordinates_exn ~x:x' ~y:y' + +let from_affine_montgomery_to_affine_weierstrass + (type affine_mt affine_wt base scalar) + (module Affine_mt : Ec_sig.AffineMontgomeryT + with type t = affine_mt + and type Base.t = base + and type Scalar.t = scalar) + (module Affine_wt : Ec_sig.AffineWeierstrassT + with type t = affine_wt + and type Base.t = base + and type Scalar.t = scalar) (p_mt : affine_mt) : affine_wt option = + let coords_opt = Affine_mt.to_weierstrass p_mt in + Option.bind coords_opt (fun (x, y) -> Affine_wt.from_coordinates_opt ~x ~y) + +(* let from_weierstrass_montgomery (type affine_wt affine_mt base scalar) + (module Affine_wt : Ec_sig.AffineWeierstrassT + with type t = affine_wt + and type Base.t = base + and type Scalar.t = scalar) + (module Affine_mt : Ec_sig.AffineMontgomeryT + with type t = affine_mt + and type Base.t = base + and type Scalar.t = scalar) (p_wt : affine_wt) : affine_mt option = + let coords_opt = Affine_wt.to_montgomery p_wt in + Option.bind coords_opt (fun (x, y) -> Affine_mt.from_coordinates_opt ~x ~y) *) + +let from_affine_montgomery_to_affine_edwards + (type affine_mt affine_tw base scalar) + (module Affine_mt : Ec_sig.AffineMontgomeryT + with type t = affine_mt + and type Base.t = base + and type Scalar.t = scalar) + (module Affine_tw : Ec_sig.AffineEdwardsT + with type t = affine_tw + and type Base.t = base + and type Scalar.t = scalar) (p_mt : affine_mt) : affine_tw option = + let coords_opt = Affine_mt.to_twisted p_mt in + Option.bind coords_opt (fun (u, v) -> Affine_tw.from_coordinates_opt ~u ~v) + +let from_affine_edwards_to_affine_montgomery + (type affine_tw affine_mt base scalar) + (module Affine_tw : Ec_sig.AffineEdwardsT + with type t = affine_tw + and type Base.t = base + and type Scalar.t = scalar) + (module Affine_mt : Ec_sig.AffineMontgomeryT + with type t = affine_mt + and type Base.t = base + and type Scalar.t = scalar) (p_tw : affine_tw) : affine_mt option = + let coords_opt = Affine_tw.to_montgomery p_tw in + Option.bind coords_opt (fun (x, y) -> Affine_mt.from_coordinates_opt ~x ~y) + +module MakeAffineEdwardsToAffineMontgomery (E : Ec_sig.AffineEdwardsT) : + Ec_sig.AffineMontgomeryT + with module Base = E.Base + and module Scalar = E.Scalar = + MakeAffineMontgomery (E.Base) (E.Scalar) + (struct + let two = E.Base.(double one) + + let four = E.Base.(double two) + + let a_neg_d = E.Base.(E.a + negate E.d) + + let a = E.Base.(two * (E.a + E.d) / a_neg_d) + + let b = E.Base.(four / a_neg_d) + + let cofactor = E.cofactor + + let bytes_generator = + let u = E.get_u_coordinate E.one in + let v = E.get_v_coordinate E.one in + let one_plus_v = E.Base.(one + v) in + let one_minus_v = E.Base.(one + negate v) in + let x = E.Base.(one_plus_v / one_minus_v) in + let y = E.Base.(x / u) in + Bytes.concat Bytes.empty [E.Base.to_bytes x; E.Base.to_bytes y] + end) diff --git a/src/lib_mec/ec_pbt.ml b/src/lib_mec/ec_pbt.ml new file mode 100644 index 000000000000..36996023a4f6 --- /dev/null +++ b/src/lib_mec/ec_pbt.ml @@ -0,0 +1,554 @@ +let rec repeat n f () = + if n > 0 then ( + f () ; + repeat (n - 1) f ()) + +module MakeEquality (G : Ec_sig.BASE) = struct + (** Verify the equality is correct with the value zero *) + let zero () = assert (G.eq G.zero G.zero) + + (** Verify the equality is correct with the value one *) + let one () = assert (G.eq G.one G.one) + + (** Verify the equality of two random values created invidually *) + let random_same_objects () = + let random = G.random () in + assert (G.eq random random) + + (** Returns the tests to be used with Alcotest *) + let get_tests () = + let open Alcotest in + ( "equality", + [ + test_case "zero" `Quick (repeat 1 zero); + test_case "one" `Quick (repeat 1 one); + test_case "random_same_objects" `Quick (repeat 100 random_same_objects); + ] ) +end + +module MakeValueGeneration (G : Ec_sig.BASE) = struct + let random () = ignore @@ G.random () + + let negation_with_random () = + let random = G.random () in + ignore @@ G.negate random + + let negation_with_zero () = ignore @@ G.negate G.zero + + let negation_with_one () = ignore @@ G.negate G.one + + let double_with_zero () = ignore @@ G.double G.zero + + let double_with_one () = ignore @@ G.double G.one + + let double_with_random () = + let g = G.random () in + ignore @@ G.double g + + let addition_generates_valid_point () = + assert (G.(check_bytes (to_bytes (add (random ()) (random ()))))) + + let double_generates_valid_point () = + assert (G.(check_bytes (to_bytes (double (random ()))))) + + let scalar_multiplication_generates_valid_point () = + assert (G.(check_bytes (to_bytes (mul (random ()) (Scalar.random ()))))) + + let check_bytes_random_with_to_bytes () = + let g = G.random () in + assert (G.(check_bytes (to_bytes g))) + + let negate_generates_a_valid_point () = + let g = G.random () in + assert (G.(check_bytes (to_bytes (negate g)))) + + let of_bytes_with_to_bytes_are_inverse_functions () = + let g = G.random () in + assert (G.(eq (of_bytes_exn (to_bytes g)) g)) + + (** Returns the tests to be used with Alcotest *) + let get_tests () = + let open Alcotest in + ( "value generation", + [ + test_case "random" `Quick (repeat 100 random); + test_case "negate_with_one" `Quick (repeat 1 negation_with_one); + test_case "negate_with_zero" `Quick (repeat 1 negation_with_zero); + test_case "negate_with_random" `Quick (repeat 100 negation_with_random); + test_case "double_with_random" `Quick (repeat 100 double_with_random); + test_case + "negate generates a valid point" + `Quick + (repeat 100 negate_generates_a_valid_point); + test_case + "addition generates a valid point" + `Quick + (repeat 100 addition_generates_valid_point); + test_case + "double generates a valid point" + `Quick + (repeat 100 double_generates_valid_point); + test_case + "scalar multiplication generates a valid point" + `Quick + (repeat 100 scalar_multiplication_generates_valid_point); + test_case + "of_bytes_exn and to_bytes are inverse functions" + `Quick + (repeat 100 of_bytes_with_to_bytes_are_inverse_functions); + test_case + "check bytes on random with to_bytes" + `Quick + (repeat 100 check_bytes_random_with_to_bytes); + test_case "double_with_one" `Quick (repeat 1 double_with_one); + test_case "double_with_zero" `Quick (repeat 100 double_with_zero); + ] ) +end + +module MakeIsZero (G : Ec_sig.BASE) = struct + let with_zero_value () = assert (G.is_zero G.zero = true) + + let with_one_value () = assert (G.is_zero G.one = false) + + let with_random_value () = assert (G.is_zero (G.random ()) = false) + + (** Returns the tests to be used with Alcotest *) + let get_tests () = + let open Alcotest in + ( "is_zero", + [ + test_case "with zero value" `Quick (repeat 1 with_zero_value); + test_case "with one value" `Quick (repeat 1 with_one_value); + test_case "with random value" `Quick (repeat 100 with_random_value); + ] ) +end + +module MakeECProperties (G : Ec_sig.BASE) = struct + (** Verify that a random point is valid *) + let check_bytes_random () = assert (G.(check_bytes @@ to_bytes @@ random ())) + + (** Verify that the zero point is valid *) + let check_bytes_zero () = assert (G.(check_bytes @@ to_bytes @@ zero)) + + (** Verify that the fixed generator point is valid *) + let check_bytes_one () = assert (G.(check_bytes @@ to_bytes @@ one)) + + (** Verify that doubling a random point gives a valid point *) + let check_bytes_random_double () = + assert (G.(check_bytes @@ to_bytes @@ double (random ()))) + + (** Verify that the sum of random points is valid *) + let check_bytes_random_sum () = + assert (G.(check_bytes @@ to_bytes @@ add (random ()) (random ()))) + + (** Verify that multiplying a random point by a scalar gives a valid point *) + let check_bytes_random_multiplication () = + assert (G.(check_bytes @@ to_bytes @@ mul (random ()) (Scalar.random ()))) + + (** Verify 0_S * g_EC = 0_EC where 0_S is the zero of the scalar field, 0_EC + is the point at infinity and g_EC is an element of the EC *) + let zero_scalar_nullifier_random () = + let random = G.random () in + assert (G.is_zero (G.mul random G.Scalar.zero)) + + (** Verify 0_S * 0_EC = 0_EC where 0_S is the zero of the scalar field and + 0_EC is the point at infinity of the EC *) + let zero_scalar_nullifier_zero () = + assert (G.is_zero (G.mul G.zero G.Scalar.zero)) + + (** Verify 0_S * 1_EC = 0_EC where 0_S is the 0 of the scalar field, 1_EC is a + fixed generator and 0_EC is the point at infinity of the EC *) + let zero_scalar_nullifier_one () = + assert (G.is_zero (G.mul G.one G.Scalar.zero)) + + let multiply_by_one_does_nothing () = + let g = G.random () in + assert (G.(eq (mul g Scalar.one) g)) + + (** Verify -(-g) = g where g is an element of the EC *) + let opposite_of_opposite () = + let random = G.random () in + assert (G.eq (G.negate (G.negate random)) random) + + let opposite_of_opposite_using_scalar () = + let r = G.random () in + assert (G.(eq r (mul r (Scalar.negate (Scalar.negate Scalar.one))))) + + (** Verify -(-0_EC) = 0_EC where 0_EC is the point at infinity of the EC *) + let opposite_of_zero_is_zero () = assert (G.eq (G.negate G.zero) G.zero) + + (** Verify -(-0_EC) = 0_EC where 0_EC is the point at infinity of the EC *) + let opposite_of_opposite_of_zero_is_zero () = + assert (G.eq (G.negate (G.negate G.zero)) G.zero) + + (** Verify -(-0_EC) = 0_EC where 0_EC is the point at infinity of the EC *) + let opposite_of_opposite_of_one_is_one () = + assert (G.eq (G.negate (G.negate G.one)) G.one) + + (** Verify g1 + (g2 + g3) = (g1 + g2) + g3 *) + let additive_associativity () = + let g1 = G.random () in + let g2 = G.random () in + let g3 = G.random () in + assert (G.eq (G.add (G.add g1 g2) g3) (G.add g1 (G.add g2 g3))) + + (** Verify (g1 + g2) = (g2 + g1) *) + let additive_commutativity () = + let g1 = G.random () in + let g2 = G.random () in + assert (G.eq (G.add g1 g2) (G.add g2 g1)) + + (** Verify that g + (-g) = 0 *) + let opposite_existential_property () = + let g = G.random () in + assert (G.(eq (add g (negate g)) zero)) + + (** Verify a (g1 + g2) = a * g1 + a * g2 where a is a scalar, g1, g2 two + elements of the EC *) + let distributivity () = + let s = G.Scalar.random () in + let g1 = G.random () in + let g2 = G.random () in + assert (G.eq (G.mul (G.add g1 g2) s) (G.add (G.mul g1 s) (G.mul g2 s))) + + (** Verify (a + -a) * g = a * g - a * g = 0 *) + let opposite_equality () = + let a = G.Scalar.random () in + let g = G.random () in + assert (G.(eq (mul g (Scalar.add a (Scalar.negate a))) zero)) ; + assert (G.(eq zero (add (mul g a) (mul g (Scalar.negate a))))) ; + assert ( + G.( + eq + (mul g (Scalar.add a (Scalar.negate a))) + (add (mul g a) (mul g (Scalar.negate a))))) + + (** a g + b + g = (a + b) g*) + let additive_associativity_with_scalar () = + let a = G.Scalar.random () in + let b = G.Scalar.random () in + let g = G.random () in + let left = G.(add (mul g a) (mul g b)) in + let right = G.(mul g (Scalar.add a b)) in + assert (G.(eq left right)) + + (** (a * b) g = a (b g) = b (a g) *) + let multiplication_properties_on_base_field_element () = + let a = G.Scalar.random () in + let b = G.Scalar.random () in + let g = G.random () in + assert (G.(eq (mul g (Scalar.mul a b)) (mul (mul g a) b))) ; + assert (G.(eq (mul g (Scalar.mul a b)) (mul (mul g b) a))) + + (** Verify (-s) * g = s * (-g) *) + let opposite_of_scalar_is_opposite_of_ec () = + let s = G.Scalar.random () in + let g = G.random () in + let left = G.mul g (G.Scalar.negate s) in + let right = G.mul (G.negate g) s in + assert (G.eq left right) + + let generator_is_of_prime_order () = + assert (G.(eq (mul one (G.Scalar.of_z G.Scalar.order)) zero)) + + let mul_by_order_of_scalar_field_equals_zero () = + let s = G.Scalar.random () in + let g = G.random () in + (* (g * s) * order = zero *) + assert (G.(eq (mul (mul g s) (G.Scalar.of_z G.Scalar.order)) zero)) ; + (* (one * s) * order = zero *) + assert (G.(eq (mul (mul one s) (G.Scalar.of_z G.Scalar.order)) zero)) + + (** Verify 2*g = g + g *) + let double () = + let s = G.random () in + assert (G.(eq (double s) (add s s))) + + let inverse_on_scalar () = + let g = G.random () in + let a = G.Scalar.random () in + let inv_a = G.Scalar.inverse_exn a in + let ga = G.mul g a in + let ga_inv = G.mul g inv_a in + (* g * (a * a^(-1)) *) + let res1 = G.mul g (G.Scalar.mul inv_a a) in + (* (g * a^(-1)) * a *) + let res2 = G.mul ga_inv a in + (* (g * a) * a^(-1) *) + let res3 = G.mul ga inv_a in + assert (G.(eq res2 res3)) ; + (* g * (a * a^(-1)) = g *) + assert (G.(eq res1 g)) ; + (* (g * a^(-1)) * a = g *) + assert (G.(eq res2 g)) ; + (* (g * a) * a^(-1) = g *) + assert (G.(eq res3 g)) + + let zero_is_the_identity () = + let g = G.random () in + assert (G.(eq (add g zero) (add zero g))) ; + assert (G.(eq (add g zero) g)) + + (** Returns the tests to be used with Alcotest *) + let get_tests () = + let open Alcotest in + ( "Group properties", + [ + test_case "check_bytes_random" `Quick (repeat 100 check_bytes_random); + test_case "check_bytes_zero" `Quick (repeat 1 check_bytes_zero); + test_case "check_bytes_one" `Quick (repeat 1 check_bytes_one); + test_case + "check_bytes_random_double" + `Quick + (repeat 100 check_bytes_random_double); + test_case + "check_bytes_random_sum" + `Quick + (repeat 100 check_bytes_random_sum); + test_case + "check_bytes_random_multiplication" + `Quick + (repeat 100 check_bytes_random_multiplication); + test_case + "zero_scalar_nullifier_one" + `Quick + (repeat 1 zero_scalar_nullifier_one); + test_case + "zero_scalar_nullifier_zero" + `Quick + (repeat 1 zero_scalar_nullifier_zero); + test_case + "zero_scalar_nullifier_random" + `Quick + (repeat 100 zero_scalar_nullifier_random); + test_case + "multiply_by_one_does_nothing" + `Quick + (repeat 100 multiply_by_one_does_nothing); + test_case + "opposite_of_opposite" + `Quick + (repeat 100 opposite_of_opposite); + test_case + "opposite_of_opposite_using_scalar" + `Quick + (repeat 100 opposite_of_opposite_using_scalar); + test_case + "opposite_of_zero_is_zero" + `Quick + (repeat 1 opposite_of_zero_is_zero); + test_case + "opposite_of_opposite_of_zero_is_zero" + `Quick + (repeat 1 opposite_of_opposite_of_zero_is_zero); + test_case + "opposite_of_opposite_of_one_is_one" + `Quick + (repeat 1 opposite_of_opposite_of_one_is_one); + test_case "opposite_equality" `Quick (repeat 1 opposite_equality); + test_case + "zero is the identity" + `Quick + (repeat 100 zero_is_the_identity); + test_case "distributivity" `Quick (repeat 100 distributivity); + test_case + "opposite_of_scalar_is_opposite_of_ec" + `Quick + (repeat 100 opposite_of_scalar_is_opposite_of_ec); + test_case + "opposite_existential_property" + `Quick + (repeat 100 opposite_existential_property); + test_case + "mul_by_order_of_base_field_equals_element" + `Quick + (repeat 100 mul_by_order_of_scalar_field_equals_zero); + test_case + "multiplication_properties_on_base_field_element" + `Quick + (repeat 100 multiplication_properties_on_base_field_element); + test_case "double" `Quick (repeat 100 double); + test_case + "additive_associativity_with_scalar" + `Quick + (repeat 100 additive_associativity_with_scalar); + test_case "inverse on scalar" `Quick (repeat 100 inverse_on_scalar); + test_case + "additive_associativity" + `Quick + (repeat 100 additive_associativity); + test_case + "additive_commutativity" + `Quick + (repeat 100 additive_commutativity); + test_case + "Generator is of prime order" + `Quick + (repeat 1 generator_is_of_prime_order); + ] ) +end + +module MakeEdwardsCurveProperties (G : Ec_sig.AffineEdwardsT) = struct + let rec test_of_bytes_and_check_bytes_with_different_size_of_bytes () = + (* Generate a random number of bytes between 0 and 10 * G.size_in_bytes. If + the random value is the correct number of bytes, we ignore + *) + let b_size = Random.int (G.size_in_bytes * 10) in + if b_size = G.size_in_bytes then + test_of_bytes_and_check_bytes_with_different_size_of_bytes () + else + let b = Bytes.create b_size in + assert (not (G.check_bytes b)) ; + assert (Option.is_none (G.of_bytes_opt b)) ; + try + ignore @@ G.of_bytes_exn b ; + assert false + with + | G.Not_on_curve exn_bytes -> assert (Bytes.equal exn_bytes b) + | _ -> assert false + + let test_unsafe_from_coordinates_do_not_check () = + let u = G.Base.random () in + let v = G.Base.random () in + ignore @@ G.unsafe_from_coordinates ~u ~v + + let get_tests () = + let open Alcotest in + ( "Group properties of Edwards curve", + [ + test_case + "unsafe_from_coordinates do not check the point is on the curve" + `Quick + test_unsafe_from_coordinates_do_not_check; + test_case + "Test check_bytes and of_bytes_[exn/opt] with a different number of \ + bytes than expected" + `Quick + test_of_bytes_and_check_bytes_with_different_size_of_bytes; + ] ) +end + +module MakeSerialisationProperties (G : Ec_sig.BASE) = struct + let test_of_bytes_exn_to_bytes_are_inverse_functions () = + let r = G.random () in + assert (G.(eq (of_bytes_exn (to_bytes r)) r)) + + let test_of_bytes_opt_to_bytes_are_inverse_functions () = + let r = G.random () in + assert (G.(eq (Option.get (of_bytes_opt (to_bytes r))) r)) + + let get_tests () = + let open Alcotest in + ( "Serialisation", + [ + test_case + "of_bytes_exn and to_bytes are inverse functions" + `Quick + test_of_bytes_exn_to_bytes_are_inverse_functions; + test_case + "of_bytes_opt and to_bytes are inverse functions" + `Quick + test_of_bytes_opt_to_bytes_are_inverse_functions; + ] ) +end + +module MakeCompressedSerialisationAffine (G : sig + include Ec_sig.BASE + + val of_compressed_bytes_exn : Bytes.t -> t + + val of_compressed_bytes_opt : Bytes.t -> t option + + val to_compressed_bytes : t -> Bytes.t +end) = +struct + let test_zero () = + let expected_zero_bytes_compressed = + Bytes.make (G.size_in_bytes / 2) '\000' + in + assert ( + Bytes.( + equal (G.to_compressed_bytes G.zero) expected_zero_bytes_compressed)) + + let test_of_compressed_bytes_exn_recover_correct_point_from_uncompressed_representation + () = + let g = G.random () in + let compressed_bytes = G.to_compressed_bytes g in + let uncompressed_g = G.of_compressed_bytes_exn compressed_bytes in + assert (G.eq g uncompressed_g) + + let test_of_compressed_bytes_opt_recover_correct_point_from_uncompressed_representation + () = + let g = G.random () in + let compressed_bytes = G.to_compressed_bytes g in + let uncompressed_g = + Option.get (G.of_compressed_bytes_opt compressed_bytes) + in + assert (G.eq g uncompressed_g) + + (* it is correct to test this for BLS12-381 *) + let test_compressed_version_is_half_the_size () = + let g = G.random () in + assert (Bytes.length (G.to_compressed_bytes g) = G.size_in_bytes / 2) + + let test_of_compressed_bytes_exn_and_opt_do_not_accept_uncompressed_bytes_representation + () = + let x = G.random () in + let x_uncompressed_bytes = G.to_bytes x in + assert (Option.is_none (G.of_compressed_bytes_opt x_uncompressed_bytes)) ; + try + ignore @@ G.of_compressed_bytes_exn x_uncompressed_bytes ; + assert false + with G.Not_on_curve _b -> () + + let test_of_bytes_exn_and_opt_do_not_accept_compressed_bytes_representation () + = + let x = G.random () in + let x_compressed_bytes = G.to_compressed_bytes x in + assert (Option.is_none (G.of_bytes_opt x_compressed_bytes)) ; + try + ignore @@ G.of_bytes_exn x_compressed_bytes ; + assert false + with G.Not_on_curve _b -> () + + let get_tests () = + let open Alcotest in + ( "Compressed representation", + [ + test_case + "Compressed representation of zero is the bs with zeroes" + `Quick + test_zero; + test_case + "of_compressed_bytes_exn recovers correct point from uncompressed \ + representation" + `Quick + (repeat + 100 + test_of_compressed_bytes_exn_recover_correct_point_from_uncompressed_representation); + test_case + "of_compressed_bytes_opt recovers correct point from uncompressed \ + representation" + `Quick + (repeat + 100 + test_of_compressed_bytes_opt_recover_correct_point_from_uncompressed_representation); + test_case + "Compressed version is half the size" + `Quick + test_compressed_version_is_half_the_size; + test_case + "of_compressed_bytes_exn/opt do not accept uncompressed bytes \ + representation" + `Quick + (repeat + 100 + test_of_compressed_bytes_exn_and_opt_do_not_accept_uncompressed_bytes_representation); + test_case + "of_bytes_exn/opt do not accept compressed bytes representation" + `Quick + (repeat + 100 + test_of_bytes_exn_and_opt_do_not_accept_compressed_bytes_representation); + ] ) +end diff --git a/src/lib_mec/ec_sig.ml b/src/lib_mec/ec_sig.ml new file mode 100644 index 000000000000..1b2372fac51a --- /dev/null +++ b/src/lib_mec/ec_sig.ml @@ -0,0 +1,340 @@ +(** Basic interface for elliptic curves *) +module type BASE = sig + exception Not_on_curve of Bytes.t + + (** Represents an element on the curve. In the case of a curve with a + cofactor, the element is not necessarily in the prime subgroup. + *) + type t + + (** The size of a point representation, in bytes *) + val size_in_bytes : int + + module Scalar : Bls12_381.Ff_sig.PRIME + + module Base : Bls12_381.Ff_sig.PRIME + + (** Check if a point, represented as a byte array, is on the curve **) + val check_bytes : Bytes.t -> bool + + (** Attempt to construct a point from a byte array *) + val of_bytes_opt : Bytes.t -> t option + + (** Attempt to construct a point from a byte array. + Raise [Not_on_curve] if the point is not on the curve + *) + val of_bytes_exn : Bytes.t -> t + + (** Return a representation in bytes *) + val to_bytes : t -> Bytes.t + + (** Zero of the elliptic curve *) + val zero : t + + (** A fixed generator of the elliptic curve *) + val one : t + + (** Return [true] if the given element is zero *) + val is_zero : t -> bool + + (** Generate a random element *) + val random : ?state:Random.State.t -> unit -> t + + (** Return the addition of two element *) + val add : t -> t -> t + + (** Double the element *) + val double : t -> t + + (** Return the opposite of the element *) + val negate : t -> t + + (** Return [true] if the two elements are algebraically the same *) + val eq : t -> t -> bool + + (** Multiply an element by a scalar *) + val mul : t -> Scalar.t -> t +end + +(** Curve in Weierstrass form with a and b. In affine, the curve has the + equation form y² = x³ + ax + b *) +module type WeierstrassT = sig + include BASE + + val a : Base.t + + val b : Base.t + + val cofactor : Z.t +end + +module type AffineWeierstrassT = sig + include WeierstrassT + + val get_x_coordinate : t -> Base.t + + val get_y_coordinate : t -> Base.t + + (* val to_montgomery_curve_parameters : unit -> (Base.t * Base.t * Z.t * (Base.t * Base.t)) option + + val to_montgomery : t -> (Base.t * Base.t) option *) + + (** [is_on_curve ~x ~y] returns [true] if the coordinates [(x, y)] represents + a point on the curve. It does not check the point is in the prime subgroup. + *) + val is_on_curve : x:Base.t -> y:Base.t -> bool + + (** [is_in_prime_subgroup ~x ~y] returns [true] if the coordinates [(x, y)] + represents a point in the prime subgroup. The coordinates must be a point + on the curve + *) + val is_in_prime_subgroup : x:Base.t -> y:Base.t -> bool + + (** Build a point from the affine coordinates. If the point is not on the curve + and in the subgroup, returns [None] + *) + val from_coordinates_opt : x:Base.t -> y:Base.t -> t option + + (** Build a point from the affine coordinates. If the point is not on the curve + and in the subgroup, raise [Not_on_curve]. + *) + val from_coordinates_exn : x:Base.t -> y:Base.t -> t + + (** Build a point from a compressed representation. It supposes the base field + leaves at least a free bit in the last byte to encode the sign. + Raise [Not_on_curve] if the bytes do not represent a point on the curve + and in the prime subgroup. + *) + val of_compressed_bytes_exn : Bytes.t -> t + + (** Same than [of_compressed_bytes_exn] but returns an option instead of + raising an exception + *) + val of_compressed_bytes_opt : Bytes.t -> t option + + (** Return the compressed representation of the point *) + val to_compressed_bytes : t -> Bytes.t +end + +module type ProjectiveWeierstrassT = sig + include WeierstrassT + + (** [is_on_curve ~x ~y ~z] returns [true] if the coordinates [(x, y, z)] + represents a point on the curve. It does not check the point is in the + prime subgroup. + *) + val is_on_curve : x:Base.t -> y:Base.t -> z:Base.t -> bool + + (** [is_in_prime_subgroup ~x ~y ~z] returns [true] if the coordinates + [(x, y, z)] represents a point in the prime subgroup. The coordinates must + be a point on the curve. + *) + val is_in_prime_subgroup : x:Base.t -> y:Base.t -> z:Base.t -> bool + + val get_x_coordinate : t -> Base.t + + val get_y_coordinate : t -> Base.t + + val get_z_coordinate : t -> Base.t + + (** Build a point from the affine coordinates. If the point is not on the curve + and in the subgroup, returns [None] + *) + val from_coordinates_opt : x:Base.t -> y:Base.t -> z:Base.t -> t option + + (** Build a point from the affine coordinates. If the point is not on the curve + and in the subgroup, raise [Not_on_curve]. + *) + val from_coordinates_exn : x:Base.t -> y:Base.t -> z:Base.t -> t + + val get_affine_x_coordinate : t -> Base.t + + val get_affine_y_coordinate : t -> Base.t + + val from_affine_coordinates_exn : x:Base.t -> y:Base.t -> t + + val from_affine_coordinates_opt : x:Base.t -> y:Base.t -> t +end + +module type JacobianWeierstrassT = sig + include WeierstrassT + + (** [is_on_curve ~x ~y ~z] returns [true] if the coordinates [(x, y, z)] represents + a point on the curve. It does not check the point is in the prime subgroup. + *) + val is_on_curve : x:Base.t -> y:Base.t -> z:Base.t -> bool + + (** [is_in_prime_subgroup ~x ~y ~z] returns [true] if the coordinates [(x, y, z)] + represents a point in the prime subgroup. The coordinates must be a point + on the curve + *) + val is_in_prime_subgroup : x:Base.t -> y:Base.t -> z:Base.t -> bool + + val get_x_coordinate : t -> Base.t + + val get_y_coordinate : t -> Base.t + + val get_z_coordinate : t -> Base.t + + (** Build a point from the projective coordinates. If the point is not on the curve + and in the subgroup, returns [None] + *) + val from_coordinates_opt : x:Base.t -> y:Base.t -> z:Base.t -> t option + + (** Build a point from the projective coordinates. If the point is not on the curve + and in the subgroup, raise [Not_on_curve]. + *) + val from_coordinates_exn : x:Base.t -> y:Base.t -> z:Base.t -> t + + val get_affine_x_coordinate : t -> Base.t + + val get_affine_y_coordinate : t -> Base.t + + val from_affine_coordinates_exn : x:Base.t -> y:Base.t -> t + + val from_affine_coordinates_opt : x:Base.t -> y:Base.t -> t +end + +module type MontgomeryT = sig + include BASE + + val a : Base.t + + val b : Base.t + + val cofactor : Z.t +end + +module type AffineMontgomeryT = sig + (** by^2 = x3 + ax^2 + x with b * (a^2 - 4) != 0*) + include MontgomeryT + + (** [is_on_curve ~x ~y] returns [true] if the coordinates [(x, y)] represents + a point on the curve. It does not check the point is in the prime subgroup. + *) + val is_on_curve : x:Base.t -> y:Base.t -> bool + + (** [is_in_prime_subgroup ~x ~y] returns [true] if the coordinates [(x, y)] + represents a point in the prime subgroup. The coordinates must be a point + on the curve + *) + val is_in_prime_subgroup : x:Base.t -> y:Base.t -> bool + + val get_x_coordinate : t -> Base.t + + val get_y_coordinate : t -> Base.t + + val to_twisted_curve_parameters : + unit -> (Base.t * Base.t * Z.t * (Base.t * Base.t)) option + + val to_twisted : t -> (Base.t * Base.t) option + + val to_weierstrass_curve_parameters : + unit -> (Base.t * Base.t * Z.t * (Base.t * Base.t)) option + + val to_weierstrass : t -> (Base.t * Base.t) option + + (** Build a point from the affine coordinates. If the point is not on the curve + and in the subgroup, returns [None] + *) + val from_coordinates_opt : x:Base.t -> y:Base.t -> t option + + (** Build a point from the affine coordinates. If the point is not on the curve + and in the subgroup, raise [Not_on_curve]. + *) + val from_coordinates_exn : x:Base.t -> y:Base.t -> t + + (** Build a point from a compressed representation. It supposes the base field + leaves at least a free bit in the last byte to encode the sign. + Raise [Not_on_curve] if the bytes do not represent a point on the curve + and in the prime subgroup. + *) + val of_compressed_bytes_exn : Bytes.t -> t + + (** Same than [of_compressed_bytes_exn] but returns an option instead of + raising an exception + *) + val of_compressed_bytes_opt : Bytes.t -> t option + + (** Return the compressed representation of the point *) + val to_compressed_bytes : t -> Bytes.t +end + +module type AffineEdwardsT = sig + (** au^2 + v^2 = 1 + du^2v^2 *) + include BASE + + (** The parameter [a] of the curve, from the equation a * u^2 + v^2 = 1 + d * u^2 * v^2 *) + val a : Base.t + + (** The parameter [d] of the curve, from the equation a * u^2 + v^2 = 1 + d * u^2 * v^2 *) + val d : Base.t + + (** The cofactor of the curve. The parameter is used in [is_small_order] and + in the random point generator. + *) + val cofactor : Z.t + + (** [is_on_curve ~u ~v] returns [true] if the coordinates [(u, v)] represents + a point on the curve. It does not check the point is in the prime subgroup. + *) + val is_on_curve : u:Base.t -> v:Base.t -> bool + + (** [is_in_prime_subgroup ~u ~v] returns [true] if the coordinates [(u, v)] + represents a point in the prime subgroup. The coordinates must be a point + on the curve + *) + val is_in_prime_subgroup : u:Base.t -> v:Base.t -> bool + + (** Return the affine coordinate u (such that au^2 + v^2 = 1 + d u^2 v^2 *) + val get_u_coordinate : t -> Base.t + + (** Return the affine coordinate u (such that au^2 + v^2 = 1 + d u^2 v^2 *) + val get_v_coordinate : t -> Base.t + + val to_montgomery_curve_parameters : + unit -> (Base.t * Base.t * Z.t * (Base.t * Base.t)) option + + val to_montgomery : t -> (Base.t * Base.t) option + + (** Build a point from the affine coordinates. If the point is not on the curve + and in the subgroup, returns [None] + *) + val from_coordinates_opt : u:Base.t -> v:Base.t -> t option + + (** Build a point from the affine coordinates. If the point is not on the curve + and in the subgroup, raise [Not_on_curve]. + *) + val from_coordinates_exn : u:Base.t -> v:Base.t -> t + + (** Build a point from the affine coordinates, without verifying the point is + on the curve. Use with precaution. + *) + val unsafe_from_coordinates : u:Base.t -> v:Base.t -> t +end + +module type PAIRING = sig + module G1 : BASE + + module G2 : BASE + + module GT : Bls12_381.Ff_sig.BASE + + exception FailToComputeFinalExponentiation of GT.t + + val miller_loop : (G1.t * G2.t) list -> GT.t + + (** Compute the miller loop on a single tuple of point *) + val miller_loop_simple : G1.t -> G2.t -> GT.t + + (** Compute a pairing result of a list of points *) + val pairing : G1.t -> G2.t -> GT.t + + (** Compute the final exponentiation of the given point. Returns a [None] if + the point is null *) + val final_exponentiation_opt : GT.t -> GT.t option + + (** Compute the final exponentiation of the given point. Raise + [FailToComputeFinalExponentiation] if the point is null *) + val final_exponentiation_exn : GT.t -> GT.t +end diff --git a/src/lib_mec/ff.ml b/src/lib_mec/ff.ml new file mode 100644 index 000000000000..bacaf422ae29 --- /dev/null +++ b/src/lib_mec/ff.ml @@ -0,0 +1,347 @@ +open Bls12_381.Ff_sig + +module MakeFp (S : sig + val prime_order : Z.t +end) : PRIME_WITH_ROOT_OF_UNITY = struct + exception Not_in_field of Bytes.t + + type t = Z.t + + let order = + assert (S.prime_order >= Z.of_string "2") ; + S.prime_order + + let two_z = Z.succ Z.one + + let factor_power_of_two = + let rec aux i n = + let q, r = Z.ediv_rem n two_z in + if Z.equal r Z.zero then aux (i + 1) q else (i, n) + in + aux 0 (Z.pred order) + + let log256 n = log n /. log 256. + + let size_in_bytes = int_of_float (log256 (Z.to_float order)) + 1 + + let zero = Z.zero + + let one = Z.one + + (** By default, any bytes sequence is valid because we care about the result + modulo the order *) + let check_bytes _bs = true + + let copy x = x + + let is_zero s = Z.equal (Z.erem s order) Z.zero + + let is_one s = Z.equal (Z.erem s order) Z.one + + let random ?state () = + (match state with None -> () | Some s -> Random.set_state s) ; + let r = Bytes.init size_in_bytes (fun _ -> char_of_int (Random.int 256)) in + Z.erem (Z.of_bits (Bytes.to_string r)) order + + let non_null_random ?state () = + (match state with None -> () | Some s -> Random.set_state s) ; + let rec aux () = + let r = random () in + if is_zero r then aux () else r + in + aux () + + let add a b = Z.erem (Z.add a b) order + + let sub a b = Z.erem (Z.sub a b) order + + let mul a b = Z.erem (Z.mul a b) order + + let eq a b = Z.equal (Z.erem a order) (Z.erem b order) + + let negate a = sub order a + + let inverse_exn a = + if a = zero then raise Division_by_zero else Z.invert a order + + let inverse_opt a = + try Some (Z.invert a order) with Division_by_zero -> None + + let div_exn a b = + if b = zero then raise Division_by_zero else mul a (inverse_exn b) + + let div_opt a b = if b = zero then None else Some (mul a (inverse_exn b)) + + let square x = mul x x + + let double x = add x x + + let pow x n = + if Z.equal n Z.zero then one + else if is_zero x then zero + else if Z.equal n Z.one then x + else Z.powm x n order + + (* Decimal representation by default *) + let of_string s = Z.erem (Z.of_string s) order + + (* Decimal representation by default *) + let to_string s = Z.to_string s + + (** From a predefined bytes representation, construct a value t. It is not + required that to_bytes (of_bytes_exn t)) = t. By default, little endian + encoding is used and the given element is modulo the prime order *) + let of_bytes_exn s = Z.erem (Z.of_bits (Bytes.to_string s)) order + + (** From a predefined bytes representation, construct a value t. It is not + required that to_bytes (Option.get (of_bytes_opt t)) = t. By default, + little endian encoding is used and the given element is modulo the prime + order *) + let of_bytes_opt s = Some (of_bytes_exn s) + + (* Little endian representation *) + let to_bytes s = + let b = Bytes.of_string (Z.to_bits s) in + let res = Bytes.make size_in_bytes '\000' in + Bytes.blit b 0 res 0 (min (Bytes.length b) size_in_bytes) ; + res + + let is_nth_root_of_unity n x = (not (eq x zero)) && is_one (pow x n) + + let get_nth_root_of_unity n = + let pred_order = Z.pred order in + if Z.gt n pred_order || not (Z.(erem pred_order n) = zero) then + failwith "n must divide the order of the multiplication subgroup" + else + let rec aux () = + let r = random () in + if is_nth_root_of_unity n r then r else aux () + in + aux () + + let to_z t = t + + let of_z t = Z.erem t order + + let legendre_symbol x = + if is_zero x then Z.zero + else if is_one (pow x (Z.divexact (Z.pred order) (Z.of_int 2))) then Z.one + else Z.neg Z.one + + let is_quadratic_residue x = + if is_zero x then true else is_one (legendre_symbol x) + + let rec pick_non_square () = + let z = random () in + if Z.equal (legendre_symbol z) (Z.of_int (-1)) then z + else pick_non_square () + + let sqrt_opt x = + if not (is_quadratic_residue x) then None + else + (* https://en.wikipedia.org/wiki/Tonelli%E2%80%93Shanks_algorithm *) + let s, q = factor_power_of_two in + (* implies p = 3 mod 4 *) + if s = 1 then + (* r = x^((p + 1) / 4) *) + let r = pow x (Z.divexact (Z.succ order) (Z.of_string "4")) in + Some r + else + let rec compute_lowest_n_2th_root_of_unity i x upper = + let x = square x in + if is_one x then i + else if i = upper then failwith "Upperbound should be higher" + (* should never happen in this case, just being explicit *) + else compute_lowest_n_2th_root_of_unity (i + 1) x upper + in + let z = pick_non_square () in + let c = pow z q in + let rec aux m c t r = + if eq t zero then zero (* case x is zero *) + else if eq t one then r (* base case *) + else + let i = compute_lowest_n_2th_root_of_unity 1 t m in + let b = pow c (Z.pow two_z (m - i - 1)) in + let m = i in + let c = mul b b in + let t = mul t c in + let r = mul r b in + aux m c t r + in + Some (aux s c (pow x q) (pow x (Z.divexact (Z.succ q) two_z))) + + let of_int x = of_z (Z.of_int x) + + let ( + ) = add + + let ( * ) = mul + + let ( - ) = negate + + let ( ** ) = pow + + let ( = ) = eq + + let ( / ) = div_exn +end + +module MakeFp2 + (Fp : BASE) (Intf : sig + (* Non square residue. Arithmetic is over Fp[X] / X^2 - r *) + val nsr : Fp.t + end) : sig + include BASE + + val components : t -> Fp.t * Fp.t +end = struct + exception Not_in_field of Bytes.t + + type t = Fp.t * Fp.t + + let components (a, b) = (a, b) + + let order = Z.mul Fp.order Fp.order + + let size_in_bytes = Fp.size_in_bytes * 2 + + let check_bytes b = + if Bytes.length b = size_in_bytes then + let x = Bytes.sub b 0 (size_in_bytes / 2) in + let y = Bytes.sub b (size_in_bytes / 2) (size_in_bytes / 2) in + Fp.check_bytes x && Fp.check_bytes y + else false + + let copy x = x + + let zero = (Fp.zero, Fp.zero) + + let one = (Fp.one, Fp.zero) + + let is_zero (x, y) = Fp.(x = zero && y = zero) + + let is_one (x, y) = Fp.(x = Fp.one && y = Fp.zero) + + let random ?state () = + (match state with None -> () | Some s -> Random.set_state s) ; + (Fp.random (), Fp.random ()) + + let non_null_random ?state () = + (match state with None -> () | Some s -> Random.set_state s) ; + let x = Random.bool () in + if x then (Fp.non_null_random (), Fp.random ()) + else (Fp.random (), Fp.non_null_random ()) + + let add (x1, y1) (x2, y2) = (Fp.(x1 + x2), Fp.(y1 + y2)) + + let mul (x1, y1) (x2, y2) = + let open Fp in + let tmp_x = x1 * x2 in + let tmp_y = y1 * y2 in + let x' = tmp_x + (Intf.nsr * tmp_y) in + let y' = (x1 * y2) + (y1 * x2) in + (x', y') + + let eq (x1, y1) (x2, y2) = Fp.(x1 = x2 && y1 = y2) + + let negate (x, y) = (Fp.negate x, Fp.negate y) + + let sub a b = add a (negate b) + + let aux_inverse (x, y) = + (* Let's use square in case of `*` is not optimised for the square case *) + let x_square = Fp.square x in + let y_square = Fp.square y in + (* inverse of [x_square - nsr * y_square] *) + let tmp_inverse = + Fp.(inverse_exn (x_square + Fp.negate (Intf.nsr * y_square))) + in + let x' = Fp.(x * tmp_inverse) in + let y' = Fp.(negate y * tmp_inverse) in + (x', y') + + let inverse_exn x = + if is_zero x then raise Division_by_zero else aux_inverse x + + let inverse_opt x = if is_zero x then None else Some (aux_inverse x) + + let div_exn a b = + if b = zero then raise Division_by_zero else mul a (inverse_exn b) + + let div_opt a b = if b = zero then None else Some (mul a (inverse_exn b)) + + let square (a, b) = + let ab = Fp.(a * b) in + Fp. + ( ((a + b) * (a + (Intf.nsr * b))) + + Fp.negate ab + + Fp.negate (Intf.nsr * ab), + ab + ab ) + + let double x = add x x + + let two_z = Z.succ Z.one + + let rec pow x n = + if Z.equal n Z.zero then one + else if is_zero x then zero + else if Z.equal n Z.one then x + else + let n = Z.erem n (Z.pred order) in + let a, r = Z.ediv_rem n two_z in + let acc = pow x a in + let acc_square = mul acc acc in + if Z.equal r Z.zero then acc_square else mul acc_square x + + (** From a predefined bytes representation, construct a value t. It is not + required that to_bytes (of_bytes_exn t)) = t. By default, little endian + encoding is used and the given element is modulo the prime order *) + let of_bytes_exn b = + if Int.equal (Bytes.length b) size_in_bytes then + let x_bytes = Bytes.sub b 0 (Int.div size_in_bytes 2) in + let y_bytes = + Bytes.sub b (Int.div size_in_bytes 2) (Int.div size_in_bytes 2) + in + (Fp.of_bytes_exn x_bytes, Fp.of_bytes_exn y_bytes) + else raise (Not_in_field b) + + (** From a predefined bytes representation, construct a value t. It is not + required that to_bytes (Option.get (of_bytes_opt t)) = t. By default, + little endian encoding is used and the given element is modulo the prime + order *) + let of_bytes_opt b = + if Int.equal (Bytes.length b) size_in_bytes then + let x_bytes = Bytes.sub b 0 (Int.div size_in_bytes 2) in + let y_bytes = + Bytes.sub b (Int.div size_in_bytes 2) (Int.div size_in_bytes 2) + in + let x = Fp.of_bytes_opt x_bytes in + let y = Fp.of_bytes_opt y_bytes in + match (x, y) with + | None, _ | _, None -> None + | Some x, Some y -> Some (x, y) + else None + + (* Little endian representation *) + let to_bytes (x, y) = + let b = Bytes.make size_in_bytes '\000' in + Bytes.blit (Fp.to_bytes x) 0 b 0 (Int.div size_in_bytes 2) ; + Bytes.blit + (Fp.to_bytes y) + 0 + b + (Int.div size_in_bytes 2) + (Int.div size_in_bytes 2) ; + b + + let ( + ) = add + + let ( * ) = mul + + let ( - ) = negate + + let ( ** ) = pow + + let ( = ) = eq + + let ( / ) = div_exn +end diff --git a/src/lib_mec/group_hash.ml b/src/lib_mec/group_hash.ml new file mode 100644 index 000000000000..d65d546a0aa3 --- /dev/null +++ b/src/lib_mec/group_hash.ml @@ -0,0 +1,58 @@ +(*****************************************************************************) +(* *) +(* Copyright (c) 2021 Danny Willems *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Reference implementation: + https://github.com/zcash/librustzcash/blob/da431a0eb207f69c9b0631d7d02136d819e1bfd9/zcash_primitives/src/sapling/group_hash.rs +*) + +(* https://github.com/zcash/librustzcash/blob/da431a0eb207f69c9b0631d7d02136d819e1bfd9/zcash_primitives/src/constants.rs#L12 *) +let gh_first_block = + "096b36a5804bfacef1691e173c366a47ff5ba84a44f26ddd7e8d9f79d5b42df0" + +module Blake2s = Mec_digestif.Make_BLAKE2S (struct + let digest_size = 32 +end) + +let group_hash message personalisation = + let h = Blake2s.init ~personalisation () in + let h = Blake2s.feed_string h gh_first_block in + let h = Blake2s.feed_bytes h message in + let hash_hex = `Hex Blake2s.(to_hex (get h)) in + let hash_hex = Hex.to_bytes hash_hex in + let p_opt = Jubjub.AffineEdwards.of_compressed_opt hash_hex in + match p_opt with + | None -> None + | Some p -> + let p = Jubjub.AffineEdwards.(mul p (Scalar.of_z cofactor)) in + if Jubjub.AffineEdwards.is_zero p then None else Some p + +let find_group_hash message personalisation = + let rec aux i = + let message = + Bytes.concat Bytes.empty [message; Bytes.make 1 (char_of_int i)] + in + let p = group_hash message personalisation in + match p with None -> aux (i + 1) | Some p -> p + in + aux 0 diff --git a/src/lib_mec/group_hash.mli b/src/lib_mec/group_hash.mli new file mode 100644 index 000000000000..23792f50c9ff --- /dev/null +++ b/src/lib_mec/group_hash.mli @@ -0,0 +1,25 @@ +(*****************************************************************************) +(* *) +(* Copyright (c) 2021 Danny Willems *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +val find_group_hash : Bytes.t -> Bytes.t -> Jubjub.AffineEdwards.t diff --git a/src/lib_mec/hades.ml b/src/lib_mec/hades.ml new file mode 100644 index 000000000000..1e47c50da379 --- /dev/null +++ b/src/lib_mec/hades.ml @@ -0,0 +1,115 @@ +module type PARAMETERS = sig + val width : int + + val full_rounds : int + + val partial_rounds : int + + val round_constants : string array + + val linear_transformation : string array array + + val partial_round_idx_to_permute : int + + val alpha : Z.t +end + +module Make (Param : PARAMETERS) (Scalar : Bls12_381.Ff_sig.PRIME) = struct + open Param + + (* Verify: - the constants are consistent - the sbox is a permutation, i.e. + pgcd(alpha, p - 1) = 1 + + IMPROVEME: - Verify the linear layer is secure. It requiers to implement + different algorithms in Caml, and it does require a bit of code about + linear algebra not available in the ecosystem AFAIK. Use the sage scripts + in the meantime *) + let () = + assert (Array.length linear_transformation = width) ; + assert ( + Array.for_all + (fun line -> Array.length line = width) + linear_transformation) ; + assert (Z.(equal (gcd (Z.pred Scalar.order) alpha) one)) + + let linear_transformation = + Array.map (Array.map Scalar.of_string) linear_transformation + + let round_constants = Array.map Scalar.of_string round_constants + + (* Initialize only once an array for the MDS matrix multiplication *) + let res = Array.make width Scalar.zero + + type state = {mutable i_round_key : int; state : Scalar.t array} + + let init state = + if Array.length state != width then + failwith + (Printf.sprintf + "State length is %d, but the width of the strategy is %d" + (Array.length state) + width) + else {i_round_key = 0; state = Array.copy state} + + let get_next_round_key s = + let v = round_constants.(s.i_round_key) in + s.i_round_key <- s.i_round_key + 1 ; + v + + let substitution x = Scalar.(pow x alpha) + + (* Functions prefixed with apply_ are modifying the state given in + parameters *) + let apply_round_key s = + let state = s.state in + for i = 0 to Array.length state - 1 do + state.(i) <- Scalar.(get_next_round_key s + state.(i)) + done + + let apply_substitution_last_elem s = + let s = s.state in + s.(partial_round_idx_to_permute) <- + substitution s.(partial_round_idx_to_permute) + + let apply_substitution s = + let s = s.state in + for i = 0 to Array.length s - 1 do + s.(i) <- substitution s.(i) + done + + let apply_permutation m v = + let v = v.state in + for j = 0 to width - 1 do + for k = 0 to width - 1 do + res.(k) <- Scalar.(res.(k) + (m.(k).(j) * v.(j))) + done + done ; + for j = 0 to width - 1 do + v.(j) <- res.(j) ; + res.(j) <- Scalar.zero + done + + let apply_partial_round s = + apply_round_key s ; + apply_substitution_last_elem s ; + apply_permutation linear_transformation s + + let apply_full_round s = + apply_round_key s ; + apply_substitution s ; + apply_permutation linear_transformation s + + let apply s = + s.i_round_key <- 0 ; + for _i = 0 to (full_rounds / 2) - 1 do + apply_full_round s + done ; + for _i = 0 to partial_rounds - 1 do + apply_partial_round s + done ; + for _i = 0 to (full_rounds / 2) - 1 do + apply_full_round s + done + + let get s = Array.copy s.state +end diff --git a/src/lib_mec/hades.mli b/src/lib_mec/hades.mli new file mode 100644 index 000000000000..a4d346b77d8f --- /dev/null +++ b/src/lib_mec/hades.mli @@ -0,0 +1,50 @@ +(** HADES Strategy, based on {{: https://eprint.iacr.org/2019/1107.pdf } On a + Generalization of Substitution-Permutation Networks: The HADES Design + Strategy} *) + +module type PARAMETERS = sig + (** The state size *) + val width : int + + (** The total number of full rounds *) + val full_rounds : int + + (** The number of partial rounds *) + val partial_rounds : int + + (** The round constants, given in decimal representation + + Secure round constants can be constructed using {{: + https://gitlab.com/dannywillems/ocaml-ec/-/tree/master/utils/poseidon-hash + } Sage scripts provided in this repository } *) + val round_constants : string array + + (** The linear transformation, given in decimal representation. + + Secure linear transformations can be constructed using {{: + https://gitlab.com/dannywillems/ocaml-ec/-/tree/master/utils/poseidon-hash + } Sage scripts provided in this repository } *) + val linear_transformation : string array array + + (** The index of the element of the state to permute during the partial + rounds *) + val partial_round_idx_to_permute : int + + (** The exponent to be used in the sbox *) + val alpha : Z.t +end + +(** Build an HADES SP network based on the parameters and a scalar field *) +module Make (Param : PARAMETERS) (Scalar : Bls12_381.Ff_sig.PRIME) : sig + (** The state of the permutation *) + type state + + (** Initialize the state with the given input *) + val init : Scalar.t array -> state + + (** Apply a complete permutation *) + val apply : state -> unit + + (** Return the current scalar elements in the state *) + val get : state -> Scalar.t array +end diff --git a/src/lib_mec/hades_linear_optimisation.ml b/src/lib_mec/hades_linear_optimisation.ml new file mode 100644 index 000000000000..9174f434248c --- /dev/null +++ b/src/lib_mec/hades_linear_optimisation.ml @@ -0,0 +1,512 @@ +module MakePoly (R : Bls12_381.Ff_sig.PRIME) = struct + (* We encode the polynomials as a list with decreasing degree. + Invariants to respect for the type: + - all coefficients are non null. + - [a_n * X^n + ... a_1 X + a0] is encoded as [a_n ; ... ; a_1 ; a_0] with [a_i] + non zero for all [i], i.e. the monomials are given in decreasing order. + - the zero polynomial is represented as the empty list. + *) + type t = (R.t * int) list + + let zero = [] + + let one = [(R.one, 0)] + + let of_coefficients l = + (* check if the powers are all positive *) + assert (List.for_all (fun (_e, power) -> power >= 0) l) ; + (* Remove null coefficients *) + let l = List.filter (fun (e, _power) -> not (R.is_zero e)) l in + (* sort by the power, higher power first *) + let l = + List.fast_sort + (fun (_e1, power1) (_e2, power2) -> Int.sub power2 power1) + l + in + l + + let get_dense_polynomial_coefficients polynomial = + match polynomial with + | [] -> [R.zero] + | l -> + let l = List.rev l in + let rec to_dense acc current_i l = + match l with + | [] -> acc + | (e, n) :: xs -> + if n = current_i then to_dense (e :: acc) (current_i + 1) xs + else to_dense (R.zero :: acc) (current_i + 1) l + in + to_dense [] 0 l + + let add p1 p2 = + let rec inner acc l1 l2 = + match (l1, l2) with + | [], l | l, [] -> List.rev_append acc l + | l1, l2 -> + let e1, p1 = List.hd l1 in + let e2, p2 = List.hd l2 in + if p1 = p2 && R.is_zero (R.add e1 e2) then + inner acc (List.tl l1) (List.tl l2) + else if p1 = p2 then + inner ((R.add e1 e2, p1) :: acc) (List.tl l1) (List.tl l2) + else if p1 > p2 then inner ((e1, p1) :: acc) (List.tl l1) l2 + else inner ((e2, p2) :: acc) l1 (List.tl l2) + in + let l = inner [] p1 p2 in + of_coefficients l + + let mul p q = + let mul_by_monom (scalar, int) p = + List.map (fun (scalar_2, int_2) -> (R.mul scalar scalar_2, int + int_2)) p + in + List.fold_left (fun acc monom -> add acc (mul_by_monom monom q)) zero p + + let equal p1 p2 = + if List.compare_lengths p1 p2 != 0 then false + else List.for_all2 (fun (e1, n1) (e2, n2) -> n1 = n2 && R.eq e1 e2) p1 p2 + + let opposite poly = List.(rev (rev_map (fun (a, i) -> (R.negate a, i)) poly)) + + let sub p1 p2 = + let rec inner acc l1 l2 = + match (l1, l2) with + | [], l2 -> List.rev_append acc (opposite l2) + | l1, [] -> List.rev_append acc l1 + | l1, l2 -> + let e1, p1 = List.hd l1 in + let e2, p2 = List.hd l2 in + if p1 = p2 && R.is_zero (R.sub e1 e2) then + inner acc (List.tl l1) (List.tl l2) + else if p1 = p2 then + inner ((R.sub e1 e2, p1) :: acc) (List.tl l1) (List.tl l2) + else if p1 > p2 then inner ((e1, p1) :: acc) (List.tl l1) l2 + else inner ((R.negate e2, p2) :: acc) l1 (List.tl l2) + in + let l = inner [] p1 p2 in + of_coefficients l + + let ( - ) = sub + + let ( * ) = mul +end + +let compute_updated_constants_one_batch (type a) + (module Fp : Bls12_381.Ff_sig.PRIME with type t = a) width batch_size mds + k_cols = + let var_name ?(s2 = "") s1 i = s1 ^ "_" ^ string_of_int i ^ s2 in + (* We will represent the variables with monomials of increasing degree. + For width = 3 and batch = 4, we would have the following matching: + x_0, x_1, x_2^5, a, a^5, b, b^5, c, c^5, y_0, y_1, y_2 + | | | | | | | | | | | | + x^1, x^2, x^3, x^4, x^5, x^6, x^7, x^8, x^9, x^10, x^11, x^12 *) + let module Poly = MakePoly (Fp) in + let module Poly_Module = Linear_algebra.Make_Module (struct + include Poly + + type t = Poly.t + + let eq = Poly.equal + + let negate p = Poly.(sub zero p) + + let mul = Poly.( * ) + end) in + (* For convenience, we will store the variables and their degree in a + StringMap: key = variable's name, value = degree. *) + let module SMap = Map.Make (String) in + let varsMap = + let vars = + (* The initial state of the batch: x_0, ..., x_{width-2}, x_{width-1}^alpha. *) + let init_state = + List.init width (fun i -> + if i != width - 1 then var_name "x" i + else var_name "x" i ~s2:"^alpha") + in + (* The temporary variables of the batch: + tmp_0 (= a above), tmp_0^5, ..., tmp_{batch-2}, tmp_{batch-2}^5. *) + let tmp = + List.concat + (List.init (batch_size - 1) (fun i -> + [var_name "tmp" i; var_name "tmp" i ~s2:"^alpha"])) + in + (* The final state of the batch: y_0, ..., y_{width-1}. *) + let final_state = List.init width (fun i -> var_name "y" i) in + init_state @ tmp @ final_state + in + SMap.of_seq @@ List.(to_seq @@ mapi (fun i s -> (s, i + 1)) vars) + in + let get_var s = try SMap.find s varsMap with e -> raise e in + let pvar s = Poly.of_coefficients [(Fp.one, get_var s)] in + + (* We store in variable "state", the state after the first SBox. *) + let state = + (* [| [| pvar "x0" |]; [| pvar "x1" |]; [| pvar "x2_5" |] |] *) + Array.init width (fun i -> + if i != width - 1 then [|pvar (var_name "x" i)|] + else [|pvar (var_name "x" i ~s2:"^alpha")|]) + in + + (* We convert the MDS and round constants into matrices of constant polynomials. *) + let to_poly = Array.(map (map (fun c -> Poly.of_coefficients [(c, 0)]))) in + let matrix = to_poly mds in + let k_cols = Array.map to_poly k_cols in + + (* Computing tmp state and saving corresponding polys for each of them. + a = α_31 x_0 + α_32 x_1 + α_33 x_2^alpha + κ_0 + b = β_1 x_1 + β_2 x_1 + β_3 x_2^alpha + β_a a^5 + κ_b + c = γ_1 x_1 + γ_2 x_1 + γ_3 x_2^alpha + γ_a a^5 + γ_b b^5 + κ_c + *) + let dummy_list = List.init (batch_size - 1) (fun i -> i) in + let state, polys = + List.fold_left + (fun (acc_state, acc_poly) i -> + (* Updating state by applying the MDS matrix and round constants. *) + let state = Poly_Module.(add (mul matrix acc_state) @@ k_cols.(i)) in + (* Updating state by applying SBox, defining the next tmp var + and saving tmp state to retrieve coeffs later. *) + let permuted_var = pvar (var_name "tmp" i) in + let poly = Poly.(state.(Int.pred width).(0) - permuted_var) in + state.(width - 1) <- [|pvar (var_name "tmp" i ~s2:"^alpha")|] ; + (state, poly :: acc_poly)) + (state, []) + dummy_list + in + let polys_tmp_var = List.rev polys in + + (* Computing last state. + y_0 = δ_11 x_0 + δ_12 x_1 + δ_13 x_2^alpha + δ_1a a^alpha + δ_1b b^alpha + δ_1c c^alpha + κ_y1 + y_1 = δ_21 x_0 + δ_22 x_1 + δ_23 x_2^alpha + δ_2a a^alpha + δ_2b b^alpha + δ_2c c^alpha + κ_y2 + y_2 = δ_31 x_0 + δ_32 x_1 + δ_33 x_2^alpha + δ_3a a^alpha + δ_3b b^alpha + δ_3c c^alpha + κ_y3 + *) + let state = Poly_Module.(add (mul matrix state) @@ k_cols.(batch_size - 1)) in + (* Saving final polynomials to retrieve coeffs later. *) + let polys_final = + List.init width (fun i -> Poly.(state.(i).(0) - pvar (var_name "y" i))) + in + + let polys = + let nb_coefs = SMap.cardinal varsMap + 1 in + let row_of_eq eq = + (* This function gives coefficients in decending order of degree *) + let coeffs = Poly.get_dense_polynomial_coefficients eq in + let size = nb_coefs - List.length coeffs in + List.(rev coeffs @ init size (fun _ -> Fp.zero)) |> Array.of_list + in + List.map row_of_eq (polys_tmp_var @ polys_final) + in + (* We retrieve the updated coefficients and round constants for each round/poly. *) + let coeffs, _, _ = + (* We list the name of the variables whose coeff need to be retrieved. *) + let vars = + List.init width (fun i -> + if i != width - 1 then var_name "x" i else var_name "x" i ~s2:"^alpha") + in + (* We iterate over each equations/polys in the paper (c.f. page 8 Fig 5). *) + List.fold_left + (fun (coeffs, i, vars) poly -> + (* For each batched round, we retrieve the constants: the coefficients + first followed by the round constant. *) + let coeffs = + coeffs @ List.map (fun s -> poly.(get_var s)) vars @ [poly.(0)] + in + (* We update vars by appending the new tmp variable. *) + let new_var = [var_name "tmp" i ~s2:"^alpha"] in + let vars = if i < batch_size - 1 then vars @ new_var else vars in + (* We retrieve the round constant, which is the polynomial constant. *) + (coeffs, i + 1, vars)) + ([], 0, vars) + polys + in + coeffs + +let compute_updated_constants (type a) + (module Fp : Bls12_381.Ff_sig.PRIME with type t = a) r_p r_f width + batch_size arc mds = + (* We retrieve the partial rounds' round constants by offsetting with the + number of constants used in the first full rounds and the first shifted + partial round. *) + let arc_offset = (r_f * width / 2) + width in + let nb_batch = r_p / batch_size in + let arc_per_batch = batch_size * width in + (* We retrieve the ARC constants for each batch. *) + let batched_arc = + Array.init nb_batch (fun i -> + Array.sub arc (arc_offset + (i * arc_per_batch)) arc_per_batch) + in + (* We retrieve the remaining ARC constants. *) + let unbatched_arc_offset = arc_offset + (arc_per_batch * nb_batch) in + let unbatched_arc_size = r_p mod batch_size * width in + let unbatched_arc = Array.sub arc unbatched_arc_offset unbatched_arc_size in + (* The remainin constants are for the last set of full rounds. As a round ends + with adding the round keys, there are (r_f / 2 - 1) * width constants left *) + let arc_full_round_end = + Array.sub + arc + (unbatched_arc_offset + unbatched_arc_size) + (((r_f / 2) - 1) * width) + in + let constants = + Array.fold_left + (fun acc ks -> + (* We split the ARC constants per batch in chunks of size width and + format them in a matrix, each batch corresponding to the constants + used in one partial round.*) + let k_cols = + Array.init batch_size (fun i -> + Array.init width (fun j -> [|ks.((i * width) + j)|])) + in + let batch_constants = + compute_updated_constants_one_batch + (module Fp) + width + batch_size + mds + k_cols + in + acc @ batch_constants) + [] + batched_arc + in + let arc_full_round_start = Array.sub arc 0 arc_offset in + ( arc_full_round_start, + Array.of_list constants, + unbatched_arc, + arc_full_round_end ) + +module type PARAMETERS = sig + (** The state size *) + val width : int + + (** The total number of full rounds *) + val full_rounds : int + + (** The number of partial rounds *) + val partial_rounds : int + + (** The number of partial round to batch. It must be between 1 and the number + of partial rounds *) + val batch_size : int + + (** The round constants, given in decimal representation + + Secure round constants can be constructed using {{: + https://gitlab.com/dannywillems/ocaml-ec/-/tree/master/utils/poseidon-hash + } Sage scripts provided in this repository } *) + val round_constants : string array + + (** The linear transformation, given in decimal representation. + + Secure linear transformations can be constructed using {{: + https://gitlab.com/dannywillems/ocaml-ec/-/tree/master/utils/poseidon-hash + } Sage scripts provided in this repository } *) + val linear_transformation : string array array + + (** The index of the element of the state to permute during the partial + rounds *) + val partial_round_idx_to_permute : int + + (** The exponent to be used in the sbox *) + val alpha : Z.t +end + +module Make (Param : PARAMETERS) (Scalar : Bls12_381.Ff_sig.PRIME) = struct + open Param + + (* Verify: + - the constants are consistent + - the sbox is a permutation, i.e. pgcd(alpha, p - 1) = 1 + + IMPROVEME: + - Verify the linear layer is secure. It requiers to implement + different algorithms in Caml, and it does require a bit of code about + linear algebra not available in the ecosystem AFAIK. Use the sage scripts + in the meantime + - chechk the batch size consistency + *) + let () = + assert (Array.length linear_transformation = width) ; + assert ( + Array.for_all + (fun line -> Array.length line = width) + linear_transformation) ; + assert (batch_size >= 1 && batch_size <= partial_rounds) ; + assert (Z.(equal (gcd (Z.pred Scalar.order) alpha) one)) + + let linear_transformation = + Array.map (Array.map Scalar.of_string) linear_transformation + + let round_constants = Array.map Scalar.of_string round_constants + + let nb_batched_partial_rounds = Param.(partial_rounds / batch_size) + + let nb_unbatched_partial_rounds = Param.(partial_rounds mod batch_size) + + (* We compute the round constants on the fly, when initializing the module *) + let ( arc_full_round_start_with_first_partial, + arc_intermediate_state, + arc_unbatched, + arc_full_round_end ) = + compute_updated_constants + (module Scalar) + Param.partial_rounds + Param.full_rounds + Param.width + Param.batch_size + round_constants + linear_transformation + + let round_constants = + Array.concat + [ + arc_full_round_start_with_first_partial; + arc_intermediate_state; + arc_unbatched; + arc_full_round_end; + (* Adding for the last round as we apply the round key at the end of + a full round *) + Array.make width Scalar.zero; + ] + + (* Initialize only once an array for the MDS matrix multiplication *) + let res = Array.make width Scalar.zero + + type state = {mutable i_round_key : int; state : Scalar.t array} + + let init state = + if Array.length state != width then + failwith + (Printf.sprintf + "State length is %d, but the width of the strategy is %d" + (Array.length state) + width) + else {i_round_key = 0; state = Array.copy state} + + let get_next_round_key s = + let v = round_constants.(s.i_round_key) in + s.i_round_key <- s.i_round_key + 1 ; + v + + let substitution x = Scalar.(pow x alpha) + + (* Functions prefixed with apply_ modify the state given in + parameters *) + let apply_round_key s = + let state = s.state in + for i = 0 to Array.length state - 1 do + let r = get_next_round_key s in + state.(i) <- Scalar.(r + state.(i)) + done + + let apply_substitution_last_elem s = + let s = s.state in + s.(partial_round_idx_to_permute) <- + substitution s.(partial_round_idx_to_permute) + + let apply_substitution s = + let s = s.state in + for i = 0 to Array.length s - 1 do + s.(i) <- substitution s.(i) + done + + let apply_permutation m v = + let v = v.state in + for j = 0 to width - 1 do + for k = 0 to width - 1 do + res.(k) <- Scalar.(res.(k) + (m.(k).(j) * v.(j))) + done + done ; + for j = 0 to width - 1 do + v.(j) <- res.(j) ; + res.(j) <- Scalar.zero + done + + let apply_partial_round s = + (* First, we apply the substitution *) + apply_substitution_last_elem s ; + (* And after that, we apply the linear transformation followed by the + constant *) + apply_permutation linear_transformation s ; + apply_round_key s + + let apply_batched_partial_round s = + let nb_tmp_vars = Param.batch_size - 1 in + (* We want to compute + [s0, s1, s2^5, var_1^5, ..., var_n^5] to use it when computing the final + state. + The final state is simply a linear combinaison of this list. + var_1 := a0 * s0 + a1 * s1 + a2 * s2^5 + kappa + We will compute + acc = (a0 * s0) + zero + acc = (a1 * s1) + acc + acc = (a2 * s2^5) + acc + acc = acc + kappa + We can do the first 3 additions with a fold_right on [s2^5, s1, s0] + starting with zero, and we add kappa at the end. + For var_i, we will do the same on [var_(i - 1)^5, ..., var_1^5, s2^5, + ..., s0] + *) + let rec aux i interm_state = + if i = nb_tmp_vars then interm_state + else + let res = + List.fold_right + (fun interm_state_i acc -> + Scalar.(acc + (interm_state_i * get_next_round_key s))) + interm_state + Scalar.zero + in + let res = Scalar.(res + get_next_round_key s) in + let res = substitution res in + aux (i + 1) (res :: interm_state) + in + (* get [s2, s1, s0] *) + let interm_state = List.rev (Array.to_list s.state) in + (* call aux with s2^5 :: [s1, s0] *) + let interm_state = + substitution (List.hd interm_state) :: List.tl interm_state + in + let interm_state = aux 0 interm_state in + Array.iteri + (fun i _ -> + let res = + List.fold_right + (fun interm_state_i acc -> + Scalar.(acc + (interm_state_i * get_next_round_key s))) + interm_state + Scalar.zero + in + let res = Scalar.(res + get_next_round_key s) in + Array.set s.state i res) + s.state + + let apply_full_round s = + (* We apply the substitution, followed by the linear transformation and the + round constant *) + apply_substitution s ; + apply_permutation linear_transformation s ; + apply_round_key s + + let apply s = + s.i_round_key <- 0 ; + (* We apply the first round constants (as rounds are shifted) *) + apply_round_key s ; + (* We apply the first set of full rounds *) + for _i = 0 to (full_rounds / 2) - 1 do + apply_full_round s + done ; + (* We apply the optimized batched partial rounds *) + for _i = 0 to nb_batched_partial_rounds - 1 do + apply_batched_partial_round s + done ; + (* We apply the remaining unbatched partial rounds *) + for _i = 0 to nb_unbatched_partial_rounds - 1 do + apply_partial_round s + done ; + (* We apply the last set of full rounds *) + for _i = 0 to (full_rounds / 2) - 1 do + apply_full_round s + done + + let get s = Array.copy s.state +end diff --git a/src/lib_mec/hades_linear_optimisation.mli b/src/lib_mec/hades_linear_optimisation.mli new file mode 100644 index 000000000000..8c1d47813cfc --- /dev/null +++ b/src/lib_mec/hades_linear_optimisation.mli @@ -0,0 +1,43 @@ +(** Update the constants for the linear trick *) +val compute_updated_constants : + (module Bls12_381.Ff_sig.PRIME with type t = 'a) -> + int -> + int -> + int -> + int -> + 'a array -> + 'a array array -> + 'a array * 'a array * 'a array * 'a array + +module type PARAMETERS = sig + val width : int + + val full_rounds : int + + val partial_rounds : int + + val batch_size : int + + val round_constants : string array + + val linear_transformation : string array array + + val partial_round_idx_to_permute : int + + val alpha : Z.t +end + +(** Build an HADES SP network based on the parameters and a scalar field *) +module Make (Param : PARAMETERS) (Scalar : Bls12_381.Ff_sig.PRIME) : sig + (** The state of the permutation *) + type state + + (** Initialize the state with the given input *) + val init : Scalar.t array -> state + + (** Apply a complete permutation *) + val apply : state -> unit + + (** Return the current scalar elements in the state *) + val get : state -> Scalar.t array +end diff --git a/src/lib_mec/iterator.ml b/src/lib_mec/iterator.ml new file mode 100644 index 000000000000..a74cbcb07d0b --- /dev/null +++ b/src/lib_mec/iterator.ml @@ -0,0 +1,54 @@ +type bit = int + +module Bit = struct + type t = {f : unit -> bit option; size : int; mutable i : int} + + let of_bytes_le b = + let length = Bytes.length b in + if length = 0 then {f = (fun () -> None); size = 0; i = 0} + else + let current_byte_int = ref (Bytes.get_uint8 b 0) in + let i = ref 0 in + let j = ref 0 in + let rec f () : bit option = + if !i = length - 1 && !j = 8 then None + else if !j = 8 then ( + i := !i + 1 ; + current_byte_int := Bytes.get_uint8 b !i ; + j := 0 ; + f ()) + else + let b = !current_byte_int mod 2 in + j := !j + 1 ; + current_byte_int := !current_byte_int lsr 1 ; + Some b + in + {f; size = length * 8; i = 0} + + let is_processed {f = _; size; i} = size = i + + let of_bool_list bs = + let bs_ref = ref bs in + let length = List.length bs in + if length = 0 then {f = (fun () -> None); size = length; i = 0} + else + let f () = + match !bs_ref with + | [] -> None + | b :: bs -> + bs_ref := bs ; + Some (if b then 1 else 0) + in + {f; size = length; i = 0} + + let next iterator = + if is_processed iterator then None + else + let res = iterator.f () in + iterator.i <- iterator.i + 1 ; + res + + let get_chunk iterator ?(default = 0) n = + if is_processed iterator then List.init n (fun _ -> default) + else List.init n (fun _ -> Option.value (next iterator) ~default) +end diff --git a/src/lib_mec/iterator.mli b/src/lib_mec/iterator.mli new file mode 100644 index 000000000000..af3ef5ad6837 --- /dev/null +++ b/src/lib_mec/iterator.mli @@ -0,0 +1,15 @@ +type bit = int + +module Bit : sig + type t + + val of_bytes_le : Bytes.t -> t + + val is_processed : t -> bool + + val of_bool_list : bool list -> t + + val next : t -> bit option + + val get_chunk : t -> ?default:int -> int -> bit list +end diff --git a/src/lib_mec/jubjub.ml b/src/lib_mec/jubjub.ml new file mode 100644 index 000000000000..e41eb190b882 --- /dev/null +++ b/src/lib_mec/jubjub.ml @@ -0,0 +1,207 @@ +(** + https://github.com/daira/jubjub + + Base field: 52435875175126190479447740508185965837690552500527637822603658699938581184513 (254 bits - 32 bytes) + Scalar field: 6554484396890773809930967563523245729705921265872317281365359162392183254199 (251 bits - 32 bytes) + + Base field multiplicative subgroup decomposition: + 2^32 * 3 * 11 * 19 * 10177 * 125527 * 859267 * 906349^2 * 2508409 * 2529403 * 52437899 * 254760293^2 + + Prime field multiplication subgroup decomposition: + 2 * 3 * 12281 * 88951556562858260862727893541829461901934170206990707615630637602694993 +*) + +module Base = Ff.MakeFp (struct + let prime_order = + Z.of_string + "52435875175126190479447740508185965837690552500527637822603658699938581184513" +end) + +module Scalar = Ff.MakeFp (struct + let prime_order = + Z.of_string + "6554484396890773809930967563523245729705921265872317281365359162392183254199" +end) + +module AffineEdwards : sig + include + Ec_sig.AffineEdwardsT with type Base.t = Base.t and type Scalar.t = Scalar.t + + val of_compressed_exn : Bytes.t -> t + + val of_compressed_opt : Bytes.t -> t option + + val to_compressed : t -> Bytes.t +end = struct + include + Ec.MakeAffineEdwards (Base) (Scalar) + (struct + let a = Base.(negate one) + + let d = + Base.of_string + "19257038036680949359750312669786877991949435402254120286184196891950884077233" + + let cofactor = Z.of_string "8" + + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Base.( + to_bytes + (of_string + "8076246640662884909881801758704306714034609987455869804520522091855516602923")); + Base.( + to_bytes + (of_string + "13262374693698910701929044844600465831413122818447359594527400194675274060458")); + ] + end) + + let of_compressed_opt b = + (* required to avoid side effect! *) + let b = Bytes.copy b in + let length = Bytes.length b in + if length <> 32 then None + else + (* We get the last bit of the input, representing the bit of u. We also + remove the last bit from the bytes we received + *) + let last_byte = int_of_char @@ Bytes.get b (length - 1) in + let sign = last_byte lsr 7 in + let last_byte_without_sign = last_byte land 0b01111111 in + Bytes.set b (length - 1) (char_of_int last_byte_without_sign) ; + (* We compute u *) + let v = Base.of_bytes_opt b in + match v with + | None -> None + | Some v -> ( + (* Isolate u^2 *) + (* a u^2 + v^2 = 1 + d u^2 v^2 *) + (* <==> a u^2 - d u^2 v^2 = 1 - v^2 *) + (* <==> u^2 (a - d v^2) = 1 - v^2 *) + (* <==> u^2 = (1 - v^2) / (a - d v^2) *) + let vv = Base.(v * v) in + let dvv = Base.(d * vv) in + let num = Base.(one + negate vv) in + let den = Base.(a + negate dvv) in + let uu = Base.(num / den) in + let u_opt = Base.sqrt_opt uu in + let u = + match u_opt with + | None -> None + | Some u -> + (* computed before for constant time *) + let negated_u = Base.negate u in + let u_first_byte = Bytes.get (Base.to_bytes u) 0 in + let is_sign_flipped = + int_of_char u_first_byte lxor sign land 1 + in + Some (if is_sign_flipped = 0 then u else negated_u) + in + match u with + | Some u -> Some (unsafe_from_coordinates ~u ~v) + | None -> None) + + let of_compressed_exn b = + match of_compressed_opt b with + | None -> raise (Not_on_curve b) + | Some p -> p + + let to_compressed p = + let u = get_u_coordinate p in + let v = get_v_coordinate p in + let u_bytes = Base.to_bytes u in + let v_bytes = Base.to_bytes v in + let u_first_byte = int_of_char (Bytes.get u_bytes 0) in + let v_last_byte = + int_of_char (Bytes.get v_bytes (Base.size_in_bytes - 1)) + in + (* Get the first bit of u, i.e. the sign of u *) + let sign_of_u = u_first_byte land 0b00000001 in + (* Set the last bit of the last byte of v to the sign of u *) + let v_last_byte_with_u = v_last_byte lor (sign_of_u lsl 7) in + Bytes.set v_bytes (Base.size_in_bytes - 1) (char_of_int v_last_byte_with_u) ; + v_bytes +end + +module AffineMontgomery = + Ec.MakeAffineMontgomery (Base) (Scalar) + (struct + let a = Base.of_string "40962" + + let b = + Base.of_string + "52435875175126190479447740508185965837690552500527637822603658699938581143549" + + let cofactor = Z.of_int 8 + + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Base.( + to_bytes + (of_string + "37380265172535953876205871964221324158436172047572074969815349807835370906304")); + Base.( + to_bytes + (of_string + "14806724895810515565537763359156126150942240025109370624530515646853716216120")); + ] + end) + +module AffineWeierstrass = + Ec.MakeAffineWeierstrass (Base) (Scalar) + (struct + let a = + Base.of_string + "52296097456646850916096512823759002727550416093741407922227928430486925478210" + + let b = + Base.of_string + "48351165704696163914533707656614864561753505123260775585269522553028192119009" + + let cofactor = Z.of_int 8 + + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Base.( + to_bytes + (of_string + "33835869156188682335217394949746694649676633840125476177319971163079011318731")); + Base.( + to_bytes + (of_string + "43777270878440091394432848052353307184915192688165709016756678962558652055320")); + ] + end) + +let from_affine_edwards_to_affine_montgomery p = + Ec.from_affine_edwards_to_affine_montgomery + (module AffineEdwards) + (module AffineMontgomery) + p + +let from_affine_montgomery_to_affine_edwards p = + Ec.from_affine_montgomery_to_affine_edwards + (module AffineMontgomery) + (module AffineEdwards) + p + +let from_affine_montgomery_to_affine_weierstrass p = + Ec.from_affine_montgomery_to_affine_weierstrass + (module AffineMontgomery) + (module AffineWeierstrass) + p + +let from_affine_edwards_to_affine_weierstrass p = + let p = from_affine_edwards_to_affine_montgomery p in + Option.bind p (fun opt -> + Ec.from_affine_montgomery_to_affine_weierstrass + (module AffineMontgomery) + (module AffineWeierstrass) + opt) diff --git a/src/lib_mec/jubjub.mli b/src/lib_mec/jubjub.mli new file mode 100644 index 000000000000..1a588bf9bce0 --- /dev/null +++ b/src/lib_mec/jubjub.mli @@ -0,0 +1,25 @@ +module AffineEdwards : sig + include Ec_sig.AffineEdwardsT + + val of_compressed_exn : Bytes.t -> t + + val of_compressed_opt : Bytes.t -> t option + + val to_compressed : t -> Bytes.t +end + +module AffineWeierstrass : Ec_sig.AffineWeierstrassT + +module AffineMontgomery : Ec_sig.AffineMontgomeryT + +val from_affine_edwards_to_affine_montgomery : + AffineEdwards.t -> AffineMontgomery.t option + +val from_affine_montgomery_to_affine_edwards : + AffineMontgomery.t -> AffineEdwards.t option + +val from_affine_montgomery_to_affine_weierstrass : + AffineMontgomery.t -> AffineWeierstrass.t option + +val from_affine_edwards_to_affine_weierstrass : + AffineEdwards.t -> AffineWeierstrass.t option diff --git a/src/lib_mec/linear_algebra.ml b/src/lib_mec/linear_algebra.ml new file mode 100644 index 000000000000..89c97cc24115 --- /dev/null +++ b/src/lib_mec/linear_algebra.ml @@ -0,0 +1,181 @@ +(** Linear algebra module, copied from {{: + https://gitlab.com/nomadic-labs/privacy-team/-/blob/9e4050cb4a304848901c3434d61a8d7f0c7107c4/nuplompiler/linear_algebra.ml + } Nomadic Labs privacy team repository } *) +module type Ring_sig = sig + type t + + val add : t -> t -> t + + val mul : t -> t -> t + + val negate : t -> t + + val zero : t + + val one : t + + val eq : t -> t -> bool +end + +module type Field_sig = sig + include Ring_sig + + val inverse_exn : t -> t +end + +(** This refers to the mathematical generalization of vector space called + "module", where the field of scalars is replaced by a ring *) +module type Module_sig = sig + type t + + type matrix = t array array + + (** [zeros r c] is a matrix with [r] rows and [c] columns filled with zeros *) + val zeros : int -> int -> matrix + + (** [identity n] is the identity matrix of dimension [n] *) + val identity : int -> matrix + + (** matrix equality *) + val equal : matrix -> matrix -> bool + + (** matrix addition *) + val add : matrix -> matrix -> matrix + + (** matrix multiplication *) + val mul : matrix -> matrix -> matrix + + (** matrix transposition *) + val transpose : matrix -> matrix + + (** [row_add ~coeff i j m] adds to the i-th row, the j-th row times coeff in m *) + val row_add : ?coeff:t -> int -> int -> matrix -> unit + + (** [row_swap i j m] swaps the i-th and j-th rows of m *) + val row_swap : int -> int -> matrix -> unit + + (** [row_mul coeff i m] multiplies the i-th row by coeff in m *) + val row_mul : t -> int -> matrix -> unit + + (** [filter_cols f m] removes the columns of [m] whose index does not satisfy [f] *) + val filter_cols : (int -> bool) -> matrix -> matrix + + (** splits matrix [m] into the first n columns and the rest, producing two matrices *) + val split_n : int -> matrix -> matrix * matrix +end + +module type VectorSpace_sig = sig + include Module_sig + + (** reduced row Echelon form of m *) + val reduced_row_echelon_form : matrix -> matrix + + (** [inverse m] is the inverse matrix of m + + @raise [Invalid_argument] if [m] is not invertible *) + val inverse : matrix -> matrix +end + +module Make_Module (Ring : Ring_sig) : Module_sig with type t = Ring.t = struct + type t = Ring.t + + type matrix = t array array + + let zeros r c = Array.make_matrix r c Ring.zero + + let identity n = + Array.(init n (fun i -> init n Ring.(fun j -> if i = j then one else zero))) + + let equal = Array.(for_all2 (for_all2 Ring.eq)) + + let add = Array.(map2 (map2 Ring.add)) + + let mul m1 m2 = + let nb_rows = Array.length m1 in + let nb_cols = Array.length m2.(0) in + let n = Array.length m1.(0) in + assert (Array.length m2 = n) ; + let p = zeros nb_rows nb_cols in + for i = 0 to nb_rows - 1 do + for j = 0 to nb_cols - 1 do + for k = 0 to n - 1 do + p.(i).(j) <- Ring.(add p.(i).(j) @@ mul m1.(i).(k) m2.(k).(j)) + done + done + done ; + p + + let transpose m = + let nb_rows = Array.length m in + let nb_cols = Array.length m.(0) in + Array.(init nb_cols (fun i -> init nb_rows (fun j -> m.(j).(i)))) + + let row_add ?(coeff = Ring.one) i j m = + m.(i) <- Array.map2 Ring.(fun a b -> add a (mul coeff b)) m.(i) m.(j) + + let row_swap i j m = + let aux = m.(i) in + m.(i) <- m.(j) ; + m.(j) <- aux + + let row_mul coeff i m = m.(i) <- Array.map (Ring.mul coeff) m.(i) + + let filter_cols f = + Array.map (fun row -> + List.filteri (fun i _ -> f i) (Array.to_list row) |> Array.of_list) + + let split_n n m = + (filter_cols (fun i -> i < n) m, filter_cols (fun i -> i >= n) m) +end + +module Make_VectorSpace (Field : Field_sig) : + VectorSpace_sig with type t = Field.t = struct + include Make_Module (Field) + + let reduced_row_echelon_form m = + let n = Array.length m in + (* returns the first non-zero index in the row *) + let find_pivot row = + let rec aux cnt = function + | [] -> None + | x :: xs -> if Field.(eq zero x) then aux (cnt + 1) xs else Some cnt + in + aux 0 (Array.to_list row) + in + let move_zeros_to_bottom m = + let is_non_zero_row = Array.exists (fun a -> not Field.(eq zero a)) in + let rec aux nonzeros zeros = function + | [] -> Array.of_list (List.rev nonzeros @ zeros) + | r :: rs -> + if is_non_zero_row r then aux (r :: nonzeros) zeros rs + else aux nonzeros (r :: zeros) rs + in + aux [] [] (Array.to_list m) + in + let rec aux k = + if k >= Array.length m then m + else + match find_pivot m.(k) with + | Some j when j < n -> + row_mul (Field.inverse_exn m.(k).(j)) k m ; + Array.iteri + (fun i _ -> + if i <> k then row_add ~coeff:Field.(negate @@ m.(i).(j)) i k m) + m ; + row_swap k j m ; + aux (k + 1) + | _ -> aux (k + 1) + in + aux 0 |> move_zeros_to_bottom + + let inverse m = + let n = Array.length m in + let id_n = identity n in + let augmented = Array.(map2 append m id_n) in + let reduced = reduced_row_echelon_form augmented in + let residue, inv = split_n n reduced in + let is_zero_row = Array.for_all Field.(eq zero) in + if Array.exists is_zero_row residue then + raise @@ Invalid_argument "matrix [m] is not invertible" + else inv +end diff --git a/src/lib_mec/marvellous.ml b/src/lib_mec/marvellous.ml new file mode 100644 index 000000000000..5f6aacab7a16 --- /dev/null +++ b/src/lib_mec/marvellous.ml @@ -0,0 +1,97 @@ +module type PARAMETERS = sig + (** The state size *) + val width : int + + (** The number of rounds *) + val rounds : int + + (** The round constants, given in decimal representation *) + val round_constants : string array + + (** The MDS matrix, given in decimal representation *) + val mds_matrix : string array array + + val alpha : Z.t + + val alphainv : Z.t +end + +module Make (Param : PARAMETERS) (Scalar : Bls12_381.Ff_sig.PRIME) = struct + open Param + + (* Verify the constants are consistent *) + let () = + assert (Array.length mds_matrix = width) ; + assert (Array.for_all (fun line -> Array.length line = width) mds_matrix) + + let mds_matrix = Array.map (Array.map Scalar.of_string) mds_matrix + + let round_constants = Array.map Scalar.of_string round_constants + + (* Initialize only once an array for the MDS matrix multiplication *) + let res = Array.make width Scalar.zero + + type state = {mutable i_round_key : int; state : Scalar.t array} + + let init state = + if Array.length state != width then + failwith + (Printf.sprintf + "State length is %d, but the width of the strategy is %d" + (Array.length state) + width) + else {i_round_key = 0; state = Array.copy state} + + let get_next_round_key s = + let v = round_constants.(s.i_round_key) in + s.i_round_key <- s.i_round_key + 1 ; + v + + (* Functions prefixed with apply_ are modifying the state given in + parameters *) + let apply_round_key s = + let state = s.state in + for i = 0 to Array.length state - 1 do + state.(i) <- Scalar.(get_next_round_key s + state.(i)) + done + + let apply_nonlinear_alpha s = + let s = s.state in + for i = 0 to Array.length s - 1 do + s.(i) <- Scalar.pow s.(i) alpha + done + + let apply_nonlinear_alphainv s = + let s = s.state in + for i = 0 to Array.length s - 1 do + s.(i) <- Scalar.pow s.(i) alphainv + done + + let apply_linear m v = + let v = v.state in + for j = 0 to width - 1 do + for k = 0 to width - 1 do + res.(k) <- Scalar.(res.(k) + (m.(k).(j) * v.(j))) + done + done ; + for j = 0 to width - 1 do + v.(j) <- res.(j) ; + res.(j) <- Scalar.zero + done + + let apply_round s = + apply_nonlinear_alpha s ; + apply_linear mds_matrix s ; + apply_round_key s ; + apply_nonlinear_alphainv s ; + apply_linear mds_matrix s ; + apply_round_key s + + let apply s = + s.i_round_key <- 0 ; + for _i = 0 to rounds - 1 do + apply_round s + done + + let get s = Array.copy s.state +end diff --git a/src/lib_mec/marvellous.mli b/src/lib_mec/marvellous.mli new file mode 100644 index 000000000000..7cfa3aa890d6 --- /dev/null +++ b/src/lib_mec/marvellous.mli @@ -0,0 +1,34 @@ +(** Marvellous Strategy, based on {{: https://eprint.iacr.org/2019/426 } Design + of Symmetric-Key Primitives for Advanced Cryptographic Protocols } *) + +module type PARAMETERS = sig + (** The state size *) + val width : int + + (** The number of rounds *) + val rounds : int + + (** The round constants, given in decimal representation *) + val round_constants : string array + + (** The MDS matrix, given in decimal representation *) + val mds_matrix : string array array + + val alpha : Z.t + + val alphainv : Z.t +end + +module Make (Param : PARAMETERS) (Scalar : Bls12_381.Ff_sig.PRIME) : sig + (** The state of the strategy *) + type state + + (** Initialize the state with the given input *) + val init : Scalar.t array -> state + + (** Apply a complete permutation *) + val apply : state -> unit + + (** Return the current scalar elements in the state *) + val get : state -> Scalar.t array +end diff --git a/src/lib_mec/mds_orchard.ml b/src/lib_mec/mds_orchard.ml new file mode 100644 index 000000000000..d785a71f7d2e --- /dev/null +++ b/src/lib_mec/mds_orchard.ml @@ -0,0 +1,18 @@ +let v = + [| + [| + "20318286217486369426965035069836800746749435906016448674636714520170817018807"; + "22192852525643738215947851702151544501993043677579072964990735260534263737314"; + "8542598184567193950383006010698963992683774969143163395442055984920670969658"; + |]; + [| + "7392954993144188510255764707695079827771707557363197189129035318593453738368"; + "27549511735195789329533968803664746807330189702821962130064027535490056177413"; + "13129156644346446682975824711515160071389200876395558249729931114712818796177"; + |]; + [| + "21010686366472749505451494418483718181134873748085457288199401256016616439986"; + "28561190888145054647914513058959252600378056095166705432358200159539002856405"; + "21356544248278733708505686717446976476730796312725621196632235950424803603792"; + |]; + |] diff --git a/src/lib_mec/mds_poseidon128.ml b/src/lib_mec/mds_poseidon128.ml new file mode 100644 index 000000000000..fc4eef5dac77 --- /dev/null +++ b/src/lib_mec/mds_poseidon128.ml @@ -0,0 +1,21 @@ +(* Generated with the command below from commit cd13dd0e984a4eeadd82e0ac4ce792c275bd3b18 + [sage generate_mds.sage 3 NomadicLabs 52435875175126190479447740508185965837690552500527637822603658699938581184513] *) + +let v = + [| + [| + "48527463322097587091854420767453816291840635874249958396342138881138912067190"; + "11996084473350366483175782359948025962778681837397784970341328014763133439499"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + |]; + [| + "43372445583202124108992832749257195116898314930070456682841601188523728879167"; + "22957843818027924237635625446720638788994914691706001027915412076310000455035"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + |]; + [| + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + |]; + |] diff --git a/src/lib_mec/mds_poseidon252.ml b/src/lib_mec/mds_poseidon252.ml new file mode 100644 index 000000000000..4fd75f5f2383 --- /dev/null +++ b/src/lib_mec/mds_poseidon252.ml @@ -0,0 +1,40 @@ +(* Come from https://github.com/dusk-network/Hades252/tree/7a7a255f6cc48f892de5cf8935b5264eb8893852/assets *) + +let v = + [| + [| + "2184067777412762892935100798463195235577775932917057678850053321607193454182"; + "36777306597928096063744411004176639921441848277782639947444150234631715334827"; + "46505084276831565334480278148775967314861742095393016475696031258238207768284"; + "14474011154664524427946373126085988481658748083205070504932198000989141204992"; + "41996829456994127535645520838846415226858083018697639239163986389734003951389"; + |]; + [| + "36777306597928096063744411004176639921441848277782639947444150234631715334827"; + "46505084276831565334480278148775967314861742095393016475696031258238207768284"; + "14474011154664524427946373126085988481658748083205070504932198000989141204992"; + "41996829456994127535645520838846415226858083018697639239163986389734003951389"; + "1092033888706381446467550399231597617788887966458528839425026660803596727091"; + |]; + [| + "46505084276831565334480278148775967314861742095393016475696031258238207768284"; + "14474011154664524427946373126085988481658748083205070504932198000989141204992"; + "41996829456994127535645520838846415226858083018697639239163986389734003951389"; + "1092033888706381446467550399231597617788887966458528839425026660803596727091"; + "20060349053415325125678769638641803593513735424245076334969536491617299273542"; + |]; + [| + "14474011154664524427946373126085988481658748083205070504932198000989141204992"; + "41996829456994127535645520838846415226858083018697639239163986389734003951389"; + "1092033888706381446467550399231597617788887966458528839425026660803596727091"; + "20060349053415325125678769638641803593513735424245076334969536491617299273542"; + "44606590886527143271596075756181302879566200389155138885023904467285148259670"; + |]; + [| + "41996829456994127535645520838846415226858083018697639239163986389734003951389"; + "1092033888706381446467550399231597617788887966458528839425026660803596727091"; + "20060349053415325125678769638641803593513735424245076334969536491617299273542"; + "44606590886527143271596075756181302879566200389155138885023904467285148259670"; + "37141785804861502213823474505076128362854142474564156061360245762114092148579"; + |]; + |] diff --git a/src/lib_mec/mec.ml b/src/lib_mec/mec.ml new file mode 100644 index 000000000000..16a4a191a1d5 --- /dev/null +++ b/src/lib_mec/mec.ml @@ -0,0 +1,59 @@ +open Mec_curve_utils +module Ff = Ff + +module Curve = struct + module BabyJubjub = Babyjubjub + module BabyJubjubReduced = Babyjubjub_reduced + module Bandersnatch = Bandersnatch + module BN254 = Bn254 + module BLS12_381 = Bls12_381_ref + module Curve25519 = Curve25519 + module Curve448 = Curve448 + module Jubjub = Jubjub + module Pallas = Pallas + module Secp256k1 = Secp256k1 + module Secp256r1 = Secp256r1 + module Tweedledee = Tweedledee + module Tweedledum = Tweedledum + module Vesta = Vesta + + module Utils = struct + module PBT = PBT + module Functor = Ec + end +end + +module CurveSig = Ec_sig + +module Hash = struct + module Poseidon252 = Poseidon252 + module Poseidon128 = Poseidon128 + module Orchard = Orchard + module Neptunus = Neptunus + module PedersenHash = Pedersen_hash + module Sinsemilla = Sinsemilla +end + +module Permutation = struct + module Hades = Hades + module Marvellous = Marvellous + module HadesLinearOptimisation = Hades_linear_optimisation +end + +module Signature = struct + module RedDSA = Reddsa + module RedJubjub = Redjubjub +end + +module Protocol = struct + module Sapling = struct + module GroupHash = Group_hash + end +end + +module Digestif = Mec_digestif + +module Utils = struct + module Iterator = Iterator + module LinearAlgebra = Linear_algebra +end diff --git a/src/lib_mec/mec_curve_utils.ml b/src/lib_mec/mec_curve_utils.ml new file mode 100644 index 000000000000..a7b579f68487 --- /dev/null +++ b/src/lib_mec/mec_curve_utils.ml @@ -0,0 +1,5 @@ +module Ec = Ec + +(* Remove me later *) +module Functor = Ec +module PBT = Ec_pbt diff --git a/src/lib_mec/mec_digestif.ml b/src/lib_mec/mec_digestif.ml new file mode 100644 index 000000000000..5ef191a68ebf --- /dev/null +++ b/src/lib_mec/mec_digestif.ml @@ -0,0 +1,410 @@ +type bigstring = + ( char, + Bigarray_compat.int8_unsigned_elt, + Bigarray_compat.c_layout ) + Bigarray_compat.Array1.t + +type 'a iter = ('a -> unit) -> unit + +type 'a compare = 'a -> 'a -> int + +type 'a equal = 'a -> 'a -> bool + +type 'a pp = Format.formatter -> 'a -> unit + +module By = Digestif_by +module Bi = Digestif_bi +module Eq = Digestif_eq +module Conv = Digestif_conv + +let failwith fmt = Format.ksprintf failwith fmt + +module type S = sig + val digest_size : int + + type ctx + + type t + + val empty : ctx + + val init : ?personalisation:Bytes.t -> unit -> ctx + + val feed_bytes : ctx -> ?off:int -> ?len:int -> Bytes.t -> ctx + + val feed_string : ctx -> ?off:int -> ?len:int -> String.t -> ctx + + val feed_bigstring : ctx -> ?off:int -> ?len:int -> bigstring -> ctx + + val feedi_bytes : ctx -> Bytes.t iter -> ctx + + val feedi_string : ctx -> String.t iter -> ctx + + val feedi_bigstring : ctx -> bigstring iter -> ctx + + val get : ctx -> t + + val digest_bytes : ?off:int -> ?len:int -> Bytes.t -> t + + val digest_string : ?off:int -> ?len:int -> String.t -> t + + val digest_bigstring : ?off:int -> ?len:int -> bigstring -> t + + val digesti_bytes : Bytes.t iter -> t + + val digesti_string : String.t iter -> t + + val digesti_bigstring : bigstring iter -> t + + val digestv_bytes : Bytes.t list -> t + + val digestv_string : String.t list -> t + + val digestv_bigstring : bigstring list -> t + + val unsafe_compare : t compare + + val equal : t equal + + val pp : t pp + + val of_hex : string -> t + + val of_hex_opt : string -> t option + + val consistent_of_hex : string -> t + + val consistent_of_hex_opt : string -> t option + + val to_hex : t -> string + + val of_raw_string : string -> t + + val of_raw_string_opt : string -> t option + + val to_raw_string : t -> string +end + +module type Desc = sig + val digest_size : int + + val block_size : int +end + +module type Hash = sig + type ctx + + val init : ?personalisation:Bytes.t -> unit -> ctx + + val unsafe_feed_bytes : ctx -> By.t -> int -> int -> unit + + val unsafe_feed_bigstring : ctx -> Bi.t -> int -> int -> unit + + val unsafe_get : ctx -> By.t + + val dup : ctx -> ctx +end + +module Unsafe (Hash : Hash) (D : Desc) = struct + open Hash + + let digest_size = D.digest_size + + let empty = init () + + let init = init + + let unsafe_feed_bytes ctx ?off ?len buf = + let off, len = + match (off, len) with + | Some off, Some len -> (off, len) + | Some off, None -> (off, By.length buf - off) + | None, Some len -> (0, len) + | None, None -> (0, By.length buf) + in + if off < 0 || len < 0 || off > By.length buf - len then + invalid_arg "offset out of bounds" + else unsafe_feed_bytes ctx buf off len + + let unsafe_feed_string ctx ?off ?len buf = + unsafe_feed_bytes ctx ?off ?len (By.unsafe_of_string buf) + + let unsafe_feed_bigstring ctx ?off ?len buf = + let off, len = + match (off, len) with + | Some off, Some len -> (off, len) + | Some off, None -> (off, Bi.length buf - off) + | None, Some len -> (0, len) + | None, None -> (0, Bi.length buf) + in + if off < 0 || len < 0 || off > Bi.length buf - len then + invalid_arg "offset out of bounds" + else unsafe_feed_bigstring ctx buf off len + + let unsafe_get = unsafe_get +end + +module Core (Hash : Hash) (D : Desc) = struct + type t = string + + type ctx = Hash.ctx + + include Unsafe (Hash) (D) + include Conv.Make (D) + include Eq.Make (D) + + let get t = + let t = Hash.dup t in + unsafe_get t |> By.unsafe_to_string + + let feed_bytes t ?off ?len buf = + let t = Hash.dup t in + unsafe_feed_bytes t ?off ?len buf ; + t + + let feed_string t ?off ?len buf = + let t = Hash.dup t in + unsafe_feed_string t ?off ?len buf ; + t + + let feed_bigstring t ?off ?len buf = + let t = Hash.dup t in + unsafe_feed_bigstring t ?off ?len buf ; + t + + let feedi_bytes t iter = + let t = Hash.dup t in + let feed buf = unsafe_feed_bytes t buf in + iter feed ; + t + + let feedi_string t iter = + let t = Hash.dup t in + let feed buf = unsafe_feed_string t buf in + iter feed ; + t + + let feedi_bigstring t iter = + let t = Hash.dup t in + let feed buf = unsafe_feed_bigstring t buf in + iter feed ; + t + + let digest_bytes ?off ?len buf = feed_bytes empty ?off ?len buf |> get + + let digest_string ?off ?len buf = feed_string empty ?off ?len buf |> get + + let digest_bigstring ?off ?len buf = feed_bigstring empty ?off ?len buf |> get + + let digesti_bytes iter = feedi_bytes empty iter |> get + + let digesti_string iter = feedi_string empty iter |> get + + let digesti_bigstring iter = feedi_bigstring empty iter |> get + + let digestv_bytes lst = digesti_bytes (fun f -> List.iter f lst) + + let digestv_string lst = digesti_string (fun f -> List.iter f lst) + + let digestv_bigstring lst = digesti_bigstring (fun f -> List.iter f lst) +end + +module Make (H : Hash) (D : Desc) = struct + include Core (H) (D) +end + +module type Hash_BLAKE2 = sig + type ctx + + val with_outlen_and_bytes_key : + ?personalisation:Bytes.t -> int -> By.t -> int -> int -> ctx + + val unsafe_feed_bytes : ctx -> By.t -> int -> int -> unit + + val unsafe_feed_bigstring : ctx -> Bi.t -> int -> int -> unit + + val unsafe_get : ctx -> By.t + + val dup : ctx -> ctx + + val max_outlen : int +end + +module Make_BLAKE2 (H : Hash_BLAKE2) (D : Desc) = struct + let () = + if D.digest_size > H.max_outlen then + failwith + "Invalid digest_size:%d to make a BLAKE2{S,B} implementation" + D.digest_size + + include + Make + (struct + type ctx = H.ctx + + let init ?personalisation () = + H.with_outlen_and_bytes_key + (* XXX(dannywillems): adding personalisation *) + ?personalisation + D.digest_size + By.empty + 0 + 0 + + let unsafe_feed_bytes = H.unsafe_feed_bytes + + let unsafe_feed_bigstring = H.unsafe_feed_bigstring + + let unsafe_get = H.unsafe_get + + let dup = H.dup + end) + (D) +end + +module BLAKE2B : sig + include S +end = + Make_BLAKE2 + (Baijiu_blake2b.Unsafe) + (struct + let digest_size, block_size = (64, 128) + end) + +module BLAKE2S : sig + include S +end = + Make_BLAKE2 + (Baijiu_blake2s.Unsafe) + (struct + let digest_size, block_size = (32, 64) + end) + +module Make_BLAKE2B (D : sig + val digest_size : int +end) : S = struct + include + Make_BLAKE2 + (Baijiu_blake2b.Unsafe) + (struct + let digest_size, block_size = (D.digest_size, 128) + end) +end + +module Make_BLAKE2S (D : sig + val digest_size : int +end) : S = struct + include + Make_BLAKE2 + (Baijiu_blake2s.Unsafe) + (struct + let digest_size, block_size = (D.digest_size, 64) + end) +end + +type 'k hash = BLAKE2B : BLAKE2B.t hash | BLAKE2S : BLAKE2S.t hash + +let blake2b = BLAKE2B + +let blake2s = BLAKE2S + +let module_of : type k. k hash -> (module S with type t = k) = function + | BLAKE2B -> (module BLAKE2B) + | BLAKE2S -> (module BLAKE2S) + +type 'hash t = 'hash + +let digest_bytes : type k. k hash -> Bytes.t -> k t = + fun hash buf -> + let module H = (val module_of hash) in + H.digest_bytes buf + +let digest_string : type k. k hash -> String.t -> k t = + fun hash buf -> + let module H = (val module_of hash) in + H.digest_string buf + +let digest_bigstring : type k. k hash -> bigstring -> k t = + fun hash buf -> + let module H = (val module_of hash) in + H.digest_bigstring buf + +let digesti_bytes : type k. k hash -> Bytes.t iter -> k t = + fun hash iter -> + let module H = (val module_of hash) in + H.digesti_bytes iter + +let digesti_string : type k. k hash -> String.t iter -> k t = + fun hash iter -> + let module H = (val module_of hash) in + H.digesti_string iter + +let digesti_bigstring : type k. k hash -> bigstring iter -> k t = + fun hash iter -> + let module H = (val module_of hash) in + H.digesti_bigstring iter + +(* XXX(dinosaure): unsafe part to avoid overhead. *) + +let unsafe_compare : type k. k hash -> k t -> k t -> int = + fun hash a b -> + let module H = (val module_of hash) in + H.unsafe_compare a b + +let equal : type k. k hash -> k t equal = + fun hash a b -> + let module H = (val module_of hash) in + H.equal a b + +let pp : type k. k hash -> k t pp = + fun hash ppf t -> + let module H = (val module_of hash) in + H.pp ppf t + +let of_hex : type k. k hash -> string -> k t = + fun hash hex -> + let module H = (val module_of hash) in + H.of_hex hex + +let of_hex_opt : type k. k hash -> string -> k t option = + fun hash hex -> + let module H = (val module_of hash) in + H.of_hex_opt hex + +let consistent_of_hex : type k. k hash -> string -> k t = + fun hash hex -> + let module H = (val module_of hash) in + H.consistent_of_hex hex + +let consistent_of_hex_opt : type k. k hash -> string -> k t option = + fun hash hex -> + let module H = (val module_of hash) in + H.consistent_of_hex_opt hex + +let to_hex : type k. k hash -> k t -> string = + fun hash t -> + let module H = (val module_of hash) in + H.to_hex t + +let of_raw_string : type k. k hash -> string -> k t = + fun hash s -> + let module H = (val module_of hash) in + H.of_raw_string s + +let of_raw_string_opt : type k. k hash -> string -> k t option = + fun hash s -> + let module H = (val module_of hash) in + H.of_raw_string_opt s + +let to_raw_string : type k. k hash -> k t -> string = + fun hash t -> + let module H = (val module_of hash) in + H.to_raw_string t + +let of_digest (type hash) (module H : S with type t = hash) (hash : H.t) : + hash t = + hash + +let of_blake2b hash = hash + +let of_blake2s hash = hash diff --git a/src/lib_mec/mec_digestif.mli b/src/lib_mec/mec_digestif.mli new file mode 100644 index 000000000000..2e3ddb63c9f0 --- /dev/null +++ b/src/lib_mec/mec_digestif.mli @@ -0,0 +1,215 @@ +(** + This is a fork from {{:https://github.com/mirage/digestif } Digestif }, + commit 891907675ead09b5e1c5de28c24246a0e411a546, adding personalisation to + Blake2. + + When {{: https://github.com/mirage/digestif/issues/111 } this issue } is + solved, this fork can be removed. +*) + +type bigstring = + ( char, + Bigarray_compat.int8_unsigned_elt, + Bigarray_compat.c_layout ) + Bigarray_compat.Array1.t + +(** A general (inner) iterator. It applies the provided function to a collection + of elements. For instance: + + - [let iter_k : 'a -> 'a iter = fun x f -> f x] + - [let iter_pair : 'a * 'a -> 'a iter = fun (x, y) -> f x; f y] + - [let iter_list : 'a list -> 'a iter = fun l f -> List.iter f l] *) +type 'a iter = ('a -> unit) -> unit + +type 'a compare = 'a -> 'a -> int + +type 'a equal = 'a -> 'a -> bool + +type 'a pp = Format.formatter -> 'a -> unit + +module type S = sig + (** Size of hash results, in bytes. *) + val digest_size : int + + type ctx + + type t + + (** An empty hash context. *) + val empty : ctx + + (** Create a new hash state. *) + val init : ?personalisation:Bytes.t -> unit -> ctx + + (** [feed_bytes msg t] adds informations in [msg] to [t]. [feed] is analogous + to appending: [feed (feed t msg1) msg2 = feed t (append msg1 msg2)] *) + val feed_bytes : ctx -> ?off:int -> ?len:int -> Bytes.t -> ctx + + (** Same as {!feed_bytes} but for {!String.t}. *) + val feed_string : ctx -> ?off:int -> ?len:int -> String.t -> ctx + + (** Same as {!feed_bytes} but for {!bigstring}. *) + val feed_bigstring : ctx -> ?off:int -> ?len:int -> bigstring -> ctx + + (** [feedi_bytes t iter = let r = ref t in iter (fun msg -> r := feed !r msg); + !r] *) + val feedi_bytes : ctx -> Bytes.t iter -> ctx + + (** Same as {!feed_bytes} but for {!String.t}. *) + val feedi_string : ctx -> String.t iter -> ctx + + (** Same as {!feed_bytes} but for {!bigstring}. *) + val feedi_bigstring : ctx -> bigstring iter -> ctx + + (** [get t] is the digest corresponding to [t]. *) + val get : ctx -> t + + (** [digest_bytes msg] is the digest of [msg]. + + [digest_bytes msg = get (feed_bytes empty msg)]. *) + val digest_bytes : ?off:int -> ?len:int -> Bytes.t -> t + + (** Same as {!digest_bytes} but for a {!String.t}. *) + val digest_string : ?off:int -> ?len:int -> String.t -> t + + (** Same as {!digest_bytes} but for a {!bigstring}. *) + val digest_bigstring : ?off:int -> ?len:int -> bigstring -> t + + (** [digesti_bytes iter = feedi_bytes empty iter |> get]. *) + val digesti_bytes : Bytes.t iter -> t + + (** Same as {!digesti_bytes} but for {!String.t}. *) + val digesti_string : String.t iter -> t + + (** Same as {!digesti_bigstring} but for {!bigstring}. *) + val digesti_bigstring : bigstring iter -> t + + (** Specialization of {!digesti_bytes} with a list of {!Bytes.t} (see + {!iter}). *) + val digestv_bytes : Bytes.t list -> t + + (** Same as {!digestv_bytes} but for {!String.t}. *) + val digestv_string : String.t list -> t + + (** Same as {!digestv_bytes} but for {!bigstring}. *) + val digestv_bigstring : bigstring list -> t + + (** [unsafe_compare] function returns [0] on equality and a negative/positive + [int] depending on the difference (like {!String.compare}). This is + usually OK, but this is not constant time, so in some cases it could leak + some information. *) + val unsafe_compare : t compare + + (** The equal (constant-time) function for {!t}. *) + val equal : t equal + + (** Pretty-printer of {!t}. *) + val pp : t pp + + (** [of_hex] tries to parse an hexadecimal representation of {!t}. [of_hex] + raises an [invalid_argument] when input is malformed. We take only firsts + {!digest_size} hexadecimal values and ignore rest of input. If it has not + enough hexadecimal values, trailing values of the output hash are zero + ([\x00]), *) + val of_hex : string -> t + + (** [of_hex] tries to parse an hexadecimal representation of {!t}. [of_hex] + returns [None] when input is malformed. We take only first {!digest_size} + hexadecimal values and ignore rest of input. If it has not enough + hexadecimal values, trailing values of the output hash are zero ([\x00]). *) + val of_hex_opt : string -> t option + + (** [consistent_of_hex] tries to parse an hexadecimal representation of {!t}. + [consistent_of_hex] raises an [invalid_argument] when input is malformed. + However, instead {!of_hex}, [consistent_of_hex] expects exactly + [{!digest_size} * 2] hexadecimal values (but continues to ignore + whitespaces). *) + val consistent_of_hex : string -> t + + (** [consistent_of_hex_opt] tries to parse an hexadecimal representation of + {!t}. [consistent_of_hex] returns [None] when input is malformed. However, + instead {!of_hex}, [consistent_of_hex] expects exactly + [{!digest_size} * 2] hexadecimal values (but continues to ignore + whitespaces). *) + val consistent_of_hex_opt : string -> t option + + (** [to_hex] makes a hex-decimal representation of {!t}. *) + val to_hex : t -> string + + (** [of_raw_string s] see [s] as a hash. Useful when reading serialized + hashes. *) + val of_raw_string : string -> t + + (** [of_raw_string_opt s] see [s] as a hash. Useful when reading serialized + hashes. Returns [None] if [s] is not the {!digest_size} bytes long. *) + val of_raw_string_opt : string -> t option + + (** [to_raw_string s] is [(s :> string)]. *) + val to_raw_string : t -> string +end + +module BLAKE2B : sig + include S +end + +module BLAKE2S : sig + include S +end + +module Make_BLAKE2B (D : sig + val digest_size : int +end) : S + +module Make_BLAKE2S (D : sig + val digest_size : int +end) : S + +type 'k hash = BLAKE2B : BLAKE2B.t hash | BLAKE2S : BLAKE2S.t hash + +val blake2b : BLAKE2B.t hash + +val blake2s : BLAKE2S.t hash + +type 'kind t + +val module_of : 'k hash -> (module S with type t = 'k) + +val digest_bytes : 'k hash -> Bytes.t -> 'k t + +val digest_string : 'k hash -> String.t -> 'k t + +val digest_bigstring : 'k hash -> bigstring -> 'k t + +val digesti_bytes : 'k hash -> Bytes.t iter -> 'k t + +val digesti_string : 'k hash -> String.t iter -> 'k t + +val digesti_bigstring : 'k hash -> bigstring iter -> 'k t + +val pp : 'k hash -> 'k t pp + +val equal : 'k hash -> 'k t equal + +val unsafe_compare : 'k hash -> 'k t compare + +val to_hex : 'k hash -> 'k t -> string + +val of_hex : 'k hash -> string -> 'k t + +val of_hex_opt : 'k hash -> string -> 'k t option + +val consistent_of_hex : 'k hash -> string -> 'k t + +val consistent_of_hex_opt : 'k hash -> string -> 'k t option + +val of_raw_string : 'k hash -> string -> 'k t + +val of_raw_string_opt : 'k hash -> string -> 'k t option + +val to_raw_string : 'k hash -> 'k t -> string + +val of_digest : (module S with type t = 'hash) -> 'hash -> 'hash t + +val of_blake2b : BLAKE2B.t -> BLAKE2B.t t + +val of_blake2s : BLAKE2S.t -> BLAKE2S.t t diff --git a/src/lib_mec/neptunus.ml b/src/lib_mec/neptunus.ml new file mode 100644 index 000000000000..cd5a4113c55f --- /dev/null +++ b/src/lib_mec/neptunus.ml @@ -0,0 +1,17 @@ +module Constant : Poseidon_core.PARAMETERS = struct + let width = 3 + + let full_rounds = 60 + + let partial_rounds = 0 + + (* FIXME: MUST BE CHANGED. Not sure it is secure *) + let mds_matrix = Mds_orchard.v + + let round_constants = Ark_neptunus.v + + let partial_round_idx_to_permute = 4 +end + +module Make (Scalar : Bls12_381.Ff_sig.PRIME) = + Poseidon_core.Make (Constant) (Scalar) diff --git a/src/lib_mec/neptunus.mli b/src/lib_mec/neptunus.mli new file mode 100644 index 000000000000..64af432c4b0b --- /dev/null +++ b/src/lib_mec/neptunus.mli @@ -0,0 +1,7 @@ +module Constant : Poseidon_core.PARAMETERS + +module Make (Scalar : Bls12_381.Ff_sig.PRIME) : sig + module Strategy : Poseidon_core.STRATEGY with type scalar = Scalar.t + + module Hash : Poseidon_core.HASH with type scalar = Scalar.t +end diff --git a/src/lib_mec/orchard.ml b/src/lib_mec/orchard.ml new file mode 100644 index 000000000000..091078f77850 --- /dev/null +++ b/src/lib_mec/orchard.ml @@ -0,0 +1,16 @@ +module Constant : Poseidon_core.PARAMETERS = struct + let width = 3 + + let full_rounds = 8 + + let partial_rounds = 58 + + let mds_matrix = Mds_orchard.v + + let round_constants = Ark_orchard.v + + let partial_round_idx_to_permute = 0 +end + +module Make (Scalar : Bls12_381.Ff_sig.PRIME) = + Poseidon_core.Make (Constant) (Scalar) diff --git a/src/lib_mec/orchard.mli b/src/lib_mec/orchard.mli new file mode 100644 index 000000000000..64af432c4b0b --- /dev/null +++ b/src/lib_mec/orchard.mli @@ -0,0 +1,7 @@ +module Constant : Poseidon_core.PARAMETERS + +module Make (Scalar : Bls12_381.Ff_sig.PRIME) : sig + module Strategy : Poseidon_core.STRATEGY with type scalar = Scalar.t + + module Hash : Poseidon_core.HASH with type scalar = Scalar.t +end diff --git a/src/lib_mec/pallas.ml b/src/lib_mec/pallas.ml new file mode 100644 index 000000000000..03d188241de1 --- /dev/null +++ b/src/lib_mec/pallas.ml @@ -0,0 +1,268 @@ +(** + Base field: 2^254 + 45560315531419706090280762371685220353 = 28948022309329048855892746252171976963363056481941560715954676764349967630337 (254 bits - 32 bytes) + Scalar field: 2^254 + 45560315531506369815346746415080538113 = 28948022309329048855892746252171976963363056481941647379679742748393362948097 (254 bits - 32 bytes) + + Base field multiplicative subgroup decomposition: + 2^32 * 3 * 463 * 4852402207910482324454106387152561316357015077916052529702775169 + + Prime field multiplication subgroup decomposition: + 2^32 * 3^2 * 1709 * 24859 * 17627503553531704781201602214972145569028026719617221564519 +*) + +let two_z = Z.succ Z.one + +module Fq = Ff.MakeFp (struct + let prime_order = + Z.((two_z ** 254) + Z.of_string "45560315531419706090280762371685220353") +end) + +module Fp = Ff.MakeFp (struct + let prime_order = + Z.((two_z ** 254) + Z.of_string "45560315531506369815346746415080538113") +end) + +module Projective = + Ec.MakeProjectiveWeierstrass (Fq) (Fp) + (struct + (* https://github.com/zcash/pasta *) + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 5) + + let cofactor = Z.one + + (* x = -1 + y = 2 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.(to_bytes (negate (of_string "1"))); + Fq.(to_bytes (of_string "2")); + Fq.(to_bytes one); + ] + end) + +module Jacobian = + Ec.MakeJacobianWeierstrass (Fq) (Fp) + (struct + (* https://github.com/zcash/pasta *) + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 5) + + let cofactor = Z.one + + (* x = -1 + y = 2 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.(to_bytes (negate (of_string "1"))); + Fq.(to_bytes (of_string "2")); + Fq.(to_bytes one); + ] + end) + +module Affine = + Ec.MakeAffineWeierstrass (Fq) (Fp) + (struct + (* https://github.com/zcash/pasta *) + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 5) + + let cofactor = Z.one + + (* x = -1 + y = 2 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.(to_bytes (negate (of_string "1"))); Fq.(to_bytes (of_string "2")); + ] + end) + +let from_affine_weierstrass_to_jacobian_weierstrass p = + Ec.from_affine_weierstrass_to_jacobian_weierstrass + (module Affine) + (module Jacobian) + p + +let from_affine_weierstrass_to_projective_weierstrass p = + Ec.from_affine_weierstrass_to_projective_weierstrass + (module Affine) + (module Projective) + p + +let from_jacobian_weierstrass_to_affine_weierstrass p = + Ec.from_jacobian_weierstrass_to_affine_weierstrass + (module Jacobian) + (module Affine) + p + +let from_projective_weierstrass_to_affine_weierstrass p = + Ec.from_projective_weierstrass_to_affine_weierstrass + (module Projective) + (module Affine) + p + +module Iso = struct + module Affine = + Ec.MakeAffineWeierstrass (Fq) (Fp) + (struct + let a = + Fq.of_string + "0x18354a2eb0ea8c9c49be2d7258370742b74134581a27a59f92bb4b0b657a014b" + + let b = Fq.of_string "1265" + + let cofactor = Z.one + + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.(to_bytes zero); + Fq.( + to_bytes + (of_string + "10190879275902416739536393627353788808482399662677727499756286083144305497533")); + ] + end) +end + +let csts_iso_map = + [| + Fq.of_string + "0x0e38e38e38e38e38e38e38e38e38e38e4081775473d8375b775f6034aaaaaaab"; + Fq.of_string + "0x3509afd51872d88e267c7ffa51cf412a0f93b82ee4b994958cf863b02814fb76"; + Fq.of_string + "0x17329b9ec525375398c7d7ac3d98fd13380af066cfeb6d690eb64faef37ea4f7"; + Fq.of_string + "0x1c71c71c71c71c71c71c71c71c71c71c8102eea8e7b06eb6eebec06955555580"; + Fq.of_string + "0x1d572e7ddc099cff5a607fcce0494a799c434ac1c96b6980c47f2ab668bcd71f"; + Fq.of_string + "0x325669becaecd5d11d13bf2a7f22b105b4abf9fb9a1fc81c2aa3af1eae5b6604"; + Fq.of_string + "0x1a12f684bda12f684bda12f684bda12f7642b01ad461bad25ad985b5e38e38e4"; + Fq.of_string + "0x1a84d7ea8c396c47133e3ffd28e7a09507c9dc17725cca4ac67c31d8140a7dbb"; + Fq.of_string + "0x3fb98ff0d2ddcadd303216cce1db9ff11765e924f745937802e2be87d225b234"; + Fq.of_string + "0x025ed097b425ed097b425ed097b425ed0ac03e8e134eb3e493e53ab371c71c4f"; + Fq.of_string + "0x0c02c5bcca0e6b7f0790bfb3506defb65941a3a4a97aa1b35a28279b1d1b42ae"; + Fq.of_string + "0x17033d3c60c68173573b3d7f7d681310d976bbfabbc5661d4d90ab820b12320a"; + Fq.of_string + "0x40000000000000000000000000000000224698fc094cf91b992d30ecfffffde5"; + |] + +(* See 5.4.9.8: Group Hash into Pallas and Vesta *) +let iso_map p = + if Iso.Affine.is_zero p then Affine.zero + else + let x = Iso.Affine.get_x_coordinate p in + let y = Iso.Affine.get_y_coordinate p in + let xx = Fq.(x * x) in + let xxx = Fq.(xx * x) in + let x' = + Fq.( + ((csts_iso_map.(0) * xxx) + + (csts_iso_map.(1) * xx) + + (csts_iso_map.(2) * x) + + csts_iso_map.(3)) + / (xx + (csts_iso_map.(4) * x) + csts_iso_map.(5))) + in + let y' = + Fq.( + ((csts_iso_map.(6) * xxx) + + (csts_iso_map.(7) * xx) + + (csts_iso_map.(8) * x) + + csts_iso_map.(9)) + * y + / (xxx + + (csts_iso_map.(10) * xx) + + (csts_iso_map.(11) * x) + + csts_iso_map.(12))) + in + Affine.from_coordinates_exn ~x:x' ~y:y' + +module Blake2b = Mec_digestif.Make_BLAKE2B (struct + let digest_size = 64 +end) + +let hash_blake2s personalisation msg = + Hex.to_bytes + (`Hex Blake2b.(to_hex (get (feed_bytes (init ~personalisation ()) msg)))) + +let xor b0 b1 = + let rec aux acc i i0 i1 = + if i = 8 then + fst + @@ List.fold_left + (fun (acc, exp) bi -> + ((acc + ((1 lsl exp) * if bi then 1 else 0)), exp + 1)) + (0, 0) + (List.rev acc) + else + let r0 = i0 mod 2 = 1 in + let r1 = i1 mod 2 = 0 in + let b = r0 <> r1 in + aux (b :: acc) (i + 1) (i0 / 2) (i1 / 2) + in + let b0 = List.map int_of_char (List.of_seq (Bytes.to_seq b0)) in + let b1 = List.map int_of_char (List.of_seq (Bytes.to_seq b1)) in + let res = List.map2 (fun b0 b1 -> aux [] 0 b0 b1) b0 b1 in + let res = List.map char_of_int res in + Bytes.of_seq (List.to_seq res) + +let hash_to_field msg dst = + assert (Bytes.length dst < 256) ; + let dst' = + Bytes.concat + Bytes.empty + [dst; Bytes.make 1 (char_of_int (Bytes.length dst))] + in + let msg' = + Bytes.concat + Bytes.empty + [ + Bytes.make 128 (char_of_int 0); + msg; + Bytes.make 1 (char_of_int 0); + Bytes.make 1 (char_of_int 128); + Bytes.make 1 (char_of_int 0); + dst'; + ] + in + let b0 = hash_blake2s (Bytes.make 16 (char_of_int 0)) msg' in + let b1 = + hash_blake2s + (Bytes.make 16 (char_of_int 0)) + (Bytes.concat Bytes.empty [b0; Bytes.make 1 (char_of_int 1); dst']) + in + let b0_xor_b1 = xor b0 b1 in + let b2 = + hash_blake2s + (Bytes.make 16 (char_of_int 0)) + (Bytes.concat Bytes.empty [b0_xor_b1; Bytes.make 1 (char_of_int 2); dst']) + in + let b1_le = + Bytes.(to_string (init 64 (fun i -> Bytes.get b1 (64 - i - 1)))) + in + let b2_le = + Bytes.(to_string (init 64 (fun i -> Bytes.get b2 (64 - i - 1)))) + in + (Fq.of_z (Z.of_bits b1_le), Fq.of_z (Z.of_bits b2_le)) + +(* let z_iso = Iso.Affine.Base.of_z (Z.(neg (of_int 13))) *) diff --git a/src/lib_mec/pallas.mli b/src/lib_mec/pallas.mli new file mode 100644 index 000000000000..2b649fb3ef5d --- /dev/null +++ b/src/lib_mec/pallas.mli @@ -0,0 +1,21 @@ +module Projective : Ec_sig.ProjectiveWeierstrassT + +module Affine : Ec_sig.AffineWeierstrassT + +module Jacobian : Ec_sig.JacobianWeierstrassT + +val from_affine_weierstrass_to_jacobian_weierstrass : Affine.t -> Jacobian.t + +val from_affine_weierstrass_to_projective_weierstrass : Affine.t -> Projective.t + +val from_jacobian_weierstrass_to_affine_weierstrass : Jacobian.t -> Affine.t + +val from_projective_weierstrass_to_affine_weierstrass : Projective.t -> Affine.t + +module Iso : sig + module Affine : Ec_sig.AffineWeierstrassT +end + +val iso_map : Iso.Affine.t -> Affine.t + +val hash_to_field : Bytes.t -> Bytes.t -> Affine.Base.t * Affine.Base.t diff --git a/src/lib_mec/pedersen_hash.ml b/src/lib_mec/pedersen_hash.ml new file mode 100644 index 000000000000..f483ac40d2d2 --- /dev/null +++ b/src/lib_mec/pedersen_hash.ml @@ -0,0 +1,81 @@ +module MakePedersenHash + (Ec : Ec_sig.BASE) (Params : sig + val generators : Ec.t list + + val chunks_per_generator : int + end) = +struct + let hash iterator = + let rec compute_m_j acc j = + if j = Params.chunks_per_generator + 1 then (acc, false) + else + let a_opt = Iterator.Bit.next iterator in + (* end of the bit stream, we do not continue, the boolean means we + processed the entire bitstring + *) + if Option.is_none a_opt then (acc, true) + else + let a = Option.value a_opt ~default:0 in + let b = Option.value (Iterator.Bit.next iterator) ~default:0 in + let c = Option.value (Iterator.Bit.next iterator) ~default:0 in + let enc_m_j = (1 - (2 * c)) * (1 + a + (2 * b)) in + (* accumulated *) + let enc_m_j = Ec.Scalar.of_z (Z.of_int enc_m_j) in + let power = + Ec.Scalar.pow Ec.Scalar.(one + one) (Z.of_int (4 * (j - 1))) + in + let acc = Ec.Scalar.add acc (Ec.Scalar.mul enc_m_j power) in + compute_m_j acc (j + 1) + in + let rec compute_segment_i_incremental acc_res generators = + match generators with + | [] -> raise (Invalid_argument "Not enough generators") + | generator :: generators -> + let sum_m_j, fully_processed = compute_m_j Ec.Scalar.zero 1 in + (* compute segment i *) + let m_i = Ec.(mul generator sum_m_j) in + let acc_res = Ec.(add m_i acc_res) in + if fully_processed then acc_res + else compute_segment_i_incremental acc_res generators + in + compute_segment_i_incremental Ec.zero Params.generators +end + +module Zcash = + MakePedersenHash + (Jubjub.AffineEdwards) + (struct + (* generators from + https://github.com/zcash/librustzcash/blob/de1345a1c2f10b0843ab1f1ea6463b2330fdc673/zcash_primitives/src/constants.rs#L146 *) + let generators = + let tmp = + [ + ( "0x73c016a42ded9578b5ea25de7ec0e3782f0c718f6f0fbadd194e42926f661b51", + "0x289e87a2d3521b5779c9166b837edc5ef9472e8bc04e463277bfabd432243cca" + ); + ( "0x15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e", + "0x015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891" + ); + ( "0x664321a58246e2f6eb69ae39f5c84210bae8e5c46641ae5c76d6f7c2b67fc475", + "0x362e1500d24eee9ee000a46c8e8ce8538bb22a7f1784b49880ed502c9793d457" + ); + ( "0x323a6548ce9d9876edc5f4a9cff29fd57d02d50e654b87f24c767804c1c4a2cc", + "0x2f7ee40c4b56cad891070acbd8d947b75103afa1a11f6a8584714beca33570e9" + ); + ( "0x3bd2666000b5479689b64b4e03362796efd5931305f2f0bf46809430657f82d1", + "0x494bc52103ab9d0a397832381406c9e5b3b9d8095859d14c99968299c3658aef" + ); + ( "0x63447b2ba31bb28ada049746d76d3ee51d9e5ca21135ff6fcb3c023258d32079", + "0x64ec4689e8bfb6e564cdb1070a136a28a80200d2c66b13a7436082119f8d629a" + ); + ] + in + List.map + (fun (u, v) -> + Jubjub.AffineEdwards.from_coordinates_exn + ~u:(Jubjub.AffineEdwards.Base.of_string u) + ~v:(Jubjub.AffineEdwards.Base.of_string v)) + tmp + + let chunks_per_generator = 63 + end) diff --git a/src/lib_mec/pedersen_hash.mli b/src/lib_mec/pedersen_hash.mli new file mode 100644 index 000000000000..913b727789b0 --- /dev/null +++ b/src/lib_mec/pedersen_hash.mli @@ -0,0 +1,14 @@ +module MakePedersenHash : functor + (Ec : Ec_sig.BASE) + (Params : sig + val generators : Ec.t list + + val chunks_per_generator : int + end) + -> sig + val hash : Iterator.Bit.t -> Ec.t +end + +module Zcash : sig + val hash : Iterator.Bit.t -> Jubjub.AffineEdwards.t +end diff --git a/src/lib_mec/poseidon128.ml b/src/lib_mec/poseidon128.ml new file mode 100644 index 000000000000..19ea88089232 --- /dev/null +++ b/src/lib_mec/poseidon128.ml @@ -0,0 +1,16 @@ +module Constant : Poseidon_core.PARAMETERS = struct + let width = 3 + + let full_rounds = 8 + + let partial_rounds = 56 + + let mds_matrix = Mds_poseidon128.v + + let round_constants = Ark_poseidon128.v + + let partial_round_idx_to_permute = 2 +end + +module Make (Scalar : Bls12_381.Ff_sig.PRIME) = + Poseidon_core.Make (Constant) (Scalar) diff --git a/src/lib_mec/poseidon128.mli b/src/lib_mec/poseidon128.mli new file mode 100644 index 000000000000..64af432c4b0b --- /dev/null +++ b/src/lib_mec/poseidon128.mli @@ -0,0 +1,7 @@ +module Constant : Poseidon_core.PARAMETERS + +module Make (Scalar : Bls12_381.Ff_sig.PRIME) : sig + module Strategy : Poseidon_core.STRATEGY with type scalar = Scalar.t + + module Hash : Poseidon_core.HASH with type scalar = Scalar.t +end diff --git a/src/lib_mec/poseidon252.ml b/src/lib_mec/poseidon252.ml new file mode 100644 index 000000000000..6b6e047ced0f --- /dev/null +++ b/src/lib_mec/poseidon252.ml @@ -0,0 +1,16 @@ +module Constant : Poseidon_core.PARAMETERS = struct + let width = 5 + + let full_rounds = 8 + + let partial_rounds = 59 + + let mds_matrix = Mds_poseidon252.v + + let round_constants = Ark_poseidon252.v + + let partial_round_idx_to_permute = 4 +end + +module Make (Scalar : Bls12_381.Ff_sig.PRIME) = + Poseidon_core.Make (Constant) (Scalar) diff --git a/src/lib_mec/poseidon252.mli b/src/lib_mec/poseidon252.mli new file mode 100644 index 000000000000..64af432c4b0b --- /dev/null +++ b/src/lib_mec/poseidon252.mli @@ -0,0 +1,7 @@ +module Constant : Poseidon_core.PARAMETERS + +module Make (Scalar : Bls12_381.Ff_sig.PRIME) : sig + module Strategy : Poseidon_core.STRATEGY with type scalar = Scalar.t + + module Hash : Poseidon_core.HASH with type scalar = Scalar.t +end diff --git a/src/lib_mec/poseidon_core.ml b/src/lib_mec/poseidon_core.ml new file mode 100644 index 000000000000..c1741cd3d635 --- /dev/null +++ b/src/lib_mec/poseidon_core.ml @@ -0,0 +1,183 @@ +module type PARAMETERS = sig + val width : int + + val full_rounds : int + + val partial_rounds : int + + val round_constants : string array + + val mds_matrix : string array array + + val partial_round_idx_to_permute : int +end + +module type STRATEGY = sig + type scalar + + type state + + val init : ?input_length:int -> scalar array -> state + + val apply_perm : state -> unit + + val get : state -> scalar array + + val input_length : state -> int option +end + +module type HASH = sig + type scalar + + type ctxt + + val init : ?input_length:int -> unit -> ctxt + + val digest : ctxt -> scalar array -> ctxt + + val get : ctxt -> scalar +end + +module Make (C : PARAMETERS) (Scalar : Bls12_381.Ff_sig.PRIME) = struct + open C + + (* Verify the constants are consistent *) + let () = + assert (Array.length mds_matrix = width) ; + assert (Array.for_all (fun line -> Array.length line = width) mds_matrix) + + let mds_matrix = Array.map (Array.map Scalar.of_string) mds_matrix + + let round_constants = Array.map Scalar.of_string round_constants + + (* Initialize only once an array for the MDS matrix multiplication *) + let res = Array.make width Scalar.zero + + module Strategy = struct + type scalar = Scalar.t + + type state = { + mutable i_round_key : int; + state : Scalar.t array; + input_length : int option; + } + + let init ?input_length state = + {i_round_key = 0; state = Array.copy state; input_length} + + let get_next_round_key s = + let v = round_constants.(s.i_round_key) in + s.i_round_key <- s.i_round_key + 1 ; + v + + let s_box x = Scalar.(square (square x) * x) + + (* Functions prefixed with apply_ are modifying the state given in + parameters + *) + let apply_round_key s = + let state = s.state in + for i = 0 to Array.length state - 1 do + state.(i) <- Scalar.(get_next_round_key s + state.(i)) + done + + let apply_s_box_last_elem s = + let s = s.state in + s.(partial_round_idx_to_permute) <- s_box s.(partial_round_idx_to_permute) + + let apply_s_box s = + let s = s.state in + for i = 0 to Array.length s - 1 do + s.(i) <- s_box s.(i) + done + + let apply_eval_matrix m v = + let v = v.state in + for j = 0 to width - 1 do + for k = 0 to width - 1 do + res.(k) <- Scalar.(res.(k) + (m.(k).(j) * v.(j))) + done + done ; + for j = 0 to width - 1 do + v.(j) <- res.(j) ; + res.(j) <- Scalar.zero + done + + let apply_partial_round s = + apply_round_key s ; + apply_s_box_last_elem s ; + apply_eval_matrix mds_matrix s + + let apply_full_round s = + apply_round_key s ; + apply_s_box s ; + apply_eval_matrix mds_matrix s + + let apply_perm s = + s.i_round_key <- 0 ; + for _i = 0 to (full_rounds / 2) - 1 do + apply_full_round s + done ; + for _i = 0 to partial_rounds - 1 do + apply_partial_round s + done ; + for _i = 0 to (full_rounds / 2) - 1 do + apply_full_round s + done + + let get s = Array.copy s.state + + let add_cst s idx v = + assert (idx <= width) ; + s.state.(idx) <- Scalar.(s.state.(idx) + v) + + let input_length s = s.input_length + end + + module Hash = struct + type scalar = Scalar.t + + type ctxt = Strategy.state + + let init ?input_length () = + let state = Array.make width Scalar.zero in + match input_length with + | None -> Strategy.init state + | Some input_length -> Strategy.init ~input_length state + + let digest state data = + let l = Array.length data in + let assert_length expected = + let error_msg = + Format.sprintf "digest expects data of length %d, %d given" expected l + in + if l <> expected then raise @@ Invalid_argument error_msg + in + let input_length_opt = Strategy.input_length state in + Option.iter assert_length input_length_opt ; + let with_padding = Option.is_none input_length_opt in + + let chunk_size = width - 1 in + let nb_full_chunk = (l - if with_padding then 0 else 1) / chunk_size in + let r = l mod chunk_size in + (* we process first all the full chunks *) + for i = 0 to nb_full_chunk - 1 do + let ofs = i * chunk_size in + for j = 0 to chunk_size - 1 do + Strategy.add_cst state (1 + j) data.(ofs + j) + done ; + Strategy.apply_perm state + done ; + (* we add the last partial chunk, add pad with one *) + let r = if with_padding then r else l - (nb_full_chunk * (width - 1)) in + for j = 0 to r - 1 do + let idx = 1 + j in + Strategy.add_cst state idx data.((nb_full_chunk * chunk_size) + j) + done ; + if with_padding then Strategy.add_cst state (r + 1) Scalar.one ; + Strategy.apply_perm state ; + state + + let get (ctxt : ctxt) = ctxt.state.(1) + end +end diff --git a/src/lib_mec/poseidon_core.mli b/src/lib_mec/poseidon_core.mli new file mode 100644 index 000000000000..7eaf5bfdf909 --- /dev/null +++ b/src/lib_mec/poseidon_core.mli @@ -0,0 +1,60 @@ +module type PARAMETERS = sig + (** The state size *) + val width : int + + (** The total number of full rounds *) + val full_rounds : int + + (** The number of partial rounds *) + val partial_rounds : int + + (** The round constants, given in decimal representation *) + val round_constants : string array + + (** The MDS matrix, given in decimal representation *) + val mds_matrix : string array array + + (** The index of the element of the state to permute during the partial rounds *) + val partial_round_idx_to_permute : int +end + +(** A HADES strategy, for a constant length construction *) +module type STRATEGY = sig + type scalar + + (** The state of the strategy *) + type state + + (** Initialize the state with the given input *) + val init : ?input_length:int -> scalar array -> state + + (** Apply a permutation round *) + val apply_perm : state -> unit + + (** Return the current scalar elements in the state *) + val get : state -> scalar array + + (** Return the expected input length if specified *) + val input_length : state -> int option +end + +module type HASH = sig + type scalar + + type ctxt + + (** Initialize a raw hash context *) + val init : ?input_length:int -> unit -> ctxt + + (** [digest ctxt input] computes the hash of the given input *) + val digest : ctxt -> scalar array -> ctxt + + (** [get ctxt] returns the resulting point after [hash] has been called *) + val get : ctxt -> scalar +end + +module Make (C : PARAMETERS) (Scalar : Bls12_381.Ff_sig.PRIME) : sig + module Strategy : STRATEGY with type scalar = Scalar.t + + module Hash : HASH with type scalar = Scalar.t +end diff --git a/src/lib_mec/reddsa.ml b/src/lib_mec/reddsa.ml new file mode 100644 index 000000000000..3c016bfc39a9 --- /dev/null +++ b/src/lib_mec/reddsa.ml @@ -0,0 +1,130 @@ +(*****************************************************************************) +(* *) +(* Copyright (c) 2021 Danny Willems *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module type SIGNATURE_SCHEME = sig + type secret_key + + type public_key + + type signature + + val signature_to_bytes : signature -> Bytes.t + + val sign : secret_key -> Bytes.t -> signature + + val sign_deterministic : Bytes.t -> secret_key -> Bytes.t -> signature + + val verify : public_key -> Bytes.t -> signature -> bool +end + +module MakeRedDSA + (Ec : Ec_sig.AffineEdwardsT) (Param : sig + val length : int + + val hash : Bytes.t -> Bytes.t + + val generator : Ec.t + + val to_compressed : Ec.t -> Bytes.t + + val of_compressed_opt : Bytes.t -> Ec.t option + end) = +struct + let () = + if Param.length mod 8 <> 0 then failwith "Length must be a multiple of 8" + + let hash_star bytes = + let limbs = Param.hash bytes in + Ec.Scalar.of_bytes_exn limbs + + type secret_key = Ec.Scalar.t + + type public_key = Ec.t + + type signature = {r : Bytes.t; s : Bytes.t} + + let signature_to_bytes signature = + Bytes.concat Bytes.empty [signature.r; signature.s] + + let sign_deterministic randomness sk message = + (* length is given in bits *) + let length = (Param.length + 128) / 8 in + assert (Bytes.length randomness = length) ; + (* IMPORTANT!!! + r = H*(T || vk || M) --> This is the spec in the Sapling PDF. However, + the reference implementation do not use the vk: + - https://github.com/zcash/librustzcash/blob/da431a0eb207f69c9b0631d7d02136d819e1bfd9/zcash_primitives/src/sapling/redjubjub.rs#L80 + - https://github.com/zcash/librustzcash/blob/da431a0eb207f69c9b0631d7d02136d819e1bfd9/zcash_primitives/src/sapling/util.rs#L9 + - https://github.com/zcash/librustzcash/issues/179 + *) + let r = hash_star (Bytes.concat Bytes.empty [randomness; message]) in + (* R = r . P *) + let p_r = Ec.mul Param.generator r in + (* Get the little endian encoding of the point R *) + let p_r_le = Param.to_compressed p_r in + (* s = r + sk . H*(LE(P) || M) *) + let s = hash_star (Bytes.concat Bytes.empty [p_r_le; message]) in + let s = Ec.Scalar.(sk * s) in + let s = Ec.Scalar.(r + s) in + (* R || S *) + {r = p_r_le; s = Ec.Scalar.to_bytes s} + + let sign sk message = + (* Generate T, length + 128 bits *) + let t = + Bytes.init + ((Param.length + 128) / 8) + (fun _ -> char_of_int (Random.int 256)) + in + sign_deterministic t sk message + + let verify vk message signature = + (* we do not have to check the first condition as it is an invariant of the + type signature + *) + let r = Param.of_compressed_opt signature.r in + let s = Z.of_bits (Bytes.to_string signature.s) in + (* The Sapling PDF does use vk in the hash, but not the reference + implementation of zcash. Therefore, ignoring it + - https://github.com/zcash/librustzcash/blob/da431a0eb207f69c9b0631d7d02136d819e1bfd9/zcash_primitives/src/sapling/redjubjub.rs#L80 + - https://github.com/zcash/librustzcash/blob/da431a0eb207f69c9b0631d7d02136d819e1bfd9/zcash_primitives/src/sapling/util.rs#L9 + - https://github.com/zcash/librustzcash/issues/179 + *) + let c = hash_star (Bytes.concat Bytes.empty [signature.r; message]) in + (* FIXME: not constant time!! Like everything... *) + match r with + | None -> false + | Some r -> + let s_leq_r = Z.(leq s Ec.Scalar.order) in + (* [c] * vk *) + let c_vk = Ec.(mul vk c) in + (* [S] * P_G *) + let s_p_g = Ec.(mul Param.generator (Scalar.of_z s)) in + (* -[S] * P_G + R + [c] vk *) + let res = Ec.(add (add (negate s_p_g) r) c_vk) in + (* multiply by the cofactor -> [h_G] res *) + let res = Ec.(mul res (Scalar.of_z cofactor)) in + let res_is_null = Ec.is_zero res in + s_leq_r && res_is_null +end diff --git a/src/lib_mec/reddsa.mli b/src/lib_mec/reddsa.mli new file mode 100644 index 000000000000..389358b93a4e --- /dev/null +++ b/src/lib_mec/reddsa.mli @@ -0,0 +1,53 @@ +(*****************************************************************************) +(* *) +(* Copyright (c) 2021 Danny Willems *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module type SIGNATURE_SCHEME = sig + type secret_key + + type public_key + + type signature + + val signature_to_bytes : signature -> Bytes.t + + val sign : secret_key -> Bytes.t -> signature + + val sign_deterministic : Bytes.t -> secret_key -> Bytes.t -> signature + + val verify : public_key -> Bytes.t -> signature -> bool +end + +module MakeRedDSA + (Ec : Ec_sig.AffineEdwardsT) (Param : sig + val length : int + + val hash : Bytes.t -> Bytes.t + + val generator : Ec.t + + val to_compressed : Ec.t -> Bytes.t + + val of_compressed_opt : Bytes.t -> Ec.t option + end) : + SIGNATURE_SCHEME with type secret_key = Ec.Scalar.t and type public_key = Ec.t diff --git a/src/lib_mec/redjubjub.ml b/src/lib_mec/redjubjub.ml new file mode 100644 index 000000000000..98e89e43db11 --- /dev/null +++ b/src/lib_mec/redjubjub.ml @@ -0,0 +1,52 @@ +(*****************************************************************************) +(* *) +(* Copyright (c) 2021 Danny Willems *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Make (Param : sig + val generator : Jubjub.AffineEdwards.t +end) = + Reddsa.MakeRedDSA + (Jubjub.AffineEdwards) + (struct + let length = 512 + + let generator = Param.generator + + module Blake2b = Mec_digestif.Make_BLAKE2B (struct + let digest_size = 64 + end) + + let hash m = + let ctx = + Blake2b.init ~personalisation:(Bytes.of_string "Zcash_RedJubjubH") () + in + let ctx = Blake2b.feed_bytes ctx m in + let res_hexa = Blake2b.to_hex (Blake2b.get ctx) in + let res_hexa_hex = `Hex res_hexa in + let res_bytes = Hex.to_bytes res_hexa_hex in + res_bytes + + let to_compressed = Jubjub.AffineEdwards.to_compressed + + let of_compressed_opt = Jubjub.AffineEdwards.of_compressed_opt + end) diff --git a/src/lib_mec/redjubjub.mli b/src/lib_mec/redjubjub.mli new file mode 100644 index 000000000000..26596d4ab58d --- /dev/null +++ b/src/lib_mec/redjubjub.mli @@ -0,0 +1,30 @@ +(*****************************************************************************) +(* *) +(* Copyright (c) 2021 Danny Willems *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Make (Param : sig + val generator : Jubjub.AffineEdwards.t +end) : + Reddsa.SIGNATURE_SCHEME + with type secret_key = Jubjub.AffineEdwards.Scalar.t + and type public_key = Jubjub.AffineEdwards.t diff --git a/src/lib_mec/secp256k1.ml b/src/lib_mec/secp256k1.ml new file mode 100644 index 000000000000..5427bb4bcc7d --- /dev/null +++ b/src/lib_mec/secp256k1.ml @@ -0,0 +1,135 @@ +(** + Base field: 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1 = 115792089237316195423570985008687907853269984665640564039457584007908834671663 (255 bits - 32 bytes) + Scalar field: 115792089237316195423570985008687907852837564279074904382605163141518161494337 (255 bits - 32 bytes) + + Base field multiplicative subgroup decomposition: + 2 * 3 * 7 * 13441 * 205115282021455665897114700593932402728804164701536103180137503955397371 + + Prime field multiplication subgroup decomposition: + 2^6 * 3 * 149 * 631 * 6414488540731361226607730496888035255996436684289152125202372832747357 +*) + +let two_z = Z.succ Z.one + +module Fq = Ff.MakeFp (struct + let prime_order = + Z.( + (two_z ** 256) - (two_z ** 32) - (two_z ** 9) - (two_z ** 8) + - (two_z ** 7) - (two_z ** 6) - (two_z ** 4) - one) +end) + +module Fp = Ff.MakeFp (struct + let prime_order = + Z.of_string + "115792089237316195423570985008687907852837564279074904382605163141518161494337" +end) + +module Projective = + Ec.MakeProjectiveWeierstrass (Fq) (Fp) + (struct + (* See https://en.bitcoin.it/wiki/Secp256k1 *) + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 7) + + let cofactor = Z.one + + (* x = 55066263022277343669578718895168534326250603453777594175500187360389116729240 + y = 32670510020758816978083085130507043184471273380659243275938904335757337482424 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.( + to_bytes + (of_string + "55066263022277343669578718895168534326250603453777594175500187360389116729240")); + Fq.( + to_bytes + (of_string + "32670510020758816978083085130507043184471273380659243275938904335757337482424")); + Fq.(to_bytes one); + ] + end) + +module Jacobian = + Ec.MakeJacobianWeierstrass (Fq) (Fp) + (struct + (* See https://en.bitcoin.it/wiki/Secp256k1 *) + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 7) + + let cofactor = Z.one + + (* x = 55066263022277343669578718895168534326250603453777594175500187360389116729240 + y = 32670510020758816978083085130507043184471273380659243275938904335757337482424 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.( + to_bytes + (of_string + "55066263022277343669578718895168534326250603453777594175500187360389116729240")); + Fq.( + to_bytes + (of_string + "32670510020758816978083085130507043184471273380659243275938904335757337482424")); + Fq.(to_bytes one); + ] + end) + +module Affine = + Ec.MakeAffineWeierstrass (Fq) (Fp) + (struct + (* See https://en.bitcoin.it/wiki/Secp256k1 *) + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 7) + + let cofactor = Z.one + + (* x = 55066263022277343669578718895168534326250603453777594175500187360389116729240 + y = 32670510020758816978083085130507043184471273380659243275938904335757337482424 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.( + to_bytes + (of_string + "55066263022277343669578718895168534326250603453777594175500187360389116729240")); + Fq.( + to_bytes + (of_string + "32670510020758816978083085130507043184471273380659243275938904335757337482424")); + ] + end) + +let from_affine_weierstrass_to_jacobian_weierstrass p = + Ec.from_affine_weierstrass_to_jacobian_weierstrass + (module Affine) + (module Jacobian) + p + +let from_affine_weierstrass_to_projective_weierstrass p = + Ec.from_affine_weierstrass_to_projective_weierstrass + (module Affine) + (module Projective) + p + +let from_jacobian_weierstrass_to_affine_weierstrass p = + Ec.from_jacobian_weierstrass_to_affine_weierstrass + (module Jacobian) + (module Affine) + p + +let from_projective_weierstrass_to_affine_weierstrass p = + Ec.from_projective_weierstrass_to_affine_weierstrass + (module Projective) + (module Affine) + p diff --git a/src/lib_mec/secp256k1.mli b/src/lib_mec/secp256k1.mli new file mode 100644 index 000000000000..0d06a0937537 --- /dev/null +++ b/src/lib_mec/secp256k1.mli @@ -0,0 +1,13 @@ +module Projective : Ec_sig.ProjectiveWeierstrassT + +module Affine : Ec_sig.AffineWeierstrassT + +module Jacobian : Ec_sig.JacobianWeierstrassT + +val from_affine_weierstrass_to_jacobian_weierstrass : Affine.t -> Jacobian.t + +val from_affine_weierstrass_to_projective_weierstrass : Affine.t -> Projective.t + +val from_jacobian_weierstrass_to_affine_weierstrass : Jacobian.t -> Affine.t + +val from_projective_weierstrass_to_affine_weierstrass : Projective.t -> Affine.t diff --git a/src/lib_mec/secp256r1.ml b/src/lib_mec/secp256r1.ml new file mode 100644 index 000000000000..35ed2ababd61 --- /dev/null +++ b/src/lib_mec/secp256r1.ml @@ -0,0 +1,143 @@ +(** + https://www.secg.org/SEC2-Ver-1.0.pdf, page 16 + + Base field: 115792089210356248762697446949407573530086143415290314195533631308867097853951 (255 bits - 32 bytes) + Scalar field: 115792089210356248762697446949407573529996955224135760342422259061068512044369 (255 bits - 32 bytes) + + Base field multiplicative subgroup decomposition: + 2 * 3 * 5^2 * 17 * 257 * 641 * 1531 * 65537 * 490463 * 6700417 * 835945042244614951780389953367877943453916927241 + + Prime field multiplication subgroup decomposition: + 2^4 * 3 * 71 * 131 * 373 * 3407 * 17449 * 38189 * 306279700557793653483863914058668676200382493196645316621 +*) + +module Fq = Ff.MakeFp (struct + let prime_order = + Z.of_string + "115792089210356248762697446949407573530086143415290314195533631308867097853951" +end) + +module Fp = Ff.MakeFp (struct + let prime_order = + Z.of_string + "115792089210356248762697446949407573529996955224135760342422259061068512044369" +end) + +module Jacobian = + Ec.MakeJacobianWeierstrass (Fq) (Fp) + (struct + let a = + Fq.of_string + "115792089210356248762697446949407573530086143415290314195533631308867097853948" + + let b = + Fq.of_string + "41058363725152142129326129780047268409114441015993725554835256314039467401291" + + let cofactor = Z.one + + (* x = 511607918243171233453336525287549545615842888188604004153674416748734923195030 + y = 730886786380646968340011037971715329076231014666828399308622702301047192244725 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.( + to_bytes + (of_string + "48439561293906451759052585252797914202762949526041747995844080717082404635286")); + Fq.( + to_bytes + (of_string + "36134250956749795798585127919587881956611106672985015071877198253568414405109")); + Fq.(to_bytes one); + ] + end) + +module Projective = + Ec.MakeProjectiveWeierstrass (Fq) (Fp) + (struct + let a = + Fq.of_string + "115792089210356248762697446949407573530086143415290314195533631308867097853948" + + let b = + Fq.of_string + "41058363725152142129326129780047268409114441015993725554835256314039467401291" + + let cofactor = Z.one + + (* x = 511607918243171233453336525287549545615842888188604004153674416748734923195030 + y = 730886786380646968340011037971715329076231014666828399308622702301047192244725 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.( + to_bytes + (of_string + "48439561293906451759052585252797914202762949526041747995844080717082404635286")); + Fq.( + to_bytes + (of_string + "36134250956749795798585127919587881956611106672985015071877198253568414405109")); + Fq.(to_bytes one); + ] + end) + +module Affine = + Ec.MakeAffineWeierstrass (Fq) (Fp) + (struct + let a = + Fq.of_string + "115792089210356248762697446949407573530086143415290314195533631308867097853948" + + let b = + Fq.of_string + "41058363725152142129326129780047268409114441015993725554835256314039467401291" + + let cofactor = Z.one + + (* x = 511607918243171233453336525287549545615842888188604004153674416748734923195030 + y = 730886786380646968340011037971715329076231014666828399308622702301047192244725 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.( + to_bytes + (of_string + "48439561293906451759052585252797914202762949526041747995844080717082404635286")); + Fq.( + to_bytes + (of_string + "36134250956749795798585127919587881956611106672985015071877198253568414405109")); + ] + end) + +let from_affine_weierstrass_to_jacobian_weierstrass p = + Ec.from_affine_weierstrass_to_jacobian_weierstrass + (module Affine) + (module Jacobian) + p + +let from_affine_weierstrass_to_projective_weierstrass p = + Ec.from_affine_weierstrass_to_projective_weierstrass + (module Affine) + (module Projective) + p + +let from_jacobian_weierstrass_to_affine_weierstrass p = + Ec.from_jacobian_weierstrass_to_affine_weierstrass + (module Jacobian) + (module Affine) + p + +let from_projective_weierstrass_to_affine_weierstrass p = + Ec.from_projective_weierstrass_to_affine_weierstrass + (module Projective) + (module Affine) + p diff --git a/src/lib_mec/secp256r1.mli b/src/lib_mec/secp256r1.mli new file mode 100644 index 000000000000..fe7ce54a92ff --- /dev/null +++ b/src/lib_mec/secp256r1.mli @@ -0,0 +1,13 @@ +module Projective : Ec_sig.ProjectiveWeierstrassT + +module Jacobian : Ec_sig.JacobianWeierstrassT + +module Affine : Ec_sig.AffineWeierstrassT + +val from_affine_weierstrass_to_jacobian_weierstrass : Affine.t -> Jacobian.t + +val from_affine_weierstrass_to_projective_weierstrass : Affine.t -> Projective.t + +val from_jacobian_weierstrass_to_affine_weierstrass : Jacobian.t -> Affine.t + +val from_projective_weierstrass_to_affine_weierstrass : Projective.t -> Affine.t diff --git a/src/lib_mec/sinsemilla.ml b/src/lib_mec/sinsemilla.ml new file mode 100644 index 000000000000..7a734c2dd2df --- /dev/null +++ b/src/lib_mec/sinsemilla.ml @@ -0,0 +1,63 @@ +open Pallas + +exception Bottom + +(* incomplete addition for Pallas *) +let ( ++ ) p1 p2 = + if Affine.is_zero p1 then raise Bottom + else if Affine.is_zero p2 then raise Bottom + else + let x1 = Affine.get_x_coordinate p1 in + let x2 = Affine.get_x_coordinate p2 in + if Affine.Base.eq x1 x2 then raise Bottom else Affine.add p1 p2 + +module MakeSinsemilla (Params : sig + val iv : Affine.t + + val generators : Affine.t array + + val chunk_size : int +end) = +struct + let hash_exn iterator = + let rec aux acc = + if Iterator.Bit.is_processed iterator then acc + else + let m_j_bits = Iterator.Bit.get_chunk iterator Params.chunk_size in + let m_j, _ = + List.fold_left + (fun (acc, i) b -> (acc + ((1 lsl i) * b), i + 1)) + (0, 0) + m_j_bits + in + let gen_j = Params.generators.(m_j) in + aux (acc ++ (acc ++ gen_j)) + in + let v = aux Params.iv in + Affine.get_x_coordinate v + + let hash_opt iterator = + try Some (hash_exn iterator) with Bottom -> None | e -> raise e +end + +module Zcash = struct + let hash_exn iv iterator = + let module Sinsemilla = MakeSinsemilla (struct + let iv = iv + + let generators = Sinsemilla_zcash_generators.generators_zcash + + let chunk_size = 10 + end) in + Sinsemilla.hash_exn iterator + + let hash_opt iv iterator = + let module Sinsemilla = MakeSinsemilla (struct + let iv = iv + + let generators = Sinsemilla_zcash_generators.generators_zcash + + let chunk_size = 10 + end) in + Sinsemilla.hash_opt iterator +end diff --git a/src/lib_mec/sinsemilla.mli b/src/lib_mec/sinsemilla.mli new file mode 100644 index 000000000000..5f3e8b509e74 --- /dev/null +++ b/src/lib_mec/sinsemilla.mli @@ -0,0 +1,30 @@ +open Pallas + +exception Bottom + +module MakeSinsemilla : functor + (Params : sig + val iv : Affine.t + + val generators : Affine.t array + + val chunk_size : int + end) + -> sig + (** Can raise [Bottom] *) + val hash_exn : Iterator.Bit.t -> Affine.Base.t + + val hash_opt : Iterator.Bit.t -> Affine.Base.t option +end + +module Zcash : sig + (** [hash_exn initial_value iterator] is the instantiation of Sinsemilla with + the Zcash generators and a chunk size of 10 + *) + val hash_exn : Affine.t -> Iterator.Bit.t -> Affine.Base.t + + (** [hash_opt initial_value iterator] is the instantiation of Sinsemilla with + the Zcash generators and a chunk size of 10 + *) + val hash_opt : Affine.t -> Iterator.Bit.t -> Affine.Base.t option +end diff --git a/src/lib_mec/sinsemilla_zcash_generators.ml b/src/lib_mec/sinsemilla_zcash_generators.ml new file mode 100644 index 000000000000..cb100bdbd8dd --- /dev/null +++ b/src/lib_mec/sinsemilla_zcash_generators.ml @@ -0,0 +1,6155 @@ +open Pallas + +let generators_zcash_coordinates = + [| + ( Hex.to_bytes + (`Hex + "5fea442091eb915ab562debeaf5ba0297bfc4a7dead431140f1f88e68b21b50d"), + Hex.to_bytes + (`Hex + "83648ebf764fc21701ba652e1c044a94d0d593842966af9c1ca052f1c2400f2f") ); + ( Hex.to_bytes + (`Hex + "91af08a13ee34ace8f9b6424ca0077e604541739eb33fdc81895e1b3b4121121"), + Hex.to_bytes + (`Hex + "eec510f893c2831dbc190e674a743cb4fe355acd793e8aa33bb0ad933999c506") ); + ( Hex.to_bytes + (`Hex + "246d8fa175c4e022c011544b33b30cf4339b5b35e2a46146a325f949cd2cb325"), + Hex.to_bytes + (`Hex + "5797fdb88d6b7da6d2cc45f9b9ebe14b1147b423f3d0537d2c69d070baf20f14") ); + ( Hex.to_bytes + (`Hex + "bcda19040feffaa526188b9312ca39651f702cd05c46ff60c93218e1485a2114"), + Hex.to_bytes + (`Hex + "dc36ca25365d1d0156ade2534b3bb697bd03580bb9a011c74d88cbbe57696610") ); + ( Hex.to_bytes + (`Hex + "3609ed4bf6ce48cdce6138f7528b940e9f053fd295b5b99a1c15639e3bf95c31"), + Hex.to_bytes + (`Hex + "1a721ca3847657e21da570c08613ef81ca7843d0529afb2a40adfb8db3c0542c") ); + ( Hex.to_bytes + (`Hex + "df3f5aaa6296621e9b38319ddc57fb94b73a6cbe2e54c563c55e927ea551741d"), + Hex.to_bytes + (`Hex + "4b45caaac81d4c93ddc0ef4e8c0486c0bc6f4b1672149cc4c77e479339514b0a") ); + ( Hex.to_bytes + (`Hex + "8f1144acbdce7c7e1cff29842f2755e0245fa724f8b5803c6846d410743c3d0d"), + Hex.to_bytes + (`Hex + "cc5522b51bb2ea7982094fdec0616812e95aa52386312ea04f33589712e7942b") ); + ( Hex.to_bytes + (`Hex + "2f9d12d73e38770e189b0f4b71df83622c0666d67c616408570b9174bafa7e19"), + Hex.to_bytes + (`Hex + "27c1fd12cbe2b885cd4527deb575887a1bd399ed976af58da956e9d64755d934") ); + ( Hex.to_bytes + (`Hex + "55b0246b92d21cd28e414672077a16a4479b54efab11293e66ee1cb1e8d05a30"), + Hex.to_bytes + (`Hex + "38b9bfa5cf73399bd68038d1a50ca212a434b7c342120782d8bfbb6d0291253e") ); + ( Hex.to_bytes + (`Hex + "be56486b62e3bcf68434665bf1e65edf613e6647f1bd37bc1f77ccae20ed802a"), + Hex.to_bytes + (`Hex + "53d7d940cd58afaeeb44a939a1817667aed180d0204278db73c8892f539fed3b") ); + ( Hex.to_bytes + (`Hex + "343be7691c356da932b474bb2ce6dfe5093963c586f80b3e520f6b519d676911"), + Hex.to_bytes + (`Hex + "ee52563a48267f441239e8afb303d877d34f8f9879a71ebe5df8ef46d858dc24") ); + ( Hex.to_bytes + (`Hex + "305087bc2ec61d8565573c700c51571992c9ae3ae88d39d4cbd1e0e06451640a"), + Hex.to_bytes + (`Hex + "6d93a61a4c4968d7a4c248a5eed7890cb1767899b7871f7e82f179383db63f15") ); + ( Hex.to_bytes + (`Hex + "3934a842190665c5f23d3a197cf516770aea7a8de1b0251301768ba65317a905"), + Hex.to_bytes + (`Hex + "3cd4bd26162343245f57f2a364e79f954e149997406a09d708957e3430c6291c") ); + ( Hex.to_bytes + (`Hex + "2ae71114466f43e8592a497234401a2c91b68a938d0a47134435c9ceb534e325"), + Hex.to_bytes + (`Hex + "3d4bad9c33d2c5ceab45cca461070da4b284802d50d24c1974245961db646001") ); + ( Hex.to_bytes + (`Hex + "c95c3725b565f0e2ab25888c87592825666a9dbcc13152927e9c90c1d02b9c37"), + Hex.to_bytes + (`Hex + "30947563a7effba0f083737b411e0e43406ef3663a12eadd1b9fd59954c2a911") ); + ( Hex.to_bytes + (`Hex + "aaed2e861e9e5a0bc661ff618243a3c0a1f30148dcf6414b826f65d3b2c76f0c"), + Hex.to_bytes + (`Hex + "b53b603ee8500df35f8e547d78b49f58eb0eead132b0d5068efedc966da79224") ); + ( Hex.to_bytes + (`Hex + "d9e54f3a694d19072270ed5cd6cef4c3b7e6eef9c3c56519040eb53b455d170c"), + Hex.to_bytes + (`Hex + "9a97a8025ce6286ec21e3a21b2bd55918aa01bacd25d92a59029012d4f3d6e10") ); + ( Hex.to_bytes + (`Hex + "0a6d8f716957f52a809c3ddb3501cc0a055e1393959df83155b1ed20e3eae526"), + Hex.to_bytes + (`Hex + "c9d15fb9eefd5bd774538c810aa8631e40c00b0fe6c3b14b0c4b14cd2a88051d") ); + ( Hex.to_bytes + (`Hex + "945b395ef290c37e49a58fc655073042070481af33971092d900eb14d7600d31"), + Hex.to_bytes + (`Hex + "0a651044cb4304ce43ef00f95340c0b1dd1f1293a3e787405ceccecd9e55e23e") ); + ( Hex.to_bytes + (`Hex + "43eb09c7bbb2a0a2240618bfea17de8a8781ac1ee5ce3dbe8dacec0981041917"), + Hex.to_bytes + (`Hex + "5ba015cc3a97bc2a3a190a570bdfa850441d0e4f98e0f187c5f8feb9c53a6712") ); + ( Hex.to_bytes + (`Hex + "6933586dfed061b4879282c90f11bcccf0a5262647da6302c619379c22d28912"), + Hex.to_bytes + (`Hex + "126269f809d1847f7ef3c9603584b6e7aab9a3a8a326abc9441eadd4e9e5a708") ); + ( Hex.to_bytes + (`Hex + "fbcfa6670ed757d663d6d8f57a8fc21bddac2e5e97cb6c172a221ca9f148dc08"), + Hex.to_bytes + (`Hex + "8c12b640eb0caac617a270c2e59ea1943a08f4a114f1799fd0b355aa4109f421") ); + ( Hex.to_bytes + (`Hex + "c1c2137103e7c68421f52c5e9a5a49955eb8c81ba2c09dae022d7f250978de2b"), + Hex.to_bytes + (`Hex + "f9d24e31a6c014a16f877e3d08e6e79b2afd29d9236805c1bd50e2832a6dac15") ); + ( Hex.to_bytes + (`Hex + "0b3421a4d59ffeb026cd9e3c71f1e448bc954a3d71acf4e433d0b51a28612b31"), + Hex.to_bytes + (`Hex + "9c5ddbaf00d45b4090936bef9080ebaadd533ce2b3c0697459455db0bf214f2e") ); + ( Hex.to_bytes + (`Hex + "842e12762bd8bfa0272d48b50aca786c1debaf625356ae7508ead48b7f3b9b08"), + Hex.to_bytes + (`Hex + "792570c63438ca7f58625d08d23162a034eb82d736682fb3c410ae3531e80837") ); + ( Hex.to_bytes + (`Hex + "fec7056c14c06d9f5fa67cd6b5b3191154fee6f72e6dbf454f3eb69aac084101"), + Hex.to_bytes + (`Hex + "73d114a5e736f957f2a33e28b8a94e3ddfd856bfbe9b450bcec3176483be9600") ); + ( Hex.to_bytes + (`Hex + "101e0aa66e7e84bff78aa159a90d7d006ef25d80396f669b98470dc7b1a8da2d"), + Hex.to_bytes + (`Hex + "15320421a1e4fa8a5f435c661d2845fcd6d0a497235d42cf16e44435e4d53b20") ); + ( Hex.to_bytes + (`Hex + "91b969c742a35563a5fba87c613594af7c86c61b5319c69b848ce97cb2b4c635"), + Hex.to_bytes + (`Hex + "e2d005aaf2528b35a711691004f4361e5e9212f55d77b1df60568528ff4c0e2f") ); + ( Hex.to_bytes + (`Hex + "4f399d65aa45c69bc252f5afd5f9fb63df0d7d15f9a1812add1b2b796d8d4008"), + Hex.to_bytes + (`Hex + "ed6f42a4e0c91462b04ddcb2c12d0c58918b077ce67c6edf07580aaac7869b14") ); + ( Hex.to_bytes + (`Hex + "5dd16a0120fb6623a292be3209a5117edb854dd3903c46dfaeddfb3724357d3b"), + Hex.to_bytes + (`Hex + "2c3be7e2a27801d717fdbb49607a76eb048518715a0c81a08aac317a14dae130") ); + ( Hex.to_bytes + (`Hex + "e205a379c31c6c99dff97fdaa735d961fed1840e503c7ee709c0dfc198609d11"), + Hex.to_bytes + (`Hex + "89adac0bf6683ce8ea8a337f6b5fe4e3110a0327b7ed02cbd237a0c7d8fcfe0d") ); + ( Hex.to_bytes + (`Hex + "3f2ec1c0efe149020e141bfc50f735fda4240aee25fdcc3436e9501437ea852d"), + Hex.to_bytes + (`Hex + "a6c67670877e03ea989a81714a05861eddff55de670ab2c8ad6e60c5dcf1a02f") ); + ( Hex.to_bytes + (`Hex + "2a14698258409d147e0ccd8799867ec460c2e84ce4848390513def99eccc650d"), + Hex.to_bytes + (`Hex + "5cbb951bcebe9f3dce60125bea8769732c3c99e043ccc5693d5eb2bc05289612") ); + ( Hex.to_bytes + (`Hex + "f67057f8ac790ffdf258873bd05aad2c87f03a95ba4e9dd76303d8628c777400"), + Hex.to_bytes + (`Hex + "b204b775bd43534d6cbd9f38df6469fb14c4f136514f9909854ecbc6aef47607") ); + ( Hex.to_bytes + (`Hex + "c49dac8c6eb107226502c3926424cc6f45b8f4140ae0051f72e804c2bed4a901"), + Hex.to_bytes + (`Hex + "a881fb24ae6983f76799ae38a2a841f70db3aefa85080844e618b9491f7ff703") ); + ( Hex.to_bytes + (`Hex + "01c14bfd83e073ad7f193bca06c699b20665a80b0000c861764fb5c4f3359116"), + Hex.to_bytes + (`Hex + "8ce292ebce5860872d0e6cf8e016f034503f7bc45e49b086ff85c5c42bc4f103") ); + ( Hex.to_bytes + (`Hex + "8c79ab2cb7947d0123f5aa185bcb6d8d0bc294895d8b088e13fe35e678e1ba19"), + Hex.to_bytes + (`Hex + "19014a99b48427ab337e5c630efea49dc4afa2ca12814311e7c4d9de94dacf3a") ); + ( Hex.to_bytes + (`Hex + "bc557a3108cbcebbe6f03832cdddaa361ed6abe6b60500df7c083d054ec62725"), + Hex.to_bytes + (`Hex + "ef683a03ee48e86be1cef4d4acf9a355bf2865d4ce57ddf696cc09b57dea271e") ); + ( Hex.to_bytes + (`Hex + "80421695d912bce5f65d2551c20d002a82d84c164b9236a949cea8328a35a934"), + Hex.to_bytes + (`Hex + "a2accbdfe477e86021a5f825883ea50a98f0dd83c56c25e3b8cda35a5cfcdb3b") ); + ( Hex.to_bytes + (`Hex + "d8163deaeaf7956d8353d66b9a4ec00383b2fec417bb05ec073b1feda5039e28"), + Hex.to_bytes + (`Hex + "8676b1fe2fc56a2b4889494e92dab7bcd3db4dd081cd95a94a225911576c460c") ); + ( Hex.to_bytes + (`Hex + "0c9fd2a4e79b9360a20a99b7a2621815c28ce71c2ce6a344f3e57d42ea251e20"), + Hex.to_bytes + (`Hex + "4f6bff27e95e535826719295b3b5baa981561ee60807602c6d02a737f668d431") ); + ( Hex.to_bytes + (`Hex + "b327f932da2bec9787ed61c3389f797e88fa01d60bac8f58fe274d7336775f27"), + Hex.to_bytes + (`Hex + "b9d945c5278a2664eb0123c43da2a0461cc8cfdc4ce07dac99b4128378473030") ); + ( Hex.to_bytes + (`Hex + "2880153246a19194abe10164c2c963ee7b84e6e39c138fe62f84ca9a03e8e90c"), + Hex.to_bytes + (`Hex + "0946c725d1049de0adf85ec0d0bb7037679569a1888c8bdde4a627f11239992d") ); + ( Hex.to_bytes + (`Hex + "08dd636f595431e5c09fa110fe13a0f740a074acdc76b4d73f783f2fbf75a008"), + Hex.to_bytes + (`Hex + "00b2d2800932621977197f5fb6e1a63d359cdbf2bf4d6861049281b3f54b213c") ); + ( Hex.to_bytes + (`Hex + "9d8e05e38d69fc46530e8be5297482ede830d865b52a3bff501e256f8e89e62e"), + Hex.to_bytes + (`Hex + "9e7f78b76516ea2f83909e3352eb4ca8f69b0669092832fca49544d27075a022") ); + ( Hex.to_bytes + (`Hex + "50938d0230142e8bc02686bffb41ada9a7b4630a9867ffecd2ab840d0b64ec38"), + Hex.to_bytes + (`Hex + "c4ddd99f9d2417da132c18a3425d623862a27753684cb074ed8050ababc8611e") ); + ( Hex.to_bytes + (`Hex + "8cdb929df43b6392c3fcd612027e425b689c993c5b2b0cd235366d73a846a734"), + Hex.to_bytes + (`Hex + "2073c09ff19a4c48c2ddb04e044c6223733b4d851435e8273bc7a77ce8166430") ); + ( Hex.to_bytes + (`Hex + "6b3545cc0d11d432ae0703fc5e7ff4488396fff32b0e53785f2e05daab91d636"), + Hex.to_bytes + (`Hex + "2eff025377dadbbe247079f217594c4af5d7e3021c7f890ae4a04f61f3b0ac01") ); + ( Hex.to_bytes + (`Hex + "ffd846f0c024d34eb454bc41ca1a1fd850589331fd703d630ea9989303eb152f"), + Hex.to_bytes + (`Hex + "c937f75a9944bee7e72c33031b913c07da2dfff5ed25a66edfd32d09f6639002") ); + ( Hex.to_bytes + (`Hex + "c1c692700b26f21524248b67e336fd0090323d40d5366314bea6dda820d6cc26"), + Hex.to_bytes + (`Hex + "f65b3cd9f805d6249408ca75901450be1811834143d5ea7014e561be93427e19") ); + ( Hex.to_bytes + (`Hex + "5644735c7132509b1f8829b3cf79ff2a05237786f727ad20546284009cdfb21f"), + Hex.to_bytes + (`Hex + "8fd23c631c5026d77e1dc787bde975eedca37a3dd1ffa0e5ed9aab8a182a0135") ); + ( Hex.to_bytes + (`Hex + "38a02517b73be3a5ecca26d1fa446f1a113c6b8b7b0c82c6924f4bf2871a691e"), + Hex.to_bytes + (`Hex + "42ce8dcd4fcf4bef8a0c175af961d49e337b3ecc1a455b88b495b0ffc94de017") ); + ( Hex.to_bytes + (`Hex + "32e0f01adea434e129aa65fdcaab5560f62963750fbd0981a69bcd6f0c2e923d"), + Hex.to_bytes + (`Hex + "ed4901c9ffb51da5da443abe3c228688f163c78b830df39c9ad0765561dcd623") ); + ( Hex.to_bytes + (`Hex + "0c992a2b6e83e279b97e4f43030f2d98abd56ce77fb4d28b0290ce02d5a36015"), + Hex.to_bytes + (`Hex + "38f5f6791d70ca38a75c5a26a2156a0edb3c8acebdbb4169c2715d72bdbced22") ); + ( Hex.to_bytes + (`Hex + "cc172b9bb44262eb08b7b3cfbfc045dc3e3f1afdab71e91ad5f916616a925038"), + Hex.to_bytes + (`Hex + "3a1ad599f92246dbf31e98731826cddd9438d1b30885b53b676aeea7e86e0120") ); + ( Hex.to_bytes + (`Hex + "20a64dbabffde740cef9e32230b956f0257334e749eeb802e38dbce161f56f1d"), + Hex.to_bytes + (`Hex + "9d3689817a024eb81d036607da75f222ecf270c18716e54fd117e13969c02a3b") ); + ( Hex.to_bytes + (`Hex + "0cb2ef79eb1e07621a6b6f9c0101390e3d086308d4b29aad0c438ed9a60dbb24"), + Hex.to_bytes + (`Hex + "8427285352758edc235e9a386bd3f097b49bdf4dec2759df404d27f8780b5f20") ); + ( Hex.to_bytes + (`Hex + "ce430d68f696cd01ef5689b581e9d1eab659d3618f196c7cabca8ea22c658e2f"), + Hex.to_bytes + (`Hex + "f00f4af3c8e593f8270e204532cb0ac7c66d29aeea36c6f88944671dc1822823") ); + ( Hex.to_bytes + (`Hex + "7f2abe68482c8ed485377ce9243176fd765a6228a0179424b66b1458398edb1a"), + Hex.to_bytes + (`Hex + "7122d83333a9b2c5ebcc8d031f1034c2abef609f90b6f31471a705ba97deba27") ); + ( Hex.to_bytes + (`Hex + "415354a414a8813787dbb08d114f39a8e20408444093895f185081a5f27ac232"), + Hex.to_bytes + (`Hex + "2145d8530a477250194d78f826f4caf314a3030d07fcc759152a2ad88147c905") ); + ( Hex.to_bytes + (`Hex + "5c0e21700582d180fdc305bb749dc1c332dc5d797209d7b4f21fb09058d80317"), + Hex.to_bytes + (`Hex + "1c8f5bd930baa14806231dcf720cf0d8529a28314cceac1312df46f04b5f183e") ); + ( Hex.to_bytes + (`Hex + "ce5abe15df75e56f250b467780ad1f2c80e5ff95918db91f7403f6256bf8d225"), + Hex.to_bytes + (`Hex + "4da0aaad9bdd6de50c3d3d1052543a440fc3012b54e38f26ecb636c0afd00a36") ); + ( Hex.to_bytes + (`Hex + "23df58731932bed54d9bc0656c6ccd3612f23a7d9dca86283ff87f2c00c1d00a"), + Hex.to_bytes + (`Hex + "30ea68c280365c96bd7a8fc7881cc29081b42ed3fd7dbdadc89c7efe873f323e") ); + ( Hex.to_bytes + (`Hex + "c965bcbcf7c427a995da6c35b4546bb16a94a1c0ce217d46f3fca88b7a7a943a"), + Hex.to_bytes + (`Hex + "2b806b2e2fc8d56a8cdafa9a225b3421d5a19cfabb908ffcfb1cf43e235d6017") ); + ( Hex.to_bytes + (`Hex + "ffb6f88436475b7426f2287de672a72f123d580a1c285c7f3a2e063974b90121"), + Hex.to_bytes + (`Hex + "623a4ecf091116e642189d11adba0e25490fbc246a35d4fbe4fba67da7867f19") ); + ( Hex.to_bytes + (`Hex + "22a0b465f0cc7850c1ce0c7679f6ddcaf2a050953119f957814b2f2051039919"), + Hex.to_bytes + (`Hex + "329f7dd593104cba0fe90f0a45f10aa8f76a137328430a6438c1ebd25f466519") ); + ( Hex.to_bytes + (`Hex + "fc6f6dd8df75754db5ba9914c0727b8cf6408643e99f5483c7927d6d2317a501"), + Hex.to_bytes + (`Hex + "669d2d15df9a0e856e36ee4356f27bb89cf26d08af1cdd39fa5c180cfacb2e2b") ); + ( Hex.to_bytes + (`Hex + "5efb0c2cc3d2f42f482e781efb20665b39a1a6a68f044e1689d2177498de7711"), + Hex.to_bytes + (`Hex + "f896638b3cf6734468767ce418701388d65865938a65546e164d24c12ef36515") ); + ( Hex.to_bytes + (`Hex + "ca5464ad46b0f8d3fb5974f0288e830735102039076e262cb4581e9643aede1a"), + Hex.to_bytes + (`Hex + "8508cc972592accb41bbb8ecf2419702fe0fa8bc8188f7529739ead9d73b2626") ); + ( Hex.to_bytes + (`Hex + "ee15ba101cb09b23d92183e82f2edee05884b20d3da09e24eaa864c31010a102"), + Hex.to_bytes + (`Hex + "55bfd380bd6663bdd07085df0e3e68b96be3ed042f640af004a50bb322d6ff37") ); + ( Hex.to_bytes + (`Hex + "be79f5d2a7071ac33b7386dd164ae09307ac6f38d112c9be39e76cb7d9259119"), + Hex.to_bytes + (`Hex + "31a7170d8c9a6a9756722044c4c96faf8dbf7e95f80e5b7e329512751a40fe1a") ); + ( Hex.to_bytes + (`Hex + "fab0136665fae43be494262e61be1f3a57dd5e3bfca69100d4ea6bcfda5dfd39"), + Hex.to_bytes + (`Hex + "8d932da0108e1ef6245cb1e1fb5a3d301594c5f183c23b4f686dee256b63ea19") ); + ( Hex.to_bytes + (`Hex + "79c30811ffd6712f1624f8c89b64383300107009ba7fcb291cc7bbde8dbe0632"), + Hex.to_bytes + (`Hex + "c03dff970c999747bc971bbc3c24f3b0598af34caf2817809611df5332eb563f") ); + ( Hex.to_bytes + (`Hex + "1f2e096e7434665b820aeff9f587e2c2ca660c21dd954224ae954cbc2dea881d"), + Hex.to_bytes + (`Hex + "563361f8b88e9de171e9107fd610534bbf0061284e39e61ae335a33e8e98c90b") ); + ( Hex.to_bytes + (`Hex + "def20ec2b7adbec30897325b5cebcae81b631da9f5c80b7c7fa896bb0d7b7d35"), + Hex.to_bytes + (`Hex + "85edf6e66d6f73ad09631e07ea6f76a100446e541911ff73b96e3217a3a0b537") ); + ( Hex.to_bytes + (`Hex + "7b4581ecb6d7fb71f8e2bd8e0b88dba38272f7775e9dae6fd8f4e5aafe332239"), + Hex.to_bytes + (`Hex + "806d6f738c93db103197d15623e73d3468a45d9d7ac3b3782b0a60910e301716") ); + ( Hex.to_bytes + (`Hex + "a31aac5b77884a42e5c08c7ee836c8a86492fe03742371c30ea3667a8ac9f126"), + Hex.to_bytes + (`Hex + "d944b20d6eb3a35135e07d88881dea3edaf31fd502a9cb2568644845900be736") ); + ( Hex.to_bytes + (`Hex + "c1d1610bb5fd28272115d16e70a071cb6fab071dbe2909054cc87e2b627bd221"), + Hex.to_bytes + (`Hex + "80cfe07efe1c3ae11664e1a8368c30ae846de09c9efb99ed42180398b8caa734") ); + ( Hex.to_bytes + (`Hex + "8fc2eb3aef35bbfd870e441e06284b830d150766e32565bd87d96a88983d3c18"), + Hex.to_bytes + (`Hex + "a95b3dbf6ee0b2ef57b91a3783e72e8df807c7b0bd8032caf068f508886be11d") ); + ( Hex.to_bytes + (`Hex + "5bec4e92c0bd6d7847419c181c6c10e2d50a17bbaba84b7ac85e6a17ca5cd227"), + Hex.to_bytes + (`Hex + "e3381a6a9c54ccbcc1f8d5bc83d3e7ff70c84bf23306451ec12195ab09076e34") ); + ( Hex.to_bytes + (`Hex + "3e5aca3c4ff4735e357e6cdda3c765a9dc894911e4eec63e076bbed4eadf8310"), + Hex.to_bytes + (`Hex + "9ccfdb9d254b4d29c66145804e97ce7acdc0684d3f847e5025e9c0fe788f2d0a") ); + ( Hex.to_bytes + (`Hex + "05b26d2d8bc75ef0c53fa68d3bd9ed74b5e162c93dee142de27506a279e7963d"), + Hex.to_bytes + (`Hex + "df534224fc20b074e5c1848a1c73675eca9c83ee2f57b9763d7984e5c74fec20") ); + ( Hex.to_bytes + (`Hex + "6c9c2fbf503a8d61c9539dd0ad129e2c9ca771992ae10ec4f24adb8c495e9321"), + Hex.to_bytes + (`Hex + "710d474871a46d52fd44067ea6adb691b08ef1f6c80fd30e03d5cea7d2a93933") ); + ( Hex.to_bytes + (`Hex + "d2c4e2eba96b83509fb84ecf486e971aad176cd7363904875117b4941322af29"), + Hex.to_bytes + (`Hex + "c350097f10cd44f6bc94ea01c37184885852e63bcfb23789cb9802e2f5204726") ); + ( Hex.to_bytes + (`Hex + "dd6b5a4e7229c7950b751e2f97a655cc75c313f9c390b7b96c12d6bc2a0cdf1d"), + Hex.to_bytes + (`Hex + "c2681fe5e77f61b2d18ce22700f76aaf772e2c4ab55be822311cbe6afe6caf04") ); + ( Hex.to_bytes + (`Hex + "f3e25fc04e8ca68eef317bbaadd45501d9ea841ddf74eaa597e8380a90082325"), + Hex.to_bytes + (`Hex + "512163113e884aa6fff8772443d707d1fc365871f849af0d35647a68630b813e") ); + ( Hex.to_bytes + (`Hex + "2713839dd3f1e8b816fb232f9a12fdee584b7c41e995e75c70a1758c8c507935"), + Hex.to_bytes + (`Hex + "715eb2e44c57b9e115b57ee84db47ca3b88a559db92492f423f65b9e7f99c409") ); + ( Hex.to_bytes + (`Hex + "07f9ee130539105099a89ad3aa6a1947021a09e71b85de540ee7574997a28427"), + Hex.to_bytes + (`Hex + "abdf8598efcaee2478f6275f093089d11f09d915f46ad31f448e37b481ec4b08") ); + ( Hex.to_bytes + (`Hex + "134f93e4b4749fb13ce284f01be8a0e31b23a3ae1fefb2afee87c0ac46e88102"), + Hex.to_bytes + (`Hex + "2f5493730fd075d9d0599eec1ef9aef80c28c5b9118c85d283f8dd5a525d003b") ); + ( Hex.to_bytes + (`Hex + "ecf321e2ea98667b9defe381998c52aa22af14bb1a5e9485e00142d676565a00"), + Hex.to_bytes + (`Hex + "1b02310aaa2103f4ce01e94372419d4be46ffdffa130efdc6b5ce717905d5c11") ); + ( Hex.to_bytes + (`Hex + "5f73ee291aa30bb5059fbe55444287e041bb347f56533d4bd58f73efa2df9235"), + Hex.to_bytes + (`Hex + "7facaa5eb4a2ea5e51daf45d58a164ba8ba1a1e2181ef264f4f4b3602c474427") ); + ( Hex.to_bytes + (`Hex + "76d03a5a4c7db71aa9558f132e34efec3bf9bd1ccfd481e55c3d7d9f59f3a10e"), + Hex.to_bytes + (`Hex + "5fc1e39fa5ae25fce0644ff41ad7ebc8eda5b538542e6baa20fb7e1f50d9d71c") ); + ( Hex.to_bytes + (`Hex + "f97ef6d275cc2cb96cc74bbb50708c7c05b77c3e71dd06ae6f9a990a6eb6e712"), + Hex.to_bytes + (`Hex + "901ade464c1773ce2436e6dc5c8c33f2baca0761f1d01173c13b6e2fd83cc507") ); + ( Hex.to_bytes + (`Hex + "0c886306cb689f6733c7f2b8b93aeb22d57a17eef2cb9a8c05c9b296c24c1502"), + Hex.to_bytes + (`Hex + "4cde53bb9872f8f99016c41e208c36df0e2eabc582d6644969cdb71f23fd401c") ); + ( Hex.to_bytes + (`Hex + "5db75689fc8b192165b5a4350b621d996dd84e8145c4ea71323f3947b69dc728"), + Hex.to_bytes + (`Hex + "13f117ae6020ce1450fc4612c5fd45be73beac1019431c8e2e918317c6531213") ); + ( Hex.to_bytes + (`Hex + "37dd05107e766d028a42641aa22359070e6a9db70745aeee6b2573810d76d537"), + Hex.to_bytes + (`Hex + "c0566f939ed91452582f31670eb5a02638d2c16e2970fa3d901a285ff20d0c17") ); + ( Hex.to_bytes + (`Hex + "68bd4dbacb3b7a39f51ad106162877f56e1e0c22b5301408c973e345c4caee04"), + Hex.to_bytes + (`Hex + "d1654f1a9d61e63d7a6b54eb2ba90e68bf51fc19ba31d4013007a713d1350c07") ); + ( Hex.to_bytes + (`Hex + "0bc54be3da437a321763eff90cb82792f5657a7231c37b20870419958e365b2f"), + Hex.to_bytes + (`Hex + "c18b4b04c7f9da598450784c4a94b31a30a19fed136a16b7b9e000c3e0916521") ); + ( Hex.to_bytes + (`Hex + "5fb91ff28812a95f44477b83a813d2bb8c5d386970324a0ac1c9c5d593f1b92d"), + Hex.to_bytes + (`Hex + "ff9b1a1a9898bd7b0e0654ef154dd24a5e035e91a3c7248816e352813ba0ea04") ); + ( Hex.to_bytes + (`Hex + "0cd011e217518e71612c06e8a70420680688ee0252124de1bed8ad17cebbd635"), + Hex.to_bytes + (`Hex + "3e853e579590506d54ff5dbd45bbe99b0ae5b2c215d642d11c8349b0dc45210d") ); + ( Hex.to_bytes + (`Hex + "fb547735aa32e48f8b89d39413856647c4759dc8d0856f773481b01e1e094411"), + Hex.to_bytes + (`Hex + "6493b4dc36908f393e1c46dd191fa7aa9e655d7bf30b24da7038f27b3882091c") ); + ( Hex.to_bytes + (`Hex + "fdd95fe793c97065f93787e1eed39555584bc7cea7322906fab484bc6c810202"), + Hex.to_bytes + (`Hex + "74dab95f9c9ef01dee50f44271f247b8a6dc75da3b3499f4266725743b328117") ); + ( Hex.to_bytes + (`Hex + "d251887f370dff5ab3bf7de859295373961cb7fb6c474c638376fdce1888df11"), + Hex.to_bytes + (`Hex + "3d547745c4faac35fc61581644db8f5c30fb3ccf390f194bb8d6a34268c8dc27") ); + ( Hex.to_bytes + (`Hex + "3463e1bcb5366f700d8f7ed68ebc63ed8b14a1d9118289539a9f1ded661a4e08"), + Hex.to_bytes + (`Hex + "e56e839324e9e0a96108958f64d6c4540643238dffbedee2102b480b89193820") ); + ( Hex.to_bytes + (`Hex + "d78a0c331cf8fe3a467fb73c8bb3318f37f2bcb4e3a9e80b58ae17799b72ce09"), + Hex.to_bytes + (`Hex + "e08d324786ef99d14481f5a34467037b94790a58efb845a5ab076997111c7410") ); + ( Hex.to_bytes + (`Hex + "afb9da869ad63dcc3e0b2bd5095ae7d4757f108b1d09ade81ef0d8f82ecc432b"), + Hex.to_bytes + (`Hex + "630f3db0510c14bd5d28cf4b3c92061011790c12997a21726f05538f792b2f01") ); + ( Hex.to_bytes + (`Hex + "6c4813a39f94eb0bf8ab9d05d6e45c0d162bf576414b91494cebb597c75d141a"), + Hex.to_bytes + (`Hex + "02dcfbb52bfb0a9b7ee6328b01d02eb7a140f6e7acf4c18de835c1e2e699030a") ); + ( Hex.to_bytes + (`Hex + "d63b850afc3ce5248a53845240a491c6673fcaa287855f28acb19a58ba294900"), + Hex.to_bytes + (`Hex + "b5119eb5510fd04718d0244fc5e64c0377225293f5fdfacd59e480cda4014017") ); + ( Hex.to_bytes + (`Hex + "cd64e488a6fbf2054ede9383114f07cc16f63a2dd184d38cdbc5bd6561c52e08"), + Hex.to_bytes + (`Hex + "3814f6cd63d4f40f0b8297121385d4b96f7b116049ab7a5749de476fa5ca9f18") ); + ( Hex.to_bytes + (`Hex + "059c9d4534f2666aa20c6a04e7b4b35273860bacc7f50c5f4d0fb78a8b374d2d"), + Hex.to_bytes + (`Hex + "e37d3b46f3c3e8250cdd23b39364b71d7f7cf869c7cba696e1657bd5e4093304") ); + ( Hex.to_bytes + (`Hex + "a0e020c5044d05cff13aa11cc7ed40d50004dd774b04934999ff7eb7cda90e1b"), + Hex.to_bytes + (`Hex + "3bcd1c32a80e28693df0a8a195b8ab723477872c8f93d3f3cf6b73ae69177012") ); + ( Hex.to_bytes + (`Hex + "2da15fadf0a2523e64b0bc38a65b18442266f15befd38befbf28b216c25ef53e"), + Hex.to_bytes + (`Hex + "059cf4f214cb2bb858096e35e5aecb1e3ad8cd851c6850d88ac1cda3307a2813") ); + ( Hex.to_bytes + (`Hex + "d2e45b673115c976d5a3e7f5c0eff3bf5a2e04c7eb1f16bf2d213e5e5ca83300"), + Hex.to_bytes + (`Hex + "07165b735f29feb31188852f9f16074c4be214e33dcdaf53fc44469d1a2fdd33") ); + ( Hex.to_bytes + (`Hex + "7181e7979606418e95c7bf320812ff268a809611a40ad70bf599d24044f3e03a"), + Hex.to_bytes + (`Hex + "9a66ad2d0bb774243f7198e8a7660346baaed90b245b69b3eae25e466dbb743c") ); + ( Hex.to_bytes + (`Hex + "eac2dd91a342896ea9fbf3fce1288ac378f1795a512631eb5b413a2d3d5e1f34"), + Hex.to_bytes + (`Hex + "a84c5e3764ce4974336db30f5a740206559070d391f8582943e0c82d1222b209") ); + ( Hex.to_bytes + (`Hex + "171a867f62c6b406301af709558a926814c56f210c7e160f265c2ad095af3a3d"), + Hex.to_bytes + (`Hex + "c69b3143ff9ddff155f7a6c95bab2837953fd72e3502738ca02b90c70c6e653f") ); + ( Hex.to_bytes + (`Hex + "0a3f62d00459459fb67ba6729e022378e42b0a512cf2fb99e78a23472ddf852e"), + Hex.to_bytes + (`Hex + "e36678e87b317d32943edf95ef755ea4490f02c46dc71a7b5e817ca3cdfb603a") ); + ( Hex.to_bytes + (`Hex + "c2a5a4e28ea0df17c83c397fbffd370dab3aa369ee0a655fef6f2f513fcdcc21"), + Hex.to_bytes + (`Hex + "bb3b34197bf4015503579b83da2529c6db98c74aff5d69e8b3b1e8e0c0311626") ); + ( Hex.to_bytes + (`Hex + "df27009ef97ab811f1a4fcd648bfd7af33c2f442ff1a40d5b237408d45628d15"), + Hex.to_bytes + (`Hex + "36eb436247fd6f8b2e195d42a62a6d6c4c6260de15af4891a00086383899873e") ); + ( Hex.to_bytes + (`Hex + "c2e7e1e4772c07fede6862e68c3cd8939b73bc2902519f6159af2bc0245f663a"), + Hex.to_bytes + (`Hex + "76a8c85898f157c5f91a817395983177e6935d998d917d6b36968ec97d067f30") ); + ( Hex.to_bytes + (`Hex + "75c6686a755436a453354f7999f2f288c762ae74b845117f81b4270f1af8ee0d"), + Hex.to_bytes + (`Hex + "8ccf5e7fcf473e9947045e1b2c5d10e882ac1d1a23b9adca30e22b4b69897a14") ); + ( Hex.to_bytes + (`Hex + "84611eae66e323479bea19d77f3204ee7df252e173bedb248d43716176990021"), + Hex.to_bytes + (`Hex + "6712949b4e8ee4ef84a0b0fa8689b1ac5eea11ae6356107b0c401c771d224f27") ); + ( Hex.to_bytes + (`Hex + "1e3d57869017b85cc4dddd2ede6305ddebff88b357e5ba785d36d04af1b9841a"), + Hex.to_bytes + (`Hex + "6a2366e9b8bfdad1c80cd6cb91fad3573a334802968092dc7f994752b4216c37") ); + ( Hex.to_bytes + (`Hex + "b1f721dc7ac0f0134b85fe05e9695c2a4fda7d1d4dd173059da474b6dae53e19"), + Hex.to_bytes + (`Hex + "904b4a71ca74a17f93a7a5522eaa21fe91c75b0f36b5dc696ce2d70337b2161b") ); + ( Hex.to_bytes + (`Hex + "e6b8d4276568f6eacf1f6626b4aaa01a735ea0a2af9ba71a8540c28e2c728935"), + Hex.to_bytes + (`Hex + "8ffb47d79104424157bf8a72f7630bc20bd22aab74191df678a9cd28b3a2163a") ); + ( Hex.to_bytes + (`Hex + "11e084e8c89a9a4726ae03cdb0934e5077e919131f9e11c7e71577dbe7119337"), + Hex.to_bytes + (`Hex + "58ec786548ef5bf0dd50cade2fb5b905a295f69bfec4926c6d55d78ae465e62a") ); + ( Hex.to_bytes + (`Hex + "3950113a07f018941daa3c29e6f7ba84e8e8376cb57be54b9e2f9dba6c0c012e"), + Hex.to_bytes + (`Hex + "73133a79c5630cb392a6dae468a8a7c2ddb61fb77be69f782a8e263192c11228") ); + ( Hex.to_bytes + (`Hex + "b6bcfbd66d8b3e8ae2cb83358695b6faa1b5bfa4473c2e3d9de951b3760e1517"), + Hex.to_bytes + (`Hex + "5777a465fa22a82e1c7455c64ae62f1f7095acf55a20aad1e9c8360888ddcf27") ); + ( Hex.to_bytes + (`Hex + "79792a82295f307de29664a3c14f82804d0f7ac7f41c3df7be26196a3cbe9c1c"), + Hex.to_bytes + (`Hex + "2318761c8caf17aa26e9f6ba90a2d0092bc2d6b5f8061cf6cdd932fc6d1a2f17") ); + ( Hex.to_bytes + (`Hex + "b92f20b54387d35ad240be5095263a08e3cd673f031811b910b8cf3062f44628"), + Hex.to_bytes + (`Hex + "4cc537e9e7b523e2213f8bb0fd77c5f2d3a705752b65c1b630e1602e98a48f2c") ); + ( Hex.to_bytes + (`Hex + "f395754185e1bb5602c207945300c1ec2efd307615c4a59020ce1064f28e331f"), + Hex.to_bytes + (`Hex + "d4b7561a59543b1a25bdc8cf2bc41127651962a4d64213b328be6a6c2757041e") ); + ( Hex.to_bytes + (`Hex + "d6e9c21f2d12f033f4b50d6de207afbb2809f290dbe1a4ad519b1f7ed3780d32"), + Hex.to_bytes + (`Hex + "f9790eb82ffe4f6d4d9c6001f546971617e11f3769aa949c617697827da4ff08") ); + ( Hex.to_bytes + (`Hex + "1517557d5f41ed0e7b4511aa983b20f4fb0a7644d5f35390a176a2deba03c202"), + Hex.to_bytes + (`Hex + "afa542e84a02d7552fcdeb9dba038cb5b542aaceb6c86b0c3e5c356eab7f4e3b") ); + ( Hex.to_bytes + (`Hex + "e9db0d6af8819deaf1e6573209280fce04ff52fd643b390024ef238d21584229"), + Hex.to_bytes + (`Hex + "5bdc17950f717fbbca48ab435314dbb95134e81fe360cd948bbe98f7e07ce12b") ); + ( Hex.to_bytes + (`Hex + "a23a1f078bee71d94866212f6f044265eb2fc5c4b4a01170cbc75d30e4756a17"), + Hex.to_bytes + (`Hex + "24ae75ce0b68feb8447bd2c3f6cb498587c5406aa792eea831f13d01bab0e609") ); + ( Hex.to_bytes + (`Hex + "65dafd64979e0bb82d8ac50b11b4c0b0555ce1c6a0b11bace8707ad3414da436"), + Hex.to_bytes + (`Hex + "2fe7aa81b2ef776aa7fa589b868678c5dc68337ebd3374ab00a0547f2ead9217") ); + ( Hex.to_bytes + (`Hex + "a7a99503eff692872972c2663d7f75d31090c7d576e84969a78b7f0c16f16c17"), + Hex.to_bytes + (`Hex + "bfc28da9f0d8f5f0e9d96cac9ee0184157f6975fe451d14ee454b8265637e713") ); + ( Hex.to_bytes + (`Hex + "d006c2f35732cdbc42a391f9ae8e39316c5aa32f14442d5a5231f613c7bcef3c"), + Hex.to_bytes + (`Hex + "ab007e01973b06c8c3acb544d5fd205ecd188feff6c0ce6cebbf6aec774bee14") ); + ( Hex.to_bytes + (`Hex + "b3eadb58382296c029ef10dbb0610e5ca41dcb8aedf19a6c39d925c473fe763f"), + Hex.to_bytes + (`Hex + "6f5580b2e882d4da4ec5dc7fde06f4c3b954361db888ca37d3a4447276f76102") ); + ( Hex.to_bytes + (`Hex + "fe8e2aa19aca1c7e9bec22c5a8628b94f83d8c219b04bb9d78af55d26c3afd1e"), + Hex.to_bytes + (`Hex + "1f0a654d750fb5a4132c5ea7866cb725531d4def87686cfdf051bc71d30b590a") ); + ( Hex.to_bytes + (`Hex + "50d6d0b8a8ceeedcd4f2296a8d8b2d4feb11f9ea8f52d043522b6c54524c0424"), + Hex.to_bytes + (`Hex + "f6d9f01ccdfac396d86a509f126763ca5b9b5ffa05d0852f30c196983f159e06") ); + ( Hex.to_bytes + (`Hex + "57d9614c12826e689e6486a4de9baac78d7aa3d4e091c2d3f3285f2ce3e20701"), + Hex.to_bytes + (`Hex + "1b59d7c3df450bab3df60b714a85b5f7f3260c2ef1c84d5485eacc30a7959b2d") ); + ( Hex.to_bytes + (`Hex + "f056ce95c2333d513170d77fdd2f2bbd31e0e209fe474f5db454807b4248942f"), + Hex.to_bytes + (`Hex + "67746ad365d66fdf076bea2f1f19c95d2264407163efa2ec2cf7da96c0507101") ); + ( Hex.to_bytes + (`Hex + "5828ce874f1d7a3619cd3781075c549dfd3b8f7372201adfd425f05220414e11"), + Hex.to_bytes + (`Hex + "ead566bfdf28fd18759a49f9f077bd8b3b45e8f3994f62634984388afeed8027") ); + ( Hex.to_bytes + (`Hex + "d45aa90e82300274fd2f5035e57bb263b660e2fb3ecbdc917734320fb1bfe225"), + Hex.to_bytes + (`Hex + "4f09b439713ac0adbbc2d1b40fc6f8edcb9f02b747091169658050a8e02ff401") ); + ( Hex.to_bytes + (`Hex + "d0b496e562cd2dffc80ff55ad41ad3c7fd63a6b1fa73bfa005a03e7e9546c501"), + Hex.to_bytes + (`Hex + "79678f93cfaaebef9172de076e3f866996e7e6ad678e6ec0e99a6679e7ab4b16") ); + ( Hex.to_bytes + (`Hex + "e08f27b5516e331c0b06b08867020f83f4cd36618afe89e55b3130ec36bbe204"), + Hex.to_bytes + (`Hex + "fb5b3493b55ce6cdf4f5874283fba110c12819460ca2c737626b2641855adc2a") ); + ( Hex.to_bytes + (`Hex + "ba61e24235ba3239cd4dde829e391e3a733cac03ff6d5f3aa916d953f415bd2c"), + Hex.to_bytes + (`Hex + "37898da95fa325248c589f5dd3a2660a2b8551395a8c32f855dda2b4666f4808") ); + ( Hex.to_bytes + (`Hex + "64954d3a8083c3a4f254eb310cbd9a1011a212b0b4573da8853ffd4c0cc84939"), + Hex.to_bytes + (`Hex + "409ef11e0d3fcdfd81b492467754f84707862f251d0efc6019dcc345082a4715") ); + ( Hex.to_bytes + (`Hex + "af7be5486d592e0428f615cb4130d7d91609884e78a3ec65da01e9270d7f9f05"), + Hex.to_bytes + (`Hex + "43b4f84cd4777dd3ec76417da672a1bf4e7b242561b7c8d8f5242d5c88649b07") ); + ( Hex.to_bytes + (`Hex + "be6db5a403079fd2fc466b95a86ae2750628e202e749a4841c12acced6f1bb38"), + Hex.to_bytes + (`Hex + "d1b66630731a72c706ec3bb5f3553717212c1e3e62bd2a3c160166633bd48d08") ); + ( Hex.to_bytes + (`Hex + "b68b5a05776f16a1a48d89588c2d856317774b75cdf4b4345f51e7f32daa2615"), + Hex.to_bytes + (`Hex + "b8e457261ac5854045862446a45e79969839d6e3a10304c8084b3221b0c29c19") ); + ( Hex.to_bytes + (`Hex + "c27768d15ddb2aa52eaf520b22f9036bbd22efb4e801c87f1d2f81ecc267e512"), + Hex.to_bytes + (`Hex + "0bc2e8a414400903cca800a2d60cbfe7ea945bfbfe6508c6ac41683f45149309") ); + ( Hex.to_bytes + (`Hex + "d8756f8b57fdd7bf6a293dd36ef87ef012ee8ed478c954503ac46f4fcb763d0b"), + Hex.to_bytes + (`Hex + "eb90ed4e5a62f7bef773fe22deba8d1ffe1be53a94ab60c93e975c86d8b25808") ); + ( Hex.to_bytes + (`Hex + "dd043a84373ce4e2c0e766691e8ae928a1f529d64f30c46afb320cece1f1fc2d"), + Hex.to_bytes + (`Hex + "6e7fd099f81567bdff47cc89995a85cbc435726826242dddb8fca3a3c60e6819") ); + ( Hex.to_bytes + (`Hex + "7610941f6eb9aba568027ab951b4b55175e3ed584fdce0d7637e6df7a518ee2b"), + Hex.to_bytes + (`Hex + "b4d71d44be807ded3bcf193c0ad3c2a4ed911f2e9b734fac813d89e3da486235") ); + ( Hex.to_bytes + (`Hex + "c0a1cb4d8cfc797ca1c158b9351c62814df06532196e410a417fe14548489e00"), + Hex.to_bytes + (`Hex + "d1eb35ab94932d71fb49e1d81ee11263de1ae5773399af84c91d36cd6c3c423f") ); + ( Hex.to_bytes + (`Hex + "e1b1237f566e71f394490d6a4d3c8f53ec3289b02a6e2aafaf98a237c7493e2f"), + Hex.to_bytes + (`Hex + "cc18c3dcbaafebc53dfd39634c6bf264ccb627fa5495f05e35e1e451c15edd21") ); + ( Hex.to_bytes + (`Hex + "3c4be5f9eac482c343c13eb17af2ea470f40afca75376c2adf26ee65a6cbd108"), + Hex.to_bytes + (`Hex + "25cd82f30df1f2fdf3d24540724d2b814b082264e232c3c1d38c76f1a49ea426") ); + ( Hex.to_bytes + (`Hex + "5393e594ea9132e1e5827bfc8056697d02fed7fc9fbca6ad351341ac4fe9d42a"), + Hex.to_bytes + (`Hex + "ef9845d8578566f16a5c3a9cdf78f8b6cf8c7300b9e2930931ae85486768b009") ); + ( Hex.to_bytes + (`Hex + "76a1512ca7de6141178ec18228e27b14cd8bafd427b87cf433aaa990c45ea030"), + Hex.to_bytes + (`Hex + "41a8a83edbf6093205692deac6069c1d8f6239acc834fe6adeac2faced03f835") ); + ( Hex.to_bytes + (`Hex + "edb5eb83dbdf8dbec307ab57558a5a18b0ebd564b1999c10f7c4e7c0be404302"), + Hex.to_bytes + (`Hex + "3904106bb637516bcd1e1d1afe002e6f975fb47a62ffafe26843ad0bbc3ed131") ); + ( Hex.to_bytes + (`Hex + "5b80e077c2002ce53e61e400fc6c9a2843af0eb8e6646dbae110eba23abb8d02"), + Hex.to_bytes + (`Hex + "71afc2b2845de0b5b4d42dedc819a88c1d184e89851223bf202842afec55dd13") ); + ( Hex.to_bytes + (`Hex + "785579f4649ed57c121dad4d0183e4b27b7aaef33333bc6973ce568ee3be8b1d"), + Hex.to_bytes + (`Hex + "8e6df39332e0ed62904dfd4270b6ffe011189d3c7cb9e52830b2c256d74e6e1a") ); + ( Hex.to_bytes + (`Hex + "4586a17c8e35280841fc31c8d004144eb982ed1def42d9a2c941e6337899b82f"), + Hex.to_bytes + (`Hex + "51e322123b88a11f98295ca672e6928aac66e30cae70952c798f942f30c48221") ); + ( Hex.to_bytes + (`Hex + "55449c90201437719548ffe5fa72a879602d9d25118ac5640b9d402c3f244a1b"), + Hex.to_bytes + (`Hex + "cf775c3e7b09b724c1d32c8ae4bb3c10c10a2bbd35ff53fbc3932fda5c072035") ); + ( Hex.to_bytes + (`Hex + "2b1911731ed60ff7bb66781f58663f66c2769960f3dc23b266b128c6d3cec322"), + Hex.to_bytes + (`Hex + "ea7156465be190c35bd8c712747a9c83c2f28d4765c1ab9e51b99f275e242604") ); + ( Hex.to_bytes + (`Hex + "6aa1ac087b582ef3d618d1a054090fef1b71930f0e0d3a668615c20989d9a93b"), + Hex.to_bytes + (`Hex + "9bf3fa7869feb0671788175d977c654391d3269a543934361dd6053ca5611229") ); + ( Hex.to_bytes + (`Hex + "3549d916dcf813b2d8b33f8bb95b086ccb6123a312778e3cbf8d919628538611"), + Hex.to_bytes + (`Hex + "610495c36f6a0fdd9a8b0af3eccd2e40829c3d4a4254c063344701e6b0873b1e") ); + ( Hex.to_bytes + (`Hex + "aaf8253f22febfd29a89e388d2da133d961747102b040ce4a4b7b9b25f35ef20"), + Hex.to_bytes + (`Hex + "b74ea40590fc84255e2860e8aa0f3dc7f693ce9db5e4a9a3fa73675a64470210") ); + ( Hex.to_bytes + (`Hex + "9dee5ff0efd44db404afc3575ee311d3e0ac35df48e7fa6a05af5cedbf475228"), + Hex.to_bytes + (`Hex + "59590904c4bbe16706c6cef13c0264102c8d5577937bea12a40dcaa65a9de614") ); + ( Hex.to_bytes + (`Hex + "58bfcc41a164ad3d966dbbe195cc45cd449f68c17110714f2c60ad35ce27420f"), + Hex.to_bytes + (`Hex + "5cf62ae72405ef54bcdf2e43834daf7b1799ebb7fb4b79345e3f75bcf25fad1b") ); + ( Hex.to_bytes + (`Hex + "a0e4b46e2363df1773b980c2581e9aec17e2ab12ad468d5aa4791f4bcc2e2202"), + Hex.to_bytes + (`Hex + "c3cf7e626bc2c68dacfe578c9234d4ca1e7601f27fc57e4c9fa0ecebc9197a1a") ); + ( Hex.to_bytes + (`Hex + "8f3ef4de3ad3ddfb0ae30f0b5d1c50d61befc8c434fdd56f4e3ab3c8be4f7e33"), + Hex.to_bytes + (`Hex + "b16f987c11539afe9c8912d1eed9fe90148871c1db1935a932f1422e59d8321a") ); + ( Hex.to_bytes + (`Hex + "4cab95d50e571fbdebbc17dc9e06112ee893d202f54e635cc5537b9d9d94e43b"), + Hex.to_bytes + (`Hex + "ac0ec06c6a4587f0ebedb77324678eb6999a918352e54895d6b5ae041f0f0701") ); + ( Hex.to_bytes + (`Hex + "176e6232ea9a3a4969e9b274154c8e7b98caf2b5b6615380a379921701c5d739"), + Hex.to_bytes + (`Hex + "e9f2dc43195cd3536032bf474f6013ba6a59464de7b82483eb45d8b7db9b8218") ); + ( Hex.to_bytes + (`Hex + "e8e983f1510a270d038f6630f9a776d2e9885d9eb5978dd4e144a14590ee8a0e"), + Hex.to_bytes + (`Hex + "40bba03f9f4a182864af5004d0ac0f719f6e7419df4b0f90d4761521a32da427") ); + ( Hex.to_bytes + (`Hex + "8d66dc3740cf89b628c42d14010a7793fd0878c8c4ea3431ed6865806190fc3a"), + Hex.to_bytes + (`Hex + "b657ad3f3d7dc760b359aa34bc9ef45984730a0c09d0639dce6186bc58c35925") ); + ( Hex.to_bytes + (`Hex + "b4795c149256095cb4b0bd495fbb8bdad79dbf9d942c35417881749e79dc5304"), + Hex.to_bytes + (`Hex + "3995c707059f01da326def2ad54539e6e2394349c64e194144fd81be55efa22e") ); + ( Hex.to_bytes + (`Hex + "92f8be04a94f9ff4fb3f00378b97dc62a644634225e60267fc7e8edc2ce13b3b"), + Hex.to_bytes + (`Hex + "9010e4937fe6bd101e99b0ec1ea1cc8c00e48aebf072dd50ad8a87a756db3c3f") ); + ( Hex.to_bytes + (`Hex + "30b4f455a6530aff6b8e1c84a241be0fda24345549624ae4f3e4d9cf83d1163d"), + Hex.to_bytes + (`Hex + "0d01124a477a73f10c01e35a202a8633b26ec97c8cac75947e78e392baed5e2d") ); + ( Hex.to_bytes + (`Hex + "c88bb63accbd32eca86b05828dc6f15e0a230f76b1c6792a02ac424807c06902"), + Hex.to_bytes + (`Hex + "d70df7ac736aa5de2cd305d6fd24aeef8f8a725a790144760dcf3bee3559bf29") ); + ( Hex.to_bytes + (`Hex + "e05728d9a4fcecaf2a468d2d254aefa2088c1f7bd21c9c3f4ee786ae65e8063f"), + Hex.to_bytes + (`Hex + "ce5c2a54c660ca2b451ff9ddcaa01720cfb903f14f6ae19e2add8045ec5b9537") ); + ( Hex.to_bytes + (`Hex + "c6edcfc1b4e4918613fd20818c46f6b489dc26b81775b1050c71ef3c6835610c"), + Hex.to_bytes + (`Hex + "591ce26b5f0219b1da341accd4c80ee6ff347abdf8a8ba61bad333a4982a271c") ); + ( Hex.to_bytes + (`Hex + "c4539b226e8f75c74f83d41fe3148781f4b19252141c729ba06985fd5e63d02a"), + Hex.to_bytes + (`Hex + "3ed819a1e7b69a35f01e641f63fc8f59fd2092772b4b4e447992c9e75852df03") ); + ( Hex.to_bytes + (`Hex + "2e5e30be6152349174287aa31da1d4e6ece744b31f281cbab588da58d7d90d16"), + Hex.to_bytes + (`Hex + "6a56febb8f8fdeda5ff3235426650020a522a671f201190f2023cbfe3a50a032") ); + ( Hex.to_bytes + (`Hex + "ba551712975983061b2e3087d0c9572a76d0dc3f7bc5078fb51311ecafb24908"), + Hex.to_bytes + (`Hex + "2d88279c6153d613935d0fa68a02d984f262fa337b43eef11d97db3fe40d6f0c") ); + ( Hex.to_bytes + (`Hex + "67ef93970444236e413c924ce590d57cfe451116d10edc27b1c9b4cff44ee01c"), + Hex.to_bytes + (`Hex + "67d3cfdd8f9f5bfdc2c97993bdc65d6ab8637b52ce9e97c2722a0f583d873d32") ); + ( Hex.to_bytes + (`Hex + "897a1dc3c782f944b5608d1759e84698ac70d68597510aa5b756389111877707"), + Hex.to_bytes + (`Hex + "4c0540709350a18f94b3a884e48dafe01d268f467ffad96e8a04702f4c8fe026") ); + ( Hex.to_bytes + (`Hex + "159b41bf6a361016cf4904f5a53395549474b934867403ff236a09e583decd2c"), + Hex.to_bytes + (`Hex + "b2d7fe1f25c72497a7bbb7b3d1a24a01b903bd01abd628edfd37c83c559ad804") ); + ( Hex.to_bytes + (`Hex + "3dcecba8c72d5350936c79891a6832939f95aae755f31c1b8bec979861c4040b"), + Hex.to_bytes + (`Hex + "0360c2ea1598c091058f528b5ac944dfc596a232b9539dfb81944d51c0a7f705") ); + ( Hex.to_bytes + (`Hex + "aac36af3bd2ee8e9c684e3ddba3a3cd6d257d5bb944765a0b46bebb8e374f12a"), + Hex.to_bytes + (`Hex + "1cbc1cb628ecb7c1a5ad443bd91fdfa6e140b754bd1fb441aed60062b5b7b607") ); + ( Hex.to_bytes + (`Hex + "257c0cc6b11409f8bb0bd2d97a9d6ec990605a06b614f19b1c63993975c0f307"), + Hex.to_bytes + (`Hex + "71fefb4170a9846ded6a3248ccf867730d9898b99ab0a49f9b9d8140f451b510") ); + ( Hex.to_bytes + (`Hex + "eb0688841f21b2133fa9bd68e5a86187dbbec7b2b01879fee666fae72894b80e"), + Hex.to_bytes + (`Hex + "0f02dd74d15caea4d5ebbcd78374360a9fb489a579e4ee02023d03f73f441f38") ); + ( Hex.to_bytes + (`Hex + "6cabea659972e9bf3e2296d143c6d791e20eba2fe01ec4c11192d5ee82a59103"), + Hex.to_bytes + (`Hex + "0a87be5f50acf5f6b710a9a34fce3245fced6f07dc95042e8ec770b099686625") ); + ( Hex.to_bytes + (`Hex + "99463af7f831d35984ec3e6b33a19eb8da958fe69285bb67fcfaed036e431709"), + Hex.to_bytes + (`Hex + "7e6f68773fc12827ebf82af4e8d615262657fb1f77dfc55c97b42d919feba000") ); + ( Hex.to_bytes + (`Hex + "de61c15ff712a5455455963c44e3c60fd0eb5521c537ea4f91e89f59accfc207"), + Hex.to_bytes + (`Hex + "bb020c3c5d932ad39c5e2b43681e636293b33d1fd2be2c07164bdc8349e7ed28") ); + ( Hex.to_bytes + (`Hex + "eebaa88d3948de06e0f49302a720cc6854767724e2a93fdeb5be6a1754fad63f"), + Hex.to_bytes + (`Hex + "9997a7e59ff553536dd43bf8051d8217c35f5ea08d076d42e7d6437406e88e27") ); + ( Hex.to_bytes + (`Hex + "633f2983cb0162c0a85cc3e603bb1226b2b25f48c9e8f46c9ed87035992ef71d"), + Hex.to_bytes + (`Hex + "a7706d1bc2d3a478692fc1b02fc8d814e34a8849aa2d78f64ffd12dff4eed235") ); + ( Hex.to_bytes + (`Hex + "ed19b023ccfdaeb4999989c1b7a189ac2d0a7a4f65815b3c3f1d6517697db30a"), + Hex.to_bytes + (`Hex + "107b3dd049f530a1c7b876afa5fb3efe684d15d592b29c473757d17c27b1ed08") ); + ( Hex.to_bytes + (`Hex + "669ed14a81355072c109a294016aad9f131a38013f3f98ea5b881f787ce9b317"), + Hex.to_bytes + (`Hex + "dfb65d52ed121a87d7a30959b09dc2adcedacc7073df07980418e816e8cbcc31") ); + ( Hex.to_bytes + (`Hex + "1a301685a3c7b642ec3faa584d548564012a250ca45c05e18568e8adc5aced3c"), + Hex.to_bytes + (`Hex + "0cc263e5ccede54dea36366ab7537908a3a3cae69ccfda1eb1b3984115b4823f") ); + ( Hex.to_bytes + (`Hex + "5876f5150361812782a51da579b7c0fcd7e1f292f3bfdf9901ae4da81e2f091e"), + Hex.to_bytes + (`Hex + "8020a28ec52b6f1e755f99035db1d98eaf200e91a9eb7a72b1cb5a9255dcc638") ); + ( Hex.to_bytes + (`Hex + "472722db05bcfc912c0c6b33c136bc256352fedc49c9f44d5abe90ec5b78ec2e"), + Hex.to_bytes + (`Hex + "655bb1c193fc7e4d6b98dc0fccfaef2d4da7a3caef985012c1418359fe772406") ); + ( Hex.to_bytes + (`Hex + "eae3d555667e3db687cc6561cbb416fb9016e26a4d6cd2369d44f8816cc76a16"), + Hex.to_bytes + (`Hex + "2b5c88936839e282306adf85989d871b04cead696d150754fafacce52dbd0609") ); + ( Hex.to_bytes + (`Hex + "2378969741cc7c7397ec6f1fe0280710242d9ebad3089bfc65c94029e5aaf506"), + Hex.to_bytes + (`Hex + "be438528cd62f1286538adfc0d689e3fce13b376210361862f37b9abcdd4bd14") ); + ( Hex.to_bytes + (`Hex + "df4e4ee7d7b3256c3904ad2e65aefb67518a0bbf370882c1847df34d19cec93b"), + Hex.to_bytes + (`Hex + "b840de98742e056ac77f6d4c73a078ca62ec697426a10a5aedc70f851c85172f") ); + ( Hex.to_bytes + (`Hex + "0dfc91fd3ac017333ca9a8fecf9e0d386eb89f3abce1cd7ee3afa4987b3f7017"), + Hex.to_bytes + (`Hex + "c7f2a0c920504bc58cc9efadc3056bc6107d478eaea78df3f5ef1b9c9a0c8437") ); + ( Hex.to_bytes + (`Hex + "1e8239a7fe7e93506e10a1faa26cf87ff12c9d7e4b972a2510b02bd69cd1691b"), + Hex.to_bytes + (`Hex + "4e84a2127f5a6fc11457ad8ebbd053ae674f6666f50ac7a3761251938ab9cb3e") ); + ( Hex.to_bytes + (`Hex + "e9f048e85348c5bd8524771ebe67281b949ecada5415f5e070b6c48913da8611"), + Hex.to_bytes + (`Hex + "002b76c7053d51162b875fb9a4e3b2203213fc1539eb7cbf6a4990accc5a2304") ); + ( Hex.to_bytes + (`Hex + "9f2556d85d7eb001c1b055a18f20437f738b932115e82889ac7e38a514978d17"), + Hex.to_bytes + (`Hex + "bb46204c8a65b4fc7fc735a282e4c76bff88b73fb0f7e8444237046e7277e73c") ); + ( Hex.to_bytes + (`Hex + "da913ed4a0eaee55275fca7824600ec951e0b6cb40ec2a6c7cbe484a5c36ff0b"), + Hex.to_bytes + (`Hex + "c98dead804ef5a144d41c8e5489b562d73fe8f063a941c787bb97a96389f6133") ); + ( Hex.to_bytes + (`Hex + "d42b9679a571beac2be7b99c6b76083a65b03d532cd88815e6c36777d1c1d630"), + Hex.to_bytes + (`Hex + "176ee4efac0d525d3f7dab6e1f657ad8dbb64e321f59756ae4d87477989a5d1a") ); + ( Hex.to_bytes + (`Hex + "6bff01aee97225022b2136efd21a5aceadb33dda420fc1140e0fa9165e626722"), + Hex.to_bytes + (`Hex + "ec71d6d6d35df47baccc9811020abb01fa48fa24ca34d015e2c076dd5b8ca819") ); + ( Hex.to_bytes + (`Hex + "2d1efa34c17cd9fd3481cf9c75b71437776b82d9e37a6bb7a291bde131f6cb1e"), + Hex.to_bytes + (`Hex + "de4ed1eace0011b63c63f79b5cdc649fe6c26ef0264d5e31266f88505a534a02") ); + ( Hex.to_bytes + (`Hex + "4123b6741e4f759ca12ca3cff2db29c27896b9e106a0128005228e9ff47d9a28"), + Hex.to_bytes + (`Hex + "4c85cc14b78692a239b2b8ba805ac063df1693335ba9bc77066ec467e878a10a") ); + ( Hex.to_bytes + (`Hex + "fcb0ebab05e3836924c6e4cd11864740edb77f55fedbeecdd118028e141ce804"), + Hex.to_bytes + (`Hex + "2906a821338d56e553aebbf2e966f897bb2b02504eb6a5ce1af5eaace052341a") ); + ( Hex.to_bytes + (`Hex + "522cc78c17d705341b1e9a3904a5a72844c8e9f739e270f188dc69bb9563d31c"), + Hex.to_bytes + (`Hex + "2d8ee604510b5b676321ed1dcc6e7f187970e3851e42531a51772b75c7e38a15") ); + ( Hex.to_bytes + (`Hex + "d7cfa9123e8800555347bd120204d89cd5da2bf65489751fd0d2fec29cfabb0b"), + Hex.to_bytes + (`Hex + "8da2244809d9e619513e8398c0c4d68c596fccbe4f1946b6e51334d7ece22034") ); + ( Hex.to_bytes + (`Hex + "9ef61016e3e5a980208e5610924a9cdd56435cc8b6ae6cf80d704b5eccdfad31"), + Hex.to_bytes + (`Hex + "04dfe17914d9abe9dc74f636f323f0b7b68b137f7133d2a96f9734cb1726151f") ); + ( Hex.to_bytes + (`Hex + "785022fba3000d965f3f610e56718899eba3a6cc97afbab2fdb504c7e7197f2e"), + Hex.to_bytes + (`Hex + "09b2d90d9f46bb5726bd4ac88681409c60974524b730135450b84fee7737a73e") ); + ( Hex.to_bytes + (`Hex + "530088be2d5e41627a5f95055b815de67454e043ede75b6bff203d013ceff929"), + Hex.to_bytes + (`Hex + "1a71f0cf74e05c64dc30e60a5e6e089bdf68f27fe65e6517a962eae60f193028") ); + ( Hex.to_bytes + (`Hex + "8142619c8b56a6f9ced546d57bf3f34b147b74341077fc47eff96af7a42a463a"), + Hex.to_bytes + (`Hex + "794cefaed7190d481d93fbae75e160abb4a51fc7d085554d3595d597628e960a") ); + ( Hex.to_bytes + (`Hex + "f99dac243f9036e4a617a81df0dd00932a93bcb439683e127fd7fd3588841827"), + Hex.to_bytes + (`Hex + "bc46099bbd7ae452a5e4eb0fce3e85c05d997e34c835f8f324a2c02c13e9de19") ); + ( Hex.to_bytes + (`Hex + "58a7e6b4a98353a447e4c123b500159036572686c8c05ee85af8c840e6a86114"), + Hex.to_bytes + (`Hex + "c8b272fdea081d5003f46d4f79ec63eb190d531c50f2e3f1d8193d6959d72e06") ); + ( Hex.to_bytes + (`Hex + "75fc49b28da3c4a29085c7772107e48aa59e5b8d044bdc037d3103e8380d890d"), + Hex.to_bytes + (`Hex + "a7ad589360ee103e0ed76208eb4809351c8c5a18df80aa7577a827d080c3e737") ); + ( Hex.to_bytes + (`Hex + "cf069af065a5fdaaeb0068b6c0f0e991eb5d9a9a614a89baa5672aa72f6cab35"), + Hex.to_bytes + (`Hex + "6fa2c1bb305834dd4797c36f0c14d2c32cf6a3a4aa4a80655f9e041b2bda8a2c") ); + ( Hex.to_bytes + (`Hex + "0f63ad986a241e642c2eb319de91ab7261b669214b77925ccd61ce7043c51a1e"), + Hex.to_bytes + (`Hex + "48845b28f53fb29c276731f32ba4b49b20476ec813a5dd6285aed04ff0a03821") ); + ( Hex.to_bytes + (`Hex + "c0c2c831308aff05af137db38a4e0c32620ae07d9261e15f01df99c8ec6e3932"), + Hex.to_bytes + (`Hex + "0bdb4c25a75a6af80140507c4363f8ff3428c41331ce7e90044ff6fe20918300") ); + ( Hex.to_bytes + (`Hex + "05710be81556a30d68eaf583c7350dcd84c714fd178f5619805b218e9d164438"), + Hex.to_bytes + (`Hex + "51ed9b1cf46fcc1f6becd75d8194e5345d7cad7c16d3a00b8e638a393cc8c03e") ); + ( Hex.to_bytes + (`Hex + "239ea8ca2adde330aa3421a9c72456ca0a0c62be5d4c9a56e10764f035f4b50b"), + Hex.to_bytes + (`Hex + "3bf5225e97e1e8dffbb13771c5befa8d1aae85b6989fe101c1c228059014c128") ); + ( Hex.to_bytes + (`Hex + "f8e4d80acef7cc3d3b769e192e318e588d5525032fa56a8cf3f472c669bac429"), + Hex.to_bytes + (`Hex + "d752717118f2ec194eba38fa557aee0695fd3c6cf2a4f0d80c7fbb4daf61f73e") ); + ( Hex.to_bytes + (`Hex + "755fbb04adba0f1ff0e2f456b602ef4aa48ea0b8ff9b894c8d70c7a12c7e4e3f"), + Hex.to_bytes + (`Hex + "bf9b9c1c107af602d68aa28bdb0cf305e2a860159ac43ac118593594dbbe3415") ); + ( Hex.to_bytes + (`Hex + "23be10b8ff6d87fa412075e0e10cc772ef3c1f5138bfc8075be21bed3e5f6c1a"), + Hex.to_bytes + (`Hex + "b065fa85aec0dd51473fc34cca4d5b8307681a22bd02d61b9fae908a1a3dc232") ); + ( Hex.to_bytes + (`Hex + "0d9614a12c53ed0e0d034597072d8369928797c50e8cb80cbc8fbdbaf346d43e"), + Hex.to_bytes + (`Hex + "bb6ee77c6295a72f0b5e867c1950217e0926160b86690e6dbd9dd20303a8ed17") ); + ( Hex.to_bytes + (`Hex + "6e4f75287ff0dd5a696e38ce1910d2de464546d10e5d11ba7bd5f76bf5adb81c"), + Hex.to_bytes + (`Hex + "9f5c6730e743b3740c2538c06c1abeaa68eb5c7c0258f98ef3cb34b60823f726") ); + ( Hex.to_bytes + (`Hex + "a3092a2ed09c97e6b60841b1b41ab4bf6157b02c81dd0d2982e5108d2d646c2a"), + Hex.to_bytes + (`Hex + "a4843ee12a8a3685d2869e49b26cce9e11684e1f0403d1a60bc04f2986354917") ); + ( Hex.to_bytes + (`Hex + "ecc988b233f900d06cf8fcb127fa0800f60ade5e36dcb877263feb592dea9d28"), + Hex.to_bytes + (`Hex + "fc4d6e2bad9ae96e8d5cb563fbf957a310d7a898c4039db9194fc39d80b9fd2c") ); + ( Hex.to_bytes + (`Hex + "df5cbdfa4bf23f4ae8203336b35b1574b6a3a699d9ad05f6583fa53df1396503"), + Hex.to_bytes + (`Hex + "08c4590410e9a54a9930fcdbe4d4dfe4ae8be1471e6de4ec520faf3af8fb7125") ); + ( Hex.to_bytes + (`Hex + "f056a66f5a758bc0a6195835d2cb17ac9fd5de76a9631d0e71cd8f06ccba0d0f"), + Hex.to_bytes + (`Hex + "36c266d31788b69ad75f883f7642da7aec44e39f4fde3d08094df7ca93e1de33") ); + ( Hex.to_bytes + (`Hex + "6eb48728fd8b9535284ebef10191385fd508ed99baacd1f93e3773fa66a6ae34"), + Hex.to_bytes + (`Hex + "c26c69b26d385085c09e04856ff2e0ac54543d9d6dd41e8eeeae445bd8827809") ); + ( Hex.to_bytes + (`Hex + "60a73554a0193713d0face0fb73a59eb3a850dbfa8896b066e01f71b20df051a"), + Hex.to_bytes + (`Hex + "c66a887e8a56f0690d88b8cc1afbd190f403870f9bcbf381cf6e36a98903e528") ); + ( Hex.to_bytes + (`Hex + "15d7dd64293fbb5006773fdca6f9aad53d3c9cc433146d6e404406b0900e871a"), + Hex.to_bytes + (`Hex + "672afe9f0d8f4a8fb2e83d8b37fff73d4a22e5b250ac00e2d6195f6275bea82e") ); + ( Hex.to_bytes + (`Hex + "a684df79aef35293d27c1eb96ac721d89b36e5af7d8b161501285fedb3d1b239"), + Hex.to_bytes + (`Hex + "edcdc04ad3c8c1e3b212b87fbb486724cae9239af6468df17357bd3cbf73b112") ); + ( Hex.to_bytes + (`Hex + "4dc76a4707cb920da29ee5912ab87991e0f592d6b33afcd5503ac300d0efee3d"), + Hex.to_bytes + (`Hex + "cd4332fa447037ce83a175a9ca04ea2371b862ec2eb0a33af08e58c51121a904") ); + ( Hex.to_bytes + (`Hex + "5f66a57d02a197dc1858fdce5d5bbba17135cd62761a4e7b702d76529bd9a33a"), + Hex.to_bytes + (`Hex + "5977c3fe3679bd943c5a2e23554b167271b2bd52a2e26b753b6f56d674bbf233") ); + ( Hex.to_bytes + (`Hex + "b9d9dcd65672fdc85e7f657fd8c903cadb46f62bfa4339fd91a599634f59c122"), + Hex.to_bytes + (`Hex + "6c06be58891bd3a351d771434cdf7637877a0000cd1d4f6b19e233a4e9836d3a") ); + ( Hex.to_bytes + (`Hex + "a18c9d74ca92ac2bc16483d96ab7ffcd66e24b07439e714a313df14a9f191d21"), + Hex.to_bytes + (`Hex + "723f8a7d75f35c61cfe0252b4e0a71e20f18e1a9f8627ee063468fd269516836") ); + ( Hex.to_bytes + (`Hex + "117225a02bb926508b55032a9abe610fce5758c5ce4fb56ed76b0e38a0209331"), + Hex.to_bytes + (`Hex + "a8f64a55431de56f72f9c9b9c048f06f7704a307ca7bf3b6a16e97f30c08b401") ); + ( Hex.to_bytes + (`Hex + "83bfc521b214850ce3f186f7f8f7656a46f05b862c3a453c07e7c1fb3f8ce218"), + Hex.to_bytes + (`Hex + "bd60e019907e11b379f2d58529b02c68803cf3ac3918072d2a25e4095abefb24") ); + ( Hex.to_bytes + (`Hex + "dd1330fd4913383fc4acf9642c3fa3505248aeea9ac2fcbd1f4d7e73f1e7cd08"), + Hex.to_bytes + (`Hex + "f9cf2e0df195ebc9b87cfae81e09162edf87b1b245d53823a5394a93cd019c2f") ); + ( Hex.to_bytes + (`Hex + "32dd98fa86244f2f02ab2994b950b35a09fbf967085b004d4cfb4462281b7937"), + Hex.to_bytes + (`Hex + "ed1970ad411b7af3f3ef04049162583d31710b69649d1037010a8a642bfe3d32") ); + ( Hex.to_bytes + (`Hex + "ac904c42631b992cb119019248e1e0cddd234ea9cdcd0a6b5ba2675485ec830a"), + Hex.to_bytes + (`Hex + "f55f29e056b4aee29e0fd4957e15f2bb232186528583f3fc60182163b8c6d409") ); + ( Hex.to_bytes + (`Hex + "6add8ab69b26985a2ab2394641b9fe1e2b62ae46041c713504c4e2614e0c2407"), + Hex.to_bytes + (`Hex + "79bfe0b9c532f24e7946b9826d2c4928ce5a95d562c1c96d4b7e46cbc946a123") ); + ( Hex.to_bytes + (`Hex + "4457881667e4a60e510f063ca9c73ad7f00f1109ef3e461bb0152b8b1b1af525"), + Hex.to_bytes + (`Hex + "f0cf47d8d724940e224dd3c8261cca9e8a3571a0f4447c3ecc2a859e553ee002") ); + ( Hex.to_bytes + (`Hex + "8c54724f63e9f6fa1830cb067866ba75d01ea6f6c14d5cdd117d9c964aaa8a35"), + Hex.to_bytes + (`Hex + "f726410b8cb8927172d67351aa5fbfdc6b38c5d77b3f44288288540d2d622603") ); + ( Hex.to_bytes + (`Hex + "8df0491620861df3db1c2ec6c950c21f8b302ac17f7da23fd6402b3f98767a08"), + Hex.to_bytes + (`Hex + "1fcf1af1f855fe1def349599fdc933ee1823aa686a7706c3ac64f037fb5ac32a") ); + ( Hex.to_bytes + (`Hex + "9734e3e5e8cfde3aedcb4a370f93416cd88aa8c764f8b0125825f497b0df0f37"), + Hex.to_bytes + (`Hex + "99cfb51ae4b120723c629c77de923216e7864a4b220034b05b92f26ea2af9b30") ); + ( Hex.to_bytes + (`Hex + "2751c0f912500634754b009919f428c8f3e380f41da1d7f607f242fc462d332d"), + Hex.to_bytes + (`Hex + "e36e689e5062462e255e9edf7cdefdabd575024b950e57fd139aea2802ef7724") ); + ( Hex.to_bytes + (`Hex + "be58ca762fe23ebc0bc59bd5d877a83e46d78b77659b8ba8631582a68176c63a"), + Hex.to_bytes + (`Hex + "0ca6a275a1262d010e529e5b751693d204080af9b281b37b897ade700dbba133") ); + ( Hex.to_bytes + (`Hex + "90ee4484cac9cab0611d27ffad198e966bf65a83093e263f640c1cdaf771bd05"), + Hex.to_bytes + (`Hex + "8225856fcedee961f5c9f55dee17d1e547815dbc5f5bd6a34e753c1b9c82583b") ); + ( Hex.to_bytes + (`Hex + "80ef9cb51691e839999a8d86153feee84484d5a5dd6a324b669ff79f0294fe14"), + Hex.to_bytes + (`Hex + "cbb512002040668f13fa371579c9cc6f82826a38cc3e9ed1dd745c6d85c72c16") ); + ( Hex.to_bytes + (`Hex + "af88fe078e2ec0dc34f8aeff172a3bbdd5780b6498326f0c56cf10e083a6a434"), + Hex.to_bytes + (`Hex + "33ea7372eeabf363a5920b042e703705c93bd68dc36e7d5445158a75125b6400") ); + ( Hex.to_bytes + (`Hex + "75510fb3917e8eee4f2ab1988b321891f52e19ce437d6b0cc27707f745658326"), + Hex.to_bytes + (`Hex + "29f8d58f0b7898d7a4eb78025ea068c4c17a64003cf1fab776d1a43bee6a2a32") ); + ( Hex.to_bytes + (`Hex + "dd138961d64d3b1e948f95daddf28b242618e19726481682ecdce7a59893ac21"), + Hex.to_bytes + (`Hex + "f43f4c5b758d2d77e3bcdffff9d077761f408ea208b8a3106ec849b3465b6e3f") ); + ( Hex.to_bytes + (`Hex + "7c36bef187d8855559b63aa55acc07af4617a835e1923e9283f14df28c26f23b"), + Hex.to_bytes + (`Hex + "4da7785e7304e66f478446b79190a139ebcbedb75ec494a5c3ecca4cda13c90b") ); + ( Hex.to_bytes + (`Hex + "034937c52c2cd41d61ae39d4e77dcda6074b7a3b7f89db15d73d51cef8815c38"), + Hex.to_bytes + (`Hex + "c98d9e191c0bd80eed391d5b2267e2792f070b6c4179048b34d9255337a60715") ); + ( Hex.to_bytes + (`Hex + "3546ad84eb8631af3603d3cc316379a71f677cc6e26c28f10a7cb25c69b4c100"), + Hex.to_bytes + (`Hex + "daa3ae1c0ebe4f7c18be4802ad1b7bc1616c0fc503f9ddbde703a9ea5e843f2f") ); + ( Hex.to_bytes + (`Hex + "7f144b2610663873057018e0e6ea8ae7fcb8926e4d4f9e90283fb498c433ec20"), + Hex.to_bytes + (`Hex + "ea3e0755a1eaa8290f1b312a7c229d721b65ee6d999c54b1f517248ac32a6030") ); + ( Hex.to_bytes + (`Hex + "e7d138fc320fa13f122e0cd06c71301107cf9cbbeee77b8bc8b4257c4e0ddc03"), + Hex.to_bytes + (`Hex + "4e49f01c2f2d37cccba73f69711981f289d712012357c8715ad368de62403a0b") ); + ( Hex.to_bytes + (`Hex + "f53ce68f5d96572e2fb4cf9675037d1e21f271e0faacebe46bb9a925aa30c818"), + Hex.to_bytes + (`Hex + "a5db45b155c9351e558c664c39a2bf38e544e10ac0b6792b18de1a2af2700633") ); + ( Hex.to_bytes + (`Hex + "2c5289807dc13703931e09e5f9b7f38c8228f95b9500c2308f307434946e0318"), + Hex.to_bytes + (`Hex + "bbf3ab1460e9ac8348a25867894ce9397822bbbaaf4e823bbeab0e778adcfc05") ); + ( Hex.to_bytes + (`Hex + "ec11dca69faf154d56b783faf7b48896122c56c5929500a9a9763ec2b2f93131"), + Hex.to_bytes + (`Hex + "d1178d410bbc77635e20a8a12fc6c7bde12775dc8ce508b8a00aea426a9ae33c") ); + ( Hex.to_bytes + (`Hex + "e0aa951b61369c91291f7085f5adc021957e430a24a8d81550e25b977f0e8724"), + Hex.to_bytes + (`Hex + "8f4f25d342f98a2b03280e9d93f2bfb81136e5fd0114362be06f251e3d975f09") ); + ( Hex.to_bytes + (`Hex + "f7afd7af69cab5255f9667b61b763157f6d578e00080dbf06c486f9a51d65f10"), + Hex.to_bytes + (`Hex + "253adf4e187cedf6c1264cb5fcd216f70ac7f8de72300383a8d8f9c6cc43723c") ); + ( Hex.to_bytes + (`Hex + "1329afa140f59ad29af000ed7517f886b6fc96798d7278c9cf2b525ccfc4aa15"), + Hex.to_bytes + (`Hex + "a265f65b658badcc0a8a3dfe29447e19eff7c8cb825a26bc7acc330ce97b6309") ); + ( Hex.to_bytes + (`Hex + "63f1a59cce37dc75670d01f81c4fe43c70ae04d36f913319d03ea73d8228c909"), + Hex.to_bytes + (`Hex + "298d35eb5b781a1436cab86b2175a110268264997ed751cd6cb53825b115961d") ); + ( Hex.to_bytes + (`Hex + "d354576fbdc1717c6cb1df953d53a0c9c686eb48601145c92e0d448cf3f8a805"), + Hex.to_bytes + (`Hex + "60f488cf9559d811423fbbf78a7feb445beaee7943bb8cbe862f50ed8fb9dc02") ); + ( Hex.to_bytes + (`Hex + "15a95d4dbeaea24aec6233b9b26c25340766446a1ead29d2f8cb5fe6b2e2fd35"), + Hex.to_bytes + (`Hex + "c07c0ae1cce5369a9e8e4264bfad417dc3dd7de7b0aa4ac686b017dd44ceb628") ); + ( Hex.to_bytes + (`Hex + "09de57c73ef02917d6ddae3c98d51487be5cf8761b98bc46b634d4985d7a7c1b"), + Hex.to_bytes + (`Hex + "fcfa970f818861fb007d444753129e7666ac376be59466e1d640a4aa2c590d0e") ); + ( Hex.to_bytes + (`Hex + "744e9a7b1c6977b48a9973b2a0ea611c388769a8042b9592cb314df9c7d1ae18"), + Hex.to_bytes + (`Hex + "a03aa09102a1b463e8e200cd596a5684ea99fbf4768facd96c00191f3cc39a24") ); + ( Hex.to_bytes + (`Hex + "29c1d99dc5c511a69a3b0c461e4349b40764ac50de28ca8a47efa7a7a6f2e12b"), + Hex.to_bytes + (`Hex + "521fca87c9464ca16293f9a4bbf4fd40475df0ffe28cf2992362fd2072e63923") ); + ( Hex.to_bytes + (`Hex + "df1953d5ee397eb09e7b63cdb6a22e2e854d76585c1c30b2116e3f8576880131"), + Hex.to_bytes + (`Hex + "40f788fdbb011c6df9f00e8178ec45ac537cd95ee789789164a8fb1272e7022e") ); + ( Hex.to_bytes + (`Hex + "d8fb04a995ce2b484edfd4d9ef459f09a5326c035616706edf12d547d7cf380a"), + Hex.to_bytes + (`Hex + "794876ac01110e571ae45e2014ffd6997dca6483e14ccbc0ab8827210f3a213f") ); + ( Hex.to_bytes + (`Hex + "89318e9905d791d42a143c66dcbabe7bbf18cb639098711d7be5cc2bc5a1f824"), + Hex.to_bytes + (`Hex + "526f46b9ab3f521017761b6b50612146bb15665f33b12be2e3d44cc32ebef700") ); + ( Hex.to_bytes + (`Hex + "a9111819c0ba7c9bcd1327bf331c4ae17107d54e6f67349cdfcbc7e4f9b8c33b"), + Hex.to_bytes + (`Hex + "be2b193aa5e7c3c05b60a8d8c0be9796b0488dd08bdc32f847db367a647dd30a") ); + ( Hex.to_bytes + (`Hex + "a07769d5cadc491a61e4482b407469274a42c1f6b2b735769fb889a2f410e62b"), + Hex.to_bytes + (`Hex + "04fcf33e67c1613eedf047ce8b264f7036d8ded25f3f4514d81dcd4e34d8c92c") ); + ( Hex.to_bytes + (`Hex + "43e2437ca7a2be116a1e49bb581accae3e4f4b846c3b18ad018c781ea829f23a"), + Hex.to_bytes + (`Hex + "dd4657381188c9e55b064b3fa637a2186e504f8aa377eb959f9e81bbb4e7190f") ); + ( Hex.to_bytes + (`Hex + "c9cc0d12958689420d508fb2b576477c430e5762f6a087736f720304751a0a3e"), + Hex.to_bytes + (`Hex + "d0e2a5f57f61b8a48fbec08d177501bfceaa63570f8a123ef2c51b1bb6051910") ); + ( Hex.to_bytes + (`Hex + "b0697ac336631c6a38c99c4cf5b801abf10f5888c277704b1393572662949d21"), + Hex.to_bytes + (`Hex + "b4b81d4854eccaf019f8ed8c6e70aa9c27d92d34f84c2e891995a8c280191c24") ); + ( Hex.to_bytes + (`Hex + "c34c36eb3e585722885028d57e3e2927cd6ff9605714ca7eb69b40d5fd416d36"), + Hex.to_bytes + (`Hex + "f919821e5929fe8b16e2ecef2217cfbbfea5ee0343fd6095a8fa6f05f4cca201") ); + ( Hex.to_bytes + (`Hex + "4ca918520badb5f454936ddd9090243a7cc587de690fdc983e40f15f7c35da3d"), + Hex.to_bytes + (`Hex + "3ab15dc89b451951407fb0900c72fc2b81d58bf81d0f378598a20ec06e22db37") ); + ( Hex.to_bytes + (`Hex + "d277a139a923b363cc013d7148972fe6bf59a1a0509008251d85b8e9787c7c3d"), + Hex.to_bytes + (`Hex + "ce6fb2b4cb548439b9d41fb1b1f16ec097a2d7e71c78564453f4b8f19481cd04") ); + ( Hex.to_bytes + (`Hex + "f47a17b6cb834818d5c3fea46c54572d0adc3292a8e34d9876f513b37a7de50f"), + Hex.to_bytes + (`Hex + "b72d0e70b14a5f6727710d3add6b44b0808074c1a3c6668dfb92520589ae9e33") ); + ( Hex.to_bytes + (`Hex + "ceb69754e746c62801d108093a75faa3dc2a5d06f5d0091f73156e21ddd18a17"), + Hex.to_bytes + (`Hex + "571e41b006a30e03a9bd28dfec032a761cb5c9ec5af3c1a231e13f8014717f03") ); + ( Hex.to_bytes + (`Hex + "66835394bbb5ea592430f0c2f807d15ff285a0770a9e1f494633d65aba5b4819"), + Hex.to_bytes + (`Hex + "40f7f65f70857de0fbeb8ff74b9feba7e28774bad5d8c74e48a4d31a0cbf2f15") ); + ( Hex.to_bytes + (`Hex + "04e38ab8b7a45189e52dd66394f4bafb04b6fb46cff4dc525382a2f0af616738"), + Hex.to_bytes + (`Hex + "55f23d0c33a39ea7fa7bf3ef0618c098d6bcb8367b7c04ceeaed63c3f4a78b3c") ); + ( Hex.to_bytes + (`Hex + "ef0aab7161f63dafb0ccb7fe27df2af44e71e0956a0952f600dc9fbb2e2fd212"), + Hex.to_bytes + (`Hex + "1a7e5c743be1d32b31473b1ced8bd5306c0e6d1560dee94fe1a56c04ca82751e") ); + ( Hex.to_bytes + (`Hex + "4ebe302d3a3b264b4e9c9eefb5e103a34dd3781fc7d30c1a091a932be2cbc60b"), + Hex.to_bytes + (`Hex + "e67850c90a54f85e855e65850bb7905d784ce63617c753ed669179308a468616") ); + ( Hex.to_bytes + (`Hex + "489e31b714dd0d0ddc3f915382bc2e71ba081eb5a4ddcf5f78fe442deb063d2f"), + Hex.to_bytes + (`Hex + "2df3b3a0348669a55095300dd0e6a6c8589f20967482e7890564905b04f1b305") ); + ( Hex.to_bytes + (`Hex + "f15e3fc9ab9f5665f03fb0e545fb778c5d0d61a604446214a98c128c82fd3114"), + Hex.to_bytes + (`Hex + "2a53817ae0fff4e073e5457669e054622a82fd194bfa423652bb910335d18524") ); + ( Hex.to_bytes + (`Hex + "254966b206e3685752f629e7a1fdefd2c0a99c317cd4c621eeb34de5360c0124"), + Hex.to_bytes + (`Hex + "800b1bebfc905149f29104ee15c3c2f0d6b30713089dbc6164a207363eb74a02") ); + ( Hex.to_bytes + (`Hex + "3feff4547e387f106bf5430ada320a290909834e56869f8b0362aeb6450f7f27"), + Hex.to_bytes + (`Hex + "0e4cccf565286b541000bf07d6557082710361febd687e3f35724d0f45eb8716") ); + ( Hex.to_bytes + (`Hex + "48266d31ac4ea678aa507fa621253e75fd461ff1a579786eb76edab1ff18d905"), + Hex.to_bytes + (`Hex + "e93ac99b6358b9ba5557cf04463f7bc3dfd2299f79aee47da3000c06a6e17b04") ); + ( Hex.to_bytes + (`Hex + "b67cdf61c271c8491a0beae96cca80530efeb84103445ad01c3d5f038cd10c08"), + Hex.to_bytes + (`Hex + "4a2494a8b3e17452b27f1ea2af74dcdeb454ee990d5fb1eff6dbb64e62324c16") ); + ( Hex.to_bytes + (`Hex + "776888d553ab0a72aedf7116f85caacee7520554169e4b6dbe063f23fa476c1c"), + Hex.to_bytes + (`Hex + "3faaa4f40a3cf5619a38f0b434235852fef8aa5030dba1c85c476cc434dbdc26") ); + ( Hex.to_bytes + (`Hex + "893e403870290832e34ff1193b59a190e41bd7e671eef3095e534a13258f1f0e"), + Hex.to_bytes + (`Hex + "1276acb1f9b819d5465874900e85f791282bcf08113646884c0de0732ba6ea13") ); + ( Hex.to_bytes + (`Hex + "6fc65a4453a3394fb784bae167a79db5a8af5409049c1737d8b66ad636f2cf2f"), + Hex.to_bytes + (`Hex + "7b596a0d95f21a680a722560ae9c42564d575c768d99448ad26e17107ee6ee12") ); + ( Hex.to_bytes + (`Hex + "eebf04aff16610a3906579fb36ea3725b975e164f625a7b35ed0359e7e938807"), + Hex.to_bytes + (`Hex + "a2a09f8f7edf4eb521a9739b002062e3fbae4fcd468cdbf8dade90b5ee431925") ); + ( Hex.to_bytes + (`Hex + "cb7718de822b8ea859d06ce4d7f5948bda1f54328103a787912ef3f58f72b722"), + Hex.to_bytes + (`Hex + "97f950fa69783d67a351d2f499241997d3b1c7cfa81d211c3799ac77609bcb2b") ); + ( Hex.to_bytes + (`Hex + "b6ae910e358e85a6e8da3e42166aa597540ea028a28dd3f93a57aa12fb889b1e"), + Hex.to_bytes + (`Hex + "22c30c2db763e19bed8c7039d44c506637ab3ec4caffb1d3fe60979f8ab24611") ); + ( Hex.to_bytes + (`Hex + "3489b1a89ed2dada9b5306360f9450127688f16c39b12bde6563289f63cfe811"), + Hex.to_bytes + (`Hex + "a65a02218c5f1550fb1d674588d8a1a1b20f36d2350827497bb896b982555327") ); + ( Hex.to_bytes + (`Hex + "8fcab4e092e4c58c483cc6b0f7298fb21e77a23210ef387ead3237e643c51333"), + Hex.to_bytes + (`Hex + "0c732ceb574d697608fef7b3c09e7405a4f149e45324a7201280604f56c67020") ); + ( Hex.to_bytes + (`Hex + "4c006a23431ac27edb56135d430e75a07d76d9a0de38fef3100162b593f03703"), + Hex.to_bytes + (`Hex + "245d06748471ce62af55d581a5c9bb6beabe1860e64e2dfaa0dce7e754c60b28") ); + ( Hex.to_bytes + (`Hex + "fb44c2b03d91e1b038598e21c4d9a4aac628d65f6b9b463522b2d34307919523"), + Hex.to_bytes + (`Hex + "9ee94c4b9b12aa5cec851353aaec45ef2bfbc2c8cca20f9c0ab818f531819c18") ); + ( Hex.to_bytes + (`Hex + "dda413b06c422c03a0d917335a5e1be1803b0d83fdb99214d4555ccf949df105"), + Hex.to_bytes + (`Hex + "03d03d6704474c2c078dd897af298ec4df53d8913ddd27d10564d8f252c0940d") ); + ( Hex.to_bytes + (`Hex + "0936b9d4c97b810292a5d42d0d6a46fd94c43c05add5bfd7f60606c96d09233e"), + Hex.to_bytes + (`Hex + "bbd048cfada21bcabd5e12e69e2a8848aafacd3300f357a8779f1029b5d80d0c") ); + ( Hex.to_bytes + (`Hex + "1b5716cd762caa63ee9e5df3ee270867288f30ed0c3732f728b2459c0f69e72c"), + Hex.to_bytes + (`Hex + "0022dad2e58f08cf4a5a793ba535756b583deb35c678dd6cd4be94e757da8b08") ); + ( Hex.to_bytes + (`Hex + "fa048235f290924f0f6e7aced59b25bc6a5999fdba7d44e927a6eabb69a35121"), + Hex.to_bytes + (`Hex + "d183994d083f1ec19b617b3a0e882d3afc11f27546dfcea9a879418a40e13b15") ); + ( Hex.to_bytes + (`Hex + "154eaa320bedb4163e1603e02698025dc2fef912a09074a6dee0d413f30db113"), + Hex.to_bytes + (`Hex + "c96fbf0d1458c3fad864ddf3e3db978d8e1973b9c58004f6fe30c7c4a16b440e") ); + ( Hex.to_bytes + (`Hex + "fcb367d6ce02e55331b6352d92f26fbd89b2780c81761e51a6c3ebf268b9d935"), + Hex.to_bytes + (`Hex + "8d3f5917a7f33b4bbf7e769938762048604f4e9603674915f033f043a1813d15") ); + ( Hex.to_bytes + (`Hex + "01ffe53dfc52ba31e2ecd1b9412b6a37a02de8dc3183fc6280a7acf644578f11"), + Hex.to_bytes + (`Hex + "a0f7a71e68dfe6b195f4eb1d63d3ad408bcb5f08bbdabc414722c14220f04f36") ); + ( Hex.to_bytes + (`Hex + "0ed09e0c3816b436dbd1a410dcbfe051abaeb54a35583c918913296a647dab0f"), + Hex.to_bytes + (`Hex + "ab9938c4a5182133a2ff9aec69ef16af00d10bafaa59b2c147737cef07667505") ); + ( Hex.to_bytes + (`Hex + "3498a1fa1808e074fd60ed6b7c2b98fb7446bd2e5a23e3ddb6f4a3fd74525a21"), + Hex.to_bytes + (`Hex + "cecd4dc583976c105454711a467228e1c31d3ac9856bf3d4704bf9d9c5926e0c") ); + ( Hex.to_bytes + (`Hex + "1546c0c026d7651bda7e7b1963e88bbfd1bf5224b1e0d7aa899cd8a55c411135"), + Hex.to_bytes + (`Hex + "636f9649780a33d8d4f66b4b4764e1307c105913507cffca615cf1915eff5209") ); + ( Hex.to_bytes + (`Hex + "74e94aa3de79030d1ad773861f5694ccbffd1bd1e3c01a13d841c76a19c0f825"), + Hex.to_bytes + (`Hex + "4e304d8904344dc1e916b36aa9698316a8ed9ccd70bc3537a54823f53a44b437") ); + ( Hex.to_bytes + (`Hex + "68752e196e1c5699a8449ad787bee765a5cff788691377c41ff96a1fd1d2082e"), + Hex.to_bytes + (`Hex + "ebaf4dcf7868168a6cde05e7d604b3aba715dc8914c859086fb479a075074d27") ); + ( Hex.to_bytes + (`Hex + "13eba84fa8113ddbafd6d39aa87e3aeaae4cf13a35af8199d9dfe87a1ec0382b"), + Hex.to_bytes + (`Hex + "7780063cc0de0d8338ebe25190fa2d42bc760cd10d0df7b8ac88510e675d9f05") ); + ( Hex.to_bytes + (`Hex + "0ee1bde2f89710d9a053288f524c492f3b92abb381d4ce18828418a7dbe3d925"), + Hex.to_bytes + (`Hex + "860995ba0580a7d556256dd76723ffca9410f5d2150e49fd01c12e73a951ec04") ); + ( Hex.to_bytes + (`Hex + "37c2082d55b0759f1f554bb9f6407b8fd4021265651d0aff0e2aad4407355932"), + Hex.to_bytes + (`Hex + "fc8735567b00b0c38b0056154c66fe674ba1907c4ed13339f59ef53766b0dc08") ); + ( Hex.to_bytes + (`Hex + "1e6ff4d79156d6667aed39a0e42574578b09ddc7f5c327fe31a2f1227ab7af1d"), + Hex.to_bytes + (`Hex + "9bac9d9f10e6bfa35c861453f2e638a53561f21319568cd46755c3ebbd667d26") ); + ( Hex.to_bytes + (`Hex + "9afd5a00b755c022c1df4d54b45fe9fbccc6d1434126d548083c7aea2aa7c337"), + Hex.to_bytes + (`Hex + "a4d22febd5afe1779c528c24bf76cfbf4aa4fa9faa07898511983da2adb38a28") ); + ( Hex.to_bytes + (`Hex + "83a29ab02e2f7f8488a0ec5feecb74287286f29a8dfcd93435ff79d54f11013e"), + Hex.to_bytes + (`Hex + "0bc6542237d2045527b7a76bcd148f8f07d580113f9f39754bc2208397567719") ); + ( Hex.to_bytes + (`Hex + "5437efa47d67d821cc71fec4ca790f97f0a2e7933856029272817d5965316c27"), + Hex.to_bytes + (`Hex + "ee4fa1a9d983dbcd2ccedf951e2bfa05847cb6e1ef118cd5e1fde023c6cbc701") ); + ( Hex.to_bytes + (`Hex + "f89b41beb711c45d9e50fd71de610261c1156f4be55fdf938cfc55ef2aa6172b"), + Hex.to_bytes + (`Hex + "43fe2854e727e91348d958533a6e073d9473a00785901d32f9f5853fbc174826") ); + ( Hex.to_bytes + (`Hex + "4a54c9c58c6655dae94af106c242d57d22ee1c3debaf8ab8dcd6a642c225121a"), + Hex.to_bytes + (`Hex + "e7f46170d602d8d8e2e03eede6e3211a6b85e5893892e5cb89bd172eab449003") ); + ( Hex.to_bytes + (`Hex + "0b29b7e3df41e83a706180fddeec3ff1973fe54c4ea239ac22e1d5b2c575ce26"), + Hex.to_bytes + (`Hex + "5d1179dc56f073e4ae0d62ada515e37621973c481e6c13a326d9d586ea836d3e") ); + ( Hex.to_bytes + (`Hex + "f11683d91a742faebd449dcf58582d38be0f2df7ab984e3804386d404bd3f330"), + Hex.to_bytes + (`Hex + "63804722625345c24bbbb4600826173ed62700c5fcda6db8182c295f4148e82f") ); + ( Hex.to_bytes + (`Hex + "fa803c3c28116a7bb4f3f3dfc2b9a29c8037d17e61f20f34ec2b7decace50c3e"), + Hex.to_bytes + (`Hex + "89fb373d2b2e41d7d8feb1c86a8647620c59052839026b6ff4f368922c38ed0c") ); + ( Hex.to_bytes + (`Hex + "abe3e962ecdc17f535670c1beb7e0fefcf37f9707cf2978bfcee3cf8377d8f3b"), + Hex.to_bytes + (`Hex + "e0ca2671e6a89cc808e20579f98a34bbf56fe2156de54a45f4bd822c1f8d451e") ); + ( Hex.to_bytes + (`Hex + "905baaac55d2218ffbe74008a0e529e75deb630b759bc656f782c34cb9c9aa1e"), + Hex.to_bytes + (`Hex + "f4adf0d467d470a3e20b7c19cfc5c15e426d3ff0f451cfc1ff27dc4e4404fb09") ); + ( Hex.to_bytes + (`Hex + "fe315c202f0d2cb19115fb6b1cf7a6eeb20350f79c0aaf67e747371d66bc9803"), + Hex.to_bytes + (`Hex + "86e81ca79bc5cbcfe3f8edabeadcc5137f1337e32bf9cc940e269971f8138406") ); + ( Hex.to_bytes + (`Hex + "2b988d30f7262df837d7645195f763a49327012adb0c3b94d27777d9c743dc36"), + Hex.to_bytes + (`Hex + "d49c00c99c72d0283864b7831e75ce952fd8e41e0c8d757fb22303875c978404") ); + ( Hex.to_bytes + (`Hex + "03bc95c207643b5776b253366243813d9962191638555a71dd1324294c542d1a"), + Hex.to_bytes + (`Hex + "b9eb2aa8370deb352bff687674bf3bc46fe3beca7fe286b068e85e0d8b49a32a") ); + ( Hex.to_bytes + (`Hex + "454e2e36adbfc2bd90929da9c41da5e65d7df660f1067b7ad8d9a7657788cd19"), + Hex.to_bytes + (`Hex + "6f93ff640563518def9713504dc6dbfabce5e4100f7c9fc69d98b6d1eadb2a2d") ); + ( Hex.to_bytes + (`Hex + "637255cdb1b43a58568c2f3110f8e4aa4ddfd9071d2a232f3a77c6c4a3b5ba2f"), + Hex.to_bytes + (`Hex + "f2be5dd31244e573a8e5ec67a187ce3e8167e9593ff623925d0598f510e0e50e") ); + ( Hex.to_bytes + (`Hex + "a445f2d0cf6d6929a066c373bffc7782cf74991f74c241689b28e6184c2e0937"), + Hex.to_bytes + (`Hex + "82f2372d532b8f831660b0c4605edd815d4e114534b07cfc1f34a94d639cff32") ); + ( Hex.to_bytes + (`Hex + "6d5d440031aef09f4ef68c962ce2d87c2dbc3ffd9970c76e7a75ce4a09d4ed03"), + Hex.to_bytes + (`Hex + "abda7daaf4d049b951ce21e4a67579959a19d468c9f787e38c37c2acd8837610") ); + ( Hex.to_bytes + (`Hex + "92f9020d16ca367c1bcf2abd4477c4b37d238e2a7a87fad49a81c5f7daa39413"), + Hex.to_bytes + (`Hex + "5a45631b525e13b65ae138aca01ff94bb655e81b649fd98121145dd78b1b2422") ); + ( Hex.to_bytes + (`Hex + "1bfe89b9695fb4ce458d97c7ed93e7b7390c0341635a073be6d2006c8fb6762d"), + Hex.to_bytes + (`Hex + "3e0c1fce111fc83a0c05b52a29af6550f143baa95a30c18a6730d9e7ba819716") ); + ( Hex.to_bytes + (`Hex + "8fa435d889f0fe20642a07d6667723cb7c3b7cdd570bef18a0a4578f575f3d1a"), + Hex.to_bytes + (`Hex + "89c9323e97257425ee9ab5381acb95de08ae8e325ac4695e179045517038fa12") ); + ( Hex.to_bytes + (`Hex + "f30015b11db7cc54074e55c9087be2ea5d81336e91a0acd753a8dd1173e22409"), + Hex.to_bytes + (`Hex + "2a94e9cc3cf9616d33e8837ed15d9e2d50f7676dea7a1084a5a17c75626ebe3c") ); + ( Hex.to_bytes + (`Hex + "767397b7d011967434eccd4c4616ee911a122aa811ee1aa795de85d1bf4b9f0b"), + Hex.to_bytes + (`Hex + "6da27eeacc7257d1276d0887db5871d14d2bea1eae1f936099dd28b81346dc34") ); + ( Hex.to_bytes + (`Hex + "6ff9e51ed803bd1f7a0791b682971c37e55cbf19a7f52df5539d1d45b2cad602"), + Hex.to_bytes + (`Hex + "c3f9905e7153b8192be0b7629e101e6e355b4a1d2cb70243f84621e26dbeb010") ); + ( Hex.to_bytes + (`Hex + "2273aa81c734cf24e35ec4b12ebd473239ea13047843aef9a6786578b8dc160d"), + Hex.to_bytes + (`Hex + "c8b1a73b02e5419d811a66fc862c5efec30f7e42d6c029e7cb057149ca05f305") ); + ( Hex.to_bytes + (`Hex + "9d7b2f2568a8fa1a2cb4e9527b61199e83f1e3e99d44f4d5e820ce63110e2a32"), + Hex.to_bytes + (`Hex + "73bf51630acb91b3cd6a5a4f7b1f0b6126aa20cd319f763a67bf1b56a228e33c") ); + ( Hex.to_bytes + (`Hex + "b23f40fd399ec73004f56f915612821d6b2bd665deef73fee24da3c642479429"), + Hex.to_bytes + (`Hex + "174da5b241996eaacad4341b9644e25045cb99a1c442066b0ca0fdee9d60f301") ); + ( Hex.to_bytes + (`Hex + "9e4a77e0a506ab4b9953bd52423b30a3209529e77b1fb44bb4faebd0efed213e"), + Hex.to_bytes + (`Hex + "e59964cb5f144c461048ca1ab76135df35565637fc58bc045057bf6b9a27581c") ); + ( Hex.to_bytes + (`Hex + "44cac09dfef0f499021742b082d6fb0290d8682931f1fe2e1044b16d2e22e215"), + Hex.to_bytes + (`Hex + "67069ac9e283a067fb87d26b4ad1ab23b0fd5d2a1eebddab7e6690be0a96600b") ); + ( Hex.to_bytes + (`Hex + "af4f5aba4e6840c76cc37c1395ce224c1a2b5ac42ba41a28599ae0976b146b37"), + Hex.to_bytes + (`Hex + "89e22a98b0bdefc4fc834c56b6a754f5dff831be0fd2678af66d7841039f372c") ); + ( Hex.to_bytes + (`Hex + "4f8e1f4ba82fb62ad4d7e051527604569b0b6162b42e1d86506e0e45bde0c431"), + Hex.to_bytes + (`Hex + "1ebe2af79e3ed3d8ef6c4a7f7bee03b8a64d390c38b43c9af0b5b313278e2812") ); + ( Hex.to_bytes + (`Hex + "3e0fea1f9e118c1d53a7c0af238448cff41a1d4285dc6e0b8e5d1fffddf11f26"), + Hex.to_bytes + (`Hex + "aa6c9ed150579901d48e49b7df821dadb73191b609d77b2480f7a51579b83925") ); + ( Hex.to_bytes + (`Hex + "9a93e8f880fb8975cdbc5ad41008bd9e449bcc0cca79bafd80c95d8fea1aa01a"), + Hex.to_bytes + (`Hex + "0be3836b27fa55a51b8aa48cd31d8f570d376bf802d1f71d9153334e63464a39") ); + ( Hex.to_bytes + (`Hex + "0560a0b2b4ffa620e2c424fb718feb92f884f79667098daa0d330e8d0716e316"), + Hex.to_bytes + (`Hex + "705032d4601a44dd5b7b211b1a77114b482fda264e509bcd7e47722ae3eb0a30") ); + ( Hex.to_bytes + (`Hex + "8c50d4d1874c4f7473a548d95860ecb3ea9fb94379b4ccc4f23feb7c8f922e29"), + Hex.to_bytes + (`Hex + "ad27d0037644ce87200b88e6ca90b99b5a7465e4da412dc99c27292df5812302") ); + ( Hex.to_bytes + (`Hex + "e31dd6300738620705cc7137f3e3dd1eb34ab6c21c057f1b930e0a8a02ef5304"), + Hex.to_bytes + (`Hex + "3fb806518c20f44ab2e91119b80b2fa18462ca13e355238d2de4dd7726c69a19") ); + ( Hex.to_bytes + (`Hex + "cb31a5658b07d5a5addea84096d3d4d64a19842ea3109573dab2242d7f7e4607"), + Hex.to_bytes + (`Hex + "e56551185dd5ca2aadc7c9776a14b20f3d79255ac7f9214a9a665c7e53b61f05") ); + ( Hex.to_bytes + (`Hex + "fce339273e2c775cfd20dcc52751f3fe04b0f0432b09d193812e303ab41a1036"), + Hex.to_bytes + (`Hex + "612927698a2c06a23c55fe33da1eae959f1dc313d68e550c18f5b10badb37926") ); + ( Hex.to_bytes + (`Hex + "876556932d4a994c602dd195820debdec48dec459325c2e1eb887237f2d2352a"), + Hex.to_bytes + (`Hex + "4dee9daf3f2098ddb81921c58c2c665c4e518084cbcd3ea6aa1b2a33d5f4da18") ); + ( Hex.to_bytes + (`Hex + "c370faccadd04cd8a00931cc09d27c000ffa25325e58ed78a0be8a4243aa9e03"), + Hex.to_bytes + (`Hex + "5cc661aaf904f7b8d11f81d7ee1e02b5b6c34106e1d13a5ec809fb97992d6d28") ); + ( Hex.to_bytes + (`Hex + "739c43f5b378162f1b110ad3dd1c1b9f4d83329b9f4701161b722094b6c1c117"), + Hex.to_bytes + (`Hex + "1a20c290720b685b23bc1ab04dcbf9f904e56af2d46b4e1d2f82885969e09d38") ); + ( Hex.to_bytes + (`Hex + "86bd6ca246a5ccb13075488df03681d5072fc493615c22c0d46bdc1cd2590039"), + Hex.to_bytes + (`Hex + "d4228e31de720c6bb6b62f543a9e5bc240749fdae606a8a74d8d2643ce712a3c") ); + ( Hex.to_bytes + (`Hex + "22f18904a211e150cb8e5ffdda1adb07b902901fee51a6f6ca57ca41858fdc25"), + Hex.to_bytes + (`Hex + "dceeedc4e0e641829253a057055adbe1a332e56ea1d4074b32f4ed70970c1a1d") ); + ( Hex.to_bytes + (`Hex + "f4718600f6686bb207439e0b0ba0db751f712fc8b765a7d953e8cb27c0f46527"), + Hex.to_bytes + (`Hex + "5bb67ae924d0a7b26d2a277726eef51d3d2789c751450e6c9d637528997da127") ); + ( Hex.to_bytes + (`Hex + "8dd66042fefc10db6326bea7957c5471a3a1ced06a285812ea47e988ac52df27"), + Hex.to_bytes + (`Hex + "b70fc300535b4e3d326e8836e4bef6935d55d9bd1ccfe4bce21055c3cf324620") ); + ( Hex.to_bytes + (`Hex + "a6c2ecd7f8287c8b172ad204b7ba8434cdbfd8e63855eb682ffd0905258d0804"), + Hex.to_bytes + (`Hex + "08b92e758e01f857e9b36033e29409c764139a96c5e0b531511c4cb69c3b1d24") ); + ( Hex.to_bytes + (`Hex + "378b326307a90f074e45d1f7c97fb7809f9b1cb095ba51a83cdf207254174f10"), + Hex.to_bytes + (`Hex + "fb19e705537ec87d878bd5fbd5f68f335f32f71420e7c5f888fe510cfcfe0903") ); + ( Hex.to_bytes + (`Hex + "8015f89c47813eb3d8391a4378f7433dd116aff8672534cadb0c4b210a431331"), + Hex.to_bytes + (`Hex + "99434f0b7359c913b0a25cc66e1a34e5d3e4143323a652cb21dafcf952c5ed2c") ); + ( Hex.to_bytes + (`Hex + "a72c0bbc21d3f2e25b41f2b98b6d52b20110fe528f2a60bfbc8eeb9589f2683d"), + Hex.to_bytes + (`Hex + "aee060f28c98bc15b47315a75372fed3b955305a86a06e5dfe4067ecfd9aef08") ); + ( Hex.to_bytes + (`Hex + "14c5be91c3d6a64fb8ec64b82932a8b567219841273f5935e491b464d3ab0214"), + Hex.to_bytes + (`Hex + "bf9c825fb5914fadc14617bdce247860af5c35adad5a418902aa318eb1541d1e") ); + ( Hex.to_bytes + (`Hex + "f09217ffe3ff68f2b77a24c16d820dd36a545104a8de35d828671b5b7f78f307"), + Hex.to_bytes + (`Hex + "485bda22307cbe06ceee7ee5afb01961edebd03b93efb2ffcb2f1bdb2cf76901") ); + ( Hex.to_bytes + (`Hex + "8d884b29342856e48456f2643b51fdbc23d4abc4fbb88ef09fb46bc8e300b60f"), + Hex.to_bytes + (`Hex + "def83f3b0efcbce71ed7aef9ea5ea6be581b8acd85ecdf70a6d86c896753f619") ); + ( Hex.to_bytes + (`Hex + "331b223ccfbffa347b09c6d53c884b047c0ccc005a71b0bff5c94420d0547906"), + Hex.to_bytes + (`Hex + "078ddf61da1b19d9754485a646a42a6d13db8aa5bbbfbc92394f1cbafbec5a06") ); + ( Hex.to_bytes + (`Hex + "57bd887c48ebc3868ef8d211d0d48bdbcf4de4a7ea69d8fa286e9c6eed302230"), + Hex.to_bytes + (`Hex + "f691a2bba5edbe0f9a3591ab646aea9273838b4b7072652ef40284e57376fd30") ); + ( Hex.to_bytes + (`Hex + "3abf55a9ab2e84eab9191d65a28c0da27afbeb8c50312eab53e8738391f4ca3a"), + Hex.to_bytes + (`Hex + "97caec92f6a4ca44d3d3ac229a4b2e2baae67bff9e2730bc15175b84716c913b") ); + ( Hex.to_bytes + (`Hex + "47d0d1213bb00212beb554aa5257ae033c2aaf2e084125c97a0b295d1ce5ad13"), + Hex.to_bytes + (`Hex + "4c97365cdc8c41809fc2811a730404d66d1b899306baa223a136164bdc9a6f26") ); + ( Hex.to_bytes + (`Hex + "020cca405eaafd9a518a14a44d9858a3780f42997cccd4ac8b312c2385c18721"), + Hex.to_bytes + (`Hex + "80459f495d3d818a26d8a2df3e1113a566f42df2f7fe8debd09959433bfd3120") ); + ( Hex.to_bytes + (`Hex + "9a30183361658e031816676898ccbcfbed87900b5ff478c0bbbd9c84efe8f230"), + Hex.to_bytes + (`Hex + "91daef49015a6ba37493201b96de957ab85a3b0faa06caec15decb64b863dd31") ); + ( Hex.to_bytes + (`Hex + "b3938ef997b296471e02d91e41b393f422c9115af04959198687c54c32a0c535"), + Hex.to_bytes + (`Hex + "04186326a7ce71feed07bbe55d54353be09b0864028c0c1e7e829e13274bb224") ); + ( Hex.to_bytes + (`Hex + "1b7018481e523df3eb12b14f9b6bd00e385768d5b1f68dd32d1f64e3a354832f"), + Hex.to_bytes + (`Hex + "9c485d8e8bb5572fc561c34d17abb18891a007176061feff2640d93fd9759707") ); + ( Hex.to_bytes + (`Hex + "e034069f084b097df3b4972073426032e34a058f565d952d37a8b0a0e1839420"), + Hex.to_bytes + (`Hex + "65218bc632cb32743f2db07f6521d97b8aed43619ecd8e0f49ec4ab9a95f801e") ); + ( Hex.to_bytes + (`Hex + "04ca44836c89135162b0dc144081f83e3686e3642a401244ab3adf7fcac0a22c"), + Hex.to_bytes + (`Hex + "4e3339ddb611d4aef559883ce864bfac0f8bf1bb0f908ac61cadb75997a1c235") ); + ( Hex.to_bytes + (`Hex + "fa62d868af183e3d136b057f4906d5e3d37f7bbeadfa454e57e9cd203eda5918"), + Hex.to_bytes + (`Hex + "49e76af390a05d64f12a46a0b2b31dd4583c97655e2c6da9d0e0518f18141e14") ); + ( Hex.to_bytes + (`Hex + "f0fe677abe00bbdadaedd76a1ccf7b5ca1556c3156f46c93067f67e1ba6b3a0d"), + Hex.to_bytes + (`Hex + "a3ba600075809bd3af615130fa40e3e82d6585054bc45d19d107a90b6b79d300") ); + ( Hex.to_bytes + (`Hex + "811d33c05eb9720ff03a368eb47009c5c4fc16a72330678d146824fb5d482d01"), + Hex.to_bytes + (`Hex + "de172426b86b91edd34970018d026d428c0de3b950158f39eefdb5ac46c21809") ); + ( Hex.to_bytes + (`Hex + "44402507c9b99312dcac2f1adf0c8840be0305f480cde34d1d5c21e08cdcc921"), + Hex.to_bytes + (`Hex + "bba3d923e0320b2a5da84d2c0033fd8d2c03dcea54fafa9094bb76d9b4e6222b") ); + ( Hex.to_bytes + (`Hex + "f56d433622fb677ff4bf056940a9b78c0af21f48c68500075861b8c4f16b672c"), + Hex.to_bytes + (`Hex + "9e1a9c4a008cf17c6cb05fa18fe631f987957e6721005a4b606c5ea34af6b02f") ); + ( Hex.to_bytes + (`Hex + "5f59700235110c98608a8054c2a007da818815dde167aab0fbc6fc9f46e47520"), + Hex.to_bytes + (`Hex + "32190aaaf6d6d0441be004f3b6522b865e1317b5486e0d693fe392632c93e522") ); + ( Hex.to_bytes + (`Hex + "46fa5ed54dd261f21d2dce2ee18ca2e33c1ae45d0fedc3b6a0cf871a91dab01c"), + Hex.to_bytes + (`Hex + "421f365355564254f53848a045c29b089e5a4179664ecc8d1b66d71dfb80c634") ); + ( Hex.to_bytes + (`Hex + "185b6ed57290652df3dbbd22b4248779236f7817d15b46a385e3134b0e406139"), + Hex.to_bytes + (`Hex + "3c5dd2ae92625efd3f78cbb3bc16754856583c2918fe9f8ecfd0c399a9cd7e25") ); + ( Hex.to_bytes + (`Hex + "120f56aa7ee41383cec1d019ced188a2ced9b524c847e70db8f95060f617f91e"), + Hex.to_bytes + (`Hex + "12d5e3aa17c4b35120b5f93ecb268c3024c11005e2fe249efa09454a2059c410") ); + ( Hex.to_bytes + (`Hex + "0b1db126f6705453b451f8c3982b6e365e7019b0ef1a2ac0293ac4de78f8f20e"), + Hex.to_bytes + (`Hex + "fbd6f8c8fdeae1bbc10f62c04a3582ba7c919bd39a288449141ed5bb6e04b032") ); + ( Hex.to_bytes + (`Hex + "73cf163209e7afe580e5922562ea7cce3d467b9d3dbe3b07d7b9c1e96f970502"), + Hex.to_bytes + (`Hex + "dc16abb94629ef1ec4a5ab5c0eea13552514f9888ff37401e94d4865c6f6b716") ); + ( Hex.to_bytes + (`Hex + "855c62779c2ecb07ec1a517324d3f633aee7f1f10eacf0f7ef90974e94c53f3e"), + Hex.to_bytes + (`Hex + "ad238ce2ff2186f2e6fab52ed245e444f057df5bad91c6dda9dc5d396f15bf36") ); + ( Hex.to_bytes + (`Hex + "9a7d264465a124d5abaeb284962e661fef47b1134568892cf154d031dec6c938"), + Hex.to_bytes + (`Hex + "1de2685a2b03ac05ab206c60c0ddbb133a8b7c22da8a263046ff717bbe3f5b2d") ); + ( Hex.to_bytes + (`Hex + "2bc92e84e385b6118b4924a6dbf44499976a40b041d6c09f7f374c12514f4716"), + Hex.to_bytes + (`Hex + "ae2d34aff3606811c5fcc3f348c205788a09d3d152d11348f9e53b82dfc68f20") ); + ( Hex.to_bytes + (`Hex + "3ebe5e83997a69c1ca1a9931bbb7f15e37c9b8fa3bd93b42dd0b1804a3356729"), + Hex.to_bytes + (`Hex + "dad1a20709c0b7bda1e043b55b8c8c368e748c86209513c27cfec2461f178a0f") ); + ( Hex.to_bytes + (`Hex + "c1e0c0aa16fbdb6a5cf229a37f9f70e6a1adcd3650334503b7ef5d1a0e227c06"), + Hex.to_bytes + (`Hex + "ca52d41f087afbef41fa95399e53c591c22b09b270e29f94f5636c9580eb940c") ); + ( Hex.to_bytes + (`Hex + "e93cb9c48ff0ce769bd189d8bb0065cdbac014e591bc76cb35cc7ff1edb37626"), + Hex.to_bytes + (`Hex + "b13b0d44fc7ceea668b59f5537faf0f9fde07b982299755ccc1eb99f259bba18") ); + ( Hex.to_bytes + (`Hex + "e5f1aab77090aa8867bb332b4a1219ed13f8d2c569e56ee545659c68483d6d3c"), + Hex.to_bytes + (`Hex + "3727926d983cd32dc5d368ccc967384a898450234b10d80d55d5295103a72012") ); + ( Hex.to_bytes + (`Hex + "f6e39ec2dcb74ff3b4d67f789f41ff6824fd50b6446013e1bb060a3f4ebb070f"), + Hex.to_bytes + (`Hex + "6848d6309b3c2faf418dbceebdd076b81d9731a5eacfe1d5b0e745953f739f04") ); + ( Hex.to_bytes + (`Hex + "3426ba1dcaf730075da949ac6cc89c22ff5bf06787549f296572c9bb6f6cf01f"), + Hex.to_bytes + (`Hex + "9efb43c3b385d442ed32f4d709b5a0a641c3543e257560ea1e269b8e3d14002c") ); + ( Hex.to_bytes + (`Hex + "47f2fc2eae58da8f0ee1f754220035ee5468d8a167f06e73db7b81f3f6731b17"), + Hex.to_bytes + (`Hex + "6511782882b44fc38ffc61a1af16a5f121f79f6dbd8cc798c1119fb9d37d383b") ); + ( Hex.to_bytes + (`Hex + "c2015bffdc8d2cf528ca93bddf703d527437c1c4a5d3299cc373de38cbfecd31"), + Hex.to_bytes + (`Hex + "b89cb126283f8cc660fe100693758bfa8499512f95d4f2de85b1adddb66c2122") ); + ( Hex.to_bytes + (`Hex + "4ed2c0f3df8eed6bd4a0bacdb937ef99db54fd65497457af44ca19244eec0427"), + Hex.to_bytes + (`Hex + "c2b17eb6d02bdf8c6be826b43da3f8587f9666fe62af3b650847ce4d587f2623") ); + ( Hex.to_bytes + (`Hex + "3422b7ad84f2126396ab1cfaa20a4f7795567c13e74c2f7bd2e0da8303b26408"), + Hex.to_bytes + (`Hex + "6cb7fe53d13e1d733e4cc9d5bc32f0cac6aab283280bb6c4b5c0cfb93cd62521") ); + ( Hex.to_bytes + (`Hex + "5997d9a1173fe95320a01be03ec7bd5b752fd3f9a6bbf7ac756a3516c8c15219"), + Hex.to_bytes + (`Hex + "e0d4f31ab6f0ec66901a6eed24091c57c014c01fdeb5057780ea73f6225ad71f") ); + ( Hex.to_bytes + (`Hex + "d6aa918c40eae151a35dd76d4adcb39d969a1fe8065a5d56905399ed0ffb2a0b"), + Hex.to_bytes + (`Hex + "a3eaeb24f7e685cbdcb92795b83de70a687a1c95e128e3cb71159e231aae2f2e") ); + ( Hex.to_bytes + (`Hex + "d589c164a2ea58f9f74f1c12d1b766fd1b546de90c6cb33425003b6c0986730e"), + Hex.to_bytes + (`Hex + "ecb83b7fde19bd2c7f17c90d74989d04506c8bdc94e476dc1aab68a96cea163c") ); + ( Hex.to_bytes + (`Hex + "f3dab789ccad5a9185971f0e1cff0929f27e9a0128a1bdd5518dea9e8ffb373d"), + Hex.to_bytes + (`Hex + "38f180a028e3be092021fe07905873e610917c5de11513217754fdeef4690f19") ); + ( Hex.to_bytes + (`Hex + "9b4514c828d087987d9a77c91497fe0b372c70a023a1bc09ef33f9553fd6b52a"), + Hex.to_bytes + (`Hex + "aacb9a6675310477afaa9c275632d9d2030d2e9914f43b168a37230725add32d") ); + ( Hex.to_bytes + (`Hex + "e11e622c4daf70aa6ae14fa4f976bf82f41be928b3df23d8ce50ef8fa7862e0e"), + Hex.to_bytes + (`Hex + "909ee695dd97df96d6bc59e9757d40a355929fd8c5080688332bc16de1b3e32d") ); + ( Hex.to_bytes + (`Hex + "cbb2ec583429960c0e561e7d4d867d0d55c5dd3ca6d328ec1a74630200ebe00d"), + Hex.to_bytes + (`Hex + "0e6f7b937d20c81cc6c87edceee797977ae741e48a088622a4c54fc511482f24") ); + ( Hex.to_bytes + (`Hex + "913021b4b808e602fb83af262cd8f90425252fba44e59c4d3ba5514848e28e3f"), + Hex.to_bytes + (`Hex + "b42a3df93c0aac9d67ed1bf36955d77e3187e7143fb730b5d8b1efc758680a32") ); + ( Hex.to_bytes + (`Hex + "ef5b8cc1739cc7f133af5dbe27fbdcb4b89a13a43734fb005846b8fe2669a927"), + Hex.to_bytes + (`Hex + "015905a804954ff986c18c5fb57016d84cd4ca3fc9410ad8f9fa9669fa6dfb35") ); + ( Hex.to_bytes + (`Hex + "08ddfd8ac81cd4ba27eb8131a3bdd24987f264e72ea4d96bd33dd6aabc7ff91b"), + Hex.to_bytes + (`Hex + "79343fb9b614709e8e0ad985cc3acd2ebf737e3824dadc9aa1e613ee8e20461e") ); + ( Hex.to_bytes + (`Hex + "e712e232374bfcbec78243194e0a9479cb7654ba4121b5317e09c611d9b8d70d"), + Hex.to_bytes + (`Hex + "f724a645be378f870e298db510f7039ef808ca79c0aeeb9dbdb80015ac3ec900") ); + ( Hex.to_bytes + (`Hex + "fb42090389eb08d891e61f81e447ffbc56912274b6d2a748bffd0ee052a78e22"), + Hex.to_bytes + (`Hex + "cad44cc20aca99f121865207a7070f6b36db2d033665458d7833b140483b8802") ); + ( Hex.to_bytes + (`Hex + "1b5b9e9fb44393e6c713fd326aced589979aa15a5c6fd79ed1bbe100c933c42e"), + Hex.to_bytes + (`Hex + "e1ab3e4086edc3ea4e8ab8df5e9afef620dbb09751636a8fa2cf11053d042c1e") ); + ( Hex.to_bytes + (`Hex + "d494a3ba15f2b79a6fa28fe3163e8f1d5674387719fc5941db25c0f3a108ab00"), + Hex.to_bytes + (`Hex + "aa845322474227718ba61efc39d216bb7035e40bc2b73b0e8e9c763bd7d90e10") ); + ( Hex.to_bytes + (`Hex + "ff24e948c9aec34214f44bca8f1a639b16a40e06fef7f29ed18195f09f8db425"), + Hex.to_bytes + (`Hex + "6e76a0353a2de48ad672cde9d8f64d1063292304b25cdf7136625478d7589908") ); + ( Hex.to_bytes + (`Hex + "bf675ba6ad0bdca557b04422a2e89ff290b1b88dee3e115585d47b2f19c11012"), + Hex.to_bytes + (`Hex + "23dfe960e5e8624bdb5e6922a03225e6e4f9a2bf17a3fe4a884b261df6673401") ); + ( Hex.to_bytes + (`Hex + "9d20789f8c3cd5d1d1f6c79d542e13978fcee219b6fe999983adb245c1192718"), + Hex.to_bytes + (`Hex + "caeb1b0de8074064aac8c2215ab49ab5e9bd1b136a16cd37ae113905f179883e") ); + ( Hex.to_bytes + (`Hex + "d1afb380a74728217b149d72a3982dd655e480775bcd76ac5779936455d87113"), + Hex.to_bytes + (`Hex + "61d82178ac35c503ff21d3d4b87f97184cd9d2099d5eec573dc3253d96883329") ); + ( Hex.to_bytes + (`Hex + "33b75b4f0990644c3d1238b69e14252f56fe073ce6d53b58fcd89acfbee3d038"), + Hex.to_bytes + (`Hex + "57f382021076829474d455fd5d4a35906134d7465f0690df6211f7a7e9e8e21e") ); + ( Hex.to_bytes + (`Hex + "f6f92583da20cfc26ce0b53a2b325841afde5fe77003ea5545b3072355519104"), + Hex.to_bytes + (`Hex + "5611d258c7b76c3ad4c80a42a9ace53e2b04b093fc784e8267d679865fec0023") ); + ( Hex.to_bytes + (`Hex + "86124acde74d344595bd45d5be9f00704dfe9c32dc45f3567086224c100f111b"), + Hex.to_bytes + (`Hex + "130b034dee677e58fde3a1cfe04ed62666315be4bc3da431877d99cf741a4c38") ); + ( Hex.to_bytes + (`Hex + "de5baf0315b839a751371659c34f73fe680f71a5abe2ae876960dbfb097f8028"), + Hex.to_bytes + (`Hex + "fe91c30852ef9a955cc396b294488392735ff0997fc45c4af2e55095d423a504") ); + ( Hex.to_bytes + (`Hex + "f0a2738455a1aabb97704a59dd488d84c1ddeefa5cecdce32ed9c4d75a2c8c3a"), + Hex.to_bytes + (`Hex + "e12bfed45077bc3bffba3be5480cba7004680dc1835604a8fe0d7fc631669410") ); + ( Hex.to_bytes + (`Hex + "d7cc7736c5210236b3119e60d946e89d1ee5c50f590f00c6f3832aba186fe512"), + Hex.to_bytes + (`Hex + "fd7c6e6333c972b42b25f1b15e507b74699ebe0f8b8b4f94cd1f35ccb2051b08") ); + ( Hex.to_bytes + (`Hex + "cc02e6a236279ff61f62c4d5b725b64080bcc94ba7e2ba09b4a198324239b019"), + Hex.to_bytes + (`Hex + "dd6ddd92069c25ab77265a71850e3089917b966d354d181577f725c07e01fc1a") ); + ( Hex.to_bytes + (`Hex + "c447d1c91da19cbd65f6ea74e77029a79b8d50e3517fb24af165e2525f85801b"), + Hex.to_bytes + (`Hex + "314cbe25f33ecd479bad2af59538c1e4277f9993a39d33356fcf5af4287e8823") ); + ( Hex.to_bytes + (`Hex + "e211a6e144f06308f8787a8e7555e479d630540f159cfcc84d27de84368e7a3a"), + Hex.to_bytes + (`Hex + "4d3ab3bab52fa3036778645ca634d20bc1d713d0ad192b9760f22ee2942c1216") ); + ( Hex.to_bytes + (`Hex + "fbf853c54d1878df1428553738eae89538db396d2f0903169fbb01c9eae66927"), + Hex.to_bytes + (`Hex + "452db622d21aae6aa91e0d984f704183a62360da03b51773e6927ca7aa5bb116") ); + ( Hex.to_bytes + (`Hex + "e593f3d34f69ad355d63c1ecab6b77b97f840fa852253e672d6cfd6f2e562a28"), + Hex.to_bytes + (`Hex + "33769baf0f3061cd7a76b96fdd7b785f2ea8cba30b3ee6f82658f6706c8b293c") ); + ( Hex.to_bytes + (`Hex + "f08533400b9278f9edf4e787eddf414740b097a0509af79a553d7f7a0104f209"), + Hex.to_bytes + (`Hex + "decf1d1ec7a74c48c1cba5c817fe5e4357500471aa1281e92680c5b805992c1d") ); + ( Hex.to_bytes + (`Hex + "87e6a4e2c1dd4e8a8f858e01e25cff5b6ae5a1832f66e5c6ba2d9b670d00a202"), + Hex.to_bytes + (`Hex + "a0b2767ceaf66a2f5640699bfa4bc7b8141e6d49ad1679fbe2044df105caf41d") ); + ( Hex.to_bytes + (`Hex + "5cea36e3eff68860c854b53a0a119774701bab907e8a4abb07e344a6a805ca16"), + Hex.to_bytes + (`Hex + "cf03e0eef64b6bbc4c31175d39c29794eb57df964e8c28a52fc3b270d22cec05") ); + ( Hex.to_bytes + (`Hex + "4468512dba5a4b1df0cfac1463e7bb0e47595019c352e2caec586b9869776f10"), + Hex.to_bytes + (`Hex + "912653bd24de32ecaab8ba9f79b182af514df3332d59f7addb22805382abd71d") ); + ( Hex.to_bytes + (`Hex + "f9946c35cc5d0177ab739ff85f8f5be73747e281897c4a93e39e04e705ea5209"), + Hex.to_bytes + (`Hex + "f775509d2dc9db7bd49e285ff0218599b26f287afe4f0d929232694bf6edb419") ); + ( Hex.to_bytes + (`Hex + "acb3f918b748932d72cbe907d8c3e61e590b7bbde347f727af390f0e4e264433"), + Hex.to_bytes + (`Hex + "857f279fe514925384fac7755cf1b5ba8aa8cb1b01a5925eefeb986ec47bbe39") ); + ( Hex.to_bytes + (`Hex + "367d9857b85cfcef061c8ae083e33142e55fb499e7c3f48324b38d62d94ac41b"), + Hex.to_bytes + (`Hex + "bc83601aed7351b00f557c379db43f5d56c934c67e1fc49e52e34979bda4a22e") ); + ( Hex.to_bytes + (`Hex + "c515ab186db811cebdebcfe7bb58fdfd41a7de1a65161a01bedcfc0383766718"), + Hex.to_bytes + (`Hex + "a6633674b3a7658ccabcb4822cf6950842bfe51948267f6955c13a69898a9e1c") ); + ( Hex.to_bytes + (`Hex + "62d983b5c150f120a433f36bdd4f7c5b9506566b14f21666d7f939ae2a15093c"), + Hex.to_bytes + (`Hex + "765fe4115cd14c8d957a65a3a2fbe63e68ae90294d94df57fdfc7fdd0696403e") ); + ( Hex.to_bytes + (`Hex + "7f204ec6aacb1d0faf74e8049600ce242b3b164f41a3068283536095a5ff4118"), + Hex.to_bytes + (`Hex + "b7df2d17844a4574878c74e93d66614e10ae52766fc4ac49403da02d31ebf935") ); + ( Hex.to_bytes + (`Hex + "d27c21e629cfb27172c7dc0ce46dfb857a87460a602db0fc34628325a8cbcd0d"), + Hex.to_bytes + (`Hex + "7b3211d658e0e7a5dd0246d4dcda291fe560aa221606d250285d1169d74ac11b") ); + ( Hex.to_bytes + (`Hex + "9f413babd498ad76ff97256e508cadffbd1eea43b6bb063af7c5fb6ff3b0a33d"), + Hex.to_bytes + (`Hex + "6d29f06b0eed47f7b09358d36398b5084e067fa701a3c9fe8603dcd79eb5e918") ); + ( Hex.to_bytes + (`Hex + "4f68a0659b7b6519691bc4192d8c3821fa8783d70b214fae1baaf91756f14a2e"), + Hex.to_bytes + (`Hex + "ac23bb7d88da5a7ea5ce1aaada816a07c71229464a2cf54600cd9aa7473c7c37") ); + ( Hex.to_bytes + (`Hex + "60895a774f9be6d953228c3a6d68f83c50f6dd38e7167c00fbafa9d17fd85c27"), + Hex.to_bytes + (`Hex + "dc39be83e8faac2e92975e5490cb47a15621a50c0b6694b81f2ae654d57b2c10") ); + ( Hex.to_bytes + (`Hex + "43d78a812552503d51449622daa4107638e1cd15a3dbc14a688bb493eae9632a"), + Hex.to_bytes + (`Hex + "aea07c988a7b2f60a29c2bd1ffd96df27451de6c96363474f6988d59012b771d") ); + ( Hex.to_bytes + (`Hex + "2df10325fa79e69ea7c17caba867a0e30d5d00a9d6cf044a0e35ce031fe7b620"), + Hex.to_bytes + (`Hex + "c0e9d9012e3599ff8a918bf328ebff1c4b6a2f6b1d215a3f783f33b9c51afc35") ); + ( Hex.to_bytes + (`Hex + "3bc12e0d30ac29fd9d2690a02888866d3f6e1ddfe3b47b61223d9920bd446210"), + Hex.to_bytes + (`Hex + "53b0837d07624bbab4a55405b3222b75c412a0f320839993f353a7f99512323e") ); + ( Hex.to_bytes + (`Hex + "f62dda67132ab021e571bb2a36f55ed98dbb9a8197cf66c48dd1efa9f5d2c10a"), + Hex.to_bytes + (`Hex + "3d056fe5da722c65f82509dd3cdf163e8eaeaef064dc8644283dccafd6d18310") ); + ( Hex.to_bytes + (`Hex + "22cb04153f906dd6a2f1fd24951d747d1d70055b42112004f928a6a4dba18125"), + Hex.to_bytes + (`Hex + "e80435946131f531ee2723e96a08b5560bd453f4a6db7004c38b466abb3cb737") ); + ( Hex.to_bytes + (`Hex + "5a09622ae6fa645ae109cca39ab95d1acfd4f1b44dbf875c25cec75a45e15435"), + Hex.to_bytes + (`Hex + "3c6559b2aa29fb6299bf69f628e07910d3566ab6a2e1b5c73d667906276ca91d") ); + ( Hex.to_bytes + (`Hex + "95c5e40597758aa304917936bf16b593a9ecb7067c61f3dc0ad946624996041c"), + Hex.to_bytes + (`Hex + "10b09820de629bcb5b3cc4e6dcbd110bb5a471211996060e63b55e54bdf9a00c") ); + ( Hex.to_bytes + (`Hex + "8cd6e15cbbccccab82a20de547af7c6f6f80aaab5e136af3e8aa9510deba6e0c"), + Hex.to_bytes + (`Hex + "e2b3e6699ecc9c75bf63a205df54ddf96b9447cf3cd7da8952bc832bafd81203") ); + ( Hex.to_bytes + (`Hex + "8440093219f4633dbdd30da139092ea824ca16e0482da409d6a5fb486025d522"), + Hex.to_bytes + (`Hex + "8ef085e37b915f20c5968215ea59bae8f4610212055fdb07812d0dcf10fe271b") ); + ( Hex.to_bytes + (`Hex + "bccdc0c42620c5c3f1c4049875a0c9e5016d9b894fa33d33f19fee696f9b9308"), + Hex.to_bytes + (`Hex + "296a0ba6905c3857e39e8998f00afecbc29405ed494f6ce5d0fee4a7df878c1a") ); + ( Hex.to_bytes + (`Hex + "52704a521786cc9b39803ba53ebcd19eaeb3c198280a3be85f0078f379b85621"), + Hex.to_bytes + (`Hex + "030c4c1ad64f45e437d1459eee772dfd2e46cabed1d74c362402066da0615404") ); + ( Hex.to_bytes + (`Hex + "dfc842770be4dca6bb4c5e2f9ffbf677f601a1c8f2a671897e558de61d89f606"), + Hex.to_bytes + (`Hex + "60932cf332eb36e1e39483157a80cc43850e3fbdd86883b89bd9ffa343f7c739") ); + ( Hex.to_bytes + (`Hex + "88a1c5de2480924d3e3586d32ba9fcc666761bf55dc8125875ad85b9ae962236"), + Hex.to_bytes + (`Hex + "5bccbc0e474374af4ee04fbd03df6486e1a6ed90e1df7cbb6d8dc16af049b704") ); + ( Hex.to_bytes + (`Hex + "645de6613a7ecb478b161d614b8f68260a2781f0c6b11e85d3c4d9077765cd0b"), + Hex.to_bytes + (`Hex + "596e64011d9ca7b8148dbe3c810aa0ac6122d4a422d6e39baf0a21ffec448f22") ); + ( Hex.to_bytes + (`Hex + "d877fc32eb32e8011d6d1ecf9fd47ba302693a002676de4a5b287368ba181028"), + Hex.to_bytes + (`Hex + "f7e06a3f8cbd223bf99d9ecce9d47a641a86e2e54e269f591be111c7bb4dc71b") ); + ( Hex.to_bytes + (`Hex + "150eb8f12c5031ea28b448cd60513dc3ecad17de10c923cc479ca51acef9de07"), + Hex.to_bytes + (`Hex + "325964b4baeeaea4654d8710501423b1d6fbb3e273284fd72f46e456e528f737") ); + ( Hex.to_bytes + (`Hex + "b4c54bbb959f307e80c561727df462609085156d2a4f3d8e98a3381694e2d501"), + Hex.to_bytes + (`Hex + "52627651e025942d2b2f6d6d263a1f66ddb8f42f376026e2a5e48e77c3121712") ); + ( Hex.to_bytes + (`Hex + "7c6fce773ebc8980c07f0fd8eb22b2a650823e9490b7b8e9b115b46660069510"), + Hex.to_bytes + (`Hex + "6c2130aa2358afec67c88cae7671d31b924c003a175d4666a25facbbdab80817") ); + ( Hex.to_bytes + (`Hex + "0604d51ef4b35a0f93818e6b24b8d63eef7266c1a717c8efed6fe0555ce6d903"), + Hex.to_bytes + (`Hex + "d9ef153a0a0a66d23a60380260315831070404ef6e578ad0ad02863379fcb512") ); + ( Hex.to_bytes + (`Hex + "61b21a863850b4afefdda20e12253633f0c3e9bd8a1ed2d06766440f07564231"), + Hex.to_bytes + (`Hex + "2695cdb0f62b7dd49759ea036251b6df863df1d93ae9c86bfea39f871e7be336") ); + ( Hex.to_bytes + (`Hex + "f863713825b7419689fb7d9713e2142f01248e810f0f2e875552019442470527"), + Hex.to_bytes + (`Hex + "3ebf77e2e99814e9e80dcc4636131cbcc224bb9d5f260d8117d4220ca74f3c07") ); + ( Hex.to_bytes + (`Hex + "dbcb574f7684e07274ec5aedbe43deaaa8efaa38e7197a6b389c03b2e403e13f"), + Hex.to_bytes + (`Hex + "fc5f479009a4b0f77fd46c59458b27f2209b6100333c898e44b35199120a9a1e") ); + ( Hex.to_bytes + (`Hex + "f7def4251d1d3e27b1be71315a840320d4f2295f6581176dc0295b5d7f5e7008"), + Hex.to_bytes + (`Hex + "ff7c5dfa295893557e5d89f7cd412af33de7a2d143eaf21b54d6530408bf0f02") ); + ( Hex.to_bytes + (`Hex + "139ab82dc799ccc77f453e1a72f869e8275ee9f9759bd5f82172ecb0b9df3c2a"), + Hex.to_bytes + (`Hex + "ae43b3c8879b92daf023ca1ae3223cb39b02d54320c0f67e16601bfbe575160f") ); + ( Hex.to_bytes + (`Hex + "f5a81e589cc4a7daa468f60bdf60245e4661af9c29ece2048962b6c6eee73824"), + Hex.to_bytes + (`Hex + "e35c900950c54cd9bbac987cc93949914f009de6d5a0d6905e000a439997300e") ); + ( Hex.to_bytes + (`Hex + "37ba3ddf71bad216f3467290393a87f978892c2ec70f0973d8db93769fca6a3e"), + Hex.to_bytes + (`Hex + "42822fe167c6bb148ecec764dfdaabb82aeab27bc15b941aec3a71aff6bb2d01") ); + ( Hex.to_bytes + (`Hex + "ac36d7c9da000d245460d51e2454015efb9c423e768e7bb7efbacd38ec954314"), + Hex.to_bytes + (`Hex + "f8f4ef183f46d5a112e9ec6e2b6a13acb6ab5b651a2f5b1712dc628877e5f811") ); + ( Hex.to_bytes + (`Hex + "269f8e1ba5917d91f92edbe2b3d4a796a580eceb93286764ada7dd6a2cc71504"), + Hex.to_bytes + (`Hex + "9db61c54e578fe3107a964a12ea4d06f9da9e75938fe9b7753cceaf913f30215") ); + ( Hex.to_bytes + (`Hex + "2c9609f5d0689962e8a1b9a56c54d80f4d86ee883771714fff9878bbd739be21"), + Hex.to_bytes + (`Hex + "fab4a1567c59302ee107818353ad021a336dfd1c9e2a024dc1b4aa517de33c1f") ); + ( Hex.to_bytes + (`Hex + "9bad87977a27e8d2f3de813d87efb8069492dc0c58a03fcbd5da10b666b80e3e"), + Hex.to_bytes + (`Hex + "e1fc0b298d986f41fca7ea9e469c9de91af38c967cd326e83ebc962965503a30") ); + ( Hex.to_bytes + (`Hex + "9665f9b73dc40d977ab3be7b04a0be8b20ff864f7cc0bfff7b815b2a70e8b02e"), + Hex.to_bytes + (`Hex + "15cf3ac792dfeccd4b1ac14bf4b849a38604351a825ca24c4ece638feea8350c") ); + ( Hex.to_bytes + (`Hex + "9d90c582fffe3033658f7615f5cc37a07eab65d1bfe5b4041f70982e0dd38f3d"), + Hex.to_bytes + (`Hex + "16693f614c35cf76e4b868effc8cacb348336dfbec231e127e00656976469c04") ); + ( Hex.to_bytes + (`Hex + "16ad8a20f85a8bd2c19e2225010ccc8544b7bafcb7001000da5059e1b53c162f"), + Hex.to_bytes + (`Hex + "0c8f4c85a6a50482f31b9c9fed50c2aebacfa84c3b9778a6f6ad6210c2786020") ); + ( Hex.to_bytes + (`Hex + "e7ba44aea2bf72b5d96558ede57b39479dcdd5d76026d812f411fbd0b0910238"), + Hex.to_bytes + (`Hex + "ed004fe304f09eda9e7145f1c5c9c7d1779c32e071b0075d6cccca5af31b1f11") ); + ( Hex.to_bytes + (`Hex + "4bf7ecdbe9fe4e9d401cd16e986bb65477922a1f67e99dc6196f0109c2f71e38"), + Hex.to_bytes + (`Hex + "70483d4c9162cd78c9a766433fb09d96ca8c98adfced3fc639ed6c19f1c37108") ); + ( Hex.to_bytes + (`Hex + "e48825cde05a95bfc685c15b45be5d1a701be7931ffb0f80b893a41f52689904"), + Hex.to_bytes + (`Hex + "7f44a4462ba08808288cb99c8f424fbfe29dff140307378110b4104376908713") ); + ( Hex.to_bytes + (`Hex + "df076b0fc0b42ed1f43977f3b79c674800447db1859c8dd249e375a8e147d90b"), + Hex.to_bytes + (`Hex + "bae16ce5278d62dad89fb896d5f8b93f376258f629b9e35db62e3826a4623515") ); + ( Hex.to_bytes + (`Hex + "5cafe6bd033baf36c60df6d71533a44f979191a420a06770eedd06b3f147321c"), + Hex.to_bytes + (`Hex + "96f60f655abb52c6e164fed20c893ef551ac0e6720c1bd9d8ab02344e0cc8607") ); + ( Hex.to_bytes + (`Hex + "e2ab025c045a529b10fc693ccd0388ab22f86749e7045c4f73c9248d8bba7c3d"), + Hex.to_bytes + (`Hex + "a78c0ec2a96d6fc34d05c718d30cb83ad888fbf18bc400ead575e9784fcd852a") ); + ( Hex.to_bytes + (`Hex + "a211b6d45ef95bac432cc780814d6d134e8d8cd288dfb61f1160d5171bfe6a24"), + Hex.to_bytes + (`Hex + "72495647337b683664bc0d362ddd67145862a9935fdf0c41a0e8c624688b8835") ); + ( Hex.to_bytes + (`Hex + "92d4624a722ac25d8c8d50a72b9b60267184531be65a5950ffcd6597b1346a26"), + Hex.to_bytes + (`Hex + "cba258d3db5bbe7f6aa7a81cfdf7a4404a000ea573321d49ad624fdc4a0e6835") ); + ( Hex.to_bytes + (`Hex + "4efd77f90c99dbbf9ecc6dca9d363764ee5150b548d0b5c74546d571ec730b25"), + Hex.to_bytes + (`Hex + "81b312446be4ae41fb61dc6d00e59e9e94cfcebbf56d2fec3d60160b15e29317") ); + ( Hex.to_bytes + (`Hex + "47620c77796d886f82e1a10f74030015822f6917b20376f3ecb7f50a68731f3d"), + Hex.to_bytes + (`Hex + "9e72f9e45aa7b68117ae1f34aaae35e70abbaae1c5b7ff4e4ac35d4cd4c12302") ); + ( Hex.to_bytes + (`Hex + "327545794df19d4112c5024e3f2880d736c56c75a147fcf082ed6ba00207e31c"), + Hex.to_bytes + (`Hex + "60687914539720aaa05350d971967bb7ba84dd093ee64e8006a8dd961b71e109") ); + ( Hex.to_bytes + (`Hex + "19c089a534ba7f609859825db6babd7938d9bb7fbda4caca4de5f82c85ca9436"), + Hex.to_bytes + (`Hex + "547eb33fc02855f5e466bb1181b7494a5b51c559e777e49448fe090bf2a09b36") ); + ( Hex.to_bytes + (`Hex + "61e7413c434803a9aeb2da070e6c4f33e1e87507b13576fa21191d90d143dd1f"), + Hex.to_bytes + (`Hex + "a3e1f5117eaf42b0da0a840543c3dc724a7aa040f3221feca7af460c14cd4d3d") ); + ( Hex.to_bytes + (`Hex + "63b85aada153166599723a3fa4c50931d98c51acfe89264a254b6f30e528cb32"), + Hex.to_bytes + (`Hex + "32077077f14122ce1af87714bf68c2e97cf5d9bef5c543b6af3eed8f0c8eb31a") ); + ( Hex.to_bytes + (`Hex + "29c95bcf7df437ad20b6a63ccb68c4fe5d62cde260528c3861b447bf9420143e"), + Hex.to_bytes + (`Hex + "d6dbc4b9cc3b91e1fe94d3cb8e016bf548d1d8b28bd8847a1a57d1318bd09510") ); + ( Hex.to_bytes + (`Hex + "a4183ba473da244c1c4f6d8849ad2f199efdb0290022cab9613f0e918ecdc323"), + Hex.to_bytes + (`Hex + "5b99530c2c7b6a44c6d646f7829e40f646f060d6a5f19ad4daa7f7c888669f28") ); + ( Hex.to_bytes + (`Hex + "ea1969f4892f2293af412fd56dceca23ecb7b5a036009f7bf81bf73acc0ea936"), + Hex.to_bytes + (`Hex + "6ee9ed2f5a4d78aca148cce5c20ec7838865bedacd7a3c62c2559f683c4d2e26") ); + ( Hex.to_bytes + (`Hex + "0e13ddd33eb08bc4c0c4e8e38d66dac8784d0e62fb8d9684073a14ef838bd221"), + Hex.to_bytes + (`Hex + "2b519f7cba4107a68f043fb2596bafe96bdd979ae3ff9bb47ce6b5ea7aef3c07") ); + ( Hex.to_bytes + (`Hex + "025cef02bd2e8cbbe7d5a3a86bfb3e9ffd7a2482d6af5edd491dc23496064d0a"), + Hex.to_bytes + (`Hex + "1721457493268bde7591c89a133e278822cefa60113f4dafb0f50c42def72e37") ); + ( Hex.to_bytes + (`Hex + "4fad94e671317a00836499b4437d630b1ee3d971a4d9413fe25f67f759410423"), + Hex.to_bytes + (`Hex + "c322f098d9d989c6eaf3ef96a4044338989686a7fb07f7cd7510f35252aaff00") ); + ( Hex.to_bytes + (`Hex + "0caebd3b5059edc7cfa863f34e0a7107222224251da454b8d1f7718c98d91c36"), + Hex.to_bytes + (`Hex + "5ee81de3a8f5c3d1f572eda2e11ff9616b7a42b447302ad0617f0a14c82aa928") ); + ( Hex.to_bytes + (`Hex + "ef09db68f58f9be61d1bb64584a855a9370ac00bf80f810134b6a12d8774773f"), + Hex.to_bytes + (`Hex + "9e11585f9761fcba024acf941768c88e6b5861eff7b49df732b3e9deff0ecb1e") ); + ( Hex.to_bytes + (`Hex + "026b9a5d511b7c2e635b41bcd95eb86de13178f261c7619ec568e71d077f631d"), + Hex.to_bytes + (`Hex + "fce88aa83b0195b6f59b52561a868760d0c39e44e254e437b1a689a834acf132") ); + ( Hex.to_bytes + (`Hex + "9d8fc89579e9c64511354f36bd137791ec4c37f78ad4b518f321bc82aa50cb1a"), + Hex.to_bytes + (`Hex + "7c13730e1eacb5a0dd332a7c693bcce9b9467f83d6fb433822f0bdda07c3f23a") ); + ( Hex.to_bytes + (`Hex + "af8085b17d5120f3faaeb8da5d76e44eec342ccbc89e876ba79a2cd0610e0418"), + Hex.to_bytes + (`Hex + "d54466ca319a9977378c52dfbb40575cc25c73995bfa6f3cb202e32dcb7f422d") ); + ( Hex.to_bytes + (`Hex + "14d38b244e1f02b76ffc771e7dd4a645b3c047947e17de71958281fc8e6f362c"), + Hex.to_bytes + (`Hex + "be59f73e1c6417d4ea276d3793a4f046943e98a3f38958cc0c6a24950482ca24") ); + ( Hex.to_bytes + (`Hex + "2d02f9fda108414d2aab38fff6c15b44cd67c5088f46342cfbf205b04e22c927"), + Hex.to_bytes + (`Hex + "5858d83a86e37fb6e00a7032c189e735c2729cbe8eea43af420193a57bb9ff35") ); + ( Hex.to_bytes + (`Hex + "eaad3efa779c9c67dde959c17e610c05535d9e270badd0e4d0d2caaca785131c"), + Hex.to_bytes + (`Hex + "9ef9d8768c7505a609c13e23b6095c244fc9defa3f1251999edb1ae132cb060e") ); + ( Hex.to_bytes + (`Hex + "a1e3fa9746c6a6ddbcd2b951803ef4575d45fa2b2616ac05eab46dc414b2e627"), + Hex.to_bytes + (`Hex + "e4ca65722439dfe05b7ad4c3b21ec0093cdc18a7ddd6074b80d6a416b1e66e04") ); + ( Hex.to_bytes + (`Hex + "fb93840d4a882788252ae517bed441b6e5f113ca5ed6bbd1b7f9bd9d7583e614"), + Hex.to_bytes + (`Hex + "d6093e04f227bcc5bc180d74d81b83436c6451db51b9284d064135ae5c92f22f") ); + ( Hex.to_bytes + (`Hex + "65c009a8eab8abd2f74258d54f4c26a56a68ed523368bd368e02d9a220a1033e"), + Hex.to_bytes + (`Hex + "ffbc642ba215cdad4e1d41facffb418b1817c4aa29e77562ca7628a5ddd1f405") ); + ( Hex.to_bytes + (`Hex + "924218dbdf459f25a28827bd219fa38569a42b9d50d04177af7cd3fa8ae42836"), + Hex.to_bytes + (`Hex + "d4edc25209a58cf34f965dface3dc8db0ddc4a705813e5672ab772777f03d72d") ); + ( Hex.to_bytes + (`Hex + "573dbb92bd3893de419460c838724b945542eb6cc05b3de043be0316f60b8928"), + Hex.to_bytes + (`Hex + "c4915bffbedf8d59d86640b0247d1790929562caaa24fe295dee0fd06db51b0e") ); + ( Hex.to_bytes + (`Hex + "c3a231cdd9b1f2802be864533481cafe2678864705847e660424ccdfa52a6a19"), + Hex.to_bytes + (`Hex + "227bcb504eeaf24487252b84a9ac03a27d483fe05e523f9cc83624d6c60fbb1d") ); + ( Hex.to_bytes + (`Hex + "a72e26171df8f8d9bc8bba3e8d21c248ebab2a90c9ac316a8293c6c657be8610"), + Hex.to_bytes + (`Hex + "b03f3844eec4219b1371c6d27c18bbfff99d9c0da086dfbb39ef1569bd0d0019") ); + ( Hex.to_bytes + (`Hex + "83f05071a1e67eb84cbbcac72a17d31da72a537585600d45a9beeaa4f54a870e"), + Hex.to_bytes + (`Hex + "f0bd396a0530d9277524acfa8feafcafd1261eac2bf9ce2755e8f293f2ecce1d") ); + ( Hex.to_bytes + (`Hex + "a6b67cf624f132ecc76f04bba9c06fe74b9d69a8b92fc908191f1336caf0a40a"), + Hex.to_bytes + (`Hex + "8c29f9f53a387ac76a7a618f570c2a6c23576987f483fba8747db12f3893ac0d") ); + ( Hex.to_bytes + (`Hex + "aff7d79b26edaea4658179be905545cf02ba07cac2a566bb3b2fe033fb97712f"), + Hex.to_bytes + (`Hex + "ff55dc2679faf5c675b82c79001dd7b181fc4bb3821b0043ff359d24f9898525") ); + ( Hex.to_bytes + (`Hex + "26c3ea84546986ca8f52057654b4d8641469c8f19813a147968b946633f32606"), + Hex.to_bytes + (`Hex + "1aacdf8c95c69acb565a8cf25d39a251628743017a998229eacd87e53436a020") ); + ( Hex.to_bytes + (`Hex + "87af6aad1538224a14f151fe39c23db2f971761dbc6f44e7416277f2c4b38f00"), + Hex.to_bytes + (`Hex + "e12bcf38bcff35ef2a154b6e67100664ca5543f7651b39cdc42daa8f54aca933") ); + ( Hex.to_bytes + (`Hex + "1aacb71660613eb4bedbdd33fa45172d96b98c15dcc7f2fcda41f522b4d62d22"), + Hex.to_bytes + (`Hex + "71199a6bb68e5fd18cde768b37b45e732fcb1ce209fd9e7ae347d03691680526") ); + ( Hex.to_bytes + (`Hex + "270c7db20e6728a7f4096ed89b85fa0f3e1dca5bdd1d12fc15397092acf5d53e"), + Hex.to_bytes + (`Hex + "b59eb0f39cad662d3f4975391b4a760fe4806cde397d1c3161218e5310a9c510") ); + ( Hex.to_bytes + (`Hex + "9e44fe08552eefd8dc21389bb4f0959792ff561959336d432f5667ffa1c2f02e"), + Hex.to_bytes + (`Hex + "2c259623c05a61eaecf48f2472e5c3d3f815ef359351910853d009c5df7d0b0e") ); + ( Hex.to_bytes + (`Hex + "d13a9b5275745f591aef14e1a29302c2f203874b317918a33181df56fedeb525"), + Hex.to_bytes + (`Hex + "9ac875ce3d6807323e6a66eecc95a30a633a70db4b0d751df2505d6d148ca821") ); + ( Hex.to_bytes + (`Hex + "d05444fe57a1a0f1488ea1b983ea8fe575bd21b3be1e5fe799eb3d26e1cdf02f"), + Hex.to_bytes + (`Hex + "8bd57138cb13ad78154adfde0af90bd75518864a9b4659ceb3f8b0d8f2b9d007") ); + ( Hex.to_bytes + (`Hex + "6081943dc85f8611acf89d7df6cd33ef1608871b1fc8fe7708f2bc818e5ce433"), + Hex.to_bytes + (`Hex + "39808f5f7df59ca78d1e2f18abdbbd461b2de6c3621e1e126b12087a2686ab2a") ); + ( Hex.to_bytes + (`Hex + "264e57924e5f0973abd0c665c5920a803edf338c96739b956e669adbbc0a1217"), + Hex.to_bytes + (`Hex + "a4ddbfdc71dbcea4257145cc12bba92312504450986584491a152d4523a8b915") ); + ( Hex.to_bytes + (`Hex + "b337f8d4c9588118bfd4ea123af5e135729605718010b043f4afaef618bba112"), + Hex.to_bytes + (`Hex + "ffae05648c3ac9d068b8ed214bdb797c0d5885324dab64fed64a964e9b6ef221") ); + ( Hex.to_bytes + (`Hex + "be93bcd82774ad5e10dc40a29bdf741075e483b858f4025eba48711a88945816"), + Hex.to_bytes + (`Hex + "93e4b630a3d620cfcab52a3e5bfc50c04d4b1c5264cad1caa94da94feb999b2d") ); + ( Hex.to_bytes + (`Hex + "c01fab20529e05bf3a0e1e8a2b617d8a8cb3cdf44442deeaf25424818e7f3133"), + Hex.to_bytes + (`Hex + "5e4c9305919b88c8f6977c0a0ec769e5f44891f8c8b9d5442fc7f5685b5a1223") ); + ( Hex.to_bytes + (`Hex + "2814a6f29bbfe49410f389df685790a548bfd7e6c4ea265fef42313a61847717"), + Hex.to_bytes + (`Hex + "44e9a9013da9c5d4b41a82f3b30bf3005c1101905eb0303e01d5620d7d86aa13") ); + ( Hex.to_bytes + (`Hex + "8468d583e66e770dad7fb00c333190c6acb63cd871faf9034e2ef2693f2c5b38"), + Hex.to_bytes + (`Hex + "9c4726f977da2ae5d5f7f9a3dd183240633be00f67ca8a69730da9456fe4e61b") ); + ( Hex.to_bytes + (`Hex + "f3234cb388244fb56c55f3dc0f4df7208351ca876bc429b67d4de597071b053e"), + Hex.to_bytes + (`Hex + "a9c4f4a76bdf45281232c5efb37bd801eb68c3f06f8438743e786895cd4c4c05") ); + ( Hex.to_bytes + (`Hex + "1e60f2ed412b030eaba15626806356caba4a365bf473c1a9c798fe76a4f60b37"), + Hex.to_bytes + (`Hex + "c8237370c8b93ae863e42c92fc12cb681dcde2aaa7cb581dac8573d7bedc4116") ); + ( Hex.to_bytes + (`Hex + "b18c8607b250d9338118b079244d4655cfe7b37063aef8ce9fdf54566f0ddd1e"), + Hex.to_bytes + (`Hex + "7d6df83bd25f19ca870c1d488b7788d804a09c9ab64c1877851739c52284cd18") ); + ( Hex.to_bytes + (`Hex + "a938403c1d06d0d37d333ab36fbad2358c8c48a0d0cc5a2bc855f070f9517731"), + Hex.to_bytes + (`Hex + "44cfdce5462da07d87acfd0004724819ed095279052f5dd3ae40d48fe4667b06") ); + ( Hex.to_bytes + (`Hex + "19623bc5c1f567be4151dc49ebd34d0c72dc3dc8066e85199df3606c344e8005"), + Hex.to_bytes + (`Hex + "ca2e4ee8f8b570d90a0baa6fe7baee8dddcf754c0d4636ceffc2b64ea8300b0c") ); + ( Hex.to_bytes + (`Hex + "37f3da85b4b311d29b8b76d1c9c1af7c9166a06a086d294f50e46e3956176914"), + Hex.to_bytes + (`Hex + "1893b76cbe5e8c9093197a8a3c125e484d5430dc97829cba9f57ad67c8b31b0b") ); + ( Hex.to_bytes + (`Hex + "388e899c6a12bbfd6ae1c724e3b9b0ee7639bda49b64632a672ecf38e38abe2c"), + Hex.to_bytes + (`Hex + "10df874297e2c802365ecbff3a304bfd8026c299645d24fe42096aac03f0d42a") ); + ( Hex.to_bytes + (`Hex + "2e47f25ce4456663f306708c20fa1b58b6538ca62ffc427f853e96a5595c5f3e"), + Hex.to_bytes + (`Hex + "98749517d77cae3fcd170f330df797182496be93a8c4bc0896110a88705ab616") ); + ( Hex.to_bytes + (`Hex + "0064fa6c4ea3b8ec69b037178da62b87d600304d568b2b69f728bdc2326bc81a"), + Hex.to_bytes + (`Hex + "b6ecb84ad77315cd59896fd056d4d810a6a6b840db94d7c4e80122f60514c40f") ); + ( Hex.to_bytes + (`Hex + "29cc86fb214e3cb141a80b225622d46df644099157d35d4836625ce8f337e613"), + Hex.to_bytes + (`Hex + "202595d1d6d23e39d9414d7de0201487a0d54d1bc9e4974f99795693266ee10e") ); + ( Hex.to_bytes + (`Hex + "c4787fb618e8f018d752fe5c76828ec7495272338e102910bb15323e9f77e71c"), + Hex.to_bytes + (`Hex + "ef7df469792c3c0a77b20ac1d35b4a92de00da3f025184a61e35868b7fc64828") ); + ( Hex.to_bytes + (`Hex + "190af46e70005a780c45791e6de19efc31ee138f13beb02115e530eb796e5a20"), + Hex.to_bytes + (`Hex + "92ffcd54367b9b1064d644bb76fd19e2d4cfc6a4f547dc26738e389622009613") ); + ( Hex.to_bytes + (`Hex + "0a7edbdee3ee4f28348674abd6d6a3ebb38887733e136d20d26719084494e206"), + Hex.to_bytes + (`Hex + "26fa5ddd4577f2327e6c1d4369ffb961ddec68d881c35e7b8e991f1b42b46d39") ); + ( Hex.to_bytes + (`Hex + "5a43b30925299ff089620e70727fd85de7e427306b038f42c2c42a85ab38a13b"), + Hex.to_bytes + (`Hex + "c963a6e3f76eeb31ef5e2a2219a5fb662d5fa5d985ea56f07bafc7426e1a9d0f") ); + ( Hex.to_bytes + (`Hex + "4d5c7d5a0fb6d82ed40b2bbb81ec413c57ccd3cfc15162517a25928447f82816"), + Hex.to_bytes + (`Hex + "d23a49dfa0de28105d1fba54e08e649f71504b33a600c3a5cb8d9d4c47d6ec22") ); + ( Hex.to_bytes + (`Hex + "c9b418a64f8878badeb81cefbdcf9024cfa7b849554562622e82d852006cde22"), + Hex.to_bytes + (`Hex + "3bf1b44eb6d874b59174fdc6a87de53aebd26ac59a8451d967bbf58a4327953d") ); + ( Hex.to_bytes + (`Hex + "02e5aea9c9213b422a3759a14f5860b5f32754e152a6e3bd48666a10ee25e913"), + Hex.to_bytes + (`Hex + "d43c51f0c583c0210f67fbbb069ca41ac4de35a920263e0000d3fcfe9b2cd006") ); + ( Hex.to_bytes + (`Hex + "9ddf68399a34ac1bf48c94dd88957a4fda415b42b9b2259c2204066780c3bc34"), + Hex.to_bytes + (`Hex + "6aab7d7608e5432e22d5de3057132e8f7bb99c7b5e425d1ed1a14c3a68c0613b") ); + ( Hex.to_bytes + (`Hex + "b3338ddc1515222f4457cff4d24544874b70247a9c9e39d46dcbaab7cdd0480a"), + Hex.to_bytes + (`Hex + "f8b4ed7694a96532fb34db834c4f35ad6bf583019a97768c4bf33c384a3cc024") ); + ( Hex.to_bytes + (`Hex + "368fde6bde486402cc945b068cc9df47d4657b8f8600ae1b27fcfa49e4ed2537"), + Hex.to_bytes + (`Hex + "adaba0c2742c84075cc6faa13169b09849d6a0c5f5f3a2a0aaf67af0b40ae434") ); + ( Hex.to_bytes + (`Hex + "2d805a98a5824ac0e3f8f20fc211dcf05bab43c342889cf91ebc434960d5fe1e"), + Hex.to_bytes + (`Hex + "877cb172af38732b8a451f13903e767a7e79e7ed8c1a58f54852e5547f886021") ); + ( Hex.to_bytes + (`Hex + "198278bd297906a8a64b6808c2b702456286fa1213a72418c0829cec68eb5f1d"), + Hex.to_bytes + (`Hex + "7e19ffa0d86f0cb5ef17981ac867cb1eade9e2c38e660238c5bdeab8e8bf1f17") ); + ( Hex.to_bytes + (`Hex + "200ba31acb320438f5db8a12769e06723e41f913816230fe3da2c0a3f6fa953d"), + Hex.to_bytes + (`Hex + "0c5f707b6d68915c9af776abab2532a4100e52b0e8ba34152d8a937df7245113") ); + ( Hex.to_bytes + (`Hex + "9aa433073ed4a5d85b68f84d6c16fc5980d51e480b732c6b3987a5b3c9b4740b"), + Hex.to_bytes + (`Hex + "68e94b034cafc3f742b746dad14d0b28f12ba59243637c8121fda40f1972c620") ); + ( Hex.to_bytes + (`Hex + "a9ce8ccc855d9a9be0695f636cdb3a8a841160158cbbe9d9eeb52a296042cc1d"), + Hex.to_bytes + (`Hex + "66696df646c69112dcfaaf6b60d8b2d08e39f221f842e45f0c62eb3542d0971b") ); + ( Hex.to_bytes + (`Hex + "cbb02186ed471191d4137590c5a0d9151457b5f64182b655a818babdcd218f38"), + Hex.to_bytes + (`Hex + "e90bdd57edb6f4d78f712fc7a1dc59c630c2800401b03b671d2b14b034379f08") ); + ( Hex.to_bytes + (`Hex + "d364f06611e2ef3f74fe232b92a61eabd3ed135bb816ccab0297fd5b92581e2f"), + Hex.to_bytes + (`Hex + "0c6e6bcdf55f11e1d3c9626a60608e3b2a9629230a2c712ab5a3c2e51d1f8a39") ); + ( Hex.to_bytes + (`Hex + "27556c51af5ff7b1745d54a911e43418e5489251228f3d5ae4e2e5993b5c9b0c"), + Hex.to_bytes + (`Hex + "78914ccd971b19c5379f1decfd2c1f3d129b74a6b51aea771992501a3775541c") ); + ( Hex.to_bytes + (`Hex + "a3ecf0bd7cbb48ebf9238a3f8faf1838c2525182c62b25126b75916b1c23f220"), + Hex.to_bytes + (`Hex + "df64bc4170b76ce5eb887cecfb3e0765a3e9e3e010fcb84d7ae3d07e8daaf525") ); + ( Hex.to_bytes + (`Hex + "9215b5c574119d983d4f18d323de22bc16920cc3e1e3740d0eef7499e6469f3c"), + Hex.to_bytes + (`Hex + "8fa64e279fbc71cab07787b7d4f40ada525425547f1911e0ce07ad5f241fbc02") ); + ( Hex.to_bytes + (`Hex + "17b081a006e16ef666ed1a14b99fa0bd8f21b2a5d3859b8d0552a09adf446833"), + Hex.to_bytes + (`Hex + "3e28507ac29ecb215e35988a8deb2665d25b5b5a51662546aa31bbeaa2cfcc0d") ); + ( Hex.to_bytes + (`Hex + "7810d5d5dceb01dfa9409745fe4fe7dc6f92d48821c730ecd20bd066bae3f425"), + Hex.to_bytes + (`Hex + "48bd5d3028cfa41ace2fc52941edacf123209d4199ae796aa2dda7abc2cc7a28") ); + ( Hex.to_bytes + (`Hex + "0137e461b167c9f64a3175cf714159ba26d345980cfd66234310552eef75ea07"), + Hex.to_bytes + (`Hex + "b302501d63b36a5f8618f78dd3f1a742b14144e2da5f75b184e8e94781b8d806") ); + ( Hex.to_bytes + (`Hex + "97f76924e10e60770021cf631194289dacd7381ebcd9f594d8f14823eda89d0d"), + Hex.to_bytes + (`Hex + "8143f97e4510cb9d0d25de418e886ff2ff98bea59e56b44db6b183e7fe266e2c") ); + ( Hex.to_bytes + (`Hex + "7ee7688b17215282db0eafda044cb662219bcec56aeffc560fb2a92683216000"), + Hex.to_bytes + (`Hex + "be5758c756f78193d0aab2e92287642c9f89b72297fa1dd2973bd136ab34b337") ); + ( Hex.to_bytes + (`Hex + "7e25acc9a7d2ca1d1e56dedf41bd81f4a19b4fe1595db97ff15f753aaee54f16"), + Hex.to_bytes + (`Hex + "b904ed0480235dd8be670b24caf4a2f0c0e837b139658d323829723cd27a911f") ); + ( Hex.to_bytes + (`Hex + "c8dd1d51691f1a7cbbc6938ad022efaf868efb5d6ede7d6bdf1f1b9bfb141804"), + Hex.to_bytes + (`Hex + "19eede5a8d8d32c28c32aa1f3e23cdfc5d08d2bf62eb4ab774b6dae27a499b34") ); + ( Hex.to_bytes + (`Hex + "408c05de2e4976eefd0d2163a9ce6796784dafbbe7dffb9ffbedf2bb477f4a02"), + Hex.to_bytes + (`Hex + "a6b6c0545394982706937ce9f1045802f8310ff75b7489a5d51ba0d23e758029") ); + ( Hex.to_bytes + (`Hex + "1fcf8dfbea7917c2991ae874683dd4c72502a73d7ae84edfec66c07e64667426"), + Hex.to_bytes + (`Hex + "ff71663e8d43089a33e0f07efdf597256b33e416b3d29034d050e52cb868f10a") ); + ( Hex.to_bytes + (`Hex + "b9d781adce3ae79e872220c4514d7d7fd5212cf7da8ca47e6292057c89aba53b"), + Hex.to_bytes + (`Hex + "621fafe7f62da765016e87ed7970185033f5f8b2ac7b49dd4883ca10e1b10523") ); + ( Hex.to_bytes + (`Hex + "6608816f6e85b87b2c345835a6871029ee2aeca5a1f6970136a982be840e3f2e"), + Hex.to_bytes + (`Hex + "6ed2fede234fd2241f5323e1cbfda3a67a9b59904f5454f588d7052c742c2b1b") ); + ( Hex.to_bytes + (`Hex + "b7615fe7c58caa775d227a2c2cd2b07a336204d9ae0b1a2696fee6df2754ca23"), + Hex.to_bytes + (`Hex + "f1f4e58b26f165396844e0195df0bcfb90daa3dd1a7a20cf9fae58e7b338c12d") ); + ( Hex.to_bytes + (`Hex + "973af151bbd4cde466f147d907b3e00add615495800dc1956ba28cf5cd0d6326"), + Hex.to_bytes + (`Hex + "fbe7257fce7669ecb9b23e6067eff121efd7dc65ae4538b5f0d47534d2e56b00") ); + ( Hex.to_bytes + (`Hex + "b5374dc7f5da37d9d478b0d760ad6f7b8e2e19ccf948a2eaf3619c3f4998ff1b"), + Hex.to_bytes + (`Hex + "b879936971deb41e28c6b084a7ad3116cc74fa060052af00832ac59a480f9714") ); + ( Hex.to_bytes + (`Hex + "6cc37bb0a28c5d585331fbb35b120e6ae5481ca3d8995616cd2e3d2d4328900c"), + Hex.to_bytes + (`Hex + "53059f0aaac3b6370609313b837c5fe7f080ddfe5913280be72ae4781df2ea2a") ); + ( Hex.to_bytes + (`Hex + "bbab98f092b405f9b9fb3d15ad32e7916e956fc23d9bb7230208deb49969a830"), + Hex.to_bytes + (`Hex + "80ce1aef4a1e98abf7767fccb71a6a3ebd24a9b090acfcfcf0d964b31a7b0c29") ); + ( Hex.to_bytes + (`Hex + "102395140359d289029bfee39347f6b8eddd48104c319812475f873fef6af635"), + Hex.to_bytes + (`Hex + "009a0b4eecc9097fe8c5638ba858e5024dd234ebaba2f2dfa53ea561c6042a18") ); + ( Hex.to_bytes + (`Hex + "c0c38d5a489a4977a8540bd6b78b0173d3f434e1ec5a74bd259f96984043e60c"), + Hex.to_bytes + (`Hex + "c95ae8a54aa914b2bf715b2cdb007b3aa73e954ae9971f1fc3bdf290131fdc0f") ); + ( Hex.to_bytes + (`Hex + "4992343612377bfd01e93ea2f6319cb2b0196aabb7098c42c37f4a7fac6edb3e"), + Hex.to_bytes + (`Hex + "fe39d033625fae41ae3f836aad2f1b35d6ab3cdc87de27b0e6fbf48f896b3c1c") ); + ( Hex.to_bytes + (`Hex + "7973d736b4ea79854f6aada70ef67669e0827fbd8604444d336b69d17b08df33"), + Hex.to_bytes + (`Hex + "b1e104773e25aed872cba95c983c806c2ae77371940a764f3eb576a52a3c4917") ); + ( Hex.to_bytes + (`Hex + "a8d2e5bee39c8d0dc77e1614321e113b2924bcf744566a86696b70d65ce6532f"), + Hex.to_bytes + (`Hex + "b95427538da9bcc952ac6033220a201c675f49321f44d18f4ca07a7ba6e79108") ); + ( Hex.to_bytes + (`Hex + "5ee63633c2b0ac3380b25f36b7f7bde99c3524b11c30db3ffc0bfb48a4f85c22"), + Hex.to_bytes + (`Hex + "f537017c5c52d07bac3cf55e9e2ecc256558f633e786bf0afd34d59b37f8ec25") ); + ( Hex.to_bytes + (`Hex + "390d3a43df745919c14566fe55d52af9a305676b69fe22de7fcf8952cd33c630"), + Hex.to_bytes + (`Hex + "b9cd5b21ae06e22d6ff01c5d3a73ba1db607297c620595775f29f85843a4052e") ); + ( Hex.to_bytes + (`Hex + "e2279e0e5a3e8d8cd59a833334aca733f227ca6788ef3a81ea9357aac5825103"), + Hex.to_bytes + (`Hex + "759e190528d37ae38f4d2572b8ec92944f3bd932580d40e4040ede3134f6d723") ); + ( Hex.to_bytes + (`Hex + "c7d27c8b4dfc93ed391013282ae8f92f8274dd8e2f40419b26557ce88a40e82d"), + Hex.to_bytes + (`Hex + "5b6f7890ee7a82846f8aa97acc1aa5fc4176b11fd8c0263b4fce3034a5cf971e") ); + ( Hex.to_bytes + (`Hex + "4b2e30dd6f3fd82862b148df1616338bc6d5beab0b7f66eb2d99002f7d9fb41b"), + Hex.to_bytes + (`Hex + "8f5b755985251b8fa44944ac45562a998e878a3778a7f8c7142f9aaa95d48823") ); + ( Hex.to_bytes + (`Hex + "5ce1a6cc2b83eeb3b0f59cd076092e309005ca0711c9733be5202ae39d723310"), + Hex.to_bytes + (`Hex + "97fbab62c9034d8248daa4fcc30576337bebb1c1925b38d95303d79d3bd5e904") ); + ( Hex.to_bytes + (`Hex + "891bfe2beace312ab2faed3e64789c45f721089adaeb1580388f2eed485d7631"), + Hex.to_bytes + (`Hex + "67a500222ee1d2bb6131c9608e8b7eee7fa11eb5a81350440f603f413deab33f") ); + ( Hex.to_bytes + (`Hex + "9954af65bbe19257db90d1d9ceec8ef3eda1f9ae7f772e78f4897ed4f61a7532"), + Hex.to_bytes + (`Hex + "ac9f9cd757865805aa3f97c759fafc4c25e03a3e9c52ec4690b5fe1cc79f882e") ); + ( Hex.to_bytes + (`Hex + "cf98df27895a364fd490dfe12aad4ddca6a334f5c9f8c7e8b1886f5472db531f"), + Hex.to_bytes + (`Hex + "8e45f36410f721c544caebb413b8f455f7c1c269a1fcbe1f08db6905d0727032") ); + ( Hex.to_bytes + (`Hex + "0ac334455ebf1ce59bac825bfe38119f4067c9648e61e5311fae658008a02616"), + Hex.to_bytes + (`Hex + "2b3b6203ca354f4e66ca434bc74e9e587917399752a8fcadfcb47f30c2c8c93e") ); + ( Hex.to_bytes + (`Hex + "c5fc262b721758e56bbcd757c778d28c138c8356d70e6f21ef67a10c14b2ad2b"), + Hex.to_bytes + (`Hex + "745de4bdac548e7b2bef85f008ee2bf1ba7cb39b38cbbe59053289d23ae5c210") ); + ( Hex.to_bytes + (`Hex + "2b92cca27360bf05f5a661c1b1a140aabef2b3d799a1aae776535bff5a89c82e"), + Hex.to_bytes + (`Hex + "34ad375c6f2aa92154d3304c7e8fd09ef0ddd0736bae920c2485d8f6c9e3af02") ); + ( Hex.to_bytes + (`Hex + "5f44f72e631c64a3e90617ab414401165c6d68d2dde50c5eb2495a5856bd6229"), + Hex.to_bytes + (`Hex + "90c408691239338fc6f2fbf6a10137b37e58a1d595ed5d5bfadc0b9dc9305a17") ); + ( Hex.to_bytes + (`Hex + "ec8489aa5c0b82f90000f7048a6fd58c68c6e642431ebf45830cc8cff25e332b"), + Hex.to_bytes + (`Hex + "4ceb73a99a8c8ed2b85e65c53c638dfc6024f8b18f80f8496ce532c79224df26") ); + ( Hex.to_bytes + (`Hex + "df1510ed4ae102cc321b4861dae6b27a1f7c5979f5ccb8f1d487a5d2761c391f"), + Hex.to_bytes + (`Hex + "78c000c93c8e616106cab85ddad25180597e814aa6bb0cf0a428619979f21202") ); + ( Hex.to_bytes + (`Hex + "2d35d11ea4be12ba064e743038122ac71e52ce7b80464b774419834407f3551b"), + Hex.to_bytes + (`Hex + "56f79971b5053943cd187483d2a218503fe32c48353769c322ed35e9c433d106") ); + ( Hex.to_bytes + (`Hex + "6b9af84255e0d21711994a832c57c463b906e9307d19987c73a71c7b9c0eb81b"), + Hex.to_bytes + (`Hex + "dd82ddf577567f752b18bb5792533060f2463b4911e7e822396307116c9d6224") ); + ( Hex.to_bytes + (`Hex + "fa67480d070027c24c165a8eeda6145adca4fae49b971bf3e12f8aae329c6022"), + Hex.to_bytes + (`Hex + "7a6cba3659cdbecbe039b9dd86778f7623e106e20386e08e5298ad193ebbf114") ); + ( Hex.to_bytes + (`Hex + "8a1f5e86fed0cc3683019b2ff16d2ad1583775808679c18fa65fb2fe92a70a23"), + Hex.to_bytes + (`Hex + "e0bac00ccda5892476464f92d3c50d6f719b349702652aeaed40cd6bb5759625") ); + ( Hex.to_bytes + (`Hex + "b06cce14f6ad11c19200b9ba210eba4ad0ea391ddcd9e99984ea1592c64e841d"), + Hex.to_bytes + (`Hex + "283ad634ce325f66da51f3b4af7f6d1637083a4ac91df271077a02d875ddbd1c") ); + ( Hex.to_bytes + (`Hex + "443407b44f0c16bbf7a400ac613c4f4f8b982b011a273a3c10aed32b60414d1b"), + Hex.to_bytes + (`Hex + "5bb2f7221291f2616423dfd3e7eee6d2969befa1e6246e151994982bf6b4c42c") ); + ( Hex.to_bytes + (`Hex + "525099cf9e37ad900ff12e45065bd3fd4758d6cce19f31327d159b6f5c0ed637"), + Hex.to_bytes + (`Hex + "1136118a6d4b5eef8fe61997ed8af2ff864bc52b04f722000f15a0873917d124") ); + ( Hex.to_bytes + (`Hex + "29df765b04a0b667c572d15d587780d74761471bdaba94fd7579b13b12ef5a05"), + Hex.to_bytes + (`Hex + "5900fdb614790dc4cfc02196e5034bcdb45c1baa593904585c9f3c33937d9e39") ); + ( Hex.to_bytes + (`Hex + "f3a8f36fb63687e9291cd0e27c6b33b6948571e838e1b572942d59f7f01ae339"), + Hex.to_bytes + (`Hex + "9169e9a9d2aa8425f800a057b6c9674d6bf65d24397cef1fce130eb6f561a539") ); + ( Hex.to_bytes + (`Hex + "7d2e9d67b32ba8126e2692cf9d94237946a7da8ed1e097b99d917a93bfd42227"), + Hex.to_bytes + (`Hex + "9173795cfd3ac8dcac9833a73d83a7258b3f0fc03f902ed81ab43f26e67ab220") ); + ( Hex.to_bytes + (`Hex + "abaaec522aec97ef32054cb8730e5664bc9d64211e0f2ef49b423b3e9b762d36"), + Hex.to_bytes + (`Hex + "c7072982d44549a824ebfd9d9a311983479d2f83bd33531beb140e4405468d1a") ); + ( Hex.to_bytes + (`Hex + "84c40e5255f0fe2c8985105ed91a9bd3084b0281a73baf1a0960fe2228c6c339"), + Hex.to_bytes + (`Hex + "ac6732224e89f84579d8f294d40e964228a62e0a7559c391d8b9a22e583f5500") ); + ( Hex.to_bytes + (`Hex + "4ca28d73f497d79d58319033ca7d59278839e1552dcf6925c7ec5a850344353a"), + Hex.to_bytes + (`Hex + "588d2124df53d48cba7bdf396a60b83e042c6d01cdb3b6e159282f12011ec02a") ); + ( Hex.to_bytes + (`Hex + "efbb74eec3beee05207661d2b6be3592fd924fc39be81bbe8bb82c751cf0523e"), + Hex.to_bytes + (`Hex + "53af8acdca51a9f343c37e09e4974ac7229afcbf059e2e0939bae311c85f5a3d") ); + ( Hex.to_bytes + (`Hex + "583a38d52c3de50c2fe7a36c32ebf13e9bfc98768876783cc6c6d249d7ca743e"), + Hex.to_bytes + (`Hex + "d513970cedfa1c1f78183bd4d9cd443cbe8da645e2499ea9902e5767ac8b133d") ); + ( Hex.to_bytes + (`Hex + "2fc76ed735daf783e5069e35e6361b5d0715080e98a1674458fccf12d4e91634"), + Hex.to_bytes + (`Hex + "6577d48e07093027907d2b91b40a22b0c9e919632bbc16b42c349aa1ccd4fa10") ); + ( Hex.to_bytes + (`Hex + "4f8821919427cea6448ee8028fa1a892e9439539d104dfca76177ea27c98f235"), + Hex.to_bytes + (`Hex + "63f8d8e5a31e734f2880cbdac9b1fabed4024eabefd4bd91ec47b86c5e3cea39") ); + ( Hex.to_bytes + (`Hex + "26a5409038d60eba2fce46102d6ae3addabf637d1f03c4074b6df1efe57f0537"), + Hex.to_bytes + (`Hex + "4f7d0f239ada3dcb2ce2c4acc7fac23eca522260c883bc095018907b69c1d701") ); + ( Hex.to_bytes + (`Hex + "8baa62707522160368eb01c378bfe706fee88d518cea455a165ad8fd76f18b1a"), + Hex.to_bytes + (`Hex + "a93d616297ede41d8ec5a5755b262d7c3c49a613e184cfded91a18fcacc95318") ); + ( Hex.to_bytes + (`Hex + "7a855cda90f6f818664c7af4545eaf8b87e45690db5a96c523470bc54f5e410b"), + Hex.to_bytes + (`Hex + "3352c1d18b8e58f74ea01e7b2d51b83bda73dab3100e8237afe05a0126102a2c") ); + ( Hex.to_bytes + (`Hex + "fa3840aba20d91c4b04b1721f60b1989311c70fe4633b61150933f5881fde301"), + Hex.to_bytes + (`Hex + "1e60c198c01761dc1ef85ee47ba2b51a12167ef3163fa252cfe6e297807f0a0b") ); + ( Hex.to_bytes + (`Hex + "a4e78ae72f060b525ee1c515c92afd3c42d5c141820d6f6f329f1360b4bb453d"), + Hex.to_bytes + (`Hex + "79387ac9975cacb12153ab56f2c00cefc66084e16f372a62b5324c37fd7e2905") ); + ( Hex.to_bytes + (`Hex + "0ac65f4c734926c2e6505ab1282f93dad4ce759c13e4e7cc0ccaf384df7e0a2a"), + Hex.to_bytes + (`Hex + "c6e951cf4daee99762ebf834766a6377d784d6151f73dbc180221128a045ae28") ); + ( Hex.to_bytes + (`Hex + "06f96f520479e1485dd21831af96fdd5853e5a297913f21665f0091282666e05"), + Hex.to_bytes + (`Hex + "5348f0180c3b094ded3657c7cfae8cf29ba66f96ba3c240195e1f4a8d169f02b") ); + ( Hex.to_bytes + (`Hex + "188c7a3fa32caba2ee3f2c299e9abf5f6fbfd4629bfbd242a8b21950c4871315"), + Hex.to_bytes + (`Hex + "928f9d70990ade45512d8cf12bc63b01b5a551e477e417dcfacc4827b3e99b18") ); + ( Hex.to_bytes + (`Hex + "973638c3c010d2b11e9f980af01fe9dd0baec4fa1155b1573afba9ed09551534"), + Hex.to_bytes + (`Hex + "a0f2044de4a0360368111df53080380cb6529b35180288db0419293754796916") ); + ( Hex.to_bytes + (`Hex + "46d6152e394d54f7febf5ce7b5852c041e37a3c3e1c78be3fd3f55395449781f"), + Hex.to_bytes + (`Hex + "55fe95ceef03b0b321a2433e20f04734a7a401f1005becd3bbe9cafd55fbaf1d") ); + ( Hex.to_bytes + (`Hex + "7157433be4b222d0a95fae0d7380981f79229deeae1d9ca1e2fb8a1ff1107c2d"), + Hex.to_bytes + (`Hex + "519ec6e5c44d3ee5c3bf3ce77b1cf42a18708b6a3611e0f0bffc778cc844770b") ); + ( Hex.to_bytes + (`Hex + "b9bc403b62bed79e96ebdf5860f6313e0d433163c1905801a96486f1ae7ead21"), + Hex.to_bytes + (`Hex + "0bf657ded685974961286bc41d9c833a9adfcde10eada4aeb2530b1d0e297224") ); + ( Hex.to_bytes + (`Hex + "cfd3b01e84323ea757cdcb16b8c1d25db666c2a9597816acdc5f2fee802fd039"), + Hex.to_bytes + (`Hex + "e508f48123b53df3ce94b6dd64d467a27a3faf83542c0ddefc8ab04ed7d90531") ); + ( Hex.to_bytes + (`Hex + "1c7451aef2d3060f805ab9a45c9d47b7b0891547ab363978ceab73cff77ce117"), + Hex.to_bytes + (`Hex + "a60c397ef0328e22a8164d74e735fe92a7dfd9a11c5e5f232667d63b5b4cdb2a") ); + ( Hex.to_bytes + (`Hex + "4138663266601958049f286b1eb9da240541a46349cf9ab70377b60cc6e5da21"), + Hex.to_bytes + (`Hex + "6e5706647e4823a2b27e67749e9db686e26a8b041d532e7e6705b94664bb9617") ); + ( Hex.to_bytes + (`Hex + "dc041d5645eb906b9aae1c13609443e77432b1d3724e3527f2dbe61c96891b18"), + Hex.to_bytes + (`Hex + "cbeb7d6e74a5934321734b37b057b917fff4eb0a99148ff459add880cca0f02a") ); + ( Hex.to_bytes + (`Hex + "a9c5819a9cd2868a971f1a412f6d93232595fa402a24f6504b0a15c3f1fab005"), + Hex.to_bytes + (`Hex + "951c83ab939a0cc7b1efeacee99ad26e03cfe122b268fec7b4441819d0cf1d38") ); + ( Hex.to_bytes + (`Hex + "d9b7be5d27315a7db6dace25e53de079b4eadc9fdc025a934844117819474d2b"), + Hex.to_bytes + (`Hex + "b21efee2df787376185faac9019391be8ea29647c048ee6093467f7b8c3e242f") ); + ( Hex.to_bytes + (`Hex + "02636a3becfcac58b4ff498ab2ce8c77048a71275df5288cb37d246f86cb4e3c"), + Hex.to_bytes + (`Hex + "86fc3f7bdfd4be7fedf270d4c96c408520020e833d5eef0b8ed77a4574c8602c") ); + ( Hex.to_bytes + (`Hex + "765618f9b7b9b12f85e379f985099c3b3fdf9eb199e2643c1ae2c2f4c703c638"), + Hex.to_bytes + (`Hex + "f934c33b4b4e28b3219ba69c9d4a141ab6b9924979c20c8d85107cd5ca19e60c") ); + ( Hex.to_bytes + (`Hex + "7a6195a6a8d155955e4c6480fe43389fe7c2858dcb3595a46f977ceb1321012d"), + Hex.to_bytes + (`Hex + "b5509164bd72b7b4d51febbd2fd9dd45411bd8414364aaed9202e012c6c16629") ); + ( Hex.to_bytes + (`Hex + "239fd5ffb200956048de58b2ef61c2c0ac00c2517bb9cdcba6704a5b3a2fef0b"), + Hex.to_bytes + (`Hex + "26c273dfcffff969df5d515b1df5863c20e05eef6c402608c9e85f22fe31f005") ); + ( Hex.to_bytes + (`Hex + "6c7319092ed54d31ff39e955eab554f5279f7fd0d8a57577d4afbe57fb43b918"), + Hex.to_bytes + (`Hex + "e7634587741363f5d28c2e62d6a91cbd4ecc1b61066060d0a002f6385e020d36") ); + ( Hex.to_bytes + (`Hex + "b9d32d4e742e9e39ba0c838bf874e343e0f4cd48c4a18942169794b515f36d19"), + Hex.to_bytes + (`Hex + "eb4d3f67d66c88c2d34e9fb82827f221fe48a9d9666d393475bbfe40b45f8910") ); + ( Hex.to_bytes + (`Hex + "4add82fc51a3164350edfc4c507959c95ed1cf843a947372c16ab9c16caaaa15"), + Hex.to_bytes + (`Hex + "6d792b5176d6991bbbdba5cbf1df39ce446d6214a74f1d42695bafdf2a9dad34") ); + ( Hex.to_bytes + (`Hex + "ef6e4a10d1a6ad49cfb7b5cf4f028bcf91cc3b3a9dcc0c84fcdde1644457b929"), + Hex.to_bytes + (`Hex + "80c28c706a71870b3544216f0f803df9ff836a2d673c511dbcf3bdc191d4e60a") ); + ( Hex.to_bytes + (`Hex + "72c1fcf1b0415e47b00bc4690814b709140c586baa2eedc7ae7e5645cedd5a1d"), + Hex.to_bytes + (`Hex + "a9190aed89a905b86ace484a92a0f018ba48676690c37c3784879b5eec7b0101") ); + ( Hex.to_bytes + (`Hex + "d14f4adf9d8624c4778e0615c6e989cb1ead640d9d5f7365a8d2eff31019161a"), + Hex.to_bytes + (`Hex + "b9e2962e44ec2a1cd13c93e7bb6ce2e5330bcfafa5f55241c2afd72cf633bd18") ); + ( Hex.to_bytes + (`Hex + "a362120fd42eef6cb613089a6abe9f629a5e70fd7ae988e1ddbb5e08aeab811c"), + Hex.to_bytes + (`Hex + "cc143dd82de3646b728ed3b712e81c055d95ab9dffe59c7c3a55d57eb2dc112c") ); + ( Hex.to_bytes + (`Hex + "5c7c4365531086a4b59949592835efba5678d58b212dbc6ed8208d8fa8f39411"), + Hex.to_bytes + (`Hex + "440bc602cf1683c52c4f956673dbe8ba74ffc84b4bfe2113c966db5c5dec901f") ); + ( Hex.to_bytes + (`Hex + "1b060b50bc8b783eb4d1407dd5049fa32e3295e60aff75106fd7eb17f2f7e829"), + Hex.to_bytes + (`Hex + "c91f136b790b38bf97453bf50da76464444697dde666267050e68996d1b0fe12") ); + ( Hex.to_bytes + (`Hex + "71495d4e002e13fd7260eab5d20105c5d79e652e52b90292117b4310aa84b23a"), + Hex.to_bytes + (`Hex + "e1f5f770208de04d08c548567db40f55339c7360305a4af7ec48db598cc9523b") ); + ( Hex.to_bytes + (`Hex + "66f29d4dc37265b525e66e2f318dcbd401a50a6f93217ecdb7bcb9e1b5b07331"), + Hex.to_bytes + (`Hex + "2b3836d96703b77ba09f241ae003d5905a29eb21ebfc1a1ddef2b70a8655422a") ); + ( Hex.to_bytes + (`Hex + "8a42dac965ff5bea5453dbea20a5cba4db7b030b43500dd871d4bf173e49f530"), + Hex.to_bytes + (`Hex + "a5db99dd7f0e52a7252aa3d9d06e125d669c3e52c57735f82ad4125f360d9630") ); + ( Hex.to_bytes + (`Hex + "a66a44ac135d9866126e7796262f73b7b150018540b6b71f29a8ace35c045c33"), + Hex.to_bytes + (`Hex + "01aedfbdf8b834114d9e0b11229614fc5a49d2fefe9d2a298c9fd6787447232d") ); + ( Hex.to_bytes + (`Hex + "b9e7e0bf84a397e6618fec7e48e5009680400dd011d9f65c3d9cb47fef9f722f"), + Hex.to_bytes + (`Hex + "eaccb30ecd44276fee750f8582f5a32026f6a94413de5d0a9911ba5a7472ce35") ); + ( Hex.to_bytes + (`Hex + "66a4ad2133e74577c1ea4e9eafb0967e0841fed2d289769059de9a27ec74d70a"), + Hex.to_bytes + (`Hex + "45f930fad22687eb8e752a9536fb9ff55bf17b2797d36cf41e4e88a700e6420e") ); + ( Hex.to_bytes + (`Hex + "397d541ae8c6d74262bda8505f6971b1ba163957935f87fe47f11a9ea1817b2b"), + Hex.to_bytes + (`Hex + "f07c58ebbcf67954ab069ef37c82a155aeaae9d3c40f9c2a82e6199c67b53419") ); + ( Hex.to_bytes + (`Hex + "fb218f0178eb8fe10700a50f7540a5cf8b5e0f9dd5f7e30554371afec14cc92c"), + Hex.to_bytes + (`Hex + "1cae4c8b24f3d2c2dddea9c545777f44689cf632cb26213c5b5da5fbf6cfd208") ); + ( Hex.to_bytes + (`Hex + "12c24c449053d8b5103cf6be9dcf8fe0e3803cfb6a86cce6a40f2fd0e7ff7319"), + Hex.to_bytes + (`Hex + "80e339b674193d43b23b9cd7f5a8e31097f598c733768bc434e443af886a492b") ); + ( Hex.to_bytes + (`Hex + "0a9b46469e5ae36b30f607d157d6fe21628d7babbd0ad3992fe30e4a66180935"), + Hex.to_bytes + (`Hex + "2387382b7bba5404d3ad350544fd4c99821094a6d5e73e5ce257bb161f3a6b3e") ); + ( Hex.to_bytes + (`Hex + "3d27f9f47ae8b6fff0d14f849092b4a3a20341ac7791d9d9e05dad98f8f2a61b"), + Hex.to_bytes + (`Hex + "d2200a0ed0f29921487f691c925dbf47954e42b39d400db5a48f69b90568c80f") ); + ( Hex.to_bytes + (`Hex + "f416d626e672ee36d1e52e8f1e135ca877bcfed5b6494d54fd23df10792d0009"), + Hex.to_bytes + (`Hex + "0b92a74741c68f76f37e9137264dedaf3ca872b962bcef2555e6fea046b6200a") ); + ( Hex.to_bytes + (`Hex + "2c6a0367de093eb86f8a1c9a862de4c6573740a12899cf262bd661bba420a12e"), + Hex.to_bytes + (`Hex + "fdea21b15652aac745fba19199d8a937bd4b3451a8296b0c19fb24f26acc4700") ); + ( Hex.to_bytes + (`Hex + "2f8c6994825b0e9c14ebf7578dab6a245c018bd2f827cc6abbb62e2ec2c3bc14"), + Hex.to_bytes + (`Hex + "84ac0398659ffdbca8f11a7b678c6590349dcafbd7139e77f51d4e32bdf9de0c") ); + ( Hex.to_bytes + (`Hex + "f16190b4dd5db52f60ff8cf4f6c48de1228e951f49179e20c611d8e074e45106"), + Hex.to_bytes + (`Hex + "bbcb3cecc245b6ad1002d3b2c6eaa03594a1433dad2ed94ab68518bc7a0f392e") ); + ( Hex.to_bytes + (`Hex + "8687994af8ecca231833d62b27dbda489977d3b2f940899d8789a505d661fa17"), + Hex.to_bytes + (`Hex + "af8d261de1478fc8bc62ff5512a00dfbca2c83df88cf10ac29abeb19770cf132") ); + ( Hex.to_bytes + (`Hex + "319b27c32f10953178d8a589c5b6feac23a4e8d8b22a679307ba6966c650ac14"), + Hex.to_bytes + (`Hex + "0ee73a0970fc54841697ea7118e2cf83978860253a51878ffd82f3655c844230") ); + ( Hex.to_bytes + (`Hex + "48b962cfe144bde3f9f897f09683a4ac59dd33e5f228e7aa0e7992d202005a20"), + Hex.to_bytes + (`Hex + "58da40633a5747374cc366e608be62c4d10def22bda92b93c2552375d97d053c") ); + ( Hex.to_bytes + (`Hex + "e9c7013bf67abc2177dcbab62a735262af3edaa6d27a36898c64b2a85a222334"), + Hex.to_bytes + (`Hex + "bdcd7ed3b4969fbf1ec2b5a6315788973fd0bd53b0de538e579d418e59f66702") ); + ( Hex.to_bytes + (`Hex + "324ed89925c5ce161a796bf7cf87e90bcb90ed3d24f7e9645b0afdf7457c4b3f"), + Hex.to_bytes + (`Hex + "9b6f5e0a2df54d505ec271c4147ffd0f3532e4f4a6f6f5052f8e9b1bf64ded03") ); + ( Hex.to_bytes + (`Hex + "76b0bcd9cd7e554de47807d29b520854d59bef8333cede58cef1c4807f3be208"), + Hex.to_bytes + (`Hex + "e75f3f1d0a553924dee729c2ba49356f4cc358546381f14f2d5b6cf83310b018") ); + ( Hex.to_bytes + (`Hex + "b6ac90141f98327987baf169c6d132ae2fadde98383e7d48bbe4b91c969d6033"), + Hex.to_bytes + (`Hex + "d942e09d07c1f52d8e33954fd8e25e3a71605d8e541e610f6a4f86b699f54a31") ); + ( Hex.to_bytes + (`Hex + "9c4c34fbda74ec12b0b28c3994c3e786b355410f555e50b304960fd174c28238"), + Hex.to_bytes + (`Hex + "c83c40a7165475041784be18575cc77bbbf0ef5d87cf2572b58ab7e4afa54b35") ); + ( Hex.to_bytes + (`Hex + "6bcf60ae668c28b933616783ed3b018aaf6169a2e7d4d3f90f8a17b73dbf9015"), + Hex.to_bytes + (`Hex + "3bb69de0e56d882931593f59e18deeffb04a4a789cc9106c8fc14e7a400cb808") ); + ( Hex.to_bytes + (`Hex + "646a8476825def07e4831633427566f2a898e0b6b2e5e863153916a1de365d11"), + Hex.to_bytes + (`Hex + "17b88169d4cccbf5c1ac3a5a086e9c731b4ac80ddca2c3438c72c9be0b056130") ); + ( Hex.to_bytes + (`Hex + "9798c484ba9784a77b47116f544adf0bc44fb461c75bd47827bde4015a269c00"), + Hex.to_bytes + (`Hex + "2f442431e288d683287237731041f5da6ca95fa34ee77604cea6c5310cb1bc1c") ); + ( Hex.to_bytes + (`Hex + "41c92574ef095f816eb11faf915beadd5b4d4c6ec08ec4447a34dd094469b23e"), + Hex.to_bytes + (`Hex + "e1367d083b857550d28cb94fed4c37a64d7656fa7104418f31540ae54929492a") ); + ( Hex.to_bytes + (`Hex + "b1c7ca80c594442a204c0cbe62bc805c9da2ee76a6c89b3e5202735389f4e931"), + Hex.to_bytes + (`Hex + "5f79442dcc99c50c69d7bb6d7a2d345f703bb15bac83031e9053cceefab87635") ); + ( Hex.to_bytes + (`Hex + "249a2cf10288730d47fc887a1ad34b579235935d6a3f84fc279cbef8fbf08613"), + Hex.to_bytes + (`Hex + "44f06c290a54235a987a0815f43a92611028cc15cfb4955936f0a05076320617") ); + ( Hex.to_bytes + (`Hex + "0ba9de8555f153262f48a18ad0943dd655d127801547826a4cdab850c502f51d"), + Hex.to_bytes + (`Hex + "37eb62dabebe941c6712b804bc527d0de40400eb33be2f8c2f6135ea840a4004") ); + ( Hex.to_bytes + (`Hex + "36455956528f1b5c5f8297234d4d799b1cba7d0fdfa8debb64552a08f0b2293d"), + Hex.to_bytes + (`Hex + "81c3e8a8bee07a99277e4639892efbd89c74ae326b4ee923f16ed396a7d4be37") ); + ( Hex.to_bytes + (`Hex + "15afa04972fd552b1922bf0086efb684e1258841da2742a7874b48d350dde32d"), + Hex.to_bytes + (`Hex + "af1987013599517c8033adf542c32be1db6fb6d697397147bd8880f01acf8127") ); + ( Hex.to_bytes + (`Hex + "28622ee46785b5d68416abcaeec955baa9bfe2c03eb098b072ab6c2df6925816"), + Hex.to_bytes + (`Hex + "0a750470c2f3ce7cbd0faf87ecb86467da108fb8233e4a95b46e75ed557c6b01") ); + ( Hex.to_bytes + (`Hex + "816a41f4923772154f56874d29d395f9e82e5ccc0e1fd2b0ba22bdd40bc3d027"), + Hex.to_bytes + (`Hex + "730447abc7fd2cdbb90356223dd1f36cca2353b0493b3220922a243af6127438") ); + ( Hex.to_bytes + (`Hex + "3cb844d0380c6a99a5cd925b180609de55a200d5670a43467eac77eb8596f527"), + Hex.to_bytes + (`Hex + "df5ed1df6e239a05631fe6ea5f3161e53ab3a48594a505bbd81eac14badd8532") ); + ( Hex.to_bytes + (`Hex + "c39deb0cd0c049e539aa21b4f67c73d22b3a8f5aa032d6976ca30c8e475f243c"), + Hex.to_bytes + (`Hex + "8b7d4aaa378a0bf2da2320560ce089814781272f54d1ff5a151c90169bd6a203") ); + ( Hex.to_bytes + (`Hex + "b863432a71ecb81d60c02668493a2089dd0a30dae83852ab83fdf90564c0ba1f"), + Hex.to_bytes + (`Hex + "48c73efd6a28ca353a2ad4db71e2744d4b3010e3ff48f71a9c70be6b6448e538") ); + ( Hex.to_bytes + (`Hex + "a54617c480643f9c10ec5596cb115574bac3df9295d9300b95562daa08d2b504"), + Hex.to_bytes + (`Hex + "0b2f80db8a14fae37bf221ccdbde2a6961015e815332bde5b3d7b7746a83ae06") ); + ( Hex.to_bytes + (`Hex + "33823a63e77fa623ac4f717eca4e9afbcd24bda55fef0d956ce3dd6853487a18"), + Hex.to_bytes + (`Hex + "543e66967663d94aab7e444772605b9317baf40c01efd0404eef7be08f8fd62b") ); + ( Hex.to_bytes + (`Hex + "188c7b14a78269e25dbeb9b9c4e67b60efe0dbb37b302de3b0c8d3800b01763a"), + Hex.to_bytes + (`Hex + "928474a66c14a9061b73aa496b2d4bcebb955a4a3d875b79467a76988d77e519") ); + ( Hex.to_bytes + (`Hex + "cafd698328e5c902ec6246d9ed8e6f5488a0bd12268bc4a4532c49cbbcab5135"), + Hex.to_bytes + (`Hex + "f7b4a12904b7bedf6119a90c507343690557d12d5dbcf24c76044d497f164123") ); + ( Hex.to_bytes + (`Hex + "6f35ab8bd567c8ae662697e78934075a875888850be093e5cc1bd88bb78e9832"), + Hex.to_bytes + (`Hex + "bebd27d13b443cca2f23f9cb87dbf6538d407513813c5e92119c48dabbd32f36") ); + ( Hex.to_bytes + (`Hex + "ace34c79d08510600aff2e4269792b164d3218974b7c12fab06e18acba74eb05"), + Hex.to_bytes + (`Hex + "d4dbad3776619cfa49c926965f987bd77a4ea634b7dee453cf93bb9131273311") ); + ( Hex.to_bytes + (`Hex + "3416b40817fbc99692cb242d5ebca6a9703816fd2ba24c8399fc411112ae563e"), + Hex.to_bytes + (`Hex + "939f3f16bc4dbb50933b60ff156f251e6b8a6cb66faa613ec0e3b80621dae200") ); + ( Hex.to_bytes + (`Hex + "13b5b623798bdd429d779ab504bf85eadd721aa050faa9b0f41f7441380ba008"), + Hex.to_bytes + (`Hex + "9bff1e3f14e0cb64b915e767f21245a111361b8dcc3afcd56bee6d7f1fcf1727") ); + ( Hex.to_bytes + (`Hex + "3dc3db0c5e92e3117847c35134d48ebc319b43973c8504731d626c95d37ada1a"), + Hex.to_bytes + (`Hex + "7b91727f05ed0f557860cd7315cf452321f99984debe0fc065332eebfc213539") ); + ( Hex.to_bytes + (`Hex + "35f2a3163cccdc0a03ac858db3dc7626543f323206fac2b76c2668814ec0001b"), + Hex.to_bytes + (`Hex + "8163b2c675f9b82289657f8721f5a064b2b246623439e40d68c967c8630dab10") ); + ( Hex.to_bytes + (`Hex + "10cb4e059f4dff72533c7110c5c6cc28cf7b4036a13c4441e3dc4882548aa13c"), + Hex.to_bytes + (`Hex + "a923f6c40786b574e8b42440ce86cf52b89ea98fde221f0c122817287c9dd106") ); + ( Hex.to_bytes + (`Hex + "1ab4251acb9e2934534f0f43cde2204c8563fa5de78dacd3aa490d299f545d31"), + Hex.to_bytes + (`Hex + "da0191737a7a0a95c515592b17446ed05b8a2cc36bd572884c64f9645da4281f") ); + ( Hex.to_bytes + (`Hex + "5add9c3f2bb862ec0f2689bae068e453638a446640b871bfcaa60e3078257d1a"), + Hex.to_bytes + (`Hex + "43345279e1ead2df433e58904b2853e7ecb23ee070e35038ca41b510421ef224") ); + ( Hex.to_bytes + (`Hex + "6b0539d7f36960399ba90a247d25842f473e2e1d3e6abccb886cf560fd11f232"), + Hex.to_bytes + (`Hex + "d601e7f30adc9389fb1f5f3d087f493c80402e76c398697c6249d84709cdff25") ); + ( Hex.to_bytes + (`Hex + "05055ea07adfeb009a768d8afe73d7325dc794bae04ad7a0b86a19bf28688f02"), + Hex.to_bytes + (`Hex + "3fcba1db6107401221c1ee5a097e39f485c0afcdbe26399a55d922226d6ed111") ); + ( Hex.to_bytes + (`Hex + "fe505ea4c8ea43ebcae4b99f5531e176780d1b3f0471668fa53b2662a364c90d"), + Hex.to_bytes + (`Hex + "ead9f79880a243242d18fc13119d73787e27df30846c2cd6ad77f029f2798139") ); + ( Hex.to_bytes + (`Hex + "a6418be1e1833b3f0e1f99d4d0b779e8a4a357dc9152143a8d421ba5a3640611"), + Hex.to_bytes + (`Hex + "7efc93d75d83cb9aac691d7bbcbb5e69eb774124efbf8d4131c66188590d030e") ); + ( Hex.to_bytes + (`Hex + "174a793dbb1b6c6724180ba3b140f786cdd66e2c3881140488b8a9ac7a266024"), + Hex.to_bytes + (`Hex + "a391dec2e4288e4be77290bbe623b90e4bd61895a1c9a58463f5fec74f852820") ); + ( Hex.to_bytes + (`Hex + "dc5eb3b41b0b55ecf144a0a213e7d69b9b8415e22fd5b71b89e5a8605a4a3b2a"), + Hex.to_bytes + (`Hex + "7b90f9470982db3737ecd0fe5fa90696912adb0691f4a5a47b96448a458ec32d") ); + ( Hex.to_bytes + (`Hex + "6cebf9d9993440ac882ea1f3c4a76d026ba66718ff04fa7da91324e4294e8009"), + Hex.to_bytes + (`Hex + "5f050a3a8c21b551bb346174fdc1dc5d00c453cff0cd9636200c8f7964139435") ); + ( Hex.to_bytes + (`Hex + "4232cb25fc7ca7e688293788f5d7312c85ac07a494902e5680e12226fbefb13a"), + Hex.to_bytes + (`Hex + "57657c59cfbd24b4192267baf948a3edcdd3f2637be31a8c9a092f5a5aedf726") ); + ( Hex.to_bytes + (`Hex + "1272eddd3e8697d2bcbe363e7e2b1bf9b908bf0446d4ffae4ec77cabdd956724"), + Hex.to_bytes + (`Hex + "04f775e9de5313c708044d643d0476b2adde7530ed7f78587aae9b2039e97127") ); + ( Hex.to_bytes + (`Hex + "f9993d37d79add066afa08b65460738ab5339322d37e1134de0221208a7d332e"), + Hex.to_bytes + (`Hex + "33d63ba7d016eec388b2652be9085fd2b9281a30ce086ac2be396f148f353539") ); + ( Hex.to_bytes + (`Hex + "5bceeff60cb55b3f5d4c675fe4326db74bbbd72bf17fa1cab2064db9fdce8d1b"), + Hex.to_bytes + (`Hex + "7820832c14b069a48f47582a69ae174d6b384769eec008cc51482d31a36b2814") ); + ( Hex.to_bytes + (`Hex + "37031aa4e9b33d2f6da2673f237fa4035b35c3bfcffec22881f42ebd0a96bc2b"), + Hex.to_bytes + (`Hex + "862121b1520911c353fcd5480152872e2cda6aa9f69f5c87e5a515d435492302") ); + ( Hex.to_bytes + (`Hex + "fe56e2221584f03626f1b11c964c556dd60febdcc5e6beef0c187ad9ecb1e23d"), + Hex.to_bytes + (`Hex + "669be6aa95ab04539379800c9338ed603e4af56f8d3eb4d99030ba16368efc18") ); + ( Hex.to_bytes + (`Hex + "f069fe4d85d8220838dcf1cc451f5e50848bec7e0a648a62019cc814d3232701"), + Hex.to_bytes + (`Hex + "3677d4d5cbf34e7eac5be5d6bd2f0b850296f318c23b2f6c1ff1dc2870133525") ); + ( Hex.to_bytes + (`Hex + "fea6d23aeb9034a10a314d086311670b1316ca08cb15df8667611c8d67098621"), + Hex.to_bytes + (`Hex + "43903d614b95de58de5c4a9d72a0df4c097500b958f0a4d2fb945ee8636d6026") ); + ( Hex.to_bytes + (`Hex + "59302e5183c3ee1b31b535afef6de4756974fa896c86cb2535c69c70c8a90023"), + Hex.to_bytes + (`Hex + "3addb6d80abafe307ba16c3c9a287bfe9505924f3f766a7a1cf87d78fee36906") ); + ( Hex.to_bytes + (`Hex + "5afbc12b7eaf17237ac5760f3ca8a04ff42a18e950184dad24a709994e299530"), + Hex.to_bytes + (`Hex + "ee1522c02b714cb05d3788c5200f18f193bf7d9fd2debdaa04dcf67f0ea10b17") ); + ( Hex.to_bytes + (`Hex + "5d16116437ca1446ead2f21cff195efe9bf2b7752b7057fd1a32b54e963d1b2d"), + Hex.to_bytes + (`Hex + "d794528cb16fb003af8358a6a7d282d24e25efb3bcb56d13eb9afe61f85e8c2e") ); + ( Hex.to_bytes + (`Hex + "0ffed718aad5cc79c59f847f2ae4fb211cf9a4526bf3286a6904da2d72e61d01"), + Hex.to_bytes + (`Hex + "9cdc532c3097074f85cf2bb009a79d6c53370827a1cdf06b60eb9645faa1ad02") ); + ( Hex.to_bytes + (`Hex + "b7115ed426d9f174a287370e4b97481c08ee6025b1544f578bfa9bffcda6171a"), + Hex.to_bytes + (`Hex + "dd6fc2180a43bd65b444ff5f26f2a706a6d40e3217270f606ba095ac954e3b0c") ); + ( Hex.to_bytes + (`Hex + "6926e626c6af8bb10b297d40c890de340e6858fe7180c947164b20c9e0017412"), + Hex.to_bytes + (`Hex + "45fc922fa5e72d339d1a6b68c6cd17c9688be072fe766cb80fb75a54ca394f0b") ); + ( Hex.to_bytes + (`Hex + "4accb9bc703617c49221640bb8f15cbdfbc2098e026a97183287a4791a657e18"), + Hex.to_bytes + (`Hex + "afc194527d5d69ae54bf13e84c653419ddc23d296fb22c6463da7b5131e02c09") ); + ( Hex.to_bytes + (`Hex + "79bcc9ec078a6276b35ba6aa861fb28c26d2568a23cf09bb1a35a6197b5d1a1c"), + Hex.to_bytes + (`Hex + "af715cfe31879ffecfc6607682808dddf6b47d6046bbfba2f402fa29c4de6c06") ); + ( Hex.to_bytes + (`Hex + "b9facd4d9938bafee9b2a853e0be85016cda1967e34a182d8c4efc9743dede38"), + Hex.to_bytes + (`Hex + "965a4997561a8caff83f6156ef43af1eedfcc444ce2c65fef4f2912d9bf6ca24") ); + ( Hex.to_bytes + (`Hex + "8a88e83f15230e05daeafbd79475d65c9e16fa5fac899058770a79024edb7a2c"), + Hex.to_bytes + (`Hex + "0b3189484c6fe5ac972da849e6a3cb36ef02724d715f3f0ad8b366ecc612e934") ); + ( Hex.to_bytes + (`Hex + "38443c93a68c2d8d613ff35409b6f0d74cf9ed13cce73be986af556b4cbe4a11"), + Hex.to_bytes + (`Hex + "b7221070f162371898a6a2d23d6b11488e18f3a37f8541ea4377ba653818b51f") ); + ( Hex.to_bytes + (`Hex + "78f5a3d8608c82a08f6c3f654f68250a267766dcc49d4d2b1d6581d64820c836"), + Hex.to_bytes + (`Hex + "9cc20a2396916ce21b0718bc7803fb0827a778c5448fa075109cdc249671ee15") ); + ( Hex.to_bytes + (`Hex + "18ccf3d7bf76aafea5e92bffbed0707d99e89f81e3adb7bfa28901827f59800a"), + Hex.to_bytes + (`Hex + "cbab735ef87c0c7cee0406c14039b0ef43ef143d88c5e485b7970a9db2fbfe27") ); + ( Hex.to_bytes + (`Hex + "bebd4f6888a8c6477952190e44212754eaac9c842379b3f6f13433337341f334"), + Hex.to_bytes + (`Hex + "d4daaad26918040a6fb6a6f74d9ca7343a6d1b12e9e17b7bbc09bbb1527f2124") ); + ( Hex.to_bytes + (`Hex + "c040dc3de7fd01fede27e09ddf873167f9842421c80d5021d105bf4ffe906417"), + Hex.to_bytes + (`Hex + "6027de83ccff963e9111696ecc6cd3fff71aa6545b95cee38618a0c2c1701d09") ); + ( Hex.to_bytes + (`Hex + "75603ed1181b0cdf8ca27c6dcdd96036705a855e2a74dbc818b7defcdf635608"), + Hex.to_bytes + (`Hex + "a94bcbbf443bc6dfa3e5dac67a07abe16f100a1df8314a2b1aba413c389de926") ); + ( Hex.to_bytes + (`Hex + "b68ec82219b75ba5fd0176f7d993a92b55b99045c3389def8588b28ad8903c39"), + Hex.to_bytes + (`Hex + "18dc98866c9c672377ed04e2891a75c3c542c02c0af6cca2c9eff531647e1a3b") ); + ( Hex.to_bytes + (`Hex + "2812d8930320aa016a426561b4de65d519a2c323b2c85913eafb6d653b224117"), + Hex.to_bytes + (`Hex + "1766d2998daaa2685ce0958ee3d548325ca9533664e24743402a9e0030ab6a3b") ); + ( Hex.to_bytes + (`Hex + "b7d70bb8f5ca01c4e48dbcbb2f0675d44ed4a95522a388f84d46213bfb8b011a"), + Hex.to_bytes + (`Hex + "8643d21c4e728f5dd4ef40865f53a378a15305490a29ce474c4a733bea7a912a") ); + ( Hex.to_bytes + (`Hex + "096ef299dd894e03a962dae400bdb5451e2788baffdbf3eb0faf98ea9c2bc802"), + Hex.to_bytes + (`Hex + "4fbd6865dea2ca3a4366ed3afccf44551d13592605d1f85234a548f244471f01") ); + ( Hex.to_bytes + (`Hex + "8ea68351549c04e5fddd04fdd076d8b206fa1744da0c66e2ad662f29d1f5c02b"), + Hex.to_bytes + (`Hex + "044de4c7c134fa98546a2cc95adff086866ac6e1bc258a4521745f9ab7ddc636") ); + ( Hex.to_bytes + (`Hex + "f55df9eaceb89b3001eabaa40f4b490172d1e6cc654624a1cde45985eeac1234"), + Hex.to_bytes + (`Hex + "9c03219937800ca029f92626f03fec261561c71e8451427f3fde1151a94d320d") ); + ( Hex.to_bytes + (`Hex + "48c3268414492306aec2fb758a753b92183a1c8a9a4763852690306b89f12202"), + Hex.to_bytes + (`Hex + "669f583a7ab8836304084cc0db22685d265ec8b80d30d53c817fa9f5af87d61e") ); + ( Hex.to_bytes + (`Hex + "5ae0f423d9a976493750f38056d3a98979a6ff200bd8cefc2e8c72e56ac9aa2e"), + Hex.to_bytes + (`Hex + "94a8b135c89e26e384f5d5385d6c34e36815b69e5b99d658ab2c1e183713133b") ); + ( Hex.to_bytes + (`Hex + "5e22ab8f8c3c26d6d60c49c28aaf1161d6867c14296ceff2adc06239894ff527"), + Hex.to_bytes + (`Hex + "86595c18353c42a8a3bf9c7750f8ae706eb7c81f88f428f6fa9d41fe92f29c0a") ); + ( Hex.to_bytes + (`Hex + "3ff51c3ae1087c5361fc2b7b6542df78c635c6ea8aa5002523f199bcc2c9cf0f"), + Hex.to_bytes + (`Hex + "4a1bbe8f470e4731b9e385b418e31e990ebb4230dd473d6327a5b09903816033") ); + ( Hex.to_bytes + (`Hex + "726989f9171da2d72baad7306b6e8b5e05a397eeae735484e518c17c56211631"), + Hex.to_bytes + (`Hex + "81df1eb19f5dcffc00b23ec05877122e2119aaeeb97d045f24f5b37745fc863a") ); + ( Hex.to_bytes + (`Hex + "938448c1c81c939e92e3692513cf0f9022d0b548e9585e76c06469ef2ec3de2e"), + Hex.to_bytes + (`Hex + "d4ebebbfaceb9556ff2164fda874cc9838323119cb5ed8273cda2354b5655310") ); + ( Hex.to_bytes + (`Hex + "edd3702d189822f2ebfb8bb9db0d8edf0b55ef57c2a0ec443aa0994f8e83e212"), + Hex.to_bytes + (`Hex + "71d98e8d7cb0556635c699f7e8b9549de00ab031abf7acd3b4ce9d0434b0b73d") ); + ( Hex.to_bytes + (`Hex + "30f7c6c83a76ba107ac65091b48679ae74a911e4f280ed8289652c0bd622e004"), + Hex.to_bytes + (`Hex + "e4c3ade8a2798c084fd6e160b2bfb1a2a803f550dfea532106c1451f95d77104") ); + ( Hex.to_bytes + (`Hex + "2a1d0a543468afa07d3309a60b5322bc061292ff01747eb2487ace5f470b660f"), + Hex.to_bytes + (`Hex + "911e345de40c2d0de57348629bedd65ea8046f8588b30ddbadec4d6be5130939") ); + ( Hex.to_bytes + (`Hex + "858d3234f4eb1f938f77f313b4dfacb446475a06f0109821ac28eed0e6254b27"), + Hex.to_bytes + (`Hex + "1e0df82acf5dff85aa6ad57375dacf4f17de55f6d610bffeaa3dfbe21eedc40f") ); + ( Hex.to_bytes + (`Hex + "47fb07082b68882c33982a7661e272e5d6e297ddb794a592f19267ae080f0c29"), + Hex.to_bytes + (`Hex + "f2e2bd9f2aa23e9f9d3f48b51ac1287849fc71604dbe9f88ff3134a42a232721") ); + ( Hex.to_bytes + (`Hex + "d27f2fcd6a2750df094c32058a302162e499b63f543f281c03d93a0994bf9126"), + Hex.to_bytes + (`Hex + "33978cffff82f06ac0d86ee3f0faf95f0f6088174af494ce9bc4351c5dd61813") ); + ( Hex.to_bytes + (`Hex + "1cbb89be9a556391a7014977cfbf51521ecf9381e26dfb3e49695bfec3184219"), + Hex.to_bytes + (`Hex + "e0ed3bccc0f4747187467f88c2e35b7320059756f43dab93518612f603d89d0d") ); + ( Hex.to_bytes + (`Hex + "a4ecc31f33e0747f56c8075f48785fd579fd344f42553f4afc64bbe66477480a"), + Hex.to_bytes + (`Hex + "a9537cb01bae467782f14eb5a826d80cf52ea7c790d5d2642fa719db7c9ae734") ); + ( Hex.to_bytes + (`Hex + "fec674992c82e79e62dff8ece696796df04adff52e2b6332e53081b427bef910"), + Hex.to_bytes + (`Hex + "3a62b28a170f72124808256f3bea50a0d4e647999584f10108b542e831d5253e") ); + ( Hex.to_bytes + (`Hex + "cb38f28fac5d201cd70c4673717a0e4ce719494ca1b1b85c1ca36c7f43cc1710"), + Hex.to_bytes + (`Hex + "abcfd7b02993a7c7ef572eb24e0510f99ae3f33ee29b7ea21c47a3ded38f1a22") ); + ( Hex.to_bytes + (`Hex + "1d5156c1aac8a58d1995ad015029f53dd295fefec13c4e6594c5f3f7e8502618"), + Hex.to_bytes + (`Hex + "cc27e24f9057146ade907f380a60dcdbbdd3068936a77fb48b5c5328f47a1929") ); + ( Hex.to_bytes + (`Hex + "5ba192c29047600ec07002b53dbf8d56ded745bb35c9ae548ae5623cd956eb30"), + Hex.to_bytes + (`Hex + "f414d7ce002e0f94bbc6d85d901ad0f38fec9c36b366882122f09e92603cad16") ); + ( Hex.to_bytes + (`Hex + "1fc44664c3e5170c01315964b7ae36bcbb1c9ff82b22b3e6a6659426f707550a"), + Hex.to_bytes + (`Hex + "7cc0b01302928e5d25ef53668020750c48ec719e9cc98a0a7a9c4812fc69ea0c") ); + ( Hex.to_bytes + (`Hex + "e4bf672e25aaf76bb2ef643262dd38f6eb95b87addd3d9c50f40ead5416fcc19"), + Hex.to_bytes + (`Hex + "24a43dc9ac31f9b50bab68f0e628690663851625f0d197aa7e021af4452ec912") ); + ( Hex.to_bytes + (`Hex + "8c2d6f54f603cdb5ccd8b45f8ded8b00345e82de1386cbfb27bfa12774951d32"), + Hex.to_bytes + (`Hex + "7ef65a5d71ef6ef469a9dfd7a56a180754650a724365d8cd4981212d38070901") ); + ( Hex.to_bytes + (`Hex + "f26a1d2f14d00a3b14fc34d2da56d799fb5d4c45c4b1a84529f627ad774fe71e"), + Hex.to_bytes + (`Hex + "0f5a92df64128ff3d718ac05c9818a1942edf424af1c50cc4038d1d41d539e39") ); + ( Hex.to_bytes + (`Hex + "bf6bc8b89ab329b58e672de0daeb8f7d02838eca95d7ae7f2cac02e041a4ed31"), + Hex.to_bytes + (`Hex + "bb6c5568f81e9d61d6ab81a3ed2f8cd8d0dd1f1ea142456893229ca3ca387107") ); + ( Hex.to_bytes + (`Hex + "639cbef20a043c8ee2e1b041c4acfc0c3f36061f752852f7cce3812bbd713200"), + Hex.to_bytes + (`Hex + "8061dc26dbaeadc38679772e137bd62a54de7b0263e0c62da404286ee5daf40a") ); + ( Hex.to_bytes + (`Hex + "2edcd094c9537550a7269a6412400f94db7b07cb3d6f6291978e99ba61906c3c"), + Hex.to_bytes + (`Hex + "453f32074bff78214837a7b4176cbdc73f1f36d3af307e56d29298dc2e0de00f") ); + ( Hex.to_bytes + (`Hex + "8b8371fcf95e3e922fa740d235030f7d3ebbc71b954895194177388bc330ab21"), + Hex.to_bytes + (`Hex + "b22c1c4db852a528f9c67ddb6bb67978c3c307b2a2e4cb66c21f7ece4e325e1c") ); + ( Hex.to_bytes + (`Hex + "e35d6e7a378bea0b88c88f7bbefcade8441554ebff7d436408d798e00171e317"), + Hex.to_bytes + (`Hex + "497518eaee163c5edc4fda5d7bd0bcce171365c361d0efca79f5b0c8acafba08") ); + ( Hex.to_bytes + (`Hex + "60c3dcdfd364450c43b77a62dbd6343c7de5ceaeef66d619b87cb6d17c132c20"), + Hex.to_bytes + (`Hex + "bc1a32c47fc6ee0d83874abc6845cbc50c55caec5114b186772e2048f709f00f") ); + ( Hex.to_bytes + (`Hex + "8b3c05a9e2eb99f29da2df8901134d424b4a0d4964f328ea81d87f33a0a20825"), + Hex.to_bytes + (`Hex + "33bca9168bbf5cd2f0d572a9edc1a1114e317d9dda8aef9cd32ed1badfb4a800") ); + ( Hex.to_bytes + (`Hex + "73199d9aeb9bbe231a89bed69ca7cb0876ca9e0d746d6bfe72c7ad7c3d8af91c"), + Hex.to_bytes + (`Hex + "6713a68ca948b537e9f7b5a96a85177738e385a677edc3bb4f827aa6ad1c2137") ); + ( Hex.to_bytes + (`Hex + "b6906351ff2e8fecaab63570eb812b503e4dfa5df90df2c6495997c12b84190a"), + Hex.to_bytes + (`Hex + "0d61be8f17a30b7605b3bd6a62d570034c2d186ebfae05b0276456ebda19fb0b") ); + ( Hex.to_bytes + (`Hex + "5007fc60795c7e5727730dcaac4255efb2851bce26e1011f3ea8f14fd0424a2a"), + Hex.to_bytes + (`Hex + "b615da054d59fb89676e92c2a7a89f40bcd7d8aa98181df5a1cc1dd54929a211") ); + ( Hex.to_bytes + (`Hex + "fddd546c54ce3aa124c66b3bd0052f4fd6be1b6f2b34d824b0495830fddcf610"), + Hex.to_bytes + (`Hex + "8b2c1eb16c77e445b19f31734078dd2191f3942c299a3d9b4909eb6bc1667624") ); + ( Hex.to_bytes + (`Hex + "d197860f5ba74269b9ffde735535651e4f17cc147752a7ca3f9ed8fd523cd50b"), + Hex.to_bytes + (`Hex + "562a7907ab85bdef09b6e05bd36dee94ad80604cf4ebe2e264f5a46db5f6e737") ); + ( Hex.to_bytes + (`Hex + "2ca8f0da8c9385a71ae00f6b2c05f10f06d545969248a3a30ceee4259f4dfc35"), + Hex.to_bytes + (`Hex + "d0eed5358713d81b102202442b6e3120c8188233e587e41d86acb77bef153926") ); + ( Hex.to_bytes + (`Hex + "25af689d94537072128555bc683aec3145479041b9b22462927fa0bffbd2ae2b"), + Hex.to_bytes + (`Hex + "e7179dc36ead8515e0300979315df4b3ab27ce6d93cff2105b5acca3dc25c73a") ); + ( Hex.to_bytes + (`Hex + "d3e65e79fd99d5168d265a530c7e32a8a0c9d0a2f159f36613ef55c7cfb8430b"), + Hex.to_bytes + (`Hex + "4f7393998cbb1e7778890e7ffa9e2be2f595aaa06e2847f8654ecbf0dc00ab3c") ); + ( Hex.to_bytes + (`Hex + "d65e8193995b0e947284c94a32f958e4966bc6a4b2a97772ff6a7135bb1d9b2a"), + Hex.to_bytes + (`Hex + "fa745f7c61851e1decbd5e2d57d9e004dd360e730f9f7f69ae296b7d63689631") ); + ( Hex.to_bytes + (`Hex + "bace5dbe6a66ecf4703620625475554e56cb37a2b490c0c233e47ad98d22ae32"), + Hex.to_bytes + (`Hex + "98a96ee7b36996ad7c7b57ed9f87e791d7946c9e839d411e0008e3a0ba948d04") ); + ( Hex.to_bytes + (`Hex + "19766a579f7b906c20911c1d9f59b17b0ce929d44de82f3be95acc8aeafbd933"), + Hex.to_bytes + (`Hex + "ec17ca4450ec9a54d22caedbee165d64effe8b9c276ab10af208ec6fb942e83c") ); + ( Hex.to_bytes + (`Hex + "29bc9cb4eaabfe66d01a804ffd431b83779f5ba91fb86389dac8a9339f5bff3f"), + Hex.to_bytes + (`Hex + "f6c0ce3eb3fd46b8c12d862ddeee8f02538483d7a0b8feb684f147ea3efbbf1e") ); + ( Hex.to_bytes + (`Hex + "02d17e18a628d3db08c4b1fae1ba924d5c3fc44da98c36505e7f35919065e903"), + Hex.to_bytes + (`Hex + "be3c645125102969539b56bcf39b88a413f4cd2ce6bf20f04687a20a405e2801") ); + ( Hex.to_bytes + (`Hex + "b612a2b4af35248a8493fa3f8815325102b341c735b559ba145046c5e6794f02"), + Hex.to_bytes + (`Hex + "bdb67d7444078d70b84a56999c0fa04b850d2b802686a1a65f9fbe83b3938011") ); + ( Hex.to_bytes + (`Hex + "413386ac80e8814e52d05ceea5dd99b1bf409e2bdb9efb4b714e82bcf9ccf331"), + Hex.to_bytes + (`Hex + "9aa34c4127ac7ec763802d3e0b9ae77583732c39291622069a54db01a6f93f00") ); + ( Hex.to_bytes + (`Hex + "779919896efea319dc1f2a3aabdcaeca5db071b8fb6f085d0b54a210dad40910"), + Hex.to_bytes + (`Hex + "d2d86ee50bb6523e02552052c062d1a1e240ff9e5f4b1edf5e7d75a483048339") ); + ( Hex.to_bytes + (`Hex + "28fc3efd9e970e8a6889e0942d284949eb6b139c4b9fb2f278ca11f7f37bff10"), + Hex.to_bytes + (`Hex + "2b9a6ffe39a7acf3e189093bdd32a42458889ce6ec37222f9f014864a5827e2d") ); + ( Hex.to_bytes + (`Hex + "7c2fb2b2b425d90d2336b3a52ab2565f4ca891f2e09fd55714bef1302b97090d"), + Hex.to_bytes + (`Hex + "b4d6f852c2d474333bd0d1bdb43c76c062c79bfad7ca75005f3b255a43c53132") ); + ( Hex.to_bytes + (`Hex + "c65e1b365d397ed257aaa35f0bb465bf47d04c737ad4be6e0b525999cb49721c"), + Hex.to_bytes + (`Hex + "38ef1f92e5b8a7da3fee05ad6d2aef96a4180bfce276f1c64d8a757081679f38") ); + ( Hex.to_bytes + (`Hex + "e7ee3e9ee7ca19b7a015b11d780595711a10d4891ddff34bfeb288068a028011"), + Hex.to_bytes + (`Hex + "fa8481c15b6ad4ea59d2d19ef14e2e750f6e42444e468769519e2d84024f760e") ); + ( Hex.to_bytes + (`Hex + "fb7ae3e01b56c84f4381afb7cd7e224e6044303dccade5188a5b905c611e1d1c"), + Hex.to_bytes + (`Hex + "02321afac99f4be89f97a5de738ad264e3acc452782ab7a188e090902e467631") ); + ( Hex.to_bytes + (`Hex + "6e407d42c4583d0773b9a49d4ca6aeeafd989cce6a602bdbf0cf060661ab0d32"), + Hex.to_bytes + (`Hex + "38b767e51760f5f6cf6d0dc8a42f8badc6eec5ac876776effd8cc20c02af4620") ); + ( Hex.to_bytes + (`Hex + "e29345ea8cbee0df57a7012ce67125bfe4cd1f722abd46565adf5e0c6584562e"), + Hex.to_bytes + (`Hex + "e03d23e79b1167c3e2d71983d36459a8b3447277064156bfe33f1cf9a3a0a705") ); + ( Hex.to_bytes + (`Hex + "cfb1bd7eb91f57a1fb4a8494d45870adda34f9fd3e38ff2255a58d6236f5a803"), + Hex.to_bytes + (`Hex + "df83358b60b5a689be3ab64b5b76d893ce395ec789c20766933c13d6c77a4608") ); + ( Hex.to_bytes + (`Hex + "6d59f7c0a50abb09093f310a5e9db7c02ddfc86348aec725f5c4c85778710f34"), + Hex.to_bytes + (`Hex + "5c17bde99909d658cc3d3669e3513c415fccbda5fb08bf4433721042ab43d909") ); + ( Hex.to_bytes + (`Hex + "a3690b19b2e26076ba5a6812bde675a6a3615f344c46c3705c833a2069a2060c"), + Hex.to_bytes + (`Hex + "b84a7f2fb881a95e956b025e6c890c2754791611eb6b0a413f41f9515df4cc25") ); + ( Hex.to_bytes + (`Hex + "8fc26a1a9a8eb6832b8c5ee879902f25237d273f34a3d53d86d3febd7766001f"), + Hex.to_bytes + (`Hex + "394b1ea07c59c221a83ab6ca79b295111c37d5895dc447599af6f27605bcfd0b") ); + ( Hex.to_bytes + (`Hex + "aeaed6f6a5ccaa565d17565bedb6de0048ace3f620099ee9687050faf96d7019"), + Hex.to_bytes + (`Hex + "fb93d8dc5201d168477fb3e51dc8ce05149c1f2c62e0837f357b05ed5d80cb31") ); + ( Hex.to_bytes + (`Hex + "013cf584338940f7913a704bad855da6b49e169c51f188e93745509c6863b739"), + Hex.to_bytes + (`Hex + "3c9d898f8128cc8fedb74e346776099aacb999109aff7ac7409a3fe528f2203c") ); + ( Hex.to_bytes + (`Hex + "2f519904b6025f3e3e7efcb5d035aac677903b9954150d3198e5a7971caf2e3b"), + Hex.to_bytes + (`Hex + "bf424c9b64cbebc719cef210912bf32b8ea2846868b8ebd068e9a495d6435e02") ); + ( Hex.to_bytes + (`Hex + "a377e905ed3a21e589606e36c62391fec755bd4bbfb19dff8743eb7f09f80628"), + Hex.to_bytes + (`Hex + "a33ffcd0d7f9cdf2b76ae8e99be77e274e9c3882f896c9373162adfacf9ed037") ); + ( Hex.to_bytes + (`Hex + "65a13a3d2db1976d4307db9733bda03c4c2aec27f5cdebc6e2c87b5872777f37"), + Hex.to_bytes + (`Hex + "652efd3f30f96325219b1aef2c47e7545249baa409b2f1fd3076ad0994bf5e28") ); + ( Hex.to_bytes + (`Hex + "bb0a4ff8139e0d30d6c88d9c40776dd10597c402db6eb4886dd3dabafbe9c405"), + Hex.to_bytes + (`Hex + "0276adbee85c51f1ae02229b28bb2839d938b5587680dd117479872c478fef0b") ); + ( Hex.to_bytes + (`Hex + "234bdbac76508291015e522bb6aa1d5eab7e00cf94f648d356b02725bf10cc0f"), + Hex.to_bytes + (`Hex + "51cb5892c9acf6804670481e316f5dc18a07ab8b8eb442301b5dab48cf7ff43c") ); + ( Hex.to_bytes + (`Hex + "fd58ce49129e136ce8d9c723f981b004430de58839927a8fbea325b38d3bca1f"), + Hex.to_bytes + (`Hex + "e1efc75b92f22f6995d802b18d355d377eee122146f17773cfacd3742acab922") ); + ( Hex.to_bytes + (`Hex + "9477919458d38dda4b0577896de067e0993e35e8cf65e768c605607c76ae7b2c"), + Hex.to_bytes + (`Hex + "4fe35e4e065d71bfebab4687e1a7999cc4cc165eebe91576faf7ab73b7848e32") ); + ( Hex.to_bytes + (`Hex + "eeb8a37fcefc57fe7a68c2f78c44c2c9d4c2d3ef38bed26fa23c64ad02658802"), + Hex.to_bytes + (`Hex + "5c4d3fb04198c14b0174b0dc82ea0b46b484576c5e4ab295929ca67deef8fb2b") ); + ( Hex.to_bytes + (`Hex + "2c2315c430ac9fd38d41ac3b9ea7dd76bda803cc61506a14c845b0231be6d133"), + Hex.to_bytes + (`Hex + "6761c1a0381d860a76fd253650d703341151fc4dd843145cb834ca436d16c411") ); + ( Hex.to_bytes + (`Hex + "32dcf3730149d0596439c4fe5b8d05ba5ab9396616dd34e9e0cd03bbeac6bb2b"), + Hex.to_bytes + (`Hex + "073d234518cf85eef33ca9e0b64c68eed021ee79ba3b6b25b97b7f0fec242219") ); + ( Hex.to_bytes + (`Hex + "aee7702624420d5e127aa114153e2516eefe065d277719dcdd75053ec3e24519"), + Hex.to_bytes + (`Hex + "347699720f153ad178d8b3aec05f54fbb9fa5b4f6d97f330c2574e96d68de239") ); + ( Hex.to_bytes + (`Hex + "3113ef1de3943863f0177291d2dc8a178338e16b78381d66e22cc86f10a70834"), + Hex.to_bytes + (`Hex + "3fed1bc7442e2c34d670ee09e142de960f8266dd91688985cf7b705d93874107") ); + ( Hex.to_bytes + (`Hex + "1d89dcf2087e0bc11ed0e6d93c91685d03390b094c235ddd4db316a28d5bf015"), + Hex.to_bytes + (`Hex + "57f27acfa0fa62797da452121c18b0aea5e2caf14b6f61122291bd1f04da2223") ); + ( Hex.to_bytes + (`Hex + "54b51049d7d41f6afb2d4ea307118fe3a43e6b80cbf5c668da07568c11474a2b"), + Hex.to_bytes + (`Hex + "2610aa01cbe383c799518f285426615cfd1a7a4ca75a08632cc693602cc5e02b") ); + ( Hex.to_bytes + (`Hex + "3a6784b97f88d8cf7a842d57f54a457dfaca57e46b5eccb8316b14154a5bf005"), + Hex.to_bytes + (`Hex + "dfb9663307b1839b83ad08626e4e647ebeec7f4f6bfff1e7a15a07e207475c31") ); + ( Hex.to_bytes + (`Hex + "609bf47539a47f930087e54008b82b3068265d3f91c139b1558e383f47f7d037"), + Hex.to_bytes + (`Hex + "af51bbe185dec885fea35467a65c8e2473c8f9d44a2ed6fcc7d5a76b6803ff33") ); + ( Hex.to_bytes + (`Hex + "4304fbd5bcad5b5e136635958dd6c478f9ce25e81df93afc1c4f2de187cea70d"), + Hex.to_bytes + (`Hex + "77d37460885ef07e9c60b55208af7f4a8689812fa233090b908655dec5bb6f0d") ); + ( Hex.to_bytes + (`Hex + "32e1ecb5bf0391aa149c6c12ebaa041108666f57c639d50323e3b4c5d2a29722"), + Hex.to_bytes + (`Hex + "bee79c2148c8d660b063cd00e1105ab0884b3f7b17ea9b42bae723f316c91d0c") ); + ( Hex.to_bytes + (`Hex + "f48bb04155af917eb1d65fcef387b77e562bf14588a36d714d6f64ac986e630b"), + Hex.to_bytes + (`Hex + "db133ea4d112b74abf274be2eb520ae6097f552ba5fb6c0536f2cd32f462ac1f") ); + ( Hex.to_bytes + (`Hex + "31e6bdebb715fa2daf63c0a94df920b3376ae8501c60771b76380ad0f52f4c3d"), + Hex.to_bytes + (`Hex + "bc26de4317342a27713c9249594ba5ae83b135c507e84d0ca771c7ae06c86527") ); + ( Hex.to_bytes + (`Hex + "3ae1637b258fec55e89eec66d534fcd57882d09120e3c25623dc3d0e85219116"), + Hex.to_bytes + (`Hex + "8d63e5be834948a1718b92c41beb798a4b9829d0fcd4dfd6e99a2f169836bd2c") ); + ( Hex.to_bytes + (`Hex + "2073c4e3bc051b7a09847e293960a73297a98053e5442f734ea470e84aa32a20"), + Hex.to_bytes + (`Hex + "e774314f6e6f6848e3a112ae5c57ff36a7501b582df49ae025f81c0a37491421") ); + ( Hex.to_bytes + (`Hex + "021183b1772a42dbb19849101dc2f87bf975d69a9cb743ce218918a7c6789d34"), + Hex.to_bytes + (`Hex + "0f089f690fba70308ac1b836e0f634d13faad22ca7d034da20b0c3373e7a4529") ); + ( Hex.to_bytes + (`Hex + "4e771bd26666a16f7c766f0eb1c41fb90bdf6c410184af12a0d1c14ca3430f22"), + Hex.to_bytes + (`Hex + "92f86eb20c062babe21038a5b18a80e50c57133372e46ff3b1593439733bf136") ); + ( Hex.to_bytes + (`Hex + "88b47d94b2eb494e53c27dd9d3042c2417b0fdd7d8d8419fe081ffaddc523c01"), + Hex.to_bytes + (`Hex + "d9ebca54ca7a290a099e34e4deabb0630bf249c78c94d051f4b0559ab08d9a06") ); + ( Hex.to_bytes + (`Hex + "3280f7718ab26f402949fe8229b49e969520c853a124afb1a72365a155322a05"), + Hex.to_bytes + (`Hex + "d2dcc35ab982f198a8f343bf0ced88b022db59c02dfe50f939d56fcdda064014") ); + ( Hex.to_bytes + (`Hex + "1e3f9dacdffe59dab129983e4acb6a22dc8804a58833733a57a43b130af79138"), + Hex.to_bytes + (`Hex + "1fd7f24bd86ec42537e7001be22ff1bf87873f1e7763dcaeacd5efc77cb2d10e") ); + ( Hex.to_bytes + (`Hex + "81ccd3406d51d0c0c9437716160849a6d5c14342c4f442ca5e8b3db25b8fb323"), + Hex.to_bytes + (`Hex + "23fac3dc2ca32aedc302f1fe6334da8c3cce33e406f05a6bb256847f05df2512") ); + ( Hex.to_bytes + (`Hex + "4ce0a056730d9182f0668fc3ac73b6643209039d57f623ddcd7328038dcf912e"), + Hex.to_bytes + (`Hex + "b3d6c0645085946cb0be0a5ed280297a5616b826fbe051b63215409640845a3b") ); + ( Hex.to_bytes + (`Hex + "fbbb71952786dbba35885ea709484b12171c6147a700e7c9cd5b07f257b02009"), + Hex.to_bytes + (`Hex + "696e577fd228f4ed38b4e92961b8db8193ec151ed3ee8efaed0b4e89be9f2611") ); + ( Hex.to_bytes + (`Hex + "1f7f447c1dfef4b1fc5158979d25c4831b601ebfb52c7c11dd0054d9094cd922"), + Hex.to_bytes + (`Hex + "2449d2b59f7d83d6190604f536263b31d648e00849fc632b9cac5305d2de4411") ); + ( Hex.to_bytes + (`Hex + "945342a208b47c38d9534cb29b3679d0c3d4e9d908d0158f9df4c6e2bfc65031"), + Hex.to_bytes + (`Hex + "9d72f7c18f7204048cfc5424bda46778e2128a3e2d53ce415ff38e46a902a31b") ); + ( Hex.to_bytes + (`Hex + "c54eb3c9bf09b33dcc8bca20960f3350e02baa7658c0baa8eb7a53526cb14814"), + Hex.to_bytes + (`Hex + "6f2ad80090ae39c1b54743e2a07682e85baf821e6e9cdd3db87020c01229f636") ); + ( Hex.to_bytes + (`Hex + "8ffd61d8052b0214e6a9b650f589d7413223c86f5d6cd2872e56b695e235f802"), + Hex.to_bytes + (`Hex + "d84af752063cb9be9dcde405c17219e6dd758f677f8d4a886f88c81c06607428") ); + ( Hex.to_bytes + (`Hex + "f258b9c3ca75f1699839b5abeff147674cf44909534cec460e1ee146f2e7ba07"), + Hex.to_bytes + (`Hex + "41dc190c5bd22110f4289794bd367aeaa7c8ea2ccde759a8903925f88c9afc0e") ); + ( Hex.to_bytes + (`Hex + "7ba7a50db91fea5dc6bc4a13b83be1c0d4b2eac95cd338991fcd6ba112558322"), + Hex.to_bytes + (`Hex + "7ead0f1bf3eae99bf971a10c522b91347eacb931008f21072f69c490e8f8740e") ); + ( Hex.to_bytes + (`Hex + "b95fac26e40c4a6b7e7071e13123cf13a16ecd4f2e193985ab01036e53aa8c12"), + Hex.to_bytes + (`Hex + "bafca743b38c6b6e3d3272643a35b2b4a261fda8710867484d1ccabdf8bcc811") ); + ( Hex.to_bytes + (`Hex + "93760c6f6fbb8f8fda9e6f9f9f2ccda8fadaab011d1ef7f8dca11205e0411a30"), + Hex.to_bytes + (`Hex + "8f86809d7b6c70cbf464035c79d2a6f243736bec48e12abfb859c4744b3b3f30") ); + ( Hex.to_bytes + (`Hex + "3b8e07e0c8a5674ccb6b59f287f4115aaab898e4c826d452d6e14645ee81f91b"), + Hex.to_bytes + (`Hex + "ce0ac4f3da9e5bb28ea6f95fe557d84caae50ba59542574c72ef139fd8bc5714") ); + ( Hex.to_bytes + (`Hex + "2350f99a9681496e4dfd85da41adf4a979dadbfcf0d943f67562d62ddf617710"), + Hex.to_bytes + (`Hex + "6ec7afb106bd32fa0ecba21da42f1ce6ede93c049c28704c91d3fbdd5ddd5620") ); + ( Hex.to_bytes + (`Hex + "f48aeba511b3f7e63dc1284fa1decbbbc0486bc02afc2a83d139239a84c48418"), + Hex.to_bytes + (`Hex + "7e1405cf27ea85ae7087d75a54d661a6021ecd23bdb5ff8cb087593d7aa14a0c") ); + ( Hex.to_bytes + (`Hex + "d6c6d220712b0309c6cc6dd05d351f63966b4aef8cc77cf89d9f6fdcd1d7f83e"), + Hex.to_bytes + (`Hex + "d2c9dd4849adce43fc9fca7c0774c32d8d3edb67bddd61acdcde3fd0b8f79702") ); + ( Hex.to_bytes + (`Hex + "0da0baafb50e1c362582c8489c785180222d492616168798a2181f509066513d"), + Hex.to_bytes + (`Hex + "26d13d84fb1b633a2205ebc4d0648c4af37615302e952491c810af798325001a") ); + ( Hex.to_bytes + (`Hex + "436eee1e60d0b3d17c3dcbaf77f7c5c4414feecd65cf90586908a76ccd6dac3b"), + Hex.to_bytes + (`Hex + "c60f7d9cc520f9dd3d2dfe6a0c3a860516f4179376e2d21497b0c7daba6e0a1b") ); + ( Hex.to_bytes + (`Hex + "39aaaa46b64a96131bf354ae7a08ab63205303b98d90986de09ed66e93a5d038"), + Hex.to_bytes + (`Hex + "2a57e3ae45dfad63fe96a83a42228bce075d24c76142c1dda21bf9d4d41c3535") ); + ( Hex.to_bytes + (`Hex + "dde944a76fa0cab557d47056587fe338bb0b6f5467a4dfb494c3e9872118c301"), + Hex.to_bytes + (`Hex + "6fa4861cf31d5c7384873095e7475ac315d7ad1784cd2d0baa2b3ab6e8df6c10") ); + ( Hex.to_bytes + (`Hex + "bb0a070c6d026e1ab232b51562b5a9ac0af35c36955c1ed4dc36c08d02ca8d28"), + Hex.to_bytes + (`Hex + "ed982385ed4d2c663d42121d0abed7b25c8120deb5e3c63e8faf24d061f41f29") ); + ( Hex.to_bytes + (`Hex + "ec276cd166fa9fb02ad79385b022daa120eb54dc409232e68d6744e05479761a"), + Hex.to_bytes + (`Hex + "2704a58509cdfae6b2f7dded988548d3c4bcc8086f30a2d759e41603d5fcf014") ); + ( Hex.to_bytes + (`Hex + "4e6f645bf3c8328fef4deb88fc08aa21349a58de7f5901286604d62a17a4303a"), + Hex.to_bytes + (`Hex + "ee1911e04095067d56731b737c5567c91d2fa483024c5adae0c172c9fb573a3d") ); + ( Hex.to_bytes + (`Hex + "532ae0c3ccf6c1d36812c77edc5f47059d5b9ff1379600f081bd48cafddeff30"), + Hex.to_bytes + (`Hex + "9ac215820994ae91f603eb20d05e3261dc18be0495c70279e2ff6bcb090dd22f") ); + ( Hex.to_bytes + (`Hex + "dc7342d50ba6311a50b1b604c71c7fdb13d0210154c06118a3a5539173c16c20"), + Hex.to_bytes + (`Hex + "d5fb755782cbe9e0dff72475cc49764315cd34210e08d27b717edae288def031") ); + ( Hex.to_bytes + (`Hex + "a5d70b78738172fc5b06bfbc64d6ef7a55e32c0bb7a30bb0dbf5c928a7849936"), + Hex.to_bytes + (`Hex + "17429f83051009cea3587cfec5dc95320ab6a0bd0906a35af2b0bbcd89cf4102") ); + ( Hex.to_bytes + (`Hex + "b129ba9e3119001ba38df926557d16724f7599a705f7cfe72bdcf87050fd9029"), + Hex.to_bytes + (`Hex + "993ec649c4c7ed1e445585ef3826f4bb2ea4f02396cb55f7971de35fe0b0ee01") ); + ( Hex.to_bytes + (`Hex + "a354b1409e1f7ee36d0213ccf0232d65e87e491d9041868eb9b32507669f6406"), + Hex.to_bytes + (`Hex + "f456c083bcdc7ef13f38c13dc3ce63bb36a54f8921613f8e7cb0601c8a2d113c") ); + ( Hex.to_bytes + (`Hex + "12febb56797d3e1abe371d4c39caa9a72ea8c4c9af4a40978a377c3da035aa38"), + Hex.to_bytes + (`Hex + "5dbbe08d5e7d31b6d069bcad179967dc6685f3c7fe71b968957a709989cd8919") ); + ( Hex.to_bytes + (`Hex + "bb9692ba135020b276a7fa3675da582088c04af8e35b360432a00f3b2f7af41a"), + Hex.to_bytes + (`Hex + "8fd5433d9647bf2af1f03d40750d35b25a3efe7706f721a0907b074cadcd2f32") ); + ( Hex.to_bytes + (`Hex + "d4d5e5cb6caea906f6e6a503d7456baa3209bebe8ba7144621ec902cd26bcc18"), + Hex.to_bytes + (`Hex + "b8a0d8fe8d717c964742b3317fbca7952cdae019af1f195a8f48381341c85b11") ); + ( Hex.to_bytes + (`Hex + "85a45e9119ca511dafb71d25f877430b485aeae037fb2508bf9c8c3b2e074815"), + Hex.to_bytes + (`Hex + "294b54abb86beb483aea75ec9cf266ae9cb47a16a24b95317b5f93dbaaaa573d") ); + ( Hex.to_bytes + (`Hex + "974314d49033460cf680f04bdc5283b6450e37076158a1a641d3bcffaa810024"), + Hex.to_bytes + (`Hex + "03a8b346cadfefbb7768040c850eddc364eceb2fe2e8e371fc39a5b5f7eaa908") ); + ( Hex.to_bytes + (`Hex + "b4931bb3b1c2065e75dc20437ca313c37b6f122695a2fc7e4117bf403df8ff0a"), + Hex.to_bytes + (`Hex + "4b1dc8fd4c8fcbc757840cf494fd505a2bf1741e9147d671707c80ee61664115") ); + ( Hex.to_bytes + (`Hex + "615de989f2c3022884ea076cfb773cf33a14f40d0f32c9bb804fc09cdfa36c35"), + Hex.to_bytes + (`Hex + "aa1dd89f2bfa454f6e619971595e477fb5df4ece29df3b7d871f27f96b8dae1d") ); + ( Hex.to_bytes + (`Hex + "2f19947ede873f47b0441112889d93d3eac5101098e73b962ede23df9735ef17"), + Hex.to_bytes + (`Hex + "76dbe355ac8d951e9ced2ed881c6d212cfe05e1d8416d5d34734ea9cdd26c90a") ); + ( Hex.to_bytes + (`Hex + "088b0515c4895868af9713dbe4b0b76d77a75cf64815805b4b085e1444e8c70b"), + Hex.to_bytes + (`Hex + "8a20793f8c4d38e55433fd29e1221f15db21ac275ca9907a55a6022245e4ed19") ); + ( Hex.to_bytes + (`Hex + "893732eefc57d8de336f1d300faafe0b6dbf9b5dd3969cf36f97bffa09839d2a"), + Hex.to_bytes + (`Hex + "6131ee53450f8c5293aa93efccd2ca6d6c99c92e8af004e73f2d0dccda16fd1b") ); + ( Hex.to_bytes + (`Hex + "40360ce471848b18d0769706598601a271059d20e0578dd0ae6454e1bb63901a"), + Hex.to_bytes + (`Hex + "96c097e549908d56c587aa87d07850ddf25e8771d973153cf4239eea1e698e38") ); + ( Hex.to_bytes + (`Hex + "60157093c13fab40f540c82e90a2ce297bf9f7a9950b5dd713c6d8ab7979f00a"), + Hex.to_bytes + (`Hex + "ed9c5305d2ca155c1b096b03430902c65e7f91e5ce782c4cf94ba3f5ffac5919") ); + ( Hex.to_bytes + (`Hex + "b80fc07c6d878dfaa1196d78974a9c5ae9ae9b3b1581be123fd4948578290f1a"), + Hex.to_bytes + (`Hex + "f78de8d4bc1497eda39ed80dd3c034e7f5e16dc859225decaf8f8857f3032213") ); + ( Hex.to_bytes + (`Hex + "938f8404693bb59322cf8cdf0d8c3913424f66a52e116df44086d6f2f5e24100"), + Hex.to_bytes + (`Hex + "607710bc790c05b6acad494bea1550ee6822f4228221e365adc0a9419469cc31") ); + ( Hex.to_bytes + (`Hex + "ab8162eb7cabae94ab56f1d894ca28524e88b91693af5a476db13e6c4a0f8619"), + Hex.to_bytes + (`Hex + "406d8ced8fe9dceb7f304e459782400503674a3f253224d0e35b7df5e4a0f11a") ); + ( Hex.to_bytes + (`Hex + "34e65bb82ea936fa5088b7ea3ded4ab44bc17067d65832be4f636d814151ff35"), + Hex.to_bytes + (`Hex + "2cbdaace1b0c0c502eef8af69b66d6f0729c399404f98dbdd369ad352cefb12d") ); + ( Hex.to_bytes + (`Hex + "0cc1ff585d8bb4c0d28c8ea2be70cae5bdfbab87af9539f477d383d5f6823007"), + Hex.to_bytes + (`Hex + "130d05d5a030621050c34bf3803c6a4b19a396302783fec6f089c20c7f633022") ); + ( Hex.to_bytes + (`Hex + "09b08bc19191e825ad8aa1b2c529f98206972a6a2015853f7c73d71e6142fe25"), + Hex.to_bytes + (`Hex + "f6023ed652c53783b45f100ba977cc738c7aad3b61e5db9440c49fa3b736e726") ); + ( Hex.to_bytes + (`Hex + "4387c0b150b64609658cb81120c0b99d13fff8cbca4d3cfabc2413eb44c8e506"), + Hex.to_bytes + (`Hex + "a170a3a8f9578f3caf1bfce0388bc5373b81c8af1535336b3a579f79f2f5821a") ); + ( Hex.to_bytes + (`Hex + "9b270a42635ea1be1d3512892b28078e7dfd6ad899f78f40e4226ece8e7b8f07"), + Hex.to_bytes + (`Hex + "dfecf1ce99d9bc88ec0be7d4449c3d338eb11a69bdfe35804811a57098a00714") ); + ( Hex.to_bytes + (`Hex + "5faa8425de974c4599a8277a0694c7ee0247d38027d45509ffd643c15997351d"), + Hex.to_bytes + (`Hex + "5c60f61530af16a843a99b68d6711007e1a83cc78a1402db77a765b7ec3ddd05") ); + ( Hex.to_bytes + (`Hex + "2ffb6ad7eb3880db5d32881c9f0ac90df56c22161ec88ccf72a171a77b7c992a"), + Hex.to_bytes + (`Hex + "2fe25521bdd9c2e8a9e98fbda025708a41e8281d92c1e95b3b9c8a5c6387ea12") ); + ( Hex.to_bytes + (`Hex + "3c93b88498225c4e4c99a8b2a0867746305b23c30b90251318ccaea423461e2a"), + Hex.to_bytes + (`Hex + "9bd44b6e2b516c565d0b2f1e1c0f4ea71d6e83553c5543cb46a3306975a1a413") ); + ( Hex.to_bytes + (`Hex + "10222189f0483c50d0865d78327291edfa35fdb995adc2c0f617381e6aca030b"), + Hex.to_bytes + (`Hex + "b6be3bf42e4c854c12c79707e38f25337fd1d771b2652b7bd7fecb59d2450826") ); + ( Hex.to_bytes + (`Hex + "4216ca16659643514dad4f09c577a0faeb147daa69d8c1cb2510c2340a0ff22c"), + Hex.to_bytes + (`Hex + "c6cd2199a9ee36ad410a7f290d371d2e419315096f0857c9af1d1ee210cfcc22") ); + ( Hex.to_bytes + (`Hex + "4cad14c314e644fb7d61d8df0bdb248b269e6a3f6f197dd16477df32d6ffc827"), + Hex.to_bytes + (`Hex + "dc420c39b443caa58b561b6a1f79a2d751b2639c221fa7989d77a9e7030da331") ); + ( Hex.to_bytes + (`Hex + "0d552287e94cb4f4c80a3901228b93ddaaee275223f486fecbadb7adfe8dd231"), + Hex.to_bytes + (`Hex + "dc7bbc74337fdb5a3086b82bb1d10fc11cf45b93e57c28ae9fa354807397202a") ); + ( Hex.to_bytes + (`Hex + "6b14673d3e41e73bbd75172ea9cd57ade9ae71e3c4f95f2c494e332f0e7a811b"), + Hex.to_bytes + (`Hex + "37276dcdfb8d5da1cb8f435f19ce492ad1cf1a1b521b384d3ca2285894ce930e") ); + ( Hex.to_bytes + (`Hex + "a2ce76d45dce511fd4738421cf922fdd6b0b66c731926a66fbb35697aea91a2b"), + Hex.to_bytes + (`Hex + "a3cc158cce9ca946aad960c4cebb85bf2110a44ab8a78a4e4ce52a6a1aa88017") ); + ( Hex.to_bytes + (`Hex + "8ac06895506b7ae182fd4e9e60ae9f25dc4bc43e28d17fafad91a674d3de091c"), + Hex.to_bytes + (`Hex + "d5a45135a3b9df7082c58711ccee2efe561421db26f48685ca0f5093a82ba626") ); + ( Hex.to_bytes + (`Hex + "5866245623cdc35e7fb0fe146b69ab0b251b805b729a0ef780cdc6a17b98ff22"), + Hex.to_bytes + (`Hex + "41ee7c8bb50f08789b9256b93dd84dcec4dd4da7ce39c8ea6da8062bea331723") ); + ( Hex.to_bytes + (`Hex + "1ffe5d684667c8ae68511eb70a0c18c2fa70701a7669768ddb9cfc7ba2c80800"), + Hex.to_bytes + (`Hex + "77ca7198363a4faa6f69adc1a10e4c7b80f9b0fa1052d84edb1b9cb412bd6c3e") ); + ( Hex.to_bytes + (`Hex + "c87be147ea0c6a8f26af9107eb1f6428892b2ac779c1a360f3cbe07c3044ee10"), + Hex.to_bytes + (`Hex + "63a4c0f497dbaa666d57d578dbd702e32f1ecb8794912d488118ad364a4a9a0e") ); + ( Hex.to_bytes + (`Hex + "706498f8295c344c8060f7e1e047f4df70192c06bac0dbf977e27cac9361cd06"), + Hex.to_bytes + (`Hex + "97357d3461a7046104e1a148a1fa80824737372f0a5d11a03bb79e82b850730c") ); + ( Hex.to_bytes + (`Hex + "f003181da041987a30d09dea39a6cd9d14d4fcf21f8c1cd97f4dfc75597eb122"), + Hex.to_bytes + (`Hex + "21dd745461f4eaca0e15354ee9493b9749bccb03e43e201a2c2c3d94e4401220") ); + ( Hex.to_bytes + (`Hex + "51535614d933f175542887004f2196189deafe26e77cd40c6e280570f8266326"), + Hex.to_bytes + (`Hex + "5ff37142263837171f7c0a6e40f9d8c75c9d7f7683d224597d5727310e0fb50e") ); + ( Hex.to_bytes + (`Hex + "4cc139bd5e0fe268cb779fa956697b47ce9970a185983a3173dfa2041d5d861a"), + Hex.to_bytes + (`Hex + "bb6552c1c40f230676e38127d472dd5235664e86f54918a40d2703eb9dc2fa10") ); + ( Hex.to_bytes + (`Hex + "15fb644a95387da5e2ca21744ec609ca7ffe60ec2b5c17f07eac5ab0a1079501"), + Hex.to_bytes + (`Hex + "ac77ab6327dd7560078ab77b9060a01a5f63688cdbbd6aef82f87a1be0b5091b") ); + ( Hex.to_bytes + (`Hex + "c337e01aec724978bdd82647be69425ac76d65e1a219a75683d3da50789c1814"), + Hex.to_bytes + (`Hex + "95eb53ca2bcd5b81f6db5177b4786c55c108201a13fd53f0d268abfe8cc78128") ); + ( Hex.to_bytes + (`Hex + "9e7ae04a131906f3104a6bbd266f06d3fc519ac2ead830d2f0c0ead1f8d06c0e"), + Hex.to_bytes + (`Hex + "b89becacbe27a49f7f69aa8050c22b2a95bd4ddb2f9cf7dbf54322866abb2800") ); + ( Hex.to_bytes + (`Hex + "991896cc498413f06a87bf9e9dac9d373de9cd31d0997febfd08be19855b0b13"), + Hex.to_bytes + (`Hex + "ebba2c42437eeda4f199d0cf65a5bd15088212efae3fe775bc1ff13c27b09611") ); + ( Hex.to_bytes + (`Hex + "e5ba30559ef911c3c067982f9121965e1f7932087961c40ebcca1f79628cb83a"), + Hex.to_bytes + (`Hex + "f346a3d1b2db0ce373d557211b880d3032b062af2b2962e3a1a3f426ea23c402") ); + ( Hex.to_bytes + (`Hex + "155b4af182fb4472a0c580c8f8db161730d104fa0dbb4b131f9716ac4309802c"), + Hex.to_bytes + (`Hex + "315c9a08cad28a97493f6301bd1be6e1d0cb42b6f3aa30332c3d6bbad2c6a109") ); + ( Hex.to_bytes + (`Hex + "bed533bcf34fa5285c3948cf2eb1f63b43907c551bc72d225ba8741f658b4024"), + Hex.to_bytes + (`Hex + "c052af0495086690d115c066f7e8e43584249f65299286a3c76bdf1198317d20") ); + ( Hex.to_bytes + (`Hex + "54c07cd92b72d915f94539624004a4c09c98fd73e5376bb466913aace76c582b"), + Hex.to_bytes + (`Hex + "efdb313f9d2dd6b9a5a7e6b716cd75724d7ad56d44c0858d050553dafca9860d") ); + ( Hex.to_bytes + (`Hex + "27e71620bcc1c36c4b160a18d80d7b611e97619fde39d64ff027ba19d86f4a3d"), + Hex.to_bytes + (`Hex + "d48b57aa0ee813349f76bb635e48167ba24a4c8c2159bb626f58aff857989810") ); + ( Hex.to_bytes + (`Hex + "3de53a2ed2b7334da15a24b77eaf88e896b8760bf3f0e678618e50f8caf0f915"), + Hex.to_bytes + (`Hex + "6acb33e20d4fcebe899bc3d0dfa93febc6cacb4358ff51b3303f20e91ba62a37") ); + ( Hex.to_bytes + (`Hex + "26f2d5a50c4af774b67c03e752b8513791189a75fac8d19a42843424b7b6fd10"), + Hex.to_bytes + (`Hex + "75e416672caad7fc92c3dece46229c4fe397b90136a4aa0610c07ed54b80260a") ); + ( Hex.to_bytes + (`Hex + "364864f181f79f53c6a0993d87dcdcd1890bf18e9673e42d4c33ba82a967f10f"), + Hex.to_bytes + (`Hex + "478e885191ab0db5cb88df97fa55e0c15d75dde0a1e347350aedfb9a5e73282d") ); + ( Hex.to_bytes + (`Hex + "96d689c0098a78a21e710006d9cb29f53e52f81e7abb66cbac2beb34aa17b929"), + Hex.to_bytes + (`Hex + "96bfa48539a67fed6486a4cea4b546bcde3f521691860b2c1774dc7dc243303d") ); + ( Hex.to_bytes + (`Hex + "fcc6456512e76e3cb572649aa3601e3672375a6fc52bfaa44a845dab68096b20"), + Hex.to_bytes + (`Hex + "08ad43ba876ec37cdcb1a6eceb2315f95a941f38dad1a92f43aa6c8ac657ff25") ); + ( Hex.to_bytes + (`Hex + "e02bc2c1a3422677aedab77a08846150e4c3e38982d9ee677973e1123278401c"), + Hex.to_bytes + (`Hex + "01ceb9fccbbe43aa524ab9eafd4a38e5ff33248d324b9c3ea224e5a2ff5a5700") ); + ( Hex.to_bytes + (`Hex + "4f85e15417ce0eeac486c09f9460594466e73dc259675e834d48ecee41abe30b"), + Hex.to_bytes + (`Hex + "e16b016209a6f94849d5b7ef63380919ce39cfacf28f592be9b1a1e57e849d38") ); + ( Hex.to_bytes + (`Hex + "37656b6937c06a93a82813a3b4e560359028cbcfa4fe471f283c57494dbc6b0c"), + Hex.to_bytes + (`Hex + "4687a6fb2f7ec62a38e5b195eed8e18019a39347f037f90f182771a68ba39410") ); + ( Hex.to_bytes + (`Hex + "e3fab8b22cdfc78e89ef2c65e1cb40eb8518dfaa53a32da085e4cb845e88642c"), + Hex.to_bytes + (`Hex + "77e226d9a706f9cc3e5cf557088f7e5df2d57217471b71df33b385f10c26a80c") ); + ( Hex.to_bytes + (`Hex + "072399d91d50baefda860abcbfe2cecb580eca8c66c3a97b28fc3367da7be010"), + Hex.to_bytes + (`Hex + "c3eb7ddf6fe6720ab975a22ad6676af16f2a84aa005ed20370cedbdfbc55c726") ); + ( Hex.to_bytes + (`Hex + "ff2def9a647653181797a4104f4c947f99acf5b9ff8035e2524a7f5fb67f381d"), + Hex.to_bytes + (`Hex + "9ec11fb406699fb56bd24bba26f2e36a0ccbe3d3ca2a7151250e5092abb31930") ); + ( Hex.to_bytes + (`Hex + "ec97138d8cdb0574b2b4b844635c1f3acbea99df5b17163b6649615a36395c0e"), + Hex.to_bytes + (`Hex + "ee263b2a4f822a3cc94d772e14c8b50cf6905fe4f67d48e679e40ae2c571373a") ); + ( Hex.to_bytes + (`Hex + "a9082996a840510fc5c6374699d028ab7d59bbdf2d0c408d2398f2b463fe9a35"), + Hex.to_bytes + (`Hex + "cc7542db14f0c41f3c500454d65f6d133a5286ce439c44088f094e036e007706") ); + ( Hex.to_bytes + (`Hex + "930afcecb74bb57cafa1ba53543bfc64d5866a2e19e653c4179998ac5c033828"), + Hex.to_bytes + (`Hex + "4086f8df39586e0fdf73bc7e824190128a7e1f4a6f3b35474c7f93caada1aa31") ); + ( Hex.to_bytes + (`Hex + "4d532b6dc337439fc30be7ed39bbc43b558a4b10ae79382fc84f7ad971c1b013"), + Hex.to_bytes + (`Hex + "21540c37fad1460d53b7be65287f9783d8df9ee47d7ef4639fa1f317bf468c11") ); + ( Hex.to_bytes + (`Hex + "bf486989cea0ebb4f30c6d65d9982aad8a665c4d1d7451c66f4d42e984bf9e03"), + Hex.to_bytes + (`Hex + "a2816c4778c895e00e689d6768bcc7edf12aed4e2b8563f71b6e8ee9b198e915") ); + ( Hex.to_bytes + (`Hex + "218d282b189a668513da1f0a7f354493edb879a144d772375ab5c04e3485031b"), + Hex.to_bytes + (`Hex + "2104b639ac8d6146b6013cb1885df54e3497c650477c155395037421076e3a2a") ); + ( Hex.to_bytes + (`Hex + "913b994375b7171e3d6f03c4acec3728b48f4d660a0ab45654d5e4e7710f042f"), + Hex.to_bytes + (`Hex + "69c28fb9de51f0cb9694887504a76a5cfebc9f29f8c5fa425b644978cdec4712") ); + ( Hex.to_bytes + (`Hex + "40715f4dad3a3e16a5671074588192b6a28b9f506868b526ffa43f6a3d5cb105"), + Hex.to_bytes + (`Hex + "c71dd0a8a864ab7c0736682d69f23b5b343987674884152aa139041c620f9a25") ); + ( Hex.to_bytes + (`Hex + "f56dfbbdcfeada5b3da4b932d7566effc9aff9ef7b5d574560bb70b3253e5f11"), + Hex.to_bytes + (`Hex + "aa8dc8dabddf75fab3fd396ef793302fff95c57d27e2c1c89d678c14c57ea13e") ); + ( Hex.to_bytes + (`Hex + "d16a93998c5f4724c087781f6263ee5128f629abd0d15e47b7a03024aaff0303"), + Hex.to_bytes + (`Hex + "9d18a5d552a9d21d71424150bfa0cc2227c62c625834b249897ff84036c23001") ); + ( Hex.to_bytes + (`Hex + "281cd7ca5a9cf1aa58787a8b1829b18b6ad6dc922dcee723232f3a8e51374219"), + Hex.to_bytes + (`Hex + "d9d43e4b66eb2ca37367b0f23e682beb073a6e391955f3a64cc31eb64db92b1d") ); + ( Hex.to_bytes + (`Hex + "d90e0bed83de214d3b5ef2a5abdadfbdd5595e4986a4bc0bade3a69d68478516"), + Hex.to_bytes + (`Hex + "256e59e0fb6a048788594a6f21ef4fbf9770215dd0e96a33e5028e75b013210a") ); + ( Hex.to_bytes + (`Hex + "c24ef690194f2a1b6905025d9f84ab56eda9bff7aa071428418b06211ac90106"), + Hex.to_bytes + (`Hex + "3dbc8e80dda015cb56d564c085f3de07d864931e285a6e2d54a19ecb0adc3910") ); + ( Hex.to_bytes + (`Hex + "82ec8f2f05e90aedb25430e52cbd13c19b7703f3fca47a0c08a78ccd29287408"), + Hex.to_bytes + (`Hex + "f0c39978872f8268b3679e5baba6961830636c35995249cd13b6dc3a29eea628") ); + ( Hex.to_bytes + (`Hex + "b15c83355b4d5e4be448a9aa852a027c20d34b8d9b4a1f8ec63fa9a7db94173a"), + Hex.to_bytes + (`Hex + "d359fee0e97255ddcb5a4a52c9d3107b7c64637b822dfdfdac01e5efb5119a0f") ); + ( Hex.to_bytes + (`Hex + "dadf8af866db468a619114d930f11a234d0437a0b8b0fc9a7606d64378ba802f"), + Hex.to_bytes + (`Hex + "acf9b0b386448b7b2a23ff035201b8e9272e6bbf3fb65231cd259a3bdd0a412c") ); + ( Hex.to_bytes + (`Hex + "e59576bef0db6c346ad716ed6af6e367a3606387a2f16104d5a1919fce29180a"), + Hex.to_bytes + (`Hex + "9283c86f2b9a7bf152fd5dbca2a74e2caca265532f0912f59656ceef6d2e5f2c") ); + ( Hex.to_bytes + (`Hex + "d09b0d46f8e1c1a54222b6fbe1ce39b138258527a014e6f591df710923ce3b13"), + Hex.to_bytes + (`Hex + "52daf70097cd9c18ce6547cbf079bf0e111d7d1eef449c7404c2e7bb99ad2f31") ); + ( Hex.to_bytes + (`Hex + "e26b7a91bc8b52e752cf04251eabc20b3140ca092617483a9a527c0ae137e52c"), + Hex.to_bytes + (`Hex + "792dc4f4ef9af76464ed928565dbd89faf9f8688da0442f80c861b3a5c987a37") ); + ( Hex.to_bytes + (`Hex + "fa05d225c6bf3e5d3fffe620b3dafa10ca309ae263f684177396c53abb96692a"), + Hex.to_bytes + (`Hex + "8804d6e6c2a9b63fbf7901a42192b590cbfa28754ba988dc899abd7fd6ee292c") ); + ( Hex.to_bytes + (`Hex + "4cafa674822ca6fefe738c22cf7b8c38d7dd55e919eac7c0cac12b7b0246461e"), + Hex.to_bytes + (`Hex + "013c9ce3e1e009cafcaf7e47ec201a706743e9798edba50fd1043ae7483cfc3c") ); + ( Hex.to_bytes + (`Hex + "794133ebf5cc4cd8c7f8de15981823ce1f8eb57dea8d6ce78a9db4f69f47ca3a"), + Hex.to_bytes + (`Hex + "607a23f16d24f117a62f2f8d8f9d172e4ff63e4213e6d032aec16e8b3d297c06") ); + ( Hex.to_bytes + (`Hex + "198aa7170a0ccd8e88b1607fa67b36713ad6aad12cbf5affb5ed5ed19b095636"), + Hex.to_bytes + (`Hex + "bc9ee2d16310dfc0b55af33deb45ec9aa1cb867b493f716eca5923b51d9f442e") ); + ( Hex.to_bytes + (`Hex + "690ebaaf0e446ea51abe3e43c04afb106dee718d2c395fd9db75f48a9e08ef34"), + Hex.to_bytes + (`Hex + "29eeaf4f6889de9c934645462b7c90d3ef6db29e45c058f89e1996fc3661592a") ); + ( Hex.to_bytes + (`Hex + "4b09a068b88341d34fb224123063c5464b390bdc11ac9f9385ed5fb4dc5d9811"), + Hex.to_bytes + (`Hex + "acbd238c52520345a831790478e28c81680abe33af058b4d4729fe0140b25428") ); + ( Hex.to_bytes + (`Hex + "5727ba9d3b92ea21a4ba6772ee322d106dd95bff178d7ee044cb3b5992fe3905"), + Hex.to_bytes + (`Hex + "da2c98a78ce7a68945fcc1c6ae986a77c520fb5e4eccc1a42cfe5389001e152f") ); + ( Hex.to_bytes + (`Hex + "971db9834150231060ca77882abcfe814cbb3ffe495c2419f374f3e33fa1380d"), + Hex.to_bytes + (`Hex + "de45a144311743d6875f57738bd795cde30929d33f6cd26e2a345fe880836009") ); + ( Hex.to_bytes + (`Hex + "5ec02fbedb8c914295d466b1574acf9aab495ef423c999cae9a1b704ab33a13f"), + Hex.to_bytes + (`Hex + "a04d4d5282a931d7721121038d87ec55cd9224e3edead548987167d157b9ff0c") ); + ( Hex.to_bytes + (`Hex + "c2a429c48aad28f57e92cb8bcd859bd91df1cd3e3f6c3a85b0ec910de9d9b43f"), + Hex.to_bytes + (`Hex + "70a78870bd5c37915dfc6340bd4673bc1ca33419a0b5ee523413c10d9b389735") ); + ( Hex.to_bytes + (`Hex + "0238a3c6bde204db7809becec361964897f59ea4cc61f921422294b3b7c0c80f"), + Hex.to_bytes + (`Hex + "d6be8a94569b858f47237cbba152b172d388b434d582dafcf7dcbfc10b044d3e") ); + ( Hex.to_bytes + (`Hex + "4cfbf8f5d9d7a92464657ada2fe94ba8f69fac1bc0a2107cf99e702ebbec3d34"), + Hex.to_bytes + (`Hex + "54e6fdd72e6438f54b582e43a6fa306dcc2b5628ad02f2181dd2522366710c1a") ); + ( Hex.to_bytes + (`Hex + "6a3fd3141190e808a2288cf4ea62820d466550277b08fe89e6e8aaef7a2f9508"), + Hex.to_bytes + (`Hex + "ad8455950f2863ca22d5a5e803a1bec791e4415413d995b732a0ab62ad13a23a") ); + ( Hex.to_bytes + (`Hex + "a1af6da4e2e34d1541967caf7ecb1befb7489c0b3f1eccc42e2a991aa3147b22"), + Hex.to_bytes + (`Hex + "614afb7190e2e2e7733b2c9efea7f4286ac825193680c82f6af9923d3d37de2c") ); + ( Hex.to_bytes + (`Hex + "c8f4d6a74218196c703d393099ba1da37670063e266c14356b484646479a0338"), + Hex.to_bytes + (`Hex + "c596825949d2af2752d2b2f5aab6f6fcecdf95741eb9225c0765a4df709b572d") ); + ( Hex.to_bytes + (`Hex + "df64764311b1af5025536ffef472851a0e63cfea8bbf8813137609e199376b38"), + Hex.to_bytes + (`Hex + "2ae143915b2f701d8d42f3c57eafc6aaf2521f55116bdc1793e735e8b0387c0f") ); + ( Hex.to_bytes + (`Hex + "463ed49b75bde1c6af0be14152cca0b4abf66ec475ed779b03ff485229f9020c"), + Hex.to_bytes + (`Hex + "25685609245045c41879e1b25cb69609a649b11e0f9f22ec875862442888640c") ); + ( Hex.to_bytes + (`Hex + "18ba9727bd8b12c4085bd369041f47bd64236c84e60a1a027963eaf41e3b0d1e"), + Hex.to_bytes + (`Hex + "789fab1cb28ebdd0e37472fe11e6fb1bded7e310158844f89693aca5bb000b15") ); + ( Hex.to_bytes + (`Hex + "dec069912b2b2e7556162b5aeb7fe4f212794b313178f7616c143015bf36d529"), + Hex.to_bytes + (`Hex + "720cff9a54bb90c82ab4db76e0a47d190652213842016f741e955a4c7ec51225") ); + ( Hex.to_bytes + (`Hex + "6c68aac1456ae6e7671246bd74b4988cdf4cc14c14d4e18a678c5c94fa339f1b"), + Hex.to_bytes + (`Hex + "216b6dad957402981b1bccce29edc8cc44703069510fc8743822063becd24b33") ); + ( Hex.to_bytes + (`Hex + "42458ae44ae3e3e23a2372ee9d9da777993f975dcd2f90926bd87b5380df280e"), + Hex.to_bytes + (`Hex + "9a5b98a1b7f557b2198fc2cb707eddad77bbd311df175bc34c985be8768af428") ); + ( Hex.to_bytes + (`Hex + "837fa57ab964d2c1bad331107d69a7c8bac1c1d6c833541e957a857c6243281a"), + Hex.to_bytes + (`Hex + "3b8038f60570005c3634d13310683c15cfc4ec65fa84ca39a12de3eb6973a536") ); + ( Hex.to_bytes + (`Hex + "d188d61eb7fa3bcb7044dac3b1759d952b3d2e2188cf6bff996b0b99e50eb41a"), + Hex.to_bytes + (`Hex + "438ee5d671ccfc18210d001ccfe1fa5225a2a442c19755feba13a372ab538a0a") ); + ( Hex.to_bytes + (`Hex + "4b8e1654373acef44a4352ec6a54c761e857936866ac707dc8ef7d9a7544121c"), + Hex.to_bytes + (`Hex + "5adb6ea9b62c5f3b4f5d592386e871efe0c9fd5a3674a2e5fe3e74271ff90a11") ); + ( Hex.to_bytes + (`Hex + "95de77e62ae29568c33d7b933d9bbb9f66bdd5d4d9f4c10b8ae7ec1f7fb6f227"), + Hex.to_bytes + (`Hex + "c4efbc50119434726203f5a853578eac6c4628e4418ce3f713cf4d5d5b645e31") ); + ( Hex.to_bytes + (`Hex + "936908e894bb9454e8ef21c45b799a9033f4456b01cb8b03ddd6b6cb3646c42f"), + Hex.to_bytes + (`Hex + "87bbbd0ce06f7fa3060508be06cbae0a6ff34de82fa180dd50e2f97ae084c81d") ); + ( Hex.to_bytes + (`Hex + "0b0e6da5051da4da3c44eb13755ced6f50cdb1654c0e8b7aefb08bed8e7c4f21"), + Hex.to_bytes + (`Hex + "16ea8118d5d949fe371334ed64dd5323d926f1d98e0cb256e80d2b4cb492222c") ); + ( Hex.to_bytes + (`Hex + "bb047c9b4e964da7ec2dc04e5bbb5c339f329469ec7b848ad4c5e70d221ca71a"), + Hex.to_bytes + (`Hex + "93f5f9d6a682b8c3e68a9f251b9ea79b26cc79bd63b7b68a40b7fa34af618321") ); + ( Hex.to_bytes + (`Hex + "6136d55b795eb697388bdcf44bb20b56da1255c0c1dcce165b10f2b4ae6c7115"), + Hex.to_bytes + (`Hex + "257f91aba4b41a3fc72e484e6ef197454b54789fe2b3c443591cbf26c2eebf0a") ); + ( Hex.to_bytes + (`Hex + "d791b64139a7eb9ba3eb089d9be415cf6ebb9b4f652443d4f6b475590cf14225"), + Hex.to_bytes + (`Hex + "1c22c7f3a6c20d411d8238f182ef649e50cb2adfe268073646a9a1a20c28f02a") ); + ( Hex.to_bytes + (`Hex + "cc322525a44daa4018695068f52547a04ae1fcfe448696d085a1a99622ae9105"), + Hex.to_bytes + (`Hex + "23c2e92d56ea9dc5f194628a851b4815a225b6c18da0ac0aa1ddce219acf050f") ); + ( Hex.to_bytes + (`Hex + "cc727650d1b74bd1d53ace526f7f3063723024ad251ee57ca06e7cddac2bdc07"), + Hex.to_bytes + (`Hex + "aeff407cd5c3365809aeb7449e81f54685979ce055fb96b7d15dd5557b73952d") ); + ( Hex.to_bytes + (`Hex + "af821501bfa9dd86446b90361ee4d940a2bf8389aa208757fb8af11806171a2f"), + Hex.to_bytes + (`Hex + "c6a8e4750993f809799f1cbe7d9685efd4bcb732ba18384ab75cb56395128f0a") ); + ( Hex.to_bytes + (`Hex + "382a4ea80f85e5649228cba1d2f9a167dc1a3d6aa9e8b634c0a0d686e3306f2e"), + Hex.to_bytes + (`Hex + "6aff658e173fd1b948785ae2200bfb4fd3e268e6d2dc2f6c9c23faa6549c931e") ); + ( Hex.to_bytes + (`Hex + "f6e7ce796784163360c360557bd06efb5763ff55592f8f4a8d6d7593fc77fb28"), + Hex.to_bytes + (`Hex + "1256cfb2781be2e3887622cbe270d4c84bf2d4e16e0c1b73c2551946ff02cd30") ); + ( Hex.to_bytes + (`Hex + "2691eae5024a9c8edd965e4e8ef1b96f3111496874324c491209aa3524feb518"), + Hex.to_bytes + (`Hex + "758dfc8d920a56497e26113b697b48c99f78421b1dda5e319abf739f0335d435") ); + ( Hex.to_bytes + (`Hex + "622f969f21681000e7e2306b4d2d3139c6c236ad9ab2be94d27307c02853f436"), + Hex.to_bytes + (`Hex + "b5d85d1e410bf3e4d8cb23486f1fe56599f2b6d0d33f7ff4be5651e9f88f2714") ); + ( Hex.to_bytes + (`Hex + "15201ed9add04fe1abfda960d9ccbca272b51cf7b5aa5f718c8c3fe23bed6019"), + Hex.to_bytes + (`Hex + "b075d93292e74d6d90449cf76fd8e0a0d9083c5f8eec7e94b6ee76f1d0f92a16") ); + ( Hex.to_bytes + (`Hex + "4f4e4f64892abe77f81979f92ffdc2da6e33a40a5e412d48eadd5dc2678fb412"), + Hex.to_bytes + (`Hex + "c2fd955456b34714bda646202d1586fa3034b696ee3c480e6b35049f69f90a31") ); + ( Hex.to_bytes + (`Hex + "b290494b8f56d949ed0e436ce9521dffbc7fb60a7ec6ab9dd06bfcdaf0acb815"), + Hex.to_bytes + (`Hex + "e1ebafc8bc2adb04deaeedb802438a851a378396dff97e85a956bcc59267d50e") ); + ( Hex.to_bytes + (`Hex + "b829be97bbc4c88f8893fdc63aec3f720038ce14445b18cc8caf7ceda9310319"), + Hex.to_bytes + (`Hex + "68170c82b08e486e49caf1982c5dcb7f25418e236689c632ccea65b15ed0ca06") ); + ( Hex.to_bytes + (`Hex + "384c4299c073d6056cd3d86544e91c9b990b65f3f4c0924171b84d0885b38333"), + Hex.to_bytes + (`Hex + "dc42b4ab62b1a341ed468325b0867f01b5a2ede383978e45816bd329cbe13e08") ); + ( Hex.to_bytes + (`Hex + "7d767779439576e45f176cf62a7b9ced5ecd415788a533b82cd758cdfbb73d36"), + Hex.to_bytes + (`Hex + "e302f8d9cb9313f38b07432b6c36ebe64e591232dcb4a3bc341b11df7819b108") ); + ( Hex.to_bytes + (`Hex + "6c006f9e05a7ce77ab6608dc7ddb5ba3ea97f1562ef95a716ed8c40545936436"), + Hex.to_bytes + (`Hex + "fccf1da168e4539c2c60dd68670f3e1c77455cd6b877a51be69af667b809421d") ); + ( Hex.to_bytes + (`Hex + "80580fa180530a26e5045ab6ccb81b7a08238bd2fff9a827c3f3beac37fb323a"), + Hex.to_bytes + (`Hex + "549974a3469b4a913581610cfcb9d9fe1ef272a1c93e45fe0fec7857fd909f1c") ); + ( Hex.to_bytes + (`Hex + "083109c261a4109904909eb323d02e2c3b917fa2339b032cec4d779554690e0a"), + Hex.to_bytes + (`Hex + "d89049453db7b9e6ed1e522367ddba4700cca58146e0be402d93ff1e1feab536") ); + ( Hex.to_bytes + (`Hex + "a3f761469803e0d2e151e6097cc179ca38a50b41d34736785d9acb8aa4557c21"), + Hex.to_bytes + (`Hex + "63e2fd046c0bd21b59a36ddc94b6c7021c9a1b8afc9c713abe9b485b2353ff3f") ); + ( Hex.to_bytes + (`Hex + "d216fc66f6d25be2c2759cdba1b199f92d164f79cff6f6d0985f5253de326633"), + Hex.to_bytes + (`Hex + "98e03092793a681ced042ca7257b7c8062e7080c050c4e53b0bab2881f1dc62b") ); + ( Hex.to_bytes + (`Hex + "0638116d02ade16ef8c2690c86cf02c44879d47a980a431b7340e704b0ca2331"), + Hex.to_bytes + (`Hex + "931174af1ec0ac28b5b2653e062c353dab522a3d8881a65d7a516955b34af238") ); + ( Hex.to_bytes + (`Hex + "809a02271c34af6bc12226233dcfd731a37d6f4561e36bb59404475bc207d922"), + Hex.to_bytes + (`Hex + "e1b22193ea081081c10e048b9cc1159e1a0ffda40c86b4c792cef29f5c5bb33f") ); + ( Hex.to_bytes + (`Hex + "5d21c357e9cbb43e18205aaa301cbbe36acedf0464f329680235775eb89b4c1e"), + Hex.to_bytes + (`Hex + "92b65ac3065427f9ebd2f843cfcab3ed8dfa2fe8416f045b2e77e11b90b4c216") ); + ( Hex.to_bytes + (`Hex + "25b3f30db05bf2910e3114bf2e04a29f055ab18b068c0d44b65117115ae00a00"), + Hex.to_bytes + (`Hex + "fc96dce852f2a971fc4748a9940ee9932265e4826d75bd35ad9022092d18d40d") ); + ( Hex.to_bytes + (`Hex + "5a392e158a897dacda33b31a51883e8912181e79b18269f002d065cfc4f3b61f"), + Hex.to_bytes + (`Hex + "38bca2bc04e1c56562a23f113c881bcd5ed4ae5849afbc9672a3b96ed2e74c3c") ); + ( Hex.to_bytes + (`Hex + "ea0290ed0fb47f8676a7ba7c1b04a54098acc4c7a43706c2be8f460ea29d7025"), + Hex.to_bytes + (`Hex + "53fdc04e9f681a6598e0ea4108301e4ad24983ca05ec4d9e9507c65731edcb2f") ); + ( Hex.to_bytes + (`Hex + "d16f17e8601cb5a50f75b9bfe3218f2e41a9748b3ce55cf4997b4ae0361afd04"), + Hex.to_bytes + (`Hex + "f9d45a9bc972a75ceeca93833daa3ceaa60b182820ad08350f072cc569cd7d1b") ); + ( Hex.to_bytes + (`Hex + "0ed2f1b3264e76f0c8e925862e14c718e2dcde7d4f7df751223f2b2350bf7323"), + Hex.to_bytes + (`Hex + "60c68c323dd6b8475dae050ec4f5feda8912c94765a9b5986c0a05099104ad01") ); + ( Hex.to_bytes + (`Hex + "df947f9489a14411ba2210cd16df28e4a8c47634ead96575dcc36512e3a67020"), + Hex.to_bytes + (`Hex + "46e1c9de7d7fdf91e7db9e341c8735910abbe8d0b4dcdb7e158d750509c9900c") ); + ( Hex.to_bytes + (`Hex + "a61e1fb3189d7e49e3b0ec1b395e7a08648c446a9c4ddee8b82285dfad4a1d14"), + Hex.to_bytes + (`Hex + "643caeb7776215ff3ca75b0f96b0553461e8f904e3cf5120d7d6e2528b6ff819") ); + ( Hex.to_bytes + (`Hex + "a4460ceeac3cb29ed67ca7cb93c21ae6af30079c71650ec526d9c90d4f2c2522"), + Hex.to_bytes + (`Hex + "3543202d108fee99d302f63b54c1d90919c5649ed0e3d761f3b827c2bcb83f1b") ); + ( Hex.to_bytes + (`Hex + "3fcb65dfeaa49e6b27eb176722f8fec12c4ff3a02eb869fb4c6c2c92aff39425"), + Hex.to_bytes + (`Hex + "aea9216ab7a231c4aa4c49a74efa4fbaf9c436ab08e34d351b71785dc7964b24") ); + ( Hex.to_bytes + (`Hex + "92514265c3ed6847fefe47a38a8e3566ce73b9e5d5dff4b554f4bf25c551591a"), + Hex.to_bytes + (`Hex + "8afdf58d9a04017edd19d2419028016b12e000e5893e4438776df54a34f2e02b") ); + ( Hex.to_bytes + (`Hex + "3a216018fc741eae2cf286283a3ce43fe1c1beed1e9bfadeaf5f9f4eb65abc31"), + Hex.to_bytes + (`Hex + "13852a5796b119bdc9f226f49be07242f7dd11ae75f82599630dfb539e5bb91f") ); + ( Hex.to_bytes + (`Hex + "2673e80863a736b2a3dce8452eb07489d81033ff04b97505caef044f41ed4703"), + Hex.to_bytes + (`Hex + "d80ab53289fdeb185d51d04e7455a2822a157703bfd635b180989abcdba11934") ); + ( Hex.to_bytes + (`Hex + "00e4428c1407848c6783996172bd8aeed94c515ce9c34efe07cfc80b9a7f7d2b"), + Hex.to_bytes + (`Hex + "d4df6830617f8fe5d47d927182d4c93174fe5edb901e9fa046b5547e57f9122e") ); + ( Hex.to_bytes + (`Hex + "c11456ebf3c1253ddc5a91dbf02fb078bb1a45475a59e4526226285d2b81c020"), + Hex.to_bytes + (`Hex + "7497ffa332e066c1c15c7f883f6121bfb3ac5ae4cc2366661554ae470a678a1f") ); + ( Hex.to_bytes + (`Hex + "b31b94b298ea320e4b17d0d5f6f54000a4657132e7877c130ada9bf9658c1406"), + Hex.to_bytes + (`Hex + "dc7e4df4065e4863ab0780b1a4372b3b6d3b23402e3096fed180caefda9d860c") ); + ( Hex.to_bytes + (`Hex + "f11cd4173e30e374c1d145895650b5b9eec8b0bad6f3caf51618dcdccec0aa20"), + Hex.to_bytes + (`Hex + "76a80cf84b2a5b46074930ebedde657fe277389f80c839cf3b74e57146a38602") ); + ( Hex.to_bytes + (`Hex + "4bb07f1268a150fb03dff504e301f840eb5059c934c0e1b4075df7ca17932611"), + Hex.to_bytes + (`Hex + "ad93be71bd97c5424b2e7df8271b20e234691ca8f5a2f211dfad5b1d530da725") ); + ( Hex.to_bytes + (`Hex + "a43f8d1d12b6c3865ff1a40c83c71449eca786f9e64fea040c7b504a68f42620"), + Hex.to_bytes + (`Hex + "eb667479f3505e4333000eb7b6735c8bbf184a14b64ad97e75d7a9fff091102b") ); + ( Hex.to_bytes + (`Hex + "a585f215d6a5357353469a3755cee365f02a76cc4aed9cc5767f46602c7a2904"), + Hex.to_bytes + (`Hex + "576286023fecf338c0a59ea410f0131eec2eca06bbe8f1da2d925a9bdb3d9d32") ); + ( Hex.to_bytes + (`Hex + "881b3b11f0e70a40d90e9f725add0565c8b46182a6816df4203887e890845024"), + Hex.to_bytes + (`Hex + "2186ea7f5b1eb835866a065ebd93b19ac38f66d2f11292861e0d542b70d0ea15") ); + ( Hex.to_bytes + (`Hex + "da662ef46a8b8c95f5d6141c1f95cddf0af3546fdc07bcb5da56167049d6821d"), + Hex.to_bytes + (`Hex + "f9016ea3e3a7be05be4718466cd9ab77f35f6797d316b5a7bee43ccc765e8517") ); + ( Hex.to_bytes + (`Hex + "5a5ffbb40a310afd6fbb1846c2e15fd084e33d0167e04157f14b9c87d60e7323"), + Hex.to_bytes + (`Hex + "165d4cb9bcf79f7e96fd769fb3565ed70fea6d25b13562556d05084fbe11cd3e") ); + ( Hex.to_bytes + (`Hex + "a68cb7d23844043db0dcf35114db79a615bbb2a26c162b928a773d6e35380711"), + Hex.to_bytes + (`Hex + "e2b73ed65da4ce9526d526e617c6f02a5dd931913735559d773a996b1a16840d") ); + ( Hex.to_bytes + (`Hex + "915161f1c274f84df41f43089a0d97d289f85d529b4bc1669aed228a778a833b"), + Hex.to_bytes + (`Hex + "aecacb06219686672bf63f43980bf2830e97114da9c205ff4c896c590c3fdb32") ); + ( Hex.to_bytes + (`Hex + "b495b7c5176bd2186b3ddf314c019750476fa3a9b754bcc1a42c524249013f00"), + Hex.to_bytes + (`Hex + "5d2b7168731704e7d06e2514173a2a01ba4dc8dae16a0f75ecdca90dace6fa39") ); + ( Hex.to_bytes + (`Hex + "173096c14ffc2200f2a65ab791a86d6e4184c7d960aa658ea89f1a1881f1f02f"), + Hex.to_bytes + (`Hex + "f374a0ea6a64ea0800bebb01ca0993e86424f75536c921004faf8cb3dc5f6f2e") ); + ( Hex.to_bytes + (`Hex + "01c58457d657bf992cb58e7c72bd17705d8f322d1cd319e9b72ff5aaaf43cd0b"), + Hex.to_bytes + (`Hex + "a8e2d4c3a35bd060d20252dff039a1038194e1216e8ac8e5a59b521da4d04a38") ); + ( Hex.to_bytes + (`Hex + "fbc33b6953111fac6408f826543dcb95a717c2911f53c9acd6ba622bab65a037"), + Hex.to_bytes + (`Hex + "98cc28d733285625867adc6be35f7a15966e0317befaa945fb6e843e9a2ea615") ); + ( Hex.to_bytes + (`Hex + "7e7db5606609eb84b6699f6883c1b3bc8d7aa21a0c6b79c1e373776bb012471f"), + Hex.to_bytes + (`Hex + "666fc4f30aa1002e1ee35849a4d9d2d46a6e8c9ff9c9e5aaaac34a6c9c5cfb0f") ); + ( Hex.to_bytes + (`Hex + "3260aae67c42dfeb3acc8f88b0d884228dfef28366819c3fb0d26218d2c3e03b"), + Hex.to_bytes + (`Hex + "82032578e34f68d08f533b56cf85a3296191b007c92a01b41606265fbefae43f") ); + ( Hex.to_bytes + (`Hex + "9ac24d8da786c20b727ccb57c0ba08a8cdd6ade713e2711e110b96957c986b3d"), + Hex.to_bytes + (`Hex + "5a471d7ed3cdace47ce99a8eb2afb1e61b7738dc42793cb41d58765b2c629f0a") ); + ( Hex.to_bytes + (`Hex + "0dd215d3371c6d3432225997b633902f03fd46c49599fa1942fc67b3faa5970e"), + Hex.to_bytes + (`Hex + "803a477b5878f9a4cc9b4858cf723a5c99a22124e4722b81f7be6d41ab99112b") ); + ( Hex.to_bytes + (`Hex + "484e3ab7b3f1075e836b8f6f5f92b019b29c9a7fccc598cf1716399b410d1a0f"), + Hex.to_bytes + (`Hex + "ecfd90f03ec82f6360d68ea15b0e3c2fbfcae74680d890ce59ea2ea40bfdad0c") ); + ( Hex.to_bytes + (`Hex + "2350ab7674cf8c2335001bfb8a884a07eeecebefe856633754db5144971e3e20"), + Hex.to_bytes + (`Hex + "b7d157d8cca85f2084724f279b3771a2fcd82f53668f473d71e7b956be886613") ); + ( Hex.to_bytes + (`Hex + "6f741cbb3db5082bf9590e133263d6deb3110f89707d3eec71a5570594830b07"), + Hex.to_bytes + (`Hex + "bcfe6c00852c20934d5bc63f93369f67e1062a0d30f012ea2c792f802347112e") ); + ( Hex.to_bytes + (`Hex + "47e2672e5ce86f356d5f00a35e770d1d6cc1d0bbc664f880f0e94e11a0ed7a31"), + Hex.to_bytes + (`Hex + "5504fc4b8945a6cd1f3c88ac763afcf9ec288d7908a2f661499bc2a8e91b022c") ); + ( Hex.to_bytes + (`Hex + "89bec5f537a17a715b9802315953289050075a2c330bfc4f533a84ed9c2c9424"), + Hex.to_bytes + (`Hex + "a74fae0c8d19dbfb29ae9f3366d61e30c1541f351b27dbe8da480ce41db8c61e") ); + ( Hex.to_bytes + (`Hex + "e3614971b9ffad1feb6fe404273976a18d039120f8895d334a038ab6a50d5605"), + Hex.to_bytes + (`Hex + "2931ef1561a0bc7c8d009cdb8de0198efb36a1b7b6ab45a74555de6b07b7cc2c") ); + ( Hex.to_bytes + (`Hex + "401b886f9cc5ba666cf9c551861f9baee152dc9b007e8e6833d72e840e38e427"), + Hex.to_bytes + (`Hex + "db788d61f347e81b7ff58b6c3dc6f1cbdc919fa3483bcb625285840b2b7ded0c") ); + ( Hex.to_bytes + (`Hex + "ae9db1d347edc32b8068df2b5c232979aede234d6671c84e479692d729bf6a02"), + Hex.to_bytes + (`Hex + "966b62524b205189d2fa72c6c729ba154c1380a4a79b490dce65544db1df7c39") ); + |] + +let generators_zcash = + Array.map + (fun (x_bytes, y_bytes) -> + Affine.of_bytes_exn (Bytes.concat Bytes.empty [x_bytes; y_bytes])) + generators_zcash_coordinates diff --git a/src/lib_mec/test/ark_pobls.ml b/src/lib_mec/test/ark_pobls.ml new file mode 100644 index 000000000000..b65a6e77cedd --- /dev/null +++ b/src/lib_mec/test/ark_pobls.ml @@ -0,0 +1,90 @@ +(** Round constants for {!Pobls}, an instantiation of Rescue over the scalar + field of BLS12-381. *) + +let v = + [| + "35495817390819093545263349384941809089491580678942832859579453034368810736263"; + "4734865798690304458175502708216292605326887152358688691882538799996069070938"; + "31271008447681288492961289082649653266089021637020407236527451612237705002107"; + "3752272659749554246987316978069954116630957098620898965749354210894049705204"; + "22641555720019163306763445608116202165619173600682976754848212896631953422071"; + "28122533469631806190969995639553619503758826280316271478360761787725211583550"; + "25847917841495375497002109968427099088777388041775300281757084913772616807196"; + "32694606500120353152300866547101238346520817919199364752958292990138213972843"; + "27286327057691837800467727052167328890802672763096896941933952396730026264130"; + "11421505857991327619183254231367489753132565965114463729904675480639756627135"; + "521411871436069789624101480374109564923458769959324381065745329697883697117"; + "23880784307761253829209017376202022699450440759526482483183942457652656506129"; + "32944735989607121897647886317992117157418889561697480633116336030286723761501"; + "23809168654834556097350366212084670162247725165957937623679460641681583816451"; + "3163860194972429483721954648842733164010713297776971497284575674748141326227"; + "4994154821407041837874226315683255286085207059107827489820229821534877668868"; + "50472710115457611398312524300398743989276776324315737822995925423912734574272"; + "251866835357267652745308982111788504159393069098120092619439598668220537943"; + "29306447221479286209562070090539769526225070913770783266162336064629228514551"; + "29283041777181961494713136804131952798141345310627850728919908467956333015832"; + "28656363295645570828788643827370268834132346888229153863515891780361414296486"; + "25038928963239238795570624926346448459425394096652630785926109997438209703232"; + "8137054880809446884023200631931681550641379823710586899296036975467179806266"; + "40023642373942331790709007028495088784452433159634511649021697266107433596568"; + "35762237949937672281308268151392628513069349315494090383109234785560672634670"; + "30999566811631951689259246295471339743428563889981096112711184113782054324157"; + "20279178450660587763205226449293238908131708902882258115414408411285674682667"; + "7251226788353540177691937542431845975737106489341120571030231114808456476646"; + "52125099959305698802726608420202937507908602874086034970293871469588059526157"; + "36947771116325024965590213964896639663487838999452121836698608133540047510904"; + "6731449362796983987468313257604646517406447849071950000589095424962988643919"; + "46799204329731723451752711923834870677752669570495984560450489328024837708708"; + "35089631385082017128756246668734504606091189119241613702809534617529750689438"; + "48404791586561114467519265925614105026432456534013682923179665391057050944501"; + "25910045457085525717925797997640841840596905619632452927132962053945891631463"; + "1002644049329627578859603332717752156946995816186878866098534634466684910592"; + "27000834541453700882360080348023947440783037764820885196153273422481631245741"; + "12589074081116083610034305532223638886927072126291986576471860562392225733147"; + "42427223203410224646468929039478899902048566366856240877703602702087931641888"; + "13041605696900798404650686538893086909353822453068056131548498883864307018762"; + "7724559080250826493557773439911765324995115520951876421071063545832580076523"; + "2608760983816514764568197126437451665283344192910536302819820213681815485600"; + "4325576551800410431474186754039992813847609089390921236861130833620395142916"; + "28244869281227089786402354774575238327642814071062911402571918173773147690382"; + "52254320812514580546932455788288716956214894268551482805284261007871578815161"; + "44449246366481365934850731985584672122835299278127134772360027315881296465188"; + "38769336262079049280674269301353892930067342680672673045972987208159445324024"; + "42379436704506954159182654240696088598260763773619436089417882065405547940000"; + "22632779538473440042293241998410977359589070603696185849507766111228222504955"; + "15890983544445833013318912933113160561188216234423366865567699135890287302776"; + "42613622386509970285531317746282776785466762852259244468998263414951438072346"; + "3349279328650947992104289938299770603841093392045299702204191673899696292828"; + "24960454956681584943062398789550512391287992748093736571644480050215988836698"; + "31771416517485450527236959099354889665790926800645171236881417310335951093156"; + "6723262288337923380317441046361546981088139618189440979848042063784738198448"; + "34890105450847731125549485970715770779411614440863872580331681887247489622411"; + "11578979089604924419672152758230524155578424562011333797269885929442680042317"; + "50413588594256908654341963895371964591208017449187726872226940257366479794931"; + "25342645262500526730472670090219790271213097305995599586909134601382438580057"; + "8823851208157208211075893000112820438603010547555640271936182343488623715695"; + "48715166069588125017688857080421400882110756555551531562607166243928305121118"; + "457928742693316582022794368629361528074764749146022984852066320975235063636"; + "40784591676918140113004512439228960581998583153376036451231191678625605644121"; + "18433242804842005502998987143284711404363511412515282751547329224013759991670"; + "13389179080347763657382998600872902733061029331254291204270991952891409570918"; + "50192764209384080101272306620889875080455867628520281400927714930481563250325"; + "21188812847528225766555643216406799500549004969671500977130541863203997121380"; + "15467310814359095588985846207322319122950649805677111326687390171860927014900"; + "43568129081901200261103456211527409151200730655566657378341556085992472943958"; + "34271132631203889901701300408318058004416254071247236806623005223769350150039"; + "22173004425756666568314241635854763913339665884248599814793658197582222664954"; + "32975563242070450354147568749607182665869459510325615902750312087436132984686"; + "22696762757124796424578806530049133427552572655901519744413916679979764071390"; + "17763704296411643970998432037239004006015355463277677435659459899409343551392"; + "47107020014905029302099526236973268575042805085389783842994685212684421454488"; + "13304672766482627838923613214260444961210749299235217922669168410578113120633"; + "14336471400558675842362782084319960764287611922882892949544609123042059062824"; + "19303757685423427260649409150012846414071844305131989213305575732858057757894"; + "41105909312432760443399922527873622836019389621682258300053074843930035806751"; + "4449965847617470660026263611722341184463318026296894969809166330782012760219"; + "31939993490530073679397065723723444395703645080257573290017499883874398700446"; + "44612014630702294701797504988969181620837907283197659821551486351788471559337"; + "42992712381319065313644044212157260265940162092852802442073735607198967462282"; + "966835047744911231490794763166379188555949592683359886287393788918898119684"; + |] diff --git a/src/lib_mec/test/ark_poseidon128.ml b/src/lib_mec/test/ark_poseidon128.ml new file mode 100644 index 000000000000..96220f7bd83b --- /dev/null +++ b/src/lib_mec/test/ark_poseidon128.ml @@ -0,0 +1,198 @@ +(* Generated with the command below from commit cd13dd0e984a4eeadd82e0ac4ce792c275bd3b18 + [dune exec ./generate_ark.exe 8 56 3 52435875175126190479447740508185965837690552500527637822603658699938581184513 NomadicLabs] *) + +let v = + [| + "51466596801245350172389236854912648222719187746298709105513845567941180611585"; + "21750751762978437653936573013155607200736969558902465208523342419237410586198"; + "12486517768781903523286807847370218034689963995541894791925792444351839473647"; + "20445718088460789875962943176961386089719184042145123661083866290956184640219"; + "27873160203424299876666416455237485949282512273439804047040763657322096149056"; + "41356063063918478660008355287283031045994439439052675999621074603564345282569"; + "39339901461669097862513996312696398098463519178491001542393778258774347097156"; + "9204042589329629203508256352213922752007565761246017599071231880772962888313"; + "44872792620396140616818721079703154415798612187578057809815607666928058754777"; + "15937726977018206908966109373834056579034465379649731865901151172854062328666"; + "23605712034497375740219228439343452998072299839093594319857450624289690266228"; + "6402638958817972947806346954920050102512724107777426591914400080844084499349"; + "3185239264644999224390913018332891687143438328474986546082170376396564918303"; + "8810128481422180179093610800905689707749830921384041843188605671660723745224"; + "23856254368860098877925830552890800356559853619873956523749705505858453741419"; + "24587049159258135725439557767222187037564112044982562605667614163816312730472"; + "22837536766890438293232796017074642678223630893636795777506185541273623237047"; + "9192015516308615812149895996678356120602200776491327365416854885711899134185"; + "4002652916865493677251257166117182479501804845054999793592382685603350748223"; + "33066348252219459468552045146523238597048287748451612668563453612283148717787"; + "22032405802641325275844419284045173476338377422793990841002770933934147271753"; + "40810499016480900907962993830032852958946905562531549979714594924288595159449"; + "11360048753112901991330610389408512769078774607723790648797196048769123341818"; + "31073120699274505130875191050788584204810084807427992815212547386082177411939"; + "38905424489726634595807315824887707754301482341060164517868666848234609856296"; + "16437589687938886598993201288686198745024640875414943299079721648754955896524"; + "9246415141807177921760679831767807305667023086044867913825908258624135672402"; + "43267134335847210508826260454424281515957785150826503791438907274325277067689"; + "47405994765042204778087426457971662098880376129631959037220571890293893837627"; + "51109501544539159334717344833663305202169784719089645141283241708762847921831"; + "28367352686904931835510258483164340654232741901091990185726515423922311395266"; + "49750106362878302307560487257360445042628424171940583005315598767946030678175"; + "45959469784902653889236043731939532829295000363517367441618551318205534438835"; + "27018375398598043392768159138944903620978890067620474698695220978535490993662"; + "37680060127197925845671480407334293104013784691230898581176604640776871595820"; + "10072365749347322273683640976003223868449058525371389769456254873788829510856"; + "5776958426313577264021166002700070711779258526703552908022966622941040975486"; + "2052552766687385987890760301444512953288614090851121718631539540584797743813"; + "29589973335212398499653074528975769763663217998670026908669929887809390254086"; + "47176517056998440790693968750261830775359488909857950144871025285282622331205"; + "4044841108655017183998683299702141262167457310115051178539772996106040315055"; + "23145769961882962007007503964681965122021931165884937363089732236563915279899"; + "7603705117156652453963281055927587143772971225944827219299824918233735396544"; + "678587461188445034628596985861476825212606316443632929982806452029635142763"; + "43358198653600383869329744766691886425670686115842008451706594321104589073353"; + "29783989749004381558893964246285207519677877370947641650381151227672399441258"; + "46788814117768703246098518443423934593855222525287642802070140820481989754464"; + "47667240567568953271881931068585333300960463653436442752666537199724542862209"; + "36185825409915459203448245743109969343193138020188742950229819419575178293681"; + "10268626031678681962519788038923114866365639923373751230918298280203944789089"; + "22423180878570467317830579782624040309181433514468470079452795926252301501451"; + "27854213599947523969400957712485981554578482677686500615005910306191690675548"; + "32552238758912415934584820719305968737837410579067602670579118065160652867044"; + "27524020150199858721583983985008046355789957344374031640804833804334599991125"; + "11598691035533751109698164453612171297192910953856758972631340412485692367245"; + "19240281692025919244580609351663678384250073443852130798436970816624877123792"; + "19081743524319516787728673230184684387616956386482784328031473187929184929813"; + "13482824733237717061443533817612030042881142888904695925365483772570662398419"; + "24557586779364722370887646696339785224219486745231704250023468368642112077961"; + "49132695885737549819731989839786719093658647324506783818463101428078920152339"; + "47598003338017334595631291432676651103981450315484662200923020856309789617505"; + "29657580775158274893108525946918168971159316368647847989798236676167226124425"; + "2089871173039090298283861039787654594553968107879556266696645874401027551594"; + "17062674176584193145991964541286296980632589397952567044305875706903816798918"; + "39759050960205479940159986279409353005846424612008117451162722701140967479478"; + "22533616828186323521649895181466155821530425549183373709986149684843468562921"; + "11710329771453525931280127059748492796905639784050357470339844149929022650252"; + "28382230089609321965313624834250197889691846195285335974753263997326737343307"; + "17483468269617424580234048407267881623433885539437967900597355348779845904370"; + "15393678108977111939937458813237466536883800502542016725609655847312425800060"; + "35335672469945182745009570081451366206953223954844817103347451918365408472583"; + "18485543557533557196522038987860777539645907448847172084578647917456309932838"; + "35453109551100805378496992884404555281031142908343718145992408005796255932067"; + "26162388899534531304185889785161995414351042512495564813598387581820788701274"; + "30513272868498004256565910019709317337704607470343755267516092336967857454429"; + "7482438077715696595671300257575441576458965352889636767368860652528296466835"; + "4420972756750713378268292139245553512010082345332818480344347760992140415579"; + "45443072118542869094106210430408632401658283491040846320908484790994846489479"; + "4587498519897850005501095589592009810295823998176500983502979737014704428427"; + "20140268669484747984769809200637802968551617462409085249909344252279198873265"; + "29246773006012167464394782413277073922652993569428539217341804135677142314734"; + "2090453766635748262896094182234431405487694916721156619151573559829565285658"; + "28154797511075990999067437210883725325588221412791352016549710458849851400443"; + "7437576051454980648324143413673447321627481635285743115910231258907952681902"; + "47849325109234284589063376275405356989691773872687047237532536232042052359483"; + "12480987611376364480590099596287568108053904335043512585655935306753098846056"; + "35282772152784155873872416038091486728018085424598473101796189937824691931982"; + "44644309599357388823648910637703362148932670809274055496007925095230623381923"; + "40669859985254288073391010054507859022800795198091698303895855303568474914724"; + "49443653278257139506363224578511517450965492260748531903735461532886298470324"; + "28151927370999705099548977210331844092002690574491843105417307465011218883372"; + "1645107825636563552234056692699842524648459238860722695243162269478817742307"; + "20451009040028965353495911802150535366781462589345362185312598771266505204706"; + "27819682514111647266735378995664843430901566567232355462928465778589146617300"; + "9554102125843498587844759244118187314040788045621020914785690475852459244712"; + "19166777550065260996957117606165528594010042113228133002376856047908024628860"; + "26933579719124735456146556120749918059938219375765953757687070745926421730690"; + "43664899352313137143462906778788854871017052765412139294077435721003011363428"; + "36173458814979531375880943417934798141032455281648386700864729797402421147643"; + "11182517313384645430276258135181995604973901045769946685233925860600679925400"; + "18957585496621103259998572202861039692818169581041076732942953590132787413185"; + "990272065387976234207571590743065697998566272630425704533408985373371347703"; + "4566865954002478217870742631824891308061027453183663472158387320791808636718"; + "13275080024861611833879690760787568594881779009163813547717517171800075477326"; + "18280289328587924651942995072338785526297904605272226018248763384856128538194"; + "37393719051038483957290231134622753224758957341736360150179478705995454183736"; + "35471769041551236267108986169916522221022951796087962631717489467967242728989"; + "18313615850921029128115249415256953514199920171298188893865360820700589880640"; + "8649505551495013773478550513798423370916587725243242103915932173300802613836"; + "29426595573001164623970767658482684730540336753851606403197168017465308935012"; + "15800050789941506886367343947552537811144738254935176866599264324633404561668"; + "2388599729796011963372654009792156200311446590133223685676648683498130023426"; + "39710359146943858258478963255479846071237665235335480449874571631729609456656"; + "12539354052138844839668649494440055311612800274194314682724519322900896888667"; + "34775703808689652205221353219074769424059692664878491357308664495453361798542"; + "16602078529355937689782643082006360605957411241022465529030420514355243740084"; + "20279850236027730246187137397861434992518721949131469477063849268012331913542"; + "20700406847766119075096991790226756382972208779794861885683190244345925948772"; + "10767548586122669600841175107605340206307369812479898137983203022752955229420"; + "33780485917217277294437000521052335973598541648381872358473220524753392579944"; + "26053477836690449767759260916263153231466698419416254714069016291032716493795"; + "51075719579296898046678332991810264442802867440545970415662411469944202971572"; + "44425065795172674272025431261784423304992373196100933574446818463450861237636"; + "21673427825228648696679367470878911746787913779734335379612724957949663438503"; + "39500036723407342733895180253912956707996173847799994738506003893694134507820"; + "18814390742264124557923083818518430926773544077233525827507879093955534745943"; + "33285136419882565391925060802949863649369447257963104257237128389534667335431"; + "7242824697084765204242498009056108554791055701454269759053340822841847843590"; + "31173248312673499793759274086904799638353536404479301039538892557122201869326"; + "31186133094427811821728441124091409602329280228993044467507339271468902426067"; + "25737910716320624211587760844165755540380223663083209047341376780006952817951"; + "41007486903540773766178646801963663835738017272207371664092100665995867447476"; + "33733614421653704619906981612465553433605639878071728634533669588152171336923"; + "44508002187727655261274038726582531821774653664912931880913651223618478524203"; + "29308206009053294442851242412693308913204908282227130202504576346803290538114"; + "37195044959073314994498067496758410674853446343706809704471573374824766240756"; + "27750290920151880266415654177442693344449343287594569254432923001134909857161"; + "15765188586172333129026261765507777427830002956246082548695725135386026089531"; + "1723567911352974656239983052419150859691079784042460780666277969900550546629"; + "32624380698163043349452348170080919066187676495607088889037247382764371823304"; + "42332347907545864823851740450059178607636354773434217763190376183475294814740"; + "32851187296571784166842016235453193261263026420621113443940941911613891853263"; + "46515450218610398244495734725817662625773300495752440637456039809680716524335"; + "48802434618714806701215020572358407402163910104929505500552346872970874445024"; + "15041030433764412988626541831537854311766371887970954109236962491586466599144"; + "24914207471851043784197436527940466212674042052967065649457499415892446136159"; + "9071888319763577380151443506898914744736366395870413605185856133895174517345"; + "14324407136483074978482942921602872905704673210914714962854893980450386451889"; + "29042406409942557018444189727617456411092110677398829954434968404039936168367"; + "45298132425441112218235385216467264374863717020516284112024948473015955374084"; + "5848266257013307529285399749765616739303579930676051972945621978827280728485"; + "50258542824814649118248459254788489871100732773736051031417014804244168803608"; + "2211331518382464997157173039326358398024782525487574099479995890254668498248"; + "25495625009683093041292487489064498029388757676050435379647316032736436019034"; + "1673456300079357795623609138015785582077169647352697470259283949067483430156"; + "732875001458000671533092091268384759392197266180901126140125986324726970217"; + "15937486314053418275659636264513684188072392679031027560851186610858143116536"; + "37523979262473761872442642124630377368104280370382009467506872860620420272028"; + "1463301537361190248611634113301833004506917120571380701549297040601288661632"; + "15388046866006485479772795262309796656931214897645470303116977773763549826647"; + "24820458677922696742762859449292673635627885851532245057181102097543570979209"; + "42204379350085294410776773079715228191662735656426212256162333812793552403993"; + "1195814176795714164840835333744966813414161441324551406851397366147530373686"; + "16761973517502055324144398018035682278752429331149035356778515867109688520079"; + "5794935406580257517632452299232288835369749493148532249516641371649010994761"; + "28489054235450115341655557856812811692903805568161190542887091508558194202484"; + "46027667092982098207528356294714952530753544394086856091550981466630371723227"; + "36549545461270844973100848885411892468389487357334958172813302441582453767995"; + "27730798985447029088568033769773024804917434212093202895074054132301610442265"; + "30053494660111523933577748614419372203999341521131288200082766152193752930915"; + "42669519840379176591693261573919152190190830699417113996773900230897690941207"; + "40491463463369636128381274334600090418795787105664137021554873372325496120497"; + "37855317198077808209359933009653152621140711928666934200968394018548493650684"; + "30289339203582770465154470558134566153982220926251521920946038335272057457401"; + "27778690140622310321003540914723670899734999136798303644913768708258653156597"; + "3973394156719142858738591330892034076809261304074876595400530436577715032673"; + "34101414891901169069858357639409485174940075127343413252072373211617833012486"; + "24763874711353584430968413634679742313122411936945926412259875031351381484206"; + "36482519855965638025925823411871352935082631497149119671124638993468289313858"; + "33663960240182462215313666658229034428117630528389633368925326911863733915779"; + "24156616496917756781377614606496469046971000527652456728186486373912788616012"; + "17862377433968409862537980143869608526991820954912158743675488121333401401128"; + "9883166492675772730546061809268489723031153354700278026721716994418744028520"; + "651720966810612228203754272949951577724164458606405611640617175537862475287"; + "45029571820041579599811835408905235857907197206303946042784264756752149312055"; + "15218138019507525985285504884751281493313515412230279354014712290617793064643"; + "7889502179901137713876340968057633612399550484642109442993286207350478652780"; + "51114781021375925510384757787309929484526957562759351412663650152039538436129"; + "49153605396638540179308253872425727518164881509781489770081628829948751933325"; + "39446436805473057234521273352946756590838723177719005850741347955181052035907"; + "32522116151199401996556140465344290516461661003004520182401454275644784968841"; + "35709586671485611381280332540710898003892567989895109778435218770617343891091"; + |] diff --git a/src/lib_mec/test/dune b/src/lib_mec/test/dune new file mode 100644 index 000000000000..e1dc4b028c77 --- /dev/null +++ b/src/lib_mec/test/dune @@ -0,0 +1,305 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(executables + (names + test_neptunus + test_orchard + test_pedersen_hash + test_poseidon128 + test_poseidon252 + test_sinsemilla + test_babyjubjub + test_babyjubjub_reduced + test_bandersnatch_affine_montgomery + test_bandersnatch_affine_weierstrass + test_bandersnatch_affine_edwards + test_bls12_381_affine + test_bls12_381_projective + test_bn254_affine + test_bn254_jacobian + test_bn254_projective + test_curve25519_affine_edwards + test_curve25519_conversions_between_forms + test_curve25519_montgomery + test_curve448 + test_ec_functor + test_iso_pallas_affine + test_jubjub + test_jubjub_conversions_between_forms + test_jubjub_weierstrass + test_pallas_affine + test_pallas_jacobian + test_pallas_projective + test_secp256k1_affine + test_secp256k1_jacobian + test_secp256k1_projective + test_secp256r1_affine + test_secp256r1_jacobian + test_secp256r1_projective + test_tweedledee_affine + test_tweedledee_jacobian + test_tweedledee_projective + test_tweedledum_affine + test_tweedledum_jacobian + test_tweedledum_projective + test_vesta_affine + test_vesta_jacobian + test_vesta_projective + test_digestif + test_linear_trick + test_marvellous + test_redjubjub + test_find_group_hash + test_iterator) + (libraries + alcotest + octez-mec) + (flags + (:standard) + -open Mec)) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_neptunus.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_orchard.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_pedersen_hash.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_poseidon128.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_poseidon252.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_sinsemilla.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_babyjubjub.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_babyjubjub_reduced.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_bandersnatch_affine_montgomery.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_bandersnatch_affine_weierstrass.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_bandersnatch_affine_edwards.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_bls12_381_affine.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_bls12_381_projective.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_bn254_affine.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_bn254_jacobian.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_bn254_projective.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_curve25519_affine_edwards.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_curve25519_conversions_between_forms.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_curve25519_montgomery.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_curve448.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_ec_functor.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_iso_pallas_affine.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_jubjub.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_jubjub_conversions_between_forms.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_jubjub_weierstrass.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_pallas_affine.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_pallas_jacobian.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_pallas_projective.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_secp256k1_affine.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_secp256k1_jacobian.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_secp256k1_projective.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_secp256r1_affine.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_secp256r1_jacobian.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_secp256r1_projective.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_tweedledee_affine.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_tweedledee_jacobian.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_tweedledee_projective.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_tweedledum_affine.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_tweedledum_jacobian.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_tweedledum_projective.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_vesta_affine.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_vesta_jacobian.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_vesta_projective.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_digestif.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_linear_trick.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_marvellous.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_redjubjub.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_find_group_hash.exe}))) + +(rule + (alias runtest) + (package octez-mec) + (action (run %{dep:./test_iterator.exe}))) diff --git a/src/lib_mec/test/mds_pobls.ml b/src/lib_mec/test/mds_pobls.ml new file mode 100644 index 000000000000..ef8499578604 --- /dev/null +++ b/src/lib_mec/test/mds_pobls.ml @@ -0,0 +1,18 @@ +let v = + [| + [| + "343"; + "52435875175126190479447740508185965837690552500527637822603658699938581184114"; + "57"; + |]; + [| + "19551"; + "52435875175126190479447740508185965837690552500527637822603658699938581162113"; + "2850"; + |]; + [| + "977550"; + "52435875175126190479447740508185965837690552500527637822603658699938580066914"; + "140050"; + |]; + |] diff --git a/src/lib_mec/test/mds_poseidon128.ml b/src/lib_mec/test/mds_poseidon128.ml new file mode 100644 index 000000000000..fc4eef5dac77 --- /dev/null +++ b/src/lib_mec/test/mds_poseidon128.ml @@ -0,0 +1,21 @@ +(* Generated with the command below from commit cd13dd0e984a4eeadd82e0ac4ce792c275bd3b18 + [sage generate_mds.sage 3 NomadicLabs 52435875175126190479447740508185965837690552500527637822603658699938581184513] *) + +let v = + [| + [| + "48527463322097587091854420767453816291840635874249958396342138881138912067190"; + "11996084473350366483175782359948025962778681837397784970341328014763133439499"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + |]; + [| + "43372445583202124108992832749257195116898314930070456682841601188523728879167"; + "22957843818027924237635625446720638788994914691706001027915412076310000455035"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + |]; + [| + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + |]; + |] diff --git a/src/lib_mec/test/poseidon128_linear_trick_expected_output.ml b/src/lib_mec/test/poseidon128_linear_trick_expected_output.ml new file mode 100644 index 000000000000..b82849f3b949 --- /dev/null +++ b/src/lib_mec/test/poseidon128_linear_trick_expected_output.ml @@ -0,0 +1,507 @@ +let v = + [| + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "9192015516308615812149895996678356120602200776491327365416854885711899134185"; + "32953309468943531490839943962309869402925783570438389574347733408052522035367"; + "41849214595467910123673033520102794108104712997008198889522813877734245824992"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "2882178528690637799196969962825392366414635583132469812939771951597834311585"; + "33312374379319542810991447038237232988042258339322606967927166686005294530141"; + "2737318182661479970580613550792855222106118769205538817720593077458586232462"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "44304878322376821471457979178742319458450672742516208066149226620627785026699"; + "28069804560566986820780141306617957617142124689083726799461195695753383204290"; + "34993469540808095486523884664145037729429846937484126092996667946941269260665"; + "11844085669837119750115930248863854777199847054885070800716560090573754609681"; + "35914353067034535100652019426938814231673372200100789099223322096377158467494"; + "520503526423274284711901945026220761232488147249669637631551937442183120274"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + "5372317495492347281497506320851323467659133629626575345521824702293347397900"; + "18192150206125313032264815747914724777905185814539525394719756794023760665086"; + "7169284984681148301101070301086569799214236786154614020456024084708327543744"; + "12609311342646272297200914221417675005357093654436013989372519104778233478270"; + "31170352425453189271982573751891724347094384200281623320937122512461975148357"; + "43222315627129083568275705268856575434253276738761458024197396244348192453816"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + "15070385223307874561805571012610427344563770787382376434673237848556393795971"; + "29493317929139945087331316348191328190403379874196425053979399148385870374626"; + "7638134712636322282750220652430072697753918180880580620720783612440458134642"; + "50625858391910681386377169116496102383629369302093953246867762562643904782135"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "6801218399527127889551260199762930275886221521061350291393997345035057475198"; + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "51109501544539159334717344833663305202169784719089645141283241708762847921831"; + "32953309468943531490839943962309869402925783570438389574347733408052522035367"; + "41849214595467910123673033520102794108104712997008198889522813877734245824992"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "701520725639690163032745458587880472444505536342074354063413762385927034368"; + "33312374379319542810991447038237232988042258339322606967927166686005294530141"; + "2737318182661479970580613550792855222106118769205538817720593077458586232462"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "45815550288643568378962602194063952559111198251796382389442212808642516396244"; + "28069804560566986820780141306617957617142124689083726799461195695753383204290"; + "34993469540808095486523884664145037729429846937484126092996667946941269260665"; + "11844085669837119750115930248863854777199847054885070800716560090573754609681"; + "35914353067034535100652019426938814231673372200100789099223322096377158467494"; + "520503526423274284711901945026220761232488147249669637631551937442183120274"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + "21565604724642717257531910530284104108260419130421011016242241442509695943256"; + "18192150206125313032264815747914724777905185814539525394719756794023760665086"; + "7169284984681148301101070301086569799214236786154614020456024084708327543744"; + "12609311342646272297200914221417675005357093654436013989372519104778233478270"; + "31170352425453189271982573751891724347094384200281623320937122512461975148357"; + "43222315627129083568275705268856575434253276738761458024197396244348192453816"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + "3831002866006904725518065651762960860618840749452010434637151722539469444794"; + "29493317929139945087331316348191328190403379874196425053979399148385870374626"; + "7638134712636322282750220652430072697753918180880580620720783612440458134642"; + "50625858391910681386377169116496102383629369302093953246867762562643904782135"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "46382240481646496809518413791152102428709762113979378104003187789894083722732"; + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "23145769961882962007007503964681965122021931165884937363089732236563915279899"; + "32953309468943531490839943962309869402925783570438389574347733408052522035367"; + "41849214595467910123673033520102794108104712997008198889522813877734245824992"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "36716342521726419117213128980076097451026731907573671960102537830416244422156"; + "33312374379319542810991447038237232988042258339322606967927166686005294530141"; + "2737318182661479970580613550792855222106118769205538817720593077458586232462"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "41160294377463621643120454721197344078941574765536806589315567702131332430733"; + "28069804560566986820780141306617957617142124689083726799461195695753383204290"; + "34993469540808095486523884664145037729429846937484126092996667946941269260665"; + "11844085669837119750115930248863854777199847054885070800716560090573754609681"; + "35914353067034535100652019426938814231673372200100789099223322096377158467494"; + "520503526423274284711901945026220761232488147249669637631551937442183120274"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + "39635218593468451201873814299498013949623506004261368123612430853226008726675"; + "18192150206125313032264815747914724777905185814539525394719756794023760665086"; + "7169284984681148301101070301086569799214236786154614020456024084708327543744"; + "12609311342646272297200914221417675005357093654436013989372519104778233478270"; + "31170352425453189271982573751891724347094384200281623320937122512461975148357"; + "43222315627129083568275705268856575434253276738761458024197396244348192453816"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + "33795981006394818310316039388542050681256500164109603671284530700045469864829"; + "29493317929139945087331316348191328190403379874196425053979399148385870374626"; + "7638134712636322282750220652430072697753918180880580620720783612440458134642"; + "50625858391910681386377169116496102383629369302093953246867762562643904782135"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "44492276353551975169669752712528032154797627858865281332045086120100069224234"; + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "27524020150199858721583983985008046355789957344374031640804833804334599991125"; + "32953309468943531490839943962309869402925783570438389574347733408052522035367"; + "41849214595467910123673033520102794108104712997008198889522813877734245824992"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "9045120383777347506717569286405878058741460907242830253734638279992086824184"; + "33312374379319542810991447038237232988042258339322606967927166686005294530141"; + "2737318182661479970580613550792855222106118769205538817720593077458586232462"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "9150760937678337865415014144050024892628210825433660429495424331535737185525"; + "28069804560566986820780141306617957617142124689083726799461195695753383204290"; + "34993469540808095486523884664145037729429846937484126092996667946941269260665"; + "11844085669837119750115930248863854777199847054885070800716560090573754609681"; + "35914353067034535100652019426938814231673372200100789099223322096377158467494"; + "520503526423274284711901945026220761232488147249669637631551937442183120274"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + "29090523152346524130465280512009521666245284022124568723225710854929183797713"; + "18192150206125313032264815747914724777905185814539525394719756794023760665086"; + "7169284984681148301101070301086569799214236786154614020456024084708327543744"; + "12609311342646272297200914221417675005357093654436013989372519104778233478270"; + "31170352425453189271982573751891724347094384200281623320937122512461975148357"; + "43222315627129083568275705268856575434253276738761458024197396244348192453816"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + "50837348711737925443994433233727541196234549476164392543618221140427615276862"; + "29493317929139945087331316348191328190403379874196425053979399148385870374626"; + "7638134712636322282750220652430072697753918180880580620720783612440458134642"; + "50625858391910681386377169116496102383629369302093953246867762562643904782135"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "43318348879832277681218577988634751052157288538049522526835660453429163230046"; + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "22533616828186323521649895181466155821530425549183373709986149684843468562921"; + "32953309468943531490839943962309869402925783570438389574347733408052522035367"; + "41849214595467910123673033520102794108104712997008198889522813877734245824992"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "5473949805226263839409194619542301210263934164988109662666902474080780699068"; + "33312374379319542810991447038237232988042258339322606967927166686005294530141"; + "2737318182661479970580613550792855222106118769205538817720593077458586232462"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "27143882270795362706411619280688018870129180483360681728065780816295741529957"; + "28069804560566986820780141306617957617142124689083726799461195695753383204290"; + "34993469540808095486523884664145037729429846937484126092996667946941269260665"; + "11844085669837119750115930248863854777199847054885070800716560090573754609681"; + "35914353067034535100652019426938814231673372200100789099223322096377158467494"; + "520503526423274284711901945026220761232488147249669637631551937442183120274"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + "23112129942619371367658776059780045057719568001591854124634812570238532784690"; + "18192150206125313032264815747914724777905185814539525394719756794023760665086"; + "7169284984681148301101070301086569799214236786154614020456024084708327543744"; + "12609311342646272297200914221417675005357093654436013989372519104778233478270"; + "31170352425453189271982573751891724347094384200281623320937122512461975148357"; + "43222315627129083568275705268856575434253276738761458024197396244348192453816"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + "14214250504225450405147549228356006477855799758255258443520503373180077352156"; + "29493317929139945087331316348191328190403379874196425053979399148385870374626"; + "7638134712636322282750220652430072697753918180880580620720783612440458134642"; + "50625858391910681386377169116496102383629369302093953246867762562643904782135"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "41279525378457135352856953999638593140524334438408816281046085283531491653329"; + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "45443072118542869094106210430408632401658283491040846320908484790994846489479"; + "32953309468943531490839943962309869402925783570438389574347733408052522035367"; + "41849214595467910123673033520102794108104712997008198889522813877734245824992"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "45256294718302567208444127530291127760136086297101325412422516962866719949323"; + "33312374379319542810991447038237232988042258339322606967927166686005294530141"; + "2737318182661479970580613550792855222106118769205538817720593077458586232462"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "14290273929072566209365354273024098471931207548728736015088087706981194461601"; + "28069804560566986820780141306617957617142124689083726799461195695753383204290"; + "34993469540808095486523884664145037729429846937484126092996667946941269260665"; + "11844085669837119750115930248863854777199847054885070800716560090573754609681"; + "35914353067034535100652019426938814231673372200100789099223322096377158467494"; + "520503526423274284711901945026220761232488147249669637631551937442183120274"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + "18971848689514595074202710646693937054384719067158699717347895698062002339472"; + "18192150206125313032264815747914724777905185814539525394719756794023760665086"; + "7169284984681148301101070301086569799214236786154614020456024084708327543744"; + "12609311342646272297200914221417675005357093654436013989372519104778233478270"; + "31170352425453189271982573751891724347094384200281623320937122512461975148357"; + "43222315627129083568275705268856575434253276738761458024197396244348192453816"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + "22412129993404212112583696208950114796350703529131401292910224191348746231387"; + "29493317929139945087331316348191328190403379874196425053979399148385870374626"; + "7638134712636322282750220652430072697753918180880580620720783612440458134642"; + "50625858391910681386377169116496102383629369302093953246867762562643904782135"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "42063803510340274491021907036360349339297099844057268534414906125340124041065"; + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "49443653278257139506363224578511517450965492260748531903735461532886298470324"; + "32953309468943531490839943962309869402925783570438389574347733408052522035367"; + "41849214595467910123673033520102794108104712997008198889522813877734245824992"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "35644170807639027802624947327251117861064897002750597297705088225244401074522"; + "33312374379319542810991447038237232988042258339322606967927166686005294530141"; + "2737318182661479970580613550792855222106118769205538817720593077458586232462"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "3709114126960789026074419529896930433504800147579707920229988833216705635450"; + "28069804560566986820780141306617957617142124689083726799461195695753383204290"; + "34993469540808095486523884664145037729429846937484126092996667946941269260665"; + "11844085669837119750115930248863854777199847054885070800716560090573754609681"; + "35914353067034535100652019426938814231673372200100789099223322096377158467494"; + "520503526423274284711901945026220761232488147249669637631551937442183120274"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + "38951261709763542999599642463251546936505948647834365905313493153297160176472"; + "18192150206125313032264815747914724777905185814539525394719756794023760665086"; + "7169284984681148301101070301086569799214236786154614020456024084708327543744"; + "12609311342646272297200914221417675005357093654436013989372519104778233478270"; + "31170352425453189271982573751891724347094384200281623320937122512461975148357"; + "43222315627129083568275705268856575434253276738761458024197396244348192453816"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + "8486120907783193656776682428962693434266794894079684915814814454049793852066"; + "29493317929139945087331316348191328190403379874196425053979399148385870374626"; + "7638134712636322282750220652430072697753918180880580620720783612440458134642"; + "50625858391910681386377169116496102383629369302093953246867762562643904782135"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "26071586616788726848118556702785198614811014431572157865835762587997587261753"; + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "990272065387976234207571590743065697998566272630425704533408985373371347703"; + "32953309468943531490839943962309869402925783570438389574347733408052522035367"; + "41849214595467910123673033520102794108104712997008198889522813877734245824992"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "42465867405048387994299611299781332928078030657924061122730149082107406250971"; + "33312374379319542810991447038237232988042258339322606967927166686005294530141"; + "2737318182661479970580613550792855222106118769205538817720593077458586232462"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "47417714702373971202970658463388009961699423232949158744627403853091033544538"; + "28069804560566986820780141306617957617142124689083726799461195695753383204290"; + "34993469540808095486523884664145037729429846937484126092996667946941269260665"; + "11844085669837119750115930248863854777199847054885070800716560090573754609681"; + "35914353067034535100652019426938814231673372200100789099223322096377158467494"; + "520503526423274284711901945026220761232488147249669637631551937442183120274"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + "46284618424341315932153926513869205664927876451305121878302731574910828880800"; + "18192150206125313032264815747914724777905185814539525394719756794023760665086"; + "7169284984681148301101070301086569799214236786154614020456024084708327543744"; + "12609311342646272297200914221417675005357093654436013989372519104778233478270"; + "31170352425453189271982573751891724347094384200281623320937122512461975148357"; + "43222315627129083568275705268856575434253276738761458024197396244348192453816"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + "45316049235984510813087146306153207979084325303859528181741142285642819498577"; + "29493317929139945087331316348191328190403379874196425053979399148385870374626"; + "7638134712636322282750220652430072697753918180880580620720783612440458134642"; + "50625858391910681386377169116496102383629369302093953246867762562643904782135"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "23415742371440809999881103425623606266510432302864166169516920775086454158674"; + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "12539354052138844839668649494440055311612800274194314682724519322900896888667"; + "32953309468943531490839943962309869402925783570438389574347733408052522035367"; + "41849214595467910123673033520102794108104712997008198889522813877734245824992"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "36181344118250819095008146000746655303902366834212519322224019208342175497009"; + "33312374379319542810991447038237232988042258339322606967927166686005294530141"; + "2737318182661479970580613550792855222106118769205538817720593077458586232462"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "26009655444826085765219601607499661107442772246165927613520153785006434877592"; + "28069804560566986820780141306617957617142124689083726799461195695753383204290"; + "34993469540808095486523884664145037729429846937484126092996667946941269260665"; + "11844085669837119750115930248863854777199847054885070800716560090573754609681"; + "35914353067034535100652019426938814231673372200100789099223322096377158467494"; + "520503526423274284711901945026220761232488147249669637631551937442183120274"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + "23416138091439234726367337073336780995765284856729461011006248193031203232630"; + "18192150206125313032264815747914724777905185814539525394719756794023760665086"; + "7169284984681148301101070301086569799214236786154614020456024084708327543744"; + "12609311342646272297200914221417675005357093654436013989372519104778233478270"; + "31170352425453189271982573751891724347094384200281623320937122512461975148357"; + "43222315627129083568275705268856575434253276738761458024197396244348192453816"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + "14541266812231252376229861599404802687608769019798002526145891405186344824126"; + "29493317929139945087331316348191328190403379874196425053979399148385870374626"; + "7638134712636322282750220652430072697753918180880580620720783612440458134642"; + "50625858391910681386377169116496102383629369302093953246867762562643904782135"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "51994716290380331591600828704017143849094776548672170854588324330154294252493"; + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "18814390742264124557923083818518430926773544077233525827507879093955534745943"; + "32953309468943531490839943962309869402925783570438389574347733408052522035367"; + "41849214595467910123673033520102794108104712997008198889522813877734245824992"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "13385312906301377273955934436875769194431305104364014104682634101917200197278"; + "33312374379319542810991447038237232988042258339322606967927166686005294530141"; + "2737318182661479970580613550792855222106118769205538817720593077458586232462"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "25934304330824777179395950377293803672187454562170204848490728738678115541128"; + "28069804560566986820780141306617957617142124689083726799461195695753383204290"; + "34993469540808095486523884664145037729429846937484126092996667946941269260665"; + "11844085669837119750115930248863854777199847054885070800716560090573754609681"; + "35914353067034535100652019426938814231673372200100789099223322096377158467494"; + "520503526423274284711901945026220761232488147249669637631551937442183120274"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + "39773999529478581065965404144373550265474871993312600979434555965805982959674"; + "18192150206125313032264815747914724777905185814539525394719756794023760665086"; + "7169284984681148301101070301086569799214236786154614020456024084708327543744"; + "12609311342646272297200914221417675005357093654436013989372519104778233478270"; + "31170352425453189271982573751891724347094384200281623320937122512461975148357"; + "43222315627129083568275705268856575434253276738761458024197396244348192453816"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + "27137694804103784268118506475266175668513933624428580267061207329693588554116"; + "29493317929139945087331316348191328190403379874196425053979399148385870374626"; + "7638134712636322282750220652430072697753918180880580620720783612440458134642"; + "50625858391910681386377169116496102383629369302093953246867762562643904782135"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "33293363571203305765518098307458508738951719889060636983700129353536105487320"; + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "15765188586172333129026261765507777427830002956246082548695725135386026089531"; + "32953309468943531490839943962309869402925783570438389574347733408052522035367"; + "41849214595467910123673033520102794108104712997008198889522813877734245824992"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "31158152590223406958253833055870187482229277741032977785347732417871366938184"; + "33312374379319542810991447038237232988042258339322606967927166686005294530141"; + "2737318182661479970580613550792855222106118769205538817720593077458586232462"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "14766234537644355539949872368460173482297840168859677038523901539692763060334"; + "28069804560566986820780141306617957617142124689083726799461195695753383204290"; + "34993469540808095486523884664145037729429846937484126092996667946941269260665"; + "11844085669837119750115930248863854777199847054885070800716560090573754609681"; + "35914353067034535100652019426938814231673372200100789099223322096377158467494"; + "520503526423274284711901945026220761232488147249669637631551937442183120274"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + "50364513462222341644872927972152893188287310341312210911257616498800673072090"; + "18192150206125313032264815747914724777905185814539525394719756794023760665086"; + "7169284984681148301101070301086569799214236786154614020456024084708327543744"; + "12609311342646272297200914221417675005357093654436013989372519104778233478270"; + "31170352425453189271982573751891724347094384200281623320937122512461975148357"; + "43222315627129083568275705268856575434253276738761458024197396244348192453816"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + "36083369656588640571394881615882071309583905836597209849010517081129292381133"; + "29493317929139945087331316348191328190403379874196425053979399148385870374626"; + "7638134712636322282750220652430072697753918180880580620720783612440458134642"; + "50625858391910681386377169116496102383629369302093953246867762562643904782135"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "13673369653006216515617235627338566452016865434724788153202762846343942861319"; + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "45298132425441112218235385216467264374863717020516284112024948473015955374084"; + "32953309468943531490839943962309869402925783570438389574347733408052522035367"; + "41849214595467910123673033520102794108104712997008198889522813877734245824992"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "29524470991383628902485277756758611955172502193988354542727469903424895062856"; + "33312374379319542810991447038237232988042258339322606967927166686005294530141"; + "2737318182661479970580613550792855222106118769205538817720593077458586232462"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "15292339359480072132711509994191992458107233772646088214565467948291687686435"; + "28069804560566986820780141306617957617142124689083726799461195695753383204290"; + "34993469540808095486523884664145037729429846937484126092996667946941269260665"; + "11844085669837119750115930248863854777199847054885070800716560090573754609681"; + "35914353067034535100652019426938814231673372200100789099223322096377158467494"; + "520503526423274284711901945026220761232488147249669637631551937442183120274"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + "45603574302599021101902434031122226050335478068762259794493473555807247105595"; + "18192150206125313032264815747914724777905185814539525394719756794023760665086"; + "7169284984681148301101070301086569799214236786154614020456024084708327543744"; + "12609311342646272297200914221417675005357093654436013989372519104778233478270"; + "31170352425453189271982573751891724347094384200281623320937122512461975148357"; + "43222315627129083568275705268856575434253276738761458024197396244348192453816"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + "29864952522628173540141781827286025219255572638173950766594864104352748102539"; + "29493317929139945087331316348191328190403379874196425053979399148385870374626"; + "7638134712636322282750220652430072697753918180880580620720783612440458134642"; + "50625858391910681386377169116496102383629369302093953246867762562643904782135"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "16641564667155368214093686957385557686405362280765063076081101236567607472317"; + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "42204379350085294410776773079715228191662735656426212256162333812793552403993"; + "32953309468943531490839943962309869402925783570438389574347733408052522035367"; + "41849214595467910123673033520102794108104712997008198889522813877734245824992"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "1847629386593049442582088228888651742916508951275671968804128950653548728607"; + "33312374379319542810991447038237232988042258339322606967927166686005294530141"; + "2737318182661479970580613550792855222106118769205538817720593077458586232462"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "30544835368812793010213561008915983327461588018090146382657236899374564162730"; + "28069804560566986820780141306617957617142124689083726799461195695753383204290"; + "34993469540808095486523884664145037729429846937484126092996667946941269260665"; + "11844085669837119750115930248863854777199847054885070800716560090573754609681"; + "35914353067034535100652019426938814231673372200100789099223322096377158467494"; + "520503526423274284711901945026220761232488147249669637631551937442183120274"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + "28595648932918935772445374385314895104412006232383782075196768579632846450674"; + "18192150206125313032264815747914724777905185814539525394719756794023760665086"; + "7169284984681148301101070301086569799214236786154614020456024084708327543744"; + "12609311342646272297200914221417675005357093654436013989372519104778233478270"; + "31170352425453189271982573751891724347094384200281623320937122512461975148357"; + "43222315627129083568275705268856575434253276738761458024197396244348192453816"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + "47000259701454069967234544238066296258151585523185310016832999595782861846174"; + "29493317929139945087331316348191328190403379874196425053979399148385870374626"; + "7638134712636322282750220652430072697753918180880580620720783612440458134642"; + "50625858391910681386377169116496102383629369302093953246867762562643904782135"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "47703279462193590619364955077397056339622697689679116583920137294722168872744"; + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "30289339203582770465154470558134566153982220926251521920946038335272057457401"; + "32953309468943531490839943962309869402925783570438389574347733408052522035367"; + "41849214595467910123673033520102794108104712997008198889522813877734245824992"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "46550664815228892911835361428622023642836150007501939891947520631998198520461"; + "33312374379319542810991447038237232988042258339322606967927166686005294530141"; + "2737318182661479970580613550792855222106118769205538817720593077458586232462"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "29330496567572546017153710518251054135983574840194932992496153317832580755621"; + "28069804560566986820780141306617957617142124689083726799461195695753383204290"; + "34993469540808095486523884664145037729429846937484126092996667946941269260665"; + "11844085669837119750115930248863854777199847054885070800716560090573754609681"; + "35914353067034535100652019426938814231673372200100789099223322096377158467494"; + "520503526423274284711901945026220761232488147249669637631551937442183120274"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + "23521896256625658872048253216362574573656709966770066603163571873126564832134"; + "18192150206125313032264815747914724777905185814539525394719756794023760665086"; + "7169284984681148301101070301086569799214236786154614020456024084708327543744"; + "12609311342646272297200914221417675005357093654436013989372519104778233478270"; + "31170352425453189271982573751891724347094384200281623320937122512461975148357"; + "43222315627129083568275705268856575434253276738761458024197396244348192453816"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + "26872945751991350642631421070723241120870220431408930340372284319898628216320"; + "29493317929139945087331316348191328190403379874196425053979399148385870374626"; + "7638134712636322282750220652430072697753918180880580620720783612440458134642"; + "50625858391910681386377169116496102383629369302093953246867762562643904782135"; + "44272122653750460801234557742923174986464497642858313467284296699819305989270"; + "11252096837444447077479443148219111380485423018273939574785760442435635849620"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + "40997078256594146220685824349789077364499556772111503769304227994615031515994"; + |] diff --git a/src/lib_mec/test/test_babyjubjub.ml b/src/lib_mec/test/test_babyjubjub.ml new file mode 100644 index 000000000000..447f02f6eb69 --- /dev/null +++ b/src/lib_mec/test/test_babyjubjub.ml @@ -0,0 +1,142 @@ +module ValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.BabyJubjub.Affine) +module Equality = Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.BabyJubjub.Affine) +module Properties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.BabyJubjub.Affine) +module EdwardsCurveProperties = + Mec.Curve.Utils.PBT.MakeEdwardsCurveProperties (Mec.Curve.BabyJubjub.Affine) +module Serialisation = + Mec.Curve.Utils.PBT.MakeSerialisationProperties (Mec.Curve.BabyJubjub.Affine) + +let test_doubling () = + let vectors = + [ + ( ( "17777552123799933955779906779655732241715742912184938656739573121738514868268", + "2626589144620713026669568689430873010625803728049924121243784502389097019475" + ), + ( "6890855772600357754907169075114257697580319025794532037257385534741338397365", + "4338620300185947561074059802482547481416142213883829469920100239455078257889" + ) ); + ] + in + List.iter + (fun ((x1, y1), (x2, y2)) -> + let x1 = Mec.Curve.BabyJubjub.Affine.Base.of_string x1 in + let y1 = Mec.Curve.BabyJubjub.Affine.Base.of_string y1 in + let x2 = Mec.Curve.BabyJubjub.Affine.Base.of_string x2 in + let y2 = Mec.Curve.BabyJubjub.Affine.Base.of_string y2 in + let p1 = Mec.Curve.BabyJubjub.Affine.from_coordinates_exn ~u:x1 ~v:y1 in + let p2 = Mec.Curve.BabyJubjub.Affine.from_coordinates_exn ~u:x2 ~v:y2 in + assert (Mec.Curve.BabyJubjub.Affine.(eq (double p1) p2))) + vectors + +let test_addition () = + let vectors = + [ + ( ( "17777552123799933955779906779655732241715742912184938656739573121738514868268", + "2626589144620713026669568689430873010625803728049924121243784502389097019475" + ), + ( "16540640123574156134436876038791482806971768689494387082833631921987005038935", + "20819045374670962167435360035096875258406992893633759881276124905556507972311" + ), + ( "7916061937171219682591368294088513039687205273691143098332585753343424131937", + "14035240266687799601661095864649209771790948434046947201833777492504781204499" + ) ); + ] + in + List.iter + (fun ((x1, y1), (x2, y2), (x3, y3)) -> + let x1 = Mec.Curve.BabyJubjub.Affine.Base.of_string x1 in + let y1 = Mec.Curve.BabyJubjub.Affine.Base.of_string y1 in + let x2 = Mec.Curve.BabyJubjub.Affine.Base.of_string x2 in + let y2 = Mec.Curve.BabyJubjub.Affine.Base.of_string y2 in + let x3 = Mec.Curve.BabyJubjub.Affine.Base.of_string x3 in + let y3 = Mec.Curve.BabyJubjub.Affine.Base.of_string y3 in + let p1 = Mec.Curve.BabyJubjub.Affine.from_coordinates_exn ~u:x1 ~v:y1 in + let p2 = Mec.Curve.BabyJubjub.Affine.from_coordinates_exn ~u:x2 ~v:y2 in + let p3 = Mec.Curve.BabyJubjub.Affine.from_coordinates_exn ~u:x3 ~v:y3 in + assert (Mec.Curve.BabyJubjub.Affine.(eq (add p1 p2) p3)) ; + assert (Mec.Curve.BabyJubjub.Affine.(eq (add p2 p1) p3)) ; + assert (Mec.Curve.BabyJubjub.Affine.(not (eq (add p1 p2) p1)))) + vectors + +let test_mul_scalar () = + let vectors = + [ + ( ( "17777552123799933955779906779655732241715742912184938656739573121738514868268", + "2626589144620713026669568689430873010625803728049924121243784502389097019475" + ), + "14035240266687799601661095864649209771790948434046947201833777492504781204499", + ( "17070357974431721403481313912716834497662307308519659060910483826664480189605", + "4014745322800118607127020275658861516666525056516280575712425373174125159339" + ) ); + ] + in + List.iter + (fun ((x1, y1), n, (x2, y2)) -> + let x1 = Mec.Curve.BabyJubjub.Affine.Base.of_string x1 in + let y1 = Mec.Curve.BabyJubjub.Affine.Base.of_string y1 in + let x2 = Mec.Curve.BabyJubjub.Affine.Base.of_string x2 in + let y2 = Mec.Curve.BabyJubjub.Affine.Base.of_string y2 in + let n = Mec.Curve.BabyJubjub.Affine.Scalar.of_string n in + let p1 = Mec.Curve.BabyJubjub.Affine.from_coordinates_exn ~u:x1 ~v:y1 in + let p2 = Mec.Curve.BabyJubjub.Affine.from_coordinates_exn ~u:x2 ~v:y2 in + assert (Mec.Curve.BabyJubjub.Affine.(eq (mul p1 n) p2))) + vectors + +let test_random_points_not_on_curve () = + (* pick random values u and v and test constructors fail *) + let u = Mec.Curve.BabyJubjub.Affine.Base.random () in + let v = Mec.Curve.BabyJubjub.Affine.Base.random () in + let bytes = + Bytes.concat + Bytes.empty + [ + Mec.Curve.BabyJubjub.Affine.Base.to_bytes u; + Mec.Curve.BabyJubjub.Affine.Base.to_bytes v; + ] + in + (* check_bytes *) + assert (not (Mec.Curve.BabyJubjub.Affine.check_bytes bytes)) ; + (* of_bytes_opt *) + assert (Option.is_none (Mec.Curve.BabyJubjub.Affine.of_bytes_opt bytes)) ; + (* of_bytes_exn *) + (try + ignore (Mec.Curve.BabyJubjub.Affine.of_bytes_exn bytes) ; + assert false + with + | Mec.Curve.BabyJubjub.Affine.Not_on_curve _ -> () + | _ -> assert false) ; + (* from_coordinates_opt *) + assert ( + Option.is_none (Mec.Curve.BabyJubjub.Affine.from_coordinates_opt ~u ~v)) ; + (* from_coordinates_exn *) + try + ignore (Mec.Curve.BabyJubjub.Affine.from_coordinates_exn ~u ~v) ; + assert false + with + | Mec.Curve.BabyJubjub.Affine.Not_on_curve _ -> () + | _ -> assert false + +let () = + let open Alcotest in + run + ~verbose:true + "BabyJubjub" + [ + ( "Vectors", + [ + Alcotest.test_case "test vectors addition" `Quick test_addition; + Alcotest.test_case "test scalar multiplication" `Quick test_mul_scalar; + Alcotest.test_case + "test random coordinates u, v do not give a point on the curve" + `Quick + (Mec.Curve.Utils.PBT.repeat 100 test_random_points_not_on_curve); + Alcotest.test_case "test vectors doubling" `Quick test_doubling; + ] ); + ValueGeneration.get_tests (); + Properties.get_tests (); + Serialisation.get_tests (); + EdwardsCurveProperties.get_tests (); + Equality.get_tests (); + ] diff --git a/src/lib_mec/test/test_babyjubjub_reduced.ml b/src/lib_mec/test/test_babyjubjub_reduced.ml new file mode 100644 index 000000000000..e6ccc604faeb --- /dev/null +++ b/src/lib_mec/test/test_babyjubjub_reduced.ml @@ -0,0 +1,67 @@ +module ValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.BabyJubjubReduced.Affine) +module Equality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.BabyJubjubReduced.Affine) +module Properties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.BabyJubjubReduced.Affine) +module EdwardsCurveProperties = + Mec.Curve.Utils.PBT.MakeEdwardsCurveProperties + (Mec.Curve.BabyJubjubReduced.Affine) +module Serialisation = + Mec.Curve.Utils.PBT.MakeSerialisationProperties + (Mec.Curve.BabyJubjubReduced.Affine) + +let test_random_points_not_on_curve () = + (* pick random values u and v and test constructors fail *) + let u = Mec.Curve.BabyJubjubReduced.Affine.Base.random () in + let v = Mec.Curve.BabyJubjubReduced.Affine.Base.random () in + let bytes = + Bytes.concat + Bytes.empty + [ + Mec.Curve.BabyJubjubReduced.Affine.Base.to_bytes u; + Mec.Curve.BabyJubjubReduced.Affine.Base.to_bytes v; + ] + in + (* check_bytes *) + assert (not (Mec.Curve.BabyJubjubReduced.Affine.check_bytes bytes)) ; + (* of_bytes_opt *) + assert (Option.is_none (Mec.Curve.BabyJubjubReduced.Affine.of_bytes_opt bytes)) ; + (* of_bytes_exn *) + (try + ignore (Mec.Curve.BabyJubjubReduced.Affine.of_bytes_exn bytes) ; + assert false + with + | Mec.Curve.BabyJubjubReduced.Affine.Not_on_curve _ -> () + | _ -> assert false) ; + (* from_coordinates_opt *) + assert ( + Option.is_none + (Mec.Curve.BabyJubjubReduced.Affine.from_coordinates_opt ~u ~v)) ; + (* from_coordinates_exn *) + try + ignore (Mec.Curve.BabyJubjubReduced.Affine.from_coordinates_exn ~u ~v) ; + assert false + with + | Mec.Curve.BabyJubjubReduced.Affine.Not_on_curve _ -> () + | _ -> assert false + +let () = + let open Alcotest in + run + ~verbose:true + "BabyJubjub reduced twisted edwards form" + [ + ( "Vectors", + [ + Alcotest.test_case + "test random coordinates u, v do not give a point on the curve" + `Quick + (Mec.Curve.Utils.PBT.repeat 100 test_random_points_not_on_curve); + ] ); + ValueGeneration.get_tests (); + EdwardsCurveProperties.get_tests (); + Properties.get_tests (); + Serialisation.get_tests (); + Equality.get_tests (); + ] diff --git a/src/lib_mec/test/test_bandersnatch_affine_edwards.ml b/src/lib_mec/test/test_bandersnatch_affine_edwards.ml new file mode 100644 index 000000000000..2cde3df47710 --- /dev/null +++ b/src/lib_mec/test/test_bandersnatch_affine_edwards.ml @@ -0,0 +1,21 @@ +module ValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Bandersnatch.AffineEdwards) +module Equality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Bandersnatch.AffineEdwards) +module Properties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Bandersnatch.AffineEdwards) +module EdwardsCurveProperties = + Mec.Curve.Utils.PBT.MakeEdwardsCurveProperties + (Mec.Curve.Bandersnatch.AffineEdwards) + +let () = + let open Alcotest in + run + ~verbose:true + "Bandersnatch Edwards form, affine coordinates" + [ + ValueGeneration.get_tests (); + Properties.get_tests (); + EdwardsCurveProperties.get_tests (); + Equality.get_tests (); + ] diff --git a/src/lib_mec/test/test_bandersnatch_affine_montgomery.ml b/src/lib_mec/test/test_bandersnatch_affine_montgomery.ml new file mode 100644 index 000000000000..76bfbbabc431 --- /dev/null +++ b/src/lib_mec/test/test_bandersnatch_affine_montgomery.ml @@ -0,0 +1,18 @@ +module ValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration + (Mec.Curve.Bandersnatch.AffineMontgomery) +module Equality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Bandersnatch.AffineMontgomery) +module Properties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Bandersnatch.AffineMontgomery) + +let () = + let open Alcotest in + run + ~verbose:true + "Bandersnatch Montgomery form and affine coordinates" + [ + ValueGeneration.get_tests (); + Properties.get_tests (); + Equality.get_tests (); + ] diff --git a/src/lib_mec/test/test_bandersnatch_affine_weierstrass.ml b/src/lib_mec/test/test_bandersnatch_affine_weierstrass.ml new file mode 100644 index 000000000000..a2413ae90752 --- /dev/null +++ b/src/lib_mec/test/test_bandersnatch_affine_weierstrass.ml @@ -0,0 +1,22 @@ +module BandersnatchAffineValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration + (Mec.Curve.Bandersnatch.AffineWeierstrass) +module BandersnatchAffineEquality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Bandersnatch.AffineWeierstrass) +module BandersnatchAffineECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Bandersnatch.AffineWeierstrass) +module BandersnatchAffineRepresentation = + Mec.Curve.Utils.PBT.MakeCompressedSerialisationAffine + (Mec.Curve.Bandersnatch.AffineWeierstrass) + +let () = + let open Alcotest in + run + ~verbose:true + "Bandersnatch Weierstrass form, affine coordinates" + [ + BandersnatchAffineValueGeneration.get_tests (); + BandersnatchAffineEquality.get_tests (); + BandersnatchAffineECProperties.get_tests (); + BandersnatchAffineRepresentation.get_tests (); + ] diff --git a/src/lib_mec/test/test_bls12_381_affine.ml b/src/lib_mec/test/test_bls12_381_affine.ml new file mode 100644 index 000000000000..dfcfadc362c5 --- /dev/null +++ b/src/lib_mec/test/test_bls12_381_affine.ml @@ -0,0 +1,18 @@ +open Mec.Curve +module G1ValueGeneration = Utils.PBT.MakeValueGeneration (BLS12_381.G1.Affine) +module G1Equality = Utils.PBT.MakeEquality (BLS12_381.G1.Affine) +module G1ECProperties = Utils.PBT.MakeECProperties (BLS12_381.G1.Affine) +module G1Representation = + Mec.Curve.Utils.PBT.MakeCompressedSerialisationAffine (BLS12_381.G1.Affine) + +let () = + let open Alcotest in + run + ~verbose:true + "BLS12-381 G1 affine form" + [ + G1ValueGeneration.get_tests (); + G1Equality.get_tests (); + G1ECProperties.get_tests (); + G1Representation.get_tests (); + ] diff --git a/src/lib_mec/test/test_bls12_381_projective.ml b/src/lib_mec/test/test_bls12_381_projective.ml new file mode 100644 index 000000000000..9811ca623a33 --- /dev/null +++ b/src/lib_mec/test/test_bls12_381_projective.ml @@ -0,0 +1,16 @@ +open Mec.Curve +module G1ValueGeneration = + Utils.PBT.MakeValueGeneration (BLS12_381.G1.Projective) +module G1Equality = Utils.PBT.MakeEquality (BLS12_381.G1.Projective) +module G1ECProperties = Utils.PBT.MakeECProperties (BLS12_381.G1.Projective) + +let () = + let open Alcotest in + run + ~verbose:true + "BLS12-381 G1 projective form" + [ + G1ValueGeneration.get_tests (); + G1Equality.get_tests (); + G1ECProperties.get_tests (); + ] diff --git a/src/lib_mec/test/test_bn254_affine.ml b/src/lib_mec/test/test_bn254_affine.ml new file mode 100644 index 000000000000..5847eb0b4180 --- /dev/null +++ b/src/lib_mec/test/test_bn254_affine.ml @@ -0,0 +1,20 @@ +module BN254AffineValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.BN254.Affine) +module BN254AffineEquality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.BN254.Affine) +module BN254AffineECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.BN254.Affine) +module BN254AffineRepresentation = + Mec.Curve.Utils.PBT.MakeCompressedSerialisationAffine (Mec.Curve.BN254.Affine) + +let () = + let open Alcotest in + run + ~verbose:true + "BN254 affine form" + [ + BN254AffineValueGeneration.get_tests (); + BN254AffineEquality.get_tests (); + BN254AffineECProperties.get_tests (); + BN254AffineRepresentation.get_tests (); + ] diff --git a/src/lib_mec/test/test_bn254_jacobian.ml b/src/lib_mec/test/test_bn254_jacobian.ml new file mode 100644 index 000000000000..a6e412f32852 --- /dev/null +++ b/src/lib_mec/test/test_bn254_jacobian.ml @@ -0,0 +1,17 @@ +module BN254JacobianValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.BN254.Jacobian) +module BN254JacobianEquality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.BN254.Jacobian) +module BN254JacobianECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.BN254.Jacobian) + +let () = + let open Alcotest in + run + ~verbose:true + "BN254 jacobian coordinates" + [ + BN254JacobianValueGeneration.get_tests (); + BN254JacobianEquality.get_tests (); + BN254JacobianECProperties.get_tests (); + ] diff --git a/src/lib_mec/test/test_bn254_projective.ml b/src/lib_mec/test/test_bn254_projective.ml new file mode 100644 index 000000000000..d4b4b6bb7489 --- /dev/null +++ b/src/lib_mec/test/test_bn254_projective.ml @@ -0,0 +1,17 @@ +module BN254ProjectiveValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.BN254.Projective) +module BN254ProjectiveEquality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.BN254.Projective) +module BN254ProjectiveECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.BN254.Projective) + +let () = + let open Alcotest in + run + ~verbose:true + "BN254 projective form" + [ + BN254ProjectiveValueGeneration.get_tests (); + BN254ProjectiveEquality.get_tests (); + BN254ProjectiveECProperties.get_tests (); + ] diff --git a/src/lib_mec/test/test_curve25519_affine_edwards.ml b/src/lib_mec/test/test_curve25519_affine_edwards.ml new file mode 100644 index 000000000000..40724a6e9770 --- /dev/null +++ b/src/lib_mec/test/test_curve25519_affine_edwards.ml @@ -0,0 +1,21 @@ +module ValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Curve25519.AffineEdwards) +module Equality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Curve25519.AffineEdwards) +module Properties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Curve25519.AffineEdwards) +module EdwardsCurveProperties = + Mec.Curve.Utils.PBT.MakeEdwardsCurveProperties + (Mec.Curve.Curve25519.AffineEdwards) + +let () = + let open Alcotest in + run + ~verbose:true + "Curve25519 edwards form and affine coordinates" + [ + ValueGeneration.get_tests (); + Properties.get_tests (); + EdwardsCurveProperties.get_tests (); + Equality.get_tests (); + ] diff --git a/src/lib_mec/test/test_curve25519_conversions_between_forms.ml b/src/lib_mec/test/test_curve25519_conversions_between_forms.ml new file mode 100644 index 000000000000..33c512851238 --- /dev/null +++ b/src/lib_mec/test/test_curve25519_conversions_between_forms.ml @@ -0,0 +1,98 @@ +open Mec.Curve.Curve25519 +module AffineEdwards = Mec.Curve.Curve25519.AffineEdwards + +let rec repeat n f = + if n <= 0 then + let f () = () in + f + else ( + f () ; + repeat (n - 1) f) + +let test_generation () = + let pt_ed1 = AffineEdwards.random () in + let pt_mt1 = from_affine_edwards_to_affine_montgomery pt_ed1 in + assert (Option.(is_some pt_mt1)) ; + let pt_mt2 = AffineMontgomery.random () in + let pt_ed2 = from_affine_montgomery_to_affine_edwards pt_mt2 in + assert (Option.(is_some pt_ed2)) + +let test_addition () = + (* Edwards -> Montgomery *) + let pt_ed1 = AffineEdwards.random () in + let pt_ed2 = AffineEdwards.random () in + let pt_ed1_add = AffineEdwards.add pt_ed1 pt_ed2 in + let pt_mt1 = from_affine_edwards_to_affine_montgomery pt_ed1 |> Option.get in + let pt_mt2 = from_affine_edwards_to_affine_montgomery pt_ed2 |> Option.get in + let pt_mt1_add = AffineMontgomery.add pt_mt1 pt_mt2 in + let pt_ed2_add = + from_affine_montgomery_to_affine_edwards pt_mt1_add |> Option.get + in + let pt_mt2_add = + from_affine_edwards_to_affine_montgomery pt_ed1_add |> Option.get + in + assert (AffineMontgomery.eq pt_mt1_add pt_mt2_add) ; + assert (AffineEdwards.eq pt_ed1_add pt_ed2_add) ; + (* Montgomery -> Edwards *) + let pt_mta = AffineMontgomery.random () in + let pt_mtb = AffineMontgomery.random () in + let pt_mta_add = AffineMontgomery.add pt_mta pt_mtb in + let pt_eda = from_affine_montgomery_to_affine_edwards pt_mta |> Option.get in + let pt_edb = from_affine_montgomery_to_affine_edwards pt_mtb |> Option.get in + let pt_eda_add = AffineEdwards.add pt_eda pt_edb in + let pt_mtb_add = + from_affine_edwards_to_affine_montgomery pt_eda_add |> Option.get + in + let pt_edb_add = + from_affine_montgomery_to_affine_edwards pt_mta_add |> Option.get + in + assert (AffineEdwards.eq pt_eda_add pt_edb_add) ; + assert (AffineMontgomery.eq pt_mta_add pt_mtb_add) + +let test_multiplication () = + (* Edwards -> Montgomery *) + let pt_ed1 = AffineEdwards.random () in + let alpha = AffineEdwards.Scalar.random () in + let pt_ed1_mul = AffineEdwards.mul pt_ed1 alpha in + let pt_mt1 = from_affine_edwards_to_affine_montgomery pt_ed1 |> Option.get in + let alpha = AffineMontgomery.Scalar.of_z (AffineEdwards.Scalar.to_z alpha) in + let pt_mt1_mul = AffineMontgomery.mul pt_mt1 alpha in + let pt_ed2_mul = + from_affine_montgomery_to_affine_edwards pt_mt1_mul |> Option.get + in + let pt_mt2_mul = + from_affine_edwards_to_affine_montgomery pt_ed1_mul |> Option.get + in + assert (AffineMontgomery.eq pt_mt1_mul pt_mt2_mul) ; + assert (AffineEdwards.eq pt_ed1_mul pt_ed2_mul) ; + (* Montgomery -> Edwards *) + let pt_mta = AffineMontgomery.random () in + let beta = AffineMontgomery.Scalar.random () in + let pt_mta_mul = AffineMontgomery.mul pt_mta beta in + let pt_eda = from_affine_montgomery_to_affine_edwards pt_mta |> Option.get in + let beta = AffineEdwards.Scalar.of_z (AffineMontgomery.Scalar.to_z beta) in + let pt_eda_mul = AffineEdwards.mul pt_eda beta in + let pt_mtb_mul = + from_affine_edwards_to_affine_montgomery pt_eda_mul |> Option.get + in + let pt_edb_mul = + from_affine_montgomery_to_affine_edwards pt_mta_mul |> Option.get + in + assert (AffineEdwards.eq pt_eda_mul pt_edb_mul) ; + assert (AffineMontgomery.eq pt_mta_mul pt_mtb_mul) + +let get_tests () = + let open Alcotest in + ( "Edwards <-> Montgomery", + [ + test_case "Points are on both curves" `Quick (repeat 100 test_generation); + test_case "Addition" `Quick (repeat 100 test_addition); + test_case "Scalar multiplication" `Quick (repeat 100 test_multiplication); + ] ) + +let () = + let open Alcotest in + run + ~verbose:true + "Curve 25519 conversions between the different forms" + [get_tests ()] diff --git a/src/lib_mec/test/test_curve25519_montgomery.ml b/src/lib_mec/test/test_curve25519_montgomery.ml new file mode 100644 index 000000000000..2f1992455562 --- /dev/null +++ b/src/lib_mec/test/test_curve25519_montgomery.ml @@ -0,0 +1,17 @@ +module ValueGeneration_Mt = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Curve25519.AffineMontgomery) +module Equality_Mt = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Curve25519.AffineMontgomery) +module Properties_Mt = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Curve25519.AffineMontgomery) + +let () = + let open Alcotest in + run + ~verbose:true + "Curve25519" + [ + ValueGeneration_Mt.get_tests (); + Properties_Mt.get_tests (); + Equality_Mt.get_tests (); + ] diff --git a/src/lib_mec/test/test_curve448.ml b/src/lib_mec/test/test_curve448.ml new file mode 100644 index 000000000000..73529df2ce3c --- /dev/null +++ b/src/lib_mec/test/test_curve448.ml @@ -0,0 +1,19 @@ +module ValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Curve448.Affine) +module Equality = Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Curve448.Affine) +module Properties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Curve448.Affine) +module EdwardsCurveProperties = + Mec.Curve.Utils.PBT.MakeEdwardsCurveProperties (Mec.Curve.Curve448.Affine) + +let () = + let open Alcotest in + run + ~verbose:true + "Curve448" + [ + ValueGeneration.get_tests (); + Properties.get_tests (); + EdwardsCurveProperties.get_tests (); + Equality.get_tests (); + ] diff --git a/src/lib_mec/test/test_digestif.ml b/src/lib_mec/test/test_digestif.ml new file mode 100644 index 000000000000..eecf265b3df3 --- /dev/null +++ b/src/lib_mec/test/test_digestif.ml @@ -0,0 +1,119 @@ +(*****************************************************************************) +(* *) +(* Copyright (c) 2021 Danny Willems *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Digestif = Mec.Digestif + +let rec repeat n f () = + if n > 0 then ( + f () ; + repeat (n - 1) f ()) + +module Blake2b = Digestif.Make_BLAKE2B (struct + let digest_size = 64 +end) + +let test_blake2b_feed_twice_and_concat_is_the_same () = + let vectors = + [ + ( Bytes.init 16 (fun _ -> char_of_int (Random.int 256)), + Bytes.init (Random.int 1000) (fun _ -> char_of_int (Random.int 256)), + Bytes.init (Random.int 1000) (fun _ -> char_of_int (Random.int 256)) ); + ] + in + List.iter + (fun (personalisation, a, b) -> + let ab = Bytes.concat Bytes.empty [a; b] in + let ctx_1 = Blake2b.init ~personalisation () in + let ctx_1 = Blake2b.feed_bytes ctx_1 a in + let ctx_1 = Blake2b.feed_bytes ctx_1 b in + let res_1 = Blake2b.to_hex (Blake2b.get ctx_1) in + let ctx_2 = Blake2b.init ~personalisation () in + let ctx_2 = Blake2b.feed_bytes ctx_2 ab in + let res_2 = Blake2b.to_hex (Blake2b.get ctx_2) in + assert (String.equal res_1 res_2)) + vectors + +let test_vectors_blake2b () = + let vectors = + [ + ( Bytes.of_string "Zcash_RedJubjubH", + Hex.to_string + (`Hex + "1de4252d8a94cd363901802d944a267a27aabd81b5ee9205810a14e9b353c04f466f6f20626172"), + "7f1c630bd9ce5daac6d42506b860032d08e185896f5bf33082548644afb89ae4a34926112f066ac88819004263cde207423c74e158d53ed6e23c92f208a2ef1b" + ); + ( Bytes.of_string "Zcash_RedJubjubH", + Hex.to_string + (`Hex + "e733065e8fa3f5172cf389ba48990e0ae50af8650e34abdf44ac4e2a9cb4f454c533fef1b062737796cc00285ecda1d9b4adc1d9de324b359d2c011b9ed91dcca4616518b47dd47477d2a36614265044466f6f20626172"), + "7e7cd9dad1aa4890333558296a48038ac6f4b0730c238693867e3cc3711d5a471917c71cd695c8718ecaa8a69747f8454e35dda0c4a699ce2d1f166644acf80b" + ); + ( Bytes.make 16 '\000', + Hex.to_string (`Hex ""), + "786a02f742015903c6c6fd852552d272912f4740e15847618a86e217f71f5419d25e1031afee585313896444934eb04b903a685b1448b755d56f701afe9be2ce" + ); + ( Bytes.make 16 '\000', + Hex.to_string (`Hex "00"), + "2fa3f686df876995167e7c2e5d74c4c7b6e48f8068fe0e44208344d480f7904c36963e44115fe3eb2a3ac8694c28bcb4f5a0f3276f2e79487d8219057a506e4b" + ); + ] + in + List.iter + (fun (personalisation, input, expected_output) -> + let ctx = Blake2b.init ~personalisation () in + let ctx = Blake2b.feed_string ctx input in + let output = Blake2b.to_hex (Blake2b.get ctx) in + let output_bytes = Bytes.of_string output in + let expected_output_bytes = Bytes.of_string expected_output in + if not (Bytes.compare output_bytes expected_output_bytes = 0) then + Alcotest.failf + "Fail on input %s with personalisation %s. Expected output is %s but \ + the computed output is %s" + input + (Bytes.to_string personalisation) + (Hex.show (`Hex expected_output)) + output) + vectors + +let () = + Alcotest.run + ~verbose:true + "Digestif fork" + [ + ( "Blake2b test vectors", + [ + Alcotest.test_case + "Test vector with personalisation" + `Quick + test_vectors_blake2b; + ] ); + ( "Blake2b properties", + [ + Alcotest.test_case + "Feed twice and finalize gives the same result than feeding with \ + the concatenation and finalize" + `Quick + (repeat 100 test_blake2b_feed_twice_and_concat_is_the_same); + ] ); + ] diff --git a/src/lib_mec/test/test_ec_functor.ml b/src/lib_mec/test/test_ec_functor.ml new file mode 100644 index 000000000000..8cd73188f121 --- /dev/null +++ b/src/lib_mec/test/test_ec_functor.ml @@ -0,0 +1,33 @@ +let test_b_cannot_be_null_for_weierstrass_form () = + let module Fq = Ff.MakeFp (struct + let prime_order = Z.of_int 3 + end) in + try + let module E = + Mec.Curve.Utils.Functor.MakeProjectiveWeierstrass (Fq) (Fq) + (struct + let a = Fq.random () + + let b = Fq.zero + + let cofactor = Z.one + + let bytes_generator = Bytes.make (Fq.size_in_bytes * 3) '\000' + end) + in + assert false + with _ -> assert true + +let () = + Alcotest.run + ~verbose:true + "Curve functors" + [ + ( "Check initialisation strengthen conditions", + [ + Alcotest.test_case + "b cannot be null" + `Quick + test_b_cannot_be_null_for_weierstrass_form; + ] ); + ] diff --git a/src/lib_mec/test/test_find_group_hash.ml b/src/lib_mec/test/test_find_group_hash.ml new file mode 100644 index 000000000000..fe432232f725 --- /dev/null +++ b/src/lib_mec/test/test_find_group_hash.ml @@ -0,0 +1,83 @@ +(*****************************************************************************) +(* *) +(* Copyright (c) 2021 Danny Willems *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Mec.Protocol.Sapling +open Mec.Curve + +let test_vectors () = + let v = + [ + (* Spending key: + https://github.com/zcash/librustzcash/blob/da431a0eb207f69c9b0631d7d02136d819e1bfd9/zcash_primitives/src/constants.rs#L344 + *) + ( "Zcash_G_", + Bytes.empty, + ( "0x0926d4f32059c712d418a7ff26753b6ad5b9a7d3ef8e282747bf46920a95a753", + "0x57a1019e6de9b67553bb37d0c21cfd056d65674dcedbddbc305632adaaf2b530" + ) ); + (* note commitment: + https://github.com/zcash/librustzcash/blob/da431a0eb207f69c9b0631d7d02136d819e1bfd9/zcash_primitives/src/constants.rs#L312 + *) + ( "Zcash_PH", + Bytes.of_string "r", + ( "0x26eb9f8a9ec72a8ca1409aa1f33bec2cf0919d06ffb1ecdaa5143b34a8e36462", + "0x114b7501ad104c57949d77476e262c9596b78beafa9cc44cd4fc6365796c77ac" + ) ); + (* value commitment value generator: + https://github.com/zcash/librustzcash/blob/da431a0eb207f69c9b0631d7d02136d819e1bfd9/zcash_primitives/src/constants.rs#L328 + *) + ( "Zcash_cv", + Bytes.of_string "v", + ( "0x273f910d9ecc1615d8618ed1d15fef4e9472c89ac043042d36183b2cb4d7ef51", + "0x466a7e3a82f67ab1d32294fd89774ad6bc3332d0fa1ccd18a77a81f50667c8d7" + ) ); + (* value commitment randomness generator: + https://github.com/zcash/librustzcash/blob/da431a0eb207f69c9b0631d7d02136d819e1bfd9/zcash_primitives/src/constants.rs#L336 + *) + ( "Zcash_cv", + Bytes.of_string "r", + ( "0x6800f4fa0f001cfc7ff6826ad58004b4d1d8da41af03744e3bce3b7793664337", + "0x6d81d3a9cb45dedbe6fb2a6e1e22ab50ad46f1b0473b803b3caefab9380b6a8b" + ) ); + ] + in + List.iter + (fun (personalisation, bytes, (u, v)) -> + let u = Jubjub.AffineEdwards.Base.of_string u in + let v = Jubjub.AffineEdwards.Base.of_string v in + let expected_p = Jubjub.AffineEdwards.from_coordinates_exn ~u ~v in + let p = + GroupHash.find_group_hash bytes (Bytes.of_string personalisation) + in + assert (Jubjub.AffineEdwards.eq p expected_p)) + v + +let () = + Alcotest.run + ~verbose:true + "Find group hash" + [ + ( "Zcash test vectors", + [Alcotest.test_case "Test vectors" `Quick test_vectors] ); + ] diff --git a/src/lib_mec/test/test_hades_optimised.ml b/src/lib_mec/test/test_hades_optimised.ml new file mode 100644 index 000000000000..2ae4dfe03128 --- /dev/null +++ b/src/lib_mec/test/test_hades_optimised.ml @@ -0,0 +1,91 @@ +let rec repeat n f () = + if n > 0 then ( + f () ; + repeat (n - 1) f ()) + +module BaseParameters = struct + let width = 3 + + let full_rounds = 8 + + let partial_rounds = 56 + + let round_constants = Ark_poseidon128.v + + let partial_round_idx_to_permute = 2 + + let linear_transformation = Mds_poseidon128.v + + (* This is the first alpha such that pgc(alpha, p - 1) = 1 *) + let alpha = Z.of_string "5" +end + +module Scalar = Ff.MakeFp (struct + let prime_order = + Z.of_string + "52435875175126190479447740508185965837690552500527637822603658699938581184513" +end) + +let test_consistency_between_optimised_and_naive_with_a_fixed_batch_size () = + let module Parameters : Mec.Permutation.HadesLinearOptimisation.PARAMETERS = + struct + include BaseParameters + + let batch_size = 4 + end in + let module PermutationOptimised = + Mec.Permutation.HadesLinearOptimisation.Make (Parameters) (Scalar) + in + let module PermutationNaive = Mec.Permutation.Hades.Make (Parameters) (Scalar) + in + let state = Array.init Parameters.width (fun _ -> Scalar.random ()) in + let ctxt_naive = PermutationNaive.init state in + let ctxt_optimised = PermutationOptimised.init state in + PermutationNaive.apply ctxt_naive ; + PermutationOptimised.apply ctxt_optimised ; + let res_naive = PermutationNaive.get ctxt_naive in + let res_optimised = PermutationOptimised.get ctxt_optimised in + assert (Array.for_all2 Scalar.eq res_naive res_optimised) + +let test_consistency_between_optimised_and_naive_with_a_random_batch_size () = + let module Parameters : Mec.Permutation.HadesLinearOptimisation.PARAMETERS = + struct + include BaseParameters + + let batch_size = 1 + Random.int partial_rounds + end in + let module PermutationOptimised = + Mec.Permutation.HadesLinearOptimisation.Make (Parameters) (Scalar) + in + let module PermutationNaive = Mec.Permutation.Hades.Make (Parameters) (Scalar) + in + let state = Array.init Parameters.width (fun _ -> Scalar.random ()) in + let ctxt_naive = PermutationNaive.init state in + let ctxt_optimised = PermutationOptimised.init state in + PermutationNaive.apply ctxt_naive ; + PermutationOptimised.apply ctxt_optimised ; + let res_naive = PermutationNaive.get ctxt_naive in + let res_optimised = PermutationOptimised.get ctxt_optimised in + assert (Array.for_all2 Scalar.eq res_naive res_optimised) + +let () = + let open Alcotest in + run + "HADES Strategy Optimised with linear trick" + [ + ( "Test consistency between naive and optimised implementation", + [ + Alcotest.test_case + "On random values with a fixed batch size" + `Quick + (repeat + 100 + test_consistency_between_optimised_and_naive_with_a_fixed_batch_size); + Alcotest.test_case + "On random values with a random batch size" + `Quick + (repeat + 100 + test_consistency_between_optimised_and_naive_with_a_random_batch_size); + ] ); + ] diff --git a/src/lib_mec/test/test_iso_pallas_affine.ml b/src/lib_mec/test/test_iso_pallas_affine.ml new file mode 100644 index 000000000000..d84ebb0a6984 --- /dev/null +++ b/src/lib_mec/test/test_iso_pallas_affine.ml @@ -0,0 +1,21 @@ +open Mec.Curve +module IsoPallasValueGeneration = + Utils.PBT.MakeValueGeneration (Pallas.Iso.Affine) +module IsoPallasEquality = Utils.PBT.MakeEquality (Pallas.Iso.Affine) +module IsoPallasECProperties = Utils.PBT.MakeECProperties (Pallas.Iso.Affine) + +let test_isogeny () = + let r = Pallas.Iso.Affine.random () in + ignore @@ Pallas.iso_map r + +let () = + let open Alcotest in + run + ~verbose:true + "Iso Pallas affine form" + [ + ("Test isogeny", [test_case "With random point" `Quick test_isogeny]); + IsoPallasValueGeneration.get_tests (); + IsoPallasEquality.get_tests (); + IsoPallasECProperties.get_tests (); + ] diff --git a/src/lib_mec/test/test_iterator.ml b/src/lib_mec/test/test_iterator.ml new file mode 100644 index 000000000000..53031e51e03f --- /dev/null +++ b/src/lib_mec/test/test_iterator.ml @@ -0,0 +1,162 @@ +open Mec.Utils + +let test_one_byte () = + (* Single byte *) + let test_vectors = + [ + ("\x00", [0; 0; 0; 0; 0; 0; 0; 0]); + ("\x0f", [1; 1; 1; 1; 0; 0; 0; 0]); + ("\x10", [0; 0; 0; 0; 1; 0; 0; 0]); + ] + in + List.iter + (fun (b, expected_l) -> + let iterator = Iterator.Bit.of_bytes_le (Bytes.of_string b) in + List.iter + (fun exp_b -> assert (Iterator.Bit.next iterator = Some exp_b)) + expected_l ; + assert (Iterator.Bit.next iterator = None)) + test_vectors + +let test_from_bool_list () = + (* Single byte *) + let test_vectors = + [ + ([true; true; true], [1; 1; 1]); + ([false; true; true], [0; 1; 1]); + ([true; true; false; true; false], [1; 1; 0; 1; 0]); + ] + in + List.iter + (fun (b, expected_l) -> + let iterator = Iterator.Bit.of_bool_list b in + List.iter + (fun exp_b -> assert (Iterator.Bit.next iterator = Some exp_b)) + expected_l ; + assert (Iterator.Bit.next iterator = None)) + test_vectors + +let test_multiple_bytes () = + (* The individual bytes are given in big endian and are concatenated in the + order of appearance in the string + \x10\x00 represents 0x0010 in big endian, i.e. 16. + *) + let test_vectors = + [ + ("\x00\x00", [0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0]); + ("\x0f\x00", [1; 1; 1; 1; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0]); + ("\x10\x00", [0; 0; 0; 0; 1; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0]); + ( "\x10\x00\x10", + [0; 0; 0; 0; 1; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 0; 1; 0; 0; 0] + ); + ( "\x10\x00\x10\x2f", + [ + (* 0x10 *) + 0; + 0; + 0; + 0; + 1; + 0; + 0; + 0; + (* 0x00 *) + 0; + 0; + 0; + 0; + 0; + 0; + 0; + 0; + (* 0x10 *) + 0; + 0; + 0; + 0; + 1; + 0; + 0; + 0; + (* 0x2f *) + 1; + 1; + 1; + 1; + 0; + 1; + 0; + 0; + ] ); + ] + in + List.iter + (fun (b, expected_l) -> + let iterator = Iterator.Bit.of_bytes_le (Bytes.of_string b) in + List.iter + (fun exp_b -> assert (Iterator.Bit.next iterator = Some exp_b)) + expected_l ; + assert (Iterator.Bit.next iterator = None)) + test_vectors + +let test_is_processed () = + let test_vectors = + [ + ([], [(0, true); (1, true); (Random.int 1000, true)]); + ([true], [(0, false); (1, true); (2, true); (2 + Random.int 1000, true)]); + ([true; false; true], [(Random.int 3, false); (3 + Random.int 1000, true)]); + (let n = Random.int 1000 in + ( List.init n (fun _ -> Random.bool ()), + [(Random.int n, false); (n, true); (n + 1 + Random.int 1000, true)] )); + ([true; false; true], [(Random.int 3, false); (3 + Random.int 1000, true)]); + ] + in + List.iter + (fun (v, iterations) -> + List.iter + (fun (n, expected_value) -> + let iterator = Iterator.Bit.of_bool_list v in + for _ = 0 to n - 1 do + ignore @@ Iterator.Bit.next iterator + done ; + assert (Iterator.Bit.is_processed iterator = expected_value)) + iterations) + test_vectors + +let test_get_chunk () = + let test_vectors = + [ + ([], 5, [List.init 5 (fun _ -> 0)]); + ([true; false], 1, [[1]; [0]]); + ([true; false], 2, [[1; 0]; [0; 0]]); + ([true; false; true], 2, [[1; 0]; [1; 0]]); + ([true; false; true; true], 2, [[1; 0]; [1; 1]]); + ([true; false; true; true], 3, [[1; 0; 1]; [1; 0; 0]]); + ] + in + List.iter + (fun (l, chunk_size, exp_values) -> + let iterator = Iterator.Bit.of_bool_list l in + List.iter + (fun exp_value -> + let chunk = Iterator.Bit.get_chunk iterator chunk_size in + assert (chunk = exp_value)) + exp_values) + test_vectors + +let () = + Alcotest.run + ~verbose:true + "Iterator" + [ + ( "Bytes", + [ + Alcotest.test_case "One byte" `Quick test_one_byte; + Alcotest.test_case "Multiple bytes" `Quick test_multiple_bytes; + ] ); + ( "Bool list", + [Alcotest.test_case "Test vectors" `Quick test_from_bool_list] ); + ( "Utils functions", + [Alcotest.test_case "is processed" `Quick test_is_processed] ); + ("get chunk", [Alcotest.test_case "get chnk" `Quick test_get_chunk]); + ] diff --git a/src/lib_mec/test/test_jubjub.ml b/src/lib_mec/test/test_jubjub.ml new file mode 100644 index 000000000000..2241943cd4af --- /dev/null +++ b/src/lib_mec/test/test_jubjub.ml @@ -0,0 +1,776 @@ +module ValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Jubjub.AffineEdwards) +module Equality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Jubjub.AffineEdwards) +module Properties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Jubjub.AffineEdwards) +module EdwardsCurveProperties = + Mec.Curve.Utils.PBT.MakeEdwardsCurveProperties (Mec.Curve.Jubjub.AffineEdwards) + +let test_vectors () = + (* Coming from + https://github.com/zcash/librustzcash/blob/1b4aab0b76d465e4fe548f230b7c3ebdc398a1a5/zcash_primitives/src/constants.rs *) + let points = + [ + ( "0x73c016a42ded9578b5ea25de7ec0e3782f0c718f6f0fbadd194e42926f661b51", + "0x289e87a2d3521b5779c9166b837edc5ef9472e8bc04e463277bfabd432243cca" ); + ( "0x15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e", + "0x015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891" ); + ( "0x664321a58246e2f6eb69ae39f5c84210bae8e5c46641ae5c76d6f7c2b67fc475", + "0x362e1500d24eee9ee000a46c8e8ce8538bb22a7f1784b49880ed502c9793d457" ); + ( "0x323a6548ce9d9876edc5f4a9cff29fd57d02d50e654b87f24c767804c1c4a2cc", + "0x2f7ee40c4b56cad891070acbd8d947b75103afa1a11f6a8584714beca33570e9" ); + ( "0x3bd2666000b5479689b64b4e03362796efd5931305f2f0bf46809430657f82d1", + "0x494bc52103ab9d0a397832381406c9e5b3b9d8095859d14c99968299c3658aef" ); + ( "0x63447b2ba31bb28ada049746d76d3ee51d9e5ca21135ff6fcb3c023258d32079", + "0x64ec4689e8bfb6e564cdb1070a136a28a80200d2c66b13a7436082119f8d629a" ); + ] + in + List.iter + (fun (u, v) -> + (* from_coordinates_exn *) + ignore + @@ Mec.Curve.Jubjub.AffineEdwards.from_coordinates_exn + ~u:(Mec.Curve.Jubjub.AffineEdwards.Base.of_string u) + ~v:(Mec.Curve.Jubjub.AffineEdwards.Base.of_string v) ; + (* from_coordinates_opt *) + assert ( + Option.is_some + (Mec.Curve.Jubjub.AffineEdwards.from_coordinates_opt + ~u:(Mec.Curve.Jubjub.AffineEdwards.Base.of_string u) + ~v:(Mec.Curve.Jubjub.AffineEdwards.Base.of_string v))) ; + (* convert to bytes. Use Zarith for simplicity as points are given in hexa *) + let bytes = + Bytes.concat + Bytes.empty + [ + (Bytes.of_string @@ Z.(to_bits (of_string u))); + (Bytes.of_string @@ Z.(to_bits (of_string v))); + ] + in + (* of_bytes_opt *) + assert (Option.is_some (Mec.Curve.Jubjub.AffineEdwards.of_bytes_opt bytes)) ; + (* of_bytes_exn *) + ignore @@ Mec.Curve.Jubjub.AffineEdwards.of_bytes_exn bytes ; + (* check_bytes *) + assert (Mec.Curve.Jubjub.AffineEdwards.check_bytes bytes)) + points + +let test_random_points_not_on_curve () = + (* pick random values u and v and test constructors fail *) + let u = Mec.Curve.Jubjub.AffineEdwards.Base.random () in + let v = Mec.Curve.Jubjub.AffineEdwards.Base.random () in + let bytes = + Bytes.concat + Bytes.empty + [ + Mec.Curve.Jubjub.AffineEdwards.Base.to_bytes u; + Mec.Curve.Jubjub.AffineEdwards.Base.to_bytes v; + ] + in + (* check_bytes *) + assert (not (Mec.Curve.Jubjub.AffineEdwards.check_bytes bytes)) ; + (* of_bytes_opt *) + assert (Option.is_none (Mec.Curve.Jubjub.AffineEdwards.of_bytes_opt bytes)) ; + (* of_bytes_exn *) + (try + ignore (Mec.Curve.Jubjub.AffineEdwards.of_bytes_exn bytes) ; + assert false + with + | Mec.Curve.Jubjub.AffineEdwards.Not_on_curve _ -> () + | _ -> assert false) ; + (* from_coordinates_opt *) + assert ( + Option.is_none (Mec.Curve.Jubjub.AffineEdwards.from_coordinates_opt ~u ~v)) ; + (* from_coordinates_exn *) + try + ignore (Mec.Curve.Jubjub.AffineEdwards.from_coordinates_exn ~u ~v) ; + assert false + with + | Mec.Curve.Jubjub.AffineEdwards.Not_on_curve _ -> () + | _ -> assert false + +let test_compressed_uncompressed_zero () = + let expected_encoding_of_zero = + Bytes.sub Mec.Curve.Jubjub.AffineEdwards.(to_bytes zero) 32 32 + in + assert ( + Mec.Curve.Jubjub.AffineEdwards.( + Bytes.equal (to_compressed zero) expected_encoding_of_zero)) ; + assert ( + Mec.Curve.Jubjub.AffineEdwards.( + eq zero (of_compressed_exn expected_encoding_of_zero))) ; + assert ( + Mec.Curve.Jubjub.AffineEdwards.( + eq zero (Option.get @@ of_compressed_opt expected_encoding_of_zero))) + +let test_compressed_and_uncompressed_exn () = + let p = Mec.Curve.Jubjub.AffineEdwards.random () in + let compressed_p = Mec.Curve.Jubjub.AffineEdwards.to_compressed p in + let uncompressed_p = + Mec.Curve.Jubjub.AffineEdwards.of_compressed_exn compressed_p + in + assert (Mec.Curve.Jubjub.AffineEdwards.eq p uncompressed_p) + +let test_compressed_gives_32_bytes () = + let compressed_p = + Mec.Curve.Jubjub.AffineEdwards.(to_compressed (random ())) + in + assert (Bytes.length compressed_p = 32) + +let test_compressed_and_uncompressed_opt () = + let p = Mec.Curve.Jubjub.AffineEdwards.random () in + let compressed_p = Mec.Curve.Jubjub.AffineEdwards.to_compressed p in + let uncompressed_p = + Option.get @@ Mec.Curve.Jubjub.AffineEdwards.of_compressed_opt compressed_p + in + assert (Mec.Curve.Jubjub.AffineEdwards.eq p uncompressed_p) + +let rec test_uncompressed_fail_on_random_values () = + let nb_bytes = + Random.int (Mec.Curve.Jubjub.AffineEdwards.size_in_bytes * 10) + in + if nb_bytes = Mec.Curve.Jubjub.AffineEdwards.size_in_bytes then + test_uncompressed_fail_on_random_values () + else + let b = Bytes.create nb_bytes in + assert (Option.is_none (Mec.Curve.Jubjub.AffineEdwards.of_compressed_opt b)) ; + try ignore @@ Mec.Curve.Jubjub.AffineEdwards.of_compressed_exn b with + | Mec.Curve.Jubjub.AffineEdwards.Not_on_curve exn_b -> + assert (Bytes.equal b exn_b) + | _ -> assert false + +let test_vector_compressed_and_uncompressed () = + let u_bytes, v_bytes = + ( "0x62edcbb8bf3787c88b0f03ddd60a8187caf55d1b29bf81afe4b3d35df1a7adfe", + "0x000000000000000000000000000000000000000000000000000000000000000b" ) + in + let full_generator = + Mec.Curve.Jubjub.AffineEdwards.from_coordinates_exn + ~u:(Mec.Curve.Jubjub.AffineEdwards.Base.of_string u_bytes) + ~v:(Mec.Curve.Jubjub.AffineEdwards.Base.of_string v_bytes) + in + let gen = + Mec.Curve.Jubjub.AffineEdwards.mul + full_generator + (Mec.Curve.Jubjub.AffineEdwards.Scalar.of_z + Mec.Curve.Jubjub.AffineEdwards.cofactor) + in + let vectors_as_int = + [ + [ + 203; + 85; + 12; + 213; + 56; + 234; + 12; + 193; + 19; + 132; + 128; + 64; + 142; + 110; + 170; + 185; + 179; + 108; + 97; + 63; + 13; + 211; + 247; + 120; + 79; + 219; + 110; + 234; + 131; + 123; + 19; + 215; + ]; + [ + 113; + 154; + 240; + 230; + 224; + 198; + 208; + 170; + 104; + 15; + 59; + 126; + 151; + 222; + 233; + 195; + 203; + 195; + 167; + 129; + 89; + 121; + 240; + 142; + 51; + 166; + 64; + 250; + 184; + 202; + 154; + 177; + ]; + [ + 197; + 41; + 93; + 209; + 203; + 55; + 164; + 174; + 88; + 0; + 90; + 199; + 1; + 156; + 149; + 141; + 240; + 29; + 14; + 82; + 86; + 225; + 126; + 129; + 186; + 157; + 148; + 162; + 219; + 51; + 156; + 199; + ]; + [ + 182; + 117; + 250; + 241; + 81; + 196; + 199; + 227; + 151; + 74; + 243; + 17; + 221; + 97; + 200; + 139; + 192; + 83; + 231; + 35; + 214; + 14; + 95; + 69; + 130; + 201; + 4; + 116; + 177; + 19; + 179; + 0; + ]; + [ + 118; + 41; + 29; + 200; + 60; + 189; + 119; + 252; + 78; + 40; + 230; + 18; + 208; + 221; + 38; + 214; + 176; + 250; + 4; + 10; + 77; + 101; + 26; + 216; + 193; + 198; + 226; + 84; + 25; + 177; + 230; + 185; + ]; + [ + 226; + 189; + 227; + 208; + 112; + 117; + 136; + 98; + 72; + 38; + 211; + 167; + 254; + 82; + 174; + 113; + 112; + 166; + 138; + 171; + 166; + 113; + 52; + 251; + 129; + 197; + 138; + 45; + 195; + 7; + 61; + 140; + ]; + [ + 38; + 198; + 156; + 196; + 146; + 225; + 55; + 163; + 138; + 178; + 157; + 128; + 115; + 135; + 204; + 215; + 0; + 33; + 171; + 20; + 60; + 32; + 142; + 209; + 33; + 233; + 125; + 146; + 207; + 12; + 16; + 24; + ]; + [ + 17; + 187; + 231; + 83; + 165; + 36; + 232; + 184; + 140; + 205; + 195; + 252; + 166; + 85; + 59; + 86; + 3; + 226; + 211; + 67; + 179; + 29; + 238; + 181; + 102; + 142; + 58; + 63; + 57; + 89; + 174; + 138; + ]; + [ + 210; + 159; + 80; + 16; + 181; + 39; + 221; + 204; + 224; + 144; + 145; + 79; + 54; + 231; + 8; + 140; + 142; + 216; + 93; + 190; + 183; + 116; + 174; + 63; + 33; + 242; + 177; + 118; + 148; + 40; + 241; + 203; + ]; + [ + 0; + 143; + 107; + 102; + 149; + 187; + 27; + 124; + 18; + 10; + 98; + 28; + 113; + 123; + 121; + 185; + 29; + 152; + 14; + 130; + 149; + 28; + 87; + 35; + 135; + 135; + 153; + 54; + 112; + 53; + 54; + 68; + ]; + [ + 178; + 131; + 85; + 160; + 214; + 51; + 208; + 157; + 196; + 152; + 247; + 93; + 202; + 56; + 81; + 239; + 155; + 122; + 59; + 188; + 237; + 253; + 11; + 169; + 208; + 236; + 12; + 4; + 163; + 211; + 88; + 97; + ]; + [ + 246; + 194; + 231; + 195; + 159; + 101; + 180; + 133; + 80; + 21; + 185; + 220; + 195; + 115; + 144; + 12; + 90; + 150; + 44; + 117; + 8; + 156; + 168; + 248; + 206; + 41; + 60; + 82; + 67; + 75; + 57; + 67; + ]; + [ + 212; + 205; + 171; + 153; + 113; + 16; + 194; + 241; + 224; + 43; + 177; + 110; + 190; + 248; + 22; + 201; + 208; + 166; + 2; + 83; + 134; + 130; + 85; + 129; + 166; + 136; + 185; + 191; + 163; + 38; + 54; + 10; + ]; + [ + 8; + 60; + 190; + 39; + 153; + 222; + 119; + 23; + 142; + 237; + 12; + 110; + 146; + 9; + 19; + 219; + 143; + 64; + 161; + 99; + 199; + 77; + 39; + 148; + 70; + 213; + 246; + 227; + 150; + 178; + 237; + 178; + ]; + [ + 11; + 114; + 217; + 160; + 101; + 37; + 100; + 220; + 56; + 114; + 42; + 31; + 138; + 33; + 84; + 157; + 214; + 167; + 73; + 233; + 115; + 81; + 124; + 134; + 15; + 31; + 181; + 60; + 184; + 130; + 175; + 159; + ]; + [ + 141; + 238; + 235; + 202; + 241; + 32; + 210; + 10; + 127; + 230; + 54; + 31; + 146; + 80; + 247; + 9; + 107; + 124; + 0; + 26; + 203; + 16; + 237; + 34; + 214; + 147; + 133; + 15; + 29; + 236; + 37; + 88; + ]; + ] + in + let serialised_vectors = + List.map (fun int_list -> List.map char_of_int int_list) vectors_as_int + in + let serialised_vectors = + List.map + (fun int_list -> Bytes.init 32 (List.nth int_list)) + serialised_vectors + in + ignore + @@ List.fold_left + (fun p expected_bytes -> + (* Test of_compressed *) + let expected_p = + Mec.Curve.Jubjub.AffineEdwards.of_compressed_exn expected_bytes + in + assert (Mec.Curve.Jubjub.AffineEdwards.eq p expected_p) ; + (* Test to_compressed *) + let serialised_p = Mec.Curve.Jubjub.AffineEdwards.to_compressed p in + assert (Bytes.equal serialised_p expected_bytes) ; + Mec.Curve.Jubjub.AffineEdwards.add p gen) + gen + serialised_vectors + +let () = + let open Alcotest in + run + ~verbose:true + "Jubjub" + [ + ( "Vectors", + [Alcotest.test_case "test vectors elements" `Quick test_vectors] ); + ( "Compressed/Uncompressed", + [ + Alcotest.test_case + "Correct point; uncompressed_exn" + `Quick + test_compressed_and_uncompressed_exn; + Alcotest.test_case + "Random values must not be accepted" + `Quick + test_uncompressed_fail_on_random_values; + Alcotest.test_case + "Compressed gives 32 bytes" + `Quick + test_compressed_gives_32_bytes; + Alcotest.test_case + "Correct point; uncompressed_opt" + `Quick + test_compressed_and_uncompressed_opt; + Alcotest.test_case + "Test vectors" + `Quick + test_vector_compressed_and_uncompressed; + Alcotest.test_case + "Encoding of zero" + `Quick + test_compressed_uncompressed_zero; + ] ); + ( "Tests random", + [ + Alcotest.test_case + "test random coordinates do not give a point on the curve" + `Quick + (Mec.Curve.Utils.PBT.repeat 100 test_random_points_not_on_curve); + ] ); + ValueGeneration.get_tests (); + EdwardsCurveProperties.get_tests (); + Properties.get_tests (); + Equality.get_tests (); + ] diff --git a/src/lib_mec/test/test_jubjub_conversions_between_forms.ml b/src/lib_mec/test/test_jubjub_conversions_between_forms.ml new file mode 100644 index 000000000000..c3cc7d1cea13 --- /dev/null +++ b/src/lib_mec/test/test_jubjub_conversions_between_forms.ml @@ -0,0 +1,116 @@ +open Mec.Curve.Jubjub + +let rec repeat n f = + if n <= 0 then + let f () = () in + f + else ( + f () ; + repeat (n - 1) f) + +let test_generation () = + let pt_ed1 = AffineEdwards.random () in + let pt_mt1 = from_affine_edwards_to_affine_montgomery pt_ed1 in + assert (Option.(is_some pt_mt1)) ; + let pt_wt1 = from_affine_edwards_to_affine_weierstrass pt_ed1 in + assert (Option.(is_some pt_wt1)) ; + let pt_mt2 = AffineMontgomery.random () in + let pt_wt2 = from_affine_montgomery_to_affine_weierstrass pt_mt2 in + assert (Option.(is_some pt_wt2)) ; + let pt_ed2 = from_affine_montgomery_to_affine_edwards pt_mt2 in + assert (Option.(is_some pt_ed2)) + +let test_addition () = + let pt_ed1 = AffineEdwards.random () in + let pt_ed2 = AffineEdwards.random () in + let pt_ed1_add = AffineEdwards.add pt_ed1 pt_ed2 in + (* Twisted -> Montgomery *) + let pt_mt1 = from_affine_edwards_to_affine_montgomery pt_ed1 |> Option.get in + let pt_mt2 = from_affine_edwards_to_affine_montgomery pt_ed2 |> Option.get in + let pt_mt1_add = AffineMontgomery.add pt_mt1 pt_mt2 in + let pt_ed2_add = + from_affine_montgomery_to_affine_edwards pt_mt1_add |> Option.get + in + let pt_mt2_add = + from_affine_edwards_to_affine_montgomery pt_ed1_add |> Option.get + in + assert (AffineMontgomery.eq pt_mt1_add pt_mt2_add) ; + assert (AffineEdwards.eq pt_ed1_add pt_ed2_add) ; + (* Twisted -> Weierstrass *) + let pt_wt1 = from_affine_edwards_to_affine_weierstrass pt_ed1 |> Option.get in + let pt_wt2 = from_affine_edwards_to_affine_weierstrass pt_ed2 |> Option.get in + let pt_wt1_add = AffineWeierstrass.add pt_wt1 pt_wt2 in + let pt_wt2_add = + from_affine_edwards_to_affine_weierstrass pt_ed1_add |> Option.get + in + assert (AffineWeierstrass.eq pt_wt1_add pt_wt2_add) ; + (* Montgomery -> Twisted *) + let pt_mta = AffineMontgomery.random () in + let pt_mtb = AffineMontgomery.random () in + let pt_mta_add = AffineMontgomery.add pt_mta pt_mtb in + let pt_eda = from_affine_montgomery_to_affine_edwards pt_mta |> Option.get in + let pt_edb = from_affine_montgomery_to_affine_edwards pt_mtb |> Option.get in + let pt_eda_add = AffineEdwards.add pt_eda pt_edb in + let pt_mtb_add = + from_affine_edwards_to_affine_montgomery pt_eda_add |> Option.get + in + let pt_edb_add = + from_affine_montgomery_to_affine_edwards pt_mta_add |> Option.get + in + assert (AffineEdwards.eq pt_eda_add pt_edb_add) ; + assert (AffineMontgomery.eq pt_mta_add pt_mtb_add) + +let test_multiplication () = + let pt_ed1 = AffineEdwards.random () in + let alpha = AffineEdwards.Scalar.random () in + let pt_ed1_mul = AffineEdwards.mul pt_ed1 alpha in + (* Twisted -> Montgomery *) + let pt_mt1 = from_affine_edwards_to_affine_montgomery pt_ed1 |> Option.get in + let alpha = AffineMontgomery.Scalar.of_z (AffineEdwards.Scalar.to_z alpha) in + let pt_mt1_mul = AffineMontgomery.mul pt_mt1 alpha in + let pt_ed2_mul = + from_affine_montgomery_to_affine_edwards pt_mt1_mul |> Option.get + in + let pt_mt2_mul = + from_affine_edwards_to_affine_montgomery pt_ed1_mul |> Option.get + in + assert (AffineMontgomery.eq pt_mt1_mul pt_mt2_mul) ; + assert (AffineEdwards.eq pt_ed1_mul pt_ed2_mul) ; + (* Twisted -> Weierstrass *) + let pt_wt1 = from_affine_edwards_to_affine_weierstrass pt_ed1 |> Option.get in + let alpha = + AffineWeierstrass.Scalar.of_z (AffineMontgomery.Scalar.to_z alpha) + in + let pt_wt1_mul = AffineWeierstrass.mul pt_wt1 alpha in + let pt_wt2_mul = + from_affine_edwards_to_affine_weierstrass pt_ed1_mul |> Option.get + in + assert (AffineWeierstrass.eq pt_wt1_mul pt_wt2_mul) ; + (* Montgomery -> Twisted *) + let pt_mta = AffineMontgomery.random () in + let beta = AffineMontgomery.Scalar.random () in + let pt_mta_mul = AffineMontgomery.mul pt_mta beta in + let pt_eda = from_affine_montgomery_to_affine_edwards pt_mta |> Option.get in + let beta = AffineEdwards.Scalar.of_z (AffineMontgomery.Scalar.to_z beta) in + let pt_eda_mul = AffineEdwards.mul pt_eda beta in + let pt_mtb_mul = + from_affine_edwards_to_affine_montgomery pt_eda_mul |> Option.get + in + let pt_edb_mul = + from_affine_montgomery_to_affine_edwards pt_mta_mul |> Option.get + in + assert (AffineEdwards.eq pt_eda_mul pt_edb_mul) ; + assert (AffineMontgomery.eq pt_mta_mul pt_mtb_mul) + +let get_tests () = + let open Alcotest in + ( "Affine Edwards <-> Affine Montgomery ; Affine Edwards -> Affine Weierstrass", + [ + test_case "Points are on both curves" `Quick (repeat 100 test_generation); + test_case "Addition" `Quick (repeat 100 test_addition); + test_case "Scalar multiplication" `Quick (repeat 100 test_multiplication); + ] ) + +let () = + let open Alcotest in + run ~verbose:true "JubJub" [get_tests ()] diff --git a/src/lib_mec/test/test_jubjub_weierstrass.ml b/src/lib_mec/test/test_jubjub_weierstrass.ml new file mode 100644 index 000000000000..82e0209d26bd --- /dev/null +++ b/src/lib_mec/test/test_jubjub_weierstrass.ml @@ -0,0 +1,21 @@ +module JubjubAffineValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Jubjub.AffineWeierstrass) +module JubjubAffineEquality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Jubjub.AffineWeierstrass) +module JubjubAffineECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Jubjub.AffineWeierstrass) +module JubjubAffineRepresentation = + Mec.Curve.Utils.PBT.MakeCompressedSerialisationAffine + (Mec.Curve.Jubjub.AffineWeierstrass) + +let () = + let open Alcotest in + run + ~verbose:true + "Jubjub - Weierstrass - Affine coordinates" + [ + JubjubAffineValueGeneration.get_tests (); + JubjubAffineEquality.get_tests (); + JubjubAffineECProperties.get_tests (); + JubjubAffineRepresentation.get_tests (); + ] diff --git a/src/lib_mec/test/test_linear_trick.ml b/src/lib_mec/test/test_linear_trick.ml new file mode 100644 index 000000000000..e6d216983d0c --- /dev/null +++ b/src/lib_mec/test/test_linear_trick.ml @@ -0,0 +1,45 @@ +module Fp = Ff.MakeFp (struct + let prime_order = + Z.of_string + "52435875175126190479447740508185965837690552500527637822603658699938581184513" +end) + +let test_poseidon128_batch4_optim () = + let width = 3 in + let batch_size = 4 in + let r_f = 8 in + let r_p = 56 in + let arc = Array.map Fp.of_string Ark_poseidon128.v in + (* We format the MDS in a matrix. *) + let mds = Array.map (fun a -> Array.map Fp.of_string a) Mds_poseidon128.v in + let _, constants, _, _unbatched_arc = + Mec.Permutation.HadesLinearOptimisation.compute_updated_constants + (module Fp) + r_p + r_f + width + batch_size + arc + mds + in + (* 30 comes from the fact that we create 3 tmp variables, needing 3, 4 and 5 + vars (as they are recursively computed) and a state of 3 vars needing the 3 + inputs and 3 tmp vars: 3 + 4 + 5 + 3*6 = 30. + 6 comes from the round constants needed to compute the former 6 tmp and output vars. + *) + let nb_constants_expected = (6 + 30) * r_p / batch_size in + let constants_expected = + Array.map Fp.of_string Poseidon128_linear_trick_expected_output.v + in + assert (Array.length constants = nb_constants_expected) ; + assert (Array.for_all2 Fp.eq constants constants_expected) + +let () = + Alcotest.run + ~verbose:true + "Linear trick" + [ + ( "Regression test", + [Alcotest.test_case "Poseidon128" `Quick test_poseidon128_batch4_optim] + ); + ] diff --git a/src/lib_mec/test/test_marvellous.ml b/src/lib_mec/test/test_marvellous.ml new file mode 100644 index 000000000000..b74bc0c443ee --- /dev/null +++ b/src/lib_mec/test/test_marvellous.ml @@ -0,0 +1,141 @@ +module Parameters : Mec.Permutation.Marvellous.PARAMETERS = struct + let width = 3 + + let rounds = 14 + + let round_constants = Ark_pobls.v + + let mds_matrix = Mds_pobls.v + + (* This is the first alpha such that pgc(alpha, p - 1) = 1 *) + let alpha = Z.of_string "5" + + let alphainv = + Z.of_string + "20974350070050476191779096203274386335076221000211055129041463479975432473805" +end + +module Scalar = Ff.MakeFp (struct + let prime_order = + Z.of_string + "52435875175126190479447740508185965837690552500527637822603658699938581184513" +end) + +module Permutation = Mec.Permutation.Marvellous.Make (Parameters) (Scalar) + +let test_vectors_from_reference_implementation () = + let values = + [ + ( [|"42"; "42"; "42"|], + [| + "1700964629023230081688449128938267741281135202287971876415319604264351638730"; + "30351877146302309485006750598668855676603663881859469782701435098299236408108"; + "1266974358383892903376729581212148792188884064230596723344843464220594616291"; + |] ); + ] + in + List.iter + (fun (input, exp_output) -> + let input = Array.map Scalar.of_string input in + let exp_output = Array.map Scalar.of_string exp_output in + let ctxt = Permutation.init input in + Permutation.apply ctxt ; + let res = Permutation.get ctxt in + Array.iter2 + (fun a b -> + if not (Scalar.eq a b) then + Alcotest.failf + "Expected output is %s but computed %s" + (Scalar.to_string a) + (Scalar.to_string b)) + exp_output + res) + values + +let test_regression () = + let test_vectors = + [ + ( [| + "0"; + "19540886853600136773806888540031779652697522926951761090609474934921975120659"; + "27368034540955591518185075247638312229509481411752400387472688330662143761856"; + |], + [| + "44673107086290821414141179286216522882469521449559636868455247005114020114445"; + "36631684854749147804429266824538272650916679166988362643455728142484809981118"; + "6299192490564547343493433393738313689693119470079691921424273466838440224855"; + |] ); + ( [| + "0"; + "27079498335589470388559429012071885383086029562052523482197446658383111072774"; + "42808036164195249275280963312025828986508786508614910971333518929197538998773"; + |], + [| + "33984868849407543137734814872861866351541889998060667955612713996984910605397"; + "4641627185242898456867942643033909448689919023961721348259024082238188176596"; + "713519522119335567984877165818659706904142877478060072511766145209379073275"; + |] ); + ( [| + "0"; + "2280773603130921897588628948561054337050485605305725986334019017364524534576"; + "49742584797721038216392695876666332237687899609664289853866233942594829409245"; + |], + [| + "20077542126429611153881019033799341995311428088869746915924850362129927371289"; + "38547305939988350836972846971113863192807010866171540518921476662284151835220"; + "8478277515116959072250029506006378039116363843044265570742187828912632979438"; + |] ); + ( [| + "0"; + "47345255170739768354940339244069904962490289137071838723660628082786560244227"; + "12508134994244913485311518548620293355291296251148491744230743543606532994206"; + |], + [| + "50927739926931280620422144191479516292814380533564245832950972175783227490582"; + "47903072246991027484665412890156631636069614146568039741296638969334550407630"; + "47491331892735386854365197646017331478438648030708643559209673528669254013444"; + |] ); + ( [| + "0"; + "22266149478348354835731057366322705807112053199389518651299197937563769914341"; + "46391019025260596444368872653036215340017923491388854958773789052412558961328"; + |], + [| + "37498820915193954318343590451968185938009803654297685764064124822117204060828"; + "16239130390180195445652573959561373168694718306164480810197800625237334891866"; + "21507804981211574030250333588537037287147041282903807447161895309722506987102"; + |] ); + ] + in + List.iter + (fun (inputs, expected_output) -> + let inputs = Array.map Scalar.of_string inputs in + let expected_output = Array.map Scalar.of_string expected_output in + let ctxt = Permutation.init inputs in + let () = Permutation.apply ctxt in + let output = Permutation.get ctxt in + Array.iter2 + (fun a b -> + if not (Scalar.eq a b) then + Alcotest.failf + "Expected output is %s, computed %s\n" + (Scalar.to_string a) + (Scalar.to_string b)) + expected_output + output) + test_vectors + +let () = + Alcotest.run + ~verbose:true + "Marvellous permutation" + [ + ( "Built on scalar field of BLS12-381", + [ + Alcotest.test_case + "Test vectors from reference implementation from KUL" + `Quick + test_vectors_from_reference_implementation; + Alcotest.test_case "Regression tests" `Quick test_regression; + ] ); + ] diff --git a/src/lib_mec/test/test_neptunus.ml b/src/lib_mec/test/test_neptunus.ml new file mode 100644 index 000000000000..1e281e010537 --- /dev/null +++ b/src/lib_mec/test/test_neptunus.ml @@ -0,0 +1,38 @@ +open Mec.Hash + +module Scalar = Ff.MakeFp (struct + let prime_order = + Z.of_string + "52435875175126190479447740508185965837690552500527637822603658699938581184513" +end) + +module Poseidon = Neptunus.Make (Scalar) + +let test_perm_is_consistent () = + let x = Array.make Neptunus.Constant.width (Scalar.of_string "17") in + let y = Array.make Neptunus.Constant.width (Scalar.of_string "17") in + let z = Array.make Neptunus.Constant.width (Scalar.of_string "19") in + + let state_x = Poseidon.Strategy.init x in + let state_y = Poseidon.Strategy.init y in + let state_z = Poseidon.Strategy.init z in + + Poseidon.Strategy.apply_perm state_x ; + Poseidon.Strategy.apply_perm state_y ; + Poseidon.Strategy.apply_perm state_z ; + + let res_x = Poseidon.Strategy.get state_x in + let res_y = Poseidon.Strategy.get state_y in + let res_z = Poseidon.Strategy.get state_z in + assert (Array.for_all2 Scalar.eq res_x res_y) ; + assert (not @@ Array.for_all2 Scalar.eq res_x res_z) + +let () = + Alcotest.run + ~verbose:true + "Neptunus" + [ + ( "Properties", + [Alcotest.test_case "Perm is consistent" `Quick test_perm_is_consistent] + ); + ] diff --git a/src/lib_mec/test/test_orchard.ml b/src/lib_mec/test/test_orchard.ml new file mode 100644 index 000000000000..189ad7ea1a71 --- /dev/null +++ b/src/lib_mec/test/test_orchard.ml @@ -0,0 +1,129 @@ +open Mec.Hash + +module Scalar = Ff.MakeFp (struct + let prime_order = + Z.( + ((one + one) ** 254) + + Z.of_string "45560315531419706090280762371685220353") +end) + +module Poseidon = Orchard.Make (Scalar) + +let test_perm_is_consistent () = + let x = Array.make Orchard.Constant.width (Scalar.of_string "17") in + let y = Array.make Orchard.Constant.width (Scalar.of_string "17") in + let z = Array.make Orchard.Constant.width (Scalar.of_string "19") in + + let state_x = Poseidon.Strategy.init x in + let state_y = Poseidon.Strategy.init y in + let state_z = Poseidon.Strategy.init z in + + Poseidon.Strategy.apply_perm state_x ; + Poseidon.Strategy.apply_perm state_y ; + Poseidon.Strategy.apply_perm state_z ; + + let res_x = Poseidon.Strategy.get state_x in + let res_y = Poseidon.Strategy.get state_y in + let res_z = Poseidon.Strategy.get state_z in + assert (Array.for_all2 Scalar.eq res_x res_y) ; + assert (not @@ Array.for_all2 Scalar.eq res_x res_z) + +let test_vectors_hades_orchard () = + let vectors = + [ + ( [|Scalar.zero; Scalar.one; Scalar.(one + one)|], + [| + "11594746544082808193684844477463633150342086886343960773487848974120850181264"; + "8014665628031024095124899320855562151905643011245776438370704956349329180958"; + "7719389013904241493524551054574463394884187129046035658329571349046169099816"; + |] ); + ] + in + List.iter + (fun (input, expected_output) -> + let s = Poseidon.Strategy.init input in + Poseidon.Strategy.apply_perm s ; + let res = Poseidon.Strategy.get s in + let expected_output = + Array.map (fun s -> Scalar.of_string s) expected_output + in + if + not + (List.for_all2 + Scalar.eq + (Array.to_list expected_output) + (Array.to_list res)) + then + let res = + String.concat + "; " + (Array.to_list @@ Array.map (fun s -> Scalar.to_string s) res) + in + let expected_output = + String.concat + "; " + (Array.to_list + @@ Array.map (fun s -> Scalar.to_string s) expected_output) + in + Alcotest.failf + "Computed result: [%s]. Expected result: [%s]\n" + res + expected_output) + vectors + +let _test_vectors_poseidon_orchard () = + let open Poseidon in + let test_inputs = + [ + ( [|"0"; "1"; "36893488147419103232"|], + "9294224303572826231334390170707418973776412638020053350998514035066722916288" + ); + ] + in + List.iter + (fun (inputs, expected_output) -> + let inputs = Array.map (fun x -> Scalar.of_string x) inputs in + let ctxt = Hash.init () in + let ctxt = Hash.digest ctxt inputs in + let v = Hash.get ctxt in + let exp_res = Scalar.of_string expected_output in + assert (Scalar.eq v exp_res)) + test_inputs + +let test_no_padding () = + List.iter + (fun _ -> + let x = Scalar.random () in + let ctxt = Poseidon.Hash.init () in + let ctxt = Poseidon.Hash.digest ctxt [|x|] in + let v = Poseidon.Hash.get ctxt in + + let ctxt = Poseidon.Hash.init ~input_length:2 () in + let ctxt = Poseidon.Hash.digest ctxt [|x; Scalar.one|] in + let v' = Poseidon.Hash.get ctxt in + assert (Scalar.eq v v')) + (List.init 10 (fun _i -> _i)) + +let () = + Alcotest.run + ~verbose:true + "Orchard" + [ + ( "Properties", + [Alcotest.test_case "Perm is consistent" `Quick test_perm_is_consistent] + ); + ( "Test vectors for Hades Orchard", + [ + Alcotest.test_case + "Test vectors from zcash-hackworks/zcash-test-vectors" + `Quick + test_vectors_hades_orchard; + ] ); + ( "No padding", + [Alcotest.test_case "Inputs of length 2" `Quick test_no_padding] ) + (* ( "Test vectors for Poseidon Orchard", + * [ Alcotest.test_case + * "Test vectors from zcash-hackworks/zcash-test-vectors" + * `Quick + * test_vectors_poseidon_orchard ] ) *); + ] diff --git a/src/lib_mec/test/test_pallas_affine.ml b/src/lib_mec/test/test_pallas_affine.ml new file mode 100644 index 000000000000..80cfb55f6f5a --- /dev/null +++ b/src/lib_mec/test/test_pallas_affine.ml @@ -0,0 +1,20 @@ +module PallasValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Pallas.Affine) +module PallasEquality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Pallas.Affine) +module PallasECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Pallas.Affine) +module PallasRepresentation = + Mec.Curve.Utils.PBT.MakeCompressedSerialisationAffine (Mec.Curve.Pallas.Affine) + +let () = + let open Alcotest in + run + ~verbose:true + "Pallas affine coordinates" + [ + PallasValueGeneration.get_tests (); + PallasEquality.get_tests (); + PallasECProperties.get_tests (); + PallasRepresentation.get_tests (); + ] diff --git a/src/lib_mec/test/test_pallas_jacobian.ml b/src/lib_mec/test/test_pallas_jacobian.ml new file mode 100644 index 000000000000..bac249dab570 --- /dev/null +++ b/src/lib_mec/test/test_pallas_jacobian.ml @@ -0,0 +1,17 @@ +module PallasValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Pallas.Jacobian) +module PallasEquality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Pallas.Jacobian) +module PallasECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Pallas.Jacobian) + +let () = + let open Alcotest in + run + ~verbose:true + "Pallas jacobian coordinates" + [ + PallasValueGeneration.get_tests (); + PallasEquality.get_tests (); + PallasECProperties.get_tests (); + ] diff --git a/src/lib_mec/test/test_pallas_projective.ml b/src/lib_mec/test/test_pallas_projective.ml new file mode 100644 index 000000000000..8719cbdeb7e2 --- /dev/null +++ b/src/lib_mec/test/test_pallas_projective.ml @@ -0,0 +1,17 @@ +module PallasValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Pallas.Projective) +module PallasEquality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Pallas.Projective) +module PallasECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Pallas.Projective) + +let () = + let open Alcotest in + run + ~verbose:true + "Pallas projective coordinates" + [ + PallasValueGeneration.get_tests (); + PallasEquality.get_tests (); + PallasECProperties.get_tests (); + ] diff --git a/src/lib_mec/test/test_pedersen_hash.ml b/src/lib_mec/test/test_pedersen_hash.ml new file mode 100644 index 000000000000..2ee3a013af47 --- /dev/null +++ b/src/lib_mec/test/test_pedersen_hash.ml @@ -0,0 +1,69 @@ +open Mec.Curve +open Mec.Hash +open Mec.Utils + +let test_vector_from_zcash_primitives () = + let open Test_vector_pedersen_hash in + let vectors = + List.map + (fun (b, (u, v)) -> + ( b, + Jubjub.AffineEdwards.from_coordinates_exn + ~u:(Jubjub.AffineEdwards.Base.of_string u) + ~v:(Jubjub.AffineEdwards.Base.of_string v) )) + vectors + in + List.iter + (fun (input, expected_output) -> + let iterator = Iterator.Bit.of_bool_list input in + let output = PedersenHash.Zcash.hash iterator in + if not (Jubjub.AffineEdwards.eq output expected_output) then + Alcotest.failf + "On input [%s] (length = %d), expected output (u=%s, v=%s), computed \ + output (u=%s, v=%s)" + (String.concat + ", " + (List.map (fun b -> if b then "1" else "0") input)) + (List.length input) + (Jubjub.AffineEdwards.Base.to_string + @@ Jubjub.AffineEdwards.get_u_coordinate expected_output) + (Jubjub.AffineEdwards.Base.to_string + @@ Jubjub.AffineEdwards.get_v_coordinate expected_output) + (Jubjub.AffineEdwards.Base.to_string + @@ Jubjub.AffineEdwards.get_u_coordinate output) + (Jubjub.AffineEdwards.Base.to_string + @@ Jubjub.AffineEdwards.get_v_coordinate output)) + vectors + +let test_zcash_bitstring_too_long () = + let n = Random.int 1_000_000 in + let max_bitstring_zcash = 6 * 3 * 63 in + let bitstring = List.init (n + max_bitstring_zcash + 1) (fun _ -> false) in + let iterator = Iterator.Bit.of_bool_list bitstring in + try + ignore @@ PedersenHash.Zcash.hash iterator ; + assert false + with + | Invalid_argument _ -> () + | _ -> assert false + +let () = + Alcotest.run + ~verbose:true + "Pedersen Hash Zcash" + [ + ( "Vectors", + [ + Alcotest.test_case + "Test vector from zcash primitives" + `Quick + test_vector_from_zcash_primitives; + ] ); + ( "Too long bitstrings", + [ + Alcotest.test_case + "Too long bitstrings, not enough generators" + `Quick + test_zcash_bitstring_too_long; + ] ); + ] diff --git a/src/lib_mec/test/test_poseidon128.ml b/src/lib_mec/test/test_poseidon128.ml new file mode 100644 index 000000000000..ad9aff1bc480 --- /dev/null +++ b/src/lib_mec/test/test_poseidon128.ml @@ -0,0 +1,99 @@ +open Mec.Hash + +module Scalar = Ff.MakeFp (struct + let prime_order = + Z.of_string + "52435875175126190479447740508185965837690552500527637822603658699938581184513" +end) + +module Poseidon = Poseidon128.Make (Scalar) + +let test_perm_is_consistent () = + let x = Array.make Poseidon128.Constant.width (Scalar.of_string "17") in + let y = Array.make Poseidon128.Constant.width (Scalar.of_string "17") in + let z = Array.make Poseidon128.Constant.width (Scalar.of_string "19") in + + let state_x = Poseidon.Strategy.init x in + let state_y = Poseidon.Strategy.init y in + let state_z = Poseidon.Strategy.init z in + + Poseidon.Strategy.apply_perm state_x ; + Poseidon.Strategy.apply_perm state_y ; + Poseidon.Strategy.apply_perm state_z ; + + let res_x = Poseidon.Strategy.get state_x in + let res_y = Poseidon.Strategy.get state_y in + let res_z = Poseidon.Strategy.get state_z in + assert (Array.for_all2 Scalar.eq res_x res_y) ; + assert (not @@ Array.for_all2 Scalar.eq res_x res_z) + +let test_vectors_poseidon128 () = + let open Poseidon in + let test_inputs = + [| + "bb67ed265bf1db490ded2e1ede55c0d14c55521509dc73f9c354e98ab76c9625"; + "7e74220084d75e10c89e9435d47bb5b8075991b2e29be3b84421dac3b1ee6007"; + "5ce5481a4d78cca03498f72761da1b9f1d2aa8fb300be39f0e4fe2534f9d4308"; + "b1e710e3c4a8c35154b0ce4e4f4af6f498ebd79f8e7cdf3150372c7501be250b"; + "33c9e2025f86b5d82149f1ab8e20a168fc3d99d09b48cbce0286db8752cc3306"; + "e98206bfdce791e4e5144079b997d4fc25006194b35655f0e48490b26e24ea35"; + "86d2a95cc552de8d5bb20bd4a407fee5ffdc314e93dfe6b2dc792bc71fd8cc2d"; + "4edd8307ce28a8c70963d20a7bc28df1e1720bbbc93878a18bd07fad7d51fa15"; + "eabc7a296704a68aa01f95adc85f6dd758b175745336d8fc795a17984024b21e"; + "cfc108673c93df305e31c283b9c767b7097ae4e174a223e0c24b15a67b701a3a"; + |] + in + let test_inputs = + Array.map (fun s -> Scalar.of_bytes_exn (Hex.to_bytes (`Hex s))) test_inputs + in + let inner points expected_res = + let ctxt = Hash.init () in + let ctxt = Hash.digest ctxt points in + let v = Hash.get ctxt in + let exp_res = Scalar.of_bytes_exn (Hex.to_bytes (`Hex expected_res)) in + if not (Scalar.eq v exp_res) then + Alcotest.failf + "Expected result %s, but computed %s" + Hex.(show (of_bytes (Scalar.to_bytes exp_res))) + Hex.(show (of_bytes (Scalar.to_bytes v))) + in + inner [||] "3cad8b2e06121cd27c6577e87d0386be4807f5a9c9515e0dd80cb6961317945a" ; + inner + (Array.sub test_inputs 0 3) + "8ac95ac433d0de78ea7aaf5075091ab4490cc7ac183bf97efc190eec9a015a3f" ; + inner + (Array.sub test_inputs 0 4) + "d59bd4fe7fb7941ffbfe34ef8aaa94f4d90bb2d0c7d1b0aa50674ec8515c7f19" ; + + inner + (Array.sub test_inputs 0 5) + "ac16f0eec1c9ddacdce21241e6fc72d1430b6f47eaf6a5caf7f4052890287155" ; + + inner + (Array.sub test_inputs 0 6) + "5ad4b11f058b622cf4d9bdbb256745a6878e98615b65edc60d3f183df3f00a61" ; + + inner + (Array.sub test_inputs 0 8) + "e633a1d2f4366743e0a641b0a8d84d4d1ac9107bf6849f443d28aa0432da481d" ; + + inner + (Array.sub test_inputs 0 10) + "fc214ce126e686a08a607ee8a755a53a9c2afae186c2d282e488ad77003cac70" + +let () = + Alcotest.run + ~verbose:true + "Poseidon128" + [ + ( "Properties", + [Alcotest.test_case "Perm is consistent" `Quick test_perm_is_consistent] + ); + ( "Test vectors for Poseidon128", + [ + Alcotest.test_case + "Regression test vectors for poseidon128" + `Quick + test_vectors_poseidon128; + ] ); + ] diff --git a/src/lib_mec/test/test_poseidon252.ml b/src/lib_mec/test/test_poseidon252.ml new file mode 100644 index 000000000000..53bcdc2299a6 --- /dev/null +++ b/src/lib_mec/test/test_poseidon252.ml @@ -0,0 +1,156 @@ +open Mec.Hash + +module Scalar = Ff.MakeFp (struct + let prime_order = + Z.of_string + "52435875175126190479447740508185965837690552500527637822603658699938581184513" +end) + +module Poseidon = Poseidon252.Make (Scalar) + +let test_perm_is_consistent () = + let x = Array.make Poseidon252.Constant.width (Scalar.of_string "17") in + let y = Array.make Poseidon252.Constant.width (Scalar.of_string "17") in + let z = Array.make Poseidon252.Constant.width (Scalar.of_string "19") in + + let state_x = Poseidon.Strategy.init x in + let state_y = Poseidon.Strategy.init y in + let state_z = Poseidon.Strategy.init z in + + Poseidon.Strategy.apply_perm state_x ; + Poseidon.Strategy.apply_perm state_y ; + Poseidon.Strategy.apply_perm state_z ; + + let res_x = Poseidon.Strategy.get state_x in + let res_y = Poseidon.Strategy.get state_y in + let res_z = Poseidon.Strategy.get state_z in + assert (Array.for_all2 Scalar.eq res_x res_y) ; + assert (not @@ Array.for_all2 Scalar.eq res_x res_z) + +let test_vectors_hades252 () = + let vectors = + [ + ( Array.make Poseidon252.Constant.width (Scalar.of_string "17"), + [| + "20b31534ae4b071c49f0bfaf757c60eeedbc8afd8de7e778c1b870e45b5a334a"; + "84460293173542e4fa384e65596b8bd34f3394c3a424470c0963c57c1208f104"; + "33106ccdafa51903ae0d6c0c1adcf1aa568dd164cc7490ce1c66b64c58865a4c"; + "4454fbb8dbe02de35e5521a4c5b7f0e6dc7968b0f983040336cc17d3792c2c43"; + "914fb19a465a71043e27b88b75603f75a4e664dd87ce27f74c47faf65b4e0f5e"; + |] ); + ( Array.make Poseidon252.Constant.width (Scalar.of_string "19"), + [| + "2f26f38f20a624eb7ddc58a28f94a868824a320a64a05c7b028be716c3d47938"; + "577a6555ceb8acfcec1024f76a647a63bef97ef490fa875d5d8d640e9c477973"; + "d3c9f03664b22c12a49a428cd13bf60c397105ae18039208598f00270b71472f"; + "968c4eeb53cb2888a565bf27bc7eb23c648c05f595b1a39fbe11a7aaaba57c4a"; + "e6ddc232b1895b132931211f1052df5a9945ef7c62011a45c5509490cf8cb001"; + |] ); + ] + in + List.iter + (fun (input, expected_output) -> + let s = Poseidon.Strategy.init input in + Poseidon.Strategy.apply_perm s ; + let res = Poseidon.Strategy.get s in + let expected_output = + Array.map + (fun s -> Scalar.of_bytes_exn (Hex.to_bytes (`Hex s))) + expected_output + in + if not (Array.for_all2 Scalar.eq res expected_output) then + let res = + String.concat + "; " + (Array.to_list @@ Array.map (fun s -> Scalar.to_string s) res) + in + let expected_output = + String.concat + "; " + (Array.to_list + @@ Array.map (fun s -> Scalar.to_string s) expected_output) + in + Alcotest.failf + "Computed result: [%s]. Expected result: [%s]\n" + res + expected_output) + vectors + +let test_vectors_poseidon252 () = + (* See https://github.com/dusk-network/Poseidon252/blob/91bab8cac8fb50bc6f9dc8b039165380600bb5f2/src/sponge/sponge.rs#L302. Only using the 10 first elements as it is the only ones used *) + let open Poseidon in + let test_inputs = + [| + "bb67ed265bf1db490ded2e1ede55c0d14c55521509dc73f9c354e98ab76c9625"; + "7e74220084d75e10c89e9435d47bb5b8075991b2e29be3b84421dac3b1ee6007"; + "5ce5481a4d78cca03498f72761da1b9f1d2aa8fb300be39f0e4fe2534f9d4308"; + "b1e710e3c4a8c35154b0ce4e4f4af6f498ebd79f8e7cdf3150372c7501be250b"; + "33c9e2025f86b5d82149f1ab8e20a168fc3d99d09b48cbce0286db8752cc3306"; + "e98206bfdce791e4e5144079b997d4fc25006194b35655f0e48490b26e24ea35"; + "86d2a95cc552de8d5bb20bd4a407fee5ffdc314e93dfe6b2dc792bc71fd8cc2d"; + "4edd8307ce28a8c70963d20a7bc28df1e1720bbbc93878a18bd07fad7d51fa15"; + "eabc7a296704a68aa01f95adc85f6dd758b175745336d8fc795a17984024b21e"; + "cfc108673c93df305e31c283b9c767b7097ae4e174a223e0c24b15a67b701a3a"; + |] + in + let test_inputs = + Array.map (fun s -> Scalar.of_bytes_exn (Hex.to_bytes (`Hex s))) test_inputs + in + let inner points expected_res = + let ctxt = Hash.init () in + let ctxt = Hash.digest ctxt points in + let v = Hash.get ctxt in + let exp_res = Scalar.of_bytes_exn (Hex.to_bytes (`Hex expected_res)) in + if not (Scalar.eq v exp_res) then + Alcotest.failf + "Expected result %s, but computed %s" + Hex.(show (of_bytes (Scalar.to_bytes exp_res))) + Hex.(show (of_bytes (Scalar.to_bytes v))) + in + inner [||] "00c78302fb0a2213d756fc08cb382d02adb4fd22d132fa14413f6a60e32d9054" ; + inner + (Array.sub test_inputs 0 3) + "e36f4ea9b858d5c85b02770823c7c5d8253c28787d17f283ca348b906dca8528" ; + inner + (Array.sub test_inputs 0 4) + "75ea3265c80d07e608c1f363ea0b4394ff1fa1cbf50b43b14c880a5755f7f755" ; + + inner + (Array.sub test_inputs 0 5) + "533106a0980eff5b01f5ce63a6b0dd87328b318ac6aa600fc28b9a2ab9f88842" ; + + inner + (Array.sub test_inputs 0 6) + "1a815864684fff47c4d279ee4c31ad964c9dc232734e08188554fa27d33e6731" ; + + inner + (Array.sub test_inputs 0 8) + "a8b936d057df818048e634254719d13970df22926c51e5190c916fcf13dfa25a" ; + + inner + (Array.sub test_inputs 0 10) + "982934231a0410c86f9ed1daa46863a5ddae6d250670d27cb21d10739088e30b" + +let () = + Alcotest.run + ~verbose:true + "Poseidon252" + [ + ( "Properties", + [Alcotest.test_case "Perm is consistent" `Quick test_perm_is_consistent] + ); + ( "Test vectors for Hades252", + [ + Alcotest.test_case + "Test vectors from dusk-network/hades252" + `Quick + test_vectors_hades252; + ] ); + ( "Test vectors for Poseidon252", + [ + Alcotest.test_case + "Test vectors from dusk-network/poseidon252" + `Quick + test_vectors_poseidon252; + ] ); + ] diff --git a/src/lib_mec/test/test_redjubjub.ml b/src/lib_mec/test/test_redjubjub.ml new file mode 100644 index 000000000000..78441a5d9219 --- /dev/null +++ b/src/lib_mec/test/test_redjubjub.ml @@ -0,0 +1,185 @@ +(*****************************************************************************) +(* *) +(* Copyright (c) 2021 Danny Willems *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Mec.Curve +open Mec.Signature + +let rec repeat n f = + if n <= 0 then + let f () = () in + f + else ( + f () ; + repeat (n - 1) f) + +(* + Generated using find_group_hash with the personalisation "Zcash_G_". Used by + Zcash for the nullifiers +*) +let u, v = + ( "0x0926d4f32059c712d418a7ff26753b6ad5b9a7d3ef8e282747bf46920a95a753", + "0x57a1019e6de9b67553bb37d0c21cfd056d65674dcedbddbc305632adaaf2b530" ) + +let generator = + Jubjub.AffineEdwards.from_coordinates_exn + ~u:(Jubjub.AffineEdwards.Base.of_string u) + ~v:(Jubjub.AffineEdwards.Base.of_string v) + +module RedJubjub = RedJubjub.Make (struct + let generator = generator +end) + +let test_sign_and_verify_random_message () = + let sk = Jubjub.AffineEdwards.Scalar.random () in + let vk = Jubjub.AffineEdwards.(mul generator sk) in + let message = + Bytes.init (Random.int 100) (fun _ -> char_of_int (Random.int 256)) + in + let signature = RedJubjub.sign sk message in + assert (RedJubjub.verify vk message signature) + +let test_sign_and_verify_wrong_message () = + (* Sign a message and use the signature with a different message *) + let sk = Jubjub.AffineEdwards.Scalar.random () in + let vk = Jubjub.AffineEdwards.(mul generator sk) in + let correct_message = Bytes.of_string "Correct message" in + let incorrect_message = Bytes.of_string "Incorrect message" in + let signature = RedJubjub.sign sk correct_message in + assert (not (RedJubjub.verify vk incorrect_message signature)) + +let test_sign_and_verify_wrong_vk_because_of_different_sk () = + (* Sign a message with a sk and attempt to verify with an invalid vk. The + verifying key is computed using a different secret key, but the same generator + than the scheme + *) + let sk = Jubjub.AffineEdwards.Scalar.random () in + let vk = + Jubjub.AffineEdwards.(mul generator (Jubjub.AffineEdwards.Scalar.random ())) + in + let message = Bytes.of_string "Message" in + let signature = RedJubjub.sign sk message in + assert (not (RedJubjub.verify vk message signature)) + +let test_sign_and_verify_wrong_vk_because_of_different_generator () = + (* Sign a message with a sk and attempt to verify with an invalid vk. The vk + is generated using the correct secret key but using a different generator than + the one used in the scheme. + *) + let sk = Jubjub.AffineEdwards.Scalar.random () in + let vk = Jubjub.AffineEdwards.(mul one sk) in + let message = Bytes.of_string "Message" in + let signature = RedJubjub.sign sk message in + assert (not (RedJubjub.verify vk message signature)) + +let test_vectors () = + (* + Picked from https://github.com/zcash/librustzcash/blob/da431a0eb207f69c9b0631d7d02136d819e1bfd9/zcash_primitives/src/sapling/redjubjub.rs#L214 + The randomness can be printed using `println!("{:?}", t)` at line https://github.com/zcash/librustzcash/blob/da431a0eb207f69c9b0631d7d02136d819e1bfd9/zcash_primitives/src/sapling/redjubjub.rs#L78. + The expected signature and the secret key can be printed using + ``` + println!("SK: {:?}", sk_bytes); + println!("SIG: {:?}", sig_bytes); + ``` + at line https://github.com/zcash/librustzcash/blob/da431a0eb207f69c9b0631d7d02136d819e1bfd9/zcash_primitives/src/sapling/redjubjub.rs#L308. + The first tuple comes from the 10th iteration (i = 9), and the second tuple comes + from the first iteration (i = 0). Simply add a variable name in the for loop at line 296, and print for i = 0 and i = 9. Ignore the second part with [sk/vk/sig]_2. + *) + let vectors = + [ + ( "Foo bar", + "e705f4fd254312adc9c28d34433f1077111233aa6d6e3554b70135ae1a423403", + "e733065e8fa3f5172cf389ba48990e0ae50af8650e34abdf44ac4e2a9cb4f454c533fef1b062737796cc00285ecda1d9b4adc1d9de324b359d2c011b9ed91dcca4616518b47dd47477d2a36614265044", + ( "1de4252d8a94cd363901802d944a267a27aabd81b5ee9205810a14e9b353c04f", + "689a85c808017250ad3187fe2316917378ae7a171433cb0a21dbf8af18e88d09" ) + ); + ( "Foo bar", + "7a202b25feb063be0410b9df8cc8f9a949f7de6b1cbe08527d4a5f64638afe0a", + "0adf4bd75fac61fd430021e782921106c5ae2b8f2be8d87f8bdc149089c91b1a891194c80021b570195b7346df85e08253d490ea2055f433d46b83ef86c5cb69a0b6950567be5994f3ba70608ea4a057", + ( "18391a03cd8bcb8b9fbc1165cfed61fd3f4d953f9e213380f1ef9c12b1e12834", + "99d380bbbc9d99c8ec109ce5fc12595fedc2a193751d7e69b87974fa661ae108" ) + ); + ] + in + List.iter + (fun (msg, sk, randomness, (rbar, sbar)) -> + let msg = Bytes.of_string msg in + let sk = Hex.to_bytes (`Hex sk) in + let sk = Jubjub.AffineEdwards.Scalar.of_bytes_exn sk in + (* reconstruct expected signature *) + let rbar = Hex.to_bytes (`Hex rbar) in + let sbar = Hex.to_bytes (`Hex sbar) in + let expected_signature = Bytes.concat Bytes.empty [rbar; sbar] in + let randomness = Hex.to_bytes (`Hex randomness) in + (* Compute the signature given by the library *) + let signature = RedJubjub.sign_deterministic randomness sk msg in + let signature_bytes = RedJubjub.signature_to_bytes signature in + (* Verify the computed signature is the same than the Rust reference + implementation + *) + if not (Bytes.equal signature_bytes expected_signature) then + Alcotest.failf + "Expected signature is %s, computed %s" + Hex.(show (of_bytes expected_signature)) + Hex.(show (of_bytes signature_bytes)) ; + (* Let's verify at the same time *) + assert ( + RedJubjub.verify (Jubjub.AffineEdwards.mul generator sk) msg signature)) + vectors + +let () = + let open Alcotest in + run + ~verbose:true + "RedJubjub" + [ + ( "Signature scheme properties", + [ + Alcotest.test_case + "Sign and verify random message" + `Quick + (repeat 100 test_sign_and_verify_random_message); + Alcotest.test_case + "Sign and verify wrong message" + `Quick + (repeat 100 test_sign_and_verify_wrong_message); + Alcotest.test_case + "sign and verify with an invalid verifying key (different sk)" + `Quick + (repeat 100 test_sign_and_verify_wrong_vk_because_of_different_sk); + Alcotest.test_case + "sign and verify with an invalid verifying key (different \ + generator)" + `Quick + (repeat + 100 + test_sign_and_verify_wrong_vk_because_of_different_generator); + ] ); + ( "Sign on test vectors", + [ + Alcotest.test_case + "Sign on test vectors from librustzcash/zcash_primitives" + `Quick + test_vectors; + ] ); + ] diff --git a/src/lib_mec/test/test_secp256k1_affine.ml b/src/lib_mec/test/test_secp256k1_affine.ml new file mode 100644 index 000000000000..6b209ba9e1d0 --- /dev/null +++ b/src/lib_mec/test/test_secp256k1_affine.ml @@ -0,0 +1,70 @@ +module Secp256k1ValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Secp256k1.Affine) +module Secp256k1Equality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Secp256k1.Affine) +module Secp256k1ECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Secp256k1.Affine) +module CompressedRepresentation = + Mec.Curve.Utils.PBT.MakeCompressedSerialisationAffine + (Mec.Curve.Secp256k1.Affine) + +let test_vectors () = + (* http://point-at-infinity.org/ecc/nisttv *) + let vectors = + [ + ( "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8" ); + ( "C6047F9441ED7D6D3045406E95C07CD85C778E4B8CEF3CA7ABAC09B95C709EE5", + "1AE168FEA63DC339A3C58419466CEAEEF7F632653266D0E1236431A950CFE52A" ); + ( "F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", + "388F7B0F632DE8140FE337E62A37F3566500A99934C2231B6CB9FD7584B8E672" ); + ( "E493DBF1C10D80F3581E4904930B1404CC6C13900EE0758474FA94ABE8C4CD13", + "51ED993EA0D455B75642E2098EA51448D967AE33BFBDFE40CFE97BDC47739922" ); + ( "2F8BDE4D1A07209355B4A7250A5C5128E88B84BDDC619AB7CBA8D569B240EFE4", + "D8AC222636E5E3D6D4DBA9DDA6C9C426F788271BAB0D6840DCA87D3AA6AC62D6" ); + ( "FFF97BD5755EEEA420453A14355235D382F6472F8568A18B2F057A1460297556", + "AE12777AACFBB620F3BE96017F45C560DE80F0F6518FE4A03C870C36B075F297" ); + ( "5CBDF0646E5DB4EAA398F365F2EA7A0E3D419B7E0330E39CE92BDDEDCAC4F9BC", + "6AEBCA40BA255960A3178D6D861A54DBA813D0B813FDE7B5A5082628087264DA" ); + ( "2F01E5E15CCA351DAFF3843FB70F3C2F0A1BDD05E5AF888A67784EF3E10A2A01", + "5C4DA8A741539949293D082A132D13B4C2E213D6BA5B7617B5DA2CB76CBDE904" ); + ( "ACD484E2F0C7F65309AD178A9F559ABDE09796974C57E714C35F110DFC27CCBE", + "CC338921B0A7D9FD64380971763B61E9ADD888A4375F8E0F05CC262AC64F9C37" ); + ( "A0434D9E47F3C86235477C7B1AE6AE5D3442D49B1943C2B752A68E2A47E247C7", + "893ABA425419BC27A3B6C7E693A24C696F794C2ED877A1593CBEE53B037368D7" ); + ( "774AE7F858A9411E5EF4246B70C65AAC5649980BE5C17891BBEC17895DA008CB", + "D984A032EB6B5E190243DD56D7B7B365372DB1E2DFF9D6A8301D74C9C953C61B" ); + ( "A6B594B38FB3E77C6EDF78161FADE2041F4E09FD8497DB776E546C41567FEB3C", + "71444009192228730CD8237A490FEBA2AFE3D27D7CC1136BC97E439D13330D55" ); + ( "2B4EA0A797A443D293EF5CFF444F4979F06ACFEBD7E86D277475656138385B6C", + "7A17643FC86BA26C4CBCF7C4A5E379ECE5FE09F3AFD9689C4A8F37AA1A3F60B5" ); + ] + in + let bytes = + List.map + (fun (x, y) -> + Bytes.concat + Bytes.empty + (List.map + (fun x -> + Mec.Curve.Secp256k1.Affine.Base.to_bytes + (Mec.Curve.Secp256k1.Affine.Base.of_z (Z.of_string_base 16 x))) + [x; y])) + vectors + in + List.iter + (fun bytes -> assert (Mec.Curve.Secp256k1.Affine.check_bytes bytes)) + bytes + +let () = + let open Alcotest in + run + ~verbose:true + "secp256k1 affine coordinates" + [ + ("Vectors", [Alcotest.test_case "test vectors" `Quick test_vectors]); + Secp256k1ValueGeneration.get_tests (); + Secp256k1Equality.get_tests (); + Secp256k1ECProperties.get_tests (); + CompressedRepresentation.get_tests (); + ] diff --git a/src/lib_mec/test/test_secp256k1_jacobian.ml b/src/lib_mec/test/test_secp256k1_jacobian.ml new file mode 100644 index 000000000000..c840375014ba --- /dev/null +++ b/src/lib_mec/test/test_secp256k1_jacobian.ml @@ -0,0 +1,17 @@ +module Secp256r1ValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Secp256r1.Jacobian) +module Secp256r1Equality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Secp256r1.Jacobian) +module Secp256r1ECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Secp256r1.Jacobian) + +let () = + let open Alcotest in + run + ~verbose:true + "secp256r1 jacobian coordinates" + [ + Secp256r1ValueGeneration.get_tests (); + Secp256r1Equality.get_tests (); + Secp256r1ECProperties.get_tests (); + ] diff --git a/src/lib_mec/test/test_secp256k1_projective.ml b/src/lib_mec/test/test_secp256k1_projective.ml new file mode 100644 index 000000000000..a81e5ebe6964 --- /dev/null +++ b/src/lib_mec/test/test_secp256k1_projective.ml @@ -0,0 +1,67 @@ +module Secp256k1ValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Secp256k1.Projective) +module Secp256k1Equality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Secp256k1.Projective) +module Secp256k1ECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Secp256k1.Projective) + +let test_vectors () = + (* http://point-at-infinity.org/ecc/nisttv *) + let vectors = + [ + ( "79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", + "483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8" ); + ( "C6047F9441ED7D6D3045406E95C07CD85C778E4B8CEF3CA7ABAC09B95C709EE5", + "1AE168FEA63DC339A3C58419466CEAEEF7F632653266D0E1236431A950CFE52A" ); + ( "F9308A019258C31049344F85F89D5229B531C845836F99B08601F113BCE036F9", + "388F7B0F632DE8140FE337E62A37F3566500A99934C2231B6CB9FD7584B8E672" ); + ( "E493DBF1C10D80F3581E4904930B1404CC6C13900EE0758474FA94ABE8C4CD13", + "51ED993EA0D455B75642E2098EA51448D967AE33BFBDFE40CFE97BDC47739922" ); + ( "2F8BDE4D1A07209355B4A7250A5C5128E88B84BDDC619AB7CBA8D569B240EFE4", + "D8AC222636E5E3D6D4DBA9DDA6C9C426F788271BAB0D6840DCA87D3AA6AC62D6" ); + ( "FFF97BD5755EEEA420453A14355235D382F6472F8568A18B2F057A1460297556", + "AE12777AACFBB620F3BE96017F45C560DE80F0F6518FE4A03C870C36B075F297" ); + ( "5CBDF0646E5DB4EAA398F365F2EA7A0E3D419B7E0330E39CE92BDDEDCAC4F9BC", + "6AEBCA40BA255960A3178D6D861A54DBA813D0B813FDE7B5A5082628087264DA" ); + ( "2F01E5E15CCA351DAFF3843FB70F3C2F0A1BDD05E5AF888A67784EF3E10A2A01", + "5C4DA8A741539949293D082A132D13B4C2E213D6BA5B7617B5DA2CB76CBDE904" ); + ( "ACD484E2F0C7F65309AD178A9F559ABDE09796974C57E714C35F110DFC27CCBE", + "CC338921B0A7D9FD64380971763B61E9ADD888A4375F8E0F05CC262AC64F9C37" ); + ( "A0434D9E47F3C86235477C7B1AE6AE5D3442D49B1943C2B752A68E2A47E247C7", + "893ABA425419BC27A3B6C7E693A24C696F794C2ED877A1593CBEE53B037368D7" ); + ( "774AE7F858A9411E5EF4246B70C65AAC5649980BE5C17891BBEC17895DA008CB", + "D984A032EB6B5E190243DD56D7B7B365372DB1E2DFF9D6A8301D74C9C953C61B" ); + ( "A6B594B38FB3E77C6EDF78161FADE2041F4E09FD8497DB776E546C41567FEB3C", + "71444009192228730CD8237A490FEBA2AFE3D27D7CC1136BC97E439D13330D55" ); + ( "2B4EA0A797A443D293EF5CFF444F4979F06ACFEBD7E86D277475656138385B6C", + "7A17643FC86BA26C4CBCF7C4A5E379ECE5FE09F3AFD9689C4A8F37AA1A3F60B5" ); + ] + in + let bytes = + List.map + (fun (x, y) -> + Bytes.concat + Bytes.empty + (List.map + (fun x -> + Mec.Curve.Secp256k1.Projective.Base.to_bytes + (Mec.Curve.Secp256k1.Projective.Base.of_z + (Z.of_string_base 16 x))) + [x; y; "1"])) + vectors + in + List.iter + (fun bytes -> assert (Mec.Curve.Secp256k1.Projective.check_bytes bytes)) + bytes + +let () = + let open Alcotest in + run + ~verbose:true + "secp256k1 projective coordinates" + [ + ("Vectors", [Alcotest.test_case "test vectors" `Quick test_vectors]); + Secp256k1ValueGeneration.get_tests (); + Secp256k1Equality.get_tests (); + Secp256k1ECProperties.get_tests (); + ] diff --git a/src/lib_mec/test/test_secp256r1_affine.ml b/src/lib_mec/test/test_secp256r1_affine.ml new file mode 100644 index 000000000000..cfebc3cc57ee --- /dev/null +++ b/src/lib_mec/test/test_secp256r1_affine.ml @@ -0,0 +1,23 @@ +module Secp256r1ValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Secp256r1.Affine) +module Secp256r1Equality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Secp256r1.Affine) +module Secp256r1ECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Secp256r1.Affine) + +(* FIXME: Looks like it is failing. I don't have time for the moment to verify *) +(* module CompressedRepresentation = + * Mec.Curve.Utils.PBT.MakeCompressedSerialisationAffine + * (Mec.Curve.Secp256r1.Affine) *) + +let () = + let open Alcotest in + run + ~verbose:true + "secp256r1 affine coordinates" + [ + Secp256r1ValueGeneration.get_tests (); + Secp256r1Equality.get_tests (); + Secp256r1ECProperties.get_tests () + (* CompressedRepresentation.get_tests () *); + ] diff --git a/src/lib_mec/test/test_secp256r1_jacobian.ml b/src/lib_mec/test/test_secp256r1_jacobian.ml new file mode 100644 index 000000000000..c840375014ba --- /dev/null +++ b/src/lib_mec/test/test_secp256r1_jacobian.ml @@ -0,0 +1,17 @@ +module Secp256r1ValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Secp256r1.Jacobian) +module Secp256r1Equality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Secp256r1.Jacobian) +module Secp256r1ECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Secp256r1.Jacobian) + +let () = + let open Alcotest in + run + ~verbose:true + "secp256r1 jacobian coordinates" + [ + Secp256r1ValueGeneration.get_tests (); + Secp256r1Equality.get_tests (); + Secp256r1ECProperties.get_tests (); + ] diff --git a/src/lib_mec/test/test_secp256r1_projective.ml b/src/lib_mec/test/test_secp256r1_projective.ml new file mode 100644 index 000000000000..7faf192f2a09 --- /dev/null +++ b/src/lib_mec/test/test_secp256r1_projective.ml @@ -0,0 +1,17 @@ +module Secp256r1ValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Secp256r1.Projective) +module Secp256r1Equality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Secp256r1.Projective) +module Secp256r1ECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Secp256r1.Projective) + +let () = + let open Alcotest in + run + ~verbose:true + "secp256r1 projective coordinates" + [ + Secp256r1ValueGeneration.get_tests (); + Secp256r1Equality.get_tests (); + Secp256r1ECProperties.get_tests (); + ] diff --git a/src/lib_mec/test/test_sinsemilla.ml b/src/lib_mec/test/test_sinsemilla.ml new file mode 100644 index 000000000000..87580aae6a45 --- /dev/null +++ b/src/lib_mec/test/test_sinsemilla.ml @@ -0,0 +1,238 @@ +open Mec.Curve +open Mec.Utils + +(* let two_z = Z.succ Z.one *) + +(* The test vectors have been generated from https://github.com/zcash/orchard, + b4a82211cee82ceb02d2e0e99b7566a967804a6c + + The following rust code has been added in primitives/sinsemilla.rs: + + ```rust + #[test] + fn test_vectors() { + use crate::primitives::sinsemilla::HashDomain; + use group::GroupEncoding; + + let mut rng = OsRng; + let hasher = HashDomain::new("hasher"); + println!("Initial value: {:?}", hex::encode(hasher.Q.to_bytes())); + // Change the size here + let size = 100; + let bits: Vec = (0..1086).map(|_| rng.gen()).collect(); + println!("Inputs: {:?}", &bits[..size]); + println!( + "Result: {:?}", + hasher.hash(bits[..size].iter().cloned()).unwrap() + ); + } + ``` + + and the result can be printed on stdout using: + ```shell + cargo test "primitives::sinsemilla::tests::test_vectors" -- --nocapture + ``` +*) +let iv = + Pallas.Affine.of_compressed_bytes_exn + (Hex.to_bytes + (`Hex "857d3f841a79306bc85c63b4da7547fb302557d09e39bc9b9856b67d5b618910")) + +let test_inputs = + [ + [true; false; false; false; false; false; false; false; false; true]; + [true]; + [true; false; false; false; false; false; false; false; false]; + [true; false; false; false; false]; + [true; false; false]; + [ + false; + false; + false; + true; + true; + false; + true; + false; + false; + false; + true; + false; + true; + true; + false; + true; + false; + false; + false; + false; + false; + false; + true; + false; + true; + false; + true; + true; + false; + true; + true; + true; + true; + true; + true; + false; + true; + true; + true; + false; + false; + true; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + false; + true; + true; + true; + false; + true; + false; + true; + false; + true; + false; + true; + false; + false; + false; + false; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + true; + true; + false; + false; + false; + true; + false; + false; + true; + true; + false; + false; + false; + false; + false; + false; + true; + false; + false; + ]; + ] + +let test_outputs = + [ + "080056d41fd433913bb29359803e9eab30fc328fd0bccaa6792d4fad68c516cd"; + "31bad63b65ecce065c51860c168b8c09916ab092c9ba3c5467955cd90e20e9c2"; + "31bad63b65ecce065c51860c168b8c09916ab092c9ba3c5467955cd90e20e9c2"; + "31bad63b65ecce065c51860c168b8c09916ab092c9ba3c5467955cd90e20e9c2"; + "31bad63b65ecce065c51860c168b8c09916ab092c9ba3c5467955cd90e20e9c2"; + "34fd57c58f73de765ad9627ced0405fb0868ca6e7e9ced5c311cc120379abc6b"; + ] + +let inverse_endianness bs = + let length = Bytes.length bs in + Bytes.init length (fun i -> Bytes.get bs (length - i - 1)) + +module Sinsemilla = Mec.Hash.Sinsemilla.Zcash + +let test_vectors_sinsemilla_orchard () = + let open Sinsemilla in + List.iter2 + (fun input expected_output -> + let it = Iterator.Bit.of_bool_list input in + let expected_output = Hex.to_bytes (`Hex expected_output) in + let expected_output = inverse_endianness expected_output in + let output = hash_exn iv it in + let output = Pallas.Affine.Base.to_bytes output in + if not (output = expected_output) then + Alcotest.failf + "On input [%s], computed output is %s but expected %s" + (String.concat ", " (List.map string_of_bool input)) + Hex.(show (of_bytes expected_output)) + Hex.(show (of_bytes output))) + test_inputs + test_outputs + +module Properties = struct + let test_collision_when_padding_with_zeroes_last_chunk () = + let chunk_size = 1 + Random.int 10 in + let generators = + Array.init (1 lsl chunk_size) (fun _ -> Pallas.Affine.random ()) + in + let iv = Pallas.Affine.random () in + let module Sinsemilla = Mec.Hash.Sinsemilla.MakeSinsemilla (struct + let chunk_size = chunk_size + + let generators = generators + + let iv = iv + end) in + let nb_chunk_input = 1 + Random.int 10 in + let input = + List.init ((nb_chunk_input * chunk_size) + 1) (fun _ -> Random.bool ()) + in + let exp_output = Sinsemilla.hash_exn (Iterator.Bit.of_bool_list input) in + for i = 0 to chunk_size - 1 do + let input_padded = input @ List.init i (fun _ -> false) in + let output = + Sinsemilla.hash_exn (Iterator.Bit.of_bool_list input_padded) + in + assert (Pallas.Affine.Base.eq output exp_output) + done + + let get_tests () = + ( "Properties", + [ + Alcotest.test_case + "Collision when padding last chunk with zeroes" + `Quick + (Mec.Curve.Utils.PBT.repeat + 100 + test_collision_when_padding_with_zeroes_last_chunk); + ] ) +end + +let () = + Alcotest.run + ~verbose:true + "Sinsemilla" + [ + ( "Test vectors for Sinsemilla", + [ + Alcotest.test_case + "Test vectors from zcash-ochard/zcash-test-vectors" + `Quick + test_vectors_sinsemilla_orchard; + ] ); + Properties.get_tests (); + ] diff --git a/src/lib_mec/test/test_tweedledee_affine.ml b/src/lib_mec/test/test_tweedledee_affine.ml new file mode 100644 index 000000000000..c9e9fa4b8567 --- /dev/null +++ b/src/lib_mec/test/test_tweedledee_affine.ml @@ -0,0 +1,21 @@ +module TweedledeeValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Tweedledee.Affine) +module TweedledeeEquality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Tweedledee.Affine) +module TweedledeeECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Tweedledee.Affine) +module TweedledeeRepresentation = + Mec.Curve.Utils.PBT.MakeCompressedSerialisationAffine + (Mec.Curve.Tweedledee.Affine) + +let () = + let open Alcotest in + run + ~verbose:true + "Tweedledee affine coordinates" + [ + TweedledeeValueGeneration.get_tests (); + TweedledeeEquality.get_tests (); + TweedledeeECProperties.get_tests (); + TweedledeeRepresentation.get_tests (); + ] diff --git a/src/lib_mec/test/test_tweedledee_jacobian.ml b/src/lib_mec/test/test_tweedledee_jacobian.ml new file mode 100644 index 000000000000..23e7701a1fa9 --- /dev/null +++ b/src/lib_mec/test/test_tweedledee_jacobian.ml @@ -0,0 +1,17 @@ +module TweedledeeValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Tweedledee.Jacobian) +module TweedledeeEquality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Tweedledee.Jacobian) +module TweedledeeECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Tweedledee.Jacobian) + +let () = + let open Alcotest in + run + ~verbose:true + "Tweedledee jacobian coordinates" + [ + TweedledeeValueGeneration.get_tests (); + TweedledeeEquality.get_tests (); + TweedledeeECProperties.get_tests (); + ] diff --git a/src/lib_mec/test/test_tweedledee_projective.ml b/src/lib_mec/test/test_tweedledee_projective.ml new file mode 100644 index 000000000000..4f274d401cb2 --- /dev/null +++ b/src/lib_mec/test/test_tweedledee_projective.ml @@ -0,0 +1,17 @@ +module TweedledeeValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Tweedledee.Projective) +module TweedledeeEquality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Tweedledee.Projective) +module TweedledeeECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Tweedledee.Projective) + +let () = + let open Alcotest in + run + ~verbose:true + "Tweedledee projective coordinates" + [ + TweedledeeValueGeneration.get_tests (); + TweedledeeEquality.get_tests (); + TweedledeeECProperties.get_tests (); + ] diff --git a/src/lib_mec/test/test_tweedledum_affine.ml b/src/lib_mec/test/test_tweedledum_affine.ml new file mode 100644 index 000000000000..144dece0e10c --- /dev/null +++ b/src/lib_mec/test/test_tweedledum_affine.ml @@ -0,0 +1,21 @@ +module TweedledumValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Tweedledum.Affine) +module TweedledumEquality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Tweedledum.Affine) +module TweedledumECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Tweedledum.Affine) +module TweedledumRepresentation = + Mec.Curve.Utils.PBT.MakeCompressedSerialisationAffine + (Mec.Curve.Tweedledum.Affine) + +let () = + let open Alcotest in + run + ~verbose:true + "Tweedledum affine coordinates" + [ + TweedledumValueGeneration.get_tests (); + TweedledumEquality.get_tests (); + TweedledumECProperties.get_tests (); + TweedledumRepresentation.get_tests (); + ] diff --git a/src/lib_mec/test/test_tweedledum_jacobian.ml b/src/lib_mec/test/test_tweedledum_jacobian.ml new file mode 100644 index 000000000000..2990aff55252 --- /dev/null +++ b/src/lib_mec/test/test_tweedledum_jacobian.ml @@ -0,0 +1,17 @@ +module TweedledumValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Tweedledum.Jacobian) +module TweedledumEquality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Tweedledum.Jacobian) +module TweedledumECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Tweedledum.Jacobian) + +let () = + let open Alcotest in + run + ~verbose:true + "Tweedledum jacobian coordinates" + [ + TweedledumValueGeneration.get_tests (); + TweedledumEquality.get_tests (); + TweedledumECProperties.get_tests (); + ] diff --git a/src/lib_mec/test/test_tweedledum_projective.ml b/src/lib_mec/test/test_tweedledum_projective.ml new file mode 100644 index 000000000000..f3df4ab135c1 --- /dev/null +++ b/src/lib_mec/test/test_tweedledum_projective.ml @@ -0,0 +1,17 @@ +module TweedledumValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Tweedledum.Projective) +module TweedledumEquality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Tweedledum.Projective) +module TweedledumECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Tweedledum.Projective) + +let () = + let open Alcotest in + run + ~verbose:true + "Tweedledum projective coordinates" + [ + TweedledumValueGeneration.get_tests (); + TweedledumEquality.get_tests (); + TweedledumECProperties.get_tests (); + ] diff --git a/src/lib_mec/test/test_vector_pedersen_hash.ml b/src/lib_mec/test/test_vector_pedersen_hash.ml new file mode 100644 index 000000000000..12885bbd154d --- /dev/null +++ b/src/lib_mec/test/test_vector_pedersen_hash.ml @@ -0,0 +1,8256 @@ +(* Test vectors from + https://github.com/zcash/librustzcash/blob/de1345a1c2f10b0843ab1f1ea6463b2330fdc673/zcash_primitives/src/test_vectors/pedersen_hash_vectors.rs *) + +let vectors = + [ + ( [true; true; true; true; true; true], + ( "0x06b1187c11ca4fb4383b2e0d0dbbde3ad3617338b5029187ec65a5eaed5e4d0b", + "0x3ce70f536652f0dea496393a1e55c4e08b9d55508e16d11e5db40d4810cbc982" ) + ); + ( [true; true; true; true; true; true; false], + ( "0x2fc3bc454c337f71d4f04f86304262fcbfc9ecd808716b92fc42cbe6827f7f1a", + "0x46d0d25bf1a654eedc6a9b1e5af398925113959feac31b7a2c036ff9b9ec0638" ) + ); + ( [true; true; true; true; true; true; true], + ( "0x4f8ce0e0a9e674b3ab9606a7d7aefba386e81583d81918127814cde41d209d97", + "0x312b5ab93b14c9b9af334fe1fe3c50fffb53fbd074fa40ca600febde7c97e346" ) + ); + ( [true; true; true; true; true; true; true; false; false], + ( "0x4f8ce0e0a9e674b3ab9606a7d7aefba386e81583d81918127814cde41d209d97", + "0x312b5ab93b14c9b9af334fe1fe3c50fffb53fbd074fa40ca600febde7c97e346" ) + ); + ( [ + true; + true; + true; + true; + true; + true; + true; + false; + true; + true; + false; + true; + false; + false; + false; + false; + true; + false; + false; + false; + false; + false; + true; + true; + false; + false; + true; + false; + false; + false; + false; + false; + false; + false; + true; + false; + true; + true; + true; + false; + true; + false; + true; + true; + true; + false; + true; + false; + true; + true; + false; + false; + false; + false; + false; + true; + false; + true; + true; + true; + false; + true; + true; + true; + false; + true; + false; + false; + false; + true; + false; + false; + true; + true; + true; + false; + false; + true; + false; + true; + true; + false; + true; + true; + false; + false; + true; + false; + false; + false; + false; + false; + false; + false; + true; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + true; + false; + true; + true; + true; + true; + true; + true; + true; + false; + true; + false; + false; + true; + true; + false; + false; + false; + true; + true; + true; + true; + false; + true; + false; + false; + false; + true; + true; + false; + false; + true; + false; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + true; + true; + true; + false; + true; + false; + false; + false; + false; + false; + true; + false; + true; + true; + true; + false; + true; + false; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + false; + false; + true; + false; + false; + false; + false; + ], + ( "0x599ab788360ae8c6d5bb7618aec37056d6227408d857fdc394078a3d7afdfe0f", + "0x4320c373da670e28d168f4ffd72b43208e8c815f40841682c57a3ee1d005a527" ) + ); + ( [ + true; + true; + true; + true; + true; + true; + true; + false; + false; + false; + false; + false; + true; + true; + true; + true; + false; + true; + true; + true; + false; + false; + false; + true; + true; + true; + false; + false; + false; + false; + true; + false; + false; + false; + false; + true; + false; + false; + true; + true; + true; + false; + true; + false; + true; + true; + false; + true; + false; + false; + false; + true; + true; + false; + true; + false; + false; + false; + false; + true; + false; + false; + false; + false; + false; + false; + true; + false; + true; + false; + false; + false; + true; + false; + true; + true; + true; + true; + true; + false; + true; + true; + true; + false; + true; + false; + true; + true; + true; + false; + false; + true; + false; + false; + true; + true; + false; + true; + false; + false; + true; + true; + false; + true; + true; + true; + false; + false; + false; + false; + true; + true; + true; + false; + true; + true; + false; + false; + true; + true; + false; + false; + true; + false; + true; + false; + false; + true; + false; + true; + true; + true; + true; + true; + true; + true; + true; + true; + false; + false; + false; + false; + true; + false; + true; + true; + true; + false; + true; + false; + false; + true; + true; + true; + true; + true; + false; + false; + true; + false; + true; + false; + true; + false; + false; + true; + true; + false; + true; + false; + false; + false; + true; + false; + true; + false; + false; + true; + false; + true; + false; + true; + false; + true; + false; + true; + false; + false; + false; + ], + ( "0x2da510317620f5dfdce1f31db6019f947eedcf02ff2972cff597a5c3ad21f5dd", + "0x198789969c0c33e6c359b9da4a51771f4d50863f36beef90436944fe568399f2" ) + ); + ( [ + true; + true; + true; + true; + true; + true; + true; + false; + true; + false; + false; + false; + true; + true; + false; + true; + false; + false; + false; + true; + false; + false; + false; + true; + false; + false; + false; + false; + false; + false; + true; + true; + false; + false; + false; + false; + false; + true; + true; + true; + true; + true; + false; + false; + false; + false; + true; + true; + true; + false; + false; + false; + true; + true; + true; + false; + true; + true; + false; + false; + true; + true; + true; + true; + true; + false; + false; + true; + false; + true; + false; + true; + false; + false; + false; + false; + true; + false; + true; + true; + false; + true; + true; + false; + false; + true; + true; + true; + true; + true; + false; + true; + false; + false; + false; + true; + false; + true; + false; + true; + false; + false; + false; + false; + true; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + true; + true; + false; + false; + true; + false; + true; + true; + false; + false; + false; + false; + true; + true; + false; + false; + true; + false; + false; + true; + false; + false; + true; + false; + false; + false; + false; + false; + false; + true; + false; + true; + true; + false; + true; + true; + true; + true; + true; + false; + true; + true; + true; + true; + false; + true; + true; + false; + false; + false; + true; + true; + false; + false; + true; + true; + true; + true; + false; + false; + false; + false; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + false; + true; + true; + ], + ( "0x601247c7e640992d193dfb51df6ed93446687a7f2bcd0e4a598e6feb1ef20c40", + "0x371931733b73e7b95c2cad55a6cebd15c83619f697c64283e54e5ef61442a743" ) + ); + ( [ + true; + true; + true; + true; + true; + true; + true; + true; + false; + false; + true; + false; + false; + true; + false; + false; + true; + false; + true; + false; + false; + false; + false; + false; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + true; + false; + true; + false; + true; + true; + false; + false; + true; + true; + true; + false; + false; + false; + false; + true; + true; + false; + false; + true; + false; + false; + true; + true; + true; + false; + false; + true; + false; + false; + true; + true; + true; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + false; + false; + false; + false; + true; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + true; + true; + true; + true; + true; + true; + false; + false; + false; + true; + true; + false; + true; + true; + false; + false; + true; + false; + true; + false; + true; + true; + true; + false; + true; + false; + false; + false; + false; + false; + true; + false; + false; + true; + true; + true; + false; + false; + false; + true; + false; + true; + true; + true; + false; + false; + false; + true; + true; + false; + true; + true; + true; + false; + false; + false; + false; + false; + true; + true; + false; + true; + false; + false; + false; + false; + false; + true; + true; + true; + true; + false; + true; + false; + true; + true; + false; + false; + false; + true; + false; + false; + false; + false; + true; + true; + false; + true; + false; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + true; + false; + true; + false; + true; + true; + true; + false; + false; + true; + false; + false; + true; + true; + false; + false; + false; + true; + true; + false; + false; + true; + true; + false; + true; + false; + true; + true; + false; + false; + true; + false; + false; + true; + true; + true; + true; + false; + true; + true; + true; + true; + false; + false; + true; + true; + true; + false; + false; + false; + true; + false; + true; + false; + false; + false; + true; + false; + false; + true; + false; + false; + false; + true; + false; + false; + false; + false; + true; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + true; + true; + true; + false; + true; + true; + false; + false; + false; + true; + false; + false; + false; + true; + true; + false; + true; + true; + false; + false; + true; + false; + false; + false; + false; + true; + false; + true; + false; + false; + true; + false; + true; + false; + false; + true; + false; + true; + false; + true; + true; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + false; + true; + false; + false; + false; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + true; + false; + true; + true; + true; + true; + false; + false; + true; + false; + true; + true; + true; + true; + false; + true; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + true; + true; + true; + true; + false; + true; + false; + false; + true; + true; + false; + false; + false; + true; + false; + false; + true; + true; + false; + true; + true; + true; + false; + false; + false; + false; + false; + true; + true; + true; + false; + false; + true; + false; + true; + false; + true; + false; + false; + false; + true; + false; + false; + true; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + true; + false; + false; + false; + false; + false; + true; + false; + false; + false; + false; + true; + false; + true; + true; + false; + true; + false; + true; + false; + true; + false; + true; + true; + false; + false; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + false; + false; + true; + false; + false; + false; + true; + false; + false; + false; + true; + true; + true; + true; + true; + false; + true; + false; + false; + false; + false; + true; + true; + true; + false; + true; + true; + true; + true; + true; + true; + true; + false; + true; + true; + true; + true; + false; + true; + false; + false; + false; + false; + true; + false; + true; + false; + false; + true; + false; + false; + false; + true; + true; + false; + false; + true; + false; + false; + false; + true; + true; + false; + false; + true; + false; + false; + true; + true; + false; + true; + false; + true; + false; + false; + false; + true; + false; + true; + true; + false; + true; + false; + false; + false; + true; + true; + true; + false; + true; + false; + false; + true; + true; + false; + false; + true; + false; + false; + false; + true; + false; + false; + false; + false; + false; + false; + true; + false; + true; + true; + false; + true; + true; + false; + true; + false; + true; + false; + false; + false; + true; + false; + true; + false; + true; + false; + true; + true; + true; + false; + false; + false; + true; + false; + false; + false; + true; + false; + false; + false; + false; + true; + false; + true; + true; + false; + false; + true; + true; + false; + true; + false; + true; + true; + false; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + true; + true; + true; + true; + false; + false; + false; + true; + false; + true; + true; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + true; + true; + true; + true; + true; + true; + false; + true; + false; + true; + true; + true; + true; + false; + true; + true; + false; + true; + false; + true; + false; + true; + false; + false; + true; + false; + false; + false; + true; + false; + true; + false; + true; + true; + false; + false; + false; + true; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + true; + false; + false; + false; + true; + false; + true; + true; + false; + true; + false; + false; + false; + false; + false; + true; + false; + false; + true; + false; + true; + false; + false; + true; + false; + false; + false; + true; + true; + false; + true; + false; + true; + true; + true; + true; + false; + false; + true; + true; + false; + true; + false; + false; + true; + false; + false; + false; + false; + false; + false; + true; + false; + false; + false; + false; + false; + false; + false; + true; + true; + true; + ], + ( "0x314192ecb1f2d8806a8108704c875a25d9fb7e444f9f373919adedebe8f2ae27", + "0x6b12b32f1372ad574799dee9eb591d961b704bf611f55fcc71f7e82cd3330b74" ) + ); + ( [ + true; + true; + true; + true; + true; + true; + true; + true; + false; + false; + true; + true; + false; + true; + false; + true; + true; + true; + false; + true; + false; + true; + true; + true; + false; + false; + true; + false; + false; + true; + true; + true; + false; + true; + false; + false; + false; + false; + false; + false; + false; + true; + false; + true; + false; + true; + false; + true; + true; + false; + false; + false; + false; + true; + true; + false; + true; + true; + true; + true; + false; + false; + true; + true; + true; + false; + false; + false; + false; + true; + true; + false; + true; + true; + false; + false; + true; + false; + true; + false; + true; + true; + false; + true; + true; + false; + false; + true; + false; + false; + true; + false; + false; + false; + true; + false; + false; + false; + true; + true; + true; + false; + true; + false; + true; + true; + false; + false; + true; + false; + true; + true; + false; + false; + false; + false; + true; + true; + true; + true; + false; + true; + false; + false; + true; + false; + true; + false; + false; + true; + false; + true; + false; + false; + false; + false; + true; + false; + false; + true; + false; + true; + true; + false; + false; + false; + true; + true; + true; + true; + false; + false; + true; + true; + true; + false; + false; + true; + true; + true; + false; + true; + false; + true; + true; + false; + true; + false; + false; + true; + true; + false; + true; + true; + false; + false; + false; + true; + true; + false; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + false; + true; + false; + true; + true; + false; + false; + true; + true; + true; + true; + false; + false; + false; + false; + true; + false; + true; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + false; + true; + true; + false; + true; + false; + true; + false; + true; + true; + true; + false; + true; + true; + true; + false; + true; + false; + true; + true; + false; + false; + false; + true; + false; + true; + false; + true; + true; + true; + false; + true; + false; + true; + true; + true; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + true; + true; + false; + true; + true; + false; + false; + true; + false; + false; + false; + false; + false; + true; + false; + true; + false; + false; + false; + true; + false; + false; + false; + false; + true; + false; + false; + false; + true; + false; + false; + false; + true; + true; + false; + true; + true; + true; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + true; + true; + false; + true; + true; + false; + false; + false; + true; + true; + true; + true; + true; + true; + true; + true; + false; + false; + false; + true; + false; + true; + false; + true; + true; + false; + false; + true; + false; + false; + false; + true; + true; + true; + false; + false; + true; + true; + false; + true; + false; + false; + false; + true; + true; + false; + true; + false; + true; + false; + true; + true; + true; + false; + true; + true; + false; + false; + true; + false; + true; + false; + true; + true; + false; + false; + false; + true; + true; + true; + true; + true; + false; + true; + false; + true; + false; + true; + false; + true; + true; + true; + true; + false; + true; + false; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + false; + true; + false; + true; + true; + false; + true; + true; + false; + false; + true; + true; + false; + false; + false; + false; + true; + true; + false; + false; + false; + false; + false; + false; + true; + true; + false; + false; + true; + false; + false; + true; + false; + false; + false; + true; + true; + false; + false; + true; + true; + false; + false; + true; + true; + false; + false; + false; + true; + false; + false; + true; + true; + false; + true; + false; + false; + true; + false; + false; + true; + false; + true; + false; + false; + false; + true; + false; + true; + false; + true; + false; + false; + false; + true; + true; + true; + true; + false; + true; + false; + true; + false; + true; + false; + false; + false; + true; + false; + true; + true; + true; + false; + false; + false; + true; + true; + true; + true; + true; + false; + true; + false; + true; + false; + true; + false; + false; + true; + false; + true; + false; + true; + false; + true; + false; + true; + true; + true; + false; + false; + true; + false; + false; + false; + true; + true; + true; + true; + true; + false; + true; + false; + true; + false; + true; + false; + true; + false; + false; + false; + false; + true; + false; + true; + true; + false; + true; + true; + true; + false; + false; + true; + false; + true; + true; + true; + true; + false; + true; + true; + false; + true; + true; + false; + false; + false; + true; + false; + false; + false; + false; + false; + false; + true; + false; + false; + false; + true; + false; + false; + true; + true; + false; + true; + true; + true; + true; + false; + true; + false; + false; + false; + true; + true; + false; + false; + true; + false; + true; + true; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + false; + false; + false; + true; + false; + true; + false; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + false; + false; + false; + true; + false; + true; + false; + true; + false; + true; + true; + false; + true; + true; + false; + false; + false; + true; + false; + false; + true; + true; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + true; + true; + false; + true; + false; + false; + false; + false; + true; + true; + false; + true; + true; + true; + false; + true; + false; + true; + false; + true; + false; + false; + false; + false; + false; + true; + false; + true; + false; + false; + true; + true; + false; + false; + true; + true; + false; + false; + false; + true; + false; + false; + false; + false; + true; + true; + true; + false; + true; + false; + true; + true; + false; + false; + false; + false; + true; + true; + true; + true; + false; + true; + false; + true; + true; + true; + true; + true; + false; + false; + true; + false; + true; + false; + false; + false; + false; + true; + false; + true; + false; + true; + false; + true; + true; + true; + false; + ], + ( "0x0666c2bce7f362a2b807d212e9a577f116891a932affd7addec39fbf372c494e", + "0x6758bccfaf2e47c07756b96edea23aa8d10c33b38220bd1c411af612eeec18ab" ) + ); + ( [ + true; + true; + true; + true; + true; + true; + true; + false; + false; + false; + false; + false; + false; + true; + false; + true; + true; + false; + false; + true; + false; + false; + true; + false; + false; + false; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + false; + false; + false; + false; + false; + true; + false; + false; + false; + true; + false; + true; + true; + false; + false; + false; + false; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + false; + true; + false; + true; + true; + true; + false; + true; + false; + false; + true; + true; + false; + false; + true; + true; + true; + false; + true; + true; + false; + false; + false; + false; + true; + true; + true; + false; + false; + true; + true; + false; + false; + false; + false; + false; + false; + true; + true; + false; + false; + true; + true; + false; + true; + false; + true; + false; + false; + true; + false; + false; + false; + false; + false; + true; + true; + true; + true; + true; + false; + false; + false; + false; + true; + true; + false; + false; + true; + false; + true; + false; + false; + false; + false; + true; + true; + false; + false; + true; + true; + true; + false; + true; + false; + false; + true; + true; + false; + false; + false; + true; + false; + false; + false; + true; + true; + false; + false; + true; + false; + true; + false; + false; + false; + true; + false; + true; + false; + false; + true; + false; + true; + true; + false; + false; + true; + false; + false; + true; + true; + true; + false; + true; + false; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + true; + true; + false; + false; + true; + true; + true; + true; + false; + false; + false; + false; + true; + true; + false; + true; + false; + false; + false; + false; + true; + false; + true; + true; + true; + false; + false; + true; + true; + true; + true; + true; + false; + false; + false; + true; + false; + true; + true; + true; + false; + true; + true; + false; + false; + false; + false; + false; + true; + false; + false; + false; + false; + true; + false; + true; + true; + true; + true; + false; + true; + true; + false; + true; + true; + true; + true; + false; + true; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + true; + false; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + true; + false; + false; + false; + true; + false; + false; + true; + true; + false; + false; + false; + true; + false; + false; + false; + true; + false; + false; + false; + true; + false; + false; + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + true; + true; + true; + true; + true; + true; + true; + true; + false; + true; + true; + false; + false; + false; + false; + false; + false; + true; + false; + false; + false; + true; + true; + true; + true; + true; + false; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + true; + true; + true; + true; + true; + true; + false; + true; + false; + false; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + false; + false; + false; + true; + false; + true; + true; + true; + true; + true; + true; + false; + true; + true; + false; + false; + false; + false; + true; + true; + false; + false; + false; + true; + false; + false; + false; + false; + false; + true; + true; + true; + true; + true; + false; + true; + false; + false; + false; + false; + false; + true; + true; + false; + true; + false; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + false; + false; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + false; + false; + false; + true; + false; + false; + true; + true; + true; + false; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + false; + false; + false; + true; + false; + false; + false; + false; + true; + true; + true; + true; + false; + true; + false; + true; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + false; + true; + true; + false; + false; + false; + false; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + true; + false; + false; + true; + true; + false; + true; + true; + true; + true; + true; + true; + true; + true; + false; + true; + true; + false; + false; + true; + true; + false; + false; + true; + false; + false; + true; + false; + true; + true; + true; + false; + false; + false; + false; + true; + true; + false; + false; + true; + false; + false; + false; + false; + false; + true; + true; + true; + false; + true; + false; + true; + false; + false; + false; + false; + true; + false; + false; + false; + true; + false; + true; + false; + true; + true; + true; + false; + true; + false; + false; + false; + true; + false; + false; + false; + false; + false; + true; + true; + false; + true; + false; + false; + false; + false; + true; + false; + true; + false; + true; + false; + true; + false; + true; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + true; + false; + false; + true; + false; + false; + true; + true; + true; + false; + true; + false; + false; + false; + true; + true; + false; + true; + true; + false; + false; + true; + false; + false; + false; + true; + true; + false; + true; + false; + true; + true; + false; + true; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + false; + false; + true; + true; + false; + true; + true; + true; + false; + false; + false; + true; + false; + true; + true; + true; + true; + false; + false; + true; + false; + false; + true; + true; + false; + false; + true; + true; + false; + true; + true; + false; + false; + true; + false; + true; + true; + false; + false; + true; + true; + true; + false; + true; + true; + true; + false; + true; + false; + true; + false; + false; + true; + true; + true; + true; + true; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + false; + true; + true; + true; + true; + true; + false; + true; + false; + true; + true; + true; + false; + true; + true; + false; + false; + false; + true; + true; + false; + false; + true; + true; + true; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + true; + true; + false; + true; + true; + false; + true; + true; + true; + true; + false; + true; + true; + false; + true; + true; + true; + false; + true; + true; + true; + false; + true; + true; + true; + true; + false; + false; + true; + true; + true; + false; + true; + true; + true; + false; + false; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + true; + false; + true; + true; + false; + true; + false; + true; + true; + false; + true; + false; + false; + false; + false; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + true; + true; + false; + true; + false; + false; + false; + false; + false; + false; + true; + false; + false; + false; + false; + false; + false; + false; + true; + true; + true; + false; + false; + true; + true; + false; + true; + false; + true; + true; + true; + true; + true; + false; + true; + false; + true; + true; + false; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + true; + false; + true; + true; + true; + true; + false; + false; + false; + false; + false; + false; + false; + true; + true; + true; + false; + false; + false; + true; + true; + true; + false; + true; + true; + false; + false; + true; + true; + false; + true; + false; + false; + true; + false; + true; + false; + true; + false; + true; + false; + false; + true; + false; + true; + false; + true; + true; + true; + false; + true; + true; + false; + false; + true; + true; + ], + ( "0x130afe02b99375484efb0998f5331d2178e1d00e803049bb0769099420624f5f", + "0x5e2fc6970554ffe358652aa7968ac4fcf3de0c830e6ea492e01a38fafb68cd71" ) + ); + ( [ + true; + true; + true; + true; + true; + true; + false; + true; + true; + false; + false; + true; + true; + false; + true; + false; + false; + true; + true; + false; + true; + true; + false; + false; + true; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + false; + false; + false; + true; + true; + false; + false; + true; + true; + true; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + true; + false; + true; + true; + true; + false; + false; + false; + false; + true; + false; + true; + false; + true; + true; + true; + false; + false; + true; + true; + false; + false; + false; + false; + false; + false; + true; + false; + false; + true; + false; + true; + false; + true; + false; + true; + true; + false; + false; + false; + true; + false; + false; + false; + true; + false; + false; + true; + true; + false; + true; + false; + false; + false; + true; + true; + false; + false; + true; + false; + true; + false; + true; + true; + true; + true; + true; + true; + false; + false; + true; + false; + true; + true; + true; + true; + false; + true; + true; + false; + false; + false; + true; + false; + false; + true; + true; + true; + true; + false; + false; + true; + false; + true; + false; + true; + false; + false; + false; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + true; + true; + false; + true; + false; + false; + true; + false; + false; + true; + true; + true; + true; + true; + false; + true; + false; + true; + false; + true; + true; + true; + true; + false; + true; + true; + false; + false; + true; + false; + false; + true; + false; + false; + false; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + true; + true; + true; + false; + false; + false; + false; + true; + true; + false; + false; + true; + false; + true; + false; + true; + false; + false; + true; + true; + false; + false; + false; + true; + false; + true; + false; + true; + false; + true; + false; + false; + false; + false; + true; + false; + true; + true; + false; + false; + true; + false; + false; + false; + true; + false; + false; + false; + true; + false; + false; + true; + true; + true; + false; + false; + true; + false; + true; + false; + false; + false; + false; + true; + false; + true; + false; + true; + true; + true; + true; + true; + false; + true; + true; + false; + false; + true; + true; + false; + false; + false; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + true; + false; + true; + true; + false; + false; + true; + true; + true; + true; + true; + false; + false; + false; + false; + false; + false; + false; + true; + true; + false; + true; + true; + false; + false; + false; + false; + true; + false; + false; + false; + false; + true; + true; + true; + false; + false; + false; + true; + false; + false; + true; + false; + false; + false; + false; + false; + true; + true; + false; + true; + false; + true; + false; + false; + false; + false; + false; + true; + true; + false; + false; + false; + true; + true; + false; + true; + false; + true; + false; + false; + true; + true; + false; + false; + false; + true; + false; + true; + false; + true; + false; + false; + false; + true; + false; + false; + true; + true; + true; + true; + true; + false; + true; + false; + true; + true; + false; + true; + false; + false; + false; + true; + false; + false; + true; + false; + true; + true; + true; + true; + false; + true; + true; + false; + true; + false; + true; + true; + false; + true; + true; + false; + false; + false; + true; + true; + true; + false; + true; + true; + true; + false; + false; + false; + false; + false; + false; + false; + true; + true; + false; + true; + false; + false; + false; + true; + false; + true; + true; + true; + true; + false; + true; + true; + true; + true; + false; + false; + true; + true; + false; + true; + true; + false; + true; + false; + true; + false; + true; + true; + true; + true; + true; + false; + false; + true; + false; + true; + false; + false; + true; + false; + true; + false; + true; + true; + false; + false; + true; + false; + false; + true; + false; + true; + false; + false; + false; + false; + false; + true; + true; + false; + true; + false; + false; + false; + false; + true; + false; + true; + false; + true; + true; + false; + false; + false; + true; + false; + true; + false; + true; + false; + false; + true; + false; + false; + true; + false; + true; + true; + false; + true; + true; + false; + false; + true; + true; + true; + false; + false; + false; + true; + false; + true; + true; + false; + true; + false; + true; + false; + true; + false; + true; + true; + false; + false; + false; + true; + false; + false; + false; + true; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + true; + true; + false; + false; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + true; + true; + false; + false; + true; + false; + false; + false; + false; + true; + false; + true; + false; + false; + true; + false; + true; + true; + false; + true; + true; + true; + false; + false; + true; + true; + false; + true; + false; + false; + false; + true; + true; + false; + false; + false; + true; + false; + true; + true; + true; + false; + true; + true; + false; + true; + true; + true; + false; + false; + false; + false; + false; + false; + false; + true; + true; + true; + true; + true; + false; + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + true; + true; + true; + false; + false; + false; + false; + false; + true; + true; + true; + false; + true; + true; + true; + false; + true; + true; + true; + true; + false; + false; + false; + false; + false; + true; + true; + true; + false; + true; + false; + true; + true; + false; + false; + true; + false; + true; + false; + false; + false; + false; + true; + false; + true; + true; + true; + true; + true; + false; + false; + true; + true; + false; + true; + false; + false; + false; + false; + true; + true; + true; + false; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + false; + false; + false; + true; + false; + true; + true; + true; + true; + false; + false; + false; + true; + false; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + true; + true; + true; + false; + false; + true; + true; + true; + true; + false; + false; + false; + true; + true; + false; + true; + true; + true; + true; + true; + true; + false; + false; + false; + false; + true; + true; + false; + true; + false; + false; + false; + true; + false; + false; + true; + false; + true; + true; + true; + false; + false; + false; + false; + false; + false; + true; + false; + true; + true; + false; + false; + true; + false; + false; + true; + true; + true; + true; + true; + false; + false; + false; + true; + false; + true; + true; + true; + false; + false; + true; + true; + false; + true; + true; + true; + false; + true; + false; + true; + true; + true; + true; + true; + true; + false; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + false; + true; + true; + true; + false; + false; + false; + true; + false; + false; + true; + true; + true; + false; + true; + false; + false; + false; + true; + false; + false; + true; + false; + true; + false; + false; + false; + true; + false; + false; + true; + true; + true; + true; + false; + false; + true; + false; + false; + false; + true; + true; + false; + true; + true; + true; + true; + false; + false; + false; + false; + true; + false; + false; + true; + true; + true; + true; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + false; + true; + true; + true; + false; + true; + true; + false; + false; + true; + true; + true; + false; + false; + false; + true; + ], + ( "0x67914ebd539961b70f468fa23d4cb42133693a8ac57cd35a1e6369fe34fbedf7", + "0x44770870c0f0cfe59a10df95d6c21e6f1514a2f464b66377599438c126052d9f" ) + ); + ( [false; false; false; false; false; false], + ( "0x62454a957289b3930d10f3def0d512cfe0ef3de06421321221af3558de9d481d", + "0x0279f0aebfb66e53ff69fba16b6608dbf4319b944432f45c6e69a3dbd1f7b330" ) + ); + ( [false; false; false; false; false; false; false], + ( "0x283c7880f35179e201161402d9c4556b255917dbbf0142ae60519787d36d4dea", + "0x648224408b4b83297cd0feb4cdc4eeb224237734931145432793bcd414228dc4" ) + ); + ( [false; false; false; false; false; false; true], + ( "0x1f1086b287636a20063c9614db2de66bb7d49242e88060956a5e5845057f6f5d", + "0x6b1b395421dde74d53341caa9e01f39d7a3138efb9b57fc0381f98f4868df622" ) + ); + ( [false; false; false; false; false; false; true; false; false], + ( "0x1f1086b287636a20063c9614db2de66bb7d49242e88060956a5e5845057f6f5d", + "0x6b1b395421dde74d53341caa9e01f39d7a3138efb9b57fc0381f98f4868df622" ) + ); + ( [ + false; + false; + false; + false; + false; + false; + true; + true; + false; + true; + false; + false; + true; + true; + true; + false; + false; + true; + false; + false; + true; + false; + true; + true; + false; + true; + true; + true; + false; + false; + false; + true; + true; + true; + true; + false; + false; + true; + true; + false; + true; + false; + true; + false; + true; + true; + true; + false; + true; + false; + true; + true; + true; + false; + false; + false; + false; + true; + false; + false; + false; + false; + true; + false; + false; + true; + true; + false; + true; + false; + false; + true; + true; + true; + false; + false; + true; + true; + false; + true; + true; + false; + false; + true; + true; + true; + false; + false; + true; + true; + true; + false; + true; + true; + true; + false; + true; + false; + true; + false; + false; + false; + true; + true; + false; + true; + true; + false; + true; + false; + true; + true; + false; + false; + true; + true; + false; + false; + false; + true; + false; + true; + false; + true; + true; + true; + false; + true; + false; + false; + false; + true; + true; + false; + false; + false; + true; + true; + true; + false; + true; + true; + true; + false; + false; + false; + false; + true; + true; + false; + true; + true; + false; + false; + true; + false; + true; + false; + true; + true; + true; + false; + true; + false; + true; + true; + false; + true; + true; + true; + false; + true; + true; + true; + true; + true; + true; + false; + false; + true; + false; + false; + false; + true; + true; + false; + ], + ( "0x20d2b1b0551efe511755d564f8da4f5bf285fd6051331fa5f129ad95b318f6cd", + "0x2834d96950de67ae80e85545f8333c6e14b5cf5be7325dac768f401e6edd9544" ) + ); + ( [ + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + false; + false; + false; + true; + true; + false; + false; + false; + true; + true; + false; + false; + true; + true; + true; + true; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + true; + false; + false; + true; + true; + false; + false; + true; + true; + true; + false; + true; + false; + true; + true; + false; + true; + true; + true; + true; + true; + true; + true; + false; + false; + true; + true; + true; + true; + false; + false; + false; + false; + false; + false; + false; + false; + false; + false; + true; + true; + false; + false; + true; + true; + true; + false; + false; + false; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + true; + false; + false; + true; + false; + true; + true; + false; + false; + true; + false; + true; + false; + true; + true; + true; + true; + true; + true; + false; + true; + false; + false; + true; + false; + true; + true; + false; + false; + false; + true; + false; + true; + false; + false; + true; + true; + false; + false; + true; + false; + true; + false; + true; + false; + false; + false; + true; + false; + false; + true; + true; + true; + false; + false; + false; + true; + true; + false; + true; + true; + false; + true; + true; + true; + false; + true; + true; + true; + false; + true; + false; + false; + false; + true; + false; + true; + true; + true; + true; + false; + true; + true; + true; + true; + false; + true; + true; + false; + true; + false; + false; + false; + false; + ], + ( "0x01f4850a0f40e07186fee1f0a276f52fb12cffe05c18eb2aa18170330a93c555", + "0x19b0807358e7c8cba9168815ec54c4cd76997c34c592607d172151c48d5377cb" ) + ); + ( [ + false; + false; + false; + false; + false; + false; + true; + true; + true; + true; + true; + false; + false; + false; + false; + true; + false; + true; + true; + true; + true; + true; + true; + true; + true; + false; + false; + false; + false; + true; + false; + true; + true; + false; + false; + false; + true; + true; + true; + true; + true; + true; + true; + true; + false; + false; + true; + true; + true; + false; + true; + false; + true; + false; + false; + true; + false; + false; + false; + false; + true; + false; + true; + true; + false; + true; + true; + true; + true; + false; + false; + true; + false; + true; + false; + false; + true; + false; + true; + true; + true; + false; + true; + false; + false; + true; + true; + true; + false; + true; + true; + true; + true; + true; + true; + false; + false; + true; + true; + true; + true; + true; + false; + false; + true; + false; + false; + true; + false; + true; + false; + true; + false; + true; + false; + false; + true; + false; + true; + true; + true; + false; + true; + false; + false; + false; + false; + true; + true; + false; + true; + true; + false; + true; + true; + true; + true; + true; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + true; + true; + false; + true; + false; + true; + false; + true; + true; + true; + true; + true; + true; + false; + true; + false; + false; + true; + true; + false; + true; + false; + true; + true; + false; + true; + false; + true; + false; + false; + true; + true; + false; + true; + true; + false; + false; + ], + ( "0x26dd81a3ffa37452c6a932d41eb4f2e0fedd531e9af8c2a7935b91dff653879d", + "0x2fc7aebb729ef5cabf0fb3f883bc2eb2603093850b0ec19c1a3c08b653e7f27f" ) + ); + ( [ + false; + false; + false; + false; + false; + false; + false; + true; + false; + false; + false; + true; + true; + true; + true; + true; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + true; + false; + true; + true; + false; + false; + true; + true; + true; + false; + false; + false; + false; + true; + true; + true; + false; + false; + true; + false; + false; + false; + true; + false; + true; + false; + false; + true; + false; + true; + true; + true; + false; + false; + true; + false; + false; + true; + true; + false; + false; + false; + false; + true; + true; + false; + true; + false; + true; + false; + true; + false; + true; + false; + true; + true; + true; + true; + false; + false; + true; + false; + true; + true; + true; + true; + true; + true; + false; + false; + false; + false; + false; + false; + false; + true; + true; + true; + false; + false; + true; + true; + true; + false; + true; + false; + true; + false; + true; + false; + true; + false; + true; + false; + true; + false; + true; + false; + false; + false; + false; + false; + false; + true; + false; + true; + true; + true; + false; + false; + false; + false; + false; + false; + true; + true; + false; + true; + true; + false; + false; + false; + false; + true; + false; + false; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + false; + false; + true; + false; + true; + true; + true; + false; + true; + false; + false; + true; + true; + false; + false; + true; + true; + true; + true; + true; + false; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + false; + false; + false; + true; + true; + false; + false; + true; + true; + true; + true; + false; + false; + false; + false; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + true; + true; + true; + false; + true; + false; + false; + true; + false; + false; + true; + true; + false; + true; + false; + true; + true; + true; + false; + true; + false; + false; + true; + true; + true; + false; + true; + false; + false; + true; + true; + false; + false; + true; + true; + true; + false; + true; + false; + true; + false; + false; + false; + true; + true; + false; + true; + false; + false; + true; + false; + true; + true; + false; + true; + true; + false; + false; + false; + true; + false; + true; + false; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + false; + true; + false; + false; + true; + true; + false; + true; + false; + false; + false; + true; + false; + false; + true; + false; + true; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + false; + true; + false; + false; + false; + true; + false; + true; + false; + true; + false; + true; + true; + false; + true; + true; + false; + false; + false; + true; + false; + false; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + true; + true; + false; + true; + true; + true; + true; + false; + true; + true; + true; + false; + false; + true; + false; + false; + false; + false; + false; + false; + true; + true; + false; + true; + true; + true; + true; + false; + false; + false; + false; + false; + true; + false; + false; + false; + true; + false; + true; + false; + false; + true; + false; + true; + false; + true; + false; + true; + false; + false; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + false; + true; + false; + true; + true; + true; + false; + false; + true; + true; + true; + false; + true; + false; + false; + false; + false; + false; + false; + true; + false; + false; + true; + true; + false; + true; + true; + false; + false; + false; + false; + true; + true; + true; + true; + false; + false; + false; + false; + false; + true; + false; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + true; + false; + true; + true; + true; + false; + true; + false; + false; + true; + false; + true; + false; + false; + true; + false; + true; + false; + true; + false; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + false; + false; + false; + false; + false; + true; + false; + true; + false; + false; + false; + true; + true; + true; + false; + false; + false; + false; + true; + false; + false; + true; + false; + true; + false; + true; + true; + true; + true; + false; + true; + false; + true; + true; + false; + false; + true; + false; + false; + false; + true; + false; + false; + true; + true; + false; + false; + false; + true; + true; + false; + true; + true; + false; + true; + false; + true; + false; + true; + true; + true; + true; + false; + false; + false; + true; + true; + true; + true; + true; + false; + true; + false; + false; + false; + true; + true; + false; + true; + false; + false; + true; + true; + false; + true; + true; + true; + false; + false; + true; + false; + true; + false; + true; + true; + false; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + false; + true; + true; + false; + true; + false; + false; + true; + true; + false; + true; + true; + false; + false; + false; + false; + false; + false; + true; + true; + false; + true; + false; + true; + false; + true; + false; + false; + false; + true; + false; + false; + false; + true; + true; + true; + false; + true; + false; + true; + false; + false; + true; + false; + false; + true; + false; + true; + false; + true; + true; + false; + false; + false; + false; + true; + false; + false; + true; + false; + true; + false; + false; + false; + false; + true; + true; + true; + true; + false; + false; + true; + false; + true; + true; + false; + false; + false; + true; + false; + true; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + true; + true; + false; + true; + false; + false; + true; + true; + false; + true; + false; + false; + true; + true; + true; + true; + true; + true; + true; + false; + false; + false; + true; + true; + false; + false; + true; + true; + true; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + true; + true; + false; + false; + true; + ], + ( "0x1111740552773b00aa6a2334575aa94102cfbd084290a430c90eb56d6db65b85", + "0x6560c44b11683c20030626f89456f78a53ae8a89f565956a98ffc554b48fbb1a" ) + ); + ( [ + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + false; + true; + true; + false; + true; + false; + true; + true; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + true; + false; + false; + false; + false; + true; + false; + false; + false; + false; + false; + false; + true; + true; + false; + false; + true; + false; + true; + false; + true; + false; + true; + false; + true; + false; + false; + false; + false; + true; + false; + false; + true; + false; + false; + false; + true; + false; + true; + false; + false; + true; + false; + true; + true; + true; + true; + false; + false; + false; + false; + true; + true; + true; + true; + true; + false; + false; + false; + true; + false; + false; + true; + true; + false; + true; + false; + true; + true; + true; + true; + false; + false; + true; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + false; + false; + true; + false; + false; + false; + true; + true; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + true; + false; + false; + false; + false; + true; + true; + false; + true; + true; + true; + false; + true; + true; + true; + false; + false; + true; + true; + true; + false; + true; + false; + false; + false; + true; + false; + false; + true; + false; + true; + true; + false; + true; + false; + false; + false; + false; + false; + true; + false; + false; + false; + false; + true; + true; + false; + true; + false; + false; + false; + true; + true; + false; + true; + true; + false; + true; + false; + false; + false; + true; + true; + true; + true; + false; + true; + false; + false; + false; + true; + false; + true; + true; + false; + true; + false; + true; + true; + true; + false; + false; + false; + true; + false; + true; + true; + true; + true; + true; + false; + true; + true; + false; + true; + false; + true; + true; + false; + false; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + true; + false; + true; + true; + true; + true; + true; + false; + true; + false; + false; + true; + false; + true; + true; + false; + true; + false; + false; + false; + true; + false; + true; + false; + true; + false; + true; + true; + false; + false; + false; + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + false; + true; + false; + true; + false; + true; + true; + false; + true; + false; + true; + true; + false; + true; + true; + true; + false; + false; + false; + false; + true; + false; + true; + true; + true; + true; + true; + true; + true; + true; + false; + true; + true; + true; + true; + false; + false; + false; + false; + true; + true; + false; + false; + true; + false; + false; + true; + false; + false; + false; + false; + false; + true; + true; + true; + false; + false; + false; + false; + true; + false; + true; + false; + false; + false; + true; + true; + false; + true; + false; + true; + true; + true; + true; + true; + false; + false; + true; + false; + false; + true; + false; + false; + false; + false; + true; + false; + true; + false; + true; + true; + true; + true; + false; + false; + true; + true; + false; + true; + false; + true; + false; + false; + true; + true; + false; + true; + true; + false; + true; + false; + true; + false; + false; + false; + false; + false; + true; + false; + true; + false; + true; + false; + true; + true; + true; + false; + false; + false; + true; + true; + false; + false; + false; + false; + false; + true; + true; + false; + true; + true; + true; + true; + false; + false; + false; + false; + true; + false; + false; + true; + true; + true; + true; + true; + true; + true; + false; + true; + false; + true; + true; + true; + true; + false; + false; + false; + true; + false; + false; + false; + false; + true; + false; + true; + false; + false; + false; + false; + true; + false; + false; + false; + false; + true; + true; + false; + true; + true; + false; + false; + false; + false; + true; + false; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + true; + false; + false; + true; + false; + false; + true; + false; + true; + false; + false; + false; + false; + true; + true; + true; + true; + true; + true; + true; + false; + true; + false; + false; + false; + false; + true; + false; + true; + true; + false; + true; + true; + true; + false; + true; + true; + false; + false; + true; + true; + false; + false; + false; + false; + true; + false; + false; + true; + true; + false; + true; + true; + false; + false; + true; + false; + true; + false; + true; + false; + false; + true; + true; + true; + true; + true; + false; + true; + true; + false; + false; + false; + true; + false; + true; + true; + false; + true; + false; + true; + true; + true; + false; + true; + true; + false; + false; + true; + true; + true; + true; + false; + true; + false; + true; + true; + false; + false; + false; + false; + true; + true; + false; + true; + true; + true; + false; + false; + false; + true; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + true; + false; + true; + false; + true; + true; + false; + false; + false; + true; + true; + true; + false; + true; + true; + true; + true; + false; + false; + false; + false; + true; + false; + true; + false; + true; + true; + false; + true; + true; + true; + true; + false; + true; + true; + true; + true; + true; + true; + true; + false; + false; + false; + true; + false; + false; + false; + false; + false; + true; + true; + false; + false; + false; + true; + false; + true; + false; + false; + false; + true; + false; + true; + true; + false; + false; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + true; + false; + true; + true; + true; + true; + false; + true; + true; + true; + true; + false; + false; + false; + true; + false; + true; + true; + true; + true; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + false; + true; + true; + false; + true; + false; + false; + false; + false; + false; + true; + true; + true; + true; + false; + false; + false; + ], + ( "0x429349ea9b5f8163bcda3014b3e15554df5173353fd73f315a49360c97265f68", + "0x188774bb6de41eba669be5d368942783f937acf2f418385fc5c78479b0a405ee" ) + ); + ( [ + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + false; + false; + false; + false; + true; + true; + false; + true; + false; + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + false; + true; + false; + true; + true; + true; + true; + false; + true; + false; + false; + true; + false; + true; + false; + true; + false; + true; + false; + true; + true; + false; + true; + true; + true; + false; + false; + false; + false; + false; + true; + false; + true; + true; + true; + true; + true; + true; + false; + false; + false; + true; + true; + true; + true; + true; + true; + true; + false; + true; + true; + false; + false; + true; + true; + false; + false; + false; + true; + true; + false; + true; + true; + false; + true; + false; + true; + false; + true; + true; + false; + false; + true; + false; + false; + false; + false; + true; + false; + true; + false; + false; + true; + false; + false; + true; + false; + false; + true; + true; + false; + true; + false; + true; + false; + false; + false; + true; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + false; + false; + true; + true; + false; + true; + true; + false; + true; + true; + true; + true; + true; + true; + false; + false; + false; + false; + false; + true; + false; + true; + false; + true; + true; + false; + true; + false; + false; + false; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + true; + true; + true; + false; + false; + true; + true; + false; + true; + true; + false; + false; + false; + true; + false; + false; + true; + false; + false; + false; + false; + false; + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + true; + true; + false; + false; + false; + false; + false; + false; + false; + true; + false; + false; + false; + false; + false; + false; + true; + false; + false; + false; + true; + true; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + true; + false; + false; + true; + true; + false; + false; + false; + true; + true; + true; + false; + false; + true; + false; + true; + true; + true; + true; + false; + false; + true; + true; + true; + true; + false; + true; + true; + true; + true; + true; + true; + false; + false; + true; + false; + false; + false; + false; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + false; + true; + true; + false; + false; + false; + false; + true; + true; + true; + true; + true; + false; + true; + false; + false; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + true; + false; + false; + true; + true; + false; + false; + false; + false; + false; + true; + true; + true; + false; + true; + true; + true; + false; + true; + true; + true; + false; + true; + true; + false; + false; + true; + false; + false; + true; + false; + true; + true; + false; + false; + true; + false; + false; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + true; + false; + false; + false; + true; + true; + false; + true; + true; + false; + true; + false; + true; + true; + true; + false; + false; + false; + false; + false; + true; + true; + false; + false; + true; + true; + false; + true; + true; + false; + true; + false; + true; + true; + true; + false; + true; + false; + true; + false; + false; + true; + false; + false; + true; + false; + false; + true; + true; + true; + false; + false; + false; + false; + false; + true; + true; + true; + true; + false; + true; + false; + true; + true; + true; + false; + true; + true; + true; + true; + true; + false; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + false; + true; + false; + true; + false; + false; + true; + false; + false; + false; + false; + false; + true; + false; + false; + false; + true; + false; + false; + false; + true; + true; + false; + true; + false; + true; + true; + false; + false; + true; + true; + false; + false; + true; + false; + false; + true; + true; + true; + false; + false; + false; + true; + false; + true; + false; + false; + true; + false; + false; + false; + true; + false; + false; + false; + false; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + false; + false; + false; + false; + true; + false; + true; + true; + true; + false; + false; + false; + false; + true; + true; + true; + true; + false; + false; + true; + true; + true; + false; + true; + false; + true; + false; + true; + true; + true; + false; + false; + false; + true; + true; + true; + true; + false; + false; + true; + false; + false; + true; + false; + true; + true; + true; + true; + false; + false; + false; + true; + true; + false; + false; + false; + false; + true; + false; + false; + true; + false; + true; + true; + false; + false; + false; + false; + true; + true; + true; + false; + true; + true; + false; + false; + false; + true; + true; + false; + true; + false; + false; + true; + true; + false; + false; + true; + true; + false; + true; + false; + true; + true; + true; + false; + false; + false; + false; + false; + true; + true; + true; + true; + true; + false; + false; + false; + true; + false; + true; + false; + false; + true; + false; + false; + true; + true; + false; + false; + false; + false; + true; + true; + true; + false; + false; + false; + true; + false; + false; + true; + false; + false; + false; + true; + true; + true; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + false; + false; + true; + false; + true; + false; + true; + true; + true; + false; + true; + false; + true; + true; + true; + true; + false; + true; + true; + false; + false; + true; + true; + false; + false; + true; + true; + false; + false; + true; + false; + true; + true; + true; + true; + true; + true; + false; + false; + true; + true; + false; + false; + true; + true; + true; + false; + true; + true; + false; + true; + true; + false; + false; + false; + true; + true; + false; + true; + true; + true; + false; + false; + true; + true; + false; + false; + false; + true; + false; + true; + false; + false; + true; + true; + false; + false; + false; + false; + true; + false; + false; + false; + true; + false; + false; + true; + true; + false; + true; + true; + true; + true; + false; + true; + false; + false; + true; + true; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + true; + true; + true; + true; + false; + true; + false; + false; + true; + false; + true; + false; + false; + true; + true; + false; + false; + false; + false; + true; + true; + false; + false; + true; + true; + true; + false; + true; + false; + false; + false; + false; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + true; + false; + false; + true; + false; + true; + false; + false; + false; + true; + true; + true; + true; + false; + true; + true; + false; + false; + false; + false; + false; + true; + false; + false; + true; + true; + false; + false; + false; + true; + true; + false; + false; + false; + false; + true; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + false; + false; + true; + true; + false; + false; + true; + false; + true; + false; + true; + true; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + true; + false; + false; + true; + true; + true; + false; + false; + true; + true; + false; + false; + true; + true; + true; + false; + false; + false; + false; + true; + false; + false; + true; + false; + true; + false; + false; + false; + false; + false; + false; + false; + true; + true; + false; + false; + false; + true; + false; + true; + true; + true; + true; + false; + false; + true; + false; + false; + true; + true; + false; + ], + ( "0x00e827f3ed136f3c91c61c97ab9b7cca0ea53c20e47abb5e226ede297bdd5f37", + "0x315cc00a54972df6a19f650d3fab5f2ad0fb07397bacb6944568618f2aa76bf6" ) + ); + ( [ + false; + false; + false; + false; + false; + false; + false; + false; + true; + true; + true; + false; + false; + true; + false; + true; + false; + true; + true; + true; + false; + false; + true; + true; + true; + true; + true; + true; + false; + false; + true; + true; + false; + true; + true; + true; + false; + true; + false; + false; + false; + false; + true; + true; + true; + false; + true; + true; + true; + true; + false; + false; + true; + true; + false; + true; + true; + false; + true; + false; + true; + true; + true; + false; + true; + false; + true; + false; + true; + false; + true; + false; + true; + true; + false; + false; + true; + true; + true; + false; + true; + true; + true; + false; + false; + false; + false; + true; + true; + true; + true; + false; + false; + true; + true; + false; + false; + true; + false; + false; + true; + true; + false; + true; + true; + true; + true; + false; + false; + false; + true; + true; + true; + false; + false; + false; + false; + true; + false; + true; + false; + true; + true; + true; + true; + true; + false; + true; + false; + false; + false; + true; + false; + false; + true; + false; + true; + false; + true; + false; + false; + true; + false; + false; + false; + true; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + true; + true; + false; + true; + true; + true; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + false; + true; + false; + true; + true; + true; + false; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + true; + false; + false; + true; + false; + false; + false; + true; + false; + false; + true; + false; + false; + false; + false; + true; + false; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + true; + false; + true; + false; + true; + true; + true; + false; + false; + true; + true; + false; + true; + true; + true; + false; + false; + true; + false; + false; + true; + true; + true; + true; + true; + false; + false; + false; + true; + true; + false; + false; + false; + true; + false; + true; + false; + false; + true; + true; + true; + true; + false; + true; + true; + true; + false; + true; + true; + false; + true; + false; + true; + true; + true; + false; + true; + true; + true; + false; + false; + true; + false; + false; + false; + false; + true; + false; + false; + true; + false; + false; + false; + true; + true; + false; + false; + true; + true; + true; + false; + false; + true; + false; + true; + false; + false; + false; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + false; + false; + true; + true; + true; + false; + false; + false; + false; + true; + true; + false; + true; + false; + true; + true; + true; + false; + true; + false; + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + true; + false; + false; + false; + true; + false; + false; + false; + false; + false; + false; + true; + false; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + true; + false; + false; + true; + false; + true; + true; + false; + false; + true; + false; + true; + true; + false; + false; + true; + true; + true; + true; + true; + false; + false; + false; + true; + true; + false; + false; + false; + true; + false; + true; + false; + false; + true; + false; + true; + false; + false; + true; + false; + false; + false; + true; + true; + false; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + false; + true; + true; + false; + false; + true; + false; + false; + false; + true; + false; + false; + true; + false; + false; + true; + false; + false; + true; + false; + false; + true; + false; + true; + true; + true; + true; + true; + true; + true; + true; + false; + true; + false; + false; + false; + false; + false; + false; + false; + false; + true; + false; + true; + true; + false; + false; + false; + false; + true; + false; + false; + true; + true; + false; + false; + false; + false; + false; + false; + true; + false; + false; + true; + false; + true; + true; + false; + true; + false; + false; + true; + false; + false; + true; + false; + false; + true; + false; + false; + true; + false; + true; + true; + false; + true; + false; + true; + false; + true; + true; + false; + true; + false; + true; + false; + false; + true; + false; + true; + false; + true; + false; + true; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + true; + false; + true; + false; + true; + false; + false; + false; + true; + true; + true; + false; + true; + false; + true; + false; + false; + false; + true; + false; + false; + true; + true; + true; + false; + false; + true; + false; + true; + true; + true; + false; + true; + false; + false; + false; + true; + true; + true; + false; + true; + false; + true; + true; + false; + false; + true; + false; + false; + true; + true; + false; + false; + true; + false; + false; + true; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + false; + true; + true; + true; + true; + false; + true; + true; + true; + false; + false; + false; + false; + true; + false; + false; + true; + true; + true; + false; + false; + false; + true; + false; + true; + false; + false; + true; + true; + false; + true; + true; + false; + false; + false; + false; + false; + false; + true; + false; + true; + true; + true; + true; + true; + true; + true; + true; + false; + false; + false; + true; + false; + false; + true; + false; + true; + true; + true; + true; + true; + false; + false; + false; + false; + false; + false; + false; + true; + false; + true; + true; + true; + true; + false; + false; + false; + false; + false; + true; + false; + true; + false; + false; + true; + true; + false; + true; + false; + false; + true; + true; + false; + true; + true; + true; + true; + false; + true; + true; + false; + true; + true; + true; + false; + false; + true; + false; + true; + true; + true; + true; + false; + false; + true; + false; + false; + false; + false; + true; + true; + true; + true; + false; + false; + false; + true; + true; + true; + false; + true; + false; + true; + false; + true; + false; + true; + false; + true; + false; + true; + true; + false; + false; + true; + true; + false; + false; + true; + false; + true; + false; + false; + false; + true; + true; + true; + false; + true; + false; + false; + false; + false; + true; + true; + true; + true; + true; + true; + false; + true; + false; + false; + false; + true; + false; + false; + true; + true; + true; + false; + false; + false; + false; + false; + true; + false; + false; + true; + false; + false; + true; + true; + true; + true; + false; + false; + true; + true; + true; + false; + true; + true; + true; + false; + false; + false; + true; + false; + false; + false; + true; + false; + false; + true; + true; + true; + false; + true; + true; + false; + true; + true; + false; + false; + false; + true; + false; + true; + false; + true; + true; + true; + false; + false; + true; + false; + true; + true; + true; + false; + false; + false; + true; + false; + false; + true; + false; + false; + false; + false; + true; + true; + true; + false; + true; + false; + false; + false; + true; + true; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + false; + false; + false; + false; + false; + false; + true; + false; + false; + true; + true; + true; + true; + false; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + false; + true; + true; + false; + false; + true; + true; + false; + false; + true; + true; + true; + false; + false; + true; + true; + false; + false; + false; + true; + false; + false; + true; + true; + true; + true; + false; + true; + false; + true; + false; + false; + false; + false; + true; + false; + false; + false; + false; + true; + false; + true; + false; + true; + false; + false; + false; + ], + ( "0x3ee50557c4aa9158c4bb9d5961208e6c62f55c73ad7c7695a0eba0bcb6d83d05", + "0x1b1a2be6e47688828aeadf2d37db298eac0c2736c2722b227871fdeeee29de33" ) + ); + ( [false; true; false; false; false; true], + ( "0x61f8e2cb8e945631677b450d5e5669bc6b5f2ec69b321ac550dbe74525d7ac9a", + "0x4e11951ab9c9400ee38a18bd98cdb9453f1f67141ee9d9bf0c1c157d4fb34f9a" ) + ); + ( [false; true; false; false; false; true; false], + ( "0x27fa1e296c37dde8448483ce5485c2604d1d830e53812246299773a02ecd519c", + "0x08e499113675202cb42b4b681a31430814edebd72c5bb3bc3bfedf91fb0605df" ) + ); + ( [false; true; false; false; false; true; true], + ( "0x52112dd7a4293d049bb011683244a0f957e6ba95e1d1cf2fb6654d449a6d3fbc", + "0x2ae14ecd81bb5b4489d2d64b5d2eb92a684087b28dd9a4950ecdb78c014e178c" ) + ); + ( [false; true; false; false; false; true; true; false; false], + ( "0x52112dd7a4293d049bb011683244a0f957e6ba95e1d1cf2fb6654d449a6d3fbc", + "0x2ae14ecd81bb5b4489d2d64b5d2eb92a684087b28dd9a4950ecdb78c014e178c" ) + ); + ( [ + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + true; + true; + false; + ], + ( "0x414f6ba05f6b92da1f9051950769e1083d05615def32b016ae424309828a11f4", + "0x471d2109656afcb96d0609b371b132b97efcf72c6051064dd19fdc004799bfa9" ) + ); + ] diff --git a/src/lib_mec/test/test_vesta_affine.ml b/src/lib_mec/test/test_vesta_affine.ml new file mode 100644 index 000000000000..e1ace1c545fd --- /dev/null +++ b/src/lib_mec/test/test_vesta_affine.ml @@ -0,0 +1,19 @@ +module VestaValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Vesta.Affine) +module VestaEquality = Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Vesta.Affine) +module VestaECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Vesta.Affine) +module VestaRepresentation = + Mec.Curve.Utils.PBT.MakeCompressedSerialisationAffine (Mec.Curve.Vesta.Affine) + +let () = + let open Alcotest in + run + ~verbose:true + "Vesta affine coordinates" + [ + VestaValueGeneration.get_tests (); + VestaEquality.get_tests (); + VestaECProperties.get_tests (); + VestaRepresentation.get_tests (); + ] diff --git a/src/lib_mec/test/test_vesta_jacobian.ml b/src/lib_mec/test/test_vesta_jacobian.ml new file mode 100644 index 000000000000..3461fa280e72 --- /dev/null +++ b/src/lib_mec/test/test_vesta_jacobian.ml @@ -0,0 +1,17 @@ +module VestaValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Vesta.Jacobian) +module VestaEquality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Vesta.Jacobian) +module VestaECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Vesta.Jacobian) + +let () = + let open Alcotest in + run + ~verbose:true + "Vesta jacobian coordinates" + [ + VestaValueGeneration.get_tests (); + VestaEquality.get_tests (); + VestaECProperties.get_tests (); + ] diff --git a/src/lib_mec/test/test_vesta_projective.ml b/src/lib_mec/test/test_vesta_projective.ml new file mode 100644 index 000000000000..d8d27d1f7710 --- /dev/null +++ b/src/lib_mec/test/test_vesta_projective.ml @@ -0,0 +1,17 @@ +module VestaValueGeneration = + Mec.Curve.Utils.PBT.MakeValueGeneration (Mec.Curve.Vesta.Projective) +module VestaEquality = + Mec.Curve.Utils.PBT.MakeEquality (Mec.Curve.Vesta.Projective) +module VestaECProperties = + Mec.Curve.Utils.PBT.MakeECProperties (Mec.Curve.Vesta.Projective) + +let () = + let open Alcotest in + run + ~verbose:true + "Vesta projective coordinates" + [ + VestaValueGeneration.get_tests (); + VestaEquality.get_tests (); + VestaECProperties.get_tests (); + ] diff --git a/src/lib_mec/tweedledee.ml b/src/lib_mec/tweedledee.ml new file mode 100644 index 000000000000..14cdeb087500 --- /dev/null +++ b/src/lib_mec/tweedledee.ml @@ -0,0 +1,112 @@ +(** + + https://github.com/daira/tweedle + + Base field: 2^254 + 4707489544292117082687961190295928833 = 28948022309329048855892746252171976963322203655954433126947083963168578338817 (254 bits - 32 bytes) + Scalar field: 2^254 + 4707489545178046908921067385359695873 = 28948022309329048855892746252171976963322203655955319056773317069363642105857 (254 bits - 32 bytes) + + Base field multiplicative subgroup decomposition: + 2^34 * 3 * 561665555565638329055562814312908972367531846121311209609791868583 + Prime field multiplication subgroup decomposition: + 2^33 * 3 * 5179 * 216901160674121772178243990852639108850176422522235334586122689 +*) + +let two_z = Z.succ Z.one + +module Fq = Ff.MakeFp (struct + let prime_order = + Z.((two_z ** 254) + Z.of_string "4707489544292117082687961190295928833") +end) + +module Fp = Ff.MakeFp (struct + let prime_order = + Z.((two_z ** 254) + Z.of_string "4707489545178046908921067385359695873") +end) + +module Jacobian = + Ec.MakeJacobianWeierstrass (Fq) (Fp) + (struct + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 5) + + let cofactor = Z.one + + (* x = -1 + y = 2 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.(to_bytes (negate (of_string "1"))); + Fq.(to_bytes (of_string "2")); + Fq.(to_bytes one); + ] + end) + +module Projective = + Ec.MakeProjectiveWeierstrass (Fq) (Fp) + (struct + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 5) + + let cofactor = Z.one + + (* x = -1 + y = 2 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.(to_bytes (negate (of_string "1"))); + Fq.(to_bytes (of_string "2")); + Fq.(to_bytes one); + ] + end) + +module Affine = + Ec.MakeAffineWeierstrass (Fq) (Fp) + (struct + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 5) + + let cofactor = Z.one + + (* x = -1 + y = 2 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.(to_bytes (negate (of_string "1"))); Fq.(to_bytes (of_string "2")); + ] + end) + +let from_affine_weierstrass_to_jacobian_weierstrass p = + Ec.from_affine_weierstrass_to_jacobian_weierstrass + (module Affine) + (module Jacobian) + p + +let from_affine_weierstrass_to_projective_weierstrass p = + Ec.from_affine_weierstrass_to_projective_weierstrass + (module Affine) + (module Projective) + p + +let from_jacobian_weierstrass_to_affine_weierstrass p = + Ec.from_jacobian_weierstrass_to_affine_weierstrass + (module Jacobian) + (module Affine) + p + +let from_projective_weierstrass_to_affine_weierstrass p = + Ec.from_projective_weierstrass_to_affine_weierstrass + (module Projective) + (module Affine) + p diff --git a/src/lib_mec/tweedledee.mli b/src/lib_mec/tweedledee.mli new file mode 100644 index 000000000000..0d06a0937537 --- /dev/null +++ b/src/lib_mec/tweedledee.mli @@ -0,0 +1,13 @@ +module Projective : Ec_sig.ProjectiveWeierstrassT + +module Affine : Ec_sig.AffineWeierstrassT + +module Jacobian : Ec_sig.JacobianWeierstrassT + +val from_affine_weierstrass_to_jacobian_weierstrass : Affine.t -> Jacobian.t + +val from_affine_weierstrass_to_projective_weierstrass : Affine.t -> Projective.t + +val from_jacobian_weierstrass_to_affine_weierstrass : Jacobian.t -> Affine.t + +val from_projective_weierstrass_to_affine_weierstrass : Projective.t -> Affine.t diff --git a/src/lib_mec/tweedledum.ml b/src/lib_mec/tweedledum.ml new file mode 100644 index 000000000000..c1240b0b33aa --- /dev/null +++ b/src/lib_mec/tweedledum.ml @@ -0,0 +1,112 @@ +(** + + https://github.com/daira/tweedle + + Base field: 2^254 + 4707489545178046908921067385359695873 = 28948022309329048855892746252171976963322203655955319056773317069363642105857 (254 bits - 32 bytes) + Scalar field: 2^254 + 4707489544292117082687961190295928833 = 28948022309329048855892746252171976963322203655954433126947083963168578338817 (254 bits - 32 bytes) + + Base field multiplication subgroup decomposition: + 2^33 * 3 * 5179 * 216901160674121772178243990852639108850176422522235334586122689 + Scalar field multiplicative subgroup decomposition: + 2^34 * 3 * 561665555565638329055562814312908972367531846121311209609791868583 +*) + +let two_z = Z.succ Z.one + +module Fq = Ff.MakeFp (struct + let prime_order = + Z.((two_z ** 254) + Z.of_string "4707489545178046908921067385359695873") +end) + +module Fp = Ff.MakeFp (struct + let prime_order = + Z.((two_z ** 254) + Z.of_string "4707489544292117082687961190295928833") +end) + +module Jacobian = + Ec.MakeJacobianWeierstrass (Fq) (Fp) + (struct + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 5) + + let cofactor = Z.one + + (* x = -1 + y = 2 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.(to_bytes (negate (of_string "1"))); + Fq.(to_bytes (of_string "2")); + Fq.(to_bytes one); + ] + end) + +module Projective = + Ec.MakeProjectiveWeierstrass (Fq) (Fp) + (struct + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 5) + + let cofactor = Z.one + + (* x = -1 + y = 2 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.(to_bytes (negate (of_string "1"))); + Fq.(to_bytes (of_string "2")); + Fq.(to_bytes one); + ] + end) + +module Affine = + Ec.MakeAffineWeierstrass (Fq) (Fp) + (struct + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 5) + + let cofactor = Z.one + + (* x = -1 + y = 2 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.(to_bytes (negate (of_string "1"))); Fq.(to_bytes (of_string "2")); + ] + end) + +let from_affine_weierstrass_to_jacobian_weierstrass p = + Ec.from_affine_weierstrass_to_jacobian_weierstrass + (module Affine) + (module Jacobian) + p + +let from_affine_weierstrass_to_projective_weierstrass p = + Ec.from_affine_weierstrass_to_projective_weierstrass + (module Affine) + (module Projective) + p + +let from_jacobian_weierstrass_to_affine_weierstrass p = + Ec.from_jacobian_weierstrass_to_affine_weierstrass + (module Jacobian) + (module Affine) + p + +let from_projective_weierstrass_to_affine_weierstrass p = + Ec.from_projective_weierstrass_to_affine_weierstrass + (module Projective) + (module Affine) + p diff --git a/src/lib_mec/tweedledum.mli b/src/lib_mec/tweedledum.mli new file mode 100644 index 000000000000..0d06a0937537 --- /dev/null +++ b/src/lib_mec/tweedledum.mli @@ -0,0 +1,13 @@ +module Projective : Ec_sig.ProjectiveWeierstrassT + +module Affine : Ec_sig.AffineWeierstrassT + +module Jacobian : Ec_sig.JacobianWeierstrassT + +val from_affine_weierstrass_to_jacobian_weierstrass : Affine.t -> Jacobian.t + +val from_affine_weierstrass_to_projective_weierstrass : Affine.t -> Projective.t + +val from_jacobian_weierstrass_to_affine_weierstrass : Jacobian.t -> Affine.t + +val from_projective_weierstrass_to_affine_weierstrass : Projective.t -> Affine.t diff --git a/src/lib_mec/vesta.ml b/src/lib_mec/vesta.ml new file mode 100644 index 000000000000..412694a2d208 --- /dev/null +++ b/src/lib_mec/vesta.ml @@ -0,0 +1,113 @@ +(** + Base field: 2^254 + 45560315531506369815346746415080538113 = 28948022309329048855892746252171976963363056481941647379679742748393362948097 (254 bits - 32 bytes) + Scalar field: 2^254 + 45560315531419706090280762371685220353 = 28948022309329048855892746252171976963363056481941560715954676764349967630337 (254 bits - 32 bytes) + + Base field multiplicative subgroup decomposition: + 2^32 * 3^2 * 1709 * 24859 * 17627503553531704781201602214972145569028026719617221564519 + + Prime field multiplication subgroup decomposition: + 2^32 * 3 * 463 * 4852402207910482324454106387152561316357015077916052529702775169 +*) + +let two_z = Z.succ Z.one + +module Fq = Ff.MakeFp (struct + let prime_order = + Z.((two_z ** 254) + Z.of_string "45560315531506369815346746415080538113") +end) + +module Fp = Ff.MakeFp (struct + let prime_order = + Z.((two_z ** 254) + Z.of_string "45560315531419706090280762371685220353") +end) + +module Jacobian = + Ec.MakeJacobianWeierstrass (Fq) (Fp) + (struct + (* https://github.com/zcash/pasta *) + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 5) + + let cofactor = Z.one + + (* x = -1 + y = 2 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.(to_bytes (negate (of_string "1"))); + Fq.(to_bytes (of_string "2")); + Fq.(to_bytes one); + ] + end) + +module Projective = + Ec.MakeProjectiveWeierstrass (Fq) (Fp) + (struct + (* https://github.com/zcash/pasta *) + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 5) + + let cofactor = Z.one + + (* x = -1 + y = 2 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.(to_bytes (negate (of_string "1"))); + Fq.(to_bytes (of_string "2")); + Fq.(to_bytes one); + ] + end) + +module Affine = + Ec.MakeAffineWeierstrass (Fq) (Fp) + (struct + (* https://github.com/zcash/pasta *) + let a = Fq.zero + + let b = Fq.of_z (Z.of_int 5) + + let cofactor = Z.one + + (* x = -1 + y = 2 + *) + let bytes_generator = + Bytes.concat + Bytes.empty + [ + Fq.(to_bytes (negate (of_string "1"))); Fq.(to_bytes (of_string "2")); + ] + end) + +let from_affine_weierstrass_to_jacobian_weierstrass p = + Ec.from_affine_weierstrass_to_jacobian_weierstrass + (module Affine) + (module Jacobian) + p + +let from_affine_weierstrass_to_projective_weierstrass p = + Ec.from_affine_weierstrass_to_projective_weierstrass + (module Affine) + (module Projective) + p + +let from_jacobian_weierstrass_to_affine_weierstrass p = + Ec.from_jacobian_weierstrass_to_affine_weierstrass + (module Jacobian) + (module Affine) + p + +let from_projective_weierstrass_to_affine_weierstrass p = + Ec.from_projective_weierstrass_to_affine_weierstrass + (module Projective) + (module Affine) + p diff --git a/src/lib_mec/vesta.mli b/src/lib_mec/vesta.mli new file mode 100644 index 000000000000..0d06a0937537 --- /dev/null +++ b/src/lib_mec/vesta.mli @@ -0,0 +1,13 @@ +module Projective : Ec_sig.ProjectiveWeierstrassT + +module Affine : Ec_sig.AffineWeierstrassT + +module Jacobian : Ec_sig.JacobianWeierstrassT + +val from_affine_weierstrass_to_jacobian_weierstrass : Affine.t -> Jacobian.t + +val from_affine_weierstrass_to_projective_weierstrass : Affine.t -> Projective.t + +val from_jacobian_weierstrass_to_affine_weierstrass : Jacobian.t -> Affine.t + +val from_projective_weierstrass_to_affine_weierstrass : Projective.t -> Affine.t diff --git a/src/lib_mec/xor.ml b/src/lib_mec/xor.ml new file mode 100644 index 000000000000..e80e83dc97e4 --- /dev/null +++ b/src/lib_mec/xor.ml @@ -0,0 +1,65 @@ +module Nat = struct + include Nativeint + + let ( lxor ) = Nativeint.logxor +end + +module type BUFFER = sig + type t + + val length : t -> int + + val sub : t -> int -> int -> t + + val copy : t -> t + + val benat_to_cpu : t -> int -> nativeint + + val cpu_to_benat : t -> int -> nativeint -> unit +end + +let imin (a : int) (b : int) = if a < b then a else b + +module Make (B : BUFFER) = struct + let size_of_long = Sys.word_size / 8 + + (* XXX(dinosaure): I'm not sure about this code. May be we don't need the + first loop and the _optimization_ is irrelevant. *) + let xor_into src src_off dst dst_off n = + let n = ref n in + let i = ref 0 in + while !n >= size_of_long do + B.cpu_to_benat + dst + (dst_off + !i) + Nat.( + B.benat_to_cpu dst (dst_off + !i) + lxor B.benat_to_cpu src (src_off + !i)) ; + n := !n - size_of_long ; + i := !i + size_of_long + done ; + while !n > 0 do + B.cpu_to_benat + dst + (dst_off + !i) + Nat.( + B.benat_to_cpu src (src_off + !i) + lxor B.benat_to_cpu dst (dst_off + !i)) ; + incr i ; + decr n + done + + let xor_into a b n = + if n > imin (B.length a) (B.length b) then + raise (Invalid_argument "Baijiu.Xor.xor_inrot: buffers to small") + else xor_into a 0 b 0 n + + let xor a b = + let l = imin (B.length a) (B.length b) in + let r = B.copy (B.sub b 0 l) in + xor_into a r l ; + r +end + +module Bytes = Make (Digestif_by) +module Bigstring = Make (Digestif_bi) -- GitLab From 0b26bc7c203455b960c40c090b4589c41166736e Mon Sep 17 00:00:00 2001 From: Victor Dumitrescu Date: Thu, 9 Mar 2023 11:25:58 +0100 Subject: [PATCH 06/34] Lib_polynomial: import from cryptography/ocaml-polynomial --- .gitlab/ci/jobs/packaging/opam_package.yml | 7 + dune-project | 1 + manifest/main.ml | 20 +- opam/octez-polynomial.opam | 24 + opam/tezos-bls12-381-polynomial-internal.opam | 2 +- opam/virtual/octez-deps.opam | 1 - src/lib_bls12_381_polynomial/test/dune | 2 +- src/lib_polynomial/dune | 10 + src/lib_polynomial/polynomial.ml | 655 +++++++++++++ src/lib_polynomial/polynomial.mli | 216 +++++ src/lib_polynomial/test/dune | 20 + src/lib_polynomial/test/polynomial_pbt.ml | 874 ++++++++++++++++++ src/lib_polynomial/test/test_utils.ml | 25 + .../test/test_with_finite_field.ml | 809 ++++++++++++++++ src/lib_polynomial/utils.ml | 24 + 15 files changed, 2683 insertions(+), 7 deletions(-) create mode 100644 opam/octez-polynomial.opam create mode 100644 src/lib_polynomial/dune create mode 100644 src/lib_polynomial/polynomial.ml create mode 100644 src/lib_polynomial/polynomial.mli create mode 100644 src/lib_polynomial/test/dune create mode 100644 src/lib_polynomial/test/polynomial_pbt.ml create mode 100644 src/lib_polynomial/test/test_utils.ml create mode 100644 src/lib_polynomial/test/test_with_finite_field.ml create mode 100644 src/lib_polynomial/utils.ml diff --git a/.gitlab/ci/jobs/packaging/opam_package.yml b/.gitlab/ci/jobs/packaging/opam_package.yml index 2399c9823951..8dab51dcc580 100644 --- a/.gitlab/ci/jobs/packaging/opam_package.yml +++ b/.gitlab/ci/jobs/packaging/opam_package.yml @@ -300,6 +300,13 @@ opam:octez-node-config: variables: package: octez-node-config +opam:octez-polynomial: + extends: + - .opam_template + - .rules_template__trigger_opam_batch_7 + variables: + package: octez-polynomial + opam:octez-protocol-compiler: extends: - .opam_template diff --git a/dune-project b/dune-project index 90ff1f17844c..40cc671ed83b 100644 --- a/dune-project +++ b/dune-project @@ -21,6 +21,7 @@ (package (name octez-mec)) (package (name octez-node)) (package (name octez-node-config)) +(package (name octez-polynomial)) (package (name octez-protocol-compiler)) (package (name octez-proxy-server)) (package (name octez-signer)) diff --git a/manifest/main.ml b/manifest/main.ml index 9753568b0919..f457ca432077 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -252,9 +252,6 @@ let plompiler = let plonk = external_lib "tezos-plonk" V.(at_least "1.0.1" && less_than "2.0.0") -let polynomial = - external_lib "polynomial" V.(at_least "0.4.0" && less_than "0.5.0") - let ptime = external_lib ~js_compatible:true "ptime" V.(at_least "1.0.0") let ppx_import = external_lib "ppx_import" V.True @@ -1022,6 +1019,21 @@ let _octez_mec_tests = ~opam:"octez-mec" ~deps:[alcotest; octez_mec |> open_] +let octez_polynomial = + public_lib + "octez-polynomial" + ~path:"src/lib_polynomial" + ~internal_name:"polynomial" + ~synopsis:"Polynomials over finite fields" + ~deps:[bls12_381; bisect_ppx; zarith] + +let _octez_polynomial_tests = + tests + ["test_with_finite_field"; "test_utils"] + ~path:"src/lib_polynomial/test" + ~opam:"octez-polynomial" + ~deps:[bls12_381; octez_mec; alcotest; octez_polynomial] + let octez_bls12_381_polynomial_internal = public_lib "tezos-bls12-381-polynomial-internal" @@ -1066,7 +1078,7 @@ let _octez_bls12_381_polynomial_tests = [ alcotezt; qcheck_alcotest; - polynomial; + octez_polynomial; bisect_ppx; bls12_381; octez_bls12_381_polynomial_internal; diff --git a/opam/octez-polynomial.opam b/opam/octez-polynomial.opam new file mode 100644 index 000000000000..02da2b2aaecb --- /dev/null +++ b/opam/octez-polynomial.opam @@ -0,0 +1,24 @@ +# This file was automatically generated, do not edit. +# Edit file manifest/main.ml instead. +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: ["Tezos devteam"] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "3.0" } + "ocaml" { >= "4.14" } + "bls12-381" { >= "6.0.1" & < "6.1.0" } + "bisect_ppx" { >= "2.7.0" } + "zarith" { >= "1.12" & < "1.13" } + "octez-mec" {with-test} + "alcotest" { with-test & >= "1.5.0" } +] +build: [ + ["rm" "-r" "vendors"] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Polynomials over finite fields" diff --git a/opam/tezos-bls12-381-polynomial-internal.opam b/opam/tezos-bls12-381-polynomial-internal.opam index f0f91de7f031..a2900ac81084 100644 --- a/opam/tezos-bls12-381-polynomial-internal.opam +++ b/opam/tezos-bls12-381-polynomial-internal.opam @@ -16,7 +16,7 @@ depends: [ "tezt" { with-test & >= "3.0.0" } "octez-alcotezt" {with-test} "qcheck-alcotest" { with-test & >= "0.20" } - "polynomial" { with-test & >= "0.4.0" & < "0.5.0" } + "octez-polynomial" {with-test} "bisect_ppx" { with-test & >= "2.7.0" } ] build: [ diff --git a/opam/virtual/octez-deps.opam b/opam/virtual/octez-deps.opam index 465a20e6ac62..622115a0b321 100644 --- a/opam/virtual/octez-deps.opam +++ b/opam/virtual/octez-deps.opam @@ -63,7 +63,6 @@ depends: [ "ocp-ocamlres" { >= "0.4" } "ocplib-endian" "ometrics" { >= "0.2.1" } - "polynomial" { >= "0.4.0" & < "0.5.0" } "ppx_deriving" "ppx_expect" "ppx_import" diff --git a/src/lib_bls12_381_polynomial/test/dune b/src/lib_bls12_381_polynomial/test/dune index 495ef546db4c..fdbb0a6c8704 100644 --- a/src/lib_bls12_381_polynomial/test/dune +++ b/src/lib_bls12_381_polynomial/test/dune @@ -8,7 +8,7 @@ tezt.core octez-alcotezt qcheck-alcotest - polynomial + octez-polynomial bls12-381 tezos-bls12-381-polynomial-internal) (library_flags (:standard -linkall)) diff --git a/src/lib_polynomial/dune b/src/lib_polynomial/dune new file mode 100644 index 000000000000..07b36641ac1f --- /dev/null +++ b/src/lib_polynomial/dune @@ -0,0 +1,10 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name polynomial) + (public_name octez-polynomial) + (instrumentation (backend bisect_ppx)) + (libraries + bls12-381 + zarith)) diff --git a/src/lib_polynomial/polynomial.ml b/src/lib_polynomial/polynomial.ml new file mode 100644 index 000000000000..e2584fe587d1 --- /dev/null +++ b/src/lib_polynomial/polynomial.ml @@ -0,0 +1,655 @@ +(*****************************************************************************) +(* *) +(* Copyright (c) 2020-2021 Danny Willems *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +include Utils + +type natural_with_infinity = Natural of int | Infinity + +module type UNIVARIATE = sig + (** The type of the polynomial coefficients. Can be a field or more generally + a ring. For the moment, it is restricted to prime fields. + *) + type scalar + + (** Represents a polynomial *) + type t + + (** Returns the polynomial [P(X) = 0] *) + val zero : t + + (** Returns the polynomial [P(X) = 1] *) + val one : t + + (** Returns the degree of the polynomial *) + val degree : t -> natural_with_infinity + + val degree_int : t -> int + + (** [have_same_degree P Q] returns [true] if [P] and [Q] have the same + degree + *) + val have_same_degree : t -> t -> bool + + (* (\** [shift_by_n P n] multiplies [P] by [X^n]. For instance, + * [P(X) = a_{0} + a_{1} X + ... + a_{m} X^m] will be transformed in + * [a_{0} X^{n} + a_{1} X^{n + 1} + ... a_{m} X^{n + m}]. + * *\) + * val shift_by_n : t -> int -> t *) + + (** [get_dense_polynomial_coefficients P] returns the list of the + coefficients of P, including the null coefficients, in decreasing order + i.e. if P(X) = a_{0} + a_{1} X + ... + a_{n - 1} X^{n - 1}, the function + will return [a_{n - 1}, ..., a_{0}] + *) + val get_dense_polynomial_coefficients : t -> scalar list + + (** [get_dense_polynomial_coefficients_with_degree P] returns the list of the + coefficients of P with the degree as a tuple, including the null + coefficients, in decreasing order + i.e. if P(X) = a_{0} + a_{1} X + ... + a_{n - 1} X^{n - 1}, the function + will return [(a_{n - 1}, n -1), ..., (a_{0}, 0)]. + *) + val get_dense_polynomial_coefficients_with_degree : t -> (scalar * int) list + + (** [get_list_coefficients P] returns [(a_4,4), (a_2,2), (a_0,0)] if + P = a_4 X^4 + a_2 X^2 + a_0*) + val get_list_coefficients : t -> (scalar * int) list + + (** [evaluation P s] computes [P(s)]. Use Horner's method in O(n). *) + val evaluation : t -> scalar -> scalar + + (** [constants s] returns the constant polynomial [P(X) = s] *) + val constants : scalar -> t + + (** [add P Q] returns [P(X) + Q(X)] *) + val add : t -> t -> t + + (** [sub P Q] returns [P(X) - Q(X)] *) + val sub : t -> t -> t + + (** [mult_by_scalar s P] returns [s*P(X)] *) + val mult_by_scalar : scalar -> t -> t + + (** [is_null P] returns [true] iff [P(X) = 0] *) + val is_null : t -> bool + + (** [is_constant P] returns [true] iff [P(X) = s] for s scalar *) + val is_constant : t -> bool + + (** [opposite P] returns [-P(X)] *) + val opposite : t -> t + + (** [equal P Q] returns [true] iff [P(X) = Q(X)] on S *) + val equal : t -> t -> bool + + (** [of_coefficients [(x_0, y_0) ; (x_1, y_1); ... ; (x_n ; y_n)]] builds the + polynomial Σ(a_i * X^i) as a type [t]. + + By default, the null coefficients will be removed as the internal + representation of polynomials is sparsed. However, a version with null + coefficients can be generated if required. It is not recommended to use + this possibility as it breaks an invariant of the type [t]. + *) + val of_coefficients : (scalar * int) list -> t + + (** [lagrange_interpolation [(x_0, y_0) ; (x_1, y_1); ... ; (x_n ; y_n)]] + builds the unique polynomial P of degre n such that P(x_i) = y_i for i = 0...n + using the intermediate lagrange polynomials. [lagrange_interpolation_fft] can + be used in case of a FFT friendly scalar structure. It is supposed all x_i + are different. + *) + val lagrange_interpolation : (scalar * scalar) list -> t + + (** [even_polynomial P] returns the polynomial P_even containing only the even + coefficients of P *) + val even_polynomial : t -> t + + (** [odd_polynomial P] returns the polynomial P_odd containing only the odd + coefficients of P *) + val odd_polynomial : t -> t + + (** [evaluate_fft_imperative ~domain P] evaluates P on the points given in the [domain]. + The domain should be of the form [g^{i}] where [g] is a principal root of + unity. If the domain is of size [n], [g] must be a [n]-th principal root + of unity. + The degree of [P] can be smaller than the domain size. Larger polynomials + can also be used but the implementation is not the most memory efficient + yet and must be improved. The + complexity is in [O(n log(m))] where [n] is the domain size and [m] the + degree of the polynomial. When [m] is smaller than [n], the polynomial is + padded with zeroes to reach [n] coefficients. + The resulting list contains the evaluation points + [P(1), P(w), ..., P(w^{n - 1})]. + *) + val evaluation_fft : domain:scalar array -> t -> scalar list + + (** [generate_random_polynomial n] returns a random polynomial of degree [n] *) + val generate_random_polynomial : natural_with_infinity -> t + + (** [get_highest_coefficient P] where [P(X) = a_n X^n + ... a_0] returns [a_n] *) + val get_highest_coefficient : t -> scalar + + (** [interpolation_fft ~domain [y_{0} ; y_{1} ; + ... y_{n}]] computes the interpolation at the points [y_{0}, ..., y_{n}] + using FFT Cookey Tukey. + The domain should be of the form [g^{i}] where [g] is a principal root of + unity. If the domain is of size [n], [g] must be a [n]-th principal root + of unity. + The domain size must be exactly the same than the number of points. The + complexity is [O(n log(n))] where [n] is the domain size. + *) + val interpolation_fft : domain:scalar array -> scalar list -> t + + (** [polynomial_multiplication P Q] computes the + product P(X).Q(X) *) + val polynomial_multiplication : t -> t -> t + + (** [polynomial_multiplication_fft ~domain P Q] computes the + product [P(X).Q(X)] using FFT. + The domain should be of the form [g^{i}] where [g] is a principal root of + unity. If the domain is of size [n], [g] must be a [n]-th principal root + of unity. + The degrees of [P] and [Q] can be different. The only condition is + [degree P + degree Q] should be smaller or equal to [n - 2] (i.e. the domain should + be big enough to compute [n - 1] points of [P * Q]). + *) + val polynomial_multiplication_fft : domain:scalar array -> t -> t -> t + + val euclidian_division_opt : t -> t -> (t * t) option + + (** [extended_euclide P S] returns (GCD, U, V) the greatest common divisor of [P] and [S] + and the Bezout's coefficient: + [U P + V S = GCD] and [GCD] greatest coefficient is one + *) + val extended_euclide : t -> t -> t * t * t + + (** Infix operator for [equal] *) + val ( = ) : t -> t -> bool + + (** Infix operator for [add] *) + val ( + ) : t -> t -> t + + (** Infix operator for [polynomial_multiplication] *) + val ( * ) : t -> t -> t + + (** Infix operator for [sub] *) + val ( - ) : t -> t -> t + + val to_string : t -> string +end + +module DomainEvaluation (R : Bls12_381.Ff_sig.PRIME) = struct + type t = {size : int; generator : R.t; domain_values : R.t array} + + let generate_domain generator n = + let rec aux previous acc i = + if i = n then List.rev acc + else + let current = R.mul previous generator in + aux current (current :: acc) (i + 1) + in + Array.of_list @@ aux R.one [R.one] 1 + + let generate size generator = + {size; generator; domain_values = generate_domain generator size} + + let _size d = d.size + + let _generator d = d.generator + + let domain_values d = d.domain_values +end + +(* TODO: Functions should use DomainEvaluation *) +let generate_evaluation_domain (type a) + (module Fp : Bls12_381.Ff_sig.PRIME with type t = a) size (generator : a) = + let module D = DomainEvaluation (Fp) in + let g = D.generate size generator in + D.domain_values g + +(* TODO: this function should be part of DomainEvaluation. However, for the + moment, functions do not use this representation *) +let inverse_domain_values domain = + let length_domain = Array.length domain in + Array.init length_domain (fun i -> + if i = 0 then domain.(i) else domain.(length_domain - i)) + +module MakeUnivariate (R : Bls12_381.Ff_sig.PRIME) = struct + type scalar = R.t + + (* We encode the polynomials as a list with decreasing degree. + Invariants to respect for the type: + - all coefficients are non null. + - [a_n * X^n + ... a_1 X + a0] is encoded as [a_n ; ... ; a_1 ; a_0] with [a_i] + non zero for all [i], i.e. the monomials are given in decreasing order. + - the zero polynomial is represented as the empty list. + *) + type t = (scalar * int) list + + let degree p = + match p with + | [] -> Infinity + | [(e, 0)] -> if R.is_zero e then Infinity else Natural 0 + | _ as l -> Natural (snd (List.hd l)) + + let degree_int p = match degree p with Infinity -> -1 | Natural n -> n + + let have_same_degree p q = degree p = degree q + + (* let shift_by_n p n = + * assert (n >= 1) ; + * List.map (fun (c, e) -> (c, e + n)) p *) + + let zero = [] + + let one = [(R.one, 0)] + + let constants c = if R.eq c R.zero then [] else [(c, 0)] + + let is_null p = match p with [] -> true | _ -> false + + let is_constant p = + match p with + | [] -> true + | l -> + if List.compare_length_with l 1 > 0 then false + else + let _, p = List.hd l in + if p = 0 then true else false + + let of_coefficients l = + (* check if the powers are all positive *) + assert (List.for_all (fun (_e, power) -> power >= 0) l) ; + (* Remove null coefficients *) + let l = List.filter (fun (e, _power) -> not (R.is_zero e)) l in + (* sort by the power, higher power first *) + let l = + List.fast_sort + (fun (_e1, power1) (_e2, power2) -> Int.sub power2 power1) + l + in + l + + let add p1 p2 = + let rec inner acc l1 l2 = + match (l1, l2) with + | [], l | l, [] -> List.rev_append acc l + | l1, l2 -> + let e1, p1 = List.hd l1 in + let e2, p2 = List.hd l2 in + if p1 = p2 && R.is_zero (R.add e1 e2) then + inner acc (List.tl l1) (List.tl l2) + else if p1 = p2 then + inner ((R.add e1 e2, p1) :: acc) (List.tl l1) (List.tl l2) + else if p1 > p2 then inner ((e1, p1) :: acc) (List.tl l1) l2 + else inner ((e2, p2) :: acc) l1 (List.tl l2) + in + let l = inner [] p1 p2 in + of_coefficients l + + let mult_by_scalar a p = + List.filter_map + (fun (coef, power) -> + let c = R.mul coef a in + if R.is_zero c then None else Some (c, power)) + p + + let opposite poly = List.(rev (rev_map (fun (a, i) -> (R.negate a, i)) poly)) + + let sub p1 p2 = + let rec inner acc l1 l2 = + match (l1, l2) with + | [], l2 -> List.rev_append acc (opposite l2) + | l1, [] -> List.rev_append acc l1 + | l1, l2 -> + let e1, p1 = List.hd l1 in + let e2, p2 = List.hd l2 in + if p1 = p2 && R.is_zero (R.sub e1 e2) then + inner acc (List.tl l1) (List.tl l2) + else if p1 = p2 then + inner ((R.sub e1 e2, p1) :: acc) (List.tl l1) (List.tl l2) + else if p1 > p2 then inner ((e1, p1) :: acc) (List.tl l1) l2 + else inner ((R.negate e2, p2) :: acc) l1 (List.tl l2) + in + let l = inner [] p1 p2 in + of_coefficients l + + let equal p1 p2 = + if List.compare_lengths p1 p2 != 0 then false + else List.for_all2 (fun (e1, n1) (e2, n2) -> n1 = n2 && R.eq e1 e2) p1 p2 + + let get_list_coefficients p = p + + let get_dense_polynomial_coefficients polynomial = + match polynomial with + | [] -> [R.zero] + | l -> + let l = List.rev l in + let rec to_dense acc current_i l = + match l with + | [] -> acc + | (e, n) :: xs -> + if n = current_i then to_dense (e :: acc) (current_i + 1) xs + else to_dense (R.zero :: acc) (current_i + 1) l + in + to_dense [] 0 l + + let get_dense_polynomial_coefficients_with_degree polynomial = + let n = degree_int polynomial in + if n = -1 then [(R.zero, 0)] + else + let h_list = get_dense_polynomial_coefficients polynomial in + let ffold (acc, i) a = ((a, i) :: acc, i - 1) in + let res, _ = List.fold_left ffold ([], n) h_list in + List.rev res + + let evaluation polynomial point = + (* optimized_pow is used instead of Scalar.pow because Scalar.pow makes + evaluation slower than the standard Horner algorithm when dif_degree <= 4 is + involved. + TODO: use memoisation + *) + let n = degree_int polynomial in + let optimized_pow x = function + | 0 -> R.one + | 1 -> x + | 2 -> R.square x + | 3 -> R.(x * square x) + | 4 -> R.(square (square x)) + | n -> R.pow x (Z.of_int n) + in + let aux (acc, prec_i) (a, i) = + let dif_degree = prec_i - i in + (R.((acc * optimized_pow point dif_degree) + a), i) + in + let res, last_degree = List.fold_left aux (R.zero, n) polynomial in + R.(res * optimized_pow point last_degree) + + let assert_no_duplicate_point points = + let points = List.map fst points in + let points_uniq = + List.sort_uniq (fun e1 e2 -> if R.eq e1 e2 then 0 else -1) points + in + assert (List.compare_lengths points points_uniq = 0) + + let intermediate_lagrange_interpolation x_i i xs = + List.fold_left + (fun acc (j, x_j) -> + if i = j then acc + else + match acc with + | [] -> [] + | acc -> + let acc_1 = List.map (fun (e, p) -> (e, p + 1)) acc in + let acc_2 = mult_by_scalar x_j (of_coefficients acc) in + let acc = add acc_1 (opposite acc_2) in + let scalar = R.inverse_exn R.(x_i + R.negate x_j) in + let acc_final = mult_by_scalar scalar acc in + acc_final) + (constants R.one) + xs + + let lagrange_interpolation points = + assert_no_duplicate_point points ; + let indexed_points = List.mapi (fun i (x_i, y_i) -> (i, x_i, y_i)) points in + let evaluated_at = List.mapi (fun i (x_i, _) -> (i, x_i)) points in + List.fold_left + (fun acc (i, x_i, y_i) -> + let l_i = intermediate_lagrange_interpolation x_i i evaluated_at in + add acc (mult_by_scalar y_i l_i)) + [] + indexed_points + + let even_polynomial polynomial = + match polynomial with + | [] -> [] + | l -> List.filter (fun (_e, n) -> n mod 2 = 0) l + + let odd_polynomial polynomial = + match polynomial with + | [] -> [] + | l -> List.filter (fun (_e, n) -> n mod 2 = 1) l + + (* assumes that len(domain) = len(output) *) + let evaluation_fft_in_place ~domain output = + let n = Array.length output in + let logn = Z.log2 (Z.of_int n) in + let m = ref 1 in + for _i = 0 to logn - 1 do + let exponent = n / (2 * !m) in + let k = ref 0 in + while !k < n do + for j = 0 to !m - 1 do + let w = domain.(exponent * j) in + (* odd *) + let right = R.mul output.(!k + j + !m) w in + output.(!k + j + !m) <- R.sub output.(!k + j) right ; + output.(!k + j) <- R.add output.(!k + j) right + done ; + k := !k + (!m * 2) + done ; + m := !m * 2 + done ; + () + + let evaluation_fft ~domain polynomial = + let open Utils in + let n = degree_int polynomial + 1 in + let d = Array.length domain in + let logd = Z.(log2 (of_int d)) in + if is_null polynomial then List.init d (fun _ -> R.zero) + else + let dense_polynomial = get_dense_polynomial_coefficients polynomial in + let output = Array.of_list (List.rev dense_polynomial) in + let output = + (* if the polynomial is too small, we pad with zeroes *) + if d > n then ( + let output = Array.append output (Array.make (d - n) R.zero) in + reorg_coefficients d logd output ; + output + (* if the polynomial is larger, we evaluate on the sub polynomials *)) + else if n > d then ( + let next_power = next_power_of_two n in + let log_next_power = Z.log2 (Z.of_int next_power) in + let output = + Array.append output (Array.make (next_power - n) R.zero) + in + let n = next_power in + reorg_coefficients next_power log_next_power output ; + Array.init d (fun i -> + let poly = Array.sub output (i * (n / d)) (n / d) in + let poly = + List.init (n / d) (fun i -> + (poly.((n / d) - i - 1), (n / d) - i - 1)) + in + let poly = of_coefficients poly in + (* we may sum *) + evaluation poly domain.(0))) + else ( + reorg_coefficients d logd output ; + output) + in + evaluation_fft_in_place ~domain output ; + Array.to_list output + + let generate_random_polynomial degree = + let rec random_non_null () = + let r = R.random () in + if R.is_zero r then random_non_null () else r + in + match degree with + | Infinity -> [] + | Natural n when n >= 0 -> + let coefficients = List.init n (fun _i -> R.random ()) in + let coefficients = + (random_non_null (), n) + :: List.mapi (fun i c -> (c, n - i - 1)) coefficients + in + of_coefficients coefficients + | _ -> failwith "The degree must be positive" + + let get_highest_coefficient polynomial = + match polynomial with [] -> R.zero | (c, _e) :: _ -> c + + let interpolation_fft ~domain points = + let n = Array.length domain in + assert (List.compare_length_with points n = 0) ; + let n_z = Z.of_int n in + let logn = Z.log2 n_z in + (* Points are in a list of size N. Let's define + points = [y_0, y_1, ... y_(N - 1)] + We build the polynomial [P(X) = y_(N - 1) X^(N - 1) + ... + y_1 X * y_0]. + The resulting value is not necessarily of type [t] because it might not + respect the sparse representation as there might be some null + coefficients [y_i]. However, [evaluation_fft] gets the dense + polynomial in its body. + If all the points are zero, mult_by_scalar will take care of keeping the + invariant, see below. + *) + let inverse_domain = inverse_domain_values domain in + let inverse_fft = Array.of_list points in + (* We evaluate the resulting polynomial on the domain *) + Utils.reorg_coefficients n logn inverse_fft ; + evaluation_fft_in_place ~domain:inverse_domain inverse_fft ; + let polynomial, _ = + Array.fold_left + (fun (acc, i) p -> ((p, i) :: acc, i + 1)) + ([], 0) + inverse_fft + in + (* mult_by_scalar does use filter_map removing all the zero coefficients. + Therefore, we keep the invariant consisting of representing the zero + polynomial with an empty list + *) + mult_by_scalar (R.inverse_exn (R.of_z n_z)) polynomial + + let polynomial_multiplication p q = + let mul_by_monom (scalar, int) p = + List.map (fun (scalar_2, int_2) -> (R.mul scalar scalar_2, int + int_2)) p + in + List.fold_left (fun acc monom -> add acc (mul_by_monom monom q)) zero p + + let polynomial_multiplication_fft ~domain p q = + if is_null p || is_null q then zero + else + (* Evaluate P on the domain -> eval_p contains N points where N is the + domain size. The resulting list contains the points P(w_i) where w_i + \in D + *) + let eval_p = evaluation_fft ~domain p in + (* Evaluate Q on the domain -> eval_q contains N points where N is the + domain size. The resulting list contains the points Q(w_i) where w_i + \in D. + *) + let eval_q = evaluation_fft ~domain q in + (* Contains N points, resulting of p(w_i) * q(w_i) where w_i \in D *) + let eval_pq = + List.(rev (rev_map2 (fun a b -> R.mul a b) eval_p eval_q)) + in + interpolation_fft ~domain eval_pq + + let euclidian_division_opt a b = + if is_null b then None + else + let deg_b = degree_int b in + let highest_coeff_b = get_highest_coefficient b in + let rec aux q r = + if degree_int r < deg_b then Some (q, r) + else + let diff_degree = degree_int r - deg_b in + let rescale_factor = + R.(get_highest_coefficient r / highest_coeff_b) + in + let to_sub = + polynomial_multiplication b [(rescale_factor, diff_degree)] + in + aux (add q [(rescale_factor, diff_degree)]) (sub r to_sub) + in + aux zero a + + let extended_euclide polynomial_1 polynomial_2 = + let n_1 = degree_int polynomial_1 and n_2 = degree_int polynomial_2 in + if n_1 = -1 && n_2 = -1 then (zero, zero, zero) + else if n_1 = -1 then + let rescale_factor = + R.inverse_exn @@ get_highest_coefficient polynomial_2 + in + ( mult_by_scalar rescale_factor polynomial_2, + zero, + mult_by_scalar rescale_factor one ) + else if n_2 = -1 then + let rescale_factor = + R.inverse_exn @@ get_highest_coefficient polynomial_1 + in + + ( mult_by_scalar rescale_factor polynomial_1, + mult_by_scalar rescale_factor one, + zero ) + else + let rec aux poly_1 u_1 v_1 poly_2 u_2 v_2 = + let q, r = euclidian_division_opt poly_1 poly_2 |> Option.get in + if is_null r then (poly_2, u_2, v_2) + else + aux + poly_2 + u_2 + v_2 + r + (sub u_1 (polynomial_multiplication q u_2)) + (sub v_1 (polynomial_multiplication q v_2)) + in + let gcd, u, v = aux polynomial_1 one zero polynomial_2 zero one in + let rescale_factor = R.inverse_exn @@ get_highest_coefficient gcd in + ( mult_by_scalar rescale_factor gcd, + mult_by_scalar rescale_factor u, + mult_by_scalar rescale_factor v ) + + let to_string p = + let rec inner l = + match l with + | [] -> "0" + | [(e, p)] -> + if R.is_one e && p = 1 then Printf.sprintf "X" + else if p = 1 then Printf.sprintf "%sX" (R.to_string e) + else if p = 0 then Printf.sprintf "%s" (R.to_string e) + else if R.is_one e then Printf.sprintf "X^%d" p + else Printf.sprintf "%s X^%d" (R.to_string e) p + | (e, p) :: tail -> + if R.is_one e && p = 1 then Printf.sprintf "X + %s" (inner tail) + else if p = 1 then + Printf.sprintf "%sX + %s" (R.to_string e) (inner tail) + else if p = 0 then Printf.sprintf "%s" (R.to_string e) + else if R.is_one e then Printf.sprintf "X^%d + %s" p (inner tail) + else Printf.sprintf "%s X^%d + %s" (R.to_string e) p (inner tail) + in + inner p + + let ( = ) = equal + + let ( + ) = add + + let ( * ) = polynomial_multiplication + + let ( - ) = sub +end diff --git a/src/lib_polynomial/polynomial.mli b/src/lib_polynomial/polynomial.mli new file mode 100644 index 000000000000..fd0afd643d39 --- /dev/null +++ b/src/lib_polynomial/polynomial.mli @@ -0,0 +1,216 @@ +(*****************************************************************************) +(* *) +(* Copyright (c) 2020-2021 Danny Willems *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type natural_with_infinity = Natural of int | Infinity + +module type UNIVARIATE = sig + (** The type of the polynomial coefficients. Can be a field or more generally + a ring. For the moment, it is restricted to prime fields. + *) + type scalar + + (** Represents a polynomial *) + type t + + (** Returns the polynomial [P(X) = 0] *) + val zero : t + + (** Returns the polynomial [P(X) = 1] *) + val one : t + + (** Returns the degree of the polynomial *) + val degree : t -> natural_with_infinity + + val degree_int : t -> int + + (** [have_same_degree P Q] returns [true] if [P] and [Q] have the same + degree + *) + val have_same_degree : t -> t -> bool + + (* (\** [shift_by_n P n] multiplies [P] by [X^n]. For instance, + * [P(X) = a_{0} + a_{1} X + ... + a_{m} X^m] will be transformed in + * [a_{0} X^{n} + a_{1} X^{n + 1} + ... a_{m} X^{n + m}]. + * *\) + * val shift_by_n : t -> int -> t *) + + (** [get_dense_polynomial_coefficients P] returns the list of the + coefficients of P, including the null coefficients, in decreasing order + i.e. if P(X) = a_{0} + a_{1} X + ... + a_{n - 1} X^{n - 1}, the function + will return [a_{n - 1}, ..., a_{0}] + *) + val get_dense_polynomial_coefficients : t -> scalar list + + (** [get_dense_polynomial_coefficients_with_degree P] returns the list of the + coefficients of P with the degree as a tuple, including the null + coefficients, in decreasing order + i.e. if P(X) = a_{0} + a_{1} X + ... + a_{n - 1} X^{n - 1}, the function + will return [(a_{n - 1}, n -1), ..., (a_{0}, 0)]. + *) + val get_dense_polynomial_coefficients_with_degree : t -> (scalar * int) list + + (** [get_list_coefficients P] returns [(a_4,4), (a_2,2), (a_0,0)] if + P = a_4 X^4 + a_2 X^2 + a_0*) + val get_list_coefficients : t -> (scalar * int) list + + (** [evaluation P s] computes [P(s)]. Use Horner's method in O(n). *) + val evaluation : t -> scalar -> scalar + + (** [constants s] returns the constant polynomial [P(X) = s] *) + val constants : scalar -> t + + (** [add P Q] returns [P(X) + Q(X)] *) + val add : t -> t -> t + + (** [sub P Q] returns [P(X) - Q(X)] *) + val sub : t -> t -> t + + (** [mult_by_scalar s P] returns [s*P(X)] *) + val mult_by_scalar : scalar -> t -> t + + (** [is_null P] returns [true] iff [P(X) = 0] *) + val is_null : t -> bool + + (** [is_constant P] returns [true] iff [P(X) = s] for s scalar *) + val is_constant : t -> bool + + (** [opposite P] returns [-P(X)] *) + val opposite : t -> t + + (** [equal P Q] returns [true] iff [P(X) = Q(X)] on S *) + val equal : t -> t -> bool + + (** [of_coefficients [(x_0, y_0) ; (x_1, y_1); ... ; (x_n ; y_n)]] builds the + polynomial Σ(a_i * X^i) as a type [t]. + + By default, the null coefficients will be removed as the internal + representation of polynomials is sparsed. However, a version with null + coefficients can be generated if required. It is not recommended to use + this possibility as it breaks an invariant of the type [t]. + *) + val of_coefficients : (scalar * int) list -> t + + (** [lagrange_interpolation [(x_0, y_0) ; (x_1, y_1); ... ; (x_n ; y_n)]] + builds the unique polynomial P of degre n such that P(x_i) = y_i for i = 0...n + using the intermediate lagrange polynomials. [lagrange_interpolation_fft] can + be used in case of a FFT friendly scalar structure. It is supposed all x_i + are different. + *) + val lagrange_interpolation : (scalar * scalar) list -> t + + (** [even_polynomial P] returns the polynomial P_even containing only the even + coefficients of P *) + val even_polynomial : t -> t + + (** [odd_polynomial P] returns the polynomial P_odd containing only the odd + coefficients of P *) + val odd_polynomial : t -> t + + (** [evaluate_fft_imperative ~domain P] evaluates P on the points given in the [domain]. + The domain should be of the form [g^{i}] where [g] is a principal root of + unity. If the domain is of size [n], [g] must be a [n]-th principal root + of unity. + The degree of [P] can be smaller than the domain size. Larger polynomials + can also be used but the implementation is not the most memory efficient + yet and must be improved. The + complexity is in [O(n log(m))] where [n] is the domain size and [m] the + degree of the polynomial. When [m] is smaller than [n], the polynomial is + padded with zeroes to reach [n] coefficients. + The resulting list contains the evaluation points + [P(1), P(w), ..., P(w^{n - 1})]. + *) + val evaluation_fft : domain:scalar array -> t -> scalar list + + (** [generate_random_polynomial n] returns a random polynomial of degree [n] *) + val generate_random_polynomial : natural_with_infinity -> t + + (** [get_highest_coefficient P] where [P(X) = a_n X^n + ... a_0] returns [a_n] *) + val get_highest_coefficient : t -> scalar + + (** [interpolation_fft ~domain [y_{0} ; y_{1} ; + ... y_{n}]] computes the interpolation at the points [y_{0}, ..., y_{n}] + using FFT Cookey Tukey. + The domain should be of the form [g^{i}] where [g] is a principal root of + unity. If the domain is of size [n], [g] must be a [n]-th principal root + of unity. + The domain size must be exactly the same than the number of points. The + complexity is [O(n log(n))] where [n] is the domain size. + *) + val interpolation_fft : domain:scalar array -> scalar list -> t + + (** [polynomial_multiplication P Q] computes the + product P(X).Q(X) *) + val polynomial_multiplication : t -> t -> t + + (** [polynomial_multiplication_fft ~domain P Q] computes the + product [P(X).Q(X)] using FFT. + The domain should be of the form [g^{i}] where [g] is a principal root of + unity. If the domain is of size [n], [g] must be a [n]-th principal root + of unity. + The degrees of [P] and [Q] can be different. The only condition is + [degree P + degree Q] should be smaller or equal to [n - 2] (i.e. the domain should + be big enough to compute [n - 1] points of [P * Q]). + *) + val polynomial_multiplication_fft : domain:scalar array -> t -> t -> t + + val euclidian_division_opt : t -> t -> (t * t) option + + (** [extended_euclide P S] returns (GCD, U, V) the greatest common divisor of [P] and [S] + and the Bezout's coefficient: + [U P + V S = GCD] and [GCD] greatest coefficient is one + *) + val extended_euclide : t -> t -> t * t * t + + (** Infix operator for [equal] *) + val ( = ) : t -> t -> bool + + (** Infix operator for [add] *) + val ( + ) : t -> t -> t + + (** Infix operator for [polynomial_multiplication] *) + val ( * ) : t -> t -> t + + (** Infix operator for [sub] *) + val ( - ) : t -> t -> t + + val to_string : t -> string +end + +(** [generate_evaluation_domain (module Fp) n generator] generates the domain + [g^{i}] to be used in FFT related algorithms. [generator] must be a [n]-th + principal root of unity in the finite field [Fp] *) +val generate_evaluation_domain : + (module Bls12_381.Ff_sig.PRIME with type t = 'a) -> int -> 'a -> 'a array + +(** [Make(Fp)] builds a module of type [T] where the coefficients are in the prime field Fp *) +module MakeUnivariate : functor (R : Bls12_381.Ff_sig.PRIME) -> + UNIVARIATE with type scalar = R.t + +module Utils : sig + val bitreverse : int -> int -> int + + val reorg_coefficients : int -> int -> 'a array -> unit + + val next_power_of_two : int -> int +end diff --git a/src/lib_polynomial/test/dune b/src/lib_polynomial/test/dune new file mode 100644 index 000000000000..894e92710224 --- /dev/null +++ b/src/lib_polynomial/test/dune @@ -0,0 +1,20 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(executables + (names test_with_finite_field test_utils) + (libraries + bls12-381 + octez-mec + alcotest + octez-polynomial)) + +(rule + (alias runtest) + (package octez-polynomial) + (action (run %{dep:./test_with_finite_field.exe}))) + +(rule + (alias runtest) + (package octez-polynomial) + (action (run %{dep:./test_utils.exe}))) diff --git a/src/lib_polynomial/test/polynomial_pbt.ml b/src/lib_polynomial/test/polynomial_pbt.ml new file mode 100644 index 000000000000..32cc3cd4bb86 --- /dev/null +++ b/src/lib_polynomial/test/polynomial_pbt.ml @@ -0,0 +1,874 @@ +(*****************************************************************************) +(* *) +(* Copyright (c) 2020-2021 Danny Willems *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let rec repeat n f = + if n <= 0 then + let f () = () in + f + else ( + f () ; + repeat (n - 1) f) + +let rec non_null_int bound = + let r = Random.int bound in + if r = 0 then non_null_int bound else r + +module MakeTestConstant + (Scalar : Bls12_381.Ff_sig.PRIME) + (Poly : Polynomial.UNIVARIATE with type scalar = Scalar.t) = +struct + let test_zero () = assert (Poly.is_constant Poly.zero) + + let test_random () = + assert (Poly.is_constant (Poly.constants (Scalar.random ()))) + + let test_random_polynomials () = + assert ( + not + (Poly.is_constant + (Poly.generate_random_polynomial + (Polynomial.Natural (non_null_int 100))))) + + let get_tests () = + let open Alcotest in + ( Printf.sprintf + "Tests for constant polynomials, field order = %s" + (Z.to_string Scalar.order), + [ + test_case "zero polynomial is constant" `Quick test_zero; + test_case "Constant random value" `Quick (repeat 100 test_random); + test_case + "Non constant polynomial" + `Quick + (repeat 100 test_random_polynomials); + ] ) +end + +module MakeTestDegree + (Scalar : Bls12_381.Ff_sig.PRIME) + (Poly : Polynomial.UNIVARIATE with type scalar = Scalar.t) = +struct + let test_degree_zero_is_infinity () = + assert (Poly.degree Poly.zero = Polynomial.Infinity) + + let test_degree_of_constants_is_one () = + assert ( + Poly.degree (Poly.constants (Scalar.random ())) = Polynomial.Infinity) + + let test_degree_int_test_vectors () = + let vectors = + [ + (Poly.zero, -1); + (Poly.generate_random_polynomial (Polynomial.Natural 10), 10); + (Poly.generate_random_polynomial (Polynomial.Natural 100), 100); + (Poly.generate_random_polynomial (Polynomial.Natural 0), 0); + (Poly.generate_random_polynomial (Polynomial.Natural 42), 42); + ] + in + List.iter + (fun (p, expected_result) -> assert (Poly.degree_int p = expected_result)) + vectors + + let test_have_same_degree () = + let rec generate_random_non_null () = + let r = Scalar.random () in + if Scalar.is_zero r then generate_random_non_null () else r + in + let random_non_null = generate_random_non_null () in + let test_vectors = + [ + (Poly.zero, Poly.zero, true); + (Poly.zero, Poly.constants random_non_null, false); + (Poly.constants random_non_null, Poly.zero, false); + (Poly.constants random_non_null, Poly.constants random_non_null, true); + ( Poly.generate_random_polynomial (Polynomial.Natural 10), + Poly.generate_random_polynomial (Polynomial.Natural 10), + true ); + ( Poly.generate_random_polynomial (Polynomial.Natural 10), + Poly.zero, + false ); + ( Poly.generate_random_polynomial (Polynomial.Natural 10), + Poly.constants (Scalar.random ()), + false ); + ( Poly.generate_random_polynomial (Polynomial.Natural 10), + Poly.generate_random_polynomial (Polynomial.Natural 20), + false ); + ( Poly.generate_random_polynomial (Polynomial.Natural 20), + Poly.generate_random_polynomial (Polynomial.Natural 10), + false ); + ] + in + List.iter + (fun (p, q, expected_result) -> + assert (Poly.have_same_degree p q = expected_result)) + test_vectors + + let get_tests () = + let open Alcotest in + ( Printf.sprintf + "Tests on degrees, field order = %s" + (Z.to_string Scalar.order), + [ + test_case + "degree of zero is infinity" + `Quick + test_degree_zero_is_infinity; + test_case + "degree of constants is one" + `Quick + test_degree_zero_is_infinity; + test_case "degree int test vectors" `Quick test_degree_int_test_vectors; + test_case "have same degree" `Quick test_have_same_degree; + ] ) +end + +module MakeTestEvaluation + (Scalar : Bls12_381.Ff_sig.PRIME) + (Poly : Polynomial.UNIVARIATE with type scalar = Scalar.t) = +struct + let test_eval_random_point_zero_polynomial () = + assert (Scalar.is_zero (Poly.evaluation Poly.zero (Scalar.random ()))) + + let test_eval_at_zero_of_zero_polynomial () = + assert (Scalar.is_zero (Poly.evaluation Poly.zero Scalar.zero)) + + let test_eval_at_zero_point_of_random_constant_polynomial () = + let constant = Scalar.random () in + assert ( + Scalar.eq (Poly.evaluation (Poly.constants constant) Scalar.zero) constant) + + let test_eval_random_point_constant_polynomial () = + let constant = Scalar.random () in + assert ( + Scalar.eq + (Poly.evaluation (Poly.constants constant) (Scalar.random ())) + constant) + + let test_eval_x_to_random_point () = + let p = Scalar.random () in + assert ( + Scalar.eq (Poly.evaluation (Poly.of_coefficients [(Scalar.one, 1)]) p) p) + + let get_tests () = + let open Alcotest in + ( Printf.sprintf + "Test evaluation, field order = %s" + (Z.to_string Scalar.order), + [ + test_case + "evaluation at any point of the zero polynomial" + `Quick + (repeat 100 test_eval_random_point_zero_polynomial); + test_case + "evaluation at any point of a random constant polynomial" + `Quick + (repeat 100 test_eval_random_point_constant_polynomial); + test_case + "evaluation at zero of a random constant polynomial" + `Quick + (repeat 100 test_eval_at_zero_point_of_random_constant_polynomial); + test_case + "evaluation at zero of the zero polynomial" + `Quick + (repeat 100 test_eval_at_zero_of_zero_polynomial); + test_case + "evaluation at any point of the polynomial X" + `Quick + (repeat 100 test_eval_x_to_random_point); + ] ) +end + +module MakeTestLagrangeInterpolation + (Scalar : Bls12_381.Ff_sig.PRIME) + (Poly : Polynomial.UNIVARIATE with type scalar = Scalar.t) = +struct + let rec test_with_random_number_of_points () = + let rec generate_evaluation_points i n acc = + if i < n then + let r = Scalar.random () in + if List.mem r acc then generate_evaluation_points i n acc + else generate_evaluation_points (i + 1) n (r :: acc) + else acc + in + let n = Random.int 30 in + if n <= 0 then test_with_random_number_of_points () + else + let points = + List.combine + (generate_evaluation_points 0 n []) + (List.init n (fun _i -> Scalar.random ())) + in + let interpolated_polynomial = Poly.lagrange_interpolation points in + match Poly.degree interpolated_polynomial with + | Polynomial.Infinity -> + if + List.length points = 1 + && + let _, x = List.hd points in + Scalar.is_zero x + then assert true + else assert false + | Natural n -> + assert (n <= List.length points - 1) ; + List.iter + (fun (x, y) -> + assert (Scalar.eq (Poly.evaluation interpolated_polynomial x) y)) + points + + let get_tests () = + let open Alcotest in + ( Printf.sprintf + "Test lagrange interpolation, prime field order %s" + (Z.to_string Scalar.order), + [ + test_case + "test random number of points" + `Quick + (repeat 10 test_with_random_number_of_points); + ] ) +end + +module MakeTestEuclidianDivision + (Scalar : Bls12_381.Ff_sig.PRIME) + (Poly : Polynomial.UNIVARIATE with type scalar = Scalar.t) = +struct + let test_verify_equality_with_random () = + let a = Poly.generate_random_polynomial (Polynomial.Natural 100) in + let b = Poly.generate_random_polynomial (Polynomial.Natural 50) in + let res = Poly.euclidian_division_opt a b in + match res with + | None -> assert false + | Some (q, r) -> + assert (Poly.equal a (Poly.add (Poly.polynomial_multiplication b q) r)) + + let test_verify_equality_with_random_divided_by_constant () = + let a = + Poly.generate_random_polynomial (Polynomial.Natural (Random.int 1000)) + in + let b = Poly.generate_random_polynomial (Polynomial.Natural 0) in + let res = Poly.euclidian_division_opt a b in + match res with + | None -> assert false + | Some (q, r) -> + assert (Poly.equal a (Poly.add (Poly.polynomial_multiplication b q) r)) + + let rec test_with_constants () = + let a = Scalar.random () in + let b = Scalar.random () in + if Scalar.is_zero b || Scalar.is_zero a then test_with_constants () + else + let res = + Poly.euclidian_division_opt (Poly.constants a) (Poly.constants b) + in + match res with + | None -> assert false + | Some (q, r) -> + assert (Poly.equal (Poly.constants Scalar.(a / b)) q && Poly.is_null r) + + let get_tests () = + let open Alcotest in + ( Printf.sprintf + "Euclidian division for prime field %s" + (Z.to_string Scalar.order), + [ + test_case + "test vectors for random" + `Quick + (repeat 10 test_verify_equality_with_random); + test_case "test with constants" `Quick (repeat 10 test_with_constants); + test_case + "test vectors for random divided by constant" + `Quick + (repeat 10 test_verify_equality_with_random_divided_by_constant); + ] ) +end + +module MakeTestDensifiedPolynomial + (Scalar : Bls12_381.Ff_sig.PRIME) + (Poly : Polynomial.UNIVARIATE with type scalar = Scalar.t) = +struct + let test_vectors () = + let rec generate_non_null () = + let r = Scalar.random () in + if Scalar.is_zero r then generate_non_null () else r + in + let x = generate_non_null () in + let zero = Scalar.zero in + let test_vectors = + [ + (Poly.zero, [Scalar.zero]); + (Poly.constants x, [x]); + (Poly.of_coefficients [(x, 2)], [x; zero; zero]); + (Poly.of_coefficients [(x, 1)], [x; zero]); + (Poly.of_coefficients [(x, 3); (x, 1)], [x; zero; x; zero]); + (Poly.of_coefficients [(x, 4); (x, 1)], [x; zero; zero; x; zero]); + ( Poly.of_coefficients [(x, 17); (x, 14); (x, 3); (x, 1); (x, 0)], + [ + x; + zero; + zero; + x; + zero; + zero; + zero; + zero; + zero; + zero; + zero; + zero; + zero; + zero; + x; + zero; + x; + x; + ] ); + ] + in + List.iter + (fun (v, expected_result) -> + let r = Poly.get_dense_polynomial_coefficients v in + assert (List.for_all2 Scalar.eq expected_result r)) + test_vectors + + let get_tests () = + let open Alcotest in + ( (Printf.sprintf "Dense polynomial coefficients for prime field %s") + (Z.to_string Scalar.order), + [test_case "test vectors" `Quick (repeat 10 test_vectors)] ) +end + +module MakeTestDensifiedPolynomialWithDegree + (Scalar : Bls12_381.Ff_sig.PRIME) + (Poly : Polynomial.UNIVARIATE with type scalar = Scalar.t) = +struct + let test_vectors () = + let rec generate_non_null () = + let r = Scalar.random () in + if Scalar.is_zero r then generate_non_null () else r + in + let x = generate_non_null () in + let zero = Scalar.zero in + let test_vectors = + [ + (Poly.zero, [(Scalar.zero, 0)]); + (Poly.constants x, [(x, 0)]); + (Poly.of_coefficients [(x, 2)], [(x, 2); (zero, 1); (zero, 0)]); + (Poly.of_coefficients [(x, 1)], [(x, 1); (zero, 0)]); + ( Poly.of_coefficients [(x, 3); (x, 1)], + [(x, 3); (zero, 2); (x, 1); (zero, 0)] ); + ( Poly.of_coefficients [(x, 4); (x, 1)], + [(x, 4); (zero, 3); (zero, 2); (x, 1); (zero, 0)] ); + ( Poly.of_coefficients [(x, 17); (x, 14); (x, 3); (x, 1); (x, 0)], + [ + (x, 17); + (zero, 16); + (zero, 15); + (x, 14); + (zero, 13); + (zero, 12); + (zero, 11); + (zero, 10); + (zero, 9); + (zero, 8); + (zero, 7); + (zero, 6); + (zero, 5); + (zero, 4); + (x, 3); + (zero, 2); + (x, 1); + (x, 0); + ] ); + ] + in + List.iter + (fun (v, expected_result) -> + let r = Poly.get_dense_polynomial_coefficients_with_degree v in + assert ( + List.for_all2 + (fun (e1, p1) (e2, p2) -> Scalar.eq e1 e2 && p1 = p2) + expected_result + r)) + test_vectors + + let get_tests () = + let open Alcotest in + ( (Printf.sprintf + "Dense polynomial coefficients with degree for prime field %s") + (Z.to_string Scalar.order), + [test_case "test vectors" `Quick (repeat 10 test_vectors)] ) +end + +module MakeTestExtendedEuclide + (Scalar : Bls12_381.Ff_sig.PRIME) + (Poly : Polynomial.UNIVARIATE with type scalar = Scalar.t) = +struct + let test_random_properties () = + let test poly_1 poly_2 = + let gcd1, u1, v1 = Poly.extended_euclide poly_1 poly_2 in + let gcd2, u2, v2 = Poly.extended_euclide poly_2 poly_1 in + assert (Poly.equal gcd1 gcd2) ; + assert ( + Poly.equal + (Poly.add + (Poly.polynomial_multiplication poly_1 u1) + (Poly.polynomial_multiplication poly_2 v1)) + gcd1) ; + assert ( + Poly.equal + (Poly.add + (Poly.polynomial_multiplication poly_2 u2) + (Poly.polynomial_multiplication poly_1 v2)) + gcd2) ; + if not (Poly.equal gcd1 Poly.zero) then ( + let remainder_poly_1 = + Poly.euclidian_division_opt poly_1 gcd1 |> Option.get |> snd + in + assert (Poly.is_null remainder_poly_1) ; + let remainder_poly_2 = + Poly.euclidian_division_opt poly_2 gcd1 |> Option.get |> snd + in + assert (Poly.is_null remainder_poly_2)) + in + let n = Random.int 100 in + let m = Random.int 50 in + let poly_1 = Poly.generate_random_polynomial (Polynomial.Natural n) in + let poly_2 = Poly.generate_random_polynomial (Polynomial.Natural m) in + let poly_3 = Poly.generate_random_polynomial (Polynomial.Natural n) in + + test poly_1 poly_2 ; + test poly_1 Poly.zero ; + test Poly.zero poly_1 ; + test poly_1 poly_3 ; + test poly_3 poly_1 ; + test Poly.zero Poly.zero + + let get_tests () = + let open Alcotest in + ( Printf.sprintf + "Extended Euclide alogrithm for prime field %s" + (Z.to_string Scalar.order), + [ + test_case + "test properties on random polynomials" + `Quick + (repeat 10 test_random_properties); + ] ) +end + +module MakeTestPolynomialMultiplication + (Scalar : Bls12_381.Ff_sig.PRIME) + (Poly : Polynomial.UNIVARIATE with type scalar = Scalar.t) = +struct + let test_multiply_by_zero_is_zero () = + let r = Poly.generate_random_polynomial (Natural (Random.int 1000)) in + assert (Poly.equal (Poly.polynomial_multiplication r Poly.zero) Poly.zero) ; + assert (Poly.equal (Poly.polynomial_multiplication Poly.zero r) Poly.zero) + + let test_communitativity () = + let p = Poly.generate_random_polynomial (Natural (Random.int 30)) in + let q = Poly.generate_random_polynomial (Natural (Random.int 30)) in + assert ( + Poly.equal + (Poly.polynomial_multiplication p q) + (Poly.polynomial_multiplication q p)) + + let test_distributivity () = + let a = Scalar.random () in + let b = Scalar.random () in + let p = Poly.generate_random_polynomial (Natural (Random.int 30)) in + let q = Poly.generate_random_polynomial (Natural (Random.int 30)) in + assert ( + Poly.equal + (Poly.polynomial_multiplication + (Poly.mult_by_scalar a p) + (Poly.mult_by_scalar b q)) + (Poly.polynomial_multiplication + (Poly.mult_by_scalar a q) + (Poly.mult_by_scalar b p))) ; + assert ( + Poly.equal + (Poly.polynomial_multiplication + (Poly.mult_by_scalar Scalar.(a * b) p) + q) + (Poly.polynomial_multiplication + (Poly.mult_by_scalar Scalar.(a * b) q) + p)) ; + assert ( + Poly.equal + (Poly.polynomial_multiplication + p + (Poly.mult_by_scalar Scalar.(a * b) q)) + (Poly.polynomial_multiplication + q + (Poly.mult_by_scalar Scalar.(a * b) p))) ; + assert ( + Poly.equal + (Poly.polynomial_multiplication + (Poly.mult_by_scalar a p) + (Poly.mult_by_scalar b q)) + Poly.(mult_by_scalar Scalar.(a * b) (polynomial_multiplication p q))) + + let get_tests () = + let open Alcotest in + ( Printf.sprintf + "Polynomial multiplication for prime field %s" + (Z.to_string Scalar.order), + [ + test_case + "test properties nullifier 0 * P = P * 0 = 0" + `Quick + (repeat 10 test_multiply_by_zero_is_zero); + test_case + "test properties commutativity p * q = p * q" + `Quick + (repeat 10 test_communitativity); + test_case + "test properties distributivity and communtativity a p * b q = (a * \ + b) (p * q) = (b p) * (a q) = p * (a * b) q" + `Quick + (repeat 10 test_distributivity); + ] ) +end + +module MakeTestInterpolationFFT + (Scalar : Bls12_381.Ff_sig.PRIME) + (Poly : Polynomial.UNIVARIATE with type scalar = Scalar.t) = +struct + let test_interpolation_fft_random_values_against_lagrange_interpolation + ~generator ~power () = + let random_polynomial = + Poly.generate_random_polynomial (Polynomial.Natural (power - 1)) + in + let evaluation_points = + Poly.get_dense_polynomial_coefficients random_polynomial + in + let domain = + Polynomial.generate_evaluation_domain (module Scalar) power generator + in + let expected_results = + Poly.lagrange_interpolation + (List.combine (Array.to_list domain) evaluation_points) + in + let results = Poly.interpolation_fft ~domain evaluation_points in + assert (Poly.equal results expected_results) + + let test_interpolation_fft_with_only_roots ~generator ~power () = + let domain = + Polynomial.generate_evaluation_domain (module Scalar) power generator + in + (* only roots *) + let evaluation_points = List.init power (fun _i -> Scalar.zero) in + let expected_results = + Poly.lagrange_interpolation + (List.combine (Array.to_list domain) evaluation_points) + in + let results = Poly.interpolation_fft ~domain evaluation_points in + assert (Poly.equal results expected_results) ; + assert (Poly.is_null results) + + let get_tests ~domains () = + let domains = List.map (fun (g, p) -> (Scalar.of_z g, p)) domains in + let open Alcotest in + ( Printf.sprintf "Inverse FFT for prime field %s" (Z.to_string Scalar.order), + List.( + flatten + (map + (fun (generator, power) -> + [ + test_case + "test interpolation at random points" + `Quick + (repeat + 10 + (test_interpolation_fft_random_values_against_lagrange_interpolation + ~generator + ~power)); + test_case + "test interpolation with only roots" + `Quick + (repeat + 10 + (test_interpolation_fft_with_only_roots ~generator ~power)); + ]) + domains)) ) +end + +module MakeTestEvaluationFFT + (Scalar : Bls12_381.Ff_sig.PRIME) + (Poly : Polynomial.UNIVARIATE with type scalar = Scalar.t) = +struct + let test_evaluation_fft_zero ~generator ~power () = + let domain = + Polynomial.generate_evaluation_domain (module Scalar) power generator + in + let polynomial = Poly.zero in + let results = Poly.evaluation_fft ~domain polynomial in + let expected_results = List.init power (fun _ -> Scalar.zero) in + if not (List.for_all2 Scalar.eq results expected_results) then + let expected_values = + String.concat "; " (List.map Scalar.to_string expected_results) + in + let values = String.concat "; " (List.map Scalar.to_string results) in + Alcotest.failf + "Expected values [%s]\nComputed [%s]" + expected_values + values + + let test_evaluation_fft_constant ~generator ~power () = + let domain = + Polynomial.generate_evaluation_domain (module Scalar) power generator + in + let s = Scalar.random () in + let polynomial = Poly.constants s in + let results = Poly.evaluation_fft ~domain polynomial in + let expected_results = List.init power (fun _ -> s) in + if not (List.for_all2 Scalar.eq results expected_results) then + let expected_values = + String.concat "; " (List.map Scalar.to_string expected_results) + in + let values = String.concat "; " (List.map Scalar.to_string results) in + Alcotest.failf + "Expected values [%s]\nComputed [%s]" + expected_values + values + + let test_evaluation_fft_random_values_against_normal_evaluation ~generator + ~power () = + let domain = + Polynomial.generate_evaluation_domain (module Scalar) power generator + in + let polynomial = + Poly.generate_random_polynomial (Polynomial.Natural (power - 1)) + in + let expected_results = + List.map (fun x -> Poly.evaluation polynomial x) (Array.to_list domain) + in + let results = Poly.evaluation_fft ~domain polynomial in + if not (List.for_all2 Scalar.eq results expected_results) then + let expected_values = + String.concat "; " (List.map Scalar.to_string expected_results) + in + let values = String.concat "; " (List.map Scalar.to_string results) in + Alcotest.failf + "Expected values [%s]\nComputed [%s]" + expected_values + values + + let test_evaluation_fft_random_values_with_larger_polynomial ~generator ~power + () = + let domain = + Polynomial.generate_evaluation_domain (module Scalar) power generator + in + let polynomial = + Poly.generate_random_polynomial + (Polynomial.Natural (power + Random.int 100)) + in + let expected_results = + List.map (fun x -> Poly.evaluation polynomial x) (Array.to_list domain) + in + let results = Poly.evaluation_fft ~domain polynomial in + if not (List.for_all2 Scalar.eq results expected_results) then + let expected_values = + String.concat "; " (List.map Scalar.to_string expected_results) + in + let values = String.concat "; " (List.map Scalar.to_string results) in + Alcotest.failf + "Expected values [%s]\nComputed [%s]" + expected_values + values + + let test_evaluation_fft_random_values_with_smaller_polynomial ~generator + ~power () = + let domain = + Polynomial.generate_evaluation_domain (module Scalar) power generator + in + let polynomial = + Poly.generate_random_polynomial + (Polynomial.Natural (Random.int (power - 1))) + in + let expected_results = + List.map (fun x -> Poly.evaluation polynomial x) (Array.to_list domain) + in + let results = Poly.evaluation_fft ~domain polynomial in + if not (List.for_all2 Scalar.eq results expected_results) then + let expected_values = + String.concat "; " (List.map Scalar.to_string expected_results) + in + let values = String.concat "; " (List.map Scalar.to_string results) in + Alcotest.failf + "Expected values [%s]\nComputed [%s]" + expected_values + values + + let get_tests ~domains () = + let domains = List.map (fun (g, p) -> (Scalar.of_z g, p)) domains in + let open Alcotest in + ( Printf.sprintf + "Evaluation FFT for prime field %s" + (Z.to_string Scalar.order), + List.flatten + (List.map + (fun (generator, power) -> + [ + test_case + "test evaluation at random points" + `Quick + (repeat + 10 + (test_evaluation_fft_random_values_against_normal_evaluation + ~generator + ~power)); + test_case + "test evaluation with zero polynomial" + `Quick + (test_evaluation_fft_zero ~generator ~power); + test_case + "test evaluation with smaller polynomial" + `Quick + (repeat + 10 + (test_evaluation_fft_random_values_with_smaller_polynomial + ~generator + ~power)); + test_case + "test evaluation with larger polynomial" + `Quick + (repeat + 10 + (test_evaluation_fft_random_values_with_larger_polynomial + ~generator + ~power)); + ]) + domains) ) +end + +module MakeTestPolynomialMultiplicationFFT + (Scalar : Bls12_381.Ff_sig.PRIME) + (Poly : Polynomial.UNIVARIATE with type scalar = Scalar.t) = +struct + let test_with_zero_polynomial ~generator ~power () = + let domain = + Polynomial.generate_evaluation_domain (module Scalar) power generator + in + let p = Poly.zero in + let q_is_zero = Random.bool () in + let degree_q = if q_is_zero then -1 else Random.int power in + let q = + if q_is_zero then Poly.zero + else Poly.generate_random_polynomial (Polynomial.Natural degree_q) + in + let p_times_q_fft = Poly.polynomial_multiplication_fft ~domain p q in + assert (Poly.degree_int p_times_q_fft = -1) ; + assert (Poly.is_null p_times_q_fft) + + let test_degree_non_null_polynomials ~generator ~power () = + (* We generate two polynomials with any degree whose the sum is smaller than + the domain size and we check the resulting polynomial has the expected degree. + *) + let domain = + Polynomial.generate_evaluation_domain (module Scalar) power generator + in + let degree_p = Random.int power in + let degree_q = Random.int (power - degree_p) in + let p = Poly.generate_random_polynomial (Polynomial.Natural degree_p) in + let q = Poly.generate_random_polynomial (Polynomial.Natural degree_q) in + let p_times_q_fft = Poly.polynomial_multiplication_fft ~domain p q in + let p_times_q_fft_degree = Poly.degree_int p_times_q_fft in + if p_times_q_fft_degree != degree_p + degree_q then + Alcotest.failf + "Expected degree of FFT multiplication: %d (%d + %d). Computed: %d" + (degree_p + degree_q) + degree_p + degree_q + p_times_q_fft_degree + + let test_commutativity ~generator ~power () = + let domain = + Polynomial.generate_evaluation_domain (module Scalar) power generator + in + let degree_p = Random.int power in + let degree_q = Random.int (power - degree_p) in + let p = Poly.generate_random_polynomial (Polynomial.Natural degree_p) in + let q = Poly.generate_random_polynomial (Polynomial.Natural degree_q) in + let q_times_p_fft = Poly.polynomial_multiplication_fft ~domain q p in + let p_times_q_fft = Poly.polynomial_multiplication_fft ~domain p q in + assert (Poly.equal q_times_p_fft p_times_q_fft) + + let test_random_values_fft_against_normal_multiplication ~generator ~power () + = + let domain = + Polynomial.generate_evaluation_domain (module Scalar) power generator + in + let degree_p = Random.int power in + let degree_q = Random.int (power - degree_p) in + let p = Poly.generate_random_polynomial (Polynomial.Natural degree_p) in + let q = Poly.generate_random_polynomial (Polynomial.Natural degree_q) in + let p_times_q = Poly.polynomial_multiplication p q in + let p_times_q_fft = Poly.polynomial_multiplication_fft ~domain p q in + if not (Poly.equal p_times_q_fft p_times_q) then + Alcotest.failf + "Fail on p = @[%s@] and q = @[%s@].@,Expected result is %s, computed %s" + (Poly.to_string p) + (Poly.to_string q) + (Poly.to_string p_times_q) + (Poly.to_string p_times_q_fft) + + let get_tests ~domains () = + let domains = List.map (fun (g, p) -> (Scalar.of_z g, p)) domains in + let open Alcotest in + ( Printf.sprintf + "Polynomial multiplication FFT for prime field %s" + (Z.to_string Scalar.order), + List.flatten + (List.map + (fun (generator, power) -> + [ + test_case + "Compare FFT version of polynomial multiplication against \ + normal polynomial multiplication" + `Quick + (repeat + 20 + (test_random_values_fft_against_normal_multiplication + ~generator + ~power)); + test_case + "At least one of the polynomial is zero" + `Quick + (repeat 20 (test_with_zero_polynomial ~generator ~power)); + test_case + "Verify the degree of P * Q is correct" + `Quick + (repeat + 100 + (test_degree_non_null_polynomials ~generator ~power)); + test_case + "Commutativity of polynomial multiplication using FFT" + `Quick + (repeat 20 (test_commutativity ~generator ~power)); + ]) + domains) ) +end diff --git a/src/lib_polynomial/test/test_utils.ml b/src/lib_polynomial/test/test_utils.ml new file mode 100644 index 000000000000..1ce216782aac --- /dev/null +++ b/src/lib_polynomial/test/test_utils.ml @@ -0,0 +1,25 @@ +open Polynomial + +let () = Random.self_init () + +let test_next_power_of_two () = + let vectors = [(2, 2); (3, 4); (7, 8); (12, 16)] in + List.iter + (fun (x, expected_result) -> + let res = Utils.next_power_of_two x in + if res != expected_result then + Alcotest.failf + "Expected result is %d (for %d), got %d" + expected_result + x + res) + vectors + +let () = + let open Alcotest in + run + "Utils" + [ + ( "Reorganizing the coefficients", + [test_case "Next power of two" `Quick test_next_power_of_two] ); + ] diff --git a/src/lib_polynomial/test/test_with_finite_field.ml b/src/lib_polynomial/test/test_with_finite_field.ml new file mode 100644 index 000000000000..88690ed7e3ae --- /dev/null +++ b/src/lib_polynomial/test/test_with_finite_field.ml @@ -0,0 +1,809 @@ +(*****************************************************************************) +(* *) +(* Copyright (c) 2020-2021 Danny Willems *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Mec + +let () = Random.self_init () + +let is_prime_number n = + let two = Z.succ Z.one in + let rec internal div n = + if Z.gt (Z.mul div div) n then true + else if Z.equal (Z.erem n div) Z.zero then false + else internal (Z.add div two) n + in + if not (Z.gt n Z.one) then false + else if Z.equal two n then true + else if Z.equal (Z.erem n two) Z.zero then false + else internal (Z.succ two) n + +module F379 = Ff.MakeFp (struct + let prime_order = Z.of_int 379 +end) + +module Poly = Polynomial.MakeUnivariate (F379) +module TestDegree_F379 = Polynomial_pbt.MakeTestDegree (F379) (Poly) + +module TestEvaluation_F379 = struct + include Polynomial_pbt.MakeTestEvaluation (F379) (Poly) + + let test_eval_some_test_vectors () = + let one = F379.one in + let p = Poly.of_coefficients [(one, 2); (one, 1); (one, 0)] in + let evaluation_point_with_expected_value = + [ + (F379.of_string "5", F379.of_string "31"); + (F379.of_string "42", F379.of_string "291"); + (F379.of_string "3", F379.of_string "13"); + (F379.of_string "0", F379.of_string "1"); + ] + in + List.iter + (fun (x, expected_value) -> + assert (F379.eq (Poly.evaluation p x) expected_value)) + evaluation_point_with_expected_value ; + let p = + Poly.of_coefficients + [(one, 17); (F379.of_string "-42", 2); (F379.of_string "10", 0)] + in + let evaluation_point_with_expected_value = + [ + (F379.of_string "5", F379.of_string "40"); + (F379.of_string "42", F379.of_string "148"); + (F379.of_string "3", F379.of_string "93"); + (F379.of_string "0", F379.of_string "10"); + ] + in + List.iter + (fun (x, expected_value) -> + assert (F379.eq (Poly.evaluation p x) expected_value)) + evaluation_point_with_expected_value + + let get_tests () = + let open Alcotest in + let specific_tests = + [test_case "evaluation test vectors" `Quick test_eval_some_test_vectors] + in + let desc, tests = get_tests () in + (desc, List.concat [specific_tests; tests]) +end + +module TestAdd_F379 = struct + let test_vectors () = + (* 2 X^2 + 3X *) + let p1 = + Poly.of_coefficients [(F379.of_string "2", 2); (F379.of_string "3", 1)] + in + (* 10 X + 3 *) + let p2 = + Poly.of_coefficients [(F379.of_string "10", 1); (F379.of_string "3", 0)] + in + let expected_result = + Poly.of_coefficients + [ + (F379.of_string "2", 2); + (F379.of_string "13", 1); + (F379.of_string "3", 0); + ] + in + assert (Poly.equal (Poly.add p1 p2) expected_result) + + let get_tests () = + let open Alcotest in + ("Test add", [test_case "test vectors" `Quick test_vectors]) +end + +module TestMultByScalar_F379 = struct + let test_vectors () = + (* X/2 in F379 *) + let p1 = + Poly.mult_by_scalar + (F379.inverse_exn (F379.of_string "2")) + (Poly.of_coefficients [(F379.of_string "1", 1)]) + in + assert (Poly.equal (Poly.of_coefficients [(F379.of_string "190", 1)]) p1) + + let test_multiply_constants_by_scalar_zero_is_zero () = + let p1 = Poly.constants (F379.random ()) in + assert (Poly.is_null (Poly.mult_by_scalar F379.zero p1)) + + let test_multiply_degree_one_by_scalar_zero_is_zero () = + let p1 = Poly.of_coefficients [(F379.of_string "1", 1)] in + assert (Poly.is_null (Poly.mult_by_scalar F379.zero p1)) + + let get_tests () = + let open Alcotest in + ( "Test mult by scalar", + [ + test_case "test vectors" `Quick test_vectors; + test_case + "test multiply constants by scalar zero is zero" + `Quick + test_multiply_constants_by_scalar_zero_is_zero; + test_case + "test multiply degree one by scalar zero is zero" + `Quick + test_multiply_degree_one_by_scalar_zero_is_zero; + ] ) +end + +module TestOpposite_F379 = struct + let test_property_of_twice_opposite () = + let p1 = Poly.of_coefficients [(F379.of_string "10", 1)] in + assert (Poly.equal (Poly.opposite (Poly.opposite p1)) p1) + + let test_property_opposite_of_constant () = + let random = F379.random () in + assert ( + Poly.equal + (Poly.opposite (Poly.constants random)) + (Poly.constants (F379.negate random))) + + let test_property_opposite_of_zero () = + assert (Poly.(Poly.opposite Poly.zero = Poly.zero)) + + let get_tests () = + let open Alcotest in + ( "Test opposite", + [ + test_case + "test property opposite twice" + `Quick + test_property_of_twice_opposite; + test_case + "test property opposite of constant" + `Quick + test_property_opposite_of_constant; + test_case + "test property opposite of zero" + `Quick + test_property_opposite_of_zero; + ] ) +end + +module TestLagrangeInterpolation_F379 = struct + include Polynomial_pbt.MakeTestLagrangeInterpolation (F379) (Poly) + + let test_vector () = + let points = + [ + (F379.of_string "2", F379.of_string "3"); + (F379.of_string "0", F379.of_string "1"); + ] + in + let interpolated_polynomial = Poly.lagrange_interpolation points in + match Poly.degree interpolated_polynomial with + | Polynomial.Infinity -> assert false + | Natural n -> + assert (n <= List.length points - 1) ; + assert ( + Poly.equal + (Poly.of_coefficients + [(F379.of_string "1", 1); (F379.of_string "1", 0)]) + interpolated_polynomial) ; + assert ( + F379.eq + (Poly.evaluation interpolated_polynomial (F379.of_string "0")) + (F379.of_string "1")) ; + assert ( + F379.eq + (Poly.evaluation interpolated_polynomial (F379.of_string "2")) + (F379.of_string "3")) ; + (* Other random points *) + assert ( + F379.eq + (Poly.evaluation interpolated_polynomial (F379.of_string "1")) + (F379.of_string "2")) ; + assert ( + F379.eq + (Poly.evaluation interpolated_polynomial (F379.of_string "17")) + (F379.of_string "18")) + + let get_tests () = + let open Alcotest in + let specific_tests = [test_case "test vector" `Quick test_vector] in + let desc, tests = get_tests () in + (desc, List.concat [specific_tests; tests]) +end + +module TestSplitPolynomial_F379 = struct + let test_even_polynomial () = + let x = F379.random () in + let test_vectors = + [ + (Poly.zero, Poly.zero); + (Poly.constants x, Poly.constants x); + (Poly.of_coefficients [(x, 2)], Poly.of_coefficients [(x, 2)]); + (Poly.of_coefficients [(x, 1)], Poly.zero); + (Poly.of_coefficients [(x, 3); (x, 1)], Poly.zero); + (Poly.of_coefficients [(x, 4); (x, 1)], Poly.of_coefficients [(x, 4)]); + ( Poly.of_coefficients + [ + (x, 34534); + (x, 345); + (x, 23); + (x, 21); + (x, 17); + (x, 14); + (x, 3); + (x, 1); + (x, 0); + ], + Poly.of_coefficients [(x, 34534); (x, 14); (x, 0)] ); + ] + in + List.iter + (fun (v, expected_result) -> + assert (Poly.equal expected_result (Poly.even_polynomial v))) + test_vectors + + let test_odd_polynomial () = + let x = F379.random () in + let test_vectors = + [ + (Poly.zero, Poly.zero); + (Poly.constants x, Poly.zero); + (Poly.of_coefficients [(x, 2)], Poly.zero); + (Poly.of_coefficients [(x, 1)], Poly.of_coefficients [(x, 1)]); + ( Poly.of_coefficients [(x, 3); (x, 1)], + Poly.of_coefficients [(x, 3); (x, 1)] ); + (Poly.of_coefficients [(x, 4); (x, 1)], Poly.of_coefficients [(x, 1)]); + ( Poly.of_coefficients + [ + (x, 34534); + (x, 345); + (x, 23); + (x, 21); + (x, 17); + (x, 14); + (x, 3); + (x, 1); + (x, 0); + ], + Poly.of_coefficients + [(x, 345); (x, 23); (x, 21); (x, 17); (x, 3); (x, 1)] ); + ] + in + List.iter + (fun (v, expected_result) -> + assert (Poly.equal expected_result (Poly.odd_polynomial v))) + test_vectors + + let get_tests () = + let open Alcotest in + ( "Split polynomials", + [ + test_case + "Test even polynomial with test vectors" + `Quick + test_even_polynomial; + test_case + "Test odd polynomial with test vectors" + `Quick + test_odd_polynomial; + ] ) +end + +module TestDensifiedPolynomial_F379 = + Polynomial_pbt.MakeTestDensifiedPolynomial (F379) (Poly) + +module TestEvaluationFFT_F337 = struct + module F337 = Ff.MakeFp (struct + let prime_order = Z.of_string "337" + end) + + module Poly = Polynomial.MakeUnivariate (F337) + + let generator = Z.of_string "85" + + let power = 8 + + let domain = + Polynomial.generate_evaluation_domain + (module F337) + power + (F337.of_z generator) + + include Polynomial_pbt.MakeTestEvaluationFFT (F337) (Poly) + + let test_evaluation_fft_vectors () = + let test_vectors = + [ + ( Poly.of_coefficients + [ + (F337.of_string "6", 7); + (F337.of_string "2", 6); + (F337.of_string "9", 5); + (F337.of_string "5", 4); + (F337.of_string "1", 3); + (F337.of_string "4", 2); + (F337.of_string "1", 1); + (F337.of_string "3", 0); + ], + [ + F337.of_string "31"; + F337.of_string "70"; + F337.of_string "109"; + F337.of_string "74"; + F337.of_string "334"; + F337.of_string "181"; + F337.of_string "232"; + F337.of_string "4"; + ] ); + ] + in + List.iter + (fun (polynomial, expected_result) -> + let res = Poly.evaluation_fft polynomial ~domain in + assert (res = expected_result)) + test_vectors + + let get_tests () = + let open Alcotest in + let specific_tests = + [ + test_case + "test vectors for evaluation" + `Quick + test_evaluation_fft_vectors; + ] + in + let desc, tests = get_tests ~domains:[(generator, power)] () in + (desc, List.concat [specific_tests; tests]) +end + +module TestInverseFFT_F337 = struct + module F337 = Ff.MakeFp (struct + let prime_order = Z.of_string "337" + end) + + module Poly = Polynomial.MakeUnivariate (F337) + + let generator = Z.of_string "85" + + let power = 8 + + let domain = + Polynomial.generate_evaluation_domain + (module F337) + power + (F337.of_z generator) + + include Polynomial_pbt.MakeTestInterpolationFFT (F337) (Poly) + + let test_interpolation_fft_vectors () = + let test_vectors = + [ + ( [ + F337.of_string "31"; + F337.of_string "70"; + F337.of_string "109"; + F337.of_string "74"; + F337.of_string "334"; + F337.of_string "181"; + F337.of_string "232"; + F337.of_string "4"; + ], + Poly.of_coefficients + [ + (F337.of_string "6", 7); + (F337.of_string "2", 6); + (F337.of_string "9", 5); + (F337.of_string "5", 4); + (F337.of_string "1", 3); + (F337.of_string "4", 2); + (F337.of_string "1", 1); + (F337.of_string "3", 0); + ] ); + ] + in + List.iter + (fun (points, expected_polynomial) -> + let res = Poly.interpolation_fft ~domain points in + assert (Poly.equal res expected_polynomial)) + test_vectors ; + (* With a null coefficient *) + let points = + [ + F337.of_string "34"; + F337.of_string "34"; + F337.of_string "34"; + F337.of_string "34"; + F337.of_string "34"; + F337.of_string "34"; + F337.of_string "34"; + F337.of_string "0"; + ] + in + let res = Poly.interpolation_fft ~domain points in + let expected_results = + Poly.lagrange_interpolation (List.combine (Array.to_list domain) points) + in + assert (Poly.equal res expected_results) + + let get_tests () = + let open Alcotest in + let specific_tests = + [ + test_case + "test vectors for interpolation fft" + `Quick + test_interpolation_fft_vectors; + ] + in + let desc, tests = get_tests ~domains:[(generator, power)] () in + (desc, List.concat [specific_tests; tests]) +end + +module TestPolynomialMultiplicationFFT_F337 = struct + module F337 = Ff.MakeFp (struct + let prime_order = Z.of_string "337" + end) + + module Poly = Polynomial.MakeUnivariate (F337) + + let generator = Z.of_string "85" + + let power = 8 + + let domain = + Polynomial.generate_evaluation_domain + (module F337) + power + (F337.of_z generator) + + include Polynomial_pbt.MakeTestPolynomialMultiplicationFFT (F337) (Poly) + + let test_vectors () = + let vectors = + [ + ( Poly.zero, + Poly.generate_random_polynomial (Polynomial.Natural 1000), + Poly.zero ); + ( Poly.generate_random_polynomial (Polynomial.Natural 100), + Poly.zero, + Poly.zero ); + ( Poly.zero, + Poly.generate_random_polynomial (Polynomial.Natural 1000), + Poly.zero ); + ( Poly.of_coefficients + [ + (F337.of_string "3", 3); + (F337.of_string "2", 2); + (F337.of_string "1", 1); + (F337.of_string "1", 0); + ], + Poly.of_coefficients + [ + (F337.of_string "3", 3); + (F337.of_string "2", 2); + (F337.of_string "1", 1); + (F337.of_string "1", 0); + ], + Poly.of_coefficients + [ + (F337.of_string "9", 6); + (F337.of_string "12", 5); + (F337.of_string "10", 4); + (F337.of_string "10", 3); + (F337.of_string "5", 2); + (F337.of_string "2", 1); + (F337.of_string "1", 0); + ] ); + ( Poly.of_coefficients [(F337.of_string "3", 1); (F337.of_string "1", 0)], + Poly.of_coefficients + [ + (F337.of_string "3", 5); + (F337.of_string "3", 4); + (F337.of_string "3", 3); + (F337.of_string "2", 2); + (F337.of_string "1", 1); + (F337.of_string "1", 0); + ], + Poly.of_coefficients + [ + (F337.of_string "9", 6); + (F337.of_string "12", 5); + (F337.of_string "12", 4); + (F337.of_string "9", 3); + (F337.of_string "5", 2); + (F337.of_string "4", 1); + (F337.of_string "1", 0); + ] ); + ( Poly.of_coefficients + [ + (F337.of_string "23", 3); + (F337.of_string "35", 2); + (F337.of_string "213", 1); + (F337.of_string "32", 0); + ], + Poly.of_coefficients + [ + (F337.of_string "121", 3); + (F337.of_string "43", 2); + (F337.of_string "56", 1); + (F337.of_string "82", 0); + ], + Poly.of_coefficients + [ + (F337.of_string "87", 6); + (F337.of_string "169", 5); + (F337.of_string "258", 4); + (F337.of_string "27", 3); + (F337.of_string "335", 2); + (F337.of_string "49", 1); + (F337.of_string "265", 0); + ] ); + ] + in + List.iter + (fun (p, q, expected_result) -> + assert ( + let res = Poly.polynomial_multiplication_fft ~domain p q in + Poly.equal expected_result res)) + vectors + + let get_tests () = + let open Alcotest in + let specific_tests = + [ + test_case + "test vectors for polynomial multiplication FFT" + `Quick + test_vectors; + ] + in + let desc, tests = get_tests ~domains:[(generator, power)] () in + (desc, List.concat [specific_tests; tests]) +end + +module TestEuclidianDivision_F379 = struct + include Polynomial_pbt.MakeTestEuclidianDivision (F379) (Poly) + + let test_vectors () = + let vectors = + [ + (* X^2 + 7X + 6 / X + 6 -> Q = X + 1 and R = 0 *) + ( Poly.of_coefficients + [ + (F379.of_string "1", 2); + (F379.of_string "7", 1); + (F379.of_string "6", 0); + ], + Poly.of_coefficients + [(F379.of_string "1", 1); (F379.of_string "6", 0)], + Some + ( Poly.of_coefficients + [(F379.of_string "1", 1); (F379.of_string "1", 0)], + Poly.zero ) ); + (* 2X^2 + 4X + 6 / 2 -> Q = X^2 + 2X + 3 and R = 0 *) + ( Poly.of_coefficients + [ + (F379.of_string "2", 2); + (F379.of_string "4", 1); + (F379.of_string "6", 0); + ], + Poly.of_coefficients [(F379.of_string "2", 0)], + Some + ( Poly.of_coefficients + [ + (F379.of_string "1", 2); + (F379.of_string "2", 1); + (F379.of_string "3", 0); + ], + Poly.zero ) ); + (* 2X^2 + 4X + 6 / 1 -> Q = 2X^2 + 4X + 6 and R = 0 *) + ( Poly.of_coefficients + [ + (F379.of_string "2", 2); + (F379.of_string "4", 1); + (F379.of_string "6", 0); + ], + Poly.of_coefficients [(F379.of_string "1", 0)], + Some + ( Poly.of_coefficients + [ + (F379.of_string "2", 2); + (F379.of_string "4", 1); + (F379.of_string "6", 0); + ], + Poly.zero ) ); + (* X^2 + 7X + 6 / X + 1 -> Q = X + 6 and R = 0 *) + ( Poly.of_coefficients + [ + (F379.of_string "1", 2); + (F379.of_string "7", 1); + (F379.of_string "6", 0); + ], + Poly.of_coefficients + [(F379.of_string "1", 1); (F379.of_string "1", 0)], + Some + ( Poly.of_coefficients + [(F379.of_string "1", 1); (F379.of_string "6", 0)], + Poly.zero ) ); + (* X^2 + 7X + 10 / X + 1 -> Q = X + 6 and R = 4 *) + ( Poly.of_coefficients + [ + (F379.of_string "1", 2); + (F379.of_string "7", 1); + (F379.of_string "10", 0); + ], + Poly.of_coefficients + [(F379.of_string "1", 1); (F379.of_string "1", 0)], + Some + ( Poly.of_coefficients + [(F379.of_string "1", 1); (F379.of_string "6", 0)], + Poly.constants (F379.of_string "4") ) ); + (* X + 1 / X^2 + 1 -> Q = 0 and R = X^2 + 1*) + ( Poly.of_coefficients [(F379.of_string "1", 1); (F379.of_string "1", 0)], + Poly.of_coefficients + [(F379.of_string "1", 2); (F379.of_string "1", 0)], + Some + ( Poly.zero, + Poly.of_coefficients + [(F379.of_string "1", 1); (F379.of_string "1", 0)] ) ); + (* Zero / X^2 + 1 -> Q = 0 and R = 0*) + ( Poly.zero, + Poly.of_coefficients + [(F379.of_string "1", 2); (F379.of_string "1", 0)], + Some (Poly.zero, Poly.zero) ); + (* Random polynomial / Zero -> None *) + ( Poly.generate_random_polynomial (Polynomial.Natural (Random.int 10000)), + Poly.zero, + None ); + ] + in + List.iter + (fun (a, b, expected_result) -> + let res = Poly.euclidian_division_opt a b in + match (res, expected_result) with + | None, None -> assert true + | None, _ | _, None -> assert false + | Some (q, r), Some (expected_q, expected_r) -> + assert (Poly.equal q expected_q && Poly.equal r expected_r)) + vectors + + let get_tests () = + let open Alcotest in + let specific_tests = + [test_case "test vectors for euclidian division" `Quick test_vectors] + in + let desc, tests = get_tests () in + (desc, List.concat [specific_tests; tests]) +end + +module TestExtendedEuclide_F379 = + Polynomial_pbt.MakeTestExtendedEuclide (F379) (Poly) + +let make_test_battery_for_prime_order_field ~domains p = + let module Fp = Ff.MakeFp (struct + let prime_order = p + end) in + let module Poly = Polynomial.MakeUnivariate (Fp) in + let module TestDegree = Polynomial_pbt.MakeTestDegree (Fp) (Poly) in + let module TestDensifiedPolynomial = + Polynomial_pbt.MakeTestDensifiedPolynomial (Fp) (Poly) + in + let module TestDensifiedPolynomialWithDegree = + Polynomial_pbt.MakeTestDensifiedPolynomialWithDegree (Fp) (Poly) + in + let module TestEvaluation = Polynomial_pbt.MakeTestEvaluation (Fp) (Poly) in + let module TestEuclidianDivision = + Polynomial_pbt.MakeTestEuclidianDivision (Fp) (Poly) + in + let module TestExtendedEuclide = + Polynomial_pbt.MakeTestExtendedEuclide (Fp) (Poly) + in + let module TestLagrangeInterpolation = + Polynomial_pbt.MakeTestLagrangeInterpolation (Fp) (Poly) + in + let module TestPolynomialMultiplication = + Polynomial_pbt.MakeTestPolynomialMultiplication (Fp) (Poly) + in + let module TestConstant = Polynomial_pbt.MakeTestConstant (Fp) (Poly) in + let module TestInterpolationFFT = + Polynomial_pbt.MakeTestInterpolationFFT (Fp) (Poly) + in + let module TestEvaluationFFT = + Polynomial_pbt.MakeTestEvaluationFFT (Fp) (Poly) + in + let module TestPolynomialMultiplicationFFT = + Polynomial_pbt.MakeTestPolynomialMultiplicationFFT (Fp) (Poly) + in + [ + TestDegree.get_tests (); + TestEvaluation.get_tests (); + TestEuclidianDivision.get_tests (); + TestPolynomialMultiplication.get_tests (); + TestExtendedEuclide.get_tests (); + TestDensifiedPolynomial.get_tests (); + TestDensifiedPolynomialWithDegree.get_tests (); + TestConstant.get_tests (); + TestLagrangeInterpolation.get_tests (); + TestPolynomialMultiplicationFFT.get_tests ~domains (); + TestEvaluationFFT.get_tests ~domains (); + TestInterpolationFFT.get_tests ~domains (); + ] + +let rec make_test_battery_with_random_fields acc n = + if n = 0 then acc + else + let prime_number = Random.int 0x3FFFFFFF (* max random *) in + if not (is_prime_number (Z.of_int prime_number)) then + make_test_battery_with_random_fields acc n + else + let tests = + make_test_battery_for_prime_order_field + ~domains:[] + (Z.of_int prime_number) + in + make_test_battery_with_random_fields (List.concat [acc; tests]) (n - 1) + +let () = + let open Alcotest in + let random_prime_fields_tests = make_test_battery_with_random_fields [] 5 in + let tests_for_BLS_Fr = + make_test_battery_for_prime_order_field + ~domains: + [ + ( Z.of_string + "16624801632831727463500847948913128838752380757508923660793891075002624508302", + 1 lsl 4 ); + ] + (Z.of_string + "52435875175126190479447740508185965837690552500527637822603658699938581184513") + in + let tests_for_BLS_Fq = + make_test_battery_for_prime_order_field + ~domains:[] + (Z.of_string + "4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787") + in + let test_for_base_field_curve25519 = + make_test_battery_for_prime_order_field Z.(pow (succ one) 255 - of_int 19) + in + run + "Polynomials with F379 and some random prime fields" + (List.concat + [ + random_prime_fields_tests; + tests_for_BLS_Fr; + tests_for_BLS_Fq; + test_for_base_field_curve25519 ~domains:[]; + [ + TestDegree_F379.get_tests (); + TestEvaluation_F379.get_tests (); + TestLagrangeInterpolation_F379.get_tests (); + TestMultByScalar_F379.get_tests (); + TestOpposite_F379.get_tests (); + TestSplitPolynomial_F379.get_tests (); + TestDensifiedPolynomial_F379.get_tests (); + TestInverseFFT_F337.get_tests (); + TestPolynomialMultiplicationFFT_F337.get_tests (); + TestEvaluationFFT_F337.get_tests (); + TestEuclidianDivision_F379.get_tests (); + TestExtendedEuclide_F379.get_tests (); + TestAdd_F379.get_tests (); + ]; + ]) diff --git a/src/lib_polynomial/utils.ml b/src/lib_polynomial/utils.ml new file mode 100644 index 000000000000..9892cdabd673 --- /dev/null +++ b/src/lib_polynomial/utils.ml @@ -0,0 +1,24 @@ +module Utils = struct + let bitreverse n' l = + let r = ref 0 in + let n = ref n' in + for _i = 0 to l - 1 do + r := (!r lsl 1) lor (!n land 1) ; + n := !n lsr 1 + done ; + !r + + let reorg_coefficients n logn values = + for i = 0 to n - 1 do + let reverse_i = bitreverse i logn in + if i < reverse_i then ( + let a_i = values.(i) in + let a_ri = values.(reverse_i) in + values.(i) <- a_ri ; + values.(reverse_i) <- a_i) + done + + let next_power_of_two x = + let logx = Z.log2 (Z.of_int x) in + if 1 lsl logx = x then x else 1 lsl (logx + 1) +end -- GitLab From d4c1cc9c240b006d9cab1ac5b14fb1b6e479061b Mon Sep 17 00:00:00 2001 From: Victor Dumitrescu Date: Thu, 9 Mar 2023 15:23:30 +0100 Subject: [PATCH 07/34] Lib_bls12_381_signature: import from ocaml-bls12-381-signature --- .gitlab/ci/jobs/packaging/opam_package.yml | 20 +- dune-project | 1 + manifest/main.ml | 62 +- opam/octez-bls12-381-hash.opam | 2 +- opam/octez-bls12-381-signature.opam | 23 + opam/octez-mec.opam | 2 +- opam/octez-polynomial.opam | 2 +- opam/tezos-bls12-381-polynomial-internal.opam | 2 +- opam/tezos-crypto.opam | 4 +- opam/tezos-protocol-environment.opam | 2 +- opam/virtual/octez-deps.opam | 3 +- package.json | 2 +- .../bls12_381_signature.ml | 727 ++++++++++ .../bls12_381_signature.mli | 394 ++++++ .../blst_bindings_stubs.c | 251 ++++ .../blst_bindings_stubs.js | 373 ++++++ src/lib_bls12_381_signature/dune | 32 + .../gen_wasm_needed_names.ml | 33 + src/lib_bls12_381_signature/needed-wasm-names | 15 + src/lib_bls12_381_signature/test/dune | 38 + .../test/test_aggregated_signature.ml | 467 +++++++ .../test/test_signature.ml | 1178 +++++++++++++++++ .../test/test_vectors/fft_test_vector_g1_2 | Bin 0 -> 384 bytes .../test/test_vectors/fft_test_vector_g2_2 | Bin 0 -> 768 bytes .../hash_to_curve_g1/g1_fips_186_3_B233 | 60 + .../hash_to_curve_g1/g1_fips_186_3_B283 | 60 + .../hash_to_curve_g1/g1_fips_186_3_B409 | 60 + .../hash_to_curve_g1/g1_fips_186_3_B571 | 60 + .../hash_to_curve_g1/g1_fips_186_3_K233 | 60 + .../hash_to_curve_g1/g1_fips_186_3_K283 | 60 + .../hash_to_curve_g1/g1_fips_186_3_K409 | 60 + .../hash_to_curve_g1/g1_fips_186_3_K571 | 60 + .../hash_to_curve_g1/g1_fips_186_3_P224 | 60 + .../hash_to_curve_g1/g1_fips_186_3_P256 | 60 + .../hash_to_curve_g1/g1_fips_186_3_P384 | 60 + .../hash_to_curve_g1/g1_fips_186_3_P521 | 60 + .../test_vectors/hash_to_curve_g1/g1_rfc6979 | 34 + .../hash_to_curve_g2/g2_fips_186_3_B233 | 60 + .../hash_to_curve_g2/g2_fips_186_3_B283 | 60 + .../hash_to_curve_g2/g2_fips_186_3_B409 | 60 + .../hash_to_curve_g2/g2_fips_186_3_B571 | 60 + .../hash_to_curve_g2/g2_fips_186_3_K233 | 60 + .../hash_to_curve_g2/g2_fips_186_3_K283 | 60 + .../hash_to_curve_g2/g2_fips_186_3_K409 | 60 + .../hash_to_curve_g2/g2_fips_186_3_K571 | 60 + .../hash_to_curve_g2/g2_fips_186_3_P224 | 60 + .../hash_to_curve_g2/g2_fips_186_3_P256 | 60 + .../hash_to_curve_g2/g2_fips_186_3_P384 | 60 + .../hash_to_curve_g2/g2_fips_186_3_P521 | 60 + .../test_vectors/hash_to_curve_g2/g2_rfc6979 | 34 + .../test/test_vectors/ifft_test_vector_g1_2 | Bin 0 -> 384 bytes .../test/test_vectors/ifft_test_vector_g2_2 | Bin 0 -> 768 bytes .../pop_g1/pop_g1_fips_186_3_B233 | 60 + .../pop_g1/pop_g1_fips_186_3_B233_blst | 60 + .../pop_g1/pop_g1_fips_186_3_B283 | 60 + .../pop_g1/pop_g1_fips_186_3_B283_blst | 60 + .../pop_g1/pop_g1_fips_186_3_B409 | 60 + .../pop_g1/pop_g1_fips_186_3_B409_blst | 60 + .../pop_g1/pop_g1_fips_186_3_B571 | 60 + .../pop_g1/pop_g1_fips_186_3_B571_blst | 60 + .../pop_g1/pop_g1_fips_186_3_K233 | 60 + .../pop_g1/pop_g1_fips_186_3_K233_blst | 60 + .../pop_g1/pop_g1_fips_186_3_K283 | 60 + .../pop_g1/pop_g1_fips_186_3_K283_blst | 60 + .../pop_g1/pop_g1_fips_186_3_K409 | 60 + .../pop_g1/pop_g1_fips_186_3_K409_blst | 60 + .../pop_g1/pop_g1_fips_186_3_K571 | 60 + .../pop_g1/pop_g1_fips_186_3_K571_blst | 60 + .../pop_g1/pop_g1_fips_186_3_P224 | 60 + .../pop_g1/pop_g1_fips_186_3_P224_blst | 60 + .../pop_g1/pop_g1_fips_186_3_P256 | 60 + .../pop_g1/pop_g1_fips_186_3_P256_blst | 60 + .../pop_g1/pop_g1_fips_186_3_P384 | 60 + .../pop_g1/pop_g1_fips_186_3_P384_blst | 60 + .../pop_g1/pop_g1_fips_186_3_P521 | 60 + .../pop_g1/pop_g1_fips_186_3_P521_blst | 60 + .../test/test_vectors/pop_g1/pop_g1_rfc6979 | 34 + .../test_vectors/pop_g1/pop_g1_rfc6979_blst | 34 + .../pop_g2/pop_g2_fips_186_3_B233 | 60 + .../pop_g2/pop_g2_fips_186_3_B233_blst | 60 + .../pop_g2/pop_g2_fips_186_3_B283 | 60 + .../pop_g2/pop_g2_fips_186_3_B283_blst | 60 + .../pop_g2/pop_g2_fips_186_3_B409 | 60 + .../pop_g2/pop_g2_fips_186_3_B409_blst | 60 + .../pop_g2/pop_g2_fips_186_3_B571 | 60 + .../pop_g2/pop_g2_fips_186_3_B571_blst | 60 + .../pop_g2/pop_g2_fips_186_3_K233 | 60 + .../pop_g2/pop_g2_fips_186_3_K233_blst | 60 + .../pop_g2/pop_g2_fips_186_3_K283 | 60 + .../pop_g2/pop_g2_fips_186_3_K409 | 60 + .../pop_g2/pop_g2_fips_186_3_K409_blst | 60 + .../pop_g2/pop_g2_fips_186_3_K571 | 60 + .../pop_g2/pop_g2_fips_186_3_K571_blst | 60 + .../pop_g2/pop_g2_fips_186_3_P224 | 60 + .../pop_g2/pop_g2_fips_186_3_P224_blst | 60 + .../pop_g2/pop_g2_fips_186_3_P256 | 60 + .../pop_g2/pop_g2_fips_186_3_P256_blst | 60 + .../pop_g2/pop_g2_fips_186_3_P384 | 60 + .../pop_g2/pop_g2_fips_186_3_P384_blst | 60 + .../pop_g2/pop_g2_fips_186_3_P521 | 60 + .../pop_g2/pop_g2_fips_186_3_P521_blst | 60 + .../test/test_vectors/pop_g2/pop_g2_rfc6979 | 34 + .../test_vectors/pop_g2/pop_g2_rfc6979_blst | 34 + .../sig_g1_aug/sig_g1_aug_fips_186_3_B233 | 60 + .../sig_g1_aug_fips_186_3_B233_blst | 60 + .../sig_g1_aug/sig_g1_aug_fips_186_3_B283 | 60 + .../sig_g1_aug_fips_186_3_B283_blst | 60 + .../sig_g1_aug/sig_g1_aug_fips_186_3_B409 | 60 + .../sig_g1_aug_fips_186_3_B409_blst | 60 + .../sig_g1_aug/sig_g1_aug_fips_186_3_B571 | 60 + .../sig_g1_aug_fips_186_3_B571_blst | 60 + .../sig_g1_aug/sig_g1_aug_fips_186_3_K233 | 60 + .../sig_g1_aug_fips_186_3_K233_blst | 60 + .../sig_g1_aug/sig_g1_aug_fips_186_3_K283 | 60 + .../sig_g1_aug_fips_186_3_K283_blst | 60 + .../sig_g1_aug/sig_g1_aug_fips_186_3_K409 | 60 + .../sig_g1_aug_fips_186_3_K409_blst | 60 + .../sig_g1_aug/sig_g1_aug_fips_186_3_K571 | 60 + .../sig_g1_aug_fips_186_3_K571_blst | 60 + .../sig_g1_aug/sig_g1_aug_fips_186_3_P224 | 60 + .../sig_g1_aug_fips_186_3_P224_blst | 60 + .../sig_g1_aug/sig_g1_aug_fips_186_3_P256 | 60 + .../sig_g1_aug_fips_186_3_P256_blst | 60 + .../sig_g1_aug/sig_g1_aug_fips_186_3_P384 | 60 + .../sig_g1_aug_fips_186_3_P384_blst | 60 + .../sig_g1_aug/sig_g1_aug_fips_186_3_P521 | 60 + .../sig_g1_aug_fips_186_3_P521_blst | 60 + .../sig_g1_aug/sig_g1_aug_rfc6979 | 34 + .../sig_g1_aug/sig_g1_aug_rfc6979_blst | 34 + .../sig_g1_basic/sig_g1_basic_fips_186_3_B233 | 60 + .../sig_g1_basic_fips_186_3_B233_blst | 60 + .../sig_g1_basic/sig_g1_basic_fips_186_3_B283 | 60 + .../sig_g1_basic_fips_186_3_B283_blst | 60 + .../sig_g1_basic/sig_g1_basic_fips_186_3_B409 | 60 + .../sig_g1_basic_fips_186_3_B409_blst | 60 + .../sig_g1_basic/sig_g1_basic_fips_186_3_B571 | 60 + .../sig_g1_basic_fips_186_3_B571_blst | 60 + .../sig_g1_basic/sig_g1_basic_fips_186_3_K233 | 60 + .../sig_g1_basic_fips_186_3_K233_blst | 60 + .../sig_g1_basic/sig_g1_basic_fips_186_3_K283 | 60 + .../sig_g1_basic_fips_186_3_K283_blst | 60 + .../sig_g1_basic/sig_g1_basic_fips_186_3_K409 | 60 + .../sig_g1_basic_fips_186_3_K409_blst | 60 + .../sig_g1_basic/sig_g1_basic_fips_186_3_K571 | 60 + .../sig_g1_basic_fips_186_3_K571_blst | 60 + .../sig_g1_basic/sig_g1_basic_fips_186_3_P224 | 60 + .../sig_g1_basic_fips_186_3_P224_blst | 60 + .../sig_g1_basic/sig_g1_basic_fips_186_3_P256 | 60 + .../sig_g1_basic_fips_186_3_P256_blst | 60 + .../sig_g1_basic/sig_g1_basic_fips_186_3_P384 | 60 + .../sig_g1_basic_fips_186_3_P384_blst | 60 + .../sig_g1_basic/sig_g1_basic_fips_186_3_P521 | 60 + .../sig_g1_basic_fips_186_3_P521_blst | 60 + .../sig_g1_basic/sig_g1_basic_rfc6979 | 34 + .../sig_g1_basic/sig_g1_basic_rfc6979_blst | 34 + .../sig_g1_pop/sig_g1_pop_fips_186_3_B233 | 60 + .../sig_g1_pop_fips_186_3_B233_blst | 60 + .../sig_g1_pop/sig_g1_pop_fips_186_3_B283 | 60 + .../sig_g1_pop_fips_186_3_B283_blst | 60 + .../sig_g1_pop/sig_g1_pop_fips_186_3_B409 | 60 + .../sig_g1_pop_fips_186_3_B409_blst | 60 + .../sig_g1_pop/sig_g1_pop_fips_186_3_B571 | 60 + .../sig_g1_pop_fips_186_3_B571_blst | 60 + .../sig_g1_pop/sig_g1_pop_fips_186_3_K233 | 60 + .../sig_g1_pop_fips_186_3_K233_blst | 60 + .../sig_g1_pop/sig_g1_pop_fips_186_3_K283 | 60 + .../sig_g1_pop_fips_186_3_K283_blst | 60 + .../sig_g1_pop/sig_g1_pop_fips_186_3_K409 | 60 + .../sig_g1_pop_fips_186_3_K409_blst | 60 + .../sig_g1_pop/sig_g1_pop_fips_186_3_K571 | 60 + .../sig_g1_pop_fips_186_3_K571_blst | 60 + .../sig_g1_pop/sig_g1_pop_fips_186_3_P224 | 60 + .../sig_g1_pop_fips_186_3_P224_blst | 60 + .../sig_g1_pop/sig_g1_pop_fips_186_3_P256 | 60 + .../sig_g1_pop_fips_186_3_P256_blst | 60 + .../sig_g1_pop/sig_g1_pop_fips_186_3_P384 | 60 + .../sig_g1_pop_fips_186_3_P384_blst | 60 + .../sig_g1_pop/sig_g1_pop_fips_186_3_P521 | 60 + .../sig_g1_pop_fips_186_3_P521_blst | 60 + .../sig_g1_pop/sig_g1_pop_rfc6979 | 34 + .../sig_g1_pop/sig_g1_pop_rfc6979_blst | 34 + .../sig_g2_aug/sig_g2_aug_fips_186_3_B233 | 60 + .../sig_g2_aug_fips_186_3_B233_blst | 60 + .../sig_g2_aug/sig_g2_aug_fips_186_3_B283 | 60 + .../sig_g2_aug_fips_186_3_B283_blst | 60 + .../sig_g2_aug/sig_g2_aug_fips_186_3_B409 | 60 + .../sig_g2_aug_fips_186_3_B409_blst | 60 + .../sig_g2_aug/sig_g2_aug_fips_186_3_B571 | 60 + .../sig_g2_aug_fips_186_3_B571_blst | 60 + .../sig_g2_aug/sig_g2_aug_fips_186_3_K233 | 60 + .../sig_g2_aug_fips_186_3_K233_blst | 60 + .../sig_g2_aug/sig_g2_aug_fips_186_3_K283 | 60 + .../sig_g2_aug/sig_g2_aug_fips_186_3_K409 | 60 + .../sig_g2_aug_fips_186_3_K409_blst | 60 + .../sig_g2_aug/sig_g2_aug_fips_186_3_K571 | 60 + .../sig_g2_aug_fips_186_3_K571_blst | 60 + .../sig_g2_aug/sig_g2_aug_fips_186_3_P224 | 60 + .../sig_g2_aug_fips_186_3_P224_blst | 60 + .../sig_g2_aug/sig_g2_aug_fips_186_3_P256 | 60 + .../sig_g2_aug_fips_186_3_P256_blst | 60 + .../sig_g2_aug/sig_g2_aug_fips_186_3_P384 | 60 + .../sig_g2_aug_fips_186_3_P384_blst | 60 + .../sig_g2_aug/sig_g2_aug_fips_186_3_P521 | 60 + .../sig_g2_aug_fips_186_3_P521_blst | 60 + .../sig_g2_aug/sig_g2_aug_rfc6979 | 34 + .../sig_g2_aug/sig_g2_aug_rfc6979_blst | 34 + .../sig_g2_basic/sig_g2_basic_fips_186_3_B233 | 60 + .../sig_g2_basic_fips_186_3_B233_blst | 60 + .../sig_g2_basic/sig_g2_basic_fips_186_3_B283 | 60 + .../sig_g2_basic_fips_186_3_B283_blst | 60 + .../sig_g2_basic/sig_g2_basic_fips_186_3_B409 | 60 + .../sig_g2_basic_fips_186_3_B409_blst | 60 + .../sig_g2_basic/sig_g2_basic_fips_186_3_B571 | 60 + .../sig_g2_basic_fips_186_3_B571_blst | 60 + .../sig_g2_basic/sig_g2_basic_fips_186_3_K233 | 60 + .../sig_g2_basic_fips_186_3_K233_blst | 60 + .../sig_g2_basic/sig_g2_basic_fips_186_3_K283 | 60 + .../sig_g2_basic/sig_g2_basic_fips_186_3_K409 | 60 + .../sig_g2_basic_fips_186_3_K409_blst | 60 + .../sig_g2_basic/sig_g2_basic_fips_186_3_K571 | 60 + .../sig_g2_basic_fips_186_3_K571_blst | 60 + .../sig_g2_basic/sig_g2_basic_fips_186_3_P224 | 60 + .../sig_g2_basic_fips_186_3_P224_blst | 60 + .../sig_g2_basic/sig_g2_basic_fips_186_3_P256 | 60 + .../sig_g2_basic_fips_186_3_P256_blst | 60 + .../sig_g2_basic/sig_g2_basic_fips_186_3_P384 | 60 + .../sig_g2_basic_fips_186_3_P384_blst | 60 + .../sig_g2_basic/sig_g2_basic_fips_186_3_P521 | 60 + .../sig_g2_basic_fips_186_3_P521_blst | 60 + .../sig_g2_basic/sig_g2_basic_rfc6979 | 34 + .../sig_g2_basic/sig_g2_basic_rfc6979_blst | 34 + .../sig_g2_pop/sig_g2_pop_fips_186_3_B233 | 60 + .../sig_g2_pop_fips_186_3_B233_blst | 60 + .../sig_g2_pop/sig_g2_pop_fips_186_3_B283 | 60 + .../sig_g2_pop_fips_186_3_B283_blst | 60 + .../sig_g2_pop/sig_g2_pop_fips_186_3_B409 | 60 + .../sig_g2_pop_fips_186_3_B409_blst | 60 + .../sig_g2_pop/sig_g2_pop_fips_186_3_B571 | 60 + .../sig_g2_pop_fips_186_3_B571_blst | 60 + .../sig_g2_pop/sig_g2_pop_fips_186_3_K233 | 60 + .../sig_g2_pop_fips_186_3_K233_blst | 60 + .../sig_g2_pop/sig_g2_pop_fips_186_3_K283 | 60 + .../sig_g2_pop/sig_g2_pop_fips_186_3_K409 | 60 + .../sig_g2_pop_fips_186_3_K409_blst | 60 + .../sig_g2_pop/sig_g2_pop_fips_186_3_K571 | 60 + .../sig_g2_pop_fips_186_3_K571_blst | 60 + .../sig_g2_pop/sig_g2_pop_fips_186_3_P224 | 60 + .../sig_g2_pop_fips_186_3_P224_blst | 60 + .../sig_g2_pop/sig_g2_pop_fips_186_3_P256 | 60 + .../sig_g2_pop_fips_186_3_P256_blst | 60 + .../sig_g2_pop/sig_g2_pop_fips_186_3_P384 | 60 + .../sig_g2_pop_fips_186_3_P384_blst | 60 + .../sig_g2_pop/sig_g2_pop_fips_186_3_P521 | 60 + .../sig_g2_pop_fips_186_3_P521_blst | 60 + .../sig_g2_pop/sig_g2_pop_rfc6979 | 34 + .../sig_g2_pop/sig_g2_pop_rfc6979_blst | 34 + .../test/test_vectors/test_vector_g1_2 | Bin 0 -> 384 bytes .../test/test_vectors/test_vector_g2_2 | Bin 0 -> 768 bytes src/lib_bls12_381_signature/test/utils.ml | 48 + src/lib_crypto/dune | 2 +- 260 files changed, 16985 insertions(+), 30 deletions(-) create mode 100644 opam/octez-bls12-381-signature.opam create mode 100644 src/lib_bls12_381_signature/bls12_381_signature.ml create mode 100644 src/lib_bls12_381_signature/bls12_381_signature.mli create mode 100644 src/lib_bls12_381_signature/blst_bindings_stubs.c create mode 100644 src/lib_bls12_381_signature/blst_bindings_stubs.js create mode 100644 src/lib_bls12_381_signature/dune create mode 100644 src/lib_bls12_381_signature/gen_wasm_needed_names.ml create mode 100644 src/lib_bls12_381_signature/needed-wasm-names create mode 100644 src/lib_bls12_381_signature/test/dune create mode 100644 src/lib_bls12_381_signature/test/test_aggregated_signature.ml create mode 100644 src/lib_bls12_381_signature/test/test_signature.ml create mode 100644 src/lib_bls12_381_signature/test/test_vectors/fft_test_vector_g1_2 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/fft_test_vector_g2_2 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g1/g1_fips_186_3_B233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g1/g1_fips_186_3_B283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g1/g1_fips_186_3_B409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g1/g1_fips_186_3_B571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g1/g1_fips_186_3_K233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g1/g1_fips_186_3_K283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g1/g1_fips_186_3_K409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g1/g1_fips_186_3_K571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g1/g1_fips_186_3_P224 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g1/g1_fips_186_3_P256 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g1/g1_fips_186_3_P384 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g1/g1_fips_186_3_P521 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g1/g1_rfc6979 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g2/g2_fips_186_3_B233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g2/g2_fips_186_3_B283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g2/g2_fips_186_3_B409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g2/g2_fips_186_3_B571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g2/g2_fips_186_3_K233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g2/g2_fips_186_3_K283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g2/g2_fips_186_3_K409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g2/g2_fips_186_3_K571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g2/g2_fips_186_3_P224 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g2/g2_fips_186_3_P256 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g2/g2_fips_186_3_P384 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g2/g2_fips_186_3_P521 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/hash_to_curve_g2/g2_rfc6979 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/ifft_test_vector_g1_2 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/ifft_test_vector_g2_2 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B233_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B283_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B409_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B571_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K233_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K283_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K409_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K571_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P224 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P224_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P256 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P256_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P384 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P384_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P521 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P521_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_rfc6979 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_rfc6979_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B233_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B283_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B409_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B571_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K233_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K409_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K571_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P224 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P224_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P256 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P256_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P384 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P384_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P521 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P521_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_rfc6979 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_rfc6979_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B233_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B283_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B409_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B571_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K233_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K283_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K409_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K571_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P224 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P224_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P256 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P256_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P384 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P384_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P521 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P521_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_rfc6979 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_rfc6979_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B233_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B283_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B409_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B571_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K233_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K283_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K409_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K571_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P224 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P224_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P256 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P256_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P384 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P384_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P521 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P521_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_rfc6979 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_rfc6979_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B233_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B283_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B409_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B571_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K233_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K283_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K409_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K571_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P224 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P224_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P256 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P256_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P384 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P384_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P521 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P521_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_rfc6979 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_rfc6979_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B233_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B283_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B409_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B571_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K233_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K409_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K571_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P224 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P224_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P256 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P256_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P384 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P384_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P521 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P521_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_rfc6979 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_rfc6979_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B233_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B283_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B409_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B571_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K233_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K409_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K571_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P224 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P224_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P256 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P256_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P384 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P384_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P521 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P521_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_rfc6979 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_rfc6979_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B233_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B283_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B409_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B571_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K233 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K233_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K283 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K409 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K409_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K571 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K571_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P224 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P224_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P256 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P256_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P384 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P384_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P521 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P521_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_rfc6979 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_rfc6979_blst create mode 100644 src/lib_bls12_381_signature/test/test_vectors/test_vector_g1_2 create mode 100644 src/lib_bls12_381_signature/test/test_vectors/test_vector_g2_2 create mode 100644 src/lib_bls12_381_signature/test/utils.ml diff --git a/.gitlab/ci/jobs/packaging/opam_package.yml b/.gitlab/ci/jobs/packaging/opam_package.yml index 8dab51dcc580..b87b45bb1acb 100644 --- a/.gitlab/ci/jobs/packaging/opam_package.yml +++ b/.gitlab/ci/jobs/packaging/opam_package.yml @@ -238,12 +238,14 @@ opam:octez-baker-PtMumbai: # Ignoring unreleased package octez-baker-alpha. -opam:octez-bls12-381-hash: +# Ignoring unreleased package octez-bls12-381-hash. + +opam:octez-bls12-381-signature: extends: - .opam_template - .rules_template__trigger_opam_batch_7 variables: - package: octez-bls12-381-hash + package: octez-bls12-381-signature opam:octez-client: extends: @@ -279,12 +281,7 @@ opam:octez-injector: variables: package: octez-injector -opam:octez-mec: - extends: - - .opam_template - - .rules_template__trigger_opam_batch_7 - variables: - package: octez-mec +# Ignoring unreleased package octez-mec. opam:octez-node: extends: @@ -300,12 +297,7 @@ opam:octez-node-config: variables: package: octez-node-config -opam:octez-polynomial: - extends: - - .opam_template - - .rules_template__trigger_opam_batch_7 - variables: - package: octez-polynomial +# Ignoring unreleased package octez-polynomial. opam:octez-protocol-compiler: extends: diff --git a/dune-project b/dune-project index 40cc671ed83b..3a3eaff03a50 100644 --- a/dune-project +++ b/dune-project @@ -11,6 +11,7 @@ (package (name octez-baker-PtMumbai)) (package (name octez-baker-alpha)) (package (name octez-bls12-381-hash)) +(package (name octez-bls12-381-signature)) (package (name octez-client)) (package (name octez-codec)) (package (name octez-crawler)) diff --git a/manifest/main.ml b/manifest/main.ml index f457ca432077..8f63f492663a 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -91,10 +91,6 @@ let bls12_381 = "bls12-381" version -let bls12_381_signature = - let version = V.exactly "1.0.0" in - external_lib ~js_compatible:true "bls12-381-signature" version - let camlzip = external_lib "camlzip" V.(at_least "1.11" && less_than "1.12") let caqti = external_lib "caqti" V.True @@ -836,6 +832,62 @@ let octez_rpc = ] ~js_compatible:true +let octez_bls12_381_signature = + public_lib + "octez-bls12-381-signature" + ~path:"src/lib_bls12_381_signature" + ~internal_name:"bls12_381_signature" + ~synopsis: + "Implementation of BLS signatures for the pairing-friendly curve \ + BLS12-381" + ~deps:[bls12_381] + ~modules:["bls12_381_signature"] + ~js_compatible:true + ~foreign_stubs: + { + language = C; + flags = ["-Wall"; "-Wextra"; ":standard"]; + names = ["blst_bindings_stubs"]; + } + ~c_library_flags:["-Wall"; "-Wextra"; ":standard"; "-lpthread"] + ~js_of_ocaml:[[S "javascript_files"; S "blst_bindings_stubs.js"]] + + ~linkall:true + ~dune: + Dune. + [ + targets_rule + ["needed-wasm-names"] + ~promote:true + ~action: + [ + S "with-outputs-to"; + S "%{targets}"; + [S "run"; S "./gen_wasm_needed_names.exe"; S "%{files}"]; + ] + ~deps:[[S ":files"; S "blst_bindings_stubs.js"]]; + ] + +(* TODO: dep_globs aren't added to the rules for JS tests *) +let _octez_bls12_381_signature_tests = + tests + ["test_aggregated_signature"; "test_signature"] + ~path:"src/lib_bls12_381_signature/test" + ~opam:"octez-bls12-381-signature" + ~modes:[Native; JS] + ~deps:[bls12_381; octez_bls12_381_signature; alcotest; integers_stubs_js] + ~dep_globs_rec:["test_vectors/*"] + ~js_compatible:true + +let _octez_bls12_381_signature_gen_wasm_needed_names = + private_exe + "gen_wasm_needed_names" + ~path:"src/lib_bls12_381_signature" + ~opam:"octez-bls12-381-signature" + ~bisect_ppx:No + ~modules:["gen_wasm_needed_names"] + ~deps:[re] + let octez_crypto = public_lib "tezos-crypto" @@ -856,7 +908,7 @@ let octez_crypto = zarith; zarith_stubs_js; bls12_381; - bls12_381_signature; + octez_bls12_381_signature; ] ~js_compatible:true diff --git a/opam/octez-bls12-381-hash.opam b/opam/octez-bls12-381-hash.opam index dd8b63ab8fae..bb12d2f191e2 100644 --- a/opam/octez-bls12-381-hash.opam +++ b/opam/octez-bls12-381-hash.opam @@ -10,7 +10,7 @@ license: "MIT" depends: [ "dune" { >= "3.0" } "ocaml" { >= "4.14" } - "bls12-381" { >= "6.0.1" & < "6.1.0" } + "bls12-381" { >= "6.1.0" & < "6.2.0" } "bisect_ppx" { >= "2.7.0" } "alcotest" { with-test & >= "1.5.0" } ] diff --git a/opam/octez-bls12-381-signature.opam b/opam/octez-bls12-381-signature.opam new file mode 100644 index 000000000000..3134fabfdc32 --- /dev/null +++ b/opam/octez-bls12-381-signature.opam @@ -0,0 +1,23 @@ +# This file was automatically generated, do not edit. +# Edit file manifest/main.ml instead. +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: ["Tezos devteam"] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "3.0" } + "ocaml" { >= "4.14" } + "bls12-381" { >= "6.1.0" & < "6.2.0" } + "alcotest" { with-test & >= "1.5.0" } + "integers_stubs_js" {with-test} + "re" { >= "1.9.0" } +] +build: [ + ["rm" "-r" "vendors"] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Implementation of BLS signatures for the pairing-friendly curve BLS12-381" diff --git a/opam/octez-mec.opam b/opam/octez-mec.opam index b734dfc00c3e..54f776b52627 100644 --- a/opam/octez-mec.opam +++ b/opam/octez-mec.opam @@ -11,7 +11,7 @@ depends: [ "dune" { >= "3.0" } "ocaml" { >= "4.14" } "alcotest" { >= "1.5.0" } - "bls12-381" { >= "6.0.1" & < "6.1.0" } + "bls12-381" { >= "6.1.0" & < "6.2.0" } "bigarray-compat" "eqaf" ] diff --git a/opam/octez-polynomial.opam b/opam/octez-polynomial.opam index 02da2b2aaecb..308caa38d65f 100644 --- a/opam/octez-polynomial.opam +++ b/opam/octez-polynomial.opam @@ -10,7 +10,7 @@ license: "MIT" depends: [ "dune" { >= "3.0" } "ocaml" { >= "4.14" } - "bls12-381" { >= "6.0.1" & < "6.1.0" } + "bls12-381" { >= "6.1.0" & < "6.2.0" } "bisect_ppx" { >= "2.7.0" } "zarith" { >= "1.12" & < "1.13" } "octez-mec" {with-test} diff --git a/opam/tezos-bls12-381-polynomial-internal.opam b/opam/tezos-bls12-381-polynomial-internal.opam index a2900ac81084..d597ac3e32b5 100644 --- a/opam/tezos-bls12-381-polynomial-internal.opam +++ b/opam/tezos-bls12-381-polynomial-internal.opam @@ -11,7 +11,7 @@ depends: [ "dune" { >= "3.0" } "ocaml" { >= "4.14" } "ppx_repr" { >= "0.6.0" } - "bls12-381" { >= "6.0.1" & < "6.1.0" } + "bls12-381" { >= "6.1.0" & < "6.2.0" } "bigstringaf" { >= "0.5.0" } "tezt" { with-test & >= "3.0.0" } "octez-alcotezt" {with-test} diff --git a/opam/tezos-crypto.opam b/opam/tezos-crypto.opam index 9453efa4d09c..c90f724a9d0d 100644 --- a/opam/tezos-crypto.opam +++ b/opam/tezos-crypto.opam @@ -21,8 +21,8 @@ depends: [ "aches" { >= "1.0.0" } "zarith" { >= "1.12" & < "1.13" } "zarith_stubs_js" - "bls12-381" { >= "6.0.1" & < "6.1.0" } - "bls12-381-signature" { = "1.0.0" } + "bls12-381" { >= "6.1.0" & < "6.2.0" } + "octez-bls12-381-signature" "tezt" { with-test & >= "3.0.0" } "octez-alcotezt" {with-test} "qcheck-alcotest" { with-test & >= "0.20" } diff --git a/opam/tezos-protocol-environment.opam b/opam/tezos-protocol-environment.opam index f1ba59104e1c..4fa17ffc4aa0 100644 --- a/opam/tezos-protocol-environment.opam +++ b/opam/tezos-protocol-environment.opam @@ -15,7 +15,7 @@ depends: [ "tezos-lwt-result-stdlib" "tezos-scoru-wasm" "data-encoding" { >= "0.7.1" & < "1.0.0" } - "bls12-381" { >= "6.0.1" & < "6.1.0" } + "bls12-381" { >= "6.1.0" & < "6.2.0" } "tezos-plonk" { >= "1.0.1" & < "2.0.0" } "zarith" { >= "1.12" & < "1.13" } "zarith_stubs_js" diff --git a/opam/virtual/octez-deps.opam b/opam/virtual/octez-deps.opam index 622115a0b321..a30c8a8906ee 100644 --- a/opam/virtual/octez-deps.opam +++ b/opam/virtual/octez-deps.opam @@ -18,8 +18,7 @@ depends: [ "bigstring" "bigstringaf" { >= "0.5.0" } "bisect_ppx" { >= "2.7.0" } - "bls12-381" { >= "6.0.1" & < "6.1.0" } - "bls12-381-signature" { = "1.0.0" } + "bls12-381" { >= "6.1.0" & < "6.2.0" } "camlzip" { >= "1.11" & < "1.12" } "caqti" "caqti-dynload" diff --git a/package.json b/package.json index 292a99e89045..0106d3dcd5b1 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "description": "n/a", "license": "n/a", "dependencies": { - "@nomadic-labs/ocaml-bls12-381": ">=6.0.1 <6.1.0", + "@nomadic-labs/ocaml-bls12-381": ">=6.1.0 <6.2.0", "@nomadic-labs/secp256k1-wasm": ">=0.4.0", "hacl-wasm": ">=1.2.0 <1.3.0" } diff --git a/src/lib_bls12_381_signature/bls12_381_signature.ml b/src/lib_bls12_381_signature/bls12_381_signature.ml new file mode 100644 index 000000000000..80a8d772c3c8 --- /dev/null +++ b/src/lib_bls12_381_signature/bls12_381_signature.ml @@ -0,0 +1,727 @@ +module CommonStubs = struct + type ctxt + + type scalar + + external allocate_g1_affine : unit -> Bls12_381.G1.affine + = "allocate_p1_affine_stubs" + + external allocate_g2_affine : unit -> Bls12_381.G2.affine + = "allocate_p2_affine_stubs" + + external uncompress_g1 : Bls12_381.G1.affine -> Bytes.t -> int + = "caml_blst_p1_uncompress_stubs" + + external uncompress_g2 : Bls12_381.G2.affine -> Bytes.t -> int + = "caml_blst_p2_uncompress_stubs" + + external allocate_scalar : unit -> scalar = "allocate_scalar_stubs" + + external scalar_of_fr : scalar -> Bls12_381.Fr.t -> int + = "caml_blst_scalar_from_fr_stubs" + + external scalar_to_bytes_le : Bytes.t -> scalar -> int + = "caml_blst_scalar_to_bytes_stubs" + + external keygen : + scalar -> + Bytes.t -> + Unsigned.Size_t.t -> + Bytes.t -> + Unsigned.Size_t.t -> + unit = "caml_bls12_381_signature_blst_signature_keygen_stubs" + + external pairing_init : bool -> Bytes.t -> Unsigned.Size_t.t -> ctxt + = "caml_bls12_381_signature_blst_pairing_init_stubs" + + external pairing_commit : ctxt -> int + = "caml_bls12_381_signature_blst_pairing_commit_stubs" + + external pairing_finalverify : ctxt -> bool + = "caml_bls12_381_signature_blst_pairing_finalverify_stubs" +end + +let check_unicity_lst list = + let hashtbl = Hashtbl.create (List.length list) in + List.for_all + (fun x -> + let res = not (Hashtbl.mem hashtbl x) in + Hashtbl.add hashtbl x 0 ; + res) + list + +let with_aggregation_ctxt ciphersuite f = + let ciphersuite_length = Bytes.length ciphersuite in + let ctxt = + CommonStubs.pairing_init + true + ciphersuite + (Unsigned.Size_t.of_int ciphersuite_length) + in + f ctxt + +type sk = CommonStubs.scalar + +let sk_size_in_bytes = Bls12_381.Fr.size_in_bytes + +let sk_of_bytes_exn bytes = + let buffer = CommonStubs.allocate_scalar () in + let exn = + Invalid_argument + "Input should be maximum 32 bytes, encoded the secret key in little \ + endian and must be smaller than the order of Bls12_381.Fr" + in + if Bytes.length bytes > 32 then raise exn + else + try + let sk = Bls12_381.Fr.of_bytes_exn bytes in + ignore @@ CommonStubs.scalar_of_fr buffer sk ; + buffer + with Bls12_381.Fr.Not_in_field _ -> raise exn + +let sk_of_bytes_opt bytes = + try Some (sk_of_bytes_exn bytes) with Invalid_argument _ -> None + +let sk_to_bytes sk = + let bytes = Bytes.make 32 '\000' in + ignore @@ CommonStubs.scalar_to_bytes_le bytes sk ; + bytes + +let generate_sk ?(key_info = Bytes.empty) ikm = + let buffer_scalar = CommonStubs.allocate_scalar () in + let key_info_length = Bytes.length key_info in + let ikm_length = Bytes.length ikm in + + (* https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04 + Section 2.3 - KeyGen + + For security, IKM MUST be infeasible to guess, e.g., generated by a trusted + source of randomness. IKM MUST be at least 32 bytes long, but it MAY be + longer. + + Also, blst_keygen returns a vector of zero (commit + 095a8c53787d6c91b725152ebfbbf33acf05a931) if ikm is less than 32 bytes *) + if ikm_length < 32 then + raise + (Invalid_argument + "generate_sk: ikm argument must be at least 32 bytes long") + else + CommonStubs.keygen + buffer_scalar + ikm + (Unsigned.Size_t.of_int ikm_length) + key_info + (Unsigned.Size_t.of_int key_info_length) ; + buffer_scalar + +module MinPk = struct + module Stubs = struct + external sk_to_pk : Bls12_381.G1.t -> CommonStubs.scalar -> int + = "caml_bls12_381_signature_blst_sk_to_pk_in_g1_stubs" + + external sign : + Bls12_381.G2.t -> Bls12_381.G2.t -> CommonStubs.scalar -> int + = "caml_bls12_381_signature_blst_sign_pk_in_g1_stubs" + + external pairing_chk_n_mul_n_aggr_pk_in_g1 : + CommonStubs.ctxt -> + Bls12_381.G1.affine -> + bool -> + Bls12_381.G2.affine option -> + bool -> + Bytes.t -> + Unsigned.Size_t.t -> + Bytes.t -> + Unsigned.Size_t.t -> + Bytes.t -> + Unsigned.Size_t.t -> + int + = "caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g1_stubs_bytecode" "caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g1_stubs" + end + + type pk = Bytes.t + + let pk_size_in_bytes = Bls12_381.G1.size_in_bytes / 2 + + let unsafe_pk_of_bytes pk_bytes = Bytes.copy pk_bytes + + let pk_of_bytes_exn pk_bytes = + let pk_opt = Bls12_381.G1.of_compressed_bytes_opt pk_bytes in + match pk_opt with + | None -> + raise + (Invalid_argument + (Printf.sprintf + "%s is not a valid public key" + Hex.(show (`Hex (Bytes.to_string pk_bytes))))) + | Some _ -> Bytes.copy pk_bytes + + let pk_of_bytes_opt pk_bytes = + let pk_opt = Bls12_381.G1.of_compressed_bytes_opt pk_bytes in + match pk_opt with None -> None | Some _ -> Some (Bytes.copy pk_bytes) + + let pk_to_bytes pk_bytes = Bytes.copy pk_bytes + + let derive_pk sk = + let buffer_g1 = Bls12_381.G1.(copy zero) in + ignore @@ Stubs.sk_to_pk buffer_g1 sk ; + Bls12_381.G1.to_compressed_bytes buffer_g1 + + type signature = Bytes.t + + let signature_size_in_bytes = Bls12_381.G2.size_in_bytes / 2 + + let unsafe_signature_of_bytes bytes = Bytes.copy bytes + + let signature_of_bytes_exn bytes = + let opt = Bls12_381.G2.of_compressed_bytes_opt bytes in + match opt with + | None -> + raise + (Invalid_argument + (Printf.sprintf + "%s is not a valid signature" + Hex.(show (`Hex (Bytes.to_string bytes))))) + | Some _ -> Bytes.copy bytes + + let signature_of_bytes_opt bytes = + let opt = Bls12_381.G2.of_compressed_bytes_opt bytes in + match opt with None -> None | Some _ -> Some (Bytes.copy bytes) + + let signature_to_bytes bytes = Bytes.copy bytes + + let core_sign sk message ciphersuite = + let hash = Bls12_381.G2.hash_to_curve message ciphersuite in + let buffer = Bls12_381.G2.(copy zero) in + ignore @@ Stubs.sign buffer hash sk ; + Bls12_381.G2.to_compressed_bytes buffer + + let core_verify pk msg signature_bytes ciphersuite = + with_aggregation_ctxt ciphersuite (fun ctxt -> + let msg_length = Bytes.length msg in + let unsafe_signature_affine = CommonStubs.allocate_g2_affine () in + let res_signature = + CommonStubs.uncompress_g2 unsafe_signature_affine signature_bytes + in + let unsafe_pk_affine = CommonStubs.allocate_g1_affine () in + let res_pk = CommonStubs.uncompress_g1 unsafe_pk_affine pk in + if res_signature = 0 && res_pk = 0 then + let res = + Stubs.pairing_chk_n_mul_n_aggr_pk_in_g1 + ctxt + unsafe_pk_affine + (* the pk argument might not be in the subgroup even if the + decompression went successfull. `true` means the function must + verify the point is in the prime subgroup. IMPORTANT: a test + called test_sign_and_verify_with_a_pk_not_in_the_subgroup does + exist. We can check the verification is performed correctly + because this call returns 3, neaning the point is not in the + subgroup. However, even when not verifying the point is in the + subgroup, the verification will fail. *) + true + (Some unsafe_signature_affine) + (* the signature argument might not be in the subgroup even if the + decompression went successfull. `true` means the function must + verify the point is in the prime subgroup. *) + true + (* scalar *) + Bytes.empty + Unsigned.Size_t.zero + (* msg *) + msg + (Unsigned.Size_t.of_int msg_length) + (* aug *) + Bytes.empty + Unsigned.Size_t.zero + in + if res = 0 then ( + ignore @@ CommonStubs.pairing_commit ctxt ; + CommonStubs.pairing_finalverify ctxt) + else false + else false) + + let aggregate_signature_opt signatures = + let rec aux signatures acc = + match signatures with + | [] -> Some acc + | signature :: signatures -> ( + let signature = Bls12_381.G2.of_compressed_bytes_opt signature in + match signature with + | None -> None + | Some signature -> + let acc = Bls12_381.G2.(add signature acc) in + aux signatures acc) + in + let res = aux signatures Bls12_381.G2.zero in + Option.map Bls12_381.G2.to_compressed_bytes res + + let core_aggregate_verify pks_with_msgs aggregated_signature ciphersuite = + let rec aux aggregated_signature pks_with_msgs ctxt = + match pks_with_msgs with + | (unsafe_pk_affine, msg) :: rest -> + let msg_length = Bytes.length msg in + (* sign the message *) + let res = + Stubs.pairing_chk_n_mul_n_aggr_pk_in_g1 + ctxt + unsafe_pk_affine + (* the signature argument might not be in the subgroup even if the + decompression went successfull. `true` means the function must + verify the point is in the prime subgroup. *) + true + aggregated_signature + (* IMPORTANT: does not check signature is a point on the curve and + in the subgroup, it is verified by of_compressed_bytes_opt + below. *) + false + (* scalar *) + Bytes.empty + Unsigned.Size_t.zero + (* msg *) + msg + (Unsigned.Size_t.of_int msg_length) + (* aug *) + Bytes.empty + Unsigned.Size_t.zero + in + if res = 0 then + (* signature: must be null except the first one *) + aux None rest ctxt + else false + | [] -> true + in + (* IMPORTANT: the verification the aggregated signature is in the subgroup + is performed here. *) + let aggregated_signature_opt = + Bls12_381.G2.of_compressed_bytes_opt aggregated_signature + in + (* Converts the pk received as bytes in points on the curve. There are no + checks about points belonging to the subgroup. It is verified when + calling the auxiliary function. *) + let pks = List.map fst pks_with_msgs in + let are_pks_on_curve = ref true in + let unsafe_pks_affine = + List.map + (fun pk_bytes -> + let pk_affine = CommonStubs.allocate_g1_affine () in + let res = CommonStubs.uncompress_g1 pk_affine pk_bytes in + are_pks_on_curve := res = 0 && !are_pks_on_curve ; + pk_affine) + pks + in + let pks_with_msgs = + List.map2 + (fun pk_affine (_, msg) -> (pk_affine, msg)) + unsafe_pks_affine + pks_with_msgs + in + if !are_pks_on_curve then + match aggregated_signature_opt with + | None -> false + | Some aggregated_signature -> + with_aggregation_ctxt ciphersuite (fun ctxt -> + let signature_affine = + Bls12_381.G2.affine_of_jacobian aggregated_signature + in + let res = aux (Some signature_affine) pks_with_msgs ctxt in + if res then ( + ignore @@ CommonStubs.pairing_commit ctxt ; + CommonStubs.pairing_finalverify ctxt) + else false) + else false + + module Basic = struct + let ciphersuite = + Bytes.of_string "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_NUL_" + + let sign sk message = core_sign sk message ciphersuite + + let verify pk msg signature = core_verify pk msg signature ciphersuite + + let aggregate_verify pks_with_msgs aggregated_signature = + let msgs = List.map snd pks_with_msgs in + if check_unicity_lst msgs then + core_aggregate_verify pks_with_msgs aggregated_signature ciphersuite + else raise (Invalid_argument "Messages must be distinct") + end + + module Aug = struct + let ciphersuite = + Bytes.of_string "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_AUG_" + + let sign sk msg = + let pk = derive_pk sk in + (* Important note: we concatenate with the compressed representation of + the point! *) + let msg = Bytes.concat Bytes.empty [pk; msg] in + core_sign sk msg ciphersuite + + let verify pk msg signature = + (* Important note: we concatenate with the compressed representation of + the point! *) + let msg = Bytes.concat Bytes.empty [pk; msg] in + core_verify pk msg signature ciphersuite + + let aggregate_verify pks_with_msgs aggregated_signature = + let pks_with_msgs = + List.map + (fun (pk, msg) -> (pk, Bytes.concat Bytes.empty [pk; msg])) + pks_with_msgs + in + core_aggregate_verify pks_with_msgs aggregated_signature ciphersuite + end + + module Pop = struct + type proof = Bytes.t + + let sign sk message = + let ciphersuite = + Bytes.of_string "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_" + in + core_sign sk message ciphersuite + + let verify pk msg signature = + let ciphersuite = + Bytes.of_string "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_" + in + core_verify pk msg signature ciphersuite + + let pop_prove sk = + let ciphersuite = + Bytes.of_string "BLS_POP_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_" + in + let pk = derive_pk sk in + core_sign sk pk ciphersuite + + let pop_verify pk signature = + let ciphersuite = + Bytes.of_string "BLS_POP_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_" + in + core_verify pk pk signature ciphersuite + + let aggregate_verify pks_with_pops msg aggregated_signature = + let pks_bytes = List.map fst pks_with_pops in + let pks_opts = List.map Bls12_381.G1.of_compressed_bytes_opt pks_bytes in + let pks_are_ok = List.for_all Option.is_some pks_opts in + if not pks_are_ok then false + else + let pks = List.map Option.get pks_opts in + let aggregated_pk = + List.fold_left Bls12_381.G1.add Bls12_381.G1.zero pks + in + let aggregated_pk = Bls12_381.G1.to_compressed_bytes aggregated_pk in + let signature_check = verify aggregated_pk msg aggregated_signature in + let pop_checks = + List.for_all + (fun (pk, signature) -> pop_verify pk signature) + pks_with_pops + in + pop_checks && signature_check + end +end + +module MinSig = struct + module Stubs = struct + external sk_to_pk : Bls12_381.G2.t -> CommonStubs.scalar -> int + = "caml_bls12_381_signature_blst_sk_to_pk_in_g2_stubs" + + external sign : + Bls12_381.G1.t -> Bls12_381.G1.t -> CommonStubs.scalar -> int + = "caml_bls12_381_signature_blst_sign_pk_in_g2_stubs" + + external pairing_chk_n_mul_n_aggr_pk_in_g2 : + CommonStubs.ctxt -> + Bls12_381.G2.affine -> + bool -> + Bls12_381.G1.affine option -> + bool -> + Bytes.t -> + Unsigned.Size_t.t -> + Bytes.t -> + Unsigned.Size_t.t -> + Bytes.t -> + Unsigned.Size_t.t -> + int + = "caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g2_stubs_bytecode" "caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g2_stubs" + end + + type pk = Bytes.t + + let pk_size_in_bytes = Bls12_381.G2.size_in_bytes / 2 + + let unsafe_pk_of_bytes pk_bytes = Bytes.copy pk_bytes + + let pk_of_bytes_exn pk_bytes = + let pk_opt = Bls12_381.G2.of_compressed_bytes_opt pk_bytes in + match pk_opt with + | None -> + raise + (Invalid_argument + (Printf.sprintf + "%s is not a valid public key" + Hex.(show (`Hex (Bytes.to_string pk_bytes))))) + | Some _ -> Bytes.copy pk_bytes + + let pk_of_bytes_opt pk_bytes = + let pk_opt = Bls12_381.G2.of_compressed_bytes_opt pk_bytes in + match pk_opt with None -> None | Some _ -> Some (Bytes.copy pk_bytes) + + let pk_to_bytes pk_bytes = Bytes.copy pk_bytes + + let derive_pk sk = + let buffer = Bls12_381.G2.(copy one) in + ignore @@ Stubs.sk_to_pk buffer sk ; + Bls12_381.G2.to_compressed_bytes buffer + + type signature = Bytes.t + + let signature_size_in_bytes = Bls12_381.G1.size_in_bytes / 2 + + let unsafe_signature_of_bytes bytes = Bytes.copy bytes + + let signature_of_bytes_exn bytes = + let opt = Bls12_381.G1.of_compressed_bytes_opt bytes in + match opt with + | None -> + raise + (Invalid_argument + (Printf.sprintf + "%s is not a valid signature" + Hex.(show (`Hex (Bytes.to_string bytes))))) + | Some _ -> Bytes.copy bytes + + let signature_of_bytes_opt bytes = + let opt = Bls12_381.G1.of_compressed_bytes_opt bytes in + match opt with None -> None | Some _ -> Some (Bytes.copy bytes) + + let signature_to_bytes bytes = Bytes.copy bytes + + let core_sign sk message ciphersuite = + let hash = Bls12_381.G1.hash_to_curve message ciphersuite in + let buffer = Bls12_381.G1.(copy one) in + ignore @@ Stubs.sign buffer hash sk ; + Bls12_381.G1.to_compressed_bytes buffer + + let core_verify pk msg signature_bytes ciphersuite = + with_aggregation_ctxt ciphersuite (fun ctxt -> + let msg_length = Bytes.length msg in + let unsafe_signature_affine = CommonStubs.allocate_g1_affine () in + let res_signature = + CommonStubs.uncompress_g1 unsafe_signature_affine signature_bytes + in + let unsafe_pk_affine = CommonStubs.allocate_g2_affine () in + let res_pk = CommonStubs.uncompress_g2 unsafe_pk_affine pk in + if res_signature = 0 && res_pk = 0 then + let res = + Stubs.pairing_chk_n_mul_n_aggr_pk_in_g2 + ctxt + unsafe_pk_affine + (* the pk argument might not be in the subgroup even if the + decompression went successfull. `true` means the function must + verify the point is in the prime subgroup. IMPORTANT: a test + called test_sign_and_verify_with_a_pk_not_in_the_subgroup does + exist. We can check the verification is performed correctly + because this call returns 3, neaning the point is not in the + subgroup. However, even when not verifying the point is in the + subgroup, the verification will fail. *) + true + (Some unsafe_signature_affine) + (* the signature argument might not be in the subgroup even if the + decompression went successfull. `true` means the function must + verify the point is in the prime subgroup. *) + true + (* scalar *) + Bytes.empty + Unsigned.Size_t.zero + (* msg *) + msg + (Unsigned.Size_t.of_int msg_length) + (* aug *) + Bytes.empty + Unsigned.Size_t.zero + in + if res = 0 then ( + ignore @@ CommonStubs.pairing_commit ctxt ; + CommonStubs.pairing_finalverify ctxt) + else false + else false) + + let aggregate_signature_opt signatures = + let rec aux signatures acc = + match signatures with + | [] -> Some acc + | signature :: signatures -> ( + let signature = Bls12_381.G1.of_compressed_bytes_opt signature in + match signature with + | None -> None + | Some signature -> + let acc = Bls12_381.G1.(add signature acc) in + aux signatures acc) + in + let res = aux signatures Bls12_381.G1.zero in + Option.map Bls12_381.G1.to_compressed_bytes res + + let core_aggregate_verify pks_with_msgs aggregated_signature ciphersuite = + let rec aux aggregated_signature pks_with_msgs ctxt = + match pks_with_msgs with + | (unsafe_pk_affine, msg) :: rest -> + let msg_length = Bytes.length msg in + (* sign the message *) + let res = + Stubs.pairing_chk_n_mul_n_aggr_pk_in_g2 + ctxt + unsafe_pk_affine + (* the signature argument might not be in the subgroup even if the + decompression went successfull. `true` means the function must + verify the point is in the prime subgroup. *) + true + aggregated_signature + (* IMPORTANT: does not check signature is a point on the curve and + in the subgroup, it is verified by of_compressed_bytes_opt + below. *) + false + (* scalar *) + Bytes.empty + Unsigned.Size_t.zero + (* msg *) + msg + (Unsigned.Size_t.of_int msg_length) + (* aug *) + Bytes.empty + Unsigned.Size_t.zero + in + if res = 0 then + (* signature: must be null except the first one *) + aux None rest ctxt + else false + | [] -> true + in + (* IMPORTANT: the verification the aggregated signature is in the subgroup + is performed here. *) + let aggregated_signature_opt = + Bls12_381.G1.of_compressed_bytes_opt aggregated_signature + in + (* Converts the pk received as bytes in points on the curve. There are no + checks about points belonging to the subgroup. It is verified when + calling the auxiliary function. *) + let pks = List.map fst pks_with_msgs in + let are_pks_on_curve = ref true in + let unsafe_pks_affine = + List.map + (fun pk_bytes -> + let pk_affine = CommonStubs.allocate_g2_affine () in + let res = CommonStubs.uncompress_g2 pk_affine pk_bytes in + are_pks_on_curve := res = 0 && !are_pks_on_curve ; + pk_affine) + pks + in + let pks_with_msgs = + List.map2 + (fun pk_affine (_, msg) -> (pk_affine, msg)) + unsafe_pks_affine + pks_with_msgs + in + if !are_pks_on_curve then + match aggregated_signature_opt with + | None -> false + | Some aggregated_signature -> + with_aggregation_ctxt ciphersuite (fun ctxt -> + let signature_affine = + Bls12_381.G1.affine_of_jacobian aggregated_signature + in + let res = aux (Some signature_affine) pks_with_msgs ctxt in + if res then ( + ignore @@ CommonStubs.pairing_commit ctxt ; + CommonStubs.pairing_finalverify ctxt) + else false) + else false + + module Basic = struct + let ciphersuite = + Bytes.of_string "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_NUL_" + + let sign sk message = core_sign sk message ciphersuite + + let verify pk msg signature = core_verify pk msg signature ciphersuite + + let aggregate_verify pks_with_msgs aggregated_signature = + let msgs = List.map snd pks_with_msgs in + if check_unicity_lst msgs then + core_aggregate_verify pks_with_msgs aggregated_signature ciphersuite + else raise (Invalid_argument "Messages must be distinct") + end + + module Aug = struct + let ciphersuite = + Bytes.of_string "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_AUG_" + + let sign sk msg = + let pk = derive_pk sk in + (* Important note: we concatenate with the compressed representation of + the point! *) + let msg = Bytes.concat Bytes.empty [pk; msg] in + core_sign sk msg ciphersuite + + let verify pk msg signature = + (* Important note: we concatenate with the compressed representation of + the point! *) + let msg = Bytes.concat Bytes.empty [pk; msg] in + core_verify pk msg signature ciphersuite + + let aggregate_verify pks_with_msgs aggregated_signature = + let pks_with_msgs = + List.map + (fun (pk, msg) -> (pk, Bytes.concat Bytes.empty [pk; msg])) + pks_with_msgs + in + core_aggregate_verify pks_with_msgs aggregated_signature ciphersuite + end + + module Pop = struct + type proof = Bytes.t + + let sign sk message = + let ciphersuite = + Bytes.of_string "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_" + in + core_sign sk message ciphersuite + + let verify pk msg signature = + let ciphersuite = + Bytes.of_string "BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_" + in + core_verify pk msg signature ciphersuite + + let pop_prove sk = + let ciphersuite = + Bytes.of_string "BLS_POP_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_" + in + let pk = derive_pk sk in + core_sign sk pk ciphersuite + + let pop_verify pk signature = + let ciphersuite = + Bytes.of_string "BLS_POP_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_" + in + core_verify pk pk signature ciphersuite + + let aggregate_verify pks_with_pops msg aggregated_signature = + let pks_bytes = List.map fst pks_with_pops in + let pks_opts = List.map Bls12_381.G2.of_compressed_bytes_opt pks_bytes in + let pks_are_ok = List.for_all Option.is_some pks_opts in + if not pks_are_ok then false + else + let pks = List.map Option.get pks_opts in + let aggregated_pk = + List.fold_left Bls12_381.G2.add Bls12_381.G2.zero pks + in + let aggregated_pk = Bls12_381.G2.to_compressed_bytes aggregated_pk in + let signature_check = verify aggregated_pk msg aggregated_signature in + let pop_checks = + List.for_all + (fun (pk, signature) -> pop_verify pk signature) + pks_with_pops + in + pop_checks && signature_check + end +end diff --git a/src/lib_bls12_381_signature/bls12_381_signature.mli b/src/lib_bls12_381_signature/bls12_381_signature.mli new file mode 100644 index 000000000000..a29bf3573329 --- /dev/null +++ b/src/lib_bls12_381_signature/bls12_381_signature.mli @@ -0,0 +1,394 @@ +(** Follow {{:https://tools.ietf.org/pdf/draft-irtf-cfrg-bls-signature-04.pdf} + the BLS signature draft of CFRG, version 4} *) + +(** Type of the secret keys. *) +type sk + +(** The size of a serialized value [sk] *) +val sk_size_in_bytes : int + +(** [sk_of_bytes_exn bs] attempts to deserialize [bs] into a secret key. [bs] + must be the little endian representation of the secret key. In this case, + secret keys are scalars of BLS12-381 and are encoded on 32 bytes. The + bytes sequence might be less of 32 bytes and in this case, the bytes + sequence is padded on the right by 0's. + + @raise Invalid_argument if the bytes sequence is longer than 32 bytes *) +val sk_of_bytes_exn : Bytes.t -> sk + +(** [sk_of_bytes_opt bs] is the same than {!sk_of_bytes_exn} but returns an + option instead of an exception. *) +val sk_of_bytes_opt : Bytes.t -> sk option + +(** [sk_to_bytes sk] serialises the secret key into the little endian + representation. *) +val sk_to_bytes : sk -> Bytes.t + +(** [generate_sk ?key_info ikm] generates a new (random) secret key. [ikm] + must be at least 32 bytes (otherwise, raise [Invalid_argument]). The + default value of [key_info] is the empty bytes sequence. *) +val generate_sk : ?key_info:Bytes.t -> Bytes.t -> sk + +(** BLS signatures instantiation minimizing the size of the public keys (48 + bytes) but use longer signatures (96 bytes). *) +module MinPk : sig + (** Type of the public keys *) + type pk + + (** The size of a serialized value [pk] *) + val pk_size_in_bytes : int + + (** The size of a serialized value [signature] *) + val signature_size_in_bytes : int + + (** Build a value of type {!pk} without performing any check on the input + (hence the unsafe prefix because it might not give a correct + inhabitant of the type [pk]). + It is safe to use this function when verifying a signature as the + signature function verifies if the point is in the prime subgroup. Using + {!unsafe_pk_of_bytes} removes a verification performed twice when used + {!pk_of_bytes_exn} or {!pk_of_bytes_opt}. + + The expected bytes format are the compressed form of a point on G1. *) + val unsafe_pk_of_bytes : Bytes.t -> pk + + (** Build a value of type [pk] safely, i.e. the function checks the bytes + given in parameters represents a point on the curve and in the prime + subgroup. Raise [Invalid_argument] if the bytes are not in the correct + format or does not represent a point in the prime subgroup. + + The expected bytes format are the compressed form of a point on G1. *) + val pk_of_bytes_exn : Bytes.t -> pk + + (** Build a value of type {!pk} safely, i.e. the function checks the bytes + given in parameters represents a point on the curve and in the prime + subgroup. Return [None] if the bytes are not in the correct format or + does not represent a point in the prime subgroup. + + The expected bytes format are the compressed form of a point on G1. *) + val pk_of_bytes_opt : Bytes.t -> pk option + + (** Returns a bytes representation of a value of type {!pk}. The output is + the compressed form of the point [Bls12_381.G1.t] the [pk] represents. *) + val pk_to_bytes : pk -> Bytes.t + + (** [derive_pk sk] derives the corresponding public key of [sk]. *) + val derive_pk : sk -> pk + + (** Type of the signatures *) + type signature + + (** Build a value of type {!signature} without performing any check on the + input (hence the unsafe prefix because it might not give a correct + inhabitant of the type [signature]). + It is safe to use this function when verifying a signature as the + signature function verifies if the point is in the prime subgroup. Using + {!unsafe_signature_of_bytes} removes a verification performed twice when + used {!signature_of_bytes_exn} or {!signature_of_bytes_opt}. + + The expected bytes format are the compressed form of a point on G2. *) + val unsafe_signature_of_bytes : Bytes.t -> signature + + (** Build a value of type {!signature} safely, i.e. the function checks the + bytes given in parameters represents a point on the curve and in the + prime subgroup. Raise [Invalid_argument] if the bytes are not in the + correct format or does not represent a point in the prime subgroup. + + The expected bytes format are the compressed form of a point on G2. *) + val signature_of_bytes_exn : Bytes.t -> signature + + (** Build a value of type {!signature} safely, i.e. the function checks the + bytes given in parameters represents a point on the curve and in the + prime subgroup. Return [None] if the bytes are not in the correct format + or does not represent a point in the prime subgroup. + + The expected bytes format are the compressed form of a point on G2. *) + val signature_of_bytes_opt : Bytes.t -> signature option + + (** Returns a bytes representation of a value of type [signature]. The + output is the compressed form of a point {!Bls12_381.G2.t} the signature + represents. *) + val signature_to_bytes : signature -> Bytes.t + + (** [aggregate_signature_opt signatures] aggregates the signatures + [signatures], following {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-2.8 + } section 2.8}. + Return [None] if [INVALID] is expected in the specification *) + val aggregate_signature_opt : signature list -> signature option + + (** Basic scheme described in + {{:https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.1} + section 3.1} + + In a basic scheme, rogue key attacks are handled by requiring all + messages signed by an aggregate signature to be distinct. This + requirement is enforced in the definition of AggregateVerify. + + {!Basic.sign} and {!Basic.verify} implements the algorithms {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-2.6 + } CoreSign} and {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-2.7} + CoreVerify}, respectively. *) + module Basic : sig + val sign : sk -> Bytes.t -> signature + + val verify : pk -> Bytes.t -> signature -> bool + + (** [aggregate_verify pks msg aggregated_signature] performs a aggregate + signature verification. + It implements the AggregateVerify algorithm specified in {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.1.1 + } section 3.1.1 }. Raise [Invalid_argument] if the messages are not + distinct. *) + val aggregate_verify : (pk * Bytes.t) list -> signature -> bool + end + + (** Augmentation scheme described in + {{:https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.2} + section 3.2} + + In a message augmentation scheme, signatures are generated over the + concatenation of the public key and the message, ensuring that messages + signed by different public keys are distinct. *) + module Aug : sig + (** [sign sk msg] implements the algorithm described in {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.2.1 + } section 3.2.1 } *) + val sign : sk -> Bytes.t -> signature + + (** [verify pk msg signature] implements the algorithm described in {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.2.2 + } section 3.2.2 } *) + val verify : pk -> Bytes.t -> signature -> bool + + (** [aggregate_verify pks msg aggregated_signature] performs a aggregate + signature verification. + It implements the AggregateVerify algorithm specified in {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.2.3 + } section 3.2.3 }*) + val aggregate_verify : (pk * Bytes.t) list -> signature -> bool + end + + (** Proof of possession scheme described in + {{:https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.3} + section 3.3} + + A proof of possession scheme uses a separate public key validation step, + called a proof of possession, to defend against rogue key attacks. This + enables an optimization to aggregate signature verification for the case + that all signatures are on the same message. *) + module Pop : sig + type proof = Bytes.t + + (** Equivalent to [core_sign] with the DST given in the specification + {{:https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-4.2.3} + in section 4.2.3}. *) + val sign : sk -> Bytes.t -> signature + + (** Equivalent to [core_verify] with the DST given in the specification + {{:https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-4.2.3} + in section 4.2.3}. *) + val verify : pk -> Bytes.t -> signature -> bool + + (** [pop_proof sk] implements + {{:https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.3.2} + section 3.3.2}. *) + val pop_prove : sk -> proof + + (** [pop_verify pk signature] implements + {{:https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.3.3} + section 3.3.3}. *) + val pop_verify : pk -> proof -> bool + + (** [aggregate_verify pks msg aggregated_signature] performs a aggregate + signature verification. It supposes the same message [msg] has been + signed. It implements the FastAggregateVerify algorithm specified in + {{:https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.3.4} + section 3.3.4}. *) + val aggregate_verify : (pk * proof) list -> Bytes.t -> signature -> bool + end +end + +(** BLS signatures instantiation minimizing the size of the signatures (48 + bytes) but use longer public keys (96 bytes). *) +module MinSig : sig + (** Type of the public keys *) + type pk + + (** The size of a serialized value [pk] *) + val pk_size_in_bytes : int + + (** Build a value of type [pk] without performing any check on the input + (hence the unsafe prefix because it might not give a correct inhabitant + of the type [pk]). + It is safe to use this function when verifying a signature as the + signature function verifies if the point is in the prime subgroup. Using + {!unsafe_pk_of_bytes} removes a verification performed twice when used + {!pk_of_bytes_exn} or {!pk_of_bytes_opt}. + + The expected bytes format are the compressed form of a point on G2. *) + val unsafe_pk_of_bytes : Bytes.t -> pk + + (** Build a value of type [pk] safely, i.e. the function checks the bytes + given in parameters represents a point on the curve and in the prime + subgroup. Raise [Invalid_argument] if the bytes are not in the correct + format or does not represent a point in the prime subgroup. + + The expected bytes format are the compressed form of a point on G2. *) + val pk_of_bytes_exn : Bytes.t -> pk + + (** Build a value of type [pk] safely, i.e. the function checks the bytes + given in parameters represents a point on the curve and in the prime + subgroup. Return [None] if the bytes are not in the correct format or + does not represent a point in the prime subgroup. + + The expected bytes format are the compressed form of a point on G2. *) + val pk_of_bytes_opt : Bytes.t -> pk option + + (** Returns a bytes representation of a value of type [pk]. The output is + the compressed form of the point [Bls12_381.Bls12_381.G2.t] the [pk] represents. *) + val pk_to_bytes : pk -> Bytes.t + + (** [derive_pk sk] derives the corresponding public key of [sk]. *) + val derive_pk : sk -> pk + + (** Type of the signatures *) + type signature + + (** The size of a serialized value [signature] *) + val signature_size_in_bytes : int + + (** Build a value of type [signature] without performing any check on the + input (hence the unsafe prefix because it might not give a correct + inhabitant of the type [signature]). + It is safe to use this function when verifying a signature as the + signature function verifies if the point is + in the prime subgroup. Using {!unsafe_signature_of_bytes} removes a + verification performed twice when + used {!signature_of_bytes_exn} or {!signature_of_bytes_opt}. + + The expected bytes format are the compressed form of a point on G1. *) + val unsafe_signature_of_bytes : Bytes.t -> signature + + (** Build a value of type [signature] safely, i.e. the function checks the + bytes given in parameters represents a point on the curve and in the + prime subgroup. Raise [Invalid_argument] if the bytes are not in the + correct format or does not represent a point in the prime subgroup. + + The expected bytes format are the compressed form of a point on G1. *) + val signature_of_bytes_exn : Bytes.t -> signature + + (** Build a value of type [signature] safely, i.e. the function checks the + bytes given in parameters represents a point on the curve and in the + prime subgroup. Return [None] if the bytes are not in the correct format + or does not represent a point in the prime subgroup. + + The expected bytes format are the compressed form of a point on G1. *) + val signature_of_bytes_opt : Bytes.t -> signature option + + (** Returns a bytes representation of a value of type [signature]. The + output is the compressed form a the point [Bls12_381.G1.t] the [signature] + represents. *) + val signature_to_bytes : signature -> Bytes.t + + (** [aggregate_signature_opt signatures] aggregates the signatures + [signatures], following {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-2.8 + } section 2.8 }. + Return [None] if [INVALID] is expected in the specification *) + val aggregate_signature_opt : signature list -> signature option + + (** Basic scheme described in + {{:https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.1} + section 3.1} + + In a basic scheme, rogue key attacks are handled by requiring all + messages signed by an aggregate signature to be distinct. This + requirement is enforced in the definition of AggregateVerify. + + {!Basic.sign} and {!Basic.verify} implements the algorithms {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-2.6 + } CoreSign} and {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-2.7} + CoreVerify}, respectively. *) + module Basic : sig + val sign : sk -> Bytes.t -> signature + + val verify : pk -> Bytes.t -> signature -> bool + + (** [aggregate_verify pks msg aggregated_signature] performs a aggregate + signature verification. + It implements the AggregateVerify algorithm specified in {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.1.1 + } section 3.1.1 }. Raise [Invalid_argument] if the messages are not + distinct. *) + val aggregate_verify : (pk * Bytes.t) list -> signature -> bool + end + + (** Augmentation scheme described in + {{:https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.2} + section 3.2} + + In a message augmentation scheme, signatures are generated over the + concatenation of the public key and the message, ensuring that messages + signed by different public keys are distinct. *) + module Aug : sig + (** [sign sk msg] implements the algorithm described in {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.2.1 + } section 3.2.1 } *) + val sign : sk -> Bytes.t -> signature + + (** [verify pk msg signature] implements the algorithm described in {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.2.2 + } section 3.2.2 } *) + val verify : pk -> Bytes.t -> signature -> bool + + (** [aggregate_verify pks msg aggregated_signature] performs a aggregate + signature verification. + It implements the FastAggregateVerify algorithm specified in {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.2.3 + } section 3.2.3 }*) + val aggregate_verify : (pk * Bytes.t) list -> signature -> bool + end + + (** Follow {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.3 + } section 3.3 }. + + A proof of possession scheme uses a separate public key validation step, + called a proof of possession, to defend against rogue key attacks. This + enables an optimization to aggregate signature verification for the case + that all signatures are on the same message. *) + module Pop : sig + type proof = Bytes.t + + (** Equivalent to [core_sign] with the DST given in the specification, {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-4.2.3} + section 4.2.3 } *) + val sign : sk -> Bytes.t -> signature + + (** Equivalent to [core_verify] with the DST given in the specification + {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-4.2.3} + section 4.2.3 } *) + val verify : pk -> Bytes.t -> signature -> bool + + (** [pop_proof sk] implements the algorithm described in {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.3.2 + } section 3.3.2 } *) + val pop_prove : sk -> proof + + (** [pop_verify pk proof] implements the algorithm described in {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.3.3 + } section 3.3.3 } *) + val pop_verify : pk -> proof -> bool + + (** [aggregate_verify pks msg aggregated_signature] performs a aggregate + signature verification. It supposes the same message [msg] has been + signed. It implements the FastAggregateVerify algorithm specified in {{: + https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#section-3.3.4 + } section 3.3.4 }*) + val aggregate_verify : (pk * proof) list -> Bytes.t -> signature -> bool + end +end diff --git a/src/lib_bls12_381_signature/blst_bindings_stubs.c b/src/lib_bls12_381_signature/blst_bindings_stubs.c new file mode 100644 index 000000000000..99bd81888a0b --- /dev/null +++ b/src/lib_bls12_381_signature/blst_bindings_stubs.c @@ -0,0 +1,251 @@ +#include "blst.h" +#include "blst_misc.h" +#include "caml_bls12_381_stubs.h" +#include "ocaml_integers.h" +#include +#include +#include +#include +#include +#include +#include + +// From ocaml-ctypes: +// https://github.com/ocamllabs/ocaml-ctypes/blob/9048ac78b885cc3debeeb020c56ea91f459a4d33/src/ctypes/ctypes_primitives.h#L110 +#if SIZE_MAX == UINT64_MAX +#define ctypes_size_t_val Uint64_val +#define ctypes_copy_size_t integers_copy_uint64 +#else +#error "No suitable OCaml type available for representing size_t values" +#endif + +// From ocaml/ocaml +// https://github.com/ocaml/ocaml/blob/aca84729327d327eaf6e82f3ae15d0a63953288e/runtime/caml/mlvalues.h#L401 +#if OCAML_VERSION < 412000 +#define Val_none Val_int(0) +#define Some_val(v) Field(v, 0) +#define Tag_some 0 +#define Is_none(v) ((v) == Val_none) +#define Is_some(v) Is_block(v) +#endif + +#define Blst_pairing_val(v) (*(blst_pairing **)Data_custom_val(v)) + +// For signatures +static void finalize_free_pairing(value v) { + byte *dst = (byte *)blst_pairing_get_dst(Blst_pairing_val(v)); + // See libblst/src/aggregate.c + if ((uintptr_t)dst != (uintptr_t)42) { + free(dst); + } + free(Blst_pairing_val(v)); +} + +static struct custom_operations blst_pairing_ops = { + "blst_pairing", + finalize_free_pairing, + custom_compare_default, + custom_hash_default, + custom_serialize_default, + custom_deserialize_default, + custom_compare_ext_default, + custom_fixed_length_default}; + +// Common to both instantiations +CAMLprim value caml_bls12_381_signature_blst_pairing_init_stubs( + value check, value dst, value dst_length) { + CAMLparam3(check, dst, dst_length); + CAMLlocal1(block); + size_t dst_length_c = ctypes_size_t_val(dst_length); + // See + // https://gitlab.com/nomadic-labs/cryptography/ocaml-bls12-381/-/merge_requests/195 + byte *dst_copy = malloc(sizeof(byte) * dst_length_c); + if (dst_copy == NULL) { + caml_raise_out_of_memory(); + } + memcpy(dst_copy, Bytes_val(dst), dst_length_c * sizeof(byte)); + void *p = calloc(1, blst_pairing_sizeof()); + if (p == NULL) { + free(dst_copy); + caml_raise_out_of_memory(); + } + size_t out_of_heap_memory_size = + blst_pairing_sizeof() + sizeof(byte) * dst_length_c; + block = caml_alloc_custom_mem(&blst_pairing_ops, sizeof(blst_pairing *), + out_of_heap_memory_size); + blst_pairing **d = (blst_pairing **)Data_custom_val(block); + *d = p; + blst_pairing_init(Blst_pairing_val(block), Bool_val(check), dst_copy, + dst_length_c); + CAMLreturn(block); +} + +CAMLprim value +caml_bls12_381_signature_blst_pairing_commit_stubs(value buffer) { + CAMLparam1(buffer); + blst_pairing_commit(Blst_pairing_val(buffer)); + CAMLreturn(CAML_BLS12_381_OUTPUT_SUCCESS); +} + +CAMLprim value +caml_bls12_381_signature_blst_pairing_finalverify_stubs(value buffer) { + CAMLparam1(buffer); + bool r = blst_pairing_finalverify(Blst_pairing_val(buffer), NULL); + CAMLreturn(Val_bool(r)); +} + +CAMLprim value caml_bls12_381_signature_blst_signature_keygen_stubs( + value buffer, value ikm, value ikm_length, value key_info, + value key_info_length) { + CAMLparam5(buffer, ikm, ikm_length, key_info, key_info_length); + blst_keygen(Blst_scalar_val(buffer), Bytes_val(ikm), + ctypes_size_t_val(ikm_length), Bytes_val(key_info), + ctypes_size_t_val(key_info_length)); + CAMLreturn(CAML_BLS12_381_OUTPUT_SUCCESS); +} + +// Pk in G1, Signature in G2 +CAMLprim value +caml_bls12_381_signature_blst_sk_to_pk_in_g1_stubs(value buffer, value scalar) { + CAMLparam2(buffer, scalar); + blst_sk_to_pk_in_g1(Blst_p1_val(buffer), Blst_scalar_val(scalar)); + CAMLreturn(CAML_BLS12_381_OUTPUT_SUCCESS); +} + +CAMLprim value caml_bls12_381_signature_blst_sign_pk_in_g1_stubs(value buffer, + value p, + value s) { + CAMLparam3(buffer, p, s); + blst_sign_pk_in_g1(Blst_p2_val(buffer), Blst_p2_val(p), Blst_scalar_val(s)); + CAMLreturn(CAML_BLS12_381_OUTPUT_SUCCESS); +} + +CAMLprim value caml_bls12_381_signature_blst_aggregate_signature_pk_in_g1_stubs( + value buffer, value g1, value g2, value msg, value msg_length, value aug, + value aug_length) { + CAMLparam5(buffer, g1, g2, msg, msg_length); + CAMLxparam2(aug, aug_length); + int r = blst_pairing_aggregate_pk_in_g1( + Blst_pairing_val(buffer), Blst_p1_affine_val(g1), Blst_p2_affine_val(g2), + Bytes_val(msg), ctypes_size_t_val(msg_length), Bytes_val(aug), + ctypes_size_t_val(aug_length)); + CAMLreturn(Val_int(r)); +} + +CAMLprim value +caml_bls12_381_signature_blst_aggregate_signature_pk_in_g1_stubs_bytecode( + value *argv, int argn) { + if (argn != 7) { + caml_failwith("caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_" + "in_g2_stubs_bytecode: wrong value argn"); + } + return caml_bls12_381_signature_blst_aggregate_signature_pk_in_g1_stubs( + argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]); +} + +CAMLprim value +caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g1_stubs( + value buffer, value pk, value check_pk, value signature, + value check_signature, value scalar, value nbits, value msg, + value msg_length, value aug, value aug_length) { + CAMLparam5(buffer, pk, check_pk, signature, check_signature); + CAMLxparam5(scalar, nbits, msg, msg_length, aug); + CAMLxparam1(aug_length); + blst_p2_affine *signature_c; + if (Is_none(signature)) { + signature_c = NULL; + } else { + signature_c = Blst_p2_affine_val(Some_val(signature)); + } + int r = blst_pairing_chk_n_mul_n_aggr_pk_in_g1( + Blst_pairing_val(buffer), Blst_p1_affine_val(pk), Bool_val(check_pk), + signature_c, Bool_val(check_signature), Bytes_val(scalar), + ctypes_size_t_val(nbits), Bytes_val(msg), ctypes_size_t_val(msg_length), + Bytes_val(aug), ctypes_size_t_val(aug_length)); + CAMLreturn(Val_int(r)); +} + +CAMLprim value +caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g1_stubs_bytecode( + value *argv, int argn) { + if (argn != 11) { + caml_failwith("caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_" + "in_g2_stubs_bytecode: wrong value argn"); + } + return caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g1_stubs( + argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], + argv[8], argv[9], argv[10]); +} + +// Pk in G2, signature in G1 +CAMLprim value +caml_bls12_381_signature_blst_sk_to_pk_in_g2_stubs(value buffer, value scalar) { + CAMLparam2(buffer, scalar); + blst_sk_to_pk_in_g2(Blst_p2_val(buffer), Blst_scalar_val(scalar)); + CAMLreturn(CAML_BLS12_381_OUTPUT_SUCCESS); +} + +CAMLprim value caml_bls12_381_signature_blst_sign_pk_in_g2_stubs(value buffer, + value p, + value s) { + CAMLparam3(buffer, p, s); + blst_sign_pk_in_g2(Blst_p1_val(buffer), Blst_p1_val(p), Blst_scalar_val(s)); + CAMLreturn(CAML_BLS12_381_OUTPUT_SUCCESS); +} + +CAMLprim value caml_bls12_381_signature_blst_aggregate_signature_pk_in_g2_stubs( + value buffer, value g1, value g2, value msg, value msg_length, value aug, + value aug_length) { + CAMLparam5(buffer, g1, g2, msg, msg_length); + CAMLxparam2(aug, aug_length); + int r = blst_pairing_aggregate_pk_in_g2( + Blst_pairing_val(buffer), Blst_p2_affine_val(g1), Blst_p1_affine_val(g2), + Bytes_val(msg), ctypes_size_t_val(msg_length), Bytes_val(aug), + ctypes_size_t_val(aug_length)); + CAMLreturn(Val_int(r)); +} + +CAMLprim value +caml_bls12_381_signature_blst_aggregate_signature_pk_in_g2_stubs_bytecode( + value *argv, int argn) { + if (argn != 7) { + caml_failwith("caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_" + "in_g2_stubs_bytecode: wrong value argn"); + } + return caml_bls12_381_signature_blst_aggregate_signature_pk_in_g2_stubs( + argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]); +} + +CAMLprim value +caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g2_stubs( + value buffer, value pk, value check_pk, value signature, + value check_signature, value scalar, value nbits, value msg, + value msg_length, value aug, value aug_length) { + CAMLparam5(buffer, pk, check_pk, signature, check_signature); + CAMLxparam5(scalar, nbits, msg, msg_length, aug); + CAMLxparam1(aug_length); + blst_p1_affine *signature_c; + if (Is_none(signature)) { + signature_c = NULL; + } else { + signature_c = Blst_p1_affine_val(Some_val(signature)); + } + int r = blst_pairing_chk_n_mul_n_aggr_pk_in_g2( + Blst_pairing_val(buffer), Blst_p2_affine_val(pk), Bool_val(check_pk), + signature_c, Bool_val(check_signature), Bytes_val(scalar), + ctypes_size_t_val(nbits), Bytes_val(msg), ctypes_size_t_val(msg_length), + Bytes_val(aug), ctypes_size_t_val(aug_length)); + CAMLreturn(Val_int(r)); +} + +CAMLprim value +caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g2_stubs_bytecode( + value *argv, int argn) { + if (argn != 11) { + caml_failwith("caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_" + "in_g2_stubs_bytecode: wrong value argn"); + } + return caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g2_stubs( + argv[0], argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], + argv[8], argv[9], argv[10]); +} diff --git a/src/lib_bls12_381_signature/blst_bindings_stubs.js b/src/lib_bls12_381_signature/blst_bindings_stubs.js new file mode 100644 index 000000000000..53360a74f845 --- /dev/null +++ b/src/lib_bls12_381_signature/blst_bindings_stubs.js @@ -0,0 +1,373 @@ +// Fr +//Provides: Blst_pairing_val +function Blst_pairing_val(v) { + return v.v; +} + +//Provides: blst_pairing_sizeof +//Requires: wasm_call +function blst_pairing_sizeof() { + return wasm_call('_blst_pairing_sizeof'); +} + +//Provides: Blst_pairing +//Requires: blst_pairing_sizeof +//Requires: bls_allocate_mlbytes, bls_free +if (typeof globalThis.FinalizationRegistry === 'function') { + var blst_pairing_finalizer = new globalThis.FinalizationRegistry(bls_free); +} else { + var blst_pairing_finalizer = null; +} +function Blst_pairing(dst) { + this.v = new globalThis.Uint8Array(blst_pairing_sizeof()); + this.dst = bls_allocate_mlbytes(dst); + if (blst_pairing_finalizer) blst_pairing_finalizer.register(this.v, this.dst); +} + +//Provides: caml_bls12_381_signature_blst_pairing_init_stubs +//Requires: wasm_call +//Requires: Blst_pairing_val +//Requires: integers_int32_of_uint32 +//Requires: Blst_pairing +function caml_bls12_381_signature_blst_pairing_init_stubs(check, dst, dst_length) { + var b = new Blst_pairing(dst); + wasm_call( + '_blst_pairing_init', + Blst_pairing_val(b), + check, + b.dst, + integers_int32_of_uint32(dst_length) + ); + return b; +} + +//Provides: caml_bls12_381_signature_blst_pairing_commit_stubs +//Requires: wasm_call +//Requires: Blst_pairing_val +function caml_bls12_381_signature_blst_pairing_commit_stubs(buffer) { + wasm_call('_blst_pairing_commit', Blst_pairing_val(buffer)); + return 0; +} + +//Provides: caml_bls12_381_signature_blst_pairing_finalverify_stubs +//Requires: wasm_call +//Requires: Blst_pairing_val +function caml_bls12_381_signature_blst_pairing_finalverify_stubs(buffer) { + var r = wasm_call( + '_blst_pairing_finalverify', + Blst_pairing_val(buffer), + null + ); + return r ? 1 : 0; +} + +//Provides: caml_bls12_381_signature_blst_signature_keygen_stubs +//Requires: wasm_call +//Requires: Blst_scalar_val +//Requires: integers_int32_of_uint32 +function caml_bls12_381_signature_blst_signature_keygen_stubs( + buffer, + ikm, + ikm_length, + key_info, + key_info_length +) { + wasm_call( + '_blst_keygen', + Blst_scalar_val(buffer), + ikm, + integers_int32_of_uint32(ikm_length), + key_info, + integers_int32_of_uint32(key_info_length) + ); + return 0; +} + +// Pk in G1, Signature in G2 + +//Provides: caml_bls12_381_signature_blst_sk_to_pk_in_g1_stubs +//Requires: wasm_call +//Requires: Blst_p1_val, Blst_scalar_val +function caml_bls12_381_signature_blst_sk_to_pk_in_g1_stubs(buffer, scalar) { + wasm_call( + '_blst_sk_to_pk_in_g1', + Blst_p1_val(buffer), + Blst_scalar_val(scalar) + ); + return 0; +} + +//Provides: caml_bls12_381_signature_blst_sign_pk_in_g1_stubs +//Requires: wasm_call +//Requires: Blst_p2_val, Blst_scalar_val +function caml_bls12_381_signature_blst_sign_pk_in_g1_stubs(buffer, p, s) { + wasm_call( + '_blst_sign_pk_in_g1', + Blst_p2_val(buffer), + Blst_p2_val(p), + Blst_scalar_val(s) + ); + return 0; +} + +//Provides: caml_bls12_381_signature_blst_aggregate_signature_pk_in_g1_stubs +//Requires: wasm_call +//Requires: Blst_pairing_val, Blst_p1_affine_val, Blst_p2_affine_val +//Requires: integers_int32_of_uint32 +function caml_bls12_381_signature_blst_aggregate_signature_pk_in_g1_stubs( + buffer, + g1, + g2, + msg, + msg_length, + aug, + aug_length +) { + var r /* int */ = wasm_call( + '_blst_pairing_aggregate_pk_in_g1', + Blst_pairing_val(buffer), + Blst_p1_affine_val(g1), + Blst_p2_affine_val(g2), + msg, + integers_int32_of_uint32(msg_length), + aug, + integers_int32_of_uint32(aug_length) + ); + return r; +} + +//Provides: caml_bls12_381_signature_blst_aggregate_signature_pk_in_g1_stubs_bytecode +//Requires: caml_bls12_381_signature_blst_aggregate_signature_pk_in_g1_stubs +function caml_bls12_381_signature_blst_aggregate_signature_pk_in_g1_stubs_bytecode( + buffer, + g1, + g2, + msg, + msg_length, + aug, + aug_length +) { + return caml_bls12_381_signature_blst_aggregate_signature_pk_in_g1_stubs( + buffer, + g1, + g2, + msg, + msg_length, + aug, + aug_length + ); +} + +//Provides: caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g1_stubs +//Requires: wasm_call +//Requires: Blst_pairing_val, Blst_p1_affine_val, Blst_p2_affine_val +//Requires: integers_int32_of_uint32 +function caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g1_stubs( + buffer, + pk, + check_pk, + signature, + check_signature, + scalar, + nbits, + msg, + msg_length, + aug, + aug_length +) { + var signature_c; + if (signature == 0) { + signature_c = null; + } else { + signature_c = Blst_p2_affine_val(signature[1]); + } + var r /* int */ = wasm_call( + '_blst_pairing_chk_n_mul_n_aggr_pk_in_g1', + Blst_pairing_val(buffer), + Blst_p1_affine_val(pk), + check_pk, + signature_c, + check_signature, + scalar, + integers_int32_of_uint32(nbits), + msg, + integers_int32_of_uint32(msg_length), + aug, + integers_int32_of_uint32(aug_length) + ); + return r; +} + +//Provides: caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g1_stubs_bytecode +//Requires: caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g1_stubs +function caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g1_stubs_bytecode( + buffer, + pk, + check_pk, + signature, + check_signature, + scalar, + nbits, + msg, + msg_length, + aug, + aug_length +) { + return caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g1_stubs( + buffer, + pk, + check_pk, + signature, + check_signature, + scalar, + nbits, + msg, + msg_length, + aug, + aug_length + ); +} + +// Pk in G2, signature in G1 + +//Provides: caml_bls12_381_signature_blst_sk_to_pk_in_g2_stubs +//Requires: wasm_call +//Requires: Blst_p2_val, Blst_scalar_val +function caml_bls12_381_signature_blst_sk_to_pk_in_g2_stubs(buffer, scalar) { + wasm_call( + '_blst_sk_to_pk_in_g2', + Blst_p2_val(buffer), + Blst_scalar_val(scalar) + ); + return 0; +} + +//Provides: caml_bls12_381_signature_blst_sign_pk_in_g2_stubs +//Requires: wasm_call +//Requires: Blst_p1_val, Blst_scalar_val +function caml_bls12_381_signature_blst_sign_pk_in_g2_stubs(buffer, p, s) { + wasm_call( + '_blst_sign_pk_in_g2', + Blst_p1_val(buffer), + Blst_p1_val(p), + Blst_scalar_val(s) + ); + return 0; +} + +//Provides: caml_bls12_381_signature_blst_aggregate_signature_pk_in_g2_stubs +//Requires: wasm_call +//Requires: Blst_pairing_val, Blst_p2_affine_val, Blst_p1_affine_val +//Requires: integers_int32_of_uint32 +function caml_bls12_381_signature_blst_aggregate_signature_pk_in_g2_stubs( + buffer, + g1, + g2, + msg, + msg_length, + aug, + aug_length +) { + var r = wasm_call( + '_blst_pairing_aggregate_pk_in_g2', + Blst_pairing_val(buffer), + Blst_p2_affine_val(g1), + Blst_p1_affine_val(g2), + msg, + integers_int32_of_uint32(msg_length), + aug, + integers_int32_of_uint32(aug_length) + ); + return r; +} + +//Provides: caml_bls12_381_signature_blst_aggregate_signature_pk_in_g2_stubs_bytecode +//Requires: caml_bls12_381_signature_blst_aggregate_signature_pk_in_g2_stubs +function caml_bls12_381_signature_blst_aggregate_signature_pk_in_g2_stubs_bytecode( + buffer, + g1, + g2, + msg, + msg_length, + aug, + aug_length +) { + return caml_bls12_381_signature_blst_aggregate_signature_pk_in_g2_stubs( + buffer, + g1, + g2, + msg, + msg_length, + aug, + aug_length + ); +} +//Provides: caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g2_stubs +//Requires: wasm_call +//Requires: Blst_pairing_val, Blst_p2_affine_val +//Requires: Blst_p1_affine_val, Blst_p1_affine +//Requires: integers_int32_of_uint32 +function caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g2_stubs( + buffer, + pk, + check_pk, + signature, + check_signature, + scalar, + nbits, + msg, + msg_length, + aug, + aug_length +) { + var signature_c = new Blst_p1_affine(); + if (signature == 0) { + signature_c = null; + } else { + signature_c = Blst_p1_affine_val(signature[1]); + } + var r = wasm_call( + '_blst_pairing_chk_n_mul_n_aggr_pk_in_g2', + Blst_pairing_val(buffer), + Blst_p2_affine_val(pk), + check_pk, + signature_c, + check_signature, + scalar, + integers_int32_of_uint32(nbits), + msg, + integers_int32_of_uint32(msg_length), + aug, + integers_int32_of_uint32(aug_length) + ); + return r; +} +//Provides: caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g2_stubs_bytecode +//Requires: caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g2_stubs +function caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g2_stubs_bytecode( + buffer, + pk, + check_pk, + signature, + check_signature, + scalar, + nbits, + msg, + msg_length, + aug, + aug_length +) { + return caml_bls12_381_signature_blst_pairing_chk_n_mul_n_aggr_pk_in_g2_stubs( + buffer, + pk, + check_pk, + signature, + check_signature, + scalar, + nbits, + msg, + msg_length, + aug, + aug_length + ); +} diff --git a/src/lib_bls12_381_signature/dune b/src/lib_bls12_381_signature/dune new file mode 100644 index 000000000000..09230daba0d2 --- /dev/null +++ b/src/lib_bls12_381_signature/dune @@ -0,0 +1,32 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(env (_ (env-vars (NODE_PRELOAD ocaml-bls12-381)))) + +(library + (name bls12_381_signature) + (public_name octez-bls12-381-signature) + (instrumentation (backend bisect_ppx)) + (libraries + bls12-381) + (js_of_ocaml (javascript_files blst_bindings_stubs.js)) + (library_flags (:standard -linkall)) + (modules bls12_381_signature) + (foreign_stubs + (language c) + (flags (-Wall -Wextra :standard)) + (names blst_bindings_stubs)) + (c_library_flags (-Wall -Wextra :standard -lpthread))) + +(rule + (targets needed-wasm-names) + (mode promote) + (deps (:files blst_bindings_stubs.js)) + (action + (with-outputs-to %{targets} (run ./gen_wasm_needed_names.exe %{files})))) + +(executable + (name gen_wasm_needed_names) + (libraries + re) + (modules gen_wasm_needed_names)) diff --git a/src/lib_bls12_381_signature/gen_wasm_needed_names.ml b/src/lib_bls12_381_signature/gen_wasm_needed_names.ml new file mode 100644 index 000000000000..e912aa9f0455 --- /dev/null +++ b/src/lib_bls12_381_signature/gen_wasm_needed_names.ml @@ -0,0 +1,33 @@ +(* This collects all the wasm function names that are used in the js_of_ocaml stubs. + * We use this to make sure they are all properly exported in wasm. + * See the test in the dune file. *) + +let process_file f = + let ic = open_in f in + let len = in_channel_length ic in + let content = really_input_string ic len in + let re = + Re.( + compile + (seq + [ + str "wasm_call"; + rep space; + str "("; + rep space; + str "'"; + group (rep1 wordc); + rep space; + str "'"; + ])) + in + let groups = Re.all re content in + List.map (fun g -> Re.Group.get g 1) groups + +let () = + match Array.to_list Sys.argv with + | [] | [_] -> exit 1 + | _ :: rest -> + let call_wasm = List.concat_map process_file rest in + let all = "_malloc" :: "_free" :: call_wasm in + all |> List.sort_uniq (fun a b -> compare a b) |> List.iter print_endline diff --git a/src/lib_bls12_381_signature/needed-wasm-names b/src/lib_bls12_381_signature/needed-wasm-names new file mode 100644 index 000000000000..f67891daf0a4 --- /dev/null +++ b/src/lib_bls12_381_signature/needed-wasm-names @@ -0,0 +1,15 @@ +_blst_keygen +_blst_pairing_aggregate_pk_in_g1 +_blst_pairing_aggregate_pk_in_g2 +_blst_pairing_chk_n_mul_n_aggr_pk_in_g1 +_blst_pairing_chk_n_mul_n_aggr_pk_in_g2 +_blst_pairing_commit +_blst_pairing_finalverify +_blst_pairing_init +_blst_pairing_sizeof +_blst_sign_pk_in_g1 +_blst_sign_pk_in_g2 +_blst_sk_to_pk_in_g1 +_blst_sk_to_pk_in_g2 +_free +_malloc diff --git a/src/lib_bls12_381_signature/test/dune b/src/lib_bls12_381_signature/test/dune new file mode 100644 index 000000000000..cf31ceb9a953 --- /dev/null +++ b/src/lib_bls12_381_signature/test/dune @@ -0,0 +1,38 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(env (_ (env-vars (NODE_PRELOAD ocaml-bls12-381)))) + +(executables + (names test_aggregated_signature test_signature) + (modes native js) + (libraries + bls12-381 + octez-bls12-381-signature + alcotest + integers_stubs_js) + (js_of_ocaml)) + +(rule + (alias runtest) + (package octez-bls12-381-signature) + (deps (glob_files_rec test_vectors/*)) + (action (run %{dep:./test_aggregated_signature.exe}))) + +(rule + (alias runtest) + (package octez-bls12-381-signature) + (deps (glob_files_rec test_vectors/*)) + (action (run %{dep:./test_signature.exe}))) + +(rule + (alias runtest_js) + (package octez-bls12-381-signature) + (deps (glob_files_rec test_vectors/*)) + (action (run node %{dep:./test_aggregated_signature.bc.js}))) + +(rule + (alias runtest_js) + (package octez-bls12-381-signature) + (deps (glob_files_rec test_vectors/*)) + (action (run node %{dep:./test_signature.bc.js}))) diff --git a/src/lib_bls12_381_signature/test/test_aggregated_signature.ml b/src/lib_bls12_381_signature/test/test_aggregated_signature.ml new file mode 100644 index 000000000000..49f4e3019a96 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_aggregated_signature.ml @@ -0,0 +1,467 @@ +open Utils + +let () = Random.self_init () + +module type SIGNATURE_INSTANTIATION = module type of Bls12_381_signature.MinPk + +module MakeAggregatedSignatureTest (SignatureM : SIGNATURE_INSTANTIATION) = +struct + module type SIG_SCHEME = sig + val sign : Bls12_381_signature.sk -> Bytes.t -> SignatureM.signature + + (* val verify : SignatureM.pk -> Bytes.t -> SignatureM.signature -> bool *) + + val aggregate_verify : + (SignatureM.pk * Bytes.t) list -> SignatureM.signature -> bool + end + + module MakeProperties (Scheme : sig + include SIG_SCHEME + + val name : string + end) = + struct + let test_sign_and_verify_correct_signature_with_correct_pks_and_msgs () = + let random_values = + List.init + (1 + Random.int 10) + (fun _ -> + let msg = generate_random_bytes (1 + Random.int 512) in + let ikm = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let pk = SignatureM.derive_pk sk in + let signature = Scheme.sign sk msg in + (pk, msg, signature)) + in + let signatures = List.map (fun (_, _, s) -> s) random_values in + let pks_with_msgs = + List.map (fun (pk, msg, _) -> (pk, msg)) random_values + in + let aggregated_signatures = + Option.get (SignatureM.aggregate_signature_opt signatures) + in + assert (Scheme.aggregate_verify pks_with_msgs aggregated_signatures) + + let test_sign_and_verify_correct_signature_with_correct_pks_and_some_incorrect_msgs + () = + let random_values = + List.init + (2 + Random.int 10) + (fun i -> + let msg = generate_random_bytes (1 + Random.int 512) in + let msg' = + if i mod 2 = 0 then msg + else generate_random_bytes (1 + Random.int 512) + in + let ikm = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let pk = SignatureM.derive_pk sk in + let signature = Scheme.sign sk msg in + (pk, msg', signature)) + in + let signatures = List.map (fun (_, _, s) -> s) random_values in + let pks_with_msgs = + List.map (fun (pk, msg, _) -> (pk, msg)) random_values + in + let aggregated_signatures = + Option.get (SignatureM.aggregate_signature_opt signatures) + in + assert (not (Scheme.aggregate_verify pks_with_msgs aggregated_signatures)) + + let test_sign_and_verify_correct_signature_with_some_incorrect_pks_and_correct_msgs + () = + let random_values = + List.init + (2 + Random.int 10) + (fun i -> + let msg = generate_random_bytes (1 + Random.int 512) in + let ikm = generate_random_bytes 32 in + let ikm' = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let pk = SignatureM.derive_pk sk in + let pk' = + if i mod 2 = 0 then pk + else SignatureM.(derive_pk (Bls12_381_signature.generate_sk ikm')) + in + let signature = Scheme.sign sk msg in + (pk', msg, signature)) + in + let signatures = List.map (fun (_, _, s) -> s) random_values in + let pks_with_msgs = + List.map (fun (pk, msg, _) -> (pk, msg)) random_values + in + let aggregated_signatures = + Option.get (SignatureM.aggregate_signature_opt signatures) + in + assert (not (Scheme.aggregate_verify pks_with_msgs aggregated_signatures)) + + let get_tests () = + let open Alcotest in + ( Printf.sprintf "Properties for %s" Scheme.name, + [ + test_case + "Sign and verify corret signature with correct pks and msgs" + `Quick + (Utils.repeat + 10 + test_sign_and_verify_correct_signature_with_correct_pks_and_msgs); + test_case + "Sign and verify corret signature with correct pks and some \ + incorrect msgs" + `Quick + (Utils.repeat + 10 + test_sign_and_verify_correct_signature_with_correct_pks_and_some_incorrect_msgs); + test_case + "Sign and verify corret signature with some incorrect pks and \ + correct msgs" + `Quick + (Utils.repeat + 10 + test_sign_and_verify_correct_signature_with_some_incorrect_pks_and_correct_msgs); + ] ) + end + + module BasicProperties = struct + include MakeProperties (struct + include SignatureM.Basic + + let name = "Basic" + end) + + let test_verify_not_distinct_messages_should_raise_invalid_argument () = + let n = 2 + Random.int 10 in + let msg = generate_random_bytes (1 + Random.int 512) in + let pks_with_sigs = + List.init n (fun _ -> + let ikm = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let pk = SignatureM.derive_pk sk in + let signature = SignatureM.Basic.sign sk msg in + (pk, signature)) + in + let pks_with_msgs = List.map (fun (pk, _) -> (pk, msg)) pks_with_sigs in + let aggregated_signature = + Option.get + (SignatureM.aggregate_signature_opt (List.map snd pks_with_sigs)) + in + ignore + @@ Alcotest.check_raises + "" + (Invalid_argument "Messages must be distinct") + (fun () -> + ignore + @@ SignatureM.Basic.aggregate_verify + pks_with_msgs + aggregated_signature) + + let get_tests () = + let open Alcotest in + let specific_tests = + [ + test_case + "Verify signatures with the same message" + `Quick + test_verify_not_distinct_messages_should_raise_invalid_argument; + ] + in + let desc, tests = get_tests () in + (desc, List.concat [specific_tests; tests]) + end + + module AugProperties = struct + include MakeProperties (struct + include SignatureM.Aug + + let name = "Message augmentation" + end) + + let test_verify_same_msg () = + let n = 2 + Random.int 10 in + let msg = generate_random_bytes (1 + Random.int 512) in + let pks_with_sigs = + List.init n (fun _ -> + let ikm = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let pk = SignatureM.derive_pk sk in + let signature = SignatureM.Aug.sign sk msg in + (pk, signature)) + in + let pks_with_msgs = List.map (fun (pk, _) -> (pk, msg)) pks_with_sigs in + let aggregated_signature = + Option.get + (SignatureM.aggregate_signature_opt (List.map snd pks_with_sigs)) + in + ignore + @@ SignatureM.Aug.aggregate_verify pks_with_msgs aggregated_signature + + let get_tests () = + let open Alcotest in + let specific_tests = + [ + test_case + "Verify signatures with the same message is allowed" + `Quick + test_verify_same_msg; + ] + in + let desc, tests = get_tests () in + (desc, List.concat [specific_tests; tests]) + end + + module PopProperties = struct + let test_sign_and_verify_correct_signature_with_correct_pks_pops_and_msg () + = + let msg = generate_random_bytes (1 + Random.int 512) in + let random_values = + List.init + (1 + Random.int 10) + (fun _ -> + let ikm = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let proof = SignatureM.Pop.pop_prove sk in + let pk = SignatureM.derive_pk sk in + let signature = SignatureM.Pop.sign sk msg in + ((pk, proof), signature)) + in + let pks_with_proofs = List.map fst random_values in + let signatures = List.map snd random_values in + let aggregated_signatures = + Option.get (SignatureM.aggregate_signature_opt signatures) + in + assert ( + SignatureM.Pop.aggregate_verify + pks_with_proofs + msg + aggregated_signatures) + + let test_sign_and_verify_correct_signature_with_correct_pks_pops_and_incorrect_msg + () = + let msg = generate_random_bytes (1 + Random.int 512) in + let msg' = generate_random_bytes (1 + Random.int 512) in + + let random_values = + List.init + (2 + Random.int 10) + (fun _ -> + let ikm = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let proof = SignatureM.Pop.pop_prove sk in + let pk = SignatureM.derive_pk sk in + let signature = SignatureM.Pop.sign sk msg in + ((pk, proof), signature)) + in + let pks_with_proofs = List.map fst random_values in + let signatures = List.map snd random_values in + let aggregated_signatures = + Option.get (SignatureM.aggregate_signature_opt signatures) + in + assert ( + not + (SignatureM.Pop.aggregate_verify + pks_with_proofs + msg' + aggregated_signatures)) + + let test_sign_and_verify_incorrect_signature_with_correct_pks_pops_msg () = + let msg = generate_random_bytes (1 + Random.int 512) in + let random_values = + List.init + (2 + Random.int 10) + (fun i -> + let ikm = generate_random_bytes 32 in + let ikm' = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let sk' = Bls12_381_signature.generate_sk ikm' in + let proof = SignatureM.Pop.pop_prove sk in + let pk = SignatureM.derive_pk sk in + let signature = + if i mod 2 = 0 then SignatureM.Pop.sign sk msg + else SignatureM.Pop.sign sk' msg + in + ((pk, proof), signature)) + in + let pks_with_proofs = List.map fst random_values in + let signatures = List.map snd random_values in + let aggregated_signatures = + Option.get (SignatureM.aggregate_signature_opt signatures) + in + assert ( + not + (SignatureM.Pop.aggregate_verify + pks_with_proofs + msg + aggregated_signatures)) + + let test_sign_and_verify_correct_signature_with_some_correct_pks_and_incorrect_pops_and_msg + () = + let msg = generate_random_bytes (1 + Random.int 512) in + let random_values = + List.init + (2 + Random.int 10) + (fun i -> + let ikm = generate_random_bytes 32 in + let ikm' = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let sk' = Bls12_381_signature.generate_sk ikm' in + let pk = SignatureM.derive_pk sk in + let proof = SignatureM.Pop.pop_prove sk in + let proof' = + if i mod 2 = 0 then proof else SignatureM.Pop.pop_prove sk' + in + let signature = SignatureM.Pop.sign sk msg in + ((pk, proof'), signature)) + in + let pks_with_proofs = List.map fst random_values in + let signatures = List.map snd random_values in + let aggregated_signatures = + Option.get (SignatureM.aggregate_signature_opt signatures) + in + assert ( + not + (SignatureM.Pop.aggregate_verify + pks_with_proofs + msg + aggregated_signatures)) + + let test_sign_and_verify_correct_signature_with_some_incorrect_pks_pops_and_correct_msg + () = + let msg = generate_random_bytes (1 + Random.int 512) in + let random_values = + List.init + (2 + Random.int 10) + (fun i -> + let ikm = generate_random_bytes 32 in + let ikm' = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let sk' = Bls12_381_signature.generate_sk ikm' in + let proof = SignatureM.Pop.pop_prove sk in + let proof' = + if i mod 2 = 1 then proof else SignatureM.Pop.pop_prove sk' + in + let pk = SignatureM.derive_pk sk in + let pk' = + if i mod 2 = 0 then pk + else SignatureM.(derive_pk (Bls12_381_signature.generate_sk ikm')) + in + let signature = SignatureM.Pop.sign sk msg in + ((pk', proof'), signature)) + in + let pks_with_proofs = List.map fst random_values in + let signatures = List.map snd random_values in + let aggregated_signatures = + Option.get (SignatureM.aggregate_signature_opt signatures) + in + assert ( + not + (SignatureM.Pop.aggregate_verify + pks_with_proofs + msg + aggregated_signatures)) + + let test_sign_and_verify_correct_signature_with_some_incorrect_pks_and_correct_pops_and_msg + () = + let msg = generate_random_bytes (1 + Random.int 512) in + let random_values = + List.init + (2 + Random.int 10) + (fun i -> + let ikm = generate_random_bytes 32 in + let ikm' = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let proof = SignatureM.Pop.pop_prove sk in + let pk = SignatureM.derive_pk sk in + let pk' = + if i mod 2 = 0 then pk + else SignatureM.(derive_pk (Bls12_381_signature.generate_sk ikm')) + in + let signature = SignatureM.Pop.sign sk msg in + ((pk', proof), signature)) + in + let pks_with_proofs = List.map fst random_values in + let signatures = List.map snd random_values in + let aggregated_signatures = + Option.get (SignatureM.aggregate_signature_opt signatures) + in + assert ( + not + (SignatureM.Pop.aggregate_verify + pks_with_proofs + msg + aggregated_signatures)) + + let get_tests () = + let open Alcotest in + ( "Properties for Proof of possession", + [ + test_case + "Sign and verify correct signature with correct pks, pops and msg" + `Quick + (Utils.repeat + 10 + test_sign_and_verify_correct_signature_with_correct_pks_pops_and_msg); + test_case + "Sign and verify incorrect signature with correct pks, pops and msg" + `Quick + (Utils.repeat + 10 + test_sign_and_verify_incorrect_signature_with_correct_pks_pops_msg); + test_case + "Sign and verify correct signature with correct pks, pops and \ + incorrect msg" + `Quick + (Utils.repeat + 10 + test_sign_and_verify_correct_signature_with_correct_pks_pops_and_incorrect_msg); + test_case + "Sign and verify correct signature with some incorrect pks and \ + correct pops and msg" + `Quick + (Utils.repeat + 10 + test_sign_and_verify_correct_signature_with_some_incorrect_pks_and_correct_pops_and_msg); + test_case + "Sign and verify correct signature with some incorrect pks and \ + pops and correct msg" + `Quick + (Utils.repeat + 10 + test_sign_and_verify_correct_signature_with_some_incorrect_pks_pops_and_correct_msg); + test_case + "Sign and verify correct signature with correct pks and some \ + incorrect pops and correct msg" + `Quick + (Utils.repeat + 10 + test_sign_and_verify_correct_signature_with_some_correct_pks_and_incorrect_pops_and_msg); + ] ) + end +end + +let () = + let open Alcotest in + let module MinPkTest = MakeAggregatedSignatureTest (Bls12_381_signature.MinPk) in + let module MinSigTest = + MakeAggregatedSignatureTest (Bls12_381_signature.MinSig) in + let minpk_tests = + [ + MinPkTest.BasicProperties.get_tests (); + MinPkTest.AugProperties.get_tests (); + MinPkTest.PopProperties.get_tests (); + ] + in + let minpk_tests = + List.map (fun (desc, tests) -> ("minPk " ^ desc, tests)) minpk_tests + in + let minsig_tests = + [ + MinPkTest.BasicProperties.get_tests (); + MinPkTest.AugProperties.get_tests (); + MinPkTest.PopProperties.get_tests (); + ] + in + let minsig_tests = + List.map (fun (desc, tests) -> ("minSig " ^ desc, tests)) minsig_tests + in + let all_tests = List.concat [minpk_tests; minsig_tests] in + run "BLS Aggregated Signature" all_tests diff --git a/src/lib_bls12_381_signature/test/test_signature.ml b/src/lib_bls12_381_signature/test/test_signature.ml new file mode 100644 index 000000000000..14fb07637fcf --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_signature.ml @@ -0,0 +1,1178 @@ +open Utils + +(* Related to sk *) +let test_sk_size_in_bytes () = + let ikm = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + assert ( + Bls12_381_signature.sk_size_in_bytes + = Bytes.length (Bls12_381_signature.sk_to_bytes sk)) + +let test_sk_of_bytes_exn_and_to_bytes_are_inverse_functions () = + let bytes = Bls12_381.Fr.(to_bytes (random ())) in + assert ( + Bytes.equal Bls12_381_signature.(sk_to_bytes (sk_of_bytes_exn bytes)) bytes) ; + let sk = Bls12_381_signature.(generate_sk (generate_random_bytes 32)) in + let sk_bytes = Bls12_381_signature.sk_to_bytes sk in + assert ( + Bytes.equal + sk_bytes + Bls12_381_signature.(sk_to_bytes (sk_of_bytes_exn sk_bytes))) + +let test_sk_of_bytes_opt_and_to_bytes_are_inverse_functions () = + let bytes = Bls12_381.Fr.(to_bytes (random ())) in + assert ( + Bytes.equal + Bls12_381_signature.(sk_to_bytes (Option.get @@ sk_of_bytes_opt bytes)) + bytes) ; + let sk = Bls12_381_signature.(generate_sk (generate_random_bytes 32)) in + let sk_bytes = Bls12_381_signature.sk_to_bytes sk in + assert ( + Bytes.equal + sk_bytes + Bls12_381_signature.(sk_to_bytes (Option.get @@ sk_of_bytes_opt sk_bytes))) + +let test_sk_of_bytes_opt_valid_values () = + let bytes = Bytes.of_string @@ Z.to_bits Bls12_381.Fr.(to_z (random ())) in + assert (Option.is_some (Bls12_381_signature.sk_of_bytes_opt bytes)) + +let test_sk_of_bytes_exn_valid_values () = + let bytes = Bytes.of_string @@ Z.to_bits Bls12_381.Fr.(to_z (random ())) in + ignore @@ Bls12_381_signature.sk_of_bytes_exn bytes + +(* let test_sk_of_bytes_opt_accepts_less_than_32_bytes () = *) +(* let bytes = generate_random_bytes (Random.int 32) in *) +(* assert (Option.is_some (Bls12_381_signature.sk_of_bytes_opt bytes)) *) + +(* let test_sk_of_bytes_exn_accepts_less_than_32_bytes () = *) +(* let bytes = generate_random_bytes (Random.int 32) in *) +(* ignore (Bls12_381_signature.sk_of_bytes_exn bytes) *) + +let test_sk_of_bytes_exn_does_not_accept_more_than_32_bytes () = + let bytes = generate_random_bytes (32 + Random.int 1_000_000) in + let err_msg = + "Input should be maximum 32 bytes, encoded the secret key in little endian \ + and must be smaller than the order of Bls12_381.Fr" + in + Alcotest.check_raises "" (Invalid_argument err_msg) (fun () -> + ignore @@ Bls12_381_signature.sk_of_bytes_exn bytes) + +let test_sk_of_bytes_opt_does_not_accept_more_than_32_bytes () = + let bytes = generate_random_bytes (32 + Random.int 1_000_000) in + assert (Option.is_none (Bls12_381_signature.sk_of_bytes_opt bytes)) + +let test_sk_of_bytes_opt_does_not_accept_elements_higher_than_the_modulus_but_still_on_32_bytes + () = + (* last byte of Bls12_381.Fr.order is 115 *) + let r = + Bytes.init 32 (fun i -> + char_of_int + @@ if i = 31 then 116 + Random.int (256 - 116) else Random.int 256) + in + assert (Option.is_none (Bls12_381_signature.sk_of_bytes_opt r)) + +let test_sk_of_bytes_exn_does_not_accept_elements_higher_than_the_modulus_but_still_on_32_bytes + () = + (* last byte of Bls12_381.Fr.order is 115 *) + let bytes = + Bytes.init 32 (fun i -> + char_of_int + @@ if i = 31 then 116 + Random.int (256 - 116) else Random.int 256) + in + let err_msg = + "Input should be maximum 32 bytes, encoded the secret key in little endian \ + and must be smaller than the order of Bls12_381.Fr" + in + Alcotest.check_raises "" (Invalid_argument err_msg) (fun () -> + ignore @@ Bls12_381_signature.sk_of_bytes_exn bytes) + +let test_keygen_raise_invalid_argument_if_ikm_too_small () = + ignore + @@ Alcotest.check_raises + "" + (Invalid_argument + "generate_sk: ikm argument must be at least 32 bytes long") + (fun () -> + let ikm = generate_random_bytes (Random.int 32) in + ignore @@ Bls12_381_signature.generate_sk ikm) + +(* Both can be used i.e. MinPk or MinSig. They must share the same interface. *) +module type SIGNATURE_INSTANTIATION = module type of Bls12_381_signature.MinPk + +module MakeTestsForInstantiation (MISC : sig + val sig_basic_filenames : string list + + val sig_aug_filenames : string list + + val sig_pop_filenames : string list + + val pop_filenames : string list + + val pk_not_in_subgroup : string list + + val signature_not_in_subgroup : string list +end) +(PkGroup : Bls12_381.CURVE) +(SigGroup : Bls12_381.CURVE) +(SignatureM : SIGNATURE_INSTANTIATION) = +struct + let test_pk_size_in_bytes () = + let ikm = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let pk = SignatureM.derive_pk sk in + assert ( + SignatureM.pk_size_in_bytes = Bytes.length (SignatureM.pk_to_bytes pk)) + + let test_signature_size_in_bytes () = + let ikm = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let msg_length = 1 + Random.int 512 in + let msg = generate_random_bytes msg_length in + let signature = SignatureM.Basic.sign sk msg in + assert ( + SignatureM.signature_size_in_bytes + = Bytes.length (SignatureM.signature_to_bytes signature)) ; + let signature = SignatureM.Aug.sign sk msg in + assert ( + SignatureM.signature_size_in_bytes + = Bytes.length (SignatureM.signature_to_bytes signature)) ; + let signature = SignatureM.Pop.sign sk msg in + assert ( + SignatureM.signature_size_in_bytes + = Bytes.length (SignatureM.signature_to_bytes signature)) + + let test_unsafe_pk_of_bytes_does_no_check_on_the_input () = + let bytes = generate_random_bytes (Random.int 1000) in + ignore @@ SignatureM.unsafe_pk_of_bytes bytes + + let test_pk_of_bytes_opt_does_check_the_input () = + let bytes = generate_random_bytes (Random.int 1000) in + assert (Option.is_none (SignatureM.pk_of_bytes_opt bytes)) + + let test_pk_of_bytes_exn_does_check_the_input () = + let bytes = generate_random_bytes (Random.int 1000) in + let err_msg = + Printf.sprintf + "%s is not a valid public key" + Hex.(show (`Hex (Bytes.to_string bytes))) + in + Alcotest.check_raises "" (Invalid_argument err_msg) (fun () -> + ignore @@ SignatureM.pk_of_bytes_exn bytes) + + let test_pk_of_bytes_opt_accepts_points_in_the_subgroup_and_in_compressed_form + () = + let pk = PkGroup.random () in + let pk_compressed_bytes = PkGroup.to_compressed_bytes pk in + assert (Option.is_some (SignatureM.pk_of_bytes_opt pk_compressed_bytes)) + + let test_pk_of_bytes_exn_accepts_points_in_the_subgroup_and_in_compressed_form + () = + let pk = PkGroup.random () in + let pk_compressed_bytes = PkGroup.to_compressed_bytes pk in + ignore @@ SignatureM.pk_of_bytes_exn pk_compressed_bytes + + let test_pk_of_bytes_exn_does_not_accept_points_in_the_subgroup_and_in_uncompressed_form + () = + let pk = PkGroup.random () in + let pk_uncompressed_bytes = PkGroup.to_bytes pk in + let err_msg = + Printf.sprintf + "%s is not a valid public key" + Hex.(show (`Hex (Bytes.to_string pk_uncompressed_bytes))) + in + Alcotest.check_raises "" (Invalid_argument err_msg) (fun () -> + ignore @@ SignatureM.pk_of_bytes_exn pk_uncompressed_bytes) + + let test_pk_of_bytes_opt_does_not_accept_points_in_the_subgroup_and_in_uncompressed_form + () = + let pk = PkGroup.random () in + let pk_uncompressed_bytes = PkGroup.to_bytes pk in + assert (Option.is_none (SignatureM.pk_of_bytes_opt pk_uncompressed_bytes)) + + let test_pk_to_bytes_of_bytes_exn_are_inverse_functions_on_valid_inputs () = + let pk = PkGroup.random () in + let pk_bytes = PkGroup.to_compressed_bytes pk in + assert ( + Bytes.equal + pk_bytes + (SignatureM.pk_to_bytes (SignatureM.pk_of_bytes_exn pk_bytes))) + + let test_pk_to_bytes_of_bytes_opt_are_inverse_functions_on_valid_inputs () = + let pk = PkGroup.random () in + let pk_bytes = PkGroup.to_compressed_bytes pk in + assert ( + Bytes.equal + pk_bytes + (SignatureM.pk_to_bytes + (Option.get (SignatureM.pk_of_bytes_opt pk_bytes)))) + + let test_pk_to_bytes_unsafe_of_bytes_are_inverse_functions_on_valid_inputs () + = + let pk = PkGroup.random () in + let pk_bytes = PkGroup.to_compressed_bytes pk in + assert ( + Bytes.equal + pk_bytes + (SignatureM.pk_to_bytes (SignatureM.unsafe_pk_of_bytes pk_bytes))) + + let test_pk_to_bytes_unsafe_of_bytes_are_inverse_functions_on_any_input () = + let pk_bytes = generate_random_bytes (Random.int 1000) in + assert ( + Bytes.equal + pk_bytes + (SignatureM.pk_to_bytes (SignatureM.unsafe_pk_of_bytes pk_bytes))) + + let test_unsafe_pk_of_bytes_copies_the_input () = + let initial_pk_bytes = generate_random_bytes (1 + Random.int 1000) in + let pk_bytes = + SignatureM.(pk_to_bytes (unsafe_pk_of_bytes initial_pk_bytes)) + in + let i = Random.int (Bytes.length initial_pk_bytes) in + let b_i = Bytes.get initial_pk_bytes i in + Bytes.set initial_pk_bytes i (char_of_int ((int_of_char b_i + 1) mod 256)) ; + let res = Bytes.equal pk_bytes initial_pk_bytes in + assert (not res) + + let test_pk_of_bytes_exn_copies_the_input () = + let pk = PkGroup.random () in + let initial_pk_bytes = PkGroup.to_compressed_bytes pk in + let pk_bytes = + SignatureM.(pk_to_bytes (pk_of_bytes_exn initial_pk_bytes)) + in + let i = Random.int (Bytes.length initial_pk_bytes) in + let b_i = Bytes.get initial_pk_bytes i in + Bytes.set initial_pk_bytes i (char_of_int ((int_of_char b_i + 1) mod 256)) ; + let res = Bytes.equal pk_bytes initial_pk_bytes in + assert (not res) + + let test_pk_of_bytes_opt_copies_the_input () = + let pk = PkGroup.random () in + let initial_pk_bytes = PkGroup.to_compressed_bytes pk in + let pk_bytes = + SignatureM.(pk_to_bytes (Option.get @@ pk_of_bytes_opt initial_pk_bytes)) + in + let i = Random.int (Bytes.length initial_pk_bytes) in + let b_i = Bytes.get initial_pk_bytes i in + Bytes.set initial_pk_bytes i (char_of_int ((int_of_char b_i + 1) mod 256)) ; + let res = Bytes.equal pk_bytes initial_pk_bytes in + assert (not res) + + let test_unsafe_pk_of_bytes_accepts_points_not_in_the_subgroup () = + List.iter + (fun pk_bytes_str -> + let pk_bytes = Hex.(to_bytes (`Hex pk_bytes_str)) in + ignore @@ SignatureM.unsafe_pk_of_bytes pk_bytes) + MISC.pk_not_in_subgroup + + let test_pk_of_bytes_exn_does_verify_the_input_represents_a_point_in_the_subgroup + () = + List.iter + (fun pk_bytes_str -> + let pk_bytes = Hex.(to_bytes (`Hex pk_bytes_str)) in + let err_msg = + Printf.sprintf + "%s is not a valid public key" + Hex.(show (`Hex (Bytes.to_string pk_bytes))) + in + Alcotest.check_raises "" (Invalid_argument err_msg) (fun () -> + ignore @@ SignatureM.pk_of_bytes_exn pk_bytes)) + MISC.pk_not_in_subgroup + + let test_pk_of_bytes_opt_does_verify_the_input_represents_a_point_in_the_subgroup + () = + List.iter + (fun pk_bytes_str -> + let pk_bytes = Hex.(to_bytes (`Hex pk_bytes_str)) in + assert (Option.is_none (SignatureM.pk_of_bytes_opt pk_bytes))) + MISC.pk_not_in_subgroup + + let test_unsafe_signature_of_bytes_does_no_check_on_the_input () = + let bytes = generate_random_bytes (Random.int 1000) in + ignore @@ SignatureM.unsafe_signature_of_bytes bytes + + let test_signature_of_bytes_opt_does_check_the_input () = + let bytes = generate_random_bytes (Random.int 1000) in + assert (Option.is_none (SignatureM.signature_of_bytes_opt bytes)) + + let test_signature_of_bytes_exn_does_check_the_input () = + let bytes = generate_random_bytes (Random.int 1000) in + let err_msg = + Printf.sprintf + "%s is not a valid signature" + Hex.(show (`Hex (Bytes.to_string bytes))) + in + Alcotest.check_raises "" (Invalid_argument err_msg) (fun () -> + ignore @@ SignatureM.signature_of_bytes_exn bytes) + + let test_signature_of_bytes_opt_accepts_points_in_the_subgroup_and_in_compressed_form + () = + let r = SigGroup.random () in + let compressed_bytes = SigGroup.to_compressed_bytes r in + assert (Option.is_some (SignatureM.signature_of_bytes_opt compressed_bytes)) + + let test_signature_of_bytes_exn_accepts_points_in_the_subgroup_and_in_compressed_form + () = + let r = SigGroup.random () in + let compressed_bytes = SigGroup.to_compressed_bytes r in + ignore @@ SignatureM.signature_of_bytes_exn compressed_bytes + + let test_signature_of_bytes_exn_does_not_accept_points_in_the_subgroup_and_in_uncompressed_form + () = + let r = SigGroup.random () in + let uncompressed_bytes = SigGroup.to_bytes r in + let err_msg = + Printf.sprintf + "%s is not a valid signature" + Hex.(show (`Hex (Bytes.to_string uncompressed_bytes))) + in + Alcotest.check_raises "" (Invalid_argument err_msg) (fun () -> + ignore @@ SignatureM.signature_of_bytes_exn uncompressed_bytes) + + let test_signature_of_bytes_opt_does_not_accept_points_in_the_subgroup_and_in_uncompressed_form + () = + let r = SigGroup.random () in + let uncompressed_bytes = SigGroup.to_bytes r in + assert ( + Option.is_none (SignatureM.signature_of_bytes_opt uncompressed_bytes)) + + let test_signature_to_bytes_of_bytes_exn_are_inverse_functions_on_valid_inputs + () = + let r = SigGroup.random () in + let bytes = SigGroup.to_compressed_bytes r in + assert ( + Bytes.equal + bytes + (SignatureM.signature_to_bytes + (SignatureM.signature_of_bytes_exn bytes))) + + let test_signature_to_bytes_of_bytes_opt_are_inverse_functions_on_valid_inputs + () = + let r = SigGroup.random () in + let bytes = SigGroup.to_compressed_bytes r in + assert ( + Bytes.equal + bytes + (SignatureM.signature_to_bytes + (Option.get (SignatureM.signature_of_bytes_opt bytes)))) + + let test_signature_to_bytes_unsafe_of_bytes_are_inverse_functions_on_valid_inputs + () = + let r = SigGroup.random () in + let bytes = SigGroup.to_compressed_bytes r in + assert ( + Bytes.equal + bytes + (SignatureM.signature_to_bytes + (SignatureM.unsafe_signature_of_bytes bytes))) + + let test_signature_to_bytes_unsafe_of_bytes_are_inverse_functions_on_any_input + () = + let bytes = generate_random_bytes (Random.int 1000) in + assert ( + Bytes.equal + bytes + (SignatureM.signature_to_bytes + (SignatureM.unsafe_signature_of_bytes bytes))) + + let test_unsafe_signature_of_bytes_copies_the_input () = + let initial_bytes = generate_random_bytes (1 + Random.int 1000) in + let bytes = + SignatureM.(signature_to_bytes (unsafe_signature_of_bytes initial_bytes)) + in + let i = Random.int (Bytes.length initial_bytes) in + let b_i = Bytes.get initial_bytes i in + Bytes.set initial_bytes i (char_of_int ((int_of_char b_i + 1) mod 256)) ; + let res = Bytes.equal bytes initial_bytes in + assert (not res) + + let test_signature_of_bytes_exn_copies_the_input () = + let r = SigGroup.random () in + let initial_bytes = SigGroup.to_compressed_bytes r in + let bytes = + SignatureM.(signature_to_bytes (signature_of_bytes_exn initial_bytes)) + in + let i = Random.int (Bytes.length initial_bytes) in + let b_i = Bytes.get initial_bytes i in + Bytes.set initial_bytes i (char_of_int ((int_of_char b_i + 1) mod 256)) ; + let res = Bytes.equal bytes initial_bytes in + assert (not res) + + let test_signature_of_bytes_opt_copies_the_input () = + let r = SigGroup.random () in + let initial_bytes = SigGroup.to_compressed_bytes r in + let bytes = + SignatureM.( + signature_to_bytes (Option.get @@ signature_of_bytes_opt initial_bytes)) + in + let i = Random.int (Bytes.length initial_bytes) in + let b_i = Bytes.get initial_bytes i in + Bytes.set initial_bytes i (char_of_int ((int_of_char b_i + 1) mod 256)) ; + let res = Bytes.equal bytes initial_bytes in + assert (not res) + + let test_unsafe_signature_of_bytes_accepts_points_not_in_the_subgroup () = + List.iter + (fun bytes_str -> + let bytes = Hex.(to_bytes (`Hex bytes_str)) in + ignore @@ SignatureM.unsafe_signature_of_bytes bytes) + MISC.signature_not_in_subgroup + + let test_signature_of_bytes_exn_does_verify_the_input_represents_a_point_in_the_subgroup + () = + List.iter + (fun bytes_str -> + let bytes = Hex.(to_bytes (`Hex bytes_str)) in + let err_msg = + Printf.sprintf + "%s is not a valid signature" + Hex.(show (`Hex (Bytes.to_string bytes))) + in + Alcotest.check_raises "" (Invalid_argument err_msg) (fun () -> + ignore @@ SignatureM.signature_of_bytes_exn bytes)) + MISC.signature_not_in_subgroup + + let test_signature_of_bytes_opt_does_verify_the_input_represents_a_point_in_the_subgroup + () = + List.iter + (fun bytes_str -> + let bytes = Hex.(to_bytes (`Hex bytes_str)) in + assert (Option.is_none (SignatureM.signature_of_bytes_opt bytes))) + MISC.signature_not_in_subgroup + + let test_pop_prove_verify_with_correct_keys () = + let ikm = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let pk = SignatureM.derive_pk sk in + (* sign a random message *) + let proof = SignatureM.Pop.pop_prove sk in + assert (SignatureM.Pop.pop_verify pk proof) + + let test_pop_prove_verify_with_different_pk_for_verify () = + let ikm = generate_random_bytes 32 in + let ikm' = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let pk' = SignatureM.(derive_pk (Bls12_381_signature.generate_sk ikm')) in + (* sign a random message *) + let proof = SignatureM.Pop.pop_prove sk in + assert (not (SignatureM.Pop.pop_verify pk' proof)) + + let test_pop_verify_random_proof () = + let ikm = generate_random_bytes 32 in + let pk = SignatureM.(derive_pk (Bls12_381_signature.generate_sk ikm)) in + let proof = generate_random_bytes (PkGroup.size_in_bytes / 2) in + assert (not (SignatureM.Pop.pop_verify pk proof)) + + module MakeProperties (Scheme : sig + val test_vector_filenames : string list + + val sign : Bls12_381_signature.sk -> Bytes.t -> SignatureM.signature + + val verify : SignatureM.pk -> Bytes.t -> SignatureM.signature -> bool + + val name : string + end) = + struct + let test_sign_and_verify_same_message_with_correct_keys () = + let ikm = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let pk = SignatureM.derive_pk sk in + (* sign a random message *) + let msg_length = 1 + Random.int 512 in + let msg = generate_random_bytes msg_length in + let signature = Scheme.sign sk msg in + assert (Scheme.verify pk msg signature) + + let test_sign_and_verify_different_message_with_correct_keys () = + let ikm = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let pk = SignatureM.derive_pk sk in + (* sign a random message *) + let msg_length = 1 + Random.int 512 in + let msg = generate_random_bytes msg_length in + let msg'_length = 1 + Random.int 512 in + let msg' = generate_random_bytes msg'_length in + let signature = Scheme.sign sk msg in + assert (not (Scheme.verify pk msg' signature)) + + let test_sign_and_verify_different_message_with_different_keys () = + let ikm = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let _pk = SignatureM.derive_pk sk in + + let ikm' = generate_random_bytes 32 in + let sk' = Bls12_381_signature.generate_sk ikm' in + let pk' = SignatureM.derive_pk sk' in + + (* sign a random message *) + let msg_length = 1 + Random.int 512 in + let msg = generate_random_bytes msg_length in + let msg'_length = 1 + Random.int 512 in + let msg' = generate_random_bytes msg'_length in + let signature = Scheme.sign sk msg in + assert (not (Scheme.verify pk' msg' signature)) + + let test_sign_and_verify_same_message_with_different_keys () = + let ikm = generate_random_bytes 32 in + let sk = Bls12_381_signature.generate_sk ikm in + let _pk = SignatureM.derive_pk sk in + + let ikm' = generate_random_bytes 32 in + let sk' = Bls12_381_signature.generate_sk ikm' in + let pk' = SignatureM.derive_pk sk' in + + (* sign a random message *) + let msg_length = 1 + Random.int 512 in + let msg = generate_random_bytes msg_length in + let signature = Scheme.sign sk msg in + assert (not (Scheme.verify pk' msg signature)) + + let test_full_sign_and_verify_with_different_ikm_sizes () = + let ikm = generate_random_bytes (32 + Random.int 1000) in + let sk = Bls12_381_signature.generate_sk ikm in + let pk = SignatureM.derive_pk sk in + (* sign a random message *) + let msg_length = 1 + Random.int 512 in + let msg = generate_random_bytes msg_length in + let signature = Scheme.sign sk msg in + assert (Scheme.verify pk msg signature) + + (* let test_verify_signature_which_represents_point_on_the_curve_but_not_in_the_prime_subgroup *) + (* () = *) + (* List.iter *) + (* (fun signature_hex -> *) + (* let ikm = Bytes.init 32 (fun _i -> char_of_int @@ Random.int 256) in *) + (* let sk = Bls12_381_signature.generate_sk ikm in *) + (* let pk = SignatureM.derive_pk sk in *) + (* let msg = Bytes.of_string "Hello" in *) + (* let signature = Hex.(to_bytes (`Hex signature_hex)) in *) + (* let signature = SignatureM.unsafe_signature_of_bytes signature in *) + (* assert (not (Scheme.verify pk msg signature))) *) + (* MISC.signature_not_in_subgroup *) + + let test_sign_and_verify_with_a_pk_not_in_the_subgroup () = + List.iter + (fun invalid_pk_bytes -> + let invalid_pk_bytes = Hex.(to_bytes (`Hex invalid_pk_bytes)) in + let sk = + Bls12_381_signature.sk_of_bytes_exn Bls12_381.Fr.(to_bytes one) + in + let pk = SignatureM.unsafe_pk_of_bytes invalid_pk_bytes in + let msg = Bytes.of_string "Hello" in + let signature = Scheme.sign sk msg in + (* Even when not checking the pk belongs to the subgroup in the + core_verify algorithm, the verification fails. Better attacks must + be implemented. *) + assert (not (Scheme.verify pk msg signature))) + MISC.pk_not_in_subgroup + + let test_vectors_from_bls_sigs_ref_files () = + let aux filename = + let contents = read_file filename in + List.iter + (fun content -> + let contents = String.split_on_char ' ' content in + let msg_str, ikm_str, expected_result_str = + (List.nth contents 0, List.nth contents 1, List.nth contents 2) + in + let msg = Hex.(to_bytes (`Hex msg_str)) in + let ikm = Hex.to_bytes (`Hex ikm_str) in + if Bytes.length ikm < 32 then () + else + let sk = Bls12_381_signature.generate_sk ikm in + let expected_result = Hex.(to_bytes (`Hex expected_result_str)) in + let res = Scheme.sign sk msg in + let res = SignatureM.signature_to_bytes res in + if not @@ Bytes.equal res expected_result then + Alcotest.failf + "Expected result is %s on input %s with ikm %s, but computed \ + %s" + Hex.(show (Hex.of_bytes expected_result)) + msg_str + ikm_str + Hex.(show (Hex.of_bytes res))) + contents + in + List.iter (fun filename -> aux filename) Scheme.test_vector_filenames + + let get_tests () = + let open Alcotest in + ( Printf.sprintf "Properties and test vectors for %s" Scheme.name, + [ + test_case + "Sign and verify same message with correct keys" + `Quick + (Utils.repeat + 100 + test_sign_and_verify_same_message_with_correct_keys); + test_case + "Sign and verify different message with correct keys" + `Quick + (Utils.repeat + 100 + test_sign_and_verify_different_message_with_correct_keys); + test_case + "Sign and verify same message with different keys" + `Quick + (Utils.repeat + 100 + test_sign_and_verify_same_message_with_different_keys); + test_case + "Sign and verify different message with different keys" + `Quick + (Utils.repeat + 100 + test_sign_and_verify_different_message_with_different_keys); + test_case + "Test full sign and verify with different ikm sizes" + `Quick + (Utils.repeat + 100 + test_full_sign_and_verify_with_different_ikm_sizes); + test_case + "Sign and verify with a pk not in the prime subgroup" + `Quick + test_sign_and_verify_with_a_pk_not_in_the_subgroup; + test_case + "Test vectors from bls_sigs_ref" + `Quick + test_vectors_from_bls_sigs_ref_files; + ] ) + end + + module BasicProperties = MakeProperties (struct + let test_vector_filenames = MISC.sig_basic_filenames + + let name = "Basic" + + let sign = SignatureM.Basic.sign + + let verify = SignatureM.Basic.verify + end) + + module AugProperties = MakeProperties (struct + let test_vector_filenames = MISC.sig_aug_filenames + + let name = "Message augmentation" + + let sign = SignatureM.Aug.sign + + let verify = SignatureM.Aug.verify + end) + + module PopProperties = MakeProperties (struct + let test_vector_filenames = MISC.sig_pop_filenames + + let name = "Proof of possession" + + let sign = SignatureM.Pop.sign + + let verify = SignatureM.Pop.verify + end) + + let test_pop_g2_from_blst_sigs_ref_files () = + let aux filename = + let contents = read_file filename in + List.iter + (fun content -> + let contents = String.split_on_char ' ' content in + let ikm_str, exp_result_str = + (List.nth contents 1, List.nth contents 2) + in + let ikm_bytes = Hex.(to_bytes (`Hex ikm_str)) in + if Bytes.length ikm_bytes < 32 then () + else + let sk = Bls12_381_signature.generate_sk ikm_bytes in + let exp_result_bytes = Hex.(to_bytes (`Hex exp_result_str)) in + let res = SignatureM.Pop.pop_prove sk in + if not @@ Bytes.equal res exp_result_bytes then + Alcotest.failf + "Expected result is %s with ikm %s, but computed %s" + exp_result_str + ikm_str + Hex.(show (Hex.of_bytes res))) + contents + in + List.iter (fun filename -> aux filename) MISC.pop_filenames + + let get_tests () = + let open Alcotest in + [ + ( "Size in bytes", + [ + test_case "pk" `Quick test_pk_size_in_bytes; + test_case "signature" `Quick test_signature_size_in_bytes; + ] ); + ( "Auxiliary functions", + [ + test_case + "unsafe_pk_of_bytes does no check on the input" + `Quick + test_unsafe_pk_of_bytes_does_no_check_on_the_input; + test_case + "pk_of_bytes_exn accepts points in the subgroup and in compressed \ + form" + `Quick + (Utils.repeat + 10 + test_pk_of_bytes_exn_accepts_points_in_the_subgroup_and_in_compressed_form); + test_case + "pk_of_bytes_opt accepts points in the subgroup and in compressed \ + form" + `Quick + (Utils.repeat + 10 + test_pk_of_bytes_opt_accepts_points_in_the_subgroup_and_in_compressed_form); + test_case + "pk_of_bytes_exn does not accept points in the subgroup and in \ + uncompressed form" + `Quick + (Utils.repeat + 10 + test_pk_of_bytes_exn_does_not_accept_points_in_the_subgroup_and_in_uncompressed_form); + test_case + "pk_of_bytes_opt does not accept points in the subgroup and in \ + uncompressed form" + `Quick + (Utils.repeat + 10 + test_pk_of_bytes_opt_does_not_accept_points_in_the_subgroup_and_in_uncompressed_form); + test_case + "unsafe_pk_of_bytes copies the input" + `Quick + (Utils.repeat 10 test_unsafe_pk_of_bytes_copies_the_input); + test_case + "pk_of_bytes_exn copies the input" + `Quick + (Utils.repeat 10 test_pk_of_bytes_exn_copies_the_input); + test_case + "pk_of_bytes_opt copies the input" + `Quick + (Utils.repeat 10 test_pk_of_bytes_opt_copies_the_input); + test_case + "unsafe_pk_of_bytes accepts points not in the subgroup" + `Quick + test_unsafe_pk_of_bytes_accepts_points_not_in_the_subgroup; + test_case + "pk_of_bytes_exn does check the input" + `Quick + test_pk_of_bytes_exn_does_check_the_input; + test_case + "pk_of_bytes_opt and pk_to_bytes are inverse functions on valid \ + inputs" + `Quick + (Utils.repeat + 10 + test_pk_to_bytes_of_bytes_opt_are_inverse_functions_on_valid_inputs); + test_case + "unsafe_pk_of_bytes and pk_to_bytes are inverse functions on valid \ + inputs" + `Quick + (Utils.repeat + 10 + test_pk_to_bytes_unsafe_of_bytes_are_inverse_functions_on_valid_inputs); + test_case + "pk_of_bytes_exn and pk_to_bytes are inverse functions on valid \ + inputs" + `Quick + (Utils.repeat + 10 + test_pk_to_bytes_of_bytes_exn_are_inverse_functions_on_valid_inputs); + test_case + "unsafe_pk_of_bytes and pk_to_bytes are inverse functions on any \ + valid input" + `Quick + (Utils.repeat + 10 + test_pk_to_bytes_unsafe_of_bytes_are_inverse_functions_on_any_input); + test_case + "pk_of_bytes_exn does verify the input represents a point in the \ + subgroup" + `Quick + test_pk_of_bytes_exn_does_verify_the_input_represents_a_point_in_the_subgroup; + test_case + "pk_of_bytes_opt does verify the input represents a point in the \ + subgroup" + `Quick + test_pk_of_bytes_opt_does_verify_the_input_represents_a_point_in_the_subgroup; + test_case + "pk_of_bytes_opt does check the input" + `Quick + test_pk_of_bytes_opt_does_check_the_input; + test_case + "unsafe_signature_of_bytes does no check on the input" + `Quick + test_unsafe_signature_of_bytes_does_no_check_on_the_input; + test_case + "signature_of_bytes_exn accepts points in the subgroup and in \ + compressed form" + `Quick + (Utils.repeat + 10 + test_signature_of_bytes_exn_accepts_points_in_the_subgroup_and_in_compressed_form); + test_case + "signature_of_bytes_opt accepts points in the subgroup and in \ + compressed form" + `Quick + (Utils.repeat + 10 + test_signature_of_bytes_opt_accepts_points_in_the_subgroup_and_in_compressed_form); + test_case + "signature_of_bytes_exn does not accept points in the subgroup and \ + in uncompressed form" + `Quick + (Utils.repeat + 10 + test_signature_of_bytes_exn_does_not_accept_points_in_the_subgroup_and_in_uncompressed_form); + test_case + "signature_of_bytes_opt does not accept points in the subgroup and \ + in uncompressed form" + `Quick + (Utils.repeat + 10 + test_signature_of_bytes_opt_does_not_accept_points_in_the_subgroup_and_in_uncompressed_form); + test_case + "unsafe_signature_of_bytes copies the input" + `Quick + (Utils.repeat 10 test_unsafe_signature_of_bytes_copies_the_input); + test_case + "signature_of_bytes_exn copies the input" + `Quick + (Utils.repeat 10 test_signature_of_bytes_exn_copies_the_input); + test_case + "signature_of_bytes_opt copies the input" + `Quick + (Utils.repeat 10 test_signature_of_bytes_opt_copies_the_input); + test_case + "unsafe_signature_of_bytes accepts points not in the subgroup" + `Quick + test_unsafe_signature_of_bytes_accepts_points_not_in_the_subgroup; + test_case + "signature_of_bytes_exn does check the input" + `Quick + test_signature_of_bytes_exn_does_check_the_input; + test_case + "signature_of_bytes_opt and signature_to_bytes are inverse \ + functions on valid inputs" + `Quick + (Utils.repeat + 10 + test_signature_to_bytes_of_bytes_opt_are_inverse_functions_on_valid_inputs); + test_case + "unsafe_signature_of_bytes and signature_to_bytes are inverse \ + functions on valid inputs" + `Quick + (Utils.repeat + 10 + test_signature_to_bytes_unsafe_of_bytes_are_inverse_functions_on_valid_inputs); + test_case + "signature_of_bytes_exn and signature_to_bytes are inverse \ + functions on valid inputs" + `Quick + (Utils.repeat + 10 + test_signature_to_bytes_of_bytes_exn_are_inverse_functions_on_valid_inputs); + test_case + "unsafe_signature_of_bytes and signature_to_bytes are inverse \ + functions on any valid input" + `Quick + (Utils.repeat + 10 + test_signature_to_bytes_unsafe_of_bytes_are_inverse_functions_on_any_input); + test_case + "signature_of_bytes_exn does verify the input represents a point \ + in the subgroup" + `Quick + test_signature_of_bytes_exn_does_verify_the_input_represents_a_point_in_the_subgroup; + test_case + "signature_of_bytes_opt does verify the input represents a point \ + in the subgroup" + `Quick + test_signature_of_bytes_opt_does_verify_the_input_represents_a_point_in_the_subgroup; + test_case + "signature_of_bytes_opt does check the input" + `Quick + test_signature_of_bytes_opt_does_check_the_input; + ] ); + BasicProperties.get_tests (); + AugProperties.get_tests (); + PopProperties.get_tests (); + ( "Proof of possession proof/verify properties and test vectors", + [ + test_case + "Pop G2 from file" + `Quick + test_pop_g2_from_blst_sigs_ref_files; + test_case + "Prove and verify with correct keys" + `Quick + (Utils.repeat 10 test_pop_prove_verify_with_correct_keys); + test_case + "Prove and verify with different pk for verify" + `Quick + (Utils.repeat 10 test_pop_prove_verify_with_different_pk_for_verify); + test_case + "Verify random proof" + `Quick + (Utils.repeat 10 test_pop_verify_random_proof); + ] ); + ] +end + +let () = + let open Alcotest in + let module TestMinPk = + MakeTestsForInstantiation + (struct + let sig_basic_filenames = + [ + "sig_g2_basic_fips_186_3_B233_blst"; + "sig_g2_basic_fips_186_3_B283_blst"; + "sig_g2_basic_fips_186_3_B409_blst"; + "sig_g2_basic_fips_186_3_B571_blst"; + "sig_g2_basic_fips_186_3_K233_blst"; + "sig_g2_basic_fips_186_3_K409_blst"; + "sig_g2_basic_fips_186_3_K571_blst"; + "sig_g2_basic_fips_186_3_P224_blst"; + "sig_g2_basic_fips_186_3_P256_blst"; + "sig_g2_basic_fips_186_3_P384_blst"; + "sig_g2_basic_fips_186_3_P521_blst"; + "sig_g2_basic_rfc6979_blst"; + ] + + let sig_aug_filenames = + [ + "sig_g2_aug_fips_186_3_B233_blst"; + "sig_g2_aug_fips_186_3_B283_blst"; + "sig_g2_aug_fips_186_3_B409_blst"; + "sig_g2_aug_fips_186_3_B571_blst"; + "sig_g2_aug_fips_186_3_K233_blst"; + "sig_g2_aug_fips_186_3_K409_blst"; + "sig_g2_aug_fips_186_3_K571_blst"; + "sig_g2_aug_fips_186_3_P224_blst"; + "sig_g2_aug_fips_186_3_P256_blst"; + "sig_g2_aug_fips_186_3_P384_blst"; + "sig_g2_aug_fips_186_3_P521_blst"; + "sig_g2_aug_rfc6979_blst"; + ] + + let sig_pop_filenames = + [ + "sig_g2_pop_fips_186_3_B233_blst"; + "sig_g2_pop_fips_186_3_B283_blst"; + "sig_g2_pop_fips_186_3_B409_blst"; + "sig_g2_pop_fips_186_3_B571_blst"; + "sig_g2_pop_fips_186_3_K233_blst"; + "sig_g2_pop_fips_186_3_K409_blst"; + "sig_g2_pop_fips_186_3_K571_blst"; + "sig_g2_pop_fips_186_3_P224_blst"; + "sig_g2_pop_fips_186_3_P256_blst"; + "sig_g2_pop_fips_186_3_P384_blst"; + "sig_g2_pop_fips_186_3_P521_blst"; + "sig_g2_pop_rfc6979_blst"; + ] + + (* These elements have been generated by bls12-381-unix-blst, commit + ffa2ad5f1c882f05d64c7cb1633c6256b08513bf, by removing the + multiplication by the cofactor in the random generator. It can be + verified the elements are not in the prime subgroup by checking + multiplying by Fr.order does not give zero. *) + let pk_not_in_subgroup = + [ + "a4c9678ad327129f4388e7f7ff781fc8e98d181add820b79d15facdca422b3ee7fb20f7082a7f9b7c7915053191cb013"; + "97ae9b4dc6a05cda8bc833dfb983e41423d224bbf6954ce4721a50364a2b37643e18a276ce19b07b83a333f90e2de6c2"; + "b1be8c9f94c1435227b9a18fb57a6d9932c1670d16c514d2d9d67839cc0cc19afdcd114d6e06bf8eb8394061bf880bd4"; + "b173357ce7e2340dc64c6a5633e6800683fb0a6c0f4af92b383425bd76d915819252ac9459e79a1bae530ea0145338cb"; + "a53944773013669c2722949399322703c0b92d877e52b95e0309bdf286d8290314763d61952d6812da50c1826bcaf4c3"; + "8fd2557441f4076917ffe8dfb0e12270994351661600e72f48fe654198199f6cc625a041ce3c9b7c765b32cb53e77192"; + ] + + (* These points are on the curve, but not in the subgroup, see + test_g2.ml to see how it has been generated. It is given in the + compressed form as required for the signature. *) + let signature_not_in_subgroup = + [ + "a7da246233ad216e60ee03070a0916154ae9f9dc23310c1191dfb4e277fc757f58a5cf5bdf7a9f322775143c37539cb90798205fd56217b682d5656f7ac7bc0da111dee59d3f863f1b040be659eda7941afb9f1bc5d0fe2beb5e2385e2cfe9ee"; + "b112717bbcd089ea99e8216eab455ea5cd462b0b3e3530303b83477f8e1bb7abca269fec10b3eb998f7f6fd1799d58ff11ed0a53bf75f91d2bf73d11bd52d061f401ac6a6ec0ef4a163e480bac85e75b97cb556f500057b9ef4b28bfe196791d"; + "86e5fa411047d9632c95747bea64d973757904c935ac0741b9eeefa2c7c4e439baf1d2c1e8633ba6c884ed9fdf1ffbdd129a32c046f355c5126254973115d6df32904498db6ca959d5bf1869f235be4c0e60fc334ed493f864476907cadfef2c"; + "88c83e90520a5ea31733cc01e3589e10b2ed755e2faade29199f97645fbf73f52b29297c22a3b1c4fcd3379bceeec832091df6fb3b9d23f04e8267fc41e578002484155562e70f488c2a4c6b11522c66736bc977755c257478f3022656abb630"; + "a25099811f52ad463c762197466c476a03951afdb3f0a457efa2b9475376652fba7b2d56f3184dad540a234d471c53a113203f73dd661694586c75d9c418d34cd16504356253e3ba4618f61cbee02880a43efeacb8f9fe1fdc84ceec4f780ba2"; + "990f5e1d200d1b9ab842c516ce50992730917a8b2e95ee1a4b830d7d9507c6846ace7a0eed8831a8d1f1e233cd24581215fe8fe85a99f4ca3fe046dba8ac6377fc3c10d73fa94b25c2d534d7a587a507b498754a2534cd85777b2a7f2978eec6"; + "a29415562a1d18b11ec8ab2e0b347a9417f9e904cf25f9b1dc40f235507814371fb4568cc1070a0b8c7baf39e0039d1e0b49d4352b095883ccc262e23d8651c49c39c06d0a920d40b2765d550a78c4c1940c8a2b6843a0063402c169f079f0ae"; + "8a257ed6d95cb226c3eb57218bd075ba27164fc1b972c4230ee70c7b81c89d38253ccf7ed2896aa5eb3d9fd6021fac000e368080e705f2a65c919539e2d28e6dd1117296b4210fd56db8d96891f8586bd333e9c47f838ed436659a1dafaee16c"; + ] + + let pop_filenames = + [ + "pop_g2_fips_186_3_B233_blst"; + "pop_g2_fips_186_3_B283_blst"; + "pop_g2_fips_186_3_B409_blst"; + "pop_g2_fips_186_3_B571_blst"; + "pop_g2_fips_186_3_K233_blst"; + "pop_g2_fips_186_3_K409_blst"; + "pop_g2_fips_186_3_K571_blst"; + "pop_g2_fips_186_3_P224_blst"; + "pop_g2_fips_186_3_P256_blst"; + "pop_g2_fips_186_3_P384_blst"; + "pop_g2_fips_186_3_P521_blst"; + "pop_g2_rfc6979_blst"; + ] + end) + (Bls12_381.G1) + (Bls12_381.G2) + (Bls12_381_signature.MinPk) + in + let module TestMinSig = + MakeTestsForInstantiation + (struct + let sig_basic_filenames = + [ + "sig_g1_basic_fips_186_3_B233_blst"; + "sig_g1_basic_fips_186_3_B283_blst"; + "sig_g1_basic_fips_186_3_B409_blst"; + "sig_g1_basic_fips_186_3_B571_blst"; + "sig_g1_basic_fips_186_3_K233_blst"; + "sig_g1_basic_fips_186_3_K409_blst"; + "sig_g1_basic_fips_186_3_K571_blst"; + "sig_g1_basic_fips_186_3_P224_blst"; + "sig_g1_basic_fips_186_3_P256_blst"; + "sig_g1_basic_fips_186_3_P384_blst"; + "sig_g1_basic_fips_186_3_P521_blst"; + "sig_g1_basic_rfc6979_blst"; + ] + + let sig_aug_filenames = + [ + "sig_g1_aug_fips_186_3_B233_blst"; + "sig_g1_aug_fips_186_3_B283_blst"; + "sig_g1_aug_fips_186_3_B409_blst"; + "sig_g1_aug_fips_186_3_B571_blst"; + "sig_g1_aug_fips_186_3_K233_blst"; + "sig_g1_aug_fips_186_3_K409_blst"; + "sig_g1_aug_fips_186_3_K571_blst"; + "sig_g1_aug_fips_186_3_P224_blst"; + "sig_g1_aug_fips_186_3_P256_blst"; + "sig_g1_aug_fips_186_3_P384_blst"; + "sig_g1_aug_fips_186_3_P521_blst"; + "sig_g1_aug_rfc6979_blst"; + ] + + let sig_pop_filenames = + [ + "sig_g1_pop_fips_186_3_B233_blst"; + "sig_g1_pop_fips_186_3_B283_blst"; + "sig_g1_pop_fips_186_3_B409_blst"; + "sig_g1_pop_fips_186_3_B571_blst"; + "sig_g1_pop_fips_186_3_K233_blst"; + "sig_g1_pop_fips_186_3_K409_blst"; + "sig_g1_pop_fips_186_3_K571_blst"; + "sig_g1_pop_fips_186_3_P224_blst"; + "sig_g1_pop_fips_186_3_P256_blst"; + "sig_g1_pop_fips_186_3_P384_blst"; + "sig_g1_pop_fips_186_3_P521_blst"; + "sig_g1_pop_rfc6979_blst"; + ] + + (* These elements have been generated by bls12-381-unix-blst, commit + ffa2ad5f1c882f05d64c7cb1633c6256b08513bf, by removing the + multiplication by the cofactor in the random generator. It can be + verified the elements are not in the prime subgroup by checking + multiplying by Fr.order does not give zero. *) + let signature_not_in_subgroup = + [ + "a4c9678ad327129f4388e7f7ff781fc8e98d181add820b79d15facdca422b3ee7fb20f7082a7f9b7c7915053191cb013"; + "97ae9b4dc6a05cda8bc833dfb983e41423d224bbf6954ce4721a50364a2b37643e18a276ce19b07b83a333f90e2de6c2"; + "b1be8c9f94c1435227b9a18fb57a6d9932c1670d16c514d2d9d67839cc0cc19afdcd114d6e06bf8eb8394061bf880bd4"; + "b173357ce7e2340dc64c6a5633e6800683fb0a6c0f4af92b383425bd76d915819252ac9459e79a1bae530ea0145338cb"; + "a53944773013669c2722949399322703c0b92d877e52b95e0309bdf286d8290314763d61952d6812da50c1826bcaf4c3"; + "8fd2557441f4076917ffe8dfb0e12270994351661600e72f48fe654198199f6cc625a041ce3c9b7c765b32cb53e77192"; + ] + + (* These points are on the curve, but not in the subgroup, see + test_g2.ml to see how it has been generated. It is given in the + compressed form as required for the signature. *) + let pk_not_in_subgroup = + [ + "a7da246233ad216e60ee03070a0916154ae9f9dc23310c1191dfb4e277fc757f58a5cf5bdf7a9f322775143c37539cb90798205fd56217b682d5656f7ac7bc0da111dee59d3f863f1b040be659eda7941afb9f1bc5d0fe2beb5e2385e2cfe9ee"; + "b112717bbcd089ea99e8216eab455ea5cd462b0b3e3530303b83477f8e1bb7abca269fec10b3eb998f7f6fd1799d58ff11ed0a53bf75f91d2bf73d11bd52d061f401ac6a6ec0ef4a163e480bac85e75b97cb556f500057b9ef4b28bfe196791d"; + "86e5fa411047d9632c95747bea64d973757904c935ac0741b9eeefa2c7c4e439baf1d2c1e8633ba6c884ed9fdf1ffbdd129a32c046f355c5126254973115d6df32904498db6ca959d5bf1869f235be4c0e60fc334ed493f864476907cadfef2c"; + "88c83e90520a5ea31733cc01e3589e10b2ed755e2faade29199f97645fbf73f52b29297c22a3b1c4fcd3379bceeec832091df6fb3b9d23f04e8267fc41e578002484155562e70f488c2a4c6b11522c66736bc977755c257478f3022656abb630"; + "a25099811f52ad463c762197466c476a03951afdb3f0a457efa2b9475376652fba7b2d56f3184dad540a234d471c53a113203f73dd661694586c75d9c418d34cd16504356253e3ba4618f61cbee02880a43efeacb8f9fe1fdc84ceec4f780ba2"; + "990f5e1d200d1b9ab842c516ce50992730917a8b2e95ee1a4b830d7d9507c6846ace7a0eed8831a8d1f1e233cd24581215fe8fe85a99f4ca3fe046dba8ac6377fc3c10d73fa94b25c2d534d7a587a507b498754a2534cd85777b2a7f2978eec6"; + "a29415562a1d18b11ec8ab2e0b347a9417f9e904cf25f9b1dc40f235507814371fb4568cc1070a0b8c7baf39e0039d1e0b49d4352b095883ccc262e23d8651c49c39c06d0a920d40b2765d550a78c4c1940c8a2b6843a0063402c169f079f0ae"; + "8a257ed6d95cb226c3eb57218bd075ba27164fc1b972c4230ee70c7b81c89d38253ccf7ed2896aa5eb3d9fd6021fac000e368080e705f2a65c919539e2d28e6dd1117296b4210fd56db8d96891f8586bd333e9c47f838ed436659a1dafaee16c"; + ] + + let pop_filenames = + [ + "pop_g1_fips_186_3_B233_blst"; + "pop_g1_fips_186_3_B283_blst"; + "pop_g1_fips_186_3_B409_blst"; + "pop_g1_fips_186_3_B571_blst"; + "pop_g1_fips_186_3_K233_blst"; + "pop_g1_fips_186_3_K409_blst"; + "pop_g1_fips_186_3_K571_blst"; + "pop_g1_fips_186_3_P224_blst"; + "pop_g1_fips_186_3_P256_blst"; + "pop_g1_fips_186_3_P384_blst"; + "pop_g1_fips_186_3_P521_blst"; + "pop_g1_rfc6979_blst"; + ] + end) + (Bls12_381.G2) + (Bls12_381.G1) + (Bls12_381_signature.MinSig) + in + let min_pk_tests = TestMinPk.get_tests () in + let min_pk_tests = + List.map (fun (s, tests) -> ("MinPk " ^ s, tests)) min_pk_tests + in + let min_sig_tests = TestMinSig.get_tests () in + let min_sig_tests = + List.map (fun (s, tests) -> ("MinSig " ^ s, tests)) min_sig_tests + in + let all_tests = List.concat [min_pk_tests; min_sig_tests] in + run + "BLS Signature" + (( "Common features to both instanciations", + [ + test_case "Size in bytes of sk" `Quick test_sk_size_in_bytes; + test_case + "sk_of_bytes_opt and sk_to_bytes are inverse functions" + `Quick + test_sk_of_bytes_opt_and_to_bytes_are_inverse_functions; + test_case + "sk_of_bytes_exn and sk_to_bytes are inverse functions" + `Quick + test_sk_of_bytes_exn_and_to_bytes_are_inverse_functions; + test_case + "sk_of_bytes_opt valid values" + `Quick + test_sk_of_bytes_opt_valid_values; + test_case + "sk_of_bytes_exn does not accept more than 32 bytes" + `Quick + test_sk_of_bytes_exn_does_not_accept_more_than_32_bytes; + test_case + "sk_of_bytes_opt does not accept more than 32 bytes" + `Quick + test_sk_of_bytes_opt_does_not_accept_more_than_32_bytes; + test_case + "sk_of_bytes_opt does not accept values higher than Fr modules but \ + still on 32 bytes" + `Quick + test_sk_of_bytes_opt_does_not_accept_elements_higher_than_the_modulus_but_still_on_32_bytes; + test_case + "sk_of_bytes_exn does not accept values higher than Fr modules but \ + still on 32 bytes" + `Quick + test_sk_of_bytes_exn_does_not_accept_elements_higher_than_the_modulus_but_still_on_32_bytes; + test_case + "sk_of_bytes_exn valid values" + `Quick + test_sk_of_bytes_exn_valid_values; + test_case + "generate_sk raises Invalid_argument is ikm is smaller than 32 bytes" + `Quick + test_keygen_raise_invalid_argument_if_ikm_too_small; + ] ) + :: all_tests) diff --git a/src/lib_bls12_381_signature/test/test_vectors/fft_test_vector_g1_2 b/src/lib_bls12_381_signature/test/test_vectors/fft_test_vector_g1_2 new file mode 100644 index 0000000000000000000000000000000000000000..84a2023ca4ebe70f94b2de1d1cf7c1db8158dad8 GIT binary patch literal 384 zcmWd(&YNV$$>N#fe5CYe!uo4xD>*}6tMg5{wq<)^M9J+nSGf;9%=mW0tv6<5vz1j-*2T>m9JS%VKZ)sLjI==fYm%qm+{y7O@?J~D*`ZDjb zH`KK_3I@quxP3yXGTLRud>?7$J*Q$y{&MKPe|0S9Nv-3%h{i{X_x$$kt?l;tWW-o` z&E9_7ony9195-7|vCZEw^TfTv*6?HMf46@x=Mvj`zpyJ1|K=0oH|gJAc*5?Ra`ai-#^TdAmRW@Dz3OcpcSr1VQpRHev*n9(GYvDvR&f{^ zTbx!uSK*#p(qkUjs=W8``=4CAdaMtR+Zq^q{wtm{=YOR9q&a(DGCZ)ne3M)Dv1cFO z3#MwV4*6$pR(|(#*k;}^m{F_9G{-IB^*^!Vww0{5za0I{vjxmm)?Nw~UuJmud|>Dk zP_N?45FNw6)7I&~JIN$|a$2JCyr(xDSifrDFSVS~@{D_?=GhBBFW$4hcgNM^oR`G( z-i1;O4~ib2>E!=@b#7jR&R_p6O9Qs7(p@WU^tfp9Z0EDja~=P#QnK3;uA$GnjDvCM zkL53#tPLA$*=Gjvxjw%tCCD#d`%>Y1&Ns~-gW~MRU97Eo3d;lLy=qk2zM z$w*z$%rWsza!c)`1#R9(5RD8}1v-_zn!r`vw6_fm3}dhE}NBthWuQ z%37J!e%L3!pr?2Hoht{U++VnQC%-G+dzn9HS3;*)gmTJ9qcvRO_F+%O7YF}WN2j1vtM3DwdA-2* z{Mb#GGvPX6?5gDNjW=3^tubj za+8Xn_;&x$Zk?MSPk!jhTVGb)xUz&fD_uo79jD+sNfNcTRI`NYf-mx8I zI1|XW^vCjR6L#%XPhpgnQ{ORh-@7jFqe6U3eLVRepLx>Q9-iJY-{au(NhyAvlV|d6 z&bXveC}mZ{oLQ$690dZeC&@ z%T%@TZZAVvcHFzvFJ}&!N1c1MNMv8L;>?w+qIp(7Wej4Ak9ZYwj{R^t&+@AH3vce- vO`9SUR{Uy;sQQNR9eY1@IULQKI;W?gJh5=H#Uv}kn%`PG_rF|r&Lsl?ti7_v literal 0 HcmV?d00001 diff --git a/src/lib_bls12_381_signature/test/test_vectors/ifft_test_vector_g2_2 b/src/lib_bls12_381_signature/test/test_vectors/ifft_test_vector_g2_2 new file mode 100644 index 0000000000000000000000000000000000000000..234d97893c91c6dccd9739d94f019fc2f40af2e2 GIT binary patch literal 768 zcmd;G)VpVyNzM7HjH_*RC%V>}f4#i;=KkA%u65*>TdpZGJ-5(VheK%)$$} zxn|tUP2XL<`r_iY+xE{?+LyjoONr0$TK?}3*TeYLAF?F-dVHqbcifiweebodx260q zO7AV-825l*?9Gv)^$H66`PzSPWY%9|xoaug1KskOXKv?wzj5|+?#CY|w=+&=3+0!b z{#NVZ3GEZ6th!H_yfjuZv_J0in|%6nQ;heN>*+O%8 za#LJ*f+??h+HPqR@BNOq@`R>Ox!%z0nEdh5uT`RRPc2Ch-h8&1Qy}@}vmCZLHqYCF zm!A%a<19brZsdE>fwM}$sg+}O0Na**Uke*U^qzICeVWhUZk8V&@6ob_i*rS%&7LBr zf6H(GPBJBx5^LYf36gr*LeJ`@z+gF z(~DkD3EDC(>x$a?_b1l+o%?f7Sz+rIhlL$GzD_Y;_u;($%EANQ#}kDLZ!MUAEOOGN zu1}wAEo?Jsxf%dp+JrO! literal 0 HcmV?d00001 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B233 b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B233 new file mode 100644 index 000000000000..630d241a7c01 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B233 @@ -0,0 +1,60 @@ +00 0056673197bfeea9bd7a8b820b4ae51a50411bf118a692bb9ed3d304da53 b754a85e7658a5dd042ab85154b77ac4fe692f67c7150e52df3ad03eebc8b8f4d74aa82a80dc316d71f31ef3c5e4bb69 +00 00468f01d483144e514ec257f2e5fdee28a927f2adb19714c1f3524dd0d3 b6c01a52475b706f991ed08c73536926535edc4b1efdafbb7b7ddbb5d0fd535ac6cbf8006ad247cf9e952d7f55c71df2 +00 0074052d027f05465a8083a59cdbf32600224e1f563f653b34314651517f a3708e2ac7751dc78cb2b30bc117ad165cd3db1e4e516aad37487289365addc6e406785dede6cc92dc4e4d69906f8a9e +00 001856e7544223f55f80de72a6ef3822fa8fbd68eb397d06e2d76ddd35e0 b28a30e60baddb6a5d98ddd190abd693cd1e442ebb12198b1bd298b3886098eb77542d7e2fdb7fa891a684a8c07546c2 +00 00860aa2b589f2defc617be73e191502e5d9952bf60547fef19eeccbca26 8a65f49113cc95ae027bff1310cadc330ec5d09e5034e587c4f78bd5621b46eb75a426b57833dfc65dfeb61804ae8908 +00 00d0dec052a00ccebd0c0c5d9a08272f75744a2582cec7ddd924a2b022b2 8b05d1a76b1c68a4f9e8959c62c66f5ee1c833dd9acd8fe04616367bd39e832174f88e2796ac0d2e8a96a19bdd71ed47 +00 008a017d717d6d1213f2b74c53281b07258738c0c7db649ea1ac46b9a3b6 8665a6befa5963a5d8372535b851f16709410a27922d205415e7f7bac4338dfe5557fd8bdd7b8aa31d82023bf8e22d0a +00 001b56c14442b084cfd22aeef0f8028ec57c8b571c9fc1e43de05c45e47f ac6436e41be6c2534b254f51a62d2d89cb8f2e4566035ee7adf595fb41175e9ff01e52b72cec5866637bc28ce7658171 +00 005afce37c5594586ac46a34ae291f591eacb9880a7de92701977f447fbf 9988b985a98478685b6902316a3ee6d84dcb98aa5a7ede42e172b8e8c3d103639f681cdad8c1ad022daf12c05a0384d0 +00 000696df05dc7a54a9908a73eb18416a155cc8df4ab26032539d86eae537 89781f07339dfc3dd3f599e919c79af126130d01c06c1c534a0536cf75568ace9c486e1f99a0954de764c6ca7dd6c554 +00 005ca31e88c5b2e96e433af2023a66095161710628e7bfa428944d6676b8 81f07abec3c99081023c1ad717e7eccbff88bf729793393fed59471a4f1312a8ab0fd01c844051ef3d1f5ca9c717cccc +00 00ef8fe84727a2ad8bf4e646ef28a492adfaf785a3a2ba6e6f985c649a8c 95086689dc428917fa190456f093181c23073bc875dac43f541b863aa0adb2bd3329e79a6ac4be0ce7a569bb1723df65 +00 003edb94b8c62f9af30c14a790c0f5d65e362a21cd8569b9725916d534c0 b1a7124815a8492c7b8e7149057bf992a09387cd5760f297a94b850bedaf46847e57075ba9ca20b0703ae061dc8ef144 +00 000a7519be62562318da1b67d22cf8e720353d22641e0cee11c7a352bb93 ae1709390236914bcbe8f17adccd92f79604c29ddb8fad4ff8237276966d5c05bb7c54279e1107c2136a4f1a16c2f8a8 +00 00264022fd7dc2328a6436b522793ad9406d7a586667a0daaf1bce927338 8796c0d0de390c6d852e6be13e0e56233ee85d525a6d7c72b9a9040fc21f43fffbee7e44e98eaa5aa69f73354495598d +00 00da43214e2efb7892cc1ccde6723946d2a8248a6b4d6c8872fad525ec3b 8ac1b149a313ac4b6ecec457c00cf949585b4f8fb8731d80911881b2f690c8fcc412766ac5b1c3c25468f637341ceca7 +00 00aeafa49d776b61f6a30d66ff64bd40dd8d79891dd5293c1b5cd3b46a7c b21b63f9a4f836ee03f2ac1061aa410e1e58c93cf08988af2921d92a577ba85e394d6f840880f96bf72f64c1c581c8f9 +00 00e95db309f4305b621f51f93588a2678cb19aad0932f365fa0aaa3a3895 ab1f2cdab3119d5f383804d63692f074ba694ea7c70bbe7c7925c9c946fdc5a4eab4e40b1bc83dfdfed2fc4880d162a5 +00 00d4319cc8e409b8755880827f3200d3f0f1c64d6356fe74eb1f5aa42499 b01e0c3396d4620911519ff5a286a4dd77fe4d0f162bf792823696735f348cb5fcf93cbfe9e6f39ec3c2ba6b3ad39b56 +00 009e556c945052e5954915c773b2d47970c521fcc99139269c3ef46093b7 b23f67407aef0c7ed43b4134b01df8c55c5a61157a495f0e0d7fad676d466b81dbf457e88df90d0d013537807ec41de5 +00 00becc76f8a77615c4f92ae1f91645bf5bb908e75ef22fd544aae63a3c8e 8e5215851c8ff0a581df89b724ddd0447f17dbf5ad2a4594a1c55f6acedb35fb5369a457d18eb86b5dc88dae6b6c57e2 +00 0020572c2a3dc3ea430cd8cde9d642081c21658e8bda165550cd9a5d37d9 8370a007453ee8f2140d2490e3a2ecc7553647f8fa9ca579a65d2c214e028168b739636df77bf1e2402366491d6ede14 +00 00769cfbf2dd8248ea1e0ac9b275c9d6ddcf923fe762079b9ed62ccbaa89 8c16e58e6ad1a015cb0a2fe13c258d737911eb4c11a059cc3b24706b07687014c2f0a852252d155fbbe6833884f16201 +00 0040ea4a37b388f0cc464f7e2bf92173107b268ff77a8acf5f517b4ec0e4 a9c1ab27f28ceaaf2daa1cb854e48e8f52d4fdaa4ef3c1b19d17e2ba083395b20371f5ee73a8f61bab70febd7617375b +00 0037fc7898df9b37b5390537352f5c0b8de22659166c19d7d4df31c3938d 91d8c95230ce222cbdbf4e2da3d32a523ad3c8c027c29cee6269c965db54d8be2f9df36a5ee29a3b5a83245b44c08731 +00 005d5069425e7a9925d2cfc6360a708147b2c1b55ede243591885147ef3b ab2f28a1a05abafd7d510cf834bb9960cce5fff79443338fb9fef1670baf59d803b8e7301f6bd33cdc39a64a91f37347 +00 00ffe3e7b82ca62b96e057ee072a4718ca20a6cc9a3e51e4fe8ed7b4b9f9 8ab18cdbb902bfc0f089f8498ace206a8eb8368db9924b05c4981d6a273279925dd6c53ee92a07579b8cc0bf6a20095c +00 0007a9cb5ce27c763646de414ca2a4dcdb774d69ed2bde7a817baddbc9de 981b6f38cf07fbfdb1768e229ffe78ad7907da51e391f7181844cb33b1422b5d7762d8c8ffb95637f60a9be99e5b5ad6 +00 00c03fa9e38dc1c697f70bc6381f2bacaf860bb5632fc837f728da959ac9 b10b8d7319debd34316225eb1e1d61086287f2a2c164e478c72cdaeecc95fe33c906e6a57ec78a8ca34443a72990b4da +00 0087dba00e3fe4802e01718017510094924496bd2785d4ac1a352c530473 88f788ad3b7db4345fadafc31848e6ddfea6753e29d864388d11bfad4ae95c77ac9f6c2a7fd2d36d8f4bac4e0b74aee2 +00 005a387e7affc54a8fbb9157b5ebd400c98e2d7bd5c3e095538987d4f8d9 b5e2a0ea8f4b5e38c6e6a90df63928fe6437516f82fd1778316d425e733d43641c84b5beda1a0bcec1638b5df9826ce8 +00 00adae709a930d6f5a5c0e3d8ef4aab004d741d23f0ffb8287f7059890c0 b4a6ee0aa45219fa13fb1ab1f4322a7a2410746395f6c1fd5bc95f9bb31e3e1f92d452623a814ef59856bf991eae9907 +00 0035d391411e6d679751092c4ea5a079c591e77ebdcb57c1d9006ae70d90 82e2af60b523f0b355b6f5b3f09c8df297caa09c43c1139ced791f90572ba51bf3fa860c288af0d0409f0afe4a706b78 +00 0084e79093f1947d6ab9cf399782436e36ef87c59a4c090930c9a74ddb10 b3bddc805ec1ee6a38dcff55d0014c176aa30b55e8fd9dd9ac68c8d4181867f8932a41f47673f6f4f4dfa52edd7e1ed8 +00 0079b6be015b8006f86fd81c2792bec6b42c08bee2d295cf9dc214c326ab a3ed224d56a205af8f45f412f5f34ada666254803b25887acd185a85c12b668067bd068ff39b2d025ef5bef71a5829ea +00 00ca9d751a060fde64336cdc88122819f4b3cd1b4e7df42d495197787894 b7ec7e94a4cfd7e5469d063b75fe9d3cc256eb8bebaa901aee42ce83a7772822602b80ec3a762735c10d458461eea215 +00 001dde4b2d49338a10c8ebf475b3697e8480227b39bc04253a0055839e9e 826ee633bd9b0afb9ce2a13b2fa5c5b673eaa6c65dbe8b8ed910656f8c545a680ad8349861e16fc45ca5e5ae32a8e6c9 +00 002c8bea2803fd746c874fa110a716538c179c82712f38d33d0f6d037e7a 844268e070ba7917daab5ed9d929664aa2bebda9906e25d5f9eb9708377cce778a762b56aeebfea63cb824ebae2121cc +00 00b9119b3b4b30cbfb98ddf0a4f6953417e515fcf0e5a94e83ebc1d1d14d 8fe54dc1ea3d6ceb223375674d63a0bea43c196a63ead9e7f3c6bcd9c35a76b32ba36f5bbc725e8ec15a53bc0a0c8007 +00 00f4ab2a573f3771d1e4222e251faf14e06cefed544e804c299c9a8395f5 81306aa407b8ddec674c4e66050ddadd32bd1c7cdae0cec8e0fb7e21eefc11f54102995e6f8f346e099795f228612874 +00 00f4649cf30d4a5269296a45977de2652cb06d3ca2aff4475bb24517b927 a65e698c2b24aa2a56e29d21ba87d4ff4688f095399914b870c57a974d60e820b8999edff4101620beaf64541ab0e83a +00 00cca24ad914c24c011f41f80d27ea41caf41fcc8dc9dc6dff5248b2b474 a5b4f764997d789e9a3d9381b30a515f9f95bf9c2bcfa49df68424f77bca2cba751256261a458a98af1ec100077ba3ad +00 00f5e12d536ef327e3b0ba65ac5fc3f7f4880f5968f3340eb8868c1d47da acd0015076e62ad50da547ac149ea2b724962dc6b6cf3e4294b5d3d61d7d670fa9252ef56dbfe02bb61e9c03e87d35dc +00 008c30d93536b8cb132277645021775d86c2ba8f199816c7539d560ac6de b2cbb93868cddc13c4e47d4b257bc2f292ba88f475536c741eb6cafe99da96a18f40696e131790141774cbb3af288999 +00 00fa3f15a506ccf7b50bbbad0a54d3223f5a95eb54f0d1f4e5d0cc21469b 87a0c0088f8f8c4ccf3afcbf448eaafe8f2b9b64f3f266a121aedb0463ba69cef61251139fb1676710c61f2326d853d1 +00 006400a4830889115aa88b860b3fb65905b01fd126c4aec2785518c2543a 9752fee43aa90576d2dfdceff21d77518e44806ef737059c323acc256635c986d0894b694bd52aeb323e715374907e88 +00 00c7b73c324250f14fac0edc941f79bdbc6933ee8f64bf94b847bee5eef6 80f8409354423c827f3ee3638fc027886421a9f8b56c907d33e17538b4ecf4d006186aa8e6ad6724f8787a645e026c99 +00 003db7f28e161abf52ab0adc8c4c8544fc989af081303b8688f22b7b2eb7 8ffd794ca77180d1b65517b6bb4404ed41ab75c5c7ffb663db29387b5003a3f1f89d2ec56e0bc7dbaa1cdde24f0f8b70 +00 007e9d2fdd017d6da6029e88f78927d9ac9437f542db1f1fa99e32bfcf1a a556374c867c8ae39e4566076eef735d2864aa965526791ca63c2556e38de8d77b9f842b15a1f3a33069dd5b69e088ef +00 00c94052760fc74c2b405ee4dd5dd2a7d38ebc16df9cc32df706075450b5 a74e1a52894f5384df7d61c3db07c2b10fc0067f3d238dd38331417b0bb31e28017d1a5fdd636da336c4157909c94405 +00 004076b93487c2da8aeaeb4725fb53b7b41b465315335c18c6ca041175b4 a365e9b78c53c44056e852e6e93e7e5f8ed4c2c04c6e04afb231a5f89df0b7b94b7870756ee83949127dcf816f84215c +00 0076ddd73ee4fc1f5e6766e229cc7236cdfce312417ea291f7c3328d5ab1 a54bfd4dafd2cced8033cba94757f5951485a8b41a6661f811584bcb00f3c9a91c9e9dc2f1d82412e737aa1c5dd3ec1c +00 007e1f8988ad804aae7d09a99be19384cc599e7652c02c391542be74b17b b9df3088507616be45fcdeb56a56947ea8fc27d940bf7b9fa5a940eb4d4e582c76427dbc9436ed416f7b654a3402ba71 +00 009b2292b0244c2aabe8b43d95039984d504ebe05eaff318760e4dee739f b25dfc4d0ee72729325692534c2b2a69bd52d2e9534251d5a124e12fbf045852b663c81ba80e6d5164c64376e4e1af96 +00 007ca463b50fdd92d9163f1c2bdfce2ee45ba1437b79162e3e959b814cab 86be073b08862e8af6bf292e63819393b8e741f4428ab9ed1d2ea8c3054c22b91cecb9f81d8f1fe37845c2bb1071c671 +00 00c3844750f63fe0c2e930bc38fe88522f4e72a2fd0db9778ade20e939b3 913d7c3579c2becac229c56cc21adcbba486427ef2e5dc1ebc04a3da2ee56481f97a6b4fa18964cf34fac7fd734960dd +00 00a3bea235dea86506be4476eb7999dcb8e584a34238c4a894ad6823b93f 932d460247437ab65b6de38bb5ad8a940ff8e756cfa1d89e0cd28c6b99da4b6721d5caed89e023520a7598990f8226c7 +00 009a367cd1cffd8dfcca179e167ea437ee48e9b6f42559dda9224701d3f6 abc6f556b8f43b9a35d3b9c646e29a7456e362ce119ad29c894179f20bb152d9824ddece924887fbf2a98272e352b680 +00 0046f4ad2522e78b9b35297d28f361fb0ce82306322aedc119251d8241be a300185d65320e1d1d20807c8248836c0d8f4f89de5b643e6d93d3e104c50dd6efdc2c58dc2df47da8e0c3b72fef094c +00 00ac82137e9c7a5ecfb8b1a7df9ab50732934566a392a6c8915ee8ca8144 9147fc93191026bf1b14c46bcaf2929a6dc8d59695a1685cf77a20406dac5f2e4e58338de03dadb2a5cb87f82214026b diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B233_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B233_blst new file mode 100644 index 000000000000..630d241a7c01 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B233_blst @@ -0,0 +1,60 @@ +00 0056673197bfeea9bd7a8b820b4ae51a50411bf118a692bb9ed3d304da53 b754a85e7658a5dd042ab85154b77ac4fe692f67c7150e52df3ad03eebc8b8f4d74aa82a80dc316d71f31ef3c5e4bb69 +00 00468f01d483144e514ec257f2e5fdee28a927f2adb19714c1f3524dd0d3 b6c01a52475b706f991ed08c73536926535edc4b1efdafbb7b7ddbb5d0fd535ac6cbf8006ad247cf9e952d7f55c71df2 +00 0074052d027f05465a8083a59cdbf32600224e1f563f653b34314651517f a3708e2ac7751dc78cb2b30bc117ad165cd3db1e4e516aad37487289365addc6e406785dede6cc92dc4e4d69906f8a9e +00 001856e7544223f55f80de72a6ef3822fa8fbd68eb397d06e2d76ddd35e0 b28a30e60baddb6a5d98ddd190abd693cd1e442ebb12198b1bd298b3886098eb77542d7e2fdb7fa891a684a8c07546c2 +00 00860aa2b589f2defc617be73e191502e5d9952bf60547fef19eeccbca26 8a65f49113cc95ae027bff1310cadc330ec5d09e5034e587c4f78bd5621b46eb75a426b57833dfc65dfeb61804ae8908 +00 00d0dec052a00ccebd0c0c5d9a08272f75744a2582cec7ddd924a2b022b2 8b05d1a76b1c68a4f9e8959c62c66f5ee1c833dd9acd8fe04616367bd39e832174f88e2796ac0d2e8a96a19bdd71ed47 +00 008a017d717d6d1213f2b74c53281b07258738c0c7db649ea1ac46b9a3b6 8665a6befa5963a5d8372535b851f16709410a27922d205415e7f7bac4338dfe5557fd8bdd7b8aa31d82023bf8e22d0a +00 001b56c14442b084cfd22aeef0f8028ec57c8b571c9fc1e43de05c45e47f ac6436e41be6c2534b254f51a62d2d89cb8f2e4566035ee7adf595fb41175e9ff01e52b72cec5866637bc28ce7658171 +00 005afce37c5594586ac46a34ae291f591eacb9880a7de92701977f447fbf 9988b985a98478685b6902316a3ee6d84dcb98aa5a7ede42e172b8e8c3d103639f681cdad8c1ad022daf12c05a0384d0 +00 000696df05dc7a54a9908a73eb18416a155cc8df4ab26032539d86eae537 89781f07339dfc3dd3f599e919c79af126130d01c06c1c534a0536cf75568ace9c486e1f99a0954de764c6ca7dd6c554 +00 005ca31e88c5b2e96e433af2023a66095161710628e7bfa428944d6676b8 81f07abec3c99081023c1ad717e7eccbff88bf729793393fed59471a4f1312a8ab0fd01c844051ef3d1f5ca9c717cccc +00 00ef8fe84727a2ad8bf4e646ef28a492adfaf785a3a2ba6e6f985c649a8c 95086689dc428917fa190456f093181c23073bc875dac43f541b863aa0adb2bd3329e79a6ac4be0ce7a569bb1723df65 +00 003edb94b8c62f9af30c14a790c0f5d65e362a21cd8569b9725916d534c0 b1a7124815a8492c7b8e7149057bf992a09387cd5760f297a94b850bedaf46847e57075ba9ca20b0703ae061dc8ef144 +00 000a7519be62562318da1b67d22cf8e720353d22641e0cee11c7a352bb93 ae1709390236914bcbe8f17adccd92f79604c29ddb8fad4ff8237276966d5c05bb7c54279e1107c2136a4f1a16c2f8a8 +00 00264022fd7dc2328a6436b522793ad9406d7a586667a0daaf1bce927338 8796c0d0de390c6d852e6be13e0e56233ee85d525a6d7c72b9a9040fc21f43fffbee7e44e98eaa5aa69f73354495598d +00 00da43214e2efb7892cc1ccde6723946d2a8248a6b4d6c8872fad525ec3b 8ac1b149a313ac4b6ecec457c00cf949585b4f8fb8731d80911881b2f690c8fcc412766ac5b1c3c25468f637341ceca7 +00 00aeafa49d776b61f6a30d66ff64bd40dd8d79891dd5293c1b5cd3b46a7c b21b63f9a4f836ee03f2ac1061aa410e1e58c93cf08988af2921d92a577ba85e394d6f840880f96bf72f64c1c581c8f9 +00 00e95db309f4305b621f51f93588a2678cb19aad0932f365fa0aaa3a3895 ab1f2cdab3119d5f383804d63692f074ba694ea7c70bbe7c7925c9c946fdc5a4eab4e40b1bc83dfdfed2fc4880d162a5 +00 00d4319cc8e409b8755880827f3200d3f0f1c64d6356fe74eb1f5aa42499 b01e0c3396d4620911519ff5a286a4dd77fe4d0f162bf792823696735f348cb5fcf93cbfe9e6f39ec3c2ba6b3ad39b56 +00 009e556c945052e5954915c773b2d47970c521fcc99139269c3ef46093b7 b23f67407aef0c7ed43b4134b01df8c55c5a61157a495f0e0d7fad676d466b81dbf457e88df90d0d013537807ec41de5 +00 00becc76f8a77615c4f92ae1f91645bf5bb908e75ef22fd544aae63a3c8e 8e5215851c8ff0a581df89b724ddd0447f17dbf5ad2a4594a1c55f6acedb35fb5369a457d18eb86b5dc88dae6b6c57e2 +00 0020572c2a3dc3ea430cd8cde9d642081c21658e8bda165550cd9a5d37d9 8370a007453ee8f2140d2490e3a2ecc7553647f8fa9ca579a65d2c214e028168b739636df77bf1e2402366491d6ede14 +00 00769cfbf2dd8248ea1e0ac9b275c9d6ddcf923fe762079b9ed62ccbaa89 8c16e58e6ad1a015cb0a2fe13c258d737911eb4c11a059cc3b24706b07687014c2f0a852252d155fbbe6833884f16201 +00 0040ea4a37b388f0cc464f7e2bf92173107b268ff77a8acf5f517b4ec0e4 a9c1ab27f28ceaaf2daa1cb854e48e8f52d4fdaa4ef3c1b19d17e2ba083395b20371f5ee73a8f61bab70febd7617375b +00 0037fc7898df9b37b5390537352f5c0b8de22659166c19d7d4df31c3938d 91d8c95230ce222cbdbf4e2da3d32a523ad3c8c027c29cee6269c965db54d8be2f9df36a5ee29a3b5a83245b44c08731 +00 005d5069425e7a9925d2cfc6360a708147b2c1b55ede243591885147ef3b ab2f28a1a05abafd7d510cf834bb9960cce5fff79443338fb9fef1670baf59d803b8e7301f6bd33cdc39a64a91f37347 +00 00ffe3e7b82ca62b96e057ee072a4718ca20a6cc9a3e51e4fe8ed7b4b9f9 8ab18cdbb902bfc0f089f8498ace206a8eb8368db9924b05c4981d6a273279925dd6c53ee92a07579b8cc0bf6a20095c +00 0007a9cb5ce27c763646de414ca2a4dcdb774d69ed2bde7a817baddbc9de 981b6f38cf07fbfdb1768e229ffe78ad7907da51e391f7181844cb33b1422b5d7762d8c8ffb95637f60a9be99e5b5ad6 +00 00c03fa9e38dc1c697f70bc6381f2bacaf860bb5632fc837f728da959ac9 b10b8d7319debd34316225eb1e1d61086287f2a2c164e478c72cdaeecc95fe33c906e6a57ec78a8ca34443a72990b4da +00 0087dba00e3fe4802e01718017510094924496bd2785d4ac1a352c530473 88f788ad3b7db4345fadafc31848e6ddfea6753e29d864388d11bfad4ae95c77ac9f6c2a7fd2d36d8f4bac4e0b74aee2 +00 005a387e7affc54a8fbb9157b5ebd400c98e2d7bd5c3e095538987d4f8d9 b5e2a0ea8f4b5e38c6e6a90df63928fe6437516f82fd1778316d425e733d43641c84b5beda1a0bcec1638b5df9826ce8 +00 00adae709a930d6f5a5c0e3d8ef4aab004d741d23f0ffb8287f7059890c0 b4a6ee0aa45219fa13fb1ab1f4322a7a2410746395f6c1fd5bc95f9bb31e3e1f92d452623a814ef59856bf991eae9907 +00 0035d391411e6d679751092c4ea5a079c591e77ebdcb57c1d9006ae70d90 82e2af60b523f0b355b6f5b3f09c8df297caa09c43c1139ced791f90572ba51bf3fa860c288af0d0409f0afe4a706b78 +00 0084e79093f1947d6ab9cf399782436e36ef87c59a4c090930c9a74ddb10 b3bddc805ec1ee6a38dcff55d0014c176aa30b55e8fd9dd9ac68c8d4181867f8932a41f47673f6f4f4dfa52edd7e1ed8 +00 0079b6be015b8006f86fd81c2792bec6b42c08bee2d295cf9dc214c326ab a3ed224d56a205af8f45f412f5f34ada666254803b25887acd185a85c12b668067bd068ff39b2d025ef5bef71a5829ea +00 00ca9d751a060fde64336cdc88122819f4b3cd1b4e7df42d495197787894 b7ec7e94a4cfd7e5469d063b75fe9d3cc256eb8bebaa901aee42ce83a7772822602b80ec3a762735c10d458461eea215 +00 001dde4b2d49338a10c8ebf475b3697e8480227b39bc04253a0055839e9e 826ee633bd9b0afb9ce2a13b2fa5c5b673eaa6c65dbe8b8ed910656f8c545a680ad8349861e16fc45ca5e5ae32a8e6c9 +00 002c8bea2803fd746c874fa110a716538c179c82712f38d33d0f6d037e7a 844268e070ba7917daab5ed9d929664aa2bebda9906e25d5f9eb9708377cce778a762b56aeebfea63cb824ebae2121cc +00 00b9119b3b4b30cbfb98ddf0a4f6953417e515fcf0e5a94e83ebc1d1d14d 8fe54dc1ea3d6ceb223375674d63a0bea43c196a63ead9e7f3c6bcd9c35a76b32ba36f5bbc725e8ec15a53bc0a0c8007 +00 00f4ab2a573f3771d1e4222e251faf14e06cefed544e804c299c9a8395f5 81306aa407b8ddec674c4e66050ddadd32bd1c7cdae0cec8e0fb7e21eefc11f54102995e6f8f346e099795f228612874 +00 00f4649cf30d4a5269296a45977de2652cb06d3ca2aff4475bb24517b927 a65e698c2b24aa2a56e29d21ba87d4ff4688f095399914b870c57a974d60e820b8999edff4101620beaf64541ab0e83a +00 00cca24ad914c24c011f41f80d27ea41caf41fcc8dc9dc6dff5248b2b474 a5b4f764997d789e9a3d9381b30a515f9f95bf9c2bcfa49df68424f77bca2cba751256261a458a98af1ec100077ba3ad +00 00f5e12d536ef327e3b0ba65ac5fc3f7f4880f5968f3340eb8868c1d47da acd0015076e62ad50da547ac149ea2b724962dc6b6cf3e4294b5d3d61d7d670fa9252ef56dbfe02bb61e9c03e87d35dc +00 008c30d93536b8cb132277645021775d86c2ba8f199816c7539d560ac6de b2cbb93868cddc13c4e47d4b257bc2f292ba88f475536c741eb6cafe99da96a18f40696e131790141774cbb3af288999 +00 00fa3f15a506ccf7b50bbbad0a54d3223f5a95eb54f0d1f4e5d0cc21469b 87a0c0088f8f8c4ccf3afcbf448eaafe8f2b9b64f3f266a121aedb0463ba69cef61251139fb1676710c61f2326d853d1 +00 006400a4830889115aa88b860b3fb65905b01fd126c4aec2785518c2543a 9752fee43aa90576d2dfdceff21d77518e44806ef737059c323acc256635c986d0894b694bd52aeb323e715374907e88 +00 00c7b73c324250f14fac0edc941f79bdbc6933ee8f64bf94b847bee5eef6 80f8409354423c827f3ee3638fc027886421a9f8b56c907d33e17538b4ecf4d006186aa8e6ad6724f8787a645e026c99 +00 003db7f28e161abf52ab0adc8c4c8544fc989af081303b8688f22b7b2eb7 8ffd794ca77180d1b65517b6bb4404ed41ab75c5c7ffb663db29387b5003a3f1f89d2ec56e0bc7dbaa1cdde24f0f8b70 +00 007e9d2fdd017d6da6029e88f78927d9ac9437f542db1f1fa99e32bfcf1a a556374c867c8ae39e4566076eef735d2864aa965526791ca63c2556e38de8d77b9f842b15a1f3a33069dd5b69e088ef +00 00c94052760fc74c2b405ee4dd5dd2a7d38ebc16df9cc32df706075450b5 a74e1a52894f5384df7d61c3db07c2b10fc0067f3d238dd38331417b0bb31e28017d1a5fdd636da336c4157909c94405 +00 004076b93487c2da8aeaeb4725fb53b7b41b465315335c18c6ca041175b4 a365e9b78c53c44056e852e6e93e7e5f8ed4c2c04c6e04afb231a5f89df0b7b94b7870756ee83949127dcf816f84215c +00 0076ddd73ee4fc1f5e6766e229cc7236cdfce312417ea291f7c3328d5ab1 a54bfd4dafd2cced8033cba94757f5951485a8b41a6661f811584bcb00f3c9a91c9e9dc2f1d82412e737aa1c5dd3ec1c +00 007e1f8988ad804aae7d09a99be19384cc599e7652c02c391542be74b17b b9df3088507616be45fcdeb56a56947ea8fc27d940bf7b9fa5a940eb4d4e582c76427dbc9436ed416f7b654a3402ba71 +00 009b2292b0244c2aabe8b43d95039984d504ebe05eaff318760e4dee739f b25dfc4d0ee72729325692534c2b2a69bd52d2e9534251d5a124e12fbf045852b663c81ba80e6d5164c64376e4e1af96 +00 007ca463b50fdd92d9163f1c2bdfce2ee45ba1437b79162e3e959b814cab 86be073b08862e8af6bf292e63819393b8e741f4428ab9ed1d2ea8c3054c22b91cecb9f81d8f1fe37845c2bb1071c671 +00 00c3844750f63fe0c2e930bc38fe88522f4e72a2fd0db9778ade20e939b3 913d7c3579c2becac229c56cc21adcbba486427ef2e5dc1ebc04a3da2ee56481f97a6b4fa18964cf34fac7fd734960dd +00 00a3bea235dea86506be4476eb7999dcb8e584a34238c4a894ad6823b93f 932d460247437ab65b6de38bb5ad8a940ff8e756cfa1d89e0cd28c6b99da4b6721d5caed89e023520a7598990f8226c7 +00 009a367cd1cffd8dfcca179e167ea437ee48e9b6f42559dda9224701d3f6 abc6f556b8f43b9a35d3b9c646e29a7456e362ce119ad29c894179f20bb152d9824ddece924887fbf2a98272e352b680 +00 0046f4ad2522e78b9b35297d28f361fb0ce82306322aedc119251d8241be a300185d65320e1d1d20807c8248836c0d8f4f89de5b643e6d93d3e104c50dd6efdc2c58dc2df47da8e0c3b72fef094c +00 00ac82137e9c7a5ecfb8b1a7df9ab50732934566a392a6c8915ee8ca8144 9147fc93191026bf1b14c46bcaf2929a6dc8d59695a1685cf77a20406dac5f2e4e58338de03dadb2a5cb87f82214026b diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B283 b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B283 new file mode 100644 index 000000000000..f0304f5759ac --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B283 @@ -0,0 +1,60 @@ +00 0299ff06e019b5f78a1aec39706b22213abb601bd62b9979bf9bc89fb702e724e3ada994 93cb567034ecbdb31141b3b3cbbf0e85a4a99859af4fc314dc747dead113b1c671c289672edb6bb9b4e87695c2a62a05 +00 009c2804f8cab768248fb3fff8a055b3f4585c00de5c1615a19f9425b9432ea09afba8f2 94fc41a9a08b181938aafb5b457cfda2a60a4e94345e1d595c328f9c178ccd02386b281e0adcea97da5ad7f2ad5d5250 +00 02e625a6bc6d0ce7c06231de827068bdb0abc8ffb57c82b35ee3a0f873b9473905974d34 adb065ab3b1f8f5eca15b2e5368fa5528f123a93a2e33ff1b38b1e8087ca56c9d4693deb7ed5863351fdfc95fb95103c +00 0376ac24e1b86f8a55c052d92a0bdc6472fa03acdcdbccbf7c321ec0ccd97aa0a66b4181 8adcd8b46d72b1bb4ac749697e710acaccada085921f506d4ba4fac85064da3bef8d8580c87de57a1a4d5c1d571539a4 +00 02b50a6395fc02b9ac1841323de4520292f913519bc0d6a471aa28021322fc4dbcd7b802 b7fba7f35d656d271d1356fd781ebe267ee78814017fa9e33ad31498b778cc345f759133eb7b8433a5bc10fcb2c1a770 +00 024e5889722f6c35e18ca47effa9e415b1ba790066a91fb3c9f7b001ce28fc732b09bc23 99776912771995c8a842cae0276421e53375c03d9c05a9eadb11ce1caca5be290987b2dd694c4dc0461c903b50c79886 +00 0056d15b81f40b6378588a5efe43e21b95e18120d514bfdda0e7759a1d0766a8a35ce5ac 8e46a3b6916ac41cb8f4cef378a5f392ae8156cc1ef6a79b3e586d157b46fae0bde9d4d26cc69a9b8a9121832c17e251 +00 012fb2fb5bf5f7e42a500154823a174ba2d05af71e3b0cf47fab46e673ea1822f1563def 85ec0554f794c37e075b09582b27849c21c4a4d3574fd20ef13720fa63a28cc63aade15fa89b7837d1d8998fad9777f8 +00 030096c54fd480647e017f8cdbbdef292e799f054e3279d228b09816a757566a744a8266 a9867dcfc35ade246c6938807fc4dff8482b867c0113b56d06928226ba23ae1172d4f5f3c44869d5f9ef30b06e383e6d +00 00a1b7e9c8c2dc25b494b5ef3195b294e41cd3c2c35235ab42542bd3e2a52d5826662bf9 81f1fa2dcff086e3c90c1cfe5fed45a408b6ae7e09bf250a709fa6742011f5f49f9409e4f192eb29ff94c7789ba54bb3 +00 0059b1a8fb84530bba7a607ee88310e31bc6ea6a6881603567a1081a05a3a9ff87e719ef 8d2fd540ede30a6343ed67798a8e234749ae7f20122f4cdc10d754714b0214e5d3259a531c6fe69683bb7309da3d5e65 +00 030ddc2c7a4ce300cc2b75f0f977033f16c1f8bb13aae3d494c381f9a6dc8622499ae4df 8a3f21e0a42454ca0cb8fb25f093a6e4bbb5c64ff43e03355a5d61b2db3f85a38e3da262437083c42f7bfc7fa89e7447 +00 007899928922fbfdb5407517725edf231d15a8b62d90b7fb6d8c8d20424850dc44f797ed b7f27e66617f3c292f659228b1787703df78aad6bf2a8cff4873cedc989051e0dea3a22ad602a13e1d7881a5d30a247c +00 02a2af63d1171930758bd3e5bfdac62cca1a83a3b55a49b3f80cf0d9ee4b2082757beac0 b1facac83fdf893862e1dc29178327cc5efd85401ee7ee797b8090dfa8652f8f72bdfcc45d04fdf12edad761bd4ba7d7 +00 035994e89e13916ad82608f74a639e6aceb756ff913aec440519946d6434af9a60a6af49 8744350555f95bcdaa219423e2cb240bcbe12db754db7c059da83ed7eb4680c377f0226929eeea5ec4d79a5451ad5f4a +00 029639da33f48e4fb0d9efdf50bba550e739f0d2476385cba09d926e789191b6fb0a73ff a37429f128b69dcc57030b8566e85de4a0418ad188c073367a68aafab0fdd70173b0347567e7a8080964dbae00d91197 +00 00583a7ecbf2a975a32d07428d27ac82e5dc13d1466c4fdfc1e6a05a8d9a289f1010617d 8f42a2b4c045c16cada913c2154ae4922c5db50f27d879699dfaf8f0b9c6e9a394ac8bf5cf8e403521cde5fbe8e9e4f4 +00 00f817ab1b49131fb9bbe8c112c25a36f064efa85de7506fb9cd29d81b326bf276277f7f aa5a8633aad800a9d06ab4a28e86675402ae3151703144edbded8c53553ab108a56ec68a0d3bd3c43aff85d36acf6147 +00 02782af76ffebf3e2bfc0576b70e4f4bb87c762e2bb230d278ce776310a14f5b678f29af a1990bc12bddd3403a11392318c233802858ae082ea861ebc8b615ab6616ccfb66b799fee682433f739be86c8b2faee7 +00 031b827b88f14d3822244809096157df3c0aa99da90c00cd9f0b18dfe306f6881834e6b6 a6e2321a814317b2a3682739cb260459bc4869be69683172515e11791f64eeb69bef66b250aa2396b1633f7596161338 +00 027da4916f1c471cff80bfa14d12aa10270fc3b26caed010c0111f6e5a40d914a3927763 84e62770076d97830fd92edb8ec10b4088e360f885c6ed46e088a75033db072cd565353f39ddefe004b8854077309eaa +00 010608eb51dc0ee97d6e488a23c582ecf0ea1df9a24db77094d87b3fb6ca98507280a934 8d1fa33118b3270f51557bc584237e6f9457b02eb3a535d177e909a607ff1fae5b88c6c4019d3741532a22fb056b4b1d +00 0123f9eb8babed548df08cc3afc1d3b3bbed52b538d4654f2088fe76062fbea75b85a560 b9c85ae95d6124e4eacbda4f6cb996d99bd0e5d481dc43fc8059e6bb30ca10c0dacf2518b2b853e4701283399a7bf6d4 +00 006a18e626452111922e02e31d662f4301319946a204ae8a34f06b91dd1b5b96456365e3 af452bfd96bf034477f20c7a647ac8ded3b3075cb2115e14d72fb81658d987a73c23e0c116cb67f108c8b929b07ca391 +00 03307fd717015b12a2dc76ada21442ac1d97519f66898b214c2ea317ab0f0905e819e4e9 b19044569204d673d0c9ba2a19111b126e4852ed133a9faa508f7e2d610067182bac6f5dccd73697def926811fc9e138 +00 014f9f412e3c7d770626e800d43cfcbba3ae6aec8563af748e8a97b67d244334b6e6d2b3 a15eef23be1d6c03af35e2445e57f6599238eb6b7b62b40b604a5b27d98d33369a5559b0ee1cae1bb23f4f02d4abfef8 +00 03091a6a8bdac1e43542dce752694972e734dca31c061c7d1000754296d0748055db3f09 ad444169e59ed323fe9a681a8add9f156b6682de6d9f5f51d71982fae41f7b8bde619fcd5b908fd373cc25552ca524ba +00 01195921b91353db9bcd00510efffe009c94f6bd8d790f5fb3e5a0101c9ca5d21c6ef2eb b314a93e53bad3a70ac8b37c93af1ab27d279820ab2ce1be47d91c5c7a8c4a4e671a42b9063d3abaa98dea439f9a54c3 +00 029dc20446e9abacb43823e12a83737b46e6e577466b5a3925e0f9d496824dadb4d4b50c 8c76eb6225105e0c5bada3f61d22a780dc6a23908ac96927053c0f0650208f796e2572423d50e65db398dc060a11500c +00 03b9b77d19a42e9a555da8ab70aa5638890b2ed21daefa28ca6323fc658662dabcbfaf52 b277b6f9939c1bb5b9a5df693ab011c105b3fcf7647a36215cba554593e6f96b91d2a8deec5fcfd5ebe51cc8b8734e67 +00 00b9f8f3e89e9c1ef835390612bfe26d714e878c1c864f0a50190e5d2281081c5083923b ae3bf529d5f014ed421da087e76746da47f3a48ab4e2396c7e18024eb4d378a9bc428137ff429ec62be5478d93de38c2 +00 03a30a1c15b9ed71e102341f97c223a9b5ea3e6a335861c3cf407ef691a18cc639dbe74c acdfed36fb5154457f546be3747716e5cb54d4787fbd7c38c40d1434e9d4776775c747217944b8390db1dd93113ccb8d +00 0083330123cc64c11888c1fd388629d0b329a50ef31a476b909a182c930ff02d0c389b93 a71e4da56860a1c22fcefa8d909816af8af63f9c6ed6183c7132969fd46f7c60912262822dd32fd200c4a5574fa6449d +00 01dc2b656c207eabc9e0d6272099babca8d149c9c4258b779c2f06de75f76d77505271c0 b33c982d38d7762ff93cfac6a02d3088051677770b8057a2c45aa795256ddd1332a881a0eeeebfe288e852ae278805b4 +00 00081772348ff2d7a3fd57fe703555ab2e14f5d203c4cf0292f944e827e884d95f3b1d83 9785baf282caab05ff6c7a5c27808be3b9000308713e354bb75224ffbb8915c06ca23460411e779b908c2ac78869651d +00 01eb6bf2ca1b5ffe6f6a795733eaeed12de6e87c53571e702635b9dbd0d96b47df4a005b 940c52024ff754817d71ffdee2601e311268789c21aaf718223cbc3124e1ad6a5dc95bd604091ed69bdce92f55d62264 +00 03b2a3e65e5a306bf8e3955b60e856dfa9bf68c1275a678ca056207a0ec67c96eb3f8309 909a25df62af499a5ff42434eebd4cf191ebff192c403d3d1ebf724166dd330c413ffb958fa5185354787145b40b6db3 +00 01fd4d1af0bb7c79ed5fea7bb45574e46534387bd916649485ef15207352d7302e81dc01 b56b3339788de24bbc52bdd6c1b61ce7f86c36936aebf5c080fae4f883aa2f1797b1f956575454c1020dabcc9d90c1de +00 020380b1136b5283e9b7f54b7535ebda33b129ceb177bf5d3d07b1daed5edd9fb3862530 989a1b496b49607e3943aed76a104874f064d8d1ebeb0c1fa861a1f79aa901f211262a03ae937dc0ba8f4e07e375aa00 +00 019f815b98836948e0a0dc9c30828c31b13e175f1e79f23d084ae1bbe64823f4866214b5 812c55c82b717f887ffeb7d8acaf89c86be8d0a301b29777e5ca7dc48938559430611e5835cca97abac5175b2981e3c8 +00 001854e954654e726cf4bebc0e5a840e8809fd716059211c6ffeaed36829808363164684 80d1784a8502b1f0004c269930f98c25503ad1335450fa2f8807ccd048041a44b74d6c453d1bad0f246f5675336c9e77 +00 03548f8020819588b3202f4c1ac62eaec6a47c2a19b2900c5a3cf5b4ba5804231141c647 ae7bdc298608161a75f218cd09a734a68325d1c84c7ac860b77f86dc514dea41114d1605d72b74dd65db9f6b2ccb475a +00 03cc4505005c41142308f1489226b7b542e2e7f24f1d3089ff6b92a4b0013f490ad52e60 87e9e630d6a1ff3199112c526d3efa3d2a4080c42c8b79c609da538760a557fe7fc7e794c13d090e037a0b71e08891ae +00 0144a2fc8e0aa63506e14e4307df36416f963dd9da78655832f5b991af8c3eb97df78efc 901af2ea16b1182374c6d40e7a7b20d0bb73a88539e66c0b50bdc28f38c135543475c428895044ac5a8b7a0895fa8265 +00 024ffeaf139043ff25a395e4c560c7680c1c2155191378917eb25194136b4a69597dc277 a13c8b8d73cf618dde9ac87255dd79c53755d95470b8f07b5423032bcc2d8dd750883d37f2f0ee18570217287216a54b +00 01d1f2e0f044a416e1087d645f60c53cb67be2efe7944b29ac832142f13d39b08ac52931 a847101fb18c5dd88781cf7ad3cb8256d03a665d63f3bfe1ccca645100a960e152faa203085741f9ecd0e7d2bc0ed1a0 +00 01337362609df74d25f7adee382225e6a04dd6ee4c6b45fa31499ce9edb0ec046325caf9 8b0f19d3fde73caddd2100e6150331db90726bd979edfbf4155bd2158a2f98c56859011cdd0acf04b988e2fa8c9cf7f6 +00 01be00aa0afdfe92e24a2536594d4b41701ad4dfb223aab35ff49310bdba7566057fe8ac 804ad11798244000029524d3cadeb0b604334a11f56ec78aa1ab897d0e1a72d32c26963289b48286cb840b1c759a7ffe +00 012ad0aa248db4fbc649f503e93f86104cb705d88c58e01d3ae0099590a69aa006aa7efb 987b168812634a7ee05aab391dafcf6df39a5a470b847004bfe57cc1c43cb550364fe7a06dd4d3791a4ce4962b32508f +00 02cfbb8f340cae8e2e2322829148981cd9e509b0c65497fd8d9da5dee9dcfd39b0f7556c b0a3aec5f10fe23c4a52d66971e204811b281cedec591a678a84c6059f06c2bf4dd51eae7b23238ed8d2a32284b9e4ec +00 0070e82a1f3fa6158d15b7346dd56150faee5c98c9d07c996e01a06dc9b211b12ff62d60 a3715addff3a260444b83197a4e4f13d61f1e696635bfcb438d59a43f45d1eadc8a1e1383e46804079e21c69fb07dd09 +00 00b471bbc5f7a07996e370da4a09e71e2119ab3a562a273f079401951fbe4df39a4493da 9651cbc6fd82259d36fab9888634e7fb3dbb856a1ed7b41265fc9bbae3657fee684097d938d012594307fe8e4c5aabb7 +00 03c65cf80bfb507dff52f9bf2f93df0642020d41619b3990009409e7210fd7130ac44ffe 8ee597c5bfdb48896ad32d52c8225755efa6f59aa21382c6e6d45dbecfcf95f4796ee3dd03c9dfb8f07f51506489f37f +00 00f4d33a9c7e6744ab3c441828bf0f1866ae1c042cc54abc754e3801263a96cbb3955dfc a91e5f2b3991ffc2d61de7492c09273190da112431d9c9ebe2c41554a07f45c3f8741cf54ae634cdf0d7cdf6f6e38706 +00 03a4824bdcea6a144d85f1b194431724cc49849b6cb949b4766d641ae95477d1ec3d1464 b16b7ff272d3c8dd35b58685fa38eae0ae034c17be4c220bb68854eac62ca4d8c2d1c952d51027aa48b2c152545143b6 +00 027ba543ea785df1d53d4ae4c1bd0a3a994cddf0c25d2b4e8ff17ea7aa00619e858da1a5 8ebe4b17b2df6bafdaeb0d4a7fc11609ad07df535821618e2873e922ade7ebcd3443fd95e922b5fe28770adae2865e99 +00 00708d0907d14dcd5f40e2903e1e90e48a0ffaa6d4d9b84ca14df4e985c294f74eb9f2d2 adcb73e4074ee82768837df0786cde005eb31816617774f7d1e4275f11678a1764719750327ccb204d78a4d800d90dfb +00 021fb0a6b94080da8b8299b87457dc09d21bc430ba5f3359d92aacc1151be9941739567e abbe406128586ae2956b6ec33f78f67ff542c1ddeaf7e8b0b2f58a233cadc5b59e9940520f764b61731deddd51e0f937 +00 02c80151f91301fb6b0c7685bd172f20515b46bf94dbc4160d0720fbaedd40ec00084447 89a1799373a22a098688108fbe6ed358a7a85c5a128c2318eebed2a5af6ad760b22327fdf9d25408e83934b0972a98a0 +00 01538abd7ce8a6028d01604b1b87db3aaf720e04220edf4d1d28c2d731aa25f509e58f2f b4f2cbafc0557d6a379730a69889f998d20aae0590c0d0900cc71b8346444076d263e3bb76e612203513ca4631f767e7 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B283_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B283_blst new file mode 100644 index 000000000000..be737883f1aa --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B283_blst @@ -0,0 +1,60 @@ +00 0299ff06e019b5f78a1aec39706b22213abb601bd62b9979bf9bc89fb702e724e3ada994 8b8517eb730e9321435f7c012a9971f06e7e4cfc6e108801fa298bf80eec017997ca248f7226d2d96b9f3c5ad651d83d +00 009c2804f8cab768248fb3fff8a055b3f4585c00de5c1615a19f9425b9432ea09afba8f2 8c943786a6143c93e8367dfaa8fb77121e056d3a8cd03e5b6275812d8e28a174bfa15cb4121b4e530d17cfadaa083935 +00 02e625a6bc6d0ce7c06231de827068bdb0abc8ffb57c82b35ee3a0f873b9473905974d34 b94a5cc69f3e8db65c33ca6173101f2066280f17a3f3e740ad375e47c46ba99034cc4e97e9f1ec3e89e3343bdacea25d +00 0376ac24e1b86f8a55c052d92a0bdc6472fa03acdcdbccbf7c321ec0ccd97aa0a66b4181 a2b6e146a3b49197e85a3ce1dfd1eb75076388b1f2526fea53ed8e8207669e5d081cda45e8e318fbd240a580b5984830 +00 02b50a6395fc02b9ac1841323de4520292f913519bc0d6a471aa28021322fc4dbcd7b802 b506b5c6610e348b8cd56929b7c95463da119a197e087e1f71b162f02ca388870b7334eefdbab9373e5ff78d3bb84215 +00 024e5889722f6c35e18ca47effa9e415b1ba790066a91fb3c9f7b001ce28fc732b09bc23 a1298241bf89d7ee38de76ac8d0e82019abe0963f3cabf0f6fa5fd41324eb42170354e5ead1c132a641efe4d00e893fb +00 0056d15b81f40b6378588a5efe43e21b95e18120d514bfdda0e7759a1d0766a8a35ce5ac a1c956b5f668b6aa49e76b0a90e6581389e20b18075de8e576b81923e442e3d18951c8700484aab1fd45a8dbfdc8f573 +00 012fb2fb5bf5f7e42a500154823a174ba2d05af71e3b0cf47fab46e673ea1822f1563def a5d545f1fe3a8e5aac70a87921eccd2a46bacb48f187c1899d9f6eab5ccaf067f43f62defe6d0662262f6f4872793378 +00 030096c54fd480647e017f8cdbbdef292e799f054e3279d228b09816a757566a744a8266 8d59ce11f238cd9fecaa9aaa063065830d9a112981e55a2c2c0898c2fd4530883e0f85679474a4d9f84cea648a294393 +00 00a1b7e9c8c2dc25b494b5ef3195b294e41cd3c2c35235ab42542bd3e2a52d5826662bf9 ad6b4d0e528184e908d48053e1681ec4fb9868d0e87d088836a7d9d770bab84fc5a3a45125b3a8a88e07bd1354e359a2 +00 0059b1a8fb84530bba7a607ee88310e31bc6ea6a6881603567a1081a05a3a9ff87e719ef 944d1a7faa6972f28371ee4a3231b5da3e0d11d8d767a4036527f8639d5166b3f0fc38f2fc500f8c1c175a7a0d887636 +00 030ddc2c7a4ce300cc2b75f0f977033f16c1f8bb13aae3d494c381f9a6dc8622499ae4df 95d3d348da0ec8987183047bdf4c692ca39e70dc67915956922b99437169ceba72b9816930b3d8c4c8b1f4ca823c71cd +00 007899928922fbfdb5407517725edf231d15a8b62d90b7fb6d8c8d20424850dc44f797ed 812a847c50727daa6ad32a66eec9878e4340c08dd5cc6f594a9e13bfba85395cde26ea5d636aa6900bb491f2ca968e6f +00 02a2af63d1171930758bd3e5bfdac62cca1a83a3b55a49b3f80cf0d9ee4b2082757beac0 a03950ce639ed148fce1adefc1c693ba61e39f294e009f29a986d2b82f427b141053ac0a624cd432b3f7a93e2ba42633 +00 035994e89e13916ad82608f74a639e6aceb756ff913aec440519946d6434af9a60a6af49 a9e1a93c387a881cfd43d1ea11bb426c843ea761e940c599be82d3ccf4ab089d52b4288fd999a588e418136f4d4c819c +00 029639da33f48e4fb0d9efdf50bba550e739f0d2476385cba09d926e789191b6fb0a73ff 8628000dd0a528bada336e8ee90504d2d4bdaba9d9c24f8c9b89dfb46645d1082cb0a9b801ee4249fa583f6e2e860082 +00 00583a7ecbf2a975a32d07428d27ac82e5dc13d1466c4fdfc1e6a05a8d9a289f1010617d b011f387c03a77c98d30840e2bd846b546e07a57aafb82ca91a3e8461efb9d8887989827b15aa2fa226a2932e223197a +00 00f817ab1b49131fb9bbe8c112c25a36f064efa85de7506fb9cd29d81b326bf276277f7f 992c2a829f225184ba2cd80245ddd6ae4c422abe346be023c504f9dfe6fe6fbc6bc02b401df556f82be813f6f8278823 +00 02782af76ffebf3e2bfc0576b70e4f4bb87c762e2bb230d278ce776310a14f5b678f29af b694b40f4c252dd13afe38efd43db0931fae09d2d6d5d7bd2c419f295dfb8f17c4a5cc02303f21ce273cce8a702ee403 +00 031b827b88f14d3822244809096157df3c0aa99da90c00cd9f0b18dfe306f6881834e6b6 8f16df9f734815695c22a6ff6f77e918e9d0aa9e9eab574648ef21b9bedfb7c7cd8d18aeef39c577e09a659c5c2ff5cf +00 027da4916f1c471cff80bfa14d12aa10270fc3b26caed010c0111f6e5a40d914a3927763 9616e26b270f525b846feca89d67908f0fcd30205b6bee443396858c4b2b4eb4dd3f4f3bbdb76496235ed9f390cc4ab8 +00 010608eb51dc0ee97d6e488a23c582ecf0ea1df9a24db77094d87b3fb6ca98507280a934 91f4ffda924e94fc3e6468ec7d7377b813c62caccb1cf083c333afb50c2e34df178f72c77add6e6b6119313bf9bf44b0 +00 0123f9eb8babed548df08cc3afc1d3b3bbed52b538d4654f2088fe76062fbea75b85a560 88a79fec137dec185b2f901ad789eb975ba1c5f05a5b9b4e6ea2823433ebb73b5d91dd4eb9763025c0dcd1785ea2f367 +00 006a18e626452111922e02e31d662f4301319946a204ae8a34f06b91dd1b5b96456365e3 a44ff7707173f77f89f97187eda24c743315b17e998fcb6696df69d43abd3b85b05d50408567239f05187520bc240fb5 +00 03307fd717015b12a2dc76ada21442ac1d97519f66898b214c2ea317ab0f0905e819e4e9 94369a5e2642fea14052f22a42335a088f3fe8b7d87d3bb3fc07301ee6ea7cdf6870fd54a752f8ceac5dbfabb8ca9dc4 +00 014f9f412e3c7d770626e800d43cfcbba3ae6aec8563af748e8a97b67d244334b6e6d2b3 90fe1d1cc28326087a0bba4815dfea2adfeb9eacfae01d3c9f83359cf187d5641602e84376fa346e8cdc2ba030a2e746 +00 03091a6a8bdac1e43542dce752694972e734dca31c061c7d1000754296d0748055db3f09 8b96e76b7eb26f6ccb26ef0df8d2c79835a4475b03e7b80904e331efedd0412ea6daf87343f625ae0cb4e7486f72d638 +00 01195921b91353db9bcd00510efffe009c94f6bd8d790f5fb3e5a0101c9ca5d21c6ef2eb a76f164bcddd3b531541dbd8296a9b070ce2a3eed279d8bdd9c8e5fce0ca47e639662c2a150a23cd8efcc5664ee6d6ac +00 029dc20446e9abacb43823e12a83737b46e6e577466b5a3925e0f9d496824dadb4d4b50c b9762b900763383da969a2847365659c91ccb75967b683c6746abed4db0d19c359d84672e1c61362861599420cc0cff1 +00 03b9b77d19a42e9a555da8ab70aa5638890b2ed21daefa28ca6323fc658662dabcbfaf52 86110ac205d240df827628443c5ef9f69c467444eed2fccd847c7b1c70d85f603a37c9ac06eb11df40035be2871b398c +00 00b9f8f3e89e9c1ef835390612bfe26d714e878c1c864f0a50190e5d2281081c5083923b 83f75f3ce82ba7e5bbeb8f9f4828cd3ab6bf4ca6990d1ade933ecde9c93a31c3ee5d08829cc413d5dc2bc54d6a00d1d0 +00 03a30a1c15b9ed71e102341f97c223a9b5ea3e6a335861c3cf407ef691a18cc639dbe74c a7771abdbdf89483145a30ded9a8f9899654df2827e271026eabb5f7072888d308b46076964cb871194ffadd56e5b99c +00 0083330123cc64c11888c1fd388629d0b329a50ef31a476b909a182c930ff02d0c389b93 a58c21dfeae343254c7a296ca26128de4768b66d579dc075316a7cdd53b3d0a78603b490296e84358eac6f6d4c868c85 +00 01dc2b656c207eabc9e0d6272099babca8d149c9c4258b779c2f06de75f76d77505271c0 965949ef33337143ae26cbe13fa791634e632df2be295ce314ff546d0dce053ec9833beb7f50f0a34b0c3c89253be41f +00 00081772348ff2d7a3fd57fe703555ab2e14f5d203c4cf0292f944e827e884d95f3b1d83 ae4786fe953d2af6fc37ef5ebbf694bbdc09728d0abe3accb6f6c56c6787b3eeb57b697d0f9a2309251b43e83632d696 +00 01eb6bf2ca1b5ffe6f6a795733eaeed12de6e87c53571e702635b9dbd0d96b47df4a005b b5aad264e4f1d6bb9701415be94ede9f8a7180e0a9aa1e424830e58e4526ef0a9e0522ea41004c904ebc450bebf8e212 +00 03b2a3e65e5a306bf8e3955b60e856dfa9bf68c1275a678ca056207a0ec67c96eb3f8309 90ff6b1e8dcc5ca722ffd133d2e3a99afc09085c4b4192953d4d53a79a7aea370a3794f6e672d079f29be65ce8f9e6c4 +00 01fd4d1af0bb7c79ed5fea7bb45574e46534387bd916649485ef15207352d7302e81dc01 a30d92a8666dc03bb4ec248e00c6401c935231ff8e0169240655df64d436d7830fd6938317aefae3a691d3bf4eaf9c8b +00 020380b1136b5283e9b7f54b7535ebda33b129ceb177bf5d3d07b1daed5edd9fb3862530 aff0e6028a68fb16bd0e513d07ebb6c6973f9321e019e2fd903b21934910636e64a5b625d8d91cc5dadc47ab91e6994f +00 019f815b98836948e0a0dc9c30828c31b13e175f1e79f23d084ae1bbe64823f4866214b5 95bb9c79110658e4149b0f69bf74066fe81e56a831886de91dd97bfba86a5e76ba63a372a6837af83459df66a8a5ee73 +00 001854e954654e726cf4bebc0e5a840e8809fd716059211c6ffeaed36829808363164684 b06e42de16818be075cbe27ff50ad940dfacf02835f6b3072c344418551e1c0681d84f9ed9bd7036f1a7a263e248a21d +00 03548f8020819588b3202f4c1ac62eaec6a47c2a19b2900c5a3cf5b4ba5804231141c647 88ebb8cfcca278281902627054514502a7bd9be7c9035bf2496cb77628ed5b86c34e1a999fe75bb5d33649862c6f41b9 +00 03cc4505005c41142308f1489226b7b542e2e7f24f1d3089ff6b92a4b0013f490ad52e60 95684944f60c2e98d8b2b1d25ef3d088f190f742fa72659d2c7465e06f910099ed9fa7c80afbae18144dde06d36fcd26 +00 0144a2fc8e0aa63506e14e4307df36416f963dd9da78655832f5b991af8c3eb97df78efc adaf9420fbf3a4147e5011b19cdb6ca3079f0ba2b458f98761ef075383fb031443ec055493215119a475b789331c0e5c +00 024ffeaf139043ff25a395e4c560c7680c1c2155191378917eb25194136b4a69597dc277 a02cada907d27c1ee187f244e661932748bcf6358db105f994d13fa398f774b3fc9eef215d2bf770cb81e70c8eb5af50 +00 01d1f2e0f044a416e1087d645f60c53cb67be2efe7944b29ac832142f13d39b08ac52931 84b08f8f847409926ed676b5da4b2bfbaa8168a401b7ffe98bfb8dfa937c52b08d9e12e8f1a88e432b5c34ead6867f05 +00 01337362609df74d25f7adee382225e6a04dd6ee4c6b45fa31499ce9edb0ec046325caf9 90880de2b9270122fb24d2a7b22e7cd1969bee33b4ddabd0fe56c734fadec9d263272b65764f0eb1a1410c2f458a5f9f +00 01be00aa0afdfe92e24a2536594d4b41701ad4dfb223aab35ff49310bdba7566057fe8ac a4d0dbbafa2abc4fce2352793b656e9617f214471b4a404cfc73c9589319110aaf74949694c5bce8d3c3564f3b18e224 +00 012ad0aa248db4fbc649f503e93f86104cb705d88c58e01d3ae0099590a69aa006aa7efb a66285c691802ce2f79b715ddb9bb0b642f41d245355cc2f9a51214b61f3e3700927055eb3d1a72771bc82b8a8849e34 +00 02cfbb8f340cae8e2e2322829148981cd9e509b0c65497fd8d9da5dee9dcfd39b0f7556c 8804caec9c153a8b8185feab2087937f50e4add74e906f2c5c2c1eb352873b337266b539387c3242990a43f4e7e09cea +00 0070e82a1f3fa6158d15b7346dd56150faee5c98c9d07c996e01a06dc9b211b12ff62d60 95866de86623fad7f7e9cd3db2e0696d7674b188fa7492729330f630bb38858dc9fd598184f9cc8377d87d1770e1441e +00 00b471bbc5f7a07996e370da4a09e71e2119ab3a562a273f079401951fbe4df39a4493da aa691990280e6ce8874e83df462c757d373a1f36d93a4c5075f737cbc10ca2cd587a5e5ca6311b05845ddd0762192dc8 +00 03c65cf80bfb507dff52f9bf2f93df0642020d41619b3990009409e7210fd7130ac44ffe 9937662348982fab29d02ba1b90ecd7ad5dcccd67d4a2fa312ef3e3ff5524b759028bfe496ff165bd3a718f29147bca4 +00 00f4d33a9c7e6744ab3c441828bf0f1866ae1c042cc54abc754e3801263a96cbb3955dfc a1799923a7669816042e1766af8d770cde53bdbddce23a5ba46d96c9387a6beefb5187fb8248962758de1f078f94482f +00 03a4824bdcea6a144d85f1b194431724cc49849b6cb949b4766d641ae95477d1ec3d1464 b8e5a1266826228973ab1533bab915ce95df349e41a6ac4f6a14423ee3949ee166fdfc30c51ebb31af0fde0e84bda374 +00 027ba543ea785df1d53d4ae4c1bd0a3a994cddf0c25d2b4e8ff17ea7aa00619e858da1a5 b8ea91341794fe7866d7af01435e7c160f8937f0e306a122cc818656cb4030e01ccab2a8635a7266941cbdadabdb69f1 +00 00708d0907d14dcd5f40e2903e1e90e48a0ffaa6d4d9b84ca14df4e985c294f74eb9f2d2 84890cb9d133fc30386d93aad9111ffc8ebdf1ba86f2bebd98a9cf33e6fb60277b13f42f24a7b367f187649d7d0b4c0c +00 021fb0a6b94080da8b8299b87457dc09d21bc430ba5f3359d92aacc1151be9941739567e b55db16ebcb7f00d0c8ca42aa420019ad58e78546437d4cd539e017441a6bf208510472015a05496cfd31047632c2ada +00 02c80151f91301fb6b0c7685bd172f20515b46bf94dbc4160d0720fbaedd40ec00084447 ad7313e27ab48846550ce06df040b72bc6650c58892e08ddc1f7911f7f931b2d02b9a9a2b2756d7bc921676864ef6140 +00 01538abd7ce8a6028d01604b1b87db3aaf720e04220edf4d1d28c2d731aa25f509e58f2f 9473da84fe38b441272233c91e8393689aa71ebc8e6658cd95bf3ff34e69d0f240a1e882792d828d02dbb094226964c8 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B409 b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B409 new file mode 100644 index 000000000000..36393b008c7c --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B409 @@ -0,0 +1,60 @@ +00 00beb0df3b0e05a4b5cf67abef2b1827f5f3ada4a0e6c3f23d698f15a3176cb40e85bf741c9fbc78c9e207fa7302657527fd92fb 89aa4ce7009a671ccf9acc5f9b347e30338fd01b85b6d9982a49e77a6db880432d5de062b34955ec18085571fd6a8e94 +00 00504865a30984a9b273d1bc289d734d10e0aa56e93ab14720f1a42a27d8cc932cb8804b963175de6fe57d8eafa8ab7ea0592dfa 8d622ffe789f0fd7d2d314b72a078911c33b37e454e3e59c6270819b473f382f128e0a35174d35a99d227d8ba0a1b8bd +00 00cc08a4ea5ebe32027885a8c212870e7c45b6c610117994d6a42a284c05199414a3a0e8e6645ac5c2ebf21c505a601f69c62b85 adda7737f05adcc1c815279a46a3bac6bbd2a65a85f46ae7c1e65299559e1e3db4810b19260f67693982486004c13f47 +00 007156ef0a74ee1119532a2a7e8c02be1559c3c21897af9d5b34553c3d0feca4a8d5929d1945df824478e0c0b92a6fac8c84f639 88c8e334f5a90d3cc7c445095a4bb79742bf6b0aaf896a39222ad30bb09a98197d0ae767e04f7677de1ee055f116f481 +00 00a95c7abffa92e2c637611ccba66ff9d2ab121b40a85c5b71454cb0dca1f098ce1be8d9ea4933d1a91bcd270c5a33687835d6e4 a05a2a5be424331c14b94d0387f4347475f2aaa5975f548fa534c6536b5949dee26ab01f6e479f1be6c8774a1243093a +00 002c438b07c6e0685d1f94a4bbafc013f8f21265d893f54e54c3ac2071606ad1ffacace0b8367aad724b1d9508c65ce52282e397 ac1277fc50306c257afbef23a16b6c0e87fda7fb537282090f77abbb9aa7228c278d603667b34423d65a92076d5c379b +00 009e8658f8f9e6cd98c0f4f0fd20d64d725653aeba339504def17f3ad12a63dc6157d80804e5f43f4ff48fc5573fde2c615ed31b 97c95ebd059ef80ef1409cd55c6d70c8daa722b6375c451fa2279827c8a8ec26bc88474226dcbb4b651d03fb8304833e +00 00c4c13f65eacce85a51881caa6f82d9e48ec2ac574947d2751823a7f072d38bd9da0cdf30b6f19084a6d291052e7bbc2e1349e1 a852cc4ee6fa65f8d1825199ea2e8daeff2cabfd3c96530168d34f87f21c495f15ea6534573ffed9ff86b87fd4a15877 +00 00da591461791ae7847e6d8dd8df46a63d3021644abe9520e158406c96540d8fd82ecfb1c3f6f5cfd7688c7656cc3e3dc94e586e 87ea2a8ef6b9f1352d62aa6df30f0230aff5e18c2060f457dfcf3a6d57bba3852e2210173637276c458f188b35085d1f +00 00b5eb943f0dd390b737510e2bb703a67f2dd89dc9f6dca6790bc7a260cb2d0fb8e1a81ad6009ed51010e7686d5b48233c6c1686 8c494f92fd4aa53baf0d0028b562d230905d23095374b41cfb8b887c5a8bbc65776a72dfe900680b07cd75f4dc7cb684 +00 009cc63f32152284fca27ab2837bf1343144336a1fdf15b9727c47e877ac69ac9cf4c97b4bf42f1ab10d73de8597a554ed099efa b15accf19b0ee86ec52b77e8c342e5eaea21a31df6051d117a87b1acc407ceade0cb5d0427c5110ff5748accb5eb368e +00 009950355e8667bea8bbe3a2c4988436ab5394551b375e27fdc0c1a1d1b07ae957932f428f1aca0a486e54cd0b5bb0a5c5650641 af1c95308b7525eb7de28ccaa1ca37beac78d5bff93a62c9396b3601e8a987c7f8540087fe0bae4abf39cd6a2a212ee2 +00 00a995493d6971c2d7e8fac3da9f8c0b5afd877cfb94924cfecc167f9d87002136ab253e3a4f9ddf5c9c99bb1dc1af0c6a3a3c4c 805c79878a7ffdf704fcd92c14ccdbb07dd9fe7cf5f0e0949d314ee420d1251daaf45e94249dba231135b9612de61103 +00 0070daf435cdc26ad66c3186267ad12d10f28d32d863f950cbfcf042fe9dfce553750ad098f82f7f1650c1126b3e4451bee6e11f b2bfa2c81851228e91cb974c89c0d8cc895f18d39e98bfae4759ff8a0906e773ae7220828ee7734865e98d005beb4959 +00 00f8121980dfbe9ad0bf92383c7cab95fb72d5caba96e1de7772c6a179e85414802fbb86d725401451329287305570ec7fdd873a aaa025cdf48afeadc28a8fad90a9a8cee8480b3d242d973a1b75d159f7008a608945410d19aee70381d5f1c720dbb45e +00 0047682b2e3bcb5800a531858e8137692a9b1ee98ea74e929ce4c919c26ae3b3f1d4122d07fd9a70d8315fab727ccb67004187a3 b4b88031d8f6e09423cd1689412955d8ce50ef4515f509d66f9cc7511ea5c7adfc0664ea0866fcd032fb0eeab01754df +00 0040cd1a06233ac27f3ddd108de7c6c0982793ee620d71982697713be9fd5143658929924cc88747a680779bb00da8a44e1e7d3f 83c79a178fd8f8cc281a96af8e429081c33489979c6cdd254b234efa1b939d84a169e097dedb4518fbcd221f2e391eba +00 001ca6f752aae4eb7fc9c73a08d6fbd96bfde5030d759a2507bd45b6e1d1487e53abbe98fad4f41976364e0a1d830910ccf97abc 9111d146e791179e685218bb305da833995e94ab3fd4618b68e3e9de2c9d1a8073906e850105b2a9541f63480b0ffe2f +00 00fb9b1a9597d216028902abf743d25944258b48c9762d4589fe660396130b75f6006cacfde60f6204463cb8c18b032de1dd68d2 a09e0cb96991f60d240b85d2a5062e558ec7404e64f48ae7f964b447149a2eb36f9866b28a654824ab4536aa9ca9c1dc +00 0032109202d754da290c266f74f47805a06e6b5c3f721a72fc97a3bffeb8887e0c642d49a6bd034847d0a5ba09239c5dfdf0772d a87c1aa85957bc0c90e2110e198260baba0b4de26d0fe5bf86e17349a0945208dd236c6b6c896cdd7de2a4f8888da577 +00 0080536e820fac59b3203aea928475043b2576446619001647e35693a9e65d15236c3cbc12e1bbe0eb305973535c882b70197a92 a1681827a2be1281c05abffe19e8c9af3ad412e53ab64d3c0a75c10f4e83fda96cf75d377b93df899dfb29a0c9e66477 +00 00b05e5f0dad9583ea18fb8fc4d8c75fd2e3cf9e92cdd9b737485c953620d345006c31c288b380258b6500b84f729ce6730e5303 b08eb3e161c486a9d19557661158182482db3186973a0cb1f6fbc5793f855572955bc77ea46247f94bd126c8817f36b0 +00 00be1d277813e79051ca1611c783d66003ef759b9e104f32298017fb97667b94dcee1ce807dc6b4d62416e65d4120523bf6a4edc b06cff5d673f05ca12e5f7f8429233245e737e0101783689d9d666c2421ed0b02eefc4ddb92e2608a01c0c24ce75bbcb +00 0073c807bd7e07379782ab790720de4ae5106f16d34e80ed70da5b1594e660c9b775db94066b93e74f855f57d88b6ecc6228aace b555cb8b12244d0ec1a977841d9a9ab37bfefa216c55a101cd55d18edd1b9bb600ec4849a64950f65f382acd4024f8df +00 00a68379b2296a6c944ad5dacb593b302d8ef0b05873ce12bbc371d705f308c739d21f343349524aa72f05341e64f7435daef112 9711c8b7d293451dd78a29007ddaafd2557ce1a263a7649d207694441d81261c55d1ec6859925ee3b12ad4ceca7114b4 +00 0026046bbb269ddb1ec14ade56175482343a21b7c265026cef3c7d6a1ae0f6a68166b9e6c49a6e733ad2ad64df7137ef230038fb 970db0643c42b5c1443e0b6abc963559425cf3e72af31eaacbfd308cd7e9d4201126524653a827b2e0711f93770b541b +00 00bbcda66978ea526f7bd867c3303b625f11b94dd9ee6e2c2f8688ff07f2bba83c662949d47ad47fa882cb7d203a7f0ef5dbc52a b2337177cb9d053b5c6ce93eec3b2e84a65465a456b0b38a8e1b140bb9c227b7e05a749a8faeb0edbaef97081ac58311 +00 009be3dd3442e0330750f0a6252bf9cb317f32f942ae516a4038dea2c40ca6484fb33611bef016cc64baf166c122e87c15466fd8 966711827163a769b70ca420c2091b4374feaff4ee80d1d0b29fb2765c2aa26cf026e389968acd8145a2aa5570f27055 +00 00ed321fa283c662e87eaab99b7715e6cdc9b42e14fa5bbe2c56fdfb381369191a42da7e574839f90a85577485f19446fccaf6cd 94925deb490b41e8f8a9c1af2eddd96a6f4a95d1ae221fbc4f3702cda38b3fc48e59f44d5f58b00674e98debe2c2b59c +00 00396b805073f3c3b552b1024dcf35559ac44f255b688871a3c6657f727a4b09f3806cbb75d26a00ae1728be632387e804775a8c a31c9316840c6cf6d5bc5101cb439af0e94204b8ec82b87a2e3820115111df4cd616ccc16a6eba0cb7564f4cb6c28de9 +00 00a8fe323f6736bcabe971c7d964e75dece70cb54561da48a11c40027ebddb23e41c7b48600f569500fe8ea2abebdf480171dde4 8eb4872a19fe444d47bc60b0f5a63f7ddfe2a17cf476c8f569a44d354b2c375f1ea51438d5eb5c1f762d3bd2d7969b38 +00 00105938ba9f25034da3e032dee121bdb192ac2128b50a2ed4bca042e96cfaf4660c9d35f3e67bafd4c99f9447e6dc408e0c4471 a3c1a87203340ee3f5d807ab2e72287081128c2b07d30c3537069aebee4a1a75ce37493f59858f0e8db6c8a31bbbb5a4 +00 00ce11677ca818537dbaeb880fc967dc8bead203a2538a55e756679c4a9e7975b9b3e6aba4e6c6eab4152d0c0939027e9b0bd92a a9e011cea8dae01e17f5835605923c1107b0c8be65ac374f0171bcf3caadf6474423570816dcc7ee6f5cd7f1b0ad6dbd +00 005a239ae0f40d76d8d3589f1662b5ca12176a4b2784faa8339b54e96a1e1294433a4d83bf904196f939bd8b33bdb4be340ec703 a88c969cd2ac43d5fc05872c62be621d494b543ed3a7e7493a70bbcc6cf63ac01dff841f47aabb58b698ad8ff7ce4e16 +00 00077390c62ac41aca995640fde0c79c76f4ea8a8dbb22323ed812bee837ab8798c5d0ba976c7aa634d4b1c2c155de2709e7352c 87c7d0cf6eefbd41fec6f2d24a3b4bd0c10950a78897c2420130faf70cffcdae77822fbd2fd14bf16d4441444134f291 +00 008bf23b09fbbed1b55769907aafb97f4759cec98649b2c9da5157517d4f85bb70157076b5e4aaa7a940af042302f8be06a84ab6 852e85e896bc27f16f19844625d3048c164ee9592cbc42405605eb20ba90bb842bbfbff09d7b530959dd48516093d4cc +00 00082ad05d19b8e16f80e53a4cccf6869ab5128c5e622ed146fa8555985ccd2aa3b9957dd374586115d4d75b1c01cf98ecfc3646 b529e1ab5808e96ba9f2a1fca3f6e367727e42bb38777a2448a1d2eb9ff2cb2f1c5657cc54b04529bd8cdeaaa4fcf3c4 +00 00af7e581aa4f9be5815f0c447e39de00da9194eee5e5f609668b9b69930b5b48a948614c2250260d1917f0ebcb00ebda4bb52f8 958291cf9572e089abd719c92115c1e4e6ed01ba842f24c41824da41bbb75f39a27e380aee1d6ec19a5233c861203b07 +00 006d14107b08354e6a41d7d7d50c004419db8bdc50db43428df5e86084551237223c498bce71a17e25695bc438c5c09e009c60e2 af18ad8014ec85bd0291b4fc696f727fcf21511a46a1f1a1888fc3926f24e9ef8966e4d0678190448bfa68a184c040dc +00 0099d96d2dc9c79549f031bd5346cf6a8544c312a3fbfc560dc8e378efdfe025b0e6e61e09c04c8bf4133396f993b0906c33dd30 b05b65bd676d629ae6f95dfe3e5d7423b3ae29b318718a3e0a395e162967a84a533711f8417cb1f2d552999fdfcd7a79 +00 0049f347dfd361a65910e97fcefbf60013a54837f2ae657d65e02397f59dc6bca27704fed3affdc3d833fdc621cc5e5f99b92a63 9931c4141ee82de364cd4ebf9a8cd488172f806c2bd1b5d35404d930e512a51e293bbbcf29eb64c33ca78963311ea43b +00 00dd226de602af4e9f8e25784bd1bbd4cadb0a8aef525d5e2d57b9f3555feb698765672c5099a7d6dd5faaded69d8d68b4804f26 80f0f69f85e245a4ade6db9f902f6b203983032bf04a5952258598789bfee1de1f2b5a1090fd9661bf7f16b278dd1a9d +00 00b6fdbc9c8c76cb2b822a940d8675889ca6f5132429da795462381ce29313a23bc132976fbeb346ed4c691e651028f873ce7971 b2e3487bdf2f8987c07bab7d130a76584b93f455e9c3a1b4abe359b9df378b041888c0c02a99dabc9056f6e49fa502a0 +00 00203d77fac64591eb9a18de20a9d5eacaa1c3ec58a5ecdb3008c2d642e197141d16b3a9fdffe61429264f5b420f5e9926659a4c 8ea7a1d1f15b8a0dd95ce3411fc5206047f1d180c10e37235d072929e487949b821295d15b427ab2cb0d4c374cfd3085 +00 0057a2e6a59d4871c3d547690237dd9846d6d5dc4ec0678aafc9c8669af8a641eed67bfea4b05fd6b3b5357ec4d0caf352691ea4 944b68443903ae24b38ed07fea747aad882774034b13bcc5ba8bd4de10b506da8a991855600aeb48c26b0eb3eacd3a11 +00 000a3da7a6633608fcee9ce4253bbcec08d41ee6b00178ceb017de74e24d48fd89107c9f2db3556063abe3cb011938f4b4871795 8280b8e43add5c08641390ba6f19104a1b5675c0a56fd9bccf1ff856c2c2f8d3eef26c6322ca7af391f797e6fbff892b +00 00384723c8b4a316b450d1fce0b2645912b8acaeb3cad50860cca43bdc0206ed5b3b60ebdc29b3eda305d0d60eeaec261edc24d5 85a2fccc6632a063e31558d4d4e857c3012a3c4e18b41e9d463a5f0545be42790d51a1d88837a75adfbc1132acd87fcd +00 00bd3136647572fef3de51b12e64b36460bd3a27dc660c164fc705417339cab21f9e1f9be0f3da926df459c5ba58b701d306e67a 88f9b11bf4cf4e60d37df72fac51ea43098105a185c4d1f215aea2a7db0e3d434e0921feeeb0b9f8d2205d99de25b65d +00 00495be0b0a9d357f6155fac008cec90442200bb842d89292fde38b7256e4117284a60249b3101b3f19f778b680c0d1d7422b84a aedc7246b71b7993c4bf528ac52bf0e41c519c790dc8f298369099142012deadb8e2e4c71280b71611856983181f481c +00 0079626354dfc4eeeb51fcf232ee9e6b0130c9bd40f15ed45606bb7faeca8f359e0c3e18bf12769254522fd4077eb24bd5454871 a07484c735811ee83faa7a1e795c8f2b7f380270595c6b9c970114fdd0280b1b878f68231cda89eab9f6dd6d4f6e8efe +00 00ab42bc7d0e3c23f8bcf928e25f9f027b56f270398a1d37bea0ee5426b944a9c9ba6d0d7796899543feedb470f70b2ab148234f af1cebfb2df38b298aef6b5e40b72879cedbd1921f243a9c632784eb01f38f3f9ae2238157760f7bd95aeb443993b806 +00 007f7aa2216164ba689459ee5d5ca29e70ef75a5b2a4416ab588df1dcb9164330c0b405a9d80c3acc41c19f58e24e17ecbc0fa7b ae1c3a7d98dbbe29bf8ea5741a55da0426660ba11ea249bf61ea221d8e9a6d37a29b15823a3831cb9f87efffcbf24e8d +00 0021d84f070c6823a70f1a74225a472118c93ce9dc509aa6064051ca4574939dcfa96be862069424bdf1a23f62f2868326422e64 a93e1bb3fe9e6acf472dcc9b24d23b5bfb5148cea73d7392018acdf839b6e2bf69cc97283d025b0badb4598f81c7d02b +00 00b6645344d17528968c719091b6e2072388881dc10bdb4c7fbf41906cadf3699b30f9c1dbfb4796d009480664e6276c0359e5db a27ade2bbd6083624f064ea7afebf8072f0f222c84d0cc266cc8893595bb5c2cc22edb911fe10b17d9eeffa9ec6354e2 +00 00f8c2f770cf5f8e1f900e996ecdcd84fcff5cd959777fd005d721a419123221a3237e39834b270d37752470deaa6cea023c5058 b67a7184bee6ddafcc9027756212248108fb7f33fb547c7df4bc30f7b7a878caa9326ac72d5dc11aa2b2e4acc9403dac +00 00144adae951fe897d5812ee4a16c0be4c86c5e57e615c398f5768a1223a9be20fa82ceccf8a16a31432bbfd17e594a4cd8a6a07 aa98e8e84ecaa96ab12b8b8f2de0a452b0362a3bda4ee826459a1b07918399d9d6a47292789d87f13a7cc5f58cc5ce8b +00 00a51f065fb32c55bf4ff6f18ba9d488d35d9f8da593adb0ab1632533284e0adc43ccdbda9d9507b9862ac63b5ae7b0f78b479bb 8885ce5fa1ab26243a4bc1f232867c344a132e42cd6a93b2f4ede73521220d7355209e61a7f5c12db6e171637839b03a +00 0095351c0bc07acfabe6477fe85f97eab520dc96bdd58b44b036328ceadaa56a1904d2217c5fd25155ff2aaf9005a3e2687fec81 b8c3609e359d32c062d180d34b38e519d3fd451fc2361e77d2adefde5af413d2210f685a6f6e650de5490dba339b6e01 +00 0050245c1682344fef23bd549ac8d1e8e44b2840c43eec1cecd33daa4e9ef6b53f496104d7432e14248682cfd6f5b4853b65adac 8589bbeb9d967577b748e1cc770226a6f5c66321d6720ef99c97b1b9cec263f0f152a1ec54c20ceb744cfb595226cfe2 +00 008d3b0277f0e9fe54581d3a9499ccd7f015c08339591326859af969d2a26284e3b3beac4a0b74d324ce5cb5f38c7995e4e3a41f ac7f7c2a16c1d7184538e09385074337ad8be310ca41eae4790cb8627a35868e3bc14c51487ff7a0de847c16ed7ab057 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B409_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B409_blst new file mode 100644 index 000000000000..5bd277a30b79 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B409_blst @@ -0,0 +1,60 @@ +00 00beb0df3b0e05a4b5cf67abef2b1827f5f3ada4a0e6c3f23d698f15a3176cb40e85bf741c9fbc78c9e207fa7302657527fd92fb aa4b0b69a223516e17522edc9dcfc2a6c3682c68a9c4200a5475838ccdc6f1c180e89bc48a95a0162c329d7f50ad7e61 +00 00504865a30984a9b273d1bc289d734d10e0aa56e93ab14720f1a42a27d8cc932cb8804b963175de6fe57d8eafa8ab7ea0592dfa b63998337604f8717d459cea83a8c0590232aa591bbcaa14f755c7075dd1924babbcf81ffca395c8f9d53ad4bca91852 +00 00cc08a4ea5ebe32027885a8c212870e7c45b6c610117994d6a42a284c05199414a3a0e8e6645ac5c2ebf21c505a601f69c62b85 96cf32fe10568a883165459882ccf9b63fdf29f7e43b14809528334eaeb9ff0c1e942d75d4b2c36ea9feac9e72c16079 +00 007156ef0a74ee1119532a2a7e8c02be1559c3c21897af9d5b34553c3d0feca4a8d5929d1945df824478e0c0b92a6fac8c84f639 ae102a70254666140689fbdd26f74b0c14fc0c91d20b22e36fdbc57677c02d6422871702aad8c395115030185752e668 +00 00a95c7abffa92e2c637611ccba66ff9d2ab121b40a85c5b71454cb0dca1f098ce1be8d9ea4933d1a91bcd270c5a33687835d6e4 b4fc6fe6554db126ec4171deb913f4027eedcf6e2d70c08d693d40448d8b7c567c768a21bd6dada7ff5009763b5d68c0 +00 002c438b07c6e0685d1f94a4bbafc013f8f21265d893f54e54c3ac2071606ad1ffacace0b8367aad724b1d9508c65ce52282e397 92ac9d90553fe410d23f23d4a0743c1da0c2cdf129705d30e5a2cb7f930d31a9a7b8b5b261cefc90c973986e1d651fee +00 009e8658f8f9e6cd98c0f4f0fd20d64d725653aeba339504def17f3ad12a63dc6157d80804e5f43f4ff48fc5573fde2c615ed31b b406b0481696898ccf320d8d619e27690e56c1f404cd24a6aa3c84bf14f4242353c4820a253cca8fa5f61b8dd5971a8e +00 00c4c13f65eacce85a51881caa6f82d9e48ec2ac574947d2751823a7f072d38bd9da0cdf30b6f19084a6d291052e7bbc2e1349e1 aac2495c7198e8ca040b095b9aaba5ac37976f7683cbac3a41aa52cbeea19408a303b71f7a53c01708d56f60260bec9c +00 00da591461791ae7847e6d8dd8df46a63d3021644abe9520e158406c96540d8fd82ecfb1c3f6f5cfd7688c7656cc3e3dc94e586e 94ddabd219ec9a4f406012b0b07c2966a5b7584e6f84edbe9ce7898b8d022bfdbb70171d49ae9053a2da55763007fb0f +00 00b5eb943f0dd390b737510e2bb703a67f2dd89dc9f6dca6790bc7a260cb2d0fb8e1a81ad6009ed51010e7686d5b48233c6c1686 aae26c11d6aac56ed0a7e98ea34f41e4709964ddf85936648cfc35a813a1a9ba48dbe0453bdf5c3dc2daeed83848231a +00 009cc63f32152284fca27ab2837bf1343144336a1fdf15b9727c47e877ac69ac9cf4c97b4bf42f1ab10d73de8597a554ed099efa 92237947e15b5596a26efebad76e209ccc6bafb14be56bfe1e0f7b71d3bf52665db4bfc06d6db5ef4a58242c80d9904d +00 009950355e8667bea8bbe3a2c4988436ab5394551b375e27fdc0c1a1d1b07ae957932f428f1aca0a486e54cd0b5bb0a5c5650641 8b293cc2ac1c9b2b3071f9056eb30f46d5451b676ba16fb7dc3627c0e32d95a2410f8b21dec03ecddd8ab9b4b7e104d6 +00 00a995493d6971c2d7e8fac3da9f8c0b5afd877cfb94924cfecc167f9d87002136ab253e3a4f9ddf5c9c99bb1dc1af0c6a3a3c4c 8367fb01fdd92640bca9daf4fc13111acc482eeb8b832014cdd6aa13b6e7c6373aeb9aa2596d6aa1f7323d9af98a9e02 +00 0070daf435cdc26ad66c3186267ad12d10f28d32d863f950cbfcf042fe9dfce553750ad098f82f7f1650c1126b3e4451bee6e11f a2dfe8113e011a3d57eecf450ce5c50f85b0003484b5dffb916fa2f03275bd7d333ed12bfe4b17658835b3b1f5ecf67c +00 00f8121980dfbe9ad0bf92383c7cab95fb72d5caba96e1de7772c6a179e85414802fbb86d725401451329287305570ec7fdd873a 844959b5780521974ab50816cc98d6ba9d7dc9d0860e01bb317d8f61620ef4c70fbc34f45c75d55b3b8bad8d9cf4b5c8 +00 0047682b2e3bcb5800a531858e8137692a9b1ee98ea74e929ce4c919c26ae3b3f1d4122d07fd9a70d8315fab727ccb67004187a3 8d14108e76981b52e75aecf929c9c2dc60f82adf62075f394a24bd4c8688cc70c53d49c6b5baff87ef2dae5232d66d24 +00 0040cd1a06233ac27f3ddd108de7c6c0982793ee620d71982697713be9fd5143658929924cc88747a680779bb00da8a44e1e7d3f a3e0b05126e88fa9e867da667ff233008a4931a74fbea88ae0412f8d2611b19ace3222553f35879a3649f6528a4304a4 +00 001ca6f752aae4eb7fc9c73a08d6fbd96bfde5030d759a2507bd45b6e1d1487e53abbe98fad4f41976364e0a1d830910ccf97abc 81625814ede94a69e45d5e4898d0ff6a782ae9ffa66d9b799254d5fc1eebce05ae64d2755a34f84450f85dea26302e8c +00 00fb9b1a9597d216028902abf743d25944258b48c9762d4589fe660396130b75f6006cacfde60f6204463cb8c18b032de1dd68d2 b8456eb2db1dc5416ffa9132fc6681e89b586e491fd1598875ac237778f0721f9fce429b86327d6a539a1f5913787f20 +00 0032109202d754da290c266f74f47805a06e6b5c3f721a72fc97a3bffeb8887e0c642d49a6bd034847d0a5ba09239c5dfdf0772d b859d0d45646471b41ff818717cdb9e8997af19b239562d668184af59a081323554cb45aed3fd7aaa5e2a926c6ec4691 +00 0080536e820fac59b3203aea928475043b2576446619001647e35693a9e65d15236c3cbc12e1bbe0eb305973535c882b70197a92 a8ecef1e5492c845f918885f9f0e801848aee511c1c8920c7363cf8343a2033350d1302f8eaa105a162fd2a8cf6aba26 +00 00b05e5f0dad9583ea18fb8fc4d8c75fd2e3cf9e92cdd9b737485c953620d345006c31c288b380258b6500b84f729ce6730e5303 8ac0e11fe717201ad058362871688be8cfcc4136d939898d7241a60978eecf386cbbb831a55061eb5e2e9052db890722 +00 00be1d277813e79051ca1611c783d66003ef759b9e104f32298017fb97667b94dcee1ce807dc6b4d62416e65d4120523bf6a4edc afd824fca25988a8fb01e4d374131de0f493e9279908c804b27efeebda00d7af1d2d93c3f3ff23e07b2519429e6fb587 +00 0073c807bd7e07379782ab790720de4ae5106f16d34e80ed70da5b1594e660c9b775db94066b93e74f855f57d88b6ecc6228aace b7ef2412b4c8ac4245259dfe1bf1920cb3870e2602f712f6cd4080d169b7cc1d07405769f8c0bd3b0c3cdfb2cf539829 +00 00a68379b2296a6c944ad5dacb593b302d8ef0b05873ce12bbc371d705f308c739d21f343349524aa72f05341e64f7435daef112 8075b73084248f2cfa6b84f2b798ac18bcd1a19eb22fc5f70fc45b153d931872a49a8d126cef4d7c726a9259b455bef9 +00 0026046bbb269ddb1ec14ade56175482343a21b7c265026cef3c7d6a1ae0f6a68166b9e6c49a6e733ad2ad64df7137ef230038fb 8773469e174e28cf232fd3322dbf5ff16bdba2d5dacc435ccd0e9ac17be55c793de46035de5fa94f55ddb5e379edcbaa +00 00bbcda66978ea526f7bd867c3303b625f11b94dd9ee6e2c2f8688ff07f2bba83c662949d47ad47fa882cb7d203a7f0ef5dbc52a 95de42dd38232dd23822d571489a7a5d0699858f37a8d1af81658115ef7229a41b0d67961f8f57efff33d86d1a905c9d +00 009be3dd3442e0330750f0a6252bf9cb317f32f942ae516a4038dea2c40ca6484fb33611bef016cc64baf166c122e87c15466fd8 a721588acd660d6202cc6ebdd9b211899b336ab4010e592fd36ec0b032d1882eea273173c0c2a3cb990f23c182946770 +00 00ed321fa283c662e87eaab99b7715e6cdc9b42e14fa5bbe2c56fdfb381369191a42da7e574839f90a85577485f19446fccaf6cd 87ce7b0c6a55c28d2cc5be26f82c4e815a44ec453b3b6993ec81466e60e708e9af0837dd37d4fa8b32a25f07c8d393ad +00 00396b805073f3c3b552b1024dcf35559ac44f255b688871a3c6657f727a4b09f3806cbb75d26a00ae1728be632387e804775a8c a323b1388c3ab7c5e079f1649f9bc87b6e072f65c02a43247dc36c64a83cf35b89f56634106a00e26e012a4aee22f03a +00 00a8fe323f6736bcabe971c7d964e75dece70cb54561da48a11c40027ebddb23e41c7b48600f569500fe8ea2abebdf480171dde4 8cc738cc748e50fb44a2beb6ddb03409e6d734f9a1e28db70ca8ad9d3b735595300b41a3ee46a7698b8d3bdbfed61de7 +00 00105938ba9f25034da3e032dee121bdb192ac2128b50a2ed4bca042e96cfaf4660c9d35f3e67bafd4c99f9447e6dc408e0c4471 8062284e721398dc86c9525d45b821e4f256bbd3c6b5e6b3c06f4a62b5d0eb7c0d28796d107c0b72df916ed887135e48 +00 00ce11677ca818537dbaeb880fc967dc8bead203a2538a55e756679c4a9e7975b9b3e6aba4e6c6eab4152d0c0939027e9b0bd92a a5b99aad2794ea07e31f09ffc31c311846aa28845dfa84bba49cd0463c4600d4f4e803876ac2c1e066ec9d73a332f43c +00 005a239ae0f40d76d8d3589f1662b5ca12176a4b2784faa8339b54e96a1e1294433a4d83bf904196f939bd8b33bdb4be340ec703 af69cbd1a816ef71af0857ddd1eeb04f0ec8291895fb081b725c22bc93bd2041d333424a00fe6bee28d3dc0fa5d43ddc +00 00077390c62ac41aca995640fde0c79c76f4ea8a8dbb22323ed812bee837ab8798c5d0ba976c7aa634d4b1c2c155de2709e7352c 93458cfc02116a1b324bf470f2495b20316077b254fdd635a3ca4296cb96dc35e90c1c331ab5dcdbacd4faea5d532fc6 +00 008bf23b09fbbed1b55769907aafb97f4759cec98649b2c9da5157517d4f85bb70157076b5e4aaa7a940af042302f8be06a84ab6 a1703f2c0411645ed13180336bf30930f5fc82023d9e238d47a5fe19bacfe5408b7ac79fa329cc7122fc89d2745d5f31 +00 00082ad05d19b8e16f80e53a4cccf6869ab5128c5e622ed146fa8555985ccd2aa3b9957dd374586115d4d75b1c01cf98ecfc3646 a3489caf70de5659bb1b55b2adb093e85e8e4f6a66df882620fc043dc4525a565d1298c9fc95664621e1d6b60544205e +00 00af7e581aa4f9be5815f0c447e39de00da9194eee5e5f609668b9b69930b5b48a948614c2250260d1917f0ebcb00ebda4bb52f8 a6ac8779663385f88f793ac4156a010cd6bbeff503aa23023f4a515e5312d5a910054a383eb24582f21e2ac1c262364b +00 006d14107b08354e6a41d7d7d50c004419db8bdc50db43428df5e86084551237223c498bce71a17e25695bc438c5c09e009c60e2 855e6e48fdeaf76a5017d0c8fe550511cb6536cffba563dd6d091f32f0059569c74bc49d17ba7dc3481cc8d15ba05b76 +00 0099d96d2dc9c79549f031bd5346cf6a8544c312a3fbfc560dc8e378efdfe025b0e6e61e09c04c8bf4133396f993b0906c33dd30 84537eee56dfc8e48aee1b55d2d3887dbee5310ee777c0a02f6d748dad780a51142fd04ab7bbfb1d4774f4393c722e87 +00 0049f347dfd361a65910e97fcefbf60013a54837f2ae657d65e02397f59dc6bca27704fed3affdc3d833fdc621cc5e5f99b92a63 b0baea307831230276abf5307ac8e0d88e72d2c98731b45f4f5a2b11e12893128e767e4e3aee4a6eb71426550e2a71c0 +00 00dd226de602af4e9f8e25784bd1bbd4cadb0a8aef525d5e2d57b9f3555feb698765672c5099a7d6dd5faaded69d8d68b4804f26 96722e0caa243610d3104c32da07da6a15497122a8ee005731a1cb165e7982faecf384484f1afbc4ba963797f99d5006 +00 00b6fdbc9c8c76cb2b822a940d8675889ca6f5132429da795462381ce29313a23bc132976fbeb346ed4c691e651028f873ce7971 932249fcf88f60e670c7aefc085f95cc451a85740ef94a9031e702a050a75ae7472dd82d4dc137cc2ae1e383f7b14707 +00 00203d77fac64591eb9a18de20a9d5eacaa1c3ec58a5ecdb3008c2d642e197141d16b3a9fdffe61429264f5b420f5e9926659a4c a5f32fcbe5dfbd6bea6821286a9e47a1afebae161c334cfcfc479e3faecb186127acd99c1257885a441b5831bb7f94f9 +00 0057a2e6a59d4871c3d547690237dd9846d6d5dc4ec0678aafc9c8669af8a641eed67bfea4b05fd6b3b5357ec4d0caf352691ea4 a1788ce78f30d113d8d603eebca9666fdf1d6f282d8f4c24bc09a2ea0ad866ef85c4bc2cdc8ce32d59af9560abe383af +00 000a3da7a6633608fcee9ce4253bbcec08d41ee6b00178ceb017de74e24d48fd89107c9f2db3556063abe3cb011938f4b4871795 a42888f301936edb773ec60fc946eaed42c718e708204d2516298571048a1b0a9bbc253eebc593c5736be6051da77b33 +00 00384723c8b4a316b450d1fce0b2645912b8acaeb3cad50860cca43bdc0206ed5b3b60ebdc29b3eda305d0d60eeaec261edc24d5 81a61d301af5bf779b468c325436e4a093904174a76f1843133e98681672f74aeb1747f29a068a3ac9eeca3aec2178ae +00 00bd3136647572fef3de51b12e64b36460bd3a27dc660c164fc705417339cab21f9e1f9be0f3da926df459c5ba58b701d306e67a 8a310931a7fb6bd07157dffdb74624255622a2aa144ec3e927015fb1fc4fcf5ab606c5000b773c2f0c0f1eb60fd1657e +00 00495be0b0a9d357f6155fac008cec90442200bb842d89292fde38b7256e4117284a60249b3101b3f19f778b680c0d1d7422b84a b3f7903698e3fc7f18209f6ba82003c2e06105f7615d96173292528bc1fe5e05d4e8e349004e2c5a13f2a3d623bd3efb +00 0079626354dfc4eeeb51fcf232ee9e6b0130c9bd40f15ed45606bb7faeca8f359e0c3e18bf12769254522fd4077eb24bd5454871 b72578b4f5631146e0a1ec6f8c9bcf9c6152e6c6a8ab2cd10c536a766f76804c127f1de6c06a5cb2dcc8fc735c9bd7d1 +00 00ab42bc7d0e3c23f8bcf928e25f9f027b56f270398a1d37bea0ee5426b944a9c9ba6d0d7796899543feedb470f70b2ab148234f 8ddd65e077da4e61a542770ceb32c0e762c79543262f0002506e0f923d7c16dc09d78823806a88649aa6d6d300864bab +00 007f7aa2216164ba689459ee5d5ca29e70ef75a5b2a4416ab588df1dcb9164330c0b405a9d80c3acc41c19f58e24e17ecbc0fa7b aaf93702abb2f17c5fd57719990c59a53ea55b4b34f19368991acfd6d9b7e930c7c477cc022c6009317982e5323ddb08 +00 0021d84f070c6823a70f1a74225a472118c93ce9dc509aa6064051ca4574939dcfa96be862069424bdf1a23f62f2868326422e64 b5b248fe86c8346baf640df9f9fd36ff9cdff7f9a368ed60f10a494b4334d611fe006f3a107bb235110a20cf5633ac32 +00 00b6645344d17528968c719091b6e2072388881dc10bdb4c7fbf41906cadf3699b30f9c1dbfb4796d009480664e6276c0359e5db b771b13b5391a6ba51b365b8e5e042ba86b78cbe7ebdc750c3167e2f4db1dd6fbe4f79ddc6d75491f1014b14f424359e +00 00f8c2f770cf5f8e1f900e996ecdcd84fcff5cd959777fd005d721a419123221a3237e39834b270d37752470deaa6cea023c5058 95f35bb5c3ddbbdfca99185bd41afe0e108d9840ee806fdd40e998af184d4cf472099ee9a770d9108cb1bc5ec7ab4b0b +00 00144adae951fe897d5812ee4a16c0be4c86c5e57e615c398f5768a1223a9be20fa82ceccf8a16a31432bbfd17e594a4cd8a6a07 a80bc32699e7928e64422f9b68e90e3ba09b9f99455b85845a350d8e244cfaa3f0bd8cdd6b1ce6420dac42219261d2a7 +00 00a51f065fb32c55bf4ff6f18ba9d488d35d9f8da593adb0ab1632533284e0adc43ccdbda9d9507b9862ac63b5ae7b0f78b479bb 882c6959260a523251ddbfc157e044cccb608a5f52b882c5bf3d728a827acc71c220246b423dee3c6e5a2756ee472973 +00 0095351c0bc07acfabe6477fe85f97eab520dc96bdd58b44b036328ceadaa56a1904d2217c5fd25155ff2aaf9005a3e2687fec81 8cc94fec0fcc34f6d3cb5954b548638affcba5662eb7647a673722b6f6ae99ec22cad58d89303ddac71f32f551b25e0f +00 0050245c1682344fef23bd549ac8d1e8e44b2840c43eec1cecd33daa4e9ef6b53f496104d7432e14248682cfd6f5b4853b65adac 99bb6d19f5314a9e157a1e021082c6cb4d414dd9fecec904511c4633e183f595276aedc9f7260718029fa87be40d1973 +00 008d3b0277f0e9fe54581d3a9499ccd7f015c08339591326859af969d2a26284e3b3beac4a0b74d324ce5cb5f38c7995e4e3a41f b4db9863fd96752cce23ca4d5e97ff75b05695e1ea3c18e5fd9e31fa163f12a6069ea77f06ea9de344afa3354539032e diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B571 b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B571 new file mode 100644 index 000000000000..8aca8e69259f --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B571 @@ -0,0 +1,60 @@ +00 00f42afce7f7b3d45f3f925ab29fc3882a89c9f585177887584703cf8bd8fc572e677adfa55b402446fe1e90dc855358d92c3267c35be9674b40c2ad5ce8dbe6a533c44b0ad8d2b2 878925a7664cfa8d6a8f5c697825419e183d23c0b82a80b712b5097387c3e26f2515f2038e043c163aa80c23f1cda53e +00 02f36613043cbf53ad36e2b38998bb867503359ae082d07d040e5a10a43e06ba9c91e7c73308e41e2391b65e634f83b162cbdf4e7a44ad818fb93a978af00f06be06731d8c5886c6 a1fabd6c8d43d47c7e6addb9eb293f77595e9f468be155758f26c1402f960d6677d94a042a00d8816ce35a403e5b4432 +00 02e74948c46930cbcd9dbe2325539c7dfdd910f309fd610e6599d425aad9ae230a8d4681970a14f2a71fd08030d0a40ff40dade7de1b06a80441bbf7e2fcf1809cff39c7ef88bf9f a5d1658977823592ab00a0c5476fb2f82e178c2718be814aa2a4dfca52caf4d47e32cd7a212c04d42feabf7d194d89d9 +00 01b5fab1d36f6f6d559f65d8b01edba610620fc3a38307b1fb1c5bd63e7ffbd4a9098cb8bdf50975a873f5d047ee2b627b090897a7fb5f56d3f4a0f3528179e7c969926fc0d3b0e5 99d34504f658c64a1a72cc28da57bce63f69059baec0d797429f341cef3fc41770005025db9782d11ad8ddc9574e565a +00 0383e70c71b431eedd4574f65d01fb0304f7744d668408c847f7899eae44770a7f3243109740f177d7146a27748886b7b77ecf3792b512e8d8e37c3bf4ecef2b1253df7066498f01 b8baeb214d52b4fbbd40d28f48493a79d02eb8b095fd3710b65774fcdb8ece01926ac1023b5c4c49e5a74e0ba5561ebe +00 002261d4ead21f02fab19bbb0da8c272286704c8f0c6842ba47ded121e5cddef79fb34e6b9694f725ca502949faecfb21e3cc062a2b4c654bd542d9a1fe8d97bdd0905c510aa0999 a51d59e2b3375ea4440e7d5458a8c189634092ed0523e0548ad69c98ccd8fb8a53f7bb91677b07a624db3677ff3fefcc +00 0316c78f289e1860bb623082be9d9238b88e38c5e978a868bb90f776235bdff4eff591877b7f350cf14c40356922b2b6aa51d64990360b2b0e44d6941b5dd9492b4f4e1f42ca163a a2120c09ddd9c39886e30a4d90602798b246203088ac05039a7a5636a594c6f344f5d4c972901bdac3b1240c546ba73d +00 02c1bc13f8320d97a82f3d9354e195481902214e16a4fd89332a0499208e91d50e5cabeb4927ba030cb42f5bc53b10f500fa646a8c88508cb0d63ebfce5c4bd574c527d686c735ce a5175adfae291c070de41184f4fba2d97cefd8c078c7a2902e30348aaf7f1b79542035002bb1aab74085c8f8c361d618 +00 013bd80eafa67663e75d7ae139bf285d2b9f1e03d8e32153c73e26d06e86d7acad22bde9f121a3f1ea674dcc1fe67bc7f5398d5e92555056bc046a02b0ba86c2a0dfe32e91add5b6 84145f1ceb5f461bc10672bee8429e764c021e68952beee35759f3c9ea8212ad935037cefffa46a2c9dd679af275e8ef +00 030834b0a4284097cdda2ada6947c6c281f7290a49b56becefea1e2788ea3ef78fb96807633c47c25138341768b241164ce0d42f7301728b928be2c047f2eb60fc2f844ab77306d2 b0fb44fb65804be366c65c650d4d1ad3baeb8a64423c8178a36ac5ef11ca2a3b6258f00f9ea7d93b0be84ef0405ba325 +00 00c81a79ced1eaaafc31b69a40d9939f4e484d625db6364a8e589b6b4d336d458b44287ea6c6aa7661113fc07806b147ff98216fa0c08708dc9d651821b922741deda522b4e436ad b5538462f93b08c6f71f8f63ec66918a56d08f8e33c02108b185218f2e2d3e7cef92a3b23830e2639fd5150cbfa70418 +00 02f24670c0f77d2ca0266a743023d2c7413d56d0b5ec77b454ac59087efc4ea4d46179e10278e4ba416ffd8c3f9786ed202faf8251c0ef5a9ea5371fbb35b7afe3d15a9cb4bad975 b54e816a8d7e776d39b71bfc8956daa6f5eff3e8ca7c75213c3aba3394a0ffc06d23e4115cf6f531b00938761d2563bb +00 020985f2c6fe3ea04bdbab66a8b6167e5969c073b9d53cf3c77cebbf73f4dbf75e601620ec9c3107bf3fbfc6c79f8f063409bf8fe1d14b19e323d857e23dc05157d270c7514137e4 86fca733341ba7cbcaf211780aae1a103b232266f095115dada2deebf781926d7f7add63e2e807bb313ae88b530ec897 +00 02b3d641607b8a141f876f6d285ee46aea543880e772dadd5dd83d595b9643191d9597218e1d6adb081df133304037bcd2c05c24a54e6c4cca64fb2cc4569d6882315360059496d8 b724cc9062ced45c3c281bf341c1dcad7f2ea50179fe16b3630eb499a4cb031bbbccfd29898311f7ee4f7ea89160f312 +00 01afeb5ca87c81025ddf09c2b2c5ee22ba0105c0e619b67a324467485bd839030d149fee44d8bac6f5902a1245a50c3437046b7c89a84116b2147cddc645b6d2fd24d68e8d53bf5b 996a238af2b83db476d4dea2ac8922fced314f0c402bcd7cb84513b4e02518ab79a7be9ff66d38635685c1a8e3d863b4 +00 032c97639b69c7cdbf419286d0a1b406d9b1f2886521a8b979a36118d2a368aace5b02dd8c515f2041e6fb9f026d1e82e789dc826a56d2ef732b1bb0f49be2b696ab5d3d5694a2de 8ec5ea3cc17e03e302d4bfe8c1853e88179584ac170c65295c5d2640151479c7dd1fde6c97e216ef8eeb9a9795d3eec4 +00 00f93672159276c5a293582b9f49607bbdb970112f6c63b2b3b5d32ad3c8240c86b1af13a8dff6502c6b6a17712cfd988f8cd23a60693d64104143b3f91adb37f852e9e11a0ef110 b30f5aabe298f29c4d85364c561df719ade9130d1bff043dccedc3359deca0d9f03236104e2d2886d904b070e8706688 +00 03db080bc99c5fe7e06d5032167af56783cb423fae59fb5b3c6bce5fbedf56b7b39b17810e48ea9a172881aa1f42f5e267349b60294d4a208b4437666b44abcfee5a1829e9467908 a7fdc52c133714a5f2285c4c1e42b58750ca2ad61f283c15d2e0ebe17e0a357b182c572855da67e5be0bc62f6407c953 +00 006ee767f6f36bb8f364f324d8346455c899a49237d759003dd52cfa13b9baa4c71347b134b24ecaee32d247c34e3787a0c64bc5d299b55c86f64b47521d22f2c09db225b0c84cc6 8dd089a19f7eb3403e7768752d26445496708365c1505c499469743fbb0dcb7e49abaa133f0fd4d65ea9358a1a57cf17 +00 038e2571d9f22309a636586d62863ed67a70538287f3ef88b88c3c2fa1a2900d48c342b6f15c26b8e7fb4875cda4093b7de7ceda48fe1e2cc2975afe958040881de61f309931e48d 8512cbe1d0a96511224e782a6edfd511db923648e9d666d7f68f475d8e036fd6fa643823e91c0cb5ca624164a813d989 +00 00c8f5736f1ae65592f3ca850f43d06441aaad8c03820f3b08d8a6db46488dcfb828459f8b3f34af73cce8dc7a5e3834e085a64523d890028e194214cef4003210e6eb530005b01a b5e6583532e504b212e6bcdb15c2f095e2ae2f55fb2d4d5780edd326ab7d512d3633cca5c892defe1a7a0368072b72fe +00 01ee68c3994adaaa9e0d61bfcd3bc1cdf198d3fbfe28a44e5dd518867ea04b20e795eadacc48bfcf8e8216dceeaa069b756e8e99ed87b6b1d31154cc9310bc3b4555162a890b0c6c a07e1c2d96f58b3969c869f1fcb2b2c4307289f9db5e506438ebb381001ad704357a0c8e8f49d4d02d52348c9b671bd9 +00 03a6fbf66ebc1365ea7699c72cdac2dd85907ec59cd26e2d18713354b619ccb83b7fc0db9193aa8493c1855f1a83fd987cbbb65de17c59fbe79256aa5392f4eba045346e9ba26592 874d9d67ff3a92b712e3f648cda094fed44611d926c71ec2db52a745485901e8c00554f2301e9c3be2d98fe9a53fbf5f +00 0145748871a0b5c1cee628de04a12fd68ff2b154fda96e47afaa96389d66d22802968584f6753d36618d49ed205260f09d3f5ccc2b27a34390ce58179b9834ff92a86d66ea0a97ca 9172ccfb2ead846cddb4d13aed2a1ab8b95d79206e39384ee94111ece514767f3f5fbb3e7e91d2a7f9ec9562d73f9eef +00 03c71911d24ad19c20fc1d8a044d63c9bb417abc3778d7e6234c6af79b898cbfc2f2787244708d2fe203be786edbdc4c9b12b413156b7b0bab0be8af895d191d853cd58aafe1ccce b0ea190fce7cd03a090b4763f204c1c0ea3df3096aa4eef06158245923f1fca56aed9cc6585a0e81caed8bbc8157d897 +00 018bd74698bac36ef11add6b3e3fad227ecd868f370ec04569462565d2f0af2340bf793486953a7b79ab04f0ab1f0e4fd16bf6b576cce677d543e73aa8edb0e50372f24ddfbff966 aa6b652e72afedf3596118fd08ec97226d6c90568f4df110af0f333b0b8687a545cd455ab5c05b0dde1294df2e840826 +00 0335699bfd058ee2e6163f55d1816bf3669acea8b73be9c4ddfe775230925e6093cff7a66813adf22222c8376faa106d85ac9f3c67929bc58d8986795b6d35d5b9fa546dceabbedc b60b4857779f0fbe3aeffed63efe332669becde8d255f06f995e6a6d12cd17b4563ea77bba80722bb1ad75ee895d8ba7 +00 02c3eaf801330b3f1b0504f2399f1d24455db29911f750c246ba0a134c3b59da8b3562911197764699a92ea1d95a2aac587e24f743df1dad3e1cf7edf955203e24a0225717f8d2df 8a5bf14ffe8590a894589d54dde7e3371fdb921564e3ff73a9331de0310b552b4d871522f8c638cf33615fcab1fa9655 +00 01c3ff067497e5d387f31f0ecc9c67b3c0dd6ec8c81318c492aad83c9dec6c99e4fa47447f6f7082d636c2591d0df940b947d0a4ae3778e2b7cc8fb92214638399def894ada276b8 a990d89f58e77a829da508b65d9eae4a432ea34dbcd572100a28c7f6b1c949bd4e8a2cd4f9e25b717b0f952883d647d9 +00 004b4e04281b210fe78d516a5b69f878b7fa058941ee9ae8cc63b061d1eb9e12c3e0ecb8717ff4623ff5bbbcdb53c48adbd9c69636506ab929c5507d7ebafae5654aad65a263e48d ad8e9fb57266208a175ce2f79945d953520888a8b826e74a6d2a100003724f8c54f866d918eff42981f6cf2275ccf5e7 +00 030f2849a713aeac95fde5ce3af853e9d070ee60709eccf35a076567be2c43f0fa34420b0fc097ff577221275a3a56e759efc32183be2d76058a7d20e5dd59f00415114d73a15b8f 81948547a982287c46b807972c6d7ed806f9ef0c78d57b65ec6af6ff9ab3b62426314e5bc256245d822b9ee9b83edeb2 +00 02ebb73d04e6e5361e20629e3ad119b33db5163ed91fd9a8aec4b774898784b6822a08992118a8fe6013094bad0be1e9bf01b27c069e4335bff7e0abd28a10443818f6b825e9cef1 8e9b48aacea904bf552cc88f0e50dcb1cc5af6bae9bdfa55a342c4aedab8dd14cd1cad06917457226746c63def7ad938 +00 01bfab717d6f6e16d9bc6e89d2ffac7cbe0f808cc8ca2eb515af7ecce5f3b230303775710a21bd25c2cc4566bb53c78c78e3774a9f306c751cc6e149929e45eef60f56c1d2388c6d 8990e27fc61ed122252a3ee40dceb3ee89296e2b1c51abc7f3fcb69d5a1dc49c2af8d4fe37462a15a2553ce1c51818f0 +00 000cc53bf7f1cad5e3dede4b4f4b082831604c92dd2b147869cdf1107259305b1d50359647f9f3d7d4e1e608865c65dc7c9ea46bc324dcb8423b554dc369d621743cbfb592b70eb5 995fae2859222a8c4365224e8e59a30b31d5d1962c79e14e10cb10115c01a83729c9a6ca4282aea1de929a6a1ecf0a34 +00 02b009530cb9d586e35dd8951ccb686833afb7a37ec253e547e85b253ba999f0f186b6d4ba41091615fe57678e9801b4dc94fa683511da25637b2acc9fe60936be15af16234c4ee7 a7d6b4ed184e67b83594bb40a6a701c1601950b865d00c90fdb6e6077aee96144419e0fe13ef94bf63f69b5eb2681c08 +00 02cc2d0d7189cc8fb3565a039aee7633ddc00ff427cafad32fd2010b10fe249c9724d91785e7080203626038109158e3a61a3970aa3e51688aa7f5184b22f63af63f80d3540ec023 827411df21b10fa5ace15b7cdd7c81f66404abb17100b1831825a02f725ca64b89f9e20b474b95ded73fd586168994df +00 03d8936c00c131e38c6566d2464c4e207c878070bbf681695a6cd98cab2c6e80fe98cda80c66a5cf584e90a071144dda59c07b8fc7bb42464dbee5b6f739b0f2ee5fdff7e5a4e7cf b8268cc81bbe7ec0385f56383d09259249101f73f32646078ec17d6340ea0ede22ada3dd6ca30e631a2364b6ba2f5bec +00 03dc7de970bce28a943d7599f2a9010fc99435b93bc4ba884d42503ac2941aa63fd07db34bcbb1127d56d6a4e277d6ca32051ea3467e376f74f98c3999d2f276b282ef8a28cf0cbc a5fa3786fb3ac7f154465ca1bdfa0458c97b2b5c7ee2fbbe90bad92b3fe34b9963d6cc0936a3d870dbca894b65bfae29 +00 02de6ee12eefa7a4a736484b19b42a513dfc059a060976edc3b0aa4b50e98d72df6506fed0499ff8480986748e938289e54a5e86c0c29733a9bcf5985aa63d8a2b57933a04a8e8e0 8a3b0c2a0f6fb7291ae7e9a24033021e7e35b95f1e800b884e1bf7610cc4eb36596dd6d54190a89ad4b15f98af13a51a +00 005468f0df2c9854f5f655743e79c750fd8812db28b096d97207bae7f5aafc6b6090c9c636ead9e0fde32a1ff8d539b53813733ca812b41b58ff85a941abe4f128d59fdf9847baa4 a08fa9d81e761d858682e961b837b73cb7a47a7d7a20154ffb24e9b89799f0c4df65d6880052709a61d74fa0033cec9f +00 03d3c6a7ab9450c94aa3b8a1ffb678e5b647af24cbfd66ee3944e6f264f406295b803767471fc67936fdfed1714b4b8761a07eec86543b7c4da6bd2fcb33fa8cda4077737f398e18 ae4382d316372691709fa2914cc7cf38c76d903681a8c779b7aacd7e05ecedfc79f96c54282962f4c316a2d33f87396f +00 001ce010ea8e6e1a0c26ab22eb90f0700dc73b232c429d36371e68e429792afb7223f10327708bcff779ea55fb5f22ad87aa054e84d10f5450f1bc9a89279062ea2173f55ab0f76c b731a2c2c5ea0b976a58dd85d0492108f2ff1fe4d781aa2c9bea399f40feb7979007ac5e6592d993291568ab0c9ad43d +00 01e7410d012aeef02b3723346d24ebafd684c99087ecccaea1cf3735d52c4c81dda41812c09f1e874dc964d858ca240a19963d5dc89451f5dd6764426ae41cb23f19cbfdca0fc562 824e3250fb8245c98131f9696b3a9615599895956f8e37a1effe74e51a297ba730bd6ae9d0839782b2fb2a2e5d74cf64 +00 02139839ce38eb879d266065dde5e5ea227244323b330e3ad5a0bc690f3c210f794cf18f0d730693887548bfbc434f48ee10ed34cb41d52172b06e448df938170a5e17311cab8e88 abb730da058608fa38a469ec94bed905fa0bbe4bf54c38d7ba6d3117736c57e04b66168e200bce05a3c4074ad995cfa7 +00 0274f70fe69e4dbb55c5d404e39f5196335047113087f8711f2f67f2be4964e4fbcb865680758df1c401cd677b0971654b7a6aeb7bee0d6d80ac0de14d4f46f356b2d5545c185aa6 97adb59169fbe7828166a2068bd530adddcdbdeada441969a100fa7f1727663d42c6a9a7de38417cdb008a58811b1839 +00 003e1b03ffca4399d5b439fac8f87a5cb06930f00d304193d7daf83d5947d0c1e293f74aef8e56849f16147133c37a6b3d1b1883e5d61d6b871ea036c5291d9a74541f28878cb986 99cae8e743f2ae38afe549d4e48ded398535dcf832fabd126e42f13b4289c49249548af57928ffba23ab1e1471952622 +00 02e09ffd8b434bb7f67d1d3ccf482164f1653c6e4ec64dec2517aa21b7a93b2b21ea1eebb54734882f29303e489f02e3b741a87287e2dcdf3858eb6d2ec668f8b5b26f442ce513a2 860be16f47149f3f6fbcfb3e545f7a29a19ea42c2e0f26867adb9868fd3126b4436420c4b4502f2faa1bd05deb0cfadf +00 02a69bc1df069c6e89722521a63675f318252be629e7558f3716917998e660ac960b0b750562846fe6c12ef492951e51e224754bab84a6eacd4147a5f26ae85ee4381bb14ec2a8c7 909987e50bdcdec6b3a6987089cd45f478a5c532764e2e54535732822f16d2a4a332379027c177cd60f4bc799d916736 +00 00d11ed1b78b22b3420df4ddc4acc7c2286d9569dd6dd88e0fa3ecae69bcced68bb81bbb4ca6e9b54e67856e7fdf39155aa27aecb9cc827ccb9cdcf9ac633561b27d8eebfc261aee 8b4c4d89b0d38ef11327f8e562148bc991c63a980b366027b0dfd026a4a235ff2066131c1be6f606fe0cbeb169f0d39c +00 02c36ef754b5bd065e9eadde684750acc52795be80f54dd3d7a7d743d968a18f7e404bd71f8a76eb0395f396df5a7c2ff7e0ab6de35df34282fda6ee01fe5b9b68ecb4e378dbe32e 80277fffc36ca1ec13a1cef75f3b13c53348610404cfad8866aaa17c9db5c7c7e02cfdd893707ae6d4e31d6c427c6175 +00 019ffee50be5496507e3ef5c40ee88a49625e46d1dd1686a52b09ad4a8e3ee9ef364f953bfcd97c52104eecb6138067192997cd4ebadaccb73c7b2560879289a46353a756b73cc43 95304936879e5d5cba93f350372bdffb2f9f42ebcc775d9e382eb39aaaf89bc90c4998aec7db3fb2b06f4f9ad2b3d09f +00 03129e96fd28c4198cc5242c1e3531a3979fae643d527044e98d7721aa56b5b4b45dfddfa17a4115e10a2b4f46d92f81cbdd7e86e588a4c6d8c2b3a83f54cebcee1d1dd33e85d81a b5d9e2dbf41d688ed403f8178003d35cc148b746170cd78aa82ab62ed29abaef0a4888b52643da96247455bb7e7f7a81 +00 03d723d2697cd07dd8444f992f2ab4a063db334034c25ea9be99fd7a1f495e3a644e5ea033a41264e0d24a911e55741d0cab80a0bd678eaec2bd1e60424d4491eb86d664900d907e b8851122dbdf5d525e6a792f6c93871e0ebf604cc6c3195b26445ae4788f1feabe76a69c7fab98697d83532233d53dec +00 01999ab45d66cd1d3a0fe6aa43bf5ef1e2a67637d53674f6fbbfb9b582be91fc42a12cdcad94b50b0fc7ac55030de24a0b99fbc4314fa743ef4b5198bcc5f54d8b669fbed78e2e91 b9981ac1e4fb085e3f5544c67017587afbba5a963301426b0251a67805bf933a2a0ecfe907ed645ce39bb3205dafe77a +00 02ce1cae0716205330d730e6bc6dbfb6b951dc83ee3b4a7dae75d057e32e8a46e22be75b5f09135452b29c34dfe81a9be2e8dcd243fbd946a0ed14a832a7802e20cfe1abfd3d6e4b 82c2035cc185a4b4bc7e690cf7cadad2ae81dedd615748a30272da1a78298a0f4d1f9d0bb3dc7608e5dcf8ae244b929f +00 02c9d0fcfcee7e75c3245ba955ae04188b1033c55ec9c821d8de7685276bda3e9a93c3ae1b003e5ea722913e7b169d67b1aa2dc8cd42adbd9368672a3f81a6817bf3e5529dcb0c8b b0ac9a441066ba312afb9ad5c4ad72f93e587c7af75dfc51acf48a3d899f3b19427d1a2b9a88e86ca82e31f5b82d2a6a +00 010c057bbaa44ef0f565edc288bfe66d4f6acd8686899359bca418ba89fb690429489a37bd3c6c9f3a8714b2ca225868c6a45fee360e378a676f7ea39321790f32a4b005b81dce43 a4004e610bc7e0323f19f584415afa9e357a4ab93be973319600ed3583c4fb195ab51fc937b949be1948f6a55a7be807 +00 02c182df7976ea93d996f3ba5d2221f3cb755cc7847bc3fe9e022fa4285046f5bfb426bafa3580beea206de36f87593ae561b4b74a03fcd61fbd0e8d6fd5668f2148819a88a650aa ade9af51d4d29a44c159e49c8967700c86d9d559dca3f378ed0beed4172b63b038d4efb2c55f0453a863140068126a70 +00 02d3a65bbe133cc98cf0eb56ee1362195968b4eab960a1d55d8b762f1361fc21348d6f275d4bea1de7158fb97c995e20b92a9c887a3e332d154667ad167acc632eb88a0ead6113a2 ab0e54267d7b74a207ce770e1faafa311cc921d389f9de2f1f10ebd12902690f2393bf4dee8efe2e4dd69bc333ff8238 +00 02a920e8dc928acdd56e3655b2340d4371c793e66f67405fb7a90f31e9c4ef466cc44331d1d2fe3ff7391d2576dc6640772166ef8c154a5ff1808f5dab2f03061070ec8b3f786c36 81a9cab4ae356d67c6750413916e18da82eff38765d7bd62eb03b723cf2afa81fc9836721234d3cf26d3a69f06a5e00f diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B571_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B571_blst new file mode 100644 index 000000000000..0c617fe22db6 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_B571_blst @@ -0,0 +1,60 @@ +00 00f42afce7f7b3d45f3f925ab29fc3882a89c9f585177887584703cf8bd8fc572e677adfa55b402446fe1e90dc855358d92c3267c35be9674b40c2ad5ce8dbe6a533c44b0ad8d2b2 82c96e9989e4af4952f44e5d03674c962fad8907fe565ee062acd44cbb13ab67f6510deb2e17f0add2e12e591e0efcae +00 02f36613043cbf53ad36e2b38998bb867503359ae082d07d040e5a10a43e06ba9c91e7c73308e41e2391b65e634f83b162cbdf4e7a44ad818fb93a978af00f06be06731d8c5886c6 a96a0fb9860e27082289564824237508217ce24801bcb82b9a9d2563b7eca33279713f7650922595fe284d91ecc31f81 +00 02e74948c46930cbcd9dbe2325539c7dfdd910f309fd610e6599d425aad9ae230a8d4681970a14f2a71fd08030d0a40ff40dade7de1b06a80441bbf7e2fcf1809cff39c7ef88bf9f 894a0652872bcd66cc9c92cf965d91af3eaabc082500b1ed00cdfb2b182d9291cb7459b14ee62d729171f53a63cacc9e +00 01b5fab1d36f6f6d559f65d8b01edba610620fc3a38307b1fb1c5bd63e7ffbd4a9098cb8bdf50975a873f5d047ee2b627b090897a7fb5f56d3f4a0f3528179e7c969926fc0d3b0e5 8560ce65bb346a4032f37bbc2c8fded95f54789d0d02b726d801bd85ea61c5a78607e4d26e5ed976eb82756e6fd040e9 +00 0383e70c71b431eedd4574f65d01fb0304f7744d668408c847f7899eae44770a7f3243109740f177d7146a27748886b7b77ecf3792b512e8d8e37c3bf4ecef2b1253df7066498f01 8e68c091e283d0eefa45bbaa7ffd6b7c7be4103485f5e419d824892dbede686f744c8cdae5e0b4485f05a5a94afd601f +00 002261d4ead21f02fab19bbb0da8c272286704c8f0c6842ba47ded121e5cddef79fb34e6b9694f725ca502949faecfb21e3cc062a2b4c654bd542d9a1fe8d97bdd0905c510aa0999 b0ba666335ef99d8fd93af2314fdff7f7ee501dea0afbfbde0ed1cd079c43f630ee85e3ea0d117ee72a253cd42318acb +00 0316c78f289e1860bb623082be9d9238b88e38c5e978a868bb90f776235bdff4eff591877b7f350cf14c40356922b2b6aa51d64990360b2b0e44d6941b5dd9492b4f4e1f42ca163a 8588958f94e13276668ea9ef751ac35c66f86ceafeade7291edef295cc80de25ee164f24f38ac4bb9ae8333c41eb8a4c +00 02c1bc13f8320d97a82f3d9354e195481902214e16a4fd89332a0499208e91d50e5cabeb4927ba030cb42f5bc53b10f500fa646a8c88508cb0d63ebfce5c4bd574c527d686c735ce b9d657111065f3d2ef84159cca778930385cb29d84d15363fe678b42eaf868274c4fce7101dbae133e859b5f09f72e85 +00 013bd80eafa67663e75d7ae139bf285d2b9f1e03d8e32153c73e26d06e86d7acad22bde9f121a3f1ea674dcc1fe67bc7f5398d5e92555056bc046a02b0ba86c2a0dfe32e91add5b6 b50962ece7bec817a89f4cd38419979da259e84ba6768cd4e4d0bb70d227bac7ec5ad9c542d4a711bd448a15b1c83517 +00 030834b0a4284097cdda2ada6947c6c281f7290a49b56becefea1e2788ea3ef78fb96807633c47c25138341768b241164ce0d42f7301728b928be2c047f2eb60fc2f844ab77306d2 b0f178264efdfe195da19e205ad4f96911eaa790198f69ee32f30122d181de729c97018542c7a2f072c674145f5b403c +00 00c81a79ced1eaaafc31b69a40d9939f4e484d625db6364a8e589b6b4d336d458b44287ea6c6aa7661113fc07806b147ff98216fa0c08708dc9d651821b922741deda522b4e436ad a5c36e2bd31117df7458127b1b358ccea5f9b79fc4f61ac94fdccdd8e250aba9cde89eeff09cdfdbca05f4245356e4ed +00 02f24670c0f77d2ca0266a743023d2c7413d56d0b5ec77b454ac59087efc4ea4d46179e10278e4ba416ffd8c3f9786ed202faf8251c0ef5a9ea5371fbb35b7afe3d15a9cb4bad975 a7680662409ef481ad707011338d4815c5d90a1e56d565db45804b99b5ff1f8a750fcc0921e45855dc8e6fcc4bb63d64 +00 020985f2c6fe3ea04bdbab66a8b6167e5969c073b9d53cf3c77cebbf73f4dbf75e601620ec9c3107bf3fbfc6c79f8f063409bf8fe1d14b19e323d857e23dc05157d270c7514137e4 b7930a6be6ea2594af9cbcfe3a950013012cf1dba3b0e8397a9096104e24208814aa260e881d687f9829bf34322c1eef +00 02b3d641607b8a141f876f6d285ee46aea543880e772dadd5dd83d595b9643191d9597218e1d6adb081df133304037bcd2c05c24a54e6c4cca64fb2cc4569d6882315360059496d8 b1b49e547d43136fa9208b19353e9ea2cfe5356b1ecd9f3c7577d9b85ba578259929a06b841281330502c4e322168c3f +00 01afeb5ca87c81025ddf09c2b2c5ee22ba0105c0e619b67a324467485bd839030d149fee44d8bac6f5902a1245a50c3437046b7c89a84116b2147cddc645b6d2fd24d68e8d53bf5b a3fe80efa21900693657e22337101f3a2a727d97bceda6cdd9f9c68ee1a333a72751a1b8e3b587df842561bc38448476 +00 032c97639b69c7cdbf419286d0a1b406d9b1f2886521a8b979a36118d2a368aace5b02dd8c515f2041e6fb9f026d1e82e789dc826a56d2ef732b1bb0f49be2b696ab5d3d5694a2de b195c9242c7e7f23038972b0ce1c3a6ef1b4ae67d6702d1ffc024235bcae3468a8eb1b0a60aa565923574299d9105c61 +00 00f93672159276c5a293582b9f49607bbdb970112f6c63b2b3b5d32ad3c8240c86b1af13a8dff6502c6b6a17712cfd988f8cd23a60693d64104143b3f91adb37f852e9e11a0ef110 acace9cf3a07b12b1e3ea512578e4f4573c8f8ebb763f76f593a598571f3b4754722761209d6763bf4085e38f6be4e0f +00 03db080bc99c5fe7e06d5032167af56783cb423fae59fb5b3c6bce5fbedf56b7b39b17810e48ea9a172881aa1f42f5e267349b60294d4a208b4437666b44abcfee5a1829e9467908 b3080fb52ce513d817723628da56a84be8ab6969e45ca4f1b26c5f7c93d624a471bdd74896aef9d257a2db9af01e4622 +00 006ee767f6f36bb8f364f324d8346455c899a49237d759003dd52cfa13b9baa4c71347b134b24ecaee32d247c34e3787a0c64bc5d299b55c86f64b47521d22f2c09db225b0c84cc6 ac3c3c0e5cf7dfb4a905801ca1205ca18ca7241429afa801727b90acebd581b1b9f73bef66d046a2b016221e69edf5c4 +00 038e2571d9f22309a636586d62863ed67a70538287f3ef88b88c3c2fa1a2900d48c342b6f15c26b8e7fb4875cda4093b7de7ceda48fe1e2cc2975afe958040881de61f309931e48d 9811337ed2414f59bc6a5156ff3746923e4e06b2a8883d0869924fa8672d0da642eec8040f5e548c8a4cae74986727c5 +00 00c8f5736f1ae65592f3ca850f43d06441aaad8c03820f3b08d8a6db46488dcfb828459f8b3f34af73cce8dc7a5e3834e085a64523d890028e194214cef4003210e6eb530005b01a b6c07de20d04ccb8a835fb10999fc5c60e98ef8e5e4cd46a7970dc3aa4665d17378e29bb0a0378f8c70be364aad76854 +00 01ee68c3994adaaa9e0d61bfcd3bc1cdf198d3fbfe28a44e5dd518867ea04b20e795eadacc48bfcf8e8216dceeaa069b756e8e99ed87b6b1d31154cc9310bc3b4555162a890b0c6c 91286889cc0578e2869a55d6fefe8d38cdbdad27393799754fde08f61bc0530455492eeb21abc809d30f24dbbc07aa49 +00 03a6fbf66ebc1365ea7699c72cdac2dd85907ec59cd26e2d18713354b619ccb83b7fc0db9193aa8493c1855f1a83fd987cbbb65de17c59fbe79256aa5392f4eba045346e9ba26592 84835cd65495474aa0d89063bf050b616a8ddb0b745d8055a1e3ed65010b82f2fbbbf60c26f99414e183a9211c503a60 +00 0145748871a0b5c1cee628de04a12fd68ff2b154fda96e47afaa96389d66d22802968584f6753d36618d49ed205260f09d3f5ccc2b27a34390ce58179b9834ff92a86d66ea0a97ca 8d2ef5627880b1591ac4468539a95b9c05218c420e33764ec2f504c740ebfa2e7b3454e55d65e998696dcf6d87779ea9 +00 03c71911d24ad19c20fc1d8a044d63c9bb417abc3778d7e6234c6af79b898cbfc2f2787244708d2fe203be786edbdc4c9b12b413156b7b0bab0be8af895d191d853cd58aafe1ccce b493d6b2f1226b6ef5a4dbfcce01e788c656ee2268b354e1a1ee1a71945661e8203b1f18a7ca7677d6f3ec30b16b4c2c +00 018bd74698bac36ef11add6b3e3fad227ecd868f370ec04569462565d2f0af2340bf793486953a7b79ab04f0ab1f0e4fd16bf6b576cce677d543e73aa8edb0e50372f24ddfbff966 a8b4f6a8469c099aa24bec4b98d82b85d5aa65272a31545054371b63a368d85596b6258c5b26af572f2bdad767f36e61 +00 0335699bfd058ee2e6163f55d1816bf3669acea8b73be9c4ddfe775230925e6093cff7a66813adf22222c8376faa106d85ac9f3c67929bc58d8986795b6d35d5b9fa546dceabbedc 8a2b15bc0deb0241b196dc01c19a877a40adfee94ff423da505ef27c70928c6893e3643f67162ddffc9e067fec680076 +00 02c3eaf801330b3f1b0504f2399f1d24455db29911f750c246ba0a134c3b59da8b3562911197764699a92ea1d95a2aac587e24f743df1dad3e1cf7edf955203e24a0225717f8d2df b5b118755dc046b44386cb2597094114203a005dc5472b919bc95a9593670099ac7f42982f76ef08bbaf5d83c79978f9 +00 01c3ff067497e5d387f31f0ecc9c67b3c0dd6ec8c81318c492aad83c9dec6c99e4fa47447f6f7082d636c2591d0df940b947d0a4ae3778e2b7cc8fb92214638399def894ada276b8 876d603e6e35e5920e998d5262a536662a691bf11247bf82eb7bbeb82a520c4dd3941c9820d4f642ad8c4016969add5d +00 004b4e04281b210fe78d516a5b69f878b7fa058941ee9ae8cc63b061d1eb9e12c3e0ecb8717ff4623ff5bbbcdb53c48adbd9c69636506ab929c5507d7ebafae5654aad65a263e48d 934d8d8cb62546748412bef3252cfe319cd09ed564dbe30432376edce4a2640729c3ecfb1603e3e5246d2ab3329014f1 +00 030f2849a713aeac95fde5ce3af853e9d070ee60709eccf35a076567be2c43f0fa34420b0fc097ff577221275a3a56e759efc32183be2d76058a7d20e5dd59f00415114d73a15b8f b039264f8b13f8a342e5020e7bde1fd4d46508053e9d150a3889f2e7b9af011abf0d28856bf5135842af3536798fb000 +00 02ebb73d04e6e5361e20629e3ad119b33db5163ed91fd9a8aec4b774898784b6822a08992118a8fe6013094bad0be1e9bf01b27c069e4335bff7e0abd28a10443818f6b825e9cef1 b831fac202972d387edb757287aa641487e7597f934a44a5b9fb6638c932442d5d4711b62e8dfab19069d564b43676ef +00 01bfab717d6f6e16d9bc6e89d2ffac7cbe0f808cc8ca2eb515af7ecce5f3b230303775710a21bd25c2cc4566bb53c78c78e3774a9f306c751cc6e149929e45eef60f56c1d2388c6d b67f3f5a461faae29a27c1ccb6ab08b65db2b92393fc46f32562f3f54ae6b734650fbad83dc9e244591cb9f2a44c0553 +00 000cc53bf7f1cad5e3dede4b4f4b082831604c92dd2b147869cdf1107259305b1d50359647f9f3d7d4e1e608865c65dc7c9ea46bc324dcb8423b554dc369d621743cbfb592b70eb5 872fb0075de0c89e3634af691e2a06e771d58d52023d813ca2cf154bb43717d72404135892cfa51c24055a7e48f4caa3 +00 02b009530cb9d586e35dd8951ccb686833afb7a37ec253e547e85b253ba999f0f186b6d4ba41091615fe57678e9801b4dc94fa683511da25637b2acc9fe60936be15af16234c4ee7 8ab879321958f943e7f2a779ef6a65c2c343570372588bc8d237f29c56e61bfa760e574f7ae19a88c920cebe49c247fe +00 02cc2d0d7189cc8fb3565a039aee7633ddc00ff427cafad32fd2010b10fe249c9724d91785e7080203626038109158e3a61a3970aa3e51688aa7f5184b22f63af63f80d3540ec023 a32330696038abcd584dd67f7d39cce871b2cd33a8193e1fb7d6fb8bc4420632213f6db31165facd8249e8a9af882f99 +00 03d8936c00c131e38c6566d2464c4e207c878070bbf681695a6cd98cab2c6e80fe98cda80c66a5cf584e90a071144dda59c07b8fc7bb42464dbee5b6f739b0f2ee5fdff7e5a4e7cf 903b6a37ba12b5949228b2e68c85fae5fe0d9c2f7a91c50245d4bdad3d4dd57ca296bb86ea9a3ea8d2849c92fad329c0 +00 03dc7de970bce28a943d7599f2a9010fc99435b93bc4ba884d42503ac2941aa63fd07db34bcbb1127d56d6a4e277d6ca32051ea3467e376f74f98c3999d2f276b282ef8a28cf0cbc a4bfd1bb6e55b437a40e44e937b1f2cf707eed91fc3375f9445a2b6f0260e02ba5f660046fbcf5f125d8a47fbe3cf784 +00 02de6ee12eefa7a4a736484b19b42a513dfc059a060976edc3b0aa4b50e98d72df6506fed0499ff8480986748e938289e54a5e86c0c29733a9bcf5985aa63d8a2b57933a04a8e8e0 a5292ab2a93828b5e3e2133a0144a4f1ec8e68ad430c2cfb4a7ef1b41e28f769a3eb57b0d4fcbf21ad99147f8a14e880 +00 005468f0df2c9854f5f655743e79c750fd8812db28b096d97207bae7f5aafc6b6090c9c636ead9e0fde32a1ff8d539b53813733ca812b41b58ff85a941abe4f128d59fdf9847baa4 916d8deee2199cae61f10f674e87439189482a329cebced542577fa49b5e63832dd0aaa2bcc2bf10122768d5c31f9147 +00 03d3c6a7ab9450c94aa3b8a1ffb678e5b647af24cbfd66ee3944e6f264f406295b803767471fc67936fdfed1714b4b8761a07eec86543b7c4da6bd2fcb33fa8cda4077737f398e18 85798772637e98209caeea37e2156801059bb6e793f25c4fcd83d998662f4e780553f2cf74269b8cfe45c414a4a4af38 +00 001ce010ea8e6e1a0c26ab22eb90f0700dc73b232c429d36371e68e429792afb7223f10327708bcff779ea55fb5f22ad87aa054e84d10f5450f1bc9a89279062ea2173f55ab0f76c 96126c11e5534f6d5578b095548b999f4d24bf1a5d0659753903358629011439d252e94696b89ae97d3d14aaf7357961 +00 01e7410d012aeef02b3723346d24ebafd684c99087ecccaea1cf3735d52c4c81dda41812c09f1e874dc964d858ca240a19963d5dc89451f5dd6764426ae41cb23f19cbfdca0fc562 abd92fae526fee34317be59ba5a105fcc42245b936e08ca62c6372094bf16925c91c28d7a8978379e375818b31e2b807 +00 02139839ce38eb879d266065dde5e5ea227244323b330e3ad5a0bc690f3c210f794cf18f0d730693887548bfbc434f48ee10ed34cb41d52172b06e448df938170a5e17311cab8e88 88927682a34c21dee57d53aae966b4197a92819ef29e518c0474e3467a047db537684694ca10034dab775313a6bcab21 +00 0274f70fe69e4dbb55c5d404e39f5196335047113087f8711f2f67f2be4964e4fbcb865680758df1c401cd677b0971654b7a6aeb7bee0d6d80ac0de14d4f46f356b2d5545c185aa6 aac5dd8662593831079e0de92ce7f71a9aee7e0aae161aef3005eceab5f1d03f4803b8a9bfcf49349af76951559fb749 +00 003e1b03ffca4399d5b439fac8f87a5cb06930f00d304193d7daf83d5947d0c1e293f74aef8e56849f16147133c37a6b3d1b1883e5d61d6b871ea036c5291d9a74541f28878cb986 8d872816e5cd2d9bce11add2fc740b8cb20894b2ad7130ff43fd5f39954bfedad1bfbcac0d57897a158d57aacc1da7a6 +00 02e09ffd8b434bb7f67d1d3ccf482164f1653c6e4ec64dec2517aa21b7a93b2b21ea1eebb54734882f29303e489f02e3b741a87287e2dcdf3858eb6d2ec668f8b5b26f442ce513a2 a756b3041c13701b3a2d1b4bdc7dcf796e7b2f20d2eb085a7f1ea8d1678acf99dcfcd87ce8b74383da39d594a350722f +00 02a69bc1df069c6e89722521a63675f318252be629e7558f3716917998e660ac960b0b750562846fe6c12ef492951e51e224754bab84a6eacd4147a5f26ae85ee4381bb14ec2a8c7 acbf2b026e18cdb739a7c61830d996232920beb66f636320fa5b87cc76ae09312aee8e7e2f0bb7d47b7280dde61d1e53 +00 00d11ed1b78b22b3420df4ddc4acc7c2286d9569dd6dd88e0fa3ecae69bcced68bb81bbb4ca6e9b54e67856e7fdf39155aa27aecb9cc827ccb9cdcf9ac633561b27d8eebfc261aee 8f82765cb80d36397947cdf5b5d8cbe4da19fd598732ad3e09478f7289de352b9d57c9738ca53b6c57359ae1a82278c6 +00 02c36ef754b5bd065e9eadde684750acc52795be80f54dd3d7a7d743d968a18f7e404bd71f8a76eb0395f396df5a7c2ff7e0ab6de35df34282fda6ee01fe5b9b68ecb4e378dbe32e 90ca0afb04f5c7681f4126830dae9e73ae7ad9b7db079214ea3dbd7b2e4b7a4afe1b6b893512e670d728e0221922f5d3 +00 019ffee50be5496507e3ef5c40ee88a49625e46d1dd1686a52b09ad4a8e3ee9ef364f953bfcd97c52104eecb6138067192997cd4ebadaccb73c7b2560879289a46353a756b73cc43 8bc9e7c60eed22ecfdc6217889835716ff90caffb218828433926cbb3d8c28e72ccb9d8cc4293930d95fc24d1830d08a +00 03129e96fd28c4198cc5242c1e3531a3979fae643d527044e98d7721aa56b5b4b45dfddfa17a4115e10a2b4f46d92f81cbdd7e86e588a4c6d8c2b3a83f54cebcee1d1dd33e85d81a 89aef840fd0eeee015e582beff8b7c314836d5fe8d8cbf3f108dea9d275f4dd15fc6672f6acd8c9575a14cb577073a00 +00 03d723d2697cd07dd8444f992f2ab4a063db334034c25ea9be99fd7a1f495e3a644e5ea033a41264e0d24a911e55741d0cab80a0bd678eaec2bd1e60424d4491eb86d664900d907e 9518bdc2f309221cf36c6c36a7fefe42b39b0021e723839bb235bb852634a06c138f356bb031dbeedad6fed9d004c3f5 +00 01999ab45d66cd1d3a0fe6aa43bf5ef1e2a67637d53674f6fbbfb9b582be91fc42a12cdcad94b50b0fc7ac55030de24a0b99fbc4314fa743ef4b5198bcc5f54d8b669fbed78e2e91 a245c43509cdf71b7b4765b892a6b41b6af6c9affa143f3abeea78b7d2368a221e78a99376667e41967852f9646a6c4a +00 02ce1cae0716205330d730e6bc6dbfb6b951dc83ee3b4a7dae75d057e32e8a46e22be75b5f09135452b29c34dfe81a9be2e8dcd243fbd946a0ed14a832a7802e20cfe1abfd3d6e4b 8796eb16599984477e4976f6537fad94231b50a1e051c5702e3857838a3caf8a0aa14358198dd967883ebc94694ccfdf +00 02c9d0fcfcee7e75c3245ba955ae04188b1033c55ec9c821d8de7685276bda3e9a93c3ae1b003e5ea722913e7b169d67b1aa2dc8cd42adbd9368672a3f81a6817bf3e5529dcb0c8b a9d37d2339b0825480b8947c5af4d19787695dd8ea43c9170de4f64bf76688f19487bdfd440ae24a7b1ac00a3ae688ac +00 010c057bbaa44ef0f565edc288bfe66d4f6acd8686899359bca418ba89fb690429489a37bd3c6c9f3a8714b2ca225868c6a45fee360e378a676f7ea39321790f32a4b005b81dce43 99bd9e793c49ae778019a72f28d78ef6fb57ad57b4dd3b7058447dbee34fb3a259b748f08b037d38e054ff111e6f9c7b +00 02c182df7976ea93d996f3ba5d2221f3cb755cc7847bc3fe9e022fa4285046f5bfb426bafa3580beea206de36f87593ae561b4b74a03fcd61fbd0e8d6fd5668f2148819a88a650aa b670fb1139ec5b207f33372865884477d2bfabe565dca7dae345a00ab460d1aa57da7c8e54be1c71aef2c15156421bd5 +00 02d3a65bbe133cc98cf0eb56ee1362195968b4eab960a1d55d8b762f1361fc21348d6f275d4bea1de7158fb97c995e20b92a9c887a3e332d154667ad167acc632eb88a0ead6113a2 93c5d0510c294dad72d1a3bb897894a5ba58ef2099a0475d7837d163362961357cfadf67cdb413926111dae6588e93e2 +00 02a920e8dc928acdd56e3655b2340d4371c793e66f67405fb7a90f31e9c4ef466cc44331d1d2fe3ff7391d2576dc6640772166ef8c154a5ff1808f5dab2f03061070ec8b3f786c36 b14f1654e1430bad4f4ab1f51ece5d28c5efc759172d14d4aedc50fc9cc0b4978f488a512bb5112f88627a187f24679d diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K233 b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K233 new file mode 100644 index 000000000000..fe3653da4353 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K233 @@ -0,0 +1,60 @@ +00 004c1d414696cc3657dd9df73ace56eda2636769ce7082e064c260be45a5 a2c2ce174315343da9a08aa4b2e8d8592adb9952fbd7342cda2e477b618c761e7ff2fa56e01af3e1775ea8f84e7bf6fe +00 0027cb1d84865a16992476c9e353283d5d6a40c349a8e9179d1b1f403531 acb75ff306790568b9aed3ba11a1d49e1be2a99ba19cd5f5f5b905dac354079c1b2670838ac8e412eb0b6832bb1ff67a +00 0031b443f46c4b5224237fac1022ee1570173f664aba0c84dbaa4246bdc1 b66e4a7aedc30c33173f13cf2968dc2d35e9ed5839d05ca44b25fe81ef073eed9bec54929275e3c41b77ced5c4eea02d +00 0048f6ca29f35f253a4962734357c995920967b9eeff1ba5fd2080bfede5 9628a09ff0485c7f070700e57b571b6913975b299e648d297a85dece95e30be0d56e99bcb9cb9fa34250ff254ec7b305 +00 0019b940eabbe682f961d9f3d90432e347fef3910e641656825d775705b1 88abd0bff843d5199625a5f6549670b55ed5dca76f456b710a8d0d0a5f68152398b11bab165e3efaf2b2deb1cb553713 +00 007a884b22e29fa9fe945e9ba13c0df8d786dc87cef0f77f069e182dd56c 85dccf115f55b4a6ba743e9e5307255bcf89b00f183acf867719d915e879c3c850aba0f33801f9c2568dd8c389a065a9 +00 005da61f881d5a0dc085bb93764f584352882923cd237d878220ec624c1a a361452528307acd042dc2b4f09d9a17a476152992b6a3cf6266e69f3ae694c268e5eb5bfba2511d6782ffcde9c2cb0b +00 003fe9f04647f6d82b13ec1ae5a8c2e49bc66b05649ad778eb16149ad83a 8f3cea1f94fd2e021b4f7cc40f4b2f6cf7376e008542435527ee95017a555dfc4fcd5431a1caa620bea9e85be84affeb +00 005ebce648ace4cd555413de6a456fc487d14bf4b0b9a72311ef480d2f26 8406966489eafdce4a693296a455eac790f4acec8fdfd3c224ac93751cb2525c17e3f6e25a1a42b4992ea73ab3249823 +00 0056653c2f85593f789a926ba49fa3da9d7f946d8f1020508c5a527ce813 8eb5416609af9109c7ac1a2c9e394909ed5a9bb092c9a81d09ff66605fc8a82e83c1a471c19fc55791635d5a251b2e1c +00 0049a91d320783cc70a5952c32036cfc75d41f1aa84127db2dc759fb291c a8e0fa9ba57303626a9763fc11c1826110a3e4b1bc492a84110036ae124c4354cdc8a092e8d82e76ea561cf91f8ada4f +00 0016a20016602fc7088a60469843e1d29ad67e3c3cb9500b1e2a00d4050a af68de9801f4cf14b2bff44b63b8032680a6ee8f517ce8cd665794359bd75366faac5433fc6cdd9be3f27ae10887eaef +00 000ba922149bada2551b7be1c3df076f3f97ce93c13c50c285fef3f42363 9555ce312169d572d8178a69ae942e1e00ccb1dea31cbc475ad49810e079a5e284873494e129b7fc366386e6fedacb32 +00 002d635e12a58cc6dea44e71e87c37f91e8d08659f0b7955d24f65ab55ba b8a0969c0ec1b2a660d178a80c50c3fbd922b9c0df4e622ec4c5246fa3b78727c0828b04940001403f6653482a9aeca4 +00 00073883e5064e06814fc4de32e15f7a6cf825d2daf6eb1df8c83e25d80a a7a559a3197ff8197fbb5d847ddbd96e29b602dc499d4184aece39f05866c05899d501a163a25dc8ecd3549a4da045e0 +00 001532271bfae8d4dfe60f69b88d3006d58e28aacfa701861cde8d624db6 9137cb797ff1b022a03e0c1a5c985b02fa9c1e90f4fe6f38875e66ea0514ad85be1649449ba30c8d34238473725dd512 +00 00550406c0db882c6aee6cf3b6baf377375208c3e90cc44a067cee43efcf 9753ab48fed10b038ae93e2cf3931f19b100b416d4c47fae3b310e5da233659dce72f3131d61ac096b0e9bce14480b1a +00 00257dc63752920b6854d6c2d1cca68589a38418c3d036e73760a12214ab 819982050e824e49ec64ff8671f6b9571a82f389b43c98b98e704496c2ca59f5d0563be9c047447ae0ddccdde40eff68 +00 0029025352297a7be850f8852411c09259b83219135e0e8949c1bd5b94c1 9175198e95f6221e4dfec45215dc19cec422d6d95f471b68297de69f5e45bd9c68f414442ee35c99b6928802999c6928 +00 002dc82d0e69e498528925c0e62a13fda9af8cefd047c10c3ffc2e41da3e b680d8d6d3810d0687f8b083d5b2dc9ee0782329508c0d494ad5e848a346b7c6edced8f16b549de40e4bb0de961ea25b +00 0041535fff5d279bcd744b04e643458ce20b81df8a9e01b1181d52bb14e4 8f4eeb9a39212958748ed6577754a49ecbc331bd62c0370cfa48236b71879307e5713feb2224dc50be451ecbed1fce42 +00 0000ecfe580a624df66c25e87e7689fc3b471d205970ff9ab51a64aa12ed ae25c990243ad8100d9826704546f395a5c9de853803777973887a08529a7257284f94f379395978230aa6287b5f6d6d +00 0013c72c73358ffa168423149ecdd897f0a5f75a641de008649f00134944 b0544d51187e3de05b75dab730b00f0b7a1c46367db1326e1be1f9a0324b289fe8336942fd2e5832bc09dd4c941f027c +00 000ac60e2e70b7c4cda64071c7738f68773c94df9456a8ec3bbb468fa7f8 b3ecaf4b0c442db4988f5fc50696b7429c9d137fe6af22f0b93704bfd73efb68a60bf7e8a39e5f5acf611bbb6d3160c6 +00 0060bf720052e8b9508a801340c213cf53bbecf4975faee63d4b44fc647a a9ffdb95aa81f3af8b463bdc29d0b28282f7825dfe07f65e1427c067e1c60104e5b05021eebab1be03ed85d53ee5dca8 +00 007cf3c216592febd8630a478b5b3e3a605084020322adb13ac0a626bc7b afa515be8b0c1c6db6d7ac1f087e9da020f0cddc4f167326285c4c9d17d8d646ef34e83ef21ce54e39ea2951de6093a5 +00 0061eda5999e5a9ed4485d2a0ac5510549b76ca37df858ea5d95aeed571b 934aeb9d12f0ecda7823f7daca3754a43a7328e80da5280f7f64ca21c5b3847384e108bb08fdec0f3ee0c234ddb4cba8 +00 007e7e73171e4d2f2989dc024757c186485435b82544a448f5cfca05f281 9515fd5d8b70a25fa49375e15b5996d6f69b0aa8ecaf46354d58155d343343544b2a4a9eb1ba70630766a4212122d8f2 +00 005f7270764a0444c7159d2db867930fdb0fb9fa6b8fc80ca02e11753095 ac02a6b501115ac3b6669ce7a0332849a71b176dbfcfd98e5c2b1da6c9242dfefe723df4fdbf607b6c09b3cc48898365 +00 00179b924afa4acf30ecbe2b3c12de533a1f9675687876a7e5e5ddc8e03b b8d7fddfdfe3b5c8dd64aacf296567e6b03d99bad0deb176f1578d338964305b92c42381ec33b49d0523899375880d2b +00 002c9eb4d392d7f2eef606e1861183acb1fc753d666225f0f154d9eda147 a046a181dec447dc577f6705149f607f97501d3ccc94ff0219fb8251ac43198878a20bb035ff19dc8cea6cd74afc7f61 +00 0024661c89b77b2c743cc175a6130904461138ddc4ef771ffb9fc2c8679a 82b5cdf93ee5b81da4a99f7ee72bc0a2a4ce8109482c27af4de54d4df1d47a0dd6cdfe3b8bb7dddc8dd7ab8cef8e58fb +00 00065e20e5ce534576d7c17616cd4ede3bf4f500894850723bcc9f895f4b 8d6c1fbe76c5497a745d008eb2efec071c05e9c22969c3e22855d77470fe7c42cb7142c86405e214b702471603acbd7a +00 0014c85f66fbbd653f1e4e590cffe62c343ba6062df4b271fbd02e5d42f7 8ca76fd6a819923c7148af2a20b7e8c3cd50cdef7a7a0e8ed7bfc861c976d749c536ced7ef1f8ac09c631bea412680dd +00 0030ac7a78593b570b29f6d3d267abb6ba7e5870ee1c8ee4f1ab2f141051 83475ea7eb26f2977e57710563511d06cb0e02145ea65b43257d78a60f71cb189d95dd01d4896a6f1855df17c990edcf +00 006d7516aa040f7d559cae248e485834e8d9bb608279ed4d4f7e1dbcd2b3 8f717a45900f5029741f3371c3f499fd71da1bf191c9102e81e8b951275ffe669603bfdf1df47db1a51f3e0fa3f3a4a6 +00 00137050d7b455f43a8dc2516cfff5a91062c1a2727b27df41488f3dcf18 960a3f9f31c14adeabf1a4d224325f6c6bf0f9eec9203d75d28d476bfffcbe635cea98a6dc1d878b99d043faafae81a5 +00 0001fd447b33a2ee3595b9f885c290d241422afdd74c3dc4981955a7e9ad b8aa0f875fe3e9e0e9e6cc4860f1cfd094aeecbab553aeb566832611d604b35c41938b8b4abbc8139fbc2aebd233b1e2 +00 006a061e10b4a6e7001d95411cb31bdea9c84670a59ed61b14fbbb05c8e7 84f367bf140526bc21cae2cc77e869a6e38c1bcbb829d99d7efa574a5a7d28b8f29fd86d585617c6d015dfc93df9506b +00 0027ec31ca31acb4d2fbacb49fc085f1261b0042cc755cc97f9b199e7a37 9494d80fa7da14c54907807f4e535840d85aadec0ac63a0d8a79ddd86ad3bd65ebbd8c74c023835d4ca508e1258e5843 +00 004c6f4d88e5a4f4f83196f2dda9dcf2a66eaf94d50c851f59bfcea1d876 ae9f69941d5db5608fa1542e1809ae6b4b7428bfc2031ffbe249c61b392997a12b4da74c205d7f2d4e0954373af42cec +00 001aa169ea84365c22981bb766bfdad27e373440850569957544b0f9332a 8f514991218d5356adca42d223866a210d7126e6c98a47ca0781441c665de6966b29e689e83b6836f3367b9ef1cf12f9 +00 004a665b92c0c33a3f8b9eb4b0ec061d40b603de36c87096455102ffe57b b5730aad77c00edf06c618726770b43fa53470b0853c4b416e99e34a47e3fb71bd8a5683c60a2152b24f217db7bd28a9 +00 000531540d94823e19ab2b95cbc6e7492e1effcbabce875de6ba96f53aa9 b977be2eed4c2119bdfacdb648586f1c9a753cf2d3022a8adfd5797fd726f54a98aaaa6d7f2f84d9fbd7a3c37d80939a +00 0022a89addd8b85809e87e0aa2c038593ec277054842854de1197833a51c 8bdc06f45b93bc70e93acc4d0ad3b181bca1feb7b25f3169a6825bbc24229b1cc347545d23284628461db5bcb93e2ed3 +00 001df252a11ff97b4421b3a2361db94e908e8243cd50d9179f9e03e331f1 9613d994d9e34c3818fdac72b93f6e33fc1909442d3c24b608cb2f914e5bb8478943afb12dc4c301feb4ecd037c8e531 +00 001d7125c299ebd0dbcc050f07de931c7ad0450af590d0a2d0228a66ac5d 8863081937ce0fc0f4f171c0eebb7be42d6a7c58ae2cde25e05ad4587dcce10f05b3d328fe1a43ee1e104adc62ca14a3 +00 0021238e66119844b146d40e48341f522f6ac2f9c8a0b33aaf95a3099a41 8e5ab48ad9726933a09b9ef59f7a198d90c632b6ddd727794fb86f103226d046ca1ec665f3b5539b42bcdb5e78addbc2 +00 0015e1bdfdacd87c42ed439f3e243abf27fd42e54f3ebdfb47f60dbae5fe 8085ab37fd82b1d9e59443442e294a4b7b2f6ba173495258955535639939a982b283b855343865d5b156ac0f54297413 +00 000e09410548c17bbbf28a68c3963a52d39743a4f1ac28e6dfe7a6ede281 8dd19d3cf8b72c6634357b00f3467420964b61fbc7d15866e15b63eaf3e249658903b53edf29e536506f45b02ed4df0f +00 0049f5bea6e72d98579b78cb07d89f64503f8759dd7a73cd73713c120428 8e3585100e752ef69410e5e3815c06d41f380fb4996dac587746d5881c69c4be95f7d3cc2b606394b5c348ea4898ec38 +00 0005eaa818690d1ca4838f0bc667be5721d178c3869884260fb230277c3b ad523f57c95ebf77b36b40a6975245e394d623699e7ea68c6a4fece810a15444967cb8cd050899bd056e70e3ade98217 +00 00603d89cd2f741d734587e77554fe6bbb1e5739d5ff73084d4de8ed69c4 92ca66bb2af6d5ab3b30850b514384e268257e37e69bcfba07209880da645d3c35dac9fa878a9423f7cd02346088630d +00 007977b3aba53616dac27b4d74930da23966a88ad98f1769674789c0be3d b9225727d21f3cb60590bc74a1ae4c62c7a4c7ea66d747a36a4ae628b43284d279b324007bdc59248c49e87d80d5b50a +00 0050cd20e7eabd29008cc977d0a17e1195d79587b8f15ac2447e15daafc0 937ea053078fa827e66244612c5b6463e0aac8bb2c91a317844c4f9c4278b1067da7605348150b3f6410033803f0d21a +00 002dbb24fcaf9f3cd5d50d209937f0e2d134fa20ee3c9c2f1fff3dfbf302 877c1fbf035fddf866c0d3bb801f7e5d5523ecdbb64b704d29e313970907e10653438d0ac7038dfa337dd7b701df95f7 +00 00047142197d3d43fa46545b547968680ec81688589d1ec8d7c7e90eb969 b27d000204059f05a51973aef74a5855dde66a065bdc43e4f6f29061d9adf003219a28422baff80b416a42196388a8d2 +00 0031352b49ecde5434aac05f898e6ce4337304845d748f114c14319fe97f 87cc61be732e5a3d8f84726efd1eb53a402a159845a18372633c8b2752dca89f2b28025386c4c677c793e539372725c2 +00 00176f124c24e4420f6e726a6ca25f09dfa0c5a37e5bf879e7bdd36c3b65 89069edb8d7a239bb01d63c08d14ca482a7285e062f182c207f8271a069466305ccde29321be3e6dbb4452f3d4e79fe2 +00 00755c48c3dbaf71042c58cb137f3632e3cf9d90b7b9a58fd378feef3d19 8d66844bfa4261e89bf648e9ed29a9bb6f5db87dd58fe6e9ae2018de8ae0287897a3e319ea8a5a9a804018f0c7ee6c1c diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K233_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K233_blst new file mode 100644 index 000000000000..fe3653da4353 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K233_blst @@ -0,0 +1,60 @@ +00 004c1d414696cc3657dd9df73ace56eda2636769ce7082e064c260be45a5 a2c2ce174315343da9a08aa4b2e8d8592adb9952fbd7342cda2e477b618c761e7ff2fa56e01af3e1775ea8f84e7bf6fe +00 0027cb1d84865a16992476c9e353283d5d6a40c349a8e9179d1b1f403531 acb75ff306790568b9aed3ba11a1d49e1be2a99ba19cd5f5f5b905dac354079c1b2670838ac8e412eb0b6832bb1ff67a +00 0031b443f46c4b5224237fac1022ee1570173f664aba0c84dbaa4246bdc1 b66e4a7aedc30c33173f13cf2968dc2d35e9ed5839d05ca44b25fe81ef073eed9bec54929275e3c41b77ced5c4eea02d +00 0048f6ca29f35f253a4962734357c995920967b9eeff1ba5fd2080bfede5 9628a09ff0485c7f070700e57b571b6913975b299e648d297a85dece95e30be0d56e99bcb9cb9fa34250ff254ec7b305 +00 0019b940eabbe682f961d9f3d90432e347fef3910e641656825d775705b1 88abd0bff843d5199625a5f6549670b55ed5dca76f456b710a8d0d0a5f68152398b11bab165e3efaf2b2deb1cb553713 +00 007a884b22e29fa9fe945e9ba13c0df8d786dc87cef0f77f069e182dd56c 85dccf115f55b4a6ba743e9e5307255bcf89b00f183acf867719d915e879c3c850aba0f33801f9c2568dd8c389a065a9 +00 005da61f881d5a0dc085bb93764f584352882923cd237d878220ec624c1a a361452528307acd042dc2b4f09d9a17a476152992b6a3cf6266e69f3ae694c268e5eb5bfba2511d6782ffcde9c2cb0b +00 003fe9f04647f6d82b13ec1ae5a8c2e49bc66b05649ad778eb16149ad83a 8f3cea1f94fd2e021b4f7cc40f4b2f6cf7376e008542435527ee95017a555dfc4fcd5431a1caa620bea9e85be84affeb +00 005ebce648ace4cd555413de6a456fc487d14bf4b0b9a72311ef480d2f26 8406966489eafdce4a693296a455eac790f4acec8fdfd3c224ac93751cb2525c17e3f6e25a1a42b4992ea73ab3249823 +00 0056653c2f85593f789a926ba49fa3da9d7f946d8f1020508c5a527ce813 8eb5416609af9109c7ac1a2c9e394909ed5a9bb092c9a81d09ff66605fc8a82e83c1a471c19fc55791635d5a251b2e1c +00 0049a91d320783cc70a5952c32036cfc75d41f1aa84127db2dc759fb291c a8e0fa9ba57303626a9763fc11c1826110a3e4b1bc492a84110036ae124c4354cdc8a092e8d82e76ea561cf91f8ada4f +00 0016a20016602fc7088a60469843e1d29ad67e3c3cb9500b1e2a00d4050a af68de9801f4cf14b2bff44b63b8032680a6ee8f517ce8cd665794359bd75366faac5433fc6cdd9be3f27ae10887eaef +00 000ba922149bada2551b7be1c3df076f3f97ce93c13c50c285fef3f42363 9555ce312169d572d8178a69ae942e1e00ccb1dea31cbc475ad49810e079a5e284873494e129b7fc366386e6fedacb32 +00 002d635e12a58cc6dea44e71e87c37f91e8d08659f0b7955d24f65ab55ba b8a0969c0ec1b2a660d178a80c50c3fbd922b9c0df4e622ec4c5246fa3b78727c0828b04940001403f6653482a9aeca4 +00 00073883e5064e06814fc4de32e15f7a6cf825d2daf6eb1df8c83e25d80a a7a559a3197ff8197fbb5d847ddbd96e29b602dc499d4184aece39f05866c05899d501a163a25dc8ecd3549a4da045e0 +00 001532271bfae8d4dfe60f69b88d3006d58e28aacfa701861cde8d624db6 9137cb797ff1b022a03e0c1a5c985b02fa9c1e90f4fe6f38875e66ea0514ad85be1649449ba30c8d34238473725dd512 +00 00550406c0db882c6aee6cf3b6baf377375208c3e90cc44a067cee43efcf 9753ab48fed10b038ae93e2cf3931f19b100b416d4c47fae3b310e5da233659dce72f3131d61ac096b0e9bce14480b1a +00 00257dc63752920b6854d6c2d1cca68589a38418c3d036e73760a12214ab 819982050e824e49ec64ff8671f6b9571a82f389b43c98b98e704496c2ca59f5d0563be9c047447ae0ddccdde40eff68 +00 0029025352297a7be850f8852411c09259b83219135e0e8949c1bd5b94c1 9175198e95f6221e4dfec45215dc19cec422d6d95f471b68297de69f5e45bd9c68f414442ee35c99b6928802999c6928 +00 002dc82d0e69e498528925c0e62a13fda9af8cefd047c10c3ffc2e41da3e b680d8d6d3810d0687f8b083d5b2dc9ee0782329508c0d494ad5e848a346b7c6edced8f16b549de40e4bb0de961ea25b +00 0041535fff5d279bcd744b04e643458ce20b81df8a9e01b1181d52bb14e4 8f4eeb9a39212958748ed6577754a49ecbc331bd62c0370cfa48236b71879307e5713feb2224dc50be451ecbed1fce42 +00 0000ecfe580a624df66c25e87e7689fc3b471d205970ff9ab51a64aa12ed ae25c990243ad8100d9826704546f395a5c9de853803777973887a08529a7257284f94f379395978230aa6287b5f6d6d +00 0013c72c73358ffa168423149ecdd897f0a5f75a641de008649f00134944 b0544d51187e3de05b75dab730b00f0b7a1c46367db1326e1be1f9a0324b289fe8336942fd2e5832bc09dd4c941f027c +00 000ac60e2e70b7c4cda64071c7738f68773c94df9456a8ec3bbb468fa7f8 b3ecaf4b0c442db4988f5fc50696b7429c9d137fe6af22f0b93704bfd73efb68a60bf7e8a39e5f5acf611bbb6d3160c6 +00 0060bf720052e8b9508a801340c213cf53bbecf4975faee63d4b44fc647a a9ffdb95aa81f3af8b463bdc29d0b28282f7825dfe07f65e1427c067e1c60104e5b05021eebab1be03ed85d53ee5dca8 +00 007cf3c216592febd8630a478b5b3e3a605084020322adb13ac0a626bc7b afa515be8b0c1c6db6d7ac1f087e9da020f0cddc4f167326285c4c9d17d8d646ef34e83ef21ce54e39ea2951de6093a5 +00 0061eda5999e5a9ed4485d2a0ac5510549b76ca37df858ea5d95aeed571b 934aeb9d12f0ecda7823f7daca3754a43a7328e80da5280f7f64ca21c5b3847384e108bb08fdec0f3ee0c234ddb4cba8 +00 007e7e73171e4d2f2989dc024757c186485435b82544a448f5cfca05f281 9515fd5d8b70a25fa49375e15b5996d6f69b0aa8ecaf46354d58155d343343544b2a4a9eb1ba70630766a4212122d8f2 +00 005f7270764a0444c7159d2db867930fdb0fb9fa6b8fc80ca02e11753095 ac02a6b501115ac3b6669ce7a0332849a71b176dbfcfd98e5c2b1da6c9242dfefe723df4fdbf607b6c09b3cc48898365 +00 00179b924afa4acf30ecbe2b3c12de533a1f9675687876a7e5e5ddc8e03b b8d7fddfdfe3b5c8dd64aacf296567e6b03d99bad0deb176f1578d338964305b92c42381ec33b49d0523899375880d2b +00 002c9eb4d392d7f2eef606e1861183acb1fc753d666225f0f154d9eda147 a046a181dec447dc577f6705149f607f97501d3ccc94ff0219fb8251ac43198878a20bb035ff19dc8cea6cd74afc7f61 +00 0024661c89b77b2c743cc175a6130904461138ddc4ef771ffb9fc2c8679a 82b5cdf93ee5b81da4a99f7ee72bc0a2a4ce8109482c27af4de54d4df1d47a0dd6cdfe3b8bb7dddc8dd7ab8cef8e58fb +00 00065e20e5ce534576d7c17616cd4ede3bf4f500894850723bcc9f895f4b 8d6c1fbe76c5497a745d008eb2efec071c05e9c22969c3e22855d77470fe7c42cb7142c86405e214b702471603acbd7a +00 0014c85f66fbbd653f1e4e590cffe62c343ba6062df4b271fbd02e5d42f7 8ca76fd6a819923c7148af2a20b7e8c3cd50cdef7a7a0e8ed7bfc861c976d749c536ced7ef1f8ac09c631bea412680dd +00 0030ac7a78593b570b29f6d3d267abb6ba7e5870ee1c8ee4f1ab2f141051 83475ea7eb26f2977e57710563511d06cb0e02145ea65b43257d78a60f71cb189d95dd01d4896a6f1855df17c990edcf +00 006d7516aa040f7d559cae248e485834e8d9bb608279ed4d4f7e1dbcd2b3 8f717a45900f5029741f3371c3f499fd71da1bf191c9102e81e8b951275ffe669603bfdf1df47db1a51f3e0fa3f3a4a6 +00 00137050d7b455f43a8dc2516cfff5a91062c1a2727b27df41488f3dcf18 960a3f9f31c14adeabf1a4d224325f6c6bf0f9eec9203d75d28d476bfffcbe635cea98a6dc1d878b99d043faafae81a5 +00 0001fd447b33a2ee3595b9f885c290d241422afdd74c3dc4981955a7e9ad b8aa0f875fe3e9e0e9e6cc4860f1cfd094aeecbab553aeb566832611d604b35c41938b8b4abbc8139fbc2aebd233b1e2 +00 006a061e10b4a6e7001d95411cb31bdea9c84670a59ed61b14fbbb05c8e7 84f367bf140526bc21cae2cc77e869a6e38c1bcbb829d99d7efa574a5a7d28b8f29fd86d585617c6d015dfc93df9506b +00 0027ec31ca31acb4d2fbacb49fc085f1261b0042cc755cc97f9b199e7a37 9494d80fa7da14c54907807f4e535840d85aadec0ac63a0d8a79ddd86ad3bd65ebbd8c74c023835d4ca508e1258e5843 +00 004c6f4d88e5a4f4f83196f2dda9dcf2a66eaf94d50c851f59bfcea1d876 ae9f69941d5db5608fa1542e1809ae6b4b7428bfc2031ffbe249c61b392997a12b4da74c205d7f2d4e0954373af42cec +00 001aa169ea84365c22981bb766bfdad27e373440850569957544b0f9332a 8f514991218d5356adca42d223866a210d7126e6c98a47ca0781441c665de6966b29e689e83b6836f3367b9ef1cf12f9 +00 004a665b92c0c33a3f8b9eb4b0ec061d40b603de36c87096455102ffe57b b5730aad77c00edf06c618726770b43fa53470b0853c4b416e99e34a47e3fb71bd8a5683c60a2152b24f217db7bd28a9 +00 000531540d94823e19ab2b95cbc6e7492e1effcbabce875de6ba96f53aa9 b977be2eed4c2119bdfacdb648586f1c9a753cf2d3022a8adfd5797fd726f54a98aaaa6d7f2f84d9fbd7a3c37d80939a +00 0022a89addd8b85809e87e0aa2c038593ec277054842854de1197833a51c 8bdc06f45b93bc70e93acc4d0ad3b181bca1feb7b25f3169a6825bbc24229b1cc347545d23284628461db5bcb93e2ed3 +00 001df252a11ff97b4421b3a2361db94e908e8243cd50d9179f9e03e331f1 9613d994d9e34c3818fdac72b93f6e33fc1909442d3c24b608cb2f914e5bb8478943afb12dc4c301feb4ecd037c8e531 +00 001d7125c299ebd0dbcc050f07de931c7ad0450af590d0a2d0228a66ac5d 8863081937ce0fc0f4f171c0eebb7be42d6a7c58ae2cde25e05ad4587dcce10f05b3d328fe1a43ee1e104adc62ca14a3 +00 0021238e66119844b146d40e48341f522f6ac2f9c8a0b33aaf95a3099a41 8e5ab48ad9726933a09b9ef59f7a198d90c632b6ddd727794fb86f103226d046ca1ec665f3b5539b42bcdb5e78addbc2 +00 0015e1bdfdacd87c42ed439f3e243abf27fd42e54f3ebdfb47f60dbae5fe 8085ab37fd82b1d9e59443442e294a4b7b2f6ba173495258955535639939a982b283b855343865d5b156ac0f54297413 +00 000e09410548c17bbbf28a68c3963a52d39743a4f1ac28e6dfe7a6ede281 8dd19d3cf8b72c6634357b00f3467420964b61fbc7d15866e15b63eaf3e249658903b53edf29e536506f45b02ed4df0f +00 0049f5bea6e72d98579b78cb07d89f64503f8759dd7a73cd73713c120428 8e3585100e752ef69410e5e3815c06d41f380fb4996dac587746d5881c69c4be95f7d3cc2b606394b5c348ea4898ec38 +00 0005eaa818690d1ca4838f0bc667be5721d178c3869884260fb230277c3b ad523f57c95ebf77b36b40a6975245e394d623699e7ea68c6a4fece810a15444967cb8cd050899bd056e70e3ade98217 +00 00603d89cd2f741d734587e77554fe6bbb1e5739d5ff73084d4de8ed69c4 92ca66bb2af6d5ab3b30850b514384e268257e37e69bcfba07209880da645d3c35dac9fa878a9423f7cd02346088630d +00 007977b3aba53616dac27b4d74930da23966a88ad98f1769674789c0be3d b9225727d21f3cb60590bc74a1ae4c62c7a4c7ea66d747a36a4ae628b43284d279b324007bdc59248c49e87d80d5b50a +00 0050cd20e7eabd29008cc977d0a17e1195d79587b8f15ac2447e15daafc0 937ea053078fa827e66244612c5b6463e0aac8bb2c91a317844c4f9c4278b1067da7605348150b3f6410033803f0d21a +00 002dbb24fcaf9f3cd5d50d209937f0e2d134fa20ee3c9c2f1fff3dfbf302 877c1fbf035fddf866c0d3bb801f7e5d5523ecdbb64b704d29e313970907e10653438d0ac7038dfa337dd7b701df95f7 +00 00047142197d3d43fa46545b547968680ec81688589d1ec8d7c7e90eb969 b27d000204059f05a51973aef74a5855dde66a065bdc43e4f6f29061d9adf003219a28422baff80b416a42196388a8d2 +00 0031352b49ecde5434aac05f898e6ce4337304845d748f114c14319fe97f 87cc61be732e5a3d8f84726efd1eb53a402a159845a18372633c8b2752dca89f2b28025386c4c677c793e539372725c2 +00 00176f124c24e4420f6e726a6ca25f09dfa0c5a37e5bf879e7bdd36c3b65 89069edb8d7a239bb01d63c08d14ca482a7285e062f182c207f8271a069466305ccde29321be3e6dbb4452f3d4e79fe2 +00 00755c48c3dbaf71042c58cb137f3632e3cf9d90b7b9a58fd378feef3d19 8d66844bfa4261e89bf648e9ed29a9bb6f5db87dd58fe6e9ae2018de8ae0287897a3e319ea8a5a9a804018f0c7ee6c1c diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K283 b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K283 new file mode 100644 index 000000000000..8691a5d69a31 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K283 @@ -0,0 +1,60 @@ +00 01e846c830a8ec04e8572d1a9d2df044ab47352fb346f67403a3bf87243871b164511c53 85e72f0e7a21647efe2fee95aa7e41cebc60022118a35efc577f67fcc28482b9369fdfedfbfdf19de5771ca7053f84bb +00 0101c5ed48231a56ca0ea85eb45de0e395e6df2efd4987a226ae36489dd8b2dfbf7c465c b9b365ccf593c38349d08e88620e987da6b9b5d85df2e65d0e5c2b1404a259f2ab426d3ff71f3cfa8c4de002b9173455 +00 0019679dc589440b11f82b3716e5b2a2bd42c3b1c83e88a28e304cf5148877faf760b4de 89a9b8f7a54644577e1272080b7cbdbbc43f245f004baa8859658f657054624f7c805de9de25f9f2515d7069a9f601e5 +00 01703c21fb1e09f8947e12fddf166fda6f685221fbd803d75a0ae377a54a1e494e6c5e7b 856c49e1b5b0c5b0d71155c262165060fa013fa62550664174c8022de7c87aaa78b67faa2d5ac08d134ed072130b6fc6 +00 0071de8eb14cbfb88e61b908990ce08b81e624ef4f2cd9cdf3dd7ca9097d5ffed9ae9a71 b2ae576b31fbf4f945d8bcf9344da6acd4f6b76f61f79dc6bfe4deb5a36e0ad6f0c2bdb031ea2753da17f3a1a5b9a54f +00 01d156eb15762ed00c4021884adbfc2426e910b18a5bc474268196f4b74e593a8f38702b 8b7b5355e7bada29c32484eaf72a98fac6c8e6c44acba85869fe8bd67c6bd3091df3b7d90c2149c5689b4e9696e05ddd +00 017d6eb1219cab8577168be86b61f372b27ca70fb1f1a767947895c185344e966db17aea ae9387c57a449089b0292e17327b174d21de4944d00a500cacde05422419823095e61c4f687d502c2b4c399c6f12732f +00 010ede9be6615b3b2a294d67da78127ffbf3a15bdba6f4fd78be7a60415b5d1a097c0cff 9760c7a18ba0749b20100062efcf4b981b285e7cc247dac6ed9c6726ee6c70f4c1e7cc7f980edc25db141d59c4560be4 +00 014f237cface123b64e8578ff33f86bfd2a8181b9c81f36b9ca31e2a446f0d91dbbe2249 985eb0f0b91614ec55f801f85921c9a9613313c1df3b34cdb0f455ee6a41cbfcae6bbb5391a2f432c63cb13160ba44dd +00 008dbecb26587cb2ed7df2404e680fcfa5bf8cf6a58e87a350a1600211b3c844ca86daa5 b91b846667508760a11b79e7a97d481e4700e19290aa3f05727dc8e96f245d168e38a6960b0536ae3a85113be5e6ee17 +00 0191badec2d28cbbe62c072c6b57eb5d4644d0c0b3283951bb66096cd15edd43a1bbde53 aae99eb0c226cafc6005c8482ed7e6bae33d6ba4aa228038c31bc8d5d020d7c8777accc358ab0b2e4ddbaefa4684792d +00 00ff5e3d66eb57fd35ba4472effd6e7a016ca461e39000a7125e99080f6ab6ef4380dd7a af14e4c0e0ba7bc93e189a2148899e208f994262c72e69f33449bf92399f5ad0ce16094ef1cb148fab9319ffaaae0902 +00 01f3591eec4a8a3fe6ae6debe230d238a6b73cf3791cb735add1abee64239bb100f15166 b330a2b22fbcedc425351ee2fe965d32293f120ace8d2c7492330440318ff7fb3203612797bd46ac7ab213e36c622959 +00 005af03cdb45961e7ff35fb0146904ddd6c2bfd3cce814073d3aa56eaa9f13b4f7423926 9358a38fd64f74ac2483be68e6c71e63abe5704be44f95f2ea82228a9eed135e58b0aa093863655ebdd84bfd7282ce29 +00 01ec9710ada06e6270720692a06d488ae2ba863b905dd2fc323e7ce68dedacb35fc8c7d8 b5da42a417e0ba4fdd47f358bd4e0f5ea63f6eb04ee49c1c986516d127eda0a4297c520ddd24824f84c7626ad0666ccd +00 00668de088c6913640fbefbe6d2c44ab26e481802dbf957044a4957c3c5d0a0fde331501 903216ef5512900f1bbffcc7a7d6aefba197c5a633c04d718067be07c1bb8d45fe5d1e3ed3c32c9ad0df58c4bbf0b51e +00 00e6af57cf47de1e6f07041eb5e1a413fb7ddd82f8c7f7ce957eb28a118004930bec4dbd 8156336712a5ca1959afa9cddeb94ee6b0d34239f226427daa49788fa85bb94d3a176777a78dd45d4ebbd7816f00c65a +00 019f9b63fde8c6aa6177f2a38981505d04f8ac62bcc21007b05615d028cfe851ab9cbbc6 b8fc23adbf1f7d162d7195c3a36817f4a440246b0d66956a5b9c483cd6ec579cbfd0f376a202d545d469ea61d5935ea4 +00 017704c1f436beb52f7ec97192e23e206ec09f9e8986e06bef71467c192bad6f0066b3c2 a6ac28fb8c905a7aca120c1fe7860f0a76df07db460184300a9a60b0a9965dbdb0078b5c0adcb80bdad16f198e633d22 +00 00c7d1ac8faa689698f5c6325a3b3f35e7730bdbddabd0693f2bfdc5c838bd62f84508d4 9699ad48d333315f7c41cc17443cd7f58f130a6087fe46168ea8f79871278b937d6580185d27db83ca6ec251ef672b9d +00 01a173d158866db0ec665ee632b5fc397893f6a44ee17c348e7452800aadd8ce676e7fdc 89a0a68e3845e82faa7df060ae9fd72034ca4f4d208f5e36608fc7351f7529f1a72e6874223c9e30e2f6343490ddbdc7 +00 005523cfacf4ed3b74ebc30f608292e45173001d80cc801f729c5f71fc213b243f041ad5 97abf74092ac601b9a7c9c0c55ac7073ab9e8e4508903781782f7c7a5f7f4ecbefbe4735468153cb98d745ad65fffce1 +00 009f6bd008c04b8823ccc3ee7d5aca535c211f35e9d9e7cfaec518b98647fbe6d28283de b9cf948cdb8fd2a3601614a62b5c5da2e40de3f8d3cfa8a0b8d2686cdbf426a6c3d74d20828dd5b4ab8f3cadd0b4cc5a +00 0150d2812505c82584201e93f6e0cb875d29dc7bd99d9c0f98e0ed20128886e67e1f1071 90546f584daf15aba4798913339f3e60ec107a496033867323a82031fad36962148b8a667d9297ec0e108840ea6ebedb +00 01b3fb9e1ff70f94bc9d7742ea535ca982215af3df381b5ebdf1db40c7c849a7978ceb98 b08418f7bdf61113a58a2e9bc600ea1c959bd272437099fa226dabcbeed29c05e2565d25f0b569df9cb947a593da9764 +00 0147fa46fccf0805d14c1b84ea59bb8b8283d54ca0ceefb29b5585e7141340c55b7232f7 a95cbb9698a956a72a1a84bbdf079e4306f4011d02f8cbf9b7ce8bdac4b85cd4153e58f5e0fded88cb4344ca5c5313d6 +00 00fae097ea56b35a517be5480802f450eb832b244558d0cc922cd4a5b40b84d02ef11216 b52ce1518bbc597b99cadd761f408759b1bf8d3f5d6d4565b6943329de6000cac643dafafd9b1086c05d5f3647dcbeca +00 0026cd72e6ae19b3f4c53493fba1e8082a8df1fb7da6dc111b47a41f713f49b33f618d0c a60e6007f266e54b992e2e6155a19a314bfe9a71e44d6821a3ff5448e67892220e88fbd7e3100917edc3c8d377cebf5b +00 0198e13c7d95bbbb6e226688719639bda988867764ffa9b029018b5547850daecf58fe1f a7f8ae8cd2c542cd336bc6c3605dad5aaac5056c87374ba975537e3f9c760c3daa76abd9504cdc0d6ee980b6a13970ae +00 019098a39956747de24ded56435fa1e6c30cc2b8088fe9a75f5d07b2f5939c7a60db64ad a59ee90f8c0a57b3828f1bda267c6ba4bf01f8126ed21c3c96510d2199ce6a19c57048ff7a434314b34ed5e9ebc321a5 +00 01636bd2be121e07ee83ac5e880cfdfca6a56f2b9d0badff003e872348368c7c2cd96b6c 95801adb35d336efcbf2a9b4e3b4ab69fe705dec9c77c4416d818c6b13b87ae5541e6f9a58860fc5788b78e6481ce9cd +00 015e5f555119c19b055b15b0c0d2813068bfc184f864e250b202384f5728bbbda1cb0f5a aeeb86edb46ca876e05006521a4c154609a657b512de33a6953cb68d7752c93d6cdd30fcad53343d38a54a35761fad09 +00 0190c8f17bdd38669e345440d2c7631d67cee9c6548c4e7b9452377adb9303430efeda0e b9b3340fc476014e85a4fb119319a9abea93668c2afa1cae43314afcc11396f042b1b5ae7aebbe616347c73f143a46a8 +00 00dbbc2a0409ca58a9e39e33b95fdd15080443c1dbdb5874bee991bd1b127047f08ec9f3 b559b7c0671a025b2aab657b86abc97b37551b13bb895e1cb2fe77a77ba0053012ec14dadc94e6abefc345721c2303d0 +00 005495e6c59ca1873f36b756579632fd47f9fb95b64f52589d70f2739aa6a3bf8cf8c198 82c07c90347608b5bd4a045b4a1079f948057a1a9adf409cbff18e567f5846aacc73f75fb86d6f1fd1b128a5dd7698ea +00 01724987c9b698519b6c225cf1261b77d0300045e5fd774dcbf13f285e6bd74512cb7edf 953dddfded4f35e777ea0e1d45fb6b39e4eaabefa270d04ee68bbbdc0a9d3404b4aa1dbe0e8ccedb1f08086c07062b6f +00 01a5489091cfd51a0970508ee3e8449081ed175928ff8386592c83043a7911bbc2f8778b 8acc1b49867df11ba7d919b63016737398af4b2f141887e3386603899d57ff5ffa2fa52b65d4b1182d9946c933255cb3 +00 01a45ecda0788fbd7cb7a716dcf4c6e83d4148bf63ed58078690ebd238c00329c462590a 91337ac8fcd10c667f1ba16ba47d732d2845ddc08fd2255fc8dbb9685a219a9aab87277e25814656fb3c51f499f3b248 +00 011461776c33f20b176dc8f2b0cb2446a9b69e55b6c7bc7457a7fb4639116b452b79661a 8a24e53e8d12d5b0f3b66db60c85017acbb3888548109a10ff929af3fbe38a59524cb6acea3d5d518190c1fb73cdb92e +00 0025a65f627db2b4d6cf83c5b0c00265b9b63f7656c5e3382139e4992bcdf3cab502844a 8e3d55a067baf0b7096ac884161689f687669fb7a43280b727e8b78dd2c952a33a152840606aff5cd454c3d5a240fe2a +00 0173b28fc29f10245221a907778708b3ee62e0480aa9051d4c3eb4e8d552e6aad5509943 af82dfa248dcec8ec82955d0980c3022d308443131288b0a196e9b9916ce2e63cfc6a3dd00642640349e869d4d29e302 +00 00624616adcd45e1fdc6cfeab2b17230d73d91fe0b39f4664f3c6891554f9b8e238257f7 aac82a1367b0911a7aa9e3debeaa8461bd7bd4f7d01a7197b7725aaa283767c4d6f5bf07d4436f6906e1b1f25a9f1f64 +00 0199757ffaa2c59e198d66824eaad37cc42d49b2e241b6a60382d05e425e800eaaf32470 82c9dd0bcbb94ad8b405f08691c933be8d86e9e5a81c16d398d7f8ae4c91f2f934bafb357cc9e65231f71f94165158b4 +00 006e51381dcf21050aef2e9b97e35303cf3bd91956854ecf9b6b9827871d2efbe8201c5e a5c20735f67666e7924a10478b66e60c07e9455d5349449e77d5e2ee49ff67ba22c84ec9632c00d03aff8f092843ef48 +00 0018adcc22cb9a2db64bad3d60f1608c353e091637b948914115ebd43679904f955c8732 8642bc4d6be080f2bf3b61025f7021428919e1d4be96d69a524fee3e335fa9ee3eb7fbaa1add33628580ae0e240b2fc2 +00 01898276f159c10d92d8d4b6ae214d68c72792a4b5f1f79936ca3c063dc8d9a88be439e2 b22c0405102200f09d3ad924fd9fcdadb37f7957097633d7579aea3016c37018b3d812b8b50c10e4f32faf962763034d +00 012ff37c808c3cc029a9cfbb67a5ed21f3bf362b49270d4ed0f1e38fad25ebd79f112a50 925c86779e192fe63b8b5254afc1ff4fe63cfad490e5c77c8404681d8d673186892e8526d3ab368d2dee3050f76753e3 +00 002b8c1fef9c6def32b5f4127273ce384b6add4aecec957c1662f52334f5ee97f49852d4 895fe4fa649a390f0ce9d3610c11f82577d0a87d5ec0fc464a5f447d9894ef88b66ce43407b5a058eff82d9adcf676fa +00 00afb1c45e9a9f02942b8e04da4b815498454dde6643de186625a98b3c1c6993abc8bba4 93889bde4ef121ea03b8d10514c5dfcfc2d89886533202750168293d8807bb4a0e1d1be438d9b6d92b4fe95138144332 +00 00ff537d73a4da0ae3a4894016b71dccef3bc886f3d24a5abb7dd96cf8fdcbdf0fdc5e51 a1d03276e57f54728cfa6ce3e0f1f4a5f29b0a7f1ac2eb1c2943e86e5b0b1cbf67bd1f32c3b91fec961d007b5cd00d87 +00 016000d2e879906d1040b32eb6ba3caff700e5565871ac75f10c5c15b509964bbe5e14c7 99bc7e5fb753b120b9f2d8af6e012895c02568071591fec5ec91eb5cb05304400cb190832dcb3fa303771eb310c8aa88 +00 0019528d505bf0584628d0214bc857150a929d3f59619bf8f3acab545fff0977c9bcdc97 8d4a184bd53c7dfb75472baa7e39e5294d1d0939c340a795bfda9e64286f3f321ac7646d83dbdb29d2f663015347fdfb +00 0067795ce117bc0a389397fc22a01cfd9422cfbfb5aa44131938a8c45e48e1d5a718539c 86e6b7c797723c9e22d4323373eb064ad6ba75f4195e91595bfe23454ae7d56cef28eb1becb5fa6f88f276f78ec0e795 +00 019269dbfe4184249952a651a507584746c5b62c64cb3b17e0158aaf4d086a4afb0330c1 ab4520bd4b3b0924c9671e6d308c99f535cdbdd035722d7eca554836faae8183614b9cac0ade609f3f1a7e728e461140 +00 003835814de0d6441cd80a44e40350cc8bd62ffcc81e939a4410bb9c9259e30463c453b5 a7a12f77aa00f79bfebecad80dc7a4f757035269199f7c1b2d3fafe2036e304b2364038fd8c0982fd4a0014b982d5ad4 +00 00aee83dbed3b703cb6e60d51e373eb20e298ac005fa6a572d02fa1e6da0345558ad2a46 914e06e6b1b92001186a5d920f98e0d829b3752c369c1831c5b74817776cb5d719ea712a37f450054c8bedb7c2652d6a +00 017b65c66514019ff935e9d571a4e68e9ee4463b7b9a754b93f4f7741693f4399879fa8a a068219b60daf51de1b991934b04708c10bcd065b90f1b91b4eac3fbcd5a8d0780eac8fb8e803c6076d5bf7f166227f2 +00 017d2071f39ba35515a8ec977ddd36ca15983e15bcda626f15af61d87d58114f4c80a8be 8e11ee14eb7007b351e6c6a4b6f15fd52d1b29bbeda56b68af7ab63a344e0019f6977823f2de2f1dc3d30a77ceb8e45b +00 011504659e12235855fe55220287a101e511d39a627f8a0d414446385d4a88f31507fe74 953e1163ec23fec323b8976b8b61855aa48ff38b3be2a92d477c01ae1279b0ba69ef5ecafb0f6b08885719809724d3df +00 016e4cbabb03215767249ba2a608708b78d7387be9e77f5efd2462467fa05e8dcde2c036 b0d0ea032fb9327a952839896387e911619281515610ca825ec208ddbf7a2b4a851f4e4d3c4516677ece2e7e82ce431c diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K283_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K283_blst new file mode 100644 index 000000000000..60dd23b87250 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K283_blst @@ -0,0 +1,60 @@ +00 01e846c830a8ec04e8572d1a9d2df044ab47352fb346f67403a3bf87243871b164511c53 ae2f686ba52c9b58c13fea8714a10fda15fed42ec3e91ce74b0a098f02db64a29633cd8d2082ba5adb11782dcab1880a +00 0101c5ed48231a56ca0ea85eb45de0e395e6df2efd4987a226ae36489dd8b2dfbf7c465c 921d8d9204666f989682a459594d3853bec07338d819539e2bbc7b5991a8dbe8a1ddc3b6c6ec5aaaaaf1064e1ad93552 +00 0019679dc589440b11f82b3716e5b2a2bd42c3b1c83e88a28e304cf5148877faf760b4de 861fd62f52c379a27fc7f1e8ed08457165106f3b764c64ab02017bfc02961092edfb5537bb80ef67e311f07458075ec7 +00 01703c21fb1e09f8947e12fddf166fda6f685221fbd803d75a0ae377a54a1e494e6c5e7b 87742927c6c3608bfa38e57c254e94e678bccce4d7ad13c8fa5549209c47742c4010b7777e137a835e1cebcf93841b0d +00 0071de8eb14cbfb88e61b908990ce08b81e624ef4f2cd9cdf3dd7ca9097d5ffed9ae9a71 ac1b47de9779a3e976f88d73699252936928b46a9be93a0e9c5ecf42de5e3ad06597dd283f447fb2f85c116e921752bc +00 01d156eb15762ed00c4021884adbfc2426e910b18a5bc474268196f4b74e593a8f38702b a393d79121d62329757d6c0847ccceba2f8397ad260775fbdc6e3024eeb0b4f6e226b8d6c059144635a85f65b83fd823 +00 017d6eb1219cab8577168be86b61f372b27ca70fb1f1a767947895c185344e966db17aea 80a581b1d92769626ca8a510634823567ccbc51c47ec23781fc53248bc5d95d8f4dacfff4401a917aaa33f1ac5cc42bd +00 010ede9be6615b3b2a294d67da78127ffbf3a15bdba6f4fd78be7a60415b5d1a097c0cff 854a564495527004d0c858a1b8e98278fc28aa415808f5bdf8e2b23fbf1765ea7c02bc1d87aaf11b9e1b6aee6bc8a217 +00 014f237cface123b64e8578ff33f86bfd2a8181b9c81f36b9ca31e2a446f0d91dbbe2249 9383d8711f464c786dc9d58211c4612d497943249542778372c713a2737be725ac6128d97c40cfcfc583b3193e7c5c0d +00 008dbecb26587cb2ed7df2404e680fcfa5bf8cf6a58e87a350a1600211b3c844ca86daa5 897f3f97fa69d5652e2e452cd9b18c83c4e0593848eeb1004a1e5c7f1e85dfd85318452d9742a85ee6168292ccaafe6d +00 0191badec2d28cbbe62c072c6b57eb5d4644d0c0b3283951bb66096cd15edd43a1bbde53 96270f46850f5db2833064baf617a82ee1a810a3743018ba77999812d8d33ce1c13900cb41d2b32c7444b88d01f51ad0 +00 00ff5e3d66eb57fd35ba4472effd6e7a016ca461e39000a7125e99080f6ab6ef4380dd7a 87d90b4fdc5eb6e6efbde8547b4ea7b5ce7784b4c1977dee40c6eecd3c53c4f5fe12a93092f45dcacf12191bf9335ea5 +00 01f3591eec4a8a3fe6ae6debe230d238a6b73cf3791cb735add1abee64239bb100f15166 88e3f5f1b16e881f66f6414dad48e6d2020a32e5b88c05526a4caf1dd76ce8f613c8070280a64a077da2fa8a2896e1dc +00 005af03cdb45961e7ff35fb0146904ddd6c2bfd3cce814073d3aa56eaa9f13b4f7423926 acc1d67227c6696ecc0d2e3244d45858ccd615cf5d6d6d84bbd745c9cbd57bd4dd5490b13720ada0475d020c36e4073d +00 01ec9710ada06e6270720692a06d488ae2ba863b905dd2fc323e7ce68dedacb35fc8c7d8 b04034713afcfcabda43708bd56c4a3cd224e22e6055775fdbfac71f118902f72c0238234c056053a81f321280a8f79b +00 00668de088c6913640fbefbe6d2c44ab26e481802dbf957044a4957c3c5d0a0fde331501 9052ff81fd3d9b78e977bf9d87b898a1b8ad99472650c1dc5fc972e575378ebecea44b04a5b06eb59697d5dd68af2b17 +00 00e6af57cf47de1e6f07041eb5e1a413fb7ddd82f8c7f7ce957eb28a118004930bec4dbd 8de55537d0bbf4d481558a17cd6512ea9abba58fac87d16e7c42042b05ac4a6b1cfbe5fa22b2c8baa40e3c4c90c45c9c +00 019f9b63fde8c6aa6177f2a38981505d04f8ac62bcc21007b05615d028cfe851ab9cbbc6 adfa67f25f2e617feef889cff5eff7f5b7c58330741da3151999992d3fc02b071be516a05c5da0cdfc85f21f3d4af88e +00 017704c1f436beb52f7ec97192e23e206ec09f9e8986e06bef71467c192bad6f0066b3c2 b245417a47d6feb3279fed35ba739e7b747548d82bf2fa3ec912d23cd4bfb3a34e1f8d533d31de46fe129330267a5d5d +00 00c7d1ac8faa689698f5c6325a3b3f35e7730bdbddabd0693f2bfdc5c838bd62f84508d4 8fd1ae6326e8c4e303c85103936588c7e42e1a2252553d1f57da5db151b47cb118a63e38f49f6b5f6eb9454f7a3f0188 +00 01a173d158866db0ec665ee632b5fc397893f6a44ee17c348e7452800aadd8ce676e7fdc ad9dea77db70b4e80484ae176c67e226ba31f81d004f670419edb76bed0278f30c6c787ff65536ee381e4f3d33f8be97 +00 005523cfacf4ed3b74ebc30f608292e45173001d80cc801f729c5f71fc213b243f041ad5 8316134017eb033b4ff587ed01899c7f90501de1158644b33e6c6c581de30989cc7ee0c33a1d55e8333f5ba044b30b20 +00 009f6bd008c04b8823ccc3ee7d5aca535c211f35e9d9e7cfaec518b98647fbe6d28283de b2d16ef43fb6b1ad24695153fb38ab538d07ee7acea238bb8cdd3d74700a30ee93e5692466d83453122518f117589f1e +00 0150d2812505c82584201e93f6e0cb875d29dc7bd99d9c0f98e0ed20128886e67e1f1071 b98bff4f4c140fa50f7a8e4dcbb3392b770d8b4df800bf97d36717eefb1c6ebfcdf0083c2c9bde8525a3df4203d86bdd +00 01b3fb9e1ff70f94bc9d7742ea535ca982215af3df381b5ebdf1db40c7c849a7978ceb98 a7c4a7edbc1fae96feb0e14dba97227034c8a2302a4dcd597c34a57e85de01557b01deb95ac263ab5a4088f45f906211 +00 0147fa46fccf0805d14c1b84ea59bb8b8283d54ca0ceefb29b5585e7141340c55b7232f7 809df44c96777749651df86ce58686d6f79071eb96952174d061978fcf42d3fe97dd39a29cc04d08375e975e9c315b0c +00 00fae097ea56b35a517be5480802f450eb832b244558d0cc922cd4a5b40b84d02ef11216 90c554c81efae5df86729a63eb76f0ca5f2337c042cc18d274b7d48bdd33d4c4eb61658ec0a730443971b0eab8ffcd61 +00 0026cd72e6ae19b3f4c53493fba1e8082a8df1fb7da6dc111b47a41f713f49b33f618d0c b6da5ce63ea91548aeeb6457cdc0132e7e1fd1c460d5e1f64d655e0ba997f00df184efbc9b0d2b871dfd72db070df1f7 +00 0198e13c7d95bbbb6e226688719639bda988867764ffa9b029018b5547850daecf58fe1f 91c09a2477e50ca6f0003871c4173b96301f28ea9a78c608e252eb0e7ba7730b1158786ae5c3e30d98dc7ec763f97a66 +00 019098a39956747de24ded56435fa1e6c30cc2b8088fe9a75f5d07b2f5939c7a60db64ad b9e9c4706a8435587e7ee05d3a7bb0ac92c9df5a7019463c9b1a8367e96a8732a62e88ac45e3e68ed9b5c6ea8e07eec7 +00 01636bd2be121e07ee83ac5e880cfdfca6a56f2b9d0badff003e872348368c7c2cd96b6c a8066d29bae0fbfe8762d4d8f5325c8b826f3efebc17080cea4cc08b14f415f7062f1dca5be501f6aabb10bacef40d3a +00 015e5f555119c19b055b15b0c0d2813068bfc184f864e250b202384f5728bbbda1cb0f5a 86351165daf03cf5d78c7ccac2bda5f19adb5e0e9185be6222532bc099e703aa4ae43e6de094a367e2dd44f364f55d84 +00 0190c8f17bdd38669e345440d2c7631d67cee9c6548c4e7b9452377adb9303430efeda0e a3142da42a6e4e065c64a3ba1c774b84d3f31e96542e52b4ec1a05445ee9cf87cdb3233a769fdd4d0dfee9d18d47ce3b +00 00dbbc2a0409ca58a9e39e33b95fdd15080443c1dbdb5874bee991bd1b127047f08ec9f3 a51e223b62ced5ec3d118dbb653b051bb82bbe52089d88d164d4132d10f18f31bcaa27e26ed59ffc55196fa392716933 +00 005495e6c59ca1873f36b756579632fd47f9fb95b64f52589d70f2739aa6a3bf8cf8c198 a140aff5e2487eae86c0bea8b88f2b1a918412081b5d979b4eabaded7050e6480d27fdfb8da7f3722dbbc56c56292b8d +00 01724987c9b698519b6c225cf1261b77d0300045e5fd774dcbf13f285e6bd74512cb7edf 98bdd239aa0eb43424c7ea2ac964fe37a9793cedb1b19943e38ffff574956de5a6d9feea767e2b1f70abc0749fd4b222 +00 01a5489091cfd51a0970508ee3e8449081ed175928ff8386592c83043a7911bbc2f8778b 8c562c853f2f6fd5dafd2a0d866f6a8c1e55df75d5c74dc9a111cb8e6be6e4ef419596d32fbefca5e6d744108b74d445 +00 01a45ecda0788fbd7cb7a716dcf4c6e83d4148bf63ed58078690ebd238c00329c462590a 92bea03810cd9647da7355b7175dd5855edb40d807ea1501227b03b49beb5f9beb9da63741eacaa6298dc0146473420d +00 011461776c33f20b176dc8f2b0cb2446a9b69e55b6c7bc7457a7fb4639116b452b79661a 88309e5b85dd6a8477b051668d4a3204e412be6cf5d8c069f779c5e3c2783cbad995c0997553117f1307710bc8d1da70 +00 0025a65f627db2b4d6cf83c5b0c00265b9b63f7656c5e3382139e4992bcdf3cab502844a a9353b82756a339328539c07faa175156d8666b293e7607f06daabf9f6f8fb7d49d0a42a204eda452e02603d49167afc +00 0173b28fc29f10245221a907778708b3ee62e0480aa9051d4c3eb4e8d552e6aad5509943 8995bed515ce403f9ed23663f26fe96381274a4b8942e87d2ae4ecb9d500ea024ceece9bf9a46d52c6c1f8d3daf4d2ab +00 00624616adcd45e1fdc6cfeab2b17230d73d91fe0b39f4664f3c6891554f9b8e238257f7 8edb1e31fcf9812fdd1baeb084458557dcef2a15ce44f73766206f937687d76633338ac8119027080568249a7e3ff84e +00 0199757ffaa2c59e198d66824eaad37cc42d49b2e241b6a60382d05e425e800eaaf32470 b6bb2adeafe0bcb739fa389eae7915d46eb8c3eb9957f47512acd0777d709ecc4d1bd2a5e858968203baf9f0f53213b9 +00 006e51381dcf21050aef2e9b97e35303cf3bd91956854ecf9b6b9827871d2efbe8201c5e 8b741156f3e4c1be3dacbc40c13bf69d3ec035173298da38263e0fbacfab6000fe84d8d5d7da2ab34fc5bcf0a9093d0f +00 0018adcc22cb9a2db64bad3d60f1608c353e091637b948914115ebd43679904f955c8732 8facdfd56c64830c77322c40ca000bb94923a0bfb3544191b27fec7c15f5a280cdafc0b136a1c64bbe76006169ea527d +00 01898276f159c10d92d8d4b6ae214d68c72792a4b5f1f79936ca3c063dc8d9a88be439e2 806fdeb1234da9fe0922f720180cc9d06154f964d4dd4f8b5cf08cee87acd635955fe1421a155d377c3a71de418604a4 +00 012ff37c808c3cc029a9cfbb67a5ed21f3bf362b49270d4ed0f1e38fad25ebd79f112a50 a05eccad964d703b6e49e0f130e5a61049bff7c2661d16059781819d069660f04226fd9a4886acd5f0476c00fdc16059 +00 002b8c1fef9c6def32b5f4127273ce384b6add4aecec957c1662f52334f5ee97f49852d4 b2a773411c8be1d84995f97511f20ec6a68c1e471f91f2daf79ab3f3b70e7e2549d86ed7d83e8f072fef815888244e02 +00 00afb1c45e9a9f02942b8e04da4b815498454dde6643de186625a98b3c1c6993abc8bba4 a945f93d96ef215d49f79a9e85d631c0f72c943c71ac6e86a7184bf21fcca39488607b3893011bb458e0c2a793b3bdf0 +00 00ff537d73a4da0ae3a4894016b71dccef3bc886f3d24a5abb7dd96cf8fdcbdf0fdc5e51 ac4c1445d51662e9cad154e29669feecd7a405fdfc83d768ddea23d195976b60dc12ba1ec4ac9ee0850bea491c40284a +00 016000d2e879906d1040b32eb6ba3caff700e5565871ac75f10c5c15b509964bbe5e14c7 b5fe3ec5f84543c91f37978dd00544c0b57b8a767a0ca7c2cbface9ffcc4bed783fb49010c0c69691003cf6428ac78a6 +00 0019528d505bf0584628d0214bc857150a929d3f59619bf8f3acab545fff0977c9bcdc97 b923ce79832fee9eb39f22a09b943a2264546d36e6eb204024eaf2d2ddaa405ea76ffd031052e39ce4b0a62e9f802cc3 +00 0067795ce117bc0a389397fc22a01cfd9422cfbfb5aa44131938a8c45e48e1d5a718539c 94b387adb898fc4aa462dc05d8eab9a03c54eccba5fc73c8846a97bd19700cdfbaed2d1b4655ef56945f87f46c42f160 +00 019269dbfe4184249952a651a507584746c5b62c64cb3b17e0158aaf4d086a4afb0330c1 8d9ef785cbbc8bfc344339b3e243ea1997ee56edd385e4a401478d5106a8723dd282f55a294457cb993ed68a67833b85 +00 003835814de0d6441cd80a44e40350cc8bd62ffcc81e939a4410bb9c9259e30463c453b5 b8a8a88d77bc4ca3746c5e02fc1cad732ed48867098ae8f1bd0309274d7fa2fdf82aa07ab0fd4eb8a43a10b1e06d7060 +00 00aee83dbed3b703cb6e60d51e373eb20e298ac005fa6a572d02fa1e6da0345558ad2a46 a178a8dbfb75bb495f71599d4aef821b80f0b82373cb87130a261d4d108c567456494b68e1eb652999b801c5fff15540 +00 017b65c66514019ff935e9d571a4e68e9ee4463b7b9a754b93f4f7741693f4399879fa8a 8d6e29959ac097afdf040a65c36a1f1a8d93b9e9aa58fea795cc9a5d4c0542897d3d729479cadb4941620a5a1d7df679 +00 017d2071f39ba35515a8ec977ddd36ca15983e15bcda626f15af61d87d58114f4c80a8be 940a6eba7d5b5e78db2094ee18c7ccee02c150424362f10332da49fc3c04c8af3e04604421aabc84db93deb8213b2336 +00 011504659e12235855fe55220287a101e511d39a627f8a0d414446385d4a88f31507fe74 a6d71bfda399458e6b552b92288dc50d27323f29e696e83edb2d9c4b52d3ebe6248ca88c844d4fdbde436d872b9b011e +00 016e4cbabb03215767249ba2a608708b78d7387be9e77f5efd2462467fa05e8dcde2c036 ae990f81dd5bb3ea322687698e08ac1913cd475876536eab37d16090372928ed0ec53edf07f331b8d7c4f1953c8338a5 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K409 b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K409 new file mode 100644 index 000000000000..8c3fadf3d4c0 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K409 @@ -0,0 +1,60 @@ +00 0011c6528939672bed3e8c905b7ba594c3ce95f37fb28044f210cccd01dfdb42c10e8e1a0b5d6fc757834ca7f08e98cbc52b0edd 82ec06a91f3c09c65b602a498b65a3689e06f595905c3650d331776a1ef64fad038ae0fc134e293c9431fc72e1a052df +00 007e3b714496dd118d8f3f597961eec5c43d0265bf85723b0b9b0616977e0acc2cf686cb6afa6cdc19114e27ab000e762dfe467b 83479d7f780f2b88e45b131caf412aea609b9783e22bae9565b2195fca75ddfc5ec6cb122a4611cce9be9dc71615650e +00 00182d1e937b037bf7f84144f7d4c94c935269c9aae7d500aa459a7a0ec113b232dcf282908eee4c84b8106cd38cdc41db3f89e1 aaee8b99165b0bd31968f0c3ac7f511a5fbca328f6e4950ecded7bec38dacc5a44e2cd265191c402a620d0ac2991fc81 +00 007ed09428f460724c8a5225a31151e031d9949493fff5703369c401762345d002c4ce424294baab22d9e71edc4f854510cf0e6a b14deb82ef3690faeb0296818a7e00b3528c4990637c38082ebf269aa0adc1a634355db4e102fe9fbec1d83169ef86cc +00 00390f05b9619c27b800e99aeaf61ef7f6249367d5cfaeae3c7b523a8b29153eb8a77132f6c4412545a842d6deb7b7aea7e2bda5 b014e8e5d4ddd9d7b0fbe5a8b5b7f073a4a7f377013d73692bddeb94bc2a6e5296b23765290fd196ba23584e63167d32 +00 0007d18652732596add3db31f7a0ce6020d03f3df58131b0c7c633faf619b8210cd309d6c0c4083aef1a1b6d2a756adad0bfe344 a5d52acf680ae524517071ef69e9bc098776e1cd3e09d5c1c36d632ad65417afce4989f9ba5ea886db26281e2db2f084 +00 002a91244ea4623b63403dba807d60b914ca3b901a2523244c322f2f11251446d3f15e869d086ebecfa1a39ce304e8b5c8de23e2 aacb2b43d1e2ec2664345b4bf1b2f2b4e6625a20da9e8e061b32736e0d39e6e08a447acfe201028a4c36b4de33b02f83 +00 00068c56c6b5d50d1d4e13d3837d8c5e8ba2f825e121b63e97603fdfe78bb6899600ff0dc87b6b3b6868ad0d2f62b7b7a31603ff 907285bcbff7d1edbf74aa1d0ec77f8ff320b8a6e343bf06ef2b2fd10872ab386f4272958cf27e64dea98d58ee9a1788 +00 003c88084f8b78446db431bd6e240a0c050813d2a763675b0ea869cbe183df697146cf29c03479af3d34587a95cd257027fbeed8 b76ef27b3fb346d6c20e77532c192dfe81372e4fa3dea9721d4bf2b96bba2a68dd3a48ed2eac1f40627b996ec32ba3dd +00 0051af7b63bf3297ae20517faaa1552f4fde65819dbbff6a52721611e5b7dc1242ed6e69768cdc37ea8cdfd1a5971f06b84b5803 928d0733a79368d30487b64a485611f0cc73b9a4d0c9d1ea597a76bf5a6c637b8b6665fb2b3a759b900c42c10f814b5d +00 003d65bdec48972d03811b78150a06956eb22d337dbec5416bbd8185a6322cd8c0ff8000210dbd1326422289071cab65175f5d10 81145bd8c3d4f2638bc2940e1d4ef16f1f34c6ac70bccbfb742cde517f80a4c182295ffb5ffd8213b11b035fa3e8cc13 +00 001f1a8b5f35dbbf82c102df550c72216a243f986f0325920f6186a16d1da74228cc02be6024c7411160c183c923c743354f9438 8204b1e50b03493df842267af91c28b070a9537f9be58d63728c48f03ee09b345532aa4b5c496bf2ad529a14e388808b +00 0031dc621200cd174193d95e9092ffb86189c52cdbb9ed937593f2cde7c4a0264b9100e1b8407336c8dfb5520d28a18dc4e39a89 90799d1789c34b351943dce50f44772d9440ebfbecb679efe7b2e08166494830de55ac9234b14c4de3e593e56a8d5d7a +00 0016e6750245a88340b0f0665b890459f8038e9b1366f2fc1326245a88d4c523ec94429f21869ce3dbf75126e58f77241c99efaa ad1f9fd5b9c9d79908bd5849f96ebf548900f6ac24f72ba3d13e92554413ef73279b2ad43a375f3113282e87e6358f6f +00 00788fabdafeebb72f6385301e30024b56639e629a400f9c50d402cfc9b5817844f06a451fbda29c7ece41dc9ffcfc625fe0ff0a b6a024bf90dec4e922a7fce8614b2952847ef542e01bcfabbd24f90cdb5003ee6eb6d77e4f08d5e948396a2265fd1dfc +00 001b8dfd64563dc219d6eeb53f2e3ad1d771140d0960b211dc1f757af5e297dc7548d6133ddb574711d466688f80dbd65a7bbcdc aa4d6fa1e7a0fba740eaa612394732f15dffa489b69308cd27a29e7439fe0466e40446301d72815dba05284d3eb87440 +00 00422131829608ff730c24ddf7e8b4a2600eaa9681eaf45432daa7d41fe2fb488fd0199d431a1ed823801ce21f4f01a4dd4248ca adbd0518ad4f5471ffd6930cebddd2be678e7f13c5e82b2dd5032eaeb8ceba53fcdd8ae0cc8dbaf05602d8d7c348edbd +00 00095ae8e4c7e55eb5da01acc05ecfe72a4dcd8ec152f1c8dc165014f70eb4e4a7861aeb2b96c418b2d4db58659e76184e013a49 89e82309f97cd4b66bc58bd7ead456e69605bebf62dced986f42abb14fa22c58d90b3e0cdfd226e3b967e042df16096b +00 0006f2075bd730f34df111ebda919167b1d3358ada32cd6747cb3353bcfb814a77ac70cd51b31a0e538539453bf9eaf9d8b384c9 8ab34fb5c3695c16a200a5592bfd21b9c05aad676f4962f089a0c6b0eeec90eab039489085ac18f2ebf56f3590e48272 +00 003887d284e9ad17d38bc6da9d83c192a434c509340a7f233cebb032b09ab7c4c6e8730b4a80844898616c9abcd16b753c6bb4c5 8b1d2b112aa38d3c7e8c798954b54ac5a26b0f1238896c4d6d0950d3e8918ef6b8094c56c4d1123346c9f9004b854765 +00 002ea5430610864257c9dc393c3addcd0d8d5bc8aab1067643b08857210464428aa85cf1ae6c743fd2682255d4c8eaa46ca21e73 97a8da074998817c10bbcedbbfeb8b1ed40d4d6dd2c3cba141751ae008004340201e9647c910dddac563574a6ada9c89 +00 0062c757c92eaef41f5d81169ec4968145b5aa2bc1d2a3a5fd000634777748ecb93677b3da12e3be33272a8f0a52300f4a5a37c4 a5cf526e8b2ad1ad218227ccec3d3899578ff9e4a3fef25fd6b89c234aada28e793aa0bf1e3b21cdb1d5ebe02878708a +00 0048a313c0c11489939fc0cffc6ccb9f179093c4e13141b92dbbaac441b7ae878c9d412066e95615174a24692555cbbe904a14cf b5ff5afe07a2353ff3d7ffa8286fe89f0212a3d793eed74740225f08b9fc83a8670df4dc38ea3ccbeea702b8bc6db508 +00 0046e2adfe5d3549e1e6fa1fe69a7cbb4ac9b111c8903d544268f8318b0b47d4b78fe3e56eb5e639ad5382e7cd5bd4b2c3e70ef6 b8208315b01c0a181eb58ae762e991a9c2cab06a1c1aabe98d3294c785587aa18d832cbd3af1f5728a1b8186d9375afe +00 00480103fd6180a431c837643566706e2b9597de0a1346a224d176a5b2c54aa4d064418ed654a5d39f4773fb509f86473ebb373f b1883764cda642e413b6ac9dd7a9e300dd2fe7355ce376fb3b85f99cbd0c6a142f43fbe2dca3d8856d292ecd642ba2eb +00 0013c489e8311c6bef02c8f58903b2ba2a98a27cb935d75a30d320af9a14fa3cbc6adcce09235a9eaf333dd05f4b2f1694985dc4 a504fd9a02f433e0f443c02a9c23b8e044ffaedb928359e3d4bacc1f926f8874e71d1ee9cb6ce2ee12f0cf93387a87d4 +00 002419bd2200f8e1d87db848b0379741685e680d9affe693eed49d82931030b6cb05d21a4965f4e1df2045c8513a8f574ca9f2e7 92617422b638ebda2058539cc882b22c97f5ee66e89bbe1d0d615ddf22e7e4c7b4407eefeac7fbd0e2d2347d3b43545b +00 00722951879a65bfcb414e11712ee9431eeb32319e0ff28601112f89276ffc2b96eb65c7fd77d023f09914a53e2aae2c84652bad a3ebcc16b2db00fc4a494d133f6618675356a68ebbaeed731900b747eef3d5ee36dc7376d4cdf18e7142a26d10fa65cc +00 003f5b5a772d24bd5454bf26759dbd433fcc7bae4f5c593664c4d75da0cdf9430d7d9162bce3d7f6e13a344259da5a7d6a1635bb 92a2041f712eac00d357b86ff471b8f02d5b6d5bd9f4cc0fe905a561810530941643f64219bafeae7081994210dd2772 +00 0046bb4a141c9099d531dd23ac440eff1f5b10f7cf34920b6b702311d490d25344c665ed5211d401def24986c8094165d10f8934 8bd290c2370511ebd3a99094c9619cb0219c8e0fa8bd836dea5c41b5790cf85fa5956a8e33f577de0c3747d36c97856f +00 006f2c6e9ea8109223d9a349fce14927618fc4fa95e05ecf9aba1546619eaeaca7b5815cc07e97ae8cd1e9973ac603f84d838393 90872827e781812133e80e329f3b1c7aa04aa405a73b6c8a6bf8b7e76ec125bf5e30e151b729d0fc7762e0078018a85d +00 0004212b7fd913d794fc6bb33e0276e349c052c969ecbf6afc89b28f75a599a9242acf74dec9f374361ba296ba42a38407f9b7d6 841abe193759ec716bda04ff619a73df5de92816f22c7cce2c365a69132764a4df35747c08a54b9b18d247ea1a534f54 +00 006baeebb5ffc89c94c3e8b37b9b0904e7c4b251d204894655bf3b1235710215c29820b9d401c9ca7df1404d2d62d708aafe208a b25d6c920bc0ce912fa39804a05bfe0eea11b4ecb7aeef73ace66db4736c85dad6c72a92b8c42910377c512c072ae069 +00 0008e5f66ba53e7caad1feda122a80c32c82d2c32a7237b8ee8ead44ea8f2f01d77c7056b9dd60b92d051f060da8532c1fd0e8f4 b970d350b1a7c37c22758e23032707f0d2ecc83212958435ac36bf4beffcece05e4517b11c664459abc65351524bd79e +00 004ecb22b44e809f89b16abb10be062c89b41ee34e110403e42a20ce59a99afdc22f6f6dda56e1d9d1b8ce1d057f390db111def3 a38fd80186ad29ac4019ec3955e80181e4be21a61fcc169ee6583d94dfd0cf935ca6115e499d8bbba639976aba6715c3 +00 0051f9500c15ae73d6d479b9f3d2caccc2039d8d03820befc2aae3bbaf65d59bd9cb3c4e3aa8bed5b3acb70a5566047ffad80729 b6beabcc87f29848e44c282da3bdf7e28b7fe5b2521a1feb130d03e218c632fde296f2372c68187cc7901b5f9d88bab1 +00 000cf01dc4462cca764f4f8cbef48c51980737b9b98d1384b8de9f4c733829db7718a9b5eaa46a8475c2144fe4454cb8eeb0a443 b0999faeabbab9e634662cd6ef4186d7d70c4f1a4aa049ddc80530d81b4bf467e337bd6abf528bc0ac58b0974fa274a7 +00 0063a9a565497974c6dd459bea0d1196d74f263f333c31b7e8591499960e1cd79e2ef4cc8709f6d54713f873b16e7b0be42f71c8 b360cb5c55888eb4f18e31d6eb6b0cf241c0eef96b1f098196fb7228993befd0f2e783fc468a1681d0506049b31bf44f +00 0041074dc186193d30aac7cc6d269b938ab40b257d095e54ba79967a377a91b8f73671470cd07f0a3d1db7cf0a31ba9070625e43 9122ce63da5520b9aecc04c700bd5fbb3e67285c6ebd2ff0e7884760573c5bb1bcd5342372aa7ae14b58e2c911073280 +00 0010820db54ccf0226161aeaee79cfd2797f87702b4ee91adf8543b3c9e79579d0df8a889e366ec1e0718e039b87a37c24d620e9 b8a131bf20e014e1d35f90c5485f121b20de8976290da58127e1cdc28976451f2957bef3d121219c4f896811441ff79c +00 0059d2a06e8bfd5e14a9bc8777958b85be5e97af892d2cdeb0ecbd2d5017952b5042349db5fedba2e26e7b85bbb31ad313d99434 a1dba868b6b382ce1300005008d943f8d86aa1967329f95ef3670c83e3db0ae88405f498a31b52acdb28efef75de1851 +00 00405590893cbbe18f4ad99df28b5f9d17f8f1882269aff0b7eee9392859d68927a99c942a3075269ddec6d69c0df2d76ab9d801 83d477af35523d5dac0834ea93be07a90edb406f763caef5ef4997748f8e2db098a2b5bf5e9d48dd39f461050f7fdbb3 +00 0062bbb4f565aa0f23b88ab9029d33b995729d10fcfc33ba7c4051e2fbc72f15636a834e3ebfe604b927cdfc89f53c57f36890db 954fffac0d98615cac631853a4fa0b15a867bcc0e2d665e1e40fdc20058c274fdd3d1c8d6ec1b648041bfa02bd7d2567 +00 003fad7031cf8810544a3e4bd1382c0a2e22c5a9fe4804ce67b27591fc516ee81dbac841d399327168aa6abd79e2b5ef85df1528 9069bd7fbe36d0910e1c262fc929657ce4151592a097a976f461cf9db14fd08c41ac19ee8ce52362c8267837526ce77b +00 003db41b4f637fe7977c90e4f1a21799baaddd1826c667102414877138436cfae1b9959842b8097b5276f15f2b982ee59df263c8 a11564e2f2deca4be8d9301817bda731e6ca90b78aa37e7ef0ac497ccfc7194cd2fe6df1ed5bbe254f0d7a1495094121 +00 0065b76c6093d9c49591293471286df1a4444e60d9d06cfa114e175afb5f119d2abeb273b0596019a0ec5db5b5869f2cc827b364 aede0728981fd90187782216930b7c43a7ed30e82b26053dfe2fb46a6e3a4648ff9fb46667cf76d1a997e66f7a0ba48d +00 007e9993f3fc1fdc4c376ef77ecded96006ac1159740bd1b2dc6ae3d97e15a67383f1fc931e460b9af3fe14a54e47919667ed06c a4dae13b466f122c76fd0bf2a579b94c7be5b48b7c173cea8d66407db016a5701634baed86eb87b6a8679553255e07d0 +00 000c11e2979498695c660a2bdfd105b115bc4ff8664ea15cfb40c725406c6fc9a13027bd1d72ffff6258f29e4e19b845243444a7 8fa65b13adf8ad9dd3138acfaa2d465c492fe5c3f994c86219ccdcec7b67ce1ffea9352d5f68f449b0c2e6a628070eaa +00 0068dfc23c6635bd1fa1076dcbd456ad6e8df7ce7c1370fe275803befc4ffad007fd062a61cf1d50b93aeb9afe1aab47a65af82a 96b648442e61ac723d12142f4d831d060f2ef3dc35dda5c062299b34625bf013f5f5d13468d2ba50f8cb75ee4a2b3212 +00 0040807fb888e1d9fd33604546656a493629d94d4a0a9de2608962225ed158167f9e2438abe2d12a11e2adb6c2b66ed78215b0b1 899ad0d459ce7a5c6679c09ce5847914e3fe411920d57ab4827d30241051719dd0ac1254f0b5765b19d143f89ee3fb96 +00 0033bda0a02badae08fe40c239b9d59e5bfe1c4d4b9b7a5acda6790bfd77ad08dde5e93a2da80ec54a7f88146d72218bbb88aa10 a556e11b9b9e76d4c4eca98c66e36e1d301148680bbe67deb328d92027985d748083246879367463aa3b1bad7c18b084 +00 004ff431769d26b8837d3e1295f5464fe82be29edefba76323e92078a6483ea0daa96221549102509a1bdcfd46a5a2e5de10c39f 83426ed6d814b0acebac904a6b99cbb8ad1e0445f31fc1bed40b91e005229a43ebdf08d252c7123d7ceafc147103a111 +00 003f85ca1169ca7e9df44cbc6bc7d2868c9d94e8f8b699a42ca492dca0914eb5789a9032218dcef7f95f959c9554a1cd83360439 8384710fc7103c5fc7da40643bd98bc1190e373b9aad306fc6206d590114a29415481574f457e1beab621a560acc0b5f +00 003a97deb36d68f81f50c8829d412ee5de7f9d775633cb69c09dac558182039e275fc258240517a7c4aa592e364765321f27cb12 866e1ead311e2ce8782ab844e8b3d9ffa72a87ef44343a14950c5b553669f499ac035e8774d626f51aedc1fd6a6f235d +00 003b1da0ffed24e1a3b5ba22bd684337f6b08053591620541bdad50c761d66201a2cf21a4cc636426456525b598e96baf97d9851 90e7cabe8931ee4e8fca473788b54f72a34d698b708b7e06e79ebc3b6a1138c76e400fc03b0cabc973cd7fc33c3ecaf2 +00 0040bac7e0d3b54c7753c79d43469e310d876015d948fac4e3a9765444754476af72330e88d79ee6119697aafac8435ab5690754 a3f1aed974741d68d40555a6fb91eb037eebe4d308c01ed75e942f814f67c6ba581df12c8b8d289e927cecc50310c026 +00 0025b7eb3bdefba3c5134438caf968f615b315204f348006f82e8d61057a8a8a853230cf0500f9d0b8c1551a59b9184862dd2ed9 874d15562f80b3d2f8001e9e7412926c73f736d0c596cde4190e5cbd3b5c20186e305314408051b9e0fb37133df9a2b3 +00 00673b3a2985c95904732632e5d988d8d437a60db13215bb6aa880b348f011c609a1e860461427a8cf0d622abc47f910f5c97ffa ab9dfee5542bf91f258f218a44f1cec441de06d6450fdb3185575b0ccc99fc5a81de4642517084ea2dde6618f6c2ba7b +00 000db7dcac414010b816236cad584dabeaec1da76c97182d1b62f87bb7fe2946a64d10430571b2b29ccf2ef72c969a9f045f1f3b 8e89d74135a6566b6634b00d02c6bf5c52a32c31df80a3a06212887bd62d1ade8670e07ce9bae9ad5fc42f25dabe8be1 +00 004717efef16e1ae267e155aa1daabafc68515aa391dfeb73c13d01f3132bd22c984228dddc4dff4c39979e7585acd3f730cfcfa 95122ca9d9ae4c3a4ba2cc286b149bd4afc24ad1309d075c83b9d1ec5d2060856caccbb2384d32133dd74a8ff2274c6d diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K409_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K409_blst new file mode 100644 index 000000000000..95d8b3b1f413 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K409_blst @@ -0,0 +1,60 @@ +00 0011c6528939672bed3e8c905b7ba594c3ce95f37fb28044f210cccd01dfdb42c10e8e1a0b5d6fc757834ca7f08e98cbc52b0edd a2d4b591a1becb36b55459daf78b66633e4684f26fd5d43b3927035ab71e418f8c7480d9c115f40386e2c50e73151060 +00 007e3b714496dd118d8f3f597961eec5c43d0265bf85723b0b9b0616977e0acc2cf686cb6afa6cdc19114e27ab000e762dfe467b b3e68e86ab91fdccf6add138b6aa121adbe2c12f0fbc92591f5ac3a2ca63d2a14859523659550acd2802d9b425c206ee +00 00182d1e937b037bf7f84144f7d4c94c935269c9aae7d500aa459a7a0ec113b232dcf282908eee4c84b8106cd38cdc41db3f89e1 8d40dc8fee2e729eae8f20796cbf0dcd05d76a8a05b3144d23224d320723ab84e492df35d0ccf743b5c14cc4df6a0b79 +00 007ed09428f460724c8a5225a31151e031d9949493fff5703369c401762345d002c4ce424294baab22d9e71edc4f854510cf0e6a 8024e09ee8b1a82f969e7cb919eece8e360db37dcad50d2d30c65d2b87dbf64a108799d7334b4d7acf91ba46217b7382 +00 00390f05b9619c27b800e99aeaf61ef7f6249367d5cfaeae3c7b523a8b29153eb8a77132f6c4412545a842d6deb7b7aea7e2bda5 9515250d9a4ff9c662fc6516a0acc4f45d1ffdd90c9c377c24531e8252b68b5169b02b77cea2790dd022a6a4d9cfebc6 +00 0007d18652732596add3db31f7a0ce6020d03f3df58131b0c7c633faf619b8210cd309d6c0c4083aef1a1b6d2a756adad0bfe344 ab50d516f84859766970f250ef99b2cd3f3b6b54e6aed67e78526c7c73d177969beeb9412e70a16f817c39f7ee546287 +00 002a91244ea4623b63403dba807d60b914ca3b901a2523244c322f2f11251446d3f15e869d086ebecfa1a39ce304e8b5c8de23e2 8c65c1bafcd30c852e1f32492c813038c9640e5f5387b38c91aa481052cceff08583fa0223308d6724b03a14f4e4d275 +00 00068c56c6b5d50d1d4e13d3837d8c5e8ba2f825e121b63e97603fdfe78bb6899600ff0dc87b6b3b6868ad0d2f62b7b7a31603ff 91a4a42eb1a70cd09650a6831bb77ec17c512ac77369aba54d35ff5c4354c8f3975d95ab975dc48e1cb37843c72a7985 +00 003c88084f8b78446db431bd6e240a0c050813d2a763675b0ea869cbe183df697146cf29c03479af3d34587a95cd257027fbeed8 93aa77d46a85cbd40c5fbdff0f9b012eac62c632edfef4dbcf83d9ca27a5de11a48b6b855149fd8a136047eb6803027d +00 0051af7b63bf3297ae20517faaa1552f4fde65819dbbff6a52721611e5b7dc1242ed6e69768cdc37ea8cdfd1a5971f06b84b5803 881d67b0e3f372cd26c591752ddbf2794ad4ee33070d8d13f2abd1ca0df2016c41f4ce5d413211f5821cc64b23c5351b +00 003d65bdec48972d03811b78150a06956eb22d337dbec5416bbd8185a6322cd8c0ff8000210dbd1326422289071cab65175f5d10 97f64737041dcddc9573b3cf0b68f8f0008722dcb192fc2ff7b9f446ae5a6b126401d10d14bc69bca8919f6caf264350 +00 001f1a8b5f35dbbf82c102df550c72216a243f986f0325920f6186a16d1da74228cc02be6024c7411160c183c923c743354f9438 8848e957657c3941566cd2e303ea3ebe237f4dbdbf162ec2fd80935104cad360f68178b863f8f886e128e8056bb6734d +00 0031dc621200cd174193d95e9092ffb86189c52cdbb9ed937593f2cde7c4a0264b9100e1b8407336c8dfb5520d28a18dc4e39a89 84c03721305635a3b08c6bb0f67bba3a88145ca273cceb2d041f9f3f9e3f0325ba91499d28283bb44a96bdbb8935fb2b +00 0016e6750245a88340b0f0665b890459f8038e9b1366f2fc1326245a88d4c523ec94429f21869ce3dbf75126e58f77241c99efaa 88c5a24417f4d5299a8645a967eefd9bcc2834e6f97187151cf1b3622f6ac460a264bf8ce191a33b3a5170126b2712f4 +00 00788fabdafeebb72f6385301e30024b56639e629a400f9c50d402cfc9b5817844f06a451fbda29c7ece41dc9ffcfc625fe0ff0a a22e17e10a73be1b1f7c4a9cdb3358b66787233dac90a2a3bb34623a477528e251cb5eb60f2e1fe2f2b204be2d65a397 +00 001b8dfd64563dc219d6eeb53f2e3ad1d771140d0960b211dc1f757af5e297dc7548d6133ddb574711d466688f80dbd65a7bbcdc 810647213c7f596fc84d0e094d6429d95d7da6ee8eaee958d7c329bbf1d8bf2a5cae12e28ab3cdd0f743e5864504df39 +00 00422131829608ff730c24ddf7e8b4a2600eaa9681eaf45432daa7d41fe2fb488fd0199d431a1ed823801ce21f4f01a4dd4248ca 8a2996c086029df39d870a20d4fd1ebf9b54db14e74ccdac0311554cb13ca7a72c819185483ab803547c1140327ef1ff +00 00095ae8e4c7e55eb5da01acc05ecfe72a4dcd8ec152f1c8dc165014f70eb4e4a7861aeb2b96c418b2d4db58659e76184e013a49 8ec241267c216432a48bfd403aedc117ec7aec7aca4001d5677f45caa68c7d6d496f8f1d9a2e56ec72f1a02c01cacb97 +00 0006f2075bd730f34df111ebda919167b1d3358ada32cd6747cb3353bcfb814a77ac70cd51b31a0e538539453bf9eaf9d8b384c9 980a6186d314ea527e448a9df07b221b4fef74b4a07473a190d7e8195972874de272b91723683dabb13eba24cc4bf72b +00 003887d284e9ad17d38bc6da9d83c192a434c509340a7f233cebb032b09ab7c4c6e8730b4a80844898616c9abcd16b753c6bb4c5 a9b50b9a781b1f7393f00da3477c95cf0afc2576d6294e095689b1ff6b9d99934a29c58f91afd7f03267566f380350a2 +00 002ea5430610864257c9dc393c3addcd0d8d5bc8aab1067643b08857210464428aa85cf1ae6c743fd2682255d4c8eaa46ca21e73 a85743a80f63616c14202587358e90a6c8f2f64514c6e8fb2f046d5ff3d9810eb81c5bab052b80be212acdd6f6d2f47b +00 0062c757c92eaef41f5d81169ec4968145b5aa2bc1d2a3a5fd000634777748ecb93677b3da12e3be33272a8f0a52300f4a5a37c4 a63929a27fd07c03adf1158d6ab79e083709d7fd83463ebf2266cc2ce84f660acd1c03194a627f2188a5c62b8b8c9d01 +00 0048a313c0c11489939fc0cffc6ccb9f179093c4e13141b92dbbaac441b7ae878c9d412066e95615174a24692555cbbe904a14cf 802ffd82b3dac32a94744982dcb18f76670d8ac0ed97c42e36b492554df208e599d6a53c290255bf07d823ce219abe20 +00 0046e2adfe5d3549e1e6fa1fe69a7cbb4ac9b111c8903d544268f8318b0b47d4b78fe3e56eb5e639ad5382e7cd5bd4b2c3e70ef6 ace7611e53de07215712721f3101310187110957646cd1735180286bfc6fa2e58b6b48123937e9edbecc926a9c845106 +00 00480103fd6180a431c837643566706e2b9597de0a1346a224d176a5b2c54aa4d064418ed654a5d39f4773fb509f86473ebb373f a369d4ff0b0e0661058f98b530b848d3f56b426f280dcbdf1d87eb8efdac1b00fb7de5cef66364c3c9c94a28e785e3f7 +00 0013c489e8311c6bef02c8f58903b2ba2a98a27cb935d75a30d320af9a14fa3cbc6adcce09235a9eaf333dd05f4b2f1694985dc4 8a0d350230baefc2a5e411e8c400faf788c8275978762a415f97dce3536ec5268f6d406d9b8db2afab25c6ba9f671eb3 +00 002419bd2200f8e1d87db848b0379741685e680d9affe693eed49d82931030b6cb05d21a4965f4e1df2045c8513a8f574ca9f2e7 ada9e5f8daf7858f5be34d69f5d47b254a7f0b62a32fe01ff74696880337d8643c83bd040340df28290d578fe96aeb0d +00 00722951879a65bfcb414e11712ee9431eeb32319e0ff28601112f89276ffc2b96eb65c7fd77d023f09914a53e2aae2c84652bad 96ba3e59d94848d4a1b24a8953327b6e6276a6e94443750b25739bd61870a78f6a202e9399d326b6980f93be6d907743 +00 003f5b5a772d24bd5454bf26759dbd433fcc7bae4f5c593664c4d75da0cdf9430d7d9162bce3d7f6e13a344259da5a7d6a1635bb a7da4fa88b8f80dd884334b3a6d0ad12e3ebb6deca1e53dd869ac66916e7072a502d4f62053d4543f66f32c7d02caa5f +00 0046bb4a141c9099d531dd23ac440eff1f5b10f7cf34920b6b702311d490d25344c665ed5211d401def24986c8094165d10f8934 8df859a772f64e7ef8c3eaa3373236aaea3faff14cd673d7a3e370cc2ddce537483925c28f5b753ba95cad8db90f2755 +00 006f2c6e9ea8109223d9a349fce14927618fc4fa95e05ecf9aba1546619eaeaca7b5815cc07e97ae8cd1e9973ac603f84d838393 818a5c30b53cd07fcfde65870b6c28b6afaf705d450972e56747cfe421c014de8897e4214cbcc23c72830f84f6d86358 +00 0004212b7fd913d794fc6bb33e0276e349c052c969ecbf6afc89b28f75a599a9242acf74dec9f374361ba296ba42a38407f9b7d6 90bd9fdc9d75eee9a495f3bfba8177c9659750afdef0b6f8980a818e4089f4f672bb1d9b1e9cc1f7e5692ea65fc352dd +00 006baeebb5ffc89c94c3e8b37b9b0904e7c4b251d204894655bf3b1235710215c29820b9d401c9ca7df1404d2d62d708aafe208a 91e01f89df8dabf2c058234919edd1f08fa54cb936fd7381f7add0216cac6f9fca54f6110671003233b02debe9e146f2 +00 0008e5f66ba53e7caad1feda122a80c32c82d2c32a7237b8ee8ead44ea8f2f01d77c7056b9dd60b92d051f060da8532c1fd0e8f4 85439ddfe95fde1224cf68245b26323d74ff4e462d69daa23290322353c8b64d1f24aadc6a3a13c1a739a2f67312e728 +00 004ecb22b44e809f89b16abb10be062c89b41ee34e110403e42a20ce59a99afdc22f6f6dda56e1d9d1b8ce1d057f390db111def3 b03a07ddba87b2b93c24625671254d89288058a8d6be728956590ce559979efc917370f4cb5265658404ccbd19e46df7 +00 0051f9500c15ae73d6d479b9f3d2caccc2039d8d03820befc2aae3bbaf65d59bd9cb3c4e3aa8bed5b3acb70a5566047ffad80729 b1c346f883112571dd3d9ed9e0f6b99da6ccec99702f3c807debc9a31762f18a9fab1bf0847f4c0e477ecfbe5e0aa711 +00 000cf01dc4462cca764f4f8cbef48c51980737b9b98d1384b8de9f4c733829db7718a9b5eaa46a8475c2144fe4454cb8eeb0a443 acd92e92276400b39d64e3f712a2dc5533439b11dab8cd967216a457b7b3d3eb1788c944a65abf8cf9ca84f3172420de +00 0063a9a565497974c6dd459bea0d1196d74f263f333c31b7e8591499960e1cd79e2ef4cc8709f6d54713f873b16e7b0be42f71c8 a01b9c86c246c601b8d7fbb897019e60cdd3c6419557df6a1287a1986220c3163b4e85ed3cee0bdabd279bd16135e886 +00 0041074dc186193d30aac7cc6d269b938ab40b257d095e54ba79967a377a91b8f73671470cd07f0a3d1db7cf0a31ba9070625e43 b56eae09a3542ecf3f3a8dd882aa35ee70e6dda2e132eb2bddce45d313c3e2095b5c432042875de50bdc1fdb5a65d42f +00 0010820db54ccf0226161aeaee79cfd2797f87702b4ee91adf8543b3c9e79579d0df8a889e366ec1e0718e039b87a37c24d620e9 a2d1169774633b0827d1a3ff026fd27eb15b7db096e30ea3eff5ab47ab6bf382cd5d1c7c7051da9281d90f118497fc04 +00 0059d2a06e8bfd5e14a9bc8777958b85be5e97af892d2cdeb0ecbd2d5017952b5042349db5fedba2e26e7b85bbb31ad313d99434 aa27b65f9233a2768b772f9c363f5f7cb968abe23987a4bf4e22e99dd0f5429c3e220050602a0c6e06ef7d1bccc32a12 +00 00405590893cbbe18f4ad99df28b5f9d17f8f1882269aff0b7eee9392859d68927a99c942a3075269ddec6d69c0df2d76ab9d801 b03db39abef3c9bfedae600a315177380ce1b971f7f95ea1d2466fa6d78b6ef58a80f026be6ecbe43fd319cca8c3cd76 +00 0062bbb4f565aa0f23b88ab9029d33b995729d10fcfc33ba7c4051e2fbc72f15636a834e3ebfe604b927cdfc89f53c57f36890db 954e6def26aa8327941c8dcffa734226846e63b5654f329c971bbf740ef0728d5faf0d99b1e2b485be7684ca0a9343c0 +00 003fad7031cf8810544a3e4bd1382c0a2e22c5a9fe4804ce67b27591fc516ee81dbac841d399327168aa6abd79e2b5ef85df1528 a72cb1626ffe29f46377760dccdc29995b96a9aa0e90fe2eb4ac855736d896201d27de5b8bd7b9d810f2307c42ed71b1 +00 003db41b4f637fe7977c90e4f1a21799baaddd1826c667102414877138436cfae1b9959842b8097b5276f15f2b982ee59df263c8 a12da54d39499f30d513f4026165a0d224ea7bedb2a146ec450d2a45a2a51784b26f0a42f26589d24c4331d266c20cca +00 0065b76c6093d9c49591293471286df1a4444e60d9d06cfa114e175afb5f119d2abeb273b0596019a0ec5db5b5869f2cc827b364 8230bef49b3d35764233ff77d4cc809ee5b5f31eec219a447c2f9545a77048a4467788d81cadd00b2c1f924a65e9b4c5 +00 007e9993f3fc1fdc4c376ef77ecded96006ac1159740bd1b2dc6ae3d97e15a67383f1fc931e460b9af3fe14a54e47919667ed06c 859c800d72bb6429cf3ea97f7934effa6b66dde43c98e8bd852ca48bfa06db283a1ac2f09fccf91361b06a2023b5ef18 +00 000c11e2979498695c660a2bdfd105b115bc4ff8664ea15cfb40c725406c6fc9a13027bd1d72ffff6258f29e4e19b845243444a7 aaca377cb9f08a18f2cec8ec0bd817f1b141a1440d32e575acd9b33b641d364134c6e65e2af7ae36f71c9f4726749ab7 +00 0068dfc23c6635bd1fa1076dcbd456ad6e8df7ce7c1370fe275803befc4ffad007fd062a61cf1d50b93aeb9afe1aab47a65af82a a20a5f75d7126ca3a054a8873e8ea1cd70d032a03909abfab62c73e17e768e4bcb86bd01e8b89b3b204cd768c70d578b +00 0040807fb888e1d9fd33604546656a493629d94d4a0a9de2608962225ed158167f9e2438abe2d12a11e2adb6c2b66ed78215b0b1 ab39f6b877d0b7dcd7b35c3e5e8125946218cdccf018983f6117aed225f14ba447858264f3467fec8ff7645b81471f46 +00 0033bda0a02badae08fe40c239b9d59e5bfe1c4d4b9b7a5acda6790bfd77ad08dde5e93a2da80ec54a7f88146d72218bbb88aa10 aa86c55d849197b22210c7e8293189507981f96e9bc634067e5789107b30761a3689ab890069b676c3f3b56ba700bc0e +00 004ff431769d26b8837d3e1295f5464fe82be29edefba76323e92078a6483ea0daa96221549102509a1bdcfd46a5a2e5de10c39f 8afce9b29e939062abea02db6eb73edf7772d540f5730bc851ac2543cf52205f2f8b1b72076a2718d795abb1f83c51ff +00 003f85ca1169ca7e9df44cbc6bc7d2868c9d94e8f8b699a42ca492dca0914eb5789a9032218dcef7f95f959c9554a1cd83360439 835f44080133af9f34abeebb27a10afab6e259082c1c1c7f196bec59011553e20aa22b861637e5a59f326634a4f85f49 +00 003a97deb36d68f81f50c8829d412ee5de7f9d775633cb69c09dac558182039e275fc258240517a7c4aa592e364765321f27cb12 99a24dc254e3a2a60b203ba30dc388be6b16a84eb553b553c42e4148cf66c223237f454de3734c7d91ed683fe1b5743e +00 003b1da0ffed24e1a3b5ba22bd684337f6b08053591620541bdad50c761d66201a2cf21a4cc636426456525b598e96baf97d9851 a8ae621794d170d983b7724ff63ef0faba08ad231a7b8d959bf975ffb80acb9a985cb66f3f7fd578400d91a0a615a5d2 +00 0040bac7e0d3b54c7753c79d43469e310d876015d948fac4e3a9765444754476af72330e88d79ee6119697aafac8435ab5690754 91ed7a5491041efab38983f9b3ef0f47f85ff2ee6a8f425278db7114c4b7015671ceddcd5807a913d514dda371ab6e98 +00 0025b7eb3bdefba3c5134438caf968f615b315204f348006f82e8d61057a8a8a853230cf0500f9d0b8c1551a59b9184862dd2ed9 94b9245178d45cd768350fa153afd4aa2a2c0a6f59af33e4a368daae85604504971b42fce3cf71bb658f820585876d61 +00 00673b3a2985c95904732632e5d988d8d437a60db13215bb6aa880b348f011c609a1e860461427a8cf0d622abc47f910f5c97ffa b58ffb793d7d47116fba82fd7ff137303ec16fc21fec2dfd672cefbbe17c164efd0fde5ce9d885757311e41d4644e427 +00 000db7dcac414010b816236cad584dabeaec1da76c97182d1b62f87bb7fe2946a64d10430571b2b29ccf2ef72c969a9f045f1f3b 98c4f0c9edd537253fa2aaf7f0c18c49269663462bdf94f07db819b90d9817963c242670d5338e96d7cf04c807f057c1 +00 004717efef16e1ae267e155aa1daabafc68515aa391dfeb73c13d01f3132bd22c984228dddc4dff4c39979e7585acd3f730cfcfa ac69a1c7df8ee532e3d5b6fd0bb88f04a916bb9f8b91f589cb0cfe95f88a4b25b2ca9bb434a731d276aecd70f5da0c3e diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K571 b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K571 new file mode 100644 index 000000000000..5d6fba2be35e --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K571 @@ -0,0 +1,60 @@ +00 019cf4f4d06825499949f9e0b442586fe1bfe3459813a2b92cd8de0f775a4735e02655702ead8e60824180761808d9e816d60bdb0238e1e8039ca7bb63c92e1cf8433ef447e64ead 8fce58737ed32b1f0d91b5b48c1343c97be08aeba330e93dd3c77faae9cec994d1c2dcfaefe3de3ecd119814b459706d +00 0098521a732e72ed945a549afc92318fef7156ed1d1ed9bab93b581478cb2339eb32bcef705c9bf61cf2873ddbadff8ff3806740a2e30ce67d1807a8179dfd5d952e6f8a583baf81 95363fb68345cf83aba086b45dfc9bf4031c310a3272f9d6cb9326b2ef4203922bc56b29c7936695dabe6c8c8ead3092 +00 00336fb21549e397a190beac38a1ee10f0551952da15f71e11dfda415e5ee08da2356f114d450c661f52b2b32cfc7b9be61732672691a079f0927989b7e9f4efe6095a242155b641 845f662146c7721d3aaf3b05212f5adaff739d0f9bdc71084825b071bf22f5cee56b6bab569c1b3cf9ea0ea0c722aa6f +00 00e287ebfd9ba294128cbd484fc5121d271cd33e685bb1804f09b40aaacf64b5a9f2cde9b30a4a02d3a9bda97d92f46bb8787b3c61f280b1e1a0680f1f0679d3bb34d53725d62e52 b00da4437f12abaccfc4f06237f33ee7f216440c5d97e9ca357f1285cfde5bd411e9926b5197656c26a4e8469bbe22f6 +00 0149de496fa8f88b2741864d0c35b3df666b87179b7bd06cd426a45f13bc87ea9f50dea85e1fd02a532630e0e3a231cc3e7fbb7c7ba85b40cff1124e72c677c6a3ea6aa40ffc64b7 a98e219730540f5538d1ffffe333e26b0311a9eda9181a5a30b96c20e3e70ba3947175070c90e9d2376d2c7fa5a93541 +00 017605d7c5873d870462375d741b4bc6375f3d47f7f5e9d998917adf2137a81e63b66917b3dda8968930c4b850f2270eb3187fc756e2beeaa67fe0d73053e6cc0ff0004a21250551 80f8325744d87faba4aab8f7110620e775725f0fe1ea9716918ebe3639a83e180f3278fe0438293ede0935971eaa7d88 +00 009214dc2da0967912c31995cb8f5bcf4bfa832c5a2d3610f3a9857e5eee7c77100d599d9ed003b4106013155dffd6c48859b846e45e0ddbc5fe24f4891c9b2df51407e9cddbd974 997c90ce5bfe4beb4eaae823091e44e2ab7f4486f5eb09e003525659679d3e4417dd02d271b717f742dbbc8170762762 +00 0042f2682e9ac8b76f3c0880e12c292524601dce9ea6982dcf68bfdb0d3fbfb50dc9229e54149ef09b95bbf624eb04ce1427077f30d8536be9f69970ddb449ca22ab8368d2689ed4 b2d4553a1ba10460f38bf13fc58c5c3981c5f46f9f77ffa8179da2e6235a2c2a5273d33b0a6619de53fb8facc51187ef +00 017ed9a9c75cf66528428e85b0f019e3488af8b893b12023ff1b4ca9c3691b74e594539afa0f4d7c3863d15399b862f15e27bb077392d6bbd546ddfd46728c75177338466eb2f4ff b1fd43e3873b8304af96c7f2040538ffa04a1d68e9f5c542104d56a0873c427383d1a62165efd1c2691330f0f9d7b296 +00 01bcc09b3f2f1d26ab9955bff7e8c0f85c8a61293511a196b53d7963f4a4503849c96fb4daa68c9852ad9185e01a35f0bf298e34a09ec352cb6da34f89a1f23e8ea27712a8f43aa7 915d4d565f1180b12a5af4cbfaf9e89ada9fc240345c36829542fc2f6aa4b1368594982ccac0d87611e894f25a1648a8 +00 00ec52fc3d9c272ca80623e06b15c35f349b13548ef7ee400bbfa04196850b3b8cc7b239238c827f9b0a3160cd97969ce21d66752791f5896e0385b0527d4d77e4b9fc70f04d73b2 86c61c18070d0cd465927f7f892fdba7e9c311291b79b72324b826b0b2a8ec1b8a4c584b90ca58b25025ebc701fd08e3 +00 006403de7627de22d1dcf6b8da5af62f9ec59ec065cc1ca1311bb98aa439a6d5985619b17c17a70f59e17cf180ea6828ef57f5f1f8ef05680a9fc12ab7faad5af61e4e11fb45d341 aa128ed3c327df9a1275b5a97bf87d3b45e072f74a1fec5723afa1cbff3d3d96d3a87b30e6dce01307c51310501519d8 +00 001fb980aef64254aeb9bb613ff2fc6967503db4bc1f337882f1566cbeb57489cf32e34f310549f41cba1b951f487453c29753a184e33330e90d4b973d2e406c99a239a5c3f96233 ae18a409825d1d2afef8ab95b59d956e5c03ba1ab29cabb7cd04955e7aa9612af8e97b980e9ba8472ccf9295056aaae9 +00 01d96dc09dfaf602789c1dffa5c9ba130832badcf180429660daadf4cf1be5cca92fe9713173861670eebfe3a0ba25bcc76aecac60a756f07b69687e05c7e25984a39556469f62b4 b189957e8c48470de10ec0dde050b863a7a9c552fd5e13c33f6f38323ec8458d82ce906b7b373079bf4617ad9ce74aba +00 009d98b32c8eacd135ffb8e13223690ef02c0c1f29ea8b4da193502c8cb3f39f9eed608c02fd457f2fb685ec4595e8fc8f388d26778d225d2b18c9bc8b199d8b65c0d1a6af33854a a9ff3041ff3e8b69b65fc9c0600407463d33c1b245f32c7592e785226f2775b95483a2dc35191fa348235e940fdad2ea +00 004d873ac744c4f68bb044783ad69e1a733cb8b8f483f2695bbd90c4211282036ad7914a53b25c3e890c6824643cffbdc4138d7ff457e3fbb99387494eb5cf2bdf1ad243a3a1e644 b726fbccde423ea5c91b770a0e4936717b069f6d65be4d0ebe6875acc4f9adc3f6746a76e4cdb7fa8297a4a7ace7d10c +00 018d2eb947297a054f8a789771dd875b12b26ef057fb91235dff3b062916f85aab3365609bd2a38a861439c8514e33f174c198139354e63766942f605107cb1b9709b782622b295a 8ba45e6c922ad54af9a79dd87d96138890d25fc1ecbd02bf9240814d2f8b1f2299b20841120471ccd5978fc93438ea2c +00 00594fc0b7a5cc0216d2e78eeeb6394c8225de795f4b73bec48b2f4ede185ba622b59a16dd3eedf8cf2c94f2ccd6dcd205f64c97cf1b7f1e34129e94b5129502909f43940dba0746 8fc46cb2db52e8900ba63d4d02e0d7efc8a996b4d6011a5abffc60f056e32c94dc01b12f20678fabfd510030d2380a4a +00 00f000631106c5851e8ae0802b01e7a8a8540b427a8a3956a1d36f0600be89318032320cc420931d825cc964e823745c60aad3437ebc1c91d32004472e9677605fb708e5a71a0d83 97167c21388f558164603bcde7d06fd8fee3ce717cd11b01d750fc85dc6a8b9f192753a5bb7cd76b6ba29eade2e60c0d +00 01023997206341c6147c536d034a9c38b4012035dc2c9b7ef0bb9cfe65e7d788296f055d508a1fd957b2dc7f9eb10c27790f15f30d81670945e54a508c57b70b46b4a09f4c769289 847069ff39ebc9bfbdc3e3fb069a79fed82cea0b0c2fc840b0a7950273b6838c3b141ab2459fb829be7297329fe1f398 +00 011ebf320ecf6a908ea5b868afb8e22246ce84e743e1076d6185ec65dd79043380708bf8da4ba802c3b93b8d15509bb7d7de9dc29f1e9fb0f0f2cb97a26698f955b1f7ef668122be 90579b372336c54b607bccd2f4851b2dbb67787357fb23727df271458f3fe757e9f6202bfb0cab51dadb10d401d13dc1 +00 00746d5c824d78f42a1fd63d8fcca61f154ba3e75788b7a0b87f53e5420e23a935b02eaf67bace8dd8a8e7c1caee30154c2428e0a437cf12e235f41c416f92fb54528865fd4766d1 abb7285f6638661fb6bc0fc13d05d675795f9e8d5d08fc92315a5faf4a7d7cc95d89a7f003dd97f7e872b5472d489f95 +00 000670e72ac2de50dd2cdd975a6cdab10ac45e37ef7a28c685d77447051496b5e161f8b1b93f6c7f32fce8ea05e94ed35fd7cb28c44bf51ea29cbaf5aaa31d6abca30a89430323dc aba70bacaa21fa370221fc955f05c8a7f0e6496f8d434d9df6b8deaa318597d50247122e4d2490ea2c1fe2e9d852a116 +00 00369a3bb96f884983c23281bcd04e24a3e5f6359f81e3c8e46f3f6b865eb6bdf98a630e90646275c587e41b546d3ca7688cc207afda15cf9b25cf83bd6ad27908647f3f9de59de7 a42f8010ddc34face204df562bbaa2d19e354d365b55270a1c6206ef7150e6575c66a7099919eda9ca453498c6beb95f +00 0026717b039df834855511815d5665ff9b654facab469390ae257b7f0eb4dfe66ea0dc037242ed0c13bf229b8f7ff26da9b55fe4750d3451c62804aad493c179ae45d08ece5af085 8f514e3bd9218fc106d5e3f2c63cd6c5cdd194dede870caf72ac9b55d824cefed5d8cb1b2c9f4075dcc31d50e1aeea2e +00 01d642f2d393ed4abea37173e4a79534af87adf534ead4a0a1c46fb047619221e3577e6b8bcc776114d01159c736ab78af3e53feac339d7afe58be8e7a8ed290f1dad960f1b5de94 81601782a26e2b7a4d61756c54a36696afd7f1f8fb85ee4c99de37fdb66095a60d4b654cd15dd4106f54e7cfceeae096 +00 008cb70be29e83f697a3e2f67d86f1c1ec9a163b5335cb4a06004b6634948bf60b8ad9df9b27d2bedc4975265ce44a7884e57082d521320ca4372d38fc77b18d3fa05ad8aa5c43d6 8083c70bf7b0657207004215ae8edca5e8940674b82d4a8a633a8822f82fea26312fd1fb7ea18f34716e8e943d8d9674 +00 01eef463771f9c6285f3257691dea0844687606d4dd00b6020517f190891cc1be97cfad21d147ed8881b5a6e19b22ceeae30e1132476325f2de0e9af2e14c80b8c780a9d2d6c96de b9596baaa40f10ba976ccb71c0f30d2c837addd20994c4aac6f099888da29191973a147ac0b7fc3aa09c886d116432c2 +00 013bd452b0880b101df1aa65724fb60d5d85b37ed5419027481661a3617e0fb37bda1151b9b5b41f908ba832011f7850b75a07b678e5b8cb35c5fc8b94a625e4398cd5ada2b04cc9 a7d0c8f9553da925f5e58cd16a460adf0ad1cc5fc6af767eab963cdeae5bf85ee786236573a478fe7d807d4f41e9dac5 +00 01288141ec2244e4bb3f62daf4ee588aed09ce22be55e3d42e9085a947c1f8cd16533635d170bd64ae0b417346fa4670c25d41387acb2a8e14407a1931d9f7c5358a14eca40974bb b1dc8554685d7b029eb9cb35134e70c9e6abea73fc40490a3566478f9817a629b50e391e44e7c8feaf64153813012aeb +00 001fe06b94a27d551d409b0eb9db0b163fadcf0486e2a6074bafe167f9a3b4ce8ac11f42cf72f9a1833a126b9473163d29bca2ad139dd1a5e7fedf54798bf56507326fae73a3e9a2 a475ed0b6cb14d1308f1cb0a72539f8b379e88f97ffd3a1254a21921e7c0b5e2895e53542cfd747712840763873d1159 +00 009cdc7e4945c485a41728f83d5188f539e372ff4fe38fffcaacbcb4522428e4f93ef4972556f4398fe17bdd885768f0fb5590df495badc794d4d274e22f2f4a2535555922fa43f9 a2524eb676e9b15ed4b77dd9160270ceca3dd112b7729e1b12d203385aecc000589240e2ac8d862747d8a6a286a3bf7f +00 002bc753d007c4491cfb8ce0a6c96455acd16d37e02c982db216b8cc1afd6d10c6be4e15a3988b8b8b86b2b5b59a5c1939889024849317f27ee08a06bd8e7524d4ad83a1de208564 857a690257125610f365c69069bcdd373d863aca08ff8548fe6bcb05f50f243caab3b6be5afc43b2d8d9bce887c7d048 +00 002082c6e61d0d72f040905d8c1c20d47b029f41ec68d6cbf43ce97c3b2a0a770557a33cb803c432cfbd3958fda30ec1bba77a6613c318597a85ad02b26c44bb77ca96d9cc1194ea 867cbe0741ace99e39b20baeded0df1539cac36cceb11e302bf955d47276554ef3d926ba75d254baa69343fb161d91e3 +00 00e298c93351323e2c5304015a4878997ae4e79d1c32f1dc64262e534d4f2c4b3e222356ffce746763373fdfb936fd330d3214a18c07f1205b20c9a941331cd676040ba1fe3dbce7 b0cb2b387742539586eb8cff23ba1de2a2de5c074dab1f1b144d6e92bc588f005a49884044ab5bbc4fd63783950e82b8 +00 0104f4ad56594c5cec2a988c5596d73adaa5a81802b40110dbae698ddb1f0b271fd1479c38abcdb9b234e69cd0da8a0328d2135c287d5b130a09fa0b899058e7800eb2dfcee95c1a 88814b5bfe7ba8a6c9e483151f53009a837ee9dce03b1b683480a94f012d8e780273e3b8584b5c788648f5d820b7ac79 +00 00c4989bf33b3136bcb4ba67906eaff2bcbc6567635aa4b057acb7353ee87ba3cb4cb9838f8f679729d5c6ed98e6c4199cf58605f009c6873a1b8321f83cd3c0973b7a3cfd9dbaa5 945e87737b09f2d43a7436ff33a5d412ec50d268bc05b4479fba150de1acd2e1024f884d0d14d8099a7ae2612a5e1220 +00 01a96f2ad56e31397e236cafc108087479c9823589a5fbc3dc7488d0e5d1199cf245d7f21f524cc0e8b47feca14c93fb760e631434a91188b32965053942f3bd39b3714f9d6f1a11 a766bf3db0a7fd3a7a7388004839eb64ce718488a5f3d7e6716bd9f0e74fd8b64bdca03f1595a4d5cacd053ac8535f4b +00 00c08ed8e0e0f8b0d0714b46a2164b933f8147692f18da97e5a108c44d5a5cf221cb50536e41832b83bff4026c6df156386235cf5e3e9a67b7cf9b2fa7707c5e0ff33a91601b8e34 a984b176d66084f2ac13d4ab03f2bdd8412e184afc8bd8255dc87880fc2e9f92d979ddc99d374e572318b831405275fd +00 0144090a0ee38cfa21fabcc24d35139a99656911ad4f6dbffb77dbe74e7993edfa9fd63d2c4f6bbdbc8ec21ba13c9f4a3576b5d6e3abeab5af5ac81b1f2bb6d4c42dde645d854d9c ada6b9f3e096d7bbbb17e15f276dc1f6f9c40f2fa1b7c4d91dff62d8bd57e505ae177b8ff1a053b197b238b1522a10fd +00 01df26b672b2e3617b6b6c631d3c6be0cb49c0a690de49643e0f416215bcdaefc03fa9c708471f1d87476d58c8f147517ec8a14aa945ef001fa01984d5c3d81f7083ea500558fef4 8bfe8578264f74233b4667c35d8435f0899aaed5c693e6b2d24c14cfcdf42c6fe3bf8d2dfd0961a92e4157a47f6eb0ac +00 0189918b832e9fa30161fdd927bfc267f6405335df3d66d225e17173af52a671138883bcb94c4403ca3e001fcf09ef4c6488934d6775af2b1da30a8f331579af2d0fbb530298d8f9 a62e15b79cb8c010146fedc89871cd386d6b5199722ffe685708f0e1bbc55591b172faac99c90202caa957a48dee4e32 +00 00bdcc175eca3a399b944eb0334ff33c4fd130999c8ac0e7b52ac5b774fbad53ccc3a31024f5262b2eecfeb2104b14bb244307effe3dbe8ed25686dbf46a42c4b6f8e34010ad826a 86d8173e29388e00b171f7d785b4c83fae05e983ac2595d971d6bfc6fa8f2152b2ecaea0e57f4686a59de082be6406f5 +00 0007ab5a55a1d8ecb7f5dca2afdf9ef465569a4b0374716f604ad42a6e0271e934b09655e8e2529784b69b2894bb399b02aeeae30e9e7ae70a2a8e56b9e775bd978a04c728e3951e b58b1b7ee57183eec870ba3603dcd66991d78f9429a5aee2456a39603fa51662cf499889c88e167a842f7174b8535831 +00 01e7d4da72b1d82e17a066fe387f2a0a7fa4c60ab993ee09710531789186077f2f32b42ddda497d5fb57356383e1f96973df043307f0b6519430c3f0d40d62954032872fceb7dce9 b531159a04514d494cf5fc09c13f0ac0fd90205e16d6e61c81011b21e7ae956189b31129ad3b2fca05acb6d0c918e80b +00 015b7271d4319db5743119c8103a7d4c6d57e9c62f3eb93762156d2ebd159980aa57cea948e416717d715a2e458851f1b2e9ad4172bbcc53861db29c3ee0ba8e82617a5866170847 98e25c041cdd8d2905c97bbee609f2d0e7b29e4e4aaf1fd6e491f36f7f1ab26bc39eabd65fc22b11e8f0800aa7bf6647 +00 007219ea7917d174a5386df985d0dca798ac9f8e215ab2f0003aee929a2dbd91e37fedead0ed95b1e8aabcf516bdf54337b4aff7ace4c6b3179f2e919a49db50a41c9d4d58d4f636 a94374f270fc94b809c84bfd53a48e27bcf36b3173dbe960b54d13a565d32b54af863c2f4c72cb64289eee4d06703cab +00 00bc623152253da24bf8d752bd78aedf7d5f6a2f889453ccdec14e10753335ea8bea83fd181a1f3680ed50f2324fbeaadae160cc85831750e021f3e44121ea1b1efc29a7d0069479 9701017bb85cece6db7fde9d05b3febd1628c5a54ac4d9d4cb201d63b2e0f8def8e6359b7c4d6c90b8a13e06fa3b259c +00 00645947d981d258f2954558c31022a3b6ba5fa7b675312f794cb61bfff1d9ce87267e4a1dacb7c8fc58624d31c85ebe22f80d26a620fed5df5bf38515e0903f0b69a606048197d8 8c11a0dd43ba88cda6e5d7cb0c21f7c31de7036e6133213bd28727a7d74ae9f3c9c4d8d9d45f61a9c5b966352b6fd261 +00 014cf93ca69d94ee8fbea0c8da9d76aea092b73073d8f5385b65c6dd4d567fe86bc2cfb8e8be890c3c6cd9abf7dc3a17eaecee3d7a9455887863e496c48dc3e47821bd3d825b6bed b75c0954fc167b2e5c8f519088aef62577c8a24ccbd0299cdf04d25d92f8814addfee321cc70c140b2ad3968a3812ef6 +00 0033feeaaaa28f16bfaf5ea9c7319cf4561ba4fc55327a8477b6cd58ef6ccad3962ee1f3edb243f3a04e7e49c8e23509fa2d63252adb186b8bc7e9255cd61fa9bc45242d42da3a68 87683c632f13c0ab25567f34a67548f5a9db6ffdcaec4a64c01e45acd3c053fbfa5b649ef6ee39f42e8359b255cfba55 +00 005613dfb53149bf5fdc4e08ccc1c752b0b66ab43aef2d008ed40f3df40fcbb2938d2c41e3ea2dd4428aeba9059a97efe5593119673866a19d27a2ee37dd357e22b6bc849e7e22cc 81199d697915a2f1275d0663f95ac12e42ddcb78de8e9c7674fc15b4969e9118ae17ab6867124c4449020f00ff6af38c +00 011b92c8b72b86c51903387a65aa206988d443d1988253329ad3a89c902ff1ef8cf73b7f2e4aaa352443bcb833712d94c3e637ec12cbe4c2d4606878576b17fae1512fc77785b737 9776d8b02c6011312d8f4e7cab237f3a822b7b298711a5376bb9ff43910e664a569bebb57d65a5b1ac30bbf74cb697a3 +00 00c3c90d5ce4375a08b85575faa78ee6bbd9e5571ce5a90582042617b807339c282cdc3b003d82006264b1c08c20af4ad4549fbde53d262facb98d923d81b8eb6093374b6a1e84cb 960ad44e434b48f3886a4e2136cc8ee9ed7161c45fc4a2a01adc1bcce10d417469a083918b123b80a034e4ffc479382a +00 010f184c16228d9034271332178ed485d10b6aa76003efc160d63fea26fbbdf5552205ac7df0d8c852a1210cf0ba512f20b798827b36ad56b12a826fa7dc1db45aed264ca6822659 92ddeb2ca22b8c53ea78239fc9b77e3555289f36e403c0a538027b333f62b5e6c51018bf66a007a2babb93586f030e59 +00 0181baf9d497159f837cba58a11ca435c442e5ca792ea559bff9f6a1f562c05bf6bb5914afbd1bcaea75b35f88bdd832314b249a5298622c89462344d3f28a44ba3d059df432fc71 8ef867f234c2bf06e7fd41dbaf3aa5c1637979f7e0c19d8964d9196755350e4e4cf5876a5573a92c69fd3021febf61e3 +00 0083fae86ab96bce99a53e50b7eecff38e4e25b21c4b0f6a4986915de245eae24f16b6a00a4db159ebc27f5a6a072da94ab6be5bf75f5eb3f75c4452bf4ea7014392eb1e02706fb4 971e010b552d36a6f807554dd7c84dc04e860f42976427ea9d3a1e6243f03f4043d6d64f521153d13cec50f4c7cbd60e +00 01a663efa7bf4d8479bc535fad71e9b5e4f4281aec55967baa008ba17ac2f89cc3398d30573edef29d590fddce8cb157f655e92779f59e7a18d0327d02e7daf4c1216143b3688fed 829b4b9724dc7d983a8c4af5ac5b6f204292f3e6411aaa9507e16543fea537aaebbac2aa682cf573e9e42fbf44c33a77 +00 00088d1a2c0219696a94337cd56516252b74139ea0733b17fdcbf7692c3e5f6c3989e5da2aaed7468e65a5d578571928ca273ec3b6aa72cd196f560f05095cdc8346e5d31c4c2e0c a8a05b924b595428464bae3fdceff0eac28f4b846750895976145479fe52a93184eb48133e151792162ac4754777d9fe +00 016cc8a0fd59455ed8d4de561fd518df2e008f7dfaa5f7f29ac2489a411e233917b43eb3ebe2596fc824be58871949545e667dbcf240dfb5e0c615ade0179d9ea2a1b1ebb8ab9384 a8536afdd6a1a3583a1c46d98e47e30309b9156327aa41aae4b630e707e54bbcf2072e50745f6659ed587094d3d4a5fe diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K571_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K571_blst new file mode 100644 index 000000000000..63b5714bd613 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_K571_blst @@ -0,0 +1,60 @@ +00 019cf4f4d06825499949f9e0b442586fe1bfe3459813a2b92cd8de0f775a4735e02655702ead8e60824180761808d9e816d60bdb0238e1e8039ca7bb63c92e1cf8433ef447e64ead b946ece5579c40b3d8632b182def7b0f8d723d6e24a09e5dff00c4b222eeb801217f1943a6d6840fc0f1ea713951917c +00 0098521a732e72ed945a549afc92318fef7156ed1d1ed9bab93b581478cb2339eb32bcef705c9bf61cf2873ddbadff8ff3806740a2e30ce67d1807a8179dfd5d952e6f8a583baf81 8e80e0ce2347907ff0c9ef9e9ec258d49dfc7404b3be05b2a0eb3d14a41d37d426f8c5e6d0a2684dd0a79080be21fdf5 +00 00336fb21549e397a190beac38a1ee10f0551952da15f71e11dfda415e5ee08da2356f114d450c661f52b2b32cfc7b9be61732672691a079f0927989b7e9f4efe6095a242155b641 a8aceb21d23bd8df344a49cc905ff2ce0ce95a1b54715ff53fbb23a976121754a2e53dcfa17446eb7c5b1573558a1e8b +00 00e287ebfd9ba294128cbd484fc5121d271cd33e685bb1804f09b40aaacf64b5a9f2cde9b30a4a02d3a9bda97d92f46bb8787b3c61f280b1e1a0680f1f0679d3bb34d53725d62e52 8817ccd5ac1027f488ffc48e57659b22bd9b6f0a4ae1e592cb0fedb961cfdd8a8366c9aaf7988fcfcd2c6c2371eb1284 +00 0149de496fa8f88b2741864d0c35b3df666b87179b7bd06cd426a45f13bc87ea9f50dea85e1fd02a532630e0e3a231cc3e7fbb7c7ba85b40cff1124e72c677c6a3ea6aa40ffc64b7 8201910411c92008bb4ef606b92dd8fbe27717123ceac0156c7b27ae83bf9d3d15c92d63b09dbe3b34c7aac6f51862f8 +00 017605d7c5873d870462375d741b4bc6375f3d47f7f5e9d998917adf2137a81e63b66917b3dda8968930c4b850f2270eb3187fc756e2beeaa67fe0d73053e6cc0ff0004a21250551 8bfde3ccb2a09b253a79294d2e65e20de832435306608fa00a21da275d887ef8a8f384cfe7532a77ef7c96b387946bf5 +00 009214dc2da0967912c31995cb8f5bcf4bfa832c5a2d3610f3a9857e5eee7c77100d599d9ed003b4106013155dffd6c48859b846e45e0ddbc5fe24f4891c9b2df51407e9cddbd974 b9c372d30f339fd389cff228fad84192f952f517ef5f91505bb2d35ab58a6f14d5881118abf6d5666cdbe3c6d7a1af1c +00 0042f2682e9ac8b76f3c0880e12c292524601dce9ea6982dcf68bfdb0d3fbfb50dc9229e54149ef09b95bbf624eb04ce1427077f30d8536be9f69970ddb449ca22ab8368d2689ed4 809b279bd105cd627b242245c15f3be5175c9ee37561c632365a379ec524e523a39a0b1ecb53327b98792d736113392d +00 017ed9a9c75cf66528428e85b0f019e3488af8b893b12023ff1b4ca9c3691b74e594539afa0f4d7c3863d15399b862f15e27bb077392d6bbd546ddfd46728c75177338466eb2f4ff b0feb08df1f9023336120f8da9a87a9bc2b7e1a463a8127f2c6b3751588651373281aeed0c66f2d43cf31382b8e64c57 +00 01bcc09b3f2f1d26ab9955bff7e8c0f85c8a61293511a196b53d7963f4a4503849c96fb4daa68c9852ad9185e01a35f0bf298e34a09ec352cb6da34f89a1f23e8ea27712a8f43aa7 8a11ba4412955b1c6a71e7e09db223492dde51155423a95ccb9d74e3e19f639bd4e2ca890996d4721055c90db8357c09 +00 00ec52fc3d9c272ca80623e06b15c35f349b13548ef7ee400bbfa04196850b3b8cc7b239238c827f9b0a3160cd97969ce21d66752791f5896e0385b0527d4d77e4b9fc70f04d73b2 907506f9f05b99b024c202947757e63c126ca8e6516082f807a1d30c90318645aa89d705d22df1495fc5f82191b69122 +00 006403de7627de22d1dcf6b8da5af62f9ec59ec065cc1ca1311bb98aa439a6d5985619b17c17a70f59e17cf180ea6828ef57f5f1f8ef05680a9fc12ab7faad5af61e4e11fb45d341 977fddb82172e5be1117d6351e906fb9945b6afec1eb190f0709026a0db3f48c7f1000adf0448968da9d5a5ab1835bdd +00 001fb980aef64254aeb9bb613ff2fc6967503db4bc1f337882f1566cbeb57489cf32e34f310549f41cba1b951f487453c29753a184e33330e90d4b973d2e406c99a239a5c3f96233 b29f2089fe7a6a4c0fbf731e1e8d26d6ea47e621e6dcde6036418f462fabe5a54ba43eede76196ed9f67b5d9b3ea4da8 +00 01d96dc09dfaf602789c1dffa5c9ba130832badcf180429660daadf4cf1be5cca92fe9713173861670eebfe3a0ba25bcc76aecac60a756f07b69687e05c7e25984a39556469f62b4 952a8ee452eb4dde7658722ec601e681b342522954a0cdb6904c722ee09e9ab00e4646f6ba4801a7e0db9cea58656b09 +00 009d98b32c8eacd135ffb8e13223690ef02c0c1f29ea8b4da193502c8cb3f39f9eed608c02fd457f2fb685ec4595e8fc8f388d26778d225d2b18c9bc8b199d8b65c0d1a6af33854a 9796b6f10ace5e41d9f5740c494e37df2400aff48553dd0a9bfadcea8888ca11888b2296181539e618b1afd778cefaac +00 004d873ac744c4f68bb044783ad69e1a733cb8b8f483f2695bbd90c4211282036ad7914a53b25c3e890c6824643cffbdc4138d7ff457e3fbb99387494eb5cf2bdf1ad243a3a1e644 812b900b134e2c89d634389bb790c08fff6a6a5fe3b77a289e46bf76d7f3a3c93f7e2afcda6d417a5a0c243dc3594468 +00 018d2eb947297a054f8a789771dd875b12b26ef057fb91235dff3b062916f85aab3365609bd2a38a861439c8514e33f174c198139354e63766942f605107cb1b9709b782622b295a 9582701b301fbf8415f540f2a753c87e922351a8d3283179b788c5fbc69b4dc8eee0be933020dfad3880af235339cc98 +00 00594fc0b7a5cc0216d2e78eeeb6394c8225de795f4b73bec48b2f4ede185ba622b59a16dd3eedf8cf2c94f2ccd6dcd205f64c97cf1b7f1e34129e94b5129502909f43940dba0746 8d713c6f0c3192b65bae72ab7a6201b64a38bb38729529c63fba24ddd27ce2d0ceb6fdea12e06977d417064a26bf0699 +00 00f000631106c5851e8ae0802b01e7a8a8540b427a8a3956a1d36f0600be89318032320cc420931d825cc964e823745c60aad3437ebc1c91d32004472e9677605fb708e5a71a0d83 92ad7c63ed4c347440d49f8352269b2a384d4fca3f40812d59fdf1001a461e81a3dfd1bd785222517426a5dc3f30ecc2 +00 01023997206341c6147c536d034a9c38b4012035dc2c9b7ef0bb9cfe65e7d788296f055d508a1fd957b2dc7f9eb10c27790f15f30d81670945e54a508c57b70b46b4a09f4c769289 b720be920ba4b229a121c3a26b58188f5fdf81b8977702237665124f199fbc63bdc000eece2e14275c38fd7cd7683cd7 +00 011ebf320ecf6a908ea5b868afb8e22246ce84e743e1076d6185ec65dd79043380708bf8da4ba802c3b93b8d15509bb7d7de9dc29f1e9fb0f0f2cb97a26698f955b1f7ef668122be ab7faf3b693b1e974b44a4b9309d7aad0171854ca3cd3e3549ce6b40151ff4610d9bdc0fa1a45f6c4f8be4c940f92f87 +00 00746d5c824d78f42a1fd63d8fcca61f154ba3e75788b7a0b87f53e5420e23a935b02eaf67bace8dd8a8e7c1caee30154c2428e0a437cf12e235f41c416f92fb54528865fd4766d1 934c4f142e5422728f8ee2ec8dddd15693e3dd1f443d66d8db69e1e4ed427d709c2aac4c4a0d6aa05a411ec4b0eed44d +00 000670e72ac2de50dd2cdd975a6cdab10ac45e37ef7a28c685d77447051496b5e161f8b1b93f6c7f32fce8ea05e94ed35fd7cb28c44bf51ea29cbaf5aaa31d6abca30a89430323dc b8e9e35f7a5e8c185b7ff99c9201d50807477755147957ca1edccbfe93713ef0defb2019d4366bc3bad8f598d3dd1055 +00 00369a3bb96f884983c23281bcd04e24a3e5f6359f81e3c8e46f3f6b865eb6bdf98a630e90646275c587e41b546d3ca7688cc207afda15cf9b25cf83bd6ad27908647f3f9de59de7 8b9923b7e7882a70285804514ffa204399740cbc58ca490b85095c0108c367292ab44be2bfc363f740a507393b89a128 +00 0026717b039df834855511815d5665ff9b654facab469390ae257b7f0eb4dfe66ea0dc037242ed0c13bf229b8f7ff26da9b55fe4750d3451c62804aad493c179ae45d08ece5af085 973f616fc0b773807cb35b64f9b6516b886d3fd863e51f0635df33fd3ccd363129cad3a936f0570e44cef38daf2a9559 +00 01d642f2d393ed4abea37173e4a79534af87adf534ead4a0a1c46fb047619221e3577e6b8bcc776114d01159c736ab78af3e53feac339d7afe58be8e7a8ed290f1dad960f1b5de94 b56eaddce291f9cc4c8fe13b503656e0d96b87edf1ba63a25ee37e182d28c92b30cc4c90b1100c433cd94bb2cb02f8b1 +00 008cb70be29e83f697a3e2f67d86f1c1ec9a163b5335cb4a06004b6634948bf60b8ad9df9b27d2bedc4975265ce44a7884e57082d521320ca4372d38fc77b18d3fa05ad8aa5c43d6 a04bd2f6b352e5185ef512c42a482671c4895a57452c0030e4c2b0d59f88da16bd0792ab46708f9659daf822156fd668 +00 01eef463771f9c6285f3257691dea0844687606d4dd00b6020517f190891cc1be97cfad21d147ed8881b5a6e19b22ceeae30e1132476325f2de0e9af2e14c80b8c780a9d2d6c96de b08476ff085e231a4261f7d3bf5fb98061cffa8372bd4ede1f8815d780a5d148efcee55bd11a1bdc2d943b34b393d548 +00 013bd452b0880b101df1aa65724fb60d5d85b37ed5419027481661a3617e0fb37bda1151b9b5b41f908ba832011f7850b75a07b678e5b8cb35c5fc8b94a625e4398cd5ada2b04cc9 8d1ec5044815b638d55fec611cd698d91065e40c649647ca83e080d346a4645e58de2487a737b90cdf701418f2f80fcf +00 01288141ec2244e4bb3f62daf4ee588aed09ce22be55e3d42e9085a947c1f8cd16533635d170bd64ae0b417346fa4670c25d41387acb2a8e14407a1931d9f7c5358a14eca40974bb 85b0c7374cdeac9e517c5eb768a7233735cc9db81e5003476916ec631fc1bd7579e03c9be31eccb3edc617acfe6c9e25 +00 001fe06b94a27d551d409b0eb9db0b163fadcf0486e2a6074bafe167f9a3b4ce8ac11f42cf72f9a1833a126b9473163d29bca2ad139dd1a5e7fedf54798bf56507326fae73a3e9a2 94f22c8f65f82e6004a0b9f8929ad9dc76209ccb7fdba26da049919cf022b3e85d0277a725a15094117492baf82e529e +00 009cdc7e4945c485a41728f83d5188f539e372ff4fe38fffcaacbcb4522428e4f93ef4972556f4398fe17bdd885768f0fb5590df495badc794d4d274e22f2f4a2535555922fa43f9 a647125205355ad5992edcab4a3ca8114e6ba309c35e1a35b707c6c74c9b1ca4507352746148fbce3a8de2e7cb5fbd9c +00 002bc753d007c4491cfb8ce0a6c96455acd16d37e02c982db216b8cc1afd6d10c6be4e15a3988b8b8b86b2b5b59a5c1939889024849317f27ee08a06bd8e7524d4ad83a1de208564 a28cd707190f449e5f6601ec54abdb19f18342a414f258c8aee30549f35b21e11f8f2805a1cd80ef5e9a562c5062d4f6 +00 002082c6e61d0d72f040905d8c1c20d47b029f41ec68d6cbf43ce97c3b2a0a770557a33cb803c432cfbd3958fda30ec1bba77a6613c318597a85ad02b26c44bb77ca96d9cc1194ea a734561f14e668bc09bc67d8d1de7071096273a225c2dd7944e46fc080ac387cb3ecea48391a46603f1e5bde941fb2e4 +00 00e298c93351323e2c5304015a4878997ae4e79d1c32f1dc64262e534d4f2c4b3e222356ffce746763373fdfb936fd330d3214a18c07f1205b20c9a941331cd676040ba1fe3dbce7 a3f12157e3b9a01372d02cb86a3e42d45d61d142337ba5a86e5a3ac06d5dcdf464caff5545f127971d7531f8792fa5b2 +00 0104f4ad56594c5cec2a988c5596d73adaa5a81802b40110dbae698ddb1f0b271fd1479c38abcdb9b234e69cd0da8a0328d2135c287d5b130a09fa0b899058e7800eb2dfcee95c1a 8ba3d85de63820431f8a3defffc7c1925febba0052dd05c7e1b3b1f497303eadf678883e525336cc4e7368d4a0209c14 +00 00c4989bf33b3136bcb4ba67906eaff2bcbc6567635aa4b057acb7353ee87ba3cb4cb9838f8f679729d5c6ed98e6c4199cf58605f009c6873a1b8321f83cd3c0973b7a3cfd9dbaa5 88d425525cc77b101d2b651009c4a8834af31fb01256f5d3819b884a494390bd604f45a49a795d20a758b0922a78d41a +00 01a96f2ad56e31397e236cafc108087479c9823589a5fbc3dc7488d0e5d1199cf245d7f21f524cc0e8b47feca14c93fb760e631434a91188b32965053942f3bd39b3714f9d6f1a11 8f5e147838edf6623d55ca6988d0709d7d2f5a7a9f7ed0b33af57b40fda002adead5abd748ae1e2d9ad3253170e18551 +00 00c08ed8e0e0f8b0d0714b46a2164b933f8147692f18da97e5a108c44d5a5cf221cb50536e41832b83bff4026c6df156386235cf5e3e9a67b7cf9b2fa7707c5e0ff33a91601b8e34 aac1ccd62fab2cae14a3b3ca5c5bda44bfb9f291c8aff24c8021e713544e7c9ad9edbcb6ed2fc110729287ea57e1f3b4 +00 0144090a0ee38cfa21fabcc24d35139a99656911ad4f6dbffb77dbe74e7993edfa9fd63d2c4f6bbdbc8ec21ba13c9f4a3576b5d6e3abeab5af5ac81b1f2bb6d4c42dde645d854d9c 818da8b9cb245697b0eb6fb4dd78bfeefb5fdb45dc885545c9934c76e0022c4e3b4877f7a3e2cc4ae1866e9c293f918a +00 01df26b672b2e3617b6b6c631d3c6be0cb49c0a690de49643e0f416215bcdaefc03fa9c708471f1d87476d58c8f147517ec8a14aa945ef001fa01984d5c3d81f7083ea500558fef4 82caf3eb5096741e89fdeea2be42b537b535e9a9a5a2caa64c268e19513b50dd8c64a1e2750216039633784f56f54c1d +00 0189918b832e9fa30161fdd927bfc267f6405335df3d66d225e17173af52a671138883bcb94c4403ca3e001fcf09ef4c6488934d6775af2b1da30a8f331579af2d0fbb530298d8f9 8bd9364308fabbfb2d2ee7645fa7aedcf3a7dd6cf6222eec2c2ac8d2434ca8f059ab47f457fabad82f3e5c7d43d81191 +00 00bdcc175eca3a399b944eb0334ff33c4fd130999c8ac0e7b52ac5b774fbad53ccc3a31024f5262b2eecfeb2104b14bb244307effe3dbe8ed25686dbf46a42c4b6f8e34010ad826a b00f8a8c57333215379b9f6b7afce712b9106f04424b5cc2e04b3ace5a0b287be6c9b5629296c50f76bb15e80e68b26a +00 0007ab5a55a1d8ecb7f5dca2afdf9ef465569a4b0374716f604ad42a6e0271e934b09655e8e2529784b69b2894bb399b02aeeae30e9e7ae70a2a8e56b9e775bd978a04c728e3951e a08fbb36d6b1b2780217014fbdfd71b116ee1f4fbfc5a1fcdc8acd0a2bc06c949cd37f0a15d84a98da9b9ead709331a1 +00 01e7d4da72b1d82e17a066fe387f2a0a7fa4c60ab993ee09710531789186077f2f32b42ddda497d5fb57356383e1f96973df043307f0b6519430c3f0d40d62954032872fceb7dce9 af47a563720225c08f665a21c078fe379957c782b3c5bb199a8d62b7d923920619bd2c6eee97afff95cdea3eaacb132f +00 015b7271d4319db5743119c8103a7d4c6d57e9c62f3eb93762156d2ebd159980aa57cea948e416717d715a2e458851f1b2e9ad4172bbcc53861db29c3ee0ba8e82617a5866170847 ae934530cf0c7f95100f911dbcccafe480efabe5c499fb832ca802a1cdf60f54c8382ce9151b7da424cfd8ef2031ce43 +00 007219ea7917d174a5386df985d0dca798ac9f8e215ab2f0003aee929a2dbd91e37fedead0ed95b1e8aabcf516bdf54337b4aff7ace4c6b3179f2e919a49db50a41c9d4d58d4f636 a73e8fa1886a09e0c5a1439daf01618ac09b866b6d5baf4f9243d19fb3522c6bb1917d5717fd76722e4f4988d66032f5 +00 00bc623152253da24bf8d752bd78aedf7d5f6a2f889453ccdec14e10753335ea8bea83fd181a1f3680ed50f2324fbeaadae160cc85831750e021f3e44121ea1b1efc29a7d0069479 82c9a5dc5c1d0f430dca4044de4df450827362847fa56f10cd8ea05d9a678157080fba60a3a6f70d3b91116a4c5178dd +00 00645947d981d258f2954558c31022a3b6ba5fa7b675312f794cb61bfff1d9ce87267e4a1dacb7c8fc58624d31c85ebe22f80d26a620fed5df5bf38515e0903f0b69a606048197d8 99ef5b1b4f92d399f6d1fd7fc5ad38b48f47ee541434f5910d1b24f8a053cfa644a9d8c6597f417585d2e727ab1333bb +00 014cf93ca69d94ee8fbea0c8da9d76aea092b73073d8f5385b65c6dd4d567fe86bc2cfb8e8be890c3c6cd9abf7dc3a17eaecee3d7a9455887863e496c48dc3e47821bd3d825b6bed 968d9259ebb95ca1fa758c9c7e19134e9fd99183a132f45783fbebaf93be15b9092f4b8fb5bc7eebf9b1b5c1b24b9196 +00 0033feeaaaa28f16bfaf5ea9c7319cf4561ba4fc55327a8477b6cd58ef6ccad3962ee1f3edb243f3a04e7e49c8e23509fa2d63252adb186b8bc7e9255cd61fa9bc45242d42da3a68 a443e79ebef90422f5804c3d0f198422ee6786b68b1750034117408fb4e14d5fb7d0972d4771beff45860811d81a7349 +00 005613dfb53149bf5fdc4e08ccc1c752b0b66ab43aef2d008ed40f3df40fcbb2938d2c41e3ea2dd4428aeba9059a97efe5593119673866a19d27a2ee37dd357e22b6bc849e7e22cc 84cfb169e5d4caa0e6d0e0a5f6c2fd6c3337f63bc70f896d262e36af5a303e022ba110f45af116b83b72f0155beabcfd +00 011b92c8b72b86c51903387a65aa206988d443d1988253329ad3a89c902ff1ef8cf73b7f2e4aaa352443bcb833712d94c3e637ec12cbe4c2d4606878576b17fae1512fc77785b737 8d4796584c144f98f1e36430cfd6419106dd231fdd031beba26600feee137aff57e24af0e419e7b53c620f510694c6a9 +00 00c3c90d5ce4375a08b85575faa78ee6bbd9e5571ce5a90582042617b807339c282cdc3b003d82006264b1c08c20af4ad4549fbde53d262facb98d923d81b8eb6093374b6a1e84cb 8dcd07a7edabdc50a43838ca55da5b325af86fde1ff9d71a413c74ac9f33dd81aa484e0cd09530141f2f933bf5ecb5ae +00 010f184c16228d9034271332178ed485d10b6aa76003efc160d63fea26fbbdf5552205ac7df0d8c852a1210cf0ba512f20b798827b36ad56b12a826fa7dc1db45aed264ca6822659 b35dd61f5c0a641ad723ffd96f393da560a85a66ee5b75b1947d6aad6f101a319951e0c52fb03f0bfe71b77631717f2d +00 0181baf9d497159f837cba58a11ca435c442e5ca792ea559bff9f6a1f562c05bf6bb5914afbd1bcaea75b35f88bdd832314b249a5298622c89462344d3f28a44ba3d059df432fc71 a8561ffddc05e71ebcadc56962a54aa10263c468fabbc18e1f2ec4e415a382080a53f336d46bb62bf2ede638eaa9779b +00 0083fae86ab96bce99a53e50b7eecff38e4e25b21c4b0f6a4986915de245eae24f16b6a00a4db159ebc27f5a6a072da94ab6be5bf75f5eb3f75c4452bf4ea7014392eb1e02706fb4 ac2a44f0e48bf187a9a45027bd0902b91ef9f42e14e94ed7adfbc46115d920b551bff8912ec94fae98b5d4397aedc6b1 +00 01a663efa7bf4d8479bc535fad71e9b5e4f4281aec55967baa008ba17ac2f89cc3398d30573edef29d590fddce8cb157f655e92779f59e7a18d0327d02e7daf4c1216143b3688fed 8ae3dcdb0a48042ec57aed481586901b8ce8f89fb736030a6344f4288dd9ff0fa5c789f02b8bcc9b989ccfd87e969c65 +00 00088d1a2c0219696a94337cd56516252b74139ea0733b17fdcbf7692c3e5f6c3989e5da2aaed7468e65a5d578571928ca273ec3b6aa72cd196f560f05095cdc8346e5d31c4c2e0c b1ed4ee036eeb6d17bd34382768f9f5b0e1207f4bff6cae20d42a20d535d47fa13d88f4be16d72ae25bacb0b3a6f1b33 +00 016cc8a0fd59455ed8d4de561fd518df2e008f7dfaa5f7f29ac2489a411e233917b43eb3ebe2596fc824be58871949545e667dbcf240dfb5e0c615ade0179d9ea2a1b1ebb8ab9384 99f6d998fc6f05acae13e2be99a31e401f4b2dde87b7c4937056ebb5150add3a3c3cb2f093e206377b7e6235b3699408 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P224 b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P224 new file mode 100644 index 000000000000..083fc9cb0552 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P224 @@ -0,0 +1,60 @@ +00 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615 b95a40a3baa5e69604f7020e474a0d6a0a68bc29e1a0b7e52296793093c35d49c4bab5b22aaa2f2bdc752c626eec7ee1 +00 cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5 a85e580655c766a3297ac85ddfaf5ba64dd4d653460f64c9264dedd59f9d055f71eef68b2cc2c19bebc76c98a44bc699 +00 dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73 b578b0bd71cf08979ff657f95d6fe6a5858bb5438c5eff46d40d694fe6ab41986246ce88a672ba4c0e334a28271a2787 +00 aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e 8cc234a5d0d1e381714b8e3f94feaf2de7447e937282e5e0b61be5c8fe94d8a4fe1267fde87876593a3c292ef27179a0 +00 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4 96a2f0113f8358ae88da60dab7e335a72f6a35193fb7ecc6376ba2f54fc81af70eab410cf9e261084281a2b2c6a8bf7b +00 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131 8119e40859a21976f404e422a0c1d586f877a975da8b2d85b6bd573bfa188d7f86983f897e8362c851fd3e3d1d25de89 +00 d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974 8c5bae2a5804d4c30106b76175f827ea980a05e758229bec0ce8c9ffaf42d583fe8dc90542fefd1292ec812453d60c02 +00 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8 a8ab1efa26822255f4723cbfbbb9cb3960a48906532a99aed7ccb207aad01ceaeded579ef4167ef515da86ba7162fed2 +00 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2 ae83272a7f1ea4c99800e6139b1eb0055c02ab4f0763f9c75c42be864c4ee17b189a40a46a42cb0c70115961c2b88669 +00 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7 b2b8a2c7a83c625acc525aade394e07d58d61b9f732a23cd03bda3d092a1263d50a0776b7d5c3f04206a6709eae0c57a +00 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b b7a9d526fbd92e92b04519b8474937b95fbf240b830f8442594e354e3a8bdb6a7197d2c8558e47797289a601aee6ed7a +00 c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6 9332e7903c1e194d0d8ead749b170251c3e9b16c6c7f312f8b7d391dd79ad36b71d9edb63be1d457a384b0089da5ef91 +00 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc 9210352d0567a4512189fdf3fc819a18de0007c3a21650e1a131722d073abefcd30614e29928e461d6cc811ac4141d2b +00 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3 85c9837c740ccca8c7798c904ce6ba12bd8f7d3d4168ef8ebe0af9a438804b9528235fff9c69b3c348d32b7084e4d4ce +00 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912 b0d3df7d0ee74a246f14fa5b7028b93d0b67f257fbb7b143fd8c8ad77665186b7c771bd223a8a04d1e862d03f87a6cdf +00 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa af76c8f4481925539a43d42063a18fe4eac2ae78ee352e6f9023135e55b44bd33001cf1d8134b999b5082562faa1e572 +00 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972 82dffc662069d3426b59fcbd1d4a70f9fa905b22e671f147395d24d8f8afc17c446590ecc1f818ba5764d6644e27e6cb +00 f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170 b0a419020c4f02d8445f9e6453e5989c11caf6f339c129d43f94d3e7a417e8101a319fd6cf3dc75ed60b312225514931 +00 c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85 8a577ad4e8de539b3e08929594beae54b2931d79c5ca37239824e5ee376ff67fa469e88b8d8977ccf9ab4f14e1bf1248 +00 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6 833f70683c1932719e3709fda204874534a8f2601a8ea5a624b20e5eb1878db85f092f37da7d5a9fb1e37d2147022f30 +00 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39 b669c62a10b717c45453e7c95e582afd5dbbfb61144dcc25fcb1748ef3fa57c5138e62fea2502e4ca85608d2489cfed2 +00 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6 a2f58068135fc7aa18acf4812ad07ad1714ffaba96bd9ca11857ea5aec9b0c19a6ad8513a5600936ee6b2f975d57d037 +00 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b 960c3d789c803ee732b5796782f763e5b15010578f55e6fca045284a80ec49b6f616413ae4c4d2aceaad8ea99117f970 +00 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b 8eddab939dd2a30635b2c24be125f2fd9f33ae1c33f3fb3ce7f65d239073352d3d7de4300843d6739549c31158fefa52 +00 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8 804eb7059d348482eb3def297bfce4bbc9a5054112736c2d923cee18ed231270632cf081d98153110e156384efaaaafe +00 e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784 87b5022178ae339c66c2531c9a8d7df287add74ea05636e19904b3fe2e0837cd9144e5867d879b6e5698ec3957e559e1 +00 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c a19c98b61ae222f6c1960204bd5b217fba2039c37b54c8d8fb503b9807584bcc95b59d35517feca7665643e6d6f52108 +00 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583 a6c0a517dc567f9e27181c20328687dd945e9387855d00d46e290555a1df0a44c985f9e5382ff0e82a83ca03aeedabef +00 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2 a5e6cb5533977f86b81dd76a2d62fc279f076457e601ece03234272ce25a07bf3ee5053766863896f95024022940a2b3 +00 f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc 975475b44aed9d188440d98b24deae836ea5c7db2dff349e1a7cc5be68d174be8eb0576eb782df659c02180adf215559 +00 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd b68d6d44b56824228152e12d7810f208806751868c2a41528e0ae5b32ac0fb88430591f0e3391ce16988608c751cad92 +00 e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3 93ccb995313b0b19ef63214958a2dd4f16205b4126915f1c93cdf84be5592b12c710a7cdb5d56b7fe6b868bb3718902d +00 b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17 8c7471369c4eb9ce9800c2041bd6da2bc79cb7f7fedd2f83c584e40ed1e94e87b25d9dc49284fb4c0a44b1554c44c754 +00 efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085 a02cafae13ff3e16ead3be6c380e1e91a2a5e1128974a99dbe4ac4e3935afcc016ca52a6d4cc4c700e6a65e8c76f2712 +00 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd 982df5e99d145aa613687ab7b0333705d08f2d06dfeb752aea053d7472b36bfdffeb6c06d47b416c6c79610e6221aed5 +00 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d 85cdd90b1fd343e0e714c89a1a2deeb66428250d2a8bdc96906b21e231147c12655c6918b86815e26de7e9365d20de82 +00 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0 9668fbac4074d8f0bca4ba5d44d26c9b85e78d3382e23baa81a5369342b7bd2b8bbfc8401d716a88b6944d58dbb5460b +00 e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d 9404afe47db439e722db2139da29a9131a904265d51f255bb19c7e59802c7cf7cd7d088d2f953dad43634a054ba746ad +00 f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7 b830fb0e8f975fae4c4dd12399fd7dd3c6fe9b77746063cb7106d2071c75197dc073f6d7f956044a328993157b26d4a0 +00 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c b878bb0d676d0fe9d4e51a0e7689c87290b0363b0a09869041be515a621bf931c5e01f7552e114954a497d90e938d7a8 +00 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18 925100f42175a349228bdf16b2f6a4be2bdf0fc8ebb64b99897ec9970d50843f295269fa1618b73636c31492408af1d9 +00 bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a 86fc2522fe7d045bef3b8e91e7461ea1f16167cc80d1962dadabab413afa60afa147823aeb4618129e9af9661f03ea73 +00 dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738 8459f345c1a790a49936f0f094c44ff93fee334742ce7b8367a92ebb336baf769608af93c3f43f092591cce8388aa45d +00 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01 a8cab8855c6b18d8e288b35d726cb6dfe1f6f4da897faf5f598b415083b3d43adf7e10634f78d0a172ca43a4c5ca83ae +00 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28 9092d2011b578ee4f4f1c42a685cdc6b1687f52ecaae8c8141ef7c3310525ef545bc8fea9b260467c1f93836690e9cdc +00 ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6 8b4f9aaf084d4c0cfbbdcd0064694eb380328b3a4da68dccdd82f53b8814f00ca8ae5ca9c85905bd913500accdc11d85 +00 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc a1f126f50658f4c0ee37fb022b907572876826fc07f28c9119d7b0fda2d3723e039c431a4f58be89e7fe3d9f0afb35d4 +00 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b 8f70df4c9e4ab23c36f93dcb2d9b08a7b708a82b24f67529fc652d3f0673760fab27ac6be8c679aacaae2836c58be999 +00 afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc ad5ecea7f4a123688b03257aafc7971c4a78919f1d2428ca5d3f3479b76ac04beefbfa9ead0e420ed391f5248b961869 +00 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c 95cc1b4051c1e25d563676d3776a1ace7d90f4bb6851354ec590f1439bacb40d85dec23259cb508afd8378cedece18fb +00 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc 95efae066c64a44ea34bca2e27ada8afa5a617fab318a92df6c944f8b3e54788387cb4c47258a08ce91d2f79ecafc3cd +00 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4 861fe4787603e688edd884fb9be744b7ca13c0a4a85d120de532c107c96c4c7090c3688d7934b6a4fcbbffe0e757c0e0 +00 a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916 93f9cdce787c3d2b2b6c5955f7b5d72eba027878bfc5e8292613384e7427c721bc10bdd2745cfda3488d3f03d2ab1248 +00 fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b a32a75a9acc934402f95a95044ecbecb44f7b7c41a4ce0375ce2290bae3878311d549614715c222b5e9fcc3ed50b4b68 +00 a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea 99810478e2c10ab89384941a6438b9d5721202258baee51bc85cf7eabc11aa750792a6bf459573400f36582f6cdb0373 +00 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0 87bf53c2ea20508bfe26d64045f5192e8e966e4b71b4dccf82cebc14ad5bb42c312000dadf13dd1c63dcba4eda4aa796 +00 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294 b967757f1d3e0323c69c59de3501e7c6b57017a75da6462d870e7a318d214e354b4bb85f9400352212590f7f54772a62 +00 b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a 938b7764c41aca8b6d153e797e3773556cc9ada8e287caf6757989ca03550206bf6b14a75c17fe7c2b436e33a08f072c +00 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4 acc507576f0f43542f3fa8f249f33c99ff821a0949a118f410d7c1a7f75d0da9aa9081e4619b72e0ebf44f0d431963db +00 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04 8877760712aa61903bc3335e9475d79e9b8e2879716b3e2475b59b78f0ddea5309d42e279a09ccce20939b1fab42ee39 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P224_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P224_blst new file mode 100644 index 000000000000..083fc9cb0552 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P224_blst @@ -0,0 +1,60 @@ +00 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615 b95a40a3baa5e69604f7020e474a0d6a0a68bc29e1a0b7e52296793093c35d49c4bab5b22aaa2f2bdc752c626eec7ee1 +00 cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5 a85e580655c766a3297ac85ddfaf5ba64dd4d653460f64c9264dedd59f9d055f71eef68b2cc2c19bebc76c98a44bc699 +00 dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73 b578b0bd71cf08979ff657f95d6fe6a5858bb5438c5eff46d40d694fe6ab41986246ce88a672ba4c0e334a28271a2787 +00 aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e 8cc234a5d0d1e381714b8e3f94feaf2de7447e937282e5e0b61be5c8fe94d8a4fe1267fde87876593a3c292ef27179a0 +00 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4 96a2f0113f8358ae88da60dab7e335a72f6a35193fb7ecc6376ba2f54fc81af70eab410cf9e261084281a2b2c6a8bf7b +00 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131 8119e40859a21976f404e422a0c1d586f877a975da8b2d85b6bd573bfa188d7f86983f897e8362c851fd3e3d1d25de89 +00 d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974 8c5bae2a5804d4c30106b76175f827ea980a05e758229bec0ce8c9ffaf42d583fe8dc90542fefd1292ec812453d60c02 +00 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8 a8ab1efa26822255f4723cbfbbb9cb3960a48906532a99aed7ccb207aad01ceaeded579ef4167ef515da86ba7162fed2 +00 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2 ae83272a7f1ea4c99800e6139b1eb0055c02ab4f0763f9c75c42be864c4ee17b189a40a46a42cb0c70115961c2b88669 +00 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7 b2b8a2c7a83c625acc525aade394e07d58d61b9f732a23cd03bda3d092a1263d50a0776b7d5c3f04206a6709eae0c57a +00 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b b7a9d526fbd92e92b04519b8474937b95fbf240b830f8442594e354e3a8bdb6a7197d2c8558e47797289a601aee6ed7a +00 c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6 9332e7903c1e194d0d8ead749b170251c3e9b16c6c7f312f8b7d391dd79ad36b71d9edb63be1d457a384b0089da5ef91 +00 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc 9210352d0567a4512189fdf3fc819a18de0007c3a21650e1a131722d073abefcd30614e29928e461d6cc811ac4141d2b +00 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3 85c9837c740ccca8c7798c904ce6ba12bd8f7d3d4168ef8ebe0af9a438804b9528235fff9c69b3c348d32b7084e4d4ce +00 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912 b0d3df7d0ee74a246f14fa5b7028b93d0b67f257fbb7b143fd8c8ad77665186b7c771bd223a8a04d1e862d03f87a6cdf +00 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa af76c8f4481925539a43d42063a18fe4eac2ae78ee352e6f9023135e55b44bd33001cf1d8134b999b5082562faa1e572 +00 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972 82dffc662069d3426b59fcbd1d4a70f9fa905b22e671f147395d24d8f8afc17c446590ecc1f818ba5764d6644e27e6cb +00 f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170 b0a419020c4f02d8445f9e6453e5989c11caf6f339c129d43f94d3e7a417e8101a319fd6cf3dc75ed60b312225514931 +00 c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85 8a577ad4e8de539b3e08929594beae54b2931d79c5ca37239824e5ee376ff67fa469e88b8d8977ccf9ab4f14e1bf1248 +00 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6 833f70683c1932719e3709fda204874534a8f2601a8ea5a624b20e5eb1878db85f092f37da7d5a9fb1e37d2147022f30 +00 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39 b669c62a10b717c45453e7c95e582afd5dbbfb61144dcc25fcb1748ef3fa57c5138e62fea2502e4ca85608d2489cfed2 +00 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6 a2f58068135fc7aa18acf4812ad07ad1714ffaba96bd9ca11857ea5aec9b0c19a6ad8513a5600936ee6b2f975d57d037 +00 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b 960c3d789c803ee732b5796782f763e5b15010578f55e6fca045284a80ec49b6f616413ae4c4d2aceaad8ea99117f970 +00 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b 8eddab939dd2a30635b2c24be125f2fd9f33ae1c33f3fb3ce7f65d239073352d3d7de4300843d6739549c31158fefa52 +00 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8 804eb7059d348482eb3def297bfce4bbc9a5054112736c2d923cee18ed231270632cf081d98153110e156384efaaaafe +00 e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784 87b5022178ae339c66c2531c9a8d7df287add74ea05636e19904b3fe2e0837cd9144e5867d879b6e5698ec3957e559e1 +00 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c a19c98b61ae222f6c1960204bd5b217fba2039c37b54c8d8fb503b9807584bcc95b59d35517feca7665643e6d6f52108 +00 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583 a6c0a517dc567f9e27181c20328687dd945e9387855d00d46e290555a1df0a44c985f9e5382ff0e82a83ca03aeedabef +00 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2 a5e6cb5533977f86b81dd76a2d62fc279f076457e601ece03234272ce25a07bf3ee5053766863896f95024022940a2b3 +00 f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc 975475b44aed9d188440d98b24deae836ea5c7db2dff349e1a7cc5be68d174be8eb0576eb782df659c02180adf215559 +00 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd b68d6d44b56824228152e12d7810f208806751868c2a41528e0ae5b32ac0fb88430591f0e3391ce16988608c751cad92 +00 e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3 93ccb995313b0b19ef63214958a2dd4f16205b4126915f1c93cdf84be5592b12c710a7cdb5d56b7fe6b868bb3718902d +00 b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17 8c7471369c4eb9ce9800c2041bd6da2bc79cb7f7fedd2f83c584e40ed1e94e87b25d9dc49284fb4c0a44b1554c44c754 +00 efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085 a02cafae13ff3e16ead3be6c380e1e91a2a5e1128974a99dbe4ac4e3935afcc016ca52a6d4cc4c700e6a65e8c76f2712 +00 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd 982df5e99d145aa613687ab7b0333705d08f2d06dfeb752aea053d7472b36bfdffeb6c06d47b416c6c79610e6221aed5 +00 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d 85cdd90b1fd343e0e714c89a1a2deeb66428250d2a8bdc96906b21e231147c12655c6918b86815e26de7e9365d20de82 +00 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0 9668fbac4074d8f0bca4ba5d44d26c9b85e78d3382e23baa81a5369342b7bd2b8bbfc8401d716a88b6944d58dbb5460b +00 e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d 9404afe47db439e722db2139da29a9131a904265d51f255bb19c7e59802c7cf7cd7d088d2f953dad43634a054ba746ad +00 f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7 b830fb0e8f975fae4c4dd12399fd7dd3c6fe9b77746063cb7106d2071c75197dc073f6d7f956044a328993157b26d4a0 +00 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c b878bb0d676d0fe9d4e51a0e7689c87290b0363b0a09869041be515a621bf931c5e01f7552e114954a497d90e938d7a8 +00 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18 925100f42175a349228bdf16b2f6a4be2bdf0fc8ebb64b99897ec9970d50843f295269fa1618b73636c31492408af1d9 +00 bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a 86fc2522fe7d045bef3b8e91e7461ea1f16167cc80d1962dadabab413afa60afa147823aeb4618129e9af9661f03ea73 +00 dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738 8459f345c1a790a49936f0f094c44ff93fee334742ce7b8367a92ebb336baf769608af93c3f43f092591cce8388aa45d +00 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01 a8cab8855c6b18d8e288b35d726cb6dfe1f6f4da897faf5f598b415083b3d43adf7e10634f78d0a172ca43a4c5ca83ae +00 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28 9092d2011b578ee4f4f1c42a685cdc6b1687f52ecaae8c8141ef7c3310525ef545bc8fea9b260467c1f93836690e9cdc +00 ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6 8b4f9aaf084d4c0cfbbdcd0064694eb380328b3a4da68dccdd82f53b8814f00ca8ae5ca9c85905bd913500accdc11d85 +00 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc a1f126f50658f4c0ee37fb022b907572876826fc07f28c9119d7b0fda2d3723e039c431a4f58be89e7fe3d9f0afb35d4 +00 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b 8f70df4c9e4ab23c36f93dcb2d9b08a7b708a82b24f67529fc652d3f0673760fab27ac6be8c679aacaae2836c58be999 +00 afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc ad5ecea7f4a123688b03257aafc7971c4a78919f1d2428ca5d3f3479b76ac04beefbfa9ead0e420ed391f5248b961869 +00 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c 95cc1b4051c1e25d563676d3776a1ace7d90f4bb6851354ec590f1439bacb40d85dec23259cb508afd8378cedece18fb +00 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc 95efae066c64a44ea34bca2e27ada8afa5a617fab318a92df6c944f8b3e54788387cb4c47258a08ce91d2f79ecafc3cd +00 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4 861fe4787603e688edd884fb9be744b7ca13c0a4a85d120de532c107c96c4c7090c3688d7934b6a4fcbbffe0e757c0e0 +00 a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916 93f9cdce787c3d2b2b6c5955f7b5d72eba027878bfc5e8292613384e7427c721bc10bdd2745cfda3488d3f03d2ab1248 +00 fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b a32a75a9acc934402f95a95044ecbecb44f7b7c41a4ce0375ce2290bae3878311d549614715c222b5e9fcc3ed50b4b68 +00 a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea 99810478e2c10ab89384941a6438b9d5721202258baee51bc85cf7eabc11aa750792a6bf459573400f36582f6cdb0373 +00 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0 87bf53c2ea20508bfe26d64045f5192e8e966e4b71b4dccf82cebc14ad5bb42c312000dadf13dd1c63dcba4eda4aa796 +00 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294 b967757f1d3e0323c69c59de3501e7c6b57017a75da6462d870e7a318d214e354b4bb85f9400352212590f7f54772a62 +00 b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a 938b7764c41aca8b6d153e797e3773556cc9ada8e287caf6757989ca03550206bf6b14a75c17fe7c2b436e33a08f072c +00 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4 acc507576f0f43542f3fa8f249f33c99ff821a0949a118f410d7c1a7f75d0da9aa9081e4619b72e0ebf44f0d431963db +00 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04 8877760712aa61903bc3335e9475d79e9b8e2879716b3e2475b59b78f0ddea5309d42e279a09ccce20939b1fab42ee39 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P256 b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P256 new file mode 100644 index 000000000000..ffc91d0bedb7 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P256 @@ -0,0 +1,60 @@ +00 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590 ae175cc23d06cb6e133c20cf140cce355e043fa5d95a3222bd6a9a3a85f7a64530eee998cf7652c3063b7b54e70fd57e +00 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98 b8601617635e371ddee9c24fd7332227345a2981f8bd13e6103c144ffd922a198d98d38951b1adb181c1b2c2e8702ede +00 a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870 946c36fa53a274902d772daacc21199fe2f7af4e15396dc8d07513238bf25ae3f752e729a228a9f223c67a614f4bb699 +00 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f b7bc74c0dc9f9fa77bf2e0cad0cd1bcea2ebf376e5cc6791e9e139c152f7f10b2bdd03cf669bc5bb024385a82e3abda7 +00 daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d aa5bf7da40d33dd2289bc87318ba65df281fc34312bc4c1a6e25a0e2c4e0d4a048fa964c4af1588cd535b32562325456 +00 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5 8004bec2127b3937e788112556fc485865a754b5b5cf05ad78b895463357bc367e4f0b33b19338e038c16157d7113211 +00 f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96 af71823ee51e7f15078d89d8ca3bad4b7a7038420aac9f25cbd42b680b96ce4a20ceb5bab9df9dae3976db32a2032705 +00 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d 9220240434adaf2da69029cc63e76230928935838f07e9773adb2f5c0034b12907286e57a166a1b04dd1523e08a6da54 +00 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9 b72e43999fcecaa6e94b42f7fa23389d93dfa8ecf912f7c6398c081f6e83a247604635eb749487ab63e1093c8d4e2d48 +00 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634 b56402ca6ec49a0d75fd6cda6f2293ba1b4aaf1a2a3df5579ee9a76734b0ee9a656539d5278f03824c971db06e6cc34f +00 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27 924200ae4d810b7fc12cb4c810d1af66412346b59580390320e04d3363cba0ff9f2b5009dabeef4dab4138eb7ca4b779 +00 cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d 95c44661a065d0a082f4b5078aa72866f674c409ee764a66812d947951ba5c314c055feba73aa737da43bf34370befe7 +00 b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c 852486ebb585b18506a1923046121f943520adb654725abf44ac246afe74cc8a05e258cae3ea4e52e5719c02dff6ade2 +00 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48 a61c03853283e8bdf1e260c96a6503a6acb13427d498c35929f739c0e170d40dff260f3f2376344f6dd1181ab8093620 +00 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f b35c1da9433dfb77f5f3d3074870df2463ce762abfb7242fa846b1ebb4bd358ce9db9c7e77c7611845a66b5f3f6f4a6e +00 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 a1fc6b0a47ada04db68aef73ac9ff644aab5de55f14203360371b7bfd30e31078725a987c7f54f95a372de3186d24568 +00 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 95b197a341e52a97005fd1454f179d8cfea834957835efed3a40771a3df387a57e12ce30a72548fcdcc37f11afcc34f7 +00 e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef ad3061203d40b2a0cbeedc00c436dfa4ece97b0b762788242125784f22fb9e83ead47211df2d8be314b9031775fee863 +00 a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 b426f01e2e1d242427edc09106b2b07822e0f6b97fad730c789d781b2a7e56009e330f07eed920fbed52149aa8c3f463 +00 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d 9647b2f12cdf7bf671d73977f67b5ee3f7d1ca466b4d39b062a9b3cc2d9b81957c372bd87879fb9819e89849a03669a3 +00 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d b4e6bfbf70ffa32181bc2508e51fbf2d46a4fdd2d0c521163eee3e41ca68dbf36bc00c5b0616315fa64f0eb7717eb555 +00 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab a9b6a2e37feeae1de5a76de5e9e8c02863624f8ccfff9bc08f67809360217b389ece7f5f4d32e452a523108a2e0cb338 +00 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a a6f7a09aa1760e0ee790ed47b13009624a63d41fd8af60f94fa6a40a0ca00919b2fdc749de714a4b783fb28b2318895a +00 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 a616ae304e748fd5b04c80dbd47d84d25b60b721475f6bf045d6a4b38a93bc6021226ffb542dd949591a1d5d03907dcb +00 f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 b7f05b9743d0290d5f4eb4ab64636c26acebf66a2fe983228fae42844488669a2df010ef2565c882e7ff56560325276d +00 b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 b30c45e817326942a48a8dcab5e0ea8bfe0feddafa83a2e7c5de36035bf0176c8a727f289f1397d27dedd0441931790e +00 d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 824827cb1636a4a34409cdd5fdfb7195d8c2667789782ad1c789c6ebc663e368d0d1dba40798b7ed868678b4a7fc4b85 +00 b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c a0fdd9fb2b0553d00add90df3916faf85785b16a0d3feaf933f50b2ea88623ce3310e4d2928262dff0f7bd7087c8a33b +00 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 a071fbdf2eb1bc11ec37563633e7859d5cecc94380d2a6b84185fb594ad967c427edc900c1f5924df3ceb512f84641f2 +00 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 83807ac64a41a2a4c10746f63813be78400b7beb48f0206f46bee9e85dd15a9a6861e3f0a3011fe5a1edeef20cb28a69 +00 b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced a80d1d2d789b9731cc0525c5b75ecac72ef07d68b3a753a4e1f77676a9869530eb89ff77321172b4b2f8c811979ea92c +00 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181 a349a1c472c4bb4273819ff6547a23a929f9b1c140c36b2d027506691d9e05b3b360a6bed72f65ba2c3ca16bf46e7af7 +00 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431 afac2ee875b67533ce35b32287a63dc19ea2d9c8c5d9293293b77d8573a78c88173891c923657afcd0d7e7dd9d5f3fb6 +00 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd acf0443e036736dd489d9c3bfe1eab3fc9f0669901f5a8de390e3690a174f0d87c00856592402431d34983b1e99d535a +00 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de 94ef3a090d11a6fd5520785cb855dd1bd96476cf359666c55c601113fa1ea63c548f5eaf794d89f7b99fe601e091860f +00 ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566 a79765b5a51ab13d413167ce3973c29f2475cca51700e79ce8a361cce9b0bc6f823600c4c293c41b941c3071461e087f +00 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee 93ef97057fec51ac3a67ce685b3490017d551ad5f3d2204f8dd4e80b31426d63087b9607bb22a04603bc291b35072b20 +00 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd b5ac8bcda6e74dc6c2f4337137bb7c826f8ba9be52a9a4dec0c405ffb149ec16099e0f441d4c3888a38213a7844dfe5b +00 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666 b454012bf2d3a8d6910c572245d18a362e5bce495907188452f138ed624dd4190926626b23b4c8c7d94a01c06fdd3e19 +00 bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67 8c501749db300cc8a2bd3559fc8f7d4e46830d6250100ffc02d4ebf4492dccac79f8b3a2aa1d3ee4364b54b441ced897 +00 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9 a64fa53ede2cb483f25576a7a2adba54d2145961c9c871d057229bf98ca0bc67304f042b0a39e907065a2a72741874d8 +00 f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce 99e30ddcfdf1344ad90ab7dce6c7df08361cbcec5d9cd756de4a5d70860aced291e7d4c995184ab1b0a72d51603f8be5 +00 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f 8d7e109714432aee681a64c3c4f93cabe56ffc9c9cc06f487a5ba2443e41351b7911c05343b7299b4d0a43e9d03ff3fb +00 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b 99d8ae0e56de141bd62241bf1907d2613344340ab31b2c34909a6259d510eb59a1cede90547af79ad0c481beed88826a +00 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388 801f54733382ae68cfd91a6f589334b8f333fd64632d840ee167307f5e66f251b57a974b2396be7b1d9797be085f808a +00 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499 8c16e71fd9e1c8e4c79564e465383c10e7e03fd237a57c48121f11a61e0bffbfa7b604ea4a42d0cb776e7edbb9031243 +00 f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6 9590c9151c66a492c0515dfe95eb24e0b4c8a894979a80071d2757d93ce363197dc862e29e5a48fb2b8d3d8cbbda7bec +00 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead 9984298af6e5845fa559112d55b79d1c88e1469c008956bd41d9075625b0bb0aff132b08ccaa9c306b7be186f06b3f88 +00 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd a919429c781f721bcb8b24e803474557ce0da0affc9d2f90b863820755e36b7159360f25bc44e749fefdf8b33c086b3b +00 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117 b3a7391e8240904bc9eac00ab5fd7a3bc90d4fea07da4023a544f217c9f1c056360f13005732685040a5b0f36374129f +00 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61 948ace6fef41cffc75e38943f4fd0ec58862a1891cea402214b0f9884915620194fcded5ddb1dc5a513de4a3a19abb9c +00 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2 a067b0a93262fe4f2b7db81f7837c50ed28538588169150db3ee8af9665438d9875f11f42a19dacf333bb0f1e25d6246 +00 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7 97b19a3d325b02ce4d64341edc52eff9fd1396b3ecf3a09351674a0f858b976e68d3018dfa57fe26c03cb3f7aa38eba3 +00 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870 af00f2893ddc2a03031c11899f35a8ec52d6be4168f371da5ea67ad5a0200f131a2f6b149b728bc5dcb5372046949f00 +00 e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf a0e979d06041aea50cd5fb0470712d2f603c47f416c40252128bfb1a980d93767028e09adf3b0f1e654c7b397c360020 +00 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c a5f51b1a87fcdf98458f47e54b0fc16d7addf8237101a8e4dd8d86f9c4d39857ac4c2a8e421d403256fc91019ee08399 +00 f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9 8b0c0cc6a1ea32107f75f65e086e0800533a1c9cfac397f4a23cec2fcce809e1b4887167c2723ab16406250580c90d25 +00 f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5 889a94a46093a4fb1052dc3451188165e8cd941276120b547ee050c861c9456c4242eb3fedcfc9a419be2cf138b5bfb2 +00 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628 84620bdb030c3babf5ac622caa85c7f3f2b11c28172ed34d65306fc9a7ba08317ad706120a6a388e78165b34237e6715 +00 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49 801cffdad0feeb09f9d8bf7bf8e7108d780e9d2f975baebf310bf7b3909cc69b191dc069d7c1346e13999d8c777494fe diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P256_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P256_blst new file mode 100644 index 000000000000..4ba159d59862 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P256_blst @@ -0,0 +1,60 @@ +00 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590 aee12d089e0e61701d11e370d611dd3abacbd40a06340233da676ab1795d0a03ad1bedcb2c9f5a1c7f9e94be1645c9d2 +00 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98 80165628fd51f73fba98b8f2287b0cf34373d237bf631ddf5c6c0861d375dd968773cde90cd0bc7019c24cea3ad4523f +00 a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870 8009c3e08e43c08b70282a6a799357050744d11116f4388c098bf0e180cd8171fd8d17764c815d63fd0489dab1a62330 +00 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f a41220c98ff9ed769d8df7a4822a5eadee0a7566f441ad2dd0fb4a3597a3f31f56b68df013b6b0aff5be168555c4c51c +00 daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d 87029458d72f5a9bd22a8d469111c34da32b1cc622c1508bc68fdf9c78d7987a6c4ceef6889293dc7d993cacd3ae1dd5 +00 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5 8d4b7e9ad975d4257ad39972dd2ae227631375068251a53060821ac4480c41a46bea033054b4bb49c0dd2bea275ec18f +00 f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96 9694b7171ed2f0a77acea6bd39240a61c3b767586756b9f00fef98fb32d363194572ec660268d2a09a7033334634d0bf +00 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d b19871458ac2dc926a40cbcd5bee4ef3a5d2f509715af762f5b00a85d10b8a9bb8ff0a591123d980db86a1b5671e653e +00 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9 a20e0a520ef21c88c57dd96ab8d3a7b321319219d295944e7792483b147300110cc572569097b4feb4c970c099c80662 +00 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634 a54a039f3969012bee9669f1d2f97fb779cb8e5201b67dbd768dcc6aed975e20b18969311874677450a73a926b1e683e +00 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27 a117b53d927fc0834bd55e65fcfbad78ad09db9c5e191ee7e9b62c35d7d67658d4bbecd3880dfee16b212777f9961af8 +00 cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d a8e8f52ac7704630df1409964b160ad85a6e7504dd9068d59c3d4eca3f782a450d82ed29d20f173b301e687795457488 +00 b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c 92173ea3103a629711d85de0d6360372ba2c863017646d7eb7423438d45170e11cf21a24539e7a09c2371d78e7e1d40b +00 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48 994ea71ebf51344bdac134e7934c2ae44243de9e72414ef67c4954e2096b58205a03a41e0bf35588135c49bd95d23ec1 +00 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f b89d1c6df0546f6a4fedf5c0ee03a6c293df9c6bb8ffef806a7317bda0f86f7f43ee7e4bc4ee98136d6c42005fa645eb +00 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 b8a08f8fd06e139ecb6b65b5adb2b7bd8e3df6cbdba25a1d7f07352edcecd5b10a6da11653861f0cc37694c2c5802732 +00 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 a2801638fb4261b4367c8e480ddd39f780e7ede975d47316e47b86518a4156682a41b4f58239477162005f9a06ac631b +00 e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef 918aad4a5cbd18e9490bd58dfb1131616741688445a0feb350b606fa3377825de5483a8ee721b59f84510bd5b80cb314 +00 a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 a10af83f37430ffcb685237c231e916399feadb09e358b09d4e8aac18f0e21caf19ef86037f1781fffe57e84661421e3 +00 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d 99fe15b2d1ba6630b8be0e373ac63817b4826b1a2a018a71604061839191567c1608e1c01344443735f5376a14a2c1a1 +00 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d 985697c17900cbf196dcf15d226a252f2e16bbbd1c954f989f58e452918aac54e603e4c6914a6da69887c3f176cd6737 +00 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab 8b2b39624b720255ec50e04cb1153e11cc3ec4f85bba3626bbf600e623f28d6d43d5ed28f21431c1ea6395abe6589b3d +00 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a 96762cd95be6c7094504e7b0155a47c98827f274d957198fb8ee73b166f09c42af02ed4ceba1e41aded8fb9be41ac38f +00 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 9157644b0c6bcc32e1f6a80218e2f3262b1db799dc8cebbd3c32b4035c19ce75dfd175110ed2341534677dcbae8fd95e +00 f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 a477ae1e552c492a64efb4cdc8e560c16624415b5ddb364c2fc62054b38cfcc97e17db26debdf3866b5a5ad5cd8f682c +00 b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 8035e26bcbab6bbdf8446c2126f9232aabb9b0c577cd8fe96692132ef4b134795e91091a509073a2b40a8a39ff80ad00 +00 d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 8ae87d2be4b73e1d03dd3586eb8952b960a3bad6d393b089c7d48da31a7db9f6d8afdba2a3d6dcb1396cba9a5ce65e9c +00 b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c 8736da602e692befe98462d3d8093cc23eba8f161d327f7d824de5feb5cdd8fb2104f8d85dccca69f56350c473ca42b9 +00 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 9205ad1ce8d085fd58c7bba7550be5ddfc63e8526a5473a95ec03d83d72683ecc6a7f0d22af829a4ec2d2a96e73f64fd +00 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 a5d34d0f6a09db02f9e79fa5c395d0c6a99618dec9b8525c1b7dba486947b0d702a6e9aaa1108f57801259a308eb324c +00 b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced aaef5cdf272ed121c98a2773d3c8f8fc02dbf90671221df2fafc17f83ad26a370586a763f792fd524947aedb0a88f497 +00 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181 a5d97eb852c539167835b467b3903b29e18bd6d128f491c59d849c9637c4fc2210038983c24afe3173441a996d3cc116 +00 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431 b95c5e26396770ad272a31d4e8527b592422696fefc85b97ea9498cca2a6a0808f689ce98309ffcff72e6bdd0bcc2395 +00 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd b0dfca61d6731561d0922199e1e5930917209960507f86f1732211c42e9d0fe0ef465b963f26c637ca453366feb90e10 +00 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de 98fbe510b5fe8d5c7ae60055b955bc66f708734c54a5aa4adfc87169e23c4c20bb1f0aab6dd636af93ad54daff811a3c +00 ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566 981eaa7c203fc6c71c317e9afe25eaf4dccef56abc06a7c2642b1626f41c76b0f9e7177840f068b0ac3341ef7123e06c +00 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee aedb8fe65e059bcdbaf227c1a13574264e0c97fcc29e159878847899b6893f2a8d00bb4701b96311a3a3f610b6bde886 +00 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd 88ecf2c7712c5e033e6b8bd13b66bcbdf7391cf78e75c54cc534ffc1de2367e80d810796f0eb2b5d5d74f1bf0a75a839 +00 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666 82a855a47de1c124ef1b54d2570c5efea37f7d28df655c52afa7f0f02ac4cc89aa3011c14175ebededf64530168a5930 +00 bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67 a2d3aa8370901494fc0e819b8de5751b0a5248a3bd312c82dcc29cce97a918590cc1fa51efe4eb12b6d145485b388a98 +00 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9 92d9bfc48b5677fdf577f0444a1b994a0a6dd90d9ed6858765074f7122f422803a413c3a534134ddfbc68580b7d112c7 +00 f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce 8d8df73852b1768ec1c06e6e9b86ac7646ff6fa3385ac25677892f21e78140cc44867dc1fef6600817d62588b0c22875 +00 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f 8ac12c19b6610664bdaa7b5297f21a6438b52a8342cedbaec847d91898726f4f6ca5738487532c8a1f5decf1cb7b155b +00 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b ab0b15c2a419ca7764a3a41f6f724363d092cc6c97508a9752932d6f27f7e63e35e484dcebc78f6b8b7ff5ba30250fb6 +00 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388 876a246cc4c73004f348047327721fc083e5473fc80a825fe310b59b6e517b9216741b0559cd591c9252c2cd24033787 +00 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499 b017ce52161cd5a5f71da3044de000c9071560121d7778d2aff0519ec91af76478d834e3164f33d1c736be9b5769c448 +00 f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6 ae99c9e0a4150098e85467ab8d4a8a8d649478b1a4820852c6b02fbc9d23ab67547eb1473a9442768b65e11459aa5e9f +00 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead ac9f9ae9850b46f5f6ece9e630ace81ddba513d0420d4ce47c7206827196ba4220fd3bd3d09536951ef7cccf4446d836 +00 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd 84c231806f222e335d5016edb13ff63dfbf36ff3ca4eacfd31d368f3542b92dc4918683ba32c0dd80d90debff27d8289 +00 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117 8ffd4a5b9b18d312028fc9653bb933263d5601acbbc8096140d8862a930aca1484b499077f10d5d569913828580fb21c +00 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61 884d284c68aafc16dc2ebb67df715f0a429f288d834cda442a7ffe4a62ee47fc1143973595db022d8fc038ce21e475a7 +00 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2 b359ca95cbaa281807dfff54b2c72b3ecc485991ee676a071d47b74fcc119e7d778d0414c8eeb2129351376300f480ee +00 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7 9913feb96388a8831b60fc18b8a978e83d1b4f62fda1ccf8f3d464a0868ac1f6ae0ba9d65d48fb64c2792bf985067abc +00 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870 aa09682edb4830e2bef95838e84256c6fbd8712ebe645d212902bd11816acc4a7c46a7ca0f86f2c82bda1a288abf88b4 +00 e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf 8d7348aab54a67c9b44b501065bebf7863c43dc356daf6e25e45d9247c8a79f4f520f361627c901318ba7c576c0852e8 +00 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c 8465b1a4eff801f14226130a676cf8f4869d02976d2276863658fa3f5146fe71218e90db46d6221c66128b13cd3a48d9 +00 f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9 b4672cf4305815c23325b6ffdbbe703e14b76da50e8c7ef8ece1bea29e33430d8dba2a06fe944081b29ed47c003b845b +00 f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5 af65764520ecded013fd041d0270d18970799515c73369c761c65ec37acc14315cf059d20a66a62a12686dd8edd14554 +00 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628 9952bf08b1dd0b63ea5f03fa83d9d1f0bad5a18a9a70ce8c0c4611d1c0bdfe74e624e28bba808ea5fe3fa64e1b38736c +00 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49 b19af415636de52d4a550594d62df961c5ceb59cea258f41c2aed00535790d21860695b972e67724455493ddcc6873b0 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P384 b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P384 new file mode 100644 index 000000000000..c630dbcc79a0 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P384 @@ -0,0 +1,60 @@ +00 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727 974f52b25e245bc49a800c2eff1a20aa2e0bdf5c04a2881ccb34fb1d47ffe07e93269c5312690b89fa298a1d26317729 +00 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246 b7f56d61afe82252ca6deecf51f741e21b7923f9a72dabfe02a847212fb87733aca532b94d29b5c30d0d5e997010370c +00 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83 8d36e04bc1de27cbe3d7d56c9240ab31b9439b39a50737159c9119ed9fef1d63414310a9999d18cd75382379c5f48ac1 +00 dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659 b956b44a3fbceec6b0afcfef077c96fe4a6c3094a8f9ef53d648967252ff4789fae6ec92ed92777a707497c7a3572978 +00 df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718 b0342ce1cc18ed4aa3c20b9f3b86329e0173342ae504c02959276b29ef479ca48ba562b2f6fe3f9fd551c77bf1cef755 +00 ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f 91ebbbb45a602924bc47a5a03c9d0a012bb88997ea15b3e867a87ee3c12434f39e20908a5d2b7f52553582acef4678c3 +00 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829 91ec69c948c7678081b90b374698f58086efa722bc7d3c04acbcfae65378356d74eecea9aa722f0659e1ca6aa4f2a5bd +00 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1 aa651b0bf27db9d5be5c7f28e8fef95178dd8b6f4336416be9d1b28ae1775fa58527363b49d1b2a183436f99af2f2966 +00 e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d aed08563a82501ff12b33027285c9d1bf034c95ae28160eb26bc147c5beda1d33cf66516f40abf64c4d42043c70fff9d +00 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead 90b0ec5280e6a644694ad1bf68f6e12e843036780f2841c692bdcdb79d647fa469754188f6d1e3338dfa758fe9a4cb1f +00 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0 b4c3bd5c96329169f2ecf6684ba742d3b3350663ac4a6699caae37dbb7cef3a69a5bfa4101a46190fae4d00846aa99cb +00 f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1 8d3c178d822d2281cd8b56065f21a9894b80a7584b61781a95c841b16a652ab14dc25cd276c06602891cc50102e0294a +00 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb 84b7a49b473b39ad4632fb106471243d6c2f6c37e11c28869f41f2eb949bc9853f0d6ec41984335c12c7fb8f8a567c6c +00 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6 955050d26a41710b69ad61df7206dc4202ed880a3b35014ffb0b4b5addb608569b21edaea9ceebd8a986a782362976e0 +00 cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd b179d7e1ff524b5ade50f168e60c86f99b170f589c868be96222412e0cc278d018a208a067a851f25fb44a13df8c61df +00 c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b aadd4eaf37241209c5e8e43807c541c38d219a7cddd8c4a7937a8aedca403504632605c8dae9d6434fa661bccec267a4 +00 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9 8fcbf7f521e48ce280cdc5a5b17438f5bc8005eb14fc91754960f381d0b3be5afcba66013b2b9767f5fb9ac973d0a916 +00 d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f b35ac4b1911e5d8a0f511c17799d083fb179bef7be7d00aee2702910b4f8a945eed37e299890baecaaac5add9b5ede75 +00 d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3 8f1ee27b97f2f52f09ac8ac813e0f0b2d56fd3bdc7c0561b31db345b2ad0d4f68924827c0362d5156cc56921353a4b0d +00 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93 a1108cd313a6bb81e9930025bf3fc859564c3e05ae06aa6f1e39385f56edfccf57092b69d1396e493b9432b28db873bc +00 e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1 a47f140743a75a00555a10b3e42087958c99af4bb3b29ea2b5c2468798fe6702f923a79ac71fd9818c64c8101f4052a9 +00 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960 b2bee5710b31ef7e12b99b7f0ef977970558f4eb4c1f9d5924c883bfda7e72733c698c64cfe70af5f5c6a098bde5a031 +00 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57 8ef67f80eda0c4be8644386ce1b75d9ed5774caec367238c3933ea0509c85095a0edbdb91425338b3290af2bf5e9598a +00 a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1 82a00dfa233d7edcb7c893c8598280e803bca5488bba52b8bd1bad0d06a3a734ff7e2cb028f7ba81bf6e21d40254eb23 +00 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3 b99d671164a63b833995fa5ef9ed25780ca0df04f6b880607065a49e60134bd7172d058a627204dd27cf1d607f9ed661 +00 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907 929af80f244ab7d8a0f8f92a480c1d70ee60c0989eafb9eadcdf98eb5934cf5d55df69aad87d667445d4587c68accd4e +00 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245 9081604171c97c8b04284131a00cea80217328783a1faa924c3ebbf5b8c1201361582211dbe86bcbaa8fbcdada8c8fed +00 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7 ade1fb6b28a01a35c455ea89688f502315a287112b0df7b82be42ee6191394380317ebb899afb1f5b4a1793bb5d6c53d +00 d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5 a1257844dac2f2d6f8f3f38562c956d1d9a2a6c7c1f357d329394ea6b076851b0294e5a7ae65178130683ebe3dc38849 +00 b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224 88cf1faeb3aee7f367439eeba894173c371a98c977ed83048f7356656aeff00be3f6ae20872913965bb0801bc5a55cac +00 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 ac93acda52555babb366e02b8cb100f600a395b90160730d690b8831b319d39a3c7d2ba1d694bcaa4beb99d7e19b86ff +00 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 96e07f5b234ba03436be692259f1d49b526e4c671f7eeeb3936e575186e31ce7b62d9b9ca78440bf51aa55b2d74887d1 +00 b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 a193666fd0ea217dff52f60d74da10db2756b3ad93609915e6940d9394ea62f128bb5227b32f0bcd9c793fe115c07999 +00 de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 a25b5115b457ab0eecfb98df3ed74607d51308fca3f5d0fba4e96ce8854fa1219d4eea22b37040861f233a300e9af239 +00 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc a7356c0f8a5779048c4a628ac9e20911d4e93929de2fcd5487f4687858f17308d7bd63fa047d5e5ae7451892d018d0fd +00 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 aad0764df880f837d2c4a1240f150d3dda460a9931da6a571922db68c638491e3e1859530a95d6ee8814449bf1ecd100 +00 ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 b69bfa98e89c62c72e6faa4e3e927eb34c0e749cef85b40c062701cdad8882b10785b6f5436aaa3b00922746b14a27d7 +00 adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 a723df13514b2947b07adc725040a06321ff4442d372e891e3a1e474849c28fe709d775491b1b077b047c46692912130 +00 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d 8f64a31ecd264cb09895db820a4987ce0564359ee42c77fec5bf915ba463d20b318f98de06b28ee19c0c07fd7820b28b +00 e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 88d65f68cfe98e86c35511c6ee2bb081ecc3ea45f5b332186a3683996f97403ac7b3c1cbf5625397a61c15a8198bf69a +00 d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca 90bcce6a51b6f1472d646598621c066bbca4a00a91e6d2dc9c862f9a1990e84398c692bb4c34d7980b892fb7a3035115 +00 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d aff0ad6d95f634cc090cb7002e988f20a4f94c6a7816046230d8bbda95e7c4a68eb8ee18165f704737516cf358930436 +00 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 84806fa3b3930bfcc37b4a808bf0880448c8bb2af57fbaa73785274f1e6b835996adb439baa1ae314277a964f6b0dfaa +00 ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 b0c9bee4aa3dd6dd6fdc0293dc33176f8c25693d0411912574678204746ebed517bf0dbb3474381ce314737181915026 +00 e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb afbd67f80e6775bc1bc63fd95430beebe779400859f4151690bde973e2fa64fe81d96eeb1081d566fdf6235ab469bb0d +00 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c b032bf60536ed4d51fa3c7017e690d842c3334a5ba1c07a547741df1bf607e2c18980e049f36219d13f548b9937e3a8a +00 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f 8969d55fe5dbd9998911dce23b30d62f281d3f379045c3bff0a1bf4e2797ef15124c82a9db80f1083e038d18d4127097 +00 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7 b7789418c564b60705d4b1ed79609d3251f2883bac4dd132fcbd6d536364eda2053f936e5550ae2c2be2a21bd1a06f74 +00 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf 8133007b05e4735dac58f429cffabd3c86970c18f58ea8fe579c764f4eebeff26e3a9c0989a3b8ff94aad1ef55fba33e +00 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b b7438492228f49a8a971c9523ffb22957c411a18437f44cf196e2b704af7bbbaf9ea7d0c6a90d11bacd1b372ce91d066 +00 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69 b15417614e7e54819bf3f0f66322a39cf11dd92d7e4538e200609351c980e69bd8b5df4eab7073790796b37742e06269 +00 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db b48db4ced5dc31a9e582fb68d9e29a8764737abfa999c92bdfd67e4571d82e80851fc9f2def951a548bed712ada1048e +00 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d 80b3fcfd95918e40fa74e51d2a7a1832fca9faa053d31c9151e8458774e6e1d1485e5ce163ae020b4f4cd2ee604f9582 +00 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476 84d0c11426bc92919cb97e09d019f1d306dca8fc47b4f2e36d4d52e1275bd62dd1a9ace14d0961ed6eb1dcea1f05afd5 +00 ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa 8d981f283ccac98ccda7b10bf9512cf34e3f376f569f13b84d4a837cf1611b743f254bc6e7b1fa771b887d2bd61692f1 +00 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f 81598e05f356fae9fc5db4fc229d1fcbf5ebccae49d9ba567c1a864b9c2535363ce44f67ba2d041974c604c260bbcf1b +00 e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1 a88305457b7f363bc9b272c95bba91ce4f5f7db75c6b2219e9c37b9c80245ffe33fb08429531bbfccf608072a42e6277 +00 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c 91303ce37e5429ce8eed9db114859528f2ba90f5ee8f66cae8d9d59a3ca0731dc8b8053cdd6ea91496713e2455838be4 +00 e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c a04cd297bda156c802bc19cd455e2b51c700f6082e989ffeff32345eca8ba19dcf4e733f5388863b768406f212950a98 +00 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855 ab684ead38bc3774ddb453a3133dfd4b641c6c7d5311165490946c8f48da9b7be65c8f27880fb731abe1f54a597e1a79 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P384_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P384_blst new file mode 100644 index 000000000000..8af12d717fb8 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P384_blst @@ -0,0 +1,60 @@ +00 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727 b7adfca983e9ed236e67b13b04aefa256d8d1510f99de5bce2622ef03600aeaff79dc75440f7dc9790d4549d8b280be7 +00 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246 aca5c5a483f1d0726f1c4d4dfeaab534bf084c49a200d261db4b2ad0abc39b94f1711da2ffa040822488c273f0087952 +00 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83 8bd50cabae0ca8822d757a9e1b0e9afc581450bc9eee161baa3a8c6f9438fcac281f92bfdce8295276ad589e9e72dc90 +00 dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659 8feda828f08782e0dc1126bc03384b6db558bf2443c9094bb8afdd1785d5e2a317b7319f811b863b07d709a797b8645d +00 df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718 80bfc56f8a538a68a4f9877f2ef099c261bf4304767df52bd1eb719d4b62e6cf564d3bd92453397d6f8462294deb7333 +00 ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f 8c07bcf036b6b5558656eb3cff55fd8277b7b8189961b40c31593b30238323343d6eaf11fcddfa96ba8bfc5e211fa1b5 +00 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829 81c93720a4bb5fe4e5c8671400bfe9f768b172a9e2108bd259f034ac0a5376d924cc6c3b425bada208914586c48fb838 +00 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1 aac35efd7dbadd40f3837d76477cce6477794044c2d03226cbb273217e790ba21db02d5d7d854bb1066d5851a5771774 +00 e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d ae40ac0c07a38339f194b8d0cb97dfbdb4d76d200c17670c425f4963692bba54f7d25c419ee641b46ef10ef0648e5a0d +00 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead 89d234c5f0510986dad415f40ceff4fc9063e9d3b46b3f0bb97f5295b275a698976a3cb7bd86dc13fbfa9059e42ff557 +00 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0 a4cc65a36ab4bf528179697628742ec293afeb58f83c525b503aece90f60cf59c5236ba671613d7a616032c7d14165ae +00 f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1 b3b4d289d6b3da5f0c6a16502757b2f7c5bb1eb6cc7e47732e7bd65ce529fd92c7f7778860b878c6a6698f4a5c6dedc8 +00 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb 918bde8ba6415b4ca9a864d35d453cacfecdc7a7378f5218aacf98e309e22ae1f3da664e90266409a18b7ebbbd21aabc +00 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6 a364dcbcfc7ffb09778ea1b1c3d6c003bb3489aef18fac63ad3a1d10e35bcd5add4e3be5e34b63cb2269271b45b4d2af +00 cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd b43c6c92143a45da01fafa1853f364496d30ed74dd6fd1515d4b4dcb1d0d7ddc4680b0f0ee3e07bd0dd8db104dea1cc6 +00 c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b b7c63d62a7dc8242bf4e39fe86ad3dcd21623dceb87e904846aec12079993c42f66a27c10419d39fc32a711a8945eda3 +00 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9 b5ecfe3b2cc35e616c4771f96113e57ef723937696207960dce947d14f3efc673902a2795b1295f9815d2ce1abee0763 +00 d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f 803621b3f6b6856b9ba701cb46332dc213ba074500004c4a6c73340c31da874fdce40c4a0f30455b65f8b054a9064f43 +00 d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3 92e6ae56b3c7a89e32c220b62b0fef3b03a4b8d69833deb014de9eaecaa0adb87c1a95368074ff868ce0dbd6cc48269c +00 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93 b238ad8420658ccfe9feca52d9a2fd8c7998537e9dfeae325c5df78a61630e043dd7c15306d57a2f2f1b8e8cd127c745 +00 e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1 937d9b67721008a5325a3d88d1000b2f70edad7e518d5be985fcb11c705a8ff57b503692749e132a058c85c59dbea307 +00 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960 8ddf0eb7e5a708fe23777d5cacedf9fb0840fec75195705bd48cb0b4abd2796c63c721225eaddcea271528b4a1d11f98 +00 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57 87797a995e976c954003066adcb9b1e9519449305a516168cf2a3a9d074409d3a41bc4ce0e7368abc3354a829417ccff +00 a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1 8817152668591909d7806301a8fe646400d9b1340e7a0f3dbaf035f2bbe860b93edfb25b5198c8577dadaa90a848e40a +00 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3 8bf9b72c9f0f519f3ff5028f1c5b3c114fe5b0b200ab3f8cb58ce4f2dcac745fde30d881527ef242d37aab5e0dd4b3ed +00 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907 827941eb07b25d54ce57698c99f66e35d6b96a07feb45bbc90e3bb13185c0c8d706479dbf76672233c442c41018d0224 +00 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245 8e6160a8b314133ac00ad795a177af9cbeb25f64c0d15863386f941723da3bcd2b34dbeb71d5a534449e69beb3e1953e +00 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7 a81cbd4ae0ca526c96efdbbb637f699f6561a76d0c530b284f79723b6a6874f17b42002eafe0e200a42ac22fef98f5ff +00 d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5 a637a4aef641e5957ce18577d12365df0591fd2f7d32851c708adac911fcbf4ac3f7ea2b6eec395cabd1e57cdf71d225 +00 b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224 b1caa6c1d12b15539ff1536f42b807226bb5f841b92bc91b8e9bafe7e15879f23901a2a91e8b853a8e11e6fcf34b66bf +00 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 b06c64918458e2ce2bcd9bc80d7107b03b39dcd10e2100f4525b069e5a48b1b3af2292c36aef7caca3b55d92291a4f5b +00 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 80b9fdc1e930849a63142be922aef9e7900f46d905782e2a91e2da45098ffc202f7697d920ba902b7691e1519ee9820b +00 b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 84e109873ee120805bb45e2a46fac227414ea843b00fc97d423b024f0fa66df0eb16404d99b32b2b2ab4c02559c26f40 +00 de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 8981aeb5bf53e59ce35ee1dcd0cf310569770c29c75a60467b44f3ddca2dcbe3af5527f2fc7a617b2d6676ea22b2b30b +00 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc 8ff0751a9cb6a8fad6bf2bcefca329173b9219b1e413b6de1083e72da2b59fad2858c342b31e16ec851e665dfd4aaed6 +00 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 b74b4a2cbf051d2bb79cb699899dcfd13fde8ed705d443640868bf33d8422e5fb8255a4b26ce759ee3598818febd5919 +00 ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 86cba293d43864785d3e595a1ec7b4b27a01d6d9d5d2411e8918847eb4cd92bd55dcf0157a81bf6596ae392eca7caabf +00 adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 92d3cea41fc16de748c55286042975f7e6439b531023c871719d3b9f5a22dc39559350ceed83e025637edbf569598542 +00 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d b397b1170ee2e72036279b80c6f806e9671bb4244cfe0cde8a84dde09512128e96a62af68046da6c6ca1691afc3f9861 +00 e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 a8323cbf6387bd1c4c0a62ceeec4dd08be752a6af2c4e80eb11f38dc27eedad316bc698b624a41f0aeeb60efde2a8e9e +00 d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca 98b35259ea21beb893ab669741e54976dccc162581a66cbba1c393fa1639c31c6e77143e89466977cadcaf5d1dbf0f84 +00 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d a241ed216041d727afecfe9b3e433f1221cb70f16ee7340df024253ad272e129e5698aae77f28b75c5d48bd8c297524a +00 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 a0d6bf198d803e05337a15d5b722c162e5bbd3c3c10e2812fd3c6d6147a7e2b9cdf9d5f7c623c0d2f96b71e47eda7d85 +00 ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 b7a58cff606fdfe62e60320a6fb72c5668ff486da725781f05762d8607abee109d59edb503a3294e84ca8827621101cc +00 e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb 84ebd3e7ee1553b90c9f42311ad63d5924130af004465720d0c1a1c9064ba9ccfdcf2d16fc22a1d8c369fc18073ea5d5 +00 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c 8a6878651f14edb3289339013bc05161832b61a77a9cfdd44409bbb7aac717b49a87bddd9b7e4e5ed74c8a597a47adad +00 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f 90861f5002c83eb8e3fd9cf68ed74bb737696380dfe60c3d347bb9163b0c30c088f444708c8f7d416505521832cd1f77 +00 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7 a7fb662eaf23e80f7e4f443b23dac54c0c0ee230d35a65c4ac333f3242a777f3b35d76e4a7b668d33f69a85793c02443 +00 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf b78a712357b577a32d2827a70a28e002c9727a60d900eb7c3dc1beee36596984d740d926fd81bf910eb0913df0daa161 +00 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b 92383a3ee8b42984181bb8ffd44a43e4be1147d8c3635050fe5b0d4b67a791cbb7fd57d8f70eb93c4b99af1546a8e059 +00 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69 a5f5492b80ecb667d164175ad686439c8a62208dc30a1be84f531808e53b4721577a31a6bb9dcb230691203552844087 +00 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db a8c59802647c475dbe850e77fc02f94b89d6a04470f1d05d8225c45fdc1ad3cd97b9ed42e77db4aa996af6771b780c8d +00 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d 8fd7c5b734ffb52b1fbf3cb33cd000a5a44187aa30c997b34273e9fb273aea987cb3f123443b893b6a2338cca60bf0cc +00 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476 a1b5655d945fc53415630b8d9a425de47178a23084fc7436f9b2a7f9a7d4a4f55cce16a6cc9a3185e681ed3a97db82ca +00 ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa 9391990d0cd9206bc478940f027cf1978bdc7d1099163f135cde9fd5ee3261ce67275e1b6c0d1cadae6aa563a4a8f3cc +00 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f a75bf61cd697b1a9dc5a9be90529f67d77364c14c4701ed171dbda7e63d81b54a971f2b2d540eeecc388161ab2646b42 +00 e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1 ab53b259b9fa6a5a0893b788653ffc36db7a5fd3104fde9495db9b1f8d5967f4b59c67a89ed4f47f70b8e71d356d578e +00 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c a50354218a2a7c6a7337096ae515448e62aa937366d9ff46d25f3b0b10a1122237013cb2600e4064ac7d8bee528aa2cf +00 e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c b252a109ada8d75847f17cd39b6020ee1b03f78d9ebc42b503e756c4c619d9f5cd6515a4355f655ed28bc88e012917b6 +00 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855 a939d298a3d0997c75edff4f3afc8046495540ae530955b031a77e043edc8a27466ebefb64b1cb930e8815628dcfdba0 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P521 b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P521 new file mode 100644 index 000000000000..1497262341b4 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P521 @@ -0,0 +1,60 @@ +00 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46 9845e98a6692d438b5b5501b960194e1e98704ce7ab3fa9831662ca89b5a628030fa03a88ac1ac8270fb059bcdac8cad +00 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73 aee2168804b9e1e962c108014aa01a1d725e6f4aa6f4dc6469a097b4632a94d839039a5cbf64e3d818731608248b201a +00 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace 923446298f852373edd64435bb6d845ef37df29c98e587137fcac528d5ed7401395f5f21ca650b04f8a1d8c5cf23bd06 +00 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc 90559c65acabbbf67d2fba11fa3e65a895ab792872b6cc3ae317189f96c13def6e0e7cad81e75b1698f5517b88718cdb +00 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549 8b8bd1f0410b6a9b2f50916091b01cca4393f10f0c9e4cb409868ca571488b67e3d6468b651202b8abc54bc3527ef747 +00 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4 91cd615dffc5392caa04c17ce47d66ec0df85ebf436a4373142d59a08696af5f4b583b2448a4dcf23dc29e7fe1c7f184 +00 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16 a14ef90e08c2711091d910c838e811a3e558dd8d73b5ff57f9fa36b9a0f4f4a5933809810b8285441e15f8a0c4be81b1 +00 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37 90e2dbc865c0050ce706cd3a2c85c341c0b63e45ef714a0eb927dad4ef9743d41159d96c6f440cb2cdfb6405885f50c9 +00 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256 80440d1737d1d88f622d40a8a95e8d4ef7edd340a9c2971e2e971daa2504361f003d5b4a13d80fc611580fc85be28439 +00 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7 b2d50780b88051f460c94938d3780f708c1fb338e5347cc4217f194e995a39f55f5a721983d577a6b79562018f27bbcd +00 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73 892f6f6fd325f9803d3c79e73ea888267db5d3550666daf0312eb1a46dea1bd7d66116a2dcfd366b6c4d228a3917d6fa +00 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c 976e91309e9f959bef36349f6ee46462b48ed9951dd0e028f37ee8cca43fb7af1d25da5cd017a51da60a1a50d80d4b97 +00 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace a3830f66626646bacd49f0e1b13dbdb0713e9e2ed6e4bc2849bcdf9d5bda1dde33aa6fd1031fade614f3ee477850ae27 +00 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8 855012e5253cf084543820a9d73d63ed3b16c021d5bcbb8915c36d12a9ddf78879a2cc206b300d12b0778fb0873ca980 +00 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad a696b0aa0572734d8fce29492fe69ec15b2a34c55bf2949189f4e20f11c5543a91fff9efd49c89e377575b30e55d4d98 +00 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a a0ec2c6b1bb8da76bcc56db766871613a61d7ac2e40d304aa3026a3884bd9f8c0b0be37d28fcdae97aa70a87f183b997 +00 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c 8339bbbabf4598104c8f24c5c3884b54c6384262358bb9e100eca3f799ac4d9acb3af56dc771f4e136fa6452c0a64b0e +00 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d 9310e7ef0ff8e03a01c7ed879dc6912d80e470de4d7a2013d9a827b8938652a2eac9beaa4d88b96dda0d515c9096276a +00 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c 847cbb024fa24a32dc2e90e509acc74a0ede2276c543323f4afdd6af3ee22bc27eacfa9d3c95181ec95d61d7cb565c27 +00 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25 859d835c9ed51bdc14967073671ca32cb31fa505cee0030b5095f81e7c3634f5c48774f160a25d631b823a1ebe3f643a +00 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf af99268c1b2724df24c3e8cc890287ad0dc917403ddd35e5077f5d967e939b5ee8a816be1877acf0dd44fa74120e0925 +00 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570 88f5767f48cb66469844aabcc2919d8122738525234e83c33f721b7262a237e2c0343b3af8c5eba442451e97abd79dad +00 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6 87d29d143ad165b8185c67c523b45ef1391a954a9f473b597ff7a008098e78d7c8af5eae178920994c960af5ba3eccef +00 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7 8e83b75f8ea8ecc520f8d09e056db5160ae5832d2126e5eca0dd20c06c29278698998acb1f223fa853b9098f1a691066 +00 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e 958c697827a0bec9c64973d790be07e4a7c2968099a5182d3ec071312de9300bbec3b435694b6bb06f9f78f270907bb4 +00 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938 91723f21e066fe6de81a1db3dfb1dc33b7c1c77042ae33317addeae5623b516fbfbd4b5e4385db8dffc4ac40d204da7f +00 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662 ae7b456625b112d0493397a27e38335023e78371b75c18e193820d16aff4738ad8d5d874217f52ecd673ac434e6ed777 +00 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721 b0f55b1d729ea69cafd557fb91d8c34ab91dd702e0888bbd6bf85e3ff7f8103c1e5ac2bd7ed8b094aeb6604d33eba596 +00 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e 90bafd3abd65e6d184d2057772d62efadf13f355d6fe143f6d48f0a370596cae2f46d10cb406f0691cbd7f1db8d4da5a +00 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418 927d413a56432b4de2ed93b1fd3b9dc6fce76759b082c42a83a4413e3bb4c49b317e18ab3d07afa0dace9a866f011599 +00 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950 a6e757b13accb1bc38a975903a99c26ec3a8613387c7d762875aa3e955a9a09295f4e9440078b1a309c6e10c4d2dce31 +00 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b 8e0f20237445a5f6000504c22ee928a2722cf45151da08b85457f8ef877ad4c85c67a08c78398d98f8a151b444dfc4e9 +00 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f 8a16cdc0b9a2a2b04a9d7c96b9509dd6ca746f0ee930f43290cb20863ff277127588c45f5324ed656faaa4866e6bb89f +00 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66 b01a789606e8484e60623ca3bf6ef8c52bef48a1fdfe70bf122fb79b27321cd9e8b3161dc01f9260a504d2f84748602f +00 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c 8f8c9321aa1a443580d5a50a0a217a7112fb61c1c769a7349fd215f61008b3a0b74ce311f14e7751bac6db4dfcb9a298 +00 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0 8920fadf68d5ebeaedfdfa1815bcd6cc5e9edaa028be81fcc36380881b7525fa473d4a1ebcf12f722cb4cc129ac5b5cd +00 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9 a1756344dd1a532011236e393a010b1417340d96d70433601ef65d4f6fdf230671f051b0372585490cbbb763231c3443 +00 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d 85fc0089a208f74a086067f367cc239806e9dcc202915c0c0331e1811fd1c5991d645c9044bf47563691eaaa0f1b5c80 +00 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490 a90914ddea70036f0995da084fef3ca9fa250815dc33579c5c2e10dd5cf65319aa2a28f302261986b690c08c76d56630 +00 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1 99c3a4d2fc2b660dbb56e7d8b289309666ebe577e4da0994cd00cf868790bd1c9fa0d37350e24e8c9c55fe8b75ef0734 +00 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745 90a57bec873e223bf3fd31c9698aa72a2b6855edbd381e2d7dcc0625f722697971b9a4fc1c1d7c90698c256747d66231 +00 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f 8a1a74a37a1a8842b4fd909dad5dc85c48f4d9294df020a8a78f24c32335025f5ed46acc271815b44fd20005fceab535 +00 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e 9100403f1f18cf272ff8a8e2a7ffefe0b4fb5badac2a76a0fc1e9243050f7aa54f43e10e8e3b71eb0117cbc0d2536681 +00 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89 a11756993030c7aac05693e1d5bb3b42a653f313363c613c857e763e2948a826376ef4d5c01a5e1fbb42a9c65aa37a59 +00 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a a0c4c2cf947de1dbe9f73555066a319381068dca8109891e9b1d249c76b6d2d8bbe514200138a353f933adbc04817581 +00 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926 b3542e39df0b3bf3177aa7e7186d9d7fcbc970af9fb9123bcf8d197db9ea8ca825704f479610ec3c2208802ebb0f0668 +00 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6 b6a622f5eb76c1d352d34c2d4039a01f757979d8e99fd86f3d6673979a360d48dc13316ee32405876e3c74730e024a27 +00 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f a140a63e66bdad1ed3b7bc0418483d67d61ad4a009d0f6de0e259a93ba2a039bb57fb603d53d679a8ceca16f5f1b71c3 +00 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742 a8e4af8fe2e7f443d8689b9150594c226e9397d424d0fe26f16427d5283245614d82f2104460de87534bc2fd6977034d +00 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697 ae18e2111c9bdf03792106c8934732bd84c02f1a5dbce270ef91f441aeb8d74286f5bbbf965f144e41137ef8d9543ca5 +00 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04 a5a475a3868225218665b9a03f02926e9700597ce2d4a24cb21745a9506db6cae9f493f6d56703e05ef2289e8ed1a6e4 +00 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6 8e486bfafb10dd98360d5aa03695cff5ba6143318537cf771f7fca34eaf02b1725d002e8d9f39f75f791622340e53e56 +00 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e 85af238da56ecdc940338a34aeb0da7ec95273edf3d8dc42d14307493ee78216a3792c55d54cde868f159b146fcf46d3 +00 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5 b7340c678f22c5e9ad5179caf912d355f52b0ed616fdf392017d24a5b94db4f1936b6a9946a6531525dc12130d3d0821 +00 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a a5f6a70075270e8a191122576043f29667ecf8f61d9aabdec213784dd056387e57860fbd552d187975e49738c22b5d3f +00 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb 87efc4badb751a606798878212e29cacce520e499575cc44f0d5eb3f5e1edfa82f2821e1a72641d1a8496777bee90d70 +00 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77 aa95d46b54fba42148230a0a6171e56a8af6be6e2439ba433317b4ebbbd439fbf0b4b325eeddfa83b0d4fae5529f2730 +00 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c 94ac7ee0795ba4fc90c4fe10f63a28c86cb0921eac099dca722456533a3560935d64a6b273e583e64a7b015d3831a9df +00 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63 95ade772867129054dc39adb27d66c828272a15398c6d814eebd90456f5d84220fe7a8070323d8870f57223cd8421159 +00 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da a2ee822a9f3e65b8294b29ede1f2636648b75508783dda5660a6d6489d425da89c5905f110a1350f87f6ff6b33c61e4a diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P521_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P521_blst new file mode 100644 index 000000000000..7c0340914068 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_fips_186_3_P521_blst @@ -0,0 +1,60 @@ +00 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46 b25e6da66a9481c74adb8b60166fbe39bed444d53c8723836ec42ee782e95b4f6b0b368fdd4c28eaba936f177c204725 +00 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73 b9ea0299bce38aa65ca54a4b8913c0d56cacf60d5038ded6c17282fc09f6bf29d2b75911798ea160c7ec62c9ad363792 +00 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace 88a1e653cc81538ddc1ddbf1efd1025dcc205fd5cbb0d035a140cf6a15b1fae8ba3b8e1ae7b8c0ded03a8dbf88864e08 +00 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc a3219b1d64277f8312bdac6c6617740e731b8d7728e3923bc897204c23b14aac3a2d522eab8bc1d7aa6b488f6329ae0f +00 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549 acade52fe85cd374a02b6fc536d57e19dc3d0b95564e6adaa29e4f94a116f00a585ac8e372c8ccd03b32ffad04bd6f6c +00 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4 a080d326bd08bcffb2438a82f5a9237d7e3f5afa367814a3e318431e5b2211ddb398c086a5dcac7f88be2193fb4e6cc1 +00 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16 a9e31f5cf0499928a84976deaf98d4dbbeef0eb2d4d19e0739271b47294f9884aad9b5bfffa6df1aa0caa1ba59a69793 +00 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37 872e60cff80ff5aafb865f89b3ebd657d31c9c778d6e5bf817632e6350f573aa51ba9b028a098e2cba66efb21371979c +00 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256 81db17851695cbba01aa75f0e7d967fd67a2521fc5d7a0e00fb0ec2002cf8195b178c29a42c257e624fcd61ce2fe992d +00 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7 88386595dbfb4e4d5a0c0b4b50d2922073d802e295932655deffa55d00534e848be018481e084c267d838454484a79a3 +00 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73 a1b372fdbbf4ad7548444d5d3ca7cc47930646c488ca03140275914af9383918683c127b1881f8e5c6fe60b99508426d +00 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c 844f0c3574728f5c15a4c0835c155bd39ec0dbbfdaf170c9d5afd2a88a60a150f3aa748499d6bf7ef239447bd5a8ac1a +00 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace 925f2c2fff4b595046f29fa52ed97ed649d4b8f42b839061cae7ddb85da8853cd498c2099b9af3e75361cc9e0d5a05b1 +00 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8 9840da550ee77b309c60ce1664797ecf0cdc8e8dca0dd37466325cd5edc86f474ef5fc3d22efe5b1b229d357137817a2 +00 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad b906588f19e3686b762b7dec30e5468d83237ccebc4f21e5e64f19b72bf930ea48bed48d14868ef8f9e90b214bc33e22 +00 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a aad52601a9f13d7ee0e550fc25bbedfcb72c54badde13b56865cf5665af8d13aae855b6f496a58738e98387169840625 +00 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c a93d59e429d6402e8c2c1a55fee0fdbe6befa9f2643cad26358d771cedc46289878577e9d4647cd309fc44a3ae701e12 +00 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d a5677e9a841879a7caa554784afb0b52ceb5e97b35ed695950600b3f6e4ec98d59a77e2b54042c79de0b03347897e560 +00 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c 992e35e0b78e9b9b45099410c96b916b722052929f404defbb16171c2cfa8be3b2ca2e70ca899372783cb640550d3c68 +00 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25 a7105c7cf5ee589375d5ecc46160cefcc13f3d24a9a724e614b0c182415b1f3cc523b6a06d1e8015b86d492783ccb12a +00 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf ab626ec33cfca3915e7b77320327fd672460357f6b833e98b58866c961388d3bb594f1e42d95d197c5a8b824c7aa55cc +00 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570 ab772fb8afc0fd5fe924b80e80c62013fd4ed6eacbff03fffa42659e2c2937c5076d91857d07513869c599e5b9ca66af +00 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6 8064383b963d1b7be12e46753cc11510ffb5fb8a03354f3e18df76a72758429ebeb996bd4356f751be4303c2d750d36a +00 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7 98223c7f91b694580ed187de6b6272e1ba3ca03780051759eb563853ede63df56b44af2f20d418c07e2a6b28cd90bac8 +00 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e 81c114ff267b85b3be4fafcf770afbc9398996ee3da4ab9f5ff41ae9906449f86089d86b96f6e675773ab54349dce31a +00 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938 819f85e6e7f04f359488290284cd5e4959efc4c3d82bdee393c5606d3324c53948dafa9ddf854d322a5cd5266e28a2a2 +00 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662 af811bf9cd70da86ec10220bf337031b6824e2eb1fcc93c143ab191c1d8275aac39e9516d41f01a59fbb1ed55ba85717 +00 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721 871f92edc770a0471611b4ef39958c0a76f385980d47f2caddf3d326198cd9cc5b278bfff04824ac6be347aa43c1e10e +00 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e a7b36fc6929e28426c4b8209c71e00d83cf2021f4e656928d43d521da6491318469d6097fac7e0a5ccb163e38854ab89 +00 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418 98f7d937220610460b3b1073f8063ac8aefc26ae1ae23b08907b04113921a90465fa91d82532f840c5272efd09c05ce9 +00 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950 8f6d1852112dbbf94b92ad46f628cc8655e04d7c1c683c19eaa92a774d96ba9882aedee684ee70ff7f5c863ea1c88262 +00 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b 8bf38008d2a3f5b5746953b29d76e5861fbe88191b09f747cafe1f5d45ee6ffd581108d74d4c74d9bc556b370e86cd27 +00 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f 8471ac66114baf4bc2e7695841179353e4a3723b8f348027c4985bc63ea662db3351a1a9cbe02beca29122439afc18fb +00 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66 aa896c19d8299632a69df793b54174ede36a18dcdcf46eba7f2fc44ca6504bed4dfc67fa34bbdd6c0e2242f45a6379f0 +00 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c 956601ee94ab07312c51c90702d2602a81d91432e4caabac6a2ed2ce7a80ae4b7484f86a2b4c5d24995f4fbbde6e08ac +00 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0 8311a69e9988f9c3aa226460565ada2dd78151cb3acbb1bd60bbe1d5ca2b3e41e79218a59e69394494639282678746ff +00 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9 81d33e72bd68b9c40fe226aaba946a64437f377341f0e92153261fcbfa4ea44e27ca0e9ac4bfd04c12db2e4688713975 +00 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d 8b6c9d45d2f73f033a80150da4b2ae750375eb4f3809071c902ac7a48243a11762b59e6dde0ce3c092ba385a64eae9e0 +00 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490 98b5ee842bf3a04a13320c84949ce0497e01ad43be42528740c75445823ed0c8828d5e7a53e385fc856dc9d82a45ad22 +00 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1 b2f68671e8533c9accc8887081eb4269cceaa163aa11f03929e9b3dd7ffaed7499af3a819c884197dd1b5012250ad38f +00 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745 95868a500b94cb962d66fd55dbb4d4e6dc3335b2f005b2f026a766ffb5e06e6e8b9d092772143bc679ccf239c7ac49fd +00 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f b034e4115ac2d91f7b45c1adbc4acd04fbad70066ae520fe45fb5fc44c9db30582a2cbc620b9db399b752ecdacb28564 +00 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e a619bb4cec32975b3c961d695655b512aa02cc2452901202aee3eb12033a00a021467c6b6de559464a44f8e2bad9bbae +00 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89 806add9dcb75179e167651f4ff327307b8453558f2247f85133bf9871066cf43fa7be29ff1b587ad09234a81d1caf707 +00 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a 8bc1f18c167c3eeac37d9f9d906af3f6591c0067033c1f5df8ebd61eab3705812b726204611ed3459097560be051d8ca +00 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926 8c991dcadb1596f3f7067bc69b454d3c0dd0df72ff450d533b82ade98f3195b03cdb370ca92b0b9289b6039e7e1cf680 +00 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6 9727087528844a6ab9c39935c8650769094a0de808fcda9f66683ef95bb8696328764fa3bad78bac8372b260202b3dab +00 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f 99b4ac0a035d164f6f69efc867095ef0693a2582f9a75c675aca084fdec161bafd6f809243bf7348b2d2682a15be5bc2 +00 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742 b760a8bf5e1bc895fb648d8a39102878b662eb32702d07c545de953e2fd49472aaf5d89de0f34255b43453865be9415e +00 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697 b0882e99049b423249b0ac1fad705321be02b448d6140f338fd99f4489ff67f703a54b9cabbd9df2cdb67d0ed1a2696c +00 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04 a43019c82a40706e1bd300970dde0844fecb5e63a0167d1ca0a83b495c3079fca6490b017e867b75dc9d5832dc5363e1 +00 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6 9450db696afe0a7c0b7f21eb077dd68994496a3ef866d713625408c6f64bcc9072fb724334497112224eb5d35864de5f +00 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e b608f9964e4b8beeca2340d5ae32b8c696d89c5b5fae7c417b6e853ab9788d9eaf6dcd4d8e11dd79eae3cc9ac7e4d68f +00 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5 98fb5d59d5b62c428e9289017651942fc20ab2553b009c0a1db5ec97eeeca9bfc213827f5a21fd402b87b62d595412f9 +00 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a 83c2f8be26d3559a76c74cd91045f92ad4fbcd285b1fab168ff5a5647371c36644a7b5b7dcadac5483d31ba2a89111d7 +00 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb 98e3361e3aa3c84c2ddaf45a2099cbf7e46e512e4118300014a4f1abf3d23052ff1dd48c4a4d708674f9171c987f0344 +00 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77 8b2d8083ccba871f7afffc7c15785c5e47ce7e12276e0109b253aed67bfe948e54b44fef29fe359d8a59dc0e64adc854 +00 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c a85a228a3e68244ed7f11d454cd2a8739bfff16a8ca946f65ef22f9ea352038c410d37d5ce30a1fb54b09c5d979b048f +00 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63 b6bded241af88dd704f0926fb194c479d457559257f0118844da3bec504c9c07ce6f2a320856b923aa9cb7868768a641 +00 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da ab32470635374804f52fb98db2b1906e24a3a8c8813dea4b6e83f32178a16c1893cb57ad2088cb0aa28380e29723af25 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_rfc6979 b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_rfc6979 new file mode 100644 index 000000000000..566b6cca6560 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_rfc6979 @@ -0,0 +1,34 @@ +00 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 8276a883fee8c756749d8ca0ba0b8f941ddfa3705d24dd1efd5560c0918cc99567fd6b724d4f8b0cda0270e5a949940e +00 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 8276a883fee8c756749d8ca0ba0b8f941ddfa3705d24dd1efd5560c0918cc99567fd6b724d4f8b0cda0270e5a949940e +00 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc b9b994bf3b7465846fbcf30e6db5678d0cf49e51afd861858e24975b57f4e49eaa43adac71ef650d9ad86c6eb9a25941 +00 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc b9b994bf3b7465846fbcf30e6db5678d0cf49e51afd861858e24975b57f4e49eaa43adac71ef650d9ad86c6eb9a25941 +00 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 81695be1f1be9f9427a7895a31d0369b416324f8f732e943bc81b7db5321cb23d89261da87ea826e3906fd45421a8bab +00 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 81695be1f1be9f9427a7895a31d0369b416324f8f732e943bc81b7db5321cb23d89261da87ea826e3906fd45421a8bab +00 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 a9d1ff5d5b5e448757f00161e73d399a2bb746f922db87141c767e62e6d259122961d7c383b7638a864e0c129f746598 +00 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 a9d1ff5d5b5e448757f00161e73d399a2bb746f922db87141c767e62e6d259122961d7c383b7638a864e0c129f746598 +00 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 a7b67b161b1495ff31fd0f3b65c4c6dcd412ddc7827f8909b97911f2e2abd88fc2ff193f5ea701a6f8c04efe6e1b40cb +00 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 a7b67b161b1495ff31fd0f3b65c4c6dcd412ddc7827f8909b97911f2e2abd88fc2ff193f5ea701a6f8c04efe6e1b40cb +00 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 a7fbd08ed7b0463d6e21c77efc212e6cf3082a51f232365d1b1402b2ec7ebceabe7f74b96e9cb9d2701389cd7b65caf5 +00 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 a7fbd08ed7b0463d6e21c77efc212e6cf3082a51f232365d1b1402b2ec7ebceabe7f74b96e9cb9d2701389cd7b65caf5 +00 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c a22076614110787760e41bca7a16b45bbada287e52baf3b69fb0fac91183e367153051fd6031e118e09c54c5e0df3ce8 +00 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c a22076614110787760e41bca7a16b45bbada287e52baf3b69fb0fac91183e367153051fd6031e118e09c54c5e0df3ce8 +00 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 8b9342d9e1789d3de876a9b9de22247dafe798bb48655ed613cf5383de5016477c4f023794d5d77cfdb5ec24915cdcb9 +00 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 8b9342d9e1789d3de876a9b9de22247dafe798bb48655ed613cf5383de5016477c4f023794d5d77cfdb5ec24915cdcb9 +00 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 959d0ec18f6fbb40fb97b9f24ec3d7d6f56c758dfc6bfdc4bced9a747e8accb3b9b235d616fa0f92f1bc46582e61fcdd +00 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 959d0ec18f6fbb40fb97b9f24ec3d7d6f56c758dfc6bfdc4bced9a747e8accb3b9b235d616fa0f92f1bc46582e61fcdd +00 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 8113c8e1e4f1967805e23b5d447c27fe06ef2b16ddef7de879b2859de4989196f714583d487519d550775bb55387ce4c +00 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 8113c8e1e4f1967805e23b5d447c27fe06ef2b16ddef7de879b2859de4989196f714583d487519d550775bb55387ce4c +00 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 860003a318c08fe553192d0b34b0b8c946fac0750d1e288331a5b3bc13a5d3b26921ef754dea4329864ea11b0cf45612 +00 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 860003a318c08fe553192d0b34b0b8c946fac0750d1e288331a5b3bc13a5d3b26921ef754dea4329864ea11b0cf45612 +00 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 86d59dca0a6e4b805284780a9a510b0ecfb1af12e81bdbd6b28b7537d5c24e8440316e49a6e441f5e0cff5b68cbc925f +00 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 86d59dca0a6e4b805284780a9a510b0ecfb1af12e81bdbd6b28b7537d5c24e8440316e49a6e441f5e0cff5b68cbc925f +00 035318fc447d48d7e6bc93b48617dddedf26aa658f a1010fa8c631322f9730c734011dd8b686c28ed134557b1a862c86092be47875be554efc3f2b5f8bb1e72126f79c2cd0 +00 035318fc447d48d7e6bc93b48617dddedf26aa658f a1010fa8c631322f9730c734011dd8b686c28ed134557b1a862c86092be47875be554efc3f2b5f8bb1e72126f79c2cd0 +00 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 8fa18ff6214f7c2f21d5ff652d69d614bc560e63066b36e23e17180a94924b8b0fe14bf90661b8a44bfd08627d5a7b7c +00 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 8fa18ff6214f7c2f21d5ff652d69d614bc560e63066b36e23e17180a94924b8b0fe14bf90661b8a44bfd08627d5a7b7c +00 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e 83886fcf3af2cb4cc0843c17ad7837424e8af2f9f48b1d70521b9e29d1ead5cb20392a1bc2f94c43bc56ec65fb655f82 +00 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e 83886fcf3af2cb4cc0843c17ad7837424e8af2f9f48b1d70521b9e29d1ead5cb20392a1bc2f94c43bc56ec65fb655f82 +00 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 b1bbd74a1fb153b32fdbcf88413a79b9d75ff800f65b7aa8d2e21110d6de11b58c90cc6448cde953835daf0b073b3696 +00 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 b1bbd74a1fb153b32fdbcf88413a79b9d75ff800f65b7aa8d2e21110d6de11b58c90cc6448cde953835daf0b073b3696 +00 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 903aaf27ff035fcc8da086fedcd818332cb69ca6fd710c8bfd20e11613596aace8fbcfad326090c1cbc785f14756bece +00 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 903aaf27ff035fcc8da086fedcd818332cb69ca6fd710c8bfd20e11613596aace8fbcfad326090c1cbc785f14756bece diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_rfc6979_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_rfc6979_blst new file mode 100644 index 000000000000..b97ec3269210 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g1/pop_g1_rfc6979_blst @@ -0,0 +1,34 @@ +00 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 8276a883fee8c756749d8ca0ba0b8f941ddfa3705d24dd1efd5560c0918cc99567fd6b724d4f8b0cda0270e5a949940e +00 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 8276a883fee8c756749d8ca0ba0b8f941ddfa3705d24dd1efd5560c0918cc99567fd6b724d4f8b0cda0270e5a949940e +00 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc a50058e8c01d853cb175cbaca20ee73a7b2edbfac3ea8a04f010908e2d763be4c13b2bbe0af13324b472b057ef81c603 +00 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc a50058e8c01d853cb175cbaca20ee73a7b2edbfac3ea8a04f010908e2d763be4c13b2bbe0af13324b472b057ef81c603 +00 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 81695be1f1be9f9427a7895a31d0369b416324f8f732e943bc81b7db5321cb23d89261da87ea826e3906fd45421a8bab +00 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 81695be1f1be9f9427a7895a31d0369b416324f8f732e943bc81b7db5321cb23d89261da87ea826e3906fd45421a8bab +00 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 a9d1ff5d5b5e448757f00161e73d399a2bb746f922db87141c767e62e6d259122961d7c383b7638a864e0c129f746598 +00 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 a9d1ff5d5b5e448757f00161e73d399a2bb746f922db87141c767e62e6d259122961d7c383b7638a864e0c129f746598 +00 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 afe2aea0e9f893759600938a0ecacea69c0d4663bf4869b371c4068e2b67168b25e6aac59b4d957d90a430d8b472581f +00 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 afe2aea0e9f893759600938a0ecacea69c0d4663bf4869b371c4068e2b67168b25e6aac59b4d957d90a430d8b472581f +00 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 8a6197a433a730b20f886ef9be7d20af3a5ccdd93589c09fc8771174c127209acb71ee5983b16e497d724d56f8f4224d +00 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 8a6197a433a730b20f886ef9be7d20af3a5ccdd93589c09fc8771174c127209acb71ee5983b16e497d724d56f8f4224d +00 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 98a5c343066c98c60c5be4c29687930f4cbc0ab10f28dfaf73a740ec83dd1352d6f8d6514f35532c7cc1cfa505771c34 +00 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 98a5c343066c98c60c5be4c29687930f4cbc0ab10f28dfaf73a740ec83dd1352d6f8d6514f35532c7cc1cfa505771c34 +00 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 8b9342d9e1789d3de876a9b9de22247dafe798bb48655ed613cf5383de5016477c4f023794d5d77cfdb5ec24915cdcb9 +00 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 8b9342d9e1789d3de876a9b9de22247dafe798bb48655ed613cf5383de5016477c4f023794d5d77cfdb5ec24915cdcb9 +00 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 959d0ec18f6fbb40fb97b9f24ec3d7d6f56c758dfc6bfdc4bced9a747e8accb3b9b235d616fa0f92f1bc46582e61fcdd +00 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 959d0ec18f6fbb40fb97b9f24ec3d7d6f56c758dfc6bfdc4bced9a747e8accb3b9b235d616fa0f92f1bc46582e61fcdd +00 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 931d14d7804e32efed979141a9c6c09e39151a25717f015d1326ed02b9e4561758e1eb8e87e54722b525c9a0213145d1 +00 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 931d14d7804e32efed979141a9c6c09e39151a25717f015d1326ed02b9e4561758e1eb8e87e54722b525c9a0213145d1 +00 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 b25b3b42ef6445209c2c886a88360d4c8a802bf2df7c60444b11a37a6de5b59b7452fa95ff901ba2ecd531376304b368 +00 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 b25b3b42ef6445209c2c886a88360d4c8a802bf2df7c60444b11a37a6de5b59b7452fa95ff901ba2ecd531376304b368 +00 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c b53399cbccee3ed366d98b9edccc365ef08ed51e88f1d74e64285992d67f927e421181836c472fdb81cb9bb2d75b808a +00 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c b53399cbccee3ed366d98b9edccc365ef08ed51e88f1d74e64285992d67f927e421181836c472fdb81cb9bb2d75b808a +00 035318fc447d48d7e6bc93b48617dddedf26aa658f a1010fa8c631322f9730c734011dd8b686c28ed134557b1a862c86092be47875be554efc3f2b5f8bb1e72126f79c2cd0 +00 035318fc447d48d7e6bc93b48617dddedf26aa658f a1010fa8c631322f9730c734011dd8b686c28ed134557b1a862c86092be47875be554efc3f2b5f8bb1e72126f79c2cd0 +00 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 8fa18ff6214f7c2f21d5ff652d69d614bc560e63066b36e23e17180a94924b8b0fe14bf90661b8a44bfd08627d5a7b7c +00 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 8fa18ff6214f7c2f21d5ff652d69d614bc560e63066b36e23e17180a94924b8b0fe14bf90661b8a44bfd08627d5a7b7c +00 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e 8f4e51a5714178e6cad4bf38670d2c4007bcc469746cc89fb7238dec82844917575b811af4834d9bdcac380ad4000ebb +00 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e 8f4e51a5714178e6cad4bf38670d2c4007bcc469746cc89fb7238dec82844917575b811af4834d9bdcac380ad4000ebb +00 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 ae0f9523cdb9c8ebe5bab4df4cb01c2f78009ef3391c8b51cadb99a10049e530678aa938102c1140ff7fc5dec3cda5ee +00 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 ae0f9523cdb9c8ebe5bab4df4cb01c2f78009ef3391c8b51cadb99a10049e530678aa938102c1140ff7fc5dec3cda5ee +00 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 84c910a022e87abcdb7150dacd5221551d1c9aa3c453658fc6e5a311f83e04bb3ed9d935ed67667bc26c3fae1763ec83 +00 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 84c910a022e87abcdb7150dacd5221551d1c9aa3c453658fc6e5a311f83e04bb3ed9d935ed67667bc26c3fae1763ec83 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B233 b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B233 new file mode 100644 index 000000000000..3498a6dd3d30 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B233 @@ -0,0 +1,60 @@ +00 0056673197bfeea9bd7a8b820b4ae51a50411bf118a692bb9ed3d304da53 8d22b6d8faafe4feda7ca2a2402b7060355e424bd94cfd63e307ac61bdd98bc2875e355e5283934dc594bfc242c7449f0a3f4135dec32fe2a36888be0fb6d3279acd00cb1096fe8e4b09711871d9fdf51e0adc7aafacbd7ddf410b3341c6c12c +00 00468f01d483144e514ec257f2e5fdee28a927f2adb19714c1f3524dd0d3 997b16ed369819f18c4c99d2b593290424c2c184631440a79e49c1a86747a25ae772d5945db3a2a724f608e23ffc1ae106a2aee19eeef96c4b231f0a319c20b4641c39ad6d41e0b98469120ec888b81ec7fe8b20f6c3b45c0de27fbb6371a8ea +00 0074052d027f05465a8083a59cdbf32600224e1f563f653b34314651517f a3444439a4c9cfe150d735cf53ba1dba591bb658793938d46acf7ec55c243cd1800287fd2b76aa54e094daa2c6083cf7167a7d841e1e3f2e90294f8a2f1b723cee4201c2c924329d2ffb29b501d9d457373673d4f9e39243803bf9e44b2f1af8 +00 001856e7544223f55f80de72a6ef3822fa8fbd68eb397d06e2d76ddd35e0 8d5941c34eec83de09f74a2c95e707724c375301ea142e84d211f77cabd20077ff8cc95bd3f94dad8c74a165e820183411b3e9842f27b2cad3627a7bd283f2c351f27c8207e06e2eacc3419601fc8ab57c2c5ea1ef4188be5b5a91dd19b7a28e +00 00860aa2b589f2defc617be73e191502e5d9952bf60547fef19eeccbca26 aeac9a0da2a3d80cdc7014879d56e6879aabd491f27727577285c185e590c71f6aad4d102a7111e5ff81543aa4df3e1913bb999f44170e2b84fd03cdc6a334cd351d8a932ab435e0292cd3785130b9320f1bef5798201ccec2e5875f39524408 +00 00d0dec052a00ccebd0c0c5d9a08272f75744a2582cec7ddd924a2b022b2 b388f95112d27d26c2655b25f8bf9a70a45085c4b4f9c5479421790ea3ef0959c79541f1b4b92c66cc3cc5fce06d3e720664b63a4cd9133c8924de97597408fd3713566a5ffd9c7b688ef787b08b51786c2f96c34b3b5b8bcda2b9718f29cf9e +00 008a017d717d6d1213f2b74c53281b07258738c0c7db649ea1ac46b9a3b6 b5d299d9ff8539345471a887e72b7737886aa52c2afa9fa0b248fc8d1f16e34e42b6ee9e2ec596f6c127271a81bdb4e20cdd62957c4ea760b8566a07b646df3da4e55acf62bfe92f69afc8b481ca192c3689767918b26d7e0655a79c2581c6bd +00 001b56c14442b084cfd22aeef0f8028ec57c8b571c9fc1e43de05c45e47f ae32737157ac994d11a82d792907334cf6aa984c01536ece613290ca3495981b6ddc0177584531b53cff83284657044d0f07bb124b8d7acca15eb57166e4043c0c07e17dcdf47cc1467828f763f51a655496f8bd356958d3e28c14e80a183f1b +00 005afce37c5594586ac46a34ae291f591eacb9880a7de92701977f447fbf 89f31278e04f1aefbc074bd8668927c02ea45e7cb84a9200747010614d5e4163836352ac2bcf294ab4d5f753e1a6290712ebb41583b4961280941b42df2ed706bc284b14df4d5d2665ee5501429e5b803e0a7648b32a83ae0b6d229cc4490ee5 +00 000696df05dc7a54a9908a73eb18416a155cc8df4ab26032539d86eae537 b280b2bd80351e07b8785687115fdad696f5ba060bfadd9b5073a075d6a40b4c99439c3222af144764812ee3dd1538f20fc9307101c8d8b7020f6e8e7c9126665b66d32eae70de0678fc29750f3ee36ef4947ff3d22a7eff26b7d9fb93c78143 +00 005ca31e88c5b2e96e433af2023a66095161710628e7bfa428944d6676b8 98a5fd6c6e86a8beadad4c1b1e6109fead19477a47f68fadad6c345bf6c23cb7debdd4529ac3b9bde2884d65f6d475bb0a65e2de2ae18847eebeb6ab3b657f883bc966c26f8dbaf9d96db43bdbb27f05ef8b1dbbed3c3d7a810d3ef975d5b23f +00 00ef8fe84727a2ad8bf4e646ef28a492adfaf785a3a2ba6e6f985c649a8c a1e2083f9cdebb365f11a163ba8025171b2ef1c0dc60cdb45688aba05d5b87e774c09221f88cc169d332a7eb668da905046bacf7de557766f3af47d1eeadeff830329c525ccdf7436ddea348fd360c7e65516901de6c5d346cff766e2a514186 +00 003edb94b8c62f9af30c14a790c0f5d65e362a21cd8569b9725916d534c0 a69105feceabf48a4704a9e57cbe16ff3681441fa85706d42c6e1d6fb238ff1002e39354552a2e75aa2e0d9dc7aaea9410848f7d671eb1508671fb55aa353bdca66130c798565ec93fde994842e915bb57243fbaa24dd4756e2eef3f705af2a2 +00 000a7519be62562318da1b67d22cf8e720353d22641e0cee11c7a352bb93 a4598e2b9c26c20827e7e371b1d1312d110936b8d9a245ecce4b74895f9d02c00e79635efafbf61be14ceea45979597b0e060d271d8309d0e3aa63e32f3e9dd1de3457fe53fc562fec48a84a6bcad794b59ced9f98c950501183cfd72eb67df4 +00 00264022fd7dc2328a6436b522793ad9406d7a586667a0daaf1bce927338 84c6bc4a98816fc899d3e5bd23e28218e953c5cec954508fd3cc5131fd691143d9b645aa06cce80b626e4c75e87ca5010e292d3a2e69c15884547a99466713a578b595d60e19a2949572623fe36b3d5663acbc7d97f6c69e7df255fa6019b0bb +00 00da43214e2efb7892cc1ccde6723946d2a8248a6b4d6c8872fad525ec3b aba8f98c766c422ef5991500acae4ff2cffb09fdf0bc0a7906cd3d085bc9be975d7e20d04baa4bd877cef0a5d59358e307558bf1ba1c91efa2416ed68f8370bff18d0185e6f7a4d8249e3c63e63b6d608bbd11514ece20e4babe27596225abdf +00 00aeafa49d776b61f6a30d66ff64bd40dd8d79891dd5293c1b5cd3b46a7c 9382058a0e3a97f2af48bf86954cdb31860ae559b2a339cf62ff9c5aa155e0bd1c05fb7100f1093abfabb2a0f21221020fd8c98edfa2e9d2c08292da0555f16afaaf8270bbb4d7441f1a9d068925e7d6dfb5404ced783b031a538fc7c85fc208 +00 00e95db309f4305b621f51f93588a2678cb19aad0932f365fa0aaa3a3895 99a50f5658368477bc0225acfd548d652a24b4f4c8c3df86dfb422e2571fa3637de423b9d7beb7a1daae3c3e5ec715db115ab2acba94533106a8fe95a5586caf04e5c28034a345390bcbdce8e370e7d5fad23e448464b8bffbc5b3f9ed0bcbf9 +00 00d4319cc8e409b8755880827f3200d3f0f1c64d6356fe74eb1f5aa42499 a4f1fe70c42ed07b1defb9baa842205dab8d3fee080e1577a3143c46d4d9dbf012e8f43a722808f0459442a071ee096616918d1ec0aa4d09376af3aa8082f434c0c2af36606dde894ef72351e2b3f755a2afab29cf0e91836757c376165fce27 +00 009e556c945052e5954915c773b2d47970c521fcc99139269c3ef46093b7 84c1b73dac58269e13c2559da9e1c7b32ad0d19231c080b431c44412356a6c2aa765da2f63a3dfc3b28bda47fb2666ba19b9470d7932bb61ac049ad3395470f8df6c2c246840fb5db0af09766383aeb9d22258e54a63f6567ceb45f78d8fd573 +00 00becc76f8a77615c4f92ae1f91645bf5bb908e75ef22fd544aae63a3c8e 84e325e28b70bd765326eeac6feb4f3e7122781e0c2bbb5627c042913147a1cd375923ff8d99f9dba31a34c7319f73290d566c1f4a484af492ff199e4dbc9d6c078e83f3656074c8a1df91a7493dd6370865bbe762be6b6a505c50e7898cd82e +00 0020572c2a3dc3ea430cd8cde9d642081c21658e8bda165550cd9a5d37d9 b30a38e9f1b11f176623f4317bc4320e546afbe7ac105812e39b65f1f01e2a7c3a7b3086bd98ac920874f9b98ee54aca04036b5c241b1b172a3303ea30f103fe3ed3a7e4bd99bc5ab0c83a768933d1ca9a384ab80d880d5d9347dd02f2c011af +00 00769cfbf2dd8248ea1e0ac9b275c9d6ddcf923fe762079b9ed62ccbaa89 b4cf19b144a84619ec9947f57ed5324cddab065ebd7abc67300c3a647259d48444ff01cd2965064a0f308fc195cd9f4a02819688b46bfaac7e47456a110fb1383dff68dab4b817bdcc6ac495bcea623d307090838c2ff8fd149552ef9437f05a +00 0040ea4a37b388f0cc464f7e2bf92173107b268ff77a8acf5f517b4ec0e4 99a77dfc4bb140f8b3f1ce7e500bbc1a5a210720440fa6966432be9f61447a65a473b90841f47bfd73a62f908a224ed616343aa78d3d407517b240247f8910ff1eb9945d5ef1040d5518c55132413b18330df4e7cfce8908d03fd064640dfe52 +00 0037fc7898df9b37b5390537352f5c0b8de22659166c19d7d4df31c3938d a48d6afcb46fe5ff1c46c133a2156f36995c63ab3fd8c7e3a737ef9a1e2cc4e59b5c17c7f2831e448f1c2578cde1bb660c727f6c2e82c97d7b2d17cdaf4b8ad21bd839e4590b5d20f5d5085a462210def7dbe356c415d6f2c5acd57fbb03104f +00 005d5069425e7a9925d2cfc6360a708147b2c1b55ede243591885147ef3b acf28640646d4f9fa63986b1a7f8511705ec9cddf79ad78535c18e7a4bd044368721b617d8da0e74ce571909d970dc0a00d187ee8cb3f582e4a5dac323ef859f5dc62bdd9f049a5ec5e2f81b264dececc79bff78b28016890a8f40657a33e436 +00 00ffe3e7b82ca62b96e057ee072a4718ca20a6cc9a3e51e4fe8ed7b4b9f9 b50189a3792628bdb4b7a32dc38b24d1119f9c03c0cc215a93960f049ba353fee69ddc79248bf919db13083f9d9c1b810a1e4b0aa6f229068357620658686368e3d0f71e0f4fd5e288928d0fefddf6a9a5b1580dbee259c15cb14ecd1031f2e9 +00 0007a9cb5ce27c763646de414ca2a4dcdb774d69ed2bde7a817baddbc9de 88eaad600835e11a8f45eb50404a454419a88da8f1853f7dccc11a195012944664897f219716aa6854d87b384fd5f8b513af8787c52913f620786dea7a0fe2945687f063c3934afc59cebf0fab0a585bc59458c300269010d189abb7771b65b0 +00 00c03fa9e38dc1c697f70bc6381f2bacaf860bb5632fc837f728da959ac9 82596c22aeadb502ef962201ca787357b5e0ae3884c4a84406c9147c3b6fc838dea9e9712391fb928e8549af64cae708095f8cfbbbf213870e676c348a895c98cab3562bb7956e73426c8d179c4ebd24aff4c4b47f5a1535d6d04c88a2c56acd +00 0087dba00e3fe4802e01718017510094924496bd2785d4ac1a352c530473 84f025e1e555078da566be64edce0f6fb4e32664d82f5e6b57ed08f330167128e7f6bafee6fbcdc4e07f637ad6a06db9011aedf386c58d6d46604fa85fa2d0ef26e73ca630c324475f23afad876ff1975ba9ecc2707323803ff22e0d3c1d49fa +00 005a387e7affc54a8fbb9157b5ebd400c98e2d7bd5c3e095538987d4f8d9 a4f3b7ea312eb1caf9f273de3465e1a0a0a1af006d8e57598ab0c653dc7d7cc98cc90fa7c94e180d839e903a732c68251178489851445cf2e3c20b4f8d1642abafd837d11e6716b21fc8ca67cddb6a350ff1bb5a9ed0edb371ca9b4c478f7409 +00 00adae709a930d6f5a5c0e3d8ef4aab004d741d23f0ffb8287f7059890c0 b070e297f68f97fb86df765877f10f2be89ea930e404cabd1cc420d5aeab6e50b620fea4c885cbf4b4049b27b26099bb0ac99a56e50b3a7580b9d46b25a955f0b2c01b031fc4f4bcf52298157185bf698f2b8ea9f9b22b0f3ed9fc7e05702629 +00 0035d391411e6d679751092c4ea5a079c591e77ebdcb57c1d9006ae70d90 af6de34ce979cac011f30f945790aff802c9bd207a480913525c73940806f5c09c632c12c40802e24b413c718aa41a2318251ed2438106d23a98b6dd7dea8997bfeeee0eef7e18f8ee5e6b7641e5ff91538017bf740c5c192c5d70a69e9358e4 +00 0084e79093f1947d6ab9cf399782436e36ef87c59a4c090930c9a74ddb10 b70789709d847043723a86194b881e8d7399384d98665975196455432f568f09e9fe666547b68eee13a59bf08a76840916a79e770b8e88def83f759221c11f166283a74656c0e86010c6ef0636b57825131cc846160f0190b4b122b97c95dd45 +00 0079b6be015b8006f86fd81c2792bec6b42c08bee2d295cf9dc214c326ab ad6c4cffd7168904b5ab4401c0ca075d571d94badcd3434f596b5227d8459fd3ca3444ceb0370fdfa225b1c8df4f5cd70b6e73d29575ea2cac6fe200e5ddc450b2b44427b15000071f234b1cce6f58fec3bf729296bb232505e97fad5c8ad196 +00 00ca9d751a060fde64336cdc88122819f4b3cd1b4e7df42d495197787894 8d4105f5d54e0cecdc35686d9d209944d9bfefc460bd05369204bb2613f90066dd4e2fbaef0cdb97d102bfc92399eeeb0b1ba218fe6dc10b9a95c992bd9c9512dbe4e6b6952cbe68d0d946dabb42fad779b0ec1e5687681a09cf0004f8414c16 +00 001dde4b2d49338a10c8ebf475b3697e8480227b39bc04253a0055839e9e 867a97c385b08983f5f8f4d8bf4ee0a1f9fc45c38c1f63ea47bbc26bc08b2681d0946017ce9d4a1a663dbf0b1f6cf2c11281dbdd205aea1eda85fe6e0c441b00def4901ff8ca9ceb861654844c16974e49c5b502ffe1b0b36d0c820b49331101 +00 002c8bea2803fd746c874fa110a716538c179c82712f38d33d0f6d037e7a 80f3766c75b8b5ab0318698002051969af04179e67d946461c1e48e356f319d75e6d31df8443536ce5573829a1939a3003c06451e25477eecb99a0f213a10086c439e6a7f038657634137a7869704c9645b4858d33b459ae4d880fe32af261d9 +00 00b9119b3b4b30cbfb98ddf0a4f6953417e515fcf0e5a94e83ebc1d1d14d b0e87fa7cca988e15e6eaaffe1e6c08e2361eb3c7879cc0e5527c87139fca3f00076003b68870a02bbfb85558b8a7dca0c16323f5b54f7210d96ccfa1707cd988c3a2a159b480515084ae6c159e0ff9cd0b46d99289074b21270c741acfa4474 +00 00f4ab2a573f3771d1e4222e251faf14e06cefed544e804c299c9a8395f5 b85986c82adc0291f8285fc5c39fb434c7554d1628aa9cfb5c869031bee36051436fadd8dfb0307a45a3393efee2aee009b71459f5665c90e1519951c7c01786567e984c4dd65af3408aac37bb4f3376a5a01dbaface4a1a12cf5821ce8e561e +00 00f4649cf30d4a5269296a45977de2652cb06d3ca2aff4475bb24517b927 837da5b141e8563194872bc24a6876cd91d74bf93a83cb0d9c3e4eba3f4483de6c056b1121857442c87b5b7e70cbe8cc0e331073db1e0cca6e13adc66b60d5eb0958da77fdd9d587d52608752a4cfb75bad8300ed2c09120b2927a2c81afd4a5 +00 00cca24ad914c24c011f41f80d27ea41caf41fcc8dc9dc6dff5248b2b474 a275bebbd8a54a480b3137b2b758ed159da37304554e75114d6bdb4bb9e008237a8a55b997729c66806e641d864ec7c80d4f6417e820e0f82da5c42fcd7ce44fb1afa64b84f22980320fa50d2ee62d796f1467fadb67b2bb3e34d4200864dd56 +00 00f5e12d536ef327e3b0ba65ac5fc3f7f4880f5968f3340eb8868c1d47da 82635d1c528fa7e063c2a8b3e545eb333bb7c0de637ab4e6042a3ebe7c330f0078f9b439cb0d1584e5d25b6615f880ae1959d4c661baf444ab1250cbb8da8baa33816644656399e4395375fc3a239c3154bc1006c209966c6f9c114f8fd5b087 +00 008c30d93536b8cb132277645021775d86c2ba8f199816c7539d560ac6de 8624a33da9ea0cc13c3c9b126852a90dc61ea964517112970b04fd944f525a4d9e2bf6da60257dc235f718b4440aba8519e32cf33711d1e311778463d29c956d3f04e8e45584339b4c34ea70a4c4e4921e61336ca1f9693eef4233f391112359 +00 00fa3f15a506ccf7b50bbbad0a54d3223f5a95eb54f0d1f4e5d0cc21469b a9ed59d4a462750e4a62274af1520712ca326e069d2bfebe34e94774204f7eb4ca703b5a34e2287802affc14a1c80d930bedf9ef5a016f721910755b4f68a2d9c54f38f3366cf62a3521c9391d14efcd48654a1819a902661994c4847933c8ab +00 006400a4830889115aa88b860b3fb65905b01fd126c4aec2785518c2543a 8140fdc98be239edc1748a8bd728386cb23b3630e0e5665121f4f4f62cde61b673c2e5eff7fa200cd72eda3d3a17aeb3108cea90f16b5a6c09d545bae078bf9df1b1beb21144c48e0d79f1ff79c26ddae36aed9cb7cd1595f5bbd6b800b5104c +00 00c7b73c324250f14fac0edc941f79bdbc6933ee8f64bf94b847bee5eef6 a8955ac0826dba05c17ef4e784a8c417cac0d6c21297680f6c1a6cb7ba98e949d02138f554e9967c8fb1d1f13009ae9d1122acf8b9856de897612267b25f53259ec2775f3e4138bbb26ae224d0096ddbdbf1ee8bcbffccc0941ddab87a4c66ee +00 003db7f28e161abf52ab0adc8c4c8544fc989af081303b8688f22b7b2eb7 8cc193bbc68bd3b3bad5f28d13232706095f2bb3ea5bc5ed071c30de689f834bb66010b365a1337a985051acbd6dc56009e92261993a0c71f69d23cebc8e6acd7ead86ecd70e68951aeee8d9382f89fa5bb0c55d0cefafd2c0e7bc22c26eb499 +00 007e9d2fdd017d6da6029e88f78927d9ac9437f542db1f1fa99e32bfcf1a a22ef2365f8d0760de930e3635323904fd79c783582e36ace89396cd88c785433b16327852bf39f54aefad731377688613545273fe9a83eba734e7916876c99aefac251c5ff2b54bbc2bcb60bb8015edb7892d6e27dba8a6cee116036ab1726a +00 00c94052760fc74c2b405ee4dd5dd2a7d38ebc16df9cc32df706075450b5 9941064bb46e9919a10f1564d3eba9b5dfcda537dff53be90099055d4955f7378bdbb91723a6f144a3b7c290192bc40b18151ac0804144dfa315f573e309807a077785dedf683c5e59d9a257b32a77a8cf6bf09059a5f7dab3475a781fd3458c +00 004076b93487c2da8aeaeb4725fb53b7b41b465315335c18c6ca041175b4 881b19bf8e57b3401537695fe3c2f3f83837990ce55a6f95775a5def20776eeca4477db10f4f75b5054344fa9d0255b00467dd9e6892309e69d6a56ec6dec0fb3b133928b56970b6835839032588ea3cb2a89146b02f4aa2cabdae3d789ba59d +00 0076ddd73ee4fc1f5e6766e229cc7236cdfce312417ea291f7c3328d5ab1 8919aace7fad3114e699de352638d08706ab4a869961b04f30d73a4b5efdf33e9ae09432d429ce278f7206080a9deff600f9bf7bb87f6f36f68689cd80edde8007dbf24638097ad767a9fa34d3029d5b2aee74a8e9e22eed6edbfa8df23e855e +00 007e1f8988ad804aae7d09a99be19384cc599e7652c02c391542be74b17b 987db3916473cf973f77b3f89c506cd86ed184b61efe7a609813f4c8be15f0cc9913dbe112d1533a1e47b690f343e4ef017167a66b951cf11a280c2f639fb14a35c5ad08a74226f7144019ef367f1a1187480e82763ef55a1202803b25b86ecc +00 009b2292b0244c2aabe8b43d95039984d504ebe05eaff318760e4dee739f a4d06ef99f553af76e990231418e1ea718c9a898c8782dc73d7f838371eeb1e36947739a6e3ada2248a4af2bdfca131907d23745b39d53fc4085867fe25e13a71566c0cc734c776f17573b2cb4cd3ff647e843548763570008400ec5088b2cb6 +00 007ca463b50fdd92d9163f1c2bdfce2ee45ba1437b79162e3e959b814cab 88a505c682d76333551bcbf962cbe656643043132b9e293f4183237968fad953f124afa7a8f5228834875a1c6b88e1da198ea30bb9f1803a97ace236634cc6e35f44bf1fae31c0b6cc31966129f325e050012f716ee0ce39fa2193d323528475 +00 00c3844750f63fe0c2e930bc38fe88522f4e72a2fd0db9778ade20e939b3 8a47cb312b84c3cad04aa32e919f9b859e859537d56339ee985666a256367c324d757de3157d3fe2ff103765604fd116079bc5f0a3bbda859557a710a03c71a9f35c5e5ff8d3eba7d93ba9549aca3aad8412ede4332229f3d242ef70c87c7a56 +00 00a3bea235dea86506be4476eb7999dcb8e584a34238c4a894ad6823b93f 81b285c4e513395637d3f2b97d2091f6a0249de816142aeeaefc6a4455d8298a6fecebf422ab2aef8ec2fbd7d398039f0d016662fdf3b60b4be6cc6f6d8585708a7bc0ac449f86ca616dcb03db402465030d874c4e36a92d4c52168df5befdc3 +00 009a367cd1cffd8dfcca179e167ea437ee48e9b6f42559dda9224701d3f6 b96ece16ec10696bfcbb8c4fd6dbee23712d632144a56063d789ef0d6e34ba65fb5c6af5e49f4ab5132c9d108a189a4b001dc2f95666d9d94e96037c7a741f1920cb2f6f68e48513ac05c5bf32d54fb03cd615859e63e152c06fd67505d69204 +00 0046f4ad2522e78b9b35297d28f361fb0ce82306322aedc119251d8241be 83eba6ba487eb59a0d61046a86ae68a989256a7328b66ab2178f4a10634176ff66c392900894debf182a673b3d96f0a0182b3e65e50996596f3ef0cdc459385d6e339bf3d8db6e9a314a2200c5110d385642032c033eb17eaf32dfd9d2168775 +00 00ac82137e9c7a5ecfb8b1a7df9ab50732934566a392a6c8915ee8ca8144 89b3114ad04decaf0685a207af3055e7698fa7bb24f2d0477d812bc583fe4214514a1c968f2a847eeefe0cbeb24d2acb140701040c082cab665e8da31b909907f4bc3ffa51941dad3f28d82adacc21fc0f0d1899670c001439241570af5de9e2 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B233_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B233_blst new file mode 100644 index 000000000000..3498a6dd3d30 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B233_blst @@ -0,0 +1,60 @@ +00 0056673197bfeea9bd7a8b820b4ae51a50411bf118a692bb9ed3d304da53 8d22b6d8faafe4feda7ca2a2402b7060355e424bd94cfd63e307ac61bdd98bc2875e355e5283934dc594bfc242c7449f0a3f4135dec32fe2a36888be0fb6d3279acd00cb1096fe8e4b09711871d9fdf51e0adc7aafacbd7ddf410b3341c6c12c +00 00468f01d483144e514ec257f2e5fdee28a927f2adb19714c1f3524dd0d3 997b16ed369819f18c4c99d2b593290424c2c184631440a79e49c1a86747a25ae772d5945db3a2a724f608e23ffc1ae106a2aee19eeef96c4b231f0a319c20b4641c39ad6d41e0b98469120ec888b81ec7fe8b20f6c3b45c0de27fbb6371a8ea +00 0074052d027f05465a8083a59cdbf32600224e1f563f653b34314651517f a3444439a4c9cfe150d735cf53ba1dba591bb658793938d46acf7ec55c243cd1800287fd2b76aa54e094daa2c6083cf7167a7d841e1e3f2e90294f8a2f1b723cee4201c2c924329d2ffb29b501d9d457373673d4f9e39243803bf9e44b2f1af8 +00 001856e7544223f55f80de72a6ef3822fa8fbd68eb397d06e2d76ddd35e0 8d5941c34eec83de09f74a2c95e707724c375301ea142e84d211f77cabd20077ff8cc95bd3f94dad8c74a165e820183411b3e9842f27b2cad3627a7bd283f2c351f27c8207e06e2eacc3419601fc8ab57c2c5ea1ef4188be5b5a91dd19b7a28e +00 00860aa2b589f2defc617be73e191502e5d9952bf60547fef19eeccbca26 aeac9a0da2a3d80cdc7014879d56e6879aabd491f27727577285c185e590c71f6aad4d102a7111e5ff81543aa4df3e1913bb999f44170e2b84fd03cdc6a334cd351d8a932ab435e0292cd3785130b9320f1bef5798201ccec2e5875f39524408 +00 00d0dec052a00ccebd0c0c5d9a08272f75744a2582cec7ddd924a2b022b2 b388f95112d27d26c2655b25f8bf9a70a45085c4b4f9c5479421790ea3ef0959c79541f1b4b92c66cc3cc5fce06d3e720664b63a4cd9133c8924de97597408fd3713566a5ffd9c7b688ef787b08b51786c2f96c34b3b5b8bcda2b9718f29cf9e +00 008a017d717d6d1213f2b74c53281b07258738c0c7db649ea1ac46b9a3b6 b5d299d9ff8539345471a887e72b7737886aa52c2afa9fa0b248fc8d1f16e34e42b6ee9e2ec596f6c127271a81bdb4e20cdd62957c4ea760b8566a07b646df3da4e55acf62bfe92f69afc8b481ca192c3689767918b26d7e0655a79c2581c6bd +00 001b56c14442b084cfd22aeef0f8028ec57c8b571c9fc1e43de05c45e47f ae32737157ac994d11a82d792907334cf6aa984c01536ece613290ca3495981b6ddc0177584531b53cff83284657044d0f07bb124b8d7acca15eb57166e4043c0c07e17dcdf47cc1467828f763f51a655496f8bd356958d3e28c14e80a183f1b +00 005afce37c5594586ac46a34ae291f591eacb9880a7de92701977f447fbf 89f31278e04f1aefbc074bd8668927c02ea45e7cb84a9200747010614d5e4163836352ac2bcf294ab4d5f753e1a6290712ebb41583b4961280941b42df2ed706bc284b14df4d5d2665ee5501429e5b803e0a7648b32a83ae0b6d229cc4490ee5 +00 000696df05dc7a54a9908a73eb18416a155cc8df4ab26032539d86eae537 b280b2bd80351e07b8785687115fdad696f5ba060bfadd9b5073a075d6a40b4c99439c3222af144764812ee3dd1538f20fc9307101c8d8b7020f6e8e7c9126665b66d32eae70de0678fc29750f3ee36ef4947ff3d22a7eff26b7d9fb93c78143 +00 005ca31e88c5b2e96e433af2023a66095161710628e7bfa428944d6676b8 98a5fd6c6e86a8beadad4c1b1e6109fead19477a47f68fadad6c345bf6c23cb7debdd4529ac3b9bde2884d65f6d475bb0a65e2de2ae18847eebeb6ab3b657f883bc966c26f8dbaf9d96db43bdbb27f05ef8b1dbbed3c3d7a810d3ef975d5b23f +00 00ef8fe84727a2ad8bf4e646ef28a492adfaf785a3a2ba6e6f985c649a8c a1e2083f9cdebb365f11a163ba8025171b2ef1c0dc60cdb45688aba05d5b87e774c09221f88cc169d332a7eb668da905046bacf7de557766f3af47d1eeadeff830329c525ccdf7436ddea348fd360c7e65516901de6c5d346cff766e2a514186 +00 003edb94b8c62f9af30c14a790c0f5d65e362a21cd8569b9725916d534c0 a69105feceabf48a4704a9e57cbe16ff3681441fa85706d42c6e1d6fb238ff1002e39354552a2e75aa2e0d9dc7aaea9410848f7d671eb1508671fb55aa353bdca66130c798565ec93fde994842e915bb57243fbaa24dd4756e2eef3f705af2a2 +00 000a7519be62562318da1b67d22cf8e720353d22641e0cee11c7a352bb93 a4598e2b9c26c20827e7e371b1d1312d110936b8d9a245ecce4b74895f9d02c00e79635efafbf61be14ceea45979597b0e060d271d8309d0e3aa63e32f3e9dd1de3457fe53fc562fec48a84a6bcad794b59ced9f98c950501183cfd72eb67df4 +00 00264022fd7dc2328a6436b522793ad9406d7a586667a0daaf1bce927338 84c6bc4a98816fc899d3e5bd23e28218e953c5cec954508fd3cc5131fd691143d9b645aa06cce80b626e4c75e87ca5010e292d3a2e69c15884547a99466713a578b595d60e19a2949572623fe36b3d5663acbc7d97f6c69e7df255fa6019b0bb +00 00da43214e2efb7892cc1ccde6723946d2a8248a6b4d6c8872fad525ec3b aba8f98c766c422ef5991500acae4ff2cffb09fdf0bc0a7906cd3d085bc9be975d7e20d04baa4bd877cef0a5d59358e307558bf1ba1c91efa2416ed68f8370bff18d0185e6f7a4d8249e3c63e63b6d608bbd11514ece20e4babe27596225abdf +00 00aeafa49d776b61f6a30d66ff64bd40dd8d79891dd5293c1b5cd3b46a7c 9382058a0e3a97f2af48bf86954cdb31860ae559b2a339cf62ff9c5aa155e0bd1c05fb7100f1093abfabb2a0f21221020fd8c98edfa2e9d2c08292da0555f16afaaf8270bbb4d7441f1a9d068925e7d6dfb5404ced783b031a538fc7c85fc208 +00 00e95db309f4305b621f51f93588a2678cb19aad0932f365fa0aaa3a3895 99a50f5658368477bc0225acfd548d652a24b4f4c8c3df86dfb422e2571fa3637de423b9d7beb7a1daae3c3e5ec715db115ab2acba94533106a8fe95a5586caf04e5c28034a345390bcbdce8e370e7d5fad23e448464b8bffbc5b3f9ed0bcbf9 +00 00d4319cc8e409b8755880827f3200d3f0f1c64d6356fe74eb1f5aa42499 a4f1fe70c42ed07b1defb9baa842205dab8d3fee080e1577a3143c46d4d9dbf012e8f43a722808f0459442a071ee096616918d1ec0aa4d09376af3aa8082f434c0c2af36606dde894ef72351e2b3f755a2afab29cf0e91836757c376165fce27 +00 009e556c945052e5954915c773b2d47970c521fcc99139269c3ef46093b7 84c1b73dac58269e13c2559da9e1c7b32ad0d19231c080b431c44412356a6c2aa765da2f63a3dfc3b28bda47fb2666ba19b9470d7932bb61ac049ad3395470f8df6c2c246840fb5db0af09766383aeb9d22258e54a63f6567ceb45f78d8fd573 +00 00becc76f8a77615c4f92ae1f91645bf5bb908e75ef22fd544aae63a3c8e 84e325e28b70bd765326eeac6feb4f3e7122781e0c2bbb5627c042913147a1cd375923ff8d99f9dba31a34c7319f73290d566c1f4a484af492ff199e4dbc9d6c078e83f3656074c8a1df91a7493dd6370865bbe762be6b6a505c50e7898cd82e +00 0020572c2a3dc3ea430cd8cde9d642081c21658e8bda165550cd9a5d37d9 b30a38e9f1b11f176623f4317bc4320e546afbe7ac105812e39b65f1f01e2a7c3a7b3086bd98ac920874f9b98ee54aca04036b5c241b1b172a3303ea30f103fe3ed3a7e4bd99bc5ab0c83a768933d1ca9a384ab80d880d5d9347dd02f2c011af +00 00769cfbf2dd8248ea1e0ac9b275c9d6ddcf923fe762079b9ed62ccbaa89 b4cf19b144a84619ec9947f57ed5324cddab065ebd7abc67300c3a647259d48444ff01cd2965064a0f308fc195cd9f4a02819688b46bfaac7e47456a110fb1383dff68dab4b817bdcc6ac495bcea623d307090838c2ff8fd149552ef9437f05a +00 0040ea4a37b388f0cc464f7e2bf92173107b268ff77a8acf5f517b4ec0e4 99a77dfc4bb140f8b3f1ce7e500bbc1a5a210720440fa6966432be9f61447a65a473b90841f47bfd73a62f908a224ed616343aa78d3d407517b240247f8910ff1eb9945d5ef1040d5518c55132413b18330df4e7cfce8908d03fd064640dfe52 +00 0037fc7898df9b37b5390537352f5c0b8de22659166c19d7d4df31c3938d a48d6afcb46fe5ff1c46c133a2156f36995c63ab3fd8c7e3a737ef9a1e2cc4e59b5c17c7f2831e448f1c2578cde1bb660c727f6c2e82c97d7b2d17cdaf4b8ad21bd839e4590b5d20f5d5085a462210def7dbe356c415d6f2c5acd57fbb03104f +00 005d5069425e7a9925d2cfc6360a708147b2c1b55ede243591885147ef3b acf28640646d4f9fa63986b1a7f8511705ec9cddf79ad78535c18e7a4bd044368721b617d8da0e74ce571909d970dc0a00d187ee8cb3f582e4a5dac323ef859f5dc62bdd9f049a5ec5e2f81b264dececc79bff78b28016890a8f40657a33e436 +00 00ffe3e7b82ca62b96e057ee072a4718ca20a6cc9a3e51e4fe8ed7b4b9f9 b50189a3792628bdb4b7a32dc38b24d1119f9c03c0cc215a93960f049ba353fee69ddc79248bf919db13083f9d9c1b810a1e4b0aa6f229068357620658686368e3d0f71e0f4fd5e288928d0fefddf6a9a5b1580dbee259c15cb14ecd1031f2e9 +00 0007a9cb5ce27c763646de414ca2a4dcdb774d69ed2bde7a817baddbc9de 88eaad600835e11a8f45eb50404a454419a88da8f1853f7dccc11a195012944664897f219716aa6854d87b384fd5f8b513af8787c52913f620786dea7a0fe2945687f063c3934afc59cebf0fab0a585bc59458c300269010d189abb7771b65b0 +00 00c03fa9e38dc1c697f70bc6381f2bacaf860bb5632fc837f728da959ac9 82596c22aeadb502ef962201ca787357b5e0ae3884c4a84406c9147c3b6fc838dea9e9712391fb928e8549af64cae708095f8cfbbbf213870e676c348a895c98cab3562bb7956e73426c8d179c4ebd24aff4c4b47f5a1535d6d04c88a2c56acd +00 0087dba00e3fe4802e01718017510094924496bd2785d4ac1a352c530473 84f025e1e555078da566be64edce0f6fb4e32664d82f5e6b57ed08f330167128e7f6bafee6fbcdc4e07f637ad6a06db9011aedf386c58d6d46604fa85fa2d0ef26e73ca630c324475f23afad876ff1975ba9ecc2707323803ff22e0d3c1d49fa +00 005a387e7affc54a8fbb9157b5ebd400c98e2d7bd5c3e095538987d4f8d9 a4f3b7ea312eb1caf9f273de3465e1a0a0a1af006d8e57598ab0c653dc7d7cc98cc90fa7c94e180d839e903a732c68251178489851445cf2e3c20b4f8d1642abafd837d11e6716b21fc8ca67cddb6a350ff1bb5a9ed0edb371ca9b4c478f7409 +00 00adae709a930d6f5a5c0e3d8ef4aab004d741d23f0ffb8287f7059890c0 b070e297f68f97fb86df765877f10f2be89ea930e404cabd1cc420d5aeab6e50b620fea4c885cbf4b4049b27b26099bb0ac99a56e50b3a7580b9d46b25a955f0b2c01b031fc4f4bcf52298157185bf698f2b8ea9f9b22b0f3ed9fc7e05702629 +00 0035d391411e6d679751092c4ea5a079c591e77ebdcb57c1d9006ae70d90 af6de34ce979cac011f30f945790aff802c9bd207a480913525c73940806f5c09c632c12c40802e24b413c718aa41a2318251ed2438106d23a98b6dd7dea8997bfeeee0eef7e18f8ee5e6b7641e5ff91538017bf740c5c192c5d70a69e9358e4 +00 0084e79093f1947d6ab9cf399782436e36ef87c59a4c090930c9a74ddb10 b70789709d847043723a86194b881e8d7399384d98665975196455432f568f09e9fe666547b68eee13a59bf08a76840916a79e770b8e88def83f759221c11f166283a74656c0e86010c6ef0636b57825131cc846160f0190b4b122b97c95dd45 +00 0079b6be015b8006f86fd81c2792bec6b42c08bee2d295cf9dc214c326ab ad6c4cffd7168904b5ab4401c0ca075d571d94badcd3434f596b5227d8459fd3ca3444ceb0370fdfa225b1c8df4f5cd70b6e73d29575ea2cac6fe200e5ddc450b2b44427b15000071f234b1cce6f58fec3bf729296bb232505e97fad5c8ad196 +00 00ca9d751a060fde64336cdc88122819f4b3cd1b4e7df42d495197787894 8d4105f5d54e0cecdc35686d9d209944d9bfefc460bd05369204bb2613f90066dd4e2fbaef0cdb97d102bfc92399eeeb0b1ba218fe6dc10b9a95c992bd9c9512dbe4e6b6952cbe68d0d946dabb42fad779b0ec1e5687681a09cf0004f8414c16 +00 001dde4b2d49338a10c8ebf475b3697e8480227b39bc04253a0055839e9e 867a97c385b08983f5f8f4d8bf4ee0a1f9fc45c38c1f63ea47bbc26bc08b2681d0946017ce9d4a1a663dbf0b1f6cf2c11281dbdd205aea1eda85fe6e0c441b00def4901ff8ca9ceb861654844c16974e49c5b502ffe1b0b36d0c820b49331101 +00 002c8bea2803fd746c874fa110a716538c179c82712f38d33d0f6d037e7a 80f3766c75b8b5ab0318698002051969af04179e67d946461c1e48e356f319d75e6d31df8443536ce5573829a1939a3003c06451e25477eecb99a0f213a10086c439e6a7f038657634137a7869704c9645b4858d33b459ae4d880fe32af261d9 +00 00b9119b3b4b30cbfb98ddf0a4f6953417e515fcf0e5a94e83ebc1d1d14d b0e87fa7cca988e15e6eaaffe1e6c08e2361eb3c7879cc0e5527c87139fca3f00076003b68870a02bbfb85558b8a7dca0c16323f5b54f7210d96ccfa1707cd988c3a2a159b480515084ae6c159e0ff9cd0b46d99289074b21270c741acfa4474 +00 00f4ab2a573f3771d1e4222e251faf14e06cefed544e804c299c9a8395f5 b85986c82adc0291f8285fc5c39fb434c7554d1628aa9cfb5c869031bee36051436fadd8dfb0307a45a3393efee2aee009b71459f5665c90e1519951c7c01786567e984c4dd65af3408aac37bb4f3376a5a01dbaface4a1a12cf5821ce8e561e +00 00f4649cf30d4a5269296a45977de2652cb06d3ca2aff4475bb24517b927 837da5b141e8563194872bc24a6876cd91d74bf93a83cb0d9c3e4eba3f4483de6c056b1121857442c87b5b7e70cbe8cc0e331073db1e0cca6e13adc66b60d5eb0958da77fdd9d587d52608752a4cfb75bad8300ed2c09120b2927a2c81afd4a5 +00 00cca24ad914c24c011f41f80d27ea41caf41fcc8dc9dc6dff5248b2b474 a275bebbd8a54a480b3137b2b758ed159da37304554e75114d6bdb4bb9e008237a8a55b997729c66806e641d864ec7c80d4f6417e820e0f82da5c42fcd7ce44fb1afa64b84f22980320fa50d2ee62d796f1467fadb67b2bb3e34d4200864dd56 +00 00f5e12d536ef327e3b0ba65ac5fc3f7f4880f5968f3340eb8868c1d47da 82635d1c528fa7e063c2a8b3e545eb333bb7c0de637ab4e6042a3ebe7c330f0078f9b439cb0d1584e5d25b6615f880ae1959d4c661baf444ab1250cbb8da8baa33816644656399e4395375fc3a239c3154bc1006c209966c6f9c114f8fd5b087 +00 008c30d93536b8cb132277645021775d86c2ba8f199816c7539d560ac6de 8624a33da9ea0cc13c3c9b126852a90dc61ea964517112970b04fd944f525a4d9e2bf6da60257dc235f718b4440aba8519e32cf33711d1e311778463d29c956d3f04e8e45584339b4c34ea70a4c4e4921e61336ca1f9693eef4233f391112359 +00 00fa3f15a506ccf7b50bbbad0a54d3223f5a95eb54f0d1f4e5d0cc21469b a9ed59d4a462750e4a62274af1520712ca326e069d2bfebe34e94774204f7eb4ca703b5a34e2287802affc14a1c80d930bedf9ef5a016f721910755b4f68a2d9c54f38f3366cf62a3521c9391d14efcd48654a1819a902661994c4847933c8ab +00 006400a4830889115aa88b860b3fb65905b01fd126c4aec2785518c2543a 8140fdc98be239edc1748a8bd728386cb23b3630e0e5665121f4f4f62cde61b673c2e5eff7fa200cd72eda3d3a17aeb3108cea90f16b5a6c09d545bae078bf9df1b1beb21144c48e0d79f1ff79c26ddae36aed9cb7cd1595f5bbd6b800b5104c +00 00c7b73c324250f14fac0edc941f79bdbc6933ee8f64bf94b847bee5eef6 a8955ac0826dba05c17ef4e784a8c417cac0d6c21297680f6c1a6cb7ba98e949d02138f554e9967c8fb1d1f13009ae9d1122acf8b9856de897612267b25f53259ec2775f3e4138bbb26ae224d0096ddbdbf1ee8bcbffccc0941ddab87a4c66ee +00 003db7f28e161abf52ab0adc8c4c8544fc989af081303b8688f22b7b2eb7 8cc193bbc68bd3b3bad5f28d13232706095f2bb3ea5bc5ed071c30de689f834bb66010b365a1337a985051acbd6dc56009e92261993a0c71f69d23cebc8e6acd7ead86ecd70e68951aeee8d9382f89fa5bb0c55d0cefafd2c0e7bc22c26eb499 +00 007e9d2fdd017d6da6029e88f78927d9ac9437f542db1f1fa99e32bfcf1a a22ef2365f8d0760de930e3635323904fd79c783582e36ace89396cd88c785433b16327852bf39f54aefad731377688613545273fe9a83eba734e7916876c99aefac251c5ff2b54bbc2bcb60bb8015edb7892d6e27dba8a6cee116036ab1726a +00 00c94052760fc74c2b405ee4dd5dd2a7d38ebc16df9cc32df706075450b5 9941064bb46e9919a10f1564d3eba9b5dfcda537dff53be90099055d4955f7378bdbb91723a6f144a3b7c290192bc40b18151ac0804144dfa315f573e309807a077785dedf683c5e59d9a257b32a77a8cf6bf09059a5f7dab3475a781fd3458c +00 004076b93487c2da8aeaeb4725fb53b7b41b465315335c18c6ca041175b4 881b19bf8e57b3401537695fe3c2f3f83837990ce55a6f95775a5def20776eeca4477db10f4f75b5054344fa9d0255b00467dd9e6892309e69d6a56ec6dec0fb3b133928b56970b6835839032588ea3cb2a89146b02f4aa2cabdae3d789ba59d +00 0076ddd73ee4fc1f5e6766e229cc7236cdfce312417ea291f7c3328d5ab1 8919aace7fad3114e699de352638d08706ab4a869961b04f30d73a4b5efdf33e9ae09432d429ce278f7206080a9deff600f9bf7bb87f6f36f68689cd80edde8007dbf24638097ad767a9fa34d3029d5b2aee74a8e9e22eed6edbfa8df23e855e +00 007e1f8988ad804aae7d09a99be19384cc599e7652c02c391542be74b17b 987db3916473cf973f77b3f89c506cd86ed184b61efe7a609813f4c8be15f0cc9913dbe112d1533a1e47b690f343e4ef017167a66b951cf11a280c2f639fb14a35c5ad08a74226f7144019ef367f1a1187480e82763ef55a1202803b25b86ecc +00 009b2292b0244c2aabe8b43d95039984d504ebe05eaff318760e4dee739f a4d06ef99f553af76e990231418e1ea718c9a898c8782dc73d7f838371eeb1e36947739a6e3ada2248a4af2bdfca131907d23745b39d53fc4085867fe25e13a71566c0cc734c776f17573b2cb4cd3ff647e843548763570008400ec5088b2cb6 +00 007ca463b50fdd92d9163f1c2bdfce2ee45ba1437b79162e3e959b814cab 88a505c682d76333551bcbf962cbe656643043132b9e293f4183237968fad953f124afa7a8f5228834875a1c6b88e1da198ea30bb9f1803a97ace236634cc6e35f44bf1fae31c0b6cc31966129f325e050012f716ee0ce39fa2193d323528475 +00 00c3844750f63fe0c2e930bc38fe88522f4e72a2fd0db9778ade20e939b3 8a47cb312b84c3cad04aa32e919f9b859e859537d56339ee985666a256367c324d757de3157d3fe2ff103765604fd116079bc5f0a3bbda859557a710a03c71a9f35c5e5ff8d3eba7d93ba9549aca3aad8412ede4332229f3d242ef70c87c7a56 +00 00a3bea235dea86506be4476eb7999dcb8e584a34238c4a894ad6823b93f 81b285c4e513395637d3f2b97d2091f6a0249de816142aeeaefc6a4455d8298a6fecebf422ab2aef8ec2fbd7d398039f0d016662fdf3b60b4be6cc6f6d8585708a7bc0ac449f86ca616dcb03db402465030d874c4e36a92d4c52168df5befdc3 +00 009a367cd1cffd8dfcca179e167ea437ee48e9b6f42559dda9224701d3f6 b96ece16ec10696bfcbb8c4fd6dbee23712d632144a56063d789ef0d6e34ba65fb5c6af5e49f4ab5132c9d108a189a4b001dc2f95666d9d94e96037c7a741f1920cb2f6f68e48513ac05c5bf32d54fb03cd615859e63e152c06fd67505d69204 +00 0046f4ad2522e78b9b35297d28f361fb0ce82306322aedc119251d8241be 83eba6ba487eb59a0d61046a86ae68a989256a7328b66ab2178f4a10634176ff66c392900894debf182a673b3d96f0a0182b3e65e50996596f3ef0cdc459385d6e339bf3d8db6e9a314a2200c5110d385642032c033eb17eaf32dfd9d2168775 +00 00ac82137e9c7a5ecfb8b1a7df9ab50732934566a392a6c8915ee8ca8144 89b3114ad04decaf0685a207af3055e7698fa7bb24f2d0477d812bc583fe4214514a1c968f2a847eeefe0cbeb24d2acb140701040c082cab665e8da31b909907f4bc3ffa51941dad3f28d82adacc21fc0f0d1899670c001439241570af5de9e2 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B283 b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B283 new file mode 100644 index 000000000000..0eb8906b0184 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B283 @@ -0,0 +1,60 @@ +00 0299ff06e019b5f78a1aec39706b22213abb601bd62b9979bf9bc89fb702e724e3ada994 b1e070eec0e6c9097b0d792dcf746c5b71c76ed45ccc01ea01de850b04dcec288c7cbdb8f9754c3bb356ea9bf068d3251976360013548523f9866ccd4a4fc187a0ae7694c16592b2839fe6523ee93895201571df6ca2d3d4b252c7ed99d4f38f +00 009c2804f8cab768248fb3fff8a055b3f4585c00de5c1615a19f9425b9432ea09afba8f2 af393aca708e59de3b914effcac9e76875a441fefe5854d5542e84233509140c3e87d30d48d2e3dae9682d47415c4cc009d219e82f1905b2bb98d00aaefc11fa63833652bfa7332596926b1f404cab40c60510ea384a8215152d807109ac8c5b +00 02e625a6bc6d0ce7c06231de827068bdb0abc8ffb57c82b35ee3a0f873b9473905974d34 aedf45b77bd9b3c5669774ae074f14077e67fdf29df7b7802be8de1b9bcba67236e2a2afe34119130b9aae8164bf1b030faaff9f56a5536aa9b40b9759f53a42de754ff4029a5a5a4e0eb90ad770ca279ecdc4b4c03d618732ffb3b1e116c9c3 +00 0376ac24e1b86f8a55c052d92a0bdc6472fa03acdcdbccbf7c321ec0ccd97aa0a66b4181 b3b98ae3cd89f07b4f7a28dfbd5c17e332c1ec633130ef4bf940de3b6f55a95d98bbf2eb6acf2a03c69de525540e68630fee0dbba912a575229214f7c64e0ae307e39bb5bf6fdbeb7b3fcbcb1b03ff65dbdce7368af4e98d23521a0530d5c350 +00 02b50a6395fc02b9ac1841323de4520292f913519bc0d6a471aa28021322fc4dbcd7b802 852b3176c9b0b136ee6045705eec62965ffdc32251a3a3540b6d0368192aaa9bd5fb37b58661e9fa226701c480887ead0ab4ea2ef4dc1bdd54085317708ac6378edc2db0b20c189b13209d90f3d9b3fc19d6dc29dbffe6d6041f634ce3a873bf +00 024e5889722f6c35e18ca47effa9e415b1ba790066a91fb3c9f7b001ce28fc732b09bc23 886656c1a172f2ca8ecbf8b3ded1e4d4bfff76ff2606d775301c7ceafee23984610140a16344f2eda8d42b38483fb6171144bfae2e145f2f9f51b02c1274ae1c366a09f79a0ba68b644359aa9b4147e4b93b9b11ba9fd878df4cb3c88798d649 +00 0056d15b81f40b6378588a5efe43e21b95e18120d514bfdda0e7759a1d0766a8a35ce5ac 9144fb40d77a2679248bbfdf610d8f5251e230639afb6bab26e4a616603d24ec81f36c5792940307b40de4b8b9433ce20e51630bafb93026020ff321ca4e9529985d50b25c22c04be051f95bf4f43524f25331fe9835fffa4167b7cc3838dd82 +00 012fb2fb5bf5f7e42a500154823a174ba2d05af71e3b0cf47fab46e673ea1822f1563def af546b770c7b6d1eee63f625e992032f2d900a44207c420daa06147df50cbb973f51caefd4664b9c6a6a8c4d8ae85c890412462f8f7957aee7388244bff8666f65f1d0d9a19d151876c3ca841baa9f0751b6ecccbad69a9abb0879f7ffc6bff1 +00 030096c54fd480647e017f8cdbbdef292e799f054e3279d228b09816a757566a744a8266 933da19c4840020ff3e90a5d16a02deed826ddbd92b6586a5904c33c392849a8b2161034159e5900fec067a6f26488d5186fc54f5def435bfec7afb180c5bce6448f4c70a55e34ab7431e88dc8e71e2a003bbb046226cb57a2c94acef226d0db +00 00a1b7e9c8c2dc25b494b5ef3195b294e41cd3c2c35235ab42542bd3e2a52d5826662bf9 8c0dda39a20578e2a4909790f1bfcaa371bfc3fb076b9a522fe623bc4ab5047bb39f31b9cb0b23d69bcb6dbb266f4a27007df3badef598a72d3b756378f15a998d8bb9d5e7da29a40c83079a13f2af40cc512ea9a89d7de3d19528f1d1ec803b +00 0059b1a8fb84530bba7a607ee88310e31bc6ea6a6881603567a1081a05a3a9ff87e719ef 8031a0d5ec805526c47b2bdcf21259702f051620556a63980a357b35c9cd2c3e64caa3f7c43a939404358f0482eee1f71355e8cbbcc6e99c7154e1ce7fd6b9a93c6606a9f439232dc2d09f88d4c773bd72848d5384a61e76a563a9b002a0b43f +00 030ddc2c7a4ce300cc2b75f0f977033f16c1f8bb13aae3d494c381f9a6dc8622499ae4df 9403f6628ccb0c45a0b8e2ca50c19fcb5018d44fb491f9595e1d6a57e5e1cb21c49db55d245f5a79b088871c7ca41c9e02cb6c3e6aca1467db4357fc458915c870188e65e8d7f529c403c6e39fabbeb9881bafbe22af4f38cb61422815fd6bf0 +00 007899928922fbfdb5407517725edf231d15a8b62d90b7fb6d8c8d20424850dc44f797ed af8ed2f69699084b49581467019391ddef0954f060a6219d4045c5fed7538a71b5c0a4bc931730cf64c55e19a777011107797f259fb9787fbc073833f139c451d6737248207c00833e28584c331def51ec42cfa5032f51e33cd779c87f70d18f +00 02a2af63d1171930758bd3e5bfdac62cca1a83a3b55a49b3f80cf0d9ee4b2082757beac0 8ac62175b10487dbfb6fe41ebbb80f335b9fd6aefa77da10a8de6b8332dd8cdd2a781c9f8c51d8df82dc590c716022e00774f51c486ca95b0e07e4ec6f51666668c37a7ffd006ee0b860c793b29475b3ab95e9f9b24cf66dd6c6a04bb6ce2239 +00 035994e89e13916ad82608f74a639e6aceb756ff913aec440519946d6434af9a60a6af49 8c422ce484b67074b0261f45576e19829032a6afecf441129a3357ca53b9839e640d86b347376fa01a5998929d4b7b7e09ccf16b5590fc779fdff7e8307c186bd0fd0511df39f154677b3567373b2bdb77a0df7ee33c3684ca439049d9fd185d +00 029639da33f48e4fb0d9efdf50bba550e739f0d2476385cba09d926e789191b6fb0a73ff 8e24643648bedec7772e89cf87cadc5a85ac2b9cf336eeb8e25a100e01b73bc1bca088779394b6289037559c09dcb94806c60bb9e5fc07527d8bf53165591fd64e7a36af26d9a9f6dc7da443b2d42ef36377d43e95aeb3fb314f21fd39d4d174 +00 00583a7ecbf2a975a32d07428d27ac82e5dc13d1466c4fdfc1e6a05a8d9a289f1010617d afdc484a12b5afbd91d8e9ed3031f17a8b434b35a82ab5c82e1dbe331899f1baa561b7478b44699e6d5db7523a9fe2f81233cb31c530365891129d1b8105af1c0f03a2c0dbaafb1fe21fb250c821547b1a2b2facd3b4242c0e6bb2007ea8f4ca +00 00f817ab1b49131fb9bbe8c112c25a36f064efa85de7506fb9cd29d81b326bf276277f7f 89b41443bb35feda6d3bbcf4542840bf5d9874b7fd03f9cc401bb1fee9801a6970f600a7c236b4090acd37ca194c6753185a8739cd46509397edb9072315d50706c8d19acf23d88059f5799f096559fd9f82536d9f8ef24a5f3eaa8a008d029d +00 02782af76ffebf3e2bfc0576b70e4f4bb87c762e2bb230d278ce776310a14f5b678f29af 8a749cc466a2c76fe4e50dce748244133f7ef9a1ce92216af52ca0a2badc0c6a22761840aeb2e243c13bed1fce0a235f077d75ce941b3669d159c2654e8ce7d08f97fb81089c63c3671b7352fa29881c0098aa45595259bdd60cb52e94434c79 +00 031b827b88f14d3822244809096157df3c0aa99da90c00cd9f0b18dfe306f6881834e6b6 aea2c770f7f2abea42ac570ad7f31b41d47b74e25ee41c27c27d791d1ee2b31666321cec80f543c8f4bbbb8498da272b02218338348b445d556dcf01b05e8f7cf7575d8a3b3c104538e2c62e552fce7039960733eefd96448c5d4d53d88d544b +00 027da4916f1c471cff80bfa14d12aa10270fc3b26caed010c0111f6e5a40d914a3927763 8ea26f4d90eb89f9583d8620938e6cdcca661b1fbe357a9f7735d6eeb98c1e02205546c6dd9585a2b31a5df3b988c3cc023912ba05e551128561cf69efb5a8cbc726fe8eba1dc5ea4a14b269295b0bd6e8a44939e2111e1fc777cc02c8815501 +00 010608eb51dc0ee97d6e488a23c582ecf0ea1df9a24db77094d87b3fb6ca98507280a934 8042d6771b0d0bd2f11c7933c5a195a07f03d4b22a74764dd5a432a513f60ea8b8455da9ca36c68b8b114e4e5dd1667c14aa0242bc684591bd23a33bbeb2272bc487b90a35d3f717d260ae5345e4a41e1e78d238f1934c01238ea2e1001083ce +00 0123f9eb8babed548df08cc3afc1d3b3bbed52b538d4654f2088fe76062fbea75b85a560 83b7895e4a634fbf316f9ebe62f4a2f293ca984a95748253a092b4cbaadc5e1f1c30f21805dbf7e2d2cfe12054a671ea01261a4e478ac41357f511132792e46877d39a96676f657e3ffda4d570d4d724be5acf0f62f82f53215ec3d2c14835dc +00 006a18e626452111922e02e31d662f4301319946a204ae8a34f06b91dd1b5b96456365e3 8f33244f238593676820a2ef5f23495d47398e39b3bc0724d3193d786040c9c0f3556ca3a7e5530ac456e142e4d920580726bdefb9dcd5fac232260e73b33cd2b828ca5f8c67a22f590a27b7f6ce8daf39c3d0d71a4402e536def98fb743a1ef +00 03307fd717015b12a2dc76ada21442ac1d97519f66898b214c2ea317ab0f0905e819e4e9 a34d99ecff8ab8fc2e05e8abd2fc78c864950c1476d653e2bf88e4ca5b485395edb72fa967ccf38f5bb79d8d6f8b04f515ba4cc392f017ebb0b8fbcde4bc1528d6439422f0a50d25a49d69775567910d9c5fe39bf35f172400142493c1eed89f +00 014f9f412e3c7d770626e800d43cfcbba3ae6aec8563af748e8a97b67d244334b6e6d2b3 8d740e3cd42daee89a0ff10f071904c72755ec0a18f2e912377424e19552816419a93f05f624544ed01f906b78ceef1f0c55902dbb5ab0fcffc52e5df5807eb7f7df70a571cc7bf08e9bf1114ba2153b8817882c0eb1a45752241622c881da72 +00 03091a6a8bdac1e43542dce752694972e734dca31c061c7d1000754296d0748055db3f09 b93e5e2b8bd863e12dc2f17f01821bff3e5a3d8b5d0943d96888773233c3dda47e72493cee1110085e4787f080e9d5ed0a606092c88494edd820727af41d49ba28eb683b81ec587a9acd8a61fc910e0c4fdc00358110d05f3d8e4ce18f961235 +00 01195921b91353db9bcd00510efffe009c94f6bd8d790f5fb3e5a0101c9ca5d21c6ef2eb afd6bb010caadca8ecc41e2177bafa561955631ca7f1074b462941585dcd78570ad066e2927a4c8701ed57607cead58b0e2f96e9bc349343e1f32e738847535ea4971ec8e676e7de91508f52e13d5198aa63d3bf464a4584923ceed78089a63b +00 029dc20446e9abacb43823e12a83737b46e6e577466b5a3925e0f9d496824dadb4d4b50c aef7a1f477fbac3791d6560e9fb895c433e9272842b52265a2b12a86f989da81e9e3fe8fb1d8f798ddc80c4c9fde1d6f0f785817a1cf386bb1b8d569d57d1a3c5f112442b67e002b295dca927584f6381609f995d909d9e48af840b8a3d3b80c +00 03b9b77d19a42e9a555da8ab70aa5638890b2ed21daefa28ca6323fc658662dabcbfaf52 8f0a6e4a682bb269fea5c7c3cd87b17991dcc456523706869f1435f8524572fff185e693376fc3b2bee0a3370812a8d1073972532983085cadd1bfe0f27580dfdc20fc6f38489a0e9eeb06386c718c050b705667105b2017efcd47a3276a04ce +00 00b9f8f3e89e9c1ef835390612bfe26d714e878c1c864f0a50190e5d2281081c5083923b 97e56033c53987e3293f95147a1fbc8d18643a629bc7afff09aef9eee6ce792b27ba635a93722a1f45771db858a2283419eb1581ef27ad71c8547e3a069a3105421fce07b8745510095bf094cd5097bec8759edea317391d6f57b9054e9f13d4 +00 03a30a1c15b9ed71e102341f97c223a9b5ea3e6a335861c3cf407ef691a18cc639dbe74c aefdc775c6222078b3a21ff2fe4f0b2daf9800b993351ca6d4e6276ffb9fc94a308fe0af6109cecb6e99711c7875f2b40d846fbda1992eb8ed134121cafcfc8f332c6a8d83af38eceba06873fb4eac4b63e420d018b8520304fa8b841d98f03f +00 0083330123cc64c11888c1fd388629d0b329a50ef31a476b909a182c930ff02d0c389b93 aec1e00ee40fb45b52a3e2f5fa383ee53c7743db7403b691ca85ac649954bcba859eb7f86188fb45bd1ac4fbb8226e690a938683ebefd772ba5fe3d06ae85a4de6c7aa711c59656408c0854e670eb94dfc7347554d442219bbb97f682fcfc7ca +00 01dc2b656c207eabc9e0d6272099babca8d149c9c4258b779c2f06de75f76d77505271c0 a683646798ff719f7cc186ebc5cdaf7d88874a3837ae5f3b386c801ba78af026537a7c9a668107e449a2d7eef96a4f9703cefa6f2e5376c3e0f537893d2020ea1231819e5be75be59dbca66e32eb9adbb8f6919b3b535b3f6cee9caa6ca65057 +00 00081772348ff2d7a3fd57fe703555ab2e14f5d203c4cf0292f944e827e884d95f3b1d83 ab3285fe3af56a98d54a952764c5e434b5064165bd43e80536290c6a3fabeeccdf52fff2d8d5a7f88bfcc0ebc309c53502834c50874966efe145eeceae7ce0963bbf3d54971a91c704136a975e6e71600ee7c45ab97e64e9e99a60cfc38b52d7 +00 01eb6bf2ca1b5ffe6f6a795733eaeed12de6e87c53571e702635b9dbd0d96b47df4a005b a6d6f545c3f1c98bb659c52fb24da0d3ef100bc576579579c5cc27e814ee7b466c0209c4e517ec46d0f72d708d113d7915f42bd52275f98d24f37ea8b9724d48741eeeeb17c3e9c8a657d96cbc0be71df6487784e424d32f730bfef6189a09e6 +00 03b2a3e65e5a306bf8e3955b60e856dfa9bf68c1275a678ca056207a0ec67c96eb3f8309 af21088532900a2208dcc42645f7463ce3d8ffc1a65c8bc2432f46cca21d5aeaead086712605b8f2da00646495bd39770f7ef87b7f161186a0d8c15728b8c4da95ff612b241c8279dd67056cb7f0363ef5646446f667a256dfaaeea78abf316b +00 01fd4d1af0bb7c79ed5fea7bb45574e46534387bd916649485ef15207352d7302e81dc01 9914b35a9955e3bf5db2428f16af5379651587d16de2708ccc4c229fa2aba6b395e059d0088b9a60fa7bce6a6744a37d086faa6719253198a7f1a2d4fadee1e88caceb3c50651aba07b529fcae7aa86cb3095bee927e5c117d3865e274699e0a +00 020380b1136b5283e9b7f54b7535ebda33b129ceb177bf5d3d07b1daed5edd9fb3862530 b56bb46f0c2ebe555f65d8635d122a43eb73de1df6f9e742d4bc893f9d23264e3fddd8fa0c4135710ba244b9b2c197cb12fc35fde761d0882826cb913a2b17dc956a417ebde948697bc4d8bcbb1b27e9db3d2b2cb48eb87fb786caa5b47a37e9 +00 019f815b98836948e0a0dc9c30828c31b13e175f1e79f23d084ae1bbe64823f4866214b5 98a518c3a723350931fca6242ee34da262bb3a80c2bac7eb93bc8ab13f92c0f9165b55033cddb28e1e6a0f40010cd01e1230b48a6c4c89622bb2213d8d509bb4ca150c9ba3320575ee1f8dc23f27666212ff628f77353b4c4185096fcf35e08f +00 001854e954654e726cf4bebc0e5a840e8809fd716059211c6ffeaed36829808363164684 82c7601ec3805678e1879568a4d78764c717c8ddbd6dc872b9495caea2ccc949c3763cd727b1eb34eb15388d9279e46c0e3f5b96990c52d4b1a08002392df0037b4c6bb6ca3272d5bce92f0b8b0f79831f97867eab4e129006eeb7cce79acc9c +00 03548f8020819588b3202f4c1ac62eaec6a47c2a19b2900c5a3cf5b4ba5804231141c647 93da1bbe234fdf5419e3514fc2163ce4e0383fd5aabf42c9d9f8e758f25897d485893396041e1e0ba19b3ac3a41e2fc40129a6e34ddd63e662fef67118d2ab25b0b48abbdb70f8a67f582c08ef6e1b3864c7360083cc9bef92803c207403cc38 +00 03cc4505005c41142308f1489226b7b542e2e7f24f1d3089ff6b92a4b0013f490ad52e60 87c2fc432322a218d511b79a7b81aaf28f3b9c2d6523809c46ae04a522b71590956cad74d47d6f0a201801274283f8e516dbf6e21f3fcc1ecde2cfde9e1157b68b636cc1df95099a143619dda86b4d91dc34c6dd9f9902b42683a333f8913793 +00 0144a2fc8e0aa63506e14e4307df36416f963dd9da78655832f5b991af8c3eb97df78efc ae255092499c9e1e6f6c912dcea8bdb56cee425a27a4eee66ebd27114399f9926d00d4ecdd5b32ce23421bc08f154c2d0ce000830f58deeea2b9f97437f93ec172d63b4bb4a66793d98106339d0650c3d74a91175cdbc3308d800afce8b161fa +00 024ffeaf139043ff25a395e4c560c7680c1c2155191378917eb25194136b4a69597dc277 8d5d2a2904678510ff3acbd4503e23e43fbdaf5fd1d3b0b2338536d696ec07615a0fd4bf5c55fecc25a02aa96445d38608b33476c7ebfa69d63a67b484bc8eb9ffd719530f4ee34c3050d0de45aabe8da905f58c86d43c5dd99893fc0f6323e7 +00 01d1f2e0f044a416e1087d645f60c53cb67be2efe7944b29ac832142f13d39b08ac52931 99af8c8c192b6f6a13e46899ed0116ecbd221f4cd7ea4855cf9d334bbb85452f0026b29f3d7d3ce93c6a831f7536f0bd1490721031e5a767e0a9719dcd33254117e0da24ef4d27ad6a8e7656f4997f4f0d5797a087c1de61c771150cf57a91a6 +00 01337362609df74d25f7adee382225e6a04dd6ee4c6b45fa31499ce9edb0ec046325caf9 abcc11978b2d1daaf38d0e3a659d32f8e584db59f7efafb7a6e4c85c76f3955426ed861e1434897816b80aea248cb9aa0fb6a0b6ef901c37d96bf07b175e48dd81d992f62dfe2b4fa17b51cc4c9171b2dca0e4050f0224c8ab1a7459fc7b60af +00 01be00aa0afdfe92e24a2536594d4b41701ad4dfb223aab35ff49310bdba7566057fe8ac 90a2b8f44141c6a773b51af3fe5705c19c0224c64a45a7e96c45f09b3dcc4ccbcb07b3c20102843df805670b57e8ef1c16fa8f57219c89a34e6a0057a38013120574596e86dffa44337f34767a1a7ec84cecd9516c36e485b8c5f9db68f3761d +00 012ad0aa248db4fbc649f503e93f86104cb705d88c58e01d3ae0099590a69aa006aa7efb 85006a880aab5f84f90d6c83c58e443c4c4a57cc8d61253ac9449b0252087d766f684cf36504f3d85f33abd44772a592185c368b732a8f44e6be4d6cec0edb149ae0d8f677fad9309f5acdd5ea374503c708ee51fb1502ae3081e4f01befc7ee +00 02cfbb8f340cae8e2e2322829148981cd9e509b0c65497fd8d9da5dee9dcfd39b0f7556c b122cf334f8fd8190d2c47bf7758b6f85871a05acc9d51c30903447b3c87c5af9022b49fbc6a14520ce4ba4a64a449670b350e0f1e3167ba51dc9827da02628d9f724fe2bedf076e3b5b547ea542834652a114249377ec7a8744d11036f8bbce +00 0070e82a1f3fa6158d15b7346dd56150faee5c98c9d07c996e01a06dc9b211b12ff62d60 936fe4e42cee2545622b35cea9d2a9e546ff7165511c5a29923e3e58cda864102484830b54f940378b418248fad66d6e095ed6cc1a02a2aa1dcb33abd21f3fe38203fbdcb408c4d084013fc6bae8363416f85fbc5d36edb237df5964f0cffe72 +00 00b471bbc5f7a07996e370da4a09e71e2119ab3a562a273f079401951fbe4df39a4493da 8ba67d5b724dab97ebd1976a64fa23c2a9ab8a8cf4bced808d471980205eeadaae0dcf2ae47613316a7e4c537079055400a1ee008f2ffff1367d6c630c91b93ae8ea3b4ca461c88c50a571b792d497fcf5d59dca098c499f6b5acf598fe96ea7 +00 03c65cf80bfb507dff52f9bf2f93df0642020d41619b3990009409e7210fd7130ac44ffe b093d6cce3028e6cd6fc679cfcb0666a9ca8a72d4631f73cd3848b8ba20d4b5d57a9768721c614c0ad75e2424ba7a5200cf33ea0a01571334514e83b08aa477a94809a88742c24d0d789e74c59b96de0f7ff2a2a6b67c2edde07aa2b6f1a7032 +00 00f4d33a9c7e6744ab3c441828bf0f1866ae1c042cc54abc754e3801263a96cbb3955dfc 96b0fe0a7823a9e41e249e707139ed2901dc1091cff8d49d357d68f62e67c249eee4a9153a3b373fb92c8ee3c6d6b8eb0fab5bbc7a49b85574ba3d6e7deee71cfc6a36360a705f1aa814aaeb2897c8fadb2205e71e65d47fab589af19d8b07ba +00 03a4824bdcea6a144d85f1b194431724cc49849b6cb949b4766d641ae95477d1ec3d1464 b86c2d864e113a2b33d1ee7ea101aa54e00dbdd309a36146c5f1f21ce70149f33cfc1993330fd283bdb24ee271950abb0019e548b904c0f6bf72708ef0e9bf4c183847719cdf6b353e07103f0a8a6f49e6c2b7fe14c59dd58501c9c9244815db +00 027ba543ea785df1d53d4ae4c1bd0a3a994cddf0c25d2b4e8ff17ea7aa00619e858da1a5 aaaad908e26cdaf7484852a2c97b79f51d9480c24edeaa3cd34b50096d3b217dbd08cdf5bd73dcb8502642bc214447190e0caf478fb5fe071cc8610d944c4bca0cb10451a26f669ab14bbe829c7c20fb05bd30477343af610c983d82c0888b21 +00 00708d0907d14dcd5f40e2903e1e90e48a0ffaa6d4d9b84ca14df4e985c294f74eb9f2d2 905f0cf7c308b5d3905f0d5057b94dc8794835cc09ead67f2bac68ad296e88bf0c35411f0f01d9a38229cdfb7fa666f90334cede55b74a7fd0ddc5238f971eaedb5af13379835f782006d20467af8425817983a155bec2ef6cbbec001c9f528e +00 021fb0a6b94080da8b8299b87457dc09d21bc430ba5f3359d92aacc1151be9941739567e 87df4ea7e7e35754311e7625c53f24eda779cfa66d2707c864bc4463dccb5e9c38157cc74ce87b05927540c312e01d2605d87413a84104d976a0f2cc6a6380e43dfb00a828795c693de854ce661582dd2cce4fd1e031c91ab9eec6225e1c3f55 +00 02c80151f91301fb6b0c7685bd172f20515b46bf94dbc4160d0720fbaedd40ec00084447 81610a3a1ee2933d5c63893622f735b5829cd8c1add8c3669a8d7f7110cd9287006371e2e589781a39e1354dbe60b47c069f2d65256a472ec3f2893ef12a084d88772be2edc213ae8599831ef4e943111eb047918f333ee089a30cfcf6351362 +00 01538abd7ce8a6028d01604b1b87db3aaf720e04220edf4d1d28c2d731aa25f509e58f2f 871f92595d4320a3298bd9b9945f1995f07ec93b90df551279335f9472f1378f1afe91faeefc9676b3ccc95b053cf05d0678b22375ee532937421f35ce877b435595c0e91bef369e3640a19e91ae16bd2b2c6df8d9a6a82d595f1fa3ee8bf0f1 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B283_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B283_blst new file mode 100644 index 000000000000..c0734dcf065e --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B283_blst @@ -0,0 +1,60 @@ +00 0299ff06e019b5f78a1aec39706b22213abb601bd62b9979bf9bc89fb702e724e3ada994 b31de7063f9ed5d8eb7af16208b679bcbebb04508eda9ca28e524cda3ee7dd65391312ae9cbaf7d37e653de8061c09091169d325a9fd3fe91739ccd0adbe1b126118b71c01c7cbc3c9f519be95bee38c552a73a70412b12b02a7dd80c4ef5a47 +00 009c2804f8cab768248fb3fff8a055b3f4585c00de5c1615a19f9425b9432ea09afba8f2 a5cd29fcdda3c0be5c022433e57a8cbe7fe15c946682b7bfd14513c581d96ad0b463d291b7b27dc521fc4ae14de2bd5d008d94a7d83684ad14be58fa09690dbc3ae81fb990e2f931ff9d10e2e1ada841c36edfcc99a08ce58e766d0de943985b +00 02e625a6bc6d0ce7c06231de827068bdb0abc8ffb57c82b35ee3a0f873b9473905974d34 842a414e81c608a18ff9a2864c4b9af0b8137535c0567a77ab927143e0984ebc87af07964454f6478c7c599b2cd735db017ea720d048a3f79c26d4da5fe52c6adbd131f0f04e6cf142d99ddf14bac4e481e8e8d3b040c4478e56251273db8762 +00 0376ac24e1b86f8a55c052d92a0bdc6472fa03acdcdbccbf7c321ec0ccd97aa0a66b4181 95b77dc928c25f062c1209e57d02fc1bf4d51b9e90e4e0dcba3f56d0d8aa20d3be24999118ec99e269e190c013b8a5ec0f1dbf5782c47a6e002b127e13d69a4fd0457ef2ebe160e31c906f6a40161eac1f7fe5761794aea5646f60eeecaee988 +00 02b50a6395fc02b9ac1841323de4520292f913519bc0d6a471aa28021322fc4dbcd7b802 871a9aec03629f5e02222c763b7165dad7ebeef2e25989a1c82d2a7159b262974b9261c27cfd548af7d209fc7760fa970f9ce691afea8d23591893d2f665baa7b235aa4e497a01a54e82a42092ed8dd4bf0159238c76e654cdf2b16d80afdd92 +00 024e5889722f6c35e18ca47effa9e415b1ba790066a91fb3c9f7b001ce28fc732b09bc23 a16f3d7bc9cd14a790f207160060c0fb1c7bba6a553b7196424f6d7148c5d67399fdec7c7cf972e3b1476bc6db856fe517372548a87feb4a508ce396fa1d980e2ed1de4b1f591ac9a4664697c82e4bd0d4388032294fb936423ddc779ee480b8 +00 0056d15b81f40b6378588a5efe43e21b95e18120d514bfdda0e7759a1d0766a8a35ce5ac 956a5c5f939986de42a9c11beb445dea3eba091e246a4c676ce0dde432e1b0b2be826d181b89defaa4b36c130d8806781677a772d4daa88be87f929531b108fc06f26228d2d744a73bc394d3c69eccc76bbf7e3ea01c6db9d31547a557ce2df2 +00 012fb2fb5bf5f7e42a500154823a174ba2d05af71e3b0cf47fab46e673ea1822f1563def 8ad0f09af09bf9e059b00e55e358d115a8abd384bb642d1bd991dd6a8949c62b6e5e00c66f316bb77a4ed09cf72c091d020a491de62a62447d2585ddd878e73696a0c2580c6517a6c2c67b753d1fb64d83bcdec917d0fa5c2a2342cf9471d126 +00 030096c54fd480647e017f8cdbbdef292e799f054e3279d228b09816a757566a744a8266 b834a5fb4559e7f134f52b803cf799b419cb1d2fe79a00f033956a48e8bf7c577aedd49a9a87d6c51fa92a60b1d8d2830e25d2273f8cf9581f6e2ce98de5847d2cc4c217b5d6bcc84f34e9e0a304ff9b0002a8a2be10e66d419cf5fc54a13044 +00 00a1b7e9c8c2dc25b494b5ef3195b294e41cd3c2c35235ab42542bd3e2a52d5826662bf9 a12e47363e99f1292f16b114117048bf0647b8bafce14f0a22391d4b0ebfc5dfe99013383894ef4e9b898449a1ff2f0b19b71ebd39a9c416545ae0cab9947d08cbd5226ac295251d2f249b432e6c4aa97a02cc3e66dab242732691b11dfd4d0f +00 0059b1a8fb84530bba7a607ee88310e31bc6ea6a6881603567a1081a05a3a9ff87e719ef b4e8938b7ca50fc0b959c254856dbe7782a5e87f1f1aac994f6e6805615f829b6a905a8a448007bc2aa8ab972dd97b160d7512fc878ae7b2deae8d4c5b609a7104e4bec60fa43f1ad63b50d7c7ab35f83360716d3834b871f6b01bff2e0043c0 +00 030ddc2c7a4ce300cc2b75f0f977033f16c1f8bb13aae3d494c381f9a6dc8622499ae4df a8e240589c714bcc58e7bbae6e0573e3b2696e27738f82ef5c79ef4410488cfabea112b954065f307f097092aff1327b09b7932411d285cbf777ef3aa744b249f7d39f1a4e6bf83706377e0f6cc44ca3b709bcd4b712e4a595a0bdb7d84167f5 +00 007899928922fbfdb5407517725edf231d15a8b62d90b7fb6d8c8d20424850dc44f797ed 82b598508997b0142e660266f97800fe4f4029793b784de4dc6530acf3038608a8646d1ef156cbb9eb84b02df48a5a4202ef7aa86aa0b6b10e4959f2e6604c9daa6ccd160930f9984eccd97bc9aa9ce6ce8dfcec1606c9bad1b5d01b1ec421fc +00 02a2af63d1171930758bd3e5bfdac62cca1a83a3b55a49b3f80cf0d9ee4b2082757beac0 ae02ac8f89dc4836f23438c13a9bc284e1bab9b8ef1790f1539aede7bfb2b269845a7f6004984d878807d16a8879c8b208fa7ada5d1369230889daf9720eacfb475908cc15300bc690dd8d6831f2e776ffa8bcb0e0980058ae031bda944486c3 +00 035994e89e13916ad82608f74a639e6aceb756ff913aec440519946d6434af9a60a6af49 b720fb2cbba10c62423728fe507842f54920055621f86ecd53d8f57e2d020e714445b81e1243562f12d21ac303a892550e4a39882af775ad5d0aa4016c20d4e6e55d8f2b254e35656b3bd863cb1fcbd7cfc3b3a7b10d9b79c2caa39d31798447 +00 029639da33f48e4fb0d9efdf50bba550e739f0d2476385cba09d926e789191b6fb0a73ff b8a3271f347e6dc0d6c8556119f1d01479943a3a2800afcee9bddd98753f5bb646d03930556653fb53c4819530c09ab507d6df96659e4183cd8c2fe6f0c75c5a6f99d34e113c072318af03800283bec59b20adf1b3137d745fe4f4451ecec65b +00 00583a7ecbf2a975a32d07428d27ac82e5dc13d1466c4fdfc1e6a05a8d9a289f1010617d a2648c984db107016649e6aad07ccb3d6f0b795e30fe6f5dc75e1d166a90ba662a38bd368074d7b2f559e8c4e55af03f05e9b04c5c3f1b710713337e07a319f66995453d0a038f91c379e89f62547e041e470a6883d165ece3b1a34ee250efef +00 00f817ab1b49131fb9bbe8c112c25a36f064efa85de7506fb9cd29d81b326bf276277f7f a6443afc55bb147a3ce1964efcc452936e6313fd1adb2b208aa4a7136512594ae9fb304d188bf41761682a112f6084ca05a145547ef5f6b5f8cf17b44c1fe1192efbf09396bbbae860fcc968fc799b9fd57feb6238c6796c35e04381a724c9ca +00 02782af76ffebf3e2bfc0576b70e4f4bb87c762e2bb230d278ce776310a14f5b678f29af 961695b81a8489e9a48c9b3fdc5d0149279b058e2fb73da1c8ef1beeb46c6ea32b57f2250def9ed39e5cb59bf5396ec719bbfb4e30d8734d962a26702dfb41fbbe0f325a72b121b19c27813a127bef3f5fd36af1893150224fb5a6f572fb0bc0 +00 031b827b88f14d3822244809096157df3c0aa99da90c00cd9f0b18dfe306f6881834e6b6 a8e704079befc22f8b7f81c08de2a4d1d94f4b612fcacbb41d4ee2e9d1bf8ca4d8c15ef8daa48979320c9f2e488a7b860da7c6013294a302ded6183e730775dc57046a9a4c2471059a68c50e091ddbceeaa02fc929f7e1f9e8b50e99f46ade2a +00 027da4916f1c471cff80bfa14d12aa10270fc3b26caed010c0111f6e5a40d914a3927763 803eaafb3b3a77c1a98bbbcd96f7d44ad82b75c629249130ec5f3a2e89cd31a9fc7e5d0f59c029aba1bffb392d620cdc079aff94f8dc53d1d05f1e8da81a362e1805e2341cbc202be937e50d80ac5762244b20ef73e26f78c1ca20d35688246e +00 010608eb51dc0ee97d6e488a23c582ecf0ea1df9a24db77094d87b3fb6ca98507280a934 b866417eb5c1fbc2787260de975d7c869c9dd76baa2b1dbbfe078a547192404c76efbe07fbed6ce785ad59ecfb0d23de07017c91b22574850d95aa1534f29b885fbcc1e8fc561c1afbc881722480abf31434b63f247d775f0df8da3413442c10 +00 0123f9eb8babed548df08cc3afc1d3b3bbed52b538d4654f2088fe76062fbea75b85a560 90b62fce79d5d94013a9fd27924ab7043a2c23661bb99bb4a9f3115fc4b0c92fb94864a43f8bee9f70ccb00a1fc7156a17ed22643cc1de62a9ca563df5c71b65cf4153cd862817159d5fb5e0f1d447e3e6fbff9e47700ba6c4de8d859227d94a +00 006a18e626452111922e02e31d662f4301319946a204ae8a34f06b91dd1b5b96456365e3 80e71c0259523e8a0021138b03e87e9db960d6e350698597e7be9fe8498e39fa88dd61e19930bf8c5399579ccb52136f0e808c84440b218adff66932395c6043e1ee499b45a4ffb0855a2e4072cab7690444b7e302f6db24392bbc63d77c4535 +00 03307fd717015b12a2dc76ada21442ac1d97519f66898b214c2ea317ab0f0905e819e4e9 8d458a81455838e66624178a1510d4eb56b0023879a73e7486bfd3307b60681d8101429ab9aae4c8afc6d5df4885e98a158818a0dfdb45e8d529d2c481e0a1d9aa2aafc2bc80ad4bcd0438074a9564a947825dda4bfe09c0bc809f7d123d29db +00 014f9f412e3c7d770626e800d43cfcbba3ae6aec8563af748e8a97b67d244334b6e6d2b3 81f0ff32bac26cabbb6bb7e33b3cbfa37301c053b3ef6b0829842b89fe9c1081728b03f1dc1232090dda8975d730ba5a11d6fbb07371ed643faf724ef54e28b58f2701c944aaa059e3e24aefcc376d2ed97775950e8033a7540a4b996835c7ec +00 03091a6a8bdac1e43542dce752694972e734dca31c061c7d1000754296d0748055db3f09 83eda9450ad26f5b6291e83e611e0a4a0fc6bde808430d8003bf923917f90a54d6cdc7be9516a6246b082ac6799276940f3380ddf0380ead886a2d33343353cbfcbf4faca5174fe72e2608a3dd94725fa06231a9625a6a66098a30ce12a75d3b +00 01195921b91353db9bcd00510efffe009c94f6bd8d790f5fb3e5a0101c9ca5d21c6ef2eb acf27787c5a7f263a0c00d119b08d38ea54c72f4b5ddbfcd127240a8776cfc3a1b438187f31ca2e444b1d30b2ed2e8240b7980b8ca38be2325defa5afec156981f53a56f9538edf2a377ccb9cbf0606e16e8315e56ae8af6af37c27166c48439 +00 029dc20446e9abacb43823e12a83737b46e6e577466b5a3925e0f9d496824dadb4d4b50c b1e93cdac9594ab020a53e00ad3e4f7f199790d75042f2980448ebf6387be8e4af522d65b46176e01b4b3772ec06b0d7159b9998efc74a9daf4628cc1af450570d9c9810bce69cf0c289d3b2864c4abdcdd5c6ba5db3561fb137f69bba0c364a +00 03b9b77d19a42e9a555da8ab70aa5638890b2ed21daefa28ca6323fc658662dabcbfaf52 84c46a567db2a20f4621f9ef940084d7e078935657ae4ee871889c5aee9c971b6823a345ab570d6922c4ccac4fa6f36700f467de51cbde59ceac0fb54653780dc033dbff426586fd404036e79018630dbfac35c07b72ad86a253acf9abf12693 +00 00b9f8f3e89e9c1ef835390612bfe26d714e878c1c864f0a50190e5d2281081c5083923b 911fc9e985fc23046b936aa4a24378efd8ad85e8cb5aa09e074776233af262fe0b1d6ebd875c0589cc9d626b8e5d30a31180206d67adbde5702b625a88550b7e2666517d5ce429c42412c31d119699004272d0dcd929369ec4b103eb9d6e2590 +00 03a30a1c15b9ed71e102341f97c223a9b5ea3e6a335861c3cf407ef691a18cc639dbe74c 833d668f1a2bd37e218f660579ba2e5312e3446a4f3172320f38e191077410b5b484e630f1c597231ad5b150d0a84ca4143e5bae967e1ecb5d67fc026d1200e5cfa1bc10006f2957bf8c0ee206a74cef41ad4ce9c83c62337052a40920207f16 +00 0083330123cc64c11888c1fd388629d0b329a50ef31a476b909a182c930ff02d0c389b93 a411dee660ebfca16b1281595d48ad76eea1e1d5a301317b32a4167467815e21129d347c1e7524d29b2a9755940ba6d70296f8af372a8efda226e18131b9b0c2b6cc54d302c3d4e531469707f4c4ae496f725f7df899d709b953e78bc97545b3 +00 01dc2b656c207eabc9e0d6272099babca8d149c9c4258b779c2f06de75f76d77505271c0 8ae2502ae300e8b2f7d22609d11095ada58ae130033c3e2452302f78b603a601fbccbab5f2d9ea02eda4d1b006fe886906ec0d31647b25c608bf101ee5421e86e2866589d857fb8f075e3d00b810ce73ef7a4a9be8ef2db73240b19b41287a26 +00 00081772348ff2d7a3fd57fe703555ab2e14f5d203c4cf0292f944e827e884d95f3b1d83 b68d5b4f994555aea54bdb0c1934990a0d4939219b9a8d329d009e02ecb2ef658fc8b888fcdda7674b3f62e097bc40180fe2799b4295ab037e6f57ae8962c10e170bfb9e83b2e2b50f160ed11066fad72240db0c07c5265aae8c6df52db958ed +00 01eb6bf2ca1b5ffe6f6a795733eaeed12de6e87c53571e702635b9dbd0d96b47df4a005b b0ff0e8183267c1dcce1527b39d3628a7417dfab0fe83ee9b903f83d6e770c46e09af136cdb2a8c0b1925c9ee21ac857139ee0344b5403cef5971187e03b70f430055898bed9f75d80ae6053f8d937061527e58ba55c529fe1e21bc415b46d5e +00 03b2a3e65e5a306bf8e3955b60e856dfa9bf68c1275a678ca056207a0ec67c96eb3f8309 a62b1ad09dfff2c17f55853ed141ce246594d94a7206fac0e4fae3fc064d996addf345bd6a142b3795e227c9bc836ae90370c0890e392f44479f56c7dd4f2fbd0bd569fcf36b13f69c3f85281be9c42b3dbe77c20ce235f033e38ba1af13f86d +00 01fd4d1af0bb7c79ed5fea7bb45574e46534387bd916649485ef15207352d7302e81dc01 a60f444c3789e7861653f55a0b7f7fd0aba9c3d19e558844210fd978406dd4f4cfde48fe9a9f812a4f46e6712d62f2f7131afc5cc37b63b8c668c7f80e173590bbab25f6ebecf47421b95a2db3669e5e0114b7349e795f4061bc67ee876ad811 +00 020380b1136b5283e9b7f54b7535ebda33b129ceb177bf5d3d07b1daed5edd9fb3862530 8288ae3d4b4db0b4cd2cb35a6f39419ededc3f9688332bdeef1c80fe82ed650eca9f06fac26ab827b4f5441dff2ee37e03f4fa5d28833942dacc7c39620f84e78abb8ba3327edf0bd47289747bf1738c84007bfbacb6b06015eae35bd590eec2 +00 019f815b98836948e0a0dc9c30828c31b13e175f1e79f23d084ae1bbe64823f4866214b5 af173f654f5ee45cef501d3356a0298650be3be1b6f55db9c752fc9b66fe08f722e03143dd0528f8c0f86eeba242be0c11efa834c3d602dec61a371a82061244d65f82e7cb177d2ce429ef2fad27682b83211dd94bd3498fde7753d4fda0868b +00 001854e954654e726cf4bebc0e5a840e8809fd716059211c6ffeaed36829808363164684 ab186d799e41ac44bc22f75e5f48f16fe9fe88e7145fbfa4043047cc036ff7f5f0297bb1d44c07d771b869ac2a106a7f15e614205465ec6769d43e2e13798e2f135f174e0df082b0dd9106a76b57c7016a536019f9f80d4ad31ec163bdaaa4b6 +00 03548f8020819588b3202f4c1ac62eaec6a47c2a19b2900c5a3cf5b4ba5804231141c647 88dcd1a45bd8fa036c9de28a8f4bbb728bd13376cb15ff9ca7bbd530fa48ad4d2a9384bd4aa97ae9ed0225c64a7a12461249079810b7d488189a92bb4b957ca0a9e9647e5b96ce66d37efeb64b9fa57ad7ec775632a1c64e00c0526e6426816f +00 03cc4505005c41142308f1489226b7b542e2e7f24f1d3089ff6b92a4b0013f490ad52e60 801eaef93fd9f7ad472cc1f30be268019bfc362a626fc8fbb1a01581a687429e8da1854274a5966dcc3dfefb015ff26b19a9a13d2edc122cc5b92c5dc36452b97c0e40e2c12e24a005414fecc78dfbeea3b1213d3a16772cd4ed0c5f30fc031a +00 0144a2fc8e0aa63506e14e4307df36416f963dd9da78655832f5b991af8c3eb97df78efc a82994b2c47d752b89273c77b0dd6179c4096984c04c4f7eca68923ab894c141c9b32f583ec7ee761220de22fc02860b0b6ae9f9871922993d77fc7e4b1cc76a43e7c2a767bea8e71810f72479bdfbcfe8814aa8ed28786c36584be145cc778c +00 024ffeaf139043ff25a395e4c560c7680c1c2155191378917eb25194136b4a69597dc277 894d2ae103181aae711c1ca7ced15a1d6d5daf1b74f8b215af5fd89969a804f3b2fd50cb41aba62caaa222e3f8db30120bc398df1e71b864fee0a52d78f11cc5b2e5f2ce39009a2cf0a151463de91ad1d5825045dafd69cc3727efe84ed7fb66 +00 01d1f2e0f044a416e1087d645f60c53cb67be2efe7944b29ac832142f13d39b08ac52931 adca913438648d0a8996a8c14be2837ef4474de7c26c3fa290f9d07bcd2e25ea7e9c427fbd865223294b80e3c189e5b60120b60633ba76a8652c171f5cb3093361b7bb85bc6bf3f041ec00a84820eb5b8b69879900477772139ac4c94e35eded +00 01337362609df74d25f7adee382225e6a04dd6ee4c6b45fa31499ce9edb0ec046325caf9 a0fd6922bebf35c0c73b65a3fa62d469f813ef6e23b4c0fc5bf3f232f657b4ad6e5dcf4f22f63505e36bec1e58afc97c04ad0ebeb5f40c3efebb06ed4249dff3aaa62a284d08d5afb7b710ba01ff6c61a11339ce486b3f025c7200c027e8764f +00 01be00aa0afdfe92e24a2536594d4b41701ad4dfb223aab35ff49310bdba7566057fe8ac b639e7bb5b9cba147fcdab9de59c4d1a82b7755cc8fe5422841306141c72ba10ede8d3e3227520443d6bc2a806eea1a90ece93472db83691a93d1a21dac9c4e7a0322ae8c4eb6a67424c47be43072a11e6cbb7437b8a65ebacaaf8440d97e30c +00 012ad0aa248db4fbc649f503e93f86104cb705d88c58e01d3ae0099590a69aa006aa7efb ae3f871b8311a7e464a0af78f6d1681171770b8dbe3d7dabea4b7acd39a57886f8f920dfe4e4d169b4220c57d975bacd074a98f6e98430ae4b1e001fe51d4897ecb6c62b718cc3a8e9107cc63c2e4fe936d29bff6273475995dff4b388d59f04 +00 02cfbb8f340cae8e2e2322829148981cd9e509b0c65497fd8d9da5dee9dcfd39b0f7556c 884e9c831443804992cb83036d7ac62206829a5eb7b3dbcc137e3446c574a09c891b45ed34596275a7434037087e7b210f403a58cd97d2f9bcb21273e9adf538fc52de00d50c8551825e9cf94c2092fee548fb9e39bd37421958224021f69e0c +00 0070e82a1f3fa6158d15b7346dd56150faee5c98c9d07c996e01a06dc9b211b12ff62d60 995a04d398174674dc8d562ee1196db6dde624613a7cb30f67886db12bf7ca8a87c5e88cbd405dc9fccd7ecf90518381131e0b7ef4ca427068a0b9984e7abc5dc1932ac3e02aef05c4cfbfd39ca5417a73ae22b9989b52a11554d92d2a0f5c84 +00 00b471bbc5f7a07996e370da4a09e71e2119ab3a562a273f079401951fbe4df39a4493da b2f0869f9775670451451a81bfcd9438b38b8aa15d92f5444cb4d9f8b1fe040cd33b4ffbe7f6de3b0abd7e03dbc7349b0561ac3ab6d3c3c4e8e3cd1adf6e86b46f3127602d9df42c8a78b2e8bfa8f38a879805614bc348213e5f39b004e10304 +00 03c65cf80bfb507dff52f9bf2f93df0642020d41619b3990009409e7210fd7130ac44ffe 991757d68f3028ddc892c63bb5bf07ae4a1393887fae9782ec3178844745402a242bbe6da30117cc78860029a313042007ed2721fa4b4414f097b0552066a93e5870505cad967b69686b22033f7bad72033d48343d3668030f4c3bb85ffafea8 +00 00f4d33a9c7e6744ab3c441828bf0f1866ae1c042cc54abc754e3801263a96cbb3955dfc 8cfa4cbfd9f13e6888cc9e7e7423b754717d4dbfb32296b6ebd198f37dece001a79c340da28cfb8259c1ca52a3a5202b0e60feff281e3efd13dd8939c7f745eee8aa679b20c36d1db000e66d9cc58d4aa3af9a29236e96608b174e1d81583d63 +00 03a4824bdcea6a144d85f1b194431724cc49849b6cb949b4766d641ae95477d1ec3d1464 8db5b010ede48cd8750aed03308125377d5dffdad79b9d3c16391504587e52cd1e133589fc0288410f4bb08ffdba460f0dc71cac78252891aa50f6a32dedeefac248659f5b873eefaf8f968452e442dd450233d6f21523ebc152d2e53a291ac2 +00 027ba543ea785df1d53d4ae4c1bd0a3a994cddf0c25d2b4e8ff17ea7aa00619e858da1a5 b755d610d80d2a1b23c8b05f25949e2017e3b1149f7097e548fa77e4046ddc1f852104ce9d8412c8985ee34a51286fc211bfc15934bca8eaae97aacb832ca4c8a0269db121996c742ca66f87b4e5a835a6a98cdf375e263ff2aeb4cfccf944d7 +00 00708d0907d14dcd5f40e2903e1e90e48a0ffaa6d4d9b84ca14df4e985c294f74eb9f2d2 856be08c059c092cf56dbc95733d13a350316b0dbed89059ace5183ce84aa944705bf8c6df5f7ee36029d9e5479a3fd0169f9d7553eb06f9b79307201b8234a95594f6ced7884fd0f4b800881205d4eabe1901ab08224abed26a0b8284089906 +00 021fb0a6b94080da8b8299b87457dc09d21bc430ba5f3359d92aacc1151be9941739567e a8936059832fe02e7e8ad2d05610ee581cf6383247717853bb8eb5501c354cd13351328e222daacb26be0db3d46bf2eb021083280ce4fbca8adf687bd4e6b54419ce9283bc8ab87588312083f46034fa198da9789de0eba67dea05b10427248e +00 02c80151f91301fb6b0c7685bd172f20515b46bf94dbc4160d0720fbaedd40ec00084447 b48065fcd5588e275dfbd0f7bdc9440713a20ebaaa9091236b0e7e9a4838658860b22da9828712ea02c6f6e7d8dc2f1b12b2e4ac0f8539b40a1ab366baa8fc0449120fbf83e41e9ebc0ac57e26123c64be79025797418615bbe969b0b10bdd03 +00 01538abd7ce8a6028d01604b1b87db3aaf720e04220edf4d1d28c2d731aa25f509e58f2f ab1b223d5a7e38cacbdfc01d273f03498b066ec58947e0c31822bfe67ca7d260942f07a5d20d8736cc2e69ff803176230bb55b3a202ca135a18bd83d70cec9d6dd4a46605e9dc447bc9fb608c95e3ba455fefa6bcf00a9f561e06d25d7696b89 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B409 b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B409 new file mode 100644 index 000000000000..de5c736a8d57 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B409 @@ -0,0 +1,60 @@ +00 00beb0df3b0e05a4b5cf67abef2b1827f5f3ada4a0e6c3f23d698f15a3176cb40e85bf741c9fbc78c9e207fa7302657527fd92fb b8350432b240efe5547699861d22dd1659260ca25a17924f31c47442637f67cfafe507a9b684e3bcb03fc51eb10698d20873fc3123e33908fd29c14720eb64cdd0024a65e68d4fa32ce7e87826b368466a93c507f12dc2683d08a84c6f29f5ac +00 00504865a30984a9b273d1bc289d734d10e0aa56e93ab14720f1a42a27d8cc932cb8804b963175de6fe57d8eafa8ab7ea0592dfa 82fd9fa6893bb50bf1036cbfd48ad76c746b8f73855b4ca7e550dd00e123264aea306a757cc1e5c79973260230c72c2e01b1f4d67c58b5088ad02408d7e1935386c4d5a0ee7948c57fc2f7bdbf75d3f7c9bbb6d94afffb85939080c0256cde26 +00 00cc08a4ea5ebe32027885a8c212870e7c45b6c610117994d6a42a284c05199414a3a0e8e6645ac5c2ebf21c505a601f69c62b85 80a55ba877940ed89452785559680b380c7779d01db2689eea3be7a01082a5af2fa4b778bf208cd7382c5f1636fd050b0fa66af141c1035db47a1ece8d69ac94d0dd8a909403c5ec13393feef6e0216c7a7b0eb018afa48fe9929f74a0b1de9a +00 007156ef0a74ee1119532a2a7e8c02be1559c3c21897af9d5b34553c3d0feca4a8d5929d1945df824478e0c0b92a6fac8c84f639 8d71ddefa891c65b383f08699e3d6c6d61af148acacc4e4a921a63d512ef95e285a54c67c457f94c7bd33f9bad9c23ac192d91b1adff724c784caf9345e6059562be556c8212780e0f697eb7fb385e1eaa8e66d0ae776ede07431a56630f6def +00 00a95c7abffa92e2c637611ccba66ff9d2ab121b40a85c5b71454cb0dca1f098ce1be8d9ea4933d1a91bcd270c5a33687835d6e4 a11bb8df998f3272e5b3dda64819db686c9cdc17def6a830d72c482cfc7eeb7b2127e9f60310eb6e97d4fc2627e9f02812644f1fc7a83e72ddf57c6ed3e00d370ac7c7f406dd7a37cf8f1d111d1bd47d2e444ae2e5b0bfb5be36e4fc7524b9c8 +00 002c438b07c6e0685d1f94a4bbafc013f8f21265d893f54e54c3ac2071606ad1ffacace0b8367aad724b1d9508c65ce52282e397 92258de5b51d24815932f7b780fdca38c25ed0a554997e9f4390eb48935e6dfba7356d7a655bf01297be87a45a3a089f0a05596545882650cc9c69cec61d7e54bbd25549006d636b0d930f3aba58e608e7e5466a77cb5bfade3b84a892095525 +00 009e8658f8f9e6cd98c0f4f0fd20d64d725653aeba339504def17f3ad12a63dc6157d80804e5f43f4ff48fc5573fde2c615ed31b b3a1bd8610db60c9c56886275193ee3864e6800591c41b46d1c4fb360f80f87c2b4a8615790d426ecef5a14a40d205d51319c94d5a6a697f5aae9ce9721e0fb7c4999bc3472ff25e5c6ba3a242b65fcdc7a970c8e778c815bff6774cdef62e54 +00 00c4c13f65eacce85a51881caa6f82d9e48ec2ac574947d2751823a7f072d38bd9da0cdf30b6f19084a6d291052e7bbc2e1349e1 b7772ffc7084ca7c68fee9db7c071d8e0492475855409cb6ab4aee8a646284ba24222b41caf0d74d21dcc05b674736d1065d3ed995b7ea342bd2871145522b64da2d85575c6aec699660af6c769299fd5d7aed525655d87d2f10071ec4e27c66 +00 00da591461791ae7847e6d8dd8df46a63d3021644abe9520e158406c96540d8fd82ecfb1c3f6f5cfd7688c7656cc3e3dc94e586e 871b372d53bd20873ab7eadfda0220d5b9d8faa3f68f2a0e25e77ac82ba5131c356acb0f9bcc1fd0595f289ad549fdcb156a80ffc2db71b5ac4c3c78d68c19d51aec8591357a5845610ab58180172f166123d52f44a9712a713cd84d4255e39c +00 00b5eb943f0dd390b737510e2bb703a67f2dd89dc9f6dca6790bc7a260cb2d0fb8e1a81ad6009ed51010e7686d5b48233c6c1686 870c892814329b5be89bec06722b5a8dc63b6b5ac8f23e3584ba228d0156d3b69a4c522d7811957693f057774194574c1930cd7a77a90fe89f915d06ba3518ad08d55d5d202e3ca63d7b700bc24e2aded6d3ea8fbe8395470d00ded59cc534d9 +00 009cc63f32152284fca27ab2837bf1343144336a1fdf15b9727c47e877ac69ac9cf4c97b4bf42f1ab10d73de8597a554ed099efa 90397cced483e9bb3629f37dcc041a52a66129efdda2dd06a272262b63e69155b5bde7e46d90729615b4be00e77a196309f23afbbf01616b7e5da66f1a2cbfbdb939f19048a8fecedd7858e4fc3e5b5170bdf69ff374d4db87d82b64fa0ee12b +00 009950355e8667bea8bbe3a2c4988436ab5394551b375e27fdc0c1a1d1b07ae957932f428f1aca0a486e54cd0b5bb0a5c5650641 88a44b8f98f9d33baaecb9733a0e6c6b5b7f01736826b491b8f35d7136d719d7d24b875b2d9a22cacd1924a7a2d042f700525c409e2e83766ec8b1a738e5370c1a992711f2bb5db8aed89cde21e9cafd12486ac9af8cdc7b0910d15a705f3045 +00 00a995493d6971c2d7e8fac3da9f8c0b5afd877cfb94924cfecc167f9d87002136ab253e3a4f9ddf5c9c99bb1dc1af0c6a3a3c4c ad8527ba1c5f44761c901895d53f9d86880162e171853327f579407fd22e433d01c8e03d8ca589461072ebda76791e00054217eec2867ed8174d23acd22368de8409f65a7e57eeb69385663433599d845d353826d4148aa91e33106772d1a8fb +00 0070daf435cdc26ad66c3186267ad12d10f28d32d863f950cbfcf042fe9dfce553750ad098f82f7f1650c1126b3e4451bee6e11f 8cafa0683547cd09491fec344f8844af7c4a6a3429d9fb47f03128c425f8b5bfe01562c465d77f9dc6560b59caded102039ce9b196deffe34bcd33fde10601180bab71890fcc9b651934c0086912c4edea90774cf7943d94d8e737e4cde35c85 +00 00f8121980dfbe9ad0bf92383c7cab95fb72d5caba96e1de7772c6a179e85414802fbb86d725401451329287305570ec7fdd873a 8b66645d2ea892c37d239f951c0e48cfa80b2145c9c60e60f84d17c473cc6bce5328a4924fc3d9e340ff1604e2d9ad820b90f7af5f385afd0b800d5fbf5309e9ed71eb2b3cff42cf95f04127a05d65f9ed961a7132351dcc95badcd77270dcd6 +00 0047682b2e3bcb5800a531858e8137692a9b1ee98ea74e929ce4c919c26ae3b3f1d4122d07fd9a70d8315fab727ccb67004187a3 ae4cdaadc6b582587bc4f87a8868156756de18451cf1ec60ccf62fc2ef687c2303a5367cc44c7533a2b417f1648fc1c819c9f70615d00af2b3052734f8cf4f0c5579ff1b7b6bdd46fb107310df897641fcfc39d026337ba4d54e5fe0c71afc47 +00 0040cd1a06233ac27f3ddd108de7c6c0982793ee620d71982697713be9fd5143658929924cc88747a680779bb00da8a44e1e7d3f a4b31a39cfb88ea9fa265a422639e9d363ddc6d769a1f5b15b95a9d5e1c0c085692bf884ea90ec6853da41971e37512819c784135b6733d4af1aa12f247a913ad8334fe173fdb96913a0869aea4fd9e1431015db8ecc12204619882317e12bac +00 001ca6f752aae4eb7fc9c73a08d6fbd96bfde5030d759a2507bd45b6e1d1487e53abbe98fad4f41976364e0a1d830910ccf97abc 8ac589aa9bd6116dfa23b0830c791413b2f70f9094d3385398b84c1999df331b935ce68816936106eb103e00ebebc42106a950739af25ddd4fecf3c6c553a6acfc74e24c0f6e4e1bd6b849b1ee06b092b553d459ed3ebc565d90fd62f4ccc707 +00 00fb9b1a9597d216028902abf743d25944258b48c9762d4589fe660396130b75f6006cacfde60f6204463cb8c18b032de1dd68d2 8f2f44fada4d459243216824f3dbd68c444902157bab649725b8d98454bc7a895d971cb3934e7ad9185bce22f4050f640ff9508bdd7e59f68bf9d2382b458a6eed565e66f99c32799a0852807adb1610c99f7a967b0a5734f36ca4297b93c28a +00 0032109202d754da290c266f74f47805a06e6b5c3f721a72fc97a3bffeb8887e0c642d49a6bd034847d0a5ba09239c5dfdf0772d 985e1668e4ad12f572921908978e63fcec37cf2cb418c25847cb00205f0142a4708c40c51f99b0462610c11c20278195019e6c9f89f77b97c863b9eb54a201fd38f3bfbb7d15cea6dea81d2b753c33e9c9a3e2663434d2eb724dfbdd253ec654 +00 0080536e820fac59b3203aea928475043b2576446619001647e35693a9e65d15236c3cbc12e1bbe0eb305973535c882b70197a92 8a3d6ca70609a9cd2e77467a0cd4b7c409a249064951a15e39d2ccadee78a2125e1c9fbba7d873f2003469427690b0d217906ae7aaeec3ff91ee3047b22dc27838a2899e6ee108fd2d951ead518a094ee2cf1a3960b6bc62474647bfc8199a85 +00 00b05e5f0dad9583ea18fb8fc4d8c75fd2e3cf9e92cdd9b737485c953620d345006c31c288b380258b6500b84f729ce6730e5303 a082b8c19d76529e3fbfcb46a1bbc049a24fefa2ab41f9a34ca370effe7fd3f2d06d49517e6983d82dc8535971c0dbdc180322c8b6219b075068a4d20ecbe3bcce8bd1b30ec7452cfce78b2403782f492d6f1e7da85bcae5009bb291b9baf8b0 +00 00be1d277813e79051ca1611c783d66003ef759b9e104f32298017fb97667b94dcee1ce807dc6b4d62416e65d4120523bf6a4edc 85d5381b293cce043294c0552ae3fec586155179c8a339f9f43f6c1a68a2d5da9ac90687aa936b5db79c864d38c937500199fe1eedea70956422b5f04b97f9c8119f353c8c2f3f8f0873cc2c85b6b17882e70d611c411734626f2ddf23434255 +00 0073c807bd7e07379782ab790720de4ae5106f16d34e80ed70da5b1594e660c9b775db94066b93e74f855f57d88b6ecc6228aace a0460ad159f67bdddd10b576d30a9d64408d5db42e6959c1187e02e947c2b809b5fbf1a5651ebfc8bc0c040a4a4d86c6005d066d38c1d662ded37049d8991531a166ab42c74ed9d68547d8b060f636b2a1cb3ba64248162c0310515af3fec938 +00 00a68379b2296a6c944ad5dacb593b302d8ef0b05873ce12bbc371d705f308c739d21f343349524aa72f05341e64f7435daef112 8e2fe3cddc992b1b90cccda3df44f94fa90b22a493ba10065cff1c8c1fdf168b5656fb3cc6d0c0f43294b61d9785ae800d3f8cbca773d61047ddde733feec4137f5f87df6967451d716377ad3fa5aba8614fbc13119685578b3c2f5010acf2e6 +00 0026046bbb269ddb1ec14ade56175482343a21b7c265026cef3c7d6a1ae0f6a68166b9e6c49a6e733ad2ad64df7137ef230038fb 87d0dbae6b0bf5d6770054774799724d2ee913a68e3a3a003d202e2445cf1d01d5bc2007f9c83bbd2043f89237ec282f171fcd2edd72247c5f543d6a92192ff1fa8d30d3d3041efb07401c162920603685a1a503c850f866d1153141782260db +00 00bbcda66978ea526f7bd867c3303b625f11b94dd9ee6e2c2f8688ff07f2bba83c662949d47ad47fa882cb7d203a7f0ef5dbc52a a34739cedf36c5bbfb6fb7d40fd5b77377e174fabce8f06e058261d90aaeec2668074f03a3c88d6dbb05a439bbb287580dfe4930665759148f2a91ea71050ae5e384b07dd268205ed1eb904c94e505646463f11072b79021fdb9461a4d02f1d6 +00 009be3dd3442e0330750f0a6252bf9cb317f32f942ae516a4038dea2c40ca6484fb33611bef016cc64baf166c122e87c15466fd8 93a924513d7de2b0de15c141ce6b0c256d03cbff98cd98e7101446ca8c084aa411c0e6e603cb4ec19ec6ebc9312cfc8e0f722e5d919b8f5ba44ee7aab01b03be0c88ac6b290ae4077a132ba0dd9b3b34d23a4f920a2055bce686e668a34e01a7 +00 00ed321fa283c662e87eaab99b7715e6cdc9b42e14fa5bbe2c56fdfb381369191a42da7e574839f90a85577485f19446fccaf6cd 93eb62f9644b4de70382df61ec86af0941ee78c26fd8783ca7492295048ff4fb38778e9e5a534052cad03a253e0c09690517837c4238b7155b8be084dd5534d588820536504a770347ee42610190ffcd10cd2628f6b787ee834c760daa635064 +00 00396b805073f3c3b552b1024dcf35559ac44f255b688871a3c6657f727a4b09f3806cbb75d26a00ae1728be632387e804775a8c b357644dfe5acae963d919e3b0cbd239e0f7315e2a98217426adad720e8f9ea6df3b9611d50259cd8c94beae8398ae0b14ed36e74529c2110ad165954667b83d57d034082e96911ffda0a73fbada61a55afe6592fadfe0bb0c7a7a96ac5d78a9 +00 00a8fe323f6736bcabe971c7d964e75dece70cb54561da48a11c40027ebddb23e41c7b48600f569500fe8ea2abebdf480171dde4 952fe4055491fec8e45c4f435642c079726adefed149658ad5401a47eeaf9d9d5213748678f09edad1a2f05914e48c3519e5d3cade81d0c490f157be1a4288ac2b9d47a6d884c6511e9664332cf0def33630e0b6935f5cf8d2fb65d3dff3cd75 +00 00105938ba9f25034da3e032dee121bdb192ac2128b50a2ed4bca042e96cfaf4660c9d35f3e67bafd4c99f9447e6dc408e0c4471 8878347cd85cad968ff03194e6e5f27436bd4be9a6491c338078b23020d6ec01d58f19130fae3d593db3dca46d523b9d0c4f185c5739f94afe13dbe759ae84b1451bb4a8eea0f1a299a2ae2a2f9ec8f145b2bc1f2bfabbc125b7181d9753681b +00 00ce11677ca818537dbaeb880fc967dc8bead203a2538a55e756679c4a9e7975b9b3e6aba4e6c6eab4152d0c0939027e9b0bd92a 875cd35fd0f542d9135e7bb5ddc580d728996c95476f0a6f3913f780829706d72eae94681ef4739390b86b134db3922219a573045a38f15920c64921777bb74837ae8f31508960792d3807ff26d90e748c035a0cdf6b9fcb700115ccd9cb3afd +00 005a239ae0f40d76d8d3589f1662b5ca12176a4b2784faa8339b54e96a1e1294433a4d83bf904196f939bd8b33bdb4be340ec703 812f17b09005e4910a24b5ce01722b28f4c970338c2654800fa61c6fec8a7feeeab796ab9b0d8a3ccf1674747c3bd66f105ee2ce0798bb9d48ca256392cceb2745b785e1b69ad40f0ce76de38f644f9b26316c6466ddf8750c442a86b2296071 +00 00077390c62ac41aca995640fde0c79c76f4ea8a8dbb22323ed812bee837ab8798c5d0ba976c7aa634d4b1c2c155de2709e7352c a96782e6f7327408376b41f073202210e785495d6d8a395bc18c521b72275337e3945f139ae3e41ae39c86c6e8d2ed340baa361a4559878f45b547e723459df781a2f5489855c65421b8a361ad1bfc252754515b5697445435304d5fe4dabb0f +00 008bf23b09fbbed1b55769907aafb97f4759cec98649b2c9da5157517d4f85bb70157076b5e4aaa7a940af042302f8be06a84ab6 a885a1d0086ff60abce07003997eae741573b99ad36ca43a5786d6836dd83dce68e59735c5eb6f58626854c0a39cffff033b5636efec2f72ae833f345384d95d628faddb294e88ae16544d519f4c971565ae2b38ed388c5961d1c66ad064c21c +00 00082ad05d19b8e16f80e53a4cccf6869ab5128c5e622ed146fa8555985ccd2aa3b9957dd374586115d4d75b1c01cf98ecfc3646 8b4b42a149d1c3892e3607d853e2c1cacb742a6eb9a77f3562b5b0b0c7d870c65b746a54907d8b74098ba5115cb1627f020c4db5678f0311b6d3fda7dae78dd410ce8c8577f52463d8e5c165c9c392f0905e2aa4b00c88292c84c34746e639cb +00 00af7e581aa4f9be5815f0c447e39de00da9194eee5e5f609668b9b69930b5b48a948614c2250260d1917f0ebcb00ebda4bb52f8 95894bcaf27d10ee643f2fc6ece479906cde897f00c9f505df0b1cfae0f3afb57a3afa2635caeb7b5c633c839fb04c340f71983b8c187c76fc79ce5630dd5df04d059182760ac97becb66e0c44617501c42552dade49429cf7c9c672487e937d +00 006d14107b08354e6a41d7d7d50c004419db8bdc50db43428df5e86084551237223c498bce71a17e25695bc438c5c09e009c60e2 ac86de1b58a43b488a4544e9781c0742be34b9f6177e57c4c530edd394f0c689a621b03eec5bb04d686ce03d0b1532ca144028f1677c789c799c92a2eb1a3243609fa8680e4d5bf96bc22c7cca7c2c0b05c6fdd4bd679f42cf20386fdcff02cc +00 0099d96d2dc9c79549f031bd5346cf6a8544c312a3fbfc560dc8e378efdfe025b0e6e61e09c04c8bf4133396f993b0906c33dd30 8186f5109f454922cf134fc29da1ede7a9bce8a6dccca196400e215209cc36c019fe77811edd6636f66d34d5c79de4aa08d5c0467bcc2b7e165e8e279b2de946d18e73800a59fb84860887590ef1b9b660f0b98ca36d6ecb6fe695a730580894 +00 0049f347dfd361a65910e97fcefbf60013a54837f2ae657d65e02397f59dc6bca27704fed3affdc3d833fdc621cc5e5f99b92a63 8a00928b7e1937d4dbc944052215cfb620718c6d9fa189aa9257f3299394f88fa22a402eee96ac3a699a9a0768b33c181477bf5ddff72b01c75bc8bd3ebe534cba25af263dde7c2a33fc6a28c071187523e6d0249bcedabc5c96357e96e20c71 +00 00dd226de602af4e9f8e25784bd1bbd4cadb0a8aef525d5e2d57b9f3555feb698765672c5099a7d6dd5faaded69d8d68b4804f26 a60fb800a2bab0443a509f6c042946c0d742d5b7a5edf6d58c0f45f2b23394373c4637f89c9759befacda20e18819f37063ebcc570e3e5ccdebf6c9c5cd717cc8094d6843cbb2aaa9ddc1ffa177f7c680aecacf855fceef37be35d46362a076e +00 00b6fdbc9c8c76cb2b822a940d8675889ca6f5132429da795462381ce29313a23bc132976fbeb346ed4c691e651028f873ce7971 a598148fd8e207d7358be18279c5b23a73be82aca638c3a98a5505fb91b5628c69bc246a7cf8f383fef67d9578e0750103d432b81a159dc4a2589b7d4768c078fec16658f7be108efe079666e9f3f92a26e76c940694029dd1585409e48a20d5 +00 00203d77fac64591eb9a18de20a9d5eacaa1c3ec58a5ecdb3008c2d642e197141d16b3a9fdffe61429264f5b420f5e9926659a4c a59855f94cd6227e4efd2b43d56542bc609c04921a3ab46174bcf54cac841188798af94fa49d6b09a5ae40df6cf85b030127fa89204ea34e3bc607d1a88918ba2e6b0aa6d7bd1ef2279d3742f879d26be92dd853d07e98b9968609be58497f89 +00 0057a2e6a59d4871c3d547690237dd9846d6d5dc4ec0678aafc9c8669af8a641eed67bfea4b05fd6b3b5357ec4d0caf352691ea4 81c9a7d3cfbda36587fdbcb908790d7068079a5269529720cd6ed083e3ded28326835d2532a2274319d5330112ab010917b85562ab45ff27be101fc2c3263d9499123ac02ca4e0e6ea5fa10a31aeb61d01a92c915afbc2fd81e498c9ee545d8f +00 000a3da7a6633608fcee9ce4253bbcec08d41ee6b00178ceb017de74e24d48fd89107c9f2db3556063abe3cb011938f4b4871795 824402f58e3f58e7ee0d68b105e58cb0db1edd3bfa7bf4a02d7b213c332de18e0a3e258c1d00c495428dfa1b7e604eab07efcea141c5a93dcfb8ea8a89b7e474e126d45ee7e0e34c1ec14c55407bb6303ba00d69d22c7d172f66b41413a90699 +00 00384723c8b4a316b450d1fce0b2645912b8acaeb3cad50860cca43bdc0206ed5b3b60ebdc29b3eda305d0d60eeaec261edc24d5 b1c269d33f78b4f6164be1d2641ea40540706a019e5d69ec9fcdae58585d36353401493a539d16a22eeae6b6dec603b507f95f0cad62b030f21db59f0113297945beb98ae7459e52949038c98ececf590dca8464c02a5739de1137b2e6b04ee6 +00 00bd3136647572fef3de51b12e64b36460bd3a27dc660c164fc705417339cab21f9e1f9be0f3da926df459c5ba58b701d306e67a aba859e02efdb143c44bc571cad6752976519ecbadab3d347e6988006861aeae5cb58396540e5f3291a71f61968a09870e6fcabebd7ecae272f89cb324581d94ae5d9ac157a5d0a7a54329e6290b4e74fd6618cb2fae5a6a88b6596bf616ad5d +00 00495be0b0a9d357f6155fac008cec90442200bb842d89292fde38b7256e4117284a60249b3101b3f19f778b680c0d1d7422b84a 8310c3435168eb3f1ed55d4ae0982a7af0ea32b93368c622890aed294e117d43c1ba2d955b8e968b8ccff07509844b670f309fdfd8e5e65537d67f5031969ff93c4a6f376a0fbdb9b9206b8bff7d3cc630acbf8dadad4deb55ebcab4cec346c8 +00 0079626354dfc4eeeb51fcf232ee9e6b0130c9bd40f15ed45606bb7faeca8f359e0c3e18bf12769254522fd4077eb24bd5454871 af4947ec4ab1c8dc2f1694ff85d43bdf0a7c373f950f1252b1416bdcea6e1225d1f065e5ffcf3f2b4299243951b5c38a0e9da1f2322ebe7ec4d9e6b91f18ad48edd799a010a9468595968371ba25173634f0c97ea3504bce7555fa9721294444 +00 00ab42bc7d0e3c23f8bcf928e25f9f027b56f270398a1d37bea0ee5426b944a9c9ba6d0d7796899543feedb470f70b2ab148234f 8007cf582b513b4e189c1f401a855194087d2dd7ff6ced9363efec6134ec00e524a4ac147b8af7ccf80e0ad33bfc915900783b80015ca8e288c598b9eb04f64b4df6dbd8ea05ff506c029f538fe32a5cbb6e886a14bf5d3d715f8ad5e349d213 +00 007f7aa2216164ba689459ee5d5ca29e70ef75a5b2a4416ab588df1dcb9164330c0b405a9d80c3acc41c19f58e24e17ecbc0fa7b b48029d3cb110607d3c41b64497fa99ec415098e54dae9ff04bfcbc207699783779a2181e24eb4526e18ff8752614b68124c2af0d0e8bd9cda5b19dc70b5f766fff9700f316d6ba0993f70db9f538eedd0dee25137f5167e8a7178f9f2599959 +00 0021d84f070c6823a70f1a74225a472118c93ce9dc509aa6064051ca4574939dcfa96be862069424bdf1a23f62f2868326422e64 b2fbc018e01935628651f8e595b84e883192182b5f344635c3ece667c27f2a8339181f8938cd1d5f33d1ef16abe2b12404cabcefbadd9f47595369d6a7b76eedb48c72a82a831ce1c900a4ae63af6c8a6c91bdc2345e068264f957b79d7cd0e0 +00 00b6645344d17528968c719091b6e2072388881dc10bdb4c7fbf41906cadf3699b30f9c1dbfb4796d009480664e6276c0359e5db ae86fe3e00c5fb3909646f189f5a39f210f024c42f5efe2a331b7012d795410665bb72ff7a6113d6667a34b311723eda03daeffd4b41ea73dff6d492959693c055bdf76bcae44e37ecf62bd9d78575e59d181666f0c8629e3e89f4461918442f +00 00f8c2f770cf5f8e1f900e996ecdcd84fcff5cd959777fd005d721a419123221a3237e39834b270d37752470deaa6cea023c5058 85cd383d092b28392265d109ec7d606366afc3a388b4c25a5359b17b8c2d556fc076d4070b37007487b2facb95f16a1d0d56d5f4c57047c92921a0f103c79ff5588543bd995ce1416d24eea7e81f2981a724fc7d6c3667d809a1c5c0bb7f6796 +00 00144adae951fe897d5812ee4a16c0be4c86c5e57e615c398f5768a1223a9be20fa82ceccf8a16a31432bbfd17e594a4cd8a6a07 a086b2bf8bcf423efbced67aa25626c99144cd57d75929942a9628556e69f76d4479f487bf61aee2d553bd483d593b6c011a7b210284bd9daced15818b12eea078fdc3c80130eb1352ef7cf4b3f9e858f8bc80988df2c4fd7eb25d0acebe716b +00 00a51f065fb32c55bf4ff6f18ba9d488d35d9f8da593adb0ab1632533284e0adc43ccdbda9d9507b9862ac63b5ae7b0f78b479bb b602cc6ee7c7b3ff616fe313ee1328bbb9252e100b1779b74df2a6af7c79994f6a12a926ca0ccc1ea842c648d09b7018169359db8b0439df33759db1db8aa08306a1dbff66b0cb5b556a3033ce1236e9733f9ce9d920dfc367618e2888a45cc1 +00 0095351c0bc07acfabe6477fe85f97eab520dc96bdd58b44b036328ceadaa56a1904d2217c5fd25155ff2aaf9005a3e2687fec81 b679e7269c4775b7ce29b694c4a37fbe021608052a399c1e0901ebb6eaf983d228b0419f9f90bf79a94b72379d9be010116faab92fb05d138cc1395df44a6c7ecf4d54a3a0ff55dfe675b476c5283e10a5a77c2947c45b43203be07eefeffb4a +00 0050245c1682344fef23bd549ac8d1e8e44b2840c43eec1cecd33daa4e9ef6b53f496104d7432e14248682cfd6f5b4853b65adac 9321986514e3efe71dd2a51c1c960330ad2ad80370a451f2392895d83a111b06ccd6a70597f4a51ed7fc0d20b5673f7b0a9540f67af134d0bc7ae9808a1006062f08459c5496b02d5746ce2b8ee9a6d9f96e4f4dbfd1fa67c6feb8d8ac5bc7e6 +00 008d3b0277f0e9fe54581d3a9499ccd7f015c08339591326859af969d2a26284e3b3beac4a0b74d324ce5cb5f38c7995e4e3a41f 849417847b46ccbd05d0608a02491a796cfbcbe18bcac992b964b0c389c0fb1ba981301c38476de840444e89c85a2d5d1113e308736c09cf22dbaf0f15bff429f28bbe38208f717cd9630fc56cb19d059b101d5559404f6ffb4de2da609f7b77 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B409_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B409_blst new file mode 100644 index 000000000000..6e587d514ad6 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B409_blst @@ -0,0 +1,60 @@ +00 00beb0df3b0e05a4b5cf67abef2b1827f5f3ada4a0e6c3f23d698f15a3176cb40e85bf741c9fbc78c9e207fa7302657527fd92fb a9f396bd8a0060e1b5469ef22744f636de3a088672a85df1cf9ce52e33432d0387579ef4050aef40cf67bbabbdc6993d129a6748b5f59fcb520889eca6a2e4a0807ae3cefded76a3588250a3e98e614021d16b62b7d9f21a90ac1afab8dc0e15 +00 00504865a30984a9b273d1bc289d734d10e0aa56e93ab14720f1a42a27d8cc932cb8804b963175de6fe57d8eafa8ab7ea0592dfa ac47a2a15dae3c369939690733bb25f27ea21e5bd1fccf1b0aa36a23243cce2d9a34606d7d51b9658af45dc7a4450344087f43e6b8fbc68ad76a2428c62e0d50324672424253c1aea01cc749e6863898cb72e4085e6757cbd89eef4096032dca +00 00cc08a4ea5ebe32027885a8c212870e7c45b6c610117994d6a42a284c05199414a3a0e8e6645ac5c2ebf21c505a601f69c62b85 8f749c951cb3c3c1eefbe67285952d865cd00bf20ce2c648ba1bdbbcd026540bef33881be9bb48f6e806dbac548e13bc0d6b13868248e82a701d1c9c95be64e92bb1092d1c8d3cd97a3d97eccd26317f8f742727eba2bf5d6220d34ac8f35ddb +00 007156ef0a74ee1119532a2a7e8c02be1559c3c21897af9d5b34553c3d0feca4a8d5929d1945df824478e0c0b92a6fac8c84f639 8daceab29c80e21511be965f139b747645ee4b4716a9ad0636aa11dcc5b7be292f2ef3f8d6f0019feb888a528deddaa118605ed7811a36e17d2aa9d081430ab11e0c2138579e530cb6b2c4d9185eb7d9c475854ebef99ee177049c6eec5721b1 +00 00a95c7abffa92e2c637611ccba66ff9d2ab121b40a85c5b71454cb0dca1f098ce1be8d9ea4933d1a91bcd270c5a33687835d6e4 aecb4633a923bf42e515f1a36eb4fd0483ad7733be8d8253cacf0538fccf8f66e211067356e37fd03b134c93709e807700c2059261bd57e98938af1cd375759b3780fd7f6883b52fcdafb82e36f4160e45dec46c6b7c6fb323735381fd927df8 +00 002c438b07c6e0685d1f94a4bbafc013f8f21265d893f54e54c3ac2071606ad1ffacace0b8367aad724b1d9508c65ce52282e397 922e987ca1dab852ef607cc45ee66c264ebeb812f0aba777df2b10d89d543a86972e6b35db31be9392e6cf6286d2ea0c0c4a649e93b7ac587b4c23c981692039466a855a1ce6c832f987ec14103968040a6ead5d1cb1a625298d7c0277634eb2 +00 009e8658f8f9e6cd98c0f4f0fd20d64d725653aeba339504def17f3ad12a63dc6157d80804e5f43f4ff48fc5573fde2c615ed31b b107becc83c58a5be808ab1a4f3f6d181050531eb5fc640d7587b7995a9e8ebf2e60194ec666f337248d029a4746893819f97036a73b7151bc13c7e27a8551f91a9b6e68fab0830e2865bbfd7c614fc43ce50e6105c08ed28528c86fe58cfbc7 +00 00c4c13f65eacce85a51881caa6f82d9e48ec2ac574947d2751823a7f072d38bd9da0cdf30b6f19084a6d291052e7bbc2e1349e1 87b1328481ba0e897aa38c1f6c0e8fc0269be0e94ad14854c463aa9a4d33ef57e2f8cd84fd8a7be1d54f20fd2598ced903e757f45ac546325a513212c0a3603b24c243888fc46a78d3cabe8b74e52d618fe24a1bc957d4149db756154e1021ec +00 00da591461791ae7847e6d8dd8df46a63d3021644abe9520e158406c96540d8fd82ecfb1c3f6f5cfd7688c7656cc3e3dc94e586e ab79746fa54729245219ed172dc26ceb299a33c25dc1034b13f4d2f94789033c61b3a332d6213493249275830932752b0dfaa83566971df97927ed510492548f9e31f702a6b60849f729e669e6da885578736ac4f0b3b1dae86b4ee61bb19999 +00 00b5eb943f0dd390b737510e2bb703a67f2dd89dc9f6dca6790bc7a260cb2d0fb8e1a81ad6009ed51010e7686d5b48233c6c1686 a799c5888545acaba68c06321b422df198d834af69a37c058ae1b98bc5888735dfcdb0fa3796e55e17bb31eae17b2540170a250798f4afd63f32852c3f12d04f34f72077952b6118aeff5673580b499dba362d30ee4bb0b83802f622dfed9366 +00 009cc63f32152284fca27ab2837bf1343144336a1fdf15b9727c47e877ac69ac9cf4c97b4bf42f1ab10d73de8597a554ed099efa b744c4fc2660300002f19105256b7a12270c2263e244647bf45bc2473565c93ceee771550c1fc961ad916e395a3c1acc17c42ad3ebb08b423bf6246dcc6ae3da1bb0baa5df6612d4417c2236f0363a1d449dcf3a04552499d1bee0ab1f08ba81 +00 009950355e8667bea8bbe3a2c4988436ab5394551b375e27fdc0c1a1d1b07ae957932f428f1aca0a486e54cd0b5bb0a5c5650641 98ab8610c0fbebb16996a1c4b9787dacd6264acbf27191b38f2709868e5ef69f6c29d43c967402beac949ec9772cdd12010ce590cdf83b18bdeb9c0cf796bfcb637d03f01866c3f7cb46eb95e0f83e8ffe722046fc38b4a9c6063e294ae3843c +00 00a995493d6971c2d7e8fac3da9f8c0b5afd877cfb94924cfecc167f9d87002136ab253e3a4f9ddf5c9c99bb1dc1af0c6a3a3c4c 941c8aa51f0868adabb308901f5192b81685da568f0782a5ad948e73f7d10e7f9e72c241cacd01e76c7cf5441730ec4c155a2caef2796a3ce86c47b2ed6ed3b857f1f7233b88129aaff533620a4509b1f31afb8856bc7050270b5c7c36ae328c +00 0070daf435cdc26ad66c3186267ad12d10f28d32d863f950cbfcf042fe9dfce553750ad098f82f7f1650c1126b3e4451bee6e11f 8fd6003a6c8d054125310adf78aa3d3d7f056a600c481cdcde7167c03a3fca89f81389819525e22cd5134af7f7ebbf850f0f1a2424d825663bc365a3ba38a75d5f7172f4ab2cf83d9f1909761332145635480453a3e72b2a0be7df5c3fe15a11 +00 00f8121980dfbe9ad0bf92383c7cab95fb72d5caba96e1de7772c6a179e85414802fbb86d725401451329287305570ec7fdd873a 990e6045687ff6fb9bd16947a6aecbc21ade6902cc469edd42d61e077d7109d111cc8ca6325f5bdd88e48ac340ade9cb13c54dd0a4d7a90ec35bf706de7e9a58f57c6915072b052b1d23c62a6296957ccb1c273614db9d615c630190845033ad +00 0047682b2e3bcb5800a531858e8137692a9b1ee98ea74e929ce4c919c26ae3b3f1d4122d07fd9a70d8315fab727ccb67004187a3 a9d6dd4c23bc85273bdf6e5b96be373858372bde3df424f13f780de1988f5794b74fb2ed593ecf4995ee48983f69cbb50dded533969c984a5d20e34865c5666a5b448c77866264b8b57f972bc27d50dec28b227c417334b36a0726a95d4dd180 +00 0040cd1a06233ac27f3ddd108de7c6c0982793ee620d71982697713be9fd5143658929924cc88747a680779bb00da8a44e1e7d3f b2a0c29a3ba89795cfc48370933f7db8f0af18679fa9c2ca0c15e0244d24352793534b877fb01807afb7e953592b4cb614e726ce2966db441b5aa15d878c4e5e08ba1ed5cfb7bce01cc86993412a7c455c2dfd245b574ff6701e4327e0061273 +00 001ca6f752aae4eb7fc9c73a08d6fbd96bfde5030d759a2507bd45b6e1d1487e53abbe98fad4f41976364e0a1d830910ccf97abc 951f802df5dfd1ebb041e867e08fdf5cda712a75aa5e8c4b7abc3901edf9d2cb9952bebec4ba7925922b39adae7a6db4088927d4d0e86f47e5a31123c0a654e8e82f108b2712c52a932098af43feeebb99909020de50a43fdc26e3a67411f6cb +00 00fb9b1a9597d216028902abf743d25944258b48c9762d4589fe660396130b75f6006cacfde60f6204463cb8c18b032de1dd68d2 b02d396a1530b4fdf2643672198c272da47771f30f6ab1c9fdc7515d4cc3c6e68b64a4b2c34b73ca682ba7c058c92c9c18965904fd0c48e003882fbb28bfca39791f809fc67f6db57263d84587d914aff615d778cb2cc93e807fd6a980ecbe22 +00 0032109202d754da290c266f74f47805a06e6b5c3f721a72fc97a3bffeb8887e0c642d49a6bd034847d0a5ba09239c5dfdf0772d 9082c6503fae42a2ff1fd97112097b347ca05b04be468e286ece4befa2bbcf4b0b9cbf1061468a19d75697f63f719a9614e886609b4205501674bd792f0bbbf1d9de8a185c08f00e108cab3ff4f9ad2593fb06a418a0beed984314ace6c4e75e +00 0080536e820fac59b3203aea928475043b2576446619001647e35693a9e65d15236c3cbc12e1bbe0eb305973535c882b70197a92 b6073e05a8f5821f3be7f555e99c568b3ee81ca8ecb9eba566d79d3279956c9fdab92907b45b880f408e77b68bf47439137a26e239663fd1e3b7271dd9f392fcdecacf042686b625ad644c8a0f8746143c8e278acdd5c7a365b2c8c3982b41d5 +00 00b05e5f0dad9583ea18fb8fc4d8c75fd2e3cf9e92cdd9b737485c953620d345006c31c288b380258b6500b84f729ce6730e5303 80c5f172da0c96b668b4f450d67b722001964195562fffe1d666a2199f0e7555df83c8c02de74c732af49f8615364c36081c951ad02694fe2b95a4ddddf9934027397ad40ffbf4ff6d8756556476dd9b0d313c16d63a02060c830d95a4a37187 +00 00be1d277813e79051ca1611c783d66003ef759b9e104f32298017fb97667b94dcee1ce807dc6b4d62416e65d4120523bf6a4edc 80db4d689afc6f15b742d0e7c5cd0b7bd08ae734a04ad233e2044390c3c82425122fe72707d8ff6340171c039b36e05e0dc31e92e8fd4d69d3d2f0d4f9b413e46e3b98b175dc1234e998c31504109434cffbe95103b253b4662df576b9103693 +00 0073c807bd7e07379782ab790720de4ae5106f16d34e80ed70da5b1594e660c9b775db94066b93e74f855f57d88b6ecc6228aace ae4b87d5de933385aa711000b61fc3306d3915480d87c89e2edddf83b7037519787de9889bbfae2170f5836a89aab25401fed81d5ef49f6615705a12c46d0d484089cc1b1827754c0c8d7a2c2805c2fe2c6042fedc2cb07a37d8335383c93feb +00 00a68379b2296a6c944ad5dacb593b302d8ef0b05873ce12bbc371d705f308c739d21f343349524aa72f05341e64f7435daef112 aa3bb1d125d46fa372612a347bf983915f602e7a09f2ec9652a771c1649045f526edd4c1de7e8a453c4c293506cb81d319653c8744a1096ab758941e61bb73448e9b97abb71034039ff6a73b35d6129c2dabbb861b152619fc340115e3860487 +00 0026046bbb269ddb1ec14ade56175482343a21b7c265026cef3c7d6a1ae0f6a68166b9e6c49a6e733ad2ad64df7137ef230038fb 844a4347185c713e2f749ab4379510ea4e1959839f82c405535fe742ad0c205e9b4c0fdf7539f50d22358009bb373b590e90613044b6b6e1068f41dd1c8c6f87c26db2cc1a04f810d7d62cff9852247512d6878ef66acd042b9d8b13d60659ba +00 00bbcda66978ea526f7bd867c3303b625f11b94dd9ee6e2c2f8688ff07f2bba83c662949d47ad47fa882cb7d203a7f0ef5dbc52a a1ae059e9f52915bf9caaa5961985894df87cb9074e84037d796529a4d1448b2b00fc224d0be4549a2e9bb7dd63fac4c050953c59b243787f1ce37ce0dd58cb88df46b8ff29b716f266ddb33e3aaac68fbb71a49fd80a8db2f4b03a57814914d +00 009be3dd3442e0330750f0a6252bf9cb317f32f942ae516a4038dea2c40ca6484fb33611bef016cc64baf166c122e87c15466fd8 ad1d5b8b39cb9310797d693980376b0a394fdad3f92d77b8c9a05dfa3d8cf5e66ca7fde6e38fc8a380291ac2c3ef70190e0abdd9116a79f62799085cd4a7d45c12fba4fec1026d325e138257311d09474d28801e8ef96509accb385278835df7 +00 00ed321fa283c662e87eaab99b7715e6cdc9b42e14fa5bbe2c56fdfb381369191a42da7e574839f90a85577485f19446fccaf6cd 90d658b1364dbcdf62b62257e59d059f3f0402df493f5231bfa41bc06ca32fb763733400a9498e4d84e118f2e54a93c016bc20963245e4fb92daa153813e3033eb971480b4b339a141c3a80409233883022370c4572bbf1d2ceb121b66c8f16e +00 00396b805073f3c3b552b1024dcf35559ac44f255b688871a3c6657f727a4b09f3806cbb75d26a00ae1728be632387e804775a8c 87533bf26dde33f8dfd8eef17c35c3e6a8b8da1d5381e789d01a657f32d3b67ed54e7a6c21f9957e3fa1f81f793d144803b7b2e453189404575ef05b1a030490fc064d842fd5617730b135a30f91de09db49cd9a4fca184ec832163ce7fe441e +00 00a8fe323f6736bcabe971c7d964e75dece70cb54561da48a11c40027ebddb23e41c7b48600f569500fe8ea2abebdf480171dde4 8eb35019693a225c410a56b65f3f2fe856eeb396524f07ef02c1458a58d60fab66a4c97cba889cb13544a74673d07fa10b8a351ba901ceeb7d279698bc1ed955d3f8505a921d3a50ca13fe58a0fa28ec48cfd7818a962d2f214a933b02106a18 +00 00105938ba9f25034da3e032dee121bdb192ac2128b50a2ed4bca042e96cfaf4660c9d35f3e67bafd4c99f9447e6dc408e0c4471 a42e255a066727597a54e8486ebcd3e2ddc2ff75e9462d84385cae8788a7f54fdc724708243d7afad1170717448d88e701f6867e48a3381a3a4948e03b11d0098701cee932c1ed149807fb685e38314c8cbacd2111b1ad9cf74070a05ac148b7 +00 00ce11677ca818537dbaeb880fc967dc8bead203a2538a55e756679c4a9e7975b9b3e6aba4e6c6eab4152d0c0939027e9b0bd92a b0a4a9acaaa5333fa912a3867ff04464a6fc252503eb7bb8c906ecd04329aeba8f87a1942322c5cc18f46d2db8aca72400238701e8b4f3a8ac6371c8259aadd709d7148dff0c3c8cae3fa6652379f0b4f195eebd252031fc966a9e3a840536b3 +00 005a239ae0f40d76d8d3589f1662b5ca12176a4b2784faa8339b54e96a1e1294433a4d83bf904196f939bd8b33bdb4be340ec703 95c3fa257127d90a0e1b2efa265521d5a853b47735d0281a36c72f6e999ae20ba59310500e3e1555f9726a54241088fa0da1faad8152ada2c001ef9a0c83ace7c2db93e5d8063588fdba2b1afd88d8c10eaa7f95629e6ba45409539cd721d2ba +00 00077390c62ac41aca995640fde0c79c76f4ea8a8dbb22323ed812bee837ab8798c5d0ba976c7aa634d4b1c2c155de2709e7352c b34c9cca4903d6e1cd9d77648fa99815b88a8ed11b7c7dd2379c580ab0f80b602cd8b91ae1f0bd8358766d42e3c134e10b09cdf6993abc5300ab6d85fcd0b35938edc62b35ec36e0ce2b068a6c86535425db0e8e9d5d2a1cbbfaaa833d9d3c54 +00 008bf23b09fbbed1b55769907aafb97f4759cec98649b2c9da5157517d4f85bb70157076b5e4aaa7a940af042302f8be06a84ab6 87644ced5c8a88e39d47c716d42e920d34130e51329ea8fcf57ac82a8059ea39ecca135f8eee69a7c498e64dc1c874e71328a8d520146b65f97ea02d6c4589568260322dd935363ebcfb530cdf636d87884c8eb218f85da1234135e6d133c96e +00 00082ad05d19b8e16f80e53a4cccf6869ab5128c5e622ed146fa8555985ccd2aa3b9957dd374586115d4d75b1c01cf98ecfc3646 b4c682d10dca01ef529f3e120a5afe6e1f13a2b8ec6a35578fdaae57a7a48c3f55ad0ef188f85f826cc1498a8f44276c0fab4a1510d0bb149c50bc264e27efccadac943731c92910856b77de66a6a00763e099bce53ab5881de78d6a6f651664 +00 00af7e581aa4f9be5815f0c447e39de00da9194eee5e5f609668b9b69930b5b48a948614c2250260d1917f0ebcb00ebda4bb52f8 aa8a20fdc15c8ff5e0b5dd8b4f811f14238a21ea4a1eebac598d4a0dc19d00aa4d690af5961286a104535a1c0242b3ce011db8f5de234d12d0cdc710c40f471d94d0a6de62ca129caa279f035398c2cebde0fbd92789b86d8f766f561bfb98c0 +00 006d14107b08354e6a41d7d7d50c004419db8bdc50db43428df5e86084551237223c498bce71a17e25695bc438c5c09e009c60e2 b70b56908327193142d987ac489a60f17d19105c38b5c2e5ef83303fc2d98865be02a3dfc30aa6fe71199d2e043467f90d6868c63f9e5a53b0b4b311e6f945a912175c9c39b304df3a5ecc17d6fc7bc1e495f6c886c1b81ac32bef6d8d62b12a +00 0099d96d2dc9c79549f031bd5346cf6a8544c312a3fbfc560dc8e378efdfe025b0e6e61e09c04c8bf4133396f993b0906c33dd30 a857d31fa60f7a1405a9853d56b2bdf042c76012877b6810105cbcaa4297903346264b6c293c2f7b08971715b97dfe1e140d86cb70af000932cdb4aebac6c67ff88ee9bb466b7b2c4888145164eacf4c781cae61fccf6582b46ddae6c6bc4e15 +00 0049f347dfd361a65910e97fcefbf60013a54837f2ae657d65e02397f59dc6bca27704fed3affdc3d833fdc621cc5e5f99b92a63 83a04b3c634807a68d3c13ab91b1e4561701e8e1adf9c40ee518c90b8570ae67e13c707ae7072ffa4aa882742c18b7e00fe6a1a6ce01f50574d6381bdec5f59ae4a60ca388ea5c2951ef6d444cefc4208ed134471e88119832b811d198cc94b7 +00 00dd226de602af4e9f8e25784bd1bbd4cadb0a8aef525d5e2d57b9f3555feb698765672c5099a7d6dd5faaded69d8d68b4804f26 89b5b4d429deda16fe75ac3baec5e74d9c5874e3faf2fb1e81cc26620bf55b3ab04add66c3806dcc1b92e7c5f161ae1d1364a5e156fe57294b625a84d728276a1bef706c498cc7e5d4cb50f99c18fa7609b91fc78c440e0b81f23f943b56160b +00 00b6fdbc9c8c76cb2b822a940d8675889ca6f5132429da795462381ce29313a23bc132976fbeb346ed4c691e651028f873ce7971 9970eade992a026c852d259887d3a0948f51b5e3b24bed2cdcdea0b2a92c8a980d746c072291076c13fa60084d1abcfd0aaab31e8014a6d9062083c4f7d4f7a7fa16c5e65b2474ef400d60a181b5ee9fdd6a018b063cb5bb34d54f3cef839861 +00 00203d77fac64591eb9a18de20a9d5eacaa1c3ec58a5ecdb3008c2d642e197141d16b3a9fdffe61429264f5b420f5e9926659a4c 83214f75a5de8250b8fa3a7270570ea1e97f64e9b0c5eb8dfa0b9834fb08c5ae51fb77094fc801f7b0f2276ae3704ce8097e302705dafc2aebb926be10effb33945c9ec2802873e818dc54f49c2b3f55f2fd1c90e39e8b5b080d416f0a6dd22d +00 0057a2e6a59d4871c3d547690237dd9846d6d5dc4ec0678aafc9c8669af8a641eed67bfea4b05fd6b3b5357ec4d0caf352691ea4 99b2255fddeea9e9b14c1c1230cc5b4b25e40391e64527c564df952698c61958dba5aa8b2fcf7d9b2d75d0b51c4c966f094c9837abba4466d6fcf474f43513bf47b934d6b8f8573ff1be1dbeb8115c90ed687411123f587d05fa017937133b70 +00 000a3da7a6633608fcee9ce4253bbcec08d41ee6b00178ceb017de74e24d48fd89107c9f2db3556063abe3cb011938f4b4871795 a86c74cd141245e8bf5f6ed8a65723485d2dcec6918be06950f1b2af9ebb87426fb053b2951fc0ba27f6f323ee7e091d0430483a5ac782a7b61981e284772308a126fa46a6d68e0c333842ddbe0bccd9615bb7a9ee11f905a11c31eecde1555c +00 00384723c8b4a316b450d1fce0b2645912b8acaeb3cad50860cca43bdc0206ed5b3b60ebdc29b3eda305d0d60eeaec261edc24d5 917264ce56b27364e531de42f4949306dea65938b75db67738ca1f665aac97b0c396cef37429bdb9031be136fed133f7128ff6c66359d78d9a29292e0becfb5b58a0ba70e52e73b211ba526f0e8fa5d9eefea31655b6acb1263904de5cdb023d +00 00bd3136647572fef3de51b12e64b36460bd3a27dc660c164fc705417339cab21f9e1f9be0f3da926df459c5ba58b701d306e67a a9c1f1d0e47aa6eeda6dd8fb318decbe6f2da01d3fe08db91424f88e7f75d5115834f157e50ada351f56b5eed926fd8c032730556e6b84a2408d5e06642ed71faab11536ef1da4e24470ef256d9f207e3f6f3d99b2b77704e9f096b6de81f036 +00 00495be0b0a9d357f6155fac008cec90442200bb842d89292fde38b7256e4117284a60249b3101b3f19f778b680c0d1d7422b84a a3cce8bb1f27c8543f1d9f5b6b178f1fdfc0564430814c66ba9c7494725e621b97a581c5004828494a088dfc07dd93d91913ea15a6751a95d3d922d8d03ccc30b1a8f0e48fb5cf3247f06f69c71a154d03ee0c6f8c04b20a557c1db048d5910c +00 0079626354dfc4eeeb51fcf232ee9e6b0130c9bd40f15ed45606bb7faeca8f359e0c3e18bf12769254522fd4077eb24bd5454871 aa1030c086350e2fbbed6f2f2cb03dce7ec830d74e47729b92aac515cca35339c548066c2184019a646c28d47a37829d18b711145010250a878d5cdb9297ce352cd3dd39d345fcf4bb036094c45e9a0e697adaa6396edc0a976a1ce7319e98af +00 00ab42bc7d0e3c23f8bcf928e25f9f027b56f270398a1d37bea0ee5426b944a9c9ba6d0d7796899543feedb470f70b2ab148234f 89da3adf5e19a9443dbea344c954fa0aec7c1232c3ecb3214612ec436b719f6f31989ac99539380b046fd73920024b2e14f0c72e73f07bad02b1c5f2f621c06d1128ac32234717bc1c6d9818ca3ca1d1e1cc59d8c97e04627ef0145d34e71d00 +00 007f7aa2216164ba689459ee5d5ca29e70ef75a5b2a4416ab588df1dcb9164330c0b405a9d80c3acc41c19f58e24e17ecbc0fa7b 8dfafac960d088f208f94cd1ccd90110ca8f0b941c8e57b63907b8c70d90195bd66cb884d1dd24b8ff75c6521ca1e2c611e1d30d947b9b4ac177bfb79f1c1901108e6f009ef9688a053cb910215b81bf56ff7635e36d1da1d2e403c4861d6b5f +00 0021d84f070c6823a70f1a74225a472118c93ce9dc509aa6064051ca4574939dcfa96be862069424bdf1a23f62f2868326422e64 8e2bc8c53ba7738ce99d221e1a4c036503dfc17aa14a88fd0187e02e2f20130e65ff8118a81f9c2a2ab5748e92f8c43e0396cad8bc8fb2c137e2b82ce492b1d2d0502c07f504e6ba3d0e3d3ca6b9ce109fe48d37c648c9470c485027b2b573cb +00 00b6645344d17528968c719091b6e2072388881dc10bdb4c7fbf41906cadf3699b30f9c1dbfb4796d009480664e6276c0359e5db b1890e1f991e724f83bb52ccb890665e2b13b93f33230d8d7656b6759364cb91a3046db44a2451556ee3925706f50761091bb5a402a34e9fdb30b9bec5f788b55c6e7f5d5f7f9915de0c522018f70537b27afd097e7cdaa898016a77a7f00c8f +00 00f8c2f770cf5f8e1f900e996ecdcd84fcff5cd959777fd005d721a419123221a3237e39834b270d37752470deaa6cea023c5058 9129063b1749978eaf0b76075e09efe1ae66579bb00d68f9c69342e48dc4b7ade2e3dfc07cbca7cdcafe63ddc0ae094e0133d9e16df13b20253cf34eb39ba567ae12b296127ed7fae00da1507ad4c329bcc702661f984366bc51eca6d4ecc97e +00 00144adae951fe897d5812ee4a16c0be4c86c5e57e615c398f5768a1223a9be20fa82ceccf8a16a31432bbfd17e594a4cd8a6a07 8da15d3676065a5ec9d719f4c8b50ec38459edb0f78a00bd7ebcc323db6e83a42c0f0b87acfc84a3116b57c016151c9b15e113594581f67755288075bc4287252386b9ea7354f0db5fca6420608a1ac1604105110f2661694da05af9f69a6bfc +00 00a51f065fb32c55bf4ff6f18ba9d488d35d9f8da593adb0ab1632533284e0adc43ccdbda9d9507b9862ac63b5ae7b0f78b479bb b13abafad59160b774cd3588931d54a9f0218b961b32defd272bf7a15b9a4755344ed6b6f285cdd9a01538aa94af068901a3c336cf24c22d9786a2723770fdb5acb0e14fa3f46d72db5830422996ae89b848a412e187892acd8ad466acf7b4b0 +00 0095351c0bc07acfabe6477fe85f97eab520dc96bdd58b44b036328ceadaa56a1904d2217c5fd25155ff2aaf9005a3e2687fec81 af50cf5cb84e0b4d6eec000e6fd80e3dffff5f62a5c1e05d2e69b712eec213d045b752d4aff7509d0a105b29c43227340b3c7535cb776e219d6eaadbe3de451f7a00c89c7b4ed6108cc9b6a09f4bc94379592254b260188aa18781d15905c305 +00 0050245c1682344fef23bd549ac8d1e8e44b2840c43eec1cecd33daa4e9ef6b53f496104d7432e14248682cfd6f5b4853b65adac 917217aa75a739a37be5b334b12c4a6adcec9c30530515848281b4ac7cb79cdcfa525034a812798b5a84b188b4cce8cc199b824e8499514ea3f6da6bc4594c27689d03590c6e85347618d45487c4d33bfd1f3252ab6506f0783e631b0f247c55 +00 008d3b0277f0e9fe54581d3a9499ccd7f015c08339591326859af969d2a26284e3b3beac4a0b74d324ce5cb5f38c7995e4e3a41f b1526e50ff3caf848e3ee874bb85db958b8358543dfa2b1748d5b69258b5ba9e140d6f8d23b6fd282a0e567882c26c670f4e8fbf05d8dabfff9bdd76ad93bac9c507f600e1da54783752af234523f422c1cb64cd7b46b185cb6acba3cb25ed94 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B571 b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B571 new file mode 100644 index 000000000000..68c31746ff79 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B571 @@ -0,0 +1,60 @@ +00 00f42afce7f7b3d45f3f925ab29fc3882a89c9f585177887584703cf8bd8fc572e677adfa55b402446fe1e90dc855358d92c3267c35be9674b40c2ad5ce8dbe6a533c44b0ad8d2b2 93b029e705fc05a444a3f61255fcbdb2f49c6d521d6456e8b0b730bf5096800dfd52775773067223270d7a44d30639b812406214eab3d1c3ceee5077617a2413ea7c653e76103695f41d66d91994e4d6ac2827ab4f94ce61c9fffd09b21f6a06 +00 02f36613043cbf53ad36e2b38998bb867503359ae082d07d040e5a10a43e06ba9c91e7c73308e41e2391b65e634f83b162cbdf4e7a44ad818fb93a978af00f06be06731d8c5886c6 b9cd522e4808609d5036dec4534740627657d4b6fc416417fbb8a8f5b1d20a5b5cc90468d5944360d85564111830914513e030c6020abff1d6f917241308320caaaf3925ab0b29bdd66cfd19e8335d95a5467e898872f29d1fff1039f09a1815 +00 02e74948c46930cbcd9dbe2325539c7dfdd910f309fd610e6599d425aad9ae230a8d4681970a14f2a71fd08030d0a40ff40dade7de1b06a80441bbf7e2fcf1809cff39c7ef88bf9f 8f51ac09ac2156a63d4154bcb1c1f22033c3dd177d35ee0d5830021aba7f7f5dc6db4ad27bc2fd5d789852d199e835db0889d362ebde205ed2e90e31acf49e0479e80d61da2472af65b9074f14fd63d771cc501460ca5f30484363033aa2af8b +00 01b5fab1d36f6f6d559f65d8b01edba610620fc3a38307b1fb1c5bd63e7ffbd4a9098cb8bdf50975a873f5d047ee2b627b090897a7fb5f56d3f4a0f3528179e7c969926fc0d3b0e5 a47a38406a278280497bff44609efa4a167dd27454d400307a5c67a0cdb4f8a7dc355b448ed18e73cc158dda4b6168c703f6957a124ca2dbe0820650c20ee7cc61b4c9d62f47410a85f194361fb12048c369dedb118ea314ee0478fcf01e3aa3 +00 0383e70c71b431eedd4574f65d01fb0304f7744d668408c847f7899eae44770a7f3243109740f177d7146a27748886b7b77ecf3792b512e8d8e37c3bf4ecef2b1253df7066498f01 b4292288c2ba53718b50de4268baa73d3458c1f043af9ee062a1e7f742bb3d54b574e7f3db10f52c01ac48b2aecfd50e18bfaafca0fd58aac15f4923eca508d9daceb4ee242e29472d2414cee7f0f0b72795ecff0f252fb2e65878e916573b8e +00 002261d4ead21f02fab19bbb0da8c272286704c8f0c6842ba47ded121e5cddef79fb34e6b9694f725ca502949faecfb21e3cc062a2b4c654bd542d9a1fe8d97bdd0905c510aa0999 a18bf283239ad1c1d434d96f7d4802bc99b17472fcb50f6ef198e318f2bed05a3154bf8c67e1235d9cac5d0cd4f98f470361cd57a0e01d47daafd612c3aa888f322c017eac2615b499756f8162ab9595b198fe40a9363c3a114c364c39ededaf +00 0316c78f289e1860bb623082be9d9238b88e38c5e978a868bb90f776235bdff4eff591877b7f350cf14c40356922b2b6aa51d64990360b2b0e44d6941b5dd9492b4f4e1f42ca163a 87f7684532e3f7e26b35267e4d628283adc0283c48065c4754e5dc3d92c0942fe03e4027d36daf8a8928bb890f22b9d300924495f47c81f8b2148cf7b2b3f02d25840c5d7951f7968013e3738d3fb28090064ac457eac1054d83801e80935cac +00 02c1bc13f8320d97a82f3d9354e195481902214e16a4fd89332a0499208e91d50e5cabeb4927ba030cb42f5bc53b10f500fa646a8c88508cb0d63ebfce5c4bd574c527d686c735ce 8fd05ecef8f59a471ec51f1902d758814e677e25bb92b43096386533be04868e91feed319273a6d428538dd2f88d592e0c70ff52badb655667a6fef856840d9767c7bc01da1938d42645424cfcd4f1389f198e84c98ed6edbf09af0e257880cd +00 013bd80eafa67663e75d7ae139bf285d2b9f1e03d8e32153c73e26d06e86d7acad22bde9f121a3f1ea674dcc1fe67bc7f5398d5e92555056bc046a02b0ba86c2a0dfe32e91add5b6 85cce47435c0bb63a71f216c5c2e44430c0b94f2d33630b88d9683657c4a811708654eb256eb0dfc6ae627d965fd3ce21663ae5091f2caec8795861a11fc106b118e13e2292058f072c6f236fe880b7fd998e8267fa894ce99d9dd5180c01756 +00 030834b0a4284097cdda2ada6947c6c281f7290a49b56becefea1e2788ea3ef78fb96807633c47c25138341768b241164ce0d42f7301728b928be2c047f2eb60fc2f844ab77306d2 ad706c7a22200a8e17cebb58a5728d00dcdb5a22566d6b4755a8ebbceb3da0807d10fd87353f6ec434bf7c8b4c2b362203252421eda5600dbbaaa6837b5f942c4709d9a0360ad57d6a539d7e7e99b4e8c036f933ddf192356c07690853de8874 +00 00c81a79ced1eaaafc31b69a40d9939f4e484d625db6364a8e589b6b4d336d458b44287ea6c6aa7661113fc07806b147ff98216fa0c08708dc9d651821b922741deda522b4e436ad b346d28931712a3286eecbeb5664841bab48d44383cce99894b3bad76738327fa66af7f7c573ea8efbd141114314d6e108bd30e762ea4b89ff4d2effb4d6e828cf972bc0d4053489692dcf5c68c9aeb44bded6bc8a33be15d41c8844c96a2d0e +00 02f24670c0f77d2ca0266a743023d2c7413d56d0b5ec77b454ac59087efc4ea4d46179e10278e4ba416ffd8c3f9786ed202faf8251c0ef5a9ea5371fbb35b7afe3d15a9cb4bad975 8f1820519daf282bce9ed79776953dc23ccda8c3d56e886299473dd39ef03dc47c9274b89d2bbb9ec2e0b95940f6cc8f0b52b6dfded66ae9af2bbaea8b90eed6b31deb7e5decaac47fac0f9125eb12bc35565696f3a51b98218bfc88c30c3778 +00 020985f2c6fe3ea04bdbab66a8b6167e5969c073b9d53cf3c77cebbf73f4dbf75e601620ec9c3107bf3fbfc6c79f8f063409bf8fe1d14b19e323d857e23dc05157d270c7514137e4 88def66ba66d6b5ce5a0e68b02ee4357edb559c76fd74e47e49a608151bc060ff5326e093c2ab06ca21630a47e2b970e04d1e7317e278606e965171578515823c8ec665bd4824bd960fd5505244824047d615bb255e6d63177c007554f877411 +00 02b3d641607b8a141f876f6d285ee46aea543880e772dadd5dd83d595b9643191d9597218e1d6adb081df133304037bcd2c05c24a54e6c4cca64fb2cc4569d6882315360059496d8 a9b6e6325de1c9984a9a4e6bd8010b14e65de9f0f559aa036615dd35c24ce2e2deac7f549635a22f01dc4d4dd9b397ee06231fd5af51dc46015116ab1a473e419ef7c0f70e9535f99a3607fee5a02f3b222b977348edd196519681986c9c8e37 +00 01afeb5ca87c81025ddf09c2b2c5ee22ba0105c0e619b67a324467485bd839030d149fee44d8bac6f5902a1245a50c3437046b7c89a84116b2147cddc645b6d2fd24d68e8d53bf5b 86ad02b6c9c19c07cd510d800924bba429440a0d602a31cd468b3ba012a4ad8cae046add3bbfa12ea46d1060c0e335ce0dee6fc79193145977bb719c5597b739013f1abf65aa3c0247814357b7e543a5ae785b208667c8461b3eeec55d412bde +00 032c97639b69c7cdbf419286d0a1b406d9b1f2886521a8b979a36118d2a368aace5b02dd8c515f2041e6fb9f026d1e82e789dc826a56d2ef732b1bb0f49be2b696ab5d3d5694a2de 9366b01772debf490e4740760cbd23ec01856ec9b370abeda1c33df7723eae6e24db0e793d208c8cd647cf514009542406fd5555f1230c76786b06c3bb1a47a371495c00e9c4321177a1108fef65f64fd2995b3b9a34a1a6da9e0ae80580536f +00 00f93672159276c5a293582b9f49607bbdb970112f6c63b2b3b5d32ad3c8240c86b1af13a8dff6502c6b6a17712cfd988f8cd23a60693d64104143b3f91adb37f852e9e11a0ef110 b346d76376ee6ddb2a8e5d79383a9987ab3a97a302e9b23cace9167a37875e9c249b4721dfad552ded22cf258f7318ab0a67329566c4eba220086a5703ec9f0be67be6030826960a374180431f3e0ca8cb47ce3baf8830ca7f6eaa8b75ac5631 +00 03db080bc99c5fe7e06d5032167af56783cb423fae59fb5b3c6bce5fbedf56b7b39b17810e48ea9a172881aa1f42f5e267349b60294d4a208b4437666b44abcfee5a1829e9467908 84473822050720174180d50d5ab14a5cfbb29342d0be6f257361dc5dc97f8dab73f46ba6d2cd448031d642f66da6701d13fb0daec3d14d59af0bb2ca257e486589c741fd7fad2ad0251ef5b9dd20e2570321b056989f395d975c7820b87c61a5 +00 006ee767f6f36bb8f364f324d8346455c899a49237d759003dd52cfa13b9baa4c71347b134b24ecaee32d247c34e3787a0c64bc5d299b55c86f64b47521d22f2c09db225b0c84cc6 aab63b7ffbed2f738e010bcf79ca58702b6f4c0f6adb89e72d5af80354ba6f6165471343e4315bf3a876ed3721f1b96003e71538b24cbe7d236311d585b925ade04afba6058602ed5a75c059977e28435054a43ebbb3f4aa2742e017e9d8a66f +00 038e2571d9f22309a636586d62863ed67a70538287f3ef88b88c3c2fa1a2900d48c342b6f15c26b8e7fb4875cda4093b7de7ceda48fe1e2cc2975afe958040881de61f309931e48d 87d159d9ffb09a13d0d8680b799e7cae9329a6763770bdfa955eed97780296e1159b4cd4851914d40aa81b0c59db7744143d2d799671dd21320ad21eaa0ee8f098972c163ee9a0c7d789649a45d742ab159b4df3d70d15eb36bd18b8dfd4b190 +00 00c8f5736f1ae65592f3ca850f43d06441aaad8c03820f3b08d8a6db46488dcfb828459f8b3f34af73cce8dc7a5e3834e085a64523d890028e194214cef4003210e6eb530005b01a 8baaeb3bb4abe53aecbdbf1a10c0b7099f7672368fa72ade897b5bfec95f92aa775e254e6e1dbea7179644c13555fa1814d2bc896f03e98f3e9788237de83f492f2c3accc703c779ba8558e699f7a7c21024997e4eda7d113254bd9aaecb78a3 +00 01ee68c3994adaaa9e0d61bfcd3bc1cdf198d3fbfe28a44e5dd518867ea04b20e795eadacc48bfcf8e8216dceeaa069b756e8e99ed87b6b1d31154cc9310bc3b4555162a890b0c6c af019aeece45364b18823a78798a42bea9fdc82eef472f1fa1365ab65955eedd2d803a9e463dc97b1d3515cd4c8889f6115133a8b84e96d14831e3e90ef30b292f1401b353d9773138cf1e4c412f7fde9a4a5ef5cb576fabad21d14945d59292 +00 03a6fbf66ebc1365ea7699c72cdac2dd85907ec59cd26e2d18713354b619ccb83b7fc0db9193aa8493c1855f1a83fd987cbbb65de17c59fbe79256aa5392f4eba045346e9ba26592 8b12394295a2a85cff46db8124a902ff91387a677e17965c242eabcacee499efcced5b4326777d7180d16e2559e139c40b89934939bbf55a589379b3cd1dca73e6ab96848d22029f0cef6b785c5cd5b69262958f0448dc8b0a69e6461e7afd99 +00 0145748871a0b5c1cee628de04a12fd68ff2b154fda96e47afaa96389d66d22802968584f6753d36618d49ed205260f09d3f5ccc2b27a34390ce58179b9834ff92a86d66ea0a97ca 980dd84407e897bd7d17d0e37ad6b20a845a2c408a198f2b1d0c36f437ad01a315b37b7178ebfd85ac3169499c3fec4011b886c499e9cf7f7ae79356ae4a52ec3f4817f5fee669099ba58aff0da3687b653c7fd7a93b523813cfa54160278e35 +00 03c71911d24ad19c20fc1d8a044d63c9bb417abc3778d7e6234c6af79b898cbfc2f2787244708d2fe203be786edbdc4c9b12b413156b7b0bab0be8af895d191d853cd58aafe1ccce 877df9b3af737d61bf2ee4217fadf3b9e4025e9e763c26edc7f1c43e899736da228782ed9dfaf598c200222bb5b583d5005edf2dddf3421a97a561a8eec67110a02611b63fcef234ca4a11af760cca1dbac899c0f64efa7e99bf181483d49f28 +00 018bd74698bac36ef11add6b3e3fad227ecd868f370ec04569462565d2f0af2340bf793486953a7b79ab04f0ab1f0e4fd16bf6b576cce677d543e73aa8edb0e50372f24ddfbff966 82ce0ed9d346a5f0143fdba623e8987df038cefb758bed793632ee5cfc0b50a5518485effdd77589d96ff2e2c9c5966f01de4aec07859bae41321a67d8738d64b6275e639fef8b1e2daf4a556a25b8a3590d99a3bef1b895458c5f9631c0cf05 +00 0335699bfd058ee2e6163f55d1816bf3669acea8b73be9c4ddfe775230925e6093cff7a66813adf22222c8376faa106d85ac9f3c67929bc58d8986795b6d35d5b9fa546dceabbedc b1e21a0e4032d6f9e33fee0d06974270294e917798e3ada18cb287a857de40e4bdaee4e79ede0f1cf658cdab893aed8014af7e77a7c344843226408198fc6a6a8372b74794442a355b85cec538dbcd3d3d2071b327d443f3790f317c0df42c02 +00 02c3eaf801330b3f1b0504f2399f1d24455db29911f750c246ba0a134c3b59da8b3562911197764699a92ea1d95a2aac587e24f743df1dad3e1cf7edf955203e24a0225717f8d2df 963e9e810c7f4fa7e087a627bb678731dd388111f758b2e8cc0c5c20f159a67ac99c891484da997a885d70fad8e0e73108f712fbebdfb5fc9fc321fc09d45de6b69505aa8ffc5e63dcaa6a280fa4f39b6be462f1226b22e36d0c857b890d55d5 +00 01c3ff067497e5d387f31f0ecc9c67b3c0dd6ec8c81318c492aad83c9dec6c99e4fa47447f6f7082d636c2591d0df940b947d0a4ae3778e2b7cc8fb92214638399def894ada276b8 a95eeb0d0b8936670388474733e8e1b25b813d8724000c0ea538c7f0cb412492bce5e454b61efed40a7c4d150a280399152f07398e6586c3de4893bc0a72ce6b5ddc7bd951f2ea62ce1a13a99f084fb4be66f1014c5851b9c303017e4ba5e094 +00 004b4e04281b210fe78d516a5b69f878b7fa058941ee9ae8cc63b061d1eb9e12c3e0ecb8717ff4623ff5bbbcdb53c48adbd9c69636506ab929c5507d7ebafae5654aad65a263e48d a821293938aff49c8a9552bce86c563b52b7b2c2df372fa0640fc1bfd01ff8938cccbf07134765f45f7308e869d805f719008e55d0649ea8a0ff56e3c33f9687349bbc603815de5f0f5a2a3ebec994d35e489e26fa9699db32becc5a2209e07a +00 030f2849a713aeac95fde5ce3af853e9d070ee60709eccf35a076567be2c43f0fa34420b0fc097ff577221275a3a56e759efc32183be2d76058a7d20e5dd59f00415114d73a15b8f 9716534909c9ed701c538e94a64000cead9ffe880f8f71e87f874734f6f7f9717ad0745cf607c179aa5065df4d78090a041b9a7c8d901575839fd15848995315a2c8af9eb06d2908468549e4cf28c78ccd62d84c40b591a71a759596b5e26f36 +00 02ebb73d04e6e5361e20629e3ad119b33db5163ed91fd9a8aec4b774898784b6822a08992118a8fe6013094bad0be1e9bf01b27c069e4335bff7e0abd28a10443818f6b825e9cef1 80be3226aa28469198765dc02510d4a72a33a2059a51dd7a690810a07e5e02e793b2f7f443532b5ea7275a7f52e8c549096593138145896e086654ca8d2582af74c7956d4b7e12001fe70c1c11cbc73599102e50673db64b3d9f4d416b68d093 +00 01bfab717d6f6e16d9bc6e89d2ffac7cbe0f808cc8ca2eb515af7ecce5f3b230303775710a21bd25c2cc4566bb53c78c78e3774a9f306c751cc6e149929e45eef60f56c1d2388c6d 812bad48768ae17a3a01c252ff9f33ac9f19e57eefe131d3f35b0743633088b3a3b6d075db19de212ee7c052e1b305aa091f4d759c35ed7f035597b524a5d5beaccee3fc00644fbd719b09f13a829db5ed558c2063fd3a486301fa0d147ca018 +00 000cc53bf7f1cad5e3dede4b4f4b082831604c92dd2b147869cdf1107259305b1d50359647f9f3d7d4e1e608865c65dc7c9ea46bc324dcb8423b554dc369d621743cbfb592b70eb5 b86e2e1f1fdb35627f75496c84c4ba1f2b8be015c4b33a06e752fadbc82581230a16deb4caf8f58f0854be02a9d2c6a201231afe8f5b80f0cb85d0b0ad12e5cc4b787e499c81e8ba780488cbcd9a1072bd7a9010dc00ba8bc7ac0af596cd5362 +00 02b009530cb9d586e35dd8951ccb686833afb7a37ec253e547e85b253ba999f0f186b6d4ba41091615fe57678e9801b4dc94fa683511da25637b2acc9fe60936be15af16234c4ee7 87b94e4f92ca04bd392deb4f87ce76f19ddd13ec52e2ea9ed1e9704618ba06b7d5b6bda5e98e19b332029cbc23cc7d2302cfcf3d6f35051e0711a3105039c62c1317185b9b1c3e330b0016cc293f41756079b846f8e9d856f4a29dcb76cceb41 +00 02cc2d0d7189cc8fb3565a039aee7633ddc00ff427cafad32fd2010b10fe249c9724d91785e7080203626038109158e3a61a3970aa3e51688aa7f5184b22f63af63f80d3540ec023 a9b7051ea78993a300fcbccbc0e52c40f213da04741f6e6bc799e0d2d3f73ff022a751ddd78ba19dc73295fcdb307fcf14a4149016089f906c96298fed2ff66765c8743c3917ddd2e7423ae5e70609c71726ed5a3ee5f2cf32d437a896ab411f +00 03d8936c00c131e38c6566d2464c4e207c878070bbf681695a6cd98cab2c6e80fe98cda80c66a5cf584e90a071144dda59c07b8fc7bb42464dbee5b6f739b0f2ee5fdff7e5a4e7cf 8d25a7d1bbfd20daaca3430e7ebcbe9381e6574c87e8b38b012d4b4fe594111b3e586518de6cbcb6e016bcd6414fba2003c17d3ce3bc9fa4a3f3f581095d7cb51afffa90a6f3e05f68c059168f55f3c89910f118ba01c09a5fac438700a5c59e +00 03dc7de970bce28a943d7599f2a9010fc99435b93bc4ba884d42503ac2941aa63fd07db34bcbb1127d56d6a4e277d6ca32051ea3467e376f74f98c3999d2f276b282ef8a28cf0cbc 83113f1378946251e50d737df7fcfcda89bdbd860aeed84c2fa719665116ebcc4d75c41becd24ed41e75ac719586b9061189269d6509e2a6e8b7f6cd097e8d57543e0655d89dfa74c7ea51d9d693442c14cfff6e28186228cf36e8b6c9f757a6 +00 02de6ee12eefa7a4a736484b19b42a513dfc059a060976edc3b0aa4b50e98d72df6506fed0499ff8480986748e938289e54a5e86c0c29733a9bcf5985aa63d8a2b57933a04a8e8e0 a1f329302342d324515099004d13fd0dcc44ac835305fc3fffa1864e3a4f9b5e102e021c990e334ee1034c98e38abbd20cfa9c1df6cf15ddd894bf2e56f71a8f85482939ba6a567078aa57f0b1daad5290c52ebe7ff510e0c5f57d64bf8a0f56 +00 005468f0df2c9854f5f655743e79c750fd8812db28b096d97207bae7f5aafc6b6090c9c636ead9e0fde32a1ff8d539b53813733ca812b41b58ff85a941abe4f128d59fdf9847baa4 a3f786af3df916494f5eef9b0b36a993da54fa3f1e786923f9244a78cde7f717e95503528381ece7f80f4f36a66cda6319c371a72a3d3408373e6ee0d2b66ffda4a438892f4aca2cafbfd91c5d0127170a86e3bb62deda225a553c33fb81dfc7 +00 03d3c6a7ab9450c94aa3b8a1ffb678e5b647af24cbfd66ee3944e6f264f406295b803767471fc67936fdfed1714b4b8761a07eec86543b7c4da6bd2fcb33fa8cda4077737f398e18 b3c52a46da72edbd3c2685643508f775acdba2d306feea5ffdc5c411186211e0cd5b23330584a08bbe22a04acd181b8516db7089f61b5156800b554e3371ca72ce107c68c03444e746f27ec6f459cda4959658cb1d327151379e6055d95e2039 +00 001ce010ea8e6e1a0c26ab22eb90f0700dc73b232c429d36371e68e429792afb7223f10327708bcff779ea55fb5f22ad87aa054e84d10f5450f1bc9a89279062ea2173f55ab0f76c 97904773567fdd7fc2daa6f05dbcf25757f58f6b4609a45938e13311ea2650b8eb117158b21541083e8ca7715532c162168a7195954665914729e36d447ec30fd16feb48c3d53fb7a38f774dd0183fbb3c8f389a7db87059acddffd619f470ac +00 01e7410d012aeef02b3723346d24ebafd684c99087ecccaea1cf3735d52c4c81dda41812c09f1e874dc964d858ca240a19963d5dc89451f5dd6764426ae41cb23f19cbfdca0fc562 81b87cc44cdbea34d9b890345795335baf5f4ac650f5d1754dc58af0e45a13582ddc7b6544d0fac5b1a20fbd4c490ec40942dfe5e9e87eac7b3c5ae7b004e3a5bb77992e923362608258004df5c08135c8ade04d911c43379be659212c6fa582 +00 02139839ce38eb879d266065dde5e5ea227244323b330e3ad5a0bc690f3c210f794cf18f0d730693887548bfbc434f48ee10ed34cb41d52172b06e448df938170a5e17311cab8e88 93ead86e2aad1854818ae204e4fd2ce90f892ad832153a073db1ae8a74674ac7d77b16707e9e1d460138faceece8f4a5158c775f0532c959ff187329803052878deb36485f7a8627c864e9eb24ddbf2fcae484a054df967a116ff84c382056d0 +00 0274f70fe69e4dbb55c5d404e39f5196335047113087f8711f2f67f2be4964e4fbcb865680758df1c401cd677b0971654b7a6aeb7bee0d6d80ac0de14d4f46f356b2d5545c185aa6 80af6d593ea01dbb6c81d6a6854406aa7f794d7bbfc2500aca32af97c4f92bb83ddf0c5c2bae03d93d6cb7a59b7465c7139cae7a7c24be627a9796587661dccf072dd34814313fabc2035fdfd27ad8edcb615fc9319bca251dddb123d154ae0f +00 003e1b03ffca4399d5b439fac8f87a5cb06930f00d304193d7daf83d5947d0c1e293f74aef8e56849f16147133c37a6b3d1b1883e5d61d6b871ea036c5291d9a74541f28878cb986 8c8ce77037aaa11075f061abfbb9936483f9a5c24b67747449554175c7f17b0fca923a39a18301a2b07f6969a79a412601882a601e066081c6484205903cc335e51aeecd013db98d7f68e486259abcacc5a632fc4f617df6e4d92d61b55b726e +00 02e09ffd8b434bb7f67d1d3ccf482164f1653c6e4ec64dec2517aa21b7a93b2b21ea1eebb54734882f29303e489f02e3b741a87287e2dcdf3858eb6d2ec668f8b5b26f442ce513a2 94582758e1bd535ff4ba03ee063ce90cf0607305d56170e4b8cba5422c23acb168251aa79be6bf5e6df40a675a085aaf047948d23bd88d37f7a0518bdb5af22fd750a4497bf4c60d634eb4d7fbae5dcf9ba67fd504ec61b1a7d7a3af9104f803 +00 02a69bc1df069c6e89722521a63675f318252be629e7558f3716917998e660ac960b0b750562846fe6c12ef492951e51e224754bab84a6eacd4147a5f26ae85ee4381bb14ec2a8c7 89afdcdf6aee32d157f3f98d4cbb2aff3199029981a64262bb822deb95972c4e69ffc172d5683b870cac17a97c92b2e6184d91ee5b146a77b2c48b063d795c7381ff5ebc5d396fbaf7bbb4642c39287363e6132aa3838c8a21c39cbaab0a083b +00 00d11ed1b78b22b3420df4ddc4acc7c2286d9569dd6dd88e0fa3ecae69bcced68bb81bbb4ca6e9b54e67856e7fdf39155aa27aecb9cc827ccb9cdcf9ac633561b27d8eebfc261aee 8bb4af062b0df75d37badaced689c7c08c23671139154e16d45ff6270b5afae9877414eec30bbcb9af94e35f6e0b2cef01d2c19bf09b41567edb9c3a777879510e01180d3aa19c0138669f96976dcf39da6922e28cf1588ee51bf21d1ea76428 +00 02c36ef754b5bd065e9eadde684750acc52795be80f54dd3d7a7d743d968a18f7e404bd71f8a76eb0395f396df5a7c2ff7e0ab6de35df34282fda6ee01fe5b9b68ecb4e378dbe32e b3a67e80431c49191eb85c4cd858761d468083eee2c3f172809e21602e04d3f4b6ae45dab55674e0019ecf418b95983e191d5ef9546a3284143a5f2f25a7ed721f0d82c1fc6e95b4a29ec93cebf86b1eec135d9b94a48394518deb20b27f9a99 +00 019ffee50be5496507e3ef5c40ee88a49625e46d1dd1686a52b09ad4a8e3ee9ef364f953bfcd97c52104eecb6138067192997cd4ebadaccb73c7b2560879289a46353a756b73cc43 986b75a93d60c63e06c0114ef376729907ea8291585c22e0880acc37a4fdd8569ab7a77ac71001818dceae2f7d2e7b6703e2fc63c091b924dc6e61b60a744a5b3f3566f1ae9a6d10298801f7b43398b7548b50825d828ad6675ef488a9a1d2c4 +00 03129e96fd28c4198cc5242c1e3531a3979fae643d527044e98d7721aa56b5b4b45dfddfa17a4115e10a2b4f46d92f81cbdd7e86e588a4c6d8c2b3a83f54cebcee1d1dd33e85d81a 897414af522e17574b8e8d47181783e6cf24005feeb2cb56506bea7627f1652ff81e8c8237a62e8d7f02262db2fd90991132e751f77d0b4dea49324c89f92d1da43c3eebc1277de021e372680f7e95b149069093ac9d96a2d043cf1f4391a736 +00 03d723d2697cd07dd8444f992f2ab4a063db334034c25ea9be99fd7a1f495e3a644e5ea033a41264e0d24a911e55741d0cab80a0bd678eaec2bd1e60424d4491eb86d664900d907e a1edd7cff46773da349d2f9b3efa6ef75700a803a226bc3ad20b2b3be9c4c8d80eaa197162f05452c52a750e45e5e777026f4d42757a4471c0d81512dbb3ca687d12d12fd46deb8aca543a779372b892fd211d443cd2a21660bb68e5dc2bbe0e +00 01999ab45d66cd1d3a0fe6aa43bf5ef1e2a67637d53674f6fbbfb9b582be91fc42a12cdcad94b50b0fc7ac55030de24a0b99fbc4314fa743ef4b5198bcc5f54d8b669fbed78e2e91 923980fc98dc5317dd01ce953337448aca18c6233cdb821ce288ea896969bd8365190b6597f7a10a60e8d3e189a7f2e6035ed7d2e1f4ee4fcf43f3c709f0440dc9104eec1d8265ec563fb389fb07ca0b9663889076f768944f40d747d3b48a77 +00 02ce1cae0716205330d730e6bc6dbfb6b951dc83ee3b4a7dae75d057e32e8a46e22be75b5f09135452b29c34dfe81a9be2e8dcd243fbd946a0ed14a832a7802e20cfe1abfd3d6e4b 8d611282f502fe0659a0f3f20b8bedff585e92c9c2f48fc9894a5ba6b04d05ae8ed4a3504bfd554187d3c4f221c45b8e1055da7da20454514b83fa71791e1e052027894f4f1638a208266beb3d1d174731721ada79788ecdd29ea0628f351685 +00 02c9d0fcfcee7e75c3245ba955ae04188b1033c55ec9c821d8de7685276bda3e9a93c3ae1b003e5ea722913e7b169d67b1aa2dc8cd42adbd9368672a3f81a6817bf3e5529dcb0c8b b4d239468266149b4676f2b0191c6031bbc43e7faad3128bebb082aa057bf6e436ab51eb146b45ba64350496828e8e5418b56ee65e39c04c79ba9a4c92c0fb38ed5e29626d426dfd8a3b72a8de29a23063eb39ae7b25823e9b7af698fce9af29 +00 010c057bbaa44ef0f565edc288bfe66d4f6acd8686899359bca418ba89fb690429489a37bd3c6c9f3a8714b2ca225868c6a45fee360e378a676f7ea39321790f32a4b005b81dce43 8b42b64fa2bd52745d5bfd9be4b8a5ac7062e526313cecc03c389d7975b47feaa4131c54c9510d10a8d0b8e48a8208e3182032f742ecfd4a7857acb42ae2286792b6a111d831958468639c50e583df0afde92e18d084e2e76d011919685ca6d4 +00 02c182df7976ea93d996f3ba5d2221f3cb755cc7847bc3fe9e022fa4285046f5bfb426bafa3580beea206de36f87593ae561b4b74a03fcd61fbd0e8d6fd5668f2148819a88a650aa 826ca239a73b1211466b389eb56eaa8454d1723fe884fcc466c825e49696c8f795757bd14e44414af27119eefdd1d5aa08a4b3b2fcd93b000be9ca71aba020c89eabe5f8ee2fb493a138f8be4a4a76a755c123b0430697f60c21ba09f51227f3 +00 02d3a65bbe133cc98cf0eb56ee1362195968b4eab960a1d55d8b762f1361fc21348d6f275d4bea1de7158fb97c995e20b92a9c887a3e332d154667ad167acc632eb88a0ead6113a2 af88dde9c4a2d55c72f3df7691969f028dacd397957a11dc19c17acdf3bbe1d3e275e41a1a86d416bc0c4f65721639db15ab603a66e2475f4d73889ab4bd28453f76eeb92631dd6babbb62b5befa9afe6b72a25a34c0b4f3aca8649dc77c4df6 +00 02a920e8dc928acdd56e3655b2340d4371c793e66f67405fb7a90f31e9c4ef466cc44331d1d2fe3ff7391d2576dc6640772166ef8c154a5ff1808f5dab2f03061070ec8b3f786c36 a0ef62d8414cc284d20fc332f270a57c1705de491033f1b15a367121ddda206664ebf5c72b5a755572c8df283f1da25409e1fb6f3bd8ae3fc0e3db9cc789ac666e215407b16711ca8ceebbbe31c67bcfdeec41ae854552b4fc43f41dfb9f6228 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B571_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B571_blst new file mode 100644 index 000000000000..847f4b749dc7 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_B571_blst @@ -0,0 +1,60 @@ +00 00f42afce7f7b3d45f3f925ab29fc3882a89c9f585177887584703cf8bd8fc572e677adfa55b402446fe1e90dc855358d92c3267c35be9674b40c2ad5ce8dbe6a533c44b0ad8d2b2 88e91efc527e2387520e679cac7609862e0c10af1f76eda75cc62b67567133b562ff75e756b7d509f91952a4c72887c7163bc7238dfd78f74e9a06a3fbe88e1c3c3d64158cbb10a01c2552ec740a82362eb6aabc0a3c3a4918bfe44f4a9a6d8d +00 02f36613043cbf53ad36e2b38998bb867503359ae082d07d040e5a10a43e06ba9c91e7c73308e41e2391b65e634f83b162cbdf4e7a44ad818fb93a978af00f06be06731d8c5886c6 aa09c62bb5bdaf88a8cbf3fd88ca2a2f56c650bf1ef8499b40ab7315c799e3f38ee8769676da118a06a63fbd1f4eef6018f578e0f217d870939f4ca017a69e9656764976ef2f70ffee24d62f0f921f6e24f0325069de716b99523325243c8e3d +00 02e74948c46930cbcd9dbe2325539c7dfdd910f309fd610e6599d425aad9ae230a8d4681970a14f2a71fd08030d0a40ff40dade7de1b06a80441bbf7e2fcf1809cff39c7ef88bf9f a6d5f44cf0b82b79219865f86c5180328bd3a8c6227ebf3c9b788e6b9ecaf42e4b9793e047bfa8421411c3c0c91eadc10c5838b36736f78256c1c19f69b0fef59ebe91b3aab92b8572cbdb6e402d372d32d5eb4aa3f7cf9005dd662cb057da31 +00 01b5fab1d36f6f6d559f65d8b01edba610620fc3a38307b1fb1c5bd63e7ffbd4a9098cb8bdf50975a873f5d047ee2b627b090897a7fb5f56d3f4a0f3528179e7c969926fc0d3b0e5 85f1880907038e959eafd35a89fe03c61011100d7e727a0cdaf104f5fc2fdc6eb60cb35424c6815bd4bd40159b7680af145d1145d44aebaf12dc42fd7812410dd68fadc9bb660d3934ae8b7d0775a5e3cbb3f55bd15109bf28c0467725b806ea +00 0383e70c71b431eedd4574f65d01fb0304f7744d668408c847f7899eae44770a7f3243109740f177d7146a27748886b7b77ecf3792b512e8d8e37c3bf4ecef2b1253df7066498f01 8c2a1b52f1e1ab6d4c2125335f8cb1837cc4b491353a142f8a2896d8399a2a649fe4e4a4458ae7c88d9d2179dc6bf95a19df7b51dd0405fe849dbbbd47039ee4e446b5cc408885bc9ff32f29ed5fca5fcd34885fbbe918cc1fa4f1f1b4c08537 +00 002261d4ead21f02fab19bbb0da8c272286704c8f0c6842ba47ded121e5cddef79fb34e6b9694f725ca502949faecfb21e3cc062a2b4c654bd542d9a1fe8d97bdd0905c510aa0999 add3dedd3080e396f74a1ba83a9a87b3ba2acb5aa50631f1dc94a8f38186e40a677bab94b0cc3020cad2ba24cbdf929613bf2cd9629d81cd83c6116a8e727e75c88a30e34ff85993f07a735773f22caf3654b044ea2b6dbfd745668371846472 +00 0316c78f289e1860bb623082be9d9238b88e38c5e978a868bb90f776235bdff4eff591877b7f350cf14c40356922b2b6aa51d64990360b2b0e44d6941b5dd9492b4f4e1f42ca163a b2219edf80a6ea44fef35222fc454cd62ddfac494321e0218c65a9dbb888613050c28044553398d3172f6a4ed50a053709bbd14036714d9a34251b59d38c18c7594568d172257eaa6e836275921c4b117ac603fde20701753dff0455a35f2ebd +00 02c1bc13f8320d97a82f3d9354e195481902214e16a4fd89332a0499208e91d50e5cabeb4927ba030cb42f5bc53b10f500fa646a8c88508cb0d63ebfce5c4bd574c527d686c735ce b071b145b64b12b359f1ada741453b341fc7d8c523ae022fa000514556e6fba3af871ffd680c9ceaa873c41ae2debe5807bee74984d13729639e5d8b4afcbaa486eb55a7b8fbff427ebada313f83390409bf8beb04feade57e23012946b9596b +00 013bd80eafa67663e75d7ae139bf285d2b9f1e03d8e32153c73e26d06e86d7acad22bde9f121a3f1ea674dcc1fe67bc7f5398d5e92555056bc046a02b0ba86c2a0dfe32e91add5b6 99fc36816e675c40ac984c20003cb13ba6681ffd21de7d0667cb90a78894925fdf096e15efa76d0678114f6a453a35a102a66de73088fe2b650459df152acc4d61efc3754fc5782e609de6112cce257255fac487fa1328133c18a5bee4b818dc +00 030834b0a4284097cdda2ada6947c6c281f7290a49b56becefea1e2788ea3ef78fb96807633c47c25138341768b241164ce0d42f7301728b928be2c047f2eb60fc2f844ab77306d2 a1ebfc32e6be8c564faff0adcc396c70c457bbce51821837b1836031c976fa7d5ea440e1647cbca449fcdae6f6d9d3f8022eb2f3fb4e3b68eb2b019ab47d21d474345cec6b598b8d0bd2fc620354e8d1a615fea3cc15daf3ea98e3a214c9afe3 +00 00c81a79ced1eaaafc31b69a40d9939f4e484d625db6364a8e589b6b4d336d458b44287ea6c6aa7661113fc07806b147ff98216fa0c08708dc9d651821b922741deda522b4e436ad 88174d56293671ae2f945eefec5d5e1144ab8502553e878db5e5155be7757432a6d3b26394a5f20823a39c1a9f292c8b0277c4c94a935ea3fbd9e310de852a7b122acc5160681e5fa028933a163086bbef666c00172ceb06acad90013d0dfdea +00 02f24670c0f77d2ca0266a743023d2c7413d56d0b5ec77b454ac59087efc4ea4d46179e10278e4ba416ffd8c3f9786ed202faf8251c0ef5a9ea5371fbb35b7afe3d15a9cb4bad975 b74e77b15c282ec5b9511a0e2d36ee7f647b17039000a476d746dd8fdcaaf28867ec8a9224700d57da160c1fa8b5accb13c1bfb6b392fce963ccf3d3ee328138949576b147d1bd1650a480bd04aa37ec2e3a97a2b21a0ba3911065867825d259 +00 020985f2c6fe3ea04bdbab66a8b6167e5969c073b9d53cf3c77cebbf73f4dbf75e601620ec9c3107bf3fbfc6c79f8f063409bf8fe1d14b19e323d857e23dc05157d270c7514137e4 b093aa0cefb7d2193fa695ff8f43dfc171041755f7b36ea98ff2879912024589183ed2835e9c9a314fc93a00fb96046218ee4df9480ffb1763473a4cdc97b4aec26fb7ab5de0d7f675f60ba7ce8e9016210360624f5b2bc061a6f590be78d9ea +00 02b3d641607b8a141f876f6d285ee46aea543880e772dadd5dd83d595b9643191d9597218e1d6adb081df133304037bcd2c05c24a54e6c4cca64fb2cc4569d6882315360059496d8 a3ea0d23436c64936c47fae698fc37a2b3a39017953c3b35662562208e6d007903a371d21b1745a40221de05b8e5ea4002da5c1c7d23de0c4a52710ad4c468d8d054c2f9116fd3e99cbefb61fdb7811a38ad5393f21ebf67be4f668572e7218e +00 01afeb5ca87c81025ddf09c2b2c5ee22ba0105c0e619b67a324467485bd839030d149fee44d8bac6f5902a1245a50c3437046b7c89a84116b2147cddc645b6d2fd24d68e8d53bf5b 84a4eacd7893acec037a84b824031369c4c3b6c80a4f378eea3bdaedfd49d9eac4f1313b1be59b461c75b31df68d96ed107964fa3591fb180a4ca7e783dcce33451883619e4d64bbdb7b93e4cae3b321dd0e66bc0edcbdaaaf30d5d5a0788c05 +00 032c97639b69c7cdbf419286d0a1b406d9b1f2886521a8b979a36118d2a368aace5b02dd8c515f2041e6fb9f026d1e82e789dc826a56d2ef732b1bb0f49be2b696ab5d3d5694a2de 98281aaff32751f0e29b7db4d47bb0f5199f3c03336d7ee69c8838c3c5dbbdf7b4eb462d593431bcb645a4fd24baec5019ddac40d0ad72ca72732751ccbae15196a52e2db352f6c5516410ad8bbed410fb252407ef5a50ffb45fd2c77f0880a0 +00 00f93672159276c5a293582b9f49607bbdb970112f6c63b2b3b5d32ad3c8240c86b1af13a8dff6502c6b6a17712cfd988f8cd23a60693d64104143b3f91adb37f852e9e11a0ef110 a615e44316c738f41ca4b2845307ea2668396953449699baed348d9edc733c90cd0313f7c1c2f17060e3cc2aa73de49d080c8783a1ff4a518ec0fa5992df5fcabaf75ead137c5f39905a70bf89b08f3dbf68b91fc132a528419ee40fa3e484e3 +00 03db080bc99c5fe7e06d5032167af56783cb423fae59fb5b3c6bce5fbedf56b7b39b17810e48ea9a172881aa1f42f5e267349b60294d4a208b4437666b44abcfee5a1829e9467908 ae3c1f2d12bc51b8d8988955e2d67de4bc97a75affcf22e8b832512c06ae12f3d6f9b463acef513a8d523906b9af373403e6439d3bc96559d4a0cbe36556212ddea3369e1ebd959f1a4fa76fb95d9a963811f0a6d1f87a8b9077ca8950874ee8 +00 006ee767f6f36bb8f364f324d8346455c899a49237d759003dd52cfa13b9baa4c71347b134b24ecaee32d247c34e3787a0c64bc5d299b55c86f64b47521d22f2c09db225b0c84cc6 86c2ee888ed97b5fc968f9a9943e7bed13bf84088af04f317ed16e7aa85119de70341aeb30dd0fc7cdcd2d0ea357488a0230b780a5f21268ef7c87e6dd4e316a21fd6de4525248cc24d7f66258bce16d5eff10a7867d053e7ee4785f7e1af5f4 +00 038e2571d9f22309a636586d62863ed67a70538287f3ef88b88c3c2fa1a2900d48c342b6f15c26b8e7fb4875cda4093b7de7ceda48fe1e2cc2975afe958040881de61f309931e48d a164b9c248799896ee7f04854018ec74d7efb12d5c2b6224590d9b971305508bbcd3a63580ebc764acb04e21982704120efe760c51f1a1edcf8539ba4814d12c0c1090b9c2fa982ff7ce149741155bd7007b93113220b0c7675eada7b009d167 +00 00c8f5736f1ae65592f3ca850f43d06441aaad8c03820f3b08d8a6db46488dcfb828459f8b3f34af73cce8dc7a5e3834e085a64523d890028e194214cef4003210e6eb530005b01a b986ec8ee692ac7ee4f5cd8351ac8d2c3eab390749ad1606e84da39471164f353bfc82ce36135579a719a356ad9cda38078b1c9dc8ab6c0040fd536c07040f96071c40a68893c892ae0cd6b63fcbc01711880eebb651659cbb57a239b6708218 +00 01ee68c3994adaaa9e0d61bfcd3bc1cdf198d3fbfe28a44e5dd518867ea04b20e795eadacc48bfcf8e8216dceeaa069b756e8e99ed87b6b1d31154cc9310bc3b4555162a890b0c6c 86fdd220e894d9f3faaa5a12f9927b4be58f9d26fcb3491a8b5506a806c5af629b16271ca10f6ec38ece7bc6dca422a20164c84e72c4c144af140369e6830c004360ce3a8696cb9bebd0527bfa0aebf58b695b5caa951bc896770e8802335db6 +00 03a6fbf66ebc1365ea7699c72cdac2dd85907ec59cd26e2d18713354b619ccb83b7fc0db9193aa8493c1855f1a83fd987cbbb65de17c59fbe79256aa5392f4eba045346e9ba26592 b1c52c8a62e8ffa30b4f005a78d5f59366f2a13d96b284f820669664e55fd4a7439af5e0e8489629fceb6f2f9f74a5450a0ddf5c95b2304384bc25851a1f01cdf1859ca768fe3639c02978bdc11b55d4f1c57b26584ccdc16826a75992539a64 +00 0145748871a0b5c1cee628de04a12fd68ff2b154fda96e47afaa96389d66d22802968584f6753d36618d49ed205260f09d3f5ccc2b27a34390ce58179b9834ff92a86d66ea0a97ca addfebad4cfd4e53f95854c5ac509c397dc2ad52d35f4b35adfe380c9bb4bdf1a58e0b2588b3a6ca4df745afe4a0d3330e91d939dfe8c98451bd226c4f12df41da7f09ff83065ad76712ef882730f7ba286c5310867e6491f8f6412eb963154a +00 03c71911d24ad19c20fc1d8a044d63c9bb417abc3778d7e6234c6af79b898cbfc2f2787244708d2fe203be786edbdc4c9b12b413156b7b0bab0be8af895d191d853cd58aafe1ccce 8c515dc0bd13f915deb5988eaa40dcdd8d1c5c64a5e5488e55cb5d78396d164adc5da3742fcb04902eeb2bae099bd86e0efa4694ca8b696c21d4fb7fe406a66b1280d5da4d9fe82f71df7846a049270a4f88b1366fc399bf63e7e9921057b67e +00 018bd74698bac36ef11add6b3e3fad227ecd868f370ec04569462565d2f0af2340bf793486953a7b79ab04f0ab1f0e4fd16bf6b576cce677d543e73aa8edb0e50372f24ddfbff966 b61c744e24af752f0c0d41e1203214d4eb738ae21fb5772ab453d9ffa526dec22676c12e905c1ed020d6c0c1011ba2c501ae0956c1b1421bb1fc2ef8692888f119247927616ba21d178b904d9a276ba2898cc1eac6852d5663c9f8b1eaaa96a1 +00 0335699bfd058ee2e6163f55d1816bf3669acea8b73be9c4ddfe775230925e6093cff7a66813adf22222c8376faa106d85ac9f3c67929bc58d8986795b6d35d5b9fa546dceabbedc ae0f32b0f1f06ec2ae5296937b6c93793c5d6aae9fc1853e4cacd27087d61d0c2c23d6e45ffb2e3993a2fb7ce1cb216512b03684bb4aff61e61d9636bc6c500c4f905ef72f644ef5ac1196ec6068ad44ee1b1a43d04409dcf5c16836048b93f6 +00 02c3eaf801330b3f1b0504f2399f1d24455db29911f750c246ba0a134c3b59da8b3562911197764699a92ea1d95a2aac587e24f743df1dad3e1cf7edf955203e24a0225717f8d2df 98221ccedd0c45414232b1cbfed748b10ad175a62fde1f94b87c6ded86318ab5bc5f5b1ac766abaad84c1299fa33e87f00b31b4b6ba0c9008617c11ebfdbf7aa3162b41548bc3683e438ea07e9cb4e1f6a09f2656209050cd60f3385f45c0933 +00 01c3ff067497e5d387f31f0ecc9c67b3c0dd6ec8c81318c492aad83c9dec6c99e4fa47447f6f7082d636c2591d0df940b947d0a4ae3778e2b7cc8fb92214638399def894ada276b8 806048ff0ebcee6a5533be17d75091dff65026464111340f0c8655ddcdba38a62af2369ed505c17236a6cea5af5e946009a1e414cfbca68b888b6111d9a44b6db6e1b3f4daa81589648e9840ee3d538f2a7cebb4794d34396f653cf28afbf6ef +00 004b4e04281b210fe78d516a5b69f878b7fa058941ee9ae8cc63b061d1eb9e12c3e0ecb8717ff4623ff5bbbcdb53c48adbd9c69636506ab929c5507d7ebafae5654aad65a263e48d a8627e9b8cb66fe53f37c07f10b3c1b64f69338fee73eef1559a9ce86f258cac880cedf0a15bab7e5fa7a8393f1cdad704df6cece0314300b940ca9754f59e6182896b6307f8e60a4fbccef3135376dd32930087f5d258fb5c5c7a988d8a1471 +00 030f2849a713aeac95fde5ce3af853e9d070ee60709eccf35a076567be2c43f0fa34420b0fc097ff577221275a3a56e759efc32183be2d76058a7d20e5dd59f00415114d73a15b8f b37673fb7090d96eed8427d763a9d9bf6e4d85083fc4acda48438c9c1f1ff605d8e9e3431192363059c24a64867cb3b500bebb0cb60ca2b339789c27666d719c3450e883b6ad9e493e57f45e0c2ab6a0b6f3c3a363b54379c96742d1bdd955fc +00 02ebb73d04e6e5361e20629e3ad119b33db5163ed91fd9a8aec4b774898784b6822a08992118a8fe6013094bad0be1e9bf01b27c069e4335bff7e0abd28a10443818f6b825e9cef1 92a17b0228ae4d1680d4c399f8a6de558e3839e0cbcb58eb1861e5392204a097b6a52f2881f1a4c9f4a008763fc6941904f016cdc8a22807dba0318dca1d6c3df396f02c229a41d9034e133a22c6750d1a5ed7300c5d23b43b22c919b605fc40 +00 01bfab717d6f6e16d9bc6e89d2ffac7cbe0f808cc8ca2eb515af7ecce5f3b230303775710a21bd25c2cc4566bb53c78c78e3774a9f306c751cc6e149929e45eef60f56c1d2388c6d 804b8ab263016766d4e9c70bafd3182a2c6842bfcccebd03ad9a646069a945cc6fa015b63745c382dc8674e40ec73ffb018543e4baf718e8735cb904f2957008c46e3adf4958b1642a387ccaf4520e5052d9a1258665c061448021f25e1221a8 +00 000cc53bf7f1cad5e3dede4b4f4b082831604c92dd2b147869cdf1107259305b1d50359647f9f3d7d4e1e608865c65dc7c9ea46bc324dcb8423b554dc369d621743cbfb592b70eb5 8d10dfbcb00883475454693363aca87b97923d39056eba331f84955d8008e18d6d67e214426c6dd21cf4f478a9aee2c80c6ae40c08de9f6df4721604ada76044ac7f532b82d9bb150bce08d7e8996d7a29ab3e30667bef6de3da1adfbf9aac59 +00 02b009530cb9d586e35dd8951ccb686833afb7a37ec253e547e85b253ba999f0f186b6d4ba41091615fe57678e9801b4dc94fa683511da25637b2acc9fe60936be15af16234c4ee7 84f0c243b8dafee8d0f209bf70219b799c519abf73cd1644193a300032b30377636a30ecdc702df18aac22add93eea100a4c4f5802d10ab8b32fbed343156bc397bb96527cbaf413e3d578b1a6e3ae1ce19a4a308da0c51d410cf7e0f6ca5b49 +00 02cc2d0d7189cc8fb3565a039aee7633ddc00ff427cafad32fd2010b10fe249c9724d91785e7080203626038109158e3a61a3970aa3e51688aa7f5184b22f63af63f80d3540ec023 8ccf214fc3a8fdc605cb550a62263a905f0f2f416826c6f05f216d95318e1097a583a762350b559f21f3c4d04fb192c803d25e2192eee69cd8f217487f1c6f9d54d2b8d8318db3d4437f71fb6c926dd6d631c44116802de0b45c3a49ec50bcd8 +00 03d8936c00c131e38c6566d2464c4e207c878070bbf681695a6cd98cab2c6e80fe98cda80c66a5cf584e90a071144dda59c07b8fc7bb42464dbee5b6f739b0f2ee5fdff7e5a4e7cf 8c0c39df473e9086fd89fe079d76a7a1fed48cae3d0e76be697f57daaa076ad8cd82f0463ea93dd766ef9a5103de6eaf142a05df161b8b94d10802768fe7285671151be9ef397faf6b56ff7dade3a92045f4f35bd31b63841844a91c4650a395 +00 03dc7de970bce28a943d7599f2a9010fc99435b93bc4ba884d42503ac2941aa63fd07db34bcbb1127d56d6a4e277d6ca32051ea3467e376f74f98c3999d2f276b282ef8a28cf0cbc ae4793c1a95260f73abb0eef3049e312c05cd35b2088dfceb396d3faad1a670fc92da46c9e2d9e613ac633164a085b2801674ad8c748cf0d610959952f224d76d3543b1e26684e9977782a25faf502b0cbebccb2cdd72f3d50f666bc37128c04 +00 02de6ee12eefa7a4a736484b19b42a513dfc059a060976edc3b0aa4b50e98d72df6506fed0499ff8480986748e938289e54a5e86c0c29733a9bcf5985aa63d8a2b57933a04a8e8e0 8975b6a4b995d3ebf5afef8ee36680b2f099a068bc964ba7956507e8be3ecf48a4e5aff3b5f5707ef3c36173e7f56d630bc427511ed0a311eb20bb12dd608af0f0c8bb53fa6e9b6baf3589e2bda769a6d26c82ce3107462f320b0c17e7e2a2c9 +00 005468f0df2c9854f5f655743e79c750fd8812db28b096d97207bae7f5aafc6b6090c9c636ead9e0fde32a1ff8d539b53813733ca812b41b58ff85a941abe4f128d59fdf9847baa4 8d135573a308012e2f8fe9f82694501334d1614e595dbb4b14d852df3085155586719846b6adf06819a00aa0799b2abd057697b58cfafa275fe3fa5060365f5df364edebfe92b9c5002d92ac206bfb34167b39bbfa31789df00a611843eb047d +00 03d3c6a7ab9450c94aa3b8a1ffb678e5b647af24cbfd66ee3944e6f264f406295b803767471fc67936fdfed1714b4b8761a07eec86543b7c4da6bd2fcb33fa8cda4077737f398e18 8cfe7bf32c936354b74e7601e9c903d2fd092ed9845c6f3a5124154af2d7ba9933ce44c81b9154258b4d2319613f388e16ace439d03cf5c9699ea4186903c5b8d04bd27826a145d4b5cd20ce4ac75ff31521cce8bdc9aabe793dade1112b41c4 +00 001ce010ea8e6e1a0c26ab22eb90f0700dc73b232c429d36371e68e429792afb7223f10327708bcff779ea55fb5f22ad87aa054e84d10f5450f1bc9a89279062ea2173f55ab0f76c 8fe773056e039f4d57b5fc931984293d5455b22776d3d8f6371b816e392799795566d10a83292aeef5accf3c87040d031593df6ea37c0df8874e3868853bdf7bd8dc4e0af9df9eba65a1f8bde65b1bcde7f3b477f7ff0e31b82ac61185845f4e +00 01e7410d012aeef02b3723346d24ebafd684c99087ecccaea1cf3735d52c4c81dda41812c09f1e874dc964d858ca240a19963d5dc89451f5dd6764426ae41cb23f19cbfdca0fc562 a9d1fbb380fbf3dd78df7af149152c280560672a1dde4d5dab2edf7be47e156af879d1c63c62e3ce3f264aa553e228040046b1a8bfd535c08d956c91d04b7a55e4d0121232b25b0fbc66335d54f5c5cf545468acae78ba19284b79a674dedc45 +00 02139839ce38eb879d266065dde5e5ea227244323b330e3ad5a0bc690f3c210f794cf18f0d730693887548bfbc434f48ee10ed34cb41d52172b06e448df938170a5e17311cab8e88 8e4510e2815ac38d9e8be090e6c58cb44d7fd878154f3f856ee77628b77e19392edb6fef240c1922f431ab80558991ae12c613d797e8a9e02b988db5fc85e4a6a049b7677db9be01d15227eddf83a16c544ec4bed1960775d3171c58062a2dcf +00 0274f70fe69e4dbb55c5d404e39f5196335047113087f8711f2f67f2be4964e4fbcb865680758df1c401cd677b0971654b7a6aeb7bee0d6d80ac0de14d4f46f356b2d5545c185aa6 adddddc4a7c5f4aa1362f95567207330d214993fe55a196e1bed149f28ab6f6768bd846a7b32a859b71bca7f5bb1feb6093dd07ca73b9b621da58eacc5b4a3b3e6170743fd4ba4bb29ba693bdd7bbbeed214db52cffe06af5e24fe19cc4f7dcf +00 003e1b03ffca4399d5b439fac8f87a5cb06930f00d304193d7daf83d5947d0c1e293f74aef8e56849f16147133c37a6b3d1b1883e5d61d6b871ea036c5291d9a74541f28878cb986 86bd1740b762aaf0f61fc1ab8f7e06167a9e2e938b6469fb146086428362b676654d90b5edb86b1a1f63e62388e3899f04866bfeeaac029b6927bd58e701f8a402e2bbd30231a3a85761d394406c5eaf32d3c9bf244e8b676fd83b7ff17dff4d +00 02e09ffd8b434bb7f67d1d3ccf482164f1653c6e4ec64dec2517aa21b7a93b2b21ea1eebb54734882f29303e489f02e3b741a87287e2dcdf3858eb6d2ec668f8b5b26f442ce513a2 b82f6a92992531112f26400255353a50032e5c75adda88d6773fde8834ffa00d773cd8b3dbc256d4b39feffb34dd473101243f43c55065fb76f7e9beb5ac94fda6cf614d1a82976f1b237e0c077f824dba5990a2c140f77312a607bd69dc7d97 +00 02a69bc1df069c6e89722521a63675f318252be629e7558f3716917998e660ac960b0b750562846fe6c12ef492951e51e224754bab84a6eacd4147a5f26ae85ee4381bb14ec2a8c7 a1b0574d98e22115a8fce68333b48e413ae6424c2ae72088682dc34a238e383313005390834ca75a31f301be8b3abcc103f7e2fcc4cf46de4c44a8f452b7a474395132aba5d5f3286fc609d9d95a31193e5a34d1b23cca89de7595a26754fd63 +00 00d11ed1b78b22b3420df4ddc4acc7c2286d9569dd6dd88e0fa3ecae69bcced68bb81bbb4ca6e9b54e67856e7fdf39155aa27aecb9cc827ccb9cdcf9ac633561b27d8eebfc261aee b80a3ef9b68c994c8a0064bec201971d56dd1ccc116641321d6600db49b7efec2aae6c83f394c981c23243757255a2f11813a0f57b07eed107262b13cc6330e3893b306d0dc4a39cee8e9a02e0d615bc04fe81739009a29e9c6213596395d926 +00 02c36ef754b5bd065e9eadde684750acc52795be80f54dd3d7a7d743d968a18f7e404bd71f8a76eb0395f396df5a7c2ff7e0ab6de35df34282fda6ee01fe5b9b68ecb4e378dbe32e a5cf23d519761c10c6c1ec398c02ebfef2215dfd9e4bb58c0c33f8a91de010997373e95666e7142f280bc6cd8ed75afb08463fffc683d02b39121b2f3b63e2e304a1b8589822802f7adc29452205f078fd38152ab5262d19d58e2947538ad16c +00 019ffee50be5496507e3ef5c40ee88a49625e46d1dd1686a52b09ad4a8e3ee9ef364f953bfcd97c52104eecb6138067192997cd4ebadaccb73c7b2560879289a46353a756b73cc43 af0bf480a714133d27f44002a3bace94ea79b5e13ba7df9d66c5d24cad95ed8344654173c61363c804bb8b8c6c6851c219b9a6b322e701a75ab1486c612d8f0113fccb4b0de0cdeb02cd38bbf100124e41551a05eb9fad5abdafb8561e6637e9 +00 03129e96fd28c4198cc5242c1e3531a3979fae643d527044e98d7721aa56b5b4b45dfddfa17a4115e10a2b4f46d92f81cbdd7e86e588a4c6d8c2b3a83f54cebcee1d1dd33e85d81a 84f6f8979e6eef19e04d9fc906f6bf69830618eecd5faea8a99a4f3b57032351b9e6d244d63793d6c3a2499772c0fa170db91330d49170fe3fd6bfe393f7cb5ff4681c1eabea206c055179235de4e7a0d1a5950fcc743306c088e2a17c3b1a77 +00 03d723d2697cd07dd8444f992f2ab4a063db334034c25ea9be99fd7a1f495e3a644e5ea033a41264e0d24a911e55741d0cab80a0bd678eaec2bd1e60424d4491eb86d664900d907e 842abdaf97e67cda731b4fcdf6b010c7875944b7eb3cbe50023298a07027fa01504a25d9073a1e2115cb43907c98476e0a5aedaa37770befcc3f7e7084f051e85ced1ab495d571e5cd3b69a3953228d67afaf6d1f039e273cebba85febc51943 +00 01999ab45d66cd1d3a0fe6aa43bf5ef1e2a67637d53674f6fbbfb9b582be91fc42a12cdcad94b50b0fc7ac55030de24a0b99fbc4314fa743ef4b5198bcc5f54d8b669fbed78e2e91 9451e1bfbb6914b4115f9405538040386f939706f4ce97a446344de1c13964fe655ded2eb20c836b5018da58c5e4ec3117908eec98c49e46d9d277211f417ad5522977395385f8c5394542170cbb9a05afee63c441ed12e08867632e7da8129b +00 02ce1cae0716205330d730e6bc6dbfb6b951dc83ee3b4a7dae75d057e32e8a46e22be75b5f09135452b29c34dfe81a9be2e8dcd243fbd946a0ed14a832a7802e20cfe1abfd3d6e4b a5530924f9eae6e07bc781767b60915867262381c079ccd2acd22fe30c3e330d4fdb2039035f59c3b17484d4ed6fc3a7175adda2517f5adce77e59bfa30aa4fd4507c7b44f77ff149c1201023a79d08b472130cee283ad299086b9faeacf78d1 +00 02c9d0fcfcee7e75c3245ba955ae04188b1033c55ec9c821d8de7685276bda3e9a93c3ae1b003e5ea722913e7b169d67b1aa2dc8cd42adbd9368672a3f81a6817bf3e5529dcb0c8b 86ad6b801113e66b3d682e8c434c86cb4333cc9e4f114e393a98d4fd216feb945177ad7174dfc76c3c51935abc4ea45303c0ab17e1ce21db45a60675f280b0a1499912ad4e6c238159a47c8d380cc493fe65aded1220b423b25ebbbe95c503ac +00 010c057bbaa44ef0f565edc288bfe66d4f6acd8686899359bca418ba89fb690429489a37bd3c6c9f3a8714b2ca225868c6a45fee360e378a676f7ea39321790f32a4b005b81dce43 976e6c4feead1b69d2b97525863a9b774075d4c4a3a4948a383b61f86399bbdbb832b7f43fe0265e9296c293db738bf917bb3509e500e859fd80e3a64356df29ca9ffd674b7994e297ef706eafb9c2c148ddcaf2eb0160156748baadcd4b8efa +00 02c182df7976ea93d996f3ba5d2221f3cb755cc7847bc3fe9e022fa4285046f5bfb426bafa3580beea206de36f87593ae561b4b74a03fcd61fbd0e8d6fd5668f2148819a88a650aa 861e249cce8f3b5756ae07623f9168a61a28d4672ea6b3c344dc599a260af2c21e74f0050928bf6666afd4a4bbbf7a4b007f9b2e02c3ace89ea66affe795339229722983a00bbc6739a75ae9ec830ece97330e3551fb94e06ee164d853faedf1 +00 02d3a65bbe133cc98cf0eb56ee1362195968b4eab960a1d55d8b762f1361fc21348d6f275d4bea1de7158fb97c995e20b92a9c887a3e332d154667ad167acc632eb88a0ead6113a2 a92ec16815793e3878f9a3eaf429c896a6e0bccf58c31e9804dc4b64fdf2bc5350298d542527a8b79d12de18453ce2c610a4c2b33b3dd0027f0e3211c497cc8fc2f17ed1e303647bf8bec06f1282092bf3cfdfb7f4f628cad30ff3812ffcc1d2 +00 02a920e8dc928acdd56e3655b2340d4371c793e66f67405fb7a90f31e9c4ef466cc44331d1d2fe3ff7391d2576dc6640772166ef8c154a5ff1808f5dab2f03061070ec8b3f786c36 80f8c4858caf33baf97f45c2aa9879687c6d81fe646dfb861e9d6d951ab0132c95b4653bbc1280e84ff0cad0170a007f043a728a84c63973909a9b69a29cff1483cab7d95b0009b586676965c7bf6eb3db8c535d4896d333241214a460298609 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K233 b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K233 new file mode 100644 index 000000000000..36b569654ed5 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K233 @@ -0,0 +1,60 @@ +00 004c1d414696cc3657dd9df73ace56eda2636769ce7082e064c260be45a5 982146219f4816d49ebfd5536755534d372cee947babab8a3722444ef04a56994f77eb58ac9de5da68bd451fd321b03d179ea13db4cd83b64a7a504cc24c39fd6bd93a62fb12f2682998865f8d3ea36fdce975394d8d195943df89f12ad1f4c1 +00 0027cb1d84865a16992476c9e353283d5d6a40c349a8e9179d1b1f403531 9705caa523ed868a66cae1153de3f4f6f427f7981fc8987b9ac0f2df690930c7878f3a8923297b01024114d2f3a4f5c60d1bdcc44ef193bfb9f98487a276bacfe5d22048209e1375928b42417360b736caede0d9ebc4bc8281fdd9134a833b65 +00 0031b443f46c4b5224237fac1022ee1570173f664aba0c84dbaa4246bdc1 90825e1898a4427ab272ea3d5d141db4a3b201130eb83f27db7b2fc6d98ab47b1fc78f739fd822d4c8c13eac4d3add3f1284cfdaa0f864ebb2030b85815d2b192f2ab374c0d0857a7aae839f8f0609dfb9a3e9c97bd1b096774986300c9fd4eb +00 0048f6ca29f35f253a4962734357c995920967b9eeff1ba5fd2080bfede5 a7a38c62f49855e1ecef0a7e5354178b7b1d2ed1ba1919e65bb95b4bd5a2bfd4a816ab2b67b2028da000234ab3334414132dbae824299210f41a35193e54f9a6efff9f3a090cd6a0a3a2dc32d592ab1eda9ec788b63bc954d92576c19fbd1dd3 +00 0019b940eabbe682f961d9f3d90432e347fef3910e641656825d775705b1 86baf4c74d2924a19dcac4a903c4866adb3476ed43da9d523cb57a6ee63408150406995898a80070a96374153bedd75a0e2c9f168a88c4cf62390c0b495a9b3a9b9dfa98b20411781ab6ae9516c59f975583d60011b2573cbfc7d815f74c0eda +00 007a884b22e29fa9fe945e9ba13c0df8d786dc87cef0f77f069e182dd56c 9483ee088c2de4170dc0a6d5ddd70427f2b87c52059be3737260948145f0f43797defdcc0fba41f3e93281787ce8d1ba094f26a824cd3892cc0e4ce29499271f56a552d0aa4fddaeb8faa370a6b3c6d38f00dcecd63f9379982483233e1ac1f1 +00 005da61f881d5a0dc085bb93764f584352882923cd237d878220ec624c1a b731d992589b7b68d5834b3bc6dbd128d825536bb064af7df88de5b83bf18d298806fb5e0bc63999eeed95ab96ed11c503ac04b49596e7f5d2466dfc60f6f53365d6f0579733a9ef35386fb9008cdc13aaa7ccd096675cda436ef4b86c3d7e3d +00 003fe9f04647f6d82b13ec1ae5a8c2e49bc66b05649ad778eb16149ad83a b08625119628c3ae879a55c78f5bafa5ffc534359b15dc71909fe1a0c7f6c7930193e4ed0560a3f78502096af2029184178eb387020f656abaf5d8218eb282cda64baa4a202a5e240d324f8c20bf4b5cab97b88da11ad42694831d1492e0f1a1 +00 005ebce648ace4cd555413de6a456fc487d14bf4b0b9a72311ef480d2f26 84c825ff5abd7fe0e6eb2ae1a6d2581d95e29c0a9bfb729720a3fa996158c825c1dddd9fe114ada368e38e21e47fea3b19ff881c3a35997c092c9830f4e342904e0ddc40426f99856c98bd0c59d4d626f232112f15c45cf9855bb5715b75a443 +00 0056653c2f85593f789a926ba49fa3da9d7f946d8f1020508c5a527ce813 82a1a45f88d36e29c30dc877a77ea09378938b4295f2f694a8d3890269bad589f38632057766bcc31f657d5bc31c37e5123ed8e02970c913e346270c57b8a23506c10767550a7660f8666dda2edef387f3df109579b41adc7ece4ced72893ba8 +00 0049a91d320783cc70a5952c32036cfc75d41f1aa84127db2dc759fb291c a71fb7abb6e218f62286723ecd20b272796cc940f53d19d3a30aeaa04ff5b0057cfd025769e690e4c34f11583ad59d5107d0e541770672e7fd2adea10c022b16c3e1ee210e8691475ab752ec975635f43624cf579c0ac13976aeeaad123679e4 +00 0016a20016602fc7088a60469843e1d29ad67e3c3cb9500b1e2a00d4050a a5f82d320c2487fae45b8da4659cb0797ecd8f980f3e2919cff3df3a8381bddb870324cd9a4353fb0aa498084d98d75707aa942c60268f23a677161fb80e9515b336cc4ba13f7245cf2bdfa5d5408c7b9455054d1a7906d044e356263e3cea70 +00 000ba922149bada2551b7be1c3df076f3f97ce93c13c50c285fef3f42363 88a215c8282a8b55d1caeca0bd53a944d481e099ccbabc08bdf19d58cd1a5c28f8b3d15ef1f9d1f00f596c17841c702d0914d5b828b1a5a659dede1df665b86517d9bf962c44eb0dfb6cd9aea24ab1714b54108f5a8a3203be221f27d9e8ea64 +00 002d635e12a58cc6dea44e71e87c37f91e8d08659f0b7955d24f65ab55ba ab3cbc09d546b40dbe9c640e7dd370d6763ee59e16059e16da601e5656bd1fc178519039f50bd1a416414b907ec777ce0f553c405b7b9ca5fbe350d99c4351d39ab1eafff0fd633fa659dff033eb8e0c2952ddd9b3071a3d5f697eec207d13ec +00 00073883e5064e06814fc4de32e15f7a6cf825d2daf6eb1df8c83e25d80a 91946483827db0fb91982669f142bb5ee7ef2dd21f38ce2426a3d39c665ce9da92c750ee9792951241695c58e399c18900024288244dbc800c0caa332fec6298f83a546e455bc6efa1ee893f1125eb0fd3be98e0235b3bea2743293b95be7b18 +00 001532271bfae8d4dfe60f69b88d3006d58e28aacfa701861cde8d624db6 8a9bc931a2497f2c9bcabba9c6cf7859cf961d30e267e989702e9e83079c292cdb431a1699ef07bd8c5312a043977fa30dbac2ed00555da345601edc72a0cfde3109cc58a30fbbc8cbee3385bd2b7f66ecc125c39acede0ac63a06828c267a04 +00 00550406c0db882c6aee6cf3b6baf377375208c3e90cc44a067cee43efcf b14bf3984b429ecb88431f5513088719867546ef89537f78df74f5c9b8fdadeefe6eb72b8fb23eef51e4ab4ce157cd3706fc57413f5fed7a1295ee86ba4e09cbfb91a9a9ea58c103ecbcecdd2c131077574ac09953db5a3b76362404c579b3ea +00 00257dc63752920b6854d6c2d1cca68589a38418c3d036e73760a12214ab a23d4629a8215e7ce03ceab18fa2ddbf291755562012ceed67f168fcb250bb16af31bba7acb4306536944a807a43920b132f04877e44f32a1c0da41e0a6f619b4e23c20f5b23fc42ad25a713d6bdedfe3428419ddd743705e79d37d18fec2189 +00 0029025352297a7be850f8852411c09259b83219135e0e8949c1bd5b94c1 b0ba834748e310a7da4e8a0a7b7a9c3637b000c6d1264264f2786a2148cb80dd326e1c5ea4b63a27847999d5b0740ae3182d4be65ef0c0ec2118b0eb3bd4dd5edd541d1d5f132ac437f954f5d15d03bdeb2ece87a9c59c9d5ea0fa6975b08967 +00 002dc82d0e69e498528925c0e62a13fda9af8cefd047c10c3ffc2e41da3e a7e27460af74c925e363d749505e0b81bc7b2f7f9cdd9298fa143e02a2fe25f87a09d732eff8dfff90ce1e64c223e85d11461b0da1ead322d7fbbc95a4ce53008a0936804a57e2a648100ff9f92d0e04454f6971e78227a796d14ee4ba14e1ec +00 0041535fff5d279bcd744b04e643458ce20b81df8a9e01b1181d52bb14e4 800d8cb026326d9cacac8ee500f31bb156d6038745add28e69e184f58cfefc2a81b5f14cfb84fe47e4989efebbcb3f9c10ee5da7e0cc4325dd0d72eaf6b82af4049390ec63a905d5a4025a2d96f53cb87ad5bd3be52a09f47532a9c7bee9a6af +00 0000ecfe580a624df66c25e87e7689fc3b471d205970ff9ab51a64aa12ed 8fac41859b0acb3e893ef2ddc88cc9ac7f11a657c86d6338bf06792f7b835dc845fce80d0d68d817f7200bcfed6848101430abb33896584de718b6f93c6a50553ccc808fa76dd48016e85a8bf5f9bf98d2648fe443d54ece08069443d34bc3f2 +00 0013c72c73358ffa168423149ecdd897f0a5f75a641de008649f00134944 86d39d890ff43cfde095b8b62540829415f5a6fdde5fbcd9a1883b9c1f2eddb22d01908aa6d979dd3d9a8f94d5957267108b1edaeddd34d3329eea400a61a4d6bdf57d7ddce260ecddb79a356142eee913fcbb6f1cb17b5ac0d80561d699fa81 +00 000ac60e2e70b7c4cda64071c7738f68773c94df9456a8ec3bbb468fa7f8 b8103209763d35c8b5185a729af05be56cb8e789d530829a00d1fc4426375f8ec31a93d380688974a80b459ea6212f4a123c2f1d6da2136963d3a0a6dc04f3d6ca0ceee904e8116669ee2ef2d45e4304fa0cd5ecbd77e4206e982ed7faca8d40 +00 0060bf720052e8b9508a801340c213cf53bbecf4975faee63d4b44fc647a 992985668574734e3a856352140b8998567230103ffb8fa4b0e1d27b18580e260e37b8ce28ed7b12c0858cc6203e1db20502355533b9bce838676b4274012f26940be4d43e709f5aec165a38ae2ee6d82058b24b93a9272b88bd9d0f3961f902 +00 007cf3c216592febd8630a478b5b3e3a605084020322adb13ac0a626bc7b 80dc26e6e6c0a3427ed5b120b396cbe5d0138a6dc4be983bb53404ab8e9bd1fae57062756216952ae3298a571154d43c0ad25cc6f3c57549448b9e5976231fd62dd3e601d3cb77887575c5f843575e014ea3b6ccae6dc2f53c39ad071e5d4919 +00 0061eda5999e5a9ed4485d2a0ac5510549b76ca37df858ea5d95aeed571b 8bf4c2fb5226f8362784e43473b69151e7d44b11e35677cf16302ab7bfc6cb28a9ab7f0f9f3c5b1aa6b34a101ec025fe1127aaaa0979acefec44ce4f5d837ff69267b5b6987a763d59a718c92b4de65060d3b59e49442fffce426abe9c64d113 +00 007e7e73171e4d2f2989dc024757c186485435b82544a448f5cfca05f281 8480c4bcbfe408e0e305fc5031cdc1372cdf3d0a7d9a13194bcacd03068aa1751d7f4026697673127b885bd97d91a52a13613d7cc659d5a6319759ac13f7852e804813b2dfb9011d00c0814d36bd571eaacf4f29e2dca67931b5224e03dd6b6c +00 005f7270764a0444c7159d2db867930fdb0fb9fa6b8fc80ca02e11753095 95a5ae441b027f0137548c45c0b77a217c75b2bcae909766606eabc81e3ef60c3b18a01e5e51e0f50ed7efd126c32f9a10198bbd2c6aeaf111bdc456895c95eefb3216185f04793bf4e97123d31c483a7a1a4946a1494c9781a65352550758e8 +00 00179b924afa4acf30ecbe2b3c12de533a1f9675687876a7e5e5ddc8e03b 97f024e5aee2f834288e4cbb98b7d52b11dfa37fa73726a474f5e657dc300a1d1eb4bf959e73c6d167fc4a1894c3b25b10e01eb46fa6760099ed5c5020cca25e791617f2106d8a2284c81d82fad47c71dc16d00beff730ed47620854f2ddbb4f +00 002c9eb4d392d7f2eef606e1861183acb1fc753d666225f0f154d9eda147 a1d242497d7c89dff223df89a3d382bbf13b079465b545cfa89b01ed41f17ba381711908b3b4ecb50fc5e34e6b552ccb16e68db7acc4f78b336660a34586589b6a33636a530e3e6f9c40eef5205066780963a1e693f4ec59fc9f9d08d1c988b9 +00 0024661c89b77b2c743cc175a6130904461138ddc4ef771ffb9fc2c8679a 8ef4fb39c48c903bf9e650ec6b3768e6099c774b26c0d7e79d612019b7f48067438cbcb872a144edd9131a48f51236e705beb00a3f1e800b126ab419e496ac413a3090ad3d66c767e8577b6531092b8645984db768b31a59ce48a47862e3ba60 +00 00065e20e5ce534576d7c17616cd4ede3bf4f500894850723bcc9f895f4b abd98f08fc5a1773afc0f9226507009d499f424b6f354f0492468f13fcc0ff38873a401049441e40987035ef8b641e3e17b3991393f7c45d4a59e1bd3ce458f45374eeca36780b889df98d77f98572cf48f22a048895c629301d43d2a358bf1d +00 0014c85f66fbbd653f1e4e590cffe62c343ba6062df4b271fbd02e5d42f7 8030eea4738f1b9fb1b26a293947d9dded3e8c0d70045887230b0ca35292ec08d66f3c9ee13e200b1fc343e9349262e6135c13c91a6d9e351d242da7fb59dda26be9961a8d6c379385d7de67ff856c804e90282f82abde35e6d1ef0316a6c970 +00 0030ac7a78593b570b29f6d3d267abb6ba7e5870ee1c8ee4f1ab2f141051 a0070682f2faf5fbcf3415412fa9dce704f7a4776c882b4dee059b83cabca89dfe87cce9edb140710a648c334f357fac02790b80e5bae6047220f722f348c95f712103ca242b9d30bba05c21b2e632a651576277ed436890ab2016bd616a1209 +00 006d7516aa040f7d559cae248e485834e8d9bb608279ed4d4f7e1dbcd2b3 87edd0b75fab843ff16a9d2fd04951d3dabf3c8c5c0b9c5463e495df2c52f9f6b3985236b54fb0e56a62879cf453e003058a2bb5c82dc3fa9038d39649ca85f267cf36d4d68da53e94c2ca15d2dbe0e20d78829f8a5eb9123a0b212bd31d5ad1 +00 00137050d7b455f43a8dc2516cfff5a91062c1a2727b27df41488f3dcf18 83a38c74ceb45ec7111240e614aef3205404b2955e01633ed32044bf8dad5425873a80a9267a295a143c6a073f0c9f1f06ebd91cda7e5360df205324d0f54938dad13093078e40faa349433a7d1ce7c8bd4cdafc7b837b33eefa10a096d18ad3 +00 0001fd447b33a2ee3595b9f885c290d241422afdd74c3dc4981955a7e9ad 9789b06f213baf5ffa7ba967822c30c5d1fdc86874c72d4695eae98193487d2b6e08d019b8a809c4537e67a0e49aacc3034df3605b56ac8ef8ce4073a92e18bc888bc99de0b52035ea5b49db046dba4edcda220ea89d7045daa3ae2c8b3a3a4c +00 006a061e10b4a6e7001d95411cb31bdea9c84670a59ed61b14fbbb05c8e7 86ef6ee0849123e0eb2a6282b5a1460c8bbde455f3933bebe0501c70c0abcd58a43dc01aceb749dff9230a4a0824abd30e589a007826285c96ad3a33c8b3969a1fae0d35710d06fd94ec4a6ccceb470dd666a54e3b45bb0df2bfd7b417dd2fa8 +00 0027ec31ca31acb4d2fbacb49fc085f1261b0042cc755cc97f9b199e7a37 b8fdb61a1f84b3be74eaf9d0b010c855056ff1fe4034bd6d1d427bc0e15b4353ee4a7cb136f75d2eff12ccc424d09ca10817c220c4823f53aeb0bb717b56a9bd6ef3deda87bb4f915fe4d26eddccfd286d0a9eae9a310966ae7319b10a707bb8 +00 004c6f4d88e5a4f4f83196f2dda9dcf2a66eaf94d50c851f59bfcea1d876 b3482b62e06dfc1c92649ec3620ca71a6ebd2b2c6fd32f3786d46cac9bc8e2f6cdaf96c0fd8b153496a1b22df50897531805d13da19cdf098eba954217511b48f821b47294c068f2f29f2750e6a67f1dc9fe09b3e93abc09d3b681866c2b26b1 +00 001aa169ea84365c22981bb766bfdad27e373440850569957544b0f9332a 97425fe966562d16c8335457e888089ee0220c553e6e204f813d401083730bcbd89a98c884ff941e34ca4bb68d09e9e700f9a3140264e289ca6094cac78ec854479365510e0c0b035c5c4e432da43b521f1f1b373daacb993e71721b1fe2901b +00 004a665b92c0c33a3f8b9eb4b0ec061d40b603de36c87096455102ffe57b ac0ee53963e1c5984dcd5af29646247cec4712e94b345b3bee5676593792f0e0cb9cff8386da5076e664f6d95e54dc38026b1e89b5bdcd8eb986284b22f37686fb617537a9159eb31776ab426f9179c5e6b14d4a8c2bf5b2fe991842fc9ed871 +00 000531540d94823e19ab2b95cbc6e7492e1effcbabce875de6ba96f53aa9 a229f55434fa4d0c893cadaab331e606325afdc81de30d228d10010723632a57a5bba920dcdea380772d975d1c3609460cf9c48dfbbc1713c7166b836e743a34fa4536be185caf80cee00ee0cd542bbd2023e68ec99a9952ff8b7d14b77545fd +00 0022a89addd8b85809e87e0aa2c038593ec277054842854de1197833a51c 93739a9bab8435e04c351f6170f1f9c45bc0572ac64f5cd1e3a795c1d816b469efa2ccc3192877aecd51a63d3022fe3c16b5bb6c123685a3fd2a205b96e261351d9af872d172df6919a7c274098c2823289206ab50af31141229c99e8accb55b +00 001df252a11ff97b4421b3a2361db94e908e8243cd50d9179f9e03e331f1 b182f995ee87c0f8cd6dce689dafb8bf5a0f04a1a81ebab09e92d6c9d346849357ac6481c98bd49869947fbd89977fe11694b084e3fa95d7db0a65c78b79b80ff414a36a4a56754da36de326b6e3ef2b0f531051275224202e234a918a83dc2f +00 001d7125c299ebd0dbcc050f07de931c7ad0450af590d0a2d0228a66ac5d 83e5c54a8b41da60c408feb4a93172083f768be133e2fd75fca508b26cf597ff4799fc8ed1772fcc213f76c98d78f46801eeb9d7ef36ca9e7ba1d0399d18f7c23bbe8a6284445c1d62816d909a9903388b975909fb52acec142c265dd6e66503 +00 0021238e66119844b146d40e48341f522f6ac2f9c8a0b33aaf95a3099a41 8a92beb210a5271d21892755e21da5613f9cb6a8c32925f73dcd97ae62dde2300720854de6be5d76fc97224f7122aabb0c8161a6da56231f34613edca02b58b8d20c84dcecc6eb8d38ffad775296d9ff61276ce96431346ad9519a73105276a5 +00 0015e1bdfdacd87c42ed439f3e243abf27fd42e54f3ebdfb47f60dbae5fe 8615a4ef76b6bbdf86f4190d1632e9fde486a2780b53575002d0309424ad5dc379b27c92a4f822bd152199a80d7b6053100759bb97a546d82538d2439b43666082a5b9403580eaca5a3dd74ddd4e4175c01af11cc2fca225d50d2ae206684dcd +00 000e09410548c17bbbf28a68c3963a52d39743a4f1ac28e6dfe7a6ede281 91ac748758c394cbab86af7ab9cd1618f8091ad70c379cdb8edf69afd1877e73f68e85e0196d87bf01e9c1aa91e9e53d0bbc76e7fd83644831b555aab0900f13aefddd31e7912f505526b98606e779a0c16efd0f00de738166aeb47039c8c1fb +00 0049f5bea6e72d98579b78cb07d89f64503f8759dd7a73cd73713c120428 8079e16a32a0983c1c0296cdafe86b62b0cfc8ae9d6d9cfdd15fba764f7468a179b620e2ef0c384cb52220d86557ff330d5b8887154a494d44dff8b9b5732ce9d227d828336fa410079c5c7047198e3c0dce1b750eb386d96734e5a79e5aba7c +00 0005eaa818690d1ca4838f0bc667be5721d178c3869884260fb230277c3b 891597412f7f2812f90ff69f985a39ff92bc39578f62f36bbfe9cbcd8abfded6baff4731f7c2f6979ca9fe23b7bb7e7c16990a967e13c470bf7f9c0567e4aff9ee4e7fcf0c7352aebbd55b49e695992efc3747798ea0f2f266fc323fb3f9e4f6 +00 00603d89cd2f741d734587e77554fe6bbb1e5739d5ff73084d4de8ed69c4 8b58393b040b68c02b13b98b73478bdf31f191e196eacfdd7a9c508c7d2db516005f79e5f99a0c5a5932ae5cb3004ab81874f72f814155aa94e0ba3c7d404e176317a4f05b4099a1981928ec39070071162cfd0e1d52f064b5f1078c442b1681 +00 007977b3aba53616dac27b4d74930da23966a88ad98f1769674789c0be3d 9861a79054c2108d8f14376e0a88cdd1469ba382a88e212a55d232661654a4ea8013a71a5a73e9de45259e94cae2c54b19fa63cdf820156be96d4123888cef328a775d12a2b4b31ed708990d86629acae63dee098996ef709d6e8601e98fbc50 +00 0050cd20e7eabd29008cc977d0a17e1195d79587b8f15ac2447e15daafc0 8597678d0c65f8878f78f316978b96aed40ae6bb942a76cbde5014d1018f79803f93e87080c8c1d4a47518f9cbab3e0a000b67b6e05d97b4c297dcb8f5861726ac9d00d0a5906c949b9fbebb92405c20bf2201fec68b5ded00e7b056b77c8708 +00 002dbb24fcaf9f3cd5d50d209937f0e2d134fa20ee3c9c2f1fff3dfbf302 a0f69ec6db33e729efb50b4b9c2260bb66ca06507091fd55341ea050a4c4c2694b327328abdc8c1efeccfb37fd780c080f93e4727071cd3838d0fffc8fec7c534320c5e01f8332f65bf277c0e7db878987a88314e1181f071b2a888eee5c4e4d +00 00047142197d3d43fa46545b547968680ec81688589d1ec8d7c7e90eb969 813306b74894a783dd174bd67e00d2b8b3953dc2ced872ebb5c363beca450a463ef4691d133ab77b9059a9560c409f83054959fa5177bac4d12759eff6180d3ba2f34da5379bb35ba1325b0965667b6882f372b32206758f641eff1bc1998dc4 +00 0031352b49ecde5434aac05f898e6ce4337304845d748f114c14319fe97f 99e69a4f8388afd3a94ffbdb1c17636e4c4c794f62d37af541c28946d0bd9ffd1d11e6d4b3f69c41ef787c97bdad3ec90a4cec5b24e79cd430cfb991c6faa06521dc8ad98fec2b35520e49ca473fd40331cf6124c0a86b10464d6eed29c8a078 +00 00176f124c24e4420f6e726a6ca25f09dfa0c5a37e5bf879e7bdd36c3b65 901ff6c85c635c2f8b985cc2b10cf4f64f4cb7de063482b08fdd168f1dd48974548bafa2b3d23e141bc0cc6a3eab2f5a0c70c9eced3bc52312f83e95327cb1f52d489ec4a787db44aa441dd17e67f0742f277b51fe4210afb54f69b1408c8b7d +00 00755c48c3dbaf71042c58cb137f3632e3cf9d90b7b9a58fd378feef3d19 8d5bb4139a0cc35cb5734ccbf7e6a70c2c4243889cde9dc00922f0547d91e9aedc74c62a0d8f84c9900b6c37d3c75da901673581f04b26396cacf2030afcdab7929fc82736fab89cecfe618b314d8aa81ce42cfe95a7a9ec26095995d0913c77 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K233_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K233_blst new file mode 100644 index 000000000000..36b569654ed5 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K233_blst @@ -0,0 +1,60 @@ +00 004c1d414696cc3657dd9df73ace56eda2636769ce7082e064c260be45a5 982146219f4816d49ebfd5536755534d372cee947babab8a3722444ef04a56994f77eb58ac9de5da68bd451fd321b03d179ea13db4cd83b64a7a504cc24c39fd6bd93a62fb12f2682998865f8d3ea36fdce975394d8d195943df89f12ad1f4c1 +00 0027cb1d84865a16992476c9e353283d5d6a40c349a8e9179d1b1f403531 9705caa523ed868a66cae1153de3f4f6f427f7981fc8987b9ac0f2df690930c7878f3a8923297b01024114d2f3a4f5c60d1bdcc44ef193bfb9f98487a276bacfe5d22048209e1375928b42417360b736caede0d9ebc4bc8281fdd9134a833b65 +00 0031b443f46c4b5224237fac1022ee1570173f664aba0c84dbaa4246bdc1 90825e1898a4427ab272ea3d5d141db4a3b201130eb83f27db7b2fc6d98ab47b1fc78f739fd822d4c8c13eac4d3add3f1284cfdaa0f864ebb2030b85815d2b192f2ab374c0d0857a7aae839f8f0609dfb9a3e9c97bd1b096774986300c9fd4eb +00 0048f6ca29f35f253a4962734357c995920967b9eeff1ba5fd2080bfede5 a7a38c62f49855e1ecef0a7e5354178b7b1d2ed1ba1919e65bb95b4bd5a2bfd4a816ab2b67b2028da000234ab3334414132dbae824299210f41a35193e54f9a6efff9f3a090cd6a0a3a2dc32d592ab1eda9ec788b63bc954d92576c19fbd1dd3 +00 0019b940eabbe682f961d9f3d90432e347fef3910e641656825d775705b1 86baf4c74d2924a19dcac4a903c4866adb3476ed43da9d523cb57a6ee63408150406995898a80070a96374153bedd75a0e2c9f168a88c4cf62390c0b495a9b3a9b9dfa98b20411781ab6ae9516c59f975583d60011b2573cbfc7d815f74c0eda +00 007a884b22e29fa9fe945e9ba13c0df8d786dc87cef0f77f069e182dd56c 9483ee088c2de4170dc0a6d5ddd70427f2b87c52059be3737260948145f0f43797defdcc0fba41f3e93281787ce8d1ba094f26a824cd3892cc0e4ce29499271f56a552d0aa4fddaeb8faa370a6b3c6d38f00dcecd63f9379982483233e1ac1f1 +00 005da61f881d5a0dc085bb93764f584352882923cd237d878220ec624c1a b731d992589b7b68d5834b3bc6dbd128d825536bb064af7df88de5b83bf18d298806fb5e0bc63999eeed95ab96ed11c503ac04b49596e7f5d2466dfc60f6f53365d6f0579733a9ef35386fb9008cdc13aaa7ccd096675cda436ef4b86c3d7e3d +00 003fe9f04647f6d82b13ec1ae5a8c2e49bc66b05649ad778eb16149ad83a b08625119628c3ae879a55c78f5bafa5ffc534359b15dc71909fe1a0c7f6c7930193e4ed0560a3f78502096af2029184178eb387020f656abaf5d8218eb282cda64baa4a202a5e240d324f8c20bf4b5cab97b88da11ad42694831d1492e0f1a1 +00 005ebce648ace4cd555413de6a456fc487d14bf4b0b9a72311ef480d2f26 84c825ff5abd7fe0e6eb2ae1a6d2581d95e29c0a9bfb729720a3fa996158c825c1dddd9fe114ada368e38e21e47fea3b19ff881c3a35997c092c9830f4e342904e0ddc40426f99856c98bd0c59d4d626f232112f15c45cf9855bb5715b75a443 +00 0056653c2f85593f789a926ba49fa3da9d7f946d8f1020508c5a527ce813 82a1a45f88d36e29c30dc877a77ea09378938b4295f2f694a8d3890269bad589f38632057766bcc31f657d5bc31c37e5123ed8e02970c913e346270c57b8a23506c10767550a7660f8666dda2edef387f3df109579b41adc7ece4ced72893ba8 +00 0049a91d320783cc70a5952c32036cfc75d41f1aa84127db2dc759fb291c a71fb7abb6e218f62286723ecd20b272796cc940f53d19d3a30aeaa04ff5b0057cfd025769e690e4c34f11583ad59d5107d0e541770672e7fd2adea10c022b16c3e1ee210e8691475ab752ec975635f43624cf579c0ac13976aeeaad123679e4 +00 0016a20016602fc7088a60469843e1d29ad67e3c3cb9500b1e2a00d4050a a5f82d320c2487fae45b8da4659cb0797ecd8f980f3e2919cff3df3a8381bddb870324cd9a4353fb0aa498084d98d75707aa942c60268f23a677161fb80e9515b336cc4ba13f7245cf2bdfa5d5408c7b9455054d1a7906d044e356263e3cea70 +00 000ba922149bada2551b7be1c3df076f3f97ce93c13c50c285fef3f42363 88a215c8282a8b55d1caeca0bd53a944d481e099ccbabc08bdf19d58cd1a5c28f8b3d15ef1f9d1f00f596c17841c702d0914d5b828b1a5a659dede1df665b86517d9bf962c44eb0dfb6cd9aea24ab1714b54108f5a8a3203be221f27d9e8ea64 +00 002d635e12a58cc6dea44e71e87c37f91e8d08659f0b7955d24f65ab55ba ab3cbc09d546b40dbe9c640e7dd370d6763ee59e16059e16da601e5656bd1fc178519039f50bd1a416414b907ec777ce0f553c405b7b9ca5fbe350d99c4351d39ab1eafff0fd633fa659dff033eb8e0c2952ddd9b3071a3d5f697eec207d13ec +00 00073883e5064e06814fc4de32e15f7a6cf825d2daf6eb1df8c83e25d80a 91946483827db0fb91982669f142bb5ee7ef2dd21f38ce2426a3d39c665ce9da92c750ee9792951241695c58e399c18900024288244dbc800c0caa332fec6298f83a546e455bc6efa1ee893f1125eb0fd3be98e0235b3bea2743293b95be7b18 +00 001532271bfae8d4dfe60f69b88d3006d58e28aacfa701861cde8d624db6 8a9bc931a2497f2c9bcabba9c6cf7859cf961d30e267e989702e9e83079c292cdb431a1699ef07bd8c5312a043977fa30dbac2ed00555da345601edc72a0cfde3109cc58a30fbbc8cbee3385bd2b7f66ecc125c39acede0ac63a06828c267a04 +00 00550406c0db882c6aee6cf3b6baf377375208c3e90cc44a067cee43efcf b14bf3984b429ecb88431f5513088719867546ef89537f78df74f5c9b8fdadeefe6eb72b8fb23eef51e4ab4ce157cd3706fc57413f5fed7a1295ee86ba4e09cbfb91a9a9ea58c103ecbcecdd2c131077574ac09953db5a3b76362404c579b3ea +00 00257dc63752920b6854d6c2d1cca68589a38418c3d036e73760a12214ab a23d4629a8215e7ce03ceab18fa2ddbf291755562012ceed67f168fcb250bb16af31bba7acb4306536944a807a43920b132f04877e44f32a1c0da41e0a6f619b4e23c20f5b23fc42ad25a713d6bdedfe3428419ddd743705e79d37d18fec2189 +00 0029025352297a7be850f8852411c09259b83219135e0e8949c1bd5b94c1 b0ba834748e310a7da4e8a0a7b7a9c3637b000c6d1264264f2786a2148cb80dd326e1c5ea4b63a27847999d5b0740ae3182d4be65ef0c0ec2118b0eb3bd4dd5edd541d1d5f132ac437f954f5d15d03bdeb2ece87a9c59c9d5ea0fa6975b08967 +00 002dc82d0e69e498528925c0e62a13fda9af8cefd047c10c3ffc2e41da3e a7e27460af74c925e363d749505e0b81bc7b2f7f9cdd9298fa143e02a2fe25f87a09d732eff8dfff90ce1e64c223e85d11461b0da1ead322d7fbbc95a4ce53008a0936804a57e2a648100ff9f92d0e04454f6971e78227a796d14ee4ba14e1ec +00 0041535fff5d279bcd744b04e643458ce20b81df8a9e01b1181d52bb14e4 800d8cb026326d9cacac8ee500f31bb156d6038745add28e69e184f58cfefc2a81b5f14cfb84fe47e4989efebbcb3f9c10ee5da7e0cc4325dd0d72eaf6b82af4049390ec63a905d5a4025a2d96f53cb87ad5bd3be52a09f47532a9c7bee9a6af +00 0000ecfe580a624df66c25e87e7689fc3b471d205970ff9ab51a64aa12ed 8fac41859b0acb3e893ef2ddc88cc9ac7f11a657c86d6338bf06792f7b835dc845fce80d0d68d817f7200bcfed6848101430abb33896584de718b6f93c6a50553ccc808fa76dd48016e85a8bf5f9bf98d2648fe443d54ece08069443d34bc3f2 +00 0013c72c73358ffa168423149ecdd897f0a5f75a641de008649f00134944 86d39d890ff43cfde095b8b62540829415f5a6fdde5fbcd9a1883b9c1f2eddb22d01908aa6d979dd3d9a8f94d5957267108b1edaeddd34d3329eea400a61a4d6bdf57d7ddce260ecddb79a356142eee913fcbb6f1cb17b5ac0d80561d699fa81 +00 000ac60e2e70b7c4cda64071c7738f68773c94df9456a8ec3bbb468fa7f8 b8103209763d35c8b5185a729af05be56cb8e789d530829a00d1fc4426375f8ec31a93d380688974a80b459ea6212f4a123c2f1d6da2136963d3a0a6dc04f3d6ca0ceee904e8116669ee2ef2d45e4304fa0cd5ecbd77e4206e982ed7faca8d40 +00 0060bf720052e8b9508a801340c213cf53bbecf4975faee63d4b44fc647a 992985668574734e3a856352140b8998567230103ffb8fa4b0e1d27b18580e260e37b8ce28ed7b12c0858cc6203e1db20502355533b9bce838676b4274012f26940be4d43e709f5aec165a38ae2ee6d82058b24b93a9272b88bd9d0f3961f902 +00 007cf3c216592febd8630a478b5b3e3a605084020322adb13ac0a626bc7b 80dc26e6e6c0a3427ed5b120b396cbe5d0138a6dc4be983bb53404ab8e9bd1fae57062756216952ae3298a571154d43c0ad25cc6f3c57549448b9e5976231fd62dd3e601d3cb77887575c5f843575e014ea3b6ccae6dc2f53c39ad071e5d4919 +00 0061eda5999e5a9ed4485d2a0ac5510549b76ca37df858ea5d95aeed571b 8bf4c2fb5226f8362784e43473b69151e7d44b11e35677cf16302ab7bfc6cb28a9ab7f0f9f3c5b1aa6b34a101ec025fe1127aaaa0979acefec44ce4f5d837ff69267b5b6987a763d59a718c92b4de65060d3b59e49442fffce426abe9c64d113 +00 007e7e73171e4d2f2989dc024757c186485435b82544a448f5cfca05f281 8480c4bcbfe408e0e305fc5031cdc1372cdf3d0a7d9a13194bcacd03068aa1751d7f4026697673127b885bd97d91a52a13613d7cc659d5a6319759ac13f7852e804813b2dfb9011d00c0814d36bd571eaacf4f29e2dca67931b5224e03dd6b6c +00 005f7270764a0444c7159d2db867930fdb0fb9fa6b8fc80ca02e11753095 95a5ae441b027f0137548c45c0b77a217c75b2bcae909766606eabc81e3ef60c3b18a01e5e51e0f50ed7efd126c32f9a10198bbd2c6aeaf111bdc456895c95eefb3216185f04793bf4e97123d31c483a7a1a4946a1494c9781a65352550758e8 +00 00179b924afa4acf30ecbe2b3c12de533a1f9675687876a7e5e5ddc8e03b 97f024e5aee2f834288e4cbb98b7d52b11dfa37fa73726a474f5e657dc300a1d1eb4bf959e73c6d167fc4a1894c3b25b10e01eb46fa6760099ed5c5020cca25e791617f2106d8a2284c81d82fad47c71dc16d00beff730ed47620854f2ddbb4f +00 002c9eb4d392d7f2eef606e1861183acb1fc753d666225f0f154d9eda147 a1d242497d7c89dff223df89a3d382bbf13b079465b545cfa89b01ed41f17ba381711908b3b4ecb50fc5e34e6b552ccb16e68db7acc4f78b336660a34586589b6a33636a530e3e6f9c40eef5205066780963a1e693f4ec59fc9f9d08d1c988b9 +00 0024661c89b77b2c743cc175a6130904461138ddc4ef771ffb9fc2c8679a 8ef4fb39c48c903bf9e650ec6b3768e6099c774b26c0d7e79d612019b7f48067438cbcb872a144edd9131a48f51236e705beb00a3f1e800b126ab419e496ac413a3090ad3d66c767e8577b6531092b8645984db768b31a59ce48a47862e3ba60 +00 00065e20e5ce534576d7c17616cd4ede3bf4f500894850723bcc9f895f4b abd98f08fc5a1773afc0f9226507009d499f424b6f354f0492468f13fcc0ff38873a401049441e40987035ef8b641e3e17b3991393f7c45d4a59e1bd3ce458f45374eeca36780b889df98d77f98572cf48f22a048895c629301d43d2a358bf1d +00 0014c85f66fbbd653f1e4e590cffe62c343ba6062df4b271fbd02e5d42f7 8030eea4738f1b9fb1b26a293947d9dded3e8c0d70045887230b0ca35292ec08d66f3c9ee13e200b1fc343e9349262e6135c13c91a6d9e351d242da7fb59dda26be9961a8d6c379385d7de67ff856c804e90282f82abde35e6d1ef0316a6c970 +00 0030ac7a78593b570b29f6d3d267abb6ba7e5870ee1c8ee4f1ab2f141051 a0070682f2faf5fbcf3415412fa9dce704f7a4776c882b4dee059b83cabca89dfe87cce9edb140710a648c334f357fac02790b80e5bae6047220f722f348c95f712103ca242b9d30bba05c21b2e632a651576277ed436890ab2016bd616a1209 +00 006d7516aa040f7d559cae248e485834e8d9bb608279ed4d4f7e1dbcd2b3 87edd0b75fab843ff16a9d2fd04951d3dabf3c8c5c0b9c5463e495df2c52f9f6b3985236b54fb0e56a62879cf453e003058a2bb5c82dc3fa9038d39649ca85f267cf36d4d68da53e94c2ca15d2dbe0e20d78829f8a5eb9123a0b212bd31d5ad1 +00 00137050d7b455f43a8dc2516cfff5a91062c1a2727b27df41488f3dcf18 83a38c74ceb45ec7111240e614aef3205404b2955e01633ed32044bf8dad5425873a80a9267a295a143c6a073f0c9f1f06ebd91cda7e5360df205324d0f54938dad13093078e40faa349433a7d1ce7c8bd4cdafc7b837b33eefa10a096d18ad3 +00 0001fd447b33a2ee3595b9f885c290d241422afdd74c3dc4981955a7e9ad 9789b06f213baf5ffa7ba967822c30c5d1fdc86874c72d4695eae98193487d2b6e08d019b8a809c4537e67a0e49aacc3034df3605b56ac8ef8ce4073a92e18bc888bc99de0b52035ea5b49db046dba4edcda220ea89d7045daa3ae2c8b3a3a4c +00 006a061e10b4a6e7001d95411cb31bdea9c84670a59ed61b14fbbb05c8e7 86ef6ee0849123e0eb2a6282b5a1460c8bbde455f3933bebe0501c70c0abcd58a43dc01aceb749dff9230a4a0824abd30e589a007826285c96ad3a33c8b3969a1fae0d35710d06fd94ec4a6ccceb470dd666a54e3b45bb0df2bfd7b417dd2fa8 +00 0027ec31ca31acb4d2fbacb49fc085f1261b0042cc755cc97f9b199e7a37 b8fdb61a1f84b3be74eaf9d0b010c855056ff1fe4034bd6d1d427bc0e15b4353ee4a7cb136f75d2eff12ccc424d09ca10817c220c4823f53aeb0bb717b56a9bd6ef3deda87bb4f915fe4d26eddccfd286d0a9eae9a310966ae7319b10a707bb8 +00 004c6f4d88e5a4f4f83196f2dda9dcf2a66eaf94d50c851f59bfcea1d876 b3482b62e06dfc1c92649ec3620ca71a6ebd2b2c6fd32f3786d46cac9bc8e2f6cdaf96c0fd8b153496a1b22df50897531805d13da19cdf098eba954217511b48f821b47294c068f2f29f2750e6a67f1dc9fe09b3e93abc09d3b681866c2b26b1 +00 001aa169ea84365c22981bb766bfdad27e373440850569957544b0f9332a 97425fe966562d16c8335457e888089ee0220c553e6e204f813d401083730bcbd89a98c884ff941e34ca4bb68d09e9e700f9a3140264e289ca6094cac78ec854479365510e0c0b035c5c4e432da43b521f1f1b373daacb993e71721b1fe2901b +00 004a665b92c0c33a3f8b9eb4b0ec061d40b603de36c87096455102ffe57b ac0ee53963e1c5984dcd5af29646247cec4712e94b345b3bee5676593792f0e0cb9cff8386da5076e664f6d95e54dc38026b1e89b5bdcd8eb986284b22f37686fb617537a9159eb31776ab426f9179c5e6b14d4a8c2bf5b2fe991842fc9ed871 +00 000531540d94823e19ab2b95cbc6e7492e1effcbabce875de6ba96f53aa9 a229f55434fa4d0c893cadaab331e606325afdc81de30d228d10010723632a57a5bba920dcdea380772d975d1c3609460cf9c48dfbbc1713c7166b836e743a34fa4536be185caf80cee00ee0cd542bbd2023e68ec99a9952ff8b7d14b77545fd +00 0022a89addd8b85809e87e0aa2c038593ec277054842854de1197833a51c 93739a9bab8435e04c351f6170f1f9c45bc0572ac64f5cd1e3a795c1d816b469efa2ccc3192877aecd51a63d3022fe3c16b5bb6c123685a3fd2a205b96e261351d9af872d172df6919a7c274098c2823289206ab50af31141229c99e8accb55b +00 001df252a11ff97b4421b3a2361db94e908e8243cd50d9179f9e03e331f1 b182f995ee87c0f8cd6dce689dafb8bf5a0f04a1a81ebab09e92d6c9d346849357ac6481c98bd49869947fbd89977fe11694b084e3fa95d7db0a65c78b79b80ff414a36a4a56754da36de326b6e3ef2b0f531051275224202e234a918a83dc2f +00 001d7125c299ebd0dbcc050f07de931c7ad0450af590d0a2d0228a66ac5d 83e5c54a8b41da60c408feb4a93172083f768be133e2fd75fca508b26cf597ff4799fc8ed1772fcc213f76c98d78f46801eeb9d7ef36ca9e7ba1d0399d18f7c23bbe8a6284445c1d62816d909a9903388b975909fb52acec142c265dd6e66503 +00 0021238e66119844b146d40e48341f522f6ac2f9c8a0b33aaf95a3099a41 8a92beb210a5271d21892755e21da5613f9cb6a8c32925f73dcd97ae62dde2300720854de6be5d76fc97224f7122aabb0c8161a6da56231f34613edca02b58b8d20c84dcecc6eb8d38ffad775296d9ff61276ce96431346ad9519a73105276a5 +00 0015e1bdfdacd87c42ed439f3e243abf27fd42e54f3ebdfb47f60dbae5fe 8615a4ef76b6bbdf86f4190d1632e9fde486a2780b53575002d0309424ad5dc379b27c92a4f822bd152199a80d7b6053100759bb97a546d82538d2439b43666082a5b9403580eaca5a3dd74ddd4e4175c01af11cc2fca225d50d2ae206684dcd +00 000e09410548c17bbbf28a68c3963a52d39743a4f1ac28e6dfe7a6ede281 91ac748758c394cbab86af7ab9cd1618f8091ad70c379cdb8edf69afd1877e73f68e85e0196d87bf01e9c1aa91e9e53d0bbc76e7fd83644831b555aab0900f13aefddd31e7912f505526b98606e779a0c16efd0f00de738166aeb47039c8c1fb +00 0049f5bea6e72d98579b78cb07d89f64503f8759dd7a73cd73713c120428 8079e16a32a0983c1c0296cdafe86b62b0cfc8ae9d6d9cfdd15fba764f7468a179b620e2ef0c384cb52220d86557ff330d5b8887154a494d44dff8b9b5732ce9d227d828336fa410079c5c7047198e3c0dce1b750eb386d96734e5a79e5aba7c +00 0005eaa818690d1ca4838f0bc667be5721d178c3869884260fb230277c3b 891597412f7f2812f90ff69f985a39ff92bc39578f62f36bbfe9cbcd8abfded6baff4731f7c2f6979ca9fe23b7bb7e7c16990a967e13c470bf7f9c0567e4aff9ee4e7fcf0c7352aebbd55b49e695992efc3747798ea0f2f266fc323fb3f9e4f6 +00 00603d89cd2f741d734587e77554fe6bbb1e5739d5ff73084d4de8ed69c4 8b58393b040b68c02b13b98b73478bdf31f191e196eacfdd7a9c508c7d2db516005f79e5f99a0c5a5932ae5cb3004ab81874f72f814155aa94e0ba3c7d404e176317a4f05b4099a1981928ec39070071162cfd0e1d52f064b5f1078c442b1681 +00 007977b3aba53616dac27b4d74930da23966a88ad98f1769674789c0be3d 9861a79054c2108d8f14376e0a88cdd1469ba382a88e212a55d232661654a4ea8013a71a5a73e9de45259e94cae2c54b19fa63cdf820156be96d4123888cef328a775d12a2b4b31ed708990d86629acae63dee098996ef709d6e8601e98fbc50 +00 0050cd20e7eabd29008cc977d0a17e1195d79587b8f15ac2447e15daafc0 8597678d0c65f8878f78f316978b96aed40ae6bb942a76cbde5014d1018f79803f93e87080c8c1d4a47518f9cbab3e0a000b67b6e05d97b4c297dcb8f5861726ac9d00d0a5906c949b9fbebb92405c20bf2201fec68b5ded00e7b056b77c8708 +00 002dbb24fcaf9f3cd5d50d209937f0e2d134fa20ee3c9c2f1fff3dfbf302 a0f69ec6db33e729efb50b4b9c2260bb66ca06507091fd55341ea050a4c4c2694b327328abdc8c1efeccfb37fd780c080f93e4727071cd3838d0fffc8fec7c534320c5e01f8332f65bf277c0e7db878987a88314e1181f071b2a888eee5c4e4d +00 00047142197d3d43fa46545b547968680ec81688589d1ec8d7c7e90eb969 813306b74894a783dd174bd67e00d2b8b3953dc2ced872ebb5c363beca450a463ef4691d133ab77b9059a9560c409f83054959fa5177bac4d12759eff6180d3ba2f34da5379bb35ba1325b0965667b6882f372b32206758f641eff1bc1998dc4 +00 0031352b49ecde5434aac05f898e6ce4337304845d748f114c14319fe97f 99e69a4f8388afd3a94ffbdb1c17636e4c4c794f62d37af541c28946d0bd9ffd1d11e6d4b3f69c41ef787c97bdad3ec90a4cec5b24e79cd430cfb991c6faa06521dc8ad98fec2b35520e49ca473fd40331cf6124c0a86b10464d6eed29c8a078 +00 00176f124c24e4420f6e726a6ca25f09dfa0c5a37e5bf879e7bdd36c3b65 901ff6c85c635c2f8b985cc2b10cf4f64f4cb7de063482b08fdd168f1dd48974548bafa2b3d23e141bc0cc6a3eab2f5a0c70c9eced3bc52312f83e95327cb1f52d489ec4a787db44aa441dd17e67f0742f277b51fe4210afb54f69b1408c8b7d +00 00755c48c3dbaf71042c58cb137f3632e3cf9d90b7b9a58fd378feef3d19 8d5bb4139a0cc35cb5734ccbf7e6a70c2c4243889cde9dc00922f0547d91e9aedc74c62a0d8f84c9900b6c37d3c75da901673581f04b26396cacf2030afcdab7929fc82736fab89cecfe618b314d8aa81ce42cfe95a7a9ec26095995d0913c77 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K283 b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K283 new file mode 100644 index 000000000000..a99a7cf17025 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K283 @@ -0,0 +1,60 @@ +00 01e846c830a8ec04e8572d1a9d2df044ab47352fb346f67403a3bf87243871b164511c53 8b46ecdf69b5d5156961dd48ea26e640c4ae744c9b40aaa69fb5c3ed6b717483e690d3b3ba6ce0688063eb28edf372a01972bb90b5e37073a98b6f0ae9768888795a01dbc9c8442d5cde695fb2a787121f5a57e11a42a0af0496797a9999bdd1 +00 0101c5ed48231a56ca0ea85eb45de0e395e6df2efd4987a226ae36489dd8b2dfbf7c465c 87c9f9d4cc8039565e7975c6b6a149b3ab08b6fa69d216c1547af6534597b974b2ded7667694ebc1d8d9ca33e651b740003a6fec67b87721fa8f7f541dc7b0a861244e4b167fdc2b813c15170a16c459b5338f0e99814a973bdf11cee14b2655 +00 0019679dc589440b11f82b3716e5b2a2bd42c3b1c83e88a28e304cf5148877faf760b4de 949f8fa3599d39813d0b6ef1b509a350f60954223f6c053656e2d571dc613be5e3b769106126b9ad06e5aa1b64444fbd07bec783857a2083d6dc525e68249d5fbb8157192d5aa771b01124d40b17f184e51942a36f44cc33680c908a7b620bab +00 01703c21fb1e09f8947e12fddf166fda6f685221fbd803d75a0ae377a54a1e494e6c5e7b a5d62c807e84b56b50bf61051d81c5a59a4e4e9b95318b98d2ca990718d4f5b845730dea78e311905e0ca9d20dc8cc1b089fab873c64145b02256b602716833002ff034b3f524a84d017139eb977fdc0fb9184865938cd575dd1e96e91f5f92d +00 0071de8eb14cbfb88e61b908990ce08b81e624ef4f2cd9cdf3dd7ca9097d5ffed9ae9a71 88ed08a1f11cab67c1eb39eb94f510102ac2640ee7ee35bd256542a5134ecc8a10c3297f295a6bf97a2f84abf8d2f07f0f8420a93c47b565c3546957aa7285cf571d405c7376bb12d5184d769b23c8cca818a757cb3d053b8bff63e23d3acc07 +00 01d156eb15762ed00c4021884adbfc2426e910b18a5bc474268196f4b74e593a8f38702b b630c493389abdf504f9aafbab3068c94b076b9ea15cce32e7c0df2b06c70d5a058235fb89b0e9dd4fa6cc16522380470b3b137a4d24b6ba76d18bb4fc4331a3f4bfb16232883c6160485e181fcc105635bb9461cb177eae467e5acbe95bbbcc +00 017d6eb1219cab8577168be86b61f372b27ca70fb1f1a767947895c185344e966db17aea a2c1ad19eacf26af2f952368ef17fe7e90b6fa6a01fff45b97e64842889056ce943de0f1d3e3d2742a7a43c5c3d70cba12e016053c492712eeb78ae0000cedbb38ad909925b4ead85160856b2ccec4ae78360490170e9d93e7ebcc1275a79520 +00 010ede9be6615b3b2a294d67da78127ffbf3a15bdba6f4fd78be7a60415b5d1a097c0cff ac1fbe9ddebf0e322e6aefce4c41e10bb009de094958a4d114954099e9f12fcac3e3e6c5498837b325a05a64f29ac70207b4a2cb45adde77fef7bae45b43d433afdce58d54aa6a5cf852d63f008ceefd3c33d1b237fa50cf2c3245c0375be37a +00 014f237cface123b64e8578ff33f86bfd2a8181b9c81f36b9ca31e2a446f0d91dbbe2249 8e6f11b682e95499625059200bec0e851805ef26f0bcf0656e9ee38fe82cc9b6480fbee686ba31670cca861c065ce652170819e5448764864f7d94cd64805696e29eb7835e53dd61ea2436297dbda390839ce6a8f2cd71f4a45afd9e6f54fc43 +00 008dbecb26587cb2ed7df2404e680fcfa5bf8cf6a58e87a350a1600211b3c844ca86daa5 a737aff8e26d6d1ffe4fd59378ad7181c6eb2cd461830bb12361b466050ea46dd0ee1ec76441c87b11ac61ed3d95e58a12244effd1fabf4d09f0f7d8c9c4e9cb742610489a5522d77cc4f9a3e8c10803f30c97c82bdca74f28ab8a8b71b44419 +00 0191badec2d28cbbe62c072c6b57eb5d4644d0c0b3283951bb66096cd15edd43a1bbde53 891b47a312a218a943040972d2feaf1428d22f313bffb8bcb91933ea5a3153a4a166207054075422791fc44f8bd8f9600eac31c6f44b8b4094a98fb994682226733b48be14afc1f82a56fb1271e951d7c9b6f929c72b9bfce4c3cb05e97149ba +00 00ff5e3d66eb57fd35ba4472effd6e7a016ca461e39000a7125e99080f6ab6ef4380dd7a a4aa9e0ea683f2c9632df4c34c52c1d03fcc0bfb4849660b3fa9f43203478be7d54e5129356c1ff67d86a08b9152448612f7a446872dfcf588f72f12d1ba3781d468e83b3430bfeacf990fc3a6e6ccab39b2304a3516b8822e735805c0fdde2f +00 01f3591eec4a8a3fe6ae6debe230d238a6b73cf3791cb735add1abee64239bb100f15166 85d324f6f1b9c7881e399a2acac80d777eb3cf962d8b18e7141dc12b2533694acb0404392d29d724b2086ca9ace20aed00d6484ad6f95a64fd1424526e5b8d408587a7a1e9445dfe8a603e1fb450621e55e6916975040068673d8e714e0f6158 +00 005af03cdb45961e7ff35fb0146904ddd6c2bfd3cce814073d3aa56eaa9f13b4f7423926 90425edd4d6515c62ae3a81cd133f149113e4ad75e6cf846003ab3c95b3013aa5bc85bd5d3cbad865356c966f9ddac3f1911e45ea1e0cd8b4b568601541a26e45115ced2d0a3ebe04773767e37f21157cc8f2c0a39f21fba1b4d1b4dab205c4f +00 01ec9710ada06e6270720692a06d488ae2ba863b905dd2fc323e7ce68dedacb35fc8c7d8 a493f431d7ac58f733c06591b3513fa46b78098320c114920a1533c91a22cb9c61ef349ec1da554aa02d0d1e77771e1a02d572e5e04c42179bf9db9eb606f4cb8bb9ad65cf2bf708046332476565755d66b329dceb849a97ea867f4c80f73dff +00 00668de088c6913640fbefbe6d2c44ab26e481802dbf957044a4957c3c5d0a0fde331501 932e4e20071d1559a22842389b63ef701f74715d725d2ee72d8bfdbe2733061f7d7f41d88854685854280c54098f3778008c2a26a49fcfaea48d413f20d73a83a8911d3f46a96acf5b5091a14b470fe995095ed1a494685715227f1489aca00b +00 00e6af57cf47de1e6f07041eb5e1a413fb7ddd82f8c7f7ce957eb28a118004930bec4dbd 887fe02f3bac6d28c668eb7d72b42c7cbf00f93e64acae4715eb10cdec1cc2c8d45f204a7ac5033bb73d066205b0487416008847e03f8b83201ee5a92aba4acaefe396f0fd0dfded86fde15a69d7d11ce06c373c3c5be6bba450573cbdeb06fe +00 019f9b63fde8c6aa6177f2a38981505d04f8ac62bcc21007b05615d028cfe851ab9cbbc6 a89c99e45fda3042c16554d7b7498953edfec5d2f9c89f17290329380d3dec33ece24ca24420a686f5cbe20abd9abd1316a92b00c86502841bba53db46666beff91bd3a9c00e395b005b48ebfac04ef86a86636f25e35743bf4c752d25584e81 +00 017704c1f436beb52f7ec97192e23e206ec09f9e8986e06bef71467c192bad6f0066b3c2 938e14eb1b365478011d455c36c157a792503d02e2c0ba1296176d922cadf2e5dc5c57717f130cf6e2f66bca574fe4570c0900776612ecff6c22a3963f3a9ae4bcdfa221da144fc4440c43335c38747f7e97f0f9b40f1764dc1b44cf522e27b9 +00 00c7d1ac8faa689698f5c6325a3b3f35e7730bdbddabd0693f2bfdc5c838bd62f84508d4 a986d34c4dda198f44b18a12d8586953cb73f30a8f51252634afb49d6d4429ce7fe898540435c070c51afea8b7a569d5033cff2175312a3cd11704b4858ba913b11c58bbc83097851c1eb2bd5e878210878d4f7bcdb0708526b3cb4c1c00cf9f +00 01a173d158866db0ec665ee632b5fc397893f6a44ee17c348e7452800aadd8ce676e7fdc 8e90837bd65e24c6aecf4b15e928d98df4c6823ed77b3fc90e4f61db97c38a69fd01a0bb004a26700e5e70061d3c77f7107c5d99fbd596db44d95b4974d349c8351f4ba37f84d6b16aefbf13cc302f7e25f8093e9345fa6460ee693ae8a7de1b +00 005523cfacf4ed3b74ebc30f608292e45173001d80cc801f729c5f71fc213b243f041ad5 89294925aec38faeb497f6db8e5b486b242d45f415b780e88dd02aca2c03e4e9d2b31d83bd4cce4b9b03bd61b6a8d06402c55358c2ffe3880d01ddf45f56d29c372aa2ba552fe3303d653d17036a7e850fba6fbe2468db7f7da12284aceaa572 +00 009f6bd008c04b8823ccc3ee7d5aca535c211f35e9d9e7cfaec518b98647fbe6d28283de 8e38b49f63d30a02466e240de9a717c5e1e5a92a66ad8d6cd2f7eff8a9327541be0c49e1f5b1f6e824ed06e186f372eb0a89713bc646719737612b96a48b5bed26d71d49bb2fc1cdc9ea17f840b49a7acb1a35007d29dac4b021db48f26ffa83 +00 0150d2812505c82584201e93f6e0cb875d29dc7bd99d9c0f98e0ed20128886e67e1f1071 b8971ef2928b87587de492d7f786018541ca1335992a62f4b2b2d11da32d75da018b7803f8b35d5b2ec4bf154a1fcf2001639439219fbf8f450aeae619e0bcaed47f217c5b23533a04a139630b484c4e6efb0230e54560b64436169d5ecc164e +00 01b3fb9e1ff70f94bc9d7742ea535ca982215af3df381b5ebdf1db40c7c849a7978ceb98 a01d805391eaf722f36d0103013aa6073cc75ca29c3b4a13364e4e81ef9eb9bbc0db5364e1864c630e49f1ddce29dabb10f1e639cef394c16380a1b439ff4879785029559ad4edb035574bc460c6bbcc14b9181ad738ff6ab8b501fba4a67dd8 +00 0147fa46fccf0805d14c1b84ea59bb8b8283d54ca0ceefb29b5585e7141340c55b7232f7 b110530815ffdd7b04d38813afc583fcbfe916a9822187fe78553535500efae308124226b3c7afa325b2e44539e7dc91040a6f9cc5036699c645bfb899381282631ff1ea9792585229aeabe4aaad38cd58576247ec96ef73cd0e7c03627c00b8 +00 00fae097ea56b35a517be5480802f450eb832b244558d0cc922cd4a5b40b84d02ef11216 8ec7e25c14877dd371fc29ec62ba8033225a020e81a93b4af529ac77385c7f90d179905d8163fb16e635800b8b2ff13b094018bdc9d91a13e4407640e384786f6d9b7eef0f002805212c685844c4b74042da1111353309bdfc7ade8039f2107c +00 0026cd72e6ae19b3f4c53493fba1e8082a8df1fb7da6dc111b47a41f713f49b33f618d0c 9676f93f22a9c6165cdb5684c2cf1990d521719b18b714510710c6647cf3066a98f12258b3c4183bf48e0b57c1f59b3d19584abf9d7c0b4acf1d329500afa0daac1cdab8133f391aab1f861805e974823503091d15bc69a05cb6740727be67f8 +00 0198e13c7d95bbbb6e226688719639bda988867764ffa9b029018b5547850daecf58fe1f 853dbd5415a5ed2c5a5d91305b55bcc93e4c199b2ecd50c8fba77eb0d4e30e571aae61e3bbd412b9dfc1e070e9fe528b0f3d26be6f9c4d2748ea00563b5a1166257bca29251955deec4d19e5c4bb26c97fd150bbc04386c745ed9e9589e42d1a +00 019098a39956747de24ded56435fa1e6c30cc2b8088fe9a75f5d07b2f5939c7a60db64ad a176d3cc02a0c0567757e3beabe3ae0d53ac82900273bd19fe8983b8c3b41b0cb32391527b64f687e1d2e35b2e97dc1d0d23683eccf6a01a47ceebfaf8005443618bbcd66a513349925f08de36ffbc4c2ce469f831baadd38d6ba6fe3738d10c +00 01636bd2be121e07ee83ac5e880cfdfca6a56f2b9d0badff003e872348368c7c2cd96b6c 99a54247852f8124b045546272fe4a361ef7df43f47286469e9a67b9574e6f7809fd99b1df56a829553a35baf39bedfc015654926a9c1dad6f23ad0fb197a48027354a019e0b4332850ea27d6680e14a241c969da406a5632b15501cfe663eff +00 015e5f555119c19b055b15b0c0d2813068bfc184f864e250b202384f5728bbbda1cb0f5a afa9786627028b0cf78cf8f05593c0ea113d378be34f83b1a18e838dd78d60eb405e3f2743eecf34b5e224edd0ff401902615ffe1695b135be47facedea89cd5162bfa8101703baac994db1b797034675747b675358743bd0bb1b18649004fe5 +00 0190c8f17bdd38669e345440d2c7631d67cee9c6548c4e7b9452377adb9303430efeda0e 9063a2ed794e1c44626474b22ae36e529bf8c4a60545fab9a3e008ea992385294c186adaaa1ad2760b43a8c01bc017cb027e517b29782b318c0b706eafd7191d73ad896ea6653ec08f915b2e0ac2ad0bdda9ad81d90d82880ab28316772a4486 +00 00dbbc2a0409ca58a9e39e33b95fdd15080443c1dbdb5874bee991bd1b127047f08ec9f3 b027538f18420ddf3947549aa02f455f15782a8042a870c819c19e16321c0b4e9f2e8824d438e99809882c6517649dd302f97460944e35859d6e9b8f7aec82166c2961c0158aa012db5605f02e489eed670da480146439199a9bb520d600e345 +00 005495e6c59ca1873f36b756579632fd47f9fb95b64f52589d70f2739aa6a3bf8cf8c198 b6e807e28b5857cfddd323f986c1289f885461230170a6093600fd38c3fd093d7abe7d71f875ec11c2301ee55570e17e03e3550f94078849577b4d0a80e9b781402bb24afc3d7c18b90489ed2878be5ea3c920ce72dc54952031c551b5b3936c +00 01724987c9b698519b6c225cf1261b77d0300045e5fd774dcbf13f285e6bd74512cb7edf 8aedff4f595cebb3f445e85ba135138766b9d3ee44f766fade2bbca499609f3da39d67472230d001ee431b889db6dfc8026493620c7edc902d3fe1be81c0dc8e120a39c284148c069dc2e460c8a1c6bfd151e63bbd4a39ceb82f47e0b33e0f3c +00 01a5489091cfd51a0970508ee3e8449081ed175928ff8386592c83043a7911bbc2f8778b 8be61dd3787241c3f980a5373b0cc87b2839670b51158fc89c6677b508d8c03ddd1274ab03bf15171ac9a5e8843109061920f85d0f442937f62b43c01714aab99b77e68d97e1f6153f35e20b7464302e2c37a901bb7d5e91c3348dd4b46c0640 +00 01a45ecda0788fbd7cb7a716dcf4c6e83d4148bf63ed58078690ebd238c00329c462590a aada0c402e70b6a2bc1b7bba32b6b1ff1a8eb3bf7a6d4c79d694bede2d91606e53a9336712a88a9a8f0bb73044b2963b162a01c76cab30b33d0d0d0927a6167267bdbda31dbe4b789b07ff45f88b787004ad2adcc86820d6eaa938e17584828a +00 011461776c33f20b176dc8f2b0cb2446a9b69e55b6c7bc7457a7fb4639116b452b79661a 80371fdccecd0d8c1331991bc443a84ffa0d3789d32900a51a35cce3b007cbf851a2b88b108d08b6909b2270502e4b76097bf56192e448d43f685352e2971df25b2e14a09fbd716e5eb956ef440f1d413f512ec5a3aa9fa2be643625e9e4105c +00 0025a65f627db2b4d6cf83c5b0c00265b9b63f7656c5e3382139e4992bcdf3cab502844a aed77ff4c8de0b5029733def9f4d4d3a7df8cfa67a7bec75a9179be795ba1ee9d3a46dfeb60f6488178cd0b2cde33d530e45c6bfcbd7a72667ac4a763abd4bd7a54ae8f44da8e29de603e1d44ffa326a5f51c54413931ccc3af135e5cb78c612 +00 0173b28fc29f10245221a907778708b3ee62e0480aa9051d4c3eb4e8d552e6aad5509943 9771e2014150a6325fd75f10fa6307254896f3c156445cd145177fbe9a9e93c7230b758570c17a03249da4199dc58ff60daef7e051400cc553c6137c8ac682b3e3cee38e127a24467d6894e722c117f953f5a7e8e9d0841773f6bb84ea638c1e +00 00624616adcd45e1fdc6cfeab2b17230d73d91fe0b39f4664f3c6891554f9b8e238257f7 830d6d4a341079901c5a524d627df1684126a1d2481a9924219b40c73e7f212ff4702262b7dac61291f2a68b223637830f1f249f18a232e975d602ea2f8ebc137565117479b654e969cd2c01f39be7f56d5b015f8da0867d4b9f3dd72e8031cd +00 0199757ffaa2c59e198d66824eaad37cc42d49b2e241b6a60382d05e425e800eaaf32470 9340c88ba6ce5583d2753c8707ba1000237d39953e283cf49f7e1c170a5830eee11ce3159982c4f0a745d5d30fe3154e169fc0674810352a32d4f9e20dcc1b51381c8118e97e302aecb6cf27547e1a5d8ecc7330618b3817f27d785d3c8fcd83 +00 006e51381dcf21050aef2e9b97e35303cf3bd91956854ecf9b6b9827871d2efbe8201c5e 84d1483ebff8b75f41da80ac7bb271625f8e92877c7249eec94c5fbc2ca463e81a298f1712beb14f01397475518c636c12d7c296a9012ebdc4a81853cff31eeb2294745c08449678f0a1c74657e98c3b602fd609a4c295e9f6a528693720eb96 +00 0018adcc22cb9a2db64bad3d60f1608c353e091637b948914115ebd43679904f955c8732 a2d6820c6c7db7de82166e276737a4fa80a0ad1c671b08f530ddbcc8f8f622ac1325922ac442a557e848016ac4eae3b5119d89b5769b4fe1d21b781388e47139f982b01a46710431f6d023ceb62c34d73dcafe045364b58eaa4f67d84335903f +00 01898276f159c10d92d8d4b6ae214d68c72792a4b5f1f79936ca3c063dc8d9a88be439e2 916039a6341cb1f6271ba7aabf01ef627fa537ced694d42e09e9579bf1b7e3e9743b840083b0f197642d5909941e5c5804929082b3027912f0b4aaa3dda3183a5058bcc56f142c6f43d26f887fb051228aad88881f857624a20eb0b0742dbb5d +00 012ff37c808c3cc029a9cfbb67a5ed21f3bf362b49270d4ed0f1e38fad25ebd79f112a50 8b859f406ef913e08ec9cfff1fcb696e2bd2fe603d38ae9663a708a7a5e41354c2f7b56e67f651cac17d9a097e662556142bf00791e8f181a281cc800e80c861dbb432a9b53a4cc7632329cef6d3fb3664c6d9021e3436b80c048965ea470bd5 +00 002b8c1fef9c6def32b5f4127273ce384b6add4aecec957c1662f52334f5ee97f49852d4 86b42045b6cdd4087afac425d986f3673ab0d8be03720c4146885f6ac93a6ffbfca5a26beec748644f27a8bff23c4c8d02563cac05bda8ebd6afa028dfc6a8d41b755e0645f62a46a9058f62f09405dbb1c3e5b3e4e196c6ede3586092065282 +00 00afb1c45e9a9f02942b8e04da4b815498454dde6643de186625a98b3c1c6993abc8bba4 991b41ce25c5c53a1fb8325e5cd298d3a6d96ea4ede76d6255b4afd7c73f05120cf47d5a374275628e8b302eef0a441615f154964225ada78ffb68a59742a8d7c8bf359fcfddef300fc37592a33a62173bc2af21c8259a7be7d62f98964ab962 +00 00ff537d73a4da0ae3a4894016b71dccef3bc886f3d24a5abb7dd96cf8fdcbdf0fdc5e51 8b9bf22e4459e9c02bf7df13b6b81cf026809ee6817935bcf3f6b6dc58d29f8dc086e22e320e93060c1fae77fcb0704a00385ca7a807d924432d25432ee883255b9bbcb972ee73c11fbeba579f30b5c8e77982fccd611f4c4fcedc54cb528c7a +00 016000d2e879906d1040b32eb6ba3caff700e5565871ac75f10c5c15b509964bbe5e14c7 a2bdb0430c228aabaf7c3eed5daca1a6727ef0df376ce860df1886e0c7f92ee47cc998efe885e10d8275d7184e4d17c0112e452bd0166db4fd779cfeadaba0c0d94960f34606ac72342cc49ea31f30d0d11da739c9e1bcfe10ef0eedeb054e98 +00 0019528d505bf0584628d0214bc857150a929d3f59619bf8f3acab545fff0977c9bcdc97 b49c9741a6417939c45b2d7f6a621d71bf847174e2548dc2cd466b15549b4a33cba75848fc6064debbc63b3006c7a19909571137bd5b62b43c48685a2d923166aece9e05f2f8663ae7543d97a52b1e681224d3872763f8684c9e844be63259e9 +00 0067795ce117bc0a389397fc22a01cfd9422cfbfb5aa44131938a8c45e48e1d5a718539c 8fd3681887a7a285e63f8e54d84a9f4dbb7a344c5bc054ff09e02321a12f989de0529f4ca2b728221f375a8a99ee65580a3e332c932f799dd4bdb00887a0715817a22390031037c7ddcdbec0787cd3f61ad72c955b2fd673e604c0d464b39eee +00 019269dbfe4184249952a651a507584746c5b62c64cb3b17e0158aaf4d086a4afb0330c1 ab6f91ef151b8a0247d303856ec774269e01e2b49072fa2e26eb483b9cbd890665a77a1cea376f2b865bd8a4e805d141050e8892756070eb0fa7f6e70a11090e95d6a15acac4b21a22ad0697bfe16f9f964ae29cff6cd507f4f884d0c4086a0d +00 003835814de0d6441cd80a44e40350cc8bd62ffcc81e939a4410bb9c9259e30463c453b5 b7ddb5b78fe2a973309bebcab9e964fe74224ec215151b450a5aeb7a160dcc6044e1035f2d3c97f798fe955864a2136b158b2765bf79b3e3ee58ee28f0a6f15a2ec79247285c093b838e49d58d719333c9227cb81acf2f17840f6ba16fa8113e +00 00aee83dbed3b703cb6e60d51e373eb20e298ac005fa6a572d02fa1e6da0345558ad2a46 a9806265c99a32c125027d6f021377a7ac2d296699ed7eda4b31a02dbee5c5b3bf35ed1261f6c4b6e28354322af51046078e9c3f9dc50836bb9212ad208fc0ebe1c4169c8b6f1d121200b090da7a17aadcbf31e2f31a0c66b950d862b9c09b93 +00 017b65c66514019ff935e9d571a4e68e9ee4463b7b9a754b93f4f7741693f4399879fa8a 875964f6eb1ef0d3e8facbd865a30b6506ae31de84ed1884deff99f15aa2f3fe8f4ba18a327976973aaa1fa3b63837a6080f6952dc8e5c5d9cc884573b7dc4c71b42ba65059997333b5076f2429ffd7fe945acf0056b84fe365e7702c23a7d44 +00 017d2071f39ba35515a8ec977ddd36ca15983e15bcda626f15af61d87d58114f4c80a8be b6963cde97b04bc401e61e90bcd591993ac90f07e5e2131e7e71ffc0c349f0eebdbe3951bd2c534b8b4346e5bcb403d114757b0624c14116b5ec6f27fa3c197b3b7081e96fa0e0bb94666491c114665c042a662571da44e338558076f8f75b42 +00 011504659e12235855fe55220287a101e511d39a627f8a0d414446385d4a88f31507fe74 872ec087ef4f7f6fe16e29315ac4a40c7bd6e816d31ce61d56c99635d71721ecef49154b80a8deca945c9a4289d8989207a560f2db98d903c49a0f57de103dbebbac5e15ce438dcbe520a200d14670c164ac519bc91a81695208bde4867d9477 +00 016e4cbabb03215767249ba2a608708b78d7387be9e77f5efd2462467fa05e8dcde2c036 884dee9dd7289b3f539e87f493a0d4accec10942bf476cb66b60dce1b1e1308da016ca3928ae0aaad77ff9889d95ce3b07695c2052c48e1c159ebc6dfe871f8165125bd20a9c772062fc26e6480f9e54f89f66ae3fd820acd43195218fc61661 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K409 b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K409 new file mode 100644 index 000000000000..5a4b3fc3b740 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K409 @@ -0,0 +1,60 @@ +00 0011c6528939672bed3e8c905b7ba594c3ce95f37fb28044f210cccd01dfdb42c10e8e1a0b5d6fc757834ca7f08e98cbc52b0edd a9af7706d989bcc443ee85540a274543ff7846b21be70fcc9a59663ef2f69abcfe04f7f3f5bc2ce3ab122bcf6a4521c2040a77d8dbaf987d50f2b206234ea0dfb727191cff13adb6801e377ea8033f8a60e4259cfcad1b853adaf34010aa60ea +00 007e3b714496dd118d8f3f597961eec5c43d0265bf85723b0b9b0616977e0acc2cf686cb6afa6cdc19114e27ab000e762dfe467b b5b4b4d93270e41f3c52b2d8326659de5db33df00270eb3eb9d522a8a9df1278ba82e9476efc0105b6faf74ba09ec90b05c4ed6363a95685525f6059af940458c683ded1981ed10557cb9fe016a56b843bd0c6f7b994f5b24357edb4d239af95 +00 00182d1e937b037bf7f84144f7d4c94c935269c9aae7d500aa459a7a0ec113b232dcf282908eee4c84b8106cd38cdc41db3f89e1 8e8505f1339c053aa86e74aaccf8c483d3e3d47238302c1910e426ad6a6eb2377f628d2e38b48ce583b0d625e2c2d2480716ed8d5b768d32807ec8ea8e244a843370932c4b458f09c4b7c8828001bcf9521ee36102234900f2548e43b6f9aa70 +00 007ed09428f460724c8a5225a31151e031d9949493fff5703369c401762345d002c4ce424294baab22d9e71edc4f854510cf0e6a aaf4648d6bbce6e70e9bc35fb573e3fbf0803a6b667d68ca3866c6af8ce3c93e8b4b846b45c25bc4f1c952c9d34a89df05db8081eaf12e246425884961b19f0a3098f561fdf36c1f408c4a766e2c9ef85da1caaf5e616e916192eca68fcb353f +00 00390f05b9619c27b800e99aeaf61ef7f6249367d5cfaeae3c7b523a8b29153eb8a77132f6c4412545a842d6deb7b7aea7e2bda5 838524177def5dac5c692ed6fffea82976e882a0fdf0420d8fb9a4c2120f19a35692b86a9189a79685b8768e02dc18e20ea0db4919ec831d261553c0b55c38b0b704603848cfe316385b13dc9a0051e4519bbe2680343589d1642b0e0a93ade3 +00 0007d18652732596add3db31f7a0ce6020d03f3df58131b0c7c633faf619b8210cd309d6c0c4083aef1a1b6d2a756adad0bfe344 916008f01cf6a4eb48a43716ec7fa8e313e2e52fc44088e5cf34412d04656eb07fa39e103b60b07520fffc43e243369601087daf9eca37f48a77b06d5d110ccf3fbab369f0aa8b41715ec37d6f2b2083c28c34cc25bf750f10fe82415d872294 +00 002a91244ea4623b63403dba807d60b914ca3b901a2523244c322f2f11251446d3f15e869d086ebecfa1a39ce304e8b5c8de23e2 a0add23fd3d23d52ae804f4fb30dd0df76c3f732b677d0403f2c70dba911002f85b911b93b08b193da3d51ee370ff65b0b9d2c2be147b7b1c1be02bcfe1a2c64d5845a1b3cf149aa7f1f773c9d522265c55989bab307fb33da46ee1312b1441f +00 00068c56c6b5d50d1d4e13d3837d8c5e8ba2f825e121b63e97603fdfe78bb6899600ff0dc87b6b3b6868ad0d2f62b7b7a31603ff 95b5e24872ae5e4c804242b1d1f508ad620497881e149b83946a7f67376dc58c48761e44843946e66b946c38ce40f3111766b40f1e8a43f85523c43943e19acfb8bf4f57647bb6b1489dc0dade569c8720b5df1cd55bf94a9df1edc71713cdcc +00 003c88084f8b78446db431bd6e240a0c050813d2a763675b0ea869cbe183df697146cf29c03479af3d34587a95cd257027fbeed8 97479cb6978c0474a488efe8bc75e77773511111618c161cf3f398e39bf217e3cd061a53f2245d084f6b9a370ff7ba31169683416ded88e9ab7c34ee076a7665224402a7f3c44dbb22f1d6bd166139c54867510b6691e3e5248d9e90b99a6ab0 +00 0051af7b63bf3297ae20517faaa1552f4fde65819dbbff6a52721611e5b7dc1242ed6e69768cdc37ea8cdfd1a5971f06b84b5803 8e09ed0f268a4ed3c7110873b2f17c86055f49ead20ad490e97cfa96cebde7ec42b3b896ecfe4a5b2b88fa950098a170008845de96723006e2605868c19ea1e816dbd45e923aad2ec4d57d5d7fe0a7666231b7f5a9f596acccc30e0100e49534 +00 003d65bdec48972d03811b78150a06956eb22d337dbec5416bbd8185a6322cd8c0ff8000210dbd1326422289071cab65175f5d10 98fd1af831cdc9de6f1f031de937997bfddb02010d8911f81258ca810cfb7748d92036e4a00e04545eb8da049acaedb30f682840dd3e9e2392c5f7a026b70b5101eeb00e390daf9291b5c95bddfac7b38f74cc7dd869b17e49be9808f73a72c3 +00 001f1a8b5f35dbbf82c102df550c72216a243f986f0325920f6186a16d1da74228cc02be6024c7411160c183c923c743354f9438 964e642f6b01bd3bc1758d4918ed4ec19aab70495e70b7f0fc73077a1b6aebb70724f05b5adbe40bd52780331bdcca8a0777142627df424e33890f27f84d5a9e51641873d1426fc49e530fead1fe0792a149bd5d7cebd19be43adde2331a9df8 +00 0031dc621200cd174193d95e9092ffb86189c52cdbb9ed937593f2cde7c4a0264b9100e1b8407336c8dfb5520d28a18dc4e39a89 9481c07ff834ce978a9550ab8075b473887469f7afb8d21d825b05e920a6a0cd0a308b598f1edebcca48b6fe6e5a104018a5cced63e53a8b1407a4c3ef407870a611fba7551dff2199e5279e18b6c8647be47385c1f227f7313abb7e027667e2 +00 0016e6750245a88340b0f0665b890459f8038e9b1366f2fc1326245a88d4c523ec94429f21869ce3dbf75126e58f77241c99efaa ad64d2f1f9d5255d587a2f3c1aa3c2e252fa8dc0744dbea4828c8d85a681aadc973985dadf32e10f67159d99f51ffc840a987efa5c0f0eb03ff115e473d30317194e3d2e9eedf32499408df4773fa94397061bfb20d5294ea8578c7a828c9249 +00 00788fabdafeebb72f6385301e30024b56639e629a400f9c50d402cfc9b5817844f06a451fbda29c7ece41dc9ffcfc625fe0ff0a 980ef3c54375a86a9437454da99f2c065991c0d1eeb806dd74122f224e68699723ef3f8c1622eef68b9ab949ee285c2f1958ed4b6b96c31c21b9c19869d69b54fd56ff2322169b6488dc4226412e47bf5fc266fa7bc3aee17669884b92c36777 +00 001b8dfd64563dc219d6eeb53f2e3ad1d771140d0960b211dc1f757af5e297dc7548d6133ddb574711d466688f80dbd65a7bbcdc ab05aa9dd129adbdb63d35399cf56d37ace28653c257cf9050130fc2ba83efb56441a5c130c1e9ec749c7deebd54effd08aa1f918f7e2b45d6e59181cbb928b62fcc0fe502806a27399f5c68759b72ae5bb9d3f958400e44a7eb76044c329b0c +00 00422131829608ff730c24ddf7e8b4a2600eaa9681eaf45432daa7d41fe2fb488fd0199d431a1ed823801ce21f4f01a4dd4248ca aec995fc986be2ddafeca90be2f027cc23fab9514e539d7e8a6a2c31b7fa6c577552d24fb837d617cf23ed16877e2ef510153df0717af57ca1bd375e21e6dd80c4322a721c953569ad34ee08f9239f125213caf4575dcda0972b6caaf0f24270 +00 00095ae8e4c7e55eb5da01acc05ecfe72a4dcd8ec152f1c8dc165014f70eb4e4a7861aeb2b96c418b2d4db58659e76184e013a49 9332b75937695839d48dc8e755a3e07bb281ba5f79174b108c663b3b3a6b178aa379ba302e4ebe5e55c8b6a321470387058ca4e410903420d057cc1990637a0d67991e53789dfdce4fd91d5dcf795b8369e2758bec158521c0b3d1ca1779e43d +00 0006f2075bd730f34df111ebda919167b1d3358ada32cd6747cb3353bcfb814a77ac70cd51b31a0e538539453bf9eaf9d8b384c9 86f853adce803c7a37da8f647024b7f6529a84febb83b99c505c5bb250f68b6a969e3f6b18419788ff4c13a2afd58046038b41d978b7492209417f04adcd5ef49074f0041684b19462bf80f1a00f93d9e25d85d2a325c3a039384f642c6add68 +00 003887d284e9ad17d38bc6da9d83c192a434c509340a7f233cebb032b09ab7c4c6e8730b4a80844898616c9abcd16b753c6bb4c5 96d0591e8dddfbbbd893503cbab684d4b5e785a68d4c370910bb5283cfd2849287afbb64e9e608398a97adc877100ce312f3cb296c2d23dd7a62cad07c8813e6e4062d14cabf6c8828cf6bc478d44cea548f03716d3bb93644ce1d1890ffc7e9 +00 002ea5430610864257c9dc393c3addcd0d8d5bc8aab1067643b08857210464428aa85cf1ae6c743fd2682255d4c8eaa46ca21e73 8d94dcfcbf3de4f4b4b63016ac198a439daf2c1bbb622c618aa0410acc42225158dbe287d25e7f6daffc6e4bb6a80bad14b888bf4bd6084548944eab23980efe26d56dd8606e13392a3fb9bfe78603cb01768f2daa2a90da41b69dfa262a72a7 +00 0062c757c92eaef41f5d81169ec4968145b5aa2bc1d2a3a5fd000634777748ecb93677b3da12e3be33272a8f0a52300f4a5a37c4 b84013f38782b5d6d2592c7cc177e5a9d1ea470ef6ad449816916c939cb15b4a717de25204a3b1b022e8155cabbc9a5e0122ca19515e061258a1d2012b4b364c03464746eb5622b21e9a840b6f17988d281374c1af522d86c7f9837dda7c1e1e +00 0048a313c0c11489939fc0cffc6ccb9f179093c4e13141b92dbbaac441b7ae878c9d412066e95615174a24692555cbbe904a14cf 8789ec77f97ecf9f7ea34d96d44e880eb31ac124616c1a63efc2c444acc2bb547f6b529f2265fcb4fc4fa44dde67e18315ee4c493ea44fa64567c545052d0e13198fc33574048d58eb0a2340b88a63c97830e0273774d83415308fdb1c83cd6e +00 0046e2adfe5d3549e1e6fa1fe69a7cbb4ac9b111c8903d544268f8318b0b47d4b78fe3e56eb5e639ad5382e7cd5bd4b2c3e70ef6 8d15cfc3bfc5cf25b8acbc9f91c756a460f5bd38c97dd32118e106b87664624c25cee08f914d2ee7bca9a3f00f69319215d164abb66ed0bd9f42d70eb574ae255147936479870d51249c7d982ccb32cc2483df1c3af48bd0133a9d63e40ee434 +00 00480103fd6180a431c837643566706e2b9597de0a1346a224d176a5b2c54aa4d064418ed654a5d39f4773fb509f86473ebb373f b6746bf3c613844786c1841a155a494465d4584418ab1fc0b9b38bc52829bce40bb41f64325bc619218243573e5a394713a2247221f1ff555aba097a648fbdb095149af88d032339f1448b04aaea1e0ff00596102a8e1987b6fc317f31c3e110 +00 0013c489e8311c6bef02c8f58903b2ba2a98a27cb935d75a30d320af9a14fa3cbc6adcce09235a9eaf333dd05f4b2f1694985dc4 93a93604bef68d5c7d4a954491796207ad63f69cbbb9c777ad2a228f0e35b7bbd3b33d38a7dada65faa3b79bfc16b07811218cdd24a55a94842984e4dea903ec0989b474d0fd2a32ebd95ffe66c19eb71a765d4cbe0aa67f3f83219c5d2a549b +00 002419bd2200f8e1d87db848b0379741685e680d9affe693eed49d82931030b6cb05d21a4965f4e1df2045c8513a8f574ca9f2e7 b19b0e94a4f7e0bc8b1845ef39fac62395bcf356732ab607c931d6c115bb48da29c31dd1ddac7b516af9bb01b90dd4e0096bb0d88ff1b971f1dc52de379204c91e035dbc11125a833b798cb4e97d8ca8e23b8400ba3c696d33cd76ce7c8fafbf +00 00722951879a65bfcb414e11712ee9431eeb32319e0ff28601112f89276ffc2b96eb65c7fd77d023f09914a53e2aae2c84652bad a69ac7df1ed206c54fe6cba89bfc81cf18529d4bd061040de96c04ff12a8db412fc61603a1f00b457dbd9c2e803f125b08562b19d41737f92edbe7c1ddb18067f63687ded66ce369d5733ccd45de3e64230d82678a9fbed57a1a59ce1cab0205 +00 003f5b5a772d24bd5454bf26759dbd433fcc7bae4f5c593664c4d75da0cdf9430d7d9162bce3d7f6e13a344259da5a7d6a1635bb 82e19bda5ef2b066df18f725701f9077b62ec1a8ae6f52f292f02f909015f2edf3e925db5e9ab6e5f19749b7df68d1c50ec6ef8ac7e2e222c9b50cc11306402a57c5bf737b0e41056262139b2a9d1240a76516ddd61a7c17beb171965ebc411d +00 0046bb4a141c9099d531dd23ac440eff1f5b10f7cf34920b6b702311d490d25344c665ed5211d401def24986c8094165d10f8934 ae3ae7d6878fa1399c851ee71b274b87ef2f1eeec91278a7e1efb361fe2b28b2013e625f155995727102092dab31d927027a9a310f423288e83c448fe0db13136d18f5ee03d4a3b3a6f551425fa04f45f9d5e64ff714394df7cb9740e4da8574 +00 006f2c6e9ea8109223d9a349fce14927618fc4fa95e05ecf9aba1546619eaeaca7b5815cc07e97ae8cd1e9973ac603f84d838393 8c4ff7de12969ebbf5ed20cc50baefcb1fd72eb7a7a08baf0cf4a32c99ac4958c8da92284881b0931af2c6d0b5563889172ff99091b49fcb253dedfe5576625859eff59b75e4f1122e6ca251c3fd03eebedb7143265735bbf3e9f74a60089355 +00 0004212b7fd913d794fc6bb33e0276e349c052c969ecbf6afc89b28f75a599a9242acf74dec9f374361ba296ba42a38407f9b7d6 85be22d813bf1cca9241b824302351d30a8b50dadb551b86d22d10f633f62fdc58cfc02ee74bd73ce09579ffb19a0cdf0b97755942d9b77781ee2dfef9f491e142fbaf0d8d5b58531a6b0b732c7dee6527b38197040808b5098fade53061900a +00 006baeebb5ffc89c94c3e8b37b9b0904e7c4b251d204894655bf3b1235710215c29820b9d401c9ca7df1404d2d62d708aafe208a 97c7f6b951073f4f7b5fbaa0cf75cd93ca7e749ccb34c6922c86a7b57102565eb9e9db3b918cbfcc85a193f9dc090f4d03dc8c81cd4644b8c3eab9c3e79be5d2eda8785a9a26396eaf0149e460dc177fed95eb0b0b51eafa09f247130985f36d +00 0008e5f66ba53e7caad1feda122a80c32c82d2c32a7237b8ee8ead44ea8f2f01d77c7056b9dd60b92d051f060da8532c1fd0e8f4 a731ca427acf376ff37ab00d1d1ea8885a744e908baf86bbbc0eaee4782dd1c2f5f34551b17a2bc70491ae9db3d5933a04851ec83743993e47fd136f4fcd26f66e490d774cd6152857335dd069a9789c37e91e582679dfec52ec55c5f8354779 +00 004ecb22b44e809f89b16abb10be062c89b41ee34e110403e42a20ce59a99afdc22f6f6dda56e1d9d1b8ce1d057f390db111def3 98a66e1ce7674f8a5beb850e1d0d16bd7dcd991f37eb7abfd1ac87269b32fcb9b91b87597036d4742c6c3b7fb879560d11ceedf415b66cf8052dbcf618816ee5f27f7a9efb7664b0ca862b4ced9953747fcc03dfcd87e621093ad78e89649970 +00 0051f9500c15ae73d6d479b9f3d2caccc2039d8d03820befc2aae3bbaf65d59bd9cb3c4e3aa8bed5b3acb70a5566047ffad80729 a4a50871ca96f2f3c66f0a79d10b5035a3edef9707cc7533ae898d8ee771e3503d14c159466c7a5339b47529d34b74b41535ad1f9779d71804bd5b09f57486821230a934e74c8c6e5e7947b1e57448586fa8e6cbc57595ff3ec0ea1b2b2fc142 +00 000cf01dc4462cca764f4f8cbef48c51980737b9b98d1384b8de9f4c733829db7718a9b5eaa46a8475c2144fe4454cb8eeb0a443 b7bdf177664ef5b75651c71bf3d7742afc56114a54e24e44f9dfbb8c1f5cf77c81d08bfccd050317a828a38641678c94030997ef720cd10fbe6c6e01367b1f16a16acd46bd168c057a655aa84ac5e0059c7d9e368c3728200b3bda45e6426ed1 +00 0063a9a565497974c6dd459bea0d1196d74f263f333c31b7e8591499960e1cd79e2ef4cc8709f6d54713f873b16e7b0be42f71c8 9232976994e507ffd55176f84ac0698ddd35a69ab39994526fd88c2447907768bc84eee011ce6e611a9ceda988d84360185a84c54834f78ade52a01d4021bf4e9ddd3c7487a5aa2af600ab8f4415da9d5ef516f0c8dfa8b71b514273741a8412 +00 0041074dc186193d30aac7cc6d269b938ab40b257d095e54ba79967a377a91b8f73671470cd07f0a3d1db7cf0a31ba9070625e43 b236382c116164463b5da91107853417f454bb7cf17e5b87e3841b43f81482df36b3039fbb27207cb0c2f7ba00292245134ab93fec48a9b1b3ab4567ab787755027add1cdad4b2aada33b457cd4daeb49bd845eda5130bead5f03eae0ded9b09 +00 0010820db54ccf0226161aeaee79cfd2797f87702b4ee91adf8543b3c9e79579d0df8a889e366ec1e0718e039b87a37c24d620e9 8a99867d437ed58cf8744359dd0bafdd8f50da59f23812b6032eece1effaf1cd7cc60ad17a4b0202630fd2e69aee9be7138d87e72fe6cf6acd4d87473d491b6632ba07a664ddd312d8f6c07362379015856d00307da2bbb1e943ab00c639f13a +00 0059d2a06e8bfd5e14a9bc8777958b85be5e97af892d2cdeb0ecbd2d5017952b5042349db5fedba2e26e7b85bbb31ad313d99434 8b859ec8e38e8297627d7ebf656239490823e5176701e8238c71c8e5558177aed6ecba79d84659bec2c0d15ed77c0e3604032ab8c5909321d0a7029887bf09f90ecdcb05934145e6cd5fa2b15e84c7375463806abfc1e76342589ba9e2b0dd01 +00 00405590893cbbe18f4ad99df28b5f9d17f8f1882269aff0b7eee9392859d68927a99c942a3075269ddec6d69c0df2d76ab9d801 b492627dc793c189c310f115508fc8ed0daad317a4717635ac9a0c4efc438c9c1ad7de33fc50c73f69fe22689a35586415fe88eb8841efe1626f4a6e84a817e12a27472868f908b24f5fcbcce2e6a977f56b1ea5b41f59c2a0324de5d6f57fd7 +00 0062bbb4f565aa0f23b88ab9029d33b995729d10fcfc33ba7c4051e2fbc72f15636a834e3ebfe604b927cdfc89f53c57f36890db b79bc4b5706ca67d249ac71e7d13f63a498b542d51d375077e2825f9f424f1874b926f0dd65bf102de85f66bea0c0f650d6fb824e6d81e47c2ef81ab4cbfbcf082f46209e81705b0e6958bff5f1b470ec06c13c58812258290c50cae77e43212 +00 003fad7031cf8810544a3e4bd1382c0a2e22c5a9fe4804ce67b27591fc516ee81dbac841d399327168aa6abd79e2b5ef85df1528 87515ad9885fe86bec829f8c1aaef31fca654c1df8d1139532064c8fc36437b4e0fe413163d0f06695000416adb51b78165dc28a20febca4d19c418376d9bdec328f1b68ba57c8db7d30cb2b8d68f535ad33cf523f8a3173a1c2e3be8fb8446c +00 003db41b4f637fe7977c90e4f1a21799baaddd1826c667102414877138436cfae1b9959842b8097b5276f15f2b982ee59df263c8 83d84756562a1c1f8707fddc8b1e7b6d1d2764650efb53512df6d4f123809b678ef75eb994bf4f55b96b706a6e18b8e50412c5b1e69f3674a47a79b37468c146c306d69266db984d4c0bca9637061044822176c89a259e03c89c076e5f5180d0 +00 0065b76c6093d9c49591293471286df1a4444e60d9d06cfa114e175afb5f119d2abeb273b0596019a0ec5db5b5869f2cc827b364 997b58abee57f0a5bd997f6d157f1d9134f301d683133f548a9cdad5543a209b170bcd02b0aef63812fcc5793b39b5a7097f2e64342e1fcee5f4b01d8ecfd28efb599f88e434aecf36191c67aa1a8230c90eb17d88894812f16ed98eb9570719 +00 007e9993f3fc1fdc4c376ef77ecded96006ac1159740bd1b2dc6ae3d97e15a67383f1fc931e460b9af3fe14a54e47919667ed06c a3f381964d0dda9894d3f28c13641befe33efcf6ffc1e3d1f5487d82cc25f15cdf7066c27fbf3c9f553a7cf8847e0d0412a3410df2f65f3d54722521ba74d03c26aa9a6dd76a8e32aa996c473a1d8045e4b5b55b2a0c6727d0e3949080ecd0c5 +00 000c11e2979498695c660a2bdfd105b115bc4ff8664ea15cfb40c725406c6fc9a13027bd1d72ffff6258f29e4e19b845243444a7 aa1a2d81c917fe9db8e771cb713f945a33c62652e2aa66426c263d495d119085aa9f2fecae04b54db0c9ee44966bda560d545637c187eb5b56b03aa8696344835e2298d043baf3f87a7ef0f3371fa87e1f445af560f726a3fdf6828e77691fb9 +00 0068dfc23c6635bd1fa1076dcbd456ad6e8df7ce7c1370fe275803befc4ffad007fd062a61cf1d50b93aeb9afe1aab47a65af82a 974c5919e81330cc4e33723a4803d5c574c6977df9072ebc6bccf6e589ce936df4951e6d04d1219075c088119dd865cf0084471dcf33ff87cf929b23f29162248d7fed1004b9cf907a0942160baa843826114725b88aa4c782f44ceaf9064d4d +00 0040807fb888e1d9fd33604546656a493629d94d4a0a9de2608962225ed158167f9e2438abe2d12a11e2adb6c2b66ed78215b0b1 86eed272e6cd0c0a592b414b60b4d88731a48e9daa15b6f3d44d602d44522592ea217857cf302949381c4769dcb5c1ed137631c802718ac44695b7525696d384870d17d6019d4986ae2a5779eefd6154f4905e276602dc0d12ccd6c87dd27410 +00 0033bda0a02badae08fe40c239b9d59e5bfe1c4d4b9b7a5acda6790bfd77ad08dde5e93a2da80ec54a7f88146d72218bbb88aa10 aa2d3b4cb78e1f824934fc4d4372b93157cd46ff67285b52fab59638818605288002224ad978d8ccb8911d603cec241911a8810ea2a2645dba242fd2bb908646ac73a36c09a241718b758f9eb8123baf85a6b9881a0ee841a37fa04e41d502a2 +00 004ff431769d26b8837d3e1295f5464fe82be29edefba76323e92078a6483ea0daa96221549102509a1bdcfd46a5a2e5de10c39f ad50d2fc0da078934a7a2b7e1e0934f50d436eee90f4a18ec8552ea27e889a6da22717973364c96429c481ea768f33fa1892f26311d746cc9edc7f74bcfc533dc8c2eebc2e6ce2b8876603544b628ba1cdb08698e252f0cbef184a02358c476f +00 003f85ca1169ca7e9df44cbc6bc7d2868c9d94e8f8b699a42ca492dca0914eb5789a9032218dcef7f95f959c9554a1cd83360439 988a3dd727a2ba9f35b3205ce08ba6578b28db695789f076e8c01052118e8132601974c46e6c9103aeee86fb7e4dac150035a0ab3884f454023b327fc41c0e430dcef41692b6bca02d801439cf75125f418579bbc20957a69dc0b8f44b2a6d35 +00 003a97deb36d68f81f50c8829d412ee5de7f9d775633cb69c09dac558182039e275fc258240517a7c4aa592e364765321f27cb12 91d8b9a343f35190aaac781082f14635cb4f69439fef29576a00880f7ed8a8fb8553692a4184447faa48db0a2f92e934043a2ba47a985666a27b490eee7df64a2dd7425ae875cb337849c94fd4d8ee6dcfea6728ba9a34db526eceaee7427db5 +00 003b1da0ffed24e1a3b5ba22bd684337f6b08053591620541bdad50c761d66201a2cf21a4cc636426456525b598e96baf97d9851 aa3df3b8222bf267ed19f6f38d2c96605dad51ab6d57f075f1e578ef46d9c12800119d0d1766390cbc450dff976214b10063f4fad4c96f7d2fcea033aabe792a11155afc62a6d64a6a34486ee267a39d8960b9d61105ac9f5ea9fbb7d3d3a05b +00 0040bac7e0d3b54c7753c79d43469e310d876015d948fac4e3a9765444754476af72330e88d79ee6119697aafac8435ab5690754 a461dcbb1c234b089edec30e62a079937802d8d89a67ef01f6a8a45943c4a8d64c7cd5d1f078281cdb37fc7f34379efc16db791b1c91d4de9ba07bab3823ac442cc3b99f4b14b165baf0a9db1ef4623d0d14f2c70ae771e6d800a45b3b002f30 +00 0025b7eb3bdefba3c5134438caf968f615b315204f348006f82e8d61057a8a8a853230cf0500f9d0b8c1551a59b9184862dd2ed9 8949193bd465703ec6cfd5e2c1d629579b79f087fdb82a3e13c8c5343d72cfe8d652c4726474094be52769f71274766207903544c6914c0f9520c10c8793af689fff24ca8dbe86a26e76ba6373223a77e86ca31961ee11a12c1cda77c9ef96d4 +00 00673b3a2985c95904732632e5d988d8d437a60db13215bb6aa880b348f011c609a1e860461427a8cf0d622abc47f910f5c97ffa 9154e6e5d3e05ddd5d8f6ca6baa1503da68d9547f4a9c7848361ad976e0b9be4195703f05ce8ce8f9e4ca8d841ea170e07e1987f3025ca7a20f5c3868beec12b8bc1c22c312fd0963befd5b71c875d5fb805a38f8c17a10b1be0b8d3a515d2e4 +00 000db7dcac414010b816236cad584dabeaec1da76c97182d1b62f87bb7fe2946a64d10430571b2b29ccf2ef72c969a9f045f1f3b 8654486d237e5dae6a29a2ce8d1059abe85b8c95dd55de9f78b3e14362fc85e097f8c01406fbfbef977e9c56b5f245b0176a897697bef00001e5918ec98484aa970f8ed394ddaaf1de3772e32f351698f3698c24fb24885d890a0bf9a8514e0f +00 004717efef16e1ae267e155aa1daabafc68515aa391dfeb73c13d01f3132bd22c984228dddc4dff4c39979e7585acd3f730cfcfa 8fab55e44c17876dab8fc8481cecdecddf6d56c5d0ab7b4ab7982b15ea3616987674008b9407e3855719e65a8532ff83099644e760ab2ab209c20132b9d8e18838f06f864adb117d21b50ab6ff8d47e486fdab1e0f253dd0450cf83215c841ae diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K409_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K409_blst new file mode 100644 index 000000000000..9a1478c695a6 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K409_blst @@ -0,0 +1,60 @@ +00 0011c6528939672bed3e8c905b7ba594c3ce95f37fb28044f210cccd01dfdb42c10e8e1a0b5d6fc757834ca7f08e98cbc52b0edd b8357986cd7400d061eaa975cfeb21cdab484ac671afcf2df1b8be83423a016164e1fe723573c9f362cd4cdb0bde9249168cbc0aca2dca16270434e1d5280e1402b97274a38beaaca1513e10f67fe5129b8d344d932e3904a22e5b03b4f6c2cd +00 007e3b714496dd118d8f3f597961eec5c43d0265bf85723b0b9b0616977e0acc2cf686cb6afa6cdc19114e27ab000e762dfe467b 92cc63ac66aced3a70cfcc916b70aa2092608dbd6cfa46b98850b8936665dd49b00871c3c19a64e7e8b58e9d282d411316aa9bffa12f51387c954db8e6e269d0f308722546ade9f1d242f78e2769926036318b4d18394a8b3adf40696101a9f3 +00 00182d1e937b037bf7f84144f7d4c94c935269c9aae7d500aa459a7a0ec113b232dcf282908eee4c84b8106cd38cdc41db3f89e1 8cb8b809342dec272a56e88e785c77a746ec76568ad06d9a98486daecf29e621fbce611f7b8bbfcbb67397f308a35dd006c3ada5014da9da8f85d67170c8a993860745c32ce389bd4db7111e87724df4cf5a917d9efbbcd9f8873b1f6246edb9 +00 007ed09428f460724c8a5225a31151e031d9949493fff5703369c401762345d002c4ce424294baab22d9e71edc4f854510cf0e6a a24b79a130b4e6baed0fea5547b2006a5280a75cdcee60e637d4421671e90c6175f168c9782382f70128cbd3b13bc20d146c9908c21ced76cb8adf4c5b44b03366724151dd65462319fe5d6fcdacf92aad2b1bf8d422be141fcb2fcdd9a788e2 +00 00390f05b9619c27b800e99aeaf61ef7f6249367d5cfaeae3c7b523a8b29153eb8a77132f6c4412545a842d6deb7b7aea7e2bda5 89fa3abc7662cbbb5ed8463e44fe9925fb7d4a17e7f8fa852aaf2c1208098dcf263b67d4553984985a205a67f14ee7450137f5e8187f66bc5cf50af1b1c0dd2ed11137c6c3eb4f62dd2dfcb7805a3c296fd23312f27db7cf7c630d806ecbfd58 +00 0007d18652732596add3db31f7a0ce6020d03f3df58131b0c7c633faf619b8210cd309d6c0c4083aef1a1b6d2a756adad0bfe344 a8ce10bb1bb22c5646e40176d4af6d8d390abcb6e740a80c048973f09de629ae0273784f64f2dad5edb142a1972670da069463390bc48881421359b202fd22438ae9550a181c2cb28b693964248fde3d7bafe2ec746b651322dbf8e130927355 +00 002a91244ea4623b63403dba807d60b914ca3b901a2523244c322f2f11251446d3f15e869d086ebecfa1a39ce304e8b5c8de23e2 aa2e36da11e5b9280d87a6f9f5a9a2bb55703bc516eedbedc4050619f1ff33ca31997cd92a916ca1658a42ae35f1b8080bdb5d5b8d408b9c73177849e4aa829f60fe6a65fef3445d27963be0122e5d5299469bf789e05e568f00b281f286707e +00 00068c56c6b5d50d1d4e13d3837d8c5e8ba2f825e121b63e97603fdfe78bb6899600ff0dc87b6b3b6868ad0d2f62b7b7a31603ff adcbf9f5bb81df5c7fc1ddd9fbfe895072993623bc072fe0ae1781d34cd91f897127c066ee951541deaf8df442af5f960ca1d7da07cdeea52b8329fbdea8b87ac01b298a2d719a816829847c8536fb112b6300c6565bbe9f9ccc459d8120d33b +00 003c88084f8b78446db431bd6e240a0c050813d2a763675b0ea869cbe183df697146cf29c03479af3d34587a95cd257027fbeed8 8bc1aed0d9fc6af9437dbe83dcf26312473b5d9f450a97b8355241e4abc621bed9578e9b88a817fcc453f9fd0ce9a20115b39a4e471d4829710f525c1e4b00cac25a0186285f2657bb43ba9ce32b0f2819473abba731ece026d7e46ca4aed3e0 +00 0051af7b63bf3297ae20517faaa1552f4fde65819dbbff6a52721611e5b7dc1242ed6e69768cdc37ea8cdfd1a5971f06b84b5803 8e94250e67ad290596648840556b8eb679879e4ed1ef85dc1a35e1d83c577611757d4b87ab98caceec346a4d18d5bee30bf26b7abe08b06c4319a812b3ad3b854be952d393d5ba59d4a3217737ddb16a69657ea8f508aa22ddc7d67cb5458ba2 +00 003d65bdec48972d03811b78150a06956eb22d337dbec5416bbd8185a6322cd8c0ff8000210dbd1326422289071cab65175f5d10 a698b8e6b7f82ca0b66ba2cffbd08a35e6cc62ed942230bd968240694356efeb4beaf4c268efb17a4e9ed5351962179d0a33cc144182ac4bbda7996893d5ac62d2e25ac760f133f166ba12fc3ffcf6401e98d0bf7e64a4b5301c54fabc1f993b +00 001f1a8b5f35dbbf82c102df550c72216a243f986f0325920f6186a16d1da74228cc02be6024c7411160c183c923c743354f9438 b159b66e25ef9c82a505ea586f9f9733dd97d2cc25d72fabd0775c9eb40b80163a01cffc15eacfea3145e513410f41980f4f388039ba5c4c3f9909fca089fdbf3a684d40edc83a59b51647ef577120cb12ff0bccade6e781b75a711dc0a8ca03 +00 0031dc621200cd174193d95e9092ffb86189c52cdbb9ed937593f2cde7c4a0264b9100e1b8407336c8dfb5520d28a18dc4e39a89 97f043cb7693703a50eb2c71985adbf95f9bf2bc35b8276fe2810d230de6d521b05075cb751c99eab89983e23e2c0073015913a174f45f4654267993a4088205488602529cf67a967db9fae979f148514cc4284528d83cda22d62d1d04cc8641 +00 0016e6750245a88340b0f0665b890459f8038e9b1366f2fc1326245a88d4c523ec94429f21869ce3dbf75126e58f77241c99efaa 8ba46578afc1f61121de861209efe29eb61ead34ad2251ad4d56e55fbbf17c9c7b1058dc7538e4576498cebfcdf2e76d00cbd668fb6c32e7d2a93036b0884102ca0b0b827f6cf7473eff0c1e4d15d3d7a4043d5da4d6eb0d20a322fc70d5023b +00 00788fabdafeebb72f6385301e30024b56639e629a400f9c50d402cfc9b5817844f06a451fbda29c7ece41dc9ffcfc625fe0ff0a b16f16bcfae5b860f3d080f28465a6638475b5f94be9f8c6e22af50af442f5205ad4567366a75fddf0d8182679102bd405db7e1d99b4eca24a073d5e8062bb1a2b650554f9343c691c527ec332587b3f3d982d954074f460380e6a1cecc9f028 +00 001b8dfd64563dc219d6eeb53f2e3ad1d771140d0960b211dc1f757af5e297dc7548d6133ddb574711d466688f80dbd65a7bbcdc 855d5b71b6d42888285828dfd1364dba70da13488edde49ef88f7c12d7f4a86914fca0fb00183d356bc2e32f8556cd0f0cc75c8d52c9358d7343f630c59372202d30d90739c5fdbc349ff4d57deb973692fb8003166546fdd3336a1b3fbdafdf +00 00422131829608ff730c24ddf7e8b4a2600eaa9681eaf45432daa7d41fe2fb488fd0199d431a1ed823801ce21f4f01a4dd4248ca a77faeb7693ac1fcdecdf337c07bbd5df7669b661ceb452403e869894177d89833c3d9ce26b1a2be3984e44c0aa19b8b0337e90480e137c4771d4d2acbf1c5bfeb8c2d773a23c8deda70e2815790bf3fb5aca537533a9f57288ba86dd1776111 +00 00095ae8e4c7e55eb5da01acc05ecfe72a4dcd8ec152f1c8dc165014f70eb4e4a7861aeb2b96c418b2d4db58659e76184e013a49 8bc9479d2b4c25959a2adf5af3141c63cd50b824b700167828e30a8d516f8265dd193f2ec32b06db9971fde94d3307f4117845448416e2172b85989ef26b60021c5f13ca0a14cc316a06fa81c670526aa2644a0788010b1f4e255863673f264f +00 0006f2075bd730f34df111ebda919167b1d3358ada32cd6747cb3353bcfb814a77ac70cd51b31a0e538539453bf9eaf9d8b384c9 b85be09e6c9d4ca1aaf4e44c0d5237b964968c97a4f002cd6e0bcaea9cec8eb5d9daf7a4f3c926501449656e062e67450d81b9d7ba0119494bc66d0e3b35eb5b894ab2d782824c1e8e0506bd26791a322944d52afff5a5489d392dca2cd6819e +00 003887d284e9ad17d38bc6da9d83c192a434c509340a7f233cebb032b09ab7c4c6e8730b4a80844898616c9abcd16b753c6bb4c5 8c21ee7fb44ffd88050f24a9b67da9771404d581e45d88c5888c4abf4b04a0eeacb6c044c2e7d7e7c5390e5120c801b009aaa2f87d5039714f7577f4bebf1c5a343aa3c047a93773b1b285bac0ffcd354049e2774892bef97d89e662cfb92330 +00 002ea5430610864257c9dc393c3addcd0d8d5bc8aab1067643b08857210464428aa85cf1ae6c743fd2682255d4c8eaa46ca21e73 852c7fc5388278aabb734e1f12e9c175099c479ee85ff892cabebeb1dd87cd49d95efd448a47e3386cdbbca380a9d474054349558490fcbe59ff3c6c4284aac7def0d1295456c36778e6061a2f427849246844006a7d76b190f10d139de286d5 +00 0062c757c92eaef41f5d81169ec4968145b5aa2bc1d2a3a5fd000634777748ecb93677b3da12e3be33272a8f0a52300f4a5a37c4 87f9bc63054ee6f8883f227f87040d8a3189c3dcd7b6fa4ef3752d2bcdc69cb06dad3266ffd02bcd5e7511ae04b96cff16c7fe2d5f1dec3ad72513ab3a966ab85c53b30fc407e4e5cdf087d6644fba1d8d5e49edb0dfb60851591e553c222395 +00 0048a313c0c11489939fc0cffc6ccb9f179093c4e13141b92dbbaac441b7ae878c9d412066e95615174a24692555cbbe904a14cf b22a95564d5f16ae78ad351e6cb59be3c4cf3b35ae91379809403c8684afa0efff01319b0a9724f592a9a586779076b817c09e61763db9662be6e9245a91cd53aadf7dd9733b9f410501d8315b8af84a24f1e05e0154f08439354f752fec23de +00 0046e2adfe5d3549e1e6fa1fe69a7cbb4ac9b111c8903d544268f8318b0b47d4b78fe3e56eb5e639ad5382e7cd5bd4b2c3e70ef6 abb7d418c2594df8c2440c9974d62d88ed8cae8645edcdc295df585010998884dc5089d8561fd62ff0c33987c18b8b4a052d3ba86281adfe5e30440483ef89144a5fe0782dcefa8b683d4fd7a76bcb8b02962bc0d9540dfef237673522ecc084 +00 00480103fd6180a431c837643566706e2b9597de0a1346a224d176a5b2c54aa4d064418ed654a5d39f4773fb509f86473ebb373f ab9ae2fa2542745dbe93cc85f8bbf12b7af6c51a0f2025f57c8768d93859fb4534223c6f37fb52cc8c1afb0488a4046e14c22ceb1dfecdd1c4350b821d9bcd877c7e406d596e11c0ab8b18711e57363410d2bd86b4a550e8b1e893943a0f73ca +00 0013c489e8311c6bef02c8f58903b2ba2a98a27cb935d75a30d320af9a14fa3cbc6adcce09235a9eaf333dd05f4b2f1694985dc4 af43144c79aaa859a7151008faae390e9cff6381784e2d75be78d4f0d0aabc11750adccfb4e5bd0b3f4b75aeef24855c0d7b39aec65f3959492271e9a5be74a8f0cee22a1a711dae790cb0ddb283fc3c33fb26a5aa75f78c44ca534d9e9fdc67 +00 002419bd2200f8e1d87db848b0379741685e680d9affe693eed49d82931030b6cb05d21a4965f4e1df2045c8513a8f574ca9f2e7 b8c24a377deb5197dd14b2071d8b0ccb052bbcd156ea70445a05b2b1be2654ca13e8fdb0629a728bd6206a45dd5039e619c7cf7a785b3a2d424944a9911a7fdafd7a304f3a7944f2721ece7c13c4ce5c4715fe5d135a0c67b0bad1c53cf5d690 +00 00722951879a65bfcb414e11712ee9431eeb32319e0ff28601112f89276ffc2b96eb65c7fd77d023f09914a53e2aae2c84652bad a119e2f113012f111b8b93d3406c30360418ac99cc773b92002a3d11add0df003ddb71b2d7a90ab554571e8df4d98fa915c3aa25368e614f5a7c6b36159cd264a03997edefde41f480537c9487a765f8614263b4a28af4bf6cf93c33f3c8e4f2 +00 003f5b5a772d24bd5454bf26759dbd433fcc7bae4f5c593664c4d75da0cdf9430d7d9162bce3d7f6e13a344259da5a7d6a1635bb b0e017fbd841d953fcff17132305ac659ab6dc117550a857e8221e017597b341c174fd496ea4f347c00236f4838fc20b17be69d558aa54ec02bfe30b554ba7ce1e5dfadd3c5396b1b46c601c4d2bec140771c43ad11306bb51c3dfc1ba11e86a +00 0046bb4a141c9099d531dd23ac440eff1f5b10f7cf34920b6b702311d490d25344c665ed5211d401def24986c8094165d10f8934 a6d9cdc940f037a4d4dafd666bf28506f7dd613643f2d1ee1bc91044f067c2e9f713f58b93c94480212be59cb28e8c380662206f1f39843c023a21088fde02b6e65d40ee2322371140f2c2be07169d13b7add1f5f565d02b20e1ecdfcf2c20b1 +00 006f2c6e9ea8109223d9a349fce14927618fc4fa95e05ecf9aba1546619eaeaca7b5815cc07e97ae8cd1e9973ac603f84d838393 b8a5f54b8d9249ad2788ed2bd752c26025f5a8149422ad6c229e7f2e817b21c023a7d0f5207ee9b26609f575519d17cb034242e05454a5d52e88cf6f04f6b8f004208fa37e7e610d64afefaa1bde1e5a374cf7c6c0fead860ebd4b48d7dfa305 +00 0004212b7fd913d794fc6bb33e0276e349c052c969ecbf6afc89b28f75a599a9242acf74dec9f374361ba296ba42a38407f9b7d6 9987e726aa0202ff1657c9d606c346cd04cb1142edda6a80d590ee7359955633b5ce0b7ef2bf178e75a983f6a433a379139021bf9384ecdd6cd43026ecd3e7d46825b36488b86cc4cc9d36ea7c8239d80bf1aa9ea9cc15455ccec9f06d52283f +00 006baeebb5ffc89c94c3e8b37b9b0904e7c4b251d204894655bf3b1235710215c29820b9d401c9ca7df1404d2d62d708aafe208a 8df182a01160e861370112452785297dade01561fe14ebca95d6a35449621e57c1c23e58c47a1510c84d353d53d307a30381dba367615d9f987d2f599f0c764bddf15005aa95b61e52143f8fcb133542b260128b7160ca745f1e54a2d48f4c09 +00 0008e5f66ba53e7caad1feda122a80c32c82d2c32a7237b8ee8ead44ea8f2f01d77c7056b9dd60b92d051f060da8532c1fd0e8f4 b47d2ba11d0cfbc95594da9e0b079e0b12c8935f2592c6c8f63d56275744d0e11b9b30ed95bba3ad4b3b268244c59fa20e797c096414b1a1349ce23f7a12992a10f3532339aa104def02f86b0eb3a700aef7db865d019a97e230a595503834a2 +00 004ecb22b44e809f89b16abb10be062c89b41ee34e110403e42a20ce59a99afdc22f6f6dda56e1d9d1b8ce1d057f390db111def3 94400ef44d076129b4c437873b1bb30629b3663b43aaed638c240ee903e3a9823504f8322f62bc0fc9d91739f6b78bf20c684cee22e60df661acb4bed118f35c8cab3e8d6599ec5b56cf95e9273c0046a221b841d70f2794a07ec4d9babc00cb +00 0051f9500c15ae73d6d479b9f3d2caccc2039d8d03820befc2aae3bbaf65d59bd9cb3c4e3aa8bed5b3acb70a5566047ffad80729 90c63aaf67bf06570bb2c679343998a435484c3ae6970242714059b6d045db0bc13bf1dd47db07b6707593d5e81b4eb617811b9c755927d4f46d61f4c864c859a0c93d9841ecc036328a1655be5074b785ff3d6baf8fb41a519a5f502a271879 +00 000cf01dc4462cca764f4f8cbef48c51980737b9b98d1384b8de9f4c733829db7718a9b5eaa46a8475c2144fe4454cb8eeb0a443 a753fb4bb5b284df3baee56e36787959a7a2394abbe17168ea54a66d462cfa8de79e81b0f60889b2e8d985fb258650d90036213199ec0050859a3d5e98dca1776e7e8a371513a7021884b99d8c015b4c3391867e8345d8e678b2eb250161d398 +00 0063a9a565497974c6dd459bea0d1196d74f263f333c31b7e8591499960e1cd79e2ef4cc8709f6d54713f873b16e7b0be42f71c8 b7a37d4ae0ede20c708d9397313657c5fa6881a5a2eab5b86020e2f2f01b7ed8ffb220eb6fb37d899dd0555b5261578d136a53ad7398b593bee6285d4a3ef686f812f7f05ec2a17541973c4e7b8c46bd7029163cd805cfa1d36eb2dddd81183b +00 0041074dc186193d30aac7cc6d269b938ab40b257d095e54ba79967a377a91b8f73671470cd07f0a3d1db7cf0a31ba9070625e43 8bdcfc8ef6af824233bdbe7fc65809df05e5750d2a5b53c2fd1b611d627fa343bb5f011e60f13ecdbde9127ae42d01390f7e6662620785802a8981cb9bf43c818cb090a5929db92f932e0ea514759aa96b71eb30cfa3953b0f7513edb3b2e636 +00 0010820db54ccf0226161aeaee79cfd2797f87702b4ee91adf8543b3c9e79579d0df8a889e366ec1e0718e039b87a37c24d620e9 af2b7ad7b208d0e689e3405c99189a693391aac409100077d7538f79d8257afcc320cdc1d788f909b686b0e68869c897009e5498e268dc9b86f539e908703dca834de6a4e2cbe8e3a955af1d618380d6b7e04a60bc35fe477b9ea967ace0900e +00 0059d2a06e8bfd5e14a9bc8777958b85be5e97af892d2cdeb0ecbd2d5017952b5042349db5fedba2e26e7b85bbb31ad313d99434 9798ff70c00a24c9525f13c10c989474ac8c0febcfce58d9b36df9fcfa5760246c58671cb4c0f4cd51a2270bb57682fe0f8c4661c795740413ff216d2a316561c2468a1668cc6c9bfdb79c227624385e039166226768bf48139c1b859005c24f +00 00405590893cbbe18f4ad99df28b5f9d17f8f1882269aff0b7eee9392859d68927a99c942a3075269ddec6d69c0df2d76ab9d801 b0c58b8f17dea16f9eb8210c150524c87b523a890ace29f399312dea4a3fe730f900b90f2e59ccd74020fd11e65f69490a1d3279914f60a7d5ff6503669bdf37530352b9c70faf52feb9419b7d33e6e5c13274a1307be7258ca83c24b1d90d43 +00 0062bbb4f565aa0f23b88ab9029d33b995729d10fcfc33ba7c4051e2fbc72f15636a834e3ebfe604b927cdfc89f53c57f36890db 8f1ab6488c5ceee4327a6bfe9e6a56ec81409b131288683b5840dc9bbd4068ef2d4436d274786885024a9af71ee5443014dda0ab87df54aa7b9a1fc09af1ace7e528929f343593bcddd8cd2f93ff06b7d7ceb1ce67dca97a612b40b35cc80122 +00 003fad7031cf8810544a3e4bd1382c0a2e22c5a9fe4804ce67b27591fc516ee81dbac841d399327168aa6abd79e2b5ef85df1528 892b8dc4c265f2f67e64b02ed2c8b383d5dae9af2b7fba603658393c17c18cd136706e2fd0ea7af9a2fefd483820b89b1045d52fe7e13f12ca270371cedab8179628d4df489cd04ab503f23fc9b0b75baa703c3cfa54fb130f7df3129b7f11a9 +00 003db41b4f637fe7977c90e4f1a21799baaddd1826c667102414877138436cfae1b9959842b8097b5276f15f2b982ee59df263c8 840831cfcb6be6da6be1695780fb6756281df019ba5f4295c31a48eea7e5028f7198e80db375d6135fd65d9f4ff1260b070fad6893fe74c2f09faf182904052c35d27be279d7cabbd15044787e393e14aad281937a67bfa60af80c97d8d050dc +00 0065b76c6093d9c49591293471286df1a4444e60d9d06cfa114e175afb5f119d2abeb273b0596019a0ec5db5b5869f2cc827b364 a5ab25f06f46cdce620693a526e5700d1deed1406f23baf5ff5e9fc6d06db2f1a0583fe37e34b049ce6c8c456a6710f818fb4cc3d582f218abe84f91cfb9bdb230ea433e7173b775a1e95f7c5823c1de6115a8fc8e8cc74ca810c4f189194a44 +00 007e9993f3fc1fdc4c376ef77ecded96006ac1159740bd1b2dc6ae3d97e15a67383f1fc931e460b9af3fe14a54e47919667ed06c a2ff3d4a5bc7779f715961fc985da7e1c873d85144653270aad0a4eab445d0fbf3a612fecc7e8f9b0623a3aef3a554760d81ea0025720d637eb0d54f737d88095602959ab941d4253436d0066a17d80ab5d4c78701c9e7941a5c5c510a02381e +00 000c11e2979498695c660a2bdfd105b115bc4ff8664ea15cfb40c725406c6fc9a13027bd1d72ffff6258f29e4e19b845243444a7 a788295c327adba0ae38bf6918af5e6a69ed7aea6ae9aa1cba4854185060a5f7d6f3d87d1966d8afebb9bbd86b4299580c033c99666fd5b7d3e350d603987d665f5341e45950cb816aef807f00aadd1e1e7009877eb714ebe608880b445475c4 +00 0068dfc23c6635bd1fa1076dcbd456ad6e8df7ce7c1370fe275803befc4ffad007fd062a61cf1d50b93aeb9afe1aab47a65af82a a81a37b10f407994e8429c2df454bff26ba544cfde9386b217de5c1ffa80faea4dd5f12728cd129f5e1d768d0fd1b24d03ce814af4b4f6b6dc8e2d7156fce1948eaa01aa9f892c59edb97a5e85ca3f87127663ecbfef035f3a66bc39b21093ab +00 0040807fb888e1d9fd33604546656a493629d94d4a0a9de2608962225ed158167f9e2438abe2d12a11e2adb6c2b66ed78215b0b1 b2e5323b0fcd47d68035cb422505a5ef564fabdfe4c2272176e41f72fc924d886bede153d574302e7d46e95b88e8fba507b58d0c721f03f82159d3a4a3732686ba4c2a97b92a67774e235e9674d3ee44de9400c49bc02de17b0bcb61e8b0ef97 +00 0033bda0a02badae08fe40c239b9d59e5bfe1c4d4b9b7a5acda6790bfd77ad08dde5e93a2da80ec54a7f88146d72218bbb88aa10 86885ee1518c7969e8d14bd05c0665272fea863a8654b1a74d65c764b6db893181e26d3540fca91792873347bc2cb28a11e14a8aa345b8e21b0d7080ea0494ef132d2791046acb7d24a201d35e57c5742f23980a1936cbb92620e049f782af69 +00 004ff431769d26b8837d3e1295f5464fe82be29edefba76323e92078a6483ea0daa96221549102509a1bdcfd46a5a2e5de10c39f 96bbff35a2edfabccce90252594d809a7995c348798a3b9bac2e40151dca6fd9f043f8832f5c9736816937d114b022650273f3cdd286efc308433aae602a290b59ac45432af4a8567c1a7a1e2b598026162711729e163ddce736ffacbe8a51f6 +00 003f85ca1169ca7e9df44cbc6bc7d2868c9d94e8f8b699a42ca492dca0914eb5789a9032218dcef7f95f959c9554a1cd83360439 93c17568fdf99a70252fbe7834957362b400f3c93a1f1fea1d4f4c4463cd8d07f5d3534559f6a5aad59567f54dcceac801d1f73502c439d6b3c6db0e88f7abcbc873d00493a6bc88d88b21ca26fd38559b6f57e9d34f138b1a7639ea4c08fe65 +00 003a97deb36d68f81f50c8829d412ee5de7f9d775633cb69c09dac558182039e275fc258240517a7c4aa592e364765321f27cb12 8d09253416c68b2f4547ec03314f435cc4e21d697d39972a7c2ff2c5476b7060565aaa8e90ba0c2e19d1b539f05eee7e001b72829bef667b5b03b91b3a2228203d73db468dd11ca9b56b83a0600205198a23b2139d6dfde64c3b0d09290d9209 +00 003b1da0ffed24e1a3b5ba22bd684337f6b08053591620541bdad50c761d66201a2cf21a4cc636426456525b598e96baf97d9851 97a7317c1ea83b13dad4321920abcc73f5615e0a6e6b3cb75a5a658c1ac1284f00a2b29067eefc9a9f099da1198c185f08fc7f8dfae69266ee911db5f1761fed82d8e942aade2ff867b8fabd03d5e2eccf82b9cc2e159597d2fe903ebd128899 +00 0040bac7e0d3b54c7753c79d43469e310d876015d948fac4e3a9765444754476af72330e88d79ee6119697aafac8435ab5690754 953e95454ea4cc1d1b501c1f666b77cb19cdacad999f94eefd4b880d37018b34e9d9f55fa1edc4562e28677f1384d454166437a2b5ef4fb1dc0e6631afae6f4b0bc1cd7b79cc32981dad76b84b8a5282d7d078304eb699bbc84c7a12bcbd928c +00 0025b7eb3bdefba3c5134438caf968f615b315204f348006f82e8d61057a8a8a853230cf0500f9d0b8c1551a59b9184862dd2ed9 95a063624c4b88da1948fce9f8cd823fa612e8144ab296541eace3e0beb0a404bd34eb6c5b52cfeab229313ff4e07d2008b07222ff691e96c3caff4a8e4db691c6c3b90e345fe3df22ad8bbab0fcdbe50c6eefaa957c5cceb57bec154fb1a606 +00 00673b3a2985c95904732632e5d988d8d437a60db13215bb6aa880b348f011c609a1e860461427a8cf0d622abc47f910f5c97ffa a648b49839a11414a9ba57735ed87a384d6ab6f00e1e6d64b0cb0ecce4ccbb1d95f037312a1536f48ee11ea57898183a083035230d298ca2c255c09e3d75a2c69c2991d298bd48ad50a136716007e09de6544a23a0a2aa4d09449575fa6a0bc8 +00 000db7dcac414010b816236cad584dabeaec1da76c97182d1b62f87bb7fe2946a64d10430571b2b29ccf2ef72c969a9f045f1f3b acc2e604849fb2df4ae71f57c182fdd1e5f9ad3ad335e925b24ec42671735c2c1899c698ddc31a810931c47221a988d816fd604619b8eb1af856aa8dba40e59028827f036a0043d98208442c9817b5075861db167da1109d55b1fec384ecd6e1 +00 004717efef16e1ae267e155aa1daabafc68515aa391dfeb73c13d01f3132bd22c984228dddc4dff4c39979e7585acd3f730cfcfa a1bcca93aa89fdcab7b76d50d35d07d2c00e6aa8e84f4d4737139fdd2551bf99a9af4728ff8695d91b8a0e1499bc55b71626f875df782ff53bcdeb4829876d0c44615aeb2b065dfaa6739f97bbadcae8e1678a8b67cd5a22495cf6a994518fdd diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K571 b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K571 new file mode 100644 index 000000000000..aa54c2588b18 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K571 @@ -0,0 +1,60 @@ +00 019cf4f4d06825499949f9e0b442586fe1bfe3459813a2b92cd8de0f775a4735e02655702ead8e60824180761808d9e816d60bdb0238e1e8039ca7bb63c92e1cf8433ef447e64ead b4ec0bdd9b43edb0e70ea6a74a0ccc4abc210636895dc845caf6edacb65a02f54a41e570727a51a42bf33ef1e0dd247a076c11df4a0a935897738d59e6f0083455d092041828a1b28f6b5ef3f478d615aa2886a01bb64a724ff7f5bc6715cfb3 +00 0098521a732e72ed945a549afc92318fef7156ed1d1ed9bab93b581478cb2339eb32bcef705c9bf61cf2873ddbadff8ff3806740a2e30ce67d1807a8179dfd5d952e6f8a583baf81 87adf8f4df8ddcf8bc213a7f80c34baf366e0cbc394cf7e6e59052294be53c4545acae93ea4f5d6b1d1ae1478763b6ce06beb688aafa35dee9d97e95f95787dd455acc042c530b93878ed3e0f152a91f2d23acb75bc523f0b19971f549362e42 +00 00336fb21549e397a190beac38a1ee10f0551952da15f71e11dfda415e5ee08da2356f114d450c661f52b2b32cfc7b9be61732672691a079f0927989b7e9f4efe6095a242155b641 aac791992addc4d805060407e1ceaf7849ee9ac9b98fcb0a279eae530a92bd6b56658bcc8acc748cc03784ff9cfe4b7300a00cf7d4ca66d6bd8bb82e6e300be4b5b3cd39624fa9cbf72e2177edd6b27c233dcc81638c0ef73db585db9092a207 +00 00e287ebfd9ba294128cbd484fc5121d271cd33e685bb1804f09b40aaacf64b5a9f2cde9b30a4a02d3a9bda97d92f46bb8787b3c61f280b1e1a0680f1f0679d3bb34d53725d62e52 b8accc843c842b509c8a8640a229efcdf72eb9c24024782697e67f0695de29b43258ce574a43aa4ac2d6c61de7f3af3001fa2de2eb5fbb09792ca04ec292900785da3665af66081e32ead6e0ea196ecb5ceb37ebf5c5b4f70f778ef6f8119d11 +00 0149de496fa8f88b2741864d0c35b3df666b87179b7bd06cd426a45f13bc87ea9f50dea85e1fd02a532630e0e3a231cc3e7fbb7c7ba85b40cff1124e72c677c6a3ea6aa40ffc64b7 9823cc7eda577b8931da87871015c7e340855efc32393417e403f8fb6c25b887027d87f555d21378309a5003fa895835110826f16be330cfd5f48c41f68372be2b5eca3531f18933a4eea09caa78b6d8a2d2abfbfe335076533a8a20ba9af4c9 +00 017605d7c5873d870462375d741b4bc6375f3d47f7f5e9d998917adf2137a81e63b66917b3dda8968930c4b850f2270eb3187fc756e2beeaa67fe0d73053e6cc0ff0004a21250551 a4b7471f5419b56391025dbdb91ebe4b121ba648fcc6d6f0e95818cc1b8017d4847961575c2988472a1652d97234d715152ac5159efe8da4cdc0bafcea34ed5edbbc34d425f400e1b17973c45a03e7229cdfa865a21ceeb623a1156fdf9feb2a +00 009214dc2da0967912c31995cb8f5bcf4bfa832c5a2d3610f3a9857e5eee7c77100d599d9ed003b4106013155dffd6c48859b846e45e0ddbc5fe24f4891c9b2df51407e9cddbd974 ad7d89ddaa94c88beeb482512b159a7d54ca418e0d59b99aa4318dd00a8e6dd9dfc9003d12f941ff0359f671035378280d58f7a3ee01c450d13177d643466128631d2cb20aedf1367e50ada1faa8305da1b215f4adb01a5208cee5a6355e2838 +00 0042f2682e9ac8b76f3c0880e12c292524601dce9ea6982dcf68bfdb0d3fbfb50dc9229e54149ef09b95bbf624eb04ce1427077f30d8536be9f69970ddb449ca22ab8368d2689ed4 8e05a262ff4052cabafe58f1efb9df004a1eb36019a861da5a5410f23fe75c432d456e2b7b8eca70de867a071f8c0dbd107e147760ab526c1d80853f5ffde54fbebc9877005ab2c588ed080ac00a9a974c4abda92429b780d55f0de3bdc8b320 +00 017ed9a9c75cf66528428e85b0f019e3488af8b893b12023ff1b4ca9c3691b74e594539afa0f4d7c3863d15399b862f15e27bb077392d6bbd546ddfd46728c75177338466eb2f4ff 82a7c1263caa940b3980be4c988fb74b97bda5d19bf432a68f02fe9c235c97c775919ffc2e5355e32021bb72fa9a789f03fa5dae5c4a493e3dd40c25181901a0600b8d2f8dca648ed766950127c190d3580999e67844b9caf382e1ac3a7b6a73 +00 01bcc09b3f2f1d26ab9955bff7e8c0f85c8a61293511a196b53d7963f4a4503849c96fb4daa68c9852ad9185e01a35f0bf298e34a09ec352cb6da34f89a1f23e8ea27712a8f43aa7 a8b4e5ab880801eb109d1fc275d55688615d21c993d68e0ea2e37c00e431a220e9163b948468cd3b4cdd7534ada5be3312b430e7000168ffa0af90eeb2565d94c870e59ccc29aae59235ea9c65b15c54bc53991946b1e808f60d83c666a1cf9c +00 00ec52fc3d9c272ca80623e06b15c35f349b13548ef7ee400bbfa04196850b3b8cc7b239238c827f9b0a3160cd97969ce21d66752791f5896e0385b0527d4d77e4b9fc70f04d73b2 9928e4dbb103c13330cb2e3b50764b9734110f3e465b19f28835ccaecfc17a285663a4f65d361504704b873af83e550e058a990d3508281c80a64a5a37ae54bec88b1f584a26dffb331b8a7bfae727952c71e1fbb3f263139ab8d2f3a404fbf9 +00 006403de7627de22d1dcf6b8da5af62f9ec59ec065cc1ca1311bb98aa439a6d5985619b17c17a70f59e17cf180ea6828ef57f5f1f8ef05680a9fc12ab7faad5af61e4e11fb45d341 8ea6c5e834d9240f0e9d3b01c90a51380ce930dedb1748adf52fe469b3e2165e98488b162d0daa6a5380ddf16041b000158c814ff61be04db4acf7d956e9db5285de1dcb2bc5876ddfc1c54026997ee074a5203bf00bded68ec6673989a0af4a +00 001fb980aef64254aeb9bb613ff2fc6967503db4bc1f337882f1566cbeb57489cf32e34f310549f41cba1b951f487453c29753a184e33330e90d4b973d2e406c99a239a5c3f96233 89258292d29277c1b72c11ca5c17c76efe7ab8c439aac5e2491a160fc322d7649255de8d3ca0aaaeb3fa27399bfb54341593553e9db6a6442e0e539dd72c1af7847d2ad32d5b0c958380f1b04b800f6deaef44963dd1596390ae600f67767ae4 +00 01d96dc09dfaf602789c1dffa5c9ba130832badcf180429660daadf4cf1be5cca92fe9713173861670eebfe3a0ba25bcc76aecac60a756f07b69687e05c7e25984a39556469f62b4 8dd1acb5b3f8e09c14bfb369e6a61df3c9668a5a5fc52f120c59004dae8577d0e86fca7536157888a691fda922c3085f17d227ab21a3d2fb6bb84576cd484535fe4f0aaceb3ea2fb859f9b1b688d330bf03f702dd5c8e92163c924214c8867f7 +00 009d98b32c8eacd135ffb8e13223690ef02c0c1f29ea8b4da193502c8cb3f39f9eed608c02fd457f2fb685ec4595e8fc8f388d26778d225d2b18c9bc8b199d8b65c0d1a6af33854a 8f008741469f8adf4497d04d325fe90a05685069ed9f9241691efb7ce40dd22311fad8f039dfd0da7910d745e14d0e9a09e655c5b5259af2195907d71b6820a2c18860a29309ac2e10d14b770d17c8c3536feda55f9a8248e40b812b749d0169 +00 004d873ac744c4f68bb044783ad69e1a733cb8b8f483f2695bbd90c4211282036ad7914a53b25c3e890c6824643cffbdc4138d7ff457e3fbb99387494eb5cf2bdf1ad243a3a1e644 a1ae8114fae23a80d68ba19348accc4ccd0ac3a177ef405acd9dae1aef5e31bed61d255f7db5533100c0f62149d8f4960f2fe6ad54fdb92f667f8ca70332d63ee0c76b79c7de83c308126d208b271d4546b720eab5c9887e7db2e1af2e65b0b3 +00 018d2eb947297a054f8a789771dd875b12b26ef057fb91235dff3b062916f85aab3365609bd2a38a861439c8514e33f174c198139354e63766942f605107cb1b9709b782622b295a b074157e49a86d7957119055be320ba894e6cb0dd8c9b89f331f672da056e9fee3e0cd569352c8c8aa00e70bb2028235104e8609015a4548954bdce1bfc0f57e2c7d236a4154d2714973cbd5f7acf4c4277f336459760ae630ca066f0ce3de1a +00 00594fc0b7a5cc0216d2e78eeeb6394c8225de795f4b73bec48b2f4ede185ba622b59a16dd3eedf8cf2c94f2ccd6dcd205f64c97cf1b7f1e34129e94b5129502909f43940dba0746 a83eeb1fb3c0ea281433e0a5766bf7295dd57354581daf017d045f567d52bd4a7993ae3f488829eb49a08bbcac13490d12381fdac61e8b5c23f92df5b01d1f7213dd791f4d800ade5b252a5d353fd718b2bd03bcc6b01f034b8268a769c2067a +00 00f000631106c5851e8ae0802b01e7a8a8540b427a8a3956a1d36f0600be89318032320cc420931d825cc964e823745c60aad3437ebc1c91d32004472e9677605fb708e5a71a0d83 aa083a09952d97aa377c4d56b2535497b876a98057bc8f9cd2accea8363ae22b75a3aa3b0a3f7860c8559bb99f7e3cf113755074ac20235a75fe0c290248682adacda4f488007e064f1f8d19b62964ccbd7eb15984b12aa2361f5bc4571bc838 +00 01023997206341c6147c536d034a9c38b4012035dc2c9b7ef0bb9cfe65e7d788296f055d508a1fd957b2dc7f9eb10c27790f15f30d81670945e54a508c57b70b46b4a09f4c769289 b256865dbc34d703e471e62f9820c6ac7be2fa5a55f08ef6306b3e984f6b444454610f312787132cfc6ea8dbc670d5b202a249e1dada380813052cdecefe5aa87cc5d0d3adda34b6629b719e45d173431403e647f1a09b3409b1f782d9051e3e +00 011ebf320ecf6a908ea5b868afb8e22246ce84e743e1076d6185ec65dd79043380708bf8da4ba802c3b93b8d15509bb7d7de9dc29f1e9fb0f0f2cb97a26698f955b1f7ef668122be ab0141c46dfd1b1b181f026a9bfc63c297b2feaf2dee8231debd5d8e8cb082195e1b096fa7154db6a53610d6b9e05c5503cffa1208d347b989f31a890d5aceab4ba08966158a1647d056e1124c7d8308628b72be038f0529e6cffa1cf8c34df9 +00 00746d5c824d78f42a1fd63d8fcca61f154ba3e75788b7a0b87f53e5420e23a935b02eaf67bace8dd8a8e7c1caee30154c2428e0a437cf12e235f41c416f92fb54528865fd4766d1 984a574ef299f585b13fde5dcf2d11d0f49aaac876e4c620582ce7bd45ab4b187834066666e609a68fbf9a77e5ad68d1002e136b03d7ba5f55305c5f93386dbb610d984db9a8075e9eb8f2f06ea96881ca5e3d2c915d4fba862520ae67e10d2c +00 000670e72ac2de50dd2cdd975a6cdab10ac45e37ef7a28c685d77447051496b5e161f8b1b93f6c7f32fce8ea05e94ed35fd7cb28c44bf51ea29cbaf5aaa31d6abca30a89430323dc 862c24df3cb3e0114fac6656fd6717ea2b72da09f10f9036d45003f1ea75fd9e75157b36bb43b6c920ad4a4c0675365d1022c67c7c5c622adc312f98444a4b1379934557a2be7afa70d62bdb8adffc481898c772b203e2ab9373c3a38b1681d9 +00 00369a3bb96f884983c23281bcd04e24a3e5f6359f81e3c8e46f3f6b865eb6bdf98a630e90646275c587e41b546d3ca7688cc207afda15cf9b25cf83bd6ad27908647f3f9de59de7 8925ed38a1eabc1ea70be8809d600bbea8b35025984e480e291ea5bfc6b301569d14615014f08d64baa4a3af41e2f03e0dce0854a7ed7ad269908e66ec76bffd70829d389127247da48a07945aab64531a52dab9197e95f2f89b09d379f2ab2b +00 0026717b039df834855511815d5665ff9b654facab469390ae257b7f0eb4dfe66ea0dc037242ed0c13bf229b8f7ff26da9b55fe4750d3451c62804aad493c179ae45d08ece5af085 826dd8e5d277b5787d8a34664a245b38816bde788ff08b88038d666c0351c3cfd8e34d5c5b9168606730a6891a52e1c917773f26aa47434da93517dae322d37e6e6627990078dc2ab2715772cf60ea36e0711659270c279ceadb9455bb51c520 +00 01d642f2d393ed4abea37173e4a79534af87adf534ead4a0a1c46fb047619221e3577e6b8bcc776114d01159c736ab78af3e53feac339d7afe58be8e7a8ed290f1dad960f1b5de94 b3b446fa13a9bb6c01f18a16109b9182d6b64281adbc30c5bc3eee4b7ded9d911c18152c2e682ffe4177382497c5801f17836529416d2dcc2ca8e714209b1d8780a42a7c647c4ab8843dc1e7f123d255711a726f5bdf752cbee8d0be20ef07b1 +00 008cb70be29e83f697a3e2f67d86f1c1ec9a163b5335cb4a06004b6634948bf60b8ad9df9b27d2bedc4975265ce44a7884e57082d521320ca4372d38fc77b18d3fa05ad8aa5c43d6 896e304542f61f6a6a21628883d1be493ab5ced33fe7ba683aa1611ae78547ad4f2e94709e991216a319e80c64b75e8a0c334eb73494db984ba3449a7ddb56ada917786e5ce9318194945de8cc1b742d06c147af24fc4409bce4623890f6fb50 +00 01eef463771f9c6285f3257691dea0844687606d4dd00b6020517f190891cc1be97cfad21d147ed8881b5a6e19b22ceeae30e1132476325f2de0e9af2e14c80b8c780a9d2d6c96de ae9d02a0a1823b47c81c0d81a9dea5d6c968d1af768f017ca55f5589bb686846b98daad9d6d7f652fa5b70678c28b71d110af9d074251bed13509de49fafacf012f59177f921bde53e54d7b10a18310728959e3de165b3a21c69bb9200ed38c7 +00 013bd452b0880b101df1aa65724fb60d5d85b37ed5419027481661a3617e0fb37bda1151b9b5b41f908ba832011f7850b75a07b678e5b8cb35c5fc8b94a625e4398cd5ada2b04cc9 a17baf8164878d2a528acf7ea91ca4b7ca42e082d154bf0a44be87ea0460786429e60e0e0b17ecdb141a96699856f34c0355b3d7457a1376376258e0eac08731b20bcc15a595e81e8eac6d963deb31b606a068de6ffb340e3b5066fd679c3ffd +00 01288141ec2244e4bb3f62daf4ee588aed09ce22be55e3d42e9085a947c1f8cd16533635d170bd64ae0b417346fa4670c25d41387acb2a8e14407a1931d9f7c5358a14eca40974bb 8cc690b2b82e5fc4f7b4ec79423954350d685e89b50c74e19872f8b0b94c8279db68454955f27bd363a9173470e222311294d41ad665e4b5b539f4ac551811ec9c5a7e87cb245ab918a77a874991ae9f429b1341cc2faa46321e32d1da718862 +00 001fe06b94a27d551d409b0eb9db0b163fadcf0486e2a6074bafe167f9a3b4ce8ac11f42cf72f9a1833a126b9473163d29bca2ad139dd1a5e7fedf54798bf56507326fae73a3e9a2 8a2a68c74ff52243383592a39b32d47fbe2a668fb5bc05003e19457e46e65cc2fbddefa2268db9ebb738c01dfaae940116bded8c2bae5bd4b5c9c1342e1941c4e9486e04cb0012405a95feca60a339888bf84b9e5e0bec22607c0960b56974f5 +00 009cdc7e4945c485a41728f83d5188f539e372ff4fe38fffcaacbcb4522428e4f93ef4972556f4398fe17bdd885768f0fb5590df495badc794d4d274e22f2f4a2535555922fa43f9 b16590eb69a5b248491405254f59da6af9ac6805a1af13e9ac0e1f86c70127e36381bb8a8b3810e3523092c370800ea319c661d34edd3337030dbb71b1c4c32ece28263ba6a3d6fc578bc519392e2a6d946ce23911dcd46fca652c80c15be3a7 +00 002bc753d007c4491cfb8ce0a6c96455acd16d37e02c982db216b8cc1afd6d10c6be4e15a3988b8b8b86b2b5b59a5c1939889024849317f27ee08a06bd8e7524d4ad83a1de208564 986f9ff7d4e67ddd21087f749ecce85cf4070b4ae791593611df44d87b3c28ae86ef5df414566ee9c15069357737d90e0623ae1d5cc22aea3945de2c360c1078993f2b79764daead1b7cfe49c067cf353daeebd34a50622071c165cfab8167b0 +00 002082c6e61d0d72f040905d8c1c20d47b029f41ec68d6cbf43ce97c3b2a0a770557a33cb803c432cfbd3958fda30ec1bba77a6613c318597a85ad02b26c44bb77ca96d9cc1194ea afc1a041caba6171d4b762bb009df251b2b4099aac8e990d49f8fe1619dad34006bc966dc5037dcf7cea7501acf4978f01bb1382da53d755776a8d6d10813e245e5f4606d871253b1448e0542026fc9380401d2986fd9979923d3b3d66621697 +00 00e298c93351323e2c5304015a4878997ae4e79d1c32f1dc64262e534d4f2c4b3e222356ffce746763373fdfb936fd330d3214a18c07f1205b20c9a941331cd676040ba1fe3dbce7 a77d16905a3e73998f4eae857bea47ac61b2c935a5b743388a5b561631bf4fe3fd9d080bfa99751c3f49d3a1b49413810fd5d4fc7c14cf7884a4988a1c277743d4c93cbe597027d5ab97b0690390967e16f084688c9db5727d814f9aa5802260 +00 0104f4ad56594c5cec2a988c5596d73adaa5a81802b40110dbae698ddb1f0b271fd1479c38abcdb9b234e69cd0da8a0328d2135c287d5b130a09fa0b899058e7800eb2dfcee95c1a b72cd97b2f7408b90e5061adc244d5454bdb41c1c23621cfa53e682259c6e6bdde2b57e11c35dcb7a3d35896ffec893b122e0611b567478f803fafb223a846e52ab31295875cb2fb5d7cd2cfe0de44674bdbca313de6ba0cd47066dd8afe7e09 +00 00c4989bf33b3136bcb4ba67906eaff2bcbc6567635aa4b057acb7353ee87ba3cb4cb9838f8f679729d5c6ed98e6c4199cf58605f009c6873a1b8321f83cd3c0973b7a3cfd9dbaa5 848bde8b90b1e65ed57e7687176b05698656f4ff8bcddf8f03f48b46da158a55f9f51da7c33be1744417e45d38413cc204051fcc42a187957f5b313e78c8c51d324224ed8bafb38bd57901bc124a945647cc9cba62c9313faa90e37901b0e872 +00 01a96f2ad56e31397e236cafc108087479c9823589a5fbc3dc7488d0e5d1199cf245d7f21f524cc0e8b47feca14c93fb760e631434a91188b32965053942f3bd39b3714f9d6f1a11 b9442104263a277ca24fd303d4beaf0aad13b3632a47906a5a3efce941d990e3293ffd18374e5fdcf0be2afebc682f771013e393208d53ccc5e3785ce89d82a523e67def9bbbd434a6a89a38bba416ef0e3de86ef142431db1e9e4a7400f2da3 +00 00c08ed8e0e0f8b0d0714b46a2164b933f8147692f18da97e5a108c44d5a5cf221cb50536e41832b83bff4026c6df156386235cf5e3e9a67b7cf9b2fa7707c5e0ff33a91601b8e34 a4eac54431b52075c094b88436c3dc0f549676a2fcf5099bcb177ab8ce525ea159e9df0493311ee6980bbdaa62ad2a1605560536e4cde269efdc97eb34f57b43e68f532e127bae74dcc8d2969fdd4bcae66f6632f9e6a99ef64d18dec04cbffc +00 0144090a0ee38cfa21fabcc24d35139a99656911ad4f6dbffb77dbe74e7993edfa9fd63d2c4f6bbdbc8ec21ba13c9f4a3576b5d6e3abeab5af5ac81b1f2bb6d4c42dde645d854d9c af598f96a61ae80b97861b1e8f0aff1b7ef7b43d0d1f8f0bfac380e138b732760f95cc1bf534b90e626b659f77f0addf18279af617074d407eda49391eac51e33f883ec2ae6ab6ef849df9885aa20bfeb22b228395ffeaaaf3639bc3786c01df +00 01df26b672b2e3617b6b6c631d3c6be0cb49c0a690de49643e0f416215bcdaefc03fa9c708471f1d87476d58c8f147517ec8a14aa945ef001fa01984d5c3d81f7083ea500558fef4 ace46bf5a73eca69b0713ba326ca5d3a52f7b71147668b47c4e72d5b235e2d36f99848a70a96d1ccb5a175a887c3203111b7bbe15a4246a07eb1974bc3f61855c3072a49d2c1d70de3362b701c48913003ca90f2e001f22dde335552b3a18bbe +00 0189918b832e9fa30161fdd927bfc267f6405335df3d66d225e17173af52a671138883bcb94c4403ca3e001fcf09ef4c6488934d6775af2b1da30a8f331579af2d0fbb530298d8f9 b40005fa4a290c7121d60a4ccc25a8b2aa340213031be5234d556f5aea671df8347250b15a79140f6f851bb21de56f3d02e3eb85ee7e76573d0c5652ca32bfba012a9dd788edd9174d62abd6f742124e03e68f8989f79e8693d6ec1ac69cb408 +00 00bdcc175eca3a399b944eb0334ff33c4fd130999c8ac0e7b52ac5b774fbad53ccc3a31024f5262b2eecfeb2104b14bb244307effe3dbe8ed25686dbf46a42c4b6f8e34010ad826a 92b7182c5eddb4ca4a42bfccdccf9e35b25b3db5e56d5788d3ff60adfe416e9ff1ebf64abb98c6d7c3023bded506c83704f6a8dd6f438c163e8e16d11a31204ca3225959084a53067127a17b790f69cb26d418cc3d542902f8f77b77a7384a01 +00 0007ab5a55a1d8ecb7f5dca2afdf9ef465569a4b0374716f604ad42a6e0271e934b09655e8e2529784b69b2894bb399b02aeeae30e9e7ae70a2a8e56b9e775bd978a04c728e3951e 8f77ff925c5be971e2ec66a72bc5ae720d1c38c1757189be60f541d1574078607afdd9cb3799f7a5425f1b6db85f63f0018afe0fd5117bbf72bbad85e44d2a1415085410cfe0ec1525680375844cb19c8fee552595fd43899bd96c32a5028ef5 +00 01e7d4da72b1d82e17a066fe387f2a0a7fa4c60ab993ee09710531789186077f2f32b42ddda497d5fb57356383e1f96973df043307f0b6519430c3f0d40d62954032872fceb7dce9 8ad9f123e87b731a1dae65ddd62e46cc710a42276e9aefb203c174fdc0219494b59cb73cab087cea8985ffb74d46fda613378263cb86743201a7e27e4283412c2d56e369b53e3a9e81d97dd1b0c52d2421673c17acdb3819e799cf73ca6fbebd +00 015b7271d4319db5743119c8103a7d4c6d57e9c62f3eb93762156d2ebd159980aa57cea948e416717d715a2e458851f1b2e9ad4172bbcc53861db29c3ee0ba8e82617a5866170847 b6c2967b2ad5c5bc5abab04ecc9f75ef0e0d7ed9c9ae860d214ab0b0e1e8e8bb235234ee21a5c10390074148fe53678405046f0ce2b591a596b33b47c2b6f10d888c6fc3cf3f8002182a5014f75604e82f7e87cb508e349af8b21ac5bafea669 +00 007219ea7917d174a5386df985d0dca798ac9f8e215ab2f0003aee929a2dbd91e37fedead0ed95b1e8aabcf516bdf54337b4aff7ace4c6b3179f2e919a49db50a41c9d4d58d4f636 8c96dca18e6413790d49993de2b57420f73f4af0854b1d51c4a9f286b352b07b5bf11e4ecacf0223a697454f7e8a305603b16825ec244950b0f2b45091f692210ce466aa4acd713a2524651901f08cc6337dd89d84d97dc0cdc582b81d667001 +00 00bc623152253da24bf8d752bd78aedf7d5f6a2f889453ccdec14e10753335ea8bea83fd181a1f3680ed50f2324fbeaadae160cc85831750e021f3e44121ea1b1efc29a7d0069479 a49e4c7ac99ce3aea34e097e01b3e2a164187f6188379908faf6fd466df3d7166debffb012dbcbd5b8882e6dfe2b7380137f38079b1926bafacece4e651882abc43c82c6b5018c1114569ec10c4e8cb3f1d0aaf0d2c86cd3a36d05626cf76ce6 +00 00645947d981d258f2954558c31022a3b6ba5fa7b675312f794cb61bfff1d9ce87267e4a1dacb7c8fc58624d31c85ebe22f80d26a620fed5df5bf38515e0903f0b69a606048197d8 8fd79d366cb407b93bd41d5d140ae8212826f041a6661e134ab91928fa5f8f3fa6efe8d0badb0afc2e3b45e4fd8db132142421b85e99645bbfc1185bab7cce650422230eba757e4b84a1667660a24b177f49bd5f21bb78b567f6e67f6fc0ca03 +00 014cf93ca69d94ee8fbea0c8da9d76aea092b73073d8f5385b65c6dd4d567fe86bc2cfb8e8be890c3c6cd9abf7dc3a17eaecee3d7a9455887863e496c48dc3e47821bd3d825b6bed 8abccd171f8dd72d2696f6c0192bffefac06749c0881afc061cfd327d00903adcd7c01e0e769c1bca3c3e03c519b83c516a0c45d23c97f89fe6e9c7db07a8221431f30f02253e596aaad60a3952f42e7802d5e7da1596f1b7a5583c2ed427ff8 +00 0033feeaaaa28f16bfaf5ea9c7319cf4561ba4fc55327a8477b6cd58ef6ccad3962ee1f3edb243f3a04e7e49c8e23509fa2d63252adb186b8bc7e9255cd61fa9bc45242d42da3a68 8a34ee3a5c3a51d6c505676279ccfe66a82b6fcb303f17e4682c3b0802b047e012fd314dda8cf72a91883a4a2694d82e0d4351fe72e962461cd93b4a43d577ed9c54bfcc46543f63324dc4f7dfdc728b299c07e4e016ff13d64f6d2d44d2e62c +00 005613dfb53149bf5fdc4e08ccc1c752b0b66ab43aef2d008ed40f3df40fcbb2938d2c41e3ea2dd4428aeba9059a97efe5593119673866a19d27a2ee37dd357e22b6bc849e7e22cc 9688fe849e3618b923cb50306971ef0897cee39c93578520862e99bb576807d1750c81a25feb16922fcc91bc4742966b003bcfa996079096c56199afd7b2feafae58e323270388b612793fa913b93f190407a116edec6fa739b636985f84788a +00 011b92c8b72b86c51903387a65aa206988d443d1988253329ad3a89c902ff1ef8cf73b7f2e4aaa352443bcb833712d94c3e637ec12cbe4c2d4606878576b17fae1512fc77785b737 b68050432b19471ee4f02d79cf69216b8b1f8accbd4e12d115330304845787498fe2296ef787a74e4c965e355589d8c600539cebb0d046c7933b776def3e1f9bff8f540ab583324ceacb7b8e55e08da943566d711f99f456510c08f0123d3118 +00 00c3c90d5ce4375a08b85575faa78ee6bbd9e5571ce5a90582042617b807339c282cdc3b003d82006264b1c08c20af4ad4549fbde53d262facb98d923d81b8eb6093374b6a1e84cb 813a32a6115023456ff539aa3c0c399b34d1fddfa4beae7829c6d77d8a65e9824df499f3848bed7357097aa0640a1b5d0efd98c65d9950c77b3dec04fdbd84e1849cdfdbf97300c0b1f7143f95e9ffc6c3c8cce23ef4164a13e00c30a1946f41 +00 010f184c16228d9034271332178ed485d10b6aa76003efc160d63fea26fbbdf5552205ac7df0d8c852a1210cf0ba512f20b798827b36ad56b12a826fa7dc1db45aed264ca6822659 b600d9659635f974b46fd689d84b6fd8e0d34403391c995fbddca0b7cd38e1c942997acaaa2638ab534bf6dec15f560418d60673447e74044ee414ef4167eb0f4cfee8976590051fab1ac8593a1c7eceeb15e0fe1bb712735ab064fde3892db7 +00 0181baf9d497159f837cba58a11ca435c442e5ca792ea559bff9f6a1f562c05bf6bb5914afbd1bcaea75b35f88bdd832314b249a5298622c89462344d3f28a44ba3d059df432fc71 afd1c59bb2999415fc7ffa2d7535370007477f517293e50750fafef82d6868c0e10513d8b19a200ab1d0fa3975cdef6b17039116a9a2c268c6a6f92e64e892916c529c3f6e0a48bca9624ceb9e6c38ad731a63d2ca5b27c862944fac30fea6e8 +00 0083fae86ab96bce99a53e50b7eecff38e4e25b21c4b0f6a4986915de245eae24f16b6a00a4db159ebc27f5a6a072da94ab6be5bf75f5eb3f75c4452bf4ea7014392eb1e02706fb4 88415a2f98d086433bf11d805c1aba416eb6af93feca06eafffeb9e5f42b9a354a25ecaa918cc73da495aee26ac77e9614ae48d6649c8edd687f728cf920bb9abd73def423cac6af587783e23953c8ffed6f8a9a29b93faecf60751e550b7d58 +00 01a663efa7bf4d8479bc535fad71e9b5e4f4281aec55967baa008ba17ac2f89cc3398d30573edef29d590fddce8cb157f655e92779f59e7a18d0327d02e7daf4c1216143b3688fed 997b60b87d949cdfa60e2ca84fb111c562a4454193a11125e3699740a3ff12fe6e269c5fa9aaec41f7516d07515a875a0e82fa9bddb009af0a322bb36f83212352d4783c43628078fa22dc127a703d9047677e484824fe966b1732da697fcd9d +00 00088d1a2c0219696a94337cd56516252b74139ea0733b17fdcbf7692c3e5f6c3989e5da2aaed7468e65a5d578571928ca273ec3b6aa72cd196f560f05095cdc8346e5d31c4c2e0c 891819372dafd9cd048028b626c3c9cf2b3bfa52752c11b277c308049d3bdc34c1b377ae1f17716ef4c403a6bc8c666d060d71a9fe77668deab420760624979374eb20c724db46bc40f411dc597bf49e91be0eb962a40a5b7a0bca2a23226a5d +00 016cc8a0fd59455ed8d4de561fd518df2e008f7dfaa5f7f29ac2489a411e233917b43eb3ebe2596fc824be58871949545e667dbcf240dfb5e0c615ade0179d9ea2a1b1ebb8ab9384 af71c97362cffc43a06f219f193cf1337cfc38f1f9df0c03b18daa693209caa6620494fad6cafc68393a98cde18f79ae0cb5a2dc6177af5a91bcb94ade435519ac3701eb0db2ca6d2c4ab04ffca7d16723a84bb7b2f3c2a9e44df1dd5fd2c453 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K571_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K571_blst new file mode 100644 index 000000000000..73302dcada66 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_K571_blst @@ -0,0 +1,60 @@ +00 019cf4f4d06825499949f9e0b442586fe1bfe3459813a2b92cd8de0f775a4735e02655702ead8e60824180761808d9e816d60bdb0238e1e8039ca7bb63c92e1cf8433ef447e64ead 9885c409354ecb967088b61b797c7bb847fd30d56dee5530946040853e57b3f21351cb92c5d16909c24ddf1d6d8e049c07360ea7e5fee2b47c36ffb6ff60078e6c1d3f1980a52c2607c74c5a319723ef5bf8ede62f9deacfd0135427d1cce704 +00 0098521a732e72ed945a549afc92318fef7156ed1d1ed9bab93b581478cb2339eb32bcef705c9bf61cf2873ddbadff8ff3806740a2e30ce67d1807a8179dfd5d952e6f8a583baf81 ad1fb5419e4c200efdd5d607237fe99c6d7ca494de4c5cb840597dee3ba7e5b5cdfbef66f1aab6a165d27c93bcc7677518bb0d134d963ba4d7c1edd72e4b14f19ca3989818334e702e3d127fc6d860943e4f44276d516102b8923c8f883194ef +00 00336fb21549e397a190beac38a1ee10f0551952da15f71e11dfda415e5ee08da2356f114d450c661f52b2b32cfc7b9be61732672691a079f0927989b7e9f4efe6095a242155b641 89fb3e5e7714df6500a70d7da5f0426f1bf00fce9cfcf7281d25071face342c1468fe1e3f9c6a5813a615a55753c89b40ef6c2163045120e65bcae91eb544bac5923ea110cd2f557e43119335ed52adcdbbab3b3d46e2491bed364e4a9517bfb +00 00e287ebfd9ba294128cbd484fc5121d271cd33e685bb1804f09b40aaacf64b5a9f2cde9b30a4a02d3a9bda97d92f46bb8787b3c61f280b1e1a0680f1f0679d3bb34d53725d62e52 8de5d8049cb999a9d0f3bfc2a43c788f0efa8b4c443e16c4dcac64c3e5d259515ab62be5c3a7c00d09db4ce6790074b50a67ab3d07f2bf557994a0090f588b260e0a45e6f451eb41eec6cac831b51ce06aadb0b1155577ff4d3f46fd4bd5e268 +00 0149de496fa8f88b2741864d0c35b3df666b87179b7bd06cd426a45f13bc87ea9f50dea85e1fd02a532630e0e3a231cc3e7fbb7c7ba85b40cff1124e72c677c6a3ea6aa40ffc64b7 94f7156293542631cb1e0f6a472c551e8aafc121305dadac36db235a8d42f3280553fb74964b287e8ac0bc29474f3c3303b1ad6a705386593a8ba74dc7b52efeecf30ddd421ea73b2c999af2040ff276b6c078f787c4e93349fadd199ece7c2c +00 017605d7c5873d870462375d741b4bc6375f3d47f7f5e9d998917adf2137a81e63b66917b3dda8968930c4b850f2270eb3187fc756e2beeaa67fe0d73053e6cc0ff0004a21250551 b335ca962fa8bd02a1ad2c4a077ba96532a7a2c67a96ba8d806a847d80824275e7dcf62bc3cf70dc0f6fdeccf6d7a06e0e4855f6b70bd35f78be46948c00979f9af8a7b6eb21b140f0307e2734cb4fe19b2fe57ce2a0053093871f65c48f385e +00 009214dc2da0967912c31995cb8f5bcf4bfa832c5a2d3610f3a9857e5eee7c77100d599d9ed003b4106013155dffd6c48859b846e45e0ddbc5fe24f4891c9b2df51407e9cddbd974 b38091cf69fd9b13a820e2a519446cd18924fd2fb024b0ba21f5153dc9db5879b6a6d93ccadfd84ede2923826257e1521390d2c23ab4ced81e1924265d28dd74aa3b0e6d2d198c524cab473a275e12017351b65427ed3f46f4ae35f2c3d86e2b +00 0042f2682e9ac8b76f3c0880e12c292524601dce9ea6982dcf68bfdb0d3fbfb50dc9229e54149ef09b95bbf624eb04ce1427077f30d8536be9f69970ddb449ca22ab8368d2689ed4 875d77051054b186f3a6a059bc10b61ce99fbda33cecdf3d22c80b306b956277b4791e03c400f074881cb3edb09780f811aae8633761583172ff604c8877249f640f79eceddbc85884939e275fe7b0fd410c45eac2d81a3f3eb33feca96543be +00 017ed9a9c75cf66528428e85b0f019e3488af8b893b12023ff1b4ca9c3691b74e594539afa0f4d7c3863d15399b862f15e27bb077392d6bbd546ddfd46728c75177338466eb2f4ff 84ab0627d9ba1f66f0a0fa99b117d8fadffa6587af74276148f6c688995199e3af98c04ff6d768e518c8856ff996c5241090574f014eb38efe614b94ee7cc3716ca6f6af9e00cd3dba73e97f03ef2d279831647b82559e590ca41711cf6e0490 +00 01bcc09b3f2f1d26ab9955bff7e8c0f85c8a61293511a196b53d7963f4a4503849c96fb4daa68c9852ad9185e01a35f0bf298e34a09ec352cb6da34f89a1f23e8ea27712a8f43aa7 8a4f1fe6fae9a18435dc16e18ea9dc794df4566fb13e571ae93d6e9159534936319f9368c563e7d0bdd49084b640bf1e0ed6322961b93da88a0c0beb53dcd1d8305664a2411f070abaf2a9dcc5ef3708c2bd68a1b5824b98a64d319c484da0ac +00 00ec52fc3d9c272ca80623e06b15c35f349b13548ef7ee400bbfa04196850b3b8cc7b239238c827f9b0a3160cd97969ce21d66752791f5896e0385b0527d4d77e4b9fc70f04d73b2 8c968791303e43cf4c6bfdf029d8573d3b016810a723cd2190621f84bf3a85169cd206b6082e7402aa5eb532bd1a9a9f0901cdebf566475198dd47d91943f674db968ebe0aafea503c060b5d46cb834786b841c632246950a041ebe1d72fec8e +00 006403de7627de22d1dcf6b8da5af62f9ec59ec065cc1ca1311bb98aa439a6d5985619b17c17a70f59e17cf180ea6828ef57f5f1f8ef05680a9fc12ab7faad5af61e4e11fb45d341 aec11b81d8ebcb2ea10f848767fc80f892cb4d211053361b3fde26a16114e64b4bc68c0e95009cc4aed5c71635f856ce17b6c85bbd13c38f361c740713c2c08130b41bfa7181cd29f2be919adf3e666f47cca4b78362a0755553a7c2a96007af +00 001fb980aef64254aeb9bb613ff2fc6967503db4bc1f337882f1566cbeb57489cf32e34f310549f41cba1b951f487453c29753a184e33330e90d4b973d2e406c99a239a5c3f96233 969ca2ce4ffc1753d79357fe9887fb07e4d8ee40242f5cbaebfafeca1bebaed114fa0c393436106bb496ebe48799e0b114cd8a8c99249ffc5cc953fb18679a44347b4b385e360dbb18878000a323a0cb057757675e0bbc11c54749962a055c0c +00 01d96dc09dfaf602789c1dffa5c9ba130832badcf180429660daadf4cf1be5cca92fe9713173861670eebfe3a0ba25bcc76aecac60a756f07b69687e05c7e25984a39556469f62b4 a3b8a02d706ce3251e5eb5b62a97eef1f5da7f60a703519ee0fcab2712e0d0bdbce433b18c6bddb1d44f01be41fdb0571452d7bc918e4ff507c90b937933ae83f463b75fa5dc8ecbf53836d5bef751a60d5cbd6d054100c975f16b5b6e68ac12 +00 009d98b32c8eacd135ffb8e13223690ef02c0c1f29ea8b4da193502c8cb3f39f9eed608c02fd457f2fb685ec4595e8fc8f388d26778d225d2b18c9bc8b199d8b65c0d1a6af33854a a1e27dad99ad7015d78dffb4a85485f9b2bcce1992047542cf1131a0ba0879b4fc14ea4564de8a03d75bb68ee70d130111cd45d9b827a6cda54c820834092b11b3ea38e0a5c7da617284a0e6d52134fc33dae0d3bb0129c783b2e5b38081fb30 +00 004d873ac744c4f68bb044783ad69e1a733cb8b8f483f2695bbd90c4211282036ad7914a53b25c3e890c6824643cffbdc4138d7ff457e3fbb99387494eb5cf2bdf1ad243a3a1e644 82717d4c63ec340a329a1a31be45d163f2f2fb3c7f30e9152b1b3778f006ce6bc4cee64a5af52979c0720d528ec1017008fd71b2c96d055ad0e3138b8cc9dfeeeb5a6dd54bad9652ea82fb36feb8b6cbf8d537c7852d1a564877e7dcac71f371 +00 018d2eb947297a054f8a789771dd875b12b26ef057fb91235dff3b062916f85aab3365609bd2a38a861439c8514e33f174c198139354e63766942f605107cb1b9709b782622b295a a7b734489c7d5488ee29731b5d65653caa85a7ca8120b6ff89fd02b708c069f7a94219714a4d5b7ce916405d09973f5f0452a483f7622cce857c06abd566ce93a7a724735d19df7e6670ecdf1d522b2418b6f98268c5329066dd765f3e330548 +00 00594fc0b7a5cc0216d2e78eeeb6394c8225de795f4b73bec48b2f4ede185ba622b59a16dd3eedf8cf2c94f2ccd6dcd205f64c97cf1b7f1e34129e94b5129502909f43940dba0746 824941622d859e57c95070a826d6cd99a6313ccaee599e147a371f1ed35b9d900bca3ce49d3604ccc8c5057b745417d20fe6c5f5e3304f266bf96087d3e6ce10995e9ea1ba2647f1385292171754f2c973e25ddc75c412ce87dd8aa3bbd1c73e +00 00f000631106c5851e8ae0802b01e7a8a8540b427a8a3956a1d36f0600be89318032320cc420931d825cc964e823745c60aad3437ebc1c91d32004472e9677605fb708e5a71a0d83 a4cb8938d42425eece758e932ec6f68bfb7357911a84637fcbb3a1f4b08be393c5d6d2b8ae91cdbf35e1998815605b5d118b11f21d01e1fe9e5a0e3727f2c2f7614e68a7ec5e899996d3716183aee3b3b629e0cf9be2162d4aa6c73b14647f85 +00 01023997206341c6147c536d034a9c38b4012035dc2c9b7ef0bb9cfe65e7d788296f055d508a1fd957b2dc7f9eb10c27790f15f30d81670945e54a508c57b70b46b4a09f4c769289 a4c2cf2561576cf0ba193bda4ea72b8718c0065f0ef3b385fa38a8d6ff6fde134d045cd3e9317b3164a9d3b43e289b3801c22317ef5dc6ede6201d1bd5ad995078cec3e7c974d92a9d324911fbd3565c713c0422bd79c8237df17321f287e08c +00 011ebf320ecf6a908ea5b868afb8e22246ce84e743e1076d6185ec65dd79043380708bf8da4ba802c3b93b8d15509bb7d7de9dc29f1e9fb0f0f2cb97a26698f955b1f7ef668122be 81630ecc57fb0c1af072ac498fceb025ad65be616b68d59bda2fe4231230f06839b6826d5926961ef7b28ed2b53ec291003597da1e1810adfc2fd095cb754b2da5d56043ef92fb2424c746940cb80ee9df958d80fa9dfcee8e5f35957f814196 +00 00746d5c824d78f42a1fd63d8fcca61f154ba3e75788b7a0b87f53e5420e23a935b02eaf67bace8dd8a8e7c1caee30154c2428e0a437cf12e235f41c416f92fb54528865fd4766d1 b13e335c939eba9509bc0798e707153f66386da0b5adcf5d0381eca5c37849ba4e813be8f0aaded8a8f05a097e03e91c13798d2d43b386f5ef697729c5786be9f50a47c38baa6416c6fcfe221e1abe037502301d5874ef5143c45ead08aa8416 +00 000670e72ac2de50dd2cdd975a6cdab10ac45e37ef7a28c685d77447051496b5e161f8b1b93f6c7f32fce8ea05e94ed35fd7cb28c44bf51ea29cbaf5aaa31d6abca30a89430323dc 87f38bba404eeffe0315452320fc06c3fae9f22280b9da2965c5abcd7157274b8c0614fb99e4f85cadb125a0f0de970511ffdf61d6a94c0972c40e03d429a0919cd7dce86c995213379ab45110ae98be548ededb0af29646806652426c8babe5 +00 00369a3bb96f884983c23281bcd04e24a3e5f6359f81e3c8e46f3f6b865eb6bdf98a630e90646275c587e41b546d3ca7688cc207afda15cf9b25cf83bd6ad27908647f3f9de59de7 8cdb416dbb3cfaec22eee69b558747db305589d63227a8e51efb52fad8d18a149d729940cb297a76b11455515ec05ca10bfc74b2259ef5e9acd6d0dffdf1778b4da2c4285a1426673b804fc7aad8d564e4d0988773bd07d9516f55c3f688786e +00 0026717b039df834855511815d5665ff9b654facab469390ae257b7f0eb4dfe66ea0dc037242ed0c13bf229b8f7ff26da9b55fe4750d3451c62804aad493c179ae45d08ece5af085 81912d7e3dcadd661cd0b841641d4742d8db3d9810bea2fa600d7e98d0348c2cf737012db040bc6c32da3b3d20e1e0e70f6e6b487ecf42e78baab9cd261d2c980c600357f04cb40979d17abd41468492933da9a3ea10fead4b76069edef11639 +00 01d642f2d393ed4abea37173e4a79534af87adf534ead4a0a1c46fb047619221e3577e6b8bcc776114d01159c736ab78af3e53feac339d7afe58be8e7a8ed290f1dad960f1b5de94 8061426bdaf2664c5b232fc0ed51e9c0ebad59723e6081c63f7cd5ac772c434917e0a6e523cda3db1324fd00702c424f0dcf092f6bf41d066388abe0c740b09347a3f2152bc16f6ab7dfa975bb76ef44f26e4f06cf5233f8df8ac8312e4bf467 +00 008cb70be29e83f697a3e2f67d86f1c1ec9a163b5335cb4a06004b6634948bf60b8ad9df9b27d2bedc4975265ce44a7884e57082d521320ca4372d38fc77b18d3fa05ad8aa5c43d6 8dbb475dd19197400fe4e43231865db52ac4981896b7ad51ed392c2ce80b2994929a285a6f5e089a15fe93f047580755026a3dee02ab3446da8d9dcdf6ad83716356b3259fc3f1974e590fda13d89006e0d04288b0bc20e5c8a34d683f65bd5b +00 01eef463771f9c6285f3257691dea0844687606d4dd00b6020517f190891cc1be97cfad21d147ed8881b5a6e19b22ceeae30e1132476325f2de0e9af2e14c80b8c780a9d2d6c96de 94f7bb7b5f7e9f11c5212b35445164f60518e2c270666093a4415e9a6b294b476366b4e531d6fe3d81118307af07aa7e166e21d7cbb206c31a2ee70d821e34aedc65b39a26c7c6ed1e7e2a722950712933551877b6be054f4cbc0db8964ddfb4 +00 013bd452b0880b101df1aa65724fb60d5d85b37ed5419027481661a3617e0fb37bda1151b9b5b41f908ba832011f7850b75a07b678e5b8cb35c5fc8b94a625e4398cd5ada2b04cc9 9283d7eb83e16471bbf5b7aef8553c9d92a71d9f3dd2d442ef0932840278952201a1e970a52e7db45ac366247e7afb16170eb7420adf38f3c8dcf59660afb3d4258078ee6dc2b72a41d8ecc3b3b651d645f414fc25a380a7b4468221e7c5d6de +00 01288141ec2244e4bb3f62daf4ee588aed09ce22be55e3d42e9085a947c1f8cd16533635d170bd64ae0b417346fa4670c25d41387acb2a8e14407a1931d9f7c5358a14eca40974bb 8f751531c0183c3148c78a6f537c8e769ceb4b862e28e5feb89f2a69a2889a8dd5d31e5f338605fe618e9d8426b85fb7003c94cca9b9c7c533960e4ad5b8be2bf52fa5589063ac1fc768e751ce2c2ce9bd48f67a5b9ba26dfdcd022f6a23a7f8 +00 001fe06b94a27d551d409b0eb9db0b163fadcf0486e2a6074bafe167f9a3b4ce8ac11f42cf72f9a1833a126b9473163d29bca2ad139dd1a5e7fedf54798bf56507326fae73a3e9a2 8b54604e82a01301ec8eb27ac40f1d0d2bbc37a7e46c765ddb1148d74c2f7ff5083c8e77d03fc5e9944570a2c975bd89039e6d7d515b845fec751549ad5690cdaa3659396f5b88f0fcd5b09adf0aeda2effe52d3ffea2e3eb934c7a2baf8df04 +00 009cdc7e4945c485a41728f83d5188f539e372ff4fe38fffcaacbcb4522428e4f93ef4972556f4398fe17bdd885768f0fb5590df495badc794d4d274e22f2f4a2535555922fa43f9 80deaa1e64d8a8a69925340933d6d7bb66c744ed07eb564b32833e5e035e917312b6e8b79dde675140cc9c7cab3393931908bfb94a34abb30b463ac6d4e5693b303dacc4ecd8de0f328d3f58c6f327a574b1ddd5212e4f0d20825e2935aa5b74 +00 002bc753d007c4491cfb8ce0a6c96455acd16d37e02c982db216b8cc1afd6d10c6be4e15a3988b8b8b86b2b5b59a5c1939889024849317f27ee08a06bd8e7524d4ad83a1de208564 816432a95bf70524b48d350c96725631f321108ca4a30488ccbc385d7e65e8475d2f0b9e15cd2b57de50b6aaf4c3707e03686211575865954fd54cd739ba6ca5e2aa1916162261a1e79826152bbc0fa53847fdaf4754c34fcf9cce898a949feb +00 002082c6e61d0d72f040905d8c1c20d47b029f41ec68d6cbf43ce97c3b2a0a770557a33cb803c432cfbd3958fda30ec1bba77a6613c318597a85ad02b26c44bb77ca96d9cc1194ea a013603c03bb090195058b06f69e583cea5b6e83b458fd8f288f3285c6aeeb67d7bb91bc417657c44ef0492f0c3382df110844d04b953b12d740fb24b329e5d598453b9c2b9eac8b24115fac1749b2b537dd4df58c49465a440602e8b00441c2 +00 00e298c93351323e2c5304015a4878997ae4e79d1c32f1dc64262e534d4f2c4b3e222356ffce746763373fdfb936fd330d3214a18c07f1205b20c9a941331cd676040ba1fe3dbce7 a3ad2097cae32e940757e23f95d9cd788c045e0ed0a035504be7dcc96737dd0ac321e30ab78bf857648666f434742bcd16ca7cd9b9bcd24c02bbe3686030f55ed5658a7f13e1bcad1dbde616e4efd95bc266878d897ac185cd04bee01dd613f2 +00 0104f4ad56594c5cec2a988c5596d73adaa5a81802b40110dbae698ddb1f0b271fd1479c38abcdb9b234e69cd0da8a0328d2135c287d5b130a09fa0b899058e7800eb2dfcee95c1a 971544451c1ea77808ee863aa84e0d23d45a241ec193f94d8025bca13ebf8277b863a2a160a89145ec48e91aa60152b2081fd86795fbe12b621dff40d5e69c8cefe8d319478481bdf3780e192d449e7b04d3ad9b84b0b083de10c411d8fd3878 +00 00c4989bf33b3136bcb4ba67906eaff2bcbc6567635aa4b057acb7353ee87ba3cb4cb9838f8f679729d5c6ed98e6c4199cf58605f009c6873a1b8321f83cd3c0973b7a3cfd9dbaa5 82c5e113f00aa0f7d0d400c99d838370521f5a1c5126dfdf01a8df74be53ae9b974d8a7a62e3512234674841e1f9bac20906496fd23d4c44d593057db8af7f13cb6ac0e5c6e314e9cab928f6a217063abd067e323591bbc5e966f962ddd7e837 +00 01a96f2ad56e31397e236cafc108087479c9823589a5fbc3dc7488d0e5d1199cf245d7f21f524cc0e8b47feca14c93fb760e631434a91188b32965053942f3bd39b3714f9d6f1a11 a1b9ef3cf03346a454e4f3b151e13b06055160e55afebc53451a2b308bf3914919a469c47842d9896ef242b742f3f42b14e896b98e41133c13a003b93ee64248c54185076e0801e9a250b39919fd44e018ad14b4af1828cc7bf5ee083989d409 +00 00c08ed8e0e0f8b0d0714b46a2164b933f8147692f18da97e5a108c44d5a5cf221cb50536e41832b83bff4026c6df156386235cf5e3e9a67b7cf9b2fa7707c5e0ff33a91601b8e34 864699ca48ec2bb10194c7383bc321b856eb541d852233cb64bf8de0b3d01e3c82a1ea6f554625af00ff43d64af1c6ee10a1372b13c4d0e7102c4f9ee5702b11d81d7346d018d63dfe8d30210298e51a8082ed38885fa0f523db89012fe1069e +00 0144090a0ee38cfa21fabcc24d35139a99656911ad4f6dbffb77dbe74e7993edfa9fd63d2c4f6bbdbc8ec21ba13c9f4a3576b5d6e3abeab5af5ac81b1f2bb6d4c42dde645d854d9c 94d6190632463846c98bd0c02d2159f40f62e3fea0c2be40e79606efedde6e0faf4f74d6e1726f41ae841b13c2f9e8f001b4602fc52361d262acd52802e74608291b078aa3b2baa55dfe86233062eec726e8c0d59ee6e722db36ad584f5ece02 +00 01df26b672b2e3617b6b6c631d3c6be0cb49c0a690de49643e0f416215bcdaefc03fa9c708471f1d87476d58c8f147517ec8a14aa945ef001fa01984d5c3d81f7083ea500558fef4 a3de721e9f2e1aebb1e7682893b1b3aa893d361a37c4d18ef6068155d3638f3481c864c4b4115b1236b0967ba5380b1205802042b0cd50f7e2b2c9fc3242e980905b0f11e749ec24247705972fd51ee33279d4817c6ff59ae2cf8fe459565948 +00 0189918b832e9fa30161fdd927bfc267f6405335df3d66d225e17173af52a671138883bcb94c4403ca3e001fcf09ef4c6488934d6775af2b1da30a8f331579af2d0fbb530298d8f9 85812e4c72933b59841ecf9d27d861585707871e7aa7a5383fd893b3f8f8d99eecd4f2e6397daabde61569f2ba6b830d0e040873ce62b43199edaffbc11fb9526bb2747558b3464d1b5acc3a2ab35e32692816c174c6c2708aa05cbc2330cca7 +00 00bdcc175eca3a399b944eb0334ff33c4fd130999c8ac0e7b52ac5b774fbad53ccc3a31024f5262b2eecfeb2104b14bb244307effe3dbe8ed25686dbf46a42c4b6f8e34010ad826a 883c155a0046dfd66908c5e62201396d45de854440f3c9d232c580645fe01e208a2051f0d2adfff7fb4e0a66c5dcd71d0cbbda6f671ff5661db5916a5619a51ec4968489d2bdaeb6ebdafd6f173ea2bd4323ce74cfeedc62eeffa574d59a556e +00 0007ab5a55a1d8ecb7f5dca2afdf9ef465569a4b0374716f604ad42a6e0271e934b09655e8e2529784b69b2894bb399b02aeeae30e9e7ae70a2a8e56b9e775bd978a04c728e3951e 8a2f9b2d16f40481515418937807414a9a150635959f5c9575c8f27d9f4b2f9215fac889e4f440bd3ec7e0fe705a0eca194ee2cf78ec3182bc9b5695873e23e163fcf2a6db2ef89c846acc6d601d91860855e2f52e8c3819ec44e9f0812dc506 +00 01e7d4da72b1d82e17a066fe387f2a0a7fa4c60ab993ee09710531789186077f2f32b42ddda497d5fb57356383e1f96973df043307f0b6519430c3f0d40d62954032872fceb7dce9 98406ae44a206d6faba811bf393212b383570e3d16df382c49b486544a6f79574d03ecf27e4317bf2de7d02184eec000100a2c17398fa04566fb328f4c8626ab34642c19e0b992126cb7517447ba999a91495a29b47ad0dae81737b04959dc4e +00 015b7271d4319db5743119c8103a7d4c6d57e9c62f3eb93762156d2ebd159980aa57cea948e416717d715a2e458851f1b2e9ad4172bbcc53861db29c3ee0ba8e82617a5866170847 a0c2a47550381f174a0d69cfcc55369a7fa44b815eec1f4cbdd0cd073bdaeb70c4c5f3a697170de48e7e3f41dcf9ac8d00ebc7c4db479aaeb9decbc1c91e95bca29d12bab69fed4b215c59c8608bd6d37023dfa22cad805c1aba41f783b4198f +00 007219ea7917d174a5386df985d0dca798ac9f8e215ab2f0003aee929a2dbd91e37fedead0ed95b1e8aabcf516bdf54337b4aff7ace4c6b3179f2e919a49db50a41c9d4d58d4f636 9874e69c50129090fb13d273794e8d9198cc19dbf2a9384290a0408cc3adc83dcf8ed24ac46e00d65d78fa16f10f61af19dc71dde6a631b81bbf36e5f4881ee341a3f50306058c0c80730d8ea370ccbfb92ca1aea30ce7627d839e375cf90fc6 +00 00bc623152253da24bf8d752bd78aedf7d5f6a2f889453ccdec14e10753335ea8bea83fd181a1f3680ed50f2324fbeaadae160cc85831750e021f3e44121ea1b1efc29a7d0069479 90c8d2ccd37463002899e5b051fe444dbaa467c9dfb76f17fbc3f54f27ea9b54134e2837bbec94e05abe5d2baa8b773a1243fb7860d90cbdbc16383f071f6aeebdd506adc6478ae5a8779e52b882b5b0ec3a94546044843be1cabde28e1f07bb +00 00645947d981d258f2954558c31022a3b6ba5fa7b675312f794cb61bfff1d9ce87267e4a1dacb7c8fc58624d31c85ebe22f80d26a620fed5df5bf38515e0903f0b69a606048197d8 8c62ff02a587d420f7124ea525af75b7dab49639ebca64c7ddc6cec0ec1d72ec0622ecd4dac29c4eef758000addcff12161b57e01061694b0905d47fa6dca32b23ecdc14384a9be2b3328856215d61323533a645663a93011d585f91160abf01 +00 014cf93ca69d94ee8fbea0c8da9d76aea092b73073d8f5385b65c6dd4d567fe86bc2cfb8e8be890c3c6cd9abf7dc3a17eaecee3d7a9455887863e496c48dc3e47821bd3d825b6bed b8c8f611cb319d3923fd48d22d744bc99aeb46b3525a939bdad0c5694730630661c3b05d9fc412bb8420e711e3a32e3f07bb19aa1199b2852550d273cebf8dce4ad228f47b6e4413af03cf9288ffdd0461aaff84b25237fbeff13e68a33d3c58 +00 0033feeaaaa28f16bfaf5ea9c7319cf4561ba4fc55327a8477b6cd58ef6ccad3962ee1f3edb243f3a04e7e49c8e23509fa2d63252adb186b8bc7e9255cd61fa9bc45242d42da3a68 94ae26bbb68bae29b0cfba2d78c43c0aa92f6ea70eb3c8a17857e2e4ba396c3b7188c18d31c61cdaad7be259e8f64fa4042cf3af6c7df8ab620315ecf014d57b16c6573fdd4721d334c0ca6ce74eb1da1bc4f173fb46a6bfd0aaa6851a1c8f4a +00 005613dfb53149bf5fdc4e08ccc1c752b0b66ab43aef2d008ed40f3df40fcbb2938d2c41e3ea2dd4428aeba9059a97efe5593119673866a19d27a2ee37dd357e22b6bc849e7e22cc 86dc2b1ca91b218debf03e29ec94f680c5230b87f934675fbb4072d6b8c7820b67228630f95a4ab50a9ab9902494745111ad2a2b29c2d0784967180eca519975724207ecf26cdc89a62c0ec5b82cf7b62418bdddb555570958b59ebcfca55048 +00 011b92c8b72b86c51903387a65aa206988d443d1988253329ad3a89c902ff1ef8cf73b7f2e4aaa352443bcb833712d94c3e637ec12cbe4c2d4606878576b17fae1512fc77785b737 8d92ee126ed32295249077abbbb39602cd492ebc42cdc06a97e746c23236880cdd1f37fc4621ea018eeba4d0e77d0f100e275f6fac73e5e6467277c4b84fdcf3c497dda02ea0cf01c77f465c0aa8f0cf0d07231585263aa8a2ebb53cbe9979e8 +00 00c3c90d5ce4375a08b85575faa78ee6bbd9e5571ce5a90582042617b807339c282cdc3b003d82006264b1c08c20af4ad4549fbde53d262facb98d923d81b8eb6093374b6a1e84cb 8dfd6b8a4efeeb53e265f424c5b89901db2773a563f1edf4b7a28f03243ff4eba8c4e4a3ede574df01c57070640cd93d185fd65cf0d44f30f40ebea646769104f39cb1c6d653b1dbd5dd1d6a66723cdcde2d6def326002a16ebfdf35c8ba8e35 +00 010f184c16228d9034271332178ed485d10b6aa76003efc160d63fea26fbbdf5552205ac7df0d8c852a1210cf0ba512f20b798827b36ad56b12a826fa7dc1db45aed264ca6822659 a78738305aced0026c2479f72e62b1e52f59ddc6dbfb8d7d55d1bc15aa3a3b14ffe6a5223cf672875fff527920376c1b0488b4c8425a48f60d550a4c6e82e13b5abe9082dec57095d7d620aa314077893003b8c432d2198ace451313a1b305b8 +00 0181baf9d497159f837cba58a11ca435c442e5ca792ea559bff9f6a1f562c05bf6bb5914afbd1bcaea75b35f88bdd832314b249a5298622c89462344d3f28a44ba3d059df432fc71 8745c64af1bad6c8d969a35ebfa82b21377d23eb2c131bb5d0e6909022a0e56c60fb68dd8c0328cf9bfb9eaf3acf49210e06e39b9b161c9b5bf377509b78f1c12f8e30c51921f253764e21499c1494c39b55778e7bf08475f2fea0f5780c8812 +00 0083fae86ab96bce99a53e50b7eecff38e4e25b21c4b0f6a4986915de245eae24f16b6a00a4db159ebc27f5a6a072da94ab6be5bf75f5eb3f75c4452bf4ea7014392eb1e02706fb4 afa1e3d9fbbd4fee100862300cca4ba4bd9b48a888c5e0515ae7e238efce25c700900a5f145d9341063e9bdb626107a501a957d29040cbf3b0df3ba059b67a8da5f2932dddfda1c10e5a49fc1e62f34b6cb1ab4092b2ea6d7190bb67ad09304e +00 01a663efa7bf4d8479bc535fad71e9b5e4f4281aec55967baa008ba17ac2f89cc3398d30573edef29d590fddce8cb157f655e92779f59e7a18d0327d02e7daf4c1216143b3688fed 80c8e232be938b8f3a0db6c7961348f0548b92f7436106cd900044cc82e3821a5b51f3092de206c2d4f3f283edc99b4f0c9dd8d8e0407cbf2545647c7581fcb7cf447ba4fbd1e99ae99fbde6b89a03f02dca7a73d752acb351f858b3dfd5b813 +00 00088d1a2c0219696a94337cd56516252b74139ea0733b17fdcbf7692c3e5f6c3989e5da2aaed7468e65a5d578571928ca273ec3b6aa72cd196f560f05095cdc8346e5d31c4c2e0c a070ed48fc59b30dc15a95fab36fca2efba7c9fe1dd8ab9a5dc4ce6610b260cba6764e36a56208d7134cc1025fbcb65e144f59318ac1b0835f3ebf4730425bf859bcbe80260973ec3f6cdd06603b61ad8c7189f6e2c35db7b0a107a8af514a30 +00 016cc8a0fd59455ed8d4de561fd518df2e008f7dfaa5f7f29ac2489a411e233917b43eb3ebe2596fc824be58871949545e667dbcf240dfb5e0c615ade0179d9ea2a1b1ebb8ab9384 a339f41328f649456da806f22d81327abfd9f4e1dc3e8a7597ff97a18904ef4106d5c9e5aa5515beb2eae7a1ef6889f5108894482020fc7aeb6906489940d40ca119f15d0394efa560b7920ac99bd3e66a00cf76af12aff978c3c9e0b5dda0f4 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P224 b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P224 new file mode 100644 index 000000000000..48bba65bacfd --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P224 @@ -0,0 +1,60 @@ +00 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615 87e26b747225024627f2bdc8976289fea20bd508d54fea5862307537f545a202117cdb010f5ccdf921fae39d15db3e161156e957614e1699ebc81e67202d50ebee21ab24081974cff85f4f197b7d349f9eefa0734ca3a06beb9ab06791e2e959 +00 cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5 ab3d54de8cbb00d0acdd4b8880fff9748d7987335ac0900087423795a75a93edb5fd5660b7b4fa2b73a683421d7ec403021dd9bc2bfb535bdb4c54628c343fda6e73a8055146f7a0f0c5ef4a3970959ba1b1db9520f632d077e3275ef35235a0 +00 dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73 aa891971676c00623290d883b7f62e293432f8c9d18892c9d9a0a5f5b418d8dca2c805da615e5fa4e8e2b1d112e6ccc613408fb470b7fa82f82343d3a5f82ab509ed3ac1da4b117da9405b9d8826c1e82a1b92644e8493188eb7681d709fa1b0 +00 aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e b6836dfac4af8d0b6fda142cd004e040bbdc840d34b736d1af82c6500602875baa888435567d4f627f1a74db3795e30a1184ed656fe3369d1f8401f366094008f71a7d6a8110a029f7030895f52d968d53c6e18bfdfbe440fc38bb89b1fe9424 +00 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4 91dbc86efe203feb6d8819d53ac888fa4583707dc443a3708d9b09f6376ec44f1260dcbbe27c7c41b198e88c77dfae4708dcd428ea37039e00fc6ea3c08858179c40c3a1bf860b6b0cb4c13a21adf1125ba2a902a53cd6b73101054f8ff4dbf4 +00 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131 b898ddb35d9a34cbc49138ad93994514fe5d9e0b7b3855482fcf5a67e085739f662725baf5b18973871896a8c7e6251312285739bdd5ba398c03254a967a3e0d8c06554178e0f26e0f9f858e6b84c8b6be38d92288e2b6241daf2037ce44ecef +00 d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974 8ada5ca8c7a5ef73d5fa314a387d541f0b35350b23737aa8ad330db7d1768ab9c42faeadc47efebd1b1aa529bdf1c6a100859114b9ad07a66857f69125050c83f3270c98222b8b97971c8c02c907a8bd1e98b98061c583c53aac3d841da4d01f +00 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8 a5445e5d31388a7dbdaf1d0f1c447f8f7a738b42d6668efd1c0e466a9df01bf664e98fda2a3a84b8e7ba698e7343c4be0fe77e350f889d1789dcc52b6bb2446fcc4d09c4ef3a797338640c442ff24d9f0375f5350771dc89636af3989d8244a4 +00 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2 999833f026c9c7a239ef502f64a6c6cea06fd82dc5f7f36d53ea7b31e1cf72552036a3aaff1988db17482ed1c302b96d0c08a59a59585a3618e9a55d130349f245dc0923ce56c76045df07b54e9e3d5bf3d72c28d39784c3bf3d3a4a5a61c1b1 +00 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7 8e9422be4b65c9f9045d3884d1433bf4e799b9649c9345baab812625b50d2a4f948c8a7c2bd2abee2723825fd4eeed33071a8dffdf5e455009d5316aa2a700b76502f03d96160450468db0aa6ed1f4a331deb5298809fc7e63d7c7fb28b89958 +00 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b 819f105246914b793db926eaa9af0fa79ebaa50eab77cccf2ae912b8b62dce37f6564de9aa96226dd45f53d64c931759077de4097be241e367e50d7ba0bc3ad10fa4155c413bc289c06b095298cfde79d94fdd329990f46fc5c0f52309d1b575 +00 c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6 8969a7e7e8d9492d7618f2a3ac2f107b0285a8de4b051946219f47afc9e5d1803264e269314a73cf0cd54f3e1ea9080b0eb8e5754fcd6c8856bb1dd559fd128ec080c08d51e45aff3046b4e54fc7d7b9aaefbe09f8ec5a7cee247f5edd12fb83 +00 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc a39fde6c761cda2e7f6d75c55735eb1f38fcecad57aacdee089e89d1e813430efd985544666c904c659905484156885a00bbb67188af2cd1bf3a1ee3c7dedeaad63e6a2f4e79741727d9aeb9ae51110966f6fd14afa266b4f910c720d9a5d4a7 +00 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3 a9c3c277d401f16542cb4e38b2556c5d8a6ca066c23256d529c8359544e7ee9f069de28501b7bd71a19e3c0ac2e2afb300c767bf024be9c270c0c51e39cb56fc544f8b29082e8ba6f25ed47967ad335774c687c4e9dfa99075c553f0c3be471f +00 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912 a7600d36243ee560b6556ac2fe86969e5010d3d0774d13c005d139f92fc0bde5995f18a29327c84f367d517e8925bc7d03e27ec77421f2294e6c2c18ed814f3b31aec10c026a51bdad0705b217bb5439394c8490a37a4eb94ab13e96aebd3b73 +00 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa a16fe645568e357136fef6dc5df06d06db2e8c95037a857c5d2a981b47ad135514e8b774e61c0f5bf52e619513d86109125213ab61cb00e7c03b83bdaf189ed0d41a23be73bb28996da2a80e1e55567b6953ecbb0a7edc16bba62a6c1be92d9c +00 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972 8c807f106d93d400d9e608b34a9c2b181c51e4811886d77d3f93370c0d5d7d52c6a2ded4e531f6dad3e9b2c8ab8b04590c473250ff32376eac97bcab742e20e173d9a9e78d9409c9913bc80f3c8cd9eb98062ff4a10ae4606aadbf9510c97c57 +00 f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170 8191b10f07f3a1f90f27c00d1e5e6b8634827127f86d475015336ce8edf3d8c8e31fa3ea2f2d3510a5221e0dbfe3fbae0a33ed247490911df9f8dd89c5f7828d023e23acdc57817973b079b96e43187f0bca669ab785a60d86a88b58ce5e313f +00 c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85 9657a3e08a8d9d00d0a32f88725df3212024b4680c6659b67b14718b037263be9932f7f81458a6ec3b9d47fc22761e71051337079be6f9ec6e8f9ba8ef1dc8a222df8184f721c51b0356e48428f075ce7bb18993b80f12c62c0da2787a5933f0 +00 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6 94291a1dc4d3e490289375e134a7e9dbe763cc74a4111bbe82726831e534da6f1ef94e67373ce964d26a44d611da44d00f2af186c6f9e2c11e5354e950366ba75e6e94ae31481708e7368fcc53270ab21ba9a4c7c213725f47b7b4d778417a0d +00 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39 910556d7c4da360cfc422d7b55723c27f38e65122c2bc13073c6c87ca8b9cfea54db21a7fb10b912d95dc33d515e6bc614a7160321c67201f6b0101a0db623a38cfaac69ebf14d44da928183ce78394212c1dfab90f60873d44d5b80a0188436 +00 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6 b76cfdb3f411c7478fba43750cf45768ac546e8607fc8b73ad4b3eebbcedabd341926ac143d91264a30d8ab6bb9d5f960115a07c06a2b44295597659582be7d68ae4408702a6f6580096391c3b69d3f04ae8a87210790cbc67f17dfc626e7a66 +00 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b 921078cdc5ea11a03343aee05635b56dec596c421cc674482a37e955697025162c1e59fb9ca4c0310445bdeba07271d60d71ab990190f59aca4e38fc1755b8aea8d52a3e6be340750c012f5652240dde17cd4c83324e065fdace8dbfe2a19c1c +00 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b 96093fcde4b9c9c6077bc9778d648bb3ce1091a697c202ac5a96f7550fba8947ab4f564cecc3ab40c7ac967a609526c607a238933af46389c31eaaf149c3f094709944f6c167c409b4265991f9389ee2a544ec29aafc70e14cd3c5ed63c1729c +00 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8 a632ac05e51452e1163be8a81c65409eda9a3d8004dc88badc88e94e7f421e64ae913d867d603d3f10a20f2e32931551065c42bcec5c3d9ba4f721addce4d8c734c465a43807e568d3975938ba446492856b95d47499edf51a0283aba14fe5ca +00 e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784 a94b87c4e18108622bd59d1b3d58ee1c2c27942b09b6cc62050269226851309fc3c8c737d156df6e05c92fb367d1611801191cffb5bd5f08c9945300e721bcb07c1b7b03556012a5eb728afa693e2e25cc0b769ca91e06095438fccb803ffe38 +00 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c b720e032d20a4f48f21de4ef30afbe89c2e4b412d78b766b5c1201f5f783b47146c60a2238f5ca0104fb02ba8216371616008e0f00eef37497565d0501a3e0a72fb1fbd1bf7b912f094bbe68d400e2e05317cbfaa49ce0e6b59470137ef18cfc +00 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583 adc8d3be75a648a533d00e2d8252a723be738e55c32153e421b9c82ea56823c7c7557245798254de4d1d1fea940f1f51154757b5f87989518d82b340d84b990820e3f6cb507f58e32aedf0738e59bad2a614ec2914cf09e5c1bbc064fc35e0a2 +00 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2 9880280d5d9b2af07c768f67d23f3401d2b71ea6d83bd991bdc1396af75088607e62548f89d69d0630243ad9e1e6e56e1266a4d2786997e4c4716e3b3316b9b89125c02fbf72c699d00012a2844b687e12ede8fdfece16299c2c3d63e834c65f +00 f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc 83defab0d1f0c5d8f1939939153fcec9c71667cdc24ddead95133e1ff7bd31f28b12c08078a6412365e9d7959c2937d2063cad4f91501f7264ea33318a2cf5eb5bfc00493233d0f4f6f0195e10658f7a9ec9e2bec3e86e9a2d59011b0fc797b4 +00 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd b34310e4cc12d328dc64dc641dbaad9e43760b2e6095d03c61a4c741da642db232413570d6f4d774a8ee826d78ae872c0e30578e5acfb558d24f1c35768a733cf604891bcc344c0daf1a2f96bdd68d3ba51d704b5352a2d0fc9665a9108fc322 +00 e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3 a186534f887b64772caee9320293e491a30e61dc73e62b98b2fdaf9efc861de130d84c789eeea97296f530bb61b8f8b10e1bd5f05f18d768cbb6740a9b63166e6ed762660e813afaee5f0295ec29c4ef2fbe94dc807da066307e49ee47b0f353 +00 b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17 800315c3b714ca243682b8613f1f62994f1b44e9844e8ae9b7ea4fb09e7f849c609decc7c109eebf0439ad0cf96266eb07cb3ac7442f390b541a57b9e1d254b0c7982b2af32d5fa86484e0d811413a1c9e36a3fd2c1390e17ef3638f5d33e46c +00 efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085 b83a504a41c9e8a050aef760fcfd614e2e5027e7a13a63704a801ca5dcb589495ac6d2bccd4c837045178b3b82faf775177519b58a5f7b6c4d1970b3c8291beb233abfd66376af9089d6ebdded9edf782f72cb4605e8406611b24284062f875b +00 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd 93f8d43ed20493efad429009228c1b74e9da0a7b7ee6804ad6d6a4aef0dffd5439507fa40576bd6b1cbcc7313a0c0ac21825210295ca8efcf56eb5f7ea3e7717ba921a95815606d4ec5431f908d31fcc31df1b69c78b118c4928084c55aaf932 +00 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d a3e0667a9dbff0ddbc6fe74d9b4179a75dc1f6b24f9d28b361361d7c5ffd173578f950ca8a43284cac98fe272a351dd50b3768ffc98423ad1e329f9a7104d0c15b00002b06ab389a9084fc07de9f528dcda2b29518e74b2bed7cc6bb705442f8 +00 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0 8bc552e77ce59233c08051c0f2b374283cc685a7bf0bc9496b86e03f4d7645514be0f74e1dad1b0bcf024b053e08208a07a4714470bb9afb3d91f8a64121483b007428042efa7503c39cba289fba9479e0ec55f4c5e9fd068bdc6660e987b9d9 +00 e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d b26d9c35669eca6dfbdf4f429e4e1ca9fb90932a258f621c1f2cbf1d96364ce188a3a351c6b466b5405a3915db9b1f8603e6285c4c4d0ab30a36f32b2aa343cfa5817e6b868bfe3e73c4cf352e20b163a080183158e2859302657075d8e458d7 +00 f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7 a845c2e00854de7ce1b2cdb2fc81bf2da8f312ff773cce1c668d2a649bffeefc16d06a3352137d73480284d216eddfc5187a5395350da6384fe161a796eca2a873b9e9397a7cc298df2a1a966524fb03ba87459e596433e500d9557b156903cb +00 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c 969376db2dc64ca24d5174ce46a8d4414d4ec6d6b27f1445a8a95ad7377244bb8faaf99c8fde100cd96b9528c2cd70d70b43dbbb5469c16f0040e86dda20b9a8e9ddce1069bf5c599ce35b526f62242755f66badbc093f32a4980da126554b36 +00 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18 afba8fc5e200c32d055ef2236de618d23d40b9dc8398e24f9b03057aafcc7e48ee6aa3e1aecb1a5c1762a80cb9d6cb350387c1a410b08d2573c59c39440b1873d24bace85de464595e9b75576278a0cb44b08af631bd9db254e29aab28f84474 +00 bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a a345a487d8bf3b83601b300ab20aaa53d0a7892aa832a0c6f30ce4574cf3fecd54348b95cab1ae70cc61ccfbcf38a7ed017dab2d4e588d56fa6dec92ccdb4acc94ffa6c7880096cfa3f7589bc903ddfbfe1e8d53c25414f98062bbd0733c2aac +00 dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738 a133127283eeab42576ee783464565bb64fc82ebf19419de156b36a97afb78dcc1c70080f18994ad2ba49a2f2a1c934c0e6248f8d10fb348e21a8485c5f1fdd25b9cb651d30632a13108d2ce44eb5bee3ea117fe687fb59ef2357dbb59539ad9 +00 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01 8490074b2d72654c335b95bd3aca90e19c6fc4c163566f4c80b3fe05b6b5c93a2a704eac8fd313cd529c03f882c5403d05d5312b1ac9887d0a1e80b7a003e2b78e74ef6a3a8f6ed79477131223af5850a57f94ff2a3592c0557bbeff2aa05d2f +00 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28 8e7c4578d0ddac8c8385f7679636e1163b7480134dbddde4a1e5cc369f7760c87e4be3ca132c89fe23fb1de0b60eb216058c7aa2850fb51ed0b2b10dbc4167fa5d2ef2cdb83d4175a16b16267dbb5a6fa9df7af13e790a24b0dcb12b60f00489 +00 ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6 a2376630707da1e994ced71c341f6b5d3b6b1dff747dc24f83e90b1fda064063f84e6d55602076a6018720abde3f33b50a89acfd048d21056f60108ce282d0ff9c7c6cfde4935595c0a6e53c423d386cf466142a3f21f488e62886d7bc7e0615 +00 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc 94209278c2ca13c045fe02964e85825ec07f8ba68077779d8258abadee6103227b7a2154ecce0fe2273a238c94a747f108e5e2dfe8748b756dc3dcae81d5002a479af36c3fd27c2681fa258be8a52375710e6e24ad79c6abd4b7ba3cd8980a8c +00 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b 9610c6e3b884797c8468380f296e89a4ce5c5db2415c269405b8fe197c5c2599cefbb039111c2fc7844dad86ecd5b2c21053a88b0f0dd16c786b53ccb49ba06001140efeed3187182e2a71a0a46c0b19cdc5f3c2cc297a16995687ae720aac50 +00 afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc 8602d9dd587319885519c04b46374dbf035c0efa23c2d1cdc89cb09010c82e688b91ba500f97b87e9a0898bc10226bac066af1088779bcfe967a153ee64c5f2e8b1e5c99b9f2f2a710dab6ac8b7aeffb19a84dce84e6aa2348adfd18cc9b122c +00 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c aede8397b145f98d78f125ac4bafe02d3bf2cf11b5f2b49b6683e36e714825add29f2ba666a68bc766f5c644228cd4cf177298e106561b6d42f633b6d3d6ed16c66236296c1f7348b66ea351065b4fd83ff28261c73a66f23675640b5118a83b +00 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc 915cdb004b3b44ac09940c5b9c865521919d8cbcc75c7beedcd97cd021ff9c671d2696036c93d71af53389f2ea93581d183a37c68eaf08e12683497e4a6756892a22b136de52bb48fda83b5769aaeeafef4ad8f72b5a65993dfdbc0c39aa068e +00 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4 953629894b6e45cec914a8231fc7ecf7566b30735925d18f54600d9fd55cdf0e479ccff30b00c2a6ed0f101004e0a4d90bee99045d3017946c51720352a555173b5bb5e4c84f3cacdc251c1edf84bc0c9a6113b32818581a7a893653d07fed1a +00 a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916 a18fa1b0ce3ebade28868a3fdc810ca53b7cee3ec7ed52d844076ab1d5def4fe45c868e421f12eda2db5b69ec977fd00163806498baf26918a2bd409967d527191a7f12199146ebe485d9b3c57a0ba7264a0a04e6bacd240ed826db97bfd52ff +00 fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b a89351004888607ab8f843f91f6eb1d5cf8cda1592b3819673cc7e16514a629d359f1ddb0df5d5cea6e0a328819948bc03000cef8c44755f030626655bb038d7c53d1354e788e4e52ddb5a3ff36304738679bd324f0dc477da13169ba7184b28 +00 a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea 9327298db7adb595d94114abad802d313f4f12bc0704e373696941fca3012f5e1cea28f264122451e659fcddb3da42210b2fc6f71a2db6efed84136a80ac0d913aac4061fa19f01e16855955426a50a2954aa6647acd04fe5cb77fbd5dd11a10 +00 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0 978ab721a797f9cad2f22796ec70467102e746f18a29a71b186e896beadf434892aca7c02a4654d5ded320c69ccee66a117db23121208a53af57f0cee00ef52fb483cb7f4e932321de29e5781fa748d19a73f0d2ec45ccebd30fad8dd0d98009 +00 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294 898351ba82e0acf23eb0e2f8df4de010c1f480d08b2337874abbb1d6c65b02ecbc78ca1517d121efb79b7f47bd1e441004fdd5f0cf5a70b011eb83d17a1ef453153758aeb9433edb9dce79c7907f0a4b2b9ec1f4d7bcea3c71fc0c9d22aebcd5 +00 b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a 88d63a45648b45c4abca4d087386bdb571012f9bdd40bc8b99c2c28a20aa21bd913565d28aa3b68ad9e25358c782f60d03d9954bff95c7815e999cdec780a47483dfc6436e696d7c8367fd54e96b6f45937f542bc015df1cccea806cac0478c6 +00 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4 8c1092d066d63f328c106867d2bf4d4e4cd9331ab35746bb1524c5970c234c43e70f2fa3cd08faa5ca8f008ed3df7c6815a53ffb481c0b9d57ce1d248c16cecaaa9dd8ee02dd8493e8abe4aa89fe4c980c7e4a59cfc0b9f96daacb04629809c8 +00 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04 a59934db54a8b5741612159108a4365124223312efa8130bbddd3050e538e2c952c0d27d2e2b6912b3a9ee4c8222199118e4a98c9ba756c8bdaddc19da9d676f64312617ff6055d677a02fb6941334a567d2a6d17e98d057bb4bc435d74a935e diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P224_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P224_blst new file mode 100644 index 000000000000..48bba65bacfd --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P224_blst @@ -0,0 +1,60 @@ +00 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615 87e26b747225024627f2bdc8976289fea20bd508d54fea5862307537f545a202117cdb010f5ccdf921fae39d15db3e161156e957614e1699ebc81e67202d50ebee21ab24081974cff85f4f197b7d349f9eefa0734ca3a06beb9ab06791e2e959 +00 cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5 ab3d54de8cbb00d0acdd4b8880fff9748d7987335ac0900087423795a75a93edb5fd5660b7b4fa2b73a683421d7ec403021dd9bc2bfb535bdb4c54628c343fda6e73a8055146f7a0f0c5ef4a3970959ba1b1db9520f632d077e3275ef35235a0 +00 dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73 aa891971676c00623290d883b7f62e293432f8c9d18892c9d9a0a5f5b418d8dca2c805da615e5fa4e8e2b1d112e6ccc613408fb470b7fa82f82343d3a5f82ab509ed3ac1da4b117da9405b9d8826c1e82a1b92644e8493188eb7681d709fa1b0 +00 aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e b6836dfac4af8d0b6fda142cd004e040bbdc840d34b736d1af82c6500602875baa888435567d4f627f1a74db3795e30a1184ed656fe3369d1f8401f366094008f71a7d6a8110a029f7030895f52d968d53c6e18bfdfbe440fc38bb89b1fe9424 +00 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4 91dbc86efe203feb6d8819d53ac888fa4583707dc443a3708d9b09f6376ec44f1260dcbbe27c7c41b198e88c77dfae4708dcd428ea37039e00fc6ea3c08858179c40c3a1bf860b6b0cb4c13a21adf1125ba2a902a53cd6b73101054f8ff4dbf4 +00 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131 b898ddb35d9a34cbc49138ad93994514fe5d9e0b7b3855482fcf5a67e085739f662725baf5b18973871896a8c7e6251312285739bdd5ba398c03254a967a3e0d8c06554178e0f26e0f9f858e6b84c8b6be38d92288e2b6241daf2037ce44ecef +00 d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974 8ada5ca8c7a5ef73d5fa314a387d541f0b35350b23737aa8ad330db7d1768ab9c42faeadc47efebd1b1aa529bdf1c6a100859114b9ad07a66857f69125050c83f3270c98222b8b97971c8c02c907a8bd1e98b98061c583c53aac3d841da4d01f +00 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8 a5445e5d31388a7dbdaf1d0f1c447f8f7a738b42d6668efd1c0e466a9df01bf664e98fda2a3a84b8e7ba698e7343c4be0fe77e350f889d1789dcc52b6bb2446fcc4d09c4ef3a797338640c442ff24d9f0375f5350771dc89636af3989d8244a4 +00 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2 999833f026c9c7a239ef502f64a6c6cea06fd82dc5f7f36d53ea7b31e1cf72552036a3aaff1988db17482ed1c302b96d0c08a59a59585a3618e9a55d130349f245dc0923ce56c76045df07b54e9e3d5bf3d72c28d39784c3bf3d3a4a5a61c1b1 +00 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7 8e9422be4b65c9f9045d3884d1433bf4e799b9649c9345baab812625b50d2a4f948c8a7c2bd2abee2723825fd4eeed33071a8dffdf5e455009d5316aa2a700b76502f03d96160450468db0aa6ed1f4a331deb5298809fc7e63d7c7fb28b89958 +00 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b 819f105246914b793db926eaa9af0fa79ebaa50eab77cccf2ae912b8b62dce37f6564de9aa96226dd45f53d64c931759077de4097be241e367e50d7ba0bc3ad10fa4155c413bc289c06b095298cfde79d94fdd329990f46fc5c0f52309d1b575 +00 c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6 8969a7e7e8d9492d7618f2a3ac2f107b0285a8de4b051946219f47afc9e5d1803264e269314a73cf0cd54f3e1ea9080b0eb8e5754fcd6c8856bb1dd559fd128ec080c08d51e45aff3046b4e54fc7d7b9aaefbe09f8ec5a7cee247f5edd12fb83 +00 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc a39fde6c761cda2e7f6d75c55735eb1f38fcecad57aacdee089e89d1e813430efd985544666c904c659905484156885a00bbb67188af2cd1bf3a1ee3c7dedeaad63e6a2f4e79741727d9aeb9ae51110966f6fd14afa266b4f910c720d9a5d4a7 +00 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3 a9c3c277d401f16542cb4e38b2556c5d8a6ca066c23256d529c8359544e7ee9f069de28501b7bd71a19e3c0ac2e2afb300c767bf024be9c270c0c51e39cb56fc544f8b29082e8ba6f25ed47967ad335774c687c4e9dfa99075c553f0c3be471f +00 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912 a7600d36243ee560b6556ac2fe86969e5010d3d0774d13c005d139f92fc0bde5995f18a29327c84f367d517e8925bc7d03e27ec77421f2294e6c2c18ed814f3b31aec10c026a51bdad0705b217bb5439394c8490a37a4eb94ab13e96aebd3b73 +00 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa a16fe645568e357136fef6dc5df06d06db2e8c95037a857c5d2a981b47ad135514e8b774e61c0f5bf52e619513d86109125213ab61cb00e7c03b83bdaf189ed0d41a23be73bb28996da2a80e1e55567b6953ecbb0a7edc16bba62a6c1be92d9c +00 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972 8c807f106d93d400d9e608b34a9c2b181c51e4811886d77d3f93370c0d5d7d52c6a2ded4e531f6dad3e9b2c8ab8b04590c473250ff32376eac97bcab742e20e173d9a9e78d9409c9913bc80f3c8cd9eb98062ff4a10ae4606aadbf9510c97c57 +00 f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170 8191b10f07f3a1f90f27c00d1e5e6b8634827127f86d475015336ce8edf3d8c8e31fa3ea2f2d3510a5221e0dbfe3fbae0a33ed247490911df9f8dd89c5f7828d023e23acdc57817973b079b96e43187f0bca669ab785a60d86a88b58ce5e313f +00 c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85 9657a3e08a8d9d00d0a32f88725df3212024b4680c6659b67b14718b037263be9932f7f81458a6ec3b9d47fc22761e71051337079be6f9ec6e8f9ba8ef1dc8a222df8184f721c51b0356e48428f075ce7bb18993b80f12c62c0da2787a5933f0 +00 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6 94291a1dc4d3e490289375e134a7e9dbe763cc74a4111bbe82726831e534da6f1ef94e67373ce964d26a44d611da44d00f2af186c6f9e2c11e5354e950366ba75e6e94ae31481708e7368fcc53270ab21ba9a4c7c213725f47b7b4d778417a0d +00 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39 910556d7c4da360cfc422d7b55723c27f38e65122c2bc13073c6c87ca8b9cfea54db21a7fb10b912d95dc33d515e6bc614a7160321c67201f6b0101a0db623a38cfaac69ebf14d44da928183ce78394212c1dfab90f60873d44d5b80a0188436 +00 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6 b76cfdb3f411c7478fba43750cf45768ac546e8607fc8b73ad4b3eebbcedabd341926ac143d91264a30d8ab6bb9d5f960115a07c06a2b44295597659582be7d68ae4408702a6f6580096391c3b69d3f04ae8a87210790cbc67f17dfc626e7a66 +00 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b 921078cdc5ea11a03343aee05635b56dec596c421cc674482a37e955697025162c1e59fb9ca4c0310445bdeba07271d60d71ab990190f59aca4e38fc1755b8aea8d52a3e6be340750c012f5652240dde17cd4c83324e065fdace8dbfe2a19c1c +00 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b 96093fcde4b9c9c6077bc9778d648bb3ce1091a697c202ac5a96f7550fba8947ab4f564cecc3ab40c7ac967a609526c607a238933af46389c31eaaf149c3f094709944f6c167c409b4265991f9389ee2a544ec29aafc70e14cd3c5ed63c1729c +00 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8 a632ac05e51452e1163be8a81c65409eda9a3d8004dc88badc88e94e7f421e64ae913d867d603d3f10a20f2e32931551065c42bcec5c3d9ba4f721addce4d8c734c465a43807e568d3975938ba446492856b95d47499edf51a0283aba14fe5ca +00 e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784 a94b87c4e18108622bd59d1b3d58ee1c2c27942b09b6cc62050269226851309fc3c8c737d156df6e05c92fb367d1611801191cffb5bd5f08c9945300e721bcb07c1b7b03556012a5eb728afa693e2e25cc0b769ca91e06095438fccb803ffe38 +00 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c b720e032d20a4f48f21de4ef30afbe89c2e4b412d78b766b5c1201f5f783b47146c60a2238f5ca0104fb02ba8216371616008e0f00eef37497565d0501a3e0a72fb1fbd1bf7b912f094bbe68d400e2e05317cbfaa49ce0e6b59470137ef18cfc +00 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583 adc8d3be75a648a533d00e2d8252a723be738e55c32153e421b9c82ea56823c7c7557245798254de4d1d1fea940f1f51154757b5f87989518d82b340d84b990820e3f6cb507f58e32aedf0738e59bad2a614ec2914cf09e5c1bbc064fc35e0a2 +00 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2 9880280d5d9b2af07c768f67d23f3401d2b71ea6d83bd991bdc1396af75088607e62548f89d69d0630243ad9e1e6e56e1266a4d2786997e4c4716e3b3316b9b89125c02fbf72c699d00012a2844b687e12ede8fdfece16299c2c3d63e834c65f +00 f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc 83defab0d1f0c5d8f1939939153fcec9c71667cdc24ddead95133e1ff7bd31f28b12c08078a6412365e9d7959c2937d2063cad4f91501f7264ea33318a2cf5eb5bfc00493233d0f4f6f0195e10658f7a9ec9e2bec3e86e9a2d59011b0fc797b4 +00 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd b34310e4cc12d328dc64dc641dbaad9e43760b2e6095d03c61a4c741da642db232413570d6f4d774a8ee826d78ae872c0e30578e5acfb558d24f1c35768a733cf604891bcc344c0daf1a2f96bdd68d3ba51d704b5352a2d0fc9665a9108fc322 +00 e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3 a186534f887b64772caee9320293e491a30e61dc73e62b98b2fdaf9efc861de130d84c789eeea97296f530bb61b8f8b10e1bd5f05f18d768cbb6740a9b63166e6ed762660e813afaee5f0295ec29c4ef2fbe94dc807da066307e49ee47b0f353 +00 b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17 800315c3b714ca243682b8613f1f62994f1b44e9844e8ae9b7ea4fb09e7f849c609decc7c109eebf0439ad0cf96266eb07cb3ac7442f390b541a57b9e1d254b0c7982b2af32d5fa86484e0d811413a1c9e36a3fd2c1390e17ef3638f5d33e46c +00 efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085 b83a504a41c9e8a050aef760fcfd614e2e5027e7a13a63704a801ca5dcb589495ac6d2bccd4c837045178b3b82faf775177519b58a5f7b6c4d1970b3c8291beb233abfd66376af9089d6ebdded9edf782f72cb4605e8406611b24284062f875b +00 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd 93f8d43ed20493efad429009228c1b74e9da0a7b7ee6804ad6d6a4aef0dffd5439507fa40576bd6b1cbcc7313a0c0ac21825210295ca8efcf56eb5f7ea3e7717ba921a95815606d4ec5431f908d31fcc31df1b69c78b118c4928084c55aaf932 +00 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d a3e0667a9dbff0ddbc6fe74d9b4179a75dc1f6b24f9d28b361361d7c5ffd173578f950ca8a43284cac98fe272a351dd50b3768ffc98423ad1e329f9a7104d0c15b00002b06ab389a9084fc07de9f528dcda2b29518e74b2bed7cc6bb705442f8 +00 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0 8bc552e77ce59233c08051c0f2b374283cc685a7bf0bc9496b86e03f4d7645514be0f74e1dad1b0bcf024b053e08208a07a4714470bb9afb3d91f8a64121483b007428042efa7503c39cba289fba9479e0ec55f4c5e9fd068bdc6660e987b9d9 +00 e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d b26d9c35669eca6dfbdf4f429e4e1ca9fb90932a258f621c1f2cbf1d96364ce188a3a351c6b466b5405a3915db9b1f8603e6285c4c4d0ab30a36f32b2aa343cfa5817e6b868bfe3e73c4cf352e20b163a080183158e2859302657075d8e458d7 +00 f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7 a845c2e00854de7ce1b2cdb2fc81bf2da8f312ff773cce1c668d2a649bffeefc16d06a3352137d73480284d216eddfc5187a5395350da6384fe161a796eca2a873b9e9397a7cc298df2a1a966524fb03ba87459e596433e500d9557b156903cb +00 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c 969376db2dc64ca24d5174ce46a8d4414d4ec6d6b27f1445a8a95ad7377244bb8faaf99c8fde100cd96b9528c2cd70d70b43dbbb5469c16f0040e86dda20b9a8e9ddce1069bf5c599ce35b526f62242755f66badbc093f32a4980da126554b36 +00 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18 afba8fc5e200c32d055ef2236de618d23d40b9dc8398e24f9b03057aafcc7e48ee6aa3e1aecb1a5c1762a80cb9d6cb350387c1a410b08d2573c59c39440b1873d24bace85de464595e9b75576278a0cb44b08af631bd9db254e29aab28f84474 +00 bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a a345a487d8bf3b83601b300ab20aaa53d0a7892aa832a0c6f30ce4574cf3fecd54348b95cab1ae70cc61ccfbcf38a7ed017dab2d4e588d56fa6dec92ccdb4acc94ffa6c7880096cfa3f7589bc903ddfbfe1e8d53c25414f98062bbd0733c2aac +00 dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738 a133127283eeab42576ee783464565bb64fc82ebf19419de156b36a97afb78dcc1c70080f18994ad2ba49a2f2a1c934c0e6248f8d10fb348e21a8485c5f1fdd25b9cb651d30632a13108d2ce44eb5bee3ea117fe687fb59ef2357dbb59539ad9 +00 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01 8490074b2d72654c335b95bd3aca90e19c6fc4c163566f4c80b3fe05b6b5c93a2a704eac8fd313cd529c03f882c5403d05d5312b1ac9887d0a1e80b7a003e2b78e74ef6a3a8f6ed79477131223af5850a57f94ff2a3592c0557bbeff2aa05d2f +00 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28 8e7c4578d0ddac8c8385f7679636e1163b7480134dbddde4a1e5cc369f7760c87e4be3ca132c89fe23fb1de0b60eb216058c7aa2850fb51ed0b2b10dbc4167fa5d2ef2cdb83d4175a16b16267dbb5a6fa9df7af13e790a24b0dcb12b60f00489 +00 ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6 a2376630707da1e994ced71c341f6b5d3b6b1dff747dc24f83e90b1fda064063f84e6d55602076a6018720abde3f33b50a89acfd048d21056f60108ce282d0ff9c7c6cfde4935595c0a6e53c423d386cf466142a3f21f488e62886d7bc7e0615 +00 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc 94209278c2ca13c045fe02964e85825ec07f8ba68077779d8258abadee6103227b7a2154ecce0fe2273a238c94a747f108e5e2dfe8748b756dc3dcae81d5002a479af36c3fd27c2681fa258be8a52375710e6e24ad79c6abd4b7ba3cd8980a8c +00 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b 9610c6e3b884797c8468380f296e89a4ce5c5db2415c269405b8fe197c5c2599cefbb039111c2fc7844dad86ecd5b2c21053a88b0f0dd16c786b53ccb49ba06001140efeed3187182e2a71a0a46c0b19cdc5f3c2cc297a16995687ae720aac50 +00 afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc 8602d9dd587319885519c04b46374dbf035c0efa23c2d1cdc89cb09010c82e688b91ba500f97b87e9a0898bc10226bac066af1088779bcfe967a153ee64c5f2e8b1e5c99b9f2f2a710dab6ac8b7aeffb19a84dce84e6aa2348adfd18cc9b122c +00 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c aede8397b145f98d78f125ac4bafe02d3bf2cf11b5f2b49b6683e36e714825add29f2ba666a68bc766f5c644228cd4cf177298e106561b6d42f633b6d3d6ed16c66236296c1f7348b66ea351065b4fd83ff28261c73a66f23675640b5118a83b +00 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc 915cdb004b3b44ac09940c5b9c865521919d8cbcc75c7beedcd97cd021ff9c671d2696036c93d71af53389f2ea93581d183a37c68eaf08e12683497e4a6756892a22b136de52bb48fda83b5769aaeeafef4ad8f72b5a65993dfdbc0c39aa068e +00 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4 953629894b6e45cec914a8231fc7ecf7566b30735925d18f54600d9fd55cdf0e479ccff30b00c2a6ed0f101004e0a4d90bee99045d3017946c51720352a555173b5bb5e4c84f3cacdc251c1edf84bc0c9a6113b32818581a7a893653d07fed1a +00 a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916 a18fa1b0ce3ebade28868a3fdc810ca53b7cee3ec7ed52d844076ab1d5def4fe45c868e421f12eda2db5b69ec977fd00163806498baf26918a2bd409967d527191a7f12199146ebe485d9b3c57a0ba7264a0a04e6bacd240ed826db97bfd52ff +00 fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b a89351004888607ab8f843f91f6eb1d5cf8cda1592b3819673cc7e16514a629d359f1ddb0df5d5cea6e0a328819948bc03000cef8c44755f030626655bb038d7c53d1354e788e4e52ddb5a3ff36304738679bd324f0dc477da13169ba7184b28 +00 a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea 9327298db7adb595d94114abad802d313f4f12bc0704e373696941fca3012f5e1cea28f264122451e659fcddb3da42210b2fc6f71a2db6efed84136a80ac0d913aac4061fa19f01e16855955426a50a2954aa6647acd04fe5cb77fbd5dd11a10 +00 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0 978ab721a797f9cad2f22796ec70467102e746f18a29a71b186e896beadf434892aca7c02a4654d5ded320c69ccee66a117db23121208a53af57f0cee00ef52fb483cb7f4e932321de29e5781fa748d19a73f0d2ec45ccebd30fad8dd0d98009 +00 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294 898351ba82e0acf23eb0e2f8df4de010c1f480d08b2337874abbb1d6c65b02ecbc78ca1517d121efb79b7f47bd1e441004fdd5f0cf5a70b011eb83d17a1ef453153758aeb9433edb9dce79c7907f0a4b2b9ec1f4d7bcea3c71fc0c9d22aebcd5 +00 b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a 88d63a45648b45c4abca4d087386bdb571012f9bdd40bc8b99c2c28a20aa21bd913565d28aa3b68ad9e25358c782f60d03d9954bff95c7815e999cdec780a47483dfc6436e696d7c8367fd54e96b6f45937f542bc015df1cccea806cac0478c6 +00 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4 8c1092d066d63f328c106867d2bf4d4e4cd9331ab35746bb1524c5970c234c43e70f2fa3cd08faa5ca8f008ed3df7c6815a53ffb481c0b9d57ce1d248c16cecaaa9dd8ee02dd8493e8abe4aa89fe4c980c7e4a59cfc0b9f96daacb04629809c8 +00 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04 a59934db54a8b5741612159108a4365124223312efa8130bbddd3050e538e2c952c0d27d2e2b6912b3a9ee4c8222199118e4a98c9ba756c8bdaddc19da9d676f64312617ff6055d677a02fb6941334a567d2a6d17e98d057bb4bc435d74a935e diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P256 b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P256 new file mode 100644 index 000000000000..714abfcdde49 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P256 @@ -0,0 +1,60 @@ +00 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590 a9c529dff707a6b12633de4087c4a556500d7097131ca30d739015c2bf5be16992cf16e74a2e98db04c8ea948d22da5005394d36aaf927b9b9206c9979f412d5a5f7f7a141ecc0563c6f2cb6a60a099371d01f94aa849df52d3c51c492953f0f +00 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98 8b8d49db848b7ee120593ad927b51409822aac20307160fc5becaf5f9f21a4ab860294af61ba765600eb4c07061659cb0cd5336d9c1eb944e9a88e88dc23c9a3d924d3d8b6f79b18fad0bbbd6146e3f68e00fae8e5dc56115156ee84dc77776e +00 a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870 b718db517463cc7f9d7305a7939d5e00cbe855f3ad515e2f2c036755748c26013110d509e76a07f6ab8ecc9443d97b1e13d1221a29fbd64bb9e302cec7263bc50f1a833d3698f475759171c9cbcc9dee8aea83abb4fcf8bad48010e5c85d0eda +00 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f b14667bdfdd315e1b0e0f2ab624be900b0a15fd51da252b40a11afd8ba3a441cf4870c9ab13b7afc4bf5805de182db6014f4c0b324b1a27e6270cbd19b23e4543415a0c0157ca82ef8d3d5985da8af669b37644beabdc64e254e9fe79957efee +00 daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d 9718bc4859ece3680acb00c2a4a7096951ea9d2e9a52e1ef513942711e8370d0ab0138bb4789aa713ebd2305781b88ac01af2a972a9bc667ef6615b84ada3d475815e150f4b9d5458bd04cc6ad26d1e2e95f8bb7fea61480b0da77ff8d93cd04 +00 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5 aa2df27b6dc2097d836f68516d45fc28c4e1f89bfdb7d19fe0267c762a7c8bc383dfd58d8c858f61c6b7ff50ae042d090179cbd61622a56fe0047744249fe6c009c9d7e8e5d431ad02c15ab4d7190818fac91bdcb5f18ccb95859dc4084d5f42 +00 f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96 8f892fd3f16939b7c9445ac7add81136ec879b81f8db5746071589747bf9ae95d86abdcbdf9bd732e0651c2ecd84cb370f39ce3bbd2ba69e379861a356a3d5a711bd7c829baf7c46d74762b2a12cfe65a954b8eaa1409af89989fb9d574178ab +00 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d ab91bb57c57b57ec2561e124937b7dde705e8a9c1b608b0101c61921a9a3533a567db9a6222df23c8e8f3b175ac9ff56027c18a36ed472fe40a0512e67016ea3262bfc2c6d35501fcca7079980b3a2c8d4aad005e73fd9a43c8716a95e6f6537 +00 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9 b791e720522059b94860345b4e32e347912d6b04503717e8bb2663f364ee05984cda778b2a0fba7f7199c2841cdc26370ce14848f4ac6e343aae640fdd301579566c5451fc19e178601e01da1c364e373adf13a509b78e4c0e92f4c959473a73 +00 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634 948a21c4422768d5e3a3d0dc90e9dbba730aec9732ca2b9ae03064220590bafe25943686d1192132de7facc4dce5b2b501d113cf2d62eb9560e31a65279e93044db8ae3d41d475497f8b877958435229895ae60b2af8abfa377fd9ae9b7b5a62 +00 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27 86194772ade81adbcc5c0955feef30d97313bfb21fa290ea667c9b1c0001585534b56c68777e146df3d033e82c10a40508efe3384260c1dea14d14b902a4a93dce8f9a9953b266968c64772552063d9f0fea8aa74df75bfaee6ca909b9c84c0d +00 cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d 8528169cd757c1e7f1ae9b088aeb708ce5dfc2350926872a19587d078e369b0f7b467059c3fa04822a2fe53c1025d629127a30cc99ce32ba20d56f1eb35fdbd9b64907f168359cf1f46f33eb02ed1a3afd20b27ab57a5bc61308e005eb264b5f +00 b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c 97569efdc927e65dcf71f513fb280fb5b71f50d23e7ad7af8ebff4e9815b7729bf9192fa1c087b3f08ef4683076ec7101445e473220b8fbbba3c06cb96e4e5129fc1c6549be7da7e37e01b113f6ea9a773e77d7a2668d44d8117ce9b3eb47288 +00 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48 b6de7c4fdd6ba94158091aa5183e550d7a06349c3696a781a2aabe6d9d1d30f1616ebe4a1465c4022f1360e6e90a297104175f26115979dfca6eefcc931f5a38c615338c0da429429809e9bfa0ca40d78bd2e350a0c69fcc4a14fd6ee4530e39 +00 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f a85ce8a8f4b19e84f3970989214f95a0e7e3ec176b5fbfb1a420b0cf4be06ff62202df4c563ff43f28e731dfff3f419c11fb4858b05be0741d0fc8f1b6ee722ad42cd16035e73739992752f4e6e8f53b01fe46c3bb4398ad2af399f64f2dcb89 +00 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 a877c28c9428d510740757660744c0e6ffd6ed9cc6db7c58b6c6c986ff5c2497c2b68118f0a8a5ebed3ac759db1ef4c8055e83fc41f49c4b929fff03343aec6c37d8d193113897ae0d8fd263cae1d655631cb5b447f6da76618eb83929220b79 +00 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 8003907280883d881709b92a2832b154754cf240ad21077d886405db9d699687334abc879d2f9fe669116e747d714cbe0fd6ea9a37b6f690aeeefb6d45007c704a8c1e9bb6b76e227e3670aec7e9c97c7ca75650c02f5c757fd46ad644d902e9 +00 e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef a3fe957fdaae8e08fe7740602eced2079c2a46dc298c2ee7dca6e6f5aaeb94aec5f2e7059b6c3b4a0c70532d399c2afb18d117be8e73ac9e501e06d44969843a176806674787f47c65d2862cc01364b2f85d1b3f834a0347ba73b24e401725ac +00 a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 81ce2958efc16dd4eb78cfa16a5e2c6a4ea8353863ee1bc75867d8ccccc68f2b41ef73e772d03b77b7aa6602a0f0ad540e515fbc2badab0e2c563cd874aae69c774818e20a8620633a29fcf3fe803c3b4afd232e97d81bccc66b0eb8b3cd252a +00 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d 881daeb1b3c80cd579c738d83d5d7ccf4a8d16dc109dd1553defb02bc8a32c99520b8b23afe7c7f9e9a9a961ec6656b309da697967d9c6d15093d729b463bebd20c49e725294fd50bbb812be932dee395b978a2521258e8d26feac9ade586839 +00 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d a35714f99b24e4f5681cd2f7fd7135e2f7e3859dba535d73bd8e5fbea466c3367d9a3012d65fe4ed24a7d9605d9b624b01305ea95e1554fb6a875a9665dff903782fc1ad135010bfce3953d6d89d5ff693985a04495e90e531bc7cb057d536c8 +00 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab b14123b677eab644a9afc931888b44451d2ef06e1be4c38d8231df08bff8543695dbbb8395b82963443f766492b6e1c9086ec2cf367f6213634cbaf2d23a183df58b27626920d2987c340770b4d14f89002ec3a4926477b375786608770066b1 +00 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a 87fcb4017d52624c17be2f4d7961b7c20224c6be3a169dc4b30aec426f2de1820eebdf218380024e25f13e7f0aca72f90477034d5a656cee747552c4eb6c82807941253b3e521b49db5a732455c4b24d791d6268127e614ea33befd66a4df200 +00 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 ab0c038e9888c26662cafff920343457b5ad07c989b1d3551c3a7c692164fd4bc7a03aa8a2ebca325b68b5a5c5ed400a007b29a4a5f9d079bf74f2f7a8a3dd834af82b57a4873620f224ee572ee3d4bd92d0caa889baf19ebe2d6bbc188a6e9c +00 f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 a02c7cacb6cb4231b915a78019e24dfd0f40995be41c6a9ebc4e83192b24e6ff3a8049af28301060251f7602236c3cd10f1b6e6b6d6cf2cea3ab42756c91775281c457e4e8e773e373dc35b0a1309d9f60841b6d09fbc8351882c0ae90d35228 +00 b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 aaa4f5b9b5ddb21ad1dc1ab6ccce2463fc443de8a983f1a6161aed0ab164ecbb55632e262ca7cf402ecefa43bf43fead12b0ba740ca2fe684380b959c3318a989779c3006b3752a075cadd94d94b107c17dd36c6a78e1f7896665a96437e57d6 +00 d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 b3f6a1be39063b1d5f9a32fea02a657042b150365989dc9aba7a1146bae8b202e163bc6865807ae487bac7300783345013dce7b8aad2ad6cc9c4fd248cc7c3042bd1e29b3d1471d5fa077204aac2373584cc1039c133d461871511a3d4a34778 +00 b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c a32ff2e665d617f84a92ddec1adc29053570f4e2f1e342df603d4062fddf4ad1f939176c18196b46d051ee9b79592bb703b56f039ce290a8de61056936db83154f63153ebbe555d595927efa7f404b4b3786453da52d6807735125856d1d073e +00 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 8aafeca50a490cd03bc9ee7b32ef802d3087aa3e2bf4a841e3f9fbfedd57a18e3217d55a86181ad389fc656256ffd2e50108f6d28e2fb4f0a9f3d672400136a948cd1319d1d1bf7cc0bc01d562162aca78409245bc91cf31b74148f4d2082b5d +00 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 b64de64ed6c0b09566c4f422bfa3008b8aec58faab80d92692f7e02cf8b9382d1666c131ecd78594354d9035ba6e61fe16d62ebdd2887449ad99d4d9e83b3d4cf1cb5aab509446c3cfe68ca4b4d35ea0d1a2b41900669fb4ef6addef80c333c9 +00 b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced 89e33c681bbfa46f7f1f2a1d806d3f2d2e5feb746a1796be32b67d8490072eb7b14a352a370f815ddacbb1d4eb4962d9160da843441b08674b4d5ef07e490543a0f4c69f84903728b414d10bc9b59e264163012df32df65244480bd80cdbbe5b +00 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181 8543e676538ee9781dccff769db675f55a5fad0c30214e9d6f906089ff3b93fb6d7e225690f27e4968e0b97c51ef89bc179482739118d2724224c827a8d96a31a72614886f8acf2ac3d4e735771f8bb1220b1fc51f3c82664bb96225181c3221 +00 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431 afa2e9fc0dde74b7ba7503c4baee1b144b223cf6e06c0cdd1b0fa855b95e8c5ab195037ac04d018c5fa9a7b2fd4576191039cff33db77e5b371b63182d496a43d9d766a138bee73cdd89fa9a41cee71c7d0d982d610d9e50cd566ac1c466233c +00 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd a4688572099fbe49acbbfb2f6759bc3a335b552d24179383c669c797dbb18cf41ba35d71e7bf1f882331457dce90f72912382e3fc827630854dd5e089b19da82e3c3d3f46478f3351519a989737a57b6ca7f0319bb1434a28a4287a0e2975327 +00 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de 82079969ef44d6cbd51437a860f7b0800d500ee1e28888d124567258c384c4e85877b71dbcedd19ac703d244e8a784091755d0d9e727cf21d040f31250251f4c96a1949c0c323386e03647180b808d6c777cbaaffe78cec8d27f8f9afaaa72a3 +00 ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566 b077c7a4c1a82215dba33f7ab4aa8f9e722e6c464790462142a2fffdd91b4d2a7bdd6e74dbf3f726600839c2720373ef009314a72346eb1382fb05c4996ecb1565ba660bd830c5c23b3fbd898032f7dc52b02b111c2e3fb0c37fd31645b54892 +00 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee 8966c98ac0527f2d2f6617397fcbaf1b6787274fea7bac3be0685bdfe439fd29a96a62fe83fa5282ff9bea44602102fb14638107af11d7a3fa6a4926b67804565a4a8b19d69259936ce8d57ce95c6281788990b51accbe3b67149e6e36473d95 +00 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd af2d67b83c4770fde7813229cc3c6bf417862218def098fbc6485abcd3876b2f0a174360761f241b4bb296449f848e200fa67c612bd1e9cbc630a96826bbc0083b6de4522869638e3beba79740f69d7c544ce522150149030c04c55a2764e693 +00 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666 b932b96c18624f4a6a62147aa1c08c6f94e4aaa953e27fd5299d9b39c6d3cf8cb4eaf283fbdb156c12b0d7d6b774bc6b184ccdd4848aa2a910254f049aab6c0de4f94fc86972a9874e1acff88742f0eec0ed7ab3067c13809cd0245cbbdf3dd6 +00 bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67 a9eac565e78cbd371b371be1c85b82feccd74db3077088b3efad905cdd89c16c5ba01556ecd1470ec184d1ae8eb71874163771168ae4f06c771f1ea647c899297ba3365d1b22d5ddf791e6001fafbc6e174de634b1158d26e45d2b336158f2d8 +00 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9 944b16e2b58b7e34487e9b3e405aa24b0679198ae62b45d5c9e0f3fa054def44994dfc5086151d9e0b1937b1f96bcfc5098c076d035bbbef94770c7db5eeae506b6aff4acf26dc0d22d388a70b9647c52874924eb50848e41214ae49553b33fc +00 f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce ad8850f2b5d7444efa498a5e6e3e195b704109c256d473aa46db3010cdd6001ddd7d5ebe439110b7ba2baca836ea91b71833835aacd6a0730586db7e02390bda5836eb5849ccc2c07261942501fd9da22da3e3205b88439ef65ae6ee1df36a34 +00 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f b6974432b37de08cd15a8b04655961bf5a75706608ac9a836f2939bb5d3ab223d8ce86885b3fa9083fe3582bb7e50b3e0a7e72d3c4f99e52e455101a0df14f9b5d067f3aafda947d321d5cb598014df479fca5d646dee87ecc43c73e9f13392b +00 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b 807ea33fc198fd3d7365039f4ad5f95f59d5fd54a1c610203ef78d3892b235c41fc664ca956db4a1067541f36cd548390d8e951dce8ae11f74ed0dcfef9610a3cb33abecc7335b636ae8a1420fc2a2bfdf411d2ca5eeb73472b0e77889a86d27 +00 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388 837a4d3a13f7f7625d5a7d853c92412a9f9835f84a68c4fdb8675bc04809f0ee6af0e5b7da314ba04599be8e5ae14527037b6bf7c1501457b43a17ab3615e9abfea5846702b1fcf510a00b581065b3448be802eea5a62a947565bbcee4e6b480 +00 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499 934c9bfe3fbe84ac8ba977d905e9019a0aba02f9269344520e52791faf06453e4e11165df3f3d31408ee0f23e016026f028d2ccb6139c85ec2129d49c34ee928d8c9e65e05530045c9429bb70a60135c291dc8aa8cfe0a214a325bea0742019b +00 f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6 b0e962cffc9b97e81ac48c8dca152fb7ae3e781c3f0a2ae41da5870706ec9b380e8490c10afdb0320da89b25abe3bff6151a3d2b63f2d664b03749fd70cafb138e3b1eb7d07f54fb9a1acca21e32aca2036cd3a8b4724f4a576934cfa753bed9 +00 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead 930845bea66412e1281592feddef01e110b8064d8927de20ab4c6cc97abf5e5da088648914b010575c816fa6ca84a7440142722e46183ec674e4fd8c9f59c07b877a6e4152115f69b511d558ec864b178278b6db2002a2813ec7e2abc332734c +00 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd 8c1fb6b71c86be348cf0e87a6accf25d8b1ffefe59dfa6e540f614966857be7d6292de761e2efb0741e4ca7c7433ece00b352ea53fb2c93e3d6513ad247c04dc84485c67d0209ee51d7502f98287ac587432aecc14752c8626acf2e55a0bb143 +00 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117 b735e06b0541fba5c7b7327f43299af26e37a40a9455b974cd53d8f4bde40560c0addc65177c40e0ac6b1a8425a85b4c0a41d1d10fbc8621bf3d1f57a65810c129089723b49853e5e5df69752b7a98dcb152256eeb9121cf4fcbc3db7ac8b7c0 +00 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61 959ea12dd94d0c473929f37e741da00dede50941661745e4f5d35072231f173b8877895820f8df4d4c1a6f3115934d1506dcdd3a5e32486878255e66816da07a43362c1928604deec4f17be9ec9c34e6db34e1a107456f4275d0d9e6c1705851 +00 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2 8dbfc3ffb776348f065e60a06d91cffcfbc3d02e5b02a85010503fbd1d7fed023959cc5644bdaff534cfa3a2d1702ae211d7b71833f4b071db8ad5c432b28d42ace8aafb943ffcf50faba0e587732c4e424f06374ecd2cdc4b49e70e9de5e071 +00 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7 b8e96dbfa05b41af9cb9f8b2f12e684593480122df82d8a6aa8a4d0a8372574450647a289057270429c231c7894f18bd17f564ac8367f7d16175006b1db7574950bd8cb93bdcd6c3758966c6be16b723b8a88d85e293da06864dd0e279890419 +00 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870 ae7d6216fac7d1d68b2d371fd329b9b4a7821b411f19bf25361caa1cf9953b7da1cf98e1206bd61fa2084f612398148b19e506295ce52224de8dd9c9e7f3f6eba8c6c852b106a4c09f84149b5715349a99942958c9e93aef1e5cacb9c671d04b +00 e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf 93b9b7bdf2b0019a383025b4c845d0c37cb1569675f97a7af6405f2ee0f97ec947177ef4e81e33c95fb7d7a0961c0e1b152b227c921ed4c1436b8dc3a96487adcc742726bde2ecfcf73f998e2ce30d1f8aff856c1df5d9e27e10d219eb2a2a79 +00 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c a69f4e8320ea9b790b87b6c9a4827f8c0c5b02cff996301e461cac091d14fec02e886a1f126fc74075ffcc799b70dfe30d6aa8c33768d37ba47d48233b672fc48f25940fc53226b7542fb42995af06c6eb686cc7b34b88887cbfb24d238fd8cc +00 f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9 89e0981fa8530f41f757bbbaca45d8c99af4846cb38aea2f6ecbbe1f8c6ecc6db6b5cc16f26cc4fb22fedcf4b7674a681204d9800f50b619d28d89331ac0ecfc7fc30e1ffb63db4defaaeeaa42aae1a6b9368900c1634582f579a04e4c05f0a4 +00 f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5 9897406f0d53737346460f6788dec45fc23ffb02cc950318656d58ca6eceb2789cac167700fe9c2ca203e5321ba51caf0fd3d812917bcc39f21867176d0cb4a324585214d6ca2add9996ce25e81b40b5c454e33f9d04652dded687357ddf2a72 +00 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628 b39b9b4964757cefe6fff079a01b018a45306936fb4d848fb7200116483947f2f22fbcbe63d71a2b954fcc6434d2af7001d450f31ea3b5e42e6b6fcf9e07a1fa2d68f7f644583a4c537be8e905e422bfe0c8fcdcc2cee34c3e89e475c14021fe +00 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49 80ce87e6bd76780a3fbe60077a945cca66bacdb9767416a783dc46dad1adeb4be882b773cb0cf34f6a76ebdde80820160fea9e75814a5ad98adbe812ac89b31513baf26a0dec9d04b8f9431ade441579bc97ac5b302f202fefe9ee73a187d6b9 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P256_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P256_blst new file mode 100644 index 000000000000..da113dd7155b --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P256_blst @@ -0,0 +1,60 @@ +00 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590 b3d02633ace417335721d54f4533f9f4379674a8d7cccbf6b5d6faaaf1b1e5daca699b668c18a0fc9ecd5520f5628ab90433e5854116502200d0f98cb94abf012c7368e6547d3f816bc9af4a7365f8fe5c9c5dd9931990f8ec05f3e6c347b518 +00 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98 a34f5e1849d1533957d7d73f47639fe1e6aa03564bb4da6ff8ec912b2fcb34c9c9a0a8e81da615b9439d94ac9077536d18838e871def5782f3c7ca221898867f8ed520c39856ed9041934a56fd6f7d5cc91be7e7a0f34c04af39899397d09054 +00 a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870 832b7c3d6e28a507b24adb13b2017a8eaddd68cade07ac9009bbe8ded2b98269966628e5a9d4fdc462036db9695e0675146f93f116e9c40f383ada47af782c76247a11b8480711c55585d2bf858f0c22a95b04e7c695da9e14cccbd204ea7348 +00 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f 9441d7d83eb499686386b83eaaca95a583ed6d0d8008ee3bfbcf254b8f77f45667119e66690f59a314207b9f7ae723d90c387f076100bbb655f396efca0c152f0b434961f18d1b9baa6397083e4d87eb1c701b13bde84e14ec75ac0854f54736 +00 daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d 80ebca83ed5fc77bf34014d3de15d7e969dc33ab2388b21d25b33fd77574ceef54d38a6196148cc91985bbee805895ad15ea3b6d8abf4c129917202c224178e44858a358be0b8d902acb0ee7975270781b965a618a96009f8275deab4bd64778 +00 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5 871a38d0d30409aaf896a74c4b7a006e3259f486e11bb0f956cc6902c52dfaad895e5527765921b067b528d6d06a216014039032aa3739e1c6f6d2b576fcdd314177c469c18853695857174513e57b48f57f8c4d9f20735a2b837e2688dcebcc +00 f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96 a8d1497ef10c1df3199e7d75105a53009c067f9ae1b27b12d839f4c5038f44b0af1a476f3188de0c5b8011a6f9277708196924d1aa68f8cbb347874fae0b6e29361e320d69374f1f322ae501a473a14aeed55cbbe6adea5ba0dd42c801792095 +00 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d ac94756fed79d6671688d975f3a5474cee02858924334603f6da6c86bbc8c61187b1ac66bdd287491c50560cc72f86a31399e55a029aebd51154da8fc13715c5d75671f3c2ea65cb7b9d4aaab0d65f795067b2ac1f1e05de254630c22c3f79ca +00 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9 b757bc0935eb8d853828e0ffc662b48939fea76ec517afcf7810576429da6af6bf9cbeda269ca45d7374cf971fb7de6e0c29f240a7cdf1b4dcc0f6368edd64637a7e1b489c59c1265a939c015ef63a8ab3d5ac7424c7c45b8a0ca83cee59a9c3 +00 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634 b2eef4f6585be01d7766d991f4ca3db09e5df52d31b6ba915c535955656aa7884c21091cacc60820047066431d44da5915a4847dacd81196ac060b2a43c62d144fcf6884270ec9b7cf0b78f67814e3551b37b37955213cc4d2dbf1b6db20f090 +00 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27 aad21f37319df8a7812ef30de75bb3b21e0cd80146d5b0e70f8191b6edbba12c0fb0ad45e7d770bd8a9cc452a9f3a3a111b2d9eea7bceca2203e70b7ae6e89de73c3fbdce51a4517c9f63a90ebbff990f3586fe2f3676b026cb20491f3f8ac72 +00 cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d 91fdc2ace6a32475c9a3b6a03262be4d6e81a8367dd5dff1882b2fd9b358ba4de4984087490dbae3f30e359f8f113b6317399e4909c3d8733d1afa745fd34f6fcf676b9be5e6f2918693688c09a8ecd5a41a2c5a1c5fb731805a4d3d2d7e1e25 +00 b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c 8a629c1a5f85f1cb096080fbf041b10b24250946d9290a71d50ed4a664419d85ac2eda5cb0af2e1b699da014b3a5b11c0c0d8d532ab7c31b0e5e350bb9f8c78911f6f7397e067cff7b43bfeb862f43f8ecb973aa18a357f497770b90aa5e5404 +00 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48 a0d6405a3dc31c0340fa422fcebd210c53b1067ac7b5f1a4817b52180dcecca6f3ca04cd86df76b5893d838a9640653513cd2beb53be3aad7237e286a62bba2b3b59bae2265d2e8bf513f2a9c76c7d1a5ef676564565daaf420d2bf4fa3d14a1 +00 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f 98f82d27d25f7589cbfd2bda33b0a630106269cae3f038cd00baf7f3ba88dd618caccd6fadb095e6e101148fc9bc8aae01a5e52323d3983acc5e9c3ee612abb8b8617aa48579fb140783c2705827414ad8c4830080e1acd7961ea3ab01ee82ad +00 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 94744ccf70d247d52c197adcaafbe09ba6b420bf48b94e211d105137358c542831644e87b8d8b9ee3511b7b2cb94c6a10fd7b4ec333907c640a86c5a6d9f15c0196137e0dfe0bbb4d4c28616b6bed6313664482f7fc13bad80dbe846f60ae904 +00 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 900e9bb9f2b62fc31330aab1e881151dbbdbc2c843740e3b178f17acf6f604fa1031a9f260765830e9ecb0b11aa0c1df15803da16f01808c93cbab6bd06d0b6785cb3fae9c6369eac128ba1d28282c22b4c7ed3053ce2be3e08c19b1345d0aba +00 e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef 982dd2860749dddb511cd64c6a24362ebc790bd3788c7b43c392ca4df88dafd309028c15596e7ea2ece9e83c6c83eb060d2489629c8d10bfe22774ccb87f89ac113a709ddddaf51a353ed57775ec7e7391009133388128bc0c12e7b98c6a1edd +00 a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 8289af5025545324eb04f1aa04c10ae1b965338d32f3b9d83ae73227c3125d2fe87a0214321641e751e10661837be97506bd21d5f94f77f437de0c6ae13f9c1d7688d807853b5c0e7ee8973a4379e5c912ed88f33f5ec12cd26573e9925f938a +00 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d b390741e564af0b114d16320884786adbbfc9570b697758f8ef1f68e3349241b58875caaf0e32dc962db7a73ef2ccc0a00859f54898edb70eb81f7ce7d7ac9f74f8cd924999a2d7f51de3bed983d64781c9b4e871da0fee30f4003b76b81b21b +00 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d a7028a7e35f49010fac3df8ddfeaaa8cecc06ec8ef6b8abf9241c9b1c3f5b4cb31a2af34116776f6c659eb615496dddf05856373ce1a2d113d0b89e3f343660a8f1670e93d6e1ae37c0fc1f963766b0c7ca30516b0dad335bbef40a6d25c165f +00 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab a13cf53de2de79f17f59225834cfa25a2dc5a621112f47bd789fc8f85b241acb54638ce3c9b33de0c9e73174faf0eebb15257bce49aa51b841fa75658b2225bbf5caf4c8d287803f2d8bdf6e44571653a83de9a2726494e543173dea2b5cd40e +00 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a 85b378fbde844be5992675a8a656b9cdc31bdc15cf3fc614ff52c4119349d7c525ba432b46e02c90b5a9884b330b1ede0f961b1a352dd001e05b931a39b2057537d17d6e94ce2cd85c16dcb393df236ef17ee328c178be65dead5a1278b90561 +00 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 94fbbc81d7a3527885305e82913be58a2cfff3293b77a0efe5c0f2be60c5afd799a6a4df7ec149fbf85c6bf591527184144060b4d00144276e5a353b4d30bcb62d7b6e412307e0ab7e689cad21ec6617cffcb66e00f136207de6e7d03e1aa63e +00 f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 91b0b16f7328f92cc6689ed2eaea3e4a87169554105e4364e4f3f07879f191f00310eeb9bcc19fdac79e0544c3c13fa21163604316b4d41e9389d4122c14a93f6710c828534577fc634e58b5c01020b234180ae3b571121dd0f8823f0661dfc1 +00 b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 a6ee4ddfef9f089d2a88a55356cabf73f74449bccf8672c935fe8bf22c266a49d9184bc94541ccc775374395cfd5204c18c5cb11789dd2980b58d74a6f7c6f6e5bb1d81728d4811b08b836ad4ea4c0384ccd67e29afa5d966e44463f604ff44e +00 d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 a63d1f0259a6884b746445cfe792097a8702d8c0875a592bca6b155ab05517e584c1cbbb5a562bf915087f15e5989f6305bf6fc21a14ac519bc4f4ca31120cbc4fa47caee4badd3d0dd2bf2ba4b9a8bd765cf73bfd48e2bac50c63449b3d9aaa +00 b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c 86c169c30d48a32ec626a44a9585c6d03949f669f77af177f3727c50a39363c53d331cff995171fb7f51cc08da01476c105874b8b5c6414c130a0251bac91e56bdcbc33ecb2e0707b3e7df8c513b160aa9c23bc6eb3e99f6f68efc4d1e2e2c0d +00 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 af9ce9811eee5b37209df81fc5a2cb44c1ae48bb71af7a7fa54daf2f31b38c0ef72d3a41efc6c41a296b1a8ba320480e09d0276abd0aca6b0ce612d73376ec5289600f1f2a59cb88610668b299fbd08e1eea563caa0e17216ea20c0ac72d97e2 +00 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 998e4eec2bca44eb6bd50e7417118329cde7798f26f9fd5f2f00e1960c94e7c185c4c000cb39cbaa47b84aa456a262430e6b97f05ae90e2f4be00c470b2007c01567693e8518318001b72dd69eecd6338892969d90e02e8fb921c430fbc3052f +00 b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced b8a0b77f926c63769174c7486f7d62514897667e79e15b6820222be306a7cb94582bdb44d867cb0606e185985c883d8d04efbe9c06728a221ac46ebbf6ada00ddd281633a7c3e704ba1276051d97b05c1de8a34157703b22c4abb63042ef49d9 +00 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181 9166a250a01b2da4398b56d8b97f4ca2a8459bd06d66fb8760181adf2128a10b3782e4c327cf5b8fae6dbd508aa89e4c019d9beb145069613d417b4262385d5474366135fbafaaf9d380418d7831f32bee9a841350b4f6b0e430017c5adcd40f +00 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431 a4dc7b60b2d505fa42f581315c86197ef075ae36a62c9ddd6031f63fef819252879579ca12eedd83c4c21fc98f48e2510d8284e5a2dbf6900b257df0540d4d09465a293e61adbef822c72563580ab6eb4422e9a89e11a4645348043af73b56c8 +00 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd a9b884b9f19e90a52ee2c1fd9121508dad5445045168cd1e634b76c4c3bdc78537630262c304466817c7599fb90427ff14fcbe5420a29886316abe597dadf89103994c4c5ffd4e30e3a234e9e1659271706b57145795841cffaa4013847fffec +00 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de 83760c8f8de56486d5585c0ea9927c1ec61a77b5dfeaa80ed7be0871558d432439ab5e4e19030bb27beca1f44552a39a0963484d6f3facc397ef981a872fafeb3dc92b5e874848133a65de3fab1fc0723046d358971537bc5e5d015775e1f85e +00 ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566 abe5d260fb24bdf8126ed612dbfe96cb2fd28ae195a85d979e3063bb1e04935d07404ddf6650e99c4b840ba6e30a30560ce7e44adbf8b7e1dc6389fe91e2d6cd8f4ab40426a0efd5c93f16da6fdf5b4850c46c454a924c107bf7984c288d0ae0 +00 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee 9212b86cd5bb8ae7998cd580283658f222f467fd06f8e5ce130812d8c715e2e7062d8576770cc3ab5711bb6252ba53b607d31174ce8daa9da2e25ab446d0bf15faf3162ba5dbfa22f0c0f2f9a3a23581a039e3dda7e9bc629b904192dd3ea527 +00 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd 91aa2d9e051d4c6df06fdf9b8fe1c989042e049495157b1df4000debb360f24836de2fbc375694389fb7a7812a1d08500ea3667b6d0117873b3a28443c65bf333d5d986cad9d50602fb9e035c08b33b01c785a9c8d5c94002e75a281e7bc3ebb +00 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666 b648f02d0c523807377708d110c1077b098540b3c98a28975879f1d21fea9ede2774047da5f96248ca10927bb745d23d04220c1391c8efd6217bfa433aa6c65cb057204109b5ebd7467ee5f0c43d8a0c9701375716e26dd2d9bb8ccc1039e577 +00 bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67 b813eef5c999cc428939260c9521777492eea3edc17d9d2827436e6a28bc220a8f9a99cfdb7397790933f05bd3a9a2b10c35f59a905b3fadf99e85f8ada7e3ff6d564a272a03ac7b9d4c21118ccd1e5fdf8e2f983b3a4984647e9b00d88d9cfc +00 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9 8ba023d8fbb7999d0741ce322116490e840a42a6b8032a36eb5c140d0f720ddf12c77c0ee35ecfdb11b0f10f803086060696b74e2b86761dee8081497459dfeb2e942b0e8ab6dfe1a43db4ab655177b78a83b400f8bb7ce0bd45c9a452fd96ff +00 f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce b3b8af632f7992aecf93df698cd4a7f3fa5fec07cf647b2b376d23ae4262343ae1bf0bf10a9ab82020b865a77a154cce0cff58547e52e56cb342531010db163279983014a8c963e14d33e3d292dae6419dae8a292d443aa51b8c331c7bd7e6f7 +00 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f a70b1edeebf4105e186a9ce9f3fa29f2f1b3d18238ca8b7233efe9d2d6ca03f192661d95aad8a1da9e8cc3e956b903990175d5e20f4b86d432c382d0100f0b862c9257ca09c8c215e2dad949624c121bdf1f1b4b286e2b7857b443800f9a7427 +00 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b 9484cc71cec842a0ab9bc0376f562e24b0d156b8ea51fabf702ef324ea6f621f95ebe69843216c048923557d78a1cb8604d470a57a4980c97d87d3d7ecbbc935dda17fbfaf15589309cfeb9ebed33a64d0742bf2f0c4fd391475368a11936893 +00 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388 8e32325f3779360817e21985d18fd57eac762f634a122d69ce7b8d8a194c8d44e9c0dbdcdc890915c7adc0615859fef405908fce5ae741ac715e0d1e8db888f77d199c46cf7c30a74ebd197e33a415fbd49a8668f7b77e0cded4651e5b62766a +00 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499 b6bf1f2b2da06f4cb43846760e7c3a2c721f1d98edbff198fd020a6145f932c744737d216f23844f1c5b30d76b5a604211ce952e96550e2012a61127cb2ba35a69ade790f9a913d1db6cb6caedf1a8ad625784f1cbb97259531fc22c4556eb0d +00 f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6 8e71554e7d178d3f69df2a4d604e645073dd6dd963ef0db277f49f162baca1aca4a07ab48749eab6b7c9e7940adcca0813bf129a82d10f265566d1802a6e2b108191087927108a76b97a2787619c5b0b5d8faab6e466c3dee43c3cd85caf1718 +00 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead adf08c20d13751f1c6c0136f6ff9a7aa4a4c1119ea940a3785fb775f76d8e50edaa177db3657a24e125b707ef731b0e917da4041663f6f9cda84445b77a302be160443b8fc6a2c5838aac11c3fc268ca7d913298b38e5b8d9e172f2c7e56a75f +00 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd 81b1ed9d98dc0cbd4ec47fff5bddee4ce753613799bf063751a632c7ebfd0254ed53748a2fc2aa2c0abfbcc0683cba4219cb2810f568d1fc07a0224e6fe0cdf0df82e20cf4fa82895f84746152b13bce187a8a90069a68828b1425f23174afa7 +00 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117 874f698813ed1c5bfe2c54ac30dfe2987b7507ba9c663f3a07014b4b0a2a5936a555eb9920e79bfd99f017d19497552f1898f262987fdd945b7e1c6c4aa5fb03dd0c7dc45cb9846ec1fedc481ac8c80ccc9ac9b75536c506e394124828537bfc +00 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61 ab3145c18dfdaddd59c5597c17191eaa694756ef71f68c5f0934c0e06571b4301718f10699e870589d419bf2c3ef955a01243c26808b52d1567de2be6263557e54cd5e60f90262c75d0090698e63ef8c0f4ca6ebb99ffe9a3e4fb2c2293d2ccb +00 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2 95ce2313dea0a7ac6b0055b34c4403897e30c109b7b7ebf1da494ec44d5c1e54c8bf0f3272f981f4822de5cdcbc7dbba1297561972c9721424de1ddf4be4497470fdcdaed46ca58860bd7bc67515759e67ce511f15d7de3075241baedd90d322 +00 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7 80f6d319db932902a00a34179bc7d6411d98ab1248f47fd470f68fe037107b9f9436a250df6b10f5117cb8a985556a200df869abd09358f9d7a388b0eb506c6570180d671479c4e8a519ed1fd199fdcf7c1bd719fd0b6444545ab91311798d9a +00 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870 a0b94ab23c01891094a263cee80802006fa48452c4f9b1143ba90bee83b3f38e3ffc310b80dd83f4558a05e34198fd6a0ae355bfdcf4b1e2d49f107400c90404e6b042798d65a93b97ef88f6ced73c5177f70c648125760dc5277dfa94cf28de +00 e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf b36f630cfe03932f3032f17634e0d637f82276bc1b3e6871c3508008452c1ae9013003ebc26aa1f99944cb9a553c568d156111a8685c35b3d6a53be80b17258fa74ef383432f2758549421c5c46a56784f050ca5d0110fb2467a5a18e236cbcc +00 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c ae1deed75ae7be281ea60ea76b1620db1d1f6b0f805a0c1f392808847fd9e58cd34e7099ce45f276262050001c112ed904763924fe44ee75f47901b22e441356384268882378fc9f9dd6de87bb5dafd4bdd3020ca765dfe42e91a0169670eb17 +00 f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9 a5aab251bed6ddbed2aab6c5dfc5612daf73412b4523c2059a43875c71067a695052885041cbb6025efad4385396adbe1878cf968fcecf2d6671707b8dba4711614f54f0133d11f3755e15463b9d0ed79953633c936cdb46a91623c990040240 +00 f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5 99e823834e7dedd30dfa3e783ea0c1e9025ab499e20e11a3f834493a8ea26e71dbdded90272484f3515bf1e65342b7c80139c8f082a123aecde52c4268a87764fa6a1dec5d99382abbd97e618e91693b207379a6f0fe3a5c9ce65b20ffd34eac +00 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628 90934790b82cd937898df0d5bbcea6545c92750ea39ecd353cff5e5ea36759f14f04f1b4c82741ef7d9a736cfeafee6a117c16a700edfa2ca4cd5ca0b6da69cdec521f792f3327e88d4ec256f999683cc79d5530272234aa557e56ef32cad73a +00 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49 95093402ad99857acb52c85504a3263b4aae0992145f344e6b36715559803a91757ce414a9122b0b9181be036943a458065c31174fe232103d0a82976d610b369a18de7018e3abb6d2792d09c6485dc20eaace2e6f3e73743f1a7c49f13d379e diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P384 b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P384 new file mode 100644 index 000000000000..40a1773ff137 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P384 @@ -0,0 +1,60 @@ +00 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727 8391e425160edd7c8cf83ae407b33dd37f0a433960b4c68cf85eb9ca9a2feb5ff924d8a6bb44f73ed78e8bdb8f632bd20495c27e420be35d84199f25df04887eb0d49ce938be1828a44b4233c51a09ddd5742920603060a4f955d4b16160cc46 +00 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246 b67c8d9296708ec77dcd2e2d9445b01baaef6c185b0512a741803c96c4e07b1c0a1217083290f8b41d02bb236486f865098115ec1f6284408bafe22e48fcfaa3eee8f89419e83762b5943a2eee2eed214c00ce9236ea9d95fed9280c34efb8ae +00 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83 979f1bafdd72dc5cc75d43eb994a4e99d9320f572891d0ee0e28be8472377ec4fb8468c0ccef36d9e7edfe53f71800bd01fa2a61e4f3731e4121f1ab0a2d7cf9f450e66acc92ef1533681a8aff6b8fe0b29cefc78a92332f9df521b2521b980e +00 dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659 8ad763df9bb33b3bfb63470b840c72e984b6761c430a3d52ccafa30f7a8cea6d9d6f8ff20104f0eebc209111d933b8e4064826222d21807766b752a00e7ff6270c5f40bb07b527ad88976e9824e48116822e2df999015561f4faded2afbb1b0d +00 df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718 8dbac2360638775bc2bd81e90cb9b0626d31dcdc11f12eda4812451d1c97440d0569b3a89a900b97586edb02198900f70c7e83962344c6cb5fe1c69d211968c14dd76b2610343abfc51d9d94001c7f655845ee49f828265e77773ba0b06fe042 +00 ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f b8bb06fd8605cb86347231553dbaf407e2e58a9c2b0f2dfc16341943ae8836a421f0658c4dba1e88838b4e6dca0e7ca211205154218e18b1154e25324407da85e20517b995717ef7f93187cf11332b8f6432a283390372b8faac0b8b4f067461 +00 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829 8c7a5df7a210c90ec7cd0b4502494a367b8cb187319cac5f8c25dbbd9f2969c2af7a7b5d3d3984e3aad456d2711f2a7c03a9b323df23b09608b570ca05c8dbff1ecbe7e745f47db345a35237190c0cf79b94a1dbf10a97a2fd43ee59968a6783 +00 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1 8b43aa3d8886e324680c592e5d776b306efb5497698b592f77038692422855551dc1ca5f127a3b02f60839cbeaa9f4c00537dbe4138c24a959ea4775ccc24e53657321b0747c0d53c4609846f6fd2040aae242dc1c5adad83b3b67407c0336a3 +00 e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d 89bd15d4698293cb2564622f97196eb3fb8c3a1d19db3f2626762e200b27c16c062928d8616c9644be36561cf6235eba0c1acdfc41c1ace3b65232e328aeb6de5d5be8a7591ae185b7d51bb974385f5a542760cdf066994e6b50b8c2b91d57fe +00 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead a9640a0b0e0241bd4e1b6053a0247bf2219e1653a082d283f5823ae50cfb25fb3b39e5526f407b45eed0ec016ac10fcb0655b910fdd5f88850d134b3c82c918ef1d5e13b2c8dfbdca6dffa254e3e02a50f60bf52d0c7adbf937240aeb887c63f +00 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0 a7206094c1aba04d19f73e9293064e4161b25b4f6ebe345a72d619a3ce9b530c14865e5c8174b3f9b27a61cb8d165a9b0c4575f84992d2b0e42f83537899b6ed5bbf68fe98656f79251a0096a1d8474c5249672f6488202a4b87662aeb5ef7ea +00 f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1 b2bcc05299e49cbc7936a80865967723f65ded687e65ef93701243f2c3ef35ff58ae1883a7f89beece3ec9e8f35c08ba0191cbf0e2d3ca507f146ce85f38a6f2d86d64d2dab9849934b5fe22d092e96743bad90159e1a4a3339e64e5abb08d58 +00 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb 99e1e13f09abb6a0cf00e4ddc798e776008034777b122170f4b4eed5c39a8773d347caa54d2907c728eda04fe2a3956c0bdcb08e0a8ce39ecdd3a39b02166fd4e884c430e2edb5140e4d28546f327042fd2af8e5b1171ebf02ea79cdd9c03868 +00 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6 a40e5bde503ab95faab35c59ea035ef899549a056637e88ac522f1b45330ab6b2bf64d370597d316171c8c31d7cc767d0dde7cb2ec530b612e204f11aa676c676c766f7654d73f0421230c25e9f34620aeeb8d27c17987b6e3bab767e4c1fcbf +00 cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd 8b4822988690aed6455bbe16637b38998f1154382872fef51a1a1fdc3bfd351eb2ad140e0c42a815ae5c97cd53c6ab3110eb54848d074cdd02590bf543f4a815d56886226f0610347c34394f5b0de156b43637106a7d53dff6e9cbbdd66707ea +00 c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b 81a9d090ed1d228412a2be9ebe1322a3b54085026d8afa71fec00903a2b720ce139d1bae137d7f788e2b388348322e2a0df3c25d52fb42c95082616792cdfb0d3cfef09579c7bbeae0b0f6f4e4c405162583c138f2e4afe3f71722ec41786381 +00 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9 8a57226e4d3f3aeaf5b390710c74d4daddab811bd2b299483aba014a90d8e70fb2aa54ae9ce7b2aba87b448f7fb7d0640c597817ae9a7d618741d41b0c50a34f14ac1e9dc9c6bd77a50b7c2ff8cfb1b056b902c83a4012f34632cb23ba247625 +00 d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f b31098c23af5646de98f8b9025674f9b3f249ce5b83f165de56743a1fa6a8f53bb81632ed74bfbe9aa9c2f8e8630b8cc08335b89d641fbd5b3073551a6eff586ac610b8934b03b208f15ce3490840beb23fe179b85997a439252ee340a0ecff5 +00 d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3 a84467e2eb8bebe4ed0f502ffba3891b6f81c556424ee2597a56cd99a9a7d2503d80b688a20eedc0fef03475425b614d1382fb8984aae5fd9bc75cde7ad3878abbf52cb566b34ecbaef5d8e8b58a1b2f1421dfcfe10deb3c6a50b6d7a3d2d3bb +00 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93 891d91aff6d03a15650015dc15848e3a1e94f820507a5fd8b05c408a93584c9d67c4db14c7b7d7224a0b4ef508fde96a0113eead718904266f46091920487e0893a07e0d4588e6d3c59a0d0390b9c757368ed1dc4e64963456edc7cdd21d1f1b +00 e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1 99df1265226ddf06ab055a0de3160465f5589d41a68ba7b228a3a873092a9a3f3bd40076e3ba26b36cdd9e3d3cda311919cb41028bb714eb3f32aeacce9c57393a1f03830a43080dc7a0c40bdb959876ba5d6050bec92f6666336cd586af90a2 +00 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960 9713ac01ebfd24efa9211db65e54aa3347c968d267658beb03c22f091e196e9d8d82fce7b2d2c6426a843f46c9ecc5de1835de2174f7b7f23b2309f9348c405008f4ca765076ec3704f125322a9b09c42ce90ba7adc084ff9933226cd99c4491 +00 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57 a8704c782c90b301292d2b2c2b7354866693d0782101b6d1001a3b2dafcc4f7cb9436172e18f8f8933cdea28b01f890810c40637c79e39bf51c712c9f3292f3c9d4bc45f896b53a187a624765cc2364627f65fedfe1cac58566a5c5b3d380bd4 +00 a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1 b929babf8f4be86076b6196d27d3b0c27f6efeab2b29d3f5f910d95b7d7e9dd491cbdfc553a0acb1493d5505e46c518c1478843902bdeb78b11efcdb5fe2547c8339a0dfb99b9961e1c18d6eab2839b367ce86fe5ee49e80ae01517c94f9f5c9 +00 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3 b7d6136093ac487893e055f5db4240c63c0dbeb9174673a43b47e62595e7933c48a0787f99a66d4f9d1b7738483df19d08518131227d1a2e8a0d89651d16717777ad821dc5590376b0fe01ede0d1ed087db92fd626c6a476d0afd3a577c86cbe +00 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907 8b760cc0387913226a72c482d6fe8487c3a207d69c592d4af306164b287dcdd99ca351bceae1815ec3ba6e2ed64893661933972f4baabf5211b042094d82ca9b81533a8db83c05fc9ce922dda7ec5cdf9be2bf6876c90ec2804d20d4336b3e86 +00 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245 8ff705c69d4b7e2572242eb02afb6b975469c3baa4dbcfa3b750077fbc80ab488bacc270a1900b500c7c9470d7b55a41025c80ec241e67a1ab0f8411cc73ef7de16fff6f3b252c6b1b38112c74485188adef21309eb0a95db8d61316ae39a493 +00 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7 8279df6f564059ca36e0c8615502dfe8c3e781e195e50c6a05df1805a3d9c62798ebffa56bb2f912598c09ff7c48c001129f689311dd8b8b6326fcf2bb90a8b6dd16f5e2de68f6ca7de052149d3fef969ae3300c5779d75683723a3de7e53f02 +00 d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5 b8570e3efc8b4e369b8321d4b7b5431989d727b8e375179bdd73d499c5e5f4af55ccd568b501bb00d519d521672080350c8dcb9424e588b4dd28cf36c8df7cba5f8f3b0bfbff925b636ccc4a794f7e07685de18a75849b00460f4380fac6a181 +00 b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224 820687bf689c7d1c14888d067ca1b6e06242e0899ad0b6bb96b28daa89e4c813857491487423f0a87ad4b48b30b3e68f1232b49b8c9051e27b36179d79d2e5557c2d929e40cf530cda30230b781013828aa4878c41a03a94d3dd449564f3443f +00 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 a38d027fc701da9cdae51c563cd5df92c2cab536e404dc39cc063f7690251df8c928203b2b5939857385989a7ab01c9117ad54852987f3102c5136c97d97a50f4c6026610c675958a9bd78a97566fbbfa10719b18af795c24235f12431378ef6 +00 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 a56e48bb7aeeca7a993a98c7f59e4ca231020d67a10e32465aef9a0bf771a1e86325e4f8e6e43738dc66f788d3155e15140e26e53ec49f85fe7de748205b8275d74b150c6634d298e2ab7407c8a231d065f921c3c332a26bf0851fa41d85be1b +00 b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 87db8181050c469a9986cb974f9726c8f27c12a6266fd49fe3baa3d8091a042b4d0a65a655f47d25a4898aad4511142f09cbd955b93effa263a4d82c0eaac5c8b384e36fd7637b535a767706e5f23e0c89b265b743fd30b5519b2fe422ba646e +00 de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 922fe9dcc40cd8bfc1d325fa6271c080b5a6df548e486eb63ee25d3df14d22ee3af6edef264a9e65292801aaac9b20ac0d5e9b4487a6806ec456bdf0c44da519a9bcd9ab2e180582565eab1df3ad8f8c3f7d2f6ef210027eef5dbb93ba6649d7 +00 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc a7fca8c7f8b0371c2598cd1e31e52db4e156f349f457d67bb22c8173ed098d3394050dba969c53cd111d9bde48e2e118090c10c46aa26ac4c69a60cd6595bbd593e988f10021acfbb1dbdd57edab0b5a292f1ad78a601f21b1da0ef69abe25d9 +00 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 8803b6c3b6676ebd57e2d505a152b167fd0b786bd1a8556e7779fe4184c1a495632ec27d6a91d3032501c202dd3386f5185326d63498c25ab16a3378459b02b4142759f8c2a1e127be5186a2d4fba9b605b92e92b5f08536c4d75e983577e6ed +00 ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 825531f8ae6efd2ad5cb9758edf39c6650ad41ff0045acdeda7054c95b9b34103c35bc67cb9085d60ef4e87036b4705c05820690fc9e6f4a66d194e2dc064555f9aba17f549be68c9c248880dec0f2b194f338ac1bd820df2585748c2e635d28 +00 adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 88e87832b7b81f6af5090cb895dc96fb509b119687acd1d0e8e64f4b14b3a53ee5b400db8f064be290ebd91934a0eb680e1c7bc41fd33d37dca409ad7ead375408f3d2a6a1c41cba5a8737e5dde301d19c1c0acfdb730b55d9e723177fa7d02c +00 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d a8a9349f61c545e84002d9878f0482abe9a5000d3b3b3f1a90cb69f89ab47dca04a1d539f5b1c94c98817f526191f05512604fb5b8f353a45f6fec8954f1711ffe553bbd97e24dd0e9adba2384e8bd96c311a17eb9062fd8e964684bf3360cc1 +00 e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 a71c29e9af6860773cd2d61b803308731e5b6bea3f4992b6cdc73e02630ec04a330625db4adb7444d57c489b58eeec8300513985345e384b1a7b9aad96ef2a6f4dbfe7559976b8f2b1db1ca997f4ef0732b3e7f3d3dcb67aa6072433a087cdb0 +00 d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca a6f654c46011d3d8256c016bd85014ba53ea1e8384a27e21c24094297e581e79ddcf77f85de81282667c3addc2981674074bd94b9dcfcd01bd5770094a12f51a4cbf956158fc03d6a1c4976af2ac597cc02e211b65b9ee59049fac00b9872fa7 +00 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d 898fa375917e4cec32416b509f978abad0b5f4b80928b83c275634f9a8c2219348ab162da7832a98beb98bdbda20ecf10b97380cd9d40578592537e415744d1c4e4730fbc4d723437b0063320ea0a0320a2a77c497651333da7da8d0bf14d26a +00 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 b0e526a274293cde6971d54255882eacc86f1fa5b1e7646cf10df090d35540cf78aebf931db48494006c8848a33f74b70be233ff851a488d6f00c2d63e36953a9a5bac73ffc71b68e1473da393b51a3a2fbc8d0f821723a5aa7bce4c6f0a4e94 +00 ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 aed1f9f0ae3fe8f07d94e9ce3391d2fa3727038aa7afaec5cce4cd54dd99741de8b01051cd2d485f45e81e307e04a6790702d8bab062b4f041ed01fa3bb1294225413082d7b91d40769730053450475a741d315135e2993e228b6a2da06574ea +00 e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb a439d8bd1679dc4bf0dac1785612082d284adba899d4354815a5790ed6cde2b64afc17eb3299c293480309370c28603415de0c6b00cf22c90eca67e7bc79cc3105ed5ef03605c3d2b9b2b2baad7ff7ba363fb600c60795f6cd043746b89bc577 +00 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c b4c92a182a5d781f02851f58e7d03b8dc6dba530a22f1335370b2a4ef9f014b666a28e7af1b52ef87686263966a6ca0c09a20438ad908e980c8d462ad1985054ea9d930ee92456616d92503e66012aae93cc8356e203ff6a2779c2264f1745b1 +00 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f 8258ad6c68a37903c29b16028b921e8dc7f568d6cf6063173004e02271423149e2acc2b98e592ff4734b70e7e926db890855d9e5fa458384c20663ece64a760e054c6e1596a82ef146066d2de7c7a686a5ba19951fb39ab7df4963e71a5e9c1b +00 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7 ae0b52965f73c475bec94caf7f5602413132341c8186277e85948938baf8d6d935fb2953262919c0fd5b27f5127490d60e2267ccfb418f8f1185b1ec31c609cd9e982eef010a5dc481209335703a2217b21971e9a5bdbdd01dcdaa41c4483b7b +00 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf 85f5dc200b1e9ca76ce9e66b5e2aeafca242b263e7cbf0c99051bf557e04ab28c27dd87ce115fcac2713ed5c163147bd0fd3e6a30e7bffed61008eb54ee1b82a9d68a8025431b696df945ecb74fba4f9505935607526998160ae815641231b17 +00 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b a20a4c2b89809ff34b7fed8eddf1a41df8581e98688f0d5e468a7c9cf89c99916a2580b4a2a39d5196d94e87501448bf17fe0b9e1b1e6b121307f74ed8b9c0a2a4cedc77aa2b44e0468e8fd39e4ddb67e90acdf753c8461db4a6ab0707810d60 +00 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69 b86a33068945a1dc36560874d3ae3e345938e5d89af971d1855c70cb9fc0362da1956d912fffed1e92605ca057df55090fda5c04cd1de1eddbc14261ba9c14123328c1a4c62b05f2af5aa1604b7c1292e58782e906c15c5ce0117fe9847e1575 +00 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db a3224dde9455387ec35fcdea79cd573eef60baa3ad28c96c1fbcfb5c954eda9311273a35493d758577eed8eee5d3f88d07333035a7f0c1211f807b9f1f104b0521219fb276bda7792829e408cc05291bee4fde72e2e267dab8e42eb15afdaff8 +00 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d 8ea665b42d53b593dd35927a00c14c007d9a7a4375d97255b344965b0e90a207202d386c01698c9a3631de5dcaeab49e13d2b531a7f4cde42127f941b54081905b6ac3ae76a893cc54807d65fd93fe9e6d55f1a25dc545ac9d9d79a360673664 +00 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476 856b714cb9df32201f09898806500dc5b4e6a3852c15fbe59f0a13b8192ecb1b4d74e9bb91839d56d82f7b6e75d6a7db046f41e4c0c6d090e609aacdabe6f2a045075fcc7d6025e94dc87c07df770da58c1e1cba60fc01fbc15e1734bf1f44a9 +00 ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa 993ae005a749692da2ccb889b59d23226225dbce5920826e4e7bc45eee395e9f211610a672db07c98aed212976a7745807ed5be2fae16c351d5522541ecf542afd8253c614f61069346ddc9b6131c4dd2b16fbdef7c5a52680ddda9787c86387 +00 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f 86cf3e1a75a090b3afd396f420adf351465abc7fe14b1ea19ad1616c3e7bb28ad3adb7131faa23f74f9348e9769d9241161ead55ae11ddc30b579f0b65502afd51cd6114cf5d33a455bda5714b5064ea0b4645f45e3000c1aefbfca1fdbc7bbc +00 e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1 ac2d24324d5f4c7a6d6b013cc54ee8da2b437ddfad694ab8333dedc3c74508239b5ddf0ceadc23ffe9a6a67bf7b7b988088bd0f81a1ced85128cc45f697369938da1d711866e260ce64ac5e0517611c6438b3d73b1df09cd1029dc7e75df83ca +00 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c b9329ade1efa574f224a4c0770c942f55faa65d8206a365467b02caf01f538e5d04449a01a3aae206bb63ceb47b9c65617c6d521a13118184c6c0da4266a2ab89151e2461e0d6f8702c2dcfc05c0b5c37d030dd5950e18871ff1badb627750a2 +00 e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c 8f4ca73248f9d98dd79a44d18764a0f5aae0b2dadf6441a4ade85090d43a4f03cf9d28539885d22236586a7b15df6a7b0e09ce07d5c3e74f0cc0ae4d5b3e8c43ac0c621c58bbdc3946002de75412ef6a62dee7ce3543500efeb9517a11b7b59f +00 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855 963544bee4b4709c31a0d0bf69e6e42a90697587f4a54a39e13aea6592efef14d80fb37c568a44fbea9f69def0eb058515d2bb71ab99c379d5225f35dd3119af9f699512d093d81d686a33f436fb1b7e20b2ba8a86996e439291e5039c489eb4 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P384_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P384_blst new file mode 100644 index 000000000000..2986f4090fbd --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P384_blst @@ -0,0 +1,60 @@ +00 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727 aedcc21aee3d24413e3eff0a6e9b9d07b73ac6723538e57f8f9ba389fe571a7a0b1a92b4d721de46d0535697fa512e7f0465409c584e5ce23ca4571f451ac71ab665786a71c7edb037054277a632dbe035dbab239ba0973ab67f3b1d21ebd06a +00 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246 b101410f7223a7e180567311a9375e312e32b56ef1e3058e93533fa1032823d7eb94544481082f0353832b28d48a44910e48c2967b91685d96e2118df187123d9b12d8f0ff7ce003ef204f1f0233ccc19a2c44db3b9b7e3ecbc3cfc74110143c +00 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83 ae6810e3c93bb077680c1db601bcd346c98eb03f0ff55a908197274a7a921beb6950721827288d8c49edeaf564a1ad5300357138ee396f3222fc61eb11a4e47fe68eab8c37904adf4a576fec461f17f69247be0ca75826bc33998265f3319842 +00 dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659 8bf5d9b589b79256ceb3b0cca06cc9e399a8ce631b0612425e97e8ddda3b8c3d2227b8491980b17fe311ee6400c2476d1657a4bda78f1c728bacb1b26cf263a278d4ea1e0fb8229d72a3a15634a067dc13ebfa24205a46de9ffbc60e1a49509f +00 df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718 aa52fa1572072ddcb3b463f6730a6ceaf8dd48cf39e14b04c4cd8024eccc2c489d52b588be039630108d8c517f4773010bc3b3f98a60a8944a44abe2681c882b0aa9d245c5e1c9f0b9e12a1640d1224138f0fa34de3b70cb436d221cdd6d3161 +00 ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f a00b2ba707180b9ccff8071f586b31c8bc171eedeaa0716c51d1dcd0486f324c2babaffd22130e1698b1f305350ec8e21300863a2ecf3d2ac2b3d4d3b354c8d016f30deb0229cec18581f9789b244ec34f0b15b4685477d046c9effb48456406 +00 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829 a05d33f55a74e8e781e51d71a42bc1b48fcb25b49b165fca6d4d25a0542053a60efa01b404ec9f4412ef045a2afd170611394e271f2419589a90f05a695e8f57f7439135f3093495bfd94429d2e63d0e9bd824a10f8b3567dc6a7a68c6de376c +00 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1 947159cd886b2a7c536cbd4a6f302f4a4c3591be8fa4cc43a4a99f27e887db53e73bc7e4449c6e0076e9a072208bc8db05542c81a9d18bb4c5e5e685d2c6c586bec1cdf762f4235d05ee22aebaa8643ae662a5c5adf55dcd834b805a5e24bcab +00 e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d b07f4f99559086b936fafad2f9105d79a7cd32ae5244330254c66ff6e8d82cbc756aa95c4cc6efb6e093fa62da97290a19bb5a4e14e8d531fd36e1dda63773186b32ee4a4efb76f7c2b53e3aad1d665a2c780e9837d80ea757626bc13c0cf69d +00 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead 8db4f58fccbc2b5639e5a2de4d52e6d97b54713f2abf745b8fcbc251cd1cf28912c48f9dab83387e485f8d354fdf6b09014b68ec4885f09d786ca576ae2c7cb7c510c0893c2c078fef036d7a3939707ccc7d61e333dc30144e190d3ceeba6c7a +00 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0 a29803aada2ecdc33aad03ba940ac6fa9327752fd725ee4a4b7ae86d1ca0ee1ee6ba3b1a1a3164fb5afd450cc171abfc0f40eb07619d4201531a4bcb187c383d10bb3e7707f9f033f9e91249fdfa4a17f0c54a97c15be404d639db3491668414 +00 f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1 896f2b35d3716a567bacdbb6809d6c9ef386193d48a45da10b0cbb699b9ac4da9b72b9d3ab147f375e67f09cf7c9465901ebd55ebad37b2b1a65cf84acb6d7847df38b8d0b9c755e9e3249d753e99576f64779afa399210fdfc10fd1bf5556c8 +00 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb a5c0cc8d7ac548a60e4c9ca5111d7132b3b55fea34bbb80ba5d70ce503c1c4956e9b24223e7572d8f360eb79ffe90b3d1034f9373f11033a29d94b6fe5e92ed9583a84f44a1cfa2bb1eed1a015ab175a1678528f0487303d0071a0eec37b0e5a +00 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6 8e3ef5971ab705017876d4d66a8ee448724fa85df2fd49c73c9e095645312737e12b631e1a7300e400a85b75ba45fb480207b51a6da579027fbfd7268b47b8ce9b16f16ae62ca677284a2b9e55d7d9e118513070a7d2c3d3c77630c6fac33f14 +00 cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd 92901c4fb3199594c0186631b8ea6925e154efdd391e7c109046f3897803d81f9c02c25ce848ae2a851dd1d9c74dd960014d5c20cdcf1aafd8a061f8fcddc1e4a67258990f8aa55f1db9b56f6ee7d8c4ab9431612a608ce14b1bbeda18bf5e48 +00 c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b 89085e8980bb49c1cf485cb7b2ff4c9897f78dff7172fe397168b78fce67ec25cc80ef683498d637fcbcd94d9adbcc0b19c285e0f2e1b0ab6d3f5adf1f7dfdaf6a83ee468cd5493c89db66dd10bc467191ee12e8207a655e4fb8768f4f381019 +00 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9 b1f13016d6222c364f10f43d8d46ee98bc75adaba82624a1d9c0d329fb95dc29d990041705ca1298b76064caa1ed5a500ba86f3a9aaa7e64cdf73939c3b35a445c3c6184e89ae7d4c71c25b4759528092d135f6e9e27bb8ebf2f486c4103f3e8 +00 d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f b31e67ba2fa27f2f576e97dc03e9d7add544cae5ab4e3c13136d9fee1ba7f777f190efb0401604f3090ee7da095774590a1d2ba4869fafa07f18c137c8cea120e475f4e661320d142c7773e1703f97c64df5427bff61839935eac00ab6f403f8 +00 d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3 b594875ef3bc79519dd4293e8e997050365351290cd7e02d451d39cf5620b1c1d288fba709fb410b2d03356da6d3d8d405812a79d0cb1faad5837c9dec07526a3824e29a014076df0a73a549c2734f65219bf00e6922c6225e142775c76023b4 +00 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93 85578926e02467c89cb4f1c199de023b3705b919829a84f61014c9b9be76aa4f0c28e490bb6e165b778e926fb0c9e03314b8d0fdbe5b63798e5b69cbf139a32c65930ce045d84f9ef6df7d2e1ad00135542ca44c1670099102c22d58a19ca27d +00 e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1 9645d4a86f217044f2afc498d597802312a7359b8e292041c259122d6b3c66f67e66b006578a21607d579923579f870b007cf5deeaba2c022a09b5c57516a8b4951d75ae6f7cf1acb6934e3045d8773d73deed91b5cb1a1d03acca246460cf71 +00 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960 ae2e520621b9a0d4a6c22ec6ddbbe301dae0a074849edeaf0d0ba97439130cd0cfd0de220867aa5d6983315e6e2ad40404d260182e704cabce3aae3a19084ad02b78dc8bd499e7e3977e0989c6ad0b75b7271ad1638658f1ebd0ff0a189e02c2 +00 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57 972e7cea3c5b74b2333fca5699f3a5704e2f92b585bfc2c8d1fa134bb7a4c5d77a6e00b18f906ac42bffe2d2b49cc5cb1723335f72077aa45a60a025a38a43579fd429effc3055081a51a604f76c93efd1a885c191fc305f6fe1038791746a34 +00 a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1 b183310c7756cac1ad86a78cdf5abfa80cf4c506f376f61d936521b42eb407e713ddf9c794b9f379aee46519930cd7a10edcec7486a5aacb485698c2aa9c04df1cec5d04af6589446d301d9c07f9ffc61e30020ce3d5e3a0982a1def2bdd2765 +00 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3 8d5be49cf3356ae7ff805458bc12935a48d64e53a078abfe9b1cf40e4ad34ba3fd90625b4a8dc239280898334bfccd4f0a116c64ca4f26e43c4583dc4e676c1aa8ba2ffde4bb03694515cd475f8f253ff0726830ef4224c840099f3d9f38bd13 +00 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907 b4c82d2a0f4a54fac1df622f583a14225f936c060dac72aa60530e8d466f74d2ac4f138f4ad0b20ee4054d8c8acacd360c91e305c2e9fcbf62325e8f02e8eaedf7a3565c2b614f31c156ae7994857a35642a8ed431df1334800d80cd75e9ac1f +00 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245 8883a5ea73855c3ac2632368291c4971d56e1fdf1329f1b6d0e2ed5d2149af7904e0edbddabf5cad2bb4324fe7f831e1083230fcf714cab76e433a2574d72bb46914ec7f1cc130bbce42819733ce67f6705718df1970fe3cec079e0de392b821 +00 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7 adad367e09017155a321283a79d4e8f3cc389513ae00fc8ed94997f94c51bf6c8a512ef488f286134a03fdda48f264d60701900f1283c009c91ba4dfe9f8d72be676586a93befb42b5ad6b0d8f621a0beac218b096c0ac1553551610900b7c99 +00 d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5 92846e2b1253086645fabb7c17e96036ffd2222e006653ac082c7b6fb80a2f2f8ce4cad308ed74e06e3b19cd4bb4dd4b07a6143424b2d8b951e3a6cb1c0f1941ae39711a11adf8272f0f584e168b706bc1dd94e3272dfe9b8a7b6e90c1fca299 +00 b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224 a2f2a57e72d9be5f7ae106f8dba7f6b0171f37f6a953bca81aa0737b5c50f9624069d4cbfc335ca01b17277138e88ccc018a6feb8854aeb7e0dee810b0b7be02f3c9a7f57b398e59edc02d78aee4f02c605f801873f350858f60246a545c2930 +00 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 a08417aec33610094a3e268683d0fb834d117b3c3a324f5b0e53be0cd48cb8ea5a18ae95d637d988acaa3a0642dedb5e1154b8b72d7d7b01c8fc28d96a0da624a82da846ef726c0182eb507145712fbeecea7583f44b820a13a770dade8eadc1 +00 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 ae7727733a9fd73d4a3f7badfface82aaf5535a51776b7103693fb5730458c6c1a86ff1f25bed5fd7ada5f337818d74308f108e948b21f53f90f1acb453f93ec14bd0e15c5937bfd2489dca020567b875c9b931dc455bf3776fcfa69d9a4797a +00 b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 a1d5b5ac044f6319194488122b1fd4055434ecfe68fe1f10d9e05913dc86674e3b46be9940ab5122fe205f7c45012f480d7d41720f7737be69acb310bb31a5b7d844a8191902786a31e2255ac01a7250d1a32405ac658141aaed4e2468f39bc8 +00 de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 ab2b4d4a1aeccc468a751972119a6ab3a40c57c25378d5a98a6509ae2a90ed988b54aa6abfe0a9aafd4c2bcdd81a752c0cb4ebee99006853526bb13596af922cc6e4fe7c98a164b673e26916c1cd0a09e07b5754e37e03c6074a8fcd06863636 +00 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc 95f333dfec2843de54d73a3fcdf54713a488979d6bba27a5b02d3e381307db3174b9cc72f757f23dd99cd545e572806304551fd74b2d97668967caae563b8e86bb730a2d1db5ca5e059647802b3a322c7c6672ad4b62f3f08848940b1abcd4c5 +00 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 854efedd6b9e6f9dea1486a82239b8c8c635d81a6857d3846179ae207d9358138138f2ce57f3fe53ce89e4a28a9ca4120aee51448e0b4bc81b6bc8c26a349a619b67992b4772a8d0066ea664dd00103d94c399a12a007f33678c9a5736018099 +00 ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 9917acbf545449a9da992e419dad585b2a2a5e8cf54cf309b58a742aaba82dd0c5294a9b2200fda82655e6dfcc83a269136c219be856b309a975413f625faa90b4620597a4b2552a7fb895a8c48438fdd1cdd894a11fe97ba73f880649fa27ed +00 adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 822d9335edba1dfef5f79c12ef749f19f848cc607e3b0a37e068db3d52c6451b32f9e99793a874741c40c67692bb2e110c6acd6b77a2b56feb1e0f2dbf89c795c925909f2183518638fe36e2941a76fdbf4b5b77f1ea843f1e573437db00f27d +00 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d 815b979c60e0899ec4ef9044c64923788fd71ab2b9fc0a8c24495f894877b260b2a5c451301cf439035ae0d3729b52330f30a0d3f74c997e59c79c1f94045ca2cbd4722d5262771c08af82c53f7444131fa3b6d6fd32719cad0586cc6a327bfc +00 e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 b4d303b9cc08390bb846ed099660413f41cf16e8158adf3d6f7b6294b14f14a304adedd438fb77689d6789f702ba7a450459ff58f0022d3170c4eb6bd7f88ea402a95668e475ffbbdc6c6b341fde034b19d3b32cb31d1cfd27b84d139a21c2c2 +00 d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca aae9c54595bc68965cc767a918dffd80d86605cb6b038a08c3690a95ebd95aebf2f0b9b7ef536fcfcdaf85392c6df5920a9c47f92878506694f6341932f48a26e87e8b90a41047e341ec8206772b44312ff0db817ac3b6fecba5a601882a6949 +00 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d ac18300c88310c6c1ab675dbfb98b4f86fdc5d13410f0a963056dc044b1bbf155b1de8049367f6f063b9a42a745e8c4c12bfb4a440129168ad42e591ffeb808f84c471bb04c975b30a3367faad30507205c8481282ee5df439472cd0944da9d4 +00 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 8372c2a03697bc00636be774d0f1ee99283e6fdf77b44b6d439db69bf1a2afa682826a917187461e6eee56b23333e3dd094322e7208f79ff7baf34f490754b6bd4942061a964238480e48383d5c082cb839d739e6e7fb8763fcd78291f55e163 +00 ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 90591b0c6d234f3f476638fd99d6ff1943ba8ddd6cd51e813b8500f8280e6d55fd86c4a5729021bb5f7e930022099bbd091ee4368393586b60b2e1117801356e36fbbe1c8bf4dbc9e8c1897eed19ebdf3ff923e2da2fbe09cc3d05bf513a4c02 +00 e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb b86f5744e7ae4e992b74f37d8b270646b67f992e10667620b2bca546843c6c88591bc42dc288af069690e6c98d5470d8193369f518461a4b4e81606e67684372856d44dfce58bd23543e3acf844689a9864bb21c1c97ddeae204fb609193f85b +00 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c b5bf60d110451d71013ca5ff7a71b55d01eb9d2b820fb745a76b2366b8851e84610f91b0f92c1202d6cd39c7e81550f91677ffc113a4d0daaf8f9967e01b37c33c0ba29d131d3146f01556364dd12d688cbcc4f22cefde6bd1c183b2f1fbe066 +00 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f b499a5511a0a44999fae701ea9ddd7cf1aadd300c9af3aee84133a7fe7abe33b68257c338b4f3490d540e2fc983f221a0b7426ff3eab206757599442550e6fc1f090744894b9ec341c75b0aa6f70dff14f51817260beb788c75c81c8d550a413 +00 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7 98e9902947931bceb53ff88ccf3f7b14ac1e6cc9de4471d5312d9545c09a583236d1c495a5831f97c25a2df9d5690b650fea79ac4731796c76f7dd07b8504d023920748597e38ae5417f9512fb98ebb7609c83ddf69ae72e68c3dcc1761bbfcd +00 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf b48657d716b9fa8431f40e201e425ef855222bb0f8b90ed387ee9a95f931ecc7c66be4b63624c2ef2fdd3c1cc8f9c41d0edd1edc40fabb506994bb6c2f1da637cf9073fa9947b67f4a4af855dc52d85e4f0817a1d818b773af654adcef3d0f18 +00 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b 81fcf18c1a548bbd67d7383d3b66d63e99eb07a522660aaff271c4fd4cdd5e567d7355698bcec40307a35c4e534d7ae519967a2551ebdcfef18d48c1948d0b3a03f410be6dd82a2870546da62f522ace232627c46327a3e2dd7c7402f06cc9f2 +00 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69 8861f51121635a1b59424cdb9057959cb640436be5a92732c12363b72a53e560328491fd46fc2c7bfd8c5cf47eca94731023a0b33110d656cee5d13ac979813f1d591ab0f911c4727c84cfc044eef5ac4da52490ff894d3a0db77ab1a1b3c38d +00 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db 843ff3b7e89e304982bbf5d7bb19bd833528ac69fb91cdd8cea504cce85a1c6dcd10a2334ea646735136d6ec843478410fc674cc30bd87c642a30909d0bc10657969d7c1f5ad566d2e2bbd8004ccd85abf11ed0d94361c85bb8027938308880b +00 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d 890775c235ecf2d0a2f386a39897bd447f8816605f49ec4bc3a1ec4bd251ae3d457c2b7a7906fe4a150642c0c3f96211056abde8bc20286669c65980b025529ac28eb1f16c164d17ee10b01f0872a18f9b9677c99c0b7e2cc78a7e2eb40dd1a5 +00 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476 ad52fbe4ae219d51af012fa5bd42ab2881e1a37dd42023b35c860ef9fea01dc3086148c00aeac6475090c2ca382487a319ae988201a02ecc9d911c630d790979b2bef306498a09aba42877ae8178c71a1c904bf74eda06f8e4f5990b481fc835 +00 ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa a300cd4cb277b1875d93b38170f057eca017d111f5c351577a3039797c9d3b23651598600ae295605d23d37db2bc5ba70f61598e8de3a1fc3f3c02314dcc49641930a24d85831ee77eb5c2c248176f05b2cd1ed46f1ac1e105b0bafdebe1cc25 +00 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f 853798ac1d8097f6da19b9444254a16b91719b82247102d0078a5d9efb00259912d4784417333ee6287dd78cbbe4186e1589bb8a4fd7b19da7c200b34a6fe769fc2c0e6f14d3f9fd08dd2c67ff588f8878e58d4b1c8f4a966a731fd740927239 +00 e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1 88a957ac6dbeb46741af42bf833c7a9a4a13d069ec4f4b15fc8168334deb6c36795b6c404705f85449220c4d0ea83ba40c5fb43b76517cf88d9cf6a5ccad7613aab2667d7e92631c684df27a9f29d50c3c6a468188295ebeb5e4fce1597c85f2 +00 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c 83b6c3cedd9f8d939abc2e7219c9ed0822b1d0ad07ddf7d84eacfd146cc8d9759b85f8afc73ec41d1f2d35b248df44e005e4a72a8dd9e3a92bb1abaae349d93e0d79d7fe1ccea65e5fa5b899adf602b3b34f6c81dd53fde429285e92db2e1a52 +00 e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c 98df6963b9549c8f431aae65a59cef3c1b2f4d2feffbd361c627f872609914d492ced5c04a7b58623af1d9e3bab2090506ca541f1babc14c26ed6f2fb1af78a46af601c01ce50441997f10d64c1f95ed68ed03911db0d27e0101a4fdce5fbc13 +00 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855 b68363b1797e03f1b482531f87e689c6043dd75a299af4b4cd0b1953078fd2c808accb08753ad92fde381bac64198c340633b693f8bd448fc8ff7307e5be3e33256367fcb4859af7f7e4e97235334442e857a7ad6852987c3ca479a55bc7837d diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P521 b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P521 new file mode 100644 index 000000000000..45b697200008 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P521 @@ -0,0 +1,60 @@ +00 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46 90aab24807e8e8b035311edef391144b71f6fe0a60e203f27bbf13613414788755417702da8feb01c9c4941bc24a02021783a96ffafaaf93f544610d37deeb2c4eda825783f121cc39b959e8862cf90685d618f2d0f18f05674d09536993a9e8 +00 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73 b8b8ee05315b8bd6d7d5bc7e02574fecef8d03d87a37e62d60d3395ad7dd0a0bf777042c01c38f89d1adafe533aef0e0025ec9dba597474a537a226af785978f65115853328e04517760d2dfb19db0493e70a8047ccb43be10f4db4995bf84b4 +00 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace 99f55646b332356cc25377f3af61f994f0a49030a0e294ecb8fe8823a26d19d364e176015579ea1c88e8085ed1c683d611b102b7089fe9d25fa5cd0a7f91a8d46ff76a467ae1f25727779339aee9b78b9ceabee007307dda05e6e3fc841ad8b8 +00 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc 916ee47c4555330121423027235129a56ba8ed4519bfbab351d454d5803d4a1ae26d74f488237ae841eb134ecaa3eb390b3b7c93faecd9a923e5ff771683558db5d0be82e6a476c38fdba08a1c76eb06f71beb3d4adcfeaced64799b77c16560 +00 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549 a774841bef4ea019a380b08c5d22ca5274ddb1f31a345dba1370ec5e36a5a46d471a0a91382cec513fdce0e345152370032ada0462effa6489dd54be506759a00f58a87c56e7000998a40757ede9bcc8340a1971fb44f24d5f1639106fcf8f64 +00 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4 954fb54aeafc23eabccb5c1e8625a01c0989178a4beab6b84a286996951923c4017599bb2518b4a53fa6cbb5bb1b36a3058ddb0ba8eb81ea7654d5c9edb7bbf3cc62ea7607b8cabeaedc50ffdb69ffdeae3b380ae0f7a00a44b1c749e97cdfe5 +00 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16 a6f06f1e0a9a87d1f23a870fff8b7e6888c87a41b83916e17d38893cdc52ad4e04f75c66dbf32f366866178873f2fa7f07c65e78d64f355ec4450119a2e7736b4d17b69cce6d70444d0c6bb204f5d067c4d48e8ed020b2405b9c6d89d20612de +00 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37 b54e7195db03c3f2b9fba4ee6e7930906f9207fe96aceb2357d27a360b0294e592f7a3544f2e885695c66591d32bb64a0d02dfd13e977b8e69479fc62331e756c5f312bcbab90f2a29574d653079373c795a6c03d0d0778c42c2bbca2c73c104 +00 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256 829ede508f332627fe5f642a890ac9ee137545cc213a9b63c2ce1002b06a6e036b0e833d03d38c39abdfdd3bc922c66d17cced84a6cda02031ab3185bb39d0b7d6aad1858b5d55dc4672e7f6964bac2148cac6fbce9ea88ed9b199b6e31372a9 +00 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7 989f65b78f233c1c7fb6d9603d1a0b7dde6b7cccd948524855d6fb6e860441f73976a854e50c6360736bbd3d2f3300a90366b6fe33a40321c64e98bd0a14075fffd15ab301909362091d769a34bba3af20f1ce72c6f43a681747680b95d2ed7b +00 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73 b2b0b1b4561cef5aa300b7eaeab55b78c2ecac7123ce91302363074c184f7e376aecfcdf61c6b8bd0c0480c6965efe7a132117d26db475a9f74548c595b2acad790240a47c7cdf63319eeac5f3364676d08978407037265459bf838a12077e8d +00 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c a5898c08aead19bffb902409d69153dad7b16e9cf63a57ac28c03cb8e67e160bf0562e23a8ad0891c5524e79d1a0de580a92a5f6011f807cb7cbe5054a911596c9875040cc572bac7dbe243622f2e633680f3725ada8107edbd173a52624f6ea +00 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace 803663ba7a41133262c0ef90bc8f648c64ea49e66a35835badcd41305e7c02938e77934bb2580040220539b3a05d1a500ba501ceac9040fc27edb41c1a103f1eaa104af1bae874a4355c81b898504d36e849e3e5ec1efeb4ee8b9f614d689269 +00 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8 a4ca71a2df3bdb6340f0968d541d81c6e86e1065ebf99a6c7ea883540857be53636cfb7166d2638b248804bf9527c2990937a59eb5eac19da6e7430370a6a7542107f1b90bbed7773aa5736e876c8d5b20f0ac1ab4a4d316952695964f273967 +00 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad a8812f9aed5ab6903cdaaac0fdc3afc94538190349508dbb861066edc33ffa4da5c337c202083c2dbcfff7a5264ddbbf0a29937188378e49ba81a3529bf4c2b944fc77507eb54ea2d5d66ceb9e771175008374b4aefa9215c7125a01f51094a1 +00 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a 8597fb1385d86c856f648dc0ed54f442cc08bc49804f994342f9db6eba8330af9002491351647315a9b87301368f1867183339b47142f55f8d5da80bcb7687dc6b4f30ead5d3b0cb688ad6128b227a1741b0662b33657b28b2a0a61628ef4353 +00 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c 85d0642fe15fd6afaa48843c914c011086a0bc747c68276be792af0009b9ee7c0c5a45b6ab70b520bb4888f3b4a64af511ead0fbda3deac2a63d86ecfcd9ac6c98d18ecdeb1c47fa897a943a5b3363a8051ab77a806397c596840c3f22c0b792 +00 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d 8b5cbf2d19f4927b9556405cbf97865c30295df7523187b3b4b10be39c522133082b0bb640dc1e0c4d5382b306fcaac805317490693a8f17480ba2405e09eb8b2ff263b53c25d899591427daaa608905dbdeef754bf997e1e7d6705faaa5cfc5 +00 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c a927c44a3da0abe689d4ed1bce8adbdc7274c2ae1c2bd131a9d5162c2dd48fa4dce70b0ccc78115f1326c1888f0f4441094921cafb5e6e2dd5912da3cfeb73d8e1fbcfaa871a54658b717df55543f24144c4e294652c556d5ed9fbf3ae6be374 +00 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25 a8e334b1d3e80dff69ac453801e7ef0176fc2783cde889a54a496fe52ac6fa2941b3de2b1b77311fce646759f55b2f3c13e7096b792696e53383cc0398fb02c8d67c4caec4b503d52872e0477832641e7c20e21ac934517a980a5f73d6f7037d +00 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf 89eb3a91f288dd2235df61d6a3964d6fc4caf201231db7e967ebe2e61c346698c079be5df80cd7c426bfe370724a277f0374f471fb54be1476e74b5ee57b81955f98ce65c800463c1dfad346bdbbed4ebcf6ae0b7935c6d4c59c0584e3248367 +00 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570 941c3acd5e5a9097de2642636f676a704fcf001d1fdf3af0129c7e44dcf5a5ce0b6379fcf7cf161f68473a212493fdcf1231040646d2f18e9aebe8acef62c2ab01e646ec11f3da91f02ca755e4411050576a57d4a302ddfd7fbf1bd94a670e5f +00 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6 908c8b001080c411755e63693c393995c14e0da6c0d26586b71cdd45e4be031329055a1da89ae3a0def38639593994b10c0b4ee1251b822eff8e43de2aac94cbf95f472e51ed0a274a7feb10bf838597df8df7c4105d34be54c39e8086674490 +00 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7 aad2e4546486f401d06085a9945ce25698b5892ee8d82bc95eeec3ee65e37895a20aa55acbdb2e9c77296b6a1373698110ab27c258a17a68087be995ce74ed9d4529dfc6ff0798ab9305f4ee793581dd70e7a52e99c53bee9d352264238f3163 +00 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e 8fcdfdccc6cc45f005d26a71c7a7cb48f302d65668faf2a3cba7e9770cb318651ebb1a779dd76cebbc3c133236c48d0411ab7d4d3d5b98ccef840a38bec510fc5500264a1b9a2c103a81ac150436396faf81d32a742f68744b66b5983763a820 +00 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938 94c6e7b9e637b6db0e8e777c08e3c086740ceb54886db20c6faa1c8c859e61ebaf9c1a5a960b529d6e98591f73862c81000982a18875375e937a46183f149c6defb166e6a65fbcbf72373f57370546193f02ec3b75dc83d283e7193d6e11faa6 +00 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662 98372d840fb89f358dd759995eb2a44b954d5a2662762a93283ad8a7de45d9ade49af8dc3fd5101b4bf4a81ef7e89297173d24107c7492c1c38de12c41c4dcf68a59b181efd6854eb95d391c52bdd9f86b611a12e021f7d53be5d4f96adc77c9 +00 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721 a2296185786a870c63021eac6735d552785a9ad87cb73bd3e76c464bcbcf4cb8065d85eb8da1716cc75df4b310c6cb130521328f2e4ce1fbea3cd71171b2cb5b411e1942c77c213585dc853d21e0f3e3d4c6db2ebefb608453c5c8b23dc54be5 +00 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e a8360d1ec86249353ce7c772ef9ebd7647eae1c3bad8d5bcc755cfc68f5cfe3b2cd203bac699f2800316dea92ae075fb15dc5423e07180ee7ea2ef1a6a29a3143080b93cceedf42241786796365bb35ae2a5f269e858f0ca3aed008c30cce520 +00 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418 a44d7459e305b61642fe845c791462f69b93e17d096c338b80a990c57bc70f7ed84c7d1e28fc98764c26a8082f39189a01659c3a96708468f1c23276a83f6a0c690ca3122e9341dc8916e6c7e8d64eac364ac28af7e2ac559f351115abcf5917 +00 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950 b20ab3b7edbbb6032dc48c7121407c7439e37f6d1a48f859aa93d7f25c633f0530cce010ac00c7f614859050e7cc2c400e3f499483d1d352fceeafe74b785d9c05334703e669b6fd416757acb86a88ac64b086b64ea4cc159e15a685f1758c1d +00 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b 97d5c6f8fd9738a3ead9e8dd205bc9b52e225acb7b28ecda8fb85ab17a31f7551fa2ff0d9864dc78a87b351d0d72f548102b07387fc5a9a9e81c799afad8b80f43b57ee6a4630c669383a84515647a56114f104f93252611840bcdfb33d1520e +00 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f 83e0cf48c5def37cc1d59ceb3450ace460803f171b0a034257268c59818febfca6f9331fabdeb90e906bde6c9d80c26e0c604796d36bd5faeb3e5dbd03850a72aef5ad735d2a3ea0a759dfd718b556923def2dd1290c4b3af5e83e21f7bf3760 +00 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66 ac4b43252b7fa45d8d50b1f30267d3099143e4d03e2019cc7b8a5ae3ad60e6b1bd20eedbd4ab669bf2f066b6bfe3420810fdcc52b0bd89f47ec727902a551e845d03e1dc01f31cf11a646a7cc69cf24b2d9e829178b63c5a2c491a287e3bdcc6 +00 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c 81367d680cfb6fc3856c32edaef725e363389494e435fdb9d57bbcd8b154e0764d5b2456290a4c2a0c23ec218047f5ad055ea8d431fa3d1ff938ae84d2c79e7bb416c43edf96d9fa54de32948f5b03d922c4b3de198908576b69cf888761e5f0 +00 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0 99b4413e02738ad6c7ee82aa7487d628e07ec556b087b530e5425b7d7fee8779ae1684a16510034ed31c755a4cdab06802fa6ada4553fc28549ef6211b2aee25ad2d4fd864f10e8b293bc043ef0007697c18c57e6ccd7279ab32dd302bac9df4 +00 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9 8437185c267e603e12029c7177c55ca5c5849bf7aa88ddda704dea86401fba9ac3b077eeb483643da05beb66643487510d6e038fdbe2d95afbc12370f155dc01d75a6c356076c1ef3f3c6c5ddc0a06bc937583cfa4a8287df5f20a45f3a95530 +00 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d b67d25b193e10dba4ee8f1679de940434986664324767cd58dc265ce2930c81d7da3639f77bd4509b79d12059b3d7260122f3cb5ed4eb319f7c2b3125c757846547e4be488e86b79f55db7ed64cd793609715cf460344059e1d5b114f66593ab +00 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490 9752e6e98ea9f8ce5afc38c9fada08ffd6baf417dc93407cbb5f69dca390a03711e0d8b4d9bac8116e26b62e7070026312f7a375d66116ee9227de611218f06a4d18edd007ceca333704f2b3e7a59e66a06e38dc93b258cbf93233c7c0a2dffb +00 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1 8f20b848322612bcfcb299cf66e4f421f80e2fb9a8196cd995df0b1f23075febcbe05eb5368065bb616dc5bb1efb87f012a8924a71c193dc5ed7ab069381e55f62cd325c6ba90cbb4d9db58681396c79c2b2f4a56fe6fef55880bcdd40287d9a +00 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745 99b899281632b11c3499245967bad8397ceb3844d968a26845f93f8cfa27f940a0d3637016113ccfc0c1851a702b05f804f15ca80d994609c3804f620d339e403a8153a71bae2bc7f6696306c553f1a479d9efab0c4e11783653a5dd661004f6 +00 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f ad680b2ff1a2b5a0b64026707ad318ac7d9d7f3b971adcc83e365a4c6c147dac6b3b399da4e1391e766fc1e9e4c02c13094ed7be357f5a2058bcb1c0b2c47caba74f7d68e0736f790811534026b84456821175e8cd2cc970d3ebc209909a4d01 +00 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e aa37245d1d72f3281321de2d54ce02dbefe3b0afc51ee48b406fc4afcf95d30b2bdfcde5352dcd86ed883321f99335f9143ca5a4f0677602617978e69ce8bb48bd2b321a612ef4a691f6fa4caac9cdbe2e3c3bfc563778dd9f4c4ce5a1d52b04 +00 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89 80dd1532a2b61fdc07a28bc5d0978660b5f1ea5673d255f89e83e4a7b17233cf39f6a7ef5df4c0e9e5cb812e2e618d4407d45e52c1ebdd72cbbf487c1436cbd4a58049f4e055af29680026d23b52b7425a21c54f8a1bc7213b764d4e630beab7 +00 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a 87a03b6147202b8e83c1236d10c04f8e287d758cf761e4e7d48934066ac648e4b1ce98f0377969ed751c0fcfa3f3b7bb0d3e9c2cff0507a45ebadfacf82f399590748c26ee300da2afbe181ec3206e94a299ccb38225a56dab6d6f53e08d26fd +00 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926 94e1fbd05fccad3e0ae4fe6d66f138471f9e370e02cfc321555876fc39e7c60b5f6d597008557e5ece3776a0fcb0ee920b5c1b0667368521be2312e200331ab0cf29098d6085aa52c737f696d06979e50d2eda2780f66b279f8ab81ea299e78a +00 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6 a90da96f3b6cb1147cc83fa95a201ee4c73564298acb3766dbe1d2d4902ab64ff5812504d079937bcd469e65954295ee08790a78967e9b6d636f10c490704f932b42a3e18408c7c55860b6ba4de26191b07ae60a6caf69b4b3bb47ddb29cfbd3 +00 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f b9ff53a84c60579b2a3a08bafb80613f2e9bf344a385a9658f013208ee0ff60a9e9dae18bde1fa89cd1caf402b3ff6cf0027dec81c5e1d20de72aacc1da09d415577d975d4ebc4aaa3cc3a6bba2e54565cd45c6930b8b279a4cc807912ffba17 +00 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742 8f96dc4008d0b488c28291a8b289abc3d10b7f0853a321d4e22dfa30a2ba91d5326dee55d09f7a266287199c9840b12812413b381fa0bd5e5bc7fcf88670b6095a36facd58ae6d9a4fe37180215b7610bd0fff5d44ab1b2fc75808641d93d5e7 +00 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697 b3d26615808967ead0e9419ce4930968f4b8a7085dc39e3f95892c7cc8a5b58a9a9747243416ea81d99449818c04821a08bde4022918a91cd39ee64c8667841a2bca07a0bbd6261c0e2a12fb3bf1411817223e361e7253b37cc815baecaa2dbe +00 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04 83c0bc541a473681f24f60874ef6b3c93e44343653365f65ae25ff1ac040ea82e71aa7030b914d14ebeb017fc5702a0612102d569a484907e46ba55ac5163cd0a33974c029aeb88812d1b74332f1a514b6d89a7aa2f5ee821723e809e6fcaf6f +00 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6 92b7cecad4a104f43ab6315123e0c748ec2738bba0e25ee50126c9000a4c1cb4f7f5b983510b2ab33734b0d8c31691180e08f6d3d8dcb746e5c6094c830d3d21321e6fed1f019450eda9691ab811dd3b606c9f66ca52e5a0bab776c3a5f63885 +00 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e adedb8abea52010b2c529bd78df559139aec110e08d8340502e2eb576e2bd0ac4bffc7910c012634f051dca3e4af0b1111e57af58beacfb8e5de88f5b949d99635478dbeb3596d975cc6c701ba8e6b6ee46531a405f83d728f211bcd0b92c50a +00 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5 ac8220f8c1933667b5c43e10e1272555763fb9c43f95d52ebb25a48678dd96287a39a2cb295421a41e488b029929654b13a6452ebad1bfd47104b381defc2b6613bbac214a6fb10d10e5060cfd249f839121d645211579fd92fdef82a013373c +00 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a 860691ed848f3393628e5b3ea846d9b27f9dbe035378e51ad7a7c642a9e0bc3085cf830c5309bb0646394b1523120d100df4899df1edddcd8c1bbadf3764a9d74681b84f6b296ebfb10f858b3f4e2338b766897364aa6ac7ba45267b4ac1a7ac +00 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb b39cb85fec5f55f03c9896a976f92502fcb4be84d7edce38d5abe7d46c18a4c9dc74e2bf95fdaa800319604dbfd3a2de1186db518f69ba276cdc36fd21bcf9bb1c957b36a60332b123ead869e27ea127e80a9f00c676c70de4278c0fe1bc5933 +00 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77 afae7a6df422216d650af013a95a42e1fdf68a7b7de6ccdfb03a9af00d2270e1c4ceb583ebfac5d2f9121b4b454eb8520335d442f22c5f945b643f08512177ccb6d8247a5b441aa6d54f5024f3b6481526f7a712374a89fc4583106bc29255c6 +00 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c b49ee3e22aafe9a53626e9a68f8bc3797196dd609d5860cde3ebedecb5c39663a5122b4f6388a445896cfab370e3311c0b450bd83cc867f1cd95afc677a00b87154e737e8acccfddeed7fc74e36c3c847cc40293336c0d9f27b7ebfb0e4176df +00 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63 93b0e51407871b3c0d4938d4ff9842047b211646a2cf7f23ade1639883a6327b188289153646cea04d3fd93f3205e92d0626c61b0bc6a30dc98377459e6abfc426a16b5002bb97694ab38b08b9c62d4b3afc693af3222a1d8a71da25fd75ec30 +00 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da 8f624031efd3a8fac6562b6bb6a7a69ded48392ccc7eedf14e5266e711fede94216be5458839a93be6bde4aad43ad82d1326cfe2f2afd93d7ca786b3c5ea5afe16f9295c3274aa0753907fe367e7d8c2716dd2aa5ed48eb82ca511da936ecc9d diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P521_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P521_blst new file mode 100644 index 000000000000..9f965d51ea9c --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_fips_186_3_P521_blst @@ -0,0 +1,60 @@ +00 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46 adde751830ad5ca41f2b7d251af2365305e2654c97fc69bac087d7b6fc1c651b18972aa313f8e39c6c2185e7926651f4130b709b7104cd633fc65f5f7bfdcbf667be154a72ccc1463a5fc697e17a4f589b46f695189763a3fc81349ea9ff3a77 +00 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73 81d95139101e96d9119c1b421efb94c959445fd600563058ad8387302bd8983895c5988dc08c4191b7ac4f0dbba2ff6b0f0aef1306d98a2018df79920e6869c9b7f4496bc86769d0f9337a6fcdd3c3175b7eaaa46219a1f611d1da24338c0d11 +00 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace a7400e91fa7f33ff64543b581a77921cc3f9adb0b5faa59f1dde22bd593a6c86705ce9357cb44f6f78f3b053f7726f15118ffc09de2ad45fea701670614bd7a90f2f7609c4d0e41959f90aae63a6162d76253349a8c225be12921ffa54c7daf6 +00 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc b6f28fb2d0b9b48594b00f09618b77345f7edb60910a9e4711dc99c930cb268608c3e762387eef3a3ed3062d5f00616f12fe224d9ebcbe406a63042ff34fff05ad24bf76068816042489d25b11f75bfb2163b1718cef1a16e95f02ad6d8612fa +00 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549 a616c764c01a4ae97e26fc98bdc46bdd5e39a033630616a536b06058352dd69a54902df3d79b6da869d3c1b1fca4fad608d7609fe67b5fdc829d261a1fbb3be743ac7bb988352c06f56eced1b3ae70a7c8b802e073bda2a8a5c82ba08e4d810d +00 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4 b811cb6eef98c97b9baf4612644fb3fbd2dbcbb16d45415812e5fdba509ad2fd17dc5b4dc5a3a531c585e8a6b2ffd6ea1091e9247284952f2e4249ac4fe489e1f7110d7ef660c4f0689c920799bc4fa74320e209ef7e582cefee6f2388dbe179 +00 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16 910c09ab7a6587b4b391de6622efaab49f64ea8c3040786efcb9ab98807ba26d29ee2a036f9dd3b5ba8ef5f3494e461e18fc82948c61858abcacda1f7b06aa6a31c4722e152b56f43f1613166afc520f1d0347ee38f2b16be3234815c1e59095 +00 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37 8be9e8fbc105101c1ad6e495ba23b1bb3e72caa5a7821722d2a8da0f03a0e174b2aa58f9a9361ed17f5a3fb40662c1520fc22dda669c29fffcff0b8514af638200d0ebc6503e7b897d2319f20b9846a90145603238ea98eaf1bea589f3d8bd16 +00 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256 a8bdd2f3e18fdeba0f12d9ba7f484685a0aa3512d7b6d83324c4444ad8d10da03b60a67125d72c3ea7cdbe9bc35f513604bf8b45a5cb95913c123818a9857322740ce87cd269317af609ee01702f770ffbd869e7e32259b6c0ca8c3238938733 +00 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7 96804c02dd5c5a287c875994aff5c227f9be5f5373a170ceb829df269a65e98b0666ff6d5c88396ab03202090ebbce2e02a2569e424a0f97ba022522e61d502b97da9d9b4af74d537c84f25f5f93544760182f851343206339bac9c9a9507850 +00 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73 af74b6791554c2e8a6b4292b6142cd45228d6962d4f777e3b678cb7ee0a88d1465d9b9d813b4df53dfe33586e3e2aded09109dd40cad4a1f8af29ba03d682d11b74d9b8c159929a085b3e71319cb7a8688213f4e6d3ee0013efd2ac6f1329d24 +00 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c 8f0bd75d483a72f721dc868de7a6a935d766e282d50b240077c93bb61f327dfd746bbc5b091f94392c7f8a3238bd94521070106e1accf1b10fa2e437126de3b33226e25af2ab8988b8e7f92c34931c71f7d1e3a087330e5abce95557f64ceb77 +00 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace 91cc1453b26fabca4943b2467c5c4ec32917f30a05a944bc8cb103814f3a6023dfb0d23ae71a3f8cc8f607f689c56da102dbbec90ca1ad22ed8b42b77d047fbec8e653c2c90a823ee0ac4b88b01233ce6691d4891fffada434e42a60182a3ad1 +00 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8 a9ec592d44e0b56c1725dd50f2dc1e4d3baee2260cdaf3fd759a395985d792adc70f779c42ef16ced856506b56f824001605777b562c358af97b36e03634704f64ed45f011935cb10f0b4fb918980122679c8a0ae92250f5c95858362c3711eb +00 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad 96abcc87771ec5c0e2d4f129e84b0d934e4882dbdf593d129e8c99488fc0fa38c95644e014a1d472b03dda1936fa5de8045e24b27999bb0c3cd0834ccf41aa425035f3f9a1b0b31b33e318a53dc7e7e134c2c55d28be2ff774294a1e1f5f8fbe +00 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a a8ba92c136aa9afd08b915f47e148d5d70cba5a1ea17b6cffedb3b3f1d3c85db3fac094c116ed2e992587400b993346901f27fc449332c808c54447adfab2162ee7df6d3316d185c2906181d1b5fe29500eaf601236ff9c5ec6264963edc6e82 +00 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c a0d8521a1f7b5984ed8ae166370c3ff03532474996ff91ca321dd087455cfc57f8ab5eb7c1d718ee1d0514ae01fc83410bb4a957ac74f809c66454e9bd056e15b4ddc4a2cee2b664d7701a4b974e02210d0f24232a99751e5d62d037a5c74e27 +00 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d abe3eebb2c27a4f6d3befb1612e92f06e6715050bc935dc45d18ca8ece1a2adc6e2d339ce595201268606eb9695f0f470eb8d33a0427258779e28eda02125922e5dac9a7fe0e29e3e570a982f90c1095762c8403a4be36d6086deb8777881fae +00 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c 95f5075138d2e178516e95b8d05b62fbc0394d1657eb0351ca7bc70d3892c499d9df6d45d391d66c31ccb35421a4b3140de958789ed7df6b2e2f89023a13d691b27a4a309dd7a2117d1532c2d0a645e5c295101a8e55ac293353be5c7a0d6030 +00 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25 b2c098aa13dcaf88c9eec68fcf7cdcec36fabc1e9f545835668206726f84f20032491a9cd173df5f8816cde0a1cd99640396205b1474334142926db3888f727bd5192b6cd711456fad2321b0538dd5772399a1bf06470059a3a3940548d01080 +00 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf 91ddedf84c3c78f705ba928370adc616ddd5abe720581911e048fbbbae6f2968822dea10efd6b7429dcc30f3d403da0900cb6a1dc2bc501203a026e6b937da1b7933c0455ef7df3ebabc32ce9c833905a5a66e542768eeea64d9558172ae1431 +00 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570 a17c5f3e579d3d8992e4ffbebe49bd1e483cffa20b6bb35280c8da2f41699ab6eca727318a943a8fbf5fb0ffde26a4a40d78052ea3249286461d48ce966b6c1723e88ab5050ba9a562b9652edd95a977679341e7a793ae805a9cb39963bb2603 +00 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6 8fe5bc2fe911ab5d5046117684fed38da7e52ffedba49a791a7733e0f6227cb0a0fbfd656c0cf0569c050a7105ea972601a18c8adac91803825f3f1028cc3cfabea7a03a15c63f6780c8d1bcab1d544e453585c6b0fd486d86a9627440af7663 +00 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7 abb010ab53a3b4cae268a120324cc1c947b8530825944f55381454b912db5991d1250b2f6fc5d6edfa0a4dfe355a8dcd187d125ea3e96b708e53d73b55582d4362907ceac2be4f5e49ad8e36174af87035f62967c36e035ca0e8767111d56e57 +00 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e ac6eb5a0cbcfaed8618255f8e21b463b2cadb6972684a843c5bf193a4741629c08b7ed5beaca737470d19864f7cb5f5e194b3f2ad6971a84e6b84f62d2843a68790f7d8b30fc56a14c87791f464e387c3952576dc95a83745eede6b6615cb424 +00 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938 b36e55547a0281645b101a71a320409349194c0b0cfde0e487b52108d99323890910e1706282913be70217f53b054b4f19b85086c659b49963e95eebcef6631f209a3f9efc1afaa3c1bb5085786db06e257263bb57b2086f810369b4b98096e5 +00 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662 b3a60d9af1a9d7173df122c7892225a5670980ac837a917b0d5135543e1b95e12d337cd3a9d2cdb2854650f92e8140850c5d02c579a7ec1f7627e970913dc1cd8911c0ca0ae335af0992dee764647867574122f41ee1ccc489924724c7ec088c +00 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721 8530c6fb578909d7eba18a64624266f849a71580f4e1e5131274e7d7363df10e4effc2e4b7f12fe40feec37867775a721210f327f8659fca675f4ae144ac5c9290c7e3fc98230b8fb0b02c2d109a8e41e453ebe73a2ab34e68bba76cc165261e +00 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e ae23ca0cb67a028c8e110e814d8ab00ed817c17a6ec62dfcda8450b91cfad00b0ffb1597b338917d596e8560b6ea593f074d467e5899026bb19fbc5ec9cfe736d8fbba80faa537c032736dd267f060bf6916cd3e6a4a69cec0d3844b70c995f5 +00 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418 849babdaa89f8e013473d36f3123a8b8861b27a8ef45a8fbaceee586940c31ee199f13204564a4b0a1164bf79266b20012880840ca3829878b8a1a817d3fd5ebd4a871d977f34fd61221878cd4d3b89556ab727926da4756492b0396713989a6 +00 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950 8e753191ba32c4332ada4267441dff2913206bbf72c12137e8da5489ae5b9c3b58c5955fb68909dabbc5458128192dcd18a99b04185c7488e9a6658128db4bc27bfec72f3eaa1f1aa1c8c469a1e3b9215f7a38c3814df8f1227777a6fc4f9041 +00 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b afc3d782b80349c5c80c52b3c69bf717633e7659229ca0a65223e37f307ec02cf78b56c4c22940c6291bf3a80087765302229a87e1330610fb7c98642fd14dd62a4def8b5723bb01164d51905c1509376c6868769b875c5f937aeca84ebfb0c9 +00 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f aeddcc5f0daba68707770ae50c5fb7cc7cac3e3673aacd0c841b6a208abfbd3ee38cd7d96e43f311f612ee1f9ecbb778097a81f348afa17e85014bc2f9959241193c39ce2a52d07ebe541dde2b3f6ea29f63ce7aac8e674c35c42053812be210 +00 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66 a4b2cb2bfd2ea593067854457a9df40720924a1eb8feb81e1188e31e5ed2f77ad50ba5c07b4cad37f5719e5dcfbc26690dca46057522ec45546c17f5af3abf64a99b4c90e47aa9d180dd50ada66e39169c9ac68d83511a1edb6afc82cfa25c08 +00 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c 8a3a1998f82dcfe0cd8c10011d1d0842ff400f987b26b954a80620d1452a68b68a0dcf08948e932d495d0f4697e6b6720cc2bbe683c5a01877d78602abb90dee34c313aae9402ac641f65e1b701f224c13fe6daeea771775f9263694f61e97bb +00 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0 9393a4773db6030926b57a98c8ac7884f6b8f601476dc6d66e1b0f84640df372b9d21f67abb131241bf5493b20293d93038dfc16ddab88ae6c93924ec19e457a7fb9267c4bdacc65740dea0fff274bfbc1631e639819f4a570f946ae88965a50 +00 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9 906af57fd387b00c5ccf1fca312191ff847b98a47ea54e637d3ed060aa428acb8f18361c4a16c96c5b841a08e82e24d208e95924f9ce4c7a71c793cc9c8ffb4a7ab811510b442401b76813969d57f24f84f3421bba8285f430eca46478a5fd6b +00 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d b24638482aa4da56ca8ea26b6dd630fd0a558f9b2a025afd814315fa265e07e1a6062f1addd83075b2adde11ebe5c629168f5a9e72091366d3e4b1ef3748e819a756a4a196bbed2c0d6ec8f1ab7187c29d55309791feffd0d5613cfba7e3a9f5 +00 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490 a672f090e91533f8ef936f41e2bb953752f6f6fa5c4ad9f755685d571fdac09afcd43df637a061e54de833af4b14532807ee27b2313f8d0dba4f978d12761e1f629f95dee5d0d77ed4b7c6dd471ca11ebf8549185c61d3a67505944d83086979 +00 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1 afa2fc028a10f9d075cae2f790dc25509a36557c1afb4c821a8a144b1af3bba2d250673f06e2b7648396ca9bb7e681cf027855120cacf60f0dbafd2f10303b1862abce6e6b5e91b98d55e40464b0e1e6d20d57612223c224ae71250873fd9306 +00 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745 a06b88e31a062efc8b4e846373403acaa4ffd48a9fa70cdb74f1f8c62ba836b84dc9e91f1b0fb0e0165050dc59c82001177d7adb648c179fbcbbe38f645c89a0df8d4ba2d37824b580c2f7428621885ede30cc182f4af1af16b5d6cd53584156 +00 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f b735b97aba8579a356bc5342de455d445ad1bc4ae2bed50c18bd641ac0dccafcb2f2786161163a212602856e6505fd29172d63865a42df5d06ca784ed3482cbb85f1eec9eefb1f7db007bd454582148329d359a50c28b25c162e6a6bf3cf3938 +00 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e aba3a8c36834fbbb107bbf5dcb708d5b46134880bc38e1978bffc8d05fe717b4381fec1892095144e952f0cc5e3a5f300231ba4697241264611a79f8482c8f4706e6dc10be5f217da81156e4fea6c9df3b3edac7f3d6d0915b8748f889dbbda1 +00 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89 8bff177eba3117188df4bd02ac247aad291768bc155abc7f8370de20b6a22a3570b8a43a8dffc185f07a464e42c6c6c816727443a3a50ac6a687de514f8fd17f33d53db458cea72709c9cb525bf78f4b26ec000eb88a4489b799b29ad0f9bc78 +00 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a 85456110fb289fd49d73ed2782129628eaf585e3cb182ef73d41fd9c340d009756b9b1c485375487603d95ac53d13a4813272cbcfe2c983c04b3d1ca36828d83c3c49617517e336b5d634df8ba2774f5dc6b3027577f8abf449bcd97be37d90c +00 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926 b253d6b29d9f13d12c0d47c19745b06ec6c23b3841970b57ecd21b30ad29f4af1596766cd612b35f0423bd433eb101a00393a308da66e6bef1c72343d0dd3ec9b3751fe0f5d198d1c84b4adc375fc8fdd20ec9ae55687e53b972cca92ff3e707 +00 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6 a166e7590a8461b28689281cd50cb05b4777aa88c910c1b1c5b093371481f7ffd95cb511b523c0be91422f5843edbe9b0b3d626f303f269ab7ce0f5bc47bc7a3ad54ffc2e33ceb3541d7729822ef025ad5046e858612e9d82e8d4f4e08af5c18 +00 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f 8fbd4e42733015097eaffc90c5123676d953b0860c027cc93c90e6b18a612bc4a6bdbd7faf044f582889a17e1439a3c50a8970069daea13a096c7b606df21e370b7332c34da75667a1063e81d9a703f45a23f0061e7928c0f69f472835c5c81c +00 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742 8dbecdd38f6c29a8142c5c769fe8e038ac430053370dc587e73727acc523544b56669473fc9461c8eceeb9c1be0f02bb01d6a28bb70bc7c7c4555b0a6fd47435f9cd3d28d873597c7fce7f80108e563e1965e142c06d27b1f0835895492fea1d +00 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697 b0f1333aa68a2a1ea92b837a9f19dcd49b0086e5c8e2cc4cd46008296f84ac07723f78d45494c6ced7a5c5b594275f6f1910829b3ff4fce37579fc69354a513b9ae6743df41564b08b690ea714f25ff42f56d4337ee7d37a069109e1dc5f3214 +00 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04 b39b72b688e5fb99b9914a39e0aa1897eae80999eb642732d2deec8a7fe20114c1085cd906fc7cecdf44d86792e8e677056d487c9216908de3eb8f1457ebce1c5e60913223911e6580a6dac3e8348b1adbc06fcd159cfb47272c19f72d1407c2 +00 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6 92ab7edb2b9b4fd294ff1f43949ae38b33e2da3a206bc44e7ac767473e58b93634d84e398ac3fc6b0eaf149f4744a8c110edd225c47d61781d64e0ebe4aac87e03bef73e71c4c4f11ce408f03542cd57bb85cf9d2b5761baa8a4c839835cc937 +00 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e a89c7d5181e804a520e3e58fe2126c2a0a75b0f2ff63492a6968f8189ee2cfd2c12c93cb670ce6be3ef5934fb8ddbb4212f3e53dc8f94aeea1e65be965ed021e0a0da8a20822b1c60cf9b804255f47fc51062d087fc40781322115e72c97eedd +00 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5 ace7daf7067f364b66984de0cd9a22744a9b9642c00d835dcecf8d82e8d8ef1937a254e15ca05d692db7ee3d37a06c4405b6fbbf8766620b1e26d8c0163d1c061918d202eb140b734b0652f1244f7c369248878a195ac0a9c74aff5e5d1afb67 +00 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a a03fbb2aa3ba1ef0402be208f7dc1188725ff84a5573e993a56dbd1e7bada74f0c1da9c262361a5de3f4a22663ac2d250c9d71b2f43450017739e1edc9784b5cdfd614cf3c1d7222ea2a72ee04168f1db2df8d6b87302e7baed2a6ddc1a37b18 +00 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb a0ec0db42c1c2d083dc89aec253463e0c76fa1289a1bcfbb8c4d1aaa117cd9425ea7fbf7aba9c4484223880654120f0209f5a05b7fc59aa4b4a30f4da3f6a090824336340425b67063d4f5d82e8b6806e8c9d431f6ab65830a46a994641cbee2 +00 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77 80af3589a882dcd9986ca4758449a9048f408c4028c2f797e1942f3e8ed1b5054548bedb07e34b96f651a1ac7cf55b2d0134425e6432006b7e1086e50512bbe6e8604984b24eb5abd56bb2674a2b7c93bdaf7745bf5bf498917f1be141392900 +00 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c 80ecb0f10b8b41e49ba7c17fb401dcbedf6eebd2bc02824fad3f5afe26d39d966d88b351f3caaa75d4c8d7388fc5c1691962214e3de7fc963bfd5a76498f7e655262bff18a431f14c6728d5f1583f5038ba359e66fb951e20a0b6fce6b402003 +00 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63 ad9b2e03c895ed7704a4599f9824485a1aa3e1efd84a5701c36218e5bac665277aec943664536396fd5edeba1fc3ea40178ec0cd8f9a072e658c086a390084854da3b9886938d5a2b565f77808648553fb710e7a2880a3aa824b45c925193437 +00 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da 84eb4bd382ce64dc4c81bfb9703739dfd92be669353e10f695a86461cf0496214fe16ccc5eb94dd1e12898bc8ef781840666eb2ec082c9e4b0e16bd48eb147c0643172270748faa44f1e51cb516660dfef0d7e7da6ecaa9c15661abda0d37bce diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_rfc6979 b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_rfc6979 new file mode 100644 index 000000000000..906e08abf390 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_rfc6979 @@ -0,0 +1,34 @@ +00 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 8cede1108493f166f9fe40c29e0343a4ca4b3fb0b3da03bc243c4fe93b5c8928f0c7e40e547dc458546514446cb7b41911623bc0b2243bd5bbda2afded6e5993eb93875b7e27274c63202717f08ed8a69796cc96e8e28fdf240d084aaae3250a +00 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 8cede1108493f166f9fe40c29e0343a4ca4b3fb0b3da03bc243c4fe93b5c8928f0c7e40e547dc458546514446cb7b41911623bc0b2243bd5bbda2afded6e5993eb93875b7e27274c63202717f08ed8a69796cc96e8e28fdf240d084aaae3250a +00 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc a22d31fd50c460fc25f5e47f3c78d453733039ba57ccf88f82be99e0263a664bd3d9cb49513cf947ad78dcc1ebba1ccd087716a93f56774309d4cae8bb1476cf0973ee276c4d60e4408d59aa78f73bb2a72ef3e4d4a8f085aea70bdc8e680133 +00 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc a22d31fd50c460fc25f5e47f3c78d453733039ba57ccf88f82be99e0263a664bd3d9cb49513cf947ad78dcc1ebba1ccd087716a93f56774309d4cae8bb1476cf0973ee276c4d60e4408d59aa78f73bb2a72ef3e4d4a8f085aea70bdc8e680133 +00 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 8f47f970c5aa7aec857bc8dfce24662f187bf53a484948b19879fe7a0cdecf692e55857db252da4914231b93f8a622c209fc25996206be8aaa76ec366c1a92bb4be1e484a5c4d4cf7af9cdab9ca38720db4058120854d3d5dba0c61cce633b33 +00 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 8f47f970c5aa7aec857bc8dfce24662f187bf53a484948b19879fe7a0cdecf692e55857db252da4914231b93f8a622c209fc25996206be8aaa76ec366c1a92bb4be1e484a5c4d4cf7af9cdab9ca38720db4058120854d3d5dba0c61cce633b33 +00 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 b8f19d12353fa40b9ca48d2c03857614751ea91b4ff9bc166cd2ca961a8262f21faf9ceed506faae54555918104b60e201037fd577eeb491b7b94ee549d47481adff7652580bc94c464a469e0f87db81caad3f19f014b1191f0f6d1cdae13d5a +00 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 b8f19d12353fa40b9ca48d2c03857614751ea91b4ff9bc166cd2ca961a8262f21faf9ceed506faae54555918104b60e201037fd577eeb491b7b94ee549d47481adff7652580bc94c464a469e0f87db81caad3f19f014b1191f0f6d1cdae13d5a +00 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 a83af176eef7ef185611cffc05e52f37fb276860fc4becc262d1f61bbd3ed0bf5d4d533d4b1fb2fe5270009632a82c1f0134a6654cf171351099fc67ff86ff530d9f663a15384a1861765baa7b61cddcff883e74eba140732303a5f5f0708061 +00 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 a83af176eef7ef185611cffc05e52f37fb276860fc4becc262d1f61bbd3ed0bf5d4d533d4b1fb2fe5270009632a82c1f0134a6654cf171351099fc67ff86ff530d9f663a15384a1861765baa7b61cddcff883e74eba140732303a5f5f0708061 +00 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 8911b0e7d572a8da24e6ab714100bfc2f58876572c64a6edcaf9ea1556cad5ff56375ebefdee458fa01d88ac433e7a9a013191c9eab7329590f2b4465e4e3d1cb28c45858f3829b5bcd34d8ec5cc53651e0267314ef0a7c71257e20ebe4b8115 +00 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 8911b0e7d572a8da24e6ab714100bfc2f58876572c64a6edcaf9ea1556cad5ff56375ebefdee458fa01d88ac433e7a9a013191c9eab7329590f2b4465e4e3d1cb28c45858f3829b5bcd34d8ec5cc53651e0267314ef0a7c71257e20ebe4b8115 +00 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c b8f9343f424e0619af111ef81ca638b9f3049d159f8d1118e1ffb8d17b9f446e61731eec49c22e7582f0b16a64465cc70b3fe33ec76851e345638ed7ad1416c8ba86fd91f5ed8558b9f16def06d42f7951e0144e3b338bebb28adcc5f19797e3 +00 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c b8f9343f424e0619af111ef81ca638b9f3049d159f8d1118e1ffb8d17b9f446e61731eec49c22e7582f0b16a64465cc70b3fe33ec76851e345638ed7ad1416c8ba86fd91f5ed8558b9f16def06d42f7951e0144e3b338bebb28adcc5f19797e3 +00 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 864f82a57661816925173bdfe4d04b0e290bb5f468bbc7d2753dd64d6a4e5fa6a3111081ddc420ba0066beaa57fc137c18eaa46b38e4dd93cfcc444b49c011694ebbbf02e2af55a0aed4fb1f060f5b25802388ec7d28772b7c576658abd3c3b8 +00 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 864f82a57661816925173bdfe4d04b0e290bb5f468bbc7d2753dd64d6a4e5fa6a3111081ddc420ba0066beaa57fc137c18eaa46b38e4dd93cfcc444b49c011694ebbbf02e2af55a0aed4fb1f060f5b25802388ec7d28772b7c576658abd3c3b8 +00 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 a5de334f3eea90d08b4f5e93218fbf9f016a9f6310b91ee7879e70e2d5a7550ebd8459ee3d07d0cc37a7bf290566db7d03ef748aa0267cb528312b078c7a54ba1d922ea0a5679fb09f849a83ea9e40df72836d4ae65c227ea399d4ef178139d1 +00 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 a5de334f3eea90d08b4f5e93218fbf9f016a9f6310b91ee7879e70e2d5a7550ebd8459ee3d07d0cc37a7bf290566db7d03ef748aa0267cb528312b078c7a54ba1d922ea0a5679fb09f849a83ea9e40df72836d4ae65c227ea399d4ef178139d1 +00 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 8fc789ef224cbdf82e9b82a74f1cef05298365a2548a8aac56d2f937f9c44cba8f4ad64699e5198dd0ec0f0354e4e56618a55226c69512399c4716c3895f060b4f8c4c43795d81ec36e2dd377234bf911c0171b2e8e3a510e03cb71eda5a09ff +00 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 8fc789ef224cbdf82e9b82a74f1cef05298365a2548a8aac56d2f937f9c44cba8f4ad64699e5198dd0ec0f0354e4e56618a55226c69512399c4716c3895f060b4f8c4c43795d81ec36e2dd377234bf911c0171b2e8e3a510e03cb71eda5a09ff +00 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 b7ca9076439a49b2cb53374f3a969ceabade7b7e26d2300573f0d0e3a1765076122d3a1889b2f812a7b514408eed17330e757c421fca565761e1bc483aeb1fa14d1fbab9d45ed45e57eaca20724136f22000b00852cce98448beb253fc3b806d +00 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 b7ca9076439a49b2cb53374f3a969ceabade7b7e26d2300573f0d0e3a1765076122d3a1889b2f812a7b514408eed17330e757c421fca565761e1bc483aeb1fa14d1fbab9d45ed45e57eaca20724136f22000b00852cce98448beb253fc3b806d +00 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 8b25f0627250af805a25ffd0d2b26227f90bf771f6c63fd229e95cdf4ed2f011aaf2fde68c783262d53f6073daa51bb70a8f8f5f2582d800a8ee8af3ded315e95f6c480f0276941c5c672b76f343c6b72e79e9e40061dc55117810660dbd93d0 +00 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 8b25f0627250af805a25ffd0d2b26227f90bf771f6c63fd229e95cdf4ed2f011aaf2fde68c783262d53f6073daa51bb70a8f8f5f2582d800a8ee8af3ded315e95f6c480f0276941c5c672b76f343c6b72e79e9e40061dc55117810660dbd93d0 +00 035318fc447d48d7e6bc93b48617dddedf26aa658f a6ca8ea7c1093d9f35cff7921dd46a1757d209b6a98e74b815e99fd2813d63b322df752d6f14093fa7074b46a87f390b163bb4328eb0b1990cd136f3e7769813e621e37d00f0283b36cc35feebcfa7962809db73db6d217123fb70630918c45b +00 035318fc447d48d7e6bc93b48617dddedf26aa658f a6ca8ea7c1093d9f35cff7921dd46a1757d209b6a98e74b815e99fd2813d63b322df752d6f14093fa7074b46a87f390b163bb4328eb0b1990cd136f3e7769813e621e37d00f0283b36cc35feebcfa7962809db73db6d217123fb70630918c45b +00 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 ae15737faefad6b367a9bd32ffef20186011364075c6b21f0e2ba870c53b015177c98511e405d1f888a3b287582c2a95060494b0f058d166c250cd1930d147634b6236ddf525a2d6e9931c335b2c300425c163e1303777d7f4ec555b052b678d +00 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 ae15737faefad6b367a9bd32ffef20186011364075c6b21f0e2ba870c53b015177c98511e405d1f888a3b287582c2a95060494b0f058d166c250cd1930d147634b6236ddf525a2d6e9931c335b2c300425c163e1303777d7f4ec555b052b678d +00 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e ade3bb32bd975176df9e18debd8ee047a1484a34bac9437d446f9f53daa9927b1d95b6cd432252b8ec17928d054472100f48de371bb1af3b53fe12f89095c7d1dc148797b47afffd9f37ab232b41de6917cb8acba82134b71f651d171d57a105 +00 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e ade3bb32bd975176df9e18debd8ee047a1484a34bac9437d446f9f53daa9927b1d95b6cd432252b8ec17928d054472100f48de371bb1af3b53fe12f89095c7d1dc148797b47afffd9f37ab232b41de6917cb8acba82134b71f651d171d57a105 +00 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 a4b60242d309c06224075125243a293fc2583c2f20173b404dea13dee442b666715bf3fd16d70d6ed8d7b0b2daffebbb07e978a73b1c2a329af858e23dfeb3fd4c21de33b7eff193a049c3c845ede1e6aa3e5f364643ba3f5258bad9244b07af +00 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 a4b60242d309c06224075125243a293fc2583c2f20173b404dea13dee442b666715bf3fd16d70d6ed8d7b0b2daffebbb07e978a73b1c2a329af858e23dfeb3fd4c21de33b7eff193a049c3c845ede1e6aa3e5f364643ba3f5258bad9244b07af +00 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 a8a8d9826c20d69f47a1580441a170b37d77cfade55f7845f1f5f650634fe660c249f429a4fc292813402e104d0bb5f01163195ba4f14dc41ca720d4c031749fc60a470d966606951b9ea46ffa98f6c3f77e3989bd0e5b1a2c00b30092846e14 +00 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 a8a8d9826c20d69f47a1580441a170b37d77cfade55f7845f1f5f650634fe660c249f429a4fc292813402e104d0bb5f01163195ba4f14dc41ca720d4c031749fc60a470d966606951b9ea46ffa98f6c3f77e3989bd0e5b1a2c00b30092846e14 diff --git a/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_rfc6979_blst b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_rfc6979_blst new file mode 100644 index 000000000000..dbeae800e669 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/pop_g2/pop_g2_rfc6979_blst @@ -0,0 +1,34 @@ +00 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 8cede1108493f166f9fe40c29e0343a4ca4b3fb0b3da03bc243c4fe93b5c8928f0c7e40e547dc458546514446cb7b41911623bc0b2243bd5bbda2afded6e5993eb93875b7e27274c63202717f08ed8a69796cc96e8e28fdf240d084aaae3250a +00 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 8cede1108493f166f9fe40c29e0343a4ca4b3fb0b3da03bc243c4fe93b5c8928f0c7e40e547dc458546514446cb7b41911623bc0b2243bd5bbda2afded6e5993eb93875b7e27274c63202717f08ed8a69796cc96e8e28fdf240d084aaae3250a +00 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc 8d89a9630bb3ccae97054d853ffe35bff7961a50a004db5753167d00d32a3d5dac37305ef54a168c5561009d0d23e69c021c8aac8d00fc96efae07aef20532ab20faeb88463f244e46e913e144caed93d50dcc4c5ddeb7829c67ab4ba8bba1bd +00 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc 8d89a9630bb3ccae97054d853ffe35bff7961a50a004db5753167d00d32a3d5dac37305ef54a168c5561009d0d23e69c021c8aac8d00fc96efae07aef20532ab20faeb88463f244e46e913e144caed93d50dcc4c5ddeb7829c67ab4ba8bba1bd +00 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 8f47f970c5aa7aec857bc8dfce24662f187bf53a484948b19879fe7a0cdecf692e55857db252da4914231b93f8a622c209fc25996206be8aaa76ec366c1a92bb4be1e484a5c4d4cf7af9cdab9ca38720db4058120854d3d5dba0c61cce633b33 +00 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 8f47f970c5aa7aec857bc8dfce24662f187bf53a484948b19879fe7a0cdecf692e55857db252da4914231b93f8a622c209fc25996206be8aaa76ec366c1a92bb4be1e484a5c4d4cf7af9cdab9ca38720db4058120854d3d5dba0c61cce633b33 +00 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 b8f19d12353fa40b9ca48d2c03857614751ea91b4ff9bc166cd2ca961a8262f21faf9ceed506faae54555918104b60e201037fd577eeb491b7b94ee549d47481adff7652580bc94c464a469e0f87db81caad3f19f014b1191f0f6d1cdae13d5a +00 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 b8f19d12353fa40b9ca48d2c03857614751ea91b4ff9bc166cd2ca961a8262f21faf9ceed506faae54555918104b60e201037fd577eeb491b7b94ee549d47481adff7652580bc94c464a469e0f87db81caad3f19f014b1191f0f6d1cdae13d5a +00 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 aeb522a869bd99872215d4e0cdc141ebe7647f91127e6ea0f67f54f54eb6d15e0f0f29a37f5abb2dcdd5f72f2261ef4f005d474b778ee08cc5beb43afea480d8e2a8813654cc43b469e44d4f50d5aa9e206088acd73fc6034a1a60135b345fff +00 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 aeb522a869bd99872215d4e0cdc141ebe7647f91127e6ea0f67f54f54eb6d15e0f0f29a37f5abb2dcdd5f72f2261ef4f005d474b778ee08cc5beb43afea480d8e2a8813654cc43b469e44d4f50d5aa9e206088acd73fc6034a1a60135b345fff +00 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 a9537bb3ea1b26f032c680ca8b30f49b27a4d2c4c516623a61da8a274595eaa1782625bd88be98b31a756a0437ed9d17075e3d044a084e323b386de27c07cd52dfc6cf8d6f69d65e0a9fbb85ca701ce8ceb01303abc9fae87418cc7fc08c2c0a +00 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 a9537bb3ea1b26f032c680ca8b30f49b27a4d2c4c516623a61da8a274595eaa1782625bd88be98b31a756a0437ed9d17075e3d044a084e323b386de27c07cd52dfc6cf8d6f69d65e0a9fbb85ca701ce8ceb01303abc9fae87418cc7fc08c2c0a +00 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 8fb1b75f6959e88e285048e8d10161cf7c460cfb0673a2a4b8c5a5760b8c7f7ac6ef6e7a56387203cfae499d36d46f9a198851ced4049e462c352ee6bae6a33a9e9711185d19027ac1959df74b87b6d846f401abbd3ec592c517a9042503d146 +00 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 8fb1b75f6959e88e285048e8d10161cf7c460cfb0673a2a4b8c5a5760b8c7f7ac6ef6e7a56387203cfae499d36d46f9a198851ced4049e462c352ee6bae6a33a9e9711185d19027ac1959df74b87b6d846f401abbd3ec592c517a9042503d146 +00 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 864f82a57661816925173bdfe4d04b0e290bb5f468bbc7d2753dd64d6a4e5fa6a3111081ddc420ba0066beaa57fc137c18eaa46b38e4dd93cfcc444b49c011694ebbbf02e2af55a0aed4fb1f060f5b25802388ec7d28772b7c576658abd3c3b8 +00 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 864f82a57661816925173bdfe4d04b0e290bb5f468bbc7d2753dd64d6a4e5fa6a3111081ddc420ba0066beaa57fc137c18eaa46b38e4dd93cfcc444b49c011694ebbbf02e2af55a0aed4fb1f060f5b25802388ec7d28772b7c576658abd3c3b8 +00 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 a5de334f3eea90d08b4f5e93218fbf9f016a9f6310b91ee7879e70e2d5a7550ebd8459ee3d07d0cc37a7bf290566db7d03ef748aa0267cb528312b078c7a54ba1d922ea0a5679fb09f849a83ea9e40df72836d4ae65c227ea399d4ef178139d1 +00 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 a5de334f3eea90d08b4f5e93218fbf9f016a9f6310b91ee7879e70e2d5a7550ebd8459ee3d07d0cc37a7bf290566db7d03ef748aa0267cb528312b078c7a54ba1d922ea0a5679fb09f849a83ea9e40df72836d4ae65c227ea399d4ef178139d1 +00 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a a42b287a59b6c8d77026748832f245c42fe02b63ef61d439e30db2f1b2ced082bb237dfa1a4c00a38c9ef9c7d868c97e089744e67de3fe22fde462e6e8d170874b00e68fbf6d8141c717d74c66b5fa5770774b744ac11e3fbcaf710a84930fe9 +00 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a a42b287a59b6c8d77026748832f245c42fe02b63ef61d439e30db2f1b2ced082bb237dfa1a4c00a38c9ef9c7d868c97e089744e67de3fe22fde462e6e8d170874b00e68fbf6d8141c717d74c66b5fa5770774b744ac11e3fbcaf710a84930fe9 +00 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 ad88fdd3d120a6739066600e791380a50819634f2bbe2f7e263ab426dcd7649df5bda4cd6ecc797ab0bf7156a1b59090079f0e1f7c3fc2e89835a582bf76e59ff43cd7c9c5b2f2e6b0a3beac5acb527860f703d972ccf06e29bd1e06f7da521e +00 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 ad88fdd3d120a6739066600e791380a50819634f2bbe2f7e263ab426dcd7649df5bda4cd6ecc797ab0bf7156a1b59090079f0e1f7c3fc2e89835a582bf76e59ff43cd7c9c5b2f2e6b0a3beac5acb527860f703d972ccf06e29bd1e06f7da521e +00 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c a470eb2759d718b65f37737222344612d3214e8843e2dae2982d76caf76922583cc3d78242d7674f99507334f5ace7d719781cba7c69ff33ce35346126edc8a1b5bc61eee2335bb69037de594ee06ec16b7d2474d5b0814301d81e6698822dec +00 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c a470eb2759d718b65f37737222344612d3214e8843e2dae2982d76caf76922583cc3d78242d7674f99507334f5ace7d719781cba7c69ff33ce35346126edc8a1b5bc61eee2335bb69037de594ee06ec16b7d2474d5b0814301d81e6698822dec +00 035318fc447d48d7e6bc93b48617dddedf26aa658f a6ca8ea7c1093d9f35cff7921dd46a1757d209b6a98e74b815e99fd2813d63b322df752d6f14093fa7074b46a87f390b163bb4328eb0b1990cd136f3e7769813e621e37d00f0283b36cc35feebcfa7962809db73db6d217123fb70630918c45b +00 035318fc447d48d7e6bc93b48617dddedf26aa658f a6ca8ea7c1093d9f35cff7921dd46a1757d209b6a98e74b815e99fd2813d63b322df752d6f14093fa7074b46a87f390b163bb4328eb0b1990cd136f3e7769813e621e37d00f0283b36cc35feebcfa7962809db73db6d217123fb70630918c45b +00 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 ae15737faefad6b367a9bd32ffef20186011364075c6b21f0e2ba870c53b015177c98511e405d1f888a3b287582c2a95060494b0f058d166c250cd1930d147634b6236ddf525a2d6e9931c335b2c300425c163e1303777d7f4ec555b052b678d +00 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 ae15737faefad6b367a9bd32ffef20186011364075c6b21f0e2ba870c53b015177c98511e405d1f888a3b287582c2a95060494b0f058d166c250cd1930d147634b6236ddf525a2d6e9931c335b2c300425c163e1303777d7f4ec555b052b678d +00 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e 95c492c71df198ae2574184ca0d6c73a96b0076db9b9386925a959c91b84332ab5e465a02bb8ed26db19e9d5df836f3c0aff1f5931f1986d0cf1a3a12a0fd0100a036d39f44e623038c9d1f765a2f08f980ae88ccc9c726b3c3e9fd73270f290 +00 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e 95c492c71df198ae2574184ca0d6c73a96b0076db9b9386925a959c91b84332ab5e465a02bb8ed26db19e9d5df836f3c0aff1f5931f1986d0cf1a3a12a0fd0100a036d39f44e623038c9d1f765a2f08f980ae88ccc9c726b3c3e9fd73270f290 +00 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 944fb9137655540ad3d929c5b21f73c8b41b92420658d650bea2d9dac52d579305c4cd0171b9070827385018b436da3d10f6bfe17e2f5f0222a405fd96c1f9343b2f5143c1a236ec1d2c465e3b972a0cf09eaa86258e8d1ec28d6f64fafb0742 +00 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 944fb9137655540ad3d929c5b21f73c8b41b92420658d650bea2d9dac52d579305c4cd0171b9070827385018b436da3d10f6bfe17e2f5f0222a405fd96c1f9343b2f5143c1a236ec1d2c465e3b972a0cf09eaa86258e8d1ec28d6f64fafb0742 +00 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 94ce61bdb139f268eb18e48b8bbde2cf55b18dbcf19e232ea8e513668c0f3a4d2e3958de0e2d1e88cecd6b848a4339d70373292e79e4f55d074e14d2086ed131e13cf98cdd0391c72bf02f7b4eef5c23af49c0b27eecb5ba8853a72c3200214e +00 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 94ce61bdb139f268eb18e48b8bbde2cf55b18dbcf19e232ea8e513668c0f3a4d2e3958de0e2d1e88cecd6b848a4339d70373292e79e4f55d074e14d2086ed131e13cf98cdd0391c72bf02f7b4eef5c23af49c0b27eecb5ba8853a72c3200214e diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B233 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B233 new file mode 100644 index 000000000000..d43b73706f27 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B233 @@ -0,0 +1,60 @@ +f1b67fde01e60e4bb7904d906e9436a330c5cb5721fd4e0a3c75b83dade868736bb1d21cfb1b5c6407c373e386ee68ec2239b700e763728eb675a153b8ac44cf2a87be85fe8ed6683430cf4b7d718891cbf8d583d0a37cc952cc25fe803a7aa4fda80f05541a2f1f2601cdd0c095f7110f2a84f7d641b8531572269b21cbe77b 0056673197bfeea9bd7a8b820b4ae51a50411bf118a692bb9ed3d304da53 a26d6a8cd51fb8e81579166b6e54fa16b7870f15f1e4e51541a0a92d1ac84ecb6272011a5c2b8a8c6ed3ce490a023ceb +1d496d96b533c632ed6a91f6e3653cdffaa5b8cc0008b35e49b2dd52fe261105c2ec7ee71a4ad5d51fdc3d36d688a3b7ccb3b3b0c3a65be17b8d8aa172e3005cfbf37a2d1b1a6e268c090c6f318e7e96f9ec9b9f5a8fbcc7558d89e840f7e76e44bed91c26ca48e6f5cbc253ca2fe8cb81c484cabd24070e488f9c00cd96ad4f 00468f01d483144e514ec257f2e5fdee28a927f2adb19714c1f3524dd0d3 87911c234bf6bfae33ecee67d8354df3e39c2a54b4990e258d3e8e4e1bde4bbb68601283555d6e960f77beb0a7bb5c82 +723400655027f474446843645757f7e2cd466bf97275067b4bc4c9d79bb3b19b2421835d69db916f24b77c381fa771fc1e7a19d2b4d09411ae55acccc615b16fd24705762b441ab67083a921fd4ae569ce0de69449aa96f5b977ac7dc022fdc8335656853796f54b3fbd118577f98920624eb0a00204f1ef83827245c06646cc 0074052d027f05465a8083a59cdbf32600224e1f563f653b34314651517f 8cb733eeaffec3c331776d61f62e5dd9a13a6fdf1a27e6ad66a018c718ec1409698f3a84a8962f0a17ff7a9ccc0c04ac +155860cb31a142082bcc0bad828d747e916392d21f1873b3a3c1d28ca3ff9d45ddb66a712e3856b6afd07c8d2b2a7badab296a9775b03f6fec0befa2d8d6d00fe3938df244ab46e836a3e686c8b4f918da49f0bb3940bba34a9aa22c7caf02df7758b0de01d9f47af6146344b9be3842d9c055eaf0fb399cd8db95c544a62d8a 001856e7544223f55f80de72a6ef3822fa8fbd68eb397d06e2d76ddd35e0 a0846c5901d5d1e4d412c840d90af7b688043f204c80de758ee3670e8529013cfc00d27c21fdae6e63c80aa461c24151 +cbd6e305cc9f0dc90caee6e65a74582e9357bd25c78e33a7b14e1ac7e9397ff4466f192fb432143e6df6d61a0ab808ec0a361a6d95a357a38cd3e241fe03ed883ccc364b248ee2a08702110745c2688bdcefa33c1a45b9c8b200e45cddf3e3f66b8d37eff07fbb3366ea1558ef304085613c56707095724b3e134c7a7d3f8dbf 00860aa2b589f2defc617be73e191502e5d9952bf60547fef19eeccbca26 a42bd350105d8c3eaf6a4df21f17c4f2b3c08b02fc1117a05e70a62f623c1516bbd7cbe5f8ab7ef9dd1d9a07b4ba8b56 +812a218ff1ee1472c189f63386e5b8ab341671c3a4dad27a8c6249d1c0f9a29338b471b6179f17a078b6504e804ac55ca3b13e68a623041bc1a092ea2adf3fa1124bbfeb161e6d7c483433f1548763b84da00352a6386e1339f674d45dab13898147ede468e0e01d2c4e0ed66b395a16cc3ded3e952ac739205f35a83376cbce 00d0dec052a00ccebd0c0c5d9a08272f75744a2582cec7ddd924a2b022b2 8d0b4d697115b4fe7dd48f3e066d0f943b65d7538f8f670d065eefaaa3656ec1b6971ada9fda981f3ac2063d8c608a20 +0204b1fca831919e89e108cf140b3770f531a696b1d9a4d1fb68809eb10afccc257cc90cd36717c02b2f3d6d3d1d8a93cc5c48aa7ab9f9fddfe121ce9143376535a0c65e247c6558eac49fd1d6d1bf431ba918c471cb3d536ad485ec51f6471a340ac75f160c4c54cd3ffb9dcc123124b42df1fd2eaa005e3377c5d2d55938c6 008a017d717d6d1213f2b74c53281b07258738c0c7db649ea1ac46b9a3b6 837ea9e21881affc3e6b3637d3724383b80164f2921e886e436d5c03a6980bccf3904fe9effde910c63522c3347f750f +2033eb48756638cb56e2cc39a3e775cfa11fce86cf71f04487dcdbc7f262bc8350a30ced54d1fcb697b28a6e96f88f782947c997872307ed963e1d68985f756435af77f57755cacbb4c6b50ed419deec9f39f0a549a13e54254fa0a5832dba2d943ad4aed8688889a2dd29dcb4ea12abd6a6c50eabcb3981c3a0c1ca5f0b9629 001b56c14442b084cfd22aeef0f8028ec57c8b571c9fc1e43de05c45e47f b7679b40870fe7781dc9953d71d2cfe8be46663bc028b0173bc6086d1ea1ccff21198b8e62ca93779a09214fd386735e +2986ab1cfe8873009e932dc68d4727d77ccbbf378e43fe4aa7c54416346b036b89c0aad1b82977c9fbc39a00f1dc916c0561d8dd70298c02b6cbfe572e0ef2058641e841c6875e8515f3c1082765e046c90c956d984b76e0e8e6eb433ce26c1757ac5b13422479141971c20102e9621d18f51096ae3173c2753facee2862d66e 005afce37c5594586ac46a34ae291f591eacb9880a7de92701977f447fbf 95f2bcc4f68e565b0ccf9211a11ec661c97956ed1faabfd402e68a3c36cb7ddcf69bad0c23072e61970df7689acbe6bc +aabf5aa90ceef91c2155f90660adbcb0eedb996f5242cee15468ae217058ebeaad8cd4ff8cdc754a8ab85ba43c59fbab6386686fad5e27ad3848fe52191c7e4b203720841501792a625aef2acb6e36493b792fa55f253effca682946ad8c77e01f44e92ec3c258d0dd98d3183f4dc4a0bd3eca183794abd6232a6f9e4add8f57 000696df05dc7a54a9908a73eb18416a155cc8df4ab26032539d86eae537 aca3213625fc42c21fd774111445e3384483df27fa826b7d03197a6be5a5f117316ddd1e2e1fabd39bafd803c77809f0 +29ff209eabbde02b10b3fd559671fa53e418750c32c4a18d31cc0186d1077581bbefb8770ed079f536e866414a07431ae6633955bf42a2389b6f8a565d6e4ffb4444336e0030093876a26d4e3106e9ac697788e41f8a21c755eeb86a7c60f18e5e1069f16408a4c375a6a68d42959f2fab7ac09736c7b37c80c05897d8566ce8 005ca31e88c5b2e96e433af2023a66095161710628e7bfa428944d6676b8 aaf0b8e7ead7634a05702a0b06b282eb2d8dc570c9189a736a6bb27894004b3619a742fdc0b243a16e09cc88a6f55c33 +97765d876c80819f4004a36d09ccba78e600efc71eb7e869d3a00f658d2ace6769c7ab1ef590f41fb070aa8e08615e138df45ffbb6473d4a86ba5fdf17dd6dc9ea9ee19c0332563c99e6a3451c211d286d69102b47bfa6e07d468d9bde82e5c2063fb1ebbbed6086f542cf68ba46d4f214634afb1146dd5a6f3d50912ef5b824 00ef8fe84727a2ad8bf4e646ef28a492adfaf785a3a2ba6e6f985c649a8c b0871f5db62039f9ec8a954bb4e4f48dfeef01c97d695cd92ebc7800d09d85bea771e152dc5cf945b56b3f34e6a9445a +21cf768d087d1e4eaa8a05e2008020e243116206d675c09be42ef2bc93617ecbb0575c873c6510ede9979215531b62126552738862fc4323d487992754e39d8f0d7e111e165ff254200e05082f59a57ef649bccaef6f980094fad3b7ef93bceb161760e200f0a2e396fbb6b6142dc84d872311bf932b84616b22231747937d58 003edb94b8c62f9af30c14a790c0f5d65e362a21cd8569b9725916d534c0 b62edf403c9579de9519dbb0044019f8d12b972f0d62fdc5a3fc5b5322d69719917b5ef1ab0d768dafddb728a495d53c +7b8e58eecdab3e40212bba6bf284f9379265b3d2baec3e4625aa08d0ced851da193c292ec793dab42732c07b4e94d8b19c83aed796a7e3a6c2b954a7a9a1ff9b2bd4ca62592c8b68f709f1ad38a5c8033ebb3f33d176945bfc68e9ef2b0cee2d45a13ce89d238a33c09ce2c0c63c4233aba5717b85c4c161dd7648a41a5e39d8 000a7519be62562318da1b67d22cf8e720353d22641e0cee11c7a352bb93 82279f6267f6f163eaee78e7493463c92c80586f40c635391dab428e6c979d8af155c452cb5c7c214a67e4c7393e5dbf +f8f268d2b04fe47e5052c8d0d653787384b9654f0bd2138a6f52b80713feeed452b976a90eea4edcfbb62d04f3eafe172ddebd7cdc3701ecd6008e3d82e8eb217b13b5228839f61075159f3bd1e1409c08903874b6dfee2789dd72c208ae769ec8c7d52552a2b1fd73dad24de8b571f88e2184d0ee7d063a121187f97e746f2f 00264022fd7dc2328a6436b522793ad9406d7a586667a0daaf1bce927338 b8b7c19b1f6b12ddba944554a2b58667ade2cb92fa3f1aad3f2f0b73100d8d13f892247d74ce8a42bc5769f0e0f5df4b +d288768cbd066fad4bb2500b5683fa9e4eaedfb3dbb519b083f6b802efda0a022355565c5fc6babeccb22f3adbbda450ce5d633193d1431e40c0fe631a295cf85965cd3f5937b31866bd6a5300eaef9941daf54d49832acfceed90e572ef34ccc94eacd0fd6b903fee3c572b963d21e2881656a214d2a4c125778dbe3bbeebca 00da43214e2efb7892cc1ccde6723946d2a8248a6b4d6c8872fad525ec3b 8fdde855edaa80b70fb39ae1743c660bae41760ef9a45cd74ca35ca25e3bd6d5231a3c6d8bd2213abbeb85c79f79288f +bf0ab46e0a756c11229b0ea961f8d57218be5b00ab8b0e91d7664cdf5e0341c412c0e992d26ab12115197db39df2d1a6e18ed26a91be461432a2dfc21d98cb16003e339b0b0b1f100e4e6f4824ddac5442f22a1fac26326ed8a89cc91343d7223986d485cc8c64424e84d56be536c57e4dc5faee459b1958efd79e07e90a9811 00aeafa49d776b61f6a30d66ff64bd40dd8d79891dd5293c1b5cd3b46a7c b7cfab3a77c4567da42422df4eae81194f5588ed890bb782a4c023eecbeff9553939728d5be302327a2f68eebfc7237c +c7b1eeb7c19eb16e7f42b61d79e421b71de797a6cab4e0baee522fee7acdb533f7bbf5855316544e1b82b4f2a18ad0a2311e7622549332122171f32fc62a90e408207e0fb90d1b052821dede9c41b15b6e07d84d5d7b9e31e6396a8ed229fb6232b3051298dc5321aa589f4e289d27169f14c8cc93644916d9b72dbc92c43488 00e95db309f4305b621f51f93588a2678cb19aad0932f365fa0aaa3a3895 87cb752e6da34eb4adbc0609931988d42ddb05030d0333e1ba8ec7cd541208deeb74ccacf0261b786607d7c95c57e6a4 +a738eb074e1f277dc665118ca055e6328059ab26da188c16f56384c566e43df8cff3d2a10d2d15c3c1406de8f734b20be5dd1ce937a4289f0ddfd7bddabd03586556eb8233b8feefedaa1f49bdec6d45fd562c2a83fa9fcfc2013bdd77900857199e51fa9c7cbeab925ba8f6c3c5fae46bf8e9c574b302f1e5f9c44400152a78 00d4319cc8e409b8755880827f3200d3f0f1c64d6356fe74eb1f5aa42499 8abd51f8df4aa955c1a9ad904c4aeddbc9a03ab68229f483a7b12568aa31b1db754e5859d1edf87a54bd5a63b14f940d +b28103d77e5457c42e026e713ea6ff03722a36512da17197140117442a976f9e2139c54a759fc26af5811b455e5a0d3a95362d9939c1e738045be9237b469ae2106ceed7e7842b44cc0a475d5af6d781e32ff1dd1f4e1833dbc7f82b27dc7e1562d0e29213fd8911105104a7a16f665b926aa137f70d868c90e72f8ee2c95b64 009e556c945052e5954915c773b2d47970c521fcc99139269c3ef46093b7 8585c9010be75bb17a9998142542a53284c5c3312c172b47939a2f2acf8e55e8e8eb51ec5f2c43120078ca7a9a9b93f4 +463d04c84521ae671bb35c0a7acb3ae509b1b0470f39b8fe7ae5f3c9fbadbeb2bcc3a87e284cbdff07407a351f7ba743aeac50c4a1fef7375b90eb4af8ea2df040776bbf3e4389e7a80bea40530842642b9895ab9ef5ac8ed6c9ce7917d7b3ebcf80b801da845943313988c1970e7748cc306f914c37414f8247d648b580000f 00becc76f8a77615c4f92ae1f91645bf5bb908e75ef22fd544aae63a3c8e 97af00a98528398ebd748fa9c8508704321512c7456c5f16a15f19a9c38ef45b6bf5ce89a3968e5d0d544c8020e2ac8c +8b2379b5553ae7db6023cb010e26ae91322bc3f94dbaa369481936f90a886e5d3827d995ccf03ca59f46805fbac0337d31a8f117cc7044218a934d5bf507090e7e21178a7162c8fcb39111e6967803dbf9d752f3ae737ba024d0f4f7627e08be58efbe997a164106bfe37f67d2f19c0fcc7a6c7eebd96a72582a9c7bdf881896 0020572c2a3dc3ea430cd8cde9d642081c21658e8bda165550cd9a5d37d9 829800f62711bfe70646a474ac2804092d2c0810d10eecdc4d041f1b6e27d04ab67beb5ab89e24971cf6dd6430002937 +3090bf7373731cc44c00372c1ac59280b0f36e627ccf763fa68a7be37bb0ac8cbd4f70db54fc652566c78ad268f78f015e4bb1e41516fa56ac303a3bb4a52e1fe897d8338db5a6e37cad685e704b994504bd231c7dec0002dbd907a7ebfa809833e32eb23fffdb44fe4a18e11fa19d67356cfd703cf39a75b1a290b8a7c73afb 00769cfbf2dd8248ea1e0ac9b275c9d6ddcf923fe762079b9ed62ccbaa89 a5939a55422c00c2a1c0d44ad555ad2f063bb359986734fb63ebc8d71fd2129a306394c1a2fbd682adf10a49b7290f62 +c37389cbe3f46eeebdda343e354ccd543e96b0c2a87e057aa6b9c4895a403de706d658bbc9066c140e50fef4b56af2db1f42efb70b8021254649983f1e11d04d6b10169d5a1c2093b6ab89227b88a30537c776bb7575749c3ed87bcb29effd8e4f17915b4d5dff6cab9678d88f33abead1e73dbdc5c3307ff3d3b2d5fd7bfa83 0040ea4a37b388f0cc464f7e2bf92173107b268ff77a8acf5f517b4ec0e4 8e0dc13df78117d1a559804353580cef905cdff234855affae8a3edddaf553ebe39723b71dd92863474fcab1b97fd3ee +8884def8c3b9c5f856b9c2352c85ea71aae3c8d0e84ca74e70e404a21467159fc9826548d16dd1ec5a75dc2c23ca37b30312f25e1194e0f9385a0499db34c855412bbf58979ffce7fc3afeb7b8dbf9898df44023200d809f520db99eae315b5cf85674fab008a20340fae8f6974034fd3e55bf08c5522a460680218f9757e368 0037fc7898df9b37b5390537352f5c0b8de22659166c19d7d4df31c3938d 982f123cb1ef37a8dab88c7645425a88c63a3ea6cc486836f1ca750051b6e79cce303f29a07df51b0e399a4ade10db8d +f1fc154d469433f56c2bd42aa52237a4a4bfc08fb6d2f3f0da70a62f54e94e3f29c629c837e7adf0474fa8f23251b9b349a16848942c0d9cf5db1d0fd99527020dbe21cf0b94a9aa21f376bf74da72d36f87b306b0696771efa7250c6182b426a4500ac14de4a1804b38db8d4f3beefb8c9bb619ac82cb63fb37c2e1d22951f7 005d5069425e7a9925d2cfc6360a708147b2c1b55ede243591885147ef3b a3b67d3791c3783e9125ae370e9074c1366d32ad1b1c1e38159ba79ab33b5c5a0ed6985324bc6329da5ad54bd6aa2e36 +885cd348f7983a0721f96c0e866821223d3e5a95178b16d18652b4062b1b2278aed6f54ab06f7e37ae6ce1020aa3eb812d215194bcd212302da5b971fd86aee1dcb23057dbedb569bd0bbef80df538da69ae2358cb03bb77c64d3ead475c8c5ae5bfbdd75684b421a26f1a7b0c37548fa32d805acdc91230dd70a48232a12846 00ffe3e7b82ca62b96e057ee072a4718ca20a6cc9a3e51e4fe8ed7b4b9f9 81a771fc7e407255268da05c67137ffd487cd7d47f8f4005c569717483afff809c784a6ee0a06fe36e9153229c16c632 +ca3b0e2f1c7db4e73c699f06e432bb0f63705ba66954bec4a259bf31c161bb4861476e2f2f7dde9d841d1ea6bd0990cc793cd7a10432e38735c3eeda7a0d786e8821239bdd6c4972c96c2cf68ec5b935391f963a50fe16af2719c9029943b539ff0f1f5645962a6ac46c75d2037fa0c7cd46deadcdfc66e1ddcaada3a376acbf 0007a9cb5ce27c763646de414ca2a4dcdb774d69ed2bde7a817baddbc9de 839a5f5bc1b1068e40d574c9e9d40585d09a6948715b2ad47a0bf879e17ddaad82b97ba06713d9f2b045b2bf7b206b95 +4b0a31b746763beee77cecd318b90acf50fac4172cf4bfb354e5a440f651cb89d7a515e09ab19e9850803ab9167c2aee3b395a5da10dc9aff799d73756dfb0a9961d93bc32f15a96bf13962a03d5bd42ddc8b5928def7fc48fb063f42866fc5f96cf88fe0eb125b7c01906ad6a7fdade28ccb0a421ceff50ae03a974671b2c27 00c03fa9e38dc1c697f70bc6381f2bacaf860bb5632fc837f728da959ac9 8f9a5803d2be4e232378c5995896c328fabc956553faab5f110572a583aee2b9cfc51f9b18fed00ff25e07089c81a210 +3011d42792b21c0f1719faf6f744d576f72c5fdfd22b1a520d0e8d47e8c2b06823d853b13c9fa039fa30a6f2e3e27bb2100c6a35f55703806bbf0f79b09d0f629f8042ec63fa04062f15f2edb92b19237980005566f02bb12a40b4ec66e4ba6c599d928b33f72d7437c0e399a8e6a9068d1fef24917fc4f9ab5464ea6684dde9 0087dba00e3fe4802e01718017510094924496bd2785d4ac1a352c530473 889242dc2b5b9ae6a99a47d4505ff10115863387b9d538d51f0a960e6f48a0252b9fbf7ab6bb9554bbc3a56a345937c7 +05a5d3a3b79f4e51b722e513620c88092a9bb02408f5f52a32e782fd4923f4fd3094fc5536caf4b645d830260eba91b5173f3833dd65600fb9e246aec968b1f6ebdfddb4059fb2de7e636ed60bb7affdb74aefd158e54485d5f26be373cf944c6570daf8fd7e4b77fad57300667d6decf5c65db99ab8763bb4ecbb09fdf47e3a 005a387e7affc54a8fbb9157b5ebd400c98e2d7bd5c3e095538987d4f8d9 af9fb551f94797cf9bebc568e0c38e96d14e57965f9631a61ccc8e139c40ee18fc54ab11fbafed211a8b3b9aebfae4ac +247a101c8196eb93a440280650ad463795690bc620e46e8118db6900a71eb493d03fbcf2f73a79bb47aa8e2d8c87ef70e4cfae36fae5c45fe247d8cd0f7d0718dad106526945014b4f3bec324897d8e1fa2f457b8a68e61873b7fa0350fde3b87b7b001c13953c2050a24f71fb77eb455053e49200ebcbba7299485c0f1a40db 00adae709a930d6f5a5c0e3d8ef4aab004d741d23f0ffb8287f7059890c0 b2781a4f91d2ca8623588dd2adc7797d15727a3c9175aef19eca2190f01e16909d741b31e5a742431b83671d8eac77de +a16678c71976a3ce3362ca379b3272b92e8ca7085b43752473db34e4d6b61eeed3875f49f3328366fc9d0644824e0104817de458e4c1036636b18b83dbaf063f2f99818959224906571c7b28873d9c702360888df151e9ad1a7003e6130033203acf8a69889be6ebd90816f2abf0764f10be68653b1e56766ecc3150bef8b042 0035d391411e6d679751092c4ea5a079c591e77ebdcb57c1d9006ae70d90 82fee058b1d6c8fc4e37c487e5ca5dbbcf3e8fbae631fab5536f3d6b6d5b3892f6bfdf9dcb4025a5a305f1997c84e2f1 +bc2f080a7f0b69a6b142b8f3fb481a43bd71d07418df4f3b802568073c1a8d35729ad197f34a4e941a6dd511c63f201d1f6c34a1b66545bd5f43508c10bda1d6ef60ee5bdd25dde975e50c61f76cd36d50ee3bd8dfa2dff59524db9ef12f1e28d109b552cb42f021963f559c843476b5c889fc567b7840297c5a480e18c221dc 0084e79093f1947d6ab9cf399782436e36ef87c59a4c090930c9a74ddb10 856110bdb060e85f1e398efdda64ee9ba9148e21355f376eb8a6bb70e9b0d9a969e8b88afbe67be21a567ac438ff46ab +ea71cede8b63ddc5648eb244184bae265cd65d50f77a9e25ff93f02b132487c08732544cb88936d4fff7c0fedb39685822dd1c9be1158f647c605c9bb5f6a1ae34722fa08882c14b36b6c93cab33c9a269c7c10f755b6453ed045ea3e56f29e95a9404ba189a0b48848120392b4dcac43148b706c3d9e4c03db410cbe5dca3da 0079b6be015b8006f86fd81c2792bec6b42c08bee2d295cf9dc214c326ab 948e268e9a7e18ee90ec5bd54e1e895d8e09a1240d01edf73aba7f5b59c898e28c278c30f2f1da072abbcdbe44434189 +319b41d16e18059a1324c37161c937e882192cd949c420ce9c59208a0ac208ebb06f894a7fd78df2a3c5f23f25dee6595d3dacb25a699f115dd482ccd36fc54ba29dda279335424c86b07a1b1fa76a5411bcecaf4d37065b229cdce0bac75b666c6626ec37a716e9841be93c907f87453ad91d36846561f284421a89013b88c3 00ca9d751a060fde64336cdc88122819f4b3cd1b4e7df42d495197787894 a12a036ad13be474f907422e872b3cd0d58f850a968820a38251af5e9ce43923d83cd0e8ebba18d2480d72febce85829 +aebeee215e7b3d4c3b82db243a47506ffbf2263f6fe9de5b69286e8649d9218367c36ba95f55e48eebcbc99de3e652b0fecc4099714ee147d71b393de14a13e5044b1251e40c6791f533b310df9e70a746f4c68c604b41752eca9ce5ce67cdc574a742c694ada8f20b34d0eb467dce5566023f8533abfa9688d782646420c77b 001dde4b2d49338a10c8ebf475b3697e8480227b39bc04253a0055839e9e b49dd68d74e23a94ee12754bb6ecdabb5bea361b4e03a5a09fac92cd59e72d0b04b1c78bbfbb72a2f6686855595d5e55 +8d353a6b6f35590baef59b638914d3e934d0145b045d221d846517ceddc8ff5e3d28826d3459f8ce1260f705e80923f39abc73d5949aa7aa8ad1734be0e992bff0c9a8f4cc9bdfa430d4cf52e29d3737b0cd3231b72b16e15e1a9040b832e4a920b4a1d94c4964ac6c8abb75bbbdb10825f882ae44c534c7154c446421a04d87 002c8bea2803fd746c874fa110a716538c179c82712f38d33d0f6d037e7a b164c075e80abbbc9603f9a888ed6292797372b28e2194130224583dc3562f9c06f9023ee47a29d725fff40d05bebe2d +847f134b90f10ba3636ec24f36a94111f26d58428fda5bba4501e58c7bb55809f52320cbe9e0df55af1e40bbac9f3eaa26a55d78b60621d4356d090d98363662f406367601eaa9eb9568b1a1b319730bad7bf6a7ddf1b45eb6922faf8d065c540b671c50df758ebf8c4aca6f01878e5e0012dd038c58833e2b13ebdb9a9f3fc3 00b9119b3b4b30cbfb98ddf0a4f6953417e515fcf0e5a94e83ebc1d1d14d 940d380510f7333cdc0a8fe677cd7d117508d1cca2fb28b26bce5eb9c02de5050d1382caf1ead83a2e345c6e7cbed6b8 +99d23950493bdd931915e9f9b65e4cd1329866c0071a19d4f7d6fd190689275b7b10fc07503dd1c27a4da274dbeb3aa5cb0e71e9b7b03fc2697729b7be913756e6760098951d7015df181cf14b1e0b954e6260276af553e3e59907794b863e941950718ef154669c5c262946ba120892e0239e05910c2194f712db46e37e53b7 00f4ab2a573f3771d1e4222e251faf14e06cefed544e804c299c9a8395f5 a568f168edcf0c0d485b79b13743d9f32b8f7e195ea0fc0e1a16a2a9e70881077e78123b7a408babe09b14c11e288323 +7bef2487bc2bbbcbcc1570bbd4ed437c0dbcbbf63f666a3355aec49ea6ef593da25aefe9ae0d94db50692475425dee3c88cdea975794ac69142c25732f3541457d68d9101c8be069f2b515aadadea2019dc7abefa6c12cb3f76d9f4b5e46546f77eaf636aa8f2329130922111151a4df913d18b7cf9d0308f01ad84d878adde7 00f4649cf30d4a5269296a45977de2652cb06d3ca2aff4475bb24517b927 a5e0ddc4ee2800a7b550b3ae33ebd13da900e6c59279b83f8476685e788b27c1ac4a205880f277dc7b39d9fa53cf231b +87c717eef6dd3c7434b2c91de05723783bef603d170f654b49a04b067b077c405d2d757ce780101b930196ca4261efcfbd3fc1ebb762cc0eecf101072988aca508c41581936526d3f337053000dcf77b16172492c5d654c6612bbd2523a6ad5966d7091697a29ce882fe331f79a7eb59e5a3fe536263083cc59b8133bfd33c1d 00cca24ad914c24c011f41f80d27ea41caf41fcc8dc9dc6dff5248b2b474 9918348bc9883538497876e602203b0fb1a51677ef6f3b9d6c719662dfdfe28f09fbfbe071be96e0a2ba8978f4b5db64 +9bf48c2aebf473b3a4a928b3b6a4d2fb7e9193c9e60bc2067f9f03083a8cc7b892bdbf05601118bcc34dd283e7be996bf19b0bd36727eb9d65276b6517bf0c77ae0a9091e7a9e46182a2586eb22324939801034e5ba94ba30d1bde7d8fed51eb71036fab6224f8ff30a008422efcff7ea239ff23b9f462777e62b41b396c5dc5 00f5e12d536ef327e3b0ba65ac5fc3f7f4880f5968f3340eb8868c1d47da 95754f8128ca29ae65770ffda8222964d9d0be7b205faf9df117d35e21ee130c3fee0de4f09e651add4cb9953e6c819a +716d25519ae8f3717da269902be4a7566d6f62b68cd0faae94bce98c8a4ac6f66215ebac5407d6f64adf9d53f79f02e50921b6f0e8c805926a839443d30d9294eaa802faa7c5471d81fd1db148cdc621a8dd0c096e06fb0b71943337d5325e1bca77062684873fe904ed9012474ceae5b138e079f941a665a995026d13d7eed9 008c30d93536b8cb132277645021775d86c2ba8f199816c7539d560ac6de 94c69d0d7686bc2e3daf499ad76ef086813816825d244cc137c7848156d9079db399be09fbad28e9fe0e0ec40d0e9cbf +01e76755007b2ee5ac9e1d4c8adabad6d0f9c1c08ac6e2622b7c1ead89bd3ad0921b9525b49a780a262fe8fc0904a80391717ad7cac9607de55f7c744af8a132ec45ce79723f4a4a8c8b9ef658b360bd3890df164c9f1cd74eafb74feea251a34514ff2a57ae7a6d4bec2067cbf6ee4fdaabf13721bf9ae178b9034ac5e9665b 00fa3f15a506ccf7b50bbbad0a54d3223f5a95eb54f0d1f4e5d0cc21469b 8826dd8c0657b8d4b18df5638267660252421463ab04f968644e949178139482fc6108e02312f2825df1fb528128e899 +e95abeeb2c51a8cb75ab74253dbe130b5560cd52e2a63d501d26e1458aa568aca6694be91eee5fdfcf582c47c1c727084ee2b2c810281cf9b095808bf7e7c668eff00a6e48b06df3fe6a445e092c24d5687d7d89acc8063275caac186c441bc697b2f67aa71b03294e1adeb7e557c296dd91304ba0587cda3c984619f1eb4f2b 006400a4830889115aa88b860b3fb65905b01fd126c4aec2785518c2543a b86c127d258e68ea663d42c665f730429ea3a0a618632b5e012a49cda1d5b5180b9279c659f49047c0a24e55437baaac +bb8d8515365d240b2071daef0d80558fd3d0e059be9f6abb7b7a0a5f47e2ddca7d1b3b5101d5c583143258520ce8db0a87f877a395615c9bf879ef46f2f20f68bbc9706f82781fad69019396b27f292cdc70fff1772e90205a2225f80889f9daece1d03914d8776ac5bad24d8fb190ba10a2ca17768b918c2e079d83734eb372 00c7b73c324250f14fac0edc941f79bdbc6933ee8f64bf94b847bee5eef6 a7ee702572f2e273cfa1117e097728c001396c590c4c6c08dee18509e3493ceb06909574f7294d34cbcf0fc6425f5375 +cd8b2403435fac9caeffa21b55eaba52d7efee0f89df7142340cdffeb89556303ca01a800429397e2ff6c746743b6bc60a87133274282d4cac02e4ca90ad95d80c93b84163b96296f67d40b2a1124b2b6534ab6b60fdee312fbcdf468d0e84eb85fce4ff360136bb31ced3998d29cfaa3ae685e638ee272058f123c4f35f8b6b 003db7f28e161abf52ab0adc8c4c8544fc989af081303b8688f22b7b2eb7 904bbe0b89b38271fed8fb21278476b0976963f06475704a6337c17adb83d255f2cb2a43328681969aa46781f0e23ee4 +4bb08eeb202564efb5bda40777d71f1bcc4c7c10b611e803e5c570876f3e319e9e2bc2d32031c56a32fc0d1fcf620d4e4377d881e9e1695bcdb78acba370b849115b86c1c4b83edfa03299da8e7fd14c7cadb81a8e4911c8e427e32c8c9b67e317575331967cf58085cff0c0d48ee0b8e7dc0b49687bb1c70c703a5dad08ec81 007e9d2fdd017d6da6029e88f78927d9ac9437f542db1f1fa99e32bfcf1a b7e80a801cd238d4ffe8659538168b534d6d291ebf5a61246d3778c571c6defc2ae46237734762878fc3fc4838ae2c38 +0bce683d835fe64e6484328aa13e18b0956f6887b5e4442fce36ff09aed015889794e79da8aa60b4be565c78685674c51e1e7ac60db6a763c777198a56e382a03aff8b40862f961ae23e8b8683b76a5577769422418972ab0049119382edde9e752b42e8b93f403c1ef8665d7ce8530ce4ed9ebf6d397827cba6b7645e177231 00c94052760fc74c2b405ee4dd5dd2a7d38ebc16df9cc32df706075450b5 83d9fdfd94b1aaff24a12cab679b6c75a4b93f15da99457a1d9e974542224a34a0b26d1acc854562f8d16468a6d59b5c +a6defc770426daad4dafba3bbd2a69881334f7c31269b297e440926db54cdad3fd7ad200f5ada2b72ad221ad99a06ecac9c2563a8deed89f0d0896991d1a652f6fa282affefbdb1c1985652300d1792725071631d75a182b683a48448063c7d2563ec3d430e0fd3acea33a35cd38ec0b5b07af96af71d0bfcd879d9864ededf3 004076b93487c2da8aeaeb4725fb53b7b41b465315335c18c6ca041175b4 a9ae9f6fe381c4404f10ec054533b0e70b09588b214a4cd7688fd745e9d8b1e925912b80135afc77df3632cccd05d0d9 +7803cdf4758c199962b62943f475c6c31356f5d9b997a12e21146a2399cd0dd3b97a860b2ce639e2801571599136d4a8cdbfb12fd1a5ce22374991e090533ff42823a2c58d2076b772814eea7fd7a1fde68263ef912681c72c7aa3e5a7cc44ee8c65e72228b7631e600121ea35bfbbc783b6ae3c0c8f80198ada218be533760b 0076ddd73ee4fc1f5e6766e229cc7236cdfce312417ea291f7c3328d5ab1 aa60d4f7296f7ab4c09c8eaa7e488d4cb217141efcb05a90f155e9b0e5e070d02cb35b3d315e1e6d7f855392f6cafe25 +e789461e1dad0b6e21abeb6ae2e96385549d1bae39415188c8f833233da6a3328144c97ddb36e0ff4d9e19d84f869e79e609c51b32de59892fb0446dd28cc164a3e53534c950d26f87fb74e682db2038cde778bde06c3ee2eca2a077d8fcc2b0332e352e0e7e6487444a8ad60e78ff213b16fda9faf374dc6d27b7a3c4c6d196 007e1f8988ad804aae7d09a99be19384cc599e7652c02c391542be74b17b 9245d775b80a03c33a851f4724fddc479a069503447050ab71f8f3c60b71b32bfe18e502c4f0b93fb9e748772eb2eaab +9b58c145d1b6c887f2b25fb672cd49c3a1117224be697c15182d4048be92968a6500f8bcf747fcf33145c13a8d72e891a6e0c4c7310c2b62f3181bf586fe32f1ecf4feee8c2c8bf6c2bfdf9d5f88981ce080095c93e49a772d8e7b59f9cffccec3ca2f212ef4c6748f64e224f4f098334d83108bf6f8c7b43c5eb549f1526897 009b2292b0244c2aabe8b43d95039984d504ebe05eaff318760e4dee739f ade9efaf3ce99e2e392492fd1093331d34a24db47fc77e6861788945da2d7c691ace3d43300ecac25d8a6935050d390a +52310a901fe9681a23dd6e02f12974d57f2c4f653322d9a0ff8b338cc6c2bd9f4765c90c6b3c9fb17df3f492e67d204e39d81a8fdeb92c852a1dcc6151ed6c63049037235c6751c9a902748163a567b714725b4d3995e0edbde03215c645b1a1da3147f7406245432800c50f823a1f991c863427ff4c68e4e16d1b106ee40dd9 007ca463b50fdd92d9163f1c2bdfce2ee45ba1437b79162e3e959b814cab 918ac5f3b9dd8b5403b42971521775ebf97e0cf5e85762d5ac60bd1db12d27d3f0326fe6d5e5f5d1536842ab345b7e71 +ff419c011601cfaf833067cf28dbe6e935ebeddf8b5111a97f6eebf3bb28376334f329cd877a134b074790a073db766efe018fce666a34650cbac285ae856fb6b3b8b96877282bc11cd9f9c8e510ed1f69bc2725a44a1d2b35de1edfd8bc9d20c7525ab0bbc27662a7cfc1bbd1e0f4fce5b88411521e3893e027cc8c73acdabd 00c3844750f63fe0c2e930bc38fe88522f4e72a2fd0db9778ade20e939b3 8ab2a92bfcf1f818c2a3b61c9919e863279aa14436a746f150d5fb147553ca854971ba3719427299959952842cf1eea6 +05a89c4824c5de66587875011e704bc6e06e991ba8f3aed331cfffe55aa266a08c729f77b8d082dca4d286b2d451ea838d726cc2cf298fddf2d7376714c5e37b64506f353917caec525a1209391449c078c5197a371feade74f8fc8a1a1d67576edfda13c14ad324342fc0b09277941dc072ec0d39434ff1cb91fc59478fcde7 00a3bea235dea86506be4476eb7999dcb8e584a34238c4a894ad6823b93f 8ca0796698bea38430a8ac02bb82a26cd8201c67d53abd7f47f1c1e84fc5aaf8848a18bc75d9180c8977be3ee39a7ea9 +13e6b5241365d9d0ef9e8b05cabb3248afd221ec02eab92284b98bda3d9272184bfe5251d35705defba5085381430e99b33a3ab77d7870e5102757d065862372df2434a25556b76e54ebc39d4e6c3aba5cd6acf0c335756f7d9385c1068d4cfa37526a9a58c0ccc7f87a8189176c5d4f201499236058ec061357dcdb5acdba40 009a367cd1cffd8dfcca179e167ea437ee48e9b6f42559dda9224701d3f6 a367e1389a2515976855269d28989ee03942073d4f68c4df27b726f5edd20f8cfc4830ac945e2722f31a11a273a4acd9 +139a1a5090b97afb8fecfff8745efacf7dcf91a4393a7b629564e598d58d5be39c05c5830d4c8ca85d29e9e2c31ad0447864e867d0ef4788ac734f8d871daebceda98d449308c2afbe97724c3af8a468f1925065f39e52ba4b7d15728a744b1252a20476dcfff7bcb82aa72c209e72abb3c24419bc26191390ffed340c1b9c6f 0046f4ad2522e78b9b35297d28f361fb0ce82306322aedc119251d8241be 80c5a59f2d15bdd5ef28be5068da44f770080eebcfe2afe49bf6bb45542b0a39af4ead1ae0e622bd9061a0cf19a75833 +3315e5cda5f252e3291b61e493ab919c20a8af1286d9660cfa2f5ca38b6defe19ebecf820787fe692d04eae8a5f5d37abfb593309569cedf45efd0cecef6951b718924c8380ba52e8ab8c9bfb2261ed5f01cc5a5f9fc5fcdd269a0f122c597afdd9a836cf8f96838c3e8962c1788c3ce4128719b3ef4fc88569643dcad6da16f 00ac82137e9c7a5ecfb8b1a7df9ab50732934566a392a6c8915ee8ca8144 993da52250ce953ac7d5a07843c470f3ea7398190ee2b54a47d113a1b69d454a492ef6e6e9d95376afe1948979472db4 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B233_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B233_blst new file mode 100644 index 000000000000..d43b73706f27 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B233_blst @@ -0,0 +1,60 @@ +f1b67fde01e60e4bb7904d906e9436a330c5cb5721fd4e0a3c75b83dade868736bb1d21cfb1b5c6407c373e386ee68ec2239b700e763728eb675a153b8ac44cf2a87be85fe8ed6683430cf4b7d718891cbf8d583d0a37cc952cc25fe803a7aa4fda80f05541a2f1f2601cdd0c095f7110f2a84f7d641b8531572269b21cbe77b 0056673197bfeea9bd7a8b820b4ae51a50411bf118a692bb9ed3d304da53 a26d6a8cd51fb8e81579166b6e54fa16b7870f15f1e4e51541a0a92d1ac84ecb6272011a5c2b8a8c6ed3ce490a023ceb +1d496d96b533c632ed6a91f6e3653cdffaa5b8cc0008b35e49b2dd52fe261105c2ec7ee71a4ad5d51fdc3d36d688a3b7ccb3b3b0c3a65be17b8d8aa172e3005cfbf37a2d1b1a6e268c090c6f318e7e96f9ec9b9f5a8fbcc7558d89e840f7e76e44bed91c26ca48e6f5cbc253ca2fe8cb81c484cabd24070e488f9c00cd96ad4f 00468f01d483144e514ec257f2e5fdee28a927f2adb19714c1f3524dd0d3 87911c234bf6bfae33ecee67d8354df3e39c2a54b4990e258d3e8e4e1bde4bbb68601283555d6e960f77beb0a7bb5c82 +723400655027f474446843645757f7e2cd466bf97275067b4bc4c9d79bb3b19b2421835d69db916f24b77c381fa771fc1e7a19d2b4d09411ae55acccc615b16fd24705762b441ab67083a921fd4ae569ce0de69449aa96f5b977ac7dc022fdc8335656853796f54b3fbd118577f98920624eb0a00204f1ef83827245c06646cc 0074052d027f05465a8083a59cdbf32600224e1f563f653b34314651517f 8cb733eeaffec3c331776d61f62e5dd9a13a6fdf1a27e6ad66a018c718ec1409698f3a84a8962f0a17ff7a9ccc0c04ac +155860cb31a142082bcc0bad828d747e916392d21f1873b3a3c1d28ca3ff9d45ddb66a712e3856b6afd07c8d2b2a7badab296a9775b03f6fec0befa2d8d6d00fe3938df244ab46e836a3e686c8b4f918da49f0bb3940bba34a9aa22c7caf02df7758b0de01d9f47af6146344b9be3842d9c055eaf0fb399cd8db95c544a62d8a 001856e7544223f55f80de72a6ef3822fa8fbd68eb397d06e2d76ddd35e0 a0846c5901d5d1e4d412c840d90af7b688043f204c80de758ee3670e8529013cfc00d27c21fdae6e63c80aa461c24151 +cbd6e305cc9f0dc90caee6e65a74582e9357bd25c78e33a7b14e1ac7e9397ff4466f192fb432143e6df6d61a0ab808ec0a361a6d95a357a38cd3e241fe03ed883ccc364b248ee2a08702110745c2688bdcefa33c1a45b9c8b200e45cddf3e3f66b8d37eff07fbb3366ea1558ef304085613c56707095724b3e134c7a7d3f8dbf 00860aa2b589f2defc617be73e191502e5d9952bf60547fef19eeccbca26 a42bd350105d8c3eaf6a4df21f17c4f2b3c08b02fc1117a05e70a62f623c1516bbd7cbe5f8ab7ef9dd1d9a07b4ba8b56 +812a218ff1ee1472c189f63386e5b8ab341671c3a4dad27a8c6249d1c0f9a29338b471b6179f17a078b6504e804ac55ca3b13e68a623041bc1a092ea2adf3fa1124bbfeb161e6d7c483433f1548763b84da00352a6386e1339f674d45dab13898147ede468e0e01d2c4e0ed66b395a16cc3ded3e952ac739205f35a83376cbce 00d0dec052a00ccebd0c0c5d9a08272f75744a2582cec7ddd924a2b022b2 8d0b4d697115b4fe7dd48f3e066d0f943b65d7538f8f670d065eefaaa3656ec1b6971ada9fda981f3ac2063d8c608a20 +0204b1fca831919e89e108cf140b3770f531a696b1d9a4d1fb68809eb10afccc257cc90cd36717c02b2f3d6d3d1d8a93cc5c48aa7ab9f9fddfe121ce9143376535a0c65e247c6558eac49fd1d6d1bf431ba918c471cb3d536ad485ec51f6471a340ac75f160c4c54cd3ffb9dcc123124b42df1fd2eaa005e3377c5d2d55938c6 008a017d717d6d1213f2b74c53281b07258738c0c7db649ea1ac46b9a3b6 837ea9e21881affc3e6b3637d3724383b80164f2921e886e436d5c03a6980bccf3904fe9effde910c63522c3347f750f +2033eb48756638cb56e2cc39a3e775cfa11fce86cf71f04487dcdbc7f262bc8350a30ced54d1fcb697b28a6e96f88f782947c997872307ed963e1d68985f756435af77f57755cacbb4c6b50ed419deec9f39f0a549a13e54254fa0a5832dba2d943ad4aed8688889a2dd29dcb4ea12abd6a6c50eabcb3981c3a0c1ca5f0b9629 001b56c14442b084cfd22aeef0f8028ec57c8b571c9fc1e43de05c45e47f b7679b40870fe7781dc9953d71d2cfe8be46663bc028b0173bc6086d1ea1ccff21198b8e62ca93779a09214fd386735e +2986ab1cfe8873009e932dc68d4727d77ccbbf378e43fe4aa7c54416346b036b89c0aad1b82977c9fbc39a00f1dc916c0561d8dd70298c02b6cbfe572e0ef2058641e841c6875e8515f3c1082765e046c90c956d984b76e0e8e6eb433ce26c1757ac5b13422479141971c20102e9621d18f51096ae3173c2753facee2862d66e 005afce37c5594586ac46a34ae291f591eacb9880a7de92701977f447fbf 95f2bcc4f68e565b0ccf9211a11ec661c97956ed1faabfd402e68a3c36cb7ddcf69bad0c23072e61970df7689acbe6bc +aabf5aa90ceef91c2155f90660adbcb0eedb996f5242cee15468ae217058ebeaad8cd4ff8cdc754a8ab85ba43c59fbab6386686fad5e27ad3848fe52191c7e4b203720841501792a625aef2acb6e36493b792fa55f253effca682946ad8c77e01f44e92ec3c258d0dd98d3183f4dc4a0bd3eca183794abd6232a6f9e4add8f57 000696df05dc7a54a9908a73eb18416a155cc8df4ab26032539d86eae537 aca3213625fc42c21fd774111445e3384483df27fa826b7d03197a6be5a5f117316ddd1e2e1fabd39bafd803c77809f0 +29ff209eabbde02b10b3fd559671fa53e418750c32c4a18d31cc0186d1077581bbefb8770ed079f536e866414a07431ae6633955bf42a2389b6f8a565d6e4ffb4444336e0030093876a26d4e3106e9ac697788e41f8a21c755eeb86a7c60f18e5e1069f16408a4c375a6a68d42959f2fab7ac09736c7b37c80c05897d8566ce8 005ca31e88c5b2e96e433af2023a66095161710628e7bfa428944d6676b8 aaf0b8e7ead7634a05702a0b06b282eb2d8dc570c9189a736a6bb27894004b3619a742fdc0b243a16e09cc88a6f55c33 +97765d876c80819f4004a36d09ccba78e600efc71eb7e869d3a00f658d2ace6769c7ab1ef590f41fb070aa8e08615e138df45ffbb6473d4a86ba5fdf17dd6dc9ea9ee19c0332563c99e6a3451c211d286d69102b47bfa6e07d468d9bde82e5c2063fb1ebbbed6086f542cf68ba46d4f214634afb1146dd5a6f3d50912ef5b824 00ef8fe84727a2ad8bf4e646ef28a492adfaf785a3a2ba6e6f985c649a8c b0871f5db62039f9ec8a954bb4e4f48dfeef01c97d695cd92ebc7800d09d85bea771e152dc5cf945b56b3f34e6a9445a +21cf768d087d1e4eaa8a05e2008020e243116206d675c09be42ef2bc93617ecbb0575c873c6510ede9979215531b62126552738862fc4323d487992754e39d8f0d7e111e165ff254200e05082f59a57ef649bccaef6f980094fad3b7ef93bceb161760e200f0a2e396fbb6b6142dc84d872311bf932b84616b22231747937d58 003edb94b8c62f9af30c14a790c0f5d65e362a21cd8569b9725916d534c0 b62edf403c9579de9519dbb0044019f8d12b972f0d62fdc5a3fc5b5322d69719917b5ef1ab0d768dafddb728a495d53c +7b8e58eecdab3e40212bba6bf284f9379265b3d2baec3e4625aa08d0ced851da193c292ec793dab42732c07b4e94d8b19c83aed796a7e3a6c2b954a7a9a1ff9b2bd4ca62592c8b68f709f1ad38a5c8033ebb3f33d176945bfc68e9ef2b0cee2d45a13ce89d238a33c09ce2c0c63c4233aba5717b85c4c161dd7648a41a5e39d8 000a7519be62562318da1b67d22cf8e720353d22641e0cee11c7a352bb93 82279f6267f6f163eaee78e7493463c92c80586f40c635391dab428e6c979d8af155c452cb5c7c214a67e4c7393e5dbf +f8f268d2b04fe47e5052c8d0d653787384b9654f0bd2138a6f52b80713feeed452b976a90eea4edcfbb62d04f3eafe172ddebd7cdc3701ecd6008e3d82e8eb217b13b5228839f61075159f3bd1e1409c08903874b6dfee2789dd72c208ae769ec8c7d52552a2b1fd73dad24de8b571f88e2184d0ee7d063a121187f97e746f2f 00264022fd7dc2328a6436b522793ad9406d7a586667a0daaf1bce927338 b8b7c19b1f6b12ddba944554a2b58667ade2cb92fa3f1aad3f2f0b73100d8d13f892247d74ce8a42bc5769f0e0f5df4b +d288768cbd066fad4bb2500b5683fa9e4eaedfb3dbb519b083f6b802efda0a022355565c5fc6babeccb22f3adbbda450ce5d633193d1431e40c0fe631a295cf85965cd3f5937b31866bd6a5300eaef9941daf54d49832acfceed90e572ef34ccc94eacd0fd6b903fee3c572b963d21e2881656a214d2a4c125778dbe3bbeebca 00da43214e2efb7892cc1ccde6723946d2a8248a6b4d6c8872fad525ec3b 8fdde855edaa80b70fb39ae1743c660bae41760ef9a45cd74ca35ca25e3bd6d5231a3c6d8bd2213abbeb85c79f79288f +bf0ab46e0a756c11229b0ea961f8d57218be5b00ab8b0e91d7664cdf5e0341c412c0e992d26ab12115197db39df2d1a6e18ed26a91be461432a2dfc21d98cb16003e339b0b0b1f100e4e6f4824ddac5442f22a1fac26326ed8a89cc91343d7223986d485cc8c64424e84d56be536c57e4dc5faee459b1958efd79e07e90a9811 00aeafa49d776b61f6a30d66ff64bd40dd8d79891dd5293c1b5cd3b46a7c b7cfab3a77c4567da42422df4eae81194f5588ed890bb782a4c023eecbeff9553939728d5be302327a2f68eebfc7237c +c7b1eeb7c19eb16e7f42b61d79e421b71de797a6cab4e0baee522fee7acdb533f7bbf5855316544e1b82b4f2a18ad0a2311e7622549332122171f32fc62a90e408207e0fb90d1b052821dede9c41b15b6e07d84d5d7b9e31e6396a8ed229fb6232b3051298dc5321aa589f4e289d27169f14c8cc93644916d9b72dbc92c43488 00e95db309f4305b621f51f93588a2678cb19aad0932f365fa0aaa3a3895 87cb752e6da34eb4adbc0609931988d42ddb05030d0333e1ba8ec7cd541208deeb74ccacf0261b786607d7c95c57e6a4 +a738eb074e1f277dc665118ca055e6328059ab26da188c16f56384c566e43df8cff3d2a10d2d15c3c1406de8f734b20be5dd1ce937a4289f0ddfd7bddabd03586556eb8233b8feefedaa1f49bdec6d45fd562c2a83fa9fcfc2013bdd77900857199e51fa9c7cbeab925ba8f6c3c5fae46bf8e9c574b302f1e5f9c44400152a78 00d4319cc8e409b8755880827f3200d3f0f1c64d6356fe74eb1f5aa42499 8abd51f8df4aa955c1a9ad904c4aeddbc9a03ab68229f483a7b12568aa31b1db754e5859d1edf87a54bd5a63b14f940d +b28103d77e5457c42e026e713ea6ff03722a36512da17197140117442a976f9e2139c54a759fc26af5811b455e5a0d3a95362d9939c1e738045be9237b469ae2106ceed7e7842b44cc0a475d5af6d781e32ff1dd1f4e1833dbc7f82b27dc7e1562d0e29213fd8911105104a7a16f665b926aa137f70d868c90e72f8ee2c95b64 009e556c945052e5954915c773b2d47970c521fcc99139269c3ef46093b7 8585c9010be75bb17a9998142542a53284c5c3312c172b47939a2f2acf8e55e8e8eb51ec5f2c43120078ca7a9a9b93f4 +463d04c84521ae671bb35c0a7acb3ae509b1b0470f39b8fe7ae5f3c9fbadbeb2bcc3a87e284cbdff07407a351f7ba743aeac50c4a1fef7375b90eb4af8ea2df040776bbf3e4389e7a80bea40530842642b9895ab9ef5ac8ed6c9ce7917d7b3ebcf80b801da845943313988c1970e7748cc306f914c37414f8247d648b580000f 00becc76f8a77615c4f92ae1f91645bf5bb908e75ef22fd544aae63a3c8e 97af00a98528398ebd748fa9c8508704321512c7456c5f16a15f19a9c38ef45b6bf5ce89a3968e5d0d544c8020e2ac8c +8b2379b5553ae7db6023cb010e26ae91322bc3f94dbaa369481936f90a886e5d3827d995ccf03ca59f46805fbac0337d31a8f117cc7044218a934d5bf507090e7e21178a7162c8fcb39111e6967803dbf9d752f3ae737ba024d0f4f7627e08be58efbe997a164106bfe37f67d2f19c0fcc7a6c7eebd96a72582a9c7bdf881896 0020572c2a3dc3ea430cd8cde9d642081c21658e8bda165550cd9a5d37d9 829800f62711bfe70646a474ac2804092d2c0810d10eecdc4d041f1b6e27d04ab67beb5ab89e24971cf6dd6430002937 +3090bf7373731cc44c00372c1ac59280b0f36e627ccf763fa68a7be37bb0ac8cbd4f70db54fc652566c78ad268f78f015e4bb1e41516fa56ac303a3bb4a52e1fe897d8338db5a6e37cad685e704b994504bd231c7dec0002dbd907a7ebfa809833e32eb23fffdb44fe4a18e11fa19d67356cfd703cf39a75b1a290b8a7c73afb 00769cfbf2dd8248ea1e0ac9b275c9d6ddcf923fe762079b9ed62ccbaa89 a5939a55422c00c2a1c0d44ad555ad2f063bb359986734fb63ebc8d71fd2129a306394c1a2fbd682adf10a49b7290f62 +c37389cbe3f46eeebdda343e354ccd543e96b0c2a87e057aa6b9c4895a403de706d658bbc9066c140e50fef4b56af2db1f42efb70b8021254649983f1e11d04d6b10169d5a1c2093b6ab89227b88a30537c776bb7575749c3ed87bcb29effd8e4f17915b4d5dff6cab9678d88f33abead1e73dbdc5c3307ff3d3b2d5fd7bfa83 0040ea4a37b388f0cc464f7e2bf92173107b268ff77a8acf5f517b4ec0e4 8e0dc13df78117d1a559804353580cef905cdff234855affae8a3edddaf553ebe39723b71dd92863474fcab1b97fd3ee +8884def8c3b9c5f856b9c2352c85ea71aae3c8d0e84ca74e70e404a21467159fc9826548d16dd1ec5a75dc2c23ca37b30312f25e1194e0f9385a0499db34c855412bbf58979ffce7fc3afeb7b8dbf9898df44023200d809f520db99eae315b5cf85674fab008a20340fae8f6974034fd3e55bf08c5522a460680218f9757e368 0037fc7898df9b37b5390537352f5c0b8de22659166c19d7d4df31c3938d 982f123cb1ef37a8dab88c7645425a88c63a3ea6cc486836f1ca750051b6e79cce303f29a07df51b0e399a4ade10db8d +f1fc154d469433f56c2bd42aa52237a4a4bfc08fb6d2f3f0da70a62f54e94e3f29c629c837e7adf0474fa8f23251b9b349a16848942c0d9cf5db1d0fd99527020dbe21cf0b94a9aa21f376bf74da72d36f87b306b0696771efa7250c6182b426a4500ac14de4a1804b38db8d4f3beefb8c9bb619ac82cb63fb37c2e1d22951f7 005d5069425e7a9925d2cfc6360a708147b2c1b55ede243591885147ef3b a3b67d3791c3783e9125ae370e9074c1366d32ad1b1c1e38159ba79ab33b5c5a0ed6985324bc6329da5ad54bd6aa2e36 +885cd348f7983a0721f96c0e866821223d3e5a95178b16d18652b4062b1b2278aed6f54ab06f7e37ae6ce1020aa3eb812d215194bcd212302da5b971fd86aee1dcb23057dbedb569bd0bbef80df538da69ae2358cb03bb77c64d3ead475c8c5ae5bfbdd75684b421a26f1a7b0c37548fa32d805acdc91230dd70a48232a12846 00ffe3e7b82ca62b96e057ee072a4718ca20a6cc9a3e51e4fe8ed7b4b9f9 81a771fc7e407255268da05c67137ffd487cd7d47f8f4005c569717483afff809c784a6ee0a06fe36e9153229c16c632 +ca3b0e2f1c7db4e73c699f06e432bb0f63705ba66954bec4a259bf31c161bb4861476e2f2f7dde9d841d1ea6bd0990cc793cd7a10432e38735c3eeda7a0d786e8821239bdd6c4972c96c2cf68ec5b935391f963a50fe16af2719c9029943b539ff0f1f5645962a6ac46c75d2037fa0c7cd46deadcdfc66e1ddcaada3a376acbf 0007a9cb5ce27c763646de414ca2a4dcdb774d69ed2bde7a817baddbc9de 839a5f5bc1b1068e40d574c9e9d40585d09a6948715b2ad47a0bf879e17ddaad82b97ba06713d9f2b045b2bf7b206b95 +4b0a31b746763beee77cecd318b90acf50fac4172cf4bfb354e5a440f651cb89d7a515e09ab19e9850803ab9167c2aee3b395a5da10dc9aff799d73756dfb0a9961d93bc32f15a96bf13962a03d5bd42ddc8b5928def7fc48fb063f42866fc5f96cf88fe0eb125b7c01906ad6a7fdade28ccb0a421ceff50ae03a974671b2c27 00c03fa9e38dc1c697f70bc6381f2bacaf860bb5632fc837f728da959ac9 8f9a5803d2be4e232378c5995896c328fabc956553faab5f110572a583aee2b9cfc51f9b18fed00ff25e07089c81a210 +3011d42792b21c0f1719faf6f744d576f72c5fdfd22b1a520d0e8d47e8c2b06823d853b13c9fa039fa30a6f2e3e27bb2100c6a35f55703806bbf0f79b09d0f629f8042ec63fa04062f15f2edb92b19237980005566f02bb12a40b4ec66e4ba6c599d928b33f72d7437c0e399a8e6a9068d1fef24917fc4f9ab5464ea6684dde9 0087dba00e3fe4802e01718017510094924496bd2785d4ac1a352c530473 889242dc2b5b9ae6a99a47d4505ff10115863387b9d538d51f0a960e6f48a0252b9fbf7ab6bb9554bbc3a56a345937c7 +05a5d3a3b79f4e51b722e513620c88092a9bb02408f5f52a32e782fd4923f4fd3094fc5536caf4b645d830260eba91b5173f3833dd65600fb9e246aec968b1f6ebdfddb4059fb2de7e636ed60bb7affdb74aefd158e54485d5f26be373cf944c6570daf8fd7e4b77fad57300667d6decf5c65db99ab8763bb4ecbb09fdf47e3a 005a387e7affc54a8fbb9157b5ebd400c98e2d7bd5c3e095538987d4f8d9 af9fb551f94797cf9bebc568e0c38e96d14e57965f9631a61ccc8e139c40ee18fc54ab11fbafed211a8b3b9aebfae4ac +247a101c8196eb93a440280650ad463795690bc620e46e8118db6900a71eb493d03fbcf2f73a79bb47aa8e2d8c87ef70e4cfae36fae5c45fe247d8cd0f7d0718dad106526945014b4f3bec324897d8e1fa2f457b8a68e61873b7fa0350fde3b87b7b001c13953c2050a24f71fb77eb455053e49200ebcbba7299485c0f1a40db 00adae709a930d6f5a5c0e3d8ef4aab004d741d23f0ffb8287f7059890c0 b2781a4f91d2ca8623588dd2adc7797d15727a3c9175aef19eca2190f01e16909d741b31e5a742431b83671d8eac77de +a16678c71976a3ce3362ca379b3272b92e8ca7085b43752473db34e4d6b61eeed3875f49f3328366fc9d0644824e0104817de458e4c1036636b18b83dbaf063f2f99818959224906571c7b28873d9c702360888df151e9ad1a7003e6130033203acf8a69889be6ebd90816f2abf0764f10be68653b1e56766ecc3150bef8b042 0035d391411e6d679751092c4ea5a079c591e77ebdcb57c1d9006ae70d90 82fee058b1d6c8fc4e37c487e5ca5dbbcf3e8fbae631fab5536f3d6b6d5b3892f6bfdf9dcb4025a5a305f1997c84e2f1 +bc2f080a7f0b69a6b142b8f3fb481a43bd71d07418df4f3b802568073c1a8d35729ad197f34a4e941a6dd511c63f201d1f6c34a1b66545bd5f43508c10bda1d6ef60ee5bdd25dde975e50c61f76cd36d50ee3bd8dfa2dff59524db9ef12f1e28d109b552cb42f021963f559c843476b5c889fc567b7840297c5a480e18c221dc 0084e79093f1947d6ab9cf399782436e36ef87c59a4c090930c9a74ddb10 856110bdb060e85f1e398efdda64ee9ba9148e21355f376eb8a6bb70e9b0d9a969e8b88afbe67be21a567ac438ff46ab +ea71cede8b63ddc5648eb244184bae265cd65d50f77a9e25ff93f02b132487c08732544cb88936d4fff7c0fedb39685822dd1c9be1158f647c605c9bb5f6a1ae34722fa08882c14b36b6c93cab33c9a269c7c10f755b6453ed045ea3e56f29e95a9404ba189a0b48848120392b4dcac43148b706c3d9e4c03db410cbe5dca3da 0079b6be015b8006f86fd81c2792bec6b42c08bee2d295cf9dc214c326ab 948e268e9a7e18ee90ec5bd54e1e895d8e09a1240d01edf73aba7f5b59c898e28c278c30f2f1da072abbcdbe44434189 +319b41d16e18059a1324c37161c937e882192cd949c420ce9c59208a0ac208ebb06f894a7fd78df2a3c5f23f25dee6595d3dacb25a699f115dd482ccd36fc54ba29dda279335424c86b07a1b1fa76a5411bcecaf4d37065b229cdce0bac75b666c6626ec37a716e9841be93c907f87453ad91d36846561f284421a89013b88c3 00ca9d751a060fde64336cdc88122819f4b3cd1b4e7df42d495197787894 a12a036ad13be474f907422e872b3cd0d58f850a968820a38251af5e9ce43923d83cd0e8ebba18d2480d72febce85829 +aebeee215e7b3d4c3b82db243a47506ffbf2263f6fe9de5b69286e8649d9218367c36ba95f55e48eebcbc99de3e652b0fecc4099714ee147d71b393de14a13e5044b1251e40c6791f533b310df9e70a746f4c68c604b41752eca9ce5ce67cdc574a742c694ada8f20b34d0eb467dce5566023f8533abfa9688d782646420c77b 001dde4b2d49338a10c8ebf475b3697e8480227b39bc04253a0055839e9e b49dd68d74e23a94ee12754bb6ecdabb5bea361b4e03a5a09fac92cd59e72d0b04b1c78bbfbb72a2f6686855595d5e55 +8d353a6b6f35590baef59b638914d3e934d0145b045d221d846517ceddc8ff5e3d28826d3459f8ce1260f705e80923f39abc73d5949aa7aa8ad1734be0e992bff0c9a8f4cc9bdfa430d4cf52e29d3737b0cd3231b72b16e15e1a9040b832e4a920b4a1d94c4964ac6c8abb75bbbdb10825f882ae44c534c7154c446421a04d87 002c8bea2803fd746c874fa110a716538c179c82712f38d33d0f6d037e7a b164c075e80abbbc9603f9a888ed6292797372b28e2194130224583dc3562f9c06f9023ee47a29d725fff40d05bebe2d +847f134b90f10ba3636ec24f36a94111f26d58428fda5bba4501e58c7bb55809f52320cbe9e0df55af1e40bbac9f3eaa26a55d78b60621d4356d090d98363662f406367601eaa9eb9568b1a1b319730bad7bf6a7ddf1b45eb6922faf8d065c540b671c50df758ebf8c4aca6f01878e5e0012dd038c58833e2b13ebdb9a9f3fc3 00b9119b3b4b30cbfb98ddf0a4f6953417e515fcf0e5a94e83ebc1d1d14d 940d380510f7333cdc0a8fe677cd7d117508d1cca2fb28b26bce5eb9c02de5050d1382caf1ead83a2e345c6e7cbed6b8 +99d23950493bdd931915e9f9b65e4cd1329866c0071a19d4f7d6fd190689275b7b10fc07503dd1c27a4da274dbeb3aa5cb0e71e9b7b03fc2697729b7be913756e6760098951d7015df181cf14b1e0b954e6260276af553e3e59907794b863e941950718ef154669c5c262946ba120892e0239e05910c2194f712db46e37e53b7 00f4ab2a573f3771d1e4222e251faf14e06cefed544e804c299c9a8395f5 a568f168edcf0c0d485b79b13743d9f32b8f7e195ea0fc0e1a16a2a9e70881077e78123b7a408babe09b14c11e288323 +7bef2487bc2bbbcbcc1570bbd4ed437c0dbcbbf63f666a3355aec49ea6ef593da25aefe9ae0d94db50692475425dee3c88cdea975794ac69142c25732f3541457d68d9101c8be069f2b515aadadea2019dc7abefa6c12cb3f76d9f4b5e46546f77eaf636aa8f2329130922111151a4df913d18b7cf9d0308f01ad84d878adde7 00f4649cf30d4a5269296a45977de2652cb06d3ca2aff4475bb24517b927 a5e0ddc4ee2800a7b550b3ae33ebd13da900e6c59279b83f8476685e788b27c1ac4a205880f277dc7b39d9fa53cf231b +87c717eef6dd3c7434b2c91de05723783bef603d170f654b49a04b067b077c405d2d757ce780101b930196ca4261efcfbd3fc1ebb762cc0eecf101072988aca508c41581936526d3f337053000dcf77b16172492c5d654c6612bbd2523a6ad5966d7091697a29ce882fe331f79a7eb59e5a3fe536263083cc59b8133bfd33c1d 00cca24ad914c24c011f41f80d27ea41caf41fcc8dc9dc6dff5248b2b474 9918348bc9883538497876e602203b0fb1a51677ef6f3b9d6c719662dfdfe28f09fbfbe071be96e0a2ba8978f4b5db64 +9bf48c2aebf473b3a4a928b3b6a4d2fb7e9193c9e60bc2067f9f03083a8cc7b892bdbf05601118bcc34dd283e7be996bf19b0bd36727eb9d65276b6517bf0c77ae0a9091e7a9e46182a2586eb22324939801034e5ba94ba30d1bde7d8fed51eb71036fab6224f8ff30a008422efcff7ea239ff23b9f462777e62b41b396c5dc5 00f5e12d536ef327e3b0ba65ac5fc3f7f4880f5968f3340eb8868c1d47da 95754f8128ca29ae65770ffda8222964d9d0be7b205faf9df117d35e21ee130c3fee0de4f09e651add4cb9953e6c819a +716d25519ae8f3717da269902be4a7566d6f62b68cd0faae94bce98c8a4ac6f66215ebac5407d6f64adf9d53f79f02e50921b6f0e8c805926a839443d30d9294eaa802faa7c5471d81fd1db148cdc621a8dd0c096e06fb0b71943337d5325e1bca77062684873fe904ed9012474ceae5b138e079f941a665a995026d13d7eed9 008c30d93536b8cb132277645021775d86c2ba8f199816c7539d560ac6de 94c69d0d7686bc2e3daf499ad76ef086813816825d244cc137c7848156d9079db399be09fbad28e9fe0e0ec40d0e9cbf +01e76755007b2ee5ac9e1d4c8adabad6d0f9c1c08ac6e2622b7c1ead89bd3ad0921b9525b49a780a262fe8fc0904a80391717ad7cac9607de55f7c744af8a132ec45ce79723f4a4a8c8b9ef658b360bd3890df164c9f1cd74eafb74feea251a34514ff2a57ae7a6d4bec2067cbf6ee4fdaabf13721bf9ae178b9034ac5e9665b 00fa3f15a506ccf7b50bbbad0a54d3223f5a95eb54f0d1f4e5d0cc21469b 8826dd8c0657b8d4b18df5638267660252421463ab04f968644e949178139482fc6108e02312f2825df1fb528128e899 +e95abeeb2c51a8cb75ab74253dbe130b5560cd52e2a63d501d26e1458aa568aca6694be91eee5fdfcf582c47c1c727084ee2b2c810281cf9b095808bf7e7c668eff00a6e48b06df3fe6a445e092c24d5687d7d89acc8063275caac186c441bc697b2f67aa71b03294e1adeb7e557c296dd91304ba0587cda3c984619f1eb4f2b 006400a4830889115aa88b860b3fb65905b01fd126c4aec2785518c2543a b86c127d258e68ea663d42c665f730429ea3a0a618632b5e012a49cda1d5b5180b9279c659f49047c0a24e55437baaac +bb8d8515365d240b2071daef0d80558fd3d0e059be9f6abb7b7a0a5f47e2ddca7d1b3b5101d5c583143258520ce8db0a87f877a395615c9bf879ef46f2f20f68bbc9706f82781fad69019396b27f292cdc70fff1772e90205a2225f80889f9daece1d03914d8776ac5bad24d8fb190ba10a2ca17768b918c2e079d83734eb372 00c7b73c324250f14fac0edc941f79bdbc6933ee8f64bf94b847bee5eef6 a7ee702572f2e273cfa1117e097728c001396c590c4c6c08dee18509e3493ceb06909574f7294d34cbcf0fc6425f5375 +cd8b2403435fac9caeffa21b55eaba52d7efee0f89df7142340cdffeb89556303ca01a800429397e2ff6c746743b6bc60a87133274282d4cac02e4ca90ad95d80c93b84163b96296f67d40b2a1124b2b6534ab6b60fdee312fbcdf468d0e84eb85fce4ff360136bb31ced3998d29cfaa3ae685e638ee272058f123c4f35f8b6b 003db7f28e161abf52ab0adc8c4c8544fc989af081303b8688f22b7b2eb7 904bbe0b89b38271fed8fb21278476b0976963f06475704a6337c17adb83d255f2cb2a43328681969aa46781f0e23ee4 +4bb08eeb202564efb5bda40777d71f1bcc4c7c10b611e803e5c570876f3e319e9e2bc2d32031c56a32fc0d1fcf620d4e4377d881e9e1695bcdb78acba370b849115b86c1c4b83edfa03299da8e7fd14c7cadb81a8e4911c8e427e32c8c9b67e317575331967cf58085cff0c0d48ee0b8e7dc0b49687bb1c70c703a5dad08ec81 007e9d2fdd017d6da6029e88f78927d9ac9437f542db1f1fa99e32bfcf1a b7e80a801cd238d4ffe8659538168b534d6d291ebf5a61246d3778c571c6defc2ae46237734762878fc3fc4838ae2c38 +0bce683d835fe64e6484328aa13e18b0956f6887b5e4442fce36ff09aed015889794e79da8aa60b4be565c78685674c51e1e7ac60db6a763c777198a56e382a03aff8b40862f961ae23e8b8683b76a5577769422418972ab0049119382edde9e752b42e8b93f403c1ef8665d7ce8530ce4ed9ebf6d397827cba6b7645e177231 00c94052760fc74c2b405ee4dd5dd2a7d38ebc16df9cc32df706075450b5 83d9fdfd94b1aaff24a12cab679b6c75a4b93f15da99457a1d9e974542224a34a0b26d1acc854562f8d16468a6d59b5c +a6defc770426daad4dafba3bbd2a69881334f7c31269b297e440926db54cdad3fd7ad200f5ada2b72ad221ad99a06ecac9c2563a8deed89f0d0896991d1a652f6fa282affefbdb1c1985652300d1792725071631d75a182b683a48448063c7d2563ec3d430e0fd3acea33a35cd38ec0b5b07af96af71d0bfcd879d9864ededf3 004076b93487c2da8aeaeb4725fb53b7b41b465315335c18c6ca041175b4 a9ae9f6fe381c4404f10ec054533b0e70b09588b214a4cd7688fd745e9d8b1e925912b80135afc77df3632cccd05d0d9 +7803cdf4758c199962b62943f475c6c31356f5d9b997a12e21146a2399cd0dd3b97a860b2ce639e2801571599136d4a8cdbfb12fd1a5ce22374991e090533ff42823a2c58d2076b772814eea7fd7a1fde68263ef912681c72c7aa3e5a7cc44ee8c65e72228b7631e600121ea35bfbbc783b6ae3c0c8f80198ada218be533760b 0076ddd73ee4fc1f5e6766e229cc7236cdfce312417ea291f7c3328d5ab1 aa60d4f7296f7ab4c09c8eaa7e488d4cb217141efcb05a90f155e9b0e5e070d02cb35b3d315e1e6d7f855392f6cafe25 +e789461e1dad0b6e21abeb6ae2e96385549d1bae39415188c8f833233da6a3328144c97ddb36e0ff4d9e19d84f869e79e609c51b32de59892fb0446dd28cc164a3e53534c950d26f87fb74e682db2038cde778bde06c3ee2eca2a077d8fcc2b0332e352e0e7e6487444a8ad60e78ff213b16fda9faf374dc6d27b7a3c4c6d196 007e1f8988ad804aae7d09a99be19384cc599e7652c02c391542be74b17b 9245d775b80a03c33a851f4724fddc479a069503447050ab71f8f3c60b71b32bfe18e502c4f0b93fb9e748772eb2eaab +9b58c145d1b6c887f2b25fb672cd49c3a1117224be697c15182d4048be92968a6500f8bcf747fcf33145c13a8d72e891a6e0c4c7310c2b62f3181bf586fe32f1ecf4feee8c2c8bf6c2bfdf9d5f88981ce080095c93e49a772d8e7b59f9cffccec3ca2f212ef4c6748f64e224f4f098334d83108bf6f8c7b43c5eb549f1526897 009b2292b0244c2aabe8b43d95039984d504ebe05eaff318760e4dee739f ade9efaf3ce99e2e392492fd1093331d34a24db47fc77e6861788945da2d7c691ace3d43300ecac25d8a6935050d390a +52310a901fe9681a23dd6e02f12974d57f2c4f653322d9a0ff8b338cc6c2bd9f4765c90c6b3c9fb17df3f492e67d204e39d81a8fdeb92c852a1dcc6151ed6c63049037235c6751c9a902748163a567b714725b4d3995e0edbde03215c645b1a1da3147f7406245432800c50f823a1f991c863427ff4c68e4e16d1b106ee40dd9 007ca463b50fdd92d9163f1c2bdfce2ee45ba1437b79162e3e959b814cab 918ac5f3b9dd8b5403b42971521775ebf97e0cf5e85762d5ac60bd1db12d27d3f0326fe6d5e5f5d1536842ab345b7e71 +ff419c011601cfaf833067cf28dbe6e935ebeddf8b5111a97f6eebf3bb28376334f329cd877a134b074790a073db766efe018fce666a34650cbac285ae856fb6b3b8b96877282bc11cd9f9c8e510ed1f69bc2725a44a1d2b35de1edfd8bc9d20c7525ab0bbc27662a7cfc1bbd1e0f4fce5b88411521e3893e027cc8c73acdabd 00c3844750f63fe0c2e930bc38fe88522f4e72a2fd0db9778ade20e939b3 8ab2a92bfcf1f818c2a3b61c9919e863279aa14436a746f150d5fb147553ca854971ba3719427299959952842cf1eea6 +05a89c4824c5de66587875011e704bc6e06e991ba8f3aed331cfffe55aa266a08c729f77b8d082dca4d286b2d451ea838d726cc2cf298fddf2d7376714c5e37b64506f353917caec525a1209391449c078c5197a371feade74f8fc8a1a1d67576edfda13c14ad324342fc0b09277941dc072ec0d39434ff1cb91fc59478fcde7 00a3bea235dea86506be4476eb7999dcb8e584a34238c4a894ad6823b93f 8ca0796698bea38430a8ac02bb82a26cd8201c67d53abd7f47f1c1e84fc5aaf8848a18bc75d9180c8977be3ee39a7ea9 +13e6b5241365d9d0ef9e8b05cabb3248afd221ec02eab92284b98bda3d9272184bfe5251d35705defba5085381430e99b33a3ab77d7870e5102757d065862372df2434a25556b76e54ebc39d4e6c3aba5cd6acf0c335756f7d9385c1068d4cfa37526a9a58c0ccc7f87a8189176c5d4f201499236058ec061357dcdb5acdba40 009a367cd1cffd8dfcca179e167ea437ee48e9b6f42559dda9224701d3f6 a367e1389a2515976855269d28989ee03942073d4f68c4df27b726f5edd20f8cfc4830ac945e2722f31a11a273a4acd9 +139a1a5090b97afb8fecfff8745efacf7dcf91a4393a7b629564e598d58d5be39c05c5830d4c8ca85d29e9e2c31ad0447864e867d0ef4788ac734f8d871daebceda98d449308c2afbe97724c3af8a468f1925065f39e52ba4b7d15728a744b1252a20476dcfff7bcb82aa72c209e72abb3c24419bc26191390ffed340c1b9c6f 0046f4ad2522e78b9b35297d28f361fb0ce82306322aedc119251d8241be 80c5a59f2d15bdd5ef28be5068da44f770080eebcfe2afe49bf6bb45542b0a39af4ead1ae0e622bd9061a0cf19a75833 +3315e5cda5f252e3291b61e493ab919c20a8af1286d9660cfa2f5ca38b6defe19ebecf820787fe692d04eae8a5f5d37abfb593309569cedf45efd0cecef6951b718924c8380ba52e8ab8c9bfb2261ed5f01cc5a5f9fc5fcdd269a0f122c597afdd9a836cf8f96838c3e8962c1788c3ce4128719b3ef4fc88569643dcad6da16f 00ac82137e9c7a5ecfb8b1a7df9ab50732934566a392a6c8915ee8ca8144 993da52250ce953ac7d5a07843c470f3ea7398190ee2b54a47d113a1b69d454a492ef6e6e9d95376afe1948979472db4 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B283 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B283 new file mode 100644 index 000000000000..e09b2833758a --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B283 @@ -0,0 +1,60 @@ +067f27bbcecbad85277fa3629da11a24b2f19ba1e65a69d827fad430346c9d102e1b4452d04147c8133acc1e268490cd342a54065a1bd6470aabbad42fbddc54a9a76c68aceba397cb350327c5e6f5a6df0b5b5560f04700d536b384dd4b412e74fd1b8f782611e9426bf8ca77b2448d9a9f415bcfee30dda1ccb49737994f2d 0299ff06e019b5f78a1aec39706b22213abb601bd62b9979bf9bc89fb702e724e3ada994 8aa1ba14a100902b89aa04239faadd48be036d118acbbc12fd7847bfc492534b77ded3b05fbf0a9fc863f77a2fed548d +44adcb7e2462247b44c59608cbe228ada574ecb9f6f38baf30e42b589fb9b157bb0560e5a2aa5523b71cc0d7f583b502bec45d9b8352f29ee1842f42a17a5b16136feaa2efa4a0ae306402940ecd6b71e57d1467c98e7960de2a97f88b43487e4f4016af1292381d70c18c7e6eed99a14cdeb5b3caf73688658e4c5b54c81e08 009c2804f8cab768248fb3fff8a055b3f4585c00de5c1615a19f9425b9432ea09afba8f2 9710ac154df619ceeebf699b20d9e13e8c02e599f40c6e4b6fad3da69eaf3c7259c089da270ca14d5a2d3c18d47326c2 +cffee6252c7eb6d91d8fe100a1e62f0ad9f862d78ca2b747a6c17b8c9ea8980dc239b3b673310e6e7483582399163e39d889abc1a613fe77849ebc09b4f7f4fe0688b8a9869ae918a88294c7ee199be50ee9460db14725ae70b449d0cb48f30e7d817ec02c0cd586119341dba0b74f0279330807cfccc99c8c340b72c1764a45 02e625a6bc6d0ce7c06231de827068bdb0abc8ffb57c82b35ee3a0f873b9473905974d34 b33673f9ef18cf51c5a623385fb25d9490319656a13ddea70fe2d80007d88f2bfcb0b8dcbd4a7dbeae3326186a1ff2d0 +d058ab5dc07228253707ef224897ea0fcd09c3d5cc91fdce9e03c1c59c53fb4596be2ed929c7455e67ac7f4891aed3eb06ad88f2c4aaaabff045b959f900d1019d706b60526375851bb891494e99995928e4cd51c9616aa651ec77bd7e398916bb9ed3156391bf7fb1e29181e2b011dae2edaf803607def2ac6b194929a57f45 0376ac24e1b86f8a55c052d92a0bdc6472fa03acdcdbccbf7c321ec0ccd97aa0a66b4181 93488b80d237868f60af9674b9d4f2df265169bb9cfb2c8f56a20457626ff15b929970cb9f21059c92365218ed3038e6 +c86f2cc7ab5df5cf1a236fd83792769474cef464032800ffe98a44cf29dbfb6f24088160eb31a11a382ff2a49f3e05e983462f5304272f96c0a002b69af3d233aebe867ee63fa46666760a6889d022c18645b491f8d71b6a3b6b4ef058e280cf625198715b64b025bf0449445d3dd7e1f27153926e617bd2c96638345431d1ed 02b50a6395fc02b9ac1841323de4520292f913519bc0d6a471aa28021322fc4dbcd7b802 a7c18f8bbf323153fedc15b3d78a2f0f0ae9b984b8b9d109aa9f438883e2d91c638becebad87b52cb42e4d6036acd5ac +c1328d8d2e5b6ffc850a9600bd6482518ddd9cee3fc9140febb72bcd444b0cd7e8074587d51b62cce4b3d4f34ad3355353fabe363369cf790db2df9fdac3a0ec4757e2dfb3b683eaa3e26531691ce765742e1c0bdc0e1028d347b6085fc459df0989c6a144271454eaffe413cae2ad7c8b2371fd2df1afffe56df727009765a2 024e5889722f6c35e18ca47effa9e415b1ba790066a91fb3c9f7b001ce28fc732b09bc23 8c11141400cc9f51e3c1356f51094ac600b0c345b2f5df5dbddfb5d719eb555fdac102035b756c8a75652e337161d73e +7176b7013ea27e94281977eacb976bb31c753bf80fa09680a29128a6fc15234f79f0e9900aff3217ce9be72c378042c6c34fced0158740073d1a985fa25987fb218002e425868fda5a47de51abfd04de34e2b8634cebfbdc98e80f93d94096193eaa82dc8778fc23f3765c7acdad94fdaa272df0ff0f28190c10a462ee78ac92 0056d15b81f40b6378588a5efe43e21b95e18120d514bfdda0e7759a1d0766a8a35ce5ac a4d8479ab01862b6f09ba70816335d019d573aa23be741357c3f9493ddcc9577bf5416e7eed4973a527e186f5f7c21ac +4c3642ba040a9955b9d50dcd1c936688c17c363854358afa8ca49c6abd906dfdc4d89bb4cab0bbc363fb5b74e1f004d4b09ec9dfeed4c0bfb482a9061a1f487a3d79195ff7b65a0504bced3a28db0ebe8fcf8ab1ee4a3ae91324d15d890ac4c479144dd5538d2e36d3a587769ee9cd2d5c6f85a03362a022fe0efc4a3902b71a 012fb2fb5bf5f7e42a500154823a174ba2d05af71e3b0cf47fab46e673ea1822f1563def 97ae64157b962fe9513f200649d9a14cec1ce65df0daeab290322f0ea3c4aeb6688f37f2a6fecdf79b991ec8da82f9a8 +e471f39c18b081362adc7da47dec254dab8d765f005ac574640d78c14222639245563912d942f3be212ee3cef134407334c8fe3602fa0e1629de5331643d76715dc1b0ffcebd484d86c5211be4b285a31688b205fa988e6c15b36daf396ccdcc209c7dde2a732f5c31c84c7ea041408ebf15e56632583af0131bd7f531b5fc45 030096c54fd480647e017f8cdbbdef292e799f054e3279d228b09816a757566a744a8266 ae739598a37e3cb6ab880dbdca4538feb7f4dac1a6218d14a338118c0a893349d701173ed4167cc2eef4addf88ad64ef +8a93fe53e83075c4025228540af7e96a588520da34e3eadeb99a4ab2f3dbbb8f85fe63a3b86c1f4ec912e665ca05b43e869985eae3791b91205afb1380e16c25b74e6793fa63e4a55dcf25dc22d03f09deddeb9042b620434111afe08c5657c7d754af66ad91a1b5423301b1e8e6389a1404060d1b6a99fe0f89598482979e42 00a1b7e9c8c2dc25b494b5ef3195b294e41cd3c2c35235ab42542bd3e2a52d5826662bf9 b30713a3c155fd94bd4035fe22086aa5ee79a8720077c339a4bf136c20085d35716e240c4b947d5694fbcb9288cb0731 +e193a8ef6f454ca1aed38bb67aca6d08280d421b196d89938c0582b7cde74dafd71716f3818940af412d4a7ff3960a8517aee108ae03576b68ee7557d35e6f1ab823d124de7243dd02b542591f62c80d822608572889573e4c9dc62f99d68e07800da6f83cb6f5e03d1f2ac15f90e38b4f25e0a75e354e4b60cc81c0bbe81d39 0059b1a8fb84530bba7a607ee88310e31bc6ea6a6881603567a1081a05a3a9ff87e719ef 98dbd9d4e11f330ec2260a7028c9c8494843f67801b58848608a5a51d491a26031b878e205b1cc580a1dd2e54af93723 +8a99b9db191f6cabc88b430bc2293e6774d5180f019d871839289e25aec29379f14606e742190b7aa062e3b29fe0254146d9614856c5140c7315015abb98ac00da2c7e33cbcc82c24b797366f12767322c4381454d9d1eeaedb616b0ea5c66d1422da459f18081f4f966d05ce279c6ee69b1bf94b8388d38d4b770d9ed69025f 030ddc2c7a4ce300cc2b75f0f977033f16c1f8bb13aae3d494c381f9a6dc8622499ae4df 8dd40de1e9c9f12ccdda7235ced30a5837b6bcc28a9b723c3c68a1cc1fd6ba20a87ce96f9e1f82d0649653b663b32b00 +5c437b331831530aa94623b1736f00b986172699f0a02a5e5df0008bf25341787e2e66046f2c929dfe0058c3cb89fc5bebbe1025bb1edd1ee31522ed568e7b5b4ca3991afdc76a68cbc2c4f81863e27fdaf6a564fab2c6354e5c657de81390f8a4132669fd24a48580c716b5b7961a9c091f614d11cf45dfdaec8946a54a11d8 007899928922fbfdb5407517725edf231d15a8b62d90b7fb6d8c8d20424850dc44f797ed a9e9270d545179ffe489b59f16aa04a85312bf4ad8b5dab28e4ae243c85235881c4c2a43956c205f380586625da292f9 +91aa08567d8da4c90684dc06068f69deae240212842ff1786f04ec41b40d9187aa92c76401f9fcedced62876a34df82ad7c1e63b68bb2a972257ea8542bda6a7f1a020c9b122943b6d651abda8b8d322a8fb762eee376daa2d3637a71ed6c4f5cf96f61c0da2d6e1dda3370d80e51da2cbd8aef3267168c67359523faf910dfb 02a2af63d1171930758bd3e5bfdac62cca1a83a3b55a49b3f80cf0d9ee4b2082757beac0 80431ad43d05ddeaab83fb70314adf5bda5c414ab11d34c44b9e4a1b8ea5b4f9bd3333620fb3478b51069bb2829fb84f +eb5297bf408c1a55e400a20a3c10acbc5c2bc6d6ccfcc0941fb7a6fd4d2834415a6df86c3a6c4b867d1215aeb8222153da8cbbb1576c92c07ca2c36d8f243fd911f9a057e39ee25832454e28d7ed52a8d04169b9b9677a16b32d5d211b8573a8986e9bf36d7206417ad2771daa11bc21fd7ee1029b65ff7c9b2705a6dc9cf9cb 035994e89e13916ad82608f74a639e6aceb756ff913aec440519946d6434af9a60a6af49 8f74f3e97323ee0fcface68c7bd05af2240b87f11d0eadb972ac3dececf612b2123351206b82a388414f26ddab370f75 +f415d0adcd533dd8318b94560f86732c262ad2c6dff9dc83e2435543f429a2158cd2fbab0d96c027f71008c4895ecc644c2ceaefa80937f6cc6338d15d36e459a16bd9387a361a6d800acfd834ad5aecf442e30b70f5bfa164747cf9f89325b80976052a83a5e896c00c54f81472b14329cf23bec10a8e693005de2a506ba83d 029639da33f48e4fb0d9efdf50bba550e739f0d2476385cba09d926e789191b6fb0a73ff 986a91a4be5d83f369de2ff2a41f49a6c3afdb68d44f186d7ba72e98535abee93be5cf3ab5ca86510901865953fcbbf8 +b178d86c9335b85e02178fc4551769db589ab91d823fac219c7e14e2f029753b203962389476723832f8d9631dd7764e6dd35da290afa42a794476f5c7727b3688aced848dabc9954201578cc7b25801710931f45cba1199d3788d64dc0188412e70723fb25b8ecb6718358150c4037b5b81466dac1686cb5270bb1c72d34bb1 00583a7ecbf2a975a32d07428d27ac82e5dc13d1466c4fdfc1e6a05a8d9a289f1010617d b42f24f945a5066e8f3a77f0329d750a9606afd3c05bd74e7f3d2d27fb873233a0b8411f7a94a8f84127ff6822ccba15 +c8bfe9fa7c848531aa2762d48c153cd091100858aa0d79f994fd0e31b495ec662209a9c8761cd1d40c3d8c4262cf4dc83c4a2549a5cd477726ab6268b4b94a78b1c4a7e700812872d7f41912a723dd9abc305420ea1e1fb1fee41bf643f3a24abd6e8fbf6fde2475e290527724a6f99fd75374bf7cb01b34d3e60d8db33c4de1 00f817ab1b49131fb9bbe8c112c25a36f064efa85de7506fb9cd29d81b326bf276277f7f 82776803681aa1dba90536c4c42d6775b59bd994284ae16442fa8973f74e0d2aa6213a5a59866b9d6239214713c231d4 +9a5f563d0f9fd1f31f3a822de628ae970954f4e71292492d727109036491c29e66b9b0f2c90c26abe94c08502f5e923a9ddaf6a7d91e9541ce90d0a49f03ce4e4769753d5b7d922e1ceaac4b4cfa4262732a09550aa076b8ff9d46a50fa17de17e3b6bd606698464d116fcd5f1ae11bf45b0c48d3b738427cb47b0d1272b03cc 02782af76ffebf3e2bfc0576b70e4f4bb87c762e2bb230d278ce776310a14f5b678f29af a0ec809b301afd1580e88e41f614328ce18011576fc4488e7f5eabb5074699cc396713d921f616f5f815928f27166604 +3d6b065721da9de82cb33ec2c27107eb399b1e69ac8fa51145ed4147e20d72e27434104e76af988a3bc94f55e36677a05182fe2376dbe38195fc6a30673a4dca87336c7304f3f31d49216fbdfea00fd1e105d8b0c13ab11f8892e0045e915c17dfaab07b24ed21b06af5a8cad4f45fbee5a25bb6e87466a7bc422c0bb896440b 031b827b88f14d3822244809096157df3c0aa99da90c00cd9f0b18dfe306f6881834e6b6 b530a6af9af4d418c28282ff8455e9e59bc83794f36550c08d847f6ea6eb6b30ec31773cc0b03de611ad8b1886494617 +d125f0e2e6135567adec9e77da2afc6862e28d618416632ced829d14ee8b61116da59dfb44098a40a0b927731125617e3d2f32cfbd1546a6e758c1ab6597e75db07add52ecb61d37da2e9ed04df95b36ac249f4cbd794cb561655cbbe4b34834c497b3d392d78ed0db8db683aff0076fb6e43acba3fa2b91210cc6cf3fa594b0 027da4916f1c471cff80bfa14d12aa10270fc3b26caed010c0111f6e5a40d914a3927763 994346fd4a27af7f225dc194c8721ad3ecb5df000e2a7d3b8ade5c3b12074836faeb50f0467451cd1a1eacc52a455356 +b380f97687ba24d617a42df1b14e5506edc4b62dfec35ed9fd886bb769832cec7f9adae10c21b7cd9152588797b4efc6b2b30a873d3f25e683ea9be070dd69731949a51121e534fabfa3a2eae0ee90a454182248bedf2595cd47ad08614177d58f7a773f5023b538f5f568682c83fb60e3fb1aa859948d01bf7b214e7f2dc719 010608eb51dc0ee97d6e488a23c582ecf0ea1df9a24db77094d87b3fb6ca98507280a934 b4be9e44e51d2fef4c060e2bdc638d1a663f3604d73484f5898ea2322a823fcb718afd4c2dd977504ddeda6a7ac19b90 +3f9ec57e4228e1a6ec49df02c58d756515305e48763ba1dc67298be9a1548576c28c82b4e9b3f62357d9b3c522b16d5c496a39effbdc8290edd2cadc0019e6b9fae1e61238b13b6265ad2ff413a5a0684babdb0013e7632051455e6fd943815213c555dba96cba8911e006bfddec6c3353065004538f37e48df9e339498d85c6 0123f9eb8babed548df08cc3afc1d3b3bbed52b538d4654f2088fe76062fbea75b85a560 8aa7900d060b0225959675709058fd90ca1c488aad8b6d837d06e91162ae46d0acd0091dc6b9e74762fec0f1e4171b0d +bdbd7b7bf3337bd9d21a3c6db379f95408c17e49dd394e94737ceae889f45dc0ff5d48cadc53703a16b5589939506b548f8dfd34c577c084f372166cbea320c8fd07c809b211e0749ea639e68f890affa1569b66bd763c7c710989e491011371eb1d93ed9479ff0216b7f79c901a2023e2cf80b565d1c0517e73117190cd2f02 006a18e626452111922e02e31d662f4301319946a204ae8a34f06b91dd1b5b96456365e3 99593be8543a207de6373c5d91d47cb6cf8bf649be3a7465a4d29583cf33474060fac54fd3befc83aafd26aed0276556 +436b288512ea57bc24f84fdd117da9dc1858bae8c11637f99295d88fa9d05e3c053a2584a6fe200ad190b3077d9a1608f660349dda405066c1562f6897ef69b6b674d6bc11fa470d0b96a7cf8f6e098c9ac03b0ef415aa045867ac7c11d16cee78ecf08850ccabf70f761682b561d0d0e4a889d840dc74932648ca2fb58259f7 03307fd717015b12a2dc76ada21442ac1d97519f66898b214c2ea317ab0f0905e819e4e9 ab3d3c0ebf0f20357887fcc13f9c78b85bc97a098694086fa696f474695a6da7cab0c9d30c3ee938ecc7e27a296f6170 +672faa156dc188bf16bf8933d65e091c633f294486049ce96a4a403dca28a149f4f840e8bef47412285363e9e89006614b013a41baad9885f1d9980cc897ffbd5f8a7d0e63feaeb42c07776efb307ed680ba1cebf470dd9bd8a2a9efc2b1daa569524394f9a50398add1a5bd2f7c263f9e63c2d49461acf98444fd23341ce78d 014f9f412e3c7d770626e800d43cfcbba3ae6aec8563af748e8a97b67d244334b6e6d2b3 94bd9aeee2a8aca9a4e17d490d0778001b561cc35ec99f9e01eeadfdc0ffc2fc7cd4d442ed3433d56219c8db626d1502 +4321334cc8ee44f1cb392a4b280a95561809dd3639ddf43b6e11cb73067597988d95b8643d86c76c3c6b932d9262b9b8b55a04fba0666dd8b8ff1e8fdf799ae3945b6e30d3af3966f1a6d634d5e012710d66cb447fc3375130968a2e1e647780aada2609d87247c90338dd71c3bcc3902311caba27d5d4ea4d73ccea960d4bfa 03091a6a8bdac1e43542dce752694972e734dca31c061c7d1000754296d0748055db3f09 b448216965f5f0bdd988e6425565da4d07ff83e2877bcc7776274ac6b41ad78595c47ccfccb8dbed5f5e2b3677595d7e +2087e22094570d39fa937f15a3ef0601709a66666344186a33b487d041793fbb9709a95af250b1df0762ea98e911aeb3ff1fa19f0aca53fd4179e454e0e91636e55cc5b17cad9e1575c82ad265dc34c4a66b7a31ecb9ef9dc756f2ac1d9dab35369a6bad4a0f47e629daab91addc6d297d1e5d81477b3966d8c3b607ed194d88 01195921b91353db9bcd00510efffe009c94f6bd8d790f5fb3e5a0101c9ca5d21c6ef2eb 967d57f6495119d10e255e255a2dd5248a2dc1c492fe3d7852a4180ffada156fe57aa5b9afd071d581ddad0f551e831a +15c7bca449a73b03bbfa783f5a91ca0b7916889a5d99d541e2e8593c3b176a5b634ba20b34407fbd94ae1c1398f5313cab7402f3bcd7ad277a8c66d09a6df5dd086b20a0a3823fbbb80980cd86bd13e527eee15656cc977103e80113539e26695addd9eef6a1f56986168d9a53f8b5de833f8962c3826cca106ae9e8c00208d2 029dc20446e9abacb43823e12a83737b46e6e577466b5a3925e0f9d496824dadb4d4b50c b79a0949d1b8ab9fbc3b09f21c7810db0dc69189543f103282736f3c687377d84569845e6b31abf0bfa8d89f528f668f +d12fbb82ee7a57eaf76b63fd6bc6c0a65c85f135f019d43ff7bc295cad15d53729d904fed63d69d3ffe8b82c0ebaf0399e2717ece40e011f710b5db46aa457c23b85545953398b814816a1e7a8ab5b0b14c4a0451b0bda9d0d2ec4a374bcaae208b7fe8056bfa17d6b7ffd4ba2e9179f49b9cd781b0c06f6ce3eec26cd428cb6 03b9b77d19a42e9a555da8ab70aa5638890b2ed21daefa28ca6323fc658662dabcbfaf52 960242652584e6df7fa8c2901b8da643dd598b82397bdac0229f05764c2f4f024d192ce9324dc02120efb3a29bdbcbde +eab0a37915c6b43b0d1e3ef92e6317b3afc8b8301b22f6059da8271fc5fe0e419ca6097daba213915855631af64e10d8382d70599d903d1535e25cbf74da3a12ba2f13c33a8562e0db03edce791f1d39af8850fd1feff0eb25f9ad0a86dfab627b96e65831bffc5f6d9693d20493bc9dd6eb3e9325dea50b055768e8aa30d49c 00b9f8f3e89e9c1ef835390612bfe26d714e878c1c864f0a50190e5d2281081c5083923b 963562b963e324153eee04aa4d498d535723aa68610415eab16c228a0249a6e29392c59c40c7f21000754036db8a50a1 +fdb93afd5dd1e3eaf72c7ea9a6cddb07fc2054499ffe152cb2870163eee71ace5bd420b898cb4fa80ea53fbbaece2a1eef6427b632320e9c97e38acb16b62fdbf6585b54fabf0a703307ca50f86387bed1815a05b0c8991e0743d10cdf49c8facfd7ddeb8d4a7b706b5a29e1d00ac88b0ee88b3153185495ac8388cc70104154 03a30a1c15b9ed71e102341f97c223a9b5ea3e6a335861c3cf407ef691a18cc639dbe74c b25d2dc20559f68f9ee6fc00b5d0ff395a7ce1f15f7e6eb3c7d3499a23b96a1b54501ff3e82fa62f10cea38c9be95bf7 +c78e35d1a5b1bbb0ec21e7ba7b7c74c859d88f3e100e40ae34128cf093885dae4e87cd09f3239dd8e79e25305220880dd352a650225d9bd193b9b84e488c458b0b5fde1af941c0c9fdf952d2fa41f665918dccae27ab7923da4710f8c27ac8ed424992568dd6f0a6c3ecead21650ed162e0292104eef3c2d8551be866a88d279 0083330123cc64c11888c1fd388629d0b329a50ef31a476b909a182c930ff02d0c389b93 953a2ed2c245213e4ac7541525155fc058aabbe3306810eb158602ad54ddd3d93ac4620d02bea6e6b4d5493e26960c5c +e05435f695997229cce314e50065f3c5f71981988dddccaae6efb81f936b22cb48813f506d1edf5ebd69b0be34f278592c5935f0f6db0cca1ef9d62834fbf3c4c03f4da0596cb4d67b7b767e85dde7b7c6fbef7d89babe6f97b876b33594a9e36ab87079861ee556fb03274ad4af527342a4794192b8933f28c6220f954c77de 01dc2b656c207eabc9e0d6272099babca8d149c9c4258b779c2f06de75f76d77505271c0 82ab97cb0383388a2cf64b9ebc7ad44bb72141f8756c7ed0bf492ea0e4b8e74369ee91b08b4c32568be51dafe39b98ba +0f9f36477076c4b5a7d1ceb314a397fb14646695b0803e36e98908c8a978770269f165a1fed8f4b655d4efd6ad283d7f5d51b6e1e302d360e8ebf4e887c7523a757ffd55384e114bbfc6b7a0ec8511079507b919065ca018573418f9e394854c5704227772161707b4d0246ebceb91192f0eb2ea994ce61fd98a6d14cc8246c5 00081772348ff2d7a3fd57fe703555ab2e14f5d203c4cf0292f944e827e884d95f3b1d83 950940d281fc23a500d8432d975cf8d3e567cca3500478566cd8a9f172d8393723725f84d1287ce04564d36c22fa334f +1d38b1c342b6611dbaf412a66c1c0b8397692755f576df33b31c2bd12b7f0707cc423376391f7b00aa4e7b7fe54532e2b39c3c5284b9c8ccce48eaf9308ed338992f1d4ecde6cbe352e46339d7d602942158387881d9b493fd40cc59d4f9b53ee4191d42352c6f7bf32c331f0c5afbd44a92901a4b713c7cf6ccddf7de4cc6e4 01eb6bf2ca1b5ffe6f6a795733eaeed12de6e87c53571e702635b9dbd0d96b47df4a005b a334be544bc6863c03263e63a6ea1f3ac24950ea4d8e192a63388c52a9330b34e7173663fa7e22e066841d7d4fac9d15 +3353ad05ef90e9762bcfedd6ef44a1e8ea0392ebef30cffd48ae620f3e567e1cd44882d514e7c6759200d4bcab18afd3038c3d3f8c50f7bba32a04eee5a4b1cfb8c349939e4efe0a46fd047d02ed000d8fa1b98b0af5586f120d9ad174b3aea33905b979ece1eb3660b1e070c8821b32df41904ad68bbd8ed247aabd94066f16 03b2a3e65e5a306bf8e3955b60e856dfa9bf68c1275a678ca056207a0ec67c96eb3f8309 a3c6e836693c04480263634724786c62f7db1109c6d7a9fd83b371e39eaccc0769e8034eca3852c0e8f6b33286b9f055 +e7ec162185fe9a5803c6b03d98041422315ccdac67e48fbd07a1ef3c5661158710abc6791bd0a75d56791b4ac0e7695d53c5989d9fa6a3b037583b2a80d2b154b024f1c36b63548be9afe1d51f2f68b2ba94d4ca1e69a35ac10e15ba72242aac20f7526b12ff9d3cde9a9bfd70d55adf9bd92c66d092d7d08e9764c84bf7f329 01fd4d1af0bb7c79ed5fea7bb45574e46534387bd916649485ef15207352d7302e81dc01 899da5646a02cd86fe44838baa43260890f9d987ba6b0a123ba9a6340dd4476aa6da5deb6a861db7619137e73e0ae347 +87c8f2e3f4fdebce0ca9300fc1ebcaa934f51a12b6b8f2cb6bb6eb77965468663044afeb2a1334cb5a81e74b8427267f8b34b5e9ff0cf157a9f18be2b1942e32ca61dc23ea13c3f9fcfa16df8fe05e067938b6994982676463fb12842d4ec532cb904cf222aa805dd0d86ab9a33a83e294c6d81e8dfa273835e62e9041dc8ff6 020380b1136b5283e9b7f54b7535ebda33b129ceb177bf5d3d07b1daed5edd9fb3862530 96731569ad01efe29eca02854c3c1f57a937242825d961b54ddd5ef61dc81cc2ff6e56471fcb1f8e303f9633c641bd83 +2ac53e8a50c4afe3b38904255b7cbf150c5f79dc15932dc0ac9aa631521f68a0d4b6bc5a04d55c99a36531fd4886a23a8d99f262ecd2a9feea925d7a96ebe9b6979a207b7f9378afbe404fc8e959b0333572a2c911f8743c0ba64eebc7ef12fe5435d2cb0e5091ae518b6e4233489efe3c16c6f21abf4e2c6808b733914e5a7d 019f815b98836948e0a0dc9c30828c31b13e175f1e79f23d084ae1bbe64823f4866214b5 9975b167d4156d2b219c9ca53ed92ff27bcd8768071014a7509c9be50ebbc5b02d1836f913b43f791eb5abc27a908c9b +0b201469cac4c078f587edecdcdb6efd5752cb4a3f43ab540463c4d908c27527aa3592f2f9acad85dd94a3c056bd28618317ebdf2e7dd6c5ad26fa3c31dd8e5c50c60418d91c93bcbb59ec1adb1db791f485ded78a5cdcddd23dd1cfa4f13443468d8a5f2d648059b9c4470d0f4fe7733d56a28a2c24456b6923703ef32cf0b8 001854e954654e726cf4bebc0e5a840e8809fd716059211c6ffeaed36829808363164684 a19b85b77e012dd346750e9ff6b6a9dfdb1f0805e09b4dd73987d057e74091629ab3c604cbbfc086d2cfc6d47b593d52 +fc5e4dddf4c4a328b685035ee79069770fbebcc56c14e31afb4bbcdd5220e025f31eba794fd6c05e64f19678dab33ce4f084bc32790392f14bf35669d75b6466b4214ec30d58ca90ae285c9058f5804a1fc9d7a995958f2a0e84ee52e8a78b601bec04ab607ffc2091749cc548c6754ed14e2e5f92315bdacaa7a12823ef76bf 03548f8020819588b3202f4c1ac62eaec6a47c2a19b2900c5a3cf5b4ba5804231141c647 ae1efea9e9334e3f948ed6631794b2915e58a49735b077565956abe325c2651cca25954383684bd4786a260d4aed365b +284cad790e6207e451a6a469cee3befc3ec43e047cf91b9dff1485718aa29de36a43f7c51eacd8589f0c3a96ec18e8ccfa92941b50b2132e3612d5b45e16f60d411d1c53e373e1ba451352e28970ada9dcb9802102518a385dc571dcf6900971b00346098a58042e0d1d129bd6801fa640a895a458a45b31318fe63ebb30c6e3 03cc4505005c41142308f1489226b7b542e2e7f24f1d3089ff6b92a4b0013f490ad52e60 a5e5c0a404c83432f2ef32ebaa97c5294516ca8c0248a001ad22ebecda281d3fcc1fef8ab89b35e0c615d29e8a7cf802 +6d46e57abea9d115deda48b69fe8e0b36144df2f6a659509ce1b514c8cc4769d46e5f71df2a084f1db4a22fdd3ef0c2f90394f2898ce291b9f279c0664aa01419f5f6bee1fc1299871b27ecd57a5ac548f99d01871b8c238a6b46044c953b2e78e22346a0c7663af4db62799038ffb5c21ee512e26d01e70a4ed967377ab8405 0144a2fc8e0aa63506e14e4307df36416f963dd9da78655832f5b991af8c3eb97df78efc b129834a878a6ae8c8f9dff582d8cfe443c63d60e66fbf6eb766583e05918a028d12476fdd7c212b98bc4ccd7e4fc622 +dd750b39bd8753f4e473c4484e2b36ce2da7576813ebe05861c339ffae1d029bc793173ed394091c00685ad82f0550cb21ed1c68f0c27cb7396922239cfb886647af204e88a9101b7453a8ab662e270b87a8a13f2fe61d695597382cabeb781933bebfd7d0dcd33f77266e43e32d937f2dc89f67525e522977ce73e9ad36c8e1 024ffeaf139043ff25a395e4c560c7680c1c2155191378917eb25194136b4a69597dc277 9841943e72d874430b6869656f1021d4666d57d3ead1c731bd70524e335b5f22c1722335caee6aed43df1490660efa3e +4736e59fe5812f63737eed57a570182c065538abd9fb0a1c9c2059199e7052ba57d84b5fa1cda2ad9f216610361ce1dfb9334816b6bea509283756a03aaae2e5b0597f492d078b6b015a40c9785dcc5d2ae266176980db04f5cffef40e16661a50ef871c5f531d73fd5d114fa19bae9dd2da4267a131fc31849da38c2b78d1af 01d1f2e0f044a416e1087d645f60c53cb67be2efe7944b29ac832142f13d39b08ac52931 a0ab243770410be9118998289e62f26b5b3d6e72cb642be58a342f813b148e90088d5fb7d95861e8a57f48af19407bbd +e573fa7d4bf5a5601e320130de91f4ad87eb7ca6b8998488afcef69c215b0cccd221b8b66eb0af9d699af9ad6c4b4a580e82941f31e4c0a9bd83995dd076c5ac9bebb34481061e7cb1b26f6e8c6b26ee4bdf9887f7ae2eb9fad3115a21dcc96acce85d23a040c0ebbe0a56e75714dbfa803d6e279b2f4280bcb993f96ba321e1 01337362609df74d25f7adee382225e6a04dd6ee4c6b45fa31499ce9edb0ec046325caf9 a2c41a31c3308ff845fc9448b1de002b43dabfe3b49fa290220a0bc93d3a92d424a86ca69c8c4d14cda883b8820801db +7862864d0d78b44e2a28af44a0a16d8e9b1b8c4b794db0410c0a863ba011018ef43e1e11f2fcda2f56fdb2a69cc817df425c9cb3b458922ba00d710190cae16d61af3c304a42fbb3d0c4a74a297253fccd70aca414865b41f68b01c561be281265fa89f63f975d3101334886e85929a5a47fa8dc459b663548faf8ed7484958d 01be00aa0afdfe92e24a2536594d4b41701ad4dfb223aab35ff49310bdba7566057fe8ac 821ccbed53448940b14f48b5bed5f7e08087b799b61b786076a180860f1d41cb3367332605674acd99d720b6aa002543 +e73c96d1a84cf7cc96065b3c6a45db9531cd86a397e434072a38d5eeb9a90f62bf5d20bae22b926cfe967647d2bbb5dd1f59d6d58183f2cf8d06f4ac002ead026409ca6a1f868b406c84ff8887d737f65f9664f94801b2cd1f11aec336c0dbd4ec236d1cc4fc257489dc9709dfa64eae3653ac66ab32344936c03eeb06d5852d 012ad0aa248db4fbc649f503e93f86104cb705d88c58e01d3ae0099590a69aa006aa7efb a6c78d51bfd2922ff0fd4e1d8b0ef7d1b495ff085db71678843e4799fc64b911828d87129ba0a1c75db9f70a79b3b2ea +a73fb0aaec838d011110d49c5e94395ce07408917bacf7689d2cfe0948c582214b263c6b80e0a55f1e159086817605723740569eeaa1bae96b979679165c5c35ef2142525e943e595e6b4b160acd7ebe41de19775346363f779b1f80b6d5f0785b92a648028e456af8496102d19dc6526247a654bdae3368f075fa9ee92b2f4a 02cfbb8f340cae8e2e2322829148981cd9e509b0c65497fd8d9da5dee9dcfd39b0f7556c 8f3fb5eb5398ef5e63acacdb1f8ad3a3b765da319e0e6c7eebc1464ad737c423bff5194947109a84d017eb0b3b3fb914 +eda775984c7c9f7db47af30dab314d070fb77e9b623baa6b73e2cbda800f167b20fdc2e7219391efacf908f4ceed9b9b6bd3541b52ea087177e18c97391214758cf6455311fad336ab56cfdce57a18add8cf85b0a0bd6fa7297dbaa34bfc8585b0f06a0aae055186658c227e19cddb65de88d260f09f805c2e8854dcc524189d 0070e82a1f3fa6158d15b7346dd56150faee5c98c9d07c996e01a06dc9b211b12ff62d60 903093609ea3c67021ec9c013cb8c8476f5398b3021d8b8ad8bfd04f5b87fe978204536369bc1c6e2c40d8c56bf9ffa8 +a4a13e0bfa761b9bf37fade6570d41c161e20558874911ff3bee38e5649849b159beccf321c6bc7243f99c01a2fadbab9e157e9952ca65d8ea676c74fdc976d00501c626b8465c6cf0e4fd1a7d1260aea987161b821528b0b423e62ecc5193a0a49442b0c3e4ec9c4786a3a86b199c07dd3a17033d430d2c83c100f54e0a7c31 00b471bbc5f7a07996e370da4a09e71e2119ab3a562a273f079401951fbe4df39a4493da 9533ea32fde3a721ac730513e89c7b8f3b0fdc9c1736e2e20cbc44c4890431d74cbd3f3b7491cdb2126fa195e37089c4 +7ceda7a7248640f7055309ae712c19d741375d6a7e0608e07f0135bb830dc3e8863ee9e7a75331a5e1bd38c42cdd484d4f45a26c2c1d4e05ce0d0ca941f4e94ecc6b371102f31633629e9861de558bcb6407d66eb91f1062ac0e0409db68b9f2855296a7f42fc92359a7dae16c73fd2dddea52bd866a4d501aedd8fe3b3ea733 03c65cf80bfb507dff52f9bf2f93df0642020d41619b3990009409e7210fd7130ac44ffe b6e426355062ca4024f7495434feb5249c3f20201576c1bb2f96e102d83bdac2d3e336a2b2996bf36195890682c06f37 +609815edfd58c0e26a4b06dded831d2f33466a130754b96d8d7c3b4d99fd4b0789ec719bc25338d0ae8c5880560c02687d352d77c291e406eae865c3b26d00f2e63dc644ce7e01d6e96ceeac8bc1eeb257d36cbb25d89b5fff6e30b6051506a0ae54cfaf6214f30985d54cab78f708029c1fc0175bc58e888db89dea8d300abc 00f4d33a9c7e6744ab3c441828bf0f1866ae1c042cc54abc754e3801263a96cbb3955dfc b5d60c5ea663e86404020f0617130b4fe1c17b58294fad23b0751c44886a9738a39640f44275ca3538ae19a9b45143cb +82d8ebba707b72655497320200ce719520c1ae7f46f38122958fd99322c25c9f4d4344bcb77a6658df0eece5df163412ecdca58475d56b0c2d14a0361e4cef458df146925d473a43692b15e9bbec550f1bde3444f2a5b2ecb55d2abd273ae999f16a32333529d94455e485ca4585e6b07bedbfc2bd1eb766abf0d28bdb1ae6ec 03a4824bdcea6a144d85f1b194431724cc49849b6cb949b4766d641ae95477d1ec3d1464 a15333498946f161e8052b5657469a0333458b688aeb908ccac1fd9848f84e47f7696080a72915110dd08e0d7d18e577 +9c6fce18a6a96349b10c9f2f5f1505c8ab727a650b44bc0782a5f39fcb48b45fc7c1b82180d5f229b8abfc807071f931d333d265fc940c93fae7520d8d40ef59d7c6e3678c6a2ecde52b6a8827b1ffc6ed269cb9832feb20e593a7e3d4708309342875199eb2ffceba7ecd707b122516c815e83e27872eda812e3ea52ee3c4a8 027ba543ea785df1d53d4ae4c1bd0a3a994cddf0c25d2b4e8ff17ea7aa00619e858da1a5 a9800592b4abc146701886d86e6b0994dc33757a6d64769deaedf8829e4cfa4ee271f97b3f39540cb4d56916c836bca0 +5eac15a64c7653d125605869012b8f036804817aedacbb5a5248a595ee0c12329f91e8179c187192d3ed0d4ca2e202d8d4d9c93ad3f3ed931121c193af5b47a8a5dc39775b6c2d702708e5134f77a31bd62eaf87e39e6fd3f2b9f782c3057e162dd53b3addf92bf0ab99835c7f6649abd1c5322a1ebb2ba313df9464a74c14d3 00708d0907d14dcd5f40e2903e1e90e48a0ffaa6d4d9b84ca14df4e985c294f74eb9f2d2 95dfee56e4be983e61228592bf4450f3d847c0bb4f1299fd6eabe8d48030cac82920f28730a7ff0109d60b1386e5ff16 +df735a7e60bc267b18f313ad56bff830be5ef119baf43ce27c6368ff1dd89f010afd4f48740b11c12101c5903bfa71d6cb3d6462cf875bbd55a570ffedf3564088dfe8c8d3148231b78b5adaa6c53696737d4704daa59eab8d986fc6e519e81540f201e77b923a6a4af65d7173635b3b19b2023022186a7b8e869e1ed51717ab 021fb0a6b94080da8b8299b87457dc09d21bc430ba5f3359d92aacc1151be9941739567e a210ec516a4908b246d986ca0cafabb54a65d9baddf8bae7f192e4b43b916264859d2348637cc8c2df58c2195e725999 +bb107b0eeaf175a786a61db923bc6d51dad5e922e85e57536118e032167b197b1a1f62d9bbcde04922fde781665c1094181c16ac914cf6fbbfb27bb8346b2134f05c55a8c6b9b481273758e380666d6e22c28577c29446cecc5c3df9ed9f1be060ca55ab2b7fda36a147aeb46df0275bb923e0876b703452fab42f6b7ad2ceb0 02c80151f91301fb6b0c7685bd172f20515b46bf94dbc4160d0720fbaedd40ec00084447 893ab78d1189b22dfa691445c4b64088ded9cc694adbdedeecf09d38fd37ca5a1c99a3b515d983588883dd132d59d29e +f47e49ae30b09b7666600b7a95e81b0afa1553da5e01fd917e4ce1b58dfaddb8dc8c03c0f5591f533610deb6a7bb5faf5dd1ec4103a587a1a4c58a110a706b0f301a5c408b3d984c210d5b4a0b347d2b5447271f25b527b3c7864f7cdfa735dfded47c63b723fa0f0413c57a24ffde9a95c35f743f892ab1ed1df704cde82d9c 01538abd7ce8a6028d01604b1b87db3aaf720e04220edf4d1d28c2d731aa25f509e58f2f 97ea220fa4480cb6444c57707c46ee98ede0ebc17cd0f253f272bc484bb7afc6a41fed81800456887aa9203fb14f7cd7 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B283_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B283_blst new file mode 100644 index 000000000000..832176e74b55 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B283_blst @@ -0,0 +1,60 @@ +067f27bbcecbad85277fa3629da11a24b2f19ba1e65a69d827fad430346c9d102e1b4452d04147c8133acc1e268490cd342a54065a1bd6470aabbad42fbddc54a9a76c68aceba397cb350327c5e6f5a6df0b5b5560f04700d536b384dd4b412e74fd1b8f782611e9426bf8ca77b2448d9a9f415bcfee30dda1ccb49737994f2d 0299ff06e019b5f78a1aec39706b22213abb601bd62b9979bf9bc89fb702e724e3ada994 887949e260661b01f6aa22c02107a9d556b0aaa1bb5aa097d3eecc3be7a1bcfc5e246b8886c2339dfb502d342f996a08 +44adcb7e2462247b44c59608cbe228ada574ecb9f6f38baf30e42b589fb9b157bb0560e5a2aa5523b71cc0d7f583b502bec45d9b8352f29ee1842f42a17a5b16136feaa2efa4a0ae306402940ecd6b71e57d1467c98e7960de2a97f88b43487e4f4016af1292381d70c18c7e6eed99a14cdeb5b3caf73688658e4c5b54c81e08 009c2804f8cab768248fb3fff8a055b3f4585c00de5c1615a19f9425b9432ea09afba8f2 b84e0feb68ca1526b347606e00e1d128a82d3df28a78e719999c5fbc90a1805b319a4d0c5bb8767b7d68f8a8dc042ec6 +cffee6252c7eb6d91d8fe100a1e62f0ad9f862d78ca2b747a6c17b8c9ea8980dc239b3b673310e6e7483582399163e39d889abc1a613fe77849ebc09b4f7f4fe0688b8a9869ae918a88294c7ee199be50ee9460db14725ae70b449d0cb48f30e7d817ec02c0cd586119341dba0b74f0279330807cfccc99c8c340b72c1764a45 02e625a6bc6d0ce7c06231de827068bdb0abc8ffb57c82b35ee3a0f873b9473905974d34 a8f15138beb6f449feece82d196296421f6b1595b0cd7e0b16ae7893be445bb574200fc07754ac64f23f88e6a79b6f85 +d058ab5dc07228253707ef224897ea0fcd09c3d5cc91fdce9e03c1c59c53fb4596be2ed929c7455e67ac7f4891aed3eb06ad88f2c4aaaabff045b959f900d1019d706b60526375851bb891494e99995928e4cd51c9616aa651ec77bd7e398916bb9ed3156391bf7fb1e29181e2b011dae2edaf803607def2ac6b194929a57f45 0376ac24e1b86f8a55c052d92a0bdc6472fa03acdcdbccbf7c321ec0ccd97aa0a66b4181 b81135484ad64639dace4072d88613057089a4e1660581ee9d08476cbc5432e169034ab9e3ea1793fc3717e061a0c41a +c86f2cc7ab5df5cf1a236fd83792769474cef464032800ffe98a44cf29dbfb6f24088160eb31a11a382ff2a49f3e05e983462f5304272f96c0a002b69af3d233aebe867ee63fa46666760a6889d022c18645b491f8d71b6a3b6b4ef058e280cf625198715b64b025bf0449445d3dd7e1f27153926e617bd2c96638345431d1ed 02b50a6395fc02b9ac1841323de4520292f913519bc0d6a471aa28021322fc4dbcd7b802 ae3b24420bd9175a85adaac8ba30c6ed594252dd07a7bee7aff3be170441d4cf05b39bdc5c5ce0c7ca11ba52f1d3eec5 +c1328d8d2e5b6ffc850a9600bd6482518ddd9cee3fc9140febb72bcd444b0cd7e8074587d51b62cce4b3d4f34ad3355353fabe363369cf790db2df9fdac3a0ec4757e2dfb3b683eaa3e26531691ce765742e1c0bdc0e1028d347b6085fc459df0989c6a144271454eaffe413cae2ad7c8b2371fd2df1afffe56df727009765a2 024e5889722f6c35e18ca47effa9e415b1ba790066a91fb3c9f7b001ce28fc732b09bc23 b0cdd7f7042355a0811e0bbb657a6c49d81b9b4a9904a8724f3cee6ca8bc3b723d0cbfea4096b244fd1a3c7fbf5b3bbb +7176b7013ea27e94281977eacb976bb31c753bf80fa09680a29128a6fc15234f79f0e9900aff3217ce9be72c378042c6c34fced0158740073d1a985fa25987fb218002e425868fda5a47de51abfd04de34e2b8634cebfbdc98e80f93d94096193eaa82dc8778fc23f3765c7acdad94fdaa272df0ff0f28190c10a462ee78ac92 0056d15b81f40b6378588a5efe43e21b95e18120d514bfdda0e7759a1d0766a8a35ce5ac ae0a56a23349f5269f374073f8ba280ba58d9d9f9f054f76aa9109b52426888de237c1923e93b4fd0cdc774d3082822c +4c3642ba040a9955b9d50dcd1c936688c17c363854358afa8ca49c6abd906dfdc4d89bb4cab0bbc363fb5b74e1f004d4b09ec9dfeed4c0bfb482a9061a1f487a3d79195ff7b65a0504bced3a28db0ebe8fcf8ab1ee4a3ae91324d15d890ac4c479144dd5538d2e36d3a587769ee9cd2d5c6f85a03362a022fe0efc4a3902b71a 012fb2fb5bf5f7e42a500154823a174ba2d05af71e3b0cf47fab46e673ea1822f1563def b2764f05bb666b26aea205ba5876cf8518603d46b748852528ddf8d857c254d2e8f7df100a934a9c707babb6de5f991e +e471f39c18b081362adc7da47dec254dab8d765f005ac574640d78c14222639245563912d942f3be212ee3cef134407334c8fe3602fa0e1629de5331643d76715dc1b0ffcebd484d86c5211be4b285a31688b205fa988e6c15b36daf396ccdcc209c7dde2a732f5c31c84c7ea041408ebf15e56632583af0131bd7f531b5fc45 030096c54fd480647e017f8cdbbdef292e799f054e3279d228b09816a757566a744a8266 b72271b338b4e94244ca65e1ba61881717c98d07594a42fb55e28f2b0d5a954d81b13504221e05aa5e4f15a5571e13d0 +8a93fe53e83075c4025228540af7e96a588520da34e3eadeb99a4ab2f3dbbb8f85fe63a3b86c1f4ec912e665ca05b43e869985eae3791b91205afb1380e16c25b74e6793fa63e4a55dcf25dc22d03f09deddeb9042b620434111afe08c5657c7d754af66ad91a1b5423301b1e8e6389a1404060d1b6a99fe0f89598482979e42 00a1b7e9c8c2dc25b494b5ef3195b294e41cd3c2c35235ab42542bd3e2a52d5826662bf9 9311cbc38985a9e5986439d97bb3d99dbc260d0fdb29e24b4c655ac8be3745961d1bf3850bd6af44903e9bef662ecd40 +e193a8ef6f454ca1aed38bb67aca6d08280d421b196d89938c0582b7cde74dafd71716f3818940af412d4a7ff3960a8517aee108ae03576b68ee7557d35e6f1ab823d124de7243dd02b542591f62c80d822608572889573e4c9dc62f99d68e07800da6f83cb6f5e03d1f2ac15f90e38b4f25e0a75e354e4b60cc81c0bbe81d39 0059b1a8fb84530bba7a607ee88310e31bc6ea6a6881603567a1081a05a3a9ff87e719ef ab99f7541a9bf5d1ab032525515b750692cf9eee79bbdb82e27a2f8fa6c7470352227b74592a6b4192c9ee0a885bdb51 +8a99b9db191f6cabc88b430bc2293e6774d5180f019d871839289e25aec29379f14606e742190b7aa062e3b29fe0254146d9614856c5140c7315015abb98ac00da2c7e33cbcc82c24b797366f12767322c4381454d9d1eeaedb616b0ea5c66d1422da459f18081f4f966d05ce279c6ee69b1bf94b8388d38d4b770d9ed69025f 030ddc2c7a4ce300cc2b75f0f977033f16c1f8bb13aae3d494c381f9a6dc8622499ae4df a9ce5f6f6625ee6f60539522b52b40c420c2abba8cfee6865f8eb3b80fb49511280e807cad2a7f1460ec14d35dd1bc3c +5c437b331831530aa94623b1736f00b986172699f0a02a5e5df0008bf25341787e2e66046f2c929dfe0058c3cb89fc5bebbe1025bb1edd1ee31522ed568e7b5b4ca3991afdc76a68cbc2c4f81863e27fdaf6a564fab2c6354e5c657de81390f8a4132669fd24a48580c716b5b7961a9c091f614d11cf45dfdaec8946a54a11d8 007899928922fbfdb5407517725edf231d15a8b62d90b7fb6d8c8d20424850dc44f797ed 94091458f3a9139d73bd79e48ca800bb91ea995bafb903d4f40c35335515e3c2cd0709d452294997dac5acc855a029e8 +91aa08567d8da4c90684dc06068f69deae240212842ff1786f04ec41b40d9187aa92c76401f9fcedced62876a34df82ad7c1e63b68bb2a972257ea8542bda6a7f1a020c9b122943b6d651abda8b8d322a8fb762eee376daa2d3637a71ed6c4f5cf96f61c0da2d6e1dda3370d80e51da2cbd8aef3267168c67359523faf910dfb 02a2af63d1171930758bd3e5bfdac62cca1a83a3b55a49b3f80cf0d9ee4b2082757beac0 ae0b3cdc1d8eab9c09311c34c25f6298719b09532edeb353e45f3a84c473cd14c2f41b90653ffa643c54a19b8be9f4d1 +eb5297bf408c1a55e400a20a3c10acbc5c2bc6d6ccfcc0941fb7a6fd4d2834415a6df86c3a6c4b867d1215aeb8222153da8cbbb1576c92c07ca2c36d8f243fd911f9a057e39ee25832454e28d7ed52a8d04169b9b9677a16b32d5d211b8573a8986e9bf36d7206417ad2771daa11bc21fd7ee1029b65ff7c9b2705a6dc9cf9cb 035994e89e13916ad82608f74a639e6aceb756ff913aec440519946d6434af9a60a6af49 8c3b2a51b379cf46dc96400bf9bdb0f461752bc31a2950e1cabea82cfecc5e4d5a1d28a34c2d9cccc26d8fa582fae79c +f415d0adcd533dd8318b94560f86732c262ad2c6dff9dc83e2435543f429a2158cd2fbab0d96c027f71008c4895ecc644c2ceaefa80937f6cc6338d15d36e459a16bd9387a361a6d800acfd834ad5aecf442e30b70f5bfa164747cf9f89325b80976052a83a5e896c00c54f81472b14329cf23bec10a8e693005de2a506ba83d 029639da33f48e4fb0d9efdf50bba550e739f0d2476385cba09d926e789191b6fb0a73ff 99120b956bf1d8956a01184ff2c47ced9b0df6b60f14db239a7d69f93d0484a19d1afafaefee0bbf8dfdab1996f4552c +b178d86c9335b85e02178fc4551769db589ab91d823fac219c7e14e2f029753b203962389476723832f8d9631dd7764e6dd35da290afa42a794476f5c7727b3688aced848dabc9954201578cc7b25801710931f45cba1199d3788d64dc0188412e70723fb25b8ecb6718358150c4037b5b81466dac1686cb5270bb1c72d34bb1 00583a7ecbf2a975a32d07428d27ac82e5dc13d1466c4fdfc1e6a05a8d9a289f1010617d 8baa0682450eee8e8e890fa1110fb16fbd69c42513e94bff5d06e4ca9c7c4cd9b9a2c5b6abb52de78d6f4be7bfe98666 +c8bfe9fa7c848531aa2762d48c153cd091100858aa0d79f994fd0e31b495ec662209a9c8761cd1d40c3d8c4262cf4dc83c4a2549a5cd477726ab6268b4b94a78b1c4a7e700812872d7f41912a723dd9abc305420ea1e1fb1fee41bf643f3a24abd6e8fbf6fde2475e290527724a6f99fd75374bf7cb01b34d3e60d8db33c4de1 00f817ab1b49131fb9bbe8c112c25a36f064efa85de7506fb9cd29d81b326bf276277f7f 868f0bdf5c03fc01fda1f1627f9145bbc0e8842e691572eb1d7dc1651948e1ebc20677912bd410ed332a4d3692b8016a +9a5f563d0f9fd1f31f3a822de628ae970954f4e71292492d727109036491c29e66b9b0f2c90c26abe94c08502f5e923a9ddaf6a7d91e9541ce90d0a49f03ce4e4769753d5b7d922e1ceaac4b4cfa4262732a09550aa076b8ff9d46a50fa17de17e3b6bd606698464d116fcd5f1ae11bf45b0c48d3b738427cb47b0d1272b03cc 02782af76ffebf3e2bfc0576b70e4f4bb87c762e2bb230d278ce776310a14f5b678f29af 939ae9299fe7f358e0dd5bb6e399ea8f9614082650a0adc389f64e21dd486ce4851d3a679cbb35dba5057dbad56610c4 +3d6b065721da9de82cb33ec2c27107eb399b1e69ac8fa51145ed4147e20d72e27434104e76af988a3bc94f55e36677a05182fe2376dbe38195fc6a30673a4dca87336c7304f3f31d49216fbdfea00fd1e105d8b0c13ab11f8892e0045e915c17dfaab07b24ed21b06af5a8cad4f45fbee5a25bb6e87466a7bc422c0bb896440b 031b827b88f14d3822244809096157df3c0aa99da90c00cd9f0b18dfe306f6881834e6b6 85c393c2f94dcbed1acefe9e3eb2122c7ac9b58f51e6a0fb0b03a4648637c4474918b81bff5ee19a2a3a3fb3109f819a +d125f0e2e6135567adec9e77da2afc6862e28d618416632ced829d14ee8b61116da59dfb44098a40a0b927731125617e3d2f32cfbd1546a6e758c1ab6597e75db07add52ecb61d37da2e9ed04df95b36ac249f4cbd794cb561655cbbe4b34834c497b3d392d78ed0db8db683aff0076fb6e43acba3fa2b91210cc6cf3fa594b0 027da4916f1c471cff80bfa14d12aa10270fc3b26caed010c0111f6e5a40d914a3927763 9922e6302afff04b8b61a7c39173404f9f406c633867fc2d87edb4f6694e678d9be179bd3b2c4fbc4a93b956b540c63e +b380f97687ba24d617a42df1b14e5506edc4b62dfec35ed9fd886bb769832cec7f9adae10c21b7cd9152588797b4efc6b2b30a873d3f25e683ea9be070dd69731949a51121e534fabfa3a2eae0ee90a454182248bedf2595cd47ad08614177d58f7a773f5023b538f5f568682c83fb60e3fb1aa859948d01bf7b214e7f2dc719 010608eb51dc0ee97d6e488a23c582ecf0ea1df9a24db77094d87b3fb6ca98507280a934 82327caf3028a1df62da73d9ece3d94af54eaef67be6a40c6603233e796c789e0e119c9f8d576d2074d7e828bfbaca00 +3f9ec57e4228e1a6ec49df02c58d756515305e48763ba1dc67298be9a1548576c28c82b4e9b3f62357d9b3c522b16d5c496a39effbdc8290edd2cadc0019e6b9fae1e61238b13b6265ad2ff413a5a0684babdb0013e7632051455e6fd943815213c555dba96cba8911e006bfddec6c3353065004538f37e48df9e339498d85c6 0123f9eb8babed548df08cc3afc1d3b3bbed52b538d4654f2088fe76062fbea75b85a560 b13eab41c8688c6ac3cae42d1c9e99d61f9ab8fc2cb2bc76cafb40889d9ecc8a32f6f32d1682b3f3ff386f90ba9683e3 +bdbd7b7bf3337bd9d21a3c6db379f95408c17e49dd394e94737ceae889f45dc0ff5d48cadc53703a16b5589939506b548f8dfd34c577c084f372166cbea320c8fd07c809b211e0749ea639e68f890affa1569b66bd763c7c710989e491011371eb1d93ed9479ff0216b7f79c901a2023e2cf80b565d1c0517e73117190cd2f02 006a18e626452111922e02e31d662f4301319946a204ae8a34f06b91dd1b5b96456365e3 80125d7f9fc2c5df1b15ceb3f65ff67e8b5ff060c0bc0a071e2fb2e3a1e066ca24aa7c2bbb7c301dfb299d91e9c3c697 +436b288512ea57bc24f84fdd117da9dc1858bae8c11637f99295d88fa9d05e3c053a2584a6fe200ad190b3077d9a1608f660349dda405066c1562f6897ef69b6b674d6bc11fa470d0b96a7cf8f6e098c9ac03b0ef415aa045867ac7c11d16cee78ecf08850ccabf70f761682b561d0d0e4a889d840dc74932648ca2fb58259f7 03307fd717015b12a2dc76ada21442ac1d97519f66898b214c2ea317ab0f0905e819e4e9 93c50447336be3f0c00629d838e33d19a553d54269cd652ef0a10b0c1e6ff8c7b6938076dfa43a9f96dd3be6412ef87a +672faa156dc188bf16bf8933d65e091c633f294486049ce96a4a403dca28a149f4f840e8bef47412285363e9e89006614b013a41baad9885f1d9980cc897ffbd5f8a7d0e63feaeb42c07776efb307ed680ba1cebf470dd9bd8a2a9efc2b1daa569524394f9a50398add1a5bd2f7c263f9e63c2d49461acf98444fd23341ce78d 014f9f412e3c7d770626e800d43cfcbba3ae6aec8563af748e8a97b67d244334b6e6d2b3 b720c71f1b9ef4da798187479a74e654dad08346633233eae6cfe06bdfb30743a2e28345a05a51e646bd94178f9e3e9e +4321334cc8ee44f1cb392a4b280a95561809dd3639ddf43b6e11cb73067597988d95b8643d86c76c3c6b932d9262b9b8b55a04fba0666dd8b8ff1e8fdf799ae3945b6e30d3af3966f1a6d634d5e012710d66cb447fc3375130968a2e1e647780aada2609d87247c90338dd71c3bcc3902311caba27d5d4ea4d73ccea960d4bfa 03091a6a8bdac1e43542dce752694972e734dca31c061c7d1000754296d0748055db3f09 a175ab417d05be969a5331124eb76c7171d0ab3ca048fa96eda044c18a4d903eef182cc34303975ba57d18a092845e7f +2087e22094570d39fa937f15a3ef0601709a66666344186a33b487d041793fbb9709a95af250b1df0762ea98e911aeb3ff1fa19f0aca53fd4179e454e0e91636e55cc5b17cad9e1575c82ad265dc34c4a66b7a31ecb9ef9dc756f2ac1d9dab35369a6bad4a0f47e629daab91addc6d297d1e5d81477b3966d8c3b607ed194d88 01195921b91353db9bcd00510efffe009c94f6bd8d790f5fb3e5a0101c9ca5d21c6ef2eb a76b9184bf01e1e0d189102ab6a6e34db8857a4cfeeb7c3e40410331ef2c4607fad4d6771909cc3bd29c65ca441aabba +15c7bca449a73b03bbfa783f5a91ca0b7916889a5d99d541e2e8593c3b176a5b634ba20b34407fbd94ae1c1398f5313cab7402f3bcd7ad277a8c66d09a6df5dd086b20a0a3823fbbb80980cd86bd13e527eee15656cc977103e80113539e26695addd9eef6a1f56986168d9a53f8b5de833f8962c3826cca106ae9e8c00208d2 029dc20446e9abacb43823e12a83737b46e6e577466b5a3925e0f9d496824dadb4d4b50c aedc86b5dde4d898c06070bc0cad647b3619ddaecd4298c7eb3ecd32fb82f3ab2db023fecf41013060753da855f48103 +d12fbb82ee7a57eaf76b63fd6bc6c0a65c85f135f019d43ff7bc295cad15d53729d904fed63d69d3ffe8b82c0ebaf0399e2717ece40e011f710b5db46aa457c23b85545953398b814816a1e7a8ab5b0b14c4a0451b0bda9d0d2ec4a374bcaae208b7fe8056bfa17d6b7ffd4ba2e9179f49b9cd781b0c06f6ce3eec26cd428cb6 03b9b77d19a42e9a555da8ab70aa5638890b2ed21daefa28ca6323fc658662dabcbfaf52 b1a3965bbd85bb02c6a4b86c0f5de50e622a1ab57d0c96f1b4481289f63753e734f9927202aed3bd1e4ee08e8bf7a04f +eab0a37915c6b43b0d1e3ef92e6317b3afc8b8301b22f6059da8271fc5fe0e419ca6097daba213915855631af64e10d8382d70599d903d1535e25cbf74da3a12ba2f13c33a8562e0db03edce791f1d39af8850fd1feff0eb25f9ad0a86dfab627b96e65831bffc5f6d9693d20493bc9dd6eb3e9325dea50b055768e8aa30d49c 00b9f8f3e89e9c1ef835390612bfe26d714e878c1c864f0a50190e5d2281081c5083923b 86779f1a1e861ca9562901efadaa7704f1963fd154889f1e03a9341fbd582554779024fdd343a40515cb308fdacd715a +fdb93afd5dd1e3eaf72c7ea9a6cddb07fc2054499ffe152cb2870163eee71ace5bd420b898cb4fa80ea53fbbaece2a1eef6427b632320e9c97e38acb16b62fdbf6585b54fabf0a703307ca50f86387bed1815a05b0c8991e0743d10cdf49c8facfd7ddeb8d4a7b706b5a29e1d00ac88b0ee88b3153185495ac8388cc70104154 03a30a1c15b9ed71e102341f97c223a9b5ea3e6a335861c3cf407ef691a18cc639dbe74c 8dcfb81bbf46be38f184960f4e81d44cee43ec91dd320c88d78e5fe0ed8b26ed39ccd7c217b5c1489d8e0d5a80552ce7 +c78e35d1a5b1bbb0ec21e7ba7b7c74c859d88f3e100e40ae34128cf093885dae4e87cd09f3239dd8e79e25305220880dd352a650225d9bd193b9b84e488c458b0b5fde1af941c0c9fdf952d2fa41f665918dccae27ab7923da4710f8c27ac8ed424992568dd6f0a6c3ecead21650ed162e0292104eef3c2d8551be866a88d279 0083330123cc64c11888c1fd388629d0b329a50ef31a476b909a182c930ff02d0c389b93 9699bcf1a8ef5873b3f3e088445f3016c22eba498d6231b14e76b94d0f4fcdaa2cc2d8a0e7b875ff0370c16ea30a7219 +e05435f695997229cce314e50065f3c5f71981988dddccaae6efb81f936b22cb48813f506d1edf5ebd69b0be34f278592c5935f0f6db0cca1ef9d62834fbf3c4c03f4da0596cb4d67b7b767e85dde7b7c6fbef7d89babe6f97b876b33594a9e36ab87079861ee556fb03274ad4af527342a4794192b8933f28c6220f954c77de 01dc2b656c207eabc9e0d6272099babca8d149c9c4258b779c2f06de75f76d77505271c0 9197d399ba8d20654f01dae6ed66f6f4420d285aad11365da9f5497dd8aa4d0026ebd994a37663f7029d278f0e5945d2 +0f9f36477076c4b5a7d1ceb314a397fb14646695b0803e36e98908c8a978770269f165a1fed8f4b655d4efd6ad283d7f5d51b6e1e302d360e8ebf4e887c7523a757ffd55384e114bbfc6b7a0ec8511079507b919065ca018573418f9e394854c5704227772161707b4d0246ebceb91192f0eb2ea994ce61fd98a6d14cc8246c5 00081772348ff2d7a3fd57fe703555ab2e14f5d203c4cf0292f944e827e884d95f3b1d83 828039006960f512db4919f340c3e2bc7a119b4fcd9cebffc7ed8bc37bea2326eb7f631959249f66cd133b71433e0b11 +1d38b1c342b6611dbaf412a66c1c0b8397692755f576df33b31c2bd12b7f0707cc423376391f7b00aa4e7b7fe54532e2b39c3c5284b9c8ccce48eaf9308ed338992f1d4ecde6cbe352e46339d7d602942158387881d9b493fd40cc59d4f9b53ee4191d42352c6f7bf32c331f0c5afbd44a92901a4b713c7cf6ccddf7de4cc6e4 01eb6bf2ca1b5ffe6f6a795733eaeed12de6e87c53571e702635b9dbd0d96b47df4a005b a10014295a9341e4697d7a5fa169acac112a28d66b62101c6b2fe973ffaf60ccded9be1145c46907ff25cd48b4b2f275 +3353ad05ef90e9762bcfedd6ef44a1e8ea0392ebef30cffd48ae620f3e567e1cd44882d514e7c6759200d4bcab18afd3038c3d3f8c50f7bba32a04eee5a4b1cfb8c349939e4efe0a46fd047d02ed000d8fa1b98b0af5586f120d9ad174b3aea33905b979ece1eb3660b1e070c8821b32df41904ad68bbd8ed247aabd94066f16 03b2a3e65e5a306bf8e3955b60e856dfa9bf68c1275a678ca056207a0ec67c96eb3f8309 ada74a202a8672411f43adb2d7276ad1ca5e2d00ef9acc586fad73e5ba2a6795086d6165e230aa14d1b775b62e34a7c6 +e7ec162185fe9a5803c6b03d98041422315ccdac67e48fbd07a1ef3c5661158710abc6791bd0a75d56791b4ac0e7695d53c5989d9fa6a3b037583b2a80d2b154b024f1c36b63548be9afe1d51f2f68b2ba94d4ca1e69a35ac10e15ba72242aac20f7526b12ff9d3cde9a9bfd70d55adf9bd92c66d092d7d08e9764c84bf7f329 01fd4d1af0bb7c79ed5fea7bb45574e46534387bd916649485ef15207352d7302e81dc01 ae2935bd254c16fa2b8d5d3ad11848298f4a4f04d9d49d699969ed547666e4af0cc9f08b9e258352b4a5d3ae71daf36a +87c8f2e3f4fdebce0ca9300fc1ebcaa934f51a12b6b8f2cb6bb6eb77965468663044afeb2a1334cb5a81e74b8427267f8b34b5e9ff0cf157a9f18be2b1942e32ca61dc23ea13c3f9fcfa16df8fe05e067938b6994982676463fb12842d4ec532cb904cf222aa805dd0d86ab9a33a83e294c6d81e8dfa273835e62e9041dc8ff6 020380b1136b5283e9b7f54b7535ebda33b129ceb177bf5d3d07b1daed5edd9fb3862530 b0b5139cfc4fdb2929d858eb27e9785533ee2274f7da1cdf893f2c7ad5f400c7fbef3158d122fbcbbff333e1ae7901fa +2ac53e8a50c4afe3b38904255b7cbf150c5f79dc15932dc0ac9aa631521f68a0d4b6bc5a04d55c99a36531fd4886a23a8d99f262ecd2a9feea925d7a96ebe9b6979a207b7f9378afbe404fc8e959b0333572a2c911f8743c0ba64eebc7ef12fe5435d2cb0e5091ae518b6e4233489efe3c16c6f21abf4e2c6808b733914e5a7d 019f815b98836948e0a0dc9c30828c31b13e175f1e79f23d084ae1bbe64823f4866214b5 ae817d424248f36e4aa7d34a0f95c52039e5e2ee474d3b2512a998a5f4e070e8585f537907b620b966b583b8bcabd36c +0b201469cac4c078f587edecdcdb6efd5752cb4a3f43ab540463c4d908c27527aa3592f2f9acad85dd94a3c056bd28618317ebdf2e7dd6c5ad26fa3c31dd8e5c50c60418d91c93bcbb59ec1adb1db791f485ded78a5cdcddd23dd1cfa4f13443468d8a5f2d648059b9c4470d0f4fe7733d56a28a2c24456b6923703ef32cf0b8 001854e954654e726cf4bebc0e5a840e8809fd716059211c6ffeaed36829808363164684 a0560d89bf27dd540bedbfcef28367629c6a626ac766746ade6e8c12c0a12cd534d3461aa9b583c179c77d159b78b7c9 +fc5e4dddf4c4a328b685035ee79069770fbebcc56c14e31afb4bbcdd5220e025f31eba794fd6c05e64f19678dab33ce4f084bc32790392f14bf35669d75b6466b4214ec30d58ca90ae285c9058f5804a1fc9d7a995958f2a0e84ee52e8a78b601bec04ab607ffc2091749cc548c6754ed14e2e5f92315bdacaa7a12823ef76bf 03548f8020819588b3202f4c1ac62eaec6a47c2a19b2900c5a3cf5b4ba5804231141c647 b31770284a5a61fb5d43998bc5f2821157da77d7b31bab25166d49e3954331fc78d714547835fda3cb39ce18110d5a50 +284cad790e6207e451a6a469cee3befc3ec43e047cf91b9dff1485718aa29de36a43f7c51eacd8589f0c3a96ec18e8ccfa92941b50b2132e3612d5b45e16f60d411d1c53e373e1ba451352e28970ada9dcb9802102518a385dc571dcf6900971b00346098a58042e0d1d129bd6801fa640a895a458a45b31318fe63ebb30c6e3 03cc4505005c41142308f1489226b7b542e2e7f24f1d3089ff6b92a4b0013f490ad52e60 aac199e47b821e81b285ab3a64e1c6b3f89de0cd7b621528ee07d3bcae012f16cea50eaeb89dbedc5910f2cac99a045f +6d46e57abea9d115deda48b69fe8e0b36144df2f6a659509ce1b514c8cc4769d46e5f71df2a084f1db4a22fdd3ef0c2f90394f2898ce291b9f279c0664aa01419f5f6bee1fc1299871b27ecd57a5ac548f99d01871b8c238a6b46044c953b2e78e22346a0c7663af4db62799038ffb5c21ee512e26d01e70a4ed967377ab8405 0144a2fc8e0aa63506e14e4307df36416f963dd9da78655832f5b991af8c3eb97df78efc 95229bfc0e0cd80da1192d464c05cc5abbe58e7f1f24573fb4ac573308b025cf0d05138f98cbf9621252eb89bcfce96d +dd750b39bd8753f4e473c4484e2b36ce2da7576813ebe05861c339ffae1d029bc793173ed394091c00685ad82f0550cb21ed1c68f0c27cb7396922239cfb886647af204e88a9101b7453a8ab662e270b87a8a13f2fe61d695597382cabeb781933bebfd7d0dcd33f77266e43e32d937f2dc89f67525e522977ce73e9ad36c8e1 024ffeaf139043ff25a395e4c560c7680c1c2155191378917eb25194136b4a69597dc277 b4b5e23eed04ef07fd616be1f90d2e99221395b0abe4b885cf44fa427731e787f82b02c3607e8677d7aa78846da6e2d7 +4736e59fe5812f63737eed57a570182c065538abd9fb0a1c9c2059199e7052ba57d84b5fa1cda2ad9f216610361ce1dfb9334816b6bea509283756a03aaae2e5b0597f492d078b6b015a40c9785dcc5d2ae266176980db04f5cffef40e16661a50ef871c5f531d73fd5d114fa19bae9dd2da4267a131fc31849da38c2b78d1af 01d1f2e0f044a416e1087d645f60c53cb67be2efe7944b29ac832142f13d39b08ac52931 a6a2bc29e57019fea932cf609453a42fa4d851949abf7b045e50338b61c01e71b91f5f1535abfbdccd45d6c026562585 +e573fa7d4bf5a5601e320130de91f4ad87eb7ca6b8998488afcef69c215b0cccd221b8b66eb0af9d699af9ad6c4b4a580e82941f31e4c0a9bd83995dd076c5ac9bebb34481061e7cb1b26f6e8c6b26ee4bdf9887f7ae2eb9fad3115a21dcc96acce85d23a040c0ebbe0a56e75714dbfa803d6e279b2f4280bcb993f96ba321e1 01337362609df74d25f7adee382225e6a04dd6ee4c6b45fa31499ce9edb0ec046325caf9 999b8c5b312df8658d84c276179ca5ad8aad01d5118a42b054ab15388604d6e84becbfc8e0656834c43d48a8667bd494 +7862864d0d78b44e2a28af44a0a16d8e9b1b8c4b794db0410c0a863ba011018ef43e1e11f2fcda2f56fdb2a69cc817df425c9cb3b458922ba00d710190cae16d61af3c304a42fbb3d0c4a74a297253fccd70aca414865b41f68b01c561be281265fa89f63f975d3101334886e85929a5a47fa8dc459b663548faf8ed7484958d 01be00aa0afdfe92e24a2536594d4b41701ad4dfb223aab35ff49310bdba7566057fe8ac 86e78bf3ead11dc21843288b09ae24b7d8085d4e673e8198b90ee5a78ad2743827d58d87a654e1437b4e10423563f2b9 +e73c96d1a84cf7cc96065b3c6a45db9531cd86a397e434072a38d5eeb9a90f62bf5d20bae22b926cfe967647d2bbb5dd1f59d6d58183f2cf8d06f4ac002ead026409ca6a1f868b406c84ff8887d737f65f9664f94801b2cd1f11aec336c0dbd4ec236d1cc4fc257489dc9709dfa64eae3653ac66ab32344936c03eeb06d5852d 012ad0aa248db4fbc649f503e93f86104cb705d88c58e01d3ae0099590a69aa006aa7efb 8774918225303bd6f6082fdd6c1447e4e85496b2510bd2367253bf03d6a925fc501d9bd2ace94375550c61917116532a +a73fb0aaec838d011110d49c5e94395ce07408917bacf7689d2cfe0948c582214b263c6b80e0a55f1e159086817605723740569eeaa1bae96b979679165c5c35ef2142525e943e595e6b4b160acd7ebe41de19775346363f779b1f80b6d5f0785b92a648028e456af8496102d19dc6526247a654bdae3368f075fa9ee92b2f4a 02cfbb8f340cae8e2e2322829148981cd9e509b0c65497fd8d9da5dee9dcfd39b0f7556c 82bed2fa8e063c3c7b1a7074fe132cfb2b685b71614f44e2f347c104df2febcd78c28368701a5690bc384c3f963e4b75 +eda775984c7c9f7db47af30dab314d070fb77e9b623baa6b73e2cbda800f167b20fdc2e7219391efacf908f4ceed9b9b6bd3541b52ea087177e18c97391214758cf6455311fad336ab56cfdce57a18add8cf85b0a0bd6fa7297dbaa34bfc8585b0f06a0aae055186658c227e19cddb65de88d260f09f805c2e8854dcc524189d 0070e82a1f3fa6158d15b7346dd56150faee5c98c9d07c996e01a06dc9b211b12ff62d60 b31eff1d0241ae608bb3e118899c3b0f704ee16a91c9c3607f5cee00acc9f7af807b60acb3e45ea6c26366bdfd43c318 +a4a13e0bfa761b9bf37fade6570d41c161e20558874911ff3bee38e5649849b159beccf321c6bc7243f99c01a2fadbab9e157e9952ca65d8ea676c74fdc976d00501c626b8465c6cf0e4fd1a7d1260aea987161b821528b0b423e62ecc5193a0a49442b0c3e4ec9c4786a3a86b199c07dd3a17033d430d2c83c100f54e0a7c31 00b471bbc5f7a07996e370da4a09e71e2119ab3a562a273f079401951fbe4df39a4493da b1275a4c8ccf9ee298f77f3cb0e173692be50567bfdb408a2209e9d876215323268a99056ed251e848ee74b05708fc0b +7ceda7a7248640f7055309ae712c19d741375d6a7e0608e07f0135bb830dc3e8863ee9e7a75331a5e1bd38c42cdd484d4f45a26c2c1d4e05ce0d0ca941f4e94ecc6b371102f31633629e9861de558bcb6407d66eb91f1062ac0e0409db68b9f2855296a7f42fc92359a7dae16c73fd2dddea52bd866a4d501aedd8fe3b3ea733 03c65cf80bfb507dff52f9bf2f93df0642020d41619b3990009409e7210fd7130ac44ffe a5c46079223575e0d1ff72e3d4b78777ff1a372166df567b474de6f46d29a6a369146f9a18ed673ad8575f96d8efcfd0 +609815edfd58c0e26a4b06dded831d2f33466a130754b96d8d7c3b4d99fd4b0789ec719bc25338d0ae8c5880560c02687d352d77c291e406eae865c3b26d00f2e63dc644ce7e01d6e96ceeac8bc1eeb257d36cbb25d89b5fff6e30b6051506a0ae54cfaf6214f30985d54cab78f708029c1fc0175bc58e888db89dea8d300abc 00f4d33a9c7e6744ab3c441828bf0f1866ae1c042cc54abc754e3801263a96cbb3955dfc 9738b74c350ec0368c64ce9741457dc2e2402a89f47e79b9e6c5e0750f4946fa7e98cce13dacf8bf99be9e96f1649987 +82d8ebba707b72655497320200ce719520c1ae7f46f38122958fd99322c25c9f4d4344bcb77a6658df0eece5df163412ecdca58475d56b0c2d14a0361e4cef458df146925d473a43692b15e9bbec550f1bde3444f2a5b2ecb55d2abd273ae999f16a32333529d94455e485ca4585e6b07bedbfc2bd1eb766abf0d28bdb1ae6ec 03a4824bdcea6a144d85f1b194431724cc49849b6cb949b4766d641ae95477d1ec3d1464 82e48b3cf632711a94fb70afa189c9065a804812195794fbf310d7a63192239c2ab783fbee87d96a710518fb4f4d891d +9c6fce18a6a96349b10c9f2f5f1505c8ab727a650b44bc0782a5f39fcb48b45fc7c1b82180d5f229b8abfc807071f931d333d265fc940c93fae7520d8d40ef59d7c6e3678c6a2ecde52b6a8827b1ffc6ed269cb9832feb20e593a7e3d4708309342875199eb2ffceba7ecd707b122516c815e83e27872eda812e3ea52ee3c4a8 027ba543ea785df1d53d4ae4c1bd0a3a994cddf0c25d2b4e8ff17ea7aa00619e858da1a5 aaadf817f7240bca04799d8ca00a0d7f9f83614b02a9be4bad71584355276eb304d9d6741794a000d20524aec888af6e +5eac15a64c7653d125605869012b8f036804817aedacbb5a5248a595ee0c12329f91e8179c187192d3ed0d4ca2e202d8d4d9c93ad3f3ed931121c193af5b47a8a5dc39775b6c2d702708e5134f77a31bd62eaf87e39e6fd3f2b9f782c3057e162dd53b3addf92bf0ab99835c7f6649abd1c5322a1ebb2ba313df9464a74c14d3 00708d0907d14dcd5f40e2903e1e90e48a0ffaa6d4d9b84ca14df4e985c294f74eb9f2d2 b5cda87324d363e23a696d66741d90a45a65187ec16ebb7370e789e4d0fdac11fbdef9fcc5a776a94b346fb17a4169ce +df735a7e60bc267b18f313ad56bff830be5ef119baf43ce27c6368ff1dd89f010afd4f48740b11c12101c5903bfa71d6cb3d6462cf875bbd55a570ffedf3564088dfe8c8d3148231b78b5adaa6c53696737d4704daa59eab8d986fc6e519e81540f201e77b923a6a4af65d7173635b3b19b2023022186a7b8e869e1ed51717ab 021fb0a6b94080da8b8299b87457dc09d21bc430ba5f3359d92aacc1151be9941739567e 974b90551e266113ecf95955b991f4adcf397319688bdb15b8c687e76a600fcc18ba6a2690847b5b419ec6bb3a4216c7 +bb107b0eeaf175a786a61db923bc6d51dad5e922e85e57536118e032167b197b1a1f62d9bbcde04922fde781665c1094181c16ac914cf6fbbfb27bb8346b2134f05c55a8c6b9b481273758e380666d6e22c28577c29446cecc5c3df9ed9f1be060ca55ab2b7fda36a147aeb46df0275bb923e0876b703452fab42f6b7ad2ceb0 02c80151f91301fb6b0c7685bd172f20515b46bf94dbc4160d0720fbaedd40ec00084447 a9141a25b1cc128fe1760601656c6a7b7794c8e710dad5fb1bec9cfafeb37c141faebe4561688363522564f4ae158338 +f47e49ae30b09b7666600b7a95e81b0afa1553da5e01fd917e4ce1b58dfaddb8dc8c03c0f5591f533610deb6a7bb5faf5dd1ec4103a587a1a4c58a110a706b0f301a5c408b3d984c210d5b4a0b347d2b5447271f25b527b3c7864f7cdfa735dfded47c63b723fa0f0413c57a24ffde9a95c35f743f892ab1ed1df704cde82d9c 01538abd7ce8a6028d01604b1b87db3aaf720e04220edf4d1d28c2d731aa25f509e58f2f a00e9f7b6b9c563f38aa190fdd67f5f858b226e52057e4f8085108306d73005935134f36aeff579840a3fed148dde7b1 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B409 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B409 new file mode 100644 index 000000000000..41d09e2effc2 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B409 @@ -0,0 +1,60 @@ +f2380acb0d869d1cf2e25a6bd46ebe49d1c9270624c5507be4299fe773749596d07d10f7c2be1c0b27e86f27b4a6f8dff68cfe5c0b4c58dad1b4ebec7bd00ab195fdd635d9fa8a15acf81816868d737b8922379648ed70022b98c388ede5355e4d50e6bc9ec57737d8843fabda78054e92777c4b90466a5af35dd79e5d7a81ce 00beb0df3b0e05a4b5cf67abef2b1827f5f3ada4a0e6c3f23d698f15a3176cb40e85bf741c9fbc78c9e207fa7302657527fd92fb 99893afc00308ee473e798533d10f7af9f3aace33dde4e6aec1321407ac8c8a0743242907e541f7d2f8678f1a33ed28d +22a97fc0a9694dabc6f274ab52eb592dbbe8beeb646ebe6cef60eff341a13017eef980aba6d24ab3afd976e2f6a84cf652654d4a54a36b2f2f62fab8858f8b0479a48fe9f47f8fd5a4a1f3141a91cbca186507b2bbfef5e4c4d2df525f04ef7c4720fb443ccad540f03a2be468d88c9545d1dad579fd7cbcd103bbebc9e9f961 00504865a30984a9b273d1bc289d734d10e0aa56e93ab14720f1a42a27d8cc932cb8804b963175de6fe57d8eafa8ab7ea0592dfa 91f08b9850a6695b0362f31c7a8966959b3a56a7154578d4d33e3dbf0f1ccb40326c56552ae63d49494dae501522266e +af36c04af0e3fd64bf52dedf52fb788d2d1bd67fe05d98880cc7ad3c20436abf02f637fcec209fbf888903fdec8682717299f8a4386768153b7faeb6581db57fb9aaf4615b4ea8d924198fdd158363a1f40312527d6bd14c13d19985b668c6b88a7548104b1ff057d07082eea421f50062a315bc3866378f2d2d634f03fbc0cf 00cc08a4ea5ebe32027885a8c212870e7c45b6c610117994d6a42a284c05199414a3a0e8e6645ac5c2ebf21c505a601f69c62b85 a9aa8935d497a20b28c777662925ae81a7a5ea0790664c5f00f01f17e62026ee61c11e44565b2ee23594d1781aea3feb +6bd6f52a6204b60f37929aeff28c87ef61ddeecc231e52a7772275f9329add899c130956f8c50ac2698aad3654fdb49b74a6427a62a11eca0a8ee8b719b8c0df7b9f0bb0af5fef4918a8c83367d29fddd04b6a1ecad904471e5b59c8fe3cdb06b4f8f96419518dda960845d83c49a49f1b1f2fd1d2682a9d60c25fe3ce982cf7 007156ef0a74ee1119532a2a7e8c02be1559c3c21897af9d5b34553c3d0feca4a8d5929d1945df824478e0c0b92a6fac8c84f639 afd3fa85813a8ed801fecf76cd66d0e4166311d86a7ef3ff6ea7828a6d940730870954d20a0706e7a6225e87ff302744 +0eb8de25f63abc9cba16823270e9b6f3fdedf0fb90f6652a34688970932e3ae98f6d3bf0fefc5f247f72960a6975bff1f1acc2188a1775fe8974b2bb2b4c8d226ceb735113a14009e8ce66d58808fada4e6f697fd016829913352c0f659b6be354a067df00cf74919580750aa6064f21264d89dcb28b3b2d4d699115c36d1310 00a95c7abffa92e2c637611ccba66ff9d2ab121b40a85c5b71454cb0dca1f098ce1be8d9ea4933d1a91bcd270c5a33687835d6e4 a83c8edeec45bb0b21a01163d73971cbf4a500edbd82e8607887a008b6562f309d33b40476b986e8ad2ca00f0822f14b +cad58ca7a3b9967dc0ab62a43037764f8074ef9177d60bd98f623d693333971c24a575ed03cb61f4dc2e3d6285fb1204502a540f3c0bbbf23f5bbbd1544f322ce35d949d8b1d8edeb82e90927ac67ad49c91007056bf5096bd690d15ac00e1874fe33293d8003a4a2b094078cf09af799dde384143350c54a99e1f99cc31f2d1 002c438b07c6e0685d1f94a4bbafc013f8f21265d893f54e54c3ac2071606ad1ffacace0b8367aad724b1d9508c65ce52282e397 a1762ef5e73fc1b001504a4afcb1a365e452867045b39ef40e076860b64a0b541ddd528bc31e07de269c32eb65cb7d84 +281ce2643799bbfacc7d5993683a4fa656040517854f3c2dc7c4f8848dc305382e34e894d433caf12d8b493020a6a08d1fa05b08bf6c53127ad5f33bbe75b9db0615e3dd94408d028dcf3cb7598f6e7cb4c787681dabac7cba2cc06fccb7506fece6c7c1c1bf622d525ae9737085ab4ac578905950002024f30159cf0d99f50c 009e8658f8f9e6cd98c0f4f0fd20d64d725653aeba339504def17f3ad12a63dc6157d80804e5f43f4ff48fc5573fde2c615ed31b a2c3c21661627143113397e40b51f0154c030de672e760b5068c11825d0d490cb7146cc91181f67c42446fc9d48540c9 +0c061da1a16f2be130ae3b20b89745e840bee09633fb49671db28ec9a051545f57ee07e2410ae7ebc61c9af79868d3047705bfc64ac0c04ef0b286e579b650c7165443631e49e6a53c84cefa5625b1e1035a6ed89b8e839540040151132a937666524265e099272c1849f806db0fdf2be64960d5b5853965099459968e5beb32 00c4c13f65eacce85a51881caa6f82d9e48ec2ac574947d2751823a7f072d38bd9da0cdf30b6f19084a6d291052e7bbc2e1349e1 924c43a0d0c4f8e5bb4aaa69449581bb037b2a098397dd1f2eb2c7fa96f9c8feeabee8f383cddb69b60759a3a786cb6f +74ac2e1303297efc3ed8e624722df505df55b7f33964cc0d270604cc48b58205d8a11952232a8feb0079baa30d7d33660268b56a5a3dd90105f0703abef8f6636a99bc63bd47d9df100351bee32d8205dab0dbd2af36fd173409ff8d1fb7b24570f3c1e968458f58aea5aa2f46731ee91ffd6d3a060af6b3d5020daf1362af3e 00da591461791ae7847e6d8dd8df46a63d3021644abe9520e158406c96540d8fd82ecfb1c3f6f5cfd7688c7656cc3e3dc94e586e abd378393209389ca5cf85753d0e6500584fc124d273e8b5801b27f9491c68fbf43311063cce16cbc7c3d322f2b0843c +2afd17344552ccc577b0118caeb7dd56a0766e25f84df17c0505f9798931374b48df89a48c64e199108c36e00c0bf00a97ccde55787bb97c6765601765ab5417f3e75e35a9fe5e0f85a721d9f08440ed617afcdc200b318940a1e496040a6ad9090476b0fb4fcceee77b3fea11de09e7fb14853d1fff8ab12d66c101257e2d4f 00b5eb943f0dd390b737510e2bb703a67f2dd89dc9f6dca6790bc7a260cb2d0fb8e1a81ad6009ed51010e7686d5b48233c6c1686 8c64d1155a2baef71b81a24cb843ab9757818d0d08872ea2257d70924e7eac5d12ea38785245e44e93989b3f386808fe +174b2b083541f8284645a810801e72631a11bd7bb805f684a7159e055afc44357f2c80df2b7853678d34a04144e0ede2327d03db6df23769ec41194a8d9d86af74d51c5bc11ea878c6a80689af71d3fdaf1c651003385332a512e03dd040c33d9c328ca89ec7ee9026bbacf30a7f3a68e0d894fb9f7100ffbc64bf17679dedd1 009cc63f32152284fca27ab2837bf1343144336a1fdf15b9727c47e877ac69ac9cf4c97b4bf42f1ab10d73de8597a554ed099efa b54ad28f4ac10f859e736759ea99efc29056e1018931bcb80a2f83230378978ef93c6ed9077c0d1c297cfd7751cacfdc +758df71a952cdcffdc417b9fffdfb57582ab5c5473a8bdf0c2101953b023b77824263353dea0e2ede1f800a5757ec6ac0e1e4e3ab5a4cd85567d2d19acc6b7069a6e7368401cba2b6e642373654bec0ddd19fbf032794c15b7ef7e714e13e36875262c01e77766ed53cbcf735936dc9b33eaf2152a396349c82ca0297dbae4a5 009950355e8667bea8bbe3a2c4988436ab5394551b375e27fdc0c1a1d1b07ae957932f428f1aca0a486e54cd0b5bb0a5c5650641 8b4d418dc6aca83947e33f01dd292e1866a09203a736b46eb9145912e5ef5303291d62d3a351e0a2380cee0db33afbb6 +b96d9f66b2000e9408d602096f032b112f0e05ea874229ab9daf6e05bee49b4722e4f2d8bf2eeaab9dad94438c76b7cc64dcbb59cb4e03f9ac70487a1d24d8d6b72d7462fe738a17edf381d52179b3acc0c0177c113eb4d10e8e78041deac1d56abda0ddf892edb8be956d285e7236bc6794168f8a180f622dd5f2b9e690c275 00a995493d6971c2d7e8fac3da9f8c0b5afd877cfb94924cfecc167f9d87002136ab253e3a4f9ddf5c9c99bb1dc1af0c6a3a3c4c ad1dce759ded654fe1889e43d27bb5cf57177d319fda4c39f34b29ddb91e33d26fd483a03cc32e3f5ad242277b8182b8 +e7ae60ac55e6ba62a75d5328bbc15269d4638764169de0bf0df043d15f9152bed909b1fb8c7a8d8e88ac4f552c1092b62db00958a3a827f64896f6de4bbd8fa5258d6c36e3904d82d3eacf6eedba50b0242eb6b01212288448c3a9821c4fa493869c01149ff1850e8115cf9de1618cb8744626b1951d1de305745507c8b21045 0070daf435cdc26ad66c3186267ad12d10f28d32d863f950cbfcf042fe9dfce553750ad098f82f7f1650c1126b3e4451bee6e11f aaceff41951272f713d1369edc642a94755c91eac7e93f3de2cc1c60686e452736597d201f10e1915ab54bce7f8323cf +666b0dc2ddffaa7ffd57ea3b2768f02d4b77c16fa007c6d1918400d195f068cae2dcaa69817e6e4c70d5b29c5598efe2d957bd12d0fafdcf5ac52dee80a2d46e77fc18cce2a49bfd787ff77b942c753974d22434742bdb494590d17c42af725b1309e54566276af3bcfbf5e174d3cf191b85903faafa1583282c97e66c5da6c4 00f8121980dfbe9ad0bf92383c7cab95fb72d5caba96e1de7772c6a179e85414802fbb86d725401451329287305570ec7fdd873a b529733ef4bb4f2e80ac7d9e0a2a9c7ce0e3bc117b9c46fa494cdfa08d30a303b75d0c28ef2bdd01610003d0be9a32a7 +3e967cbc2bd936e0b6125dc5cf885735bdcd2d95b2f764de6931c4578ac8e0e87abdf96375481df67dbe1b6c43537e84ec62bfca6672cc5f3ea4125abd4a4119edffe04e42411d338e8b10abb1f1f818c50a9631a3f89feb5be5367bdcb0a8a82c96a427ba6ce99f9631d4411a2b7f5b14d32cb3901dc9d285e4cf5508940942 0047682b2e3bcb5800a531858e8137692a9b1ee98ea74e929ce4c919c26ae3b3f1d4122d07fd9a70d8315fab727ccb67004187a3 99e7b2c5954444c96d81b3d05f2378deeb431c6d6920d35bf5c629134967c3315ac4abdd6c6d11b0c2bb17da105deca7 +ca1c90012eba4e7c5f01d8cb3814c58f48c03a16be6ed86934014365eee547070b870d1d26a872cfd28b60d9ee0a66dea223e9eaa90ee28076188d6091f26f665684f4b486af70669555db9058d485c677b2a34d4a98aa8d6f43bf6f44aff2a23c5d765e98f0438ab81be0585a5be29daece5d4116f44ce6062753a3ddc505f3 0040cd1a06233ac27f3ddd108de7c6c0982793ee620d71982697713be9fd5143658929924cc88747a680779bb00da8a44e1e7d3f 85871d6954db9b1aa917796f5ae7ea63039a6192ccec8681775637b1506563986b810d66aaf285b545fbe500b1ab6ba3 +a54c4351ebdb075d6a42a787647390f864b2bbfd8bb3d0e0ea9d767200fa344d1a9ff091bddb186acd69bcaecd767068efe4d752d185bfe63f6674279d0e7192d2077c400bbc0d5599ee28507c1253f05eae0687b965a015e1f3a292b4650106765266f5c95b77ad2d82a6a6e012f233169eb6b8d83576901cfd4a927c54d7f4 001ca6f752aae4eb7fc9c73a08d6fbd96bfde5030d759a2507bd45b6e1d1487e53abbe98fad4f41976364e0a1d830910ccf97abc 97b43c5a36af62909657f62aee336214fe1b408ac7ffb13cf2aacac0920ef7fe6eba0f729b26027a24f2546507c72e07 +6723dbddc8720feeb75e2a061b7fc49079f999fbc79ec8a8e01ab8d35b438b7049da5a23c49a58101742791f84f45d5f5cf551cd7de6926a0e2c4ffa1e378f038da597368c62df8cd8349bf046de46d02183dc05b3a3575f5f232dd2970057200e2c9cb60eaa6b4d72f8b73d4d40b98d1cc801d1a69cb5ed780a75a4064623b2 00fb9b1a9597d216028902abf743d25944258b48c9762d4589fe660396130b75f6006cacfde60f6204463cb8c18b032de1dd68d2 a6396e323f3e026d3c411fda1a9a6bbe31aeaccf115269a2d8657d413c473bce38bfb2709fcdb1e6ed0e05cffb17ee96 +ed53cec5e5500d62d38c829002916c657674ede4439c6f405ba672327ec677490e656bdd698f114c2ab5e6a1fc94a1a8d64466cfe9eaabd23a8b5c37f76a3c0decdef73b3e7b751cbf3b0817f4079560b5ea34cead88ba374201236bffc48eaf289bbaa4e828afa7d732473c228ad00588c9b443d65b998f21c3d7a9e9196c08 0032109202d754da290c266f74f47805a06e6b5c3f721a72fc97a3bffeb8887e0c642d49a6bd034847d0a5ba09239c5dfdf0772d ad0396ca8422d92c277fb0cf467a4861a54e1ebf1eb26724e5126b79861d1cf5f29f5eade9d451ed976ed06fe865a48e +13829401bd41e9fe01329e9f5a002f90f1a6ecbf25fc63e7c1345f265ff02e496230f706c6ab377ea52d8707b54f8fc5c7f089044e2bec1dfc66a07da76ee12fb9ea0697d87706b0ebf677600bd2fe117f6cdefb8bd636a1b6b97549ee78f992c24acdf3a946053f06fd012a9c703efb8bd929a66aa74b05d61bff0395232b00 0080536e820fac59b3203aea928475043b2576446619001647e35693a9e65d15236c3cbc12e1bbe0eb305973535c882b70197a92 a97a2ba0f7956d45734bea046d84dff89ec93987fa8630861fa1fdb59cebc8badebce483c6ccb3e59066b23aa0c41e18 +e696acdfcc96a6c088069b7595ea9516a36d8fe04dedeb789fbd965db0cc64b7017a821015f6210b6989e515def5a9605fec0d337e4ac59f3101a505168bf72ab6d98ec62a71d2f94071fc05b95e98d4efc59fedc138e3e49c5d0b44d1f48f7b1e7c1944ee189b242950d2bc804d31c7eeb45283c84638f043ab9533976433a4 00b05e5f0dad9583ea18fb8fc4d8c75fd2e3cf9e92cdd9b737485c953620d345006c31c288b380258b6500b84f729ce6730e5303 ae9e6d357281a1c7042ef84aaa9478582098d94636231219353c702eacc678029770f2b0d7481391009be388de1df14a +4058b9a8cc15ac148909eb97fa32aafbb6077b168dde91a411dbc973df7db056dc57ff78f0abcb70f70f800bd752197d681f44df4a7817c0e7f60f8f65489ecb6167c14b525e91fd2cc5d8b80ba380a83d031d5827c8b1262c687c90ef0e62723d9b565557f9f6fed0db48f3799274c2cd60a14303406c35802cba6261121296 00be1d277813e79051ca1611c783d66003ef759b9e104f32298017fb97667b94dcee1ce807dc6b4d62416e65d4120523bf6a4edc a94498d7cc3fc6137ea48e216d55a883292558d77068682275b4b6fceb309ddaffad1edbd0be6fb97b388995ce8d9df1 +e793237d46e265ab84ba9929b196405faa3b0e4686e8693567e53f68e6991e57677974677682a2510c4c35b1968a90b32c4941af7813775c061c008a60f9f671cf7419c94253d6106b61e65034497f2d273a5058379bd986e3d917f708f0a2bebdba150f6d78a3af9c722a2430ab0f4bad602e91e18aaf258e3785fee78e4502 0073c807bd7e07379782ab790720de4ae5106f16d34e80ed70da5b1594e660c9b775db94066b93e74f855f57d88b6ecc6228aace b968c4e2d850d39d8f598dd1a7af977aba2c9972de17ac53f9045af4497a55f9d0afb55f1c8607eba683d79fa008d691 +ffb8bc80e7619a562d8506eba7658bef0c25ace3dc1d01bdc2ef00933d4fa07b80364e5e5826074edd46a707dbc3b0ab19eec7ea8990839d7fc0a80b70661204c52bcbef57c1a7bdc861c10766033a82dafbead283d911a9502d5f9ef0a39d35ef26f3616212d4bafcd413ffd18b424fe09b48ba02ca5d97ec996205cd49d22e 00a68379b2296a6c944ad5dacb593b302d8ef0b05873ce12bbc371d705f308c739d21f343349524aa72f05341e64f7435daef112 8f07cba336f87425dc767324d46520c534ec75667b1e3f2f94a1bc3341aead9dbe6adca3e5500c27acc8a313b6484051 +946bde90a5b903dd281a51d7fa93d80f3fed07eaf50c18fe9fac5acf67326bb18effa3144e25c151efc006a50a274ec6c6a5d573051c4e2d117ceb0fa125acad07a10fb6534a8e5f5b3da2a1136779c51377bf76c3a4a93c0c6158f729f2293e414fcb952c9509f228c804f0adc1daa327a8991d48ccf4f3957c5f8ccbe3ad4a 0026046bbb269ddb1ec14ade56175482343a21b7c265026cef3c7d6a1ae0f6a68166b9e6c49a6e733ad2ad64df7137ef230038fb a43dbcc73cd2a93994636c28964be1dceb196647689f44545325131332ab73556e2ab25af1d055494e7415a607914073 +07f3fe1369ebfcbcacd66675bd4ab22edbbff72e68709cb57d4f590e49440f01691f490c58b5117bd24aa2fe2101b59c61c417c918ea08ea34bbb9b8aa17491ae5d9329affe894f42d7586017877fae3ce35bb80c97f92a004380374ec91e151995166e14ac00505fd1fa810cf02981bacbcebf5f81b2e633d3a3db6737890f4 00bbcda66978ea526f7bd867c3303b625f11b94dd9ee6e2c2f8688ff07f2bba83c662949d47ad47fa882cb7d203a7f0ef5dbc52a a3fca4f09501664c812d06af5e067429f54ae3cfa3a1923a22e8d1f9ab54a2ee9138d62ded5e1145504ba53cc3e83f34 +3a1cb13438e3bac9ad4ab1d319e90e2c9f118dcf1eb54d6333c674a665d41451f93cd4a9334cd057a44c010edb668254517a63700a31eb0ca474c84873e486f2f8e158a1a7735362ea0cff8ef17d959ffd851b21a91412709b3c729474d2cb40f6ca0e397030eb2611b402916e4b656f0fd868247d80be3ce33d52054b7661f0 009be3dd3442e0330750f0a6252bf9cb317f32f942ae516a4038dea2c40ca6484fb33611bef016cc64baf166c122e87c15466fd8 b3b688fb4018adf925be90bd8cc8858c4daa8af7a684f778194090b3f96e57f691b0cf52680636f3d02814a2cb764ff0 +e58e7b881a563d54772125b2863718690a5276c93d9e1c5feabbdb5d6f7c7293ff0f89805b53663bb417fdd46874b8e6a466e7e3ff6737930a0662af1d5879b071b0dc4d014778dff26a2eca5992e763bf4c4698c382ac947215aa116515876008a56e5bf547857049c38a2d3737ed3393705fd346897c3beb80caab88e5b8cf 00ed321fa283c662e87eaab99b7715e6cdc9b42e14fa5bbe2c56fdfb381369191a42da7e574839f90a85577485f19446fccaf6cd 8239044460972d3bc5ebdf7bc934819fb330765b2ff4bc14c4ee741f3b1bb8738805efe76d2a163d30eb9e07740fc000 +8889ea1da1cbed98963941f6ac24f47253ff6af52de920765214f2024aeb04f7ad46936830a8eb04d95aba64ed7cda6ef242f454b67bc2de38a46b6524bd5c96739c4b580e89829a61a8249ec8dc27a50f43b8554cfb6f4fa4ca6875983d4b60a1c6b49f32ddff6fac0cafb64d55c6f594b195c207a9bd920dcf20e0080920bf 00396b805073f3c3b552b1024dcf35559ac44f255b688871a3c6657f727a4b09f3806cbb75d26a00ae1728be632387e804775a8c 88f42161e916d3bc50adfcc9ee31d9bb34823cdc6af33319d0f8d3ed9ea419c89bb829413197ffcd690733e8dde3aecd +55053af9370901e38622734a5bc5589f6a20e258627f381fb0c366f3dbe58394e5997e978eb7ebbc530f6e6186f48294149b8594fb551c31c50521a8c4d67e5862921695604afb23977b6a69b21abe75966fdd11bfbdb6b51ab0a474c5fa07c4de7872a3bd81acc417655090558dfcd5af449b3347e61fa9e839bb9457de64c1 00a8fe323f6736bcabe971c7d964e75dece70cb54561da48a11c40027ebddb23e41c7b48600f569500fe8ea2abebdf480171dde4 826bd2366d096d9cf7b8e2fb8cf25469bc84e894bf3b619e9444dc099ebbb23e63ca421e2ae74a634badd8d1e1defa5f +c4264330534a6c2bbd8a3b757e0912558302ce302f835ad8c5474993832fd30036fdef40b10ee37293e871db5b0b149654f9e543e22111f9709ef45732125f713c031ccfbc9a2f3aba160c241d27be4dab87ab2fa9a795752ab2daf20f9d06a98d90d01c07133adfe83cb11d5176525e1bba6a9ba70ea48b224d46ddd8103f65 00105938ba9f25034da3e032dee121bdb192ac2128b50a2ed4bca042e96cfaf4660c9d35f3e67bafd4c99f9447e6dc408e0c4471 889656a3370484085b93154103d0a5afd37be4aeedf4ed53db66c91a3ab7014c7fd221ba8485cf1cbda9c8c47e65710f +3236f1ad164e1b25d828f5202e3513c80c72a577aa9af56f041fd96cf5a3363f4b827723b1511a2f16360e32eac90ac55f4ee1146791420ef9e2af333c17d157b00e43992ef6f2be2d2f211361e468413dd93fb69232f0a0d110bc5fff361c0410344aa0636bf809062c73a7ac7c142063912b6ad7e1626fd2a384f35faffaad 00ce11677ca818537dbaeb880fc967dc8bead203a2538a55e756679c4a9e7975b9b3e6aba4e6c6eab4152d0c0939027e9b0bd92a b57476451f90d6e1548f866e411f044506186a39130a966643a067eed395c18ef1b7312ff519a4c57701ceb9684607d5 +6c400ed098d8369dab6fde3553afbbd4d47836d0d12dd16015f15cb8d067a39391c85ca4e78c62b8b72c1592349ff8dc52db8ccb7fd80c085fae456dba6f4a2378e184dd59238c92cf04e40d43a66b342d2a1325a0bab12b1ac857f0564c27b35e6abed02ff5bbbdc3770ddbb2ee0513df48bcba925da6d61583076cd3129603 005a239ae0f40d76d8d3589f1662b5ca12176a4b2784faa8339b54e96a1e1294433a4d83bf904196f939bd8b33bdb4be340ec703 b29e393ea041fa23592c99c5e807d16e5551b8aa7311b339ea7e4e8bf306c4f6cea4be555b30b1e5ce41d44ab1386487 +039a149eaef2de30b0ae457b376ce6fbf88afd4cfdec02d3c5e00400d3b0484c1cd6ba74db5de65d6f2fe39871349b30fdf1ef29bcbb9e182eb3ec5629d07d98354a5dfa82d7f0db3dd10d1510c0dce086848a198893ca5ad24a663494f0596b4eee86199ea85e7e8f2f76e7a6bd4a052c54287f61b391f1e52f96b606151c34 00077390c62ac41aca995640fde0c79c76f4ea8a8dbb22323ed812bee837ab8798c5d0ba976c7aa634d4b1c2c155de2709e7352c b0c664a7abefc902877512ed1d47d874af5a4104b4c181b586bbfcf16ac5a841d7bc4660510d6531ee64725a42f96960 +08617d04fffd6644c40f7dd57919f7dcf3c888f4147535d12ca658302305bb8e220bb17ccdc480254004b9035b357120580882ef86aa5a061b2850100285b7d61588a664dd4f5394f5478e68a80f610c9204d056009c1c9e902161eda33ef61aa902e96b6f094a9f053135692182943d38b9763055a38739a2a2d133c5dbee89 008bf23b09fbbed1b55769907aafb97f4759cec98649b2c9da5157517d4f85bb70157076b5e4aaa7a940af042302f8be06a84ab6 a34e97a43a12a0c8451730407614bfbdd21090c02958bd11a89b5982f74965dea680034f18ad0997cf49b94da81cfce2 +34c959f549a307f21b850ae105f41299b8bc94fc292aefc61aefbe0a1bf57576ba8d9b80caac635e4edeb22530163fa9629665fcd43959f68eee32482f1845a78ed7278e6e43d09ed6fedf465001afc0d61f1d2e1d747623e82a762576b879c7024e34f43104593cdd691d53bccaeb8f212dc29bec6bc94cf69d0a8491db124a 00082ad05d19b8e16f80e53a4cccf6869ab5128c5e622ed146fa8555985ccd2aa3b9957dd374586115d4d75b1c01cf98ecfc3646 99fe143e2a3dbaf238882d991dcdfa8771d9bd2761cae1b177baa39fe9bc683696913e64b3f6102a2ccc252d90c1cc74 +514f4de08a6f49edbb6797c9dad6d33bfa367cc1a1b58a5becfe646c7f3352d5c5d95f7456e7112c4ddc746b9076b9756ae3916c07bbe6d3823895774a42d25d44b3309d18bfe7e3ccb1f85dacfec1654778c19e2981a853c1f40a7eafd16d331093110698c957fe9f1d86582706a6885543248b944bb70cdf9d2ea89190cb02 00af7e581aa4f9be5815f0c447e39de00da9194eee5e5f609668b9b69930b5b48a948614c2250260d1917f0ebcb00ebda4bb52f8 a6ddd6210ad2638f356f13ea9f895479192f9c889a3c30f9d848b01e3ede81c9706c9f585811f983f030f8ca447434ac +4e5d16cb1dcaa1abab1e371e1de02f31ef4e0944dfe1fdec45ab64326435b2af9aaf1a6ed8fdf1a6ab1182bb53a844c7cfd66da30aec0d41757f5988ada0017c4ca752597a9fd3637668bc1a92bb1556553f28d66805bb47f1ef91908ce098d452872da9800e77e1fbd43ffb0ed6fe6a62185d4be73ae96c9241b82cefb2da22 006d14107b08354e6a41d7d7d50c004419db8bdc50db43428df5e86084551237223c498bce71a17e25695bc438c5c09e009c60e2 978686fbfe9897008392154f1012ebc1a0cfe281650594cf39d9dca86380a15f6e5d0fafb39e4df8e9f9091eccb05e40 +e29e75269754ec1194270f5c9e8267dfdd8c696008b5ebc92bb840981fd065672f07f6a0f1b19841adfc51b478371e1a0db9c3346a9f0a4ccbdecb7040191a00ddfd0a8faa0e69fcf544319c0155d02797eeef99fabbc55078f9d852927c23fd931685424249b87ed0c70a4a3e2d3b9a2f92830e7d8f7650c0bffa8f8986b7d5 0099d96d2dc9c79549f031bd5346cf6a8544c312a3fbfc560dc8e378efdfe025b0e6e61e09c04c8bf4133396f993b0906c33dd30 b46cab7692109368d52273fb8dd24f78346fa57b9d9cf6e752d091f8bfd126a8b16e41c3f8a799ba1ea178d216cf636e +1a538eb447c18494ad5a5ad27be67fa60eb2c5cb2404eec1dbd7244cd802b17ca5497e779d5f779b981b165dab53ad19fd7bf2ea7dbb9b4baea782a43d758202f147e59d6b6b8ed54f4ea084bc18519943f6894d603e253ba3e8e339a6933bc3a0a47126087038e1c813c3f2997aae321b7c95a802b4b73fc7db95897b7c91e3 0049f347dfd361a65910e97fcefbf60013a54837f2ae657d65e02397f59dc6bca27704fed3affdc3d833fdc621cc5e5f99b92a63 b8c7f3f957598d26618772126d8fd45139bf65b07ff7a0f5ab7eb879ba6578b84a5b04bbf0f40a45eb6fdb8777291901 +7502c755bbd385079a4001b8cd653287dc3054f3b57de19d0ff8f63c0308c64c56f035117a8971d43654f89b52e923947e4760ac72be073136da70c5ad7ca1658cc0a2d2a880d3a0c0fe636fdb27b77ff260c4c1ef8a18da8e9fd777d732a37ae9906e6c4f381f0a3d941048d5a1f6f2cb8593873fa4bb1621a44bc2bebfbcd1 00dd226de602af4e9f8e25784bd1bbd4cadb0a8aef525d5e2d57b9f3555feb698765672c5099a7d6dd5faaded69d8d68b4804f26 b360ce87cdca7cf1b799ed5536a0d45478e48f8e5cf74a00fd0c6540fafd21eb219832dfcf653d983f75c45c8c82fe48 +95eca932d03f1df2e8bc90a27b9a1846963437cdafc49116ccf52e71e5a434cdb0aad5eccb2b692ca76e94f43a9f11fa2bdf94fe74af5c40e6bfd067a719523eea6b4e65730365ee498ac84c46e1588b9b954f1c218920cbf71b167fc977ee2a89429590f43bf637eecd91b0ce3be2d66bac5847205f76c06b914a970f543e59 00b6fdbc9c8c76cb2b822a940d8675889ca6f5132429da795462381ce29313a23bc132976fbeb346ed4c691e651028f873ce7971 8cd220ca6b13c9cff07f206a8f6589ee09d7cb29b1bbbcb686226ba327b0dfe2fd9d3d73c0f4dced6ae22ad45225efd0 +8ff68cb00d03e730dddb05fe0b2344689529096c3da6eeecaf097f22c7fa340593106b1f6726f06b7ce7358edbcf801ead959438a42f94cdb467b3cd5b17fbbcf75739805f9eadc869c33c604cc58f81591b0b8bf4d42bd53a801f0f829a31af6c129fb4f20f1250f959754eff8c629b85a716b6a18465b6495798c0c5166c8c 00203d77fac64591eb9a18de20a9d5eacaa1c3ec58a5ecdb3008c2d642e197141d16b3a9fdffe61429264f5b420f5e9926659a4c a89c3335deca93eed3ae6e91b274ee0d6c025792e99b9fa5d1a5503c02ab5b668b08cdb14d33f62f90f2883f70aeb42b +01451c4f09720cd53377a5ed04c907a735477378ed960235a833049d6bad6e6e89958b4c4249bf0f6d4f043530c9e5426deb0ec3a12b7feb4860757b41bf602ca95655155356ec35a2db8e2657998f56529be4b714364f83a140846308a2973907ed7b08e935173ebbce5e29afe1444cd51c92824ede960056439555e7e74450 0057a2e6a59d4871c3d547690237dd9846d6d5dc4ec0678aafc9c8669af8a641eed67bfea4b05fd6b3b5357ec4d0caf352691ea4 a867abc01f1eab9da06b28441f6d1f70194909ab189557424793f02cd35b7890a8d8e47b67daf32012425065f696a2ce +ccd494ca005ad706db03a3df6d5c6e876ef859ec77a54de11fe20d104377df1900b6b192126c598944d19a2364b2ae87ad7fd32265d59e1f22be5833f20767793677b628f18e9619f8ca32f3af3b41c31e87a98d1527e5e781bff33c1a8be3a82ea503e76afec5768d7f7dd1f17dc98a9e7f92fd8c96fca0db518bd143d82e6d 000a3da7a6633608fcee9ce4253bbcec08d41ee6b00178ceb017de74e24d48fd89107c9f2db3556063abe3cb011938f4b4871795 b4e2925d1cffd4396f4b8e98b5633cf22591bf466bcb7a3989673747dc937f0ee58d5d692066e65065145d031cef4e7e +5719e50d939a8d74efb444eb5a77cda48cbb59e7f976cdb2ea2848bfc558718b39ce27b893c229db94bf77992222d1746f8f52f858f85124a28193ae0da039c53d484681785f3367f6516fbb8a86560aea9e3428551facc98cdb1e9df8e2f37db823a7abc589f667b5c93c4c47061400220a2014197d514217fc252cef5a2433 00384723c8b4a316b450d1fce0b2645912b8acaeb3cad50860cca43bdc0206ed5b3b60ebdc29b3eda305d0d60eeaec261edc24d5 87388b83157ce76af2c0edde6b9c75592518fe6480272349ddd311b36d0b5c8714c6617e6dfdc92015186089c140bcbf +c84e5702a339259a61b5ba8ec1957f23ffc4f1eeef3a58f383d3731bbaabfcf49ce2ebb597960ac5115a2af1c62b193d4ab6c24433d5f168a1752e40145f19aeb6dee889a53a4fadd13eef60e28fcc7ed6a9b8b0ca286c1b3d66a4b2c327a629d15c148049e3a0ccdccf05cf22c31956014595e417060627c8125bd7c00f8850 00bd3136647572fef3de51b12e64b36460bd3a27dc660c164fc705417339cab21f9e1f9be0f3da926df459c5ba58b701d306e67a 96796e31896fa3bd7348d7caf6e5f4e3ba2fc103f1ff3b2c81b54ff14f63764fc35d0ddecb64dedbc403219c07453a91 +c90bf11d04a708e64b6f94d4cca64b92463eae878c377b188c82c1c5f05a038be20eca2e18034d46f00d9a6fc73c4084981748ee9d2915d87aee4e2321f4f9e11c176f01281913e324700d9cb474b7134fcc408fb4a7006acd9e63d4578ed4c2729d8e0d01b1e6174a43a024ad261eb644ae98979c3cdab75af357f6dbdf5db1 00495be0b0a9d357f6155fac008cec90442200bb842d89292fde38b7256e4117284a60249b3101b3f19f778b680c0d1d7422b84a b9a5cb00761dad5a349436b944527038ac8d5b5746018cdeafd24b4892b365e9dfa40ea5be2b3aca4e9835eb295c0518 +e9b2a33906a1079280100039787377c2971c378b92e70a38ab41dc23979d6fb0c41e53a21b37632407adac6f212341cf6af8605b4978c85c9c16960e1674247f1795cd73b99ff28cdca024f5078490513c77114c2f52288f5376872c331151d7b2c08f7794f2c1f9e0d849d32d73636f0aa899988ca561a76f74543b37cbf3a3 0079626354dfc4eeeb51fcf232ee9e6b0130c9bd40f15ed45606bb7faeca8f359e0c3e18bf12769254522fd4077eb24bd5454871 b099ed5fbe3aca302a0f8a84c2656cd593b0b5992fe72abcf09646a565d05fb9c5eb94cffbe4dd65cb2d0f8960cd4df8 +672db3fb8cc8e5f831be700498d3ab3aef14b7548e8011b21351215fb6dfa09460d18f52c02c8815baf396d856a429bb9afd602a10c213af34db80447f4c06ab4bd28873c88eb9639b199042d4b2cb13cc364f734fd4ab7bebede7dd4da63decc0cc1f84e34d760013f66d71641073f16c08078880b67230f2d6c6bfe17d206b 00ab42bc7d0e3c23f8bcf928e25f9f027b56f270398a1d37bea0ee5426b944a9c9ba6d0d7796899543feedb470f70b2ab148234f aef5622ce129e9213edb9b5eed98dbf362c54d7dcefa5e86129d37b53e1b24477cde16444bd9986fffc7b708bda31bad +d7fd06b89226cfd66671ce5b4b656228c52d986afa7f6f30161680eb0c9cca177992a8a8c40167a64165c518c55f678702125709361b536bd928567c97737bd750d0e2e6e0c00296a6ca565f7c05cc8c54ae7a4e0c334c6a968fc18a959c18ebbd924457701316a4e999fb11084520dac68dc2d69187134c40891af0355ba89b 007f7aa2216164ba689459ee5d5ca29e70ef75a5b2a4416ab588df1dcb9164330c0b405a9d80c3acc41c19f58e24e17ecbc0fa7b b777b9d8c8768ea26c8a8676aee78a53bb5ebc7f3de471d5747f2d44f60d43b103221281d649b8d382adfd5db2ff194b +83b7e9d3ec638fef51d2885fff5490c94e2509c126608f82660e5fc523032f3e85d69d9b76af145f6bd916dda35775abbb6d1902bf38880f8b9259822055c5b1bc726c51029972cf7474cf2a812f3251aa71813476bff55598d079f075a40c6c41498bd865ce960c518bef75a873b9d010965f342dc4b35ef5c5972efe6fdd18 0021d84f070c6823a70f1a74225a472118c93ce9dc509aa6064051ca4574939dcfa96be862069424bdf1a23f62f2868326422e64 a3e9b5ac24e4522680c82b360644d2e8b017c7902150277d43bb2af0529eba15338be408a9cd07bfab341ee525d0962e +c62c7bcc860f0e175128e1127dacf935ce62ae794cc4a0ce7966bceb023ac0498641d7281fbc86f9ef470bbc77f608f83f8d0dd6299cf08f2cdacc7a9642e4246df131820220e5c05d0dbfceda7f16b86add4793e9b6244d96b5c07cfa23574ceb43e8e8b5483192a92b301aa3b37702b8f94f0129d8af1617896b34990c9b02 00b6645344d17528968c719091b6e2072388881dc10bdb4c7fbf41906cadf3699b30f9c1dbfb4796d009480664e6276c0359e5db ad0b201a36cfce7b4c56d5ea1e94e9c8d82a2a11745734da32c8ee337076fc0657d00ec0f96c295ab60e0022ff6df3a9 +b5bf38fd9e822925254418475a1ce762a94e336f12b156b1625a4574fee11ee472d537ef94b4a4b1c0a73b0140d0b818cd06636653e6c07f0f100118242a7703756f1cb1119b3477c4ced99cf45e07e83b7f2749c1a5f8d8c9272d221fe17f7c6a5fb0f8a16af46f232ce406aaf565c6b2766a2f6528c82e74fa1c0a7fcfd49e 00f8c2f770cf5f8e1f900e996ecdcd84fcff5cd959777fd005d721a419123221a3237e39834b270d37752470deaa6cea023c5058 8c535493ba827d2d3223eed45fcd4329d0423e27b737f87de96a8cd4bef59f2a62956cab963189930bae18148d989f96 +6d3474770933ec01b76be789304b6fda423b12a0ae8c87a5ea8d7ee9f71300f39440e1c7f5aa4b47c1a8628cfc3a490b15ef292a741344f40a8fcdd02cf3863bf3e32d53031f503703deab17fc52b3d4032f4e237dcc27231b85d3fd60b49ed7ee40c3344948d87c3f47564d20a11d50e4e520bd16c8701694fc70901a5da625 00144adae951fe897d5812ee4a16c0be4c86c5e57e615c398f5768a1223a9be20fa82ceccf8a16a31432bbfd17e594a4cd8a6a07 b99ce212f91cf48d95f93df038afd3de4026ab034d525d0bf80f3af636b2e525526ee2660a83bcb50fdbabde47f4ce18 +92ba7aaf71f625f7a2e024058dc8739da3567c306da4a812ed9e1542b7d1e982c16082166a59720203f4524c3bd463a662c26a82ec7b4376545206e650eed0d3dd7909dfe3810981393070d15c45dc4a75a8c5bdeba533cad1ec34fd20466a61e4cde3b25af9a80a9a54afdd7de1cf2a74ba32d4ea0082a037775413c61a8d1f 00a51f065fb32c55bf4ff6f18ba9d488d35d9f8da593adb0ab1632533284e0adc43ccdbda9d9507b9862ac63b5ae7b0f78b479bb a608c5d069e2f0b9dbb0a0561fc5c1c3f1c5c5608a61f6be47db9793b1cf43ead14ed1b7b4e81bb3ac1712cb4035faf6 +b3fb9e48c333201324755a81f3ae5d4f0e2ae7cd24238fcc66d858e3aeb1ee03328660d6399676eb1b7d8285ba571e214d935bb45516fccfab57b8eb4c3d5f1d7357c768eb7b5e7b5710f599614bd4e92706eaba31f8a5e7e57af7ed13066af50b4540ccdc126b677789920cef8543907f0ba9dc92aae343d3425bd784ef483d 0095351c0bc07acfabe6477fe85f97eab520dc96bdd58b44b036328ceadaa56a1904d2217c5fd25155ff2aaf9005a3e2687fec81 8016c5050c00da15aad912f3a5888c842a7b140f6842e2d223a273cf253194df129d404bb32caad2d1ec1bb791303246 +9ec5f7d65082264b8a50be772c44277a73ed19199eb275fe5976f9799d8629fcb4a59a8d55074cd2eb2a0e02062d3f7cdeb05e62931a24fd1aaf14c257944d1b42eebd52726d6fe281211b39038e52baae077ea4df89675d860d6ba5a0f998d049614201b872e134367acc90066ac602e478ac3e43c3ddf4b0ca0aac1a68591a 0050245c1682344fef23bd549ac8d1e8e44b2840c43eec1cecd33daa4e9ef6b53f496104d7432e14248682cfd6f5b4853b65adac b9b68251d9ef152271ab78df473d5bc1d605a93d321295845b7187518958b41c15c7388631550c76bfc02e9e4e9ffa69 +61d657bf472676301503f6784b7286fb39fb4186bb88abf1edacb4a2693d0a1e2b77bbf2758c84f2cbfd1753e20841b1cd4b456400d53f4d686e666943f9b6ffcdb77f510be97536e9698fc84ae347d483bc8984548d1cf86b9b40d360f9c0dc5bd1c55868e26fce1460ba94ef5e94eb63c9f0776a0f446c0cfd4106d9f36352 008d3b0277f0e9fe54581d3a9499ccd7f015c08339591326859af969d2a26284e3b3beac4a0b74d324ce5cb5f38c7995e4e3a41f 9560978d80bc6abd76e8a8463c01fa09dbc7d3ca20f0f237cec53d6a38175b001c21ae240e07b105982cf59ce2201085 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B409_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B409_blst new file mode 100644 index 000000000000..8e0ad8b46c84 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B409_blst @@ -0,0 +1,60 @@ +f2380acb0d869d1cf2e25a6bd46ebe49d1c9270624c5507be4299fe773749596d07d10f7c2be1c0b27e86f27b4a6f8dff68cfe5c0b4c58dad1b4ebec7bd00ab195fdd635d9fa8a15acf81816868d737b8922379648ed70022b98c388ede5355e4d50e6bc9ec57737d8843fabda78054e92777c4b90466a5af35dd79e5d7a81ce 00beb0df3b0e05a4b5cf67abef2b1827f5f3ada4a0e6c3f23d698f15a3176cb40e85bf741c9fbc78c9e207fa7302657527fd92fb 97cf3d78f39cfa667254688e3c204309f190a10d10c43892ce379cf9a3e25eefc9189f44c9c84384097c15a0672f3e74 +22a97fc0a9694dabc6f274ab52eb592dbbe8beeb646ebe6cef60eff341a13017eef980aba6d24ab3afd976e2f6a84cf652654d4a54a36b2f2f62fab8858f8b0479a48fe9f47f8fd5a4a1f3141a91cbca186507b2bbfef5e4c4d2df525f04ef7c4720fb443ccad540f03a2be468d88c9545d1dad579fd7cbcd103bbebc9e9f961 00504865a30984a9b273d1bc289d734d10e0aa56e93ab14720f1a42a27d8cc932cb8804b963175de6fe57d8eafa8ab7ea0592dfa b1f175068585bf030bde2d97868965ba3b343b09e700eb630abdd904f363a24000592a1fe2d24be14beca4a78bdd7f33 +af36c04af0e3fd64bf52dedf52fb788d2d1bd67fe05d98880cc7ad3c20436abf02f637fcec209fbf888903fdec8682717299f8a4386768153b7faeb6581db57fb9aaf4615b4ea8d924198fdd158363a1f40312527d6bd14c13d19985b668c6b88a7548104b1ff057d07082eea421f50062a315bc3866378f2d2d634f03fbc0cf 00cc08a4ea5ebe32027885a8c212870e7c45b6c610117994d6a42a284c05199414a3a0e8e6645ac5c2ebf21c505a601f69c62b85 a43ca737bc01403c34c9e2a27d6ac044032509323e274e35dbab204e6ebc4124f3c7ee0165f8326fa2c59fda1c4de622 +6bd6f52a6204b60f37929aeff28c87ef61ddeecc231e52a7772275f9329add899c130956f8c50ac2698aad3654fdb49b74a6427a62a11eca0a8ee8b719b8c0df7b9f0bb0af5fef4918a8c83367d29fddd04b6a1ecad904471e5b59c8fe3cdb06b4f8f96419518dda960845d83c49a49f1b1f2fd1d2682a9d60c25fe3ce982cf7 007156ef0a74ee1119532a2a7e8c02be1559c3c21897af9d5b34553c3d0feca4a8d5929d1945df824478e0c0b92a6fac8c84f639 b64e2105a6050cb569562bf5af725e0f068dc5846885937be07f9e44efd0b7343c5d4a309a5081379ef7808df2e8d055 +0eb8de25f63abc9cba16823270e9b6f3fdedf0fb90f6652a34688970932e3ae98f6d3bf0fefc5f247f72960a6975bff1f1acc2188a1775fe8974b2bb2b4c8d226ceb735113a14009e8ce66d58808fada4e6f697fd016829913352c0f659b6be354a067df00cf74919580750aa6064f21264d89dcb28b3b2d4d699115c36d1310 00a95c7abffa92e2c637611ccba66ff9d2ab121b40a85c5b71454cb0dca1f098ce1be8d9ea4933d1a91bcd270c5a33687835d6e4 b2a97d99673a8d757831a15f283084d58f1899ae4ba7fcc5b47e6fe534c89c92671b7603849a98aae009617d4680c0b7 +cad58ca7a3b9967dc0ab62a43037764f8074ef9177d60bd98f623d693333971c24a575ed03cb61f4dc2e3d6285fb1204502a540f3c0bbbf23f5bbbd1544f322ce35d949d8b1d8edeb82e90927ac67ad49c91007056bf5096bd690d15ac00e1874fe33293d8003a4a2b094078cf09af799dde384143350c54a99e1f99cc31f2d1 002c438b07c6e0685d1f94a4bbafc013f8f21265d893f54e54c3ac2071606ad1ffacace0b8367aad724b1d9508c65ce52282e397 8a2aaea11d79415915ef31c7f29f823b10416589ec401f8e1a20d55bfe0691dab71907483729a575ed7eea8a44c8721a +281ce2643799bbfacc7d5993683a4fa656040517854f3c2dc7c4f8848dc305382e34e894d433caf12d8b493020a6a08d1fa05b08bf6c53127ad5f33bbe75b9db0615e3dd94408d028dcf3cb7598f6e7cb4c787681dabac7cba2cc06fccb7506fece6c7c1c1bf622d525ae9737085ab4ac578905950002024f30159cf0d99f50c 009e8658f8f9e6cd98c0f4f0fd20d64d725653aeba339504def17f3ad12a63dc6157d80804e5f43f4ff48fc5573fde2c615ed31b b1ce9ee88eb20dc3dbc13419bbb688809617fc1baa0f93cb5ad00716fd46a0469f9eab80a4f8a9ae6a2807dc998902be +0c061da1a16f2be130ae3b20b89745e840bee09633fb49671db28ec9a051545f57ee07e2410ae7ebc61c9af79868d3047705bfc64ac0c04ef0b286e579b650c7165443631e49e6a53c84cefa5625b1e1035a6ed89b8e839540040151132a937666524265e099272c1849f806db0fdf2be64960d5b5853965099459968e5beb32 00c4c13f65eacce85a51881caa6f82d9e48ec2ac574947d2751823a7f072d38bd9da0cdf30b6f19084a6d291052e7bbc2e1349e1 977861d93ebc9f7c347c09550bae1a4c7b9b44bac191fcca9d3a9b0a842bceefc8058686d6a105aae1fa7307d12ead75 +74ac2e1303297efc3ed8e624722df505df55b7f33964cc0d270604cc48b58205d8a11952232a8feb0079baa30d7d33660268b56a5a3dd90105f0703abef8f6636a99bc63bd47d9df100351bee32d8205dab0dbd2af36fd173409ff8d1fb7b24570f3c1e968458f58aea5aa2f46731ee91ffd6d3a060af6b3d5020daf1362af3e 00da591461791ae7847e6d8dd8df46a63d3021644abe9520e158406c96540d8fd82ecfb1c3f6f5cfd7688c7656cc3e3dc94e586e 9343bff38058137ece47f6bf50c52f7674a7c3c6d1321edad50861dd1dcdcbcd287687a99c5a2fbf8729cbc4165ff0c4 +2afd17344552ccc577b0118caeb7dd56a0766e25f84df17c0505f9798931374b48df89a48c64e199108c36e00c0bf00a97ccde55787bb97c6765601765ab5417f3e75e35a9fe5e0f85a721d9f08440ed617afcdc200b318940a1e496040a6ad9090476b0fb4fcceee77b3fea11de09e7fb14853d1fff8ab12d66c101257e2d4f 00b5eb943f0dd390b737510e2bb703a67f2dd89dc9f6dca6790bc7a260cb2d0fb8e1a81ad6009ed51010e7686d5b48233c6c1686 9695a451d7885287eeaf58926f205610e91978fb1149a37d44d0456a03f33d60fbfd40cfd14bf08e8aa6f24f621e0014 +174b2b083541f8284645a810801e72631a11bd7bb805f684a7159e055afc44357f2c80df2b7853678d34a04144e0ede2327d03db6df23769ec41194a8d9d86af74d51c5bc11ea878c6a80689af71d3fdaf1c651003385332a512e03dd040c33d9c328ca89ec7ee9026bbacf30a7f3a68e0d894fb9f7100ffbc64bf17679dedd1 009cc63f32152284fca27ab2837bf1343144336a1fdf15b9727c47e877ac69ac9cf4c97b4bf42f1ab10d73de8597a554ed099efa 8707df86d92ea4421ba7a730d739c2c53ac77fabfe38ad3960079c908ce9d1ce5ce4de8e27bcc94dbd47e051e00dd75f +758df71a952cdcffdc417b9fffdfb57582ab5c5473a8bdf0c2101953b023b77824263353dea0e2ede1f800a5757ec6ac0e1e4e3ab5a4cd85567d2d19acc6b7069a6e7368401cba2b6e642373654bec0ddd19fbf032794c15b7ef7e714e13e36875262c01e77766ed53cbcf735936dc9b33eaf2152a396349c82ca0297dbae4a5 009950355e8667bea8bbe3a2c4988436ab5394551b375e27fdc0c1a1d1b07ae957932f428f1aca0a486e54cd0b5bb0a5c5650641 99953012174a21ec1a23fae733c91e31b0a9ffc2c4fe67a5ea2457c9dc2f4d4c91ca04f148f56365b632a3a367e9768d +b96d9f66b2000e9408d602096f032b112f0e05ea874229ab9daf6e05bee49b4722e4f2d8bf2eeaab9dad94438c76b7cc64dcbb59cb4e03f9ac70487a1d24d8d6b72d7462fe738a17edf381d52179b3acc0c0177c113eb4d10e8e78041deac1d56abda0ddf892edb8be956d285e7236bc6794168f8a180f622dd5f2b9e690c275 00a995493d6971c2d7e8fac3da9f8c0b5afd877cfb94924cfecc167f9d87002136ab253e3a4f9ddf5c9c99bb1dc1af0c6a3a3c4c a2520ea13086a806ba0c3ea85ab8c57b2e5dbc0f62d484338170a6145a0ed4377ce7425b7e6c3ccd9dc7bec6e3cb7215 +e7ae60ac55e6ba62a75d5328bbc15269d4638764169de0bf0df043d15f9152bed909b1fb8c7a8d8e88ac4f552c1092b62db00958a3a827f64896f6de4bbd8fa5258d6c36e3904d82d3eacf6eedba50b0242eb6b01212288448c3a9821c4fa493869c01149ff1850e8115cf9de1618cb8744626b1951d1de305745507c8b21045 0070daf435cdc26ad66c3186267ad12d10f28d32d863f950cbfcf042fe9dfce553750ad098f82f7f1650c1126b3e4451bee6e11f 83f59b18ed58fcdecf4ba06c554a3e7d61a976de0ed14d26bd5881d1a3b6161bb7d8b833e25a296c927f22fb142b56e7 +666b0dc2ddffaa7ffd57ea3b2768f02d4b77c16fa007c6d1918400d195f068cae2dcaa69817e6e4c70d5b29c5598efe2d957bd12d0fafdcf5ac52dee80a2d46e77fc18cce2a49bfd787ff77b942c753974d22434742bdb494590d17c42af725b1309e54566276af3bcfbf5e174d3cf191b85903faafa1583282c97e66c5da6c4 00f8121980dfbe9ad0bf92383c7cab95fb72d5caba96e1de7772c6a179e85414802fbb86d725401451329287305570ec7fdd873a 858123529bbab8efd502ce44cd86b8c75108d2ca809b8f5a8a4e09430ff2765c7e7a0d73d1447a2888ea0663d66405ea +3e967cbc2bd936e0b6125dc5cf885735bdcd2d95b2f764de6931c4578ac8e0e87abdf96375481df67dbe1b6c43537e84ec62bfca6672cc5f3ea4125abd4a4119edffe04e42411d338e8b10abb1f1f818c50a9631a3f89feb5be5367bdcb0a8a82c96a427ba6ce99f9631d4411a2b7f5b14d32cb3901dc9d285e4cf5508940942 0047682b2e3bcb5800a531858e8137692a9b1ee98ea74e929ce4c919c26ae3b3f1d4122d07fd9a70d8315fab727ccb67004187a3 ad2a93211e7be7db3bca1b7502b722eb9e2f99f66089d1699571d57917b64a11ea6cba89ed96df2b7dfb9626a7ac7611 +ca1c90012eba4e7c5f01d8cb3814c58f48c03a16be6ed86934014365eee547070b870d1d26a872cfd28b60d9ee0a66dea223e9eaa90ee28076188d6091f26f665684f4b486af70669555db9058d485c677b2a34d4a98aa8d6f43bf6f44aff2a23c5d765e98f0438ab81be0585a5be29daece5d4116f44ce6062753a3ddc505f3 0040cd1a06233ac27f3ddd108de7c6c0982793ee620d71982697713be9fd5143658929924cc88747a680779bb00da8a44e1e7d3f a61f6c09150de181a4a3b476ac98c8f06e21a7abcef1eb3fbb4552d05d83e56b5bcf932419a35494c30f24d481bb4a6a +a54c4351ebdb075d6a42a787647390f864b2bbfd8bb3d0e0ea9d767200fa344d1a9ff091bddb186acd69bcaecd767068efe4d752d185bfe63f6674279d0e7192d2077c400bbc0d5599ee28507c1253f05eae0687b965a015e1f3a292b4650106765266f5c95b77ad2d82a6a6e012f233169eb6b8d83576901cfd4a927c54d7f4 001ca6f752aae4eb7fc9c73a08d6fbd96bfde5030d759a2507bd45b6e1d1487e53abbe98fad4f41976364e0a1d830910ccf97abc b5de0bb98745b3276064acc2828ec0b348cce6830441ce89dc56122c124be4cdfbea1e282dd1cfb35ee4597cd37232cf +6723dbddc8720feeb75e2a061b7fc49079f999fbc79ec8a8e01ab8d35b438b7049da5a23c49a58101742791f84f45d5f5cf551cd7de6926a0e2c4ffa1e378f038da597368c62df8cd8349bf046de46d02183dc05b3a3575f5f232dd2970057200e2c9cb60eaa6b4d72f8b73d4d40b98d1cc801d1a69cb5ed780a75a4064623b2 00fb9b1a9597d216028902abf743d25944258b48c9762d4589fe660396130b75f6006cacfde60f6204463cb8c18b032de1dd68d2 92c2dd796dced337b14de26bc59ce4495f2dbbf9a20e01d455597718df3a8126e3f2f8201de8f801f8943e22c52a10f1 +ed53cec5e5500d62d38c829002916c657674ede4439c6f405ba672327ec677490e656bdd698f114c2ab5e6a1fc94a1a8d64466cfe9eaabd23a8b5c37f76a3c0decdef73b3e7b751cbf3b0817f4079560b5ea34cead88ba374201236bffc48eaf289bbaa4e828afa7d732473c228ad00588c9b443d65b998f21c3d7a9e9196c08 0032109202d754da290c266f74f47805a06e6b5c3f721a72fc97a3bffeb8887e0c642d49a6bd034847d0a5ba09239c5dfdf0772d b8e6d924b33774f8f05455eeac48750e4961c4050b66ee70a324d0b4e3707453844a9969e287325799698e4ac98591f7 +13829401bd41e9fe01329e9f5a002f90f1a6ecbf25fc63e7c1345f265ff02e496230f706c6ab377ea52d8707b54f8fc5c7f089044e2bec1dfc66a07da76ee12fb9ea0697d87706b0ebf677600bd2fe117f6cdefb8bd636a1b6b97549ee78f992c24acdf3a946053f06fd012a9c703efb8bd929a66aa74b05d61bff0395232b00 0080536e820fac59b3203aea928475043b2576446619001647e35693a9e65d15236c3cbc12e1bbe0eb305973535c882b70197a92 ac1d0b90955ec508a8360a6c04a8ccb904ed24734bb0e79178e02ba5cb17ea0457851c10c5e6c6cee2fcea54533aab0f +e696acdfcc96a6c088069b7595ea9516a36d8fe04dedeb789fbd965db0cc64b7017a821015f6210b6989e515def5a9605fec0d337e4ac59f3101a505168bf72ab6d98ec62a71d2f94071fc05b95e98d4efc59fedc138e3e49c5d0b44d1f48f7b1e7c1944ee189b242950d2bc804d31c7eeb45283c84638f043ab9533976433a4 00b05e5f0dad9583ea18fb8fc4d8c75fd2e3cf9e92cdd9b737485c953620d345006c31c288b380258b6500b84f729ce6730e5303 b135d7ba429ea469b29b9f2a1843c2e6e34680cb698380b22704939e10733203b032b64b4690622522fa4cdc3ebaaf8f +4058b9a8cc15ac148909eb97fa32aafbb6077b168dde91a411dbc973df7db056dc57ff78f0abcb70f70f800bd752197d681f44df4a7817c0e7f60f8f65489ecb6167c14b525e91fd2cc5d8b80ba380a83d031d5827c8b1262c687c90ef0e62723d9b565557f9f6fed0db48f3799274c2cd60a14303406c35802cba6261121296 00be1d277813e79051ca1611c783d66003ef759b9e104f32298017fb97667b94dcee1ce807dc6b4d62416e65d4120523bf6a4edc 8ff089ce8cf1b924ad360e3dc4500f18e3305cd16110574f3b35bbe56c3169d9dcde26d0d652452829e76cde1ccda427 +e793237d46e265ab84ba9929b196405faa3b0e4686e8693567e53f68e6991e57677974677682a2510c4c35b1968a90b32c4941af7813775c061c008a60f9f671cf7419c94253d6106b61e65034497f2d273a5058379bd986e3d917f708f0a2bebdba150f6d78a3af9c722a2430ab0f4bad602e91e18aaf258e3785fee78e4502 0073c807bd7e07379782ab790720de4ae5106f16d34e80ed70da5b1594e660c9b775db94066b93e74f855f57d88b6ecc6228aace 96d2b1b556af513cddd7d9489ba1c41b483ee35c95e97074a814c8f48c996bf756cd1217228d2255b1bcea6b18db64b3 +ffb8bc80e7619a562d8506eba7658bef0c25ace3dc1d01bdc2ef00933d4fa07b80364e5e5826074edd46a707dbc3b0ab19eec7ea8990839d7fc0a80b70661204c52bcbef57c1a7bdc861c10766033a82dafbead283d911a9502d5f9ef0a39d35ef26f3616212d4bafcd413ffd18b424fe09b48ba02ca5d97ec996205cd49d22e 00a68379b2296a6c944ad5dacb593b302d8ef0b05873ce12bbc371d705f308c739d21f343349524aa72f05341e64f7435daef112 b6c428881a9efad3db2befb32cdc7b71cebe0ac89be2b156e908f84482a5b0da852dfcb17d06d13e8f04f8ab71980240 +946bde90a5b903dd281a51d7fa93d80f3fed07eaf50c18fe9fac5acf67326bb18effa3144e25c151efc006a50a274ec6c6a5d573051c4e2d117ceb0fa125acad07a10fb6534a8e5f5b3da2a1136779c51377bf76c3a4a93c0c6158f729f2293e414fcb952c9509f228c804f0adc1daa327a8991d48ccf4f3957c5f8ccbe3ad4a 0026046bbb269ddb1ec14ade56175482343a21b7c265026cef3c7d6a1ae0f6a68166b9e6c49a6e733ad2ad64df7137ef230038fb 9713995c0861aea26c643625c4b3cac6a54c04e334606cae2bd2b41b31883c6af66755a757f90a94f650d7d48394e523 +07f3fe1369ebfcbcacd66675bd4ab22edbbff72e68709cb57d4f590e49440f01691f490c58b5117bd24aa2fe2101b59c61c417c918ea08ea34bbb9b8aa17491ae5d9329affe894f42d7586017877fae3ce35bb80c97f92a004380374ec91e151995166e14ac00505fd1fa810cf02981bacbcebf5f81b2e633d3a3db6737890f4 00bbcda66978ea526f7bd867c3303b625f11b94dd9ee6e2c2f8688ff07f2bba83c662949d47ad47fa882cb7d203a7f0ef5dbc52a 81bf41b9e017363dd954021174db29ecc0467508f7b513138c549a015dcb04e2ecd9e4d9d649baf7c7109304a00d2216 +3a1cb13438e3bac9ad4ab1d319e90e2c9f118dcf1eb54d6333c674a665d41451f93cd4a9334cd057a44c010edb668254517a63700a31eb0ca474c84873e486f2f8e158a1a7735362ea0cff8ef17d959ffd851b21a91412709b3c729474d2cb40f6ca0e397030eb2611b402916e4b656f0fd868247d80be3ce33d52054b7661f0 009be3dd3442e0330750f0a6252bf9cb317f32f942ae516a4038dea2c40ca6484fb33611bef016cc64baf166c122e87c15466fd8 832094824ca1525ea328153240aa9e4d68518f32c6aaab1576d14be1dd0dfc5162d76ca255fc93021eec79d165a811c3 +e58e7b881a563d54772125b2863718690a5276c93d9e1c5feabbdb5d6f7c7293ff0f89805b53663bb417fdd46874b8e6a466e7e3ff6737930a0662af1d5879b071b0dc4d014778dff26a2eca5992e763bf4c4698c382ac947215aa116515876008a56e5bf547857049c38a2d3737ed3393705fd346897c3beb80caab88e5b8cf 00ed321fa283c662e87eaab99b7715e6cdc9b42e14fa5bbe2c56fdfb381369191a42da7e574839f90a85577485f19446fccaf6cd ae7f710d649317561b5013015990f5dc89317377598a4d55ae054ac314a88ad3e2fc98e5e3c74cdb71aff38a3a02aa07 +8889ea1da1cbed98963941f6ac24f47253ff6af52de920765214f2024aeb04f7ad46936830a8eb04d95aba64ed7cda6ef242f454b67bc2de38a46b6524bd5c96739c4b580e89829a61a8249ec8dc27a50f43b8554cfb6f4fa4ca6875983d4b60a1c6b49f32ddff6fac0cafb64d55c6f594b195c207a9bd920dcf20e0080920bf 00396b805073f3c3b552b1024dcf35559ac44f255b688871a3c6657f727a4b09f3806cbb75d26a00ae1728be632387e804775a8c 99d7b0a44a06f3d1e77158bd669c66d21832af5297a84c685f5d498493ff2d05e41dc64b1867885f8267eaffee6888a9 +55053af9370901e38622734a5bc5589f6a20e258627f381fb0c366f3dbe58394e5997e978eb7ebbc530f6e6186f48294149b8594fb551c31c50521a8c4d67e5862921695604afb23977b6a69b21abe75966fdd11bfbdb6b51ab0a474c5fa07c4de7872a3bd81acc417655090558dfcd5af449b3347e61fa9e839bb9457de64c1 00a8fe323f6736bcabe971c7d964e75dece70cb54561da48a11c40027ebddb23e41c7b48600f569500fe8ea2abebdf480171dde4 a99c5917bb9e4f018e48a5cc2df347d9fa489032ddfd03c6add96ee0153f4faf5e15238c45e9dd32e469993d8e506487 +c4264330534a6c2bbd8a3b757e0912558302ce302f835ad8c5474993832fd30036fdef40b10ee37293e871db5b0b149654f9e543e22111f9709ef45732125f713c031ccfbc9a2f3aba160c241d27be4dab87ab2fa9a795752ab2daf20f9d06a98d90d01c07133adfe83cb11d5176525e1bba6a9ba70ea48b224d46ddd8103f65 00105938ba9f25034da3e032dee121bdb192ac2128b50a2ed4bca042e96cfaf4660c9d35f3e67bafd4c99f9447e6dc408e0c4471 b3cc555c3c3b8ac12596d0af9f5a1f9a47a968a24f3295449f450867249d726522e40e4852bb7f2877d2c211f70d5f79 +3236f1ad164e1b25d828f5202e3513c80c72a577aa9af56f041fd96cf5a3363f4b827723b1511a2f16360e32eac90ac55f4ee1146791420ef9e2af333c17d157b00e43992ef6f2be2d2f211361e468413dd93fb69232f0a0d110bc5fff361c0410344aa0636bf809062c73a7ac7c142063912b6ad7e1626fd2a384f35faffaad 00ce11677ca818537dbaeb880fc967dc8bead203a2538a55e756679c4a9e7975b9b3e6aba4e6c6eab4152d0c0939027e9b0bd92a 8baecd8796c72995ae4a13b51366866c5195e53a6dee4ad3ab737dbe779bd1f0b5b3fcfc406a1ca44b162f1f55ddcfca +6c400ed098d8369dab6fde3553afbbd4d47836d0d12dd16015f15cb8d067a39391c85ca4e78c62b8b72c1592349ff8dc52db8ccb7fd80c085fae456dba6f4a2378e184dd59238c92cf04e40d43a66b342d2a1325a0bab12b1ac857f0564c27b35e6abed02ff5bbbdc3770ddbb2ee0513df48bcba925da6d61583076cd3129603 005a239ae0f40d76d8d3589f1662b5ca12176a4b2784faa8339b54e96a1e1294433a4d83bf904196f939bd8b33bdb4be340ec703 974b3e9cec531b214d89bd0555736b5473ab855dcafe183de0588e1af926b748f594e8482d750fa8d34c5db08c98255a +039a149eaef2de30b0ae457b376ce6fbf88afd4cfdec02d3c5e00400d3b0484c1cd6ba74db5de65d6f2fe39871349b30fdf1ef29bcbb9e182eb3ec5629d07d98354a5dfa82d7f0db3dd10d1510c0dce086848a198893ca5ad24a663494f0596b4eee86199ea85e7e8f2f76e7a6bd4a052c54287f61b391f1e52f96b606151c34 00077390c62ac41aca995640fde0c79c76f4ea8a8dbb22323ed812bee837ab8798c5d0ba976c7aa634d4b1c2c155de2709e7352c ab53f5e5d74e38ad787cfae4f0912432a35e058b890aa09c9082a52f999bb0bdac8823bb369d6476612e05b279d19ae8 +08617d04fffd6644c40f7dd57919f7dcf3c888f4147535d12ca658302305bb8e220bb17ccdc480254004b9035b357120580882ef86aa5a061b2850100285b7d61588a664dd4f5394f5478e68a80f610c9204d056009c1c9e902161eda33ef61aa902e96b6f094a9f053135692182943d38b9763055a38739a2a2d133c5dbee89 008bf23b09fbbed1b55769907aafb97f4759cec98649b2c9da5157517d4f85bb70157076b5e4aaa7a940af042302f8be06a84ab6 b31254110a883bd96f9ee108230aa35e270b17b88afb83d432f45c1a28c07ab6e6dabaf45683376c3239933bfb824860 +34c959f549a307f21b850ae105f41299b8bc94fc292aefc61aefbe0a1bf57576ba8d9b80caac635e4edeb22530163fa9629665fcd43959f68eee32482f1845a78ed7278e6e43d09ed6fedf465001afc0d61f1d2e1d747623e82a762576b879c7024e34f43104593cdd691d53bccaeb8f212dc29bec6bc94cf69d0a8491db124a 00082ad05d19b8e16f80e53a4cccf6869ab5128c5e622ed146fa8555985ccd2aa3b9957dd374586115d4d75b1c01cf98ecfc3646 a05d5fb211304776b0efbf162fc279eba1b5d3424c29675887fe048cd6b7b3e9011c9a3777d85ed8014e0cc7bce7c25f +514f4de08a6f49edbb6797c9dad6d33bfa367cc1a1b58a5becfe646c7f3352d5c5d95f7456e7112c4ddc746b9076b9756ae3916c07bbe6d3823895774a42d25d44b3309d18bfe7e3ccb1f85dacfec1654778c19e2981a853c1f40a7eafd16d331093110698c957fe9f1d86582706a6885543248b944bb70cdf9d2ea89190cb02 00af7e581aa4f9be5815f0c447e39de00da9194eee5e5f609668b9b69930b5b48a948614c2250260d1917f0ebcb00ebda4bb52f8 838f4694907329dc2a9fe1bb0cb37bd641d562b917f3a8858d60b1faa9be626f821ac7f0ad339859b0e157fa21e6c34e +4e5d16cb1dcaa1abab1e371e1de02f31ef4e0944dfe1fdec45ab64326435b2af9aaf1a6ed8fdf1a6ab1182bb53a844c7cfd66da30aec0d41757f5988ada0017c4ca752597a9fd3637668bc1a92bb1556553f28d66805bb47f1ef91908ce098d452872da9800e77e1fbd43ffb0ed6fe6a62185d4be73ae96c9241b82cefb2da22 006d14107b08354e6a41d7d7d50c004419db8bdc50db43428df5e86084551237223c498bce71a17e25695bc438c5c09e009c60e2 a44d8ca7d3e3ab3d7c9ae17668587535ac9a43e74b86815a931a69efe828765ef1fabc7ae89f7d641e51d78a492582ba +e29e75269754ec1194270f5c9e8267dfdd8c696008b5ebc92bb840981fd065672f07f6a0f1b19841adfc51b478371e1a0db9c3346a9f0a4ccbdecb7040191a00ddfd0a8faa0e69fcf544319c0155d02797eeef99fabbc55078f9d852927c23fd931685424249b87ed0c70a4a3e2d3b9a2f92830e7d8f7650c0bffa8f8986b7d5 0099d96d2dc9c79549f031bd5346cf6a8544c312a3fbfc560dc8e378efdfe025b0e6e61e09c04c8bf4133396f993b0906c33dd30 b6f012dce3a98cfda34a1c030d877e7fed1cc4ce7aab37ce062070d2f01ed0ce584370067629e739a8b760575fbccfeb +1a538eb447c18494ad5a5ad27be67fa60eb2c5cb2404eec1dbd7244cd802b17ca5497e779d5f779b981b165dab53ad19fd7bf2ea7dbb9b4baea782a43d758202f147e59d6b6b8ed54f4ea084bc18519943f6894d603e253ba3e8e339a6933bc3a0a47126087038e1c813c3f2997aae321b7c95a802b4b73fc7db95897b7c91e3 0049f347dfd361a65910e97fcefbf60013a54837f2ae657d65e02397f59dc6bca27704fed3affdc3d833fdc621cc5e5f99b92a63 a3867c35263d2c69443431ebb3752c403ee0af4f9458b4f3881893ac971308902c41d5a73520fbea3f55b60fde1fdf4a +7502c755bbd385079a4001b8cd653287dc3054f3b57de19d0ff8f63c0308c64c56f035117a8971d43654f89b52e923947e4760ac72be073136da70c5ad7ca1658cc0a2d2a880d3a0c0fe636fdb27b77ff260c4c1ef8a18da8e9fd777d732a37ae9906e6c4f381f0a3d941048d5a1f6f2cb8593873fa4bb1621a44bc2bebfbcd1 00dd226de602af4e9f8e25784bd1bbd4cadb0a8aef525d5e2d57b9f3555feb698765672c5099a7d6dd5faaded69d8d68b4804f26 88d0b0ad12ca7ad2d462145a4caa6bbf7c068d56834cb94e7ee7e6ea2f9174e64b67f5bd19cfdbef6e194ea4c95fd717 +95eca932d03f1df2e8bc90a27b9a1846963437cdafc49116ccf52e71e5a434cdb0aad5eccb2b692ca76e94f43a9f11fa2bdf94fe74af5c40e6bfd067a719523eea6b4e65730365ee498ac84c46e1588b9b954f1c218920cbf71b167fc977ee2a89429590f43bf637eecd91b0ce3be2d66bac5847205f76c06b914a970f543e59 00b6fdbc9c8c76cb2b822a940d8675889ca6f5132429da795462381ce29313a23bc132976fbeb346ed4c691e651028f873ce7971 a8d25d99a54f89195f0abfee801b91a921e90f0c33c3ba25f606c353005b649ac0ff65b4a5b5e54383c5d171c56658f4 +8ff68cb00d03e730dddb05fe0b2344689529096c3da6eeecaf097f22c7fa340593106b1f6726f06b7ce7358edbcf801ead959438a42f94cdb467b3cd5b17fbbcf75739805f9eadc869c33c604cc58f81591b0b8bf4d42bd53a801f0f829a31af6c129fb4f20f1250f959754eff8c629b85a716b6a18465b6495798c0c5166c8c 00203d77fac64591eb9a18de20a9d5eacaa1c3ec58a5ecdb3008c2d642e197141d16b3a9fdffe61429264f5b420f5e9926659a4c a18b07a7a404cb463612e11db2004a7ce607a05bb3d8739c2f1239279d213e8193f4efb1f086ec55e710f8a927ce7f63 +01451c4f09720cd53377a5ed04c907a735477378ed960235a833049d6bad6e6e89958b4c4249bf0f6d4f043530c9e5426deb0ec3a12b7feb4860757b41bf602ca95655155356ec35a2db8e2657998f56529be4b714364f83a140846308a2973907ed7b08e935173ebbce5e29afe1444cd51c92824ede960056439555e7e74450 0057a2e6a59d4871c3d547690237dd9846d6d5dc4ec0678aafc9c8669af8a641eed67bfea4b05fd6b3b5357ec4d0caf352691ea4 acb0ff25748eba61694b733b36cae126bfc43a6b9ffcf11d7978e69bd11ee37a1ea9e8c9d22174597a69e568b650d661 +ccd494ca005ad706db03a3df6d5c6e876ef859ec77a54de11fe20d104377df1900b6b192126c598944d19a2364b2ae87ad7fd32265d59e1f22be5833f20767793677b628f18e9619f8ca32f3af3b41c31e87a98d1527e5e781bff33c1a8be3a82ea503e76afec5768d7f7dd1f17dc98a9e7f92fd8c96fca0db518bd143d82e6d 000a3da7a6633608fcee9ce4253bbcec08d41ee6b00178ceb017de74e24d48fd89107c9f2db3556063abe3cb011938f4b4871795 87679ce9df73cdd150e4cce8ac0213cfe1c1acf5aff7ec64f5f4539893ebfd1327dc67667b498fa1eccaee4150804a5e +5719e50d939a8d74efb444eb5a77cda48cbb59e7f976cdb2ea2848bfc558718b39ce27b893c229db94bf77992222d1746f8f52f858f85124a28193ae0da039c53d484681785f3367f6516fbb8a86560aea9e3428551facc98cdb1e9df8e2f37db823a7abc589f667b5c93c4c47061400220a2014197d514217fc252cef5a2433 00384723c8b4a316b450d1fce0b2645912b8acaeb3cad50860cca43bdc0206ed5b3b60ebdc29b3eda305d0d60eeaec261edc24d5 9050ca2634c0a4d02a7d7a6d6fe62795ab9cdc2b72054b25214cd60d02d12b1843c92496c08ae445d5ce96ba0f083c4c +c84e5702a339259a61b5ba8ec1957f23ffc4f1eeef3a58f383d3731bbaabfcf49ce2ebb597960ac5115a2af1c62b193d4ab6c24433d5f168a1752e40145f19aeb6dee889a53a4fadd13eef60e28fcc7ed6a9b8b0ca286c1b3d66a4b2c327a629d15c148049e3a0ccdccf05cf22c31956014595e417060627c8125bd7c00f8850 00bd3136647572fef3de51b12e64b36460bd3a27dc660c164fc705417339cab21f9e1f9be0f3da926df459c5ba58b701d306e67a a18c678f752316c70da39e17e0f360cf8a16ad75384397eb20f29a4c9ad82e1e4b170985630d61f20a4dc9dd536f5cf7 +c90bf11d04a708e64b6f94d4cca64b92463eae878c377b188c82c1c5f05a038be20eca2e18034d46f00d9a6fc73c4084981748ee9d2915d87aee4e2321f4f9e11c176f01281913e324700d9cb474b7134fcc408fb4a7006acd9e63d4578ed4c2729d8e0d01b1e6174a43a024ad261eb644ae98979c3cdab75af357f6dbdf5db1 00495be0b0a9d357f6155fac008cec90442200bb842d89292fde38b7256e4117284a60249b3101b3f19f778b680c0d1d7422b84a 97d4b156dee86cce8789075bb2258e1d54c0481c7e2dc82d1f5f0216c144aa311eb5aca54a703378ae7a5e8b9a5a5aa7 +e9b2a33906a1079280100039787377c2971c378b92e70a38ab41dc23979d6fb0c41e53a21b37632407adac6f212341cf6af8605b4978c85c9c16960e1674247f1795cd73b99ff28cdca024f5078490513c77114c2f52288f5376872c331151d7b2c08f7794f2c1f9e0d849d32d73636f0aa899988ca561a76f74543b37cbf3a3 0079626354dfc4eeeb51fcf232ee9e6b0130c9bd40f15ed45606bb7faeca8f359e0c3e18bf12769254522fd4077eb24bd5454871 b902f4bc951baf87e808c60207a39e619995ad9a0cf4c2bf1c6e4ccdc0e014f5528b8855105ae428ff26a73e6632c8f6 +672db3fb8cc8e5f831be700498d3ab3aef14b7548e8011b21351215fb6dfa09460d18f52c02c8815baf396d856a429bb9afd602a10c213af34db80447f4c06ab4bd28873c88eb9639b199042d4b2cb13cc364f734fd4ab7bebede7dd4da63decc0cc1f84e34d760013f66d71641073f16c08078880b67230f2d6c6bfe17d206b 00ab42bc7d0e3c23f8bcf928e25f9f027b56f270398a1d37bea0ee5426b944a9c9ba6d0d7796899543feedb470f70b2ab148234f 8ecfb665adfbc73aa3cea883d3b5753df2649e0bfd531334931c005b6a337ff403a8c9025917aaf1d5f49745b8c9571e +d7fd06b89226cfd66671ce5b4b656228c52d986afa7f6f30161680eb0c9cca177992a8a8c40167a64165c518c55f678702125709361b536bd928567c97737bd750d0e2e6e0c00296a6ca565f7c05cc8c54ae7a4e0c334c6a968fc18a959c18ebbd924457701316a4e999fb11084520dac68dc2d69187134c40891af0355ba89b 007f7aa2216164ba689459ee5d5ca29e70ef75a5b2a4416ab588df1dcb9164330c0b405a9d80c3acc41c19f58e24e17ecbc0fa7b a334bbdf74e5905fa8d14eb65b609a4aebf46b56960270756102a570d8dc9ffcbf9b72f345cd83e2c7ed5847c58439d9 +83b7e9d3ec638fef51d2885fff5490c94e2509c126608f82660e5fc523032f3e85d69d9b76af145f6bd916dda35775abbb6d1902bf38880f8b9259822055c5b1bc726c51029972cf7474cf2a812f3251aa71813476bff55598d079f075a40c6c41498bd865ce960c518bef75a873b9d010965f342dc4b35ef5c5972efe6fdd18 0021d84f070c6823a70f1a74225a472118c93ce9dc509aa6064051ca4574939dcfa96be862069424bdf1a23f62f2868326422e64 8fb94de412c148bd886e95ae93c3632b53008c0352684d0895104560b688b434e20dbe4a2cb40c06487939280bdbe1a3 +c62c7bcc860f0e175128e1127dacf935ce62ae794cc4a0ce7966bceb023ac0498641d7281fbc86f9ef470bbc77f608f83f8d0dd6299cf08f2cdacc7a9642e4246df131820220e5c05d0dbfceda7f16b86add4793e9b6244d96b5c07cfa23574ceb43e8e8b5483192a92b301aa3b37702b8f94f0129d8af1617896b34990c9b02 00b6645344d17528968c719091b6e2072388881dc10bdb4c7fbf41906cadf3699b30f9c1dbfb4796d009480664e6276c0359e5db b216fc1230cbcc56736e9ea0addf8a72e8934a4b3f4a937b37f6b0f8c6ee6e1b7556a2867262b0b2ae29052834a1cfc5 +b5bf38fd9e822925254418475a1ce762a94e336f12b156b1625a4574fee11ee472d537ef94b4a4b1c0a73b0140d0b818cd06636653e6c07f0f100118242a7703756f1cb1119b3477c4ced99cf45e07e83b7f2749c1a5f8d8c9272d221fe17f7c6a5fb0f8a16af46f232ce406aaf565c6b2766a2f6528c82e74fa1c0a7fcfd49e 00f8c2f770cf5f8e1f900e996ecdcd84fcff5cd959777fd005d721a419123221a3237e39834b270d37752470deaa6cea023c5058 ade74a4d04539bdd7eb2126a0ab209cc602c7f42e54a848368e976f5e35ccfa8cd95eaa0c1e8581033e41c632cfd9eb5 +6d3474770933ec01b76be789304b6fda423b12a0ae8c87a5ea8d7ee9f71300f39440e1c7f5aa4b47c1a8628cfc3a490b15ef292a741344f40a8fcdd02cf3863bf3e32d53031f503703deab17fc52b3d4032f4e237dcc27231b85d3fd60b49ed7ee40c3344948d87c3f47564d20a11d50e4e520bd16c8701694fc70901a5da625 00144adae951fe897d5812ee4a16c0be4c86c5e57e615c398f5768a1223a9be20fa82ceccf8a16a31432bbfd17e594a4cd8a6a07 8b713a3adb4aa3c12fbf7e0e529eb1ffde896a8a9a4422574975ce9d2a75eabaf242380bb3037f971f81a689986c83e6 +92ba7aaf71f625f7a2e024058dc8739da3567c306da4a812ed9e1542b7d1e982c16082166a59720203f4524c3bd463a662c26a82ec7b4376545206e650eed0d3dd7909dfe3810981393070d15c45dc4a75a8c5bdeba533cad1ec34fd20466a61e4cde3b25af9a80a9a54afdd7de1cf2a74ba32d4ea0082a037775413c61a8d1f 00a51f065fb32c55bf4ff6f18ba9d488d35d9f8da593adb0ab1632533284e0adc43ccdbda9d9507b9862ac63b5ae7b0f78b479bb 8da78be6e7f89079cc68ea099b0aca2ccfe5f3bd4108c483b2a0b69546eb96e517b83076ea37f60f586995bb8edcd4ef +b3fb9e48c333201324755a81f3ae5d4f0e2ae7cd24238fcc66d858e3aeb1ee03328660d6399676eb1b7d8285ba571e214d935bb45516fccfab57b8eb4c3d5f1d7357c768eb7b5e7b5710f599614bd4e92706eaba31f8a5e7e57af7ed13066af50b4540ccdc126b677789920cef8543907f0ba9dc92aae343d3425bd784ef483d 0095351c0bc07acfabe6477fe85f97eab520dc96bdd58b44b036328ceadaa56a1904d2217c5fd25155ff2aaf9005a3e2687fec81 a16cef63f8c2b6c4ab0ef07da5d92392e7c1ef05e09baaa51edf07796c104a6d32aa4433c844a2d6da3043936afed8c1 +9ec5f7d65082264b8a50be772c44277a73ed19199eb275fe5976f9799d8629fcb4a59a8d55074cd2eb2a0e02062d3f7cdeb05e62931a24fd1aaf14c257944d1b42eebd52726d6fe281211b39038e52baae077ea4df89675d860d6ba5a0f998d049614201b872e134367acc90066ac602e478ac3e43c3ddf4b0ca0aac1a68591a 0050245c1682344fef23bd549ac8d1e8e44b2840c43eec1cecd33daa4e9ef6b53f496104d7432e14248682cfd6f5b4853b65adac 93c6d305d8ea0247c26437e0028e612468cfed16c024faacd2d91151109a54b3b9ea1d2eff8c6718f544f9fa208394b4 +61d657bf472676301503f6784b7286fb39fb4186bb88abf1edacb4a2693d0a1e2b77bbf2758c84f2cbfd1753e20841b1cd4b456400d53f4d686e666943f9b6ffcdb77f510be97536e9698fc84ae347d483bc8984548d1cf86b9b40d360f9c0dc5bd1c55868e26fce1460ba94ef5e94eb63c9f0776a0f446c0cfd4106d9f36352 008d3b0277f0e9fe54581d3a9499ccd7f015c08339591326859af969d2a26284e3b3beac4a0b74d324ce5cb5f38c7995e4e3a41f 80940c95b562636c39f4bd8fa92daaac431add26fb774110024ee1b1d0928aa2e5136f78137c17daada44e7e4d96c7d6 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B571 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B571 new file mode 100644 index 000000000000..3ef4b08ffffc --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B571 @@ -0,0 +1,60 @@ +8e14f713a2c427b1f79491033994f76acbead614d12e73ac6f3f518f2052a10c1273aabe628ab38e0d3d5f8ff254802e9f44a51367bf80325b6fc39d907a37f731372864747b10749ea5cb3d3a83da39c21a7b02885a8c1770e4397cedc958e4baa21d5007569dc9dd1e45d2181709d900a394454090badbd0cd9c2cd2369aad 00f42afce7f7b3d45f3f925ab29fc3882a89c9f585177887584703cf8bd8fc572e677adfa55b402446fe1e90dc855358d92c3267c35be9674b40c2ad5ce8dbe6a533c44b0ad8d2b2 a81673a4a6d59bf953a2c15067d5f55fb0ad5430c618b16dda412e1520589a5d0e5918ffc7452ce07f081ed2add3eef2 +38b60d27ff08fb191811036dbfd5b39e1cc3427ff70efb67c851e9cb407f9fac6f348d289df98d055eec73299fcac068bd0fd9ffa3c5d244659e4f714a58d79f6727f323a7ee26369000e90e34e106f99f5ae2ae1b64ee89e5a1d304ef20c071a7773e9b977ed3d49f467d300a881c8371041394910f9c366942449045568f01 02f36613043cbf53ad36e2b38998bb867503359ae082d07d040e5a10a43e06ba9c91e7c73308e41e2391b65e634f83b162cbdf4e7a44ad818fb93a978af00f06be06731d8c5886c6 840a8d6863cc57d9d4ea7321811fffc22c490e3cdd4430fd5e452f42eb081da5c981e27367ec1256c3c5984c7f2860cb +21709eeaf9e1953822294a478dfacfb205fc25f447a73a76a32601c00784cbf2f9ebd41c22721d70cdb3842dcaff4a4f208d41c0816990e421cc4b8538ac2f347cdd0aa2a39f1aa26ace8cb6a606b23f6244894d4594a0f6a5b8f6a695fd66e1a41e2eb6a377017177fec56bb58c837e311cd04c5b50575faee32606b9636ec1 02e74948c46930cbcd9dbe2325539c7dfdd910f309fd610e6599d425aad9ae230a8d4681970a14f2a71fd08030d0a40ff40dade7de1b06a80441bbf7e2fcf1809cff39c7ef88bf9f 94f1db657bf05c52fa8a765fc2fb2fd12dbd42d057d1d8d494d4717835818adc032be36dbcede385c5d3b084c1973221 +3a131fabf3dc97334f212fce41c44300440d16de1d6060450875f7276f53c026e2a511681b5a8d75fc0d578546339542833145f7ee13c708df33e584445a75a5538829286480d339be7c777c03c998a6d3f037b25799ab2d541021502a0b02a9b9c337a8b176c4f30e5b186485a6103b1d1563ad4ae73ca806a5e4daa92e9100 01b5fab1d36f6f6d559f65d8b01edba610620fc3a38307b1fb1c5bd63e7ffbd4a9098cb8bdf50975a873f5d047ee2b627b090897a7fb5f56d3f4a0f3528179e7c969926fc0d3b0e5 93f4233b6a8c0b809dd5c67005888b51929200282cc702979dca790cac9fa1fddabf40ba4326f4dc74e5a759e19873d3 +679d85a762f2574b0b31b516270b7d33d5e166c83e91a0f48e0f3db20b52f42f9e6ee9648cf58267ffe3b713723cf3df52b5fab5c14db1e7189f7cb7170bc6ec7cc71946745e152b39180f828688a5b6c0b2957ab94283b90052a3c6e36843c391aa8810f9253b639a8d5a69aec10070603ad7a99dcedb544858d057a1d66b89 0383e70c71b431eedd4574f65d01fb0304f7744d668408c847f7899eae44770a7f3243109740f177d7146a27748886b7b77ecf3792b512e8d8e37c3bf4ecef2b1253df7066498f01 a3fa0b8f4be29bec37a175b6192d121a5dfe3fd55b878346b3a626edf01e2c456002804ab76f780b6b28a1ee436c1ef4 +236152ad31ce2ffc0dead3c142cf6c770672cd2e75af4a82fda1a72e1c775cec9b481c6f3e411644df7e7ee901c501405620af4b6e9667dfd46091788daa95ef2c6c9f5c240c06b15cb0df51f5f058d8a7934bd7845f007a35f99fa97200b20f3b5b14fbf1e372507f3b2f377e8d07d30fd3e222f398f26d8f428e320327f901 002261d4ead21f02fab19bbb0da8c272286704c8f0c6842ba47ded121e5cddef79fb34e6b9694f725ca502949faecfb21e3cc062a2b4c654bd542d9a1fe8d97bdd0905c510aa0999 80b1e9ccf7e706ea63f4066faa59829563ac8c4d92b6d2bd0783cf8d71b25e7b46683e177e79fd719b1bbcfe899000d7 +ba3f02c4847fae035d747db246fe4e82fb9224ff9cf568a6ae548f5dc2befb2079541d2cf9aaa6b18c281a05e7ddfcdbcefb25f41dd91cb3092b3343e16985e91c912215cd99ae4a099baf628e33a7b277e3c36a13aaef85418fca99f64d73b789f23ecbb76c3095ade0a5f7f34836a98c5be933b44a94a2eaa3f99b1d8e7937 0316c78f289e1860bb623082be9d9238b88e38c5e978a868bb90f776235bdff4eff591877b7f350cf14c40356922b2b6aa51d64990360b2b0e44d6941b5dd9492b4f4e1f42ca163a a832fab4ab1192cec46d0f38c85ff6d53a9f5f78a1e313190485d6a6d3fdac8a6241e8a9174ea2c21f81a51225c4c47b +6d0372b40559e075af56af853cbe18ba2d471b0fc8917764abcc69102b03d5bbe1fc12458215be66409c26c89f67c72a8933677a07f88993af6918acb074fa915fe883b24bc3d191ff1b08852f07eda98977e70eba072d8bf189cd545230f59559ac05f1fa3f4e65886d0bc274a6e02e2399812b2bf91abae81e21279c5de996 02c1bc13f8320d97a82f3d9354e195481902214e16a4fd89332a0499208e91d50e5cabeb4927ba030cb42f5bc53b10f500fa646a8c88508cb0d63ebfce5c4bd574c527d686c735ce a846decc7f52ea99f449a6ffd732d3ee27d6df633055af2a059015366012c9320b9683be936d156c5105085093cc2deb +bbfe66c82bc060bd14fd0e40769d9b3a026eb447550dd9f118c30d8448f725f8366edef042447962ba7f7f833b9e9094d0ff600714697e632626e7d12a592e040bdcee166dcda93952323191021bd12f3b1647d0f25a41739994659dcbb19333ca30f46f539c6f0a5c354cda8969a1eda572a309950c84c7607eb8ac20163912 013bd80eafa67663e75d7ae139bf285d2b9f1e03d8e32153c73e26d06e86d7acad22bde9f121a3f1ea674dcc1fe67bc7f5398d5e92555056bc046a02b0ba86c2a0dfe32e91add5b6 8ba528461e583bd85b77a60b6f9c71df7dbc1ba80ad614f2198ae75a976abcbcd60d0bc248b870f3d21bf90e1f608a03 +b35e9bf686717ce3b16a59963a32a2116130453b161a4e7ceb27b755856add836d779696edcaee3b5c986523891c8836109d431e55c23afbca022437ad19e6777efabb6da3bba1f5f44f905395b4cc7c9210590fd38da621582d059598e5e4569e904358e0dfc0dbfda4ce75538aa97480912852bccd433a9b96c9c66e9597d2 030834b0a4284097cdda2ada6947c6c281f7290a49b56becefea1e2788ea3ef78fb96807633c47c25138341768b241164ce0d42f7301728b928be2c047f2eb60fc2f844ab77306d2 9496dccc27ae1dd2a1934cb3dfcaee2966e9cef55a208ef3060810919fe9a2fe25cd4f99b657689500c1aefb397ec574 +57b5ae7e95c638b258d1e09b3fcb4341e203f5706862e199b103c8fdac72cbc5155e5cf8b300a0b3fb0ce1f897c45f7aefcc528182f73dd450cd84d5fe9eadff3f704dc2a01b4e847c22df430efd1c66b0199f3e5b59348af5386962a5ef25204fd230b54d58d7fae801c086f8f405d3d0aa7a9a9da15c22b868817cd897d853 00c81a79ced1eaaafc31b69a40d9939f4e484d625db6364a8e589b6b4d336d458b44287ea6c6aa7661113fc07806b147ff98216fa0c08708dc9d651821b922741deda522b4e436ad a1f6a739ea4e4252e2c196c8b666aa2a3e2a98a74780935cfff36052a02a8bd7d2f3fb29659905a56876ee89ffb0d56c +daebfef74b452f039c999ba0528be3bd9e16deb5f46f6eae87b63db8b89952c949fd7db08311871eb2596865eed107aa065f030226ea675ee3256c31a3f85ddf4c21760582144e07af208f33c5f47cc026db5403186a65a47940691ea2d74ffb1245676260ef5717dd879d8b5b72d96f87fef5f762d4fd17454cb5ed83d8a11f 02f24670c0f77d2ca0266a743023d2c7413d56d0b5ec77b454ac59087efc4ea4d46179e10278e4ba416ffd8c3f9786ed202faf8251c0ef5a9ea5371fbb35b7afe3d15a9cb4bad975 a7d551fd513b146cc31c57daed413da34251ab75d461b26e0736f94a5a19e28fab29ab6e75bb8d99451b2b7e66fed1b7 +62af0493ae79d71b552c4647d1fb7ab2f282a91cd44aebd8ef344dfd77b521b0c0a3f72e4513c8ecc0e4b84efef3df9482a07ccc1b740c571c5e69cb913740a792aa231b9dc87edfb72bac188293c6c6e788cb3dff32e8f483f8f34e21ee7efec71302cc3bdbfa47908a135f6ef3ff179dcef26d1a3987f7be967a6c0f799b0c 020985f2c6fe3ea04bdbab66a8b6167e5969c073b9d53cf3c77cebbf73f4dbf75e601620ec9c3107bf3fbfc6c79f8f063409bf8fe1d14b19e323d857e23dc05157d270c7514137e4 ab923afb891b3e841069061efc1a93647c21bfaf0cc987a33f7c64ae695a001be904b392652df8605db29ed4fa9daa3a +566f17851951777ebea3f8285610cd8ee5f882a68e7a4205e6fc9e2d66d210ee2505ee73d6503169f7b903012d43e7e99efa493a8e6ef926b16b9ad8f52156840ab561fc6b680120a88714fd66d1d0742189bf06c155e1138ee5314707173f7352e2cea0fc26e1553643f2490428718e44afd8372cbb7bf5b88234318ebf4355 02b3d641607b8a141f876f6d285ee46aea543880e772dadd5dd83d595b9643191d9597218e1d6adb081df133304037bcd2c05c24a54e6c4cca64fb2cc4569d6882315360059496d8 a325a7c0c759f41cd991eefc82e00ccdc8288d0289946390f14a39d476a2d02aa22a5b03a2b559bbbb19d344e811bf67 +25155825fc4f9a1c4dd1db837008e7e2594a879052431f5bfc76d0d2565b8fa726008befaeddceef73f3c60fa2cdf6d9a70e56d27210bd013034b38861ae49640ef208d3fe294ac4362f8eea44f58af3af8a9167a36b5acafb7ec95652d5885a0e08067ce1dfbb45a0c89ad1acb53eb404bf88fa5c3c463a0f912b5a2522a0d9 01afeb5ca87c81025ddf09c2b2c5ee22ba0105c0e619b67a324467485bd839030d149fee44d8bac6f5902a1245a50c3437046b7c89a84116b2147cddc645b6d2fd24d68e8d53bf5b b7156a43c9d78abce342629e305093c433208a3fe97dc6e4e7a5b51fbad25e957f45b5f3a9d66805dc4877fdb793d73d +29acb0fca27e2a10d7b9e7e84a79af73e420abdb0f80dd2665696638951b52dd39ca028166b47a3b6a2eaeceb1a11c152383f0bec64e862db1c249672b3770909f775b794e0b9b28a5ec8635a996d912d837a5f22471b40ec2e84701a8804127a9f1a0b3c96ff654700bad3167240c2518fb5dedcc1be9f56a807083e587bc56 032c97639b69c7cdbf419286d0a1b406d9b1f2886521a8b979a36118d2a368aace5b02dd8c515f2041e6fb9f026d1e82e789dc826a56d2ef732b1bb0f49be2b696ab5d3d5694a2de 82caf7ec98eb5c6afa4b7c8beba4ddbdfb99e94115751a688be7e119212335c3eca1698acc56671210c08858132f1893 +c92d67cf6536f5046e15b02158da698bcbba4ff1e4e9e9c882cda67f817210402ef917ae93682c9c3dd817b21b73c6c00b7bf92ea80ecbbef2e67f4f4379d078a2b0f297742b2bb9c3fa3297a7e8079f488555bd37715eec92b4b1cbf897640ae8a1d2a0fbcee5423ab31a37629f98630275e35094a896cc574be0a449bb1bc3 00f93672159276c5a293582b9f49607bbdb970112f6c63b2b3b5d32ad3c8240c86b1af13a8dff6502c6b6a17712cfd988f8cd23a60693d64104143b3f91adb37f852e9e11a0ef110 b1a24e24e316172d3d1a926dc565288cd9901f82c0c06a1bdeb739698351bc4b378df4ff9437fab0e2f41ab6c94b78b8 +15413f614c4551e3b138b64f66d15f8964c40326a42b0afce820778eee4a88edb127fbf575da5263e5a2627b5461d311813ea868e6417615e7c4938313675009caac28bc7a2f4c0bc37572d9bf36a3b1794294e09c0121ceecaa4b916df45b0dd31225415e6c87cfeeb092a008fce2c543cd62365779ae28f29fa02a15d9dcd5 03db080bc99c5fe7e06d5032167af56783cb423fae59fb5b3c6bce5fbedf56b7b39b17810e48ea9a172881aa1f42f5e267349b60294d4a208b4437666b44abcfee5a1829e9467908 a9dd22a256dd951aa7dc5746c667d982f9186f8f849bf111bd71f2ea81d99eb43f119c778621d42de59eb5b6993c44ca +9f901557451ae2f8ec79b6d4adc794cbfd9b2e6d28f19409532d91682820205308b41498a4e1ca247a2baa8da93de95e3c0f7afd6ca46bafdbdcc6d3374a12684676a50988b86a960a82180648c8c1e38f8fd9af604c7be3be4b24799f4544ac96d6360cdb83d1d0847fda21642934fd6cf65385b50d86d4656987901fb88d0c 006ee767f6f36bb8f364f324d8346455c899a49237d759003dd52cfa13b9baa4c71347b134b24ecaee32d247c34e3787a0c64bc5d299b55c86f64b47521d22f2c09db225b0c84cc6 840aee358dfd6b4b1c268599633c5d09f036ac2d03e6e71860d3c0baab0357b3c23c240644d31d130fc5215e2e3cf1cc +959fe5a19d7aea2ba611c7203e19f8e3f3cc101e03a98f91adfef602c424c580d5a868659368a930f9883d699fc633bd07f6cf8de474937db0bea86fa7cd140ec2f202663813033a757b93bd72afba15be5e47a4eb93e8a666aa1c72c241ca3922547d63fa3732fec54afea7ade84302e2f044275bb67433fb6b125b7913143c 038e2571d9f22309a636586d62863ed67a70538287f3ef88b88c3c2fa1a2900d48c342b6f15c26b8e7fb4875cda4093b7de7ceda48fe1e2cc2975afe958040881de61f309931e48d b708393cd940bd982dd39ad78f5bc06997e0c88a08e17e39218a23b97f6372a1a02f8d159884b13c02e71298858f24fa +97b9688d9ed5101b8cfb19e84b89cd644262ca1c7ee18944e29ddd3b4cca78e06338b270385b00a5e8b91ca5e628de3bba50e36ecc695b3ea737a9cf8b36871c473a54ba17819f49e730c0f253b0c769aefa6c16366fd2dd612f330e95fb119fcf3bf7f3e254438c0ab635ec04a8b2424a05b483ecf65b74a93636fbab7bf1d8 00c8f5736f1ae65592f3ca850f43d06441aaad8c03820f3b08d8a6db46488dcfb828459f8b3f34af73cce8dc7a5e3834e085a64523d890028e194214cef4003210e6eb530005b01a ae6288c66a8d8ba6d710f6da7fb32ca5c8e564fa444474937ab83476391edbe4db5e8bd085039b856ffd26d4490fd4c8 +f08b250bf4a3980cb455338b3f4173723b3f44c97bacc9cf550149794a71426e398cb4a74bde141d8b7b4a72942f1c069676a9918e27792cb8f085ee037c78e3c468adea5123c4c64d8ca6a39f2f90140c5d2d80b669cbf0d1ccb466b18ded83a1d5f042c36188a04111c34ff769abba9aedda40a87be1e24b700225e2078056 01ee68c3994adaaa9e0d61bfcd3bc1cdf198d3fbfe28a44e5dd518867ea04b20e795eadacc48bfcf8e8216dceeaa069b756e8e99ed87b6b1d31154cc9310bc3b4555162a890b0c6c 979283fa3d1cf1a2b8fbf9779c4b3ae7d16d7694b9fa5562b919fb34a92acfa9dc04be00ddc7d42d8057ef1a903b44b1 +1cabd16fc29d7d919622810dc8b23c770b790b98b119eeab1b20900fa94fc2ebaf76be4f5eea91fc5276c5621c8677d4d117c4a5a782ee2ca1d5b0db997fdc8a05b6b3fbb833d7a7b81c3c615c2a662929760a96feefcf89e46b563314c9b77c86bf34438458b43b694ceba741b97dfcdacc0ed57652ae62856ce10ed2690770 03a6fbf66ebc1365ea7699c72cdac2dd85907ec59cd26e2d18713354b619ccb83b7fc0db9193aa8493c1855f1a83fd987cbbb65de17c59fbe79256aa5392f4eba045346e9ba26592 a8614bf4351ce30cbc7a7e599cb7cf75bed776e9cb808fe4febd98e0b5156f2da708d4d593bd1e7b9acaa5f81ad8a0f3 +7bc8bbf5ebeacf40b3c82eb6eba5d994dcc6a3f2e12ef741f90f90e176d20c21e006ecdaf14cb5beef35bff46b2c374d9ee224516679b1a9e9255cd8ad8e60ed234f8ee7e0fc53c9021488158217d4b4369cc597d6053746efa1e73340bdd73c1bd2eed57b92426fd4d278d6a86e8be0f0a66ab3dfadefca8831b2f488636251 0145748871a0b5c1cee628de04a12fd68ff2b154fda96e47afaa96389d66d22802968584f6753d36618d49ed205260f09d3f5ccc2b27a34390ce58179b9834ff92a86d66ea0a97ca a4bb696d63e53c6106414ba0dfbc126250fd712548f9b3a60d10a664f1a65514867c61b3400ab088a5b13c11e39b75ad +0cd2a45392871c0c262e7e6f036946354bb41f9c2187b8c4d399231280682f3e0a09731fbfd52c76ee63b9828c2d731f4cefee0a8c46419c398205b2ff80c67d7756db300a0a8385fa287dd37d9126f75998ae1cbab5136560592118db52fbf102b7ff0a1ed45b8a91a7d99d13a0f7fd4366392264aa1248d7324901467457ca 03c71911d24ad19c20fc1d8a044d63c9bb417abc3778d7e6234c6af79b898cbfc2f2787244708d2fe203be786edbdc4c9b12b413156b7b0bab0be8af895d191d853cd58aafe1ccce 8722c54b0178ceb7b0df26c86620c44ea38c4ed2d182477dbdf3b0057f2e2a554d0bc3c918ac29d8fbcdb71383a95412 +e97092625b09c9ae6e152e1cbee207d83361f34cb9b0e727c816a5ed851f12f91fbf88ad9d4c8f9d07350f5d828fd8574eafc768bc72a2b18aaf4d2b48fb10f7c3431137b51850154de9706487d69a40a8f4cb2c799f48c5d8f518aff752500de93cbb94ab04ae1e0c7183a32d79a27291dd07b5fb6e6a4fab76e85c3a8607e2 018bd74698bac36ef11add6b3e3fad227ecd868f370ec04569462565d2f0af2340bf793486953a7b79ab04f0ab1f0e4fd16bf6b576cce677d543e73aa8edb0e50372f24ddfbff966 b457949774acc4bcbb6d6bd10319401cd483a8e05984d5bd928d4db24e35332a16732cee668aa4e4d8f7d021e5f62622 +ae6723b8df5d6ab5fcfaa22d32fdf106d211514cb1892c7c43ca6cd85c2532f85929c8a259ed251215063cf92e1502528d1e22d5cf67efa0b8ef21e8eb2f5dff881ba1433e8bcf2b6af8742ecb2bccde081e534615a305562cc22d3398f61f277d8ca785842bda85d8a40438d9bf1aceaedcfc22c85533794a69cfc320931d3f 0335699bfd058ee2e6163f55d1816bf3669acea8b73be9c4ddfe775230925e6093cff7a66813adf22222c8376faa106d85ac9f3c67929bc58d8986795b6d35d5b9fa546dceabbedc 86781d582f1f45ec773f7f6634e0528636b28196cd8a20a3e28e98d9594178e7cea401dd5a4a3af8e2b19c26660ebd4d +ee20c6b61886e02ed94359dff3559522ff550ca126fed4b2240ea7d999a182b7bb618c50528fcbd261d5e497a991fbac0cf4c105c0f664d6a00a9001c1ed522962fb44dd4159677ce8f1531019f86457c055c9cea6247086cdfe0442485cbbc4386ad002b4bd39a1a187752437f04569705cb7adc0c68f0fd059d946deb63f0b 02c3eaf801330b3f1b0504f2399f1d24455db29911f750c246ba0a134c3b59da8b3562911197764699a92ea1d95a2aac587e24f743df1dad3e1cf7edf955203e24a0225717f8d2df ae42768bf833b016d1a4fcd0e6f30857b7d1aecf1a0c59316f25107c26f61ef06a0e1173bae1a408a60f885763b255be +734a9eb8288e32f5a67cc1d88704523ca2c68b798d90e188d871d9f50d2da2063baf1ee6685c45832a1818aabc9afc0bc935e97969dc983a484f16d2bedb3c7c0b8221408be2480a5562d5d1e5d8763d1e474bf2826aa93a68c3b870e3bf34f4941cf590d88e1f5a8cd782a33992213f3f6b4b4f6dbfb3c3c8f21f5eaf4ef609 01c3ff067497e5d387f31f0ecc9c67b3c0dd6ec8c81318c492aad83c9dec6c99e4fa47447f6f7082d636c2591d0df940b947d0a4ae3778e2b7cc8fb92214638399def894ada276b8 b7e6bfcc31c5d30a34e7b49cae6e03595959e84683901795ae91f2363bc55bca3882e35fd7459dc8148ce194ceb58df1 +68e27cc72fec8f3f1f3882c6efa08efdf21d74d13be5171da35ef2855666ad2ea6919d21dbc1cb6d296663dcbceeba2fe47a2c6507d3d4a67a61b55b0f81c93412d7e1fbe15a590e342a05f55daa55f8591171303154e615e81189a523b855829a5c96621ad118f522e397e2eea05c2603eeae6e3591215e29b2289bc384d8d4 004b4e04281b210fe78d516a5b69f878b7fa058941ee9ae8cc63b061d1eb9e12c3e0ecb8717ff4623ff5bbbcdb53c48adbd9c69636506ab929c5507d7ebafae5654aad65a263e48d b55a450bf5c921136ef8c8e26de6ec0310f8b6323132a21e718dde203e1840ceaf9831e6c9d484c9a6ecf31014e97292 +e67cecedf35058b80787589514a9c81c6b9f4bced4260411d2af75bc46b8b2c962dc9d260dc99ebbf8ee64950766efc0e394184bdc8e2891d66bd3300ecc880e9d6a3d0eb615322378afc3dba89938704e9a8d0c949d4bae9838805c00377e3fe5ec6a1a98ad7eaaba6b500973dac48b26b7fb2e1b9889f8c387de535d4b2363 030f2849a713aeac95fde5ce3af853e9d070ee60709eccf35a076567be2c43f0fa34420b0fc097ff577221275a3a56e759efc32183be2d76058a7d20e5dd59f00415114d73a15b8f 93bc77cb116894b17d5abb8d754b3401a6ec0f8de02ece7ef43e3a61352cd1c14ce3c6f78e4114c1053a3dad85fba866 +2baa1ac3f07e34b67b6af087400f261e138b070c8475378063286c16fa73578303380236a4af2484ea01ba56c1c619f6ae4e5e6ac2594c8e5aae7e7f196f96fc5d0f507bebedd4d818e77b9120e5b4bc01c7ab6339e88b71d0886631cc7fd89659bf513faf149c61eb14d55060c8dfc7e6e4c2b4ec8edaaa6bc36eca50a6feef 02ebb73d04e6e5361e20629e3ad119b33db5163ed91fd9a8aec4b774898784b6822a08992118a8fe6013094bad0be1e9bf01b27c069e4335bff7e0abd28a10443818f6b825e9cef1 b5eed9392d06e1203f9246a167c2bdf551ec26b744bdb0bf6e073d0ad6593975c0faf15994b7df44117bcd68666fd706 +0e640581f573068d8ebd2899a6aaeed0bf987ee11e22b05d25e88e9a1c3451f45ee3800d976f4603c18a041febef07a01086832a6f7ecd5d498d52e796a9d90758c87c36f4a5b704a39c456aaee2d5278183d5815d619c193da9fbc427d701bab0874bded848cb4bb066f56e119b637c78aeb6eaa387c41bec6cdd4bf7b2061a 01bfab717d6f6e16d9bc6e89d2ffac7cbe0f808cc8ca2eb515af7ecce5f3b230303775710a21bd25c2cc4566bb53c78c78e3774a9f306c751cc6e149929e45eef60f56c1d2388c6d 92ac597620d34b155520b5d1a18a36f33d6c6eca7d2ba2c239c9ebc09a126b94bbdf3ad6f386968a0e7ba07cf07dd444 +51a2a560ba226d629127ce1ea7e812219ceaddd23561256331458c9f11fe73990f21d0dcd974a3773040090cfdc8e0f01692d951a0cbb60f8448a016c67abf46a9c150466ac77e656ea827b0ea7d1e77ea32071ba8314fc8a2edf69008f498bd1c18061d7d00f3340a7e2cd73e9766862378d8702e804a1870b442beb2d0aa14 000cc53bf7f1cad5e3dede4b4f4b082831604c92dd2b147869cdf1107259305b1d50359647f9f3d7d4e1e608865c65dc7c9ea46bc324dcb8423b554dc369d621743cbfb592b70eb5 877835ea371a059e98efe6433039c3f42fbac2cb3ecc462ff3711b4b32510650b43e59b2317dff20dde7128b9eb7b5c6 +90eeecff0a2e37df318c441df220dfea013ef29774ee92a56b213e13a798858f31e52b6ccb7599e7314f12b48a89884b113c1ba0526a54f3e9a33c940944319e084bff320cf5f391c02c731c4c4f8b05afa273374a1705d6c85337782ba7d36b9c00767180cad6422c11c581672ff631fa4c49d41b02481568ec87ea97220400 02b009530cb9d586e35dd8951ccb686833afb7a37ec253e547e85b253ba999f0f186b6d4ba41091615fe57678e9801b4dc94fa683511da25637b2acc9fe60936be15af16234c4ee7 9145dac2fc828c16cb914a820969e6fde0454ae9e0bdb31041501e87022efe2a4fff321c57c85950bf0f0dbe9cc6111e +d3740cad41e2e365d80ae81da97fdf06d8b6c278b505e34cb683fb55ddc5189da543540914c0accd405dbf0063f6222885fda4b316dad4a83fd03e8d7b7e936f87fc0a5b095defc8a4b22fa97f00b394e672d5efd3e0a230c7e44dfeebda88641143502a400ed62e2a51f9561e5d652a43d616f16699e875deb9610c77de8e1c 02cc2d0d7189cc8fb3565a039aee7633ddc00ff427cafad32fd2010b10fe249c9724d91785e7080203626038109158e3a61a3970aa3e51688aa7f5184b22f63af63f80d3540ec023 b0e478d68670e976e4884b5801c5226a03956e5c73107d8c2b35002bdbe723abf77de379b11f69290ea5921026c069c9 +5eb53b5f92121396c5ff30e0c92da48db4fbbdbf27297f9bc82614ab78f7fd863e34096c615a02e349d8bc7ae4b0700130704bedf32756b5ee6af10da1cd717d624fadc57a9aa6db4a6c5d6254c0e8f8c3c0d4d03c264eeeafd52cac2c1968d9d85b106167a49d0ccdbefb20bdc10a2555f8149203af52853169a02db94e5e2a 03d8936c00c131e38c6566d2464c4e207c878070bbf681695a6cd98cab2c6e80fe98cda80c66a5cf584e90a071144dda59c07b8fc7bb42464dbee5b6f739b0f2ee5fdff7e5a4e7cf 8f26612caa3ff9cd7c0f5815316ebfd95d9abc43afe7866f3ed49c8dcf85eec9bb48887adccb6c994d925ed4ccfac154 +5aced64f702a57ed7fabd045a40c967a485d2a70b0a5e82561d5141ef329469b2da5964a34df203a980111a77adca376c643b9030aa74516f054648c1534d912ea66582adf3c655dbd71ca55e47412315df5e2893e43b2e2dfe6e4dedf426f11846ebef34a99f5615460ce0475f7bc54b4a4fd99e83c982097c3136ac6188a5c 03dc7de970bce28a943d7599f2a9010fc99435b93bc4ba884d42503ac2941aa63fd07db34bcbb1127d56d6a4e277d6ca32051ea3467e376f74f98c3999d2f276b282ef8a28cf0cbc 8f518aee376514d108cd38e74ae2549a32d1ef965c50a4dd63ca6b88af1e04689c36b39069eb8dd2b1420e9ca1113272 +43c24aea343d4e088bea25be69a332c631275c36677093e057de69cc83a4c5e70ab270e5a8930f55846f1a22ec10e03007dcf0942c6761e89c65c6a4f032eed97dc3a2c7f7ed1e82552fe48828a132ba16c41f6bd82a49335428a24fa1679522000e6a1d12c646e0e4b4c584398577ea9493bb334fa3cee8bfdb6c2e66f46436 02de6ee12eefa7a4a736484b19b42a513dfc059a060976edc3b0aa4b50e98d72df6506fed0499ff8480986748e938289e54a5e86c0c29733a9bcf5985aa63d8a2b57933a04a8e8e0 b98660eaa2bd643d8af2b0e4a7ca918e1a1dfc410b02f9ce0938e0c91eed72500050207946381aad02cbaca5746df7c7 +e89210565959d93b483659e62cf41f0a0147ea23890c2f1a694c377a826165e363860e4b084016cda878a43eb68465f81f397ecd50087a25215ce7c4ededa3552218071fa3acd7ae380655fc8fa884998209ffc8a2c26f1ca19dfcfee455dad35a4e72caecd8da47eb9ee21b889162f5d3032724abfd1a31e68612e18bfa9006 005468f0df2c9854f5f655743e79c750fd8812db28b096d97207bae7f5aafc6b6090c9c636ead9e0fde32a1ff8d539b53813733ca812b41b58ff85a941abe4f128d59fdf9847baa4 b375d39635717f36b5296bc10603534478eb9f8cec53075412a05e4c9ef61d0bcc78297ea55646014788356e3222ff3b +48629ec97f56273599cd9903f8a84ac2ba74275b40e1e42fa47649568babe05cf63c8417d828251acc2eec525b56dc9082b68d51b0c2bbaa7389fbee15d058cf482993b2bedc5a9101f1afdc79989a812478245d191550109fc17215679553c508c84e3d4cfdea377088d09eb214e6f92410facee4790beeecafe72b2e3ed192 03d3c6a7ab9450c94aa3b8a1ffb678e5b647af24cbfd66ee3944e6f264f406295b803767471fc67936fdfed1714b4b8761a07eec86543b7c4da6bd2fcb33fa8cda4077737f398e18 9993653d85806acc3de7a452998131d359e8a24595767d55f7f0087050e08256f5424f8209418fdc02ca6ca3258844c8 +aa3a9fe467b1ca638dd0622c9ea235a418b39b2e15ad81fee01b6892b240783d8db3c72e16c13df8016dac6addbfb85232158325bd7432fca3b8bf5db3abd0b4c5ccd0999609dc42199ca4680692a0805cdd68108bcb493a558ab507cec0a2782a9e976928985352edb2abc0c07078b59d2fd86fda7fc76cfe573181d934c46c 001ce010ea8e6e1a0c26ab22eb90f0700dc73b232c429d36371e68e429792afb7223f10327708bcff779ea55fb5f22ad87aa054e84d10f5450f1bc9a89279062ea2173f55ab0f76c b4de20d5bafb1c0aeae095e742fd4c6aff1700606309ee792e70cd06d2b8f7bf26ab0b0e3b21c2b0a3746a4b49596bb0 +6c3937014361799f1461f652841b5137eb0dcaf01dd293298d002f27e9a770b9e1a30367e35c04603881f0c814cf8ecfbe1619cc49cd516b1d60d27de37ed52a5e1cc300e2face4669f308ebe6747255a3d386f16778e494a7cdd10b45171b2bfcdabd91b805bf24857708c1b75e368edb2874321324f83a19154d3a1578c767 01e7410d012aeef02b3723346d24ebafd684c99087ecccaea1cf3735d52c4c81dda41812c09f1e874dc964d858ca240a19963d5dc89451f5dd6764426ae41cb23f19cbfdca0fc562 99cd5ef931f3b14b2dbe7bc8f1e2d74a570a42747c5687e8ce6386b75bb03308581271eaff8321ad692652400e4d02e4 +12fea55ffda15db902aa6a4388b9807c89c193cbf75b5d2a4c95206fa43dedc45974c80079933451bdc5b3ea015ed3ca2c54156dc61afb1bc82adefed1491302a48b9d3d2f474ab45343c611677d360515b93fb36da7a1c1b2341c9cce185c881c0beef33d43967134a190c09034ae3261f3295b79aebd3fe123616f73cf2089 02139839ce38eb879d266065dde5e5ea227244323b330e3ad5a0bc690f3c210f794cf18f0d730693887548bfbc434f48ee10ed34cb41d52172b06e448df938170a5e17311cab8e88 8661531f2add290ce4e6b58093022fbae6e522e7edcf3ad48578f0cc8ea2e6c7e2e22663c17a18f7b3b3d25d9744b7e9 +c8395546842ddb545d8ea3db4efe970453dcb06025ac3b7a25aa5ef62070f3021b9a1fea91ff7055b6c398073e7886a6f71afe53c82c47b71377dfe291972503bbeb25bd477bf0e7adc8a5d3f8b34ccd0080d61e121214e1b29802b711cdd8a6bb2275a2395c467ec2c1571952992e448d736d8bd70ee629c75b5e32b8323a00 0274f70fe69e4dbb55c5d404e39f5196335047113087f8711f2f67f2be4964e4fbcb865680758df1c401cd677b0971654b7a6aeb7bee0d6d80ac0de14d4f46f356b2d5545c185aa6 8209edf0105e00333c40510a920480e6f79576a2537dce211c1567b99c46f6ba77c849cda5aad03f0fbec247a924eef4 +10d2e00ae57176c79cdfc746c0c887abe799ee445b151b008e3d9f81eb69be40298ddf37b5c45a9b6e5ff83785d8c140cf11e6a4c3879a2845796872363da24b10f1f8d9cc48f8af20681dceb60dd62095d6d3b1779a4a805de3d74e38983b24c0748618e2f92ef7cac257ff4bd1f41113f2891eb13c47930e69ddbe91f270fb 003e1b03ffca4399d5b439fac8f87a5cb06930f00d304193d7daf83d5947d0c1e293f74aef8e56849f16147133c37a6b3d1b1883e5d61d6b871ea036c5291d9a74541f28878cb986 87d34176533db748316a8e1373cac362fa719ce026f6596e4ce8456a91aa163746958e5c5cb22698e1722d3fbc92f7e3 +b61a0849a28672cb536fcf61ea2eb389d02ff7a09aa391744cae6597bd56703c40c50ca2dee5f7ee796acfd47322f03d8dbe4d99dc8eec588b4e5467f123075b2d74b2a0b0bbfd3ac5487a905fad6d6ac1421c2e564c0cf15e1f0f10bc31c249b7b46edd2462a55f85560d99bde9d5b06b97817d1dbe0a67c701d6e6e7878272 02e09ffd8b434bb7f67d1d3ccf482164f1653c6e4ec64dec2517aa21b7a93b2b21ea1eebb54734882f29303e489f02e3b741a87287e2dcdf3858eb6d2ec668f8b5b26f442ce513a2 a3fa86c36887858bb35fdc888f49b10e80b9b8b63d3315d46b4bd3efd4602cf63fccda0e88074df87c94ae4de6060274 +ba6be551bc60653192401ed8ff9e1acd9013d8811a7a1389528bf07438366f5772cd7aedad010c19c47622cec03a4d35b8003b39ed901b720629ab59de55a03c1ca50a62987f8da159e356245df58d5ae1936e65f3cd3acbe03ad1d0fcab4aaf2a7a947549ae776772201efbc6fab1aebfa1d99994d4f43dc28f39c0f279b992 02a69bc1df069c6e89722521a63675f318252be629e7558f3716917998e660ac960b0b750562846fe6c12ef492951e51e224754bab84a6eacd4147a5f26ae85ee4381bb14ec2a8c7 851c105e8bcf1d7095e25118d4919368745aa2e6141eef6ecd9e5279872786ff585c7009b70c64aca1b185d78cf04e61 +295720a79ac8201f40a66b06ae5d970afb15f36582897eed25cd92edcd00f70ac8e31c556eed4375ea044c2e8b227a8e02c0a3e996c9272d52ac7b3ad43b80f217295dddc84b177cf1e800ad08bf7fdd021fb2f49b54162092f8d628679c4ee335abbc90c027264c8b288c6e16eca3172eaa297ba50626b00fe0a0ad3a9dbeeb 00d11ed1b78b22b3420df4ddc4acc7c2286d9569dd6dd88e0fa3ecae69bcced68bb81bbb4ca6e9b54e67856e7fdf39155aa27aecb9cc827ccb9cdcf9ac633561b27d8eebfc261aee 98e5e9c66df7483662993e76a80c957bd3e4bfd082a15a810a6a0024a0c0836b96ff6521c3f1c480d75db308090017ab +a9cff41c6dfdc4a12f31dc375a5455950077ae323d0b7a3d9a8dde73b76e9d7b94ddf9c88ae8e6c262d704052ac47681fc35adfc56c904baaa6e146eb653984369d76a85596cb744941aa7b558c945ff2e81bd5ef7f00ecb4f43af23b4cea3bd4ba7b1899f1868a0c0ecfc62ccb1d588955597ffbbaf34cab2838efc2b866669 02c36ef754b5bd065e9eadde684750acc52795be80f54dd3d7a7d743d968a18f7e404bd71f8a76eb0395f396df5a7c2ff7e0ab6de35df34282fda6ee01fe5b9b68ecb4e378dbe32e b5485b9f432eb5c843145249af25ede20637f4a82bcdbce17b44e8b5aedaf4200460eb5553a8a8b3056aeffff79e566a +efa6c582d7fcf5e431aa89b3b00180c0e78efd7ccb0384d90b80e59a115a13e55001d951528c42860132531c9b8ab29dda7a657c53c2ce96fd85549f6f1810e121eb89961295335eaa0e40532d85814a4206e6fffdf9bff76599da9b2e71a22ed572910b0e3bae38ad72c7042579f106739a8628dea5a745168bd918736e488a 019ffee50be5496507e3ef5c40ee88a49625e46d1dd1686a52b09ad4a8e3ee9ef364f953bfcd97c52104eecb6138067192997cd4ebadaccb73c7b2560879289a46353a756b73cc43 94405ed1cb0f6d01536e0ab829fb9416d302d0b8c31712901f6fe76d087362c4f726ec4fe038c2855cae901a4137be66 +211acebfaf13bba33a9dd16722ec53baab92a140127d61372cbf1850f2fc894e942e25d780778235f880743953d04eca7a9205602e388172aec2abf35412b483490751f93b51239b6701cb0aab14e5179b0d7f55d8586358381dd83e3e436bf69a6820317d1701750cb1fea1293467ba589eec5f5779c2dbf2a9b8f28c4dc239 03129e96fd28c4198cc5242c1e3531a3979fae643d527044e98d7721aa56b5b4b45dfddfa17a4115e10a2b4f46d92f81cbdd7e86e588a4c6d8c2b3a83f54cebcee1d1dd33e85d81a 87f97f5a2a1e1727f401a34a2183e0625a1e5231aeb4c572ae02ca10f221348ec839fff2e65dce601136b4ba25d50f1d +ee592e20e0a45c18089c2e41460e65a7d22ed9714379f095d43a308bdd383128aaa6fb24e9d35fd28fc95c5b792ad75c980d2cdf0f460ac60b12c5919d3cb28dac4d488196be6c2dfe462b1b0ce59f8501692255840f5215c0fd8b74b1996a267a5e3b22d2841cf0a0b6315ef4ec7180f1c8494f4c07d5869c01fa2711739efc 03d723d2697cd07dd8444f992f2ab4a063db334034c25ea9be99fd7a1f495e3a644e5ea033a41264e0d24a911e55741d0cab80a0bd678eaec2bd1e60424d4491eb86d664900d907e 8ae079213120ceea2da2e906da13b7cefdac0f13d3bd255d3640be3193a38ebc3f4e1b2bea52c2c3c1d501d607ed976c +fffca41927debbd53455821441d9115db99fb31bfc69752a382f57bc7abe021f148346ee29e17512c64b4918ab2391d12d6e5643bee6b5682885dc28177b292e23a37ff99b359b9cf7578432af56e0ad1028a6cce7428980654c145af8daf09addbb3be11228d3c742defca9d3b1667f48c63091fe3307ecf72667b02e008f24 01999ab45d66cd1d3a0fe6aa43bf5ef1e2a67637d53674f6fbbfb9b582be91fc42a12cdcad94b50b0fc7ac55030de24a0b99fbc4314fa743ef4b5198bcc5f54d8b669fbed78e2e91 8c5a9562f327582ac087f033a8a73b189e484d2aa6603947a3ff133e392a1c515767440ed7eaeacd979fa1ecc920e397 +a2f71619ea04f7057e6943c2cece8594b341ec3b96c3915d924f94ba13fd7aaeed41ffa0e842ade414784f1ef825fcf2dbcf7bd8263b802def45f94de596aec0c121fc06558c7bb06b9f27a9bf56c42090b5dc344e82b69c4f528d33be166764a593483f6fda0cf56e6000ff363ba220f5ea0ea2c3191615c7ae3bb4fa575324 02ce1cae0716205330d730e6bc6dbfb6b951dc83ee3b4a7dae75d057e32e8a46e22be75b5f09135452b29c34dfe81a9be2e8dcd243fbd946a0ed14a832a7802e20cfe1abfd3d6e4b 8a4a57e2e502363d130d15d22f297b428554fee43e3dcdbbdc9ff55f31473dc1448b2eeb206f75f9e3267dc86ab15a64 +b60415a831eca2cf60c79a334ef2f327a76d290846ee588d5d33d0a826bb0c7ec3e11dbb384a7f89c8d180425dfae7463e0ea6497d2eec1dde112f1c1efccb532a2e2b66a28e2d36d4252a4c3b12850d465fe21bddc441b92e6a7b0f67744f7f6e7812a0603211a26518b311a5b190ed890ad852bed4f6ed13377cab3eebedf4 02c9d0fcfcee7e75c3245ba955ae04188b1033c55ec9c821d8de7685276bda3e9a93c3ae1b003e5ea722913e7b169d67b1aa2dc8cd42adbd9368672a3f81a6817bf3e5529dcb0c8b b42cd802c1ce66a6da0a2640a84c67766bc60feee673dab2b653c30e44204d0898f54e337a435a9dcd522bbc78a8179b +5d15a08226cc74cf495be681b795d0bde26b19f29aca1a8c6ef77d50271ebdcb4e5fa2df23961fe11620b1c6580183f6ebdceb2c09516c8127be576496fb71449bbbf0a9d3d1c48a25024619b97c3e0d8b165897db96ae9758d13ac28441d7cbfb75b23cb423e0002046358bb6d64779974a5995dfe54b398f95f7d64fc52d96 010c057bbaa44ef0f565edc288bfe66d4f6acd8686899359bca418ba89fb690429489a37bd3c6c9f3a8714b2ca225868c6a45fee360e378a676f7ea39321790f32a4b005b81dce43 85d303235cc6b22328525c5748e82893aef313eb75a64096078d88a79a1745631db1507dbeb067e426ed197a1e8176c4 +9eca4bd88200baf61b901fca53dc1f1e7e3f83b94d58a6cc6a2adbc9b1a35fe3f8ec61787c76ed9a0d696167cd4fe46e1a0883fda564666131753c576a720125e0b712db1da0278067cb899bdb14eec08737e864544663abb1d62f34a2114be07e8e3cf56e2d17099299ce6b6d83b1a34e6153d7c6a32a72c7b1bf4583fcbcf7 02c182df7976ea93d996f3ba5d2221f3cb755cc7847bc3fe9e022fa4285046f5bfb426bafa3580beea206de36f87593ae561b4b74a03fcd61fbd0e8d6fd5668f2148819a88a650aa b565629949b69fdb40aaae90ea9658b8c1cd66659dfbf97fd517921acfa0c8f8cc7aab78d1ea70b05eefe8508283a936 +707450bd84141f3b61beb12ffa5ae89d812dd11badcdf6a88a2d50fc70e23f6d822ff4477047abc58cdfa28f97ad7f4911ae0773c04ebed1f51bb2308cf6e5712c4aaed461edd6987fdd1796aab70198276b601241f6a14225dce575830ff60f935fd9f567d1d210652e4710922fa793da78c8fdc30c273cb08365c9fc887f50 02d3a65bbe133cc98cf0eb56ee1362195968b4eab960a1d55d8b762f1361fc21348d6f275d4bea1de7158fb97c995e20b92a9c887a3e332d154667ad167acc632eb88a0ead6113a2 99e96a0b30c113624de100b429cd5a73bc92017df4167b6a79ca526063edc947c40781a77c5a141e9f63fe025161264b +d5ce9d59391cdc47ef942dd2a818d024ae3917deea8a5a4214e4db6a0c5e6b0936f3e632fdb68a3f0006e05c44b7232013e1da5f877cd197f44fd6f60c1fd2378995e9a47534948c5a09e33750f07a7165072ab38095373b07a50bc1391eb6b650ee13acd63d0352e7d9c31695ea1ec6323f9b5f57b426ace56aa7fdbf419be0 02a920e8dc928acdd56e3655b2340d4371c793e66f67405fb7a90f31e9c4ef466cc44331d1d2fe3ff7391d2576dc6640772166ef8c154a5ff1808f5dab2f03061070ec8b3f786c36 93eb1e4427819c4e90613005703534c4b189f7fa3e55958662d82c070e784c68af2faff1dba92db2cfb3399ed7f3f33a diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B571_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B571_blst new file mode 100644 index 000000000000..8e7f9b89ee1d --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_B571_blst @@ -0,0 +1,60 @@ +8e14f713a2c427b1f79491033994f76acbead614d12e73ac6f3f518f2052a10c1273aabe628ab38e0d3d5f8ff254802e9f44a51367bf80325b6fc39d907a37f731372864747b10749ea5cb3d3a83da39c21a7b02885a8c1770e4397cedc958e4baa21d5007569dc9dd1e45d2181709d900a394454090badbd0cd9c2cd2369aad 00f42afce7f7b3d45f3f925ab29fc3882a89c9f585177887584703cf8bd8fc572e677adfa55b402446fe1e90dc855358d92c3267c35be9674b40c2ad5ce8dbe6a533c44b0ad8d2b2 a2e962978f876e4aa20638d2db0512652448781131a2786e653a5854e6be3186f6322395958814984e1174487449debb +38b60d27ff08fb191811036dbfd5b39e1cc3427ff70efb67c851e9cb407f9fac6f348d289df98d055eec73299fcac068bd0fd9ffa3c5d244659e4f714a58d79f6727f323a7ee26369000e90e34e106f99f5ae2ae1b64ee89e5a1d304ef20c071a7773e9b977ed3d49f467d300a881c8371041394910f9c366942449045568f01 02f36613043cbf53ad36e2b38998bb867503359ae082d07d040e5a10a43e06ba9c91e7c73308e41e2391b65e634f83b162cbdf4e7a44ad818fb93a978af00f06be06731d8c5886c6 a963903e357f27e62c6c5b4efb316005ba26c650392c5568f625fc2216341d5ea4563462b91c06eab2ea379285b4c468 +21709eeaf9e1953822294a478dfacfb205fc25f447a73a76a32601c00784cbf2f9ebd41c22721d70cdb3842dcaff4a4f208d41c0816990e421cc4b8538ac2f347cdd0aa2a39f1aa26ace8cb6a606b23f6244894d4594a0f6a5b8f6a695fd66e1a41e2eb6a377017177fec56bb58c837e311cd04c5b50575faee32606b9636ec1 02e74948c46930cbcd9dbe2325539c7dfdd910f309fd610e6599d425aad9ae230a8d4681970a14f2a71fd08030d0a40ff40dade7de1b06a80441bbf7e2fcf1809cff39c7ef88bf9f b44a0500119144afc178ea3e28facf0540a039fecfd4827260df7684186b36139df4775d383758e8402f79196d012985 +3a131fabf3dc97334f212fce41c44300440d16de1d6060450875f7276f53c026e2a511681b5a8d75fc0d578546339542833145f7ee13c708df33e584445a75a5538829286480d339be7c777c03c998a6d3f037b25799ab2d541021502a0b02a9b9c337a8b176c4f30e5b186485a6103b1d1563ad4ae73ca806a5e4daa92e9100 01b5fab1d36f6f6d559f65d8b01edba610620fc3a38307b1fb1c5bd63e7ffbd4a9098cb8bdf50975a873f5d047ee2b627b090897a7fb5f56d3f4a0f3528179e7c969926fc0d3b0e5 a9d04cbd3c5fa66f2a0d69607bc83c941365417b69912110c6a5183c070e063c369e48f11725d9db1b02de1b4c0c3884 +679d85a762f2574b0b31b516270b7d33d5e166c83e91a0f48e0f3db20b52f42f9e6ee9648cf58267ffe3b713723cf3df52b5fab5c14db1e7189f7cb7170bc6ec7cc71946745e152b39180f828688a5b6c0b2957ab94283b90052a3c6e36843c391aa8810f9253b639a8d5a69aec10070603ad7a99dcedb544858d057a1d66b89 0383e70c71b431eedd4574f65d01fb0304f7744d668408c847f7899eae44770a7f3243109740f177d7146a27748886b7b77ecf3792b512e8d8e37c3bf4ecef2b1253df7066498f01 971894e42dbbdf2264d50f3e74ff849b59f68d91528114397218d4f0d85aa5f989572a158269b23e2b40c3791b32e933 +236152ad31ce2ffc0dead3c142cf6c770672cd2e75af4a82fda1a72e1c775cec9b481c6f3e411644df7e7ee901c501405620af4b6e9667dfd46091788daa95ef2c6c9f5c240c06b15cb0df51f5f058d8a7934bd7845f007a35f99fa97200b20f3b5b14fbf1e372507f3b2f377e8d07d30fd3e222f398f26d8f428e320327f901 002261d4ead21f02fab19bbb0da8c272286704c8f0c6842ba47ded121e5cddef79fb34e6b9694f725ca502949faecfb21e3cc062a2b4c654bd542d9a1fe8d97bdd0905c510aa0999 8888f6484f6a1556d2dc90473a3ea64cd9fe5ed73a2e2387ca8dd2f220ae236bf2f8023dfbfa5027a51869a3dd9dbc3a +ba3f02c4847fae035d747db246fe4e82fb9224ff9cf568a6ae548f5dc2befb2079541d2cf9aaa6b18c281a05e7ddfcdbcefb25f41dd91cb3092b3343e16985e91c912215cd99ae4a099baf628e33a7b277e3c36a13aaef85418fca99f64d73b789f23ecbb76c3095ade0a5f7f34836a98c5be933b44a94a2eaa3f99b1d8e7937 0316c78f289e1860bb623082be9d9238b88e38c5e978a868bb90f776235bdff4eff591877b7f350cf14c40356922b2b6aa51d64990360b2b0e44d6941b5dd9492b4f4e1f42ca163a 98a12fed9261456efbe9c770b9bb8fd92d13efb57d53da7533518084a00a13b7c7ca5487ebb284dbaad0aacefc8ed7ca +6d0372b40559e075af56af853cbe18ba2d471b0fc8917764abcc69102b03d5bbe1fc12458215be66409c26c89f67c72a8933677a07f88993af6918acb074fa915fe883b24bc3d191ff1b08852f07eda98977e70eba072d8bf189cd545230f59559ac05f1fa3f4e65886d0bc274a6e02e2399812b2bf91abae81e21279c5de996 02c1bc13f8320d97a82f3d9354e195481902214e16a4fd89332a0499208e91d50e5cabeb4927ba030cb42f5bc53b10f500fa646a8c88508cb0d63ebfce5c4bd574c527d686c735ce a60aa1d3be538a4d97bccdd44a97e1c2ccbcb85a1dce2432667fee8d6eed7d9ec9d1bae18b98895bfc228422a029c10a +bbfe66c82bc060bd14fd0e40769d9b3a026eb447550dd9f118c30d8448f725f8366edef042447962ba7f7f833b9e9094d0ff600714697e632626e7d12a592e040bdcee166dcda93952323191021bd12f3b1647d0f25a41739994659dcbb19333ca30f46f539c6f0a5c354cda8969a1eda572a309950c84c7607eb8ac20163912 013bd80eafa67663e75d7ae139bf285d2b9f1e03d8e32153c73e26d06e86d7acad22bde9f121a3f1ea674dcc1fe67bc7f5398d5e92555056bc046a02b0ba86c2a0dfe32e91add5b6 b5fbfb7ed3a0de775d0491ad41ac3da65e2f2c957825614208361724b01753c67d0e4eb2816dbeba2220e66b9b14dfce +b35e9bf686717ce3b16a59963a32a2116130453b161a4e7ceb27b755856add836d779696edcaee3b5c986523891c8836109d431e55c23afbca022437ad19e6777efabb6da3bba1f5f44f905395b4cc7c9210590fd38da621582d059598e5e4569e904358e0dfc0dbfda4ce75538aa97480912852bccd433a9b96c9c66e9597d2 030834b0a4284097cdda2ada6947c6c281f7290a49b56becefea1e2788ea3ef78fb96807633c47c25138341768b241164ce0d42f7301728b928be2c047f2eb60fc2f844ab77306d2 8cc027a9ab896f0fa2d31c97f9df8ef6fdaa273e9fc0dc2fe414e4ccbcb48ee19c879d29ebd0a3f1463cc4818a72db76 +57b5ae7e95c638b258d1e09b3fcb4341e203f5706862e199b103c8fdac72cbc5155e5cf8b300a0b3fb0ce1f897c45f7aefcc528182f73dd450cd84d5fe9eadff3f704dc2a01b4e847c22df430efd1c66b0199f3e5b59348af5386962a5ef25204fd230b54d58d7fae801c086f8f405d3d0aa7a9a9da15c22b868817cd897d853 00c81a79ced1eaaafc31b69a40d9939f4e484d625db6364a8e589b6b4d336d458b44287ea6c6aa7661113fc07806b147ff98216fa0c08708dc9d651821b922741deda522b4e436ad 8c09208c4d616b8180d42ce74c331fe0398af2b66fd10df9b4d555d10e322aa3f8a14d0c7254c3f284a15fbce0225233 +daebfef74b452f039c999ba0528be3bd9e16deb5f46f6eae87b63db8b89952c949fd7db08311871eb2596865eed107aa065f030226ea675ee3256c31a3f85ddf4c21760582144e07af208f33c5f47cc026db5403186a65a47940691ea2d74ffb1245676260ef5717dd879d8b5b72d96f87fef5f762d4fd17454cb5ed83d8a11f 02f24670c0f77d2ca0266a743023d2c7413d56d0b5ec77b454ac59087efc4ea4d46179e10278e4ba416ffd8c3f9786ed202faf8251c0ef5a9ea5371fbb35b7afe3d15a9cb4bad975 8147ad2d044c27dc6959896bb7135cdfd09b570ece7f105de5ec4e68f11946e8f6c8e94c6ce8aecfa930d2de5dd1376a +62af0493ae79d71b552c4647d1fb7ab2f282a91cd44aebd8ef344dfd77b521b0c0a3f72e4513c8ecc0e4b84efef3df9482a07ccc1b740c571c5e69cb913740a792aa231b9dc87edfb72bac188293c6c6e788cb3dff32e8f483f8f34e21ee7efec71302cc3bdbfa47908a135f6ef3ff179dcef26d1a3987f7be967a6c0f799b0c 020985f2c6fe3ea04bdbab66a8b6167e5969c073b9d53cf3c77cebbf73f4dbf75e601620ec9c3107bf3fbfc6c79f8f063409bf8fe1d14b19e323d857e23dc05157d270c7514137e4 b2c8e23c7e3c0a34098a65d1b369094e11ecacfb5160190dca690f61fe85d5edc821e572910b4cf6f538b8d3e59f3099 +566f17851951777ebea3f8285610cd8ee5f882a68e7a4205e6fc9e2d66d210ee2505ee73d6503169f7b903012d43e7e99efa493a8e6ef926b16b9ad8f52156840ab561fc6b680120a88714fd66d1d0742189bf06c155e1138ee5314707173f7352e2cea0fc26e1553643f2490428718e44afd8372cbb7bf5b88234318ebf4355 02b3d641607b8a141f876f6d285ee46aea543880e772dadd5dd83d595b9643191d9597218e1d6adb081df133304037bcd2c05c24a54e6c4cca64fb2cc4569d6882315360059496d8 b41b5cd79cdbe54fef0819bc3f12daf9705fa9dcd10008d2fdd434457b6d5870560cf554cdd81f519d87a989fcf2eb2a +25155825fc4f9a1c4dd1db837008e7e2594a879052431f5bfc76d0d2565b8fa726008befaeddceef73f3c60fa2cdf6d9a70e56d27210bd013034b38861ae49640ef208d3fe294ac4362f8eea44f58af3af8a9167a36b5acafb7ec95652d5885a0e08067ce1dfbb45a0c89ad1acb53eb404bf88fa5c3c463a0f912b5a2522a0d9 01afeb5ca87c81025ddf09c2b2c5ee22ba0105c0e619b67a324467485bd839030d149fee44d8bac6f5902a1245a50c3437046b7c89a84116b2147cddc645b6d2fd24d68e8d53bf5b 88cd6a0122c106e5d521e6e6cd0b9407e35977e25627efb129a6eeb822d662827368ebabdab368ab79f796b29aa616a3 +29acb0fca27e2a10d7b9e7e84a79af73e420abdb0f80dd2665696638951b52dd39ca028166b47a3b6a2eaeceb1a11c152383f0bec64e862db1c249672b3770909f775b794e0b9b28a5ec8635a996d912d837a5f22471b40ec2e84701a8804127a9f1a0b3c96ff654700bad3167240c2518fb5dedcc1be9f56a807083e587bc56 032c97639b69c7cdbf419286d0a1b406d9b1f2886521a8b979a36118d2a368aace5b02dd8c515f2041e6fb9f026d1e82e789dc826a56d2ef732b1bb0f49be2b696ab5d3d5694a2de a44819eb55ffac4fd6dabe61c037784cb8983d60123e6167bdd730fdb8e673cafdba2c9bce034dbae140d6c3c209f2e7 +c92d67cf6536f5046e15b02158da698bcbba4ff1e4e9e9c882cda67f817210402ef917ae93682c9c3dd817b21b73c6c00b7bf92ea80ecbbef2e67f4f4379d078a2b0f297742b2bb9c3fa3297a7e8079f488555bd37715eec92b4b1cbf897640ae8a1d2a0fbcee5423ab31a37629f98630275e35094a896cc574be0a449bb1bc3 00f93672159276c5a293582b9f49607bbdb970112f6c63b2b3b5d32ad3c8240c86b1af13a8dff6502c6b6a17712cfd988f8cd23a60693d64104143b3f91adb37f852e9e11a0ef110 b21207ef99c1651a80bb97e9e6c070c6202447a481377f10017c0828ce66d63f186f1ccd138df54a0ee40aaab18ba232 +15413f614c4551e3b138b64f66d15f8964c40326a42b0afce820778eee4a88edb127fbf575da5263e5a2627b5461d311813ea868e6417615e7c4938313675009caac28bc7a2f4c0bc37572d9bf36a3b1794294e09c0121ceecaa4b916df45b0dd31225415e6c87cfeeb092a008fce2c543cd62365779ae28f29fa02a15d9dcd5 03db080bc99c5fe7e06d5032167af56783cb423fae59fb5b3c6bce5fbedf56b7b39b17810e48ea9a172881aa1f42f5e267349b60294d4a208b4437666b44abcfee5a1829e9467908 84d2c24495b8931c8eadc4224cc3dfaf97ec9466b4ae2ca0af0fef27aa689da7355cdc29cbe37f1856e2505e6ee38d73 +9f901557451ae2f8ec79b6d4adc794cbfd9b2e6d28f19409532d91682820205308b41498a4e1ca247a2baa8da93de95e3c0f7afd6ca46bafdbdcc6d3374a12684676a50988b86a960a82180648c8c1e38f8fd9af604c7be3be4b24799f4544ac96d6360cdb83d1d0847fda21642934fd6cf65385b50d86d4656987901fb88d0c 006ee767f6f36bb8f364f324d8346455c899a49237d759003dd52cfa13b9baa4c71347b134b24ecaee32d247c34e3787a0c64bc5d299b55c86f64b47521d22f2c09db225b0c84cc6 b843cde902174c09f665d47f2f5c0bf91244f744d93be21221da6883ff6af22dc5e93ffcf5b78b8da8093c7ddb240792 +959fe5a19d7aea2ba611c7203e19f8e3f3cc101e03a98f91adfef602c424c580d5a868659368a930f9883d699fc633bd07f6cf8de474937db0bea86fa7cd140ec2f202663813033a757b93bd72afba15be5e47a4eb93e8a666aa1c72c241ca3922547d63fa3732fec54afea7ade84302e2f044275bb67433fb6b125b7913143c 038e2571d9f22309a636586d62863ed67a70538287f3ef88b88c3c2fa1a2900d48c342b6f15c26b8e7fb4875cda4093b7de7ceda48fe1e2cc2975afe958040881de61f309931e48d a843fc40d35cb51c40bb5d93284ed0511502ea413b3023a6293f465e361490d71e2b677c3a6f8bd1bc74e0cf21b18f1e +97b9688d9ed5101b8cfb19e84b89cd644262ca1c7ee18944e29ddd3b4cca78e06338b270385b00a5e8b91ca5e628de3bba50e36ecc695b3ea737a9cf8b36871c473a54ba17819f49e730c0f253b0c769aefa6c16366fd2dd612f330e95fb119fcf3bf7f3e254438c0ab635ec04a8b2424a05b483ecf65b74a93636fbab7bf1d8 00c8f5736f1ae65592f3ca850f43d06441aaad8c03820f3b08d8a6db46488dcfb828459f8b3f34af73cce8dc7a5e3834e085a64523d890028e194214cef4003210e6eb530005b01a 863e8ce62d07dae5920a394b3356cb4a3ad8417136a3a8508a8964248b2b88db46d63fad9610b9084c073d8724a9a347 +f08b250bf4a3980cb455338b3f4173723b3f44c97bacc9cf550149794a71426e398cb4a74bde141d8b7b4a72942f1c069676a9918e27792cb8f085ee037c78e3c468adea5123c4c64d8ca6a39f2f90140c5d2d80b669cbf0d1ccb466b18ded83a1d5f042c36188a04111c34ff769abba9aedda40a87be1e24b700225e2078056 01ee68c3994adaaa9e0d61bfcd3bc1cdf198d3fbfe28a44e5dd518867ea04b20e795eadacc48bfcf8e8216dceeaa069b756e8e99ed87b6b1d31154cc9310bc3b4555162a890b0c6c 933620c35b18a6c2e0b535de290cb8f8307f4d56a813d7999f63e823a9e0f606e8c15da8adba7c9d333b9bb9fdfe17ef +1cabd16fc29d7d919622810dc8b23c770b790b98b119eeab1b20900fa94fc2ebaf76be4f5eea91fc5276c5621c8677d4d117c4a5a782ee2ca1d5b0db997fdc8a05b6b3fbb833d7a7b81c3c615c2a662929760a96feefcf89e46b563314c9b77c86bf34438458b43b694ceba741b97dfcdacc0ed57652ae62856ce10ed2690770 03a6fbf66ebc1365ea7699c72cdac2dd85907ec59cd26e2d18713354b619ccb83b7fc0db9193aa8493c1855f1a83fd987cbbb65de17c59fbe79256aa5392f4eba045346e9ba26592 8e19331b1e5c436b4ccd8f2c0742bf79798e6ce5fec6b5709deab001351d49fd9273fd5938f20af78c3caf1311d6c22e +7bc8bbf5ebeacf40b3c82eb6eba5d994dcc6a3f2e12ef741f90f90e176d20c21e006ecdaf14cb5beef35bff46b2c374d9ee224516679b1a9e9255cd8ad8e60ed234f8ee7e0fc53c9021488158217d4b4369cc597d6053746efa1e73340bdd73c1bd2eed57b92426fd4d278d6a86e8be0f0a66ab3dfadefca8831b2f488636251 0145748871a0b5c1cee628de04a12fd68ff2b154fda96e47afaa96389d66d22802968584f6753d36618d49ed205260f09d3f5ccc2b27a34390ce58179b9834ff92a86d66ea0a97ca aacad3547982a05b6327e5393234b2e333b0014fef4c630f604bee98a03546652f909c3e5bf6a148bf534ea3a31f2f8f +0cd2a45392871c0c262e7e6f036946354bb41f9c2187b8c4d399231280682f3e0a09731fbfd52c76ee63b9828c2d731f4cefee0a8c46419c398205b2ff80c67d7756db300a0a8385fa287dd37d9126f75998ae1cbab5136560592118db52fbf102b7ff0a1ed45b8a91a7d99d13a0f7fd4366392264aa1248d7324901467457ca 03c71911d24ad19c20fc1d8a044d63c9bb417abc3778d7e6234c6af79b898cbfc2f2787244708d2fe203be786edbdc4c9b12b413156b7b0bab0be8af895d191d853cd58aafe1ccce aa9afea87f5f55b96d786573bdc9434bcdf0597ade35c83f964a79db40e507ef9e9bd3d35e8766d861a8deecc1a5e904 +e97092625b09c9ae6e152e1cbee207d83361f34cb9b0e727c816a5ed851f12f91fbf88ad9d4c8f9d07350f5d828fd8574eafc768bc72a2b18aaf4d2b48fb10f7c3431137b51850154de9706487d69a40a8f4cb2c799f48c5d8f518aff752500de93cbb94ab04ae1e0c7183a32d79a27291dd07b5fb6e6a4fab76e85c3a8607e2 018bd74698bac36ef11add6b3e3fad227ecd868f370ec04569462565d2f0af2340bf793486953a7b79ab04f0ab1f0e4fd16bf6b576cce677d543e73aa8edb0e50372f24ddfbff966 acb2cdfb1ff9b2816ff365f883c1ebaa1f975b68a32a0b4344199cb5f02eca5aa5695c670a16179148757dbee9dba13b +ae6723b8df5d6ab5fcfaa22d32fdf106d211514cb1892c7c43ca6cd85c2532f85929c8a259ed251215063cf92e1502528d1e22d5cf67efa0b8ef21e8eb2f5dff881ba1433e8bcf2b6af8742ecb2bccde081e534615a305562cc22d3398f61f277d8ca785842bda85d8a40438d9bf1aceaedcfc22c85533794a69cfc320931d3f 0335699bfd058ee2e6163f55d1816bf3669acea8b73be9c4ddfe775230925e6093cff7a66813adf22222c8376faa106d85ac9f3c67929bc58d8986795b6d35d5b9fa546dceabbedc 86c0e7aaec1d677fa5963bdb2b0e694e12ce884bab954e5905241f64be2f0b96188cfae4595b45307cf8723fd6eb6a0c +ee20c6b61886e02ed94359dff3559522ff550ca126fed4b2240ea7d999a182b7bb618c50528fcbd261d5e497a991fbac0cf4c105c0f664d6a00a9001c1ed522962fb44dd4159677ce8f1531019f86457c055c9cea6247086cdfe0442485cbbc4386ad002b4bd39a1a187752437f04569705cb7adc0c68f0fd059d946deb63f0b 02c3eaf801330b3f1b0504f2399f1d24455db29911f750c246ba0a134c3b59da8b3562911197764699a92ea1d95a2aac587e24f743df1dad3e1cf7edf955203e24a0225717f8d2df 90cb9c751c76bbfd57ff8fc04bb8626942f563d52a5e6da8da218ba65e946b3d305c691bd2c1b4f519d07a2dc472eabb +734a9eb8288e32f5a67cc1d88704523ca2c68b798d90e188d871d9f50d2da2063baf1ee6685c45832a1818aabc9afc0bc935e97969dc983a484f16d2bedb3c7c0b8221408be2480a5562d5d1e5d8763d1e474bf2826aa93a68c3b870e3bf34f4941cf590d88e1f5a8cd782a33992213f3f6b4b4f6dbfb3c3c8f21f5eaf4ef609 01c3ff067497e5d387f31f0ecc9c67b3c0dd6ec8c81318c492aad83c9dec6c99e4fa47447f6f7082d636c2591d0df940b947d0a4ae3778e2b7cc8fb92214638399def894ada276b8 b30d86b4cf9c19d2e729f219b1d599de5492b8f69b0dd87a7c84b5d2176455f518022e3ca38f8def7c13e106b1f3875e +68e27cc72fec8f3f1f3882c6efa08efdf21d74d13be5171da35ef2855666ad2ea6919d21dbc1cb6d296663dcbceeba2fe47a2c6507d3d4a67a61b55b0f81c93412d7e1fbe15a590e342a05f55daa55f8591171303154e615e81189a523b855829a5c96621ad118f522e397e2eea05c2603eeae6e3591215e29b2289bc384d8d4 004b4e04281b210fe78d516a5b69f878b7fa058941ee9ae8cc63b061d1eb9e12c3e0ecb8717ff4623ff5bbbcdb53c48adbd9c69636506ab929c5507d7ebafae5654aad65a263e48d 98b80711ef02a5f9485b191643f2e0eaf937d20d6f38ca3e7cd921a4615b62d2c1de1a7cc82218ce7f8d2c6c9307c268 +e67cecedf35058b80787589514a9c81c6b9f4bced4260411d2af75bc46b8b2c962dc9d260dc99ebbf8ee64950766efc0e394184bdc8e2891d66bd3300ecc880e9d6a3d0eb615322378afc3dba89938704e9a8d0c949d4bae9838805c00377e3fe5ec6a1a98ad7eaaba6b500973dac48b26b7fb2e1b9889f8c387de535d4b2363 030f2849a713aeac95fde5ce3af853e9d070ee60709eccf35a076567be2c43f0fa34420b0fc097ff577221275a3a56e759efc32183be2d76058a7d20e5dd59f00415114d73a15b8f b81a8677fd6bc4a0546489124173698c8efb73ebc1e5db0c4dfbf9fcd887cfe883272b6bb78bb25e9ed74b0309683bd4 +2baa1ac3f07e34b67b6af087400f261e138b070c8475378063286c16fa73578303380236a4af2484ea01ba56c1c619f6ae4e5e6ac2594c8e5aae7e7f196f96fc5d0f507bebedd4d818e77b9120e5b4bc01c7ab6339e88b71d0886631cc7fd89659bf513faf149c61eb14d55060c8dfc7e6e4c2b4ec8edaaa6bc36eca50a6feef 02ebb73d04e6e5361e20629e3ad119b33db5163ed91fd9a8aec4b774898784b6822a08992118a8fe6013094bad0be1e9bf01b27c069e4335bff7e0abd28a10443818f6b825e9cef1 b5d1a1986d8fdd5056f5c7b48998f7257a6cd4f28a98b5fe07a7b002b143fad8e26690e0972f1eb43c7cb596323bd208 +0e640581f573068d8ebd2899a6aaeed0bf987ee11e22b05d25e88e9a1c3451f45ee3800d976f4603c18a041febef07a01086832a6f7ecd5d498d52e796a9d90758c87c36f4a5b704a39c456aaee2d5278183d5815d619c193da9fbc427d701bab0874bded848cb4bb066f56e119b637c78aeb6eaa387c41bec6cdd4bf7b2061a 01bfab717d6f6e16d9bc6e89d2ffac7cbe0f808cc8ca2eb515af7ecce5f3b230303775710a21bd25c2cc4566bb53c78c78e3774a9f306c751cc6e149929e45eef60f56c1d2388c6d a96c18eaa263f21730d17443ecc933b0e9e01f9d00a5b23eef9e66e9ff2d89c2c5661c2c101cdfc1d5247076398b0d1b +51a2a560ba226d629127ce1ea7e812219ceaddd23561256331458c9f11fe73990f21d0dcd974a3773040090cfdc8e0f01692d951a0cbb60f8448a016c67abf46a9c150466ac77e656ea827b0ea7d1e77ea32071ba8314fc8a2edf69008f498bd1c18061d7d00f3340a7e2cd73e9766862378d8702e804a1870b442beb2d0aa14 000cc53bf7f1cad5e3dede4b4f4b082831604c92dd2b147869cdf1107259305b1d50359647f9f3d7d4e1e608865c65dc7c9ea46bc324dcb8423b554dc369d621743cbfb592b70eb5 aa6879582f800670c9e3a41377dc60e0fe97e47109297efa5e4199abfef21edbc036730e4f3bfdddaa26efd1155fd74f +90eeecff0a2e37df318c441df220dfea013ef29774ee92a56b213e13a798858f31e52b6ccb7599e7314f12b48a89884b113c1ba0526a54f3e9a33c940944319e084bff320cf5f391c02c731c4c4f8b05afa273374a1705d6c85337782ba7d36b9c00767180cad6422c11c581672ff631fa4c49d41b02481568ec87ea97220400 02b009530cb9d586e35dd8951ccb686833afb7a37ec253e547e85b253ba999f0f186b6d4ba41091615fe57678e9801b4dc94fa683511da25637b2acc9fe60936be15af16234c4ee7 a1c1de4ec20788752c6fb0be16e50fa94f8a79e0e1e57668396268179356571fab2bcd068e3deca217f0b57e5569539e +d3740cad41e2e365d80ae81da97fdf06d8b6c278b505e34cb683fb55ddc5189da543540914c0accd405dbf0063f6222885fda4b316dad4a83fd03e8d7b7e936f87fc0a5b095defc8a4b22fa97f00b394e672d5efd3e0a230c7e44dfeebda88641143502a400ed62e2a51f9561e5d652a43d616f16699e875deb9610c77de8e1c 02cc2d0d7189cc8fb3565a039aee7633ddc00ff427cafad32fd2010b10fe249c9724d91785e7080203626038109158e3a61a3970aa3e51688aa7f5184b22f63af63f80d3540ec023 98f3e4279f0d07620969347e8829c7d021821b15d7ae9caad6cea0f36356414619f6ea21176992ad09463ec9abffff51 +5eb53b5f92121396c5ff30e0c92da48db4fbbdbf27297f9bc82614ab78f7fd863e34096c615a02e349d8bc7ae4b0700130704bedf32756b5ee6af10da1cd717d624fadc57a9aa6db4a6c5d6254c0e8f8c3c0d4d03c264eeeafd52cac2c1968d9d85b106167a49d0ccdbefb20bdc10a2555f8149203af52853169a02db94e5e2a 03d8936c00c131e38c6566d2464c4e207c878070bbf681695a6cd98cab2c6e80fe98cda80c66a5cf584e90a071144dda59c07b8fc7bb42464dbee5b6f739b0f2ee5fdff7e5a4e7cf a87b42fe24b21509d5bbb3ca6ae9bf7e3b286e5393be00b8a5f9c7349fefb735c4eb1e8fe3355940ce2e9a9181204c5a +5aced64f702a57ed7fabd045a40c967a485d2a70b0a5e82561d5141ef329469b2da5964a34df203a980111a77adca376c643b9030aa74516f054648c1534d912ea66582adf3c655dbd71ca55e47412315df5e2893e43b2e2dfe6e4dedf426f11846ebef34a99f5615460ce0475f7bc54b4a4fd99e83c982097c3136ac6188a5c 03dc7de970bce28a943d7599f2a9010fc99435b93bc4ba884d42503ac2941aa63fd07db34bcbb1127d56d6a4e277d6ca32051ea3467e376f74f98c3999d2f276b282ef8a28cf0cbc aeed28e9dcf94bfde169a3bf9b3203a44b6f18c3d40128e8d1b0f78b895e2b38a4b4a1888669a2b4ff43ac97dcadd873 +43c24aea343d4e088bea25be69a332c631275c36677093e057de69cc83a4c5e70ab270e5a8930f55846f1a22ec10e03007dcf0942c6761e89c65c6a4f032eed97dc3a2c7f7ed1e82552fe48828a132ba16c41f6bd82a49335428a24fa1679522000e6a1d12c646e0e4b4c584398577ea9493bb334fa3cee8bfdb6c2e66f46436 02de6ee12eefa7a4a736484b19b42a513dfc059a060976edc3b0aa4b50e98d72df6506fed0499ff8480986748e938289e54a5e86c0c29733a9bcf5985aa63d8a2b57933a04a8e8e0 89818def08a8b6f4a3adab27d0002698abaf462df1f751fc4c0e60264efc4a78c04a10a9b5175094c2d8a25a048faf85 +e89210565959d93b483659e62cf41f0a0147ea23890c2f1a694c377a826165e363860e4b084016cda878a43eb68465f81f397ecd50087a25215ce7c4ededa3552218071fa3acd7ae380655fc8fa884998209ffc8a2c26f1ca19dfcfee455dad35a4e72caecd8da47eb9ee21b889162f5d3032724abfd1a31e68612e18bfa9006 005468f0df2c9854f5f655743e79c750fd8812db28b096d97207bae7f5aafc6b6090c9c636ead9e0fde32a1ff8d539b53813733ca812b41b58ff85a941abe4f128d59fdf9847baa4 8e7fdca6575ad3dcd6d15a59ec8ba53f38f5ec62df2adfe6baac63f089f20a639956933a3df2ef485b4b0297dba5929e +48629ec97f56273599cd9903f8a84ac2ba74275b40e1e42fa47649568babe05cf63c8417d828251acc2eec525b56dc9082b68d51b0c2bbaa7389fbee15d058cf482993b2bedc5a9101f1afdc79989a812478245d191550109fc17215679553c508c84e3d4cfdea377088d09eb214e6f92410facee4790beeecafe72b2e3ed192 03d3c6a7ab9450c94aa3b8a1ffb678e5b647af24cbfd66ee3944e6f264f406295b803767471fc67936fdfed1714b4b8761a07eec86543b7c4da6bd2fcb33fa8cda4077737f398e18 942e860d554472e79e97e3e40ee9dc71aee3e465dbdd4247ddf86dfe461b9049c06be71bb11c308db3e5191e7986570a +aa3a9fe467b1ca638dd0622c9ea235a418b39b2e15ad81fee01b6892b240783d8db3c72e16c13df8016dac6addbfb85232158325bd7432fca3b8bf5db3abd0b4c5ccd0999609dc42199ca4680692a0805cdd68108bcb493a558ab507cec0a2782a9e976928985352edb2abc0c07078b59d2fd86fda7fc76cfe573181d934c46c 001ce010ea8e6e1a0c26ab22eb90f0700dc73b232c429d36371e68e429792afb7223f10327708bcff779ea55fb5f22ad87aa054e84d10f5450f1bc9a89279062ea2173f55ab0f76c 95985aee1cd99be328926fe307af2ae487a7acce3144363f5c8057a0863bd1a0dbc5936aee19b79faf27b55767df6330 +6c3937014361799f1461f652841b5137eb0dcaf01dd293298d002f27e9a770b9e1a30367e35c04603881f0c814cf8ecfbe1619cc49cd516b1d60d27de37ed52a5e1cc300e2face4669f308ebe6747255a3d386f16778e494a7cdd10b45171b2bfcdabd91b805bf24857708c1b75e368edb2874321324f83a19154d3a1578c767 01e7410d012aeef02b3723346d24ebafd684c99087ecccaea1cf3735d52c4c81dda41812c09f1e874dc964d858ca240a19963d5dc89451f5dd6764426ae41cb23f19cbfdca0fc562 a0fd6b693c916967661a8f5b446846a073d61c5da27f4eb6ba04ebc4dd605e18adc0579fc825a44c6f89fe32c74f8d9e +12fea55ffda15db902aa6a4388b9807c89c193cbf75b5d2a4c95206fa43dedc45974c80079933451bdc5b3ea015ed3ca2c54156dc61afb1bc82adefed1491302a48b9d3d2f474ab45343c611677d360515b93fb36da7a1c1b2341c9cce185c881c0beef33d43967134a190c09034ae3261f3295b79aebd3fe123616f73cf2089 02139839ce38eb879d266065dde5e5ea227244323b330e3ad5a0bc690f3c210f794cf18f0d730693887548bfbc434f48ee10ed34cb41d52172b06e448df938170a5e17311cab8e88 8779bcb664f432b93739848480a6b89d75520c8d7f3c33f342ae2230673e7be06b0f9ccaf6eda79629f5552191dc6a29 +c8395546842ddb545d8ea3db4efe970453dcb06025ac3b7a25aa5ef62070f3021b9a1fea91ff7055b6c398073e7886a6f71afe53c82c47b71377dfe291972503bbeb25bd477bf0e7adc8a5d3f8b34ccd0080d61e121214e1b29802b711cdd8a6bb2275a2395c467ec2c1571952992e448d736d8bd70ee629c75b5e32b8323a00 0274f70fe69e4dbb55c5d404e39f5196335047113087f8711f2f67f2be4964e4fbcb865680758df1c401cd677b0971654b7a6aeb7bee0d6d80ac0de14d4f46f356b2d5545c185aa6 b7b2d19714ae58a0e6f684a984f0e14ca38d9b347cf19895fe0c2addfb81731f9ef72e0c3f416f3db6eda09b4692b5c9 +10d2e00ae57176c79cdfc746c0c887abe799ee445b151b008e3d9f81eb69be40298ddf37b5c45a9b6e5ff83785d8c140cf11e6a4c3879a2845796872363da24b10f1f8d9cc48f8af20681dceb60dd62095d6d3b1779a4a805de3d74e38983b24c0748618e2f92ef7cac257ff4bd1f41113f2891eb13c47930e69ddbe91f270fb 003e1b03ffca4399d5b439fac8f87a5cb06930f00d304193d7daf83d5947d0c1e293f74aef8e56849f16147133c37a6b3d1b1883e5d61d6b871ea036c5291d9a74541f28878cb986 b6a495d94c747ed25ea2502092d3bd45e4e1900a2436759cc93d0031276499df53a625fb67d6f9008a689755d68a3078 +b61a0849a28672cb536fcf61ea2eb389d02ff7a09aa391744cae6597bd56703c40c50ca2dee5f7ee796acfd47322f03d8dbe4d99dc8eec588b4e5467f123075b2d74b2a0b0bbfd3ac5487a905fad6d6ac1421c2e564c0cf15e1f0f10bc31c249b7b46edd2462a55f85560d99bde9d5b06b97817d1dbe0a67c701d6e6e7878272 02e09ffd8b434bb7f67d1d3ccf482164f1653c6e4ec64dec2517aa21b7a93b2b21ea1eebb54734882f29303e489f02e3b741a87287e2dcdf3858eb6d2ec668f8b5b26f442ce513a2 a61949c3123955b38805c4dec496ae379d44aca01aded5e82e3b0d7c47cbb77c32fa82161ff7e3e24d35b32b6a796bb5 +ba6be551bc60653192401ed8ff9e1acd9013d8811a7a1389528bf07438366f5772cd7aedad010c19c47622cec03a4d35b8003b39ed901b720629ab59de55a03c1ca50a62987f8da159e356245df58d5ae1936e65f3cd3acbe03ad1d0fcab4aaf2a7a947549ae776772201efbc6fab1aebfa1d99994d4f43dc28f39c0f279b992 02a69bc1df069c6e89722521a63675f318252be629e7558f3716917998e660ac960b0b750562846fe6c12ef492951e51e224754bab84a6eacd4147a5f26ae85ee4381bb14ec2a8c7 aff414f6b0eebc59a079c368a9fe1637c514623e72df04fca24b31351a89afd4fe30cdb50429e10f23c60bd38256da3b +295720a79ac8201f40a66b06ae5d970afb15f36582897eed25cd92edcd00f70ac8e31c556eed4375ea044c2e8b227a8e02c0a3e996c9272d52ac7b3ad43b80f217295dddc84b177cf1e800ad08bf7fdd021fb2f49b54162092f8d628679c4ee335abbc90c027264c8b288c6e16eca3172eaa297ba50626b00fe0a0ad3a9dbeeb 00d11ed1b78b22b3420df4ddc4acc7c2286d9569dd6dd88e0fa3ecae69bcced68bb81bbb4ca6e9b54e67856e7fdf39155aa27aecb9cc827ccb9cdcf9ac633561b27d8eebfc261aee 9608941363d967b961b34dd749b697e6e8787db009bdd63a4789e6158ffdc96c4f8becac86aabc7c55dfc3c54ce22606 +a9cff41c6dfdc4a12f31dc375a5455950077ae323d0b7a3d9a8dde73b76e9d7b94ddf9c88ae8e6c262d704052ac47681fc35adfc56c904baaa6e146eb653984369d76a85596cb744941aa7b558c945ff2e81bd5ef7f00ecb4f43af23b4cea3bd4ba7b1899f1868a0c0ecfc62ccb1d588955597ffbbaf34cab2838efc2b866669 02c36ef754b5bd065e9eadde684750acc52795be80f54dd3d7a7d743d968a18f7e404bd71f8a76eb0395f396df5a7c2ff7e0ab6de35df34282fda6ee01fe5b9b68ecb4e378dbe32e 88863f36d98bcd68e02f0b41109f44c1ecf7cc846d7cfc1b67eccc559b9ba32319c6c4b4c7f04091ace4b8a1ad8bf7bc +efa6c582d7fcf5e431aa89b3b00180c0e78efd7ccb0384d90b80e59a115a13e55001d951528c42860132531c9b8ab29dda7a657c53c2ce96fd85549f6f1810e121eb89961295335eaa0e40532d85814a4206e6fffdf9bff76599da9b2e71a22ed572910b0e3bae38ad72c7042579f106739a8628dea5a745168bd918736e488a 019ffee50be5496507e3ef5c40ee88a49625e46d1dd1686a52b09ad4a8e3ee9ef364f953bfcd97c52104eecb6138067192997cd4ebadaccb73c7b2560879289a46353a756b73cc43 9485b04eaffb55bb0638f1e3d8d6272fb15c03b63f088385441467ef5738566f1f6f559e73b800bbb9feb96fe4d8e623 +211acebfaf13bba33a9dd16722ec53baab92a140127d61372cbf1850f2fc894e942e25d780778235f880743953d04eca7a9205602e388172aec2abf35412b483490751f93b51239b6701cb0aab14e5179b0d7f55d8586358381dd83e3e436bf69a6820317d1701750cb1fea1293467ba589eec5f5779c2dbf2a9b8f28c4dc239 03129e96fd28c4198cc5242c1e3531a3979fae643d527044e98d7721aa56b5b4b45dfddfa17a4115e10a2b4f46d92f81cbdd7e86e588a4c6d8c2b3a83f54cebcee1d1dd33e85d81a 896df4307616c21cd26b5be77662f151b5816ba97979a9ee3e9213029312d0c4ac9b7a38a9ef61746699defbcd544705 +ee592e20e0a45c18089c2e41460e65a7d22ed9714379f095d43a308bdd383128aaa6fb24e9d35fd28fc95c5b792ad75c980d2cdf0f460ac60b12c5919d3cb28dac4d488196be6c2dfe462b1b0ce59f8501692255840f5215c0fd8b74b1996a267a5e3b22d2841cf0a0b6315ef4ec7180f1c8494f4c07d5869c01fa2711739efc 03d723d2697cd07dd8444f992f2ab4a063db334034c25ea9be99fd7a1f495e3a644e5ea033a41264e0d24a911e55741d0cab80a0bd678eaec2bd1e60424d4491eb86d664900d907e a0d788477ae12a7ce76779d578333d5b579fceaba1e57f42332a010431fa6b77de556fd40ea4a3e11252c1f5183dcad3 +fffca41927debbd53455821441d9115db99fb31bfc69752a382f57bc7abe021f148346ee29e17512c64b4918ab2391d12d6e5643bee6b5682885dc28177b292e23a37ff99b359b9cf7578432af56e0ad1028a6cce7428980654c145af8daf09addbb3be11228d3c742defca9d3b1667f48c63091fe3307ecf72667b02e008f24 01999ab45d66cd1d3a0fe6aa43bf5ef1e2a67637d53674f6fbbfb9b582be91fc42a12cdcad94b50b0fc7ac55030de24a0b99fbc4314fa743ef4b5198bcc5f54d8b669fbed78e2e91 804de17cdd3ee8ac33f4e9a317b8d0e423af6384d9015000f0b6a3a7e35846f0accf4b60f52bd1c5797a72d07e15f3cf +a2f71619ea04f7057e6943c2cece8594b341ec3b96c3915d924f94ba13fd7aaeed41ffa0e842ade414784f1ef825fcf2dbcf7bd8263b802def45f94de596aec0c121fc06558c7bb06b9f27a9bf56c42090b5dc344e82b69c4f528d33be166764a593483f6fda0cf56e6000ff363ba220f5ea0ea2c3191615c7ae3bb4fa575324 02ce1cae0716205330d730e6bc6dbfb6b951dc83ee3b4a7dae75d057e32e8a46e22be75b5f09135452b29c34dfe81a9be2e8dcd243fbd946a0ed14a832a7802e20cfe1abfd3d6e4b b1884e3b045018815f462287a818d2430c71cdfbdec4075a39521f45b1a7987e47b58e0d88265d34632e69c360a9483b +b60415a831eca2cf60c79a334ef2f327a76d290846ee588d5d33d0a826bb0c7ec3e11dbb384a7f89c8d180425dfae7463e0ea6497d2eec1dde112f1c1efccb532a2e2b66a28e2d36d4252a4c3b12850d465fe21bddc441b92e6a7b0f67744f7f6e7812a0603211a26518b311a5b190ed890ad852bed4f6ed13377cab3eebedf4 02c9d0fcfcee7e75c3245ba955ae04188b1033c55ec9c821d8de7685276bda3e9a93c3ae1b003e5ea722913e7b169d67b1aa2dc8cd42adbd9368672a3f81a6817bf3e5529dcb0c8b b88839c2d4c08d9ecf7ee7620e25b9e8f21be12924af3e5210893fa8995de0c112e5c9f486d8d73e445678a75a09dc09 +5d15a08226cc74cf495be681b795d0bde26b19f29aca1a8c6ef77d50271ebdcb4e5fa2df23961fe11620b1c6580183f6ebdceb2c09516c8127be576496fb71449bbbf0a9d3d1c48a25024619b97c3e0d8b165897db96ae9758d13ac28441d7cbfb75b23cb423e0002046358bb6d64779974a5995dfe54b398f95f7d64fc52d96 010c057bbaa44ef0f565edc288bfe66d4f6acd8686899359bca418ba89fb690429489a37bd3c6c9f3a8714b2ca225868c6a45fee360e378a676f7ea39321790f32a4b005b81dce43 8e9af710ae382181a4d81dfea23d03e892d0fc01ec1ca22a601e19f03b52d2369ba656a3068e39135908cbed63362325 +9eca4bd88200baf61b901fca53dc1f1e7e3f83b94d58a6cc6a2adbc9b1a35fe3f8ec61787c76ed9a0d696167cd4fe46e1a0883fda564666131753c576a720125e0b712db1da0278067cb899bdb14eec08737e864544663abb1d62f34a2114be07e8e3cf56e2d17099299ce6b6d83b1a34e6153d7c6a32a72c7b1bf4583fcbcf7 02c182df7976ea93d996f3ba5d2221f3cb755cc7847bc3fe9e022fa4285046f5bfb426bafa3580beea206de36f87593ae561b4b74a03fcd61fbd0e8d6fd5668f2148819a88a650aa 91b664ef799b2fe01cfd2d691c871814da3d059c8db18772408f472f4c02656be42a5f8f6d70e827f69d943b592f9c6e +707450bd84141f3b61beb12ffa5ae89d812dd11badcdf6a88a2d50fc70e23f6d822ff4477047abc58cdfa28f97ad7f4911ae0773c04ebed1f51bb2308cf6e5712c4aaed461edd6987fdd1796aab70198276b601241f6a14225dce575830ff60f935fd9f567d1d210652e4710922fa793da78c8fdc30c273cb08365c9fc887f50 02d3a65bbe133cc98cf0eb56ee1362195968b4eab960a1d55d8b762f1361fc21348d6f275d4bea1de7158fb97c995e20b92a9c887a3e332d154667ad167acc632eb88a0ead6113a2 a4ca483d760f4db4c08d95bc7d614a0bbcd9375785657d1c913972e61c5af9eb69334ab8625c52937078567aa8450bb7 +d5ce9d59391cdc47ef942dd2a818d024ae3917deea8a5a4214e4db6a0c5e6b0936f3e632fdb68a3f0006e05c44b7232013e1da5f877cd197f44fd6f60c1fd2378995e9a47534948c5a09e33750f07a7165072ab38095373b07a50bc1391eb6b650ee13acd63d0352e7d9c31695ea1ec6323f9b5f57b426ace56aa7fdbf419be0 02a920e8dc928acdd56e3655b2340d4371c793e66f67405fb7a90f31e9c4ef466cc44331d1d2fe3ff7391d2576dc6640772166ef8c154a5ff1808f5dab2f03061070ec8b3f786c36 a92afb881131b4063c189b210bb3d6d88d569a944ee7be6ed3bacd35785c3af38a16298a99e92869c7a9d582128902c6 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K233 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K233 new file mode 100644 index 000000000000..50138e00ed3a --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K233 @@ -0,0 +1,60 @@ +f23f784fe136c9fc0d169503d361e9c6148b0f1fbdcae0a97fae1af7033ddef25cb7489c9963cfcb009a8cbfe44a8510a64a073eb1deae4c324ceb9302008c92c69b2dafcc9077fd3cc3c7c119edc3ced36d176ceaa55ac036bf7f07f6fa215e8bb8196e59a5e1c9af4f98b90ab4970885bd7015fa26a09e03c7cf6b4b23d929 004c1d414696cc3657dd9df73ace56eda2636769ce7082e064c260be45a5 922ed45f69da7a5829a615a674413ab957ec701efde8407fcbe39ea03ee8306bf9fa3c501aa5a3d0bdcad3764c9c0845 +400bcb297552bb37f2f8135a9314a35f5126788bb6fa4dc74152731ff64c5dab4b902103d85443dec20e16b1d6629930cdc2bd183d4099f0e96295a63c2fe266f5e9d050c401a8681b4a438efe53cbd8f2f43e2a31e9f88926a9c82917d873f6e8cd5ff5eb8c1ca36126b0bfc8c2b0e85a7c9e7a45f1875ca9c82019ebedb729 0027cb1d84865a16992476c9e353283d5d6a40c349a8e9179d1b1f403531 8e21754db2e54d5092fc3d856534f800dc9c22d44b25ce12ccb07df16becfba5a6a7de2e57e7ac89883e895a68c29378 +5f74d4b35c49fa454c97c05fdb6b9f6822cf1a2295f15bd766dbcb413d77c910bd8f4147e8f317fac2300fa21cb80134d1b6f8ae8e50518c1f648a28506e419f5a6e8f05abffdb3dd2587606c7e9c223ecff4f46b121216730ea13202b59128a7616bb2fd23a7e4a5aa08641cc07b669641313febfc88d64d99447353dae3f06 0031b443f46c4b5224237fac1022ee1570173f664aba0c84dbaa4246bdc1 b89df9492fcb4d11f4b986e3f884c936d8abd3add67ea3c2223a42132cc185b7797c34d9f0777a3b078597a576782db4 +8f92096876d9f81bcd992369d42d0b5877ac969004d17c8627c58d8b8b7bbf7a37e8cb6afa962b9b043bbbaa5bef4a5ee38d8bd31cb5866b828265a2f4102a616f87009cd346fcb8af5519fb577c60d8792472232f33dc615655e53d2b715b15a2697b492f108b7906e1e3597c6911f8cc30c7121ae338a6b747ec368f8e4a36 0048f6ca29f35f253a4962734357c995920967b9eeff1ba5fd2080bfede5 a3c35483d31e9d1ea55447783ae57a9b9b83bd1c3e2b610d04f01df13e54ec5727b3dcaffa12121e9e6a16a6251d641b +3d275dbde44494c45fc15fe89e2ae32aa26426a17e923e895c7941a5582fb95df4d49873ab1bde358017f336b911b886b626b744806ab8113418473c441f1964159ded1b12122d53ac56573167588e4b55f36b8bca8c67823883a51fb6e7f204d1c6b07ea49b577bfab9ca6b8d51f72268b022e3a4db6f9d265ee8382f9b7b66 0019b940eabbe682f961d9f3d90432e347fef3910e641656825d775705b1 b4611cc6cace3841e25f683c8844042dbaaa776d9c90c44e678ce0338827c4b5e335b3df026211c9b22232fbd34562a9 +d2fa68e1f7dad02916b12fa38f1849d6d409dbad0344438520b4dd9b77d62d39ac9ae3cdeab03ccbcfd4de703c6e798873671731c108f322b9f2a68145e3e210c9b15b879798e5c53c5022742e9819b99edabb2f44d89ae221f7a99dc84421a6905695ff91928db608f861745f17584d56e34b75c47281435b1b0b34e490692d 007a884b22e29fa9fe945e9ba13c0df8d786dc87cef0f77f069e182dd56c 8b3af12f875e5e03ce22f58637e97df09257f1632573aa82187f9c9d90ac361514b476db4b5da87ca93f7d3d446764ca +3830f75cf9df4eb2998c7c1b5fe11c1476bcf849c3a8fa7d3d0b5bc2292e5d07465ab8cc9381c575d909e509c5dac49c78817c04e4bef18bd51bb09aa5897f21634633a5ce6d20bb4638cb6c3927351eaec7b62cf4a33956916045c392f325adafb10a88a5f86d7e41dd77908fa7284210071c22aa40ef40da6339c02da05392 005da61f881d5a0dc085bb93764f584352882923cd237d878220ec624c1a 947e1a2fab78b180dc5c75a61cd9c7c7091c630156e97c6f5a01fc5faf0c2d373bcb508b1a56cc30b1d2d62f1366e3db +65b9fe15e6c35d453caa6bad39ee78a720a04b60d8a0a0f049186d2f777e48ae2d657e174df53edb7beb9f7d8f21904ed674add0cda5b62a7308de76c324a144021e8c6d387daaba4ce48bf7dfe9c8aeee2c64e434ece1fa5ddcafcf3e5d0013a1eeec1742a00d384cc2ec0d7eda83bb4dccfb0e57045ebfc27a4f404d03da37 003fe9f04647f6d82b13ec1ae5a8c2e49bc66b05649ad778eb16149ad83a 8938745dfc8dba2a82bc0e634f5d0a2fe4dfb62a3298d1d592d0f79e42fa1fcc6f6afa762e6f132c54a80db7546e02b0 +d26521fd41eb5d46ece6836e188bf9cb1b461d011c41e002a935d256654d01725378e845920ec4a7fd3f379df54772493df50d312c7c6aa4e909e7b83f2442c3a5e85c37d68aa015098ecfb0a5e077370f4576f4bc63bf37e1dee06d780a3b6949af5e21c2a0960fcd20821ef5f17bebf5fd5b3bdda260842cbbfad45667287a 005ebce648ace4cd555413de6a456fc487d14bf4b0b9a72311ef480d2f26 87160d9589987e4bdbff1fce3535004d807368320948833c360cfb1beba4d571ca4fbe46ba85bb4374f74b4d78fa42ab +b778c021b1a92c41dbd09963da07018075d73e54d62df5c2b7bf8abe137151650d1c1c6abce7eebd8f32e8c3e6d1433773f257bb3ba4a4fb6a02c0db1e47d03c27d3a90898ebd1927c21df24c4c5443ca5b81f8ef2cc0f5e8b3d08f472bf07085df737adaedec63d99acd77b87ba98225f198b791124ac2d9b191cb9251b4b00 0056653c2f85593f789a926ba49fa3da9d7f946d8f1020508c5a527ce813 84cf8cac09e50295f881df480763f4e4838269b4df2b7671dbe32b22984297ff781a900282ccbfdfceaafdf095cebf12 +ec14e07f615960015a489ef999e308b42a4c571473b9bd64b433dabd9a1b1ad02e33eee9100064405175928a94543a80f440040afa2965b4e5f95f768e7fab6d3c0a5f5e1bf1df7822f78384e80f2955ea85f044ac60537d895747979f935bb0cd3673193c4a32dd7803e48d7daf70a71bc2aa97236615b6411e28fc9a652145 0049a91d320783cc70a5952c32036cfc75d41f1aa84127db2dc759fb291c 8703328185b0e1c9b9af670f597e97e3d222de50a73fddcf6396e66dc2529f82fc28f27deb8b988c1972e679db87cbeb +89c645339ad0eb850e4e2fe583cee175b35feb02ed7541d7e9aace24cdd3939584f73ad39526de6399c86b36de77a018e2c70b532bd0f032f9137d10480acc30c49f9baaa86f9df0033b77e98b485bf7a69cb5c281e527d3ccd1fce2415f0dda4a268ce68a0a34b16afda54ed922cd6810ac8dc766df2a3a6c5e55972e9786fc 0016a20016602fc7088a60469843e1d29ad67e3c3cb9500b1e2a00d4050a ac55391cae58c6f97e945f111858075540eb93f280cabf75340e88158960eb4fde9b0a21d9dbd261421a813cc4483b78 +ace14c4b101d2d8453c2bc22b756af016b5de537df9c3e639d208ad04ae0bf6232dc90b90c33228dc85de956db771ffde05fb4d0b15e4f218ed2771d703ae5bf981252a5bcd60c16f14483131a481cbe04dc0adb1fb8aa32cb48bb5008e8a8e5c7b7465be2fd7afbc811cf5ea6293b1a464669b49f55f57b93a8707e6042fda6 000ba922149bada2551b7be1c3df076f3f97ce93c13c50c285fef3f42363 96b23d0cca644d92e9221d1443fe0cd963e820ce7325622f61a5af5d5d1e1934448ad1f3028d3b933f44aa572586a308 +cec2ba0d1772c87e87d5bbbd67220692bea4301aa1a66e8dbdd7e651d45c26dc2a0d45cfc32c34d76ae3e1c61db7b0fe1863457b93937d929e6ece7462ebd16adfd708353d6f7c27aafe06593c76da7149b0cc574a4290b0d8fe219f3eada7082aca38dba3f78ed0d5942d095fa5556fc8bcef331ff0a6d5d1f4e6c51d4ff5af 002d635e12a58cc6dea44e71e87c37f91e8d08659f0b7955d24f65ab55ba 8e256e16b395f2d524a382b794840a62ba41211454064c78692fd7189059545e8565e23abcb8a4318bdcbb032dbc552d +ffa13cd0f51ae2643d5d4edecb493ddd653e9faddcffc370e7e958abf726a5d67a2ab36cef42ea8ebe22a6f01b9c31f6ffad01e6894487d979acb5e618f765ac0ec3550ac5dbbcede8f9fdbe52fbaba5c087ff382b6d7a09b2b5084227d324d98ff98793040884799b96d2ca593201f4414f18c43b51c53c5e5059e0641aca02 00073883e5064e06814fc4de32e15f7a6cf825d2daf6eb1df8c83e25d80a 97579139a0edb4476b3b194685667705f28e9eac581eb6a663aa8f7a2412b4f4b2ebbe645687d05f73230bff569c1187 +c73e3dbac9513d0361dabe94071faf03a11cba18c06d131a172d5f0125b01a5eeb6055bf72c7106fe3f4be3bd2b1771cbe7f85366dccfbc3bac20538510c3f51179cc540ddafb2f3b05a0d276899674ab1d7d8fb4f6838f04e4f9e26b8c6af31540f63f4953c85840af4c57dfa78c704f637dfc8dd750fe45e2c1e149986d127 001532271bfae8d4dfe60f69b88d3006d58e28aacfa701861cde8d624db6 a282f9ef392e5ea0e90305ee272b45b851083d8d21f0f1235cfe3b2311025d0f3c35b0ca6d6ce8c9d36e05731d2a4669 +d00dcd0f3212a3167403abed91c20e76f5e7a7678a4fd970f944d11e6a8cd149d0aa6fd3164c5a74c0f55193a4fa3d8ba6f99cabed10544625a7bd92b3e0b46edbd4a269bbc10518c5268c3910a2aea567ccd32d4c7a0cbef09ea42c20b636d1f711d220e23dacdb9d1146e0494401349749e5ed88e38295232a7effbae3aed6 00550406c0db882c6aee6cf3b6baf377375208c3e90cc44a067cee43efcf b1b055d1e36783f44bd2197cc17b812a720bf09ac76b66e1c5a877437fa790e9b2fece0b4a50bef73ede295c24c32f42 +3d36221f87157ca4db84884b8666660c4e2b6af330480c516cded9f3bfe132543626a39bb6aed1964eb5c33ea0b95b9841665417679fceb95d199d55accfce35dd3f2283c1a7ced57d0c4b9ebe3da6e1ff2f979b6440db27caf9f6a4bbfa47e20d29ae304f4d0551fce9cc4097eb2fbedb9b24680bb17d207bdccdbe799d5b0d 00257dc63752920b6854d6c2d1cca68589a38418c3d036e73760a12214ab 90a48cf554206aaeb25fb6f77d4bd8462ea0b66ef9288790fa5956315218053505ce92735c11ce22893dd5994e43b9b4 +033d82a42d0eddf58fbe3e91ddff7190e3f9fc2b1e2eede977d2c0473b358b5fce1f981ca6f88fd61ce2f79e453e3a2b77d1baab2b970ed28d5dcff58873a620e195085e61c4b8480d829525a1a944e8a4b63352f0291f0311f1f98ceb262804beec1c74947618f8e3b067866255878c2502966cefcdda4f5fa2b13d92ce7840 0029025352297a7be850f8852411c09259b83219135e0e8949c1bd5b94c1 99e01a5d029dfb0225bb17a950fb4ae1b00a72f0311f0f1450d293d1173e16eb11f06a5659403c68b2347ad75a6ff4d3 +671a7c81b64b2919722d7b258bdbd90165bb757b53106e0af03d0eef27452942f40cf52bc95cc7f6567df2613cce795f8bcfc723b2735efc35375c001d37c58480d89343697146b524835df3dbd333f7c06c98e36d3c4592ecd1f34ab57c341bb0f4c785f5b8372775f74b4bce60763fad1788e77ea158d735a64861320b36c6 002dc82d0e69e498528925c0e62a13fda9af8cefd047c10c3ffc2e41da3e b53599d6dbbc8e913e4bedeab1905afba00881339dec712a91efbf3b92d90c59612c5a0f112e2894697544267fc2fecb +0ef677f4799298f4aab73b7393598041f56e902ced1726af49657b6601a06186212e3ee8cd4bd33b760dfa2ea3c38884f94358d51dd479f2ccc8b0b352fa4e44fcfdcfbb24919d04e6ee1108527b8e8d60e8d1b467c30c18c5455e5835d483161d3fc26b4a67d6df9e3ddd9331247cb18450188752a1ca219f3396a872cb13d8 0041535fff5d279bcd744b04e643458ce20b81df8a9e01b1181d52bb14e4 a0c69c35f926797f13c049bbc037753950c0d0d0090588b6604662df5627280fa16b2bd6a7014c286d483eaeaac931d5 +9290df0cc50c3cab6655f3a6de1f4cf613d9bc06ea7c99f38038369ff2fadefa57a3c7ae7940c1b98bb1d03503cc271f7a891bf38eec93c31dcec7892dfd2e1ab337bedde3e5325ed8d9cb7fa3096f6fafc3beb3a66cba66ba826d1032debfb4908cc9dded8c0099c85072daac4373fbc428fcaa9a6da02181ebc33f0cf926fb 0000ecfe580a624df66c25e87e7689fc3b471d205970ff9ab51a64aa12ed af8d833262a06e0a2f3b8324386555fdd1937a5089daae78120241905ca3851e03ad6b1a5882ba2ef4d9e5fb5a28ac51 +855c7be75fda372f062709827f333630acf28954a62a5193ff675f0dfeb63f32bca418f7cbdb346bf388d62315b19a592267ca407120db93d4e3d7125b867c4c4670b7a57a76f61734cead2caf2425eb9ff0a63293e8cd6defc9648257b401463f4533a2425e0024f1ea93365eeee3c6da20d25928602ec8b426f9b39f97f3fe 0013c72c73358ffa168423149ecdd897f0a5f75a641de008649f00134944 919e6bd2c63a7ec03be11f3953b32b1629b59d07158fe31e053afac1aa07c903fafc57c2cacf7672032ade301f6d4329 +9c896f800281812ed57d31623d563377a5c725cec84313472b90e73f77d400f5d4fb236255741b73d46f7e5254d04099bec274db8a9af5fc7cc220d42cc172cbd3c3595c49ff74bfaab7b5e46c90855b611f74753ccdbbabf92e011d52e9ba753b83ed2a251a632e1bd5c6d346e38e743950c8ce0f394a837028575fa44bcc26 000ac60e2e70b7c4cda64071c7738f68773c94df9456a8ec3bbb468fa7f8 8e5331c90887a75d8358e9ff1ef6a140dad40209428fe36f299c5ea079571c955072086c6f957fd355febe43cbfc1b36 +139a14ead998d1a962fa47c47ef2953aa136bd912fe940709b8c560bc2a0c4bf8f3aab30a8e21b7d5f487d30b0097e3da723f11b5cb4e8c5724f5a2fe0d68ee4bacbb85e5eacf18094d2a8ec4506cf8497836a4a905059a998ea750adc54c27c69cbd0b0c1f9743a62f3d988f3fa0a9865a73fc071f526623085a2ef12838888 0060bf720052e8b9508a801340c213cf53bbecf4975faee63d4b44fc647a 87ebb1e4f742e8084e44e95268aa086ae889b1d7f362ac9089b465de8a73aa0c17c580b9b2ff45989f7a63ff9ecca0c6 +cf4a8e754b23d0fffc1c5c80b0cb11deeaba3064b315bc2cee96db5b9881baf90d30af4b69066f757b3020706def77a5fc1632d96bafba22a9c8cd3b52d535d941b3c7cc02b7fe6b51639d5e2084478ab3a29d2f5e0e16639fc2833a47b58e2c3fb5b2ea1830fe2ff68e571a8f281617a23d9a28db1c64ddfb1083d055030e5a 007cf3c216592febd8630a478b5b3e3a605084020322adb13ac0a626bc7b 9755aa5ea9e2ddaa39f98e7aa6e01a88b297287021c19d41bd748b82c15edc7fc244d7e9214a5007d0ef23d016eb162f +ae64030d4af9b36c8d3a6af0aff34e5ab201df04274691fb420b7d5c40c401ed7f3ade96065d34f2490d17943e27156e7bed83cd7222d0d5a73d167855fbe7ff6c3ed87f20986ad8bbbd80fed5f9705c6c783b423f641d40ff1f367f9648af5a79ea3cea0236997558bd9dcb011ea4dc64d61ea1e1f85b4f696ed586bc7705be 0061eda5999e5a9ed4485d2a0ac5510549b76ca37df858ea5d95aeed571b 84094ee95ac75dc81ceb3313daea2c0556703eefbd599947a570ba0ebc709052b11959525690caaf5952486bb3710ceb +94a9d9cd9efa3e4ccf2a37f904dd9cab5624ec9393cf8816ea591c5e70cccd2f105388ae133708fb974998ae61d218c71785f9eb808d1c28d953cc7eed00dd9854b6b4568c5ed5ee3df3b58a1e04c64f1c87fee4365ec9aa41b08a6bae234dc43a0bf2f61420acdb891a40f17f246972afee75a4c0b249dee0fc8f9b9c8a243d 007e7e73171e4d2f2989dc024757c186485435b82544a448f5cfca05f281 aa2020c9dbc41b94ab40c799e0919fabde80580fe74f458df842406d64cae99334176f38ce92de54e5bae06c74043339 +4db998df7b90678b8aa4ec6233c9b4629800ad1f3e2cf8f7afcac62fc6982dcb290e44587015eca8dfe77dbb4a80f9bffe75b11e961e70deed14555db6dae47d49e73004f000eb8677c18f7e8234bf0a5a104266167a05ef07152e7acc2f0368b37efe69c0c2feb51eedf7338cf9ed398f066cf1f66bacd89ab9376d41da35a2 005f7270764a0444c7159d2db867930fdb0fb9fa6b8fc80ca02e11753095 8c58d2545085689597f7d4d0826c623832dde50fed4cc98e2261a64197361cc95782d1bcab272b6356b97b0fff9a7961 +dbf9b8a4ae316bd2df0c80db1cb5d7038364a2634925ff957d7c03511b57d486274b2ecf191746827c325a14dc94daacd66ad86d369e3f598f176c4f0eadec7e9edd13e34043efbe0a801b75b8186b4a6d89ceae4fb250ab570d65b6dd7c04382738fe3f6f6c867a7d84b35b20720cb0036a5d81a87126f236833831d9ff00b1 00179b924afa4acf30ecbe2b3c12de533a1f9675687876a7e5e5ddc8e03b 8e56bcef8656146e7c6040e2b40a65aa347f7615d8ff28617dbc71c8a214e04d5a079c0ab15787f396502c26704ab2ae +986d9e5d636526f4deb7545c037fe81b09c74496ddb8e42e61650c74b6fe348593f0cf8f8eca5e839baf62f17bf6ad96ec0c71dc44fdf11259dbfe7499157e402f6bd5076972354150723afb632799a990c44cd0a4fa9609ec4db133e3b4700be3ea4a338e8ba1873d345e80163ed60d0de274d7617a8382980bc2138b0a2a01 002c9eb4d392d7f2eef606e1861183acb1fc753d666225f0f154d9eda147 8cd8908e8bd0d6bb0ffcd48f1c8208138b183e65288404b8e5584056f70954ed033fe33a5110ce1f53342db66abdb18c +68d0be2883598bfb1433886aff118349157708690380c42b8919859d96db069c7fde6e117a3669f2cff94a0f1b66b27b09e3f1b24d26299e11552a084be428446f3174da2e0414655bdceb38e58fcb065b6661190862db39c6545dead34a03584632e988d0459659dc7c7c78d4d00fc2aa10465cf24b2410f14e2a62173c9962 0024661c89b77b2c743cc175a6130904461138ddc4ef771ffb9fc2c8679a ad15fe025ce8dd4a7a65914aa327a18512edfdba1bc226ff45be4a58a4d37592eb81ce53d32db6f1467342df1bfc185a +f0ba0407485fecd7337f4b22236533a926cc744a5f06dd08276750196f1bf7ea7984278f789f92dd07e36895a8bfe297ea43d4a1177c0368900e3b969d3083cbe626f0e27e7ab38e185c923dff46d9ba187b2acb9cf4b23ec8eedbb8044b96b5263d956e50cd6240c66d5d96517130c743752404ed09473f05d0004dc5971ff5 00065e20e5ce534576d7c17616cd4ede3bf4f500894850723bcc9f895f4b 8173f94707f73fd38168555119181950c3b9359e58624ca1942eacf270a2c8ebfd52359000506feb2209a894e17b840e +3827276694e413c886129c452c9a66e7d09dee84f5f09bf34e4baa308b4627e096c7d45cf6ef45ba1d9a4019a60399feec10fa80e333e2aff1251c85ca48574d9b9e1affb9666828dff5afcef3edaf5e8cae823505a0c73afe76c1bf130399fb06b092ba34ab0ae15ac6c682f9ee8479b065ce75b57213b8aae0f55e4e386de5 0014c85f66fbbd653f1e4e590cffe62c343ba6062df4b271fbd02e5d42f7 8301c336755ca4ce508abfc058e6b4d7fd011eb7fbcc849422747863767ad04a6593c0834b3506e3fa6dceedb84a18db +d1afb8965b48d66b9acb1ece674d9548f83395275f2d8135554cfcc7ceb96450d850dd874529433883709483d0743798db5e0dee955a4f30ba328c7934b8dd9207f3c336cf89141a175ebe23d2faed629eb4236a8aea8300604c3eb7704512f240fda66acedf1494a85058dc6a31bf9531958c332b93cfe5545046876c6b99e0 0030ac7a78593b570b29f6d3d267abb6ba7e5870ee1c8ee4f1ab2f141051 af2a85109c4540550d5848f64b26d9af2d24bace2419b458dd45abbeef49ca3db169fe6db4434a3a4ef3ee476edf8164 +4f95b71669fdfe5dc46d4b951b085e099de349fc740535175337127910acf24e9a0e4b2f23196ad23880da47b740d77d74fe9bcfdcc44dd7d8d1a181ac290de5cf4da22d5034cda3d8020bcc776dde8cef1786c9ce4d2c2cfb035da61406af745efb7ef1a55f2eccc5000319cf1d6380963025dcea641cfd15a3106751fec286 006d7516aa040f7d559cae248e485834e8d9bb608279ed4d4f7e1dbcd2b3 99ca00c28488e2e5944590584a732a61a0e943fdf6cd672b2d2cbc9b0f2dbf388350ee14a0a512cb6a95de9f4e037f0f +2ad9e17780c824c4f2d1e1cbf19ab85638f2f71cb4fa3518f08085b8b358f54d4f08394a5ac29cbb3cab828c5f07f41eec51e6cd61a5f2cf44dbfa46834370cebdeb328fd3bf681e61011b5c2ebc8945ac7a2a8467606051008b15c89390e111999255bfe28634ce9bc2850a2b55a4af1c4c2f94403c78aba1ebc87386ab7b32 00137050d7b455f43a8dc2516cfff5a91062c1a2727b27df41488f3dcf18 b7847a70e682889fbacbac3095e0b0ef3643a4c0ddb0d8d909e132e377128bcc760cfc7cb2d2b085c264eccc5ca8f80b +958773c37d3eba003aa5c489f72118b3022c52b93399e9d8001695664918b86893f4922c7b6e55b1855ed0fd1d8de5dc61af403ad660fec60d7c44bd0102c069957ed804d0d416facdc1a95355ef58554606579ef89b1842f1055cfa2ae118abbc485356824cc09dddb77d0671cb3011b33bc86cac526e3f6bb3293c7bdca1ff 0001fd447b33a2ee3595b9f885c290d241422afdd74c3dc4981955a7e9ad 80cd66fbbad0316f404879e46e1bfdac21f88f772112bd010a70a5bf9cfffd2938168972c7863d2d5cef1d7f1cf76cee +9cb2c496b1bc7f040228571e005e7e936e48e8f469e295edf914f5648701249a20bff6b98b5e862603dd9f12bb71c160aafe9df02e2e383e9b8a9a9d700f4425ce408feabbf754be543f52204c849fed6c9d3e36e03dfbd9e35c18d7bb2295f1c484a66e73440a0a5aece5fe80b9ade9321ef18cde3eb2db15e4b18e788b0441 006a061e10b4a6e7001d95411cb31bdea9c84670a59ed61b14fbbb05c8e7 98126816d8cc1ae837be7c4fa7c756a8f25eabd17c1921c4abc99e5e624eca3f32601d4331a4aafb4d49a0d823b7995a +9a4bc0a029e97742ed3bca207d5912cb568e4403cda106b00247520ea02008b14c041b8c9b976294252da835f4ff27456039d79d90315abcb0b9b6958a22352672e229665457ec79571ca80447c8ff2a86e6af3dabe7427c8bdcae65e3c6746a56079ce2cf8d22235180f46646a21cd9e86032cfad874cb9c67f882fb037a13f 0027ec31ca31acb4d2fbacb49fc085f1261b0042cc755cc97f9b199e7a37 934704456259a13f93b3c76b302b4371c9be04644106cab5950e46778c557da9f77cb5689043d224d35a73ddeab59007 +8d89e22cf802dc68ff22d43c436c79311e705ff6fd845e77c880f399f403e6d5e9e2b35511553c978171189e288cb2200fd95f84ec5ee9865c0eb9190aff6dacf783ef200e82027fa992741876456472bdf27f2bd8ee55db15408c957a120eb64cd24d299818726a73fbb0697eba726a326719765735b37a2dcff0c853c906bd 004c6f4d88e5a4f4f83196f2dda9dcf2a66eaf94d50c851f59bfcea1d876 a8d8bcaf8dd168669e12c2283aa2477951e868ffab4835a58cf5fcc21a9d7ff1046ec35c6a6ac4828b3c35e661608aea +aa1bf5a79e5339fb9ef6c2817bd95725551d064bc5064d6586c5a879901adf808dc2ef7c78ec3b434b84569988db58b5e8e9782b1cbc2cc7c9b68e66f32d4ac4ebe7e75b345f654c7b8a5e650acc9f170f75b7aaa3957cce248cc69cf93faf8d72abc6fc1cfa9ae2d18a7b31ce720147e88e84f6563b2197882fe302449ac5ce 001aa169ea84365c22981bb766bfdad27e373440850569957544b0f9332a aad68a821e4aed3cb65cc00d208bc83bdf8341c6a7d4b15a06dd569dc1913958c02b5575f0492dc2e089b40a95416a3e +475664d5e22cbe0da0d0289ca9a666a37270dc71c81cffac91f6229fa39315c1d55f7e0a89b6a7a07df7d391dbdf8fb7af63d2da46ecc3b60110dbcd842da97f98d2b67f562b0364ef8e1c589519024177c8ea079794f271f6d35554c0e9d0a39062383c95721b72f4e74eaafb6fbfbda02cb670a7c4c94f67b8ebc6442e84e3 004a665b92c0c33a3f8b9eb4b0ec061d40b603de36c87096455102ffe57b a54953b2a1925cea90646713c3e5535e70c180c7047c18162e68d190c6c42c4a3f1eb52d6c8cbe6828753f251a640271 +9e5397d94465390a82a3c07e3ebf21b515776d18b4463aa5810e6b2f96ca61e92d13e034fa853c3fa45411f51f79df6f799a2c6906e6a5b7896a4576a4464f9e0be2b529a43e1f503fb640d79db6b68f3a3a7deac1b5832fbe86673784ff6db1f8438f7dd332cdd1e7ad9df8b6731aad1b6a72bde52e6bc62d80b8da57822c48 000531540d94823e19ab2b95cbc6e7492e1effcbabce875de6ba96f53aa9 acfa92378efba51b960954cdd761dcb8b3c831d4de4ccf3b0e62293f84c88c4b987c1163859c7a2c9bec86617a145d96 +3cc4c4192f317e52df6f8cefba6d4cd823c942aaee11b9a0ef5de5c2d181073b7085a55805e9554def8dc13eb978e7396044d4f4a14be2c7605998c062095c929b9c23b2b1b2fa73dd19a0c0af44ca4789f9841fa62dee8a5f91b3cc4b3264f5f67334c3f0772b30bd7431c3fbbf1f34318ce1889b6e8a76ce6d42079a451e56 0022a89addd8b85809e87e0aa2c038593ec277054842854de1197833a51c a0ac0b7da7576431072d6489e0c87c56f8d8bdf7702919bed61c774a344d75134c31295f467ae3534cffef036b2d7fc4 +72cdef5bdf710978e0aa334b86b8ff4a58630da314eabe98b4d611aab56f55c526983d54d19bbbf9ddba30a84b18aa0bae9f9503e9b222f842f084db83aa39625403213ca321cc0d9c8a136c826e6ea4ec108b913dd0a9ce9d5b8c7e3af53c3876e56a2037ebd6d99f037a097111c837647bedfe4c494e4288ed6427c15969e3 001df252a11ff97b4421b3a2361db94e908e8243cd50d9179f9e03e331f1 b4216721ece05957ded427aba20df1ecfa02a6fec99da7ec4bfeba5c8466e31171ab0f6c93efbb3bb39317144b143bfd +8e4eb88c0b2d525b2c58b8e00f32def90e6dd382301de49e0ac053dbc6b61afe926d85193e2c4948f7402a3d7c614cb2c58e060362b0516a1ba4a7425f1b3d09aa20d4c3c8993a387a3248aeec51e6efa8f558dbdcfcaa13ee08413227c8351e3107e9a3e3ac124224aaea91bfe50c11c1c8ae582e718f50bc5d5c06076517d6 001d7125c299ebd0dbcc050f07de931c7ad0450af590d0a2d0228a66ac5d 8bf436bcaf34855ba217b58a584e5e1d48dc2703e89c974e511a80d5d358d1a1f13204843dd702db0d0c0bd8d85ed69b +370fdd80f330311dbb3959666001bba61cdacf20f72f78953d946fa6cba02d24b5003f5452d535609e489b9434f192011f99f918defe877d51349870e7e75502f61145f7c261dbd2a0840926d824ebe9be3c5a77a3a84340aea930378367ed3615a47e3f792c7773f83f91ebea718a05fc62e9ed1d78629b2c27ae44fe8f8d4e 0021238e66119844b146d40e48341f522f6ac2f9c8a0b33aaf95a3099a41 97aa6bf0c9a0ab5c80d9b15e68dc9411ad478ea4c550b04fe165b4a7216cbabf807449fcc8777185cb84d902c052e485 +f86c4433787c3ec3cb1663389ccf53d62f9425274ccef05fd14b1b8fef676208867764eb98d16d006ee6ebdc27b8d9a8ddd303d941fdd82b630694cdc698bbe6bd524411907834286c94b24ee199fe6d646064277f244b7df3ea2d9d52a9dc6a33d7c8d6dbc919da0fa987a67621ef0829e48310e0ea2bb86fedcf4effc0b94b 0015e1bdfdacd87c42ed439f3e243abf27fd42e54f3ebdfb47f60dbae5fe 981233fdd0115a5d81d840ef2dfc7d47b0f9d58f58a5f35f6a211a04427670dab3be20fda923a18fd61268a47a91ebf9 +4117d593aa92e3eae1124ec7482737cd3573fe5f0f2a5051a7ce86946a2abb9e47a0c6ea75b262689b0b486476d2ab09a20efc2fb921419b1811b51a2e15891ae9e45a17ab4b96c665c6c423fc00e2d66df5804a164f0f3c958df6f25d7da6829b1fe162a0a8cf130858c83f3555d6ad627db70cb41303cc6380f7b3fed2563e 000e09410548c17bbbf28a68c3963a52d39743a4f1ac28e6dfe7a6ede281 aa2c94923f3b7a5be176b385c025ac3bdbea2917b15488fc9089337e51c69b9efa45803692740634bac186d0f993852d +882ecaff3ec8f4023df5397167f238869f78a5c499be19aea85c7486e73f66f0e08e71cf85f3f1b6f6a70796bf46a18e6b555a0a87c2088640ca73051b3dd59ebfef922be0372208fce602d8001681297b285701dbbe24ccb42541b5db4aac1a1c7f407e11c83db15b38cdbc25e930fdc6558f64d9503e214571a435d890169b 0049f5bea6e72d98579b78cb07d89f64503f8759dd7a73cd73713c120428 a4a40060b869828da4819aa7ca81ab030a0fc217b0c872f926cf51f58672f02bdee98a85a8034b347b9bcafbbf25af97 +99b3b8f876f8359bd6369ce84f9261581c52d744b90261a1427ab9e447e6d833b6b3e89af8dc770f1dd55692d01c8bbc4277a729fddfa7cbdb2ec99133201dde44ac691a77904ca816feb0a1aaacbb9fba85048bc63d73506eb908ecd697caf582747051a3a38ac8930c9a4365f407ed94ca7f2d26913c53f4c010c7ed9d7ca4 0005eaa818690d1ca4838f0bc667be5721d178c3869884260fb230277c3b 992c7abefa8676265d10f49a29b12157144efec3522faf324bbf3aedc5c367cc50ccd339551f8162149eda27f4923041 +8c1a83023930a85c5b2f9930521b8b8963d5523a3323d87f862a17d3505ccee01246ee1029b8b8c2b608772c4096d1e914cb398f027d91184a8e94e4feeae121eabb504a2a35c8bc9294edd15ddd979946c14c792ad787dc2d4deffa284830fc90b3f8c0ced6a99fc6de7c41b9ed261402a6b3d702ff86a9392731ecc37430c0 00603d89cd2f741d734587e77554fe6bbb1e5739d5ff73084d4de8ed69c4 8a4ce39e6c5bcb6a854c5eefe4a40939f896ac584e04a86125dca117fd6f7022d9892dbf691e8e6ad021f886362333e5 +f3c9dedd7115339dd3ede7d8d06a44de66bf80b4888ab7bc386cd40a92789042440a13d2cc90dbcacca5feeec1e0e3c51724146e2c4904ed6b05c7b4e9b49d7f458ada695c5d2fc36f1193329b87c1268aa38eda9151430aa0bc004e5d2a61b9390accfc699f2efabfec785eb34f52b1beff1e4c5492e922acc348667d2a3986 007977b3aba53616dac27b4d74930da23966a88ad98f1769674789c0be3d a18bb7eefd8145d46f3365bf7b070f14c49cd9485d89daa9dfe542a4460f4ba62f6d29ecb609f898b70384fd31b81a22 +d878c4ee0bd6c84652d7f9e68df7b90cc78776d8d1b60f3e4d7465032bf401f1527ca7bfd4a3dd916e13e93fadaa5e5f20c9f47d12f8fc922a9a3aaeeeef294c221ca1adf7df85b888faec8002f17ff202da1be837827619904121167bee2d2cd694a263d9a99062cada3399dcbfcb283597a96ebec129c65e0850ec4cb4e2d7 0050cd20e7eabd29008cc977d0a17e1195d79587b8f15ac2447e15daafc0 b2600225823c40ae37393438c97b44954c9f38f1da58bd98b8b048810604d68d6816bbff95eed4269787e092aed4d312 +ac3c118cc9cbc8eb3b74d8ccc9ecbd81d1996fb25ca43c8a43bffeb244f722b93c9e969241d45d5b81fda0b399f1e3623687190e428dae077e54cad1eff75ec2f7fbb9434bf716833421bc2634885677579c237340f76787b2eb19b446d56c0f2206099b81493349f4db0ecad0e2dbe85dbff7d7070abb3d3b12ef0cec828af4 002dbb24fcaf9f3cd5d50d209937f0e2d134fa20ee3c9c2f1fff3dfbf302 b989020de950861328618f438b410652991ab92336e8855e45274028ee3cfbcf919d63defdcc523e9fc406315b94cbb8 +700313698cdfdcf0044ca07bf9e5f0702ece7cc66e35decb28d5f8cb7e7e5367a95cc1728a90cc9a53a2b5fcd4702028b742538e9b386f5d8b4a2411579ed9553021a95bd00a73f03c4184a6145aaa367e3af76659d677fe7a2e98f9ddf4aa20eb8d1a1db72c3f5590598801be7ebf44255fd7376d89d998b7068bd1296fdc38 00047142197d3d43fa46545b547968680ec81688589d1ec8d7c7e90eb969 9946e146e43174677f62f9a191bed67e3e056d77987aee38263e5becb26aa54a892439ca02ba773c9bd64193d07d5700 +0374673e1a685bdee55504ce3cd333f70084dd4ae685464a16924eccea34531663fda60229166478b30193459a3113253cd6494dc26154156252dc6e822552c7c04d790eb9f8fcef2ea8dd79e72f881f7f20fff93cd73ad303c0918ec27c6486c4da61f82bcd55422d16650cc68bfd4b0132c1e7075bbf17dad919095860d445 0031352b49ecde5434aac05f898e6ce4337304845d748f114c14319fe97f a2df0c1afd5f531d3b2470938918adbdee426c18318a66089e13ad18454fe90af4cb14ae541583c6c3789932fea5798a +8b237085f135d6e94592f8d855ca397c8c1028236a3b412adefdac888245874f586d06950ee18118f751bfe26f4c31465ec34b578caa44cf1b7109ac4f6eab7f97ff9699b34271df035d3bf58a2ed4bcbf7577cf8e5792b1945ebb9389b680baeb8518c8fdc5540e192aa4fde0eed0d7c82be2e362b286f582d65752c8db7038 00176f124c24e4420f6e726a6ca25f09dfa0c5a37e5bf879e7bdd36c3b65 8c89e864cc2e606c333e02036dc684250ed2d48473bd26bfbb93d53aca28e0af3e19f060226b95763de4c159fac0f0db +e3a086ec15574f7017b3cd5f5a47ab7a73980f11074333490dfe9f8ad8926f9ea7c82271aaa74e77133b1025b0b22a6900fbb71251bb6549341a23d194e79d03462cdad52ee0d1b6f5d0d14e1136026961fa3467ccf0864bf7ae3fcc3b68cb35df7324bd9bbe58fc8aa9f63c19feedf19d935b71bf5981c74fb2a487f84e453c 00755c48c3dbaf71042c58cb137f3632e3cf9d90b7b9a58fd378feef3d19 81a720884a49da64a1a2b79cdbf157fad89ecc8d1fa2b9bd8c4bac9f020e2d6b6efd1a698ebc255958c7ea24f7721a4a diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K233_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K233_blst new file mode 100644 index 000000000000..50138e00ed3a --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K233_blst @@ -0,0 +1,60 @@ +f23f784fe136c9fc0d169503d361e9c6148b0f1fbdcae0a97fae1af7033ddef25cb7489c9963cfcb009a8cbfe44a8510a64a073eb1deae4c324ceb9302008c92c69b2dafcc9077fd3cc3c7c119edc3ced36d176ceaa55ac036bf7f07f6fa215e8bb8196e59a5e1c9af4f98b90ab4970885bd7015fa26a09e03c7cf6b4b23d929 004c1d414696cc3657dd9df73ace56eda2636769ce7082e064c260be45a5 922ed45f69da7a5829a615a674413ab957ec701efde8407fcbe39ea03ee8306bf9fa3c501aa5a3d0bdcad3764c9c0845 +400bcb297552bb37f2f8135a9314a35f5126788bb6fa4dc74152731ff64c5dab4b902103d85443dec20e16b1d6629930cdc2bd183d4099f0e96295a63c2fe266f5e9d050c401a8681b4a438efe53cbd8f2f43e2a31e9f88926a9c82917d873f6e8cd5ff5eb8c1ca36126b0bfc8c2b0e85a7c9e7a45f1875ca9c82019ebedb729 0027cb1d84865a16992476c9e353283d5d6a40c349a8e9179d1b1f403531 8e21754db2e54d5092fc3d856534f800dc9c22d44b25ce12ccb07df16becfba5a6a7de2e57e7ac89883e895a68c29378 +5f74d4b35c49fa454c97c05fdb6b9f6822cf1a2295f15bd766dbcb413d77c910bd8f4147e8f317fac2300fa21cb80134d1b6f8ae8e50518c1f648a28506e419f5a6e8f05abffdb3dd2587606c7e9c223ecff4f46b121216730ea13202b59128a7616bb2fd23a7e4a5aa08641cc07b669641313febfc88d64d99447353dae3f06 0031b443f46c4b5224237fac1022ee1570173f664aba0c84dbaa4246bdc1 b89df9492fcb4d11f4b986e3f884c936d8abd3add67ea3c2223a42132cc185b7797c34d9f0777a3b078597a576782db4 +8f92096876d9f81bcd992369d42d0b5877ac969004d17c8627c58d8b8b7bbf7a37e8cb6afa962b9b043bbbaa5bef4a5ee38d8bd31cb5866b828265a2f4102a616f87009cd346fcb8af5519fb577c60d8792472232f33dc615655e53d2b715b15a2697b492f108b7906e1e3597c6911f8cc30c7121ae338a6b747ec368f8e4a36 0048f6ca29f35f253a4962734357c995920967b9eeff1ba5fd2080bfede5 a3c35483d31e9d1ea55447783ae57a9b9b83bd1c3e2b610d04f01df13e54ec5727b3dcaffa12121e9e6a16a6251d641b +3d275dbde44494c45fc15fe89e2ae32aa26426a17e923e895c7941a5582fb95df4d49873ab1bde358017f336b911b886b626b744806ab8113418473c441f1964159ded1b12122d53ac56573167588e4b55f36b8bca8c67823883a51fb6e7f204d1c6b07ea49b577bfab9ca6b8d51f72268b022e3a4db6f9d265ee8382f9b7b66 0019b940eabbe682f961d9f3d90432e347fef3910e641656825d775705b1 b4611cc6cace3841e25f683c8844042dbaaa776d9c90c44e678ce0338827c4b5e335b3df026211c9b22232fbd34562a9 +d2fa68e1f7dad02916b12fa38f1849d6d409dbad0344438520b4dd9b77d62d39ac9ae3cdeab03ccbcfd4de703c6e798873671731c108f322b9f2a68145e3e210c9b15b879798e5c53c5022742e9819b99edabb2f44d89ae221f7a99dc84421a6905695ff91928db608f861745f17584d56e34b75c47281435b1b0b34e490692d 007a884b22e29fa9fe945e9ba13c0df8d786dc87cef0f77f069e182dd56c 8b3af12f875e5e03ce22f58637e97df09257f1632573aa82187f9c9d90ac361514b476db4b5da87ca93f7d3d446764ca +3830f75cf9df4eb2998c7c1b5fe11c1476bcf849c3a8fa7d3d0b5bc2292e5d07465ab8cc9381c575d909e509c5dac49c78817c04e4bef18bd51bb09aa5897f21634633a5ce6d20bb4638cb6c3927351eaec7b62cf4a33956916045c392f325adafb10a88a5f86d7e41dd77908fa7284210071c22aa40ef40da6339c02da05392 005da61f881d5a0dc085bb93764f584352882923cd237d878220ec624c1a 947e1a2fab78b180dc5c75a61cd9c7c7091c630156e97c6f5a01fc5faf0c2d373bcb508b1a56cc30b1d2d62f1366e3db +65b9fe15e6c35d453caa6bad39ee78a720a04b60d8a0a0f049186d2f777e48ae2d657e174df53edb7beb9f7d8f21904ed674add0cda5b62a7308de76c324a144021e8c6d387daaba4ce48bf7dfe9c8aeee2c64e434ece1fa5ddcafcf3e5d0013a1eeec1742a00d384cc2ec0d7eda83bb4dccfb0e57045ebfc27a4f404d03da37 003fe9f04647f6d82b13ec1ae5a8c2e49bc66b05649ad778eb16149ad83a 8938745dfc8dba2a82bc0e634f5d0a2fe4dfb62a3298d1d592d0f79e42fa1fcc6f6afa762e6f132c54a80db7546e02b0 +d26521fd41eb5d46ece6836e188bf9cb1b461d011c41e002a935d256654d01725378e845920ec4a7fd3f379df54772493df50d312c7c6aa4e909e7b83f2442c3a5e85c37d68aa015098ecfb0a5e077370f4576f4bc63bf37e1dee06d780a3b6949af5e21c2a0960fcd20821ef5f17bebf5fd5b3bdda260842cbbfad45667287a 005ebce648ace4cd555413de6a456fc487d14bf4b0b9a72311ef480d2f26 87160d9589987e4bdbff1fce3535004d807368320948833c360cfb1beba4d571ca4fbe46ba85bb4374f74b4d78fa42ab +b778c021b1a92c41dbd09963da07018075d73e54d62df5c2b7bf8abe137151650d1c1c6abce7eebd8f32e8c3e6d1433773f257bb3ba4a4fb6a02c0db1e47d03c27d3a90898ebd1927c21df24c4c5443ca5b81f8ef2cc0f5e8b3d08f472bf07085df737adaedec63d99acd77b87ba98225f198b791124ac2d9b191cb9251b4b00 0056653c2f85593f789a926ba49fa3da9d7f946d8f1020508c5a527ce813 84cf8cac09e50295f881df480763f4e4838269b4df2b7671dbe32b22984297ff781a900282ccbfdfceaafdf095cebf12 +ec14e07f615960015a489ef999e308b42a4c571473b9bd64b433dabd9a1b1ad02e33eee9100064405175928a94543a80f440040afa2965b4e5f95f768e7fab6d3c0a5f5e1bf1df7822f78384e80f2955ea85f044ac60537d895747979f935bb0cd3673193c4a32dd7803e48d7daf70a71bc2aa97236615b6411e28fc9a652145 0049a91d320783cc70a5952c32036cfc75d41f1aa84127db2dc759fb291c 8703328185b0e1c9b9af670f597e97e3d222de50a73fddcf6396e66dc2529f82fc28f27deb8b988c1972e679db87cbeb +89c645339ad0eb850e4e2fe583cee175b35feb02ed7541d7e9aace24cdd3939584f73ad39526de6399c86b36de77a018e2c70b532bd0f032f9137d10480acc30c49f9baaa86f9df0033b77e98b485bf7a69cb5c281e527d3ccd1fce2415f0dda4a268ce68a0a34b16afda54ed922cd6810ac8dc766df2a3a6c5e55972e9786fc 0016a20016602fc7088a60469843e1d29ad67e3c3cb9500b1e2a00d4050a ac55391cae58c6f97e945f111858075540eb93f280cabf75340e88158960eb4fde9b0a21d9dbd261421a813cc4483b78 +ace14c4b101d2d8453c2bc22b756af016b5de537df9c3e639d208ad04ae0bf6232dc90b90c33228dc85de956db771ffde05fb4d0b15e4f218ed2771d703ae5bf981252a5bcd60c16f14483131a481cbe04dc0adb1fb8aa32cb48bb5008e8a8e5c7b7465be2fd7afbc811cf5ea6293b1a464669b49f55f57b93a8707e6042fda6 000ba922149bada2551b7be1c3df076f3f97ce93c13c50c285fef3f42363 96b23d0cca644d92e9221d1443fe0cd963e820ce7325622f61a5af5d5d1e1934448ad1f3028d3b933f44aa572586a308 +cec2ba0d1772c87e87d5bbbd67220692bea4301aa1a66e8dbdd7e651d45c26dc2a0d45cfc32c34d76ae3e1c61db7b0fe1863457b93937d929e6ece7462ebd16adfd708353d6f7c27aafe06593c76da7149b0cc574a4290b0d8fe219f3eada7082aca38dba3f78ed0d5942d095fa5556fc8bcef331ff0a6d5d1f4e6c51d4ff5af 002d635e12a58cc6dea44e71e87c37f91e8d08659f0b7955d24f65ab55ba 8e256e16b395f2d524a382b794840a62ba41211454064c78692fd7189059545e8565e23abcb8a4318bdcbb032dbc552d +ffa13cd0f51ae2643d5d4edecb493ddd653e9faddcffc370e7e958abf726a5d67a2ab36cef42ea8ebe22a6f01b9c31f6ffad01e6894487d979acb5e618f765ac0ec3550ac5dbbcede8f9fdbe52fbaba5c087ff382b6d7a09b2b5084227d324d98ff98793040884799b96d2ca593201f4414f18c43b51c53c5e5059e0641aca02 00073883e5064e06814fc4de32e15f7a6cf825d2daf6eb1df8c83e25d80a 97579139a0edb4476b3b194685667705f28e9eac581eb6a663aa8f7a2412b4f4b2ebbe645687d05f73230bff569c1187 +c73e3dbac9513d0361dabe94071faf03a11cba18c06d131a172d5f0125b01a5eeb6055bf72c7106fe3f4be3bd2b1771cbe7f85366dccfbc3bac20538510c3f51179cc540ddafb2f3b05a0d276899674ab1d7d8fb4f6838f04e4f9e26b8c6af31540f63f4953c85840af4c57dfa78c704f637dfc8dd750fe45e2c1e149986d127 001532271bfae8d4dfe60f69b88d3006d58e28aacfa701861cde8d624db6 a282f9ef392e5ea0e90305ee272b45b851083d8d21f0f1235cfe3b2311025d0f3c35b0ca6d6ce8c9d36e05731d2a4669 +d00dcd0f3212a3167403abed91c20e76f5e7a7678a4fd970f944d11e6a8cd149d0aa6fd3164c5a74c0f55193a4fa3d8ba6f99cabed10544625a7bd92b3e0b46edbd4a269bbc10518c5268c3910a2aea567ccd32d4c7a0cbef09ea42c20b636d1f711d220e23dacdb9d1146e0494401349749e5ed88e38295232a7effbae3aed6 00550406c0db882c6aee6cf3b6baf377375208c3e90cc44a067cee43efcf b1b055d1e36783f44bd2197cc17b812a720bf09ac76b66e1c5a877437fa790e9b2fece0b4a50bef73ede295c24c32f42 +3d36221f87157ca4db84884b8666660c4e2b6af330480c516cded9f3bfe132543626a39bb6aed1964eb5c33ea0b95b9841665417679fceb95d199d55accfce35dd3f2283c1a7ced57d0c4b9ebe3da6e1ff2f979b6440db27caf9f6a4bbfa47e20d29ae304f4d0551fce9cc4097eb2fbedb9b24680bb17d207bdccdbe799d5b0d 00257dc63752920b6854d6c2d1cca68589a38418c3d036e73760a12214ab 90a48cf554206aaeb25fb6f77d4bd8462ea0b66ef9288790fa5956315218053505ce92735c11ce22893dd5994e43b9b4 +033d82a42d0eddf58fbe3e91ddff7190e3f9fc2b1e2eede977d2c0473b358b5fce1f981ca6f88fd61ce2f79e453e3a2b77d1baab2b970ed28d5dcff58873a620e195085e61c4b8480d829525a1a944e8a4b63352f0291f0311f1f98ceb262804beec1c74947618f8e3b067866255878c2502966cefcdda4f5fa2b13d92ce7840 0029025352297a7be850f8852411c09259b83219135e0e8949c1bd5b94c1 99e01a5d029dfb0225bb17a950fb4ae1b00a72f0311f0f1450d293d1173e16eb11f06a5659403c68b2347ad75a6ff4d3 +671a7c81b64b2919722d7b258bdbd90165bb757b53106e0af03d0eef27452942f40cf52bc95cc7f6567df2613cce795f8bcfc723b2735efc35375c001d37c58480d89343697146b524835df3dbd333f7c06c98e36d3c4592ecd1f34ab57c341bb0f4c785f5b8372775f74b4bce60763fad1788e77ea158d735a64861320b36c6 002dc82d0e69e498528925c0e62a13fda9af8cefd047c10c3ffc2e41da3e b53599d6dbbc8e913e4bedeab1905afba00881339dec712a91efbf3b92d90c59612c5a0f112e2894697544267fc2fecb +0ef677f4799298f4aab73b7393598041f56e902ced1726af49657b6601a06186212e3ee8cd4bd33b760dfa2ea3c38884f94358d51dd479f2ccc8b0b352fa4e44fcfdcfbb24919d04e6ee1108527b8e8d60e8d1b467c30c18c5455e5835d483161d3fc26b4a67d6df9e3ddd9331247cb18450188752a1ca219f3396a872cb13d8 0041535fff5d279bcd744b04e643458ce20b81df8a9e01b1181d52bb14e4 a0c69c35f926797f13c049bbc037753950c0d0d0090588b6604662df5627280fa16b2bd6a7014c286d483eaeaac931d5 +9290df0cc50c3cab6655f3a6de1f4cf613d9bc06ea7c99f38038369ff2fadefa57a3c7ae7940c1b98bb1d03503cc271f7a891bf38eec93c31dcec7892dfd2e1ab337bedde3e5325ed8d9cb7fa3096f6fafc3beb3a66cba66ba826d1032debfb4908cc9dded8c0099c85072daac4373fbc428fcaa9a6da02181ebc33f0cf926fb 0000ecfe580a624df66c25e87e7689fc3b471d205970ff9ab51a64aa12ed af8d833262a06e0a2f3b8324386555fdd1937a5089daae78120241905ca3851e03ad6b1a5882ba2ef4d9e5fb5a28ac51 +855c7be75fda372f062709827f333630acf28954a62a5193ff675f0dfeb63f32bca418f7cbdb346bf388d62315b19a592267ca407120db93d4e3d7125b867c4c4670b7a57a76f61734cead2caf2425eb9ff0a63293e8cd6defc9648257b401463f4533a2425e0024f1ea93365eeee3c6da20d25928602ec8b426f9b39f97f3fe 0013c72c73358ffa168423149ecdd897f0a5f75a641de008649f00134944 919e6bd2c63a7ec03be11f3953b32b1629b59d07158fe31e053afac1aa07c903fafc57c2cacf7672032ade301f6d4329 +9c896f800281812ed57d31623d563377a5c725cec84313472b90e73f77d400f5d4fb236255741b73d46f7e5254d04099bec274db8a9af5fc7cc220d42cc172cbd3c3595c49ff74bfaab7b5e46c90855b611f74753ccdbbabf92e011d52e9ba753b83ed2a251a632e1bd5c6d346e38e743950c8ce0f394a837028575fa44bcc26 000ac60e2e70b7c4cda64071c7738f68773c94df9456a8ec3bbb468fa7f8 8e5331c90887a75d8358e9ff1ef6a140dad40209428fe36f299c5ea079571c955072086c6f957fd355febe43cbfc1b36 +139a14ead998d1a962fa47c47ef2953aa136bd912fe940709b8c560bc2a0c4bf8f3aab30a8e21b7d5f487d30b0097e3da723f11b5cb4e8c5724f5a2fe0d68ee4bacbb85e5eacf18094d2a8ec4506cf8497836a4a905059a998ea750adc54c27c69cbd0b0c1f9743a62f3d988f3fa0a9865a73fc071f526623085a2ef12838888 0060bf720052e8b9508a801340c213cf53bbecf4975faee63d4b44fc647a 87ebb1e4f742e8084e44e95268aa086ae889b1d7f362ac9089b465de8a73aa0c17c580b9b2ff45989f7a63ff9ecca0c6 +cf4a8e754b23d0fffc1c5c80b0cb11deeaba3064b315bc2cee96db5b9881baf90d30af4b69066f757b3020706def77a5fc1632d96bafba22a9c8cd3b52d535d941b3c7cc02b7fe6b51639d5e2084478ab3a29d2f5e0e16639fc2833a47b58e2c3fb5b2ea1830fe2ff68e571a8f281617a23d9a28db1c64ddfb1083d055030e5a 007cf3c216592febd8630a478b5b3e3a605084020322adb13ac0a626bc7b 9755aa5ea9e2ddaa39f98e7aa6e01a88b297287021c19d41bd748b82c15edc7fc244d7e9214a5007d0ef23d016eb162f +ae64030d4af9b36c8d3a6af0aff34e5ab201df04274691fb420b7d5c40c401ed7f3ade96065d34f2490d17943e27156e7bed83cd7222d0d5a73d167855fbe7ff6c3ed87f20986ad8bbbd80fed5f9705c6c783b423f641d40ff1f367f9648af5a79ea3cea0236997558bd9dcb011ea4dc64d61ea1e1f85b4f696ed586bc7705be 0061eda5999e5a9ed4485d2a0ac5510549b76ca37df858ea5d95aeed571b 84094ee95ac75dc81ceb3313daea2c0556703eefbd599947a570ba0ebc709052b11959525690caaf5952486bb3710ceb +94a9d9cd9efa3e4ccf2a37f904dd9cab5624ec9393cf8816ea591c5e70cccd2f105388ae133708fb974998ae61d218c71785f9eb808d1c28d953cc7eed00dd9854b6b4568c5ed5ee3df3b58a1e04c64f1c87fee4365ec9aa41b08a6bae234dc43a0bf2f61420acdb891a40f17f246972afee75a4c0b249dee0fc8f9b9c8a243d 007e7e73171e4d2f2989dc024757c186485435b82544a448f5cfca05f281 aa2020c9dbc41b94ab40c799e0919fabde80580fe74f458df842406d64cae99334176f38ce92de54e5bae06c74043339 +4db998df7b90678b8aa4ec6233c9b4629800ad1f3e2cf8f7afcac62fc6982dcb290e44587015eca8dfe77dbb4a80f9bffe75b11e961e70deed14555db6dae47d49e73004f000eb8677c18f7e8234bf0a5a104266167a05ef07152e7acc2f0368b37efe69c0c2feb51eedf7338cf9ed398f066cf1f66bacd89ab9376d41da35a2 005f7270764a0444c7159d2db867930fdb0fb9fa6b8fc80ca02e11753095 8c58d2545085689597f7d4d0826c623832dde50fed4cc98e2261a64197361cc95782d1bcab272b6356b97b0fff9a7961 +dbf9b8a4ae316bd2df0c80db1cb5d7038364a2634925ff957d7c03511b57d486274b2ecf191746827c325a14dc94daacd66ad86d369e3f598f176c4f0eadec7e9edd13e34043efbe0a801b75b8186b4a6d89ceae4fb250ab570d65b6dd7c04382738fe3f6f6c867a7d84b35b20720cb0036a5d81a87126f236833831d9ff00b1 00179b924afa4acf30ecbe2b3c12de533a1f9675687876a7e5e5ddc8e03b 8e56bcef8656146e7c6040e2b40a65aa347f7615d8ff28617dbc71c8a214e04d5a079c0ab15787f396502c26704ab2ae +986d9e5d636526f4deb7545c037fe81b09c74496ddb8e42e61650c74b6fe348593f0cf8f8eca5e839baf62f17bf6ad96ec0c71dc44fdf11259dbfe7499157e402f6bd5076972354150723afb632799a990c44cd0a4fa9609ec4db133e3b4700be3ea4a338e8ba1873d345e80163ed60d0de274d7617a8382980bc2138b0a2a01 002c9eb4d392d7f2eef606e1861183acb1fc753d666225f0f154d9eda147 8cd8908e8bd0d6bb0ffcd48f1c8208138b183e65288404b8e5584056f70954ed033fe33a5110ce1f53342db66abdb18c +68d0be2883598bfb1433886aff118349157708690380c42b8919859d96db069c7fde6e117a3669f2cff94a0f1b66b27b09e3f1b24d26299e11552a084be428446f3174da2e0414655bdceb38e58fcb065b6661190862db39c6545dead34a03584632e988d0459659dc7c7c78d4d00fc2aa10465cf24b2410f14e2a62173c9962 0024661c89b77b2c743cc175a6130904461138ddc4ef771ffb9fc2c8679a ad15fe025ce8dd4a7a65914aa327a18512edfdba1bc226ff45be4a58a4d37592eb81ce53d32db6f1467342df1bfc185a +f0ba0407485fecd7337f4b22236533a926cc744a5f06dd08276750196f1bf7ea7984278f789f92dd07e36895a8bfe297ea43d4a1177c0368900e3b969d3083cbe626f0e27e7ab38e185c923dff46d9ba187b2acb9cf4b23ec8eedbb8044b96b5263d956e50cd6240c66d5d96517130c743752404ed09473f05d0004dc5971ff5 00065e20e5ce534576d7c17616cd4ede3bf4f500894850723bcc9f895f4b 8173f94707f73fd38168555119181950c3b9359e58624ca1942eacf270a2c8ebfd52359000506feb2209a894e17b840e +3827276694e413c886129c452c9a66e7d09dee84f5f09bf34e4baa308b4627e096c7d45cf6ef45ba1d9a4019a60399feec10fa80e333e2aff1251c85ca48574d9b9e1affb9666828dff5afcef3edaf5e8cae823505a0c73afe76c1bf130399fb06b092ba34ab0ae15ac6c682f9ee8479b065ce75b57213b8aae0f55e4e386de5 0014c85f66fbbd653f1e4e590cffe62c343ba6062df4b271fbd02e5d42f7 8301c336755ca4ce508abfc058e6b4d7fd011eb7fbcc849422747863767ad04a6593c0834b3506e3fa6dceedb84a18db +d1afb8965b48d66b9acb1ece674d9548f83395275f2d8135554cfcc7ceb96450d850dd874529433883709483d0743798db5e0dee955a4f30ba328c7934b8dd9207f3c336cf89141a175ebe23d2faed629eb4236a8aea8300604c3eb7704512f240fda66acedf1494a85058dc6a31bf9531958c332b93cfe5545046876c6b99e0 0030ac7a78593b570b29f6d3d267abb6ba7e5870ee1c8ee4f1ab2f141051 af2a85109c4540550d5848f64b26d9af2d24bace2419b458dd45abbeef49ca3db169fe6db4434a3a4ef3ee476edf8164 +4f95b71669fdfe5dc46d4b951b085e099de349fc740535175337127910acf24e9a0e4b2f23196ad23880da47b740d77d74fe9bcfdcc44dd7d8d1a181ac290de5cf4da22d5034cda3d8020bcc776dde8cef1786c9ce4d2c2cfb035da61406af745efb7ef1a55f2eccc5000319cf1d6380963025dcea641cfd15a3106751fec286 006d7516aa040f7d559cae248e485834e8d9bb608279ed4d4f7e1dbcd2b3 99ca00c28488e2e5944590584a732a61a0e943fdf6cd672b2d2cbc9b0f2dbf388350ee14a0a512cb6a95de9f4e037f0f +2ad9e17780c824c4f2d1e1cbf19ab85638f2f71cb4fa3518f08085b8b358f54d4f08394a5ac29cbb3cab828c5f07f41eec51e6cd61a5f2cf44dbfa46834370cebdeb328fd3bf681e61011b5c2ebc8945ac7a2a8467606051008b15c89390e111999255bfe28634ce9bc2850a2b55a4af1c4c2f94403c78aba1ebc87386ab7b32 00137050d7b455f43a8dc2516cfff5a91062c1a2727b27df41488f3dcf18 b7847a70e682889fbacbac3095e0b0ef3643a4c0ddb0d8d909e132e377128bcc760cfc7cb2d2b085c264eccc5ca8f80b +958773c37d3eba003aa5c489f72118b3022c52b93399e9d8001695664918b86893f4922c7b6e55b1855ed0fd1d8de5dc61af403ad660fec60d7c44bd0102c069957ed804d0d416facdc1a95355ef58554606579ef89b1842f1055cfa2ae118abbc485356824cc09dddb77d0671cb3011b33bc86cac526e3f6bb3293c7bdca1ff 0001fd447b33a2ee3595b9f885c290d241422afdd74c3dc4981955a7e9ad 80cd66fbbad0316f404879e46e1bfdac21f88f772112bd010a70a5bf9cfffd2938168972c7863d2d5cef1d7f1cf76cee +9cb2c496b1bc7f040228571e005e7e936e48e8f469e295edf914f5648701249a20bff6b98b5e862603dd9f12bb71c160aafe9df02e2e383e9b8a9a9d700f4425ce408feabbf754be543f52204c849fed6c9d3e36e03dfbd9e35c18d7bb2295f1c484a66e73440a0a5aece5fe80b9ade9321ef18cde3eb2db15e4b18e788b0441 006a061e10b4a6e7001d95411cb31bdea9c84670a59ed61b14fbbb05c8e7 98126816d8cc1ae837be7c4fa7c756a8f25eabd17c1921c4abc99e5e624eca3f32601d4331a4aafb4d49a0d823b7995a +9a4bc0a029e97742ed3bca207d5912cb568e4403cda106b00247520ea02008b14c041b8c9b976294252da835f4ff27456039d79d90315abcb0b9b6958a22352672e229665457ec79571ca80447c8ff2a86e6af3dabe7427c8bdcae65e3c6746a56079ce2cf8d22235180f46646a21cd9e86032cfad874cb9c67f882fb037a13f 0027ec31ca31acb4d2fbacb49fc085f1261b0042cc755cc97f9b199e7a37 934704456259a13f93b3c76b302b4371c9be04644106cab5950e46778c557da9f77cb5689043d224d35a73ddeab59007 +8d89e22cf802dc68ff22d43c436c79311e705ff6fd845e77c880f399f403e6d5e9e2b35511553c978171189e288cb2200fd95f84ec5ee9865c0eb9190aff6dacf783ef200e82027fa992741876456472bdf27f2bd8ee55db15408c957a120eb64cd24d299818726a73fbb0697eba726a326719765735b37a2dcff0c853c906bd 004c6f4d88e5a4f4f83196f2dda9dcf2a66eaf94d50c851f59bfcea1d876 a8d8bcaf8dd168669e12c2283aa2477951e868ffab4835a58cf5fcc21a9d7ff1046ec35c6a6ac4828b3c35e661608aea +aa1bf5a79e5339fb9ef6c2817bd95725551d064bc5064d6586c5a879901adf808dc2ef7c78ec3b434b84569988db58b5e8e9782b1cbc2cc7c9b68e66f32d4ac4ebe7e75b345f654c7b8a5e650acc9f170f75b7aaa3957cce248cc69cf93faf8d72abc6fc1cfa9ae2d18a7b31ce720147e88e84f6563b2197882fe302449ac5ce 001aa169ea84365c22981bb766bfdad27e373440850569957544b0f9332a aad68a821e4aed3cb65cc00d208bc83bdf8341c6a7d4b15a06dd569dc1913958c02b5575f0492dc2e089b40a95416a3e +475664d5e22cbe0da0d0289ca9a666a37270dc71c81cffac91f6229fa39315c1d55f7e0a89b6a7a07df7d391dbdf8fb7af63d2da46ecc3b60110dbcd842da97f98d2b67f562b0364ef8e1c589519024177c8ea079794f271f6d35554c0e9d0a39062383c95721b72f4e74eaafb6fbfbda02cb670a7c4c94f67b8ebc6442e84e3 004a665b92c0c33a3f8b9eb4b0ec061d40b603de36c87096455102ffe57b a54953b2a1925cea90646713c3e5535e70c180c7047c18162e68d190c6c42c4a3f1eb52d6c8cbe6828753f251a640271 +9e5397d94465390a82a3c07e3ebf21b515776d18b4463aa5810e6b2f96ca61e92d13e034fa853c3fa45411f51f79df6f799a2c6906e6a5b7896a4576a4464f9e0be2b529a43e1f503fb640d79db6b68f3a3a7deac1b5832fbe86673784ff6db1f8438f7dd332cdd1e7ad9df8b6731aad1b6a72bde52e6bc62d80b8da57822c48 000531540d94823e19ab2b95cbc6e7492e1effcbabce875de6ba96f53aa9 acfa92378efba51b960954cdd761dcb8b3c831d4de4ccf3b0e62293f84c88c4b987c1163859c7a2c9bec86617a145d96 +3cc4c4192f317e52df6f8cefba6d4cd823c942aaee11b9a0ef5de5c2d181073b7085a55805e9554def8dc13eb978e7396044d4f4a14be2c7605998c062095c929b9c23b2b1b2fa73dd19a0c0af44ca4789f9841fa62dee8a5f91b3cc4b3264f5f67334c3f0772b30bd7431c3fbbf1f34318ce1889b6e8a76ce6d42079a451e56 0022a89addd8b85809e87e0aa2c038593ec277054842854de1197833a51c a0ac0b7da7576431072d6489e0c87c56f8d8bdf7702919bed61c774a344d75134c31295f467ae3534cffef036b2d7fc4 +72cdef5bdf710978e0aa334b86b8ff4a58630da314eabe98b4d611aab56f55c526983d54d19bbbf9ddba30a84b18aa0bae9f9503e9b222f842f084db83aa39625403213ca321cc0d9c8a136c826e6ea4ec108b913dd0a9ce9d5b8c7e3af53c3876e56a2037ebd6d99f037a097111c837647bedfe4c494e4288ed6427c15969e3 001df252a11ff97b4421b3a2361db94e908e8243cd50d9179f9e03e331f1 b4216721ece05957ded427aba20df1ecfa02a6fec99da7ec4bfeba5c8466e31171ab0f6c93efbb3bb39317144b143bfd +8e4eb88c0b2d525b2c58b8e00f32def90e6dd382301de49e0ac053dbc6b61afe926d85193e2c4948f7402a3d7c614cb2c58e060362b0516a1ba4a7425f1b3d09aa20d4c3c8993a387a3248aeec51e6efa8f558dbdcfcaa13ee08413227c8351e3107e9a3e3ac124224aaea91bfe50c11c1c8ae582e718f50bc5d5c06076517d6 001d7125c299ebd0dbcc050f07de931c7ad0450af590d0a2d0228a66ac5d 8bf436bcaf34855ba217b58a584e5e1d48dc2703e89c974e511a80d5d358d1a1f13204843dd702db0d0c0bd8d85ed69b +370fdd80f330311dbb3959666001bba61cdacf20f72f78953d946fa6cba02d24b5003f5452d535609e489b9434f192011f99f918defe877d51349870e7e75502f61145f7c261dbd2a0840926d824ebe9be3c5a77a3a84340aea930378367ed3615a47e3f792c7773f83f91ebea718a05fc62e9ed1d78629b2c27ae44fe8f8d4e 0021238e66119844b146d40e48341f522f6ac2f9c8a0b33aaf95a3099a41 97aa6bf0c9a0ab5c80d9b15e68dc9411ad478ea4c550b04fe165b4a7216cbabf807449fcc8777185cb84d902c052e485 +f86c4433787c3ec3cb1663389ccf53d62f9425274ccef05fd14b1b8fef676208867764eb98d16d006ee6ebdc27b8d9a8ddd303d941fdd82b630694cdc698bbe6bd524411907834286c94b24ee199fe6d646064277f244b7df3ea2d9d52a9dc6a33d7c8d6dbc919da0fa987a67621ef0829e48310e0ea2bb86fedcf4effc0b94b 0015e1bdfdacd87c42ed439f3e243abf27fd42e54f3ebdfb47f60dbae5fe 981233fdd0115a5d81d840ef2dfc7d47b0f9d58f58a5f35f6a211a04427670dab3be20fda923a18fd61268a47a91ebf9 +4117d593aa92e3eae1124ec7482737cd3573fe5f0f2a5051a7ce86946a2abb9e47a0c6ea75b262689b0b486476d2ab09a20efc2fb921419b1811b51a2e15891ae9e45a17ab4b96c665c6c423fc00e2d66df5804a164f0f3c958df6f25d7da6829b1fe162a0a8cf130858c83f3555d6ad627db70cb41303cc6380f7b3fed2563e 000e09410548c17bbbf28a68c3963a52d39743a4f1ac28e6dfe7a6ede281 aa2c94923f3b7a5be176b385c025ac3bdbea2917b15488fc9089337e51c69b9efa45803692740634bac186d0f993852d +882ecaff3ec8f4023df5397167f238869f78a5c499be19aea85c7486e73f66f0e08e71cf85f3f1b6f6a70796bf46a18e6b555a0a87c2088640ca73051b3dd59ebfef922be0372208fce602d8001681297b285701dbbe24ccb42541b5db4aac1a1c7f407e11c83db15b38cdbc25e930fdc6558f64d9503e214571a435d890169b 0049f5bea6e72d98579b78cb07d89f64503f8759dd7a73cd73713c120428 a4a40060b869828da4819aa7ca81ab030a0fc217b0c872f926cf51f58672f02bdee98a85a8034b347b9bcafbbf25af97 +99b3b8f876f8359bd6369ce84f9261581c52d744b90261a1427ab9e447e6d833b6b3e89af8dc770f1dd55692d01c8bbc4277a729fddfa7cbdb2ec99133201dde44ac691a77904ca816feb0a1aaacbb9fba85048bc63d73506eb908ecd697caf582747051a3a38ac8930c9a4365f407ed94ca7f2d26913c53f4c010c7ed9d7ca4 0005eaa818690d1ca4838f0bc667be5721d178c3869884260fb230277c3b 992c7abefa8676265d10f49a29b12157144efec3522faf324bbf3aedc5c367cc50ccd339551f8162149eda27f4923041 +8c1a83023930a85c5b2f9930521b8b8963d5523a3323d87f862a17d3505ccee01246ee1029b8b8c2b608772c4096d1e914cb398f027d91184a8e94e4feeae121eabb504a2a35c8bc9294edd15ddd979946c14c792ad787dc2d4deffa284830fc90b3f8c0ced6a99fc6de7c41b9ed261402a6b3d702ff86a9392731ecc37430c0 00603d89cd2f741d734587e77554fe6bbb1e5739d5ff73084d4de8ed69c4 8a4ce39e6c5bcb6a854c5eefe4a40939f896ac584e04a86125dca117fd6f7022d9892dbf691e8e6ad021f886362333e5 +f3c9dedd7115339dd3ede7d8d06a44de66bf80b4888ab7bc386cd40a92789042440a13d2cc90dbcacca5feeec1e0e3c51724146e2c4904ed6b05c7b4e9b49d7f458ada695c5d2fc36f1193329b87c1268aa38eda9151430aa0bc004e5d2a61b9390accfc699f2efabfec785eb34f52b1beff1e4c5492e922acc348667d2a3986 007977b3aba53616dac27b4d74930da23966a88ad98f1769674789c0be3d a18bb7eefd8145d46f3365bf7b070f14c49cd9485d89daa9dfe542a4460f4ba62f6d29ecb609f898b70384fd31b81a22 +d878c4ee0bd6c84652d7f9e68df7b90cc78776d8d1b60f3e4d7465032bf401f1527ca7bfd4a3dd916e13e93fadaa5e5f20c9f47d12f8fc922a9a3aaeeeef294c221ca1adf7df85b888faec8002f17ff202da1be837827619904121167bee2d2cd694a263d9a99062cada3399dcbfcb283597a96ebec129c65e0850ec4cb4e2d7 0050cd20e7eabd29008cc977d0a17e1195d79587b8f15ac2447e15daafc0 b2600225823c40ae37393438c97b44954c9f38f1da58bd98b8b048810604d68d6816bbff95eed4269787e092aed4d312 +ac3c118cc9cbc8eb3b74d8ccc9ecbd81d1996fb25ca43c8a43bffeb244f722b93c9e969241d45d5b81fda0b399f1e3623687190e428dae077e54cad1eff75ec2f7fbb9434bf716833421bc2634885677579c237340f76787b2eb19b446d56c0f2206099b81493349f4db0ecad0e2dbe85dbff7d7070abb3d3b12ef0cec828af4 002dbb24fcaf9f3cd5d50d209937f0e2d134fa20ee3c9c2f1fff3dfbf302 b989020de950861328618f438b410652991ab92336e8855e45274028ee3cfbcf919d63defdcc523e9fc406315b94cbb8 +700313698cdfdcf0044ca07bf9e5f0702ece7cc66e35decb28d5f8cb7e7e5367a95cc1728a90cc9a53a2b5fcd4702028b742538e9b386f5d8b4a2411579ed9553021a95bd00a73f03c4184a6145aaa367e3af76659d677fe7a2e98f9ddf4aa20eb8d1a1db72c3f5590598801be7ebf44255fd7376d89d998b7068bd1296fdc38 00047142197d3d43fa46545b547968680ec81688589d1ec8d7c7e90eb969 9946e146e43174677f62f9a191bed67e3e056d77987aee38263e5becb26aa54a892439ca02ba773c9bd64193d07d5700 +0374673e1a685bdee55504ce3cd333f70084dd4ae685464a16924eccea34531663fda60229166478b30193459a3113253cd6494dc26154156252dc6e822552c7c04d790eb9f8fcef2ea8dd79e72f881f7f20fff93cd73ad303c0918ec27c6486c4da61f82bcd55422d16650cc68bfd4b0132c1e7075bbf17dad919095860d445 0031352b49ecde5434aac05f898e6ce4337304845d748f114c14319fe97f a2df0c1afd5f531d3b2470938918adbdee426c18318a66089e13ad18454fe90af4cb14ae541583c6c3789932fea5798a +8b237085f135d6e94592f8d855ca397c8c1028236a3b412adefdac888245874f586d06950ee18118f751bfe26f4c31465ec34b578caa44cf1b7109ac4f6eab7f97ff9699b34271df035d3bf58a2ed4bcbf7577cf8e5792b1945ebb9389b680baeb8518c8fdc5540e192aa4fde0eed0d7c82be2e362b286f582d65752c8db7038 00176f124c24e4420f6e726a6ca25f09dfa0c5a37e5bf879e7bdd36c3b65 8c89e864cc2e606c333e02036dc684250ed2d48473bd26bfbb93d53aca28e0af3e19f060226b95763de4c159fac0f0db +e3a086ec15574f7017b3cd5f5a47ab7a73980f11074333490dfe9f8ad8926f9ea7c82271aaa74e77133b1025b0b22a6900fbb71251bb6549341a23d194e79d03462cdad52ee0d1b6f5d0d14e1136026961fa3467ccf0864bf7ae3fcc3b68cb35df7324bd9bbe58fc8aa9f63c19feedf19d935b71bf5981c74fb2a487f84e453c 00755c48c3dbaf71042c58cb137f3632e3cf9d90b7b9a58fd378feef3d19 81a720884a49da64a1a2b79cdbf157fad89ecc8d1fa2b9bd8c4bac9f020e2d6b6efd1a698ebc255958c7ea24f7721a4a diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K283 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K283 new file mode 100644 index 000000000000..1e54f8cee9a6 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K283 @@ -0,0 +1,60 @@ +ef90f85fbda05e693006e4c64e1dac56223becaf0890f73b5274e6e289a5a1de2c141b825c24d595b3fd18ca855b5c1aa60dac6b5356275b11be670692cdbe5f282f93ac7b2e410a96cb9e9f80defcde98f3449f99e192bfd62040421a0ab8f99acb85369f25e5efbf81439efa8a5e1d9cf781355a0f47b037b09fe4086389a0 01e846c830a8ec04e8572d1a9d2df044ab47352fb346f67403a3bf87243871b164511c53 a542caf6122772b9e6ce8c3eb98e7ba988fadbf39318b0b54b5e014799d59cf89e32c39f84189e0c2161dde80719f446 +a3ebc17c867cc9c7c28797f6364f6574b80c7ec5b2d8e1542a6f5db8568c15032f92cfbceefa3fe4ee654f690b0455ee5d38dd84bb8665ffc1ff8c849bdbc4aa0ddfdbbca4eb37972fcbcee8cecc1aae21ec736ef61781716b60247b7551ec4e552d0b59a53cec5964c67cf7988787cedf769eabcc9cd5243f58034d96f0e43d 0101c5ed48231a56ca0ea85eb45de0e395e6df2efd4987a226ae36489dd8b2dfbf7c465c 9037a3e08df1896d88c5bd5dcf821402feba2bbc2772d745bb548edd7257de70d552ce397b480c71482373e52cd784b6 +60269efa4d0ffafbbc655f6f00578eadce7fc0a7eb7db923dca49b6f2bf3e13f7f829cc6133e022c3c92143c075ab9ced0531a91e6e79848194ab98bb852f40c84e7aebe71fb8bc0fd1f97ed5bb6bad6783d8dc048df42738e841d978456e055e1b8a781dfecfce2218701c7af77e7894ccac5bfff360aab0b6136b978bc39c4 0019679dc589440b11f82b3716e5b2a2bd42c3b1c83e88a28e304cf5148877faf760b4de adc3339a0c4d86eaebb928630e1bc49cee8af184ace04e0da1b4d888fd0c75724ee858bfef3745f5a3c0071bf934357f +59d704d5b1f3a0605f1497f22f71b8f45b26138bc86371f00a4517554e7f6e7fa5d35189fc656ce68bd2cb8510fa3e3c3df815dfdd749b2b6ac997d443f3954c7a927e138b579801ffd035cea90840733e7884ccfe43d8d3a4a26b430673274aae312abe4ac1e1d7c67b73580fedf2d8de46572493c9205ebf0e8b4d75ccc88c 01703c21fb1e09f8947e12fddf166fda6f685221fbd803d75a0ae377a54a1e494e6c5e7b ad59f7880660af5f2629843fe7552642caf88a42da48b9e04689af9df9d69d9ab6acbcb10f45219b8d8ec9fdfe8effeb +12c8fdba3bc5f68e13f7ff8e7bee876fa68a970afc6924314dae0c2482763ced8d4752cec29ea288d350acd8a06c69289ae41ad345a1b88bcccaac903f2bff39015c289a8ad608606bfd65270a7bcdb5fb10c89bbc2d16dcb91fc9735d66103f6b1f3575622cf4d8209290315b033ee1f79968939410f465a2d37add46af2d59 0071de8eb14cbfb88e61b908990ce08b81e624ef4f2cd9cdf3dd7ca9097d5ffed9ae9a71 aca3cae47bb6901dfab985955625245d334ee5fbe1e8172ef219cc0f92606d95b58b2fe44e3b90af514c6dc03b8d1cdf +26013a3ddf687bb2f37d9700923906f118d5cba5d8ed5113a0e3e84cff00918125108f74f4b243e351aa5d07fa7c6ece29f5700f23e50286447883d2a058c3258a12e4ed8770cabe627ebea7ef6e8c77811ed7d9a19c53287093e39226236587ddbc63b7ad5e7ad9895c64d1d03ee432d45a067afe27d4cca920ae88a7a68db1 01d156eb15762ed00c4021884adbfc2426e910b18a5bc474268196f4b74e593a8f38702b 8cebbfd97ccb8e92c5a400df6f9a9a12af890b00814d5ebf2bb3661dcf775e43fd2dbb72f55597a282cca1b925fdd50e +c4dbf70b9a2165e7279122460d05ceb8e43e03fbe2ae7c314007fe2b1d8567cac727a10fba5cbead0ddb167d387da8e8f3d6bc0ad851cc32885809d07a776fd4a95a979fe3833610af89df0f454d9edfabe12495a118fe83add5eabb2acf54ba7ba7c4be20fc77478c0a0f0726c4e60317422a612a234a7567648603b63f1c12 017d6eb1219cab8577168be86b61f372b27ca70fb1f1a767947895c185344e966db17aea 8548995afb7a1eab69c7134d741a9ab5125e20b4fb20e65d01232880ca01c1f6aba224863819bfc01b6a7c58e3d6f19d +b1d53b6af1face9b59af11c726b0099111d1adb3666209ba46b1744a528ed0f72be5a1b82423153b896384faebef0362343e2a4599803c08b8513708938aa8a498145fca1c63ba41aff06d1a18aa2a045fce7fcd7e5552a2b98d0df97b6876f06a9cf52a7a40fb737996adda97c3cedf7fe421235ac6951060eba9c0377e72a2 010ede9be6615b3b2a294d67da78127ffbf3a15bdba6f4fd78be7a60415b5d1a097c0cff 92483cf8f7705457a07aa898e6b150872260db3e013cbdc481519f9594e77b5bc5a2fa01b942d48f0a1aca4f7ccdfb8a +e78f538b1ac21602b00a09e3db243ef4803b447329c94a1476cd91a88ff790da71421b60092c8a6e55327c7982e7655eb1fd6e40fa9b9fd2f10107dfc585994dfc5bc2143d18794a39f7f69ae679b27dd11ed22040d5e93aa83f71783525a4db0c3fd7b43e57dafd0033d5317680df19c2ecaadcb37ef896c61a758a5e455206 014f237cface123b64e8578ff33f86bfd2a8181b9c81f36b9ca31e2a446f0d91dbbe2249 b797a6b569263d982b94557382f1463a06a2054c707ef58b38f400405b2e41c7ac3c547f01a52e5b3164dca51fbd3c62 +8a6ca8ec436d2c706fcbec6486b5665b21c174edee7ebe108211c388b1219a8224179f7438e0bb7d6e41ac4a67337b52d4cd9a069fe6c88960ae20be29c8060efd7c62cb7a9a37136a250e68f253e7f27755df53ce7c570135641ad49b43507e5483e17b919cedffdc0d4913b1d5e0ca0629876c0a551841a0fc2090d2857cce 008dbecb26587cb2ed7df2404e680fcfa5bf8cf6a58e87a350a1600211b3c844ca86daa5 8919dfbd46e5a14f401386072ada173b6309c13b38e2d72cc4e90a3b0e847abd1824464513c0ad9368b25bb6ee83ae1c +95bee02b423d2c6e60252da4632f693a2d8f6597b4f9c6e356f670c3a9e4e80063e92facb6421d0325b99dc150464ed2ec1d0bac72a042b35d56d33d2fda686a75d582d4756522218b4ddd25ed45503d90d3d185cba6cf0ac211b22aa4e1318a8316c369186f7130446dafad64f7966f5414f43af37a87127534060a23c6165f 0191badec2d28cbbe62c072c6b57eb5d4644d0c0b3283951bb66096cd15edd43a1bbde53 8b4233ae6d81a3fe97bca5cb79dcea436fae295ba64da938538a5effd675e40dd91d3afc2cb264ea84646a232ca62bba +ccd7f7c0e04d1ef9a3c5617d77480bc624beed6582bc28e9e3a369b12144fcd96b735ee41713f4173b64b28c6102d82dcfc7876e06e76fc497d1d238bf6d85bb5feca630bbd0c0f0fa7c0c72e28e9259087698973ac66244bc6e69c04deb22eaeaee7b20da239ab6333576f01349c76f594498620933b8969450ac2bae66db8b 00ff5e3d66eb57fd35ba4472effd6e7a016ca461e39000a7125e99080f6ab6ef4380dd7a b01febd8ebd25746a228a942fd7627cdb1fa652a8360cbaa94d3883e9106ee2c1f2db2e8b43e027fe69edd82779e307c +65e9124a2606c8784c9489add2999f4cbe6186395df20838d653b263a207ec46995d2685b55d1874e7ef05a6a3bb5b60a7be6751ad568cef1bcea2debfc494d1e2ece0dc8028c88f1b2c6e4ee26b639c5e81f6448bd25b73ec4608a8e8cf4e0155c29b6f0a62781493b03bb7384c9808529d5f87da6564ae196a365bd282f46f 01f3591eec4a8a3fe6ae6debe230d238a6b73cf3791cb735add1abee64239bb100f15166 a9ecd49f378748904752c73d1b5d15594a16e6ad3174e3d2f16a11ecbb5170fbe7fe92a6a691ca11289e73f5a507ea26 +e793c60fc725fd537d5fd38e9b4fb52e268722ae6bde5a058de8d20db301f5e8d8e1ad85532198835a04b76f27ca3c972be5617a55677cffa8219eb64fe53ced242efe1b889990979227dbaaa15ed39d3b6be8c5a3237ebe12bd96f333d947f80048463d3859e34f865d83faf03894c2243a06cc96788ed952e606c2d8948271 005af03cdb45961e7ff35fb0146904ddd6c2bfd3cce814073d3aa56eaa9f13b4f7423926 8715164da961644815dc172a6dc92b8b066021736a1e13f27241d10b7bb2594540718133c220b32a8a62fb2dede5aca2 +a57682d21cebb48190199e9f57493696eae3a59acd22f64d5ef4729decf6c2615b326817a6bc118bb7234bebfc7276dd998838c009a7348e46431574638dadc48538d6048d572e50d9c5974d2049ebe1837dd857bcd1447b1514b62808a4e7a88162ae1bb08a0f6d3db6f25874c6cd0cd4ca6333f1bd57bd192ef67e4616d182 01ec9710ada06e6270720692a06d488ae2ba863b905dd2fc323e7ce68dedacb35fc8c7d8 a9b2ab01e373ca6113a88a44c0489d7e3b791fa7ad65088e8ba806642cd5ab4f59957ed1468a30cbdb1d4be59a995c6d +f646e7334e191c2bf0056d3bfd23f03ef7f0777b923f962519a8399d311b8f68414c689ca34b96871fae99eb7ea534fcd83e788e56eeef817cbfe33677283c736b99bf6a626f9515291e842bf99f694e4e8aa7c9911c591a87d5f112b3d96b064594e2b368e6d1bf1a1cd343d54916a66da22c26355266aa2884120fffb8b94d 00668de088c6913640fbefbe6d2c44ab26e481802dbf957044a4957c3c5d0a0fde331501 a933b43e7df828547378d3b73a197ee9b7f921a0b03f6ce9ea41e43828d6627f0f68d4ffc506903d55b9a50d465bd927 +a2d7e69ea381d3edfde4664c56c4cb140d01cc4425df757975cedc995b89640dc016ab419b137ff25a6a6d64a309b23890439d2ba157262393cf93d15ca1b1ffd19373ef12367f8898aaf56d5544c2f019a4854f69b3d8d320e03135bb7b675e588a5c3fe4b703938fa0f964916501297cee2fd04af767155c7739419f9dbb7b 00e6af57cf47de1e6f07041eb5e1a413fb7ddd82f8c7f7ce957eb28a118004930bec4dbd 952d36b853bd1e72825687a068906b387e03c4c1bfd4abd81e43582a0534d888c7ded5a4064ee21a68a9abb2552e761d +7088f60e9375ec6a42f705f851fc76cc833c4dcbb3352adcce9f59197c1b7121e7aa661c4f8ad9f4ef280af3a2981e90c01291f7d1cf7d3ae2d96b37fe6975e11b7c6c02b8ef044d1470b1a26b9c72e8c4e7b1dd83c8acc9542e2fc7d211b87841dcceea2ab8128d0ff7bb622b60faa4a89ea7008f7d55f8f9de675bc4596fd8 019f9b63fde8c6aa6177f2a38981505d04f8ac62bcc21007b05615d028cfe851ab9cbbc6 b23dfa6dc00fe7a075044fd558894e3a7ef8dc4bc59a5e9ee63bb02c1ff7e4b20f19320139d239a5e65be9cf3b15bab5 +ffd6044ab991849939e8a29184b4d0ac3e07acb63c7e6b886df9e8254073fa800d5910b9fe34fceb547565a2344eed4de394ce2251ed51ec882ee9207eb7340464c742d9d140fa0964f6bcb1efcc2d13919af4f727953de41b20728ab975c1ae0ce784865f23ed1325c68daa95ed5c932893610179be94f13b9a4149f09833b3 017704c1f436beb52f7ec97192e23e206ec09f9e8986e06bef71467c192bad6f0066b3c2 b588bde3800af77e7b75a5b0c093a3c70c058746d21f5bc19c2e8de10a7dc5f56cad1c15cc20fec9a39694042f03dbf4 +c9f81c9ff7d80011fd41f2de97a6c1e6a22cc2da7b2b9e4c50e1354c3e139b44529ac786ce795fc501dcbf11a935d4728a7bba44b4e86b5e5990fed4d3e24fa5ab6f303e1842918f156e00dccebed6897c852207ae5941c630014a41696882066c2b296d39cd8658cb5830eee78e29a00335a99a0ba90722ceca5a2e9a99a2c6 00c7d1ac8faa689698f5c6325a3b3f35e7730bdbddabd0693f2bfdc5c838bd62f84508d4 b304a01dcae7230b1cd01b79273c9d6f2b7ee13f4cfcdbfcd5bef3edf5928e2d86055a189f5ee7b7e76da68ea33a6338 +a60de761eb32490184dc1d29e21fa33889295ca587b994746874c7289eb9c83e9c7bacbb4066c761a06b65ecd78d701bd41f305cd7eb258c630f3febfbb0a367ad16737b146fd793dab23562e8001cd113135b1c981d1ca23eb3be0fe3e24fe3fe1089caf9fd8f4f0d1f90dcc7dbea4a9e2357793b65daf342b8e6d109c6dd10 01a173d158866db0ec665ee632b5fc397893f6a44ee17c348e7452800aadd8ce676e7fdc 81e3710c106222387291235c47475aceff25fe8ab73658ee8317345a5acab4a8fea9a12a0428c2070fb47c332a4063f9 +2cd0320cc73120ef13e83c8144b270c9a1f2049a9250ef7ee83ccc7584025140a51e2227a5ebb824deff55b3affcda63ecb1fd3f337c67c08054dc82fdace0c4bb9cef1bea9dd792635f655363d05903cd6b5ed50ee669bcd8157509366cd85aa40d19593265da26e5641590ccf04672a6df52badd4b99964a8643d9687b499d 005523cfacf4ed3b74ebc30f608292e45173001d80cc801f729c5f71fc213b243f041ad5 a5562e3f566363c8abf3a0ed09df8a2f3275334040ca4d1920a5a8c69e16aff5ee0d1649fdbc4c27dd126befd5dbb6ff +a743d8337bdefc4753f937e869a36439da1f8c75e1278c3f6a4a969d93787dac93293818b1cbef5b8636e1a6cb3acaac1e15dbe0841c8001512b689292f3f4805997ae26ff52f7fe1842512a020c448ed01af2a061f3638689446ed5f6bed9fc70726ce4104bc11142de63873fa7039830223e8f152996388417c48e0c1fa81b 009f6bd008c04b8823ccc3ee7d5aca535c211f35e9d9e7cfaec518b98647fbe6d28283de 921a8d45101ab252d2973a16339660b7da0444c175f4d910f2c4125c1f02e40c54e0ce9f34442f0385ac1bb445a06f55 +6a7a3ad614a3a09d2dc5a80204815d0c6471057acc0fa73f3cbbf1801902c3e1cba3c1134a79a8ce61994a94a5afa85ae1a44b2cdcf5153f8625713c872da36aba0afcc5c2f26636dc3f60e04c256a5b023e20e2e7a3f7305bd5b3033fcf05368589f19021f8c9096a88679904b657bbe5b9bee67d6e53d176fce1de9e54c64b 0150d2812505c82584201e93f6e0cb875d29dc7bd99d9c0f98e0ed20128886e67e1f1071 8a203dd243e305fcdd22def7e365b0e67c2a06ffa118c8f406d7aadb624c05170c47f6f80452e2c131246f3c7142fe67 +65bcd77a3ab345cc99b9c1300755288102a6ccf140bc7d1ad25df246ef01fd57a8614b352033b88cc6ffffe5b38b99ecf03baa365ab5529d6751a3c020d0198561969aade09091434d84ffe13b46df043d0a61e20a08e9c32b646771fea1b29e202d40aae1c7079873c3af494ecf6ef5eda855736c9338b4a5c29a086a8266fa 01b3fb9e1ff70f94bc9d7742ea535ca982215af3df381b5ebdf1db40c7c849a7978ceb98 89430e14ecfe5e02d3c8d37ee265c2887560b459fe42264aefdc6d51a318de1b699f2d2fe2c02410b655c292a9392d51 +ed1acc360d02ee6c36bbc223d91bc1d2009a3e8f8dfc4c3796cd8555b0d2b46716f4c8058bf34c2d4954e098274ab9c2cbacff46a0578a14e77fe104196cbc6d2753e3bb5422b8b79fd004ac0aa920eea94925c016ece16ed4dea916fd92563ec65692a61b28ee84bef0007120bb1e31bb75b8ecf68406a71af9a18b4edf5320 0147fa46fccf0805d14c1b84ea59bb8b8283d54ca0ceefb29b5585e7141340c55b7232f7 98d8f9b3105d78c892ebb1728789f72556fa7fce6ccab44eb5213a6af83def95f1fdc6620e7cc027a14623cc8fcfb191 +2debdb95a21d72b69c545988727366a42b819ca6398a82129c5e3772aea93fac0aae9a27b11969ff0ffb9dc0301132ca2452cd863316cf24ae7696422d4dc68e37316161abc146e86f04b72d9a27a350d8545cca245b2be43c33bb822dd813d13e08a718f784845df8a4ef49b02529871ec76bb3fc1ba31089359f2ede73e767 00fae097ea56b35a517be5480802f450eb832b244558d0cc922cd4a5b40b84d02ef11216 a09eb22decf43642237e9ee9b7e7e308efaa60346756c3ec418792318cf079bac76caa12ead3aeb8449794d803a08cbf +e4e0c6c8fc01244abf81e139c961b6a6e2d95de5dff1083e8a48b40e3e5b9ed909152c92b1cf2263179629cdf76ae553b58bb2e9223ce4f9ffb5f170f5f0c5ec97294c34a7529a897e9397f71198cbcd68bb4055cb8cd6b690290761b3b73303f82788379df145358afe28f2997d191d968929b7a4b9a0f6228797dfaa17c613 0026cd72e6ae19b3f4c53493fba1e8082a8df1fb7da6dc111b47a41f713f49b33f618d0c 903a65c536a7adcc2c8a582cf1f3ec12fa3406598fd89ec19a63211a2594841584a01c664964a0e74a7fc90ee154855f +04710947b7c90855ba4e59107b919d4a1df22b503c5c4c33b286b6b08e451e6fbef8ba40852f9f0ee62c9217abe6156bed46ad6f0e25f70f528f3a73d099338c578bebd6879d810e6e173c2b0af1f7caacb3531ff0e6a7856e4c84db355d110febdb21c683223eb5990ef2038d462ddb7962bc0feea5f850954943d53041f66a 0198e13c7d95bbbb6e226688719639bda988867764ffa9b029018b5547850daecf58fe1f 96652669065efb5c907ccd381afd65b6d97011b4fb9e7b2889720b04ffceae60fa43e531549b10f090ff5523dbf22f22 +c62d07bb1ef756b6b2fad355c66b5be086b6dc387b37cbc4a63c841dba3fce65b09d3de8f239e3649382d172f065b78f8a53e0283cf345de06b4ee0b4b7d8611bfce92a7d993b1938419afe817611bc6df3ef74191e7e39ca2339fcb5b5cfee3166d09cd52a1a7d3779722aec328d326a11bbafb6aa417920225ac453146b9b7 019098a39956747de24ded56435fa1e6c30cc2b8088fe9a75f5d07b2f5939c7a60db64ad 816d0d991eaea386a5340d8f08ed5f4985a78e139fee7bdffb4680e54d2bdecf0a54a69d7f130df20aa10d1cec1f81b2 +e4d8d49c9bc566261d9134d5e237d9cbd6b67d2619a9bd06b7c9c139e091aa10682cbede114e1d4777d9cd67a16b7d64278e99eed62bbf25ec5a5a8fabcb0a3468b0e73fd02ac6533e04b1110d29da3e34f33eaa228b78341b357a5d892a61beb2168c3bd5e66bffe3f2080a1e246f55a41ebf9d579e188d16991aa060460d6a 01636bd2be121e07ee83ac5e880cfdfca6a56f2b9d0badff003e872348368c7c2cd96b6c 8cd538cb65aea95417839e91286985b53f744aef0af82d5f050e09490fc3d2c6167cef650a5dd185dd47e1fa058378c1 +2d1358fdffc14630fbc421b443d3c22ba10ef34f15c6c5bb3c73a9b8714e4c411de69b9cd6628fe2eba5efc4862af66ff916505023e0514f564164b389ea422d0f1beb92adcd65baf43556614eba25e43852ba65af78f62d64b36696519ef8284ef7316ea52c365b99f63a39e6701f81ad520d7445cfc0113c38ecdad4bf5b7a 015e5f555119c19b055b15b0c0d2813068bfc184f864e250b202384f5728bbbda1cb0f5a a9158d5183268519228669f0c4a1267aac23fa5e9592f626a3f54a75215f0cefd004a48fe7a7399a928881f0f3ef9ed6 +d6336faa5c3e838f4fa58626eb353d4cff9ba8f0aa0e6c3d0d850e8b22f5b0f047afc97767f1afe2040b85d4e401ba688a4da7a0caca7fac450899092c4fea789231ba9b07782010720f45d16d353798867dd7fef4a324520014ad5cb32684ec50cab742b750e05db040ff51140e8d740f6774a059feeb493b10d8ac722f23fa 0190c8f17bdd38669e345440d2c7631d67cee9c6548c4e7b9452377adb9303430efeda0e ac56e540bbd4614af21f5db68c40ee641d2dbee688b295dee7c2d37b0278416ab740668c4da57215099cc0ffb7a55faa +07384a3f650bd270b14ca388a441af201b7767a2d47e9033f50cefd3af8257ecb38f5267e141cbbb2ab7327d8fc78cf27198ca3543d39553e178390bf1b921618432ad895e4f8153783a7ac22f4ca3cad4560e64f1ee4a7bcad05df98ea49a3847dc2143b27c243e48be59c869a547988e2205358e8db98b635ca21b745df4d2 00dbbc2a0409ca58a9e39e33b95fdd15080443c1dbdb5874bee991bd1b127047f08ec9f3 9557599777002b9feb80f1e20802ae253df9d34305c2400352a2b9f8062cab791cc0a945969f192c15591c0baccf1997 +824f26dcb4ce0ca020982814d5c727e629cbeeaa818c49668f8f6d743f0d0ad362b24cbac48027898f386889ca5411d7d1f9afc69493b1d9ae4d7b695c9fa0a30bb59e6be2cbff79231767e96cd8bba349fa2f97955d56f05430ab4ebd007064e3d5add94dfe255b6deff19650883ce9966e1a2affaf84d9540f65c87ab1f936 005495e6c59ca1873f36b756579632fd47f9fb95b64f52589d70f2739aa6a3bf8cf8c198 b059fe094d9940ec27c7123c05a2224ee4faf6ad8cff08d352fcc0d0bf3602a2dab154f259a9ea4b2a6f77dc18648c55 +07de1e4bb9be15a710a74806d4447b093bc08ed04392d1bd5abb414f5f4b4d9d43520d0e46fc81c2a97e71086b28e53242449ed37fd7ed1c5772dbabc430fcf82ad20437b38eac15820421e51912325c872894452c3f8a10ddb040b35308e583c155c3707b52df467c4945f4e1071126ed46611a3253c297f5cbca9e27f58448 01724987c9b698519b6c225cf1261b77d0300045e5fd774dcbf13f285e6bd74512cb7edf b030f264b6a422ad5ffcddc9518e977729965075cb553add0405779a14d0d9c25e5bb931e141b920f5c43a40228e833a +1edbbbe71057bf7d0bfda922be21a3a4dff57b017ebf6fa99651246cd173bdc9b11eefd048ea599c1f98e907932aa04f64ed0a007831f30daf186c88807400970904d6090b2cf181e0f65f03b4234aceeb420867812562e47f452152bb1ddaaa48487170d06e47c5e9a7c0faa4fe494663d2fec22f7665ceffffc214b21c6b8f 01a5489091cfd51a0970508ee3e8449081ed175928ff8386592c83043a7911bbc2f8778b b90d34f8f3decf8a430dc5e11cdc5eace7954a3a142437d9195de148b26c00dec424e5afc45f2be2e2b920025f4f29ce +db5cf1de38a5187af11c1f0f19a36db52f8417de997229e83072fb51a3b7152a3b383e9919c1b8427582e53d4e7e25433d46cdf01492021c237ea0a87d38c71634743115a6b2aba66d3faa8003158340a5078171e0bd55a6e5d8c7fb2631a31c1204e1479bbfe79ac70d5e5823af502922a900576f0088a33e42ec3e26c0089e 01a45ecda0788fbd7cb7a716dcf4c6e83d4148bf63ed58078690ebd238c00329c462590a a265db9a1020b71f97cf51ef80e33c3e9c72f3721e79f06dd8162060236aa3a628a897dddf39ed3bbc051e0fa7e9fbef +4adaa850eec8272d25d76600aacf2cf66e754f6c5efa65c55a2a31b7bc69437d9a7e47c6f51c5da93895a45221f5f92c2e20ee6a95eed3cc7249688261a35d82872284900eb54dd1df6024ec48963ce43e8ed8b8cca8ed22beee8f0aadeae53726cca05443316537840ab824cd1b595f36064e9a19333748d4f4972178e7f5ae 011461776c33f20b176dc8f2b0cb2446a9b69e55b6c7bc7457a7fb4639116b452b79661a b0e2bb6b118985602ebdbcf72cf7f40b324728bae8fde69316df232bed78dbc59913a2b97dc20d6532bd0bc9b37974ad +11d212a99c39fb5e4ca0096bbe6c81ae1490e1b8e07374b4e773bee4fdd24a3c13d653919db663d2c32aa4db140c4ae2d472d4f878946e527ad33b3dc93012d97458f96cb622ddb56f1ce7c2474ad0d5291dc35545de47b7053d137a8e79dabe06757ab53e26eaf751111bd27690e57ffdab5337eb6f81889e9d1b1ac729012f 0025a65f627db2b4d6cf83c5b0c00265b9b63f7656c5e3382139e4992bcdf3cab502844a 91290d18ed5616925084e2ebf2a7cf567ae1b19615798b65f1da4778636532207e8f29392313fba6d06e799fc90fcd5e +9e4ec74c09528fdf3153a0f6955f20c70915ff524b2e19c991ec4c5b41ea9185e3e876a02ed6f27c9b3479dba951bee8680c4c99be1a626808114408856994be7444ccbd5ef9859fa479b1050bb836034e20c531b4d618f5843fe1d4b613a731895b489a2363f3f5397d5ff964cf037e9b11e3ff5e1c3d403e5a46b8387c1241 0173b28fc29f10245221a907778708b3ee62e0480aa9051d4c3eb4e8d552e6aad5509943 a6a145767072560b13ffde0fba40ba0248d4dac0a54130dd3c0ccfce995f9a7efdb286d63221de50a4e7cd3d2a5dec80 +5fe8253d2134c434cb0866796013722e82184638b024a5a30938039929ccd8415c71f71f239c5c5a81f7a9cb493dde209f189bcf766c17c6d9589cd0c7de7f07ff9f24d2320669b589d084f8a8ea71127b9760b7355b162616afb34bcdcd416f1a062035102e29b70069b2b4dbf70179b8d60bc2ee5a455efd40194533bf560a 00624616adcd45e1fdc6cfeab2b17230d73d91fe0b39f4664f3c6891554f9b8e238257f7 80a90a0d69ee7fd70405f839b4932b2d74a226d7b26856bba9a5de9201e4515b0ae21582994d3dee5fbd67346f8c3817 +db49891838fe23f0530abd4a4fbba5ea970afa5747f6a0a10d2cf4d841581ea2178705c1203f00cafec91d0a72d25448072c9cf7d7ca5580b39f8589ec63128faa95cb0689574a6bebd515049a1eb9699922cde0366b5cd58aa8f3d3e847706896f7e1cac667fbfe94b2eca9e7be79a810806ca4bf53f219bb30532ca2254c11 0199757ffaa2c59e198d66824eaad37cc42d49b2e241b6a60382d05e425e800eaaf32470 89352b38618403f257741f62338fe5cf551b2267a7f69cee923d11af362809dee4e7fc251f7e41e908e90a78e968a78e +29d385d09c1142a7c181fe4b6e6132e414c15aa8605b44208c0399464613b966edcc2d46cf203a3f85d943d8eae658695dac74366224a0d0348083bec0106f5eb8809ae8d07f792fdd7c48fb1a25d5ef3bb9acd40b20c61c821024a9acb2ede321bd2d0dda849c22d76f421cbd8d51565d3c4266f666455ca1c0c3777aa44107 006e51381dcf21050aef2e9b97e35303cf3bd91956854ecf9b6b9827871d2efbe8201c5e 8f2cf1a1c273be14d4912889be5181615ef9838f6eeb9c7459a36ac350cef47b8f14d32854c09084089301ef64a2dc76 +774c1cb8fb4f69ecfb5c7857d46415568d88f1f9f05a4bf64a1e1ff6d64aec16e1d09292010d1f067c68dddbcde06ea49be2ad3838053f0b9c0c2383edc451ef0188565118e7b3c66a4fa372b96633dc8a753106283b02d0322df273d58cc9bd061ec219f1e1a9c8ca1400e5e39c1b2c254273377dc98a1a2c44e5c2a5b89167 0018adcc22cb9a2db64bad3d60f1608c353e091637b948914115ebd43679904f955c8732 8c8310c2a01b8b924d4ac7dbe422e44155f228cd093dd9d0f4f5ae0edcd8fff2818418e5a1121a158466eabe3f1f8da6 +c406aa4295f85c854b4db2de5a7a2defae53a319866921a3673af5b48c85ef22f6eb4cef892c790d8e64530fc20c729b2821b5f5e515560b1ac764106560c3a6a05657e34cd6deadfe2884bd288cef4ca92e1f25adde7d68a30fb0a1b3678156ced62e466718e68e9d67099ad82613b8d06bdda1a7b867c2455422818ae9eeac 01898276f159c10d92d8d4b6ae214d68c72792a4b5f1f79936ca3c063dc8d9a88be439e2 89374fc86620e4399eb7564bf30bb60a64d84a6e2e39a8f47d9cdc8ea28c9a54bd2b948deed7a75874453d15e9676f7d +cb2809152f8258660933472c06ddcdb65f6d5221fa29d5b0efec9c2a7914dbbf9ce0a468ce146fb333d26f510a87a6bb01bf8816756a1b5df81c5f65360957cae84ba038e37e88777580e91c34e2f5aef4fb55af7b81ad28aeba05e0b1c64a15381a6719fd2c16e38a441516e1b394952d984baf9e051b1dc1bda2e12f8ba5b8 012ff37c808c3cc029a9cfbb67a5ed21f3bf362b49270d4ed0f1e38fad25ebd79f112a50 9626e783f46d79555ce807ba2f392dcd41b47fc5af261e5072c339ea467bf8f46c47687ae624f8bfc2b2dac0957fa614 +e060af96d4a7fe512bbf26be9a27bb6a8ff37547d4a7bbbfa710db24cffcfc760dac120f89f642880db2df6307f9ea5441d5932d49762d182b29d8e7fb067a61ab0df622f75cecc917e27d0326085d34581e052c85f50a37713e27518aed7c4434f86970e00a0a4b8503989e72614131b7164c1bdc82d2b6aeac0787f9838476 002b8c1fef9c6def32b5f4127273ce384b6add4aecec957c1662f52334f5ee97f49852d4 a87b8ddc965b77b32de198f5ea8d8d9a37670b16bd57313dc2987a058390fe1bc72a181d8039a5d7dc72c92f517307d4 +d235c31f0a82957a087c7597673970aa39321d4c2640685a03df8388b5eae4825d1fee29926f416d5e62a2e9ca1ea7cefffd31607e750fa9675983608e0f8dc895371b190574d065c5c0c23ffdaf49e65362914363a3fffbc2c1bb487cbd4f69ec22dda5c7dc3bbab805c81faa85787cc176bc0e5703924f395d8c9e7e7701e2 00afb1c45e9a9f02942b8e04da4b815498454dde6643de186625a98b3c1c6993abc8bba4 b2686de496953825cc321f321fc82c14fd350efeec859f7620f31b18c4708f7e30882e0d8cb5ff89152246fafaba48e2 +1a2559777a5fd8f269048feda82c4d9fceca95803f84a813789d6ed070422240e443789c5231d63d5268ddebc060dfb99c4eff2ff115d2984d8bbc5c05314562ea6864fd543e7e0a3b8572c017d8ae3563027d79bbe164d40a5bab354720e45094b9b26391ceb55339592fc2f10b97dc9c2649f7227648f5cd2fc46d78d31c0e 00ff537d73a4da0ae3a4894016b71dccef3bc886f3d24a5abb7dd96cf8fdcbdf0fdc5e51 b688eda169f5d6d32cf3d78aa0c244aea1819aa9fa5ac407c6b6750eeb31de69813ea16fc200308e112e90d1f775a70c +658c0d3f764bbc952fa55a258bac16a5bb5184bfa76cee06baf9ee6b9ac3f116e08bb2406b1dd4be487b057f3b29c2043ebc33019b2017c4deccb86f50ff15fc9248ea5fb64261120b1960525aec3cc18827c23291722c5add8a3761ff8516c61956c62b8cbb13f3d92bf3eb45a70704c01bb3625d21c38ffa83a6db086ee968 016000d2e879906d1040b32eb6ba3caff700e5565871ac75f10c5c15b509964bbe5e14c7 b54b5a0e31871e58fb3f1553dea41e5c814ea2c7b8519e31e2cfbc8db1b0e6ec812abe9974dc3147d00d321fe5e63208 +4f10001e3517c2c1f973b555f4827681e096d860c4db08f1f4aef8000c9c24bebe59f8bf3d7d3cac959a1a5477bb0ea43f2e746b5d14ed48a58ef35484b0ac786d2fec669f945e846ad73e6b77a9e47012a951b398941566330d89125eb3c1fbb2f06adb951ff5f047d102fdf28b5cadb4a3e1a10412eb3474d2ed5c3fce78f5 0019528d505bf0584628d0214bc857150a929d3f59619bf8f3acab545fff0977c9bcdc97 aa1521e7445fc83ef0f0e18e2051a06e8723ee9279cd8ee816df6068f8ed38b428943faa6330a94b91a15caba8476c4a +c43ec3c3232cae59bdea7cfaf18a4672035dbd2b8b6b1b44ede376b36cc2d8baeb921e416aa177f5977da8bf1d713509e5251278b6622790056271715cd5feac58bee5baf50b216e8eb886279c5a384cdb696470275b7487fe9ac4c506706f6b0f9809d1ccb102546a4297d2017c2a8df9f02f30d3d1bd9aebf6a92a02e0d202 0067795ce117bc0a389397fc22a01cfd9422cfbfb5aa44131938a8c45e48e1d5a718539c 8080ec036c1b02935bb36627e365e98d039182c826de20db155b8176871085332628cde0b3f1a2fb01315798786c4c4c +9b7d675a3d2cdeb280ea28289b5fc2a3ef6b535ebee8ad242fb031e2e1f364e8ee806568b2f8627c5a5b4f51f4f65c71acdc1152c08b9211b81907b551e0ff47f5a6aca45dcfa06f09bf195d19d7b165b52111b601fbd97b192f62465f8ba20773b1599c8041e91448eac7a5763ca0628f40768324c5304e1119ca6a1fdb0778 019269dbfe4184249952a651a507584746c5b62c64cb3b17e0158aaf4d086a4afb0330c1 a5c6cf0c107a1a136c9eca3bf7fd91095f0b1241bb0a1fd3fef30e052cb9ceac8356ef60f03e2db29e39906232f9a77f +f4a08daf8f66ce57a986f14b918099bcadcc4308bcde7c169ce8536a40d94a928cfc0968180a2c2a242c59df73ff79a03687998c421cf9a0e661630378779a4744ae2a6cd24ff61d7fcd6c11a4c8bcaf358075e96f864df0998ee98ee393b37bb38747b70bb7a208740959b45174a60153ee566e0f62528e9a5e4466186fa650 003835814de0d6441cd80a44e40350cc8bd62ffcc81e939a4410bb9c9259e30463c453b5 a3b73c1f15d23c13ac4f6976e95f7bbcfd2f445b051d99b27c1b46a524620098da9388dea1c988125e6b23a5c0b885bc +864647405c70939fdb4c026bcad53218ba1d438d82c9138f0f0ecac815dbfb242307cca52c84826cf6556c51082a23f14252dfaea43ba229f7493db2bf8ae9cdb0228dab9e25cf385b504b92cca94f813acceaa1f18de851b8936c4dfe9e4e17002f02dded6b4c231ea5e614ab46fcdd637b8c6193e8d0c2df1b3d883b97e1e8 00aee83dbed3b703cb6e60d51e373eb20e298ac005fa6a572d02fa1e6da0345558ad2a46 8ea2bc6d89d01a7ecedd710663a31de90f4fec69a2dbc0b4dd90379b0abd86b2d76dcff006ad9864b3e036b3348f3ec7 +c87c8f3ad5c28a027b28ae5021dbe8d425f74181d519451f1fead7a1f9dd102fa6785b147b610610cb59bfa91fa363bb79ea602a7d7e1439f874c5dce748e5c320560c2d9676f3a948754c72b6db249478b7e19c9829ab4de2e344535d3e0b7c20c272f82556a280ef491524b255c4fafb9c8ecb87b0149ddd9d7bf6159e3337 017b65c66514019ff935e9d571a4e68e9ee4463b7b9a754b93f4f7741693f4399879fa8a acbfaab729d0211d213dc16d8fc22bc70a92e1e5c1ca5629043924d5a98f0337e9f34dbafa9fb9b4e92f06c8e5d89ec3 +ac7da7611e2ade20aad64b418a16e02e79ab4894d758550210eb10013a9b5533132be701f8843c840807c4167c38d21dff168d3baa65d5bcf285b73dcbb75819f8d7a20a849de335e19bae2aab2ca560b93d340731f291599a5b28afd7737460d291105cbba6d0290e836f6f6c1113d1b2faf90ac5de7c64e25206d79380a4ed 017d2071f39ba35515a8ec977ddd36ca15983e15bcda626f15af61d87d58114f4c80a8be adfa71f913d577d19b57df4e15e9e1ecebd42e3b659ed36e18c9b0afed4eaae140546ed65cb5bd43d5691f97ca35a0a2 +5757c472fa2f81430dd920f39b61066a28c870b80e6c96f822f8f19b398c3574d159cc22120454dcd7e97be8211916e4bc8db365b2dbb99a6e597d06e6645046a0abdccbd06741e9c0eedf33cb78d78a540c2a390719acc498331e694e6b0118cf4f787b51c7b7237458a6149d6dbd0a08bae8097e919f970fde920485e9a0ac 011504659e12235855fe55220287a101e511d39a627f8a0d414446385d4a88f31507fe74 b7b99c9939311803e0b2c3eac1cf998c05dc695db4d88da7b003f0199393d46a1a157403aa9c36848730e70b186675fe +e350383d04af0f4081bf09b95d1d53040e7acc64e56b13b653df31dd119617b800e0cdfeb935dfa5d94f1d7814688d8ce41021810958759cec76560e1e5c0581456acd1a020165849b2203f1c11d318d816697f36a86b59f160faeac7dba71682d3c031d0d547725ef69cbaa28345512e38b75ab011911d8924b2d17a857a96b 016e4cbabb03215767249ba2a608708b78d7387be9e77f5efd2462467fa05e8dcde2c036 80364307960dbc050b97a6842f3b726b2913ffd7f0c194b0a0f3ecb470c2313260a2bee6673945e2e5c515aa19f6d491 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K283_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K283_blst new file mode 100644 index 000000000000..d8f2796c62d4 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K283_blst @@ -0,0 +1,60 @@ +ef90f85fbda05e693006e4c64e1dac56223becaf0890f73b5274e6e289a5a1de2c141b825c24d595b3fd18ca855b5c1aa60dac6b5356275b11be670692cdbe5f282f93ac7b2e410a96cb9e9f80defcde98f3449f99e192bfd62040421a0ab8f99acb85369f25e5efbf81439efa8a5e1d9cf781355a0f47b037b09fe4086389a0 01e846c830a8ec04e8572d1a9d2df044ab47352fb346f67403a3bf87243871b164511c53 81e21d11dcb9eb52555689830af844987b8af5f036047353f39144ad4b0c96b6f6e63d0179898a3e7dbf76286d64627b +a3ebc17c867cc9c7c28797f6364f6574b80c7ec5b2d8e1542a6f5db8568c15032f92cfbceefa3fe4ee654f690b0455ee5d38dd84bb8665ffc1ff8c849bdbc4aa0ddfdbbca4eb37972fcbcee8cecc1aae21ec736ef61781716b60247b7551ec4e552d0b59a53cec5964c67cf7988787cedf769eabcc9cd5243f58034d96f0e43d 0101c5ed48231a56ca0ea85eb45de0e395e6df2efd4987a226ae36489dd8b2dfbf7c465c a38b6d36c650163a3ef621d12841309d61900c3d7e34c07bbe54d06f6b098408403c1f85a3e5aaf3aff6d59df7855521 +60269efa4d0ffafbbc655f6f00578eadce7fc0a7eb7db923dca49b6f2bf3e13f7f829cc6133e022c3c92143c075ab9ced0531a91e6e79848194ab98bb852f40c84e7aebe71fb8bc0fd1f97ed5bb6bad6783d8dc048df42738e841d978456e055e1b8a781dfecfce2218701c7af77e7894ccac5bfff360aab0b6136b978bc39c4 0019679dc589440b11f82b3716e5b2a2bd42c3b1c83e88a28e304cf5148877faf760b4de b7c0c24723c4bfa34c0003e0fd838f64cc56d326dd7c772718364ab1fef48c3c62e1db5d985f511493d8927d4463e1a5 +59d704d5b1f3a0605f1497f22f71b8f45b26138bc86371f00a4517554e7f6e7fa5d35189fc656ce68bd2cb8510fa3e3c3df815dfdd749b2b6ac997d443f3954c7a927e138b579801ffd035cea90840733e7884ccfe43d8d3a4a26b430673274aae312abe4ac1e1d7c67b73580fedf2d8de46572493c9205ebf0e8b4d75ccc88c 01703c21fb1e09f8947e12fddf166fda6f685221fbd803d75a0ae377a54a1e494e6c5e7b 86affeb558f91c52b24abcaa7267f756c92b0624884e419c0f319abe8627a81398146927f2171339038b989398d37da6 +12c8fdba3bc5f68e13f7ff8e7bee876fa68a970afc6924314dae0c2482763ced8d4752cec29ea288d350acd8a06c69289ae41ad345a1b88bcccaac903f2bff39015c289a8ad608606bfd65270a7bcdb5fb10c89bbc2d16dcb91fc9735d66103f6b1f3575622cf4d8209290315b033ee1f79968939410f465a2d37add46af2d59 0071de8eb14cbfb88e61b908990ce08b81e624ef4f2cd9cdf3dd7ca9097d5ffed9ae9a71 b5801e75cc2e5e175f40240c27b8c13a224ed2b20c242ecb9626c938a2cf0b8017c3cf6512a98ca1db0a9f675ebaf53b +26013a3ddf687bb2f37d9700923906f118d5cba5d8ed5113a0e3e84cff00918125108f74f4b243e351aa5d07fa7c6ece29f5700f23e50286447883d2a058c3258a12e4ed8770cabe627ebea7ef6e8c77811ed7d9a19c53287093e39226236587ddbc63b7ad5e7ad9895c64d1d03ee432d45a067afe27d4cca920ae88a7a68db1 01d156eb15762ed00c4021884adbfc2426e910b18a5bc474268196f4b74e593a8f38702b a2c3f515ea0366305d9ffdaa4fe8e09b1594c7cbf6196fe99b3e3f3d0ccd508521717566e608ccf4bbdf64377fd1c042 +c4dbf70b9a2165e7279122460d05ceb8e43e03fbe2ae7c314007fe2b1d8567cac727a10fba5cbead0ddb167d387da8e8f3d6bc0ad851cc32885809d07a776fd4a95a979fe3833610af89df0f454d9edfabe12495a118fe83add5eabb2acf54ba7ba7c4be20fc77478c0a0f0726c4e60317422a612a234a7567648603b63f1c12 017d6eb1219cab8577168be86b61f372b27ca70fb1f1a767947895c185344e966db17aea adc051771ac70aa266004a66ab27001b5e076174dc4255a9e9bfebeeda5c05d76c72ae112972396b9a3d9e7e0ae6d5d6 +b1d53b6af1face9b59af11c726b0099111d1adb3666209ba46b1744a528ed0f72be5a1b82423153b896384faebef0362343e2a4599803c08b8513708938aa8a498145fca1c63ba41aff06d1a18aa2a045fce7fcd7e5552a2b98d0df97b6876f06a9cf52a7a40fb737996adda97c3cedf7fe421235ac6951060eba9c0377e72a2 010ede9be6615b3b2a294d67da78127ffbf3a15bdba6f4fd78be7a60415b5d1a097c0cff ac2a99a3c897b83912f9bd352f4338e5fe0962ed25f22c3084700a84a10b386beb103ac437c015b90996ef42b6579e73 +e78f538b1ac21602b00a09e3db243ef4803b447329c94a1476cd91a88ff790da71421b60092c8a6e55327c7982e7655eb1fd6e40fa9b9fd2f10107dfc585994dfc5bc2143d18794a39f7f69ae679b27dd11ed22040d5e93aa83f71783525a4db0c3fd7b43e57dafd0033d5317680df19c2ecaadcb37ef896c61a758a5e455206 014f237cface123b64e8578ff33f86bfd2a8181b9c81f36b9ca31e2a446f0d91dbbe2249 913ec79a0450f5dc73f5b61261ad381d712768818f1a01e6de998bcb65fb41cf42ddeedb6f8500efa12ec1842e162262 +8a6ca8ec436d2c706fcbec6486b5665b21c174edee7ebe108211c388b1219a8224179f7438e0bb7d6e41ac4a67337b52d4cd9a069fe6c88960ae20be29c8060efd7c62cb7a9a37136a250e68f253e7f27755df53ce7c570135641ad49b43507e5483e17b919cedffdc0d4913b1d5e0ca0629876c0a551841a0fc2090d2857cce 008dbecb26587cb2ed7df2404e680fcfa5bf8cf6a58e87a350a1600211b3c844ca86daa5 86fdf1dc70db49c8dfce8e35a28fb6429f37c7156816200b8c67e11a7e006e52039ef620d32ab7c143061e1672a501ba +95bee02b423d2c6e60252da4632f693a2d8f6597b4f9c6e356f670c3a9e4e80063e92facb6421d0325b99dc150464ed2ec1d0bac72a042b35d56d33d2fda686a75d582d4756522218b4ddd25ed45503d90d3d185cba6cf0ac211b22aa4e1318a8316c369186f7130446dafad64f7966f5414f43af37a87127534060a23c6165f 0191badec2d28cbbe62c072c6b57eb5d4644d0c0b3283951bb66096cd15edd43a1bbde53 b72c5458a7f17b137a4a3535a2adc046bc8081f00f8b59675da5a8b1f5d00c764dded2e72a18fd5fc542fcaca09236ce +ccd7f7c0e04d1ef9a3c5617d77480bc624beed6582bc28e9e3a369b12144fcd96b735ee41713f4173b64b28c6102d82dcfc7876e06e76fc497d1d238bf6d85bb5feca630bbd0c0f0fa7c0c72e28e9259087698973ac66244bc6e69c04deb22eaeaee7b20da239ab6333576f01349c76f594498620933b8969450ac2bae66db8b 00ff5e3d66eb57fd35ba4472effd6e7a016ca461e39000a7125e99080f6ab6ef4380dd7a 960359dc77967d5cc18d0e83e2f6cd86bea48092f60315677f333eb2b48b534556fb6fb9affc657c0a24db0adcfc05e3 +65e9124a2606c8784c9489add2999f4cbe6186395df20838d653b263a207ec46995d2685b55d1874e7ef05a6a3bb5b60a7be6751ad568cef1bcea2debfc494d1e2ece0dc8028c88f1b2c6e4ee26b639c5e81f6448bd25b73ec4608a8e8cf4e0155c29b6f0a62781493b03bb7384c9808529d5f87da6564ae196a365bd282f46f 01f3591eec4a8a3fe6ae6debe230d238a6b73cf3791cb735add1abee64239bb100f15166 92c8c8fcdd82b5bd8d210debfa0010dc48a5d16a6bfb3639e46dd0110e33c572a12d0d6b057de8d764bda9b3612d8ef2 +e793c60fc725fd537d5fd38e9b4fb52e268722ae6bde5a058de8d20db301f5e8d8e1ad85532198835a04b76f27ca3c972be5617a55677cffa8219eb64fe53ced242efe1b889990979227dbaaa15ed39d3b6be8c5a3237ebe12bd96f333d947f80048463d3859e34f865d83faf03894c2243a06cc96788ed952e606c2d8948271 005af03cdb45961e7ff35fb0146904ddd6c2bfd3cce814073d3aa56eaa9f13b4f7423926 b77d7c6fc811aff9bd4f83486d1cc7d11b6115f12e27a5baf10d6f2dbe1ceb7f0139a7e93ffaaa52bf74cf991488104f +a57682d21cebb48190199e9f57493696eae3a59acd22f64d5ef4729decf6c2615b326817a6bc118bb7234bebfc7276dd998838c009a7348e46431574638dadc48538d6048d572e50d9c5974d2049ebe1837dd857bcd1447b1514b62808a4e7a88162ae1bb08a0f6d3db6f25874c6cd0cd4ca6333f1bd57bd192ef67e4616d182 01ec9710ada06e6270720692a06d488ae2ba863b905dd2fc323e7ce68dedacb35fc8c7d8 813b3cb26336c41e4d7c19ff46ff113b585d1a4884db91caaf40c0ff6592e56a777811338fa0b35f5e5bb9d06a045b33 +f646e7334e191c2bf0056d3bfd23f03ef7f0777b923f962519a8399d311b8f68414c689ca34b96871fae99eb7ea534fcd83e788e56eeef817cbfe33677283c736b99bf6a626f9515291e842bf99f694e4e8aa7c9911c591a87d5f112b3d96b064594e2b368e6d1bf1a1cd343d54916a66da22c26355266aa2884120fffb8b94d 00668de088c6913640fbefbe6d2c44ab26e481802dbf957044a4957c3c5d0a0fde331501 b7770239be574c149eb5ec4d8b6a9532d60234fc2dcc76d18b964c4cd4dff66c1000a6aa6a8b3d829c3ae4db72bb897b +a2d7e69ea381d3edfde4664c56c4cb140d01cc4425df757975cedc995b89640dc016ab419b137ff25a6a6d64a309b23890439d2ba157262393cf93d15ca1b1ffd19373ef12367f8898aaf56d5544c2f019a4854f69b3d8d320e03135bb7b675e588a5c3fe4b703938fa0f964916501297cee2fd04af767155c7739419f9dbb7b 00e6af57cf47de1e6f07041eb5e1a413fb7ddd82f8c7f7ce957eb28a118004930bec4dbd 901a5d05f9434fd9933845b88f3de848d0786ae27340c8629112a37f453e6158bb3889c323d9354bd2a32fa793af2025 +7088f60e9375ec6a42f705f851fc76cc833c4dcbb3352adcce9f59197c1b7121e7aa661c4f8ad9f4ef280af3a2981e90c01291f7d1cf7d3ae2d96b37fe6975e11b7c6c02b8ef044d1470b1a26b9c72e8c4e7b1dd83c8acc9542e2fc7d211b87841dcceea2ab8128d0ff7bb622b60faa4a89ea7008f7d55f8f9de675bc4596fd8 019f9b63fde8c6aa6177f2a38981505d04f8ac62bcc21007b05615d028cfe851ab9cbbc6 9517e845b9338c7825cd2b7ca7ba46087e63c6d6c00dfa55de933f2deb3969be39dc50a0b896535024341250f31d3c59 +ffd6044ab991849939e8a29184b4d0ac3e07acb63c7e6b886df9e8254073fa800d5910b9fe34fceb547565a2344eed4de394ce2251ed51ec882ee9207eb7340464c742d9d140fa0964f6bcb1efcc2d13919af4f727953de41b20728ab975c1ae0ce784865f23ed1325c68daa95ed5c932893610179be94f13b9a4149f09833b3 017704c1f436beb52f7ec97192e23e206ec09f9e8986e06bef71467c192bad6f0066b3c2 a0375b832a1b595b429b9dab606e79edb6eddcfb12940aa2a3ba51a5a5fec5ba10aaba9d31da6eaa1c538bbcf464cb8f +c9f81c9ff7d80011fd41f2de97a6c1e6a22cc2da7b2b9e4c50e1354c3e139b44529ac786ce795fc501dcbf11a935d4728a7bba44b4e86b5e5990fed4d3e24fa5ab6f303e1842918f156e00dccebed6897c852207ae5941c630014a41696882066c2b296d39cd8658cb5830eee78e29a00335a99a0ba90722ceca5a2e9a99a2c6 00c7d1ac8faa689698f5c6325a3b3f35e7730bdbddabd0693f2bfdc5c838bd62f84508d4 9186e07334f306ce82ab369f2596490057dd70a7fa6b6b98c5ed75f4148a0295d29d80bec828eef3988b552499c12eca +a60de761eb32490184dc1d29e21fa33889295ca587b994746874c7289eb9c83e9c7bacbb4066c761a06b65ecd78d701bd41f305cd7eb258c630f3febfbb0a367ad16737b146fd793dab23562e8001cd113135b1c981d1ca23eb3be0fe3e24fe3fe1089caf9fd8f4f0d1f90dcc7dbea4a9e2357793b65daf342b8e6d109c6dd10 01a173d158866db0ec665ee632b5fc397893f6a44ee17c348e7452800aadd8ce676e7fdc a3a48cf52c67d68cd02711a609112e2148e56916b75756077116fea39599c5a5a3aeb6fb0d7fef2d1a813e3eeefd859b +2cd0320cc73120ef13e83c8144b270c9a1f2049a9250ef7ee83ccc7584025140a51e2227a5ebb824deff55b3affcda63ecb1fd3f337c67c08054dc82fdace0c4bb9cef1bea9dd792635f655363d05903cd6b5ed50ee669bcd8157509366cd85aa40d19593265da26e5641590ccf04672a6df52badd4b99964a8643d9687b499d 005523cfacf4ed3b74ebc30f608292e45173001d80cc801f729c5f71fc213b243f041ad5 abaa333fa3f3812b5a7b6d7bd5e186b4983b0399e7c62f86577eea1ee76adb7cda6afb24e0f8fbf0f357a95abbf77f5d +a743d8337bdefc4753f937e869a36439da1f8c75e1278c3f6a4a969d93787dac93293818b1cbef5b8636e1a6cb3acaac1e15dbe0841c8001512b689292f3f4805997ae26ff52f7fe1842512a020c448ed01af2a061f3638689446ed5f6bed9fc70726ce4104bc11142de63873fa7039830223e8f152996388417c48e0c1fa81b 009f6bd008c04b8823ccc3ee7d5aca535c211f35e9d9e7cfaec518b98647fbe6d28283de aee5452da23be7adba7a2b1f29a9f45e734bb071cde9f772c8283ad4fd3d1847f83024107587f5bde8ba4f429f5be93e +6a7a3ad614a3a09d2dc5a80204815d0c6471057acc0fa73f3cbbf1801902c3e1cba3c1134a79a8ce61994a94a5afa85ae1a44b2cdcf5153f8625713c872da36aba0afcc5c2f26636dc3f60e04c256a5b023e20e2e7a3f7305bd5b3033fcf05368589f19021f8c9096a88679904b657bbe5b9bee67d6e53d176fce1de9e54c64b 0150d2812505c82584201e93f6e0cb875d29dc7bd99d9c0f98e0ed20128886e67e1f1071 8a57f517158c8e52e95d34e333c0d017801b7ab57878af5a424224630aa014eba2b9ef068a1310eb3d0dbc515e70fbd2 +65bcd77a3ab345cc99b9c1300755288102a6ccf140bc7d1ad25df246ef01fd57a8614b352033b88cc6ffffe5b38b99ecf03baa365ab5529d6751a3c020d0198561969aade09091434d84ffe13b46df043d0a61e20a08e9c32b646771fea1b29e202d40aae1c7079873c3af494ecf6ef5eda855736c9338b4a5c29a086a8266fa 01b3fb9e1ff70f94bc9d7742ea535ca982215af3df381b5ebdf1db40c7c849a7978ceb98 92a9f9cc82dc24b82d6b3b38d2f6bf57b681f7f6f6f11a8ca5e999efc243a748e6381f19c9a6a26fda563e01c839a8c0 +ed1acc360d02ee6c36bbc223d91bc1d2009a3e8f8dfc4c3796cd8555b0d2b46716f4c8058bf34c2d4954e098274ab9c2cbacff46a0578a14e77fe104196cbc6d2753e3bb5422b8b79fd004ac0aa920eea94925c016ece16ed4dea916fd92563ec65692a61b28ee84bef0007120bb1e31bb75b8ecf68406a71af9a18b4edf5320 0147fa46fccf0805d14c1b84ea59bb8b8283d54ca0ceefb29b5585e7141340c55b7232f7 8b40cd4c6a503903bffba003798c7530d3335a1db2ca738054711b9e1ce903309543932335c1dd08ac06390770875f45 +2debdb95a21d72b69c545988727366a42b819ca6398a82129c5e3772aea93fac0aae9a27b11969ff0ffb9dc0301132ca2452cd863316cf24ae7696422d4dc68e37316161abc146e86f04b72d9a27a350d8545cca245b2be43c33bb822dd813d13e08a718f784845df8a4ef49b02529871ec76bb3fc1ba31089359f2ede73e767 00fae097ea56b35a517be5480802f450eb832b244558d0cc922cd4a5b40b84d02ef11216 869d3495f0a27b046a8cde282424bfbfefd66387c1f13a290a4e761f12c333a5761900cf5409900823d683c17ecb438b +e4e0c6c8fc01244abf81e139c961b6a6e2d95de5dff1083e8a48b40e3e5b9ed909152c92b1cf2263179629cdf76ae553b58bb2e9223ce4f9ffb5f170f5f0c5ec97294c34a7529a897e9397f71198cbcd68bb4055cb8cd6b690290761b3b73303f82788379df145358afe28f2997d191d968929b7a4b9a0f6228797dfaa17c613 0026cd72e6ae19b3f4c53493fba1e8082a8df1fb7da6dc111b47a41f713f49b33f618d0c 8f072cf0ada603caeb03dede9d70d27a34620f42727a296c30320449f6823a369e7e6cff69e42e04d84c39b34460df96 +04710947b7c90855ba4e59107b919d4a1df22b503c5c4c33b286b6b08e451e6fbef8ba40852f9f0ee62c9217abe6156bed46ad6f0e25f70f528f3a73d099338c578bebd6879d810e6e173c2b0af1f7caacb3531ff0e6a7856e4c84db355d110febdb21c683223eb5990ef2038d462ddb7962bc0feea5f850954943d53041f66a 0198e13c7d95bbbb6e226688719639bda988867764ffa9b029018b5547850daecf58fe1f b441bba12d1318f2d67b6abb67be4eafe9d849be9028908f86d50f31711f9e3d6e9a7ff9573baf7b26c6271052fce7e5 +c62d07bb1ef756b6b2fad355c66b5be086b6dc387b37cbc4a63c841dba3fce65b09d3de8f239e3649382d172f065b78f8a53e0283cf345de06b4ee0b4b7d8611bfce92a7d993b1938419afe817611bc6df3ef74191e7e39ca2339fcb5b5cfee3166d09cd52a1a7d3779722aec328d326a11bbafb6aa417920225ac453146b9b7 019098a39956747de24ded56435fa1e6c30cc2b8088fe9a75f5d07b2f5939c7a60db64ad 899770737cf6925f4d585d1b3395336e7efbc5d0abc7be743410b74c02f42045f9658d647953f7572a04e6bbe87d7f25 +e4d8d49c9bc566261d9134d5e237d9cbd6b67d2619a9bd06b7c9c139e091aa10682cbede114e1d4777d9cd67a16b7d64278e99eed62bbf25ec5a5a8fabcb0a3468b0e73fd02ac6533e04b1110d29da3e34f33eaa228b78341b357a5d892a61beb2168c3bd5e66bffe3f2080a1e246f55a41ebf9d579e188d16991aa060460d6a 01636bd2be121e07ee83ac5e880cfdfca6a56f2b9d0badff003e872348368c7c2cd96b6c 90e67333ea8d7dfea64d68c59041b38a19d1129edc078160677cee2b1f2b344b71c90468d4773648ae71815a563d2576 +2d1358fdffc14630fbc421b443d3c22ba10ef34f15c6c5bb3c73a9b8714e4c411de69b9cd6628fe2eba5efc4862af66ff916505023e0514f564164b389ea422d0f1beb92adcd65baf43556614eba25e43852ba65af78f62d64b36696519ef8284ef7316ea52c365b99f63a39e6701f81ad520d7445cfc0113c38ecdad4bf5b7a 015e5f555119c19b055b15b0c0d2813068bfc184f864e250b202384f5728bbbda1cb0f5a b7c758e38d8407d52020ecee75e86ceb53e3c7c5d1dbf6b67c181489333be508e4d62bf1708bbe78b4897f7958620e0f +d6336faa5c3e838f4fa58626eb353d4cff9ba8f0aa0e6c3d0d850e8b22f5b0f047afc97767f1afe2040b85d4e401ba688a4da7a0caca7fac450899092c4fea789231ba9b07782010720f45d16d353798867dd7fef4a324520014ad5cb32684ec50cab742b750e05db040ff51140e8d740f6774a059feeb493b10d8ac722f23fa 0190c8f17bdd38669e345440d2c7631d67cee9c6548c4e7b9452377adb9303430efeda0e af77764a156d080024a07eca1eb2136bf7ce1f2e2c3216d56dd5f4dcd236169a83904835ebccc0cbf612dee3f8fa1c8c +07384a3f650bd270b14ca388a441af201b7767a2d47e9033f50cefd3af8257ecb38f5267e141cbbb2ab7327d8fc78cf27198ca3543d39553e178390bf1b921618432ad895e4f8153783a7ac22f4ca3cad4560e64f1ee4a7bcad05df98ea49a3847dc2143b27c243e48be59c869a547988e2205358e8db98b635ca21b745df4d2 00dbbc2a0409ca58a9e39e33b95fdd15080443c1dbdb5874bee991bd1b127047f08ec9f3 8739ad6f1c68464755d154b0418d3fe6c62bd5865cca3cd9cf88f93a8e1170c0fc26fc593c09da649af1e15dcfaba51c +824f26dcb4ce0ca020982814d5c727e629cbeeaa818c49668f8f6d743f0d0ad362b24cbac48027898f386889ca5411d7d1f9afc69493b1d9ae4d7b695c9fa0a30bb59e6be2cbff79231767e96cd8bba349fa2f97955d56f05430ab4ebd007064e3d5add94dfe255b6deff19650883ce9966e1a2affaf84d9540f65c87ab1f936 005495e6c59ca1873f36b756579632fd47f9fb95b64f52589d70f2739aa6a3bf8cf8c198 a120dd7aac6fc1ac4655ad1a28b18413362b08a591e6d5e81a983a35b82532a8cf7620f0a42d7af7793e42e6203d413e +07de1e4bb9be15a710a74806d4447b093bc08ed04392d1bd5abb414f5f4b4d9d43520d0e46fc81c2a97e71086b28e53242449ed37fd7ed1c5772dbabc430fcf82ad20437b38eac15820421e51912325c872894452c3f8a10ddb040b35308e583c155c3707b52df467c4945f4e1071126ed46611a3253c297f5cbca9e27f58448 01724987c9b698519b6c225cf1261b77d0300045e5fd774dcbf13f285e6bd74512cb7edf a67a6b2b2af32502beb439e9f85b1dd03daae2a07d49d4a566deb68211c36032f4b3d70b8076aed86ec9503f02fce32a +1edbbbe71057bf7d0bfda922be21a3a4dff57b017ebf6fa99651246cd173bdc9b11eefd048ea599c1f98e907932aa04f64ed0a007831f30daf186c88807400970904d6090b2cf181e0f65f03b4234aceeb420867812562e47f452152bb1ddaaa48487170d06e47c5e9a7c0faa4fe494663d2fec22f7665ceffffc214b21c6b8f 01a5489091cfd51a0970508ee3e8449081ed175928ff8386592c83043a7911bbc2f8778b a4c17e6926b018df6e1ef027b1fa03033809796868db4c14753d5a442d52ad7bc066f2f7a255ee3efbbd6a1e741dc9f3 +db5cf1de38a5187af11c1f0f19a36db52f8417de997229e83072fb51a3b7152a3b383e9919c1b8427582e53d4e7e25433d46cdf01492021c237ea0a87d38c71634743115a6b2aba66d3faa8003158340a5078171e0bd55a6e5d8c7fb2631a31c1204e1479bbfe79ac70d5e5823af502922a900576f0088a33e42ec3e26c0089e 01a45ecda0788fbd7cb7a716dcf4c6e83d4148bf63ed58078690ebd238c00329c462590a 93e4be14129149f549baacc7012dd1a72e4dc6f4399c646c803612aad4ceb26567a073840ef10425cff6706bff08909b +4adaa850eec8272d25d76600aacf2cf66e754f6c5efa65c55a2a31b7bc69437d9a7e47c6f51c5da93895a45221f5f92c2e20ee6a95eed3cc7249688261a35d82872284900eb54dd1df6024ec48963ce43e8ed8b8cca8ed22beee8f0aadeae53726cca05443316537840ab824cd1b595f36064e9a19333748d4f4972178e7f5ae 011461776c33f20b176dc8f2b0cb2446a9b69e55b6c7bc7457a7fb4639116b452b79661a a743f68772c263d286873ee5cf4c6ad82ef2680224718caa3f1ca9da73039ccc745435470bd988e136d3ce093fe621f1 +11d212a99c39fb5e4ca0096bbe6c81ae1490e1b8e07374b4e773bee4fdd24a3c13d653919db663d2c32aa4db140c4ae2d472d4f878946e527ad33b3dc93012d97458f96cb622ddb56f1ce7c2474ad0d5291dc35545de47b7053d137a8e79dabe06757ab53e26eaf751111bd27690e57ffdab5337eb6f81889e9d1b1ac729012f 0025a65f627db2b4d6cf83c5b0c00265b9b63f7656c5e3382139e4992bcdf3cab502844a 839f3a188a6da4204bb79b93983e9ebefd55493801668af082259a942b34a11ce0b5670646afadb511fab0c6179a4aa6 +9e4ec74c09528fdf3153a0f6955f20c70915ff524b2e19c991ec4c5b41ea9185e3e876a02ed6f27c9b3479dba951bee8680c4c99be1a626808114408856994be7444ccbd5ef9859fa479b1050bb836034e20c531b4d618f5843fe1d4b613a731895b489a2363f3f5397d5ff964cf037e9b11e3ff5e1c3d403e5a46b8387c1241 0173b28fc29f10245221a907778708b3ee62e0480aa9051d4c3eb4e8d552e6aad5509943 845689352bae74a27d48771ddaa02c11b293453897a5f2ec5ebf74961fe2f13cca1bb82245b85c52e0c5b8853ee92f10 +5fe8253d2134c434cb0866796013722e82184638b024a5a30938039929ccd8415c71f71f239c5c5a81f7a9cb493dde209f189bcf766c17c6d9589cd0c7de7f07ff9f24d2320669b589d084f8a8ea71127b9760b7355b162616afb34bcdcd416f1a062035102e29b70069b2b4dbf70179b8d60bc2ee5a455efd40194533bf560a 00624616adcd45e1fdc6cfeab2b17230d73d91fe0b39f4664f3c6891554f9b8e238257f7 abaf628a79f2cf6555a93a35972179dacc40366f9db7f6107a5831b490ff6967ed1430c9a358940753e4e2ae462bc3c5 +db49891838fe23f0530abd4a4fbba5ea970afa5747f6a0a10d2cf4d841581ea2178705c1203f00cafec91d0a72d25448072c9cf7d7ca5580b39f8589ec63128faa95cb0689574a6bebd515049a1eb9699922cde0366b5cd58aa8f3d3e847706896f7e1cac667fbfe94b2eca9e7be79a810806ca4bf53f219bb30532ca2254c11 0199757ffaa2c59e198d66824eaad37cc42d49b2e241b6a60382d05e425e800eaaf32470 8809a3a911d8b4d22d40a4bb0643c18514e20bd13259f81259ad6ab742cff98505ad5299db7247d31d26bd8570ff053e +29d385d09c1142a7c181fe4b6e6132e414c15aa8605b44208c0399464613b966edcc2d46cf203a3f85d943d8eae658695dac74366224a0d0348083bec0106f5eb8809ae8d07f792fdd7c48fb1a25d5ef3bb9acd40b20c61c821024a9acb2ede321bd2d0dda849c22d76f421cbd8d51565d3c4266f666455ca1c0c3777aa44107 006e51381dcf21050aef2e9b97e35303cf3bd91956854ecf9b6b9827871d2efbe8201c5e a7f928ca20d6c46a01f81f4333895182ee21df6ed577fe8250ed636948c74d461c8711917e9cce353eb73fa9cceab314 +774c1cb8fb4f69ecfb5c7857d46415568d88f1f9f05a4bf64a1e1ff6d64aec16e1d09292010d1f067c68dddbcde06ea49be2ad3838053f0b9c0c2383edc451ef0188565118e7b3c66a4fa372b96633dc8a753106283b02d0322df273d58cc9bd061ec219f1e1a9c8ca1400e5e39c1b2c254273377dc98a1a2c44e5c2a5b89167 0018adcc22cb9a2db64bad3d60f1608c353e091637b948914115ebd43679904f955c8732 995ee9aef596d14d6993781de713dc269cacb8b45b5c658a878f2f564faae5f12373a95f3f92866a883a3decdfaa059c +c406aa4295f85c854b4db2de5a7a2defae53a319866921a3673af5b48c85ef22f6eb4cef892c790d8e64530fc20c729b2821b5f5e515560b1ac764106560c3a6a05657e34cd6deadfe2884bd288cef4ca92e1f25adde7d68a30fb0a1b3678156ced62e466718e68e9d67099ad82613b8d06bdda1a7b867c2455422818ae9eeac 01898276f159c10d92d8d4b6ae214d68c72792a4b5f1f79936ca3c063dc8d9a88be439e2 b0dc29c2d8946d67f012d768068fe50710cdf1ebc8e9efba920f280f46c2fc7a52056274779c6d84d23acf7572924fc5 +cb2809152f8258660933472c06ddcdb65f6d5221fa29d5b0efec9c2a7914dbbf9ce0a468ce146fb333d26f510a87a6bb01bf8816756a1b5df81c5f65360957cae84ba038e37e88777580e91c34e2f5aef4fb55af7b81ad28aeba05e0b1c64a15381a6719fd2c16e38a441516e1b394952d984baf9e051b1dc1bda2e12f8ba5b8 012ff37c808c3cc029a9cfbb67a5ed21f3bf362b49270d4ed0f1e38fad25ebd79f112a50 98d5be76f1bb7fc159fd5d3bdcf13f7482a45e35e71eb728b9898123d57fec0f51c0a340e1b0d6c8f45bf2d3eeba8fe7 +e060af96d4a7fe512bbf26be9a27bb6a8ff37547d4a7bbbfa710db24cffcfc760dac120f89f642880db2df6307f9ea5441d5932d49762d182b29d8e7fb067a61ab0df622f75cecc917e27d0326085d34581e052c85f50a37713e27518aed7c4434f86970e00a0a4b8503989e72614131b7164c1bdc82d2b6aeac0787f9838476 002b8c1fef9c6def32b5f4127273ce384b6add4aecec957c1662f52334f5ee97f49852d4 acdc545bac7b1acb3c9d9b8d0bc983ff8884da10c084b2fe1e9270481154f3926c6b91f65825d6a8e4644af71efa3b91 +d235c31f0a82957a087c7597673970aa39321d4c2640685a03df8388b5eae4825d1fee29926f416d5e62a2e9ca1ea7cefffd31607e750fa9675983608e0f8dc895371b190574d065c5c0c23ffdaf49e65362914363a3fffbc2c1bb487cbd4f69ec22dda5c7dc3bbab805c81faa85787cc176bc0e5703924f395d8c9e7e7701e2 00afb1c45e9a9f02942b8e04da4b815498454dde6643de186625a98b3c1c6993abc8bba4 8d2fd6c4a15226f1fc8ffa09b3c98f9940a76348df73ac13cc6c74f81fd34c78804c883cd1306c4fee8d3717b07f6c09 +1a2559777a5fd8f269048feda82c4d9fceca95803f84a813789d6ed070422240e443789c5231d63d5268ddebc060dfb99c4eff2ff115d2984d8bbc5c05314562ea6864fd543e7e0a3b8572c017d8ae3563027d79bbe164d40a5bab354720e45094b9b26391ceb55339592fc2f10b97dc9c2649f7227648f5cd2fc46d78d31c0e 00ff537d73a4da0ae3a4894016b71dccef3bc886f3d24a5abb7dd96cf8fdcbdf0fdc5e51 95ad8c141d0dc2a8d13e4033c6695cdb4545cd3ba9d04cf4016b5a0135de88919c3da26ac7d9eec94d79eced33d30dc0 +658c0d3f764bbc952fa55a258bac16a5bb5184bfa76cee06baf9ee6b9ac3f116e08bb2406b1dd4be487b057f3b29c2043ebc33019b2017c4deccb86f50ff15fc9248ea5fb64261120b1960525aec3cc18827c23291722c5add8a3761ff8516c61956c62b8cbb13f3d92bf3eb45a70704c01bb3625d21c38ffa83a6db086ee968 016000d2e879906d1040b32eb6ba3caff700e5565871ac75f10c5c15b509964bbe5e14c7 a3491281488673a06cd85cc15157e7fb0bee13e31ffb124b7c7e8f3ab7058ebde35d53b03e6ba98a064211a7c2c9d54d +4f10001e3517c2c1f973b555f4827681e096d860c4db08f1f4aef8000c9c24bebe59f8bf3d7d3cac959a1a5477bb0ea43f2e746b5d14ed48a58ef35484b0ac786d2fec669f945e846ad73e6b77a9e47012a951b398941566330d89125eb3c1fbb2f06adb951ff5f047d102fdf28b5cadb4a3e1a10412eb3474d2ed5c3fce78f5 0019528d505bf0584628d0214bc857150a929d3f59619bf8f3acab545fff0977c9bcdc97 b05d607bb36d80345344e341e4bd51929b60d0f5d4d8f32373c877c0650569289e2daf94386d0334b2d765a026473338 +c43ec3c3232cae59bdea7cfaf18a4672035dbd2b8b6b1b44ede376b36cc2d8baeb921e416aa177f5977da8bf1d713509e5251278b6622790056271715cd5feac58bee5baf50b216e8eb886279c5a384cdb696470275b7487fe9ac4c506706f6b0f9809d1ccb102546a4297d2017c2a8df9f02f30d3d1bd9aebf6a92a02e0d202 0067795ce117bc0a389397fc22a01cfd9422cfbfb5aa44131938a8c45e48e1d5a718539c a80c83c4e6e38648423a05f6eee28f81e14ee583b6deb7603d0ff259e8ddaae6a15dd1ed6d9d2efc72babf0a4439403a +9b7d675a3d2cdeb280ea28289b5fc2a3ef6b535ebee8ad242fb031e2e1f364e8ee806568b2f8627c5a5b4f51f4f65c71acdc1152c08b9211b81907b551e0ff47f5a6aca45dcfa06f09bf195d19d7b165b52111b601fbd97b192f62465f8ba20773b1599c8041e91448eac7a5763ca0628f40768324c5304e1119ca6a1fdb0778 019269dbfe4184249952a651a507584746c5b62c64cb3b17e0158aaf4d086a4afb0330c1 80cb59ff427d99efb204fabb4c5618373b0edc7ffd3ad32e05027a74d46417af5612c188a6d356094ccac07b25e0ce01 +f4a08daf8f66ce57a986f14b918099bcadcc4308bcde7c169ce8536a40d94a928cfc0968180a2c2a242c59df73ff79a03687998c421cf9a0e661630378779a4744ae2a6cd24ff61d7fcd6c11a4c8bcaf358075e96f864df0998ee98ee393b37bb38747b70bb7a208740959b45174a60153ee566e0f62528e9a5e4466186fa650 003835814de0d6441cd80a44e40350cc8bd62ffcc81e939a4410bb9c9259e30463c453b5 92e42cd76f3ff7aa511833fc42739af635157ffe5c62a04c0f9db620705b3865a7ff1518274f8422da481fe3ad36bdea +864647405c70939fdb4c026bcad53218ba1d438d82c9138f0f0ecac815dbfb242307cca52c84826cf6556c51082a23f14252dfaea43ba229f7493db2bf8ae9cdb0228dab9e25cf385b504b92cca94f813acceaa1f18de851b8936c4dfe9e4e17002f02dded6b4c231ea5e614ab46fcdd637b8c6193e8d0c2df1b3d883b97e1e8 00aee83dbed3b703cb6e60d51e373eb20e298ac005fa6a572d02fa1e6da0345558ad2a46 a32e5863bbf47d2e962c43f39409ccdf8941e9dce5279b88f54dcca3dc2115d183c73607839ab45b6b16f8926a1c8ed4 +c87c8f3ad5c28a027b28ae5021dbe8d425f74181d519451f1fead7a1f9dd102fa6785b147b610610cb59bfa91fa363bb79ea602a7d7e1439f874c5dce748e5c320560c2d9676f3a948754c72b6db249478b7e19c9829ab4de2e344535d3e0b7c20c272f82556a280ef491524b255c4fafb9c8ecb87b0149ddd9d7bf6159e3337 017b65c66514019ff935e9d571a4e68e9ee4463b7b9a754b93f4f7741693f4399879fa8a 80fbd4d296fc9068cdca1721c5e702dbf70ba401cea7c7a981a799e6377bf7a20e31b0a15bcbe129ecd8e71e8b32f937 +ac7da7611e2ade20aad64b418a16e02e79ab4894d758550210eb10013a9b5533132be701f8843c840807c4167c38d21dff168d3baa65d5bcf285b73dcbb75819f8d7a20a849de335e19bae2aab2ca560b93d340731f291599a5b28afd7737460d291105cbba6d0290e836f6f6c1113d1b2faf90ac5de7c64e25206d79380a4ed 017d2071f39ba35515a8ec977ddd36ca15983e15bcda626f15af61d87d58114f4c80a8be a6285eac679cf5bfa89713e67bbbd6710757dd2e7c60697d83854af711b06ce1d55e47b0e7a352ba465a0edba89c30ba +5757c472fa2f81430dd920f39b61066a28c870b80e6c96f822f8f19b398c3574d159cc22120454dcd7e97be8211916e4bc8db365b2dbb99a6e597d06e6645046a0abdccbd06741e9c0eedf33cb78d78a540c2a390719acc498331e694e6b0118cf4f787b51c7b7237458a6149d6dbd0a08bae8097e919f970fde920485e9a0ac 011504659e12235855fe55220287a101e511d39a627f8a0d414446385d4a88f31507fe74 a5f6a5990054964569f12f2819216cb74fb99a07525ab7f1f74975c1c0780178f2eec2d20474a4cfc0cf25c4b28db32a +e350383d04af0f4081bf09b95d1d53040e7acc64e56b13b653df31dd119617b800e0cdfeb935dfa5d94f1d7814688d8ce41021810958759cec76560e1e5c0581456acd1a020165849b2203f1c11d318d816697f36a86b59f160faeac7dba71682d3c031d0d547725ef69cbaa28345512e38b75ab011911d8924b2d17a857a96b 016e4cbabb03215767249ba2a608708b78d7387be9e77f5efd2462467fa05e8dcde2c036 b58b8ad8bd794b5b3c8c11452dda28856a1c1180133ff422059244abfc3db39c70833042650c43a79001f04b6b3b3d17 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K409 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K409 new file mode 100644 index 000000000000..d0c0d9622fbe --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K409 @@ -0,0 +1,60 @@ +f153cc61981a46d8a47d17d29ec157fa93fcf644beb84558db7c99c57fb131dcbc5b65581ced5ff0b29bfdc66ff703ecdd4290f7c353c02a3e6d6867f33f3dccd1a0b6752b8a35fa143f8921a5078af9c85b212564c5b795da9858c7955095938fcd10c21e35e1abe905e84c8b4bc05f2a06091ce876d9519b96951d08c7ac9e 0011c6528939672bed3e8c905b7ba594c3ce95f37fb28044f210cccd01dfdb42c10e8e1a0b5d6fc757834ca7f08e98cbc52b0edd a76b5f3a4a26c5b98fbee3ad1d340888ec9ffe6c89e618023d61782fb5187e0bc8df718a11b3c72be50f445c17856144 +258c91524423b5c876432b1930c7b07b56eb5e3945f1e2296a4e5bfb9b9123f800ad195d6104641b1f1970bca553c2032f83d17252e52403a9381c1fc18eaffdf026f7537aa27d84c5e3d6e39e651a92a41139cec5181fe794457f556b390943093be719acd23fa1ddf7ff0aaf0479484a381a309b4f681af74bf97caef08c22 007e3b714496dd118d8f3f597961eec5c43d0265bf85723b0b9b0616977e0acc2cf686cb6afa6cdc19114e27ab000e762dfe467b a506506f20186f7cfb6a43464ac299c3be78abd129c9acbe04a64e76160288705e4683c02928240dbb51e1df303188af +a16a0d6fd57240fe88c7c36b9f7f9040cfcaa9afc4beeb8300818c5f90cce73b819a12c31d42af33146399cdfa4ed4954d068dbb0f1f342269dd29f1fe357e7224304b67b0f924b794780fe7e6aa9dfa3380252fe7177b43e7b1789718949b9ec1b943c83ed4399491482f0f59d2cb8050ab6f8b5854d76c50651428cd29c40a 00182d1e937b037bf7f84144f7d4c94c935269c9aae7d500aa459a7a0ec113b232dcf282908eee4c84b8106cd38cdc41db3f89e1 90bcf991284018b0c43b74d6cd7292809f126cb3bec5c3557e78c17bf0c894a811832aebd810a420593e41d9ad4592bd +d02ff569828fd1add21f6bd1c50cbdcd09222e458ee79fd5dfdba3cbb84e9d926fcf196cccedece77d5aa17f8c8cbf3a9facf0f02c71d5c1c8aeda9d75f6fd7b6f2c5c70dff992ef6e02c438fb3c66da5a503b3c39acbe2a069da457595b542190d818015d462670b0807c401e36b1bfe05baff3a8ccf8d1f5f8de7840e87993 007ed09428f460724c8a5225a31151e031d9949493fff5703369c401762345d002c4ce424294baab22d9e71edc4f854510cf0e6a a00e94c69db019119039c3c3a35ad2aa7df6013db6deacf014bb91615fa277eb43de2eaafa795bb1b6ee6b0bdacfa6ca +57befce973b225cfce7f996fa5a1a43acd160681b88a87b7de04544eb7b6a719718f1ca7f559b6531bfc18fca3836d2be7f7a6e48387b7579a6845796d30e46f0dda9d82680f8c96c5f0989741adef9762c3db763cae2699cb6c112543635e20ed5cfb4b55ca2ccb32d2d13936085a8ff95ed658a54be73f80c912ccfe5f0ca0 00390f05b9619c27b800e99aeaf61ef7f6249367d5cfaeae3c7b523a8b29153eb8a77132f6c4412545a842d6deb7b7aea7e2bda5 922737ead1c3a832af99cfb0b5f92050051b95d22faedc2bb37e14b620e978325d155017d5f19c315181d17327d352b3 +4277ba40cb462860ca722cb4ee71c61836d2ceba18bc91f3fad7dea478972c6da0ebc02815eaaada1d1a5e93d7ab353855ccfdfc94a5742fe18daee2328871e06c1ab0a9a989d1239df2d2d27f96c415e7ef9a941f06c6790675361173cc229aac7045f49eaca207f59c497619ba32e932b5c1c6576812ee5b146e2cc7de5e62 0007d18652732596add3db31f7a0ce6020d03f3df58131b0c7c633faf619b8210cd309d6c0c4083aef1a1b6d2a756adad0bfe344 a98242ebbe3e3f27df558059b0914c8f7931b4c8cfee1b4da01e6a0cbec499e26e7aa15e61b38d37df7db4b4fab1bb1b +57ff6792ed4b12220d179bc0ea57ff217f322c85bd3676a681d32d7e4a3e0c8e891fd267df17caba5992f68c35ff670b60b4bbdfff82404f6ed996c30539bc395120f97d4d7a652eaee82bd8f9360bf8bb73748b8bbda9f9480eb54f7eaf2609d4259329e8a5ea020521e7dbd3ec56f23c849932cbdf2875f5d5c774a9d6b0c9 002a91244ea4623b63403dba807d60b914ca3b901a2523244c322f2f11251446d3f15e869d086ebecfa1a39ce304e8b5c8de23e2 ab8f3c21f5ab03ea7c9d91aff83af70cc7130f06b01c482f30347f1210cb20ac9fa971a06f92798369ca992637ccea23 +f85113eda64478f460b60f8084220134933de049200a5f37884da7901471542e26690a5fabc3cbf9e679ade71b6e54d869bc136c3d34cc4a9efcafb777abf046b5ae5429136112a9a36a475121eb1f33f1f43481286fc1ada98a41064a1fa38c89e99a93065bb2a119348a9e452497fd5a0d2b83a66b09da9f47a0583732adf4 00068c56c6b5d50d1d4e13d3837d8c5e8ba2f825e121b63e97603fdfe78bb6899600ff0dc87b6b3b6868ad0d2f62b7b7a31603ff aa2cfba0019bf5e12adea907691040722d52f5c024ae58ebed544abe5f426e8231fd2c46b470db729a002c5369ce9df8 +42811e9ee6dc509572e1cddbe5baf00afeb0c5c13e3755b922eee9e210001676082bc9edc3d78db2b5bebea7a2c0cd2b369226c2b8f83b28f33fb513407ab9d287d14b112d6c3be2493805ace5cf6fd366d03cfb28f4ce3f0f060880db64d6962e997463ba7c05b6fcd1e66babe4b94afc5c2d38c7050c69571d27b66ef0090b 003c88084f8b78446db431bd6e240a0c050813d2a763675b0ea869cbe183df697146cf29c03479af3d34587a95cd257027fbeed8 b0897bf72897274d2d86fd60b510d1ce287841c83ca1c7e078980b63eef062f8617efa72b993db6d00af9c0df8b2ef4b +b38f76ede7441ae0887e689d556f43155b38dab7cde487ce9ef9a46f2957c830d4d28006873fe2368197a6931f6fcaad755102686a457a7edccc8d344e2d2a9162e3d71d41c09a022539ae6d404955a6ad748231aee1f974d4f159940532fb3b1fa0254bfc5805d2fc68696856fadea386c542d3cefd1be3af04ca595e54be25 0051af7b63bf3297ae20517faaa1552f4fde65819dbbff6a52721611e5b7dc1242ed6e69768cdc37ea8cdfd1a5971f06b84b5803 b92560bbbda78603a57ae51b45a2103db6bf140fccb421bfcd9d01a09b6d5be7ed18cd4206ee4d313b6564b3d5e28270 +356dc86cef7979148e995fc5abe2b14a7d5e4e42c9b3509b4363bb80c581a66f4e7e4aa53a4bfd37f9a7eccf75fdd726f348f6a3f779e6599f61bd1d668517f40453b39bcf35db0852a6a6218198f52b7ceda2ec55fca5abe8e5d93af9a42b9ae4de9530c5870211bacc27c39aa094013db703de2fd3121f08d7e97dbd4e8946 003d65bdec48972d03811b78150a06956eb22d337dbec5416bbd8185a6322cd8c0ff8000210dbd1326422289071cab65175f5d10 8d9900adf32395a1b90b464693a4c108425a09b31074a71708d7a6106aa006af4544dc49c87448a3b377ce2411a595de +06fd39a50bf25e89f1071ff81fec5d1e35b6dd68990414ee403dfdebb792627b6a4ae3d2236c159e4441ff90b61ec87b1592c538515f0486b19e58583394a05e6411e69b4285d6d6589982ac0eeb2c912c4948789cad741183663fc070943389d4e9a1150b8f6088fc50605915e9e24b2d98a1f539024770e4820e14ae42ea8e 001f1a8b5f35dbbf82c102df550c72216a243f986f0325920f6186a16d1da74228cc02be6024c7411160c183c923c743354f9438 acdadeb02c375c5b2c3a3567eb85f562c4f37bc56008a3afa55612a5614c7d3a01a7768900c0779cf0242439e5d4c68a +6daaa41150ea252a3e966a338377307d909b95080e006f13027f2be5059d9208930c5a329994c0b794ef50eb059bc6c215f68cf42260bd410f9bd86d2ad5ab7179c7c92de4a93a5f6aa17de5aefea815e7c0b78a8cc53c21dc4dee037b29c9df4e12343109283ffd5d8a3b81fba1b5e95506c7e01ac056c86dd0ee23bc21af0a 0031dc621200cd174193d95e9092ffb86189c52cdbb9ed937593f2cde7c4a0264b9100e1b8407336c8dfb5520d28a18dc4e39a89 a8e114f3efd21aac282a6cbb1560e86f6e726345af619fc9d44e764893851cb76801fa26a1d795abf4b40910e79a1260 +6378dd1c12c5197b57d47dc46a67949bdd1e0809004e94d49b0234126a08ad5bf8723ebfd132145813136d8b7dd096f56c34248f09a65c34f60c2f80f9a51b3795f3d2518b11aaeaf6dd45a323794080b78f85d629e5fa719b6ab0b14c78cd908befeaef0dbfaa08cec9318bbcb376d48b11b68735c9554a45293db5e9239ae1 0016e6750245a88340b0f0665b890459f8038e9b1366f2fc1326245a88d4c523ec94429f21869ce3dbf75126e58f77241c99efaa a7b42d0c6789a7b07fa3923711d85f0bb252f9ca7d7d26ddf2d3615abaf56727bd40c4ce83f957717d084b94b8afbdf6 +b898d0f9bd80e083fa541f457d14d853bba55b120424a95e1d9511c8833f48444329e0349d68204c4b4581ef1c4dee23ed0a4445727a72e1e6cde422f7c10ae132a3fe681f9d741fda263e73f7cdf10759467c9d76164086abf6780ad474772771eee22d195339bb8f6235e0d992bbe282b13ce4fe01417f507a2c4fa155e108 00788fabdafeebb72f6385301e30024b56639e629a400f9c50d402cfc9b5817844f06a451fbda29c7ece41dc9ffcfc625fe0ff0a ac47fe497f0085495b9749b6da0af4a1ca695e0f408d95f1e402749839cca5acaa255243dffe6f4faca3b748d80f76ed +dbe04561ea8579672a2b3afa94426a3cbc274b55263989d41a778bcb082da797d84d930ca847a481789524940701cd5f1d11b460bdac0bffb0b3a3abe1ab689c519700de85a0a571494ba0cfc3c865450eba7a9e916b7fa9df55e8a1c246c992e6a0b44b78274e008472bed8d8411633e6520e1a906c5d0c8aafd572fe6f1f64 001b8dfd64563dc219d6eeb53f2e3ad1d771140d0960b211dc1f757af5e297dc7548d6133ddb574711d466688f80dbd65a7bbcdc a75278772120c5ad66c563c6ed5637abaced3f1a5e30f5a1c600f819bd6c88a348f78e0325c63a16b8a410306054ad8c +48a8300820fea2ad83c83f7d6b24192715329c3f159d56644e11ed25efcbd3d31600a813b909812987b97d1087e74a63b4494cc031c63492b6615e9d6e5b36f62cb2ef88b9f736595800de465789f43811165a5fc093ee6d776008739de8de2a84e878748641be8bd52e5b891c4145f52bbd46644852a43108e93d86352b2a3c 00422131829608ff730c24ddf7e8b4a2600eaa9681eaf45432daa7d41fe2fb488fd0199d431a1ed823801ce21f4f01a4dd4248ca 987ac9ceb35e82d1b6d5dd8f473063d210fdfbe5cda8870164d2aebd01efe63998de980f69752ea9ca5de18f4e2ef62b +276e3a986ce33256014aaa3e55cc1f4c75fe831746b342eadb017676b0cba7c353b3a2b554522c12e6aeaf1364cd2eb765a404b3d0aa61258194a30219d76d2bfa98ad20e7e91756cf65e50d7914157f283f2ba3930c0ad3a97532cc747b1cb9c806fff497f0322025a3d02ff407fc7b5808585b91d95523c9d5864efdf7d983 00095ae8e4c7e55eb5da01acc05ecfe72a4dcd8ec152f1c8dc165014f70eb4e4a7861aeb2b96c418b2d4db58659e76184e013a49 b2caa13ef3804838be87904af6032ff7dec52637e9764a21d2e8fde89429f4acf71dee2abc85acf5b287db9e49f52159 +6a4fc1827c3a7256faa8ec6a0f3d23559d6949f8cc20e7f76111dc4ebd59213951cbf0eadacaeb8862d6baa0cb298645e4314b1c303bd0d5e9893304d4b7fbd36ab05fb6a5edc3fef763e3a4124d61539eb616b359c5cb55b5e2bec50c91dd95fc39ddf521aa854216eb5a707819fa6f067b316a17a3b146e7cc2dd517f7d63f 0006f2075bd730f34df111ebda919167b1d3358ada32cd6747cb3353bcfb814a77ac70cd51b31a0e538539453bf9eaf9d8b384c9 8ca29ff95e96a218e6d95f629a9e9070f80e3a418f0d16eb0f20c36476737e62e22d6053af20e9ab220bfee46e0f42d3 +4b088199bd8c94775d8ee508377d672dbf50f6d2c7370e99821ec8f9387492fb2eebdbea473ea18465565f79e2af418555f10c4a527e05a9e20c9c00b807dc8b350cd4ccc2d87e91f66addf02ce4f43597aa258ac6fbe9365cc2c8e8bbe5c884abc929710e8423cd6722a8f473bb55804159a92a3d8b6661a536b4fb9293bb0a 003887d284e9ad17d38bc6da9d83c192a434c509340a7f233cebb032b09ab7c4c6e8730b4a80844898616c9abcd16b753c6bb4c5 85aa0d0de1faf45096f97a983227832de17ae91097c90330c2451089e50c9bcd8f520e5aede1fdcf1c9f92a95e165988 +848a13465ddcfb2dc14f7bc0db0756832c22dde1e31e4d8b3ae0dd1aafbdf15e954889e95d3bdfd6e5ebb6171fad62592c23277a89e8ba53978c9b1afedfef7e1c3f6d9f31077530460b47834b30bbd84a4da601be988738aa815d3d7e72043243a5288751ee08b4815a017fb5d9bd55833698a0d526b1ed79da35ef0fac93da 002ea5430610864257c9dc393c3addcd0d8d5bc8aab1067643b08857210464428aa85cf1ae6c743fd2682255d4c8eaa46ca21e73 8b3670c98ca40ade5ac84af4493e1ff83df99c52d2f4d5ac7b4d8034c156e5f6182e89ad94d2c12cd290c4b0b0585c51 +d1850545c04ea65528849973c220205c35eae98826d169348970d1420b4d872ce233af1daa9e62f6a562544ae3a0633a954a493e9766dd5d87e47486559fdf86229a7c9e1726de21895abdcf2422d438f4ad98d88b45c56742694ad5e11894253270997c049f0f419842482f21c792fbe5613e2defecd485585f1835b6f4c578 0062c757c92eaef41f5d81169ec4968145b5aa2bc1d2a3a5fd000634777748ecb93677b3da12e3be33272a8f0a52300f4a5a37c4 8d97aa3676cb1cbc6fba482210f32cce6eb472d0bc1b34c82f10521ba92aa838f4979ddeeef287cd053ef879fdcf2459 +421c9784d6fd507c82904e1054edf9bdd1efb58a0b211340086069ad38b7b0dd15c2345fa8767ef71254ed1bd5c35f742b1d3f4765ff9007a5477ba9e5d3d5a5cb5fab4efc1cad73701d4776c6c4343f42b5d94a9eb78ae428dfe5fbdd8e6ece09d5b75cf4346cf27db856352225ab04e6ea56661554fbc39916accebecb3935 0048a313c0c11489939fc0cffc6ccb9f179093c4e13141b92dbbaac441b7ae878c9d412066e95615174a24692555cbbe904a14cf a24e403896338bd529982c1b4e99236dbb2b767d9af73940e9b10adf3e00f5e77e3480d4355aab4d6bf40b5361a684bd +7910bab15b6429947655e33a67f41b76f1d7b71534f8904d6a0472c2faded038565272d0b5f51aa915e0d624e9ff48d50ebfa2f09324864f26c29ab73eb39b436c5c459c7cff4d2b62992e3489cb4ddfc05d7366b161a463aa1b782641d93507de43c8cd0a0a0a9d1c644f4554e3edaf7fd794248110ca9387e73ae5d00d299e 0046e2adfe5d3549e1e6fa1fe69a7cbb4ac9b111c8903d544268f8318b0b47d4b78fe3e56eb5e639ad5382e7cd5bd4b2c3e70ef6 893d1d005a34df5a97d40a0b8c679dc5f5e3f25d6b28fb271b99711590afd2f3423a03995d2bb954c187635c227c7467 +e6fc96e060b956c25d50ad25443f3c30a12d199a47451a49ce88307201dfb15ed816982e8888a28daa92eaf3c5584ca6ab2ca9e14577f84396de2e0ac214b24a2279f5e7b344fb7387e9afc8f0a2b77a4d024a20ce6183499b17096947444bbb753d9b39e5c694239d28f9c454bb05468d17ab564ee6cea3741747ccb7f108af 00480103fd6180a431c837643566706e2b9597de0a1346a224d176a5b2c54aa4d064418ed654a5d39f4773fb509f86473ebb373f 874f9f9091ba7fa692b2eea9831f5dcd8d807e2a9a19f846cafc482170886e2652af5ca17c5620ca1db5d973b0e377a0 +c8a8a0d41f35537e6fd523ee099eb45e1ad6ab54bed4d3e315e20227db03292e39dc1a91bab439c0d20e36e7fea6ef08983f390a6b5551ac3b4f1895220b2867fab95552cef9bd8702962839bd9b2c72772640e7d3be3c5889d226acbefdcb448432bc503e5a5fe7ae9ae7696c720a799f9882c64ae0385f656074dd8a6821f5 0013c489e8311c6bef02c8f58903b2ba2a98a27cb935d75a30d320af9a14fa3cbc6adcce09235a9eaf333dd05f4b2f1694985dc4 80b44ea6f6132126d93c899e6f3d8f0fb37cb2e9f42687325cb2cf520d338751f4c0af999c1ee9825fdda9de89d76f9f +3407cd6d2845197cd7414a30fc3df7184da204222ffd65c4d16a12cadabf603de8043ea14f5e6ddcc22d3572dc06dec1a23cd924e1847ae285ecf01754e2d1247876431eb98e897e47412a2330bb32990f9714122109e94b38f82cfdbbf2eeb4c6f88f5dbf9f0ccb47939df8be321dcd9bfd9bb99cac9f94885fee7d443fbd87 002419bd2200f8e1d87db848b0379741685e680d9affe693eed49d82931030b6cb05d21a4965f4e1df2045c8513a8f574ca9f2e7 99d2b9d0c967f4cbf8c29f4484ef8d28050fdd851453c9761b7e64c6b644faa3dd6bcbfe270eee899b2126a5ff302fe8 +ad43f8440071285d01fd79244907803601aff4bc5d14c77483a87cd742144d41c68269d76c9a83c09d2178bbcbdf99f927b378497ffdc907a75a3b0ad019e69758dfffa480871eb6e1e17c8539373de611a557fad120d0bd147f8debe5f09a02e56fb607e9c1253ed592071f042e42fee39775b407225a2b86a950d81bb7d7ef 00722951879a65bfcb414e11712ee9431eeb32319e0ff28601112f89276ffc2b96eb65c7fd77d023f09914a53e2aae2c84652bad afeb2db5344bf675a2a92a1d191b99d20d1a9a2245e540aed92ca4db8503851fdd859c6ccf21b7827467a633f6893640 +d61a3765229dcd0b4fa6c57280f851ec2bd54d3ee2436935cd6d94e0120d0844adda163995fbc4cd9d7275da859ad8ebf30af9efbdcfc31c7c9ef42bce9011d37cf9d15fb018e117bbc102f7d05750e5072f73d02c2f45509a55627a78cbd9082cbf36807759d1fe2ecbb92ab30cf28434941712d38bdd100955d611987b5968 003f5b5a772d24bd5454bf26759dbd433fcc7bae4f5c593664c4d75da0cdf9430d7d9162bce3d7f6e13a344259da5a7d6a1635bb 87300d9c0e64a64cdf1984434575cc406a61c74a28559bbb75e369c04400875c66f1e568f69072e974c77890e37e6565 +1f3c23636414ced48fab6763eed5b22537968e6bf08c178b3d31fb1f6ea773c6979759701d94bc1bee7c354272811edec58eff50c93331b22723d460e56dbee90466b894354777b23b13a37d15a84c762caca70c01518bf34d0c2f072145d274b3b6c932b48bd815fe81161d8507ffbc2f783bd212c29b2887af6d2ffa9d2b4d 0046bb4a141c9099d531dd23ac440eff1f5b10f7cf34920b6b702311d490d25344c665ed5211d401def24986c8094165d10f8934 a011a77ea37521925f00d172e9156f2d7fa668ef82046fc5e5013f08d125a2bd4cab2cb65e8d7f77f069c483390df52b +ec69f2937ec793aaa3486d59d0c960ee50f640a9ce98a3becffc12d6a6c1c6c2f255d37d29f9b4d068373a96beadac98fd5203a9f229bfc70bcd449640165ae5128e3f8d057769e28356e73e35d8e9af7876f608390090892c67391ddfcc1c332aa61efbf72d54bc615998b3be8ab0a9d372784bea48c9fab244482c75cb2de3 006f2c6e9ea8109223d9a349fce14927618fc4fa95e05ecf9aba1546619eaeaca7b5815cc07e97ae8cd1e9973ac603f84d838393 a8b99b70a5ebb52d85033e533410f5f4dc135dc722caa6fe101436a3d6b0ba883b0964f9c3b762d31655407b70daf5cd +70e11efc78d7f079ae41ac3c31c96d3220f4abfe23814a2a4a78d9b1a25e838c3408bd416062e4b0a5cdadf0c6e16a11e00f59711b417751f5e4b43ecad99efbdb2a81c91a034e89edc94eb552c3eba62808563cdf64453a1db07daff8742aea4a9fa738e1322da316b26dbca2954b2bc0de6da7518d28e6677dec6ba8af4285 0004212b7fd913d794fc6bb33e0276e349c052c969ecbf6afc89b28f75a599a9242acf74dec9f374361ba296ba42a38407f9b7d6 89952a04d68599bb38acd3e16832635e7f0232535ad7c4bf81e903757583055387f928e34f12e4b63a6631719d01228e +d922fa515e3bed60b517a2d37cafe4c041e5ab4b5c8d8d4011bf9fc4013dd8abf7add71fcfde5e71d6abe76bd0f749e960cbed55711c87b5629a2c39cff48ed7d0feaf5cc4765e576a4959521f9a45fcba0dc65ae618826447e02ce6e1cab5ce8d6c96c3211adbb0660de7df7453f3aa726016941d00d8ee536cc106a603d126 006baeebb5ffc89c94c3e8b37b9b0904e7c4b251d204894655bf3b1235710215c29820b9d401c9ca7df1404d2d62d708aafe208a 8232109b16caa0e4936be800be566cc9e1f56e82c5b12f20f3cba93fe13af02858fa1075d8454bbf31c96ea7084df803 +4f64d0f6bfc542a0d4347576935bd68ca88524ead03b8d2c494061d0658e6c3e14576b5bcea5f2f992f54cfb52b5c7cf1dfc517205e0454510eef1b7054a8cd06ab53ed2468193f98ff0dd62faf076549ab2a270f259276d5729996c120792c6f466a74ab65035bf38ff2c055b43e2a8b8e2449a2375ddbfc18242157bd905f8 0008e5f66ba53e7caad1feda122a80c32c82d2c32a7237b8ee8ead44ea8f2f01d77c7056b9dd60b92d051f060da8532c1fd0e8f4 a939fa56e1c7fdc65f4be460c1dcaabb0ffd009c44f118f4c21f89ba28fb02c6a3113a496bd58474d6d565c967b57314 +7047d478ec5282d55db8c19c97af10951982d908c759ff590f27d57e2664f08d526cbb2bfde39bdbb1aa3dca5a8d3feb50b868be6651f197abccc9d8040b623de367e2ea1d20ecd302afb9e273f4be9f3f64f2c2eb3f92d5e0e375db6549da2a589f0604bc7146562ccefd15995a7c4208f640e7a17afbca69cda4e173380523 004ecb22b44e809f89b16abb10be062c89b41ee34e110403e42a20ce59a99afdc22f6f6dda56e1d9d1b8ce1d057f390db111def3 85506193e3827988bb7981cf266139653b9abd503d8c8ebe3a73180b5aef7166abbea018e4a08c977c88fcfc2b7f92f9 +1a8384b4771a410663e56eb36c5d9ede8d161a8fb0e31d3f74bcb017b9e31232bb2e2f4c65a2d85bcd1cedd93ef08d4bb4af0095731574ab3f2762788a1ba3bf0ee46684da8d9dd384432fee99ed3c69213d790a5d81b351063eaf2bda71ca4868ac36be1b571024a8bf09039b347fa996d5d161078314e24b7d073e05cb3d48 0051f9500c15ae73d6d479b9f3d2caccc2039d8d03820befc2aae3bbaf65d59bd9cb3c4e3aa8bed5b3acb70a5566047ffad80729 a69b7cdb0abff7e8386a5ecda8a7c0bc478791f6ef2a1782d5600da20be486ceb5f3cc9dc2b392caa0678831a1cd440c +43513d6dd8bb0af7a6f5a2b35f99957d335a48d54f2c4019ce9518b35441d4935518976ab1df37110b5b53532cd9e2c66d9f87ae7f683d7efdbe1775a6c15eecee84c6f879999d0706f6779dc158c111fe8d7201983883bc8334f51dec60004eb1087347bfdab20f8f2f260556681e05fdbb8a6139857fd3bb2df5bc1f2dc143 000cf01dc4462cca764f4f8cbef48c51980737b9b98d1384b8de9f4c733829db7718a9b5eaa46a8475c2144fe4454cb8eeb0a443 989ac0d413a2ccde71885b1e2388d2d473f8b1332df2d2414d1beb7808ea32132341a3048c808f0a44e397228b791db4 +752300bc5066d0efaf807183a41725e349907b7339d77c79921ead3c685b616b0eb97e708f3880fce0136c510c8cb53b22cb424af6f1c34633600939a0647c02d8f9601f9416f1d24a51657241fb559c25dfba91402cea43bca1a13718b3945b048725f3df560e6717cfc6ebd894e29bff1e0c7763f15b8ea93e67385f059598 0063a9a565497974c6dd459bea0d1196d74f263f333c31b7e8591499960e1cd79e2ef4cc8709f6d54713f873b16e7b0be42f71c8 90f0e3996182b348fe0bf3d2a8a5c822d93dd9380585bda69532fcff9821b63d744e16679425b841bcbbbbe66176b6eb +f620603489944769c02e2f902c2299dd5f32b5fb463c841b7e1fc0249a85d2c31684bd3daacd97de8291c5d39e84d6e59d3dde1b30c181bfe8d31b8d8e080bd191690a67fa00024ac8c1b10981b40d4f88789ecc58fc69b15417fff34834e23453bb9933a43d08afab74d056f366b40ad167b51ee5f008db151a12b467d3eaa2 0041074dc186193d30aac7cc6d269b938ab40b257d095e54ba79967a377a91b8f73671470cd07f0a3d1db7cf0a31ba9070625e43 b5bcc45f493ffe3666b3a4afcb740a308cd39140141d9a34e00c9463fd24020b3366e6ad20fd60db71481e1eb141e9b1 +5575f610762b42ce4e98d7bcf45a7a6a0d66ec7f27d6b8b17f1961249d905bc7e58e2ce0806d467f106b16285dce4544c72666d08b5e2276cd0c4e13187cbda8aecf57b1855afedf8fad39ee4fe009f204e60bdbec79b123456ec2d85631d382b8a2f2c7634af3992e4707f7b4215e2c9d3b0aa8fb08267953883a4213669d33 0010820db54ccf0226161aeaee79cfd2797f87702b4ee91adf8543b3c9e79579d0df8a889e366ec1e0718e039b87a37c24d620e9 a4f54303bd1b143232a8683ca1a228c5eb5e7a4416822e1f892998db1cc3db33b5ff4b5bda84e3f96d25cde0f414966d +81cf067411dde2d0ab04fe5fa1e28e6975cdcc571588de60a35bd956a535fbbda4affd0803d244f3f7e6902a2c9a7ef2488691b6bef7f8ffb33be09ccae4c5285265e4957f7928ea5cbabd6823297f59a7cfc9939a49f26bde74c4c69e2d38c1efbacbcfdef011213843158072be84ed3c1781f67a0e2d4e9ba76a585c17fc0a 0059d2a06e8bfd5e14a9bc8777958b85be5e97af892d2cdeb0ecbd2d5017952b5042349db5fedba2e26e7b85bbb31ad313d99434 8909c3a7473e7871e43be1bbb2044de3d29b67fca98ceff05d0b4f749fdacbf81bde732b20d503507453c0f5af08107f +8ea18387940035cff2f37278d321b344231075db43c7fa7fee9bd3fdefe5e8f03e7af9deafa1022eb108e19ec11fae34536a4fbac2e8c8139a081a997c080cbe8f3e2d2a72ff26edcc5338b21372fa1498e439e4d9bb12d51cc539f859047957b1b1f1fc30b90231eb06b365a4d404a1fd5a0e5cef171fc95b04d0b557d78ebf 00405590893cbbe18f4ad99df28b5f9d17f8f1882269aff0b7eee9392859d68927a99c942a3075269ddec6d69c0df2d76ab9d801 80a54180ad965af6011221d7978739c450eb192826c42c8d889b9c4bfd39847d0b55f14719eba2edebd1122196be746c +6a253c1aa17b2b1e6624afc8e7456d366ef5b1bd78e740538260f395481148a64da0b6a58cd53d7e06c691beae1a616547cd95c4d259a371e51c2c0e334c8a5311ae31e4c7af325686ff9f7a36f731010ee1a9b8a29169ceac36a060dd23611dc9713c615424888bb574ad5f5755d7311bd169336ae986c977a394bf16487c4e 0062bbb4f565aa0f23b88ab9029d33b995729d10fcfc33ba7c4051e2fbc72f15636a834e3ebfe604b927cdfc89f53c57f36890db a89a45f40f41fd44ec610c41641b2dc3c71e0d5478536f0d28ea733f1e449e43000735b46708f48c2ecebeebf316c145 +0f91d0f0139faf3b90a3d4bebd7e96ff6bb6f90f6c68321fb392637d8ab2a60d649a7b7364ee6e4e274e1a8d342caee36cc11c56c54247fb0a8e8ef81ac4322b454dc9a195dc54567bf47ec8d4fa4cd32e76d78ea2d08bcbce3edbb68fd8597e56d5a9f2df4e47b2701046df89615961db601bd8204584a6a6cfbb627e2a1190 003fad7031cf8810544a3e4bd1382c0a2e22c5a9fe4804ce67b27591fc516ee81dbac841d399327168aa6abd79e2b5ef85df1528 90397be7c37797995aea5db88503ebb295941955891cb860de78a6d28591729792e8f10701284a9e7cc150af617a98de +50c17c1fe4dc84648e5c3c3ab8f7c971d4c58d8d56d2b5ddd92e35e6792111ed8dac7644ac8a07ca8bb4e38e071aa47b22ffe495e9083f9bf781ac1b5fba571862c909c7aaa7b8d05ddfb7ef61c99700de734d5658f44ae9fc908c85a2dac8e7f854d6d24be805fcd7f873a91252985c5c73129c60177ba8fd99daa87b25a073 003db41b4f637fe7977c90e4f1a21799baaddd1826c667102414877138436cfae1b9959842b8097b5276f15f2b982ee59df263c8 b96e348df235dec31921538c24dc7e50e2db16c7568ea43cf088559275e08d068151b442cdb0d3342df128ac6a915221 +3583a3226e2dc463a462fefa97024e6e969c1b13bdc1d228e2d7823d9f7c09012390c2535baf086588000e908309090daac6e6d2b06d2ede6fae838ed47f30b5b481185f607a3586f6dea47c8f84e9d3b96d5b0ebae2462fde1e49d84d36658e87dccf5e30c0937feefd8862dcdb1a1ca373f6ae41641502ac54df6633a8cec1 0065b76c6093d9c49591293471286df1a4444e60d9d06cfa114e175afb5f119d2abeb273b0596019a0ec5db5b5869f2cc827b364 84f2f3493f17eff72f8b6e4d2d480ecde25a8a693d38cea235379866911aa7d4b445854cf2ad9f08281d54636f0ae0ba +60ca58462d53d074b370127132f4e59f5eb8d15594dc721a94286afd082a8934e52462c9c1c3910f8b50d7aa3671dafa5972958d876d7992467b2fee3795a6f9d8a7bd3003a8582ea8c003aa1e02c08ab6804d85bcfa13a815d75c938671f0af0706c68bc70a6155708ca755cac2fbb68b2952208d63e0e2e3d816f04c61bc03 007e9993f3fc1fdc4c376ef77ecded96006ac1159740bd1b2dc6ae3d97e15a67383f1fc931e460b9af3fe14a54e47919667ed06c a27810e910f6a37d5a38367899335fe4daffb693d2102aa42cf551a56646132ef42c25ee0231897cfb435a91d1275f06 +c749f9bb92ca9957ca6d0124206ebf65e860ff38a225e241950bf4526cef3f4fa9184ec83f71f813fe852dc08eca6b45b14fc7f2c6a19296529bfda007efe9d0d26492de2a902b45ed39603e22f0a763dfa5deadd97ef6feb859d860baa2cfd1d066c0be0f9f4e0e2fafa69cc51b12e814ad2e33b0acc0bcbe1df8cf018dcd4f 000c11e2979498695c660a2bdfd105b115bc4ff8664ea15cfb40c725406c6fc9a13027bd1d72ffff6258f29e4e19b845243444a7 abeb2285b0103e1cefe709ee3a1554c935184c7cf1e8fa589db7c3542a5a776b4f2ce65ce15162be3284068dc765c484 +4de8414780ea20f7943b1f1adae5e3962d96e828fee43bdbf2831bd71bd25df2976a3be37a7a667c7fbe1200de578920090d131a750c9bc09bd95b261234ea8cc25423c4ddfff5656d6b32da6e2f6f530e6673a8660aeca31273bb9a3a21bbd7031a2fa71ba37c004d3d1c64b2c0798783e47b2efe1a208959ac16e35d444245 0068dfc23c6635bd1fa1076dcbd456ad6e8df7ce7c1370fe275803befc4ffad007fd062a61cf1d50b93aeb9afe1aab47a65af82a 91432418f3d9e6a3bab1f4caf9e795be7d81bb0083d345e0000e958a69fe0886be13968ba6babebe9d4aab679758b9ef +a081d54232f84bb19dbd52ec3812748e2e6486f6cf1b177b27929504ca878036547eb43531bb5b3edc81bfe105370427e92831d2239cca0106d031d9fa8da9cf89c6fb6401377d5936b6329ccad854e5567181b8f16a37c35f333eaa0ffe91d727d183fbab935fdac2d5670dafb3fba59e4fa2df1746c58dd8360fa08af7f4e6 0040807fb888e1d9fd33604546656a493629d94d4a0a9de2608962225ed158167f9e2438abe2d12a11e2adb6c2b66ed78215b0b1 8a244fa674408568e9ef784dae576138ed2fb6c910c537b4c6833be8403c4b09fec84d46d793d1f88445f90fb7212e32 +ea60266f1538565b3ff42fa4bbfe319be070329059c52c8bc04a7da2824f209c1145a05e551ea59ded8ca8439c328f6907da4e81d658937df614be98c7b8648818ea80ef40e49aaa4431f4a211d62acf2611f5d60c446b2b25745078c643859be1b12b3141a09ab765dd63ea1f2a2df015eca0840087a5db378c4c4cce76cba7 0033bda0a02badae08fe40c239b9d59e5bfe1c4d4b9b7a5acda6790bfd77ad08dde5e93a2da80ec54a7f88146d72218bbb88aa10 8505d10fe9e936851f04c6c58ca9ec5650582bb8756ef03c5462d064a7acd8816a76bb9a67340c7ce1c7fb1f8be0b230 +82f38c9405ef0d26bcdd5b3fce4fb0060c3095f61403418e17c337933f0563c03691fabd32ab5e896c593439e7492a9970ae325c67196d9e83fe0f9780409a930326f7e6efae035ef8c321cb9ad12461edd5cde66c04739fe079db65406b3c2d22f2d04b1a4335285513d4ceb901d2ca2ad10c508302266c2cd6079ff14eff4b 004ff431769d26b8837d3e1295f5464fe82be29edefba76323e92078a6483ea0daa96221549102509a1bdcfd46a5a2e5de10c39f b4aec735d000e52ede1a01216b5cd029f4ecaf8bf1531428326ee45a50886cee9f37ee5c369eaf5fa4e1726fec7d2d42 +d8506fab4f681ba4ae86066aed447571eba4fe04e6585fe3be6af2ab1000a3da68c5b0c711a85ddf3a40cb7c8944eef81f2094650459e14f5b848e6add7e580b0198070f873eb3ed5d0728eabd92bc1398764b94cbb4cdd7cc2027b9762dd10782658cd9e8a5022ac062fec535d892198c8a387b3d2b6f7c92b1af6ab7dd9e4a 003f85ca1169ca7e9df44cbc6bc7d2868c9d94e8f8b699a42ca492dca0914eb5789a9032218dcef7f95f959c9554a1cd83360439 a688623028595a26a0ddaa3cc6ef6db3c18d29cc743354727fc60cc239b5df8ee751b93af08bc5e703c1e4ec780fb631 +b3f30d34f252a4c26f396079e773142bf61c0981d912333ade3de4e27cbc72cd8a16b31807f0c46116f87accb854487d83ec8c6a61565e6fca145eab70048245db08616779d7047db63aabd90dd15acbb05eaa510072c151c0518f1b34582b95f43ec7b9484b2993c176de79e84566764467f72392ef31619426d159c91816d4 003a97deb36d68f81f50c8829d412ee5de7f9d775633cb69c09dac558182039e275fc258240517a7c4aa592e364765321f27cb12 8337941920bdeed2c7029eefa105765c2a3d67c53683fd0c19051b524e830efdc95c3afdff1d2fe10f0353d26253aa1f +0fb13b7c09467ad203852738eda5ddd25b17d330e82c279630b0e1f0c86681f67f6e537fb00da9419114973c8559306de58b0387d86e52d821d982a60769d2f15fd5ac2ee6dc55d8ac04ee247282cb2866b8cb8b4d7b4b6cfb33bfefdff09a73d727193e5fb939ff66ac5fcb644a44f9083a790888cc538c5eb435243c6a34a8 003b1da0ffed24e1a3b5ba22bd684337f6b08053591620541bdad50c761d66201a2cf21a4cc636426456525b598e96baf97d9851 b1e38920e44556fe0e98b76496d657e2be60cbd67cd889b1314f224107c6755e50ec471873fca54c58005dd1a532f679 +f9b8124281628cf4e1da0cb4f021c8d19d815644cd80c7c8de4cc62722904ec4cddd26cc4891f30b15098a25ba6923c6abf4774deb6e1883fbb409862f94467e75a725e7154be860fd58347577c83adbf18535c54b102220197afa062cc1c84f6094490ce488af4a08d2c5b808a2572e18a59de96c87162f88413795351cedc1 0040bac7e0d3b54c7753c79d43469e310d876015d948fac4e3a9765444754476af72330e88d79ee6119697aafac8435ab5690754 b5b1d724f378a0c8d5170fd801df5417d3a341f10d6b1d288d38b13a07801e9359a2d37a07e599fc2e7fc4fcf514aece +4e3cd6100520db050af0daa69fe3cfe6603a223d4f2a6318fc5836db8640d4c7fb80bb781302036d2d6fb8e552b4eaef3133b98ba2d36b9ef0b86243b0391413c73d48ecbf1d19170f1b3b781b35ffd316afb1d55d1dda8e91eed5553780cb2714a93e7ece698b832e853e2589c5ba2b8a997bbbbf625071ded66762af8cad42 0025b7eb3bdefba3c5134438caf968f615b315204f348006f82e8d61057a8a8a853230cf0500f9d0b8c1551a59b9184862dd2ed9 a1b0cab0a60b949ccde4476f20d18c403fe4e04f6e080aadc9b017092c5ff4c199888d89c333efe5fbd875903d4e667c +5411708381a65bef4381c9e13a04cdd5ba0c15829f7f25ccadf695f635384d8e4704cb562741747831b33852567f42fedbd190d2980f1bc921ce01c17d659d4bdd7eb787b3927fcee659dd3b65132496c687f2249272a473d46326e66b3cb78dafbb522390162c168f73bdec88adb145e6afecd561979846ea4c8cee38dc1686 00673b3a2985c95904732632e5d988d8d437a60db13215bb6aa880b348f011c609a1e860461427a8cf0d622abc47f910f5c97ffa 868ec6bfdef04644b073ad977b2161ea2a9ef9de5ef608f726b9febcaf729bca40ebc97cd733e0a1b89be1fefece923f +23757fa60fcabf543e603d8b31ef0cc99b3ed16b4816a84e01dbfc858872fcb79fd03d2f8a1d4f28c25dc42a39e20c34f81ebccda1682ee9bd22fe323e7f8ea90cf4a2a6ebb634cd1153cdc35f7306f28a2efd822bf23131baa1543d0ed5ab4c8168d3199983fbee117085f90550ec3ffa2b06070d3add1d707fc2593285ff58 000db7dcac414010b816236cad584dabeaec1da76c97182d1b62f87bb7fe2946a64d10430571b2b29ccf2ef72c969a9f045f1f3b b6293373d05b04f53bb5e93421f98b256f8b0b3c51912a4b1f2b9a85aa66f961297cc0cbd8b4ffbc276c463182759e3a +b976314d2f066f8893307a726f450dcf2cf865c170e90e6908ce9787eec48e1e2119a731b2bec3c12fd4e6282a393774251bcaef91af6ce57c63a8b45bedd72ab862cd169b7c84b8f6a72084ff823a96f2f8eff3483a7ebfabdabf0998377c5a6836d88135cf61c65a0ca7ca57727da68047dc635c17ad13731035fe9a6402af 004717efef16e1ae267e155aa1daabafc68515aa391dfeb73c13d01f3132bd22c984228dddc4dff4c39979e7585acd3f730cfcfa aadaa420c004212cc92dd4cde69fed748cf8563a84e66f33f4cf66551c57f6de6b8de8c07779e6b4f8588c63a343e2cb diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K409_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K409_blst new file mode 100644 index 000000000000..8ca45775a723 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K409_blst @@ -0,0 +1,60 @@ +f153cc61981a46d8a47d17d29ec157fa93fcf644beb84558db7c99c57fb131dcbc5b65581ced5ff0b29bfdc66ff703ecdd4290f7c353c02a3e6d6867f33f3dccd1a0b6752b8a35fa143f8921a5078af9c85b212564c5b795da9858c7955095938fcd10c21e35e1abe905e84c8b4bc05f2a06091ce876d9519b96951d08c7ac9e 0011c6528939672bed3e8c905b7ba594c3ce95f37fb28044f210cccd01dfdb42c10e8e1a0b5d6fc757834ca7f08e98cbc52b0edd b0e31731bc5695eb25068a32719d0e1ff175df50f14bc760c9225e2163ba45ca788bb6fe005fb5d66612ca49915a9856 +258c91524423b5c876432b1930c7b07b56eb5e3945f1e2296a4e5bfb9b9123f800ad195d6104641b1f1970bca553c2032f83d17252e52403a9381c1fc18eaffdf026f7537aa27d84c5e3d6e39e651a92a41139cec5181fe794457f556b390943093be719acd23fa1ddf7ff0aaf0479484a381a309b4f681af74bf97caef08c22 007e3b714496dd118d8f3f597961eec5c43d0265bf85723b0b9b0616977e0acc2cf686cb6afa6cdc19114e27ab000e762dfe467b 9907fe35d9a610d0cbdc28ec2acf428cd6c03f0845748476457cccc32c2442a4d101512072cb2596ae8aab203d0d303c +a16a0d6fd57240fe88c7c36b9f7f9040cfcaa9afc4beeb8300818c5f90cce73b819a12c31d42af33146399cdfa4ed4954d068dbb0f1f342269dd29f1fe357e7224304b67b0f924b794780fe7e6aa9dfa3380252fe7177b43e7b1789718949b9ec1b943c83ed4399491482f0f59d2cb8050ab6f8b5854d76c50651428cd29c40a 00182d1e937b037bf7f84144f7d4c94c935269c9aae7d500aa459a7a0ec113b232dcf282908eee4c84b8106cd38cdc41db3f89e1 b50948a52d34f2d66512dfa8c46557b1f63ee52965a7941a5c63fb458ea48216b9a670db84db649843cc90e77c64c521 +d02ff569828fd1add21f6bd1c50cbdcd09222e458ee79fd5dfdba3cbb84e9d926fcf196cccedece77d5aa17f8c8cbf3a9facf0f02c71d5c1c8aeda9d75f6fd7b6f2c5c70dff992ef6e02c438fb3c66da5a503b3c39acbe2a069da457595b542190d818015d462670b0807c401e36b1bfe05baff3a8ccf8d1f5f8de7840e87993 007ed09428f460724c8a5225a31151e031d9949493fff5703369c401762345d002c4ce424294baab22d9e71edc4f854510cf0e6a 88d7988b8afad175b306bc73cd8be08f97aaaece35f14fc71b734e5c022cba210d241b8fc1a0ef2c71403823c165f805 +57befce973b225cfce7f996fa5a1a43acd160681b88a87b7de04544eb7b6a719718f1ca7f559b6531bfc18fca3836d2be7f7a6e48387b7579a6845796d30e46f0dda9d82680f8c96c5f0989741adef9762c3db763cae2699cb6c112543635e20ed5cfb4b55ca2ccb32d2d13936085a8ff95ed658a54be73f80c912ccfe5f0ca0 00390f05b9619c27b800e99aeaf61ef7f6249367d5cfaeae3c7b523a8b29153eb8a77132f6c4412545a842d6deb7b7aea7e2bda5 8d15d4479021c4979b0ca520b5c6d6eed7410702683e251444662d2d9e0281126d1c9d4a3339edb525782237f832a0fe +4277ba40cb462860ca722cb4ee71c61836d2ceba18bc91f3fad7dea478972c6da0ebc02815eaaada1d1a5e93d7ab353855ccfdfc94a5742fe18daee2328871e06c1ab0a9a989d1239df2d2d27f96c415e7ef9a941f06c6790675361173cc229aac7045f49eaca207f59c497619ba32e932b5c1c6576812ee5b146e2cc7de5e62 0007d18652732596add3db31f7a0ce6020d03f3df58131b0c7c633faf619b8210cd309d6c0c4083aef1a1b6d2a756adad0bfe344 86173fa2ab149febfe41cc615e28b126f64a00f2b270e0c492a9ef79b04a4eceb8a22c97514a8b33031fd5328679572e +57ff6792ed4b12220d179bc0ea57ff217f322c85bd3676a681d32d7e4a3e0c8e891fd267df17caba5992f68c35ff670b60b4bbdfff82404f6ed996c30539bc395120f97d4d7a652eaee82bd8f9360bf8bb73748b8bbda9f9480eb54f7eaf2609d4259329e8a5ea020521e7dbd3ec56f23c849932cbdf2875f5d5c774a9d6b0c9 002a91244ea4623b63403dba807d60b914ca3b901a2523244c322f2f11251446d3f15e869d086ebecfa1a39ce304e8b5c8de23e2 b6e94b652c064a5c9c3334d35832380bc655ac56d00e459498de0e8f4787a6cc4036523bc94d19efbab4e58b0ff7213a +f85113eda64478f460b60f8084220134933de049200a5f37884da7901471542e26690a5fabc3cbf9e679ade71b6e54d869bc136c3d34cc4a9efcafb777abf046b5ae5429136112a9a36a475121eb1f33f1f43481286fc1ada98a41064a1fa38c89e99a93065bb2a119348a9e452497fd5a0d2b83a66b09da9f47a0583732adf4 00068c56c6b5d50d1d4e13d3837d8c5e8ba2f825e121b63e97603fdfe78bb6899600ff0dc87b6b3b6868ad0d2f62b7b7a31603ff aaee56c898f9888da7d4e8e90fd24675630cc125830c039e10ef12daa419326613f7bd08a42296a3bad4dc06003da8ef +42811e9ee6dc509572e1cddbe5baf00afeb0c5c13e3755b922eee9e210001676082bc9edc3d78db2b5bebea7a2c0cd2b369226c2b8f83b28f33fb513407ab9d287d14b112d6c3be2493805ace5cf6fd366d03cfb28f4ce3f0f060880db64d6962e997463ba7c05b6fcd1e66babe4b94afc5c2d38c7050c69571d27b66ef0090b 003c88084f8b78446db431bd6e240a0c050813d2a763675b0ea869cbe183df697146cf29c03479af3d34587a95cd257027fbeed8 b10fe32155a5256a63c4775a514a0f6ccafaf16a0c897a9f34931d5e811f73519004293da4cbfff45579b1f96239b2cd +b38f76ede7441ae0887e689d556f43155b38dab7cde487ce9ef9a46f2957c830d4d28006873fe2368197a6931f6fcaad755102686a457a7edccc8d344e2d2a9162e3d71d41c09a022539ae6d404955a6ad748231aee1f974d4f159940532fb3b1fa0254bfc5805d2fc68696856fadea386c542d3cefd1be3af04ca595e54be25 0051af7b63bf3297ae20517faaa1552f4fde65819dbbff6a52721611e5b7dc1242ed6e69768cdc37ea8cdfd1a5971f06b84b5803 a999299635cd201a5091370f738ab4569bd6aaeb86a6b2f70981cb467b348a0ba0efd58b33f531f4532e4411f8970bdd +356dc86cef7979148e995fc5abe2b14a7d5e4e42c9b3509b4363bb80c581a66f4e7e4aa53a4bfd37f9a7eccf75fdd726f348f6a3f779e6599f61bd1d668517f40453b39bcf35db0852a6a6218198f52b7ceda2ec55fca5abe8e5d93af9a42b9ae4de9530c5870211bacc27c39aa094013db703de2fd3121f08d7e97dbd4e8946 003d65bdec48972d03811b78150a06956eb22d337dbec5416bbd8185a6322cd8c0ff8000210dbd1326422289071cab65175f5d10 886bfd339fdcec2757983eadd8842a47dd6b71d9eeeb388eb1f3886385460aff77a7dd03bb23391668fa681bcbb7ee7e +06fd39a50bf25e89f1071ff81fec5d1e35b6dd68990414ee403dfdebb792627b6a4ae3d2236c159e4441ff90b61ec87b1592c538515f0486b19e58583394a05e6411e69b4285d6d6589982ac0eeb2c912c4948789cad741183663fc070943389d4e9a1150b8f6088fc50605915e9e24b2d98a1f539024770e4820e14ae42ea8e 001f1a8b5f35dbbf82c102df550c72216a243f986f0325920f6186a16d1da74228cc02be6024c7411160c183c923c743354f9438 b28b2553ece5df49b428358a64dfa45593f9af49773ed9940418c02f4d3cd6745ca250f888431fdcc5b014e32d4b57fa +6daaa41150ea252a3e966a338377307d909b95080e006f13027f2be5059d9208930c5a329994c0b794ef50eb059bc6c215f68cf42260bd410f9bd86d2ad5ab7179c7c92de4a93a5f6aa17de5aefea815e7c0b78a8cc53c21dc4dee037b29c9df4e12343109283ffd5d8a3b81fba1b5e95506c7e01ac056c86dd0ee23bc21af0a 0031dc621200cd174193d95e9092ffb86189c52cdbb9ed937593f2cde7c4a0264b9100e1b8407336c8dfb5520d28a18dc4e39a89 95578f8ec717eff00b4f46bcab63e6b9edb950b382cc80c3b1d0eb9cda1052da19c19d06650df884128b514e30c916a4 +6378dd1c12c5197b57d47dc46a67949bdd1e0809004e94d49b0234126a08ad5bf8723ebfd132145813136d8b7dd096f56c34248f09a65c34f60c2f80f9a51b3795f3d2518b11aaeaf6dd45a323794080b78f85d629e5fa719b6ab0b14c78cd908befeaef0dbfaa08cec9318bbcb376d48b11b68735c9554a45293db5e9239ae1 0016e6750245a88340b0f0665b890459f8038e9b1366f2fc1326245a88d4c523ec94429f21869ce3dbf75126e58f77241c99efaa a561e08ae031f406d6ef324ddd3fb74a31442a8c835f50f770917381a3022caaa1329f3f7f8bdee2dc9d3a6232631913 +b898d0f9bd80e083fa541f457d14d853bba55b120424a95e1d9511c8833f48444329e0349d68204c4b4581ef1c4dee23ed0a4445727a72e1e6cde422f7c10ae132a3fe681f9d741fda263e73f7cdf10759467c9d76164086abf6780ad474772771eee22d195339bb8f6235e0d992bbe282b13ce4fe01417f507a2c4fa155e108 00788fabdafeebb72f6385301e30024b56639e629a400f9c50d402cfc9b5817844f06a451fbda29c7ece41dc9ffcfc625fe0ff0a b038f25d8e236c78a8effdc36b414d72c50f19d56ffc959ab1ae41ec27526cbc149996814d06ce38c97dd91f7e71b93b +dbe04561ea8579672a2b3afa94426a3cbc274b55263989d41a778bcb082da797d84d930ca847a481789524940701cd5f1d11b460bdac0bffb0b3a3abe1ab689c519700de85a0a571494ba0cfc3c865450eba7a9e916b7fa9df55e8a1c246c992e6a0b44b78274e008472bed8d8411633e6520e1a906c5d0c8aafd572fe6f1f64 001b8dfd64563dc219d6eeb53f2e3ad1d771140d0960b211dc1f757af5e297dc7548d6133ddb574711d466688f80dbd65a7bbcdc adfca84eebb226f8bbe50e62ec6de770d87f0cbbcdc56bb142c06d5241e7fa9fd30e3a007157fdb0906b8426884a9838 +48a8300820fea2ad83c83f7d6b24192715329c3f159d56644e11ed25efcbd3d31600a813b909812987b97d1087e74a63b4494cc031c63492b6615e9d6e5b36f62cb2ef88b9f736595800de465789f43811165a5fc093ee6d776008739de8de2a84e878748641be8bd52e5b891c4145f52bbd46644852a43108e93d86352b2a3c 00422131829608ff730c24ddf7e8b4a2600eaa9681eaf45432daa7d41fe2fb488fd0199d431a1ed823801ce21f4f01a4dd4248ca afeb3bab53bd522bd98c5c3fe1682d225b5df5bce4fbe2caa5031228e9d9714a284466604e901934523a67b3846d6bca +276e3a986ce33256014aaa3e55cc1f4c75fe831746b342eadb017676b0cba7c353b3a2b554522c12e6aeaf1364cd2eb765a404b3d0aa61258194a30219d76d2bfa98ad20e7e91756cf65e50d7914157f283f2ba3930c0ad3a97532cc747b1cb9c806fff497f0322025a3d02ff407fc7b5808585b91d95523c9d5864efdf7d983 00095ae8e4c7e55eb5da01acc05ecfe72a4dcd8ec152f1c8dc165014f70eb4e4a7861aeb2b96c418b2d4db58659e76184e013a49 b7c25aacfa1990fb3b00a613458ff6957b5369f78084f7dc6cad3f63f3fd0f0eef46cdf979eb6343ae50d06278a771ec +6a4fc1827c3a7256faa8ec6a0f3d23559d6949f8cc20e7f76111dc4ebd59213951cbf0eadacaeb8862d6baa0cb298645e4314b1c303bd0d5e9893304d4b7fbd36ab05fb6a5edc3fef763e3a4124d61539eb616b359c5cb55b5e2bec50c91dd95fc39ddf521aa854216eb5a707819fa6f067b316a17a3b146e7cc2dd517f7d63f 0006f2075bd730f34df111ebda919167b1d3358ada32cd6747cb3353bcfb814a77ac70cd51b31a0e538539453bf9eaf9d8b384c9 8308f510a843045b0b78af6ce3ad7585c5187db8b2d6ee6b79414605ec8ca17267d98ee43cfacf54ee2d6b598183131e +4b088199bd8c94775d8ee508377d672dbf50f6d2c7370e99821ec8f9387492fb2eebdbea473ea18465565f79e2af418555f10c4a527e05a9e20c9c00b807dc8b350cd4ccc2d87e91f66addf02ce4f43597aa258ac6fbe9365cc2c8e8bbe5c884abc929710e8423cd6722a8f473bb55804159a92a3d8b6661a536b4fb9293bb0a 003887d284e9ad17d38bc6da9d83c192a434c509340a7f233cebb032b09ab7c4c6e8730b4a80844898616c9abcd16b753c6bb4c5 962a8e2ebf5fcd390330f15e828d09a8d816f4d94ca79fab6672016cd6bae0da46a81efd98643a6da65e489482d9d0a8 +848a13465ddcfb2dc14f7bc0db0756832c22dde1e31e4d8b3ae0dd1aafbdf15e954889e95d3bdfd6e5ebb6171fad62592c23277a89e8ba53978c9b1afedfef7e1c3f6d9f31077530460b47834b30bbd84a4da601be988738aa815d3d7e72043243a5288751ee08b4815a017fb5d9bd55833698a0d526b1ed79da35ef0fac93da 002ea5430610864257c9dc393c3addcd0d8d5bc8aab1067643b08857210464428aa85cf1ae6c743fd2682255d4c8eaa46ca21e73 831e3e5a8ac600f0e60f39e06bc964a2c7314d55e8060359603f667da13ad020df0c785b55f503293cbdc4196f39c0ff +d1850545c04ea65528849973c220205c35eae98826d169348970d1420b4d872ce233af1daa9e62f6a562544ae3a0633a954a493e9766dd5d87e47486559fdf86229a7c9e1726de21895abdcf2422d438f4ad98d88b45c56742694ad5e11894253270997c049f0f419842482f21c792fbe5613e2defecd485585f1835b6f4c578 0062c757c92eaef41f5d81169ec4968145b5aa2bc1d2a3a5fd000634777748ecb93677b3da12e3be33272a8f0a52300f4a5a37c4 b3b370a443f6bb678ab398880d0372afa9da285fc480b4be00f4068bb37c63a1a75ef83cb4e74adcc8453076d8dbe136 +421c9784d6fd507c82904e1054edf9bdd1efb58a0b211340086069ad38b7b0dd15c2345fa8767ef71254ed1bd5c35f742b1d3f4765ff9007a5477ba9e5d3d5a5cb5fab4efc1cad73701d4776c6c4343f42b5d94a9eb78ae428dfe5fbdd8e6ece09d5b75cf4346cf27db856352225ab04e6ea56661554fbc39916accebecb3935 0048a313c0c11489939fc0cffc6ccb9f179093c4e13141b92dbbaac441b7ae878c9d412066e95615174a24692555cbbe904a14cf b92acb37a0c154bf8aaed97c1b746044689a1d01ea3704c1f05473c201902b8010a5cf73ce6909e82d0d953c91f57daa +7910bab15b6429947655e33a67f41b76f1d7b71534f8904d6a0472c2faded038565272d0b5f51aa915e0d624e9ff48d50ebfa2f09324864f26c29ab73eb39b436c5c459c7cff4d2b62992e3489cb4ddfc05d7366b161a463aa1b782641d93507de43c8cd0a0a0a9d1c644f4554e3edaf7fd794248110ca9387e73ae5d00d299e 0046e2adfe5d3549e1e6fa1fe69a7cbb4ac9b111c8903d544268f8318b0b47d4b78fe3e56eb5e639ad5382e7cd5bd4b2c3e70ef6 aa22e2d4f6a7224dde2d3d27ff9948ec99c9ebee528e90c503fac96b06399873e7cfd20b136470f1f991c5c1262e4358 +e6fc96e060b956c25d50ad25443f3c30a12d199a47451a49ce88307201dfb15ed816982e8888a28daa92eaf3c5584ca6ab2ca9e14577f84396de2e0ac214b24a2279f5e7b344fb7387e9afc8f0a2b77a4d024a20ce6183499b17096947444bbb753d9b39e5c694239d28f9c454bb05468d17ab564ee6cea3741747ccb7f108af 00480103fd6180a431c837643566706e2b9597de0a1346a224d176a5b2c54aa4d064418ed654a5d39f4773fb509f86473ebb373f 96f58d5aac019b63c999d329055c24f5b771b4f03f7fa37f64948c9e86413099a25f85f1a783551de903129a7426c7e2 +c8a8a0d41f35537e6fd523ee099eb45e1ad6ab54bed4d3e315e20227db03292e39dc1a91bab439c0d20e36e7fea6ef08983f390a6b5551ac3b4f1895220b2867fab95552cef9bd8702962839bd9b2c72772640e7d3be3c5889d226acbefdcb448432bc503e5a5fe7ae9ae7696c720a799f9882c64ae0385f656074dd8a6821f5 0013c489e8311c6bef02c8f58903b2ba2a98a27cb935d75a30d320af9a14fa3cbc6adcce09235a9eaf333dd05f4b2f1694985dc4 8794549dab9b68d86d5eaa91a9c908fda7fc9b1ca2931f7645aa722b2059adcef9f9d8dbb5b1229f961df1723baea58d +3407cd6d2845197cd7414a30fc3df7184da204222ffd65c4d16a12cadabf603de8043ea14f5e6ddcc22d3572dc06dec1a23cd924e1847ae285ecf01754e2d1247876431eb98e897e47412a2330bb32990f9714122109e94b38f82cfdbbf2eeb4c6f88f5dbf9f0ccb47939df8be321dcd9bfd9bb99cac9f94885fee7d443fbd87 002419bd2200f8e1d87db848b0379741685e680d9affe693eed49d82931030b6cb05d21a4965f4e1df2045c8513a8f574ca9f2e7 b4203b0017d6ca5466bea9e89f96a2d23f2977c34b78a7518f0417919a0703bb55a463e68f0e6643d4ce7a2dddae323a +ad43f8440071285d01fd79244907803601aff4bc5d14c77483a87cd742144d41c68269d76c9a83c09d2178bbcbdf99f927b378497ffdc907a75a3b0ad019e69758dfffa480871eb6e1e17c8539373de611a557fad120d0bd147f8debe5f09a02e56fb607e9c1253ed592071f042e42fee39775b407225a2b86a950d81bb7d7ef 00722951879a65bfcb414e11712ee9431eeb32319e0ff28601112f89276ffc2b96eb65c7fd77d023f09914a53e2aae2c84652bad 8c90db861314f48977d505f042b1e0f57c538c5d8170946eeedba55a31de77ff264920993f4b9bb29d9365f26f84f0fd +d61a3765229dcd0b4fa6c57280f851ec2bd54d3ee2436935cd6d94e0120d0844adda163995fbc4cd9d7275da859ad8ebf30af9efbdcfc31c7c9ef42bce9011d37cf9d15fb018e117bbc102f7d05750e5072f73d02c2f45509a55627a78cbd9082cbf36807759d1fe2ecbb92ab30cf28434941712d38bdd100955d611987b5968 003f5b5a772d24bd5454bf26759dbd433fcc7bae4f5c593664c4d75da0cdf9430d7d9162bce3d7f6e13a344259da5a7d6a1635bb 96728690e1c2d52247d6646b38f18cedbcbf52c8a513b45c8ce192777704df4c5ee9a85718302def38adcafa23fc5e58 +1f3c23636414ced48fab6763eed5b22537968e6bf08c178b3d31fb1f6ea773c6979759701d94bc1bee7c354272811edec58eff50c93331b22723d460e56dbee90466b894354777b23b13a37d15a84c762caca70c01518bf34d0c2f072145d274b3b6c932b48bd815fe81161d8507ffbc2f783bd212c29b2887af6d2ffa9d2b4d 0046bb4a141c9099d531dd23ac440eff1f5b10f7cf34920b6b702311d490d25344c665ed5211d401def24986c8094165d10f8934 a833b9464ffe89b82f63962a8757808ddf62435d878e4e99a9fb7b3ca00b7d65b7973d46a34f75a7afc5f34584803d59 +ec69f2937ec793aaa3486d59d0c960ee50f640a9ce98a3becffc12d6a6c1c6c2f255d37d29f9b4d068373a96beadac98fd5203a9f229bfc70bcd449640165ae5128e3f8d057769e28356e73e35d8e9af7876f608390090892c67391ddfcc1c332aa61efbf72d54bc615998b3be8ab0a9d372784bea48c9fab244482c75cb2de3 006f2c6e9ea8109223d9a349fce14927618fc4fa95e05ecf9aba1546619eaeaca7b5815cc07e97ae8cd1e9973ac603f84d838393 8e9b1782421308a495d56f2b468ec39c846ab2848280ed1ae4ff56df082afa5a5f205aafe5edc6f5fa4f5c568ebf3cea +70e11efc78d7f079ae41ac3c31c96d3220f4abfe23814a2a4a78d9b1a25e838c3408bd416062e4b0a5cdadf0c6e16a11e00f59711b417751f5e4b43ecad99efbdb2a81c91a034e89edc94eb552c3eba62808563cdf64453a1db07daff8742aea4a9fa738e1322da316b26dbca2954b2bc0de6da7518d28e6677dec6ba8af4285 0004212b7fd913d794fc6bb33e0276e349c052c969ecbf6afc89b28f75a599a9242acf74dec9f374361ba296ba42a38407f9b7d6 8183c0bcfd35e545adf1ddff555f1fa9765849c0d7aace88fb59d0fcc89fe0e1d25f2f69171fc197e527e19212c3686f +d922fa515e3bed60b517a2d37cafe4c041e5ab4b5c8d8d4011bf9fc4013dd8abf7add71fcfde5e71d6abe76bd0f749e960cbed55711c87b5629a2c39cff48ed7d0feaf5cc4765e576a4959521f9a45fcba0dc65ae618826447e02ce6e1cab5ce8d6c96c3211adbb0660de7df7453f3aa726016941d00d8ee536cc106a603d126 006baeebb5ffc89c94c3e8b37b9b0904e7c4b251d204894655bf3b1235710215c29820b9d401c9ca7df1404d2d62d708aafe208a a9db21c55d790ee95ed29b86c84fb81191491c6c4fa990b2d9de6fc9aa66b0b871745ad845f8813dc3c684db35b78c70 +4f64d0f6bfc542a0d4347576935bd68ca88524ead03b8d2c494061d0658e6c3e14576b5bcea5f2f992f54cfb52b5c7cf1dfc517205e0454510eef1b7054a8cd06ab53ed2468193f98ff0dd62faf076549ab2a270f259276d5729996c120792c6f466a74ab65035bf38ff2c055b43e2a8b8e2449a2375ddbfc18242157bd905f8 0008e5f66ba53e7caad1feda122a80c32c82d2c32a7237b8ee8ead44ea8f2f01d77c7056b9dd60b92d051f060da8532c1fd0e8f4 8d8ad7651dae7c760ca933780b34fbbafbf7afb7ffba08fc85ecc7cd94d7d15accfe38120ff4eac3c7b1ce228ee63d07 +7047d478ec5282d55db8c19c97af10951982d908c759ff590f27d57e2664f08d526cbb2bfde39bdbb1aa3dca5a8d3feb50b868be6651f197abccc9d8040b623de367e2ea1d20ecd302afb9e273f4be9f3f64f2c2eb3f92d5e0e375db6549da2a589f0604bc7146562ccefd15995a7c4208f640e7a17afbca69cda4e173380523 004ecb22b44e809f89b16abb10be062c89b41ee34e110403e42a20ce59a99afdc22f6f6dda56e1d9d1b8ce1d057f390db111def3 81b5622a7871d493f674099040cb294134835de5abc835fa4048348ff9c234b8aa7ecdd1751d8afdd7c3723d100e8329 +1a8384b4771a410663e56eb36c5d9ede8d161a8fb0e31d3f74bcb017b9e31232bb2e2f4c65a2d85bcd1cedd93ef08d4bb4af0095731574ab3f2762788a1ba3bf0ee46684da8d9dd384432fee99ed3c69213d790a5d81b351063eaf2bda71ca4868ac36be1b571024a8bf09039b347fa996d5d161078314e24b7d073e05cb3d48 0051f9500c15ae73d6d479b9f3d2caccc2039d8d03820befc2aae3bbaf65d59bd9cb3c4e3aa8bed5b3acb70a5566047ffad80729 b7a0fb6c3b2bcb99d5b528a1d6bf429bd6510e60fac4ead226b0d55ee87f4d910e3b17a22c2a61f718f623bb0c684c84 +43513d6dd8bb0af7a6f5a2b35f99957d335a48d54f2c4019ce9518b35441d4935518976ab1df37110b5b53532cd9e2c66d9f87ae7f683d7efdbe1775a6c15eecee84c6f879999d0706f6779dc158c111fe8d7201983883bc8334f51dec60004eb1087347bfdab20f8f2f260556681e05fdbb8a6139857fd3bb2df5bc1f2dc143 000cf01dc4462cca764f4f8cbef48c51980737b9b98d1384b8de9f4c733829db7718a9b5eaa46a8475c2144fe4454cb8eeb0a443 b222e3796faefb28ded8684c95ff8020d1956af3c31d9b61ebccb30c06ab43ae855787a49b341cf4635ee19eaface7a0 +752300bc5066d0efaf807183a41725e349907b7339d77c79921ead3c685b616b0eb97e708f3880fce0136c510c8cb53b22cb424af6f1c34633600939a0647c02d8f9601f9416f1d24a51657241fb559c25dfba91402cea43bca1a13718b3945b048725f3df560e6717cfc6ebd894e29bff1e0c7763f15b8ea93e67385f059598 0063a9a565497974c6dd459bea0d1196d74f263f333c31b7e8591499960e1cd79e2ef4cc8709f6d54713f873b16e7b0be42f71c8 866d5e8f3e39e19078b5ea3e7afc3b4cdfe46d6402e96ebb45cd4fb3eb06c3bbaac90dcdc411664780c2cc7781bbad8c +f620603489944769c02e2f902c2299dd5f32b5fb463c841b7e1fc0249a85d2c31684bd3daacd97de8291c5d39e84d6e59d3dde1b30c181bfe8d31b8d8e080bd191690a67fa00024ac8c1b10981b40d4f88789ecc58fc69b15417fff34834e23453bb9933a43d08afab74d056f366b40ad167b51ee5f008db151a12b467d3eaa2 0041074dc186193d30aac7cc6d269b938ab40b257d095e54ba79967a377a91b8f73671470cd07f0a3d1db7cf0a31ba9070625e43 a275c35dfe679fd8696ce774717c4085ffbef42684b3917a316220b2102c0c688fcd9af1cc3818e7102465e27dfa7b83 +5575f610762b42ce4e98d7bcf45a7a6a0d66ec7f27d6b8b17f1961249d905bc7e58e2ce0806d467f106b16285dce4544c72666d08b5e2276cd0c4e13187cbda8aecf57b1855afedf8fad39ee4fe009f204e60bdbec79b123456ec2d85631d382b8a2f2c7634af3992e4707f7b4215e2c9d3b0aa8fb08267953883a4213669d33 0010820db54ccf0226161aeaee79cfd2797f87702b4ee91adf8543b3c9e79579d0df8a889e366ec1e0718e039b87a37c24d620e9 976aa9825505fa3d419f123c40c811efbb8601d0256b4f8c2f4ff978688b47bbcc495012819b4a6a80165e15f23eb283 +81cf067411dde2d0ab04fe5fa1e28e6975cdcc571588de60a35bd956a535fbbda4affd0803d244f3f7e6902a2c9a7ef2488691b6bef7f8ffb33be09ccae4c5285265e4957f7928ea5cbabd6823297f59a7cfc9939a49f26bde74c4c69e2d38c1efbacbcfdef011213843158072be84ed3c1781f67a0e2d4e9ba76a585c17fc0a 0059d2a06e8bfd5e14a9bc8777958b85be5e97af892d2cdeb0ecbd2d5017952b5042349db5fedba2e26e7b85bbb31ad313d99434 83673aeae0872878b4bbfc5c35e80a0663fb655ed4acec563e32b2824728b2c41a41a75953dd68f3dfc9eb5aacc6422b +8ea18387940035cff2f37278d321b344231075db43c7fa7fee9bd3fdefe5e8f03e7af9deafa1022eb108e19ec11fae34536a4fbac2e8c8139a081a997c080cbe8f3e2d2a72ff26edcc5338b21372fa1498e439e4d9bb12d51cc539f859047957b1b1f1fc30b90231eb06b365a4d404a1fd5a0e5cef171fc95b04d0b557d78ebf 00405590893cbbe18f4ad99df28b5f9d17f8f1882269aff0b7eee9392859d68927a99c942a3075269ddec6d69c0df2d76ab9d801 898efd35ea1b334b97d48ff58e5359c44204f7af3acba890307d26198ae0dd0fd52d75eb4defcc0f8296ef7defeb152f +6a253c1aa17b2b1e6624afc8e7456d366ef5b1bd78e740538260f395481148a64da0b6a58cd53d7e06c691beae1a616547cd95c4d259a371e51c2c0e334c8a5311ae31e4c7af325686ff9f7a36f731010ee1a9b8a29169ceac36a060dd23611dc9713c615424888bb574ad5f5755d7311bd169336ae986c977a394bf16487c4e 0062bbb4f565aa0f23b88ab9029d33b995729d10fcfc33ba7c4051e2fbc72f15636a834e3ebfe604b927cdfc89f53c57f36890db af0d54359d255a258c5c4526139d7022aee0bb537a4a74a84c765d40a0af9e9b5789505d31e2ef3ac020719dacd6d592 +0f91d0f0139faf3b90a3d4bebd7e96ff6bb6f90f6c68321fb392637d8ab2a60d649a7b7364ee6e4e274e1a8d342caee36cc11c56c54247fb0a8e8ef81ac4322b454dc9a195dc54567bf47ec8d4fa4cd32e76d78ea2d08bcbce3edbb68fd8597e56d5a9f2df4e47b2701046df89615961db601bd8204584a6a6cfbb627e2a1190 003fad7031cf8810544a3e4bd1382c0a2e22c5a9fe4804ce67b27591fc516ee81dbac841d399327168aa6abd79e2b5ef85df1528 a72ac9eb445eb2565a9beef1763010645bd635bfcbe749a3784e799c48d92078adb6e22bc87f9ddffe2a8e197c5bd7b6 +50c17c1fe4dc84648e5c3c3ab8f7c971d4c58d8d56d2b5ddd92e35e6792111ed8dac7644ac8a07ca8bb4e38e071aa47b22ffe495e9083f9bf781ac1b5fba571862c909c7aaa7b8d05ddfb7ef61c99700de734d5658f44ae9fc908c85a2dac8e7f854d6d24be805fcd7f873a91252985c5c73129c60177ba8fd99daa87b25a073 003db41b4f637fe7977c90e4f1a21799baaddd1826c667102414877138436cfae1b9959842b8097b5276f15f2b982ee59df263c8 85866a6526d30347bcee494e63c055b00d3ebc89840e9547744eb92817081bf036eb6fc984e6b4045df6195ada0d7220 +3583a3226e2dc463a462fefa97024e6e969c1b13bdc1d228e2d7823d9f7c09012390c2535baf086588000e908309090daac6e6d2b06d2ede6fae838ed47f30b5b481185f607a3586f6dea47c8f84e9d3b96d5b0ebae2462fde1e49d84d36658e87dccf5e30c0937feefd8862dcdb1a1ca373f6ae41641502ac54df6633a8cec1 0065b76c6093d9c49591293471286df1a4444e60d9d06cfa114e175afb5f119d2abeb273b0596019a0ec5db5b5869f2cc827b364 8aed99289556e322ab23d80a0836db3b257ddf38c8a9cd1c8bf95bd10d09af807ce8f10c76cf59b8e1a805aabda5bcd4 +60ca58462d53d074b370127132f4e59f5eb8d15594dc721a94286afd082a8934e52462c9c1c3910f8b50d7aa3671dafa5972958d876d7992467b2fee3795a6f9d8a7bd3003a8582ea8c003aa1e02c08ab6804d85bcfa13a815d75c938671f0af0706c68bc70a6155708ca755cac2fbb68b2952208d63e0e2e3d816f04c61bc03 007e9993f3fc1fdc4c376ef77ecded96006ac1159740bd1b2dc6ae3d97e15a67383f1fc931e460b9af3fe14a54e47919667ed06c 83807cca52b4bc670ddb3f10f35be4469d0f8cec2feefdda8fa2b72e588a443a31a539d74e718e66ca22c0aecb80ee79 +c749f9bb92ca9957ca6d0124206ebf65e860ff38a225e241950bf4526cef3f4fa9184ec83f71f813fe852dc08eca6b45b14fc7f2c6a19296529bfda007efe9d0d26492de2a902b45ed39603e22f0a763dfa5deadd97ef6feb859d860baa2cfd1d066c0be0f9f4e0e2fafa69cc51b12e814ad2e33b0acc0bcbe1df8cf018dcd4f 000c11e2979498695c660a2bdfd105b115bc4ff8664ea15cfb40c725406c6fc9a13027bd1d72ffff6258f29e4e19b845243444a7 814448616d32b3b616f8b000f1572079e2c1d1ab1b4e2c8c7d1fb7704565f4f970c3830fe86437f54a87a28e8aadef66 +4de8414780ea20f7943b1f1adae5e3962d96e828fee43bdbf2831bd71bd25df2976a3be37a7a667c7fbe1200de578920090d131a750c9bc09bd95b261234ea8cc25423c4ddfff5656d6b32da6e2f6f530e6673a8660aeca31273bb9a3a21bbd7031a2fa71ba37c004d3d1c64b2c0798783e47b2efe1a208959ac16e35d444245 0068dfc23c6635bd1fa1076dcbd456ad6e8df7ce7c1370fe275803befc4ffad007fd062a61cf1d50b93aeb9afe1aab47a65af82a a05f988e230b350434a29b20feed9021313790a13c27b64d35f52194012848bfc17859f04cfd36608df173bf2ded6d0d +a081d54232f84bb19dbd52ec3812748e2e6486f6cf1b177b27929504ca878036547eb43531bb5b3edc81bfe105370427e92831d2239cca0106d031d9fa8da9cf89c6fb6401377d5936b6329ccad854e5567181b8f16a37c35f333eaa0ffe91d727d183fbab935fdac2d5670dafb3fba59e4fa2df1746c58dd8360fa08af7f4e6 0040807fb888e1d9fd33604546656a493629d94d4a0a9de2608962225ed158167f9e2438abe2d12a11e2adb6c2b66ed78215b0b1 ac0ea13cbb83f00f5030a062304f3453f9c5b63148869dc6c6c6ad174b60b5e76b2e300c21b0dff26a39a0a0dee95d9b +ea60266f1538565b3ff42fa4bbfe319be070329059c52c8bc04a7da2824f209c1145a05e551ea59ded8ca8439c328f6907da4e81d658937df614be98c7b8648818ea80ef40e49aaa4431f4a211d62acf2611f5d60c446b2b25745078c643859be1b12b3141a09ab765dd63ea1f2a2df015eca0840087a5db378c4c4cce76cba7 0033bda0a02badae08fe40c239b9d59e5bfe1c4d4b9b7a5acda6790bfd77ad08dde5e93a2da80ec54a7f88146d72218bbb88aa10 944bfd1deeb8d0b23a47675b2b7b0dca66873912f5a70ef134208431a97e7170b4516b879fa8c5cca09b9ae048cf3ce0 +82f38c9405ef0d26bcdd5b3fce4fb0060c3095f61403418e17c337933f0563c03691fabd32ab5e896c593439e7492a9970ae325c67196d9e83fe0f9780409a930326f7e6efae035ef8c321cb9ad12461edd5cde66c04739fe079db65406b3c2d22f2d04b1a4335285513d4ceb901d2ca2ad10c508302266c2cd6079ff14eff4b 004ff431769d26b8837d3e1295f5464fe82be29edefba76323e92078a6483ea0daa96221549102509a1bdcfd46a5a2e5de10c39f b853d44cff8f81440205d2065714347b01e728b26764ad8adceb6609c5fc2169fac26bd022c4009911ef6b3a5aac2ff0 +d8506fab4f681ba4ae86066aed447571eba4fe04e6585fe3be6af2ab1000a3da68c5b0c711a85ddf3a40cb7c8944eef81f2094650459e14f5b848e6add7e580b0198070f873eb3ed5d0728eabd92bc1398764b94cbb4cdd7cc2027b9762dd10782658cd9e8a5022ac062fec535d892198c8a387b3d2b6f7c92b1af6ab7dd9e4a 003f85ca1169ca7e9df44cbc6bc7d2868c9d94e8f8b699a42ca492dca0914eb5789a9032218dcef7f95f959c9554a1cd83360439 b191139c352a915bfe727d9c5b54f00380ad067a119db704b9243e42966eaf0f0aff76aed3179847f9ece7f8ae9a22e8 +b3f30d34f252a4c26f396079e773142bf61c0981d912333ade3de4e27cbc72cd8a16b31807f0c46116f87accb854487d83ec8c6a61565e6fca145eab70048245db08616779d7047db63aabd90dd15acbb05eaa510072c151c0518f1b34582b95f43ec7b9484b2993c176de79e84566764467f72392ef31619426d159c91816d4 003a97deb36d68f81f50c8829d412ee5de7f9d775633cb69c09dac558182039e275fc258240517a7c4aa592e364765321f27cb12 85c86e27a57908a30a44854d16add9e02c33960d57a5062cc4f31ddf3e189ede464fb15bf4fa48b8dfb2a338f3324492 +0fb13b7c09467ad203852738eda5ddd25b17d330e82c279630b0e1f0c86681f67f6e537fb00da9419114973c8559306de58b0387d86e52d821d982a60769d2f15fd5ac2ee6dc55d8ac04ee247282cb2866b8cb8b4d7b4b6cfb33bfefdff09a73d727193e5fb939ff66ac5fcb644a44f9083a790888cc538c5eb435243c6a34a8 003b1da0ffed24e1a3b5ba22bd684337f6b08053591620541bdad50c761d66201a2cf21a4cc636426456525b598e96baf97d9851 8b661c4aba3b0956bd5c8259fda190790f56a309c8e36f9e66696118f853770f90e8aabedba3688e866f7fe84893afc2 +f9b8124281628cf4e1da0cb4f021c8d19d815644cd80c7c8de4cc62722904ec4cddd26cc4891f30b15098a25ba6923c6abf4774deb6e1883fbb409862f94467e75a725e7154be860fd58347577c83adbf18535c54b102220197afa062cc1c84f6094490ce488af4a08d2c5b808a2572e18a59de96c87162f88413795351cedc1 0040bac7e0d3b54c7753c79d43469e310d876015d948fac4e3a9765444754476af72330e88d79ee6119697aafac8435ab5690754 91528248fe7d20cd6027aa00835d889cacb711005fc92e74a5493e23cc1c1aa2de61ea55edd6d079f92b6b5ba5d87813 +4e3cd6100520db050af0daa69fe3cfe6603a223d4f2a6318fc5836db8640d4c7fb80bb781302036d2d6fb8e552b4eaef3133b98ba2d36b9ef0b86243b0391413c73d48ecbf1d19170f1b3b781b35ffd316afb1d55d1dda8e91eed5553780cb2714a93e7ece698b832e853e2589c5ba2b8a997bbbbf625071ded66762af8cad42 0025b7eb3bdefba3c5134438caf968f615b315204f348006f82e8d61057a8a8a853230cf0500f9d0b8c1551a59b9184862dd2ed9 a056497e597891c13473cf0060213c10e481dd695a91a42d5720dd20157cd5082fc1a1d2fbb8a7939256aee76a4dfbc4 +5411708381a65bef4381c9e13a04cdd5ba0c15829f7f25ccadf695f635384d8e4704cb562741747831b33852567f42fedbd190d2980f1bc921ce01c17d659d4bdd7eb787b3927fcee659dd3b65132496c687f2249272a473d46326e66b3cb78dafbb522390162c168f73bdec88adb145e6afecd561979846ea4c8cee38dc1686 00673b3a2985c95904732632e5d988d8d437a60db13215bb6aa880b348f011c609a1e860461427a8cf0d622abc47f910f5c97ffa 955e5909c6d39583e2a189b37059132f8be0a6c29c15d5ad801626deab3df50026a9376db9aa12450e3a8c9e79eff4e5 +23757fa60fcabf543e603d8b31ef0cc99b3ed16b4816a84e01dbfc858872fcb79fd03d2f8a1d4f28c25dc42a39e20c34f81ebccda1682ee9bd22fe323e7f8ea90cf4a2a6ebb634cd1153cdc35f7306f28a2efd822bf23131baa1543d0ed5ab4c8168d3199983fbee117085f90550ec3ffa2b06070d3add1d707fc2593285ff58 000db7dcac414010b816236cad584dabeaec1da76c97182d1b62f87bb7fe2946a64d10430571b2b29ccf2ef72c969a9f045f1f3b 8cf1dc161fde5c1abfb442fb7f1472707f984cadd7daf2793182086363f51917ace42e312e01bb695df28636a6e3ad33 +b976314d2f066f8893307a726f450dcf2cf865c170e90e6908ce9787eec48e1e2119a731b2bec3c12fd4e6282a393774251bcaef91af6ce57c63a8b45bedd72ab862cd169b7c84b8f6a72084ff823a96f2f8eff3483a7ebfabdabf0998377c5a6836d88135cf61c65a0ca7ca57727da68047dc635c17ad13731035fe9a6402af 004717efef16e1ae267e155aa1daabafc68515aa391dfeb73c13d01f3132bd22c984228dddc4dff4c39979e7585acd3f730cfcfa 95fa1e52f1073e79b33a5b5a7f3f4f6d50a080d8c1f677aa7262e1f2129532da6a2b3fe849c6ea34833239b21fa01722 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K571 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K571 new file mode 100644 index 000000000000..42bc5ffb8aa6 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K571 @@ -0,0 +1,60 @@ +964ad0b5acc1c4db6674e86035139f179a9d5ec711b5bae57d2988456bb136d3aade7ac9ef10813e651ae4b9602308b071d75a934a6c012eb90c5eb9b2947b50fc97b1d36c5bf9eb13a7b06c94212c3dcdab402a563262298defff62b836ead1f78f9d20713710fb48115cc5045ba15140fbb4bdf516e4150d830d02cf30963d 019cf4f4d06825499949f9e0b442586fe1bfe3459813a2b92cd8de0f775a4735e02655702ead8e60824180761808d9e816d60bdb0238e1e8039ca7bb63c92e1cf8433ef447e64ead a3b7d2917c6f1a61d2d1b6569eda00ecb7f7c92a6e35a23e2da54d86bfd03b97e794935ac757fa3cd1da6f6fe3f50c76 +baddec4794effa668cde267016dda67bc70b847919a9aa595f93ba9dc27354399ef7a607fbead31e57a8ce698beabb10f313d393980425e67cf95be45d512f00e950c0c5409573ddc3d556f23daf056259ee8914e860562a674311452fed780b3e0317a7fe93baa81fb98df3ae4328b28ad0ac8f8ea33efe24faee658ad026f6 0098521a732e72ed945a549afc92318fef7156ed1d1ed9bab93b581478cb2339eb32bcef705c9bf61cf2873ddbadff8ff3806740a2e30ce67d1807a8179dfd5d952e6f8a583baf81 867f9b59683fbeea01558054b2538bd3496c7360b71fb3822997a45d50f6c91387a8828acea1315adbeb2f9ef12d3185 +7ef7138fc657492d229054f8a50dcafcfcd1dc06f1c16640af3f658907e2969248b54416066eb119adbfa23b8dc578aef18bba79610b9cc109394b900a25e55a779230bb858b2ddd9499a7775d392328db9177aa9571c2f61dd52010b48502154e914a0c55a54edcc04a6713cf7bda8744a893926118b09df877d1a4f3d95e8c 00336fb21549e397a190beac38a1ee10f0551952da15f71e11dfda415e5ee08da2356f114d450c661f52b2b32cfc7b9be61732672691a079f0927989b7e9f4efe6095a242155b641 8027cc1e7393283b6a2afb23fd7c314814686362638f0660e8092eb16ceb99d24c7b576a480fddb934f1c563da58fa63 +d58e1ff1d49a471d0567ecf8f29173dab5fe5f6184ab4cdd095c231fa7b82551f99a482994a46c3d8ebc07297fc9e952a5dee7d5f199b119f6f8b250f8fba45701ac252db725e75c4da27ad77d59a4eac448e54a277986740dfee6596811e59afc9755e53d24b826c09e497e29e69a22bbc85be11763064e9ecad7ae66458ca0 00e287ebfd9ba294128cbd484fc5121d271cd33e685bb1804f09b40aaacf64b5a9f2cde9b30a4a02d3a9bda97d92f46bb8787b3c61f280b1e1a0680f1f0679d3bb34d53725d62e52 8ee75682b68627ee101566d80de685b170f9e33fc0270f5b1e51fc86cc19c18c5ceefbfa9c32395c36c093dd6ac711fb +4949ba765c14c31f68ee0ca26bb42ba2edee63537de4a6f5c42bbd862c21288d6ff48145260365193c6fd2b56dfb014da26b8a483776b717c6874f627c9a622154b824565b23e178240f53ee9748c45759ba5c035b584df0f09504e95eb9bce0301653aadb860bb25e6ea6b9606e0ec3bdb8089e6aa0d5763d331757490715f9 0149de496fa8f88b2741864d0c35b3df666b87179b7bd06cd426a45f13bc87ea9f50dea85e1fd02a532630e0e3a231cc3e7fbb7c7ba85b40cff1124e72c677c6a3ea6aa40ffc64b7 80e65148489ee7c785c640e2679696dfcec04385359b2e22633b662815095ebbf41c15e65c032c4479971ee7b6fb681d +5bc63e5c50b1650f0ed4a599960f1e4e11f6c151b2123fd71d9e3c44662312a74b6854290628e20b30eaba81555acb2fb49b640bdab2528619c7fcad0f2a2880c7ea232d427d7c935fba2313370fda8863a7e7e203d63ea15d0cfa083e716ce6068c63fa616ddc225c9e413e694cdf6b355cb1293af5d6cdea51168f5634e878 017605d7c5873d870462375d741b4bc6375f3d47f7f5e9d998917adf2137a81e63b66917b3dda8968930c4b850f2270eb3187fc756e2beeaa67fe0d73053e6cc0ff0004a21250551 a7e832ac1eed2c71c2c1fb5b6c04c9e2e9079dbd0b9dd39fde2f7f8ec89fea5121342642d274b193c2980cd6963e1d7c +610f6633718e49d232b3798654095e2efa0de11f41258b27aa01956480c870d901efa77e109d5f95f1f5101d3c90fc51312d9b3019d2e42e0067eed7b457dc7fbe5466923b62c83d7347e4dada571b57813bb9c21d5e308519b8eedb7a7706508ad04aa69698e03636eb30fd9fb363ef3a185756494ee01175b16847f5b68076 009214dc2da0967912c31995cb8f5bcf4bfa832c5a2d3610f3a9857e5eee7c77100d599d9ed003b4106013155dffd6c48859b846e45e0ddbc5fe24f4891c9b2df51407e9cddbd974 87d091c752491c3cc82390853250b506a472f3809ec20d6eff9e15e57eb7b1038c5d88594f609ba6ba887022c76c82ab +c548f0546cee0c0400401cd540a0aa9377f27ac64492e6baaf38e794db4df83e64ca3d83b67bbb46a6c269c04c2725287cce0dee984a0d468c9ce495a7e554a6835d72c7493bfe88dbd5a044a148c89001b8087fb03e57c2b7212d0b175d616333a9affd8a1802dd49ba9be3ab6c6d9f99a5578d26cc4707a5860c6c804d69ce 0042f2682e9ac8b76f3c0880e12c292524601dce9ea6982dcf68bfdb0d3fbfb50dc9229e54149ef09b95bbf624eb04ce1427077f30d8536be9f69970ddb449ca22ab8368d2689ed4 93948f3fc18fe14c350203423ed0fac32ccf3c15ce54849ca832399dfd12694dd944006e785c281a00a39804f3cfe68e +9431c6c5237f6b4b35682a0c32f68752035c8b295a1763c5dbdfd73466cea64a00ecc11356d02d2a9211dc54548f5db1651e4471898402c887fbf45005a3bda271df0158c98319d4d6751b8ca6b07100182957d5fe0d97c4e2294406f83e9afcae4850bb089f2252490417b5afd8f07f4c795fa84c9c7cdcce26bd97273c0072 017ed9a9c75cf66528428e85b0f019e3488af8b893b12023ff1b4ca9c3691b74e594539afa0f4d7c3863d15399b862f15e27bb077392d6bbd546ddfd46728c75177338466eb2f4ff 8da0ee163e9e3c9762bed91ce38b0c45cd6e25aa292adb10313da0f571d7cd14e8e02ed9b936fc2a54d64a674d7d34de +417cd5f60416f17081d2c70e9a510114e08be83573bf9deae75fbc3095dffc8a7f7325f61f9d6565381710eda871388cb17619e4448836076338ee309a2bba5f737319002e259b4a875cce1bb97996101c9a7abe0278dcac203a712f0809eb3c4b85a9c380550ab0bbc5067a8edfa78abf03c09b5c08f21714e1022ebfcada4a 01bcc09b3f2f1d26ab9955bff7e8c0f85c8a61293511a196b53d7963f4a4503849c96fb4daa68c9852ad9185e01a35f0bf298e34a09ec352cb6da34f89a1f23e8ea27712a8f43aa7 b5769777c27ede50dc2d01e4719e415376125ad823f2cc1fd5e2f0691b62de0b371232a8c557c31e243ad3f79c2277ae +eced8c412a153a643ccd69596389f83b6a36880286f8aeede503452bef8305942d95734fb5733f37ffeceb1c2dae7b1396c3323de11089082745c28a1756f784423fa7ad68bbfbf0d93ff8b7ad62220500df6d6895788402c1f5c69c06dd9ef55e2401cf297184e411be87c1bba657f847208c0e750f94a3df92f253b377b4da 00ec52fc3d9c272ca80623e06b15c35f349b13548ef7ee400bbfa04196850b3b8cc7b239238c827f9b0a3160cd97969ce21d66752791f5896e0385b0527d4d77e4b9fc70f04d73b2 b8ed38501b61cd85507f2777866b4cb4276847c5bf1718eaaa503e839bb3063a956d033719e9d0349a379dfd4943a645 +30e83ea39a92036e22b7bed7639eab5e5be1d00c20b4a9b9afa9a0d1653369cbef363c119cc6f921c8f84663949c8b8dc9b743ac2b1861a480476e9b64c8f333f34b6fa0e1ddf09d49618ee4f3c1f46751b5595f0aea413d4ca46f3c26b974b112cbe99c813a96a4423764c069454946f213c5f066ec38108f947abeeeb02fb8 006403de7627de22d1dcf6b8da5af62f9ec59ec065cc1ca1311bb98aa439a6d5985619b17c17a70f59e17cf180ea6828ef57f5f1f8ef05680a9fc12ab7faad5af61e4e11fb45d341 ac90317845c48d6418b6ec697e567a10a9315cdb7b7a3793e25c7295e659ffc380de55991b3de046af9108be597923f7 +3ed244dc16a5cb292db4b1433b0ca3226913f07377faa20c6c1402cb4d026de808ca74a6d4ecdd7c4e662105bff6edb9fae0117c50aa053aef677c0750c7a446edbb879110030758912e8fa666489d702d8fceb719963b24a256429bbcc869a1f4ab9de9db89263e3684d4daa1df2ed94bb59dde2abba63793e5f82aa2e4db83 001fb980aef64254aeb9bb613ff2fc6967503db4bc1f337882f1566cbeb57489cf32e34f310549f41cba1b951f487453c29753a184e33330e90d4b973d2e406c99a239a5c3f96233 90011b6947b8e2d965a7ee6886fac06d1f133385bf115c9b05181d851de0e185315385bbbe15fcf38ccb64d736611930 +40343935d9423ad30f3fb1832bb08a5d20ddb3a55b59057cd275320db4a5835471c96cfb7d67f41ef860cf5879897b8dcf307bd1a52a6226847b768ea38ff1858f59e64cd635b51e6863773cc6c64b363ec47ca39266422406264668415c189e2f92447ac4c63ee5d74e95d1e6af05016917ad237f482ea0b02aecadd370a8bb 01d96dc09dfaf602789c1dffa5c9ba130832badcf180429660daadf4cf1be5cca92fe9713173861670eebfe3a0ba25bcc76aecac60a756f07b69687e05c7e25984a39556469f62b4 8df87b364379f7c450a954067e940da1d784f04fe3e0b7605ce0a84db3a7c9893dc799c414b00e0298ba5fc15686326d +274567f8841183e68c4f6c6b36c5a52fb0e88492e4076b9cd768bf571facf39dad6affeb68941ee326ee461ce1f33c26e4bfb3c9e0cae8241fbcc14cc69c1af68701fd0be3def1e87b7d52b682ebbe1cc225c1bd177b0886e3698a06d0e410a1f92c9bdf7239189f6acde0d0653815a72987671b415d1e8a70e685d6e5b14c33 009d98b32c8eacd135ffb8e13223690ef02c0c1f29ea8b4da193502c8cb3f39f9eed608c02fd457f2fb685ec4595e8fc8f388d26778d225d2b18c9bc8b199d8b65c0d1a6af33854a a2fc9239cd836e4f97711cbd1bffe6beba173a5bfbb0417786366c8113c127a41aab126dd35c89729d69197eb6afc31f +d9c99b8da92d3c2e40dea3c4025dc37770e867c4d2746c4d726b6de24250591a586c166c88acb8ed340e161d4c81b9d14c919a1b06f1feb22c5ce5fca2693bdaf4994ac72c8983c87f331473fd094eccb3d5f3528e69d487562fb5a65c150a8217192f8aabfa7adcfd0b6916d5000248fbbddf1ca2f38e3d9ed2b388998b7cfc 004d873ac744c4f68bb044783ad69e1a733cb8b8f483f2695bbd90c4211282036ad7914a53b25c3e890c6824643cffbdc4138d7ff457e3fbb99387494eb5cf2bdf1ad243a3a1e644 8bc9adbbc3f07a8f938048ac609944dc8ff4da5930af442af74b92b1fef38888fb52d09077fc42576aef91bb7574a217 +d2b88a01fa17703c99e5b867c645e98feec0d6d1afaa20a97b5fce9c23f0594460142af4e36a5739b8d26d3ba35a0263caa5429b4abba157f359fce701c43372500fd2ae1bc2ed80bfcaf8cab7016ff93d4a27f565b7e67fe7dde22bf02c48be12114fbff2421517c825019c0ccc72d927bef156140d7f0e9b6ee37af78c3efa 018d2eb947297a054f8a789771dd875b12b26ef057fb91235dff3b062916f85aab3365609bd2a38a861439c8514e33f174c198139354e63766942f605107cb1b9709b782622b295a 915376c905b08fa20a0fa2176658a9b244c8347af5357fa399eb42a0200411159e07b1f95b58220e0cbd6da8023ed3d4 +a704a1428cc894f958774368979fe075353b56790555386e3b043dc6a2919b94a11c7f85883f46b4d47b324d349c28c667bf9a000daaca1d7191f2a0fd97a4867aa9f72422134a690625408a9ea4b723704690b69152655f9e9dd5fa3dd94814d97dd4f13e85c3f9bca769491c2461fbd17e28afac00bfa81371d5039013da8c 00594fc0b7a5cc0216d2e78eeeb6394c8225de795f4b73bec48b2f4ede185ba622b59a16dd3eedf8cf2c94f2ccd6dcd205f64c97cf1b7f1e34129e94b5129502909f43940dba0746 b65dbe9871d4f8f8851c7cfdca55ff35d4c27890fd2287850128ba76d5baf57e91712b1bc207894eb7855e60bd0fd2a1 +f8a87c4acadee27a908718461e3b45060ae4ebb009b10a15926460bf219cb7e75dc3a993fb9a741b94e2fd71615c50f6df958568f452b2cc284f0516816bc0d2e2d45f663155660a26326f63f4aa42a6e1cc8462a2ec620a365257ec042f55e4047b62af689592a1a072553ff174dd629a4f51837780ca232cf479a68c1ebdda 00f000631106c5851e8ae0802b01e7a8a8540b427a8a3956a1d36f0600be89318032320cc420931d825cc964e823745c60aad3437ebc1c91d32004472e9677605fb708e5a71a0d83 b886a6ed14a18286cc00c721a7f3eac5acbc7d97a8b941a2a6c64b218ccbb30a5c5c79d818aa29e33efd310d52854c66 +10b5438294a77c7e517ecfe8f8cd58d75297b14116aa93e574996ec4acb21837e6297cc0e7e7b5861e862062f192f2206a01b1caf42c6d7181d02c7d62b76c2881f8479449b02d32c6f792714d8f70f0c75e81c7d9abb996be87f5ad9a01fe42b75855558d5f00df392b62ae0d258f3f67dbeaf07208952e679a2c573aca941b 01023997206341c6147c536d034a9c38b4012035dc2c9b7ef0bb9cfe65e7d788296f055d508a1fd957b2dc7f9eb10c27790f15f30d81670945e54a508c57b70b46b4a09f4c769289 a798f979f6b27373707df93c898b3d3d42748c221a48a64c0b295d85776ea7e37d0f1e72eba1db5400f7d2016694941c +d83a52d43216fdb16b1b40469863ca8eff4df9fa358deccb5ffd18b3e22a9d654aedc98f3dbdc4f5b4e56b4299e25d8a5a38d01b34eb93de382df1ae4d1c7f966e84b84c393d167aecc6f1192c4b42cae83748b1ee3d9147ce7de74cebd122695b455e8082f86e3e488fb0f51b3b7edcd579940d1cb9d045296e5e38f201b7ef 011ebf320ecf6a908ea5b868afb8e22246ce84e743e1076d6185ec65dd79043380708bf8da4ba802c3b93b8d15509bb7d7de9dc29f1e9fb0f0f2cb97a26698f955b1f7ef668122be a0d03fab49570711f95ecf5f95c78ae0b9ed62ae24de515569fb5d69a31c64a7ef6917683696f78b2821db15d6999a19 +eddf5553ed4db6e8ce72cbcb59fb1eb80671c884ebd68e24bd7abe98bb1f40806de646f4d509be50a3fabfa85c5630905ce81abfad8a55f4cd80208afffb9056bc67d9dd7f4660a5f924af2a3745eec2daec39a3fe36131fe9eea444b92d31f6a125f12125159ba095f89968a7028549466f41ad45668a861f671050d2a6f343 00746d5c824d78f42a1fd63d8fcca61f154ba3e75788b7a0b87f53e5420e23a935b02eaf67bace8dd8a8e7c1caee30154c2428e0a437cf12e235f41c416f92fb54528865fd4766d1 97de6450fd791615e4abd5671f862c83f954335e1328b447de24ad0d9f42735a92383011cac3763ba3cde6b02468c6c6 +3db94335f6d1a125309622c0a9d71bde1da09371f0285a93bd0aac255fa8f10a56074e0f6057f1b1aecf2d86a2319590ead96a2ad1336fe844e09339b456be32374ba2e659fbe9d0f2cdd83444d117d2ce3204ce4b4294dd05405634b84747ffb4227160c4e5c2c9da9815b0c6d20f55705f16cdbaa13d107ae666d707ccbe6c 000670e72ac2de50dd2cdd975a6cdab10ac45e37ef7a28c685d77447051496b5e161f8b1b93f6c7f32fce8ea05e94ed35fd7cb28c44bf51ea29cbaf5aaa31d6abca30a89430323dc b849b0bc82e825329022974296a2363a888ebf9786448edfac4dbd0ee1ef2240eaeec2a38ec9375bd345b7fd1b832f89 +69166ba40768d0a3930325405edfd85f3272f7b8e600b0b319f070274c91f9f03d0e6ec4bfc7b4445e91b87cecabfecf5e77c7301ee3c6b0affca2fa02c92216698705eb75443eecc25438db2d2fb4b24f4195d6b9c05c53e0868d3e58477100607ffdc31b18c40b4ad7202bb034e58653daec0f6b33c024d42a3fc84bd8f86b 00369a3bb96f884983c23281bcd04e24a3e5f6359f81e3c8e46f3f6b865eb6bdf98a630e90646275c587e41b546d3ca7688cc207afda15cf9b25cf83bd6ad27908647f3f9de59de7 8325721f6137441b16ddfb59eb4a0c4dec72d9fbc5d86ca2335ae5693ffdc84e0f639bc43cce6db6b7de605a9d164f37 +f64cb668b72f1e6dd026a478505c0eb33446ae9a2993bc7648aaed02e172fa9a0e05eeec61e756ba246c1dad7e85d3f01baf734b1905c5bbd1b08d833c2cf1e079eca75b866d705c407eea8618d23ebbaf269c7185984b3bd4117ecfb295ee6b47eecc8d3a78bb96552f6be314656f91caff793838226662c75cd7804b6bef79 0026717b039df834855511815d5665ff9b654facab469390ae257b7f0eb4dfe66ea0dc037242ed0c13bf229b8f7ff26da9b55fe4750d3451c62804aad493c179ae45d08ece5af085 b63ccf4f41a866410417f32a2a26002cb8b1510c9d4ac3b2c4152b0ee14c73b06ae565308bb9b84073d60efff63d22c5 +51ee0b98eb6a3e3c1afcb35a33697c048dbf61374629ac5702a57801fafbea4d6fa5a26c9d1b79d1c58257ac0106387fab2d4a1b7f8c0dadcbe7c830613531b3c209bc17f792bdba1c1fae1b7528aac53dc86c2094b40194577325c05d2258303a2d17c854e7449489c43991b6877a50692a6340a528a6b188440ac0cddd4c4b 01d642f2d393ed4abea37173e4a79534af87adf534ead4a0a1c46fb047619221e3577e6b8bcc776114d01159c736ab78af3e53feac339d7afe58be8e7a8ed290f1dad960f1b5de94 b618235ad662112ef223d99643f9dc458cba8f759fbe321a021a340c8d50df6fbd38a357e18ca3c47b6333e7b28bc193 +feee50aeacaccb6b1c3d95c6524044edb78322ee836d8159c4a4c2cc6982480567c4c6cc4806a564876622266e1ebd45f2f4be851b79da025bd57d0e6acce1ec1c8c255eb89713a1e4897d4ee0f7a248b9d4bd3ad5dc0e57f60ebfb65691e164bc908956a019083e923cfd33dcf37c735af3462768a1e14a8051d7aee74d5228 008cb70be29e83f697a3e2f67d86f1c1ec9a163b5335cb4a06004b6634948bf60b8ad9df9b27d2bedc4975265ce44a7884e57082d521320ca4372d38fc77b18d3fa05ad8aa5c43d6 977a567d746bee40f8ac0923e71723c7c77ab254949b0add6fb58d0ce5907d749c6fac396b79f5af4e8b385b1cf708f4 +b115f7370d6a93a90fd9dfdfb292956be34b61992ce1fa5627c5e928d74bcdeea66d4040c473306a0070fa8363c4303bea32f73ea3639b5c6676fa5a1d68a2cc1f91f00580d7453a23ae70af4cb1f1657aa82c5b305374effe5d67d559e46a6cee6360503d21070506f1af30bb000d2f2f85caa6465810f89968f33abae81cb3 01eef463771f9c6285f3257691dea0844687606d4dd00b6020517f190891cc1be97cfad21d147ed8881b5a6e19b22ceeae30e1132476325f2de0e9af2e14c80b8c780a9d2d6c96de a1a4b8d99b1bab095f7b5b185fbb1360169d9f9afac4565b1723be29d514c9da1cd706825a2660a6ec4e0ac56bc9ef3c +726782eb0d9720daa64e4a77b5d8dd67a1a193f15eb6b5162e3d89c925ba63b7c7e1c4bfc8d6f11915b0e14d16ab53ab015317bd5958b0beb6074199e05181915496575768d026c23e92e06016598de008c3718aaabcda8b68bebca0a73ecfc7327e8d3646106b7d114dabc46cfe56265c326ee56fd2ca87abb5bed8f997c735 013bd452b0880b101df1aa65724fb60d5d85b37ed5419027481661a3617e0fb37bda1151b9b5b41f908ba832011f7850b75a07b678e5b8cb35c5fc8b94a625e4398cd5ada2b04cc9 99efcfead6d3d2ec95d891508dab9bb6cf8526b574000c4adf88535765f4ae53cdd504c76d409a9dbad1963eae88dfce +1c2418243fcd89c6382b7c3b2a8c341f26d08174a9e9296c4a5c98c5793a0fa48dce51e30811a96b515aa22bf9af89a43de06d696be1e531c5dece1f69fa6ecb7f20be063c602a16454ddafb14385ae3f8246c3f989d0566e06e7ed1864502896ea19df8393259c4dab3b3380a4a80b4103cbef4f38cb69198b7cf74ce94883b 01288141ec2244e4bb3f62daf4ee588aed09ce22be55e3d42e9085a947c1f8cd16533635d170bd64ae0b417346fa4670c25d41387acb2a8e14407a1931d9f7c5358a14eca40974bb b985b9271ef8cf9ffcda81fb5030cf8b30f50732faff93da8ae50cc7ee00f71be8efc217e872b56973b0e97ffde758b8 +1de4b642ec7220c64b91561caed7832044d6e811ac909f3b199cceb0d8a7db91bcdc801412044f5c34b355b95a2c6170fe497f6d5259bc20715a38cb0341c88e93029137e94d895bab464bca6568b852340a5c5d6a225475f6eefe2fc71ffa42f857d9bab768ccaf4793c80c4751a5583269ddcfccf8283c46a1b34d84463e61 001fe06b94a27d551d409b0eb9db0b163fadcf0486e2a6074bafe167f9a3b4ce8ac11f42cf72f9a1833a126b9473163d29bca2ad139dd1a5e7fedf54798bf56507326fae73a3e9a2 990888d747fb0f55dd42b4ea1f25205949d671355c49a0c3a844cfb1b06e95f2d4580251dcba5fe64098a45e5fc3e5d1 +70279be7d7ac72a32606642ecd81b5d4d0f95fbc3c0b07d85c16adf2788601e44dedb8e55e0f9e0b4ca3ca35f5be7511b0e69224a05204af67aae11ce154af6d594d47f6e3142ad183969544aa95cae1edf42bc699137f60178c12b10a67698e37ab9f3edbfb3acdf1b3513d62fe3db33b16cbb4e1f9dfe732c107f9d0c953f6 009cdc7e4945c485a41728f83d5188f539e372ff4fe38fffcaacbcb4522428e4f93ef4972556f4398fe17bdd885768f0fb5590df495badc794d4d274e22f2f4a2535555922fa43f9 90f53548a2daa82303d9580bb556de021a035b407e7a583c2f7717633a0365f1d1a6e1b2c8f11eb3da067f80def23373 +4d7e0ad520445b6a5cb46b7c77fbd367614044ae6004494c2b3a89089287e2836c73b799cd8c90139eac427ebe335804c3788f3728ffb8edd7f49a4bcc76a9e24ce3c2299cea88c04645b82033115380f81b0c1d823e470631008d350cf0c0dba1915519985b8a389ccd8c809dbd5bb5051a79e631916e0d052d9b6cca18e0ef 002bc753d007c4491cfb8ce0a6c96455acd16d37e02c982db216b8cc1afd6d10c6be4e15a3988b8b8b86b2b5b59a5c1939889024849317f27ee08a06bd8e7524d4ad83a1de208564 af0b0027c433e1894c60cf18f2b194663d963eb6013a7d778fa71d938182e929d9d531130764453bb9a271c2ab2deba7 +d49903f38b5c9b17542310425e59377f61f5b4f4740cd97371ee2116083f7758e69e7e2c1b0950ec6b76f96e3c91c721d6f2843afde8c7505a559c8a64bca2e665aa1131b75bdf86fb5b90581c7d3b61c2cff88f3fccf356ddf5ed282e27727be061b6925c51ea7f1a495f471dc8a5ca1a88bbe29e92338d3c9361460398965a 002082c6e61d0d72f040905d8c1c20d47b029f41ec68d6cbf43ce97c3b2a0a770557a33cb803c432cfbd3958fda30ec1bba77a6613c318597a85ad02b26c44bb77ca96d9cc1194ea aa5c7e4b421af5317ccc155637032cd66376945037aec1f2ecb501dd5dab029bb3bc5eebc88a180cb40f7bc1e705e7e4 +0e3f4afc3e7b25c1bf2d98098a5a87db1224d9bb45adc6e434732b8722a708ab80a1f3f6ef3c5aa70d2e1dad3e4416b12cc59171f05736c4b58bd084602c344f2f0bf3cfdcfe04c64e87597a99de23ded64b33607f7c273ec321f6462518715b11e91361e89ce5415bfc2ef520bfec378244a3bd2a4b9b6b3d68815f2f75baf6 00e298c93351323e2c5304015a4878997ae4e79d1c32f1dc64262e534d4f2c4b3e222356ffce746763373fdfb936fd330d3214a18c07f1205b20c9a941331cd676040ba1fe3dbce7 a0f1cd4a76adea73fb4809a1443348fb2843e2e75e39f8140e2dcb56958161d5c9162048fb638003d6d7f84fbdab479e +8fe32671f6927272fd3cd8dd4e34d44d27fac8c88b41bf9a48039e914990bf06d1633b38b9200ce1c2a275b9c55498e5da2d0707322c3ea0a0fd7aff598fb801628264e13047c8008153e8595a0dc95d54e70b882ac2ac9314d2b78e7b93922da818d7075215e354708994af66958954c92c074d132dbb2488e5a531c755a8e2 0104f4ad56594c5cec2a988c5596d73adaa5a81802b40110dbae698ddb1f0b271fd1479c38abcdb9b234e69cd0da8a0328d2135c287d5b130a09fa0b899058e7800eb2dfcee95c1a 8bd8bdf51b7fa17f79ce2ef1071631f089890d7caee2732cd3922e88d43e38cd75b7e7c939205e0bfc23cacefc1684fc +a8fa01136a0a78313a5d160c32fe5d1805eeb3730c18ca0c47818e82c48eb4c9e5b2dfe3ee5facef9ec59b68f4e6f3213f77fba9f8ba06dcde546ae348d343233883894f4423331b536f62373a495852977a51cb192cfbec04b5582b4ece69f345979e234de32da7a120138a057a7119735c4cb19099bf48bb202e7ffac04def 00c4989bf33b3136bcb4ba67906eaff2bcbc6567635aa4b057acb7353ee87ba3cb4cb9838f8f679729d5c6ed98e6c4199cf58605f009c6873a1b8321f83cd3c0973b7a3cfd9dbaa5 b99ad869d96483bc5e5e2045eb92b74a414e772170167328a508632cf3b1ade5b622a642a7d8244cbc34708d870fe247 +ba2d83b21c783d6ef2f3b7b10e910a418a9b9f49ae0fd37990335b3a3d15627846c9a12a1f31a3d0e062ad1bec5650606ed4dd06c30e50c1e8761a29f4ea1a20f74635d5dac22e5b787ac10f4ee82b338a641484f91771c128c84d31cdab0a6b9616078c898665655ee9dd4ae73d33b94bf091b064928b959623aa71ff73b4db 01a96f2ad56e31397e236cafc108087479c9823589a5fbc3dc7488d0e5d1199cf245d7f21f524cc0e8b47feca14c93fb760e631434a91188b32965053942f3bd39b3714f9d6f1a11 aa6d30193031e3c12d6b5eee37ed2a047070ff93874ae4b9e714f88309a5bb7fc67927c54cdaab928b8c793a5902da2d +ea2d5f4e9797bfc2f33f0fccaf530db2bdf8abcec00f09a0338eefdba318221ec0e050cad1a85c3f76b784c6e8c18da2b062f333eeff18b7b781e67d6d0a4368b8231a892e0f4103012348e5df53ac745e4d34e2cd1ee9369f97d4801ff485fc144b2007008036bbc07cb1c302a00054b54f3713919191e1d5052978c9c2895e 00c08ed8e0e0f8b0d0714b46a2164b933f8147692f18da97e5a108c44d5a5cf221cb50536e41832b83bff4026c6df156386235cf5e3e9a67b7cf9b2fa7707c5e0ff33a91601b8e34 91c6cd9b8d03f8d52aaaa532985db9569c25bd9054e8d736544d91c4261b6737d916fb7972b3bbc1075ab4e85e8f2b89 +b2293b0a09f41decd9d8e637b1b08c2efe612f33c9c0beebb6e05033c6103b958f8aacd125d7c810b4c287349f5f922d2c6ed554be597fb8b3ba0e5a8c385ed8ae70d5ae19685298f20e8d844fb5ad98db12ba7e5f45baed9045c3e86b3cac9bd55b614b82fd075954fc59bfc6124cbd68edae988596575f379d8921b594c75d 0144090a0ee38cfa21fabcc24d35139a99656911ad4f6dbffb77dbe74e7993edfa9fd63d2c4f6bbdbc8ec21ba13c9f4a3576b5d6e3abeab5af5ac81b1f2bb6d4c42dde645d854d9c 82b8333d8a5543b05bf1cbbafca1dcc99fbd39437074bf0dcf5856434809560cee9f3e1f74eef3013018158f82fd4c4b +acce54270252e7d9e983c08c993cd6b7e3caf482a9149036afe4665bd3d0662a6818047187872862d5718b8ac063477f693caf1a9baa8bdf2f36d411a796f2b46ab56f66bc94924229f8264016d6769c85d9bbb7d6bb042fefdb8fde1be026b86af2017aacfe38c97309b4689b23fff94f1de880064f1d3ad9d74dc804c41f41 01df26b672b2e3617b6b6c631d3c6be0cb49c0a690de49643e0f416215bcdaefc03fa9c708471f1d87476d58c8f147517ec8a14aa945ef001fa01984d5c3d81f7083ea500558fef4 88ba2541d1a2f0ca1e9979b72a79197dbfcaa7cddb984c4886c2275b75e003ba4a8866c19c5cd5d3e42d202d4a67342b +e25274ded4840df0d71d3369007118f002b83e2d375c78f7e29ade067db15cce21842611f3f015db2efec57da77cb9d16eb1e00a8c1444d48dfda569e29fca1ebf40a22fc646a9fd44460f0e473bde487634bfbdac2c312f66a1c2982c6fe76c54ac72b6c8cc9345e47cb319a974b3cc4bb40634df74b4ad7e18adfa9a71ddd5 0189918b832e9fa30161fdd927bfc267f6405335df3d66d225e17173af52a671138883bcb94c4403ca3e001fcf09ef4c6488934d6775af2b1da30a8f331579af2d0fbb530298d8f9 a3bbb4c0e06ca3461651c3020632e28539485c7e330a7703f91898f81437434383b8839d944dd5e112f280b5accc18ab +d8a4aed87c316012482819b03a1d91691f2ad11a2f46082497ea8f64880d686891f7da550b2ac17199c657d4eb9d04d5cb8eaa180f743b87d23b1c86103f9e9bb60f4e19f0ff9d160f180aed7735130c03adb62502e69be5c624ed7bda2301f30580ae0921b02e103a638f5623c02c186e3bfe6ff134c762a2bcac1f879a9353 00bdcc175eca3a399b944eb0334ff33c4fd130999c8ac0e7b52ac5b774fbad53ccc3a31024f5262b2eecfeb2104b14bb244307effe3dbe8ed25686dbf46a42c4b6f8e34010ad826a b77223a3e9d2b40589a73d12018fe9947121fc594d433958304a6f0df3ebb3179f7e23746b5f15f00e03f61b0b3f6d11 +acbaa5ffc4eee0850075c0e502a70cc7a897a919f5e7bca4e798385601a26f411fdae5466ba9f6b6d8d7f819a749b799fbf4a3bda9105063e74914e8583ed8b31ea4d22164bee6f14bf53afca269b901c80cb3265be32ffd4ca4bc4ddb83e11eff82ead6d75dc4aec8e5c67f35d58a8a156cd1c0351abdccc0c5396c8fbe6920 0007ab5a55a1d8ecb7f5dca2afdf9ef465569a4b0374716f604ad42a6e0271e934b09655e8e2529784b69b2894bb399b02aeeae30e9e7ae70a2a8e56b9e775bd978a04c728e3951e 8db61ef38b01ea1aabe7e2130e2c84170f8e6414054bdcbe713f975679bf00d5478d0c7c96c8cc6b58b2b46465ae64be +9a57b63a4f418404e8f5dcf3052b9bc04a4f6d2c33bde8651506d9cbc5542ffb9023292dea463111fb78913ccdcd182faabbff9164219b8900c7f9fb394f7d9678f77b18f8d58526ec64d7c1328953b983a7c416583e05a069cd76aefe26e5f5687b70abfbf9f58f052dc0863b4fc3bef805cc3bb05bf76a83235af9d6adfe66 01e7d4da72b1d82e17a066fe387f2a0a7fa4c60ab993ee09710531789186077f2f32b42ddda497d5fb57356383e1f96973df043307f0b6519430c3f0d40d62954032872fceb7dce9 b57893cd96c4574be486fdbc364f3135d9f1ba25b81728b332cfe6bcea15247d9b0f8ed8a4e99276569067ad3fdf10e4 +97b79c76d9c637f51294369e0bb52c4189f2fd3bd0607f91834aa71b3555605a89ff68e84fb5bda603f502f620e14e8b0c7affefafa2f0b303009ee99653ae4550a05315e551dd12a4d8328279b8150d030b03c5650ed4f8d3ba7c3a5361f472f436b200b321e7863c771e20ddd7bdf739c51de3676f953a5501e4477aed1bd8 015b7271d4319db5743119c8103a7d4c6d57e9c62f3eb93762156d2ebd159980aa57cea948e416717d715a2e458851f1b2e9ad4172bbcc53861db29c3ee0ba8e82617a5866170847 8d5bb05ed382861fd4459eec9eb39a0aa7d0e1e0a6f4c3845025e1ea15d02a5c5c208d85a23dead3655a309f470bfa81 +564ad0e37c9c37a60872a4780a723d08d1159ddc77bd834d74c1025cdf3cbd5338c3fc07a904fcad9b979b2a2ceb1a0139af35e5112305fd662a57af6312624b9bdd3a64849f95f59a46ca8feb2ed56f87f258518947474c1729275c4d89b7dd286ed65f286cbac76002cc63b92a73ab6bd13c4adef282f32297e441bdd8fd36 007219ea7917d174a5386df985d0dca798ac9f8e215ab2f0003aee929a2dbd91e37fedead0ed95b1e8aabcf516bdf54337b4aff7ace4c6b3179f2e919a49db50a41c9d4d58d4f636 a15d903eade44866919ece6c652180367d13a3d27bfb9568dffe0d8a2e175546dea786e4edead32f650768089afef74c +072ed5b14754fddaf54e20da42432df49bef38f4a3b1841b2db457ff86c44880727aca945770adb41269df41fc17f6a687bcaffaa45a3e59070526ed53b8dc3b78cf9a80a85461eaf4b477e44d5ec4c2bab9c05aa747a5a520b35fd09e8b44539d060ba1c3470267e0dda111b15dbb587614a46e1e477127f963a16cf3a43ee5 00bc623152253da24bf8d752bd78aedf7d5f6a2f889453ccdec14e10753335ea8bea83fd181a1f3680ed50f2324fbeaadae160cc85831750e021f3e44121ea1b1efc29a7d0069479 92cabbe3c49fedaa3a22222f2a9edfffa0ce044601fed8d61f3180c2595f1223d3ed9e400e9092f0ba1c6db984a47ecf +e660dbdf3e61af39b83b95d3f1970f66d616f03273f7dddb98f768452b21cd39604a31cf80590d4a5e4b0d4917519e10fd325dd4ab7a52d70d154506329baefe0d5816f514ae109483122b4fa8fa1ebd7fdf1fc4e21e8d278a50c05d81c8f489596633d949c6c8fea96fe91430c01522a5afbd5042be8aa47da04581b2bd21cc 00645947d981d258f2954558c31022a3b6ba5fa7b675312f794cb61bfff1d9ce87267e4a1dacb7c8fc58624d31c85ebe22f80d26a620fed5df5bf38515e0903f0b69a606048197d8 952af21732d9d186245c044f132ef786b14635827acb55e5817a10c2bde629c6c25f56b4f231cf1d6d062f890eb4de28 +8c9acbdc431565feae60e08bc7da113e12372ed373f1e1fdd581f98c8a7b0c79ac4aa42c7ffbc963fb4970fe26c5b5dd314b7051fe971c1186ebcb5650f7f7011a924de893f06961b8c75da7bff331847feead4abd2e8b9d6ecbedac18f4eac207b948e6e4215e4d5cb483e5c66ce7ad788cb89604d3a3e051539094079e7bdb 014cf93ca69d94ee8fbea0c8da9d76aea092b73073d8f5385b65c6dd4d567fe86bc2cfb8e8be890c3c6cd9abf7dc3a17eaecee3d7a9455887863e496c48dc3e47821bd3d825b6bed a2f7a55de569a77ccef9d54b1577d4f1dc1df25656604cafb7b2840ee82383fb2e754e6da849e420dd62a5fb45b1abfc +53ef87d6ac7b9698f40b3ea9f3442e7b64207b140b7f66f73fb7d5f8f98452d30a4e493b6c0e3268371e88e612b818d4d847f032ed4983817d020411a52d81fd2a17b58ebdec199d817c2a8ba77042bbd747a6fd4bcc7e844ea829fd8461b389aa0b5957d92962b6d4e86385a8fbca90b8fac40944607117e9a4ef6dccb8fc1e 0033feeaaaa28f16bfaf5ea9c7319cf4561ba4fc55327a8477b6cd58ef6ccad3962ee1f3edb243f3a04e7e49c8e23509fa2d63252adb186b8bc7e9255cd61fa9bc45242d42da3a68 a82f41d195e22610f81c4cc93dbf3454a8fd3fb3ec4d00102ea7eca8024dca5c45042863e44ac0b99921e473d1fcb3de +dca1b7a9a313ead11c2d54739d9017ae27f9d08b3544e418aee862bb57e427636cb6aedda28e10f12aa15d2355f4f8ef112a86fec5dc46e6acef693cb8fc37c3e4885f3be3d3ab31ea4d73a0de904e95c7135a149f77b621d642f9bd8ba192d39cfc58b6f19a797c4f3b4f3a87054298e3ce5eda0ff7f44f8134c9a108285dfa 005613dfb53149bf5fdc4e08ccc1c752b0b66ab43aef2d008ed40f3df40fcbb2938d2c41e3ea2dd4428aeba9059a97efe5593119673866a19d27a2ee37dd357e22b6bc849e7e22cc 982e6922a81862954ee0daab38d84db73681ebb3b335eb5f5753b0cb8328d06d5b2587bb2d402de889064b9a7a857644 +aff61d62c8f5c31bbb7d0a64a6ac589e918bbf2f13e7ad13abb9ac26405e267249a7c9922139bc28140833e10976b87e91cf28285274b2b48b63d24ac94c85c70fafa78f8ad05955c0ce6c02b841ee196dab12306e3e3d6138371217e2b474f7e67a80bbb78a47e374ffe2c9f86292e471c551da50d46e7b5c8331029f369767 011b92c8b72b86c51903387a65aa206988d443d1988253329ad3a89c902ff1ef8cf73b7f2e4aaa352443bcb833712d94c3e637ec12cbe4c2d4606878576b17fae1512fc77785b737 95c6315b6107950dd6800696f4aa90d8043cd71c93b6b6881913a11a86ee6951d2a50955842fbd38d0ce060fa8a67aff +721017294f17ef351e41256b57a64a79f3636628c4bcbe676ac9a2d96076b913dc4b246c9945183ec9bd2d251441b5101eac44e2fa1bef59dec03ccd7fa5accf3b7d094d68dcf78c8de4e2f19f56bf0dcb3b66b9421ec3f8b353b9fd74feb2e9affe0bf9aa421b6f03eeba3ffd58fba56b3ebd094880e50de01ee62a108a24cf 00c3c90d5ce4375a08b85575faa78ee6bbd9e5571ce5a90582042617b807339c282cdc3b003d82006264b1c08c20af4ad4549fbde53d262facb98d923d81b8eb6093374b6a1e84cb ab6c049e88c2dfa8d61992452731529e6239f4be7b66de041498a12a2d58fed6f6ffb2ba2b45a25ad59d258cb71d0574 +e2d1f33681759adb7954bb5248b0db3c3885fea0d4c1c0c226eb1e6d2d3ef1b9ac281a0f1c2fe5175b67114b6a501e2426d1454bd5790dcbc4c232cf06b017de8a9bb39e6033f1edb5003e8de3b44cc3d6150c3c952afb442952483cc688908337b7c1a8b5c9da70937ccfa98b2b0098c530ff848010b8e8ee0a8d65283481a8 010f184c16228d9034271332178ed485d10b6aa76003efc160d63fea26fbbdf5552205ac7df0d8c852a1210cf0ba512f20b798827b36ad56b12a826fa7dc1db45aed264ca6822659 93603bf7dc3d595010d17983d7d496a06ad14897d0049b41bb7ac84da5fdeb8216770643414b9b40c477a81088b5451f +414fc5d2bd56b30040e105cb891788792da595583b11b8fcc7320f40dbf64d9263532dc57344dd17573c95eedf851668b5d552e8796af205f3a0043af1a829fabc2e93d9af9091fdd9e0fcbcc9d6d9ec960aa60e4e2964c29a2f375400366480e513f63d124db7745847310e69a38c8455e4e602056a6a4a14a8694155e0a9bf 0181baf9d497159f837cba58a11ca435c442e5ca792ea559bff9f6a1f562c05bf6bb5914afbd1bcaea75b35f88bdd832314b249a5298622c89462344d3f28a44ba3d059df432fc71 82f1374fa3d40d4a7570f8d55fedc7220b10c209543749a4b6a3d7c7c0f3228deba1ed2e85b9e2a3d66d4cc471903174 +3b592cc8972a4782870e079b82a50f84b4c2d8ca90bd500d1ce5678982e266c391c556d8162ac3aab967154d072dbc0ba1dab5545cf2651753dee2881eca5abd412fe624bf3f9d17d33692d21ce23ad15ccffdfd250cb1949e73c9e40a64ebebb03852e92692dad1d7baef97fe109f35b7a492b343d4b643a4a7b1723eaecb64 0083fae86ab96bce99a53e50b7eecff38e4e25b21c4b0f6a4986915de245eae24f16b6a00a4db159ebc27f5a6a072da94ab6be5bf75f5eb3f75c4452bf4ea7014392eb1e02706fb4 933acb1244de7b2f9de3e1ce85b83ebef74cbe52a87a2efd5c94176eed62fc9ce9b308524c4ffd3f48d0c619728f7592 +0079a02cbab3dc02601fcb5c8607d555beef7cd71a66911ab6514a4ae21c5a9c0e166f8cf5fb198ec5a49a96e17cf041f35f00406b79270ebfe56dc6b8417d2529fd625686ffbc8f69685aefa2fd30a937c02f25b48be4679e6fde821de928b33b12470867def874bb8c7c8038ab6594346a2c44b39210d3610994ba60a05e06 01a663efa7bf4d8479bc535fad71e9b5e4f4281aec55967baa008ba17ac2f89cc3398d30573edef29d590fddce8cb157f655e92779f59e7a18d0327d02e7daf4c1216143b3688fed 82715cf43afbac74172070d276f0fccec9beb1dc8cbebd1eb24ba8d39840d09e5a7d7c05eace08a7144061aa2c0ebcfc +88573bd94ef50459814806efa868ebf92b066fbc2f7a4be9d2fa06b9dc1a72f72d783a6bcbc107b18a6314511bff217037a2252e7a5cd34cf9d5b2fe9c7846931f0133b2e95876cb800dc4ed7c4a4e4cc4f1195acf99fb0ec224b1f8fa8af71f72d390eca9d6be3879032a318734a63fec336c79035a43f70271def10c4955d3 00088d1a2c0219696a94337cd56516252b74139ea0733b17fdcbf7692c3e5f6c3989e5da2aaed7468e65a5d578571928ca273ec3b6aa72cd196f560f05095cdc8346e5d31c4c2e0c 81768d73e8ec3653c421d743ac176eaceaffc448484ebc2f42cdc0fda6b4095c90c1a028d7bd36586f9209f552750590 +d0e02045ece6e338cc8ab41d4a064c982ccb1748c48fc2fe0a6f10bdc876094358a6a90a45facec798a83cc95c6795cf0f0d7c66b77e22cb114c1432bfdaa1485ff35b6a58107cac3b7e58cb4f6c87c68db60b751e78f1fdfa54b8923b98caad0a4f31226956d065c083ace5f1e9e91944dcca51879d782e40358d58ca758750 016cc8a0fd59455ed8d4de561fd518df2e008f7dfaa5f7f29ac2489a411e233917b43eb3ebe2596fc824be58871949545e667dbcf240dfb5e0c615ade0179d9ea2a1b1ebb8ab9384 88bec98249c1a10cdb0fc5ed0a40199ca013e5a17bf67c4fb16c8ec942ac3aeadae6b2b1600f988d5b872a2dc6ac308a diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K571_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K571_blst new file mode 100644 index 000000000000..e5aab2c11a38 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_K571_blst @@ -0,0 +1,60 @@ +964ad0b5acc1c4db6674e86035139f179a9d5ec711b5bae57d2988456bb136d3aade7ac9ef10813e651ae4b9602308b071d75a934a6c012eb90c5eb9b2947b50fc97b1d36c5bf9eb13a7b06c94212c3dcdab402a563262298defff62b836ead1f78f9d20713710fb48115cc5045ba15140fbb4bdf516e4150d830d02cf30963d 019cf4f4d06825499949f9e0b442586fe1bfe3459813a2b92cd8de0f775a4735e02655702ead8e60824180761808d9e816d60bdb0238e1e8039ca7bb63c92e1cf8433ef447e64ead b4840da290dbe266d851564d13b13b2c3b6e407aba3d10e5370ac4c201a4d4005a5eb098a3bc1ce64de8d32689558fb9 +baddec4794effa668cde267016dda67bc70b847919a9aa595f93ba9dc27354399ef7a607fbead31e57a8ce698beabb10f313d393980425e67cf95be45d512f00e950c0c5409573ddc3d556f23daf056259ee8914e860562a674311452fed780b3e0317a7fe93baa81fb98df3ae4328b28ad0ac8f8ea33efe24faee658ad026f6 0098521a732e72ed945a549afc92318fef7156ed1d1ed9bab93b581478cb2339eb32bcef705c9bf61cf2873ddbadff8ff3806740a2e30ce67d1807a8179dfd5d952e6f8a583baf81 881e9283972fbe282ed3cd1d8a839d37ccffd380ad968431755341c10738c8cf9fa848507755b919570603d763704e54 +7ef7138fc657492d229054f8a50dcafcfcd1dc06f1c16640af3f658907e2969248b54416066eb119adbfa23b8dc578aef18bba79610b9cc109394b900a25e55a779230bb858b2ddd9499a7775d392328db9177aa9571c2f61dd52010b48502154e914a0c55a54edcc04a6713cf7bda8744a893926118b09df877d1a4f3d95e8c 00336fb21549e397a190beac38a1ee10f0551952da15f71e11dfda415e5ee08da2356f114d450c661f52b2b32cfc7b9be61732672691a079f0927989b7e9f4efe6095a242155b641 8030aac046681a192a51e44cf3382393ca4c7c26066345af4692dab1c168b87ddd080248dbd295be923baac339857e1f +d58e1ff1d49a471d0567ecf8f29173dab5fe5f6184ab4cdd095c231fa7b82551f99a482994a46c3d8ebc07297fc9e952a5dee7d5f199b119f6f8b250f8fba45701ac252db725e75c4da27ad77d59a4eac448e54a277986740dfee6596811e59afc9755e53d24b826c09e497e29e69a22bbc85be11763064e9ecad7ae66458ca0 00e287ebfd9ba294128cbd484fc5121d271cd33e685bb1804f09b40aaacf64b5a9f2cde9b30a4a02d3a9bda97d92f46bb8787b3c61f280b1e1a0680f1f0679d3bb34d53725d62e52 a8f92ff8a20dde23929761c954162a9810dbe2050f8a92ecda054044d6356e877565c8921c0eed2e404ae1a08e14a383 +4949ba765c14c31f68ee0ca26bb42ba2edee63537de4a6f5c42bbd862c21288d6ff48145260365193c6fd2b56dfb014da26b8a483776b717c6874f627c9a622154b824565b23e178240f53ee9748c45759ba5c035b584df0f09504e95eb9bce0301653aadb860bb25e6ea6b9606e0ec3bdb8089e6aa0d5763d331757490715f9 0149de496fa8f88b2741864d0c35b3df666b87179b7bd06cd426a45f13bc87ea9f50dea85e1fd02a532630e0e3a231cc3e7fbb7c7ba85b40cff1124e72c677c6a3ea6aa40ffc64b7 b1d7e26a7b1f0b7e44aa6ec7122699ac017cc0fc5011266475c2b2549a38847131b0d8f9584fb07c2f715ab36ae8fe01 +5bc63e5c50b1650f0ed4a599960f1e4e11f6c151b2123fd71d9e3c44662312a74b6854290628e20b30eaba81555acb2fb49b640bdab2528619c7fcad0f2a2880c7ea232d427d7c935fba2313370fda8863a7e7e203d63ea15d0cfa083e716ce6068c63fa616ddc225c9e413e694cdf6b355cb1293af5d6cdea51168f5634e878 017605d7c5873d870462375d741b4bc6375f3d47f7f5e9d998917adf2137a81e63b66917b3dda8968930c4b850f2270eb3187fc756e2beeaa67fe0d73053e6cc0ff0004a21250551 b3a3e66a35876759966877fd178cb2b15e0342e47c1fba3e355942cb7ed2afe7d8127353113ed43133d5b7f028f1024e +610f6633718e49d232b3798654095e2efa0de11f41258b27aa01956480c870d901efa77e109d5f95f1f5101d3c90fc51312d9b3019d2e42e0067eed7b457dc7fbe5466923b62c83d7347e4dada571b57813bb9c21d5e308519b8eedb7a7706508ad04aa69698e03636eb30fd9fb363ef3a185756494ee01175b16847f5b68076 009214dc2da0967912c31995cb8f5bcf4bfa832c5a2d3610f3a9857e5eee7c77100d599d9ed003b4106013155dffd6c48859b846e45e0ddbc5fe24f4891c9b2df51407e9cddbd974 b35dbbc4c1ff0d4d6bea6193c69fe022c89171c1091f8449a34c8c302f9e662a835e9b7844c052a5302bb80e23c59155 +c548f0546cee0c0400401cd540a0aa9377f27ac64492e6baaf38e794db4df83e64ca3d83b67bbb46a6c269c04c2725287cce0dee984a0d468c9ce495a7e554a6835d72c7493bfe88dbd5a044a148c89001b8087fb03e57c2b7212d0b175d616333a9affd8a1802dd49ba9be3ab6c6d9f99a5578d26cc4707a5860c6c804d69ce 0042f2682e9ac8b76f3c0880e12c292524601dce9ea6982dcf68bfdb0d3fbfb50dc9229e54149ef09b95bbf624eb04ce1427077f30d8536be9f69970ddb449ca22ab8368d2689ed4 a56dff6cb8080f472e6e49f61a23d5f000e56622150be6091536a4e33baf4f72f7dd10c258316711f029236ab740a387 +9431c6c5237f6b4b35682a0c32f68752035c8b295a1763c5dbdfd73466cea64a00ecc11356d02d2a9211dc54548f5db1651e4471898402c887fbf45005a3bda271df0158c98319d4d6751b8ca6b07100182957d5fe0d97c4e2294406f83e9afcae4850bb089f2252490417b5afd8f07f4c795fa84c9c7cdcce26bd97273c0072 017ed9a9c75cf66528428e85b0f019e3488af8b893b12023ff1b4ca9c3691b74e594539afa0f4d7c3863d15399b862f15e27bb077392d6bbd546ddfd46728c75177338466eb2f4ff 95e0184740411ee515540b88615703db2465034ace42c294b634ae4396aeca886b676e809d4caf326deeee26466594a8 +417cd5f60416f17081d2c70e9a510114e08be83573bf9deae75fbc3095dffc8a7f7325f61f9d6565381710eda871388cb17619e4448836076338ee309a2bba5f737319002e259b4a875cce1bb97996101c9a7abe0278dcac203a712f0809eb3c4b85a9c380550ab0bbc5067a8edfa78abf03c09b5c08f21714e1022ebfcada4a 01bcc09b3f2f1d26ab9955bff7e8c0f85c8a61293511a196b53d7963f4a4503849c96fb4daa68c9852ad9185e01a35f0bf298e34a09ec352cb6da34f89a1f23e8ea27712a8f43aa7 85a64267a150871a3c417b3ef9553fbf542f3e5a8f3beca17e180f3e26b1032c080c3a22c2d4de0fe5391035138397cd +eced8c412a153a643ccd69596389f83b6a36880286f8aeede503452bef8305942d95734fb5733f37ffeceb1c2dae7b1396c3323de11089082745c28a1756f784423fa7ad68bbfbf0d93ff8b7ad62220500df6d6895788402c1f5c69c06dd9ef55e2401cf297184e411be87c1bba657f847208c0e750f94a3df92f253b377b4da 00ec52fc3d9c272ca80623e06b15c35f349b13548ef7ee400bbfa04196850b3b8cc7b239238c827f9b0a3160cd97969ce21d66752791f5896e0385b0527d4d77e4b9fc70f04d73b2 b5742df69d412853cef01022bc81a4feeece8a70a81bdede95cd5b9fd7c93445f8ec1fb4a2bf24e0edbc266b0fe6d06f +30e83ea39a92036e22b7bed7639eab5e5be1d00c20b4a9b9afa9a0d1653369cbef363c119cc6f921c8f84663949c8b8dc9b743ac2b1861a480476e9b64c8f333f34b6fa0e1ddf09d49618ee4f3c1f46751b5595f0aea413d4ca46f3c26b974b112cbe99c813a96a4423764c069454946f213c5f066ec38108f947abeeeb02fb8 006403de7627de22d1dcf6b8da5af62f9ec59ec065cc1ca1311bb98aa439a6d5985619b17c17a70f59e17cf180ea6828ef57f5f1f8ef05680a9fc12ab7faad5af61e4e11fb45d341 ad2151bc000be3eb0ea5e9b05d7a7e2c79be1a91fecf5e69d021303da9d02654c2355b96ea22af193359e9b03d13cbb9 +3ed244dc16a5cb292db4b1433b0ca3226913f07377faa20c6c1402cb4d026de808ca74a6d4ecdd7c4e662105bff6edb9fae0117c50aa053aef677c0750c7a446edbb879110030758912e8fa666489d702d8fceb719963b24a256429bbcc869a1f4ab9de9db89263e3684d4daa1df2ed94bb59dde2abba63793e5f82aa2e4db83 001fb980aef64254aeb9bb613ff2fc6967503db4bc1f337882f1566cbeb57489cf32e34f310549f41cba1b951f487453c29753a184e33330e90d4b973d2e406c99a239a5c3f96233 890ea875e1047b8d4f60b070793752b5a593d5e0ac1ba20ad182808e72d61dc46019268c393d79f3b1a3a1cbb5bdaca2 +40343935d9423ad30f3fb1832bb08a5d20ddb3a55b59057cd275320db4a5835471c96cfb7d67f41ef860cf5879897b8dcf307bd1a52a6226847b768ea38ff1858f59e64cd635b51e6863773cc6c64b363ec47ca39266422406264668415c189e2f92447ac4c63ee5d74e95d1e6af05016917ad237f482ea0b02aecadd370a8bb 01d96dc09dfaf602789c1dffa5c9ba130832badcf180429660daadf4cf1be5cca92fe9713173861670eebfe3a0ba25bcc76aecac60a756f07b69687e05c7e25984a39556469f62b4 a6129c968d5de4bded1f75b03f8fab766e8293dea4bbb13e0c5f50ca836275be4fa5e3d3001e9acf3fe5d050bde93684 +274567f8841183e68c4f6c6b36c5a52fb0e88492e4076b9cd768bf571facf39dad6affeb68941ee326ee461ce1f33c26e4bfb3c9e0cae8241fbcc14cc69c1af68701fd0be3def1e87b7d52b682ebbe1cc225c1bd177b0886e3698a06d0e410a1f92c9bdf7239189f6acde0d0653815a72987671b415d1e8a70e685d6e5b14c33 009d98b32c8eacd135ffb8e13223690ef02c0c1f29ea8b4da193502c8cb3f39f9eed608c02fd457f2fb685ec4595e8fc8f388d26778d225d2b18c9bc8b199d8b65c0d1a6af33854a 891b3c2094609be95ab2a8d7d32d9d41bba95afa7f38516973f33a8ca668219a02ff1ad160465b9050027b49572274db +d9c99b8da92d3c2e40dea3c4025dc37770e867c4d2746c4d726b6de24250591a586c166c88acb8ed340e161d4c81b9d14c919a1b06f1feb22c5ce5fca2693bdaf4994ac72c8983c87f331473fd094eccb3d5f3528e69d487562fb5a65c150a8217192f8aabfa7adcfd0b6916d5000248fbbddf1ca2f38e3d9ed2b388998b7cfc 004d873ac744c4f68bb044783ad69e1a733cb8b8f483f2695bbd90c4211282036ad7914a53b25c3e890c6824643cffbdc4138d7ff457e3fbb99387494eb5cf2bdf1ad243a3a1e644 a16c52f44079322aeae91e3c4806f9aaf6974d7af9aa18c62f9f4eea4eaf590777422fffd2bd63e740ca4d59c6dbdf9e +d2b88a01fa17703c99e5b867c645e98feec0d6d1afaa20a97b5fce9c23f0594460142af4e36a5739b8d26d3ba35a0263caa5429b4abba157f359fce701c43372500fd2ae1bc2ed80bfcaf8cab7016ff93d4a27f565b7e67fe7dde22bf02c48be12114fbff2421517c825019c0ccc72d927bef156140d7f0e9b6ee37af78c3efa 018d2eb947297a054f8a789771dd875b12b26ef057fb91235dff3b062916f85aab3365609bd2a38a861439c8514e33f174c198139354e63766942f605107cb1b9709b782622b295a b58b7cba202dcd1acf54a6e89a609b68bc8b75481b4c9068a169f7ca26f6d4d7d36449619517135817ac31b18ab390e6 +a704a1428cc894f958774368979fe075353b56790555386e3b043dc6a2919b94a11c7f85883f46b4d47b324d349c28c667bf9a000daaca1d7191f2a0fd97a4867aa9f72422134a690625408a9ea4b723704690b69152655f9e9dd5fa3dd94814d97dd4f13e85c3f9bca769491c2461fbd17e28afac00bfa81371d5039013da8c 00594fc0b7a5cc0216d2e78eeeb6394c8225de795f4b73bec48b2f4ede185ba622b59a16dd3eedf8cf2c94f2ccd6dcd205f64c97cf1b7f1e34129e94b5129502909f43940dba0746 86a999a26b168e167d239989ef7db7209d3e78b8b05dc45e2217d4926cff117168b50f53e8a29aaec26088310daffa2e +f8a87c4acadee27a908718461e3b45060ae4ebb009b10a15926460bf219cb7e75dc3a993fb9a741b94e2fd71615c50f6df958568f452b2cc284f0516816bc0d2e2d45f663155660a26326f63f4aa42a6e1cc8462a2ec620a365257ec042f55e4047b62af689592a1a072553ff174dd629a4f51837780ca232cf479a68c1ebdda 00f000631106c5851e8ae0802b01e7a8a8540b427a8a3956a1d36f0600be89318032320cc420931d825cc964e823745c60aad3437ebc1c91d32004472e9677605fb708e5a71a0d83 a537c87c62b3306f6e6563ac1efa41e16ac2ab382ee231bb129e751752b43004411f64bb035c30a9ca76e1abc98ce659 +10b5438294a77c7e517ecfe8f8cd58d75297b14116aa93e574996ec4acb21837e6297cc0e7e7b5861e862062f192f2206a01b1caf42c6d7181d02c7d62b76c2881f8479449b02d32c6f792714d8f70f0c75e81c7d9abb996be87f5ad9a01fe42b75855558d5f00df392b62ae0d258f3f67dbeaf07208952e679a2c573aca941b 01023997206341c6147c536d034a9c38b4012035dc2c9b7ef0bb9cfe65e7d788296f055d508a1fd957b2dc7f9eb10c27790f15f30d81670945e54a508c57b70b46b4a09f4c769289 87a07e81423a307369bd4d343d5f30de83ad1f9a4dce144c25c97c380545caa4cb59f41c2d47ad3a70bf22b8a40a6c95 +d83a52d43216fdb16b1b40469863ca8eff4df9fa358deccb5ffd18b3e22a9d654aedc98f3dbdc4f5b4e56b4299e25d8a5a38d01b34eb93de382df1ae4d1c7f966e84b84c393d167aecc6f1192c4b42cae83748b1ee3d9147ce7de74cebd122695b455e8082f86e3e488fb0f51b3b7edcd579940d1cb9d045296e5e38f201b7ef 011ebf320ecf6a908ea5b868afb8e22246ce84e743e1076d6185ec65dd79043380708bf8da4ba802c3b93b8d15509bb7d7de9dc29f1e9fb0f0f2cb97a26698f955b1f7ef668122be b36226212696335176a65a4dc1e9ae87205f72d8e21fafb8aa0d86c9967f9ca01818915479dea42de729eba0de2430a8 +eddf5553ed4db6e8ce72cbcb59fb1eb80671c884ebd68e24bd7abe98bb1f40806de646f4d509be50a3fabfa85c5630905ce81abfad8a55f4cd80208afffb9056bc67d9dd7f4660a5f924af2a3745eec2daec39a3fe36131fe9eea444b92d31f6a125f12125159ba095f89968a7028549466f41ad45668a861f671050d2a6f343 00746d5c824d78f42a1fd63d8fcca61f154ba3e75788b7a0b87f53e5420e23a935b02eaf67bace8dd8a8e7c1caee30154c2428e0a437cf12e235f41c416f92fb54528865fd4766d1 851328342d3c9ab0071afb9325bcee5b8ece217e17575ba326fd2183717d3c6b7e2f1afe07ed34efcbba32c50f96ba6c +3db94335f6d1a125309622c0a9d71bde1da09371f0285a93bd0aac255fa8f10a56074e0f6057f1b1aecf2d86a2319590ead96a2ad1336fe844e09339b456be32374ba2e659fbe9d0f2cdd83444d117d2ce3204ce4b4294dd05405634b84747ffb4227160c4e5c2c9da9815b0c6d20f55705f16cdbaa13d107ae666d707ccbe6c 000670e72ac2de50dd2cdd975a6cdab10ac45e37ef7a28c685d77447051496b5e161f8b1b93f6c7f32fce8ea05e94ed35fd7cb28c44bf51ea29cbaf5aaa31d6abca30a89430323dc 820a4ecaac881dd6ea3408f59d3f8dd4a4992f389d8ead4689cd4dbd85daf9b9ac7a9468d227ee03b384b01b176ae8b3 +69166ba40768d0a3930325405edfd85f3272f7b8e600b0b319f070274c91f9f03d0e6ec4bfc7b4445e91b87cecabfecf5e77c7301ee3c6b0affca2fa02c92216698705eb75443eecc25438db2d2fb4b24f4195d6b9c05c53e0868d3e58477100607ffdc31b18c40b4ad7202bb034e58653daec0f6b33c024d42a3fc84bd8f86b 00369a3bb96f884983c23281bcd04e24a3e5f6359f81e3c8e46f3f6b865eb6bdf98a630e90646275c587e41b546d3ca7688cc207afda15cf9b25cf83bd6ad27908647f3f9de59de7 b0a9791488f45a40a75170edeff36ca10a734f0c0c7020d26465cb9fb169c50f04f81cb407eb38918a9e4e080682f158 +f64cb668b72f1e6dd026a478505c0eb33446ae9a2993bc7648aaed02e172fa9a0e05eeec61e756ba246c1dad7e85d3f01baf734b1905c5bbd1b08d833c2cf1e079eca75b866d705c407eea8618d23ebbaf269c7185984b3bd4117ecfb295ee6b47eecc8d3a78bb96552f6be314656f91caff793838226662c75cd7804b6bef79 0026717b039df834855511815d5665ff9b654facab469390ae257b7f0eb4dfe66ea0dc037242ed0c13bf229b8f7ff26da9b55fe4750d3451c62804aad493c179ae45d08ece5af085 b7f9582e786a85d5039d2bdcb2a7cd52240188a88b93e4885f0314afafe4bec345a0acc5e10dd40b3be6ee87c9b63677 +51ee0b98eb6a3e3c1afcb35a33697c048dbf61374629ac5702a57801fafbea4d6fa5a26c9d1b79d1c58257ac0106387fab2d4a1b7f8c0dadcbe7c830613531b3c209bc17f792bdba1c1fae1b7528aac53dc86c2094b40194577325c05d2258303a2d17c854e7449489c43991b6877a50692a6340a528a6b188440ac0cddd4c4b 01d642f2d393ed4abea37173e4a79534af87adf534ead4a0a1c46fb047619221e3577e6b8bcc776114d01159c736ab78af3e53feac339d7afe58be8e7a8ed290f1dad960f1b5de94 b0a20484c82fd0440a39bf412cd69bb3ccefa275ad12ec8d4176f0fc35e143a8ace3d805c0de76e2e0e467b3270e276c +feee50aeacaccb6b1c3d95c6524044edb78322ee836d8159c4a4c2cc6982480567c4c6cc4806a564876622266e1ebd45f2f4be851b79da025bd57d0e6acce1ec1c8c255eb89713a1e4897d4ee0f7a248b9d4bd3ad5dc0e57f60ebfb65691e164bc908956a019083e923cfd33dcf37c735af3462768a1e14a8051d7aee74d5228 008cb70be29e83f697a3e2f67d86f1c1ec9a163b5335cb4a06004b6634948bf60b8ad9df9b27d2bedc4975265ce44a7884e57082d521320ca4372d38fc77b18d3fa05ad8aa5c43d6 ae32983ec1991209dd10cf8325a3da602b3631c7ec02be0fa42dfb015073e238fce543b5b240bf99557917126816423c +b115f7370d6a93a90fd9dfdfb292956be34b61992ce1fa5627c5e928d74bcdeea66d4040c473306a0070fa8363c4303bea32f73ea3639b5c6676fa5a1d68a2cc1f91f00580d7453a23ae70af4cb1f1657aa82c5b305374effe5d67d559e46a6cee6360503d21070506f1af30bb000d2f2f85caa6465810f89968f33abae81cb3 01eef463771f9c6285f3257691dea0844687606d4dd00b6020517f190891cc1be97cfad21d147ed8881b5a6e19b22ceeae30e1132476325f2de0e9af2e14c80b8c780a9d2d6c96de aa3ca3450d70b1a62fa2822529833df167e5cdf016d21126b5a617434a00336ff60a484f72291d0684cc43b93676f9f1 +726782eb0d9720daa64e4a77b5d8dd67a1a193f15eb6b5162e3d89c925ba63b7c7e1c4bfc8d6f11915b0e14d16ab53ab015317bd5958b0beb6074199e05181915496575768d026c23e92e06016598de008c3718aaabcda8b68bebca0a73ecfc7327e8d3646106b7d114dabc46cfe56265c326ee56fd2ca87abb5bed8f997c735 013bd452b0880b101df1aa65724fb60d5d85b37ed5419027481661a3617e0fb37bda1151b9b5b41f908ba832011f7850b75a07b678e5b8cb35c5fc8b94a625e4398cd5ada2b04cc9 a73b4eb98d5fcdcf2d498b9b27db513fc2ad8d2ceabdf7c33346c730fb803bb4645fd4f24ae2e8f6a6f547478743db76 +1c2418243fcd89c6382b7c3b2a8c341f26d08174a9e9296c4a5c98c5793a0fa48dce51e30811a96b515aa22bf9af89a43de06d696be1e531c5dece1f69fa6ecb7f20be063c602a16454ddafb14385ae3f8246c3f989d0566e06e7ed1864502896ea19df8393259c4dab3b3380a4a80b4103cbef4f38cb69198b7cf74ce94883b 01288141ec2244e4bb3f62daf4ee588aed09ce22be55e3d42e9085a947c1f8cd16533635d170bd64ae0b417346fa4670c25d41387acb2a8e14407a1931d9f7c5358a14eca40974bb 8a9afc86928f171f7ec2c0be5c6ea1fb12428afbae0d33224d5e7f7bd32a908937d58d169bd45391c3f04c50b0e959c9 +1de4b642ec7220c64b91561caed7832044d6e811ac909f3b199cceb0d8a7db91bcdc801412044f5c34b355b95a2c6170fe497f6d5259bc20715a38cb0341c88e93029137e94d895bab464bca6568b852340a5c5d6a225475f6eefe2fc71ffa42f857d9bab768ccaf4793c80c4751a5583269ddcfccf8283c46a1b34d84463e61 001fe06b94a27d551d409b0eb9db0b163fadcf0486e2a6074bafe167f9a3b4ce8ac11f42cf72f9a1833a126b9473163d29bca2ad139dd1a5e7fedf54798bf56507326fae73a3e9a2 b781e6876adefc82d2d7b495c3632e1c2b3543539dd1e91084cd4567894ef798af07f51408c1b5fb4150374f04607174 +70279be7d7ac72a32606642ecd81b5d4d0f95fbc3c0b07d85c16adf2788601e44dedb8e55e0f9e0b4ca3ca35f5be7511b0e69224a05204af67aae11ce154af6d594d47f6e3142ad183969544aa95cae1edf42bc699137f60178c12b10a67698e37ab9f3edbfb3acdf1b3513d62fe3db33b16cbb4e1f9dfe732c107f9d0c953f6 009cdc7e4945c485a41728f83d5188f539e372ff4fe38fffcaacbcb4522428e4f93ef4972556f4398fe17bdd885768f0fb5590df495badc794d4d274e22f2f4a2535555922fa43f9 8d749d848a0f2044bb889abd78cb983b4ec98c71e0c2b8e1110ba28994560ebee1d172754e9d70a784f7bf756ced6dd9 +4d7e0ad520445b6a5cb46b7c77fbd367614044ae6004494c2b3a89089287e2836c73b799cd8c90139eac427ebe335804c3788f3728ffb8edd7f49a4bcc76a9e24ce3c2299cea88c04645b82033115380f81b0c1d823e470631008d350cf0c0dba1915519985b8a389ccd8c809dbd5bb5051a79e631916e0d052d9b6cca18e0ef 002bc753d007c4491cfb8ce0a6c96455acd16d37e02c982db216b8cc1afd6d10c6be4e15a3988b8b8b86b2b5b59a5c1939889024849317f27ee08a06bd8e7524d4ad83a1de208564 b34caf091fc4cd6c36edd92f92f3e1e48fa69b8f7aa45bae5b6f72fd75fd07540d952f3ba3eb6f4cd82b58ff7f11c496 +d49903f38b5c9b17542310425e59377f61f5b4f4740cd97371ee2116083f7758e69e7e2c1b0950ec6b76f96e3c91c721d6f2843afde8c7505a559c8a64bca2e665aa1131b75bdf86fb5b90581c7d3b61c2cff88f3fccf356ddf5ed282e27727be061b6925c51ea7f1a495f471dc8a5ca1a88bbe29e92338d3c9361460398965a 002082c6e61d0d72f040905d8c1c20d47b029f41ec68d6cbf43ce97c3b2a0a770557a33cb803c432cfbd3958fda30ec1bba77a6613c318597a85ad02b26c44bb77ca96d9cc1194ea ad65529cbd4c4f99e8a301da81a002a1aa17bfcf2c39b5df61932a63970d8228107c7029987d29f197c55d78b230b3b7 +0e3f4afc3e7b25c1bf2d98098a5a87db1224d9bb45adc6e434732b8722a708ab80a1f3f6ef3c5aa70d2e1dad3e4416b12cc59171f05736c4b58bd084602c344f2f0bf3cfdcfe04c64e87597a99de23ded64b33607f7c273ec321f6462518715b11e91361e89ce5415bfc2ef520bfec378244a3bd2a4b9b6b3d68815f2f75baf6 00e298c93351323e2c5304015a4878997ae4e79d1c32f1dc64262e534d4f2c4b3e222356ffce746763373fdfb936fd330d3214a18c07f1205b20c9a941331cd676040ba1fe3dbce7 b353448c515a919ce76c633fa90312e34d1ba581447150d4a9352ccb00f1e412187d886de3f46b784d214745f28130cc +8fe32671f6927272fd3cd8dd4e34d44d27fac8c88b41bf9a48039e914990bf06d1633b38b9200ce1c2a275b9c55498e5da2d0707322c3ea0a0fd7aff598fb801628264e13047c8008153e8595a0dc95d54e70b882ac2ac9314d2b78e7b93922da818d7075215e354708994af66958954c92c074d132dbb2488e5a531c755a8e2 0104f4ad56594c5cec2a988c5596d73adaa5a81802b40110dbae698ddb1f0b271fd1479c38abcdb9b234e69cd0da8a0328d2135c287d5b130a09fa0b899058e7800eb2dfcee95c1a b69b03e11163a1ba242f2c57a2438bd4c87d534a677deef43b7f61cb7c87e71fc23d129acac5b2a8b2bc12fec2c28967 +a8fa01136a0a78313a5d160c32fe5d1805eeb3730c18ca0c47818e82c48eb4c9e5b2dfe3ee5facef9ec59b68f4e6f3213f77fba9f8ba06dcde546ae348d343233883894f4423331b536f62373a495852977a51cb192cfbec04b5582b4ece69f345979e234de32da7a120138a057a7119735c4cb19099bf48bb202e7ffac04def 00c4989bf33b3136bcb4ba67906eaff2bcbc6567635aa4b057acb7353ee87ba3cb4cb9838f8f679729d5c6ed98e6c4199cf58605f009c6873a1b8321f83cd3c0973b7a3cfd9dbaa5 b1274b15ede64c79739adc663818d4499187f1c4b7195d35593763b0037f00b7c996ad79a9c4e095d31e971daaf4c955 +ba2d83b21c783d6ef2f3b7b10e910a418a9b9f49ae0fd37990335b3a3d15627846c9a12a1f31a3d0e062ad1bec5650606ed4dd06c30e50c1e8761a29f4ea1a20f74635d5dac22e5b787ac10f4ee82b338a641484f91771c128c84d31cdab0a6b9616078c898665655ee9dd4ae73d33b94bf091b064928b959623aa71ff73b4db 01a96f2ad56e31397e236cafc108087479c9823589a5fbc3dc7488d0e5d1199cf245d7f21f524cc0e8b47feca14c93fb760e631434a91188b32965053942f3bd39b3714f9d6f1a11 a90290baa4f85417183d8cf6878e9c3ebb5b75ca652edb43904a084d33b5ed962b7c75afefdc4dd4f2985dbde09dc614 +ea2d5f4e9797bfc2f33f0fccaf530db2bdf8abcec00f09a0338eefdba318221ec0e050cad1a85c3f76b784c6e8c18da2b062f333eeff18b7b781e67d6d0a4368b8231a892e0f4103012348e5df53ac745e4d34e2cd1ee9369f97d4801ff485fc144b2007008036bbc07cb1c302a00054b54f3713919191e1d5052978c9c2895e 00c08ed8e0e0f8b0d0714b46a2164b933f8147692f18da97e5a108c44d5a5cf221cb50536e41832b83bff4026c6df156386235cf5e3e9a67b7cf9b2fa7707c5e0ff33a91601b8e34 a7332a6c2e65b2e521171d073895983a2896d692ba1cf681ce087c3d4a449313b985f9a02ceb90b8f8b9a693f8617591 +b2293b0a09f41decd9d8e637b1b08c2efe612f33c9c0beebb6e05033c6103b958f8aacd125d7c810b4c287349f5f922d2c6ed554be597fb8b3ba0e5a8c385ed8ae70d5ae19685298f20e8d844fb5ad98db12ba7e5f45baed9045c3e86b3cac9bd55b614b82fd075954fc59bfc6124cbd68edae988596575f379d8921b594c75d 0144090a0ee38cfa21fabcc24d35139a99656911ad4f6dbffb77dbe74e7993edfa9fd63d2c4f6bbdbc8ec21ba13c9f4a3576b5d6e3abeab5af5ac81b1f2bb6d4c42dde645d854d9c 8ad386ac68191f3b37406aab1e8dba5218d5cbb97f2a00a30db8f5e568b4964910f599ca05c48d9e3a25ccc57cfdd47a +acce54270252e7d9e983c08c993cd6b7e3caf482a9149036afe4665bd3d0662a6818047187872862d5718b8ac063477f693caf1a9baa8bdf2f36d411a796f2b46ab56f66bc94924229f8264016d6769c85d9bbb7d6bb042fefdb8fde1be026b86af2017aacfe38c97309b4689b23fff94f1de880064f1d3ad9d74dc804c41f41 01df26b672b2e3617b6b6c631d3c6be0cb49c0a690de49643e0f416215bcdaefc03fa9c708471f1d87476d58c8f147517ec8a14aa945ef001fa01984d5c3d81f7083ea500558fef4 80e94be8d1d5d3e4a592d1cdb0530c56ac718c64a21478308027532f82b5703516f8b74a42b50cdb8b70db8be2eb95c7 +e25274ded4840df0d71d3369007118f002b83e2d375c78f7e29ade067db15cce21842611f3f015db2efec57da77cb9d16eb1e00a8c1444d48dfda569e29fca1ebf40a22fc646a9fd44460f0e473bde487634bfbdac2c312f66a1c2982c6fe76c54ac72b6c8cc9345e47cb319a974b3cc4bb40634df74b4ad7e18adfa9a71ddd5 0189918b832e9fa30161fdd927bfc267f6405335df3d66d225e17173af52a671138883bcb94c4403ca3e001fcf09ef4c6488934d6775af2b1da30a8f331579af2d0fbb530298d8f9 b2d2fbe925b2c1e2389b7e37d573ccee5ed6b173ed27270e5fc76ee5fdfa4b2db6a39045290e03d29b7d4580dde39edc +d8a4aed87c316012482819b03a1d91691f2ad11a2f46082497ea8f64880d686891f7da550b2ac17199c657d4eb9d04d5cb8eaa180f743b87d23b1c86103f9e9bb60f4e19f0ff9d160f180aed7735130c03adb62502e69be5c624ed7bda2301f30580ae0921b02e103a638f5623c02c186e3bfe6ff134c762a2bcac1f879a9353 00bdcc175eca3a399b944eb0334ff33c4fd130999c8ac0e7b52ac5b774fbad53ccc3a31024f5262b2eecfeb2104b14bb244307effe3dbe8ed25686dbf46a42c4b6f8e34010ad826a a337a40250fda465df348c37da1368d9856c33347c1540808ffdefbd936c7096bf888a7ceaff166d3c5148b5d2a77b1b +acbaa5ffc4eee0850075c0e502a70cc7a897a919f5e7bca4e798385601a26f411fdae5466ba9f6b6d8d7f819a749b799fbf4a3bda9105063e74914e8583ed8b31ea4d22164bee6f14bf53afca269b901c80cb3265be32ffd4ca4bc4ddb83e11eff82ead6d75dc4aec8e5c67f35d58a8a156cd1c0351abdccc0c5396c8fbe6920 0007ab5a55a1d8ecb7f5dca2afdf9ef465569a4b0374716f604ad42a6e0271e934b09655e8e2529784b69b2894bb399b02aeeae30e9e7ae70a2a8e56b9e775bd978a04c728e3951e b881616c769deafc519ff9869407dcc557ba080eec91533227048737906e54b41e88d3f1c547a0c8ecd4a81dcfbd4b38 +9a57b63a4f418404e8f5dcf3052b9bc04a4f6d2c33bde8651506d9cbc5542ffb9023292dea463111fb78913ccdcd182faabbff9164219b8900c7f9fb394f7d9678f77b18f8d58526ec64d7c1328953b983a7c416583e05a069cd76aefe26e5f5687b70abfbf9f58f052dc0863b4fc3bef805cc3bb05bf76a83235af9d6adfe66 01e7d4da72b1d82e17a066fe387f2a0a7fa4c60ab993ee09710531789186077f2f32b42ddda497d5fb57356383e1f96973df043307f0b6519430c3f0d40d62954032872fceb7dce9 8ddde83f5f9ee1585c2e17699c583dad51efdd0e7c17823c0f414c784a8e073c2e66517b36f828b79eaed314c3a3f8d5 +97b79c76d9c637f51294369e0bb52c4189f2fd3bd0607f91834aa71b3555605a89ff68e84fb5bda603f502f620e14e8b0c7affefafa2f0b303009ee99653ae4550a05315e551dd12a4d8328279b8150d030b03c5650ed4f8d3ba7c3a5361f472f436b200b321e7863c771e20ddd7bdf739c51de3676f953a5501e4477aed1bd8 015b7271d4319db5743119c8103a7d4c6d57e9c62f3eb93762156d2ebd159980aa57cea948e416717d715a2e458851f1b2e9ad4172bbcc53861db29c3ee0ba8e82617a5866170847 8d07792be80f2cdb33c4d280aa73c8e312642e3387941376c6b591c508c91562e115af25a3f232045428abb301e0d22f +564ad0e37c9c37a60872a4780a723d08d1159ddc77bd834d74c1025cdf3cbd5338c3fc07a904fcad9b979b2a2ceb1a0139af35e5112305fd662a57af6312624b9bdd3a64849f95f59a46ca8feb2ed56f87f258518947474c1729275c4d89b7dd286ed65f286cbac76002cc63b92a73ab6bd13c4adef282f32297e441bdd8fd36 007219ea7917d174a5386df985d0dca798ac9f8e215ab2f0003aee929a2dbd91e37fedead0ed95b1e8aabcf516bdf54337b4aff7ace4c6b3179f2e919a49db50a41c9d4d58d4f636 8015abed5f19603ca3c8df7ca0b3b1f44040f6f7e2ce8ef81a169cadfe9b050d44f46df4e422f9c11adae2480783577e +072ed5b14754fddaf54e20da42432df49bef38f4a3b1841b2db457ff86c44880727aca945770adb41269df41fc17f6a687bcaffaa45a3e59070526ed53b8dc3b78cf9a80a85461eaf4b477e44d5ec4c2bab9c05aa747a5a520b35fd09e8b44539d060ba1c3470267e0dda111b15dbb587614a46e1e477127f963a16cf3a43ee5 00bc623152253da24bf8d752bd78aedf7d5f6a2f889453ccdec14e10753335ea8bea83fd181a1f3680ed50f2324fbeaadae160cc85831750e021f3e44121ea1b1efc29a7d0069479 b8783f5b72d364548ff98c1caedb38ab0d1dc316463108bba7f152ed3e1faa1d058710e7d31e4eeab5a047684d7be19c +e660dbdf3e61af39b83b95d3f1970f66d616f03273f7dddb98f768452b21cd39604a31cf80590d4a5e4b0d4917519e10fd325dd4ab7a52d70d154506329baefe0d5816f514ae109483122b4fa8fa1ebd7fdf1fc4e21e8d278a50c05d81c8f489596633d949c6c8fea96fe91430c01522a5afbd5042be8aa47da04581b2bd21cc 00645947d981d258f2954558c31022a3b6ba5fa7b675312f794cb61bfff1d9ce87267e4a1dacb7c8fc58624d31c85ebe22f80d26a620fed5df5bf38515e0903f0b69a606048197d8 ac9d473979e91ef21bae4195f116c3a37de1975e82ab038c216b7706f2d31d7289a607a25b91922266b18db7e616baf9 +8c9acbdc431565feae60e08bc7da113e12372ed373f1e1fdd581f98c8a7b0c79ac4aa42c7ffbc963fb4970fe26c5b5dd314b7051fe971c1186ebcb5650f7f7011a924de893f06961b8c75da7bff331847feead4abd2e8b9d6ecbedac18f4eac207b948e6e4215e4d5cb483e5c66ce7ad788cb89604d3a3e051539094079e7bdb 014cf93ca69d94ee8fbea0c8da9d76aea092b73073d8f5385b65c6dd4d567fe86bc2cfb8e8be890c3c6cd9abf7dc3a17eaecee3d7a9455887863e496c48dc3e47821bd3d825b6bed 83c96684e5df58f9a25f0a27c71e988cbeb39a71a522a4c9dc8fc4add44b660e6dc42aed302608c077a593a6be98ed59 +53ef87d6ac7b9698f40b3ea9f3442e7b64207b140b7f66f73fb7d5f8f98452d30a4e493b6c0e3268371e88e612b818d4d847f032ed4983817d020411a52d81fd2a17b58ebdec199d817c2a8ba77042bbd747a6fd4bcc7e844ea829fd8461b389aa0b5957d92962b6d4e86385a8fbca90b8fac40944607117e9a4ef6dccb8fc1e 0033feeaaaa28f16bfaf5ea9c7319cf4561ba4fc55327a8477b6cd58ef6ccad3962ee1f3edb243f3a04e7e49c8e23509fa2d63252adb186b8bc7e9255cd61fa9bc45242d42da3a68 acdaa3dd6736f5a6c62a276cf3d64746610cc716d0e9ca740227ce684b6c42e3ed648b9b3da96a000014712f15687356 +dca1b7a9a313ead11c2d54739d9017ae27f9d08b3544e418aee862bb57e427636cb6aedda28e10f12aa15d2355f4f8ef112a86fec5dc46e6acef693cb8fc37c3e4885f3be3d3ab31ea4d73a0de904e95c7135a149f77b621d642f9bd8ba192d39cfc58b6f19a797c4f3b4f3a87054298e3ce5eda0ff7f44f8134c9a108285dfa 005613dfb53149bf5fdc4e08ccc1c752b0b66ab43aef2d008ed40f3df40fcbb2938d2c41e3ea2dd4428aeba9059a97efe5593119673866a19d27a2ee37dd357e22b6bc849e7e22cc 868e6ad02e4892c210bbfea253d6e7101067652180e4b2a8c5532dde970a5cef30ea52a52d1a6e491f73258504398315 +aff61d62c8f5c31bbb7d0a64a6ac589e918bbf2f13e7ad13abb9ac26405e267249a7c9922139bc28140833e10976b87e91cf28285274b2b48b63d24ac94c85c70fafa78f8ad05955c0ce6c02b841ee196dab12306e3e3d6138371217e2b474f7e67a80bbb78a47e374ffe2c9f86292e471c551da50d46e7b5c8331029f369767 011b92c8b72b86c51903387a65aa206988d443d1988253329ad3a89c902ff1ef8cf73b7f2e4aaa352443bcb833712d94c3e637ec12cbe4c2d4606878576b17fae1512fc77785b737 acc9d97fc0527848680535fb3e6e0a830cdbd5061d760dcf38fdbf4dc7fb33ca2e30e7d8d30348a6d6127a4f0ef5d3f5 +721017294f17ef351e41256b57a64a79f3636628c4bcbe676ac9a2d96076b913dc4b246c9945183ec9bd2d251441b5101eac44e2fa1bef59dec03ccd7fa5accf3b7d094d68dcf78c8de4e2f19f56bf0dcb3b66b9421ec3f8b353b9fd74feb2e9affe0bf9aa421b6f03eeba3ffd58fba56b3ebd094880e50de01ee62a108a24cf 00c3c90d5ce4375a08b85575faa78ee6bbd9e5571ce5a90582042617b807339c282cdc3b003d82006264b1c08c20af4ad4549fbde53d262facb98d923d81b8eb6093374b6a1e84cb 8a03ed5d3eb3cf72c9bc76393af63cff778579affeb2a5c256f3e911509a13ae9a6fff604bdd5e89e8f1cce4886ff285 +e2d1f33681759adb7954bb5248b0db3c3885fea0d4c1c0c226eb1e6d2d3ef1b9ac281a0f1c2fe5175b67114b6a501e2426d1454bd5790dcbc4c232cf06b017de8a9bb39e6033f1edb5003e8de3b44cc3d6150c3c952afb442952483cc688908337b7c1a8b5c9da70937ccfa98b2b0098c530ff848010b8e8ee0a8d65283481a8 010f184c16228d9034271332178ed485d10b6aa76003efc160d63fea26fbbdf5552205ac7df0d8c852a1210cf0ba512f20b798827b36ad56b12a826fa7dc1db45aed264ca6822659 a067fd2340b40b114c5efb1e210c826ae0f8a50899f4dc5b9e4e863363bb46412ce603bc6b62945356b8e5a0347c6f88 +414fc5d2bd56b30040e105cb891788792da595583b11b8fcc7320f40dbf64d9263532dc57344dd17573c95eedf851668b5d552e8796af205f3a0043af1a829fabc2e93d9af9091fdd9e0fcbcc9d6d9ec960aa60e4e2964c29a2f375400366480e513f63d124db7745847310e69a38c8455e4e602056a6a4a14a8694155e0a9bf 0181baf9d497159f837cba58a11ca435c442e5ca792ea559bff9f6a1f562c05bf6bb5914afbd1bcaea75b35f88bdd832314b249a5298622c89462344d3f28a44ba3d059df432fc71 af16458ca5f4701abd5780c05f51b677097348bd07865f2f5d35931ded292a0d84e825189cd8fc53c7e6e0c51c44a7f5 +3b592cc8972a4782870e079b82a50f84b4c2d8ca90bd500d1ce5678982e266c391c556d8162ac3aab967154d072dbc0ba1dab5545cf2651753dee2881eca5abd412fe624bf3f9d17d33692d21ce23ad15ccffdfd250cb1949e73c9e40a64ebebb03852e92692dad1d7baef97fe109f35b7a492b343d4b643a4a7b1723eaecb64 0083fae86ab96bce99a53e50b7eecff38e4e25b21c4b0f6a4986915de245eae24f16b6a00a4db159ebc27f5a6a072da94ab6be5bf75f5eb3f75c4452bf4ea7014392eb1e02706fb4 81ade76cea2374c538672bf49ac80d621ed177db765c84244412b195187fdc9a7747138d415ea6e925d90de2cd7ae365 +0079a02cbab3dc02601fcb5c8607d555beef7cd71a66911ab6514a4ae21c5a9c0e166f8cf5fb198ec5a49a96e17cf041f35f00406b79270ebfe56dc6b8417d2529fd625686ffbc8f69685aefa2fd30a937c02f25b48be4679e6fde821de928b33b12470867def874bb8c7c8038ab6594346a2c44b39210d3610994ba60a05e06 01a663efa7bf4d8479bc535fad71e9b5e4f4281aec55967baa008ba17ac2f89cc3398d30573edef29d590fddce8cb157f655e92779f59e7a18d0327d02e7daf4c1216143b3688fed b1fa1d81442676871b82130aa87821c13a083ff150612fb3164f9c71f044bb404e50e17fb4325d86e05b2e6abd082051 +88573bd94ef50459814806efa868ebf92b066fbc2f7a4be9d2fa06b9dc1a72f72d783a6bcbc107b18a6314511bff217037a2252e7a5cd34cf9d5b2fe9c7846931f0133b2e95876cb800dc4ed7c4a4e4cc4f1195acf99fb0ec224b1f8fa8af71f72d390eca9d6be3879032a318734a63fec336c79035a43f70271def10c4955d3 00088d1a2c0219696a94337cd56516252b74139ea0733b17fdcbf7692c3e5f6c3989e5da2aaed7468e65a5d578571928ca273ec3b6aa72cd196f560f05095cdc8346e5d31c4c2e0c a90b9b439a5bb69f9548b827c08f870ce0b1a9e66add416ca1a16af521987d4cd0cd502b156b90909c22731d7214a2a7 +d0e02045ece6e338cc8ab41d4a064c982ccb1748c48fc2fe0a6f10bdc876094358a6a90a45facec798a83cc95c6795cf0f0d7c66b77e22cb114c1432bfdaa1485ff35b6a58107cac3b7e58cb4f6c87c68db60b751e78f1fdfa54b8923b98caad0a4f31226956d065c083ace5f1e9e91944dcca51879d782e40358d58ca758750 016cc8a0fd59455ed8d4de561fd518df2e008f7dfaa5f7f29ac2489a411e233917b43eb3ebe2596fc824be58871949545e667dbcf240dfb5e0c615ade0179d9ea2a1b1ebb8ab9384 8940a8e1a8794cc293a73a61bb775461fd27a0df54859858a2ab685de3c7a1d558ea1a49a40444218413ef55cfccd324 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P224 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P224 new file mode 100644 index 000000000000..d75e9620143c --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P224 @@ -0,0 +1,60 @@ +699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615 a6fad7d9624aa99b4afdba883471a88ce88e7e0235079405d2b8b119ff5044282b41dba299d66e4c02fc4534e958aa40 +7de42b44db0aa8bfdcdac9add227e8f0cc7ad1d94693beb5e1d325e5f3f85b3bd033fc25e9469a89733a65d1fa641f7e67d668e7c71d736233c4cba20eb83c368c506affe77946b5e2ec693798aecd7ff943cd8fab90affddf5ad5b8d1af332e6c5fe4a2df16837700b2781e08821d4fbdd8373517f5b19f9e63b89cfeeeef6f cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5 b1dc5faa267249da2fd2a19cc250f4dcd26ccc32ad5f8ee8425f24f9dcb28ad0c0e5a33954c82739c7fbf4864e09558c +af0da3adab82784909e2b3dadcecba21eced3c60d7572023dea171044d9a10e8ba67d31b04904541b87fff32a10ccc6580869055fec6216a00320a28899859a6b61faba58a0bc10c2ba07ea16f214c3ddcc9fc5622ad1253b63fe7e95227ae3c9caa9962cffc8b1c4e8260036469d25ab0c8e3643a820b8b3a4d8d43e4b728f9 dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73 afc5a6145709ead13f0d621b5ed3921de1f6f44ed015d51df0e679f8f2c601f38556662e2cf0d6c2d7eb2160894af9ae +cfa56ae89727df6b7266f69d6636bf738f9e4f15f49c42a0123edac4b3743f32ea52389f919ceb90575c4184897773b2f2fc5b3fcb354880f15c93383215d3c2551fcc1b4180a1ac0f69c969bbc306acd115ce3976eff518540f43ad4076dbb5fbad9ce9b3234f1148b8f5e059192ff480fc4bcbd00d25f4d9f5ed4ba5693b6c aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e a27609cd54fc14967765fee061ce57735d351a9289eee54de9ad6a432a1f3bc07dfd0cc2fe297eaec3c4a0a35e06d2c1 +c223c8009018321b987a615c3414d2bb15954933569ca989de32d6bf11107bc47a330ab6d88d9b50d106cf5777d1b736b14bc48deda1bc573a9a7dd42cd061860645306dce7a5ba8c60f135a6a21999421ce8c4670fe7287a7e9ea3aa1e0fa82721f33e6e823957fe86e2283c89ef92b13cd0333c4bb70865ae1919bf538ea34 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4 a45d2336ea02a1845e790e91c1a4282fff4676ad9e51f2b7cbee04b116824d7323a4e0d12c8bfd62a76a01b2920c0e17 +1c27273d95182c74c100d85b5c08f4b26874c2abc87f127f304aedbf52ef6540eba16dd664ae1e9e30ea1e66ff9cc9ab5a80b5bcbd19dde88a29ff10b50a6abd73388e8071306c68d0c9f6caa26b7e68de29312be959b9f4a5481f5a2ad2070a396ed3de21096541cf58c4a13308e08867565bf2df9d649357a83cdcf18d2cd9 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131 950903f95eca515d524bd41d2cac259b9edae5ea4628e44410d5653fa430b26be93154a544f563a173f32d701731f242 +069ae374971627f6b8503f3aa63ab52bcf4f3fcae65b98cdbbf917a5b08a10dc760056714db279806a8d43485320e6fee0f1e0562e077ee270ace8d3c478d79bcdff9cf8b92fdea68421d4a276f8e62ae379387ae06b60af9eb3c40bd7a768aeffccdc8a08bc78ca2eca18061058043a0e441209c5c594842838a4d9d778a053 d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974 ab727a075ce4edd4b973fb2e9ae8b6a23de600bcfc1e7913a6dbb47f126d04c623f16354929e2afb3af1d525a581113c +d0d5ae3e33600aa21c1606caec449eee678c87cb593594be1fbb048cc7cfd076e5cc7132ebe290c4c014e7a517a0d5972759acfa1438d9d2e5d236d19ac92136f6252b7e5bea7588dcba6522b6b18128f003ecab5cb4908832fb5a375cf820f8f0e9ee870653a73dc2282f2d45622a2f0e85cba05c567baf1b9862b79a4b244e 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8 b608287344ad48bf51080726db8d1f61ac945bd75cbe1635415500158dcf62a13dfc7f523d3b1f0bef516532aeb97d9f +79b7375ae7a4f2e4adad8765d14c1540cd9979db38076c157c1837c760ca6febbb18fd42152335929b735e1a08041bd38d315cd4c6b7dd2729de8752f531f07fe4ddc4f1899debc0311eef0019170b58e08895b439ddf09fbf0aeb1e2fd35c2ef7ae402308c3637733802601dd218fb14c22f57870835b10818369d57d318405 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2 b7b7cf62122275389d28973ed30027703bfa2fc693fed32c699a72010aad70fee01c6d4ba61c9b9c44bdfb7b59a28056 +8c7de96e6880d5b6efc19646b9d3d56490775cb3faab342e64db2e388c4bd9e94c4e69a63ccdb7e007a19711e69c06f106b71c983a6d97c4589045666c6ab5ea7b5b6d096ddf6fd35b819f1506a3c37ddd40929504f9f079c8d83820fc8493f97b2298aebe48fdb4ff472b29018fc2b1163a22bfbb1de413e8645e871291a9f6 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7 83d170360e6acb0341ebb07c1b3da118acbb3078b9a6a8b0e2fce9623c7ef9c1f89efc9a5d825b6fb0e73fab54a7243d +c89766374c5a5ccef5823e7a9b54af835ac56afbbb517bd77bfecf3fea876bd0cc9ea486e3d685cfe3fb05f25d9c67992cd7863c80a55c7a263249eb3996c4698ad7381131bf3700b7b24d7ca281a100cf2b750e7f0f933e662a08d9f9e47d779fb03754bd20931262ff381a2fe7d1dc94f4a0520de73fa72020494d3133ecf7 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b a871848863f9ff9d2371de33c6d7526f106d6b98248beef8cc8a033dc30942c93e0fc992e6cdf59e29539d84e37ac75a +30f0e3b502eec5646929d48fd46aa73991d82079c7bd50a38b38ec0bd84167c8cf5ba39bec26999e70208af9b445046cd9d20c82b7629ca1e51bdd00daddbc35f9eb036a15ac57898642d9db09479a38cc80a2e41e380c8a766b2d623de2de798e1eabc02234b89b85d60154460c3bf12764f3fbf17fcccc82df516a2fbe4ecf c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6 aad12ebe38461bc0afea3bb8b44ee0dfb05dfbd81ea0c5624f4b92791175d2d359288383f62cc59b81f5b033be9add1d +6bbb4bf987c8e5069e47c1a541b48b8a3e6d14bfd9ac6dfaa7503b64ab5e1a55f63e91cf5c3e703ac27ad88756dd7fb2d73b909fc15302d0592b974d47e72e60ed339a40b34d39a49b69ea4a5d26ce86f3ca00a70f1cd416a6a5722e8f39d1f0e966981803d6f46dac34e4c7640204cd0d9f1e53fc3acf30096cd00fa80b3ae9 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc 8a14f4e74c7ca0d2c510080d219107b711316c23b2cb54641d925bf4095a2cf16428d5249ce615ae50b599b8d85085fe +05b8f8e56214d4217323f2066f974f638f0b83689fc4ed1201848230efdc1fbca8f70359cecc921050141d3b02c2f17aa306fc2ce5fc06e7d0f4be162fcd985a0b687b4ba09b681cb52ffe890bf5bb4a104cb2e770c04df433013605eb8c72a09902f4246d6c22b8c191ef1b0bece10d5ce2744fc7345307dd1b41b6eff0ca89 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3 88e546afa9f79fdd0255935cacd4c167b9d5e1bcc6bc5720735dd24d7c6ac7a9ea3ef205b7b54cdc1f888e5b44083054 +e5c979f0832242b143077bce6ef146a53bb4c53abfc033473c59f3c4095a68b7a504b609f2ab163b5f88f374f0f3bff8762278b1f1c37323b9ed448e3de33e6443796a9ecaa466aa75175375418186c352018a57ce874e44ae72401d5c0f401b5a51804724c10653fded9066e8994d36a137fdeb9364601daeef09fd174dde4a 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912 95746244222f26562331fa60799153b776b5328684a0e1982d5020eb342da27829b35b1a31413f45aee7275508e809b8 +2b49de971bb0f705a3fb5914eb7638d72884a6c3550667dbfdf301adf26bde02f387fd426a31be6c9ff8bfe8690c8113c88576427f1466508458349fc86036afcfb66448b947707e791e71f558b2bf4e7e7507773aaf4e9af51eda95cbce0a0f752b216f8a54a045d47801ff410ee411a1b66a516f278327df2462fb5619470e 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa 8f1463c2f4e1bea572a37b2c2526f4a1e037d5ac1746533ae67dcea64709c62f50b67d82cea3a2ae3da29b251b6f124e +1fa7201d96ad4d190415f2656d1387fa886afc38e5cd18b8c60da367acf32c627d2c9ea19ef3f030e559fc2a21695cdbb65ddf6ba36a70af0d3fa292a32de31da6acc6108ab2be8bd37843338f0c37c2d62648d3d49013edeb9e179dadf78bf885f95e712fcdfcc8a172e47c09ab159f3a00ed7b930f628c3c48257e92fc7407 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972 8d275f129a761261b794d537b44e70a677852a97ba044e3186f26c7e49d3dd48f021e514a0932d12f41581d66ce3fc5b +74715fe10748a5b98b138f390f7ca9629c584c5d6ad268fc455c8de2e800b73fa1ea9aaee85de58baa2ce9ce68d822fc31842c6b153baef3a12bf6b4541f74af65430ae931a64c8b4950ad1c76b31aea8c229b3623390e233c112586aa5907bbe419841f54f0a7d6d19c003b91dc84bbb59b14ec477a1e9d194c137e21c75bbb f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170 a04cf990b795a0b8509c764f20b7abc082126b3fcbe4c57f5d3230bb0b061471ccb4760254efa4f349c0d3c37504d755 +d10131982dd1a1d839aba383cd72855bf41061c0cb04dfa1acad3181f240341d744ca6002b52f25fb3c63f16d050c4a4ef2c0ebf5f16ce987558f4b9d4a5ad3c6b81b617de00e04ba32282d8bf223bfedbb325b741dfdc8f56fa85c65d42f05f6a1330d8cc6664ad32050dd7b9e3993f4d6c91e5e12cbd9e82196e009ad22560 c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85 b645ba8125f09af09afb5aacf09e3013c104bcdbffb83023f81f18d9e9c1c1f70ce50d0390aa5368aa103afdeb80b88e +ef9dbd90ded96ad627a0a987ab90537a3e7acc1fdfa991088e9d999fd726e3ce1e1bd89a7df08d8c2bf51085254c89dc67bc21e8a1a93f33a38c18c0ce3880e958ac3e3dbe8aec49f981821c4ac6812dd29fab3a9ebe7fbd799fb50f12021b48d1d9abca8842547b3b99befa612cc8b4ca5f9412e0352e72ab1344a0ac2913db 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6 aa8df891943ea43fd355d57e22bf06d7b749533dadca60857be418771c664a9e9624761a6e0e37f80c8766a9cd33a466 +4cc91f744ac858d3577e48813219aa3538dd813b186b42d1e6218376f07cc1cc448ddd6b37240e98bf953f49cf54d65c12878b33c0bf6eb1c60254f0b6fa974f847e53abc56773eef6f29885dfc619e6a48fc15a667ca94001a0c945b6357a53221b0f4b266181456b0d2d25e90708777f1a6f85971c00140c631c1991e0fd06 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39 94f5fbc6b4f85a43048d3adba352a51b3d63cba51c8b59bcb31766b8b8805618682a836cc59feb5d481e30bb06353413 +58f43cc1924de4bc5867664adbc9d26b4f096a43aca47c27c52851b006dc2a658919ef9ce5b5ac48372703be15ac51631c2bd84b88f479f113b0569a9a09e230ec1e8e573474c6075284d3e57d973829af35325d9e7dab4a5f9b065155bbcaff3642a82ef4c9b9e127d3575c050721653da3b087d3fa394192897a5519527d19 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6 b4ddf59065646dd7e24efccb02d8f0c4902a3cc7d6b185f9f20b14b1ea795fd4644adbe58f3429340b24db0e6013e020 +113a2806b052fde683ee09453098e402204155afb3776fd1cad3a9103421d327eab8f9ec0dd050ffcc83f93b34ea707705fabeccfe43ab1a71c95298fd3ec769d99ead1066950eee677d225816e0faad19cf69e1b35d16771689e2092cafe16d7c0dd7b0db73fffb8d0f3eaed83004dd21e753530ec939c89ba25578fa5f785b 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b 80865284810ab1b258a73de70e386f0000140f83b8c742f5df4c0f0c9c9100c63fdc4b4fbff606bedf290a346b39c216 +64cbfc8f2e2149a31b3e8a80c4a552f6c62aaeb7990b6e0ee55500a9d17be04213406578caf315951086dff5c2af3b5ce17d425d185101ef26f86396ba3a129a4f3f8e2dd595f59efb6c0f5c2dcc394569d7268695e9ac7daa84203f1f1895f1f9e4b514a5c9cd23baa63454710144fe735ad9b8f42d8c43267aa434a26d7e5f 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b 8b9978003cc36a79843a496c253e6bc29a72be07a45e82ac9c158ccc9ed71b0a58ede798f7eb9b29b096a07b36d495d5 +a10a11c8e30fff118d371daf824f16c08200b83ea059436466a4611ccac93b2dea2de8c1006f946196aef7fe9b0c251a391b0340f21797798278b412ff2b53842eec6450728e2bca062f8337a2c204b9ea04ff660cd4d4db559f2f11c4d8ef199021339fcc82396f7a93926cf5f247e37d8067fe50692de54f102bd5ab51925c 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8 840968d4f470d78c33c2ec75c2be01d2b9cdc104f861c0200dae435e644fab0ac96f170fc06717b2c8aee1acb0693fc3 +b3f720bf566ffa369259f4361959ae0641d2755ec264a4c4349981df2b02563275b2b9adb5aee47f7a456760a971991ffed6b17809bb9694138d1677fa916123795239353158fc6b22d10f20d26f5d2dcd8c56c44373eea5b93067dba2d7c5318dac2e9e8714873cb1b37f58c011fd14fa1e535554efe05f468bfc8e11cd8b99 e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784 b224b356d9aba988cd738743a00b75766409b7ace5e4dcf49f0e06f1c3d9fc7cfb9f3f9b76d03973fbdee3897711fda5 +0a398a46df7ccc48d1e7833f8bbc67100f1ef77a62dc78bbc115b2a662f9591fbaaa91ad3d788e2fdd1b3164e45293d4f5686c151296901768028ac80ded4bf89c647ad35f0c7c4cb318c0c757c1d83c44d850e5fd4677281b3f13b1ee54de79c8c042813f9d3312dcc6111a68299cb7e829557d7f3d96e702f65aefc6499415 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c ad23e13d1d23467e2097f6c1500a9f79dc14cc88bfc32e314aa2e3cdd40c60ff48f04fbb3fb3ec6dff41127b609ac2ec +8c33616821a6038b448d8918668977fcf1ef5aa0cf7c341837b39bbcc9bca875a3757f4b392630e9995b9bbe4eb66978b877586adaa02f99d2344dae082a7603351d8ffcfca081ab403cd0acb90d078dd1d0789c2eb3185c62bff2d9f04cd38e509e3b83c12ed0a5c6808fc42f7ba5b06acdc496c8ad9be648ee6a4505f8560f 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583 a36db49484996b1076c741ce92add6e6fd54d74384cebe18d9e298ba480564eea9c4e6ac3bd358544c78d66ae932ac44 +94d56535fd4edfe67a0daa6579f9d53bf6b7b8830ae2aeb62892ff59f18756ddf2811b449c7d20d65d54f8507de4e7c50eaa084830637812aa4b250a4d61ab67845be36e4a41cdc0a70f8d6e3a63d4514f0dc197e6486015046a316153d5f3a3a4a0ae1ed7ea5fa55e12e73d333333685c02e0eb636234ea7e6d4b76b4b76b5a 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2 97e956dcf0e861adb02829f5224f871a41f25b03924bf8b0b93add65a44fd060f56aa4a20aa8c78f8eab5b46d69a0556 +5d8ebdf9eb28b47bdafaa36bf0b66a9eaf99b6c83959da4f2b1151b4f4ecd28fb115a64c0cb9491093a7e9b9c53ec423e4c72e7765bb9c818da0e8c428667e44474a71db4867130c77c40bfd8544b2d7b9d6464d2b8e6a48482153256a32437c3a747231f51134dd14c703407e31146a6fcde23bededcf16950486e90ca69ac0 f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc 960985eb63d42a504c3faa1cd43b311905eccc8adc6116531ac48988af99c469f5b15f80ce5dfd1354b935faeed60a8a +25e4416695f77551fdce276355528ccf1ddc2483821c5d22d751d50111ca2fadc6593b52c74f4b5957494f1df25b0b2f86950d0d19229ec6506fee8581d2dd09d48418b146ff16bd84a17ca0dc83b1888eb407376da6c8a88fa1e60b8c2a2471dfde4b3996ef673d5bde3d70c434dc9f2488e9de16ae657d29e5e59ec922a1ec 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd 87385405f4340147df64f4097b00876a008ab490a50d9924f357c23382ec4085215eae93f21ca16ee9f6be6e1777fcaa +9164d633a553deccf3cbd2effccf1387fa3177cd28c95d94a7d1a3e159c5e5c027758cc26493301b2f4d141d8d07a5fe5fead987ce5f30abeafcb48c302afc6c2309f0e93d9b6818cbb6972d222cb7b01302dfe202ae83b89f53150ae4a0e2b8fc0fd1091f19b4ab2e6ab213ab322d04f2c5f57113bfad3c5675227237abf773 e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3 8f217ef7a00273c18e494e167b1b104d3b0373a0a6c096b58d1ca207c92f160bd4f545ad73c655587468b551397949d6 +019df05929321ecea7ee1de4f412aba1c8d3c24437db04b194a68a0a59dd871be10bd3a4be6edf551350ea49fc7155a4d887e1221486291abe77a30633a4c4f7868fe2df24311cba0c73804883954460e122387ed414111ff96ff1aebac8b6a6491d8a0d16e48a63bf3d027c0f68ee4a4b234d73b412196706af8ea022b4dcef b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17 8ef6e609c0290e6140f55eb3cfbf5a8f00a3670c3d449b8b3dbece067a404ad0e6c84c7403409600e10cec829fed742d +5d09d2b1d3fa6e12c10d8b26dc9aabc8dc02bd06e63ff33f8bb91ede4b8694592a69e4ed4cdf6820069e2b9c7803658949e877ffe23bf90bcf5ce1409c06c71d86885a94048b05ac0ec9db193e489a5a2bfa367caf6aa8ecdb032be366174343f6875d2fe1785e8d77334f5f469cec64998e08d3303e5c9a1923b34fdc105d65 efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085 b5241800e389404c99272964cc64cccebeeb67a021e28d0ede66ad4a3bf5f34c1a33cbb4ccb07a803f914d9d1a3c4274 +50f6dfc81c6cf189e0a310f992907fe93356cee9dea9a41c7671a8daf3f4cfe0c459ce6122c1e731dbf7593419d7114cb73b46956158a982c5d52c72f43f0f822046093c69aeff1f7e4cd8af00ba655c5baa2e7b6a400b4be1f6fd51b3e4cfb35a69c80a28c5cafb771b6c2e52e0aeef0e3fd045e8d40745f3f8b74fd969f816 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd 92939a4d321ff797fb91b4c2bb82ab98e8a18949e8d2fb9a50a89ff8a450c6671bf132dac14350e54a119bcc06875123 +e90129ac6672c85bb7b6b18e9dc199c96c81fd65034b53c77818364d512366fb9cd1bc7c82404c451e561fc1ed916c0948f6ac561b33a1ccca093f07684b8c2bafa9e966377bd208556018a5bafb9edcecf70498c7140fe9c8cf3ad8b8c3b0aa489df797944465047465415bb0e24333235fcdd59a98829a3941eaaf62033e82 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d 83fed7e49089569ff793255d069999c0ee79df3b244a8ffa56dba6a31b2a3ff1866acafe69d49c9eea801c3ec006c8b7 +3c9a483c9bee33b601549c592a82e95b4319b1e74b777877f0971bcb4273716b268e8f99f876e42f942f4cf08284896bbc1ffbf094ac0956c3cedfc3580cffa8c74fc6db29a371f2da2d05edb9185ece741fe0d3fabfe9d5b4d373755ebed13dc6840cfa3283b9ea46ec8b95c434f253ae86998182e9cc0e95ee64f323fc74b0 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0 96d294145bea1aa53a2c3a91a2f2ec3c428ff7793e7bc14a20cd2aba3c824fce8800d80f2f810052ec5f09be4e555718 +bfc073fdda63c5fccaa0ca8770c293e8154e7aec56128bbac4fdbd541d602216ebf7ca1e02b514d6e396f20683802ba3f334310a9226576926e3bb19ceee27738d13377cbafeb09d091043501702a07aa31d1f29d50ddc55adcf16ffd40578e734a4e6cb6535f26ad48e0c62ad90e79720000e87d419e92dca3e11f943655b03 e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d 970a4dda7e8eca85b5ee5ec1cc1cf08f343c09bb6e8b4c0fbae04e419b61b0fc470e9ffeee8d9b3c9179b323526fd067 +08079955d1a1f33728128c73673ec9f21a6ce138dcab5adc4dc068e6ab57314b9fbd8b013123b2fdafa9524fbdd0288777a233de8055cccfad83046ada6a19f01c47817496667bba8fc8b9456fc0e044a562d931dab1adcb66af8b66325bdf28d83ded3e2937958ccd19da540d70ef2c189f55a506c9c0d63406394c5bd3823b f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7 979b46ed9ea319be1c2582676ee4e342bce3f9514dbf27b3cefd79e00a9bd0056c14da6893eebc7a01565bbd765d2b34 +23900b768f6cd42b8a8df0dcbc9cb5daec8de36b9d5c619adcc1ba2b649103d5af123746cdf19c3fd0665a6fb9338156182aa06181e3c6e37ce56979612af2927440424f89cef43fc754854b8a5c43370808cf5f9929cf47712512ce2f8a2a20d2e9f568c2848b27dfbe09142843c83905ffa5da3b15501761b03dbc2c5398b6 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c 98e1de679ed6c4fee8934c09a1ccf8c465b4cdeae6303dccc4b7b95f8159b2a581897816d939945fb65d5c356a129cea +1eb28c0bcdd18f73e347f957ece15b4cc83a771b0877e1feaac38e24028fb38ccea8b54ee017dc7c3d5a1327bc6f40b294aa65d7dc487f278846cd101ee84202f14b38aa2c275046aa2577f65ebaea41cd383e8def2fd0b4444dcf426fa75c4082cd7fa035cdb1e0d34a3c79d42130f5b0273eae75bc701dda3aebe7358f41b5 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18 b1884a1f1e8dface7ecc5bc548b9e028e02f991d0d547a348b6a2277d7d128e51bb83eb65c68ab6143b6f50833cbf157 +efab51855407438fd5c250670366bca3c026ecec4a59394f00d8a4b51746d0c4564366656d507e3e13e62fe7abeb976b8859895848dbaecf6582f1898ea06f00d4247702ed9721bd375aa83ae4c67c2eaa6e080777ea5ecf2cf787d785389560ac91cf63a52f0373c3185e18a3b8a466e21b61a239f1b77624eb1acacc76c4e1 bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a 820d26017791ba20f7f8fbb8c65ca58db695d00ce117937c6422dde2e24eec5de7d29d2dfcc93f438bf76de633f0234b +31c29ca10279a417f0cc9b1382cf54dbfdfc89f2e6ef08c403c11f580cbf8674b141ed1a417563282d99a55fc616d836421cde9424815c95e7fb7668bf3f137b29937f14882d74e034b732d78d91af7721aac4950734f5fa5d4b4d35534974f8cab6d2e6dca75ddb57e99148c8a59df9fc5bcd723e546e8356f671cf2f65640a dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738 84b4336e3542fad78192290d6704238f18dc43494a958be2cb926a1f02aaef34ed4fe23618fccb845c6d256f2141bf10 +8db476f92e332519c1a0ece5d8deded6efbd2d8e8784eea0a6b4c3b4296c35f5f8de4317e5c1627b91fb1973fee86c06e4992aa5a20cb7475c8808ff1da354d07a488dffa7838c6ec1e3f99e3acba831f27bee8434eeda3eb36d0c6df3658883cd40068b1bed841310f6eb38d4a3d07d85848770ff7933c054cd8b34662660b1 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01 92f3243dbbc4e23129464f4f4d47a55ea0bb75d32917054abd67350469696b9bd6420f1c9615c11cb152499fb083b18c +fcb272c828fe8fd3c6f8de9410c7b6e2b36717c1b0e5e359e9109bd7fc378978aa98182a9d99961898ed88999b050d3b64d1457d7a899d6d273b9f4dde2aafa36d76329d62509043c338f265fc4c7d938459b7fa3b230a9f6cb632b61489546bb4181a5ad7f0d7369b8caced48eb374b075b2b325bc86add0f3b680cd9e80acd 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28 af757855631cd6d2206e7f03c6169083e90f9c1d050b3bc488e62141f5cb2c68348d1a1661fd91fc73d6775f87af1c50 +7522492bdb916a597b8121f3e5c273b1d2800ef8c1db4f7dcbae633b60d7da5193ba53a63d7a377b351897c3b24903ae1cd1994211b259be3e6ae2cbc8970e4957fdf782c7d1bc7a91c80c8ef65468d4ef35428f26e2940ae8b0bd9b8074236bf6c00d0ebe83f9ddb2ade0f835138d39f33b59f244e0037c171f1ba7045a96f5 ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6 b6251110caefae5cd9db922ebba53dc126e2f9d710bd1d1ef1da7e472e1fe47b193a49de290dc31a2d0059b20e3c2dff +61097114ff855c3e34a62d9b853f8982d35f29cfa4a89893badbca7849e5fb437a1a38d6451bf0ca5a0d528e352b8e4b57f2ea359a7fc8841d49dd3e570f9b016f14156b0bbc4be822e260bd147ec081454969e11cb0034b7450ef4deb7ed6edb977e2f4ed60121aa095fb0ab40240dc329ecc917f5c64b4410612af065ee9dd 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc 95c41e85376ff63cf124045ed74cd13cedc97512b36806e0cceec8b480e19f19ccbe53d173080fbb28f3cde39e00af14 +dd09ae6c982bb1440ca175a87766fefeacc49393ff797c446200662744f37a6e30c5d33ba70cbd8f12277fd6cc0704c17478bbab2a3047469e9618e3c340a9c8caaff5ce7c8a4d90ecae6a9b84b813419dec14460298e7521c9b7fdb7a2089328005bd51d57f92a1bcbeecd34aa40482b549e006bbf6c4ce66d34a22dda4e0e0 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b b3bb2c6731cef3d99a14b2321d464a6d6ceadde73b39c034a6312965a74aede46c6894da4a9b0422e3dd15aa13eded95 +37a73e2774d3b274db426c89b945696daa96035031f72cea01894b24508c7f81961ec254d36ed6a0f448e11cf7950af769dc6cd2c47e52c6caf0ea92c270974f0214b4db436c36a60fb722060a6bb544462a82e1714f5906ec32886f7d59ebf289541c3a00ec1e004892ef2b1286a0194f55d083c6ec92c64b8fd1452e1c68ba afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc 8bda7212fd8eca1faae32b5503d06734d2027f14f1df864f4f8967fb85f7fd62cba7d730c5f8330e624a10d9018384fd +9dc2046ffdc6804544db964481abe5d2d276a2a9eeec4c7ad40215b1de23561d402db69bd0f6eec2254711eea4487c64d9a6b62c3ebaf5ffa8db6e7e3a6e17154d126967a47a853a6f8339bdca9be306a13c7f992ded7619b0da59909a49b1e0930360e05b47f18628a36d69b2f87f2bfddd6a5d4a72f84dc76dbdd43f3a6a35 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c 86945bc34a67bbb327d3e6dff3446d2247236a98994385140af5448956379318e9f88f18f4ea3c2116f77803026a40aa +d9c6847fce688c5e7525a1098b545cb6c15dcd21a02761fc82fc664372a667390680135f91c01a2fa5430c634b1a6d1cd6002d8aa021e7bf5956a7901c2f81bc25d502ba5f55a55f30c0323dc68205cbefec0538e68654e7b327ac1743641896c3e740d8f66f400902b304eafaa4e0d8cffae140536f0922444cc3216a675697 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc b6f5d9cc2d3e03d475ee09175f25908f2ca43ae2352e6e27d820b2cc947a52a803ee507e60b0cbb77a4672bccb972985 +69df8a01b66f04930efd2012ff2243874f256ca8758145d2a9e4ecc84d0dbdbd0dc494ae06db0ccbe819918137c90957114558580d6623efbafdd342b38dad9f08708084d32f874fba04782ce26aaab78de2102ad171f8a8f2b30b5bd3d55fdac5fa3acd6f7def7e61c2533938572b331ba6d1c02bd74bfdbf7337ade8f4a190 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4 a0e860b93c30d689414358d6a897446f7b1f00cbf7929d7209375fa65ba3b97512fd3266fe5e9de9a469f3652f3d9296 +927524982b8d60777c1105c86fac05f634abf58c73f84fb95d81ba0b86e1e43592c4fcad2e395a40fbe7005697d86088e2fb3bb7287eb3f917d4f2dc281f5cbe65d05b4f9623bca849b10a03beca6aa2056a12ebb91cf257ac448c5e9a78f8349a6a29b17c8978bef43a443cbb8a149eb23f794844fc41693f2dbb97181444be a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916 b77e8a128a7c5522bde5de1f9d4572c7a94d156663d259f5383d61b346998707177c6bc2164d8877c5d8ac32c4fc9b21 +5f9042283561e7f19a436d01c7ef5a950a6d77ede5629cd7e43c0a5d58e8c5673c37945a453291d12938253c71dbe12c8b022ba7276eda6be034ef5ec1ec77dbd1e08f0d7b8e7725b7ec671c075e008a20f77f4ab266f97079b0aa6337df59a33b881954084057b21f294dd14bcb0869a4a6f1f597955ec7bf9d19bb3537a66a fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b b25ad92a11f58e1e2d2ce4777e8492fb2725aa2c73efd3d26442eeac45118209026a33cd29f90c989b06d63e292e008e +c2ae5573d3bf396523bfb703db8502fd0760cd1be528f6ddbfb95aad399e0b19f3bd9e0fabdb05d49e3f893dffec5b627c9c2f7ad5f32e92e4e27a38cb5c28657657377fdfa1b66cd7ac3d15c6d49df92d284db99f69744f37dc7cb4e7d52920fdb200a7942623a7057ba82e467dcccaa5da416b48510d8364446a6a5e2a5aa8 a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea b5f49b488cb0413c6222e7721f07ee2e08b642981a4fa6fe4f21703d78517736c188a91238c12299b4a059b129cc2a64 +03c1a1cd30a039d0dcb22fee2450a7fa79495a0d0f4f43d2de4d75bce003c0334a8860f5c164dbd94888a9f751235a3e570d31070e3e1293a7be616af7176600585d36ac013600157d2569d491da4b8a3bf3630c26e0b9925412189f50b0ae6f04c86477932e2ecd8c3546106ae1ebc684cc3adb27ed665eddece886adea4ce3 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0 b7eff37f2d0b757c9619a9acd09342f1c19fda7a69cf5bcb9df228d410bc00ea28c70f7b78955335cde06fa4dbb0a499 +888f6d9bc7c86c0079fbfd42d8c08d6958f40f6e570fb0b1f03d2f8f8a63df4fcc87b379a222cf835820a999d34996e08961f13b86b075e7fd1c303cd3baa44de42168561589012f7e5300da4f8bdf470c07119a5d9f7ba7293568cd7c6a1b7fc1e41cda40bed7d46e5a28af67ae2aabfefe67a86a1c601e6f5ee543e09bd7b6 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294 846d6a3fbd7db0065697939146162a38799f5ba7b7164fd47109e3df453ae331dff61c0d08da14573dbf7a55fed67d39 +48453340f1317769e6ee6e103153714365731163dc18f84e9f2fa4b120f9c5a9645ee2f9b66c84c26d95912b422b009b64af96aa418b2427a4209f2e7513ba8e43ec8cf20b34e7529b22eb1199545afe9a9f7d9bcb320aec9ee0162f91c0d1dd9674c9c284f25199c5e109f6f84d7ed0d269cc6413edb81bc2c83e37d644d8b9 b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a 8be7bf6bc83b07c1e08c08490a630a81a2fe6560d300eb4d0153ac283a9d1ad7a43fa3bb1d9316fd6b34a84353723348 +4bdfd3b91d83108409ad765b256e0c9b9937ecf647f8e6f9fc807e2e72af8246178b3fe046b4ea10170450d71a4eec790ecb05f03d7077341de26c4db7eeae24d55c9a9093e837dfdb38168fe8230cb9605825a1282fecd741989bfcdb34678fe077477927f66bd26d003e5dda22043341a14dd31841ba483ad5ce2701e0f68e 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4 aa06d4df8d7358991717fe1fe80771d8fee4b0a31262bba5623a3b915ac9954d81a92c0bd512ad171ba5ffa794b1e7ce +e6cdee8558bc1eacc24e82f0624ce8d02cc8d925b4dd3dec3a72f4a4e0fb76076bfa3ef2e2c33bdd7c27b322bdc09bbfee8fe46f75dbd7bbd2af09690b7137943efe21706e0a1b6d3089540fc58d85ddb55ea836616db573e36c521be008893f40a0a7c349602cc178ea43be59d31ec6449e7ff2c5379379f7d7645134df1bc3 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04 8a18a8b9f8a2e8e724771a31afb0aba7053d74ccb499d28bb52af673af3921aaf8d4c25ca1e1263471d85a3ae1f1aea4 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P224_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P224_blst new file mode 100644 index 000000000000..d75e9620143c --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P224_blst @@ -0,0 +1,60 @@ +699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615 a6fad7d9624aa99b4afdba883471a88ce88e7e0235079405d2b8b119ff5044282b41dba299d66e4c02fc4534e958aa40 +7de42b44db0aa8bfdcdac9add227e8f0cc7ad1d94693beb5e1d325e5f3f85b3bd033fc25e9469a89733a65d1fa641f7e67d668e7c71d736233c4cba20eb83c368c506affe77946b5e2ec693798aecd7ff943cd8fab90affddf5ad5b8d1af332e6c5fe4a2df16837700b2781e08821d4fbdd8373517f5b19f9e63b89cfeeeef6f cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5 b1dc5faa267249da2fd2a19cc250f4dcd26ccc32ad5f8ee8425f24f9dcb28ad0c0e5a33954c82739c7fbf4864e09558c +af0da3adab82784909e2b3dadcecba21eced3c60d7572023dea171044d9a10e8ba67d31b04904541b87fff32a10ccc6580869055fec6216a00320a28899859a6b61faba58a0bc10c2ba07ea16f214c3ddcc9fc5622ad1253b63fe7e95227ae3c9caa9962cffc8b1c4e8260036469d25ab0c8e3643a820b8b3a4d8d43e4b728f9 dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73 afc5a6145709ead13f0d621b5ed3921de1f6f44ed015d51df0e679f8f2c601f38556662e2cf0d6c2d7eb2160894af9ae +cfa56ae89727df6b7266f69d6636bf738f9e4f15f49c42a0123edac4b3743f32ea52389f919ceb90575c4184897773b2f2fc5b3fcb354880f15c93383215d3c2551fcc1b4180a1ac0f69c969bbc306acd115ce3976eff518540f43ad4076dbb5fbad9ce9b3234f1148b8f5e059192ff480fc4bcbd00d25f4d9f5ed4ba5693b6c aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e a27609cd54fc14967765fee061ce57735d351a9289eee54de9ad6a432a1f3bc07dfd0cc2fe297eaec3c4a0a35e06d2c1 +c223c8009018321b987a615c3414d2bb15954933569ca989de32d6bf11107bc47a330ab6d88d9b50d106cf5777d1b736b14bc48deda1bc573a9a7dd42cd061860645306dce7a5ba8c60f135a6a21999421ce8c4670fe7287a7e9ea3aa1e0fa82721f33e6e823957fe86e2283c89ef92b13cd0333c4bb70865ae1919bf538ea34 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4 a45d2336ea02a1845e790e91c1a4282fff4676ad9e51f2b7cbee04b116824d7323a4e0d12c8bfd62a76a01b2920c0e17 +1c27273d95182c74c100d85b5c08f4b26874c2abc87f127f304aedbf52ef6540eba16dd664ae1e9e30ea1e66ff9cc9ab5a80b5bcbd19dde88a29ff10b50a6abd73388e8071306c68d0c9f6caa26b7e68de29312be959b9f4a5481f5a2ad2070a396ed3de21096541cf58c4a13308e08867565bf2df9d649357a83cdcf18d2cd9 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131 950903f95eca515d524bd41d2cac259b9edae5ea4628e44410d5653fa430b26be93154a544f563a173f32d701731f242 +069ae374971627f6b8503f3aa63ab52bcf4f3fcae65b98cdbbf917a5b08a10dc760056714db279806a8d43485320e6fee0f1e0562e077ee270ace8d3c478d79bcdff9cf8b92fdea68421d4a276f8e62ae379387ae06b60af9eb3c40bd7a768aeffccdc8a08bc78ca2eca18061058043a0e441209c5c594842838a4d9d778a053 d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974 ab727a075ce4edd4b973fb2e9ae8b6a23de600bcfc1e7913a6dbb47f126d04c623f16354929e2afb3af1d525a581113c +d0d5ae3e33600aa21c1606caec449eee678c87cb593594be1fbb048cc7cfd076e5cc7132ebe290c4c014e7a517a0d5972759acfa1438d9d2e5d236d19ac92136f6252b7e5bea7588dcba6522b6b18128f003ecab5cb4908832fb5a375cf820f8f0e9ee870653a73dc2282f2d45622a2f0e85cba05c567baf1b9862b79a4b244e 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8 b608287344ad48bf51080726db8d1f61ac945bd75cbe1635415500158dcf62a13dfc7f523d3b1f0bef516532aeb97d9f +79b7375ae7a4f2e4adad8765d14c1540cd9979db38076c157c1837c760ca6febbb18fd42152335929b735e1a08041bd38d315cd4c6b7dd2729de8752f531f07fe4ddc4f1899debc0311eef0019170b58e08895b439ddf09fbf0aeb1e2fd35c2ef7ae402308c3637733802601dd218fb14c22f57870835b10818369d57d318405 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2 b7b7cf62122275389d28973ed30027703bfa2fc693fed32c699a72010aad70fee01c6d4ba61c9b9c44bdfb7b59a28056 +8c7de96e6880d5b6efc19646b9d3d56490775cb3faab342e64db2e388c4bd9e94c4e69a63ccdb7e007a19711e69c06f106b71c983a6d97c4589045666c6ab5ea7b5b6d096ddf6fd35b819f1506a3c37ddd40929504f9f079c8d83820fc8493f97b2298aebe48fdb4ff472b29018fc2b1163a22bfbb1de413e8645e871291a9f6 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7 83d170360e6acb0341ebb07c1b3da118acbb3078b9a6a8b0e2fce9623c7ef9c1f89efc9a5d825b6fb0e73fab54a7243d +c89766374c5a5ccef5823e7a9b54af835ac56afbbb517bd77bfecf3fea876bd0cc9ea486e3d685cfe3fb05f25d9c67992cd7863c80a55c7a263249eb3996c4698ad7381131bf3700b7b24d7ca281a100cf2b750e7f0f933e662a08d9f9e47d779fb03754bd20931262ff381a2fe7d1dc94f4a0520de73fa72020494d3133ecf7 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b a871848863f9ff9d2371de33c6d7526f106d6b98248beef8cc8a033dc30942c93e0fc992e6cdf59e29539d84e37ac75a +30f0e3b502eec5646929d48fd46aa73991d82079c7bd50a38b38ec0bd84167c8cf5ba39bec26999e70208af9b445046cd9d20c82b7629ca1e51bdd00daddbc35f9eb036a15ac57898642d9db09479a38cc80a2e41e380c8a766b2d623de2de798e1eabc02234b89b85d60154460c3bf12764f3fbf17fcccc82df516a2fbe4ecf c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6 aad12ebe38461bc0afea3bb8b44ee0dfb05dfbd81ea0c5624f4b92791175d2d359288383f62cc59b81f5b033be9add1d +6bbb4bf987c8e5069e47c1a541b48b8a3e6d14bfd9ac6dfaa7503b64ab5e1a55f63e91cf5c3e703ac27ad88756dd7fb2d73b909fc15302d0592b974d47e72e60ed339a40b34d39a49b69ea4a5d26ce86f3ca00a70f1cd416a6a5722e8f39d1f0e966981803d6f46dac34e4c7640204cd0d9f1e53fc3acf30096cd00fa80b3ae9 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc 8a14f4e74c7ca0d2c510080d219107b711316c23b2cb54641d925bf4095a2cf16428d5249ce615ae50b599b8d85085fe +05b8f8e56214d4217323f2066f974f638f0b83689fc4ed1201848230efdc1fbca8f70359cecc921050141d3b02c2f17aa306fc2ce5fc06e7d0f4be162fcd985a0b687b4ba09b681cb52ffe890bf5bb4a104cb2e770c04df433013605eb8c72a09902f4246d6c22b8c191ef1b0bece10d5ce2744fc7345307dd1b41b6eff0ca89 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3 88e546afa9f79fdd0255935cacd4c167b9d5e1bcc6bc5720735dd24d7c6ac7a9ea3ef205b7b54cdc1f888e5b44083054 +e5c979f0832242b143077bce6ef146a53bb4c53abfc033473c59f3c4095a68b7a504b609f2ab163b5f88f374f0f3bff8762278b1f1c37323b9ed448e3de33e6443796a9ecaa466aa75175375418186c352018a57ce874e44ae72401d5c0f401b5a51804724c10653fded9066e8994d36a137fdeb9364601daeef09fd174dde4a 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912 95746244222f26562331fa60799153b776b5328684a0e1982d5020eb342da27829b35b1a31413f45aee7275508e809b8 +2b49de971bb0f705a3fb5914eb7638d72884a6c3550667dbfdf301adf26bde02f387fd426a31be6c9ff8bfe8690c8113c88576427f1466508458349fc86036afcfb66448b947707e791e71f558b2bf4e7e7507773aaf4e9af51eda95cbce0a0f752b216f8a54a045d47801ff410ee411a1b66a516f278327df2462fb5619470e 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa 8f1463c2f4e1bea572a37b2c2526f4a1e037d5ac1746533ae67dcea64709c62f50b67d82cea3a2ae3da29b251b6f124e +1fa7201d96ad4d190415f2656d1387fa886afc38e5cd18b8c60da367acf32c627d2c9ea19ef3f030e559fc2a21695cdbb65ddf6ba36a70af0d3fa292a32de31da6acc6108ab2be8bd37843338f0c37c2d62648d3d49013edeb9e179dadf78bf885f95e712fcdfcc8a172e47c09ab159f3a00ed7b930f628c3c48257e92fc7407 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972 8d275f129a761261b794d537b44e70a677852a97ba044e3186f26c7e49d3dd48f021e514a0932d12f41581d66ce3fc5b +74715fe10748a5b98b138f390f7ca9629c584c5d6ad268fc455c8de2e800b73fa1ea9aaee85de58baa2ce9ce68d822fc31842c6b153baef3a12bf6b4541f74af65430ae931a64c8b4950ad1c76b31aea8c229b3623390e233c112586aa5907bbe419841f54f0a7d6d19c003b91dc84bbb59b14ec477a1e9d194c137e21c75bbb f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170 a04cf990b795a0b8509c764f20b7abc082126b3fcbe4c57f5d3230bb0b061471ccb4760254efa4f349c0d3c37504d755 +d10131982dd1a1d839aba383cd72855bf41061c0cb04dfa1acad3181f240341d744ca6002b52f25fb3c63f16d050c4a4ef2c0ebf5f16ce987558f4b9d4a5ad3c6b81b617de00e04ba32282d8bf223bfedbb325b741dfdc8f56fa85c65d42f05f6a1330d8cc6664ad32050dd7b9e3993f4d6c91e5e12cbd9e82196e009ad22560 c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85 b645ba8125f09af09afb5aacf09e3013c104bcdbffb83023f81f18d9e9c1c1f70ce50d0390aa5368aa103afdeb80b88e +ef9dbd90ded96ad627a0a987ab90537a3e7acc1fdfa991088e9d999fd726e3ce1e1bd89a7df08d8c2bf51085254c89dc67bc21e8a1a93f33a38c18c0ce3880e958ac3e3dbe8aec49f981821c4ac6812dd29fab3a9ebe7fbd799fb50f12021b48d1d9abca8842547b3b99befa612cc8b4ca5f9412e0352e72ab1344a0ac2913db 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6 aa8df891943ea43fd355d57e22bf06d7b749533dadca60857be418771c664a9e9624761a6e0e37f80c8766a9cd33a466 +4cc91f744ac858d3577e48813219aa3538dd813b186b42d1e6218376f07cc1cc448ddd6b37240e98bf953f49cf54d65c12878b33c0bf6eb1c60254f0b6fa974f847e53abc56773eef6f29885dfc619e6a48fc15a667ca94001a0c945b6357a53221b0f4b266181456b0d2d25e90708777f1a6f85971c00140c631c1991e0fd06 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39 94f5fbc6b4f85a43048d3adba352a51b3d63cba51c8b59bcb31766b8b8805618682a836cc59feb5d481e30bb06353413 +58f43cc1924de4bc5867664adbc9d26b4f096a43aca47c27c52851b006dc2a658919ef9ce5b5ac48372703be15ac51631c2bd84b88f479f113b0569a9a09e230ec1e8e573474c6075284d3e57d973829af35325d9e7dab4a5f9b065155bbcaff3642a82ef4c9b9e127d3575c050721653da3b087d3fa394192897a5519527d19 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6 b4ddf59065646dd7e24efccb02d8f0c4902a3cc7d6b185f9f20b14b1ea795fd4644adbe58f3429340b24db0e6013e020 +113a2806b052fde683ee09453098e402204155afb3776fd1cad3a9103421d327eab8f9ec0dd050ffcc83f93b34ea707705fabeccfe43ab1a71c95298fd3ec769d99ead1066950eee677d225816e0faad19cf69e1b35d16771689e2092cafe16d7c0dd7b0db73fffb8d0f3eaed83004dd21e753530ec939c89ba25578fa5f785b 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b 80865284810ab1b258a73de70e386f0000140f83b8c742f5df4c0f0c9c9100c63fdc4b4fbff606bedf290a346b39c216 +64cbfc8f2e2149a31b3e8a80c4a552f6c62aaeb7990b6e0ee55500a9d17be04213406578caf315951086dff5c2af3b5ce17d425d185101ef26f86396ba3a129a4f3f8e2dd595f59efb6c0f5c2dcc394569d7268695e9ac7daa84203f1f1895f1f9e4b514a5c9cd23baa63454710144fe735ad9b8f42d8c43267aa434a26d7e5f 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b 8b9978003cc36a79843a496c253e6bc29a72be07a45e82ac9c158ccc9ed71b0a58ede798f7eb9b29b096a07b36d495d5 +a10a11c8e30fff118d371daf824f16c08200b83ea059436466a4611ccac93b2dea2de8c1006f946196aef7fe9b0c251a391b0340f21797798278b412ff2b53842eec6450728e2bca062f8337a2c204b9ea04ff660cd4d4db559f2f11c4d8ef199021339fcc82396f7a93926cf5f247e37d8067fe50692de54f102bd5ab51925c 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8 840968d4f470d78c33c2ec75c2be01d2b9cdc104f861c0200dae435e644fab0ac96f170fc06717b2c8aee1acb0693fc3 +b3f720bf566ffa369259f4361959ae0641d2755ec264a4c4349981df2b02563275b2b9adb5aee47f7a456760a971991ffed6b17809bb9694138d1677fa916123795239353158fc6b22d10f20d26f5d2dcd8c56c44373eea5b93067dba2d7c5318dac2e9e8714873cb1b37f58c011fd14fa1e535554efe05f468bfc8e11cd8b99 e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784 b224b356d9aba988cd738743a00b75766409b7ace5e4dcf49f0e06f1c3d9fc7cfb9f3f9b76d03973fbdee3897711fda5 +0a398a46df7ccc48d1e7833f8bbc67100f1ef77a62dc78bbc115b2a662f9591fbaaa91ad3d788e2fdd1b3164e45293d4f5686c151296901768028ac80ded4bf89c647ad35f0c7c4cb318c0c757c1d83c44d850e5fd4677281b3f13b1ee54de79c8c042813f9d3312dcc6111a68299cb7e829557d7f3d96e702f65aefc6499415 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c ad23e13d1d23467e2097f6c1500a9f79dc14cc88bfc32e314aa2e3cdd40c60ff48f04fbb3fb3ec6dff41127b609ac2ec +8c33616821a6038b448d8918668977fcf1ef5aa0cf7c341837b39bbcc9bca875a3757f4b392630e9995b9bbe4eb66978b877586adaa02f99d2344dae082a7603351d8ffcfca081ab403cd0acb90d078dd1d0789c2eb3185c62bff2d9f04cd38e509e3b83c12ed0a5c6808fc42f7ba5b06acdc496c8ad9be648ee6a4505f8560f 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583 a36db49484996b1076c741ce92add6e6fd54d74384cebe18d9e298ba480564eea9c4e6ac3bd358544c78d66ae932ac44 +94d56535fd4edfe67a0daa6579f9d53bf6b7b8830ae2aeb62892ff59f18756ddf2811b449c7d20d65d54f8507de4e7c50eaa084830637812aa4b250a4d61ab67845be36e4a41cdc0a70f8d6e3a63d4514f0dc197e6486015046a316153d5f3a3a4a0ae1ed7ea5fa55e12e73d333333685c02e0eb636234ea7e6d4b76b4b76b5a 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2 97e956dcf0e861adb02829f5224f871a41f25b03924bf8b0b93add65a44fd060f56aa4a20aa8c78f8eab5b46d69a0556 +5d8ebdf9eb28b47bdafaa36bf0b66a9eaf99b6c83959da4f2b1151b4f4ecd28fb115a64c0cb9491093a7e9b9c53ec423e4c72e7765bb9c818da0e8c428667e44474a71db4867130c77c40bfd8544b2d7b9d6464d2b8e6a48482153256a32437c3a747231f51134dd14c703407e31146a6fcde23bededcf16950486e90ca69ac0 f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc 960985eb63d42a504c3faa1cd43b311905eccc8adc6116531ac48988af99c469f5b15f80ce5dfd1354b935faeed60a8a +25e4416695f77551fdce276355528ccf1ddc2483821c5d22d751d50111ca2fadc6593b52c74f4b5957494f1df25b0b2f86950d0d19229ec6506fee8581d2dd09d48418b146ff16bd84a17ca0dc83b1888eb407376da6c8a88fa1e60b8c2a2471dfde4b3996ef673d5bde3d70c434dc9f2488e9de16ae657d29e5e59ec922a1ec 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd 87385405f4340147df64f4097b00876a008ab490a50d9924f357c23382ec4085215eae93f21ca16ee9f6be6e1777fcaa +9164d633a553deccf3cbd2effccf1387fa3177cd28c95d94a7d1a3e159c5e5c027758cc26493301b2f4d141d8d07a5fe5fead987ce5f30abeafcb48c302afc6c2309f0e93d9b6818cbb6972d222cb7b01302dfe202ae83b89f53150ae4a0e2b8fc0fd1091f19b4ab2e6ab213ab322d04f2c5f57113bfad3c5675227237abf773 e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3 8f217ef7a00273c18e494e167b1b104d3b0373a0a6c096b58d1ca207c92f160bd4f545ad73c655587468b551397949d6 +019df05929321ecea7ee1de4f412aba1c8d3c24437db04b194a68a0a59dd871be10bd3a4be6edf551350ea49fc7155a4d887e1221486291abe77a30633a4c4f7868fe2df24311cba0c73804883954460e122387ed414111ff96ff1aebac8b6a6491d8a0d16e48a63bf3d027c0f68ee4a4b234d73b412196706af8ea022b4dcef b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17 8ef6e609c0290e6140f55eb3cfbf5a8f00a3670c3d449b8b3dbece067a404ad0e6c84c7403409600e10cec829fed742d +5d09d2b1d3fa6e12c10d8b26dc9aabc8dc02bd06e63ff33f8bb91ede4b8694592a69e4ed4cdf6820069e2b9c7803658949e877ffe23bf90bcf5ce1409c06c71d86885a94048b05ac0ec9db193e489a5a2bfa367caf6aa8ecdb032be366174343f6875d2fe1785e8d77334f5f469cec64998e08d3303e5c9a1923b34fdc105d65 efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085 b5241800e389404c99272964cc64cccebeeb67a021e28d0ede66ad4a3bf5f34c1a33cbb4ccb07a803f914d9d1a3c4274 +50f6dfc81c6cf189e0a310f992907fe93356cee9dea9a41c7671a8daf3f4cfe0c459ce6122c1e731dbf7593419d7114cb73b46956158a982c5d52c72f43f0f822046093c69aeff1f7e4cd8af00ba655c5baa2e7b6a400b4be1f6fd51b3e4cfb35a69c80a28c5cafb771b6c2e52e0aeef0e3fd045e8d40745f3f8b74fd969f816 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd 92939a4d321ff797fb91b4c2bb82ab98e8a18949e8d2fb9a50a89ff8a450c6671bf132dac14350e54a119bcc06875123 +e90129ac6672c85bb7b6b18e9dc199c96c81fd65034b53c77818364d512366fb9cd1bc7c82404c451e561fc1ed916c0948f6ac561b33a1ccca093f07684b8c2bafa9e966377bd208556018a5bafb9edcecf70498c7140fe9c8cf3ad8b8c3b0aa489df797944465047465415bb0e24333235fcdd59a98829a3941eaaf62033e82 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d 83fed7e49089569ff793255d069999c0ee79df3b244a8ffa56dba6a31b2a3ff1866acafe69d49c9eea801c3ec006c8b7 +3c9a483c9bee33b601549c592a82e95b4319b1e74b777877f0971bcb4273716b268e8f99f876e42f942f4cf08284896bbc1ffbf094ac0956c3cedfc3580cffa8c74fc6db29a371f2da2d05edb9185ece741fe0d3fabfe9d5b4d373755ebed13dc6840cfa3283b9ea46ec8b95c434f253ae86998182e9cc0e95ee64f323fc74b0 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0 96d294145bea1aa53a2c3a91a2f2ec3c428ff7793e7bc14a20cd2aba3c824fce8800d80f2f810052ec5f09be4e555718 +bfc073fdda63c5fccaa0ca8770c293e8154e7aec56128bbac4fdbd541d602216ebf7ca1e02b514d6e396f20683802ba3f334310a9226576926e3bb19ceee27738d13377cbafeb09d091043501702a07aa31d1f29d50ddc55adcf16ffd40578e734a4e6cb6535f26ad48e0c62ad90e79720000e87d419e92dca3e11f943655b03 e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d 970a4dda7e8eca85b5ee5ec1cc1cf08f343c09bb6e8b4c0fbae04e419b61b0fc470e9ffeee8d9b3c9179b323526fd067 +08079955d1a1f33728128c73673ec9f21a6ce138dcab5adc4dc068e6ab57314b9fbd8b013123b2fdafa9524fbdd0288777a233de8055cccfad83046ada6a19f01c47817496667bba8fc8b9456fc0e044a562d931dab1adcb66af8b66325bdf28d83ded3e2937958ccd19da540d70ef2c189f55a506c9c0d63406394c5bd3823b f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7 979b46ed9ea319be1c2582676ee4e342bce3f9514dbf27b3cefd79e00a9bd0056c14da6893eebc7a01565bbd765d2b34 +23900b768f6cd42b8a8df0dcbc9cb5daec8de36b9d5c619adcc1ba2b649103d5af123746cdf19c3fd0665a6fb9338156182aa06181e3c6e37ce56979612af2927440424f89cef43fc754854b8a5c43370808cf5f9929cf47712512ce2f8a2a20d2e9f568c2848b27dfbe09142843c83905ffa5da3b15501761b03dbc2c5398b6 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c 98e1de679ed6c4fee8934c09a1ccf8c465b4cdeae6303dccc4b7b95f8159b2a581897816d939945fb65d5c356a129cea +1eb28c0bcdd18f73e347f957ece15b4cc83a771b0877e1feaac38e24028fb38ccea8b54ee017dc7c3d5a1327bc6f40b294aa65d7dc487f278846cd101ee84202f14b38aa2c275046aa2577f65ebaea41cd383e8def2fd0b4444dcf426fa75c4082cd7fa035cdb1e0d34a3c79d42130f5b0273eae75bc701dda3aebe7358f41b5 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18 b1884a1f1e8dface7ecc5bc548b9e028e02f991d0d547a348b6a2277d7d128e51bb83eb65c68ab6143b6f50833cbf157 +efab51855407438fd5c250670366bca3c026ecec4a59394f00d8a4b51746d0c4564366656d507e3e13e62fe7abeb976b8859895848dbaecf6582f1898ea06f00d4247702ed9721bd375aa83ae4c67c2eaa6e080777ea5ecf2cf787d785389560ac91cf63a52f0373c3185e18a3b8a466e21b61a239f1b77624eb1acacc76c4e1 bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a 820d26017791ba20f7f8fbb8c65ca58db695d00ce117937c6422dde2e24eec5de7d29d2dfcc93f438bf76de633f0234b +31c29ca10279a417f0cc9b1382cf54dbfdfc89f2e6ef08c403c11f580cbf8674b141ed1a417563282d99a55fc616d836421cde9424815c95e7fb7668bf3f137b29937f14882d74e034b732d78d91af7721aac4950734f5fa5d4b4d35534974f8cab6d2e6dca75ddb57e99148c8a59df9fc5bcd723e546e8356f671cf2f65640a dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738 84b4336e3542fad78192290d6704238f18dc43494a958be2cb926a1f02aaef34ed4fe23618fccb845c6d256f2141bf10 +8db476f92e332519c1a0ece5d8deded6efbd2d8e8784eea0a6b4c3b4296c35f5f8de4317e5c1627b91fb1973fee86c06e4992aa5a20cb7475c8808ff1da354d07a488dffa7838c6ec1e3f99e3acba831f27bee8434eeda3eb36d0c6df3658883cd40068b1bed841310f6eb38d4a3d07d85848770ff7933c054cd8b34662660b1 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01 92f3243dbbc4e23129464f4f4d47a55ea0bb75d32917054abd67350469696b9bd6420f1c9615c11cb152499fb083b18c +fcb272c828fe8fd3c6f8de9410c7b6e2b36717c1b0e5e359e9109bd7fc378978aa98182a9d99961898ed88999b050d3b64d1457d7a899d6d273b9f4dde2aafa36d76329d62509043c338f265fc4c7d938459b7fa3b230a9f6cb632b61489546bb4181a5ad7f0d7369b8caced48eb374b075b2b325bc86add0f3b680cd9e80acd 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28 af757855631cd6d2206e7f03c6169083e90f9c1d050b3bc488e62141f5cb2c68348d1a1661fd91fc73d6775f87af1c50 +7522492bdb916a597b8121f3e5c273b1d2800ef8c1db4f7dcbae633b60d7da5193ba53a63d7a377b351897c3b24903ae1cd1994211b259be3e6ae2cbc8970e4957fdf782c7d1bc7a91c80c8ef65468d4ef35428f26e2940ae8b0bd9b8074236bf6c00d0ebe83f9ddb2ade0f835138d39f33b59f244e0037c171f1ba7045a96f5 ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6 b6251110caefae5cd9db922ebba53dc126e2f9d710bd1d1ef1da7e472e1fe47b193a49de290dc31a2d0059b20e3c2dff +61097114ff855c3e34a62d9b853f8982d35f29cfa4a89893badbca7849e5fb437a1a38d6451bf0ca5a0d528e352b8e4b57f2ea359a7fc8841d49dd3e570f9b016f14156b0bbc4be822e260bd147ec081454969e11cb0034b7450ef4deb7ed6edb977e2f4ed60121aa095fb0ab40240dc329ecc917f5c64b4410612af065ee9dd 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc 95c41e85376ff63cf124045ed74cd13cedc97512b36806e0cceec8b480e19f19ccbe53d173080fbb28f3cde39e00af14 +dd09ae6c982bb1440ca175a87766fefeacc49393ff797c446200662744f37a6e30c5d33ba70cbd8f12277fd6cc0704c17478bbab2a3047469e9618e3c340a9c8caaff5ce7c8a4d90ecae6a9b84b813419dec14460298e7521c9b7fdb7a2089328005bd51d57f92a1bcbeecd34aa40482b549e006bbf6c4ce66d34a22dda4e0e0 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b b3bb2c6731cef3d99a14b2321d464a6d6ceadde73b39c034a6312965a74aede46c6894da4a9b0422e3dd15aa13eded95 +37a73e2774d3b274db426c89b945696daa96035031f72cea01894b24508c7f81961ec254d36ed6a0f448e11cf7950af769dc6cd2c47e52c6caf0ea92c270974f0214b4db436c36a60fb722060a6bb544462a82e1714f5906ec32886f7d59ebf289541c3a00ec1e004892ef2b1286a0194f55d083c6ec92c64b8fd1452e1c68ba afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc 8bda7212fd8eca1faae32b5503d06734d2027f14f1df864f4f8967fb85f7fd62cba7d730c5f8330e624a10d9018384fd +9dc2046ffdc6804544db964481abe5d2d276a2a9eeec4c7ad40215b1de23561d402db69bd0f6eec2254711eea4487c64d9a6b62c3ebaf5ffa8db6e7e3a6e17154d126967a47a853a6f8339bdca9be306a13c7f992ded7619b0da59909a49b1e0930360e05b47f18628a36d69b2f87f2bfddd6a5d4a72f84dc76dbdd43f3a6a35 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c 86945bc34a67bbb327d3e6dff3446d2247236a98994385140af5448956379318e9f88f18f4ea3c2116f77803026a40aa +d9c6847fce688c5e7525a1098b545cb6c15dcd21a02761fc82fc664372a667390680135f91c01a2fa5430c634b1a6d1cd6002d8aa021e7bf5956a7901c2f81bc25d502ba5f55a55f30c0323dc68205cbefec0538e68654e7b327ac1743641896c3e740d8f66f400902b304eafaa4e0d8cffae140536f0922444cc3216a675697 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc b6f5d9cc2d3e03d475ee09175f25908f2ca43ae2352e6e27d820b2cc947a52a803ee507e60b0cbb77a4672bccb972985 +69df8a01b66f04930efd2012ff2243874f256ca8758145d2a9e4ecc84d0dbdbd0dc494ae06db0ccbe819918137c90957114558580d6623efbafdd342b38dad9f08708084d32f874fba04782ce26aaab78de2102ad171f8a8f2b30b5bd3d55fdac5fa3acd6f7def7e61c2533938572b331ba6d1c02bd74bfdbf7337ade8f4a190 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4 a0e860b93c30d689414358d6a897446f7b1f00cbf7929d7209375fa65ba3b97512fd3266fe5e9de9a469f3652f3d9296 +927524982b8d60777c1105c86fac05f634abf58c73f84fb95d81ba0b86e1e43592c4fcad2e395a40fbe7005697d86088e2fb3bb7287eb3f917d4f2dc281f5cbe65d05b4f9623bca849b10a03beca6aa2056a12ebb91cf257ac448c5e9a78f8349a6a29b17c8978bef43a443cbb8a149eb23f794844fc41693f2dbb97181444be a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916 b77e8a128a7c5522bde5de1f9d4572c7a94d156663d259f5383d61b346998707177c6bc2164d8877c5d8ac32c4fc9b21 +5f9042283561e7f19a436d01c7ef5a950a6d77ede5629cd7e43c0a5d58e8c5673c37945a453291d12938253c71dbe12c8b022ba7276eda6be034ef5ec1ec77dbd1e08f0d7b8e7725b7ec671c075e008a20f77f4ab266f97079b0aa6337df59a33b881954084057b21f294dd14bcb0869a4a6f1f597955ec7bf9d19bb3537a66a fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b b25ad92a11f58e1e2d2ce4777e8492fb2725aa2c73efd3d26442eeac45118209026a33cd29f90c989b06d63e292e008e +c2ae5573d3bf396523bfb703db8502fd0760cd1be528f6ddbfb95aad399e0b19f3bd9e0fabdb05d49e3f893dffec5b627c9c2f7ad5f32e92e4e27a38cb5c28657657377fdfa1b66cd7ac3d15c6d49df92d284db99f69744f37dc7cb4e7d52920fdb200a7942623a7057ba82e467dcccaa5da416b48510d8364446a6a5e2a5aa8 a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea b5f49b488cb0413c6222e7721f07ee2e08b642981a4fa6fe4f21703d78517736c188a91238c12299b4a059b129cc2a64 +03c1a1cd30a039d0dcb22fee2450a7fa79495a0d0f4f43d2de4d75bce003c0334a8860f5c164dbd94888a9f751235a3e570d31070e3e1293a7be616af7176600585d36ac013600157d2569d491da4b8a3bf3630c26e0b9925412189f50b0ae6f04c86477932e2ecd8c3546106ae1ebc684cc3adb27ed665eddece886adea4ce3 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0 b7eff37f2d0b757c9619a9acd09342f1c19fda7a69cf5bcb9df228d410bc00ea28c70f7b78955335cde06fa4dbb0a499 +888f6d9bc7c86c0079fbfd42d8c08d6958f40f6e570fb0b1f03d2f8f8a63df4fcc87b379a222cf835820a999d34996e08961f13b86b075e7fd1c303cd3baa44de42168561589012f7e5300da4f8bdf470c07119a5d9f7ba7293568cd7c6a1b7fc1e41cda40bed7d46e5a28af67ae2aabfefe67a86a1c601e6f5ee543e09bd7b6 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294 846d6a3fbd7db0065697939146162a38799f5ba7b7164fd47109e3df453ae331dff61c0d08da14573dbf7a55fed67d39 +48453340f1317769e6ee6e103153714365731163dc18f84e9f2fa4b120f9c5a9645ee2f9b66c84c26d95912b422b009b64af96aa418b2427a4209f2e7513ba8e43ec8cf20b34e7529b22eb1199545afe9a9f7d9bcb320aec9ee0162f91c0d1dd9674c9c284f25199c5e109f6f84d7ed0d269cc6413edb81bc2c83e37d644d8b9 b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a 8be7bf6bc83b07c1e08c08490a630a81a2fe6560d300eb4d0153ac283a9d1ad7a43fa3bb1d9316fd6b34a84353723348 +4bdfd3b91d83108409ad765b256e0c9b9937ecf647f8e6f9fc807e2e72af8246178b3fe046b4ea10170450d71a4eec790ecb05f03d7077341de26c4db7eeae24d55c9a9093e837dfdb38168fe8230cb9605825a1282fecd741989bfcdb34678fe077477927f66bd26d003e5dda22043341a14dd31841ba483ad5ce2701e0f68e 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4 aa06d4df8d7358991717fe1fe80771d8fee4b0a31262bba5623a3b915ac9954d81a92c0bd512ad171ba5ffa794b1e7ce +e6cdee8558bc1eacc24e82f0624ce8d02cc8d925b4dd3dec3a72f4a4e0fb76076bfa3ef2e2c33bdd7c27b322bdc09bbfee8fe46f75dbd7bbd2af09690b7137943efe21706e0a1b6d3089540fc58d85ddb55ea836616db573e36c521be008893f40a0a7c349602cc178ea43be59d31ec6449e7ff2c5379379f7d7645134df1bc3 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04 8a18a8b9f8a2e8e724771a31afb0aba7053d74ccb499d28bb52af673af3921aaf8d4c25ca1e1263471d85a3ae1f1aea4 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P256 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P256 new file mode 100644 index 000000000000..2f5f5b2f26c3 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P256 @@ -0,0 +1,60 @@ +ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590 b47b4acc00a5b7114f1605993716605b9417658fb2a65048ae04660e2706e357e637d3c654045c6a1f3aa99909786e12 +9155e91fd9155eeed15afd83487ea1a3af04c5998b77c0fe8c43dcc479440a8a9a89efe883d9385cb9edfde10b43bce61fb63669935ad39419cf29ef3a936931733bfc2378e253e73b7ae9a3ec7a6a7932ab10f1e5b94d05160c053988f3bdc9167155d069337d42c9a7056619efc031fa5ec7310d29bd28980b1e3559757578 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98 a6f0176dda46e2ed691fc0567b981b685b3aa2f698892c0440051aee2d0df91444f0645ce118d6f90f88b9027712de12 +b242a7586a1383368a33c88264889adfa3be45422fbef4a2df4e3c5325a9c7757017e0d5cf4bbf4de7f99d189f81f1fd2f0dd645574d1eb0d547eead9375677819297c1abe62526ae29fc54cdd11bfe17714f2fbd2d0d0e8d297ff98535980482dd5c1ebdc5a7274aabf1382c9f2315ca61391e3943856e4c5e616c2f1f7be0d a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870 8b42532bc8e93defcb55f3c2aac0235381c55d11f0cd8829c52d24a795881ccce31ca65a778710a1c3500100d1a37f47 +b64005da76b24715880af94dba379acc25a047b06066c9bedc8f17b8c74e74f4fc720d9f4ef0e2a659e0756931c080587ebdcd0f85e819aea6dacb327a9d96496da53ea21aef3b2e793a9c0def5196acec99891f46ead78a85bc7ab644765781d3543da9fbf9fec916dca975ef3b4271e50ecc68bf79b2d8935e2b25fc063358 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f adb159718311090c122a1b337f584e56a049207c002d62da7a867fae61e7391b8cb18dfe07c6d12ffc7a4253dc4df7ca +fe6e1ea477640655eaa1f6e3352d4bce53eb3d95424df7f238e93d8531da8f36bc35fa6be4bf5a6a382e06e855139eb617a9cc9376b4dafacbd80876343b12628619d7cbe1bff6757e3706111ed53898c0219823adbc044eaf8c6ad449df8f6aab9d444dadb5c3380eec0d91694df5fc4b30280d4b87d27e67ae58a1df828963 daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d 8f3c58ffdc19f5e45980bc4e11fa92566b7d8d4c2c03310ac4c84d73abc91dcae15c2be11469e3d7f978e7b40c112580 +907c0c00dc080a688548957b5b8b1f33ba378de1368023dcad43242411f554eb7d392d3e5c1668fad3944ff9634105343d83b8c85d2a988da5f5dc60ee0518327caed6dd5cf4e9bc6222deb46d00abde745f9b71d6e7aee6c7fdfc9ed053f2c0b611d4c6863088bd012ea9810ee94f8e58905970ebd07353f1f409a371ed03e3 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5 a9636017d7b40c15dca62095c5c8e2401630f5a362119a20e89685e743de5987138627fa7b915a5d4759f6eafcd4d8e4 +771c4d7bce05610a3e71b272096b57f0d1efcce33a1cb4f714d6ebc0865b2773ec5eedc25fae81dee1d256474dbd9676623614c150916e6ed92ce4430b26037d28fa5252ef6b10c09dc2f7ee5a36a1ea7897b69f389d9f5075e271d92f4eb97b148f3abcb1e5be0b4feb8278613d18abf6da60bfe448238aa04d7f11b71f44c5 f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96 997efddf99733a1f3f9552585721dccebd8b10664a8be58939ea79065f0e5e8351fcb629001990952453c4d448d75008 +a3b2825235718fc679b942e8ac38fb4f54415a213c65875b5453d18ca012320ddfbbc58b991eaebadfc2d1a28d4f0cd82652b12e4d5bfda89eda3be12ac52188e38e8cce32a264a300c0e463631f525ae501348594f980392c76b4a12ddc88e5ca086cb8685d03895919a8627725a3e00c4728e2b7c6f6a14fc342b2937fc3dd 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d 904728b229d842facbe85b18d7a5c9458db5e7b51fe3fcce31900f6bb9f00775519310279f8506cf871a77cc17f63d6a +3e6e2a9bffd729ee5d4807849cd4250021d8184cda723df6ab0e5c939d39237c8e58af9d869fe62d3c97b3298a99e891e5e11aa68b11a087573a40a3e83c7965e7910d72f81cad0f42accc5c25a4fd3cdd8cee63757bbbfbdae98be2bc867d3bcb1333c4632cb0a55dffeb77d8b119c466cd889ec468454fabe6fbee7102deaf 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9 8ff57d7ec262bcd4f051f7c37689557cd2cfc25cb5aeeca316349eb6c59dde5e2a7da3b420b5162998e9db78c9100071 +52e5c308e70329a17c71eaedb66bbee303c8ec48a6f1a2efb235d308563cd58553d434e12f353227a9ea28608ec9c820ed83c95124e7a886f7e832a2de1032e78dc059208f9ec354170b2b1cab992b52ac01e6c0e4e1b0112686962edc53ab226dafcc9fc7baed2cd9307160e8572edb125935db49289b178f35a8ad23f4f801 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634 9082e05cdafaecf9c3b20050b633302637899418c1d2514e7c68a2e9c1311b21f2bb273da1f377652e851c5131857b6c +d3e9e82051d4c84d699453c9ff44c7c09f6523bb92232bcf30bf3c380224249de2964e871d56a364d6955c81ef91d06482a6c7c61bc70f66ef22fad128d15416e7174312619134f968f1009f92cbf99248932efb533ff113fb6d949e21d6b80dfbbe69010c8d1ccb0f3808ea309bb0bac1a222168c95b088847e613749b19d04 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27 87d7bfd797efb8fc25a57c83dd1044f545e0f925a64f6b052cc7f336c37c3b08278d4dd4092770c4975ffc40c7802596 +968951c2c1918436fe19fa2fe2152656a08f9a6b8aa6201920f1b424da98cee71928897ff087620cc5c551320b1e75a1e98d7d98a5bd5361c9393759614a6087cc0f7fb01fcb173783eb4c4c23961a8231ac4a07d72e683b0c1bd4c51ef1b031df875e7b8d5a6e0628949f5b8f157f43dccaea3b2a4fc11181e6b451e06ceb37 cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d 997a6195924eb6c2371472b14211b4af7725db3e72772ac75c0f9ebd4d82446e3aed1de5ed85c2b48323c1fa9142a2ff +78048628932e1c1cdd1e70932bd7b76f704ba08d7e7d825d3de763bf1a062315f4af16eccefe0b6ebadccaf403d013f50833ce2c54e24eea8345e25f93b69bb048988d102240225ceacf5003e2abdcc90299f4bf2c101585d36ecdd7a155953c674789d070480d1ef47cc7858e97a6d87c41c6922a00ea12539f251826e141b4 b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c a19fcddc17309ba2936b01bc6d18468686470024d934bc2d65c0fba0a69118efc42eee379181b62feec73ebf316a110d +9b0800c443e693067591737fdbcf0966fdfa50872d41d0c189d87cbc34c2771ee5e1255fd604f09fcf167fda16437c245d299147299c69046895d22482db29aba37ff57f756716cd3d6223077f747c4caffbecc0a7c9dfaaafd9a9817470ded8777e6355838ac54d11b2f0fc3f43668ff949cc31de0c2d15af5ef17884e4d66a 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48 99408e731e611152fcb7d3e3ef14abfd4096b7ece5afd748fc4849ce956eb7d9f32d3a30ff4b9d3f5cc23257296ca020 +fc3b8291c172dae635a6859f525beaf01cf683765d7c86f1a4d768df7cae055f639eccc08d7a0272394d949f82d5e12d69c08e2483e11a1d28a4c61f18193106e12e5de4a9d0b4bf341e2acd6b715dc83ae5ff63328f8346f35521ca378b311299947f63ec593a5e32e6bd11ec4edb0e75302a9f54d21226d23314729e061016 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f b2173a226e68422e16706069e0c3ee7a5c1bff0de2a61946bb43031af3a9016d3bcc5b1b03d8af656a50b897c0e1df91 +5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 a7c6393f798b679380a75077a75b8a1efe7c726732bb3cc9aed5c7436c8daf70d7036b9a4aefefa95ce06a7124cb6714 +c35e2f092553c55772926bdbe87c9796827d17024dbb9233a545366e2e5987dd344deb72df987144b8c6c43bc41b654b94cc856e16b96d7a821c8ec039b503e3d86728c494a967d83011a0e090b5d54cd47f4e366c0912bc808fbb2ea96efac88fb3ebec9342738e225f7c7c2b011ce375b56621a20642b4d36e060db4524af1 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 926723d0b900d87ef84edddd1a2d95d2de70709d5993aea6d51c93f0be371604576144eca61fceaa02435918bd5000b2 +3c054e333a94259c36af09ab5b4ff9beb3492f8d5b4282d16801daccb29f70fe61a0b37ffef5c04cd1b70e85b1f549a1c4dc672985e50f43ea037efa9964f096b5f62f7ffdf8d6bfb2cc859558f5a393cb949dbd48f269343b5263dcdb9c556eca074f2e98e6d94c2c29a677afaf806edf79b15a3fcd46e7067b7669f83188ee e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef b96fa9c725f9e17337a7d513837022e03027764c77f0c3b1a8d29b9e3ee5819678bf6639175552f967eb1ae4bfc16589 +0989122410d522af64ceb07da2c865219046b4c3d9d99b01278c07ff63eaf1039cb787ae9e2dd46436cc0415f280c562bebb83a23e639e476a02ec8cff7ea06cd12c86dcc3adefbf1a9e9a9b6646c7599ec631b0da9a60debeb9b3e19324977f3b4f36892c8a38671c8e1cc8e50fcd50f9e51deaf98272f9266fc702e4e57c30 a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 b66ecb8bc6676ac07253c1dfea8977189caba6a132007af04963ca5c6905b98138fe7acc68a97b4c55c9deec60067b79 +dc66e39f9bbfd9865318531ffe9207f934fa615a5b285708a5e9c46b7775150e818d7f24d2a123df3672fff2094e3fd3df6fbe259e3989dd5edfcccbe7d45e26a775a5c4329a084f057c42c13f3248e3fd6f0c76678f890f513c32292dd306eaa84a59abe34b16cb5e38d0e885525d10336ca443e1682aa04a7af832b0eee4e7 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d b888ecfb33a82661e644dcf3cb8634a284f8e531d3fb33686db7321748aebe2c7025eab99ebe6c29d0b9a7baeb1d34a2 +600974e7d8c5508e2c1aab0783ad0d7c4494ab2b4da265c2fe496421c4df238b0be25f25659157c8a225fb03953607f7df996acfd402f147e37aee2f1693e3bf1c35eab3ae360a2bd91d04622ea47f83d863d2dfecb618e8b8bdc39e17d15d672eee03bb4ce2cc5cf6b217e5faf3f336fdd87d972d3a8b8a593ba85955cc9d71 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d a83800ba1da1f8f753caedb73efa2b207536ea100fb96889e7e93947438b2384a2175fe32d55567c2c8a47efcd0d03c0 +dfa6cb9b39adda6c74cc8b2a8b53a12c499ab9dee01b4123642b4f11af336a91a5c9ce0520eb2395a6190ecbf6169c4cba81941de8e76c9c908eb843b98ce95e0da29c5d4388040264e05e07030a577cc5d176387154eabae2af52a83e85c61c7c61da930c9b19e45d7e34c8516dc3c238fddd6e450a77455d534c48a152010b 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab a4b23872e6bce44367ac38ce03ac27ba18b6298c20856c40c8567f60248cc69211c7e74b0b307f0c5449f90d6c30bccf +51d2547cbff92431174aa7fc7302139519d98071c755ff1c92e4694b58587ea560f72f32fc6dd4dee7d22bb7387381d0256e2862d0644cdf2c277c5d740fa089830eb52bf79d1e75b8596ecf0ea58a0b9df61e0c9754bfcd62efab6ea1bd216bf181c5593da79f10135a9bc6e164f1854bc8859734341aad237ba29a81a3fc8b 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a 8fce473ad2f7df28f858a42d8968d42ddac0555ae2ac887d5a9f0589abaef0ecb377ac0119789536f1605d6fae076509 +558c2ac13026402bad4a0a83ebc9468e50f7ffab06d6f981e5db1d082098065bcff6f21a7a74558b1e8612914b8b5a0aa28ed5b574c36ac4ea5868432a62bb8ef0695d27c1e3ceaf75c7b251c65ddb268696f07c16d2767973d85beb443f211e6445e7fe5d46f0dce70d58a4cd9fe70688c035688ea8c6baec65a5fc7e2c93e8 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 b513cbdbb341efedbb2fa3b69a2b11b020a18dfabaeda493dde23eec2532bd84c361d543cafbbda18ed50810e35005db +4d55c99ef6bd54621662c3d110c3cb627c03d6311393b264ab97b90a4b15214a5593ba2510a53d63fb34be251facb697c973e11b665cb7920f1684b0031b4dd370cb927ca7168b0bf8ad285e05e9e31e34bc24024739fdc10b78586f29eff94412034e3b606ed850ec2c1900e8e68151fc4aee5adebb066eb6da4eaa5681378e f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 ae9145fddbb589dc1277e6b5c2c0ca60da4b2e5b92ae97cd488d007f4a08cde551bb197fe8776223c3619db719400d01 +f8248ad47d97c18c984f1f5c10950dc1404713c56b6ea397e01e6dd925e903b4fadfe2c9e877169e71ce3c7fe5ce70ee4255d9cdc26f6943bf48687874de64f6cf30a012512e787b88059bbf561162bdcc23a3742c835ac144cc14167b1bd6727e940540a9c99f3cbb41fb1dcb00d76dda04995847c657f4c19d303eb09eb48a b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 b55291d45782afea1f68c7e3a0cdf09cc0a48876b43acff115ce3628c8315e1166ab64bc37ed6c24463e5e4706b4a69b +3b6ee2425940b3d240d35b97b6dcd61ed3423d8e71a0ada35d47b322d17b35ea0472f35edd1d252f87b8b65ef4b716669fc9ac28b00d34a9d66ad118c9d94e7f46d0b4f6c2b2d339fd6bcd351241a387cc82609057048c12c4ec3d85c661975c45b300cb96930d89370a327c98b67defaa89497aa8ef994c77f1130f752f94a4 d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 b447b9f173980d7648cd65288ce125ab39173044397774940e69dbaa2079b20619b66e4165f6c2dee1a7b07765f8d213 +c5204b81ec0a4df5b7e9fda3dc245f98082ae7f4efe81998dcaa286bd4507ca840a53d21b01e904f55e38f78c3757d5a5a4a44b1d5d4e480be3afb5b394a5d2840af42b1b4083d40afbfe22d702f370d32dbfd392e128ea4724d66a3701da41ae2f03bb4d91bb946c7969404cb544f71eb7a49eb4c4ec55799bda1eb545143a7 b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c 9571072b029ac09e144a32c570762d6bce5527348bf390cd49dd7d96f3a828af70a5e3116fcbc804dc7789efdb052729 +72e81fe221fb402148d8b7ab03549f1180bcc03d41ca59d7653801f0ba853add1f6d29edd7f9abc621b2d548f8dbf8979bd16608d2d8fc3260b4ebc0dd42482481d548c7075711b5759649c41f439fad69954956c9326841ea6492956829f9e0dc789f73633b40f6ac77bcae6dfc7930cfe89e526d1684365c5b0be2437fdb01 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 923da31544c8d4c0b58e95473a74aaa7f7155ab133bd2c0423c6ed8c47c42625ef4c75a7c644055b08ccf80b0b1d8d92 +21188c3edd5de088dacc1076b9e1bcecd79de1003c2414c3866173054dc82dde85169baa77993adb20c269f60a5226111828578bcc7c29e6e8d2dae81806152c8ba0c6ada1986a1983ebeec1473a73a04795b6319d48662d40881c1723a706f516fe75300f92408aa1dc6ae4288d2046f23c1aa2e54b7fb6448a0da922bd7f34 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 963a093865d4f68fa97881be34cbd7e1bf99ddb2d4f0041c95c6d92739821fc0bad4bdaf180ae313fbd927228da4aaf2 +e0b8596b375f3306bbc6e77a0b42f7469d7e83635990e74aa6d713594a3a24498feff5006790742d9c2e9b47d714bee932435db747c6e733e3d8de41f2f91311f2e9fd8e025651631ffd84f66732d3473fbd1627e63dc7194048ebec93c95c159b5039ab5e79e42c80b484a943f125de3da1e04e5bf9c16671ad55a1117d3306 b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced 82713607cc58c9824ec0de251588b4083087d46934b05216ae4eeb61c9b1b51d711d7f8d0ce3a890d9a5a6e9657aff40 +099a0131179fff4c6928e49886d2fdb3a9f239b7dd5fa828a52cbbe3fcfabecfbba3e192159b887b5d13aa1e14e6a07ccbb21f6ad8b7e88fee6bea9b86dea40ffb962f38554056fb7c5bb486418915f7e7e9b9033fe3baaf9a069db98bc02fa8af3d3d1859a11375d6f98aa2ce632606d0800dff7f55b40f971a8586ed6b39e9 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181 abb263fb08d91428b69a50d2da685e596c8d97ed76d1dc76749da64d5b246a565389f314470404cf6fc879fc0ab4d5d5 +0fbc07ea947c946bea26afa10c51511039b94ddbc4e2e4184ca3559260da24a14522d1497ca5e77a5d1a8e86583aeea1f5d4ff9b04a6aa0de79cd88fdb85e01f171143535f2f7c23b050289d7e05cebccdd131888572534bae0061bdcc3015206b9270b0d5af9f1da2f9de91772d178a632c3261a1e7b3fb255608b3801962f9 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431 91039aca4dccf02f79d93fd36789f583111bb44513322af885b6cb77e06ae5c4f1558495209a3aff279d4c49693a998f +1e38d750d936d8522e9db1873fb4996bef97f8da3c6674a1223d29263f1234a90b751785316444e9ba698bc8ab6cd010638d182c9adad4e334b2bd7529f0ae8e9a52ad60f59804b2d780ed52bdd33b0bf5400147c28b4304e5e3434505ae7ce30d4b239e7e6f0ecf058badd5b388eddbad64d24d2430dd04b4ddee98f972988f 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd a2bc63399f12bbfa7fbcdc1758785c0c4fd595ed67d4bcd7cb0bf50403d822f3f75e5a8b45a44b10935efbd49c274678 +abcf0e0f046b2e0672d1cc6c0a114905627cbbdefdf9752f0c31660aa95f2d0ede72d17919a9e9b1add3213164e0c9b5ae3c76f1a2f79d3eeb444e6741521019d8bd5ca391b28c1063347f07afcfbb705be4b52261c19ebaf1d6f054a74d86fb5d091fa7f229450996b76f0ada5f977b09b58488eebfb5f5e9539a8fd89662ab 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de 8fb37a0e8e8334e8fb784704314bfebf05e213d17c097e36e36fbd71141cd84fd05da6b3d68a408d08e8eff40d3fc16b +dc3d4884c741a4a687593c79fb4e35c5c13c781dca16db561d7e393577f7b62ca41a6e259fc1fb8d0c4e1e062517a0fdf95558b7799f20c211796167953e6372c11829beec64869d67bf3ee1f1455dd87acfbdbcc597056e7fb347a17688ad32fda7ccc3572da7677d7255c261738f07763cd45973c728c6e9adbeecadc3d961 ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566 8760cb93deaefc98d2d94528f90dc306b8f68a86eda29112000d4fa983047a7ddd9ab50b177cfc2ada740cdec03236a4 +719bf1911ae5b5e08f1d97b92a5089c0ab9d6f1c175ac7199086aeeaa416a17e6d6f8486c711d386f284f096296689a54d330c8efb0f5fa1c5ba128d3234a3da856c2a94667ef7103616a64c913135f4e1dc50e38daa60610f732ad1bedfcc396f87169392520314a6b6b9af6793dbabad4599525228cc7c9c32c4d8e097ddf6 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee a7b21b27f376f13c3e089990b0efa6d3366a1a942331f43a052f1a3075189d159657a4eea4c161be352e4a534a6b6c41 +7cf19f4c851e97c5bca11a39f0074c3b7bd3274e7dd75d0447b7b84995dfc9f716bf08c25347f56fcc5e5149cb3f9cfb39d408ace5a5c47e75f7a827fa0bb9921bb5b23a6053dbe1fa2bba341ac874d9b1333fc4dc224854949f5c8d8a5fedd02fb26fdfcd3be351aec0fcbef18972956c6ec0effaf057eb4420b6d28e0c008c 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd af59654ecb8cd2c2263141bde2e9122e561491badeec4097b5a285a4bc4d1e12fdb18893124ee165e6bf1013eb99848d +b892ffabb809e98a99b0a79895445fc734fa1b6159f9cddb6d21e510708bdab6076633ac30aaef43db566c0d21f4381db46711fe3812c5ce0fb4a40e3d5d8ab24e4e82d3560c6dc7c37794ee17d4a144065ef99c8d1c88bc22ad8c4c27d85ad518fa5747ae35276fc104829d3f5c72fc2a9ea55a1c3a87007cd133263f79e405 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666 b343deb369e67a1cacb75edc209a8aa9d81f4a7445cc223162b3c5d488ad98857de6738bfaed87a7b49fef608bef3421 +8144e37014c95e13231cbd6fa64772771f93b44e37f7b02f592099cc146343edd4f4ec9fa1bc68d7f2e9ee78fc370443aa2803ff4ca52ee49a2f4daf2c8181ea7b8475b3a0f608fc3279d09e2d057fbe3f2ffbe5133796124781299c6da60cfe7ecea3abc30706ded2cdf18f9d788e59f2c31662df3abe01a9b12304fb8d5c8c bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67 97763dbaf0bafbe792e75fe8f15198fb116ee67ce09bad2a0209c0ac923694ce10009371efccd87a4bbb1abaeaf42f83 +a3683d120807f0a030feed679785326698c3702f1983eaba1b70ddfa7f0b3188060b845e2b67ed57ee68087746710450f7427cb34655d719c0acbc09ac696adb4b22aba1b9322b7111076e67053a55f62b501a4bca0ad9d50a868f51aeeb4ef27823236f5267e8da83e143047422ce140d66e05e44dc84fb3a4506b2a5d7caa8 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9 824d163181c3d6f1cd452ac830354b8d0c029438ec99b3ed40e569de6903821662e5345e7179dced1d0fc1fb459003f7 +b1df8051b213fc5f636537e37e212eb20b2423e6467a9c7081336a870e6373fc835899d59e546c0ac668cc81ce4921e88f42e6da2a109a03b4f4e819a17c955b8d099ec6b282fb495258dca13ec779c459da909475519a3477223c06b99afbd77f9922e7cbef844b93f3ce5f50db816b2e0d8b1575d2e17a6b8db9111d6da578 f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce ae888b21cacfca6790f22ce5c4d204d9418481191074e90c02d747d23cb820d8b11c88b58d591965b4d2e265031a727a +0b918ede985b5c491797d0a81446b2933be312f419b212e3aae9ba5914c00af431747a9d287a7c7761e9bcbc8a12aaf9d4a76d13dad59fc742f8f218ef66eb67035220a07acc1a357c5b562ecb6b895cf725c4230412fefac72097f2c2b829ed58742d7c327cad0f1058df1bddd4ae9c6d2aba25480424308684cecd6517cdd8 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f 961fa49996ae294df12abf0bb9afb1fafda88beb82568c2ced724086193b95540c5dc28178c9cc57cc8bd30832c2f5d1 +0fab26fde1a4467ca930dbe513ccc3452b70313cccde2994eead2fde85c8da1db84d7d06a024c9e88629d5344224a4eae01b21a2665d5f7f36d5524bf5367d7f8b6a71ea05d413d4afde33777f0a3be49c9e6aa29ea447746a9e77ce27232a550b31dd4e7c9bc8913485f2dc83a56298051c92461fd46b14cc895c300a4fb874 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b 89b2d8f097c47f9d1bb914a72846ec29cb7954efda00d31a375f20cf737dfea4b298289557395569e491f8a08df1fafc +7843f157ef8566722a7d69da67de7599ee65cb3975508f70c612b3289190e364141781e0b832f2d9627122742f4b5871ceeafcd09ba5ec90cae6bcc01ae32b50f13f63918dfb5177df9797c6273b92d103c3f7a3fc2050d2b196cc872c57b77f9bdb1782d4195445fcc6236dd8bd14c8bcbc8223a6739f6a17c9a861e8c821a6 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388 a3d3d0d3efd8c2053fde4504fd51c0f6c501ef6e92897a7783290d2a1f93c1b8ceaa9a168e475bcc152e6693c116cdb9 +6c8572b6a3a4a9e8e03dbeed99334d41661b8a8417074f335ab1845f6cc852adb8c01d9820fcf8e10699cc827a8fbdca2cbd46cc66e4e6b7ba41ec3efa733587e4a30ec552cd8ddab8163e148e50f4d090782897f3ddac84a41e1fcfe8c56b6152c0097b0d634b41011471ffd004f43eb4aafc038197ec6bae2b4470e869bded 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499 b30084cb25e9b002fef4f882b6e38bdaffd321cca13231fd889b9d96201edc77d4b1659aad2e0fec71724d21f02611ce +7e3c8fe162d48cc8c5b11b5e5ebc05ebc45c439bdbc0b0902145921b8383037cb0812222031598cd1a56fa71694fbd304cc62938233465ec39c6e49f57dfe823983b6923c4e865633949183e6b90e9e06d8275f3907d97967d47b6239fe2847b7d49cf16ba69d2862083cf1bccf7afe34fdc90e21998964107b64abe6b89d126 f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6 814c5622e395854d67ad19a8a76585e5721f738e096a9b9b11add447d54e891da769dfe2578e488bc0c37c30cf92eb18 +d5aa8ac9218ca661cd177756af6fbb5a40a3fecfd4eea6d5872fbb9a2884784aa9b5f0c023a6e0da5cf6364754ee6465b4ee2d0ddc745b02994c98427a213c849537da5a4477b3abfe02648be67f26e80b56a33150490d062aaac137aa47f11cfeddba855bab9e4e028532a563326d927f9e6e3292b1fb248ee90b6f429798db 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead b055589b690bc8526acb8817015f103211445a28b839472fdf47e9dae217fdd5d8ae695feaf7b9bcd22a241171766720 +790b06054afc9c3fc4dfe72df19dd5d68d108cfcfca6212804f6d534fd2fbe489bd8f64bf205ce04bcb50124a12ce5238fc3fe7dd76e6fa640206af52549f133d593a1bfd423ab737f3326fa79433cde293236f90d4238f0dd38ed69492ddbd9c3eae583b6325a95dec3166fe52b21658293d8c137830ef45297d67813b7a508 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd 954147276730c67f8cc7829103b958c8787be0cd3b7949140d8c83f2afd87da4464f7ea3fb1c126afafd00457b129ada +6d549aa87afdb8bfa60d22a68e2783b27e8db46041e4df04be0c261c4734b608a96f198d1cdb8d082ae48579ec9defcf21fbc72803764a58c31e5323d5452b9fb57c8991d31749140da7ef067b18bf0d7dfbae6eefd0d8064f334bf7e9ec1e028daed4e86e17635ec2e409a3ed1238048a45882c5c57501b314e636b9bc81cbe 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117 ac967336be36a05bcbb924bf5191a733135eea266a462dce34518398ad9922c8530cd0d01185642c0084c5c42400c1c8 +1906e48b7f889ee3ff7ab0807a7aa88f53f4018808870bfed6372a77330c737647961324c2b4d46f6ee8b01190474951a701b048ae86579ff8e3fc889fecf926b17f98958ac7534e6e781ca2db2baa380dec766cfb2a3eca2a9d5818967d64dfab84f768d24ec122eebacaab0a4dc3a75f37331bb1c43dd8966cc09ec4945bbd 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61 996d76f092ff4db114ea50776f87a9d66316f25afc68721dbcf298cde3e2b779feb2bc7ac7308ae7d1bc07d287be15e5 +7b59fef13daf01afec35dea3276541be681c4916767f34d4e874464d20979863ee77ad0fd1635bcdf93e9f62ed69ae52ec90aab5bbf87f8951213747ccec9f38c775c1df1e9d7f735c2ce39b42edb3b0c5086247556cfea539995c5d9689765288ec600848ecf085c01ca738bbef11f5d12d4457db988b4add90be00781024ad 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2 8419243528fafae3bdce68e327e81a2fd83882bf1c0941e8f9b67303d9ea1179df2f44826a8f35d73e731177ffaeb996 +041a6767a935dc3d8985eb4e608b0cbfebe7f93789d4200bcfe595277ac2b0f402889b580b72def5da778a680fd380c955421f626d52dd9a83ea180187b850e1b72a4ec6dd63235e598fd15a9b19f8ce9aec1d23f0bd6ea4d92360d50f951152bc9a01354732ba0cf90aaed33c307c1de8fa3d14f9489151b8377b57c7215f0b 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7 84e8204364d6b547956146bb1b26528cb0aaf9a0032a125a91e179ca62d3872add3e0eeaaf588204be2905c3c6dcc36f +7905a9036e022c78b2c9efd40b77b0a194fbc1d45462779b0b76ad30dc52c564e48a493d8249a061e62f26f453ba566538a4d43c64fb9fdbd1f36409316433c6f074e1b47b544a847de25fc67d81ac801ed9f7371a43da39001c90766f943e629d74d0436ba1240c3d7fab990d586a6d6ef1771786722df56448815f2feda48f 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870 8a8185fdb2ef67a011236ecc0dd83f535bbf16206d5b1bd4f8937f588f50685e648b690d03134e274e013806257d2f9b +cf25e4642d4f39d15afb7aec79469d82fc9aedb8f89964e79b749a852d931d37436502804e39555f5a3c75dd958fd5291ada647c1a5e38fe7b1048f16f2b711fdd5d39acc0812ca65bd50d7f8119f2fd195ab16633503a78ee9102c1f9c4c22568e0b54bd4fa3f5ff7b49160bf23e7e2231b1ebebbdaf0e4a7d4484158a87e07 e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf a79c55afd172b0f40ffadc8759653d72b924ff07efc5a0ee2843c7f9b46552290c219f9a65b6d3fa410ccdd587ef9acd +7562c445b35883cc937be6349b4cefc3556a80255d70f09e28c3f393daac19442a7eecedcdfbe8f7628e30cd8939537ec56d5c9645d43340eb4e78fc5dd4322de8a07966b262770d7ff13a071ff3dce560718e60ed3086b7e0003a6abafe91af90af86733ce8689440bf73d2aa0acfe9776036e877599acbabfcb03bb3b50faa 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c a04da18e7da011d6ca87a1dedeaa938b53d60947ca6eb8cfacbfffb90dd5568c114a28e827662629eeafb36c1144583f +051c2db8e71e44653ea1cb0afc9e0abdf12658e9e761bfb767c20c7ab4adfcb18ed9b5c372a3ac11d8a43c55f7f99b33355437891686d42362abd71db8b6d84dd694d6982f0612178a937aa934b9ac3c0794c39027bdd767841c4370666c80dbc0f8132ca27474f553d266deefd7c9dbad6d734f9006bb557567701bb7e6a7c9 f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9 ab0b2a748a650570f02518d967f531c11fe3a304b87305c30c41a9f928cfe625f08de5d0a83eb3c70e7e75b665723b65 +4dcb7b62ba31b866fce7c1feedf0be1f67bf611dbc2e2e86f004422f67b3bc1839c6958eb1dc3ead137c3d7f88aa97244577a775c8021b1642a8647bba82871e3c15d0749ed343ea6cad38f123835d8ef66b0719273105e924e8685b65fd5dc430efbc35b05a6097f17ebc5943cdcd9abcba752b7f8f37027409bd6e11cd158f f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5 b3566d4c609509c7c751c6228ea0665da64684af34aa7aa9e1c8ed0bb42be9c49c9d7db232752198dba050e268098b33 +efe55737771070d5ac79236b04e3fbaf4f2e9bed187d1930680fcf1aba769674bf426310f21245006f528779347d28b8aeacd2b1d5e3456dcbf188b2be8c07f19219e4067c1e7c9714784285d8bac79a76b56f2e2676ea93994f11eb573af1d03fc8ed1118eafc7f07a82f3263c33eb85e497e18f435d4076a774f42d276c323 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628 a5f69ac0a98475e7612d82f8e13795cd55ec5471b03e1868aeb27eb4dbcf8330e9a65087c79366207ce8c4d3ba650110 +ea95859cc13cccb37198d919803be89c2ee10befdcaf5d5afa09dcc529d333ae1e4ffd3bd8ba8642203badd7a80a3f77eeee9402eed365d53f05c1a995c536f8236ba6b6ff8897393506660cc8ea82b2163aa6a1855251c87d935e23857fe35b889427b449de7274d7754bdeace960b4303c5dd5f745a5cfd580293d6548c832 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49 b0da9179f3fbfcdb08a0367885b1aaf3f2bd61a5f6db3a08e8c588b44ecdf079b9559dfbb2b828f4b9efe1b30c068d50 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P256_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P256_blst new file mode 100644 index 000000000000..859fedd552b5 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P256_blst @@ -0,0 +1,60 @@ +ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590 b0511aa1a9f37d4c66498ed24ca5aa64f7baa3816ebdbc3b158b4c4ec2ce7a54a558bb91695029e64081e4eb2c4ec70a +9155e91fd9155eeed15afd83487ea1a3af04c5998b77c0fe8c43dcc479440a8a9a89efe883d9385cb9edfde10b43bce61fb63669935ad39419cf29ef3a936931733bfc2378e253e73b7ae9a3ec7a6a7932ab10f1e5b94d05160c053988f3bdc9167155d069337d42c9a7056619efc031fa5ec7310d29bd28980b1e3559757578 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98 8e8e4c6b0b8eeec9d3ffbb350470dcb6195e5b797406052db66d9909eaff0964512a2783d52614652fbf4a7277231ce2 +b242a7586a1383368a33c88264889adfa3be45422fbef4a2df4e3c5325a9c7757017e0d5cf4bbf4de7f99d189f81f1fd2f0dd645574d1eb0d547eead9375677819297c1abe62526ae29fc54cdd11bfe17714f2fbd2d0d0e8d297ff98535980482dd5c1ebdc5a7274aabf1382c9f2315ca61391e3943856e4c5e616c2f1f7be0d a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870 8af84ad717692e4daeb3f9b6d417efac8bf9bf9eba909c095af88ae762030e24f8dcdf86a97857232d141c14ba7935be +b64005da76b24715880af94dba379acc25a047b06066c9bedc8f17b8c74e74f4fc720d9f4ef0e2a659e0756931c080587ebdcd0f85e819aea6dacb327a9d96496da53ea21aef3b2e793a9c0def5196acec99891f46ead78a85bc7ab644765781d3543da9fbf9fec916dca975ef3b4271e50ecc68bf79b2d8935e2b25fc063358 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f 866be01d59587c49c3fd2842d0e14f7bf80f9876eed6f67fc15fed936834dcc555682c52ba75bcf113017bd87f2005cd +fe6e1ea477640655eaa1f6e3352d4bce53eb3d95424df7f238e93d8531da8f36bc35fa6be4bf5a6a382e06e855139eb617a9cc9376b4dafacbd80876343b12628619d7cbe1bff6757e3706111ed53898c0219823adbc044eaf8c6ad449df8f6aab9d444dadb5c3380eec0d91694df5fc4b30280d4b87d27e67ae58a1df828963 daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d b1c0dfd4876672c770a31f74c17c0936b13192391252254065af302013c8a156be87d752be94921b35d041d9230bfaa2 +907c0c00dc080a688548957b5b8b1f33ba378de1368023dcad43242411f554eb7d392d3e5c1668fad3944ff9634105343d83b8c85d2a988da5f5dc60ee0518327caed6dd5cf4e9bc6222deb46d00abde745f9b71d6e7aee6c7fdfc9ed053f2c0b611d4c6863088bd012ea9810ee94f8e58905970ebd07353f1f409a371ed03e3 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5 877bf6cd232bd109b02b910448c5991da3a133395e5b076c0c6d4d99077282c9a810baf3ae480e80e1eab823a513050d +771c4d7bce05610a3e71b272096b57f0d1efcce33a1cb4f714d6ebc0865b2773ec5eedc25fae81dee1d256474dbd9676623614c150916e6ed92ce4430b26037d28fa5252ef6b10c09dc2f7ee5a36a1ea7897b69f389d9f5075e271d92f4eb97b148f3abcb1e5be0b4feb8278613d18abf6da60bfe448238aa04d7f11b71f44c5 f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96 b19b80f17db3115bcff231d8c59421e3ed3a36bbed4f2c870dc5c474f46a20e4f56467d98056e52fdf7457a6febb8743 +a3b2825235718fc679b942e8ac38fb4f54415a213c65875b5453d18ca012320ddfbbc58b991eaebadfc2d1a28d4f0cd82652b12e4d5bfda89eda3be12ac52188e38e8cce32a264a300c0e463631f525ae501348594f980392c76b4a12ddc88e5ca086cb8685d03895919a8627725a3e00c4728e2b7c6f6a14fc342b2937fc3dd 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d 8ea774dd22b6ae801ead5b679dddb843ec67737644b73101920838a568fd3e2fda713463efb7905975ef3cf54e0c146e +3e6e2a9bffd729ee5d4807849cd4250021d8184cda723df6ab0e5c939d39237c8e58af9d869fe62d3c97b3298a99e891e5e11aa68b11a087573a40a3e83c7965e7910d72f81cad0f42accc5c25a4fd3cdd8cee63757bbbfbdae98be2bc867d3bcb1333c4632cb0a55dffeb77d8b119c466cd889ec468454fabe6fbee7102deaf 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9 ab52d8cf93dc4a6f8ca2636bf99a612a1d72d6ff9539b4cc55da427c6ece04e449a8dc37e79f6e0998766c428f68e858 +52e5c308e70329a17c71eaedb66bbee303c8ec48a6f1a2efb235d308563cd58553d434e12f353227a9ea28608ec9c820ed83c95124e7a886f7e832a2de1032e78dc059208f9ec354170b2b1cab992b52ac01e6c0e4e1b0112686962edc53ab226dafcc9fc7baed2cd9307160e8572edb125935db49289b178f35a8ad23f4f801 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634 a70af608ea0fe4ef94e41558476efbb9090659d74d7c1b28c0ddc64be06dda8bdf14f0ae791c1f3b9e403df077530b44 +d3e9e82051d4c84d699453c9ff44c7c09f6523bb92232bcf30bf3c380224249de2964e871d56a364d6955c81ef91d06482a6c7c61bc70f66ef22fad128d15416e7174312619134f968f1009f92cbf99248932efb533ff113fb6d949e21d6b80dfbbe69010c8d1ccb0f3808ea309bb0bac1a222168c95b088847e613749b19d04 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27 9288f5dc79dcd63f10a0b7e3311cb1a1d2240486f03fefa734c4a5d56b839c4c0f602a11a6babf7b34c3efd0a6506e53 +968951c2c1918436fe19fa2fe2152656a08f9a6b8aa6201920f1b424da98cee71928897ff087620cc5c551320b1e75a1e98d7d98a5bd5361c9393759614a6087cc0f7fb01fcb173783eb4c4c23961a8231ac4a07d72e683b0c1bd4c51ef1b031df875e7b8d5a6e0628949f5b8f157f43dccaea3b2a4fc11181e6b451e06ceb37 cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d 91b5a0cf4b5bcaf5987caed71a7a110058712bf5e5f2bda8451ba94e394b2088b9a59c1b05cbb44f0d9532fa7b952238 +78048628932e1c1cdd1e70932bd7b76f704ba08d7e7d825d3de763bf1a062315f4af16eccefe0b6ebadccaf403d013f50833ce2c54e24eea8345e25f93b69bb048988d102240225ceacf5003e2abdcc90299f4bf2c101585d36ecdd7a155953c674789d070480d1ef47cc7858e97a6d87c41c6922a00ea12539f251826e141b4 b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c abc61393031a06da6cd1162367ae5e5801df17b541bc545c8cf384c93e87e9dea248a7625e9a23a0072d4d5074a622e2 +9b0800c443e693067591737fdbcf0966fdfa50872d41d0c189d87cbc34c2771ee5e1255fd604f09fcf167fda16437c245d299147299c69046895d22482db29aba37ff57f756716cd3d6223077f747c4caffbecc0a7c9dfaaafd9a9817470ded8777e6355838ac54d11b2f0fc3f43668ff949cc31de0c2d15af5ef17884e4d66a 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48 a6ac9a53ca93f1bd39407e5fe8ac6004495096d810b745ed19fe60430cbbeee87f95cbaa64502993e07469a627a4ea61 +fc3b8291c172dae635a6859f525beaf01cf683765d7c86f1a4d768df7cae055f639eccc08d7a0272394d949f82d5e12d69c08e2483e11a1d28a4c61f18193106e12e5de4a9d0b4bf341e2acd6b715dc83ae5ff63328f8346f35521ca378b311299947f63ec593a5e32e6bd11ec4edb0e75302a9f54d21226d23314729e061016 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f 98f71df3d718edccbbe378921b15a503ca8cc2c3ebb4c1eb33c7655ca6ce08629d4be37bb4cb67096e0f53981c148428 +5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 aba0f033afb9f944b53edb6a8a6449091fb19ee61fc0c4dbf96eb2b6e86ffcabd1f046466aaa7c22bd38cfb3976bd0bc +c35e2f092553c55772926bdbe87c9796827d17024dbb9233a545366e2e5987dd344deb72df987144b8c6c43bc41b654b94cc856e16b96d7a821c8ec039b503e3d86728c494a967d83011a0e090b5d54cd47f4e366c0912bc808fbb2ea96efac88fb3ebec9342738e225f7c7c2b011ce375b56621a20642b4d36e060db4524af1 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 878347df197af66c89801b2847b558c0653a9becb6470cd17926db884f5d6303b6695dfb5fcc331363a956c73eafa584 +3c054e333a94259c36af09ab5b4ff9beb3492f8d5b4282d16801daccb29f70fe61a0b37ffef5c04cd1b70e85b1f549a1c4dc672985e50f43ea037efa9964f096b5f62f7ffdf8d6bfb2cc859558f5a393cb949dbd48f269343b5263dcdb9c556eca074f2e98e6d94c2c29a677afaf806edf79b15a3fcd46e7067b7669f83188ee e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef ae6e9df98d6743611f9b9398b7305b9e3a97e5f9b467cd90389a55aa7b41ae7fff026c1f259d2dc304c5c34842c46ae5 +0989122410d522af64ceb07da2c865219046b4c3d9d99b01278c07ff63eaf1039cb787ae9e2dd46436cc0415f280c562bebb83a23e639e476a02ec8cff7ea06cd12c86dcc3adefbf1a9e9a9b6646c7599ec631b0da9a60debeb9b3e19324977f3b4f36892c8a38671c8e1cc8e50fcd50f9e51deaf98272f9266fc702e4e57c30 a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 aa7165c504283e3bd9322c2d2da88828e2429fdd25d1c68d7476e5ec34f09a6b318e5a4e62e73ee7099996a93e35b1da +dc66e39f9bbfd9865318531ffe9207f934fa615a5b285708a5e9c46b7775150e818d7f24d2a123df3672fff2094e3fd3df6fbe259e3989dd5edfcccbe7d45e26a775a5c4329a084f057c42c13f3248e3fd6f0c76678f890f513c32292dd306eaa84a59abe34b16cb5e38d0e885525d10336ca443e1682aa04a7af832b0eee4e7 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d a78528448a1b8257f0c8bccb86b9bd232f065f8b9e401ccd545e2138872b21a38ff62b61d5a10f53e46c9d719ee504cc +600974e7d8c5508e2c1aab0783ad0d7c4494ab2b4da265c2fe496421c4df238b0be25f25659157c8a225fb03953607f7df996acfd402f147e37aee2f1693e3bf1c35eab3ae360a2bd91d04622ea47f83d863d2dfecb618e8b8bdc39e17d15d672eee03bb4ce2cc5cf6b217e5faf3f336fdd87d972d3a8b8a593ba85955cc9d71 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d 93fce6a63c8d6a653b7b1e90cb70d6553e31a527a5abd5b0526afd14692a08478e174939b1a19548d1f73957de4242ef +dfa6cb9b39adda6c74cc8b2a8b53a12c499ab9dee01b4123642b4f11af336a91a5c9ce0520eb2395a6190ecbf6169c4cba81941de8e76c9c908eb843b98ce95e0da29c5d4388040264e05e07030a577cc5d176387154eabae2af52a83e85c61c7c61da930c9b19e45d7e34c8516dc3c238fddd6e450a77455d534c48a152010b 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab 9745489d390e6588fbb8672a53dd558018be67c0c1c0cfaa08490db41cea8e7997ace5b21a47203ff9f2e3a677fda220 +51d2547cbff92431174aa7fc7302139519d98071c755ff1c92e4694b58587ea560f72f32fc6dd4dee7d22bb7387381d0256e2862d0644cdf2c277c5d740fa089830eb52bf79d1e75b8596ecf0ea58a0b9df61e0c9754bfcd62efab6ea1bd216bf181c5593da79f10135a9bc6e164f1854bc8859734341aad237ba29a81a3fc8b 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a b795103c7e87a549a02d94f014f5f23cdea285293173c072aa17ea37d0da27a14e112fd67b9bb5b29f73c5b1fd0cff52 +558c2ac13026402bad4a0a83ebc9468e50f7ffab06d6f981e5db1d082098065bcff6f21a7a74558b1e8612914b8b5a0aa28ed5b574c36ac4ea5868432a62bb8ef0695d27c1e3ceaf75c7b251c65ddb268696f07c16d2767973d85beb443f211e6445e7fe5d46f0dce70d58a4cd9fe70688c035688ea8c6baec65a5fc7e2c93e8 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 80372a3638fdad76e9f4e29e9689526e8f6075f97cd1fce49b5cbd4c197c0be51d6cf96bb12f1ea5ea4e4473e6b07c12 +4d55c99ef6bd54621662c3d110c3cb627c03d6311393b264ab97b90a4b15214a5593ba2510a53d63fb34be251facb697c973e11b665cb7920f1684b0031b4dd370cb927ca7168b0bf8ad285e05e9e31e34bc24024739fdc10b78586f29eff94412034e3b606ed850ec2c1900e8e68151fc4aee5adebb066eb6da4eaa5681378e f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 a2e43f1f2d1e5a7ca5c958b3ec80fe434112566e5a9a8cd3519913d4a80a0620b33a6dfcf63eb7f5fae4e9484adf3f02 +f8248ad47d97c18c984f1f5c10950dc1404713c56b6ea397e01e6dd925e903b4fadfe2c9e877169e71ce3c7fe5ce70ee4255d9cdc26f6943bf48687874de64f6cf30a012512e787b88059bbf561162bdcc23a3742c835ac144cc14167b1bd6727e940540a9c99f3cbb41fb1dcb00d76dda04995847c657f4c19d303eb09eb48a b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 a1c5db1463c3ffd6691683e01a5de87c13f7e4eccb0e77cac22d9a4599066c8b6bf2c1396f0d04952ead3ce547f3b565 +3b6ee2425940b3d240d35b97b6dcd61ed3423d8e71a0ada35d47b322d17b35ea0472f35edd1d252f87b8b65ef4b716669fc9ac28b00d34a9d66ad118c9d94e7f46d0b4f6c2b2d339fd6bcd351241a387cc82609057048c12c4ec3d85c661975c45b300cb96930d89370a327c98b67defaa89497aa8ef994c77f1130f752f94a4 d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 91feeb08b5bc6c9bebfa8c9e77aaadc44e55fdb275b0a4e2f303c1963cdc91b5d91dc45558ef52fc00626b2758a446da +c5204b81ec0a4df5b7e9fda3dc245f98082ae7f4efe81998dcaa286bd4507ca840a53d21b01e904f55e38f78c3757d5a5a4a44b1d5d4e480be3afb5b394a5d2840af42b1b4083d40afbfe22d702f370d32dbfd392e128ea4724d66a3701da41ae2f03bb4d91bb946c7969404cb544f71eb7a49eb4c4ec55799bda1eb545143a7 b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c b7343d5269b032bdbe1a3daf93338e6a687b0eb9fa9f57d6b2482d7f6f0162005e618f4699953c02e5a5ccb0f86bce5e +72e81fe221fb402148d8b7ab03549f1180bcc03d41ca59d7653801f0ba853add1f6d29edd7f9abc621b2d548f8dbf8979bd16608d2d8fc3260b4ebc0dd42482481d548c7075711b5759649c41f439fad69954956c9326841ea6492956829f9e0dc789f73633b40f6ac77bcae6dfc7930cfe89e526d1684365c5b0be2437fdb01 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 a6414ccebfb46d75d44c20dba562405b467ae194594f82d76e6333618833c2db3b0cb82c17121b614fca244f9ee012c9 +21188c3edd5de088dacc1076b9e1bcecd79de1003c2414c3866173054dc82dde85169baa77993adb20c269f60a5226111828578bcc7c29e6e8d2dae81806152c8ba0c6ada1986a1983ebeec1473a73a04795b6319d48662d40881c1723a706f516fe75300f92408aa1dc6ae4288d2046f23c1aa2e54b7fb6448a0da922bd7f34 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 aed7e89c4c86678dca4f893b05c89ab478d6f9125a972667bf8567f84d5468d3df18d2f3c88fced59dd55f76271bd784 +e0b8596b375f3306bbc6e77a0b42f7469d7e83635990e74aa6d713594a3a24498feff5006790742d9c2e9b47d714bee932435db747c6e733e3d8de41f2f91311f2e9fd8e025651631ffd84f66732d3473fbd1627e63dc7194048ebec93c95c159b5039ab5e79e42c80b484a943f125de3da1e04e5bf9c16671ad55a1117d3306 b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced a56b8f404cbb47b437fe36931e09595c0339bd0cfcf03a6f3b215b99e4f757dc23747be0aa7d03aa26714ad9089c7ae2 +099a0131179fff4c6928e49886d2fdb3a9f239b7dd5fa828a52cbbe3fcfabecfbba3e192159b887b5d13aa1e14e6a07ccbb21f6ad8b7e88fee6bea9b86dea40ffb962f38554056fb7c5bb486418915f7e7e9b9033fe3baaf9a069db98bc02fa8af3d3d1859a11375d6f98aa2ce632606d0800dff7f55b40f971a8586ed6b39e9 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181 84e14abf3099d3b066751217b024dd58f1eee509256b7d3f957c57e0b40e022406e5a08d2086e20455e5a714c36b5687 +0fbc07ea947c946bea26afa10c51511039b94ddbc4e2e4184ca3559260da24a14522d1497ca5e77a5d1a8e86583aeea1f5d4ff9b04a6aa0de79cd88fdb85e01f171143535f2f7c23b050289d7e05cebccdd131888572534bae0061bdcc3015206b9270b0d5af9f1da2f9de91772d178a632c3261a1e7b3fb255608b3801962f9 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431 89ee62011201e86b5ab3fd54046e3f2d35f259ac528d0f79e2cd32d30ec45070d8b37084d002f0b51c554f1a495a5f8a +1e38d750d936d8522e9db1873fb4996bef97f8da3c6674a1223d29263f1234a90b751785316444e9ba698bc8ab6cd010638d182c9adad4e334b2bd7529f0ae8e9a52ad60f59804b2d780ed52bdd33b0bf5400147c28b4304e5e3434505ae7ce30d4b239e7e6f0ecf058badd5b388eddbad64d24d2430dd04b4ddee98f972988f 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd b98e757ac17bdcd841e8f4b1132c38ed3a556cb680e1374c88e5315cf836a094b2f5b75bbc1da17454221567b5dff669 +abcf0e0f046b2e0672d1cc6c0a114905627cbbdefdf9752f0c31660aa95f2d0ede72d17919a9e9b1add3213164e0c9b5ae3c76f1a2f79d3eeb444e6741521019d8bd5ca391b28c1063347f07afcfbb705be4b52261c19ebaf1d6f054a74d86fb5d091fa7f229450996b76f0ada5f977b09b58488eebfb5f5e9539a8fd89662ab 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de 83d172e3b529f10bab19671d791069921ce74a31365dff0713a30d415182041aa95b6b57c232f8d957a2bfb3da1df244 +dc3d4884c741a4a687593c79fb4e35c5c13c781dca16db561d7e393577f7b62ca41a6e259fc1fb8d0c4e1e062517a0fdf95558b7799f20c211796167953e6372c11829beec64869d67bf3ee1f1455dd87acfbdbcc597056e7fb347a17688ad32fda7ccc3572da7677d7255c261738f07763cd45973c728c6e9adbeecadc3d961 ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566 b4833c06cd7bdffb4860b61dccb7a3e3937980ef643886d62301a0891951c5e4c7db1cd2f0c1af682ae5ce829ac82622 +719bf1911ae5b5e08f1d97b92a5089c0ab9d6f1c175ac7199086aeeaa416a17e6d6f8486c711d386f284f096296689a54d330c8efb0f5fa1c5ba128d3234a3da856c2a94667ef7103616a64c913135f4e1dc50e38daa60610f732ad1bedfcc396f87169392520314a6b6b9af6793dbabad4599525228cc7c9c32c4d8e097ddf6 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee 92e46a14bac8aa58d75431b622fd42282bd67123bce782e6df8b8346415de002f7d41417316f41de8c2ffafa33dea6d0 +7cf19f4c851e97c5bca11a39f0074c3b7bd3274e7dd75d0447b7b84995dfc9f716bf08c25347f56fcc5e5149cb3f9cfb39d408ace5a5c47e75f7a827fa0bb9921bb5b23a6053dbe1fa2bba341ac874d9b1333fc4dc224854949f5c8d8a5fedd02fb26fdfcd3be351aec0fcbef18972956c6ec0effaf057eb4420b6d28e0c008c 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd b48a8d16d8431dac8469dff66358dca8ddfa366789942650da5c830b2b0fac1149c74d8137c5d3cf75675c70488f8c4c +b892ffabb809e98a99b0a79895445fc734fa1b6159f9cddb6d21e510708bdab6076633ac30aaef43db566c0d21f4381db46711fe3812c5ce0fb4a40e3d5d8ab24e4e82d3560c6dc7c37794ee17d4a144065ef99c8d1c88bc22ad8c4c27d85ad518fa5747ae35276fc104829d3f5c72fc2a9ea55a1c3a87007cd133263f79e405 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666 98a04dac67ffac103796cc52754882286173f5be4b7785db0ba0741414d0561222d749e7b8ed500a23c65b5b651f328a +8144e37014c95e13231cbd6fa64772771f93b44e37f7b02f592099cc146343edd4f4ec9fa1bc68d7f2e9ee78fc370443aa2803ff4ca52ee49a2f4daf2c8181ea7b8475b3a0f608fc3279d09e2d057fbe3f2ffbe5133796124781299c6da60cfe7ecea3abc30706ded2cdf18f9d788e59f2c31662df3abe01a9b12304fb8d5c8c bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67 82048354e7614778505b78bd8e7d38991faadea1403d4eb81aed4b1973df5884650baee9335c2b10b108eb3170553d25 +a3683d120807f0a030feed679785326698c3702f1983eaba1b70ddfa7f0b3188060b845e2b67ed57ee68087746710450f7427cb34655d719c0acbc09ac696adb4b22aba1b9322b7111076e67053a55f62b501a4bca0ad9d50a868f51aeeb4ef27823236f5267e8da83e143047422ce140d66e05e44dc84fb3a4506b2a5d7caa8 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9 b6a22ecefeca63c9657ae39fff33d6884b1b71b52ecc8689b8f89537cf62a6e8e6e39d381e2ad57b829a198c6aca5d86 +b1df8051b213fc5f636537e37e212eb20b2423e6467a9c7081336a870e6373fc835899d59e546c0ac668cc81ce4921e88f42e6da2a109a03b4f4e819a17c955b8d099ec6b282fb495258dca13ec779c459da909475519a3477223c06b99afbd77f9922e7cbef844b93f3ce5f50db816b2e0d8b1575d2e17a6b8db9111d6da578 f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce 8219f528be2807b3992a14cfb3e5432819c69556a70f89106cfc84fd96bd52c09ffdf3e23a922ac9823e02abec53ee13 +0b918ede985b5c491797d0a81446b2933be312f419b212e3aae9ba5914c00af431747a9d287a7c7761e9bcbc8a12aaf9d4a76d13dad59fc742f8f218ef66eb67035220a07acc1a357c5b562ecb6b895cf725c4230412fefac72097f2c2b829ed58742d7c327cad0f1058df1bddd4ae9c6d2aba25480424308684cecd6517cdd8 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f b372c60732b2d3a7866cc49ad48088ccf2b96298cf7e3f23050b13cd9283bb9deef3f5fbe2b65adac9bf78643ec71cae +0fab26fde1a4467ca930dbe513ccc3452b70313cccde2994eead2fde85c8da1db84d7d06a024c9e88629d5344224a4eae01b21a2665d5f7f36d5524bf5367d7f8b6a71ea05d413d4afde33777f0a3be49c9e6aa29ea447746a9e77ce27232a550b31dd4e7c9bc8913485f2dc83a56298051c92461fd46b14cc895c300a4fb874 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b b85e26da61d1b0684699ddcd95482bf8a893a11f80dc48802f99b76d1fc8420cc54faa11892b37bca315ee3936167b7e +7843f157ef8566722a7d69da67de7599ee65cb3975508f70c612b3289190e364141781e0b832f2d9627122742f4b5871ceeafcd09ba5ec90cae6bcc01ae32b50f13f63918dfb5177df9797c6273b92d103c3f7a3fc2050d2b196cc872c57b77f9bdb1782d4195445fcc6236dd8bd14c8bcbc8223a6739f6a17c9a861e8c821a6 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388 8a879100d90c3c1c5624464097d7063a3e4033e11fd70adbdf8a643d80786b185bba9745ce164b093a2965d71c86565a +6c8572b6a3a4a9e8e03dbeed99334d41661b8a8417074f335ab1845f6cc852adb8c01d9820fcf8e10699cc827a8fbdca2cbd46cc66e4e6b7ba41ec3efa733587e4a30ec552cd8ddab8163e148e50f4d090782897f3ddac84a41e1fcfe8c56b6152c0097b0d634b41011471ffd004f43eb4aafc038197ec6bae2b4470e869bded 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499 a1a2638af5b68d28cb0f4fdfd93930c05e651fcf38081b4627b312b4c6c10ef2b028091cb9e12cfd415810dc5c5adaa2 +7e3c8fe162d48cc8c5b11b5e5ebc05ebc45c439bdbc0b0902145921b8383037cb0812222031598cd1a56fa71694fbd304cc62938233465ec39c6e49f57dfe823983b6923c4e865633949183e6b90e9e06d8275f3907d97967d47b6239fe2847b7d49cf16ba69d2862083cf1bccf7afe34fdc90e21998964107b64abe6b89d126 f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6 b3eeb533b6ce2263236a51f9aaad52d16554efc9bfef907a80e867cf147c268dcd3d23d47fa3eb6863a3e693d46be0d7 +d5aa8ac9218ca661cd177756af6fbb5a40a3fecfd4eea6d5872fbb9a2884784aa9b5f0c023a6e0da5cf6364754ee6465b4ee2d0ddc745b02994c98427a213c849537da5a4477b3abfe02648be67f26e80b56a33150490d062aaac137aa47f11cfeddba855bab9e4e028532a563326d927f9e6e3292b1fb248ee90b6f429798db 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead 96cc8d147bfca13bb92093087a5fbdaf7e76505b2f894e763d6c3e1c304b7ff301d2cb793491ffd6d177ba397c7b10ff +790b06054afc9c3fc4dfe72df19dd5d68d108cfcfca6212804f6d534fd2fbe489bd8f64bf205ce04bcb50124a12ce5238fc3fe7dd76e6fa640206af52549f133d593a1bfd423ab737f3326fa79433cde293236f90d4238f0dd38ed69492ddbd9c3eae583b6325a95dec3166fe52b21658293d8c137830ef45297d67813b7a508 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd a703e7e502601470e5b5a0646199e31006db22c89b58b0c58fd9437ea4aa841e78a604cdec41864fb58a99fdacf9e50a +6d549aa87afdb8bfa60d22a68e2783b27e8db46041e4df04be0c261c4734b608a96f198d1cdb8d082ae48579ec9defcf21fbc72803764a58c31e5323d5452b9fb57c8991d31749140da7ef067b18bf0d7dfbae6eefd0d8064f334bf7e9ec1e028daed4e86e17635ec2e409a3ed1238048a45882c5c57501b314e636b9bc81cbe 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117 8452e9077f75f6e74a7435227469f8a255c7f9c85ac62ec9d5e6dbb99de531d438d605355b088e7233ddecc6d8433fc4 +1906e48b7f889ee3ff7ab0807a7aa88f53f4018808870bfed6372a77330c737647961324c2b4d46f6ee8b01190474951a701b048ae86579ff8e3fc889fecf926b17f98958ac7534e6e781ca2db2baa380dec766cfb2a3eca2a9d5818967d64dfab84f768d24ec122eebacaab0a4dc3a75f37331bb1c43dd8966cc09ec4945bbd 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61 8e6e7adde671c17d5491a02e4a47cba603ee056d78ca7f1fb622040b856ca636a455f07b9fbaf76d0906a43b4cf93cff +7b59fef13daf01afec35dea3276541be681c4916767f34d4e874464d20979863ee77ad0fd1635bcdf93e9f62ed69ae52ec90aab5bbf87f8951213747ccec9f38c775c1df1e9d7f735c2ce39b42edb3b0c5086247556cfea539995c5d9689765288ec600848ecf085c01ca738bbef11f5d12d4457db988b4add90be00781024ad 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2 916b56cbd30ca3a7111642f0972be98d767d5ff184041c435f4d8e2d746973f41fdcd9ec8d3e3ca2ddefca89dacb2e09 +041a6767a935dc3d8985eb4e608b0cbfebe7f93789d4200bcfe595277ac2b0f402889b580b72def5da778a680fd380c955421f626d52dd9a83ea180187b850e1b72a4ec6dd63235e598fd15a9b19f8ce9aec1d23f0bd6ea4d92360d50f951152bc9a01354732ba0cf90aaed33c307c1de8fa3d14f9489151b8377b57c7215f0b 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7 80613a449759f6df249e2d7cf7ee2f72f1748e406e16f13be1b577dce464bebdc6a75c742d96269675a3d524111a1c1e +7905a9036e022c78b2c9efd40b77b0a194fbc1d45462779b0b76ad30dc52c564e48a493d8249a061e62f26f453ba566538a4d43c64fb9fdbd1f36409316433c6f074e1b47b544a847de25fc67d81ac801ed9f7371a43da39001c90766f943e629d74d0436ba1240c3d7fab990d586a6d6ef1771786722df56448815f2feda48f 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870 a8184516354d004f3f70d571496a9734c5ca1011ef0d3607df879a1f7bda82ba6132fa881e34f69fb6b53753bfb60544 +cf25e4642d4f39d15afb7aec79469d82fc9aedb8f89964e79b749a852d931d37436502804e39555f5a3c75dd958fd5291ada647c1a5e38fe7b1048f16f2b711fdd5d39acc0812ca65bd50d7f8119f2fd195ab16633503a78ee9102c1f9c4c22568e0b54bd4fa3f5ff7b49160bf23e7e2231b1ebebbdaf0e4a7d4484158a87e07 e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf 92627d1ee54ac9b366d429732d05ece4cad9bc62e62ec7cd45e8bce6dfe1ac5a0e4d00c5bfa630d582b0e239f6092d90 +7562c445b35883cc937be6349b4cefc3556a80255d70f09e28c3f393daac19442a7eecedcdfbe8f7628e30cd8939537ec56d5c9645d43340eb4e78fc5dd4322de8a07966b262770d7ff13a071ff3dce560718e60ed3086b7e0003a6abafe91af90af86733ce8689440bf73d2aa0acfe9776036e877599acbabfcb03bb3b50faa 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c 91b850fdf3beee5f89e7d4382166e8648476a88c10f6ac0d1b46b171f5eff0721f07ff8971e1c675fc189384fdd1cf62 +051c2db8e71e44653ea1cb0afc9e0abdf12658e9e761bfb767c20c7ab4adfcb18ed9b5c372a3ac11d8a43c55f7f99b33355437891686d42362abd71db8b6d84dd694d6982f0612178a937aa934b9ac3c0794c39027bdd767841c4370666c80dbc0f8132ca27474f553d266deefd7c9dbad6d734f9006bb557567701bb7e6a7c9 f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9 8f9dd85364174bad409f33fac9e7d53d7e451f5589fa3dfa7d208a856010adffa69b9e4532b5e9dc50435328229cd742 +4dcb7b62ba31b866fce7c1feedf0be1f67bf611dbc2e2e86f004422f67b3bc1839c6958eb1dc3ead137c3d7f88aa97244577a775c8021b1642a8647bba82871e3c15d0749ed343ea6cad38f123835d8ef66b0719273105e924e8685b65fd5dc430efbc35b05a6097f17ebc5943cdcd9abcba752b7f8f37027409bd6e11cd158f f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5 a53bd40c9ebad35eb051fb49d1b3aaa9f66df8ea0fb3450bd0d7a6b5f0672e1cc9a080f55b6a44a44a067214062fa8f0 +efe55737771070d5ac79236b04e3fbaf4f2e9bed187d1930680fcf1aba769674bf426310f21245006f528779347d28b8aeacd2b1d5e3456dcbf188b2be8c07f19219e4067c1e7c9714784285d8bac79a76b56f2e2676ea93994f11eb573af1d03fc8ed1118eafc7f07a82f3263c33eb85e497e18f435d4076a774f42d276c323 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628 a234d128bc58d3e45d250935a9bd5e95d1819ca97f9aa89362010f353873cc88671ef73262017f3d4b72913f827e87e4 +ea95859cc13cccb37198d919803be89c2ee10befdcaf5d5afa09dcc529d333ae1e4ffd3bd8ba8642203badd7a80a3f77eeee9402eed365d53f05c1a995c536f8236ba6b6ff8897393506660cc8ea82b2163aa6a1855251c87d935e23857fe35b889427b449de7274d7754bdeace960b4303c5dd5f745a5cfd580293d6548c832 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49 957a104d87f4a001a014c80a3c0e75ff3d3a8cae1352e1fd5bef7d4771f3bed77e553200059c4f2213708387da56b454 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P384 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P384 new file mode 100644 index 000000000000..8f1b6197053b --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P384 @@ -0,0 +1,60 @@ +39f0b25d4c15b09a0692b22fbacbb5f8aee184cb75887e2ebe0cd3be5d3815d29f9b587e10b3168c939054a89df11068e5c3fac21af742bf4c3e9512f5569674e7ad8b39042bcd73e4b7ce3e64fbea1c434ed01ad4ad8b5b569f6a0b9a1144f94097925672e59ba97bc4d33be2fa21b46c3dadbfb3a1f89afa199d4b44189938 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727 973b5ebbcc49dc4426649e0f9020f3323f149171ff0605c40a76b847c3f0ff8d7a098f4e0b3804947c00c6b74dc57c12 +5a3c80e608ed3ac75a6e45f6e94d374271a6d42b67a481860d5d309cc8b37c79cb61f1716dc8aa84cb309ef9d68eb7fc6cf4b42333f316a5c30e74198c8b340926e340c5de47674a707293c4aa2a1a2274a602f01c26b156e895499c60b38ef53fc2032e7485c168d73700d6fa14232596a0e4997854a0b05d02e351b9d3de96 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246 8eccbd7f2e1390e8aca21a5f9fa3aed5f694b7d46fe46a421afb8e9d57524903678610ff2346078f41ea13b4314ca89f +e7d974c5dbd3bfb8a2fb92fdd782f997d04be79e9713944ce13c5eb6f75dfdec811b7ee4b3859114b07f263846ae13f795eec8f3cb5b7565baff68e0fdd5e09ba8b176d5a71cb03fbc5546e6937fba560acb4db24bd42de1851432b96e8ca4078313cb849bce29c9d805258601d67cd0259e255f3048682e8fdbdda3398c3e31 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83 a18aacfa6dbf292b227f980a5cff81abed5d87b0924c923c7ab128094a3513a0abf65b45b52e5bf37c8e59aedf82c6a1 +a670fda4d1d56c70de1d8680328043b2b7029633caf0ee59ffe1421c914bb937133d5a0f9214846b2e0b350455a74c4ab434c56de65a17139bb8212bf1c76071a37536fa29348f871dbb26baa92eb93d97e923a6d2ffd9be25cbc33075e494e6db657bd8dc053fe4e17148d8cf6e2058164f2b5766750eb01bbe7b361cdb848c dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659 a43753c3e467d5f99a9d20b1f451d71dd05c1e259f402fd15f35dd993e974920ee352230e9da5ee9b9f38ca03e7d3144 +7843f918fe2588bcfe756e1f05b491d913523255aa006818be20b676c957f4edb8df863c6f5f8c15b3b80c7a2aa277b70d53f210bdfb856337980c406ea140e439dd321471407f374f69877b2d82367eed51e3c82c13948616dcb301d0c31f8f0352f2846abd9e72071f446a2f1bd3339a09ae41b84e150fd18f4ba5d3c6bfa0 df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718 b6c37bb45608fdb55d1ff689ac071db41851a82dc82c2bc7fc604c1ae20db6225359b6a944330ac45bbc3fc46b774598 +caa83d5ab07febbd2e0fe2d63738b9b7b8752594bea7aaf50345b3d2f316653a8c9222f2b7877b64679e9573e81461a426029e45b8873a575094a1d572e0d32a9f0a9c6bcb9a2868543b7d8bbe4a69a09e7321f05f8366cced1b72df526f895b60aed2c39c249653c7839538770d4e5f47d3926ec0d168ab6a1af15bf1dca1f7 ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f a0707f3351cfedce4860cc510b233b477166591d0b15f4ef9157b9da3d06e7b8c6b223883b3b2cb2eb2acbd57b456d5d +594603458d6534974aeeafba919c4d0f4cb6843a3af41204bbb88aeb2fca2772d305163dba863da050aabedbaf89db521955d1715de95bbcef979ecdc0c976181ece00355385f8a8f8cce127c9eac15ce3e958a3ed686184674ec9a50eb63271606ee7fdcb1323da3c3db8e89cad1fb42139a32d08abcfbf0d4ccfca18c89a86 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829 8c75cc2d50c2ed7a52d7780b46ce2445e9c90f6ccef013dd2ae91846bbdefb73a9d0df639f6c1a9cfa091ece6671b73a +733252d2bd35547838be22656cc7aa67eff0af0b13b428f77267a513c6824c3dbae533068b6817e82665f009560affcfe4b2ddb5b667a644fc1a42d24f24e0947e0dc50fb62c919bc1fe4e7ded5e28f2e6d80fcf66a081fb2763526f8def5a81a4ddd38be0b59ee839da1643eeeaee7b1927cec12cf3da67c02bc5465151e346 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1 9877fb609e2a76fabac078bac8b9693a8d9ff8ddd468f13fb809410304174a0110e91e87eebc36d5667b7523ac9bde00 +5a182bd174feb038dfae3346267156bf663167f713dea1ce936b0edb815cd9b8c8e4d411c786ba2494a81442617255db7158b142e720d86c9b56680fb9efd4298cdd69079a28153494c42a24251c7ad42ecf7e97eabc1b3997529b2a297cbad2474269b87a0b1e385f2d7f8b6eb8d1cd75eaf7e91d1acbecd45d7b2bfbbe3216 e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d a9f87b7f3ecfbc767b6b786372e418685e7183d66578ad0e09bd1939383528c8a008a0195de72b484d3a335b38a43e9c +aaa99fb1c71340d785a18f6f668e898c25cf7a0ac31d13c5b388b7233408493a5a109af6d07065376b96f4903df7aba2b2af671a18772bb0472490d1240cde28967680727dd4acd47e0308920a75da857a6eeedee5b6586d45dff3d8a680599665aa895c89dd7770b824b7dee477ac5e7602d409d3cc553090c970b50811dbab 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead 8c39d99ee92b38b099bee564f814d1ce89b04519d37c258eab25828ac6bdcfea14fae27c7b39d76f77ad3a43f78f559c +1fadfa8254d3a0b82d137cfdd82043d5dc1fef195d5297b09cc5cfb061f59c933451c0dc2a11b4037f34f88dacb803251f8880c4b72585c3c196e6fb23484ca43a191f8e41b9b9a37e2e6fcaab6738c3c62d1c98e1c620bb788b7b51a04f998a510efdba0d3418622fe8ce203b3fcd553b9b4206365a39031797ad11e49745ec 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0 aec8ca7d4b5a471e42259b05eda4a21931d5fa7400aead0aa83ee402302c59f51c3d0199a642f3f4380f0ea76fe125a3 +9ecb6f5ed3ba666a8536a81ef65012c2cb8b433508798d84708abb06dfb75503886f78384fb8c7a4d2d49ef539d9b8a0b60938c7f07471dda91f258b0d99691b38a8403a2bb3f956bdfd09baba16d9b6877097a9b6213481b47a06e139d23ec7abad5668d21f912fdb70d31bb9adf9b3ce80e308252fa81a51674f88d02db72b f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1 b50ac37b63912915b3a58f8f5b5a8f4e91cf4f2b89d75d1ae9cf127c16c47eac00204251aebdf592f066eab833cc9d1d +e55bfca78d98e68d1b63688db12485578f36c489766f4d0bfaa0088433ff12133aaca455805095f2e655940860958b3ead111d9070778ee3bbf3e47e43d9eba8b8d9b1fdf72f793fcde2bcaa334f3e35fa2cca531ea7cf27fe9ccba741e38ac26129b2d612bf54a34e0ae6c166c0fef07fcd2b9ac253d7e041a500f7be7b8369 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb a9dfa6b1d65b8a9fc011fe1e3e230dcc07a4721fdae85cb957e5e57a393aaa0b621a2d0ac9100f8a5dbfb4f73820bf02 +02c6b3c83bd34b288d96409162aa4ff114e9d134bf948046eb5ebcc0c7fe9dfceadda83ed69da2fac00c8840f6c702a3fc5e6959d70f7e8af923e99e4937232ae3b841ffefd2e62fab3671a7c94a0281b8ea5bc176add57c5c9b6893fe7f5d48ce7256b96510810c4e046168a3c5be9843b84d5268a50349b3444341aa5490dd 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6 98c7938fab3c852533acd108f17d4e3e53970e1e25a9b4295e193badbe0b40735ec9c36971672d198fb6e48a76c0c42e +94f8bfbb9dd6c9b6193e84c2023a27dea00fd48356909faec2161972439686c146184f80686bc09e1a698af7df9dea3d24d9e9fd6d7348a146339c839282cf8984345dc6a51096d74ad238c35233012ad729f262481ec7cd6488f13a6ebac3f3d23438c7ccb5a66e2bf820e92b71c730bb12fd64ea1770d1f892e5b1e14a9e5c cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd af9aca9048a5061587a26ad6b0392ff2ce9339dc672cea43a09df770b3077808efdce1df4082062e0d557563b96b3912 +663b12ebf44b7ed3872b385477381f4b11adeb0aec9e0e2478776313d536376dc8fd5f3c715bb6ddf32c01ee1d6f8b731785732c0d8441df636d8145577e7b3138e43c32a61bc1242e0e73d62d624cdc924856076bdbbf1ec04ad4420732ef0c53d42479a08235fcfc4db4d869c4eb2828c73928cdc3e3758362d1b770809997 c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b a87d15bcd2a5bdd48dd92977abc690b09050ec92445ecc88ca6841c6fb475a812578f7188e49eedf558d9a7b3023fb8e +784d7f4686c01bea32cb6cab8c089fb25c341080d9832e04feac6ea63a341079cbd562a75365c63cf7e63e7e1dddc9e99db75ccee59c5295340c2bba36f457690a8f05c62ab001e3d6b333780117d1456a9c8b27d6c2504db9c1428dad8ba797a4419914fcc636f0f14ede3fba49b023b12a77a2176b0b8ff55a895dcaf8dbce 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9 8560d121e340ee3d9b83158f32ac7ce2ed73755344a50407ba8dcc145682c6a500a82699c9fae38a7e24dc6d58d8c82d +45e47fccc5bd6801f237cdbeac8f66ebc75f8b71a6da556d2e002352bd85bf269b6bc7c928d7bb1b0422601e4dd80b29d5906f8fcac212fe0eaaf52eda552303259cbcbe532e60abd3d38d786a45e39a2875bce675800a3eaeb9e42983d9fd9031180abd9adccc9ba30c6c198b4202c4dd70f241e969a3c412724b9b595bc28a d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f 8f19fd6b271cd7d483ddbbfd213f984b80aabe93da0a3ab34ad351a95ad0c24bf2c2e08c55116284fc8e5d21d24d3b01 +c33ff63b4e6891e00b2349b3f2907c417ca355560544a91e24a7a0ee260d6850aeded29fc0176b6039ca6187e8333391047cceaf14b1077df8f147dad84d36b2dac5666dc2f69dc9b58b88cc73956efdb3b47f91831d5875051c76b0c4e9fc087012a1f03eeee85d6745b46aa50bd9cb0110c2c94508765cec162ee1aa841d73 d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3 8990180bca2d6ad2e5ad5ee73dfdd6dc3b5eb68993a4e52a4bbd319ebbac51178b83b698f2d6d9417450107cd65cfbee +f562f2b9d84b0e96a52532c3b43c39c8018c738bd8dc3797a7de7353971b2729d522d6961b1f2e4df3f6a4bd3653e6d72b74fc0dba92ab939c4b542e994e5db6dd8ed4f56f651e699052e791237ae1f552f990ad156226ae8f7bf17fcbfa564f749604f97e9df0879d50985747d981422a23040fe52f5ec74caf1d4aaad8a710 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93 ad78edf6e90ecaecbaa87050f5d59b59d75171f89b7edbc4bf42e9546b06ab36b1e58e74f4b12a5260d48272621cc6f6 +ace953ae851f571d71779aa120915f27450b236da23e9106f8d0756abdd25861937941228d225d5fb1aa1b1ebf759b1e326aeb3b6cd0cd87edd2ab9f6a7ad67b63d2c501d6a550edb2e7c9d216cc8af78dd33546af64d00abed4d0d2cfc5c9a7b5a055dbe8f7547902d185cf46937314832bc5c602419a82ab83dbd9d3bd5aff e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1 92f1d65ae2501205dac2c11c92b5a2eb92fe6afb07027444c9e6a3e78b50eb513d03165b32bd8f4c9c8f242965757c13 +9635ab832240be95301bedb94c5aec169eedc198cbbdfedcf41e9b586143d829b4597a6b2a81902828332825fd84a785f187a3894e21bd99d22c4f94dcf34453fc052f15ec64d1447c932cb38fcdd30b7be851963409c11881438cbaad7e96f9efbde317f2235d66af804477a5dfe9f0c51448383830050ecf228889f83631e1 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960 b28893be830ffa5ffd759045757df2feebc9d19c7bfa84fd690031f8ab0894d417bfa54dc95afa1c47e981fa6a4f28e0 +d98b9a7d4fe9d0fd95de5056af164a8b7882cd34ab5bde83a2abb32dc361eb56a479a3a6119db3b91dcad26a42d2206749567f0d97c34a981a91fc734921821a429f6a53401743a5c406ba9d560f956203abc9d1f32f1a13e7d7b290f75c95fdbf857ea597021461c06a3aacfa554ede3d69e4ff03bbbee5b7463ec77de2b3b2 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57 ae8b399608a1ce8a35a5c9a52a04fa3d15b6835ed571ac71b1506e2c9273a941ef8744ad5c25146a508558b1a098d326 +1b4c754ac1c28dc415a71eac816bde68de7e8db66409af835838c5bb2c605111108a3bf13606ed5d8ade5ed72e50503e0de664416393d178ea4eec834d8d6f15039847b410080fd5529b426e5aadd8451c20ebd92d787921f33e147bcbeb327b104d4aab1157fc1df33e4d768404b5ccb7110055c2508c600f429fd0c21b5784 a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1 93c1751703f4e61923d8cc17ebb79798539cc8268a95a9205fa4880451c6a9c81f42e01c6f8682110b2d7ec508fe9a85 +3cd8c053741dd9f974c6c5dbf8a1e5728e9b5eafb1cbcfc3452f5fbbda32a8c7564dee157e8d902c52514361da6d972934a56b3276e2a9379e328e24282e0db697c5bc29090fc489ec46b7b188325dd4e96494c250de0f4a89fe2ccf919eaefcfb50c288113e6df92714feb7f46e0822478c796d0f4ff3447a32997e892693ce 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3 b6abd8b37256fb9c59aa5df2573c76c90f106b0dae5d09e396a9160a0ae398337987f523872789aad6a4006320180b4e +ed955dda6d9650124804d3deb6aeef900e520faf98b1ef6f14efcada7ca2433f09329b70897305e59c89024d76e466b28fe02cb2a9b12e2478c66470259d7c282137a19e5a04ffadea55245c0f34a681593fedc42931d8b3321b3d82e9cc102cd00540ad311ec7bd8c9d06db21bea4ca3dc74d98931ae0d40494aefc2345132c 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907 b85f7c85d4e15c91a08e0dd14e12bda76fd8af14b0a6828eb201f65627ea2621bcbbad8d5fd3a75e006f8c41663472ef +ce395b001da2a58e49691605d44af4206306f62f561bf2394060d2a5591a350277166bed043819035f1e60b5b3fb5ae113ddd0473f8ef6b2b050c472c2a264e1d8b3ca82a4f158c40f2d78d9ce5e5ea6de243f2e1f13f47f6c6f403b270912c81c636be35b396ca58468b3fb60aa83911d61441a0528d973bc31f965d4059080 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245 b1777ab8d475e3192361d8744c3fdc8fe180d3f1fbcf404d75327cf32f5cfbcf922a0ceba32707bbc01270c774b19373 +ffefe316455ae4ffdb890bb804bf7d31424ea060ecacff419d0f7134ff76ad434063c0ec0f8bb7059584d3a03f3625bb9e9f66ace1a47ac4b8f3e76fc7c420c55edb1427d1fa15b387ad73d02b0595c4e74321be8822752230a0dcfb85d60bfa186da7623a8ec3eb1633f0a294b23ae87216b14ccee9ef56418dcfab9427371e 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7 a3c653981f2a55b7d6f3d2a7acdbc256594cbdb093b08c6a8434cfaeb8c68d9d518b8889443aaace67eef06bb4356f35 +304bccb718b3a9e12669913490cc5bcc1979287b56c628fad706c354241e88d10e81445a2853e3fc32ece094ba1abc3fdcab61da27f9a0fca739371049fed462ee6b08fa31cde12720f8144a6f00ce9b1a7a6eadd231f126717074b4efb5c72ce673ca5859000a436f67a338d698759f12c461247c45a361fb6cb661fdbe6714 d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5 b591a8a4c32e4c499fe9dffd272129bc2d4bf1bfb184def5f6d00b5e8ad69e720e9226a3fda6bb7d99f0b200a5c62197 +64f9f05c2805acf59c047b5f5d2e20c39277b6d6380f70f87b72327a76170b872bfe4b25c451602acfb6a631bb885e2655aee8abe44f69c90fb21ffde03cef2a452c468c6369867dfd8aa26ac24e16aa53b292375a8d8fbf988e302bf00088e4c061aa12c421d8fe3cbd7273b0e8993701df1c59431f436a08b8e15bd123d133 b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224 8c3592b1f2b196eeec3c40ae0f5399fa21f63a78b96fe93832a691b2325b15fb462005f37e449fe6e38daa83f8b7fa5b +6b45d88037392e1371d9fd1cd174e9c1838d11c3d6133dc17e65fa0c485dcca9f52d41b60161246039e42ec784d49400bffdb51459f5de654091301a09378f93464d52118b48d44b30d781eb1dbed09da11fb4c818dbd442d161aba4b9edc79f05e4b7e401651395b53bd8b5bd3f2aaa6a00877fa9b45cadb8e648550b4c6cbe 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 9922b01b40de56e446aaae470db23fd7d9fc5f677f887f5ef78d36ce9e09ab2fbfd7e20202f43b69784dd72c9d48e8fd +d768f41e6e8ec2125d6cf5786d1ba96668ac6566c5cdbbe407f7f2051f3ad6b1acdbfe13edf0d0a86fa110f405406b69085219b5a234ebdb93153241f785d45811b3540d1c37424cc7194424787a51b79679266484c787fb1ded6d1a26b9567d5ea68f04be416caf3be9bd2cafa208fe2a9e234d3ae557c65d3fe6da4cb48da4 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 a3ec53c23258bce1fc8e5d3c855e2cb1ad7909a38217ce9a50fbbd89fb2d75fb6595b14505bddccc37ad21c534fca397 +6af6652e92a17b7898e40b6776fabaf0d74cf88d8f0ebfa6088309cbe09fac472eeac2aa8ea96b8c12e993d14c93f8ef4e8b547afe7ae5e4f3973170b35deb3239898918c70c1056332c3f894cd643d2d9b93c2561aac069577bbab45803250a31cd62226cab94d8cba7261dce9fe88c210c212b54329d76a273522c8ba91ddf b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 b7f0c7375b98186c6244174ba810104f99a1cf04d2bfd7d2657d8ad8ae2181e7843a155b6c34a11812a54a7dfecd0dbe +b96d74b2265dd895d94e25092fb9262dc4f2f7a328a3c0c3da134b2d0a4e2058ca994e3445c5ff4f812738e1b0c0f7a126486942a12e674a21f22d0886d68df2375f41685d694d487a718024933a7c4306f33f1a4267d469c530b0fed4e7dea520a19dd68bf0203cc87cad652260ed43b7b23f6ed140d3085875190191a0381a de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 891feecde9ef57b987b206d007254e6ad7f30c7989f04d022696658361c561aa82c0362ed5ab26fd83f6f5756a390a5c +7cec7480a037ff40c232c1d2d6e8cd4c080bbeecdaf3886fccc9f129bb6d202c316eca76c8ad4e76079afe622f833a16f4907e817260c1fa68b10c7a151a37eb8c036b057ed4652c353db4b4a34b37c9a2b300fb5f5fcfb8aa8adae13db359160f70a9241546140e550af0073468683377e6771b6508327408c245d78911c2cc 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc a38674335bbae29fe518ce01e888e0985413ee84459c9f5b7c496cc1c8b1c783051015f7935b6147961033175a762503 +00ce978603229710345c9ad7c1c2dba3596b196528eea25bd822d43ca8f76a024e29217703dd0652c8a615284fc3edcc1c5ad1c8d5a8521c8e104c016a24e50c2e25066dcb56596f913b872767e3627aa3e55ec812e9fdac7c2f1beade83aef093e24c9c953982adf431a776880ae4583be158e11cdab1cbca3ad3a66900213d 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 a6ae4017f19d916c435a34b3deaef13967bb7c5086f64f1bb1c6aef77d512d7628ebfcc69caf5d4a9c5bc23b319c6088 +54a255c18692c6162a46add176a0ae8361dcb8948f092d8d7bac83e160431794d3b9812849bf1994bcdcfba56e8540c8a9ee5b93414548f2a653191b6bb28bda8dc70d45cc1b92a489f58a2d54f85766cb3c90de7dd88e690d8ebc9a79987eee1989df35af5e35522f83d85c48dda89863171c8b0bf4853ae28c2ac45c764416 ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 8345a5808d8a9c750bd49687e5f02828b6a16c93beca5f9e0d32a15d75e26be7040577885ee6588cfcd3af93b9b98f69 +692a78f90d4f9d5aee5da536314a78d68c1feabbfe5d1ccea7f6059a66c4b310f8051c411c409ccf6e19a0cbd8b8e100c48317fe8c6d4f8a638b9551ce7ee178020f04f7da3001a0e6855225fb3c9b375e4ed964588a1a41a095f3f476c42d52ffd23ce1702c93b56d4425d3befcf75d0951b6fd5c05b05455bdaf205fe70ca2 adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 844eea5fce22a46d211c400728a4277eb5356851ff7f1ff79783f5605060a808ccba84d868ea88854d40423a06f051d9 +3b309bb912ab2a51681451ed18ad79e95d968abc35423a67036a02af92f575a0c89f1b668afe22c7037ad1199e757a8f06b281c33e9a40bab69c9874e0bb680b905d909b9dc24a9fe89bb3d7f7d47082b25093c59754f8c19d1f81f30334a8cdd50a3cb72f96d4b3c305e60a439a7e93aeb640dd3c8de37d63c60fb469c2d3ed 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d a3339b6f367c844d09da01231a674f40c060a66c4c71e1148b2d5eb0cacc20ab1ef09ec950795a83af29ac4ffb42afc2 +f072b72b8783289463da118613c43824d11441dba364c289de03ff5fab3a6f60e85957d8ff211f1cb62fa90216fb727106f692e5ae0844b11b710e5a12c69df3ed895b94e8769ecd15ff433762d6e8e94d8e6a72645b213b0231344e2c968056766c5dd6b5a5df41971858b85e99afbf859400f839b42cd129068efabeea4a26 e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 a5ffd66102e737e58b5e08c032fbbc30da6994604e8b72ba856e3eb46750c496ea7c739d3752d0c73cded8d390a08547 +cf4945350be8133b575c4ad6c9585e0b83ff1ed17989b6cd6c71b41b5264e828b4e115995b1ae77528e7e9002ac1b5669064442645929f9d7dd70927cb93f95edeb73e8624f4bc897ec4c2c7581cb626916f29b2d6e6c2fba8c59a71e30754b459d81b912a12798182bcff4019c7bdfe929cc769bcc2414befe7d2906add4271 d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca b003f48e416160e68111a507558d5db68e42c77a9d765522f18caa0ec1b59f66a72a454c5fd6ebbcffc6394f20cdf8ff +d9b5cf0b50416573ff3c63133275a18394dd4326be2041e8d97e6e4e3855a4a177e9d26dfd223fe8aa74564edb49bd72de19916fb6f001f44530d5c18e2c332bce1b7415df5927ece5f3824f34d174b963136b53aef1fb78fb0c06a201a40b2db38e4d8216fc1e392a798c8ab4b3a314496b7f1087804ebfa89bf96e9cdb80c0 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d 84c0372219ffdeb84f1745d3cf8b9c74996898dafa0253d41e8619483d8ad99a91c7d6b8a1b9c3f197150022b648c992 +9e4042d8438a405475b7dab1cd783eb6ce1d1bffa46ac9dfda622b23ac31057b922eced8e2ed7b3241efeafd7c9ab372bf16230f7134647f2956fb793989d3c885a5ae064e85ed971b64f5f561e7ddb79d49aa6ebe727c671c67879b794554c04de0e05d68264855745ef3c9567bd646d5c5f8728b797c181b6b6a876e167663 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 a82717399426dab90474333a2fae3082c504cba884e01d1a2a9d6d5ac6827b512cbfe9ac065bc4eac257e87987ee2102 +0b14a7484a40b68a3ce1273b8a48b8fdb65ba900d98541c4bbd07b97e31bcc4c85545a03e9deab3c563f47a036ff60d0361684ba241b5aa68bb46f440da22181ee328a011de98eff34ba235ec10612b07bdfa6b3dc4ccc5e82d3a8d057e1862fef3def5a1804696f84699fda2ec4175a54a4d08bcb4f0406fdac4eddadf5e29b ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 8d7af4641c694473e9934cea2864f1238edb551bfbbe9a3f0c4f9bfe62d715b383c86996164781ef1053d1e3a22c2909 +0e646c6c3cc0f9fdedef934b7195fe3837836a9f6f263968af95ef84cd035750f3cdb649de745c874a6ef66b3dd83b66068b4335bc0a97184182e3965c722b3b1aee488c3620adb835a8140e199f4fc83a88b02881816b366a09316e25685217f9221157fc05b2d8d2bc855372183da7af3f0a14148a09def37a332f8eb40dc9 e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb b527cb076845197d3d7e2c4789fb29170d32189c186fba09d8f6c6d99c81f23e009fa320890dc982fb349b2278e6246a +67d9eb88f289454d61def4764d1573db49b875cfb11e139d7eacc4b7a79d3db3bf7208191b2b2078cbbcc974ec0da1ed5e0c10ec37f6181bf81c0f32972a125df64e3b3e1d838ec7da8dfe0b7fcc911e43159a79c73df5fa252b98790be511d8a732fcbf011aacc7d45d8027d50a347703d613ceda09f650c6104c9459537c8f 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c b8542730fd927a728714416c49c18c2e4e04812f9756e3bb574f91879193a2202a809e976e345b032ec118b715d8b093 +45db86829c363c80160659e3c5c7d7971abb1f6f0d495709bba908d7aa99c9df64b3408a51bd69aba8870e2aaff488ef138f3123cf94391d081f357e21906a4e2f311defe527c55e0231579957c51def507f835cceb466eb2593a509dcbee2f09e0dde6693b2bfe17697c9e86dd672f5797339cbe9ea8a7c6309b061eca7aef5 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f a7f640008fa4c111d7e7d0db370824a4b123ddbbc77f3cbe0c289280e7046c44207bbbf753cdb213d17fc299e0da387d +4672fce0721d37c5be166bffa4b30d753bcf104b9b414db994b3ed33f36af4935ea59a0bb92db66448b3f57dad4fc67cef10ce141bf82c536be604b89a0bc0e8bca605b867880049d97142d30538fc543bd9d4fab7fdbe2f703815cdb6361beb66acff764bc275f910d1662445b07b92830db69a5994857f53657ed5ca282648 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7 ac06afa41d7509bb37391aab79970800c601ba4dfb066aa41a2dfcbd7c5ab661c9c6a94d2c448b0a7ef7d3c48d126fc5 +9ae48fdd9bfc5cb0f4d4761e28b2073bda05a3e3fe82c212e66701dc4573cc67a829b0f82d7520b1bf11db0c6d1743822bbe41bb0adbd7222aa5fae70fbd1a31f2d4453a01c81e064d775388468be96f6063f8673b7b8d4455fe1bd4c801ad5e625a015eaa4a1a18da490d2af8642201eaba3c611cbd65f861d8e19ca82a1ee6 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf a7c8c9c259e25d6c4c13e2827bfcf3efa5a15c58de7c3f2beb2c35db1846f0ff850907ac2ebc0b2250e729995c94a581 +817d6a110a8fd0ca7b4d565558f68b59a156744d4c5aac5c6610c95451793de2a756f774558c61d21818d3ebeeeb71d132da1c23a02f4b305eccc5cd46bd21dfc173a8a91098354f10ffbb21bf63d9f4c3feb231c736504549a78fd76d39f3ad35c36178f5c233742d2917d5611d2073124845f1e3615b2ef25199a7a547e882 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b 8e866fed38b9c5df43fd64ebe6b0d97fabe687ac15edd3460c912e72b1ae22a9414ffe6a8af4baf72e6f925c00ef86f5 +464f10ec6fb229a51db5fd0e122f2cb8a9a022117e2987f4007bf5565b2c16aba0714e2e3cdd0c100d55ac3017e36fc7501ad8309ab9572aa65424c9eb2e580a119c55777676ec498df53ef6ae78fd8a988130ee0e6082bf1ef71cd4c946021018a8ca7154d13b174c638912613b0bdb9001c302bf7e443ad2124ab2c1cce212 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69 887867686f1a489ded3f9b88c6cfb3cd6008c4de18bb72b1087fee0832cbc44f0e5fb7c9b0281f004d4c95ae9dac69e9 +4e3e0fb96320ddccde8b463c273654c4f7164920b1d63430921d2e808dee403e6420eedda0a557b911d00736a4f8798dd4ef26673efd6d190988ad4929ec64f8685cfb76070a36cd6a3a4bf2f54fb08a349d44642b6f614043fef9b2813b63457c76537d23da7b37310334f7ba76edf1999dad86f72aa3446445a65952ac4e50 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db 817407306b4bca324fa4f2f4a221b2bb6c015910571f95cab597eaab2aaf57a1735ce21320e01c42e1e1df095b66ece7 +c466b6b6baf7e6ffa876ec06105e2d43534e0517c07b1c4c9fb67ba81ce09525a7721ec3c290f2b1f65b6463d41598e7a25b2238501629953a5ca955b644354fb6856733a2e5bb8f5bc21a0c803493f5539f9fb83aab3dba2c982989c2270c61ab244b68bfe1b948d00c2ed975e09c29b5f8a7effcad8652a148cc880d503217 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d b6ff7e0d315aebc8026fdbe1141883e4804233a47e047c636f155413f78f3ba7c8092b93de6dd36fc3e046efb673f6f4 +feac892b7720af80b3c9eede51e923f18d3d0c5de4c31f4aa75e36df7c7c2fd8f41778851a24b69e67dccb65e159dd5c383243bad7cfedcc5e85c8a01c34b0b94ba8e07e4c024c09d279b3731e8b62f9562d3c4f5042567efe42a9d0eaaabab28bc6f11232fc8ceaaf4518d9f3b2bebf020294496b7f6b879e69503f75fecd3d 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476 99e7362eeb3f4ddfa1625d706976e0c789c9ee7f5006b6e253e41da859abb66e4322e1aa672c87c1d94b8fc787c0c786 +cf2982e3bf174ce547741b969403cd11e9553067e6af8177d89511a0eb040db924530bdba65d8b1ff714228db0737c1756f509e1506014a10736e65be2f91980a73891496e90ff2714a3601c7565cdcef5a395e2e0e1652f138d90d61eaa9cba993b823245647f6e07cec9b8b4449cd68a29741cd1579c66e548ca0d0acf33aa ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa 8e2c9a6f1fd8c9b92af22213af1446b90d12b10b37d2545b5a0bc624b60a6e2680fa0a761b1967ed5bfdef0ddaab5cb9 +bf9fdd4107ef5a6070108771ac9eee4f0c8043bf0d04db772a47294f4137e2439d94b337114b074e57e0cb78d0ccf352a2833e9788ee2a1a9ffeacd34f38fcefb86653d70c7dadd4cf6548d608e70acdef6c7530974b92c813798add659752a8c72b05e1ad9c65c21834ce6fbe49d8a1426b5a54270794436d284364fac6ec1a 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f 95b50ad8c93a43f1681a626ee4e99d648a1cf2d58a0a608f7ebf15bc302d969b66daee85c599f8401750c64782b006f6 +5d634fb39a2239256107dc68db19751540b4badac9ecf2fce644724401d6d632b3ae3b2e6d05746b77ddc0c899878032248c263eda08d3d004d35952ad7a9cfe19343d14b37f9f632245e7b7b5fae3cb31c5231f82b9f1884f2de7578fbf156c430257031ba97bc6579843bc7f59fcb9a6449a4cd942dffa6adb929cf219f0ad e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1 937a7ec959dd62f5f83569d456d998ad1d36ccfb7284f5a3a259a972e7368f3402f3936748ad26d7f4142542697c80fa +c9b4ff721b3e886f0dc05856ffff0aabb64a8504b1746a47fdd73e6b7ebc068f06ac7ffa44c757e4de207fc3cbfaf0469d3ac6795d40630bcafe8c658627e4bc6b86fd6a2135afbc18ccc8e6d0e1e86016930ca92edc5aa3fbe2c57de136d0ea5f41642b6a5d0ddeb380f2454d76a16639d663687f2a2e29fb9304243900d26d 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c 85ad292a2339e8de12f7bbdc848bfd3def4aeef07fa8de0e0c0dcfe856404e69f5934e94c6e0e7e1ee655ccc8462ef91 +db2ad659cf21bc9c1f7e6469c5f262b73261d49f7b1755fc137636e8ce0202f929dca4466c422284c10be8f351f36333ebc04b1888cba217c0fec872b2dfc3aa0d544e5e06a9518a8cfe3df5b20fbcb14a9bf218e3bf6a8e024530a17bab50906be34d9f9bba69af0b11d8ed426b9ec75c3bd1f2e5b8756e4a72ff846bc9e498 e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c a68f36e748535f13f9f425e47856035d9ef916c5890ff75ae6540daebf090843071ffbcda9baff150efb0a9f876d50ee +dbd8ddc02771a5ff7359d5216536b2e524a2d0b6ff180fa29a41a8847b6f45f1b1d52344d32aea62a23ea3d8584deaaea38ee92d1314fdb4fbbecdad27ac810f02de0452332939f644aa9fe526d313cea81b9c3f6a8dbbeafc899d0cdaeb1dca05160a8a039662c4c845a3dbb07be2bc8c9150e344103e404411668c48aa7792 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855 956c2effedd21911d7792e1a2c87b1fc38ef0b07c335b6b2c4c13ea288c198036f746e002a8147341a5243673c3a95e5 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P384_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P384_blst new file mode 100644 index 000000000000..142872d107fe --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P384_blst @@ -0,0 +1,60 @@ +39f0b25d4c15b09a0692b22fbacbb5f8aee184cb75887e2ebe0cd3be5d3815d29f9b587e10b3168c939054a89df11068e5c3fac21af742bf4c3e9512f5569674e7ad8b39042bcd73e4b7ce3e64fbea1c434ed01ad4ad8b5b569f6a0b9a1144f94097925672e59ba97bc4d33be2fa21b46c3dadbfb3a1f89afa199d4b44189938 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727 82c8af16b975e30575985851c67661ef8bdd09c5d722cc4c66d474f112f1173fa7f853f1c7013121209bb7cfc2dac799 +5a3c80e608ed3ac75a6e45f6e94d374271a6d42b67a481860d5d309cc8b37c79cb61f1716dc8aa84cb309ef9d68eb7fc6cf4b42333f316a5c30e74198c8b340926e340c5de47674a707293c4aa2a1a2274a602f01c26b156e895499c60b38ef53fc2032e7485c168d73700d6fa14232596a0e4997854a0b05d02e351b9d3de96 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246 b1556df7dab55135a3c563faf82bce8d09b3e6c5e858bdf5871254bd82ee1e58e213f9312beab198e678e5f4fe54ce86 +e7d974c5dbd3bfb8a2fb92fdd782f997d04be79e9713944ce13c5eb6f75dfdec811b7ee4b3859114b07f263846ae13f795eec8f3cb5b7565baff68e0fdd5e09ba8b176d5a71cb03fbc5546e6937fba560acb4db24bd42de1851432b96e8ca4078313cb849bce29c9d805258601d67cd0259e255f3048682e8fdbdda3398c3e31 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83 8672d3a983db24f53f434c78ed3f63b17ad655b3e9cb0f45a05ec6fa9835a05d414dd55e58ec13948e2fc63f0c959858 +a670fda4d1d56c70de1d8680328043b2b7029633caf0ee59ffe1421c914bb937133d5a0f9214846b2e0b350455a74c4ab434c56de65a17139bb8212bf1c76071a37536fa29348f871dbb26baa92eb93d97e923a6d2ffd9be25cbc33075e494e6db657bd8dc053fe4e17148d8cf6e2058164f2b5766750eb01bbe7b361cdb848c dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659 a6c04fd8c0e94283a4bd2cca9a9833e70fce51e83a7fc158c14257cc9650563bd5b07b7f2d81af16185a9a0699a50105 +7843f918fe2588bcfe756e1f05b491d913523255aa006818be20b676c957f4edb8df863c6f5f8c15b3b80c7a2aa277b70d53f210bdfb856337980c406ea140e439dd321471407f374f69877b2d82367eed51e3c82c13948616dcb301d0c31f8f0352f2846abd9e72071f446a2f1bd3339a09ae41b84e150fd18f4ba5d3c6bfa0 df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718 b2de0a9ab740db1809aeb57454bd5bc21e5708ee363b772dc76472049528ccc939b463a5666a099545af18afd3a02e6b +caa83d5ab07febbd2e0fe2d63738b9b7b8752594bea7aaf50345b3d2f316653a8c9222f2b7877b64679e9573e81461a426029e45b8873a575094a1d572e0d32a9f0a9c6bcb9a2868543b7d8bbe4a69a09e7321f05f8366cced1b72df526f895b60aed2c39c249653c7839538770d4e5f47d3926ec0d168ab6a1af15bf1dca1f7 ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f a8fd2f0438f09182f8cca9e2b844515aa3ce1c42824087f642e38b94a56994f2b7fbdf8ac15f2d35c6635cedfc2633d7 +594603458d6534974aeeafba919c4d0f4cb6843a3af41204bbb88aeb2fca2772d305163dba863da050aabedbaf89db521955d1715de95bbcef979ecdc0c976181ece00355385f8a8f8cce127c9eac15ce3e958a3ed686184674ec9a50eb63271606ee7fdcb1323da3c3db8e89cad1fb42139a32d08abcfbf0d4ccfca18c89a86 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829 b7c9f4c7c5a9061ea5d39ffde58132e13a0309cd7c112852bd22ce4e4ec17a0f9e322c042c2d2048751f93302ead2971 +733252d2bd35547838be22656cc7aa67eff0af0b13b428f77267a513c6824c3dbae533068b6817e82665f009560affcfe4b2ddb5b667a644fc1a42d24f24e0947e0dc50fb62c919bc1fe4e7ded5e28f2e6d80fcf66a081fb2763526f8def5a81a4ddd38be0b59ee839da1643eeeaee7b1927cec12cf3da67c02bc5465151e346 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1 8b5cc5e362123dd2d575c3f8f60c3e9193db8143ca240fee6542101fef7cf4c5bb05b3bc3a301b21053c1bfc09fc9af6 +5a182bd174feb038dfae3346267156bf663167f713dea1ce936b0edb815cd9b8c8e4d411c786ba2494a81442617255db7158b142e720d86c9b56680fb9efd4298cdd69079a28153494c42a24251c7ad42ecf7e97eabc1b3997529b2a297cbad2474269b87a0b1e385f2d7f8b6eb8d1cd75eaf7e91d1acbecd45d7b2bfbbe3216 e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d 96ed6c87a6b7be3d340b67dc7ff9f55657e7b0d0fa5f4b94896cc2be5d9734065a13de80e61cc372a9e7f9819c9e4254 +aaa99fb1c71340d785a18f6f668e898c25cf7a0ac31d13c5b388b7233408493a5a109af6d07065376b96f4903df7aba2b2af671a18772bb0472490d1240cde28967680727dd4acd47e0308920a75da857a6eeedee5b6586d45dff3d8a680599665aa895c89dd7770b824b7dee477ac5e7602d409d3cc553090c970b50811dbab 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead 96e34d74db0f9b90f9dd6f4f94e7584e7d26df39f4025873307e8c512e178d7fdacb12d98fb946167f219575c6bf22bc +1fadfa8254d3a0b82d137cfdd82043d5dc1fef195d5297b09cc5cfb061f59c933451c0dc2a11b4037f34f88dacb803251f8880c4b72585c3c196e6fb23484ca43a191f8e41b9b9a37e2e6fcaab6738c3c62d1c98e1c620bb788b7b51a04f998a510efdba0d3418622fe8ce203b3fcd553b9b4206365a39031797ad11e49745ec 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0 9052076f9bfb784be16404f312a09b4800cc9235d5c833bce46f02d7ce3edad9fa29db608f8470bed7c06eda1c92744d +9ecb6f5ed3ba666a8536a81ef65012c2cb8b433508798d84708abb06dfb75503886f78384fb8c7a4d2d49ef539d9b8a0b60938c7f07471dda91f258b0d99691b38a8403a2bb3f956bdfd09baba16d9b6877097a9b6213481b47a06e139d23ec7abad5668d21f912fdb70d31bb9adf9b3ce80e308252fa81a51674f88d02db72b f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1 b2c5a47117773c8f2ed2b366ed643ad96da75ef8a2d3a5733ed0a0732a32b3b189fb243e4e2954b172c0e2245f582ae8 +e55bfca78d98e68d1b63688db12485578f36c489766f4d0bfaa0088433ff12133aaca455805095f2e655940860958b3ead111d9070778ee3bbf3e47e43d9eba8b8d9b1fdf72f793fcde2bcaa334f3e35fa2cca531ea7cf27fe9ccba741e38ac26129b2d612bf54a34e0ae6c166c0fef07fcd2b9ac253d7e041a500f7be7b8369 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb 9017ccd6e002250b1ade108775ffdc6824e2d57f0dd0bb7bf73e2266bfc83f5c534437306460e935881ede0c7dc5f7c3 +02c6b3c83bd34b288d96409162aa4ff114e9d134bf948046eb5ebcc0c7fe9dfceadda83ed69da2fac00c8840f6c702a3fc5e6959d70f7e8af923e99e4937232ae3b841ffefd2e62fab3671a7c94a0281b8ea5bc176add57c5c9b6893fe7f5d48ce7256b96510810c4e046168a3c5be9843b84d5268a50349b3444341aa5490dd 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6 91d1f78b5278843eb3072907da966910c7738bcfaddf215bc31a281005fa06aed8d8d8ac6e007cfd44ea43fbce280acc +94f8bfbb9dd6c9b6193e84c2023a27dea00fd48356909faec2161972439686c146184f80686bc09e1a698af7df9dea3d24d9e9fd6d7348a146339c839282cf8984345dc6a51096d74ad238c35233012ad729f262481ec7cd6488f13a6ebac3f3d23438c7ccb5a66e2bf820e92b71c730bb12fd64ea1770d1f892e5b1e14a9e5c cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd 953a06e34928c6a806274ce7bc42eeea31ff611d7809e153cc28e7faef5bb382a629ff1a5d34f3887cb8a099464dabe7 +663b12ebf44b7ed3872b385477381f4b11adeb0aec9e0e2478776313d536376dc8fd5f3c715bb6ddf32c01ee1d6f8b731785732c0d8441df636d8145577e7b3138e43c32a61bc1242e0e73d62d624cdc924856076bdbbf1ec04ad4420732ef0c53d42479a08235fcfc4db4d869c4eb2828c73928cdc3e3758362d1b770809997 c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b b1919a10507540c7bd1e049eed40a970761fe214927aae6adbef08e30c87ce6af9a1c3831cffac6d5f9719f83c23d0d5 +784d7f4686c01bea32cb6cab8c089fb25c341080d9832e04feac6ea63a341079cbd562a75365c63cf7e63e7e1dddc9e99db75ccee59c5295340c2bba36f457690a8f05c62ab001e3d6b333780117d1456a9c8b27d6c2504db9c1428dad8ba797a4419914fcc636f0f14ede3fba49b023b12a77a2176b0b8ff55a895dcaf8dbce 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9 a7e51f65d000cd11eeb7c3c4199584d2adad4f88bb61a097842f97ff421be89f5c47582a0995807ff962b6d7aaf7e860 +45e47fccc5bd6801f237cdbeac8f66ebc75f8b71a6da556d2e002352bd85bf269b6bc7c928d7bb1b0422601e4dd80b29d5906f8fcac212fe0eaaf52eda552303259cbcbe532e60abd3d38d786a45e39a2875bce675800a3eaeb9e42983d9fd9031180abd9adccc9ba30c6c198b4202c4dd70f241e969a3c412724b9b595bc28a d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f 8d655c8f04ab3183e2268fe2ea2d974c15b3b706565d6abb141f64409b29494d605804e65bf8f2c8374d7fda701e322d +c33ff63b4e6891e00b2349b3f2907c417ca355560544a91e24a7a0ee260d6850aeded29fc0176b6039ca6187e8333391047cceaf14b1077df8f147dad84d36b2dac5666dc2f69dc9b58b88cc73956efdb3b47f91831d5875051c76b0c4e9fc087012a1f03eeee85d6745b46aa50bd9cb0110c2c94508765cec162ee1aa841d73 d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3 9720c876d6483fd49da6b3b49dc3e0588c71eddac1a15768e2f0eadaccd717993842fa06250c54d8175846b90b8dd9d8 +f562f2b9d84b0e96a52532c3b43c39c8018c738bd8dc3797a7de7353971b2729d522d6961b1f2e4df3f6a4bd3653e6d72b74fc0dba92ab939c4b542e994e5db6dd8ed4f56f651e699052e791237ae1f552f990ad156226ae8f7bf17fcbfa564f749604f97e9df0879d50985747d981422a23040fe52f5ec74caf1d4aaad8a710 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93 aaaa70c59ca381f74cb924bd7efd86198d31a53bcc4d5b25c533c52edb24af4866555aceb0d5e0f07be254bac78200fb +ace953ae851f571d71779aa120915f27450b236da23e9106f8d0756abdd25861937941228d225d5fb1aa1b1ebf759b1e326aeb3b6cd0cd87edd2ab9f6a7ad67b63d2c501d6a550edb2e7c9d216cc8af78dd33546af64d00abed4d0d2cfc5c9a7b5a055dbe8f7547902d185cf46937314832bc5c602419a82ab83dbd9d3bd5aff e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1 a3c118105f84ebbfeccdeedb86f2be742de8e6b80c59affad6e013d6aa73de4a472195c013840c8fdeda32cdc52e84e5 +9635ab832240be95301bedb94c5aec169eedc198cbbdfedcf41e9b586143d829b4597a6b2a81902828332825fd84a785f187a3894e21bd99d22c4f94dcf34453fc052f15ec64d1447c932cb38fcdd30b7be851963409c11881438cbaad7e96f9efbde317f2235d66af804477a5dfe9f0c51448383830050ecf228889f83631e1 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960 b7f7ade69fbb763e6890de133480eb3fbf451048f1a39a5398632747f1fc5fe1238ecdd1530216d1214d337d4c4fd05e +d98b9a7d4fe9d0fd95de5056af164a8b7882cd34ab5bde83a2abb32dc361eb56a479a3a6119db3b91dcad26a42d2206749567f0d97c34a981a91fc734921821a429f6a53401743a5c406ba9d560f956203abc9d1f32f1a13e7d7b290f75c95fdbf857ea597021461c06a3aacfa554ede3d69e4ff03bbbee5b7463ec77de2b3b2 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57 a11159a539caba75b211cff5cab64c1b77b0a358ab89a5e80d64f9df4d0338a26d23606e4695df95c9b8974fcb8986e8 +1b4c754ac1c28dc415a71eac816bde68de7e8db66409af835838c5bb2c605111108a3bf13606ed5d8ade5ed72e50503e0de664416393d178ea4eec834d8d6f15039847b410080fd5529b426e5aadd8451c20ebd92d787921f33e147bcbeb327b104d4aab1157fc1df33e4d768404b5ccb7110055c2508c600f429fd0c21b5784 a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1 8d803b26d39ccdaa5bab3c48013171cf657e875f6a6187f2c9f6455bdaf039bf723c064f0dc910823bf481bc76fdbd9a +3cd8c053741dd9f974c6c5dbf8a1e5728e9b5eafb1cbcfc3452f5fbbda32a8c7564dee157e8d902c52514361da6d972934a56b3276e2a9379e328e24282e0db697c5bc29090fc489ec46b7b188325dd4e96494c250de0f4a89fe2ccf919eaefcfb50c288113e6df92714feb7f46e0822478c796d0f4ff3447a32997e892693ce 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3 b1648ab4aa827024bb8b0963bb4d414d500ab7b62772608c124114a49fc94739d9256161f453652d4cf497597b2c5884 +ed955dda6d9650124804d3deb6aeef900e520faf98b1ef6f14efcada7ca2433f09329b70897305e59c89024d76e466b28fe02cb2a9b12e2478c66470259d7c282137a19e5a04ffadea55245c0f34a681593fedc42931d8b3321b3d82e9cc102cd00540ad311ec7bd8c9d06db21bea4ca3dc74d98931ae0d40494aefc2345132c 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907 9834e0d0b6c5dbbcaca58529e21442641653ac83f6568cb52d7e43303667950327752d76e323acd6b229d39a77d1c624 +ce395b001da2a58e49691605d44af4206306f62f561bf2394060d2a5591a350277166bed043819035f1e60b5b3fb5ae113ddd0473f8ef6b2b050c472c2a264e1d8b3ca82a4f158c40f2d78d9ce5e5ea6de243f2e1f13f47f6c6f403b270912c81c636be35b396ca58468b3fb60aa83911d61441a0528d973bc31f965d4059080 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245 856af3f93f9303b3afbc4db09ca51a614bd0d166b21f502eea36cb847af6f240f4bee7d511ee8a6dab2dfe4bc43617a1 +ffefe316455ae4ffdb890bb804bf7d31424ea060ecacff419d0f7134ff76ad434063c0ec0f8bb7059584d3a03f3625bb9e9f66ace1a47ac4b8f3e76fc7c420c55edb1427d1fa15b387ad73d02b0595c4e74321be8822752230a0dcfb85d60bfa186da7623a8ec3eb1633f0a294b23ae87216b14ccee9ef56418dcfab9427371e 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7 8f061e1a8d27d603d125c4a48cb1b339e1adba81f066f0dce592108891e5cf5110352ef1f49db3db88951bbb3d18f948 +304bccb718b3a9e12669913490cc5bcc1979287b56c628fad706c354241e88d10e81445a2853e3fc32ece094ba1abc3fdcab61da27f9a0fca739371049fed462ee6b08fa31cde12720f8144a6f00ce9b1a7a6eadd231f126717074b4efb5c72ce673ca5859000a436f67a338d698759f12c461247c45a361fb6cb661fdbe6714 d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5 b90a2b8d0c0458b791aaaa18ecf149f8b794b4bedceb7e5d65a31dd90e4860ba12d5fe0d66f26629b8ef0498c0a6cf05 +64f9f05c2805acf59c047b5f5d2e20c39277b6d6380f70f87b72327a76170b872bfe4b25c451602acfb6a631bb885e2655aee8abe44f69c90fb21ffde03cef2a452c468c6369867dfd8aa26ac24e16aa53b292375a8d8fbf988e302bf00088e4c061aa12c421d8fe3cbd7273b0e8993701df1c59431f436a08b8e15bd123d133 b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224 ab4d574a9e520d9ce42e9992669bef099fd7b9b1ed43b4f5f0cdc5ca5dbd09758aaf73a2dd6d3a149631a24324030a7d +6b45d88037392e1371d9fd1cd174e9c1838d11c3d6133dc17e65fa0c485dcca9f52d41b60161246039e42ec784d49400bffdb51459f5de654091301a09378f93464d52118b48d44b30d781eb1dbed09da11fb4c818dbd442d161aba4b9edc79f05e4b7e401651395b53bd8b5bd3f2aaa6a00877fa9b45cadb8e648550b4c6cbe 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 a34d83e77e35330d32830fa2085afaa15169a4d4ef9e5ba904ca6fe73558e03bf86ea56c5eaf2e8dcba62ea9d7f48fe7 +d768f41e6e8ec2125d6cf5786d1ba96668ac6566c5cdbbe407f7f2051f3ad6b1acdbfe13edf0d0a86fa110f405406b69085219b5a234ebdb93153241f785d45811b3540d1c37424cc7194424787a51b79679266484c787fb1ded6d1a26b9567d5ea68f04be416caf3be9bd2cafa208fe2a9e234d3ae557c65d3fe6da4cb48da4 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 8de585c5e383d5b16e58e05592599be30b94f399b176fd28f6f74a1f530aca20c8e884deb1311b34f8418c037cdb0d79 +6af6652e92a17b7898e40b6776fabaf0d74cf88d8f0ebfa6088309cbe09fac472eeac2aa8ea96b8c12e993d14c93f8ef4e8b547afe7ae5e4f3973170b35deb3239898918c70c1056332c3f894cd643d2d9b93c2561aac069577bbab45803250a31cd62226cab94d8cba7261dce9fe88c210c212b54329d76a273522c8ba91ddf b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 8ba727438045abb637a2157959c586d7191fe7e3b6bbd03dfe0ebeecc91e0b1a2fb371404ce50a0e2e90d9471f7a403e +b96d74b2265dd895d94e25092fb9262dc4f2f7a328a3c0c3da134b2d0a4e2058ca994e3445c5ff4f812738e1b0c0f7a126486942a12e674a21f22d0886d68df2375f41685d694d487a718024933a7c4306f33f1a4267d469c530b0fed4e7dea520a19dd68bf0203cc87cad652260ed43b7b23f6ed140d3085875190191a0381a de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 abb221de9a796bec54aa8eb19a60318bcddf902bd7d37d731d00ac18c7dc32f8d4232575663ba5c69052991effb527ff +7cec7480a037ff40c232c1d2d6e8cd4c080bbeecdaf3886fccc9f129bb6d202c316eca76c8ad4e76079afe622f833a16f4907e817260c1fa68b10c7a151a37eb8c036b057ed4652c353db4b4a34b37c9a2b300fb5f5fcfb8aa8adae13db359160f70a9241546140e550af0073468683377e6771b6508327408c245d78911c2cc 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc a859e524f66a2c864f9ab7e269baec23364cb9263b12d3c6c6dbbb851c013870b6301c4c2cb7b699d5a831e3c20c3554 +00ce978603229710345c9ad7c1c2dba3596b196528eea25bd822d43ca8f76a024e29217703dd0652c8a615284fc3edcc1c5ad1c8d5a8521c8e104c016a24e50c2e25066dcb56596f913b872767e3627aa3e55ec812e9fdac7c2f1beade83aef093e24c9c953982adf431a776880ae4583be158e11cdab1cbca3ad3a66900213d 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 824caa2c83e706f7a94a547b27186bf68e4e6befdbc56fc613de6b32a14ef59b2f28a0b0e518c017fe9eb127a91d51ca +54a255c18692c6162a46add176a0ae8361dcb8948f092d8d7bac83e160431794d3b9812849bf1994bcdcfba56e8540c8a9ee5b93414548f2a653191b6bb28bda8dc70d45cc1b92a489f58a2d54f85766cb3c90de7dd88e690d8ebc9a79987eee1989df35af5e35522f83d85c48dda89863171c8b0bf4853ae28c2ac45c764416 ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 ad88bcfda9a1eed477a30c05ec0a6752b668441b6506fc10f507a79263f1e7c54a89e235a6af1c1c66ae7632cc6f0985 +692a78f90d4f9d5aee5da536314a78d68c1feabbfe5d1ccea7f6059a66c4b310f8051c411c409ccf6e19a0cbd8b8e100c48317fe8c6d4f8a638b9551ce7ee178020f04f7da3001a0e6855225fb3c9b375e4ed964588a1a41a095f3f476c42d52ffd23ce1702c93b56d4425d3befcf75d0951b6fd5c05b05455bdaf205fe70ca2 adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 9530619d3c2857e987987c2c6a99746204d14d892c3a529da546a72b43e80a74cf5ce9cc70faaa496b2714d0daaeb5e2 +3b309bb912ab2a51681451ed18ad79e95d968abc35423a67036a02af92f575a0c89f1b668afe22c7037ad1199e757a8f06b281c33e9a40bab69c9874e0bb680b905d909b9dc24a9fe89bb3d7f7d47082b25093c59754f8c19d1f81f30334a8cdd50a3cb72f96d4b3c305e60a439a7e93aeb640dd3c8de37d63c60fb469c2d3ed 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d ad3e22d52f85d8b143c506d2def873ad5196e5ca9bb767b739fde79fa9c57a44331c58f47facd2aa35a72f94df449867 +f072b72b8783289463da118613c43824d11441dba364c289de03ff5fab3a6f60e85957d8ff211f1cb62fa90216fb727106f692e5ae0844b11b710e5a12c69df3ed895b94e8769ecd15ff433762d6e8e94d8e6a72645b213b0231344e2c968056766c5dd6b5a5df41971858b85e99afbf859400f839b42cd129068efabeea4a26 e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 8c58ca350615edb0ecf4617c94ea6b71b4f3867835531c77338072d7cfeb8702a46dbd6e005347ae8941ba7a3bbd96e2 +cf4945350be8133b575c4ad6c9585e0b83ff1ed17989b6cd6c71b41b5264e828b4e115995b1ae77528e7e9002ac1b5669064442645929f9d7dd70927cb93f95edeb73e8624f4bc897ec4c2c7581cb626916f29b2d6e6c2fba8c59a71e30754b459d81b912a12798182bcff4019c7bdfe929cc769bcc2414befe7d2906add4271 d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca 81938ddeb5d3b5745f001418d760ba119bf4bc8f46c4d884e7a81fc72858ee3196f4471b996abe51ebe1b3e65b61b011 +d9b5cf0b50416573ff3c63133275a18394dd4326be2041e8d97e6e4e3855a4a177e9d26dfd223fe8aa74564edb49bd72de19916fb6f001f44530d5c18e2c332bce1b7415df5927ece5f3824f34d174b963136b53aef1fb78fb0c06a201a40b2db38e4d8216fc1e392a798c8ab4b3a314496b7f1087804ebfa89bf96e9cdb80c0 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d b41a699b3f833e0851c3bd4757e2701ab5f373b0b2218a6dab88241808e4a0feff7f6437fab8c12a3f71877745af9d46 +9e4042d8438a405475b7dab1cd783eb6ce1d1bffa46ac9dfda622b23ac31057b922eced8e2ed7b3241efeafd7c9ab372bf16230f7134647f2956fb793989d3c885a5ae064e85ed971b64f5f561e7ddb79d49aa6ebe727c671c67879b794554c04de0e05d68264855745ef3c9567bd646d5c5f8728b797c181b6b6a876e167663 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 81d8a62a43214f4ff476610cb26dbe17d3cbef4894588cc16f5c5c2b22fc975e2cce78d2c9f5aae9b044476b1e9d0d4a +0b14a7484a40b68a3ce1273b8a48b8fdb65ba900d98541c4bbd07b97e31bcc4c85545a03e9deab3c563f47a036ff60d0361684ba241b5aa68bb46f440da22181ee328a011de98eff34ba235ec10612b07bdfa6b3dc4ccc5e82d3a8d057e1862fef3def5a1804696f84699fda2ec4175a54a4d08bcb4f0406fdac4eddadf5e29b ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 ad78156894f72a8efe4dcc4ac7305f501ad53bbb402ec5dc6f7254285957dab0bc4f005569447bd09a87c4f735b2d550 +0e646c6c3cc0f9fdedef934b7195fe3837836a9f6f263968af95ef84cd035750f3cdb649de745c874a6ef66b3dd83b66068b4335bc0a97184182e3965c722b3b1aee488c3620adb835a8140e199f4fc83a88b02881816b366a09316e25685217f9221157fc05b2d8d2bc855372183da7af3f0a14148a09def37a332f8eb40dc9 e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb 8c62682f31f7c82c9447849788317f1f1e60cd319705372e4db9bf7a63e1fc4629240218842d58cdc83969cc65562a6f +67d9eb88f289454d61def4764d1573db49b875cfb11e139d7eacc4b7a79d3db3bf7208191b2b2078cbbcc974ec0da1ed5e0c10ec37f6181bf81c0f32972a125df64e3b3e1d838ec7da8dfe0b7fcc911e43159a79c73df5fa252b98790be511d8a732fcbf011aacc7d45d8027d50a347703d613ceda09f650c6104c9459537c8f 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c 95c8bbbdbdc140bce044621f382534a2c8ef741abf6aced8a28178093b2e07d5ea80f4db4b8653872831ef63e09892d5 +45db86829c363c80160659e3c5c7d7971abb1f6f0d495709bba908d7aa99c9df64b3408a51bd69aba8870e2aaff488ef138f3123cf94391d081f357e21906a4e2f311defe527c55e0231579957c51def507f835cceb466eb2593a509dcbee2f09e0dde6693b2bfe17697c9e86dd672f5797339cbe9ea8a7c6309b061eca7aef5 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f b415c649250ec03cedd25f44f76c07c34f35ea3db9640f62c8c8f0f39fbf21ba459a508517140499f0179487571a7383 +4672fce0721d37c5be166bffa4b30d753bcf104b9b414db994b3ed33f36af4935ea59a0bb92db66448b3f57dad4fc67cef10ce141bf82c536be604b89a0bc0e8bca605b867880049d97142d30538fc543bd9d4fab7fdbe2f703815cdb6361beb66acff764bc275f910d1662445b07b92830db69a5994857f53657ed5ca282648 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7 93c17eac629d28dfa31e2ba804a0ce87ab2720d0c51810886184cb25676795dc48af19ebe7808fb34ddf15cb22ee6619 +9ae48fdd9bfc5cb0f4d4761e28b2073bda05a3e3fe82c212e66701dc4573cc67a829b0f82d7520b1bf11db0c6d1743822bbe41bb0adbd7222aa5fae70fbd1a31f2d4453a01c81e064d775388468be96f6063f8673b7b8d4455fe1bd4c801ad5e625a015eaa4a1a18da490d2af8642201eaba3c611cbd65f861d8e19ca82a1ee6 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf 8adc6ad70b4fba4bdb3e7225bd695015592f47c0af08b0bcac1442521f707afdc3706a1d3173d63157c9f05727b1ab9d +817d6a110a8fd0ca7b4d565558f68b59a156744d4c5aac5c6610c95451793de2a756f774558c61d21818d3ebeeeb71d132da1c23a02f4b305eccc5cd46bd21dfc173a8a91098354f10ffbb21bf63d9f4c3feb231c736504549a78fd76d39f3ad35c36178f5c233742d2917d5611d2073124845f1e3615b2ef25199a7a547e882 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b 988ac3a4a682390913d5bfb1d25bd5c1581550cf6005d474ff7e315e82a32b32a64b00ebce4ee33d184280b08349f58d +464f10ec6fb229a51db5fd0e122f2cb8a9a022117e2987f4007bf5565b2c16aba0714e2e3cdd0c100d55ac3017e36fc7501ad8309ab9572aa65424c9eb2e580a119c55777676ec498df53ef6ae78fd8a988130ee0e6082bf1ef71cd4c946021018a8ca7154d13b174c638912613b0bdb9001c302bf7e443ad2124ab2c1cce212 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69 a2089a329822a5e6344b1d2a9466884f8cb8822d0cc47fec8e19b1379b383e9b53b987d206ef610e905d69fd7a0b0657 +4e3e0fb96320ddccde8b463c273654c4f7164920b1d63430921d2e808dee403e6420eedda0a557b911d00736a4f8798dd4ef26673efd6d190988ad4929ec64f8685cfb76070a36cd6a3a4bf2f54fb08a349d44642b6f614043fef9b2813b63457c76537d23da7b37310334f7ba76edf1999dad86f72aa3446445a65952ac4e50 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db 9972d82b2a4766480c745b4f6dde09f0e3c7191d6f1ead94244f7a7ef21c9f8d51085664d0216793bee17517dc7ec4da +c466b6b6baf7e6ffa876ec06105e2d43534e0517c07b1c4c9fb67ba81ce09525a7721ec3c290f2b1f65b6463d41598e7a25b2238501629953a5ca955b644354fb6856733a2e5bb8f5bc21a0c803493f5539f9fb83aab3dba2c982989c2270c61ab244b68bfe1b948d00c2ed975e09c29b5f8a7effcad8652a148cc880d503217 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d 85bd011b47a3aea3aa823bdc4a4c0817c0cbc2ae0b82f9992f74d219f2f29abcd3dfa66b84e53ff0380ae86ab4a97643 +feac892b7720af80b3c9eede51e923f18d3d0c5de4c31f4aa75e36df7c7c2fd8f41778851a24b69e67dccb65e159dd5c383243bad7cfedcc5e85c8a01c34b0b94ba8e07e4c024c09d279b3731e8b62f9562d3c4f5042567efe42a9d0eaaabab28bc6f11232fc8ceaaf4518d9f3b2bebf020294496b7f6b879e69503f75fecd3d 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476 b6ca012f2abdaaba7d800994c86dabfec28e0ff1ab9db563d9c5b02b9897aa0b542b93120ba5ddb93c3e7654d999e73c +cf2982e3bf174ce547741b969403cd11e9553067e6af8177d89511a0eb040db924530bdba65d8b1ff714228db0737c1756f509e1506014a10736e65be2f91980a73891496e90ff2714a3601c7565cdcef5a395e2e0e1652f138d90d61eaa9cba993b823245647f6e07cec9b8b4449cd68a29741cd1579c66e548ca0d0acf33aa ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa a742ea887d6ee1dafc5298c15fc032b353743690d66157ec18813994e49bb2bc860bc33b4ac16919b981260b0aa7cfda +bf9fdd4107ef5a6070108771ac9eee4f0c8043bf0d04db772a47294f4137e2439d94b337114b074e57e0cb78d0ccf352a2833e9788ee2a1a9ffeacd34f38fcefb86653d70c7dadd4cf6548d608e70acdef6c7530974b92c813798add659752a8c72b05e1ad9c65c21834ce6fbe49d8a1426b5a54270794436d284364fac6ec1a 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f 9308a2921c7b8da1ceffa668c384eabe4f70798f0aa429cb60cae0a6f4b02722d630baa18ffb9224e69f66d500901b28 +5d634fb39a2239256107dc68db19751540b4badac9ecf2fce644724401d6d632b3ae3b2e6d05746b77ddc0c899878032248c263eda08d3d004d35952ad7a9cfe19343d14b37f9f632245e7b7b5fae3cb31c5231f82b9f1884f2de7578fbf156c430257031ba97bc6579843bc7f59fcb9a6449a4cd942dffa6adb929cf219f0ad e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1 8f94a94513ba64750f0422c9aa9c22b069b4d8522e8ba35d36738b1196d57fdf6094cb2bc7cb8ea0b3b8e40e8e4e128e +c9b4ff721b3e886f0dc05856ffff0aabb64a8504b1746a47fdd73e6b7ebc068f06ac7ffa44c757e4de207fc3cbfaf0469d3ac6795d40630bcafe8c658627e4bc6b86fd6a2135afbc18ccc8e6d0e1e86016930ca92edc5aa3fbe2c57de136d0ea5f41642b6a5d0ddeb380f2454d76a16639d663687f2a2e29fb9304243900d26d 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c b860c70777ed760d3ceaa9e58f57e885bc8776c50bff247a2a470d0de653f1fa6ce5fa6304262062e2b14a8cb18271d1 +db2ad659cf21bc9c1f7e6469c5f262b73261d49f7b1755fc137636e8ce0202f929dca4466c422284c10be8f351f36333ebc04b1888cba217c0fec872b2dfc3aa0d544e5e06a9518a8cfe3df5b20fbcb14a9bf218e3bf6a8e024530a17bab50906be34d9f9bba69af0b11d8ed426b9ec75c3bd1f2e5b8756e4a72ff846bc9e498 e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c 96f6f7d28a4568cf159aabe21edc4e00d4c52c4efba1157d1b43cbafe9c3676025ccb2d82fd45d057facaa34458ef6a7 +dbd8ddc02771a5ff7359d5216536b2e524a2d0b6ff180fa29a41a8847b6f45f1b1d52344d32aea62a23ea3d8584deaaea38ee92d1314fdb4fbbecdad27ac810f02de0452332939f644aa9fe526d313cea81b9c3f6a8dbbeafc899d0cdaeb1dca05160a8a039662c4c845a3dbb07be2bc8c9150e344103e404411668c48aa7792 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855 80b255b9b1c7ed536eb1e3021ba8c7ff274782ad29b1cd963182a1d45003f16ed2367878f445221f33da76e45302ac02 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P521 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P521 new file mode 100644 index 000000000000..e1532811c27e --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P521 @@ -0,0 +1,60 @@ +58ec2b2ceb80207ff51b17688bd5850f9388ce0b4a4f7316f5af6f52cfc4dde4192b6dbd97b56f93d1e4073517ac6c6140429b5484e266d07127e28b8e613ddf65888cbd5242b2f0eee4d5754eb11f25dfa5c3f87c790de371856c882731a157083a00d8eae29a57884dbbfcd98922c12cf5d73066daabe3bf3f42cfbdb9d853 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46 a4fa807530a628bf301e5f2bbf5e9701813a92324c044250fd121b9fc6bed83dbd1faa3a3940960e55bc9a17ee8ae9b0 +2449a53e0581f1b56d1e463b1c1686d33b3491efe1f3cc0443ba05d65694597cc7a2595bda9cae939166eb03cec624a788c9bbab69a39fb6554649131a56b26295683d8ac1aea969040413df405325425146c1e3a138d2f4f772ae2ed917cc36465acd66150058622440d7e77b3ad621e1c43a3f277da88d850d608079d9b911 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73 887e90660999525b48cb3563f618176af17ca028dbdb3c758ff2bef5faf1df66470a74a47fcd5e3136d43601b50cba6c +7ba05797b5b67e1adfafb7fae20c0c0abe1543c94cee92d5021e1abc57720a6107999c70eacf3d4a79702cd4e6885fa1b7155398ac729d1ed6b45e51fe114c46caf444b20b406ad9cde6b9b2687aa645b46b51ab790b67047219e7290df1a797f35949aaf912a0a8556bb21018e7f70427c0fc018e461755378b981d0d9df3a9 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace a7860dddb9a6bd97ea5439c775fa45718e2ff19ec9098891e0a7e6cacb3df90f16dd4d94ca94565da6fc3c8ddba278ba +716dabdb22a1c854ec60420249905a1d7ca68dd573efaff7542e76f0eae54a1828db69a39a1206cd05e10e681f24881b131e042ed9e19f5995c253840e937b809dfb8027fed71d541860f318691c13a2eb514daa5889410f256305f3b5b47cc16f7a7dad6359589b5f4568de4c4aae2357a8ea5e0ebaa5b89063eb3aa44eb952 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc 873c3d15201e4d2c61a98aa807cbe8ff1e316a0323a7019f64639ee6d1d264c166bd4b9cbb5fe6f423853d31f2016fd9 +9cc9c2f131fe3ac7ea91ae6d832c7788cbbf34f68e839269c336ceef7bef6f20c0a62ea8cc340a333a3002145d07eba4cf4026a0c4b26b0217a0046701de92d573d7c87a386a1ea68dc80525b7dcc9be41b451ad9f3d16819e2a0a0b5a0c56736da3709e64761f97cae2399de2a4022dc4c3d73c7a1735c36dbde86c4bc5b6f7 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549 86255d4cc7ff1acc311e26cbdf1fd92e009fb91ffe522f3d179bf3aacb752ea1776153f9b7225f07cd9eb09ff73abd9b +14c69f8d660f7a6b37b13a6d9788eff16311b67598ab8368039ea1d9146e54f55a83b3d13d7ac9652135933c68fafd993a582253be0deea282d86046c2fb6fd3a7b2c80874ced28d8bed791bd4134c796bb7baf195bdd0dc6fa03fdb7f98755ca063fb1349e56fd0375cf94774df4203b34495404ebb86f1c7875b85174c574c 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4 8a695c6e11827bb04698500dd8639fcc4faa640a3ac1ff1568f1fa3f4b3e3202042de9572ba4d26e6fb957a1d23f5830 +8d8e75df200c177dbfe61be61567b82177ea5ec58e2781168d2277d2fd42668f01248ca3eb29ffa2689b12ae40f9c429532b6d2e1f15891322b825a0a072a1c68fa09e78cfdef3e95ed6fdf7233a43cb68236560d49a3278f0b3f47cb08f475bd9ab2f60755ea4a1767de9313b71a1b9ea87ef33f34682efbda263b0f8cc2f52 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16 95a28a1601497ec9241664d0aa6a7e568e999cd4df86530c32e5ebb0b7a7c993f446288193be1f119774c2f85c8def93 +10631c3d438870f311c905e569a58e56d20a2a560e857f0f9bac2bb7233ec40c79de145294da0937e6b5e5c34fff4e6270823e5c8553c07d4adf25f614845b2eac731c5773ebbd716ab45698d156d043859945de57473389954d223522fbafecf560b07ef9ba861bcc1df9a7a89cdd6debf4cd9bf2cf28c193393569ccbd0398 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37 8a48a6adbd784375ed26b9777eb47f69aa1550b374cb13d0d30f398de96e5da19995058814e8a6f17816bf836c413172 +80aad6d696cbe654faa0d0a24d2f50d46e4f00a1b488ea1a98ed06c44d1d0c568beb4ab3674fc2b1d2d3da1053f28940e89ba1244899e8515cabdd66e99a77df31e90d93e37a8a240e803a998209988fc829e239150da058a300489e33bf3dcdaf7d06069e74569fee77f4e3875d0a713ccd2b7e9d7be62b34b6e375e84209ef 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256 830eadebfe014f8dc55a43a448113a22c03f0f728fcaf381d89363be84fdfcc1ce513049c64ba4c6fdfa2a78fc591e38 +8a7792a2870d2dd341cd9c4a2a9ec2da753dcb0f692b70b64cef2e22071389c70b3b188dea5f409fb435cbd09082f59de6bc2ff9e65f91b7acc51e6e7f8e513148cb3c7c4664f227d5c704626b0fda447aa87b9d47cd99789b88628eb642ed250312de5ba6b25f3d5342a3cbb7ebd69b0044ee2b4c9ba5e3f5195afb6bea823d 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7 b53d82d2b708fcb13037a4cdf9a05de7f8fec869bc82d7140a708aabb63d7cf69447d03102367d1eb0ce1e073024a11a +f971bcd396efb8392207b5ca72ac62649b47732fba8feaa8e84f7fb36b3edb5d7b5333fbfa39a4f882cb42fe57cd1ace43d06aaad33d0603741a18bc261caa14f29ead389f7c20536d406e9d39c34079812ba26b39baedf5feb1ef1f79990496dd019c87e38c38c486ec1c251da2a8a9a57854b80fcd513285e8dee8c43a9890 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73 a0a4b88e0c5d7239830319d36cc26381492e24f91d144f95229e733453c75279bb7b606f87d31cbd27b601a5dfa091a5 +ec0d468447222506b4ead04ea1a17e2aa96eeb3e5f066367975dbaea426104f2111c45e206752896e5fa7594d74ed184493598783cb8079e0e915b638d5c317fa978d9011b44a76b28d752462adf305bde321431f7f34b017c9a35bae8786755a62e746480fa3524d398a6ff5fdc6cec54c07221cce61e46fd0a1af932fa8a33 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c 8542f9daf0ad60d94c5a4ab0f5a1372f1b10e69e5e09a722e4784234d49c3558160eb952b6e8a75396a90f8278410271 +d891da97d2b612fa6483ee7870e0f10fc12a89f9e33d636f587f72e0049f5888782ccde3ea737e2abca41492bac291e20de5b84157a43c5ea900aef761006a4471072ab6ae6d515ffe227695d3ff2341355b8398f72a723ae947f9618237c4b6642a36974860b452c0c6202688bc0814710cbbff4b8e0d1395e8671ae67ada01 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace a178d62fd89c80d588269d7c8d9eae77458103733ed6978c9f6d7bac05b2e1e2ef9d44c7703f6f7e02d3c82d5b007016 +924e4afc979d1fd1ec8ab17e02b69964a1f025882611d9ba57c772175926944e42c68422d15f9326285538a348f9301e593e02c35a9817b160c05e21003d202473db69df695191be22db05615561951867f8425f88c29ba8997a41a2f96b5cee791307369671543373ea91d5ed9d6a34794d33305db8975b061864e6b0fe775f 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8 8798fa90328abfb9a6cbcfa98324061f887bd9974f24b2989eefaefc53e21576d6e3696c73e4744d5d8caf7a07a01040 +c64319c8aa1c1ae676630045ae488aedebca19d753704182c4bf3b306b75db98e9be438234233c2f14e3b97c2f55236950629885ac1e0bd015db0f912913ffb6f1361c4cc25c3cd434583b0f7a5a9e1a549aa523614268037973b65eb59c0c16a19a49bfaa13d507b29d5c7a146cd8da2917665100ac9de2d75fa48cb708ac79 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad 989ac8f80afb709dde3ca9246e98f42aecf5bd862ed31e17860c0526e824d4284fdd78757577fa5d787fc1cc56e0ac50 +8ab8176b16278db54f84328ae0b75ef8f0cd18afdf40c04ad0927ed0f6d9e47470396c8e87cde7a9be2ffbfe6c9658c88b7de4d582111119c433b2e4a504493f0a1166e3a3ea0d7b93358f4a297d63f65a5e752f94e2ee7f49ebcc742fa3eb03a617d00c574245b77a20033854d82964b2949e2247637239ab00baf4d170d97c 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a ab63abbc449251f87ac4b054a64bdbd043e0efb9bb43391221b80b759de84faa11a80010d03fe722f870fd12e5a0457f +c4bc2cec829036469e55acdd277745034e4e3cc4fcd2f50ec8bd89055c19795a1e051ccf9aa178e12f9beab6a016a7257e391faa536eaa5c969396d4e1ade36795a82ebc709d9422de8497e5b68e7292538d4ccdc6dd66d27a3ece6a2844962b77db073df9489c9710585ba03d53fa430dbc6626dc03b61d53fc180b9af5dea6 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c b6048cdd4b36c860c2d4dd8263d269cebe0db2fe4f8df26741b761979e4557a241a9f229a3d3fc981aa748564b5978a5 +1c1b641d0511a0625a4b33e7639d7a057e27f3a7f818e67f593286c8a4c827bb1f3e4f399027e57f18a45403a310c785b50e5a03517c72b45ef8c242a57b162debf2e80c1cf6c7b90237aede5f4ab1fcaf8187be3beb524c223cc0ceff24429eb181a5eea364a748c713214880d976c2cd497fd65ab3854ad0d6c2c1913d3a06 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d a55520d95a15a9c2db386beff8fed3cd510c4860b32ef4d9bda652425769cd110997b074a56741dd64d751ba28228bef +adb5f069b2b501a3ebb83d4f1808eb07710ac4a7b12532996855a20bcc54b2f76812915f632163c3654ff13d187d007152617cf859200194b59c5e81fc6cc9eb1ceb75d654050f260caa79c265254089270ccd02607fdcf3246119738c496dc3a4bd5d3be15789fc3d29a08d6d921febe2f40aef286d5d4330b07198c7f4588e 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c a49c02e236fc932ac4d9176d19ea318edec2ef9ba8092cd47feb7d32b8e81e6faca8401c266b008106b827b78193c71f +f253484d121d1ce8a88def6a3e9e78c47f4025ead6f73285bf90647102645b0c32d4d86742a50b8b7a42d5f6156a6faf588212b7dc72c3ffd13973bdba732b554d8bffc57d04f8167aef21ee941ee6ffb6cce0f49445bd707da8deb35dca650aaf761c3aa66a5ebccddd15aee21293f63061a7f4bfc3787c2cd62c806a1a9985 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25 8c4927e5c361542c745af73c37ec71fdc7a9ccedc2ffab727d9e9094f38b61730456273863eece3bb3b53ad55f92e5fd +33bab1c369c495db1610965bc0b0546a216e8dd00cd0e602a605d40bc8812bbf1ffa67143f896c436b8f7cf0bed308054f1e1ff77f4d0a13c1e831efbd0e2fcfb3eadab9f755f070ba9aeaceb0a5110f2f8b0c1f7b1aa96a7f2d038a1b72e26400819b1f73d925ea4e34d6acaf59d0a461a34ce5d65c9c937a80e844e323a16d 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf b2cc1898c1bbb47ca73741a8e934bf59c20795603b01763da5686008f97f8102c3420e797e74dea6ab0f53f660d1fa66 +08c8b7faaac8e1154042d162dca1df0f66e0001b3c5ecf49b6a4334ce4e8a754a1a8e4daf8ec09cf1e521c96547aed5172ef852e82c03cddd851a9f992183ac5199594f288dbcc53a9bb6128561ff3236a7b4b0dce8eaf7d45e64e782955ee1b690ce6a73ece47dc4409b690de6b7928cbe60c42fc6a5ddf1d729faf1cc3885e 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570 88ad0d8737c36ff609cd4c6edd301f1af34649a3d9783d2fc3b590c1d90d8e470814411cc79f7b8ad2dd4d39a30fb580 +ba74eed74282811631bd2069e862381e4e2a1e4e9a357b1c159a9ce69786f864b60fe90eeb32d8b72b099986fc594965a33285f7185b415df58fead7b8b50fc60d073680881d7435609ad1d22fd21e789b6730e232b0d2e888889fb82d6ad0337ab909308676164d4f47df44b21190eca8ba0f94995e60ad9bb02938461eee61 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6 96173a156b51ab22b76375e261b0bd39fef5e60083ce2013267a9440b52f474271aa4f87dbbe6be5f2eecc4ff5efd8ea +dc71f171a28bdc30968c39f08f999b88dc04c550e261ecf1124d67f05edeae7e87fe9b8135a96fe2bc3996a4f47213d9d191184a76bd6310e1ee5cb67ea7fc3ef6f641a0ba165198040fa668192b75a4754fc02c224bd4a74aade5a8c814adf151c2bfeda65165a04ef359e39847c84e312afb66d4cd1db50d41ef3fe5f31296 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7 8e21acf07d56352c3f415eb0c00b3cca04963767338d959fc707cd2e11057c7cce3b425538e78cee41dd368b3a3eac33 +b895788d7828aaeace4f6b61a072ffa344d8ea324962ba6dab5efda93f65bf64a0f2ac6d5721d03ee70e2aef21cdba69fd29040199160e3a293b772ffb961ed694a8dc82800dab79367a4809a864e4aff6bc837aaa868e952b771b76591c0bb82249034e3208e593d85973d3fea753a95b16e221b2561644535c0131fe834ae7 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e 87cd54f540fc3f4c3fa5a816aa4540bd045eb30172c565d08cbef1799015e1ccafdd96c682407d0917b3c277f7ac5885 +2c5bd848c476e34b427cfe5676692e588e1957957db7b5704492bd02104a38216535607f5d092dc40020130c04a3aaf0f1c52409834926d69a05d3f3188187a71d402a10ba34eac8629b4c6359b1095f30f710219298bf06b9f19bfc299981d7e251ca232a0a85338a7e02464731d1b25d4a1f68baf97064516590644820c998 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938 b246866ebcce974fff8c5f0d7fb21ffc58def6313d45e1040b55ef495fb5370b5854b38bf80cbc32c4d77febfa578a70 +65a0b97048067a0c9040acbb5d7f6e2e6ac462e1e0064a8ce5b5bbf8e57059e25a3ef8c80fc9037ae08f63e63f5bdb9378c322ad9b2daf839fad7a75b1027abb6f70f110247da7e971c7c52914e5a4f7761854432fa16b2a521e7bcaee2c735a87cad20c535bf6d04a87340c229bf9af8647eedca9e2dc0b5aa90f7fea3cdc0a 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662 b27c7621d1933dd152f70c49fac42d6f6b77450b49b5a0f1d7dc861fd8512c8701c0dddb34891bf2c38a60605c620565 +d6e366a87808eea5d39fe77cac4b8c754e865a796062e2ec89f72165cd41fe04c48148068c570e0d29afe9011e7e7a2461f4d9897d8c1fa14b4ff88cab40059d17ab724f4039244e97fcecb07f9ffeec2fb9d6b1896700fe374104a8c44af01a10e93b268d25367bf2bef488b8abcc1ef0e14c3e6e1621b2d58753f21e28b86f 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721 afe16d489cc5c4b3d965bd90fd4c6eb4c019d6a15ec4e2380bf30283819ec32f18346eb6850ac65490a1a7665987b04c +f99e1d272d0f5fb9c4f986e873d070ec638422bc04b47c715595e2cf1a701cdf88bc6c4b20085b357bad12ccba67cac8a5ca07f31ba432f9154ff1fadefd487a83a9c37e49fb70a2f170e58889cab0552e0a3806ccfa2a60d96e346851d84b7de6d1a4b8cf37567dc161a84f13421e3412457d4bc27f6213453c8519a2d7daa2 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e 87d9c45bf5a52de702e75597d48cbe92a64128602c6ff1006ced34069d546b5be41e2c718eb30cf75a4b7585aa67f7eb +91f1ca8ce6681f4e1f117b918ae787a888798a9df3afc9d0e922f51cdd6e7f7e55da996f7e3615f1d41e4292479859a44fa18a5a006662610f1aaa2884f843c2e73d441753e0ead51dffc366250616c706f07128940dd6312ff3eda6f0e2b4e441b3d74c592b97d9cd910f979d7f39767b379e7f36a7519f2a4a251ef5e8aae1 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418 b32f4469e5a48b4d8de2e3fd3a9de9f36b21a8958adc7b1cd543439c8231755fa5a85fd4d577eafd7aaaa539ef98f91a +dbc094402c5b559d53168c6f0c550d827499c6fb2186ae2db15b89b4e6f46220386d6f01bebde91b6ceb3ec7b4696e2cbfd14894dd0b7d656d23396ce920044f9ca514bf115cf98ecaa55b950a9e49365c2f3a05be5020e93db92c37437513044973e792af814d0ffad2c8ecc89ae4b35ccb19318f0b988a7d33ec5a4fe85dfe 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950 a051f2f2158a216089fd48d451c0070c09262862413c97f92393bfd8392b959e65b7500bfbe7900334e1416428e911a5 +114187efd1f6d6c46473fed0c1922987c79be2144439c6f61183caf2045bfb419f8cddc82267d14540624975f27232117729ccfeacccc7ecd5b71473c69d128152931865a60e6a104b67afe5ed443bdbcdc45372f1a85012bbc4614d4c0c534aacd9ab78664dda9b1f1e255878e8ac59e23c56a686f567e4b15c66f0e7c0931e 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b 99f4585893208775addf469457ca46a486608ba8d38c8a39b6ad001593023ec11eaa4241a0e66fae3444ec103443a786 +6744b69fc2420fe00f2352399bd58719e4ecdd6d602e2c80f194d607e58b27a0854745bfd6d504de2eb30b04cee0f44af710dd77e2f816ac3ac5692fad2d1d417893bb0edba2707a4c146a486f8728ca696d35cc52e9c7187c82d4bdb92eb954794e5ad15133f6bfea1f025da32ada710a3014cf11095b3ff69a94d087f17753 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f 968e3c64aede347f4c0cafc8db986b828c5d961922e9439182ea8663f211648581f655f7300ef0ada3b76ff181d0d529 +16001f4dcf9e76aa134b12b867f252735144e523e40fba9b4811b07448a24ef4ccf3e81fe9d7f8097ae1d216a51b6eefc83880885e5b14a5eeee025c4232319c4b8bce26807d1b386ad6a964deb3bdca30ee196cfdd717facfad5c77d9b1d05fdd96875e9675e85029ecbf4f94c524624746b7c42870c14a9a1454acf3354474 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66 917240d680284e5b9cee4eb05e5ac1501da1c43649fe696fd7747f83c694deec484dae3c73bc995903c62b68e83bb377 +a9824a7b810aa16690083a00d422842971baf400c3563baa789c5653fc13416111c0236c67c68e95a13cec0df50324dcc9ae780ce4232607cb57dd9b2c61b382f0fa51fd4e283e2c55ffe272597651659fbd88cd03bfa9652cd54b01a7034c83a602709879e1325c77969bebfd93932ce09a23eae607374602201614ff84b141 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c a32144bf4c01ac37a92685396150d84565b1187a1750db33bc5c7eb3dde501b45d997b6f77346ecf7873f66c28455257 +90d8bbf714fd2120d2144022bf29520842d9fbd2dc8bb734b3e892ba0285c6a342d6e1e37cc11a62083566e45b039cc65506d20a7d8b51d763d25f0d9eaf3d38601af612c5798a8a2c712d968592b6ed689b88bbab95259ad34da26af9dda80f2f8a02960370bdb7e7595c0a4fffb465d7ad0c4665b5ec0e7d50c6a8238c7f53 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0 af3acd42acfddbc68547d09357c76a6506be03742df5b9317717f89946292f8648d92771da8d8e525941d774345d72f7 +09952b1e09995e95bf0022e911c6ab1a463b0a1fdd0eec69117b34af1103c720b57600217de7cd178fef92de5391e550af72a8dcf7badf25b06dd039417f9a7d0f5be88fcd4e9655931d5b605452a667c9d1bae91d3476e7d51cff4108f116a49966fb3a7cff8df1c09734ce5620faf2dccb3dc5d94e7e9ac812da31f6d07a38 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9 83a7f9a1ed258d73caf934203990c0333d007f8e4c9ec2940c9112f9dff3226e6a77ae65ea7388f99e1b76fb58bc00a3 +0bb0f80cff309c65ff7729c59c517d50fc0ed5be405ef70cb910c3f62c328c90853d4473530b654dda6156e149bc2222a8a7f9be665240e2fbe9d03f78a2356af0bacd1edb84c4801adc8293a8a0bd6123d1cf6ba216aca807a7eb4dca76b493eb6e3dbb69d36f0f00f856222f24d9b93ec34c3b261be2fca0451c00571928e5 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d b4e9af1ec7028e3bf212555291aa425e0ad515f6c6ff23f879b2f4a4b83859c00f150a17891503c9c890d86a9ab3e083 +7efacf213382ce30804e78b7256854d759147dba9729c51b2759465715bf2c421034c23dc651c13d6cce95f71fe6a84dfbee5768163ac5789ac0474c5ddf4115684683c5f7c204b33b8bcc0c03ac58f66cef2f53b721fe2fac91ad841126101a88f512a7c2ded38549d9f050d4b7961dda48a1489f026c5d111701762418cfe3 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490 b8ff510839871f22187382e47c7a5bdbdf72db4b6487f400b48fcfafc9d5039873796ffa9fef2571c0db2626bc1f8f10 +28edff8b9d85f5f58499cc11f492abdfab25e8945975bbaeee910afa2b8fc1295ec61406309ce4e09f4ab4f462959fc2a2786802466eb26d3b01be6919893ae75d0fdc2dc8a82e662550f9fce9627dd364188aaba5c6faa1b2d8a2235adfa5ad0dc140f88a2b2f103f5690e877d07fe8fd30d02d2b2729bd3d8eb5b23a21f54c 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1 a87950714802f5fcdaf35219630fdbfff3b51f68c4662ec6a3659cbed9f2f79f9adf3bef131519b070fcb6393095ee09 +bae2a8897c742fd99fbf813351cd009d3f2e18d825ca22e115276484bce8f82f8c7c0c21dd2af208404d8ef45bb5a6c41693912b630897d5246801bf0775aa9bbac8be98cb861d172c3563dc59e78a58ed13c66dea496471b3ad0eeae8995293e4ab97373edc1837ffc95ff1cc0c1e90e64ea8680b2ca5f1e09bf86b99b343b6 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745 b2e10f2e256dea1cfffbcb67bf0ffd2b7c43af993042302a3d7121988f418f822ac2bc54cc6080cb67cc35f3ba1ee4b7 +d57a26a9593e72bfc87322524639bcaae5f2252d18b99cdaa03b14445b0b8a4dd53928f66a2e4f202fb25b19cad0eb2f1bfda2ab9b0eb668cdcd0fe72f5d9ef2e45e0218590f7ab9d2c9342202610c698bc786cce108a7d4a6730a13e9ea1b470e781f1237d3f84f44abde808516975546bd89075ef9a9732bfd7ee33b6f4399 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f 8e7580a9d6583494f3bb79d4935ead6db5c6093f3b649682f9a3079c1b6ae6c0bff500a1be89653f81377c88400e8b00 +8fdcf5084b12cfc043dd3416b46274e021bbed95d341d3c500c102a5609d3a34de29f8fa9f0adb611a1f47a97ad981f8129d718fc0d6c709eab1a3490db8d550f34eb905b9e00663543afc5bc155e368e0bc919a8b8c9fa42093603537a5614927efa6be819ed42ececbf1a80a61e6e0a7f9b5bc43b9238e62d5df0571fea152 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e a330711f3af0130947096600b2182ee01e99bd30ee38d371bc8e04d965e8f8cc86ed968602976126936b6c9cd068d152 +00669f433934992257bed55861df679804107d7fa491672574a7624949c60049b0533383c88d6896c8de860704c3e6a6aefce83efa57c4d57e9ab253da5d15e1f53ab6dce218b592772ab0bc01fee8e63368e85c0639301456fe2d44cd5396a7f2b22761cd03b80eba7883eede8249a2f5db2183bf00550c5c002f45a5e4fb31 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89 842341346ebf28e73d0f27e2fda20f1e3d970e34f72bf9726d20540c97878ebf31b4a75affe52a829f723af4cf6944f3 +4be81dcfab39a64d6f00c0d7fff94dabdf3473dc49f0e12900df328d6584b854fbaebaf3194c433e9e21743342e2dd056b445c8aa7d30a38504b366a8fa889dc8ecec35b3130070787e7bf0f22fab5bea54a07d3a75368605397ba74dbf2923ef20c37a0d9c64caebcc93157456b57b98d4becb13fecb7cc7f3740a6057af287 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a 959462c10ecf84ac38d0f16a24663ec9a550da6ea3d87872acc977c82c28f1bb6af0e52d7749996d5cceec1006ebfed6 +9ecd500c60e701404922e58ab20cc002651fdee7cbc9336adda33e4c1088fab1964ecb7904dc6856865d6c8e15041ccf2d5ac302e99d346ff2f686531d25521678d4fd3f76bbf2c893d246cb4d7693792fe18172108146853103a51f824acc621cb7311d2463c3361ea707254f2b052bc22cb8012873dcbb95bf1a5cc53ab89f 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926 a3b4b110fe53c9c7bbfd5f639b97a72da52c30251352dbaf075b37c5a2b797929e774752d7903ebfc71dd661fb35358b +b3c63e5f5a21c4bfe3dbc644354d9a949186d6a9e1dd873828782aa6a0f1df2f64114a430b1c13fe8a2e09099e1ed05ef70de698161039ded73bcb50b312673bb073f8a792ac140a78a8b7f3586dffb1fc8be4f54516d57418ccc9945025ce3acf1eb84f69ceee5e9bd10c18c251dbc481562cd3aae54b54ab618cb1eeda33cf 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6 9919085e1eeb89c7ab8474021d22c537ced13fef22ec6e139f70356b7ab8ccc5c78fbed7b8c03b5cf8b27cd1e360860b +6e0f96d56505ffd2d005d5677dbf926345f0ff0a5da456bbcbcfdc2d33c8d878b0bc8511401c73168d161c23a88b04d7a9629a7a6fbcff241071b0d212248fcc2c94fa5c086909adb8f4b9772b4293b4acf5215ea2fc72f8cec57b5a13792d7859b6d40348fc3ba3f5e7062a19075a9edb713ddcd391aefc90f46bbd81e2557b 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f aa4ab6dd380566f07c167be15fa7d36d9ef75a710edb6cbbdbb0e52c24f73567061496b42959404fd28aad0e28e99d09 +3f12ab17af3c3680aad22196337cedb0a9dba22387a7c555b46e84176a6f8418004552386ada4deec59fdabb0d25e1c6668a96f100b352f8dabd24b2262bd2a3d0f825602d54150bdc4bcbd5b8e0ca52bc8d2c70ff2af9b03e20730d6bd9ec1d091a3e5c877259bcff4fd2c17a12bfc4b08117ec39fe4762be128d0883a37e9d 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742 b56bb0361c1a20fa5535b4262c3174368b628ff3c717a3b776786392c0425dc63d49d2f05805d2f0f326dfb42b7e237a +a1eed24b3b7c33296c2491d6ee092ec6124f85cf566bb5bc35bffb5c734e34547242e57593e962fb76aee9e800eed2d702cc301499060b76406b347f3d1c86456978950737703c8159001e6778f69c734a56e5ce5938bd0e0de0877d55adeee48b0d8dfa4ac65fd2d3ce3e12878bac5c7014f9284d161b2a3e7d5c88569a45f6 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697 81a1f0968ec1aa98f1d84bd3975d33d31652f325aac03000433b2b1da38cdd49312c86ad232520cb91eb01710a2ee548 +9aace26837695e6596007a54e4bccdd5ffb16dc6844140e2eeeb584b15acb2bbffd203c74440b6ee8db676fd200b4186a8c3e957c19e74d4d865ada83f80655323dfa3570907ed3ce853b6e8cc375ed2d758a2f5ad265dd3b47650517a49b3d02df9e0c60c21576378c2b3a08481eec129b2a75608e13e6420127a3a63c8a3f1 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04 a9bdf06632ef1fcacb0331e2a6115b723c918b8e2df87f25f5077325590d7d448536d3ae0fffb6de61226ba76bd315fe +ac2175940545d4fbab6e2e651c6830aba562e0c11c919e797c43eff9f187a68a9e5a128e3e2a330b955a3f4577d3f826529ad1b03d7b60f7ad678f005053b41dc0f8d267f3685c6abe1a0e9a733c44b2f3ca48b90806f935141c842e3a6c06a58f5343d75e3585971a734f4ae1074ce5b54f74bd9342f4bbca738d260393f43e 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6 8f4ad4a7380f64b847e6ba70df9d0713e856ce26941cb8d537a8e0aaf33b26bc05a89140940c72efd83808991d2f0735 +6266f09710e2434cb3da3b15396556765db2ddcd221dce257eab7399c7c490135925112932716af1434053b8b9fe340563e57a0b9776f9ac92cbb5fba18b05c0a2fafbed7240b3f93cd1780c980ff5fe92610e36c0177cabe82367c84cee9020cf26c1d74ae3eb9b9b512cb8b3cb3d81b17cf20dc76591b2b394ef1c62ac12ee 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e a07f0d17a7d50740372d131fa952822a578bbb120be6ac70d741c0a52d788e0ae1324ccd26049a47c7aaf6c6595c90f7 +3de9e617a6868dca1a1432d503f923535da3f9b34426b2a4822174399c73b1c1ee67311410a58c17202ac767844b2024d8aa21a205707d93865693ac25a24fc87034fa3a7a7e27c3344cb03b87602c15180a5fe6a9dd90cd11af4a0f150207bf2d83f55b12c088adae99aa8cfa659311b3a25beb99056643760d6a282126b9b2 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5 a58615bfe47f5593367863995f2dc70f866aab5bbbecd9b3b46027adbe9f38ced2563918886572f9e22abdeaa6112dfb +aa48851af7ef17abe233163b7185130f4646203c205e22bcc2a5a3697bcab998c73a9ffe1d3ea0b7978ce7df937a72586eb5ca60b0d939a7d1c115c820171c89c8116b7e2c7b98cf0f14e4c4df3cb2f319ad3ab0ea25ff14526ddc037469f000bf82100acd4cdf94feb4eba4ea1726f0569336604a473aee67d71afebb569209 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a b408c74c5524db5df85772d92bf066526894fed81766209bf96b7289305aaf8c021014230fc822894c9315a7623445e5 +b0d5d52259af364eb2d1a5027e5f7d0afe4b999cc5dd2268cfe76f51d2f17b541bdd7867e23a1bb897705153d9432a24012108979c6a2c9e2567c9531d012f9e4be764419491a52eae2e127430b0ab58cb8e216515a821b3db206447c235bf44ee304201b483b2a88844abaa18bca0147dfff7e502397dd62e15524f67eb2df2 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb 907396d9ebbf2435fa7abb0e013fd846d47465026dda0c358fc354682bc10ab1ea9d08bdd6cbc5430e42c158321f9ae0 +9599788344976779383a7a0812a096943a1f771ee484d586af1a06207478e4c0be9c200d42460fe837e24b266c8852d80d3c53cc52ffb1913fc3261145fc6da575611efd16c026059a2e64f802517ffd1b6b34de10ad2909c65c2155e8d939b8115400c1d793d23955b15f5d1c13c962ff92b4a815cee0e10f8e14e1f6e6cd38 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77 a8c6080be4bc88220e9858cd96b752b4a2e52ac92375bcda7173594b2369c1a49fb0f0da4436343e96e5d3b967c9a1f5 +fdde51acfd04eb0ad892ce9d6c0f90eb91ce765cbe3ce9d3f2defe8f691324d26b968b8b90e77706b068585f2a3ee7bf3e910528f7403c5af745a6f9d7ba6c53abd885c3b1be583415b128f4d3f224daf8563476bd9aa61e9c8518c144335f8f879c03696bddbe3ac37a8fbede29861611feaa87e325e2f60278b4893ed57fb0 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c a5e46c0f8a9995ea00eab07740325dfecfab27241205a0f13b58d452d83c8e17820e465ffe3b79dd8a9c247e1c9efdd8 +beb34c997f905c77451ac392f7957a0ab8b23325bd5c63ca31c109ac8f655a1e3094240cb8a99284f8091de2ab9a7db2504d16251980b86be89ec3a3f41162698bab51848880633e0b71a38f8896335853d8e836a2454ecab2acdcc052c8f659be1d703b13ae1b090334ac50ab0137ddb5e8b924c0e3d2e5789daaef2fdd4a1e 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63 a297bb296d6b83647b6b701fa962222ac031b7c7c29554db4f6bc19fb9704a1b7ea3ed3af32abaa028fa57ac9391dcf2 +543c374af90c34f50ee195006d5f9d8dd986d09ad182fcbefa085567275eee1e742bfe0af3d058675adeb5b9f87f248b00a9fbd2aa779129123a5b983f2f26fc3caf2ea34277550c22fe8c814c739b46972d50232993cddd63a3c99e20f5c5067d9b57e2d5db94317a5a16b5c12b5c4cafbc79cbc2f9940f074bbc7d0dc71e90 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da a44bc817307cc73ab759d0d54b5c1b82655e53f6af1e9782ddb15da49c498cf5ec29400e7fefa17ce78b95e85e2eecd5 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P521_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P521_blst new file mode 100644 index 000000000000..de78d6d28aa7 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_fips_186_3_P521_blst @@ -0,0 +1,60 @@ +58ec2b2ceb80207ff51b17688bd5850f9388ce0b4a4f7316f5af6f52cfc4dde4192b6dbd97b56f93d1e4073517ac6c6140429b5484e266d07127e28b8e613ddf65888cbd5242b2f0eee4d5754eb11f25dfa5c3f87c790de371856c882731a157083a00d8eae29a57884dbbfcd98922c12cf5d73066daabe3bf3f42cfbdb9d853 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46 9780d1902f1988c23540114573611ed67c15bf95b1672c582d69088ad26c9bd3394c6dd63168f1d1eccef11b84e345df +2449a53e0581f1b56d1e463b1c1686d33b3491efe1f3cc0443ba05d65694597cc7a2595bda9cae939166eb03cec624a788c9bbab69a39fb6554649131a56b26295683d8ac1aea969040413df405325425146c1e3a138d2f4f772ae2ed917cc36465acd66150058622440d7e77b3ad621e1c43a3f277da88d850d608079d9b911 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73 8e500ac83bb4ea6f4df796e298f863bd162724b559ddbd83469145ebf0d4121dbdd559865dbc1146556ed804fdef7ffb +7ba05797b5b67e1adfafb7fae20c0c0abe1543c94cee92d5021e1abc57720a6107999c70eacf3d4a79702cd4e6885fa1b7155398ac729d1ed6b45e51fe114c46caf444b20b406ad9cde6b9b2687aa645b46b51ab790b67047219e7290df1a797f35949aaf912a0a8556bb21018e7f70427c0fc018e461755378b981d0d9df3a9 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace b4cf89f57640327aab1a3a75e2d54eb538b7e7b06e14961f86b96d681b9e1f262a1c0fb306fd67edc695b0b0ea35e021 +716dabdb22a1c854ec60420249905a1d7ca68dd573efaff7542e76f0eae54a1828db69a39a1206cd05e10e681f24881b131e042ed9e19f5995c253840e937b809dfb8027fed71d541860f318691c13a2eb514daa5889410f256305f3b5b47cc16f7a7dad6359589b5f4568de4c4aae2357a8ea5e0ebaa5b89063eb3aa44eb952 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc a3f98a9e9b369190bd5471821bf5e69dc0e491b2efbfcc42308e249d54ddd5a0a068f0c26bd907cce270ff9cc8288628 +9cc9c2f131fe3ac7ea91ae6d832c7788cbbf34f68e839269c336ceef7bef6f20c0a62ea8cc340a333a3002145d07eba4cf4026a0c4b26b0217a0046701de92d573d7c87a386a1ea68dc80525b7dcc9be41b451ad9f3d16819e2a0a0b5a0c56736da3709e64761f97cae2399de2a4022dc4c3d73c7a1735c36dbde86c4bc5b6f7 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549 b6225224c4651c112cefbca5152d75865a6999c4e476482d59e3b04be630004fbbf8297a3d2ac8e2d6e0f0d9ed57b302 +14c69f8d660f7a6b37b13a6d9788eff16311b67598ab8368039ea1d9146e54f55a83b3d13d7ac9652135933c68fafd993a582253be0deea282d86046c2fb6fd3a7b2c80874ced28d8bed791bd4134c796bb7baf195bdd0dc6fa03fdb7f98755ca063fb1349e56fd0375cf94774df4203b34495404ebb86f1c7875b85174c574c 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4 99fa10ce812d4083b198b1b8a9f94fd56b28a3952bfe0783675b7010158bd9fd047c12ffac16a33737a0f107fe1d47d2 +8d8e75df200c177dbfe61be61567b82177ea5ec58e2781168d2277d2fd42668f01248ca3eb29ffa2689b12ae40f9c429532b6d2e1f15891322b825a0a072a1c68fa09e78cfdef3e95ed6fdf7233a43cb68236560d49a3278f0b3f47cb08f475bd9ab2f60755ea4a1767de9313b71a1b9ea87ef33f34682efbda263b0f8cc2f52 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16 b477bf2579ad066cd8ce18d66c19d86905f7976e4ff2025de91773a3e842fd2bf9439c37f0c0225f497aa479e42ddb5c +10631c3d438870f311c905e569a58e56d20a2a560e857f0f9bac2bb7233ec40c79de145294da0937e6b5e5c34fff4e6270823e5c8553c07d4adf25f614845b2eac731c5773ebbd716ab45698d156d043859945de57473389954d223522fbafecf560b07ef9ba861bcc1df9a7a89cdd6debf4cd9bf2cf28c193393569ccbd0398 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37 ad6dc8f9848361984519acf8999b17df02959a17bbcd883d2c6133ab388d31b6aeedbf7d46a6113abc4db75cdb5e28b6 +80aad6d696cbe654faa0d0a24d2f50d46e4f00a1b488ea1a98ed06c44d1d0c568beb4ab3674fc2b1d2d3da1053f28940e89ba1244899e8515cabdd66e99a77df31e90d93e37a8a240e803a998209988fc829e239150da058a300489e33bf3dcdaf7d06069e74569fee77f4e3875d0a713ccd2b7e9d7be62b34b6e375e84209ef 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256 883a101b3ea008b5c12d6ccdd75f6cbe1fa7bbd6499328d84d04735a11e9946ac9fcd890a856a505a31b6b7dbec18a27 +8a7792a2870d2dd341cd9c4a2a9ec2da753dcb0f692b70b64cef2e22071389c70b3b188dea5f409fb435cbd09082f59de6bc2ff9e65f91b7acc51e6e7f8e513148cb3c7c4664f227d5c704626b0fda447aa87b9d47cd99789b88628eb642ed250312de5ba6b25f3d5342a3cbb7ebd69b0044ee2b4c9ba5e3f5195afb6bea823d 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7 915c4cafe1f5ffdb511167f44e17e471e0e5f58c9063945c483186ace79e1d3e28c541406f96fdbb2bcb4b639a52a032 +f971bcd396efb8392207b5ca72ac62649b47732fba8feaa8e84f7fb36b3edb5d7b5333fbfa39a4f882cb42fe57cd1ace43d06aaad33d0603741a18bc261caa14f29ead389f7c20536d406e9d39c34079812ba26b39baedf5feb1ef1f79990496dd019c87e38c38c486ec1c251da2a8a9a57854b80fcd513285e8dee8c43a9890 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73 939ddcc24a13717aa45ec86254ddad38a03ca150ee5a8c473017c61ac49e4caacae75be109ce7a1f4f8feebc6cf9e3fa +ec0d468447222506b4ead04ea1a17e2aa96eeb3e5f066367975dbaea426104f2111c45e206752896e5fa7594d74ed184493598783cb8079e0e915b638d5c317fa978d9011b44a76b28d752462adf305bde321431f7f34b017c9a35bae8786755a62e746480fa3524d398a6ff5fdc6cec54c07221cce61e46fd0a1af932fa8a33 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c 97a4d9a812763ef3b4de327551f9f3f96dbccaaa5439774ab4f6dded72081213dd926323637e41414da78c94e3bd60f5 +d891da97d2b612fa6483ee7870e0f10fc12a89f9e33d636f587f72e0049f5888782ccde3ea737e2abca41492bac291e20de5b84157a43c5ea900aef761006a4471072ab6ae6d515ffe227695d3ff2341355b8398f72a723ae947f9618237c4b6642a36974860b452c0c6202688bc0814710cbbff4b8e0d1395e8671ae67ada01 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace 94eab36131d35843c89310daf416ee0fefa1fc98161c4b9d7b07a4445d4cb75e592f76f3ffe4c04524bedfc67686afa4 +924e4afc979d1fd1ec8ab17e02b69964a1f025882611d9ba57c772175926944e42c68422d15f9326285538a348f9301e593e02c35a9817b160c05e21003d202473db69df695191be22db05615561951867f8425f88c29ba8997a41a2f96b5cee791307369671543373ea91d5ed9d6a34794d33305db8975b061864e6b0fe775f 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8 b0f3cb5062daeca7d3706ffe9a4a96a141472696eccd310bec14ca97499830c0414811fe7140828b941d40c47b26a105 +c64319c8aa1c1ae676630045ae488aedebca19d753704182c4bf3b306b75db98e9be438234233c2f14e3b97c2f55236950629885ac1e0bd015db0f912913ffb6f1361c4cc25c3cd434583b0f7a5a9e1a549aa523614268037973b65eb59c0c16a19a49bfaa13d507b29d5c7a146cd8da2917665100ac9de2d75fa48cb708ac79 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad 8bcf80cbc8a23e61e91175a240ba0e31cb59176877053b17be45a23d9f99db7afea72ade44b1e26864152d131beea5f8 +8ab8176b16278db54f84328ae0b75ef8f0cd18afdf40c04ad0927ed0f6d9e47470396c8e87cde7a9be2ffbfe6c9658c88b7de4d582111119c433b2e4a504493f0a1166e3a3ea0d7b93358f4a297d63f65a5e752f94e2ee7f49ebcc742fa3eb03a617d00c574245b77a20033854d82964b2949e2247637239ab00baf4d170d97c 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a 95170100fea7a5c3730c662e05ffef2ab8d56ae22976e73f392b915ca5971f7db1cbc64134d12e14ce38020b8f25e11e +c4bc2cec829036469e55acdd277745034e4e3cc4fcd2f50ec8bd89055c19795a1e051ccf9aa178e12f9beab6a016a7257e391faa536eaa5c969396d4e1ade36795a82ebc709d9422de8497e5b68e7292538d4ccdc6dd66d27a3ece6a2844962b77db073df9489c9710585ba03d53fa430dbc6626dc03b61d53fc180b9af5dea6 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c ab4e31fe78721a7129f30707045da55996a31fd47b568910bd7bedc2758a3bb95864d495bda53132dbf5fce8e8dec624 +1c1b641d0511a0625a4b33e7639d7a057e27f3a7f818e67f593286c8a4c827bb1f3e4f399027e57f18a45403a310c785b50e5a03517c72b45ef8c242a57b162debf2e80c1cf6c7b90237aede5f4ab1fcaf8187be3beb524c223cc0ceff24429eb181a5eea364a748c713214880d976c2cd497fd65ab3854ad0d6c2c1913d3a06 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d 8be3c65b7cc277e863b83e103dc9e00bf1ce8018dfbee9f9cc4a208aee362096d082f252d0e5e4203d219a8a6f7087e9 +adb5f069b2b501a3ebb83d4f1808eb07710ac4a7b12532996855a20bcc54b2f76812915f632163c3654ff13d187d007152617cf859200194b59c5e81fc6cc9eb1ceb75d654050f260caa79c265254089270ccd02607fdcf3246119738c496dc3a4bd5d3be15789fc3d29a08d6d921febe2f40aef286d5d4330b07198c7f4588e 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c b6a9ce12b2b2da471f819d8199268dfb7f3b8ea0ff484f2dfbc3308a75fbb633fcdffa8d60297dcb4c420db340fdea45 +f253484d121d1ce8a88def6a3e9e78c47f4025ead6f73285bf90647102645b0c32d4d86742a50b8b7a42d5f6156a6faf588212b7dc72c3ffd13973bdba732b554d8bffc57d04f8167aef21ee941ee6ffb6cce0f49445bd707da8deb35dca650aaf761c3aa66a5ebccddd15aee21293f63061a7f4bfc3787c2cd62c806a1a9985 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25 a4000836861d5d0c1366dbdedb3b1362f5dcb0e3378d882ed853c933e31586954895ca7a36a7402977f6f8b4da595ee6 +33bab1c369c495db1610965bc0b0546a216e8dd00cd0e602a605d40bc8812bbf1ffa67143f896c436b8f7cf0bed308054f1e1ff77f4d0a13c1e831efbd0e2fcfb3eadab9f755f070ba9aeaceb0a5110f2f8b0c1f7b1aa96a7f2d038a1b72e26400819b1f73d925ea4e34d6acaf59d0a461a34ce5d65c9c937a80e844e323a16d 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf a4c77d33890a07938fa80fa74eb8234f0cb38ec502a6ccf11ed6d9b5b0c70b257e0e59e6de5ea62d711b3b9861f0dda9 +08c8b7faaac8e1154042d162dca1df0f66e0001b3c5ecf49b6a4334ce4e8a754a1a8e4daf8ec09cf1e521c96547aed5172ef852e82c03cddd851a9f992183ac5199594f288dbcc53a9bb6128561ff3236a7b4b0dce8eaf7d45e64e782955ee1b690ce6a73ece47dc4409b690de6b7928cbe60c42fc6a5ddf1d729faf1cc3885e 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570 aa159385ec2c3cedebd36819a4a753394a9ff1e8fe993d24c1603b5b9f7af31e867ebf2e88c9104f3f2b9274a6b8f289 +ba74eed74282811631bd2069e862381e4e2a1e4e9a357b1c159a9ce69786f864b60fe90eeb32d8b72b099986fc594965a33285f7185b415df58fead7b8b50fc60d073680881d7435609ad1d22fd21e789b6730e232b0d2e888889fb82d6ad0337ab909308676164d4f47df44b21190eca8ba0f94995e60ad9bb02938461eee61 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6 a62e4eecbf7808c7be8abdb8727ba7599b5f032dfa0591c29063e0cef00c3276022ba5d3c6abaae0a0d61981e5fd771b +dc71f171a28bdc30968c39f08f999b88dc04c550e261ecf1124d67f05edeae7e87fe9b8135a96fe2bc3996a4f47213d9d191184a76bd6310e1ee5cb67ea7fc3ef6f641a0ba165198040fa668192b75a4754fc02c224bd4a74aade5a8c814adf151c2bfeda65165a04ef359e39847c84e312afb66d4cd1db50d41ef3fe5f31296 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7 b300f3006b1de1495072a7906bd0c249f6fed6290d576434751d4e97862a139ee114c37c81ce0ce139e1a73dbfbe7ec8 +b895788d7828aaeace4f6b61a072ffa344d8ea324962ba6dab5efda93f65bf64a0f2ac6d5721d03ee70e2aef21cdba69fd29040199160e3a293b772ffb961ed694a8dc82800dab79367a4809a864e4aff6bc837aaa868e952b771b76591c0bb82249034e3208e593d85973d3fea753a95b16e221b2561644535c0131fe834ae7 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e b897320236069ee611fd9832f5e1a9053bc2c1c1134f1e46cc4666a3b17e2788e25028fa4ad1aae9e3f9b66987f4ddc8 +2c5bd848c476e34b427cfe5676692e588e1957957db7b5704492bd02104a38216535607f5d092dc40020130c04a3aaf0f1c52409834926d69a05d3f3188187a71d402a10ba34eac8629b4c6359b1095f30f710219298bf06b9f19bfc299981d7e251ca232a0a85338a7e02464731d1b25d4a1f68baf97064516590644820c998 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938 a5c96e3fc8d5f225f3473d113e1e5f3b3bd6d2005c67f5353f4891577802ec486cb2f92c0bd86ac08a679c9fc148607e +65a0b97048067a0c9040acbb5d7f6e2e6ac462e1e0064a8ce5b5bbf8e57059e25a3ef8c80fc9037ae08f63e63f5bdb9378c322ad9b2daf839fad7a75b1027abb6f70f110247da7e971c7c52914e5a4f7761854432fa16b2a521e7bcaee2c735a87cad20c535bf6d04a87340c229bf9af8647eedca9e2dc0b5aa90f7fea3cdc0a 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662 b5e8d9b7b842a10e8065d682b1c170e266e7a23d36842736caaa42d21da532391e4731b686ca10aa70c7213e97165ca2 +d6e366a87808eea5d39fe77cac4b8c754e865a796062e2ec89f72165cd41fe04c48148068c570e0d29afe9011e7e7a2461f4d9897d8c1fa14b4ff88cab40059d17ab724f4039244e97fcecb07f9ffeec2fb9d6b1896700fe374104a8c44af01a10e93b268d25367bf2bef488b8abcc1ef0e14c3e6e1621b2d58753f21e28b86f 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721 a76cec4cba23241a4af420769fd24edc02f22f887fbd640611ba400599dcfa0af462b8beb733a8190dbb69746e259e38 +f99e1d272d0f5fb9c4f986e873d070ec638422bc04b47c715595e2cf1a701cdf88bc6c4b20085b357bad12ccba67cac8a5ca07f31ba432f9154ff1fadefd487a83a9c37e49fb70a2f170e58889cab0552e0a3806ccfa2a60d96e346851d84b7de6d1a4b8cf37567dc161a84f13421e3412457d4bc27f6213453c8519a2d7daa2 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e ae2cf8bc0ebd4a5adf36ca69db0ea8572fbf51647d85f98d1b30dcfafa33e515c5913eacd037270502f6fda56f5df4c8 +91f1ca8ce6681f4e1f117b918ae787a888798a9df3afc9d0e922f51cdd6e7f7e55da996f7e3615f1d41e4292479859a44fa18a5a006662610f1aaa2884f843c2e73d441753e0ead51dffc366250616c706f07128940dd6312ff3eda6f0e2b4e441b3d74c592b97d9cd910f979d7f39767b379e7f36a7519f2a4a251ef5e8aae1 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418 acdae46f2b9e2cd55d01797bb87d9cd6ec36f479978ed2e6f1923c6fbf4043750d74b1ba181645846337ddd93b46c2b8 +dbc094402c5b559d53168c6f0c550d827499c6fb2186ae2db15b89b4e6f46220386d6f01bebde91b6ceb3ec7b4696e2cbfd14894dd0b7d656d23396ce920044f9ca514bf115cf98ecaa55b950a9e49365c2f3a05be5020e93db92c37437513044973e792af814d0ffad2c8ecc89ae4b35ccb19318f0b988a7d33ec5a4fe85dfe 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950 8938e4fe778cf3d37329d0bf640eed44cd14f20d74ccfb924d3cf1e49b6bef36504262a5cd36a4711f332005c6d00ff3 +114187efd1f6d6c46473fed0c1922987c79be2144439c6f61183caf2045bfb419f8cddc82267d14540624975f27232117729ccfeacccc7ecd5b71473c69d128152931865a60e6a104b67afe5ed443bdbcdc45372f1a85012bbc4614d4c0c534aacd9ab78664dda9b1f1e255878e8ac59e23c56a686f567e4b15c66f0e7c0931e 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b a881ca6b42494da94b10734d8c78bfc1bebe12f398c66aeedfb0317b5dfb5d20bcc6fd2b9a9f4d7127d27025a29452c8 +6744b69fc2420fe00f2352399bd58719e4ecdd6d602e2c80f194d607e58b27a0854745bfd6d504de2eb30b04cee0f44af710dd77e2f816ac3ac5692fad2d1d417893bb0edba2707a4c146a486f8728ca696d35cc52e9c7187c82d4bdb92eb954794e5ad15133f6bfea1f025da32ada710a3014cf11095b3ff69a94d087f17753 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f 92bfaf93c1e600678999bf70c4ecb0be22f5a30c69a5d7f35c5d8303f4625f4cc351ff97359a07d13f63ff7ac7d68b70 +16001f4dcf9e76aa134b12b867f252735144e523e40fba9b4811b07448a24ef4ccf3e81fe9d7f8097ae1d216a51b6eefc83880885e5b14a5eeee025c4232319c4b8bce26807d1b386ad6a964deb3bdca30ee196cfdd717facfad5c77d9b1d05fdd96875e9675e85029ecbf4f94c524624746b7c42870c14a9a1454acf3354474 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66 8d889d573258db60ef97b25cd10ba2130c8c797b6623a966b031fc5e651b4a6c1be60248bb089928336490891dd11870 +a9824a7b810aa16690083a00d422842971baf400c3563baa789c5653fc13416111c0236c67c68e95a13cec0df50324dcc9ae780ce4232607cb57dd9b2c61b382f0fa51fd4e283e2c55ffe272597651659fbd88cd03bfa9652cd54b01a7034c83a602709879e1325c77969bebfd93932ce09a23eae607374602201614ff84b141 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c 8d5eb6a9387b69b827bdf8b77d547da31d4f047d1480a5c6bf013cd9d274389a29d118e7c609a9cd283c39763cd72889 +90d8bbf714fd2120d2144022bf29520842d9fbd2dc8bb734b3e892ba0285c6a342d6e1e37cc11a62083566e45b039cc65506d20a7d8b51d763d25f0d9eaf3d38601af612c5798a8a2c712d968592b6ed689b88bbab95259ad34da26af9dda80f2f8a02960370bdb7e7595c0a4fffb465d7ad0c4665b5ec0e7d50c6a8238c7f53 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0 b33b0f10c9b6ebfbd04881be1466bbda6e98de9eb58ffd9490beeeedfa13b218dac17498767f0781c62ed8023a843962 +09952b1e09995e95bf0022e911c6ab1a463b0a1fdd0eec69117b34af1103c720b57600217de7cd178fef92de5391e550af72a8dcf7badf25b06dd039417f9a7d0f5be88fcd4e9655931d5b605452a667c9d1bae91d3476e7d51cff4108f116a49966fb3a7cff8df1c09734ce5620faf2dccb3dc5d94e7e9ac812da31f6d07a38 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9 b32944980393a005dc9388f51a691b538cb168a67d6e51f9a6e933010cad19daaa79bb662ebef5886d60422399a3d76e +0bb0f80cff309c65ff7729c59c517d50fc0ed5be405ef70cb910c3f62c328c90853d4473530b654dda6156e149bc2222a8a7f9be665240e2fbe9d03f78a2356af0bacd1edb84c4801adc8293a8a0bd6123d1cf6ba216aca807a7eb4dca76b493eb6e3dbb69d36f0f00f856222f24d9b93ec34c3b261be2fca0451c00571928e5 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d 817fbce199f02fe0c61c349c4933bf95f5e11a1da99acc8df1cf04c10676de139aa80671942f8e9cdf862d9d7e5992e0 +7efacf213382ce30804e78b7256854d759147dba9729c51b2759465715bf2c421034c23dc651c13d6cce95f71fe6a84dfbee5768163ac5789ac0474c5ddf4115684683c5f7c204b33b8bcc0c03ac58f66cef2f53b721fe2fac91ad841126101a88f512a7c2ded38549d9f050d4b7961dda48a1489f026c5d111701762418cfe3 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490 85940297b2087433f0d341edfa2738076e72130cca970bd301f693058448b99d30707a01da418101918a8902a1fe620d +28edff8b9d85f5f58499cc11f492abdfab25e8945975bbaeee910afa2b8fc1295ec61406309ce4e09f4ab4f462959fc2a2786802466eb26d3b01be6919893ae75d0fdc2dc8a82e662550f9fce9627dd364188aaba5c6faa1b2d8a2235adfa5ad0dc140f88a2b2f103f5690e877d07fe8fd30d02d2b2729bd3d8eb5b23a21f54c 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1 a4bec5a660248ba7fa82162542ce38387cece8eeb32a5223724b9da81728326fcd2f75bafcff95e144018da4db3275d2 +bae2a8897c742fd99fbf813351cd009d3f2e18d825ca22e115276484bce8f82f8c7c0c21dd2af208404d8ef45bb5a6c41693912b630897d5246801bf0775aa9bbac8be98cb861d172c3563dc59e78a58ed13c66dea496471b3ad0eeae8995293e4ab97373edc1837ffc95ff1cc0c1e90e64ea8680b2ca5f1e09bf86b99b343b6 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745 b23011ff5733fc4b5edcc3a2c0aef539fc70d168812440c42feac7f3350dc94fb30054d6795845f28fbfb06b0b839e82 +d57a26a9593e72bfc87322524639bcaae5f2252d18b99cdaa03b14445b0b8a4dd53928f66a2e4f202fb25b19cad0eb2f1bfda2ab9b0eb668cdcd0fe72f5d9ef2e45e0218590f7ab9d2c9342202610c698bc786cce108a7d4a6730a13e9ea1b470e781f1237d3f84f44abde808516975546bd89075ef9a9732bfd7ee33b6f4399 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f 8e79e17a756e062814a93310b5979db49d7fa7c57dda1cb686c211e3119648240563819fc89d217ca82e11dfd383c88c +8fdcf5084b12cfc043dd3416b46274e021bbed95d341d3c500c102a5609d3a34de29f8fa9f0adb611a1f47a97ad981f8129d718fc0d6c709eab1a3490db8d550f34eb905b9e00663543afc5bc155e368e0bc919a8b8c9fa42093603537a5614927efa6be819ed42ececbf1a80a61e6e0a7f9b5bc43b9238e62d5df0571fea152 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e b52705af366c598add2bd428be111a290db9940640262637b7fbc74599c0d0052dc0e7ad1f7e261b87785ef92374e901 +00669f433934992257bed55861df679804107d7fa491672574a7624949c60049b0533383c88d6896c8de860704c3e6a6aefce83efa57c4d57e9ab253da5d15e1f53ab6dce218b592772ab0bc01fee8e63368e85c0639301456fe2d44cd5396a7f2b22761cd03b80eba7883eede8249a2f5db2183bf00550c5c002f45a5e4fb31 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89 865866c828b0073da02e12e3ff0b9734b77b4eccf78a209433f42b5873b308e80e3fbaff4529f00cdde5e165941b4819 +4be81dcfab39a64d6f00c0d7fff94dabdf3473dc49f0e12900df328d6584b854fbaebaf3194c433e9e21743342e2dd056b445c8aa7d30a38504b366a8fa889dc8ecec35b3130070787e7bf0f22fab5bea54a07d3a75368605397ba74dbf2923ef20c37a0d9c64caebcc93157456b57b98d4becb13fecb7cc7f3740a6057af287 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a 85aa5fd829079830d50a88f8b1e08f850092add5006c0ab673044904c8a94a7d4f870227cc9421fdee2e8ee2e1c4e881 +9ecd500c60e701404922e58ab20cc002651fdee7cbc9336adda33e4c1088fab1964ecb7904dc6856865d6c8e15041ccf2d5ac302e99d346ff2f686531d25521678d4fd3f76bbf2c893d246cb4d7693792fe18172108146853103a51f824acc621cb7311d2463c3361ea707254f2b052bc22cb8012873dcbb95bf1a5cc53ab89f 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926 86f5e3aa3c43db9f542dbf391dcb13af6d49d5115ac8bb8a4e5578d38d9912e39cfa82c52d79f779a9452735149d7c2b +b3c63e5f5a21c4bfe3dbc644354d9a949186d6a9e1dd873828782aa6a0f1df2f64114a430b1c13fe8a2e09099e1ed05ef70de698161039ded73bcb50b312673bb073f8a792ac140a78a8b7f3586dffb1fc8be4f54516d57418ccc9945025ce3acf1eb84f69ceee5e9bd10c18c251dbc481562cd3aae54b54ab618cb1eeda33cf 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6 ac52b1fe23d5734a3d3a99b9fa4843793d4e38e8e9a02a378c0cdb203aa4f180b4af34361f32ab5bc5888413f090c8b5 +6e0f96d56505ffd2d005d5677dbf926345f0ff0a5da456bbcbcfdc2d33c8d878b0bc8511401c73168d161c23a88b04d7a9629a7a6fbcff241071b0d212248fcc2c94fa5c086909adb8f4b9772b4293b4acf5215ea2fc72f8cec57b5a13792d7859b6d40348fc3ba3f5e7062a19075a9edb713ddcd391aefc90f46bbd81e2557b 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f 92cbc62b6aba9fe36e51aad09a0821210ad25c84d696062bb3b5f4462ab627460d745db4e515730d614fdd59a093693b +3f12ab17af3c3680aad22196337cedb0a9dba22387a7c555b46e84176a6f8418004552386ada4deec59fdabb0d25e1c6668a96f100b352f8dabd24b2262bd2a3d0f825602d54150bdc4bcbd5b8e0ca52bc8d2c70ff2af9b03e20730d6bd9ec1d091a3e5c877259bcff4fd2c17a12bfc4b08117ec39fe4762be128d0883a37e9d 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742 97ad93aead04e60353d5153c0edecff2f400fa47c42a8094c9d135e5d161f81c9173aa58bbe94097051f27ba8e05e461 +a1eed24b3b7c33296c2491d6ee092ec6124f85cf566bb5bc35bffb5c734e34547242e57593e962fb76aee9e800eed2d702cc301499060b76406b347f3d1c86456978950737703c8159001e6778f69c734a56e5ce5938bd0e0de0877d55adeee48b0d8dfa4ac65fd2d3ce3e12878bac5c7014f9284d161b2a3e7d5c88569a45f6 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697 923c7552cbfa5aebd7924ea3622b3ffa20a240433e83b4bf83aad1ee01d46d7203cf344e35408ed24239174878ca92e3 +9aace26837695e6596007a54e4bccdd5ffb16dc6844140e2eeeb584b15acb2bbffd203c74440b6ee8db676fd200b4186a8c3e957c19e74d4d865ada83f80655323dfa3570907ed3ce853b6e8cc375ed2d758a2f5ad265dd3b47650517a49b3d02df9e0c60c21576378c2b3a08481eec129b2a75608e13e6420127a3a63c8a3f1 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04 abb15c509f5324d15a2567bae3e366950fb2824388873f490d0d36919054ff5de63fcb7b02abbd0080bf5d6359577d32 +ac2175940545d4fbab6e2e651c6830aba562e0c11c919e797c43eff9f187a68a9e5a128e3e2a330b955a3f4577d3f826529ad1b03d7b60f7ad678f005053b41dc0f8d267f3685c6abe1a0e9a733c44b2f3ca48b90806f935141c842e3a6c06a58f5343d75e3585971a734f4ae1074ce5b54f74bd9342f4bbca738d260393f43e 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6 a73c807ac9b58cd50dfc1d986bb82719841268f373192284bcb18c9a58d0482c281c02da7833101ea4ea9a1d1489e1dd +6266f09710e2434cb3da3b15396556765db2ddcd221dce257eab7399c7c490135925112932716af1434053b8b9fe340563e57a0b9776f9ac92cbb5fba18b05c0a2fafbed7240b3f93cd1780c980ff5fe92610e36c0177cabe82367c84cee9020cf26c1d74ae3eb9b9b512cb8b3cb3d81b17cf20dc76591b2b394ef1c62ac12ee 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e 958ded8a169c12ba67361aa9e63f59b366c7443bdaac808302e9841cbe5eb3fc8be36fa570c02e0b2a2054abe2488be4 +3de9e617a6868dca1a1432d503f923535da3f9b34426b2a4822174399c73b1c1ee67311410a58c17202ac767844b2024d8aa21a205707d93865693ac25a24fc87034fa3a7a7e27c3344cb03b87602c15180a5fe6a9dd90cd11af4a0f150207bf2d83f55b12c088adae99aa8cfa659311b3a25beb99056643760d6a282126b9b2 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5 993ddbc1a378aef327798fb938f7c9203ffe4f827a02dce71faf8ca7b802e8c29927f64c7b03ac4a3de183cc8b73f619 +aa48851af7ef17abe233163b7185130f4646203c205e22bcc2a5a3697bcab998c73a9ffe1d3ea0b7978ce7df937a72586eb5ca60b0d939a7d1c115c820171c89c8116b7e2c7b98cf0f14e4c4df3cb2f319ad3ab0ea25ff14526ddc037469f000bf82100acd4cdf94feb4eba4ea1726f0569336604a473aee67d71afebb569209 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a a121a075e51f3e1833157a9bb11e9ad6527e85dbbe02f6dfdeaffd509c6e786ee6a3e1d14152d5ed7c7c0dd43c30e63e +b0d5d52259af364eb2d1a5027e5f7d0afe4b999cc5dd2268cfe76f51d2f17b541bdd7867e23a1bb897705153d9432a24012108979c6a2c9e2567c9531d012f9e4be764419491a52eae2e127430b0ab58cb8e216515a821b3db206447c235bf44ee304201b483b2a88844abaa18bca0147dfff7e502397dd62e15524f67eb2df2 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb b2cdef79a1bae6530d278476c299f503bda390123b2864c6ae878283197fe7e7bc6195d10b9a01ebef80410ca629da38 +9599788344976779383a7a0812a096943a1f771ee484d586af1a06207478e4c0be9c200d42460fe837e24b266c8852d80d3c53cc52ffb1913fc3261145fc6da575611efd16c026059a2e64f802517ffd1b6b34de10ad2909c65c2155e8d939b8115400c1d793d23955b15f5d1c13c962ff92b4a815cee0e10f8e14e1f6e6cd38 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77 a289d661e5c39dc432c949e7c42c982ffe45d582bc000e0b8feb7e5bc58915f159cf626802b1050cf2e25b095697b3f9 +fdde51acfd04eb0ad892ce9d6c0f90eb91ce765cbe3ce9d3f2defe8f691324d26b968b8b90e77706b068585f2a3ee7bf3e910528f7403c5af745a6f9d7ba6c53abd885c3b1be583415b128f4d3f224daf8563476bd9aa61e9c8518c144335f8f879c03696bddbe3ac37a8fbede29861611feaa87e325e2f60278b4893ed57fb0 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c ac24f9a390af5dbb7de01b8b74a1f21ecae0b4a1ce0dc149be41f6f32628cce4701b0622dbbfb11232a4034f16dffbe8 +beb34c997f905c77451ac392f7957a0ab8b23325bd5c63ca31c109ac8f655a1e3094240cb8a99284f8091de2ab9a7db2504d16251980b86be89ec3a3f41162698bab51848880633e0b71a38f8896335853d8e836a2454ecab2acdcc052c8f659be1d703b13ae1b090334ac50ab0137ddb5e8b924c0e3d2e5789daaef2fdd4a1e 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63 ae3ef3aa1ebf6b2b72d39d04c9721e8d94f54bda118e3f371445d767d767425e27cc68f76bddb20073ee00153f83e4dc +543c374af90c34f50ee195006d5f9d8dd986d09ad182fcbefa085567275eee1e742bfe0af3d058675adeb5b9f87f248b00a9fbd2aa779129123a5b983f2f26fc3caf2ea34277550c22fe8c814c739b46972d50232993cddd63a3c99e20f5c5067d9b57e2d5db94317a5a16b5c12b5c4cafbc79cbc2f9940f074bbc7d0dc71e90 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da 8ae0dd682f224c5eec4dbebd5a59acf47460cf4379e7f94958a9698d071a4d2cf2ab6994c17dbf4cf9bc0c34ee57c707 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_rfc6979 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_rfc6979 new file mode 100644 index 000000000000..0963bf0fd602 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_rfc6979 @@ -0,0 +1,34 @@ +73616d706c65 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 b3693aa3a87fbdff349aa4c29cc676efb0f356bcd3bdd491dc7a2577d888a92c1ab28d5bb281690b84fdff90d7f83c02 +74657374 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 b792080b46d7e4993b21508546ab70bf4c838e02a6c6583b77be08e3350b7d3ef3f70f181add24d972382da55e58e1cd +73616d706c65 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc acdfd1a0694791def3fd16b424e53c0580f5bb7e6c13c7003d6f185b7772f3e119cd452c80a74dddf8ad882d3f01e8f6 +74657374 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc 800371bf1cc745a180cfc64a4ef89f1dc593d1e07b01f086f35df3081229aa88e73442842f035f149dd951a7ef18013c +73616d706c65 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 86304c4b0a573d2d0a30e493f96c2c03989dcca279b165be27a239b15e92466dbd84c93e65c068aec1fd9a49105c62e2 +74657374 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 8616f5b7c13e5536e6d677467a00c1203d8718a9487a7382b197ca89e84ec2c76381ad80fd2f321e62176fe8a33d70e3 +73616d706c65 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 b3e769088c1fef9d1b3f411464d1d3dfe315045d89ba8dc1ff4ada1f0c547e87bc65f29687ad57ef67fcb0dad2e303db +74657374 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 a7871e224dd69520ef11d3bbe7c3d20b948529a61f7e458a25eaab933519148c5f1a30e46d4490bbbb0eaf09c39a95f4 +73616d706c65 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 afdabef5ad1781ae5b13e0a72b2333497efcb8bd01b409c0e9e082bb7922181a2a2a10ab83c6fbf5a5e7c70662c88db5 +74657374 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 823e8f38d0c16c9822a47c6e38a526292d71120692441a1febfd5739ab3303faa6e1cdadafaf23ff21794561b95c624d +73616d706c65 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 94cf65f44efa8b955eb652cd894081fe741096c97513d746c6d30518c0931f8e7931c3eb2d3851efef1ea8b586d1ebe4 +74657374 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 83eec43576d33bfac5ac77b8fc2a99a79240a00967e9ab6d10df4ec399d7319b84aa6fda350ef37bc68284701d2eb048 +73616d706c65 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 948b032e94bf67d0ad822c4ede8de81244dac799bad116a5818e17a76101fc944318bef70d52b8eaf0f7a572cb1e97f6 +74657374 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 8e0ba60d5d8cd97c6b261ff469546b843bdc5a1670864335af5d9bbd28f8f39f2fc5f18690f6c0d216dc93abcebcb096 +73616d706c65 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 8b39af327294f927660329531e9405a1b2c8c9ce1fb9ebef9d6f00f2cce1f9530064193508f6704355fde79a24e64418 +74657374 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 95b2defedd5ddbbef24774fe1e8e713c65bffab6767756d2fb480bb9cb4d7c6f85c981d0304d19e2540e286917e5cbd5 +73616d706c65 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 b06e6781c3883734725046fd884da7bfa99114496276b8b90ba90b4d58aeefc2b22b76b650d760d28257cc817ed7a651 +74657374 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 b9a605c56b26990b3b87d1fc7b4de1474f554f3f420b4e37be6244474f299cc9c8c2571ce69ac928e44ec7a151bad1ef +73616d706c65 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a a7d0b305fa52dc8ebceb8b80560ada413e8dd489c90d250c797b64d6fe19143aeb8fb4f033066c3d5a944e61bf814d38 +74657374 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a b5ba6b64f1d168a8031e380052ab8c7b0cb56a9b58c6cac4d6c057f4ee9975bee9e3cc22fec8b48b04570dff58eccc4f +73616d706c65 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 b4341a7ea1dc369acb0155c65a21a57f61e86b357a76294b150f728c392f0169f83ef94bbb5c84d61672f4d6f2be489a +74657374 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 90a2e42c6799d85b2971e264d09208df8677969c9914f8a63a54afd65cd253060e87e07d99620fb89448355316ef0968 +73616d706c65 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c adfd136d765603f4b6adf26a4cf68bb844c1c18209b21e4eb12d35aaf520aff25e37573ab14d99747362c082473b2b93 +74657374 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 9699c2b3efebf5e543d7e3666ae622eed6ad9cd9b0f5e95a243302e257568a2659b05705900e2f6c5312e928c70792fd +73616d706c65 035318fc447d48d7e6bc93b48617dddedf26aa658f a3e9533ffa1f8049f49388c4b15bdaa8a6c856f4a095fb1df9f3c772c48b9d82816a444145e2d26608c79c13475b1ebd +74657374 035318fc447d48d7e6bc93b48617dddedf26aa658f 8c458a652e18ec3840ad779afb841ea60f931a15e766c31404e0b871e46a25c18a8dc22caa0ca185916dde694499ba4b +73616d706c65 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 8780a1d1f8d830be5146a0652ce69cbb29ec9a828c4f687ef92fa929e8218d9bf88fad61d8f7ea8034dd9ba8d48dd804 +74657374 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 a0e7114721a287785dadc9b26de5585b1d2437ac5b7564f1eed8d0256964edf07f7a57ee4c1cbfc9169c9703f9c522fe +73616d706c65 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e b03a15575181c4ff79818330ee3edcaf84049336da798a47b0aa0bdd392fbc419959c802572dedd82b8083f65192f7d6 +74657374 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e 8c45c8a7b49945a215f6185c9f8c81c33cd95b925642b43d7f290a3119c96fca6e1a03eeb2d6812f30fbe443d2950eea +73616d706c65 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 930fdedd2eadd33a0b0537ccf67428732774a9880d18dc939a5e09968d49e89d5433574f563f78d7fac16ec01a0e96b3 +74657374 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 b619e58a7c55176aa0088405424c825d8b74b0e8a6412fdb0b17caa85d5c1e0efc139039b6ee8c73003d2d9bc3340e11 +73616d706c65 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 973aa2f4abfe3c3c3052f5154e6e77e56ef655627a3661419180dab0a281e1537c5f07159c57d2772e6decd2d3f52719 +74657374 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 96575fe384eb07b34b5993a8eca6b1e3fd510bc55fd8f8a4e8e54f41fdcff3a811d07e65f0b71c0464cd9895759bda0d diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_rfc6979_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_rfc6979_blst new file mode 100644 index 000000000000..e4fbbe86ae72 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_aug/sig_g1_aug_rfc6979_blst @@ -0,0 +1,34 @@ +73616d706c65 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 b3693aa3a87fbdff349aa4c29cc676efb0f356bcd3bdd491dc7a2577d888a92c1ab28d5bb281690b84fdff90d7f83c02 +74657374 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 b792080b46d7e4993b21508546ab70bf4c838e02a6c6583b77be08e3350b7d3ef3f70f181add24d972382da55e58e1cd +73616d706c65 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc 98e9e0aa976969c575585e62dc04ac91676a9590247565954b88d01e89c3efb3830fbeb7a0d64323524db5509acb0de4 +74657374 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc acfa71bf268a00d748577dba1b71d5dd91165c92a5ef6dab14294f09d493d3a9a28dc00231c9304671b75ed814e06a2d +73616d706c65 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 86304c4b0a573d2d0a30e493f96c2c03989dcca279b165be27a239b15e92466dbd84c93e65c068aec1fd9a49105c62e2 +74657374 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 8616f5b7c13e5536e6d677467a00c1203d8718a9487a7382b197ca89e84ec2c76381ad80fd2f321e62176fe8a33d70e3 +73616d706c65 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 b3e769088c1fef9d1b3f411464d1d3dfe315045d89ba8dc1ff4ada1f0c547e87bc65f29687ad57ef67fcb0dad2e303db +74657374 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 a7871e224dd69520ef11d3bbe7c3d20b948529a61f7e458a25eaab933519148c5f1a30e46d4490bbbb0eaf09c39a95f4 +73616d706c65 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 a0588adfd7f62a93831ac98ad9e829debd76cb52f3b0d216aba560a0125e7897039afdfd2a8c7e3527e5578fc912fc36 +74657374 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 b05ea79433e3f4b570d6ce3f9d0221a6195ed529be1fa6076224a3f794a8d64a9520ec86b343462d09189bb1186ae465 +73616d706c65 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 897ce82fc1677b03bfaa2a8b9734ec234e9fdee401d0bdc4a0a17372b72c22ef62417726b5b822d451f72162b320b663 +74657374 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 8e657d831a169b5d67c28a67de37cb93bb793166412ef9ed2c85eb3dd0b092848d81d9f02462e33739f5e2432230e56d +73616d706c65 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 8fa09fbea5f56fc515ccadd4f5c82df759c8c8e8871135121f29719d6a69758a5d408cab51ebb43776910e0e1edf3587 +74657374 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 95d04574026248e1c968ef9173325f35553346b625f1ca702a80a9a61cf2053ad06929d741c915911b5a7b8f326b9126 +73616d706c65 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 8b39af327294f927660329531e9405a1b2c8c9ce1fb9ebef9d6f00f2cce1f9530064193508f6704355fde79a24e64418 +74657374 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 95b2defedd5ddbbef24774fe1e8e713c65bffab6767756d2fb480bb9cb4d7c6f85c981d0304d19e2540e286917e5cbd5 +73616d706c65 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 b06e6781c3883734725046fd884da7bfa99114496276b8b90ba90b4d58aeefc2b22b76b650d760d28257cc817ed7a651 +74657374 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 b9a605c56b26990b3b87d1fc7b4de1474f554f3f420b4e37be6244474f299cc9c8c2571ce69ac928e44ec7a151bad1ef +73616d706c65 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 885ed6c122730d0b22cbebd1598307857848485551b619281f27e1130279eade93983da2bbb237fb004aafa7663df2fd +74657374 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a a5e067b2a2bf2b193f5c53c8fcfa29766f4bbdc57d13ec4d0eab5c4821af1cff9d8a156e4c27179a04dc29036b3c6e85 +73616d706c65 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 b1cdfe7ee3db5710d44210ee39aca41eb00ac2ea03ce42b3f521ebefb7f842929470b7dee95dde6192d915421dc31a0f +74657374 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 8ea8655f69ab09bebbf113cda3a7910a63046fe2b741cbe170dc0cf0d4e8464509569df48f1168b7c90169ec4e28994a +73616d706c65 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c a081b68212a7980b251b4038e6e79d0bf53a121d3768c0ac958bb1da5d712cd46b9a6aa2c05ca795fe1626ada7b6162d +74657374 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c acc76c70a0213ce42c654ec20745ea6272e3645bf81a679d41587dc36222cfc4fe24d5e076d8e0f5742aa9ff6121cae5 +73616d706c65 035318fc447d48d7e6bc93b48617dddedf26aa658f a3e9533ffa1f8049f49388c4b15bdaa8a6c856f4a095fb1df9f3c772c48b9d82816a444145e2d26608c79c13475b1ebd +74657374 035318fc447d48d7e6bc93b48617dddedf26aa658f 8c458a652e18ec3840ad779afb841ea60f931a15e766c31404e0b871e46a25c18a8dc22caa0ca185916dde694499ba4b +73616d706c65 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 8780a1d1f8d830be5146a0652ce69cbb29ec9a828c4f687ef92fa929e8218d9bf88fad61d8f7ea8034dd9ba8d48dd804 +74657374 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 a0e7114721a287785dadc9b26de5585b1d2437ac5b7564f1eed8d0256964edf07f7a57ee4c1cbfc9169c9703f9c522fe +73616d706c65 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e 89d29dc7f2058fa0e50ddbf2f5b18b6b57da9dc8a7eb42e59bde02bef90a4fa7926fd9ed29cd11f2f4cab08b038a2d50 +74657374 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e 932d221f06f6af350bc6b329edbeea4b4e52606678baa75c654a9119eb203d947d86de097e3eae93025da5cb07172991 +73616d706c65 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 a9d23e6acc02fd61266efaaca41c5c2984a2184fc01cb49c37cb249849c5d1142d4d68a484e0ad0abfdec9bbf2e6ebb7 +74657374 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 b008fb089e11c53c15e6b7d85cce7559dbf83e22d7c914036614ff804d3bc95d3afe7df3d2216f5a3e855012a6181776 +73616d706c65 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 8cfcf323a2bac07d663cf8658d25f9de09a7938f9a2a94131fa3424027d2a40958ff0eea97b20c65cdc1ac13c5003493 +74657374 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 b9bb3023a8ce77cce9ac76c39d690aa4f87d01a1f4a1a31865b3962d1a22d8756e72962adfefdb42584947bbefa4252d diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B233 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B233 new file mode 100644 index 000000000000..2440d33c5876 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B233 @@ -0,0 +1,60 @@ +f1b67fde01e60e4bb7904d906e9436a330c5cb5721fd4e0a3c75b83dade868736bb1d21cfb1b5c6407c373e386ee68ec2239b700e763728eb675a153b8ac44cf2a87be85fe8ed6683430cf4b7d718891cbf8d583d0a37cc952cc25fe803a7aa4fda80f05541a2f1f2601cdd0c095f7110f2a84f7d641b8531572269b21cbe77b 0056673197bfeea9bd7a8b820b4ae51a50411bf118a692bb9ed3d304da53 b4f79742bce4e9c82b80b8426e7dfe66f39e84e9d1dac328139d74b16382cd35985d867fdaaad570a837236bcbe45bd1 +1d496d96b533c632ed6a91f6e3653cdffaa5b8cc0008b35e49b2dd52fe261105c2ec7ee71a4ad5d51fdc3d36d688a3b7ccb3b3b0c3a65be17b8d8aa172e3005cfbf37a2d1b1a6e268c090c6f318e7e96f9ec9b9f5a8fbcc7558d89e840f7e76e44bed91c26ca48e6f5cbc253ca2fe8cb81c484cabd24070e488f9c00cd96ad4f 00468f01d483144e514ec257f2e5fdee28a927f2adb19714c1f3524dd0d3 b300408d7fd0d41603bc1849d274f5699762832612c86cc89c86a8039e1c1c62012ba347323667ac97e891b77d01f9bb +723400655027f474446843645757f7e2cd466bf97275067b4bc4c9d79bb3b19b2421835d69db916f24b77c381fa771fc1e7a19d2b4d09411ae55acccc615b16fd24705762b441ab67083a921fd4ae569ce0de69449aa96f5b977ac7dc022fdc8335656853796f54b3fbd118577f98920624eb0a00204f1ef83827245c06646cc 0074052d027f05465a8083a59cdbf32600224e1f563f653b34314651517f 889acf309d66236c7b01915ef72b05b3c67513642fe0ade1f985ab2bb787dde1ec43825551ddfac9765a6ee9192dceed +155860cb31a142082bcc0bad828d747e916392d21f1873b3a3c1d28ca3ff9d45ddb66a712e3856b6afd07c8d2b2a7badab296a9775b03f6fec0befa2d8d6d00fe3938df244ab46e836a3e686c8b4f918da49f0bb3940bba34a9aa22c7caf02df7758b0de01d9f47af6146344b9be3842d9c055eaf0fb399cd8db95c544a62d8a 001856e7544223f55f80de72a6ef3822fa8fbd68eb397d06e2d76ddd35e0 8f3ab5d829aa5aa6d937de74f4fbb30000790a7624ae849da6394336385abf9a0552cd2402d54fdd7f416c6d6efafc3b +cbd6e305cc9f0dc90caee6e65a74582e9357bd25c78e33a7b14e1ac7e9397ff4466f192fb432143e6df6d61a0ab808ec0a361a6d95a357a38cd3e241fe03ed883ccc364b248ee2a08702110745c2688bdcefa33c1a45b9c8b200e45cddf3e3f66b8d37eff07fbb3366ea1558ef304085613c56707095724b3e134c7a7d3f8dbf 00860aa2b589f2defc617be73e191502e5d9952bf60547fef19eeccbca26 b998e5c7de3599e2669aacf087bf91a85dd9efbf2e0ce1165a260c7e3e9337c01b0ba8f64501cac03cc5fa41857ca738 +812a218ff1ee1472c189f63386e5b8ab341671c3a4dad27a8c6249d1c0f9a29338b471b6179f17a078b6504e804ac55ca3b13e68a623041bc1a092ea2adf3fa1124bbfeb161e6d7c483433f1548763b84da00352a6386e1339f674d45dab13898147ede468e0e01d2c4e0ed66b395a16cc3ded3e952ac739205f35a83376cbce 00d0dec052a00ccebd0c0c5d9a08272f75744a2582cec7ddd924a2b022b2 a222f8db7e609a398fa9f129c3c7bba86eaaa567d91cd0d9fb217dc6ec896a6391308dbc521bf1d3175d2c660f38e5fb +0204b1fca831919e89e108cf140b3770f531a696b1d9a4d1fb68809eb10afccc257cc90cd36717c02b2f3d6d3d1d8a93cc5c48aa7ab9f9fddfe121ce9143376535a0c65e247c6558eac49fd1d6d1bf431ba918c471cb3d536ad485ec51f6471a340ac75f160c4c54cd3ffb9dcc123124b42df1fd2eaa005e3377c5d2d55938c6 008a017d717d6d1213f2b74c53281b07258738c0c7db649ea1ac46b9a3b6 8b5479a9b6c67bea7a1990a0d6effd192d55875d805dd08b12573f664ba94b6e876c7b571a7b3fb65e95a8745578c7b6 +2033eb48756638cb56e2cc39a3e775cfa11fce86cf71f04487dcdbc7f262bc8350a30ced54d1fcb697b28a6e96f88f782947c997872307ed963e1d68985f756435af77f57755cacbb4c6b50ed419deec9f39f0a549a13e54254fa0a5832dba2d943ad4aed8688889a2dd29dcb4ea12abd6a6c50eabcb3981c3a0c1ca5f0b9629 001b56c14442b084cfd22aeef0f8028ec57c8b571c9fc1e43de05c45e47f 904978899433ad767ee8deff496ae975db2b4d10d01dadf6d94b651879192378756a4d8d947e1a83047c87aa60cd0091 +2986ab1cfe8873009e932dc68d4727d77ccbbf378e43fe4aa7c54416346b036b89c0aad1b82977c9fbc39a00f1dc916c0561d8dd70298c02b6cbfe572e0ef2058641e841c6875e8515f3c1082765e046c90c956d984b76e0e8e6eb433ce26c1757ac5b13422479141971c20102e9621d18f51096ae3173c2753facee2862d66e 005afce37c5594586ac46a34ae291f591eacb9880a7de92701977f447fbf 8961d1ea4d6c1de817fe47bd1ef3a0370977bd6e4711d3b809936d27f660006f6846118060461e30711d44bad4566efe +aabf5aa90ceef91c2155f90660adbcb0eedb996f5242cee15468ae217058ebeaad8cd4ff8cdc754a8ab85ba43c59fbab6386686fad5e27ad3848fe52191c7e4b203720841501792a625aef2acb6e36493b792fa55f253effca682946ad8c77e01f44e92ec3c258d0dd98d3183f4dc4a0bd3eca183794abd6232a6f9e4add8f57 000696df05dc7a54a9908a73eb18416a155cc8df4ab26032539d86eae537 80e7ddaf0500492f46046b2cd35aed8646600898db0f52e7ecb2c989dad55d32db5512e15e517b3ad6dbfb9738556eb4 +29ff209eabbde02b10b3fd559671fa53e418750c32c4a18d31cc0186d1077581bbefb8770ed079f536e866414a07431ae6633955bf42a2389b6f8a565d6e4ffb4444336e0030093876a26d4e3106e9ac697788e41f8a21c755eeb86a7c60f18e5e1069f16408a4c375a6a68d42959f2fab7ac09736c7b37c80c05897d8566ce8 005ca31e88c5b2e96e433af2023a66095161710628e7bfa428944d6676b8 812375a9ebbde8148738309cd97dbf01502eeea465b3566d094f4f3875d78e08bfd210b45c33b42a9f2f3a2987cca599 +97765d876c80819f4004a36d09ccba78e600efc71eb7e869d3a00f658d2ace6769c7ab1ef590f41fb070aa8e08615e138df45ffbb6473d4a86ba5fdf17dd6dc9ea9ee19c0332563c99e6a3451c211d286d69102b47bfa6e07d468d9bde82e5c2063fb1ebbbed6086f542cf68ba46d4f214634afb1146dd5a6f3d50912ef5b824 00ef8fe84727a2ad8bf4e646ef28a492adfaf785a3a2ba6e6f985c649a8c a7edfd655b5365d0e0b52dc81bfc74cb75c0c2740eb76d739b68aefd9d4d7c4f1f1ebef108cf39f1e375916d3f487d15 +21cf768d087d1e4eaa8a05e2008020e243116206d675c09be42ef2bc93617ecbb0575c873c6510ede9979215531b62126552738862fc4323d487992754e39d8f0d7e111e165ff254200e05082f59a57ef649bccaef6f980094fad3b7ef93bceb161760e200f0a2e396fbb6b6142dc84d872311bf932b84616b22231747937d58 003edb94b8c62f9af30c14a790c0f5d65e362a21cd8569b9725916d534c0 8007a88920bb999f33396ec90a870b0df1c0066f2e8c973fc3839128fb664e0e1ec03f8a393bb2ad8d7f0649a4cf9594 +7b8e58eecdab3e40212bba6bf284f9379265b3d2baec3e4625aa08d0ced851da193c292ec793dab42732c07b4e94d8b19c83aed796a7e3a6c2b954a7a9a1ff9b2bd4ca62592c8b68f709f1ad38a5c8033ebb3f33d176945bfc68e9ef2b0cee2d45a13ce89d238a33c09ce2c0c63c4233aba5717b85c4c161dd7648a41a5e39d8 000a7519be62562318da1b67d22cf8e720353d22641e0cee11c7a352bb93 a700741edd6ef4eb872794b8f1064cde4abce71ff82db7a6372f19a638f02ac32da4490b7af313d88eb827ef93b323af +f8f268d2b04fe47e5052c8d0d653787384b9654f0bd2138a6f52b80713feeed452b976a90eea4edcfbb62d04f3eafe172ddebd7cdc3701ecd6008e3d82e8eb217b13b5228839f61075159f3bd1e1409c08903874b6dfee2789dd72c208ae769ec8c7d52552a2b1fd73dad24de8b571f88e2184d0ee7d063a121187f97e746f2f 00264022fd7dc2328a6436b522793ad9406d7a586667a0daaf1bce927338 8d9389d3e00cbb5cd917bf952ccc63cd929070ba2ae7b4940d526bb90845706c4567e1657d6053976499c8890b61faea +d288768cbd066fad4bb2500b5683fa9e4eaedfb3dbb519b083f6b802efda0a022355565c5fc6babeccb22f3adbbda450ce5d633193d1431e40c0fe631a295cf85965cd3f5937b31866bd6a5300eaef9941daf54d49832acfceed90e572ef34ccc94eacd0fd6b903fee3c572b963d21e2881656a214d2a4c125778dbe3bbeebca 00da43214e2efb7892cc1ccde6723946d2a8248a6b4d6c8872fad525ec3b ad71cf7cd702b51fd7bfda8c022777e22a0e26ada869c0dac10b036a5cd89fa28696946da361b27d2853ebeba7ceab7a +bf0ab46e0a756c11229b0ea961f8d57218be5b00ab8b0e91d7664cdf5e0341c412c0e992d26ab12115197db39df2d1a6e18ed26a91be461432a2dfc21d98cb16003e339b0b0b1f100e4e6f4824ddac5442f22a1fac26326ed8a89cc91343d7223986d485cc8c64424e84d56be536c57e4dc5faee459b1958efd79e07e90a9811 00aeafa49d776b61f6a30d66ff64bd40dd8d79891dd5293c1b5cd3b46a7c a7420ca25a975ac0c6aafd5a7646a55213038b8aff73f67a5c4ae692f5416fe415e55e4f200f3775fb337eaee7ed9417 +c7b1eeb7c19eb16e7f42b61d79e421b71de797a6cab4e0baee522fee7acdb533f7bbf5855316544e1b82b4f2a18ad0a2311e7622549332122171f32fc62a90e408207e0fb90d1b052821dede9c41b15b6e07d84d5d7b9e31e6396a8ed229fb6232b3051298dc5321aa589f4e289d27169f14c8cc93644916d9b72dbc92c43488 00e95db309f4305b621f51f93588a2678cb19aad0932f365fa0aaa3a3895 aff726668a2a7bbba5200499a6b204ad15f16face0b310c85fe5769668f5ded200c132b44be41d8fe7377c68e86a5b79 +a738eb074e1f277dc665118ca055e6328059ab26da188c16f56384c566e43df8cff3d2a10d2d15c3c1406de8f734b20be5dd1ce937a4289f0ddfd7bddabd03586556eb8233b8feefedaa1f49bdec6d45fd562c2a83fa9fcfc2013bdd77900857199e51fa9c7cbeab925ba8f6c3c5fae46bf8e9c574b302f1e5f9c44400152a78 00d4319cc8e409b8755880827f3200d3f0f1c64d6356fe74eb1f5aa42499 98b65498afe27c9fa11148899156fab9915497e8922cc93cccb8dd4d066cdcdf37d19fa8fe6fe57c6bf5507d1cdb066d +b28103d77e5457c42e026e713ea6ff03722a36512da17197140117442a976f9e2139c54a759fc26af5811b455e5a0d3a95362d9939c1e738045be9237b469ae2106ceed7e7842b44cc0a475d5af6d781e32ff1dd1f4e1833dbc7f82b27dc7e1562d0e29213fd8911105104a7a16f665b926aa137f70d868c90e72f8ee2c95b64 009e556c945052e5954915c773b2d47970c521fcc99139269c3ef46093b7 94d46c6b863972a46641ac78911e31aef42e5013afd42342b7a84943d5d603d564cc53f504a5a2de8f56e951ef7f2d9e +463d04c84521ae671bb35c0a7acb3ae509b1b0470f39b8fe7ae5f3c9fbadbeb2bcc3a87e284cbdff07407a351f7ba743aeac50c4a1fef7375b90eb4af8ea2df040776bbf3e4389e7a80bea40530842642b9895ab9ef5ac8ed6c9ce7917d7b3ebcf80b801da845943313988c1970e7748cc306f914c37414f8247d648b580000f 00becc76f8a77615c4f92ae1f91645bf5bb908e75ef22fd544aae63a3c8e aebe1d9ae5bcfb8b0988cbec1386a9a778e50a4fe6f24faadd59df7b3efea954a73ae5c9e595b69f9a5a799bd04f9df8 +8b2379b5553ae7db6023cb010e26ae91322bc3f94dbaa369481936f90a886e5d3827d995ccf03ca59f46805fbac0337d31a8f117cc7044218a934d5bf507090e7e21178a7162c8fcb39111e6967803dbf9d752f3ae737ba024d0f4f7627e08be58efbe997a164106bfe37f67d2f19c0fcc7a6c7eebd96a72582a9c7bdf881896 0020572c2a3dc3ea430cd8cde9d642081c21658e8bda165550cd9a5d37d9 946c8b5cd9d9f01d96b32fdd7f4f802954255137e9c4c48df96b68b6bfb7a3af364a550c9e566a6b666835fcab976671 +3090bf7373731cc44c00372c1ac59280b0f36e627ccf763fa68a7be37bb0ac8cbd4f70db54fc652566c78ad268f78f015e4bb1e41516fa56ac303a3bb4a52e1fe897d8338db5a6e37cad685e704b994504bd231c7dec0002dbd907a7ebfa809833e32eb23fffdb44fe4a18e11fa19d67356cfd703cf39a75b1a290b8a7c73afb 00769cfbf2dd8248ea1e0ac9b275c9d6ddcf923fe762079b9ed62ccbaa89 a18fcfc2511f07ffb3b2fa0d6afbfc8a6d50785671c8dab83d09d29157e3b02f4f220204b10a21a39ee362957ce806d8 +c37389cbe3f46eeebdda343e354ccd543e96b0c2a87e057aa6b9c4895a403de706d658bbc9066c140e50fef4b56af2db1f42efb70b8021254649983f1e11d04d6b10169d5a1c2093b6ab89227b88a30537c776bb7575749c3ed87bcb29effd8e4f17915b4d5dff6cab9678d88f33abead1e73dbdc5c3307ff3d3b2d5fd7bfa83 0040ea4a37b388f0cc464f7e2bf92173107b268ff77a8acf5f517b4ec0e4 b3d8611dc868087f3dd4bada1e3a12f5d76df7c1a208c01c13b24bc6881b07e04be604fdbb6ed2a21314ec2510a6d18f +8884def8c3b9c5f856b9c2352c85ea71aae3c8d0e84ca74e70e404a21467159fc9826548d16dd1ec5a75dc2c23ca37b30312f25e1194e0f9385a0499db34c855412bbf58979ffce7fc3afeb7b8dbf9898df44023200d809f520db99eae315b5cf85674fab008a20340fae8f6974034fd3e55bf08c5522a460680218f9757e368 0037fc7898df9b37b5390537352f5c0b8de22659166c19d7d4df31c3938d ab87034ea4e503abbfe273b0fcbd5515953882f5dcb0a416eca0849a1b7904fdf7aa9db405a1d435181e6e0a6ca9d13a +f1fc154d469433f56c2bd42aa52237a4a4bfc08fb6d2f3f0da70a62f54e94e3f29c629c837e7adf0474fa8f23251b9b349a16848942c0d9cf5db1d0fd99527020dbe21cf0b94a9aa21f376bf74da72d36f87b306b0696771efa7250c6182b426a4500ac14de4a1804b38db8d4f3beefb8c9bb619ac82cb63fb37c2e1d22951f7 005d5069425e7a9925d2cfc6360a708147b2c1b55ede243591885147ef3b 807e3a207cf04bc93ec41af407c74ac773c6979aa537596ecfa8a9b4872cb25a9c1d41ad6710768a444afd75f75326f3 +885cd348f7983a0721f96c0e866821223d3e5a95178b16d18652b4062b1b2278aed6f54ab06f7e37ae6ce1020aa3eb812d215194bcd212302da5b971fd86aee1dcb23057dbedb569bd0bbef80df538da69ae2358cb03bb77c64d3ead475c8c5ae5bfbdd75684b421a26f1a7b0c37548fa32d805acdc91230dd70a48232a12846 00ffe3e7b82ca62b96e057ee072a4718ca20a6cc9a3e51e4fe8ed7b4b9f9 b2231de6f0843cddf316faf25aa782f99a174045f29bb0ab4e325cbe7ac3ba8da9ab6250438f2393f97bf1941550d58d +ca3b0e2f1c7db4e73c699f06e432bb0f63705ba66954bec4a259bf31c161bb4861476e2f2f7dde9d841d1ea6bd0990cc793cd7a10432e38735c3eeda7a0d786e8821239bdd6c4972c96c2cf68ec5b935391f963a50fe16af2719c9029943b539ff0f1f5645962a6ac46c75d2037fa0c7cd46deadcdfc66e1ddcaada3a376acbf 0007a9cb5ce27c763646de414ca2a4dcdb774d69ed2bde7a817baddbc9de 8fa433d56ce83e41cb3d4f5302f242899208a3868f0febb94ea52b59e8252a8971e85ac0ce159085e8a8c404d76aac56 +4b0a31b746763beee77cecd318b90acf50fac4172cf4bfb354e5a440f651cb89d7a515e09ab19e9850803ab9167c2aee3b395a5da10dc9aff799d73756dfb0a9961d93bc32f15a96bf13962a03d5bd42ddc8b5928def7fc48fb063f42866fc5f96cf88fe0eb125b7c01906ad6a7fdade28ccb0a421ceff50ae03a974671b2c27 00c03fa9e38dc1c697f70bc6381f2bacaf860bb5632fc837f728da959ac9 b01b27bedcf90f3c054419c63557ddf71e8a0dc16029c171c983a340d228ba99c53a6f65f79e7aada09e3e85c0b9eb65 +3011d42792b21c0f1719faf6f744d576f72c5fdfd22b1a520d0e8d47e8c2b06823d853b13c9fa039fa30a6f2e3e27bb2100c6a35f55703806bbf0f79b09d0f629f8042ec63fa04062f15f2edb92b19237980005566f02bb12a40b4ec66e4ba6c599d928b33f72d7437c0e399a8e6a9068d1fef24917fc4f9ab5464ea6684dde9 0087dba00e3fe4802e01718017510094924496bd2785d4ac1a352c530473 81c6cfcab71079fe1c423500a91b6e2efe2da8f0fe3e8331ad8681b8185bb0d32cb42d649b1047816aa51bcaa711ac9c +05a5d3a3b79f4e51b722e513620c88092a9bb02408f5f52a32e782fd4923f4fd3094fc5536caf4b645d830260eba91b5173f3833dd65600fb9e246aec968b1f6ebdfddb4059fb2de7e636ed60bb7affdb74aefd158e54485d5f26be373cf944c6570daf8fd7e4b77fad57300667d6decf5c65db99ab8763bb4ecbb09fdf47e3a 005a387e7affc54a8fbb9157b5ebd400c98e2d7bd5c3e095538987d4f8d9 8913877893af9952b16b8d815a157d69e9d1c9b72430abe88a210d2c5935e4ba663d3046fd2c0dd5465af304dd10ea3c +247a101c8196eb93a440280650ad463795690bc620e46e8118db6900a71eb493d03fbcf2f73a79bb47aa8e2d8c87ef70e4cfae36fae5c45fe247d8cd0f7d0718dad106526945014b4f3bec324897d8e1fa2f457b8a68e61873b7fa0350fde3b87b7b001c13953c2050a24f71fb77eb455053e49200ebcbba7299485c0f1a40db 00adae709a930d6f5a5c0e3d8ef4aab004d741d23f0ffb8287f7059890c0 9920d05da5f62b3df1c7ffb79518f1d1b006bfb5426a29edfebe0df3d4d04b268f6664edb2a29735bfc31139afd42874 +a16678c71976a3ce3362ca379b3272b92e8ca7085b43752473db34e4d6b61eeed3875f49f3328366fc9d0644824e0104817de458e4c1036636b18b83dbaf063f2f99818959224906571c7b28873d9c702360888df151e9ad1a7003e6130033203acf8a69889be6ebd90816f2abf0764f10be68653b1e56766ecc3150bef8b042 0035d391411e6d679751092c4ea5a079c591e77ebdcb57c1d9006ae70d90 8169ea1c446c30e1ae805f41b85365308508603d54269ee9d997609ab1721a23e639a7ff75445dc79f93570db18d4b31 +bc2f080a7f0b69a6b142b8f3fb481a43bd71d07418df4f3b802568073c1a8d35729ad197f34a4e941a6dd511c63f201d1f6c34a1b66545bd5f43508c10bda1d6ef60ee5bdd25dde975e50c61f76cd36d50ee3bd8dfa2dff59524db9ef12f1e28d109b552cb42f021963f559c843476b5c889fc567b7840297c5a480e18c221dc 0084e79093f1947d6ab9cf399782436e36ef87c59a4c090930c9a74ddb10 a22137a22d9691bb5ca28b663fb086cc512c8e57c8b3b9af84329c5da16a986ac98fa9c4d721abbe9d971351cdfa2d3d +ea71cede8b63ddc5648eb244184bae265cd65d50f77a9e25ff93f02b132487c08732544cb88936d4fff7c0fedb39685822dd1c9be1158f647c605c9bb5f6a1ae34722fa08882c14b36b6c93cab33c9a269c7c10f755b6453ed045ea3e56f29e95a9404ba189a0b48848120392b4dcac43148b706c3d9e4c03db410cbe5dca3da 0079b6be015b8006f86fd81c2792bec6b42c08bee2d295cf9dc214c326ab 870a80c162f2137b1e5faf225afb0ff3f8e51dc15ab8781d2cd648afc993612606e632c4cacb49d284709c6657da9ee3 +319b41d16e18059a1324c37161c937e882192cd949c420ce9c59208a0ac208ebb06f894a7fd78df2a3c5f23f25dee6595d3dacb25a699f115dd482ccd36fc54ba29dda279335424c86b07a1b1fa76a5411bcecaf4d37065b229cdce0bac75b666c6626ec37a716e9841be93c907f87453ad91d36846561f284421a89013b88c3 00ca9d751a060fde64336cdc88122819f4b3cd1b4e7df42d495197787894 8a1b4e61158c9b9abe0fe7d49f3e0862a93e195761b5f6054b4881d0a070b4073d89f5e2259451c9fc8e2dcbb30fcab1 +aebeee215e7b3d4c3b82db243a47506ffbf2263f6fe9de5b69286e8649d9218367c36ba95f55e48eebcbc99de3e652b0fecc4099714ee147d71b393de14a13e5044b1251e40c6791f533b310df9e70a746f4c68c604b41752eca9ce5ce67cdc574a742c694ada8f20b34d0eb467dce5566023f8533abfa9688d782646420c77b 001dde4b2d49338a10c8ebf475b3697e8480227b39bc04253a0055839e9e 8ff1e1be437c6e44e31ec9a5ab9b5d3cd9792ac0dc62329f48afa4096878bd9cd16e0dda54db44bd25d2cdd1a969dadd +8d353a6b6f35590baef59b638914d3e934d0145b045d221d846517ceddc8ff5e3d28826d3459f8ce1260f705e80923f39abc73d5949aa7aa8ad1734be0e992bff0c9a8f4cc9bdfa430d4cf52e29d3737b0cd3231b72b16e15e1a9040b832e4a920b4a1d94c4964ac6c8abb75bbbdb10825f882ae44c534c7154c446421a04d87 002c8bea2803fd746c874fa110a716538c179c82712f38d33d0f6d037e7a abba92cdff9efdfe216354044d37329af19b1ac5977c931582f69226a050472bf09295eb6c49792d0c5d8f9c267f9d0e +847f134b90f10ba3636ec24f36a94111f26d58428fda5bba4501e58c7bb55809f52320cbe9e0df55af1e40bbac9f3eaa26a55d78b60621d4356d090d98363662f406367601eaa9eb9568b1a1b319730bad7bf6a7ddf1b45eb6922faf8d065c540b671c50df758ebf8c4aca6f01878e5e0012dd038c58833e2b13ebdb9a9f3fc3 00b9119b3b4b30cbfb98ddf0a4f6953417e515fcf0e5a94e83ebc1d1d14d 8a3ca91ab76b7fee6e3220db943d3f9258f024317aed940fe495ae5ff367a386a10fac89b94e370ccd07622f5f262f6f +99d23950493bdd931915e9f9b65e4cd1329866c0071a19d4f7d6fd190689275b7b10fc07503dd1c27a4da274dbeb3aa5cb0e71e9b7b03fc2697729b7be913756e6760098951d7015df181cf14b1e0b954e6260276af553e3e59907794b863e941950718ef154669c5c262946ba120892e0239e05910c2194f712db46e37e53b7 00f4ab2a573f3771d1e4222e251faf14e06cefed544e804c299c9a8395f5 a727f11081e37994fd0af885d173567251065f88f270e36d355bd7df1ebc8296978c957cb609a9a1ef4febe8c8ff8e69 +7bef2487bc2bbbcbcc1570bbd4ed437c0dbcbbf63f666a3355aec49ea6ef593da25aefe9ae0d94db50692475425dee3c88cdea975794ac69142c25732f3541457d68d9101c8be069f2b515aadadea2019dc7abefa6c12cb3f76d9f4b5e46546f77eaf636aa8f2329130922111151a4df913d18b7cf9d0308f01ad84d878adde7 00f4649cf30d4a5269296a45977de2652cb06d3ca2aff4475bb24517b927 87515768f0642e92394744acb57b327253bc68ff2c835c6a331082eed080966c1fad14d20b39e97d03d72dea8eaf3687 +87c717eef6dd3c7434b2c91de05723783bef603d170f654b49a04b067b077c405d2d757ce780101b930196ca4261efcfbd3fc1ebb762cc0eecf101072988aca508c41581936526d3f337053000dcf77b16172492c5d654c6612bbd2523a6ad5966d7091697a29ce882fe331f79a7eb59e5a3fe536263083cc59b8133bfd33c1d 00cca24ad914c24c011f41f80d27ea41caf41fcc8dc9dc6dff5248b2b474 977b740bcd16e38f34fe0ca140e859e3910684600979e5e43c41d925d89037df823633bd5b2b8323237338e1adadc55e +9bf48c2aebf473b3a4a928b3b6a4d2fb7e9193c9e60bc2067f9f03083a8cc7b892bdbf05601118bcc34dd283e7be996bf19b0bd36727eb9d65276b6517bf0c77ae0a9091e7a9e46182a2586eb22324939801034e5ba94ba30d1bde7d8fed51eb71036fab6224f8ff30a008422efcff7ea239ff23b9f462777e62b41b396c5dc5 00f5e12d536ef327e3b0ba65ac5fc3f7f4880f5968f3340eb8868c1d47da 984d889b4d3e1da79d60e57bb9a88dedaa167039985130a20609db9eea183372d6de72ec487e6652d8efb90e27b8939d +716d25519ae8f3717da269902be4a7566d6f62b68cd0faae94bce98c8a4ac6f66215ebac5407d6f64adf9d53f79f02e50921b6f0e8c805926a839443d30d9294eaa802faa7c5471d81fd1db148cdc621a8dd0c096e06fb0b71943337d5325e1bca77062684873fe904ed9012474ceae5b138e079f941a665a995026d13d7eed9 008c30d93536b8cb132277645021775d86c2ba8f199816c7539d560ac6de b802464fc2ed2fba950773cd405802ae7ae1b6f270c355c83e51c5cddaf34f64027ed1850d68f8251c20410425adcaee +01e76755007b2ee5ac9e1d4c8adabad6d0f9c1c08ac6e2622b7c1ead89bd3ad0921b9525b49a780a262fe8fc0904a80391717ad7cac9607de55f7c744af8a132ec45ce79723f4a4a8c8b9ef658b360bd3890df164c9f1cd74eafb74feea251a34514ff2a57ae7a6d4bec2067cbf6ee4fdaabf13721bf9ae178b9034ac5e9665b 00fa3f15a506ccf7b50bbbad0a54d3223f5a95eb54f0d1f4e5d0cc21469b 8f11d433066f7c61aa91c52b24a4e1e269a41e4e5249a18b6535a1621c36e3e491c652a8a669cddbff6ab90e4716a7b0 +e95abeeb2c51a8cb75ab74253dbe130b5560cd52e2a63d501d26e1458aa568aca6694be91eee5fdfcf582c47c1c727084ee2b2c810281cf9b095808bf7e7c668eff00a6e48b06df3fe6a445e092c24d5687d7d89acc8063275caac186c441bc697b2f67aa71b03294e1adeb7e557c296dd91304ba0587cda3c984619f1eb4f2b 006400a4830889115aa88b860b3fb65905b01fd126c4aec2785518c2543a a0cf10b79930981adf72d108b6bf29cd9e79deb1a334f29bd828ba100e0b980996db7d2535d770ecc8185ac1e6822ae1 +bb8d8515365d240b2071daef0d80558fd3d0e059be9f6abb7b7a0a5f47e2ddca7d1b3b5101d5c583143258520ce8db0a87f877a395615c9bf879ef46f2f20f68bbc9706f82781fad69019396b27f292cdc70fff1772e90205a2225f80889f9daece1d03914d8776ac5bad24d8fb190ba10a2ca17768b918c2e079d83734eb372 00c7b73c324250f14fac0edc941f79bdbc6933ee8f64bf94b847bee5eef6 91a00a1476c30cfee3a6f3a8ad0c4a8505bf597b982890b438e2b2ee89e98af964a87fcca9caed422f99dce15f6b53b9 +cd8b2403435fac9caeffa21b55eaba52d7efee0f89df7142340cdffeb89556303ca01a800429397e2ff6c746743b6bc60a87133274282d4cac02e4ca90ad95d80c93b84163b96296f67d40b2a1124b2b6534ab6b60fdee312fbcdf468d0e84eb85fce4ff360136bb31ced3998d29cfaa3ae685e638ee272058f123c4f35f8b6b 003db7f28e161abf52ab0adc8c4c8544fc989af081303b8688f22b7b2eb7 964f13265c0a23c50952812558bc26e952d05c31a51af4c27dc64071d44bba085eeac521c80c375cec1c2218ecb20e18 +4bb08eeb202564efb5bda40777d71f1bcc4c7c10b611e803e5c570876f3e319e9e2bc2d32031c56a32fc0d1fcf620d4e4377d881e9e1695bcdb78acba370b849115b86c1c4b83edfa03299da8e7fd14c7cadb81a8e4911c8e427e32c8c9b67e317575331967cf58085cff0c0d48ee0b8e7dc0b49687bb1c70c703a5dad08ec81 007e9d2fdd017d6da6029e88f78927d9ac9437f542db1f1fa99e32bfcf1a 8721517d080019e514b0e3c2cbac1d7851d8a418e76af3038f3b78d9a21c0755839e8110d92077e086ec5c1148dcf186 +0bce683d835fe64e6484328aa13e18b0956f6887b5e4442fce36ff09aed015889794e79da8aa60b4be565c78685674c51e1e7ac60db6a763c777198a56e382a03aff8b40862f961ae23e8b8683b76a5577769422418972ab0049119382edde9e752b42e8b93f403c1ef8665d7ce8530ce4ed9ebf6d397827cba6b7645e177231 00c94052760fc74c2b405ee4dd5dd2a7d38ebc16df9cc32df706075450b5 949b83b9892cad4d009609b32cf05385141f32945359fa78cfeffb68f33e8954720360ec5059bb95e94035433c4e0fcf +a6defc770426daad4dafba3bbd2a69881334f7c31269b297e440926db54cdad3fd7ad200f5ada2b72ad221ad99a06ecac9c2563a8deed89f0d0896991d1a652f6fa282affefbdb1c1985652300d1792725071631d75a182b683a48448063c7d2563ec3d430e0fd3acea33a35cd38ec0b5b07af96af71d0bfcd879d9864ededf3 004076b93487c2da8aeaeb4725fb53b7b41b465315335c18c6ca041175b4 a0415f72c2b2c038eb2072ea3adc1f0cb0eaf01854d8b83e7979547096f4aee6912eb6c4b4e978d7624988e3c62ad35c +7803cdf4758c199962b62943f475c6c31356f5d9b997a12e21146a2399cd0dd3b97a860b2ce639e2801571599136d4a8cdbfb12fd1a5ce22374991e090533ff42823a2c58d2076b772814eea7fd7a1fde68263ef912681c72c7aa3e5a7cc44ee8c65e72228b7631e600121ea35bfbbc783b6ae3c0c8f80198ada218be533760b 0076ddd73ee4fc1f5e6766e229cc7236cdfce312417ea291f7c3328d5ab1 8382687a114c12653bf83c7cb4a0722ad7db7d8241d1476552d33143d097057ec743c65db092eace4965923f5de840d7 +e789461e1dad0b6e21abeb6ae2e96385549d1bae39415188c8f833233da6a3328144c97ddb36e0ff4d9e19d84f869e79e609c51b32de59892fb0446dd28cc164a3e53534c950d26f87fb74e682db2038cde778bde06c3ee2eca2a077d8fcc2b0332e352e0e7e6487444a8ad60e78ff213b16fda9faf374dc6d27b7a3c4c6d196 007e1f8988ad804aae7d09a99be19384cc599e7652c02c391542be74b17b 846800eda5563f0923fd3c5267bafe70bfbde7fef6ea9a1c5f5e6eabe7bccaebe39d66425c88d02a796574d2d5af6d01 +9b58c145d1b6c887f2b25fb672cd49c3a1117224be697c15182d4048be92968a6500f8bcf747fcf33145c13a8d72e891a6e0c4c7310c2b62f3181bf586fe32f1ecf4feee8c2c8bf6c2bfdf9d5f88981ce080095c93e49a772d8e7b59f9cffccec3ca2f212ef4c6748f64e224f4f098334d83108bf6f8c7b43c5eb549f1526897 009b2292b0244c2aabe8b43d95039984d504ebe05eaff318760e4dee739f a717047243d41c8b5247fdc78d6b5d140346675940f8948424ad6eb79ec2bc7743f2275b49f5020d6c36b3394f2265ad +52310a901fe9681a23dd6e02f12974d57f2c4f653322d9a0ff8b338cc6c2bd9f4765c90c6b3c9fb17df3f492e67d204e39d81a8fdeb92c852a1dcc6151ed6c63049037235c6751c9a902748163a567b714725b4d3995e0edbde03215c645b1a1da3147f7406245432800c50f823a1f991c863427ff4c68e4e16d1b106ee40dd9 007ca463b50fdd92d9163f1c2bdfce2ee45ba1437b79162e3e959b814cab 8a9612cdc22a4bcf36a6efc369f46688f7096e9c2f8fdbcfc1a3c5484f0a6d6adb2e6d673a7f314ea1e15998396aeac1 +ff419c011601cfaf833067cf28dbe6e935ebeddf8b5111a97f6eebf3bb28376334f329cd877a134b074790a073db766efe018fce666a34650cbac285ae856fb6b3b8b96877282bc11cd9f9c8e510ed1f69bc2725a44a1d2b35de1edfd8bc9d20c7525ab0bbc27662a7cfc1bbd1e0f4fce5b88411521e3893e027cc8c73acdabd 00c3844750f63fe0c2e930bc38fe88522f4e72a2fd0db9778ade20e939b3 b15a55ee5778375e2bb4a11e962d03925bf456ca185e0fe0c50dc021139daf1bb8835f0e476d9ab74dc87a13c2e31ae4 +05a89c4824c5de66587875011e704bc6e06e991ba8f3aed331cfffe55aa266a08c729f77b8d082dca4d286b2d451ea838d726cc2cf298fddf2d7376714c5e37b64506f353917caec525a1209391449c078c5197a371feade74f8fc8a1a1d67576edfda13c14ad324342fc0b09277941dc072ec0d39434ff1cb91fc59478fcde7 00a3bea235dea86506be4476eb7999dcb8e584a34238c4a894ad6823b93f 972d41eeca8ca64249f3eaf0a50c62a64ead6b2375c521cc64334863b3001baa1c3b08786b25929b570133b589da2e40 +13e6b5241365d9d0ef9e8b05cabb3248afd221ec02eab92284b98bda3d9272184bfe5251d35705defba5085381430e99b33a3ab77d7870e5102757d065862372df2434a25556b76e54ebc39d4e6c3aba5cd6acf0c335756f7d9385c1068d4cfa37526a9a58c0ccc7f87a8189176c5d4f201499236058ec061357dcdb5acdba40 009a367cd1cffd8dfcca179e167ea437ee48e9b6f42559dda9224701d3f6 b6a6ca88294e0bcd7e6de629dd0be8e3bc442706727a83f541f81c463e85b732ba82afdcd16d25b5321bd2c7b281d0ea +139a1a5090b97afb8fecfff8745efacf7dcf91a4393a7b629564e598d58d5be39c05c5830d4c8ca85d29e9e2c31ad0447864e867d0ef4788ac734f8d871daebceda98d449308c2afbe97724c3af8a468f1925065f39e52ba4b7d15728a744b1252a20476dcfff7bcb82aa72c209e72abb3c24419bc26191390ffed340c1b9c6f 0046f4ad2522e78b9b35297d28f361fb0ce82306322aedc119251d8241be a74da47f2a600a3e15e422feff8fa42f3f7cee558afcd2b8f250fbd70dbf144a73d2e60f6cfea75bf3da543c9ac72434 +3315e5cda5f252e3291b61e493ab919c20a8af1286d9660cfa2f5ca38b6defe19ebecf820787fe692d04eae8a5f5d37abfb593309569cedf45efd0cecef6951b718924c8380ba52e8ab8c9bfb2261ed5f01cc5a5f9fc5fcdd269a0f122c597afdd9a836cf8f96838c3e8962c1788c3ce4128719b3ef4fc88569643dcad6da16f 00ac82137e9c7a5ecfb8b1a7df9ab50732934566a392a6c8915ee8ca8144 ad9fdaac5d2a1f70eb494d7e7b52961b4aad4e2ec40edf7a511867129e2686122a1b0691cdffa15922e846e7b2872c8c diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B233_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B233_blst new file mode 100644 index 000000000000..2440d33c5876 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B233_blst @@ -0,0 +1,60 @@ +f1b67fde01e60e4bb7904d906e9436a330c5cb5721fd4e0a3c75b83dade868736bb1d21cfb1b5c6407c373e386ee68ec2239b700e763728eb675a153b8ac44cf2a87be85fe8ed6683430cf4b7d718891cbf8d583d0a37cc952cc25fe803a7aa4fda80f05541a2f1f2601cdd0c095f7110f2a84f7d641b8531572269b21cbe77b 0056673197bfeea9bd7a8b820b4ae51a50411bf118a692bb9ed3d304da53 b4f79742bce4e9c82b80b8426e7dfe66f39e84e9d1dac328139d74b16382cd35985d867fdaaad570a837236bcbe45bd1 +1d496d96b533c632ed6a91f6e3653cdffaa5b8cc0008b35e49b2dd52fe261105c2ec7ee71a4ad5d51fdc3d36d688a3b7ccb3b3b0c3a65be17b8d8aa172e3005cfbf37a2d1b1a6e268c090c6f318e7e96f9ec9b9f5a8fbcc7558d89e840f7e76e44bed91c26ca48e6f5cbc253ca2fe8cb81c484cabd24070e488f9c00cd96ad4f 00468f01d483144e514ec257f2e5fdee28a927f2adb19714c1f3524dd0d3 b300408d7fd0d41603bc1849d274f5699762832612c86cc89c86a8039e1c1c62012ba347323667ac97e891b77d01f9bb +723400655027f474446843645757f7e2cd466bf97275067b4bc4c9d79bb3b19b2421835d69db916f24b77c381fa771fc1e7a19d2b4d09411ae55acccc615b16fd24705762b441ab67083a921fd4ae569ce0de69449aa96f5b977ac7dc022fdc8335656853796f54b3fbd118577f98920624eb0a00204f1ef83827245c06646cc 0074052d027f05465a8083a59cdbf32600224e1f563f653b34314651517f 889acf309d66236c7b01915ef72b05b3c67513642fe0ade1f985ab2bb787dde1ec43825551ddfac9765a6ee9192dceed +155860cb31a142082bcc0bad828d747e916392d21f1873b3a3c1d28ca3ff9d45ddb66a712e3856b6afd07c8d2b2a7badab296a9775b03f6fec0befa2d8d6d00fe3938df244ab46e836a3e686c8b4f918da49f0bb3940bba34a9aa22c7caf02df7758b0de01d9f47af6146344b9be3842d9c055eaf0fb399cd8db95c544a62d8a 001856e7544223f55f80de72a6ef3822fa8fbd68eb397d06e2d76ddd35e0 8f3ab5d829aa5aa6d937de74f4fbb30000790a7624ae849da6394336385abf9a0552cd2402d54fdd7f416c6d6efafc3b +cbd6e305cc9f0dc90caee6e65a74582e9357bd25c78e33a7b14e1ac7e9397ff4466f192fb432143e6df6d61a0ab808ec0a361a6d95a357a38cd3e241fe03ed883ccc364b248ee2a08702110745c2688bdcefa33c1a45b9c8b200e45cddf3e3f66b8d37eff07fbb3366ea1558ef304085613c56707095724b3e134c7a7d3f8dbf 00860aa2b589f2defc617be73e191502e5d9952bf60547fef19eeccbca26 b998e5c7de3599e2669aacf087bf91a85dd9efbf2e0ce1165a260c7e3e9337c01b0ba8f64501cac03cc5fa41857ca738 +812a218ff1ee1472c189f63386e5b8ab341671c3a4dad27a8c6249d1c0f9a29338b471b6179f17a078b6504e804ac55ca3b13e68a623041bc1a092ea2adf3fa1124bbfeb161e6d7c483433f1548763b84da00352a6386e1339f674d45dab13898147ede468e0e01d2c4e0ed66b395a16cc3ded3e952ac739205f35a83376cbce 00d0dec052a00ccebd0c0c5d9a08272f75744a2582cec7ddd924a2b022b2 a222f8db7e609a398fa9f129c3c7bba86eaaa567d91cd0d9fb217dc6ec896a6391308dbc521bf1d3175d2c660f38e5fb +0204b1fca831919e89e108cf140b3770f531a696b1d9a4d1fb68809eb10afccc257cc90cd36717c02b2f3d6d3d1d8a93cc5c48aa7ab9f9fddfe121ce9143376535a0c65e247c6558eac49fd1d6d1bf431ba918c471cb3d536ad485ec51f6471a340ac75f160c4c54cd3ffb9dcc123124b42df1fd2eaa005e3377c5d2d55938c6 008a017d717d6d1213f2b74c53281b07258738c0c7db649ea1ac46b9a3b6 8b5479a9b6c67bea7a1990a0d6effd192d55875d805dd08b12573f664ba94b6e876c7b571a7b3fb65e95a8745578c7b6 +2033eb48756638cb56e2cc39a3e775cfa11fce86cf71f04487dcdbc7f262bc8350a30ced54d1fcb697b28a6e96f88f782947c997872307ed963e1d68985f756435af77f57755cacbb4c6b50ed419deec9f39f0a549a13e54254fa0a5832dba2d943ad4aed8688889a2dd29dcb4ea12abd6a6c50eabcb3981c3a0c1ca5f0b9629 001b56c14442b084cfd22aeef0f8028ec57c8b571c9fc1e43de05c45e47f 904978899433ad767ee8deff496ae975db2b4d10d01dadf6d94b651879192378756a4d8d947e1a83047c87aa60cd0091 +2986ab1cfe8873009e932dc68d4727d77ccbbf378e43fe4aa7c54416346b036b89c0aad1b82977c9fbc39a00f1dc916c0561d8dd70298c02b6cbfe572e0ef2058641e841c6875e8515f3c1082765e046c90c956d984b76e0e8e6eb433ce26c1757ac5b13422479141971c20102e9621d18f51096ae3173c2753facee2862d66e 005afce37c5594586ac46a34ae291f591eacb9880a7de92701977f447fbf 8961d1ea4d6c1de817fe47bd1ef3a0370977bd6e4711d3b809936d27f660006f6846118060461e30711d44bad4566efe +aabf5aa90ceef91c2155f90660adbcb0eedb996f5242cee15468ae217058ebeaad8cd4ff8cdc754a8ab85ba43c59fbab6386686fad5e27ad3848fe52191c7e4b203720841501792a625aef2acb6e36493b792fa55f253effca682946ad8c77e01f44e92ec3c258d0dd98d3183f4dc4a0bd3eca183794abd6232a6f9e4add8f57 000696df05dc7a54a9908a73eb18416a155cc8df4ab26032539d86eae537 80e7ddaf0500492f46046b2cd35aed8646600898db0f52e7ecb2c989dad55d32db5512e15e517b3ad6dbfb9738556eb4 +29ff209eabbde02b10b3fd559671fa53e418750c32c4a18d31cc0186d1077581bbefb8770ed079f536e866414a07431ae6633955bf42a2389b6f8a565d6e4ffb4444336e0030093876a26d4e3106e9ac697788e41f8a21c755eeb86a7c60f18e5e1069f16408a4c375a6a68d42959f2fab7ac09736c7b37c80c05897d8566ce8 005ca31e88c5b2e96e433af2023a66095161710628e7bfa428944d6676b8 812375a9ebbde8148738309cd97dbf01502eeea465b3566d094f4f3875d78e08bfd210b45c33b42a9f2f3a2987cca599 +97765d876c80819f4004a36d09ccba78e600efc71eb7e869d3a00f658d2ace6769c7ab1ef590f41fb070aa8e08615e138df45ffbb6473d4a86ba5fdf17dd6dc9ea9ee19c0332563c99e6a3451c211d286d69102b47bfa6e07d468d9bde82e5c2063fb1ebbbed6086f542cf68ba46d4f214634afb1146dd5a6f3d50912ef5b824 00ef8fe84727a2ad8bf4e646ef28a492adfaf785a3a2ba6e6f985c649a8c a7edfd655b5365d0e0b52dc81bfc74cb75c0c2740eb76d739b68aefd9d4d7c4f1f1ebef108cf39f1e375916d3f487d15 +21cf768d087d1e4eaa8a05e2008020e243116206d675c09be42ef2bc93617ecbb0575c873c6510ede9979215531b62126552738862fc4323d487992754e39d8f0d7e111e165ff254200e05082f59a57ef649bccaef6f980094fad3b7ef93bceb161760e200f0a2e396fbb6b6142dc84d872311bf932b84616b22231747937d58 003edb94b8c62f9af30c14a790c0f5d65e362a21cd8569b9725916d534c0 8007a88920bb999f33396ec90a870b0df1c0066f2e8c973fc3839128fb664e0e1ec03f8a393bb2ad8d7f0649a4cf9594 +7b8e58eecdab3e40212bba6bf284f9379265b3d2baec3e4625aa08d0ced851da193c292ec793dab42732c07b4e94d8b19c83aed796a7e3a6c2b954a7a9a1ff9b2bd4ca62592c8b68f709f1ad38a5c8033ebb3f33d176945bfc68e9ef2b0cee2d45a13ce89d238a33c09ce2c0c63c4233aba5717b85c4c161dd7648a41a5e39d8 000a7519be62562318da1b67d22cf8e720353d22641e0cee11c7a352bb93 a700741edd6ef4eb872794b8f1064cde4abce71ff82db7a6372f19a638f02ac32da4490b7af313d88eb827ef93b323af +f8f268d2b04fe47e5052c8d0d653787384b9654f0bd2138a6f52b80713feeed452b976a90eea4edcfbb62d04f3eafe172ddebd7cdc3701ecd6008e3d82e8eb217b13b5228839f61075159f3bd1e1409c08903874b6dfee2789dd72c208ae769ec8c7d52552a2b1fd73dad24de8b571f88e2184d0ee7d063a121187f97e746f2f 00264022fd7dc2328a6436b522793ad9406d7a586667a0daaf1bce927338 8d9389d3e00cbb5cd917bf952ccc63cd929070ba2ae7b4940d526bb90845706c4567e1657d6053976499c8890b61faea +d288768cbd066fad4bb2500b5683fa9e4eaedfb3dbb519b083f6b802efda0a022355565c5fc6babeccb22f3adbbda450ce5d633193d1431e40c0fe631a295cf85965cd3f5937b31866bd6a5300eaef9941daf54d49832acfceed90e572ef34ccc94eacd0fd6b903fee3c572b963d21e2881656a214d2a4c125778dbe3bbeebca 00da43214e2efb7892cc1ccde6723946d2a8248a6b4d6c8872fad525ec3b ad71cf7cd702b51fd7bfda8c022777e22a0e26ada869c0dac10b036a5cd89fa28696946da361b27d2853ebeba7ceab7a +bf0ab46e0a756c11229b0ea961f8d57218be5b00ab8b0e91d7664cdf5e0341c412c0e992d26ab12115197db39df2d1a6e18ed26a91be461432a2dfc21d98cb16003e339b0b0b1f100e4e6f4824ddac5442f22a1fac26326ed8a89cc91343d7223986d485cc8c64424e84d56be536c57e4dc5faee459b1958efd79e07e90a9811 00aeafa49d776b61f6a30d66ff64bd40dd8d79891dd5293c1b5cd3b46a7c a7420ca25a975ac0c6aafd5a7646a55213038b8aff73f67a5c4ae692f5416fe415e55e4f200f3775fb337eaee7ed9417 +c7b1eeb7c19eb16e7f42b61d79e421b71de797a6cab4e0baee522fee7acdb533f7bbf5855316544e1b82b4f2a18ad0a2311e7622549332122171f32fc62a90e408207e0fb90d1b052821dede9c41b15b6e07d84d5d7b9e31e6396a8ed229fb6232b3051298dc5321aa589f4e289d27169f14c8cc93644916d9b72dbc92c43488 00e95db309f4305b621f51f93588a2678cb19aad0932f365fa0aaa3a3895 aff726668a2a7bbba5200499a6b204ad15f16face0b310c85fe5769668f5ded200c132b44be41d8fe7377c68e86a5b79 +a738eb074e1f277dc665118ca055e6328059ab26da188c16f56384c566e43df8cff3d2a10d2d15c3c1406de8f734b20be5dd1ce937a4289f0ddfd7bddabd03586556eb8233b8feefedaa1f49bdec6d45fd562c2a83fa9fcfc2013bdd77900857199e51fa9c7cbeab925ba8f6c3c5fae46bf8e9c574b302f1e5f9c44400152a78 00d4319cc8e409b8755880827f3200d3f0f1c64d6356fe74eb1f5aa42499 98b65498afe27c9fa11148899156fab9915497e8922cc93cccb8dd4d066cdcdf37d19fa8fe6fe57c6bf5507d1cdb066d +b28103d77e5457c42e026e713ea6ff03722a36512da17197140117442a976f9e2139c54a759fc26af5811b455e5a0d3a95362d9939c1e738045be9237b469ae2106ceed7e7842b44cc0a475d5af6d781e32ff1dd1f4e1833dbc7f82b27dc7e1562d0e29213fd8911105104a7a16f665b926aa137f70d868c90e72f8ee2c95b64 009e556c945052e5954915c773b2d47970c521fcc99139269c3ef46093b7 94d46c6b863972a46641ac78911e31aef42e5013afd42342b7a84943d5d603d564cc53f504a5a2de8f56e951ef7f2d9e +463d04c84521ae671bb35c0a7acb3ae509b1b0470f39b8fe7ae5f3c9fbadbeb2bcc3a87e284cbdff07407a351f7ba743aeac50c4a1fef7375b90eb4af8ea2df040776bbf3e4389e7a80bea40530842642b9895ab9ef5ac8ed6c9ce7917d7b3ebcf80b801da845943313988c1970e7748cc306f914c37414f8247d648b580000f 00becc76f8a77615c4f92ae1f91645bf5bb908e75ef22fd544aae63a3c8e aebe1d9ae5bcfb8b0988cbec1386a9a778e50a4fe6f24faadd59df7b3efea954a73ae5c9e595b69f9a5a799bd04f9df8 +8b2379b5553ae7db6023cb010e26ae91322bc3f94dbaa369481936f90a886e5d3827d995ccf03ca59f46805fbac0337d31a8f117cc7044218a934d5bf507090e7e21178a7162c8fcb39111e6967803dbf9d752f3ae737ba024d0f4f7627e08be58efbe997a164106bfe37f67d2f19c0fcc7a6c7eebd96a72582a9c7bdf881896 0020572c2a3dc3ea430cd8cde9d642081c21658e8bda165550cd9a5d37d9 946c8b5cd9d9f01d96b32fdd7f4f802954255137e9c4c48df96b68b6bfb7a3af364a550c9e566a6b666835fcab976671 +3090bf7373731cc44c00372c1ac59280b0f36e627ccf763fa68a7be37bb0ac8cbd4f70db54fc652566c78ad268f78f015e4bb1e41516fa56ac303a3bb4a52e1fe897d8338db5a6e37cad685e704b994504bd231c7dec0002dbd907a7ebfa809833e32eb23fffdb44fe4a18e11fa19d67356cfd703cf39a75b1a290b8a7c73afb 00769cfbf2dd8248ea1e0ac9b275c9d6ddcf923fe762079b9ed62ccbaa89 a18fcfc2511f07ffb3b2fa0d6afbfc8a6d50785671c8dab83d09d29157e3b02f4f220204b10a21a39ee362957ce806d8 +c37389cbe3f46eeebdda343e354ccd543e96b0c2a87e057aa6b9c4895a403de706d658bbc9066c140e50fef4b56af2db1f42efb70b8021254649983f1e11d04d6b10169d5a1c2093b6ab89227b88a30537c776bb7575749c3ed87bcb29effd8e4f17915b4d5dff6cab9678d88f33abead1e73dbdc5c3307ff3d3b2d5fd7bfa83 0040ea4a37b388f0cc464f7e2bf92173107b268ff77a8acf5f517b4ec0e4 b3d8611dc868087f3dd4bada1e3a12f5d76df7c1a208c01c13b24bc6881b07e04be604fdbb6ed2a21314ec2510a6d18f +8884def8c3b9c5f856b9c2352c85ea71aae3c8d0e84ca74e70e404a21467159fc9826548d16dd1ec5a75dc2c23ca37b30312f25e1194e0f9385a0499db34c855412bbf58979ffce7fc3afeb7b8dbf9898df44023200d809f520db99eae315b5cf85674fab008a20340fae8f6974034fd3e55bf08c5522a460680218f9757e368 0037fc7898df9b37b5390537352f5c0b8de22659166c19d7d4df31c3938d ab87034ea4e503abbfe273b0fcbd5515953882f5dcb0a416eca0849a1b7904fdf7aa9db405a1d435181e6e0a6ca9d13a +f1fc154d469433f56c2bd42aa52237a4a4bfc08fb6d2f3f0da70a62f54e94e3f29c629c837e7adf0474fa8f23251b9b349a16848942c0d9cf5db1d0fd99527020dbe21cf0b94a9aa21f376bf74da72d36f87b306b0696771efa7250c6182b426a4500ac14de4a1804b38db8d4f3beefb8c9bb619ac82cb63fb37c2e1d22951f7 005d5069425e7a9925d2cfc6360a708147b2c1b55ede243591885147ef3b 807e3a207cf04bc93ec41af407c74ac773c6979aa537596ecfa8a9b4872cb25a9c1d41ad6710768a444afd75f75326f3 +885cd348f7983a0721f96c0e866821223d3e5a95178b16d18652b4062b1b2278aed6f54ab06f7e37ae6ce1020aa3eb812d215194bcd212302da5b971fd86aee1dcb23057dbedb569bd0bbef80df538da69ae2358cb03bb77c64d3ead475c8c5ae5bfbdd75684b421a26f1a7b0c37548fa32d805acdc91230dd70a48232a12846 00ffe3e7b82ca62b96e057ee072a4718ca20a6cc9a3e51e4fe8ed7b4b9f9 b2231de6f0843cddf316faf25aa782f99a174045f29bb0ab4e325cbe7ac3ba8da9ab6250438f2393f97bf1941550d58d +ca3b0e2f1c7db4e73c699f06e432bb0f63705ba66954bec4a259bf31c161bb4861476e2f2f7dde9d841d1ea6bd0990cc793cd7a10432e38735c3eeda7a0d786e8821239bdd6c4972c96c2cf68ec5b935391f963a50fe16af2719c9029943b539ff0f1f5645962a6ac46c75d2037fa0c7cd46deadcdfc66e1ddcaada3a376acbf 0007a9cb5ce27c763646de414ca2a4dcdb774d69ed2bde7a817baddbc9de 8fa433d56ce83e41cb3d4f5302f242899208a3868f0febb94ea52b59e8252a8971e85ac0ce159085e8a8c404d76aac56 +4b0a31b746763beee77cecd318b90acf50fac4172cf4bfb354e5a440f651cb89d7a515e09ab19e9850803ab9167c2aee3b395a5da10dc9aff799d73756dfb0a9961d93bc32f15a96bf13962a03d5bd42ddc8b5928def7fc48fb063f42866fc5f96cf88fe0eb125b7c01906ad6a7fdade28ccb0a421ceff50ae03a974671b2c27 00c03fa9e38dc1c697f70bc6381f2bacaf860bb5632fc837f728da959ac9 b01b27bedcf90f3c054419c63557ddf71e8a0dc16029c171c983a340d228ba99c53a6f65f79e7aada09e3e85c0b9eb65 +3011d42792b21c0f1719faf6f744d576f72c5fdfd22b1a520d0e8d47e8c2b06823d853b13c9fa039fa30a6f2e3e27bb2100c6a35f55703806bbf0f79b09d0f629f8042ec63fa04062f15f2edb92b19237980005566f02bb12a40b4ec66e4ba6c599d928b33f72d7437c0e399a8e6a9068d1fef24917fc4f9ab5464ea6684dde9 0087dba00e3fe4802e01718017510094924496bd2785d4ac1a352c530473 81c6cfcab71079fe1c423500a91b6e2efe2da8f0fe3e8331ad8681b8185bb0d32cb42d649b1047816aa51bcaa711ac9c +05a5d3a3b79f4e51b722e513620c88092a9bb02408f5f52a32e782fd4923f4fd3094fc5536caf4b645d830260eba91b5173f3833dd65600fb9e246aec968b1f6ebdfddb4059fb2de7e636ed60bb7affdb74aefd158e54485d5f26be373cf944c6570daf8fd7e4b77fad57300667d6decf5c65db99ab8763bb4ecbb09fdf47e3a 005a387e7affc54a8fbb9157b5ebd400c98e2d7bd5c3e095538987d4f8d9 8913877893af9952b16b8d815a157d69e9d1c9b72430abe88a210d2c5935e4ba663d3046fd2c0dd5465af304dd10ea3c +247a101c8196eb93a440280650ad463795690bc620e46e8118db6900a71eb493d03fbcf2f73a79bb47aa8e2d8c87ef70e4cfae36fae5c45fe247d8cd0f7d0718dad106526945014b4f3bec324897d8e1fa2f457b8a68e61873b7fa0350fde3b87b7b001c13953c2050a24f71fb77eb455053e49200ebcbba7299485c0f1a40db 00adae709a930d6f5a5c0e3d8ef4aab004d741d23f0ffb8287f7059890c0 9920d05da5f62b3df1c7ffb79518f1d1b006bfb5426a29edfebe0df3d4d04b268f6664edb2a29735bfc31139afd42874 +a16678c71976a3ce3362ca379b3272b92e8ca7085b43752473db34e4d6b61eeed3875f49f3328366fc9d0644824e0104817de458e4c1036636b18b83dbaf063f2f99818959224906571c7b28873d9c702360888df151e9ad1a7003e6130033203acf8a69889be6ebd90816f2abf0764f10be68653b1e56766ecc3150bef8b042 0035d391411e6d679751092c4ea5a079c591e77ebdcb57c1d9006ae70d90 8169ea1c446c30e1ae805f41b85365308508603d54269ee9d997609ab1721a23e639a7ff75445dc79f93570db18d4b31 +bc2f080a7f0b69a6b142b8f3fb481a43bd71d07418df4f3b802568073c1a8d35729ad197f34a4e941a6dd511c63f201d1f6c34a1b66545bd5f43508c10bda1d6ef60ee5bdd25dde975e50c61f76cd36d50ee3bd8dfa2dff59524db9ef12f1e28d109b552cb42f021963f559c843476b5c889fc567b7840297c5a480e18c221dc 0084e79093f1947d6ab9cf399782436e36ef87c59a4c090930c9a74ddb10 a22137a22d9691bb5ca28b663fb086cc512c8e57c8b3b9af84329c5da16a986ac98fa9c4d721abbe9d971351cdfa2d3d +ea71cede8b63ddc5648eb244184bae265cd65d50f77a9e25ff93f02b132487c08732544cb88936d4fff7c0fedb39685822dd1c9be1158f647c605c9bb5f6a1ae34722fa08882c14b36b6c93cab33c9a269c7c10f755b6453ed045ea3e56f29e95a9404ba189a0b48848120392b4dcac43148b706c3d9e4c03db410cbe5dca3da 0079b6be015b8006f86fd81c2792bec6b42c08bee2d295cf9dc214c326ab 870a80c162f2137b1e5faf225afb0ff3f8e51dc15ab8781d2cd648afc993612606e632c4cacb49d284709c6657da9ee3 +319b41d16e18059a1324c37161c937e882192cd949c420ce9c59208a0ac208ebb06f894a7fd78df2a3c5f23f25dee6595d3dacb25a699f115dd482ccd36fc54ba29dda279335424c86b07a1b1fa76a5411bcecaf4d37065b229cdce0bac75b666c6626ec37a716e9841be93c907f87453ad91d36846561f284421a89013b88c3 00ca9d751a060fde64336cdc88122819f4b3cd1b4e7df42d495197787894 8a1b4e61158c9b9abe0fe7d49f3e0862a93e195761b5f6054b4881d0a070b4073d89f5e2259451c9fc8e2dcbb30fcab1 +aebeee215e7b3d4c3b82db243a47506ffbf2263f6fe9de5b69286e8649d9218367c36ba95f55e48eebcbc99de3e652b0fecc4099714ee147d71b393de14a13e5044b1251e40c6791f533b310df9e70a746f4c68c604b41752eca9ce5ce67cdc574a742c694ada8f20b34d0eb467dce5566023f8533abfa9688d782646420c77b 001dde4b2d49338a10c8ebf475b3697e8480227b39bc04253a0055839e9e 8ff1e1be437c6e44e31ec9a5ab9b5d3cd9792ac0dc62329f48afa4096878bd9cd16e0dda54db44bd25d2cdd1a969dadd +8d353a6b6f35590baef59b638914d3e934d0145b045d221d846517ceddc8ff5e3d28826d3459f8ce1260f705e80923f39abc73d5949aa7aa8ad1734be0e992bff0c9a8f4cc9bdfa430d4cf52e29d3737b0cd3231b72b16e15e1a9040b832e4a920b4a1d94c4964ac6c8abb75bbbdb10825f882ae44c534c7154c446421a04d87 002c8bea2803fd746c874fa110a716538c179c82712f38d33d0f6d037e7a abba92cdff9efdfe216354044d37329af19b1ac5977c931582f69226a050472bf09295eb6c49792d0c5d8f9c267f9d0e +847f134b90f10ba3636ec24f36a94111f26d58428fda5bba4501e58c7bb55809f52320cbe9e0df55af1e40bbac9f3eaa26a55d78b60621d4356d090d98363662f406367601eaa9eb9568b1a1b319730bad7bf6a7ddf1b45eb6922faf8d065c540b671c50df758ebf8c4aca6f01878e5e0012dd038c58833e2b13ebdb9a9f3fc3 00b9119b3b4b30cbfb98ddf0a4f6953417e515fcf0e5a94e83ebc1d1d14d 8a3ca91ab76b7fee6e3220db943d3f9258f024317aed940fe495ae5ff367a386a10fac89b94e370ccd07622f5f262f6f +99d23950493bdd931915e9f9b65e4cd1329866c0071a19d4f7d6fd190689275b7b10fc07503dd1c27a4da274dbeb3aa5cb0e71e9b7b03fc2697729b7be913756e6760098951d7015df181cf14b1e0b954e6260276af553e3e59907794b863e941950718ef154669c5c262946ba120892e0239e05910c2194f712db46e37e53b7 00f4ab2a573f3771d1e4222e251faf14e06cefed544e804c299c9a8395f5 a727f11081e37994fd0af885d173567251065f88f270e36d355bd7df1ebc8296978c957cb609a9a1ef4febe8c8ff8e69 +7bef2487bc2bbbcbcc1570bbd4ed437c0dbcbbf63f666a3355aec49ea6ef593da25aefe9ae0d94db50692475425dee3c88cdea975794ac69142c25732f3541457d68d9101c8be069f2b515aadadea2019dc7abefa6c12cb3f76d9f4b5e46546f77eaf636aa8f2329130922111151a4df913d18b7cf9d0308f01ad84d878adde7 00f4649cf30d4a5269296a45977de2652cb06d3ca2aff4475bb24517b927 87515768f0642e92394744acb57b327253bc68ff2c835c6a331082eed080966c1fad14d20b39e97d03d72dea8eaf3687 +87c717eef6dd3c7434b2c91de05723783bef603d170f654b49a04b067b077c405d2d757ce780101b930196ca4261efcfbd3fc1ebb762cc0eecf101072988aca508c41581936526d3f337053000dcf77b16172492c5d654c6612bbd2523a6ad5966d7091697a29ce882fe331f79a7eb59e5a3fe536263083cc59b8133bfd33c1d 00cca24ad914c24c011f41f80d27ea41caf41fcc8dc9dc6dff5248b2b474 977b740bcd16e38f34fe0ca140e859e3910684600979e5e43c41d925d89037df823633bd5b2b8323237338e1adadc55e +9bf48c2aebf473b3a4a928b3b6a4d2fb7e9193c9e60bc2067f9f03083a8cc7b892bdbf05601118bcc34dd283e7be996bf19b0bd36727eb9d65276b6517bf0c77ae0a9091e7a9e46182a2586eb22324939801034e5ba94ba30d1bde7d8fed51eb71036fab6224f8ff30a008422efcff7ea239ff23b9f462777e62b41b396c5dc5 00f5e12d536ef327e3b0ba65ac5fc3f7f4880f5968f3340eb8868c1d47da 984d889b4d3e1da79d60e57bb9a88dedaa167039985130a20609db9eea183372d6de72ec487e6652d8efb90e27b8939d +716d25519ae8f3717da269902be4a7566d6f62b68cd0faae94bce98c8a4ac6f66215ebac5407d6f64adf9d53f79f02e50921b6f0e8c805926a839443d30d9294eaa802faa7c5471d81fd1db148cdc621a8dd0c096e06fb0b71943337d5325e1bca77062684873fe904ed9012474ceae5b138e079f941a665a995026d13d7eed9 008c30d93536b8cb132277645021775d86c2ba8f199816c7539d560ac6de b802464fc2ed2fba950773cd405802ae7ae1b6f270c355c83e51c5cddaf34f64027ed1850d68f8251c20410425adcaee +01e76755007b2ee5ac9e1d4c8adabad6d0f9c1c08ac6e2622b7c1ead89bd3ad0921b9525b49a780a262fe8fc0904a80391717ad7cac9607de55f7c744af8a132ec45ce79723f4a4a8c8b9ef658b360bd3890df164c9f1cd74eafb74feea251a34514ff2a57ae7a6d4bec2067cbf6ee4fdaabf13721bf9ae178b9034ac5e9665b 00fa3f15a506ccf7b50bbbad0a54d3223f5a95eb54f0d1f4e5d0cc21469b 8f11d433066f7c61aa91c52b24a4e1e269a41e4e5249a18b6535a1621c36e3e491c652a8a669cddbff6ab90e4716a7b0 +e95abeeb2c51a8cb75ab74253dbe130b5560cd52e2a63d501d26e1458aa568aca6694be91eee5fdfcf582c47c1c727084ee2b2c810281cf9b095808bf7e7c668eff00a6e48b06df3fe6a445e092c24d5687d7d89acc8063275caac186c441bc697b2f67aa71b03294e1adeb7e557c296dd91304ba0587cda3c984619f1eb4f2b 006400a4830889115aa88b860b3fb65905b01fd126c4aec2785518c2543a a0cf10b79930981adf72d108b6bf29cd9e79deb1a334f29bd828ba100e0b980996db7d2535d770ecc8185ac1e6822ae1 +bb8d8515365d240b2071daef0d80558fd3d0e059be9f6abb7b7a0a5f47e2ddca7d1b3b5101d5c583143258520ce8db0a87f877a395615c9bf879ef46f2f20f68bbc9706f82781fad69019396b27f292cdc70fff1772e90205a2225f80889f9daece1d03914d8776ac5bad24d8fb190ba10a2ca17768b918c2e079d83734eb372 00c7b73c324250f14fac0edc941f79bdbc6933ee8f64bf94b847bee5eef6 91a00a1476c30cfee3a6f3a8ad0c4a8505bf597b982890b438e2b2ee89e98af964a87fcca9caed422f99dce15f6b53b9 +cd8b2403435fac9caeffa21b55eaba52d7efee0f89df7142340cdffeb89556303ca01a800429397e2ff6c746743b6bc60a87133274282d4cac02e4ca90ad95d80c93b84163b96296f67d40b2a1124b2b6534ab6b60fdee312fbcdf468d0e84eb85fce4ff360136bb31ced3998d29cfaa3ae685e638ee272058f123c4f35f8b6b 003db7f28e161abf52ab0adc8c4c8544fc989af081303b8688f22b7b2eb7 964f13265c0a23c50952812558bc26e952d05c31a51af4c27dc64071d44bba085eeac521c80c375cec1c2218ecb20e18 +4bb08eeb202564efb5bda40777d71f1bcc4c7c10b611e803e5c570876f3e319e9e2bc2d32031c56a32fc0d1fcf620d4e4377d881e9e1695bcdb78acba370b849115b86c1c4b83edfa03299da8e7fd14c7cadb81a8e4911c8e427e32c8c9b67e317575331967cf58085cff0c0d48ee0b8e7dc0b49687bb1c70c703a5dad08ec81 007e9d2fdd017d6da6029e88f78927d9ac9437f542db1f1fa99e32bfcf1a 8721517d080019e514b0e3c2cbac1d7851d8a418e76af3038f3b78d9a21c0755839e8110d92077e086ec5c1148dcf186 +0bce683d835fe64e6484328aa13e18b0956f6887b5e4442fce36ff09aed015889794e79da8aa60b4be565c78685674c51e1e7ac60db6a763c777198a56e382a03aff8b40862f961ae23e8b8683b76a5577769422418972ab0049119382edde9e752b42e8b93f403c1ef8665d7ce8530ce4ed9ebf6d397827cba6b7645e177231 00c94052760fc74c2b405ee4dd5dd2a7d38ebc16df9cc32df706075450b5 949b83b9892cad4d009609b32cf05385141f32945359fa78cfeffb68f33e8954720360ec5059bb95e94035433c4e0fcf +a6defc770426daad4dafba3bbd2a69881334f7c31269b297e440926db54cdad3fd7ad200f5ada2b72ad221ad99a06ecac9c2563a8deed89f0d0896991d1a652f6fa282affefbdb1c1985652300d1792725071631d75a182b683a48448063c7d2563ec3d430e0fd3acea33a35cd38ec0b5b07af96af71d0bfcd879d9864ededf3 004076b93487c2da8aeaeb4725fb53b7b41b465315335c18c6ca041175b4 a0415f72c2b2c038eb2072ea3adc1f0cb0eaf01854d8b83e7979547096f4aee6912eb6c4b4e978d7624988e3c62ad35c +7803cdf4758c199962b62943f475c6c31356f5d9b997a12e21146a2399cd0dd3b97a860b2ce639e2801571599136d4a8cdbfb12fd1a5ce22374991e090533ff42823a2c58d2076b772814eea7fd7a1fde68263ef912681c72c7aa3e5a7cc44ee8c65e72228b7631e600121ea35bfbbc783b6ae3c0c8f80198ada218be533760b 0076ddd73ee4fc1f5e6766e229cc7236cdfce312417ea291f7c3328d5ab1 8382687a114c12653bf83c7cb4a0722ad7db7d8241d1476552d33143d097057ec743c65db092eace4965923f5de840d7 +e789461e1dad0b6e21abeb6ae2e96385549d1bae39415188c8f833233da6a3328144c97ddb36e0ff4d9e19d84f869e79e609c51b32de59892fb0446dd28cc164a3e53534c950d26f87fb74e682db2038cde778bde06c3ee2eca2a077d8fcc2b0332e352e0e7e6487444a8ad60e78ff213b16fda9faf374dc6d27b7a3c4c6d196 007e1f8988ad804aae7d09a99be19384cc599e7652c02c391542be74b17b 846800eda5563f0923fd3c5267bafe70bfbde7fef6ea9a1c5f5e6eabe7bccaebe39d66425c88d02a796574d2d5af6d01 +9b58c145d1b6c887f2b25fb672cd49c3a1117224be697c15182d4048be92968a6500f8bcf747fcf33145c13a8d72e891a6e0c4c7310c2b62f3181bf586fe32f1ecf4feee8c2c8bf6c2bfdf9d5f88981ce080095c93e49a772d8e7b59f9cffccec3ca2f212ef4c6748f64e224f4f098334d83108bf6f8c7b43c5eb549f1526897 009b2292b0244c2aabe8b43d95039984d504ebe05eaff318760e4dee739f a717047243d41c8b5247fdc78d6b5d140346675940f8948424ad6eb79ec2bc7743f2275b49f5020d6c36b3394f2265ad +52310a901fe9681a23dd6e02f12974d57f2c4f653322d9a0ff8b338cc6c2bd9f4765c90c6b3c9fb17df3f492e67d204e39d81a8fdeb92c852a1dcc6151ed6c63049037235c6751c9a902748163a567b714725b4d3995e0edbde03215c645b1a1da3147f7406245432800c50f823a1f991c863427ff4c68e4e16d1b106ee40dd9 007ca463b50fdd92d9163f1c2bdfce2ee45ba1437b79162e3e959b814cab 8a9612cdc22a4bcf36a6efc369f46688f7096e9c2f8fdbcfc1a3c5484f0a6d6adb2e6d673a7f314ea1e15998396aeac1 +ff419c011601cfaf833067cf28dbe6e935ebeddf8b5111a97f6eebf3bb28376334f329cd877a134b074790a073db766efe018fce666a34650cbac285ae856fb6b3b8b96877282bc11cd9f9c8e510ed1f69bc2725a44a1d2b35de1edfd8bc9d20c7525ab0bbc27662a7cfc1bbd1e0f4fce5b88411521e3893e027cc8c73acdabd 00c3844750f63fe0c2e930bc38fe88522f4e72a2fd0db9778ade20e939b3 b15a55ee5778375e2bb4a11e962d03925bf456ca185e0fe0c50dc021139daf1bb8835f0e476d9ab74dc87a13c2e31ae4 +05a89c4824c5de66587875011e704bc6e06e991ba8f3aed331cfffe55aa266a08c729f77b8d082dca4d286b2d451ea838d726cc2cf298fddf2d7376714c5e37b64506f353917caec525a1209391449c078c5197a371feade74f8fc8a1a1d67576edfda13c14ad324342fc0b09277941dc072ec0d39434ff1cb91fc59478fcde7 00a3bea235dea86506be4476eb7999dcb8e584a34238c4a894ad6823b93f 972d41eeca8ca64249f3eaf0a50c62a64ead6b2375c521cc64334863b3001baa1c3b08786b25929b570133b589da2e40 +13e6b5241365d9d0ef9e8b05cabb3248afd221ec02eab92284b98bda3d9272184bfe5251d35705defba5085381430e99b33a3ab77d7870e5102757d065862372df2434a25556b76e54ebc39d4e6c3aba5cd6acf0c335756f7d9385c1068d4cfa37526a9a58c0ccc7f87a8189176c5d4f201499236058ec061357dcdb5acdba40 009a367cd1cffd8dfcca179e167ea437ee48e9b6f42559dda9224701d3f6 b6a6ca88294e0bcd7e6de629dd0be8e3bc442706727a83f541f81c463e85b732ba82afdcd16d25b5321bd2c7b281d0ea +139a1a5090b97afb8fecfff8745efacf7dcf91a4393a7b629564e598d58d5be39c05c5830d4c8ca85d29e9e2c31ad0447864e867d0ef4788ac734f8d871daebceda98d449308c2afbe97724c3af8a468f1925065f39e52ba4b7d15728a744b1252a20476dcfff7bcb82aa72c209e72abb3c24419bc26191390ffed340c1b9c6f 0046f4ad2522e78b9b35297d28f361fb0ce82306322aedc119251d8241be a74da47f2a600a3e15e422feff8fa42f3f7cee558afcd2b8f250fbd70dbf144a73d2e60f6cfea75bf3da543c9ac72434 +3315e5cda5f252e3291b61e493ab919c20a8af1286d9660cfa2f5ca38b6defe19ebecf820787fe692d04eae8a5f5d37abfb593309569cedf45efd0cecef6951b718924c8380ba52e8ab8c9bfb2261ed5f01cc5a5f9fc5fcdd269a0f122c597afdd9a836cf8f96838c3e8962c1788c3ce4128719b3ef4fc88569643dcad6da16f 00ac82137e9c7a5ecfb8b1a7df9ab50732934566a392a6c8915ee8ca8144 ad9fdaac5d2a1f70eb494d7e7b52961b4aad4e2ec40edf7a511867129e2686122a1b0691cdffa15922e846e7b2872c8c diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B283 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B283 new file mode 100644 index 000000000000..31bffd2ba066 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B283 @@ -0,0 +1,60 @@ +067f27bbcecbad85277fa3629da11a24b2f19ba1e65a69d827fad430346c9d102e1b4452d04147c8133acc1e268490cd342a54065a1bd6470aabbad42fbddc54a9a76c68aceba397cb350327c5e6f5a6df0b5b5560f04700d536b384dd4b412e74fd1b8f782611e9426bf8ca77b2448d9a9f415bcfee30dda1ccb49737994f2d 0299ff06e019b5f78a1aec39706b22213abb601bd62b9979bf9bc89fb702e724e3ada994 89a67d9ba659d37eec881d172e04ae25b667dc5b98ab7967f889294e116be9089ded2b3b074ed80450735d3b2a3f237f +44adcb7e2462247b44c59608cbe228ada574ecb9f6f38baf30e42b589fb9b157bb0560e5a2aa5523b71cc0d7f583b502bec45d9b8352f29ee1842f42a17a5b16136feaa2efa4a0ae306402940ecd6b71e57d1467c98e7960de2a97f88b43487e4f4016af1292381d70c18c7e6eed99a14cdeb5b3caf73688658e4c5b54c81e08 009c2804f8cab768248fb3fff8a055b3f4585c00de5c1615a19f9425b9432ea09afba8f2 978d59bb5a235726c7fef7823130729b1d638d1d8094d45b76b8f25437d09a79c07fd41b249f046ef55bb96ef6436ddb +cffee6252c7eb6d91d8fe100a1e62f0ad9f862d78ca2b747a6c17b8c9ea8980dc239b3b673310e6e7483582399163e39d889abc1a613fe77849ebc09b4f7f4fe0688b8a9869ae918a88294c7ee199be50ee9460db14725ae70b449d0cb48f30e7d817ec02c0cd586119341dba0b74f0279330807cfccc99c8c340b72c1764a45 02e625a6bc6d0ce7c06231de827068bdb0abc8ffb57c82b35ee3a0f873b9473905974d34 adcfd58baf32c8518a438e0b73325a0a93243a470c4e65934cbebb9254928a3f1c4da1bf172e2c50f1763ce498960c63 +d058ab5dc07228253707ef224897ea0fcd09c3d5cc91fdce9e03c1c59c53fb4596be2ed929c7455e67ac7f4891aed3eb06ad88f2c4aaaabff045b959f900d1019d706b60526375851bb891494e99995928e4cd51c9616aa651ec77bd7e398916bb9ed3156391bf7fb1e29181e2b011dae2edaf803607def2ac6b194929a57f45 0376ac24e1b86f8a55c052d92a0bdc6472fa03acdcdbccbf7c321ec0ccd97aa0a66b4181 aaf01de91658881604f3f759f8fe6770c315beaa84ee5b3d05242dacdad44a2b6e1008455d44f91e5ca8222aea5b10e3 +c86f2cc7ab5df5cf1a236fd83792769474cef464032800ffe98a44cf29dbfb6f24088160eb31a11a382ff2a49f3e05e983462f5304272f96c0a002b69af3d233aebe867ee63fa46666760a6889d022c18645b491f8d71b6a3b6b4ef058e280cf625198715b64b025bf0449445d3dd7e1f27153926e617bd2c96638345431d1ed 02b50a6395fc02b9ac1841323de4520292f913519bc0d6a471aa28021322fc4dbcd7b802 8a3fea10ca737fcd2d3505f4de749126b55dc13b15dbb47e5cbceecc771fc7118aebd426bbadcbff0a9590a89b971384 +c1328d8d2e5b6ffc850a9600bd6482518ddd9cee3fc9140febb72bcd444b0cd7e8074587d51b62cce4b3d4f34ad3355353fabe363369cf790db2df9fdac3a0ec4757e2dfb3b683eaa3e26531691ce765742e1c0bdc0e1028d347b6085fc459df0989c6a144271454eaffe413cae2ad7c8b2371fd2df1afffe56df727009765a2 024e5889722f6c35e18ca47effa9e415b1ba790066a91fb3c9f7b001ce28fc732b09bc23 832c5920548ee893781d2acc8d6eedccd364b8e8bb41e6a59227bcc4bb4f6716c2f5ba35885c28f9ae581d0e68ebe0e3 +7176b7013ea27e94281977eacb976bb31c753bf80fa09680a29128a6fc15234f79f0e9900aff3217ce9be72c378042c6c34fced0158740073d1a985fa25987fb218002e425868fda5a47de51abfd04de34e2b8634cebfbdc98e80f93d94096193eaa82dc8778fc23f3765c7acdad94fdaa272df0ff0f28190c10a462ee78ac92 0056d15b81f40b6378588a5efe43e21b95e18120d514bfdda0e7759a1d0766a8a35ce5ac b4621b6e167241a16ca203723c3e2641ea90ab100a085f4ad8fe41655063240f74d99602576dd14bb1498fde1f803ace +4c3642ba040a9955b9d50dcd1c936688c17c363854358afa8ca49c6abd906dfdc4d89bb4cab0bbc363fb5b74e1f004d4b09ec9dfeed4c0bfb482a9061a1f487a3d79195ff7b65a0504bced3a28db0ebe8fcf8ab1ee4a3ae91324d15d890ac4c479144dd5538d2e36d3a587769ee9cd2d5c6f85a03362a022fe0efc4a3902b71a 012fb2fb5bf5f7e42a500154823a174ba2d05af71e3b0cf47fab46e673ea1822f1563def 93929dbf10137eff56f93485d77017a215366ba08b29db1d7015877c961725af3658601fa5f555eb4656238ff80bec25 +e471f39c18b081362adc7da47dec254dab8d765f005ac574640d78c14222639245563912d942f3be212ee3cef134407334c8fe3602fa0e1629de5331643d76715dc1b0ffcebd484d86c5211be4b285a31688b205fa988e6c15b36daf396ccdcc209c7dde2a732f5c31c84c7ea041408ebf15e56632583af0131bd7f531b5fc45 030096c54fd480647e017f8cdbbdef292e799f054e3279d228b09816a757566a744a8266 8fd6ab2b62c67619cd2e562448a2e2f2744dd1a9a87f57d690c894b18be9ee8df3bb0a19b7c0596c77e09c12e836e53a +8a93fe53e83075c4025228540af7e96a588520da34e3eadeb99a4ab2f3dbbb8f85fe63a3b86c1f4ec912e665ca05b43e869985eae3791b91205afb1380e16c25b74e6793fa63e4a55dcf25dc22d03f09deddeb9042b620434111afe08c5657c7d754af66ad91a1b5423301b1e8e6389a1404060d1b6a99fe0f89598482979e42 00a1b7e9c8c2dc25b494b5ef3195b294e41cd3c2c35235ab42542bd3e2a52d5826662bf9 8d2446651f0448d67159529c830771a327ccdf8750abc1ce4d6610831d0b7f93683dfa7ff43487b988e65617a874abe0 +e193a8ef6f454ca1aed38bb67aca6d08280d421b196d89938c0582b7cde74dafd71716f3818940af412d4a7ff3960a8517aee108ae03576b68ee7557d35e6f1ab823d124de7243dd02b542591f62c80d822608572889573e4c9dc62f99d68e07800da6f83cb6f5e03d1f2ac15f90e38b4f25e0a75e354e4b60cc81c0bbe81d39 0059b1a8fb84530bba7a607ee88310e31bc6ea6a6881603567a1081a05a3a9ff87e719ef 92237c0f2558293be2f6de07608fa50344e0eed3a1c7a5fcbd908fb8fde230385fdacba1c319468b650a0916dfc7c028 +8a99b9db191f6cabc88b430bc2293e6774d5180f019d871839289e25aec29379f14606e742190b7aa062e3b29fe0254146d9614856c5140c7315015abb98ac00da2c7e33cbcc82c24b797366f12767322c4381454d9d1eeaedb616b0ea5c66d1422da459f18081f4f966d05ce279c6ee69b1bf94b8388d38d4b770d9ed69025f 030ddc2c7a4ce300cc2b75f0f977033f16c1f8bb13aae3d494c381f9a6dc8622499ae4df 8a689fe2bfd8efd8af07446618b4547dbbf69698c9368d86a60b64aa3466fe73fa8075d4884a55322b467c3ed09136bf +5c437b331831530aa94623b1736f00b986172699f0a02a5e5df0008bf25341787e2e66046f2c929dfe0058c3cb89fc5bebbe1025bb1edd1ee31522ed568e7b5b4ca3991afdc76a68cbc2c4f81863e27fdaf6a564fab2c6354e5c657de81390f8a4132669fd24a48580c716b5b7961a9c091f614d11cf45dfdaec8946a54a11d8 007899928922fbfdb5407517725edf231d15a8b62d90b7fb6d8c8d20424850dc44f797ed 8e1ba18297b5fa9d5f1cb6a3c77e4d498f4a4e183df96bb8d0294ffa22f7ba3efa6268302ce2bfc010db863273ad4475 +91aa08567d8da4c90684dc06068f69deae240212842ff1786f04ec41b40d9187aa92c76401f9fcedced62876a34df82ad7c1e63b68bb2a972257ea8542bda6a7f1a020c9b122943b6d651abda8b8d322a8fb762eee376daa2d3637a71ed6c4f5cf96f61c0da2d6e1dda3370d80e51da2cbd8aef3267168c67359523faf910dfb 02a2af63d1171930758bd3e5bfdac62cca1a83a3b55a49b3f80cf0d9ee4b2082757beac0 8342e67796dc05e931650b49bba99684037b7ec28cf0614820d24d7161c3fa07f17d17e9fc5d4fd0e8b3f7c79519c2a8 +eb5297bf408c1a55e400a20a3c10acbc5c2bc6d6ccfcc0941fb7a6fd4d2834415a6df86c3a6c4b867d1215aeb8222153da8cbbb1576c92c07ca2c36d8f243fd911f9a057e39ee25832454e28d7ed52a8d04169b9b9677a16b32d5d211b8573a8986e9bf36d7206417ad2771daa11bc21fd7ee1029b65ff7c9b2705a6dc9cf9cb 035994e89e13916ad82608f74a639e6aceb756ff913aec440519946d6434af9a60a6af49 b9968e08d9a1cbc67fd85bd2429569cb36aad5021fbee34a8ac1160e2c75d275a3f4c548600191261df69826c8898f27 +f415d0adcd533dd8318b94560f86732c262ad2c6dff9dc83e2435543f429a2158cd2fbab0d96c027f71008c4895ecc644c2ceaefa80937f6cc6338d15d36e459a16bd9387a361a6d800acfd834ad5aecf442e30b70f5bfa164747cf9f89325b80976052a83a5e896c00c54f81472b14329cf23bec10a8e693005de2a506ba83d 029639da33f48e4fb0d9efdf50bba550e739f0d2476385cba09d926e789191b6fb0a73ff a162c0e63570b1b1722e60c54ddfe32f74f5bd446c6c1ed66fffaffb4a295a944de925e161300ed01f0711c3bb81efd0 +b178d86c9335b85e02178fc4551769db589ab91d823fac219c7e14e2f029753b203962389476723832f8d9631dd7764e6dd35da290afa42a794476f5c7727b3688aced848dabc9954201578cc7b25801710931f45cba1199d3788d64dc0188412e70723fb25b8ecb6718358150c4037b5b81466dac1686cb5270bb1c72d34bb1 00583a7ecbf2a975a32d07428d27ac82e5dc13d1466c4fdfc1e6a05a8d9a289f1010617d a6c1ebcd2af270620f626ec295a94bb897c7faea37e9fa01894bd8218ebc18e4ee3865cd3807d76a5d80ed7dd00ddd4f +c8bfe9fa7c848531aa2762d48c153cd091100858aa0d79f994fd0e31b495ec662209a9c8761cd1d40c3d8c4262cf4dc83c4a2549a5cd477726ab6268b4b94a78b1c4a7e700812872d7f41912a723dd9abc305420ea1e1fb1fee41bf643f3a24abd6e8fbf6fde2475e290527724a6f99fd75374bf7cb01b34d3e60d8db33c4de1 00f817ab1b49131fb9bbe8c112c25a36f064efa85de7506fb9cd29d81b326bf276277f7f 98a220dcd74f6d827a4d2d76bafe803a6507a48c0ed8fb70f4a07166f67d106363761ef900a59d109259a18c56aa40a8 +9a5f563d0f9fd1f31f3a822de628ae970954f4e71292492d727109036491c29e66b9b0f2c90c26abe94c08502f5e923a9ddaf6a7d91e9541ce90d0a49f03ce4e4769753d5b7d922e1ceaac4b4cfa4262732a09550aa076b8ff9d46a50fa17de17e3b6bd606698464d116fcd5f1ae11bf45b0c48d3b738427cb47b0d1272b03cc 02782af76ffebf3e2bfc0576b70e4f4bb87c762e2bb230d278ce776310a14f5b678f29af 9283fbedc142723bd1d96ad2f85cbe82792b34c312db2da9bd064bb958f7f6d5951dc7d3464e7bb289ab0cf81eb39487 +3d6b065721da9de82cb33ec2c27107eb399b1e69ac8fa51145ed4147e20d72e27434104e76af988a3bc94f55e36677a05182fe2376dbe38195fc6a30673a4dca87336c7304f3f31d49216fbdfea00fd1e105d8b0c13ab11f8892e0045e915c17dfaab07b24ed21b06af5a8cad4f45fbee5a25bb6e87466a7bc422c0bb896440b 031b827b88f14d3822244809096157df3c0aa99da90c00cd9f0b18dfe306f6881834e6b6 b2ba144dec28f59bb5740fc012d574a429cc34e4806413d50cd9c2b87fcfacf1134821b2c7a3f299bb5a9bafa51bc277 +d125f0e2e6135567adec9e77da2afc6862e28d618416632ced829d14ee8b61116da59dfb44098a40a0b927731125617e3d2f32cfbd1546a6e758c1ab6597e75db07add52ecb61d37da2e9ed04df95b36ac249f4cbd794cb561655cbbe4b34834c497b3d392d78ed0db8db683aff0076fb6e43acba3fa2b91210cc6cf3fa594b0 027da4916f1c471cff80bfa14d12aa10270fc3b26caed010c0111f6e5a40d914a3927763 8e3761742fb64cb723cbc8454180f0d3bf58a10ec3141317c9d29d82f571e4fc8f965db238dba0b16b4f74e6dc9d3e2b +b380f97687ba24d617a42df1b14e5506edc4b62dfec35ed9fd886bb769832cec7f9adae10c21b7cd9152588797b4efc6b2b30a873d3f25e683ea9be070dd69731949a51121e534fabfa3a2eae0ee90a454182248bedf2595cd47ad08614177d58f7a773f5023b538f5f568682c83fb60e3fb1aa859948d01bf7b214e7f2dc719 010608eb51dc0ee97d6e488a23c582ecf0ea1df9a24db77094d87b3fb6ca98507280a934 8c666cc08836c406ae7634cc66279542ea22ded4953a027c4a7c30a510b31083a192eee920405fedd1cce4d23a03c953 +3f9ec57e4228e1a6ec49df02c58d756515305e48763ba1dc67298be9a1548576c28c82b4e9b3f62357d9b3c522b16d5c496a39effbdc8290edd2cadc0019e6b9fae1e61238b13b6265ad2ff413a5a0684babdb0013e7632051455e6fd943815213c555dba96cba8911e006bfddec6c3353065004538f37e48df9e339498d85c6 0123f9eb8babed548df08cc3afc1d3b3bbed52b538d4654f2088fe76062fbea75b85a560 8845a592b39ae4f601010a992b7a4af37cae538cf7a3300038daf4702748ca38f447c274fdce56c6c417468aa5de785a +bdbd7b7bf3337bd9d21a3c6db379f95408c17e49dd394e94737ceae889f45dc0ff5d48cadc53703a16b5589939506b548f8dfd34c577c084f372166cbea320c8fd07c809b211e0749ea639e68f890affa1569b66bd763c7c710989e491011371eb1d93ed9479ff0216b7f79c901a2023e2cf80b565d1c0517e73117190cd2f02 006a18e626452111922e02e31d662f4301319946a204ae8a34f06b91dd1b5b96456365e3 adae006162c9a0018104b2a2bea5735309601dc0648f3a2560e9f06611ba75a3acc9e4015215e38b86383f42a6fa9940 +436b288512ea57bc24f84fdd117da9dc1858bae8c11637f99295d88fa9d05e3c053a2584a6fe200ad190b3077d9a1608f660349dda405066c1562f6897ef69b6b674d6bc11fa470d0b96a7cf8f6e098c9ac03b0ef415aa045867ac7c11d16cee78ecf08850ccabf70f761682b561d0d0e4a889d840dc74932648ca2fb58259f7 03307fd717015b12a2dc76ada21442ac1d97519f66898b214c2ea317ab0f0905e819e4e9 86d5873e0a0fdcb48525248f171c64c93c475498735034af6fa871908892960a777c3e0a87c1760247479b4179f95b38 +672faa156dc188bf16bf8933d65e091c633f294486049ce96a4a403dca28a149f4f840e8bef47412285363e9e89006614b013a41baad9885f1d9980cc897ffbd5f8a7d0e63feaeb42c07776efb307ed680ba1cebf470dd9bd8a2a9efc2b1daa569524394f9a50398add1a5bd2f7c263f9e63c2d49461acf98444fd23341ce78d 014f9f412e3c7d770626e800d43cfcbba3ae6aec8563af748e8a97b67d244334b6e6d2b3 a9aaf7cbdfe2ee3fd5159e0bc1ab02bc8f1192d231f6901477aabd40729019f1cec3d628488f395ebe79babe9f3925e6 +4321334cc8ee44f1cb392a4b280a95561809dd3639ddf43b6e11cb73067597988d95b8643d86c76c3c6b932d9262b9b8b55a04fba0666dd8b8ff1e8fdf799ae3945b6e30d3af3966f1a6d634d5e012710d66cb447fc3375130968a2e1e647780aada2609d87247c90338dd71c3bcc3902311caba27d5d4ea4d73ccea960d4bfa 03091a6a8bdac1e43542dce752694972e734dca31c061c7d1000754296d0748055db3f09 8a27be1477c0d829fd8311ec5c4b9fc56e18dc938fa6ebe7d328ade87ce8ba9f66a2e6661e1d92e8c4271032f5d968c6 +2087e22094570d39fa937f15a3ef0601709a66666344186a33b487d041793fbb9709a95af250b1df0762ea98e911aeb3ff1fa19f0aca53fd4179e454e0e91636e55cc5b17cad9e1575c82ad265dc34c4a66b7a31ecb9ef9dc756f2ac1d9dab35369a6bad4a0f47e629daab91addc6d297d1e5d81477b3966d8c3b607ed194d88 01195921b91353db9bcd00510efffe009c94f6bd8d790f5fb3e5a0101c9ca5d21c6ef2eb 87a67b1ae89526349511d444aafd24f07eec8158ee775f9d8857f42337e3b702fc383934bdd260abd1b42302b571a14a +15c7bca449a73b03bbfa783f5a91ca0b7916889a5d99d541e2e8593c3b176a5b634ba20b34407fbd94ae1c1398f5313cab7402f3bcd7ad277a8c66d09a6df5dd086b20a0a3823fbbb80980cd86bd13e527eee15656cc977103e80113539e26695addd9eef6a1f56986168d9a53f8b5de833f8962c3826cca106ae9e8c00208d2 029dc20446e9abacb43823e12a83737b46e6e577466b5a3925e0f9d496824dadb4d4b50c b1e86695207765c000632b8507f5bafff835cd057a9432bd0f27f9a5ef7c9197d225aa5142fa5d4e3f00f597c06cd783 +d12fbb82ee7a57eaf76b63fd6bc6c0a65c85f135f019d43ff7bc295cad15d53729d904fed63d69d3ffe8b82c0ebaf0399e2717ece40e011f710b5db46aa457c23b85545953398b814816a1e7a8ab5b0b14c4a0451b0bda9d0d2ec4a374bcaae208b7fe8056bfa17d6b7ffd4ba2e9179f49b9cd781b0c06f6ce3eec26cd428cb6 03b9b77d19a42e9a555da8ab70aa5638890b2ed21daefa28ca6323fc658662dabcbfaf52 a99da29ecf5feb86090cfe6dc67b79f788313641887e7c95c9a8a7e566b00177048801c07eaf4d016c9b5c520a8b517d +eab0a37915c6b43b0d1e3ef92e6317b3afc8b8301b22f6059da8271fc5fe0e419ca6097daba213915855631af64e10d8382d70599d903d1535e25cbf74da3a12ba2f13c33a8562e0db03edce791f1d39af8850fd1feff0eb25f9ad0a86dfab627b96e65831bffc5f6d9693d20493bc9dd6eb3e9325dea50b055768e8aa30d49c 00b9f8f3e89e9c1ef835390612bfe26d714e878c1c864f0a50190e5d2281081c5083923b a76a2ff7c170dd218a6a0ee1a3125e815ddc4dfb688527da05ba44948199f706c0e518bf38d6362f14679897469d1a03 +fdb93afd5dd1e3eaf72c7ea9a6cddb07fc2054499ffe152cb2870163eee71ace5bd420b898cb4fa80ea53fbbaece2a1eef6427b632320e9c97e38acb16b62fdbf6585b54fabf0a703307ca50f86387bed1815a05b0c8991e0743d10cdf49c8facfd7ddeb8d4a7b706b5a29e1d00ac88b0ee88b3153185495ac8388cc70104154 03a30a1c15b9ed71e102341f97c223a9b5ea3e6a335861c3cf407ef691a18cc639dbe74c aab9fd088b1568fc9a88b80b5bc8e07d8d7094bb537a95ceec404a03e96316ad9bbf9f1d380408f7bc511c38871c1b15 +c78e35d1a5b1bbb0ec21e7ba7b7c74c859d88f3e100e40ae34128cf093885dae4e87cd09f3239dd8e79e25305220880dd352a650225d9bd193b9b84e488c458b0b5fde1af941c0c9fdf952d2fa41f665918dccae27ab7923da4710f8c27ac8ed424992568dd6f0a6c3ecead21650ed162e0292104eef3c2d8551be866a88d279 0083330123cc64c11888c1fd388629d0b329a50ef31a476b909a182c930ff02d0c389b93 90c7e1170bde2739406ea99c9f4c217d195d9bea80f722eeadd92146c3e24d97d52dae79e5c17d598d553cfc7414f627 +e05435f695997229cce314e50065f3c5f71981988dddccaae6efb81f936b22cb48813f506d1edf5ebd69b0be34f278592c5935f0f6db0cca1ef9d62834fbf3c4c03f4da0596cb4d67b7b767e85dde7b7c6fbef7d89babe6f97b876b33594a9e36ab87079861ee556fb03274ad4af527342a4794192b8933f28c6220f954c77de 01dc2b656c207eabc9e0d6272099babca8d149c9c4258b779c2f06de75f76d77505271c0 aa247bf4a9026c71edb316c8024149def30f220ab095b0cb0139e0900fccf9a0064b506a54289e25ab2cfcb389f8eebf +0f9f36477076c4b5a7d1ceb314a397fb14646695b0803e36e98908c8a978770269f165a1fed8f4b655d4efd6ad283d7f5d51b6e1e302d360e8ebf4e887c7523a757ffd55384e114bbfc6b7a0ec8511079507b919065ca018573418f9e394854c5704227772161707b4d0246ebceb91192f0eb2ea994ce61fd98a6d14cc8246c5 00081772348ff2d7a3fd57fe703555ab2e14f5d203c4cf0292f944e827e884d95f3b1d83 a5778c2d3382c8d0bbe3e9f10c47ef8657bfa01b98c9f214b1f06016f18fea909b26fa237a5789dd857ddc3ec49ce002 +1d38b1c342b6611dbaf412a66c1c0b8397692755f576df33b31c2bd12b7f0707cc423376391f7b00aa4e7b7fe54532e2b39c3c5284b9c8ccce48eaf9308ed338992f1d4ecde6cbe352e46339d7d602942158387881d9b493fd40cc59d4f9b53ee4191d42352c6f7bf32c331f0c5afbd44a92901a4b713c7cf6ccddf7de4cc6e4 01eb6bf2ca1b5ffe6f6a795733eaeed12de6e87c53571e702635b9dbd0d96b47df4a005b b6f314ac99b594cd92c8b624e4b1c9f48da6b18dc341b07cea543acc559473dca5275790dc9c781bea2aa7b18a72bb7d +3353ad05ef90e9762bcfedd6ef44a1e8ea0392ebef30cffd48ae620f3e567e1cd44882d514e7c6759200d4bcab18afd3038c3d3f8c50f7bba32a04eee5a4b1cfb8c349939e4efe0a46fd047d02ed000d8fa1b98b0af5586f120d9ad174b3aea33905b979ece1eb3660b1e070c8821b32df41904ad68bbd8ed247aabd94066f16 03b2a3e65e5a306bf8e3955b60e856dfa9bf68c1275a678ca056207a0ec67c96eb3f8309 b14b0f51ea5564075df1b027141e09b79803dd57d982f7c2c35b962a763b092e450283f90be8cd3b97d4d490f968796a +e7ec162185fe9a5803c6b03d98041422315ccdac67e48fbd07a1ef3c5661158710abc6791bd0a75d56791b4ac0e7695d53c5989d9fa6a3b037583b2a80d2b154b024f1c36b63548be9afe1d51f2f68b2ba94d4ca1e69a35ac10e15ba72242aac20f7526b12ff9d3cde9a9bfd70d55adf9bd92c66d092d7d08e9764c84bf7f329 01fd4d1af0bb7c79ed5fea7bb45574e46534387bd916649485ef15207352d7302e81dc01 aed0a23fbbf1b5b7e8c4938b41ddbbc8d9c147996d08ef73481b66b0e815c81086e20a1e9133a3a1ed3df9173cce803a +87c8f2e3f4fdebce0ca9300fc1ebcaa934f51a12b6b8f2cb6bb6eb77965468663044afeb2a1334cb5a81e74b8427267f8b34b5e9ff0cf157a9f18be2b1942e32ca61dc23ea13c3f9fcfa16df8fe05e067938b6994982676463fb12842d4ec532cb904cf222aa805dd0d86ab9a33a83e294c6d81e8dfa273835e62e9041dc8ff6 020380b1136b5283e9b7f54b7535ebda33b129ceb177bf5d3d07b1daed5edd9fb3862530 9864d61b3ca2e6eaecd21a393fbe58710e06284393094047396bb0c5355021871b480b6fe812b1825feefd15d19cd74e +2ac53e8a50c4afe3b38904255b7cbf150c5f79dc15932dc0ac9aa631521f68a0d4b6bc5a04d55c99a36531fd4886a23a8d99f262ecd2a9feea925d7a96ebe9b6979a207b7f9378afbe404fc8e959b0333572a2c911f8743c0ba64eebc7ef12fe5435d2cb0e5091ae518b6e4233489efe3c16c6f21abf4e2c6808b733914e5a7d 019f815b98836948e0a0dc9c30828c31b13e175f1e79f23d084ae1bbe64823f4866214b5 a974d052bcd3c39caf54e912493ed6a38fd52e7ef4e06e6b65e1b7d44584b6b40bc3f1571b7b6746a9699466cd7a15f0 +0b201469cac4c078f587edecdcdb6efd5752cb4a3f43ab540463c4d908c27527aa3592f2f9acad85dd94a3c056bd28618317ebdf2e7dd6c5ad26fa3c31dd8e5c50c60418d91c93bcbb59ec1adb1db791f485ded78a5cdcddd23dd1cfa4f13443468d8a5f2d648059b9c4470d0f4fe7733d56a28a2c24456b6923703ef32cf0b8 001854e954654e726cf4bebc0e5a840e8809fd716059211c6ffeaed36829808363164684 b266fae49289c469fde6a7394e557ebf4da261503d34f0d2202a4e3391027b1c155a5458afa3f1b681ca378650c78c70 +fc5e4dddf4c4a328b685035ee79069770fbebcc56c14e31afb4bbcdd5220e025f31eba794fd6c05e64f19678dab33ce4f084bc32790392f14bf35669d75b6466b4214ec30d58ca90ae285c9058f5804a1fc9d7a995958f2a0e84ee52e8a78b601bec04ab607ffc2091749cc548c6754ed14e2e5f92315bdacaa7a12823ef76bf 03548f8020819588b3202f4c1ac62eaec6a47c2a19b2900c5a3cf5b4ba5804231141c647 afb2683649b180dc83439b9924faead001180e4b93d33ee11602b14823f29a0ef88eca5bc52edb3c4d4f10d3fa25ae9b +284cad790e6207e451a6a469cee3befc3ec43e047cf91b9dff1485718aa29de36a43f7c51eacd8589f0c3a96ec18e8ccfa92941b50b2132e3612d5b45e16f60d411d1c53e373e1ba451352e28970ada9dcb9802102518a385dc571dcf6900971b00346098a58042e0d1d129bd6801fa640a895a458a45b31318fe63ebb30c6e3 03cc4505005c41142308f1489226b7b542e2e7f24f1d3089ff6b92a4b0013f490ad52e60 95248394b7fa9049551653795d1497d2385236e68fe7ad82bf7b4f08f78839b68d07e142ac757ca21fbafd7bcde7960b +6d46e57abea9d115deda48b69fe8e0b36144df2f6a659509ce1b514c8cc4769d46e5f71df2a084f1db4a22fdd3ef0c2f90394f2898ce291b9f279c0664aa01419f5f6bee1fc1299871b27ecd57a5ac548f99d01871b8c238a6b46044c953b2e78e22346a0c7663af4db62799038ffb5c21ee512e26d01e70a4ed967377ab8405 0144a2fc8e0aa63506e14e4307df36416f963dd9da78655832f5b991af8c3eb97df78efc b8ee97357d51a66a5bd57af14109990be093e1de4e728d8083e4f4a793de2aa374355518dd306264ae3573623ed80443 +dd750b39bd8753f4e473c4484e2b36ce2da7576813ebe05861c339ffae1d029bc793173ed394091c00685ad82f0550cb21ed1c68f0c27cb7396922239cfb886647af204e88a9101b7453a8ab662e270b87a8a13f2fe61d695597382cabeb781933bebfd7d0dcd33f77266e43e32d937f2dc89f67525e522977ce73e9ad36c8e1 024ffeaf139043ff25a395e4c560c7680c1c2155191378917eb25194136b4a69597dc277 a9a28a1f615034cb99bff5e26a6579d70f16acee240b89c15084827c4003fd8c1ea0da9589284175170bb1f3e0871e14 +4736e59fe5812f63737eed57a570182c065538abd9fb0a1c9c2059199e7052ba57d84b5fa1cda2ad9f216610361ce1dfb9334816b6bea509283756a03aaae2e5b0597f492d078b6b015a40c9785dcc5d2ae266176980db04f5cffef40e16661a50ef871c5f531d73fd5d114fa19bae9dd2da4267a131fc31849da38c2b78d1af 01d1f2e0f044a416e1087d645f60c53cb67be2efe7944b29ac832142f13d39b08ac52931 a0f205792d0b42818ebe5e00d93d2e60826cdfd1a721f9dde11760f6cd2236d98983550520005844f32aad2d901055db +e573fa7d4bf5a5601e320130de91f4ad87eb7ca6b8998488afcef69c215b0cccd221b8b66eb0af9d699af9ad6c4b4a580e82941f31e4c0a9bd83995dd076c5ac9bebb34481061e7cb1b26f6e8c6b26ee4bdf9887f7ae2eb9fad3115a21dcc96acce85d23a040c0ebbe0a56e75714dbfa803d6e279b2f4280bcb993f96ba321e1 01337362609df74d25f7adee382225e6a04dd6ee4c6b45fa31499ce9edb0ec046325caf9 8925ba911bff0d8234fa17e374b229fe1a21ed4633c1cef5774935ade2dd9160e85c27dd95251c958d5ca8219f17775c +7862864d0d78b44e2a28af44a0a16d8e9b1b8c4b794db0410c0a863ba011018ef43e1e11f2fcda2f56fdb2a69cc817df425c9cb3b458922ba00d710190cae16d61af3c304a42fbb3d0c4a74a297253fccd70aca414865b41f68b01c561be281265fa89f63f975d3101334886e85929a5a47fa8dc459b663548faf8ed7484958d 01be00aa0afdfe92e24a2536594d4b41701ad4dfb223aab35ff49310bdba7566057fe8ac a9e1f6118a0177126ecc558df904e1224da4280e6a077aad3cc9eff050dbc910a5c4dcb49343e517e68b1b898f0b7a60 +e73c96d1a84cf7cc96065b3c6a45db9531cd86a397e434072a38d5eeb9a90f62bf5d20bae22b926cfe967647d2bbb5dd1f59d6d58183f2cf8d06f4ac002ead026409ca6a1f868b406c84ff8887d737f65f9664f94801b2cd1f11aec336c0dbd4ec236d1cc4fc257489dc9709dfa64eae3653ac66ab32344936c03eeb06d5852d 012ad0aa248db4fbc649f503e93f86104cb705d88c58e01d3ae0099590a69aa006aa7efb ab9e6a99d558e8924212e33382eb1a0b307c3fc47d888eb7a058abe1ca4c1d2e4383ae5cb2b4f8e793660fa7ad0e5f2f +a73fb0aaec838d011110d49c5e94395ce07408917bacf7689d2cfe0948c582214b263c6b80e0a55f1e159086817605723740569eeaa1bae96b979679165c5c35ef2142525e943e595e6b4b160acd7ebe41de19775346363f779b1f80b6d5f0785b92a648028e456af8496102d19dc6526247a654bdae3368f075fa9ee92b2f4a 02cfbb8f340cae8e2e2322829148981cd9e509b0c65497fd8d9da5dee9dcfd39b0f7556c 820866a734f93b61f2fa02912925492363e5cf277e18ffe1bc02b40a025d23da50a51135803de795e09b7433a9551c7c +eda775984c7c9f7db47af30dab314d070fb77e9b623baa6b73e2cbda800f167b20fdc2e7219391efacf908f4ceed9b9b6bd3541b52ea087177e18c97391214758cf6455311fad336ab56cfdce57a18add8cf85b0a0bd6fa7297dbaa34bfc8585b0f06a0aae055186658c227e19cddb65de88d260f09f805c2e8854dcc524189d 0070e82a1f3fa6158d15b7346dd56150faee5c98c9d07c996e01a06dc9b211b12ff62d60 af698cc851eeea08793459a77ea0063fcf45cc7d6b6c7b6aee27cda1da1b6f1b33ecf92bf126cc06996192a8486d6847 +a4a13e0bfa761b9bf37fade6570d41c161e20558874911ff3bee38e5649849b159beccf321c6bc7243f99c01a2fadbab9e157e9952ca65d8ea676c74fdc976d00501c626b8465c6cf0e4fd1a7d1260aea987161b821528b0b423e62ecc5193a0a49442b0c3e4ec9c4786a3a86b199c07dd3a17033d430d2c83c100f54e0a7c31 00b471bbc5f7a07996e370da4a09e71e2119ab3a562a273f079401951fbe4df39a4493da 96cd25fbff2459a4332bedc9d4a7ac21d8315e1a4d1d145527f55c0c82c12665bc228851315fcf8140ac39152a7a345b +7ceda7a7248640f7055309ae712c19d741375d6a7e0608e07f0135bb830dc3e8863ee9e7a75331a5e1bd38c42cdd484d4f45a26c2c1d4e05ce0d0ca941f4e94ecc6b371102f31633629e9861de558bcb6407d66eb91f1062ac0e0409db68b9f2855296a7f42fc92359a7dae16c73fd2dddea52bd866a4d501aedd8fe3b3ea733 03c65cf80bfb507dff52f9bf2f93df0642020d41619b3990009409e7210fd7130ac44ffe 91eace68aa8966b85b849860dcb6ded20672fe7c488639579214928cf7f747ebfd029393550b4b8534fd1f32d6be3fc2 +609815edfd58c0e26a4b06dded831d2f33466a130754b96d8d7c3b4d99fd4b0789ec719bc25338d0ae8c5880560c02687d352d77c291e406eae865c3b26d00f2e63dc644ce7e01d6e96ceeac8bc1eeb257d36cbb25d89b5fff6e30b6051506a0ae54cfaf6214f30985d54cab78f708029c1fc0175bc58e888db89dea8d300abc 00f4d33a9c7e6744ab3c441828bf0f1866ae1c042cc54abc754e3801263a96cbb3955dfc a234e40766a3a8f686cfd227bfc8685bb51f12cb49581c13a546dc05218134f22e764430e9143ec0ec74eaab08c8b948 +82d8ebba707b72655497320200ce719520c1ae7f46f38122958fd99322c25c9f4d4344bcb77a6658df0eece5df163412ecdca58475d56b0c2d14a0361e4cef458df146925d473a43692b15e9bbec550f1bde3444f2a5b2ecb55d2abd273ae999f16a32333529d94455e485ca4585e6b07bedbfc2bd1eb766abf0d28bdb1ae6ec 03a4824bdcea6a144d85f1b194431724cc49849b6cb949b4766d641ae95477d1ec3d1464 addb857a103cd061bdd2229af0a02573403a5bb5469364a90df6b6aed1ce7e2db4b5be58d5eb9da1dc7c09416ccff671 +9c6fce18a6a96349b10c9f2f5f1505c8ab727a650b44bc0782a5f39fcb48b45fc7c1b82180d5f229b8abfc807071f931d333d265fc940c93fae7520d8d40ef59d7c6e3678c6a2ecde52b6a8827b1ffc6ed269cb9832feb20e593a7e3d4708309342875199eb2ffceba7ecd707b122516c815e83e27872eda812e3ea52ee3c4a8 027ba543ea785df1d53d4ae4c1bd0a3a994cddf0c25d2b4e8ff17ea7aa00619e858da1a5 8bcf645a4df9b545130b67199c68d508323c6c2ad40ee43de58372ed0040071650c3cf573a8858f7c54bfc197e9685e2 +5eac15a64c7653d125605869012b8f036804817aedacbb5a5248a595ee0c12329f91e8179c187192d3ed0d4ca2e202d8d4d9c93ad3f3ed931121c193af5b47a8a5dc39775b6c2d702708e5134f77a31bd62eaf87e39e6fd3f2b9f782c3057e162dd53b3addf92bf0ab99835c7f6649abd1c5322a1ebb2ba313df9464a74c14d3 00708d0907d14dcd5f40e2903e1e90e48a0ffaa6d4d9b84ca14df4e985c294f74eb9f2d2 a9cd92ef9873177ae4ebaa6a21bb718d02865a41985df0c071b8a70562e1649e922a245a98c1cc3a961410b975b71f74 +df735a7e60bc267b18f313ad56bff830be5ef119baf43ce27c6368ff1dd89f010afd4f48740b11c12101c5903bfa71d6cb3d6462cf875bbd55a570ffedf3564088dfe8c8d3148231b78b5adaa6c53696737d4704daa59eab8d986fc6e519e81540f201e77b923a6a4af65d7173635b3b19b2023022186a7b8e869e1ed51717ab 021fb0a6b94080da8b8299b87457dc09d21bc430ba5f3359d92aacc1151be9941739567e 89f8d056eb71d2bc25e0ca964b41727de04eceb854badec5da79b9b8d867b39dc92c579ef6c21bf52a0d29f3e3d0833a +bb107b0eeaf175a786a61db923bc6d51dad5e922e85e57536118e032167b197b1a1f62d9bbcde04922fde781665c1094181c16ac914cf6fbbfb27bb8346b2134f05c55a8c6b9b481273758e380666d6e22c28577c29446cecc5c3df9ed9f1be060ca55ab2b7fda36a147aeb46df0275bb923e0876b703452fab42f6b7ad2ceb0 02c80151f91301fb6b0c7685bd172f20515b46bf94dbc4160d0720fbaedd40ec00084447 a3d29edd47dd7bf0bc301b51f4daced9db8c92f2f95319b86c34bb8503e16254b4b208ef58fcb116bf0d380e71c1881a +f47e49ae30b09b7666600b7a95e81b0afa1553da5e01fd917e4ce1b58dfaddb8dc8c03c0f5591f533610deb6a7bb5faf5dd1ec4103a587a1a4c58a110a706b0f301a5c408b3d984c210d5b4a0b347d2b5447271f25b527b3c7864f7cdfa735dfded47c63b723fa0f0413c57a24ffde9a95c35f743f892ab1ed1df704cde82d9c 01538abd7ce8a6028d01604b1b87db3aaf720e04220edf4d1d28c2d731aa25f509e58f2f a5e686659f1e86cc4202e214109018c3c709b79ecacc4ee9a7bbeb5cf337d205552f8a8d530db2c84ffec2ef1fd10619 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B283_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B283_blst new file mode 100644 index 000000000000..77b80163e0ba --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B283_blst @@ -0,0 +1,60 @@ +067f27bbcecbad85277fa3629da11a24b2f19ba1e65a69d827fad430346c9d102e1b4452d04147c8133acc1e268490cd342a54065a1bd6470aabbad42fbddc54a9a76c68aceba397cb350327c5e6f5a6df0b5b5560f04700d536b384dd4b412e74fd1b8f782611e9426bf8ca77b2448d9a9f415bcfee30dda1ccb49737994f2d 0299ff06e019b5f78a1aec39706b22213abb601bd62b9979bf9bc89fb702e724e3ada994 afac4be5fd44896ad26a858c637ce08320869636e9d0f1fd565b38585d69d0f14e3b0417473da2cc05df7a6aea1cdbc7 +44adcb7e2462247b44c59608cbe228ada574ecb9f6f38baf30e42b589fb9b157bb0560e5a2aa5523b71cc0d7f583b502bec45d9b8352f29ee1842f42a17a5b16136feaa2efa4a0ae306402940ecd6b71e57d1467c98e7960de2a97f88b43487e4f4016af1292381d70c18c7e6eed99a14cdeb5b3caf73688658e4c5b54c81e08 009c2804f8cab768248fb3fff8a055b3f4585c00de5c1615a19f9425b9432ea09afba8f2 987e06f23d7c05e1cde2ce2ced984a8ada1630a7e9ea504a468f99be9f9cc812939191e23875bf127f733ca72a937d3b +cffee6252c7eb6d91d8fe100a1e62f0ad9f862d78ca2b747a6c17b8c9ea8980dc239b3b673310e6e7483582399163e39d889abc1a613fe77849ebc09b4f7f4fe0688b8a9869ae918a88294c7ee199be50ee9460db14725ae70b449d0cb48f30e7d817ec02c0cd586119341dba0b74f0279330807cfccc99c8c340b72c1764a45 02e625a6bc6d0ce7c06231de827068bdb0abc8ffb57c82b35ee3a0f873b9473905974d34 b0d5cf60fb77de931351a36466854c9ce7a97c969b84164e3489897ce80b2c825e5c788967cc58d09b979c8c94fd36fb +d058ab5dc07228253707ef224897ea0fcd09c3d5cc91fdce9e03c1c59c53fb4596be2ed929c7455e67ac7f4891aed3eb06ad88f2c4aaaabff045b959f900d1019d706b60526375851bb891494e99995928e4cd51c9616aa651ec77bd7e398916bb9ed3156391bf7fb1e29181e2b011dae2edaf803607def2ac6b194929a57f45 0376ac24e1b86f8a55c052d92a0bdc6472fa03acdcdbccbf7c321ec0ccd97aa0a66b4181 b39947f3cfd52568158038398a96857bf7b9c5b923465920c2fde4d830bb9118c386e5dc512ac9b0ca8ba467d5068881 +c86f2cc7ab5df5cf1a236fd83792769474cef464032800ffe98a44cf29dbfb6f24088160eb31a11a382ff2a49f3e05e983462f5304272f96c0a002b69af3d233aebe867ee63fa46666760a6889d022c18645b491f8d71b6a3b6b4ef058e280cf625198715b64b025bf0449445d3dd7e1f27153926e617bd2c96638345431d1ed 02b50a6395fc02b9ac1841323de4520292f913519bc0d6a471aa28021322fc4dbcd7b802 ac6b5036d27f2dab15e56a7de9576b9c61f412b4b914c32b1758707894f2890e317de5af160a77d433fca0a700278b30 +c1328d8d2e5b6ffc850a9600bd6482518ddd9cee3fc9140febb72bcd444b0cd7e8074587d51b62cce4b3d4f34ad3355353fabe363369cf790db2df9fdac3a0ec4757e2dfb3b683eaa3e26531691ce765742e1c0bdc0e1028d347b6085fc459df0989c6a144271454eaffe413cae2ad7c8b2371fd2df1afffe56df727009765a2 024e5889722f6c35e18ca47effa9e415b1ba790066a91fb3c9f7b001ce28fc732b09bc23 9760e8ced0da0bf2b9cf8384fc04923c017719fc948dd2c7e5d4f4342bf594db77a8e5ae89b154ee37c04b0f6661a281 +7176b7013ea27e94281977eacb976bb31c753bf80fa09680a29128a6fc15234f79f0e9900aff3217ce9be72c378042c6c34fced0158740073d1a985fa25987fb218002e425868fda5a47de51abfd04de34e2b8634cebfbdc98e80f93d94096193eaa82dc8778fc23f3765c7acdad94fdaa272df0ff0f28190c10a462ee78ac92 0056d15b81f40b6378588a5efe43e21b95e18120d514bfdda0e7759a1d0766a8a35ce5ac 8d1e37e831d160f94a64693703f478f63fd6eaef8e8310127c475041215cc157ab36381f768faa70bb1625a68b7e7134 +4c3642ba040a9955b9d50dcd1c936688c17c363854358afa8ca49c6abd906dfdc4d89bb4cab0bbc363fb5b74e1f004d4b09ec9dfeed4c0bfb482a9061a1f487a3d79195ff7b65a0504bced3a28db0ebe8fcf8ab1ee4a3ae91324d15d890ac4c479144dd5538d2e36d3a587769ee9cd2d5c6f85a03362a022fe0efc4a3902b71a 012fb2fb5bf5f7e42a500154823a174ba2d05af71e3b0cf47fab46e673ea1822f1563def 843c21cceac1314848208c978ab1476261de774d3cc87ed99c7889e5aed303429f00950a5f84dd1d41b50f7c756e1445 +e471f39c18b081362adc7da47dec254dab8d765f005ac574640d78c14222639245563912d942f3be212ee3cef134407334c8fe3602fa0e1629de5331643d76715dc1b0ffcebd484d86c5211be4b285a31688b205fa988e6c15b36daf396ccdcc209c7dde2a732f5c31c84c7ea041408ebf15e56632583af0131bd7f531b5fc45 030096c54fd480647e017f8cdbbdef292e799f054e3279d228b09816a757566a744a8266 b6013393f90ca28382625d30e58872ce454d1f4655c38f1d4104894217ed164e6cbb6a3190ec92337a4c00669dee5844 +8a93fe53e83075c4025228540af7e96a588520da34e3eadeb99a4ab2f3dbbb8f85fe63a3b86c1f4ec912e665ca05b43e869985eae3791b91205afb1380e16c25b74e6793fa63e4a55dcf25dc22d03f09deddeb9042b620434111afe08c5657c7d754af66ad91a1b5423301b1e8e6389a1404060d1b6a99fe0f89598482979e42 00a1b7e9c8c2dc25b494b5ef3195b294e41cd3c2c35235ab42542bd3e2a52d5826662bf9 82b17922be99b9a211147a64340226221df72067093d01bacf0ed67674f305deea2ba5c1a1de7a564f057fdd4f4cc44c +e193a8ef6f454ca1aed38bb67aca6d08280d421b196d89938c0582b7cde74dafd71716f3818940af412d4a7ff3960a8517aee108ae03576b68ee7557d35e6f1ab823d124de7243dd02b542591f62c80d822608572889573e4c9dc62f99d68e07800da6f83cb6f5e03d1f2ac15f90e38b4f25e0a75e354e4b60cc81c0bbe81d39 0059b1a8fb84530bba7a607ee88310e31bc6ea6a6881603567a1081a05a3a9ff87e719ef 8fd3e24c2b5ec595c5077e2fec717e8cf2e0c86c6c03884e9ac3809705836587d5a6d2d8280dd0eeaf11d877eb952eb6 +8a99b9db191f6cabc88b430bc2293e6774d5180f019d871839289e25aec29379f14606e742190b7aa062e3b29fe0254146d9614856c5140c7315015abb98ac00da2c7e33cbcc82c24b797366f12767322c4381454d9d1eeaedb616b0ea5c66d1422da459f18081f4f966d05ce279c6ee69b1bf94b8388d38d4b770d9ed69025f 030ddc2c7a4ce300cc2b75f0f977033f16c1f8bb13aae3d494c381f9a6dc8622499ae4df 8e0bf7c0a594bb23c1f2abe17df1f2cfc43bb1f4cd120a14e28310ca20e059d8d98a49b4c3ab0fecf78fbdee9f6e848e +5c437b331831530aa94623b1736f00b986172699f0a02a5e5df0008bf25341787e2e66046f2c929dfe0058c3cb89fc5bebbe1025bb1edd1ee31522ed568e7b5b4ca3991afdc76a68cbc2c4f81863e27fdaf6a564fab2c6354e5c657de81390f8a4132669fd24a48580c716b5b7961a9c091f614d11cf45dfdaec8946a54a11d8 007899928922fbfdb5407517725edf231d15a8b62d90b7fb6d8c8d20424850dc44f797ed 9299f0d55b7af6b37944d1a60791cee01c2b102e5d45ab246fde86b7cc35de5fd45b5036c82866c18b158c5a0b9d9199 +91aa08567d8da4c90684dc06068f69deae240212842ff1786f04ec41b40d9187aa92c76401f9fcedced62876a34df82ad7c1e63b68bb2a972257ea8542bda6a7f1a020c9b122943b6d651abda8b8d322a8fb762eee376daa2d3637a71ed6c4f5cf96f61c0da2d6e1dda3370d80e51da2cbd8aef3267168c67359523faf910dfb 02a2af63d1171930758bd3e5bfdac62cca1a83a3b55a49b3f80cf0d9ee4b2082757beac0 97e89ee66ef3708597192b5cba1d2839773038b1dbc32f0401755aea8727e483f90b14699d2d2181578a7d752431aae5 +eb5297bf408c1a55e400a20a3c10acbc5c2bc6d6ccfcc0941fb7a6fd4d2834415a6df86c3a6c4b867d1215aeb8222153da8cbbb1576c92c07ca2c36d8f243fd911f9a057e39ee25832454e28d7ed52a8d04169b9b9677a16b32d5d211b8573a8986e9bf36d7206417ad2771daa11bc21fd7ee1029b65ff7c9b2705a6dc9cf9cb 035994e89e13916ad82608f74a639e6aceb756ff913aec440519946d6434af9a60a6af49 994f748018891d2087452ed0f68b1349b754666d15c2f6e2f344a0f6115661690f67988400678c1ed4fb6f665ffc84f5 +f415d0adcd533dd8318b94560f86732c262ad2c6dff9dc83e2435543f429a2158cd2fbab0d96c027f71008c4895ecc644c2ceaefa80937f6cc6338d15d36e459a16bd9387a361a6d800acfd834ad5aecf442e30b70f5bfa164747cf9f89325b80976052a83a5e896c00c54f81472b14329cf23bec10a8e693005de2a506ba83d 029639da33f48e4fb0d9efdf50bba550e739f0d2476385cba09d926e789191b6fb0a73ff b8930159bb1b6f05ae251e4962d0104f31b5d4e4b024855b5ef67b6cadff1cf0968fb5ffa897190e8416a1300c4b5c2d +b178d86c9335b85e02178fc4551769db589ab91d823fac219c7e14e2f029753b203962389476723832f8d9631dd7764e6dd35da290afa42a794476f5c7727b3688aced848dabc9954201578cc7b25801710931f45cba1199d3788d64dc0188412e70723fb25b8ecb6718358150c4037b5b81466dac1686cb5270bb1c72d34bb1 00583a7ecbf2a975a32d07428d27ac82e5dc13d1466c4fdfc1e6a05a8d9a289f1010617d b4e6b25f14d295e682b325a82932e1c1666a34b1182aa1a976c9c2e6e5a950c43568618099f3e968c249860544d1f7d6 +c8bfe9fa7c848531aa2762d48c153cd091100858aa0d79f994fd0e31b495ec662209a9c8761cd1d40c3d8c4262cf4dc83c4a2549a5cd477726ab6268b4b94a78b1c4a7e700812872d7f41912a723dd9abc305420ea1e1fb1fee41bf643f3a24abd6e8fbf6fde2475e290527724a6f99fd75374bf7cb01b34d3e60d8db33c4de1 00f817ab1b49131fb9bbe8c112c25a36f064efa85de7506fb9cd29d81b326bf276277f7f 91cd5ee1eb885299624f8ee5c4d574c7040c39e18fe208ba2567d221cdbd88479703a7ba26ca051e5277bfe6c5389719 +9a5f563d0f9fd1f31f3a822de628ae970954f4e71292492d727109036491c29e66b9b0f2c90c26abe94c08502f5e923a9ddaf6a7d91e9541ce90d0a49f03ce4e4769753d5b7d922e1ceaac4b4cfa4262732a09550aa076b8ff9d46a50fa17de17e3b6bd606698464d116fcd5f1ae11bf45b0c48d3b738427cb47b0d1272b03cc 02782af76ffebf3e2bfc0576b70e4f4bb87c762e2bb230d278ce776310a14f5b678f29af b35d719c67535bf09343be830d06261c124b2e80aae429dbdb42a75d635dba046977e55eb029f86de15c8d3dd6bf922d +3d6b065721da9de82cb33ec2c27107eb399b1e69ac8fa51145ed4147e20d72e27434104e76af988a3bc94f55e36677a05182fe2376dbe38195fc6a30673a4dca87336c7304f3f31d49216fbdfea00fd1e105d8b0c13ab11f8892e0045e915c17dfaab07b24ed21b06af5a8cad4f45fbee5a25bb6e87466a7bc422c0bb896440b 031b827b88f14d3822244809096157df3c0aa99da90c00cd9f0b18dfe306f6881834e6b6 b1f96ffafbffbfc636db0e0ed79db2360fbc27044cd368fb2f624d765f75ecde9cd3bae72263142ea8b1b305ecb6fc56 +d125f0e2e6135567adec9e77da2afc6862e28d618416632ced829d14ee8b61116da59dfb44098a40a0b927731125617e3d2f32cfbd1546a6e758c1ab6597e75db07add52ecb61d37da2e9ed04df95b36ac249f4cbd794cb561655cbbe4b34834c497b3d392d78ed0db8db683aff0076fb6e43acba3fa2b91210cc6cf3fa594b0 027da4916f1c471cff80bfa14d12aa10270fc3b26caed010c0111f6e5a40d914a3927763 a9b6139cedab64b415fad24dc91749ce24732764ee0b24a6571337c0fe6e99e6f92028bef601885d07eabade54811042 +b380f97687ba24d617a42df1b14e5506edc4b62dfec35ed9fd886bb769832cec7f9adae10c21b7cd9152588797b4efc6b2b30a873d3f25e683ea9be070dd69731949a51121e534fabfa3a2eae0ee90a454182248bedf2595cd47ad08614177d58f7a773f5023b538f5f568682c83fb60e3fb1aa859948d01bf7b214e7f2dc719 010608eb51dc0ee97d6e488a23c582ecf0ea1df9a24db77094d87b3fb6ca98507280a934 94cb55d9c1220883d38dd7e524e4fe36eadfd36eef3a49f12e058ad84c84f0693c0d6e1df3813f539244c71762a72a81 +3f9ec57e4228e1a6ec49df02c58d756515305e48763ba1dc67298be9a1548576c28c82b4e9b3f62357d9b3c522b16d5c496a39effbdc8290edd2cadc0019e6b9fae1e61238b13b6265ad2ff413a5a0684babdb0013e7632051455e6fd943815213c555dba96cba8911e006bfddec6c3353065004538f37e48df9e339498d85c6 0123f9eb8babed548df08cc3afc1d3b3bbed52b538d4654f2088fe76062fbea75b85a560 90db1c39319f23222dd0376267488f185b312de67d008dfa28f8d84a4fb989ffe092874893cc813178679b2cc07b3d91 +bdbd7b7bf3337bd9d21a3c6db379f95408c17e49dd394e94737ceae889f45dc0ff5d48cadc53703a16b5589939506b548f8dfd34c577c084f372166cbea320c8fd07c809b211e0749ea639e68f890affa1569b66bd763c7c710989e491011371eb1d93ed9479ff0216b7f79c901a2023e2cf80b565d1c0517e73117190cd2f02 006a18e626452111922e02e31d662f4301319946a204ae8a34f06b91dd1b5b96456365e3 b5d6f59dde236cc9dd272903c980c281e5d9d391a32d276d492a31c732a49be68ae5855bf2f90a4e6aa6f6085ff71ea6 +436b288512ea57bc24f84fdd117da9dc1858bae8c11637f99295d88fa9d05e3c053a2584a6fe200ad190b3077d9a1608f660349dda405066c1562f6897ef69b6b674d6bc11fa470d0b96a7cf8f6e098c9ac03b0ef415aa045867ac7c11d16cee78ecf08850ccabf70f761682b561d0d0e4a889d840dc74932648ca2fb58259f7 03307fd717015b12a2dc76ada21442ac1d97519f66898b214c2ea317ab0f0905e819e4e9 ab3df5c16ac80304b08be22edc558a7977b765f4ec36261aa0697710350fb304ed8205da75effbd28ffbcb8684bc8d73 +672faa156dc188bf16bf8933d65e091c633f294486049ce96a4a403dca28a149f4f840e8bef47412285363e9e89006614b013a41baad9885f1d9980cc897ffbd5f8a7d0e63feaeb42c07776efb307ed680ba1cebf470dd9bd8a2a9efc2b1daa569524394f9a50398add1a5bd2f7c263f9e63c2d49461acf98444fd23341ce78d 014f9f412e3c7d770626e800d43cfcbba3ae6aec8563af748e8a97b67d244334b6e6d2b3 8059239f3be20119c0a918730fe19c23997f607cb2dca66b9b0ab9dc12b2fb97e339f8af4153fa131fa06e62d69f11c0 +4321334cc8ee44f1cb392a4b280a95561809dd3639ddf43b6e11cb73067597988d95b8643d86c76c3c6b932d9262b9b8b55a04fba0666dd8b8ff1e8fdf799ae3945b6e30d3af3966f1a6d634d5e012710d66cb447fc3375130968a2e1e647780aada2609d87247c90338dd71c3bcc3902311caba27d5d4ea4d73ccea960d4bfa 03091a6a8bdac1e43542dce752694972e734dca31c061c7d1000754296d0748055db3f09 aaf6fc7abc372df6a2e748d6899886a0dd025f4807009169634cf7ca8d30276518e55fb9542899aefe345bbb723e70c9 +2087e22094570d39fa937f15a3ef0601709a66666344186a33b487d041793fbb9709a95af250b1df0762ea98e911aeb3ff1fa19f0aca53fd4179e454e0e91636e55cc5b17cad9e1575c82ad265dc34c4a66b7a31ecb9ef9dc756f2ac1d9dab35369a6bad4a0f47e629daab91addc6d297d1e5d81477b3966d8c3b607ed194d88 01195921b91353db9bcd00510efffe009c94f6bd8d790f5fb3e5a0101c9ca5d21c6ef2eb b7a23d251d3e719ff222c51cf1de6884a88dfcbf9a4e6eeeb9a7ee16ed30e322f30d820e0681514500bbee78cd02201a +15c7bca449a73b03bbfa783f5a91ca0b7916889a5d99d541e2e8593c3b176a5b634ba20b34407fbd94ae1c1398f5313cab7402f3bcd7ad277a8c66d09a6df5dd086b20a0a3823fbbb80980cd86bd13e527eee15656cc977103e80113539e26695addd9eef6a1f56986168d9a53f8b5de833f8962c3826cca106ae9e8c00208d2 029dc20446e9abacb43823e12a83737b46e6e577466b5a3925e0f9d496824dadb4d4b50c aafb519591b9c7dce40fe9498600105e21409204bd7e62d44459f64a20953e496e8bf5547c159ff29d66252371b8a880 +d12fbb82ee7a57eaf76b63fd6bc6c0a65c85f135f019d43ff7bc295cad15d53729d904fed63d69d3ffe8b82c0ebaf0399e2717ece40e011f710b5db46aa457c23b85545953398b814816a1e7a8ab5b0b14c4a0451b0bda9d0d2ec4a374bcaae208b7fe8056bfa17d6b7ffd4ba2e9179f49b9cd781b0c06f6ce3eec26cd428cb6 03b9b77d19a42e9a555da8ab70aa5638890b2ed21daefa28ca6323fc658662dabcbfaf52 87452c2853cada6ced81acb96eeb6f5551a12612b4bb825845846b9394fb4678534dc1703df17da4a99f4446263055e8 +eab0a37915c6b43b0d1e3ef92e6317b3afc8b8301b22f6059da8271fc5fe0e419ca6097daba213915855631af64e10d8382d70599d903d1535e25cbf74da3a12ba2f13c33a8562e0db03edce791f1d39af8850fd1feff0eb25f9ad0a86dfab627b96e65831bffc5f6d9693d20493bc9dd6eb3e9325dea50b055768e8aa30d49c 00b9f8f3e89e9c1ef835390612bfe26d714e878c1c864f0a50190e5d2281081c5083923b 8a572f58b18c4e2cbe179b0208830d4eca3b3aa51bc31a8519fb0048bd04ae1f2dc4d6dd35adb92ac4c5e1e2a1814758 +fdb93afd5dd1e3eaf72c7ea9a6cddb07fc2054499ffe152cb2870163eee71ace5bd420b898cb4fa80ea53fbbaece2a1eef6427b632320e9c97e38acb16b62fdbf6585b54fabf0a703307ca50f86387bed1815a05b0c8991e0743d10cdf49c8facfd7ddeb8d4a7b706b5a29e1d00ac88b0ee88b3153185495ac8388cc70104154 03a30a1c15b9ed71e102341f97c223a9b5ea3e6a335861c3cf407ef691a18cc639dbe74c 88d16eb5740d78393d6bf0e5faaaf0ca9cdeca444e8eccb32910b12b165d4de47de7bb66531a6b4e9d206f4e0c3f8bdc +c78e35d1a5b1bbb0ec21e7ba7b7c74c859d88f3e100e40ae34128cf093885dae4e87cd09f3239dd8e79e25305220880dd352a650225d9bd193b9b84e488c458b0b5fde1af941c0c9fdf952d2fa41f665918dccae27ab7923da4710f8c27ac8ed424992568dd6f0a6c3ecead21650ed162e0292104eef3c2d8551be866a88d279 0083330123cc64c11888c1fd388629d0b329a50ef31a476b909a182c930ff02d0c389b93 a8702b14a2507ad437030dc7e68044b0572bc1ef9eb74c0f423a6a53edc9b88f22f0d06796442a3034f62c0f1c320abf +e05435f695997229cce314e50065f3c5f71981988dddccaae6efb81f936b22cb48813f506d1edf5ebd69b0be34f278592c5935f0f6db0cca1ef9d62834fbf3c4c03f4da0596cb4d67b7b767e85dde7b7c6fbef7d89babe6f97b876b33594a9e36ab87079861ee556fb03274ad4af527342a4794192b8933f28c6220f954c77de 01dc2b656c207eabc9e0d6272099babca8d149c9c4258b779c2f06de75f76d77505271c0 89cbca4fcb24859bf6d2b35dc2baddb4badd6f3560cf68737aba69df915f826fd7c590c4399147b75c3ff807c4b8da33 +0f9f36477076c4b5a7d1ceb314a397fb14646695b0803e36e98908c8a978770269f165a1fed8f4b655d4efd6ad283d7f5d51b6e1e302d360e8ebf4e887c7523a757ffd55384e114bbfc6b7a0ec8511079507b919065ca018573418f9e394854c5704227772161707b4d0246ebceb91192f0eb2ea994ce61fd98a6d14cc8246c5 00081772348ff2d7a3fd57fe703555ab2e14f5d203c4cf0292f944e827e884d95f3b1d83 a2a1f82edd5a75143fb5fd5ac9376d6cf34c59beb3174c28f373561ae51f9c9345e7ba4436d55a8f7e258a232f471189 +1d38b1c342b6611dbaf412a66c1c0b8397692755f576df33b31c2bd12b7f0707cc423376391f7b00aa4e7b7fe54532e2b39c3c5284b9c8ccce48eaf9308ed338992f1d4ecde6cbe352e46339d7d602942158387881d9b493fd40cc59d4f9b53ee4191d42352c6f7bf32c331f0c5afbd44a92901a4b713c7cf6ccddf7de4cc6e4 01eb6bf2ca1b5ffe6f6a795733eaeed12de6e87c53571e702635b9dbd0d96b47df4a005b 83de5109ebbbe73b9e10394570ce18664a76ce44e6b5ec69f6023fb19edf76e835e8bf97ec1d4ff96c50e470fea581e4 +3353ad05ef90e9762bcfedd6ef44a1e8ea0392ebef30cffd48ae620f3e567e1cd44882d514e7c6759200d4bcab18afd3038c3d3f8c50f7bba32a04eee5a4b1cfb8c349939e4efe0a46fd047d02ed000d8fa1b98b0af5586f120d9ad174b3aea33905b979ece1eb3660b1e070c8821b32df41904ad68bbd8ed247aabd94066f16 03b2a3e65e5a306bf8e3955b60e856dfa9bf68c1275a678ca056207a0ec67c96eb3f8309 83ccf6d26fda89080c6f3b73013f77899e2f983ddd1e0da814a9d97737e4e4d9bfcfeec6598483b96eb468caa3c1080c +e7ec162185fe9a5803c6b03d98041422315ccdac67e48fbd07a1ef3c5661158710abc6791bd0a75d56791b4ac0e7695d53c5989d9fa6a3b037583b2a80d2b154b024f1c36b63548be9afe1d51f2f68b2ba94d4ca1e69a35ac10e15ba72242aac20f7526b12ff9d3cde9a9bfd70d55adf9bd92c66d092d7d08e9764c84bf7f329 01fd4d1af0bb7c79ed5fea7bb45574e46534387bd916649485ef15207352d7302e81dc01 b8d68455db74ba8f8bd580e34763552f989937d6dd9a2737fd774e0f896cb2992e9990902d3176f9d6f50b7edfeb2934 +87c8f2e3f4fdebce0ca9300fc1ebcaa934f51a12b6b8f2cb6bb6eb77965468663044afeb2a1334cb5a81e74b8427267f8b34b5e9ff0cf157a9f18be2b1942e32ca61dc23ea13c3f9fcfa16df8fe05e067938b6994982676463fb12842d4ec532cb904cf222aa805dd0d86ab9a33a83e294c6d81e8dfa273835e62e9041dc8ff6 020380b1136b5283e9b7f54b7535ebda33b129ceb177bf5d3d07b1daed5edd9fb3862530 a97884915336c022f298d3eb74a9841f74926ccb0ef74524f6023957fcac1a91461a58859eccb9adc43c6594228bf835 +2ac53e8a50c4afe3b38904255b7cbf150c5f79dc15932dc0ac9aa631521f68a0d4b6bc5a04d55c99a36531fd4886a23a8d99f262ecd2a9feea925d7a96ebe9b6979a207b7f9378afbe404fc8e959b0333572a2c911f8743c0ba64eebc7ef12fe5435d2cb0e5091ae518b6e4233489efe3c16c6f21abf4e2c6808b733914e5a7d 019f815b98836948e0a0dc9c30828c31b13e175f1e79f23d084ae1bbe64823f4866214b5 912385a843c37381c90e14cae6e583af8c9bb086f1b58887fced83a515b2267d559971f0ad70715f03b0acd3cc31c41b +0b201469cac4c078f587edecdcdb6efd5752cb4a3f43ab540463c4d908c27527aa3592f2f9acad85dd94a3c056bd28618317ebdf2e7dd6c5ad26fa3c31dd8e5c50c60418d91c93bcbb59ec1adb1db791f485ded78a5cdcddd23dd1cfa4f13443468d8a5f2d648059b9c4470d0f4fe7733d56a28a2c24456b6923703ef32cf0b8 001854e954654e726cf4bebc0e5a840e8809fd716059211c6ffeaed36829808363164684 816954bed54d543cb41676e6219a2adf595d9d3e174c636969b4fb81667a382ab143f9ee96789c69d0047ecb7aff4bb6 +fc5e4dddf4c4a328b685035ee79069770fbebcc56c14e31afb4bbcdd5220e025f31eba794fd6c05e64f19678dab33ce4f084bc32790392f14bf35669d75b6466b4214ec30d58ca90ae285c9058f5804a1fc9d7a995958f2a0e84ee52e8a78b601bec04ab607ffc2091749cc548c6754ed14e2e5f92315bdacaa7a12823ef76bf 03548f8020819588b3202f4c1ac62eaec6a47c2a19b2900c5a3cf5b4ba5804231141c647 825b1c9c8c1d9e80d27b2b2842ec7fc673b95e9a0b2a531c0897108552804ad804c95d079b227f5721fa06d677245813 +284cad790e6207e451a6a469cee3befc3ec43e047cf91b9dff1485718aa29de36a43f7c51eacd8589f0c3a96ec18e8ccfa92941b50b2132e3612d5b45e16f60d411d1c53e373e1ba451352e28970ada9dcb9802102518a385dc571dcf6900971b00346098a58042e0d1d129bd6801fa640a895a458a45b31318fe63ebb30c6e3 03cc4505005c41142308f1489226b7b542e2e7f24f1d3089ff6b92a4b0013f490ad52e60 899a844f402cf5ce853a552833c05259c4bd7364b707cb84d2eff525ab85729a33a45723a4c3e0dd002325085d67f4e9 +6d46e57abea9d115deda48b69fe8e0b36144df2f6a659509ce1b514c8cc4769d46e5f71df2a084f1db4a22fdd3ef0c2f90394f2898ce291b9f279c0664aa01419f5f6bee1fc1299871b27ecd57a5ac548f99d01871b8c238a6b46044c953b2e78e22346a0c7663af4db62799038ffb5c21ee512e26d01e70a4ed967377ab8405 0144a2fc8e0aa63506e14e4307df36416f963dd9da78655832f5b991af8c3eb97df78efc 98f97b01294aff8bea6745ac247535b360d18c8492977b8db769a874aeab4c617459eba9f30af325ffaed8371914fca0 +dd750b39bd8753f4e473c4484e2b36ce2da7576813ebe05861c339ffae1d029bc793173ed394091c00685ad82f0550cb21ed1c68f0c27cb7396922239cfb886647af204e88a9101b7453a8ab662e270b87a8a13f2fe61d695597382cabeb781933bebfd7d0dcd33f77266e43e32d937f2dc89f67525e522977ce73e9ad36c8e1 024ffeaf139043ff25a395e4c560c7680c1c2155191378917eb25194136b4a69597dc277 a761b1ce1d96932b7cc6af341887ce8811ca690100473a9f681c09b6b4a76532afd4839c000687f10d41b4393f96e090 +4736e59fe5812f63737eed57a570182c065538abd9fb0a1c9c2059199e7052ba57d84b5fa1cda2ad9f216610361ce1dfb9334816b6bea509283756a03aaae2e5b0597f492d078b6b015a40c9785dcc5d2ae266176980db04f5cffef40e16661a50ef871c5f531d73fd5d114fa19bae9dd2da4267a131fc31849da38c2b78d1af 01d1f2e0f044a416e1087d645f60c53cb67be2efe7944b29ac832142f13d39b08ac52931 86e86cbbb28cd8de9bd49b706fb6590a67bf47bcc55db0d0fd5c5f5d87dfe7bd6eaebee45b3931b0741b5b989772d7ff +e573fa7d4bf5a5601e320130de91f4ad87eb7ca6b8998488afcef69c215b0cccd221b8b66eb0af9d699af9ad6c4b4a580e82941f31e4c0a9bd83995dd076c5ac9bebb34481061e7cb1b26f6e8c6b26ee4bdf9887f7ae2eb9fad3115a21dcc96acce85d23a040c0ebbe0a56e75714dbfa803d6e279b2f4280bcb993f96ba321e1 01337362609df74d25f7adee382225e6a04dd6ee4c6b45fa31499ce9edb0ec046325caf9 aa4e581db7f16fe15ef02d6b52d2190cffb03514cfbc20d0c9e605fb33c1994e24a98d816828a159cc3866ea2e5ab02e +7862864d0d78b44e2a28af44a0a16d8e9b1b8c4b794db0410c0a863ba011018ef43e1e11f2fcda2f56fdb2a69cc817df425c9cb3b458922ba00d710190cae16d61af3c304a42fbb3d0c4a74a297253fccd70aca414865b41f68b01c561be281265fa89f63f975d3101334886e85929a5a47fa8dc459b663548faf8ed7484958d 01be00aa0afdfe92e24a2536594d4b41701ad4dfb223aab35ff49310bdba7566057fe8ac 92fae4f64f76290eab17a883f855c4e02e1ccac54b551cdc25478c51c95fb210542a91e2ffcab1221f93e53324f32692 +e73c96d1a84cf7cc96065b3c6a45db9531cd86a397e434072a38d5eeb9a90f62bf5d20bae22b926cfe967647d2bbb5dd1f59d6d58183f2cf8d06f4ac002ead026409ca6a1f868b406c84ff8887d737f65f9664f94801b2cd1f11aec336c0dbd4ec236d1cc4fc257489dc9709dfa64eae3653ac66ab32344936c03eeb06d5852d 012ad0aa248db4fbc649f503e93f86104cb705d88c58e01d3ae0099590a69aa006aa7efb b0ebcbea8d9c58aa793c314bf697ff6de153338f9d0c9d89c03b2d719d9f3c3ddc8096a96979daa6d762b25c04f928f9 +a73fb0aaec838d011110d49c5e94395ce07408917bacf7689d2cfe0948c582214b263c6b80e0a55f1e159086817605723740569eeaa1bae96b979679165c5c35ef2142525e943e595e6b4b160acd7ebe41de19775346363f779b1f80b6d5f0785b92a648028e456af8496102d19dc6526247a654bdae3368f075fa9ee92b2f4a 02cfbb8f340cae8e2e2322829148981cd9e509b0c65497fd8d9da5dee9dcfd39b0f7556c b06c2e3ddcad8141fdc43c38a141e64c45f3a4c1432fc98fc72a48029be1b6e85293bde01628aaac08e25006751c7d68 +eda775984c7c9f7db47af30dab314d070fb77e9b623baa6b73e2cbda800f167b20fdc2e7219391efacf908f4ceed9b9b6bd3541b52ea087177e18c97391214758cf6455311fad336ab56cfdce57a18add8cf85b0a0bd6fa7297dbaa34bfc8585b0f06a0aae055186658c227e19cddb65de88d260f09f805c2e8854dcc524189d 0070e82a1f3fa6158d15b7346dd56150faee5c98c9d07c996e01a06dc9b211b12ff62d60 82d3db0a6807990e230f9ec7afdcfd0c6a72265a65a6b729d27f2b70098658331410ff775447fa465a0fbd1b9e11db8e +a4a13e0bfa761b9bf37fade6570d41c161e20558874911ff3bee38e5649849b159beccf321c6bc7243f99c01a2fadbab9e157e9952ca65d8ea676c74fdc976d00501c626b8465c6cf0e4fd1a7d1260aea987161b821528b0b423e62ecc5193a0a49442b0c3e4ec9c4786a3a86b199c07dd3a17033d430d2c83c100f54e0a7c31 00b471bbc5f7a07996e370da4a09e71e2119ab3a562a273f079401951fbe4df39a4493da 86faf67a29246acbfbb3d8209c03e760c52a5f828de8eaa35406ac518cd09217fe9d6e306c12885fd0089c52d2f899a7 +7ceda7a7248640f7055309ae712c19d741375d6a7e0608e07f0135bb830dc3e8863ee9e7a75331a5e1bd38c42cdd484d4f45a26c2c1d4e05ce0d0ca941f4e94ecc6b371102f31633629e9861de558bcb6407d66eb91f1062ac0e0409db68b9f2855296a7f42fc92359a7dae16c73fd2dddea52bd866a4d501aedd8fe3b3ea733 03c65cf80bfb507dff52f9bf2f93df0642020d41619b3990009409e7210fd7130ac44ffe 8603f4409d74d6aa2e37024fdf8122c6d3490cb982c8d11e675bd6b88d878fff12a28faaac0c49802271ef0f67a5c40c +609815edfd58c0e26a4b06dded831d2f33466a130754b96d8d7c3b4d99fd4b0789ec719bc25338d0ae8c5880560c02687d352d77c291e406eae865c3b26d00f2e63dc644ce7e01d6e96ceeac8bc1eeb257d36cbb25d89b5fff6e30b6051506a0ae54cfaf6214f30985d54cab78f708029c1fc0175bc58e888db89dea8d300abc 00f4d33a9c7e6744ab3c441828bf0f1866ae1c042cc54abc754e3801263a96cbb3955dfc aaccc5c96f397e27ff169c84a06255c9a980c2a58d5122b5fe653950e3163e778a9286892995f9e49c283be9a033485b +82d8ebba707b72655497320200ce719520c1ae7f46f38122958fd99322c25c9f4d4344bcb77a6658df0eece5df163412ecdca58475d56b0c2d14a0361e4cef458df146925d473a43692b15e9bbec550f1bde3444f2a5b2ecb55d2abd273ae999f16a32333529d94455e485ca4585e6b07bedbfc2bd1eb766abf0d28bdb1ae6ec 03a4824bdcea6a144d85f1b194431724cc49849b6cb949b4766d641ae95477d1ec3d1464 ad34763775d7f5331ffb0437e7964fc075fce80eae7f2a47f1daf3e4dd6d2ac38cda1cc067fd559144bbad449d734af9 +9c6fce18a6a96349b10c9f2f5f1505c8ab727a650b44bc0782a5f39fcb48b45fc7c1b82180d5f229b8abfc807071f931d333d265fc940c93fae7520d8d40ef59d7c6e3678c6a2ecde52b6a8827b1ffc6ed269cb9832feb20e593a7e3d4708309342875199eb2ffceba7ecd707b122516c815e83e27872eda812e3ea52ee3c4a8 027ba543ea785df1d53d4ae4c1bd0a3a994cddf0c25d2b4e8ff17ea7aa00619e858da1a5 99c52410af49b6c158ab5e6595f733fded24688031e6d9141f4dc221b596fbc5de1bbd347c72003e70a5d2396e426497 +5eac15a64c7653d125605869012b8f036804817aedacbb5a5248a595ee0c12329f91e8179c187192d3ed0d4ca2e202d8d4d9c93ad3f3ed931121c193af5b47a8a5dc39775b6c2d702708e5134f77a31bd62eaf87e39e6fd3f2b9f782c3057e162dd53b3addf92bf0ab99835c7f6649abd1c5322a1ebb2ba313df9464a74c14d3 00708d0907d14dcd5f40e2903e1e90e48a0ffaa6d4d9b84ca14df4e985c294f74eb9f2d2 adde5b4b024dfe2f774f54db4b3273f690679b641b8c2ed194cd27eab57f2101b61b565e6cae08e0b224678cc18ff7b9 +df735a7e60bc267b18f313ad56bff830be5ef119baf43ce27c6368ff1dd89f010afd4f48740b11c12101c5903bfa71d6cb3d6462cf875bbd55a570ffedf3564088dfe8c8d3148231b78b5adaa6c53696737d4704daa59eab8d986fc6e519e81540f201e77b923a6a4af65d7173635b3b19b2023022186a7b8e869e1ed51717ab 021fb0a6b94080da8b8299b87457dc09d21bc430ba5f3359d92aacc1151be9941739567e 8ede5d7e180a2621d6b9620413c4c6c3f6b12da5ef57ad735457c3561274b562ee69797a45f4916fdbebf2106652c536 +bb107b0eeaf175a786a61db923bc6d51dad5e922e85e57536118e032167b197b1a1f62d9bbcde04922fde781665c1094181c16ac914cf6fbbfb27bb8346b2134f05c55a8c6b9b481273758e380666d6e22c28577c29446cecc5c3df9ed9f1be060ca55ab2b7fda36a147aeb46df0275bb923e0876b703452fab42f6b7ad2ceb0 02c80151f91301fb6b0c7685bd172f20515b46bf94dbc4160d0720fbaedd40ec00084447 92545d28977bbdb09384bb8f4df941b91b52a2fb4fc64778dd8c582adc091ff1b023a3ae3684e132ddbe82230f584f51 +f47e49ae30b09b7666600b7a95e81b0afa1553da5e01fd917e4ce1b58dfaddb8dc8c03c0f5591f533610deb6a7bb5faf5dd1ec4103a587a1a4c58a110a706b0f301a5c408b3d984c210d5b4a0b347d2b5447271f25b527b3c7864f7cdfa735dfded47c63b723fa0f0413c57a24ffde9a95c35f743f892ab1ed1df704cde82d9c 01538abd7ce8a6028d01604b1b87db3aaf720e04220edf4d1d28c2d731aa25f509e58f2f 8e8a2a34811e93eb2e83a6cb9b990a0d85b340689a6a36861a43bade775ace02f78c6be11600294576f5bbe97b037185 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B409 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B409 new file mode 100644 index 000000000000..0303cab3af50 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B409 @@ -0,0 +1,60 @@ +f2380acb0d869d1cf2e25a6bd46ebe49d1c9270624c5507be4299fe773749596d07d10f7c2be1c0b27e86f27b4a6f8dff68cfe5c0b4c58dad1b4ebec7bd00ab195fdd635d9fa8a15acf81816868d737b8922379648ed70022b98c388ede5355e4d50e6bc9ec57737d8843fabda78054e92777c4b90466a5af35dd79e5d7a81ce 00beb0df3b0e05a4b5cf67abef2b1827f5f3ada4a0e6c3f23d698f15a3176cb40e85bf741c9fbc78c9e207fa7302657527fd92fb 986d13f9a41165838281527872b717b1abbad61e6e6f746bde13c6d2906fdefd346d4c06abf367392c1baeb413d0a614 +22a97fc0a9694dabc6f274ab52eb592dbbe8beeb646ebe6cef60eff341a13017eef980aba6d24ab3afd976e2f6a84cf652654d4a54a36b2f2f62fab8858f8b0479a48fe9f47f8fd5a4a1f3141a91cbca186507b2bbfef5e4c4d2df525f04ef7c4720fb443ccad540f03a2be468d88c9545d1dad579fd7cbcd103bbebc9e9f961 00504865a30984a9b273d1bc289d734d10e0aa56e93ab14720f1a42a27d8cc932cb8804b963175de6fe57d8eafa8ab7ea0592dfa 97db274a2f7dffff8c35c020b2f0f8d3324b4914c1ab1f0d8a7e1e93429c6db48c9e339019669f7bd597ac43c29d277a +af36c04af0e3fd64bf52dedf52fb788d2d1bd67fe05d98880cc7ad3c20436abf02f637fcec209fbf888903fdec8682717299f8a4386768153b7faeb6581db57fb9aaf4615b4ea8d924198fdd158363a1f40312527d6bd14c13d19985b668c6b88a7548104b1ff057d07082eea421f50062a315bc3866378f2d2d634f03fbc0cf 00cc08a4ea5ebe32027885a8c212870e7c45b6c610117994d6a42a284c05199414a3a0e8e6645ac5c2ebf21c505a601f69c62b85 b50c66d1f36313ff58fd5927850c0cfda61805d4e1b476e171cf6acff57fccf5dad98a2b0265e22fe85f7e8fe1fc4e21 +6bd6f52a6204b60f37929aeff28c87ef61ddeecc231e52a7772275f9329add899c130956f8c50ac2698aad3654fdb49b74a6427a62a11eca0a8ee8b719b8c0df7b9f0bb0af5fef4918a8c83367d29fddd04b6a1ecad904471e5b59c8fe3cdb06b4f8f96419518dda960845d83c49a49f1b1f2fd1d2682a9d60c25fe3ce982cf7 007156ef0a74ee1119532a2a7e8c02be1559c3c21897af9d5b34553c3d0feca4a8d5929d1945df824478e0c0b92a6fac8c84f639 81ba1eb73906ff5952d4497d2cfb04cc7c16ecf7bd5ee079ab1631457bd21589727944b50a03e3e33c79c5601ba7ae55 +0eb8de25f63abc9cba16823270e9b6f3fdedf0fb90f6652a34688970932e3ae98f6d3bf0fefc5f247f72960a6975bff1f1acc2188a1775fe8974b2bb2b4c8d226ceb735113a14009e8ce66d58808fada4e6f697fd016829913352c0f659b6be354a067df00cf74919580750aa6064f21264d89dcb28b3b2d4d699115c36d1310 00a95c7abffa92e2c637611ccba66ff9d2ab121b40a85c5b71454cb0dca1f098ce1be8d9ea4933d1a91bcd270c5a33687835d6e4 a0f6bd67a035863b10b0b66707aca21a4147d613b059199827c5a903f7b89bbd83e2f116c9d50ca6991cc08def15b399 +cad58ca7a3b9967dc0ab62a43037764f8074ef9177d60bd98f623d693333971c24a575ed03cb61f4dc2e3d6285fb1204502a540f3c0bbbf23f5bbbd1544f322ce35d949d8b1d8edeb82e90927ac67ad49c91007056bf5096bd690d15ac00e1874fe33293d8003a4a2b094078cf09af799dde384143350c54a99e1f99cc31f2d1 002c438b07c6e0685d1f94a4bbafc013f8f21265d893f54e54c3ac2071606ad1ffacace0b8367aad724b1d9508c65ce52282e397 8fc52d1d571831df71a104de649077004d7109fc17bb58feca0fb00f91125f35ac6dbb93bfc335c8126b5c47716748fa +281ce2643799bbfacc7d5993683a4fa656040517854f3c2dc7c4f8848dc305382e34e894d433caf12d8b493020a6a08d1fa05b08bf6c53127ad5f33bbe75b9db0615e3dd94408d028dcf3cb7598f6e7cb4c787681dabac7cba2cc06fccb7506fece6c7c1c1bf622d525ae9737085ab4ac578905950002024f30159cf0d99f50c 009e8658f8f9e6cd98c0f4f0fd20d64d725653aeba339504def17f3ad12a63dc6157d80804e5f43f4ff48fc5573fde2c615ed31b 95b57299b6e91c38d22fd60979c1ecb9fef9cdde021f3de359a827a57b8e2dc70a49b2b212a566283ea2f15ed3cfe497 +0c061da1a16f2be130ae3b20b89745e840bee09633fb49671db28ec9a051545f57ee07e2410ae7ebc61c9af79868d3047705bfc64ac0c04ef0b286e579b650c7165443631e49e6a53c84cefa5625b1e1035a6ed89b8e839540040151132a937666524265e099272c1849f806db0fdf2be64960d5b5853965099459968e5beb32 00c4c13f65eacce85a51881caa6f82d9e48ec2ac574947d2751823a7f072d38bd9da0cdf30b6f19084a6d291052e7bbc2e1349e1 87e2ccfd8e58c3fc6f9832072dae22e0132eea247ab4400be1cc916d72a2c0604b3308524b2c93e1d284754bed5357d9 +74ac2e1303297efc3ed8e624722df505df55b7f33964cc0d270604cc48b58205d8a11952232a8feb0079baa30d7d33660268b56a5a3dd90105f0703abef8f6636a99bc63bd47d9df100351bee32d8205dab0dbd2af36fd173409ff8d1fb7b24570f3c1e968458f58aea5aa2f46731ee91ffd6d3a060af6b3d5020daf1362af3e 00da591461791ae7847e6d8dd8df46a63d3021644abe9520e158406c96540d8fd82ecfb1c3f6f5cfd7688c7656cc3e3dc94e586e 853944362400c1b627e277a26cc0bb0dff27704282817759a5c68957d2f389a28848f8eae4c62ad7fb1f6d89b401a345 +2afd17344552ccc577b0118caeb7dd56a0766e25f84df17c0505f9798931374b48df89a48c64e199108c36e00c0bf00a97ccde55787bb97c6765601765ab5417f3e75e35a9fe5e0f85a721d9f08440ed617afcdc200b318940a1e496040a6ad9090476b0fb4fcceee77b3fea11de09e7fb14853d1fff8ab12d66c101257e2d4f 00b5eb943f0dd390b737510e2bb703a67f2dd89dc9f6dca6790bc7a260cb2d0fb8e1a81ad6009ed51010e7686d5b48233c6c1686 8adb42ead643526973fb3c1e936e30eec1d67a41b5e7c3905c465d57f299d6c78e989bb5b1a9d29e46ea83c602b4121d +174b2b083541f8284645a810801e72631a11bd7bb805f684a7159e055afc44357f2c80df2b7853678d34a04144e0ede2327d03db6df23769ec41194a8d9d86af74d51c5bc11ea878c6a80689af71d3fdaf1c651003385332a512e03dd040c33d9c328ca89ec7ee9026bbacf30a7f3a68e0d894fb9f7100ffbc64bf17679dedd1 009cc63f32152284fca27ab2837bf1343144336a1fdf15b9727c47e877ac69ac9cf4c97b4bf42f1ab10d73de8597a554ed099efa 85d7ef32e0ed9875288727e6219e0801ab62e60d7caccf9ed8e205f4dace2d1e4b3c89e8e1715ed69ae6a45318f780a4 +758df71a952cdcffdc417b9fffdfb57582ab5c5473a8bdf0c2101953b023b77824263353dea0e2ede1f800a5757ec6ac0e1e4e3ab5a4cd85567d2d19acc6b7069a6e7368401cba2b6e642373654bec0ddd19fbf032794c15b7ef7e714e13e36875262c01e77766ed53cbcf735936dc9b33eaf2152a396349c82ca0297dbae4a5 009950355e8667bea8bbe3a2c4988436ab5394551b375e27fdc0c1a1d1b07ae957932f428f1aca0a486e54cd0b5bb0a5c5650641 8c51a2608b10fd7a0e004dd3fa36fb7b5120b9446b7ae46f89fa316e98f90ce2778afb4a48a0b5da5f3080dabbc9c88a +b96d9f66b2000e9408d602096f032b112f0e05ea874229ab9daf6e05bee49b4722e4f2d8bf2eeaab9dad94438c76b7cc64dcbb59cb4e03f9ac70487a1d24d8d6b72d7462fe738a17edf381d52179b3acc0c0177c113eb4d10e8e78041deac1d56abda0ddf892edb8be956d285e7236bc6794168f8a180f622dd5f2b9e690c275 00a995493d6971c2d7e8fac3da9f8c0b5afd877cfb94924cfecc167f9d87002136ab253e3a4f9ddf5c9c99bb1dc1af0c6a3a3c4c 89c815b91d8a90ff3b15a6fae2da6081ccf1e0760dc1cceebc2bbd0d56e5906f906941258ae7914f9e6a5a679dfe68ed +e7ae60ac55e6ba62a75d5328bbc15269d4638764169de0bf0df043d15f9152bed909b1fb8c7a8d8e88ac4f552c1092b62db00958a3a827f64896f6de4bbd8fa5258d6c36e3904d82d3eacf6eedba50b0242eb6b01212288448c3a9821c4fa493869c01149ff1850e8115cf9de1618cb8744626b1951d1de305745507c8b21045 0070daf435cdc26ad66c3186267ad12d10f28d32d863f950cbfcf042fe9dfce553750ad098f82f7f1650c1126b3e4451bee6e11f 886929654c60c5f7d2ce914bc684e2b1f115d35b841ce5505426dbb4b2aca987e1abc8e3690ee1f8e92fcbbe18bdcd79 +666b0dc2ddffaa7ffd57ea3b2768f02d4b77c16fa007c6d1918400d195f068cae2dcaa69817e6e4c70d5b29c5598efe2d957bd12d0fafdcf5ac52dee80a2d46e77fc18cce2a49bfd787ff77b942c753974d22434742bdb494590d17c42af725b1309e54566276af3bcfbf5e174d3cf191b85903faafa1583282c97e66c5da6c4 00f8121980dfbe9ad0bf92383c7cab95fb72d5caba96e1de7772c6a179e85414802fbb86d725401451329287305570ec7fdd873a a3439b5237cb6d510d30c64ae0e5a7a7150d52cffba57b3cf65109467be4dd0803d69123f08459870c98254b34069b71 +3e967cbc2bd936e0b6125dc5cf885735bdcd2d95b2f764de6931c4578ac8e0e87abdf96375481df67dbe1b6c43537e84ec62bfca6672cc5f3ea4125abd4a4119edffe04e42411d338e8b10abb1f1f818c50a9631a3f89feb5be5367bdcb0a8a82c96a427ba6ce99f9631d4411a2b7f5b14d32cb3901dc9d285e4cf5508940942 0047682b2e3bcb5800a531858e8137692a9b1ee98ea74e929ce4c919c26ae3b3f1d4122d07fd9a70d8315fab727ccb67004187a3 952c74357a0309811442d0f2962d6dfef8a3c4c01f0b87a042433c2f5ef81f86618e06f128c64483b6b464540b365978 +ca1c90012eba4e7c5f01d8cb3814c58f48c03a16be6ed86934014365eee547070b870d1d26a872cfd28b60d9ee0a66dea223e9eaa90ee28076188d6091f26f665684f4b486af70669555db9058d485c677b2a34d4a98aa8d6f43bf6f44aff2a23c5d765e98f0438ab81be0585a5be29daece5d4116f44ce6062753a3ddc505f3 0040cd1a06233ac27f3ddd108de7c6c0982793ee620d71982697713be9fd5143658929924cc88747a680779bb00da8a44e1e7d3f a29c9f166c83b762ed045a865dc1b57ab4b9f43e6fe806886b0869a3a2519014414ffd5d36573458f03cb170a4838462 +a54c4351ebdb075d6a42a787647390f864b2bbfd8bb3d0e0ea9d767200fa344d1a9ff091bddb186acd69bcaecd767068efe4d752d185bfe63f6674279d0e7192d2077c400bbc0d5599ee28507c1253f05eae0687b965a015e1f3a292b4650106765266f5c95b77ad2d82a6a6e012f233169eb6b8d83576901cfd4a927c54d7f4 001ca6f752aae4eb7fc9c73a08d6fbd96bfde5030d759a2507bd45b6e1d1487e53abbe98fad4f41976364e0a1d830910ccf97abc b93d2cd4bbf7dbb44137731d63f40e3dd49919292df60fb6eb3728f11c0b559333f1b932789c792eb0793d7076356151 +6723dbddc8720feeb75e2a061b7fc49079f999fbc79ec8a8e01ab8d35b438b7049da5a23c49a58101742791f84f45d5f5cf551cd7de6926a0e2c4ffa1e378f038da597368c62df8cd8349bf046de46d02183dc05b3a3575f5f232dd2970057200e2c9cb60eaa6b4d72f8b73d4d40b98d1cc801d1a69cb5ed780a75a4064623b2 00fb9b1a9597d216028902abf743d25944258b48c9762d4589fe660396130b75f6006cacfde60f6204463cb8c18b032de1dd68d2 ab89b64efad83b3294e419672749dc3f20547393ca5f58a1b7c71578e76659fdb2ef43fef227acc1cfcbff15e3eff8b9 +ed53cec5e5500d62d38c829002916c657674ede4439c6f405ba672327ec677490e656bdd698f114c2ab5e6a1fc94a1a8d64466cfe9eaabd23a8b5c37f76a3c0decdef73b3e7b751cbf3b0817f4079560b5ea34cead88ba374201236bffc48eaf289bbaa4e828afa7d732473c228ad00588c9b443d65b998f21c3d7a9e9196c08 0032109202d754da290c266f74f47805a06e6b5c3f721a72fc97a3bffeb8887e0c642d49a6bd034847d0a5ba09239c5dfdf0772d 9885f8d86d2864ad25f392b05e96aac7c2deabe7fd7260b4349a2a89df11350b933920f434ff478fc105f6e5693eca17 +13829401bd41e9fe01329e9f5a002f90f1a6ecbf25fc63e7c1345f265ff02e496230f706c6ab377ea52d8707b54f8fc5c7f089044e2bec1dfc66a07da76ee12fb9ea0697d87706b0ebf677600bd2fe117f6cdefb8bd636a1b6b97549ee78f992c24acdf3a946053f06fd012a9c703efb8bd929a66aa74b05d61bff0395232b00 0080536e820fac59b3203aea928475043b2576446619001647e35693a9e65d15236c3cbc12e1bbe0eb305973535c882b70197a92 b0cb051ac9c6872f6e10946071643a57492334fa7c8e6ef31134c4b7034174f5818d443a0510def3f96cee4cf7011431 +e696acdfcc96a6c088069b7595ea9516a36d8fe04dedeb789fbd965db0cc64b7017a821015f6210b6989e515def5a9605fec0d337e4ac59f3101a505168bf72ab6d98ec62a71d2f94071fc05b95e98d4efc59fedc138e3e49c5d0b44d1f48f7b1e7c1944ee189b242950d2bc804d31c7eeb45283c84638f043ab9533976433a4 00b05e5f0dad9583ea18fb8fc4d8c75fd2e3cf9e92cdd9b737485c953620d345006c31c288b380258b6500b84f729ce6730e5303 a245e4e260d45bab22161b5f34c6f0e7d815295e977847e55f4198681e99433540460af7d371f14341bce84856f0c347 +4058b9a8cc15ac148909eb97fa32aafbb6077b168dde91a411dbc973df7db056dc57ff78f0abcb70f70f800bd752197d681f44df4a7817c0e7f60f8f65489ecb6167c14b525e91fd2cc5d8b80ba380a83d031d5827c8b1262c687c90ef0e62723d9b565557f9f6fed0db48f3799274c2cd60a14303406c35802cba6261121296 00be1d277813e79051ca1611c783d66003ef759b9e104f32298017fb97667b94dcee1ce807dc6b4d62416e65d4120523bf6a4edc 860928828b848d8c3ba122598d509ea6bd04c4dca2cb7c0271f2cac9e9e1b0fcc612f8f4a9ea533023387a1e82f55172 +e793237d46e265ab84ba9929b196405faa3b0e4686e8693567e53f68e6991e57677974677682a2510c4c35b1968a90b32c4941af7813775c061c008a60f9f671cf7419c94253d6106b61e65034497f2d273a5058379bd986e3d917f708f0a2bebdba150f6d78a3af9c722a2430ab0f4bad602e91e18aaf258e3785fee78e4502 0073c807bd7e07379782ab790720de4ae5106f16d34e80ed70da5b1594e660c9b775db94066b93e74f855f57d88b6ecc6228aace 8de5639ff3fe4c63dbe97ef4e2abfa9d1e11a19c2325b5759f3232c1b99922890f318569de531be664caeb987ae1c407 +ffb8bc80e7619a562d8506eba7658bef0c25ace3dc1d01bdc2ef00933d4fa07b80364e5e5826074edd46a707dbc3b0ab19eec7ea8990839d7fc0a80b70661204c52bcbef57c1a7bdc861c10766033a82dafbead283d911a9502d5f9ef0a39d35ef26f3616212d4bafcd413ffd18b424fe09b48ba02ca5d97ec996205cd49d22e 00a68379b2296a6c944ad5dacb593b302d8ef0b05873ce12bbc371d705f308c739d21f343349524aa72f05341e64f7435daef112 916c927c570f1f27d5f8de33d13e96132dacf109828084209543630421388d46248dfb3de4cdd8c24d3e8fd5f06a6a7d +946bde90a5b903dd281a51d7fa93d80f3fed07eaf50c18fe9fac5acf67326bb18effa3144e25c151efc006a50a274ec6c6a5d573051c4e2d117ceb0fa125acad07a10fb6534a8e5f5b3da2a1136779c51377bf76c3a4a93c0c6158f729f2293e414fcb952c9509f228c804f0adc1daa327a8991d48ccf4f3957c5f8ccbe3ad4a 0026046bbb269ddb1ec14ade56175482343a21b7c265026cef3c7d6a1ae0f6a68166b9e6c49a6e733ad2ad64df7137ef230038fb 89e5dd7ef45e306f619b6976bef5ff5e71eaed9c9b1c6d43994bb9fafa98aa9412de2b132a28d8b93d2f10289018c3bb +07f3fe1369ebfcbcacd66675bd4ab22edbbff72e68709cb57d4f590e49440f01691f490c58b5117bd24aa2fe2101b59c61c417c918ea08ea34bbb9b8aa17491ae5d9329affe894f42d7586017877fae3ce35bb80c97f92a004380374ec91e151995166e14ac00505fd1fa810cf02981bacbcebf5f81b2e633d3a3db6737890f4 00bbcda66978ea526f7bd867c3303b625f11b94dd9ee6e2c2f8688ff07f2bba83c662949d47ad47fa882cb7d203a7f0ef5dbc52a af577f3eb894898293addd323c0e13213f91c75847cd17c0752737c2bd87aa59e20716ab2e7f1f614d250ec32aaef801 +3a1cb13438e3bac9ad4ab1d319e90e2c9f118dcf1eb54d6333c674a665d41451f93cd4a9334cd057a44c010edb668254517a63700a31eb0ca474c84873e486f2f8e158a1a7735362ea0cff8ef17d959ffd851b21a91412709b3c729474d2cb40f6ca0e397030eb2611b402916e4b656f0fd868247d80be3ce33d52054b7661f0 009be3dd3442e0330750f0a6252bf9cb317f32f942ae516a4038dea2c40ca6484fb33611bef016cc64baf166c122e87c15466fd8 97add2db2ea15528fccc2ae51986ac04b91eba96894430c7c3927fe3e52869c3c86b0099ce1c1c376642fec901b9520e +e58e7b881a563d54772125b2863718690a5276c93d9e1c5feabbdb5d6f7c7293ff0f89805b53663bb417fdd46874b8e6a466e7e3ff6737930a0662af1d5879b071b0dc4d014778dff26a2eca5992e763bf4c4698c382ac947215aa116515876008a56e5bf547857049c38a2d3737ed3393705fd346897c3beb80caab88e5b8cf 00ed321fa283c662e87eaab99b7715e6cdc9b42e14fa5bbe2c56fdfb381369191a42da7e574839f90a85577485f19446fccaf6cd 96382d616cafddcd9251832cbde2fc467b16b77c43ba55c5d4d22aee5df580a9febdebd0b78bd049ae784b3558e4fb47 +8889ea1da1cbed98963941f6ac24f47253ff6af52de920765214f2024aeb04f7ad46936830a8eb04d95aba64ed7cda6ef242f454b67bc2de38a46b6524bd5c96739c4b580e89829a61a8249ec8dc27a50f43b8554cfb6f4fa4ca6875983d4b60a1c6b49f32ddff6fac0cafb64d55c6f594b195c207a9bd920dcf20e0080920bf 00396b805073f3c3b552b1024dcf35559ac44f255b688871a3c6657f727a4b09f3806cbb75d26a00ae1728be632387e804775a8c 8ee52f3d390c07a6478750ded018675399bd3c15fce061fac20b66b05599ac1a5c9763a4d30358b1c72ef7bfc4f957c8 +55053af9370901e38622734a5bc5589f6a20e258627f381fb0c366f3dbe58394e5997e978eb7ebbc530f6e6186f48294149b8594fb551c31c50521a8c4d67e5862921695604afb23977b6a69b21abe75966fdd11bfbdb6b51ab0a474c5fa07c4de7872a3bd81acc417655090558dfcd5af449b3347e61fa9e839bb9457de64c1 00a8fe323f6736bcabe971c7d964e75dece70cb54561da48a11c40027ebddb23e41c7b48600f569500fe8ea2abebdf480171dde4 89bddc1c7848b0b6c2b172cb3caeca380e9a34ff14080719ef35cd02311ddeb0e4d793187015d98d6c6c6a298b310210 +c4264330534a6c2bbd8a3b757e0912558302ce302f835ad8c5474993832fd30036fdef40b10ee37293e871db5b0b149654f9e543e22111f9709ef45732125f713c031ccfbc9a2f3aba160c241d27be4dab87ab2fa9a795752ab2daf20f9d06a98d90d01c07133adfe83cb11d5176525e1bba6a9ba70ea48b224d46ddd8103f65 00105938ba9f25034da3e032dee121bdb192ac2128b50a2ed4bca042e96cfaf4660c9d35f3e67bafd4c99f9447e6dc408e0c4471 b7ab9ac83f6454fbee156979734372eb90c15751d0441d60dd5ce603184861347b9981b3a70f87c9b4332a5d763571ab +3236f1ad164e1b25d828f5202e3513c80c72a577aa9af56f041fd96cf5a3363f4b827723b1511a2f16360e32eac90ac55f4ee1146791420ef9e2af333c17d157b00e43992ef6f2be2d2f211361e468413dd93fb69232f0a0d110bc5fff361c0410344aa0636bf809062c73a7ac7c142063912b6ad7e1626fd2a384f35faffaad 00ce11677ca818537dbaeb880fc967dc8bead203a2538a55e756679c4a9e7975b9b3e6aba4e6c6eab4152d0c0939027e9b0bd92a a7c8066713317c866c05306ac37019633b1c519a3960e092d5e66ec41513bb262bda550edc7fb22ea856e460cfc2ad65 +6c400ed098d8369dab6fde3553afbbd4d47836d0d12dd16015f15cb8d067a39391c85ca4e78c62b8b72c1592349ff8dc52db8ccb7fd80c085fae456dba6f4a2378e184dd59238c92cf04e40d43a66b342d2a1325a0bab12b1ac857f0564c27b35e6abed02ff5bbbdc3770ddbb2ee0513df48bcba925da6d61583076cd3129603 005a239ae0f40d76d8d3589f1662b5ca12176a4b2784faa8339b54e96a1e1294433a4d83bf904196f939bd8b33bdb4be340ec703 8ff7d64a5d292777862f49e296fd288cec23aaed25cd6d168fff4a268daafcbc38cc5d0d465821186d1d70027bde85df +039a149eaef2de30b0ae457b376ce6fbf88afd4cfdec02d3c5e00400d3b0484c1cd6ba74db5de65d6f2fe39871349b30fdf1ef29bcbb9e182eb3ec5629d07d98354a5dfa82d7f0db3dd10d1510c0dce086848a198893ca5ad24a663494f0596b4eee86199ea85e7e8f2f76e7a6bd4a052c54287f61b391f1e52f96b606151c34 00077390c62ac41aca995640fde0c79c76f4ea8a8dbb22323ed812bee837ab8798c5d0ba976c7aa634d4b1c2c155de2709e7352c 95cb767209a81fe90b60c841b71e17f8bc453af390c457f21d3f3a7f64234d4a7a300359a7edfcb9705443abc8b67dfa +08617d04fffd6644c40f7dd57919f7dcf3c888f4147535d12ca658302305bb8e220bb17ccdc480254004b9035b357120580882ef86aa5a061b2850100285b7d61588a664dd4f5394f5478e68a80f610c9204d056009c1c9e902161eda33ef61aa902e96b6f094a9f053135692182943d38b9763055a38739a2a2d133c5dbee89 008bf23b09fbbed1b55769907aafb97f4759cec98649b2c9da5157517d4f85bb70157076b5e4aaa7a940af042302f8be06a84ab6 8e4840b7852f780344ef11159ef3a13daa36da2dfa787f043efd77e2a353ac6be5e2fa6cdb0dc77ec96b3b40a13a1862 +34c959f549a307f21b850ae105f41299b8bc94fc292aefc61aefbe0a1bf57576ba8d9b80caac635e4edeb22530163fa9629665fcd43959f68eee32482f1845a78ed7278e6e43d09ed6fedf465001afc0d61f1d2e1d747623e82a762576b879c7024e34f43104593cdd691d53bccaeb8f212dc29bec6bc94cf69d0a8491db124a 00082ad05d19b8e16f80e53a4cccf6869ab5128c5e622ed146fa8555985ccd2aa3b9957dd374586115d4d75b1c01cf98ecfc3646 b6de8ac1e9361e86731dafbbd2ee93dbecfa1f2b81ec7eceeac738f9ac341e5d5fb22d86966341272b494ed99c030d03 +514f4de08a6f49edbb6797c9dad6d33bfa367cc1a1b58a5becfe646c7f3352d5c5d95f7456e7112c4ddc746b9076b9756ae3916c07bbe6d3823895774a42d25d44b3309d18bfe7e3ccb1f85dacfec1654778c19e2981a853c1f40a7eafd16d331093110698c957fe9f1d86582706a6885543248b944bb70cdf9d2ea89190cb02 00af7e581aa4f9be5815f0c447e39de00da9194eee5e5f609668b9b69930b5b48a948614c2250260d1917f0ebcb00ebda4bb52f8 b65acf0b6a96e6d1ddcf08fffe091d9d8270fdcdf05f6d6b8279db43e19118a3ff8c1bc74c27bd4a6b68f01815e72827 +4e5d16cb1dcaa1abab1e371e1de02f31ef4e0944dfe1fdec45ab64326435b2af9aaf1a6ed8fdf1a6ab1182bb53a844c7cfd66da30aec0d41757f5988ada0017c4ca752597a9fd3637668bc1a92bb1556553f28d66805bb47f1ef91908ce098d452872da9800e77e1fbd43ffb0ed6fe6a62185d4be73ae96c9241b82cefb2da22 006d14107b08354e6a41d7d7d50c004419db8bdc50db43428df5e86084551237223c498bce71a17e25695bc438c5c09e009c60e2 8bb189b82707f1f4892a09f071fbd8a9466e780d5e9ab7e3e84177c6c64ae9c0cfe8292eef1180c4fe9ae9a29916e554 +e29e75269754ec1194270f5c9e8267dfdd8c696008b5ebc92bb840981fd065672f07f6a0f1b19841adfc51b478371e1a0db9c3346a9f0a4ccbdecb7040191a00ddfd0a8faa0e69fcf544319c0155d02797eeef99fabbc55078f9d852927c23fd931685424249b87ed0c70a4a3e2d3b9a2f92830e7d8f7650c0bffa8f8986b7d5 0099d96d2dc9c79549f031bd5346cf6a8544c312a3fbfc560dc8e378efdfe025b0e6e61e09c04c8bf4133396f993b0906c33dd30 a08e01cbb2160cf9bdc81ede83eb3e2b2ddfe8f611dd35b8ebc0bb6bb08f86f7c1774be32b45ba2a1eacc6218127ffb1 +1a538eb447c18494ad5a5ad27be67fa60eb2c5cb2404eec1dbd7244cd802b17ca5497e779d5f779b981b165dab53ad19fd7bf2ea7dbb9b4baea782a43d758202f147e59d6b6b8ed54f4ea084bc18519943f6894d603e253ba3e8e339a6933bc3a0a47126087038e1c813c3f2997aae321b7c95a802b4b73fc7db95897b7c91e3 0049f347dfd361a65910e97fcefbf60013a54837f2ae657d65e02397f59dc6bca27704fed3affdc3d833fdc621cc5e5f99b92a63 b694f25a45d54a37369c74cba305b2d310fad15dc93fc752e12fdfb9a900f67ed01682218585d7ace52948f0b432cffe +7502c755bbd385079a4001b8cd653287dc3054f3b57de19d0ff8f63c0308c64c56f035117a8971d43654f89b52e923947e4760ac72be073136da70c5ad7ca1658cc0a2d2a880d3a0c0fe636fdb27b77ff260c4c1ef8a18da8e9fd777d732a37ae9906e6c4f381f0a3d941048d5a1f6f2cb8593873fa4bb1621a44bc2bebfbcd1 00dd226de602af4e9f8e25784bd1bbd4cadb0a8aef525d5e2d57b9f3555feb698765672c5099a7d6dd5faaded69d8d68b4804f26 b2c36727bda0b741e74bdbdbdb5a13c1204b3e5d13d5ff36f2ce19117d2da5a7b9191369b3719d373ea27482a6528564 +95eca932d03f1df2e8bc90a27b9a1846963437cdafc49116ccf52e71e5a434cdb0aad5eccb2b692ca76e94f43a9f11fa2bdf94fe74af5c40e6bfd067a719523eea6b4e65730365ee498ac84c46e1588b9b954f1c218920cbf71b167fc977ee2a89429590f43bf637eecd91b0ce3be2d66bac5847205f76c06b914a970f543e59 00b6fdbc9c8c76cb2b822a940d8675889ca6f5132429da795462381ce29313a23bc132976fbeb346ed4c691e651028f873ce7971 9527099e9551ed8f953db5c5acea3b8851f2f541b16d569d284f4e3110e3751d81dfb26449ad340dfd36f5b7baa394dd +8ff68cb00d03e730dddb05fe0b2344689529096c3da6eeecaf097f22c7fa340593106b1f6726f06b7ce7358edbcf801ead959438a42f94cdb467b3cd5b17fbbcf75739805f9eadc869c33c604cc58f81591b0b8bf4d42bd53a801f0f829a31af6c129fb4f20f1250f959754eff8c629b85a716b6a18465b6495798c0c5166c8c 00203d77fac64591eb9a18de20a9d5eacaa1c3ec58a5ecdb3008c2d642e197141d16b3a9fdffe61429264f5b420f5e9926659a4c 864e07654a698bc6034948782ddb9cbb8ca97b8bcad2df7f948fd2dc677352a1cd62dafab5ddfef541464e5cd4ed8aca +01451c4f09720cd53377a5ed04c907a735477378ed960235a833049d6bad6e6e89958b4c4249bf0f6d4f043530c9e5426deb0ec3a12b7feb4860757b41bf602ca95655155356ec35a2db8e2657998f56529be4b714364f83a140846308a2973907ed7b08e935173ebbce5e29afe1444cd51c92824ede960056439555e7e74450 0057a2e6a59d4871c3d547690237dd9846d6d5dc4ec0678aafc9c8669af8a641eed67bfea4b05fd6b3b5357ec4d0caf352691ea4 a66c156879565e75f4af41fabd453de28bc814e5bc0251f83a6effefe977ea0aca61d42805aec30f5b1663e6a9f8fc27 +ccd494ca005ad706db03a3df6d5c6e876ef859ec77a54de11fe20d104377df1900b6b192126c598944d19a2364b2ae87ad7fd32265d59e1f22be5833f20767793677b628f18e9619f8ca32f3af3b41c31e87a98d1527e5e781bff33c1a8be3a82ea503e76afec5768d7f7dd1f17dc98a9e7f92fd8c96fca0db518bd143d82e6d 000a3da7a6633608fcee9ce4253bbcec08d41ee6b00178ceb017de74e24d48fd89107c9f2db3556063abe3cb011938f4b4871795 88d3420827e681466bc3a8f2c49a85c84142c59db65c04f146d8dd851b5300af7a63238f01ce7ed36a8f24eddec0681e +5719e50d939a8d74efb444eb5a77cda48cbb59e7f976cdb2ea2848bfc558718b39ce27b893c229db94bf77992222d1746f8f52f858f85124a28193ae0da039c53d484681785f3367f6516fbb8a86560aea9e3428551facc98cdb1e9df8e2f37db823a7abc589f667b5c93c4c47061400220a2014197d514217fc252cef5a2433 00384723c8b4a316b450d1fce0b2645912b8acaeb3cad50860cca43bdc0206ed5b3b60ebdc29b3eda305d0d60eeaec261edc24d5 86728f2594ab5426ab5addb10a3929d2946e6693afa5972d35ff94ae1b0e8b29de2ba6fa8ca11876a0b3f3111864f873 +c84e5702a339259a61b5ba8ec1957f23ffc4f1eeef3a58f383d3731bbaabfcf49ce2ebb597960ac5115a2af1c62b193d4ab6c24433d5f168a1752e40145f19aeb6dee889a53a4fadd13eef60e28fcc7ed6a9b8b0ca286c1b3d66a4b2c327a629d15c148049e3a0ccdccf05cf22c31956014595e417060627c8125bd7c00f8850 00bd3136647572fef3de51b12e64b36460bd3a27dc660c164fc705417339cab21f9e1f9be0f3da926df459c5ba58b701d306e67a b5f377abebf8498c97d09f25074a74a9e709eb6e96ab90ae42592fc5f92121bdcaa9dd8e9457420a8fcf3af637ced76e +c90bf11d04a708e64b6f94d4cca64b92463eae878c377b188c82c1c5f05a038be20eca2e18034d46f00d9a6fc73c4084981748ee9d2915d87aee4e2321f4f9e11c176f01281913e324700d9cb474b7134fcc408fb4a7006acd9e63d4578ed4c2729d8e0d01b1e6174a43a024ad261eb644ae98979c3cdab75af357f6dbdf5db1 00495be0b0a9d357f6155fac008cec90442200bb842d89292fde38b7256e4117284a60249b3101b3f19f778b680c0d1d7422b84a 997813bab04478bd4aa11ef788dcaafaa7e841651993c9866fef0326c8f635423ef0f95d05a10667294f8b7e120d649b +e9b2a33906a1079280100039787377c2971c378b92e70a38ab41dc23979d6fb0c41e53a21b37632407adac6f212341cf6af8605b4978c85c9c16960e1674247f1795cd73b99ff28cdca024f5078490513c77114c2f52288f5376872c331151d7b2c08f7794f2c1f9e0d849d32d73636f0aa899988ca561a76f74543b37cbf3a3 0079626354dfc4eeeb51fcf232ee9e6b0130c9bd40f15ed45606bb7faeca8f359e0c3e18bf12769254522fd4077eb24bd5454871 a2c217f6ceeafabe93fb38d2042eeadd0bc9409aef7566491acc1db3676eda6bbf8f2cff43fc412af07a1c764746069e +672db3fb8cc8e5f831be700498d3ab3aef14b7548e8011b21351215fb6dfa09460d18f52c02c8815baf396d856a429bb9afd602a10c213af34db80447f4c06ab4bd28873c88eb9639b199042d4b2cb13cc364f734fd4ab7bebede7dd4da63decc0cc1f84e34d760013f66d71641073f16c08078880b67230f2d6c6bfe17d206b 00ab42bc7d0e3c23f8bcf928e25f9f027b56f270398a1d37bea0ee5426b944a9c9ba6d0d7796899543feedb470f70b2ab148234f 9920e570d860c1d10c47fb80eaf0e754ea6eb08f141f106a25d0b455deeac575e24b28480848426a74871c5ce06dfbd8 +d7fd06b89226cfd66671ce5b4b656228c52d986afa7f6f30161680eb0c9cca177992a8a8c40167a64165c518c55f678702125709361b536bd928567c97737bd750d0e2e6e0c00296a6ca565f7c05cc8c54ae7a4e0c334c6a968fc18a959c18ebbd924457701316a4e999fb11084520dac68dc2d69187134c40891af0355ba89b 007f7aa2216164ba689459ee5d5ca29e70ef75a5b2a4416ab588df1dcb9164330c0b405a9d80c3acc41c19f58e24e17ecbc0fa7b a9683ab0f949874e2849b66f0ff082e55cd66168702a2c806ce511bab39d6e2e4a7a42c1cdf6f382e45f436a3b941221 +83b7e9d3ec638fef51d2885fff5490c94e2509c126608f82660e5fc523032f3e85d69d9b76af145f6bd916dda35775abbb6d1902bf38880f8b9259822055c5b1bc726c51029972cf7474cf2a812f3251aa71813476bff55598d079f075a40c6c41498bd865ce960c518bef75a873b9d010965f342dc4b35ef5c5972efe6fdd18 0021d84f070c6823a70f1a74225a472118c93ce9dc509aa6064051ca4574939dcfa96be862069424bdf1a23f62f2868326422e64 900531ce3747a559aaa71fa647010eecb10f62d2295165f487ca0aec1928d064cd6137ff8293d37e7ceb831c13723e90 +c62c7bcc860f0e175128e1127dacf935ce62ae794cc4a0ce7966bceb023ac0498641d7281fbc86f9ef470bbc77f608f83f8d0dd6299cf08f2cdacc7a9642e4246df131820220e5c05d0dbfceda7f16b86add4793e9b6244d96b5c07cfa23574ceb43e8e8b5483192a92b301aa3b37702b8f94f0129d8af1617896b34990c9b02 00b6645344d17528968c719091b6e2072388881dc10bdb4c7fbf41906cadf3699b30f9c1dbfb4796d009480664e6276c0359e5db 903165feffc67349442e680f4946001ae012517c0b6bd19601d4f0518ead7e3715be1a98da53bca1cf563b40147a06ee +b5bf38fd9e822925254418475a1ce762a94e336f12b156b1625a4574fee11ee472d537ef94b4a4b1c0a73b0140d0b818cd06636653e6c07f0f100118242a7703756f1cb1119b3477c4ced99cf45e07e83b7f2749c1a5f8d8c9272d221fe17f7c6a5fb0f8a16af46f232ce406aaf565c6b2766a2f6528c82e74fa1c0a7fcfd49e 00f8c2f770cf5f8e1f900e996ecdcd84fcff5cd959777fd005d721a419123221a3237e39834b270d37752470deaa6cea023c5058 b6a857a813ed1393307eb40213d25d4fdee404f2da280743378bdc1a9908f9527990d347f557a6dcff04280b2346c5d0 +6d3474770933ec01b76be789304b6fda423b12a0ae8c87a5ea8d7ee9f71300f39440e1c7f5aa4b47c1a8628cfc3a490b15ef292a741344f40a8fcdd02cf3863bf3e32d53031f503703deab17fc52b3d4032f4e237dcc27231b85d3fd60b49ed7ee40c3344948d87c3f47564d20a11d50e4e520bd16c8701694fc70901a5da625 00144adae951fe897d5812ee4a16c0be4c86c5e57e615c398f5768a1223a9be20fa82ceccf8a16a31432bbfd17e594a4cd8a6a07 90c437bcd10adf9cf1e3f9c0097ac2525fa9d1b844c2cc21cdaf4e633a9243acf1f87a69191ba933f45cd7494d65288d +92ba7aaf71f625f7a2e024058dc8739da3567c306da4a812ed9e1542b7d1e982c16082166a59720203f4524c3bd463a662c26a82ec7b4376545206e650eed0d3dd7909dfe3810981393070d15c45dc4a75a8c5bdeba533cad1ec34fd20466a61e4cde3b25af9a80a9a54afdd7de1cf2a74ba32d4ea0082a037775413c61a8d1f 00a51f065fb32c55bf4ff6f18ba9d488d35d9f8da593adb0ab1632533284e0adc43ccdbda9d9507b9862ac63b5ae7b0f78b479bb a2e72826e044ced7949a0cb678beb1532def4bd6c1a60ee2c08aafaea6458cef55e586a8e6d55ba1043a0057eb06cb40 +b3fb9e48c333201324755a81f3ae5d4f0e2ae7cd24238fcc66d858e3aeb1ee03328660d6399676eb1b7d8285ba571e214d935bb45516fccfab57b8eb4c3d5f1d7357c768eb7b5e7b5710f599614bd4e92706eaba31f8a5e7e57af7ed13066af50b4540ccdc126b677789920cef8543907f0ba9dc92aae343d3425bd784ef483d 0095351c0bc07acfabe6477fe85f97eab520dc96bdd58b44b036328ceadaa56a1904d2217c5fd25155ff2aaf9005a3e2687fec81 84906b8c855f16a078de37898d1e5bca025cbe9ed1c086aab6df708cb16c9c673e2fff1c362b81ca00de3e2a0559c0bb +9ec5f7d65082264b8a50be772c44277a73ed19199eb275fe5976f9799d8629fcb4a59a8d55074cd2eb2a0e02062d3f7cdeb05e62931a24fd1aaf14c257944d1b42eebd52726d6fe281211b39038e52baae077ea4df89675d860d6ba5a0f998d049614201b872e134367acc90066ac602e478ac3e43c3ddf4b0ca0aac1a68591a 0050245c1682344fef23bd549ac8d1e8e44b2840c43eec1cecd33daa4e9ef6b53f496104d7432e14248682cfd6f5b4853b65adac b967d418d35c7d75cbdfd40eb5c05e0833c89f0b377bd12d5fa712ddf9ad321471a4ae6417550c02106398f0f34e9706 +61d657bf472676301503f6784b7286fb39fb4186bb88abf1edacb4a2693d0a1e2b77bbf2758c84f2cbfd1753e20841b1cd4b456400d53f4d686e666943f9b6ffcdb77f510be97536e9698fc84ae347d483bc8984548d1cf86b9b40d360f9c0dc5bd1c55868e26fce1460ba94ef5e94eb63c9f0776a0f446c0cfd4106d9f36352 008d3b0277f0e9fe54581d3a9499ccd7f015c08339591326859af969d2a26284e3b3beac4a0b74d324ce5cb5f38c7995e4e3a41f aa434394263eee7ea4d34c8b77d75687b81181cbfdf09e241fa4f4b97ce5fb68b35310d1aa992e31a0f1f258554efce7 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B409_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B409_blst new file mode 100644 index 000000000000..f3776586523c --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B409_blst @@ -0,0 +1,60 @@ +f2380acb0d869d1cf2e25a6bd46ebe49d1c9270624c5507be4299fe773749596d07d10f7c2be1c0b27e86f27b4a6f8dff68cfe5c0b4c58dad1b4ebec7bd00ab195fdd635d9fa8a15acf81816868d737b8922379648ed70022b98c388ede5355e4d50e6bc9ec57737d8843fabda78054e92777c4b90466a5af35dd79e5d7a81ce 00beb0df3b0e05a4b5cf67abef2b1827f5f3ada4a0e6c3f23d698f15a3176cb40e85bf741c9fbc78c9e207fa7302657527fd92fb ae65b08e8f3a0b0de4472a20175e5cde0f1cd149ef930e2e0a1c8e4b8559301f3d20f30d9d7964f20325e0686b27ea59 +22a97fc0a9694dabc6f274ab52eb592dbbe8beeb646ebe6cef60eff341a13017eef980aba6d24ab3afd976e2f6a84cf652654d4a54a36b2f2f62fab8858f8b0479a48fe9f47f8fd5a4a1f3141a91cbca186507b2bbfef5e4c4d2df525f04ef7c4720fb443ccad540f03a2be468d88c9545d1dad579fd7cbcd103bbebc9e9f961 00504865a30984a9b273d1bc289d734d10e0aa56e93ab14720f1a42a27d8cc932cb8804b963175de6fe57d8eafa8ab7ea0592dfa 94db54d1fa07e4a2086ad5f43c9765dd337b9a6c74ca476458aa042022762fe91a68aeae99cdff50c7ee2348914c9814 +af36c04af0e3fd64bf52dedf52fb788d2d1bd67fe05d98880cc7ad3c20436abf02f637fcec209fbf888903fdec8682717299f8a4386768153b7faeb6581db57fb9aaf4615b4ea8d924198fdd158363a1f40312527d6bd14c13d19985b668c6b88a7548104b1ff057d07082eea421f50062a315bc3866378f2d2d634f03fbc0cf 00cc08a4ea5ebe32027885a8c212870e7c45b6c610117994d6a42a284c05199414a3a0e8e6645ac5c2ebf21c505a601f69c62b85 84488aa18048d8c447b5731b66573c067fa203577d6f8974a6bd5f099462ad1fb806cf4761c446bc9e905941b5e12aec +6bd6f52a6204b60f37929aeff28c87ef61ddeecc231e52a7772275f9329add899c130956f8c50ac2698aad3654fdb49b74a6427a62a11eca0a8ee8b719b8c0df7b9f0bb0af5fef4918a8c83367d29fddd04b6a1ecad904471e5b59c8fe3cdb06b4f8f96419518dda960845d83c49a49f1b1f2fd1d2682a9d60c25fe3ce982cf7 007156ef0a74ee1119532a2a7e8c02be1559c3c21897af9d5b34553c3d0feca4a8d5929d1945df824478e0c0b92a6fac8c84f639 9649472d9da98a99ba45edddd36a73e283f006bd6227d9e696a005015a3bdd09420846beb32059b2e9b701f44d182a74 +0eb8de25f63abc9cba16823270e9b6f3fdedf0fb90f6652a34688970932e3ae98f6d3bf0fefc5f247f72960a6975bff1f1acc2188a1775fe8974b2bb2b4c8d226ceb735113a14009e8ce66d58808fada4e6f697fd016829913352c0f659b6be354a067df00cf74919580750aa6064f21264d89dcb28b3b2d4d699115c36d1310 00a95c7abffa92e2c637611ccba66ff9d2ab121b40a85c5b71454cb0dca1f098ce1be8d9ea4933d1a91bcd270c5a33687835d6e4 82c955cd9ec606489a2623818ede14c9b11e6a1e28478913c02dc09ab4de2a915e6a957308b091aa54b80a736a1d7b83 +cad58ca7a3b9967dc0ab62a43037764f8074ef9177d60bd98f623d693333971c24a575ed03cb61f4dc2e3d6285fb1204502a540f3c0bbbf23f5bbbd1544f322ce35d949d8b1d8edeb82e90927ac67ad49c91007056bf5096bd690d15ac00e1874fe33293d8003a4a2b094078cf09af799dde384143350c54a99e1f99cc31f2d1 002c438b07c6e0685d1f94a4bbafc013f8f21265d893f54e54c3ac2071606ad1ffacace0b8367aad724b1d9508c65ce52282e397 9145d3834f1d7dd195f39d0ad354485d342889bf97f46f057d62d4c2485d7acb3bcf37062df69f73f0c5eb916f52f9fe +281ce2643799bbfacc7d5993683a4fa656040517854f3c2dc7c4f8848dc305382e34e894d433caf12d8b493020a6a08d1fa05b08bf6c53127ad5f33bbe75b9db0615e3dd94408d028dcf3cb7598f6e7cb4c787681dabac7cba2cc06fccb7506fece6c7c1c1bf622d525ae9737085ab4ac578905950002024f30159cf0d99f50c 009e8658f8f9e6cd98c0f4f0fd20d64d725653aeba339504def17f3ad12a63dc6157d80804e5f43f4ff48fc5573fde2c615ed31b 8270dfd62b67bfb2deee3b08a92e28dcc05ec2052f90ef66f264d530914ae10e7143eb45fd711edab7bb0ec58e034cc0 +0c061da1a16f2be130ae3b20b89745e840bee09633fb49671db28ec9a051545f57ee07e2410ae7ebc61c9af79868d3047705bfc64ac0c04ef0b286e579b650c7165443631e49e6a53c84cefa5625b1e1035a6ed89b8e839540040151132a937666524265e099272c1849f806db0fdf2be64960d5b5853965099459968e5beb32 00c4c13f65eacce85a51881caa6f82d9e48ec2ac574947d2751823a7f072d38bd9da0cdf30b6f19084a6d291052e7bbc2e1349e1 a2c759bc01a026754cd027c7d20792e0e697a5c38cb7f0a1cb8fb8f5f1d5357d1028ca1e7e189061faaea0d982af8c4e +74ac2e1303297efc3ed8e624722df505df55b7f33964cc0d270604cc48b58205d8a11952232a8feb0079baa30d7d33660268b56a5a3dd90105f0703abef8f6636a99bc63bd47d9df100351bee32d8205dab0dbd2af36fd173409ff8d1fb7b24570f3c1e968458f58aea5aa2f46731ee91ffd6d3a060af6b3d5020daf1362af3e 00da591461791ae7847e6d8dd8df46a63d3021644abe9520e158406c96540d8fd82ecfb1c3f6f5cfd7688c7656cc3e3dc94e586e 906d1360121693fab329f6cdf0de04e5ce38c30a1078a2a8ec8ae9281865864543f00b2817e7270a12e217df7e47d8c3 +2afd17344552ccc577b0118caeb7dd56a0766e25f84df17c0505f9798931374b48df89a48c64e199108c36e00c0bf00a97ccde55787bb97c6765601765ab5417f3e75e35a9fe5e0f85a721d9f08440ed617afcdc200b318940a1e496040a6ad9090476b0fb4fcceee77b3fea11de09e7fb14853d1fff8ab12d66c101257e2d4f 00b5eb943f0dd390b737510e2bb703a67f2dd89dc9f6dca6790bc7a260cb2d0fb8e1a81ad6009ed51010e7686d5b48233c6c1686 b0813b38add7765a86eabe0cf6746e0bbbafdd2f481e8aaf4262819efba4251d35c0305d4875324bfbbd8ee84a426ff5 +174b2b083541f8284645a810801e72631a11bd7bb805f684a7159e055afc44357f2c80df2b7853678d34a04144e0ede2327d03db6df23769ec41194a8d9d86af74d51c5bc11ea878c6a80689af71d3fdaf1c651003385332a512e03dd040c33d9c328ca89ec7ee9026bbacf30a7f3a68e0d894fb9f7100ffbc64bf17679dedd1 009cc63f32152284fca27ab2837bf1343144336a1fdf15b9727c47e877ac69ac9cf4c97b4bf42f1ab10d73de8597a554ed099efa b5dff6e849bc76431ac54387b974d1495a270eb4ea252b2428263266f5e9d05192705423beb87a0a191b1c9eb2449c18 +758df71a952cdcffdc417b9fffdfb57582ab5c5473a8bdf0c2101953b023b77824263353dea0e2ede1f800a5757ec6ac0e1e4e3ab5a4cd85567d2d19acc6b7069a6e7368401cba2b6e642373654bec0ddd19fbf032794c15b7ef7e714e13e36875262c01e77766ed53cbcf735936dc9b33eaf2152a396349c82ca0297dbae4a5 009950355e8667bea8bbe3a2c4988436ab5394551b375e27fdc0c1a1d1b07ae957932f428f1aca0a486e54cd0b5bb0a5c5650641 8575ad56b32c8a9190bf22dfd475d7b3f4c05362699ec675c3bc2576493b58b36ca56fe24a9437062956de4b26e47b6b +b96d9f66b2000e9408d602096f032b112f0e05ea874229ab9daf6e05bee49b4722e4f2d8bf2eeaab9dad94438c76b7cc64dcbb59cb4e03f9ac70487a1d24d8d6b72d7462fe738a17edf381d52179b3acc0c0177c113eb4d10e8e78041deac1d56abda0ddf892edb8be956d285e7236bc6794168f8a180f622dd5f2b9e690c275 00a995493d6971c2d7e8fac3da9f8c0b5afd877cfb94924cfecc167f9d87002136ab253e3a4f9ddf5c9c99bb1dc1af0c6a3a3c4c b4fafe13a5dbf7edeb723e5bfaf1b291ee5755b88a5263a9b4a99bdb2ffdd2442aed86e3a5928cfe9951deb1b29b6723 +e7ae60ac55e6ba62a75d5328bbc15269d4638764169de0bf0df043d15f9152bed909b1fb8c7a8d8e88ac4f552c1092b62db00958a3a827f64896f6de4bbd8fa5258d6c36e3904d82d3eacf6eedba50b0242eb6b01212288448c3a9821c4fa493869c01149ff1850e8115cf9de1618cb8744626b1951d1de305745507c8b21045 0070daf435cdc26ad66c3186267ad12d10f28d32d863f950cbfcf042fe9dfce553750ad098f82f7f1650c1126b3e4451bee6e11f 862e250e5742e09b4821812a855fdcc78a283a06cbf0e5a9a57585f224f06068d8878068074cf35c4c27c217bf388148 +666b0dc2ddffaa7ffd57ea3b2768f02d4b77c16fa007c6d1918400d195f068cae2dcaa69817e6e4c70d5b29c5598efe2d957bd12d0fafdcf5ac52dee80a2d46e77fc18cce2a49bfd787ff77b942c753974d22434742bdb494590d17c42af725b1309e54566276af3bcfbf5e174d3cf191b85903faafa1583282c97e66c5da6c4 00f8121980dfbe9ad0bf92383c7cab95fb72d5caba96e1de7772c6a179e85414802fbb86d725401451329287305570ec7fdd873a a93fc5708e5d07723e033c999fc9d0e718b1b9a6f3a87278df37f09f6db9527b4409913378da2afa761ca9a966d59120 +3e967cbc2bd936e0b6125dc5cf885735bdcd2d95b2f764de6931c4578ac8e0e87abdf96375481df67dbe1b6c43537e84ec62bfca6672cc5f3ea4125abd4a4119edffe04e42411d338e8b10abb1f1f818c50a9631a3f89feb5be5367bdcb0a8a82c96a427ba6ce99f9631d4411a2b7f5b14d32cb3901dc9d285e4cf5508940942 0047682b2e3bcb5800a531858e8137692a9b1ee98ea74e929ce4c919c26ae3b3f1d4122d07fd9a70d8315fab727ccb67004187a3 ae7dea1887a79fcb3a1087dc994870acd345072c7263c3e4ece0a0acfa9efa39f2445379f1400be38719479afd985053 +ca1c90012eba4e7c5f01d8cb3814c58f48c03a16be6ed86934014365eee547070b870d1d26a872cfd28b60d9ee0a66dea223e9eaa90ee28076188d6091f26f665684f4b486af70669555db9058d485c677b2a34d4a98aa8d6f43bf6f44aff2a23c5d765e98f0438ab81be0585a5be29daece5d4116f44ce6062753a3ddc505f3 0040cd1a06233ac27f3ddd108de7c6c0982793ee620d71982697713be9fd5143658929924cc88747a680779bb00da8a44e1e7d3f 89e83bb7824b9b328b0d0261ef819dc037325ab80a5f998117f5ce390df59a3a26f2dfa5557472903ffea4aa48cc913d +a54c4351ebdb075d6a42a787647390f864b2bbfd8bb3d0e0ea9d767200fa344d1a9ff091bddb186acd69bcaecd767068efe4d752d185bfe63f6674279d0e7192d2077c400bbc0d5599ee28507c1253f05eae0687b965a015e1f3a292b4650106765266f5c95b77ad2d82a6a6e012f233169eb6b8d83576901cfd4a927c54d7f4 001ca6f752aae4eb7fc9c73a08d6fbd96bfde5030d759a2507bd45b6e1d1487e53abbe98fad4f41976364e0a1d830910ccf97abc abc08ab157fd20852a04ea93a6e4a74f9a4c6c73b0ffcea8ca13788c9180032b4eb2d2e4f78e0f6ec31afae8ac48c252 +6723dbddc8720feeb75e2a061b7fc49079f999fbc79ec8a8e01ab8d35b438b7049da5a23c49a58101742791f84f45d5f5cf551cd7de6926a0e2c4ffa1e378f038da597368c62df8cd8349bf046de46d02183dc05b3a3575f5f232dd2970057200e2c9cb60eaa6b4d72f8b73d4d40b98d1cc801d1a69cb5ed780a75a4064623b2 00fb9b1a9597d216028902abf743d25944258b48c9762d4589fe660396130b75f6006cacfde60f6204463cb8c18b032de1dd68d2 ac7e528bcea1a3314ba0dedc77b9cf3f9b7cc6cc378696cad0d84bd8d3fa07f3b3242c3871d392333859c40f42af27a1 +ed53cec5e5500d62d38c829002916c657674ede4439c6f405ba672327ec677490e656bdd698f114c2ab5e6a1fc94a1a8d64466cfe9eaabd23a8b5c37f76a3c0decdef73b3e7b751cbf3b0817f4079560b5ea34cead88ba374201236bffc48eaf289bbaa4e828afa7d732473c228ad00588c9b443d65b998f21c3d7a9e9196c08 0032109202d754da290c266f74f47805a06e6b5c3f721a72fc97a3bffeb8887e0c642d49a6bd034847d0a5ba09239c5dfdf0772d 870cb7ae8add47ff9ca1b7d7e7a44305ea7fe64a05d83eb2c12a82e130db7987060026e56e4d8607355d4082b0d5270c +13829401bd41e9fe01329e9f5a002f90f1a6ecbf25fc63e7c1345f265ff02e496230f706c6ab377ea52d8707b54f8fc5c7f089044e2bec1dfc66a07da76ee12fb9ea0697d87706b0ebf677600bd2fe117f6cdefb8bd636a1b6b97549ee78f992c24acdf3a946053f06fd012a9c703efb8bd929a66aa74b05d61bff0395232b00 0080536e820fac59b3203aea928475043b2576446619001647e35693a9e65d15236c3cbc12e1bbe0eb305973535c882b70197a92 b4deb0a1bce493bd39df2787c7abf2f3c4f8d4040c932903523e2d987b64816327897179421d21119b1ea8b3a57a4e53 +e696acdfcc96a6c088069b7595ea9516a36d8fe04dedeb789fbd965db0cc64b7017a821015f6210b6989e515def5a9605fec0d337e4ac59f3101a505168bf72ab6d98ec62a71d2f94071fc05b95e98d4efc59fedc138e3e49c5d0b44d1f48f7b1e7c1944ee189b242950d2bc804d31c7eeb45283c84638f043ab9533976433a4 00b05e5f0dad9583ea18fb8fc4d8c75fd2e3cf9e92cdd9b737485c953620d345006c31c288b380258b6500b84f729ce6730e5303 b8c8f6c37cd7de54f53bcc0442f69a273c41dbb1bf713f797aeee79ea515516bb49f77b50bf8c3570ebf32938abd85e4 +4058b9a8cc15ac148909eb97fa32aafbb6077b168dde91a411dbc973df7db056dc57ff78f0abcb70f70f800bd752197d681f44df4a7817c0e7f60f8f65489ecb6167c14b525e91fd2cc5d8b80ba380a83d031d5827c8b1262c687c90ef0e62723d9b565557f9f6fed0db48f3799274c2cd60a14303406c35802cba6261121296 00be1d277813e79051ca1611c783d66003ef759b9e104f32298017fb97667b94dcee1ce807dc6b4d62416e65d4120523bf6a4edc a6bbeccf929d76fbc87c72802865cab242ae35f33325f0185747840c0170ef98ed3569126f8a090a633f797ed2717ece +e793237d46e265ab84ba9929b196405faa3b0e4686e8693567e53f68e6991e57677974677682a2510c4c35b1968a90b32c4941af7813775c061c008a60f9f671cf7419c94253d6106b61e65034497f2d273a5058379bd986e3d917f708f0a2bebdba150f6d78a3af9c722a2430ab0f4bad602e91e18aaf258e3785fee78e4502 0073c807bd7e07379782ab790720de4ae5106f16d34e80ed70da5b1594e660c9b775db94066b93e74f855f57d88b6ecc6228aace 8e1d5e031312498bef8edf2cd203708c2176723b3efadec0991302e04777e478d9663b853a3c753f080d2cd8bad08e56 +ffb8bc80e7619a562d8506eba7658bef0c25ace3dc1d01bdc2ef00933d4fa07b80364e5e5826074edd46a707dbc3b0ab19eec7ea8990839d7fc0a80b70661204c52bcbef57c1a7bdc861c10766033a82dafbead283d911a9502d5f9ef0a39d35ef26f3616212d4bafcd413ffd18b424fe09b48ba02ca5d97ec996205cd49d22e 00a68379b2296a6c944ad5dacb593b302d8ef0b05873ce12bbc371d705f308c739d21f343349524aa72f05341e64f7435daef112 97ea73cf93ee04c44f9a4cfe4f7dc7389b9cf61c5e1408088f3cf0aaeb5e911637c63acc9b1bbed8aee60c16c4f164e6 +946bde90a5b903dd281a51d7fa93d80f3fed07eaf50c18fe9fac5acf67326bb18effa3144e25c151efc006a50a274ec6c6a5d573051c4e2d117ceb0fa125acad07a10fb6534a8e5f5b3da2a1136779c51377bf76c3a4a93c0c6158f729f2293e414fcb952c9509f228c804f0adc1daa327a8991d48ccf4f3957c5f8ccbe3ad4a 0026046bbb269ddb1ec14ade56175482343a21b7c265026cef3c7d6a1ae0f6a68166b9e6c49a6e733ad2ad64df7137ef230038fb 811849f89d64d7fd36c26c8f4387be6576761240817432890f993b74cd2fb55c5040d16653ce6c24e8935feceb6fba72 +07f3fe1369ebfcbcacd66675bd4ab22edbbff72e68709cb57d4f590e49440f01691f490c58b5117bd24aa2fe2101b59c61c417c918ea08ea34bbb9b8aa17491ae5d9329affe894f42d7586017877fae3ce35bb80c97f92a004380374ec91e151995166e14ac00505fd1fa810cf02981bacbcebf5f81b2e633d3a3db6737890f4 00bbcda66978ea526f7bd867c3303b625f11b94dd9ee6e2c2f8688ff07f2bba83c662949d47ad47fa882cb7d203a7f0ef5dbc52a adf90500f68d85c69fcc0fedf2b9cec19e44c5b2fcf4ea92f5689a5bf93272cea37e96845ff21a537c98d151be29d551 +3a1cb13438e3bac9ad4ab1d319e90e2c9f118dcf1eb54d6333c674a665d41451f93cd4a9334cd057a44c010edb668254517a63700a31eb0ca474c84873e486f2f8e158a1a7735362ea0cff8ef17d959ffd851b21a91412709b3c729474d2cb40f6ca0e397030eb2611b402916e4b656f0fd868247d80be3ce33d52054b7661f0 009be3dd3442e0330750f0a6252bf9cb317f32f942ae516a4038dea2c40ca6484fb33611bef016cc64baf166c122e87c15466fd8 869616d2cf4d5b47acc21f6179003428239500e6db718c0463086095efc60fa30beddc330363156be5cdae5b50e24b3a +e58e7b881a563d54772125b2863718690a5276c93d9e1c5feabbdb5d6f7c7293ff0f89805b53663bb417fdd46874b8e6a466e7e3ff6737930a0662af1d5879b071b0dc4d014778dff26a2eca5992e763bf4c4698c382ac947215aa116515876008a56e5bf547857049c38a2d3737ed3393705fd346897c3beb80caab88e5b8cf 00ed321fa283c662e87eaab99b7715e6cdc9b42e14fa5bbe2c56fdfb381369191a42da7e574839f90a85577485f19446fccaf6cd 843523cd6fc134dcad1ff1ee048daf41e3cc42fb9ff4a0a29b92581a71c871779b1420c54a48bd46b4e927495113b38a +8889ea1da1cbed98963941f6ac24f47253ff6af52de920765214f2024aeb04f7ad46936830a8eb04d95aba64ed7cda6ef242f454b67bc2de38a46b6524bd5c96739c4b580e89829a61a8249ec8dc27a50f43b8554cfb6f4fa4ca6875983d4b60a1c6b49f32ddff6fac0cafb64d55c6f594b195c207a9bd920dcf20e0080920bf 00396b805073f3c3b552b1024dcf35559ac44f255b688871a3c6657f727a4b09f3806cbb75d26a00ae1728be632387e804775a8c af4d92e38797d4dccf7342268bfcd4848ec3914a8fa1d0596ec12eab72b0dea0f8f48dff7ed00c271e61d2b9ca559bf2 +55053af9370901e38622734a5bc5589f6a20e258627f381fb0c366f3dbe58394e5997e978eb7ebbc530f6e6186f48294149b8594fb551c31c50521a8c4d67e5862921695604afb23977b6a69b21abe75966fdd11bfbdb6b51ab0a474c5fa07c4de7872a3bd81acc417655090558dfcd5af449b3347e61fa9e839bb9457de64c1 00a8fe323f6736bcabe971c7d964e75dece70cb54561da48a11c40027ebddb23e41c7b48600f569500fe8ea2abebdf480171dde4 8e669c37ad44d19420a7678ed2a1478b78662852ac72198519dcecd5be6f35277aa577709c79c89c75376970cf8006d9 +c4264330534a6c2bbd8a3b757e0912558302ce302f835ad8c5474993832fd30036fdef40b10ee37293e871db5b0b149654f9e543e22111f9709ef45732125f713c031ccfbc9a2f3aba160c241d27be4dab87ab2fa9a795752ab2daf20f9d06a98d90d01c07133adfe83cb11d5176525e1bba6a9ba70ea48b224d46ddd8103f65 00105938ba9f25034da3e032dee121bdb192ac2128b50a2ed4bca042e96cfaf4660c9d35f3e67bafd4c99f9447e6dc408e0c4471 97da6c378a9e892cd1f8cf7c4b57395b83a93b1231ba2ae017784058c431d4b55eba7e805beaa96072d72b28c2e3c064 +3236f1ad164e1b25d828f5202e3513c80c72a577aa9af56f041fd96cf5a3363f4b827723b1511a2f16360e32eac90ac55f4ee1146791420ef9e2af333c17d157b00e43992ef6f2be2d2f211361e468413dd93fb69232f0a0d110bc5fff361c0410344aa0636bf809062c73a7ac7c142063912b6ad7e1626fd2a384f35faffaad 00ce11677ca818537dbaeb880fc967dc8bead203a2538a55e756679c4a9e7975b9b3e6aba4e6c6eab4152d0c0939027e9b0bd92a 90c2190b6da6c4266ed34fea16c8f93bfc61117b48e5601a3a1afed9ce015de6fbe258c59999467be8e3e1cdedfdd34b +6c400ed098d8369dab6fde3553afbbd4d47836d0d12dd16015f15cb8d067a39391c85ca4e78c62b8b72c1592349ff8dc52db8ccb7fd80c085fae456dba6f4a2378e184dd59238c92cf04e40d43a66b342d2a1325a0bab12b1ac857f0564c27b35e6abed02ff5bbbdc3770ddbb2ee0513df48bcba925da6d61583076cd3129603 005a239ae0f40d76d8d3589f1662b5ca12176a4b2784faa8339b54e96a1e1294433a4d83bf904196f939bd8b33bdb4be340ec703 abde85d01d837a85ec846780e21c9d8457308715a6225dfc52791fe9cd6123bbbb58a5877ef6005a74dbf9f8974dc701 +039a149eaef2de30b0ae457b376ce6fbf88afd4cfdec02d3c5e00400d3b0484c1cd6ba74db5de65d6f2fe39871349b30fdf1ef29bcbb9e182eb3ec5629d07d98354a5dfa82d7f0db3dd10d1510c0dce086848a198893ca5ad24a663494f0596b4eee86199ea85e7e8f2f76e7a6bd4a052c54287f61b391f1e52f96b606151c34 00077390c62ac41aca995640fde0c79c76f4ea8a8dbb22323ed812bee837ab8798c5d0ba976c7aa634d4b1c2c155de2709e7352c 8578479941373a7c98b0cc6faf36ed9830733b6748cd01e0907a843aac65517c9ee0725c8a6acae43612a99ee1ccbd7b +08617d04fffd6644c40f7dd57919f7dcf3c888f4147535d12ca658302305bb8e220bb17ccdc480254004b9035b357120580882ef86aa5a061b2850100285b7d61588a664dd4f5394f5478e68a80f610c9204d056009c1c9e902161eda33ef61aa902e96b6f094a9f053135692182943d38b9763055a38739a2a2d133c5dbee89 008bf23b09fbbed1b55769907aafb97f4759cec98649b2c9da5157517d4f85bb70157076b5e4aaa7a940af042302f8be06a84ab6 a1827e5bb39846df64974f00521d36571fbbf419a7b7a30db6ce8acd1163aa915122fa5f29d75d0e6743882a6d13368b +34c959f549a307f21b850ae105f41299b8bc94fc292aefc61aefbe0a1bf57576ba8d9b80caac635e4edeb22530163fa9629665fcd43959f68eee32482f1845a78ed7278e6e43d09ed6fedf465001afc0d61f1d2e1d747623e82a762576b879c7024e34f43104593cdd691d53bccaeb8f212dc29bec6bc94cf69d0a8491db124a 00082ad05d19b8e16f80e53a4cccf6869ab5128c5e622ed146fa8555985ccd2aa3b9957dd374586115d4d75b1c01cf98ecfc3646 9279ca815c52e7460e5c7d07fc1d25e0451878a5abe5052a065f7441169ff0244aa8d647b8654d61c292f009dd2c847a +514f4de08a6f49edbb6797c9dad6d33bfa367cc1a1b58a5becfe646c7f3352d5c5d95f7456e7112c4ddc746b9076b9756ae3916c07bbe6d3823895774a42d25d44b3309d18bfe7e3ccb1f85dacfec1654778c19e2981a853c1f40a7eafd16d331093110698c957fe9f1d86582706a6885543248b944bb70cdf9d2ea89190cb02 00af7e581aa4f9be5815f0c447e39de00da9194eee5e5f609668b9b69930b5b48a948614c2250260d1917f0ebcb00ebda4bb52f8 80212a2bab27a065a21d9058021fb84831f92e36b6e2674b80209598b03d7ce6ad23f6cf651817989d178a31311d57d9 +4e5d16cb1dcaa1abab1e371e1de02f31ef4e0944dfe1fdec45ab64326435b2af9aaf1a6ed8fdf1a6ab1182bb53a844c7cfd66da30aec0d41757f5988ada0017c4ca752597a9fd3637668bc1a92bb1556553f28d66805bb47f1ef91908ce098d452872da9800e77e1fbd43ffb0ed6fe6a62185d4be73ae96c9241b82cefb2da22 006d14107b08354e6a41d7d7d50c004419db8bdc50db43428df5e86084551237223c498bce71a17e25695bc438c5c09e009c60e2 b17a702840a23df9411db16a6c17dc09f01b4060f2910d6d81ffa2c948bbbea9acbda38cce6dd0e571e89f12093a6a25 +e29e75269754ec1194270f5c9e8267dfdd8c696008b5ebc92bb840981fd065672f07f6a0f1b19841adfc51b478371e1a0db9c3346a9f0a4ccbdecb7040191a00ddfd0a8faa0e69fcf544319c0155d02797eeef99fabbc55078f9d852927c23fd931685424249b87ed0c70a4a3e2d3b9a2f92830e7d8f7650c0bffa8f8986b7d5 0099d96d2dc9c79549f031bd5346cf6a8544c312a3fbfc560dc8e378efdfe025b0e6e61e09c04c8bf4133396f993b0906c33dd30 b8198f768939c78cc853f23cd947b97e97bb1355ea8656cd80743926baea04ff4e1c274a79b97cd08f4f5e9112931ba5 +1a538eb447c18494ad5a5ad27be67fa60eb2c5cb2404eec1dbd7244cd802b17ca5497e779d5f779b981b165dab53ad19fd7bf2ea7dbb9b4baea782a43d758202f147e59d6b6b8ed54f4ea084bc18519943f6894d603e253ba3e8e339a6933bc3a0a47126087038e1c813c3f2997aae321b7c95a802b4b73fc7db95897b7c91e3 0049f347dfd361a65910e97fcefbf60013a54837f2ae657d65e02397f59dc6bca27704fed3affdc3d833fdc621cc5e5f99b92a63 9039377422f5df1d0ffa8d9b535ef2dc16bf46eb4a09c8a229f67ff372b540cf372c4f461a940c61fbb2d814bc531b1b +7502c755bbd385079a4001b8cd653287dc3054f3b57de19d0ff8f63c0308c64c56f035117a8971d43654f89b52e923947e4760ac72be073136da70c5ad7ca1658cc0a2d2a880d3a0c0fe636fdb27b77ff260c4c1ef8a18da8e9fd777d732a37ae9906e6c4f381f0a3d941048d5a1f6f2cb8593873fa4bb1621a44bc2bebfbcd1 00dd226de602af4e9f8e25784bd1bbd4cadb0a8aef525d5e2d57b9f3555feb698765672c5099a7d6dd5faaded69d8d68b4804f26 898265010ee1b684ea73c7890e2089ccc48700d4a10bf1d5770c6896bcf1540a1af0a9d257e99e1a248c93ddfa00a826 +95eca932d03f1df2e8bc90a27b9a1846963437cdafc49116ccf52e71e5a434cdb0aad5eccb2b692ca76e94f43a9f11fa2bdf94fe74af5c40e6bfd067a719523eea6b4e65730365ee498ac84c46e1588b9b954f1c218920cbf71b167fc977ee2a89429590f43bf637eecd91b0ce3be2d66bac5847205f76c06b914a970f543e59 00b6fdbc9c8c76cb2b822a940d8675889ca6f5132429da795462381ce29313a23bc132976fbeb346ed4c691e651028f873ce7971 aeed8a2a8eabf89f76e5757bd546b27cea654e41da6efe0b3367e392018d6365e7ae963807876678a8d2969d57a3d0ba +8ff68cb00d03e730dddb05fe0b2344689529096c3da6eeecaf097f22c7fa340593106b1f6726f06b7ce7358edbcf801ead959438a42f94cdb467b3cd5b17fbbcf75739805f9eadc869c33c604cc58f81591b0b8bf4d42bd53a801f0f829a31af6c129fb4f20f1250f959754eff8c629b85a716b6a18465b6495798c0c5166c8c 00203d77fac64591eb9a18de20a9d5eacaa1c3ec58a5ecdb3008c2d642e197141d16b3a9fdffe61429264f5b420f5e9926659a4c a49ff4c961a213a6baa4f1856fd9ac0e735a5c043d904bb0a039d0ed838bafd2cf045056a6080e19332adae57e8be925 +01451c4f09720cd53377a5ed04c907a735477378ed960235a833049d6bad6e6e89958b4c4249bf0f6d4f043530c9e5426deb0ec3a12b7feb4860757b41bf602ca95655155356ec35a2db8e2657998f56529be4b714364f83a140846308a2973907ed7b08e935173ebbce5e29afe1444cd51c92824ede960056439555e7e74450 0057a2e6a59d4871c3d547690237dd9846d6d5dc4ec0678aafc9c8669af8a641eed67bfea4b05fd6b3b5357ec4d0caf352691ea4 a582e93b5f2701786399105fbc290301791e3ae60a1a3161bbb510714275dfcbfa0824cc912fbd9dbeb0b919178e614c +ccd494ca005ad706db03a3df6d5c6e876ef859ec77a54de11fe20d104377df1900b6b192126c598944d19a2364b2ae87ad7fd32265d59e1f22be5833f20767793677b628f18e9619f8ca32f3af3b41c31e87a98d1527e5e781bff33c1a8be3a82ea503e76afec5768d7f7dd1f17dc98a9e7f92fd8c96fca0db518bd143d82e6d 000a3da7a6633608fcee9ce4253bbcec08d41ee6b00178ceb017de74e24d48fd89107c9f2db3556063abe3cb011938f4b4871795 accaa4cd9047b0d04d04f25111e31ba9d2eec37155422e8d9f3b31c119cd6f2ea01d9df8145e8d9438dcac09ea185653 +5719e50d939a8d74efb444eb5a77cda48cbb59e7f976cdb2ea2848bfc558718b39ce27b893c229db94bf77992222d1746f8f52f858f85124a28193ae0da039c53d484681785f3367f6516fbb8a86560aea9e3428551facc98cdb1e9df8e2f37db823a7abc589f667b5c93c4c47061400220a2014197d514217fc252cef5a2433 00384723c8b4a316b450d1fce0b2645912b8acaeb3cad50860cca43bdc0206ed5b3b60ebdc29b3eda305d0d60eeaec261edc24d5 887334173b504de435de60bd226f6d2a91213686c33afec4bcde3694610c03e189c49a757f11b365fbb9af32c236b012 +c84e5702a339259a61b5ba8ec1957f23ffc4f1eeef3a58f383d3731bbaabfcf49ce2ebb597960ac5115a2af1c62b193d4ab6c24433d5f168a1752e40145f19aeb6dee889a53a4fadd13eef60e28fcc7ed6a9b8b0ca286c1b3d66a4b2c327a629d15c148049e3a0ccdccf05cf22c31956014595e417060627c8125bd7c00f8850 00bd3136647572fef3de51b12e64b36460bd3a27dc660c164fc705417339cab21f9e1f9be0f3da926df459c5ba58b701d306e67a a6cd1146016fbeafe08d2cc6456d4b43f729cd8485817043db5674dc665a4b4b17e6db8ef5e9f49b289a89afc6bca02c +c90bf11d04a708e64b6f94d4cca64b92463eae878c377b188c82c1c5f05a038be20eca2e18034d46f00d9a6fc73c4084981748ee9d2915d87aee4e2321f4f9e11c176f01281913e324700d9cb474b7134fcc408fb4a7006acd9e63d4578ed4c2729d8e0d01b1e6174a43a024ad261eb644ae98979c3cdab75af357f6dbdf5db1 00495be0b0a9d357f6155fac008cec90442200bb842d89292fde38b7256e4117284a60249b3101b3f19f778b680c0d1d7422b84a a9ce798fd995b373b47b7beb6b8613cc78b40d698dfd9b586252e53fe566a1e10d86b4d06fede007c78488134d581989 +e9b2a33906a1079280100039787377c2971c378b92e70a38ab41dc23979d6fb0c41e53a21b37632407adac6f212341cf6af8605b4978c85c9c16960e1674247f1795cd73b99ff28cdca024f5078490513c77114c2f52288f5376872c331151d7b2c08f7794f2c1f9e0d849d32d73636f0aa899988ca561a76f74543b37cbf3a3 0079626354dfc4eeeb51fcf232ee9e6b0130c9bd40f15ed45606bb7faeca8f359e0c3e18bf12769254522fd4077eb24bd5454871 a9d41119df62b969e2f80025bd6638332798b4747fb283ad998caca2f4e57e51557ff8c73a65ece7c215436e470d97ff +672db3fb8cc8e5f831be700498d3ab3aef14b7548e8011b21351215fb6dfa09460d18f52c02c8815baf396d856a429bb9afd602a10c213af34db80447f4c06ab4bd28873c88eb9639b199042d4b2cb13cc364f734fd4ab7bebede7dd4da63decc0cc1f84e34d760013f66d71641073f16c08078880b67230f2d6c6bfe17d206b 00ab42bc7d0e3c23f8bcf928e25f9f027b56f270398a1d37bea0ee5426b944a9c9ba6d0d7796899543feedb470f70b2ab148234f b782754dd86fb3553aee267d8344648eb5221784a869fa5ff87fe587142d25ecff21c97d503109c5a7d40da646b71c75 +d7fd06b89226cfd66671ce5b4b656228c52d986afa7f6f30161680eb0c9cca177992a8a8c40167a64165c518c55f678702125709361b536bd928567c97737bd750d0e2e6e0c00296a6ca565f7c05cc8c54ae7a4e0c334c6a968fc18a959c18ebbd924457701316a4e999fb11084520dac68dc2d69187134c40891af0355ba89b 007f7aa2216164ba689459ee5d5ca29e70ef75a5b2a4416ab588df1dcb9164330c0b405a9d80c3acc41c19f58e24e17ecbc0fa7b 8f10333f436e183485a9e40af623f7f45f6eb04c177fb447ea3c0edb6f3ef0e64027277f288580ae59fc534588859d19 +83b7e9d3ec638fef51d2885fff5490c94e2509c126608f82660e5fc523032f3e85d69d9b76af145f6bd916dda35775abbb6d1902bf38880f8b9259822055c5b1bc726c51029972cf7474cf2a812f3251aa71813476bff55598d079f075a40c6c41498bd865ce960c518bef75a873b9d010965f342dc4b35ef5c5972efe6fdd18 0021d84f070c6823a70f1a74225a472118c93ce9dc509aa6064051ca4574939dcfa96be862069424bdf1a23f62f2868326422e64 b510b40416bacddb09638c8d0790035cc40e3febe7ea89bfea501a1c94fee609a2814f7e648949d224277b08c765a5ea +c62c7bcc860f0e175128e1127dacf935ce62ae794cc4a0ce7966bceb023ac0498641d7281fbc86f9ef470bbc77f608f83f8d0dd6299cf08f2cdacc7a9642e4246df131820220e5c05d0dbfceda7f16b86add4793e9b6244d96b5c07cfa23574ceb43e8e8b5483192a92b301aa3b37702b8f94f0129d8af1617896b34990c9b02 00b6645344d17528968c719091b6e2072388881dc10bdb4c7fbf41906cadf3699b30f9c1dbfb4796d009480664e6276c0359e5db a2e6e99fd7be4c032b50bdaf236d488e3c84d564287fd73331289b4c4243ff457a78e858775a7e2931d8c5571835eda4 +b5bf38fd9e822925254418475a1ce762a94e336f12b156b1625a4574fee11ee472d537ef94b4a4b1c0a73b0140d0b818cd06636653e6c07f0f100118242a7703756f1cb1119b3477c4ced99cf45e07e83b7f2749c1a5f8d8c9272d221fe17f7c6a5fb0f8a16af46f232ce406aaf565c6b2766a2f6528c82e74fa1c0a7fcfd49e 00f8c2f770cf5f8e1f900e996ecdcd84fcff5cd959777fd005d721a419123221a3237e39834b270d37752470deaa6cea023c5058 88ccf525eb2ea5b101bb76f860611210d53df4168206ba66dbb26d6977dd0294ead30bce5f25d68114010187d51cab04 +6d3474770933ec01b76be789304b6fda423b12a0ae8c87a5ea8d7ee9f71300f39440e1c7f5aa4b47c1a8628cfc3a490b15ef292a741344f40a8fcdd02cf3863bf3e32d53031f503703deab17fc52b3d4032f4e237dcc27231b85d3fd60b49ed7ee40c3344948d87c3f47564d20a11d50e4e520bd16c8701694fc70901a5da625 00144adae951fe897d5812ee4a16c0be4c86c5e57e615c398f5768a1223a9be20fa82ceccf8a16a31432bbfd17e594a4cd8a6a07 b9ebdc89e56e4341830a81572b68d45bdd04072c133b765178babaf190028e676e845d3fcd458ba73759a12041b2cd2b +92ba7aaf71f625f7a2e024058dc8739da3567c306da4a812ed9e1542b7d1e982c16082166a59720203f4524c3bd463a662c26a82ec7b4376545206e650eed0d3dd7909dfe3810981393070d15c45dc4a75a8c5bdeba533cad1ec34fd20466a61e4cde3b25af9a80a9a54afdd7de1cf2a74ba32d4ea0082a037775413c61a8d1f 00a51f065fb32c55bf4ff6f18ba9d488d35d9f8da593adb0ab1632533284e0adc43ccdbda9d9507b9862ac63b5ae7b0f78b479bb b6c2fd00c43929f3d60b87772b5caca4a61f500bf8937a70a6d25cf5487244b84b038c34dd6e055fa69786ecf87505f5 +b3fb9e48c333201324755a81f3ae5d4f0e2ae7cd24238fcc66d858e3aeb1ee03328660d6399676eb1b7d8285ba571e214d935bb45516fccfab57b8eb4c3d5f1d7357c768eb7b5e7b5710f599614bd4e92706eaba31f8a5e7e57af7ed13066af50b4540ccdc126b677789920cef8543907f0ba9dc92aae343d3425bd784ef483d 0095351c0bc07acfabe6477fe85f97eab520dc96bdd58b44b036328ceadaa56a1904d2217c5fd25155ff2aaf9005a3e2687fec81 ad00a0823cf70771d13478484d99ae1be8e557a8011a413be1d7f0d8e026727c636fb244b2166152ab9f5634b8e03757 +9ec5f7d65082264b8a50be772c44277a73ed19199eb275fe5976f9799d8629fcb4a59a8d55074cd2eb2a0e02062d3f7cdeb05e62931a24fd1aaf14c257944d1b42eebd52726d6fe281211b39038e52baae077ea4df89675d860d6ba5a0f998d049614201b872e134367acc90066ac602e478ac3e43c3ddf4b0ca0aac1a68591a 0050245c1682344fef23bd549ac8d1e8e44b2840c43eec1cecd33daa4e9ef6b53f496104d7432e14248682cfd6f5b4853b65adac 88e27afda19525fba389888a9159567bebe09a03283a46f7c87bc8da47ec883f389a0301973ce361291f60f7f429d14e +61d657bf472676301503f6784b7286fb39fb4186bb88abf1edacb4a2693d0a1e2b77bbf2758c84f2cbfd1753e20841b1cd4b456400d53f4d686e666943f9b6ffcdb77f510be97536e9698fc84ae347d483bc8984548d1cf86b9b40d360f9c0dc5bd1c55868e26fce1460ba94ef5e94eb63c9f0776a0f446c0cfd4106d9f36352 008d3b0277f0e9fe54581d3a9499ccd7f015c08339591326859af969d2a26284e3b3beac4a0b74d324ce5cb5f38c7995e4e3a41f 8240291e674839007b8ef710a7e0c157f0d14918f01ac5b1c3829158f9e403920bca1f64bfc345c071ecf731a6ddbd0e diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B571 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B571 new file mode 100644 index 000000000000..7e02638e43c9 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B571 @@ -0,0 +1,60 @@ +8e14f713a2c427b1f79491033994f76acbead614d12e73ac6f3f518f2052a10c1273aabe628ab38e0d3d5f8ff254802e9f44a51367bf80325b6fc39d907a37f731372864747b10749ea5cb3d3a83da39c21a7b02885a8c1770e4397cedc958e4baa21d5007569dc9dd1e45d2181709d900a394454090badbd0cd9c2cd2369aad 00f42afce7f7b3d45f3f925ab29fc3882a89c9f585177887584703cf8bd8fc572e677adfa55b402446fe1e90dc855358d92c3267c35be9674b40c2ad5ce8dbe6a533c44b0ad8d2b2 8d55f78017858b916591cc79ec1ae23426b13a34e562542e1f889db0e34bcf4203d8523c7bb9d072a81c8f33cabbda82 +38b60d27ff08fb191811036dbfd5b39e1cc3427ff70efb67c851e9cb407f9fac6f348d289df98d055eec73299fcac068bd0fd9ffa3c5d244659e4f714a58d79f6727f323a7ee26369000e90e34e106f99f5ae2ae1b64ee89e5a1d304ef20c071a7773e9b977ed3d49f467d300a881c8371041394910f9c366942449045568f01 02f36613043cbf53ad36e2b38998bb867503359ae082d07d040e5a10a43e06ba9c91e7c73308e41e2391b65e634f83b162cbdf4e7a44ad818fb93a978af00f06be06731d8c5886c6 b5619c4a7a0375d5743e6126cce2e3d480465186711d7d9cb24433bcc2179e8b81ad2cbd41ab782e7737a056daf86757 +21709eeaf9e1953822294a478dfacfb205fc25f447a73a76a32601c00784cbf2f9ebd41c22721d70cdb3842dcaff4a4f208d41c0816990e421cc4b8538ac2f347cdd0aa2a39f1aa26ace8cb6a606b23f6244894d4594a0f6a5b8f6a695fd66e1a41e2eb6a377017177fec56bb58c837e311cd04c5b50575faee32606b9636ec1 02e74948c46930cbcd9dbe2325539c7dfdd910f309fd610e6599d425aad9ae230a8d4681970a14f2a71fd08030d0a40ff40dade7de1b06a80441bbf7e2fcf1809cff39c7ef88bf9f b0735e4c9292cf9e4f1fd786372e7ad61d2387ebe0b2d18f08b4adf76da3c474c2ef4b4b1b8c7b57e0d14c846bff3928 +3a131fabf3dc97334f212fce41c44300440d16de1d6060450875f7276f53c026e2a511681b5a8d75fc0d578546339542833145f7ee13c708df33e584445a75a5538829286480d339be7c777c03c998a6d3f037b25799ab2d541021502a0b02a9b9c337a8b176c4f30e5b186485a6103b1d1563ad4ae73ca806a5e4daa92e9100 01b5fab1d36f6f6d559f65d8b01edba610620fc3a38307b1fb1c5bd63e7ffbd4a9098cb8bdf50975a873f5d047ee2b627b090897a7fb5f56d3f4a0f3528179e7c969926fc0d3b0e5 b8ad5c6220eb6e7c27185aae7e11671cfac85e04eb0c8103deb771361e9384a542f8302b14e91d1123f8a693a581fd16 +679d85a762f2574b0b31b516270b7d33d5e166c83e91a0f48e0f3db20b52f42f9e6ee9648cf58267ffe3b713723cf3df52b5fab5c14db1e7189f7cb7170bc6ec7cc71946745e152b39180f828688a5b6c0b2957ab94283b90052a3c6e36843c391aa8810f9253b639a8d5a69aec10070603ad7a99dcedb544858d057a1d66b89 0383e70c71b431eedd4574f65d01fb0304f7744d668408c847f7899eae44770a7f3243109740f177d7146a27748886b7b77ecf3792b512e8d8e37c3bf4ecef2b1253df7066498f01 84ee90d59c4c367db8bc88fbbcc8cd77bb1fd31c437f74d5b2a63671f1e99b007918286b05eda44b4385954af9301b4b +236152ad31ce2ffc0dead3c142cf6c770672cd2e75af4a82fda1a72e1c775cec9b481c6f3e411644df7e7ee901c501405620af4b6e9667dfd46091788daa95ef2c6c9f5c240c06b15cb0df51f5f058d8a7934bd7845f007a35f99fa97200b20f3b5b14fbf1e372507f3b2f377e8d07d30fd3e222f398f26d8f428e320327f901 002261d4ead21f02fab19bbb0da8c272286704c8f0c6842ba47ded121e5cddef79fb34e6b9694f725ca502949faecfb21e3cc062a2b4c654bd542d9a1fe8d97bdd0905c510aa0999 a763752d90b319609f332b60dc1fe56b54afc84b9a3772367faeb2e92c0cb7899caa43cadd4378cc0f6f897462612b1f +ba3f02c4847fae035d747db246fe4e82fb9224ff9cf568a6ae548f5dc2befb2079541d2cf9aaa6b18c281a05e7ddfcdbcefb25f41dd91cb3092b3343e16985e91c912215cd99ae4a099baf628e33a7b277e3c36a13aaef85418fca99f64d73b789f23ecbb76c3095ade0a5f7f34836a98c5be933b44a94a2eaa3f99b1d8e7937 0316c78f289e1860bb623082be9d9238b88e38c5e978a868bb90f776235bdff4eff591877b7f350cf14c40356922b2b6aa51d64990360b2b0e44d6941b5dd9492b4f4e1f42ca163a a539ff49629546e6d1d27f3fcde98c4a086aacd2c493467f943fff23cd96d7a1ccc757539124421bf5cf267a59d383d7 +6d0372b40559e075af56af853cbe18ba2d471b0fc8917764abcc69102b03d5bbe1fc12458215be66409c26c89f67c72a8933677a07f88993af6918acb074fa915fe883b24bc3d191ff1b08852f07eda98977e70eba072d8bf189cd545230f59559ac05f1fa3f4e65886d0bc274a6e02e2399812b2bf91abae81e21279c5de996 02c1bc13f8320d97a82f3d9354e195481902214e16a4fd89332a0499208e91d50e5cabeb4927ba030cb42f5bc53b10f500fa646a8c88508cb0d63ebfce5c4bd574c527d686c735ce b2aea4e3aef1367cbe76a569171811e53bec26abd38c2d8a8dce0d9fbd20294d926d9702a54542e26ff47316b6c885cf +bbfe66c82bc060bd14fd0e40769d9b3a026eb447550dd9f118c30d8448f725f8366edef042447962ba7f7f833b9e9094d0ff600714697e632626e7d12a592e040bdcee166dcda93952323191021bd12f3b1647d0f25a41739994659dcbb19333ca30f46f539c6f0a5c354cda8969a1eda572a309950c84c7607eb8ac20163912 013bd80eafa67663e75d7ae139bf285d2b9f1e03d8e32153c73e26d06e86d7acad22bde9f121a3f1ea674dcc1fe67bc7f5398d5e92555056bc046a02b0ba86c2a0dfe32e91add5b6 a18a22c09fc42ea2f7e0a9796893fee3ed90d458f79ed414a5a85d260b6297e6fd6aeb61badf95619a914c698e251c5c +b35e9bf686717ce3b16a59963a32a2116130453b161a4e7ceb27b755856add836d779696edcaee3b5c986523891c8836109d431e55c23afbca022437ad19e6777efabb6da3bba1f5f44f905395b4cc7c9210590fd38da621582d059598e5e4569e904358e0dfc0dbfda4ce75538aa97480912852bccd433a9b96c9c66e9597d2 030834b0a4284097cdda2ada6947c6c281f7290a49b56becefea1e2788ea3ef78fb96807633c47c25138341768b241164ce0d42f7301728b928be2c047f2eb60fc2f844ab77306d2 8dad1a02e3e9ceab47329d6e48b65241135c90a7bfd8c153c8ccce742bec918c3350e757db8ccfa72e296df421d9f047 +57b5ae7e95c638b258d1e09b3fcb4341e203f5706862e199b103c8fdac72cbc5155e5cf8b300a0b3fb0ce1f897c45f7aefcc528182f73dd450cd84d5fe9eadff3f704dc2a01b4e847c22df430efd1c66b0199f3e5b59348af5386962a5ef25204fd230b54d58d7fae801c086f8f405d3d0aa7a9a9da15c22b868817cd897d853 00c81a79ced1eaaafc31b69a40d9939f4e484d625db6364a8e589b6b4d336d458b44287ea6c6aa7661113fc07806b147ff98216fa0c08708dc9d651821b922741deda522b4e436ad addf7cf3cb6379c446dabfef587c5e17dbede6d07193021aba6411d6c0a47424cc2e981d011f0f75cd4726271bac101d +daebfef74b452f039c999ba0528be3bd9e16deb5f46f6eae87b63db8b89952c949fd7db08311871eb2596865eed107aa065f030226ea675ee3256c31a3f85ddf4c21760582144e07af208f33c5f47cc026db5403186a65a47940691ea2d74ffb1245676260ef5717dd879d8b5b72d96f87fef5f762d4fd17454cb5ed83d8a11f 02f24670c0f77d2ca0266a743023d2c7413d56d0b5ec77b454ac59087efc4ea4d46179e10278e4ba416ffd8c3f9786ed202faf8251c0ef5a9ea5371fbb35b7afe3d15a9cb4bad975 945ba8da4acd76e7bc83f27008b7e2344b559b14ad9f1c9fe8b568db276fa938f94d75a40bbaf4c4fba0f514e1c2ef9f +62af0493ae79d71b552c4647d1fb7ab2f282a91cd44aebd8ef344dfd77b521b0c0a3f72e4513c8ecc0e4b84efef3df9482a07ccc1b740c571c5e69cb913740a792aa231b9dc87edfb72bac188293c6c6e788cb3dff32e8f483f8f34e21ee7efec71302cc3bdbfa47908a135f6ef3ff179dcef26d1a3987f7be967a6c0f799b0c 020985f2c6fe3ea04bdbab66a8b6167e5969c073b9d53cf3c77cebbf73f4dbf75e601620ec9c3107bf3fbfc6c79f8f063409bf8fe1d14b19e323d857e23dc05157d270c7514137e4 abf79f75177d4ee4b149e626c2645a5762d231badc58ebdb66fe73bcd8ece84403f1d65d7ba55b710d412a892b008b25 +566f17851951777ebea3f8285610cd8ee5f882a68e7a4205e6fc9e2d66d210ee2505ee73d6503169f7b903012d43e7e99efa493a8e6ef926b16b9ad8f52156840ab561fc6b680120a88714fd66d1d0742189bf06c155e1138ee5314707173f7352e2cea0fc26e1553643f2490428718e44afd8372cbb7bf5b88234318ebf4355 02b3d641607b8a141f876f6d285ee46aea543880e772dadd5dd83d595b9643191d9597218e1d6adb081df133304037bcd2c05c24a54e6c4cca64fb2cc4569d6882315360059496d8 a00f30db15c31de86bfb3a09de00898d8d799c58d907eb03243e8d8f4b0aae887b7202304107cc7d4559a3b293926b71 +25155825fc4f9a1c4dd1db837008e7e2594a879052431f5bfc76d0d2565b8fa726008befaeddceef73f3c60fa2cdf6d9a70e56d27210bd013034b38861ae49640ef208d3fe294ac4362f8eea44f58af3af8a9167a36b5acafb7ec95652d5885a0e08067ce1dfbb45a0c89ad1acb53eb404bf88fa5c3c463a0f912b5a2522a0d9 01afeb5ca87c81025ddf09c2b2c5ee22ba0105c0e619b67a324467485bd839030d149fee44d8bac6f5902a1245a50c3437046b7c89a84116b2147cddc645b6d2fd24d68e8d53bf5b b35ea182a62ecf2c1fd5944b38b0a6fd540b49a234ccb90c0a929e0cfa380414bb86100c8400f2980eb1dacf42512dea +29acb0fca27e2a10d7b9e7e84a79af73e420abdb0f80dd2665696638951b52dd39ca028166b47a3b6a2eaeceb1a11c152383f0bec64e862db1c249672b3770909f775b794e0b9b28a5ec8635a996d912d837a5f22471b40ec2e84701a8804127a9f1a0b3c96ff654700bad3167240c2518fb5dedcc1be9f56a807083e587bc56 032c97639b69c7cdbf419286d0a1b406d9b1f2886521a8b979a36118d2a368aace5b02dd8c515f2041e6fb9f026d1e82e789dc826a56d2ef732b1bb0f49be2b696ab5d3d5694a2de 91ce323099f228d44d717a7b5475dccff01295b9e2fd0a2fd06b4677a6c13883aa7d91529056f0ff8027d6fb35b431f1 +c92d67cf6536f5046e15b02158da698bcbba4ff1e4e9e9c882cda67f817210402ef917ae93682c9c3dd817b21b73c6c00b7bf92ea80ecbbef2e67f4f4379d078a2b0f297742b2bb9c3fa3297a7e8079f488555bd37715eec92b4b1cbf897640ae8a1d2a0fbcee5423ab31a37629f98630275e35094a896cc574be0a449bb1bc3 00f93672159276c5a293582b9f49607bbdb970112f6c63b2b3b5d32ad3c8240c86b1af13a8dff6502c6b6a17712cfd988f8cd23a60693d64104143b3f91adb37f852e9e11a0ef110 93e67e3ef8c455c866efd1c6d2898472d3e3a6b978a40a4f86924eb37367b572973b5500abe73f4363d3cd08231b496a +15413f614c4551e3b138b64f66d15f8964c40326a42b0afce820778eee4a88edb127fbf575da5263e5a2627b5461d311813ea868e6417615e7c4938313675009caac28bc7a2f4c0bc37572d9bf36a3b1794294e09c0121ceecaa4b916df45b0dd31225415e6c87cfeeb092a008fce2c543cd62365779ae28f29fa02a15d9dcd5 03db080bc99c5fe7e06d5032167af56783cb423fae59fb5b3c6bce5fbedf56b7b39b17810e48ea9a172881aa1f42f5e267349b60294d4a208b4437666b44abcfee5a1829e9467908 aea5084d8fed4c1e036a2c80efa4904d286c25a0ca565bc6bb9c21d019308a78d1d19c8e3e3da3550505795be1909556 +9f901557451ae2f8ec79b6d4adc794cbfd9b2e6d28f19409532d91682820205308b41498a4e1ca247a2baa8da93de95e3c0f7afd6ca46bafdbdcc6d3374a12684676a50988b86a960a82180648c8c1e38f8fd9af604c7be3be4b24799f4544ac96d6360cdb83d1d0847fda21642934fd6cf65385b50d86d4656987901fb88d0c 006ee767f6f36bb8f364f324d8346455c899a49237d759003dd52cfa13b9baa4c71347b134b24ecaee32d247c34e3787a0c64bc5d299b55c86f64b47521d22f2c09db225b0c84cc6 a8125aaf00d21f98bb64ce86124dde53973101a2f3e33be1c788549952b764a5c9bbcdbce351e1c20f110845eac999db +959fe5a19d7aea2ba611c7203e19f8e3f3cc101e03a98f91adfef602c424c580d5a868659368a930f9883d699fc633bd07f6cf8de474937db0bea86fa7cd140ec2f202663813033a757b93bd72afba15be5e47a4eb93e8a666aa1c72c241ca3922547d63fa3732fec54afea7ade84302e2f044275bb67433fb6b125b7913143c 038e2571d9f22309a636586d62863ed67a70538287f3ef88b88c3c2fa1a2900d48c342b6f15c26b8e7fb4875cda4093b7de7ceda48fe1e2cc2975afe958040881de61f309931e48d 8a9d0325cec806d3a1fb9762dc28546e744e6861781b20241d1096b24943873beabc2e35c154580173a13ff94c4f3225 +97b9688d9ed5101b8cfb19e84b89cd644262ca1c7ee18944e29ddd3b4cca78e06338b270385b00a5e8b91ca5e628de3bba50e36ecc695b3ea737a9cf8b36871c473a54ba17819f49e730c0f253b0c769aefa6c16366fd2dd612f330e95fb119fcf3bf7f3e254438c0ab635ec04a8b2424a05b483ecf65b74a93636fbab7bf1d8 00c8f5736f1ae65592f3ca850f43d06441aaad8c03820f3b08d8a6db46488dcfb828459f8b3f34af73cce8dc7a5e3834e085a64523d890028e194214cef4003210e6eb530005b01a a0938bdbb85278e8983f15c89a8af3d69c221fbb8cf37e8fbf45f3be1dbbd430aa335883296901f9a7a6a3bf4eb56846 +f08b250bf4a3980cb455338b3f4173723b3f44c97bacc9cf550149794a71426e398cb4a74bde141d8b7b4a72942f1c069676a9918e27792cb8f085ee037c78e3c468adea5123c4c64d8ca6a39f2f90140c5d2d80b669cbf0d1ccb466b18ded83a1d5f042c36188a04111c34ff769abba9aedda40a87be1e24b700225e2078056 01ee68c3994adaaa9e0d61bfcd3bc1cdf198d3fbfe28a44e5dd518867ea04b20e795eadacc48bfcf8e8216dceeaa069b756e8e99ed87b6b1d31154cc9310bc3b4555162a890b0c6c 811fcb5cb6f042b9b947e58bc536f20d6901bcf6139b119c259c44ae5873e244ab125e3d9d188845a2a8141dd771bed7 +1cabd16fc29d7d919622810dc8b23c770b790b98b119eeab1b20900fa94fc2ebaf76be4f5eea91fc5276c5621c8677d4d117c4a5a782ee2ca1d5b0db997fdc8a05b6b3fbb833d7a7b81c3c615c2a662929760a96feefcf89e46b563314c9b77c86bf34438458b43b694ceba741b97dfcdacc0ed57652ae62856ce10ed2690770 03a6fbf66ebc1365ea7699c72cdac2dd85907ec59cd26e2d18713354b619ccb83b7fc0db9193aa8493c1855f1a83fd987cbbb65de17c59fbe79256aa5392f4eba045346e9ba26592 8a6880c98713b19452f282bf98979293e70a1e91d80fa4e7c564aa035acfcdab728a51a50472bc7b4acd5b4d3d2a6411 +7bc8bbf5ebeacf40b3c82eb6eba5d994dcc6a3f2e12ef741f90f90e176d20c21e006ecdaf14cb5beef35bff46b2c374d9ee224516679b1a9e9255cd8ad8e60ed234f8ee7e0fc53c9021488158217d4b4369cc597d6053746efa1e73340bdd73c1bd2eed57b92426fd4d278d6a86e8be0f0a66ab3dfadefca8831b2f488636251 0145748871a0b5c1cee628de04a12fd68ff2b154fda96e47afaa96389d66d22802968584f6753d36618d49ed205260f09d3f5ccc2b27a34390ce58179b9834ff92a86d66ea0a97ca 86144469fe859176c79446cbbe9ceb63a4399d342f925637d37ea4dd05173f5b5d657cfb941e41177951ffe26139de68 +0cd2a45392871c0c262e7e6f036946354bb41f9c2187b8c4d399231280682f3e0a09731fbfd52c76ee63b9828c2d731f4cefee0a8c46419c398205b2ff80c67d7756db300a0a8385fa287dd37d9126f75998ae1cbab5136560592118db52fbf102b7ff0a1ed45b8a91a7d99d13a0f7fd4366392264aa1248d7324901467457ca 03c71911d24ad19c20fc1d8a044d63c9bb417abc3778d7e6234c6af79b898cbfc2f2787244708d2fe203be786edbdc4c9b12b413156b7b0bab0be8af895d191d853cd58aafe1ccce 98c01191a7378d6d05ed05b9bab60f6b2fff0bb8dd2baf8784d050ff0982c1a1c0cac19ac9da99485d613925b85f53c1 +e97092625b09c9ae6e152e1cbee207d83361f34cb9b0e727c816a5ed851f12f91fbf88ad9d4c8f9d07350f5d828fd8574eafc768bc72a2b18aaf4d2b48fb10f7c3431137b51850154de9706487d69a40a8f4cb2c799f48c5d8f518aff752500de93cbb94ab04ae1e0c7183a32d79a27291dd07b5fb6e6a4fab76e85c3a8607e2 018bd74698bac36ef11add6b3e3fad227ecd868f370ec04569462565d2f0af2340bf793486953a7b79ab04f0ab1f0e4fd16bf6b576cce677d543e73aa8edb0e50372f24ddfbff966 b912551cd413f7e4b0c8f73f4dc5e1395d6274dc7fd407ed1b140e4c8ac86ba05be250d34aefa1b29d6fdd6c640b3b10 +ae6723b8df5d6ab5fcfaa22d32fdf106d211514cb1892c7c43ca6cd85c2532f85929c8a259ed251215063cf92e1502528d1e22d5cf67efa0b8ef21e8eb2f5dff881ba1433e8bcf2b6af8742ecb2bccde081e534615a305562cc22d3398f61f277d8ca785842bda85d8a40438d9bf1aceaedcfc22c85533794a69cfc320931d3f 0335699bfd058ee2e6163f55d1816bf3669acea8b73be9c4ddfe775230925e6093cff7a66813adf22222c8376faa106d85ac9f3c67929bc58d8986795b6d35d5b9fa546dceabbedc b3db9fd09067eb84838efaee9bc5d7e55ee0beaa1dfa1b7244462c499ef145644926f4bd42d475b414c97d2f11abab94 +ee20c6b61886e02ed94359dff3559522ff550ca126fed4b2240ea7d999a182b7bb618c50528fcbd261d5e497a991fbac0cf4c105c0f664d6a00a9001c1ed522962fb44dd4159677ce8f1531019f86457c055c9cea6247086cdfe0442485cbbc4386ad002b4bd39a1a187752437f04569705cb7adc0c68f0fd059d946deb63f0b 02c3eaf801330b3f1b0504f2399f1d24455db29911f750c246ba0a134c3b59da8b3562911197764699a92ea1d95a2aac587e24f743df1dad3e1cf7edf955203e24a0225717f8d2df 986766468b2142f286c948fd8c9c9f6d49c290f226431cfdf032118347614bcf0b587254e4fda7121e102965a2e8a4d3 +734a9eb8288e32f5a67cc1d88704523ca2c68b798d90e188d871d9f50d2da2063baf1ee6685c45832a1818aabc9afc0bc935e97969dc983a484f16d2bedb3c7c0b8221408be2480a5562d5d1e5d8763d1e474bf2826aa93a68c3b870e3bf34f4941cf590d88e1f5a8cd782a33992213f3f6b4b4f6dbfb3c3c8f21f5eaf4ef609 01c3ff067497e5d387f31f0ecc9c67b3c0dd6ec8c81318c492aad83c9dec6c99e4fa47447f6f7082d636c2591d0df940b947d0a4ae3778e2b7cc8fb92214638399def894ada276b8 9171597f92744fa776741d4dc9ff17dffd3fd2d50a5584d5d0185ce7a38c5d6d079efe0ffb8aecfe359d7fd29cea1960 +68e27cc72fec8f3f1f3882c6efa08efdf21d74d13be5171da35ef2855666ad2ea6919d21dbc1cb6d296663dcbceeba2fe47a2c6507d3d4a67a61b55b0f81c93412d7e1fbe15a590e342a05f55daa55f8591171303154e615e81189a523b855829a5c96621ad118f522e397e2eea05c2603eeae6e3591215e29b2289bc384d8d4 004b4e04281b210fe78d516a5b69f878b7fa058941ee9ae8cc63b061d1eb9e12c3e0ecb8717ff4623ff5bbbcdb53c48adbd9c69636506ab929c5507d7ebafae5654aad65a263e48d b0d0adb6678f896facf232632c3712c548824a9d385fb77b04a6c26da798e5a6ad8b3b331d9ea2bf72625b87a27edd35 +e67cecedf35058b80787589514a9c81c6b9f4bced4260411d2af75bc46b8b2c962dc9d260dc99ebbf8ee64950766efc0e394184bdc8e2891d66bd3300ecc880e9d6a3d0eb615322378afc3dba89938704e9a8d0c949d4bae9838805c00377e3fe5ec6a1a98ad7eaaba6b500973dac48b26b7fb2e1b9889f8c387de535d4b2363 030f2849a713aeac95fde5ce3af853e9d070ee60709eccf35a076567be2c43f0fa34420b0fc097ff577221275a3a56e759efc32183be2d76058a7d20e5dd59f00415114d73a15b8f a51f3b8eefda6308fade4c01d7eac765cafba63429497164213aa42a9fbb8cee0ad7e145e3db91296fac101b92de5ddf +2baa1ac3f07e34b67b6af087400f261e138b070c8475378063286c16fa73578303380236a4af2484ea01ba56c1c619f6ae4e5e6ac2594c8e5aae7e7f196f96fc5d0f507bebedd4d818e77b9120e5b4bc01c7ab6339e88b71d0886631cc7fd89659bf513faf149c61eb14d55060c8dfc7e6e4c2b4ec8edaaa6bc36eca50a6feef 02ebb73d04e6e5361e20629e3ad119b33db5163ed91fd9a8aec4b774898784b6822a08992118a8fe6013094bad0be1e9bf01b27c069e4335bff7e0abd28a10443818f6b825e9cef1 8daf39b1e3aba53b08d7be7de300b2cadaee7477bd99a5c1e8ea306d4cf4ae81bb2180a27bd59975f2593dee6a2218e6 +0e640581f573068d8ebd2899a6aaeed0bf987ee11e22b05d25e88e9a1c3451f45ee3800d976f4603c18a041febef07a01086832a6f7ecd5d498d52e796a9d90758c87c36f4a5b704a39c456aaee2d5278183d5815d619c193da9fbc427d701bab0874bded848cb4bb066f56e119b637c78aeb6eaa387c41bec6cdd4bf7b2061a 01bfab717d6f6e16d9bc6e89d2ffac7cbe0f808cc8ca2eb515af7ecce5f3b230303775710a21bd25c2cc4566bb53c78c78e3774a9f306c751cc6e149929e45eef60f56c1d2388c6d 8435f5029fe65e9deee7e72988442ba2cfe636356a81b4b2d31793bb687de6a258311e093f02e679979453ff8e7b8a3e +51a2a560ba226d629127ce1ea7e812219ceaddd23561256331458c9f11fe73990f21d0dcd974a3773040090cfdc8e0f01692d951a0cbb60f8448a016c67abf46a9c150466ac77e656ea827b0ea7d1e77ea32071ba8314fc8a2edf69008f498bd1c18061d7d00f3340a7e2cd73e9766862378d8702e804a1870b442beb2d0aa14 000cc53bf7f1cad5e3dede4b4f4b082831604c92dd2b147869cdf1107259305b1d50359647f9f3d7d4e1e608865c65dc7c9ea46bc324dcb8423b554dc369d621743cbfb592b70eb5 b2fdb977f16341a136049d381ac5aab8575c6364a87e74c2a89ef59ca652580950a256163a42050e5cd095f04a74f125 +90eeecff0a2e37df318c441df220dfea013ef29774ee92a56b213e13a798858f31e52b6ccb7599e7314f12b48a89884b113c1ba0526a54f3e9a33c940944319e084bff320cf5f391c02c731c4c4f8b05afa273374a1705d6c85337782ba7d36b9c00767180cad6422c11c581672ff631fa4c49d41b02481568ec87ea97220400 02b009530cb9d586e35dd8951ccb686833afb7a37ec253e547e85b253ba999f0f186b6d4ba41091615fe57678e9801b4dc94fa683511da25637b2acc9fe60936be15af16234c4ee7 adf0979b57f6fee3dba008462d2be305547309f8f26260e6a395eca350728952335b949fc55b5f0cb93c40b79d5316a9 +d3740cad41e2e365d80ae81da97fdf06d8b6c278b505e34cb683fb55ddc5189da543540914c0accd405dbf0063f6222885fda4b316dad4a83fd03e8d7b7e936f87fc0a5b095defc8a4b22fa97f00b394e672d5efd3e0a230c7e44dfeebda88641143502a400ed62e2a51f9561e5d652a43d616f16699e875deb9610c77de8e1c 02cc2d0d7189cc8fb3565a039aee7633ddc00ff427cafad32fd2010b10fe249c9724d91785e7080203626038109158e3a61a3970aa3e51688aa7f5184b22f63af63f80d3540ec023 b365c753e6747a74b73e0e2e673054924198fa3669a1d3e1148d16bca756d7f61dcbec59c1cb8420105e0cc4e35542f0 +5eb53b5f92121396c5ff30e0c92da48db4fbbdbf27297f9bc82614ab78f7fd863e34096c615a02e349d8bc7ae4b0700130704bedf32756b5ee6af10da1cd717d624fadc57a9aa6db4a6c5d6254c0e8f8c3c0d4d03c264eeeafd52cac2c1968d9d85b106167a49d0ccdbefb20bdc10a2555f8149203af52853169a02db94e5e2a 03d8936c00c131e38c6566d2464c4e207c878070bbf681695a6cd98cab2c6e80fe98cda80c66a5cf584e90a071144dda59c07b8fc7bb42464dbee5b6f739b0f2ee5fdff7e5a4e7cf b85597aa8701a40c4a6b3f84b67702ec10120eac5ffb5461ed61a6a3ead7b24e34dde31837916b71cca73bc58e5148de +5aced64f702a57ed7fabd045a40c967a485d2a70b0a5e82561d5141ef329469b2da5964a34df203a980111a77adca376c643b9030aa74516f054648c1534d912ea66582adf3c655dbd71ca55e47412315df5e2893e43b2e2dfe6e4dedf426f11846ebef34a99f5615460ce0475f7bc54b4a4fd99e83c982097c3136ac6188a5c 03dc7de970bce28a943d7599f2a9010fc99435b93bc4ba884d42503ac2941aa63fd07db34bcbb1127d56d6a4e277d6ca32051ea3467e376f74f98c3999d2f276b282ef8a28cf0cbc a4889baf36b8b2db4be5dda34794245e965197ee183d07ccd3d70ff4f78252daa41c2b5036c99ac4ccd9fba068aa25b1 +43c24aea343d4e088bea25be69a332c631275c36677093e057de69cc83a4c5e70ab270e5a8930f55846f1a22ec10e03007dcf0942c6761e89c65c6a4f032eed97dc3a2c7f7ed1e82552fe48828a132ba16c41f6bd82a49335428a24fa1679522000e6a1d12c646e0e4b4c584398577ea9493bb334fa3cee8bfdb6c2e66f46436 02de6ee12eefa7a4a736484b19b42a513dfc059a060976edc3b0aa4b50e98d72df6506fed0499ff8480986748e938289e54a5e86c0c29733a9bcf5985aa63d8a2b57933a04a8e8e0 97e42424844e45e4c4d9a4ca704814497be4e0a72458fbca89e2b33fce9f8c471d0f7a97712ad685fae95abe68d5c6e2 +e89210565959d93b483659e62cf41f0a0147ea23890c2f1a694c377a826165e363860e4b084016cda878a43eb68465f81f397ecd50087a25215ce7c4ededa3552218071fa3acd7ae380655fc8fa884998209ffc8a2c26f1ca19dfcfee455dad35a4e72caecd8da47eb9ee21b889162f5d3032724abfd1a31e68612e18bfa9006 005468f0df2c9854f5f655743e79c750fd8812db28b096d97207bae7f5aafc6b6090c9c636ead9e0fde32a1ff8d539b53813733ca812b41b58ff85a941abe4f128d59fdf9847baa4 88363547500ae06b5e8076b19c318fee0c723d93eea93fa9a048c9730768f8b1a7b4af558cbe3afc4eaf192cae2ee9c4 +48629ec97f56273599cd9903f8a84ac2ba74275b40e1e42fa47649568babe05cf63c8417d828251acc2eec525b56dc9082b68d51b0c2bbaa7389fbee15d058cf482993b2bedc5a9101f1afdc79989a812478245d191550109fc17215679553c508c84e3d4cfdea377088d09eb214e6f92410facee4790beeecafe72b2e3ed192 03d3c6a7ab9450c94aa3b8a1ffb678e5b647af24cbfd66ee3944e6f264f406295b803767471fc67936fdfed1714b4b8761a07eec86543b7c4da6bd2fcb33fa8cda4077737f398e18 afb8653288a26c0e55217e2d865ff3db7b5608d211d7d0450b27245081592ef04667a1e37fc527b94586426bb8d6daba +aa3a9fe467b1ca638dd0622c9ea235a418b39b2e15ad81fee01b6892b240783d8db3c72e16c13df8016dac6addbfb85232158325bd7432fca3b8bf5db3abd0b4c5ccd0999609dc42199ca4680692a0805cdd68108bcb493a558ab507cec0a2782a9e976928985352edb2abc0c07078b59d2fd86fda7fc76cfe573181d934c46c 001ce010ea8e6e1a0c26ab22eb90f0700dc73b232c429d36371e68e429792afb7223f10327708bcff779ea55fb5f22ad87aa054e84d10f5450f1bc9a89279062ea2173f55ab0f76c 8c6b59ff7a644d3eedd6af397bdc5b5a80ae33758583d28590d46359aa4ff121f536fcec5eb88b310dcde411d40ecaec +6c3937014361799f1461f652841b5137eb0dcaf01dd293298d002f27e9a770b9e1a30367e35c04603881f0c814cf8ecfbe1619cc49cd516b1d60d27de37ed52a5e1cc300e2face4669f308ebe6747255a3d386f16778e494a7cdd10b45171b2bfcdabd91b805bf24857708c1b75e368edb2874321324f83a19154d3a1578c767 01e7410d012aeef02b3723346d24ebafd684c99087ecccaea1cf3735d52c4c81dda41812c09f1e874dc964d858ca240a19963d5dc89451f5dd6764426ae41cb23f19cbfdca0fc562 a3f4b5f9a456e9b0fa011d91afdc87960619803c58d46ad22a252e08898fee6702bff0f31e1fd6ccc065c7780d0303e5 +12fea55ffda15db902aa6a4388b9807c89c193cbf75b5d2a4c95206fa43dedc45974c80079933451bdc5b3ea015ed3ca2c54156dc61afb1bc82adefed1491302a48b9d3d2f474ab45343c611677d360515b93fb36da7a1c1b2341c9cce185c881c0beef33d43967134a190c09034ae3261f3295b79aebd3fe123616f73cf2089 02139839ce38eb879d266065dde5e5ea227244323b330e3ad5a0bc690f3c210f794cf18f0d730693887548bfbc434f48ee10ed34cb41d52172b06e448df938170a5e17311cab8e88 805f4639305dbd789df12c8421099d70b5295c94417f86284eb1ed5c166fd3bd9f1c8358a170cd57d973c749b2a1cd3b +c8395546842ddb545d8ea3db4efe970453dcb06025ac3b7a25aa5ef62070f3021b9a1fea91ff7055b6c398073e7886a6f71afe53c82c47b71377dfe291972503bbeb25bd477bf0e7adc8a5d3f8b34ccd0080d61e121214e1b29802b711cdd8a6bb2275a2395c467ec2c1571952992e448d736d8bd70ee629c75b5e32b8323a00 0274f70fe69e4dbb55c5d404e39f5196335047113087f8711f2f67f2be4964e4fbcb865680758df1c401cd677b0971654b7a6aeb7bee0d6d80ac0de14d4f46f356b2d5545c185aa6 a9f57a552e4ec82890606cc5682ce987d630edbdf8eff74f75ba5f12feb3ee8064b53d367bea474eac84c66bb73713a2 +10d2e00ae57176c79cdfc746c0c887abe799ee445b151b008e3d9f81eb69be40298ddf37b5c45a9b6e5ff83785d8c140cf11e6a4c3879a2845796872363da24b10f1f8d9cc48f8af20681dceb60dd62095d6d3b1779a4a805de3d74e38983b24c0748618e2f92ef7cac257ff4bd1f41113f2891eb13c47930e69ddbe91f270fb 003e1b03ffca4399d5b439fac8f87a5cb06930f00d304193d7daf83d5947d0c1e293f74aef8e56849f16147133c37a6b3d1b1883e5d61d6b871ea036c5291d9a74541f28878cb986 83bef55e9c4a8494fcdcc9762b19ce63fd89d7b25086f87590b734056df58d7a5eae42bbac14c4ec157a2d5590d1eecb +b61a0849a28672cb536fcf61ea2eb389d02ff7a09aa391744cae6597bd56703c40c50ca2dee5f7ee796acfd47322f03d8dbe4d99dc8eec588b4e5467f123075b2d74b2a0b0bbfd3ac5487a905fad6d6ac1421c2e564c0cf15e1f0f10bc31c249b7b46edd2462a55f85560d99bde9d5b06b97817d1dbe0a67c701d6e6e7878272 02e09ffd8b434bb7f67d1d3ccf482164f1653c6e4ec64dec2517aa21b7a93b2b21ea1eebb54734882f29303e489f02e3b741a87287e2dcdf3858eb6d2ec668f8b5b26f442ce513a2 968477405254bf89c5e33f4c54d81b98e32a7283b46fd04426b97f8c64664d4c91a44258fa19532778ddfc73ea8a97c5 +ba6be551bc60653192401ed8ff9e1acd9013d8811a7a1389528bf07438366f5772cd7aedad010c19c47622cec03a4d35b8003b39ed901b720629ab59de55a03c1ca50a62987f8da159e356245df58d5ae1936e65f3cd3acbe03ad1d0fcab4aaf2a7a947549ae776772201efbc6fab1aebfa1d99994d4f43dc28f39c0f279b992 02a69bc1df069c6e89722521a63675f318252be629e7558f3716917998e660ac960b0b750562846fe6c12ef492951e51e224754bab84a6eacd4147a5f26ae85ee4381bb14ec2a8c7 b2f0062151cb379f905d06e52f63c2ca726ee2834e763bbb08308b9e1c0560ce7fab5a8dc75a07cbb838f6b6d3ab021a +295720a79ac8201f40a66b06ae5d970afb15f36582897eed25cd92edcd00f70ac8e31c556eed4375ea044c2e8b227a8e02c0a3e996c9272d52ac7b3ad43b80f217295dddc84b177cf1e800ad08bf7fdd021fb2f49b54162092f8d628679c4ee335abbc90c027264c8b288c6e16eca3172eaa297ba50626b00fe0a0ad3a9dbeeb 00d11ed1b78b22b3420df4ddc4acc7c2286d9569dd6dd88e0fa3ecae69bcced68bb81bbb4ca6e9b54e67856e7fdf39155aa27aecb9cc827ccb9cdcf9ac633561b27d8eebfc261aee 8826b5937ecceb849d9c1af6fea8fbc72b3df31611c9136f12b3fa2cb75e4f0b47ccb4b45020b5e857c7a9916798fabb +a9cff41c6dfdc4a12f31dc375a5455950077ae323d0b7a3d9a8dde73b76e9d7b94ddf9c88ae8e6c262d704052ac47681fc35adfc56c904baaa6e146eb653984369d76a85596cb744941aa7b558c945ff2e81bd5ef7f00ecb4f43af23b4cea3bd4ba7b1899f1868a0c0ecfc62ccb1d588955597ffbbaf34cab2838efc2b866669 02c36ef754b5bd065e9eadde684750acc52795be80f54dd3d7a7d743d968a18f7e404bd71f8a76eb0395f396df5a7c2ff7e0ab6de35df34282fda6ee01fe5b9b68ecb4e378dbe32e 9290618362ce823a82c8294ee432c260f6dd58be708364ab25aaee9a78fd977a1a238bcfd3178e3d82c27d8eb98b59b9 +efa6c582d7fcf5e431aa89b3b00180c0e78efd7ccb0384d90b80e59a115a13e55001d951528c42860132531c9b8ab29dda7a657c53c2ce96fd85549f6f1810e121eb89961295335eaa0e40532d85814a4206e6fffdf9bff76599da9b2e71a22ed572910b0e3bae38ad72c7042579f106739a8628dea5a745168bd918736e488a 019ffee50be5496507e3ef5c40ee88a49625e46d1dd1686a52b09ad4a8e3ee9ef364f953bfcd97c52104eecb6138067192997cd4ebadaccb73c7b2560879289a46353a756b73cc43 80545c470673bf7cae84033fc6d8cbe1f5ff659ec4eb620b04cf0740cc010a4aaaad005dee8595b9a2a5b412bdbccd97 +211acebfaf13bba33a9dd16722ec53baab92a140127d61372cbf1850f2fc894e942e25d780778235f880743953d04eca7a9205602e388172aec2abf35412b483490751f93b51239b6701cb0aab14e5179b0d7f55d8586358381dd83e3e436bf69a6820317d1701750cb1fea1293467ba589eec5f5779c2dbf2a9b8f28c4dc239 03129e96fd28c4198cc5242c1e3531a3979fae643d527044e98d7721aa56b5b4b45dfddfa17a4115e10a2b4f46d92f81cbdd7e86e588a4c6d8c2b3a83f54cebcee1d1dd33e85d81a ab7062a551f9bfcf1fb00bb78a6d1bbb231bc3e950c7ba2264069bb33dbe0603043c0c25561cf8ea4aec63b1444de306 +ee592e20e0a45c18089c2e41460e65a7d22ed9714379f095d43a308bdd383128aaa6fb24e9d35fd28fc95c5b792ad75c980d2cdf0f460ac60b12c5919d3cb28dac4d488196be6c2dfe462b1b0ce59f8501692255840f5215c0fd8b74b1996a267a5e3b22d2841cf0a0b6315ef4ec7180f1c8494f4c07d5869c01fa2711739efc 03d723d2697cd07dd8444f992f2ab4a063db334034c25ea9be99fd7a1f495e3a644e5ea033a41264e0d24a911e55741d0cab80a0bd678eaec2bd1e60424d4491eb86d664900d907e 9896db9d65b73087ef77aee24973cade703399ef57f991b653dd56fa4d44023b63e8382110c1b30663ffd056e4c05c47 +fffca41927debbd53455821441d9115db99fb31bfc69752a382f57bc7abe021f148346ee29e17512c64b4918ab2391d12d6e5643bee6b5682885dc28177b292e23a37ff99b359b9cf7578432af56e0ad1028a6cce7428980654c145af8daf09addbb3be11228d3c742defca9d3b1667f48c63091fe3307ecf72667b02e008f24 01999ab45d66cd1d3a0fe6aa43bf5ef1e2a67637d53674f6fbbfb9b582be91fc42a12cdcad94b50b0fc7ac55030de24a0b99fbc4314fa743ef4b5198bcc5f54d8b669fbed78e2e91 97ca1021942c695b3fbbe30149cf5aea67444533f118d086e7c69f1422558e28422d7802c958c5cb461caf16db613215 +a2f71619ea04f7057e6943c2cece8594b341ec3b96c3915d924f94ba13fd7aaeed41ffa0e842ade414784f1ef825fcf2dbcf7bd8263b802def45f94de596aec0c121fc06558c7bb06b9f27a9bf56c42090b5dc344e82b69c4f528d33be166764a593483f6fda0cf56e6000ff363ba220f5ea0ea2c3191615c7ae3bb4fa575324 02ce1cae0716205330d730e6bc6dbfb6b951dc83ee3b4a7dae75d057e32e8a46e22be75b5f09135452b29c34dfe81a9be2e8dcd243fbd946a0ed14a832a7802e20cfe1abfd3d6e4b 8b3430eddbecac1c09fe58de03c5eb47440d8d2b9105602d0831ed139986714935ddbb2aca8b139c147ac6d6ee24fbc2 +b60415a831eca2cf60c79a334ef2f327a76d290846ee588d5d33d0a826bb0c7ec3e11dbb384a7f89c8d180425dfae7463e0ea6497d2eec1dde112f1c1efccb532a2e2b66a28e2d36d4252a4c3b12850d465fe21bddc441b92e6a7b0f67744f7f6e7812a0603211a26518b311a5b190ed890ad852bed4f6ed13377cab3eebedf4 02c9d0fcfcee7e75c3245ba955ae04188b1033c55ec9c821d8de7685276bda3e9a93c3ae1b003e5ea722913e7b169d67b1aa2dc8cd42adbd9368672a3f81a6817bf3e5529dcb0c8b a04a64fdadfca5b464543abaae1f3eddfb8703856f536fb0236d0166d6766f2a259090291ce44d7d2621e7d441ea3870 +5d15a08226cc74cf495be681b795d0bde26b19f29aca1a8c6ef77d50271ebdcb4e5fa2df23961fe11620b1c6580183f6ebdceb2c09516c8127be576496fb71449bbbf0a9d3d1c48a25024619b97c3e0d8b165897db96ae9758d13ac28441d7cbfb75b23cb423e0002046358bb6d64779974a5995dfe54b398f95f7d64fc52d96 010c057bbaa44ef0f565edc288bfe66d4f6acd8686899359bca418ba89fb690429489a37bd3c6c9f3a8714b2ca225868c6a45fee360e378a676f7ea39321790f32a4b005b81dce43 aa40b6a5361c7c025f45f5f054c284f508790ff43441c20bf19b9ffddf9d7ff7274d0b4196c0da570b2d20878ad9808c +9eca4bd88200baf61b901fca53dc1f1e7e3f83b94d58a6cc6a2adbc9b1a35fe3f8ec61787c76ed9a0d696167cd4fe46e1a0883fda564666131753c576a720125e0b712db1da0278067cb899bdb14eec08737e864544663abb1d62f34a2114be07e8e3cf56e2d17099299ce6b6d83b1a34e6153d7c6a32a72c7b1bf4583fcbcf7 02c182df7976ea93d996f3ba5d2221f3cb755cc7847bc3fe9e022fa4285046f5bfb426bafa3580beea206de36f87593ae561b4b74a03fcd61fbd0e8d6fd5668f2148819a88a650aa aa9932815602913aba2e2969a4847e18b2e8f3f8d257375e18fffdd47152a5ce774c4e9901ed66186cd99d5d1ba09e84 +707450bd84141f3b61beb12ffa5ae89d812dd11badcdf6a88a2d50fc70e23f6d822ff4477047abc58cdfa28f97ad7f4911ae0773c04ebed1f51bb2308cf6e5712c4aaed461edd6987fdd1796aab70198276b601241f6a14225dce575830ff60f935fd9f567d1d210652e4710922fa793da78c8fdc30c273cb08365c9fc887f50 02d3a65bbe133cc98cf0eb56ee1362195968b4eab960a1d55d8b762f1361fc21348d6f275d4bea1de7158fb97c995e20b92a9c887a3e332d154667ad167acc632eb88a0ead6113a2 97d5ad653fc483afac247bc90974fec382af9996da6162e644181f9defbf8a16d3d58c82f84319338ecfe1da3374568c +d5ce9d59391cdc47ef942dd2a818d024ae3917deea8a5a4214e4db6a0c5e6b0936f3e632fdb68a3f0006e05c44b7232013e1da5f877cd197f44fd6f60c1fd2378995e9a47534948c5a09e33750f07a7165072ab38095373b07a50bc1391eb6b650ee13acd63d0352e7d9c31695ea1ec6323f9b5f57b426ace56aa7fdbf419be0 02a920e8dc928acdd56e3655b2340d4371c793e66f67405fb7a90f31e9c4ef466cc44331d1d2fe3ff7391d2576dc6640772166ef8c154a5ff1808f5dab2f03061070ec8b3f786c36 af7642120701a61f6d96c5277c3a716dbd1a66ef7dbca28c85f5977966b06e38e606bccaec34471669ba82fe1f550568 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B571_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B571_blst new file mode 100644 index 000000000000..4da2306bfcb4 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_B571_blst @@ -0,0 +1,60 @@ +8e14f713a2c427b1f79491033994f76acbead614d12e73ac6f3f518f2052a10c1273aabe628ab38e0d3d5f8ff254802e9f44a51367bf80325b6fc39d907a37f731372864747b10749ea5cb3d3a83da39c21a7b02885a8c1770e4397cedc958e4baa21d5007569dc9dd1e45d2181709d900a394454090badbd0cd9c2cd2369aad 00f42afce7f7b3d45f3f925ab29fc3882a89c9f585177887584703cf8bd8fc572e677adfa55b402446fe1e90dc855358d92c3267c35be9674b40c2ad5ce8dbe6a533c44b0ad8d2b2 a0ae0f38edeca7f4e6d3f45f45e9e1611b992767dcb0d7700338c3241259581295fee3a2394ccc630c486da484b303f9 +38b60d27ff08fb191811036dbfd5b39e1cc3427ff70efb67c851e9cb407f9fac6f348d289df98d055eec73299fcac068bd0fd9ffa3c5d244659e4f714a58d79f6727f323a7ee26369000e90e34e106f99f5ae2ae1b64ee89e5a1d304ef20c071a7773e9b977ed3d49f467d300a881c8371041394910f9c366942449045568f01 02f36613043cbf53ad36e2b38998bb867503359ae082d07d040e5a10a43e06ba9c91e7c73308e41e2391b65e634f83b162cbdf4e7a44ad818fb93a978af00f06be06731d8c5886c6 b1712c78160c7920bbd35c303f82158ad03274c34dac3068684dac1c1280ed60d7c7ece435aa69b85dc2fe94aeb21890 +21709eeaf9e1953822294a478dfacfb205fc25f447a73a76a32601c00784cbf2f9ebd41c22721d70cdb3842dcaff4a4f208d41c0816990e421cc4b8538ac2f347cdd0aa2a39f1aa26ace8cb6a606b23f6244894d4594a0f6a5b8f6a695fd66e1a41e2eb6a377017177fec56bb58c837e311cd04c5b50575faee32606b9636ec1 02e74948c46930cbcd9dbe2325539c7dfdd910f309fd610e6599d425aad9ae230a8d4681970a14f2a71fd08030d0a40ff40dade7de1b06a80441bbf7e2fcf1809cff39c7ef88bf9f a595c902f5f08a56011fa719d0dc58aee79c2535c64cc1172b8a3609c14f323a1fb9ed4b1f8116dbf228a5e87586c8ec +3a131fabf3dc97334f212fce41c44300440d16de1d6060450875f7276f53c026e2a511681b5a8d75fc0d578546339542833145f7ee13c708df33e584445a75a5538829286480d339be7c777c03c998a6d3f037b25799ab2d541021502a0b02a9b9c337a8b176c4f30e5b186485a6103b1d1563ad4ae73ca806a5e4daa92e9100 01b5fab1d36f6f6d559f65d8b01edba610620fc3a38307b1fb1c5bd63e7ffbd4a9098cb8bdf50975a873f5d047ee2b627b090897a7fb5f56d3f4a0f3528179e7c969926fc0d3b0e5 b5ac863473bcd66baa5aaa0ee8f36d0df8bbc7040a9834195142d6059272e696f53d071da17fa3c97d7b0faf341279e9 +679d85a762f2574b0b31b516270b7d33d5e166c83e91a0f48e0f3db20b52f42f9e6ee9648cf58267ffe3b713723cf3df52b5fab5c14db1e7189f7cb7170bc6ec7cc71946745e152b39180f828688a5b6c0b2957ab94283b90052a3c6e36843c391aa8810f9253b639a8d5a69aec10070603ad7a99dcedb544858d057a1d66b89 0383e70c71b431eedd4574f65d01fb0304f7744d668408c847f7899eae44770a7f3243109740f177d7146a27748886b7b77ecf3792b512e8d8e37c3bf4ecef2b1253df7066498f01 abd798d716c1e173e8178050ba7e0bcc9601825737ea5d67f604d10766b70d4e696fd8b4f8976b44ca91efb826c8070b +236152ad31ce2ffc0dead3c142cf6c770672cd2e75af4a82fda1a72e1c775cec9b481c6f3e411644df7e7ee901c501405620af4b6e9667dfd46091788daa95ef2c6c9f5c240c06b15cb0df51f5f058d8a7934bd7845f007a35f99fa97200b20f3b5b14fbf1e372507f3b2f377e8d07d30fd3e222f398f26d8f428e320327f901 002261d4ead21f02fab19bbb0da8c272286704c8f0c6842ba47ded121e5cddef79fb34e6b9694f725ca502949faecfb21e3cc062a2b4c654bd542d9a1fe8d97bdd0905c510aa0999 b3cda2262a56a9998a51008a5627999351cb68c8a790b6216ca948a54cf8b843913f12a260a38f16330439bb1cb5a3af +ba3f02c4847fae035d747db246fe4e82fb9224ff9cf568a6ae548f5dc2befb2079541d2cf9aaa6b18c281a05e7ddfcdbcefb25f41dd91cb3092b3343e16985e91c912215cd99ae4a099baf628e33a7b277e3c36a13aaef85418fca99f64d73b789f23ecbb76c3095ade0a5f7f34836a98c5be933b44a94a2eaa3f99b1d8e7937 0316c78f289e1860bb623082be9d9238b88e38c5e978a868bb90f776235bdff4eff591877b7f350cf14c40356922b2b6aa51d64990360b2b0e44d6941b5dd9492b4f4e1f42ca163a acf4209b435ba18da0d68f4d262ecb236c4d98ab30ceb658712af4e7a883a659e59e48bfce96f28c0404b1e7cd6c8dfb +6d0372b40559e075af56af853cbe18ba2d471b0fc8917764abcc69102b03d5bbe1fc12458215be66409c26c89f67c72a8933677a07f88993af6918acb074fa915fe883b24bc3d191ff1b08852f07eda98977e70eba072d8bf189cd545230f59559ac05f1fa3f4e65886d0bc274a6e02e2399812b2bf91abae81e21279c5de996 02c1bc13f8320d97a82f3d9354e195481902214e16a4fd89332a0499208e91d50e5cabeb4927ba030cb42f5bc53b10f500fa646a8c88508cb0d63ebfce5c4bd574c527d686c735ce a59e88621f4bf24aaf6695d88662692cb54b3798045016b410b56caf7997462a48b95e775b978fc9ec3a9b40a0e34602 +bbfe66c82bc060bd14fd0e40769d9b3a026eb447550dd9f118c30d8448f725f8366edef042447962ba7f7f833b9e9094d0ff600714697e632626e7d12a592e040bdcee166dcda93952323191021bd12f3b1647d0f25a41739994659dcbb19333ca30f46f539c6f0a5c354cda8969a1eda572a309950c84c7607eb8ac20163912 013bd80eafa67663e75d7ae139bf285d2b9f1e03d8e32153c73e26d06e86d7acad22bde9f121a3f1ea674dcc1fe67bc7f5398d5e92555056bc046a02b0ba86c2a0dfe32e91add5b6 8785ee640b88603da0dc47e27f4bcad2537c16a9519bffb180a983d27b4a2a6aa159df9332b84aa0eee1b7054b2b2d79 +b35e9bf686717ce3b16a59963a32a2116130453b161a4e7ceb27b755856add836d779696edcaee3b5c986523891c8836109d431e55c23afbca022437ad19e6777efabb6da3bba1f5f44f905395b4cc7c9210590fd38da621582d059598e5e4569e904358e0dfc0dbfda4ce75538aa97480912852bccd433a9b96c9c66e9597d2 030834b0a4284097cdda2ada6947c6c281f7290a49b56becefea1e2788ea3ef78fb96807633c47c25138341768b241164ce0d42f7301728b928be2c047f2eb60fc2f844ab77306d2 b7ae26c116a4dcbf5210e2136b9993cb8b3df0a296a8fcc0a1663e15836d491b511ff480278f0ecdca00737d9fedc9d2 +57b5ae7e95c638b258d1e09b3fcb4341e203f5706862e199b103c8fdac72cbc5155e5cf8b300a0b3fb0ce1f897c45f7aefcc528182f73dd450cd84d5fe9eadff3f704dc2a01b4e847c22df430efd1c66b0199f3e5b59348af5386962a5ef25204fd230b54d58d7fae801c086f8f405d3d0aa7a9a9da15c22b868817cd897d853 00c81a79ced1eaaafc31b69a40d9939f4e484d625db6364a8e589b6b4d336d458b44287ea6c6aa7661113fc07806b147ff98216fa0c08708dc9d651821b922741deda522b4e436ad a086a984977b2abb839c84156af6d12cb7280090c195afcd4ec0602d5ac81315ea0dab68ed474dca61ca99b9332c155c +daebfef74b452f039c999ba0528be3bd9e16deb5f46f6eae87b63db8b89952c949fd7db08311871eb2596865eed107aa065f030226ea675ee3256c31a3f85ddf4c21760582144e07af208f33c5f47cc026db5403186a65a47940691ea2d74ffb1245676260ef5717dd879d8b5b72d96f87fef5f762d4fd17454cb5ed83d8a11f 02f24670c0f77d2ca0266a743023d2c7413d56d0b5ec77b454ac59087efc4ea4d46179e10278e4ba416ffd8c3f9786ed202faf8251c0ef5a9ea5371fbb35b7afe3d15a9cb4bad975 8e5e7590674ac70180d25fc0dd8d6c511c50dee1eed1c4767d9107219206d92220b2903bad719682ebd9cb3c9adfd1ec +62af0493ae79d71b552c4647d1fb7ab2f282a91cd44aebd8ef344dfd77b521b0c0a3f72e4513c8ecc0e4b84efef3df9482a07ccc1b740c571c5e69cb913740a792aa231b9dc87edfb72bac188293c6c6e788cb3dff32e8f483f8f34e21ee7efec71302cc3bdbfa47908a135f6ef3ff179dcef26d1a3987f7be967a6c0f799b0c 020985f2c6fe3ea04bdbab66a8b6167e5969c073b9d53cf3c77cebbf73f4dbf75e601620ec9c3107bf3fbfc6c79f8f063409bf8fe1d14b19e323d857e23dc05157d270c7514137e4 a81b0b0b72c327ed063723f7db91d00d93f6cf4309da0f9bc31ecc4129a88e741c9a1170cbc0393d72c7b0972864df4e +566f17851951777ebea3f8285610cd8ee5f882a68e7a4205e6fc9e2d66d210ee2505ee73d6503169f7b903012d43e7e99efa493a8e6ef926b16b9ad8f52156840ab561fc6b680120a88714fd66d1d0742189bf06c155e1138ee5314707173f7352e2cea0fc26e1553643f2490428718e44afd8372cbb7bf5b88234318ebf4355 02b3d641607b8a141f876f6d285ee46aea543880e772dadd5dd83d595b9643191d9597218e1d6adb081df133304037bcd2c05c24a54e6c4cca64fb2cc4569d6882315360059496d8 b77d1fdfb22b3fb39570b21c6ec484a6ff911cab108e4e40733bbd4462c0db07e2e3107dada85bb5ef55c7a14138f47e +25155825fc4f9a1c4dd1db837008e7e2594a879052431f5bfc76d0d2565b8fa726008befaeddceef73f3c60fa2cdf6d9a70e56d27210bd013034b38861ae49640ef208d3fe294ac4362f8eea44f58af3af8a9167a36b5acafb7ec95652d5885a0e08067ce1dfbb45a0c89ad1acb53eb404bf88fa5c3c463a0f912b5a2522a0d9 01afeb5ca87c81025ddf09c2b2c5ee22ba0105c0e619b67a324467485bd839030d149fee44d8bac6f5902a1245a50c3437046b7c89a84116b2147cddc645b6d2fd24d68e8d53bf5b 9652c252cf5e966e8a05f1b93e85d0bd3f4b64c120311d8ccab7894a1d353a9ab3c012f99daad1617ad5488424b24702 +29acb0fca27e2a10d7b9e7e84a79af73e420abdb0f80dd2665696638951b52dd39ca028166b47a3b6a2eaeceb1a11c152383f0bec64e862db1c249672b3770909f775b794e0b9b28a5ec8635a996d912d837a5f22471b40ec2e84701a8804127a9f1a0b3c96ff654700bad3167240c2518fb5dedcc1be9f56a807083e587bc56 032c97639b69c7cdbf419286d0a1b406d9b1f2886521a8b979a36118d2a368aace5b02dd8c515f2041e6fb9f026d1e82e789dc826a56d2ef732b1bb0f49be2b696ab5d3d5694a2de b2ff4b3b4fd21155547c48f4fa8ba79760ad4c1cac8c007d03b0464ec1b4e0c97558ad8d3859ed8c45aa60d43d2b09d6 +c92d67cf6536f5046e15b02158da698bcbba4ff1e4e9e9c882cda67f817210402ef917ae93682c9c3dd817b21b73c6c00b7bf92ea80ecbbef2e67f4f4379d078a2b0f297742b2bb9c3fa3297a7e8079f488555bd37715eec92b4b1cbf897640ae8a1d2a0fbcee5423ab31a37629f98630275e35094a896cc574be0a449bb1bc3 00f93672159276c5a293582b9f49607bbdb970112f6c63b2b3b5d32ad3c8240c86b1af13a8dff6502c6b6a17712cfd988f8cd23a60693d64104143b3f91adb37f852e9e11a0ef110 8625bea81a2edef40ebb0b11e14f2768192fb23ed61db7f374fcd3ccdbdab22eabc7477a40b82dd5ca5a94b396d12598 +15413f614c4551e3b138b64f66d15f8964c40326a42b0afce820778eee4a88edb127fbf575da5263e5a2627b5461d311813ea868e6417615e7c4938313675009caac28bc7a2f4c0bc37572d9bf36a3b1794294e09c0121ceecaa4b916df45b0dd31225415e6c87cfeeb092a008fce2c543cd62365779ae28f29fa02a15d9dcd5 03db080bc99c5fe7e06d5032167af56783cb423fae59fb5b3c6bce5fbedf56b7b39b17810e48ea9a172881aa1f42f5e267349b60294d4a208b4437666b44abcfee5a1829e9467908 ab9c94671d6404a188f91c5f6fb1a55be146466bdd3d86af6fa1651faa49b62a970e7cc7c8585af908316676831e1848 +9f901557451ae2f8ec79b6d4adc794cbfd9b2e6d28f19409532d91682820205308b41498a4e1ca247a2baa8da93de95e3c0f7afd6ca46bafdbdcc6d3374a12684676a50988b86a960a82180648c8c1e38f8fd9af604c7be3be4b24799f4544ac96d6360cdb83d1d0847fda21642934fd6cf65385b50d86d4656987901fb88d0c 006ee767f6f36bb8f364f324d8346455c899a49237d759003dd52cfa13b9baa4c71347b134b24ecaee32d247c34e3787a0c64bc5d299b55c86f64b47521d22f2c09db225b0c84cc6 841b5a5f6fc092bb8a72ed88de75426d9aeb8246484c34a178acbca7c443ef34606163086eedf34a2b3b7777bf4ad53d +959fe5a19d7aea2ba611c7203e19f8e3f3cc101e03a98f91adfef602c424c580d5a868659368a930f9883d699fc633bd07f6cf8de474937db0bea86fa7cd140ec2f202663813033a757b93bd72afba15be5e47a4eb93e8a666aa1c72c241ca3922547d63fa3732fec54afea7ade84302e2f044275bb67433fb6b125b7913143c 038e2571d9f22309a636586d62863ed67a70538287f3ef88b88c3c2fa1a2900d48c342b6f15c26b8e7fb4875cda4093b7de7ceda48fe1e2cc2975afe958040881de61f309931e48d b5b82fac5dbf099943fb604164d6967739e3cf34c3f062ca89a6ff7c95f9540af14bf75030c0b83430a5ba8f889cd008 +97b9688d9ed5101b8cfb19e84b89cd644262ca1c7ee18944e29ddd3b4cca78e06338b270385b00a5e8b91ca5e628de3bba50e36ecc695b3ea737a9cf8b36871c473a54ba17819f49e730c0f253b0c769aefa6c16366fd2dd612f330e95fb119fcf3bf7f3e254438c0ab635ec04a8b2424a05b483ecf65b74a93636fbab7bf1d8 00c8f5736f1ae65592f3ca850f43d06441aaad8c03820f3b08d8a6db46488dcfb828459f8b3f34af73cce8dc7a5e3834e085a64523d890028e194214cef4003210e6eb530005b01a 877fb77ec661372d7c11a0c765b1d28e1ab9c830ae3bab399363a04749fc0b9a8f96a20b74ff5ac20f50385aee2267a0 +f08b250bf4a3980cb455338b3f4173723b3f44c97bacc9cf550149794a71426e398cb4a74bde141d8b7b4a72942f1c069676a9918e27792cb8f085ee037c78e3c468adea5123c4c64d8ca6a39f2f90140c5d2d80b669cbf0d1ccb466b18ded83a1d5f042c36188a04111c34ff769abba9aedda40a87be1e24b700225e2078056 01ee68c3994adaaa9e0d61bfcd3bc1cdf198d3fbfe28a44e5dd518867ea04b20e795eadacc48bfcf8e8216dceeaa069b756e8e99ed87b6b1d31154cc9310bc3b4555162a890b0c6c a6a604f112f60131d4ab528f4763eb1bd406cee4b883786f80a2512e56a469743ffd288535bd2144e7811ff4c669f4f3 +1cabd16fc29d7d919622810dc8b23c770b790b98b119eeab1b20900fa94fc2ebaf76be4f5eea91fc5276c5621c8677d4d117c4a5a782ee2ca1d5b0db997fdc8a05b6b3fbb833d7a7b81c3c615c2a662929760a96feefcf89e46b563314c9b77c86bf34438458b43b694ceba741b97dfcdacc0ed57652ae62856ce10ed2690770 03a6fbf66ebc1365ea7699c72cdac2dd85907ec59cd26e2d18713354b619ccb83b7fc0db9193aa8493c1855f1a83fd987cbbb65de17c59fbe79256aa5392f4eba045346e9ba26592 8fbad75a933678e85782c1a01d313b3189730659eb4458a09420084929ee16ca4b35f1eee34bc5cdc9ab04de828b2eac +7bc8bbf5ebeacf40b3c82eb6eba5d994dcc6a3f2e12ef741f90f90e176d20c21e006ecdaf14cb5beef35bff46b2c374d9ee224516679b1a9e9255cd8ad8e60ed234f8ee7e0fc53c9021488158217d4b4369cc597d6053746efa1e73340bdd73c1bd2eed57b92426fd4d278d6a86e8be0f0a66ab3dfadefca8831b2f488636251 0145748871a0b5c1cee628de04a12fd68ff2b154fda96e47afaa96389d66d22802968584f6753d36618d49ed205260f09d3f5ccc2b27a34390ce58179b9834ff92a86d66ea0a97ca 93f0d4aa68ee5b7d25f753549d6dfee536489dc390a92d766599fe248561acbd329d144556c01c1846f8b042e06bfe87 +0cd2a45392871c0c262e7e6f036946354bb41f9c2187b8c4d399231280682f3e0a09731fbfd52c76ee63b9828c2d731f4cefee0a8c46419c398205b2ff80c67d7756db300a0a8385fa287dd37d9126f75998ae1cbab5136560592118db52fbf102b7ff0a1ed45b8a91a7d99d13a0f7fd4366392264aa1248d7324901467457ca 03c71911d24ad19c20fc1d8a044d63c9bb417abc3778d7e6234c6af79b898cbfc2f2787244708d2fe203be786edbdc4c9b12b413156b7b0bab0be8af895d191d853cd58aafe1ccce b8b1380f4217d3fb831966adf5f22b87ff3664092ef8eee8266473b45e8f3fc030c26b0dcd43be5804129f137d9a7a77 +e97092625b09c9ae6e152e1cbee207d83361f34cb9b0e727c816a5ed851f12f91fbf88ad9d4c8f9d07350f5d828fd8574eafc768bc72a2b18aaf4d2b48fb10f7c3431137b51850154de9706487d69a40a8f4cb2c799f48c5d8f518aff752500de93cbb94ab04ae1e0c7183a32d79a27291dd07b5fb6e6a4fab76e85c3a8607e2 018bd74698bac36ef11add6b3e3fad227ecd868f370ec04569462565d2f0af2340bf793486953a7b79ab04f0ab1f0e4fd16bf6b576cce677d543e73aa8edb0e50372f24ddfbff966 abcb0af8956f48ecf8a4c757aa0133a6524f822f440682ec51dfe9c85030cab11099a7af98f5d554ff71ab042bf39b3f +ae6723b8df5d6ab5fcfaa22d32fdf106d211514cb1892c7c43ca6cd85c2532f85929c8a259ed251215063cf92e1502528d1e22d5cf67efa0b8ef21e8eb2f5dff881ba1433e8bcf2b6af8742ecb2bccde081e534615a305562cc22d3398f61f277d8ca785842bda85d8a40438d9bf1aceaedcfc22c85533794a69cfc320931d3f 0335699bfd058ee2e6163f55d1816bf3669acea8b73be9c4ddfe775230925e6093cff7a66813adf22222c8376faa106d85ac9f3c67929bc58d8986795b6d35d5b9fa546dceabbedc 8e9c2bf25aa83cad3bdfcbca2118993f000ff82133566d496fcc35b9da38ecde59af99a24f2929cb68a5ddea75d189e8 +ee20c6b61886e02ed94359dff3559522ff550ca126fed4b2240ea7d999a182b7bb618c50528fcbd261d5e497a991fbac0cf4c105c0f664d6a00a9001c1ed522962fb44dd4159677ce8f1531019f86457c055c9cea6247086cdfe0442485cbbc4386ad002b4bd39a1a187752437f04569705cb7adc0c68f0fd059d946deb63f0b 02c3eaf801330b3f1b0504f2399f1d24455db29911f750c246ba0a134c3b59da8b3562911197764699a92ea1d95a2aac587e24f743df1dad3e1cf7edf955203e24a0225717f8d2df a0b9f7a860f2edeacb51f7555454de4879fc2c6d764f9eba2605bbc5c2890138c542bdee38c9978fc6b422c0c044eb59 +734a9eb8288e32f5a67cc1d88704523ca2c68b798d90e188d871d9f50d2da2063baf1ee6685c45832a1818aabc9afc0bc935e97969dc983a484f16d2bedb3c7c0b8221408be2480a5562d5d1e5d8763d1e474bf2826aa93a68c3b870e3bf34f4941cf590d88e1f5a8cd782a33992213f3f6b4b4f6dbfb3c3c8f21f5eaf4ef609 01c3ff067497e5d387f31f0ecc9c67b3c0dd6ec8c81318c492aad83c9dec6c99e4fa47447f6f7082d636c2591d0df940b947d0a4ae3778e2b7cc8fb92214638399def894ada276b8 84370e001ddb9084783bb6c04b85948418db33473f9f059267cdcb0e39477cf7a5e5a1e5f7d2b307b408e451f1ed376c +68e27cc72fec8f3f1f3882c6efa08efdf21d74d13be5171da35ef2855666ad2ea6919d21dbc1cb6d296663dcbceeba2fe47a2c6507d3d4a67a61b55b0f81c93412d7e1fbe15a590e342a05f55daa55f8591171303154e615e81189a523b855829a5c96621ad118f522e397e2eea05c2603eeae6e3591215e29b2289bc384d8d4 004b4e04281b210fe78d516a5b69f878b7fa058941ee9ae8cc63b061d1eb9e12c3e0ecb8717ff4623ff5bbbcdb53c48adbd9c69636506ab929c5507d7ebafae5654aad65a263e48d b9c12d8f51c445e63afa67d9567ffd8456f88832c50949e6e6858d79e204b52667e92de983f9bffe1554178158798fa5 +e67cecedf35058b80787589514a9c81c6b9f4bced4260411d2af75bc46b8b2c962dc9d260dc99ebbf8ee64950766efc0e394184bdc8e2891d66bd3300ecc880e9d6a3d0eb615322378afc3dba89938704e9a8d0c949d4bae9838805c00377e3fe5ec6a1a98ad7eaaba6b500973dac48b26b7fb2e1b9889f8c387de535d4b2363 030f2849a713aeac95fde5ce3af853e9d070ee60709eccf35a076567be2c43f0fa34420b0fc097ff577221275a3a56e759efc32183be2d76058a7d20e5dd59f00415114d73a15b8f abe495ff4dc8c5f2f3322b77b19d07d882f29e52d0240393c72537af8fdeefb8ea6be8059e9ff81c538914c327bc33a4 +2baa1ac3f07e34b67b6af087400f261e138b070c8475378063286c16fa73578303380236a4af2484ea01ba56c1c619f6ae4e5e6ac2594c8e5aae7e7f196f96fc5d0f507bebedd4d818e77b9120e5b4bc01c7ab6339e88b71d0886631cc7fd89659bf513faf149c61eb14d55060c8dfc7e6e4c2b4ec8edaaa6bc36eca50a6feef 02ebb73d04e6e5361e20629e3ad119b33db5163ed91fd9a8aec4b774898784b6822a08992118a8fe6013094bad0be1e9bf01b27c069e4335bff7e0abd28a10443818f6b825e9cef1 83b870863a548ce85d1eb99b2f573a5974e88cee8b42a6f1bac12aefa242f285a96e8fb65008b606da9c95521ed7de1a +0e640581f573068d8ebd2899a6aaeed0bf987ee11e22b05d25e88e9a1c3451f45ee3800d976f4603c18a041febef07a01086832a6f7ecd5d498d52e796a9d90758c87c36f4a5b704a39c456aaee2d5278183d5815d619c193da9fbc427d701bab0874bded848cb4bb066f56e119b637c78aeb6eaa387c41bec6cdd4bf7b2061a 01bfab717d6f6e16d9bc6e89d2ffac7cbe0f808cc8ca2eb515af7ecce5f3b230303775710a21bd25c2cc4566bb53c78c78e3774a9f306c751cc6e149929e45eef60f56c1d2388c6d a175c29c5ab6f1b64f0a7821642fd6bfa61f1f0c62af889a9066aaef71eaa788c04a2c7dada13ea48d73f11d38cb5b32 +51a2a560ba226d629127ce1ea7e812219ceaddd23561256331458c9f11fe73990f21d0dcd974a3773040090cfdc8e0f01692d951a0cbb60f8448a016c67abf46a9c150466ac77e656ea827b0ea7d1e77ea32071ba8314fc8a2edf69008f498bd1c18061d7d00f3340a7e2cd73e9766862378d8702e804a1870b442beb2d0aa14 000cc53bf7f1cad5e3dede4b4f4b082831604c92dd2b147869cdf1107259305b1d50359647f9f3d7d4e1e608865c65dc7c9ea46bc324dcb8423b554dc369d621743cbfb592b70eb5 b9fb3f5a4ed82b3ccfc095e1201ad7aa82de52159a6637b2cf2682e3790e4c00a073620708b27bd0ae2d51dd9a7509b0 +90eeecff0a2e37df318c441df220dfea013ef29774ee92a56b213e13a798858f31e52b6ccb7599e7314f12b48a89884b113c1ba0526a54f3e9a33c940944319e084bff320cf5f391c02c731c4c4f8b05afa273374a1705d6c85337782ba7d36b9c00767180cad6422c11c581672ff631fa4c49d41b02481568ec87ea97220400 02b009530cb9d586e35dd8951ccb686833afb7a37ec253e547e85b253ba999f0f186b6d4ba41091615fe57678e9801b4dc94fa683511da25637b2acc9fe60936be15af16234c4ee7 8646927b934a26c5fc249a7d241e2c89035a975d29e5d0bca1596f70720db076447906262ab2d36ab56dfbf400ce9d86 +d3740cad41e2e365d80ae81da97fdf06d8b6c278b505e34cb683fb55ddc5189da543540914c0accd405dbf0063f6222885fda4b316dad4a83fd03e8d7b7e936f87fc0a5b095defc8a4b22fa97f00b394e672d5efd3e0a230c7e44dfeebda88641143502a400ed62e2a51f9561e5d652a43d616f16699e875deb9610c77de8e1c 02cc2d0d7189cc8fb3565a039aee7633ddc00ff427cafad32fd2010b10fe249c9724d91785e7080203626038109158e3a61a3970aa3e51688aa7f5184b22f63af63f80d3540ec023 82e6a966be8c680e4aee985f41a6d539e18dd1a9aa8d04c53dc352f51e5fa10ce3c41cd2080110b26067b77d118504eb +5eb53b5f92121396c5ff30e0c92da48db4fbbdbf27297f9bc82614ab78f7fd863e34096c615a02e349d8bc7ae4b0700130704bedf32756b5ee6af10da1cd717d624fadc57a9aa6db4a6c5d6254c0e8f8c3c0d4d03c264eeeafd52cac2c1968d9d85b106167a49d0ccdbefb20bdc10a2555f8149203af52853169a02db94e5e2a 03d8936c00c131e38c6566d2464c4e207c878070bbf681695a6cd98cab2c6e80fe98cda80c66a5cf584e90a071144dda59c07b8fc7bb42464dbee5b6f739b0f2ee5fdff7e5a4e7cf b83ba8a10a64f9ef03d066ce8eecd1037a2713a1e9f0c0b37c5a66758783e46657c9bed650783a07093de564392cb9f5 +5aced64f702a57ed7fabd045a40c967a485d2a70b0a5e82561d5141ef329469b2da5964a34df203a980111a77adca376c643b9030aa74516f054648c1534d912ea66582adf3c655dbd71ca55e47412315df5e2893e43b2e2dfe6e4dedf426f11846ebef34a99f5615460ce0475f7bc54b4a4fd99e83c982097c3136ac6188a5c 03dc7de970bce28a943d7599f2a9010fc99435b93bc4ba884d42503ac2941aa63fd07db34bcbb1127d56d6a4e277d6ca32051ea3467e376f74f98c3999d2f276b282ef8a28cf0cbc a0e4c9561e949868de4551c335949570bee1e33a0db14dc61ab15e2777b2bcf2fd9f600b4f57df234f64e695c5e81fe7 +43c24aea343d4e088bea25be69a332c631275c36677093e057de69cc83a4c5e70ab270e5a8930f55846f1a22ec10e03007dcf0942c6761e89c65c6a4f032eed97dc3a2c7f7ed1e82552fe48828a132ba16c41f6bd82a49335428a24fa1679522000e6a1d12c646e0e4b4c584398577ea9493bb334fa3cee8bfdb6c2e66f46436 02de6ee12eefa7a4a736484b19b42a513dfc059a060976edc3b0aa4b50e98d72df6506fed0499ff8480986748e938289e54a5e86c0c29733a9bcf5985aa63d8a2b57933a04a8e8e0 8e4cfdff0b50be1300b30f5f579ad969637130549ae89e5b57a5c6d98f2eda3545d5c4ec6c09623fb08db7b3988af784 +e89210565959d93b483659e62cf41f0a0147ea23890c2f1a694c377a826165e363860e4b084016cda878a43eb68465f81f397ecd50087a25215ce7c4ededa3552218071fa3acd7ae380655fc8fa884998209ffc8a2c26f1ca19dfcfee455dad35a4e72caecd8da47eb9ee21b889162f5d3032724abfd1a31e68612e18bfa9006 005468f0df2c9854f5f655743e79c750fd8812db28b096d97207bae7f5aafc6b6090c9c636ead9e0fde32a1ff8d539b53813733ca812b41b58ff85a941abe4f128d59fdf9847baa4 896ca316c36ce59c7b000b479cc0f9b43e9d10dc17e4b2aec88f4321a2ebce86f353fee926a209872ceb1ad07fbc5471 +48629ec97f56273599cd9903f8a84ac2ba74275b40e1e42fa47649568babe05cf63c8417d828251acc2eec525b56dc9082b68d51b0c2bbaa7389fbee15d058cf482993b2bedc5a9101f1afdc79989a812478245d191550109fc17215679553c508c84e3d4cfdea377088d09eb214e6f92410facee4790beeecafe72b2e3ed192 03d3c6a7ab9450c94aa3b8a1ffb678e5b647af24cbfd66ee3944e6f264f406295b803767471fc67936fdfed1714b4b8761a07eec86543b7c4da6bd2fcb33fa8cda4077737f398e18 8b92c1852832515a5133db29f6a26ead38be8b228fbe6fae1b210ad207be6b872d1fb79c065d5c461ffaa27f98602db8 +aa3a9fe467b1ca638dd0622c9ea235a418b39b2e15ad81fee01b6892b240783d8db3c72e16c13df8016dac6addbfb85232158325bd7432fca3b8bf5db3abd0b4c5ccd0999609dc42199ca4680692a0805cdd68108bcb493a558ab507cec0a2782a9e976928985352edb2abc0c07078b59d2fd86fda7fc76cfe573181d934c46c 001ce010ea8e6e1a0c26ab22eb90f0700dc73b232c429d36371e68e429792afb7223f10327708bcff779ea55fb5f22ad87aa054e84d10f5450f1bc9a89279062ea2173f55ab0f76c b8d9c14cd8e38b328f20d27643f3502bc55f3849df1ee718525d95b0e26fe35e814e59eeb04cfb86f8b4216da2584da9 +6c3937014361799f1461f652841b5137eb0dcaf01dd293298d002f27e9a770b9e1a30367e35c04603881f0c814cf8ecfbe1619cc49cd516b1d60d27de37ed52a5e1cc300e2face4669f308ebe6747255a3d386f16778e494a7cdd10b45171b2bfcdabd91b805bf24857708c1b75e368edb2874321324f83a19154d3a1578c767 01e7410d012aeef02b3723346d24ebafd684c99087ecccaea1cf3735d52c4c81dda41812c09f1e874dc964d858ca240a19963d5dc89451f5dd6764426ae41cb23f19cbfdca0fc562 b91c79e77b06b451d3958a787c1fe8339c752592c3041210776e9713684bce47b95b5625adc4b1ed46f0c2576221b320 +12fea55ffda15db902aa6a4388b9807c89c193cbf75b5d2a4c95206fa43dedc45974c80079933451bdc5b3ea015ed3ca2c54156dc61afb1bc82adefed1491302a48b9d3d2f474ab45343c611677d360515b93fb36da7a1c1b2341c9cce185c881c0beef33d43967134a190c09034ae3261f3295b79aebd3fe123616f73cf2089 02139839ce38eb879d266065dde5e5ea227244323b330e3ad5a0bc690f3c210f794cf18f0d730693887548bfbc434f48ee10ed34cb41d52172b06e448df938170a5e17311cab8e88 93fb87915536ecafaf256ef47c7f8eece7ad231fbbde977e364bd372b574ad16f340847e9603294409480729aeb48b91 +c8395546842ddb545d8ea3db4efe970453dcb06025ac3b7a25aa5ef62070f3021b9a1fea91ff7055b6c398073e7886a6f71afe53c82c47b71377dfe291972503bbeb25bd477bf0e7adc8a5d3f8b34ccd0080d61e121214e1b29802b711cdd8a6bb2275a2395c467ec2c1571952992e448d736d8bd70ee629c75b5e32b8323a00 0274f70fe69e4dbb55c5d404e39f5196335047113087f8711f2f67f2be4964e4fbcb865680758df1c401cd677b0971654b7a6aeb7bee0d6d80ac0de14d4f46f356b2d5545c185aa6 aa411c20b3e188bc84cd97dc0ba3a8bb8e59ddc785a2dee0a803b47937b127e1ed35897d2098d783e037647f51f3032f +10d2e00ae57176c79cdfc746c0c887abe799ee445b151b008e3d9f81eb69be40298ddf37b5c45a9b6e5ff83785d8c140cf11e6a4c3879a2845796872363da24b10f1f8d9cc48f8af20681dceb60dd62095d6d3b1779a4a805de3d74e38983b24c0748618e2f92ef7cac257ff4bd1f41113f2891eb13c47930e69ddbe91f270fb 003e1b03ffca4399d5b439fac8f87a5cb06930f00d304193d7daf83d5947d0c1e293f74aef8e56849f16147133c37a6b3d1b1883e5d61d6b871ea036c5291d9a74541f28878cb986 b615573685084e9c382add7e0a56afcdbcabaa6fcc1862712799edbe7c44510075c2ea2c6c6ff072eea24ca3318a8e75 +b61a0849a28672cb536fcf61ea2eb389d02ff7a09aa391744cae6597bd56703c40c50ca2dee5f7ee796acfd47322f03d8dbe4d99dc8eec588b4e5467f123075b2d74b2a0b0bbfd3ac5487a905fad6d6ac1421c2e564c0cf15e1f0f10bc31c249b7b46edd2462a55f85560d99bde9d5b06b97817d1dbe0a67c701d6e6e7878272 02e09ffd8b434bb7f67d1d3ccf482164f1653c6e4ec64dec2517aa21b7a93b2b21ea1eebb54734882f29303e489f02e3b741a87287e2dcdf3858eb6d2ec668f8b5b26f442ce513a2 8bf2d7e3656598dfa75ac2915dc293fbef5301ed575639f8548a575dbef12c7477595ad773fbfffef4dee332b9f504c3 +ba6be551bc60653192401ed8ff9e1acd9013d8811a7a1389528bf07438366f5772cd7aedad010c19c47622cec03a4d35b8003b39ed901b720629ab59de55a03c1ca50a62987f8da159e356245df58d5ae1936e65f3cd3acbe03ad1d0fcab4aaf2a7a947549ae776772201efbc6fab1aebfa1d99994d4f43dc28f39c0f279b992 02a69bc1df069c6e89722521a63675f318252be629e7558f3716917998e660ac960b0b750562846fe6c12ef492951e51e224754bab84a6eacd4147a5f26ae85ee4381bb14ec2a8c7 97360ecd30f795a943b223e29d09f5365b005b8093c8d6aebfe57977d3bcfd798f3ce31f378c9ca7d6ebfc4f97bcb31f +295720a79ac8201f40a66b06ae5d970afb15f36582897eed25cd92edcd00f70ac8e31c556eed4375ea044c2e8b227a8e02c0a3e996c9272d52ac7b3ad43b80f217295dddc84b177cf1e800ad08bf7fdd021fb2f49b54162092f8d628679c4ee335abbc90c027264c8b288c6e16eca3172eaa297ba50626b00fe0a0ad3a9dbeeb 00d11ed1b78b22b3420df4ddc4acc7c2286d9569dd6dd88e0fa3ecae69bcced68bb81bbb4ca6e9b54e67856e7fdf39155aa27aecb9cc827ccb9cdcf9ac633561b27d8eebfc261aee 94282ae1121158f237c924765f065475c77a70e0a06f72910026efd8e28f9e92898e8cdf0fdabcc80a809419e46068d4 +a9cff41c6dfdc4a12f31dc375a5455950077ae323d0b7a3d9a8dde73b76e9d7b94ddf9c88ae8e6c262d704052ac47681fc35adfc56c904baaa6e146eb653984369d76a85596cb744941aa7b558c945ff2e81bd5ef7f00ecb4f43af23b4cea3bd4ba7b1899f1868a0c0ecfc62ccb1d588955597ffbbaf34cab2838efc2b866669 02c36ef754b5bd065e9eadde684750acc52795be80f54dd3d7a7d743d968a18f7e404bd71f8a76eb0395f396df5a7c2ff7e0ab6de35df34282fda6ee01fe5b9b68ecb4e378dbe32e b3452108245954cf276b81cfb940540eee2d43a5d4867e5b7dd5b6828a47998051452255373709b12cfe06dbb4a79e19 +efa6c582d7fcf5e431aa89b3b00180c0e78efd7ccb0384d90b80e59a115a13e55001d951528c42860132531c9b8ab29dda7a657c53c2ce96fd85549f6f1810e121eb89961295335eaa0e40532d85814a4206e6fffdf9bff76599da9b2e71a22ed572910b0e3bae38ad72c7042579f106739a8628dea5a745168bd918736e488a 019ffee50be5496507e3ef5c40ee88a49625e46d1dd1686a52b09ad4a8e3ee9ef364f953bfcd97c52104eecb6138067192997cd4ebadaccb73c7b2560879289a46353a756b73cc43 8bec5b2c449690900ebd79a4f7fc697276a394d7ee2c02cef7dfe594a5fcacf6a7a194aca4ee75ba79c56af99136482b +211acebfaf13bba33a9dd16722ec53baab92a140127d61372cbf1850f2fc894e942e25d780778235f880743953d04eca7a9205602e388172aec2abf35412b483490751f93b51239b6701cb0aab14e5179b0d7f55d8586358381dd83e3e436bf69a6820317d1701750cb1fea1293467ba589eec5f5779c2dbf2a9b8f28c4dc239 03129e96fd28c4198cc5242c1e3531a3979fae643d527044e98d7721aa56b5b4b45dfddfa17a4115e10a2b4f46d92f81cbdd7e86e588a4c6d8c2b3a83f54cebcee1d1dd33e85d81a aabcc4485df3b11e8a8ce2e485c58af1707e2d7432840f2b981412f0ce997572ee11834cb8302ac533a4f9228ce95454 +ee592e20e0a45c18089c2e41460e65a7d22ed9714379f095d43a308bdd383128aaa6fb24e9d35fd28fc95c5b792ad75c980d2cdf0f460ac60b12c5919d3cb28dac4d488196be6c2dfe462b1b0ce59f8501692255840f5215c0fd8b74b1996a267a5e3b22d2841cf0a0b6315ef4ec7180f1c8494f4c07d5869c01fa2711739efc 03d723d2697cd07dd8444f992f2ab4a063db334034c25ea9be99fd7a1f495e3a644e5ea033a41264e0d24a911e55741d0cab80a0bd678eaec2bd1e60424d4491eb86d664900d907e b26e22a1701d11f4579f8ef6105aab4c97f34ba0c706847e097a577e962044df5b75d8e173bf789c976030328f3ee676 +fffca41927debbd53455821441d9115db99fb31bfc69752a382f57bc7abe021f148346ee29e17512c64b4918ab2391d12d6e5643bee6b5682885dc28177b292e23a37ff99b359b9cf7578432af56e0ad1028a6cce7428980654c145af8daf09addbb3be11228d3c742defca9d3b1667f48c63091fe3307ecf72667b02e008f24 01999ab45d66cd1d3a0fe6aa43bf5ef1e2a67637d53674f6fbbfb9b582be91fc42a12cdcad94b50b0fc7ac55030de24a0b99fbc4314fa743ef4b5198bcc5f54d8b669fbed78e2e91 99f4fb31bef8d99b68c6732d6382ebe588190b713f53efb84e44c0a38719a2e4568253b6a9057acd02f028bf73722856 +a2f71619ea04f7057e6943c2cece8594b341ec3b96c3915d924f94ba13fd7aaeed41ffa0e842ade414784f1ef825fcf2dbcf7bd8263b802def45f94de596aec0c121fc06558c7bb06b9f27a9bf56c42090b5dc344e82b69c4f528d33be166764a593483f6fda0cf56e6000ff363ba220f5ea0ea2c3191615c7ae3bb4fa575324 02ce1cae0716205330d730e6bc6dbfb6b951dc83ee3b4a7dae75d057e32e8a46e22be75b5f09135452b29c34dfe81a9be2e8dcd243fbd946a0ed14a832a7802e20cfe1abfd3d6e4b 9523609d2c531a7ff8e8ad635462120b00cf5e1deee16660d29203b94727b3202320f5353998e5a1b003b8e345c40eb4 +b60415a831eca2cf60c79a334ef2f327a76d290846ee588d5d33d0a826bb0c7ec3e11dbb384a7f89c8d180425dfae7463e0ea6497d2eec1dde112f1c1efccb532a2e2b66a28e2d36d4252a4c3b12850d465fe21bddc441b92e6a7b0f67744f7f6e7812a0603211a26518b311a5b190ed890ad852bed4f6ed13377cab3eebedf4 02c9d0fcfcee7e75c3245ba955ae04188b1033c55ec9c821d8de7685276bda3e9a93c3ae1b003e5ea722913e7b169d67b1aa2dc8cd42adbd9368672a3f81a6817bf3e5529dcb0c8b 847ca390d5db6349a893b748907b2a430d99b3534301b431ab3c72c7ef7a866791e497cea51360b7d7f02c9448a79100 +5d15a08226cc74cf495be681b795d0bde26b19f29aca1a8c6ef77d50271ebdcb4e5fa2df23961fe11620b1c6580183f6ebdceb2c09516c8127be576496fb71449bbbf0a9d3d1c48a25024619b97c3e0d8b165897db96ae9758d13ac28441d7cbfb75b23cb423e0002046358bb6d64779974a5995dfe54b398f95f7d64fc52d96 010c057bbaa44ef0f565edc288bfe66d4f6acd8686899359bca418ba89fb690429489a37bd3c6c9f3a8714b2ca225868c6a45fee360e378a676f7ea39321790f32a4b005b81dce43 86d3ab6b231d507690292805bd78d42ae3ac7b5f5fc3333515e150441091de2f467f24b8fdea3b366c47c69f5de39d7a +9eca4bd88200baf61b901fca53dc1f1e7e3f83b94d58a6cc6a2adbc9b1a35fe3f8ec61787c76ed9a0d696167cd4fe46e1a0883fda564666131753c576a720125e0b712db1da0278067cb899bdb14eec08737e864544663abb1d62f34a2114be07e8e3cf56e2d17099299ce6b6d83b1a34e6153d7c6a32a72c7b1bf4583fcbcf7 02c182df7976ea93d996f3ba5d2221f3cb755cc7847bc3fe9e022fa4285046f5bfb426bafa3580beea206de36f87593ae561b4b74a03fcd61fbd0e8d6fd5668f2148819a88a650aa 93f34723aad2888579017062559e214e46a559b13ca0b58d2a5dc590b06a6c66bb6b04e95e6c610ef22c2bb148f82a33 +707450bd84141f3b61beb12ffa5ae89d812dd11badcdf6a88a2d50fc70e23f6d822ff4477047abc58cdfa28f97ad7f4911ae0773c04ebed1f51bb2308cf6e5712c4aaed461edd6987fdd1796aab70198276b601241f6a14225dce575830ff60f935fd9f567d1d210652e4710922fa793da78c8fdc30c273cb08365c9fc887f50 02d3a65bbe133cc98cf0eb56ee1362195968b4eab960a1d55d8b762f1361fc21348d6f275d4bea1de7158fb97c995e20b92a9c887a3e332d154667ad167acc632eb88a0ead6113a2 99ec6cfbfadec2a89e271e864f8571afe9c9dc8dd3ff888df04814c455d5017195ef617158c35eeb71f27db15936b80f +d5ce9d59391cdc47ef942dd2a818d024ae3917deea8a5a4214e4db6a0c5e6b0936f3e632fdb68a3f0006e05c44b7232013e1da5f877cd197f44fd6f60c1fd2378995e9a47534948c5a09e33750f07a7165072ab38095373b07a50bc1391eb6b650ee13acd63d0352e7d9c31695ea1ec6323f9b5f57b426ace56aa7fdbf419be0 02a920e8dc928acdd56e3655b2340d4371c793e66f67405fb7a90f31e9c4ef466cc44331d1d2fe3ff7391d2576dc6640772166ef8c154a5ff1808f5dab2f03061070ec8b3f786c36 97b7332a88c7a5ba90ac191ae8ef0eb9977d7c0bfaf8d74771d47e548d1aa1b420fe596fe697ce44d3a021aba085caf9 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K233 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K233 new file mode 100644 index 000000000000..eb1cb1bc0e77 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K233 @@ -0,0 +1,60 @@ +f23f784fe136c9fc0d169503d361e9c6148b0f1fbdcae0a97fae1af7033ddef25cb7489c9963cfcb009a8cbfe44a8510a64a073eb1deae4c324ceb9302008c92c69b2dafcc9077fd3cc3c7c119edc3ced36d176ceaa55ac036bf7f07f6fa215e8bb8196e59a5e1c9af4f98b90ab4970885bd7015fa26a09e03c7cf6b4b23d929 004c1d414696cc3657dd9df73ace56eda2636769ce7082e064c260be45a5 9743436754a42540631b8aacb7abd73fb68854f9de1bd07cd0d9c479d1bfae76f22522887fd30fd6cf8ddcab20874445 +400bcb297552bb37f2f8135a9314a35f5126788bb6fa4dc74152731ff64c5dab4b902103d85443dec20e16b1d6629930cdc2bd183d4099f0e96295a63c2fe266f5e9d050c401a8681b4a438efe53cbd8f2f43e2a31e9f88926a9c82917d873f6e8cd5ff5eb8c1ca36126b0bfc8c2b0e85a7c9e7a45f1875ca9c82019ebedb729 0027cb1d84865a16992476c9e353283d5d6a40c349a8e9179d1b1f403531 902714e5e4904fc849bc7a5ab22ffb6a2940e4c581b13b39709d9a3165c84de0990f797d14f3bba7c64ef217b8e72be3 +5f74d4b35c49fa454c97c05fdb6b9f6822cf1a2295f15bd766dbcb413d77c910bd8f4147e8f317fac2300fa21cb80134d1b6f8ae8e50518c1f648a28506e419f5a6e8f05abffdb3dd2587606c7e9c223ecff4f46b121216730ea13202b59128a7616bb2fd23a7e4a5aa08641cc07b669641313febfc88d64d99447353dae3f06 0031b443f46c4b5224237fac1022ee1570173f664aba0c84dbaa4246bdc1 aec587d2d76cfde7e4a411ecbf489edf837ab2cf3e8caf625a6d32c41d826b75d618a400bbd951b11f6050dc34283430 +8f92096876d9f81bcd992369d42d0b5877ac969004d17c8627c58d8b8b7bbf7a37e8cb6afa962b9b043bbbaa5bef4a5ee38d8bd31cb5866b828265a2f4102a616f87009cd346fcb8af5519fb577c60d8792472232f33dc615655e53d2b715b15a2697b492f108b7906e1e3597c6911f8cc30c7121ae338a6b747ec368f8e4a36 0048f6ca29f35f253a4962734357c995920967b9eeff1ba5fd2080bfede5 ae733dafcbfea91b21c8a6efca61a2715edb932a86df471aa327e65aebb69b5adcae6bd76ac6340c5fd701383b6a6f3b +3d275dbde44494c45fc15fe89e2ae32aa26426a17e923e895c7941a5582fb95df4d49873ab1bde358017f336b911b886b626b744806ab8113418473c441f1964159ded1b12122d53ac56573167588e4b55f36b8bca8c67823883a51fb6e7f204d1c6b07ea49b577bfab9ca6b8d51f72268b022e3a4db6f9d265ee8382f9b7b66 0019b940eabbe682f961d9f3d90432e347fef3910e641656825d775705b1 b4ae31bf40abdc08d2a69da36ce3d59e2ab9d1f86d7f73b4a3716036f6f3f87344dcb4b8b1841f42733e30857c1cec44 +d2fa68e1f7dad02916b12fa38f1849d6d409dbad0344438520b4dd9b77d62d39ac9ae3cdeab03ccbcfd4de703c6e798873671731c108f322b9f2a68145e3e210c9b15b879798e5c53c5022742e9819b99edabb2f44d89ae221f7a99dc84421a6905695ff91928db608f861745f17584d56e34b75c47281435b1b0b34e490692d 007a884b22e29fa9fe945e9ba13c0df8d786dc87cef0f77f069e182dd56c 845b36ddc6d5e4620118f0f0b5746426aba215cc35cfdc0b603fcaffa48075ee561724cc92cae3ed7540fb5d2ef88e2a +3830f75cf9df4eb2998c7c1b5fe11c1476bcf849c3a8fa7d3d0b5bc2292e5d07465ab8cc9381c575d909e509c5dac49c78817c04e4bef18bd51bb09aa5897f21634633a5ce6d20bb4638cb6c3927351eaec7b62cf4a33956916045c392f325adafb10a88a5f86d7e41dd77908fa7284210071c22aa40ef40da6339c02da05392 005da61f881d5a0dc085bb93764f584352882923cd237d878220ec624c1a 8cbe620f70bbd8591f49514d2e6a0788d79e5a693b1f89f3b9f6746d66317d29e2b87f94ec2801b51b56966c95c43f9b +65b9fe15e6c35d453caa6bad39ee78a720a04b60d8a0a0f049186d2f777e48ae2d657e174df53edb7beb9f7d8f21904ed674add0cda5b62a7308de76c324a144021e8c6d387daaba4ce48bf7dfe9c8aeee2c64e434ece1fa5ddcafcf3e5d0013a1eeec1742a00d384cc2ec0d7eda83bb4dccfb0e57045ebfc27a4f404d03da37 003fe9f04647f6d82b13ec1ae5a8c2e49bc66b05649ad778eb16149ad83a aa3b523f9323f08e3bfb0959a647c1c4b4322691baba16e723f57b8cb12ec92420a093e4cc32bb0d7989c400ca1c3338 +d26521fd41eb5d46ece6836e188bf9cb1b461d011c41e002a935d256654d01725378e845920ec4a7fd3f379df54772493df50d312c7c6aa4e909e7b83f2442c3a5e85c37d68aa015098ecfb0a5e077370f4576f4bc63bf37e1dee06d780a3b6949af5e21c2a0960fcd20821ef5f17bebf5fd5b3bdda260842cbbfad45667287a 005ebce648ace4cd555413de6a456fc487d14bf4b0b9a72311ef480d2f26 829868395305ea9921f672c38d8a3237856905bca80d0b82fa41d5cd571e638e03eae155593fdb6093915d1e917aba65 +b778c021b1a92c41dbd09963da07018075d73e54d62df5c2b7bf8abe137151650d1c1c6abce7eebd8f32e8c3e6d1433773f257bb3ba4a4fb6a02c0db1e47d03c27d3a90898ebd1927c21df24c4c5443ca5b81f8ef2cc0f5e8b3d08f472bf07085df737adaedec63d99acd77b87ba98225f198b791124ac2d9b191cb9251b4b00 0056653c2f85593f789a926ba49fa3da9d7f946d8f1020508c5a527ce813 a198896b4a8dd5e4808d087df534fc269fcc7cdd52b24e491ca43d377767a1116dd86c2e05e221fa746ebf93a999fc94 +ec14e07f615960015a489ef999e308b42a4c571473b9bd64b433dabd9a1b1ad02e33eee9100064405175928a94543a80f440040afa2965b4e5f95f768e7fab6d3c0a5f5e1bf1df7822f78384e80f2955ea85f044ac60537d895747979f935bb0cd3673193c4a32dd7803e48d7daf70a71bc2aa97236615b6411e28fc9a652145 0049a91d320783cc70a5952c32036cfc75d41f1aa84127db2dc759fb291c 8ffe5b30238d8e663c99df4ef61005ca26ff4fb1124e48a8c983cd9c723cd2435e393dd74a43af68ed8503cdabe2a36c +89c645339ad0eb850e4e2fe583cee175b35feb02ed7541d7e9aace24cdd3939584f73ad39526de6399c86b36de77a018e2c70b532bd0f032f9137d10480acc30c49f9baaa86f9df0033b77e98b485bf7a69cb5c281e527d3ccd1fce2415f0dda4a268ce68a0a34b16afda54ed922cd6810ac8dc766df2a3a6c5e55972e9786fc 0016a20016602fc7088a60469843e1d29ad67e3c3cb9500b1e2a00d4050a aaa58e9b3e1645dda66ac19bd7bb4a56edf098873f60604b5952601ceb8b17fd3b0e29a9266ce8857a532f9b59ae22eb +ace14c4b101d2d8453c2bc22b756af016b5de537df9c3e639d208ad04ae0bf6232dc90b90c33228dc85de956db771ffde05fb4d0b15e4f218ed2771d703ae5bf981252a5bcd60c16f14483131a481cbe04dc0adb1fb8aa32cb48bb5008e8a8e5c7b7465be2fd7afbc811cf5ea6293b1a464669b49f55f57b93a8707e6042fda6 000ba922149bada2551b7be1c3df076f3f97ce93c13c50c285fef3f42363 b9f6f2ecfd01f7750e68288324c623b5ab7d3498189fe8d1e76ef4131cdcbc2c02443ecd160399959d5c738adf5f0dad +cec2ba0d1772c87e87d5bbbd67220692bea4301aa1a66e8dbdd7e651d45c26dc2a0d45cfc32c34d76ae3e1c61db7b0fe1863457b93937d929e6ece7462ebd16adfd708353d6f7c27aafe06593c76da7149b0cc574a4290b0d8fe219f3eada7082aca38dba3f78ed0d5942d095fa5556fc8bcef331ff0a6d5d1f4e6c51d4ff5af 002d635e12a58cc6dea44e71e87c37f91e8d08659f0b7955d24f65ab55ba b5b49a67306fcd726f5654aca831146503ca84e6daa60981b118255a7e0bfc9d1d07c9145292627a1b04c30813818de1 +ffa13cd0f51ae2643d5d4edecb493ddd653e9faddcffc370e7e958abf726a5d67a2ab36cef42ea8ebe22a6f01b9c31f6ffad01e6894487d979acb5e618f765ac0ec3550ac5dbbcede8f9fdbe52fbaba5c087ff382b6d7a09b2b5084227d324d98ff98793040884799b96d2ca593201f4414f18c43b51c53c5e5059e0641aca02 00073883e5064e06814fc4de32e15f7a6cf825d2daf6eb1df8c83e25d80a 81d274adb7ae88d01880ec98814a2daf3318d8ca4c3f5f0ea837b91e854e9f82544d01fb02b524779381dca73110c4f3 +c73e3dbac9513d0361dabe94071faf03a11cba18c06d131a172d5f0125b01a5eeb6055bf72c7106fe3f4be3bd2b1771cbe7f85366dccfbc3bac20538510c3f51179cc540ddafb2f3b05a0d276899674ab1d7d8fb4f6838f04e4f9e26b8c6af31540f63f4953c85840af4c57dfa78c704f637dfc8dd750fe45e2c1e149986d127 001532271bfae8d4dfe60f69b88d3006d58e28aacfa701861cde8d624db6 81ae4c6bd5051e03c0120f8a45bd2b6a333bcacfef1022c83d15ded3eb482fa45c60c43a01602a837073dc9a01c36dff +d00dcd0f3212a3167403abed91c20e76f5e7a7678a4fd970f944d11e6a8cd149d0aa6fd3164c5a74c0f55193a4fa3d8ba6f99cabed10544625a7bd92b3e0b46edbd4a269bbc10518c5268c3910a2aea567ccd32d4c7a0cbef09ea42c20b636d1f711d220e23dacdb9d1146e0494401349749e5ed88e38295232a7effbae3aed6 00550406c0db882c6aee6cf3b6baf377375208c3e90cc44a067cee43efcf b37c4634d5e1709e7987c874e8ebbdc3d63b9855fbd5acb33e0c59f0baa82e56e016fee5a3f587ff74889b4b79775ee4 +3d36221f87157ca4db84884b8666660c4e2b6af330480c516cded9f3bfe132543626a39bb6aed1964eb5c33ea0b95b9841665417679fceb95d199d55accfce35dd3f2283c1a7ced57d0c4b9ebe3da6e1ff2f979b6440db27caf9f6a4bbfa47e20d29ae304f4d0551fce9cc4097eb2fbedb9b24680bb17d207bdccdbe799d5b0d 00257dc63752920b6854d6c2d1cca68589a38418c3d036e73760a12214ab ae6f146f69f32ebac9b6e40ab90d658c0ff37c71d0e7083ee3deec8fd14d9dd6fdd66b12ed16b62ea7c4e16ed108f9dc +033d82a42d0eddf58fbe3e91ddff7190e3f9fc2b1e2eede977d2c0473b358b5fce1f981ca6f88fd61ce2f79e453e3a2b77d1baab2b970ed28d5dcff58873a620e195085e61c4b8480d829525a1a944e8a4b63352f0291f0311f1f98ceb262804beec1c74947618f8e3b067866255878c2502966cefcdda4f5fa2b13d92ce7840 0029025352297a7be850f8852411c09259b83219135e0e8949c1bd5b94c1 87b056da3351586b26e28289b5133b3b36ff5254785a1f9ce7b6e2e03d5e7b7d6db9909d3d5d9916cdb57df807487b00 +671a7c81b64b2919722d7b258bdbd90165bb757b53106e0af03d0eef27452942f40cf52bc95cc7f6567df2613cce795f8bcfc723b2735efc35375c001d37c58480d89343697146b524835df3dbd333f7c06c98e36d3c4592ecd1f34ab57c341bb0f4c785f5b8372775f74b4bce60763fad1788e77ea158d735a64861320b36c6 002dc82d0e69e498528925c0e62a13fda9af8cefd047c10c3ffc2e41da3e b3580919b62726634ed242c64b1a7aad19cca2c3a277eb39eccc2fb9bec696537c3b15852c4fc6dee2edfe3d6731ca06 +0ef677f4799298f4aab73b7393598041f56e902ced1726af49657b6601a06186212e3ee8cd4bd33b760dfa2ea3c38884f94358d51dd479f2ccc8b0b352fa4e44fcfdcfbb24919d04e6ee1108527b8e8d60e8d1b467c30c18c5455e5835d483161d3fc26b4a67d6df9e3ddd9331247cb18450188752a1ca219f3396a872cb13d8 0041535fff5d279bcd744b04e643458ce20b81df8a9e01b1181d52bb14e4 934940fd9de0bb2dce5827b803bfdb7096bc102ded9a015ed4ecaee0a9c6af220548dfa5d891e047498bffc77ad82a52 +9290df0cc50c3cab6655f3a6de1f4cf613d9bc06ea7c99f38038369ff2fadefa57a3c7ae7940c1b98bb1d03503cc271f7a891bf38eec93c31dcec7892dfd2e1ab337bedde3e5325ed8d9cb7fa3096f6fafc3beb3a66cba66ba826d1032debfb4908cc9dded8c0099c85072daac4373fbc428fcaa9a6da02181ebc33f0cf926fb 0000ecfe580a624df66c25e87e7689fc3b471d205970ff9ab51a64aa12ed 8deb2f580f39bc9509ea7780833797cf62d375ee6fd2b2e2a8557c238b02cde50db5aac75afc20e0ac584fc765911773 +855c7be75fda372f062709827f333630acf28954a62a5193ff675f0dfeb63f32bca418f7cbdb346bf388d62315b19a592267ca407120db93d4e3d7125b867c4c4670b7a57a76f61734cead2caf2425eb9ff0a63293e8cd6defc9648257b401463f4533a2425e0024f1ea93365eeee3c6da20d25928602ec8b426f9b39f97f3fe 0013c72c73358ffa168423149ecdd897f0a5f75a641de008649f00134944 96d518083dd24c64fea0b66035fad8924ca0d348687b37421bb80150ceb6db19c8a6705af27d62065c3fee0b1ad590de +9c896f800281812ed57d31623d563377a5c725cec84313472b90e73f77d400f5d4fb236255741b73d46f7e5254d04099bec274db8a9af5fc7cc220d42cc172cbd3c3595c49ff74bfaab7b5e46c90855b611f74753ccdbbabf92e011d52e9ba753b83ed2a251a632e1bd5c6d346e38e743950c8ce0f394a837028575fa44bcc26 000ac60e2e70b7c4cda64071c7738f68773c94df9456a8ec3bbb468fa7f8 b48e104f0fc7bd45eff2fd6f7fdb3f114e68862327cf237f64acb0a400c2ea28636008b2af93de7b60c705369fb723e4 +139a14ead998d1a962fa47c47ef2953aa136bd912fe940709b8c560bc2a0c4bf8f3aab30a8e21b7d5f487d30b0097e3da723f11b5cb4e8c5724f5a2fe0d68ee4bacbb85e5eacf18094d2a8ec4506cf8497836a4a905059a998ea750adc54c27c69cbd0b0c1f9743a62f3d988f3fa0a9865a73fc071f526623085a2ef12838888 0060bf720052e8b9508a801340c213cf53bbecf4975faee63d4b44fc647a b1e290530a29c2c8aeff7e5d60ff0df7e67d571ae963807d46ff777ab5bfd1442e2bc174e9fa8e15a13720bbecb5a45c +cf4a8e754b23d0fffc1c5c80b0cb11deeaba3064b315bc2cee96db5b9881baf90d30af4b69066f757b3020706def77a5fc1632d96bafba22a9c8cd3b52d535d941b3c7cc02b7fe6b51639d5e2084478ab3a29d2f5e0e16639fc2833a47b58e2c3fb5b2ea1830fe2ff68e571a8f281617a23d9a28db1c64ddfb1083d055030e5a 007cf3c216592febd8630a478b5b3e3a605084020322adb13ac0a626bc7b b56a7cf6f50957def38b5ab089d2d8838b826dc17ebc15e9c4b14ec44f894ed5aa4867856707508b24a1a1e4db43aa0e +ae64030d4af9b36c8d3a6af0aff34e5ab201df04274691fb420b7d5c40c401ed7f3ade96065d34f2490d17943e27156e7bed83cd7222d0d5a73d167855fbe7ff6c3ed87f20986ad8bbbd80fed5f9705c6c783b423f641d40ff1f367f9648af5a79ea3cea0236997558bd9dcb011ea4dc64d61ea1e1f85b4f696ed586bc7705be 0061eda5999e5a9ed4485d2a0ac5510549b76ca37df858ea5d95aeed571b afd2a6f2637a1c3fb0566e7003e7c62b39f072db416623ad93ade9a83d5b26684becb5a46707adb854b179b155cd705e +94a9d9cd9efa3e4ccf2a37f904dd9cab5624ec9393cf8816ea591c5e70cccd2f105388ae133708fb974998ae61d218c71785f9eb808d1c28d953cc7eed00dd9854b6b4568c5ed5ee3df3b58a1e04c64f1c87fee4365ec9aa41b08a6bae234dc43a0bf2f61420acdb891a40f17f246972afee75a4c0b249dee0fc8f9b9c8a243d 007e7e73171e4d2f2989dc024757c186485435b82544a448f5cfca05f281 b38d21532debf90510923900c7564bc142f1e4165e1990a57189175560ebcf2fda7f254c2bb42bf3adc2dcb4e8a7b258 +4db998df7b90678b8aa4ec6233c9b4629800ad1f3e2cf8f7afcac62fc6982dcb290e44587015eca8dfe77dbb4a80f9bffe75b11e961e70deed14555db6dae47d49e73004f000eb8677c18f7e8234bf0a5a104266167a05ef07152e7acc2f0368b37efe69c0c2feb51eedf7338cf9ed398f066cf1f66bacd89ab9376d41da35a2 005f7270764a0444c7159d2db867930fdb0fb9fa6b8fc80ca02e11753095 a4a3772b2b1bf89efec70c10a7f499c35b7297c626f5c91e219572f38210d7402ad357496a1d270ed70fd512d9d70e90 +dbf9b8a4ae316bd2df0c80db1cb5d7038364a2634925ff957d7c03511b57d486274b2ecf191746827c325a14dc94daacd66ad86d369e3f598f176c4f0eadec7e9edd13e34043efbe0a801b75b8186b4a6d89ceae4fb250ab570d65b6dd7c04382738fe3f6f6c867a7d84b35b20720cb0036a5d81a87126f236833831d9ff00b1 00179b924afa4acf30ecbe2b3c12de533a1f9675687876a7e5e5ddc8e03b b7502bc48738f264c6d9fa8708839ec34f08ec3de661028813b939e9fd03d008b02dd69843b7fb140e435df02c83e807 +986d9e5d636526f4deb7545c037fe81b09c74496ddb8e42e61650c74b6fe348593f0cf8f8eca5e839baf62f17bf6ad96ec0c71dc44fdf11259dbfe7499157e402f6bd5076972354150723afb632799a990c44cd0a4fa9609ec4db133e3b4700be3ea4a338e8ba1873d345e80163ed60d0de274d7617a8382980bc2138b0a2a01 002c9eb4d392d7f2eef606e1861183acb1fc753d666225f0f154d9eda147 b632660e032fd32e55eda5c199553c86edab2916f5059e616af1895c16aea135f312847854b4c7eb0729880b4bd1eb77 +68d0be2883598bfb1433886aff118349157708690380c42b8919859d96db069c7fde6e117a3669f2cff94a0f1b66b27b09e3f1b24d26299e11552a084be428446f3174da2e0414655bdceb38e58fcb065b6661190862db39c6545dead34a03584632e988d0459659dc7c7c78d4d00fc2aa10465cf24b2410f14e2a62173c9962 0024661c89b77b2c743cc175a6130904461138ddc4ef771ffb9fc2c8679a a5e1566ae63086cd699af1cfc7095afcd5c34cdfcf7164996745516a8b1d44dfcd9ac2a525bcf4e2b70f6a07c2342505 +f0ba0407485fecd7337f4b22236533a926cc744a5f06dd08276750196f1bf7ea7984278f789f92dd07e36895a8bfe297ea43d4a1177c0368900e3b969d3083cbe626f0e27e7ab38e185c923dff46d9ba187b2acb9cf4b23ec8eedbb8044b96b5263d956e50cd6240c66d5d96517130c743752404ed09473f05d0004dc5971ff5 00065e20e5ce534576d7c17616cd4ede3bf4f500894850723bcc9f895f4b 9564aec5c54f206aecbe0438c8cf5c21ec340ef9a3fd9f958e48e10a455a2cb7a60fb7cc73e894f30a002965736ea01c +3827276694e413c886129c452c9a66e7d09dee84f5f09bf34e4baa308b4627e096c7d45cf6ef45ba1d9a4019a60399feec10fa80e333e2aff1251c85ca48574d9b9e1affb9666828dff5afcef3edaf5e8cae823505a0c73afe76c1bf130399fb06b092ba34ab0ae15ac6c682f9ee8479b065ce75b57213b8aae0f55e4e386de5 0014c85f66fbbd653f1e4e590cffe62c343ba6062df4b271fbd02e5d42f7 b0c1b92ee4702d60dddb5a439b649cc2fcdbf5148f17b1c6a19e36a09d18be977d8a17f594d41f83e6b1ac367751edbf +d1afb8965b48d66b9acb1ece674d9548f83395275f2d8135554cfcc7ceb96450d850dd874529433883709483d0743798db5e0dee955a4f30ba328c7934b8dd9207f3c336cf89141a175ebe23d2faed629eb4236a8aea8300604c3eb7704512f240fda66acedf1494a85058dc6a31bf9531958c332b93cfe5545046876c6b99e0 0030ac7a78593b570b29f6d3d267abb6ba7e5870ee1c8ee4f1ab2f141051 a0bfea0fa993432615a4a6f54b9950b8b2a0185d7b755fae21bf307e86abb78b8f92adb4a70d9e3d45411977fd582cf8 +4f95b71669fdfe5dc46d4b951b085e099de349fc740535175337127910acf24e9a0e4b2f23196ad23880da47b740d77d74fe9bcfdcc44dd7d8d1a181ac290de5cf4da22d5034cda3d8020bcc776dde8cef1786c9ce4d2c2cfb035da61406af745efb7ef1a55f2eccc5000319cf1d6380963025dcea641cfd15a3106751fec286 006d7516aa040f7d559cae248e485834e8d9bb608279ed4d4f7e1dbcd2b3 a76e5fe04e808344444fabfdecf57b3dfa271eaf2418bf515e6e1efa75ba37823e35608af181c05a853325710b287c40 +2ad9e17780c824c4f2d1e1cbf19ab85638f2f71cb4fa3518f08085b8b358f54d4f08394a5ac29cbb3cab828c5f07f41eec51e6cd61a5f2cf44dbfa46834370cebdeb328fd3bf681e61011b5c2ebc8945ac7a2a8467606051008b15c89390e111999255bfe28634ce9bc2850a2b55a4af1c4c2f94403c78aba1ebc87386ab7b32 00137050d7b455f43a8dc2516cfff5a91062c1a2727b27df41488f3dcf18 a2061d67975701ae2d4eaf929392b3a2151d26dcd0a7af0482b14c06219f0877cd70778ab6b23dcb819a6f5c4aadcaa3 +958773c37d3eba003aa5c489f72118b3022c52b93399e9d8001695664918b86893f4922c7b6e55b1855ed0fd1d8de5dc61af403ad660fec60d7c44bd0102c069957ed804d0d416facdc1a95355ef58554606579ef89b1842f1055cfa2ae118abbc485356824cc09dddb77d0671cb3011b33bc86cac526e3f6bb3293c7bdca1ff 0001fd447b33a2ee3595b9f885c290d241422afdd74c3dc4981955a7e9ad 96559d0b4b9ee89eac5d0c3a72af2be1909e771b7a0699f516ed70e9f2ac1537a6895997caa824ebabfceff1c72ee0d0 +9cb2c496b1bc7f040228571e005e7e936e48e8f469e295edf914f5648701249a20bff6b98b5e862603dd9f12bb71c160aafe9df02e2e383e9b8a9a9d700f4425ce408feabbf754be543f52204c849fed6c9d3e36e03dfbd9e35c18d7bb2295f1c484a66e73440a0a5aece5fe80b9ade9321ef18cde3eb2db15e4b18e788b0441 006a061e10b4a6e7001d95411cb31bdea9c84670a59ed61b14fbbb05c8e7 976d56e83bc0794ec519f783117c9a1803b41f3824df87464e02262ee4ff59843a53933d18a8045eabad84068f4e27da +9a4bc0a029e97742ed3bca207d5912cb568e4403cda106b00247520ea02008b14c041b8c9b976294252da835f4ff27456039d79d90315abcb0b9b6958a22352672e229665457ec79571ca80447c8ff2a86e6af3dabe7427c8bdcae65e3c6746a56079ce2cf8d22235180f46646a21cd9e86032cfad874cb9c67f882fb037a13f 0027ec31ca31acb4d2fbacb49fc085f1261b0042cc755cc97f9b199e7a37 ab1f1511e6a36e185a12dd41d71768e0ff2aeb8d957debfe6ab1dbc5624db67e68662f0d90534dc59bb10d35b4716b31 +8d89e22cf802dc68ff22d43c436c79311e705ff6fd845e77c880f399f403e6d5e9e2b35511553c978171189e288cb2200fd95f84ec5ee9865c0eb9190aff6dacf783ef200e82027fa992741876456472bdf27f2bd8ee55db15408c957a120eb64cd24d299818726a73fbb0697eba726a326719765735b37a2dcff0c853c906bd 004c6f4d88e5a4f4f83196f2dda9dcf2a66eaf94d50c851f59bfcea1d876 95382e5a43b38eacd88d122c0fbbdc9e39389d3e2ac9f1646e8c5b9a3bed455173d3c6fc755bbc8ccaefe85970dedeb7 +aa1bf5a79e5339fb9ef6c2817bd95725551d064bc5064d6586c5a879901adf808dc2ef7c78ec3b434b84569988db58b5e8e9782b1cbc2cc7c9b68e66f32d4ac4ebe7e75b345f654c7b8a5e650acc9f170f75b7aaa3957cce248cc69cf93faf8d72abc6fc1cfa9ae2d18a7b31ce720147e88e84f6563b2197882fe302449ac5ce 001aa169ea84365c22981bb766bfdad27e373440850569957544b0f9332a a304bc53e675b250a62c6a45ffa393b05d7eb86d71bd4054ca76893895a415c3d170096c8d4a3a50558c53493b2bc571 +475664d5e22cbe0da0d0289ca9a666a37270dc71c81cffac91f6229fa39315c1d55f7e0a89b6a7a07df7d391dbdf8fb7af63d2da46ecc3b60110dbcd842da97f98d2b67f562b0364ef8e1c589519024177c8ea079794f271f6d35554c0e9d0a39062383c95721b72f4e74eaafb6fbfbda02cb670a7c4c94f67b8ebc6442e84e3 004a665b92c0c33a3f8b9eb4b0ec061d40b603de36c87096455102ffe57b ae26bacde66bdd3b1cba1267d9a9a233ff6c0bb1a0a821ff63f73311dd92157a32770410fcebeddd45992ea5dbac9b2a +9e5397d94465390a82a3c07e3ebf21b515776d18b4463aa5810e6b2f96ca61e92d13e034fa853c3fa45411f51f79df6f799a2c6906e6a5b7896a4576a4464f9e0be2b529a43e1f503fb640d79db6b68f3a3a7deac1b5832fbe86673784ff6db1f8438f7dd332cdd1e7ad9df8b6731aad1b6a72bde52e6bc62d80b8da57822c48 000531540d94823e19ab2b95cbc6e7492e1effcbabce875de6ba96f53aa9 96a9fe6ff05590f43da263d022cd43a874487811d494e23f497242e9de40d8e84a9f571d33903053153547aa431449b6 +3cc4c4192f317e52df6f8cefba6d4cd823c942aaee11b9a0ef5de5c2d181073b7085a55805e9554def8dc13eb978e7396044d4f4a14be2c7605998c062095c929b9c23b2b1b2fa73dd19a0c0af44ca4789f9841fa62dee8a5f91b3cc4b3264f5f67334c3f0772b30bd7431c3fbbf1f34318ce1889b6e8a76ce6d42079a451e56 0022a89addd8b85809e87e0aa2c038593ec277054842854de1197833a51c 85196c056110f08ba18b75e4a5939b2e0db5e04105e840a96a5455798d5c55361355be5263486b6c945fbb57d7da5fe7 +72cdef5bdf710978e0aa334b86b8ff4a58630da314eabe98b4d611aab56f55c526983d54d19bbbf9ddba30a84b18aa0bae9f9503e9b222f842f084db83aa39625403213ca321cc0d9c8a136c826e6ea4ec108b913dd0a9ce9d5b8c7e3af53c3876e56a2037ebd6d99f037a097111c837647bedfe4c494e4288ed6427c15969e3 001df252a11ff97b4421b3a2361db94e908e8243cd50d9179f9e03e331f1 b1cc45ed3f3fed000176f7317268371620d73a4c538e10c103461c073fd0ffd6199ce9efa45f175878f9c881b8130a3c +8e4eb88c0b2d525b2c58b8e00f32def90e6dd382301de49e0ac053dbc6b61afe926d85193e2c4948f7402a3d7c614cb2c58e060362b0516a1ba4a7425f1b3d09aa20d4c3c8993a387a3248aeec51e6efa8f558dbdcfcaa13ee08413227c8351e3107e9a3e3ac124224aaea91bfe50c11c1c8ae582e718f50bc5d5c06076517d6 001d7125c299ebd0dbcc050f07de931c7ad0450af590d0a2d0228a66ac5d 8562f87afbd8130043bfc0132feb325f3798911ea12519f98880ab6962c45325c26c614d26be21e7c39d04e2cb88c728 +370fdd80f330311dbb3959666001bba61cdacf20f72f78953d946fa6cba02d24b5003f5452d535609e489b9434f192011f99f918defe877d51349870e7e75502f61145f7c261dbd2a0840926d824ebe9be3c5a77a3a84340aea930378367ed3615a47e3f792c7773f83f91ebea718a05fc62e9ed1d78629b2c27ae44fe8f8d4e 0021238e66119844b146d40e48341f522f6ac2f9c8a0b33aaf95a3099a41 8dfaabab2d4d5a0040e5114d4a50a449aec66c2a78e832e5366b8acc417ad9b8ce54566a3c1859d63d867d26a5c6c930 +f86c4433787c3ec3cb1663389ccf53d62f9425274ccef05fd14b1b8fef676208867764eb98d16d006ee6ebdc27b8d9a8ddd303d941fdd82b630694cdc698bbe6bd524411907834286c94b24ee199fe6d646064277f244b7df3ea2d9d52a9dc6a33d7c8d6dbc919da0fa987a67621ef0829e48310e0ea2bb86fedcf4effc0b94b 0015e1bdfdacd87c42ed439f3e243abf27fd42e54f3ebdfb47f60dbae5fe 8ad66ecacd31e9a30d967b6c39f4597978b30d9a43f5224b017f967b6e5ce3585ce92f20d562c0c472c52b8b84d9c3a8 +4117d593aa92e3eae1124ec7482737cd3573fe5f0f2a5051a7ce86946a2abb9e47a0c6ea75b262689b0b486476d2ab09a20efc2fb921419b1811b51a2e15891ae9e45a17ab4b96c665c6c423fc00e2d66df5804a164f0f3c958df6f25d7da6829b1fe162a0a8cf130858c83f3555d6ad627db70cb41303cc6380f7b3fed2563e 000e09410548c17bbbf28a68c3963a52d39743a4f1ac28e6dfe7a6ede281 ab56a135c2a8ddd7ff556072dada633351755124a6236fc4751a777910358b72f3e97634fdcd6ce1fa59413208f3ed75 +882ecaff3ec8f4023df5397167f238869f78a5c499be19aea85c7486e73f66f0e08e71cf85f3f1b6f6a70796bf46a18e6b555a0a87c2088640ca73051b3dd59ebfef922be0372208fce602d8001681297b285701dbbe24ccb42541b5db4aac1a1c7f407e11c83db15b38cdbc25e930fdc6558f64d9503e214571a435d890169b 0049f5bea6e72d98579b78cb07d89f64503f8759dd7a73cd73713c120428 854bcef1fb40749a08c3056f0c718d01ef753711fba9747a4d2d6889591d48fb784e870917a1d719c7d7990fcbb901ba +99b3b8f876f8359bd6369ce84f9261581c52d744b90261a1427ab9e447e6d833b6b3e89af8dc770f1dd55692d01c8bbc4277a729fddfa7cbdb2ec99133201dde44ac691a77904ca816feb0a1aaacbb9fba85048bc63d73506eb908ecd697caf582747051a3a38ac8930c9a4365f407ed94ca7f2d26913c53f4c010c7ed9d7ca4 0005eaa818690d1ca4838f0bc667be5721d178c3869884260fb230277c3b b24cb9ee2a3cf85d7b23792d0cb6b0dd8ef89c7f32c54c187b797f4846794fc82f737e263819b3b852907028c42adee4 +8c1a83023930a85c5b2f9930521b8b8963d5523a3323d87f862a17d3505ccee01246ee1029b8b8c2b608772c4096d1e914cb398f027d91184a8e94e4feeae121eabb504a2a35c8bc9294edd15ddd979946c14c792ad787dc2d4deffa284830fc90b3f8c0ced6a99fc6de7c41b9ed261402a6b3d702ff86a9392731ecc37430c0 00603d89cd2f741d734587e77554fe6bbb1e5739d5ff73084d4de8ed69c4 876ff9df272630817343534c74ff2280e966322018a6a20337695fa4f15a9bd2e1212abf6eac1a1fc88eed64b1109de3 +f3c9dedd7115339dd3ede7d8d06a44de66bf80b4888ab7bc386cd40a92789042440a13d2cc90dbcacca5feeec1e0e3c51724146e2c4904ed6b05c7b4e9b49d7f458ada695c5d2fc36f1193329b87c1268aa38eda9151430aa0bc004e5d2a61b9390accfc699f2efabfec785eb34f52b1beff1e4c5492e922acc348667d2a3986 007977b3aba53616dac27b4d74930da23966a88ad98f1769674789c0be3d a98da61195963f6622cc7c90ff9dc1d390d94b4f0f9bd90969ddbd8f0ae942c9a1f42997e300a44ebca96835690358d1 +d878c4ee0bd6c84652d7f9e68df7b90cc78776d8d1b60f3e4d7465032bf401f1527ca7bfd4a3dd916e13e93fadaa5e5f20c9f47d12f8fc922a9a3aaeeeef294c221ca1adf7df85b888faec8002f17ff202da1be837827619904121167bee2d2cd694a263d9a99062cada3399dcbfcb283597a96ebec129c65e0850ec4cb4e2d7 0050cd20e7eabd29008cc977d0a17e1195d79587b8f15ac2447e15daafc0 b543dbaa552e0bcf894c02251172fdaaf2383b5aeab8035b618f6f27c5ace18cc19790218220d532317206f63b4abac2 +ac3c118cc9cbc8eb3b74d8ccc9ecbd81d1996fb25ca43c8a43bffeb244f722b93c9e969241d45d5b81fda0b399f1e3623687190e428dae077e54cad1eff75ec2f7fbb9434bf716833421bc2634885677579c237340f76787b2eb19b446d56c0f2206099b81493349f4db0ecad0e2dbe85dbff7d7070abb3d3b12ef0cec828af4 002dbb24fcaf9f3cd5d50d209937f0e2d134fa20ee3c9c2f1fff3dfbf302 b209e5d80e18c9979253eee128993c210155b7966651458007074c6be7ce2777ed4e102644b8731d880a4fda1ebe8cb2 +700313698cdfdcf0044ca07bf9e5f0702ece7cc66e35decb28d5f8cb7e7e5367a95cc1728a90cc9a53a2b5fcd4702028b742538e9b386f5d8b4a2411579ed9553021a95bd00a73f03c4184a6145aaa367e3af76659d677fe7a2e98f9ddf4aa20eb8d1a1db72c3f5590598801be7ebf44255fd7376d89d998b7068bd1296fdc38 00047142197d3d43fa46545b547968680ec81688589d1ec8d7c7e90eb969 8cc2f2b9e3c51b24292cf8f9fc98868ad87e23a32b3cf20b3ecc600bae7a1ae0ae591f28e3f8b50babd769bbe6d67c8b +0374673e1a685bdee55504ce3cd333f70084dd4ae685464a16924eccea34531663fda60229166478b30193459a3113253cd6494dc26154156252dc6e822552c7c04d790eb9f8fcef2ea8dd79e72f881f7f20fff93cd73ad303c0918ec27c6486c4da61f82bcd55422d16650cc68bfd4b0132c1e7075bbf17dad919095860d445 0031352b49ecde5434aac05f898e6ce4337304845d748f114c14319fe97f 8f99fc3167f72e1d12e2caa61a61a6b47972ed3ec27f93256d4af552d8d06f5d27504366851a4f4f739e1574aa89bd5f +8b237085f135d6e94592f8d855ca397c8c1028236a3b412adefdac888245874f586d06950ee18118f751bfe26f4c31465ec34b578caa44cf1b7109ac4f6eab7f97ff9699b34271df035d3bf58a2ed4bcbf7577cf8e5792b1945ebb9389b680baeb8518c8fdc5540e192aa4fde0eed0d7c82be2e362b286f582d65752c8db7038 00176f124c24e4420f6e726a6ca25f09dfa0c5a37e5bf879e7bdd36c3b65 b7a5de6bbeaf32af3976389ca4c74e26077d747fa3ad36cd65ffdf140a3de542211c433d445f5fbe938d3e77bcf4281d +e3a086ec15574f7017b3cd5f5a47ab7a73980f11074333490dfe9f8ad8926f9ea7c82271aaa74e77133b1025b0b22a6900fbb71251bb6549341a23d194e79d03462cdad52ee0d1b6f5d0d14e1136026961fa3467ccf0864bf7ae3fcc3b68cb35df7324bd9bbe58fc8aa9f63c19feedf19d935b71bf5981c74fb2a487f84e453c 00755c48c3dbaf71042c58cb137f3632e3cf9d90b7b9a58fd378feef3d19 99a58d0f6a6959b5b126cbb545f1d99b9809a67044257be02f59c0dbf36415a5e0cabfb8c38efecb6c061cb4d90459b2 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K233_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K233_blst new file mode 100644 index 000000000000..eb1cb1bc0e77 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K233_blst @@ -0,0 +1,60 @@ +f23f784fe136c9fc0d169503d361e9c6148b0f1fbdcae0a97fae1af7033ddef25cb7489c9963cfcb009a8cbfe44a8510a64a073eb1deae4c324ceb9302008c92c69b2dafcc9077fd3cc3c7c119edc3ced36d176ceaa55ac036bf7f07f6fa215e8bb8196e59a5e1c9af4f98b90ab4970885bd7015fa26a09e03c7cf6b4b23d929 004c1d414696cc3657dd9df73ace56eda2636769ce7082e064c260be45a5 9743436754a42540631b8aacb7abd73fb68854f9de1bd07cd0d9c479d1bfae76f22522887fd30fd6cf8ddcab20874445 +400bcb297552bb37f2f8135a9314a35f5126788bb6fa4dc74152731ff64c5dab4b902103d85443dec20e16b1d6629930cdc2bd183d4099f0e96295a63c2fe266f5e9d050c401a8681b4a438efe53cbd8f2f43e2a31e9f88926a9c82917d873f6e8cd5ff5eb8c1ca36126b0bfc8c2b0e85a7c9e7a45f1875ca9c82019ebedb729 0027cb1d84865a16992476c9e353283d5d6a40c349a8e9179d1b1f403531 902714e5e4904fc849bc7a5ab22ffb6a2940e4c581b13b39709d9a3165c84de0990f797d14f3bba7c64ef217b8e72be3 +5f74d4b35c49fa454c97c05fdb6b9f6822cf1a2295f15bd766dbcb413d77c910bd8f4147e8f317fac2300fa21cb80134d1b6f8ae8e50518c1f648a28506e419f5a6e8f05abffdb3dd2587606c7e9c223ecff4f46b121216730ea13202b59128a7616bb2fd23a7e4a5aa08641cc07b669641313febfc88d64d99447353dae3f06 0031b443f46c4b5224237fac1022ee1570173f664aba0c84dbaa4246bdc1 aec587d2d76cfde7e4a411ecbf489edf837ab2cf3e8caf625a6d32c41d826b75d618a400bbd951b11f6050dc34283430 +8f92096876d9f81bcd992369d42d0b5877ac969004d17c8627c58d8b8b7bbf7a37e8cb6afa962b9b043bbbaa5bef4a5ee38d8bd31cb5866b828265a2f4102a616f87009cd346fcb8af5519fb577c60d8792472232f33dc615655e53d2b715b15a2697b492f108b7906e1e3597c6911f8cc30c7121ae338a6b747ec368f8e4a36 0048f6ca29f35f253a4962734357c995920967b9eeff1ba5fd2080bfede5 ae733dafcbfea91b21c8a6efca61a2715edb932a86df471aa327e65aebb69b5adcae6bd76ac6340c5fd701383b6a6f3b +3d275dbde44494c45fc15fe89e2ae32aa26426a17e923e895c7941a5582fb95df4d49873ab1bde358017f336b911b886b626b744806ab8113418473c441f1964159ded1b12122d53ac56573167588e4b55f36b8bca8c67823883a51fb6e7f204d1c6b07ea49b577bfab9ca6b8d51f72268b022e3a4db6f9d265ee8382f9b7b66 0019b940eabbe682f961d9f3d90432e347fef3910e641656825d775705b1 b4ae31bf40abdc08d2a69da36ce3d59e2ab9d1f86d7f73b4a3716036f6f3f87344dcb4b8b1841f42733e30857c1cec44 +d2fa68e1f7dad02916b12fa38f1849d6d409dbad0344438520b4dd9b77d62d39ac9ae3cdeab03ccbcfd4de703c6e798873671731c108f322b9f2a68145e3e210c9b15b879798e5c53c5022742e9819b99edabb2f44d89ae221f7a99dc84421a6905695ff91928db608f861745f17584d56e34b75c47281435b1b0b34e490692d 007a884b22e29fa9fe945e9ba13c0df8d786dc87cef0f77f069e182dd56c 845b36ddc6d5e4620118f0f0b5746426aba215cc35cfdc0b603fcaffa48075ee561724cc92cae3ed7540fb5d2ef88e2a +3830f75cf9df4eb2998c7c1b5fe11c1476bcf849c3a8fa7d3d0b5bc2292e5d07465ab8cc9381c575d909e509c5dac49c78817c04e4bef18bd51bb09aa5897f21634633a5ce6d20bb4638cb6c3927351eaec7b62cf4a33956916045c392f325adafb10a88a5f86d7e41dd77908fa7284210071c22aa40ef40da6339c02da05392 005da61f881d5a0dc085bb93764f584352882923cd237d878220ec624c1a 8cbe620f70bbd8591f49514d2e6a0788d79e5a693b1f89f3b9f6746d66317d29e2b87f94ec2801b51b56966c95c43f9b +65b9fe15e6c35d453caa6bad39ee78a720a04b60d8a0a0f049186d2f777e48ae2d657e174df53edb7beb9f7d8f21904ed674add0cda5b62a7308de76c324a144021e8c6d387daaba4ce48bf7dfe9c8aeee2c64e434ece1fa5ddcafcf3e5d0013a1eeec1742a00d384cc2ec0d7eda83bb4dccfb0e57045ebfc27a4f404d03da37 003fe9f04647f6d82b13ec1ae5a8c2e49bc66b05649ad778eb16149ad83a aa3b523f9323f08e3bfb0959a647c1c4b4322691baba16e723f57b8cb12ec92420a093e4cc32bb0d7989c400ca1c3338 +d26521fd41eb5d46ece6836e188bf9cb1b461d011c41e002a935d256654d01725378e845920ec4a7fd3f379df54772493df50d312c7c6aa4e909e7b83f2442c3a5e85c37d68aa015098ecfb0a5e077370f4576f4bc63bf37e1dee06d780a3b6949af5e21c2a0960fcd20821ef5f17bebf5fd5b3bdda260842cbbfad45667287a 005ebce648ace4cd555413de6a456fc487d14bf4b0b9a72311ef480d2f26 829868395305ea9921f672c38d8a3237856905bca80d0b82fa41d5cd571e638e03eae155593fdb6093915d1e917aba65 +b778c021b1a92c41dbd09963da07018075d73e54d62df5c2b7bf8abe137151650d1c1c6abce7eebd8f32e8c3e6d1433773f257bb3ba4a4fb6a02c0db1e47d03c27d3a90898ebd1927c21df24c4c5443ca5b81f8ef2cc0f5e8b3d08f472bf07085df737adaedec63d99acd77b87ba98225f198b791124ac2d9b191cb9251b4b00 0056653c2f85593f789a926ba49fa3da9d7f946d8f1020508c5a527ce813 a198896b4a8dd5e4808d087df534fc269fcc7cdd52b24e491ca43d377767a1116dd86c2e05e221fa746ebf93a999fc94 +ec14e07f615960015a489ef999e308b42a4c571473b9bd64b433dabd9a1b1ad02e33eee9100064405175928a94543a80f440040afa2965b4e5f95f768e7fab6d3c0a5f5e1bf1df7822f78384e80f2955ea85f044ac60537d895747979f935bb0cd3673193c4a32dd7803e48d7daf70a71bc2aa97236615b6411e28fc9a652145 0049a91d320783cc70a5952c32036cfc75d41f1aa84127db2dc759fb291c 8ffe5b30238d8e663c99df4ef61005ca26ff4fb1124e48a8c983cd9c723cd2435e393dd74a43af68ed8503cdabe2a36c +89c645339ad0eb850e4e2fe583cee175b35feb02ed7541d7e9aace24cdd3939584f73ad39526de6399c86b36de77a018e2c70b532bd0f032f9137d10480acc30c49f9baaa86f9df0033b77e98b485bf7a69cb5c281e527d3ccd1fce2415f0dda4a268ce68a0a34b16afda54ed922cd6810ac8dc766df2a3a6c5e55972e9786fc 0016a20016602fc7088a60469843e1d29ad67e3c3cb9500b1e2a00d4050a aaa58e9b3e1645dda66ac19bd7bb4a56edf098873f60604b5952601ceb8b17fd3b0e29a9266ce8857a532f9b59ae22eb +ace14c4b101d2d8453c2bc22b756af016b5de537df9c3e639d208ad04ae0bf6232dc90b90c33228dc85de956db771ffde05fb4d0b15e4f218ed2771d703ae5bf981252a5bcd60c16f14483131a481cbe04dc0adb1fb8aa32cb48bb5008e8a8e5c7b7465be2fd7afbc811cf5ea6293b1a464669b49f55f57b93a8707e6042fda6 000ba922149bada2551b7be1c3df076f3f97ce93c13c50c285fef3f42363 b9f6f2ecfd01f7750e68288324c623b5ab7d3498189fe8d1e76ef4131cdcbc2c02443ecd160399959d5c738adf5f0dad +cec2ba0d1772c87e87d5bbbd67220692bea4301aa1a66e8dbdd7e651d45c26dc2a0d45cfc32c34d76ae3e1c61db7b0fe1863457b93937d929e6ece7462ebd16adfd708353d6f7c27aafe06593c76da7149b0cc574a4290b0d8fe219f3eada7082aca38dba3f78ed0d5942d095fa5556fc8bcef331ff0a6d5d1f4e6c51d4ff5af 002d635e12a58cc6dea44e71e87c37f91e8d08659f0b7955d24f65ab55ba b5b49a67306fcd726f5654aca831146503ca84e6daa60981b118255a7e0bfc9d1d07c9145292627a1b04c30813818de1 +ffa13cd0f51ae2643d5d4edecb493ddd653e9faddcffc370e7e958abf726a5d67a2ab36cef42ea8ebe22a6f01b9c31f6ffad01e6894487d979acb5e618f765ac0ec3550ac5dbbcede8f9fdbe52fbaba5c087ff382b6d7a09b2b5084227d324d98ff98793040884799b96d2ca593201f4414f18c43b51c53c5e5059e0641aca02 00073883e5064e06814fc4de32e15f7a6cf825d2daf6eb1df8c83e25d80a 81d274adb7ae88d01880ec98814a2daf3318d8ca4c3f5f0ea837b91e854e9f82544d01fb02b524779381dca73110c4f3 +c73e3dbac9513d0361dabe94071faf03a11cba18c06d131a172d5f0125b01a5eeb6055bf72c7106fe3f4be3bd2b1771cbe7f85366dccfbc3bac20538510c3f51179cc540ddafb2f3b05a0d276899674ab1d7d8fb4f6838f04e4f9e26b8c6af31540f63f4953c85840af4c57dfa78c704f637dfc8dd750fe45e2c1e149986d127 001532271bfae8d4dfe60f69b88d3006d58e28aacfa701861cde8d624db6 81ae4c6bd5051e03c0120f8a45bd2b6a333bcacfef1022c83d15ded3eb482fa45c60c43a01602a837073dc9a01c36dff +d00dcd0f3212a3167403abed91c20e76f5e7a7678a4fd970f944d11e6a8cd149d0aa6fd3164c5a74c0f55193a4fa3d8ba6f99cabed10544625a7bd92b3e0b46edbd4a269bbc10518c5268c3910a2aea567ccd32d4c7a0cbef09ea42c20b636d1f711d220e23dacdb9d1146e0494401349749e5ed88e38295232a7effbae3aed6 00550406c0db882c6aee6cf3b6baf377375208c3e90cc44a067cee43efcf b37c4634d5e1709e7987c874e8ebbdc3d63b9855fbd5acb33e0c59f0baa82e56e016fee5a3f587ff74889b4b79775ee4 +3d36221f87157ca4db84884b8666660c4e2b6af330480c516cded9f3bfe132543626a39bb6aed1964eb5c33ea0b95b9841665417679fceb95d199d55accfce35dd3f2283c1a7ced57d0c4b9ebe3da6e1ff2f979b6440db27caf9f6a4bbfa47e20d29ae304f4d0551fce9cc4097eb2fbedb9b24680bb17d207bdccdbe799d5b0d 00257dc63752920b6854d6c2d1cca68589a38418c3d036e73760a12214ab ae6f146f69f32ebac9b6e40ab90d658c0ff37c71d0e7083ee3deec8fd14d9dd6fdd66b12ed16b62ea7c4e16ed108f9dc +033d82a42d0eddf58fbe3e91ddff7190e3f9fc2b1e2eede977d2c0473b358b5fce1f981ca6f88fd61ce2f79e453e3a2b77d1baab2b970ed28d5dcff58873a620e195085e61c4b8480d829525a1a944e8a4b63352f0291f0311f1f98ceb262804beec1c74947618f8e3b067866255878c2502966cefcdda4f5fa2b13d92ce7840 0029025352297a7be850f8852411c09259b83219135e0e8949c1bd5b94c1 87b056da3351586b26e28289b5133b3b36ff5254785a1f9ce7b6e2e03d5e7b7d6db9909d3d5d9916cdb57df807487b00 +671a7c81b64b2919722d7b258bdbd90165bb757b53106e0af03d0eef27452942f40cf52bc95cc7f6567df2613cce795f8bcfc723b2735efc35375c001d37c58480d89343697146b524835df3dbd333f7c06c98e36d3c4592ecd1f34ab57c341bb0f4c785f5b8372775f74b4bce60763fad1788e77ea158d735a64861320b36c6 002dc82d0e69e498528925c0e62a13fda9af8cefd047c10c3ffc2e41da3e b3580919b62726634ed242c64b1a7aad19cca2c3a277eb39eccc2fb9bec696537c3b15852c4fc6dee2edfe3d6731ca06 +0ef677f4799298f4aab73b7393598041f56e902ced1726af49657b6601a06186212e3ee8cd4bd33b760dfa2ea3c38884f94358d51dd479f2ccc8b0b352fa4e44fcfdcfbb24919d04e6ee1108527b8e8d60e8d1b467c30c18c5455e5835d483161d3fc26b4a67d6df9e3ddd9331247cb18450188752a1ca219f3396a872cb13d8 0041535fff5d279bcd744b04e643458ce20b81df8a9e01b1181d52bb14e4 934940fd9de0bb2dce5827b803bfdb7096bc102ded9a015ed4ecaee0a9c6af220548dfa5d891e047498bffc77ad82a52 +9290df0cc50c3cab6655f3a6de1f4cf613d9bc06ea7c99f38038369ff2fadefa57a3c7ae7940c1b98bb1d03503cc271f7a891bf38eec93c31dcec7892dfd2e1ab337bedde3e5325ed8d9cb7fa3096f6fafc3beb3a66cba66ba826d1032debfb4908cc9dded8c0099c85072daac4373fbc428fcaa9a6da02181ebc33f0cf926fb 0000ecfe580a624df66c25e87e7689fc3b471d205970ff9ab51a64aa12ed 8deb2f580f39bc9509ea7780833797cf62d375ee6fd2b2e2a8557c238b02cde50db5aac75afc20e0ac584fc765911773 +855c7be75fda372f062709827f333630acf28954a62a5193ff675f0dfeb63f32bca418f7cbdb346bf388d62315b19a592267ca407120db93d4e3d7125b867c4c4670b7a57a76f61734cead2caf2425eb9ff0a63293e8cd6defc9648257b401463f4533a2425e0024f1ea93365eeee3c6da20d25928602ec8b426f9b39f97f3fe 0013c72c73358ffa168423149ecdd897f0a5f75a641de008649f00134944 96d518083dd24c64fea0b66035fad8924ca0d348687b37421bb80150ceb6db19c8a6705af27d62065c3fee0b1ad590de +9c896f800281812ed57d31623d563377a5c725cec84313472b90e73f77d400f5d4fb236255741b73d46f7e5254d04099bec274db8a9af5fc7cc220d42cc172cbd3c3595c49ff74bfaab7b5e46c90855b611f74753ccdbbabf92e011d52e9ba753b83ed2a251a632e1bd5c6d346e38e743950c8ce0f394a837028575fa44bcc26 000ac60e2e70b7c4cda64071c7738f68773c94df9456a8ec3bbb468fa7f8 b48e104f0fc7bd45eff2fd6f7fdb3f114e68862327cf237f64acb0a400c2ea28636008b2af93de7b60c705369fb723e4 +139a14ead998d1a962fa47c47ef2953aa136bd912fe940709b8c560bc2a0c4bf8f3aab30a8e21b7d5f487d30b0097e3da723f11b5cb4e8c5724f5a2fe0d68ee4bacbb85e5eacf18094d2a8ec4506cf8497836a4a905059a998ea750adc54c27c69cbd0b0c1f9743a62f3d988f3fa0a9865a73fc071f526623085a2ef12838888 0060bf720052e8b9508a801340c213cf53bbecf4975faee63d4b44fc647a b1e290530a29c2c8aeff7e5d60ff0df7e67d571ae963807d46ff777ab5bfd1442e2bc174e9fa8e15a13720bbecb5a45c +cf4a8e754b23d0fffc1c5c80b0cb11deeaba3064b315bc2cee96db5b9881baf90d30af4b69066f757b3020706def77a5fc1632d96bafba22a9c8cd3b52d535d941b3c7cc02b7fe6b51639d5e2084478ab3a29d2f5e0e16639fc2833a47b58e2c3fb5b2ea1830fe2ff68e571a8f281617a23d9a28db1c64ddfb1083d055030e5a 007cf3c216592febd8630a478b5b3e3a605084020322adb13ac0a626bc7b b56a7cf6f50957def38b5ab089d2d8838b826dc17ebc15e9c4b14ec44f894ed5aa4867856707508b24a1a1e4db43aa0e +ae64030d4af9b36c8d3a6af0aff34e5ab201df04274691fb420b7d5c40c401ed7f3ade96065d34f2490d17943e27156e7bed83cd7222d0d5a73d167855fbe7ff6c3ed87f20986ad8bbbd80fed5f9705c6c783b423f641d40ff1f367f9648af5a79ea3cea0236997558bd9dcb011ea4dc64d61ea1e1f85b4f696ed586bc7705be 0061eda5999e5a9ed4485d2a0ac5510549b76ca37df858ea5d95aeed571b afd2a6f2637a1c3fb0566e7003e7c62b39f072db416623ad93ade9a83d5b26684becb5a46707adb854b179b155cd705e +94a9d9cd9efa3e4ccf2a37f904dd9cab5624ec9393cf8816ea591c5e70cccd2f105388ae133708fb974998ae61d218c71785f9eb808d1c28d953cc7eed00dd9854b6b4568c5ed5ee3df3b58a1e04c64f1c87fee4365ec9aa41b08a6bae234dc43a0bf2f61420acdb891a40f17f246972afee75a4c0b249dee0fc8f9b9c8a243d 007e7e73171e4d2f2989dc024757c186485435b82544a448f5cfca05f281 b38d21532debf90510923900c7564bc142f1e4165e1990a57189175560ebcf2fda7f254c2bb42bf3adc2dcb4e8a7b258 +4db998df7b90678b8aa4ec6233c9b4629800ad1f3e2cf8f7afcac62fc6982dcb290e44587015eca8dfe77dbb4a80f9bffe75b11e961e70deed14555db6dae47d49e73004f000eb8677c18f7e8234bf0a5a104266167a05ef07152e7acc2f0368b37efe69c0c2feb51eedf7338cf9ed398f066cf1f66bacd89ab9376d41da35a2 005f7270764a0444c7159d2db867930fdb0fb9fa6b8fc80ca02e11753095 a4a3772b2b1bf89efec70c10a7f499c35b7297c626f5c91e219572f38210d7402ad357496a1d270ed70fd512d9d70e90 +dbf9b8a4ae316bd2df0c80db1cb5d7038364a2634925ff957d7c03511b57d486274b2ecf191746827c325a14dc94daacd66ad86d369e3f598f176c4f0eadec7e9edd13e34043efbe0a801b75b8186b4a6d89ceae4fb250ab570d65b6dd7c04382738fe3f6f6c867a7d84b35b20720cb0036a5d81a87126f236833831d9ff00b1 00179b924afa4acf30ecbe2b3c12de533a1f9675687876a7e5e5ddc8e03b b7502bc48738f264c6d9fa8708839ec34f08ec3de661028813b939e9fd03d008b02dd69843b7fb140e435df02c83e807 +986d9e5d636526f4deb7545c037fe81b09c74496ddb8e42e61650c74b6fe348593f0cf8f8eca5e839baf62f17bf6ad96ec0c71dc44fdf11259dbfe7499157e402f6bd5076972354150723afb632799a990c44cd0a4fa9609ec4db133e3b4700be3ea4a338e8ba1873d345e80163ed60d0de274d7617a8382980bc2138b0a2a01 002c9eb4d392d7f2eef606e1861183acb1fc753d666225f0f154d9eda147 b632660e032fd32e55eda5c199553c86edab2916f5059e616af1895c16aea135f312847854b4c7eb0729880b4bd1eb77 +68d0be2883598bfb1433886aff118349157708690380c42b8919859d96db069c7fde6e117a3669f2cff94a0f1b66b27b09e3f1b24d26299e11552a084be428446f3174da2e0414655bdceb38e58fcb065b6661190862db39c6545dead34a03584632e988d0459659dc7c7c78d4d00fc2aa10465cf24b2410f14e2a62173c9962 0024661c89b77b2c743cc175a6130904461138ddc4ef771ffb9fc2c8679a a5e1566ae63086cd699af1cfc7095afcd5c34cdfcf7164996745516a8b1d44dfcd9ac2a525bcf4e2b70f6a07c2342505 +f0ba0407485fecd7337f4b22236533a926cc744a5f06dd08276750196f1bf7ea7984278f789f92dd07e36895a8bfe297ea43d4a1177c0368900e3b969d3083cbe626f0e27e7ab38e185c923dff46d9ba187b2acb9cf4b23ec8eedbb8044b96b5263d956e50cd6240c66d5d96517130c743752404ed09473f05d0004dc5971ff5 00065e20e5ce534576d7c17616cd4ede3bf4f500894850723bcc9f895f4b 9564aec5c54f206aecbe0438c8cf5c21ec340ef9a3fd9f958e48e10a455a2cb7a60fb7cc73e894f30a002965736ea01c +3827276694e413c886129c452c9a66e7d09dee84f5f09bf34e4baa308b4627e096c7d45cf6ef45ba1d9a4019a60399feec10fa80e333e2aff1251c85ca48574d9b9e1affb9666828dff5afcef3edaf5e8cae823505a0c73afe76c1bf130399fb06b092ba34ab0ae15ac6c682f9ee8479b065ce75b57213b8aae0f55e4e386de5 0014c85f66fbbd653f1e4e590cffe62c343ba6062df4b271fbd02e5d42f7 b0c1b92ee4702d60dddb5a439b649cc2fcdbf5148f17b1c6a19e36a09d18be977d8a17f594d41f83e6b1ac367751edbf +d1afb8965b48d66b9acb1ece674d9548f83395275f2d8135554cfcc7ceb96450d850dd874529433883709483d0743798db5e0dee955a4f30ba328c7934b8dd9207f3c336cf89141a175ebe23d2faed629eb4236a8aea8300604c3eb7704512f240fda66acedf1494a85058dc6a31bf9531958c332b93cfe5545046876c6b99e0 0030ac7a78593b570b29f6d3d267abb6ba7e5870ee1c8ee4f1ab2f141051 a0bfea0fa993432615a4a6f54b9950b8b2a0185d7b755fae21bf307e86abb78b8f92adb4a70d9e3d45411977fd582cf8 +4f95b71669fdfe5dc46d4b951b085e099de349fc740535175337127910acf24e9a0e4b2f23196ad23880da47b740d77d74fe9bcfdcc44dd7d8d1a181ac290de5cf4da22d5034cda3d8020bcc776dde8cef1786c9ce4d2c2cfb035da61406af745efb7ef1a55f2eccc5000319cf1d6380963025dcea641cfd15a3106751fec286 006d7516aa040f7d559cae248e485834e8d9bb608279ed4d4f7e1dbcd2b3 a76e5fe04e808344444fabfdecf57b3dfa271eaf2418bf515e6e1efa75ba37823e35608af181c05a853325710b287c40 +2ad9e17780c824c4f2d1e1cbf19ab85638f2f71cb4fa3518f08085b8b358f54d4f08394a5ac29cbb3cab828c5f07f41eec51e6cd61a5f2cf44dbfa46834370cebdeb328fd3bf681e61011b5c2ebc8945ac7a2a8467606051008b15c89390e111999255bfe28634ce9bc2850a2b55a4af1c4c2f94403c78aba1ebc87386ab7b32 00137050d7b455f43a8dc2516cfff5a91062c1a2727b27df41488f3dcf18 a2061d67975701ae2d4eaf929392b3a2151d26dcd0a7af0482b14c06219f0877cd70778ab6b23dcb819a6f5c4aadcaa3 +958773c37d3eba003aa5c489f72118b3022c52b93399e9d8001695664918b86893f4922c7b6e55b1855ed0fd1d8de5dc61af403ad660fec60d7c44bd0102c069957ed804d0d416facdc1a95355ef58554606579ef89b1842f1055cfa2ae118abbc485356824cc09dddb77d0671cb3011b33bc86cac526e3f6bb3293c7bdca1ff 0001fd447b33a2ee3595b9f885c290d241422afdd74c3dc4981955a7e9ad 96559d0b4b9ee89eac5d0c3a72af2be1909e771b7a0699f516ed70e9f2ac1537a6895997caa824ebabfceff1c72ee0d0 +9cb2c496b1bc7f040228571e005e7e936e48e8f469e295edf914f5648701249a20bff6b98b5e862603dd9f12bb71c160aafe9df02e2e383e9b8a9a9d700f4425ce408feabbf754be543f52204c849fed6c9d3e36e03dfbd9e35c18d7bb2295f1c484a66e73440a0a5aece5fe80b9ade9321ef18cde3eb2db15e4b18e788b0441 006a061e10b4a6e7001d95411cb31bdea9c84670a59ed61b14fbbb05c8e7 976d56e83bc0794ec519f783117c9a1803b41f3824df87464e02262ee4ff59843a53933d18a8045eabad84068f4e27da +9a4bc0a029e97742ed3bca207d5912cb568e4403cda106b00247520ea02008b14c041b8c9b976294252da835f4ff27456039d79d90315abcb0b9b6958a22352672e229665457ec79571ca80447c8ff2a86e6af3dabe7427c8bdcae65e3c6746a56079ce2cf8d22235180f46646a21cd9e86032cfad874cb9c67f882fb037a13f 0027ec31ca31acb4d2fbacb49fc085f1261b0042cc755cc97f9b199e7a37 ab1f1511e6a36e185a12dd41d71768e0ff2aeb8d957debfe6ab1dbc5624db67e68662f0d90534dc59bb10d35b4716b31 +8d89e22cf802dc68ff22d43c436c79311e705ff6fd845e77c880f399f403e6d5e9e2b35511553c978171189e288cb2200fd95f84ec5ee9865c0eb9190aff6dacf783ef200e82027fa992741876456472bdf27f2bd8ee55db15408c957a120eb64cd24d299818726a73fbb0697eba726a326719765735b37a2dcff0c853c906bd 004c6f4d88e5a4f4f83196f2dda9dcf2a66eaf94d50c851f59bfcea1d876 95382e5a43b38eacd88d122c0fbbdc9e39389d3e2ac9f1646e8c5b9a3bed455173d3c6fc755bbc8ccaefe85970dedeb7 +aa1bf5a79e5339fb9ef6c2817bd95725551d064bc5064d6586c5a879901adf808dc2ef7c78ec3b434b84569988db58b5e8e9782b1cbc2cc7c9b68e66f32d4ac4ebe7e75b345f654c7b8a5e650acc9f170f75b7aaa3957cce248cc69cf93faf8d72abc6fc1cfa9ae2d18a7b31ce720147e88e84f6563b2197882fe302449ac5ce 001aa169ea84365c22981bb766bfdad27e373440850569957544b0f9332a a304bc53e675b250a62c6a45ffa393b05d7eb86d71bd4054ca76893895a415c3d170096c8d4a3a50558c53493b2bc571 +475664d5e22cbe0da0d0289ca9a666a37270dc71c81cffac91f6229fa39315c1d55f7e0a89b6a7a07df7d391dbdf8fb7af63d2da46ecc3b60110dbcd842da97f98d2b67f562b0364ef8e1c589519024177c8ea079794f271f6d35554c0e9d0a39062383c95721b72f4e74eaafb6fbfbda02cb670a7c4c94f67b8ebc6442e84e3 004a665b92c0c33a3f8b9eb4b0ec061d40b603de36c87096455102ffe57b ae26bacde66bdd3b1cba1267d9a9a233ff6c0bb1a0a821ff63f73311dd92157a32770410fcebeddd45992ea5dbac9b2a +9e5397d94465390a82a3c07e3ebf21b515776d18b4463aa5810e6b2f96ca61e92d13e034fa853c3fa45411f51f79df6f799a2c6906e6a5b7896a4576a4464f9e0be2b529a43e1f503fb640d79db6b68f3a3a7deac1b5832fbe86673784ff6db1f8438f7dd332cdd1e7ad9df8b6731aad1b6a72bde52e6bc62d80b8da57822c48 000531540d94823e19ab2b95cbc6e7492e1effcbabce875de6ba96f53aa9 96a9fe6ff05590f43da263d022cd43a874487811d494e23f497242e9de40d8e84a9f571d33903053153547aa431449b6 +3cc4c4192f317e52df6f8cefba6d4cd823c942aaee11b9a0ef5de5c2d181073b7085a55805e9554def8dc13eb978e7396044d4f4a14be2c7605998c062095c929b9c23b2b1b2fa73dd19a0c0af44ca4789f9841fa62dee8a5f91b3cc4b3264f5f67334c3f0772b30bd7431c3fbbf1f34318ce1889b6e8a76ce6d42079a451e56 0022a89addd8b85809e87e0aa2c038593ec277054842854de1197833a51c 85196c056110f08ba18b75e4a5939b2e0db5e04105e840a96a5455798d5c55361355be5263486b6c945fbb57d7da5fe7 +72cdef5bdf710978e0aa334b86b8ff4a58630da314eabe98b4d611aab56f55c526983d54d19bbbf9ddba30a84b18aa0bae9f9503e9b222f842f084db83aa39625403213ca321cc0d9c8a136c826e6ea4ec108b913dd0a9ce9d5b8c7e3af53c3876e56a2037ebd6d99f037a097111c837647bedfe4c494e4288ed6427c15969e3 001df252a11ff97b4421b3a2361db94e908e8243cd50d9179f9e03e331f1 b1cc45ed3f3fed000176f7317268371620d73a4c538e10c103461c073fd0ffd6199ce9efa45f175878f9c881b8130a3c +8e4eb88c0b2d525b2c58b8e00f32def90e6dd382301de49e0ac053dbc6b61afe926d85193e2c4948f7402a3d7c614cb2c58e060362b0516a1ba4a7425f1b3d09aa20d4c3c8993a387a3248aeec51e6efa8f558dbdcfcaa13ee08413227c8351e3107e9a3e3ac124224aaea91bfe50c11c1c8ae582e718f50bc5d5c06076517d6 001d7125c299ebd0dbcc050f07de931c7ad0450af590d0a2d0228a66ac5d 8562f87afbd8130043bfc0132feb325f3798911ea12519f98880ab6962c45325c26c614d26be21e7c39d04e2cb88c728 +370fdd80f330311dbb3959666001bba61cdacf20f72f78953d946fa6cba02d24b5003f5452d535609e489b9434f192011f99f918defe877d51349870e7e75502f61145f7c261dbd2a0840926d824ebe9be3c5a77a3a84340aea930378367ed3615a47e3f792c7773f83f91ebea718a05fc62e9ed1d78629b2c27ae44fe8f8d4e 0021238e66119844b146d40e48341f522f6ac2f9c8a0b33aaf95a3099a41 8dfaabab2d4d5a0040e5114d4a50a449aec66c2a78e832e5366b8acc417ad9b8ce54566a3c1859d63d867d26a5c6c930 +f86c4433787c3ec3cb1663389ccf53d62f9425274ccef05fd14b1b8fef676208867764eb98d16d006ee6ebdc27b8d9a8ddd303d941fdd82b630694cdc698bbe6bd524411907834286c94b24ee199fe6d646064277f244b7df3ea2d9d52a9dc6a33d7c8d6dbc919da0fa987a67621ef0829e48310e0ea2bb86fedcf4effc0b94b 0015e1bdfdacd87c42ed439f3e243abf27fd42e54f3ebdfb47f60dbae5fe 8ad66ecacd31e9a30d967b6c39f4597978b30d9a43f5224b017f967b6e5ce3585ce92f20d562c0c472c52b8b84d9c3a8 +4117d593aa92e3eae1124ec7482737cd3573fe5f0f2a5051a7ce86946a2abb9e47a0c6ea75b262689b0b486476d2ab09a20efc2fb921419b1811b51a2e15891ae9e45a17ab4b96c665c6c423fc00e2d66df5804a164f0f3c958df6f25d7da6829b1fe162a0a8cf130858c83f3555d6ad627db70cb41303cc6380f7b3fed2563e 000e09410548c17bbbf28a68c3963a52d39743a4f1ac28e6dfe7a6ede281 ab56a135c2a8ddd7ff556072dada633351755124a6236fc4751a777910358b72f3e97634fdcd6ce1fa59413208f3ed75 +882ecaff3ec8f4023df5397167f238869f78a5c499be19aea85c7486e73f66f0e08e71cf85f3f1b6f6a70796bf46a18e6b555a0a87c2088640ca73051b3dd59ebfef922be0372208fce602d8001681297b285701dbbe24ccb42541b5db4aac1a1c7f407e11c83db15b38cdbc25e930fdc6558f64d9503e214571a435d890169b 0049f5bea6e72d98579b78cb07d89f64503f8759dd7a73cd73713c120428 854bcef1fb40749a08c3056f0c718d01ef753711fba9747a4d2d6889591d48fb784e870917a1d719c7d7990fcbb901ba +99b3b8f876f8359bd6369ce84f9261581c52d744b90261a1427ab9e447e6d833b6b3e89af8dc770f1dd55692d01c8bbc4277a729fddfa7cbdb2ec99133201dde44ac691a77904ca816feb0a1aaacbb9fba85048bc63d73506eb908ecd697caf582747051a3a38ac8930c9a4365f407ed94ca7f2d26913c53f4c010c7ed9d7ca4 0005eaa818690d1ca4838f0bc667be5721d178c3869884260fb230277c3b b24cb9ee2a3cf85d7b23792d0cb6b0dd8ef89c7f32c54c187b797f4846794fc82f737e263819b3b852907028c42adee4 +8c1a83023930a85c5b2f9930521b8b8963d5523a3323d87f862a17d3505ccee01246ee1029b8b8c2b608772c4096d1e914cb398f027d91184a8e94e4feeae121eabb504a2a35c8bc9294edd15ddd979946c14c792ad787dc2d4deffa284830fc90b3f8c0ced6a99fc6de7c41b9ed261402a6b3d702ff86a9392731ecc37430c0 00603d89cd2f741d734587e77554fe6bbb1e5739d5ff73084d4de8ed69c4 876ff9df272630817343534c74ff2280e966322018a6a20337695fa4f15a9bd2e1212abf6eac1a1fc88eed64b1109de3 +f3c9dedd7115339dd3ede7d8d06a44de66bf80b4888ab7bc386cd40a92789042440a13d2cc90dbcacca5feeec1e0e3c51724146e2c4904ed6b05c7b4e9b49d7f458ada695c5d2fc36f1193329b87c1268aa38eda9151430aa0bc004e5d2a61b9390accfc699f2efabfec785eb34f52b1beff1e4c5492e922acc348667d2a3986 007977b3aba53616dac27b4d74930da23966a88ad98f1769674789c0be3d a98da61195963f6622cc7c90ff9dc1d390d94b4f0f9bd90969ddbd8f0ae942c9a1f42997e300a44ebca96835690358d1 +d878c4ee0bd6c84652d7f9e68df7b90cc78776d8d1b60f3e4d7465032bf401f1527ca7bfd4a3dd916e13e93fadaa5e5f20c9f47d12f8fc922a9a3aaeeeef294c221ca1adf7df85b888faec8002f17ff202da1be837827619904121167bee2d2cd694a263d9a99062cada3399dcbfcb283597a96ebec129c65e0850ec4cb4e2d7 0050cd20e7eabd29008cc977d0a17e1195d79587b8f15ac2447e15daafc0 b543dbaa552e0bcf894c02251172fdaaf2383b5aeab8035b618f6f27c5ace18cc19790218220d532317206f63b4abac2 +ac3c118cc9cbc8eb3b74d8ccc9ecbd81d1996fb25ca43c8a43bffeb244f722b93c9e969241d45d5b81fda0b399f1e3623687190e428dae077e54cad1eff75ec2f7fbb9434bf716833421bc2634885677579c237340f76787b2eb19b446d56c0f2206099b81493349f4db0ecad0e2dbe85dbff7d7070abb3d3b12ef0cec828af4 002dbb24fcaf9f3cd5d50d209937f0e2d134fa20ee3c9c2f1fff3dfbf302 b209e5d80e18c9979253eee128993c210155b7966651458007074c6be7ce2777ed4e102644b8731d880a4fda1ebe8cb2 +700313698cdfdcf0044ca07bf9e5f0702ece7cc66e35decb28d5f8cb7e7e5367a95cc1728a90cc9a53a2b5fcd4702028b742538e9b386f5d8b4a2411579ed9553021a95bd00a73f03c4184a6145aaa367e3af76659d677fe7a2e98f9ddf4aa20eb8d1a1db72c3f5590598801be7ebf44255fd7376d89d998b7068bd1296fdc38 00047142197d3d43fa46545b547968680ec81688589d1ec8d7c7e90eb969 8cc2f2b9e3c51b24292cf8f9fc98868ad87e23a32b3cf20b3ecc600bae7a1ae0ae591f28e3f8b50babd769bbe6d67c8b +0374673e1a685bdee55504ce3cd333f70084dd4ae685464a16924eccea34531663fda60229166478b30193459a3113253cd6494dc26154156252dc6e822552c7c04d790eb9f8fcef2ea8dd79e72f881f7f20fff93cd73ad303c0918ec27c6486c4da61f82bcd55422d16650cc68bfd4b0132c1e7075bbf17dad919095860d445 0031352b49ecde5434aac05f898e6ce4337304845d748f114c14319fe97f 8f99fc3167f72e1d12e2caa61a61a6b47972ed3ec27f93256d4af552d8d06f5d27504366851a4f4f739e1574aa89bd5f +8b237085f135d6e94592f8d855ca397c8c1028236a3b412adefdac888245874f586d06950ee18118f751bfe26f4c31465ec34b578caa44cf1b7109ac4f6eab7f97ff9699b34271df035d3bf58a2ed4bcbf7577cf8e5792b1945ebb9389b680baeb8518c8fdc5540e192aa4fde0eed0d7c82be2e362b286f582d65752c8db7038 00176f124c24e4420f6e726a6ca25f09dfa0c5a37e5bf879e7bdd36c3b65 b7a5de6bbeaf32af3976389ca4c74e26077d747fa3ad36cd65ffdf140a3de542211c433d445f5fbe938d3e77bcf4281d +e3a086ec15574f7017b3cd5f5a47ab7a73980f11074333490dfe9f8ad8926f9ea7c82271aaa74e77133b1025b0b22a6900fbb71251bb6549341a23d194e79d03462cdad52ee0d1b6f5d0d14e1136026961fa3467ccf0864bf7ae3fcc3b68cb35df7324bd9bbe58fc8aa9f63c19feedf19d935b71bf5981c74fb2a487f84e453c 00755c48c3dbaf71042c58cb137f3632e3cf9d90b7b9a58fd378feef3d19 99a58d0f6a6959b5b126cbb545f1d99b9809a67044257be02f59c0dbf36415a5e0cabfb8c38efecb6c061cb4d90459b2 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K283 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K283 new file mode 100644 index 000000000000..b303d70ddee4 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K283 @@ -0,0 +1,60 @@ +ef90f85fbda05e693006e4c64e1dac56223becaf0890f73b5274e6e289a5a1de2c141b825c24d595b3fd18ca855b5c1aa60dac6b5356275b11be670692cdbe5f282f93ac7b2e410a96cb9e9f80defcde98f3449f99e192bfd62040421a0ab8f99acb85369f25e5efbf81439efa8a5e1d9cf781355a0f47b037b09fe4086389a0 01e846c830a8ec04e8572d1a9d2df044ab47352fb346f67403a3bf87243871b164511c53 a0df710bf9907198e8ca0a164ba17870b00221071829188970d5fcd9d536e792627911e405f6b54bd7f5d828a7eece00 +a3ebc17c867cc9c7c28797f6364f6574b80c7ec5b2d8e1542a6f5db8568c15032f92cfbceefa3fe4ee654f690b0455ee5d38dd84bb8665ffc1ff8c849bdbc4aa0ddfdbbca4eb37972fcbcee8cecc1aae21ec736ef61781716b60247b7551ec4e552d0b59a53cec5964c67cf7988787cedf769eabcc9cd5243f58034d96f0e43d 0101c5ed48231a56ca0ea85eb45de0e395e6df2efd4987a226ae36489dd8b2dfbf7c465c b101c531e1cc5b6d2b5f5fed3c1253c5b1116745ebaea90b6971e001dd2c5a7bf1acffd03b2f9623c3b1fd4224e9e0de +60269efa4d0ffafbbc655f6f00578eadce7fc0a7eb7db923dca49b6f2bf3e13f7f829cc6133e022c3c92143c075ab9ced0531a91e6e79848194ab98bb852f40c84e7aebe71fb8bc0fd1f97ed5bb6bad6783d8dc048df42738e841d978456e055e1b8a781dfecfce2218701c7af77e7894ccac5bfff360aab0b6136b978bc39c4 0019679dc589440b11f82b3716e5b2a2bd42c3b1c83e88a28e304cf5148877faf760b4de b2dc3b721038abaf12aa8cb87fe7a7b907d399adab38055053ce110acd1fd33f53876ee037a865be70f6475f4806ebc3 +59d704d5b1f3a0605f1497f22f71b8f45b26138bc86371f00a4517554e7f6e7fa5d35189fc656ce68bd2cb8510fa3e3c3df815dfdd749b2b6ac997d443f3954c7a927e138b579801ffd035cea90840733e7884ccfe43d8d3a4a26b430673274aae312abe4ac1e1d7c67b73580fedf2d8de46572493c9205ebf0e8b4d75ccc88c 01703c21fb1e09f8947e12fddf166fda6f685221fbd803d75a0ae377a54a1e494e6c5e7b 89f85db75b3e1eb4aafaeecc676b409c80a05dc902cbc563e6ca27d18d73b1248ecd3b2e2a5e5456f2370bf05abf214e +12c8fdba3bc5f68e13f7ff8e7bee876fa68a970afc6924314dae0c2482763ced8d4752cec29ea288d350acd8a06c69289ae41ad345a1b88bcccaac903f2bff39015c289a8ad608606bfd65270a7bcdb5fb10c89bbc2d16dcb91fc9735d66103f6b1f3575622cf4d8209290315b033ee1f79968939410f465a2d37add46af2d59 0071de8eb14cbfb88e61b908990ce08b81e624ef4f2cd9cdf3dd7ca9097d5ffed9ae9a71 a9ccecaade721b16f11dacb427acf99a094eef95bf9994e8f85ee9595edc8c7d1dcb24c818183b006342219b7539d92a +26013a3ddf687bb2f37d9700923906f118d5cba5d8ed5113a0e3e84cff00918125108f74f4b243e351aa5d07fa7c6ece29f5700f23e50286447883d2a058c3258a12e4ed8770cabe627ebea7ef6e8c77811ed7d9a19c53287093e39226236587ddbc63b7ad5e7ad9895c64d1d03ee432d45a067afe27d4cca920ae88a7a68db1 01d156eb15762ed00c4021884adbfc2426e910b18a5bc474268196f4b74e593a8f38702b 91c57ca26fb655de8d96718f0b0e1046197e2a6f57724e497b9930101ffc3322ef7cd2dde0d9dea4e0d693fd328eebc5 +c4dbf70b9a2165e7279122460d05ceb8e43e03fbe2ae7c314007fe2b1d8567cac727a10fba5cbead0ddb167d387da8e8f3d6bc0ad851cc32885809d07a776fd4a95a979fe3833610af89df0f454d9edfabe12495a118fe83add5eabb2acf54ba7ba7c4be20fc77478c0a0f0726c4e60317422a612a234a7567648603b63f1c12 017d6eb1219cab8577168be86b61f372b27ca70fb1f1a767947895c185344e966db17aea a6cb46f9cfbeba5bb81a48496ecc27ce9052136bf41ca5b9d3e57719f6ceb3cbc702eba509e8826e0c35cb788fc0e9da +b1d53b6af1face9b59af11c726b0099111d1adb3666209ba46b1744a528ed0f72be5a1b82423153b896384faebef0362343e2a4599803c08b8513708938aa8a498145fca1c63ba41aff06d1a18aa2a045fce7fcd7e5552a2b98d0df97b6876f06a9cf52a7a40fb737996adda97c3cedf7fe421235ac6951060eba9c0377e72a2 010ede9be6615b3b2a294d67da78127ffbf3a15bdba6f4fd78be7a60415b5d1a097c0cff a30c23959ad8eea711356e7c3e4309057cfc5c2b7f0aad8c2a06aca4559bf008aef943388192a3bb3d4b867cd36afe25 +e78f538b1ac21602b00a09e3db243ef4803b447329c94a1476cd91a88ff790da71421b60092c8a6e55327c7982e7655eb1fd6e40fa9b9fd2f10107dfc585994dfc5bc2143d18794a39f7f69ae679b27dd11ed22040d5e93aa83f71783525a4db0c3fd7b43e57dafd0033d5317680df19c2ecaadcb37ef896c61a758a5e455206 014f237cface123b64e8578ff33f86bfd2a8181b9c81f36b9ca31e2a446f0d91dbbe2249 b6f50ae37d7386532d83349e87e92e2059e41101edc8e811f9ddd340896bb2a40ef97d8fa7ed0e022b842a76357fc572 +8a6ca8ec436d2c706fcbec6486b5665b21c174edee7ebe108211c388b1219a8224179f7438e0bb7d6e41ac4a67337b52d4cd9a069fe6c88960ae20be29c8060efd7c62cb7a9a37136a250e68f253e7f27755df53ce7c570135641ad49b43507e5483e17b919cedffdc0d4913b1d5e0ca0629876c0a551841a0fc2090d2857cce 008dbecb26587cb2ed7df2404e680fcfa5bf8cf6a58e87a350a1600211b3c844ca86daa5 a63c6d2f7e879a131de5de2c5e9942eaf9ea6e9ca1e3b40c1baf6ca202590f95798684d2a975465cf3e19ce4f1da9ded +95bee02b423d2c6e60252da4632f693a2d8f6597b4f9c6e356f670c3a9e4e80063e92facb6421d0325b99dc150464ed2ec1d0bac72a042b35d56d33d2fda686a75d582d4756522218b4ddd25ed45503d90d3d185cba6cf0ac211b22aa4e1318a8316c369186f7130446dafad64f7966f5414f43af37a87127534060a23c6165f 0191badec2d28cbbe62c072c6b57eb5d4644d0c0b3283951bb66096cd15edd43a1bbde53 a2d4f756e869149f7078d64508d1ad586b5555396a2711a801b341ba64e86c4f94bab91092443bd2080ec538eec4e718 +ccd7f7c0e04d1ef9a3c5617d77480bc624beed6582bc28e9e3a369b12144fcd96b735ee41713f4173b64b28c6102d82dcfc7876e06e76fc497d1d238bf6d85bb5feca630bbd0c0f0fa7c0c72e28e9259087698973ac66244bc6e69c04deb22eaeaee7b20da239ab6333576f01349c76f594498620933b8969450ac2bae66db8b 00ff5e3d66eb57fd35ba4472effd6e7a016ca461e39000a7125e99080f6ab6ef4380dd7a 831f6ac4c3701aba850e268522ede4784e494223f18278c03a20bd7a33a899e8b77155a2abad9d91e3be8483ad31e23d +65e9124a2606c8784c9489add2999f4cbe6186395df20838d653b263a207ec46995d2685b55d1874e7ef05a6a3bb5b60a7be6751ad568cef1bcea2debfc494d1e2ece0dc8028c88f1b2c6e4ee26b639c5e81f6448bd25b73ec4608a8e8cf4e0155c29b6f0a62781493b03bb7384c9808529d5f87da6564ae196a365bd282f46f 01f3591eec4a8a3fe6ae6debe230d238a6b73cf3791cb735add1abee64239bb100f15166 a6a76ccc35152bfe3c8a099ab56ebd4511c26effca858b3f71d08f790cfd87e1d6fe29cccb34f47331bc0fc6cb73a1ac +e793c60fc725fd537d5fd38e9b4fb52e268722ae6bde5a058de8d20db301f5e8d8e1ad85532198835a04b76f27ca3c972be5617a55677cffa8219eb64fe53ced242efe1b889990979227dbaaa15ed39d3b6be8c5a3237ebe12bd96f333d947f80048463d3859e34f865d83faf03894c2243a06cc96788ed952e606c2d8948271 005af03cdb45961e7ff35fb0146904ddd6c2bfd3cce814073d3aa56eaa9f13b4f7423926 931d8b55f2d3a74e2aec49024dc1c7660e7d150f1573a9e8c29135299ee847fbc6202b3a6862d24b69ca064975623e80 +a57682d21cebb48190199e9f57493696eae3a59acd22f64d5ef4729decf6c2615b326817a6bc118bb7234bebfc7276dd998838c009a7348e46431574638dadc48538d6048d572e50d9c5974d2049ebe1837dd857bcd1447b1514b62808a4e7a88162ae1bb08a0f6d3db6f25874c6cd0cd4ca6333f1bd57bd192ef67e4616d182 01ec9710ada06e6270720692a06d488ae2ba863b905dd2fc323e7ce68dedacb35fc8c7d8 a503a5e467eba93702c05a1e37c4a30f2a9fcba45eb5a83aea59be71ceeff098fbb60b45d457243c14424b4c12b09db5 +f646e7334e191c2bf0056d3bfd23f03ef7f0777b923f962519a8399d311b8f68414c689ca34b96871fae99eb7ea534fcd83e788e56eeef817cbfe33677283c736b99bf6a626f9515291e842bf99f694e4e8aa7c9911c591a87d5f112b3d96b064594e2b368e6d1bf1a1cd343d54916a66da22c26355266aa2884120fffb8b94d 00668de088c6913640fbefbe6d2c44ab26e481802dbf957044a4957c3c5d0a0fde331501 adc1bb7030ccf6278d2b5a46ac5c4ec303bedf915f064b316bdd28c1d6b0f56d297fa3534df67a2ae299fc7af84e20ab +a2d7e69ea381d3edfde4664c56c4cb140d01cc4425df757975cedc995b89640dc016ab419b137ff25a6a6d64a309b23890439d2ba157262393cf93d15ca1b1ffd19373ef12367f8898aaf56d5544c2f019a4854f69b3d8d320e03135bb7b675e588a5c3fe4b703938fa0f964916501297cee2fd04af767155c7739419f9dbb7b 00e6af57cf47de1e6f07041eb5e1a413fb7ddd82f8c7f7ce957eb28a118004930bec4dbd 8a067a53d148cad23f1f34a87578ba0852e2b576796c461c717c02892f9534616c334635e994b9bb09c469e980725fce +7088f60e9375ec6a42f705f851fc76cc833c4dcbb3352adcce9f59197c1b7121e7aa661c4f8ad9f4ef280af3a2981e90c01291f7d1cf7d3ae2d96b37fe6975e11b7c6c02b8ef044d1470b1a26b9c72e8c4e7b1dd83c8acc9542e2fc7d211b87841dcceea2ab8128d0ff7bb622b60faa4a89ea7008f7d55f8f9de675bc4596fd8 019f9b63fde8c6aa6177f2a38981505d04f8ac62bcc21007b05615d028cfe851ab9cbbc6 a9321434f0d357aa5390a5d6f9c722f2aa5fe6d9fe34eabe3b365f9e023fee7d080372dfb468a619b9a1c0bb604a452d +ffd6044ab991849939e8a29184b4d0ac3e07acb63c7e6b886df9e8254073fa800d5910b9fe34fceb547565a2344eed4de394ce2251ed51ec882ee9207eb7340464c742d9d140fa0964f6bcb1efcc2d13919af4f727953de41b20728ab975c1ae0ce784865f23ed1325c68daa95ed5c932893610179be94f13b9a4149f09833b3 017704c1f436beb52f7ec97192e23e206ec09f9e8986e06bef71467c192bad6f0066b3c2 98c2eab8487d0a44d9293a62a80aade91d6ed3a53f6619d41404e1555bbe2c3b3c90088acc41b232560fcbd99a1d3f94 +c9f81c9ff7d80011fd41f2de97a6c1e6a22cc2da7b2b9e4c50e1354c3e139b44529ac786ce795fc501dcbf11a935d4728a7bba44b4e86b5e5990fed4d3e24fa5ab6f303e1842918f156e00dccebed6897c852207ae5941c630014a41696882066c2b296d39cd8658cb5830eee78e29a00335a99a0ba90722ceca5a2e9a99a2c6 00c7d1ac8faa689698f5c6325a3b3f35e7730bdbddabd0693f2bfdc5c838bd62f84508d4 a475d4b1a5d3e24e672d3fbb9296d8596ee1d3da0418adf8722f2c102a2a671f3182b0d2326cf6b13aa34920a0b45e14 +a60de761eb32490184dc1d29e21fa33889295ca587b994746874c7289eb9c83e9c7bacbb4066c761a06b65ecd78d701bd41f305cd7eb258c630f3febfbb0a367ad16737b146fd793dab23562e8001cd113135b1c981d1ca23eb3be0fe3e24fe3fe1089caf9fd8f4f0d1f90dcc7dbea4a9e2357793b65daf342b8e6d109c6dd10 01a173d158866db0ec665ee632b5fc397893f6a44ee17c348e7452800aadd8ce676e7fdc 8a49fee4869f568b3c0ca189f6c8b07659ed3130c26f981da73f6822cab645333a7d599b559245c8a6eca442e56a4322 +2cd0320cc73120ef13e83c8144b270c9a1f2049a9250ef7ee83ccc7584025140a51e2227a5ebb824deff55b3affcda63ecb1fd3f337c67c08054dc82fdace0c4bb9cef1bea9dd792635f655363d05903cd6b5ed50ee669bcd8157509366cd85aa40d19593265da26e5641590ccf04672a6df52badd4b99964a8643d9687b499d 005523cfacf4ed3b74ebc30f608292e45173001d80cc801f729c5f71fc213b243f041ad5 a4742f9bc7825fae463b29c0d0d09d94cda6c013d9a296c7ad25c3c204f5a8ba7d25255c9338cabf4aaeb9ff2aaa15d1 +a743d8337bdefc4753f937e869a36439da1f8c75e1278c3f6a4a969d93787dac93293818b1cbef5b8636e1a6cb3acaac1e15dbe0841c8001512b689292f3f4805997ae26ff52f7fe1842512a020c448ed01af2a061f3638689446ed5f6bed9fc70726ce4104bc11142de63873fa7039830223e8f152996388417c48e0c1fa81b 009f6bd008c04b8823ccc3ee7d5aca535c211f35e9d9e7cfaec518b98647fbe6d28283de 8e6eff676bbf09ace6716f2d41e46607b4bfc62d0bba63cbf17ac9ec0e6317b3f40ce6c29d3ef2950cbf6f2f2cf90b72 +6a7a3ad614a3a09d2dc5a80204815d0c6471057acc0fa73f3cbbf1801902c3e1cba3c1134a79a8ce61994a94a5afa85ae1a44b2cdcf5153f8625713c872da36aba0afcc5c2f26636dc3f60e04c256a5b023e20e2e7a3f7305bd5b3033fcf05368589f19021f8c9096a88679904b657bbe5b9bee67d6e53d176fce1de9e54c64b 0150d2812505c82584201e93f6e0cb875d29dc7bd99d9c0f98e0ed20128886e67e1f1071 94bf08afd2112b67d56fd2413dc629626ad6e8fd660c918b110d7fdbce707e5bfa9345c001eabe1b7735fad925ffbb5b +65bcd77a3ab345cc99b9c1300755288102a6ccf140bc7d1ad25df246ef01fd57a8614b352033b88cc6ffffe5b38b99ecf03baa365ab5529d6751a3c020d0198561969aade09091434d84ffe13b46df043d0a61e20a08e9c32b646771fea1b29e202d40aae1c7079873c3af494ecf6ef5eda855736c9338b4a5c29a086a8266fa 01b3fb9e1ff70f94bc9d7742ea535ca982215af3df381b5ebdf1db40c7c849a7978ceb98 aad64cff24f1d8cf37471ea491c615f2bcf58caf276e417f74ebcae7e403ff78cca03088d31eb328fd8fd5426d1742c5 +ed1acc360d02ee6c36bbc223d91bc1d2009a3e8f8dfc4c3796cd8555b0d2b46716f4c8058bf34c2d4954e098274ab9c2cbacff46a0578a14e77fe104196cbc6d2753e3bb5422b8b79fd004ac0aa920eea94925c016ece16ed4dea916fd92563ec65692a61b28ee84bef0007120bb1e31bb75b8ecf68406a71af9a18b4edf5320 0147fa46fccf0805d14c1b84ea59bb8b8283d54ca0ceefb29b5585e7141340c55b7232f7 b2f8cf60f979e08fdad3b557e5f71c9beb6a963bdf7bd0f5c442d3528fa2ba1e07869773ff0410fa70682e889016f49a +2debdb95a21d72b69c545988727366a42b819ca6398a82129c5e3772aea93fac0aae9a27b11969ff0ffb9dc0301132ca2452cd863316cf24ae7696422d4dc68e37316161abc146e86f04b72d9a27a350d8545cca245b2be43c33bb822dd813d13e08a718f784845df8a4ef49b02529871ec76bb3fc1ba31089359f2ede73e767 00fae097ea56b35a517be5480802f450eb832b244558d0cc922cd4a5b40b84d02ef11216 83d1e4976169608eaff25c21b85aacd60aed8ea59d314374dcd951e0260228e016ac9f1b9fa679ead00a6252248153aa +e4e0c6c8fc01244abf81e139c961b6a6e2d95de5dff1083e8a48b40e3e5b9ed909152c92b1cf2263179629cdf76ae553b58bb2e9223ce4f9ffb5f170f5f0c5ec97294c34a7529a897e9397f71198cbcd68bb4055cb8cd6b690290761b3b73303f82788379df145358afe28f2997d191d968929b7a4b9a0f6228797dfaa17c613 0026cd72e6ae19b3f4c53493fba1e8082a8df1fb7da6dc111b47a41f713f49b33f618d0c 8b2e7f64af90f4fcae5a2ca3faf853daed872f1f694df26d563d84b435164436243df980062f055d0b857f5b35b0b75b +04710947b7c90855ba4e59107b919d4a1df22b503c5c4c33b286b6b08e451e6fbef8ba40852f9f0ee62c9217abe6156bed46ad6f0e25f70f528f3a73d099338c578bebd6879d810e6e173c2b0af1f7caacb3531ff0e6a7856e4c84db355d110febdb21c683223eb5990ef2038d462ddb7962bc0feea5f850954943d53041f66a 0198e13c7d95bbbb6e226688719639bda988867764ffa9b029018b5547850daecf58fe1f abd4032ef4acca6afd21685354ee2fc0af6161a6d1542d70fcafd0ecaf255df2d1f64fcecc5559031baf9d0fbd30a068 +c62d07bb1ef756b6b2fad355c66b5be086b6dc387b37cbc4a63c841dba3fce65b09d3de8f239e3649382d172f065b78f8a53e0283cf345de06b4ee0b4b7d8611bfce92a7d993b1938419afe817611bc6df3ef74191e7e39ca2339fcb5b5cfee3166d09cd52a1a7d3779722aec328d326a11bbafb6aa417920225ac453146b9b7 019098a39956747de24ded56435fa1e6c30cc2b8088fe9a75f5d07b2f5939c7a60db64ad 8511c9fc088ca992725f1c9182c91a5ef6d6af4a4f08aa7fbde4e3f855cfb023cf4249e7403ea93655dcef68f862f31f +e4d8d49c9bc566261d9134d5e237d9cbd6b67d2619a9bd06b7c9c139e091aa10682cbede114e1d4777d9cd67a16b7d64278e99eed62bbf25ec5a5a8fabcb0a3468b0e73fd02ac6533e04b1110d29da3e34f33eaa228b78341b357a5d892a61beb2168c3bd5e66bffe3f2080a1e246f55a41ebf9d579e188d16991aa060460d6a 01636bd2be121e07ee83ac5e880cfdfca6a56f2b9d0badff003e872348368c7c2cd96b6c 9208e75c8f535fe2a4e07c574839144d5837bd88dd77036a2fa82db099a7579569eab3667c1de7a2251dffb16f42e5e0 +2d1358fdffc14630fbc421b443d3c22ba10ef34f15c6c5bb3c73a9b8714e4c411de69b9cd6628fe2eba5efc4862af66ff916505023e0514f564164b389ea422d0f1beb92adcd65baf43556614eba25e43852ba65af78f62d64b36696519ef8284ef7316ea52c365b99f63a39e6701f81ad520d7445cfc0113c38ecdad4bf5b7a 015e5f555119c19b055b15b0c0d2813068bfc184f864e250b202384f5728bbbda1cb0f5a b9f27f0185ee0a063a497d19632d5da415228d2b74d384a49a4508627a1eea547a09e2a3df5f8cbb2ff7cf77b1dcbb5e +d6336faa5c3e838f4fa58626eb353d4cff9ba8f0aa0e6c3d0d850e8b22f5b0f047afc97767f1afe2040b85d4e401ba688a4da7a0caca7fac450899092c4fea789231ba9b07782010720f45d16d353798867dd7fef4a324520014ad5cb32684ec50cab742b750e05db040ff51140e8d740f6774a059feeb493b10d8ac722f23fa 0190c8f17bdd38669e345440d2c7631d67cee9c6548c4e7b9452377adb9303430efeda0e b4619df876264c290dceb4b341da8c229e0aa3e3594a5672964c979a28cfb5334bafef4401ddcb92a735f24d3cfa124a +07384a3f650bd270b14ca388a441af201b7767a2d47e9033f50cefd3af8257ecb38f5267e141cbbb2ab7327d8fc78cf27198ca3543d39553e178390bf1b921618432ad895e4f8153783a7ac22f4ca3cad4560e64f1ee4a7bcad05df98ea49a3847dc2143b27c243e48be59c869a547988e2205358e8db98b635ca21b745df4d2 00dbbc2a0409ca58a9e39e33b95fdd15080443c1dbdb5874bee991bd1b127047f08ec9f3 85a149c36063b7d8e0dc304ff2e19a51f00ecb2030a15bda86602f9cf75a01561bfc197e03567c3e9f8928a14c9b69f2 +824f26dcb4ce0ca020982814d5c727e629cbeeaa818c49668f8f6d743f0d0ad362b24cbac48027898f386889ca5411d7d1f9afc69493b1d9ae4d7b695c9fa0a30bb59e6be2cbff79231767e96cd8bba349fa2f97955d56f05430ab4ebd007064e3d5add94dfe255b6deff19650883ce9966e1a2affaf84d9540f65c87ab1f936 005495e6c59ca1873f36b756579632fd47f9fb95b64f52589d70f2739aa6a3bf8cf8c198 ac16231e4dcb330db701b48a68f695de9568baacc7a8a59cd5b0817e9f8d28fcd3e9251f4551fa818cde6e3cc91c76b2 +07de1e4bb9be15a710a74806d4447b093bc08ed04392d1bd5abb414f5f4b4d9d43520d0e46fc81c2a97e71086b28e53242449ed37fd7ed1c5772dbabc430fcf82ad20437b38eac15820421e51912325c872894452c3f8a10ddb040b35308e583c155c3707b52df467c4945f4e1071126ed46611a3253c297f5cbca9e27f58448 01724987c9b698519b6c225cf1261b77d0300045e5fd774dcbf13f285e6bd74512cb7edf b60cb8c2b2072c8586509fe97a9dc30e603e0deb386a50c4e167a5acf0735118826656f31804885637df8c2470c6a956 +1edbbbe71057bf7d0bfda922be21a3a4dff57b017ebf6fa99651246cd173bdc9b11eefd048ea599c1f98e907932aa04f64ed0a007831f30daf186c88807400970904d6090b2cf181e0f65f03b4234aceeb420867812562e47f452152bb1ddaaa48487170d06e47c5e9a7c0faa4fe494663d2fec22f7665ceffffc214b21c6b8f 01a5489091cfd51a0970508ee3e8449081ed175928ff8386592c83043a7911bbc2f8778b b54373b365a52d7dff16e8540e707a0538bcd4e0fd3150387ca02f0f650bad6e72a1bf9cc7f9fc725a2dfa0a11d232ca +db5cf1de38a5187af11c1f0f19a36db52f8417de997229e83072fb51a3b7152a3b383e9919c1b8427582e53d4e7e25433d46cdf01492021c237ea0a87d38c71634743115a6b2aba66d3faa8003158340a5078171e0bd55a6e5d8c7fb2631a31c1204e1479bbfe79ac70d5e5823af502922a900576f0088a33e42ec3e26c0089e 01a45ecda0788fbd7cb7a716dcf4c6e83d4148bf63ed58078690ebd238c00329c462590a a1e341527b0c7a50b419fbdece59d4f3633f81f747cc771775b86901c530007c8ad4c4d399750c7f7762ae8aa4f5d085 +4adaa850eec8272d25d76600aacf2cf66e754f6c5efa65c55a2a31b7bc69437d9a7e47c6f51c5da93895a45221f5f92c2e20ee6a95eed3cc7249688261a35d82872284900eb54dd1df6024ec48963ce43e8ed8b8cca8ed22beee8f0aadeae53726cca05443316537840ab824cd1b595f36064e9a19333748d4f4972178e7f5ae 011461776c33f20b176dc8f2b0cb2446a9b69e55b6c7bc7457a7fb4639116b452b79661a 8c1198e6d9366c2ac746ae4f480ab06adf920f35ff0fbbc4459c8a948e736b74a71aca9ffd4ff63f3be809b48300b597 +11d212a99c39fb5e4ca0096bbe6c81ae1490e1b8e07374b4e773bee4fdd24a3c13d653919db663d2c32aa4db140c4ae2d472d4f878946e527ad33b3dc93012d97458f96cb622ddb56f1ce7c2474ad0d5291dc35545de47b7053d137a8e79dabe06757ab53e26eaf751111bd27690e57ffdab5337eb6f81889e9d1b1ac729012f 0025a65f627db2b4d6cf83c5b0c00265b9b63f7656c5e3382139e4992bcdf3cab502844a aa0d888b6c5fd20af4981eec37a3bb8fbf9914a1c3efba213671238a217d351cf7237debb3321b51afebc0229ea74948 +9e4ec74c09528fdf3153a0f6955f20c70915ff524b2e19c991ec4c5b41ea9185e3e876a02ed6f27c9b3479dba951bee8680c4c99be1a626808114408856994be7444ccbd5ef9859fa479b1050bb836034e20c531b4d618f5843fe1d4b613a731895b489a2363f3f5397d5ff964cf037e9b11e3ff5e1c3d403e5a46b8387c1241 0173b28fc29f10245221a907778708b3ee62e0480aa9051d4c3eb4e8d552e6aad5509943 954eccbe1728f9dd090c8946d98a619a05fd883282e16c969ed5c19534e7683fda6de9a350f5a47622c2ee93ec7cfb3d +5fe8253d2134c434cb0866796013722e82184638b024a5a30938039929ccd8415c71f71f239c5c5a81f7a9cb493dde209f189bcf766c17c6d9589cd0c7de7f07ff9f24d2320669b589d084f8a8ea71127b9760b7355b162616afb34bcdcd416f1a062035102e29b70069b2b4dbf70179b8d60bc2ee5a455efd40194533bf560a 00624616adcd45e1fdc6cfeab2b17230d73d91fe0b39f4664f3c6891554f9b8e238257f7 85ecc789b4cf7995fd519aeedf29a26b1fc01e939f56787c24443ebd7b16a3e7aaffbb8db450ce80e6c2b03bd680a911 +db49891838fe23f0530abd4a4fbba5ea970afa5747f6a0a10d2cf4d841581ea2178705c1203f00cafec91d0a72d25448072c9cf7d7ca5580b39f8589ec63128faa95cb0689574a6bebd515049a1eb9699922cde0366b5cd58aa8f3d3e847706896f7e1cac667fbfe94b2eca9e7be79a810806ca4bf53f219bb30532ca2254c11 0199757ffaa2c59e198d66824eaad37cc42d49b2e241b6a60382d05e425e800eaaf32470 a7beb0fbaf1eb2bba34c3fe589a2cec11f0e16960fb0a8e206dcb7caf8640e1e830a46edee3e62eadeaf63f983ba1468 +29d385d09c1142a7c181fe4b6e6132e414c15aa8605b44208c0399464613b966edcc2d46cf203a3f85d943d8eae658695dac74366224a0d0348083bec0106f5eb8809ae8d07f792fdd7c48fb1a25d5ef3bb9acd40b20c61c821024a9acb2ede321bd2d0dda849c22d76f421cbd8d51565d3c4266f666455ca1c0c3777aa44107 006e51381dcf21050aef2e9b97e35303cf3bd91956854ecf9b6b9827871d2efbe8201c5e b0da03e6f31c53fb0c4fd690c7f83c75dab196468c9667bfec154f4114b48aa86bfebaae47e20c0774cc297a93a4e541 +774c1cb8fb4f69ecfb5c7857d46415568d88f1f9f05a4bf64a1e1ff6d64aec16e1d09292010d1f067c68dddbcde06ea49be2ad3838053f0b9c0c2383edc451ef0188565118e7b3c66a4fa372b96633dc8a753106283b02d0322df273d58cc9bd061ec219f1e1a9c8ca1400e5e39c1b2c254273377dc98a1a2c44e5c2a5b89167 0018adcc22cb9a2db64bad3d60f1608c353e091637b948914115ebd43679904f955c8732 939d9bdce40a9876e3544b0bc2f3886a58236cf365603f4f73755ece9f22f3e74f52738ab591341da25a327af6ed28c7 +c406aa4295f85c854b4db2de5a7a2defae53a319866921a3673af5b48c85ef22f6eb4cef892c790d8e64530fc20c729b2821b5f5e515560b1ac764106560c3a6a05657e34cd6deadfe2884bd288cef4ca92e1f25adde7d68a30fb0a1b3678156ced62e466718e68e9d67099ad82613b8d06bdda1a7b867c2455422818ae9eeac 01898276f159c10d92d8d4b6ae214d68c72792a4b5f1f79936ca3c063dc8d9a88be439e2 ace4d23c01e9db2c9be28b224312814068dfc17ab96dbead12f789016174bd56e4b18b85b0a6bb73ca4448d76a05afaf +cb2809152f8258660933472c06ddcdb65f6d5221fa29d5b0efec9c2a7914dbbf9ce0a468ce146fb333d26f510a87a6bb01bf8816756a1b5df81c5f65360957cae84ba038e37e88777580e91c34e2f5aef4fb55af7b81ad28aeba05e0b1c64a15381a6719fd2c16e38a441516e1b394952d984baf9e051b1dc1bda2e12f8ba5b8 012ff37c808c3cc029a9cfbb67a5ed21f3bf362b49270d4ed0f1e38fad25ebd79f112a50 b3685a5f6f06a31b14c607e10783739eedaf3baf8f6bf872716a4ee8be01e8dda3134576cc8d9bf4c4e395a60f102b6d +e060af96d4a7fe512bbf26be9a27bb6a8ff37547d4a7bbbfa710db24cffcfc760dac120f89f642880db2df6307f9ea5441d5932d49762d182b29d8e7fb067a61ab0df622f75cecc917e27d0326085d34581e052c85f50a37713e27518aed7c4434f86970e00a0a4b8503989e72614131b7164c1bdc82d2b6aeac0787f9838476 002b8c1fef9c6def32b5f4127273ce384b6add4aecec957c1662f52334f5ee97f49852d4 9980ee367abdeb1f0655f0199aae35cb886efed740847fdf8cb84cbbd66f71743b93d6d0f606612ab2fb10458fd1196c +d235c31f0a82957a087c7597673970aa39321d4c2640685a03df8388b5eae4825d1fee29926f416d5e62a2e9ca1ea7cefffd31607e750fa9675983608e0f8dc895371b190574d065c5c0c23ffdaf49e65362914363a3fffbc2c1bb487cbd4f69ec22dda5c7dc3bbab805c81faa85787cc176bc0e5703924f395d8c9e7e7701e2 00afb1c45e9a9f02942b8e04da4b815498454dde6643de186625a98b3c1c6993abc8bba4 ae05ede274fa9a246ee026ce2cb9f8840cf480e1da0d7f0248915815dbc5008ca57e3e887161d5f5a31190a9cb674999 +1a2559777a5fd8f269048feda82c4d9fceca95803f84a813789d6ed070422240e443789c5231d63d5268ddebc060dfb99c4eff2ff115d2984d8bbc5c05314562ea6864fd543e7e0a3b8572c017d8ae3563027d79bbe164d40a5bab354720e45094b9b26391ceb55339592fc2f10b97dc9c2649f7227648f5cd2fc46d78d31c0e 00ff537d73a4da0ae3a4894016b71dccef3bc886f3d24a5abb7dd96cf8fdcbdf0fdc5e51 a90119717d89dba473af07461a84042f1c5eed93f87e17b490aa25bb09973a5a7235733be188b9e08049de04357444aa +658c0d3f764bbc952fa55a258bac16a5bb5184bfa76cee06baf9ee6b9ac3f116e08bb2406b1dd4be487b057f3b29c2043ebc33019b2017c4deccb86f50ff15fc9248ea5fb64261120b1960525aec3cc18827c23291722c5add8a3761ff8516c61956c62b8cbb13f3d92bf3eb45a70704c01bb3625d21c38ffa83a6db086ee968 016000d2e879906d1040b32eb6ba3caff700e5565871ac75f10c5c15b509964bbe5e14c7 adc106ee6c6f4ad365ebc4f2196076943b716425e88d98e7ca42bbb3a4781136c2f96cff7f94163e778a08e09aa463e9 +4f10001e3517c2c1f973b555f4827681e096d860c4db08f1f4aef8000c9c24bebe59f8bf3d7d3cac959a1a5477bb0ea43f2e746b5d14ed48a58ef35484b0ac786d2fec669f945e846ad73e6b77a9e47012a951b398941566330d89125eb3c1fbb2f06adb951ff5f047d102fdf28b5cadb4a3e1a10412eb3474d2ed5c3fce78f5 0019528d505bf0584628d0214bc857150a929d3f59619bf8f3acab545fff0977c9bcdc97 94cfb29925dcf93f8e85c2974f32ec99c231f73550a2e80c7ff3e6c1c6087f64468e3bbba7bcd74700c5672c9df55aec +c43ec3c3232cae59bdea7cfaf18a4672035dbd2b8b6b1b44ede376b36cc2d8baeb921e416aa177f5977da8bf1d713509e5251278b6622790056271715cd5feac58bee5baf50b216e8eb886279c5a384cdb696470275b7487fe9ac4c506706f6b0f9809d1ccb102546a4297d2017c2a8df9f02f30d3d1bd9aebf6a92a02e0d202 0067795ce117bc0a389397fc22a01cfd9422cfbfb5aa44131938a8c45e48e1d5a718539c 90bc65de9b7057abf16a1cbfb7e7d70628d0b02bac89a8eb372e5eee10ce899408aa44fc082cdc6bd55897a410e700db +9b7d675a3d2cdeb280ea28289b5fc2a3ef6b535ebee8ad242fb031e2e1f364e8ee806568b2f8627c5a5b4f51f4f65c71acdc1152c08b9211b81907b551e0ff47f5a6aca45dcfa06f09bf195d19d7b165b52111b601fbd97b192f62465f8ba20773b1599c8041e91448eac7a5763ca0628f40768324c5304e1119ca6a1fdb0778 019269dbfe4184249952a651a507584746c5b62c64cb3b17e0158aaf4d086a4afb0330c1 b5ec8666206e3049ecfa7fee7278096dd67db107c6dfbd27277cc9b3aeb3b021b2fdc568b8438e9566e0ee08600458ab +f4a08daf8f66ce57a986f14b918099bcadcc4308bcde7c169ce8536a40d94a928cfc0968180a2c2a242c59df73ff79a03687998c421cf9a0e661630378779a4744ae2a6cd24ff61d7fcd6c11a4c8bcaf358075e96f864df0998ee98ee393b37bb38747b70bb7a208740959b45174a60153ee566e0f62528e9a5e4466186fa650 003835814de0d6441cd80a44e40350cc8bd62ffcc81e939a4410bb9c9259e30463c453b5 a05a968d22c78c0f2f0a9559924173007a25494308e23d9a63644939ef60eda6e6fa641dd3fc5daaa3de022ca17cd5f8 +864647405c70939fdb4c026bcad53218ba1d438d82c9138f0f0ecac815dbfb242307cca52c84826cf6556c51082a23f14252dfaea43ba229f7493db2bf8ae9cdb0228dab9e25cf385b504b92cca94f813acceaa1f18de851b8936c4dfe9e4e17002f02dded6b4c231ea5e614ab46fcdd637b8c6193e8d0c2df1b3d883b97e1e8 00aee83dbed3b703cb6e60d51e373eb20e298ac005fa6a572d02fa1e6da0345558ad2a46 adef1d177fe838193671058d6f00a619f43207dd634fba60df77044140588ea2776e838c2596c46cfd38804086868820 +c87c8f3ad5c28a027b28ae5021dbe8d425f74181d519451f1fead7a1f9dd102fa6785b147b610610cb59bfa91fa363bb79ea602a7d7e1439f874c5dce748e5c320560c2d9676f3a948754c72b6db249478b7e19c9829ab4de2e344535d3e0b7c20c272f82556a280ef491524b255c4fafb9c8ecb87b0149ddd9d7bf6159e3337 017b65c66514019ff935e9d571a4e68e9ee4463b7b9a754b93f4f7741693f4399879fa8a a139d36d3b17f7b99fe3144f929b75866d37625c597e466322557f447054528e99c7a972588c6a78e4e6d0cfc72ab101 +ac7da7611e2ade20aad64b418a16e02e79ab4894d758550210eb10013a9b5533132be701f8843c840807c4167c38d21dff168d3baa65d5bcf285b73dcbb75819f8d7a20a849de335e19bae2aab2ca560b93d340731f291599a5b28afd7737460d291105cbba6d0290e836f6f6c1113d1b2faf90ac5de7c64e25206d79380a4ed 017d2071f39ba35515a8ec977ddd36ca15983e15bcda626f15af61d87d58114f4c80a8be 942946fe78ce49ec1b872b1bbfe55f23d623405499e2cf508f0b38edd221b0386b40ab043d3acdb8dcf6ec50c8d2d486 +5757c472fa2f81430dd920f39b61066a28c870b80e6c96f822f8f19b398c3574d159cc22120454dcd7e97be8211916e4bc8db365b2dbb99a6e597d06e6645046a0abdccbd06741e9c0eedf33cb78d78a540c2a390719acc498331e694e6b0118cf4f787b51c7b7237458a6149d6dbd0a08bae8097e919f970fde920485e9a0ac 011504659e12235855fe55220287a101e511d39a627f8a0d414446385d4a88f31507fe74 8d4507b22d121955e26e401c384673175842ae2570fe58d14af306dc82bfb648d58ca56f89fca573e783949ff1b4e635 +e350383d04af0f4081bf09b95d1d53040e7acc64e56b13b653df31dd119617b800e0cdfeb935dfa5d94f1d7814688d8ce41021810958759cec76560e1e5c0581456acd1a020165849b2203f1c11d318d816697f36a86b59f160faeac7dba71682d3c031d0d547725ef69cbaa28345512e38b75ab011911d8924b2d17a857a96b 016e4cbabb03215767249ba2a608708b78d7387be9e77f5efd2462467fa05e8dcde2c036 97d065468b3692fa1f5f733540b71108235b01262c26e6bba75f4162e72fec3362e1c5884a38dca02e4239003a3f63a8 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K283_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K283_blst new file mode 100644 index 000000000000..ebcc2e430b0e --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K283_blst @@ -0,0 +1,60 @@ +ef90f85fbda05e693006e4c64e1dac56223becaf0890f73b5274e6e289a5a1de2c141b825c24d595b3fd18ca855b5c1aa60dac6b5356275b11be670692cdbe5f282f93ac7b2e410a96cb9e9f80defcde98f3449f99e192bfd62040421a0ab8f99acb85369f25e5efbf81439efa8a5e1d9cf781355a0f47b037b09fe4086389a0 01e846c830a8ec04e8572d1a9d2df044ab47352fb346f67403a3bf87243871b164511c53 a752a9712667618e3c0c59b215e394c78c2b95d9eda9ab69076d957336ad4dc0099cf6c0605a0b87664770946c5f9d9d +a3ebc17c867cc9c7c28797f6364f6574b80c7ec5b2d8e1542a6f5db8568c15032f92cfbceefa3fe4ee654f690b0455ee5d38dd84bb8665ffc1ff8c849bdbc4aa0ddfdbbca4eb37972fcbcee8cecc1aae21ec736ef61781716b60247b7551ec4e552d0b59a53cec5964c67cf7988787cedf769eabcc9cd5243f58034d96f0e43d 0101c5ed48231a56ca0ea85eb45de0e395e6df2efd4987a226ae36489dd8b2dfbf7c465c 8a46ef94a379c912fef7bfc590fadf8c482fa5b5edd34fb462d94c3b24c9653e1ceb088d8f5ea04afc204397461b1c1f +60269efa4d0ffafbbc655f6f00578eadce7fc0a7eb7db923dca49b6f2bf3e13f7f829cc6133e022c3c92143c075ab9ced0531a91e6e79848194ab98bb852f40c84e7aebe71fb8bc0fd1f97ed5bb6bad6783d8dc048df42738e841d978456e055e1b8a781dfecfce2218701c7af77e7894ccac5bfff360aab0b6136b978bc39c4 0019679dc589440b11f82b3716e5b2a2bd42c3b1c83e88a28e304cf5148877faf760b4de 995fd97a740a8cdd132d0b98c1653a846ea476610de3f66363087e8ae3e47bd50dcf702e877b987caaf89c9c348264af +59d704d5b1f3a0605f1497f22f71b8f45b26138bc86371f00a4517554e7f6e7fa5d35189fc656ce68bd2cb8510fa3e3c3df815dfdd749b2b6ac997d443f3954c7a927e138b579801ffd035cea90840733e7884ccfe43d8d3a4a26b430673274aae312abe4ac1e1d7c67b73580fedf2d8de46572493c9205ebf0e8b4d75ccc88c 01703c21fb1e09f8947e12fddf166fda6f685221fbd803d75a0ae377a54a1e494e6c5e7b aa9bb49dee70b72dae42f03988e01430ec9173a80a4a485a3da9a07486ade7d081eca6bd15a2328e5869d4f00c00a54a +12c8fdba3bc5f68e13f7ff8e7bee876fa68a970afc6924314dae0c2482763ced8d4752cec29ea288d350acd8a06c69289ae41ad345a1b88bcccaac903f2bff39015c289a8ad608606bfd65270a7bcdb5fb10c89bbc2d16dcb91fc9735d66103f6b1f3575622cf4d8209290315b033ee1f79968939410f465a2d37add46af2d59 0071de8eb14cbfb88e61b908990ce08b81e624ef4f2cd9cdf3dd7ca9097d5ffed9ae9a71 837e6f4434107f9301382e91d69c8d07217322a0c23688f5e347b4bd4387b2fca51c2bdd660eac01ff66cd78fb44ffbb +26013a3ddf687bb2f37d9700923906f118d5cba5d8ed5113a0e3e84cff00918125108f74f4b243e351aa5d07fa7c6ece29f5700f23e50286447883d2a058c3258a12e4ed8770cabe627ebea7ef6e8c77811ed7d9a19c53287093e39226236587ddbc63b7ad5e7ad9895c64d1d03ee432d45a067afe27d4cca920ae88a7a68db1 01d156eb15762ed00c4021884adbfc2426e910b18a5bc474268196f4b74e593a8f38702b 8244d2ac18ad2e927e33004d83c23488afd066d72e085b649a47b47bddc33ded1cf6e76c204d01a39877a4730b89af05 +c4dbf70b9a2165e7279122460d05ceb8e43e03fbe2ae7c314007fe2b1d8567cac727a10fba5cbead0ddb167d387da8e8f3d6bc0ad851cc32885809d07a776fd4a95a979fe3833610af89df0f454d9edfabe12495a118fe83add5eabb2acf54ba7ba7c4be20fc77478c0a0f0726c4e60317422a612a234a7567648603b63f1c12 017d6eb1219cab8577168be86b61f372b27ca70fb1f1a767947895c185344e966db17aea 842beac4909ff220d6440a781da8eee970dd85cfe618add4ad61fdbd5a18223b36d1eea464eb83c8f4912f5f23d30fef +b1d53b6af1face9b59af11c726b0099111d1adb3666209ba46b1744a528ed0f72be5a1b82423153b896384faebef0362343e2a4599803c08b8513708938aa8a498145fca1c63ba41aff06d1a18aa2a045fce7fcd7e5552a2b98d0df97b6876f06a9cf52a7a40fb737996adda97c3cedf7fe421235ac6951060eba9c0377e72a2 010ede9be6615b3b2a294d67da78127ffbf3a15bdba6f4fd78be7a60415b5d1a097c0cff b6e9de3a65b6fad49413169719c47ea459baf60fac58724d61b7b71fbe10bb6bf04a0802287a036ba0d592b4378a2de4 +e78f538b1ac21602b00a09e3db243ef4803b447329c94a1476cd91a88ff790da71421b60092c8a6e55327c7982e7655eb1fd6e40fa9b9fd2f10107dfc585994dfc5bc2143d18794a39f7f69ae679b27dd11ed22040d5e93aa83f71783525a4db0c3fd7b43e57dafd0033d5317680df19c2ecaadcb37ef896c61a758a5e455206 014f237cface123b64e8578ff33f86bfd2a8181b9c81f36b9ca31e2a446f0d91dbbe2249 ae59f0789c6313f2015e6029ede785a027ac0836aa0dab36e424136638903fd98020962f5eedc6512a6b1f9392ad78c9 +8a6ca8ec436d2c706fcbec6486b5665b21c174edee7ebe108211c388b1219a8224179f7438e0bb7d6e41ac4a67337b52d4cd9a069fe6c88960ae20be29c8060efd7c62cb7a9a37136a250e68f253e7f27755df53ce7c570135641ad49b43507e5483e17b919cedffdc0d4913b1d5e0ca0629876c0a551841a0fc2090d2857cce 008dbecb26587cb2ed7df2404e680fcfa5bf8cf6a58e87a350a1600211b3c844ca86daa5 b1cc1bf33cf6f2946fbda9c018883f9183dc17428483cc5a8746f5c18fb358c51476b547897e9e4f937e19ec7b3e2e23 +95bee02b423d2c6e60252da4632f693a2d8f6597b4f9c6e356f670c3a9e4e80063e92facb6421d0325b99dc150464ed2ec1d0bac72a042b35d56d33d2fda686a75d582d4756522218b4ddd25ed45503d90d3d185cba6cf0ac211b22aa4e1318a8316c369186f7130446dafad64f7966f5414f43af37a87127534060a23c6165f 0191badec2d28cbbe62c072c6b57eb5d4644d0c0b3283951bb66096cd15edd43a1bbde53 b253bf51250df5b6cd72cd8cae56b4916966d8de0b2f84b0c11c372ddd467ac7506100a20a475c7fb99d55ea9ae96d39 +ccd7f7c0e04d1ef9a3c5617d77480bc624beed6582bc28e9e3a369b12144fcd96b735ee41713f4173b64b28c6102d82dcfc7876e06e76fc497d1d238bf6d85bb5feca630bbd0c0f0fa7c0c72e28e9259087698973ac66244bc6e69c04deb22eaeaee7b20da239ab6333576f01349c76f594498620933b8969450ac2bae66db8b 00ff5e3d66eb57fd35ba4472effd6e7a016ca461e39000a7125e99080f6ab6ef4380dd7a 8733c5478b97717785a18e59770bb5d0955d4b71374489cfe9ec7822065f2b009af79bbad0a7ade56f22bad607152e50 +65e9124a2606c8784c9489add2999f4cbe6186395df20838d653b263a207ec46995d2685b55d1874e7ef05a6a3bb5b60a7be6751ad568cef1bcea2debfc494d1e2ece0dc8028c88f1b2c6e4ee26b639c5e81f6448bd25b73ec4608a8e8cf4e0155c29b6f0a62781493b03bb7384c9808529d5f87da6564ae196a365bd282f46f 01f3591eec4a8a3fe6ae6debe230d238a6b73cf3791cb735add1abee64239bb100f15166 9024f96357a1f867f1cf2b12ad2276f4f193a264d9b1f85692b508c89c33caba5dd30e13a4e1e43fefc1045e13808734 +e793c60fc725fd537d5fd38e9b4fb52e268722ae6bde5a058de8d20db301f5e8d8e1ad85532198835a04b76f27ca3c972be5617a55677cffa8219eb64fe53ced242efe1b889990979227dbaaa15ed39d3b6be8c5a3237ebe12bd96f333d947f80048463d3859e34f865d83faf03894c2243a06cc96788ed952e606c2d8948271 005af03cdb45961e7ff35fb0146904ddd6c2bfd3cce814073d3aa56eaa9f13b4f7423926 8571eadc7c2654d5ed9bfa620840cdf30326c5ee74f6c7d71c989fb5c5eeb411f40574fcaf89094c5173b2a3f9a31866 +a57682d21cebb48190199e9f57493696eae3a59acd22f64d5ef4729decf6c2615b326817a6bc118bb7234bebfc7276dd998838c009a7348e46431574638dadc48538d6048d572e50d9c5974d2049ebe1837dd857bcd1447b1514b62808a4e7a88162ae1bb08a0f6d3db6f25874c6cd0cd4ca6333f1bd57bd192ef67e4616d182 01ec9710ada06e6270720692a06d488ae2ba863b905dd2fc323e7ce68dedacb35fc8c7d8 b68e22a74781345d7041c8f53abeb57613dd5e45414c44da565bf098bb312456f2ab43feaaffd135d55dd2d898a2bc87 +f646e7334e191c2bf0056d3bfd23f03ef7f0777b923f962519a8399d311b8f68414c689ca34b96871fae99eb7ea534fcd83e788e56eeef817cbfe33677283c736b99bf6a626f9515291e842bf99f694e4e8aa7c9911c591a87d5f112b3d96b064594e2b368e6d1bf1a1cd343d54916a66da22c26355266aa2884120fffb8b94d 00668de088c6913640fbefbe6d2c44ab26e481802dbf957044a4957c3c5d0a0fde331501 b6cb47ab11ec89a834c056eba498cdd990fa82404f78788eb8b7f43940f7df4b734edd5bf833aad1daf6e0035cacd9b2 +a2d7e69ea381d3edfde4664c56c4cb140d01cc4425df757975cedc995b89640dc016ab419b137ff25a6a6d64a309b23890439d2ba157262393cf93d15ca1b1ffd19373ef12367f8898aaf56d5544c2f019a4854f69b3d8d320e03135bb7b675e588a5c3fe4b703938fa0f964916501297cee2fd04af767155c7739419f9dbb7b 00e6af57cf47de1e6f07041eb5e1a413fb7ddd82f8c7f7ce957eb28a118004930bec4dbd 8cdad1695ff04c05b53ea402ef58990e94debb878f9d03b1df6fa6078e8605e276ea737e2dd3fb95b40185665a302fca +7088f60e9375ec6a42f705f851fc76cc833c4dcbb3352adcce9f59197c1b7121e7aa661c4f8ad9f4ef280af3a2981e90c01291f7d1cf7d3ae2d96b37fe6975e11b7c6c02b8ef044d1470b1a26b9c72e8c4e7b1dd83c8acc9542e2fc7d211b87841dcceea2ab8128d0ff7bb622b60faa4a89ea7008f7d55f8f9de675bc4596fd8 019f9b63fde8c6aa6177f2a38981505d04f8ac62bcc21007b05615d028cfe851ab9cbbc6 a32bb53e9127d7ba86a674d8059804eab47dc5435d9e07790f63a9575201bb6f031825581a3e60557fb0c1db0a3867f5 +ffd6044ab991849939e8a29184b4d0ac3e07acb63c7e6b886df9e8254073fa800d5910b9fe34fceb547565a2344eed4de394ce2251ed51ec882ee9207eb7340464c742d9d140fa0964f6bcb1efcc2d13919af4f727953de41b20728ab975c1ae0ce784865f23ed1325c68daa95ed5c932893610179be94f13b9a4149f09833b3 017704c1f436beb52f7ec97192e23e206ec09f9e8986e06bef71467c192bad6f0066b3c2 a73c6d11b2e70b96f9e393b93fb712df5beb554516109a3913d0ef71af2345ed34bf4f345941487989d8e87bf4232a69 +c9f81c9ff7d80011fd41f2de97a6c1e6a22cc2da7b2b9e4c50e1354c3e139b44529ac786ce795fc501dcbf11a935d4728a7bba44b4e86b5e5990fed4d3e24fa5ab6f303e1842918f156e00dccebed6897c852207ae5941c630014a41696882066c2b296d39cd8658cb5830eee78e29a00335a99a0ba90722ceca5a2e9a99a2c6 00c7d1ac8faa689698f5c6325a3b3f35e7730bdbddabd0693f2bfdc5c838bd62f84508d4 aa92d06e0486b8e47a2f4969d4e1c9fc2e7d1ecceeae54d6a420d51150d18a27c2881c868e81d908cc5c9ebc997e87bd +a60de761eb32490184dc1d29e21fa33889295ca587b994746874c7289eb9c83e9c7bacbb4066c761a06b65ecd78d701bd41f305cd7eb258c630f3febfbb0a367ad16737b146fd793dab23562e8001cd113135b1c981d1ca23eb3be0fe3e24fe3fe1089caf9fd8f4f0d1f90dcc7dbea4a9e2357793b65daf342b8e6d109c6dd10 01a173d158866db0ec665ee632b5fc397893f6a44ee17c348e7452800aadd8ce676e7fdc 8ebff6d6d2fab73fa9445ad55b52309af72e6a52e2ae9bb6d00e09e45910f7ca8e7e30f5bea830bac084ed0027c80545 +2cd0320cc73120ef13e83c8144b270c9a1f2049a9250ef7ee83ccc7584025140a51e2227a5ebb824deff55b3affcda63ecb1fd3f337c67c08054dc82fdace0c4bb9cef1bea9dd792635f655363d05903cd6b5ed50ee669bcd8157509366cd85aa40d19593265da26e5641590ccf04672a6df52badd4b99964a8643d9687b499d 005523cfacf4ed3b74ebc30f608292e45173001d80cc801f729c5f71fc213b243f041ad5 8132767a878872ed9a8e86eaa504a304d68775f8a9fa01bbf4d0f6a7bc2d80526627c4276852e1430b39375c01278a99 +a743d8337bdefc4753f937e869a36439da1f8c75e1278c3f6a4a969d93787dac93293818b1cbef5b8636e1a6cb3acaac1e15dbe0841c8001512b689292f3f4805997ae26ff52f7fe1842512a020c448ed01af2a061f3638689446ed5f6bed9fc70726ce4104bc11142de63873fa7039830223e8f152996388417c48e0c1fa81b 009f6bd008c04b8823ccc3ee7d5aca535c211f35e9d9e7cfaec518b98647fbe6d28283de a0c2b11211e032f5faccaa19e51d5b3e8af7388b461d1a972219c1613177ab42429a444f5d359e7562acd89f89cd4c99 +6a7a3ad614a3a09d2dc5a80204815d0c6471057acc0fa73f3cbbf1801902c3e1cba3c1134a79a8ce61994a94a5afa85ae1a44b2cdcf5153f8625713c872da36aba0afcc5c2f26636dc3f60e04c256a5b023e20e2e7a3f7305bd5b3033fcf05368589f19021f8c9096a88679904b657bbe5b9bee67d6e53d176fce1de9e54c64b 0150d2812505c82584201e93f6e0cb875d29dc7bd99d9c0f98e0ed20128886e67e1f1071 aa1ba3e034c2b467b41b69c24e28365e4ededc8de5ee990936c9a68679f9f78ace74dd99b97ad5acd4eca5ee862077e1 +65bcd77a3ab345cc99b9c1300755288102a6ccf140bc7d1ad25df246ef01fd57a8614b352033b88cc6ffffe5b38b99ecf03baa365ab5529d6751a3c020d0198561969aade09091434d84ffe13b46df043d0a61e20a08e9c32b646771fea1b29e202d40aae1c7079873c3af494ecf6ef5eda855736c9338b4a5c29a086a8266fa 01b3fb9e1ff70f94bc9d7742ea535ca982215af3df381b5ebdf1db40c7c849a7978ceb98 84d2ab4521464dac0050ccb14160fd28108da05c310ceb69cb479eda5e1f086defe56df7d475b054c376673e9d64f3f8 +ed1acc360d02ee6c36bbc223d91bc1d2009a3e8f8dfc4c3796cd8555b0d2b46716f4c8058bf34c2d4954e098274ab9c2cbacff46a0578a14e77fe104196cbc6d2753e3bb5422b8b79fd004ac0aa920eea94925c016ece16ed4dea916fd92563ec65692a61b28ee84bef0007120bb1e31bb75b8ecf68406a71af9a18b4edf5320 0147fa46fccf0805d14c1b84ea59bb8b8283d54ca0ceefb29b5585e7141340c55b7232f7 85e6732a32bc8d5ccec78e0ca11d39d1f9555a96f3d9d439548e81a7dc534cc6aa57c18959c4d6d75198fb2db66dee77 +2debdb95a21d72b69c545988727366a42b819ca6398a82129c5e3772aea93fac0aae9a27b11969ff0ffb9dc0301132ca2452cd863316cf24ae7696422d4dc68e37316161abc146e86f04b72d9a27a350d8545cca245b2be43c33bb822dd813d13e08a718f784845df8a4ef49b02529871ec76bb3fc1ba31089359f2ede73e767 00fae097ea56b35a517be5480802f450eb832b244558d0cc922cd4a5b40b84d02ef11216 811f7977ee14ae2f4f8db729ec37e7f8a7fb682c8774b3eb2a790947dcf302d14241e510c5e4bc91b238331dbd446ef2 +e4e0c6c8fc01244abf81e139c961b6a6e2d95de5dff1083e8a48b40e3e5b9ed909152c92b1cf2263179629cdf76ae553b58bb2e9223ce4f9ffb5f170f5f0c5ec97294c34a7529a897e9397f71198cbcd68bb4055cb8cd6b690290761b3b73303f82788379df145358afe28f2997d191d968929b7a4b9a0f6228797dfaa17c613 0026cd72e6ae19b3f4c53493fba1e8082a8df1fb7da6dc111b47a41f713f49b33f618d0c 93ccccf5aa04fb46ec4f0f4f4b218b9fba9a802cb4e4c18429e28b2e7c9f9b6debc8e73e2fda914e47d37d86b612f0fc +04710947b7c90855ba4e59107b919d4a1df22b503c5c4c33b286b6b08e451e6fbef8ba40852f9f0ee62c9217abe6156bed46ad6f0e25f70f528f3a73d099338c578bebd6879d810e6e173c2b0af1f7caacb3531ff0e6a7856e4c84db355d110febdb21c683223eb5990ef2038d462ddb7962bc0feea5f850954943d53041f66a 0198e13c7d95bbbb6e226688719639bda988867764ffa9b029018b5547850daecf58fe1f b89231383f4b975ed5bf2b762b0f73c31c419c5c45cfee63342194fc47e03532383ec22f9b4f7ce732dc06cb6ab599c1 +c62d07bb1ef756b6b2fad355c66b5be086b6dc387b37cbc4a63c841dba3fce65b09d3de8f239e3649382d172f065b78f8a53e0283cf345de06b4ee0b4b7d8611bfce92a7d993b1938419afe817611bc6df3ef74191e7e39ca2339fcb5b5cfee3166d09cd52a1a7d3779722aec328d326a11bbafb6aa417920225ac453146b9b7 019098a39956747de24ded56435fa1e6c30cc2b8088fe9a75f5d07b2f5939c7a60db64ad b8059c408f88de50881d18f0ed52290d4ebc1ed4b37274d97366aeac9667abed6d99fcf0a56fdd161713d04ba5ad3588 +e4d8d49c9bc566261d9134d5e237d9cbd6b67d2619a9bd06b7c9c139e091aa10682cbede114e1d4777d9cd67a16b7d64278e99eed62bbf25ec5a5a8fabcb0a3468b0e73fd02ac6533e04b1110d29da3e34f33eaa228b78341b357a5d892a61beb2168c3bd5e66bffe3f2080a1e246f55a41ebf9d579e188d16991aa060460d6a 01636bd2be121e07ee83ac5e880cfdfca6a56f2b9d0badff003e872348368c7c2cd96b6c b1f2c8a42f9dafb17b2443ab9a52607cc07d00f972af437ecff145bc902f05b0892385a81595e5d4f875e1c9babb8623 +2d1358fdffc14630fbc421b443d3c22ba10ef34f15c6c5bb3c73a9b8714e4c411de69b9cd6628fe2eba5efc4862af66ff916505023e0514f564164b389ea422d0f1beb92adcd65baf43556614eba25e43852ba65af78f62d64b36696519ef8284ef7316ea52c365b99f63a39e6701f81ad520d7445cfc0113c38ecdad4bf5b7a 015e5f555119c19b055b15b0c0d2813068bfc184f864e250b202384f5728bbbda1cb0f5a a84b8bb7706a2d1678d018feb0923f95a21fb332ca27ad65ab4a23729e0ce4e0cb2a7f472ea6eef33c9642f193c505ba +d6336faa5c3e838f4fa58626eb353d4cff9ba8f0aa0e6c3d0d850e8b22f5b0f047afc97767f1afe2040b85d4e401ba688a4da7a0caca7fac450899092c4fea789231ba9b07782010720f45d16d353798867dd7fef4a324520014ad5cb32684ec50cab742b750e05db040ff51140e8d740f6774a059feeb493b10d8ac722f23fa 0190c8f17bdd38669e345440d2c7631d67cee9c6548c4e7b9452377adb9303430efeda0e a7ae97671e31e7c75f4968e6967962718a195972d54585dc14210798c0d64be86a1188577fcc338cdbf6f4943047aa05 +07384a3f650bd270b14ca388a441af201b7767a2d47e9033f50cefd3af8257ecb38f5267e141cbbb2ab7327d8fc78cf27198ca3543d39553e178390bf1b921618432ad895e4f8153783a7ac22f4ca3cad4560e64f1ee4a7bcad05df98ea49a3847dc2143b27c243e48be59c869a547988e2205358e8db98b635ca21b745df4d2 00dbbc2a0409ca58a9e39e33b95fdd15080443c1dbdb5874bee991bd1b127047f08ec9f3 881f2dda602b9563cba30623f7c935f5e06296be75c41c647b45f915d47fc0f52466d5c3931a761a653ad4b35783f7a7 +824f26dcb4ce0ca020982814d5c727e629cbeeaa818c49668f8f6d743f0d0ad362b24cbac48027898f386889ca5411d7d1f9afc69493b1d9ae4d7b695c9fa0a30bb59e6be2cbff79231767e96cd8bba349fa2f97955d56f05430ab4ebd007064e3d5add94dfe255b6deff19650883ce9966e1a2affaf84d9540f65c87ab1f936 005495e6c59ca1873f36b756579632fd47f9fb95b64f52589d70f2739aa6a3bf8cf8c198 8d97e49ef52507f5a36a0ce61af146eb91601841d16da506bd45b962e0ec5ee08806a20f7f51ff4b13c9db988a80d1c3 +07de1e4bb9be15a710a74806d4447b093bc08ed04392d1bd5abb414f5f4b4d9d43520d0e46fc81c2a97e71086b28e53242449ed37fd7ed1c5772dbabc430fcf82ad20437b38eac15820421e51912325c872894452c3f8a10ddb040b35308e583c155c3707b52df467c4945f4e1071126ed46611a3253c297f5cbca9e27f58448 01724987c9b698519b6c225cf1261b77d0300045e5fd774dcbf13f285e6bd74512cb7edf 99c1a4e79c98ba01cdcc5e62f019f9e72b79f91e410f4c46c5eab755971edaea2527a486e45d0454f5d57661f70751f6 +1edbbbe71057bf7d0bfda922be21a3a4dff57b017ebf6fa99651246cd173bdc9b11eefd048ea599c1f98e907932aa04f64ed0a007831f30daf186c88807400970904d6090b2cf181e0f65f03b4234aceeb420867812562e47f452152bb1ddaaa48487170d06e47c5e9a7c0faa4fe494663d2fec22f7665ceffffc214b21c6b8f 01a5489091cfd51a0970508ee3e8449081ed175928ff8386592c83043a7911bbc2f8778b b1195395d4323bf504870804b92d7eb02c291cbe213cde953b092b65e040d7f2f4f43a687b2e3d3a6aaa979555949b76 +db5cf1de38a5187af11c1f0f19a36db52f8417de997229e83072fb51a3b7152a3b383e9919c1b8427582e53d4e7e25433d46cdf01492021c237ea0a87d38c71634743115a6b2aba66d3faa8003158340a5078171e0bd55a6e5d8c7fb2631a31c1204e1479bbfe79ac70d5e5823af502922a900576f0088a33e42ec3e26c0089e 01a45ecda0788fbd7cb7a716dcf4c6e83d4148bf63ed58078690ebd238c00329c462590a ab66811b723963c471480a3569e06d505f2eaa53be70e4f6545011eb003eb17280c84b85af2ac74614ccf691aed566a7 +4adaa850eec8272d25d76600aacf2cf66e754f6c5efa65c55a2a31b7bc69437d9a7e47c6f51c5da93895a45221f5f92c2e20ee6a95eed3cc7249688261a35d82872284900eb54dd1df6024ec48963ce43e8ed8b8cca8ed22beee8f0aadeae53726cca05443316537840ab824cd1b595f36064e9a19333748d4f4972178e7f5ae 011461776c33f20b176dc8f2b0cb2446a9b69e55b6c7bc7457a7fb4639116b452b79661a 8ecc0fa11a754c32c4d14a397ea756aead6fc983ca4880e84bb958de5089513c98700b86704e9fa94b9d9f0bf9d3217e +11d212a99c39fb5e4ca0096bbe6c81ae1490e1b8e07374b4e773bee4fdd24a3c13d653919db663d2c32aa4db140c4ae2d472d4f878946e527ad33b3dc93012d97458f96cb622ddb56f1ce7c2474ad0d5291dc35545de47b7053d137a8e79dabe06757ab53e26eaf751111bd27690e57ffdab5337eb6f81889e9d1b1ac729012f 0025a65f627db2b4d6cf83c5b0c00265b9b63f7656c5e3382139e4992bcdf3cab502844a a00a1e8cee88543f487ef6b3c4fd07f332a3544fbb42c38cfbfdcf6f2caa4f7753b9a3db2280e2eb33e9276429339483 +9e4ec74c09528fdf3153a0f6955f20c70915ff524b2e19c991ec4c5b41ea9185e3e876a02ed6f27c9b3479dba951bee8680c4c99be1a626808114408856994be7444ccbd5ef9859fa479b1050bb836034e20c531b4d618f5843fe1d4b613a731895b489a2363f3f5397d5ff964cf037e9b11e3ff5e1c3d403e5a46b8387c1241 0173b28fc29f10245221a907778708b3ee62e0480aa9051d4c3eb4e8d552e6aad5509943 b13a573828b30628bcde9e9f15db528d1d321cf8b3e6bdededabdff65f17c6feceec268d4fe1b2907dfa6f10a11fe838 +5fe8253d2134c434cb0866796013722e82184638b024a5a30938039929ccd8415c71f71f239c5c5a81f7a9cb493dde209f189bcf766c17c6d9589cd0c7de7f07ff9f24d2320669b589d084f8a8ea71127b9760b7355b162616afb34bcdcd416f1a062035102e29b70069b2b4dbf70179b8d60bc2ee5a455efd40194533bf560a 00624616adcd45e1fdc6cfeab2b17230d73d91fe0b39f4664f3c6891554f9b8e238257f7 b61437aa3538effdfaf70b4ea0a23fa117342c7fdfbacaa3ff9156eb8623c0e9abbdd77d845d284ac4ff107d88328383 +db49891838fe23f0530abd4a4fbba5ea970afa5747f6a0a10d2cf4d841581ea2178705c1203f00cafec91d0a72d25448072c9cf7d7ca5580b39f8589ec63128faa95cb0689574a6bebd515049a1eb9699922cde0366b5cd58aa8f3d3e847706896f7e1cac667fbfe94b2eca9e7be79a810806ca4bf53f219bb30532ca2254c11 0199757ffaa2c59e198d66824eaad37cc42d49b2e241b6a60382d05e425e800eaaf32470 889d0e577ae2c14c1ebb701b170fed1a3579740bde44be6b75ac7893a45a1994cc77b8ffdb1a6d90487b289ec165a6f4 +29d385d09c1142a7c181fe4b6e6132e414c15aa8605b44208c0399464613b966edcc2d46cf203a3f85d943d8eae658695dac74366224a0d0348083bec0106f5eb8809ae8d07f792fdd7c48fb1a25d5ef3bb9acd40b20c61c821024a9acb2ede321bd2d0dda849c22d76f421cbd8d51565d3c4266f666455ca1c0c3777aa44107 006e51381dcf21050aef2e9b97e35303cf3bd91956854ecf9b6b9827871d2efbe8201c5e 8aa40813bcc05d82cab77e0503fbb5a6d6f7117457dc7e55e7cb35d2c40757a70b87fcde8fcee07177a823a54d497771 +774c1cb8fb4f69ecfb5c7857d46415568d88f1f9f05a4bf64a1e1ff6d64aec16e1d09292010d1f067c68dddbcde06ea49be2ad3838053f0b9c0c2383edc451ef0188565118e7b3c66a4fa372b96633dc8a753106283b02d0322df273d58cc9bd061ec219f1e1a9c8ca1400e5e39c1b2c254273377dc98a1a2c44e5c2a5b89167 0018adcc22cb9a2db64bad3d60f1608c353e091637b948914115ebd43679904f955c8732 a35c4dda69573b7190cc953baa91f70c6593d8e0b6ddbe6bb3116a53c834f13dcbafc8428d49deee522a25c71eda9862 +c406aa4295f85c854b4db2de5a7a2defae53a319866921a3673af5b48c85ef22f6eb4cef892c790d8e64530fc20c729b2821b5f5e515560b1ac764106560c3a6a05657e34cd6deadfe2884bd288cef4ca92e1f25adde7d68a30fb0a1b3678156ced62e466718e68e9d67099ad82613b8d06bdda1a7b867c2455422818ae9eeac 01898276f159c10d92d8d4b6ae214d68c72792a4b5f1f79936ca3c063dc8d9a88be439e2 a243946535847eb624852a1ca8b7f7c4d11814aa0a6f67173ae6ac67b42a01a31dc134417e6aeb4088a6c3d36ddae4ba +cb2809152f8258660933472c06ddcdb65f6d5221fa29d5b0efec9c2a7914dbbf9ce0a468ce146fb333d26f510a87a6bb01bf8816756a1b5df81c5f65360957cae84ba038e37e88777580e91c34e2f5aef4fb55af7b81ad28aeba05e0b1c64a15381a6719fd2c16e38a441516e1b394952d984baf9e051b1dc1bda2e12f8ba5b8 012ff37c808c3cc029a9cfbb67a5ed21f3bf362b49270d4ed0f1e38fad25ebd79f112a50 ae528c9ef46d984fe56916f780d386c40ffcc70b1d2d9a95292175bed29c2b3200730b416264738c82c08e9361d91f0c +e060af96d4a7fe512bbf26be9a27bb6a8ff37547d4a7bbbfa710db24cffcfc760dac120f89f642880db2df6307f9ea5441d5932d49762d182b29d8e7fb067a61ab0df622f75cecc917e27d0326085d34581e052c85f50a37713e27518aed7c4434f86970e00a0a4b8503989e72614131b7164c1bdc82d2b6aeac0787f9838476 002b8c1fef9c6def32b5f4127273ce384b6add4aecec957c1662f52334f5ee97f49852d4 854ff6862f4472418eb4a7ca542dc954c0b9c807ccedc104c6b7b3600b8fe3687e4d5473f3d2abffd2ba5242ba831e81 +d235c31f0a82957a087c7597673970aa39321d4c2640685a03df8388b5eae4825d1fee29926f416d5e62a2e9ca1ea7cefffd31607e750fa9675983608e0f8dc895371b190574d065c5c0c23ffdaf49e65362914363a3fffbc2c1bb487cbd4f69ec22dda5c7dc3bbab805c81faa85787cc176bc0e5703924f395d8c9e7e7701e2 00afb1c45e9a9f02942b8e04da4b815498454dde6643de186625a98b3c1c6993abc8bba4 b3c8b82a508fd3b6cef7a4cb7a5ad56084de963c82babbbe5de8bec2c58bdbcea7b112f0a3eac8c6e85b3661d243301d +1a2559777a5fd8f269048feda82c4d9fceca95803f84a813789d6ed070422240e443789c5231d63d5268ddebc060dfb99c4eff2ff115d2984d8bbc5c05314562ea6864fd543e7e0a3b8572c017d8ae3563027d79bbe164d40a5bab354720e45094b9b26391ceb55339592fc2f10b97dc9c2649f7227648f5cd2fc46d78d31c0e 00ff537d73a4da0ae3a4894016b71dccef3bc886f3d24a5abb7dd96cf8fdcbdf0fdc5e51 81ef371711002c36d8df3671f55833c16db7ad343118cb3d94f2ac6997e4706ed59d03dd731a8cfa27af35e5a1d3a635 +658c0d3f764bbc952fa55a258bac16a5bb5184bfa76cee06baf9ee6b9ac3f116e08bb2406b1dd4be487b057f3b29c2043ebc33019b2017c4deccb86f50ff15fc9248ea5fb64261120b1960525aec3cc18827c23291722c5add8a3761ff8516c61956c62b8cbb13f3d92bf3eb45a70704c01bb3625d21c38ffa83a6db086ee968 016000d2e879906d1040b32eb6ba3caff700e5565871ac75f10c5c15b509964bbe5e14c7 93488fccfd1e8766c625ae2fa653aedb17634c7d818d6a8452e391d12ed17761fec71b2ad465cc9d8093160d3ece793a +4f10001e3517c2c1f973b555f4827681e096d860c4db08f1f4aef8000c9c24bebe59f8bf3d7d3cac959a1a5477bb0ea43f2e746b5d14ed48a58ef35484b0ac786d2fec669f945e846ad73e6b77a9e47012a951b398941566330d89125eb3c1fbb2f06adb951ff5f047d102fdf28b5cadb4a3e1a10412eb3474d2ed5c3fce78f5 0019528d505bf0584628d0214bc857150a929d3f59619bf8f3acab545fff0977c9bcdc97 981a62f4dd33b6468554ef4aa1549e9868d3123210b2bc59f4b8d822f900e7ef9fd780e0268e78e85917421fd2d89b21 +c43ec3c3232cae59bdea7cfaf18a4672035dbd2b8b6b1b44ede376b36cc2d8baeb921e416aa177f5977da8bf1d713509e5251278b6622790056271715cd5feac58bee5baf50b216e8eb886279c5a384cdb696470275b7487fe9ac4c506706f6b0f9809d1ccb102546a4297d2017c2a8df9f02f30d3d1bd9aebf6a92a02e0d202 0067795ce117bc0a389397fc22a01cfd9422cfbfb5aa44131938a8c45e48e1d5a718539c 861d8c8da60e9b1669b027370dbeff7bfee713ea547a98f465a776d059711a1281fdb9f7f1eb23c9dc8e77ea8afe7582 +9b7d675a3d2cdeb280ea28289b5fc2a3ef6b535ebee8ad242fb031e2e1f364e8ee806568b2f8627c5a5b4f51f4f65c71acdc1152c08b9211b81907b551e0ff47f5a6aca45dcfa06f09bf195d19d7b165b52111b601fbd97b192f62465f8ba20773b1599c8041e91448eac7a5763ca0628f40768324c5304e1119ca6a1fdb0778 019269dbfe4184249952a651a507584746c5b62c64cb3b17e0158aaf4d086a4afb0330c1 8ca01a3a341ac1a7e378e1934f598888c75d46e9cc6d03f982d67789ea6ada48a399dceb8186cbb96e8895fb0dd2a849 +f4a08daf8f66ce57a986f14b918099bcadcc4308bcde7c169ce8536a40d94a928cfc0968180a2c2a242c59df73ff79a03687998c421cf9a0e661630378779a4744ae2a6cd24ff61d7fcd6c11a4c8bcaf358075e96f864df0998ee98ee393b37bb38747b70bb7a208740959b45174a60153ee566e0f62528e9a5e4466186fa650 003835814de0d6441cd80a44e40350cc8bd62ffcc81e939a4410bb9c9259e30463c453b5 a9aa95fadde2634e66d9532f22df7ce1fbbf44aa212192d5445520416fa4f8905c685ec18d8cc00f717b4ddf406f2789 +864647405c70939fdb4c026bcad53218ba1d438d82c9138f0f0ecac815dbfb242307cca52c84826cf6556c51082a23f14252dfaea43ba229f7493db2bf8ae9cdb0228dab9e25cf385b504b92cca94f813acceaa1f18de851b8936c4dfe9e4e17002f02dded6b4c231ea5e614ab46fcdd637b8c6193e8d0c2df1b3d883b97e1e8 00aee83dbed3b703cb6e60d51e373eb20e298ac005fa6a572d02fa1e6da0345558ad2a46 99815b046f69a225e115deea031e8bd6ca14deeccd271e8dbc63056aa6b5ad4b9876127c00d9f02b021355af5de7303a +c87c8f3ad5c28a027b28ae5021dbe8d425f74181d519451f1fead7a1f9dd102fa6785b147b610610cb59bfa91fa363bb79ea602a7d7e1439f874c5dce748e5c320560c2d9676f3a948754c72b6db249478b7e19c9829ab4de2e344535d3e0b7c20c272f82556a280ef491524b255c4fafb9c8ecb87b0149ddd9d7bf6159e3337 017b65c66514019ff935e9d571a4e68e9ee4463b7b9a754b93f4f7741693f4399879fa8a 95e54f6eff199cf1d9e3a1d06f62c4bfb7d78a9e6d10247ab3ebfcd645cb4800ba80ef3c805e71a04371c371a21c3673 +ac7da7611e2ade20aad64b418a16e02e79ab4894d758550210eb10013a9b5533132be701f8843c840807c4167c38d21dff168d3baa65d5bcf285b73dcbb75819f8d7a20a849de335e19bae2aab2ca560b93d340731f291599a5b28afd7737460d291105cbba6d0290e836f6f6c1113d1b2faf90ac5de7c64e25206d79380a4ed 017d2071f39ba35515a8ec977ddd36ca15983e15bcda626f15af61d87d58114f4c80a8be 96ff415a93cf507b54fa592ecaa5675156f9825159e61a8153de40a65fbe95fdeb650254697971c2db6b1fac19081849 +5757c472fa2f81430dd920f39b61066a28c870b80e6c96f822f8f19b398c3574d159cc22120454dcd7e97be8211916e4bc8db365b2dbb99a6e597d06e6645046a0abdccbd06741e9c0eedf33cb78d78a540c2a390719acc498331e694e6b0118cf4f787b51c7b7237458a6149d6dbd0a08bae8097e919f970fde920485e9a0ac 011504659e12235855fe55220287a101e511d39a627f8a0d414446385d4a88f31507fe74 a8d9ff806c8089acecdb4a1ce3ea6695d4ffb2e8d544b6cddce39c7c6b16b44b4f233719077b8dd443014473aaf6e234 +e350383d04af0f4081bf09b95d1d53040e7acc64e56b13b653df31dd119617b800e0cdfeb935dfa5d94f1d7814688d8ce41021810958759cec76560e1e5c0581456acd1a020165849b2203f1c11d318d816697f36a86b59f160faeac7dba71682d3c031d0d547725ef69cbaa28345512e38b75ab011911d8924b2d17a857a96b 016e4cbabb03215767249ba2a608708b78d7387be9e77f5efd2462467fa05e8dcde2c036 877a9b7219026f012cf260b2c1bdf49874721d6472450bd8a5396f0300a8ddc76e51e501609b0a67ab78ffdc53ee7b86 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K409 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K409 new file mode 100644 index 000000000000..f5f19e30d73b --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K409 @@ -0,0 +1,60 @@ +f153cc61981a46d8a47d17d29ec157fa93fcf644beb84558db7c99c57fb131dcbc5b65581ced5ff0b29bfdc66ff703ecdd4290f7c353c02a3e6d6867f33f3dccd1a0b6752b8a35fa143f8921a5078af9c85b212564c5b795da9858c7955095938fcd10c21e35e1abe905e84c8b4bc05f2a06091ce876d9519b96951d08c7ac9e 0011c6528939672bed3e8c905b7ba594c3ce95f37fb28044f210cccd01dfdb42c10e8e1a0b5d6fc757834ca7f08e98cbc52b0edd 8e31868c2f600945d7f1075a6ad617fdda37314307b18385e937f8d1a2d342716f2621f127c527efc4c5809a87a9d65f +258c91524423b5c876432b1930c7b07b56eb5e3945f1e2296a4e5bfb9b9123f800ad195d6104641b1f1970bca553c2032f83d17252e52403a9381c1fc18eaffdf026f7537aa27d84c5e3d6e39e651a92a41139cec5181fe794457f556b390943093be719acd23fa1ddf7ff0aaf0479484a381a309b4f681af74bf97caef08c22 007e3b714496dd118d8f3f597961eec5c43d0265bf85723b0b9b0616977e0acc2cf686cb6afa6cdc19114e27ab000e762dfe467b 84ff29996d92b8b46577ec24260554c3c5d81757bc844d7540d331aecccff01f143e85f718fc1802707a733117fd89e5 +a16a0d6fd57240fe88c7c36b9f7f9040cfcaa9afc4beeb8300818c5f90cce73b819a12c31d42af33146399cdfa4ed4954d068dbb0f1f342269dd29f1fe357e7224304b67b0f924b794780fe7e6aa9dfa3380252fe7177b43e7b1789718949b9ec1b943c83ed4399491482f0f59d2cb8050ab6f8b5854d76c50651428cd29c40a 00182d1e937b037bf7f84144f7d4c94c935269c9aae7d500aa459a7a0ec113b232dcf282908eee4c84b8106cd38cdc41db3f89e1 915b473bcf416a1ba656706c64e864378fbd111aa8d9787074a79c1d482a4f50e7fc79f9ac0f582feafc7c5719772a03 +d02ff569828fd1add21f6bd1c50cbdcd09222e458ee79fd5dfdba3cbb84e9d926fcf196cccedece77d5aa17f8c8cbf3a9facf0f02c71d5c1c8aeda9d75f6fd7b6f2c5c70dff992ef6e02c438fb3c66da5a503b3c39acbe2a069da457595b542190d818015d462670b0807c401e36b1bfe05baff3a8ccf8d1f5f8de7840e87993 007ed09428f460724c8a5225a31151e031d9949493fff5703369c401762345d002c4ce424294baab22d9e71edc4f854510cf0e6a a6c6cb95aa8222dcc3612a56632800114ee3b0531cd0723344cd98be2aadb5cf3537cda25b89ccfc54a5be39b6dae967 +57befce973b225cfce7f996fa5a1a43acd160681b88a87b7de04544eb7b6a719718f1ca7f559b6531bfc18fca3836d2be7f7a6e48387b7579a6845796d30e46f0dda9d82680f8c96c5f0989741adef9762c3db763cae2699cb6c112543635e20ed5cfb4b55ca2ccb32d2d13936085a8ff95ed658a54be73f80c912ccfe5f0ca0 00390f05b9619c27b800e99aeaf61ef7f6249367d5cfaeae3c7b523a8b29153eb8a77132f6c4412545a842d6deb7b7aea7e2bda5 a299a204c912edd654f56d9728b10d93d749321255b0e9d30bf5a5f389bbd0634007a7fb32f29312f9c474f8b6ce8fa2 +4277ba40cb462860ca722cb4ee71c61836d2ceba18bc91f3fad7dea478972c6da0ebc02815eaaada1d1a5e93d7ab353855ccfdfc94a5742fe18daee2328871e06c1ab0a9a989d1239df2d2d27f96c415e7ef9a941f06c6790675361173cc229aac7045f49eaca207f59c497619ba32e932b5c1c6576812ee5b146e2cc7de5e62 0007d18652732596add3db31f7a0ce6020d03f3df58131b0c7c633faf619b8210cd309d6c0c4083aef1a1b6d2a756adad0bfe344 a9394983edfc5e5cb7a3bf6f61a704a8ce420a82153afd61e58b4360fa0231cc07b6ab5c31722e36197332fa83afce74 +57ff6792ed4b12220d179bc0ea57ff217f322c85bd3676a681d32d7e4a3e0c8e891fd267df17caba5992f68c35ff670b60b4bbdfff82404f6ed996c30539bc395120f97d4d7a652eaee82bd8f9360bf8bb73748b8bbda9f9480eb54f7eaf2609d4259329e8a5ea020521e7dbd3ec56f23c849932cbdf2875f5d5c774a9d6b0c9 002a91244ea4623b63403dba807d60b914ca3b901a2523244c322f2f11251446d3f15e869d086ebecfa1a39ce304e8b5c8de23e2 aae2289226895612bd248f3b4f47c9cdb3153fe85851df0cc24fb402136404799140e0393d5d6b0a2ec9dd78abdd51fa +f85113eda64478f460b60f8084220134933de049200a5f37884da7901471542e26690a5fabc3cbf9e679ade71b6e54d869bc136c3d34cc4a9efcafb777abf046b5ae5429136112a9a36a475121eb1f33f1f43481286fc1ada98a41064a1fa38c89e99a93065bb2a119348a9e452497fd5a0d2b83a66b09da9f47a0583732adf4 00068c56c6b5d50d1d4e13d3837d8c5e8ba2f825e121b63e97603fdfe78bb6899600ff0dc87b6b3b6868ad0d2f62b7b7a31603ff b959ca9fbc7220b1dd2069369f12c6b38e29ccfffe8207b4d99974edc7162a30bb14a1565d9bd22438099236a06b6549 +42811e9ee6dc509572e1cddbe5baf00afeb0c5c13e3755b922eee9e210001676082bc9edc3d78db2b5bebea7a2c0cd2b369226c2b8f83b28f33fb513407ab9d287d14b112d6c3be2493805ace5cf6fd366d03cfb28f4ce3f0f060880db64d6962e997463ba7c05b6fcd1e66babe4b94afc5c2d38c7050c69571d27b66ef0090b 003c88084f8b78446db431bd6e240a0c050813d2a763675b0ea869cbe183df697146cf29c03479af3d34587a95cd257027fbeed8 b0616afcab5796295051c6ab018a04ca5c8bc6ba3d0e6f4d09ae58bf88e3b982fb029831d6fdd5c6049a18c119e08b81 +b38f76ede7441ae0887e689d556f43155b38dab7cde487ce9ef9a46f2957c830d4d28006873fe2368197a6931f6fcaad755102686a457a7edccc8d344e2d2a9162e3d71d41c09a022539ae6d404955a6ad748231aee1f974d4f159940532fb3b1fa0254bfc5805d2fc68696856fadea386c542d3cefd1be3af04ca595e54be25 0051af7b63bf3297ae20517faaa1552f4fde65819dbbff6a52721611e5b7dc1242ed6e69768cdc37ea8cdfd1a5971f06b84b5803 a66d997fb103e56ca7457bc31acf9617567ff152034307d4b551d5e72bc834ea44c8f43a4d009b2606560295de223066 +356dc86cef7979148e995fc5abe2b14a7d5e4e42c9b3509b4363bb80c581a66f4e7e4aa53a4bfd37f9a7eccf75fdd726f348f6a3f779e6599f61bd1d668517f40453b39bcf35db0852a6a6218198f52b7ceda2ec55fca5abe8e5d93af9a42b9ae4de9530c5870211bacc27c39aa094013db703de2fd3121f08d7e97dbd4e8946 003d65bdec48972d03811b78150a06956eb22d337dbec5416bbd8185a6322cd8c0ff8000210dbd1326422289071cab65175f5d10 b5e4facda056786860ce309079a1fd60175ac2cbd6be2d98b01ee7725aa1c3a8a584272a7b06b277c2b194878cf8986b +06fd39a50bf25e89f1071ff81fec5d1e35b6dd68990414ee403dfdebb792627b6a4ae3d2236c159e4441ff90b61ec87b1592c538515f0486b19e58583394a05e6411e69b4285d6d6589982ac0eeb2c912c4948789cad741183663fc070943389d4e9a1150b8f6088fc50605915e9e24b2d98a1f539024770e4820e14ae42ea8e 001f1a8b5f35dbbf82c102df550c72216a243f986f0325920f6186a16d1da74228cc02be6024c7411160c183c923c743354f9438 953eba375e2d2c4c7057723568e68d7d7087d06b3af125f97f13a5ae03665b6e6232198294a98331eb108178cf11de88 +6daaa41150ea252a3e966a338377307d909b95080e006f13027f2be5059d9208930c5a329994c0b794ef50eb059bc6c215f68cf42260bd410f9bd86d2ad5ab7179c7c92de4a93a5f6aa17de5aefea815e7c0b78a8cc53c21dc4dee037b29c9df4e12343109283ffd5d8a3b81fba1b5e95506c7e01ac056c86dd0ee23bc21af0a 0031dc621200cd174193d95e9092ffb86189c52cdbb9ed937593f2cde7c4a0264b9100e1b8407336c8dfb5520d28a18dc4e39a89 8b1ff1de7957d753d530b552e0cb5d9af451c72d5f41bc1997b25f32b56df2aa5aa524605fc8787be09c25d344797bbe +6378dd1c12c5197b57d47dc46a67949bdd1e0809004e94d49b0234126a08ad5bf8723ebfd132145813136d8b7dd096f56c34248f09a65c34f60c2f80f9a51b3795f3d2518b11aaeaf6dd45a323794080b78f85d629e5fa719b6ab0b14c78cd908befeaef0dbfaa08cec9318bbcb376d48b11b68735c9554a45293db5e9239ae1 0016e6750245a88340b0f0665b890459f8038e9b1366f2fc1326245a88d4c523ec94429f21869ce3dbf75126e58f77241c99efaa b1e33dba71763283efcf1c02b95947c4981c989e1b067ded6a017bdcc7e74bd3fa10914a84718bcf034f565debed5f39 +b898d0f9bd80e083fa541f457d14d853bba55b120424a95e1d9511c8833f48444329e0349d68204c4b4581ef1c4dee23ed0a4445727a72e1e6cde422f7c10ae132a3fe681f9d741fda263e73f7cdf10759467c9d76164086abf6780ad474772771eee22d195339bb8f6235e0d992bbe282b13ce4fe01417f507a2c4fa155e108 00788fabdafeebb72f6385301e30024b56639e629a400f9c50d402cfc9b5817844f06a451fbda29c7ece41dc9ffcfc625fe0ff0a aa41703ec323bdca1490285baa5c8d6d966f04a11238ae9f7549a03525b254d22f957c9bff03a3a84dfb71547cb9de62 +dbe04561ea8579672a2b3afa94426a3cbc274b55263989d41a778bcb082da797d84d930ca847a481789524940701cd5f1d11b460bdac0bffb0b3a3abe1ab689c519700de85a0a571494ba0cfc3c865450eba7a9e916b7fa9df55e8a1c246c992e6a0b44b78274e008472bed8d8411633e6520e1a906c5d0c8aafd572fe6f1f64 001b8dfd64563dc219d6eeb53f2e3ad1d771140d0960b211dc1f757af5e297dc7548d6133ddb574711d466688f80dbd65a7bbcdc ab79b56c06344d4177de75de88868171284849fe5f55e43bcc6110fcab0e08cc71524f9b81649153ff79b77fc15cf51b +48a8300820fea2ad83c83f7d6b24192715329c3f159d56644e11ed25efcbd3d31600a813b909812987b97d1087e74a63b4494cc031c63492b6615e9d6e5b36f62cb2ef88b9f736595800de465789f43811165a5fc093ee6d776008739de8de2a84e878748641be8bd52e5b891c4145f52bbd46644852a43108e93d86352b2a3c 00422131829608ff730c24ddf7e8b4a2600eaa9681eaf45432daa7d41fe2fb488fd0199d431a1ed823801ce21f4f01a4dd4248ca 98c31ec173617d501ce86509e4c0f78d5ba3bb43ee6f5bc1520979b2c1fc53cd36723b8f196ecd7da5518a43e59b6582 +276e3a986ce33256014aaa3e55cc1f4c75fe831746b342eadb017676b0cba7c353b3a2b554522c12e6aeaf1364cd2eb765a404b3d0aa61258194a30219d76d2bfa98ad20e7e91756cf65e50d7914157f283f2ba3930c0ad3a97532cc747b1cb9c806fff497f0322025a3d02ff407fc7b5808585b91d95523c9d5864efdf7d983 00095ae8e4c7e55eb5da01acc05ecfe72a4dcd8ec152f1c8dc165014f70eb4e4a7861aeb2b96c418b2d4db58659e76184e013a49 911f9d210fd4d5d3105fb0a67a7c1d6c35dbd16b02acc60ba670e7fab42cd1c4287e06687c72d24717c1fc298f183d80 +6a4fc1827c3a7256faa8ec6a0f3d23559d6949f8cc20e7f76111dc4ebd59213951cbf0eadacaeb8862d6baa0cb298645e4314b1c303bd0d5e9893304d4b7fbd36ab05fb6a5edc3fef763e3a4124d61539eb616b359c5cb55b5e2bec50c91dd95fc39ddf521aa854216eb5a707819fa6f067b316a17a3b146e7cc2dd517f7d63f 0006f2075bd730f34df111ebda919167b1d3358ada32cd6747cb3353bcfb814a77ac70cd51b31a0e538539453bf9eaf9d8b384c9 b2586fe26afbd6f5549614f34fb76e3c437dfdff42de3e27563f08a431db58fa1c255d79f69fae9d99beb7cf9c50c61d +4b088199bd8c94775d8ee508377d672dbf50f6d2c7370e99821ec8f9387492fb2eebdbea473ea18465565f79e2af418555f10c4a527e05a9e20c9c00b807dc8b350cd4ccc2d87e91f66addf02ce4f43597aa258ac6fbe9365cc2c8e8bbe5c884abc929710e8423cd6722a8f473bb55804159a92a3d8b6661a536b4fb9293bb0a 003887d284e9ad17d38bc6da9d83c192a434c509340a7f233cebb032b09ab7c4c6e8730b4a80844898616c9abcd16b753c6bb4c5 a544368bd43c9815cae39fcfa94722e5f798a4234dc0c6ae4a08b3fae5fe7afdd03aa47eb470f8ba10349422df8f0a52 +848a13465ddcfb2dc14f7bc0db0756832c22dde1e31e4d8b3ae0dd1aafbdf15e954889e95d3bdfd6e5ebb6171fad62592c23277a89e8ba53978c9b1afedfef7e1c3f6d9f31077530460b47834b30bbd84a4da601be988738aa815d3d7e72043243a5288751ee08b4815a017fb5d9bd55833698a0d526b1ed79da35ef0fac93da 002ea5430610864257c9dc393c3addcd0d8d5bc8aab1067643b08857210464428aa85cf1ae6c743fd2682255d4c8eaa46ca21e73 a02b39ef7a822ea81a187f3debbd5279acdaf45355ae63097de47a9532be83c71bb16b5d6320619f5a23fcb70fcc9361 +d1850545c04ea65528849973c220205c35eae98826d169348970d1420b4d872ce233af1daa9e62f6a562544ae3a0633a954a493e9766dd5d87e47486559fdf86229a7c9e1726de21895abdcf2422d438f4ad98d88b45c56742694ad5e11894253270997c049f0f419842482f21c792fbe5613e2defecd485585f1835b6f4c578 0062c757c92eaef41f5d81169ec4968145b5aa2bc1d2a3a5fd000634777748ecb93677b3da12e3be33272a8f0a52300f4a5a37c4 82a90940edaea81cf3b50b23c85ac5475874614b5824b194ba07ea7142bd99820f7e5ab083e8756456f56ed5d8a25746 +421c9784d6fd507c82904e1054edf9bdd1efb58a0b211340086069ad38b7b0dd15c2345fa8767ef71254ed1bd5c35f742b1d3f4765ff9007a5477ba9e5d3d5a5cb5fab4efc1cad73701d4776c6c4343f42b5d94a9eb78ae428dfe5fbdd8e6ece09d5b75cf4346cf27db856352225ab04e6ea56661554fbc39916accebecb3935 0048a313c0c11489939fc0cffc6ccb9f179093c4e13141b92dbbaac441b7ae878c9d412066e95615174a24692555cbbe904a14cf a6c797dcf0fdf2758a2835de6294f0028a1fa0e5094c0f57cd9f4e13b00b727a32323808f06a4fe65d945dba5b327301 +7910bab15b6429947655e33a67f41b76f1d7b71534f8904d6a0472c2faded038565272d0b5f51aa915e0d624e9ff48d50ebfa2f09324864f26c29ab73eb39b436c5c459c7cff4d2b62992e3489cb4ddfc05d7366b161a463aa1b782641d93507de43c8cd0a0a0a9d1c644f4554e3edaf7fd794248110ca9387e73ae5d00d299e 0046e2adfe5d3549e1e6fa1fe69a7cbb4ac9b111c8903d544268f8318b0b47d4b78fe3e56eb5e639ad5382e7cd5bd4b2c3e70ef6 8bfda1711629e83a392f54bca5d35a4facc444b3b45fdc5f08d8ce4b6b5c8e2f0592917482aa055ccfa7633dbaebbaec +e6fc96e060b956c25d50ad25443f3c30a12d199a47451a49ce88307201dfb15ed816982e8888a28daa92eaf3c5584ca6ab2ca9e14577f84396de2e0ac214b24a2279f5e7b344fb7387e9afc8f0a2b77a4d024a20ce6183499b17096947444bbb753d9b39e5c694239d28f9c454bb05468d17ab564ee6cea3741747ccb7f108af 00480103fd6180a431c837643566706e2b9597de0a1346a224d176a5b2c54aa4d064418ed654a5d39f4773fb509f86473ebb373f aad737d321785667e2d9026192a189a11b08c8b27a491f6d6fcc357bf24a5f1c31aa14b2736568a1fd79dc344d5ea7c4 +c8a8a0d41f35537e6fd523ee099eb45e1ad6ab54bed4d3e315e20227db03292e39dc1a91bab439c0d20e36e7fea6ef08983f390a6b5551ac3b4f1895220b2867fab95552cef9bd8702962839bd9b2c72772640e7d3be3c5889d226acbefdcb448432bc503e5a5fe7ae9ae7696c720a799f9882c64ae0385f656074dd8a6821f5 0013c489e8311c6bef02c8f58903b2ba2a98a27cb935d75a30d320af9a14fa3cbc6adcce09235a9eaf333dd05f4b2f1694985dc4 b17eab1bd4852646490799152633cf277fc03c1386880f6b63731a480a190846a34212c872a27706ba682914e7be1f26 +3407cd6d2845197cd7414a30fc3df7184da204222ffd65c4d16a12cadabf603de8043ea14f5e6ddcc22d3572dc06dec1a23cd924e1847ae285ecf01754e2d1247876431eb98e897e47412a2330bb32990f9714122109e94b38f82cfdbbf2eeb4c6f88f5dbf9f0ccb47939df8be321dcd9bfd9bb99cac9f94885fee7d443fbd87 002419bd2200f8e1d87db848b0379741685e680d9affe693eed49d82931030b6cb05d21a4965f4e1df2045c8513a8f574ca9f2e7 b01703e9f66a2cd7012d89f1d5ab4a9647b8c4ce9bbd16850457318629f5af0265ea49db7266f47d096a5b7e9ebd9027 +ad43f8440071285d01fd79244907803601aff4bc5d14c77483a87cd742144d41c68269d76c9a83c09d2178bbcbdf99f927b378497ffdc907a75a3b0ad019e69758dfffa480871eb6e1e17c8539373de611a557fad120d0bd147f8debe5f09a02e56fb607e9c1253ed592071f042e42fee39775b407225a2b86a950d81bb7d7ef 00722951879a65bfcb414e11712ee9431eeb32319e0ff28601112f89276ffc2b96eb65c7fd77d023f09914a53e2aae2c84652bad 8cd8e4c25acfdfffb791b66a015c00aa1765f6f0f60c425046f7ee1eb1672382576905cdf082def44fb2af294b975971 +d61a3765229dcd0b4fa6c57280f851ec2bd54d3ee2436935cd6d94e0120d0844adda163995fbc4cd9d7275da859ad8ebf30af9efbdcfc31c7c9ef42bce9011d37cf9d15fb018e117bbc102f7d05750e5072f73d02c2f45509a55627a78cbd9082cbf36807759d1fe2ecbb92ab30cf28434941712d38bdd100955d611987b5968 003f5b5a772d24bd5454bf26759dbd433fcc7bae4f5c593664c4d75da0cdf9430d7d9162bce3d7f6e13a344259da5a7d6a1635bb 8900cda8a8683f326cfdf881d03ebe0e4cf8a7f82e8cb48aa83ab8dca7f1c14e59c12351b6e5576c79fd5074f37e7532 +1f3c23636414ced48fab6763eed5b22537968e6bf08c178b3d31fb1f6ea773c6979759701d94bc1bee7c354272811edec58eff50c93331b22723d460e56dbee90466b894354777b23b13a37d15a84c762caca70c01518bf34d0c2f072145d274b3b6c932b48bd815fe81161d8507ffbc2f783bd212c29b2887af6d2ffa9d2b4d 0046bb4a141c9099d531dd23ac440eff1f5b10f7cf34920b6b702311d490d25344c665ed5211d401def24986c8094165d10f8934 8127b2a4eb60fbe7371ac4b88cc60906b143f3938921e43450cdc39739b37f343cfeecb4ca713e601343a7fa0c71ccfb +ec69f2937ec793aaa3486d59d0c960ee50f640a9ce98a3becffc12d6a6c1c6c2f255d37d29f9b4d068373a96beadac98fd5203a9f229bfc70bcd449640165ae5128e3f8d057769e28356e73e35d8e9af7876f608390090892c67391ddfcc1c332aa61efbf72d54bc615998b3be8ab0a9d372784bea48c9fab244482c75cb2de3 006f2c6e9ea8109223d9a349fce14927618fc4fa95e05ecf9aba1546619eaeaca7b5815cc07e97ae8cd1e9973ac603f84d838393 91513781b691cb2fd4db8d23c4d5834ab8c2be2f94e27882b948dafcf478ef01a841511f24ba7a46371a15c99160172e +70e11efc78d7f079ae41ac3c31c96d3220f4abfe23814a2a4a78d9b1a25e838c3408bd416062e4b0a5cdadf0c6e16a11e00f59711b417751f5e4b43ecad99efbdb2a81c91a034e89edc94eb552c3eba62808563cdf64453a1db07daff8742aea4a9fa738e1322da316b26dbca2954b2bc0de6da7518d28e6677dec6ba8af4285 0004212b7fd913d794fc6bb33e0276e349c052c969ecbf6afc89b28f75a599a9242acf74dec9f374361ba296ba42a38407f9b7d6 b4b7c7cb563fdd0802de49e7542ab7588f068a14012856a47234d535f500e3ae8893187843be17e64475a303867a5b32 +d922fa515e3bed60b517a2d37cafe4c041e5ab4b5c8d8d4011bf9fc4013dd8abf7add71fcfde5e71d6abe76bd0f749e960cbed55711c87b5629a2c39cff48ed7d0feaf5cc4765e576a4959521f9a45fcba0dc65ae618826447e02ce6e1cab5ce8d6c96c3211adbb0660de7df7453f3aa726016941d00d8ee536cc106a603d126 006baeebb5ffc89c94c3e8b37b9b0904e7c4b251d204894655bf3b1235710215c29820b9d401c9ca7df1404d2d62d708aafe208a 92a0e8dbada6654ef67f72512c91babdcb372700db73bab02d035341d64b38d8e9b5f8f68e04f3473fa2dddc3f95925f +4f64d0f6bfc542a0d4347576935bd68ca88524ead03b8d2c494061d0658e6c3e14576b5bcea5f2f992f54cfb52b5c7cf1dfc517205e0454510eef1b7054a8cd06ab53ed2468193f98ff0dd62faf076549ab2a270f259276d5729996c120792c6f466a74ab65035bf38ff2c055b43e2a8b8e2449a2375ddbfc18242157bd905f8 0008e5f66ba53e7caad1feda122a80c32c82d2c32a7237b8ee8ead44ea8f2f01d77c7056b9dd60b92d051f060da8532c1fd0e8f4 b7c39aa434af604b483455996d6274db006093a7c45ecd0faab566ea852b7fcc7d9cd9bf68c254ab50da82405c42503f +7047d478ec5282d55db8c19c97af10951982d908c759ff590f27d57e2664f08d526cbb2bfde39bdbb1aa3dca5a8d3feb50b868be6651f197abccc9d8040b623de367e2ea1d20ecd302afb9e273f4be9f3f64f2c2eb3f92d5e0e375db6549da2a589f0604bc7146562ccefd15995a7c4208f640e7a17afbca69cda4e173380523 004ecb22b44e809f89b16abb10be062c89b41ee34e110403e42a20ce59a99afdc22f6f6dda56e1d9d1b8ce1d057f390db111def3 add132f2457ef02122741de6ade14f029f95100fa0830b1de398281eed0c4ce2d6db00b4cbb00cad32ed21ec5d4627d1 +1a8384b4771a410663e56eb36c5d9ede8d161a8fb0e31d3f74bcb017b9e31232bb2e2f4c65a2d85bcd1cedd93ef08d4bb4af0095731574ab3f2762788a1ba3bf0ee46684da8d9dd384432fee99ed3c69213d790a5d81b351063eaf2bda71ca4868ac36be1b571024a8bf09039b347fa996d5d161078314e24b7d073e05cb3d48 0051f9500c15ae73d6d479b9f3d2caccc2039d8d03820befc2aae3bbaf65d59bd9cb3c4e3aa8bed5b3acb70a5566047ffad80729 b687a3b85b1bb8b64a6e147abf902e7d261252d1f47bbe093c30dfdd1c8d4eeea879427040ca1ba4807b09fa984fe30a +43513d6dd8bb0af7a6f5a2b35f99957d335a48d54f2c4019ce9518b35441d4935518976ab1df37110b5b53532cd9e2c66d9f87ae7f683d7efdbe1775a6c15eecee84c6f879999d0706f6779dc158c111fe8d7201983883bc8334f51dec60004eb1087347bfdab20f8f2f260556681e05fdbb8a6139857fd3bb2df5bc1f2dc143 000cf01dc4462cca764f4f8cbef48c51980737b9b98d1384b8de9f4c733829db7718a9b5eaa46a8475c2144fe4454cb8eeb0a443 a64f80d33e7141c0d05f195742fff010964c7379930abf93ac60ac2c12d832939b62f02ebfeda1adc142b43cb88c6e6a +752300bc5066d0efaf807183a41725e349907b7339d77c79921ead3c685b616b0eb97e708f3880fce0136c510c8cb53b22cb424af6f1c34633600939a0647c02d8f9601f9416f1d24a51657241fb559c25dfba91402cea43bca1a13718b3945b048725f3df560e6717cfc6ebd894e29bff1e0c7763f15b8ea93e67385f059598 0063a9a565497974c6dd459bea0d1196d74f263f333c31b7e8591499960e1cd79e2ef4cc8709f6d54713f873b16e7b0be42f71c8 88d6d1310982653a3349229825c45bf0d4b9a6760d2b352e5cbc05282eb307c49580bfce803e86158b8126f785d7e547 +f620603489944769c02e2f902c2299dd5f32b5fb463c841b7e1fc0249a85d2c31684bd3daacd97de8291c5d39e84d6e59d3dde1b30c181bfe8d31b8d8e080bd191690a67fa00024ac8c1b10981b40d4f88789ecc58fc69b15417fff34834e23453bb9933a43d08afab74d056f366b40ad167b51ee5f008db151a12b467d3eaa2 0041074dc186193d30aac7cc6d269b938ab40b257d095e54ba79967a377a91b8f73671470cd07f0a3d1db7cf0a31ba9070625e43 84c9bda7fca941dfed068cfd53746de1d9bb2a3812b0c3ede7ad455fe5e7107170178c9edc321a20c9a6147924aca6bb +5575f610762b42ce4e98d7bcf45a7a6a0d66ec7f27d6b8b17f1961249d905bc7e58e2ce0806d467f106b16285dce4544c72666d08b5e2276cd0c4e13187cbda8aecf57b1855afedf8fad39ee4fe009f204e60bdbec79b123456ec2d85631d382b8a2f2c7634af3992e4707f7b4215e2c9d3b0aa8fb08267953883a4213669d33 0010820db54ccf0226161aeaee79cfd2797f87702b4ee91adf8543b3c9e79579d0df8a889e366ec1e0718e039b87a37c24d620e9 a81a731109fb16bd337582a70cec0623568fdf6386768c5866fc45897e6cace5aaa2b7001a53b2fe3eaabc033a5c2d3d +81cf067411dde2d0ab04fe5fa1e28e6975cdcc571588de60a35bd956a535fbbda4affd0803d244f3f7e6902a2c9a7ef2488691b6bef7f8ffb33be09ccae4c5285265e4957f7928ea5cbabd6823297f59a7cfc9939a49f26bde74c4c69e2d38c1efbacbcfdef011213843158072be84ed3c1781f67a0e2d4e9ba76a585c17fc0a 0059d2a06e8bfd5e14a9bc8777958b85be5e97af892d2cdeb0ecbd2d5017952b5042349db5fedba2e26e7b85bbb31ad313d99434 903cb107206c9d4be510012742b5a1f897deb047c8d087eacae178b12384c6c6fd148c7bc3db7b5a3dad93b1d683ae33 +8ea18387940035cff2f37278d321b344231075db43c7fa7fee9bd3fdefe5e8f03e7af9deafa1022eb108e19ec11fae34536a4fbac2e8c8139a081a997c080cbe8f3e2d2a72ff26edcc5338b21372fa1498e439e4d9bb12d51cc539f859047957b1b1f1fc30b90231eb06b365a4d404a1fd5a0e5cef171fc95b04d0b557d78ebf 00405590893cbbe18f4ad99df28b5f9d17f8f1882269aff0b7eee9392859d68927a99c942a3075269ddec6d69c0df2d76ab9d801 b2483ea9686e244b77a501952b9ed7021d0ecdaeaf7f190d0590e3bcca8b782e098925bb72dede46e274d93bb3639b24 +6a253c1aa17b2b1e6624afc8e7456d366ef5b1bd78e740538260f395481148a64da0b6a58cd53d7e06c691beae1a616547cd95c4d259a371e51c2c0e334c8a5311ae31e4c7af325686ff9f7a36f731010ee1a9b8a29169ceac36a060dd23611dc9713c615424888bb574ad5f5755d7311bd169336ae986c977a394bf16487c4e 0062bbb4f565aa0f23b88ab9029d33b995729d10fcfc33ba7c4051e2fbc72f15636a834e3ebfe604b927cdfc89f53c57f36890db 82ea374f89b30e662b109594925368ec26bf5880ec73a511ef06ef17c9091dc22d40043a0dbf0d9b4239c6146ab000a1 +0f91d0f0139faf3b90a3d4bebd7e96ff6bb6f90f6c68321fb392637d8ab2a60d649a7b7364ee6e4e274e1a8d342caee36cc11c56c54247fb0a8e8ef81ac4322b454dc9a195dc54567bf47ec8d4fa4cd32e76d78ea2d08bcbce3edbb68fd8597e56d5a9f2df4e47b2701046df89615961db601bd8204584a6a6cfbb627e2a1190 003fad7031cf8810544a3e4bd1382c0a2e22c5a9fe4804ce67b27591fc516ee81dbac841d399327168aa6abd79e2b5ef85df1528 a3c43625e85d186a637c3aa9a6aa52cc4388c70bac762ba8dd2f06b45dc94ed8fdc9ced57c866856083806f5f9f352c7 +50c17c1fe4dc84648e5c3c3ab8f7c971d4c58d8d56d2b5ddd92e35e6792111ed8dac7644ac8a07ca8bb4e38e071aa47b22ffe495e9083f9bf781ac1b5fba571862c909c7aaa7b8d05ddfb7ef61c99700de734d5658f44ae9fc908c85a2dac8e7f854d6d24be805fcd7f873a91252985c5c73129c60177ba8fd99daa87b25a073 003db41b4f637fe7977c90e4f1a21799baaddd1826c667102414877138436cfae1b9959842b8097b5276f15f2b982ee59df263c8 a6efa22bac2e7e75e817a4d35c7898b2b7f73415f5b12454b3de34d14c8ac42edbebd7aedc0b858e4bd582b3de395f7b +3583a3226e2dc463a462fefa97024e6e969c1b13bdc1d228e2d7823d9f7c09012390c2535baf086588000e908309090daac6e6d2b06d2ede6fae838ed47f30b5b481185f607a3586f6dea47c8f84e9d3b96d5b0ebae2462fde1e49d84d36658e87dccf5e30c0937feefd8862dcdb1a1ca373f6ae41641502ac54df6633a8cec1 0065b76c6093d9c49591293471286df1a4444e60d9d06cfa114e175afb5f119d2abeb273b0596019a0ec5db5b5869f2cc827b364 8c95a60b75535cc17fbb94425dad3a74e745d473265f3d919eadb2b6da1bdb4e9f96b921a234538a22decb396e685025 +60ca58462d53d074b370127132f4e59f5eb8d15594dc721a94286afd082a8934e52462c9c1c3910f8b50d7aa3671dafa5972958d876d7992467b2fee3795a6f9d8a7bd3003a8582ea8c003aa1e02c08ab6804d85bcfa13a815d75c938671f0af0706c68bc70a6155708ca755cac2fbb68b2952208d63e0e2e3d816f04c61bc03 007e9993f3fc1fdc4c376ef77ecded96006ac1159740bd1b2dc6ae3d97e15a67383f1fc931e460b9af3fe14a54e47919667ed06c 96b3e7405198eb076c579d9b99de6f4da7dded715a80fe5995581ff25541aa8089bc057c645c345f750a5a00985d2443 +c749f9bb92ca9957ca6d0124206ebf65e860ff38a225e241950bf4526cef3f4fa9184ec83f71f813fe852dc08eca6b45b14fc7f2c6a19296529bfda007efe9d0d26492de2a902b45ed39603e22f0a763dfa5deadd97ef6feb859d860baa2cfd1d066c0be0f9f4e0e2fafa69cc51b12e814ad2e33b0acc0bcbe1df8cf018dcd4f 000c11e2979498695c660a2bdfd105b115bc4ff8664ea15cfb40c725406c6fc9a13027bd1d72ffff6258f29e4e19b845243444a7 97fa972309c8d90895f58e9e6d74e65a28fb57946308343d1d68173cc2eabeba9be8915086616cf57797dca7914724fb +4de8414780ea20f7943b1f1adae5e3962d96e828fee43bdbf2831bd71bd25df2976a3be37a7a667c7fbe1200de578920090d131a750c9bc09bd95b261234ea8cc25423c4ddfff5656d6b32da6e2f6f530e6673a8660aeca31273bb9a3a21bbd7031a2fa71ba37c004d3d1c64b2c0798783e47b2efe1a208959ac16e35d444245 0068dfc23c6635bd1fa1076dcbd456ad6e8df7ce7c1370fe275803befc4ffad007fd062a61cf1d50b93aeb9afe1aab47a65af82a 949473fc858c572f10072219148dbb32260113e42d28f26e646c6778847e847d6427249040547ac99132dadac16844fb +a081d54232f84bb19dbd52ec3812748e2e6486f6cf1b177b27929504ca878036547eb43531bb5b3edc81bfe105370427e92831d2239cca0106d031d9fa8da9cf89c6fb6401377d5936b6329ccad854e5567181b8f16a37c35f333eaa0ffe91d727d183fbab935fdac2d5670dafb3fba59e4fa2df1746c58dd8360fa08af7f4e6 0040807fb888e1d9fd33604546656a493629d94d4a0a9de2608962225ed158167f9e2438abe2d12a11e2adb6c2b66ed78215b0b1 81bf384069f19578c960623d9670f8aeee4aa8736e20495164faa8ba5810b74141e0aa36fff86d18f7c32ee5adb31816 +ea60266f1538565b3ff42fa4bbfe319be070329059c52c8bc04a7da2824f209c1145a05e551ea59ded8ca8439c328f6907da4e81d658937df614be98c7b8648818ea80ef40e49aaa4431f4a211d62acf2611f5d60c446b2b25745078c643859be1b12b3141a09ab765dd63ea1f2a2df015eca0840087a5db378c4c4cce76cba7 0033bda0a02badae08fe40c239b9d59e5bfe1c4d4b9b7a5acda6790bfd77ad08dde5e93a2da80ec54a7f88146d72218bbb88aa10 895663e56c4c47123c43e7771caea156aa81fc65c2c821161de5eafa4766cf5fc17f61f1783f38acb1cc7c874ac12c6e +82f38c9405ef0d26bcdd5b3fce4fb0060c3095f61403418e17c337933f0563c03691fabd32ab5e896c593439e7492a9970ae325c67196d9e83fe0f9780409a930326f7e6efae035ef8c321cb9ad12461edd5cde66c04739fe079db65406b3c2d22f2d04b1a4335285513d4ceb901d2ca2ad10c508302266c2cd6079ff14eff4b 004ff431769d26b8837d3e1295f5464fe82be29edefba76323e92078a6483ea0daa96221549102509a1bdcfd46a5a2e5de10c39f a9be5838aebe448386a9784def163441c60655d288b1145b4856b71f9d07d3110ea0f60cc21d6d5d943ebcc0fbf68acd +d8506fab4f681ba4ae86066aed447571eba4fe04e6585fe3be6af2ab1000a3da68c5b0c711a85ddf3a40cb7c8944eef81f2094650459e14f5b848e6add7e580b0198070f873eb3ed5d0728eabd92bc1398764b94cbb4cdd7cc2027b9762dd10782658cd9e8a5022ac062fec535d892198c8a387b3d2b6f7c92b1af6ab7dd9e4a 003f85ca1169ca7e9df44cbc6bc7d2868c9d94e8f8b699a42ca492dca0914eb5789a9032218dcef7f95f959c9554a1cd83360439 812ef0a78a98dad6c0fd8dcd7cf9cf1d8460b5448a4c71b31429c34c412adb4ec5e89f035ff75dae219f30270ba29250 +b3f30d34f252a4c26f396079e773142bf61c0981d912333ade3de4e27cbc72cd8a16b31807f0c46116f87accb854487d83ec8c6a61565e6fca145eab70048245db08616779d7047db63aabd90dd15acbb05eaa510072c151c0518f1b34582b95f43ec7b9484b2993c176de79e84566764467f72392ef31619426d159c91816d4 003a97deb36d68f81f50c8829d412ee5de7f9d775633cb69c09dac558182039e275fc258240517a7c4aa592e364765321f27cb12 873ea2826a4e9f04586186ba7c7e93e028e213c405b9282346e78e778a7b53c4a6fa9041cfddba92e627aa4c50a1a89a +0fb13b7c09467ad203852738eda5ddd25b17d330e82c279630b0e1f0c86681f67f6e537fb00da9419114973c8559306de58b0387d86e52d821d982a60769d2f15fd5ac2ee6dc55d8ac04ee247282cb2866b8cb8b4d7b4b6cfb33bfefdff09a73d727193e5fb939ff66ac5fcb644a44f9083a790888cc538c5eb435243c6a34a8 003b1da0ffed24e1a3b5ba22bd684337f6b08053591620541bdad50c761d66201a2cf21a4cc636426456525b598e96baf97d9851 96c817b3412a6d691a9932f169337803c02b48eaf00a1cd53a9d0809c7c18299a401ed81b82184df4c323dfe9247cebf +f9b8124281628cf4e1da0cb4f021c8d19d815644cd80c7c8de4cc62722904ec4cddd26cc4891f30b15098a25ba6923c6abf4774deb6e1883fbb409862f94467e75a725e7154be860fd58347577c83adbf18535c54b102220197afa062cc1c84f6094490ce488af4a08d2c5b808a2572e18a59de96c87162f88413795351cedc1 0040bac7e0d3b54c7753c79d43469e310d876015d948fac4e3a9765444754476af72330e88d79ee6119697aafac8435ab5690754 87d38d7bc9c25895d91d8f59f0cea1691f49eabef2848caf4135ddefb8f9621b8098afec7716131575ee5043d0b592ad +4e3cd6100520db050af0daa69fe3cfe6603a223d4f2a6318fc5836db8640d4c7fb80bb781302036d2d6fb8e552b4eaef3133b98ba2d36b9ef0b86243b0391413c73d48ecbf1d19170f1b3b781b35ffd316afb1d55d1dda8e91eed5553780cb2714a93e7ece698b832e853e2589c5ba2b8a997bbbbf625071ded66762af8cad42 0025b7eb3bdefba3c5134438caf968f615b315204f348006f82e8d61057a8a8a853230cf0500f9d0b8c1551a59b9184862dd2ed9 a555cea36bb534acd2a07c9d6eb90cbf889988f8da5ba36fd388b094003c34bb4382c290f41bf01b4e35ff060a1a063e +5411708381a65bef4381c9e13a04cdd5ba0c15829f7f25ccadf695f635384d8e4704cb562741747831b33852567f42fedbd190d2980f1bc921ce01c17d659d4bdd7eb787b3927fcee659dd3b65132496c687f2249272a473d46326e66b3cb78dafbb522390162c168f73bdec88adb145e6afecd561979846ea4c8cee38dc1686 00673b3a2985c95904732632e5d988d8d437a60db13215bb6aa880b348f011c609a1e860461427a8cf0d622abc47f910f5c97ffa a743a2cb87569c8b9670f48ab8b8ab44cbb4779669713f43114c13e936217a38e736248191177d0a82620894c9894b2b +23757fa60fcabf543e603d8b31ef0cc99b3ed16b4816a84e01dbfc858872fcb79fd03d2f8a1d4f28c25dc42a39e20c34f81ebccda1682ee9bd22fe323e7f8ea90cf4a2a6ebb634cd1153cdc35f7306f28a2efd822bf23131baa1543d0ed5ab4c8168d3199983fbee117085f90550ec3ffa2b06070d3add1d707fc2593285ff58 000db7dcac414010b816236cad584dabeaec1da76c97182d1b62f87bb7fe2946a64d10430571b2b29ccf2ef72c969a9f045f1f3b ac438945f4e89961f3bde583b56e4182ca163582f6faa0188e0e354d1796045e83bd8d708f7e2b1028c5ac97eaee1284 +b976314d2f066f8893307a726f450dcf2cf865c170e90e6908ce9787eec48e1e2119a731b2bec3c12fd4e6282a393774251bcaef91af6ce57c63a8b45bedd72ab862cd169b7c84b8f6a72084ff823a96f2f8eff3483a7ebfabdabf0998377c5a6836d88135cf61c65a0ca7ca57727da68047dc635c17ad13731035fe9a6402af 004717efef16e1ae267e155aa1daabafc68515aa391dfeb73c13d01f3132bd22c984228dddc4dff4c39979e7585acd3f730cfcfa a343d37a87d6982af7b48b6fc720e68a499e64febb675f60229c441b828069eacf422ee00f3f656525287293cf60cb3b diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K409_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K409_blst new file mode 100644 index 000000000000..4b78778445f1 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K409_blst @@ -0,0 +1,60 @@ +f153cc61981a46d8a47d17d29ec157fa93fcf644beb84558db7c99c57fb131dcbc5b65581ced5ff0b29bfdc66ff703ecdd4290f7c353c02a3e6d6867f33f3dccd1a0b6752b8a35fa143f8921a5078af9c85b212564c5b795da9858c7955095938fcd10c21e35e1abe905e84c8b4bc05f2a06091ce876d9519b96951d08c7ac9e 0011c6528939672bed3e8c905b7ba594c3ce95f37fb28044f210cccd01dfdb42c10e8e1a0b5d6fc757834ca7f08e98cbc52b0edd add902d3cd6acb7900a4865bd9f795165b5936f70427e8739e8a3a8be24a9d3b96b9efb628ad9871c802c86071442eb5 +258c91524423b5c876432b1930c7b07b56eb5e3945f1e2296a4e5bfb9b9123f800ad195d6104641b1f1970bca553c2032f83d17252e52403a9381c1fc18eaffdf026f7537aa27d84c5e3d6e39e651a92a41139cec5181fe794457f556b390943093be719acd23fa1ddf7ff0aaf0479484a381a309b4f681af74bf97caef08c22 007e3b714496dd118d8f3f597961eec5c43d0265bf85723b0b9b0616977e0acc2cf686cb6afa6cdc19114e27ab000e762dfe467b b0319faabf5a680e21af461aa406ccf34ff7e86e2dd8eaa0c9e16d577d4e38736d04dd6caac24bbcd6d7c9d1f0a5dd85 +a16a0d6fd57240fe88c7c36b9f7f9040cfcaa9afc4beeb8300818c5f90cce73b819a12c31d42af33146399cdfa4ed4954d068dbb0f1f342269dd29f1fe357e7224304b67b0f924b794780fe7e6aa9dfa3380252fe7177b43e7b1789718949b9ec1b943c83ed4399491482f0f59d2cb8050ab6f8b5854d76c50651428cd29c40a 00182d1e937b037bf7f84144f7d4c94c935269c9aae7d500aa459a7a0ec113b232dcf282908eee4c84b8106cd38cdc41db3f89e1 8b71abcdc550e745e2892e2cd46828093daa277ce2c9fbec684fcfec6bdbc63d7d78960b1432e0614f83ed5bf34004f2 +d02ff569828fd1add21f6bd1c50cbdcd09222e458ee79fd5dfdba3cbb84e9d926fcf196cccedece77d5aa17f8c8cbf3a9facf0f02c71d5c1c8aeda9d75f6fd7b6f2c5c70dff992ef6e02c438fb3c66da5a503b3c39acbe2a069da457595b542190d818015d462670b0807c401e36b1bfe05baff3a8ccf8d1f5f8de7840e87993 007ed09428f460724c8a5225a31151e031d9949493fff5703369c401762345d002c4ce424294baab22d9e71edc4f854510cf0e6a b3b88c000de9f7e1934d1d1e6cc393574ad1266163b3082ae409577944e160367f8e26ad3a0153aca0d07cea848efe7d +57befce973b225cfce7f996fa5a1a43acd160681b88a87b7de04544eb7b6a719718f1ca7f559b6531bfc18fca3836d2be7f7a6e48387b7579a6845796d30e46f0dda9d82680f8c96c5f0989741adef9762c3db763cae2699cb6c112543635e20ed5cfb4b55ca2ccb32d2d13936085a8ff95ed658a54be73f80c912ccfe5f0ca0 00390f05b9619c27b800e99aeaf61ef7f6249367d5cfaeae3c7b523a8b29153eb8a77132f6c4412545a842d6deb7b7aea7e2bda5 81c31556fcd191911aac64083353393e1cdbf77d276265ac7f8d556fa918065f3d5bdf21c4ee3a49fa9172951839d170 +4277ba40cb462860ca722cb4ee71c61836d2ceba18bc91f3fad7dea478972c6da0ebc02815eaaada1d1a5e93d7ab353855ccfdfc94a5742fe18daee2328871e06c1ab0a9a989d1239df2d2d27f96c415e7ef9a941f06c6790675361173cc229aac7045f49eaca207f59c497619ba32e932b5c1c6576812ee5b146e2cc7de5e62 0007d18652732596add3db31f7a0ce6020d03f3df58131b0c7c633faf619b8210cd309d6c0c4083aef1a1b6d2a756adad0bfe344 b044f0a78d673be7935689501c83e8cb3a2312257b9716e11401576c233d2c3aa6034fe3738f98691396bfed4bd0e82d +57ff6792ed4b12220d179bc0ea57ff217f322c85bd3676a681d32d7e4a3e0c8e891fd267df17caba5992f68c35ff670b60b4bbdfff82404f6ed996c30539bc395120f97d4d7a652eaee82bd8f9360bf8bb73748b8bbda9f9480eb54f7eaf2609d4259329e8a5ea020521e7dbd3ec56f23c849932cbdf2875f5d5c774a9d6b0c9 002a91244ea4623b63403dba807d60b914ca3b901a2523244c322f2f11251446d3f15e869d086ebecfa1a39ce304e8b5c8de23e2 b4196e3b939c8848968d9515dac8b262479c59958cb977626039fa6e312db4de97b904c490c816a657c9fc8d93dee9ff +f85113eda64478f460b60f8084220134933de049200a5f37884da7901471542e26690a5fabc3cbf9e679ade71b6e54d869bc136c3d34cc4a9efcafb777abf046b5ae5429136112a9a36a475121eb1f33f1f43481286fc1ada98a41064a1fa38c89e99a93065bb2a119348a9e452497fd5a0d2b83a66b09da9f47a0583732adf4 00068c56c6b5d50d1d4e13d3837d8c5e8ba2f825e121b63e97603fdfe78bb6899600ff0dc87b6b3b6868ad0d2f62b7b7a31603ff aae6e73f949f0d0ad32abbde44ab469e117abda64d7e928ce212c1cd4dd4db0c72e20bf85feeb87839771b94f7624cdf +42811e9ee6dc509572e1cddbe5baf00afeb0c5c13e3755b922eee9e210001676082bc9edc3d78db2b5bebea7a2c0cd2b369226c2b8f83b28f33fb513407ab9d287d14b112d6c3be2493805ace5cf6fd366d03cfb28f4ce3f0f060880db64d6962e997463ba7c05b6fcd1e66babe4b94afc5c2d38c7050c69571d27b66ef0090b 003c88084f8b78446db431bd6e240a0c050813d2a763675b0ea869cbe183df697146cf29c03479af3d34587a95cd257027fbeed8 b18574265fe0ffb830eba326506d74eb7048b02f97c8543df410524f0d95192a9458660279c72d0579abcde800b18651 +b38f76ede7441ae0887e689d556f43155b38dab7cde487ce9ef9a46f2957c830d4d28006873fe2368197a6931f6fcaad755102686a457a7edccc8d344e2d2a9162e3d71d41c09a022539ae6d404955a6ad748231aee1f974d4f159940532fb3b1fa0254bfc5805d2fc68696856fadea386c542d3cefd1be3af04ca595e54be25 0051af7b63bf3297ae20517faaa1552f4fde65819dbbff6a52721611e5b7dc1242ed6e69768cdc37ea8cdfd1a5971f06b84b5803 94dbc530f80cbd52beedee5a6fe1d17da3d74326928d052aee5118abdba078de4fc22b6a345964d470d2d143de6f6875 +356dc86cef7979148e995fc5abe2b14a7d5e4e42c9b3509b4363bb80c581a66f4e7e4aa53a4bfd37f9a7eccf75fdd726f348f6a3f779e6599f61bd1d668517f40453b39bcf35db0852a6a6218198f52b7ceda2ec55fca5abe8e5d93af9a42b9ae4de9530c5870211bacc27c39aa094013db703de2fd3121f08d7e97dbd4e8946 003d65bdec48972d03811b78150a06956eb22d337dbec5416bbd8185a6322cd8c0ff8000210dbd1326422289071cab65175f5d10 953990e2ca85384959e959c278582256d2158b12d010026a78bcfc4a901ed554c545bbd3ae676705c5c1a24dae9ff46f +06fd39a50bf25e89f1071ff81fec5d1e35b6dd68990414ee403dfdebb792627b6a4ae3d2236c159e4441ff90b61ec87b1592c538515f0486b19e58583394a05e6411e69b4285d6d6589982ac0eeb2c912c4948789cad741183663fc070943389d4e9a1150b8f6088fc50605915e9e24b2d98a1f539024770e4820e14ae42ea8e 001f1a8b5f35dbbf82c102df550c72216a243f986f0325920f6186a16d1da74228cc02be6024c7411160c183c923c743354f9438 908c61b2aa95a34d256e6e93d8c6150ab64cef08a7aedced7ec76bec216614111c97e082fe93c784640ac04ae2467951 +6daaa41150ea252a3e966a338377307d909b95080e006f13027f2be5059d9208930c5a329994c0b794ef50eb059bc6c215f68cf42260bd410f9bd86d2ad5ab7179c7c92de4a93a5f6aa17de5aefea815e7c0b78a8cc53c21dc4dee037b29c9df4e12343109283ffd5d8a3b81fba1b5e95506c7e01ac056c86dd0ee23bc21af0a 0031dc621200cd174193d95e9092ffb86189c52cdbb9ed937593f2cde7c4a0264b9100e1b8407336c8dfb5520d28a18dc4e39a89 aedabf8ccc72861383265660a717803b303f45b217df32fc649c7cab3de9577588669e51bf5dc92a95a46522999ae220 +6378dd1c12c5197b57d47dc46a67949bdd1e0809004e94d49b0234126a08ad5bf8723ebfd132145813136d8b7dd096f56c34248f09a65c34f60c2f80f9a51b3795f3d2518b11aaeaf6dd45a323794080b78f85d629e5fa719b6ab0b14c78cd908befeaef0dbfaa08cec9318bbcb376d48b11b68735c9554a45293db5e9239ae1 0016e6750245a88340b0f0665b890459f8038e9b1366f2fc1326245a88d4c523ec94429f21869ce3dbf75126e58f77241c99efaa 8976e9eb55c506addb71101570e6a7d646d2d22b2f5d609aeb80671b6583c791035229ee5ec8f1cbcf6b4589099481e5 +b898d0f9bd80e083fa541f457d14d853bba55b120424a95e1d9511c8833f48444329e0349d68204c4b4581ef1c4dee23ed0a4445727a72e1e6cde422f7c10ae132a3fe681f9d741fda263e73f7cdf10759467c9d76164086abf6780ad474772771eee22d195339bb8f6235e0d992bbe282b13ce4fe01417f507a2c4fa155e108 00788fabdafeebb72f6385301e30024b56639e629a400f9c50d402cfc9b5817844f06a451fbda29c7ece41dc9ffcfc625fe0ff0a b159750f9c93c3ac295fae9278b2fdc9eeb16201b008460aeed9afe7a8f77498b665980a9f07be97a136b96150dae096 +dbe04561ea8579672a2b3afa94426a3cbc274b55263989d41a778bcb082da797d84d930ca847a481789524940701cd5f1d11b460bdac0bffb0b3a3abe1ab689c519700de85a0a571494ba0cfc3c865450eba7a9e916b7fa9df55e8a1c246c992e6a0b44b78274e008472bed8d8411633e6520e1a906c5d0c8aafd572fe6f1f64 001b8dfd64563dc219d6eeb53f2e3ad1d771140d0960b211dc1f757af5e297dc7548d6133ddb574711d466688f80dbd65a7bbcdc b01e9fe9a2231bdfbfe22e93dc7633c19332f3b1b36007dea763c221b968e44c1f5c4582f74b118d05924147d066b93f +48a8300820fea2ad83c83f7d6b24192715329c3f159d56644e11ed25efcbd3d31600a813b909812987b97d1087e74a63b4494cc031c63492b6615e9d6e5b36f62cb2ef88b9f736595800de465789f43811165a5fc093ee6d776008739de8de2a84e878748641be8bd52e5b891c4145f52bbd46644852a43108e93d86352b2a3c 00422131829608ff730c24ddf7e8b4a2600eaa9681eaf45432daa7d41fe2fb488fd0199d431a1ed823801ce21f4f01a4dd4248ca 89b52741449cc59cfa8d9239add1086beb9da0bad8a48c4882b7427ff963e668bf9585809edcd87224e2adbd19b8f4f6 +276e3a986ce33256014aaa3e55cc1f4c75fe831746b342eadb017676b0cba7c353b3a2b554522c12e6aeaf1364cd2eb765a404b3d0aa61258194a30219d76d2bfa98ad20e7e91756cf65e50d7914157f283f2ba3930c0ad3a97532cc747b1cb9c806fff497f0322025a3d02ff407fc7b5808585b91d95523c9d5864efdf7d983 00095ae8e4c7e55eb5da01acc05ecfe72a4dcd8ec152f1c8dc165014f70eb4e4a7861aeb2b96c418b2d4db58659e76184e013a49 a86e40f595932f3f444ca48dedddff4c4b2a2a34ddcd1128e2ab9958091acd2d98d89c46e248451988c72a3bdb879902 +6a4fc1827c3a7256faa8ec6a0f3d23559d6949f8cc20e7f76111dc4ebd59213951cbf0eadacaeb8862d6baa0cb298645e4314b1c303bd0d5e9893304d4b7fbd36ab05fb6a5edc3fef763e3a4124d61539eb616b359c5cb55b5e2bec50c91dd95fc39ddf521aa854216eb5a707819fa6f067b316a17a3b146e7cc2dd517f7d63f 0006f2075bd730f34df111ebda919167b1d3358ada32cd6747cb3353bcfb814a77ac70cd51b31a0e538539453bf9eaf9d8b384c9 a5d0025da403e52dd6ee8497d29bfdf5df59c00bece128847c6113c7a45db4975476ba10fa13f3a60497594da19d77a2 +4b088199bd8c94775d8ee508377d672dbf50f6d2c7370e99821ec8f9387492fb2eebdbea473ea18465565f79e2af418555f10c4a527e05a9e20c9c00b807dc8b350cd4ccc2d87e91f66addf02ce4f43597aa258ac6fbe9365cc2c8e8bbe5c884abc929710e8423cd6722a8f473bb55804159a92a3d8b6661a536b4fb9293bb0a 003887d284e9ad17d38bc6da9d83c192a434c509340a7f233cebb032b09ab7c4c6e8730b4a80844898616c9abcd16b753c6bb4c5 a58e5c459d72023d6dd4490e72b8b35d91439d49456bf0010738772d8fc29a4758b1473eeeb0d945ab3cfcec73b897a4 +848a13465ddcfb2dc14f7bc0db0756832c22dde1e31e4d8b3ae0dd1aafbdf15e954889e95d3bdfd6e5ebb6171fad62592c23277a89e8ba53978c9b1afedfef7e1c3f6d9f31077530460b47834b30bbd84a4da601be988738aa815d3d7e72043243a5288751ee08b4815a017fb5d9bd55833698a0d526b1ed79da35ef0fac93da 002ea5430610864257c9dc393c3addcd0d8d5bc8aab1067643b08857210464428aa85cf1ae6c743fd2682255d4c8eaa46ca21e73 a6c382c5e7185a91b5eb050c45ae6471c905adf0a7e54d41b7165bcfee72947a73b2952920e9e34525f55256f8284944 +d1850545c04ea65528849973c220205c35eae98826d169348970d1420b4d872ce233af1daa9e62f6a562544ae3a0633a954a493e9766dd5d87e47486559fdf86229a7c9e1726de21895abdcf2422d438f4ad98d88b45c56742694ad5e11894253270997c049f0f419842482f21c792fbe5613e2defecd485585f1835b6f4c578 0062c757c92eaef41f5d81169ec4968145b5aa2bc1d2a3a5fd000634777748ecb93677b3da12e3be33272a8f0a52300f4a5a37c4 ac07ff8276a8beb4dd2aff37c3c3bbb32dab59d5526f91b574022770e4e85173dada25b2f4ba8f629885ef0f5c05e116 +421c9784d6fd507c82904e1054edf9bdd1efb58a0b211340086069ad38b7b0dd15c2345fa8767ef71254ed1bd5c35f742b1d3f4765ff9007a5477ba9e5d3d5a5cb5fab4efc1cad73701d4776c6c4343f42b5d94a9eb78ae428dfe5fbdd8e6ece09d5b75cf4346cf27db856352225ab04e6ea56661554fbc39916accebecb3935 0048a313c0c11489939fc0cffc6ccb9f179093c4e13141b92dbbaac441b7ae878c9d412066e95615174a24692555cbbe904a14cf 929db85756389c4cf35b0aca153665105909423f3ce794ed06ac54e638d4ff8cbaf9b23a8deae249e6c77e1235a34136 +7910bab15b6429947655e33a67f41b76f1d7b71534f8904d6a0472c2faded038565272d0b5f51aa915e0d624e9ff48d50ebfa2f09324864f26c29ab73eb39b436c5c459c7cff4d2b62992e3489cb4ddfc05d7366b161a463aa1b782641d93507de43c8cd0a0a0a9d1c644f4554e3edaf7fd794248110ca9387e73ae5d00d299e 0046e2adfe5d3549e1e6fa1fe69a7cbb4ac9b111c8903d544268f8318b0b47d4b78fe3e56eb5e639ad5382e7cd5bd4b2c3e70ef6 89d73e4df763c18b3e42d6f7a072b2b21c1e0b36f673bfe5ed64aa51867e3358107b12956da5c2ea1e40f701790d38a7 +e6fc96e060b956c25d50ad25443f3c30a12d199a47451a49ce88307201dfb15ed816982e8888a28daa92eaf3c5584ca6ab2ca9e14577f84396de2e0ac214b24a2279f5e7b344fb7387e9afc8f0a2b77a4d024a20ce6183499b17096947444bbb753d9b39e5c694239d28f9c454bb05468d17ab564ee6cea3741747ccb7f108af 00480103fd6180a431c837643566706e2b9597de0a1346a224d176a5b2c54aa4d064418ed654a5d39f4773fb509f86473ebb373f b819021886b1dafe225d9ed40b43076d3f07e9a408dc64996e85286f6cef8e0e525e3105a763ed90009689523de255c4 +c8a8a0d41f35537e6fd523ee099eb45e1ad6ab54bed4d3e315e20227db03292e39dc1a91bab439c0d20e36e7fea6ef08983f390a6b5551ac3b4f1895220b2867fab95552cef9bd8702962839bd9b2c72772640e7d3be3c5889d226acbefdcb448432bc503e5a5fe7ae9ae7696c720a799f9882c64ae0385f656074dd8a6821f5 0013c489e8311c6bef02c8f58903b2ba2a98a27cb935d75a30d320af9a14fa3cbc6adcce09235a9eaf333dd05f4b2f1694985dc4 9640d607fa367d85d85d10bf2afdb41c0c4c3585c0ce08923ab18cc62a3f593b6f1f6579e053753099287380d80286a7 +3407cd6d2845197cd7414a30fc3df7184da204222ffd65c4d16a12cadabf603de8043ea14f5e6ddcc22d3572dc06dec1a23cd924e1847ae285ecf01754e2d1247876431eb98e897e47412a2330bb32990f9714122109e94b38f82cfdbbf2eeb4c6f88f5dbf9f0ccb47939df8be321dcd9bfd9bb99cac9f94885fee7d443fbd87 002419bd2200f8e1d87db848b0379741685e680d9affe693eed49d82931030b6cb05d21a4965f4e1df2045c8513a8f574ca9f2e7 92e64ec27a7b2c78207ed83abf5effebee272d9cb88ccbc779c548304fb01c61a768808175cfa0e7330cb5ba543325b2 +ad43f8440071285d01fd79244907803601aff4bc5d14c77483a87cd742144d41c68269d76c9a83c09d2178bbcbdf99f927b378497ffdc907a75a3b0ad019e69758dfffa480871eb6e1e17c8539373de611a557fad120d0bd147f8debe5f09a02e56fb607e9c1253ed592071f042e42fee39775b407225a2b86a950d81bb7d7ef 00722951879a65bfcb414e11712ee9431eeb32319e0ff28601112f89276ffc2b96eb65c7fd77d023f09914a53e2aae2c84652bad 81389e6bca8cb6ee2a2e8383e911d43c33d813d76f455ec5f4520c092297090700d6eb8078a8c5d30dd5fc5ffdac9958 +d61a3765229dcd0b4fa6c57280f851ec2bd54d3ee2436935cd6d94e0120d0844adda163995fbc4cd9d7275da859ad8ebf30af9efbdcfc31c7c9ef42bce9011d37cf9d15fb018e117bbc102f7d05750e5072f73d02c2f45509a55627a78cbd9082cbf36807759d1fe2ecbb92ab30cf28434941712d38bdd100955d611987b5968 003f5b5a772d24bd5454bf26759dbd433fcc7bae4f5c593664c4d75da0cdf9430d7d9162bce3d7f6e13a344259da5a7d6a1635bb 843e7e2b52b4614c12421c0ed480327307c6716adc27a80e639e354f532b52dd3e8e1055433f7e0f6510dbb16a340cc1 +1f3c23636414ced48fab6763eed5b22537968e6bf08c178b3d31fb1f6ea773c6979759701d94bc1bee7c354272811edec58eff50c93331b22723d460e56dbee90466b894354777b23b13a37d15a84c762caca70c01518bf34d0c2f072145d274b3b6c932b48bd815fe81161d8507ffbc2f783bd212c29b2887af6d2ffa9d2b4d 0046bb4a141c9099d531dd23ac440eff1f5b10f7cf34920b6b702311d490d25344c665ed5211d401def24986c8094165d10f8934 9104c5ac501f5b589e195ce2cba670ab9bd50ec3f268f677826bd526ee70062a782cbbc1cad3f19ec82a2f2e00837d75 +ec69f2937ec793aaa3486d59d0c960ee50f640a9ce98a3becffc12d6a6c1c6c2f255d37d29f9b4d068373a96beadac98fd5203a9f229bfc70bcd449640165ae5128e3f8d057769e28356e73e35d8e9af7876f608390090892c67391ddfcc1c332aa61efbf72d54bc615998b3be8ab0a9d372784bea48c9fab244482c75cb2de3 006f2c6e9ea8109223d9a349fce14927618fc4fa95e05ecf9aba1546619eaeaca7b5815cc07e97ae8cd1e9973ac603f84d838393 8fd5c3ddec787a5d31ef0015dfda1d69321cbcb3207bbcb78a9f59d1f48e9ac4ca0702d85e0b935854f42bf502e80008 +70e11efc78d7f079ae41ac3c31c96d3220f4abfe23814a2a4a78d9b1a25e838c3408bd416062e4b0a5cdadf0c6e16a11e00f59711b417751f5e4b43ecad99efbdb2a81c91a034e89edc94eb552c3eba62808563cdf64453a1db07daff8742aea4a9fa738e1322da316b26dbca2954b2bc0de6da7518d28e6677dec6ba8af4285 0004212b7fd913d794fc6bb33e0276e349c052c969ecbf6afc89b28f75a599a9242acf74dec9f374361ba296ba42a38407f9b7d6 89c3dba65825f1d842087977927d69baa98b6f0a9c032c928220a12d4d10aab2f8deff09d04e4ba428fdb56abba559f4 +d922fa515e3bed60b517a2d37cafe4c041e5ab4b5c8d8d4011bf9fc4013dd8abf7add71fcfde5e71d6abe76bd0f749e960cbed55711c87b5629a2c39cff48ed7d0feaf5cc4765e576a4959521f9a45fcba0dc65ae618826447e02ce6e1cab5ce8d6c96c3211adbb0660de7df7453f3aa726016941d00d8ee536cc106a603d126 006baeebb5ffc89c94c3e8b37b9b0904e7c4b251d204894655bf3b1235710215c29820b9d401c9ca7df1404d2d62d708aafe208a b6a88eba2b7141d42eb75770d0644d0dff52ca76ae898152db50c4a8515b5faf1732c39b0f1e5152499a4c7a40ec7ded +4f64d0f6bfc542a0d4347576935bd68ca88524ead03b8d2c494061d0658e6c3e14576b5bcea5f2f992f54cfb52b5c7cf1dfc517205e0454510eef1b7054a8cd06ab53ed2468193f98ff0dd62faf076549ab2a270f259276d5729996c120792c6f466a74ab65035bf38ff2c055b43e2a8b8e2449a2375ddbfc18242157bd905f8 0008e5f66ba53e7caad1feda122a80c32c82d2c32a7237b8ee8ead44ea8f2f01d77c7056b9dd60b92d051f060da8532c1fd0e8f4 99cda8bf4a76a15f4ccefab1835df8d8f255f7565160ed931f85ee991fd3f930ad208c5b1c6fa11befe0832c3640aa85 +7047d478ec5282d55db8c19c97af10951982d908c759ff590f27d57e2664f08d526cbb2bfde39bdbb1aa3dca5a8d3feb50b868be6651f197abccc9d8040b623de367e2ea1d20ecd302afb9e273f4be9f3f64f2c2eb3f92d5e0e375db6549da2a589f0604bc7146562ccefd15995a7c4208f640e7a17afbca69cda4e173380523 004ecb22b44e809f89b16abb10be062c89b41ee34e110403e42a20ce59a99afdc22f6f6dda56e1d9d1b8ce1d057f390db111def3 80e184d467abb16466b6c616e144d5a28f1211f5225ffa6fc47bf94454ff7aab54e563dfdb3b28f67b6b11fb17588116 +1a8384b4771a410663e56eb36c5d9ede8d161a8fb0e31d3f74bcb017b9e31232bb2e2f4c65a2d85bcd1cedd93ef08d4bb4af0095731574ab3f2762788a1ba3bf0ee46684da8d9dd384432fee99ed3c69213d790a5d81b351063eaf2bda71ca4868ac36be1b571024a8bf09039b347fa996d5d161078314e24b7d073e05cb3d48 0051f9500c15ae73d6d479b9f3d2caccc2039d8d03820befc2aae3bbaf65d59bd9cb3c4e3aa8bed5b3acb70a5566047ffad80729 acba78c104fae5b824ddf05307a146b63de51daf64fcf8904d56a23f736fceb74deb7a293aed2970982300dd61a65b4e +43513d6dd8bb0af7a6f5a2b35f99957d335a48d54f2c4019ce9518b35441d4935518976ab1df37110b5b53532cd9e2c66d9f87ae7f683d7efdbe1775a6c15eecee84c6f879999d0706f6779dc158c111fe8d7201983883bc8334f51dec60004eb1087347bfdab20f8f2f260556681e05fdbb8a6139857fd3bb2df5bc1f2dc143 000cf01dc4462cca764f4f8cbef48c51980737b9b98d1384b8de9f4c733829db7718a9b5eaa46a8475c2144fe4454cb8eeb0a443 825f321c4a64518c9e953ac374c368e6bbc2636307de5eb1e73838d4a256e56d31662206c19d1b7fe093d6206e74e217 +752300bc5066d0efaf807183a41725e349907b7339d77c79921ead3c685b616b0eb97e708f3880fce0136c510c8cb53b22cb424af6f1c34633600939a0647c02d8f9601f9416f1d24a51657241fb559c25dfba91402cea43bca1a13718b3945b048725f3df560e6717cfc6ebd894e29bff1e0c7763f15b8ea93e67385f059598 0063a9a565497974c6dd459bea0d1196d74f263f333c31b7e8591499960e1cd79e2ef4cc8709f6d54713f873b16e7b0be42f71c8 96f75eb04e70edb9060841c67c96d382449bb66e2a92b7fe2557afda754d28fc51e17b8798ec842097c28f342592db83 +f620603489944769c02e2f902c2299dd5f32b5fb463c841b7e1fc0249a85d2c31684bd3daacd97de8291c5d39e84d6e59d3dde1b30c181bfe8d31b8d8e080bd191690a67fa00024ac8c1b10981b40d4f88789ecc58fc69b15417fff34834e23453bb9933a43d08afab74d056f366b40ad167b51ee5f008db151a12b467d3eaa2 0041074dc186193d30aac7cc6d269b938ab40b257d095e54ba79967a377a91b8f73671470cd07f0a3d1db7cf0a31ba9070625e43 937702f0ab6c639e62865f09249e95995f524faf5a856c3ce69fc4bc2196919cf895f1df625137058d6878ab6774d518 +5575f610762b42ce4e98d7bcf45a7a6a0d66ec7f27d6b8b17f1961249d905bc7e58e2ce0806d467f106b16285dce4544c72666d08b5e2276cd0c4e13187cbda8aecf57b1855afedf8fad39ee4fe009f204e60bdbec79b123456ec2d85631d382b8a2f2c7634af3992e4707f7b4215e2c9d3b0aa8fb08267953883a4213669d33 0010820db54ccf0226161aeaee79cfd2797f87702b4ee91adf8543b3c9e79579d0df8a889e366ec1e0718e039b87a37c24d620e9 99df603b34e51f47b8c786b23358749819049b93a35a07e27f6084ec4a725c353f1b38e18bdd4e2d5bcad75c8d399c00 +81cf067411dde2d0ab04fe5fa1e28e6975cdcc571588de60a35bd956a535fbbda4affd0803d244f3f7e6902a2c9a7ef2488691b6bef7f8ffb33be09ccae4c5285265e4957f7928ea5cbabd6823297f59a7cfc9939a49f26bde74c4c69e2d38c1efbacbcfdef011213843158072be84ed3c1781f67a0e2d4e9ba76a585c17fc0a 0059d2a06e8bfd5e14a9bc8777958b85be5e97af892d2cdeb0ecbd2d5017952b5042349db5fedba2e26e7b85bbb31ad313d99434 8dd96f58cc38050f5e5a0b26b8da87ef056b5fdfbdd9660c2dd3b56296dcf6325f7ea555943ca6e9fe66bf46975de237 +8ea18387940035cff2f37278d321b344231075db43c7fa7fee9bd3fdefe5e8f03e7af9deafa1022eb108e19ec11fae34536a4fbac2e8c8139a081a997c080cbe8f3e2d2a72ff26edcc5338b21372fa1498e439e4d9bb12d51cc539f859047957b1b1f1fc30b90231eb06b365a4d404a1fd5a0e5cef171fc95b04d0b557d78ebf 00405590893cbbe18f4ad99df28b5f9d17f8f1882269aff0b7eee9392859d68927a99c942a3075269ddec6d69c0df2d76ab9d801 aa43e7d6f1c342c56aa3f425e72f0f8d307d4904a89a146ac280d36d1816bd042da22100d032a4628a33a9befde57450 +6a253c1aa17b2b1e6624afc8e7456d366ef5b1bd78e740538260f395481148a64da0b6a58cd53d7e06c691beae1a616547cd95c4d259a371e51c2c0e334c8a5311ae31e4c7af325686ff9f7a36f731010ee1a9b8a29169ceac36a060dd23611dc9713c615424888bb574ad5f5755d7311bd169336ae986c977a394bf16487c4e 0062bbb4f565aa0f23b88ab9029d33b995729d10fcfc33ba7c4051e2fbc72f15636a834e3ebfe604b927cdfc89f53c57f36890db 8d2f2118e3e7916c4135efe13b7d7c8dc69095f8dba94a80821786dccd9e119cdc3affdf47df96c3671b3823b8eaf356 +0f91d0f0139faf3b90a3d4bebd7e96ff6bb6f90f6c68321fb392637d8ab2a60d649a7b7364ee6e4e274e1a8d342caee36cc11c56c54247fb0a8e8ef81ac4322b454dc9a195dc54567bf47ec8d4fa4cd32e76d78ea2d08bcbce3edbb68fd8597e56d5a9f2df4e47b2701046df89615961db601bd8204584a6a6cfbb627e2a1190 003fad7031cf8810544a3e4bd1382c0a2e22c5a9fe4804ce67b27591fc516ee81dbac841d399327168aa6abd79e2b5ef85df1528 965cd778def8b469c5fb77081d1d659939acede0109876367db1cbef6141aba46badb59b1f6d1b30cd86e4ff3d5dd454 +50c17c1fe4dc84648e5c3c3ab8f7c971d4c58d8d56d2b5ddd92e35e6792111ed8dac7644ac8a07ca8bb4e38e071aa47b22ffe495e9083f9bf781ac1b5fba571862c909c7aaa7b8d05ddfb7ef61c99700de734d5658f44ae9fc908c85a2dac8e7f854d6d24be805fcd7f873a91252985c5c73129c60177ba8fd99daa87b25a073 003db41b4f637fe7977c90e4f1a21799baaddd1826c667102414877138436cfae1b9959842b8097b5276f15f2b982ee59df263c8 82205bfe8f7827ce925c0f473445d6ef26310337bf8fcb249d415dc0745305ddb3a6efb34120422c28434538d8ec107e +3583a3226e2dc463a462fefa97024e6e969c1b13bdc1d228e2d7823d9f7c09012390c2535baf086588000e908309090daac6e6d2b06d2ede6fae838ed47f30b5b481185f607a3586f6dea47c8f84e9d3b96d5b0ebae2462fde1e49d84d36658e87dccf5e30c0937feefd8862dcdb1a1ca373f6ae41641502ac54df6633a8cec1 0065b76c6093d9c49591293471286df1a4444e60d9d06cfa114e175afb5f119d2abeb273b0596019a0ec5db5b5869f2cc827b364 80007e4d8de6badaf77ca81a0686919b4856006674bf99f4c2cad6629c1b53820ad795647935f316f6fd9863c6643c1b +60ca58462d53d074b370127132f4e59f5eb8d15594dc721a94286afd082a8934e52462c9c1c3910f8b50d7aa3671dafa5972958d876d7992467b2fee3795a6f9d8a7bd3003a8582ea8c003aa1e02c08ab6804d85bcfa13a815d75c938671f0af0706c68bc70a6155708ca755cac2fbb68b2952208d63e0e2e3d816f04c61bc03 007e9993f3fc1fdc4c376ef77ecded96006ac1159740bd1b2dc6ae3d97e15a67383f1fc931e460b9af3fe14a54e47919667ed06c 8065e2a0c05f00cba5c313abc61de769d48d19ab24c12fbdcc622cf7b273924af8f6a77d04101f731680045eaeeb5673 +c749f9bb92ca9957ca6d0124206ebf65e860ff38a225e241950bf4526cef3f4fa9184ec83f71f813fe852dc08eca6b45b14fc7f2c6a19296529bfda007efe9d0d26492de2a902b45ed39603e22f0a763dfa5deadd97ef6feb859d860baa2cfd1d066c0be0f9f4e0e2fafa69cc51b12e814ad2e33b0acc0bcbe1df8cf018dcd4f 000c11e2979498695c660a2bdfd105b115bc4ff8664ea15cfb40c725406c6fc9a13027bd1d72ffff6258f29e4e19b845243444a7 86ff9604738d21e37b810a1a8913ef3ab8e53d7a6f55af536eb2dd0ec46ddeaaf5af9b3a93b1ddc7f4dbd379747fb911 +4de8414780ea20f7943b1f1adae5e3962d96e828fee43bdbf2831bd71bd25df2976a3be37a7a667c7fbe1200de578920090d131a750c9bc09bd95b261234ea8cc25423c4ddfff5656d6b32da6e2f6f530e6673a8660aeca31273bb9a3a21bbd7031a2fa71ba37c004d3d1c64b2c0798783e47b2efe1a208959ac16e35d444245 0068dfc23c6635bd1fa1076dcbd456ad6e8df7ce7c1370fe275803befc4ffad007fd062a61cf1d50b93aeb9afe1aab47a65af82a 9252db399e83e443aee0b1555445ec8fb8be390a5fdee2f166b1635e06f60f9f82fc1bf718ecb5d2c20790db06c8bcb2 +a081d54232f84bb19dbd52ec3812748e2e6486f6cf1b177b27929504ca878036547eb43531bb5b3edc81bfe105370427e92831d2239cca0106d031d9fa8da9cf89c6fb6401377d5936b6329ccad854e5567181b8f16a37c35f333eaa0ffe91d727d183fbab935fdac2d5670dafb3fba59e4fa2df1746c58dd8360fa08af7f4e6 0040807fb888e1d9fd33604546656a493629d94d4a0a9de2608962225ed158167f9e2438abe2d12a11e2adb6c2b66ed78215b0b1 afc18a45caefebff2ea640f62292e99a512fd5c8a07df204cfbec6b59910ab56f9988882b2b3b334225b8fcf82112fed +ea60266f1538565b3ff42fa4bbfe319be070329059c52c8bc04a7da2824f209c1145a05e551ea59ded8ca8439c328f6907da4e81d658937df614be98c7b8648818ea80ef40e49aaa4431f4a211d62acf2611f5d60c446b2b25745078c643859be1b12b3141a09ab765dd63ea1f2a2df015eca0840087a5db378c4c4cce76cba7 0033bda0a02badae08fe40c239b9d59e5bfe1c4d4b9b7a5acda6790bfd77ad08dde5e93a2da80ec54a7f88146d72218bbb88aa10 97ca6169680436dcdfa1d5fab2aedc09fa901db9f59ba44a775cc4d7a62be797a0037f99006ee6872313aa2aac9a02aa +82f38c9405ef0d26bcdd5b3fce4fb0060c3095f61403418e17c337933f0563c03691fabd32ab5e896c593439e7492a9970ae325c67196d9e83fe0f9780409a930326f7e6efae035ef8c321cb9ad12461edd5cde66c04739fe079db65406b3c2d22f2d04b1a4335285513d4ceb901d2ca2ad10c508302266c2cd6079ff14eff4b 004ff431769d26b8837d3e1295f5464fe82be29edefba76323e92078a6483ea0daa96221549102509a1bdcfd46a5a2e5de10c39f 806b3842f2b0214987a5df26dbff24d7c4f21b4f0026ef6a7d8cd1bbec80f2612273245c8739a4f26f8a26c78d2a9343 +d8506fab4f681ba4ae86066aed447571eba4fe04e6585fe3be6af2ab1000a3da68c5b0c711a85ddf3a40cb7c8944eef81f2094650459e14f5b848e6add7e580b0198070f873eb3ed5d0728eabd92bc1398764b94cbb4cdd7cc2027b9762dd10782658cd9e8a5022ac062fec535d892198c8a387b3d2b6f7c92b1af6ab7dd9e4a 003f85ca1169ca7e9df44cbc6bc7d2868c9d94e8f8b699a42ca492dca0914eb5789a9032218dcef7f95f959c9554a1cd83360439 9420049c12ef71c6d79f2d6e654489f900805ad3e6e2afe9ae2da1dcb346c7717505280701c14eaac71ae4aac3c316eb +b3f30d34f252a4c26f396079e773142bf61c0981d912333ade3de4e27cbc72cd8a16b31807f0c46116f87accb854487d83ec8c6a61565e6fca145eab70048245db08616779d7047db63aabd90dd15acbb05eaa510072c151c0518f1b34582b95f43ec7b9484b2993c176de79e84566764467f72392ef31619426d159c91816d4 003a97deb36d68f81f50c8829d412ee5de7f9d775633cb69c09dac558182039e275fc258240517a7c4aa592e364765321f27cb12 913c645d62971a5411fcb9b66376590486bad30b80ad700329ac200349aced38a74c160f16ac663b6ee112d46c8fab52 +0fb13b7c09467ad203852738eda5ddd25b17d330e82c279630b0e1f0c86681f67f6e537fb00da9419114973c8559306de58b0387d86e52d821d982a60769d2f15fd5ac2ee6dc55d8ac04ee247282cb2866b8cb8b4d7b4b6cfb33bfefdff09a73d727193e5fb939ff66ac5fcb644a44f9083a790888cc538c5eb435243c6a34a8 003b1da0ffed24e1a3b5ba22bd684337f6b08053591620541bdad50c761d66201a2cf21a4cc636426456525b598e96baf97d9851 906f708d131ceb7b8a332c3b1af2a36f10e7fd0d178a980c1fc62727a43863f431b478424cffd93469b109c14f511bf0 +f9b8124281628cf4e1da0cb4f021c8d19d815644cd80c7c8de4cc62722904ec4cddd26cc4891f30b15098a25ba6923c6abf4774deb6e1883fbb409862f94467e75a725e7154be860fd58347577c83adbf18535c54b102220197afa062cc1c84f6094490ce488af4a08d2c5b808a2572e18a59de96c87162f88413795351cedc1 0040bac7e0d3b54c7753c79d43469e310d876015d948fac4e3a9765444754476af72330e88d79ee6119697aafac8435ab5690754 a873ff9f09a7060fd628f0e6370a559232d383127b2cecbcd3d790eeac6b7a28ea5b13ef1a2f869bc51ffef962269a53 +4e3cd6100520db050af0daa69fe3cfe6603a223d4f2a6318fc5836db8640d4c7fb80bb781302036d2d6fb8e552b4eaef3133b98ba2d36b9ef0b86243b0391413c73d48ecbf1d19170f1b3b781b35ffd316afb1d55d1dda8e91eed5553780cb2714a93e7ece698b832e853e2589c5ba2b8a997bbbbf625071ded66762af8cad42 0025b7eb3bdefba3c5134438caf968f615b315204f348006f82e8d61057a8a8a853230cf0500f9d0b8c1551a59b9184862dd2ed9 943e2c41bfbbdad7abb2b0eb2e714e24ac841ed2772dc64a8b7196f7eeb7dd1b7e3fe2424e67688f8c5d483743bb65ec +5411708381a65bef4381c9e13a04cdd5ba0c15829f7f25ccadf695f635384d8e4704cb562741747831b33852567f42fedbd190d2980f1bc921ce01c17d659d4bdd7eb787b3927fcee659dd3b65132496c687f2249272a473d46326e66b3cb78dafbb522390162c168f73bdec88adb145e6afecd561979846ea4c8cee38dc1686 00673b3a2985c95904732632e5d988d8d437a60db13215bb6aa880b348f011c609a1e860461427a8cf0d622abc47f910f5c97ffa a9f4086b614ac77ab1178300df6461b83d0cc1b7d7c52384b451f88bf3dd49bc3db3488b3d0652f4c6693b1c7a215b3e +23757fa60fcabf543e603d8b31ef0cc99b3ed16b4816a84e01dbfc858872fcb79fd03d2f8a1d4f28c25dc42a39e20c34f81ebccda1682ee9bd22fe323e7f8ea90cf4a2a6ebb634cd1153cdc35f7306f28a2efd822bf23131baa1543d0ed5ab4c8168d3199983fbee117085f90550ec3ffa2b06070d3add1d707fc2593285ff58 000db7dcac414010b816236cad584dabeaec1da76c97182d1b62f87bb7fe2946a64d10430571b2b29ccf2ef72c969a9f045f1f3b 81d291df4670256605c8a617a2e9c0e25b2fea8ef14302df728a0dcca1346ec0062dc7755e915bc568ef55e09459639a +b976314d2f066f8893307a726f450dcf2cf865c170e90e6908ce9787eec48e1e2119a731b2bec3c12fd4e6282a393774251bcaef91af6ce57c63a8b45bedd72ab862cd169b7c84b8f6a72084ff823a96f2f8eff3483a7ebfabdabf0998377c5a6836d88135cf61c65a0ca7ca57727da68047dc635c17ad13731035fe9a6402af 004717efef16e1ae267e155aa1daabafc68515aa391dfeb73c13d01f3132bd22c984228dddc4dff4c39979e7585acd3f730cfcfa 9950177d614b51632f2965325801205e1cc3592cd1ea25ea56ce2f3d3cdcb5edc18f7310a2f73375f712d94736aa0a01 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K571 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K571 new file mode 100644 index 000000000000..1db9f35f98c1 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K571 @@ -0,0 +1,60 @@ +964ad0b5acc1c4db6674e86035139f179a9d5ec711b5bae57d2988456bb136d3aade7ac9ef10813e651ae4b9602308b071d75a934a6c012eb90c5eb9b2947b50fc97b1d36c5bf9eb13a7b06c94212c3dcdab402a563262298defff62b836ead1f78f9d20713710fb48115cc5045ba15140fbb4bdf516e4150d830d02cf30963d 019cf4f4d06825499949f9e0b442586fe1bfe3459813a2b92cd8de0f775a4735e02655702ead8e60824180761808d9e816d60bdb0238e1e8039ca7bb63c92e1cf8433ef447e64ead ad025e4a8d9e94b80fcbe452a6aa2695eddcadedfce78662a8ccc8411c01a3c0a198c52c06a12ac20512ecf1fd63f841 +baddec4794effa668cde267016dda67bc70b847919a9aa595f93ba9dc27354399ef7a607fbead31e57a8ce698beabb10f313d393980425e67cf95be45d512f00e950c0c5409573ddc3d556f23daf056259ee8914e860562a674311452fed780b3e0317a7fe93baa81fb98df3ae4328b28ad0ac8f8ea33efe24faee658ad026f6 0098521a732e72ed945a549afc92318fef7156ed1d1ed9bab93b581478cb2339eb32bcef705c9bf61cf2873ddbadff8ff3806740a2e30ce67d1807a8179dfd5d952e6f8a583baf81 8049a1de31bc565b2ae900ecc0fd22df7f9dc3e12c7595761dafbd6290626242b57d3b9590b4d3f0a6bc18c2cb6e6d8b +7ef7138fc657492d229054f8a50dcafcfcd1dc06f1c16640af3f658907e2969248b54416066eb119adbfa23b8dc578aef18bba79610b9cc109394b900a25e55a779230bb858b2ddd9499a7775d392328db9177aa9571c2f61dd52010b48502154e914a0c55a54edcc04a6713cf7bda8744a893926118b09df877d1a4f3d95e8c 00336fb21549e397a190beac38a1ee10f0551952da15f71e11dfda415e5ee08da2356f114d450c661f52b2b32cfc7b9be61732672691a079f0927989b7e9f4efe6095a242155b641 85cc953df02d562ac83e048338f85d1c2c593122172fc2d93d975902c0d3570bf3285057977a735e3aeace403b56485f +d58e1ff1d49a471d0567ecf8f29173dab5fe5f6184ab4cdd095c231fa7b82551f99a482994a46c3d8ebc07297fc9e952a5dee7d5f199b119f6f8b250f8fba45701ac252db725e75c4da27ad77d59a4eac448e54a277986740dfee6596811e59afc9755e53d24b826c09e497e29e69a22bbc85be11763064e9ecad7ae66458ca0 00e287ebfd9ba294128cbd484fc5121d271cd33e685bb1804f09b40aaacf64b5a9f2cde9b30a4a02d3a9bda97d92f46bb8787b3c61f280b1e1a0680f1f0679d3bb34d53725d62e52 910566f412e37ff53de33ef58a35d01d15a4d0555a7e5fd9668f1fc17c540a2027175bb6b323702ca416f5d357c016ba +4949ba765c14c31f68ee0ca26bb42ba2edee63537de4a6f5c42bbd862c21288d6ff48145260365193c6fd2b56dfb014da26b8a483776b717c6874f627c9a622154b824565b23e178240f53ee9748c45759ba5c035b584df0f09504e95eb9bce0301653aadb860bb25e6ea6b9606e0ec3bdb8089e6aa0d5763d331757490715f9 0149de496fa8f88b2741864d0c35b3df666b87179b7bd06cd426a45f13bc87ea9f50dea85e1fd02a532630e0e3a231cc3e7fbb7c7ba85b40cff1124e72c677c6a3ea6aa40ffc64b7 b2d7eb71ff235ef246f09ce9510ab5160f0d9257aadc46338ac207ef2b64c7494b3d70067619c60e0de39002c20361c3 +5bc63e5c50b1650f0ed4a599960f1e4e11f6c151b2123fd71d9e3c44662312a74b6854290628e20b30eaba81555acb2fb49b640bdab2528619c7fcad0f2a2880c7ea232d427d7c935fba2313370fda8863a7e7e203d63ea15d0cfa083e716ce6068c63fa616ddc225c9e413e694cdf6b355cb1293af5d6cdea51168f5634e878 017605d7c5873d870462375d741b4bc6375f3d47f7f5e9d998917adf2137a81e63b66917b3dda8968930c4b850f2270eb3187fc756e2beeaa67fe0d73053e6cc0ff0004a21250551 ad135770f47e9ea6343455e49be9c66c0fb3ee9a9efd2eef040324675c32235559d15737aa1516b57105405f33f5d5ff +610f6633718e49d232b3798654095e2efa0de11f41258b27aa01956480c870d901efa77e109d5f95f1f5101d3c90fc51312d9b3019d2e42e0067eed7b457dc7fbe5466923b62c83d7347e4dada571b57813bb9c21d5e308519b8eedb7a7706508ad04aa69698e03636eb30fd9fb363ef3a185756494ee01175b16847f5b68076 009214dc2da0967912c31995cb8f5bcf4bfa832c5a2d3610f3a9857e5eee7c77100d599d9ed003b4106013155dffd6c48859b846e45e0ddbc5fe24f4891c9b2df51407e9cddbd974 b360ad4b9d1e359766c3d990136789895ad603d3d798202253a36d66103a5a1f31a38b94541eed5b30660ed275adac05 +c548f0546cee0c0400401cd540a0aa9377f27ac64492e6baaf38e794db4df83e64ca3d83b67bbb46a6c269c04c2725287cce0dee984a0d468c9ce495a7e554a6835d72c7493bfe88dbd5a044a148c89001b8087fb03e57c2b7212d0b175d616333a9affd8a1802dd49ba9be3ab6c6d9f99a5578d26cc4707a5860c6c804d69ce 0042f2682e9ac8b76f3c0880e12c292524601dce9ea6982dcf68bfdb0d3fbfb50dc9229e54149ef09b95bbf624eb04ce1427077f30d8536be9f69970ddb449ca22ab8368d2689ed4 aebb10d3021e6cf017ea1473fece99c1992ea045c5b608329b1b1c1632c58584845207913a2d978feb0e0ff6342947b4 +9431c6c5237f6b4b35682a0c32f68752035c8b295a1763c5dbdfd73466cea64a00ecc11356d02d2a9211dc54548f5db1651e4471898402c887fbf45005a3bda271df0158c98319d4d6751b8ca6b07100182957d5fe0d97c4e2294406f83e9afcae4850bb089f2252490417b5afd8f07f4c795fa84c9c7cdcce26bd97273c0072 017ed9a9c75cf66528428e85b0f019e3488af8b893b12023ff1b4ca9c3691b74e594539afa0f4d7c3863d15399b862f15e27bb077392d6bbd546ddfd46728c75177338466eb2f4ff a5ca5bd743233984e1dc0705e47aa61c43c17ee266b2c21b490c1ca5f745f5c14987317ae86556b7d2ca216b29aa567e +417cd5f60416f17081d2c70e9a510114e08be83573bf9deae75fbc3095dffc8a7f7325f61f9d6565381710eda871388cb17619e4448836076338ee309a2bba5f737319002e259b4a875cce1bb97996101c9a7abe0278dcac203a712f0809eb3c4b85a9c380550ab0bbc5067a8edfa78abf03c09b5c08f21714e1022ebfcada4a 01bcc09b3f2f1d26ab9955bff7e8c0f85c8a61293511a196b53d7963f4a4503849c96fb4daa68c9852ad9185e01a35f0bf298e34a09ec352cb6da34f89a1f23e8ea27712a8f43aa7 84b0b7490329fa40c088ef55d325cbf2886c1a272a01fb11bd782e4e0d5c4d5ab000cd5fd282b0d31298839d61cc9c0b +eced8c412a153a643ccd69596389f83b6a36880286f8aeede503452bef8305942d95734fb5733f37ffeceb1c2dae7b1396c3323de11089082745c28a1756f784423fa7ad68bbfbf0d93ff8b7ad62220500df6d6895788402c1f5c69c06dd9ef55e2401cf297184e411be87c1bba657f847208c0e750f94a3df92f253b377b4da 00ec52fc3d9c272ca80623e06b15c35f349b13548ef7ee400bbfa04196850b3b8cc7b239238c827f9b0a3160cd97969ce21d66752791f5896e0385b0527d4d77e4b9fc70f04d73b2 a4b186c70a8f516eb4c6c08ef5d373aa61355f1564be9e088f2d21816e4421e93cfa429ba4029defc7dfd8b4961a8694 +30e83ea39a92036e22b7bed7639eab5e5be1d00c20b4a9b9afa9a0d1653369cbef363c119cc6f921c8f84663949c8b8dc9b743ac2b1861a480476e9b64c8f333f34b6fa0e1ddf09d49618ee4f3c1f46751b5595f0aea413d4ca46f3c26b974b112cbe99c813a96a4423764c069454946f213c5f066ec38108f947abeeeb02fb8 006403de7627de22d1dcf6b8da5af62f9ec59ec065cc1ca1311bb98aa439a6d5985619b17c17a70f59e17cf180ea6828ef57f5f1f8ef05680a9fc12ab7faad5af61e4e11fb45d341 9342ffa0da26ec54434996c9fd697017b4ebfbfaafe094148cdf7cda3091767cd993530dd9239266b90f21eb8bdf579e +3ed244dc16a5cb292db4b1433b0ca3226913f07377faa20c6c1402cb4d026de808ca74a6d4ecdd7c4e662105bff6edb9fae0117c50aa053aef677c0750c7a446edbb879110030758912e8fa666489d702d8fceb719963b24a256429bbcc869a1f4ab9de9db89263e3684d4daa1df2ed94bb59dde2abba63793e5f82aa2e4db83 001fb980aef64254aeb9bb613ff2fc6967503db4bc1f337882f1566cbeb57489cf32e34f310549f41cba1b951f487453c29753a184e33330e90d4b973d2e406c99a239a5c3f96233 ada5ad71a6d42469c03118957dea03da3b0aec8b28ad201046ca6c1307495857072a248ac37affb96eb4edb1e643816d +40343935d9423ad30f3fb1832bb08a5d20ddb3a55b59057cd275320db4a5835471c96cfb7d67f41ef860cf5879897b8dcf307bd1a52a6226847b768ea38ff1858f59e64cd635b51e6863773cc6c64b363ec47ca39266422406264668415c189e2f92447ac4c63ee5d74e95d1e6af05016917ad237f482ea0b02aecadd370a8bb 01d96dc09dfaf602789c1dffa5c9ba130832badcf180429660daadf4cf1be5cca92fe9713173861670eebfe3a0ba25bcc76aecac60a756f07b69687e05c7e25984a39556469f62b4 ae6bdcbf730b80b3b9baec8879befa656c879a60777ae63f0cca24fb6374b250472fb4a6bcd49776dcde67c37833fb4d +274567f8841183e68c4f6c6b36c5a52fb0e88492e4076b9cd768bf571facf39dad6affeb68941ee326ee461ce1f33c26e4bfb3c9e0cae8241fbcc14cc69c1af68701fd0be3def1e87b7d52b682ebbe1cc225c1bd177b0886e3698a06d0e410a1f92c9bdf7239189f6acde0d0653815a72987671b415d1e8a70e685d6e5b14c33 009d98b32c8eacd135ffb8e13223690ef02c0c1f29ea8b4da193502c8cb3f39f9eed608c02fd457f2fb685ec4595e8fc8f388d26778d225d2b18c9bc8b199d8b65c0d1a6af33854a b9242a01d58745fda52259040784a66aee0c075b67a6cff06bdd6f65b2ebb1255ff2d8174b9cf3f89019b30b7f1da5d6 +d9c99b8da92d3c2e40dea3c4025dc37770e867c4d2746c4d726b6de24250591a586c166c88acb8ed340e161d4c81b9d14c919a1b06f1feb22c5ce5fca2693bdaf4994ac72c8983c87f331473fd094eccb3d5f3528e69d487562fb5a65c150a8217192f8aabfa7adcfd0b6916d5000248fbbddf1ca2f38e3d9ed2b388998b7cfc 004d873ac744c4f68bb044783ad69e1a733cb8b8f483f2695bbd90c4211282036ad7914a53b25c3e890c6824643cffbdc4138d7ff457e3fbb99387494eb5cf2bdf1ad243a3a1e644 820542f55e843d6eef6d43e46b53fceff61d0663f7c60b51061c9a6ebd4fd2dcc1a49f74fc596712c8d9d0fb12c7e5b3 +d2b88a01fa17703c99e5b867c645e98feec0d6d1afaa20a97b5fce9c23f0594460142af4e36a5739b8d26d3ba35a0263caa5429b4abba157f359fce701c43372500fd2ae1bc2ed80bfcaf8cab7016ff93d4a27f565b7e67fe7dde22bf02c48be12114fbff2421517c825019c0ccc72d927bef156140d7f0e9b6ee37af78c3efa 018d2eb947297a054f8a789771dd875b12b26ef057fb91235dff3b062916f85aab3365609bd2a38a861439c8514e33f174c198139354e63766942f605107cb1b9709b782622b295a 947ca2a818f28add71479e4618de3ec7ad5714d54b296934f132eba6d2b44aef4abfd4ae9b94455839f87c0e08322671 +a704a1428cc894f958774368979fe075353b56790555386e3b043dc6a2919b94a11c7f85883f46b4d47b324d349c28c667bf9a000daaca1d7191f2a0fd97a4867aa9f72422134a690625408a9ea4b723704690b69152655f9e9dd5fa3dd94814d97dd4f13e85c3f9bca769491c2461fbd17e28afac00bfa81371d5039013da8c 00594fc0b7a5cc0216d2e78eeeb6394c8225de795f4b73bec48b2f4ede185ba622b59a16dd3eedf8cf2c94f2ccd6dcd205f64c97cf1b7f1e34129e94b5129502909f43940dba0746 af4ea86a5e1e37da10d9fb706ef0e1b7a5e252c2636bf3a9526985fa61dc9958ae434550b0ec24a601c3e3e627324b71 +f8a87c4acadee27a908718461e3b45060ae4ebb009b10a15926460bf219cb7e75dc3a993fb9a741b94e2fd71615c50f6df958568f452b2cc284f0516816bc0d2e2d45f663155660a26326f63f4aa42a6e1cc8462a2ec620a365257ec042f55e4047b62af689592a1a072553ff174dd629a4f51837780ca232cf479a68c1ebdda 00f000631106c5851e8ae0802b01e7a8a8540b427a8a3956a1d36f0600be89318032320cc420931d825cc964e823745c60aad3437ebc1c91d32004472e9677605fb708e5a71a0d83 a51c5d4721c8b067a532ae404b5bdade2573e0779d4a91aaaefe99014415fbbf6853204ef065bc3168f623c2994a58e0 +10b5438294a77c7e517ecfe8f8cd58d75297b14116aa93e574996ec4acb21837e6297cc0e7e7b5861e862062f192f2206a01b1caf42c6d7181d02c7d62b76c2881f8479449b02d32c6f792714d8f70f0c75e81c7d9abb996be87f5ad9a01fe42b75855558d5f00df392b62ae0d258f3f67dbeaf07208952e679a2c573aca941b 01023997206341c6147c536d034a9c38b4012035dc2c9b7ef0bb9cfe65e7d788296f055d508a1fd957b2dc7f9eb10c27790f15f30d81670945e54a508c57b70b46b4a09f4c769289 b933f489f8a9ad446df94a816d19817d8c1aea3aeddaa607a30b78d27a65fcb63bf89c1e8c095062b65b33c9b0dd0dc2 +d83a52d43216fdb16b1b40469863ca8eff4df9fa358deccb5ffd18b3e22a9d654aedc98f3dbdc4f5b4e56b4299e25d8a5a38d01b34eb93de382df1ae4d1c7f966e84b84c393d167aecc6f1192c4b42cae83748b1ee3d9147ce7de74cebd122695b455e8082f86e3e488fb0f51b3b7edcd579940d1cb9d045296e5e38f201b7ef 011ebf320ecf6a908ea5b868afb8e22246ce84e743e1076d6185ec65dd79043380708bf8da4ba802c3b93b8d15509bb7d7de9dc29f1e9fb0f0f2cb97a26698f955b1f7ef668122be 93457debb07a1de0a6314b62a119fcc47789ef39ed653f97d8cf079987fb8e1bd0054226c35b04bdf30bd769252ade42 +eddf5553ed4db6e8ce72cbcb59fb1eb80671c884ebd68e24bd7abe98bb1f40806de646f4d509be50a3fabfa85c5630905ce81abfad8a55f4cd80208afffb9056bc67d9dd7f4660a5f924af2a3745eec2daec39a3fe36131fe9eea444b92d31f6a125f12125159ba095f89968a7028549466f41ad45668a861f671050d2a6f343 00746d5c824d78f42a1fd63d8fcca61f154ba3e75788b7a0b87f53e5420e23a935b02eaf67bace8dd8a8e7c1caee30154c2428e0a437cf12e235f41c416f92fb54528865fd4766d1 827ee0931e8897e6d44b98f7c6d067b3dc68587e0c294d5528e74e85a6d78759972ace84d26aa02d42db52a0aa2fb2a1 +3db94335f6d1a125309622c0a9d71bde1da09371f0285a93bd0aac255fa8f10a56074e0f6057f1b1aecf2d86a2319590ead96a2ad1336fe844e09339b456be32374ba2e659fbe9d0f2cdd83444d117d2ce3204ce4b4294dd05405634b84747ffb4227160c4e5c2c9da9815b0c6d20f55705f16cdbaa13d107ae666d707ccbe6c 000670e72ac2de50dd2cdd975a6cdab10ac45e37ef7a28c685d77447051496b5e161f8b1b93f6c7f32fce8ea05e94ed35fd7cb28c44bf51ea29cbaf5aaa31d6abca30a89430323dc a39fa66aed1f8b54276f86799c1447259bb4f58a3a777baeaafbcd1905d5a8ebc0e23e729b89f45e8114127573628cbd +69166ba40768d0a3930325405edfd85f3272f7b8e600b0b319f070274c91f9f03d0e6ec4bfc7b4445e91b87cecabfecf5e77c7301ee3c6b0affca2fa02c92216698705eb75443eecc25438db2d2fb4b24f4195d6b9c05c53e0868d3e58477100607ffdc31b18c40b4ad7202bb034e58653daec0f6b33c024d42a3fc84bd8f86b 00369a3bb96f884983c23281bcd04e24a3e5f6359f81e3c8e46f3f6b865eb6bdf98a630e90646275c587e41b546d3ca7688cc207afda15cf9b25cf83bd6ad27908647f3f9de59de7 95e5e6be3986f76f5c65fd5c2778d0b85b9c57179ad5f080ff229001b39209db90f32facc4a4101630eb022fc5373688 +f64cb668b72f1e6dd026a478505c0eb33446ae9a2993bc7648aaed02e172fa9a0e05eeec61e756ba246c1dad7e85d3f01baf734b1905c5bbd1b08d833c2cf1e079eca75b866d705c407eea8618d23ebbaf269c7185984b3bd4117ecfb295ee6b47eecc8d3a78bb96552f6be314656f91caff793838226662c75cd7804b6bef79 0026717b039df834855511815d5665ff9b654facab469390ae257b7f0eb4dfe66ea0dc037242ed0c13bf229b8f7ff26da9b55fe4750d3451c62804aad493c179ae45d08ece5af085 b3b5296802f69f9417145aa5c22ea383399818085ece6d03a40d7cccb147cd4009e0089db0fc24a72ea65a12d5682c57 +51ee0b98eb6a3e3c1afcb35a33697c048dbf61374629ac5702a57801fafbea4d6fa5a26c9d1b79d1c58257ac0106387fab2d4a1b7f8c0dadcbe7c830613531b3c209bc17f792bdba1c1fae1b7528aac53dc86c2094b40194577325c05d2258303a2d17c854e7449489c43991b6877a50692a6340a528a6b188440ac0cddd4c4b 01d642f2d393ed4abea37173e4a79534af87adf534ead4a0a1c46fb047619221e3577e6b8bcc776114d01159c736ab78af3e53feac339d7afe58be8e7a8ed290f1dad960f1b5de94 8ddb6e7e135d96f35b184f8ace59620786a618753d590d6e7641dafffec1a6fbd68664b4f6cfe832363c876d14828c64 +feee50aeacaccb6b1c3d95c6524044edb78322ee836d8159c4a4c2cc6982480567c4c6cc4806a564876622266e1ebd45f2f4be851b79da025bd57d0e6acce1ec1c8c255eb89713a1e4897d4ee0f7a248b9d4bd3ad5dc0e57f60ebfb65691e164bc908956a019083e923cfd33dcf37c735af3462768a1e14a8051d7aee74d5228 008cb70be29e83f697a3e2f67d86f1c1ec9a163b5335cb4a06004b6634948bf60b8ad9df9b27d2bedc4975265ce44a7884e57082d521320ca4372d38fc77b18d3fa05ad8aa5c43d6 b4c1de9f0dac210445698a72bf1fa669c1d6ee2902703740318401ce79fd6599173f638b16133791c713803817488303 +b115f7370d6a93a90fd9dfdfb292956be34b61992ce1fa5627c5e928d74bcdeea66d4040c473306a0070fa8363c4303bea32f73ea3639b5c6676fa5a1d68a2cc1f91f00580d7453a23ae70af4cb1f1657aa82c5b305374effe5d67d559e46a6cee6360503d21070506f1af30bb000d2f2f85caa6465810f89968f33abae81cb3 01eef463771f9c6285f3257691dea0844687606d4dd00b6020517f190891cc1be97cfad21d147ed8881b5a6e19b22ceeae30e1132476325f2de0e9af2e14c80b8c780a9d2d6c96de b9511b1362601c9be49dfd06c1d4f147a8b8bf425161d3fc6fd107a029ea4c7c44080ce203fceb04413b9c4a328d32ee +726782eb0d9720daa64e4a77b5d8dd67a1a193f15eb6b5162e3d89c925ba63b7c7e1c4bfc8d6f11915b0e14d16ab53ab015317bd5958b0beb6074199e05181915496575768d026c23e92e06016598de008c3718aaabcda8b68bebca0a73ecfc7327e8d3646106b7d114dabc46cfe56265c326ee56fd2ca87abb5bed8f997c735 013bd452b0880b101df1aa65724fb60d5d85b37ed5419027481661a3617e0fb37bda1151b9b5b41f908ba832011f7850b75a07b678e5b8cb35c5fc8b94a625e4398cd5ada2b04cc9 892bfb867cf7b1438b2f5fc7d092790747a287c47fe722dd9e488795e35c75bbe5f7d691eaa4737c454678d0e0b37e97 +1c2418243fcd89c6382b7c3b2a8c341f26d08174a9e9296c4a5c98c5793a0fa48dce51e30811a96b515aa22bf9af89a43de06d696be1e531c5dece1f69fa6ecb7f20be063c602a16454ddafb14385ae3f8246c3f989d0566e06e7ed1864502896ea19df8393259c4dab3b3380a4a80b4103cbef4f38cb69198b7cf74ce94883b 01288141ec2244e4bb3f62daf4ee588aed09ce22be55e3d42e9085a947c1f8cd16533635d170bd64ae0b417346fa4670c25d41387acb2a8e14407a1931d9f7c5358a14eca40974bb b28e567b959f62ce687a17c8eaef8d60f88a6cad7f3e82d967774a566a82b60bb1e8bb3128ddebc29e71bf1a65a10f0b +1de4b642ec7220c64b91561caed7832044d6e811ac909f3b199cceb0d8a7db91bcdc801412044f5c34b355b95a2c6170fe497f6d5259bc20715a38cb0341c88e93029137e94d895bab464bca6568b852340a5c5d6a225475f6eefe2fc71ffa42f857d9bab768ccaf4793c80c4751a5583269ddcfccf8283c46a1b34d84463e61 001fe06b94a27d551d409b0eb9db0b163fadcf0486e2a6074bafe167f9a3b4ce8ac11f42cf72f9a1833a126b9473163d29bca2ad139dd1a5e7fedf54798bf56507326fae73a3e9a2 8b139506ef065bfaf4bca1394f1d78bb2409a9065d45603f06168ad3304b760a595f1e322ab14e6c7a1a9f75cada4c7c +70279be7d7ac72a32606642ecd81b5d4d0f95fbc3c0b07d85c16adf2788601e44dedb8e55e0f9e0b4ca3ca35f5be7511b0e69224a05204af67aae11ce154af6d594d47f6e3142ad183969544aa95cae1edf42bc699137f60178c12b10a67698e37ab9f3edbfb3acdf1b3513d62fe3db33b16cbb4e1f9dfe732c107f9d0c953f6 009cdc7e4945c485a41728f83d5188f539e372ff4fe38fffcaacbcb4522428e4f93ef4972556f4398fe17bdd885768f0fb5590df495badc794d4d274e22f2f4a2535555922fa43f9 b6c8f701dc2999a43b9761322addf2c6e67b275e1063a79bd93b963d5a88e48d33dbf9f434b743b3b6a9d985ec37dd8b +4d7e0ad520445b6a5cb46b7c77fbd367614044ae6004494c2b3a89089287e2836c73b799cd8c90139eac427ebe335804c3788f3728ffb8edd7f49a4bcc76a9e24ce3c2299cea88c04645b82033115380f81b0c1d823e470631008d350cf0c0dba1915519985b8a389ccd8c809dbd5bb5051a79e631916e0d052d9b6cca18e0ef 002bc753d007c4491cfb8ce0a6c96455acd16d37e02c982db216b8cc1afd6d10c6be4e15a3988b8b8b86b2b5b59a5c1939889024849317f27ee08a06bd8e7524d4ad83a1de208564 a9bf42c70087217a1d966bb1cae49c7c41cf5a32563426fc5553532aed6cf3b9fa5764134918d20c15fd8d3396f23b83 +d49903f38b5c9b17542310425e59377f61f5b4f4740cd97371ee2116083f7758e69e7e2c1b0950ec6b76f96e3c91c721d6f2843afde8c7505a559c8a64bca2e665aa1131b75bdf86fb5b90581c7d3b61c2cff88f3fccf356ddf5ed282e27727be061b6925c51ea7f1a495f471dc8a5ca1a88bbe29e92338d3c9361460398965a 002082c6e61d0d72f040905d8c1c20d47b029f41ec68d6cbf43ce97c3b2a0a770557a33cb803c432cfbd3958fda30ec1bba77a6613c318597a85ad02b26c44bb77ca96d9cc1194ea a4c64ec45849c9041cb2db27fd0a35c6a97bd3f0342450430a9f84397e57d04e7071e13868b9fa11c951a10feb0fef7b +0e3f4afc3e7b25c1bf2d98098a5a87db1224d9bb45adc6e434732b8722a708ab80a1f3f6ef3c5aa70d2e1dad3e4416b12cc59171f05736c4b58bd084602c344f2f0bf3cfdcfe04c64e87597a99de23ded64b33607f7c273ec321f6462518715b11e91361e89ce5415bfc2ef520bfec378244a3bd2a4b9b6b3d68815f2f75baf6 00e298c93351323e2c5304015a4878997ae4e79d1c32f1dc64262e534d4f2c4b3e222356ffce746763373fdfb936fd330d3214a18c07f1205b20c9a941331cd676040ba1fe3dbce7 83d02d058710b2bc648ae58edf4350c197ba8dbe12885da9beb265d1fbee0cd76b8f9a1617c30faf7234ad8897a5fd2e +8fe32671f6927272fd3cd8dd4e34d44d27fac8c88b41bf9a48039e914990bf06d1633b38b9200ce1c2a275b9c55498e5da2d0707322c3ea0a0fd7aff598fb801628264e13047c8008153e8595a0dc95d54e70b882ac2ac9314d2b78e7b93922da818d7075215e354708994af66958954c92c074d132dbb2488e5a531c755a8e2 0104f4ad56594c5cec2a988c5596d73adaa5a81802b40110dbae698ddb1f0b271fd1479c38abcdb9b234e69cd0da8a0328d2135c287d5b130a09fa0b899058e7800eb2dfcee95c1a 8f6f4d6e32b22d80650ee5a816ee481104b263688384daa5e5b74a22ce83c21a07e64cff63e0827afe11d8fc603e6b33 +a8fa01136a0a78313a5d160c32fe5d1805eeb3730c18ca0c47818e82c48eb4c9e5b2dfe3ee5facef9ec59b68f4e6f3213f77fba9f8ba06dcde546ae348d343233883894f4423331b536f62373a495852977a51cb192cfbec04b5582b4ece69f345979e234de32da7a120138a057a7119735c4cb19099bf48bb202e7ffac04def 00c4989bf33b3136bcb4ba67906eaff2bcbc6567635aa4b057acb7353ee87ba3cb4cb9838f8f679729d5c6ed98e6c4199cf58605f009c6873a1b8321f83cd3c0973b7a3cfd9dbaa5 a83c9cae5079104187c24830152b63483f59c71f20352393cd1207ee4b4865477a97b39d49202e773423f59f936d58b9 +ba2d83b21c783d6ef2f3b7b10e910a418a9b9f49ae0fd37990335b3a3d15627846c9a12a1f31a3d0e062ad1bec5650606ed4dd06c30e50c1e8761a29f4ea1a20f74635d5dac22e5b787ac10f4ee82b338a641484f91771c128c84d31cdab0a6b9616078c898665655ee9dd4ae73d33b94bf091b064928b959623aa71ff73b4db 01a96f2ad56e31397e236cafc108087479c9823589a5fbc3dc7488d0e5d1199cf245d7f21f524cc0e8b47feca14c93fb760e631434a91188b32965053942f3bd39b3714f9d6f1a11 835d371d00358bb8440812dc5ee81aad5ba80f967ee7cf5825eb049ef3982a0c16cc5334e4d6cda4a8bd0469e3318aaa +ea2d5f4e9797bfc2f33f0fccaf530db2bdf8abcec00f09a0338eefdba318221ec0e050cad1a85c3f76b784c6e8c18da2b062f333eeff18b7b781e67d6d0a4368b8231a892e0f4103012348e5df53ac745e4d34e2cd1ee9369f97d4801ff485fc144b2007008036bbc07cb1c302a00054b54f3713919191e1d5052978c9c2895e 00c08ed8e0e0f8b0d0714b46a2164b933f8147692f18da97e5a108c44d5a5cf221cb50536e41832b83bff4026c6df156386235cf5e3e9a67b7cf9b2fa7707c5e0ff33a91601b8e34 a3b1c3ab7b655967fe24b7d7f067aca4d542aca28f95b5aca60c9b1b52648b5b60c9a5f6dab473c626a1d9e13158e48f +b2293b0a09f41decd9d8e637b1b08c2efe612f33c9c0beebb6e05033c6103b958f8aacd125d7c810b4c287349f5f922d2c6ed554be597fb8b3ba0e5a8c385ed8ae70d5ae19685298f20e8d844fb5ad98db12ba7e5f45baed9045c3e86b3cac9bd55b614b82fd075954fc59bfc6124cbd68edae988596575f379d8921b594c75d 0144090a0ee38cfa21fabcc24d35139a99656911ad4f6dbffb77dbe74e7993edfa9fd63d2c4f6bbdbc8ec21ba13c9f4a3576b5d6e3abeab5af5ac81b1f2bb6d4c42dde645d854d9c a088247ed0eb3009e00d863d4ee3823e1eb668fc137de3726ef391828a6b46038412f9be7144b16b9be59ae3f02ff9d1 +acce54270252e7d9e983c08c993cd6b7e3caf482a9149036afe4665bd3d0662a6818047187872862d5718b8ac063477f693caf1a9baa8bdf2f36d411a796f2b46ab56f66bc94924229f8264016d6769c85d9bbb7d6bb042fefdb8fde1be026b86af2017aacfe38c97309b4689b23fff94f1de880064f1d3ad9d74dc804c41f41 01df26b672b2e3617b6b6c631d3c6be0cb49c0a690de49643e0f416215bcdaefc03fa9c708471f1d87476d58c8f147517ec8a14aa945ef001fa01984d5c3d81f7083ea500558fef4 aa44247bed621d519596db0d457da7dd398591a3183fa9ebc3b104b16b7d0625f8ca4b2845549426a2da05f8b5729f08 +e25274ded4840df0d71d3369007118f002b83e2d375c78f7e29ade067db15cce21842611f3f015db2efec57da77cb9d16eb1e00a8c1444d48dfda569e29fca1ebf40a22fc646a9fd44460f0e473bde487634bfbdac2c312f66a1c2982c6fe76c54ac72b6c8cc9345e47cb319a974b3cc4bb40634df74b4ad7e18adfa9a71ddd5 0189918b832e9fa30161fdd927bfc267f6405335df3d66d225e17173af52a671138883bcb94c4403ca3e001fcf09ef4c6488934d6775af2b1da30a8f331579af2d0fbb530298d8f9 a31df413e0b5e1e9ec1f69af7e6c2e2c294f30679f7d239c3df601aa07a0934baf3f7a989f9ef327adc6544d4559edee +d8a4aed87c316012482819b03a1d91691f2ad11a2f46082497ea8f64880d686891f7da550b2ac17199c657d4eb9d04d5cb8eaa180f743b87d23b1c86103f9e9bb60f4e19f0ff9d160f180aed7735130c03adb62502e69be5c624ed7bda2301f30580ae0921b02e103a638f5623c02c186e3bfe6ff134c762a2bcac1f879a9353 00bdcc175eca3a399b944eb0334ff33c4fd130999c8ac0e7b52ac5b774fbad53ccc3a31024f5262b2eecfeb2104b14bb244307effe3dbe8ed25686dbf46a42c4b6f8e34010ad826a a15aa62ae4d7387d5efb1829fa572376174a6e0f5210ecfea13a5b4b76c4a61987f503e438c36a7d1854bf1e0c108b88 +acbaa5ffc4eee0850075c0e502a70cc7a897a919f5e7bca4e798385601a26f411fdae5466ba9f6b6d8d7f819a749b799fbf4a3bda9105063e74914e8583ed8b31ea4d22164bee6f14bf53afca269b901c80cb3265be32ffd4ca4bc4ddb83e11eff82ead6d75dc4aec8e5c67f35d58a8a156cd1c0351abdccc0c5396c8fbe6920 0007ab5a55a1d8ecb7f5dca2afdf9ef465569a4b0374716f604ad42a6e0271e934b09655e8e2529784b69b2894bb399b02aeeae30e9e7ae70a2a8e56b9e775bd978a04c728e3951e ae78a1be7a564d94625a791e9dca8873e4b3ee569d5081b61839b2032895a92d74b6737b2db6b8df79501d346aeb5b49 +9a57b63a4f418404e8f5dcf3052b9bc04a4f6d2c33bde8651506d9cbc5542ffb9023292dea463111fb78913ccdcd182faabbff9164219b8900c7f9fb394f7d9678f77b18f8d58526ec64d7c1328953b983a7c416583e05a069cd76aefe26e5f5687b70abfbf9f58f052dc0863b4fc3bef805cc3bb05bf76a83235af9d6adfe66 01e7d4da72b1d82e17a066fe387f2a0a7fa4c60ab993ee09710531789186077f2f32b42ddda497d5fb57356383e1f96973df043307f0b6519430c3f0d40d62954032872fceb7dce9 b75c0c816d579dc019f0f3884271e1baa01f2be5c22aa5dff256af62c5cac7c4914356c5e17c6b2fbda9bacea1dbcacb +97b79c76d9c637f51294369e0bb52c4189f2fd3bd0607f91834aa71b3555605a89ff68e84fb5bda603f502f620e14e8b0c7affefafa2f0b303009ee99653ae4550a05315e551dd12a4d8328279b8150d030b03c5650ed4f8d3ba7c3a5361f472f436b200b321e7863c771e20ddd7bdf739c51de3676f953a5501e4477aed1bd8 015b7271d4319db5743119c8103a7d4c6d57e9c62f3eb93762156d2ebd159980aa57cea948e416717d715a2e458851f1b2e9ad4172bbcc53861db29c3ee0ba8e82617a5866170847 a572722888f9e15330f55003078d31d0cfb83cd0963346bcc5f83f3b6829bbcacd3adc5aa8f95f9517b5de89145d1e30 +564ad0e37c9c37a60872a4780a723d08d1159ddc77bd834d74c1025cdf3cbd5338c3fc07a904fcad9b979b2a2ceb1a0139af35e5112305fd662a57af6312624b9bdd3a64849f95f59a46ca8feb2ed56f87f258518947474c1729275c4d89b7dd286ed65f286cbac76002cc63b92a73ab6bd13c4adef282f32297e441bdd8fd36 007219ea7917d174a5386df985d0dca798ac9f8e215ab2f0003aee929a2dbd91e37fedead0ed95b1e8aabcf516bdf54337b4aff7ace4c6b3179f2e919a49db50a41c9d4d58d4f636 898a4472fd1899ae5caa0dd1d37290f294aefe6a7940f1d8eed2001585d11f1483e6a47c7e8a6ace2e7fd169b888e3f4 +072ed5b14754fddaf54e20da42432df49bef38f4a3b1841b2db457ff86c44880727aca945770adb41269df41fc17f6a687bcaffaa45a3e59070526ed53b8dc3b78cf9a80a85461eaf4b477e44d5ec4c2bab9c05aa747a5a520b35fd09e8b44539d060ba1c3470267e0dda111b15dbb587614a46e1e477127f963a16cf3a43ee5 00bc623152253da24bf8d752bd78aedf7d5f6a2f889453ccdec14e10753335ea8bea83fd181a1f3680ed50f2324fbeaadae160cc85831750e021f3e44121ea1b1efc29a7d0069479 91fbb458c5da7ee29644f22cf4e7b86cdd6ffbcf2e456b2126d641bee80eb7d82807d6aafbd249f32666e6fa9398a057 +e660dbdf3e61af39b83b95d3f1970f66d616f03273f7dddb98f768452b21cd39604a31cf80590d4a5e4b0d4917519e10fd325dd4ab7a52d70d154506329baefe0d5816f514ae109483122b4fa8fa1ebd7fdf1fc4e21e8d278a50c05d81c8f489596633d949c6c8fea96fe91430c01522a5afbd5042be8aa47da04581b2bd21cc 00645947d981d258f2954558c31022a3b6ba5fa7b675312f794cb61bfff1d9ce87267e4a1dacb7c8fc58624d31c85ebe22f80d26a620fed5df5bf38515e0903f0b69a606048197d8 8d7f9cd196c1796020209855802dd73f98098ee2d43ebd1ec3eb53c10856ddda0eff3517e75a15b3a95d3453224fb863 +8c9acbdc431565feae60e08bc7da113e12372ed373f1e1fdd581f98c8a7b0c79ac4aa42c7ffbc963fb4970fe26c5b5dd314b7051fe971c1186ebcb5650f7f7011a924de893f06961b8c75da7bff331847feead4abd2e8b9d6ecbedac18f4eac207b948e6e4215e4d5cb483e5c66ce7ad788cb89604d3a3e051539094079e7bdb 014cf93ca69d94ee8fbea0c8da9d76aea092b73073d8f5385b65c6dd4d567fe86bc2cfb8e8be890c3c6cd9abf7dc3a17eaecee3d7a9455887863e496c48dc3e47821bd3d825b6bed 862705320beb51a99fe2503b94f9302ba056d59bf6c93c06f3d1ab5adc5d219db122b68491648b633dc6d31874439f7c +53ef87d6ac7b9698f40b3ea9f3442e7b64207b140b7f66f73fb7d5f8f98452d30a4e493b6c0e3268371e88e612b818d4d847f032ed4983817d020411a52d81fd2a17b58ebdec199d817c2a8ba77042bbd747a6fd4bcc7e844ea829fd8461b389aa0b5957d92962b6d4e86385a8fbca90b8fac40944607117e9a4ef6dccb8fc1e 0033feeaaaa28f16bfaf5ea9c7319cf4561ba4fc55327a8477b6cd58ef6ccad3962ee1f3edb243f3a04e7e49c8e23509fa2d63252adb186b8bc7e9255cd61fa9bc45242d42da3a68 a67241f2deb7662dbc4f1dda4607284050744152d30444250dc33bb129f387b77d1a63687b99cf2522a221632e073b0f +dca1b7a9a313ead11c2d54739d9017ae27f9d08b3544e418aee862bb57e427636cb6aedda28e10f12aa15d2355f4f8ef112a86fec5dc46e6acef693cb8fc37c3e4885f3be3d3ab31ea4d73a0de904e95c7135a149f77b621d642f9bd8ba192d39cfc58b6f19a797c4f3b4f3a87054298e3ce5eda0ff7f44f8134c9a108285dfa 005613dfb53149bf5fdc4e08ccc1c752b0b66ab43aef2d008ed40f3df40fcbb2938d2c41e3ea2dd4428aeba9059a97efe5593119673866a19d27a2ee37dd357e22b6bc849e7e22cc ae8882578e7ebfa9ba50c983df62d451f7603953d97a00fc6a81fbd820b4dbc13a46201398a8460639d657445eacb7d3 +aff61d62c8f5c31bbb7d0a64a6ac589e918bbf2f13e7ad13abb9ac26405e267249a7c9922139bc28140833e10976b87e91cf28285274b2b48b63d24ac94c85c70fafa78f8ad05955c0ce6c02b841ee196dab12306e3e3d6138371217e2b474f7e67a80bbb78a47e374ffe2c9f86292e471c551da50d46e7b5c8331029f369767 011b92c8b72b86c51903387a65aa206988d443d1988253329ad3a89c902ff1ef8cf73b7f2e4aaa352443bcb833712d94c3e637ec12cbe4c2d4606878576b17fae1512fc77785b737 80cc2047a4113633c56be58b8e1c5f75a6511a15324355a2cf92b091dba067d162c56b5fa2592127acd519a1c80b77aa +721017294f17ef351e41256b57a64a79f3636628c4bcbe676ac9a2d96076b913dc4b246c9945183ec9bd2d251441b5101eac44e2fa1bef59dec03ccd7fa5accf3b7d094d68dcf78c8de4e2f19f56bf0dcb3b66b9421ec3f8b353b9fd74feb2e9affe0bf9aa421b6f03eeba3ffd58fba56b3ebd094880e50de01ee62a108a24cf 00c3c90d5ce4375a08b85575faa78ee6bbd9e5571ce5a90582042617b807339c282cdc3b003d82006264b1c08c20af4ad4549fbde53d262facb98d923d81b8eb6093374b6a1e84cb 81ecad2cf8c8bbe684f3858425d1f0b46f2de1f628fec7be9821a04a50619bff14cef19c45b699c9072e3b5a24558b0e +e2d1f33681759adb7954bb5248b0db3c3885fea0d4c1c0c226eb1e6d2d3ef1b9ac281a0f1c2fe5175b67114b6a501e2426d1454bd5790dcbc4c232cf06b017de8a9bb39e6033f1edb5003e8de3b44cc3d6150c3c952afb442952483cc688908337b7c1a8b5c9da70937ccfa98b2b0098c530ff848010b8e8ee0a8d65283481a8 010f184c16228d9034271332178ed485d10b6aa76003efc160d63fea26fbbdf5552205ac7df0d8c852a1210cf0ba512f20b798827b36ad56b12a826fa7dc1db45aed264ca6822659 aff190ce47a06c346173c3b7ab709fe7e2e02c96b4c2741d25ae9ce434895e6bfc2a35ef1cf644a3cbd2f6672f5c65f0 +414fc5d2bd56b30040e105cb891788792da595583b11b8fcc7320f40dbf64d9263532dc57344dd17573c95eedf851668b5d552e8796af205f3a0043af1a829fabc2e93d9af9091fdd9e0fcbcc9d6d9ec960aa60e4e2964c29a2f375400366480e513f63d124db7745847310e69a38c8455e4e602056a6a4a14a8694155e0a9bf 0181baf9d497159f837cba58a11ca435c442e5ca792ea559bff9f6a1f562c05bf6bb5914afbd1bcaea75b35f88bdd832314b249a5298622c89462344d3f28a44ba3d059df432fc71 8c46cbb704ef68fa15f32c3f4ae404d991b09a1432060178045291105b45fb1d1d589d7b9d2fe27d9f5eef0ef2eea642 +3b592cc8972a4782870e079b82a50f84b4c2d8ca90bd500d1ce5678982e266c391c556d8162ac3aab967154d072dbc0ba1dab5545cf2651753dee2881eca5abd412fe624bf3f9d17d33692d21ce23ad15ccffdfd250cb1949e73c9e40a64ebebb03852e92692dad1d7baef97fe109f35b7a492b343d4b643a4a7b1723eaecb64 0083fae86ab96bce99a53e50b7eecff38e4e25b21c4b0f6a4986915de245eae24f16b6a00a4db159ebc27f5a6a072da94ab6be5bf75f5eb3f75c4452bf4ea7014392eb1e02706fb4 a240884b7ebbf1b9ee5d0bb318c05cf296bfd6f2f0716f38ec9a0f565f95fbc66ca9391c3418a3a31731bfa590572387 +0079a02cbab3dc02601fcb5c8607d555beef7cd71a66911ab6514a4ae21c5a9c0e166f8cf5fb198ec5a49a96e17cf041f35f00406b79270ebfe56dc6b8417d2529fd625686ffbc8f69685aefa2fd30a937c02f25b48be4679e6fde821de928b33b12470867def874bb8c7c8038ab6594346a2c44b39210d3610994ba60a05e06 01a663efa7bf4d8479bc535fad71e9b5e4f4281aec55967baa008ba17ac2f89cc3398d30573edef29d590fddce8cb157f655e92779f59e7a18d0327d02e7daf4c1216143b3688fed b84986428fc9692c378a4928becc06e3b10f57dae9755f827fa57fe22c80ead188b755456720f249d36f14a6dba25bd3 +88573bd94ef50459814806efa868ebf92b066fbc2f7a4be9d2fa06b9dc1a72f72d783a6bcbc107b18a6314511bff217037a2252e7a5cd34cf9d5b2fe9c7846931f0133b2e95876cb800dc4ed7c4a4e4cc4f1195acf99fb0ec224b1f8fa8af71f72d390eca9d6be3879032a318734a63fec336c79035a43f70271def10c4955d3 00088d1a2c0219696a94337cd56516252b74139ea0733b17fdcbf7692c3e5f6c3989e5da2aaed7468e65a5d578571928ca273ec3b6aa72cd196f560f05095cdc8346e5d31c4c2e0c ad7486a2530aed92a76b13a00ee6e1a4264381fde93fbc4b0c101c6920a7f78ff0b3e46376468738a5eea8a08bd9b8d1 +d0e02045ece6e338cc8ab41d4a064c982ccb1748c48fc2fe0a6f10bdc876094358a6a90a45facec798a83cc95c6795cf0f0d7c66b77e22cb114c1432bfdaa1485ff35b6a58107cac3b7e58cb4f6c87c68db60b751e78f1fdfa54b8923b98caad0a4f31226956d065c083ace5f1e9e91944dcca51879d782e40358d58ca758750 016cc8a0fd59455ed8d4de561fd518df2e008f7dfaa5f7f29ac2489a411e233917b43eb3ebe2596fc824be58871949545e667dbcf240dfb5e0c615ade0179d9ea2a1b1ebb8ab9384 932696f8b52944c660f3ad06ae9254a079440e5d53c37e0acd7d0f9d0ad79b57edf74fcd0cfd0440396b15b92e236c41 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K571_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K571_blst new file mode 100644 index 000000000000..a2be996ee577 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_K571_blst @@ -0,0 +1,60 @@ +964ad0b5acc1c4db6674e86035139f179a9d5ec711b5bae57d2988456bb136d3aade7ac9ef10813e651ae4b9602308b071d75a934a6c012eb90c5eb9b2947b50fc97b1d36c5bf9eb13a7b06c94212c3dcdab402a563262298defff62b836ead1f78f9d20713710fb48115cc5045ba15140fbb4bdf516e4150d830d02cf30963d 019cf4f4d06825499949f9e0b442586fe1bfe3459813a2b92cd8de0f775a4735e02655702ead8e60824180761808d9e816d60bdb0238e1e8039ca7bb63c92e1cf8433ef447e64ead 987f0357c0be9796da20e9568ef85f228bfba608457d3f4703af772dd41ce01b481e869d94ee29a8c9d6548d6cb7f4a9 +baddec4794effa668cde267016dda67bc70b847919a9aa595f93ba9dc27354399ef7a607fbead31e57a8ce698beabb10f313d393980425e67cf95be45d512f00e950c0c5409573ddc3d556f23daf056259ee8914e860562a674311452fed780b3e0317a7fe93baa81fb98df3ae4328b28ad0ac8f8ea33efe24faee658ad026f6 0098521a732e72ed945a549afc92318fef7156ed1d1ed9bab93b581478cb2339eb32bcef705c9bf61cf2873ddbadff8ff3806740a2e30ce67d1807a8179dfd5d952e6f8a583baf81 8d1db35e37482dd3dd56b59240e75d1cd5faa6012e376c9755aee22ed3231b263256215d236d396308e54db77cc78eb9 +7ef7138fc657492d229054f8a50dcafcfcd1dc06f1c16640af3f658907e2969248b54416066eb119adbfa23b8dc578aef18bba79610b9cc109394b900a25e55a779230bb858b2ddd9499a7775d392328db9177aa9571c2f61dd52010b48502154e914a0c55a54edcc04a6713cf7bda8744a893926118b09df877d1a4f3d95e8c 00336fb21549e397a190beac38a1ee10f0551952da15f71e11dfda415e5ee08da2356f114d450c661f52b2b32cfc7b9be61732672691a079f0927989b7e9f4efe6095a242155b641 b2663769ccd9f67c598854c4c893d2f304a98fc8c068809a0a18b55bf25b14ddda3072b02fd6726209571891fef4fc8d +d58e1ff1d49a471d0567ecf8f29173dab5fe5f6184ab4cdd095c231fa7b82551f99a482994a46c3d8ebc07297fc9e952a5dee7d5f199b119f6f8b250f8fba45701ac252db725e75c4da27ad77d59a4eac448e54a277986740dfee6596811e59afc9755e53d24b826c09e497e29e69a22bbc85be11763064e9ecad7ae66458ca0 00e287ebfd9ba294128cbd484fc5121d271cd33e685bb1804f09b40aaacf64b5a9f2cde9b30a4a02d3a9bda97d92f46bb8787b3c61f280b1e1a0680f1f0679d3bb34d53725d62e52 a8cf6367e13d8a92b53fea912d313f0d1a16c7096a6dc0ae0fbe8317b45e7ca3d813c77454fbd83be7eaf597971d3686 +4949ba765c14c31f68ee0ca26bb42ba2edee63537de4a6f5c42bbd862c21288d6ff48145260365193c6fd2b56dfb014da26b8a483776b717c6874f627c9a622154b824565b23e178240f53ee9748c45759ba5c035b584df0f09504e95eb9bce0301653aadb860bb25e6ea6b9606e0ec3bdb8089e6aa0d5763d331757490715f9 0149de496fa8f88b2741864d0c35b3df666b87179b7bd06cd426a45f13bc87ea9f50dea85e1fd02a532630e0e3a231cc3e7fbb7c7ba85b40cff1124e72c677c6a3ea6aa40ffc64b7 8f386d41a76b0e0092274fcc0850d6fb121425efa0abaac860c9e8ceb9ab4985e840e4d5ae90301ebb5ac24e9cace0d4 +5bc63e5c50b1650f0ed4a599960f1e4e11f6c151b2123fd71d9e3c44662312a74b6854290628e20b30eaba81555acb2fb49b640bdab2528619c7fcad0f2a2880c7ea232d427d7c935fba2313370fda8863a7e7e203d63ea15d0cfa083e716ce6068c63fa616ddc225c9e413e694cdf6b355cb1293af5d6cdea51168f5634e878 017605d7c5873d870462375d741b4bc6375f3d47f7f5e9d998917adf2137a81e63b66917b3dda8968930c4b850f2270eb3187fc756e2beeaa67fe0d73053e6cc0ff0004a21250551 a18f889beb6881b702bde5285770b73125cd3f17bc466b9486bff95e0f6997c500e7964dd88e549091822ded0a40891d +610f6633718e49d232b3798654095e2efa0de11f41258b27aa01956480c870d901efa77e109d5f95f1f5101d3c90fc51312d9b3019d2e42e0067eed7b457dc7fbe5466923b62c83d7347e4dada571b57813bb9c21d5e308519b8eedb7a7706508ad04aa69698e03636eb30fd9fb363ef3a185756494ee01175b16847f5b68076 009214dc2da0967912c31995cb8f5bcf4bfa832c5a2d3610f3a9857e5eee7c77100d599d9ed003b4106013155dffd6c48859b846e45e0ddbc5fe24f4891c9b2df51407e9cddbd974 a069bf0c2eacf4bf014c8ddc464619b30d7a4b6f01a88f36c70331bc5fb52344a752f6ec9bc17cc98bc03e68f9037f1e +c548f0546cee0c0400401cd540a0aa9377f27ac64492e6baaf38e794db4df83e64ca3d83b67bbb46a6c269c04c2725287cce0dee984a0d468c9ce495a7e554a6835d72c7493bfe88dbd5a044a148c89001b8087fb03e57c2b7212d0b175d616333a9affd8a1802dd49ba9be3ab6c6d9f99a5578d26cc4707a5860c6c804d69ce 0042f2682e9ac8b76f3c0880e12c292524601dce9ea6982dcf68bfdb0d3fbfb50dc9229e54149ef09b95bbf624eb04ce1427077f30d8536be9f69970ddb449ca22ab8368d2689ed4 936e876ac259b86512bb223b3f5c1a2162c8c7a0a410679782833e5a19d452acb424acd9c795a06c4a5ba59033131a42 +9431c6c5237f6b4b35682a0c32f68752035c8b295a1763c5dbdfd73466cea64a00ecc11356d02d2a9211dc54548f5db1651e4471898402c887fbf45005a3bda271df0158c98319d4d6751b8ca6b07100182957d5fe0d97c4e2294406f83e9afcae4850bb089f2252490417b5afd8f07f4c795fa84c9c7cdcce26bd97273c0072 017ed9a9c75cf66528428e85b0f019e3488af8b893b12023ff1b4ca9c3691b74e594539afa0f4d7c3863d15399b862f15e27bb077392d6bbd546ddfd46728c75177338466eb2f4ff a9517a074f4d78f0aaa551e7657a892453fef719a91841c41c585ff9231b0d9204913b24be738fa8ddb8f66241dc65fc +417cd5f60416f17081d2c70e9a510114e08be83573bf9deae75fbc3095dffc8a7f7325f61f9d6565381710eda871388cb17619e4448836076338ee309a2bba5f737319002e259b4a875cce1bb97996101c9a7abe0278dcac203a712f0809eb3c4b85a9c380550ab0bbc5067a8edfa78abf03c09b5c08f21714e1022ebfcada4a 01bcc09b3f2f1d26ab9955bff7e8c0f85c8a61293511a196b53d7963f4a4503849c96fb4daa68c9852ad9185e01a35f0bf298e34a09ec352cb6da34f89a1f23e8ea27712a8f43aa7 988d8366d9bbac609e7c3eada20de6a3e83be9997144f305ef76cc5071ac90ae00293191c1efcfbfc7c03a379f2ee52c +eced8c412a153a643ccd69596389f83b6a36880286f8aeede503452bef8305942d95734fb5733f37ffeceb1c2dae7b1396c3323de11089082745c28a1756f784423fa7ad68bbfbf0d93ff8b7ad62220500df6d6895788402c1f5c69c06dd9ef55e2401cf297184e411be87c1bba657f847208c0e750f94a3df92f253b377b4da 00ec52fc3d9c272ca80623e06b15c35f349b13548ef7ee400bbfa04196850b3b8cc7b239238c827f9b0a3160cd97969ce21d66752791f5896e0385b0527d4d77e4b9fc70f04d73b2 93bcc52c157c2bf3c275021900143f465339e06fabd4bf7c00f4c01271de9c69948e3ed190937e4e39fca59930f206ac +30e83ea39a92036e22b7bed7639eab5e5be1d00c20b4a9b9afa9a0d1653369cbef363c119cc6f921c8f84663949c8b8dc9b743ac2b1861a480476e9b64c8f333f34b6fa0e1ddf09d49618ee4f3c1f46751b5595f0aea413d4ca46f3c26b974b112cbe99c813a96a4423764c069454946f213c5f066ec38108f947abeeeb02fb8 006403de7627de22d1dcf6b8da5af62f9ec59ec065cc1ca1311bb98aa439a6d5985619b17c17a70f59e17cf180ea6828ef57f5f1f8ef05680a9fc12ab7faad5af61e4e11fb45d341 80378caaebbbfb6157b4f70d9b20dcff5dd93c10e385c09097dbfff1375436dea0554d91afff020093c70286602a0013 +3ed244dc16a5cb292db4b1433b0ca3226913f07377faa20c6c1402cb4d026de808ca74a6d4ecdd7c4e662105bff6edb9fae0117c50aa053aef677c0750c7a446edbb879110030758912e8fa666489d702d8fceb719963b24a256429bbcc869a1f4ab9de9db89263e3684d4daa1df2ed94bb59dde2abba63793e5f82aa2e4db83 001fb980aef64254aeb9bb613ff2fc6967503db4bc1f337882f1566cbeb57489cf32e34f310549f41cba1b951f487453c29753a184e33330e90d4b973d2e406c99a239a5c3f96233 84f4e8f88a96ba50265439dedb6d73c3d61dded5762c0de391c03f1e11e4536eaad4c3831b420ae8213831a15b6564c5 +40343935d9423ad30f3fb1832bb08a5d20ddb3a55b59057cd275320db4a5835471c96cfb7d67f41ef860cf5879897b8dcf307bd1a52a6226847b768ea38ff1858f59e64cd635b51e6863773cc6c64b363ec47ca39266422406264668415c189e2f92447ac4c63ee5d74e95d1e6af05016917ad237f482ea0b02aecadd370a8bb 01d96dc09dfaf602789c1dffa5c9ba130832badcf180429660daadf4cf1be5cca92fe9713173861670eebfe3a0ba25bcc76aecac60a756f07b69687e05c7e25984a39556469f62b4 acadf0ad508afa5fde6856e251682edf734e00b81ad7a11dac35a550721337e25cee923cae185002834324ee34f3b68b +274567f8841183e68c4f6c6b36c5a52fb0e88492e4076b9cd768bf571facf39dad6affeb68941ee326ee461ce1f33c26e4bfb3c9e0cae8241fbcc14cc69c1af68701fd0be3def1e87b7d52b682ebbe1cc225c1bd177b0886e3698a06d0e410a1f92c9bdf7239189f6acde0d0653815a72987671b415d1e8a70e685d6e5b14c33 009d98b32c8eacd135ffb8e13223690ef02c0c1f29ea8b4da193502c8cb3f39f9eed608c02fd457f2fb685ec4595e8fc8f388d26778d225d2b18c9bc8b199d8b65c0d1a6af33854a 80936112f52cf42877d42c4d5e2e5ce6fe4ededbc82538e7fa98276f9dfc2532b63bbce298bca1d2bdc4f714563ef6ef +d9c99b8da92d3c2e40dea3c4025dc37770e867c4d2746c4d726b6de24250591a586c166c88acb8ed340e161d4c81b9d14c919a1b06f1feb22c5ce5fca2693bdaf4994ac72c8983c87f331473fd094eccb3d5f3528e69d487562fb5a65c150a8217192f8aabfa7adcfd0b6916d5000248fbbddf1ca2f38e3d9ed2b388998b7cfc 004d873ac744c4f68bb044783ad69e1a733cb8b8f483f2695bbd90c4211282036ad7914a53b25c3e890c6824643cffbdc4138d7ff457e3fbb99387494eb5cf2bdf1ad243a3a1e644 a7960fe51af68f073d9c579e55b2d7b10a97b1a8e8388677e8651ec11ffb123662fc0652288f8e40b28b060849e83ef8 +d2b88a01fa17703c99e5b867c645e98feec0d6d1afaa20a97b5fce9c23f0594460142af4e36a5739b8d26d3ba35a0263caa5429b4abba157f359fce701c43372500fd2ae1bc2ed80bfcaf8cab7016ff93d4a27f565b7e67fe7dde22bf02c48be12114fbff2421517c825019c0ccc72d927bef156140d7f0e9b6ee37af78c3efa 018d2eb947297a054f8a789771dd875b12b26ef057fb91235dff3b062916f85aab3365609bd2a38a861439c8514e33f174c198139354e63766942f605107cb1b9709b782622b295a a97af7cba5d26b50f5e55e13d9a2fe7d664bf12ca0077a7829018c6954a1c5c21c1ec300883a8cccb3f2089dda1f1b34 +a704a1428cc894f958774368979fe075353b56790555386e3b043dc6a2919b94a11c7f85883f46b4d47b324d349c28c667bf9a000daaca1d7191f2a0fd97a4867aa9f72422134a690625408a9ea4b723704690b69152655f9e9dd5fa3dd94814d97dd4f13e85c3f9bca769491c2461fbd17e28afac00bfa81371d5039013da8c 00594fc0b7a5cc0216d2e78eeeb6394c8225de795f4b73bec48b2f4ede185ba622b59a16dd3eedf8cf2c94f2ccd6dcd205f64c97cf1b7f1e34129e94b5129502909f43940dba0746 9871469680588f57c15225a3ff624fe4e2c708ef66a1784483fa7f82f65352977e7757a37a6611e85c64cebf25a52db5 +f8a87c4acadee27a908718461e3b45060ae4ebb009b10a15926460bf219cb7e75dc3a993fb9a741b94e2fd71615c50f6df958568f452b2cc284f0516816bc0d2e2d45f663155660a26326f63f4aa42a6e1cc8462a2ec620a365257ec042f55e4047b62af689592a1a072553ff174dd629a4f51837780ca232cf479a68c1ebdda 00f000631106c5851e8ae0802b01e7a8a8540b427a8a3956a1d36f0600be89318032320cc420931d825cc964e823745c60aad3437ebc1c91d32004472e9677605fb708e5a71a0d83 8b1bccb0ff491cc976ae541709fdf5a783873429b207c2ea30ae9b9d7e24da484edd018541bda72f8a3a16818389d945 +10b5438294a77c7e517ecfe8f8cd58d75297b14116aa93e574996ec4acb21837e6297cc0e7e7b5861e862062f192f2206a01b1caf42c6d7181d02c7d62b76c2881f8479449b02d32c6f792714d8f70f0c75e81c7d9abb996be87f5ad9a01fe42b75855558d5f00df392b62ae0d258f3f67dbeaf07208952e679a2c573aca941b 01023997206341c6147c536d034a9c38b4012035dc2c9b7ef0bb9cfe65e7d788296f055d508a1fd957b2dc7f9eb10c27790f15f30d81670945e54a508c57b70b46b4a09f4c769289 80b4af4868eb966e99296d69af87bf6303a17e8787b69649e58345245f9bc67820978711b3bd5733bbba75faaa096717 +d83a52d43216fdb16b1b40469863ca8eff4df9fa358deccb5ffd18b3e22a9d654aedc98f3dbdc4f5b4e56b4299e25d8a5a38d01b34eb93de382df1ae4d1c7f966e84b84c393d167aecc6f1192c4b42cae83748b1ee3d9147ce7de74cebd122695b455e8082f86e3e488fb0f51b3b7edcd579940d1cb9d045296e5e38f201b7ef 011ebf320ecf6a908ea5b868afb8e22246ce84e743e1076d6185ec65dd79043380708bf8da4ba802c3b93b8d15509bb7d7de9dc29f1e9fb0f0f2cb97a26698f955b1f7ef668122be 8ba7e6ac8de18474ebccf5146451b1367e3638e8e03d91c3f91912fd27bceee19774d0f0ddf1b29d922ccb8dd201bf0b +eddf5553ed4db6e8ce72cbcb59fb1eb80671c884ebd68e24bd7abe98bb1f40806de646f4d509be50a3fabfa85c5630905ce81abfad8a55f4cd80208afffb9056bc67d9dd7f4660a5f924af2a3745eec2daec39a3fe36131fe9eea444b92d31f6a125f12125159ba095f89968a7028549466f41ad45668a861f671050d2a6f343 00746d5c824d78f42a1fd63d8fcca61f154ba3e75788b7a0b87f53e5420e23a935b02eaf67bace8dd8a8e7c1caee30154c2428e0a437cf12e235f41c416f92fb54528865fd4766d1 8af38d593deb7c6641de0116b7dd752439197ab559a455b6ca9055db51bde6b37f06434b33f50df2b5f92d65e975afdf +3db94335f6d1a125309622c0a9d71bde1da09371f0285a93bd0aac255fa8f10a56074e0f6057f1b1aecf2d86a2319590ead96a2ad1336fe844e09339b456be32374ba2e659fbe9d0f2cdd83444d117d2ce3204ce4b4294dd05405634b84747ffb4227160c4e5c2c9da9815b0c6d20f55705f16cdbaa13d107ae666d707ccbe6c 000670e72ac2de50dd2cdd975a6cdab10ac45e37ef7a28c685d77447051496b5e161f8b1b93f6c7f32fce8ea05e94ed35fd7cb28c44bf51ea29cbaf5aaa31d6abca30a89430323dc b2932baa70ffdddcaf0d35749949ef3cdd180d44fdf06895f9ce8b7c5403b5d37cdfdac9108f4345f0805f6ee739cc6f +69166ba40768d0a3930325405edfd85f3272f7b8e600b0b319f070274c91f9f03d0e6ec4bfc7b4445e91b87cecabfecf5e77c7301ee3c6b0affca2fa02c92216698705eb75443eecc25438db2d2fb4b24f4195d6b9c05c53e0868d3e58477100607ffdc31b18c40b4ad7202bb034e58653daec0f6b33c024d42a3fc84bd8f86b 00369a3bb96f884983c23281bcd04e24a3e5f6359f81e3c8e46f3f6b865eb6bdf98a630e90646275c587e41b546d3ca7688cc207afda15cf9b25cf83bd6ad27908647f3f9de59de7 a6f8481d256558722b1a1e826f9f5b5df59cff269c7474fe1122d64a1eaf520ff507b8e8d4defe8a863d2d8fd799c6d0 +f64cb668b72f1e6dd026a478505c0eb33446ae9a2993bc7648aaed02e172fa9a0e05eeec61e756ba246c1dad7e85d3f01baf734b1905c5bbd1b08d833c2cf1e079eca75b866d705c407eea8618d23ebbaf269c7185984b3bd4117ecfb295ee6b47eecc8d3a78bb96552f6be314656f91caff793838226662c75cd7804b6bef79 0026717b039df834855511815d5665ff9b654facab469390ae257b7f0eb4dfe66ea0dc037242ed0c13bf229b8f7ff26da9b55fe4750d3451c62804aad493c179ae45d08ece5af085 b56a26b0db10c02338db7d66a3aa5efb234add2d01f423606a8eb615ce0c4b573ac758b5e964925b9eaa9ce298b923c5 +51ee0b98eb6a3e3c1afcb35a33697c048dbf61374629ac5702a57801fafbea4d6fa5a26c9d1b79d1c58257ac0106387fab2d4a1b7f8c0dadcbe7c830613531b3c209bc17f792bdba1c1fae1b7528aac53dc86c2094b40194577325c05d2258303a2d17c854e7449489c43991b6877a50692a6340a528a6b188440ac0cddd4c4b 01d642f2d393ed4abea37173e4a79534af87adf534ead4a0a1c46fb047619221e3577e6b8bcc776114d01159c736ab78af3e53feac339d7afe58be8e7a8ed290f1dad960f1b5de94 80a7ca0ad21d2e7f10638a101de79980d39e5295dbe3f7f4d0ff56e8f1386ed3f291d5ee652e4cb9603973bb332d8872 +feee50aeacaccb6b1c3d95c6524044edb78322ee836d8159c4a4c2cc6982480567c4c6cc4806a564876622266e1ebd45f2f4be851b79da025bd57d0e6acce1ec1c8c255eb89713a1e4897d4ee0f7a248b9d4bd3ad5dc0e57f60ebfb65691e164bc908956a019083e923cfd33dcf37c735af3462768a1e14a8051d7aee74d5228 008cb70be29e83f697a3e2f67d86f1c1ec9a163b5335cb4a06004b6634948bf60b8ad9df9b27d2bedc4975265ce44a7884e57082d521320ca4372d38fc77b18d3fa05ad8aa5c43d6 b69e07e52aa37db7238c134018804932f6f30802a9c78b2036b38644b2f67020ad03e60c4ff393b598455ca1dceaf594 +b115f7370d6a93a90fd9dfdfb292956be34b61992ce1fa5627c5e928d74bcdeea66d4040c473306a0070fa8363c4303bea32f73ea3639b5c6676fa5a1d68a2cc1f91f00580d7453a23ae70af4cb1f1657aa82c5b305374effe5d67d559e46a6cee6360503d21070506f1af30bb000d2f2f85caa6465810f89968f33abae81cb3 01eef463771f9c6285f3257691dea0844687606d4dd00b6020517f190891cc1be97cfad21d147ed8881b5a6e19b22ceeae30e1132476325f2de0e9af2e14c80b8c780a9d2d6c96de b11100ae5d3ee12959c31f0726e3deb66d7517bdc65398390f1883018ed56f9a96a1ea572c8023f16e9259e5dbe22e35 +726782eb0d9720daa64e4a77b5d8dd67a1a193f15eb6b5162e3d89c925ba63b7c7e1c4bfc8d6f11915b0e14d16ab53ab015317bd5958b0beb6074199e05181915496575768d026c23e92e06016598de008c3718aaabcda8b68bebca0a73ecfc7327e8d3646106b7d114dabc46cfe56265c326ee56fd2ca87abb5bed8f997c735 013bd452b0880b101df1aa65724fb60d5d85b37ed5419027481661a3617e0fb37bda1151b9b5b41f908ba832011f7850b75a07b678e5b8cb35c5fc8b94a625e4398cd5ada2b04cc9 85e69513ecf4baf7a8d62ed82715cf5ab36a9fe124278c4857dbac99c96d9345ecb0764d8a598cec0c02ae957b54ffd7 +1c2418243fcd89c6382b7c3b2a8c341f26d08174a9e9296c4a5c98c5793a0fa48dce51e30811a96b515aa22bf9af89a43de06d696be1e531c5dece1f69fa6ecb7f20be063c602a16454ddafb14385ae3f8246c3f989d0566e06e7ed1864502896ea19df8393259c4dab3b3380a4a80b4103cbef4f38cb69198b7cf74ce94883b 01288141ec2244e4bb3f62daf4ee588aed09ce22be55e3d42e9085a947c1f8cd16533635d170bd64ae0b417346fa4670c25d41387acb2a8e14407a1931d9f7c5358a14eca40974bb a75d555e1849f414b902479aebe455c4d1625fefbe30570ec2456f1ad12b1ea4f60b13f25020532b279ca2972857e6eb +1de4b642ec7220c64b91561caed7832044d6e811ac909f3b199cceb0d8a7db91bcdc801412044f5c34b355b95a2c6170fe497f6d5259bc20715a38cb0341c88e93029137e94d895bab464bca6568b852340a5c5d6a225475f6eefe2fc71ffa42f857d9bab768ccaf4793c80c4751a5583269ddcfccf8283c46a1b34d84463e61 001fe06b94a27d551d409b0eb9db0b163fadcf0486e2a6074bafe167f9a3b4ce8ac11f42cf72f9a1833a126b9473163d29bca2ad139dd1a5e7fedf54798bf56507326fae73a3e9a2 838c4e4bc0344d8d9a38579170b018d6b557f13f1cf1205512b7c41ae3852a452b6903cf1877d3a5a58c6fd348721984 +70279be7d7ac72a32606642ecd81b5d4d0f95fbc3c0b07d85c16adf2788601e44dedb8e55e0f9e0b4ca3ca35f5be7511b0e69224a05204af67aae11ce154af6d594d47f6e3142ad183969544aa95cae1edf42bc699137f60178c12b10a67698e37ab9f3edbfb3acdf1b3513d62fe3db33b16cbb4e1f9dfe732c107f9d0c953f6 009cdc7e4945c485a41728f83d5188f539e372ff4fe38fffcaacbcb4522428e4f93ef4972556f4398fe17bdd885768f0fb5590df495badc794d4d274e22f2f4a2535555922fa43f9 95280949ca15fc77748f0559f033df564e1522ced99149e444e17ada31313060b89d59df615ff80612a94b30a5225ccb +4d7e0ad520445b6a5cb46b7c77fbd367614044ae6004494c2b3a89089287e2836c73b799cd8c90139eac427ebe335804c3788f3728ffb8edd7f49a4bcc76a9e24ce3c2299cea88c04645b82033115380f81b0c1d823e470631008d350cf0c0dba1915519985b8a389ccd8c809dbd5bb5051a79e631916e0d052d9b6cca18e0ef 002bc753d007c4491cfb8ce0a6c96455acd16d37e02c982db216b8cc1afd6d10c6be4e15a3988b8b8b86b2b5b59a5c1939889024849317f27ee08a06bd8e7524d4ad83a1de208564 98f27144ace5f8523f945af78904a6de60698e047e10625a812b9b593464ae0dd73813a624f3054601a88266bc51714c +d49903f38b5c9b17542310425e59377f61f5b4f4740cd97371ee2116083f7758e69e7e2c1b0950ec6b76f96e3c91c721d6f2843afde8c7505a559c8a64bca2e665aa1131b75bdf86fb5b90581c7d3b61c2cff88f3fccf356ddf5ed282e27727be061b6925c51ea7f1a495f471dc8a5ca1a88bbe29e92338d3c9361460398965a 002082c6e61d0d72f040905d8c1c20d47b029f41ec68d6cbf43ce97c3b2a0a770557a33cb803c432cfbd3958fda30ec1bba77a6613c318597a85ad02b26c44bb77ca96d9cc1194ea b640d393189ae0860f9b876d8516b0c0a9653a2ce91d13ed1e1bcbde6b056dac7f6ac56c48e8a2f86fd950c54eea7c9a +0e3f4afc3e7b25c1bf2d98098a5a87db1224d9bb45adc6e434732b8722a708ab80a1f3f6ef3c5aa70d2e1dad3e4416b12cc59171f05736c4b58bd084602c344f2f0bf3cfdcfe04c64e87597a99de23ded64b33607f7c273ec321f6462518715b11e91361e89ce5415bfc2ef520bfec378244a3bd2a4b9b6b3d68815f2f75baf6 00e298c93351323e2c5304015a4878997ae4e79d1c32f1dc64262e534d4f2c4b3e222356ffce746763373fdfb936fd330d3214a18c07f1205b20c9a941331cd676040ba1fe3dbce7 b6948d5dbbc7ca5870ed0ae39435d2b33ca9e0a52cd7850bde61f8c53c33d15ffb3740bb946d00c13fb5a5638e496356 +8fe32671f6927272fd3cd8dd4e34d44d27fac8c88b41bf9a48039e914990bf06d1633b38b9200ce1c2a275b9c55498e5da2d0707322c3ea0a0fd7aff598fb801628264e13047c8008153e8595a0dc95d54e70b882ac2ac9314d2b78e7b93922da818d7075215e354708994af66958954c92c074d132dbb2488e5a531c755a8e2 0104f4ad56594c5cec2a988c5596d73adaa5a81802b40110dbae698ddb1f0b271fd1479c38abcdb9b234e69cd0da8a0328d2135c287d5b130a09fa0b899058e7800eb2dfcee95c1a afdeea2a2c01bde88050b8fd539500f9ba8f71f8ef33fd1059385c7a77d875949c8030aced575d21aa7a9544cf4300a5 +a8fa01136a0a78313a5d160c32fe5d1805eeb3730c18ca0c47818e82c48eb4c9e5b2dfe3ee5facef9ec59b68f4e6f3213f77fba9f8ba06dcde546ae348d343233883894f4423331b536f62373a495852977a51cb192cfbec04b5582b4ece69f345979e234de32da7a120138a057a7119735c4cb19099bf48bb202e7ffac04def 00c4989bf33b3136bcb4ba67906eaff2bcbc6567635aa4b057acb7353ee87ba3cb4cb9838f8f679729d5c6ed98e6c4199cf58605f009c6873a1b8321f83cd3c0973b7a3cfd9dbaa5 983eea01b71fd518351a49aa3801cc9e31d5f7793f25122ab326bef871bedddeaeba163fa50ffdcb4fc1b43a9f99adf4 +ba2d83b21c783d6ef2f3b7b10e910a418a9b9f49ae0fd37990335b3a3d15627846c9a12a1f31a3d0e062ad1bec5650606ed4dd06c30e50c1e8761a29f4ea1a20f74635d5dac22e5b787ac10f4ee82b338a641484f91771c128c84d31cdab0a6b9616078c898665655ee9dd4ae73d33b94bf091b064928b959623aa71ff73b4db 01a96f2ad56e31397e236cafc108087479c9823589a5fbc3dc7488d0e5d1199cf245d7f21f524cc0e8b47feca14c93fb760e631434a91188b32965053942f3bd39b3714f9d6f1a11 a8f94e1021cb2caff2a8ed1477d04c954e830f587ba5596eb498debc8524209949b49778833bdd829a5660b310f80d43 +ea2d5f4e9797bfc2f33f0fccaf530db2bdf8abcec00f09a0338eefdba318221ec0e050cad1a85c3f76b784c6e8c18da2b062f333eeff18b7b781e67d6d0a4368b8231a892e0f4103012348e5df53ac745e4d34e2cd1ee9369f97d4801ff485fc144b2007008036bbc07cb1c302a00054b54f3713919191e1d5052978c9c2895e 00c08ed8e0e0f8b0d0714b46a2164b933f8147692f18da97e5a108c44d5a5cf221cb50536e41832b83bff4026c6df156386235cf5e3e9a67b7cf9b2fa7707c5e0ff33a91601b8e34 a3bc514f31567abb09b5d2a010bdaa92eccfcff1bbdb637a4455a78420c253c277a1f2044cc74c4a5733bc45df75f1b1 +b2293b0a09f41decd9d8e637b1b08c2efe612f33c9c0beebb6e05033c6103b958f8aacd125d7c810b4c287349f5f922d2c6ed554be597fb8b3ba0e5a8c385ed8ae70d5ae19685298f20e8d844fb5ad98db12ba7e5f45baed9045c3e86b3cac9bd55b614b82fd075954fc59bfc6124cbd68edae988596575f379d8921b594c75d 0144090a0ee38cfa21fabcc24d35139a99656911ad4f6dbffb77dbe74e7993edfa9fd63d2c4f6bbdbc8ec21ba13c9f4a3576b5d6e3abeab5af5ac81b1f2bb6d4c42dde645d854d9c 8371b10e388ecbe49715362c81cf1f2ac5174fdc8b997944a08260bc6716ccffc5e16d6748815f33977927b914e4de61 +acce54270252e7d9e983c08c993cd6b7e3caf482a9149036afe4665bd3d0662a6818047187872862d5718b8ac063477f693caf1a9baa8bdf2f36d411a796f2b46ab56f66bc94924229f8264016d6769c85d9bbb7d6bb042fefdb8fde1be026b86af2017aacfe38c97309b4689b23fff94f1de880064f1d3ad9d74dc804c41f41 01df26b672b2e3617b6b6c631d3c6be0cb49c0a690de49643e0f416215bcdaefc03fa9c708471f1d87476d58c8f147517ec8a14aa945ef001fa01984d5c3d81f7083ea500558fef4 a0132f7afc71d3bbdd1b1a2b629f78e864497a43b9d34f233c8c4eeb1884bf0ef6bf41cfc3370abea050587dcea75bdb +e25274ded4840df0d71d3369007118f002b83e2d375c78f7e29ade067db15cce21842611f3f015db2efec57da77cb9d16eb1e00a8c1444d48dfda569e29fca1ebf40a22fc646a9fd44460f0e473bde487634bfbdac2c312f66a1c2982c6fe76c54ac72b6c8cc9345e47cb319a974b3cc4bb40634df74b4ad7e18adfa9a71ddd5 0189918b832e9fa30161fdd927bfc267f6405335df3d66d225e17173af52a671138883bcb94c4403ca3e001fcf09ef4c6488934d6775af2b1da30a8f331579af2d0fbb530298d8f9 a6a7edceb5310f1fa8400ee7b78d4ce652742d9d2ac959a7003a95a11b4ed5894ef6c046b5b2b566ed0b59a91ced19a8 +d8a4aed87c316012482819b03a1d91691f2ad11a2f46082497ea8f64880d686891f7da550b2ac17199c657d4eb9d04d5cb8eaa180f743b87d23b1c86103f9e9bb60f4e19f0ff9d160f180aed7735130c03adb62502e69be5c624ed7bda2301f30580ae0921b02e103a638f5623c02c186e3bfe6ff134c762a2bcac1f879a9353 00bdcc175eca3a399b944eb0334ff33c4fd130999c8ac0e7b52ac5b774fbad53ccc3a31024f5262b2eecfeb2104b14bb244307effe3dbe8ed25686dbf46a42c4b6f8e34010ad826a a8478f0f93affa31cd1c4ca708a47334cf5006129cce7050c331a1f11abb9eeba238e045a2169b2c96b509916e56d6bc +acbaa5ffc4eee0850075c0e502a70cc7a897a919f5e7bca4e798385601a26f411fdae5466ba9f6b6d8d7f819a749b799fbf4a3bda9105063e74914e8583ed8b31ea4d22164bee6f14bf53afca269b901c80cb3265be32ffd4ca4bc4ddb83e11eff82ead6d75dc4aec8e5c67f35d58a8a156cd1c0351abdccc0c5396c8fbe6920 0007ab5a55a1d8ecb7f5dca2afdf9ef465569a4b0374716f604ad42a6e0271e934b09655e8e2529784b69b2894bb399b02aeeae30e9e7ae70a2a8e56b9e775bd978a04c728e3951e 862af430b9513491cf2ce0cc32c4dcdc6d992f292252d88b5191d14af4c95119a4ef4ff7c650616bf2f54c6149df1f6c +9a57b63a4f418404e8f5dcf3052b9bc04a4f6d2c33bde8651506d9cbc5542ffb9023292dea463111fb78913ccdcd182faabbff9164219b8900c7f9fb394f7d9678f77b18f8d58526ec64d7c1328953b983a7c416583e05a069cd76aefe26e5f5687b70abfbf9f58f052dc0863b4fc3bef805cc3bb05bf76a83235af9d6adfe66 01e7d4da72b1d82e17a066fe387f2a0a7fa4c60ab993ee09710531789186077f2f32b42ddda497d5fb57356383e1f96973df043307f0b6519430c3f0d40d62954032872fceb7dce9 856fb83a1571bffe359fa1d74750a5ca67e653099314d19494ad9592ff34dbea83ef66ea4247f5bcaf15916918a4a399 +97b79c76d9c637f51294369e0bb52c4189f2fd3bd0607f91834aa71b3555605a89ff68e84fb5bda603f502f620e14e8b0c7affefafa2f0b303009ee99653ae4550a05315e551dd12a4d8328279b8150d030b03c5650ed4f8d3ba7c3a5361f472f436b200b321e7863c771e20ddd7bdf739c51de3676f953a5501e4477aed1bd8 015b7271d4319db5743119c8103a7d4c6d57e9c62f3eb93762156d2ebd159980aa57cea948e416717d715a2e458851f1b2e9ad4172bbcc53861db29c3ee0ba8e82617a5866170847 a000ee406f2fbb7819b2ba2dda3a6ee9d1c39b5109263c5cfa0544901b68a9cf24d4d65cb4513f975ca2e1dca3904503 +564ad0e37c9c37a60872a4780a723d08d1159ddc77bd834d74c1025cdf3cbd5338c3fc07a904fcad9b979b2a2ceb1a0139af35e5112305fd662a57af6312624b9bdd3a64849f95f59a46ca8feb2ed56f87f258518947474c1729275c4d89b7dd286ed65f286cbac76002cc63b92a73ab6bd13c4adef282f32297e441bdd8fd36 007219ea7917d174a5386df985d0dca798ac9f8e215ab2f0003aee929a2dbd91e37fedead0ed95b1e8aabcf516bdf54337b4aff7ace4c6b3179f2e919a49db50a41c9d4d58d4f636 a3d22e48b358e8560863934c76e2d14d74dc1f532cecaa489be15e2fa3254486110d5a19a3768495306578664d961752 +072ed5b14754fddaf54e20da42432df49bef38f4a3b1841b2db457ff86c44880727aca945770adb41269df41fc17f6a687bcaffaa45a3e59070526ed53b8dc3b78cf9a80a85461eaf4b477e44d5ec4c2bab9c05aa747a5a520b35fd09e8b44539d060ba1c3470267e0dda111b15dbb587614a46e1e477127f963a16cf3a43ee5 00bc623152253da24bf8d752bd78aedf7d5f6a2f889453ccdec14e10753335ea8bea83fd181a1f3680ed50f2324fbeaadae160cc85831750e021f3e44121ea1b1efc29a7d0069479 96407c4018c4f371fb2d1ae65571852a9b2e3102aeb65862a02066ffb0c2fb2696283ab999e59671ab8fd8747680aa07 +e660dbdf3e61af39b83b95d3f1970f66d616f03273f7dddb98f768452b21cd39604a31cf80590d4a5e4b0d4917519e10fd325dd4ab7a52d70d154506329baefe0d5816f514ae109483122b4fa8fa1ebd7fdf1fc4e21e8d278a50c05d81c8f489596633d949c6c8fea96fe91430c01522a5afbd5042be8aa47da04581b2bd21cc 00645947d981d258f2954558c31022a3b6ba5fa7b675312f794cb61bfff1d9ce87267e4a1dacb7c8fc58624d31c85ebe22f80d26a620fed5df5bf38515e0903f0b69a606048197d8 967f8e0d0e07c6fad24deffd020c62a558ad877f0c30e4b745345a8b180f8a0a8910a90118830058aa1b3a0a9f6ee3c3 +8c9acbdc431565feae60e08bc7da113e12372ed373f1e1fdd581f98c8a7b0c79ac4aa42c7ffbc963fb4970fe26c5b5dd314b7051fe971c1186ebcb5650f7f7011a924de893f06961b8c75da7bff331847feead4abd2e8b9d6ecbedac18f4eac207b948e6e4215e4d5cb483e5c66ce7ad788cb89604d3a3e051539094079e7bdb 014cf93ca69d94ee8fbea0c8da9d76aea092b73073d8f5385b65c6dd4d567fe86bc2cfb8e8be890c3c6cd9abf7dc3a17eaecee3d7a9455887863e496c48dc3e47821bd3d825b6bed 965b319d6f151b7824b910ef11c1d7cc2ae413e6f48eb9b43ada80b30177a9d8645e07da7e22bc2e147311ceda835c96 +53ef87d6ac7b9698f40b3ea9f3442e7b64207b140b7f66f73fb7d5f8f98452d30a4e493b6c0e3268371e88e612b818d4d847f032ed4983817d020411a52d81fd2a17b58ebdec199d817c2a8ba77042bbd747a6fd4bcc7e844ea829fd8461b389aa0b5957d92962b6d4e86385a8fbca90b8fac40944607117e9a4ef6dccb8fc1e 0033feeaaaa28f16bfaf5ea9c7319cf4561ba4fc55327a8477b6cd58ef6ccad3962ee1f3edb243f3a04e7e49c8e23509fa2d63252adb186b8bc7e9255cd61fa9bc45242d42da3a68 8c1c56e84c0755a58066772321774ccffc4a6a06183afe8b947d2105f4754873c1658a0b0f780cf2f024ba69c3bf8f40 +dca1b7a9a313ead11c2d54739d9017ae27f9d08b3544e418aee862bb57e427636cb6aedda28e10f12aa15d2355f4f8ef112a86fec5dc46e6acef693cb8fc37c3e4885f3be3d3ab31ea4d73a0de904e95c7135a149f77b621d642f9bd8ba192d39cfc58b6f19a797c4f3b4f3a87054298e3ce5eda0ff7f44f8134c9a108285dfa 005613dfb53149bf5fdc4e08ccc1c752b0b66ab43aef2d008ed40f3df40fcbb2938d2c41e3ea2dd4428aeba9059a97efe5593119673866a19d27a2ee37dd357e22b6bc849e7e22cc 877cc1963044b474be7f50b774ac4e8300b06003c16c5e5c8dc1c990bc4cbf2a5a42ab01758ecbfaf3033ad533ae9e12 +aff61d62c8f5c31bbb7d0a64a6ac589e918bbf2f13e7ad13abb9ac26405e267249a7c9922139bc28140833e10976b87e91cf28285274b2b48b63d24ac94c85c70fafa78f8ad05955c0ce6c02b841ee196dab12306e3e3d6138371217e2b474f7e67a80bbb78a47e374ffe2c9f86292e471c551da50d46e7b5c8331029f369767 011b92c8b72b86c51903387a65aa206988d443d1988253329ad3a89c902ff1ef8cf73b7f2e4aaa352443bcb833712d94c3e637ec12cbe4c2d4606878576b17fae1512fc77785b737 995a9132b3c3915785a4f36154f937696c3bfe89f6b80537444fea13ebda0975cc833dd8c2e4bcd64095324079193589 +721017294f17ef351e41256b57a64a79f3636628c4bcbe676ac9a2d96076b913dc4b246c9945183ec9bd2d251441b5101eac44e2fa1bef59dec03ccd7fa5accf3b7d094d68dcf78c8de4e2f19f56bf0dcb3b66b9421ec3f8b353b9fd74feb2e9affe0bf9aa421b6f03eeba3ffd58fba56b3ebd094880e50de01ee62a108a24cf 00c3c90d5ce4375a08b85575faa78ee6bbd9e5571ce5a90582042617b807339c282cdc3b003d82006264b1c08c20af4ad4549fbde53d262facb98d923d81b8eb6093374b6a1e84cb a8599c475d2bf5df50e2688d4234ce89b9606de32a8744a11bc48b34f96fc2e02e611f79ce2f3e9a409cdfbe05ceb971 +e2d1f33681759adb7954bb5248b0db3c3885fea0d4c1c0c226eb1e6d2d3ef1b9ac281a0f1c2fe5175b67114b6a501e2426d1454bd5790dcbc4c232cf06b017de8a9bb39e6033f1edb5003e8de3b44cc3d6150c3c952afb442952483cc688908337b7c1a8b5c9da70937ccfa98b2b0098c530ff848010b8e8ee0a8d65283481a8 010f184c16228d9034271332178ed485d10b6aa76003efc160d63fea26fbbdf5552205ac7df0d8c852a1210cf0ba512f20b798827b36ad56b12a826fa7dc1db45aed264ca6822659 ae21295d90bc5137101bf074d32a781e89acab7f656afde2c4593d4384daa2250fdbf94c984180c9f0b6720308ccdeae +414fc5d2bd56b30040e105cb891788792da595583b11b8fcc7320f40dbf64d9263532dc57344dd17573c95eedf851668b5d552e8796af205f3a0043af1a829fabc2e93d9af9091fdd9e0fcbcc9d6d9ec960aa60e4e2964c29a2f375400366480e513f63d124db7745847310e69a38c8455e4e602056a6a4a14a8694155e0a9bf 0181baf9d497159f837cba58a11ca435c442e5ca792ea559bff9f6a1f562c05bf6bb5914afbd1bcaea75b35f88bdd832314b249a5298622c89462344d3f28a44ba3d059df432fc71 a9742716f90ba0893c9ee18bd45b24ac62f539af753b671a5d2bbaabe6f3bfff13c95065454bbd3a83dfb3fa1cfae16a +3b592cc8972a4782870e079b82a50f84b4c2d8ca90bd500d1ce5678982e266c391c556d8162ac3aab967154d072dbc0ba1dab5545cf2651753dee2881eca5abd412fe624bf3f9d17d33692d21ce23ad15ccffdfd250cb1949e73c9e40a64ebebb03852e92692dad1d7baef97fe109f35b7a492b343d4b643a4a7b1723eaecb64 0083fae86ab96bce99a53e50b7eecff38e4e25b21c4b0f6a4986915de245eae24f16b6a00a4db159ebc27f5a6a072da94ab6be5bf75f5eb3f75c4452bf4ea7014392eb1e02706fb4 a39b5137d9c2f72086e7353c60b08befe828f0b10082c6f5830d00b2ff4ce28baa435eab6516ccd29d088e1a797e3930 +0079a02cbab3dc02601fcb5c8607d555beef7cd71a66911ab6514a4ae21c5a9c0e166f8cf5fb198ec5a49a96e17cf041f35f00406b79270ebfe56dc6b8417d2529fd625686ffbc8f69685aefa2fd30a937c02f25b48be4679e6fde821de928b33b12470867def874bb8c7c8038ab6594346a2c44b39210d3610994ba60a05e06 01a663efa7bf4d8479bc535fad71e9b5e4f4281aec55967baa008ba17ac2f89cc3398d30573edef29d590fddce8cb157f655e92779f59e7a18d0327d02e7daf4c1216143b3688fed ad035603f63b53bc7c8d2cefa247c4d044923e5e48593fa59bb7ce89787742f83986de43751830567354fe330a7fae67 +88573bd94ef50459814806efa868ebf92b066fbc2f7a4be9d2fa06b9dc1a72f72d783a6bcbc107b18a6314511bff217037a2252e7a5cd34cf9d5b2fe9c7846931f0133b2e95876cb800dc4ed7c4a4e4cc4f1195acf99fb0ec224b1f8fa8af71f72d390eca9d6be3879032a318734a63fec336c79035a43f70271def10c4955d3 00088d1a2c0219696a94337cd56516252b74139ea0733b17fdcbf7692c3e5f6c3989e5da2aaed7468e65a5d578571928ca273ec3b6aa72cd196f560f05095cdc8346e5d31c4c2e0c a0f2080d947707cfe336fc157bf6b14eb30ad8e28ef6f3681f6b8dd9077af4d003705b052b3e487999950857c34c6b1d +d0e02045ece6e338cc8ab41d4a064c982ccb1748c48fc2fe0a6f10bdc876094358a6a90a45facec798a83cc95c6795cf0f0d7c66b77e22cb114c1432bfdaa1485ff35b6a58107cac3b7e58cb4f6c87c68db60b751e78f1fdfa54b8923b98caad0a4f31226956d065c083ace5f1e9e91944dcca51879d782e40358d58ca758750 016cc8a0fd59455ed8d4de561fd518df2e008f7dfaa5f7f29ac2489a411e233917b43eb3ebe2596fc824be58871949545e667dbcf240dfb5e0c615ade0179d9ea2a1b1ebb8ab9384 85950c8b068504a4ed9264edbf75bbd863fc236201bd8a069d2ee5367560ef4ccf7449936b22d16ee87cd1c66a8ca9f0 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P224 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P224 new file mode 100644 index 000000000000..bd43f07df393 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P224 @@ -0,0 +1,60 @@ +699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615 af732793dc7a55f7d728873bb32a31e2bf01ec7b572a95101ada08043bcad549475b9dafa9fc9bbde290d61d37ad18a8 +7de42b44db0aa8bfdcdac9add227e8f0cc7ad1d94693beb5e1d325e5f3f85b3bd033fc25e9469a89733a65d1fa641f7e67d668e7c71d736233c4cba20eb83c368c506affe77946b5e2ec693798aecd7ff943cd8fab90affddf5ad5b8d1af332e6c5fe4a2df16837700b2781e08821d4fbdd8373517f5b19f9e63b89cfeeeef6f cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5 a774a6dc9c28266f014309cdd93cff5ce8c2c94598511cd271e24ea3c4761419d82949a16caf64ae99508a08d973671e +af0da3adab82784909e2b3dadcecba21eced3c60d7572023dea171044d9a10e8ba67d31b04904541b87fff32a10ccc6580869055fec6216a00320a28899859a6b61faba58a0bc10c2ba07ea16f214c3ddcc9fc5622ad1253b63fe7e95227ae3c9caa9962cffc8b1c4e8260036469d25ab0c8e3643a820b8b3a4d8d43e4b728f9 dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73 b7be2488a35727a21329df41b892451271802142d06c0b791f454134e52aef5e754e55d5edc7f84a16bc67bf00596829 +cfa56ae89727df6b7266f69d6636bf738f9e4f15f49c42a0123edac4b3743f32ea52389f919ceb90575c4184897773b2f2fc5b3fcb354880f15c93383215d3c2551fcc1b4180a1ac0f69c969bbc306acd115ce3976eff518540f43ad4076dbb5fbad9ce9b3234f1148b8f5e059192ff480fc4bcbd00d25f4d9f5ed4ba5693b6c aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e b5d6fd02217f16cfa0a008d7c3d01bbd40e749937cb35373a58b0f5b06a3851f5275fb96103bffedd350f47edaba0ac8 +c223c8009018321b987a615c3414d2bb15954933569ca989de32d6bf11107bc47a330ab6d88d9b50d106cf5777d1b736b14bc48deda1bc573a9a7dd42cd061860645306dce7a5ba8c60f135a6a21999421ce8c4670fe7287a7e9ea3aa1e0fa82721f33e6e823957fe86e2283c89ef92b13cd0333c4bb70865ae1919bf538ea34 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4 b36398542b86d224ed5a121f59d8af00bdbe822fe8fbaebbb10b1536b030c92f70262a952e787708da8fbb9f72d91fb7 +1c27273d95182c74c100d85b5c08f4b26874c2abc87f127f304aedbf52ef6540eba16dd664ae1e9e30ea1e66ff9cc9ab5a80b5bcbd19dde88a29ff10b50a6abd73388e8071306c68d0c9f6caa26b7e68de29312be959b9f4a5481f5a2ad2070a396ed3de21096541cf58c4a13308e08867565bf2df9d649357a83cdcf18d2cd9 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131 a662cc5af7ad95f88281811c7333bcbb7fff2dc50e5d697ff36dc4f13ceb65d078f075d2e02dee3b8878a4d192fa10fd +069ae374971627f6b8503f3aa63ab52bcf4f3fcae65b98cdbbf917a5b08a10dc760056714db279806a8d43485320e6fee0f1e0562e077ee270ace8d3c478d79bcdff9cf8b92fdea68421d4a276f8e62ae379387ae06b60af9eb3c40bd7a768aeffccdc8a08bc78ca2eca18061058043a0e441209c5c594842838a4d9d778a053 d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974 847a30dca347cf1ff56e749a693afd2848f0befb57b398cf818021c47734454f3e8d7157a175ba6cebdd2dcab11b78ad +d0d5ae3e33600aa21c1606caec449eee678c87cb593594be1fbb048cc7cfd076e5cc7132ebe290c4c014e7a517a0d5972759acfa1438d9d2e5d236d19ac92136f6252b7e5bea7588dcba6522b6b18128f003ecab5cb4908832fb5a375cf820f8f0e9ee870653a73dc2282f2d45622a2f0e85cba05c567baf1b9862b79a4b244e 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8 a07c3d9fa48fc5e7b0a5905036392f14fe4895e5041d5f8ffa1e9bc66c98e45766012caeecc8d81adbebaae728e227a0 +79b7375ae7a4f2e4adad8765d14c1540cd9979db38076c157c1837c760ca6febbb18fd42152335929b735e1a08041bd38d315cd4c6b7dd2729de8752f531f07fe4ddc4f1899debc0311eef0019170b58e08895b439ddf09fbf0aeb1e2fd35c2ef7ae402308c3637733802601dd218fb14c22f57870835b10818369d57d318405 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2 a31b8ba29409c7264d4bcbc64843aa3cb79520ebc764ff1761ae21742b6c1cf326783f772bb0f94b5c2acca25d381777 +8c7de96e6880d5b6efc19646b9d3d56490775cb3faab342e64db2e388c4bd9e94c4e69a63ccdb7e007a19711e69c06f106b71c983a6d97c4589045666c6ab5ea7b5b6d096ddf6fd35b819f1506a3c37ddd40929504f9f079c8d83820fc8493f97b2298aebe48fdb4ff472b29018fc2b1163a22bfbb1de413e8645e871291a9f6 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7 a6512474946557cd884667287f72a4d52717cca32a04b915444f770f1467f8408ec7012050095c6e6cb435da9a1e5e33 +c89766374c5a5ccef5823e7a9b54af835ac56afbbb517bd77bfecf3fea876bd0cc9ea486e3d685cfe3fb05f25d9c67992cd7863c80a55c7a263249eb3996c4698ad7381131bf3700b7b24d7ca281a100cf2b750e7f0f933e662a08d9f9e47d779fb03754bd20931262ff381a2fe7d1dc94f4a0520de73fa72020494d3133ecf7 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b b0a712af9d6261c1c71eb99d6e78e089530eeac929ed48c60c15582a5b54259433aa1a561e3df7a6b4e30545ebd68d4c +30f0e3b502eec5646929d48fd46aa73991d82079c7bd50a38b38ec0bd84167c8cf5ba39bec26999e70208af9b445046cd9d20c82b7629ca1e51bdd00daddbc35f9eb036a15ac57898642d9db09479a38cc80a2e41e380c8a766b2d623de2de798e1eabc02234b89b85d60154460c3bf12764f3fbf17fcccc82df516a2fbe4ecf c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6 871956c090a6c1a2ab1c36ac41f02ad9d3e3149f4ae406d1772e6647bbfd437f315e2a3719f2bf46849781722948ea19 +6bbb4bf987c8e5069e47c1a541b48b8a3e6d14bfd9ac6dfaa7503b64ab5e1a55f63e91cf5c3e703ac27ad88756dd7fb2d73b909fc15302d0592b974d47e72e60ed339a40b34d39a49b69ea4a5d26ce86f3ca00a70f1cd416a6a5722e8f39d1f0e966981803d6f46dac34e4c7640204cd0d9f1e53fc3acf30096cd00fa80b3ae9 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc b00fdc22dffe5ea0bf7dfce592c505002aa7138c984e06d61a5d888ae064206aefe12eb41238d84e3e756e381c389c0e +05b8f8e56214d4217323f2066f974f638f0b83689fc4ed1201848230efdc1fbca8f70359cecc921050141d3b02c2f17aa306fc2ce5fc06e7d0f4be162fcd985a0b687b4ba09b681cb52ffe890bf5bb4a104cb2e770c04df433013605eb8c72a09902f4246d6c22b8c191ef1b0bece10d5ce2744fc7345307dd1b41b6eff0ca89 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3 b9b178caa37302f0c7c1ebf43bf68fb11bd706d30b8f6ea472e82669f2ce030dbb73f56a54ca9035e243dd329a15a5e7 +e5c979f0832242b143077bce6ef146a53bb4c53abfc033473c59f3c4095a68b7a504b609f2ab163b5f88f374f0f3bff8762278b1f1c37323b9ed448e3de33e6443796a9ecaa466aa75175375418186c352018a57ce874e44ae72401d5c0f401b5a51804724c10653fded9066e8994d36a137fdeb9364601daeef09fd174dde4a 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912 a6c0bd3ecd74ce19757f459ba1c1c7390ae8f51587cb27562e06abb6c1d6e5205a46be2144c1bb58d93bee95fa3b637d +2b49de971bb0f705a3fb5914eb7638d72884a6c3550667dbfdf301adf26bde02f387fd426a31be6c9ff8bfe8690c8113c88576427f1466508458349fc86036afcfb66448b947707e791e71f558b2bf4e7e7507773aaf4e9af51eda95cbce0a0f752b216f8a54a045d47801ff410ee411a1b66a516f278327df2462fb5619470e 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa 8f16d9a8ab89fcc783c1fea5ee835b042a125203e5e25062bf9b2381a496ff4fe5a06a58cf2b0097b069f46b748948d5 +1fa7201d96ad4d190415f2656d1387fa886afc38e5cd18b8c60da367acf32c627d2c9ea19ef3f030e559fc2a21695cdbb65ddf6ba36a70af0d3fa292a32de31da6acc6108ab2be8bd37843338f0c37c2d62648d3d49013edeb9e179dadf78bf885f95e712fcdfcc8a172e47c09ab159f3a00ed7b930f628c3c48257e92fc7407 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972 a893b35e54fac2a9523dd8117045026610654abc0b88fe2990318beb6c23a34db146f4f85694576d520fef880b40e450 +74715fe10748a5b98b138f390f7ca9629c584c5d6ad268fc455c8de2e800b73fa1ea9aaee85de58baa2ce9ce68d822fc31842c6b153baef3a12bf6b4541f74af65430ae931a64c8b4950ad1c76b31aea8c229b3623390e233c112586aa5907bbe419841f54f0a7d6d19c003b91dc84bbb59b14ec477a1e9d194c137e21c75bbb f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170 a957451ffc556983632011387f222020243c26b1d2cddf696f5888d15a04c915d171c651a3731d427cfd2c8854ed457e +d10131982dd1a1d839aba383cd72855bf41061c0cb04dfa1acad3181f240341d744ca6002b52f25fb3c63f16d050c4a4ef2c0ebf5f16ce987558f4b9d4a5ad3c6b81b617de00e04ba32282d8bf223bfedbb325b741dfdc8f56fa85c65d42f05f6a1330d8cc6664ad32050dd7b9e3993f4d6c91e5e12cbd9e82196e009ad22560 c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85 a31e73567364e2e108b3fb6b6c26d1d1df4fd5e5d139cabd499a5bcb8de78618a80a0927a0c73547dbc82634aac87fff +ef9dbd90ded96ad627a0a987ab90537a3e7acc1fdfa991088e9d999fd726e3ce1e1bd89a7df08d8c2bf51085254c89dc67bc21e8a1a93f33a38c18c0ce3880e958ac3e3dbe8aec49f981821c4ac6812dd29fab3a9ebe7fbd799fb50f12021b48d1d9abca8842547b3b99befa612cc8b4ca5f9412e0352e72ab1344a0ac2913db 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6 96882e2d0d6f8c585acc7ce50b1bc5c863d52001dc0eb8c90fb0bc6909915adb88a6570a6e007ec9ec7dd386dd212143 +4cc91f744ac858d3577e48813219aa3538dd813b186b42d1e6218376f07cc1cc448ddd6b37240e98bf953f49cf54d65c12878b33c0bf6eb1c60254f0b6fa974f847e53abc56773eef6f29885dfc619e6a48fc15a667ca94001a0c945b6357a53221b0f4b266181456b0d2d25e90708777f1a6f85971c00140c631c1991e0fd06 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39 938cdd6d64a400ba023de2e012188b982279870c39f0701884c42e2267a6f5071a62d306edd5958d4f555ada2330f84b +58f43cc1924de4bc5867664adbc9d26b4f096a43aca47c27c52851b006dc2a658919ef9ce5b5ac48372703be15ac51631c2bd84b88f479f113b0569a9a09e230ec1e8e573474c6075284d3e57d973829af35325d9e7dab4a5f9b065155bbcaff3642a82ef4c9b9e127d3575c050721653da3b087d3fa394192897a5519527d19 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6 b32a87b2a1f6c1808276889b70ba20a4ab1db8ddfb7743519f9eb9230fc1bbf217d15fcb5bacb63e5790157c127cbbe0 +113a2806b052fde683ee09453098e402204155afb3776fd1cad3a9103421d327eab8f9ec0dd050ffcc83f93b34ea707705fabeccfe43ab1a71c95298fd3ec769d99ead1066950eee677d225816e0faad19cf69e1b35d16771689e2092cafe16d7c0dd7b0db73fffb8d0f3eaed83004dd21e753530ec939c89ba25578fa5f785b 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b 805d3a0b1e3e57876241a2da2c477678f25e427b922913b896397d2c26b0f288e8788d5a78f9007d49c3ad6e9dc055cc +64cbfc8f2e2149a31b3e8a80c4a552f6c62aaeb7990b6e0ee55500a9d17be04213406578caf315951086dff5c2af3b5ce17d425d185101ef26f86396ba3a129a4f3f8e2dd595f59efb6c0f5c2dcc394569d7268695e9ac7daa84203f1f1895f1f9e4b514a5c9cd23baa63454710144fe735ad9b8f42d8c43267aa434a26d7e5f 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b 8b148cb6f3c2656908c17d2ae53aed6e42516b5fd8496035d0f39a362a94cebe4f3d3cc67512050548709f6f70096f4f +a10a11c8e30fff118d371daf824f16c08200b83ea059436466a4611ccac93b2dea2de8c1006f946196aef7fe9b0c251a391b0340f21797798278b412ff2b53842eec6450728e2bca062f8337a2c204b9ea04ff660cd4d4db559f2f11c4d8ef199021339fcc82396f7a93926cf5f247e37d8067fe50692de54f102bd5ab51925c 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8 b7e71b2e52825f983d3c6aee3fa3a83bfe5101073c10741debcd405e57038e6ea2e8fcbb8995346b7776b2fa0a15a227 +b3f720bf566ffa369259f4361959ae0641d2755ec264a4c4349981df2b02563275b2b9adb5aee47f7a456760a971991ffed6b17809bb9694138d1677fa916123795239353158fc6b22d10f20d26f5d2dcd8c56c44373eea5b93067dba2d7c5318dac2e9e8714873cb1b37f58c011fd14fa1e535554efe05f468bfc8e11cd8b99 e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784 93ca3f585151f26b9a75e3aa3dc2c2c31b0d255407c978eed6c42390de0fd143fbef024f49cca7b7c634e689f0602ed1 +0a398a46df7ccc48d1e7833f8bbc67100f1ef77a62dc78bbc115b2a662f9591fbaaa91ad3d788e2fdd1b3164e45293d4f5686c151296901768028ac80ded4bf89c647ad35f0c7c4cb318c0c757c1d83c44d850e5fd4677281b3f13b1ee54de79c8c042813f9d3312dcc6111a68299cb7e829557d7f3d96e702f65aefc6499415 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c b2010fa94a15974b61a62b243bc4bfb60efc96c87c0220b1b5b8a36fb4345a80b6bfc9548489992ca77576ecd5929dc8 +8c33616821a6038b448d8918668977fcf1ef5aa0cf7c341837b39bbcc9bca875a3757f4b392630e9995b9bbe4eb66978b877586adaa02f99d2344dae082a7603351d8ffcfca081ab403cd0acb90d078dd1d0789c2eb3185c62bff2d9f04cd38e509e3b83c12ed0a5c6808fc42f7ba5b06acdc496c8ad9be648ee6a4505f8560f 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583 94672602e46bd90e1425a58e6f49eec7fb4030e67fe73a00556fb1a57edad30d20410582af39b5e3fe1c87677e79407f +94d56535fd4edfe67a0daa6579f9d53bf6b7b8830ae2aeb62892ff59f18756ddf2811b449c7d20d65d54f8507de4e7c50eaa084830637812aa4b250a4d61ab67845be36e4a41cdc0a70f8d6e3a63d4514f0dc197e6486015046a316153d5f3a3a4a0ae1ed7ea5fa55e12e73d333333685c02e0eb636234ea7e6d4b76b4b76b5a 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2 876dad1ada45c829bd02e44193f236e8ec0ea0b3fc638166f09a567a570571ed0806a2804a954963b3d3d8f6fb4a4311 +5d8ebdf9eb28b47bdafaa36bf0b66a9eaf99b6c83959da4f2b1151b4f4ecd28fb115a64c0cb9491093a7e9b9c53ec423e4c72e7765bb9c818da0e8c428667e44474a71db4867130c77c40bfd8544b2d7b9d6464d2b8e6a48482153256a32437c3a747231f51134dd14c703407e31146a6fcde23bededcf16950486e90ca69ac0 f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc 8dfe4cf7243db0e0cb1b74264b0b43c0a4ddbf520e07a774732dc4988393abe3fc3c5b6e52958b48fddeccbf5bf44826 +25e4416695f77551fdce276355528ccf1ddc2483821c5d22d751d50111ca2fadc6593b52c74f4b5957494f1df25b0b2f86950d0d19229ec6506fee8581d2dd09d48418b146ff16bd84a17ca0dc83b1888eb407376da6c8a88fa1e60b8c2a2471dfde4b3996ef673d5bde3d70c434dc9f2488e9de16ae657d29e5e59ec922a1ec 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd 883b102bf43199c6344aae82c19dabb0568ca9000bec3ecc2f8fd5cc0d0bd9cf6f5028b6168bba3864ce0bba0eeda56e +9164d633a553deccf3cbd2effccf1387fa3177cd28c95d94a7d1a3e159c5e5c027758cc26493301b2f4d141d8d07a5fe5fead987ce5f30abeafcb48c302afc6c2309f0e93d9b6818cbb6972d222cb7b01302dfe202ae83b89f53150ae4a0e2b8fc0fd1091f19b4ab2e6ab213ab322d04f2c5f57113bfad3c5675227237abf773 e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3 80ef5daffa60f949886ef24c506eb35483693a356bdf64a30a1d700222d83b83c1d56c0bffd099ca1822a7823fec040c +019df05929321ecea7ee1de4f412aba1c8d3c24437db04b194a68a0a59dd871be10bd3a4be6edf551350ea49fc7155a4d887e1221486291abe77a30633a4c4f7868fe2df24311cba0c73804883954460e122387ed414111ff96ff1aebac8b6a6491d8a0d16e48a63bf3d027c0f68ee4a4b234d73b412196706af8ea022b4dcef b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17 a0156bafec6bff847f4603aff465992279e8068601e578fc7566ad8148c98fee732bbdacc2899e3ab13fd9e51ab33ba5 +5d09d2b1d3fa6e12c10d8b26dc9aabc8dc02bd06e63ff33f8bb91ede4b8694592a69e4ed4cdf6820069e2b9c7803658949e877ffe23bf90bcf5ce1409c06c71d86885a94048b05ac0ec9db193e489a5a2bfa367caf6aa8ecdb032be366174343f6875d2fe1785e8d77334f5f469cec64998e08d3303e5c9a1923b34fdc105d65 efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085 a7e747720f0c7301283125437b01c6c1204d1cbfd806b19dda862b3fcffd6f794efe5b32edae2404906fa2ec4dd23001 +50f6dfc81c6cf189e0a310f992907fe93356cee9dea9a41c7671a8daf3f4cfe0c459ce6122c1e731dbf7593419d7114cb73b46956158a982c5d52c72f43f0f822046093c69aeff1f7e4cd8af00ba655c5baa2e7b6a400b4be1f6fd51b3e4cfb35a69c80a28c5cafb771b6c2e52e0aeef0e3fd045e8d40745f3f8b74fd969f816 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd 8db868f2902c562e2a337573432f7bac5a20502c67e4a3bc18dc56f41f1b27d1df52a0d9b97630a3e9882411f727cff4 +e90129ac6672c85bb7b6b18e9dc199c96c81fd65034b53c77818364d512366fb9cd1bc7c82404c451e561fc1ed916c0948f6ac561b33a1ccca093f07684b8c2bafa9e966377bd208556018a5bafb9edcecf70498c7140fe9c8cf3ad8b8c3b0aa489df797944465047465415bb0e24333235fcdd59a98829a3941eaaf62033e82 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d b4718530a8cad64ca4a1db045268e4508175a7590dd6480be355dcbfaa8724b7c8a96eea19e36702a627c3d370a5a5de +3c9a483c9bee33b601549c592a82e95b4319b1e74b777877f0971bcb4273716b268e8f99f876e42f942f4cf08284896bbc1ffbf094ac0956c3cedfc3580cffa8c74fc6db29a371f2da2d05edb9185ece741fe0d3fabfe9d5b4d373755ebed13dc6840cfa3283b9ea46ec8b95c434f253ae86998182e9cc0e95ee64f323fc74b0 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0 8abe31d914a0795f8637942cd676114b1b7a0de0b6e66eb22c6aa5239ee3f649d5836ba4b330f488014e5fe6f6e8bdab +bfc073fdda63c5fccaa0ca8770c293e8154e7aec56128bbac4fdbd541d602216ebf7ca1e02b514d6e396f20683802ba3f334310a9226576926e3bb19ceee27738d13377cbafeb09d091043501702a07aa31d1f29d50ddc55adcf16ffd40578e734a4e6cb6535f26ad48e0c62ad90e79720000e87d419e92dca3e11f943655b03 e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d a6341bbd3814d11dcf583d24711aa555bb8afdac93102c309012e762f63cb8a9736a802bd48f89f3904f6fc0cba7749f +08079955d1a1f33728128c73673ec9f21a6ce138dcab5adc4dc068e6ab57314b9fbd8b013123b2fdafa9524fbdd0288777a233de8055cccfad83046ada6a19f01c47817496667bba8fc8b9456fc0e044a562d931dab1adcb66af8b66325bdf28d83ded3e2937958ccd19da540d70ef2c189f55a506c9c0d63406394c5bd3823b f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7 966c5f742b5e0fb98a2f8a39201c7abe25dc2677ae4631777b180b7bf0d60fa97df948d8ffb1bce52f17f677618ad5a3 +23900b768f6cd42b8a8df0dcbc9cb5daec8de36b9d5c619adcc1ba2b649103d5af123746cdf19c3fd0665a6fb9338156182aa06181e3c6e37ce56979612af2927440424f89cef43fc754854b8a5c43370808cf5f9929cf47712512ce2f8a2a20d2e9f568c2848b27dfbe09142843c83905ffa5da3b15501761b03dbc2c5398b6 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c a9f74d978cf686ad73499b44e153210a49b2917395db65ed239ea36f5923ee77f8a9b21be178771dbe082aea9658cf25 +1eb28c0bcdd18f73e347f957ece15b4cc83a771b0877e1feaac38e24028fb38ccea8b54ee017dc7c3d5a1327bc6f40b294aa65d7dc487f278846cd101ee84202f14b38aa2c275046aa2577f65ebaea41cd383e8def2fd0b4444dcf426fa75c4082cd7fa035cdb1e0d34a3c79d42130f5b0273eae75bc701dda3aebe7358f41b5 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18 b2cefc8d96dfd3075eee4420a460344520b881f27af15cbc8a1ec05173580213bdb9dd54c4cfd31174d32e4c1b93e220 +efab51855407438fd5c250670366bca3c026ecec4a59394f00d8a4b51746d0c4564366656d507e3e13e62fe7abeb976b8859895848dbaecf6582f1898ea06f00d4247702ed9721bd375aa83ae4c67c2eaa6e080777ea5ecf2cf787d785389560ac91cf63a52f0373c3185e18a3b8a466e21b61a239f1b77624eb1acacc76c4e1 bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a 8f087295491f1953d3cfa5fc3b31c6f055b9d6f77233670defb65131c0a427359c724a1913b23eb9d2b402d787903cc6 +31c29ca10279a417f0cc9b1382cf54dbfdfc89f2e6ef08c403c11f580cbf8674b141ed1a417563282d99a55fc616d836421cde9424815c95e7fb7668bf3f137b29937f14882d74e034b732d78d91af7721aac4950734f5fa5d4b4d35534974f8cab6d2e6dca75ddb57e99148c8a59df9fc5bcd723e546e8356f671cf2f65640a dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738 8525ce8a21f02240ebca2ef46f137834cc88112e510deba12db05ad329e18be962e879e4333a83b60ae4ee5e4abd90d9 +8db476f92e332519c1a0ece5d8deded6efbd2d8e8784eea0a6b4c3b4296c35f5f8de4317e5c1627b91fb1973fee86c06e4992aa5a20cb7475c8808ff1da354d07a488dffa7838c6ec1e3f99e3acba831f27bee8434eeda3eb36d0c6df3658883cd40068b1bed841310f6eb38d4a3d07d85848770ff7933c054cd8b34662660b1 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01 964535f372829cd99709801c9eb8851f4ed34fdb7c2dc4f8ae1fc14e3cac729cc560524921772f5c7a03220bf8f18fdc +fcb272c828fe8fd3c6f8de9410c7b6e2b36717c1b0e5e359e9109bd7fc378978aa98182a9d99961898ed88999b050d3b64d1457d7a899d6d273b9f4dde2aafa36d76329d62509043c338f265fc4c7d938459b7fa3b230a9f6cb632b61489546bb4181a5ad7f0d7369b8caced48eb374b075b2b325bc86add0f3b680cd9e80acd 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28 8d7120629e70191ba01d506e1ba47458e39432461e28da89ec4da0923e73c34222d66422d39a346578aa56400745d378 +7522492bdb916a597b8121f3e5c273b1d2800ef8c1db4f7dcbae633b60d7da5193ba53a63d7a377b351897c3b24903ae1cd1994211b259be3e6ae2cbc8970e4957fdf782c7d1bc7a91c80c8ef65468d4ef35428f26e2940ae8b0bd9b8074236bf6c00d0ebe83f9ddb2ade0f835138d39f33b59f244e0037c171f1ba7045a96f5 ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6 a4d65b7b0c83e17c26af0857e175584f154c8e1cafe7b60cfcd1c9d9d80f81fab45ca44966fbcbbfee9da700d3bff9fd +61097114ff855c3e34a62d9b853f8982d35f29cfa4a89893badbca7849e5fb437a1a38d6451bf0ca5a0d528e352b8e4b57f2ea359a7fc8841d49dd3e570f9b016f14156b0bbc4be822e260bd147ec081454969e11cb0034b7450ef4deb7ed6edb977e2f4ed60121aa095fb0ab40240dc329ecc917f5c64b4410612af065ee9dd 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc 9537a509e55b739137fb71531e6d78501722b053c047ec0c545b0f9dc36226066fc66b67f8ddb72c90dee84ca265ff80 +dd09ae6c982bb1440ca175a87766fefeacc49393ff797c446200662744f37a6e30c5d33ba70cbd8f12277fd6cc0704c17478bbab2a3047469e9618e3c340a9c8caaff5ce7c8a4d90ecae6a9b84b813419dec14460298e7521c9b7fdb7a2089328005bd51d57f92a1bcbeecd34aa40482b549e006bbf6c4ce66d34a22dda4e0e0 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b b7d6d586a6fe118c7920c81248cbda46c0bfa29c849258e3a813e0a3d2209682c54d66eb0a9ea29965516655bc112060 +37a73e2774d3b274db426c89b945696daa96035031f72cea01894b24508c7f81961ec254d36ed6a0f448e11cf7950af769dc6cd2c47e52c6caf0ea92c270974f0214b4db436c36a60fb722060a6bb544462a82e1714f5906ec32886f7d59ebf289541c3a00ec1e004892ef2b1286a0194f55d083c6ec92c64b8fd1452e1c68ba afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc a411868c8647cbaea70ecb3787aeb8040ae27c3f783fab24f18aac533e78b76c6b3344756837391f680a49bb1eba054e +9dc2046ffdc6804544db964481abe5d2d276a2a9eeec4c7ad40215b1de23561d402db69bd0f6eec2254711eea4487c64d9a6b62c3ebaf5ffa8db6e7e3a6e17154d126967a47a853a6f8339bdca9be306a13c7f992ded7619b0da59909a49b1e0930360e05b47f18628a36d69b2f87f2bfddd6a5d4a72f84dc76dbdd43f3a6a35 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c 9182520bb114d68211830a3ec664c3475b3637f885afebf1bbd30dbd7bdd5012cff2c7f0e3389fbbe5f5aa3ac1c94c99 +d9c6847fce688c5e7525a1098b545cb6c15dcd21a02761fc82fc664372a667390680135f91c01a2fa5430c634b1a6d1cd6002d8aa021e7bf5956a7901c2f81bc25d502ba5f55a55f30c0323dc68205cbefec0538e68654e7b327ac1743641896c3e740d8f66f400902b304eafaa4e0d8cffae140536f0922444cc3216a675697 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc ae455b28a03b64792b239ce240690f5b2bf20333eecf66233f98029cad7f139f53c212ae7d64e54e386cdfbc75ecf1be +69df8a01b66f04930efd2012ff2243874f256ca8758145d2a9e4ecc84d0dbdbd0dc494ae06db0ccbe819918137c90957114558580d6623efbafdd342b38dad9f08708084d32f874fba04782ce26aaab78de2102ad171f8a8f2b30b5bd3d55fdac5fa3acd6f7def7e61c2533938572b331ba6d1c02bd74bfdbf7337ade8f4a190 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4 902aea621639ec1baf3fb1f920c198e3a0b715c63e349a6b990e8c77a5a383ee9659542e0075d6662b72819c6bd8e1e3 +927524982b8d60777c1105c86fac05f634abf58c73f84fb95d81ba0b86e1e43592c4fcad2e395a40fbe7005697d86088e2fb3bb7287eb3f917d4f2dc281f5cbe65d05b4f9623bca849b10a03beca6aa2056a12ebb91cf257ac448c5e9a78f8349a6a29b17c8978bef43a443cbb8a149eb23f794844fc41693f2dbb97181444be a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916 812e20e7baf0b81f1b6adee9eb090669657be8c26bb92c375960c53a7e610aab27aba93915a3a76aafab0e2082342a52 +5f9042283561e7f19a436d01c7ef5a950a6d77ede5629cd7e43c0a5d58e8c5673c37945a453291d12938253c71dbe12c8b022ba7276eda6be034ef5ec1ec77dbd1e08f0d7b8e7725b7ec671c075e008a20f77f4ab266f97079b0aa6337df59a33b881954084057b21f294dd14bcb0869a4a6f1f597955ec7bf9d19bb3537a66a fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b 8db046d3366ecb13736603eccd66e567b4c34d30f2d9212e3aabba6a1b10d879c2059d1788e2a47f6f6c90ecd869d8cd +c2ae5573d3bf396523bfb703db8502fd0760cd1be528f6ddbfb95aad399e0b19f3bd9e0fabdb05d49e3f893dffec5b627c9c2f7ad5f32e92e4e27a38cb5c28657657377fdfa1b66cd7ac3d15c6d49df92d284db99f69744f37dc7cb4e7d52920fdb200a7942623a7057ba82e467dcccaa5da416b48510d8364446a6a5e2a5aa8 a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea b096641f5ef57a9ce020466b2649a138a435c3dfeaa866c17d0b8a1230367511500098118f48c8a8eb9bf0061783a4a2 +03c1a1cd30a039d0dcb22fee2450a7fa79495a0d0f4f43d2de4d75bce003c0334a8860f5c164dbd94888a9f751235a3e570d31070e3e1293a7be616af7176600585d36ac013600157d2569d491da4b8a3bf3630c26e0b9925412189f50b0ae6f04c86477932e2ecd8c3546106ae1ebc684cc3adb27ed665eddece886adea4ce3 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0 b61b04af214d013da05beb7de48bb3383e62f80b609f27459c7b14639fbbc6fcd4ae98503b74b003feb737d16fed4f81 +888f6d9bc7c86c0079fbfd42d8c08d6958f40f6e570fb0b1f03d2f8f8a63df4fcc87b379a222cf835820a999d34996e08961f13b86b075e7fd1c303cd3baa44de42168561589012f7e5300da4f8bdf470c07119a5d9f7ba7293568cd7c6a1b7fc1e41cda40bed7d46e5a28af67ae2aabfefe67a86a1c601e6f5ee543e09bd7b6 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294 903b830c67a83f98196943caed492678f3da58cf6a246d7337215bbc2cff9e3eb66424e9112ca9bc99c0353b5a302a38 +48453340f1317769e6ee6e103153714365731163dc18f84e9f2fa4b120f9c5a9645ee2f9b66c84c26d95912b422b009b64af96aa418b2427a4209f2e7513ba8e43ec8cf20b34e7529b22eb1199545afe9a9f7d9bcb320aec9ee0162f91c0d1dd9674c9c284f25199c5e109f6f84d7ed0d269cc6413edb81bc2c83e37d644d8b9 b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a 95374ce888c946f0d8fb0984c4f3cf3292f9d051890f2e6386513aa6da1599395a83b5d92c3b56c43ee2fbc14b056097 +4bdfd3b91d83108409ad765b256e0c9b9937ecf647f8e6f9fc807e2e72af8246178b3fe046b4ea10170450d71a4eec790ecb05f03d7077341de26c4db7eeae24d55c9a9093e837dfdb38168fe8230cb9605825a1282fecd741989bfcdb34678fe077477927f66bd26d003e5dda22043341a14dd31841ba483ad5ce2701e0f68e 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4 b6800f431f4ad667f2e63a70a467fcfa2a811a757db38ddb0166ebbda2dcfe408096c230be6147d3ea3ec47be29b3b9d +e6cdee8558bc1eacc24e82f0624ce8d02cc8d925b4dd3dec3a72f4a4e0fb76076bfa3ef2e2c33bdd7c27b322bdc09bbfee8fe46f75dbd7bbd2af09690b7137943efe21706e0a1b6d3089540fc58d85ddb55ea836616db573e36c521be008893f40a0a7c349602cc178ea43be59d31ec6449e7ff2c5379379f7d7645134df1bc3 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04 9046e30e5138ac2de76ce0554958bcf6f4547612f14c8187a62ad41f25199512b5a1d880da67bb089f482f71fd5a8315 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P224_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P224_blst new file mode 100644 index 000000000000..bd43f07df393 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P224_blst @@ -0,0 +1,60 @@ +699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615 af732793dc7a55f7d728873bb32a31e2bf01ec7b572a95101ada08043bcad549475b9dafa9fc9bbde290d61d37ad18a8 +7de42b44db0aa8bfdcdac9add227e8f0cc7ad1d94693beb5e1d325e5f3f85b3bd033fc25e9469a89733a65d1fa641f7e67d668e7c71d736233c4cba20eb83c368c506affe77946b5e2ec693798aecd7ff943cd8fab90affddf5ad5b8d1af332e6c5fe4a2df16837700b2781e08821d4fbdd8373517f5b19f9e63b89cfeeeef6f cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5 a774a6dc9c28266f014309cdd93cff5ce8c2c94598511cd271e24ea3c4761419d82949a16caf64ae99508a08d973671e +af0da3adab82784909e2b3dadcecba21eced3c60d7572023dea171044d9a10e8ba67d31b04904541b87fff32a10ccc6580869055fec6216a00320a28899859a6b61faba58a0bc10c2ba07ea16f214c3ddcc9fc5622ad1253b63fe7e95227ae3c9caa9962cffc8b1c4e8260036469d25ab0c8e3643a820b8b3a4d8d43e4b728f9 dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73 b7be2488a35727a21329df41b892451271802142d06c0b791f454134e52aef5e754e55d5edc7f84a16bc67bf00596829 +cfa56ae89727df6b7266f69d6636bf738f9e4f15f49c42a0123edac4b3743f32ea52389f919ceb90575c4184897773b2f2fc5b3fcb354880f15c93383215d3c2551fcc1b4180a1ac0f69c969bbc306acd115ce3976eff518540f43ad4076dbb5fbad9ce9b3234f1148b8f5e059192ff480fc4bcbd00d25f4d9f5ed4ba5693b6c aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e b5d6fd02217f16cfa0a008d7c3d01bbd40e749937cb35373a58b0f5b06a3851f5275fb96103bffedd350f47edaba0ac8 +c223c8009018321b987a615c3414d2bb15954933569ca989de32d6bf11107bc47a330ab6d88d9b50d106cf5777d1b736b14bc48deda1bc573a9a7dd42cd061860645306dce7a5ba8c60f135a6a21999421ce8c4670fe7287a7e9ea3aa1e0fa82721f33e6e823957fe86e2283c89ef92b13cd0333c4bb70865ae1919bf538ea34 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4 b36398542b86d224ed5a121f59d8af00bdbe822fe8fbaebbb10b1536b030c92f70262a952e787708da8fbb9f72d91fb7 +1c27273d95182c74c100d85b5c08f4b26874c2abc87f127f304aedbf52ef6540eba16dd664ae1e9e30ea1e66ff9cc9ab5a80b5bcbd19dde88a29ff10b50a6abd73388e8071306c68d0c9f6caa26b7e68de29312be959b9f4a5481f5a2ad2070a396ed3de21096541cf58c4a13308e08867565bf2df9d649357a83cdcf18d2cd9 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131 a662cc5af7ad95f88281811c7333bcbb7fff2dc50e5d697ff36dc4f13ceb65d078f075d2e02dee3b8878a4d192fa10fd +069ae374971627f6b8503f3aa63ab52bcf4f3fcae65b98cdbbf917a5b08a10dc760056714db279806a8d43485320e6fee0f1e0562e077ee270ace8d3c478d79bcdff9cf8b92fdea68421d4a276f8e62ae379387ae06b60af9eb3c40bd7a768aeffccdc8a08bc78ca2eca18061058043a0e441209c5c594842838a4d9d778a053 d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974 847a30dca347cf1ff56e749a693afd2848f0befb57b398cf818021c47734454f3e8d7157a175ba6cebdd2dcab11b78ad +d0d5ae3e33600aa21c1606caec449eee678c87cb593594be1fbb048cc7cfd076e5cc7132ebe290c4c014e7a517a0d5972759acfa1438d9d2e5d236d19ac92136f6252b7e5bea7588dcba6522b6b18128f003ecab5cb4908832fb5a375cf820f8f0e9ee870653a73dc2282f2d45622a2f0e85cba05c567baf1b9862b79a4b244e 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8 a07c3d9fa48fc5e7b0a5905036392f14fe4895e5041d5f8ffa1e9bc66c98e45766012caeecc8d81adbebaae728e227a0 +79b7375ae7a4f2e4adad8765d14c1540cd9979db38076c157c1837c760ca6febbb18fd42152335929b735e1a08041bd38d315cd4c6b7dd2729de8752f531f07fe4ddc4f1899debc0311eef0019170b58e08895b439ddf09fbf0aeb1e2fd35c2ef7ae402308c3637733802601dd218fb14c22f57870835b10818369d57d318405 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2 a31b8ba29409c7264d4bcbc64843aa3cb79520ebc764ff1761ae21742b6c1cf326783f772bb0f94b5c2acca25d381777 +8c7de96e6880d5b6efc19646b9d3d56490775cb3faab342e64db2e388c4bd9e94c4e69a63ccdb7e007a19711e69c06f106b71c983a6d97c4589045666c6ab5ea7b5b6d096ddf6fd35b819f1506a3c37ddd40929504f9f079c8d83820fc8493f97b2298aebe48fdb4ff472b29018fc2b1163a22bfbb1de413e8645e871291a9f6 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7 a6512474946557cd884667287f72a4d52717cca32a04b915444f770f1467f8408ec7012050095c6e6cb435da9a1e5e33 +c89766374c5a5ccef5823e7a9b54af835ac56afbbb517bd77bfecf3fea876bd0cc9ea486e3d685cfe3fb05f25d9c67992cd7863c80a55c7a263249eb3996c4698ad7381131bf3700b7b24d7ca281a100cf2b750e7f0f933e662a08d9f9e47d779fb03754bd20931262ff381a2fe7d1dc94f4a0520de73fa72020494d3133ecf7 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b b0a712af9d6261c1c71eb99d6e78e089530eeac929ed48c60c15582a5b54259433aa1a561e3df7a6b4e30545ebd68d4c +30f0e3b502eec5646929d48fd46aa73991d82079c7bd50a38b38ec0bd84167c8cf5ba39bec26999e70208af9b445046cd9d20c82b7629ca1e51bdd00daddbc35f9eb036a15ac57898642d9db09479a38cc80a2e41e380c8a766b2d623de2de798e1eabc02234b89b85d60154460c3bf12764f3fbf17fcccc82df516a2fbe4ecf c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6 871956c090a6c1a2ab1c36ac41f02ad9d3e3149f4ae406d1772e6647bbfd437f315e2a3719f2bf46849781722948ea19 +6bbb4bf987c8e5069e47c1a541b48b8a3e6d14bfd9ac6dfaa7503b64ab5e1a55f63e91cf5c3e703ac27ad88756dd7fb2d73b909fc15302d0592b974d47e72e60ed339a40b34d39a49b69ea4a5d26ce86f3ca00a70f1cd416a6a5722e8f39d1f0e966981803d6f46dac34e4c7640204cd0d9f1e53fc3acf30096cd00fa80b3ae9 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc b00fdc22dffe5ea0bf7dfce592c505002aa7138c984e06d61a5d888ae064206aefe12eb41238d84e3e756e381c389c0e +05b8f8e56214d4217323f2066f974f638f0b83689fc4ed1201848230efdc1fbca8f70359cecc921050141d3b02c2f17aa306fc2ce5fc06e7d0f4be162fcd985a0b687b4ba09b681cb52ffe890bf5bb4a104cb2e770c04df433013605eb8c72a09902f4246d6c22b8c191ef1b0bece10d5ce2744fc7345307dd1b41b6eff0ca89 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3 b9b178caa37302f0c7c1ebf43bf68fb11bd706d30b8f6ea472e82669f2ce030dbb73f56a54ca9035e243dd329a15a5e7 +e5c979f0832242b143077bce6ef146a53bb4c53abfc033473c59f3c4095a68b7a504b609f2ab163b5f88f374f0f3bff8762278b1f1c37323b9ed448e3de33e6443796a9ecaa466aa75175375418186c352018a57ce874e44ae72401d5c0f401b5a51804724c10653fded9066e8994d36a137fdeb9364601daeef09fd174dde4a 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912 a6c0bd3ecd74ce19757f459ba1c1c7390ae8f51587cb27562e06abb6c1d6e5205a46be2144c1bb58d93bee95fa3b637d +2b49de971bb0f705a3fb5914eb7638d72884a6c3550667dbfdf301adf26bde02f387fd426a31be6c9ff8bfe8690c8113c88576427f1466508458349fc86036afcfb66448b947707e791e71f558b2bf4e7e7507773aaf4e9af51eda95cbce0a0f752b216f8a54a045d47801ff410ee411a1b66a516f278327df2462fb5619470e 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa 8f16d9a8ab89fcc783c1fea5ee835b042a125203e5e25062bf9b2381a496ff4fe5a06a58cf2b0097b069f46b748948d5 +1fa7201d96ad4d190415f2656d1387fa886afc38e5cd18b8c60da367acf32c627d2c9ea19ef3f030e559fc2a21695cdbb65ddf6ba36a70af0d3fa292a32de31da6acc6108ab2be8bd37843338f0c37c2d62648d3d49013edeb9e179dadf78bf885f95e712fcdfcc8a172e47c09ab159f3a00ed7b930f628c3c48257e92fc7407 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972 a893b35e54fac2a9523dd8117045026610654abc0b88fe2990318beb6c23a34db146f4f85694576d520fef880b40e450 +74715fe10748a5b98b138f390f7ca9629c584c5d6ad268fc455c8de2e800b73fa1ea9aaee85de58baa2ce9ce68d822fc31842c6b153baef3a12bf6b4541f74af65430ae931a64c8b4950ad1c76b31aea8c229b3623390e233c112586aa5907bbe419841f54f0a7d6d19c003b91dc84bbb59b14ec477a1e9d194c137e21c75bbb f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170 a957451ffc556983632011387f222020243c26b1d2cddf696f5888d15a04c915d171c651a3731d427cfd2c8854ed457e +d10131982dd1a1d839aba383cd72855bf41061c0cb04dfa1acad3181f240341d744ca6002b52f25fb3c63f16d050c4a4ef2c0ebf5f16ce987558f4b9d4a5ad3c6b81b617de00e04ba32282d8bf223bfedbb325b741dfdc8f56fa85c65d42f05f6a1330d8cc6664ad32050dd7b9e3993f4d6c91e5e12cbd9e82196e009ad22560 c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85 a31e73567364e2e108b3fb6b6c26d1d1df4fd5e5d139cabd499a5bcb8de78618a80a0927a0c73547dbc82634aac87fff +ef9dbd90ded96ad627a0a987ab90537a3e7acc1fdfa991088e9d999fd726e3ce1e1bd89a7df08d8c2bf51085254c89dc67bc21e8a1a93f33a38c18c0ce3880e958ac3e3dbe8aec49f981821c4ac6812dd29fab3a9ebe7fbd799fb50f12021b48d1d9abca8842547b3b99befa612cc8b4ca5f9412e0352e72ab1344a0ac2913db 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6 96882e2d0d6f8c585acc7ce50b1bc5c863d52001dc0eb8c90fb0bc6909915adb88a6570a6e007ec9ec7dd386dd212143 +4cc91f744ac858d3577e48813219aa3538dd813b186b42d1e6218376f07cc1cc448ddd6b37240e98bf953f49cf54d65c12878b33c0bf6eb1c60254f0b6fa974f847e53abc56773eef6f29885dfc619e6a48fc15a667ca94001a0c945b6357a53221b0f4b266181456b0d2d25e90708777f1a6f85971c00140c631c1991e0fd06 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39 938cdd6d64a400ba023de2e012188b982279870c39f0701884c42e2267a6f5071a62d306edd5958d4f555ada2330f84b +58f43cc1924de4bc5867664adbc9d26b4f096a43aca47c27c52851b006dc2a658919ef9ce5b5ac48372703be15ac51631c2bd84b88f479f113b0569a9a09e230ec1e8e573474c6075284d3e57d973829af35325d9e7dab4a5f9b065155bbcaff3642a82ef4c9b9e127d3575c050721653da3b087d3fa394192897a5519527d19 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6 b32a87b2a1f6c1808276889b70ba20a4ab1db8ddfb7743519f9eb9230fc1bbf217d15fcb5bacb63e5790157c127cbbe0 +113a2806b052fde683ee09453098e402204155afb3776fd1cad3a9103421d327eab8f9ec0dd050ffcc83f93b34ea707705fabeccfe43ab1a71c95298fd3ec769d99ead1066950eee677d225816e0faad19cf69e1b35d16771689e2092cafe16d7c0dd7b0db73fffb8d0f3eaed83004dd21e753530ec939c89ba25578fa5f785b 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b 805d3a0b1e3e57876241a2da2c477678f25e427b922913b896397d2c26b0f288e8788d5a78f9007d49c3ad6e9dc055cc +64cbfc8f2e2149a31b3e8a80c4a552f6c62aaeb7990b6e0ee55500a9d17be04213406578caf315951086dff5c2af3b5ce17d425d185101ef26f86396ba3a129a4f3f8e2dd595f59efb6c0f5c2dcc394569d7268695e9ac7daa84203f1f1895f1f9e4b514a5c9cd23baa63454710144fe735ad9b8f42d8c43267aa434a26d7e5f 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b 8b148cb6f3c2656908c17d2ae53aed6e42516b5fd8496035d0f39a362a94cebe4f3d3cc67512050548709f6f70096f4f +a10a11c8e30fff118d371daf824f16c08200b83ea059436466a4611ccac93b2dea2de8c1006f946196aef7fe9b0c251a391b0340f21797798278b412ff2b53842eec6450728e2bca062f8337a2c204b9ea04ff660cd4d4db559f2f11c4d8ef199021339fcc82396f7a93926cf5f247e37d8067fe50692de54f102bd5ab51925c 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8 b7e71b2e52825f983d3c6aee3fa3a83bfe5101073c10741debcd405e57038e6ea2e8fcbb8995346b7776b2fa0a15a227 +b3f720bf566ffa369259f4361959ae0641d2755ec264a4c4349981df2b02563275b2b9adb5aee47f7a456760a971991ffed6b17809bb9694138d1677fa916123795239353158fc6b22d10f20d26f5d2dcd8c56c44373eea5b93067dba2d7c5318dac2e9e8714873cb1b37f58c011fd14fa1e535554efe05f468bfc8e11cd8b99 e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784 93ca3f585151f26b9a75e3aa3dc2c2c31b0d255407c978eed6c42390de0fd143fbef024f49cca7b7c634e689f0602ed1 +0a398a46df7ccc48d1e7833f8bbc67100f1ef77a62dc78bbc115b2a662f9591fbaaa91ad3d788e2fdd1b3164e45293d4f5686c151296901768028ac80ded4bf89c647ad35f0c7c4cb318c0c757c1d83c44d850e5fd4677281b3f13b1ee54de79c8c042813f9d3312dcc6111a68299cb7e829557d7f3d96e702f65aefc6499415 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c b2010fa94a15974b61a62b243bc4bfb60efc96c87c0220b1b5b8a36fb4345a80b6bfc9548489992ca77576ecd5929dc8 +8c33616821a6038b448d8918668977fcf1ef5aa0cf7c341837b39bbcc9bca875a3757f4b392630e9995b9bbe4eb66978b877586adaa02f99d2344dae082a7603351d8ffcfca081ab403cd0acb90d078dd1d0789c2eb3185c62bff2d9f04cd38e509e3b83c12ed0a5c6808fc42f7ba5b06acdc496c8ad9be648ee6a4505f8560f 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583 94672602e46bd90e1425a58e6f49eec7fb4030e67fe73a00556fb1a57edad30d20410582af39b5e3fe1c87677e79407f +94d56535fd4edfe67a0daa6579f9d53bf6b7b8830ae2aeb62892ff59f18756ddf2811b449c7d20d65d54f8507de4e7c50eaa084830637812aa4b250a4d61ab67845be36e4a41cdc0a70f8d6e3a63d4514f0dc197e6486015046a316153d5f3a3a4a0ae1ed7ea5fa55e12e73d333333685c02e0eb636234ea7e6d4b76b4b76b5a 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2 876dad1ada45c829bd02e44193f236e8ec0ea0b3fc638166f09a567a570571ed0806a2804a954963b3d3d8f6fb4a4311 +5d8ebdf9eb28b47bdafaa36bf0b66a9eaf99b6c83959da4f2b1151b4f4ecd28fb115a64c0cb9491093a7e9b9c53ec423e4c72e7765bb9c818da0e8c428667e44474a71db4867130c77c40bfd8544b2d7b9d6464d2b8e6a48482153256a32437c3a747231f51134dd14c703407e31146a6fcde23bededcf16950486e90ca69ac0 f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc 8dfe4cf7243db0e0cb1b74264b0b43c0a4ddbf520e07a774732dc4988393abe3fc3c5b6e52958b48fddeccbf5bf44826 +25e4416695f77551fdce276355528ccf1ddc2483821c5d22d751d50111ca2fadc6593b52c74f4b5957494f1df25b0b2f86950d0d19229ec6506fee8581d2dd09d48418b146ff16bd84a17ca0dc83b1888eb407376da6c8a88fa1e60b8c2a2471dfde4b3996ef673d5bde3d70c434dc9f2488e9de16ae657d29e5e59ec922a1ec 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd 883b102bf43199c6344aae82c19dabb0568ca9000bec3ecc2f8fd5cc0d0bd9cf6f5028b6168bba3864ce0bba0eeda56e +9164d633a553deccf3cbd2effccf1387fa3177cd28c95d94a7d1a3e159c5e5c027758cc26493301b2f4d141d8d07a5fe5fead987ce5f30abeafcb48c302afc6c2309f0e93d9b6818cbb6972d222cb7b01302dfe202ae83b89f53150ae4a0e2b8fc0fd1091f19b4ab2e6ab213ab322d04f2c5f57113bfad3c5675227237abf773 e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3 80ef5daffa60f949886ef24c506eb35483693a356bdf64a30a1d700222d83b83c1d56c0bffd099ca1822a7823fec040c +019df05929321ecea7ee1de4f412aba1c8d3c24437db04b194a68a0a59dd871be10bd3a4be6edf551350ea49fc7155a4d887e1221486291abe77a30633a4c4f7868fe2df24311cba0c73804883954460e122387ed414111ff96ff1aebac8b6a6491d8a0d16e48a63bf3d027c0f68ee4a4b234d73b412196706af8ea022b4dcef b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17 a0156bafec6bff847f4603aff465992279e8068601e578fc7566ad8148c98fee732bbdacc2899e3ab13fd9e51ab33ba5 +5d09d2b1d3fa6e12c10d8b26dc9aabc8dc02bd06e63ff33f8bb91ede4b8694592a69e4ed4cdf6820069e2b9c7803658949e877ffe23bf90bcf5ce1409c06c71d86885a94048b05ac0ec9db193e489a5a2bfa367caf6aa8ecdb032be366174343f6875d2fe1785e8d77334f5f469cec64998e08d3303e5c9a1923b34fdc105d65 efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085 a7e747720f0c7301283125437b01c6c1204d1cbfd806b19dda862b3fcffd6f794efe5b32edae2404906fa2ec4dd23001 +50f6dfc81c6cf189e0a310f992907fe93356cee9dea9a41c7671a8daf3f4cfe0c459ce6122c1e731dbf7593419d7114cb73b46956158a982c5d52c72f43f0f822046093c69aeff1f7e4cd8af00ba655c5baa2e7b6a400b4be1f6fd51b3e4cfb35a69c80a28c5cafb771b6c2e52e0aeef0e3fd045e8d40745f3f8b74fd969f816 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd 8db868f2902c562e2a337573432f7bac5a20502c67e4a3bc18dc56f41f1b27d1df52a0d9b97630a3e9882411f727cff4 +e90129ac6672c85bb7b6b18e9dc199c96c81fd65034b53c77818364d512366fb9cd1bc7c82404c451e561fc1ed916c0948f6ac561b33a1ccca093f07684b8c2bafa9e966377bd208556018a5bafb9edcecf70498c7140fe9c8cf3ad8b8c3b0aa489df797944465047465415bb0e24333235fcdd59a98829a3941eaaf62033e82 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d b4718530a8cad64ca4a1db045268e4508175a7590dd6480be355dcbfaa8724b7c8a96eea19e36702a627c3d370a5a5de +3c9a483c9bee33b601549c592a82e95b4319b1e74b777877f0971bcb4273716b268e8f99f876e42f942f4cf08284896bbc1ffbf094ac0956c3cedfc3580cffa8c74fc6db29a371f2da2d05edb9185ece741fe0d3fabfe9d5b4d373755ebed13dc6840cfa3283b9ea46ec8b95c434f253ae86998182e9cc0e95ee64f323fc74b0 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0 8abe31d914a0795f8637942cd676114b1b7a0de0b6e66eb22c6aa5239ee3f649d5836ba4b330f488014e5fe6f6e8bdab +bfc073fdda63c5fccaa0ca8770c293e8154e7aec56128bbac4fdbd541d602216ebf7ca1e02b514d6e396f20683802ba3f334310a9226576926e3bb19ceee27738d13377cbafeb09d091043501702a07aa31d1f29d50ddc55adcf16ffd40578e734a4e6cb6535f26ad48e0c62ad90e79720000e87d419e92dca3e11f943655b03 e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d a6341bbd3814d11dcf583d24711aa555bb8afdac93102c309012e762f63cb8a9736a802bd48f89f3904f6fc0cba7749f +08079955d1a1f33728128c73673ec9f21a6ce138dcab5adc4dc068e6ab57314b9fbd8b013123b2fdafa9524fbdd0288777a233de8055cccfad83046ada6a19f01c47817496667bba8fc8b9456fc0e044a562d931dab1adcb66af8b66325bdf28d83ded3e2937958ccd19da540d70ef2c189f55a506c9c0d63406394c5bd3823b f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7 966c5f742b5e0fb98a2f8a39201c7abe25dc2677ae4631777b180b7bf0d60fa97df948d8ffb1bce52f17f677618ad5a3 +23900b768f6cd42b8a8df0dcbc9cb5daec8de36b9d5c619adcc1ba2b649103d5af123746cdf19c3fd0665a6fb9338156182aa06181e3c6e37ce56979612af2927440424f89cef43fc754854b8a5c43370808cf5f9929cf47712512ce2f8a2a20d2e9f568c2848b27dfbe09142843c83905ffa5da3b15501761b03dbc2c5398b6 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c a9f74d978cf686ad73499b44e153210a49b2917395db65ed239ea36f5923ee77f8a9b21be178771dbe082aea9658cf25 +1eb28c0bcdd18f73e347f957ece15b4cc83a771b0877e1feaac38e24028fb38ccea8b54ee017dc7c3d5a1327bc6f40b294aa65d7dc487f278846cd101ee84202f14b38aa2c275046aa2577f65ebaea41cd383e8def2fd0b4444dcf426fa75c4082cd7fa035cdb1e0d34a3c79d42130f5b0273eae75bc701dda3aebe7358f41b5 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18 b2cefc8d96dfd3075eee4420a460344520b881f27af15cbc8a1ec05173580213bdb9dd54c4cfd31174d32e4c1b93e220 +efab51855407438fd5c250670366bca3c026ecec4a59394f00d8a4b51746d0c4564366656d507e3e13e62fe7abeb976b8859895848dbaecf6582f1898ea06f00d4247702ed9721bd375aa83ae4c67c2eaa6e080777ea5ecf2cf787d785389560ac91cf63a52f0373c3185e18a3b8a466e21b61a239f1b77624eb1acacc76c4e1 bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a 8f087295491f1953d3cfa5fc3b31c6f055b9d6f77233670defb65131c0a427359c724a1913b23eb9d2b402d787903cc6 +31c29ca10279a417f0cc9b1382cf54dbfdfc89f2e6ef08c403c11f580cbf8674b141ed1a417563282d99a55fc616d836421cde9424815c95e7fb7668bf3f137b29937f14882d74e034b732d78d91af7721aac4950734f5fa5d4b4d35534974f8cab6d2e6dca75ddb57e99148c8a59df9fc5bcd723e546e8356f671cf2f65640a dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738 8525ce8a21f02240ebca2ef46f137834cc88112e510deba12db05ad329e18be962e879e4333a83b60ae4ee5e4abd90d9 +8db476f92e332519c1a0ece5d8deded6efbd2d8e8784eea0a6b4c3b4296c35f5f8de4317e5c1627b91fb1973fee86c06e4992aa5a20cb7475c8808ff1da354d07a488dffa7838c6ec1e3f99e3acba831f27bee8434eeda3eb36d0c6df3658883cd40068b1bed841310f6eb38d4a3d07d85848770ff7933c054cd8b34662660b1 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01 964535f372829cd99709801c9eb8851f4ed34fdb7c2dc4f8ae1fc14e3cac729cc560524921772f5c7a03220bf8f18fdc +fcb272c828fe8fd3c6f8de9410c7b6e2b36717c1b0e5e359e9109bd7fc378978aa98182a9d99961898ed88999b050d3b64d1457d7a899d6d273b9f4dde2aafa36d76329d62509043c338f265fc4c7d938459b7fa3b230a9f6cb632b61489546bb4181a5ad7f0d7369b8caced48eb374b075b2b325bc86add0f3b680cd9e80acd 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28 8d7120629e70191ba01d506e1ba47458e39432461e28da89ec4da0923e73c34222d66422d39a346578aa56400745d378 +7522492bdb916a597b8121f3e5c273b1d2800ef8c1db4f7dcbae633b60d7da5193ba53a63d7a377b351897c3b24903ae1cd1994211b259be3e6ae2cbc8970e4957fdf782c7d1bc7a91c80c8ef65468d4ef35428f26e2940ae8b0bd9b8074236bf6c00d0ebe83f9ddb2ade0f835138d39f33b59f244e0037c171f1ba7045a96f5 ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6 a4d65b7b0c83e17c26af0857e175584f154c8e1cafe7b60cfcd1c9d9d80f81fab45ca44966fbcbbfee9da700d3bff9fd +61097114ff855c3e34a62d9b853f8982d35f29cfa4a89893badbca7849e5fb437a1a38d6451bf0ca5a0d528e352b8e4b57f2ea359a7fc8841d49dd3e570f9b016f14156b0bbc4be822e260bd147ec081454969e11cb0034b7450ef4deb7ed6edb977e2f4ed60121aa095fb0ab40240dc329ecc917f5c64b4410612af065ee9dd 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc 9537a509e55b739137fb71531e6d78501722b053c047ec0c545b0f9dc36226066fc66b67f8ddb72c90dee84ca265ff80 +dd09ae6c982bb1440ca175a87766fefeacc49393ff797c446200662744f37a6e30c5d33ba70cbd8f12277fd6cc0704c17478bbab2a3047469e9618e3c340a9c8caaff5ce7c8a4d90ecae6a9b84b813419dec14460298e7521c9b7fdb7a2089328005bd51d57f92a1bcbeecd34aa40482b549e006bbf6c4ce66d34a22dda4e0e0 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b b7d6d586a6fe118c7920c81248cbda46c0bfa29c849258e3a813e0a3d2209682c54d66eb0a9ea29965516655bc112060 +37a73e2774d3b274db426c89b945696daa96035031f72cea01894b24508c7f81961ec254d36ed6a0f448e11cf7950af769dc6cd2c47e52c6caf0ea92c270974f0214b4db436c36a60fb722060a6bb544462a82e1714f5906ec32886f7d59ebf289541c3a00ec1e004892ef2b1286a0194f55d083c6ec92c64b8fd1452e1c68ba afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc a411868c8647cbaea70ecb3787aeb8040ae27c3f783fab24f18aac533e78b76c6b3344756837391f680a49bb1eba054e +9dc2046ffdc6804544db964481abe5d2d276a2a9eeec4c7ad40215b1de23561d402db69bd0f6eec2254711eea4487c64d9a6b62c3ebaf5ffa8db6e7e3a6e17154d126967a47a853a6f8339bdca9be306a13c7f992ded7619b0da59909a49b1e0930360e05b47f18628a36d69b2f87f2bfddd6a5d4a72f84dc76dbdd43f3a6a35 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c 9182520bb114d68211830a3ec664c3475b3637f885afebf1bbd30dbd7bdd5012cff2c7f0e3389fbbe5f5aa3ac1c94c99 +d9c6847fce688c5e7525a1098b545cb6c15dcd21a02761fc82fc664372a667390680135f91c01a2fa5430c634b1a6d1cd6002d8aa021e7bf5956a7901c2f81bc25d502ba5f55a55f30c0323dc68205cbefec0538e68654e7b327ac1743641896c3e740d8f66f400902b304eafaa4e0d8cffae140536f0922444cc3216a675697 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc ae455b28a03b64792b239ce240690f5b2bf20333eecf66233f98029cad7f139f53c212ae7d64e54e386cdfbc75ecf1be +69df8a01b66f04930efd2012ff2243874f256ca8758145d2a9e4ecc84d0dbdbd0dc494ae06db0ccbe819918137c90957114558580d6623efbafdd342b38dad9f08708084d32f874fba04782ce26aaab78de2102ad171f8a8f2b30b5bd3d55fdac5fa3acd6f7def7e61c2533938572b331ba6d1c02bd74bfdbf7337ade8f4a190 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4 902aea621639ec1baf3fb1f920c198e3a0b715c63e349a6b990e8c77a5a383ee9659542e0075d6662b72819c6bd8e1e3 +927524982b8d60777c1105c86fac05f634abf58c73f84fb95d81ba0b86e1e43592c4fcad2e395a40fbe7005697d86088e2fb3bb7287eb3f917d4f2dc281f5cbe65d05b4f9623bca849b10a03beca6aa2056a12ebb91cf257ac448c5e9a78f8349a6a29b17c8978bef43a443cbb8a149eb23f794844fc41693f2dbb97181444be a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916 812e20e7baf0b81f1b6adee9eb090669657be8c26bb92c375960c53a7e610aab27aba93915a3a76aafab0e2082342a52 +5f9042283561e7f19a436d01c7ef5a950a6d77ede5629cd7e43c0a5d58e8c5673c37945a453291d12938253c71dbe12c8b022ba7276eda6be034ef5ec1ec77dbd1e08f0d7b8e7725b7ec671c075e008a20f77f4ab266f97079b0aa6337df59a33b881954084057b21f294dd14bcb0869a4a6f1f597955ec7bf9d19bb3537a66a fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b 8db046d3366ecb13736603eccd66e567b4c34d30f2d9212e3aabba6a1b10d879c2059d1788e2a47f6f6c90ecd869d8cd +c2ae5573d3bf396523bfb703db8502fd0760cd1be528f6ddbfb95aad399e0b19f3bd9e0fabdb05d49e3f893dffec5b627c9c2f7ad5f32e92e4e27a38cb5c28657657377fdfa1b66cd7ac3d15c6d49df92d284db99f69744f37dc7cb4e7d52920fdb200a7942623a7057ba82e467dcccaa5da416b48510d8364446a6a5e2a5aa8 a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea b096641f5ef57a9ce020466b2649a138a435c3dfeaa866c17d0b8a1230367511500098118f48c8a8eb9bf0061783a4a2 +03c1a1cd30a039d0dcb22fee2450a7fa79495a0d0f4f43d2de4d75bce003c0334a8860f5c164dbd94888a9f751235a3e570d31070e3e1293a7be616af7176600585d36ac013600157d2569d491da4b8a3bf3630c26e0b9925412189f50b0ae6f04c86477932e2ecd8c3546106ae1ebc684cc3adb27ed665eddece886adea4ce3 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0 b61b04af214d013da05beb7de48bb3383e62f80b609f27459c7b14639fbbc6fcd4ae98503b74b003feb737d16fed4f81 +888f6d9bc7c86c0079fbfd42d8c08d6958f40f6e570fb0b1f03d2f8f8a63df4fcc87b379a222cf835820a999d34996e08961f13b86b075e7fd1c303cd3baa44de42168561589012f7e5300da4f8bdf470c07119a5d9f7ba7293568cd7c6a1b7fc1e41cda40bed7d46e5a28af67ae2aabfefe67a86a1c601e6f5ee543e09bd7b6 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294 903b830c67a83f98196943caed492678f3da58cf6a246d7337215bbc2cff9e3eb66424e9112ca9bc99c0353b5a302a38 +48453340f1317769e6ee6e103153714365731163dc18f84e9f2fa4b120f9c5a9645ee2f9b66c84c26d95912b422b009b64af96aa418b2427a4209f2e7513ba8e43ec8cf20b34e7529b22eb1199545afe9a9f7d9bcb320aec9ee0162f91c0d1dd9674c9c284f25199c5e109f6f84d7ed0d269cc6413edb81bc2c83e37d644d8b9 b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a 95374ce888c946f0d8fb0984c4f3cf3292f9d051890f2e6386513aa6da1599395a83b5d92c3b56c43ee2fbc14b056097 +4bdfd3b91d83108409ad765b256e0c9b9937ecf647f8e6f9fc807e2e72af8246178b3fe046b4ea10170450d71a4eec790ecb05f03d7077341de26c4db7eeae24d55c9a9093e837dfdb38168fe8230cb9605825a1282fecd741989bfcdb34678fe077477927f66bd26d003e5dda22043341a14dd31841ba483ad5ce2701e0f68e 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4 b6800f431f4ad667f2e63a70a467fcfa2a811a757db38ddb0166ebbda2dcfe408096c230be6147d3ea3ec47be29b3b9d +e6cdee8558bc1eacc24e82f0624ce8d02cc8d925b4dd3dec3a72f4a4e0fb76076bfa3ef2e2c33bdd7c27b322bdc09bbfee8fe46f75dbd7bbd2af09690b7137943efe21706e0a1b6d3089540fc58d85ddb55ea836616db573e36c521be008893f40a0a7c349602cc178ea43be59d31ec6449e7ff2c5379379f7d7645134df1bc3 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04 9046e30e5138ac2de76ce0554958bcf6f4547612f14c8187a62ad41f25199512b5a1d880da67bb089f482f71fd5a8315 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P256 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P256 new file mode 100644 index 000000000000..244807cf5397 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P256 @@ -0,0 +1,60 @@ +ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590 8376eaaae4275ee59263ba2a94c3e664c031bc3177eea3333ba893ab33c8df3f2e8825be3ada8ed6184b2e38367113ab +9155e91fd9155eeed15afd83487ea1a3af04c5998b77c0fe8c43dcc479440a8a9a89efe883d9385cb9edfde10b43bce61fb63669935ad39419cf29ef3a936931733bfc2378e253e73b7ae9a3ec7a6a7932ab10f1e5b94d05160c053988f3bdc9167155d069337d42c9a7056619efc031fa5ec7310d29bd28980b1e3559757578 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98 8eefa481501d1c42c67c7525396a7e7c9a83e251bb2e237b6e4cc619b62fcb5d8124fcb3b78313049a616eb4e51f391e +b242a7586a1383368a33c88264889adfa3be45422fbef4a2df4e3c5325a9c7757017e0d5cf4bbf4de7f99d189f81f1fd2f0dd645574d1eb0d547eead9375677819297c1abe62526ae29fc54cdd11bfe17714f2fbd2d0d0e8d297ff98535980482dd5c1ebdc5a7274aabf1382c9f2315ca61391e3943856e4c5e616c2f1f7be0d a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870 b750fa828946686f9a75a87ffa32f1403b4de366de7be92e02c197b4e101e4a57523e4d0b0731e9a6c9fbb496ebe8339 +b64005da76b24715880af94dba379acc25a047b06066c9bedc8f17b8c74e74f4fc720d9f4ef0e2a659e0756931c080587ebdcd0f85e819aea6dacb327a9d96496da53ea21aef3b2e793a9c0def5196acec99891f46ead78a85bc7ab644765781d3543da9fbf9fec916dca975ef3b4271e50ecc68bf79b2d8935e2b25fc063358 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f 899477dc374317d06ae2cf1707eea42637649762398904d3d3dc9a1d49eadeb9b043c61ae5369ed5facc928260a7b6e1 +fe6e1ea477640655eaa1f6e3352d4bce53eb3d95424df7f238e93d8531da8f36bc35fa6be4bf5a6a382e06e855139eb617a9cc9376b4dafacbd80876343b12628619d7cbe1bff6757e3706111ed53898c0219823adbc044eaf8c6ad449df8f6aab9d444dadb5c3380eec0d91694df5fc4b30280d4b87d27e67ae58a1df828963 daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d 907864efe95138a139e1150587bf01f9caf8685b8ffb680540708aa68465111feac9c72d85ea04472f1522480a78b21a +907c0c00dc080a688548957b5b8b1f33ba378de1368023dcad43242411f554eb7d392d3e5c1668fad3944ff9634105343d83b8c85d2a988da5f5dc60ee0518327caed6dd5cf4e9bc6222deb46d00abde745f9b71d6e7aee6c7fdfc9ed053f2c0b611d4c6863088bd012ea9810ee94f8e58905970ebd07353f1f409a371ed03e3 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5 846914ee8c12ef7d5b6e929d0ef6660bd20415fe291dc3dcbd2279e3ccbd7ac8ffde0109484179f43a2b5d6f3571f6a3 +771c4d7bce05610a3e71b272096b57f0d1efcce33a1cb4f714d6ebc0865b2773ec5eedc25fae81dee1d256474dbd9676623614c150916e6ed92ce4430b26037d28fa5252ef6b10c09dc2f7ee5a36a1ea7897b69f389d9f5075e271d92f4eb97b148f3abcb1e5be0b4feb8278613d18abf6da60bfe448238aa04d7f11b71f44c5 f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96 8b1f9376ceac50380d67715c92dd63b385f3aa3bd5f3e678c4b96d82557c211e9144db5adf49d71790586b7a68b7660e +a3b2825235718fc679b942e8ac38fb4f54415a213c65875b5453d18ca012320ddfbbc58b991eaebadfc2d1a28d4f0cd82652b12e4d5bfda89eda3be12ac52188e38e8cce32a264a300c0e463631f525ae501348594f980392c76b4a12ddc88e5ca086cb8685d03895919a8627725a3e00c4728e2b7c6f6a14fc342b2937fc3dd 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d 81400329d96bf981a68fc80583c9af0fdf09ee8bd833d178fa8ae333bbda2455ce3e55702392fecbb6af2e933a289ce8 +3e6e2a9bffd729ee5d4807849cd4250021d8184cda723df6ab0e5c939d39237c8e58af9d869fe62d3c97b3298a99e891e5e11aa68b11a087573a40a3e83c7965e7910d72f81cad0f42accc5c25a4fd3cdd8cee63757bbbfbdae98be2bc867d3bcb1333c4632cb0a55dffeb77d8b119c466cd889ec468454fabe6fbee7102deaf 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9 b46bc20986f1c8c8f3481b172d0d01ce77c540d6c05eb72aefb71c79367986855df64c003821a481a4e76c6651ff23b2 +52e5c308e70329a17c71eaedb66bbee303c8ec48a6f1a2efb235d308563cd58553d434e12f353227a9ea28608ec9c820ed83c95124e7a886f7e832a2de1032e78dc059208f9ec354170b2b1cab992b52ac01e6c0e4e1b0112686962edc53ab226dafcc9fc7baed2cd9307160e8572edb125935db49289b178f35a8ad23f4f801 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634 a06e48322d035c9fe116bbae489b17e57e567edd390308b7ba58e048e51b42c8fdff0c0302155022944db425e577b94b +d3e9e82051d4c84d699453c9ff44c7c09f6523bb92232bcf30bf3c380224249de2964e871d56a364d6955c81ef91d06482a6c7c61bc70f66ef22fad128d15416e7174312619134f968f1009f92cbf99248932efb533ff113fb6d949e21d6b80dfbbe69010c8d1ccb0f3808ea309bb0bac1a222168c95b088847e613749b19d04 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27 94fcf38b6ae6279c91d35a658e11eec9aed20525dd2c41b5447c43441f504a9cb384ea3a09338541632603509f8e8a01 +968951c2c1918436fe19fa2fe2152656a08f9a6b8aa6201920f1b424da98cee71928897ff087620cc5c551320b1e75a1e98d7d98a5bd5361c9393759614a6087cc0f7fb01fcb173783eb4c4c23961a8231ac4a07d72e683b0c1bd4c51ef1b031df875e7b8d5a6e0628949f5b8f157f43dccaea3b2a4fc11181e6b451e06ceb37 cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d 840d42672e839f707c24a1e3c2c5e2f7953fe24c909ef268ad90fcad1a49806d1dc055775f693d62f3a770157ddcee35 +78048628932e1c1cdd1e70932bd7b76f704ba08d7e7d825d3de763bf1a062315f4af16eccefe0b6ebadccaf403d013f50833ce2c54e24eea8345e25f93b69bb048988d102240225ceacf5003e2abdcc90299f4bf2c101585d36ecdd7a155953c674789d070480d1ef47cc7858e97a6d87c41c6922a00ea12539f251826e141b4 b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c 85370f933d3e314eaf009fd93fd216af2e5738cfab0a029138c4c9fba234457d27c4305750d5d715a9233c8f9308a786 +9b0800c443e693067591737fdbcf0966fdfa50872d41d0c189d87cbc34c2771ee5e1255fd604f09fcf167fda16437c245d299147299c69046895d22482db29aba37ff57f756716cd3d6223077f747c4caffbecc0a7c9dfaaafd9a9817470ded8777e6355838ac54d11b2f0fc3f43668ff949cc31de0c2d15af5ef17884e4d66a 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48 8a15c668a24ca27697660374ce2ebe7521450ec2f8d74c0a50f512e7c9c564c7c56afc233c8637403ceacedbfd3abcf2 +fc3b8291c172dae635a6859f525beaf01cf683765d7c86f1a4d768df7cae055f639eccc08d7a0272394d949f82d5e12d69c08e2483e11a1d28a4c61f18193106e12e5de4a9d0b4bf341e2acd6b715dc83ae5ff63328f8346f35521ca378b311299947f63ec593a5e32e6bd11ec4edb0e75302a9f54d21226d23314729e061016 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f b16cc14540931625fb32ea72b07db3389876154bbfc11d84435cf889dce3cd306a01a90f9ee3e92c82d38debc4bb669e +5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 ac20c9788fc2c3279ed29be54397c008a1b18777f331c66edf904827e4714f16fd025cdd6dbbe650aa3d11a97b313a45 +c35e2f092553c55772926bdbe87c9796827d17024dbb9233a545366e2e5987dd344deb72df987144b8c6c43bc41b654b94cc856e16b96d7a821c8ec039b503e3d86728c494a967d83011a0e090b5d54cd47f4e366c0912bc808fbb2ea96efac88fb3ebec9342738e225f7c7c2b011ce375b56621a20642b4d36e060db4524af1 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 9992b9395303e2647931a1b81beddeec78c78b75e77c75d20b3a20c229a97640f77c9a88d514ffcc5830fbeeb434c3dc +3c054e333a94259c36af09ab5b4ff9beb3492f8d5b4282d16801daccb29f70fe61a0b37ffef5c04cd1b70e85b1f549a1c4dc672985e50f43ea037efa9964f096b5f62f7ffdf8d6bfb2cc859558f5a393cb949dbd48f269343b5263dcdb9c556eca074f2e98e6d94c2c29a677afaf806edf79b15a3fcd46e7067b7669f83188ee e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef b884e901156c9212003c871f33a5ebec1e1c5100116d951b1957534db8f7997b41aa0fcfa011ad58e88d3cdb53bb866e +0989122410d522af64ceb07da2c865219046b4c3d9d99b01278c07ff63eaf1039cb787ae9e2dd46436cc0415f280c562bebb83a23e639e476a02ec8cff7ea06cd12c86dcc3adefbf1a9e9a9b6646c7599ec631b0da9a60debeb9b3e19324977f3b4f36892c8a38671c8e1cc8e50fcd50f9e51deaf98272f9266fc702e4e57c30 a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 aeb3c429e272fccda608d0afb9cb5882070487d2f497b166c97c82950acc8b1d91c3ededaef8e86234beb07d50e9b9f1 +dc66e39f9bbfd9865318531ffe9207f934fa615a5b285708a5e9c46b7775150e818d7f24d2a123df3672fff2094e3fd3df6fbe259e3989dd5edfcccbe7d45e26a775a5c4329a084f057c42c13f3248e3fd6f0c76678f890f513c32292dd306eaa84a59abe34b16cb5e38d0e885525d10336ca443e1682aa04a7af832b0eee4e7 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d a05df6c183519dd8a579a0fbfd8b0c009c1a920ce5f53c7e303ce3d1569625049d311b0a1432446834e78e5c2170faf0 +600974e7d8c5508e2c1aab0783ad0d7c4494ab2b4da265c2fe496421c4df238b0be25f25659157c8a225fb03953607f7df996acfd402f147e37aee2f1693e3bf1c35eab3ae360a2bd91d04622ea47f83d863d2dfecb618e8b8bdc39e17d15d672eee03bb4ce2cc5cf6b217e5faf3f336fdd87d972d3a8b8a593ba85955cc9d71 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d 90358419117eec9f5a1df73eb77f65219ff67adb36866257a21b51dc339b4fca72141a9a027c54423e396bd45cd42fba +dfa6cb9b39adda6c74cc8b2a8b53a12c499ab9dee01b4123642b4f11af336a91a5c9ce0520eb2395a6190ecbf6169c4cba81941de8e76c9c908eb843b98ce95e0da29c5d4388040264e05e07030a577cc5d176387154eabae2af52a83e85c61c7c61da930c9b19e45d7e34c8516dc3c238fddd6e450a77455d534c48a152010b 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab a4013a014092642374a4d78c05c5b460e7c7a20dccfbd8e283abce70deeaae855cf5f459e19e8ec526b76d1ced8a48e8 +51d2547cbff92431174aa7fc7302139519d98071c755ff1c92e4694b58587ea560f72f32fc6dd4dee7d22bb7387381d0256e2862d0644cdf2c277c5d740fa089830eb52bf79d1e75b8596ecf0ea58a0b9df61e0c9754bfcd62efab6ea1bd216bf181c5593da79f10135a9bc6e164f1854bc8859734341aad237ba29a81a3fc8b 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a 82a75054bfd2481e5c884a226f22ff5d9a725d74782f4e0cc6b2ff29f2bb4890ae7d98b2daa53730306bcf88cc53f23d +558c2ac13026402bad4a0a83ebc9468e50f7ffab06d6f981e5db1d082098065bcff6f21a7a74558b1e8612914b8b5a0aa28ed5b574c36ac4ea5868432a62bb8ef0695d27c1e3ceaf75c7b251c65ddb268696f07c16d2767973d85beb443f211e6445e7fe5d46f0dce70d58a4cd9fe70688c035688ea8c6baec65a5fc7e2c93e8 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 8624fe77aa6ead7ccdcbf732d72ad99ed3dddb1fdd0c98adb5b18eec820f9824ce564894e6a19f1d612fda61890f5d27 +4d55c99ef6bd54621662c3d110c3cb627c03d6311393b264ab97b90a4b15214a5593ba2510a53d63fb34be251facb697c973e11b665cb7920f1684b0031b4dd370cb927ca7168b0bf8ad285e05e9e31e34bc24024739fdc10b78586f29eff94412034e3b606ed850ec2c1900e8e68151fc4aee5adebb066eb6da4eaa5681378e f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 93b0a8c38a899af2dee912b1b9b9a4f128bd4198b08aa8015e3400bd1e5da7c1d3393e5ba5db6f2e75121aba4fa74297 +f8248ad47d97c18c984f1f5c10950dc1404713c56b6ea397e01e6dd925e903b4fadfe2c9e877169e71ce3c7fe5ce70ee4255d9cdc26f6943bf48687874de64f6cf30a012512e787b88059bbf561162bdcc23a3742c835ac144cc14167b1bd6727e940540a9c99f3cbb41fb1dcb00d76dda04995847c657f4c19d303eb09eb48a b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 b19f8dc8decc9a5e99723b9a017329ec9dab69b032a7b6b07ac5a821f26557e886062a5b8d1069045968e5c8064b5cc8 +3b6ee2425940b3d240d35b97b6dcd61ed3423d8e71a0ada35d47b322d17b35ea0472f35edd1d252f87b8b65ef4b716669fc9ac28b00d34a9d66ad118c9d94e7f46d0b4f6c2b2d339fd6bcd351241a387cc82609057048c12c4ec3d85c661975c45b300cb96930d89370a327c98b67defaa89497aa8ef994c77f1130f752f94a4 d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 ab5827806d79b07cce19524486902b0048c2d807828310640673160fadafa7fbb0932946b12be60c4457c79707318850 +c5204b81ec0a4df5b7e9fda3dc245f98082ae7f4efe81998dcaa286bd4507ca840a53d21b01e904f55e38f78c3757d5a5a4a44b1d5d4e480be3afb5b394a5d2840af42b1b4083d40afbfe22d702f370d32dbfd392e128ea4724d66a3701da41ae2f03bb4d91bb946c7969404cb544f71eb7a49eb4c4ec55799bda1eb545143a7 b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c a4fb1107b9bf77ef1dec7ada30202b6efef70001dd4b579e43c590dc4843cccca321da56d02e0d36473de2ea9007c0bf +72e81fe221fb402148d8b7ab03549f1180bcc03d41ca59d7653801f0ba853add1f6d29edd7f9abc621b2d548f8dbf8979bd16608d2d8fc3260b4ebc0dd42482481d548c7075711b5759649c41f439fad69954956c9326841ea6492956829f9e0dc789f73633b40f6ac77bcae6dfc7930cfe89e526d1684365c5b0be2437fdb01 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 a20ceaaac5195e82f91f7b7c83f445cc1d945e98b8b90a7ca3b7cc10430ec2e712cb152e207a9a45bc12765b98dd0f37 +21188c3edd5de088dacc1076b9e1bcecd79de1003c2414c3866173054dc82dde85169baa77993adb20c269f60a5226111828578bcc7c29e6e8d2dae81806152c8ba0c6ada1986a1983ebeec1473a73a04795b6319d48662d40881c1723a706f516fe75300f92408aa1dc6ae4288d2046f23c1aa2e54b7fb6448a0da922bd7f34 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 b7cd2633ebffeeaeb944d50305e6b903ad437e095663e389b3e186092a3744516cfcff1f2a59fc3d7cdf7698d29f0b9e +e0b8596b375f3306bbc6e77a0b42f7469d7e83635990e74aa6d713594a3a24498feff5006790742d9c2e9b47d714bee932435db747c6e733e3d8de41f2f91311f2e9fd8e025651631ffd84f66732d3473fbd1627e63dc7194048ebec93c95c159b5039ab5e79e42c80b484a943f125de3da1e04e5bf9c16671ad55a1117d3306 b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced b98f1ebf252b5e7ce52d0a04ce995e3c24cc88cbc89695d74988fe6a74530a7fb14f1c213dc4cbb0ef635fe53f42652a +099a0131179fff4c6928e49886d2fdb3a9f239b7dd5fa828a52cbbe3fcfabecfbba3e192159b887b5d13aa1e14e6a07ccbb21f6ad8b7e88fee6bea9b86dea40ffb962f38554056fb7c5bb486418915f7e7e9b9033fe3baaf9a069db98bc02fa8af3d3d1859a11375d6f98aa2ce632606d0800dff7f55b40f971a8586ed6b39e9 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181 98fbf461f2066875bfd63aeac8792fd198a333bae35aedf1ee278ac5c65bf90c87718362264c864590c2313d6242973f +0fbc07ea947c946bea26afa10c51511039b94ddbc4e2e4184ca3559260da24a14522d1497ca5e77a5d1a8e86583aeea1f5d4ff9b04a6aa0de79cd88fdb85e01f171143535f2f7c23b050289d7e05cebccdd131888572534bae0061bdcc3015206b9270b0d5af9f1da2f9de91772d178a632c3261a1e7b3fb255608b3801962f9 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431 b2a66c645a85088b31bc112c43eab104da3f056072f1f2deecff3060711c6ed507de4bdf9a1e3ddd058d254d3311156c +1e38d750d936d8522e9db1873fb4996bef97f8da3c6674a1223d29263f1234a90b751785316444e9ba698bc8ab6cd010638d182c9adad4e334b2bd7529f0ae8e9a52ad60f59804b2d780ed52bdd33b0bf5400147c28b4304e5e3434505ae7ce30d4b239e7e6f0ecf058badd5b388eddbad64d24d2430dd04b4ddee98f972988f 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd a5c2d4dd6cbf52995f20e1884e28c2e0d3d09fea5d6c48cfba45c7020d80fa0ab670179375c1d229984401d5017ed760 +abcf0e0f046b2e0672d1cc6c0a114905627cbbdefdf9752f0c31660aa95f2d0ede72d17919a9e9b1add3213164e0c9b5ae3c76f1a2f79d3eeb444e6741521019d8bd5ca391b28c1063347f07afcfbb705be4b52261c19ebaf1d6f054a74d86fb5d091fa7f229450996b76f0ada5f977b09b58488eebfb5f5e9539a8fd89662ab 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de a543a1a26bdb1c4b96ae8aa3f5fde06dbe7736a723e0eb5e5772068aaf82b22ee3ad47aaa715dd1f0e8439842683c6ef +dc3d4884c741a4a687593c79fb4e35c5c13c781dca16db561d7e393577f7b62ca41a6e259fc1fb8d0c4e1e062517a0fdf95558b7799f20c211796167953e6372c11829beec64869d67bf3ee1f1455dd87acfbdbcc597056e7fb347a17688ad32fda7ccc3572da7677d7255c261738f07763cd45973c728c6e9adbeecadc3d961 ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566 84b3aaaa10329a6bcd9601bb38b3a7e3657bf24c514bd5b4dad2d3b00c8649a5a1790ea7391fb0298bd04040707f8fd0 +719bf1911ae5b5e08f1d97b92a5089c0ab9d6f1c175ac7199086aeeaa416a17e6d6f8486c711d386f284f096296689a54d330c8efb0f5fa1c5ba128d3234a3da856c2a94667ef7103616a64c913135f4e1dc50e38daa60610f732ad1bedfcc396f87169392520314a6b6b9af6793dbabad4599525228cc7c9c32c4d8e097ddf6 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee 912c4d969117c077f8b2f39d3f8a7d7d85b68eef9b7d6d800282c260fea781b5bb058888bf980b74ddb38eb732f188f9 +7cf19f4c851e97c5bca11a39f0074c3b7bd3274e7dd75d0447b7b84995dfc9f716bf08c25347f56fcc5e5149cb3f9cfb39d408ace5a5c47e75f7a827fa0bb9921bb5b23a6053dbe1fa2bba341ac874d9b1333fc4dc224854949f5c8d8a5fedd02fb26fdfcd3be351aec0fcbef18972956c6ec0effaf057eb4420b6d28e0c008c 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd b2e991f261e96ab4cc5abb0bb071f34e8199c1bee8fea15eea05bc321b44066a7a2e052c52ea68ab6d75e74268a9eb40 +b892ffabb809e98a99b0a79895445fc734fa1b6159f9cddb6d21e510708bdab6076633ac30aaef43db566c0d21f4381db46711fe3812c5ce0fb4a40e3d5d8ab24e4e82d3560c6dc7c37794ee17d4a144065ef99c8d1c88bc22ad8c4c27d85ad518fa5747ae35276fc104829d3f5c72fc2a9ea55a1c3a87007cd133263f79e405 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666 928080c7025a0660b6997e783b9bfccb7a5671b3fdb153e1e1a506362777ae2c196fbb4a5cd2aad6c9f7b2e07f295d8b +8144e37014c95e13231cbd6fa64772771f93b44e37f7b02f592099cc146343edd4f4ec9fa1bc68d7f2e9ee78fc370443aa2803ff4ca52ee49a2f4daf2c8181ea7b8475b3a0f608fc3279d09e2d057fbe3f2ffbe5133796124781299c6da60cfe7ecea3abc30706ded2cdf18f9d788e59f2c31662df3abe01a9b12304fb8d5c8c bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67 aa5d2f6f959058bf7d00e2276fe5c4bb75761c0abc9948c944349058ae2232c7b920e4d03011c816f78fda5f315c55ee +a3683d120807f0a030feed679785326698c3702f1983eaba1b70ddfa7f0b3188060b845e2b67ed57ee68087746710450f7427cb34655d719c0acbc09ac696adb4b22aba1b9322b7111076e67053a55f62b501a4bca0ad9d50a868f51aeeb4ef27823236f5267e8da83e143047422ce140d66e05e44dc84fb3a4506b2a5d7caa8 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9 8688d2c5ccee13d33fdde0a02504faba8c1f267cc6ba19258b9901cab45b0e929ed93f244271621ac96933212f492fca +b1df8051b213fc5f636537e37e212eb20b2423e6467a9c7081336a870e6373fc835899d59e546c0ac668cc81ce4921e88f42e6da2a109a03b4f4e819a17c955b8d099ec6b282fb495258dca13ec779c459da909475519a3477223c06b99afbd77f9922e7cbef844b93f3ce5f50db816b2e0d8b1575d2e17a6b8db9111d6da578 f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce ac218b92c9441d5de6dc8ce0d6aaed4f1cbf64530ce8edecf9d394ccc43462980e535ef11de711cb0beceb930a1c3f63 +0b918ede985b5c491797d0a81446b2933be312f419b212e3aae9ba5914c00af431747a9d287a7c7761e9bcbc8a12aaf9d4a76d13dad59fc742f8f218ef66eb67035220a07acc1a357c5b562ecb6b895cf725c4230412fefac72097f2c2b829ed58742d7c327cad0f1058df1bddd4ae9c6d2aba25480424308684cecd6517cdd8 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f ad84865281e3c7dfc971968e8280f9a1c37abf4889a0b4cb0a0bae021905a7f0c99519651a2ffffd87f403d37ca9e4fc +0fab26fde1a4467ca930dbe513ccc3452b70313cccde2994eead2fde85c8da1db84d7d06a024c9e88629d5344224a4eae01b21a2665d5f7f36d5524bf5367d7f8b6a71ea05d413d4afde33777f0a3be49c9e6aa29ea447746a9e77ce27232a550b31dd4e7c9bc8913485f2dc83a56298051c92461fd46b14cc895c300a4fb874 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b b3b357b1c056ef78c41bf2de9a027649f7fe7faca3b2edcb885b848c382b74426ecac15c6d7dc7c7ba05a87fe35b1b51 +7843f157ef8566722a7d69da67de7599ee65cb3975508f70c612b3289190e364141781e0b832f2d9627122742f4b5871ceeafcd09ba5ec90cae6bcc01ae32b50f13f63918dfb5177df9797c6273b92d103c3f7a3fc2050d2b196cc872c57b77f9bdb1782d4195445fcc6236dd8bd14c8bcbc8223a6739f6a17c9a861e8c821a6 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388 b8ea236b83112871a41170a14b91fca3b28c42dbed414ae8560a26c3d07f7ea7481edc9a5163d2334685ce83edff7afd +6c8572b6a3a4a9e8e03dbeed99334d41661b8a8417074f335ab1845f6cc852adb8c01d9820fcf8e10699cc827a8fbdca2cbd46cc66e4e6b7ba41ec3efa733587e4a30ec552cd8ddab8163e148e50f4d090782897f3ddac84a41e1fcfe8c56b6152c0097b0d634b41011471ffd004f43eb4aafc038197ec6bae2b4470e869bded 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499 909955bc7b702e4809e08344acab388ba469851ba41ce6502a1cca2d193578ca7766f1e663cb43564c6bf8db3210465c +7e3c8fe162d48cc8c5b11b5e5ebc05ebc45c439bdbc0b0902145921b8383037cb0812222031598cd1a56fa71694fbd304cc62938233465ec39c6e49f57dfe823983b6923c4e865633949183e6b90e9e06d8275f3907d97967d47b6239fe2847b7d49cf16ba69d2862083cf1bccf7afe34fdc90e21998964107b64abe6b89d126 f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6 90576efc875b3e88e962e31aa64c5aeda85e7a42c2ed0da86d1214fbd26382fe46395c256e888903c384a2f1a71ecd8f +d5aa8ac9218ca661cd177756af6fbb5a40a3fecfd4eea6d5872fbb9a2884784aa9b5f0c023a6e0da5cf6364754ee6465b4ee2d0ddc745b02994c98427a213c849537da5a4477b3abfe02648be67f26e80b56a33150490d062aaac137aa47f11cfeddba855bab9e4e028532a563326d927f9e6e3292b1fb248ee90b6f429798db 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead 8e961e86f811a7e4060db449ccf8b1cbb569e112161ab92e268ee3dac709ae93cd957b068f8775d2b1affec9c3671713 +790b06054afc9c3fc4dfe72df19dd5d68d108cfcfca6212804f6d534fd2fbe489bd8f64bf205ce04bcb50124a12ce5238fc3fe7dd76e6fa640206af52549f133d593a1bfd423ab737f3326fa79433cde293236f90d4238f0dd38ed69492ddbd9c3eae583b6325a95dec3166fe52b21658293d8c137830ef45297d67813b7a508 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd a15fcae0722ecf0aff697e87c1e9329bc8c0c5c61cbf0fe896b1b02384b266438fac4d9c6cb5af74e2a2f26bfd327b0c +6d549aa87afdb8bfa60d22a68e2783b27e8db46041e4df04be0c261c4734b608a96f198d1cdb8d082ae48579ec9defcf21fbc72803764a58c31e5323d5452b9fb57c8991d31749140da7ef067b18bf0d7dfbae6eefd0d8064f334bf7e9ec1e028daed4e86e17635ec2e409a3ed1238048a45882c5c57501b314e636b9bc81cbe 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117 abc23f8b569963cb79f7af33427bcd77e71b7b9fcee7a5d5ab666377d327e0c4d127fb3574af7e0d37b60275baeee1b7 +1906e48b7f889ee3ff7ab0807a7aa88f53f4018808870bfed6372a77330c737647961324c2b4d46f6ee8b01190474951a701b048ae86579ff8e3fc889fecf926b17f98958ac7534e6e781ca2db2baa380dec766cfb2a3eca2a9d5818967d64dfab84f768d24ec122eebacaab0a4dc3a75f37331bb1c43dd8966cc09ec4945bbd 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61 b4a021528a9efe857ff0eb86d1105f3b5c547e6ba0c36270b0d0863d67c2a10328263e994cbc864da31300b331854af1 +7b59fef13daf01afec35dea3276541be681c4916767f34d4e874464d20979863ee77ad0fd1635bcdf93e9f62ed69ae52ec90aab5bbf87f8951213747ccec9f38c775c1df1e9d7f735c2ce39b42edb3b0c5086247556cfea539995c5d9689765288ec600848ecf085c01ca738bbef11f5d12d4457db988b4add90be00781024ad 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2 a346d4596f4fde4604ac5d359b188baad252e4a31f4737a44bb47b63ca712d44993a42d0eae43ec640b93d748332045c +041a6767a935dc3d8985eb4e608b0cbfebe7f93789d4200bcfe595277ac2b0f402889b580b72def5da778a680fd380c955421f626d52dd9a83ea180187b850e1b72a4ec6dd63235e598fd15a9b19f8ce9aec1d23f0bd6ea4d92360d50f951152bc9a01354732ba0cf90aaed33c307c1de8fa3d14f9489151b8377b57c7215f0b 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7 b777a8df7a398dcabf69cced50a131610f4bd2b6291d181d34bba6bed78e9ea3027c38aa85f5a22c481c5d20b0467aa2 +7905a9036e022c78b2c9efd40b77b0a194fbc1d45462779b0b76ad30dc52c564e48a493d8249a061e62f26f453ba566538a4d43c64fb9fdbd1f36409316433c6f074e1b47b544a847de25fc67d81ac801ed9f7371a43da39001c90766f943e629d74d0436ba1240c3d7fab990d586a6d6ef1771786722df56448815f2feda48f 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870 93ec3e7af20b850d75839e07f41d02de32022a34bece172f021dff5857fe7ae30f0b76805210109ee8bfb86b9400642f +cf25e4642d4f39d15afb7aec79469d82fc9aedb8f89964e79b749a852d931d37436502804e39555f5a3c75dd958fd5291ada647c1a5e38fe7b1048f16f2b711fdd5d39acc0812ca65bd50d7f8119f2fd195ab16633503a78ee9102c1f9c4c22568e0b54bd4fa3f5ff7b49160bf23e7e2231b1ebebbdaf0e4a7d4484158a87e07 e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf a992be7b7c8962352ea575b5f13b4e485069e07be471a7a93fc2af55f40c4139bf6a7b02270d5cd9fe3821a2439d9efa +7562c445b35883cc937be6349b4cefc3556a80255d70f09e28c3f393daac19442a7eecedcdfbe8f7628e30cd8939537ec56d5c9645d43340eb4e78fc5dd4322de8a07966b262770d7ff13a071ff3dce560718e60ed3086b7e0003a6abafe91af90af86733ce8689440bf73d2aa0acfe9776036e877599acbabfcb03bb3b50faa 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c a03e274a066ca253cb2e8f9dc645868305dedd29cac973d28585995d6673b367fb50d5fc1a7b10875ee5a752a8349acf +051c2db8e71e44653ea1cb0afc9e0abdf12658e9e761bfb767c20c7ab4adfcb18ed9b5c372a3ac11d8a43c55f7f99b33355437891686d42362abd71db8b6d84dd694d6982f0612178a937aa934b9ac3c0794c39027bdd767841c4370666c80dbc0f8132ca27474f553d266deefd7c9dbad6d734f9006bb557567701bb7e6a7c9 f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9 b57393a8d4ae29e9a1bad8c16bc41e092ba92b04286355c2c5556499671f3422acc284abd6eb66a9041b227648364698 +4dcb7b62ba31b866fce7c1feedf0be1f67bf611dbc2e2e86f004422f67b3bc1839c6958eb1dc3ead137c3d7f88aa97244577a775c8021b1642a8647bba82871e3c15d0749ed343ea6cad38f123835d8ef66b0719273105e924e8685b65fd5dc430efbc35b05a6097f17ebc5943cdcd9abcba752b7f8f37027409bd6e11cd158f f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5 a09339f1a2586918463395c323b6d51f6b59ea7ca1863f2e408a66a1e28807a00167935c79ded161f06a6fef6658d86f +efe55737771070d5ac79236b04e3fbaf4f2e9bed187d1930680fcf1aba769674bf426310f21245006f528779347d28b8aeacd2b1d5e3456dcbf188b2be8c07f19219e4067c1e7c9714784285d8bac79a76b56f2e2676ea93994f11eb573af1d03fc8ed1118eafc7f07a82f3263c33eb85e497e18f435d4076a774f42d276c323 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628 ab358f908ea354d51858830615beefc38f36a463afd3db8fad5a5ace1a8bc5e23757107cd0f9bc20d85dbf45d0818df1 +ea95859cc13cccb37198d919803be89c2ee10befdcaf5d5afa09dcc529d333ae1e4ffd3bd8ba8642203badd7a80a3f77eeee9402eed365d53f05c1a995c536f8236ba6b6ff8897393506660cc8ea82b2163aa6a1855251c87d935e23857fe35b889427b449de7274d7754bdeace960b4303c5dd5f745a5cfd580293d6548c832 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49 8c7e46619224e44b2382b096bacdee1e409e2d558d9c1a5831faf09af7a845aa79929df732a982ef5cbf2148d167fe0c diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P256_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P256_blst new file mode 100644 index 000000000000..a90b8e36ff9e --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P256_blst @@ -0,0 +1,60 @@ +ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590 b357edb9d772e233a37f861283e0fd7dae16ff101c5bfff56e4932894721f88d1f9530796d86afc8a9d6164a7cb83884 +9155e91fd9155eeed15afd83487ea1a3af04c5998b77c0fe8c43dcc479440a8a9a89efe883d9385cb9edfde10b43bce61fb63669935ad39419cf29ef3a936931733bfc2378e253e73b7ae9a3ec7a6a7932ab10f1e5b94d05160c053988f3bdc9167155d069337d42c9a7056619efc031fa5ec7310d29bd28980b1e3559757578 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98 90125ee9336f4c0de58568f23b55bbc9a14d5dc826e12ba20b24130cb1351f372aa6ac98da1d42e694b7a54129dc64a2 +b242a7586a1383368a33c88264889adfa3be45422fbef4a2df4e3c5325a9c7757017e0d5cf4bbf4de7f99d189f81f1fd2f0dd645574d1eb0d547eead9375677819297c1abe62526ae29fc54cdd11bfe17714f2fbd2d0d0e8d297ff98535980482dd5c1ebdc5a7274aabf1382c9f2315ca61391e3943856e4c5e616c2f1f7be0d a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870 88d2dd6c035f852aa97d5dccef42ca834d951456d32f1959e719a4d8017af4225456bdc18f2e1e317d8f2a570cbb0cfc +b64005da76b24715880af94dba379acc25a047b06066c9bedc8f17b8c74e74f4fc720d9f4ef0e2a659e0756931c080587ebdcd0f85e819aea6dacb327a9d96496da53ea21aef3b2e793a9c0def5196acec99891f46ead78a85bc7ab644765781d3543da9fbf9fec916dca975ef3b4271e50ecc68bf79b2d8935e2b25fc063358 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f 830eb3f3df6a068a574ea5830362b819eee2d98d19817c9bd8de11fa3fc7978c327da363e04f8fd1b712f2fd30631fdf +fe6e1ea477640655eaa1f6e3352d4bce53eb3d95424df7f238e93d8531da8f36bc35fa6be4bf5a6a382e06e855139eb617a9cc9376b4dafacbd80876343b12628619d7cbe1bff6757e3706111ed53898c0219823adbc044eaf8c6ad449df8f6aab9d444dadb5c3380eec0d91694df5fc4b30280d4b87d27e67ae58a1df828963 daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d b709df6941a1be5ef9f7d4a0f52cc94a1defaee8c9fb3cd180b5cd3bd1b3644798b9a8be24299ce245b03e4056c7e5e3 +907c0c00dc080a688548957b5b8b1f33ba378de1368023dcad43242411f554eb7d392d3e5c1668fad3944ff9634105343d83b8c85d2a988da5f5dc60ee0518327caed6dd5cf4e9bc6222deb46d00abde745f9b71d6e7aee6c7fdfc9ed053f2c0b611d4c6863088bd012ea9810ee94f8e58905970ebd07353f1f409a371ed03e3 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5 8240eb6fa775361a8ec8d7f78dd236ad804b919c2908fbb0d283418abb7dfedf2bcdfcbf7a85c8f39c6aa02958abc108 +771c4d7bce05610a3e71b272096b57f0d1efcce33a1cb4f714d6ebc0865b2773ec5eedc25fae81dee1d256474dbd9676623614c150916e6ed92ce4430b26037d28fa5252ef6b10c09dc2f7ee5a36a1ea7897b69f389d9f5075e271d92f4eb97b148f3abcb1e5be0b4feb8278613d18abf6da60bfe448238aa04d7f11b71f44c5 f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96 ab419b7b31053bb231fe906093ed020ea737aea124ef4cba5f651cff06f892558584f334f81e7e33433fc9cc9c683e56 +a3b2825235718fc679b942e8ac38fb4f54415a213c65875b5453d18ca012320ddfbbc58b991eaebadfc2d1a28d4f0cd82652b12e4d5bfda89eda3be12ac52188e38e8cce32a264a300c0e463631f525ae501348594f980392c76b4a12ddc88e5ca086cb8685d03895919a8627725a3e00c4728e2b7c6f6a14fc342b2937fc3dd 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d 8ae98b8fdeba65f9be722846bed19e68876603099c3e967293265e70c2fe7966617b89425a64281701ffb33917790036 +3e6e2a9bffd729ee5d4807849cd4250021d8184cda723df6ab0e5c939d39237c8e58af9d869fe62d3c97b3298a99e891e5e11aa68b11a087573a40a3e83c7965e7910d72f81cad0f42accc5c25a4fd3cdd8cee63757bbbfbdae98be2bc867d3bcb1333c4632cb0a55dffeb77d8b119c466cd889ec468454fabe6fbee7102deaf 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9 87312b013571ecaf98434186724259462e642f4d4eb8cb79faa6ef7ba69b26c5045e76f8da15bcb68318809f9f0ca7a1 +52e5c308e70329a17c71eaedb66bbee303c8ec48a6f1a2efb235d308563cd58553d434e12f353227a9ea28608ec9c820ed83c95124e7a886f7e832a2de1032e78dc059208f9ec354170b2b1cab992b52ac01e6c0e4e1b0112686962edc53ab226dafcc9fc7baed2cd9307160e8572edb125935db49289b178f35a8ad23f4f801 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634 af84eba1c02416aa52d9a4355a2a09916db8c6937ceba127b86bfa2aeda3253a5ba3680b3e6cb76e7d206cc7638f49d5 +d3e9e82051d4c84d699453c9ff44c7c09f6523bb92232bcf30bf3c380224249de2964e871d56a364d6955c81ef91d06482a6c7c61bc70f66ef22fad128d15416e7174312619134f968f1009f92cbf99248932efb533ff113fb6d949e21d6b80dfbbe69010c8d1ccb0f3808ea309bb0bac1a222168c95b088847e613749b19d04 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27 8163433af09cd6673291dd4fa046304225837a814d7529d82a44f629e66d5c7f210da873f5420f2bad47bb400dc68f1b +968951c2c1918436fe19fa2fe2152656a08f9a6b8aa6201920f1b424da98cee71928897ff087620cc5c551320b1e75a1e98d7d98a5bd5361c9393759614a6087cc0f7fb01fcb173783eb4c4c23961a8231ac4a07d72e683b0c1bd4c51ef1b031df875e7b8d5a6e0628949f5b8f157f43dccaea3b2a4fc11181e6b451e06ceb37 cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d 9120d0a011f61ff66877650025e57214f78cba0184b47e44547ab072ad914c5270e3af14f33d56ed8ba9ec2e5fe6a121 +78048628932e1c1cdd1e70932bd7b76f704ba08d7e7d825d3de763bf1a062315f4af16eccefe0b6ebadccaf403d013f50833ce2c54e24eea8345e25f93b69bb048988d102240225ceacf5003e2abdcc90299f4bf2c101585d36ecdd7a155953c674789d070480d1ef47cc7858e97a6d87c41c6922a00ea12539f251826e141b4 b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c 900e060f9d48617991d6cae28fc20890a138c43d869698f27d536c93e010901a3f293be1d6c80b58b805676814693289 +9b0800c443e693067591737fdbcf0966fdfa50872d41d0c189d87cbc34c2771ee5e1255fd604f09fcf167fda16437c245d299147299c69046895d22482db29aba37ff57f756716cd3d6223077f747c4caffbecc0a7c9dfaaafd9a9817470ded8777e6355838ac54d11b2f0fc3f43668ff949cc31de0c2d15af5ef17884e4d66a 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48 a17842648db4a13f1f7295ab59ec349ff1e01563f912fc2bf7aa2195468b705614ff3f6964f4778828197ed9da4c687c +fc3b8291c172dae635a6859f525beaf01cf683765d7c86f1a4d768df7cae055f639eccc08d7a0272394d949f82d5e12d69c08e2483e11a1d28a4c61f18193106e12e5de4a9d0b4bf341e2acd6b715dc83ae5ff63328f8346f35521ca378b311299947f63ec593a5e32e6bd11ec4edb0e75302a9f54d21226d23314729e061016 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f a46b3abb6beb710bb5182b7cb9a5cf90b081155dd2c49c53bad1612221b2e0fc74e6bb69a61b9d022d9c1f1484f2a7a8 +5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 ad0d2be7cd15a75fff8fe59a09790d61ed369187356b2d2bfc0cb7ae3374a3331b7ad082bc88b97a8d7166177e9d00b3 +c35e2f092553c55772926bdbe87c9796827d17024dbb9233a545366e2e5987dd344deb72df987144b8c6c43bc41b654b94cc856e16b96d7a821c8ec039b503e3d86728c494a967d83011a0e090b5d54cd47f4e366c0912bc808fbb2ea96efac88fb3ebec9342738e225f7c7c2b011ce375b56621a20642b4d36e060db4524af1 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 8b9b298fc345a758235a07f0893385a7cfa0030525c50159a75d606240b427094a261b59f93ccfd42bb2da460690dcf1 +3c054e333a94259c36af09ab5b4ff9beb3492f8d5b4282d16801daccb29f70fe61a0b37ffef5c04cd1b70e85b1f549a1c4dc672985e50f43ea037efa9964f096b5f62f7ffdf8d6bfb2cc859558f5a393cb949dbd48f269343b5263dcdb9c556eca074f2e98e6d94c2c29a677afaf806edf79b15a3fcd46e7067b7669f83188ee e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef 8c82e6597820584aff27e7fd601445efa09c77157a521b56f03d0f57022a67aa2b9174689f25a35c74748769a85656fd +0989122410d522af64ceb07da2c865219046b4c3d9d99b01278c07ff63eaf1039cb787ae9e2dd46436cc0415f280c562bebb83a23e639e476a02ec8cff7ea06cd12c86dcc3adefbf1a9e9a9b6646c7599ec631b0da9a60debeb9b3e19324977f3b4f36892c8a38671c8e1cc8e50fcd50f9e51deaf98272f9266fc702e4e57c30 a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 b515c72b5f16293b98fa67410edbb76799a37a70246d3dc266c6d129e4e28712d53deb7204d87dbf8b2dca26bec44072 +dc66e39f9bbfd9865318531ffe9207f934fa615a5b285708a5e9c46b7775150e818d7f24d2a123df3672fff2094e3fd3df6fbe259e3989dd5edfcccbe7d45e26a775a5c4329a084f057c42c13f3248e3fd6f0c76678f890f513c32292dd306eaa84a59abe34b16cb5e38d0e885525d10336ca443e1682aa04a7af832b0eee4e7 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d ad30a6dd8ed3c1c930017e1f48f65127eebd72a9be27dec9273a4f684664ce897f96aa016541ff689d93a592abb91468 +600974e7d8c5508e2c1aab0783ad0d7c4494ab2b4da265c2fe496421c4df238b0be25f25659157c8a225fb03953607f7df996acfd402f147e37aee2f1693e3bf1c35eab3ae360a2bd91d04622ea47f83d863d2dfecb618e8b8bdc39e17d15d672eee03bb4ce2cc5cf6b217e5faf3f336fdd87d972d3a8b8a593ba85955cc9d71 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d b29267063c7fe2fd27f08219ddacf8138fc06ab5ea78936dcc2a71b0585479d35c5b4fd0573504362bc100ce949fa4d4 +dfa6cb9b39adda6c74cc8b2a8b53a12c499ab9dee01b4123642b4f11af336a91a5c9ce0520eb2395a6190ecbf6169c4cba81941de8e76c9c908eb843b98ce95e0da29c5d4388040264e05e07030a577cc5d176387154eabae2af52a83e85c61c7c61da930c9b19e45d7e34c8516dc3c238fddd6e450a77455d534c48a152010b 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab a45d33f2165dd79924a5710d551136982994ab9f72de9888d702a221f610a0d8ae875f5e1765edeed57584782b336ada +51d2547cbff92431174aa7fc7302139519d98071c755ff1c92e4694b58587ea560f72f32fc6dd4dee7d22bb7387381d0256e2862d0644cdf2c277c5d740fa089830eb52bf79d1e75b8596ecf0ea58a0b9df61e0c9754bfcd62efab6ea1bd216bf181c5593da79f10135a9bc6e164f1854bc8859734341aad237ba29a81a3fc8b 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a a6038f60e693332f0ff57573179fbdeb36dbdde9f7d424a00e49f9dbd514cac5e71b91b3618eb2da658ca624d29c2a12 +558c2ac13026402bad4a0a83ebc9468e50f7ffab06d6f981e5db1d082098065bcff6f21a7a74558b1e8612914b8b5a0aa28ed5b574c36ac4ea5868432a62bb8ef0695d27c1e3ceaf75c7b251c65ddb268696f07c16d2767973d85beb443f211e6445e7fe5d46f0dce70d58a4cd9fe70688c035688ea8c6baec65a5fc7e2c93e8 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 8ce962d1f826be4aa211c82ad57deec076d1f0881f8a72637e6c57f240d9e84e382276c72b9b3eb30b1be8169be6ef6c +4d55c99ef6bd54621662c3d110c3cb627c03d6311393b264ab97b90a4b15214a5593ba2510a53d63fb34be251facb697c973e11b665cb7920f1684b0031b4dd370cb927ca7168b0bf8ad285e05e9e31e34bc24024739fdc10b78586f29eff94412034e3b606ed850ec2c1900e8e68151fc4aee5adebb066eb6da4eaa5681378e f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 b7fd5662e6a1c6e9acdf050909094907c49b8fa7111c5a66858e7571af8482f7dcd6ebcc7e5117fd50c689ed5ba554ba +f8248ad47d97c18c984f1f5c10950dc1404713c56b6ea397e01e6dd925e903b4fadfe2c9e877169e71ce3c7fe5ce70ee4255d9cdc26f6943bf48687874de64f6cf30a012512e787b88059bbf561162bdcc23a3742c835ac144cc14167b1bd6727e940540a9c99f3cbb41fb1dcb00d76dda04995847c657f4c19d303eb09eb48a b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 96fa4ec580c58f6ae2d6e525a73cfd316e79de2187663e7d826c00affa2f39274d0a7884396d2ceb126cb17b05ff937a +3b6ee2425940b3d240d35b97b6dcd61ed3423d8e71a0ada35d47b322d17b35ea0472f35edd1d252f87b8b65ef4b716669fc9ac28b00d34a9d66ad118c9d94e7f46d0b4f6c2b2d339fd6bcd351241a387cc82609057048c12c4ec3d85c661975c45b300cb96930d89370a327c98b67defaa89497aa8ef994c77f1130f752f94a4 d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 b3830d602df576260a3386cade9689627f405cb0d4904b1e5d0ef1be1b0cd5d9573a4c0da0f5750282ef458bfe02a780 +c5204b81ec0a4df5b7e9fda3dc245f98082ae7f4efe81998dcaa286bd4507ca840a53d21b01e904f55e38f78c3757d5a5a4a44b1d5d4e480be3afb5b394a5d2840af42b1b4083d40afbfe22d702f370d32dbfd392e128ea4724d66a3701da41ae2f03bb4d91bb946c7969404cb544f71eb7a49eb4c4ec55799bda1eb545143a7 b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c 81229a6e9055d59e76d600577a65ad6278926e93b00d4b35a6f582f5456f90daf7da6b6627dcafa2e8684c2b3323c96c +72e81fe221fb402148d8b7ab03549f1180bcc03d41ca59d7653801f0ba853add1f6d29edd7f9abc621b2d548f8dbf8979bd16608d2d8fc3260b4ebc0dd42482481d548c7075711b5759649c41f439fad69954956c9326841ea6492956829f9e0dc789f73633b40f6ac77bcae6dfc7930cfe89e526d1684365c5b0be2437fdb01 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 a3204ce95abb3c9d56fff6c6b1b2361488230a2381bf2153db74c83170880a7d3140bdb16f7bbc6f7e92297bd78d5c7d +21188c3edd5de088dacc1076b9e1bcecd79de1003c2414c3866173054dc82dde85169baa77993adb20c269f60a5226111828578bcc7c29e6e8d2dae81806152c8ba0c6ada1986a1983ebeec1473a73a04795b6319d48662d40881c1723a706f516fe75300f92408aa1dc6ae4288d2046f23c1aa2e54b7fb6448a0da922bd7f34 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 8a5ba0634bc543b936dc31c00699777e7d8b718a19fffbfd974a63c59c8748e0e71575c54a81db7dbce4ee5a00591d93 +e0b8596b375f3306bbc6e77a0b42f7469d7e83635990e74aa6d713594a3a24498feff5006790742d9c2e9b47d714bee932435db747c6e733e3d8de41f2f91311f2e9fd8e025651631ffd84f66732d3473fbd1627e63dc7194048ebec93c95c159b5039ab5e79e42c80b484a943f125de3da1e04e5bf9c16671ad55a1117d3306 b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced 8e8dbb1097cfacf31665e18143f187da9849988082c854e1e52705023f98f2ef45d4af11e90291803d1dca133583cce7 +099a0131179fff4c6928e49886d2fdb3a9f239b7dd5fa828a52cbbe3fcfabecfbba3e192159b887b5d13aa1e14e6a07ccbb21f6ad8b7e88fee6bea9b86dea40ffb962f38554056fb7c5bb486418915f7e7e9b9033fe3baaf9a069db98bc02fa8af3d3d1859a11375d6f98aa2ce632606d0800dff7f55b40f971a8586ed6b39e9 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181 a61f8c617f2e37b730d2ecdba4b67581de96a1006a942656c4915c077b423079d1f2816e7e88082cd478cc3ef983abae +0fbc07ea947c946bea26afa10c51511039b94ddbc4e2e4184ca3559260da24a14522d1497ca5e77a5d1a8e86583aeea1f5d4ff9b04a6aa0de79cd88fdb85e01f171143535f2f7c23b050289d7e05cebccdd131888572534bae0061bdcc3015206b9270b0d5af9f1da2f9de91772d178a632c3261a1e7b3fb255608b3801962f9 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431 a4e1ea36fe8af148db32c9ece48f6232bc7e8f1b62bea183b63b27f8a23c2f9b33b51bc372ec37ea28595103df8b2511 +1e38d750d936d8522e9db1873fb4996bef97f8da3c6674a1223d29263f1234a90b751785316444e9ba698bc8ab6cd010638d182c9adad4e334b2bd7529f0ae8e9a52ad60f59804b2d780ed52bdd33b0bf5400147c28b4304e5e3434505ae7ce30d4b239e7e6f0ecf058badd5b388eddbad64d24d2430dd04b4ddee98f972988f 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd 8f96e8f3b8c5a16d25ea7cec880bf0f407106803152a4409fc68f4a72092167369ecb0c99f00b6d432a14affd0936f4c +abcf0e0f046b2e0672d1cc6c0a114905627cbbdefdf9752f0c31660aa95f2d0ede72d17919a9e9b1add3213164e0c9b5ae3c76f1a2f79d3eeb444e6741521019d8bd5ca391b28c1063347f07afcfbb705be4b52261c19ebaf1d6f054a74d86fb5d091fa7f229450996b76f0ada5f977b09b58488eebfb5f5e9539a8fd89662ab 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de abbdf69a51b4bbfa66326134fc513a95848c9450090a9c2b473925f0db211533200eae3f1d6f9c95e403debddc748feb +dc3d4884c741a4a687593c79fb4e35c5c13c781dca16db561d7e393577f7b62ca41a6e259fc1fb8d0c4e1e062517a0fdf95558b7799f20c211796167953e6372c11829beec64869d67bf3ee1f1455dd87acfbdbcc597056e7fb347a17688ad32fda7ccc3572da7677d7255c261738f07763cd45973c728c6e9adbeecadc3d961 ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566 a41609d79efe4f657cdc65c7731d6e341c8298923d851e4bd02fe0e3c0bd3136e4e15b6590d60e3119de5257d734e37b +719bf1911ae5b5e08f1d97b92a5089c0ab9d6f1c175ac7199086aeeaa416a17e6d6f8486c711d386f284f096296689a54d330c8efb0f5fa1c5ba128d3234a3da856c2a94667ef7103616a64c913135f4e1dc50e38daa60610f732ad1bedfcc396f87169392520314a6b6b9af6793dbabad4599525228cc7c9c32c4d8e097ddf6 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee abe9c347e1b39957d4f4d9849da113bc371e3149aa6ccfadea321420a936669080b60e6c4aab5e92bfd95553db47c959 +7cf19f4c851e97c5bca11a39f0074c3b7bd3274e7dd75d0447b7b84995dfc9f716bf08c25347f56fcc5e5149cb3f9cfb39d408ace5a5c47e75f7a827fa0bb9921bb5b23a6053dbe1fa2bba341ac874d9b1333fc4dc224854949f5c8d8a5fedd02fb26fdfcd3be351aec0fcbef18972956c6ec0effaf057eb4420b6d28e0c008c 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd b1bdb9e64b6a14c1e3032ee7e822356f2ae457600af6be3feff154d834c6394eff05a12b468c7058a4df9c2c00254b2e +b892ffabb809e98a99b0a79895445fc734fa1b6159f9cddb6d21e510708bdab6076633ac30aaef43db566c0d21f4381db46711fe3812c5ce0fb4a40e3d5d8ab24e4e82d3560c6dc7c37794ee17d4a144065ef99c8d1c88bc22ad8c4c27d85ad518fa5747ae35276fc104829d3f5c72fc2a9ea55a1c3a87007cd133263f79e405 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666 8d633136ed4e1136b8a046823ffe1c14f0f354240a12d1fccd6421cea40458b8c4cca6f29984172f8dbbc37ee826cfa7 +8144e37014c95e13231cbd6fa64772771f93b44e37f7b02f592099cc146343edd4f4ec9fa1bc68d7f2e9ee78fc370443aa2803ff4ca52ee49a2f4daf2c8181ea7b8475b3a0f608fc3279d09e2d057fbe3f2ffbe5133796124781299c6da60cfe7ecea3abc30706ded2cdf18f9d788e59f2c31662df3abe01a9b12304fb8d5c8c bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67 a39f20f186b095d229a04ca876dca0bd43c4943fcd77d694c022c6f7f9df1541fa76c7338c992e35af71f3256f57c004 +a3683d120807f0a030feed679785326698c3702f1983eaba1b70ddfa7f0b3188060b845e2b67ed57ee68087746710450f7427cb34655d719c0acbc09ac696adb4b22aba1b9322b7111076e67053a55f62b501a4bca0ad9d50a868f51aeeb4ef27823236f5267e8da83e143047422ce140d66e05e44dc84fb3a4506b2a5d7caa8 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9 b55b5a9d0e1a2e069c5365f02af68c71116ee39588ed0de3bae954fc3513021ab8bd0b1784077ec2c70f619de0dcb1ab +b1df8051b213fc5f636537e37e212eb20b2423e6467a9c7081336a870e6373fc835899d59e546c0ac668cc81ce4921e88f42e6da2a109a03b4f4e819a17c955b8d099ec6b282fb495258dca13ec779c459da909475519a3477223c06b99afbd77f9922e7cbef844b93f3ce5f50db816b2e0d8b1575d2e17a6b8db9111d6da578 f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce 878b34ce70e6618ce0a282d01b2379d503264218c321e72a70cc9ebdd18f1d41bbeada60b6ad6d0fd906e2d2f9b68cf6 +0b918ede985b5c491797d0a81446b2933be312f419b212e3aae9ba5914c00af431747a9d287a7c7761e9bcbc8a12aaf9d4a76d13dad59fc742f8f218ef66eb67035220a07acc1a357c5b562ecb6b895cf725c4230412fefac72097f2c2b829ed58742d7c327cad0f1058df1bddd4ae9c6d2aba25480424308684cecd6517cdd8 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f aafd5258a3817aad6c450ea7400fc27234e8b46b258fad38992225eeec4646a7753dad434109f1362681934391c12e02 +0fab26fde1a4467ca930dbe513ccc3452b70313cccde2994eead2fde85c8da1db84d7d06a024c9e88629d5344224a4eae01b21a2665d5f7f36d5524bf5367d7f8b6a71ea05d413d4afde33777f0a3be49c9e6aa29ea447746a9e77ce27232a550b31dd4e7c9bc8913485f2dc83a56298051c92461fd46b14cc895c300a4fb874 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b b30177fd04bba2da6dff4d71f9a2e66ade02548cf5297fecaaed483c4647a2067c07489b006ab032a468f79b8e151f1c +7843f157ef8566722a7d69da67de7599ee65cb3975508f70c612b3289190e364141781e0b832f2d9627122742f4b5871ceeafcd09ba5ec90cae6bcc01ae32b50f13f63918dfb5177df9797c6273b92d103c3f7a3fc2050d2b196cc872c57b77f9bdb1782d4195445fcc6236dd8bd14c8bcbc8223a6739f6a17c9a861e8c821a6 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388 a0f6c7e3ed76fb83df728be708cc226e65a510a5c084817f63dffcf6a06449635dc9844baba8a43c4a0b05952ce0e14f +6c8572b6a3a4a9e8e03dbeed99334d41661b8a8417074f335ab1845f6cc852adb8c01d9820fcf8e10699cc827a8fbdca2cbd46cc66e4e6b7ba41ec3efa733587e4a30ec552cd8ddab8163e148e50f4d090782897f3ddac84a41e1fcfe8c56b6152c0097b0d634b41011471ffd004f43eb4aafc038197ec6bae2b4470e869bded 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499 94675b174556f318eb14e410ab6a542810377e0d6474d02eaa93f37ebd63f4730914b9774c35a9b18ce9f9e3cf8b5f10 +7e3c8fe162d48cc8c5b11b5e5ebc05ebc45c439bdbc0b0902145921b8383037cb0812222031598cd1a56fa71694fbd304cc62938233465ec39c6e49f57dfe823983b6923c4e865633949183e6b90e9e06d8275f3907d97967d47b6239fe2847b7d49cf16ba69d2862083cf1bccf7afe34fdc90e21998964107b64abe6b89d126 f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6 830439f70f17a9ed738ea1e9faf9943ffcf2922f53a97f799ebf74156c8e9b8ec96f42ac5b5972e8c3c5020b6241aed1 +d5aa8ac9218ca661cd177756af6fbb5a40a3fecfd4eea6d5872fbb9a2884784aa9b5f0c023a6e0da5cf6364754ee6465b4ee2d0ddc745b02994c98427a213c849537da5a4477b3abfe02648be67f26e80b56a33150490d062aaac137aa47f11cfeddba855bab9e4e028532a563326d927f9e6e3292b1fb248ee90b6f429798db 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead b888c2dd7f114a97ab2df0adbe566321477baa7e569c97abbe7e41082275531f9b11457bfad639ab2ea3137a7d50ee01 +790b06054afc9c3fc4dfe72df19dd5d68d108cfcfca6212804f6d534fd2fbe489bd8f64bf205ce04bcb50124a12ce5238fc3fe7dd76e6fa640206af52549f133d593a1bfd423ab737f3326fa79433cde293236f90d4238f0dd38ed69492ddbd9c3eae583b6325a95dec3166fe52b21658293d8c137830ef45297d67813b7a508 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd b306d648a8655ff58bb1e62e64a34273d2566c7300c7ad4a139b24dde3ef66d9f3a861a50041345eff4abbb5dd62126f +6d549aa87afdb8bfa60d22a68e2783b27e8db46041e4df04be0c261c4734b608a96f198d1cdb8d082ae48579ec9defcf21fbc72803764a58c31e5323d5452b9fb57c8991d31749140da7ef067b18bf0d7dfbae6eefd0d8064f334bf7e9ec1e028daed4e86e17635ec2e409a3ed1238048a45882c5c57501b314e636b9bc81cbe 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117 93f52f40f5ddc7455f096754bf3feade7682ac4cc4fe8883581df7c57bdfd4a96f280a673ea7b5682a9beb73dd54d6d6 +1906e48b7f889ee3ff7ab0807a7aa88f53f4018808870bfed6372a77330c737647961324c2b4d46f6ee8b01190474951a701b048ae86579ff8e3fc889fecf926b17f98958ac7534e6e781ca2db2baa380dec766cfb2a3eca2a9d5818967d64dfab84f768d24ec122eebacaab0a4dc3a75f37331bb1c43dd8966cc09ec4945bbd 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61 b9938246d008e4aa9d0cfde7065b65fff66bd073a916c34db0c3e2acd5e46d51d44be9aa276ca1b46b9bf32c2385422c +7b59fef13daf01afec35dea3276541be681c4916767f34d4e874464d20979863ee77ad0fd1635bcdf93e9f62ed69ae52ec90aab5bbf87f8951213747ccec9f38c775c1df1e9d7f735c2ce39b42edb3b0c5086247556cfea539995c5d9689765288ec600848ecf085c01ca738bbef11f5d12d4457db988b4add90be00781024ad 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2 813527eeaab70965fa35cd8b07950bf402b3f95016bebff5cb3d3eb1fdc48f9619c7cb98e65a865cd304702298456da7 +041a6767a935dc3d8985eb4e608b0cbfebe7f93789d4200bcfe595277ac2b0f402889b580b72def5da778a680fd380c955421f626d52dd9a83ea180187b850e1b72a4ec6dd63235e598fd15a9b19f8ce9aec1d23f0bd6ea4d92360d50f951152bc9a01354732ba0cf90aaed33c307c1de8fa3d14f9489151b8377b57c7215f0b 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7 8d5a020810fdfef64bfdc6f49493c532a7c953c378d0a1ca5302631479dfe259b167d53cc0533b4d89d699255bc3dab7 +7905a9036e022c78b2c9efd40b77b0a194fbc1d45462779b0b76ad30dc52c564e48a493d8249a061e62f26f453ba566538a4d43c64fb9fdbd1f36409316433c6f074e1b47b544a847de25fc67d81ac801ed9f7371a43da39001c90766f943e629d74d0436ba1240c3d7fab990d586a6d6ef1771786722df56448815f2feda48f 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870 b5e89a34852e64e7319cf877c2cc199e8d2701fd048317bd5270d7b99daa6952fbd3bd1f30b6a19654ea0cc81e203024 +cf25e4642d4f39d15afb7aec79469d82fc9aedb8f89964e79b749a852d931d37436502804e39555f5a3c75dd958fd5291ada647c1a5e38fe7b1048f16f2b711fdd5d39acc0812ca65bd50d7f8119f2fd195ab16633503a78ee9102c1f9c4c22568e0b54bd4fa3f5ff7b49160bf23e7e2231b1ebebbdaf0e4a7d4484158a87e07 e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf 8d9c6eb0d56d53451dc4bfdb896b5f5431e04e14d41d1834d845f6087f477db4498068652352977c27c07f0927ebd16d +7562c445b35883cc937be6349b4cefc3556a80255d70f09e28c3f393daac19442a7eecedcdfbe8f7628e30cd8939537ec56d5c9645d43340eb4e78fc5dd4322de8a07966b262770d7ff13a071ff3dce560718e60ed3086b7e0003a6abafe91af90af86733ce8689440bf73d2aa0acfe9776036e877599acbabfcb03bb3b50faa 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c 943ff63cb67585bd650be28f77003d03f41e0708ed13c9eb98b1f9e16d036dd937909955bffa77b4ba5d9ccb7778d4e9 +051c2db8e71e44653ea1cb0afc9e0abdf12658e9e761bfb767c20c7ab4adfcb18ed9b5c372a3ac11d8a43c55f7f99b33355437891686d42362abd71db8b6d84dd694d6982f0612178a937aa934b9ac3c0794c39027bdd767841c4370666c80dbc0f8132ca27474f553d266deefd7c9dbad6d734f9006bb557567701bb7e6a7c9 f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9 9456baaac48f29a818f3d5fd3f8b31e9fc9d12273bbeb9b103947337852305f674ec4ff00547b44df052d6b68a3406a2 +4dcb7b62ba31b866fce7c1feedf0be1f67bf611dbc2e2e86f004422f67b3bc1839c6958eb1dc3ead137c3d7f88aa97244577a775c8021b1642a8647bba82871e3c15d0749ed343ea6cad38f123835d8ef66b0719273105e924e8685b65fd5dc430efbc35b05a6097f17ebc5943cdcd9abcba752b7f8f37027409bd6e11cd158f f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5 a8d5873cb60902196bc916b1e4500620c53e9e06111ebff80fef0e4f8ad6f395372d9574d90cfb1c74e9027fb53e2f1b +efe55737771070d5ac79236b04e3fbaf4f2e9bed187d1930680fcf1aba769674bf426310f21245006f528779347d28b8aeacd2b1d5e3456dcbf188b2be8c07f19219e4067c1e7c9714784285d8bac79a76b56f2e2676ea93994f11eb573af1d03fc8ed1118eafc7f07a82f3263c33eb85e497e18f435d4076a774f42d276c323 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628 a8e417110651ab25129a1702d7f797b54c08f109d4a346e3591fda0a72042c37d0edbd9839f6cbe0c872f2355ca1ab83 +ea95859cc13cccb37198d919803be89c2ee10befdcaf5d5afa09dcc529d333ae1e4ffd3bd8ba8642203badd7a80a3f77eeee9402eed365d53f05c1a995c536f8236ba6b6ff8897393506660cc8ea82b2163aa6a1855251c87d935e23857fe35b889427b449de7274d7754bdeace960b4303c5dd5f745a5cfd580293d6548c832 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49 b91385bd50463e1fdd321e46521fc6fdc616fe9d023e6f35e53bf3b032a3ab1b5634d7f80709f49d927581a563e362c2 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P384 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P384 new file mode 100644 index 000000000000..ba74f14535f9 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P384 @@ -0,0 +1,60 @@ +39f0b25d4c15b09a0692b22fbacbb5f8aee184cb75887e2ebe0cd3be5d3815d29f9b587e10b3168c939054a89df11068e5c3fac21af742bf4c3e9512f5569674e7ad8b39042bcd73e4b7ce3e64fbea1c434ed01ad4ad8b5b569f6a0b9a1144f94097925672e59ba97bc4d33be2fa21b46c3dadbfb3a1f89afa199d4b44189938 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727 8ed705d445e0faaeb400222481eff7458a3b544e70c4b3eba5635f8bff88d47a1bdb35abd5caf4870472b7d9798e97ba +5a3c80e608ed3ac75a6e45f6e94d374271a6d42b67a481860d5d309cc8b37c79cb61f1716dc8aa84cb309ef9d68eb7fc6cf4b42333f316a5c30e74198c8b340926e340c5de47674a707293c4aa2a1a2274a602f01c26b156e895499c60b38ef53fc2032e7485c168d73700d6fa14232596a0e4997854a0b05d02e351b9d3de96 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246 a029682282bc386d68a7c08f288ff70f35d51e6e28512780bee144d9efe9ec1bb92d56def19d17ff09252b03e6ebf7f4 +e7d974c5dbd3bfb8a2fb92fdd782f997d04be79e9713944ce13c5eb6f75dfdec811b7ee4b3859114b07f263846ae13f795eec8f3cb5b7565baff68e0fdd5e09ba8b176d5a71cb03fbc5546e6937fba560acb4db24bd42de1851432b96e8ca4078313cb849bce29c9d805258601d67cd0259e255f3048682e8fdbdda3398c3e31 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83 b634740ae4809273be6f8afe062035b95e364cf5bbcacd429e5f1567a2b1fe8dffc256bf859b3a3b6fac6c66d1e7bcaf +a670fda4d1d56c70de1d8680328043b2b7029633caf0ee59ffe1421c914bb937133d5a0f9214846b2e0b350455a74c4ab434c56de65a17139bb8212bf1c76071a37536fa29348f871dbb26baa92eb93d97e923a6d2ffd9be25cbc33075e494e6db657bd8dc053fe4e17148d8cf6e2058164f2b5766750eb01bbe7b361cdb848c dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659 8e1018630287473e8e3cdfa393a4f9128234b539c2e4ab42c50f8e0907571cf052a8a442378e213e67d2c91718eb5ed5 +7843f918fe2588bcfe756e1f05b491d913523255aa006818be20b676c957f4edb8df863c6f5f8c15b3b80c7a2aa277b70d53f210bdfb856337980c406ea140e439dd321471407f374f69877b2d82367eed51e3c82c13948616dcb301d0c31f8f0352f2846abd9e72071f446a2f1bd3339a09ae41b84e150fd18f4ba5d3c6bfa0 df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718 927675a5f184848030eb118f1fb7373795d9907acfd97f13f8591dda50f2c09af3d9d95262c020c4560a65813a0f9e42 +caa83d5ab07febbd2e0fe2d63738b9b7b8752594bea7aaf50345b3d2f316653a8c9222f2b7877b64679e9573e81461a426029e45b8873a575094a1d572e0d32a9f0a9c6bcb9a2868543b7d8bbe4a69a09e7321f05f8366cced1b72df526f895b60aed2c39c249653c7839538770d4e5f47d3926ec0d168ab6a1af15bf1dca1f7 ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f 95ec607a258b87a27cdfd86e70ed24d234264a5b90c89156df4daf948e443f7b55430879d937861db6785e23848af016 +594603458d6534974aeeafba919c4d0f4cb6843a3af41204bbb88aeb2fca2772d305163dba863da050aabedbaf89db521955d1715de95bbcef979ecdc0c976181ece00355385f8a8f8cce127c9eac15ce3e958a3ed686184674ec9a50eb63271606ee7fdcb1323da3c3db8e89cad1fb42139a32d08abcfbf0d4ccfca18c89a86 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829 8d9bc5d7bb5a082c2d4ed0c3847dcb6b42752b9669858f40612947792fe1037a3e860730514a43a9fb1ca5728a8cd8b6 +733252d2bd35547838be22656cc7aa67eff0af0b13b428f77267a513c6824c3dbae533068b6817e82665f009560affcfe4b2ddb5b667a644fc1a42d24f24e0947e0dc50fb62c919bc1fe4e7ded5e28f2e6d80fcf66a081fb2763526f8def5a81a4ddd38be0b59ee839da1643eeeaee7b1927cec12cf3da67c02bc5465151e346 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1 8703595975c646c1782931699ca1a358f1e1e32c48fb3147ff2d1461f3ead22fef4f8bab2f42efe6b0f86c3b8dbcc2c6 +5a182bd174feb038dfae3346267156bf663167f713dea1ce936b0edb815cd9b8c8e4d411c786ba2494a81442617255db7158b142e720d86c9b56680fb9efd4298cdd69079a28153494c42a24251c7ad42ecf7e97eabc1b3997529b2a297cbad2474269b87a0b1e385f2d7f8b6eb8d1cd75eaf7e91d1acbecd45d7b2bfbbe3216 e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d 84ea7127a48eb607dad023e74f1b0d149f8d9e005909e08774dec63d1ada93015eb86132a3c936edb50fbe923c446cc9 +aaa99fb1c71340d785a18f6f668e898c25cf7a0ac31d13c5b388b7233408493a5a109af6d07065376b96f4903df7aba2b2af671a18772bb0472490d1240cde28967680727dd4acd47e0308920a75da857a6eeedee5b6586d45dff3d8a680599665aa895c89dd7770b824b7dee477ac5e7602d409d3cc553090c970b50811dbab 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead 8487bd63e6dcdf48ee28686fcc7497e9017f165b37740b7aa6672ced076c97028ddaf750ec0a443e6a22e4558fb6cfe2 +1fadfa8254d3a0b82d137cfdd82043d5dc1fef195d5297b09cc5cfb061f59c933451c0dc2a11b4037f34f88dacb803251f8880c4b72585c3c196e6fb23484ca43a191f8e41b9b9a37e2e6fcaab6738c3c62d1c98e1c620bb788b7b51a04f998a510efdba0d3418622fe8ce203b3fcd553b9b4206365a39031797ad11e49745ec 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0 8ec372c25bdb129cac1fae8e8b6e9e269413e831f494a62eeb8c832ddbbf7cdac8444621650ae12868981acfc9613ef0 +9ecb6f5ed3ba666a8536a81ef65012c2cb8b433508798d84708abb06dfb75503886f78384fb8c7a4d2d49ef539d9b8a0b60938c7f07471dda91f258b0d99691b38a8403a2bb3f956bdfd09baba16d9b6877097a9b6213481b47a06e139d23ec7abad5668d21f912fdb70d31bb9adf9b3ce80e308252fa81a51674f88d02db72b f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1 85243c01f4505370e8ca99d610ecd71e2e746d215abe99bd4784742a50271b715caa1c14631a88bfcc86f2d955701916 +e55bfca78d98e68d1b63688db12485578f36c489766f4d0bfaa0088433ff12133aaca455805095f2e655940860958b3ead111d9070778ee3bbf3e47e43d9eba8b8d9b1fdf72f793fcde2bcaa334f3e35fa2cca531ea7cf27fe9ccba741e38ac26129b2d612bf54a34e0ae6c166c0fef07fcd2b9ac253d7e041a500f7be7b8369 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb 9508e5bdf90b78fb9f791daa7cae0fdb1f3e3ce3dca3e8a7fb0ee046ee19b7021c846c2d424a650df02cfe8a84a72bee +02c6b3c83bd34b288d96409162aa4ff114e9d134bf948046eb5ebcc0c7fe9dfceadda83ed69da2fac00c8840f6c702a3fc5e6959d70f7e8af923e99e4937232ae3b841ffefd2e62fab3671a7c94a0281b8ea5bc176add57c5c9b6893fe7f5d48ce7256b96510810c4e046168a3c5be9843b84d5268a50349b3444341aa5490dd 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6 a1ca065abeb12920ce44316beabba6790537e467dc1459b0bae7e5af82e4a203cfeb01604905a0eb84e978862507edfd +94f8bfbb9dd6c9b6193e84c2023a27dea00fd48356909faec2161972439686c146184f80686bc09e1a698af7df9dea3d24d9e9fd6d7348a146339c839282cf8984345dc6a51096d74ad238c35233012ad729f262481ec7cd6488f13a6ebac3f3d23438c7ccb5a66e2bf820e92b71c730bb12fd64ea1770d1f892e5b1e14a9e5c cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd a7e498656ed78e74b659e53ea4f0e0ec52bc4788fd97b504cd0bee0aad6bef15dd699d34938cfd525faf71aeb9cd5599 +663b12ebf44b7ed3872b385477381f4b11adeb0aec9e0e2478776313d536376dc8fd5f3c715bb6ddf32c01ee1d6f8b731785732c0d8441df636d8145577e7b3138e43c32a61bc1242e0e73d62d624cdc924856076bdbbf1ec04ad4420732ef0c53d42479a08235fcfc4db4d869c4eb2828c73928cdc3e3758362d1b770809997 c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b a619e6bfd3bec836bbbb338af4d5d0144d662a963acbb97c918d1baf88b046e21a19dd1f8ebcd8312631b85985c77104 +784d7f4686c01bea32cb6cab8c089fb25c341080d9832e04feac6ea63a341079cbd562a75365c63cf7e63e7e1dddc9e99db75ccee59c5295340c2bba36f457690a8f05c62ab001e3d6b333780117d1456a9c8b27d6c2504db9c1428dad8ba797a4419914fcc636f0f14ede3fba49b023b12a77a2176b0b8ff55a895dcaf8dbce 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9 b774d2fcb0163777cec176a7d9aaaca9581fe61fabbc426024d9f1279b4130f6fa657b778292bcb982443f651d903254 +45e47fccc5bd6801f237cdbeac8f66ebc75f8b71a6da556d2e002352bd85bf269b6bc7c928d7bb1b0422601e4dd80b29d5906f8fcac212fe0eaaf52eda552303259cbcbe532e60abd3d38d786a45e39a2875bce675800a3eaeb9e42983d9fd9031180abd9adccc9ba30c6c198b4202c4dd70f241e969a3c412724b9b595bc28a d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f 97bdc50e7d82da3ba4c837c557d654eb910de403c5aba80cd799da4b3b7a210ac66f42829fe29a0161183f11021ebead +c33ff63b4e6891e00b2349b3f2907c417ca355560544a91e24a7a0ee260d6850aeded29fc0176b6039ca6187e8333391047cceaf14b1077df8f147dad84d36b2dac5666dc2f69dc9b58b88cc73956efdb3b47f91831d5875051c76b0c4e9fc087012a1f03eeee85d6745b46aa50bd9cb0110c2c94508765cec162ee1aa841d73 d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3 a79d714993af2d8c9bc0843edca7dcbc7628f952fd5d3bdb628e7c179752efbb47a5bfab1ae0fba60d18e88d25101afa +f562f2b9d84b0e96a52532c3b43c39c8018c738bd8dc3797a7de7353971b2729d522d6961b1f2e4df3f6a4bd3653e6d72b74fc0dba92ab939c4b542e994e5db6dd8ed4f56f651e699052e791237ae1f552f990ad156226ae8f7bf17fcbfa564f749604f97e9df0879d50985747d981422a23040fe52f5ec74caf1d4aaad8a710 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93 96ba7505250ca7f5e874aba047d5f652f6b2d847403d57df3789aad5bb676839b1a3fc390e8f6099cb882f2032d82846 +ace953ae851f571d71779aa120915f27450b236da23e9106f8d0756abdd25861937941228d225d5fb1aa1b1ebf759b1e326aeb3b6cd0cd87edd2ab9f6a7ad67b63d2c501d6a550edb2e7c9d216cc8af78dd33546af64d00abed4d0d2cfc5c9a7b5a055dbe8f7547902d185cf46937314832bc5c602419a82ab83dbd9d3bd5aff e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1 a8efdc00866f2020dd83d03d6b98d20d9e03b7ce092c3ba4f8b59347b4c369e961721c5350f88a6529ab48c17a7184c4 +9635ab832240be95301bedb94c5aec169eedc198cbbdfedcf41e9b586143d829b4597a6b2a81902828332825fd84a785f187a3894e21bd99d22c4f94dcf34453fc052f15ec64d1447c932cb38fcdd30b7be851963409c11881438cbaad7e96f9efbde317f2235d66af804477a5dfe9f0c51448383830050ecf228889f83631e1 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960 b3a649fb2a1e310f6f9825f769b0a2ff2cee7f5aa6594d7747621856344afd147488db26c9dbb0f0c2ab7f6ffb2cce57 +d98b9a7d4fe9d0fd95de5056af164a8b7882cd34ab5bde83a2abb32dc361eb56a479a3a6119db3b91dcad26a42d2206749567f0d97c34a981a91fc734921821a429f6a53401743a5c406ba9d560f956203abc9d1f32f1a13e7d7b290f75c95fdbf857ea597021461c06a3aacfa554ede3d69e4ff03bbbee5b7463ec77de2b3b2 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57 8ddaaaad33e9a3ea50a321405e97f262483a35e4890f46c6a5d8fcd0fc934351c15b5a724f18016ef9929be62e71df0f +1b4c754ac1c28dc415a71eac816bde68de7e8db66409af835838c5bb2c605111108a3bf13606ed5d8ade5ed72e50503e0de664416393d178ea4eec834d8d6f15039847b410080fd5529b426e5aadd8451c20ebd92d787921f33e147bcbeb327b104d4aab1157fc1df33e4d768404b5ccb7110055c2508c600f429fd0c21b5784 a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1 8e9efea8b98feaa6822bd23923ad0b6c7a86f209b16f3dfb345d9e3ed9910897b2f3c53c2185de52de9d5861edf41637 +3cd8c053741dd9f974c6c5dbf8a1e5728e9b5eafb1cbcfc3452f5fbbda32a8c7564dee157e8d902c52514361da6d972934a56b3276e2a9379e328e24282e0db697c5bc29090fc489ec46b7b188325dd4e96494c250de0f4a89fe2ccf919eaefcfb50c288113e6df92714feb7f46e0822478c796d0f4ff3447a32997e892693ce 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3 b32f4d8d17af8072f4955aba4ed11c56f32b835cdd93ce6912d4e1d75c83f38bc94a4f9ba479ca86d964b045ab5d5dfd +ed955dda6d9650124804d3deb6aeef900e520faf98b1ef6f14efcada7ca2433f09329b70897305e59c89024d76e466b28fe02cb2a9b12e2478c66470259d7c282137a19e5a04ffadea55245c0f34a681593fedc42931d8b3321b3d82e9cc102cd00540ad311ec7bd8c9d06db21bea4ca3dc74d98931ae0d40494aefc2345132c 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907 a3c172070da5b819b7464417cd3d82a42bad9c63f8f3f3c79a68ff74a5082036c638b648e1e562ad293d7a84bcc524fa +ce395b001da2a58e49691605d44af4206306f62f561bf2394060d2a5591a350277166bed043819035f1e60b5b3fb5ae113ddd0473f8ef6b2b050c472c2a264e1d8b3ca82a4f158c40f2d78d9ce5e5ea6de243f2e1f13f47f6c6f403b270912c81c636be35b396ca58468b3fb60aa83911d61441a0528d973bc31f965d4059080 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245 b84b65eb6231be58f64cebd3a0f756039c125fba238b008d915d3fca8a16a18d8e3db4dde15a06a3e82db5dabf690529 +ffefe316455ae4ffdb890bb804bf7d31424ea060ecacff419d0f7134ff76ad434063c0ec0f8bb7059584d3a03f3625bb9e9f66ace1a47ac4b8f3e76fc7c420c55edb1427d1fa15b387ad73d02b0595c4e74321be8822752230a0dcfb85d60bfa186da7623a8ec3eb1633f0a294b23ae87216b14ccee9ef56418dcfab9427371e 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7 984d85c0008fe6f7250ae64bba2ed78e50beb1c4206aa1fea680c678bcc171c0f73c4d4dd833f87fc3bc532e14ffa65c +304bccb718b3a9e12669913490cc5bcc1979287b56c628fad706c354241e88d10e81445a2853e3fc32ece094ba1abc3fdcab61da27f9a0fca739371049fed462ee6b08fa31cde12720f8144a6f00ce9b1a7a6eadd231f126717074b4efb5c72ce673ca5859000a436f67a338d698759f12c461247c45a361fb6cb661fdbe6714 d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5 82d99eb26adf5284dbe6453c57d334119d7eedc4ca7552cab662440fc58c7c53e663472fdfd759cb4af7344145c5630f +64f9f05c2805acf59c047b5f5d2e20c39277b6d6380f70f87b72327a76170b872bfe4b25c451602acfb6a631bb885e2655aee8abe44f69c90fb21ffde03cef2a452c468c6369867dfd8aa26ac24e16aa53b292375a8d8fbf988e302bf00088e4c061aa12c421d8fe3cbd7273b0e8993701df1c59431f436a08b8e15bd123d133 b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224 a5ca691069fa8e4b5b1658e47d798a39e27bd2d1f4a6f55a86c6e58299bd122cc3a58211e9d64949ab1bc91cc1c0b997 +6b45d88037392e1371d9fd1cd174e9c1838d11c3d6133dc17e65fa0c485dcca9f52d41b60161246039e42ec784d49400bffdb51459f5de654091301a09378f93464d52118b48d44b30d781eb1dbed09da11fb4c818dbd442d161aba4b9edc79f05e4b7e401651395b53bd8b5bd3f2aaa6a00877fa9b45cadb8e648550b4c6cbe 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 b21f2e8ae79f96693852a22a2ea257bd3921cbc9c6591236b69a497b06eb6481f3cd7f42e897b56810983d6472a3df80 +d768f41e6e8ec2125d6cf5786d1ba96668ac6566c5cdbbe407f7f2051f3ad6b1acdbfe13edf0d0a86fa110f405406b69085219b5a234ebdb93153241f785d45811b3540d1c37424cc7194424787a51b79679266484c787fb1ded6d1a26b9567d5ea68f04be416caf3be9bd2cafa208fe2a9e234d3ae557c65d3fe6da4cb48da4 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 a7404216f547f0f88ebe709b90d2f171c392cc589419e44647b0f58a26b7abc92997d121bdca08d9e665752e95b7e5a6 +6af6652e92a17b7898e40b6776fabaf0d74cf88d8f0ebfa6088309cbe09fac472eeac2aa8ea96b8c12e993d14c93f8ef4e8b547afe7ae5e4f3973170b35deb3239898918c70c1056332c3f894cd643d2d9b93c2561aac069577bbab45803250a31cd62226cab94d8cba7261dce9fe88c210c212b54329d76a273522c8ba91ddf b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 b41ae07492b04b5aae2a0d0b17fd697bcaead9dc2d49fce77b9d1a331b804b0eefe3ec98200f7088f73e9d763b73ffaa +b96d74b2265dd895d94e25092fb9262dc4f2f7a328a3c0c3da134b2d0a4e2058ca994e3445c5ff4f812738e1b0c0f7a126486942a12e674a21f22d0886d68df2375f41685d694d487a718024933a7c4306f33f1a4267d469c530b0fed4e7dea520a19dd68bf0203cc87cad652260ed43b7b23f6ed140d3085875190191a0381a de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 b21bd64269b09df407612b94968cd0d30996447efee2672ee7997bd4f9c34c3d4135cf684d6ac61fc65e5d9b9a428f29 +7cec7480a037ff40c232c1d2d6e8cd4c080bbeecdaf3886fccc9f129bb6d202c316eca76c8ad4e76079afe622f833a16f4907e817260c1fa68b10c7a151a37eb8c036b057ed4652c353db4b4a34b37c9a2b300fb5f5fcfb8aa8adae13db359160f70a9241546140e550af0073468683377e6771b6508327408c245d78911c2cc 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc a00aa18dcf0369aa51c1d1c036228cd913d4708e12ab07c9a0abae4f6a8bb1f8f848f18137d79193c963657889e209a6 +00ce978603229710345c9ad7c1c2dba3596b196528eea25bd822d43ca8f76a024e29217703dd0652c8a615284fc3edcc1c5ad1c8d5a8521c8e104c016a24e50c2e25066dcb56596f913b872767e3627aa3e55ec812e9fdac7c2f1beade83aef093e24c9c953982adf431a776880ae4583be158e11cdab1cbca3ad3a66900213d 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 88c4adc42d3e83b73474a75b37628947aa84a2495209b82a04dc617a579676d5c7eb5ea90fa208a8a1be8b2bc9afe75e +54a255c18692c6162a46add176a0ae8361dcb8948f092d8d7bac83e160431794d3b9812849bf1994bcdcfba56e8540c8a9ee5b93414548f2a653191b6bb28bda8dc70d45cc1b92a489f58a2d54f85766cb3c90de7dd88e690d8ebc9a79987eee1989df35af5e35522f83d85c48dda89863171c8b0bf4853ae28c2ac45c764416 ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 a379e5e6f6cf4434ac300a33a77f1b6bcdf21e95a008d1fefe6bf00986468e5d3f11a498455cc28e72b957e41fd9552d +692a78f90d4f9d5aee5da536314a78d68c1feabbfe5d1ccea7f6059a66c4b310f8051c411c409ccf6e19a0cbd8b8e100c48317fe8c6d4f8a638b9551ce7ee178020f04f7da3001a0e6855225fb3c9b375e4ed964588a1a41a095f3f476c42d52ffd23ce1702c93b56d4425d3befcf75d0951b6fd5c05b05455bdaf205fe70ca2 adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 a8a6d47a495e3fc59c28897edae5b3a79da294ef70e9801da1cd6b1b90000f2441f7b7a4d6d3c1472d81e895e5623092 +3b309bb912ab2a51681451ed18ad79e95d968abc35423a67036a02af92f575a0c89f1b668afe22c7037ad1199e757a8f06b281c33e9a40bab69c9874e0bb680b905d909b9dc24a9fe89bb3d7f7d47082b25093c59754f8c19d1f81f30334a8cdd50a3cb72f96d4b3c305e60a439a7e93aeb640dd3c8de37d63c60fb469c2d3ed 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d b825339b6d4c334288513021e5fcea802defb31c398aefc07458d877aeca65b60a540eab672437be88825082df32fc23 +f072b72b8783289463da118613c43824d11441dba364c289de03ff5fab3a6f60e85957d8ff211f1cb62fa90216fb727106f692e5ae0844b11b710e5a12c69df3ed895b94e8769ecd15ff433762d6e8e94d8e6a72645b213b0231344e2c968056766c5dd6b5a5df41971858b85e99afbf859400f839b42cd129068efabeea4a26 e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 b6a8c37de5466297745a6b348a76e5fc1af50218f0126e6419cc82b5cf8ce98d1b640482162a1fcc9b122a08cadb17e6 +cf4945350be8133b575c4ad6c9585e0b83ff1ed17989b6cd6c71b41b5264e828b4e115995b1ae77528e7e9002ac1b5669064442645929f9d7dd70927cb93f95edeb73e8624f4bc897ec4c2c7581cb626916f29b2d6e6c2fba8c59a71e30754b459d81b912a12798182bcff4019c7bdfe929cc769bcc2414befe7d2906add4271 d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca b90661020fe317c858abf447a9eb8940686916a1992607e668faf87a6c3f9df494d09fc6672e67f4f7371aa2f051c6d6 +d9b5cf0b50416573ff3c63133275a18394dd4326be2041e8d97e6e4e3855a4a177e9d26dfd223fe8aa74564edb49bd72de19916fb6f001f44530d5c18e2c332bce1b7415df5927ece5f3824f34d174b963136b53aef1fb78fb0c06a201a40b2db38e4d8216fc1e392a798c8ab4b3a314496b7f1087804ebfa89bf96e9cdb80c0 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d 83d43983049fc5040e43e2bf9010dfcce0d6b5e71947d5c80a6c73aee011b61a365af347c9410145ef627662c10d11b9 +9e4042d8438a405475b7dab1cd783eb6ce1d1bffa46ac9dfda622b23ac31057b922eced8e2ed7b3241efeafd7c9ab372bf16230f7134647f2956fb793989d3c885a5ae064e85ed971b64f5f561e7ddb79d49aa6ebe727c671c67879b794554c04de0e05d68264855745ef3c9567bd646d5c5f8728b797c181b6b6a876e167663 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 8e575b0e08cae4749d1a7c679712dfcd8f4e04e87b1f5dcd3b1b0a2a59a3c8d5a92856f38ad9faf66ca58efab341390e +0b14a7484a40b68a3ce1273b8a48b8fdb65ba900d98541c4bbd07b97e31bcc4c85545a03e9deab3c563f47a036ff60d0361684ba241b5aa68bb46f440da22181ee328a011de98eff34ba235ec10612b07bdfa6b3dc4ccc5e82d3a8d057e1862fef3def5a1804696f84699fda2ec4175a54a4d08bcb4f0406fdac4eddadf5e29b ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 a8a31ff728ce3a8839d2f0e654567b2f33ae4d8bfe3c51f482bd1900f005d793bddbb21cece2804b2f2d4ab0386eca02 +0e646c6c3cc0f9fdedef934b7195fe3837836a9f6f263968af95ef84cd035750f3cdb649de745c874a6ef66b3dd83b66068b4335bc0a97184182e3965c722b3b1aee488c3620adb835a8140e199f4fc83a88b02881816b366a09316e25685217f9221157fc05b2d8d2bc855372183da7af3f0a14148a09def37a332f8eb40dc9 e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb ae65c6abafa835df16f325a804128929177a6cfb9dc062eeb5bfc859692023b380c71c970bd86f3f26a92f2bf2158802 +67d9eb88f289454d61def4764d1573db49b875cfb11e139d7eacc4b7a79d3db3bf7208191b2b2078cbbcc974ec0da1ed5e0c10ec37f6181bf81c0f32972a125df64e3b3e1d838ec7da8dfe0b7fcc911e43159a79c73df5fa252b98790be511d8a732fcbf011aacc7d45d8027d50a347703d613ceda09f650c6104c9459537c8f 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c 90ea5dbde468ae151d08712f869a0f25aef2a7d91b7e0167a0c393fd651f4dd693c213d062ff889f21db47754a1427fc +45db86829c363c80160659e3c5c7d7971abb1f6f0d495709bba908d7aa99c9df64b3408a51bd69aba8870e2aaff488ef138f3123cf94391d081f357e21906a4e2f311defe527c55e0231579957c51def507f835cceb466eb2593a509dcbee2f09e0dde6693b2bfe17697c9e86dd672f5797339cbe9ea8a7c6309b061eca7aef5 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f 94684fc3bde90e0c653a65df230d1495fbfbc5bcd1b63ef99e246219d9ab25d4da2cd83e3bf41d5d7125da6a5391e0f4 +4672fce0721d37c5be166bffa4b30d753bcf104b9b414db994b3ed33f36af4935ea59a0bb92db66448b3f57dad4fc67cef10ce141bf82c536be604b89a0bc0e8bca605b867880049d97142d30538fc543bd9d4fab7fdbe2f703815cdb6361beb66acff764bc275f910d1662445b07b92830db69a5994857f53657ed5ca282648 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7 95b58ba245c2a9803bad6c376d8c056629a31c05f07d5e048f4b55e60d030c3dce3cbf908eef1868a6d81e6d5f4bd528 +9ae48fdd9bfc5cb0f4d4761e28b2073bda05a3e3fe82c212e66701dc4573cc67a829b0f82d7520b1bf11db0c6d1743822bbe41bb0adbd7222aa5fae70fbd1a31f2d4453a01c81e064d775388468be96f6063f8673b7b8d4455fe1bd4c801ad5e625a015eaa4a1a18da490d2af8642201eaba3c611cbd65f861d8e19ca82a1ee6 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf b3ec49d8f6da9bc55492abb8721ed1212ff2dbdc6bc225091ae0374605ae183d8c3f37d68cbf30f4d22821cbf7576a5b +817d6a110a8fd0ca7b4d565558f68b59a156744d4c5aac5c6610c95451793de2a756f774558c61d21818d3ebeeeb71d132da1c23a02f4b305eccc5cd46bd21dfc173a8a91098354f10ffbb21bf63d9f4c3feb231c736504549a78fd76d39f3ad35c36178f5c233742d2917d5611d2073124845f1e3615b2ef25199a7a547e882 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b ac70e8f4d4c201a52c917c0e5855e27bce568e6b52262f5bc8114cd41eb1a102f7f79546ad7a8685e9b6f205df807a74 +464f10ec6fb229a51db5fd0e122f2cb8a9a022117e2987f4007bf5565b2c16aba0714e2e3cdd0c100d55ac3017e36fc7501ad8309ab9572aa65424c9eb2e580a119c55777676ec498df53ef6ae78fd8a988130ee0e6082bf1ef71cd4c946021018a8ca7154d13b174c638912613b0bdb9001c302bf7e443ad2124ab2c1cce212 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69 a24c16ab6d35a976f6dc37bff831f0492df1163c5f790b496184bb3adba047bb8bd3b8460581410dcba76611d5aab0f7 +4e3e0fb96320ddccde8b463c273654c4f7164920b1d63430921d2e808dee403e6420eedda0a557b911d00736a4f8798dd4ef26673efd6d190988ad4929ec64f8685cfb76070a36cd6a3a4bf2f54fb08a349d44642b6f614043fef9b2813b63457c76537d23da7b37310334f7ba76edf1999dad86f72aa3446445a65952ac4e50 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db 86d8f6dde1e3e720b87517fb9d93d0a654418f6a2bb76c570d49ff4209c0aad0a857532e00424e3078c0a00d80a4d043 +c466b6b6baf7e6ffa876ec06105e2d43534e0517c07b1c4c9fb67ba81ce09525a7721ec3c290f2b1f65b6463d41598e7a25b2238501629953a5ca955b644354fb6856733a2e5bb8f5bc21a0c803493f5539f9fb83aab3dba2c982989c2270c61ab244b68bfe1b948d00c2ed975e09c29b5f8a7effcad8652a148cc880d503217 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d 99c2ef69c969efe7906337e9c31df94ca1930e2730de5459cb50c64cd8f03341e6e004bfc9fc1a239453ea26792c249b +feac892b7720af80b3c9eede51e923f18d3d0c5de4c31f4aa75e36df7c7c2fd8f41778851a24b69e67dccb65e159dd5c383243bad7cfedcc5e85c8a01c34b0b94ba8e07e4c024c09d279b3731e8b62f9562d3c4f5042567efe42a9d0eaaabab28bc6f11232fc8ceaaf4518d9f3b2bebf020294496b7f6b879e69503f75fecd3d 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476 82eb70503010307d69500f78c3277d8b384cd791cfd69530d3483e64bdaeb4f245117d50fe02c9bb82a2c2e478eadb1d +cf2982e3bf174ce547741b969403cd11e9553067e6af8177d89511a0eb040db924530bdba65d8b1ff714228db0737c1756f509e1506014a10736e65be2f91980a73891496e90ff2714a3601c7565cdcef5a395e2e0e1652f138d90d61eaa9cba993b823245647f6e07cec9b8b4449cd68a29741cd1579c66e548ca0d0acf33aa ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa 8da4136f440e4c5e6db70beb2e5dbf8e594b99847a803e7b9122037a76af50463cf8ee03686972739d957536c2ad9b5b +bf9fdd4107ef5a6070108771ac9eee4f0c8043bf0d04db772a47294f4137e2439d94b337114b074e57e0cb78d0ccf352a2833e9788ee2a1a9ffeacd34f38fcefb86653d70c7dadd4cf6548d608e70acdef6c7530974b92c813798add659752a8c72b05e1ad9c65c21834ce6fbe49d8a1426b5a54270794436d284364fac6ec1a 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f a00517aa8196efdf6f70c2bfb12f7f6122968eedbb45cae6e5eea92b2e46cd942df6170ebe09c4a47bb37505d15949c8 +5d634fb39a2239256107dc68db19751540b4badac9ecf2fce644724401d6d632b3ae3b2e6d05746b77ddc0c899878032248c263eda08d3d004d35952ad7a9cfe19343d14b37f9f632245e7b7b5fae3cb31c5231f82b9f1884f2de7578fbf156c430257031ba97bc6579843bc7f59fcb9a6449a4cd942dffa6adb929cf219f0ad e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1 b32e65603c6c1c2697e3c3257503f80e254317e7068ee5bed2f5659f38eb59343dfd6df977cdd7783df91a78cac0b348 +c9b4ff721b3e886f0dc05856ffff0aabb64a8504b1746a47fdd73e6b7ebc068f06ac7ffa44c757e4de207fc3cbfaf0469d3ac6795d40630bcafe8c658627e4bc6b86fd6a2135afbc18ccc8e6d0e1e86016930ca92edc5aa3fbe2c57de136d0ea5f41642b6a5d0ddeb380f2454d76a16639d663687f2a2e29fb9304243900d26d 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c 8645e69e79d064ca8bb36b840111c0626fde946447dfe864c8acd480bbbf0ce5d3fe9cc97722450dd502c39b51d735e5 +db2ad659cf21bc9c1f7e6469c5f262b73261d49f7b1755fc137636e8ce0202f929dca4466c422284c10be8f351f36333ebc04b1888cba217c0fec872b2dfc3aa0d544e5e06a9518a8cfe3df5b20fbcb14a9bf218e3bf6a8e024530a17bab50906be34d9f9bba69af0b11d8ed426b9ec75c3bd1f2e5b8756e4a72ff846bc9e498 e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c 8bccb7aeb83d1b905a37534c8582150d28e8b124b7a8d8607addb9a45fb85f629bccc91fc05e2702bf66d2282ad0745a +dbd8ddc02771a5ff7359d5216536b2e524a2d0b6ff180fa29a41a8847b6f45f1b1d52344d32aea62a23ea3d8584deaaea38ee92d1314fdb4fbbecdad27ac810f02de0452332939f644aa9fe526d313cea81b9c3f6a8dbbeafc899d0cdaeb1dca05160a8a039662c4c845a3dbb07be2bc8c9150e344103e404411668c48aa7792 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855 a5c11619d7302eaa85e8b5c5c63c52c479c95a3fb19068fd3988fd997b1133cd6ab05e1876a72eb15a40778184ec2974 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P384_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P384_blst new file mode 100644 index 000000000000..68fc781950b8 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P384_blst @@ -0,0 +1,60 @@ +39f0b25d4c15b09a0692b22fbacbb5f8aee184cb75887e2ebe0cd3be5d3815d29f9b587e10b3168c939054a89df11068e5c3fac21af742bf4c3e9512f5569674e7ad8b39042bcd73e4b7ce3e64fbea1c434ed01ad4ad8b5b569f6a0b9a1144f94097925672e59ba97bc4d33be2fa21b46c3dadbfb3a1f89afa199d4b44189938 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727 96361a512233d2864948ea0038c967182eeddd8f49ce0781e52e718d4840fb6537478a15d4f7c283b173ab865b3d36ed +5a3c80e608ed3ac75a6e45f6e94d374271a6d42b67a481860d5d309cc8b37c79cb61f1716dc8aa84cb309ef9d68eb7fc6cf4b42333f316a5c30e74198c8b340926e340c5de47674a707293c4aa2a1a2274a602f01c26b156e895499c60b38ef53fc2032e7485c168d73700d6fa14232596a0e4997854a0b05d02e351b9d3de96 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246 b16043960da793528a739efef61ec3be08d53f6bb6d8837a14c6bcabe9f98c5093a6a050eb020ce6390c04b843e1d481 +e7d974c5dbd3bfb8a2fb92fdd782f997d04be79e9713944ce13c5eb6f75dfdec811b7ee4b3859114b07f263846ae13f795eec8f3cb5b7565baff68e0fdd5e09ba8b176d5a71cb03fbc5546e6937fba560acb4db24bd42de1851432b96e8ca4078313cb849bce29c9d805258601d67cd0259e255f3048682e8fdbdda3398c3e31 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83 ad6195531b6906670b73cd4af8e630885f9b604bcd49bdfd388873112b1133cc8da87801764bb2fac00eada311b6976c +a670fda4d1d56c70de1d8680328043b2b7029633caf0ee59ffe1421c914bb937133d5a0f9214846b2e0b350455a74c4ab434c56de65a17139bb8212bf1c76071a37536fa29348f871dbb26baa92eb93d97e923a6d2ffd9be25cbc33075e494e6db657bd8dc053fe4e17148d8cf6e2058164f2b5766750eb01bbe7b361cdb848c dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659 847c400eb6d4ca003543078b92e4572f879aba6b06079db6144689df9e6ea0097de9c1ec0547069f9d4b7be75c0ba542 +7843f918fe2588bcfe756e1f05b491d913523255aa006818be20b676c957f4edb8df863c6f5f8c15b3b80c7a2aa277b70d53f210bdfb856337980c406ea140e439dd321471407f374f69877b2d82367eed51e3c82c13948616dcb301d0c31f8f0352f2846abd9e72071f446a2f1bd3339a09ae41b84e150fd18f4ba5d3c6bfa0 df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718 a6978d1e1cfb5369aa91d985c3c19ea3abbacc66346988348eaf3d9d8000b11a46591135a053458f783b3f5dd2a6cdb6 +caa83d5ab07febbd2e0fe2d63738b9b7b8752594bea7aaf50345b3d2f316653a8c9222f2b7877b64679e9573e81461a426029e45b8873a575094a1d572e0d32a9f0a9c6bcb9a2868543b7d8bbe4a69a09e7321f05f8366cced1b72df526f895b60aed2c39c249653c7839538770d4e5f47d3926ec0d168ab6a1af15bf1dca1f7 ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f 938aff34a3661363f85f4ac331e8566e01cd67c187bb15eaeaa91fbf684f4852a1f93feb9b710cd619fe4162edf5210a +594603458d6534974aeeafba919c4d0f4cb6843a3af41204bbb88aeb2fca2772d305163dba863da050aabedbaf89db521955d1715de95bbcef979ecdc0c976181ece00355385f8a8f8cce127c9eac15ce3e958a3ed686184674ec9a50eb63271606ee7fdcb1323da3c3db8e89cad1fb42139a32d08abcfbf0d4ccfca18c89a86 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829 8a1885ffc9727ddc87e1ce8bad7a10eb8d888d79192ac0833562079002096ba711fdf705484c362a9ec4eccfe9801136 +733252d2bd35547838be22656cc7aa67eff0af0b13b428f77267a513c6824c3dbae533068b6817e82665f009560affcfe4b2ddb5b667a644fc1a42d24f24e0947e0dc50fb62c919bc1fe4e7ded5e28f2e6d80fcf66a081fb2763526f8def5a81a4ddd38be0b59ee839da1643eeeaee7b1927cec12cf3da67c02bc5465151e346 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1 822f3021299113497c606bf8c457d5e6f994e40500b815f6af985ce64c0ad11cd49fb77c9c34abdd039b0f0225f159ad +5a182bd174feb038dfae3346267156bf663167f713dea1ce936b0edb815cd9b8c8e4d411c786ba2494a81442617255db7158b142e720d86c9b56680fb9efd4298cdd69079a28153494c42a24251c7ad42ecf7e97eabc1b3997529b2a297cbad2474269b87a0b1e385f2d7f8b6eb8d1cd75eaf7e91d1acbecd45d7b2bfbbe3216 e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d 948a989cab56c01c55fa12f9aa5bbe21f0b63041851d4034b4057f7a378b2aec6afdae8553bfc0dfcd5d8b8b66718e36 +aaa99fb1c71340d785a18f6f668e898c25cf7a0ac31d13c5b388b7233408493a5a109af6d07065376b96f4903df7aba2b2af671a18772bb0472490d1240cde28967680727dd4acd47e0308920a75da857a6eeedee5b6586d45dff3d8a680599665aa895c89dd7770b824b7dee477ac5e7602d409d3cc553090c970b50811dbab 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead 8999ce6b8d6ae7d8be8332b58d239bb277094fa1bd37f5f4c49c37c1432f0fc3b40b4f1b3b1b355d00eda3b3bfa5b348 +1fadfa8254d3a0b82d137cfdd82043d5dc1fef195d5297b09cc5cfb061f59c933451c0dc2a11b4037f34f88dacb803251f8880c4b72585c3c196e6fb23484ca43a191f8e41b9b9a37e2e6fcaab6738c3c62d1c98e1c620bb788b7b51a04f998a510efdba0d3418622fe8ce203b3fcd553b9b4206365a39031797ad11e49745ec 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0 8de1ed09e0c913b5e7177ae08a5412afcd595976047e928bad3dab21e9b51f1c8fdcaaac332daeff5aa663003cccb497 +9ecb6f5ed3ba666a8536a81ef65012c2cb8b433508798d84708abb06dfb75503886f78384fb8c7a4d2d49ef539d9b8a0b60938c7f07471dda91f258b0d99691b38a8403a2bb3f956bdfd09baba16d9b6877097a9b6213481b47a06e139d23ec7abad5668d21f912fdb70d31bb9adf9b3ce80e308252fa81a51674f88d02db72b f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1 826557ed736d7401e5256ee4b34551987cf8d32c89f14e918ff9e7893541dd79845c24b97b68ee736ac4ef86acb13f5c +e55bfca78d98e68d1b63688db12485578f36c489766f4d0bfaa0088433ff12133aaca455805095f2e655940860958b3ead111d9070778ee3bbf3e47e43d9eba8b8d9b1fdf72f793fcde2bcaa334f3e35fa2cca531ea7cf27fe9ccba741e38ac26129b2d612bf54a34e0ae6c166c0fef07fcd2b9ac253d7e041a500f7be7b8369 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb ab6773b002a427dfa906ab7edbfcb05c382ab8ce571a38638897bf0f1192b10a19a2fa6c8e6347e3908c6aca5e1512ad +02c6b3c83bd34b288d96409162aa4ff114e9d134bf948046eb5ebcc0c7fe9dfceadda83ed69da2fac00c8840f6c702a3fc5e6959d70f7e8af923e99e4937232ae3b841ffefd2e62fab3671a7c94a0281b8ea5bc176add57c5c9b6893fe7f5d48ce7256b96510810c4e046168a3c5be9843b84d5268a50349b3444341aa5490dd 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6 abcf40b6ab1ff0e83beda796c78b51f9ac04f25e4f13b36b759f52f8a50254948cdcf6c685e747dd29a705eb5c830023 +94f8bfbb9dd6c9b6193e84c2023a27dea00fd48356909faec2161972439686c146184f80686bc09e1a698af7df9dea3d24d9e9fd6d7348a146339c839282cf8984345dc6a51096d74ad238c35233012ad729f262481ec7cd6488f13a6ebac3f3d23438c7ccb5a66e2bf820e92b71c730bb12fd64ea1770d1f892e5b1e14a9e5c cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd 8849dc325d49582916e70be63bfea6efce7ef26e2522c20257085be41ad823c7840dbfe47570c35dee1e9c74abefcf7c +663b12ebf44b7ed3872b385477381f4b11adeb0aec9e0e2478776313d536376dc8fd5f3c715bb6ddf32c01ee1d6f8b731785732c0d8441df636d8145577e7b3138e43c32a61bc1242e0e73d62d624cdc924856076bdbbf1ec04ad4420732ef0c53d42479a08235fcfc4db4d869c4eb2828c73928cdc3e3758362d1b770809997 c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b 920f05ec280d9a84fcf1e7c7466b2b70d8f702590e7009d6c0f5db12ff2645f49d48823e62cd25dc193bdd5e088a5f3c +784d7f4686c01bea32cb6cab8c089fb25c341080d9832e04feac6ea63a341079cbd562a75365c63cf7e63e7e1dddc9e99db75ccee59c5295340c2bba36f457690a8f05c62ab001e3d6b333780117d1456a9c8b27d6c2504db9c1428dad8ba797a4419914fcc636f0f14ede3fba49b023b12a77a2176b0b8ff55a895dcaf8dbce 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9 8193d3d22fe40ab29f7d76fb60a09266d7ca56ccfe869e055330881ae25cc9c9cc578c86ceb59589c490af6d752fedb0 +45e47fccc5bd6801f237cdbeac8f66ebc75f8b71a6da556d2e002352bd85bf269b6bc7c928d7bb1b0422601e4dd80b29d5906f8fcac212fe0eaaf52eda552303259cbcbe532e60abd3d38d786a45e39a2875bce675800a3eaeb9e42983d9fd9031180abd9adccc9ba30c6c198b4202c4dd70f241e969a3c412724b9b595bc28a d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f 816ea60944a3d6a2a73246ffa421d3b2ff6c2e88f5765549ac9abd4f9ef49dd98880407c65c325086b91834880ab0603 +c33ff63b4e6891e00b2349b3f2907c417ca355560544a91e24a7a0ee260d6850aeded29fc0176b6039ca6187e8333391047cceaf14b1077df8f147dad84d36b2dac5666dc2f69dc9b58b88cc73956efdb3b47f91831d5875051c76b0c4e9fc087012a1f03eeee85d6745b46aa50bd9cb0110c2c94508765cec162ee1aa841d73 d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3 b67db014ef4059b275417b133f16cca9cfe5dcae10b75b12266639c1afc5b6e63bfa14b1ea4cf061beae4bfea1301146 +f562f2b9d84b0e96a52532c3b43c39c8018c738bd8dc3797a7de7353971b2729d522d6961b1f2e4df3f6a4bd3653e6d72b74fc0dba92ab939c4b542e994e5db6dd8ed4f56f651e699052e791237ae1f552f990ad156226ae8f7bf17fcbfa564f749604f97e9df0879d50985747d981422a23040fe52f5ec74caf1d4aaad8a710 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93 8a4d538581f3f317d0bf82aa466b930032ae49d6723b3ea838efce9db9bbde83b723430698029f0a481d470903a80555 +ace953ae851f571d71779aa120915f27450b236da23e9106f8d0756abdd25861937941228d225d5fb1aa1b1ebf759b1e326aeb3b6cd0cd87edd2ab9f6a7ad67b63d2c501d6a550edb2e7c9d216cc8af78dd33546af64d00abed4d0d2cfc5c9a7b5a055dbe8f7547902d185cf46937314832bc5c602419a82ab83dbd9d3bd5aff e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1 b51fc1badf1d5a0313fbc4409d13630c4d0597c1aead2bb3aa538ae84c95d0eea2453d37d4071ee34fd887d0f1f2cc90 +9635ab832240be95301bedb94c5aec169eedc198cbbdfedcf41e9b586143d829b4597a6b2a81902828332825fd84a785f187a3894e21bd99d22c4f94dcf34453fc052f15ec64d1447c932cb38fcdd30b7be851963409c11881438cbaad7e96f9efbde317f2235d66af804477a5dfe9f0c51448383830050ecf228889f83631e1 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960 b6be26061fd8386a7071744669afbfe0fe7fd6c94d965a8774e009315f31c224a684fec7862047e477af1796614d4b0f +d98b9a7d4fe9d0fd95de5056af164a8b7882cd34ab5bde83a2abb32dc361eb56a479a3a6119db3b91dcad26a42d2206749567f0d97c34a981a91fc734921821a429f6a53401743a5c406ba9d560f956203abc9d1f32f1a13e7d7b290f75c95fdbf857ea597021461c06a3aacfa554ede3d69e4ff03bbbee5b7463ec77de2b3b2 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57 b80dd86473133faf2e4535f875a62fc901bab43d597a6a7e543bd3a4b6f971591657449c09e52f94171fffc7fa372ea0 +1b4c754ac1c28dc415a71eac816bde68de7e8db66409af835838c5bb2c605111108a3bf13606ed5d8ade5ed72e50503e0de664416393d178ea4eec834d8d6f15039847b410080fd5529b426e5aadd8451c20ebd92d787921f33e147bcbeb327b104d4aab1157fc1df33e4d768404b5ccb7110055c2508c600f429fd0c21b5784 a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1 b8f72c5cbb5d1aca6bae47d900faa0f708a3323ec5a44181d5ebb16dc09520daacf94aec95b0d48f14c4998057096c9d +3cd8c053741dd9f974c6c5dbf8a1e5728e9b5eafb1cbcfc3452f5fbbda32a8c7564dee157e8d902c52514361da6d972934a56b3276e2a9379e328e24282e0db697c5bc29090fc489ec46b7b188325dd4e96494c250de0f4a89fe2ccf919eaefcfb50c288113e6df92714feb7f46e0822478c796d0f4ff3447a32997e892693ce 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3 81650b8e132e79d5baa3c366ae4dcb12ea1ce49970378e5fdcda8ce5d6cb272f9893b00d3b8fb2df15f882f68354969f +ed955dda6d9650124804d3deb6aeef900e520faf98b1ef6f14efcada7ca2433f09329b70897305e59c89024d76e466b28fe02cb2a9b12e2478c66470259d7c282137a19e5a04ffadea55245c0f34a681593fedc42931d8b3321b3d82e9cc102cd00540ad311ec7bd8c9d06db21bea4ca3dc74d98931ae0d40494aefc2345132c 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907 96d430ae07e4a297bf24ba5b5b4b9835d1e4a13c89915dd629500af56c2f400bb87e6b2db66e9f26c9cd5f163f9f4dea +ce395b001da2a58e49691605d44af4206306f62f561bf2394060d2a5591a350277166bed043819035f1e60b5b3fb5ae113ddd0473f8ef6b2b050c472c2a264e1d8b3ca82a4f158c40f2d78d9ce5e5ea6de243f2e1f13f47f6c6f403b270912c81c636be35b396ca58468b3fb60aa83911d61441a0528d973bc31f965d4059080 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245 a5171bf76460c819ae312ac0107d8cf805a3e49d5681300b0afea16a9630d49ae701c068ac39cd2717a22682cb4ff8da +ffefe316455ae4ffdb890bb804bf7d31424ea060ecacff419d0f7134ff76ad434063c0ec0f8bb7059584d3a03f3625bb9e9f66ace1a47ac4b8f3e76fc7c420c55edb1427d1fa15b387ad73d02b0595c4e74321be8822752230a0dcfb85d60bfa186da7623a8ec3eb1633f0a294b23ae87216b14ccee9ef56418dcfab9427371e 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7 96b5a991512f9724f15225300d451747764d72748fb43d6d47568c691b7273b5a41fa4456cfd339151a7993f84f329a7 +304bccb718b3a9e12669913490cc5bcc1979287b56c628fad706c354241e88d10e81445a2853e3fc32ece094ba1abc3fdcab61da27f9a0fca739371049fed462ee6b08fa31cde12720f8144a6f00ce9b1a7a6eadd231f126717074b4efb5c72ce673ca5859000a436f67a338d698759f12c461247c45a361fb6cb661fdbe6714 d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5 8f8155ccd3b4d0b1ac76545cf392c4bf93a5f0d552218c95c11cacc0c25fc75a584d0392bc14dfa0aabbc57e51fde92b +64f9f05c2805acf59c047b5f5d2e20c39277b6d6380f70f87b72327a76170b872bfe4b25c451602acfb6a631bb885e2655aee8abe44f69c90fb21ffde03cef2a452c468c6369867dfd8aa26ac24e16aa53b292375a8d8fbf988e302bf00088e4c061aa12c421d8fe3cbd7273b0e8993701df1c59431f436a08b8e15bd123d133 b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224 a14c39100717b7de9610eddf4f4b701c8396cda86cf82c44f0d21d25ded2f772b7d786303315f41fad8364ef44d7a322 +6b45d88037392e1371d9fd1cd174e9c1838d11c3d6133dc17e65fa0c485dcca9f52d41b60161246039e42ec784d49400bffdb51459f5de654091301a09378f93464d52118b48d44b30d781eb1dbed09da11fb4c818dbd442d161aba4b9edc79f05e4b7e401651395b53bd8b5bd3f2aaa6a00877fa9b45cadb8e648550b4c6cbe 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 ad8e2428d026d34b5e3edc2f0bfd307f3b6defab1ab7e7e7704f405c06936a186b8c7c4e1fdb193ab1a0bb57f0f10d01 +d768f41e6e8ec2125d6cf5786d1ba96668ac6566c5cdbbe407f7f2051f3ad6b1acdbfe13edf0d0a86fa110f405406b69085219b5a234ebdb93153241f785d45811b3540d1c37424cc7194424787a51b79679266484c787fb1ded6d1a26b9567d5ea68f04be416caf3be9bd2cafa208fe2a9e234d3ae557c65d3fe6da4cb48da4 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 b81b3d5dea530f9c1cb4fa01587b58296416994ccbe602ca065c68d914855b95192c85b519e042c6756022d9d5b51a02 +6af6652e92a17b7898e40b6776fabaf0d74cf88d8f0ebfa6088309cbe09fac472eeac2aa8ea96b8c12e993d14c93f8ef4e8b547afe7ae5e4f3973170b35deb3239898918c70c1056332c3f894cd643d2d9b93c2561aac069577bbab45803250a31cd62226cab94d8cba7261dce9fe88c210c212b54329d76a273522c8ba91ddf b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 8f95d1d91a14f04b328ba8c11a220b5396cf93961223781703909f76b19ff762b003ebab888bffda519d94cf3c8a1865 +b96d74b2265dd895d94e25092fb9262dc4f2f7a328a3c0c3da134b2d0a4e2058ca994e3445c5ff4f812738e1b0c0f7a126486942a12e674a21f22d0886d68df2375f41685d694d487a718024933a7c4306f33f1a4267d469c530b0fed4e7dea520a19dd68bf0203cc87cad652260ed43b7b23f6ed140d3085875190191a0381a de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 96d9f9855e09f7f728572407b00e3d1c4501deb58e7c78aedbc9b14def9da503956842c7b7dd2d6828e6fb782deccb0b +7cec7480a037ff40c232c1d2d6e8cd4c080bbeecdaf3886fccc9f129bb6d202c316eca76c8ad4e76079afe622f833a16f4907e817260c1fa68b10c7a151a37eb8c036b057ed4652c353db4b4a34b37c9a2b300fb5f5fcfb8aa8adae13db359160f70a9241546140e550af0073468683377e6771b6508327408c245d78911c2cc 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc 84d33f8d8beec516e1c3b255e2a957f4ec1ffb2e1b2987ae211f619b37d10abe10529355cfec9500cc54654ae296a604 +00ce978603229710345c9ad7c1c2dba3596b196528eea25bd822d43ca8f76a024e29217703dd0652c8a615284fc3edcc1c5ad1c8d5a8521c8e104c016a24e50c2e25066dcb56596f913b872767e3627aa3e55ec812e9fdac7c2f1beade83aef093e24c9c953982adf431a776880ae4583be158e11cdab1cbca3ad3a66900213d 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 a02dc307578570d3d365b8a4cb244683dbfb778da401690efa1db628837398e5ce206dfb7e3bcbc830672cf5a30b00b9 +54a255c18692c6162a46add176a0ae8361dcb8948f092d8d7bac83e160431794d3b9812849bf1994bcdcfba56e8540c8a9ee5b93414548f2a653191b6bb28bda8dc70d45cc1b92a489f58a2d54f85766cb3c90de7dd88e690d8ebc9a79987eee1989df35af5e35522f83d85c48dda89863171c8b0bf4853ae28c2ac45c764416 ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 b6d20e963d33dd4d924c9b52f846d8ad4889a95cfea6587500a09a44cac6c65c4629e68799e1d6494f720af9dad26e50 +692a78f90d4f9d5aee5da536314a78d68c1feabbfe5d1ccea7f6059a66c4b310f8051c411c409ccf6e19a0cbd8b8e100c48317fe8c6d4f8a638b9551ce7ee178020f04f7da3001a0e6855225fb3c9b375e4ed964588a1a41a095f3f476c42d52ffd23ce1702c93b56d4425d3befcf75d0951b6fd5c05b05455bdaf205fe70ca2 adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 863e1a9a54972bee8d0981f0293a414014eb96a83347428e3cd8f93c8bbe5bb30c3e85cfa6d6644fcf56c4fa00590efa +3b309bb912ab2a51681451ed18ad79e95d968abc35423a67036a02af92f575a0c89f1b668afe22c7037ad1199e757a8f06b281c33e9a40bab69c9874e0bb680b905d909b9dc24a9fe89bb3d7f7d47082b25093c59754f8c19d1f81f30334a8cdd50a3cb72f96d4b3c305e60a439a7e93aeb640dd3c8de37d63c60fb469c2d3ed 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d 817f846b1eb40cf45275ba45394065df67ce122a54d5215a5bcd868b179cb90cf183961f0fca5acdc152a82401e70c55 +f072b72b8783289463da118613c43824d11441dba364c289de03ff5fab3a6f60e85957d8ff211f1cb62fa90216fb727106f692e5ae0844b11b710e5a12c69df3ed895b94e8769ecd15ff433762d6e8e94d8e6a72645b213b0231344e2c968056766c5dd6b5a5df41971858b85e99afbf859400f839b42cd129068efabeea4a26 e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 b365590cec98839fdadbe3034db6ee8f71ba4d7f53ef4c600fd602300b109f1e87a9dd01ca45c253fd481db28f4da63d +cf4945350be8133b575c4ad6c9585e0b83ff1ed17989b6cd6c71b41b5264e828b4e115995b1ae77528e7e9002ac1b5669064442645929f9d7dd70927cb93f95edeb73e8624f4bc897ec4c2c7581cb626916f29b2d6e6c2fba8c59a71e30754b459d81b912a12798182bcff4019c7bdfe929cc769bcc2414befe7d2906add4271 d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca a202bca272f55ecc438b0c5f764c7c13339ef6b193eb96743ee875c51095537d8452a5064c889467a4501f5bef84e691 +d9b5cf0b50416573ff3c63133275a18394dd4326be2041e8d97e6e4e3855a4a177e9d26dfd223fe8aa74564edb49bd72de19916fb6f001f44530d5c18e2c332bce1b7415df5927ece5f3824f34d174b963136b53aef1fb78fb0c06a201a40b2db38e4d8216fc1e392a798c8ab4b3a314496b7f1087804ebfa89bf96e9cdb80c0 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d 94be35e225bf04137f637d40ade67935181bc24ebd6cecc2828d0de3415177a075ec6c7c8d586d3caa26d47ab8ee82c4 +9e4042d8438a405475b7dab1cd783eb6ce1d1bffa46ac9dfda622b23ac31057b922eced8e2ed7b3241efeafd7c9ab372bf16230f7134647f2956fb793989d3c885a5ae064e85ed971b64f5f561e7ddb79d49aa6ebe727c671c67879b794554c04de0e05d68264855745ef3c9567bd646d5c5f8728b797c181b6b6a876e167663 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 8899e44a3880834c1d56cff25fa039616fecd355bb3c155b4ccfa4798852359a31a2902d52c11183e72e71055837b67b +0b14a7484a40b68a3ce1273b8a48b8fdb65ba900d98541c4bbd07b97e31bcc4c85545a03e9deab3c563f47a036ff60d0361684ba241b5aa68bb46f440da22181ee328a011de98eff34ba235ec10612b07bdfa6b3dc4ccc5e82d3a8d057e1862fef3def5a1804696f84699fda2ec4175a54a4d08bcb4f0406fdac4eddadf5e29b ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 b861d89c7942013d303172bf38d35c41caa15d4709724a3dafc28b648246207d7f07683cd6523b18a0fbb0bffffb4c5b +0e646c6c3cc0f9fdedef934b7195fe3837836a9f6f263968af95ef84cd035750f3cdb649de745c874a6ef66b3dd83b66068b4335bc0a97184182e3965c722b3b1aee488c3620adb835a8140e199f4fc83a88b02881816b366a09316e25685217f9221157fc05b2d8d2bc855372183da7af3f0a14148a09def37a332f8eb40dc9 e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb b783a14364b7f8f621e93dec4d120b381e934d7762ef53c444ccecfce8ed60e453c3ffb167aa68459c0ec3184d21eecf +67d9eb88f289454d61def4764d1573db49b875cfb11e139d7eacc4b7a79d3db3bf7208191b2b2078cbbcc974ec0da1ed5e0c10ec37f6181bf81c0f32972a125df64e3b3e1d838ec7da8dfe0b7fcc911e43159a79c73df5fa252b98790be511d8a732fcbf011aacc7d45d8027d50a347703d613ceda09f650c6104c9459537c8f 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c 8659b553b57728581cb01c3c2fb78259e59d33e36131bcf6ba62de907ac9986fb40545213d2fb1d49d9662f93c0bf027 +45db86829c363c80160659e3c5c7d7971abb1f6f0d495709bba908d7aa99c9df64b3408a51bd69aba8870e2aaff488ef138f3123cf94391d081f357e21906a4e2f311defe527c55e0231579957c51def507f835cceb466eb2593a509dcbee2f09e0dde6693b2bfe17697c9e86dd672f5797339cbe9ea8a7c6309b061eca7aef5 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f a45b322ae6344088907b1e58d8ccd102b1d532712010c533878460f93beeb0d28d76be11e5a326ec986db73ed72be05f +4672fce0721d37c5be166bffa4b30d753bcf104b9b414db994b3ed33f36af4935ea59a0bb92db66448b3f57dad4fc67cef10ce141bf82c536be604b89a0bc0e8bca605b867880049d97142d30538fc543bd9d4fab7fdbe2f703815cdb6361beb66acff764bc275f910d1662445b07b92830db69a5994857f53657ed5ca282648 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7 ae88bde5051ab4033f7d7d581360e3f2feaf60f4dcb975c24aa0ff5ed0e561fa6bec1d1fc27fd8b4cef0c26633de46da +9ae48fdd9bfc5cb0f4d4761e28b2073bda05a3e3fe82c212e66701dc4573cc67a829b0f82d7520b1bf11db0c6d1743822bbe41bb0adbd7222aa5fae70fbd1a31f2d4453a01c81e064d775388468be96f6063f8673b7b8d4455fe1bd4c801ad5e625a015eaa4a1a18da490d2af8642201eaba3c611cbd65f861d8e19ca82a1ee6 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf b6413d254afebced50dbf4b7ed3f8e84d92713060f7e3c380237e2f0ce3da7f7ca29816b3e1ba4890dd88009fa374603 +817d6a110a8fd0ca7b4d565558f68b59a156744d4c5aac5c6610c95451793de2a756f774558c61d21818d3ebeeeb71d132da1c23a02f4b305eccc5cd46bd21dfc173a8a91098354f10ffbb21bf63d9f4c3feb231c736504549a78fd76d39f3ad35c36178f5c233742d2917d5611d2073124845f1e3615b2ef25199a7a547e882 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b 853e1248173263b61ec79b956e86c3b36f4632e588b82cef70dc6d0d7fdb4c3b0cd93418ebf55aa1a86d12dd23e5a4e3 +464f10ec6fb229a51db5fd0e122f2cb8a9a022117e2987f4007bf5565b2c16aba0714e2e3cdd0c100d55ac3017e36fc7501ad8309ab9572aa65424c9eb2e580a119c55777676ec498df53ef6ae78fd8a988130ee0e6082bf1ef71cd4c946021018a8ca7154d13b174c638912613b0bdb9001c302bf7e443ad2124ab2c1cce212 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69 a00a8af05f1c5bfed06185819d138dc47081d060da11f52146d18e2a74e9ce8f10a8213175c76536c966971ba93bc49e +4e3e0fb96320ddccde8b463c273654c4f7164920b1d63430921d2e808dee403e6420eedda0a557b911d00736a4f8798dd4ef26673efd6d190988ad4929ec64f8685cfb76070a36cd6a3a4bf2f54fb08a349d44642b6f614043fef9b2813b63457c76537d23da7b37310334f7ba76edf1999dad86f72aa3446445a65952ac4e50 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db 93ef400838a0553db9a45a80f6e2de08c21b298963874ed5216e49ebc9ff989d6cb9f1c7d7a065581138e4d2082e34fe +c466b6b6baf7e6ffa876ec06105e2d43534e0517c07b1c4c9fb67ba81ce09525a7721ec3c290f2b1f65b6463d41598e7a25b2238501629953a5ca955b644354fb6856733a2e5bb8f5bc21a0c803493f5539f9fb83aab3dba2c982989c2270c61ab244b68bfe1b948d00c2ed975e09c29b5f8a7effcad8652a148cc880d503217 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d 862637228a055543678043922be4999fc0dba6a9ad548884acd5e78e9a9e48edab43e081a8da260ff8c87764bbe996a1 +feac892b7720af80b3c9eede51e923f18d3d0c5de4c31f4aa75e36df7c7c2fd8f41778851a24b69e67dccb65e159dd5c383243bad7cfedcc5e85c8a01c34b0b94ba8e07e4c024c09d279b3731e8b62f9562d3c4f5042567efe42a9d0eaaabab28bc6f11232fc8ceaaf4518d9f3b2bebf020294496b7f6b879e69503f75fecd3d 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476 aef998738f7e3da90498cc893c0bd0ae89573a43227e46438401d73ad6ed511e488638c3bc6fac862c99ca350bb0c045 +cf2982e3bf174ce547741b969403cd11e9553067e6af8177d89511a0eb040db924530bdba65d8b1ff714228db0737c1756f509e1506014a10736e65be2f91980a73891496e90ff2714a3601c7565cdcef5a395e2e0e1652f138d90d61eaa9cba993b823245647f6e07cec9b8b4449cd68a29741cd1579c66e548ca0d0acf33aa ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa 8f2ffeae90fe77426d26603cd9acc86348ba278f81ce0534a203b9c564f5111b954d56d792e539bdf97b1fe27c44dce9 +bf9fdd4107ef5a6070108771ac9eee4f0c8043bf0d04db772a47294f4137e2439d94b337114b074e57e0cb78d0ccf352a2833e9788ee2a1a9ffeacd34f38fcefb86653d70c7dadd4cf6548d608e70acdef6c7530974b92c813798add659752a8c72b05e1ad9c65c21834ce6fbe49d8a1426b5a54270794436d284364fac6ec1a 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f 8076c5bf58d00479b4b955f63e9db1287aa73a9793b5cb87143feb9dd8815f2ce48d443eaf5b0936e13b2df476847746 +5d634fb39a2239256107dc68db19751540b4badac9ecf2fce644724401d6d632b3ae3b2e6d05746b77ddc0c899878032248c263eda08d3d004d35952ad7a9cfe19343d14b37f9f632245e7b7b5fae3cb31c5231f82b9f1884f2de7578fbf156c430257031ba97bc6579843bc7f59fcb9a6449a4cd942dffa6adb929cf219f0ad e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1 847dee867c2300474f344782dd0250b9fccf079292e95f98f246cc84979674cb3379ad51ca09f976b04042def3d1382e +c9b4ff721b3e886f0dc05856ffff0aabb64a8504b1746a47fdd73e6b7ebc068f06ac7ffa44c757e4de207fc3cbfaf0469d3ac6795d40630bcafe8c658627e4bc6b86fd6a2135afbc18ccc8e6d0e1e86016930ca92edc5aa3fbe2c57de136d0ea5f41642b6a5d0ddeb380f2454d76a16639d663687f2a2e29fb9304243900d26d 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c 9964b3cab1efab3eb4fb922093a038657492bcb9926a0f7955f01ae00f5c3a7bd851d901ed1a5c1c3f2a0050d9ca1d88 +db2ad659cf21bc9c1f7e6469c5f262b73261d49f7b1755fc137636e8ce0202f929dca4466c422284c10be8f351f36333ebc04b1888cba217c0fec872b2dfc3aa0d544e5e06a9518a8cfe3df5b20fbcb14a9bf218e3bf6a8e024530a17bab50906be34d9f9bba69af0b11d8ed426b9ec75c3bd1f2e5b8756e4a72ff846bc9e498 e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c 922c33fb14d5356b221a466946bd00f98b3f62ed2271afdbe2e943d8a9a28e108de3f6017c2bd941d28ec45d45a7eed5 +dbd8ddc02771a5ff7359d5216536b2e524a2d0b6ff180fa29a41a8847b6f45f1b1d52344d32aea62a23ea3d8584deaaea38ee92d1314fdb4fbbecdad27ac810f02de0452332939f644aa9fe526d313cea81b9c3f6a8dbbeafc899d0cdaeb1dca05160a8a039662c4c845a3dbb07be2bc8c9150e344103e404411668c48aa7792 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855 b9ad186d35a888c15aa35169d56878b38bfc36055f4057f87ee48d9c52d9b833619f7e98b42974640c172124d0c427b0 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P521 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P521 new file mode 100644 index 000000000000..cb2d5e4ba23a --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P521 @@ -0,0 +1,60 @@ +58ec2b2ceb80207ff51b17688bd5850f9388ce0b4a4f7316f5af6f52cfc4dde4192b6dbd97b56f93d1e4073517ac6c6140429b5484e266d07127e28b8e613ddf65888cbd5242b2f0eee4d5754eb11f25dfa5c3f87c790de371856c882731a157083a00d8eae29a57884dbbfcd98922c12cf5d73066daabe3bf3f42cfbdb9d853 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46 91623db6536c60c2e2411a4d582c972694742eb3381a36e5d767e70b1c2a82d093dd5e21e04dba069365bee6a0075ef1 +2449a53e0581f1b56d1e463b1c1686d33b3491efe1f3cc0443ba05d65694597cc7a2595bda9cae939166eb03cec624a788c9bbab69a39fb6554649131a56b26295683d8ac1aea969040413df405325425146c1e3a138d2f4f772ae2ed917cc36465acd66150058622440d7e77b3ad621e1c43a3f277da88d850d608079d9b911 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73 95c368fa52e7e6f29dc40acefb3a2f726c0b2478f613f50aa99b87c41f204f4e31468d293bf350b7edd098cff0137804 +7ba05797b5b67e1adfafb7fae20c0c0abe1543c94cee92d5021e1abc57720a6107999c70eacf3d4a79702cd4e6885fa1b7155398ac729d1ed6b45e51fe114c46caf444b20b406ad9cde6b9b2687aa645b46b51ab790b67047219e7290df1a797f35949aaf912a0a8556bb21018e7f70427c0fc018e461755378b981d0d9df3a9 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace b2af45cbf87e66b94cf80250649927764b8fbc554958cd288446def5991870fd6e67f6d7e47b17f40397c453a17083cc +716dabdb22a1c854ec60420249905a1d7ca68dd573efaff7542e76f0eae54a1828db69a39a1206cd05e10e681f24881b131e042ed9e19f5995c253840e937b809dfb8027fed71d541860f318691c13a2eb514daa5889410f256305f3b5b47cc16f7a7dad6359589b5f4568de4c4aae2357a8ea5e0ebaa5b89063eb3aa44eb952 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc a0bb5c6620442c2467d9fa00423647b439040cc858c37efbad62ff5f7134d75392fbab52fcfa1f1b92f38077fde5b859 +9cc9c2f131fe3ac7ea91ae6d832c7788cbbf34f68e839269c336ceef7bef6f20c0a62ea8cc340a333a3002145d07eba4cf4026a0c4b26b0217a0046701de92d573d7c87a386a1ea68dc80525b7dcc9be41b451ad9f3d16819e2a0a0b5a0c56736da3709e64761f97cae2399de2a4022dc4c3d73c7a1735c36dbde86c4bc5b6f7 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549 a0bfe7ee03ad7a31aee7a2d7e2c98ff8b05a622bd678c3977f258bb5d6b4f1efe12043c3ccd60790c45a049f54cffbb4 +14c69f8d660f7a6b37b13a6d9788eff16311b67598ab8368039ea1d9146e54f55a83b3d13d7ac9652135933c68fafd993a582253be0deea282d86046c2fb6fd3a7b2c80874ced28d8bed791bd4134c796bb7baf195bdd0dc6fa03fdb7f98755ca063fb1349e56fd0375cf94774df4203b34495404ebb86f1c7875b85174c574c 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4 b145d00c917d888d0d438f119e072296aed4375f077a781850978f65ba5314a809c9ea443d570637b9cb34640fab6f93 +8d8e75df200c177dbfe61be61567b82177ea5ec58e2781168d2277d2fd42668f01248ca3eb29ffa2689b12ae40f9c429532b6d2e1f15891322b825a0a072a1c68fa09e78cfdef3e95ed6fdf7233a43cb68236560d49a3278f0b3f47cb08f475bd9ab2f60755ea4a1767de9313b71a1b9ea87ef33f34682efbda263b0f8cc2f52 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16 85dafaf602202065d4d2f1ab5834ff0650204d64f47bce975150b21ceaf05b2b053902aed665e99794a9ae74cebff8ff +10631c3d438870f311c905e569a58e56d20a2a560e857f0f9bac2bb7233ec40c79de145294da0937e6b5e5c34fff4e6270823e5c8553c07d4adf25f614845b2eac731c5773ebbd716ab45698d156d043859945de57473389954d223522fbafecf560b07ef9ba861bcc1df9a7a89cdd6debf4cd9bf2cf28c193393569ccbd0398 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37 84ba354808721ca6cf700046324556e357d2c285931dd9f50d07bb07bacf7fc485cbe7310480c3a9bb00a5d03ca465fe +80aad6d696cbe654faa0d0a24d2f50d46e4f00a1b488ea1a98ed06c44d1d0c568beb4ab3674fc2b1d2d3da1053f28940e89ba1244899e8515cabdd66e99a77df31e90d93e37a8a240e803a998209988fc829e239150da058a300489e33bf3dcdaf7d06069e74569fee77f4e3875d0a713ccd2b7e9d7be62b34b6e375e84209ef 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256 947622c3e64338233263fd1ff0b07ec6d908b8e8a89b37e7cb25254e73027cfbb9e6bfe6ef9688007b308b02f7b73589 +8a7792a2870d2dd341cd9c4a2a9ec2da753dcb0f692b70b64cef2e22071389c70b3b188dea5f409fb435cbd09082f59de6bc2ff9e65f91b7acc51e6e7f8e513148cb3c7c4664f227d5c704626b0fda447aa87b9d47cd99789b88628eb642ed250312de5ba6b25f3d5342a3cbb7ebd69b0044ee2b4c9ba5e3f5195afb6bea823d 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7 85b4b9ed9db333070384130da7dd899017a3977e7e7284643b440b6d9f376cf24165a54d9accb059b2d95975e6a11bed +f971bcd396efb8392207b5ca72ac62649b47732fba8feaa8e84f7fb36b3edb5d7b5333fbfa39a4f882cb42fe57cd1ace43d06aaad33d0603741a18bc261caa14f29ead389f7c20536d406e9d39c34079812ba26b39baedf5feb1ef1f79990496dd019c87e38c38c486ec1c251da2a8a9a57854b80fcd513285e8dee8c43a9890 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73 b739470415905f2b3f751f8fcb264fa78ae12a0d713ce8f2e35783f76d004eb247dddad7afcc9be6d7c64982dedd771e +ec0d468447222506b4ead04ea1a17e2aa96eeb3e5f066367975dbaea426104f2111c45e206752896e5fa7594d74ed184493598783cb8079e0e915b638d5c317fa978d9011b44a76b28d752462adf305bde321431f7f34b017c9a35bae8786755a62e746480fa3524d398a6ff5fdc6cec54c07221cce61e46fd0a1af932fa8a33 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c a091d3431ea49567f939224f243208df913059856fbe246b1853a2e2c39027a1aa7bad088dbe13f2b0a5e6931fc1c819 +d891da97d2b612fa6483ee7870e0f10fc12a89f9e33d636f587f72e0049f5888782ccde3ea737e2abca41492bac291e20de5b84157a43c5ea900aef761006a4471072ab6ae6d515ffe227695d3ff2341355b8398f72a723ae947f9618237c4b6642a36974860b452c0c6202688bc0814710cbbff4b8e0d1395e8671ae67ada01 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace 96051dc61bc7eefb066bccda94cb3f9f5b274e4ca8392f7b2d46d6f881c8a63a2436f42367816745f6e9279a346bc152 +924e4afc979d1fd1ec8ab17e02b69964a1f025882611d9ba57c772175926944e42c68422d15f9326285538a348f9301e593e02c35a9817b160c05e21003d202473db69df695191be22db05615561951867f8425f88c29ba8997a41a2f96b5cee791307369671543373ea91d5ed9d6a34794d33305db8975b061864e6b0fe775f 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8 a8ee753423c94d079308f5555866d0e76cd53793fb603e5b17cdb5e8b4b50d45d1018bfa0ac13ee8fb40138a0e4af8c3 +c64319c8aa1c1ae676630045ae488aedebca19d753704182c4bf3b306b75db98e9be438234233c2f14e3b97c2f55236950629885ac1e0bd015db0f912913ffb6f1361c4cc25c3cd434583b0f7a5a9e1a549aa523614268037973b65eb59c0c16a19a49bfaa13d507b29d5c7a146cd8da2917665100ac9de2d75fa48cb708ac79 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad a4324fb66a47ed09ca81359991151b9ade1486269f5e8536ed80a04fea74ec68ac2134a2a5c9db2ed04e83df4b96085c +8ab8176b16278db54f84328ae0b75ef8f0cd18afdf40c04ad0927ed0f6d9e47470396c8e87cde7a9be2ffbfe6c9658c88b7de4d582111119c433b2e4a504493f0a1166e3a3ea0d7b93358f4a297d63f65a5e752f94e2ee7f49ebcc742fa3eb03a617d00c574245b77a20033854d82964b2949e2247637239ab00baf4d170d97c 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a 946445342a31515c052de52b0dfab3a2287d922355268977161e61bcc62052b35b83598fe90e7663c37c2db0f7076bca +c4bc2cec829036469e55acdd277745034e4e3cc4fcd2f50ec8bd89055c19795a1e051ccf9aa178e12f9beab6a016a7257e391faa536eaa5c969396d4e1ade36795a82ebc709d9422de8497e5b68e7292538d4ccdc6dd66d27a3ece6a2844962b77db073df9489c9710585ba03d53fa430dbc6626dc03b61d53fc180b9af5dea6 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c 825e505b1b2907a36816b31b5276f17bf09914444739dee66e402d2b8398d66ffe61f58b191060d1d2665714048d8268 +1c1b641d0511a0625a4b33e7639d7a057e27f3a7f818e67f593286c8a4c827bb1f3e4f399027e57f18a45403a310c785b50e5a03517c72b45ef8c242a57b162debf2e80c1cf6c7b90237aede5f4ab1fcaf8187be3beb524c223cc0ceff24429eb181a5eea364a748c713214880d976c2cd497fd65ab3854ad0d6c2c1913d3a06 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d 889aa7fdf09383610a265b8b6f5524b05b5eda184e4c8be38a24b598dd281c41814641b207b1586e4134217782ae7293 +adb5f069b2b501a3ebb83d4f1808eb07710ac4a7b12532996855a20bcc54b2f76812915f632163c3654ff13d187d007152617cf859200194b59c5e81fc6cc9eb1ceb75d654050f260caa79c265254089270ccd02607fdcf3246119738c496dc3a4bd5d3be15789fc3d29a08d6d921febe2f40aef286d5d4330b07198c7f4588e 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c b9f1dd1c09a79b6f5c939f33d5b09c0d0ba523399b112d6cd91f71a02789862af10300bb6bb2e1b14294d5da15977cb2 +f253484d121d1ce8a88def6a3e9e78c47f4025ead6f73285bf90647102645b0c32d4d86742a50b8b7a42d5f6156a6faf588212b7dc72c3ffd13973bdba732b554d8bffc57d04f8167aef21ee941ee6ffb6cce0f49445bd707da8deb35dca650aaf761c3aa66a5ebccddd15aee21293f63061a7f4bfc3787c2cd62c806a1a9985 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25 a8b436b245a9c2ae00bbdf3b41c9e6356460ed68e0a1ab1c777d6374dd4501ad6499bccfbf07bca4cadc9cdf5291cd15 +33bab1c369c495db1610965bc0b0546a216e8dd00cd0e602a605d40bc8812bbf1ffa67143f896c436b8f7cf0bed308054f1e1ff77f4d0a13c1e831efbd0e2fcfb3eadab9f755f070ba9aeaceb0a5110f2f8b0c1f7b1aa96a7f2d038a1b72e26400819b1f73d925ea4e34d6acaf59d0a461a34ce5d65c9c937a80e844e323a16d 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf 8c01d80c45e3081c2e92a15225e25fd548a718481237c0b4e2fb17482a31e5d121d5b4cadf67d3d63c389c3db604c53b +08c8b7faaac8e1154042d162dca1df0f66e0001b3c5ecf49b6a4334ce4e8a754a1a8e4daf8ec09cf1e521c96547aed5172ef852e82c03cddd851a9f992183ac5199594f288dbcc53a9bb6128561ff3236a7b4b0dce8eaf7d45e64e782955ee1b690ce6a73ece47dc4409b690de6b7928cbe60c42fc6a5ddf1d729faf1cc3885e 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570 99b0da76a8e7fb7e16b81c0c02547f9fb05f57ad5c7ea84b4e0c89cbfdc15cadc4f7f3f90d0bd85f06dffb24ef7cefcd +ba74eed74282811631bd2069e862381e4e2a1e4e9a357b1c159a9ce69786f864b60fe90eeb32d8b72b099986fc594965a33285f7185b415df58fead7b8b50fc60d073680881d7435609ad1d22fd21e789b6730e232b0d2e888889fb82d6ad0337ab909308676164d4f47df44b21190eca8ba0f94995e60ad9bb02938461eee61 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6 b8e05b5d9365f656265cfcd3153b2e47e65bc5ade0e3f0c7bd43b811e35df3fc89dd8755e9499b991bbe61a6ce99b760 +dc71f171a28bdc30968c39f08f999b88dc04c550e261ecf1124d67f05edeae7e87fe9b8135a96fe2bc3996a4f47213d9d191184a76bd6310e1ee5cb67ea7fc3ef6f641a0ba165198040fa668192b75a4754fc02c224bd4a74aade5a8c814adf151c2bfeda65165a04ef359e39847c84e312afb66d4cd1db50d41ef3fe5f31296 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7 b21ecccedf4ebeafd04985e688a5dcca7ff4342eaaa65479231388867b6f2f5c87cd4ad134b60fce45ad7feb7092e73c +b895788d7828aaeace4f6b61a072ffa344d8ea324962ba6dab5efda93f65bf64a0f2ac6d5721d03ee70e2aef21cdba69fd29040199160e3a293b772ffb961ed694a8dc82800dab79367a4809a864e4aff6bc837aaa868e952b771b76591c0bb82249034e3208e593d85973d3fea753a95b16e221b2561644535c0131fe834ae7 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e 81ad1ed0361c9e728e226210bc49c19ddee0f0a03956247738b8248ce63d82122f26874207536da21da9d152ea935d7a +2c5bd848c476e34b427cfe5676692e588e1957957db7b5704492bd02104a38216535607f5d092dc40020130c04a3aaf0f1c52409834926d69a05d3f3188187a71d402a10ba34eac8629b4c6359b1095f30f710219298bf06b9f19bfc299981d7e251ca232a0a85338a7e02464731d1b25d4a1f68baf97064516590644820c998 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938 8ee8d90d787582ac125e811a59fc73413a5fca80381cc81eb3e51adec4fc1ad5a6545788906d6c645f899eff9b3b7c62 +65a0b97048067a0c9040acbb5d7f6e2e6ac462e1e0064a8ce5b5bbf8e57059e25a3ef8c80fc9037ae08f63e63f5bdb9378c322ad9b2daf839fad7a75b1027abb6f70f110247da7e971c7c52914e5a4f7761854432fa16b2a521e7bcaee2c735a87cad20c535bf6d04a87340c229bf9af8647eedca9e2dc0b5aa90f7fea3cdc0a 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662 a88b4036ec49bea0639f1a5a6412c0848064999e844e9e7d24694114a93fd1309639e1f879ab3a9209556ac8cdb3a1ef +d6e366a87808eea5d39fe77cac4b8c754e865a796062e2ec89f72165cd41fe04c48148068c570e0d29afe9011e7e7a2461f4d9897d8c1fa14b4ff88cab40059d17ab724f4039244e97fcecb07f9ffeec2fb9d6b1896700fe374104a8c44af01a10e93b268d25367bf2bef488b8abcc1ef0e14c3e6e1621b2d58753f21e28b86f 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721 addd2a49cc742f50187558c49d40cff1b35ab747840da8837ccb54ee5f0d9beae75b4674447a70d1b5a0a2ae17dafcc5 +f99e1d272d0f5fb9c4f986e873d070ec638422bc04b47c715595e2cf1a701cdf88bc6c4b20085b357bad12ccba67cac8a5ca07f31ba432f9154ff1fadefd487a83a9c37e49fb70a2f170e58889cab0552e0a3806ccfa2a60d96e346851d84b7de6d1a4b8cf37567dc161a84f13421e3412457d4bc27f6213453c8519a2d7daa2 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e 8833462454d3355a920fd88a04a2335b0cf1bb0a91fa8981b10370ef8d203c7021b7621c4eae681ca58d8497617bea31 +91f1ca8ce6681f4e1f117b918ae787a888798a9df3afc9d0e922f51cdd6e7f7e55da996f7e3615f1d41e4292479859a44fa18a5a006662610f1aaa2884f843c2e73d441753e0ead51dffc366250616c706f07128940dd6312ff3eda6f0e2b4e441b3d74c592b97d9cd910f979d7f39767b379e7f36a7519f2a4a251ef5e8aae1 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418 805874b203076c431f02d5eeabc3ea8bf5d875a7e9b5e89a37df92c174102deb77ab06110138a7d10c3dff5d0e5bd952 +dbc094402c5b559d53168c6f0c550d827499c6fb2186ae2db15b89b4e6f46220386d6f01bebde91b6ceb3ec7b4696e2cbfd14894dd0b7d656d23396ce920044f9ca514bf115cf98ecaa55b950a9e49365c2f3a05be5020e93db92c37437513044973e792af814d0ffad2c8ecc89ae4b35ccb19318f0b988a7d33ec5a4fe85dfe 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950 b6163d4c7ad48b50a7b722f3ed12343e683a2b6e82c8e0352c2a150ae3f59e5c3f75e2830306351d576942821c72410d +114187efd1f6d6c46473fed0c1922987c79be2144439c6f61183caf2045bfb419f8cddc82267d14540624975f27232117729ccfeacccc7ecd5b71473c69d128152931865a60e6a104b67afe5ed443bdbcdc45372f1a85012bbc4614d4c0c534aacd9ab78664dda9b1f1e255878e8ac59e23c56a686f567e4b15c66f0e7c0931e 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b a9c0a877addd18faa802353cdef40e0cc26845b9e012c9ac9e9ff25fd3b98eb9f5b1771b11e33c5525f083f88e3928de +6744b69fc2420fe00f2352399bd58719e4ecdd6d602e2c80f194d607e58b27a0854745bfd6d504de2eb30b04cee0f44af710dd77e2f816ac3ac5692fad2d1d417893bb0edba2707a4c146a486f8728ca696d35cc52e9c7187c82d4bdb92eb954794e5ad15133f6bfea1f025da32ada710a3014cf11095b3ff69a94d087f17753 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f 81331398ab753ab61c0b0ec10cbc46ef96318c9c2795f92d281ba6c6266240c0e0806f417ccba6e89bb5685e08b5eb06 +16001f4dcf9e76aa134b12b867f252735144e523e40fba9b4811b07448a24ef4ccf3e81fe9d7f8097ae1d216a51b6eefc83880885e5b14a5eeee025c4232319c4b8bce26807d1b386ad6a964deb3bdca30ee196cfdd717facfad5c77d9b1d05fdd96875e9675e85029ecbf4f94c524624746b7c42870c14a9a1454acf3354474 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66 88fef1f305664e577683a94eedfaca9c65dd32429a2a083b2d79bc642029503d43e44fedd351b2e8eb21ea5ec1a76c60 +a9824a7b810aa16690083a00d422842971baf400c3563baa789c5653fc13416111c0236c67c68e95a13cec0df50324dcc9ae780ce4232607cb57dd9b2c61b382f0fa51fd4e283e2c55ffe272597651659fbd88cd03bfa9652cd54b01a7034c83a602709879e1325c77969bebfd93932ce09a23eae607374602201614ff84b141 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c a641e9fb9a8d69bb9b8df09ee36044d63e6d315a310786208d6232f53f7c6bf0b33153ed757e45b9137c29d2ccc57961 +90d8bbf714fd2120d2144022bf29520842d9fbd2dc8bb734b3e892ba0285c6a342d6e1e37cc11a62083566e45b039cc65506d20a7d8b51d763d25f0d9eaf3d38601af612c5798a8a2c712d968592b6ed689b88bbab95259ad34da26af9dda80f2f8a02960370bdb7e7595c0a4fffb465d7ad0c4665b5ec0e7d50c6a8238c7f53 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0 949665a534923c7e2d582b5f6af0d6f935ba31893338a12bc04a76de9410b985ef5e174f5b1f64b8e32d5cc77a9a1773 +09952b1e09995e95bf0022e911c6ab1a463b0a1fdd0eec69117b34af1103c720b57600217de7cd178fef92de5391e550af72a8dcf7badf25b06dd039417f9a7d0f5be88fcd4e9655931d5b605452a667c9d1bae91d3476e7d51cff4108f116a49966fb3a7cff8df1c09734ce5620faf2dccb3dc5d94e7e9ac812da31f6d07a38 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9 ad6a5d46cdda1ce98ee587fff5ba284b51de09590a165329ca0b7c023b618811fd11231f15cf7d00dc1b9f07fbeaa3c4 +0bb0f80cff309c65ff7729c59c517d50fc0ed5be405ef70cb910c3f62c328c90853d4473530b654dda6156e149bc2222a8a7f9be665240e2fbe9d03f78a2356af0bacd1edb84c4801adc8293a8a0bd6123d1cf6ba216aca807a7eb4dca76b493eb6e3dbb69d36f0f00f856222f24d9b93ec34c3b261be2fca0451c00571928e5 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d b122b80c6e104147d667d35598dc3cbdef7c90e4c5b2b13233e894ed4675a76cd2b18434208e665de503c86e1bf9ffd4 +7efacf213382ce30804e78b7256854d759147dba9729c51b2759465715bf2c421034c23dc651c13d6cce95f71fe6a84dfbee5768163ac5789ac0474c5ddf4115684683c5f7c204b33b8bcc0c03ac58f66cef2f53b721fe2fac91ad841126101a88f512a7c2ded38549d9f050d4b7961dda48a1489f026c5d111701762418cfe3 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490 8061a47540188167419008d9bed7db489ae24bb5968eb25650b351fc6288257873277620fb0d13051a6aa7da9a8575aa +28edff8b9d85f5f58499cc11f492abdfab25e8945975bbaeee910afa2b8fc1295ec61406309ce4e09f4ab4f462959fc2a2786802466eb26d3b01be6919893ae75d0fdc2dc8a82e662550f9fce9627dd364188aaba5c6faa1b2d8a2235adfa5ad0dc140f88a2b2f103f5690e877d07fe8fd30d02d2b2729bd3d8eb5b23a21f54c 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1 b774cc0e2b02c7ada17448d14675f22672855b16555ace57b172d4040eefd873c9cbe9eef2e0a3db0ee8f280946bd3cd +bae2a8897c742fd99fbf813351cd009d3f2e18d825ca22e115276484bce8f82f8c7c0c21dd2af208404d8ef45bb5a6c41693912b630897d5246801bf0775aa9bbac8be98cb861d172c3563dc59e78a58ed13c66dea496471b3ad0eeae8995293e4ab97373edc1837ffc95ff1cc0c1e90e64ea8680b2ca5f1e09bf86b99b343b6 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745 b8f8122103e6ed946073f628b85a9c790b4cc098617c598d8e1d87957dc4737ca49ffb76bf750825e49222a164ba5aaf +d57a26a9593e72bfc87322524639bcaae5f2252d18b99cdaa03b14445b0b8a4dd53928f66a2e4f202fb25b19cad0eb2f1bfda2ab9b0eb668cdcd0fe72f5d9ef2e45e0218590f7ab9d2c9342202610c698bc786cce108a7d4a6730a13e9ea1b470e781f1237d3f84f44abde808516975546bd89075ef9a9732bfd7ee33b6f4399 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f a6b4074f1664cab4691793e3692db10f894197df4179a9ba80ae856d029f52d76727752d2bf9f5003c4fe37e9b809f8e +8fdcf5084b12cfc043dd3416b46274e021bbed95d341d3c500c102a5609d3a34de29f8fa9f0adb611a1f47a97ad981f8129d718fc0d6c709eab1a3490db8d550f34eb905b9e00663543afc5bc155e368e0bc919a8b8c9fa42093603537a5614927efa6be819ed42ececbf1a80a61e6e0a7f9b5bc43b9238e62d5df0571fea152 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e 835636ef4b8cc9dc930a524c3ddf29d6f460ca30757b66de8cb5bc5c8ae26602c3c1d1769482b629223fcbb607f27af4 +00669f433934992257bed55861df679804107d7fa491672574a7624949c60049b0533383c88d6896c8de860704c3e6a6aefce83efa57c4d57e9ab253da5d15e1f53ab6dce218b592772ab0bc01fee8e63368e85c0639301456fe2d44cd5396a7f2b22761cd03b80eba7883eede8249a2f5db2183bf00550c5c002f45a5e4fb31 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89 93e6b97597c74861be978e4f91c48d61c0389252a5535a6c62d474eb1b69071010bd7bb9e7cc93f06971e909eaf3b375 +4be81dcfab39a64d6f00c0d7fff94dabdf3473dc49f0e12900df328d6584b854fbaebaf3194c433e9e21743342e2dd056b445c8aa7d30a38504b366a8fa889dc8ecec35b3130070787e7bf0f22fab5bea54a07d3a75368605397ba74dbf2923ef20c37a0d9c64caebcc93157456b57b98d4becb13fecb7cc7f3740a6057af287 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a 817279909156a615dedfc3cdc1e4873624c49d8bb557e30188a28f8a98f6d2189f3b6ff1abf8a1185b75136a1edf1eae +9ecd500c60e701404922e58ab20cc002651fdee7cbc9336adda33e4c1088fab1964ecb7904dc6856865d6c8e15041ccf2d5ac302e99d346ff2f686531d25521678d4fd3f76bbf2c893d246cb4d7693792fe18172108146853103a51f824acc621cb7311d2463c3361ea707254f2b052bc22cb8012873dcbb95bf1a5cc53ab89f 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926 9927e2a4ee3dd3ba0e009a1c4d4433a8439213eb515c41fb1120ac6a6b10d1945619974bc0ad7fcfc3b99f70e3b2141c +b3c63e5f5a21c4bfe3dbc644354d9a949186d6a9e1dd873828782aa6a0f1df2f64114a430b1c13fe8a2e09099e1ed05ef70de698161039ded73bcb50b312673bb073f8a792ac140a78a8b7f3586dffb1fc8be4f54516d57418ccc9945025ce3acf1eb84f69ceee5e9bd10c18c251dbc481562cd3aae54b54ab618cb1eeda33cf 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6 87d0fb25f48c8537fce4e219ea2798a0fe00e062dc40aebb41374971711ce4ab4ba6f4e7431800c3a6996dd2d7cebf6c +6e0f96d56505ffd2d005d5677dbf926345f0ff0a5da456bbcbcfdc2d33c8d878b0bc8511401c73168d161c23a88b04d7a9629a7a6fbcff241071b0d212248fcc2c94fa5c086909adb8f4b9772b4293b4acf5215ea2fc72f8cec57b5a13792d7859b6d40348fc3ba3f5e7062a19075a9edb713ddcd391aefc90f46bbd81e2557b 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f 83cad7070e9bba3a384e38453e720a1d580aa012bc1288542ce5cc45c81d57aa7c482c9afb19eb77efa8170170c41ea4 +3f12ab17af3c3680aad22196337cedb0a9dba22387a7c555b46e84176a6f8418004552386ada4deec59fdabb0d25e1c6668a96f100b352f8dabd24b2262bd2a3d0f825602d54150bdc4bcbd5b8e0ca52bc8d2c70ff2af9b03e20730d6bd9ec1d091a3e5c877259bcff4fd2c17a12bfc4b08117ec39fe4762be128d0883a37e9d 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742 8b4ec59e37a230158ce4066f66b2add75cbe84c4cfa46a8ea1c65f88e5fc850fc1541e6a98aa7ad351c048d0fc181020 +a1eed24b3b7c33296c2491d6ee092ec6124f85cf566bb5bc35bffb5c734e34547242e57593e962fb76aee9e800eed2d702cc301499060b76406b347f3d1c86456978950737703c8159001e6778f69c734a56e5ce5938bd0e0de0877d55adeee48b0d8dfa4ac65fd2d3ce3e12878bac5c7014f9284d161b2a3e7d5c88569a45f6 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697 86730f871885064f6c900de29a25c501446b60108b73075157ca8ad51e2e2703034329a4ed53835c4f2a22ba8a241ba8 +9aace26837695e6596007a54e4bccdd5ffb16dc6844140e2eeeb584b15acb2bbffd203c74440b6ee8db676fd200b4186a8c3e957c19e74d4d865ada83f80655323dfa3570907ed3ce853b6e8cc375ed2d758a2f5ad265dd3b47650517a49b3d02df9e0c60c21576378c2b3a08481eec129b2a75608e13e6420127a3a63c8a3f1 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04 abe00f48ea355e3bc64dacf65fd4423b6a809a49a8a8b39cd3cbff22bc92b3c265eed653ab580dbd19c6be5b7d698ac7 +ac2175940545d4fbab6e2e651c6830aba562e0c11c919e797c43eff9f187a68a9e5a128e3e2a330b955a3f4577d3f826529ad1b03d7b60f7ad678f005053b41dc0f8d267f3685c6abe1a0e9a733c44b2f3ca48b90806f935141c842e3a6c06a58f5343d75e3585971a734f4ae1074ce5b54f74bd9342f4bbca738d260393f43e 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6 b3905b2e429e28292ba2a7d75847952724dd9eee72be1bc4652b8e94b2b12a5e8a6d9b38c9d31c2364a11275d7a420a3 +6266f09710e2434cb3da3b15396556765db2ddcd221dce257eab7399c7c490135925112932716af1434053b8b9fe340563e57a0b9776f9ac92cbb5fba18b05c0a2fafbed7240b3f93cd1780c980ff5fe92610e36c0177cabe82367c84cee9020cf26c1d74ae3eb9b9b512cb8b3cb3d81b17cf20dc76591b2b394ef1c62ac12ee 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e b4b2f411e05db73db918304517b06d5cbd2bd23eb9b622e6d6e871d1ec1870f5fe0159a6ccb2b4a5f0a416878a1b87da +3de9e617a6868dca1a1432d503f923535da3f9b34426b2a4822174399c73b1c1ee67311410a58c17202ac767844b2024d8aa21a205707d93865693ac25a24fc87034fa3a7a7e27c3344cb03b87602c15180a5fe6a9dd90cd11af4a0f150207bf2d83f55b12c088adae99aa8cfa659311b3a25beb99056643760d6a282126b9b2 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5 8f04720930ebd76d39d8f2e80a5351355036727d200000300c552899dcf289266c1d155889b8f3ca17a67588c06265db +aa48851af7ef17abe233163b7185130f4646203c205e22bcc2a5a3697bcab998c73a9ffe1d3ea0b7978ce7df937a72586eb5ca60b0d939a7d1c115c820171c89c8116b7e2c7b98cf0f14e4c4df3cb2f319ad3ab0ea25ff14526ddc037469f000bf82100acd4cdf94feb4eba4ea1726f0569336604a473aee67d71afebb569209 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a b7fc6c35648a97c544dc07342f1d8be02872a59c4872f9a2ee259b048b7de4b6969205c5a95a2bd2ff8671f4bf5e06e3 +b0d5d52259af364eb2d1a5027e5f7d0afe4b999cc5dd2268cfe76f51d2f17b541bdd7867e23a1bb897705153d9432a24012108979c6a2c9e2567c9531d012f9e4be764419491a52eae2e127430b0ab58cb8e216515a821b3db206447c235bf44ee304201b483b2a88844abaa18bca0147dfff7e502397dd62e15524f67eb2df2 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb a4478663d38b88a8d442448b17e3a7c96fe6005e102f51a56d1263eb9343cf005bc2ca0c3b1608fd2b6dad1cc5a62440 +9599788344976779383a7a0812a096943a1f771ee484d586af1a06207478e4c0be9c200d42460fe837e24b266c8852d80d3c53cc52ffb1913fc3261145fc6da575611efd16c026059a2e64f802517ffd1b6b34de10ad2909c65c2155e8d939b8115400c1d793d23955b15f5d1c13c962ff92b4a815cee0e10f8e14e1f6e6cd38 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77 aaec758d63ed2c53a4ea38559dbad99e3bdd476c0557145c0ce6d5fd27d546a6c09498bdfb9b844cd28370ad3e290da1 +fdde51acfd04eb0ad892ce9d6c0f90eb91ce765cbe3ce9d3f2defe8f691324d26b968b8b90e77706b068585f2a3ee7bf3e910528f7403c5af745a6f9d7ba6c53abd885c3b1be583415b128f4d3f224daf8563476bd9aa61e9c8518c144335f8f879c03696bddbe3ac37a8fbede29861611feaa87e325e2f60278b4893ed57fb0 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c 852c039e6e8e7d4bd2bfe631c57366735161fa5a210555123d6b0e1614a7ff6874fd71ff9269de6a91c7fd52694ff1fb +beb34c997f905c77451ac392f7957a0ab8b23325bd5c63ca31c109ac8f655a1e3094240cb8a99284f8091de2ab9a7db2504d16251980b86be89ec3a3f41162698bab51848880633e0b71a38f8896335853d8e836a2454ecab2acdcc052c8f659be1d703b13ae1b090334ac50ab0137ddb5e8b924c0e3d2e5789daaef2fdd4a1e 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63 90ccce24d9049f66cf9ec8aa33822ceb40cd57a2c656d3d27bd949aa6dd8d3b1f59ac688962bbf3333f831d9ba60285e +543c374af90c34f50ee195006d5f9d8dd986d09ad182fcbefa085567275eee1e742bfe0af3d058675adeb5b9f87f248b00a9fbd2aa779129123a5b983f2f26fc3caf2ea34277550c22fe8c814c739b46972d50232993cddd63a3c99e20f5c5067d9b57e2d5db94317a5a16b5c12b5c4cafbc79cbc2f9940f074bbc7d0dc71e90 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da ac837242629082760bb50ddf07a4d00a505fdc92790ebbaa639f24f6e9245b43384c1a31075d116243b10bc4bc98e845 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P521_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P521_blst new file mode 100644 index 000000000000..2024a520bb6b --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_fips_186_3_P521_blst @@ -0,0 +1,60 @@ +58ec2b2ceb80207ff51b17688bd5850f9388ce0b4a4f7316f5af6f52cfc4dde4192b6dbd97b56f93d1e4073517ac6c6140429b5484e266d07127e28b8e613ddf65888cbd5242b2f0eee4d5754eb11f25dfa5c3f87c790de371856c882731a157083a00d8eae29a57884dbbfcd98922c12cf5d73066daabe3bf3f42cfbdb9d853 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46 a8d2fabd094bddbfe42daca2f440c1b50e4246b1a4a53005ec141d22e4426a2a8eacb289c2c4d041b8acfdb665aada01 +2449a53e0581f1b56d1e463b1c1686d33b3491efe1f3cc0443ba05d65694597cc7a2595bda9cae939166eb03cec624a788c9bbab69a39fb6554649131a56b26295683d8ac1aea969040413df405325425146c1e3a138d2f4f772ae2ed917cc36465acd66150058622440d7e77b3ad621e1c43a3f277da88d850d608079d9b911 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73 a83b0a228ee47e88d6563bd045f61386467140c9371dae93601efa32017482a6e24e6eae454652909df00023d10e3ce2 +7ba05797b5b67e1adfafb7fae20c0c0abe1543c94cee92d5021e1abc57720a6107999c70eacf3d4a79702cd4e6885fa1b7155398ac729d1ed6b45e51fe114c46caf444b20b406ad9cde6b9b2687aa645b46b51ab790b67047219e7290df1a797f35949aaf912a0a8556bb21018e7f70427c0fc018e461755378b981d0d9df3a9 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace a0d98aaacfbeefdfda662c7927dda5f9be1805946e49793a8620b2d291097ec0c148c9b92c038377ba9806ea3f0ab9b6 +716dabdb22a1c854ec60420249905a1d7ca68dd573efaff7542e76f0eae54a1828db69a39a1206cd05e10e681f24881b131e042ed9e19f5995c253840e937b809dfb8027fed71d541860f318691c13a2eb514daa5889410f256305f3b5b47cc16f7a7dad6359589b5f4568de4c4aae2357a8ea5e0ebaa5b89063eb3aa44eb952 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc 889dcb835df6fffcec91677ef0bd4e07371e3bf80bcf85ea3e6b81aba53811e3d7e13b7d99c901114c409c529fe25132 +9cc9c2f131fe3ac7ea91ae6d832c7788cbbf34f68e839269c336ceef7bef6f20c0a62ea8cc340a333a3002145d07eba4cf4026a0c4b26b0217a0046701de92d573d7c87a386a1ea68dc80525b7dcc9be41b451ad9f3d16819e2a0a0b5a0c56736da3709e64761f97cae2399de2a4022dc4c3d73c7a1735c36dbde86c4bc5b6f7 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549 b6eed519448f83233213550626be5b81e921967000d56d99032dc829a2670d496ed69ffd8a3869131aea85e41c76ff4d +14c69f8d660f7a6b37b13a6d9788eff16311b67598ab8368039ea1d9146e54f55a83b3d13d7ac9652135933c68fafd993a582253be0deea282d86046c2fb6fd3a7b2c80874ced28d8bed791bd4134c796bb7baf195bdd0dc6fa03fdb7f98755ca063fb1349e56fd0375cf94774df4203b34495404ebb86f1c7875b85174c574c 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4 8c7d189a1ec0573863146157744c7f249411edf390cf91e8b521724da5e37f945ce4616d78f973fcbf3e28972f2f039f +8d8e75df200c177dbfe61be61567b82177ea5ec58e2781168d2277d2fd42668f01248ca3eb29ffa2689b12ae40f9c429532b6d2e1f15891322b825a0a072a1c68fa09e78cfdef3e95ed6fdf7233a43cb68236560d49a3278f0b3f47cb08f475bd9ab2f60755ea4a1767de9313b71a1b9ea87ef33f34682efbda263b0f8cc2f52 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16 950f33ab05d79d5192337be83e8c62fcbbd49531f487e82ed71e4329b36a411a73330c6d5341608a556278b7e23d0f57 +10631c3d438870f311c905e569a58e56d20a2a560e857f0f9bac2bb7233ec40c79de145294da0937e6b5e5c34fff4e6270823e5c8553c07d4adf25f614845b2eac731c5773ebbd716ab45698d156d043859945de57473389954d223522fbafecf560b07ef9ba861bcc1df9a7a89cdd6debf4cd9bf2cf28c193393569ccbd0398 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37 a801e9bebc261273a6e45ee3a861604adff2a5444fa31ae7fe33efb2715159502c595b569db53f7a44c64f8f4b9286a3 +80aad6d696cbe654faa0d0a24d2f50d46e4f00a1b488ea1a98ed06c44d1d0c568beb4ab3674fc2b1d2d3da1053f28940e89ba1244899e8515cabdd66e99a77df31e90d93e37a8a240e803a998209988fc829e239150da058a300489e33bf3dcdaf7d06069e74569fee77f4e3875d0a713ccd2b7e9d7be62b34b6e375e84209ef 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256 90d4c6a2ee5c556219750cf6d5ce1fa661c0f52406419268abad2452d384b391cc99469ce09392c31ea7a371ec41e09d +8a7792a2870d2dd341cd9c4a2a9ec2da753dcb0f692b70b64cef2e22071389c70b3b188dea5f409fb435cbd09082f59de6bc2ff9e65f91b7acc51e6e7f8e513148cb3c7c4664f227d5c704626b0fda447aa87b9d47cd99789b88628eb642ed250312de5ba6b25f3d5342a3cbb7ebd69b0044ee2b4c9ba5e3f5195afb6bea823d 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7 a448b39048cbc300d1f56e0af81fca2749f25f590106860e0051d5c7f6f4d06f29cd33ce1b1ac29dde6accd69b6213ca +f971bcd396efb8392207b5ca72ac62649b47732fba8feaa8e84f7fb36b3edb5d7b5333fbfa39a4f882cb42fe57cd1ace43d06aaad33d0603741a18bc261caa14f29ead389f7c20536d406e9d39c34079812ba26b39baedf5feb1ef1f79990496dd019c87e38c38c486ec1c251da2a8a9a57854b80fcd513285e8dee8c43a9890 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73 821cb2fbe441b8a648e9f856aa1f99ebd78eb57143c06a944efb79fb80fa0e1376b7a34a2e00c1906be383843611f9ec +ec0d468447222506b4ead04ea1a17e2aa96eeb3e5f066367975dbaea426104f2111c45e206752896e5fa7594d74ed184493598783cb8079e0e915b638d5c317fa978d9011b44a76b28d752462adf305bde321431f7f34b017c9a35bae8786755a62e746480fa3524d398a6ff5fdc6cec54c07221cce61e46fd0a1af932fa8a33 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c b1bd07bc55fd39093a3add2c827ad52206d9f8a18add13ee6f57b3f6c6f498d0e937a4490f0a18b902d828cedd0893b4 +d891da97d2b612fa6483ee7870e0f10fc12a89f9e33d636f587f72e0049f5888782ccde3ea737e2abca41492bac291e20de5b84157a43c5ea900aef761006a4471072ab6ae6d515ffe227695d3ff2341355b8398f72a723ae947f9618237c4b6642a36974860b452c0c6202688bc0814710cbbff4b8e0d1395e8671ae67ada01 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace a2668697334b4ca5027ad44bcabb2d61aa6e13b671172db87e20473d5535d175bff6beefffa2a6fd9783bf8247d936ce +924e4afc979d1fd1ec8ab17e02b69964a1f025882611d9ba57c772175926944e42c68422d15f9326285538a348f9301e593e02c35a9817b160c05e21003d202473db69df695191be22db05615561951867f8425f88c29ba8997a41a2f96b5cee791307369671543373ea91d5ed9d6a34794d33305db8975b061864e6b0fe775f 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8 a74f085c5e8590a35fb82e08139cb74b925a3d9c62c8afef634ed54cd705239c30f251f6b86cc288afe3f853422404e3 +c64319c8aa1c1ae676630045ae488aedebca19d753704182c4bf3b306b75db98e9be438234233c2f14e3b97c2f55236950629885ac1e0bd015db0f912913ffb6f1361c4cc25c3cd434583b0f7a5a9e1a549aa523614268037973b65eb59c0c16a19a49bfaa13d507b29d5c7a146cd8da2917665100ac9de2d75fa48cb708ac79 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad 89cf7f317b3e4d2a98c136e5af0da9e33e0d34c36064ff3bc7c71430ba8bacc4d87e0f4bdc08aa3ee3b4f19c24139f70 +8ab8176b16278db54f84328ae0b75ef8f0cd18afdf40c04ad0927ed0f6d9e47470396c8e87cde7a9be2ffbfe6c9658c88b7de4d582111119c433b2e4a504493f0a1166e3a3ea0d7b93358f4a297d63f65a5e752f94e2ee7f49ebcc742fa3eb03a617d00c574245b77a20033854d82964b2949e2247637239ab00baf4d170d97c 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a 96a19c0be31f92788edd901abb9411935cc5f927c11bfd70bd4315946926fe61e2547c94302a296d84fb492a28deb9ae +c4bc2cec829036469e55acdd277745034e4e3cc4fcd2f50ec8bd89055c19795a1e051ccf9aa178e12f9beab6a016a7257e391faa536eaa5c969396d4e1ade36795a82ebc709d9422de8497e5b68e7292538d4ccdc6dd66d27a3ece6a2844962b77db073df9489c9710585ba03d53fa430dbc6626dc03b61d53fc180b9af5dea6 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c b5eeee9291ce4e3f6c8b01adeaf1ac2dfef916112c8e6f353f0f8bd57489f7fc0ad375ce76bb47c301102c90e48acc75 +1c1b641d0511a0625a4b33e7639d7a057e27f3a7f818e67f593286c8a4c827bb1f3e4f399027e57f18a45403a310c785b50e5a03517c72b45ef8c242a57b162debf2e80c1cf6c7b90237aede5f4ab1fcaf8187be3beb524c223cc0ceff24429eb181a5eea364a748c713214880d976c2cd497fd65ab3854ad0d6c2c1913d3a06 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d 8aa2401760b64bd8c8939562857a53d1335ef34836ca8fd8c3128b5211c7033687a51b2251f323b93dae6c5e32be8824 +adb5f069b2b501a3ebb83d4f1808eb07710ac4a7b12532996855a20bcc54b2f76812915f632163c3654ff13d187d007152617cf859200194b59c5e81fc6cc9eb1ceb75d654050f260caa79c265254089270ccd02607fdcf3246119738c496dc3a4bd5d3be15789fc3d29a08d6d921febe2f40aef286d5d4330b07198c7f4588e 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c 9386b1ace71dd421b0dcfd82ced77d8eee5d1b95fa4f5e9b0a3f88cadeacc77b810a05021e05d06fa848189cbb5f44d2 +f253484d121d1ce8a88def6a3e9e78c47f4025ead6f73285bf90647102645b0c32d4d86742a50b8b7a42d5f6156a6faf588212b7dc72c3ffd13973bdba732b554d8bffc57d04f8167aef21ee941ee6ffb6cce0f49445bd707da8deb35dca650aaf761c3aa66a5ebccddd15aee21293f63061a7f4bfc3787c2cd62c806a1a9985 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25 81979b112b3c234f911a161a55a12c535c2d47c62a9a0cd0a10341615961fd5565badcdf5fc602254b8a004a38738376 +33bab1c369c495db1610965bc0b0546a216e8dd00cd0e602a605d40bc8812bbf1ffa67143f896c436b8f7cf0bed308054f1e1ff77f4d0a13c1e831efbd0e2fcfb3eadab9f755f070ba9aeaceb0a5110f2f8b0c1f7b1aa96a7f2d038a1b72e26400819b1f73d925ea4e34d6acaf59d0a461a34ce5d65c9c937a80e844e323a16d 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf a2fe2188e02c92c56d5b9b8fd1d635c2ac29d9a2be948e1713bdd2af9f0d2a03549931a2d5893799efdcc1002c1fc9b9 +08c8b7faaac8e1154042d162dca1df0f66e0001b3c5ecf49b6a4334ce4e8a754a1a8e4daf8ec09cf1e521c96547aed5172ef852e82c03cddd851a9f992183ac5199594f288dbcc53a9bb6128561ff3236a7b4b0dce8eaf7d45e64e782955ee1b690ce6a73ece47dc4409b690de6b7928cbe60c42fc6a5ddf1d729faf1cc3885e 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570 919ec78dc8cfedbdde0bea6be133afc6ca0b33c0d167e3fbb89e997419c464fc067c456359293b9165ebf3492ba56173 +ba74eed74282811631bd2069e862381e4e2a1e4e9a357b1c159a9ce69786f864b60fe90eeb32d8b72b099986fc594965a33285f7185b415df58fead7b8b50fc60d073680881d7435609ad1d22fd21e789b6730e232b0d2e888889fb82d6ad0337ab909308676164d4f47df44b21190eca8ba0f94995e60ad9bb02938461eee61 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6 ac8b7f42ab955f778c68e7cb390dd3c91942d77ed75e3b6136ab9fbf1c0acda47a3701450b660b0d26c5164fdb56f77f +dc71f171a28bdc30968c39f08f999b88dc04c550e261ecf1124d67f05edeae7e87fe9b8135a96fe2bc3996a4f47213d9d191184a76bd6310e1ee5cb67ea7fc3ef6f641a0ba165198040fa668192b75a4754fc02c224bd4a74aade5a8c814adf151c2bfeda65165a04ef359e39847c84e312afb66d4cd1db50d41ef3fe5f31296 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7 afaa5a2b11a31bb32b72c227f102d24902e6762c17a58beeb8e1a557ffae48272c015bc4967119fecd5d1217a07884c9 +b895788d7828aaeace4f6b61a072ffa344d8ea324962ba6dab5efda93f65bf64a0f2ac6d5721d03ee70e2aef21cdba69fd29040199160e3a293b772ffb961ed694a8dc82800dab79367a4809a864e4aff6bc837aaa868e952b771b76591c0bb82249034e3208e593d85973d3fea753a95b16e221b2561644535c0131fe834ae7 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e 9085f534ee318d3e4f69adef9e8cd0884fc958669dc40440439372a6d563ee0d96f462c1bcd9c8268d7d2339020b6a98 +2c5bd848c476e34b427cfe5676692e588e1957957db7b5704492bd02104a38216535607f5d092dc40020130c04a3aaf0f1c52409834926d69a05d3f3188187a71d402a10ba34eac8629b4c6359b1095f30f710219298bf06b9f19bfc299981d7e251ca232a0a85338a7e02464731d1b25d4a1f68baf97064516590644820c998 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938 a86a6da5b82d3e588144e5099bb772ea97c6fa2bea257df751628173f3b294711c44a5ecae2bf29d0347ccb552e638fc +65a0b97048067a0c9040acbb5d7f6e2e6ac462e1e0064a8ce5b5bbf8e57059e25a3ef8c80fc9037ae08f63e63f5bdb9378c322ad9b2daf839fad7a75b1027abb6f70f110247da7e971c7c52914e5a4f7761854432fa16b2a521e7bcaee2c735a87cad20c535bf6d04a87340c229bf9af8647eedca9e2dc0b5aa90f7fea3cdc0a 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662 82231b19335b2674263988843037075876aaef9fa1bbe7c74154b353f448c9d0f318972706acec58f26130ff7e1531ed +d6e366a87808eea5d39fe77cac4b8c754e865a796062e2ec89f72165cd41fe04c48148068c570e0d29afe9011e7e7a2461f4d9897d8c1fa14b4ff88cab40059d17ab724f4039244e97fcecb07f9ffeec2fb9d6b1896700fe374104a8c44af01a10e93b268d25367bf2bef488b8abcc1ef0e14c3e6e1621b2d58753f21e28b86f 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721 8960b7c5a13df3ebdd79bc3c0e059c5159fccd848131434798fb6f4e83dea3f669b136158b9b3fb711d21731c7bfd5bf +f99e1d272d0f5fb9c4f986e873d070ec638422bc04b47c715595e2cf1a701cdf88bc6c4b20085b357bad12ccba67cac8a5ca07f31ba432f9154ff1fadefd487a83a9c37e49fb70a2f170e58889cab0552e0a3806ccfa2a60d96e346851d84b7de6d1a4b8cf37567dc161a84f13421e3412457d4bc27f6213453c8519a2d7daa2 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e ae35b44140226ba11846f17378044cfee96f8529a1411be3996289d4dd76198347e9df508c77276ea5d00b98d1e72709 +91f1ca8ce6681f4e1f117b918ae787a888798a9df3afc9d0e922f51cdd6e7f7e55da996f7e3615f1d41e4292479859a44fa18a5a006662610f1aaa2884f843c2e73d441753e0ead51dffc366250616c706f07128940dd6312ff3eda6f0e2b4e441b3d74c592b97d9cd910f979d7f39767b379e7f36a7519f2a4a251ef5e8aae1 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418 b1cf96a3f07d342ad42e189ff95665954d74c60d2be78a99fe1eebf5d71cfde869c8aa259255532a73bbf1f31e57715a +dbc094402c5b559d53168c6f0c550d827499c6fb2186ae2db15b89b4e6f46220386d6f01bebde91b6ceb3ec7b4696e2cbfd14894dd0b7d656d23396ce920044f9ca514bf115cf98ecaa55b950a9e49365c2f3a05be5020e93db92c37437513044973e792af814d0ffad2c8ecc89ae4b35ccb19318f0b988a7d33ec5a4fe85dfe 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950 8743d1dd426338bfe4bacd376e4a826022d3e00b62885021ad182e179a45b7f0e0877196db6c8cec6bb0890c44a10100 +114187efd1f6d6c46473fed0c1922987c79be2144439c6f61183caf2045bfb419f8cddc82267d14540624975f27232117729ccfeacccc7ecd5b71473c69d128152931865a60e6a104b67afe5ed443bdbcdc45372f1a85012bbc4614d4c0c534aacd9ab78664dda9b1f1e255878e8ac59e23c56a686f567e4b15c66f0e7c0931e 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b a02f91b6cd15b5343f6fdc7954c8c4c399e91087010e91f96b987af71ca740192c5d02eb58dbcfe36283a01d121226c0 +6744b69fc2420fe00f2352399bd58719e4ecdd6d602e2c80f194d607e58b27a0854745bfd6d504de2eb30b04cee0f44af710dd77e2f816ac3ac5692fad2d1d417893bb0edba2707a4c146a486f8728ca696d35cc52e9c7187c82d4bdb92eb954794e5ad15133f6bfea1f025da32ada710a3014cf11095b3ff69a94d087f17753 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f a91f3bcb670d685dac97af06e5c633098ab6c55473dc554377dd3545c60bdf9fa54af6473a453c54d928ee9f69a793a9 +16001f4dcf9e76aa134b12b867f252735144e523e40fba9b4811b07448a24ef4ccf3e81fe9d7f8097ae1d216a51b6eefc83880885e5b14a5eeee025c4232319c4b8bce26807d1b386ad6a964deb3bdca30ee196cfdd717facfad5c77d9b1d05fdd96875e9675e85029ecbf4f94c524624746b7c42870c14a9a1454acf3354474 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66 a44a801c8bc7d66bb6bb8f27697cd93f1f19c1baedeee6429f14e7e06ebc48b2dddc69025c8dad1b4f55f352d59648bb +a9824a7b810aa16690083a00d422842971baf400c3563baa789c5653fc13416111c0236c67c68e95a13cec0df50324dcc9ae780ce4232607cb57dd9b2c61b382f0fa51fd4e283e2c55ffe272597651659fbd88cd03bfa9652cd54b01a7034c83a602709879e1325c77969bebfd93932ce09a23eae607374602201614ff84b141 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c a2634436aad3cd3e3a286a680fe7da5fec7829acdcee788ee66d5951fb403bdbe466c1f02aa9a9d1f4e2bd31944ec62c +90d8bbf714fd2120d2144022bf29520842d9fbd2dc8bb734b3e892ba0285c6a342d6e1e37cc11a62083566e45b039cc65506d20a7d8b51d763d25f0d9eaf3d38601af612c5798a8a2c712d968592b6ed689b88bbab95259ad34da26af9dda80f2f8a02960370bdb7e7595c0a4fffb465d7ad0c4665b5ec0e7d50c6a8238c7f53 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0 83ec7612b84a670da8ca748fce219936162b81a212882522abbb501711f5923b71555a2459cf456c87beadc58199c4d2 +09952b1e09995e95bf0022e911c6ab1a463b0a1fdd0eec69117b34af1103c720b57600217de7cd178fef92de5391e550af72a8dcf7badf25b06dd039417f9a7d0f5be88fcd4e9655931d5b605452a667c9d1bae91d3476e7d51cff4108f116a49966fb3a7cff8df1c09734ce5620faf2dccb3dc5d94e7e9ac812da31f6d07a38 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9 abb66a93408464ca72e210d2a2dcd336a553b99d7594ab51d52a69afc96c83a355128afaa9a25db7936f52f29fdcc6ba +0bb0f80cff309c65ff7729c59c517d50fc0ed5be405ef70cb910c3f62c328c90853d4473530b654dda6156e149bc2222a8a7f9be665240e2fbe9d03f78a2356af0bacd1edb84c4801adc8293a8a0bd6123d1cf6ba216aca807a7eb4dca76b493eb6e3dbb69d36f0f00f856222f24d9b93ec34c3b261be2fca0451c00571928e5 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d 8694f5552ffbb78bff1583e6227056d49747f477d47d52d7937ceb5570b79c86f12d892829f8758ab38b93d466221b05 +7efacf213382ce30804e78b7256854d759147dba9729c51b2759465715bf2c421034c23dc651c13d6cce95f71fe6a84dfbee5768163ac5789ac0474c5ddf4115684683c5f7c204b33b8bcc0c03ac58f66cef2f53b721fe2fac91ad841126101a88f512a7c2ded38549d9f050d4b7961dda48a1489f026c5d111701762418cfe3 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490 b92d496e787a80600cbf1a2dd767608eef2d46e435a9d07afe80c9cc678d56c54be1d8e10571f88b18dfd903e599d377 +28edff8b9d85f5f58499cc11f492abdfab25e8945975bbaeee910afa2b8fc1295ec61406309ce4e09f4ab4f462959fc2a2786802466eb26d3b01be6919893ae75d0fdc2dc8a82e662550f9fce9627dd364188aaba5c6faa1b2d8a2235adfa5ad0dc140f88a2b2f103f5690e877d07fe8fd30d02d2b2729bd3d8eb5b23a21f54c 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1 b620325e25292aed51f6c13a8bc7dbf5c5d4bd8613fa5f50edc079634ab9e2ea302139df9e8a72119b02a3a974a2c195 +bae2a8897c742fd99fbf813351cd009d3f2e18d825ca22e115276484bce8f82f8c7c0c21dd2af208404d8ef45bb5a6c41693912b630897d5246801bf0775aa9bbac8be98cb861d172c3563dc59e78a58ed13c66dea496471b3ad0eeae8995293e4ab97373edc1837ffc95ff1cc0c1e90e64ea8680b2ca5f1e09bf86b99b343b6 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745 82848c124a834bb51b31373fe9169d8ceb7069f5d067cd72d04af920838c7104b73cbf9716b1fa3c13200beae57347ba +d57a26a9593e72bfc87322524639bcaae5f2252d18b99cdaa03b14445b0b8a4dd53928f66a2e4f202fb25b19cad0eb2f1bfda2ab9b0eb668cdcd0fe72f5d9ef2e45e0218590f7ab9d2c9342202610c698bc786cce108a7d4a6730a13e9ea1b470e781f1237d3f84f44abde808516975546bd89075ef9a9732bfd7ee33b6f4399 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f ac5e3e6fb49c80595ed584fdee0ff1493e008ddcc073ecf2bc696adfae91d8d893e2cd93d3ed917fdb6dad231369e1f2 +8fdcf5084b12cfc043dd3416b46274e021bbed95d341d3c500c102a5609d3a34de29f8fa9f0adb611a1f47a97ad981f8129d718fc0d6c709eab1a3490db8d550f34eb905b9e00663543afc5bc155e368e0bc919a8b8c9fa42093603537a5614927efa6be819ed42ececbf1a80a61e6e0a7f9b5bc43b9238e62d5df0571fea152 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e 87cbe6ab4a01b4779a7f68f72cf2b26cd27c3e6d57a2d0a23f902c96a9a1aa5a6924fd9b8719be7915284a247ccdf3a1 +00669f433934992257bed55861df679804107d7fa491672574a7624949c60049b0533383c88d6896c8de860704c3e6a6aefce83efa57c4d57e9ab253da5d15e1f53ab6dce218b592772ab0bc01fee8e63368e85c0639301456fe2d44cd5396a7f2b22761cd03b80eba7883eede8249a2f5db2183bf00550c5c002f45a5e4fb31 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89 aa7086163e48bcc5b40104319e0fea949cbfd8efc8ae8a90e76b0b8b0c6c04f806dbaee7498cb2093f1df64514381b8d +4be81dcfab39a64d6f00c0d7fff94dabdf3473dc49f0e12900df328d6584b854fbaebaf3194c433e9e21743342e2dd056b445c8aa7d30a38504b366a8fa889dc8ecec35b3130070787e7bf0f22fab5bea54a07d3a75368605397ba74dbf2923ef20c37a0d9c64caebcc93157456b57b98d4becb13fecb7cc7f3740a6057af287 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a 916cc3c02817d81487be52db42847d1a5580ea5060cb309cb8f3d0727cefdfad25757b2ad6599ed0765d7031fe2afbc6 +9ecd500c60e701404922e58ab20cc002651fdee7cbc9336adda33e4c1088fab1964ecb7904dc6856865d6c8e15041ccf2d5ac302e99d346ff2f686531d25521678d4fd3f76bbf2c893d246cb4d7693792fe18172108146853103a51f824acc621cb7311d2463c3361ea707254f2b052bc22cb8012873dcbb95bf1a5cc53ab89f 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926 966d3de22ff6591eb44d209ad2312196e727ad96069aa809b8b97131b77b2ba4e354588399c788251df61a145cc971c6 +b3c63e5f5a21c4bfe3dbc644354d9a949186d6a9e1dd873828782aa6a0f1df2f64114a430b1c13fe8a2e09099e1ed05ef70de698161039ded73bcb50b312673bb073f8a792ac140a78a8b7f3586dffb1fc8be4f54516d57418ccc9945025ce3acf1eb84f69ceee5e9bd10c18c251dbc481562cd3aae54b54ab618cb1eeda33cf 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6 abebd8425b6c520c03969159fb8f99a7c3fe8afc73cab74f34de40061e43133566736b781a8d51c9cb50fe866f6324fa +6e0f96d56505ffd2d005d5677dbf926345f0ff0a5da456bbcbcfdc2d33c8d878b0bc8511401c73168d161c23a88b04d7a9629a7a6fbcff241071b0d212248fcc2c94fa5c086909adb8f4b9772b4293b4acf5215ea2fc72f8cec57b5a13792d7859b6d40348fc3ba3f5e7062a19075a9edb713ddcd391aefc90f46bbd81e2557b 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f a08dcd6711c509b0cae5f90643a5736f7bff00e520eb130be1c202d8a2641352977108dd6edf1de4344046c6bc5cdfdc +3f12ab17af3c3680aad22196337cedb0a9dba22387a7c555b46e84176a6f8418004552386ada4deec59fdabb0d25e1c6668a96f100b352f8dabd24b2262bd2a3d0f825602d54150bdc4bcbd5b8e0ca52bc8d2c70ff2af9b03e20730d6bd9ec1d091a3e5c877259bcff4fd2c17a12bfc4b08117ec39fe4762be128d0883a37e9d 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742 ae8616bf394381c80c0256a8c5de7c44663607d581bbdc38afbe1205af24b096904b64c279d4b1f8d58af939a3635d4f +a1eed24b3b7c33296c2491d6ee092ec6124f85cf566bb5bc35bffb5c734e34547242e57593e962fb76aee9e800eed2d702cc301499060b76406b347f3d1c86456978950737703c8159001e6778f69c734a56e5ce5938bd0e0de0877d55adeee48b0d8dfa4ac65fd2d3ce3e12878bac5c7014f9284d161b2a3e7d5c88569a45f6 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697 905dba8ce43d110aeaa63fa2498f2660c0a31ab79cc5c04ce641bb74cf3c315e7fa5eee9a5d875bb13513f1c978d5502 +9aace26837695e6596007a54e4bccdd5ffb16dc6844140e2eeeb584b15acb2bbffd203c74440b6ee8db676fd200b4186a8c3e957c19e74d4d865ada83f80655323dfa3570907ed3ce853b6e8cc375ed2d758a2f5ad265dd3b47650517a49b3d02df9e0c60c21576378c2b3a08481eec129b2a75608e13e6420127a3a63c8a3f1 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04 a967365befaf5d590f384cdf4fcf11c2e477be9c4b5ed77587f03c704156c8679b1861cea43305922a8270b4f9ef154f +ac2175940545d4fbab6e2e651c6830aba562e0c11c919e797c43eff9f187a68a9e5a128e3e2a330b955a3f4577d3f826529ad1b03d7b60f7ad678f005053b41dc0f8d267f3685c6abe1a0e9a733c44b2f3ca48b90806f935141c842e3a6c06a58f5343d75e3585971a734f4ae1074ce5b54f74bd9342f4bbca738d260393f43e 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6 aa436fbcbcccdc51a0f71365db87edd1e047516c16eb2e5c302b99798662d3d70754fba5eeced44d93b7f0c30a87dd02 +6266f09710e2434cb3da3b15396556765db2ddcd221dce257eab7399c7c490135925112932716af1434053b8b9fe340563e57a0b9776f9ac92cbb5fba18b05c0a2fafbed7240b3f93cd1780c980ff5fe92610e36c0177cabe82367c84cee9020cf26c1d74ae3eb9b9b512cb8b3cb3d81b17cf20dc76591b2b394ef1c62ac12ee 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e 9576147ef53e5620cab6da6c137163362c2cddaae95d0b4798f58dc9f1bf8d7ba2e16bb0df0f6c28c9115b882b2f4cff +3de9e617a6868dca1a1432d503f923535da3f9b34426b2a4822174399c73b1c1ee67311410a58c17202ac767844b2024d8aa21a205707d93865693ac25a24fc87034fa3a7a7e27c3344cb03b87602c15180a5fe6a9dd90cd11af4a0f150207bf2d83f55b12c088adae99aa8cfa659311b3a25beb99056643760d6a282126b9b2 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5 84f9e4a58f8acb5498facc409bfa9cddce473eb193b2ca5945671221fcab66ffb053cf4923cdc51508ede09912113f40 +aa48851af7ef17abe233163b7185130f4646203c205e22bcc2a5a3697bcab998c73a9ffe1d3ea0b7978ce7df937a72586eb5ca60b0d939a7d1c115c820171c89c8116b7e2c7b98cf0f14e4c4df3cb2f319ad3ab0ea25ff14526ddc037469f000bf82100acd4cdf94feb4eba4ea1726f0569336604a473aee67d71afebb569209 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a 8b75448f5d60677a145306e6eee87f3dd29ca26b07592cc535bfb3b1ad80ec72d7989c88e26b8e0b81fb14631f897a1a +b0d5d52259af364eb2d1a5027e5f7d0afe4b999cc5dd2268cfe76f51d2f17b541bdd7867e23a1bb897705153d9432a24012108979c6a2c9e2567c9531d012f9e4be764419491a52eae2e127430b0ab58cb8e216515a821b3db206447c235bf44ee304201b483b2a88844abaa18bca0147dfff7e502397dd62e15524f67eb2df2 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb 882b023cad7d61e5a69710a2705d9c388875dede80db1e65e450f674f846155ba6a90ca6614f8b6954d7e9dc4b7fd22e +9599788344976779383a7a0812a096943a1f771ee484d586af1a06207478e4c0be9c200d42460fe837e24b266c8852d80d3c53cc52ffb1913fc3261145fc6da575611efd16c026059a2e64f802517ffd1b6b34de10ad2909c65c2155e8d939b8115400c1d793d23955b15f5d1c13c962ff92b4a815cee0e10f8e14e1f6e6cd38 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77 8e481fac66dad66fb3f4b2c2c4f0e7baffc59c4f5f4b1f0a2fddfd305250f9d7ffafb9a3eec87b90c1b3fcd67fd7f232 +fdde51acfd04eb0ad892ce9d6c0f90eb91ce765cbe3ce9d3f2defe8f691324d26b968b8b90e77706b068585f2a3ee7bf3e910528f7403c5af745a6f9d7ba6c53abd885c3b1be583415b128f4d3f224daf8563476bd9aa61e9c8518c144335f8f879c03696bddbe3ac37a8fbede29861611feaa87e325e2f60278b4893ed57fb0 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c 8bdf649970908f4d96022d1a01d746dd13302cc1f1e5d6df2bcdf25d10acbb611bbd00689f8d5dcff962ae9853f492ad +beb34c997f905c77451ac392f7957a0ab8b23325bd5c63ca31c109ac8f655a1e3094240cb8a99284f8091de2ab9a7db2504d16251980b86be89ec3a3f41162698bab51848880633e0b71a38f8896335853d8e836a2454ecab2acdcc052c8f659be1d703b13ae1b090334ac50ab0137ddb5e8b924c0e3d2e5789daaef2fdd4a1e 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63 b8316eea989236ddc1c8a85b08f9b1669ae5ba597c46cf27846a833f81aa7d54545fa7c2bc9b2b517d3b70d8d6a773a6 +543c374af90c34f50ee195006d5f9d8dd986d09ad182fcbefa085567275eee1e742bfe0af3d058675adeb5b9f87f248b00a9fbd2aa779129123a5b983f2f26fc3caf2ea34277550c22fe8c814c739b46972d50232993cddd63a3c99e20f5c5067d9b57e2d5db94317a5a16b5c12b5c4cafbc79cbc2f9940f074bbc7d0dc71e90 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da b728f872a90e0a76affe6bc5e890f246a9abdff0a6e4ee7b56a0bbce00bd38f5d82c09ad2350be11b2f080c2e0279fe0 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_rfc6979 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_rfc6979 new file mode 100644 index 000000000000..40b3e06ad973 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_rfc6979 @@ -0,0 +1,34 @@ +73616d706c65 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 a3878f7d8996417b0dd87c9e75931f6cda00b40b84017f323a15277368c82cba68818dc78643175f08a7060e02e94308 +74657374 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 a5fe7589bd249a1674f07c66d1c567f480fde4773678e6f24957f3dfc0a432e3f669e4fc14d6603061d576bdc1bc7a14 +73616d706c65 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc 8eab1b56195214972607fdc08b75813cb27c486e61cb3a1e1862f78c8aa3ea61ef6e514488f68331021b9db07816fc07 +74657374 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc 815907c4349a658a3b653716327ac1c754f412dccc8dad9d6967491802328932b0b0f8020c0549aa5e1781eba48774af +73616d706c65 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 97222dee4caa8eff2dde7a76fb305cb08608eae3ddcd5e00bcb6caee89b783f0e3028444e7d20016ea62387aebe9cf62 +74657374 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 b8ccdcf4d5d113faa57851474dfe69a051d52d0257a5eaea17d77376098664372f765db4d36d61cfd0a42c46ff55a7a0 +73616d706c65 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 946b813ff63e4711d544273d557107e09de63a4d1198b7c515b8a6389263eb09b331c1ae5f99ddb7b7da45f0fd02fa5b +74657374 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 b07e0d6a577d82a065c418b3a78d66a51c82d54ca88491fad062ea8c92e3802828b0a6bbce47036044fd8ec37f52c6b4 +73616d706c65 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 ad9beaf64dabbdc5b4163e78aa7a56268201b1fa79fbb988d50914bed67181ca928f56153e586d62762a315e48137cee +74657374 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 84894b474f6c6f60a8d44da16cb3d296fd1a10d82478699bc97b8e862c90fe73e6771cbbd49cd01ed959038b31a3737f +73616d706c65 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 88388b2545e0fd13cabc59844e736adcf427e46d4244f79d28822804e531e58512b7235430ef816fdbeff3b258f6d3d2 +74657374 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 b1af3511dcdc9ee61357ef96fdf416f6290bcc4da19f2e7748f537295a2d631c8a423ca4273c87e64c32cad0822a5644 +73616d706c65 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c ada793ec777ee7265e6749e3e6dc8f33580767e71b844b4ea326d444db2e6fe7b234bc03862de9e277b002f3a788a0c1 +74657374 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c aa9905a2a9f3263eb47379ab7abeaa98dcc2d4cc593cb99018173cdbcc197bbecd56884412f3c5fae78222a0d935c48e +73616d706c65 9a4d6792295a7f730fc3f2b49cbc0f62e862272f aa0287c2c8c566c06958da9d71dad3f4de34dbc4182f7e8a293742060a428366cba1d646c1603a0fe94fd6d33821f727 +74657374 9a4d6792295a7f730fc3f2b49cbc0f62e862272f b6be4ede133850262636e2a937a5e47dd4e5a65205838d18fc483225532d2ca230ad8791a88dfefd8679a911950770a0 +73616d706c65 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 a7f9b778e9172f33f969432740619c1656ef551cdce265c8a34d2329a0b5b1c33a9241cc29d52b68428db8bc77b0fc0d +74657374 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 96d7ef79a06ccd6d69650e835a9f39ae236de4f5269f90c7d4ec9ccc49aa8993aae5684b67de1a28b1676989b7eca932 +73616d706c65 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a a2088562ee85096e8c2dc5248021d9a74598349adeb50fbc723402d509330d2db612c66759c1876dd5c1af6b192c412d +74657374 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 87a675245032ee3366f0809fbb1585b16ef472fd0ef7abad25133e5096727708401c85ae7d3de105181bbad0dcec29ae +73616d706c65 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 85700c8b24196822a3610a8ae1dc0b7287d392120b99285d7aeb50add28d76e4cc07d344a1172dafbe5e941940f2bae7 +74657374 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 b8b18d944fca8076b97c1574c379a50f1192ff210649a7f26ad38e9ca5c9f7166494d03e43e26c74b9d8070556c6b162 +73616d706c65 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c ae0f9fcbc5c99e6ee04c922c798836872512edd4138abb2502112769fe2e0aee78f0fe85fd6b0b2455dbabe5d3aff2f9 +74657374 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 90f0e8126980ace53a2d19e91bacb1e1013ef082477261e7605b70a2eb64e2fa535989f510b7bfe82f75cf2fcec6bb5a +73616d706c65 035318fc447d48d7e6bc93b48617dddedf26aa658f 8da02b16d1d0f405e10e6fcd112d6ba9b73c6633305afbdc4fdde83f1478a4b420e5ed9da7fd43e8e2427e6b929f0ed0 +74657374 035318fc447d48d7e6bc93b48617dddedf26aa658f ae4d3b22a6bf08e580f68f1f87ae93964df29100cdfe8b1e448b8c3bc733b0e27207d0b8d5c0baf2ebd479f10b33060d +73616d706c65 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 8ac9b3cfdabd5ee4b380b40f7059bc0b9e4b0ac2903d8c625fc59c2d844db31dcb453749a7a142c0a7f49749ccc34a64 +74657374 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 8d015ee8c87abc91baadc6c1a896faf26791045378dfb00e50137ef58993f43b68e4315617c0cea14d9248a4dc91b9c2 +73616d706c65 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e a0cc9fa19ae4bd176401ffbd97254ef8a2782ba798ebab36729a133c64a2aa9d0f344783cbe701003a2dafc89ff65baa +74657374 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e b6ef60b7284fa52f296d08eae18d429900a8d67dadb09cbe0ad1b10bae05d7c390c5512170b1db449fda46db44232d08 +73616d706c65 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 88c3c473c158da63f46315183bbe9571549f9a1a96b633a4838bb70cd216c9ed908373ec7f6b4ee1f16e64dfbff0b104 +74657374 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 a6c202c4cbe20c374f213e955f201ad6d24b0b2fe137d5465a0e4d7283a10dca11cfd8270c410519c7f00b93673c1dd6 +73616d706c65 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 a075d44982db181ec02d3f008d0eb5b5dbe7740e0d9b997b2cdfb71eb4c69b7dd30e3cfb5b72c36567e29a14f7074046 +74657374 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 8e2ec1d4cd323135278ab40bfd7bbf1f2fd74cfcb82f9cc14f6d380444e4a865a0f863d07bc4ff755ac33c3bbae2c8ae diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_rfc6979_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_rfc6979_blst new file mode 100644 index 000000000000..0fe2a54e23cb --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_basic/sig_g1_basic_rfc6979_blst @@ -0,0 +1,34 @@ +73616d706c65 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 a3878f7d8996417b0dd87c9e75931f6cda00b40b84017f323a15277368c82cba68818dc78643175f08a7060e02e94308 +74657374 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 a5fe7589bd249a1674f07c66d1c567f480fde4773678e6f24957f3dfc0a432e3f669e4fc14d6603061d576bdc1bc7a14 +73616d706c65 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc b66c6aaa922e8ef59591d4f874928778648cafdad5f49131d3c4e4253b93f376e20c9166d692fdbd1737f6a5e89acd05 +74657374 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc 8728d68bfd71642d9cc4d687e8243b22cc8c2c337abdc0ac093595481746eb86a0ac22517759b95713ca54e2f69ae0f7 +73616d706c65 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 97222dee4caa8eff2dde7a76fb305cb08608eae3ddcd5e00bcb6caee89b783f0e3028444e7d20016ea62387aebe9cf62 +74657374 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 b8ccdcf4d5d113faa57851474dfe69a051d52d0257a5eaea17d77376098664372f765db4d36d61cfd0a42c46ff55a7a0 +73616d706c65 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 946b813ff63e4711d544273d557107e09de63a4d1198b7c515b8a6389263eb09b331c1ae5f99ddb7b7da45f0fd02fa5b +74657374 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 b07e0d6a577d82a065c418b3a78d66a51c82d54ca88491fad062ea8c92e3802828b0a6bbce47036044fd8ec37f52c6b4 +73616d706c65 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 b1e31699d6c7b9e67e733e729e254eb511c72114e27d7e05e76b97fdd1f186b6c0deda3ef43d14ed5b6eb24bd182f24b +74657374 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 942d7e6196f94d226d15985874f9a9ef045e6954e42bc47d511b0840356f434c03c2be8753d5d60254c2629534042b30 +73616d706c65 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 b5819390b471c889757ff34174df52b7bc4d0d87facf220fae68bd9016b889f313044b1ef83a9392f60ba77ca995d15c +74657374 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 a171e8b74d486096bb1c204a988c16ff67eff8efbaf12a98fe4dc21fbdfdcb1540f192f33a43f9131de58a568babfed4 +73616d706c65 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c b9ddb02107ea1866d21bb8bd13939a200224ad7646f22780e4ced4d33b942dff62234f3bf56c6f991f7000a7a2b8a24f +74657374 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c a3a1f7266fd1bb0125913c22efc1063192d278a65cd8a311d112a8cc679746c7217d272ca48ed1c25994f3fe0f5f528e +73616d706c65 9a4d6792295a7f730fc3f2b49cbc0f62e862272f aa0287c2c8c566c06958da9d71dad3f4de34dbc4182f7e8a293742060a428366cba1d646c1603a0fe94fd6d33821f727 +74657374 9a4d6792295a7f730fc3f2b49cbc0f62e862272f b6be4ede133850262636e2a937a5e47dd4e5a65205838d18fc483225532d2ca230ad8791a88dfefd8679a911950770a0 +73616d706c65 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 a7f9b778e9172f33f969432740619c1656ef551cdce265c8a34d2329a0b5b1c33a9241cc29d52b68428db8bc77b0fc0d +74657374 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 96d7ef79a06ccd6d69650e835a9f39ae236de4f5269f90c7d4ec9ccc49aa8993aae5684b67de1a28b1676989b7eca932 +73616d706c65 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a b07e815e24d20e80865db725aeabf676d0605dcf754a9820cf10dc42ed2f449173ba07fe19ca354ff4829eaa301ec9c2 +74657374 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a b270e06158c843027a46968bd93641ccc6b002e47d78c5a92f5569c21771c7701e16e28422ae04942f9a9cdfdedffe3c +73616d706c65 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 93abe8ca1d88531fdee533b817c56e1ba7e199c40dcee232d9a797c8b14ad290207f96cd581e2d0b02515f1a5d685539 +74657374 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 adbd7677e4981c7518ee9a17e9f15df39c94ec4cd0c5406a586b03bf54334e5fa3e492eadf005fd6f148b030ea16274d +73616d706c65 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c b603750cf4afb76e1c1d3e1d42e2b8c86d1c7d27a01f6288fc034a29cf254da293e0f1b27ead5ac5530ff07f2421bdcd +74657374 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 899bedc650a986ad63e51df86a2933e7e9cbdfaf1d0b708b13c07d481a885a95473a10b5978d40c7af4d162b892e550b +73616d706c65 035318fc447d48d7e6bc93b48617dddedf26aa658f 8da02b16d1d0f405e10e6fcd112d6ba9b73c6633305afbdc4fdde83f1478a4b420e5ed9da7fd43e8e2427e6b929f0ed0 +74657374 035318fc447d48d7e6bc93b48617dddedf26aa658f ae4d3b22a6bf08e580f68f1f87ae93964df29100cdfe8b1e448b8c3bc733b0e27207d0b8d5c0baf2ebd479f10b33060d +73616d706c65 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 8ac9b3cfdabd5ee4b380b40f7059bc0b9e4b0ac2903d8c625fc59c2d844db31dcb453749a7a142c0a7f49749ccc34a64 +74657374 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 8d015ee8c87abc91baadc6c1a896faf26791045378dfb00e50137ef58993f43b68e4315617c0cea14d9248a4dc91b9c2 +73616d706c65 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e a2e23700b5de2682e4390e85622532585b915a4783ae660dd56962877556630d95260859b7260c8e48c5a249f454c99e +74657374 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e aaef0cc05be376f7c91c5e575aea4dd9843275d5224ea4d1681d8bd7c3cb4c823ab2a7b540a824caf0b3788bd346bb2a +73616d706c65 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 aa68ab1baf1ec27f11c4d3015ef8a4c17c0dad574af6f68fd49f3451d2e0694701a5c44e43d81793fcbb9839c4ae904f +74657374 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 81915d4a77e40dd2229a1f6d9b1335707b6d38ae9b887dc591cf76670cefad32d811c28eb6d410590daf0d6215202e4f +73616d706c65 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 a5ea2dbacbd9d613286f620f08ce554f1652d36ab0a1453445cf408ffa731f717563e11dc4296e7b3e5bafd127715c49 +74657374 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 b23520431ced6c26e801be619a863361e6e167d9490c8f4152f40966eeca80da2149509d89bea2ef611342ce3f7dc1dc diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B233 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B233 new file mode 100644 index 000000000000..7bd198c437c0 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B233 @@ -0,0 +1,60 @@ +f1b67fde01e60e4bb7904d906e9436a330c5cb5721fd4e0a3c75b83dade868736bb1d21cfb1b5c6407c373e386ee68ec2239b700e763728eb675a153b8ac44cf2a87be85fe8ed6683430cf4b7d718891cbf8d583d0a37cc952cc25fe803a7aa4fda80f05541a2f1f2601cdd0c095f7110f2a84f7d641b8531572269b21cbe77b 0056673197bfeea9bd7a8b820b4ae51a50411bf118a692bb9ed3d304da53 91b0b92bd2e10e552ec32a667d6c8a4cdfcd77a402053203062c142c121b442b3891391cefa8dfbeae66e94a2989c5d6 +1d496d96b533c632ed6a91f6e3653cdffaa5b8cc0008b35e49b2dd52fe261105c2ec7ee71a4ad5d51fdc3d36d688a3b7ccb3b3b0c3a65be17b8d8aa172e3005cfbf37a2d1b1a6e268c090c6f318e7e96f9ec9b9f5a8fbcc7558d89e840f7e76e44bed91c26ca48e6f5cbc253ca2fe8cb81c484cabd24070e488f9c00cd96ad4f 00468f01d483144e514ec257f2e5fdee28a927f2adb19714c1f3524dd0d3 882c9f6de90dcc8fbbf07768b241e309635fd080226fd626905410d531e5fc051c865abf055d6cb91bf67cdd13d8fc6d +723400655027f474446843645757f7e2cd466bf97275067b4bc4c9d79bb3b19b2421835d69db916f24b77c381fa771fc1e7a19d2b4d09411ae55acccc615b16fd24705762b441ab67083a921fd4ae569ce0de69449aa96f5b977ac7dc022fdc8335656853796f54b3fbd118577f98920624eb0a00204f1ef83827245c06646cc 0074052d027f05465a8083a59cdbf32600224e1f563f653b34314651517f 99ad870e0376236c6ff4b59208625317443bafe1bce6e12f18a5a314f69e257af33f462abd0b5f0c91df7411956a3e59 +155860cb31a142082bcc0bad828d747e916392d21f1873b3a3c1d28ca3ff9d45ddb66a712e3856b6afd07c8d2b2a7badab296a9775b03f6fec0befa2d8d6d00fe3938df244ab46e836a3e686c8b4f918da49f0bb3940bba34a9aa22c7caf02df7758b0de01d9f47af6146344b9be3842d9c055eaf0fb399cd8db95c544a62d8a 001856e7544223f55f80de72a6ef3822fa8fbd68eb397d06e2d76ddd35e0 a4167c7cee9b42172b42bc7744631224c41093fb6f302005fa44b703e7d4ac8900cca767d8d0b4a16bfab2c632d5f7ea +cbd6e305cc9f0dc90caee6e65a74582e9357bd25c78e33a7b14e1ac7e9397ff4466f192fb432143e6df6d61a0ab808ec0a361a6d95a357a38cd3e241fe03ed883ccc364b248ee2a08702110745c2688bdcefa33c1a45b9c8b200e45cddf3e3f66b8d37eff07fbb3366ea1558ef304085613c56707095724b3e134c7a7d3f8dbf 00860aa2b589f2defc617be73e191502e5d9952bf60547fef19eeccbca26 823b0eaff80c729c58328497d81a6eae3a434cbbacc8243ca3fd801c150c8cac8764a0c175c626dc797facc578bd6f2f +812a218ff1ee1472c189f63386e5b8ab341671c3a4dad27a8c6249d1c0f9a29338b471b6179f17a078b6504e804ac55ca3b13e68a623041bc1a092ea2adf3fa1124bbfeb161e6d7c483433f1548763b84da00352a6386e1339f674d45dab13898147ede468e0e01d2c4e0ed66b395a16cc3ded3e952ac739205f35a83376cbce 00d0dec052a00ccebd0c0c5d9a08272f75744a2582cec7ddd924a2b022b2 84e175c4ec7b6480b6ba15dee9ca338eeeab23e783d7077609ebc1e8f21d8c8b9b0e882a7feb87edcb928a2b49352b17 +0204b1fca831919e89e108cf140b3770f531a696b1d9a4d1fb68809eb10afccc257cc90cd36717c02b2f3d6d3d1d8a93cc5c48aa7ab9f9fddfe121ce9143376535a0c65e247c6558eac49fd1d6d1bf431ba918c471cb3d536ad485ec51f6471a340ac75f160c4c54cd3ffb9dcc123124b42df1fd2eaa005e3377c5d2d55938c6 008a017d717d6d1213f2b74c53281b07258738c0c7db649ea1ac46b9a3b6 89eff809144469b9a887ebdbff32e9d666ae7059b09ea54169359b53f31431bd7486ba4d0683837cdf94f1467b490b6b +2033eb48756638cb56e2cc39a3e775cfa11fce86cf71f04487dcdbc7f262bc8350a30ced54d1fcb697b28a6e96f88f782947c997872307ed963e1d68985f756435af77f57755cacbb4c6b50ed419deec9f39f0a549a13e54254fa0a5832dba2d943ad4aed8688889a2dd29dcb4ea12abd6a6c50eabcb3981c3a0c1ca5f0b9629 001b56c14442b084cfd22aeef0f8028ec57c8b571c9fc1e43de05c45e47f a4c421e72d1c8e5e1345400e668a25ff9bb01fcc2586e3f17202d74df75b2e6b1a70097af87a6d962f7d5b6172ffea3c +2986ab1cfe8873009e932dc68d4727d77ccbbf378e43fe4aa7c54416346b036b89c0aad1b82977c9fbc39a00f1dc916c0561d8dd70298c02b6cbfe572e0ef2058641e841c6875e8515f3c1082765e046c90c956d984b76e0e8e6eb433ce26c1757ac5b13422479141971c20102e9621d18f51096ae3173c2753facee2862d66e 005afce37c5594586ac46a34ae291f591eacb9880a7de92701977f447fbf 9367723a141eda6890f55993cb9a738c459dbadface635d11c3e67f2155f1d606c59d76ddfa8d9097e69fc8453e8696a +aabf5aa90ceef91c2155f90660adbcb0eedb996f5242cee15468ae217058ebeaad8cd4ff8cdc754a8ab85ba43c59fbab6386686fad5e27ad3848fe52191c7e4b203720841501792a625aef2acb6e36493b792fa55f253effca682946ad8c77e01f44e92ec3c258d0dd98d3183f4dc4a0bd3eca183794abd6232a6f9e4add8f57 000696df05dc7a54a9908a73eb18416a155cc8df4ab26032539d86eae537 862701f29acd0782197ccd08559d3bc71d5998d25a8df8e2cb89579c3c1d547d434e98288e42c5572e62ec14d466a303 +29ff209eabbde02b10b3fd559671fa53e418750c32c4a18d31cc0186d1077581bbefb8770ed079f536e866414a07431ae6633955bf42a2389b6f8a565d6e4ffb4444336e0030093876a26d4e3106e9ac697788e41f8a21c755eeb86a7c60f18e5e1069f16408a4c375a6a68d42959f2fab7ac09736c7b37c80c05897d8566ce8 005ca31e88c5b2e96e433af2023a66095161710628e7bfa428944d6676b8 b09068d3e81cbdc76f7af8a7de65315eec5d30b6a2e9dc2f9f0df491cbe1d62430a76b337b1823c5f5b6ccae218e35d8 +97765d876c80819f4004a36d09ccba78e600efc71eb7e869d3a00f658d2ace6769c7ab1ef590f41fb070aa8e08615e138df45ffbb6473d4a86ba5fdf17dd6dc9ea9ee19c0332563c99e6a3451c211d286d69102b47bfa6e07d468d9bde82e5c2063fb1ebbbed6086f542cf68ba46d4f214634afb1146dd5a6f3d50912ef5b824 00ef8fe84727a2ad8bf4e646ef28a492adfaf785a3a2ba6e6f985c649a8c a68d235dd033f26832a28d2020de90a0402d58ea53c224a00b7d1cc7464a86c7393b9a330d1d4a1d9670da1b3ea927c5 +21cf768d087d1e4eaa8a05e2008020e243116206d675c09be42ef2bc93617ecbb0575c873c6510ede9979215531b62126552738862fc4323d487992754e39d8f0d7e111e165ff254200e05082f59a57ef649bccaef6f980094fad3b7ef93bceb161760e200f0a2e396fbb6b6142dc84d872311bf932b84616b22231747937d58 003edb94b8c62f9af30c14a790c0f5d65e362a21cd8569b9725916d534c0 afd50e0030528753fee60c2557f0a4669aee32414fcf94adf994c161dac632d0605a8e47387a96d56986e699bd1494f8 +7b8e58eecdab3e40212bba6bf284f9379265b3d2baec3e4625aa08d0ced851da193c292ec793dab42732c07b4e94d8b19c83aed796a7e3a6c2b954a7a9a1ff9b2bd4ca62592c8b68f709f1ad38a5c8033ebb3f33d176945bfc68e9ef2b0cee2d45a13ce89d238a33c09ce2c0c63c4233aba5717b85c4c161dd7648a41a5e39d8 000a7519be62562318da1b67d22cf8e720353d22641e0cee11c7a352bb93 a514fc292101d2d082fca77a5096ddb20c4b146bbdf3ddedae5b44d00f2eb1347167540f6db25da0555cd533fcc4cc25 +f8f268d2b04fe47e5052c8d0d653787384b9654f0bd2138a6f52b80713feeed452b976a90eea4edcfbb62d04f3eafe172ddebd7cdc3701ecd6008e3d82e8eb217b13b5228839f61075159f3bd1e1409c08903874b6dfee2789dd72c208ae769ec8c7d52552a2b1fd73dad24de8b571f88e2184d0ee7d063a121187f97e746f2f 00264022fd7dc2328a6436b522793ad9406d7a586667a0daaf1bce927338 a22d9895828e9de64b8908ed6e334ada1b805bf7791405d1f6149cafea18c1672fbfea0f507699b7ce3eab6d4062806d +d288768cbd066fad4bb2500b5683fa9e4eaedfb3dbb519b083f6b802efda0a022355565c5fc6babeccb22f3adbbda450ce5d633193d1431e40c0fe631a295cf85965cd3f5937b31866bd6a5300eaef9941daf54d49832acfceed90e572ef34ccc94eacd0fd6b903fee3c572b963d21e2881656a214d2a4c125778dbe3bbeebca 00da43214e2efb7892cc1ccde6723946d2a8248a6b4d6c8872fad525ec3b 8a53cc4e19d1cdae1feaedc9625be272e887ca144845a7ea2ccd76ecafd59b72f322c7b92ad5e64eb36387e082d684da +bf0ab46e0a756c11229b0ea961f8d57218be5b00ab8b0e91d7664cdf5e0341c412c0e992d26ab12115197db39df2d1a6e18ed26a91be461432a2dfc21d98cb16003e339b0b0b1f100e4e6f4824ddac5442f22a1fac26326ed8a89cc91343d7223986d485cc8c64424e84d56be536c57e4dc5faee459b1958efd79e07e90a9811 00aeafa49d776b61f6a30d66ff64bd40dd8d79891dd5293c1b5cd3b46a7c a70b5c0cd2017b93fa9943dcb7a25184bd4a1e1c871432ab9c762c492329c2a8a5379d0159905b2e125334af2b064aee +c7b1eeb7c19eb16e7f42b61d79e421b71de797a6cab4e0baee522fee7acdb533f7bbf5855316544e1b82b4f2a18ad0a2311e7622549332122171f32fc62a90e408207e0fb90d1b052821dede9c41b15b6e07d84d5d7b9e31e6396a8ed229fb6232b3051298dc5321aa589f4e289d27169f14c8cc93644916d9b72dbc92c43488 00e95db309f4305b621f51f93588a2678cb19aad0932f365fa0aaa3a3895 a5e82ff15993994be2f23e01860a2b881d94e0de246b1034b14d9984fa74d39885ac697d64f190f3c58b73c8e8d2f8b3 +a738eb074e1f277dc665118ca055e6328059ab26da188c16f56384c566e43df8cff3d2a10d2d15c3c1406de8f734b20be5dd1ce937a4289f0ddfd7bddabd03586556eb8233b8feefedaa1f49bdec6d45fd562c2a83fa9fcfc2013bdd77900857199e51fa9c7cbeab925ba8f6c3c5fae46bf8e9c574b302f1e5f9c44400152a78 00d4319cc8e409b8755880827f3200d3f0f1c64d6356fe74eb1f5aa42499 b32b280090bfa9002d0ecd25cb7ca9673bb361c204787e730608ebf2a3b4f3fc0d985bd04463d71861a1918bee4da4fb +b28103d77e5457c42e026e713ea6ff03722a36512da17197140117442a976f9e2139c54a759fc26af5811b455e5a0d3a95362d9939c1e738045be9237b469ae2106ceed7e7842b44cc0a475d5af6d781e32ff1dd1f4e1833dbc7f82b27dc7e1562d0e29213fd8911105104a7a16f665b926aa137f70d868c90e72f8ee2c95b64 009e556c945052e5954915c773b2d47970c521fcc99139269c3ef46093b7 a473e2c28b70856e00cc7216cdc2db4e133f87e23e7a96a449ea912c424198d5c7398a85b6a1be6cedcc396a91425169 +463d04c84521ae671bb35c0a7acb3ae509b1b0470f39b8fe7ae5f3c9fbadbeb2bcc3a87e284cbdff07407a351f7ba743aeac50c4a1fef7375b90eb4af8ea2df040776bbf3e4389e7a80bea40530842642b9895ab9ef5ac8ed6c9ce7917d7b3ebcf80b801da845943313988c1970e7748cc306f914c37414f8247d648b580000f 00becc76f8a77615c4f92ae1f91645bf5bb908e75ef22fd544aae63a3c8e b308289dc9f083bf892515e972fd0c2cfacda26b8acf741f08f356a1df0b84c95baf0d3b726f62140ef461152846d965 +8b2379b5553ae7db6023cb010e26ae91322bc3f94dbaa369481936f90a886e5d3827d995ccf03ca59f46805fbac0337d31a8f117cc7044218a934d5bf507090e7e21178a7162c8fcb39111e6967803dbf9d752f3ae737ba024d0f4f7627e08be58efbe997a164106bfe37f67d2f19c0fcc7a6c7eebd96a72582a9c7bdf881896 0020572c2a3dc3ea430cd8cde9d642081c21658e8bda165550cd9a5d37d9 86519fd982782178879a9583f703416fcf6fd3b4ec9dc80f474330ea1d7a745d828b649122f842d0d418d357f86cecf6 +3090bf7373731cc44c00372c1ac59280b0f36e627ccf763fa68a7be37bb0ac8cbd4f70db54fc652566c78ad268f78f015e4bb1e41516fa56ac303a3bb4a52e1fe897d8338db5a6e37cad685e704b994504bd231c7dec0002dbd907a7ebfa809833e32eb23fffdb44fe4a18e11fa19d67356cfd703cf39a75b1a290b8a7c73afb 00769cfbf2dd8248ea1e0ac9b275c9d6ddcf923fe762079b9ed62ccbaa89 b0887dbf335f7a5b0c12c850e676c11adef83bb20b7d8fcec56a8db16f36162aeaedd81c64bc1f487b5385e1e0bc6cf3 +c37389cbe3f46eeebdda343e354ccd543e96b0c2a87e057aa6b9c4895a403de706d658bbc9066c140e50fef4b56af2db1f42efb70b8021254649983f1e11d04d6b10169d5a1c2093b6ab89227b88a30537c776bb7575749c3ed87bcb29effd8e4f17915b4d5dff6cab9678d88f33abead1e73dbdc5c3307ff3d3b2d5fd7bfa83 0040ea4a37b388f0cc464f7e2bf92173107b268ff77a8acf5f517b4ec0e4 a3e8d79055ac621552fa18afb5656c6f9f0bd9cb07bd7201115a65598e81b243c9f56eb91c33f4b871b1c4067f3c799f +8884def8c3b9c5f856b9c2352c85ea71aae3c8d0e84ca74e70e404a21467159fc9826548d16dd1ec5a75dc2c23ca37b30312f25e1194e0f9385a0499db34c855412bbf58979ffce7fc3afeb7b8dbf9898df44023200d809f520db99eae315b5cf85674fab008a20340fae8f6974034fd3e55bf08c5522a460680218f9757e368 0037fc7898df9b37b5390537352f5c0b8de22659166c19d7d4df31c3938d 87371f5ae66b1c6a2c8f7ecbb9ad09005d3181256fe72adfd88456086f19cebced9e9dc091450f8a81c51a5dd24f43cb +f1fc154d469433f56c2bd42aa52237a4a4bfc08fb6d2f3f0da70a62f54e94e3f29c629c837e7adf0474fa8f23251b9b349a16848942c0d9cf5db1d0fd99527020dbe21cf0b94a9aa21f376bf74da72d36f87b306b0696771efa7250c6182b426a4500ac14de4a1804b38db8d4f3beefb8c9bb619ac82cb63fb37c2e1d22951f7 005d5069425e7a9925d2cfc6360a708147b2c1b55ede243591885147ef3b ae77a586e8b73c3d016b91c2d6e348f490a3d1a4c7b6a1c2647a2df77041ff25916f5bd01708053f246669443b7a172e +885cd348f7983a0721f96c0e866821223d3e5a95178b16d18652b4062b1b2278aed6f54ab06f7e37ae6ce1020aa3eb812d215194bcd212302da5b971fd86aee1dcb23057dbedb569bd0bbef80df538da69ae2358cb03bb77c64d3ead475c8c5ae5bfbdd75684b421a26f1a7b0c37548fa32d805acdc91230dd70a48232a12846 00ffe3e7b82ca62b96e057ee072a4718ca20a6cc9a3e51e4fe8ed7b4b9f9 938735b32a5026893cad81cf84d5e7c6b8ee12f6059897f179695cc94fe2091b469b7ed23b8122fda28cc56e1d30b3f6 +ca3b0e2f1c7db4e73c699f06e432bb0f63705ba66954bec4a259bf31c161bb4861476e2f2f7dde9d841d1ea6bd0990cc793cd7a10432e38735c3eeda7a0d786e8821239bdd6c4972c96c2cf68ec5b935391f963a50fe16af2719c9029943b539ff0f1f5645962a6ac46c75d2037fa0c7cd46deadcdfc66e1ddcaada3a376acbf 0007a9cb5ce27c763646de414ca2a4dcdb774d69ed2bde7a817baddbc9de 892ae280d7355bcdaf63d176cb5ccee67d2bc490b15256039072bb9dd195357b8d31257b7758e9a418f13595d843916b +4b0a31b746763beee77cecd318b90acf50fac4172cf4bfb354e5a440f651cb89d7a515e09ab19e9850803ab9167c2aee3b395a5da10dc9aff799d73756dfb0a9961d93bc32f15a96bf13962a03d5bd42ddc8b5928def7fc48fb063f42866fc5f96cf88fe0eb125b7c01906ad6a7fdade28ccb0a421ceff50ae03a974671b2c27 00c03fa9e38dc1c697f70bc6381f2bacaf860bb5632fc837f728da959ac9 8c1a332e7d914abce0b9add0386e66eaf70ecc1d30e6fde69090a06197fe8250f1286cf50d21155b3bc27fe1ddc3e017 +3011d42792b21c0f1719faf6f744d576f72c5fdfd22b1a520d0e8d47e8c2b06823d853b13c9fa039fa30a6f2e3e27bb2100c6a35f55703806bbf0f79b09d0f629f8042ec63fa04062f15f2edb92b19237980005566f02bb12a40b4ec66e4ba6c599d928b33f72d7437c0e399a8e6a9068d1fef24917fc4f9ab5464ea6684dde9 0087dba00e3fe4802e01718017510094924496bd2785d4ac1a352c530473 a0c3a69c149e90720285f150471da4ab6c3c7e14412dee292f4e63b44a567757380ad602b8e26893235f9c49f87439c9 +05a5d3a3b79f4e51b722e513620c88092a9bb02408f5f52a32e782fd4923f4fd3094fc5536caf4b645d830260eba91b5173f3833dd65600fb9e246aec968b1f6ebdfddb4059fb2de7e636ed60bb7affdb74aefd158e54485d5f26be373cf944c6570daf8fd7e4b77fad57300667d6decf5c65db99ab8763bb4ecbb09fdf47e3a 005a387e7affc54a8fbb9157b5ebd400c98e2d7bd5c3e095538987d4f8d9 a39f0684c0197d81232d5495cc9f328c04d1fbf65bde0ce0d9b0787aaf0f703ec4de3a618e5d4f45a82aae46e689d0d4 +247a101c8196eb93a440280650ad463795690bc620e46e8118db6900a71eb493d03fbcf2f73a79bb47aa8e2d8c87ef70e4cfae36fae5c45fe247d8cd0f7d0718dad106526945014b4f3bec324897d8e1fa2f457b8a68e61873b7fa0350fde3b87b7b001c13953c2050a24f71fb77eb455053e49200ebcbba7299485c0f1a40db 00adae709a930d6f5a5c0e3d8ef4aab004d741d23f0ffb8287f7059890c0 b02ca40963ef2d567cdef25ae3d3eecb712c2bd400cc2581438c76efd8bc7512e865d7a4aab16d5a314624ee909eaaea +a16678c71976a3ce3362ca379b3272b92e8ca7085b43752473db34e4d6b61eeed3875f49f3328366fc9d0644824e0104817de458e4c1036636b18b83dbaf063f2f99818959224906571c7b28873d9c702360888df151e9ad1a7003e6130033203acf8a69889be6ebd90816f2abf0764f10be68653b1e56766ecc3150bef8b042 0035d391411e6d679751092c4ea5a079c591e77ebdcb57c1d9006ae70d90 81d4c37cb72222a735f281f6e0e322bd9773b72b5eb7ce3efa4129537b00707114127a1c2c4a33b1d240530fe0638d72 +bc2f080a7f0b69a6b142b8f3fb481a43bd71d07418df4f3b802568073c1a8d35729ad197f34a4e941a6dd511c63f201d1f6c34a1b66545bd5f43508c10bda1d6ef60ee5bdd25dde975e50c61f76cd36d50ee3bd8dfa2dff59524db9ef12f1e28d109b552cb42f021963f559c843476b5c889fc567b7840297c5a480e18c221dc 0084e79093f1947d6ab9cf399782436e36ef87c59a4c090930c9a74ddb10 85470ea6e641ac1f356ede6c7c753c274ea6959f6078d56f3ee21308ab470b47336a7302c9c65452a5c52813e489cd0f +ea71cede8b63ddc5648eb244184bae265cd65d50f77a9e25ff93f02b132487c08732544cb88936d4fff7c0fedb39685822dd1c9be1158f647c605c9bb5f6a1ae34722fa08882c14b36b6c93cab33c9a269c7c10f755b6453ed045ea3e56f29e95a9404ba189a0b48848120392b4dcac43148b706c3d9e4c03db410cbe5dca3da 0079b6be015b8006f86fd81c2792bec6b42c08bee2d295cf9dc214c326ab b658a01f272ad0a2d2bdd01ce8f087754e5444734a2c5783e2e6fa0cbc2409390550322f82ec75a4bc817b6a5aa20db6 +319b41d16e18059a1324c37161c937e882192cd949c420ce9c59208a0ac208ebb06f894a7fd78df2a3c5f23f25dee6595d3dacb25a699f115dd482ccd36fc54ba29dda279335424c86b07a1b1fa76a5411bcecaf4d37065b229cdce0bac75b666c6626ec37a716e9841be93c907f87453ad91d36846561f284421a89013b88c3 00ca9d751a060fde64336cdc88122819f4b3cd1b4e7df42d495197787894 98b311c75451c5e7c7b0e88dd69e5a71e1a01b0f0f87146a7a34a42fd5d9c332760eea0c7127d195a84106b738a36d6e +aebeee215e7b3d4c3b82db243a47506ffbf2263f6fe9de5b69286e8649d9218367c36ba95f55e48eebcbc99de3e652b0fecc4099714ee147d71b393de14a13e5044b1251e40c6791f533b310df9e70a746f4c68c604b41752eca9ce5ce67cdc574a742c694ada8f20b34d0eb467dce5566023f8533abfa9688d782646420c77b 001dde4b2d49338a10c8ebf475b3697e8480227b39bc04253a0055839e9e ab9f939c4ebb52b42bd6f25425bfe3df38d92bb772584d729cc01cf961196e3065a4cbad8295ceebc164e53af9080221 +8d353a6b6f35590baef59b638914d3e934d0145b045d221d846517ceddc8ff5e3d28826d3459f8ce1260f705e80923f39abc73d5949aa7aa8ad1734be0e992bff0c9a8f4cc9bdfa430d4cf52e29d3737b0cd3231b72b16e15e1a9040b832e4a920b4a1d94c4964ac6c8abb75bbbdb10825f882ae44c534c7154c446421a04d87 002c8bea2803fd746c874fa110a716538c179c82712f38d33d0f6d037e7a 87a192b04ca2c5df8303cb2571b92149601293528e62a4d51c259f225b31c3436eca4e3e873a7c393b880a89d1ead8a5 +847f134b90f10ba3636ec24f36a94111f26d58428fda5bba4501e58c7bb55809f52320cbe9e0df55af1e40bbac9f3eaa26a55d78b60621d4356d090d98363662f406367601eaa9eb9568b1a1b319730bad7bf6a7ddf1b45eb6922faf8d065c540b671c50df758ebf8c4aca6f01878e5e0012dd038c58833e2b13ebdb9a9f3fc3 00b9119b3b4b30cbfb98ddf0a4f6953417e515fcf0e5a94e83ebc1d1d14d 8fabf6eb3d843f2a98b68a04aad92cb0cbe9a7a92389bb4f7ae3028bbdd3cff49ab3839f14017645ad01a72aa7b0c762 +99d23950493bdd931915e9f9b65e4cd1329866c0071a19d4f7d6fd190689275b7b10fc07503dd1c27a4da274dbeb3aa5cb0e71e9b7b03fc2697729b7be913756e6760098951d7015df181cf14b1e0b954e6260276af553e3e59907794b863e941950718ef154669c5c262946ba120892e0239e05910c2194f712db46e37e53b7 00f4ab2a573f3771d1e4222e251faf14e06cefed544e804c299c9a8395f5 835e03f57b6a0fe7f50c66f567760bc5c0fc0d6435e6dec5820e1d6293b0343c08328c5c80a05c4047eafa89a3dbc386 +7bef2487bc2bbbcbcc1570bbd4ed437c0dbcbbf63f666a3355aec49ea6ef593da25aefe9ae0d94db50692475425dee3c88cdea975794ac69142c25732f3541457d68d9101c8be069f2b515aadadea2019dc7abefa6c12cb3f76d9f4b5e46546f77eaf636aa8f2329130922111151a4df913d18b7cf9d0308f01ad84d878adde7 00f4649cf30d4a5269296a45977de2652cb06d3ca2aff4475bb24517b927 abcd59a507195b839649365c114c76b0e69534bb4f202584b6e3683a84e0dc03c55dfb7c4c365c36c76cd1fc08ea2446 +87c717eef6dd3c7434b2c91de05723783bef603d170f654b49a04b067b077c405d2d757ce780101b930196ca4261efcfbd3fc1ebb762cc0eecf101072988aca508c41581936526d3f337053000dcf77b16172492c5d654c6612bbd2523a6ad5966d7091697a29ce882fe331f79a7eb59e5a3fe536263083cc59b8133bfd33c1d 00cca24ad914c24c011f41f80d27ea41caf41fcc8dc9dc6dff5248b2b474 abde93cefafd2859f4dd455aaaa66017cc82571ab16dd36b8a991092fb0996f04039207b1751f24a059131d22b07a65a +9bf48c2aebf473b3a4a928b3b6a4d2fb7e9193c9e60bc2067f9f03083a8cc7b892bdbf05601118bcc34dd283e7be996bf19b0bd36727eb9d65276b6517bf0c77ae0a9091e7a9e46182a2586eb22324939801034e5ba94ba30d1bde7d8fed51eb71036fab6224f8ff30a008422efcff7ea239ff23b9f462777e62b41b396c5dc5 00f5e12d536ef327e3b0ba65ac5fc3f7f4880f5968f3340eb8868c1d47da 8693362ae8e756ab6b15d9104a2d7060274c011e204e42f7f17b83e1397bbd88ea599f1a4961568dbfb09441cf995d2a +716d25519ae8f3717da269902be4a7566d6f62b68cd0faae94bce98c8a4ac6f66215ebac5407d6f64adf9d53f79f02e50921b6f0e8c805926a839443d30d9294eaa802faa7c5471d81fd1db148cdc621a8dd0c096e06fb0b71943337d5325e1bca77062684873fe904ed9012474ceae5b138e079f941a665a995026d13d7eed9 008c30d93536b8cb132277645021775d86c2ba8f199816c7539d560ac6de b29090eb0abf1b9dd941610a8b21ccd7987a35a06ba1983a60cf306e54d06ab8b19b2da8f7247d6e7af889f664efd3d4 +01e76755007b2ee5ac9e1d4c8adabad6d0f9c1c08ac6e2622b7c1ead89bd3ad0921b9525b49a780a262fe8fc0904a80391717ad7cac9607de55f7c744af8a132ec45ce79723f4a4a8c8b9ef658b360bd3890df164c9f1cd74eafb74feea251a34514ff2a57ae7a6d4bec2067cbf6ee4fdaabf13721bf9ae178b9034ac5e9665b 00fa3f15a506ccf7b50bbbad0a54d3223f5a95eb54f0d1f4e5d0cc21469b 90cd0a35013d306fe329157180c30a1d1803b40630cf7baa60723f42abed812c89b74e63239c5236faaa56068d879cec +e95abeeb2c51a8cb75ab74253dbe130b5560cd52e2a63d501d26e1458aa568aca6694be91eee5fdfcf582c47c1c727084ee2b2c810281cf9b095808bf7e7c668eff00a6e48b06df3fe6a445e092c24d5687d7d89acc8063275caac186c441bc697b2f67aa71b03294e1adeb7e557c296dd91304ba0587cda3c984619f1eb4f2b 006400a4830889115aa88b860b3fb65905b01fd126c4aec2785518c2543a a0acf23d7cbe8ef1811a89d92f27696f3a86a8beb8e92ac7fdfcbb6c5e4cb5d49384ac5a7cac6843764d1acd90acdecb +bb8d8515365d240b2071daef0d80558fd3d0e059be9f6abb7b7a0a5f47e2ddca7d1b3b5101d5c583143258520ce8db0a87f877a395615c9bf879ef46f2f20f68bbc9706f82781fad69019396b27f292cdc70fff1772e90205a2225f80889f9daece1d03914d8776ac5bad24d8fb190ba10a2ca17768b918c2e079d83734eb372 00c7b73c324250f14fac0edc941f79bdbc6933ee8f64bf94b847bee5eef6 b804803aafe89114604dffa0d3bc2c99b8a8a777f10c930e8f1b63dea65334a4b66513c50e3c41cd1c671326caf9ebaa +cd8b2403435fac9caeffa21b55eaba52d7efee0f89df7142340cdffeb89556303ca01a800429397e2ff6c746743b6bc60a87133274282d4cac02e4ca90ad95d80c93b84163b96296f67d40b2a1124b2b6534ab6b60fdee312fbcdf468d0e84eb85fce4ff360136bb31ced3998d29cfaa3ae685e638ee272058f123c4f35f8b6b 003db7f28e161abf52ab0adc8c4c8544fc989af081303b8688f22b7b2eb7 a7186c7829719b015282ecd0acf451872b20372c9a21db0405489c2aefe199f196cc78a32cb599acfe6f1f2a1cf24a0c +4bb08eeb202564efb5bda40777d71f1bcc4c7c10b611e803e5c570876f3e319e9e2bc2d32031c56a32fc0d1fcf620d4e4377d881e9e1695bcdb78acba370b849115b86c1c4b83edfa03299da8e7fd14c7cadb81a8e4911c8e427e32c8c9b67e317575331967cf58085cff0c0d48ee0b8e7dc0b49687bb1c70c703a5dad08ec81 007e9d2fdd017d6da6029e88f78927d9ac9437f542db1f1fa99e32bfcf1a 9919e54123b86cd6195876c339997a9809915d17721954910eb1ce4a098184bcf450bd36cac7616ed795cc3e721b08b5 +0bce683d835fe64e6484328aa13e18b0956f6887b5e4442fce36ff09aed015889794e79da8aa60b4be565c78685674c51e1e7ac60db6a763c777198a56e382a03aff8b40862f961ae23e8b8683b76a5577769422418972ab0049119382edde9e752b42e8b93f403c1ef8665d7ce8530ce4ed9ebf6d397827cba6b7645e177231 00c94052760fc74c2b405ee4dd5dd2a7d38ebc16df9cc32df706075450b5 880a6b4047aa7ba1a68b3454be0d7257e4782fa1676a841adb7d78f906b9c997296676665082c6ac76fdc75ee604ed68 +a6defc770426daad4dafba3bbd2a69881334f7c31269b297e440926db54cdad3fd7ad200f5ada2b72ad221ad99a06ecac9c2563a8deed89f0d0896991d1a652f6fa282affefbdb1c1985652300d1792725071631d75a182b683a48448063c7d2563ec3d430e0fd3acea33a35cd38ec0b5b07af96af71d0bfcd879d9864ededf3 004076b93487c2da8aeaeb4725fb53b7b41b465315335c18c6ca041175b4 ab997957ecef9d2a275f100c538173e908f5b197616e808fa67e7dac4824ab2092c51cb09ca9a570e648532f666ebe22 +7803cdf4758c199962b62943f475c6c31356f5d9b997a12e21146a2399cd0dd3b97a860b2ce639e2801571599136d4a8cdbfb12fd1a5ce22374991e090533ff42823a2c58d2076b772814eea7fd7a1fde68263ef912681c72c7aa3e5a7cc44ee8c65e72228b7631e600121ea35bfbbc783b6ae3c0c8f80198ada218be533760b 0076ddd73ee4fc1f5e6766e229cc7236cdfce312417ea291f7c3328d5ab1 91cd61d092f1b53d45da19e7be0ca8eb9beaad2424004339045f5b20d0e856d19d0e6cdc9d78f30c17d291444489965b +e789461e1dad0b6e21abeb6ae2e96385549d1bae39415188c8f833233da6a3328144c97ddb36e0ff4d9e19d84f869e79e609c51b32de59892fb0446dd28cc164a3e53534c950d26f87fb74e682db2038cde778bde06c3ee2eca2a077d8fcc2b0332e352e0e7e6487444a8ad60e78ff213b16fda9faf374dc6d27b7a3c4c6d196 007e1f8988ad804aae7d09a99be19384cc599e7652c02c391542be74b17b 8392225faf5f440a3614ef0f3daa329c121eba69bd24b7d27c9bdbcd98dcfcc62827a86b06e5ef252aa3e0f6213dfe4d +9b58c145d1b6c887f2b25fb672cd49c3a1117224be697c15182d4048be92968a6500f8bcf747fcf33145c13a8d72e891a6e0c4c7310c2b62f3181bf586fe32f1ecf4feee8c2c8bf6c2bfdf9d5f88981ce080095c93e49a772d8e7b59f9cffccec3ca2f212ef4c6748f64e224f4f098334d83108bf6f8c7b43c5eb549f1526897 009b2292b0244c2aabe8b43d95039984d504ebe05eaff318760e4dee739f 94b8fcd55535473817d188930d1c0a24f20503a9475a4370327cd238d73f4f70c6f90780004643abce1b7ee01ec08464 +52310a901fe9681a23dd6e02f12974d57f2c4f653322d9a0ff8b338cc6c2bd9f4765c90c6b3c9fb17df3f492e67d204e39d81a8fdeb92c852a1dcc6151ed6c63049037235c6751c9a902748163a567b714725b4d3995e0edbde03215c645b1a1da3147f7406245432800c50f823a1f991c863427ff4c68e4e16d1b106ee40dd9 007ca463b50fdd92d9163f1c2bdfce2ee45ba1437b79162e3e959b814cab 8cd27d35df3b27bde3ce36e42f2154b412faf8a6fab68ea827c93e38460bd7aeb618cfe4bf724ad52cda83d790ef3b05 +ff419c011601cfaf833067cf28dbe6e935ebeddf8b5111a97f6eebf3bb28376334f329cd877a134b074790a073db766efe018fce666a34650cbac285ae856fb6b3b8b96877282bc11cd9f9c8e510ed1f69bc2725a44a1d2b35de1edfd8bc9d20c7525ab0bbc27662a7cfc1bbd1e0f4fce5b88411521e3893e027cc8c73acdabd 00c3844750f63fe0c2e930bc38fe88522f4e72a2fd0db9778ade20e939b3 82a686fea3b8a006f21b2d0dd31289ed9ff0a55be1f180dea7110ddeb72f113be33ccbfa04ada1726e57173d1e649be1 +05a89c4824c5de66587875011e704bc6e06e991ba8f3aed331cfffe55aa266a08c729f77b8d082dca4d286b2d451ea838d726cc2cf298fddf2d7376714c5e37b64506f353917caec525a1209391449c078c5197a371feade74f8fc8a1a1d67576edfda13c14ad324342fc0b09277941dc072ec0d39434ff1cb91fc59478fcde7 00a3bea235dea86506be4476eb7999dcb8e584a34238c4a894ad6823b93f a7575c6edc27ad5db53547c377f811a81cbe0fab6e667be38a1bdeb843db3480d12a0358ecc6d5ec48661ed3887a3bc3 +13e6b5241365d9d0ef9e8b05cabb3248afd221ec02eab92284b98bda3d9272184bfe5251d35705defba5085381430e99b33a3ab77d7870e5102757d065862372df2434a25556b76e54ebc39d4e6c3aba5cd6acf0c335756f7d9385c1068d4cfa37526a9a58c0ccc7f87a8189176c5d4f201499236058ec061357dcdb5acdba40 009a367cd1cffd8dfcca179e167ea437ee48e9b6f42559dda9224701d3f6 90930c740e22c5aa06c526d851f4b9aa412e08507b0e25a34e21b465e592c76c45cec8505efa272c6eb47819da5947a2 +139a1a5090b97afb8fecfff8745efacf7dcf91a4393a7b629564e598d58d5be39c05c5830d4c8ca85d29e9e2c31ad0447864e867d0ef4788ac734f8d871daebceda98d449308c2afbe97724c3af8a468f1925065f39e52ba4b7d15728a744b1252a20476dcfff7bcb82aa72c209e72abb3c24419bc26191390ffed340c1b9c6f 0046f4ad2522e78b9b35297d28f361fb0ce82306322aedc119251d8241be a5686d22d4026bf5c59a78e843a3e6daf790e42258e17833b049f0b84387b9cdd3f641bd9e2b40142d773a2e16c6d515 +3315e5cda5f252e3291b61e493ab919c20a8af1286d9660cfa2f5ca38b6defe19ebecf820787fe692d04eae8a5f5d37abfb593309569cedf45efd0cecef6951b718924c8380ba52e8ab8c9bfb2261ed5f01cc5a5f9fc5fcdd269a0f122c597afdd9a836cf8f96838c3e8962c1788c3ce4128719b3ef4fc88569643dcad6da16f 00ac82137e9c7a5ecfb8b1a7df9ab50732934566a392a6c8915ee8ca8144 95127c3d4c0f6a32618c25bd84a552692ae038798eb83efd03a24d69e87e2a69596a0bdcc26e22a1250892c27d547524 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B233_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B233_blst new file mode 100644 index 000000000000..7bd198c437c0 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B233_blst @@ -0,0 +1,60 @@ +f1b67fde01e60e4bb7904d906e9436a330c5cb5721fd4e0a3c75b83dade868736bb1d21cfb1b5c6407c373e386ee68ec2239b700e763728eb675a153b8ac44cf2a87be85fe8ed6683430cf4b7d718891cbf8d583d0a37cc952cc25fe803a7aa4fda80f05541a2f1f2601cdd0c095f7110f2a84f7d641b8531572269b21cbe77b 0056673197bfeea9bd7a8b820b4ae51a50411bf118a692bb9ed3d304da53 91b0b92bd2e10e552ec32a667d6c8a4cdfcd77a402053203062c142c121b442b3891391cefa8dfbeae66e94a2989c5d6 +1d496d96b533c632ed6a91f6e3653cdffaa5b8cc0008b35e49b2dd52fe261105c2ec7ee71a4ad5d51fdc3d36d688a3b7ccb3b3b0c3a65be17b8d8aa172e3005cfbf37a2d1b1a6e268c090c6f318e7e96f9ec9b9f5a8fbcc7558d89e840f7e76e44bed91c26ca48e6f5cbc253ca2fe8cb81c484cabd24070e488f9c00cd96ad4f 00468f01d483144e514ec257f2e5fdee28a927f2adb19714c1f3524dd0d3 882c9f6de90dcc8fbbf07768b241e309635fd080226fd626905410d531e5fc051c865abf055d6cb91bf67cdd13d8fc6d +723400655027f474446843645757f7e2cd466bf97275067b4bc4c9d79bb3b19b2421835d69db916f24b77c381fa771fc1e7a19d2b4d09411ae55acccc615b16fd24705762b441ab67083a921fd4ae569ce0de69449aa96f5b977ac7dc022fdc8335656853796f54b3fbd118577f98920624eb0a00204f1ef83827245c06646cc 0074052d027f05465a8083a59cdbf32600224e1f563f653b34314651517f 99ad870e0376236c6ff4b59208625317443bafe1bce6e12f18a5a314f69e257af33f462abd0b5f0c91df7411956a3e59 +155860cb31a142082bcc0bad828d747e916392d21f1873b3a3c1d28ca3ff9d45ddb66a712e3856b6afd07c8d2b2a7badab296a9775b03f6fec0befa2d8d6d00fe3938df244ab46e836a3e686c8b4f918da49f0bb3940bba34a9aa22c7caf02df7758b0de01d9f47af6146344b9be3842d9c055eaf0fb399cd8db95c544a62d8a 001856e7544223f55f80de72a6ef3822fa8fbd68eb397d06e2d76ddd35e0 a4167c7cee9b42172b42bc7744631224c41093fb6f302005fa44b703e7d4ac8900cca767d8d0b4a16bfab2c632d5f7ea +cbd6e305cc9f0dc90caee6e65a74582e9357bd25c78e33a7b14e1ac7e9397ff4466f192fb432143e6df6d61a0ab808ec0a361a6d95a357a38cd3e241fe03ed883ccc364b248ee2a08702110745c2688bdcefa33c1a45b9c8b200e45cddf3e3f66b8d37eff07fbb3366ea1558ef304085613c56707095724b3e134c7a7d3f8dbf 00860aa2b589f2defc617be73e191502e5d9952bf60547fef19eeccbca26 823b0eaff80c729c58328497d81a6eae3a434cbbacc8243ca3fd801c150c8cac8764a0c175c626dc797facc578bd6f2f +812a218ff1ee1472c189f63386e5b8ab341671c3a4dad27a8c6249d1c0f9a29338b471b6179f17a078b6504e804ac55ca3b13e68a623041bc1a092ea2adf3fa1124bbfeb161e6d7c483433f1548763b84da00352a6386e1339f674d45dab13898147ede468e0e01d2c4e0ed66b395a16cc3ded3e952ac739205f35a83376cbce 00d0dec052a00ccebd0c0c5d9a08272f75744a2582cec7ddd924a2b022b2 84e175c4ec7b6480b6ba15dee9ca338eeeab23e783d7077609ebc1e8f21d8c8b9b0e882a7feb87edcb928a2b49352b17 +0204b1fca831919e89e108cf140b3770f531a696b1d9a4d1fb68809eb10afccc257cc90cd36717c02b2f3d6d3d1d8a93cc5c48aa7ab9f9fddfe121ce9143376535a0c65e247c6558eac49fd1d6d1bf431ba918c471cb3d536ad485ec51f6471a340ac75f160c4c54cd3ffb9dcc123124b42df1fd2eaa005e3377c5d2d55938c6 008a017d717d6d1213f2b74c53281b07258738c0c7db649ea1ac46b9a3b6 89eff809144469b9a887ebdbff32e9d666ae7059b09ea54169359b53f31431bd7486ba4d0683837cdf94f1467b490b6b +2033eb48756638cb56e2cc39a3e775cfa11fce86cf71f04487dcdbc7f262bc8350a30ced54d1fcb697b28a6e96f88f782947c997872307ed963e1d68985f756435af77f57755cacbb4c6b50ed419deec9f39f0a549a13e54254fa0a5832dba2d943ad4aed8688889a2dd29dcb4ea12abd6a6c50eabcb3981c3a0c1ca5f0b9629 001b56c14442b084cfd22aeef0f8028ec57c8b571c9fc1e43de05c45e47f a4c421e72d1c8e5e1345400e668a25ff9bb01fcc2586e3f17202d74df75b2e6b1a70097af87a6d962f7d5b6172ffea3c +2986ab1cfe8873009e932dc68d4727d77ccbbf378e43fe4aa7c54416346b036b89c0aad1b82977c9fbc39a00f1dc916c0561d8dd70298c02b6cbfe572e0ef2058641e841c6875e8515f3c1082765e046c90c956d984b76e0e8e6eb433ce26c1757ac5b13422479141971c20102e9621d18f51096ae3173c2753facee2862d66e 005afce37c5594586ac46a34ae291f591eacb9880a7de92701977f447fbf 9367723a141eda6890f55993cb9a738c459dbadface635d11c3e67f2155f1d606c59d76ddfa8d9097e69fc8453e8696a +aabf5aa90ceef91c2155f90660adbcb0eedb996f5242cee15468ae217058ebeaad8cd4ff8cdc754a8ab85ba43c59fbab6386686fad5e27ad3848fe52191c7e4b203720841501792a625aef2acb6e36493b792fa55f253effca682946ad8c77e01f44e92ec3c258d0dd98d3183f4dc4a0bd3eca183794abd6232a6f9e4add8f57 000696df05dc7a54a9908a73eb18416a155cc8df4ab26032539d86eae537 862701f29acd0782197ccd08559d3bc71d5998d25a8df8e2cb89579c3c1d547d434e98288e42c5572e62ec14d466a303 +29ff209eabbde02b10b3fd559671fa53e418750c32c4a18d31cc0186d1077581bbefb8770ed079f536e866414a07431ae6633955bf42a2389b6f8a565d6e4ffb4444336e0030093876a26d4e3106e9ac697788e41f8a21c755eeb86a7c60f18e5e1069f16408a4c375a6a68d42959f2fab7ac09736c7b37c80c05897d8566ce8 005ca31e88c5b2e96e433af2023a66095161710628e7bfa428944d6676b8 b09068d3e81cbdc76f7af8a7de65315eec5d30b6a2e9dc2f9f0df491cbe1d62430a76b337b1823c5f5b6ccae218e35d8 +97765d876c80819f4004a36d09ccba78e600efc71eb7e869d3a00f658d2ace6769c7ab1ef590f41fb070aa8e08615e138df45ffbb6473d4a86ba5fdf17dd6dc9ea9ee19c0332563c99e6a3451c211d286d69102b47bfa6e07d468d9bde82e5c2063fb1ebbbed6086f542cf68ba46d4f214634afb1146dd5a6f3d50912ef5b824 00ef8fe84727a2ad8bf4e646ef28a492adfaf785a3a2ba6e6f985c649a8c a68d235dd033f26832a28d2020de90a0402d58ea53c224a00b7d1cc7464a86c7393b9a330d1d4a1d9670da1b3ea927c5 +21cf768d087d1e4eaa8a05e2008020e243116206d675c09be42ef2bc93617ecbb0575c873c6510ede9979215531b62126552738862fc4323d487992754e39d8f0d7e111e165ff254200e05082f59a57ef649bccaef6f980094fad3b7ef93bceb161760e200f0a2e396fbb6b6142dc84d872311bf932b84616b22231747937d58 003edb94b8c62f9af30c14a790c0f5d65e362a21cd8569b9725916d534c0 afd50e0030528753fee60c2557f0a4669aee32414fcf94adf994c161dac632d0605a8e47387a96d56986e699bd1494f8 +7b8e58eecdab3e40212bba6bf284f9379265b3d2baec3e4625aa08d0ced851da193c292ec793dab42732c07b4e94d8b19c83aed796a7e3a6c2b954a7a9a1ff9b2bd4ca62592c8b68f709f1ad38a5c8033ebb3f33d176945bfc68e9ef2b0cee2d45a13ce89d238a33c09ce2c0c63c4233aba5717b85c4c161dd7648a41a5e39d8 000a7519be62562318da1b67d22cf8e720353d22641e0cee11c7a352bb93 a514fc292101d2d082fca77a5096ddb20c4b146bbdf3ddedae5b44d00f2eb1347167540f6db25da0555cd533fcc4cc25 +f8f268d2b04fe47e5052c8d0d653787384b9654f0bd2138a6f52b80713feeed452b976a90eea4edcfbb62d04f3eafe172ddebd7cdc3701ecd6008e3d82e8eb217b13b5228839f61075159f3bd1e1409c08903874b6dfee2789dd72c208ae769ec8c7d52552a2b1fd73dad24de8b571f88e2184d0ee7d063a121187f97e746f2f 00264022fd7dc2328a6436b522793ad9406d7a586667a0daaf1bce927338 a22d9895828e9de64b8908ed6e334ada1b805bf7791405d1f6149cafea18c1672fbfea0f507699b7ce3eab6d4062806d +d288768cbd066fad4bb2500b5683fa9e4eaedfb3dbb519b083f6b802efda0a022355565c5fc6babeccb22f3adbbda450ce5d633193d1431e40c0fe631a295cf85965cd3f5937b31866bd6a5300eaef9941daf54d49832acfceed90e572ef34ccc94eacd0fd6b903fee3c572b963d21e2881656a214d2a4c125778dbe3bbeebca 00da43214e2efb7892cc1ccde6723946d2a8248a6b4d6c8872fad525ec3b 8a53cc4e19d1cdae1feaedc9625be272e887ca144845a7ea2ccd76ecafd59b72f322c7b92ad5e64eb36387e082d684da +bf0ab46e0a756c11229b0ea961f8d57218be5b00ab8b0e91d7664cdf5e0341c412c0e992d26ab12115197db39df2d1a6e18ed26a91be461432a2dfc21d98cb16003e339b0b0b1f100e4e6f4824ddac5442f22a1fac26326ed8a89cc91343d7223986d485cc8c64424e84d56be536c57e4dc5faee459b1958efd79e07e90a9811 00aeafa49d776b61f6a30d66ff64bd40dd8d79891dd5293c1b5cd3b46a7c a70b5c0cd2017b93fa9943dcb7a25184bd4a1e1c871432ab9c762c492329c2a8a5379d0159905b2e125334af2b064aee +c7b1eeb7c19eb16e7f42b61d79e421b71de797a6cab4e0baee522fee7acdb533f7bbf5855316544e1b82b4f2a18ad0a2311e7622549332122171f32fc62a90e408207e0fb90d1b052821dede9c41b15b6e07d84d5d7b9e31e6396a8ed229fb6232b3051298dc5321aa589f4e289d27169f14c8cc93644916d9b72dbc92c43488 00e95db309f4305b621f51f93588a2678cb19aad0932f365fa0aaa3a3895 a5e82ff15993994be2f23e01860a2b881d94e0de246b1034b14d9984fa74d39885ac697d64f190f3c58b73c8e8d2f8b3 +a738eb074e1f277dc665118ca055e6328059ab26da188c16f56384c566e43df8cff3d2a10d2d15c3c1406de8f734b20be5dd1ce937a4289f0ddfd7bddabd03586556eb8233b8feefedaa1f49bdec6d45fd562c2a83fa9fcfc2013bdd77900857199e51fa9c7cbeab925ba8f6c3c5fae46bf8e9c574b302f1e5f9c44400152a78 00d4319cc8e409b8755880827f3200d3f0f1c64d6356fe74eb1f5aa42499 b32b280090bfa9002d0ecd25cb7ca9673bb361c204787e730608ebf2a3b4f3fc0d985bd04463d71861a1918bee4da4fb +b28103d77e5457c42e026e713ea6ff03722a36512da17197140117442a976f9e2139c54a759fc26af5811b455e5a0d3a95362d9939c1e738045be9237b469ae2106ceed7e7842b44cc0a475d5af6d781e32ff1dd1f4e1833dbc7f82b27dc7e1562d0e29213fd8911105104a7a16f665b926aa137f70d868c90e72f8ee2c95b64 009e556c945052e5954915c773b2d47970c521fcc99139269c3ef46093b7 a473e2c28b70856e00cc7216cdc2db4e133f87e23e7a96a449ea912c424198d5c7398a85b6a1be6cedcc396a91425169 +463d04c84521ae671bb35c0a7acb3ae509b1b0470f39b8fe7ae5f3c9fbadbeb2bcc3a87e284cbdff07407a351f7ba743aeac50c4a1fef7375b90eb4af8ea2df040776bbf3e4389e7a80bea40530842642b9895ab9ef5ac8ed6c9ce7917d7b3ebcf80b801da845943313988c1970e7748cc306f914c37414f8247d648b580000f 00becc76f8a77615c4f92ae1f91645bf5bb908e75ef22fd544aae63a3c8e b308289dc9f083bf892515e972fd0c2cfacda26b8acf741f08f356a1df0b84c95baf0d3b726f62140ef461152846d965 +8b2379b5553ae7db6023cb010e26ae91322bc3f94dbaa369481936f90a886e5d3827d995ccf03ca59f46805fbac0337d31a8f117cc7044218a934d5bf507090e7e21178a7162c8fcb39111e6967803dbf9d752f3ae737ba024d0f4f7627e08be58efbe997a164106bfe37f67d2f19c0fcc7a6c7eebd96a72582a9c7bdf881896 0020572c2a3dc3ea430cd8cde9d642081c21658e8bda165550cd9a5d37d9 86519fd982782178879a9583f703416fcf6fd3b4ec9dc80f474330ea1d7a745d828b649122f842d0d418d357f86cecf6 +3090bf7373731cc44c00372c1ac59280b0f36e627ccf763fa68a7be37bb0ac8cbd4f70db54fc652566c78ad268f78f015e4bb1e41516fa56ac303a3bb4a52e1fe897d8338db5a6e37cad685e704b994504bd231c7dec0002dbd907a7ebfa809833e32eb23fffdb44fe4a18e11fa19d67356cfd703cf39a75b1a290b8a7c73afb 00769cfbf2dd8248ea1e0ac9b275c9d6ddcf923fe762079b9ed62ccbaa89 b0887dbf335f7a5b0c12c850e676c11adef83bb20b7d8fcec56a8db16f36162aeaedd81c64bc1f487b5385e1e0bc6cf3 +c37389cbe3f46eeebdda343e354ccd543e96b0c2a87e057aa6b9c4895a403de706d658bbc9066c140e50fef4b56af2db1f42efb70b8021254649983f1e11d04d6b10169d5a1c2093b6ab89227b88a30537c776bb7575749c3ed87bcb29effd8e4f17915b4d5dff6cab9678d88f33abead1e73dbdc5c3307ff3d3b2d5fd7bfa83 0040ea4a37b388f0cc464f7e2bf92173107b268ff77a8acf5f517b4ec0e4 a3e8d79055ac621552fa18afb5656c6f9f0bd9cb07bd7201115a65598e81b243c9f56eb91c33f4b871b1c4067f3c799f +8884def8c3b9c5f856b9c2352c85ea71aae3c8d0e84ca74e70e404a21467159fc9826548d16dd1ec5a75dc2c23ca37b30312f25e1194e0f9385a0499db34c855412bbf58979ffce7fc3afeb7b8dbf9898df44023200d809f520db99eae315b5cf85674fab008a20340fae8f6974034fd3e55bf08c5522a460680218f9757e368 0037fc7898df9b37b5390537352f5c0b8de22659166c19d7d4df31c3938d 87371f5ae66b1c6a2c8f7ecbb9ad09005d3181256fe72adfd88456086f19cebced9e9dc091450f8a81c51a5dd24f43cb +f1fc154d469433f56c2bd42aa52237a4a4bfc08fb6d2f3f0da70a62f54e94e3f29c629c837e7adf0474fa8f23251b9b349a16848942c0d9cf5db1d0fd99527020dbe21cf0b94a9aa21f376bf74da72d36f87b306b0696771efa7250c6182b426a4500ac14de4a1804b38db8d4f3beefb8c9bb619ac82cb63fb37c2e1d22951f7 005d5069425e7a9925d2cfc6360a708147b2c1b55ede243591885147ef3b ae77a586e8b73c3d016b91c2d6e348f490a3d1a4c7b6a1c2647a2df77041ff25916f5bd01708053f246669443b7a172e +885cd348f7983a0721f96c0e866821223d3e5a95178b16d18652b4062b1b2278aed6f54ab06f7e37ae6ce1020aa3eb812d215194bcd212302da5b971fd86aee1dcb23057dbedb569bd0bbef80df538da69ae2358cb03bb77c64d3ead475c8c5ae5bfbdd75684b421a26f1a7b0c37548fa32d805acdc91230dd70a48232a12846 00ffe3e7b82ca62b96e057ee072a4718ca20a6cc9a3e51e4fe8ed7b4b9f9 938735b32a5026893cad81cf84d5e7c6b8ee12f6059897f179695cc94fe2091b469b7ed23b8122fda28cc56e1d30b3f6 +ca3b0e2f1c7db4e73c699f06e432bb0f63705ba66954bec4a259bf31c161bb4861476e2f2f7dde9d841d1ea6bd0990cc793cd7a10432e38735c3eeda7a0d786e8821239bdd6c4972c96c2cf68ec5b935391f963a50fe16af2719c9029943b539ff0f1f5645962a6ac46c75d2037fa0c7cd46deadcdfc66e1ddcaada3a376acbf 0007a9cb5ce27c763646de414ca2a4dcdb774d69ed2bde7a817baddbc9de 892ae280d7355bcdaf63d176cb5ccee67d2bc490b15256039072bb9dd195357b8d31257b7758e9a418f13595d843916b +4b0a31b746763beee77cecd318b90acf50fac4172cf4bfb354e5a440f651cb89d7a515e09ab19e9850803ab9167c2aee3b395a5da10dc9aff799d73756dfb0a9961d93bc32f15a96bf13962a03d5bd42ddc8b5928def7fc48fb063f42866fc5f96cf88fe0eb125b7c01906ad6a7fdade28ccb0a421ceff50ae03a974671b2c27 00c03fa9e38dc1c697f70bc6381f2bacaf860bb5632fc837f728da959ac9 8c1a332e7d914abce0b9add0386e66eaf70ecc1d30e6fde69090a06197fe8250f1286cf50d21155b3bc27fe1ddc3e017 +3011d42792b21c0f1719faf6f744d576f72c5fdfd22b1a520d0e8d47e8c2b06823d853b13c9fa039fa30a6f2e3e27bb2100c6a35f55703806bbf0f79b09d0f629f8042ec63fa04062f15f2edb92b19237980005566f02bb12a40b4ec66e4ba6c599d928b33f72d7437c0e399a8e6a9068d1fef24917fc4f9ab5464ea6684dde9 0087dba00e3fe4802e01718017510094924496bd2785d4ac1a352c530473 a0c3a69c149e90720285f150471da4ab6c3c7e14412dee292f4e63b44a567757380ad602b8e26893235f9c49f87439c9 +05a5d3a3b79f4e51b722e513620c88092a9bb02408f5f52a32e782fd4923f4fd3094fc5536caf4b645d830260eba91b5173f3833dd65600fb9e246aec968b1f6ebdfddb4059fb2de7e636ed60bb7affdb74aefd158e54485d5f26be373cf944c6570daf8fd7e4b77fad57300667d6decf5c65db99ab8763bb4ecbb09fdf47e3a 005a387e7affc54a8fbb9157b5ebd400c98e2d7bd5c3e095538987d4f8d9 a39f0684c0197d81232d5495cc9f328c04d1fbf65bde0ce0d9b0787aaf0f703ec4de3a618e5d4f45a82aae46e689d0d4 +247a101c8196eb93a440280650ad463795690bc620e46e8118db6900a71eb493d03fbcf2f73a79bb47aa8e2d8c87ef70e4cfae36fae5c45fe247d8cd0f7d0718dad106526945014b4f3bec324897d8e1fa2f457b8a68e61873b7fa0350fde3b87b7b001c13953c2050a24f71fb77eb455053e49200ebcbba7299485c0f1a40db 00adae709a930d6f5a5c0e3d8ef4aab004d741d23f0ffb8287f7059890c0 b02ca40963ef2d567cdef25ae3d3eecb712c2bd400cc2581438c76efd8bc7512e865d7a4aab16d5a314624ee909eaaea +a16678c71976a3ce3362ca379b3272b92e8ca7085b43752473db34e4d6b61eeed3875f49f3328366fc9d0644824e0104817de458e4c1036636b18b83dbaf063f2f99818959224906571c7b28873d9c702360888df151e9ad1a7003e6130033203acf8a69889be6ebd90816f2abf0764f10be68653b1e56766ecc3150bef8b042 0035d391411e6d679751092c4ea5a079c591e77ebdcb57c1d9006ae70d90 81d4c37cb72222a735f281f6e0e322bd9773b72b5eb7ce3efa4129537b00707114127a1c2c4a33b1d240530fe0638d72 +bc2f080a7f0b69a6b142b8f3fb481a43bd71d07418df4f3b802568073c1a8d35729ad197f34a4e941a6dd511c63f201d1f6c34a1b66545bd5f43508c10bda1d6ef60ee5bdd25dde975e50c61f76cd36d50ee3bd8dfa2dff59524db9ef12f1e28d109b552cb42f021963f559c843476b5c889fc567b7840297c5a480e18c221dc 0084e79093f1947d6ab9cf399782436e36ef87c59a4c090930c9a74ddb10 85470ea6e641ac1f356ede6c7c753c274ea6959f6078d56f3ee21308ab470b47336a7302c9c65452a5c52813e489cd0f +ea71cede8b63ddc5648eb244184bae265cd65d50f77a9e25ff93f02b132487c08732544cb88936d4fff7c0fedb39685822dd1c9be1158f647c605c9bb5f6a1ae34722fa08882c14b36b6c93cab33c9a269c7c10f755b6453ed045ea3e56f29e95a9404ba189a0b48848120392b4dcac43148b706c3d9e4c03db410cbe5dca3da 0079b6be015b8006f86fd81c2792bec6b42c08bee2d295cf9dc214c326ab b658a01f272ad0a2d2bdd01ce8f087754e5444734a2c5783e2e6fa0cbc2409390550322f82ec75a4bc817b6a5aa20db6 +319b41d16e18059a1324c37161c937e882192cd949c420ce9c59208a0ac208ebb06f894a7fd78df2a3c5f23f25dee6595d3dacb25a699f115dd482ccd36fc54ba29dda279335424c86b07a1b1fa76a5411bcecaf4d37065b229cdce0bac75b666c6626ec37a716e9841be93c907f87453ad91d36846561f284421a89013b88c3 00ca9d751a060fde64336cdc88122819f4b3cd1b4e7df42d495197787894 98b311c75451c5e7c7b0e88dd69e5a71e1a01b0f0f87146a7a34a42fd5d9c332760eea0c7127d195a84106b738a36d6e +aebeee215e7b3d4c3b82db243a47506ffbf2263f6fe9de5b69286e8649d9218367c36ba95f55e48eebcbc99de3e652b0fecc4099714ee147d71b393de14a13e5044b1251e40c6791f533b310df9e70a746f4c68c604b41752eca9ce5ce67cdc574a742c694ada8f20b34d0eb467dce5566023f8533abfa9688d782646420c77b 001dde4b2d49338a10c8ebf475b3697e8480227b39bc04253a0055839e9e ab9f939c4ebb52b42bd6f25425bfe3df38d92bb772584d729cc01cf961196e3065a4cbad8295ceebc164e53af9080221 +8d353a6b6f35590baef59b638914d3e934d0145b045d221d846517ceddc8ff5e3d28826d3459f8ce1260f705e80923f39abc73d5949aa7aa8ad1734be0e992bff0c9a8f4cc9bdfa430d4cf52e29d3737b0cd3231b72b16e15e1a9040b832e4a920b4a1d94c4964ac6c8abb75bbbdb10825f882ae44c534c7154c446421a04d87 002c8bea2803fd746c874fa110a716538c179c82712f38d33d0f6d037e7a 87a192b04ca2c5df8303cb2571b92149601293528e62a4d51c259f225b31c3436eca4e3e873a7c393b880a89d1ead8a5 +847f134b90f10ba3636ec24f36a94111f26d58428fda5bba4501e58c7bb55809f52320cbe9e0df55af1e40bbac9f3eaa26a55d78b60621d4356d090d98363662f406367601eaa9eb9568b1a1b319730bad7bf6a7ddf1b45eb6922faf8d065c540b671c50df758ebf8c4aca6f01878e5e0012dd038c58833e2b13ebdb9a9f3fc3 00b9119b3b4b30cbfb98ddf0a4f6953417e515fcf0e5a94e83ebc1d1d14d 8fabf6eb3d843f2a98b68a04aad92cb0cbe9a7a92389bb4f7ae3028bbdd3cff49ab3839f14017645ad01a72aa7b0c762 +99d23950493bdd931915e9f9b65e4cd1329866c0071a19d4f7d6fd190689275b7b10fc07503dd1c27a4da274dbeb3aa5cb0e71e9b7b03fc2697729b7be913756e6760098951d7015df181cf14b1e0b954e6260276af553e3e59907794b863e941950718ef154669c5c262946ba120892e0239e05910c2194f712db46e37e53b7 00f4ab2a573f3771d1e4222e251faf14e06cefed544e804c299c9a8395f5 835e03f57b6a0fe7f50c66f567760bc5c0fc0d6435e6dec5820e1d6293b0343c08328c5c80a05c4047eafa89a3dbc386 +7bef2487bc2bbbcbcc1570bbd4ed437c0dbcbbf63f666a3355aec49ea6ef593da25aefe9ae0d94db50692475425dee3c88cdea975794ac69142c25732f3541457d68d9101c8be069f2b515aadadea2019dc7abefa6c12cb3f76d9f4b5e46546f77eaf636aa8f2329130922111151a4df913d18b7cf9d0308f01ad84d878adde7 00f4649cf30d4a5269296a45977de2652cb06d3ca2aff4475bb24517b927 abcd59a507195b839649365c114c76b0e69534bb4f202584b6e3683a84e0dc03c55dfb7c4c365c36c76cd1fc08ea2446 +87c717eef6dd3c7434b2c91de05723783bef603d170f654b49a04b067b077c405d2d757ce780101b930196ca4261efcfbd3fc1ebb762cc0eecf101072988aca508c41581936526d3f337053000dcf77b16172492c5d654c6612bbd2523a6ad5966d7091697a29ce882fe331f79a7eb59e5a3fe536263083cc59b8133bfd33c1d 00cca24ad914c24c011f41f80d27ea41caf41fcc8dc9dc6dff5248b2b474 abde93cefafd2859f4dd455aaaa66017cc82571ab16dd36b8a991092fb0996f04039207b1751f24a059131d22b07a65a +9bf48c2aebf473b3a4a928b3b6a4d2fb7e9193c9e60bc2067f9f03083a8cc7b892bdbf05601118bcc34dd283e7be996bf19b0bd36727eb9d65276b6517bf0c77ae0a9091e7a9e46182a2586eb22324939801034e5ba94ba30d1bde7d8fed51eb71036fab6224f8ff30a008422efcff7ea239ff23b9f462777e62b41b396c5dc5 00f5e12d536ef327e3b0ba65ac5fc3f7f4880f5968f3340eb8868c1d47da 8693362ae8e756ab6b15d9104a2d7060274c011e204e42f7f17b83e1397bbd88ea599f1a4961568dbfb09441cf995d2a +716d25519ae8f3717da269902be4a7566d6f62b68cd0faae94bce98c8a4ac6f66215ebac5407d6f64adf9d53f79f02e50921b6f0e8c805926a839443d30d9294eaa802faa7c5471d81fd1db148cdc621a8dd0c096e06fb0b71943337d5325e1bca77062684873fe904ed9012474ceae5b138e079f941a665a995026d13d7eed9 008c30d93536b8cb132277645021775d86c2ba8f199816c7539d560ac6de b29090eb0abf1b9dd941610a8b21ccd7987a35a06ba1983a60cf306e54d06ab8b19b2da8f7247d6e7af889f664efd3d4 +01e76755007b2ee5ac9e1d4c8adabad6d0f9c1c08ac6e2622b7c1ead89bd3ad0921b9525b49a780a262fe8fc0904a80391717ad7cac9607de55f7c744af8a132ec45ce79723f4a4a8c8b9ef658b360bd3890df164c9f1cd74eafb74feea251a34514ff2a57ae7a6d4bec2067cbf6ee4fdaabf13721bf9ae178b9034ac5e9665b 00fa3f15a506ccf7b50bbbad0a54d3223f5a95eb54f0d1f4e5d0cc21469b 90cd0a35013d306fe329157180c30a1d1803b40630cf7baa60723f42abed812c89b74e63239c5236faaa56068d879cec +e95abeeb2c51a8cb75ab74253dbe130b5560cd52e2a63d501d26e1458aa568aca6694be91eee5fdfcf582c47c1c727084ee2b2c810281cf9b095808bf7e7c668eff00a6e48b06df3fe6a445e092c24d5687d7d89acc8063275caac186c441bc697b2f67aa71b03294e1adeb7e557c296dd91304ba0587cda3c984619f1eb4f2b 006400a4830889115aa88b860b3fb65905b01fd126c4aec2785518c2543a a0acf23d7cbe8ef1811a89d92f27696f3a86a8beb8e92ac7fdfcbb6c5e4cb5d49384ac5a7cac6843764d1acd90acdecb +bb8d8515365d240b2071daef0d80558fd3d0e059be9f6abb7b7a0a5f47e2ddca7d1b3b5101d5c583143258520ce8db0a87f877a395615c9bf879ef46f2f20f68bbc9706f82781fad69019396b27f292cdc70fff1772e90205a2225f80889f9daece1d03914d8776ac5bad24d8fb190ba10a2ca17768b918c2e079d83734eb372 00c7b73c324250f14fac0edc941f79bdbc6933ee8f64bf94b847bee5eef6 b804803aafe89114604dffa0d3bc2c99b8a8a777f10c930e8f1b63dea65334a4b66513c50e3c41cd1c671326caf9ebaa +cd8b2403435fac9caeffa21b55eaba52d7efee0f89df7142340cdffeb89556303ca01a800429397e2ff6c746743b6bc60a87133274282d4cac02e4ca90ad95d80c93b84163b96296f67d40b2a1124b2b6534ab6b60fdee312fbcdf468d0e84eb85fce4ff360136bb31ced3998d29cfaa3ae685e638ee272058f123c4f35f8b6b 003db7f28e161abf52ab0adc8c4c8544fc989af081303b8688f22b7b2eb7 a7186c7829719b015282ecd0acf451872b20372c9a21db0405489c2aefe199f196cc78a32cb599acfe6f1f2a1cf24a0c +4bb08eeb202564efb5bda40777d71f1bcc4c7c10b611e803e5c570876f3e319e9e2bc2d32031c56a32fc0d1fcf620d4e4377d881e9e1695bcdb78acba370b849115b86c1c4b83edfa03299da8e7fd14c7cadb81a8e4911c8e427e32c8c9b67e317575331967cf58085cff0c0d48ee0b8e7dc0b49687bb1c70c703a5dad08ec81 007e9d2fdd017d6da6029e88f78927d9ac9437f542db1f1fa99e32bfcf1a 9919e54123b86cd6195876c339997a9809915d17721954910eb1ce4a098184bcf450bd36cac7616ed795cc3e721b08b5 +0bce683d835fe64e6484328aa13e18b0956f6887b5e4442fce36ff09aed015889794e79da8aa60b4be565c78685674c51e1e7ac60db6a763c777198a56e382a03aff8b40862f961ae23e8b8683b76a5577769422418972ab0049119382edde9e752b42e8b93f403c1ef8665d7ce8530ce4ed9ebf6d397827cba6b7645e177231 00c94052760fc74c2b405ee4dd5dd2a7d38ebc16df9cc32df706075450b5 880a6b4047aa7ba1a68b3454be0d7257e4782fa1676a841adb7d78f906b9c997296676665082c6ac76fdc75ee604ed68 +a6defc770426daad4dafba3bbd2a69881334f7c31269b297e440926db54cdad3fd7ad200f5ada2b72ad221ad99a06ecac9c2563a8deed89f0d0896991d1a652f6fa282affefbdb1c1985652300d1792725071631d75a182b683a48448063c7d2563ec3d430e0fd3acea33a35cd38ec0b5b07af96af71d0bfcd879d9864ededf3 004076b93487c2da8aeaeb4725fb53b7b41b465315335c18c6ca041175b4 ab997957ecef9d2a275f100c538173e908f5b197616e808fa67e7dac4824ab2092c51cb09ca9a570e648532f666ebe22 +7803cdf4758c199962b62943f475c6c31356f5d9b997a12e21146a2399cd0dd3b97a860b2ce639e2801571599136d4a8cdbfb12fd1a5ce22374991e090533ff42823a2c58d2076b772814eea7fd7a1fde68263ef912681c72c7aa3e5a7cc44ee8c65e72228b7631e600121ea35bfbbc783b6ae3c0c8f80198ada218be533760b 0076ddd73ee4fc1f5e6766e229cc7236cdfce312417ea291f7c3328d5ab1 91cd61d092f1b53d45da19e7be0ca8eb9beaad2424004339045f5b20d0e856d19d0e6cdc9d78f30c17d291444489965b +e789461e1dad0b6e21abeb6ae2e96385549d1bae39415188c8f833233da6a3328144c97ddb36e0ff4d9e19d84f869e79e609c51b32de59892fb0446dd28cc164a3e53534c950d26f87fb74e682db2038cde778bde06c3ee2eca2a077d8fcc2b0332e352e0e7e6487444a8ad60e78ff213b16fda9faf374dc6d27b7a3c4c6d196 007e1f8988ad804aae7d09a99be19384cc599e7652c02c391542be74b17b 8392225faf5f440a3614ef0f3daa329c121eba69bd24b7d27c9bdbcd98dcfcc62827a86b06e5ef252aa3e0f6213dfe4d +9b58c145d1b6c887f2b25fb672cd49c3a1117224be697c15182d4048be92968a6500f8bcf747fcf33145c13a8d72e891a6e0c4c7310c2b62f3181bf586fe32f1ecf4feee8c2c8bf6c2bfdf9d5f88981ce080095c93e49a772d8e7b59f9cffccec3ca2f212ef4c6748f64e224f4f098334d83108bf6f8c7b43c5eb549f1526897 009b2292b0244c2aabe8b43d95039984d504ebe05eaff318760e4dee739f 94b8fcd55535473817d188930d1c0a24f20503a9475a4370327cd238d73f4f70c6f90780004643abce1b7ee01ec08464 +52310a901fe9681a23dd6e02f12974d57f2c4f653322d9a0ff8b338cc6c2bd9f4765c90c6b3c9fb17df3f492e67d204e39d81a8fdeb92c852a1dcc6151ed6c63049037235c6751c9a902748163a567b714725b4d3995e0edbde03215c645b1a1da3147f7406245432800c50f823a1f991c863427ff4c68e4e16d1b106ee40dd9 007ca463b50fdd92d9163f1c2bdfce2ee45ba1437b79162e3e959b814cab 8cd27d35df3b27bde3ce36e42f2154b412faf8a6fab68ea827c93e38460bd7aeb618cfe4bf724ad52cda83d790ef3b05 +ff419c011601cfaf833067cf28dbe6e935ebeddf8b5111a97f6eebf3bb28376334f329cd877a134b074790a073db766efe018fce666a34650cbac285ae856fb6b3b8b96877282bc11cd9f9c8e510ed1f69bc2725a44a1d2b35de1edfd8bc9d20c7525ab0bbc27662a7cfc1bbd1e0f4fce5b88411521e3893e027cc8c73acdabd 00c3844750f63fe0c2e930bc38fe88522f4e72a2fd0db9778ade20e939b3 82a686fea3b8a006f21b2d0dd31289ed9ff0a55be1f180dea7110ddeb72f113be33ccbfa04ada1726e57173d1e649be1 +05a89c4824c5de66587875011e704bc6e06e991ba8f3aed331cfffe55aa266a08c729f77b8d082dca4d286b2d451ea838d726cc2cf298fddf2d7376714c5e37b64506f353917caec525a1209391449c078c5197a371feade74f8fc8a1a1d67576edfda13c14ad324342fc0b09277941dc072ec0d39434ff1cb91fc59478fcde7 00a3bea235dea86506be4476eb7999dcb8e584a34238c4a894ad6823b93f a7575c6edc27ad5db53547c377f811a81cbe0fab6e667be38a1bdeb843db3480d12a0358ecc6d5ec48661ed3887a3bc3 +13e6b5241365d9d0ef9e8b05cabb3248afd221ec02eab92284b98bda3d9272184bfe5251d35705defba5085381430e99b33a3ab77d7870e5102757d065862372df2434a25556b76e54ebc39d4e6c3aba5cd6acf0c335756f7d9385c1068d4cfa37526a9a58c0ccc7f87a8189176c5d4f201499236058ec061357dcdb5acdba40 009a367cd1cffd8dfcca179e167ea437ee48e9b6f42559dda9224701d3f6 90930c740e22c5aa06c526d851f4b9aa412e08507b0e25a34e21b465e592c76c45cec8505efa272c6eb47819da5947a2 +139a1a5090b97afb8fecfff8745efacf7dcf91a4393a7b629564e598d58d5be39c05c5830d4c8ca85d29e9e2c31ad0447864e867d0ef4788ac734f8d871daebceda98d449308c2afbe97724c3af8a468f1925065f39e52ba4b7d15728a744b1252a20476dcfff7bcb82aa72c209e72abb3c24419bc26191390ffed340c1b9c6f 0046f4ad2522e78b9b35297d28f361fb0ce82306322aedc119251d8241be a5686d22d4026bf5c59a78e843a3e6daf790e42258e17833b049f0b84387b9cdd3f641bd9e2b40142d773a2e16c6d515 +3315e5cda5f252e3291b61e493ab919c20a8af1286d9660cfa2f5ca38b6defe19ebecf820787fe692d04eae8a5f5d37abfb593309569cedf45efd0cecef6951b718924c8380ba52e8ab8c9bfb2261ed5f01cc5a5f9fc5fcdd269a0f122c597afdd9a836cf8f96838c3e8962c1788c3ce4128719b3ef4fc88569643dcad6da16f 00ac82137e9c7a5ecfb8b1a7df9ab50732934566a392a6c8915ee8ca8144 95127c3d4c0f6a32618c25bd84a552692ae038798eb83efd03a24d69e87e2a69596a0bdcc26e22a1250892c27d547524 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B283 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B283 new file mode 100644 index 000000000000..c572af319697 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B283 @@ -0,0 +1,60 @@ +067f27bbcecbad85277fa3629da11a24b2f19ba1e65a69d827fad430346c9d102e1b4452d04147c8133acc1e268490cd342a54065a1bd6470aabbad42fbddc54a9a76c68aceba397cb350327c5e6f5a6df0b5b5560f04700d536b384dd4b412e74fd1b8f782611e9426bf8ca77b2448d9a9f415bcfee30dda1ccb49737994f2d 0299ff06e019b5f78a1aec39706b22213abb601bd62b9979bf9bc89fb702e724e3ada994 b522f8315b3fc66d775440aa3ad644e8a5b00d735c659b2d131b7ffced7d3c49ed1a343988fbbf6960eaea9a575ff937 +44adcb7e2462247b44c59608cbe228ada574ecb9f6f38baf30e42b589fb9b157bb0560e5a2aa5523b71cc0d7f583b502bec45d9b8352f29ee1842f42a17a5b16136feaa2efa4a0ae306402940ecd6b71e57d1467c98e7960de2a97f88b43487e4f4016af1292381d70c18c7e6eed99a14cdeb5b3caf73688658e4c5b54c81e08 009c2804f8cab768248fb3fff8a055b3f4585c00de5c1615a19f9425b9432ea09afba8f2 b271a842becc9a1f058d84a2324d6f0ccd393b3598205eac4746bb1eea2de88a37960006095551acd3bebf9fbad3b538 +cffee6252c7eb6d91d8fe100a1e62f0ad9f862d78ca2b747a6c17b8c9ea8980dc239b3b673310e6e7483582399163e39d889abc1a613fe77849ebc09b4f7f4fe0688b8a9869ae918a88294c7ee199be50ee9460db14725ae70b449d0cb48f30e7d817ec02c0cd586119341dba0b74f0279330807cfccc99c8c340b72c1764a45 02e625a6bc6d0ce7c06231de827068bdb0abc8ffb57c82b35ee3a0f873b9473905974d34 88efce488d983094f76c805ab5f08ed1005b9dc8d227feec796539ca210a33df5140fdf41685f1b924f4b25e221b39bd +d058ab5dc07228253707ef224897ea0fcd09c3d5cc91fdce9e03c1c59c53fb4596be2ed929c7455e67ac7f4891aed3eb06ad88f2c4aaaabff045b959f900d1019d706b60526375851bb891494e99995928e4cd51c9616aa651ec77bd7e398916bb9ed3156391bf7fb1e29181e2b011dae2edaf803607def2ac6b194929a57f45 0376ac24e1b86f8a55c052d92a0bdc6472fa03acdcdbccbf7c321ec0ccd97aa0a66b4181 a4334c91513fd62bda2ad2772631f8635460b315b50d29a3aae765f1eb10bf09bee28f0679f0fc24d0ccf80131f8dbaf +c86f2cc7ab5df5cf1a236fd83792769474cef464032800ffe98a44cf29dbfb6f24088160eb31a11a382ff2a49f3e05e983462f5304272f96c0a002b69af3d233aebe867ee63fa46666760a6889d022c18645b491f8d71b6a3b6b4ef058e280cf625198715b64b025bf0449445d3dd7e1f27153926e617bd2c96638345431d1ed 02b50a6395fc02b9ac1841323de4520292f913519bc0d6a471aa28021322fc4dbcd7b802 820b5bb2c23d9a8a062084eb9ffdaca01004ea602a26ed268c414707dc45b7c7ed4f7ade77f9ca47ed5d9acdf9dfda7a +c1328d8d2e5b6ffc850a9600bd6482518ddd9cee3fc9140febb72bcd444b0cd7e8074587d51b62cce4b3d4f34ad3355353fabe363369cf790db2df9fdac3a0ec4757e2dfb3b683eaa3e26531691ce765742e1c0bdc0e1028d347b6085fc459df0989c6a144271454eaffe413cae2ad7c8b2371fd2df1afffe56df727009765a2 024e5889722f6c35e18ca47effa9e415b1ba790066a91fb3c9f7b001ce28fc732b09bc23 98719acb18f5e51b88801605f7716e71b34a32b614be74dd825aa2bc8db45c16d8dc1e04f5c23eedc052c8257110bc20 +7176b7013ea27e94281977eacb976bb31c753bf80fa09680a29128a6fc15234f79f0e9900aff3217ce9be72c378042c6c34fced0158740073d1a985fa25987fb218002e425868fda5a47de51abfd04de34e2b8634cebfbdc98e80f93d94096193eaa82dc8778fc23f3765c7acdad94fdaa272df0ff0f28190c10a462ee78ac92 0056d15b81f40b6378588a5efe43e21b95e18120d514bfdda0e7759a1d0766a8a35ce5ac a0f637c751766ab8d38958c3788afc83f0ec0f39b4dcb12995ec9118341eba4a701acff414bfeb9181219e0cc20a8a77 +4c3642ba040a9955b9d50dcd1c936688c17c363854358afa8ca49c6abd906dfdc4d89bb4cab0bbc363fb5b74e1f004d4b09ec9dfeed4c0bfb482a9061a1f487a3d79195ff7b65a0504bced3a28db0ebe8fcf8ab1ee4a3ae91324d15d890ac4c479144dd5538d2e36d3a587769ee9cd2d5c6f85a03362a022fe0efc4a3902b71a 012fb2fb5bf5f7e42a500154823a174ba2d05af71e3b0cf47fab46e673ea1822f1563def a77104386a51a804bd86a4f7c4c8ee9b709cc81437e9d56b264b5a0987519af62c8b7ee5ac9bb89c93520bec5d407335 +e471f39c18b081362adc7da47dec254dab8d765f005ac574640d78c14222639245563912d942f3be212ee3cef134407334c8fe3602fa0e1629de5331643d76715dc1b0ffcebd484d86c5211be4b285a31688b205fa988e6c15b36daf396ccdcc209c7dde2a732f5c31c84c7ea041408ebf15e56632583af0131bd7f531b5fc45 030096c54fd480647e017f8cdbbdef292e799f054e3279d228b09816a757566a744a8266 80e572455fe832c8557da7e193201957220465a6aa833d51b0ba4564d5eda08b250565d0ff2714be35a1a9ae5d053f11 +8a93fe53e83075c4025228540af7e96a588520da34e3eadeb99a4ab2f3dbbb8f85fe63a3b86c1f4ec912e665ca05b43e869985eae3791b91205afb1380e16c25b74e6793fa63e4a55dcf25dc22d03f09deddeb9042b620434111afe08c5657c7d754af66ad91a1b5423301b1e8e6389a1404060d1b6a99fe0f89598482979e42 00a1b7e9c8c2dc25b494b5ef3195b294e41cd3c2c35235ab42542bd3e2a52d5826662bf9 93e877a9640af3e10c494d3f69d0b53cb046f42d4201c9e1ffd264c75e3aacb876530c44a24c7cb6f65bd187ad93fff2 +e193a8ef6f454ca1aed38bb67aca6d08280d421b196d89938c0582b7cde74dafd71716f3818940af412d4a7ff3960a8517aee108ae03576b68ee7557d35e6f1ab823d124de7243dd02b542591f62c80d822608572889573e4c9dc62f99d68e07800da6f83cb6f5e03d1f2ac15f90e38b4f25e0a75e354e4b60cc81c0bbe81d39 0059b1a8fb84530bba7a607ee88310e31bc6ea6a6881603567a1081a05a3a9ff87e719ef b0bc915f89f1442a96ca50a28d2848066ba26963d6b0e1ac8cb209b33c6d9961ea9ef0e1e79f11aae218eebccac65f2f +8a99b9db191f6cabc88b430bc2293e6774d5180f019d871839289e25aec29379f14606e742190b7aa062e3b29fe0254146d9614856c5140c7315015abb98ac00da2c7e33cbcc82c24b797366f12767322c4381454d9d1eeaedb616b0ea5c66d1422da459f18081f4f966d05ce279c6ee69b1bf94b8388d38d4b770d9ed69025f 030ddc2c7a4ce300cc2b75f0f977033f16c1f8bb13aae3d494c381f9a6dc8622499ae4df a42a34386229da1a5bac7cfe1bdfd0926fe185e88f8a7daf8bb53ce7762436aa1f840a3fbbf54f5e01d6fa4cbd6b3a98 +5c437b331831530aa94623b1736f00b986172699f0a02a5e5df0008bf25341787e2e66046f2c929dfe0058c3cb89fc5bebbe1025bb1edd1ee31522ed568e7b5b4ca3991afdc76a68cbc2c4f81863e27fdaf6a564fab2c6354e5c657de81390f8a4132669fd24a48580c716b5b7961a9c091f614d11cf45dfdaec8946a54a11d8 007899928922fbfdb5407517725edf231d15a8b62d90b7fb6d8c8d20424850dc44f797ed a80338e0259be7b2f25ddc42d91238121180cc8c0415497b36f12049319f97fc3b38f1533365b45dce947847142f400f +91aa08567d8da4c90684dc06068f69deae240212842ff1786f04ec41b40d9187aa92c76401f9fcedced62876a34df82ad7c1e63b68bb2a972257ea8542bda6a7f1a020c9b122943b6d651abda8b8d322a8fb762eee376daa2d3637a71ed6c4f5cf96f61c0da2d6e1dda3370d80e51da2cbd8aef3267168c67359523faf910dfb 02a2af63d1171930758bd3e5bfdac62cca1a83a3b55a49b3f80cf0d9ee4b2082757beac0 a1b065882fe82252899e117c82e576215fa3e056422d4ce391edfebcfde0e400a9d6c4ae2a42941c6bb8389dd5083215 +eb5297bf408c1a55e400a20a3c10acbc5c2bc6d6ccfcc0941fb7a6fd4d2834415a6df86c3a6c4b867d1215aeb8222153da8cbbb1576c92c07ca2c36d8f243fd911f9a057e39ee25832454e28d7ed52a8d04169b9b9677a16b32d5d211b8573a8986e9bf36d7206417ad2771daa11bc21fd7ee1029b65ff7c9b2705a6dc9cf9cb 035994e89e13916ad82608f74a639e6aceb756ff913aec440519946d6434af9a60a6af49 b98a171a3df511240a4b1db7f72f756d13d8bb45c5cbca3d561b0f9caab6521efd9920e605802ebbe898b4ead61bc0c6 +f415d0adcd533dd8318b94560f86732c262ad2c6dff9dc83e2435543f429a2158cd2fbab0d96c027f71008c4895ecc644c2ceaefa80937f6cc6338d15d36e459a16bd9387a361a6d800acfd834ad5aecf442e30b70f5bfa164747cf9f89325b80976052a83a5e896c00c54f81472b14329cf23bec10a8e693005de2a506ba83d 029639da33f48e4fb0d9efdf50bba550e739f0d2476385cba09d926e789191b6fb0a73ff 831f4bd23ce9e6fcfe19f9e470e8dc64f9e952a1ee621a5bb167bb3385f3a74ddf02f18cd2b651073e3495ca171b661c +b178d86c9335b85e02178fc4551769db589ab91d823fac219c7e14e2f029753b203962389476723832f8d9631dd7764e6dd35da290afa42a794476f5c7727b3688aced848dabc9954201578cc7b25801710931f45cba1199d3788d64dc0188412e70723fb25b8ecb6718358150c4037b5b81466dac1686cb5270bb1c72d34bb1 00583a7ecbf2a975a32d07428d27ac82e5dc13d1466c4fdfc1e6a05a8d9a289f1010617d a5ce8698d1534c09886830409706b78684d1187b227e3dce11c7e9787b7051f8945e6e3dfd2cd387201438665edcc5af +c8bfe9fa7c848531aa2762d48c153cd091100858aa0d79f994fd0e31b495ec662209a9c8761cd1d40c3d8c4262cf4dc83c4a2549a5cd477726ab6268b4b94a78b1c4a7e700812872d7f41912a723dd9abc305420ea1e1fb1fee41bf643f3a24abd6e8fbf6fde2475e290527724a6f99fd75374bf7cb01b34d3e60d8db33c4de1 00f817ab1b49131fb9bbe8c112c25a36f064efa85de7506fb9cd29d81b326bf276277f7f afc897b6585c488722aa16b15c2270c3e37a6a3036fdeaedbdeea2a106d631ad749918c58995b242a2d975b4bb6fb9c9 +9a5f563d0f9fd1f31f3a822de628ae970954f4e71292492d727109036491c29e66b9b0f2c90c26abe94c08502f5e923a9ddaf6a7d91e9541ce90d0a49f03ce4e4769753d5b7d922e1ceaac4b4cfa4262732a09550aa076b8ff9d46a50fa17de17e3b6bd606698464d116fcd5f1ae11bf45b0c48d3b738427cb47b0d1272b03cc 02782af76ffebf3e2bfc0576b70e4f4bb87c762e2bb230d278ce776310a14f5b678f29af b29dbd780d249067581643b8ab82dbc6a69ce1f130d8814b8b2abb7b0a3bb7ae23acbc5976c628c33a6d163e4c6284a3 +3d6b065721da9de82cb33ec2c27107eb399b1e69ac8fa51145ed4147e20d72e27434104e76af988a3bc94f55e36677a05182fe2376dbe38195fc6a30673a4dca87336c7304f3f31d49216fbdfea00fd1e105d8b0c13ab11f8892e0045e915c17dfaab07b24ed21b06af5a8cad4f45fbee5a25bb6e87466a7bc422c0bb896440b 031b827b88f14d3822244809096157df3c0aa99da90c00cd9f0b18dfe306f6881834e6b6 b857eaa9d9409f9e68bafc7d1f4890d383163fb5636b1b19e368f3a7551b17e0d2944846c7c08e75c988f1b83c9291b6 +d125f0e2e6135567adec9e77da2afc6862e28d618416632ced829d14ee8b61116da59dfb44098a40a0b927731125617e3d2f32cfbd1546a6e758c1ab6597e75db07add52ecb61d37da2e9ed04df95b36ac249f4cbd794cb561655cbbe4b34834c497b3d392d78ed0db8db683aff0076fb6e43acba3fa2b91210cc6cf3fa594b0 027da4916f1c471cff80bfa14d12aa10270fc3b26caed010c0111f6e5a40d914a3927763 b4a294a82e2b302e8d19971aab5f1f8c46f8dc2515935f03359146fe641256829bbbb095ab564e11f10ce961fb0f0f80 +b380f97687ba24d617a42df1b14e5506edc4b62dfec35ed9fd886bb769832cec7f9adae10c21b7cd9152588797b4efc6b2b30a873d3f25e683ea9be070dd69731949a51121e534fabfa3a2eae0ee90a454182248bedf2595cd47ad08614177d58f7a773f5023b538f5f568682c83fb60e3fb1aa859948d01bf7b214e7f2dc719 010608eb51dc0ee97d6e488a23c582ecf0ea1df9a24db77094d87b3fb6ca98507280a934 a8d33995b874521e0a732cce555d1f338ded84ce8f364662810d60c46609fead4f782914e57b75bde145dfb0f9a0bf96 +3f9ec57e4228e1a6ec49df02c58d756515305e48763ba1dc67298be9a1548576c28c82b4e9b3f62357d9b3c522b16d5c496a39effbdc8290edd2cadc0019e6b9fae1e61238b13b6265ad2ff413a5a0684babdb0013e7632051455e6fd943815213c555dba96cba8911e006bfddec6c3353065004538f37e48df9e339498d85c6 0123f9eb8babed548df08cc3afc1d3b3bbed52b538d4654f2088fe76062fbea75b85a560 80980b26ddaec1bdb53ee339d1fbc791a7daa16af02703c0dd7b9922d707ec89815f021343bad1e970cc996f226c0aca +bdbd7b7bf3337bd9d21a3c6db379f95408c17e49dd394e94737ceae889f45dc0ff5d48cadc53703a16b5589939506b548f8dfd34c577c084f372166cbea320c8fd07c809b211e0749ea639e68f890affa1569b66bd763c7c710989e491011371eb1d93ed9479ff0216b7f79c901a2023e2cf80b565d1c0517e73117190cd2f02 006a18e626452111922e02e31d662f4301319946a204ae8a34f06b91dd1b5b96456365e3 81911aed259a4e0ca4504c7ca3ce19f8af07b11993dea8dc414f7c69720afe70b902dbb61e1c56a3c0fefbdd7105f83a +436b288512ea57bc24f84fdd117da9dc1858bae8c11637f99295d88fa9d05e3c053a2584a6fe200ad190b3077d9a1608f660349dda405066c1562f6897ef69b6b674d6bc11fa470d0b96a7cf8f6e098c9ac03b0ef415aa045867ac7c11d16cee78ecf08850ccabf70f761682b561d0d0e4a889d840dc74932648ca2fb58259f7 03307fd717015b12a2dc76ada21442ac1d97519f66898b214c2ea317ab0f0905e819e4e9 b75179408b067e0d823712e16b9b17fc94c8d2553c2263f66b840662bb0a4c91ec4b6793c266c284bacc3909beeef965 +672faa156dc188bf16bf8933d65e091c633f294486049ce96a4a403dca28a149f4f840e8bef47412285363e9e89006614b013a41baad9885f1d9980cc897ffbd5f8a7d0e63feaeb42c07776efb307ed680ba1cebf470dd9bd8a2a9efc2b1daa569524394f9a50398add1a5bd2f7c263f9e63c2d49461acf98444fd23341ce78d 014f9f412e3c7d770626e800d43cfcbba3ae6aec8563af748e8a97b67d244334b6e6d2b3 84a585d8c5bd021372e0939b1ffda3d6f16cce1e390e96158de98ea27cf8cb94f0cf99d09b6d90153c0e2c59757d2cc2 +4321334cc8ee44f1cb392a4b280a95561809dd3639ddf43b6e11cb73067597988d95b8643d86c76c3c6b932d9262b9b8b55a04fba0666dd8b8ff1e8fdf799ae3945b6e30d3af3966f1a6d634d5e012710d66cb447fc3375130968a2e1e647780aada2609d87247c90338dd71c3bcc3902311caba27d5d4ea4d73ccea960d4bfa 03091a6a8bdac1e43542dce752694972e734dca31c061c7d1000754296d0748055db3f09 a27623e8a1197bfa24a20eff5094b20163be60eda466bdba653de80b0b88f3ab6ee068dc429cd663ff48ee3610b53f77 +2087e22094570d39fa937f15a3ef0601709a66666344186a33b487d041793fbb9709a95af250b1df0762ea98e911aeb3ff1fa19f0aca53fd4179e454e0e91636e55cc5b17cad9e1575c82ad265dc34c4a66b7a31ecb9ef9dc756f2ac1d9dab35369a6bad4a0f47e629daab91addc6d297d1e5d81477b3966d8c3b607ed194d88 01195921b91353db9bcd00510efffe009c94f6bd8d790f5fb3e5a0101c9ca5d21c6ef2eb a0700bab985d9ebd5ba8e73785e27d9231a089961fd05228653dd863c7908739ac8482a73c3d7ee9dd3d976cf1db7776 +15c7bca449a73b03bbfa783f5a91ca0b7916889a5d99d541e2e8593c3b176a5b634ba20b34407fbd94ae1c1398f5313cab7402f3bcd7ad277a8c66d09a6df5dd086b20a0a3823fbbb80980cd86bd13e527eee15656cc977103e80113539e26695addd9eef6a1f56986168d9a53f8b5de833f8962c3826cca106ae9e8c00208d2 029dc20446e9abacb43823e12a83737b46e6e577466b5a3925e0f9d496824dadb4d4b50c b09dc849c165035fd27b32c038b6d5bff6caf192e35cfdb1e6e921adb0b1cef23bbeeb67492a2a4cfc0bef852e501778 +d12fbb82ee7a57eaf76b63fd6bc6c0a65c85f135f019d43ff7bc295cad15d53729d904fed63d69d3ffe8b82c0ebaf0399e2717ece40e011f710b5db46aa457c23b85545953398b814816a1e7a8ab5b0b14c4a0451b0bda9d0d2ec4a374bcaae208b7fe8056bfa17d6b7ffd4ba2e9179f49b9cd781b0c06f6ce3eec26cd428cb6 03b9b77d19a42e9a555da8ab70aa5638890b2ed21daefa28ca6323fc658662dabcbfaf52 9265dfd4ed125a800ba5a6a8960211f4f88c7d22fd8feefd1839862545b7250e799b68dd54d2c6ad4c9816124779bf20 +eab0a37915c6b43b0d1e3ef92e6317b3afc8b8301b22f6059da8271fc5fe0e419ca6097daba213915855631af64e10d8382d70599d903d1535e25cbf74da3a12ba2f13c33a8562e0db03edce791f1d39af8850fd1feff0eb25f9ad0a86dfab627b96e65831bffc5f6d9693d20493bc9dd6eb3e9325dea50b055768e8aa30d49c 00b9f8f3e89e9c1ef835390612bfe26d714e878c1c864f0a50190e5d2281081c5083923b 8b0a2fe935a929abf4571dabf548aebc6c627a044723c206684547de202dc753b0aeb2127492342bdde76c1cf2e6c329 +fdb93afd5dd1e3eaf72c7ea9a6cddb07fc2054499ffe152cb2870163eee71ace5bd420b898cb4fa80ea53fbbaece2a1eef6427b632320e9c97e38acb16b62fdbf6585b54fabf0a703307ca50f86387bed1815a05b0c8991e0743d10cdf49c8facfd7ddeb8d4a7b706b5a29e1d00ac88b0ee88b3153185495ac8388cc70104154 03a30a1c15b9ed71e102341f97c223a9b5ea3e6a335861c3cf407ef691a18cc639dbe74c 92e6272b4795d58a54230212f03daca2ff465541c21e6d8de0ff0ce3e1193245acb4cc2647cc9107ae8a2c1ba3f58256 +c78e35d1a5b1bbb0ec21e7ba7b7c74c859d88f3e100e40ae34128cf093885dae4e87cd09f3239dd8e79e25305220880dd352a650225d9bd193b9b84e488c458b0b5fde1af941c0c9fdf952d2fa41f665918dccae27ab7923da4710f8c27ac8ed424992568dd6f0a6c3ecead21650ed162e0292104eef3c2d8551be866a88d279 0083330123cc64c11888c1fd388629d0b329a50ef31a476b909a182c930ff02d0c389b93 ae7f25b2add08d9bb8a9bcff84169768d8f5cc0683df7df8bfb9e5cc1bdd13e3aa1809035fd7116f86e0e71380c5de63 +e05435f695997229cce314e50065f3c5f71981988dddccaae6efb81f936b22cb48813f506d1edf5ebd69b0be34f278592c5935f0f6db0cca1ef9d62834fbf3c4c03f4da0596cb4d67b7b767e85dde7b7c6fbef7d89babe6f97b876b33594a9e36ab87079861ee556fb03274ad4af527342a4794192b8933f28c6220f954c77de 01dc2b656c207eabc9e0d6272099babca8d149c9c4258b779c2f06de75f76d77505271c0 a06d5db00a33e13ca56aa7fb4b3014a2f9648fdcdf18f75ae1462321b21687db65ffe8e38d759cea045969befc01a80e +0f9f36477076c4b5a7d1ceb314a397fb14646695b0803e36e98908c8a978770269f165a1fed8f4b655d4efd6ad283d7f5d51b6e1e302d360e8ebf4e887c7523a757ffd55384e114bbfc6b7a0ec8511079507b919065ca018573418f9e394854c5704227772161707b4d0246ebceb91192f0eb2ea994ce61fd98a6d14cc8246c5 00081772348ff2d7a3fd57fe703555ab2e14f5d203c4cf0292f944e827e884d95f3b1d83 b05b065012d763e1b2e5628ee47dd1d75bfd68f179120e130bc06f244f287c4c27912f0cad43932f9a368117b7df6b03 +1d38b1c342b6611dbaf412a66c1c0b8397692755f576df33b31c2bd12b7f0707cc423376391f7b00aa4e7b7fe54532e2b39c3c5284b9c8ccce48eaf9308ed338992f1d4ecde6cbe352e46339d7d602942158387881d9b493fd40cc59d4f9b53ee4191d42352c6f7bf32c331f0c5afbd44a92901a4b713c7cf6ccddf7de4cc6e4 01eb6bf2ca1b5ffe6f6a795733eaeed12de6e87c53571e702635b9dbd0d96b47df4a005b a444e68d9d755d5c4e92ffbca442d09ba12c6d2d075211dc8652f36ac7ae37c7ef0f67aa1ac631adce248bc7d1a7c688 +3353ad05ef90e9762bcfedd6ef44a1e8ea0392ebef30cffd48ae620f3e567e1cd44882d514e7c6759200d4bcab18afd3038c3d3f8c50f7bba32a04eee5a4b1cfb8c349939e4efe0a46fd047d02ed000d8fa1b98b0af5586f120d9ad174b3aea33905b979ece1eb3660b1e070c8821b32df41904ad68bbd8ed247aabd94066f16 03b2a3e65e5a306bf8e3955b60e856dfa9bf68c1275a678ca056207a0ec67c96eb3f8309 8c78713b38c81b7e8eb62ce83ee32f161efe9d6c4fae53c64376d34ef45241b2298986d9990d1ffe8416fe418736cca1 +e7ec162185fe9a5803c6b03d98041422315ccdac67e48fbd07a1ef3c5661158710abc6791bd0a75d56791b4ac0e7695d53c5989d9fa6a3b037583b2a80d2b154b024f1c36b63548be9afe1d51f2f68b2ba94d4ca1e69a35ac10e15ba72242aac20f7526b12ff9d3cde9a9bfd70d55adf9bd92c66d092d7d08e9764c84bf7f329 01fd4d1af0bb7c79ed5fea7bb45574e46534387bd916649485ef15207352d7302e81dc01 920dd2626dfa7ddf156169afac186937fe5c56199f2d37768c2b23c6f70914990ab12f37804df7b40784832d6aea881f +87c8f2e3f4fdebce0ca9300fc1ebcaa934f51a12b6b8f2cb6bb6eb77965468663044afeb2a1334cb5a81e74b8427267f8b34b5e9ff0cf157a9f18be2b1942e32ca61dc23ea13c3f9fcfa16df8fe05e067938b6994982676463fb12842d4ec532cb904cf222aa805dd0d86ab9a33a83e294c6d81e8dfa273835e62e9041dc8ff6 020380b1136b5283e9b7f54b7535ebda33b129ceb177bf5d3d07b1daed5edd9fb3862530 9214a55246bfb56bc5b4bde3fcf6bc9ff7c55c9c820b43b99be5247da3ec5efd249488b02b487bd15ab2109a015553d3 +2ac53e8a50c4afe3b38904255b7cbf150c5f79dc15932dc0ac9aa631521f68a0d4b6bc5a04d55c99a36531fd4886a23a8d99f262ecd2a9feea925d7a96ebe9b6979a207b7f9378afbe404fc8e959b0333572a2c911f8743c0ba64eebc7ef12fe5435d2cb0e5091ae518b6e4233489efe3c16c6f21abf4e2c6808b733914e5a7d 019f815b98836948e0a0dc9c30828c31b13e175f1e79f23d084ae1bbe64823f4866214b5 9401044b5fada2bc18b2f7945b672c62a3159f2f6ce3d3a7a29e02d8b1647ba06e0e72fce2e5e31494bbce561fcce772 +0b201469cac4c078f587edecdcdb6efd5752cb4a3f43ab540463c4d908c27527aa3592f2f9acad85dd94a3c056bd28618317ebdf2e7dd6c5ad26fa3c31dd8e5c50c60418d91c93bcbb59ec1adb1db791f485ded78a5cdcddd23dd1cfa4f13443468d8a5f2d648059b9c4470d0f4fe7733d56a28a2c24456b6923703ef32cf0b8 001854e954654e726cf4bebc0e5a840e8809fd716059211c6ffeaed36829808363164684 b55162e4c30a1ca9276e9a30b23ae6cff7949125f5fde26ead8b4cf93c12eaf44fd81c154ed106ce61d4c0581ccc0b62 +fc5e4dddf4c4a328b685035ee79069770fbebcc56c14e31afb4bbcdd5220e025f31eba794fd6c05e64f19678dab33ce4f084bc32790392f14bf35669d75b6466b4214ec30d58ca90ae285c9058f5804a1fc9d7a995958f2a0e84ee52e8a78b601bec04ab607ffc2091749cc548c6754ed14e2e5f92315bdacaa7a12823ef76bf 03548f8020819588b3202f4c1ac62eaec6a47c2a19b2900c5a3cf5b4ba5804231141c647 a3497ea11b6f378df829ec32cc840f84e45c16baed6a7750366a70e95f01076795fe7324e0129781dd21315bc804b832 +284cad790e6207e451a6a469cee3befc3ec43e047cf91b9dff1485718aa29de36a43f7c51eacd8589f0c3a96ec18e8ccfa92941b50b2132e3612d5b45e16f60d411d1c53e373e1ba451352e28970ada9dcb9802102518a385dc571dcf6900971b00346098a58042e0d1d129bd6801fa640a895a458a45b31318fe63ebb30c6e3 03cc4505005c41142308f1489226b7b542e2e7f24f1d3089ff6b92a4b0013f490ad52e60 852dc6f0c532452e5225317eb71e95454789122ead864c1148e69180491c991dee35440d78f733e2068ae93adb1444aa +6d46e57abea9d115deda48b69fe8e0b36144df2f6a659509ce1b514c8cc4769d46e5f71df2a084f1db4a22fdd3ef0c2f90394f2898ce291b9f279c0664aa01419f5f6bee1fc1299871b27ecd57a5ac548f99d01871b8c238a6b46044c953b2e78e22346a0c7663af4db62799038ffb5c21ee512e26d01e70a4ed967377ab8405 0144a2fc8e0aa63506e14e4307df36416f963dd9da78655832f5b991af8c3eb97df78efc a40937224e5926530cb28e37f3af4d79084367556776ae8705d758f2dd91ac4209796114167d51a01bf16c1feda46674 +dd750b39bd8753f4e473c4484e2b36ce2da7576813ebe05861c339ffae1d029bc793173ed394091c00685ad82f0550cb21ed1c68f0c27cb7396922239cfb886647af204e88a9101b7453a8ab662e270b87a8a13f2fe61d695597382cabeb781933bebfd7d0dcd33f77266e43e32d937f2dc89f67525e522977ce73e9ad36c8e1 024ffeaf139043ff25a395e4c560c7680c1c2155191378917eb25194136b4a69597dc277 88a9195d9b2c755844a6631efca16e8e31baca3806f4b2598918874de61e6cde6e21e419ff8c206484fe1572cd584788 +4736e59fe5812f63737eed57a570182c065538abd9fb0a1c9c2059199e7052ba57d84b5fa1cda2ad9f216610361ce1dfb9334816b6bea509283756a03aaae2e5b0597f492d078b6b015a40c9785dcc5d2ae266176980db04f5cffef40e16661a50ef871c5f531d73fd5d114fa19bae9dd2da4267a131fc31849da38c2b78d1af 01d1f2e0f044a416e1087d645f60c53cb67be2efe7944b29ac832142f13d39b08ac52931 acc7da04c6dfcd0fa67e8fe4d0af77686c4f57f1d016366f7cb11c964b7be50e366462eb8fa9952c08d8601d01a7f22e +e573fa7d4bf5a5601e320130de91f4ad87eb7ca6b8998488afcef69c215b0cccd221b8b66eb0af9d699af9ad6c4b4a580e82941f31e4c0a9bd83995dd076c5ac9bebb34481061e7cb1b26f6e8c6b26ee4bdf9887f7ae2eb9fad3115a21dcc96acce85d23a040c0ebbe0a56e75714dbfa803d6e279b2f4280bcb993f96ba321e1 01337362609df74d25f7adee382225e6a04dd6ee4c6b45fa31499ce9edb0ec046325caf9 98797127d4454659cf325c3a4dbf0081637323ce5f49dc0c19f417fcc69222b392b3513b9e019725ff700958dab0e0db +7862864d0d78b44e2a28af44a0a16d8e9b1b8c4b794db0410c0a863ba011018ef43e1e11f2fcda2f56fdb2a69cc817df425c9cb3b458922ba00d710190cae16d61af3c304a42fbb3d0c4a74a297253fccd70aca414865b41f68b01c561be281265fa89f63f975d3101334886e85929a5a47fa8dc459b663548faf8ed7484958d 01be00aa0afdfe92e24a2536594d4b41701ad4dfb223aab35ff49310bdba7566057fe8ac a04b85969b0e916300671dba1d835b5cea7a93803092097970186604f009ddf7bb441a1064eed12443f5e2ab6ed6a857 +e73c96d1a84cf7cc96065b3c6a45db9531cd86a397e434072a38d5eeb9a90f62bf5d20bae22b926cfe967647d2bbb5dd1f59d6d58183f2cf8d06f4ac002ead026409ca6a1f868b406c84ff8887d737f65f9664f94801b2cd1f11aec336c0dbd4ec236d1cc4fc257489dc9709dfa64eae3653ac66ab32344936c03eeb06d5852d 012ad0aa248db4fbc649f503e93f86104cb705d88c58e01d3ae0099590a69aa006aa7efb 8181b588ee6c13291351d16cd39720d016ac6ef9b836d8381a67d13f52d07f4cb1537155ee072abad7d0f41f6e5c0cc7 +a73fb0aaec838d011110d49c5e94395ce07408917bacf7689d2cfe0948c582214b263c6b80e0a55f1e159086817605723740569eeaa1bae96b979679165c5c35ef2142525e943e595e6b4b160acd7ebe41de19775346363f779b1f80b6d5f0785b92a648028e456af8496102d19dc6526247a654bdae3368f075fa9ee92b2f4a 02cfbb8f340cae8e2e2322829148981cd9e509b0c65497fd8d9da5dee9dcfd39b0f7556c 90beb192f86a8898a6f9f64c589abcaece7978f5f01eb1ff33173600f074ff3afaad1db2d0bc8f5541c5fb24fc4f6571 +eda775984c7c9f7db47af30dab314d070fb77e9b623baa6b73e2cbda800f167b20fdc2e7219391efacf908f4ceed9b9b6bd3541b52ea087177e18c97391214758cf6455311fad336ab56cfdce57a18add8cf85b0a0bd6fa7297dbaa34bfc8585b0f06a0aae055186658c227e19cddb65de88d260f09f805c2e8854dcc524189d 0070e82a1f3fa6158d15b7346dd56150faee5c98c9d07c996e01a06dc9b211b12ff62d60 81e65eddc4bb5da18210883e61f0957f30502998f4ba209c51e260d6c581e11b01b8a4fdd80ff86bd42eb65b719a0a73 +a4a13e0bfa761b9bf37fade6570d41c161e20558874911ff3bee38e5649849b159beccf321c6bc7243f99c01a2fadbab9e157e9952ca65d8ea676c74fdc976d00501c626b8465c6cf0e4fd1a7d1260aea987161b821528b0b423e62ecc5193a0a49442b0c3e4ec9c4786a3a86b199c07dd3a17033d430d2c83c100f54e0a7c31 00b471bbc5f7a07996e370da4a09e71e2119ab3a562a273f079401951fbe4df39a4493da ae0c1117df3c03c48580701221450f1a553437e58a21aaac8bc781cbc2c5cd8152aeca218adeeba046fed947c76898c5 +7ceda7a7248640f7055309ae712c19d741375d6a7e0608e07f0135bb830dc3e8863ee9e7a75331a5e1bd38c42cdd484d4f45a26c2c1d4e05ce0d0ca941f4e94ecc6b371102f31633629e9861de558bcb6407d66eb91f1062ac0e0409db68b9f2855296a7f42fc92359a7dae16c73fd2dddea52bd866a4d501aedd8fe3b3ea733 03c65cf80bfb507dff52f9bf2f93df0642020d41619b3990009409e7210fd7130ac44ffe aa92f5f33b305e2373e1f8235e6146ed9580e7f9c7b291cbbe2a6f43f99b96ce58a9cbae95164ca5bb880e90fd849f4c +609815edfd58c0e26a4b06dded831d2f33466a130754b96d8d7c3b4d99fd4b0789ec719bc25338d0ae8c5880560c02687d352d77c291e406eae865c3b26d00f2e63dc644ce7e01d6e96ceeac8bc1eeb257d36cbb25d89b5fff6e30b6051506a0ae54cfaf6214f30985d54cab78f708029c1fc0175bc58e888db89dea8d300abc 00f4d33a9c7e6744ab3c441828bf0f1866ae1c042cc54abc754e3801263a96cbb3955dfc 9203f96de4cab0ef2b9b4d0f2ba62ad90301febbeeb466f3aa266e8d94b94cd709935eff5cadecaa02597718025f7f72 +82d8ebba707b72655497320200ce719520c1ae7f46f38122958fd99322c25c9f4d4344bcb77a6658df0eece5df163412ecdca58475d56b0c2d14a0361e4cef458df146925d473a43692b15e9bbec550f1bde3444f2a5b2ecb55d2abd273ae999f16a32333529d94455e485ca4585e6b07bedbfc2bd1eb766abf0d28bdb1ae6ec 03a4824bdcea6a144d85f1b194431724cc49849b6cb949b4766d641ae95477d1ec3d1464 98e4f01e2c6b568b2b38e449b7bbb9ec8ad09ad0eb78037168851b81aa7c996f984e4024660bf9db1759edb61076e021 +9c6fce18a6a96349b10c9f2f5f1505c8ab727a650b44bc0782a5f39fcb48b45fc7c1b82180d5f229b8abfc807071f931d333d265fc940c93fae7520d8d40ef59d7c6e3678c6a2ecde52b6a8827b1ffc6ed269cb9832feb20e593a7e3d4708309342875199eb2ffceba7ecd707b122516c815e83e27872eda812e3ea52ee3c4a8 027ba543ea785df1d53d4ae4c1bd0a3a994cddf0c25d2b4e8ff17ea7aa00619e858da1a5 b9703e6f534d69ef5a68164de035b2ea0ee3daff26851d43ea1e857802197aed186393f17c4a9cca6ac947b45edae5fa +5eac15a64c7653d125605869012b8f036804817aedacbb5a5248a595ee0c12329f91e8179c187192d3ed0d4ca2e202d8d4d9c93ad3f3ed931121c193af5b47a8a5dc39775b6c2d702708e5134f77a31bd62eaf87e39e6fd3f2b9f782c3057e162dd53b3addf92bf0ab99835c7f6649abd1c5322a1ebb2ba313df9464a74c14d3 00708d0907d14dcd5f40e2903e1e90e48a0ffaa6d4d9b84ca14df4e985c294f74eb9f2d2 b22fb4e92c0404e58a7f96d9394a5158cd3de495faf2ccee42079b65d613fce0e0df607040559118ad28f8031a24de0c +df735a7e60bc267b18f313ad56bff830be5ef119baf43ce27c6368ff1dd89f010afd4f48740b11c12101c5903bfa71d6cb3d6462cf875bbd55a570ffedf3564088dfe8c8d3148231b78b5adaa6c53696737d4704daa59eab8d986fc6e519e81540f201e77b923a6a4af65d7173635b3b19b2023022186a7b8e869e1ed51717ab 021fb0a6b94080da8b8299b87457dc09d21bc430ba5f3359d92aacc1151be9941739567e ae03c088e7baf15d6654fd3fed1f255c05a81e1c7c43e9f2818e5a9f938feacc9694ae658258d4f287c89c6b3465b3c7 +bb107b0eeaf175a786a61db923bc6d51dad5e922e85e57536118e032167b197b1a1f62d9bbcde04922fde781665c1094181c16ac914cf6fbbfb27bb8346b2134f05c55a8c6b9b481273758e380666d6e22c28577c29446cecc5c3df9ed9f1be060ca55ab2b7fda36a147aeb46df0275bb923e0876b703452fab42f6b7ad2ceb0 02c80151f91301fb6b0c7685bd172f20515b46bf94dbc4160d0720fbaedd40ec00084447 b730a2bfbb4d7e80d337e7ec18147094cb5bc46c4a496ad01a4689d880882cfd599462ab1f3ec613a768cde97b8f0b2b +f47e49ae30b09b7666600b7a95e81b0afa1553da5e01fd917e4ce1b58dfaddb8dc8c03c0f5591f533610deb6a7bb5faf5dd1ec4103a587a1a4c58a110a706b0f301a5c408b3d984c210d5b4a0b347d2b5447271f25b527b3c7864f7cdfa735dfded47c63b723fa0f0413c57a24ffde9a95c35f743f892ab1ed1df704cde82d9c 01538abd7ce8a6028d01604b1b87db3aaf720e04220edf4d1d28c2d731aa25f509e58f2f 886df443e2c7779aca6f5bc9b5f234dba9c10a20ff792fa74b7aae7becaa88426239d66620b677eff9bc7687b043709b diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B283_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B283_blst new file mode 100644 index 000000000000..cdb9b4020c61 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B283_blst @@ -0,0 +1,60 @@ +067f27bbcecbad85277fa3629da11a24b2f19ba1e65a69d827fad430346c9d102e1b4452d04147c8133acc1e268490cd342a54065a1bd6470aabbad42fbddc54a9a76c68aceba397cb350327c5e6f5a6df0b5b5560f04700d536b384dd4b412e74fd1b8f782611e9426bf8ca77b2448d9a9f415bcfee30dda1ccb49737994f2d 0299ff06e019b5f78a1aec39706b22213abb601bd62b9979bf9bc89fb702e724e3ada994 888b4c5b4e0fd1c9a885efd27f6bed09ccf0e5a1576c378a9dd53da0bc9e8493bf1d7020241057a37e740b16dc7fe581 +44adcb7e2462247b44c59608cbe228ada574ecb9f6f38baf30e42b589fb9b157bb0560e5a2aa5523b71cc0d7f583b502bec45d9b8352f29ee1842f42a17a5b16136feaa2efa4a0ae306402940ecd6b71e57d1467c98e7960de2a97f88b43487e4f4016af1292381d70c18c7e6eed99a14cdeb5b3caf73688658e4c5b54c81e08 009c2804f8cab768248fb3fff8a055b3f4585c00de5c1615a19f9425b9432ea09afba8f2 92f8f5c47d5f5d19f0e0bdcb59e842bf85f3a0ca4a8ca1098c0a8c2005dc4e6bfa30109e1e67e31c40e783d2ba34a1ce +cffee6252c7eb6d91d8fe100a1e62f0ad9f862d78ca2b747a6c17b8c9ea8980dc239b3b673310e6e7483582399163e39d889abc1a613fe77849ebc09b4f7f4fe0688b8a9869ae918a88294c7ee199be50ee9460db14725ae70b449d0cb48f30e7d817ec02c0cd586119341dba0b74f0279330807cfccc99c8c340b72c1764a45 02e625a6bc6d0ce7c06231de827068bdb0abc8ffb57c82b35ee3a0f873b9473905974d34 b8e5134f0d87f09670871ceb5c54ed21b416c3d82e0f15a4ca431e827d48285715bf258ffc50651ed9be1284ad4b6dd6 +d058ab5dc07228253707ef224897ea0fcd09c3d5cc91fdce9e03c1c59c53fb4596be2ed929c7455e67ac7f4891aed3eb06ad88f2c4aaaabff045b959f900d1019d706b60526375851bb891494e99995928e4cd51c9616aa651ec77bd7e398916bb9ed3156391bf7fb1e29181e2b011dae2edaf803607def2ac6b194929a57f45 0376ac24e1b86f8a55c052d92a0bdc6472fa03acdcdbccbf7c321ec0ccd97aa0a66b4181 858f59acb97c37338115a357695026b93d09fc22c85ed45b9d0210aa18eaf747eb9f4234008eb7007d3d06b09df32be9 +c86f2cc7ab5df5cf1a236fd83792769474cef464032800ffe98a44cf29dbfb6f24088160eb31a11a382ff2a49f3e05e983462f5304272f96c0a002b69af3d233aebe867ee63fa46666760a6889d022c18645b491f8d71b6a3b6b4ef058e280cf625198715b64b025bf0449445d3dd7e1f27153926e617bd2c96638345431d1ed 02b50a6395fc02b9ac1841323de4520292f913519bc0d6a471aa28021322fc4dbcd7b802 a288c6a73b709bca88d5c9965387e6e4bde6761a65879cde48aa7ac94ffbbb67ea323dbf171645b4a3e27ae4d83d2f9a +c1328d8d2e5b6ffc850a9600bd6482518ddd9cee3fc9140febb72bcd444b0cd7e8074587d51b62cce4b3d4f34ad3355353fabe363369cf790db2df9fdac3a0ec4757e2dfb3b683eaa3e26531691ce765742e1c0bdc0e1028d347b6085fc459df0989c6a144271454eaffe413cae2ad7c8b2371fd2df1afffe56df727009765a2 024e5889722f6c35e18ca47effa9e415b1ba790066a91fb3c9f7b001ce28fc732b09bc23 b393980f3e6c7b839a48c67108f5a2590c036bdc266594fb0cd8cb275fde18a72d6ec24cb32a78bfa20b6a9ec62607ad +7176b7013ea27e94281977eacb976bb31c753bf80fa09680a29128a6fc15234f79f0e9900aff3217ce9be72c378042c6c34fced0158740073d1a985fa25987fb218002e425868fda5a47de51abfd04de34e2b8634cebfbdc98e80f93d94096193eaa82dc8778fc23f3765c7acdad94fdaa272df0ff0f28190c10a462ee78ac92 0056d15b81f40b6378588a5efe43e21b95e18120d514bfdda0e7759a1d0766a8a35ce5ac 91cbf47a9d289817bbc9e67d2b4862b6ecc3b50b5e3446b5bbbd1f2011d4d632ab4915f731c8b636274e0ce372a546cf +4c3642ba040a9955b9d50dcd1c936688c17c363854358afa8ca49c6abd906dfdc4d89bb4cab0bbc363fb5b74e1f004d4b09ec9dfeed4c0bfb482a9061a1f487a3d79195ff7b65a0504bced3a28db0ebe8fcf8ab1ee4a3ae91324d15d890ac4c479144dd5538d2e36d3a587769ee9cd2d5c6f85a03362a022fe0efc4a3902b71a 012fb2fb5bf5f7e42a500154823a174ba2d05af71e3b0cf47fab46e673ea1822f1563def 9650259d48e0fefd7c9903a43d66b544396b2f70cf0d9091afa012ba0d4ce4b470f1db4b7c53b3ffc8b9570025b94ed9 +e471f39c18b081362adc7da47dec254dab8d765f005ac574640d78c14222639245563912d942f3be212ee3cef134407334c8fe3602fa0e1629de5331643d76715dc1b0ffcebd484d86c5211be4b285a31688b205fa988e6c15b36daf396ccdcc209c7dde2a732f5c31c84c7ea041408ebf15e56632583af0131bd7f531b5fc45 030096c54fd480647e017f8cdbbdef292e799f054e3279d228b09816a757566a744a8266 a0999a4d81c5cf95615794e3c31be8f39dc6264683d3d020356af601ce824c89480fdb4c96f0f9f88bd7d5620337e54b +8a93fe53e83075c4025228540af7e96a588520da34e3eadeb99a4ab2f3dbbb8f85fe63a3b86c1f4ec912e665ca05b43e869985eae3791b91205afb1380e16c25b74e6793fa63e4a55dcf25dc22d03f09deddeb9042b620434111afe08c5657c7d754af66ad91a1b5423301b1e8e6389a1404060d1b6a99fe0f89598482979e42 00a1b7e9c8c2dc25b494b5ef3195b294e41cd3c2c35235ab42542bd3e2a52d5826662bf9 a451526bd751ba6648c317007ff92b4a09e613d09aa4791231ab77c9623fb8d97ed107ba8bd634d860d4cc99b085e485 +e193a8ef6f454ca1aed38bb67aca6d08280d421b196d89938c0582b7cde74dafd71716f3818940af412d4a7ff3960a8517aee108ae03576b68ee7557d35e6f1ab823d124de7243dd02b542591f62c80d822608572889573e4c9dc62f99d68e07800da6f83cb6f5e03d1f2ac15f90e38b4f25e0a75e354e4b60cc81c0bbe81d39 0059b1a8fb84530bba7a607ee88310e31bc6ea6a6881603567a1081a05a3a9ff87e719ef b36c4d3969ab9f0d70adfca1cf6f5c16236a3b1a0d86e3a9f600457572237e3cd16af976d1b62e584c4c4f64b245792f +8a99b9db191f6cabc88b430bc2293e6774d5180f019d871839289e25aec29379f14606e742190b7aa062e3b29fe0254146d9614856c5140c7315015abb98ac00da2c7e33cbcc82c24b797366f12767322c4381454d9d1eeaedb616b0ea5c66d1422da459f18081f4f966d05ce279c6ee69b1bf94b8388d38d4b770d9ed69025f 030ddc2c7a4ce300cc2b75f0f977033f16c1f8bb13aae3d494c381f9a6dc8622499ae4df 86a947f2595c9c592cb032f8293b8455d595f69079cc841f48ec73af7d51c59f48d268efde118ba5bd9d7921e6d71384 +5c437b331831530aa94623b1736f00b986172699f0a02a5e5df0008bf25341787e2e66046f2c929dfe0058c3cb89fc5bebbe1025bb1edd1ee31522ed568e7b5b4ca3991afdc76a68cbc2c4f81863e27fdaf6a564fab2c6354e5c657de81390f8a4132669fd24a48580c716b5b7961a9c091f614d11cf45dfdaec8946a54a11d8 007899928922fbfdb5407517725edf231d15a8b62d90b7fb6d8c8d20424850dc44f797ed 81689c5732ed29915b157ce4f554438ef857f69fc18f8640f656678224b69e9dd1afcd07d8c808ba579a0aa0ee4e06d7 +91aa08567d8da4c90684dc06068f69deae240212842ff1786f04ec41b40d9187aa92c76401f9fcedced62876a34df82ad7c1e63b68bb2a972257ea8542bda6a7f1a020c9b122943b6d651abda8b8d322a8fb762eee376daa2d3637a71ed6c4f5cf96f61c0da2d6e1dda3370d80e51da2cbd8aef3267168c67359523faf910dfb 02a2af63d1171930758bd3e5bfdac62cca1a83a3b55a49b3f80cf0d9ee4b2082757beac0 a07df79958be1a141e51f3f26a2ba5150a187455b3a5bd30f786b475a86d268c71d1da0d9d8742e15f3ea311750cac56 +eb5297bf408c1a55e400a20a3c10acbc5c2bc6d6ccfcc0941fb7a6fd4d2834415a6df86c3a6c4b867d1215aeb8222153da8cbbb1576c92c07ca2c36d8f243fd911f9a057e39ee25832454e28d7ed52a8d04169b9b9677a16b32d5d211b8573a8986e9bf36d7206417ad2771daa11bc21fd7ee1029b65ff7c9b2705a6dc9cf9cb 035994e89e13916ad82608f74a639e6aceb756ff913aec440519946d6434af9a60a6af49 8a23d2078df1348934d8c6f67f2c23fc688af18090ee8bfe19ff63dc0a50e04668dbbe24e9675e38611053f7be2a5f07 +f415d0adcd533dd8318b94560f86732c262ad2c6dff9dc83e2435543f429a2158cd2fbab0d96c027f71008c4895ecc644c2ceaefa80937f6cc6338d15d36e459a16bd9387a361a6d800acfd834ad5aecf442e30b70f5bfa164747cf9f89325b80976052a83a5e896c00c54f81472b14329cf23bec10a8e693005de2a506ba83d 029639da33f48e4fb0d9efdf50bba550e739f0d2476385cba09d926e789191b6fb0a73ff 92fae238372243ed79b8d880d595335bbcae8a5bed3770f8a68a022d40d2b48177f1e98c6c1e2c565f311dfcbe178699 +b178d86c9335b85e02178fc4551769db589ab91d823fac219c7e14e2f029753b203962389476723832f8d9631dd7764e6dd35da290afa42a794476f5c7727b3688aced848dabc9954201578cc7b25801710931f45cba1199d3788d64dc0188412e70723fb25b8ecb6718358150c4037b5b81466dac1686cb5270bb1c72d34bb1 00583a7ecbf2a975a32d07428d27ac82e5dc13d1466c4fdfc1e6a05a8d9a289f1010617d a06abb6dbc46fcc263c68a33b5e391ad16110d7c37fa5d77a7bf10289e888389d6d60b0a736d509bc68fb72521c4a251 +c8bfe9fa7c848531aa2762d48c153cd091100858aa0d79f994fd0e31b495ec662209a9c8761cd1d40c3d8c4262cf4dc83c4a2549a5cd477726ab6268b4b94a78b1c4a7e700812872d7f41912a723dd9abc305420ea1e1fb1fee41bf643f3a24abd6e8fbf6fde2475e290527724a6f99fd75374bf7cb01b34d3e60d8db33c4de1 00f817ab1b49131fb9bbe8c112c25a36f064efa85de7506fb9cd29d81b326bf276277f7f 802b163cd6339f518f20e40e6c4688c5f44c362104351b07194f55ab35bc7be560de2ea29dfd829cc3409c1a31649adf +9a5f563d0f9fd1f31f3a822de628ae970954f4e71292492d727109036491c29e66b9b0f2c90c26abe94c08502f5e923a9ddaf6a7d91e9541ce90d0a49f03ce4e4769753d5b7d922e1ceaac4b4cfa4262732a09550aa076b8ff9d46a50fa17de17e3b6bd606698464d116fcd5f1ae11bf45b0c48d3b738427cb47b0d1272b03cc 02782af76ffebf3e2bfc0576b70e4f4bb87c762e2bb230d278ce776310a14f5b678f29af 8bb4f4b8e8354b46dde21c1740053df1de976539cdb8ecb67140a7a22e68482a76718634ab98bb8181f7a852ed374d04 +3d6b065721da9de82cb33ec2c27107eb399b1e69ac8fa51145ed4147e20d72e27434104e76af988a3bc94f55e36677a05182fe2376dbe38195fc6a30673a4dca87336c7304f3f31d49216fbdfea00fd1e105d8b0c13ab11f8892e0045e915c17dfaab07b24ed21b06af5a8cad4f45fbee5a25bb6e87466a7bc422c0bb896440b 031b827b88f14d3822244809096157df3c0aa99da90c00cd9f0b18dfe306f6881834e6b6 9243e842d980538aaa8d004510eaaab4d5479a909f59ef2237129a204c3492e88da1d541d7da0d6c6fc5d74218df1755 +d125f0e2e6135567adec9e77da2afc6862e28d618416632ced829d14ee8b61116da59dfb44098a40a0b927731125617e3d2f32cfbd1546a6e758c1ab6597e75db07add52ecb61d37da2e9ed04df95b36ac249f4cbd794cb561655cbbe4b34834c497b3d392d78ed0db8db683aff0076fb6e43acba3fa2b91210cc6cf3fa594b0 027da4916f1c471cff80bfa14d12aa10270fc3b26caed010c0111f6e5a40d914a3927763 8a6b5de48c5e21ee0509ac0b9c6467ed5134b91e719a941be81e6c36d82e6294e02eef8c1122389ae6879a454d1ccb3f +b380f97687ba24d617a42df1b14e5506edc4b62dfec35ed9fd886bb769832cec7f9adae10c21b7cd9152588797b4efc6b2b30a873d3f25e683ea9be070dd69731949a51121e534fabfa3a2eae0ee90a454182248bedf2595cd47ad08614177d58f7a773f5023b538f5f568682c83fb60e3fb1aa859948d01bf7b214e7f2dc719 010608eb51dc0ee97d6e488a23c582ecf0ea1df9a24db77094d87b3fb6ca98507280a934 b8e44120cc304b40c90c2c9591f11058b867e7d3a2a71acb2785c5e6b616a48292387a41bcee5c0d710107facdc998d7 +3f9ec57e4228e1a6ec49df02c58d756515305e48763ba1dc67298be9a1548576c28c82b4e9b3f62357d9b3c522b16d5c496a39effbdc8290edd2cadc0019e6b9fae1e61238b13b6265ad2ff413a5a0684babdb0013e7632051455e6fd943815213c555dba96cba8911e006bfddec6c3353065004538f37e48df9e339498d85c6 0123f9eb8babed548df08cc3afc1d3b3bbed52b538d4654f2088fe76062fbea75b85a560 867dd54e90f0d48e238f5fa14d360931942c45fa012ce094391f915d618c268ec9bd609793ec4cd65dfb357a35fe6e27 +bdbd7b7bf3337bd9d21a3c6db379f95408c17e49dd394e94737ceae889f45dc0ff5d48cadc53703a16b5589939506b548f8dfd34c577c084f372166cbea320c8fd07c809b211e0749ea639e68f890affa1569b66bd763c7c710989e491011371eb1d93ed9479ff0216b7f79c901a2023e2cf80b565d1c0517e73117190cd2f02 006a18e626452111922e02e31d662f4301319946a204ae8a34f06b91dd1b5b96456365e3 b0a3d6b56af5027e28260a375d50b0277aa9842d1819cc2654ba9ccd6cb50e1c5369f7916944db64034224db9ecbaeb7 +436b288512ea57bc24f84fdd117da9dc1858bae8c11637f99295d88fa9d05e3c053a2584a6fe200ad190b3077d9a1608f660349dda405066c1562f6897ef69b6b674d6bc11fa470d0b96a7cf8f6e098c9ac03b0ef415aa045867ac7c11d16cee78ecf08850ccabf70f761682b561d0d0e4a889d840dc74932648ca2fb58259f7 03307fd717015b12a2dc76ada21442ac1d97519f66898b214c2ea317ab0f0905e819e4e9 98556ba6e49fa83b57e49c119f7eeab0d77bd4fc776e0770e828cc769bd5553aba62043b5c01e57b8377da84f3a530d9 +672faa156dc188bf16bf8933d65e091c633f294486049ce96a4a403dca28a149f4f840e8bef47412285363e9e89006614b013a41baad9885f1d9980cc897ffbd5f8a7d0e63feaeb42c07776efb307ed680ba1cebf470dd9bd8a2a9efc2b1daa569524394f9a50398add1a5bd2f7c263f9e63c2d49461acf98444fd23341ce78d 014f9f412e3c7d770626e800d43cfcbba3ae6aec8563af748e8a97b67d244334b6e6d2b3 afc4f5a6d9d666322a25e945cf8e8541c1e388ea6c986cd362230bac225625ff505a8195738e9437a0508b338466d291 +4321334cc8ee44f1cb392a4b280a95561809dd3639ddf43b6e11cb73067597988d95b8643d86c76c3c6b932d9262b9b8b55a04fba0666dd8b8ff1e8fdf799ae3945b6e30d3af3966f1a6d634d5e012710d66cb447fc3375130968a2e1e647780aada2609d87247c90338dd71c3bcc3902311caba27d5d4ea4d73ccea960d4bfa 03091a6a8bdac1e43542dce752694972e734dca31c061c7d1000754296d0748055db3f09 805624ff604ce0f4755dfa0213b384443e3e57a518509408d84f8a61d63453c4ff1292fcfd9eab43aa8f68d28b48f85e +2087e22094570d39fa937f15a3ef0601709a66666344186a33b487d041793fbb9709a95af250b1df0762ea98e911aeb3ff1fa19f0aca53fd4179e454e0e91636e55cc5b17cad9e1575c82ad265dc34c4a66b7a31ecb9ef9dc756f2ac1d9dab35369a6bad4a0f47e629daab91addc6d297d1e5d81477b3966d8c3b607ed194d88 01195921b91353db9bcd00510efffe009c94f6bd8d790f5fb3e5a0101c9ca5d21c6ef2eb 9490d75989d7372f32c9ada90adcb9d24a918a8a21d7b7987b5381df51820777969829e335db83e924633a59c9f69828 +15c7bca449a73b03bbfa783f5a91ca0b7916889a5d99d541e2e8593c3b176a5b634ba20b34407fbd94ae1c1398f5313cab7402f3bcd7ad277a8c66d09a6df5dd086b20a0a3823fbbb80980cd86bd13e527eee15656cc977103e80113539e26695addd9eef6a1f56986168d9a53f8b5de833f8962c3826cca106ae9e8c00208d2 029dc20446e9abacb43823e12a83737b46e6e577466b5a3925e0f9d496824dadb4d4b50c b6efa64e8910038458d063c46cbbe1a85141f163f56a1f3a31e26b6b4e2958b55da1d913f6459f7b529943c97d49d440 +d12fbb82ee7a57eaf76b63fd6bc6c0a65c85f135f019d43ff7bc295cad15d53729d904fed63d69d3ffe8b82c0ebaf0399e2717ece40e011f710b5db46aa457c23b85545953398b814816a1e7a8ab5b0b14c4a0451b0bda9d0d2ec4a374bcaae208b7fe8056bfa17d6b7ffd4ba2e9179f49b9cd781b0c06f6ce3eec26cd428cb6 03b9b77d19a42e9a555da8ab70aa5638890b2ed21daefa28ca6323fc658662dabcbfaf52 97cd8f720b8c8d71ad681d0bb58188425af6dad31cae8f73983f65e67585bd0b2ecc51a842a33356bf5d4e24a2158f3c +eab0a37915c6b43b0d1e3ef92e6317b3afc8b8301b22f6059da8271fc5fe0e419ca6097daba213915855631af64e10d8382d70599d903d1535e25cbf74da3a12ba2f13c33a8562e0db03edce791f1d39af8850fd1feff0eb25f9ad0a86dfab627b96e65831bffc5f6d9693d20493bc9dd6eb3e9325dea50b055768e8aa30d49c 00b9f8f3e89e9c1ef835390612bfe26d714e878c1c864f0a50190e5d2281081c5083923b 9621568472cf4cbe405c23720010a772608f3264046a98ee930aa086c93bd3c2cea3ed9d3b62663c0edbcecf18e54af1 +fdb93afd5dd1e3eaf72c7ea9a6cddb07fc2054499ffe152cb2870163eee71ace5bd420b898cb4fa80ea53fbbaece2a1eef6427b632320e9c97e38acb16b62fdbf6585b54fabf0a703307ca50f86387bed1815a05b0c8991e0743d10cdf49c8facfd7ddeb8d4a7b706b5a29e1d00ac88b0ee88b3153185495ac8388cc70104154 03a30a1c15b9ed71e102341f97c223a9b5ea3e6a335861c3cf407ef691a18cc639dbe74c 8c3aadb06e68bf677d93f4f1c5422518c256badda29572df895fd9c1b095a7ed3d30eb572b7e844a0ccb1a269f6b04a0 +c78e35d1a5b1bbb0ec21e7ba7b7c74c859d88f3e100e40ae34128cf093885dae4e87cd09f3239dd8e79e25305220880dd352a650225d9bd193b9b84e488c458b0b5fde1af941c0c9fdf952d2fa41f665918dccae27ab7923da4710f8c27ac8ed424992568dd6f0a6c3ecead21650ed162e0292104eef3c2d8551be866a88d279 0083330123cc64c11888c1fd388629d0b329a50ef31a476b909a182c930ff02d0c389b93 ae193b718a9444b74dafcbf8e4a82e82833c23a50a56c346d1520f53df59a5fb2b1f8d02513a2d65d9ebb31d904cc07e +e05435f695997229cce314e50065f3c5f71981988dddccaae6efb81f936b22cb48813f506d1edf5ebd69b0be34f278592c5935f0f6db0cca1ef9d62834fbf3c4c03f4da0596cb4d67b7b767e85dde7b7c6fbef7d89babe6f97b876b33594a9e36ab87079861ee556fb03274ad4af527342a4794192b8933f28c6220f954c77de 01dc2b656c207eabc9e0d6272099babca8d149c9c4258b779c2f06de75f76d77505271c0 92914d66b398a5543ab712159d70b2c77b7e2ba87767007f9677a5de66fb3bf4027937eaa6b96e63b3028417772318a6 +0f9f36477076c4b5a7d1ceb314a397fb14646695b0803e36e98908c8a978770269f165a1fed8f4b655d4efd6ad283d7f5d51b6e1e302d360e8ebf4e887c7523a757ffd55384e114bbfc6b7a0ec8511079507b919065ca018573418f9e394854c5704227772161707b4d0246ebceb91192f0eb2ea994ce61fd98a6d14cc8246c5 00081772348ff2d7a3fd57fe703555ab2e14f5d203c4cf0292f944e827e884d95f3b1d83 ad51fdd9e9f9b7ab7b603a15620208742b0fa9c53781af8079b8aa26216efdfa8ed6bcef11f595090c24579a6c6005b4 +1d38b1c342b6611dbaf412a66c1c0b8397692755f576df33b31c2bd12b7f0707cc423376391f7b00aa4e7b7fe54532e2b39c3c5284b9c8ccce48eaf9308ed338992f1d4ecde6cbe352e46339d7d602942158387881d9b493fd40cc59d4f9b53ee4191d42352c6f7bf32c331f0c5afbd44a92901a4b713c7cf6ccddf7de4cc6e4 01eb6bf2ca1b5ffe6f6a795733eaeed12de6e87c53571e702635b9dbd0d96b47df4a005b a981aa34d49e4df6b833feef811f83ce890a6716d520987cd3bc13d261f40172ae71853eadb5ed11f37cc0c7f14eb87c +3353ad05ef90e9762bcfedd6ef44a1e8ea0392ebef30cffd48ae620f3e567e1cd44882d514e7c6759200d4bcab18afd3038c3d3f8c50f7bba32a04eee5a4b1cfb8c349939e4efe0a46fd047d02ed000d8fa1b98b0af5586f120d9ad174b3aea33905b979ece1eb3660b1e070c8821b32df41904ad68bbd8ed247aabd94066f16 03b2a3e65e5a306bf8e3955b60e856dfa9bf68c1275a678ca056207a0ec67c96eb3f8309 8424d74644ca35facdcc92fb129cebaf2bcd478ee706b807cb9daa75b9a4c577340c4e22db6c379d779aff75191838fd +e7ec162185fe9a5803c6b03d98041422315ccdac67e48fbd07a1ef3c5661158710abc6791bd0a75d56791b4ac0e7695d53c5989d9fa6a3b037583b2a80d2b154b024f1c36b63548be9afe1d51f2f68b2ba94d4ca1e69a35ac10e15ba72242aac20f7526b12ff9d3cde9a9bfd70d55adf9bd92c66d092d7d08e9764c84bf7f329 01fd4d1af0bb7c79ed5fea7bb45574e46534387bd916649485ef15207352d7302e81dc01 ad2a7ea1461b4f3eb93ec2af18df57cf22aa52ba2fc96dd52b6df239b33fa15686ed87916a80610278193548b702fc92 +87c8f2e3f4fdebce0ca9300fc1ebcaa934f51a12b6b8f2cb6bb6eb77965468663044afeb2a1334cb5a81e74b8427267f8b34b5e9ff0cf157a9f18be2b1942e32ca61dc23ea13c3f9fcfa16df8fe05e067938b6994982676463fb12842d4ec532cb904cf222aa805dd0d86ab9a33a83e294c6d81e8dfa273835e62e9041dc8ff6 020380b1136b5283e9b7f54b7535ebda33b129ceb177bf5d3d07b1daed5edd9fb3862530 b69b12de8920487dfad0cd95c05c4adf773b0a4765a692c7f98ead21dd51ec29d8eab5c06d97474509c78aec6f73300d +2ac53e8a50c4afe3b38904255b7cbf150c5f79dc15932dc0ac9aa631521f68a0d4b6bc5a04d55c99a36531fd4886a23a8d99f262ecd2a9feea925d7a96ebe9b6979a207b7f9378afbe404fc8e959b0333572a2c911f8743c0ba64eebc7ef12fe5435d2cb0e5091ae518b6e4233489efe3c16c6f21abf4e2c6808b733914e5a7d 019f815b98836948e0a0dc9c30828c31b13e175f1e79f23d084ae1bbe64823f4866214b5 b35896a7ce357e2aed039f4a01bd5f4d61967535bee745f44d83d2ff2634da4bb66bb32bf4f2404ed59920c39ac04e47 +0b201469cac4c078f587edecdcdb6efd5752cb4a3f43ab540463c4d908c27527aa3592f2f9acad85dd94a3c056bd28618317ebdf2e7dd6c5ad26fa3c31dd8e5c50c60418d91c93bcbb59ec1adb1db791f485ded78a5cdcddd23dd1cfa4f13443468d8a5f2d648059b9c4470d0f4fe7733d56a28a2c24456b6923703ef32cf0b8 001854e954654e726cf4bebc0e5a840e8809fd716059211c6ffeaed36829808363164684 97accdd15aea806b18e8cbcaaa9f2c6d89248e774341e9c55acfa2e983c2bf747c1a88810abe01fc595b8b9595b8b16a +fc5e4dddf4c4a328b685035ee79069770fbebcc56c14e31afb4bbcdd5220e025f31eba794fd6c05e64f19678dab33ce4f084bc32790392f14bf35669d75b6466b4214ec30d58ca90ae285c9058f5804a1fc9d7a995958f2a0e84ee52e8a78b601bec04ab607ffc2091749cc548c6754ed14e2e5f92315bdacaa7a12823ef76bf 03548f8020819588b3202f4c1ac62eaec6a47c2a19b2900c5a3cf5b4ba5804231141c647 8369f257dc2213ad86c5e1edc734916a2e89f629f751b3676b064725737813cdd6185cbca8f64d14dd639ced28dad589 +284cad790e6207e451a6a469cee3befc3ec43e047cf91b9dff1485718aa29de36a43f7c51eacd8589f0c3a96ec18e8ccfa92941b50b2132e3612d5b45e16f60d411d1c53e373e1ba451352e28970ada9dcb9802102518a385dc571dcf6900971b00346098a58042e0d1d129bd6801fa640a895a458a45b31318fe63ebb30c6e3 03cc4505005c41142308f1489226b7b542e2e7f24f1d3089ff6b92a4b0013f490ad52e60 a308a58ac8a25a136b965c1874f0959d246f4b77776b62bf94ea9b3e775031bb04fede51ba1c919ac8da1e111ca3fb2f +6d46e57abea9d115deda48b69fe8e0b36144df2f6a659509ce1b514c8cc4769d46e5f71df2a084f1db4a22fdd3ef0c2f90394f2898ce291b9f279c0664aa01419f5f6bee1fc1299871b27ecd57a5ac548f99d01871b8c238a6b46044c953b2e78e22346a0c7663af4db62799038ffb5c21ee512e26d01e70a4ed967377ab8405 0144a2fc8e0aa63506e14e4307df36416f963dd9da78655832f5b991af8c3eb97df78efc 9818ada416b99f881fba4c5c3c5fb757e5e3c9d0da7abf61ca1d0039a5f54a94a0dbbb25ac65bd952b95e841326ed1c9 +dd750b39bd8753f4e473c4484e2b36ce2da7576813ebe05861c339ffae1d029bc793173ed394091c00685ad82f0550cb21ed1c68f0c27cb7396922239cfb886647af204e88a9101b7453a8ab662e270b87a8a13f2fe61d695597382cabeb781933bebfd7d0dcd33f77266e43e32d937f2dc89f67525e522977ce73e9ad36c8e1 024ffeaf139043ff25a395e4c560c7680c1c2155191378917eb25194136b4a69597dc277 ad0ad915d6cbc3de33e067ef097e082fdb2f07db827d8390c658a6efeab4ba8abb01264e92fc302890d8b37469f305cc +4736e59fe5812f63737eed57a570182c065538abd9fb0a1c9c2059199e7052ba57d84b5fa1cda2ad9f216610361ce1dfb9334816b6bea509283756a03aaae2e5b0597f492d078b6b015a40c9785dcc5d2ae266176980db04f5cffef40e16661a50ef871c5f531d73fd5d114fa19bae9dd2da4267a131fc31849da38c2b78d1af 01d1f2e0f044a416e1087d645f60c53cb67be2efe7944b29ac832142f13d39b08ac52931 b876b0a7075c8079b09ab90b703ab0658e4a0e7dc0d3bf74a3bd0c698f3493b9229ab3c56fd716774418a1a58bd68771 +e573fa7d4bf5a5601e320130de91f4ad87eb7ca6b8998488afcef69c215b0cccd221b8b66eb0af9d699af9ad6c4b4a580e82941f31e4c0a9bd83995dd076c5ac9bebb34481061e7cb1b26f6e8c6b26ee4bdf9887f7ae2eb9fad3115a21dcc96acce85d23a040c0ebbe0a56e75714dbfa803d6e279b2f4280bcb993f96ba321e1 01337362609df74d25f7adee382225e6a04dd6ee4c6b45fa31499ce9edb0ec046325caf9 a93eb54052d1c2cb358bb6345265ed9f255cfca723af3418dd520cf6f95252159fa0ace5584b0d6c15b50351f919b286 +7862864d0d78b44e2a28af44a0a16d8e9b1b8c4b794db0410c0a863ba011018ef43e1e11f2fcda2f56fdb2a69cc817df425c9cb3b458922ba00d710190cae16d61af3c304a42fbb3d0c4a74a297253fccd70aca414865b41f68b01c561be281265fa89f63f975d3101334886e85929a5a47fa8dc459b663548faf8ed7484958d 01be00aa0afdfe92e24a2536594d4b41701ad4dfb223aab35ff49310bdba7566057fe8ac a3dd2c666b1f790934a2acb67721d617e1fb77f357e9ba3fd41917c8be2a676463c47b2a09769e2608d254567109c2c3 +e73c96d1a84cf7cc96065b3c6a45db9531cd86a397e434072a38d5eeb9a90f62bf5d20bae22b926cfe967647d2bbb5dd1f59d6d58183f2cf8d06f4ac002ead026409ca6a1f868b406c84ff8887d737f65f9664f94801b2cd1f11aec336c0dbd4ec236d1cc4fc257489dc9709dfa64eae3653ac66ab32344936c03eeb06d5852d 012ad0aa248db4fbc649f503e93f86104cb705d88c58e01d3ae0099590a69aa006aa7efb 9650ba5b830da2dc0e3976888ad831b185eea45f911de271a525c3f390bfe320687eb4ed9cc148fab71d5ed1eb87d771 +a73fb0aaec838d011110d49c5e94395ce07408917bacf7689d2cfe0948c582214b263c6b80e0a55f1e159086817605723740569eeaa1bae96b979679165c5c35ef2142525e943e595e6b4b160acd7ebe41de19775346363f779b1f80b6d5f0785b92a648028e456af8496102d19dc6526247a654bdae3368f075fa9ee92b2f4a 02cfbb8f340cae8e2e2322829148981cd9e509b0c65497fd8d9da5dee9dcfd39b0f7556c 99b7d6d391f7723b7e81eac9289374f64ace12e60f8f21db986ed5f3afaa2ddd59688de511a42f09820ed281ab732b9c +eda775984c7c9f7db47af30dab314d070fb77e9b623baa6b73e2cbda800f167b20fdc2e7219391efacf908f4ceed9b9b6bd3541b52ea087177e18c97391214758cf6455311fad336ab56cfdce57a18add8cf85b0a0bd6fa7297dbaa34bfc8585b0f06a0aae055186658c227e19cddb65de88d260f09f805c2e8854dcc524189d 0070e82a1f3fa6158d15b7346dd56150faee5c98c9d07c996e01a06dc9b211b12ff62d60 8019fa3f5fd6897a5dc8ce6961655ebe480f5b80c9c202053ae06ccc1edc96ea222aaae8c451dfca943187c54b7f790c +a4a13e0bfa761b9bf37fade6570d41c161e20558874911ff3bee38e5649849b159beccf321c6bc7243f99c01a2fadbab9e157e9952ca65d8ea676c74fdc976d00501c626b8465c6cf0e4fd1a7d1260aea987161b821528b0b423e62ecc5193a0a49442b0c3e4ec9c4786a3a86b199c07dd3a17033d430d2c83c100f54e0a7c31 00b471bbc5f7a07996e370da4a09e71e2119ab3a562a273f079401951fbe4df39a4493da a72466698f3132a62e0a0135c985518dbb72c8c77764b045e12067a6a5b333294fbe24116a13f6e22b1a4b18e28fcada +7ceda7a7248640f7055309ae712c19d741375d6a7e0608e07f0135bb830dc3e8863ee9e7a75331a5e1bd38c42cdd484d4f45a26c2c1d4e05ce0d0ca941f4e94ecc6b371102f31633629e9861de558bcb6407d66eb91f1062ac0e0409db68b9f2855296a7f42fc92359a7dae16c73fd2dddea52bd866a4d501aedd8fe3b3ea733 03c65cf80bfb507dff52f9bf2f93df0642020d41619b3990009409e7210fd7130ac44ffe 8e34a05b383f109a493b2434ce7156743b8c32016ef5e269d9aa193ec2d74eafc4dc299fc79130407d04fb3b14dea9e2 +609815edfd58c0e26a4b06dded831d2f33466a130754b96d8d7c3b4d99fd4b0789ec719bc25338d0ae8c5880560c02687d352d77c291e406eae865c3b26d00f2e63dc644ce7e01d6e96ceeac8bc1eeb257d36cbb25d89b5fff6e30b6051506a0ae54cfaf6214f30985d54cab78f708029c1fc0175bc58e888db89dea8d300abc 00f4d33a9c7e6744ab3c441828bf0f1866ae1c042cc54abc754e3801263a96cbb3955dfc 8c6e04cc5249c3ede7ead071bd19ac20c5942a32d372f078da8ccee56eb4b0bb62abaacced574edd1f0903d48dc2ffde +82d8ebba707b72655497320200ce719520c1ae7f46f38122958fd99322c25c9f4d4344bcb77a6658df0eece5df163412ecdca58475d56b0c2d14a0361e4cef458df146925d473a43692b15e9bbec550f1bde3444f2a5b2ecb55d2abd273ae999f16a32333529d94455e485ca4585e6b07bedbfc2bd1eb766abf0d28bdb1ae6ec 03a4824bdcea6a144d85f1b194431724cc49849b6cb949b4766d641ae95477d1ec3d1464 a1b893e336244969d00d4dccd611364551ed639ebd7e3f1c923574ac03c89c4b5524dfa9cb88bf47b3d54cc1c1e75f62 +9c6fce18a6a96349b10c9f2f5f1505c8ab727a650b44bc0782a5f39fcb48b45fc7c1b82180d5f229b8abfc807071f931d333d265fc940c93fae7520d8d40ef59d7c6e3678c6a2ecde52b6a8827b1ffc6ed269cb9832feb20e593a7e3d4708309342875199eb2ffceba7ecd707b122516c815e83e27872eda812e3ea52ee3c4a8 027ba543ea785df1d53d4ae4c1bd0a3a994cddf0c25d2b4e8ff17ea7aa00619e858da1a5 afb1038197788078774ee4d1bf760934d5af0ceda07409964a348a81cee855909ef42a2133111c0434e16f73ad8d3898 +5eac15a64c7653d125605869012b8f036804817aedacbb5a5248a595ee0c12329f91e8179c187192d3ed0d4ca2e202d8d4d9c93ad3f3ed931121c193af5b47a8a5dc39775b6c2d702708e5134f77a31bd62eaf87e39e6fd3f2b9f782c3057e162dd53b3addf92bf0ab99835c7f6649abd1c5322a1ebb2ba313df9464a74c14d3 00708d0907d14dcd5f40e2903e1e90e48a0ffaa6d4d9b84ca14df4e985c294f74eb9f2d2 a9d98db5a4600dbe268db5d748ff947118af5824bf1a28681805a1e35aa26513358947b58fefc4406d2b5f7dfefd9ace +df735a7e60bc267b18f313ad56bff830be5ef119baf43ce27c6368ff1dd89f010afd4f48740b11c12101c5903bfa71d6cb3d6462cf875bbd55a570ffedf3564088dfe8c8d3148231b78b5adaa6c53696737d4704daa59eab8d986fc6e519e81540f201e77b923a6a4af65d7173635b3b19b2023022186a7b8e869e1ed51717ab 021fb0a6b94080da8b8299b87457dc09d21bc430ba5f3359d92aacc1151be9941739567e 94cd8c8734be960919a3953836c4f82cf5defe6bfc40aaa97d26aae518c043960be9b029217b54918ee9991033130ce8 +bb107b0eeaf175a786a61db923bc6d51dad5e922e85e57536118e032167b197b1a1f62d9bbcde04922fde781665c1094181c16ac914cf6fbbfb27bb8346b2134f05c55a8c6b9b481273758e380666d6e22c28577c29446cecc5c3df9ed9f1be060ca55ab2b7fda36a147aeb46df0275bb923e0876b703452fab42f6b7ad2ceb0 02c80151f91301fb6b0c7685bd172f20515b46bf94dbc4160d0720fbaedd40ec00084447 aba70c26e9ffbbe1baeec9a312e38781e39e4101d7f0f7752d4a4bc27154a98efb0aa92bf2074a792fa8ad6342d275f4 +f47e49ae30b09b7666600b7a95e81b0afa1553da5e01fd917e4ce1b58dfaddb8dc8c03c0f5591f533610deb6a7bb5faf5dd1ec4103a587a1a4c58a110a706b0f301a5c408b3d984c210d5b4a0b347d2b5447271f25b527b3c7864f7cdfa735dfded47c63b723fa0f0413c57a24ffde9a95c35f743f892ab1ed1df704cde82d9c 01538abd7ce8a6028d01604b1b87db3aaf720e04220edf4d1d28c2d731aa25f509e58f2f 92abb1ea971682900cbb0829518d7b24c5037dc3e5ba65cc302f348142289ac6fda4a1b7e04af9f75a2f330b6b70557c diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B409 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B409 new file mode 100644 index 000000000000..b85dc5e7fa8b --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B409 @@ -0,0 +1,60 @@ +f2380acb0d869d1cf2e25a6bd46ebe49d1c9270624c5507be4299fe773749596d07d10f7c2be1c0b27e86f27b4a6f8dff68cfe5c0b4c58dad1b4ebec7bd00ab195fdd635d9fa8a15acf81816868d737b8922379648ed70022b98c388ede5355e4d50e6bc9ec57737d8843fabda78054e92777c4b90466a5af35dd79e5d7a81ce 00beb0df3b0e05a4b5cf67abef2b1827f5f3ada4a0e6c3f23d698f15a3176cb40e85bf741c9fbc78c9e207fa7302657527fd92fb b866d9146adff97a2ed56d00683cb9aa4b5bce06f998ea759b70eb494b58d05272636e9cbec9e0deab8a0cdd0f53ba7d +22a97fc0a9694dabc6f274ab52eb592dbbe8beeb646ebe6cef60eff341a13017eef980aba6d24ab3afd976e2f6a84cf652654d4a54a36b2f2f62fab8858f8b0479a48fe9f47f8fd5a4a1f3141a91cbca186507b2bbfef5e4c4d2df525f04ef7c4720fb443ccad540f03a2be468d88c9545d1dad579fd7cbcd103bbebc9e9f961 00504865a30984a9b273d1bc289d734d10e0aa56e93ab14720f1a42a27d8cc932cb8804b963175de6fe57d8eafa8ab7ea0592dfa b481be737cb44d19ad967b54b956888ea92104082e5318e583620f79c3c6e3f1717db5a497a8136224a1f5bb9a9f9357 +af36c04af0e3fd64bf52dedf52fb788d2d1bd67fe05d98880cc7ad3c20436abf02f637fcec209fbf888903fdec8682717299f8a4386768153b7faeb6581db57fb9aaf4615b4ea8d924198fdd158363a1f40312527d6bd14c13d19985b668c6b88a7548104b1ff057d07082eea421f50062a315bc3866378f2d2d634f03fbc0cf 00cc08a4ea5ebe32027885a8c212870e7c45b6c610117994d6a42a284c05199414a3a0e8e6645ac5c2ebf21c505a601f69c62b85 8b486eaecbbdba120224d69216b4a3f797ccbc5507832302b16b7ca6a50edc423c69aba685d1bf4c7d92a8173ac1c62c +6bd6f52a6204b60f37929aeff28c87ef61ddeecc231e52a7772275f9329add899c130956f8c50ac2698aad3654fdb49b74a6427a62a11eca0a8ee8b719b8c0df7b9f0bb0af5fef4918a8c83367d29fddd04b6a1ecad904471e5b59c8fe3cdb06b4f8f96419518dda960845d83c49a49f1b1f2fd1d2682a9d60c25fe3ce982cf7 007156ef0a74ee1119532a2a7e8c02be1559c3c21897af9d5b34553c3d0feca4a8d5929d1945df824478e0c0b92a6fac8c84f639 93933d3bf30b89b3b6f6925c8f09a6f51bdcab082c4c8ca4fd716db808970461be5adbfbafed2518f16db7341c19a34f +0eb8de25f63abc9cba16823270e9b6f3fdedf0fb90f6652a34688970932e3ae98f6d3bf0fefc5f247f72960a6975bff1f1acc2188a1775fe8974b2bb2b4c8d226ceb735113a14009e8ce66d58808fada4e6f697fd016829913352c0f659b6be354a067df00cf74919580750aa6064f21264d89dcb28b3b2d4d699115c36d1310 00a95c7abffa92e2c637611ccba66ff9d2ab121b40a85c5b71454cb0dca1f098ce1be8d9ea4933d1a91bcd270c5a33687835d6e4 aa21f34d1e919b9c037f3eac362a6def0ec5e86d7060320837c92663ad04ab8d6ef78a4a4792cdc8e83c9b9b0f6edf90 +cad58ca7a3b9967dc0ab62a43037764f8074ef9177d60bd98f623d693333971c24a575ed03cb61f4dc2e3d6285fb1204502a540f3c0bbbf23f5bbbd1544f322ce35d949d8b1d8edeb82e90927ac67ad49c91007056bf5096bd690d15ac00e1874fe33293d8003a4a2b094078cf09af799dde384143350c54a99e1f99cc31f2d1 002c438b07c6e0685d1f94a4bbafc013f8f21265d893f54e54c3ac2071606ad1ffacace0b8367aad724b1d9508c65ce52282e397 8ab7c61685e9ce72d7c292a2d06c7c24d8f6d3f064827a20f0fad08d177fb14ed2fefc3ac76e0a599b06aa714df65867 +281ce2643799bbfacc7d5993683a4fa656040517854f3c2dc7c4f8848dc305382e34e894d433caf12d8b493020a6a08d1fa05b08bf6c53127ad5f33bbe75b9db0615e3dd94408d028dcf3cb7598f6e7cb4c787681dabac7cba2cc06fccb7506fece6c7c1c1bf622d525ae9737085ab4ac578905950002024f30159cf0d99f50c 009e8658f8f9e6cd98c0f4f0fd20d64d725653aeba339504def17f3ad12a63dc6157d80804e5f43f4ff48fc5573fde2c615ed31b 81525f954f50a41c0d27c018a5a9e34c640095585e1c35e96caa9ede84cf2dfb3c0b2663ec300d2d08d9b4ece7cf2a48 +0c061da1a16f2be130ae3b20b89745e840bee09633fb49671db28ec9a051545f57ee07e2410ae7ebc61c9af79868d3047705bfc64ac0c04ef0b286e579b650c7165443631e49e6a53c84cefa5625b1e1035a6ed89b8e839540040151132a937666524265e099272c1849f806db0fdf2be64960d5b5853965099459968e5beb32 00c4c13f65eacce85a51881caa6f82d9e48ec2ac574947d2751823a7f072d38bd9da0cdf30b6f19084a6d291052e7bbc2e1349e1 b1603f676b1885e3e06213bcbd1f2ce034ee6a3ebd9a3cba1d3fce6e3860cb083bce3dda2cfd331d28dbdd2866417310 +74ac2e1303297efc3ed8e624722df505df55b7f33964cc0d270604cc48b58205d8a11952232a8feb0079baa30d7d33660268b56a5a3dd90105f0703abef8f6636a99bc63bd47d9df100351bee32d8205dab0dbd2af36fd173409ff8d1fb7b24570f3c1e968458f58aea5aa2f46731ee91ffd6d3a060af6b3d5020daf1362af3e 00da591461791ae7847e6d8dd8df46a63d3021644abe9520e158406c96540d8fd82ecfb1c3f6f5cfd7688c7656cc3e3dc94e586e b970d1aa2c5a45dc6c0e2605034b8e339d5acbd74da280ed4eec91660dee4f5ed3fdda5862edc0e7f6e8de055d6efcde +2afd17344552ccc577b0118caeb7dd56a0766e25f84df17c0505f9798931374b48df89a48c64e199108c36e00c0bf00a97ccde55787bb97c6765601765ab5417f3e75e35a9fe5e0f85a721d9f08440ed617afcdc200b318940a1e496040a6ad9090476b0fb4fcceee77b3fea11de09e7fb14853d1fff8ab12d66c101257e2d4f 00b5eb943f0dd390b737510e2bb703a67f2dd89dc9f6dca6790bc7a260cb2d0fb8e1a81ad6009ed51010e7686d5b48233c6c1686 abf2a60e4da8a86ad8dad6edc10dbc11369398aa963f33589280db8b3195354243af67241a2a722acfcefc570a61e479 +174b2b083541f8284645a810801e72631a11bd7bb805f684a7159e055afc44357f2c80df2b7853678d34a04144e0ede2327d03db6df23769ec41194a8d9d86af74d51c5bc11ea878c6a80689af71d3fdaf1c651003385332a512e03dd040c33d9c328ca89ec7ee9026bbacf30a7f3a68e0d894fb9f7100ffbc64bf17679dedd1 009cc63f32152284fca27ab2837bf1343144336a1fdf15b9727c47e877ac69ac9cf4c97b4bf42f1ab10d73de8597a554ed099efa a7e5bac870ae1e9b5e6086afabeef34ebb224e7d1dd981e35a25d02b156a1c95688a5df0a3c8a8f43843324218c6f2d5 +758df71a952cdcffdc417b9fffdfb57582ab5c5473a8bdf0c2101953b023b77824263353dea0e2ede1f800a5757ec6ac0e1e4e3ab5a4cd85567d2d19acc6b7069a6e7368401cba2b6e642373654bec0ddd19fbf032794c15b7ef7e714e13e36875262c01e77766ed53cbcf735936dc9b33eaf2152a396349c82ca0297dbae4a5 009950355e8667bea8bbe3a2c4988436ab5394551b375e27fdc0c1a1d1b07ae957932f428f1aca0a486e54cd0b5bb0a5c5650641 826c28f3edb5241cedc29dcd41953bce38b70395a262b79d4c53d5c810a24a735197a4e4970014627eabaa051aa4c56d +b96d9f66b2000e9408d602096f032b112f0e05ea874229ab9daf6e05bee49b4722e4f2d8bf2eeaab9dad94438c76b7cc64dcbb59cb4e03f9ac70487a1d24d8d6b72d7462fe738a17edf381d52179b3acc0c0177c113eb4d10e8e78041deac1d56abda0ddf892edb8be956d285e7236bc6794168f8a180f622dd5f2b9e690c275 00a995493d6971c2d7e8fac3da9f8c0b5afd877cfb94924cfecc167f9d87002136ab253e3a4f9ddf5c9c99bb1dc1af0c6a3a3c4c 93b656006fc08231bcd5eaba509d89ffa4c537b5b315c9982e4fd4b9138c8145e93006eb827819df796f6cacf01aad61 +e7ae60ac55e6ba62a75d5328bbc15269d4638764169de0bf0df043d15f9152bed909b1fb8c7a8d8e88ac4f552c1092b62db00958a3a827f64896f6de4bbd8fa5258d6c36e3904d82d3eacf6eedba50b0242eb6b01212288448c3a9821c4fa493869c01149ff1850e8115cf9de1618cb8744626b1951d1de305745507c8b21045 0070daf435cdc26ad66c3186267ad12d10f28d32d863f950cbfcf042fe9dfce553750ad098f82f7f1650c1126b3e4451bee6e11f a82b245f61cde5795a8ba3e1eb167437e9a62a61dfa2652086696cbee1dd88eb6001ea13ed75ac79d2c7975dd7318f77 +666b0dc2ddffaa7ffd57ea3b2768f02d4b77c16fa007c6d1918400d195f068cae2dcaa69817e6e4c70d5b29c5598efe2d957bd12d0fafdcf5ac52dee80a2d46e77fc18cce2a49bfd787ff77b942c753974d22434742bdb494590d17c42af725b1309e54566276af3bcfbf5e174d3cf191b85903faafa1583282c97e66c5da6c4 00f8121980dfbe9ad0bf92383c7cab95fb72d5caba96e1de7772c6a179e85414802fbb86d725401451329287305570ec7fdd873a b2d464e82305a4a22ac517b8cef3cc40be9b03ca52d28eeda478ea2f9299055386a18051235f6d8c3c2ee85e320826c5 +3e967cbc2bd936e0b6125dc5cf885735bdcd2d95b2f764de6931c4578ac8e0e87abdf96375481df67dbe1b6c43537e84ec62bfca6672cc5f3ea4125abd4a4119edffe04e42411d338e8b10abb1f1f818c50a9631a3f89feb5be5367bdcb0a8a82c96a427ba6ce99f9631d4411a2b7f5b14d32cb3901dc9d285e4cf5508940942 0047682b2e3bcb5800a531858e8137692a9b1ee98ea74e929ce4c919c26ae3b3f1d4122d07fd9a70d8315fab727ccb67004187a3 b28f0004e66534eba91b043d81df50915beb48294553dd5ac6c01610ab64e3bdec7db69dac412b4f8cb869531990b357 +ca1c90012eba4e7c5f01d8cb3814c58f48c03a16be6ed86934014365eee547070b870d1d26a872cfd28b60d9ee0a66dea223e9eaa90ee28076188d6091f26f665684f4b486af70669555db9058d485c677b2a34d4a98aa8d6f43bf6f44aff2a23c5d765e98f0438ab81be0585a5be29daece5d4116f44ce6062753a3ddc505f3 0040cd1a06233ac27f3ddd108de7c6c0982793ee620d71982697713be9fd5143658929924cc88747a680779bb00da8a44e1e7d3f 85b496993e940bc2d17d807223ac47109fe0f2f63dba6af956a7e6555b3e4a2287cde20f7a28cec9ac375be47f173d1a +a54c4351ebdb075d6a42a787647390f864b2bbfd8bb3d0e0ea9d767200fa344d1a9ff091bddb186acd69bcaecd767068efe4d752d185bfe63f6674279d0e7192d2077c400bbc0d5599ee28507c1253f05eae0687b965a015e1f3a292b4650106765266f5c95b77ad2d82a6a6e012f233169eb6b8d83576901cfd4a927c54d7f4 001ca6f752aae4eb7fc9c73a08d6fbd96bfde5030d759a2507bd45b6e1d1487e53abbe98fad4f41976364e0a1d830910ccf97abc a2b8dacdfdb67d31f5b4afcb3c6d8fc137bd4434ae87eda6d89970702080e6b24ead7e6fc1729a91d377823e79b0d756 +6723dbddc8720feeb75e2a061b7fc49079f999fbc79ec8a8e01ab8d35b438b7049da5a23c49a58101742791f84f45d5f5cf551cd7de6926a0e2c4ffa1e378f038da597368c62df8cd8349bf046de46d02183dc05b3a3575f5f232dd2970057200e2c9cb60eaa6b4d72f8b73d4d40b98d1cc801d1a69cb5ed780a75a4064623b2 00fb9b1a9597d216028902abf743d25944258b48c9762d4589fe660396130b75f6006cacfde60f6204463cb8c18b032de1dd68d2 8139bfc9243e8be3d4257d50621d8c17ddb553fcac27a3dfc714555c82f5a9c385e58827ca69b46f59436bcf002f56de +ed53cec5e5500d62d38c829002916c657674ede4439c6f405ba672327ec677490e656bdd698f114c2ab5e6a1fc94a1a8d64466cfe9eaabd23a8b5c37f76a3c0decdef73b3e7b751cbf3b0817f4079560b5ea34cead88ba374201236bffc48eaf289bbaa4e828afa7d732473c228ad00588c9b443d65b998f21c3d7a9e9196c08 0032109202d754da290c266f74f47805a06e6b5c3f721a72fc97a3bffeb8887e0c642d49a6bd034847d0a5ba09239c5dfdf0772d a6db1c1f32f4c8e4fd0d0b3ae5e289678be651df718e09d15c8bfd61d8080dc15e6bea585cecb5acd2ec5de5fdc1d2e0 +13829401bd41e9fe01329e9f5a002f90f1a6ecbf25fc63e7c1345f265ff02e496230f706c6ab377ea52d8707b54f8fc5c7f089044e2bec1dfc66a07da76ee12fb9ea0697d87706b0ebf677600bd2fe117f6cdefb8bd636a1b6b97549ee78f992c24acdf3a946053f06fd012a9c703efb8bd929a66aa74b05d61bff0395232b00 0080536e820fac59b3203aea928475043b2576446619001647e35693a9e65d15236c3cbc12e1bbe0eb305973535c882b70197a92 b8144d49b67555c1ffac28e2032893b149f1ac257c9b7bab5c275a550dad73ed79fc44dab29c42b449dbabae600b5ffc +e696acdfcc96a6c088069b7595ea9516a36d8fe04dedeb789fbd965db0cc64b7017a821015f6210b6989e515def5a9605fec0d337e4ac59f3101a505168bf72ab6d98ec62a71d2f94071fc05b95e98d4efc59fedc138e3e49c5d0b44d1f48f7b1e7c1944ee189b242950d2bc804d31c7eeb45283c84638f043ab9533976433a4 00b05e5f0dad9583ea18fb8fc4d8c75fd2e3cf9e92cdd9b737485c953620d345006c31c288b380258b6500b84f729ce6730e5303 8204c03cda27b0cf5b411f0f5a5cc70fbf351460a17823a13b4dfd73dba32603c7c88f25195cc99df0eb02e511fce278 +4058b9a8cc15ac148909eb97fa32aafbb6077b168dde91a411dbc973df7db056dc57ff78f0abcb70f70f800bd752197d681f44df4a7817c0e7f60f8f65489ecb6167c14b525e91fd2cc5d8b80ba380a83d031d5827c8b1262c687c90ef0e62723d9b565557f9f6fed0db48f3799274c2cd60a14303406c35802cba6261121296 00be1d277813e79051ca1611c783d66003ef759b9e104f32298017fb97667b94dcee1ce807dc6b4d62416e65d4120523bf6a4edc 87d41589955ce772a5cf667480bdee617ff2e29ba807e061b545f1195e38558bd680d9aa289bdcae0dcf41abfa0dc657 +e793237d46e265ab84ba9929b196405faa3b0e4686e8693567e53f68e6991e57677974677682a2510c4c35b1968a90b32c4941af7813775c061c008a60f9f671cf7419c94253d6106b61e65034497f2d273a5058379bd986e3d917f708f0a2bebdba150f6d78a3af9c722a2430ab0f4bad602e91e18aaf258e3785fee78e4502 0073c807bd7e07379782ab790720de4ae5106f16d34e80ed70da5b1594e660c9b775db94066b93e74f855f57d88b6ecc6228aace 8eaf6994223c10ea169c9f8d0c23977e45f25956442dd26b354d8577b2ac23d304ea55a7141bb257788ebd4186de86a9 +ffb8bc80e7619a562d8506eba7658bef0c25ace3dc1d01bdc2ef00933d4fa07b80364e5e5826074edd46a707dbc3b0ab19eec7ea8990839d7fc0a80b70661204c52bcbef57c1a7bdc861c10766033a82dafbead283d911a9502d5f9ef0a39d35ef26f3616212d4bafcd413ffd18b424fe09b48ba02ca5d97ec996205cd49d22e 00a68379b2296a6c944ad5dacb593b302d8ef0b05873ce12bbc371d705f308c739d21f343349524aa72f05341e64f7435daef112 80748a0fedcb7903e01371c1f6191f4290fee51115eadd45884db730490f0117d780bc1672433b6d046c4721ae7723bf +946bde90a5b903dd281a51d7fa93d80f3fed07eaf50c18fe9fac5acf67326bb18effa3144e25c151efc006a50a274ec6c6a5d573051c4e2d117ceb0fa125acad07a10fb6534a8e5f5b3da2a1136779c51377bf76c3a4a93c0c6158f729f2293e414fcb952c9509f228c804f0adc1daa327a8991d48ccf4f3957c5f8ccbe3ad4a 0026046bbb269ddb1ec14ade56175482343a21b7c265026cef3c7d6a1ae0f6a68166b9e6c49a6e733ad2ad64df7137ef230038fb a116ae4334766430d3bfdbc3062bdc085b2ff81915dcf47891f79970a65926cc4d9b64f3029700764c1e2050d7c5eb87 +07f3fe1369ebfcbcacd66675bd4ab22edbbff72e68709cb57d4f590e49440f01691f490c58b5117bd24aa2fe2101b59c61c417c918ea08ea34bbb9b8aa17491ae5d9329affe894f42d7586017877fae3ce35bb80c97f92a004380374ec91e151995166e14ac00505fd1fa810cf02981bacbcebf5f81b2e633d3a3db6737890f4 00bbcda66978ea526f7bd867c3303b625f11b94dd9ee6e2c2f8688ff07f2bba83c662949d47ad47fa882cb7d203a7f0ef5dbc52a 8efda0550abdb384b9429b18ef938ce9c087fbaefd1e7d0332f86ba898861fc8869756b03d9393ffe6fe3c5764f338b9 +3a1cb13438e3bac9ad4ab1d319e90e2c9f118dcf1eb54d6333c674a665d41451f93cd4a9334cd057a44c010edb668254517a63700a31eb0ca474c84873e486f2f8e158a1a7735362ea0cff8ef17d959ffd851b21a91412709b3c729474d2cb40f6ca0e397030eb2611b402916e4b656f0fd868247d80be3ce33d52054b7661f0 009be3dd3442e0330750f0a6252bf9cb317f32f942ae516a4038dea2c40ca6484fb33611bef016cc64baf166c122e87c15466fd8 b8af14b7ebe215f808084e5a680f3d70d16ee0f45bcadd3e60c16a0624919370210738cb1468f2103f5712d28e378a46 +e58e7b881a563d54772125b2863718690a5276c93d9e1c5feabbdb5d6f7c7293ff0f89805b53663bb417fdd46874b8e6a466e7e3ff6737930a0662af1d5879b071b0dc4d014778dff26a2eca5992e763bf4c4698c382ac947215aa116515876008a56e5bf547857049c38a2d3737ed3393705fd346897c3beb80caab88e5b8cf 00ed321fa283c662e87eaab99b7715e6cdc9b42e14fa5bbe2c56fdfb381369191a42da7e574839f90a85577485f19446fccaf6cd b3d473c46af353a79b67b7b15d8ea9f3888a9107ae847df2b8abe61acba893d5959af3dba0d1271eff4b39db5b8eaa8b +8889ea1da1cbed98963941f6ac24f47253ff6af52de920765214f2024aeb04f7ad46936830a8eb04d95aba64ed7cda6ef242f454b67bc2de38a46b6524bd5c96739c4b580e89829a61a8249ec8dc27a50f43b8554cfb6f4fa4ca6875983d4b60a1c6b49f32ddff6fac0cafb64d55c6f594b195c207a9bd920dcf20e0080920bf 00396b805073f3c3b552b1024dcf35559ac44f255b688871a3c6657f727a4b09f3806cbb75d26a00ae1728be632387e804775a8c 8c3e90cf0b645dc07ae76866b977a15d272ae655ec437f671e8d439547079b8fc069aac8212b8c0299aa0ab485677906 +55053af9370901e38622734a5bc5589f6a20e258627f381fb0c366f3dbe58394e5997e978eb7ebbc530f6e6186f48294149b8594fb551c31c50521a8c4d67e5862921695604afb23977b6a69b21abe75966fdd11bfbdb6b51ab0a474c5fa07c4de7872a3bd81acc417655090558dfcd5af449b3347e61fa9e839bb9457de64c1 00a8fe323f6736bcabe971c7d964e75dece70cb54561da48a11c40027ebddb23e41c7b48600f569500fe8ea2abebdf480171dde4 a68036289d64e467b905fa1b63714be3c3bcebff53c3f2472ebf6e2f27e0fd7e0acd2ca1f6605a3cb28652ae5a9c0f0d +c4264330534a6c2bbd8a3b757e0912558302ce302f835ad8c5474993832fd30036fdef40b10ee37293e871db5b0b149654f9e543e22111f9709ef45732125f713c031ccfbc9a2f3aba160c241d27be4dab87ab2fa9a795752ab2daf20f9d06a98d90d01c07133adfe83cb11d5176525e1bba6a9ba70ea48b224d46ddd8103f65 00105938ba9f25034da3e032dee121bdb192ac2128b50a2ed4bca042e96cfaf4660c9d35f3e67bafd4c99f9447e6dc408e0c4471 89f2166aa772107d0363dc0a982a61c25f6f351eb8af4a1aa936d2554c510aedb2ef5a9f3fbe5a17445edfde90269f5b +3236f1ad164e1b25d828f5202e3513c80c72a577aa9af56f041fd96cf5a3363f4b827723b1511a2f16360e32eac90ac55f4ee1146791420ef9e2af333c17d157b00e43992ef6f2be2d2f211361e468413dd93fb69232f0a0d110bc5fff361c0410344aa0636bf809062c73a7ac7c142063912b6ad7e1626fd2a384f35faffaad 00ce11677ca818537dbaeb880fc967dc8bead203a2538a55e756679c4a9e7975b9b3e6aba4e6c6eab4152d0c0939027e9b0bd92a ad6fb456b1d73ef77f7d569bc3cac9ccc48fe94640b771363fa22dd2884ad77fb2196d7a875f165ce73f8501964ceaf4 +6c400ed098d8369dab6fde3553afbbd4d47836d0d12dd16015f15cb8d067a39391c85ca4e78c62b8b72c1592349ff8dc52db8ccb7fd80c085fae456dba6f4a2378e184dd59238c92cf04e40d43a66b342d2a1325a0bab12b1ac857f0564c27b35e6abed02ff5bbbdc3770ddbb2ee0513df48bcba925da6d61583076cd3129603 005a239ae0f40d76d8d3589f1662b5ca12176a4b2784faa8339b54e96a1e1294433a4d83bf904196f939bd8b33bdb4be340ec703 b6daeaef7d9bef783b14858bf1e49239c816e191348fdc2cdbe75a93d9148bcb31708f1bc8f5b49a807495f5f2c1c5f2 +039a149eaef2de30b0ae457b376ce6fbf88afd4cfdec02d3c5e00400d3b0484c1cd6ba74db5de65d6f2fe39871349b30fdf1ef29bcbb9e182eb3ec5629d07d98354a5dfa82d7f0db3dd10d1510c0dce086848a198893ca5ad24a663494f0596b4eee86199ea85e7e8f2f76e7a6bd4a052c54287f61b391f1e52f96b606151c34 00077390c62ac41aca995640fde0c79c76f4ea8a8dbb22323ed812bee837ab8798c5d0ba976c7aa634d4b1c2c155de2709e7352c a409a81169d854164565c2c4499bd2ff9e49fc55d176ca81eb87ca494d3e0acdea49a3cd3fdeffeb3798a0ad7c6f3419 +08617d04fffd6644c40f7dd57919f7dcf3c888f4147535d12ca658302305bb8e220bb17ccdc480254004b9035b357120580882ef86aa5a061b2850100285b7d61588a664dd4f5394f5478e68a80f610c9204d056009c1c9e902161eda33ef61aa902e96b6f094a9f053135692182943d38b9763055a38739a2a2d133c5dbee89 008bf23b09fbbed1b55769907aafb97f4759cec98649b2c9da5157517d4f85bb70157076b5e4aaa7a940af042302f8be06a84ab6 8318332cdb44b24457a71bbf97ba09d341924c0fdf705b0ffe08f620e06074d4f64b2c1794602dbef19fdf8e66ad1b28 +34c959f549a307f21b850ae105f41299b8bc94fc292aefc61aefbe0a1bf57576ba8d9b80caac635e4edeb22530163fa9629665fcd43959f68eee32482f1845a78ed7278e6e43d09ed6fedf465001afc0d61f1d2e1d747623e82a762576b879c7024e34f43104593cdd691d53bccaeb8f212dc29bec6bc94cf69d0a8491db124a 00082ad05d19b8e16f80e53a4cccf6869ab5128c5e622ed146fa8555985ccd2aa3b9957dd374586115d4d75b1c01cf98ecfc3646 b407e9043bf4ab2670638dcde8604fc5ac0d8e76b589cdbb1c2a1b307333e080299d27739948f41373cb6aef6ed4545b +514f4de08a6f49edbb6797c9dad6d33bfa367cc1a1b58a5becfe646c7f3352d5c5d95f7456e7112c4ddc746b9076b9756ae3916c07bbe6d3823895774a42d25d44b3309d18bfe7e3ccb1f85dacfec1654778c19e2981a853c1f40a7eafd16d331093110698c957fe9f1d86582706a6885543248b944bb70cdf9d2ea89190cb02 00af7e581aa4f9be5815f0c447e39de00da9194eee5e5f609668b9b69930b5b48a948614c2250260d1917f0ebcb00ebda4bb52f8 8d69481ef41f598bfbfec7a67c09c8897f4fd37c18d6385c09e629b446f9db18724030551e5ceaa5b7afd373aebca288 +4e5d16cb1dcaa1abab1e371e1de02f31ef4e0944dfe1fdec45ab64326435b2af9aaf1a6ed8fdf1a6ab1182bb53a844c7cfd66da30aec0d41757f5988ada0017c4ca752597a9fd3637668bc1a92bb1556553f28d66805bb47f1ef91908ce098d452872da9800e77e1fbd43ffb0ed6fe6a62185d4be73ae96c9241b82cefb2da22 006d14107b08354e6a41d7d7d50c004419db8bdc50db43428df5e86084551237223c498bce71a17e25695bc438c5c09e009c60e2 a189dea8d0974f53202d80d8dc84011660fdd534c79be9eacc154ba7f3089e0ccb77a1205d2709e8796bae281141af8e +e29e75269754ec1194270f5c9e8267dfdd8c696008b5ebc92bb840981fd065672f07f6a0f1b19841adfc51b478371e1a0db9c3346a9f0a4ccbdecb7040191a00ddfd0a8faa0e69fcf544319c0155d02797eeef99fabbc55078f9d852927c23fd931685424249b87ed0c70a4a3e2d3b9a2f92830e7d8f7650c0bffa8f8986b7d5 0099d96d2dc9c79549f031bd5346cf6a8544c312a3fbfc560dc8e378efdfe025b0e6e61e09c04c8bf4133396f993b0906c33dd30 80f8cfd714f498f26e890537afed3da18dec93023d6be43def0d62fb0c8638e1e3fedcc8b9e20ae2ac77a418fab3e235 +1a538eb447c18494ad5a5ad27be67fa60eb2c5cb2404eec1dbd7244cd802b17ca5497e779d5f779b981b165dab53ad19fd7bf2ea7dbb9b4baea782a43d758202f147e59d6b6b8ed54f4ea084bc18519943f6894d603e253ba3e8e339a6933bc3a0a47126087038e1c813c3f2997aae321b7c95a802b4b73fc7db95897b7c91e3 0049f347dfd361a65910e97fcefbf60013a54837f2ae657d65e02397f59dc6bca27704fed3affdc3d833fdc621cc5e5f99b92a63 8dc236fb859886a0a0ea1c781327063c070d09ebdd09b5c28af9508f17421367bccf6bd0077f5c53b37f09ad3f4b2452 +7502c755bbd385079a4001b8cd653287dc3054f3b57de19d0ff8f63c0308c64c56f035117a8971d43654f89b52e923947e4760ac72be073136da70c5ad7ca1658cc0a2d2a880d3a0c0fe636fdb27b77ff260c4c1ef8a18da8e9fd777d732a37ae9906e6c4f381f0a3d941048d5a1f6f2cb8593873fa4bb1621a44bc2bebfbcd1 00dd226de602af4e9f8e25784bd1bbd4cadb0a8aef525d5e2d57b9f3555feb698765672c5099a7d6dd5faaded69d8d68b4804f26 b6955f55270fe6457a9431f506b512df909e62f34ac8f545fd5cfc9d554ad680e4ea7ff63adb5b23725d2a7dcb529e8d +95eca932d03f1df2e8bc90a27b9a1846963437cdafc49116ccf52e71e5a434cdb0aad5eccb2b692ca76e94f43a9f11fa2bdf94fe74af5c40e6bfd067a719523eea6b4e65730365ee498ac84c46e1588b9b954f1c218920cbf71b167fc977ee2a89429590f43bf637eecd91b0ce3be2d66bac5847205f76c06b914a970f543e59 00b6fdbc9c8c76cb2b822a940d8675889ca6f5132429da795462381ce29313a23bc132976fbeb346ed4c691e651028f873ce7971 94016d5a8e584aea2f44856f51d60b88efc5829141fd1fdf3d685481ff437377821fa3d7aeb6e69c0c731172e32111d8 +8ff68cb00d03e730dddb05fe0b2344689529096c3da6eeecaf097f22c7fa340593106b1f6726f06b7ce7358edbcf801ead959438a42f94cdb467b3cd5b17fbbcf75739805f9eadc869c33c604cc58f81591b0b8bf4d42bd53a801f0f829a31af6c129fb4f20f1250f959754eff8c629b85a716b6a18465b6495798c0c5166c8c 00203d77fac64591eb9a18de20a9d5eacaa1c3ec58a5ecdb3008c2d642e197141d16b3a9fdffe61429264f5b420f5e9926659a4c a88501e8a1f55436b3991700966aa89e2ff7d602c492e69c956da1d7c9a5be97cbe127cc6f29f3de09cb7f4fdb4af6bb +01451c4f09720cd53377a5ed04c907a735477378ed960235a833049d6bad6e6e89958b4c4249bf0f6d4f043530c9e5426deb0ec3a12b7feb4860757b41bf602ca95655155356ec35a2db8e2657998f56529be4b714364f83a140846308a2973907ed7b08e935173ebbce5e29afe1444cd51c92824ede960056439555e7e74450 0057a2e6a59d4871c3d547690237dd9846d6d5dc4ec0678aafc9c8669af8a641eed67bfea4b05fd6b3b5357ec4d0caf352691ea4 8d3c2a37417e4ce99594c59cedcd0aafae99f6ae053cde112b098144ad0555905d8e5a4f59e487cce84cd0521fa44a0c +ccd494ca005ad706db03a3df6d5c6e876ef859ec77a54de11fe20d104377df1900b6b192126c598944d19a2364b2ae87ad7fd32265d59e1f22be5833f20767793677b628f18e9619f8ca32f3af3b41c31e87a98d1527e5e781bff33c1a8be3a82ea503e76afec5768d7f7dd1f17dc98a9e7f92fd8c96fca0db518bd143d82e6d 000a3da7a6633608fcee9ce4253bbcec08d41ee6b00178ceb017de74e24d48fd89107c9f2db3556063abe3cb011938f4b4871795 9696fb2dd8ddce8e52e310aa8076ed8dfddcee00f7bc64c3f8a9416ee2dbb3ff2e7f83df902cf30eedae4c121c306c2d +5719e50d939a8d74efb444eb5a77cda48cbb59e7f976cdb2ea2848bfc558718b39ce27b893c229db94bf77992222d1746f8f52f858f85124a28193ae0da039c53d484681785f3367f6516fbb8a86560aea9e3428551facc98cdb1e9df8e2f37db823a7abc589f667b5c93c4c47061400220a2014197d514217fc252cef5a2433 00384723c8b4a316b450d1fce0b2645912b8acaeb3cad50860cca43bdc0206ed5b3b60ebdc29b3eda305d0d60eeaec261edc24d5 9276ed627f5b2ad0b14880efc501f32e766aff8604986b32fd539f16755e5a3b923b0879d0b8bf0d5e5b3803df2c5f19 +c84e5702a339259a61b5ba8ec1957f23ffc4f1eeef3a58f383d3731bbaabfcf49ce2ebb597960ac5115a2af1c62b193d4ab6c24433d5f168a1752e40145f19aeb6dee889a53a4fadd13eef60e28fcc7ed6a9b8b0ca286c1b3d66a4b2c327a629d15c148049e3a0ccdccf05cf22c31956014595e417060627c8125bd7c00f8850 00bd3136647572fef3de51b12e64b36460bd3a27dc660c164fc705417339cab21f9e1f9be0f3da926df459c5ba58b701d306e67a 90a8bde3c6fe7b989176cac701dbd304ae746b672d3a9322a130e724b6c73b5668ca3eebcc7fc41dc1c9a80ac4f50d81 +c90bf11d04a708e64b6f94d4cca64b92463eae878c377b188c82c1c5f05a038be20eca2e18034d46f00d9a6fc73c4084981748ee9d2915d87aee4e2321f4f9e11c176f01281913e324700d9cb474b7134fcc408fb4a7006acd9e63d4578ed4c2729d8e0d01b1e6174a43a024ad261eb644ae98979c3cdab75af357f6dbdf5db1 00495be0b0a9d357f6155fac008cec90442200bb842d89292fde38b7256e4117284a60249b3101b3f19f778b680c0d1d7422b84a b7a452c51b795c2505fc9bae29416e8ca07f98ac3e218697bed2da23ef6a0df6a5811b2fa15e6cef608ef3dded6ace69 +e9b2a33906a1079280100039787377c2971c378b92e70a38ab41dc23979d6fb0c41e53a21b37632407adac6f212341cf6af8605b4978c85c9c16960e1674247f1795cd73b99ff28cdca024f5078490513c77114c2f52288f5376872c331151d7b2c08f7794f2c1f9e0d849d32d73636f0aa899988ca561a76f74543b37cbf3a3 0079626354dfc4eeeb51fcf232ee9e6b0130c9bd40f15ed45606bb7faeca8f359e0c3e18bf12769254522fd4077eb24bd5454871 aea03e19e8e1ec2cf9a141b88c1b8bd3ebd597b4ffff89ffb1c9ccd990c48829cbb5320f4f1b19b631a5d1011b78d175 +672db3fb8cc8e5f831be700498d3ab3aef14b7548e8011b21351215fb6dfa09460d18f52c02c8815baf396d856a429bb9afd602a10c213af34db80447f4c06ab4bd28873c88eb9639b199042d4b2cb13cc364f734fd4ab7bebede7dd4da63decc0cc1f84e34d760013f66d71641073f16c08078880b67230f2d6c6bfe17d206b 00ab42bc7d0e3c23f8bcf928e25f9f027b56f270398a1d37bea0ee5426b944a9c9ba6d0d7796899543feedb470f70b2ab148234f aae99fdbc8416875cacefeaa016fcb30418b0993deb7f8e6cc6d44741a1eb52627d787b9ca785975f272a14536bc85be +d7fd06b89226cfd66671ce5b4b656228c52d986afa7f6f30161680eb0c9cca177992a8a8c40167a64165c518c55f678702125709361b536bd928567c97737bd750d0e2e6e0c00296a6ca565f7c05cc8c54ae7a4e0c334c6a968fc18a959c18ebbd924457701316a4e999fb11084520dac68dc2d69187134c40891af0355ba89b 007f7aa2216164ba689459ee5d5ca29e70ef75a5b2a4416ab588df1dcb9164330c0b405a9d80c3acc41c19f58e24e17ecbc0fa7b 8f059bb22cb91408e2b27310f7e59b4e1983ac2ea6d29aed858c7be64e5ce676ead45a8bb2b6481e380aa745b3488d08 +83b7e9d3ec638fef51d2885fff5490c94e2509c126608f82660e5fc523032f3e85d69d9b76af145f6bd916dda35775abbb6d1902bf38880f8b9259822055c5b1bc726c51029972cf7474cf2a812f3251aa71813476bff55598d079f075a40c6c41498bd865ce960c518bef75a873b9d010965f342dc4b35ef5c5972efe6fdd18 0021d84f070c6823a70f1a74225a472118c93ce9dc509aa6064051ca4574939dcfa96be862069424bdf1a23f62f2868326422e64 81368f6ad39fd9b25ffb3220a3eedfa7c7667d5c2fd725ea82a5af17fbcd720a1214f7e3f0fb09cdcb8b8a8e85c2b63b +c62c7bcc860f0e175128e1127dacf935ce62ae794cc4a0ce7966bceb023ac0498641d7281fbc86f9ef470bbc77f608f83f8d0dd6299cf08f2cdacc7a9642e4246df131820220e5c05d0dbfceda7f16b86add4793e9b6244d96b5c07cfa23574ceb43e8e8b5483192a92b301aa3b37702b8f94f0129d8af1617896b34990c9b02 00b6645344d17528968c719091b6e2072388881dc10bdb4c7fbf41906cadf3699b30f9c1dbfb4796d009480664e6276c0359e5db 884239313807756882102d1d2c131ae7ece1d87ac1ee3ef8351b9af45ab06ff5a63e456a3528d2ce7c579d1ff701128f +b5bf38fd9e822925254418475a1ce762a94e336f12b156b1625a4574fee11ee472d537ef94b4a4b1c0a73b0140d0b818cd06636653e6c07f0f100118242a7703756f1cb1119b3477c4ced99cf45e07e83b7f2749c1a5f8d8c9272d221fe17f7c6a5fb0f8a16af46f232ce406aaf565c6b2766a2f6528c82e74fa1c0a7fcfd49e 00f8c2f770cf5f8e1f900e996ecdcd84fcff5cd959777fd005d721a419123221a3237e39834b270d37752470deaa6cea023c5058 880a828cd644cf277916f1b51a4685533df9f8a5c57ad2746332d22d30a5cc7ca5fc8a1b044a3e2f10658a83abfb167a +6d3474770933ec01b76be789304b6fda423b12a0ae8c87a5ea8d7ee9f71300f39440e1c7f5aa4b47c1a8628cfc3a490b15ef292a741344f40a8fcdd02cf3863bf3e32d53031f503703deab17fc52b3d4032f4e237dcc27231b85d3fd60b49ed7ee40c3344948d87c3f47564d20a11d50e4e520bd16c8701694fc70901a5da625 00144adae951fe897d5812ee4a16c0be4c86c5e57e615c398f5768a1223a9be20fa82ceccf8a16a31432bbfd17e594a4cd8a6a07 8c3a01031781197c5edc38e037d1465f34dc58d31664d7763e9d7f23874c545123b9ca11fe4bc981b003fc1383387c2c +92ba7aaf71f625f7a2e024058dc8739da3567c306da4a812ed9e1542b7d1e982c16082166a59720203f4524c3bd463a662c26a82ec7b4376545206e650eed0d3dd7909dfe3810981393070d15c45dc4a75a8c5bdeba533cad1ec34fd20466a61e4cde3b25af9a80a9a54afdd7de1cf2a74ba32d4ea0082a037775413c61a8d1f 00a51f065fb32c55bf4ff6f18ba9d488d35d9f8da593adb0ab1632533284e0adc43ccdbda9d9507b9862ac63b5ae7b0f78b479bb 841a99488bb2ac753febc7159c6e65823b5332fdc15b1f4fb0f624dab5ab163a05fcd70c36d9b07b2bf81ba0c5e61afe +b3fb9e48c333201324755a81f3ae5d4f0e2ae7cd24238fcc66d858e3aeb1ee03328660d6399676eb1b7d8285ba571e214d935bb45516fccfab57b8eb4c3d5f1d7357c768eb7b5e7b5710f599614bd4e92706eaba31f8a5e7e57af7ed13066af50b4540ccdc126b677789920cef8543907f0ba9dc92aae343d3425bd784ef483d 0095351c0bc07acfabe6477fe85f97eab520dc96bdd58b44b036328ceadaa56a1904d2217c5fd25155ff2aaf9005a3e2687fec81 ac02adc0e25d5bcbaccd6aac73e6298f460bb06079301e8fecfaf78f3b82ee4bc35ef5ac828a42ce0001ca27835e19e1 +9ec5f7d65082264b8a50be772c44277a73ed19199eb275fe5976f9799d8629fcb4a59a8d55074cd2eb2a0e02062d3f7cdeb05e62931a24fd1aaf14c257944d1b42eebd52726d6fe281211b39038e52baae077ea4df89675d860d6ba5a0f998d049614201b872e134367acc90066ac602e478ac3e43c3ddf4b0ca0aac1a68591a 0050245c1682344fef23bd549ac8d1e8e44b2840c43eec1cecd33daa4e9ef6b53f496104d7432e14248682cfd6f5b4853b65adac 9452191de2b8e4a15ec70fc1dc0f2c7b1ccbe196bf5a442460d9d1d74c6a0196a2bffdbadc347af54b63fcc51cc029fe +61d657bf472676301503f6784b7286fb39fb4186bb88abf1edacb4a2693d0a1e2b77bbf2758c84f2cbfd1753e20841b1cd4b456400d53f4d686e666943f9b6ffcdb77f510be97536e9698fc84ae347d483bc8984548d1cf86b9b40d360f9c0dc5bd1c55868e26fce1460ba94ef5e94eb63c9f0776a0f446c0cfd4106d9f36352 008d3b0277f0e9fe54581d3a9499ccd7f015c08339591326859af969d2a26284e3b3beac4a0b74d324ce5cb5f38c7995e4e3a41f a2cdf25dd9410ba7907d4a931623165d50e5927cb07ad7ed7daa7131be1795fab1630b48ca77523fb63b963d0d068bce diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B409_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B409_blst new file mode 100644 index 000000000000..61524dbf506a --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B409_blst @@ -0,0 +1,60 @@ +f2380acb0d869d1cf2e25a6bd46ebe49d1c9270624c5507be4299fe773749596d07d10f7c2be1c0b27e86f27b4a6f8dff68cfe5c0b4c58dad1b4ebec7bd00ab195fdd635d9fa8a15acf81816868d737b8922379648ed70022b98c388ede5355e4d50e6bc9ec57737d8843fabda78054e92777c4b90466a5af35dd79e5d7a81ce 00beb0df3b0e05a4b5cf67abef2b1827f5f3ada4a0e6c3f23d698f15a3176cb40e85bf741c9fbc78c9e207fa7302657527fd92fb acf92c836044822212292044f44ef9958568067f6a8166fee67254880302105f69bf1c6df6a5477983ddb401d160daae +22a97fc0a9694dabc6f274ab52eb592dbbe8beeb646ebe6cef60eff341a13017eef980aba6d24ab3afd976e2f6a84cf652654d4a54a36b2f2f62fab8858f8b0479a48fe9f47f8fd5a4a1f3141a91cbca186507b2bbfef5e4c4d2df525f04ef7c4720fb443ccad540f03a2be468d88c9545d1dad579fd7cbcd103bbebc9e9f961 00504865a30984a9b273d1bc289d734d10e0aa56e93ab14720f1a42a27d8cc932cb8804b963175de6fe57d8eafa8ab7ea0592dfa b4b2787a08cebe91fc94142cf4ef03e59a940de65ac4f5793eb155501bf397e387cc9dbf1a8f763db14642f8426471bc +af36c04af0e3fd64bf52dedf52fb788d2d1bd67fe05d98880cc7ad3c20436abf02f637fcec209fbf888903fdec8682717299f8a4386768153b7faeb6581db57fb9aaf4615b4ea8d924198fdd158363a1f40312527d6bd14c13d19985b668c6b88a7548104b1ff057d07082eea421f50062a315bc3866378f2d2d634f03fbc0cf 00cc08a4ea5ebe32027885a8c212870e7c45b6c610117994d6a42a284c05199414a3a0e8e6645ac5c2ebf21c505a601f69c62b85 93bb38191b5bb1eaa2b0269f758cfe27edbfc530b6cc3b3c7222869ff0189a7f8f6fa4ec89e32e7b2cbbf4e93fa41ab9 +6bd6f52a6204b60f37929aeff28c87ef61ddeecc231e52a7772275f9329add899c130956f8c50ac2698aad3654fdb49b74a6427a62a11eca0a8ee8b719b8c0df7b9f0bb0af5fef4918a8c83367d29fddd04b6a1ecad904471e5b59c8fe3cdb06b4f8f96419518dda960845d83c49a49f1b1f2fd1d2682a9d60c25fe3ce982cf7 007156ef0a74ee1119532a2a7e8c02be1559c3c21897af9d5b34553c3d0feca4a8d5929d1945df824478e0c0b92a6fac8c84f639 95c2845b63350426d1c307bb57987b21f7578d67bdcc883287af8861b90201357ced90f803de2c5f34ff28b52776036d +0eb8de25f63abc9cba16823270e9b6f3fdedf0fb90f6652a34688970932e3ae98f6d3bf0fefc5f247f72960a6975bff1f1acc2188a1775fe8974b2bb2b4c8d226ceb735113a14009e8ce66d58808fada4e6f697fd016829913352c0f659b6be354a067df00cf74919580750aa6064f21264d89dcb28b3b2d4d699115c36d1310 00a95c7abffa92e2c637611ccba66ff9d2ab121b40a85c5b71454cb0dca1f098ce1be8d9ea4933d1a91bcd270c5a33687835d6e4 ae8e3d66058745a97b86c26d29ce32ced16bfe0a1ff7c7ecf6e763961192bc8f180cb3c77a8295c5c0550e5ccfc7f870 +cad58ca7a3b9967dc0ab62a43037764f8074ef9177d60bd98f623d693333971c24a575ed03cb61f4dc2e3d6285fb1204502a540f3c0bbbf23f5bbbd1544f322ce35d949d8b1d8edeb82e90927ac67ad49c91007056bf5096bd690d15ac00e1874fe33293d8003a4a2b094078cf09af799dde384143350c54a99e1f99cc31f2d1 002c438b07c6e0685d1f94a4bbafc013f8f21265d893f54e54c3ac2071606ad1ffacace0b8367aad724b1d9508c65ce52282e397 83a39203e6ba467f41b317129dc02df6d45becd2ea200d68d3aef495d0557791a9646db15bfaf1fffc55769088ee9bbe +281ce2643799bbfacc7d5993683a4fa656040517854f3c2dc7c4f8848dc305382e34e894d433caf12d8b493020a6a08d1fa05b08bf6c53127ad5f33bbe75b9db0615e3dd94408d028dcf3cb7598f6e7cb4c787681dabac7cba2cc06fccb7506fece6c7c1c1bf622d525ae9737085ab4ac578905950002024f30159cf0d99f50c 009e8658f8f9e6cd98c0f4f0fd20d64d725653aeba339504def17f3ad12a63dc6157d80804e5f43f4ff48fc5573fde2c615ed31b b7b0b4580dc77a868fdc2bad055baf4a7bad9b5270944f51958e8210cd7e15760fe91841f6bfaae2f4b483f6cc3410e7 +0c061da1a16f2be130ae3b20b89745e840bee09633fb49671db28ec9a051545f57ee07e2410ae7ebc61c9af79868d3047705bfc64ac0c04ef0b286e579b650c7165443631e49e6a53c84cefa5625b1e1035a6ed89b8e839540040151132a937666524265e099272c1849f806db0fdf2be64960d5b5853965099459968e5beb32 00c4c13f65eacce85a51881caa6f82d9e48ec2ac574947d2751823a7f072d38bd9da0cdf30b6f19084a6d291052e7bbc2e1349e1 85634995e582619e6b1f47c1495858cba9278932496f0112d4f2ceb8aaff3d0ef1d7e2d42191ccc3bd432749a870b62b +74ac2e1303297efc3ed8e624722df505df55b7f33964cc0d270604cc48b58205d8a11952232a8feb0079baa30d7d33660268b56a5a3dd90105f0703abef8f6636a99bc63bd47d9df100351bee32d8205dab0dbd2af36fd173409ff8d1fb7b24570f3c1e968458f58aea5aa2f46731ee91ffd6d3a060af6b3d5020daf1362af3e 00da591461791ae7847e6d8dd8df46a63d3021644abe9520e158406c96540d8fd82ecfb1c3f6f5cfd7688c7656cc3e3dc94e586e 889039a0ab429d913a7f0937b8376f1421fce612ec66f36a42bdf7c53cccb7ca42dfbccc93515583d2f9821c795cc677 +2afd17344552ccc577b0118caeb7dd56a0766e25f84df17c0505f9798931374b48df89a48c64e199108c36e00c0bf00a97ccde55787bb97c6765601765ab5417f3e75e35a9fe5e0f85a721d9f08440ed617afcdc200b318940a1e496040a6ad9090476b0fb4fcceee77b3fea11de09e7fb14853d1fff8ab12d66c101257e2d4f 00b5eb943f0dd390b737510e2bb703a67f2dd89dc9f6dca6790bc7a260cb2d0fb8e1a81ad6009ed51010e7686d5b48233c6c1686 8cc679fb16bb965d6d9422394deb94da1559cf35fe717af485a30e9a026649a08c594fbe65b7f2cb24a6df6a703d7d47 +174b2b083541f8284645a810801e72631a11bd7bb805f684a7159e055afc44357f2c80df2b7853678d34a04144e0ede2327d03db6df23769ec41194a8d9d86af74d51c5bc11ea878c6a80689af71d3fdaf1c651003385332a512e03dd040c33d9c328ca89ec7ee9026bbacf30a7f3a68e0d894fb9f7100ffbc64bf17679dedd1 009cc63f32152284fca27ab2837bf1343144336a1fdf15b9727c47e877ac69ac9cf4c97b4bf42f1ab10d73de8597a554ed099efa a73aaeae173242accde9f13b52bd01fb4c991039e1b25f723ce82e78789b58623fcb13356037f7d2f64ed95ae1bfee01 +758df71a952cdcffdc417b9fffdfb57582ab5c5473a8bdf0c2101953b023b77824263353dea0e2ede1f800a5757ec6ac0e1e4e3ab5a4cd85567d2d19acc6b7069a6e7368401cba2b6e642373654bec0ddd19fbf032794c15b7ef7e714e13e36875262c01e77766ed53cbcf735936dc9b33eaf2152a396349c82ca0297dbae4a5 009950355e8667bea8bbe3a2c4988436ab5394551b375e27fdc0c1a1d1b07ae957932f428f1aca0a486e54cd0b5bb0a5c5650641 aa9469dd2c45c1c8ba0061a44a2d14644a7df251eb52105a47c42e762817a3277c47fc5f7a96b58e1d8b453cd10df56f +b96d9f66b2000e9408d602096f032b112f0e05ea874229ab9daf6e05bee49b4722e4f2d8bf2eeaab9dad94438c76b7cc64dcbb59cb4e03f9ac70487a1d24d8d6b72d7462fe738a17edf381d52179b3acc0c0177c113eb4d10e8e78041deac1d56abda0ddf892edb8be956d285e7236bc6794168f8a180f622dd5f2b9e690c275 00a995493d6971c2d7e8fac3da9f8c0b5afd877cfb94924cfecc167f9d87002136ab253e3a4f9ddf5c9c99bb1dc1af0c6a3a3c4c a2d059be8469d30604b81b5dcb4f47e43672565fb03495d5659197c8d343ebc71da2556c9b9a88839ba1dc30024cc38e +e7ae60ac55e6ba62a75d5328bbc15269d4638764169de0bf0df043d15f9152bed909b1fb8c7a8d8e88ac4f552c1092b62db00958a3a827f64896f6de4bbd8fa5258d6c36e3904d82d3eacf6eedba50b0242eb6b01212288448c3a9821c4fa493869c01149ff1850e8115cf9de1618cb8744626b1951d1de305745507c8b21045 0070daf435cdc26ad66c3186267ad12d10f28d32d863f950cbfcf042fe9dfce553750ad098f82f7f1650c1126b3e4451bee6e11f a8da8278357f62911c4fad5b252ed5c08d73728e15d482979f36a43e01dbeb78612f4e9d2985186d0afc98e019e69004 +666b0dc2ddffaa7ffd57ea3b2768f02d4b77c16fa007c6d1918400d195f068cae2dcaa69817e6e4c70d5b29c5598efe2d957bd12d0fafdcf5ac52dee80a2d46e77fc18cce2a49bfd787ff77b942c753974d22434742bdb494590d17c42af725b1309e54566276af3bcfbf5e174d3cf191b85903faafa1583282c97e66c5da6c4 00f8121980dfbe9ad0bf92383c7cab95fb72d5caba96e1de7772c6a179e85414802fbb86d725401451329287305570ec7fdd873a 96c75d70a29f671b1b5af381d4e71d77c25483e553e8bfa6f54045e8cfb2c7713d5a9728c47138a56594a574de0a50e5 +3e967cbc2bd936e0b6125dc5cf885735bdcd2d95b2f764de6931c4578ac8e0e87abdf96375481df67dbe1b6c43537e84ec62bfca6672cc5f3ea4125abd4a4119edffe04e42411d338e8b10abb1f1f818c50a9631a3f89feb5be5367bdcb0a8a82c96a427ba6ce99f9631d4411a2b7f5b14d32cb3901dc9d285e4cf5508940942 0047682b2e3bcb5800a531858e8137692a9b1ee98ea74e929ce4c919c26ae3b3f1d4122d07fd9a70d8315fab727ccb67004187a3 a6bf975d635169de36b52d7cc2acf56ed95981567a8e9a77923e2ef6efe2dec02cfae653a8a2203d7b52a2d645d52d7f +ca1c90012eba4e7c5f01d8cb3814c58f48c03a16be6ed86934014365eee547070b870d1d26a872cfd28b60d9ee0a66dea223e9eaa90ee28076188d6091f26f665684f4b486af70669555db9058d485c677b2a34d4a98aa8d6f43bf6f44aff2a23c5d765e98f0438ab81be0585a5be29daece5d4116f44ce6062753a3ddc505f3 0040cd1a06233ac27f3ddd108de7c6c0982793ee620d71982697713be9fd5143658929924cc88747a680779bb00da8a44e1e7d3f 865fbeed404ddbf69b924ea3f8afe1ca617043d16c95d52828b5259545325c550d60d1c63980d5cef117cbacbdc31648 +a54c4351ebdb075d6a42a787647390f864b2bbfd8bb3d0e0ea9d767200fa344d1a9ff091bddb186acd69bcaecd767068efe4d752d185bfe63f6674279d0e7192d2077c400bbc0d5599ee28507c1253f05eae0687b965a015e1f3a292b4650106765266f5c95b77ad2d82a6a6e012f233169eb6b8d83576901cfd4a927c54d7f4 001ca6f752aae4eb7fc9c73a08d6fbd96bfde5030d759a2507bd45b6e1d1487e53abbe98fad4f41976364e0a1d830910ccf97abc ae81e28606e395d0aa19ad8027b22b6a482581e03e0dd65c49b44ba57f9f74ec425d26f94c5d214c603d259147e91959 +6723dbddc8720feeb75e2a061b7fc49079f999fbc79ec8a8e01ab8d35b438b7049da5a23c49a58101742791f84f45d5f5cf551cd7de6926a0e2c4ffa1e378f038da597368c62df8cd8349bf046de46d02183dc05b3a3575f5f232dd2970057200e2c9cb60eaa6b4d72f8b73d4d40b98d1cc801d1a69cb5ed780a75a4064623b2 00fb9b1a9597d216028902abf743d25944258b48c9762d4589fe660396130b75f6006cacfde60f6204463cb8c18b032de1dd68d2 ab3c7d2266fa7fe6b938020297ee25d7ba8e2296741a8af27596c9225aa717232d70b995c39cc485b0c7dd9012220585 +ed53cec5e5500d62d38c829002916c657674ede4439c6f405ba672327ec677490e656bdd698f114c2ab5e6a1fc94a1a8d64466cfe9eaabd23a8b5c37f76a3c0decdef73b3e7b751cbf3b0817f4079560b5ea34cead88ba374201236bffc48eaf289bbaa4e828afa7d732473c228ad00588c9b443d65b998f21c3d7a9e9196c08 0032109202d754da290c266f74f47805a06e6b5c3f721a72fc97a3bffeb8887e0c642d49a6bd034847d0a5ba09239c5dfdf0772d afd8ee1fed742b6b01defc8e7c277223e59c59c3566946f8eec51dfbe4bf104dbdadf725f4d185cbd47c5e1c4a0f1cb2 +13829401bd41e9fe01329e9f5a002f90f1a6ecbf25fc63e7c1345f265ff02e496230f706c6ab377ea52d8707b54f8fc5c7f089044e2bec1dfc66a07da76ee12fb9ea0697d87706b0ebf677600bd2fe117f6cdefb8bd636a1b6b97549ee78f992c24acdf3a946053f06fd012a9c703efb8bd929a66aa74b05d61bff0395232b00 0080536e820fac59b3203aea928475043b2576446619001647e35693a9e65d15236c3cbc12e1bbe0eb305973535c882b70197a92 961fcf88df289b1b7aae2d1bb8e82cb37851b48c11cd490f85e0800b9259c0a10dae7b3f31c63424dd16ca4f3d2b3c32 +e696acdfcc96a6c088069b7595ea9516a36d8fe04dedeb789fbd965db0cc64b7017a821015f6210b6989e515def5a9605fec0d337e4ac59f3101a505168bf72ab6d98ec62a71d2f94071fc05b95e98d4efc59fedc138e3e49c5d0b44d1f48f7b1e7c1944ee189b242950d2bc804d31c7eeb45283c84638f043ab9533976433a4 00b05e5f0dad9583ea18fb8fc4d8c75fd2e3cf9e92cdd9b737485c953620d345006c31c288b380258b6500b84f729ce6730e5303 b11ac2469ad79ed22b8077581bfa28794c7b4c5609147bfe273c7bd24db6c8eb3f7a0c40683ac43c2604f9207a6bb312 +4058b9a8cc15ac148909eb97fa32aafbb6077b168dde91a411dbc973df7db056dc57ff78f0abcb70f70f800bd752197d681f44df4a7817c0e7f60f8f65489ecb6167c14b525e91fd2cc5d8b80ba380a83d031d5827c8b1262c687c90ef0e62723d9b565557f9f6fed0db48f3799274c2cd60a14303406c35802cba6261121296 00be1d277813e79051ca1611c783d66003ef759b9e104f32298017fb97667b94dcee1ce807dc6b4d62416e65d4120523bf6a4edc b81f42fb56c9675573769dc01a3189f64dc88880c9ccd13b79aaa79599ca74f9997cfe5af9e4e95e062b4546b6f7553b +e793237d46e265ab84ba9929b196405faa3b0e4686e8693567e53f68e6991e57677974677682a2510c4c35b1968a90b32c4941af7813775c061c008a60f9f671cf7419c94253d6106b61e65034497f2d273a5058379bd986e3d917f708f0a2bebdba150f6d78a3af9c722a2430ab0f4bad602e91e18aaf258e3785fee78e4502 0073c807bd7e07379782ab790720de4ae5106f16d34e80ed70da5b1594e660c9b775db94066b93e74f855f57d88b6ecc6228aace 884e7243fa5eb9a8d15078300e94fdebf22a92444647e49a842ebb4fc067c4ece3c88609c0d1b53b34fe79f32dc7eb3f +ffb8bc80e7619a562d8506eba7658bef0c25ace3dc1d01bdc2ef00933d4fa07b80364e5e5826074edd46a707dbc3b0ab19eec7ea8990839d7fc0a80b70661204c52bcbef57c1a7bdc861c10766033a82dafbead283d911a9502d5f9ef0a39d35ef26f3616212d4bafcd413ffd18b424fe09b48ba02ca5d97ec996205cd49d22e 00a68379b2296a6c944ad5dacb593b302d8ef0b05873ce12bbc371d705f308c739d21f343349524aa72f05341e64f7435daef112 86ea1a735e01942c31e4c8d81703af8860f92f8ffaada55e9d82f452858abfce2b245043a931c3c7fee44d02558b1543 +946bde90a5b903dd281a51d7fa93d80f3fed07eaf50c18fe9fac5acf67326bb18effa3144e25c151efc006a50a274ec6c6a5d573051c4e2d117ceb0fa125acad07a10fb6534a8e5f5b3da2a1136779c51377bf76c3a4a93c0c6158f729f2293e414fcb952c9509f228c804f0adc1daa327a8991d48ccf4f3957c5f8ccbe3ad4a 0026046bbb269ddb1ec14ade56175482343a21b7c265026cef3c7d6a1ae0f6a68166b9e6c49a6e733ad2ad64df7137ef230038fb a59551576e8d3a6917d1e15753ed15cc9ef0c406dbd2132f85c6ce22891ce3b82cc0d632a1671b5910c429243fb6b319 +07f3fe1369ebfcbcacd66675bd4ab22edbbff72e68709cb57d4f590e49440f01691f490c58b5117bd24aa2fe2101b59c61c417c918ea08ea34bbb9b8aa17491ae5d9329affe894f42d7586017877fae3ce35bb80c97f92a004380374ec91e151995166e14ac00505fd1fa810cf02981bacbcebf5f81b2e633d3a3db6737890f4 00bbcda66978ea526f7bd867c3303b625f11b94dd9ee6e2c2f8688ff07f2bba83c662949d47ad47fa882cb7d203a7f0ef5dbc52a ad45a34111750b0ab22d99738edc11915937e624f7bc7433ae5036265fab8d1331e93ca6b43d2e337cdbee37acd24a5a +3a1cb13438e3bac9ad4ab1d319e90e2c9f118dcf1eb54d6333c674a665d41451f93cd4a9334cd057a44c010edb668254517a63700a31eb0ca474c84873e486f2f8e158a1a7735362ea0cff8ef17d959ffd851b21a91412709b3c729474d2cb40f6ca0e397030eb2611b402916e4b656f0fd868247d80be3ce33d52054b7661f0 009be3dd3442e0330750f0a6252bf9cb317f32f942ae516a4038dea2c40ca6484fb33611bef016cc64baf166c122e87c15466fd8 a5bf2e70beff54e22f9905c7d33966ea6da376a4c3b01171d9e7d5c88bfc30ccb49534aaf3e6f42a10d9f7fb98b8a2d3 +e58e7b881a563d54772125b2863718690a5276c93d9e1c5feabbdb5d6f7c7293ff0f89805b53663bb417fdd46874b8e6a466e7e3ff6737930a0662af1d5879b071b0dc4d014778dff26a2eca5992e763bf4c4698c382ac947215aa116515876008a56e5bf547857049c38a2d3737ed3393705fd346897c3beb80caab88e5b8cf 00ed321fa283c662e87eaab99b7715e6cdc9b42e14fa5bbe2c56fdfb381369191a42da7e574839f90a85577485f19446fccaf6cd a3edeb516104984e9f9024e006605d2e49fef3c4be79e5daa7d8352b7696ed463684fbec04d8339ef19c623cea63c718 +8889ea1da1cbed98963941f6ac24f47253ff6af52de920765214f2024aeb04f7ad46936830a8eb04d95aba64ed7cda6ef242f454b67bc2de38a46b6524bd5c96739c4b580e89829a61a8249ec8dc27a50f43b8554cfb6f4fa4ca6875983d4b60a1c6b49f32ddff6fac0cafb64d55c6f594b195c207a9bd920dcf20e0080920bf 00396b805073f3c3b552b1024dcf35559ac44f255b688871a3c6657f727a4b09f3806cbb75d26a00ae1728be632387e804775a8c a20785d01b4758a07e2b01fea8d53744474da774962c020bef3fb6b5b053480e7151252e839bb622cc3bafa0f98ed15d +55053af9370901e38622734a5bc5589f6a20e258627f381fb0c366f3dbe58394e5997e978eb7ebbc530f6e6186f48294149b8594fb551c31c50521a8c4d67e5862921695604afb23977b6a69b21abe75966fdd11bfbdb6b51ab0a474c5fa07c4de7872a3bd81acc417655090558dfcd5af449b3347e61fa9e839bb9457de64c1 00a8fe323f6736bcabe971c7d964e75dece70cb54561da48a11c40027ebddb23e41c7b48600f569500fe8ea2abebdf480171dde4 8bb792ac2551d1f3a808156a4de223df400ed50acee4d8fd62677b1502538c6f386d4b22c984f6ea174be36585ad51d1 +c4264330534a6c2bbd8a3b757e0912558302ce302f835ad8c5474993832fd30036fdef40b10ee37293e871db5b0b149654f9e543e22111f9709ef45732125f713c031ccfbc9a2f3aba160c241d27be4dab87ab2fa9a795752ab2daf20f9d06a98d90d01c07133adfe83cb11d5176525e1bba6a9ba70ea48b224d46ddd8103f65 00105938ba9f25034da3e032dee121bdb192ac2128b50a2ed4bca042e96cfaf4660c9d35f3e67bafd4c99f9447e6dc408e0c4471 95bcc3132db7fc5cf8a8cd54b60f007e995f4b677b397a9a521b7fd07234a66c05477d37dd5c3d0945acf94fbdbb5dc3 +3236f1ad164e1b25d828f5202e3513c80c72a577aa9af56f041fd96cf5a3363f4b827723b1511a2f16360e32eac90ac55f4ee1146791420ef9e2af333c17d157b00e43992ef6f2be2d2f211361e468413dd93fb69232f0a0d110bc5fff361c0410344aa0636bf809062c73a7ac7c142063912b6ad7e1626fd2a384f35faffaad 00ce11677ca818537dbaeb880fc967dc8bead203a2538a55e756679c4a9e7975b9b3e6aba4e6c6eab4152d0c0939027e9b0bd92a 8b7713f6ceb96306e76d5808351e59765606d3b506ade52ea73e268636a96d66b53da3323a596ebea17b7abb276319f3 +6c400ed098d8369dab6fde3553afbbd4d47836d0d12dd16015f15cb8d067a39391c85ca4e78c62b8b72c1592349ff8dc52db8ccb7fd80c085fae456dba6f4a2378e184dd59238c92cf04e40d43a66b342d2a1325a0bab12b1ac857f0564c27b35e6abed02ff5bbbdc3770ddbb2ee0513df48bcba925da6d61583076cd3129603 005a239ae0f40d76d8d3589f1662b5ca12176a4b2784faa8339b54e96a1e1294433a4d83bf904196f939bd8b33bdb4be340ec703 b25089e7c55e074d7b1ee40077b85cbc1571b4be26607843bd71552a528b81aa9997d9bd032eb6988c230173b471546d +039a149eaef2de30b0ae457b376ce6fbf88afd4cfdec02d3c5e00400d3b0484c1cd6ba74db5de65d6f2fe39871349b30fdf1ef29bcbb9e182eb3ec5629d07d98354a5dfa82d7f0db3dd10d1510c0dce086848a198893ca5ad24a663494f0596b4eee86199ea85e7e8f2f76e7a6bd4a052c54287f61b391f1e52f96b606151c34 00077390c62ac41aca995640fde0c79c76f4ea8a8dbb22323ed812bee837ab8798c5d0ba976c7aa634d4b1c2c155de2709e7352c 8e207deefae534c1f841db4b28f94bb4b5f31440f9194a6cf09c03cba18aae0acec38ab529f781ee8d13be377048dc9c +08617d04fffd6644c40f7dd57919f7dcf3c888f4147535d12ca658302305bb8e220bb17ccdc480254004b9035b357120580882ef86aa5a061b2850100285b7d61588a664dd4f5394f5478e68a80f610c9204d056009c1c9e902161eda33ef61aa902e96b6f094a9f053135692182943d38b9763055a38739a2a2d133c5dbee89 008bf23b09fbbed1b55769907aafb97f4759cec98649b2c9da5157517d4f85bb70157076b5e4aaa7a940af042302f8be06a84ab6 ad9c55640a6a019cfdaf255049ef64b204548cabc04457ad0936076176c8ad2b44f5111e0bab4405102fa74717f06909 +34c959f549a307f21b850ae105f41299b8bc94fc292aefc61aefbe0a1bf57576ba8d9b80caac635e4edeb22530163fa9629665fcd43959f68eee32482f1845a78ed7278e6e43d09ed6fedf465001afc0d61f1d2e1d747623e82a762576b879c7024e34f43104593cdd691d53bccaeb8f212dc29bec6bc94cf69d0a8491db124a 00082ad05d19b8e16f80e53a4cccf6869ab5128c5e622ed146fa8555985ccd2aa3b9957dd374586115d4d75b1c01cf98ecfc3646 93fde8240a18df7595c06f078fb5e530c35dc17a818fbe103864c4f677f9f5d810c226e09d808806818d6e5c1a878029 +514f4de08a6f49edbb6797c9dad6d33bfa367cc1a1b58a5becfe646c7f3352d5c5d95f7456e7112c4ddc746b9076b9756ae3916c07bbe6d3823895774a42d25d44b3309d18bfe7e3ccb1f85dacfec1654778c19e2981a853c1f40a7eafd16d331093110698c957fe9f1d86582706a6885543248b944bb70cdf9d2ea89190cb02 00af7e581aa4f9be5815f0c447e39de00da9194eee5e5f609668b9b69930b5b48a948614c2250260d1917f0ebcb00ebda4bb52f8 b5f2f8401b6307bc3c7d0032c03889e6737222bc3a6d5a78ac66ec665f226ab716b94c0bda9906a60ee4e04b011a6f9f +4e5d16cb1dcaa1abab1e371e1de02f31ef4e0944dfe1fdec45ab64326435b2af9aaf1a6ed8fdf1a6ab1182bb53a844c7cfd66da30aec0d41757f5988ada0017c4ca752597a9fd3637668bc1a92bb1556553f28d66805bb47f1ef91908ce098d452872da9800e77e1fbd43ffb0ed6fe6a62185d4be73ae96c9241b82cefb2da22 006d14107b08354e6a41d7d7d50c004419db8bdc50db43428df5e86084551237223c498bce71a17e25695bc438c5c09e009c60e2 b82614a849c5eb6320dd2f0183175c4142eeacf6c0d8c321ccb57404e0c6ef863222a406ef8833912c8aba9f0faf85f2 +e29e75269754ec1194270f5c9e8267dfdd8c696008b5ebc92bb840981fd065672f07f6a0f1b19841adfc51b478371e1a0db9c3346a9f0a4ccbdecb7040191a00ddfd0a8faa0e69fcf544319c0155d02797eeef99fabbc55078f9d852927c23fd931685424249b87ed0c70a4a3e2d3b9a2f92830e7d8f7650c0bffa8f8986b7d5 0099d96d2dc9c79549f031bd5346cf6a8544c312a3fbfc560dc8e378efdfe025b0e6e61e09c04c8bf4133396f993b0906c33dd30 ab1679492a1db7a5babcea51e2f6b45d75720f3de2f156e9bc805b499e64b84f48409bccaaa5925eba90cfc0dba80f0b +1a538eb447c18494ad5a5ad27be67fa60eb2c5cb2404eec1dbd7244cd802b17ca5497e779d5f779b981b165dab53ad19fd7bf2ea7dbb9b4baea782a43d758202f147e59d6b6b8ed54f4ea084bc18519943f6894d603e253ba3e8e339a6933bc3a0a47126087038e1c813c3f2997aae321b7c95a802b4b73fc7db95897b7c91e3 0049f347dfd361a65910e97fcefbf60013a54837f2ae657d65e02397f59dc6bca27704fed3affdc3d833fdc621cc5e5f99b92a63 b0c3077332a5cffe7d2e764c171afeae0366b957878d54d94a6992b2ae4b514280467c1391df07fb016be170020c7093 +7502c755bbd385079a4001b8cd653287dc3054f3b57de19d0ff8f63c0308c64c56f035117a8971d43654f89b52e923947e4760ac72be073136da70c5ad7ca1658cc0a2d2a880d3a0c0fe636fdb27b77ff260c4c1ef8a18da8e9fd777d732a37ae9906e6c4f381f0a3d941048d5a1f6f2cb8593873fa4bb1621a44bc2bebfbcd1 00dd226de602af4e9f8e25784bd1bbd4cadb0a8aef525d5e2d57b9f3555feb698765672c5099a7d6dd5faaded69d8d68b4804f26 903260cd27c222e4031c24875541c8d4d8b462c6a0665e34168233fc5a0a6127c0f22f3125a64645e7821343448ba98e +95eca932d03f1df2e8bc90a27b9a1846963437cdafc49116ccf52e71e5a434cdb0aad5eccb2b692ca76e94f43a9f11fa2bdf94fe74af5c40e6bfd067a719523eea6b4e65730365ee498ac84c46e1588b9b954f1c218920cbf71b167fc977ee2a89429590f43bf637eecd91b0ce3be2d66bac5847205f76c06b914a970f543e59 00b6fdbc9c8c76cb2b822a940d8675889ca6f5132429da795462381ce29313a23bc132976fbeb346ed4c691e651028f873ce7971 b1b224303bd179c02fed0ca470abcc55fc6c75617829669bebb8b2eb3483902f31543f67a04b0421dd27363e89036f31 +8ff68cb00d03e730dddb05fe0b2344689529096c3da6eeecaf097f22c7fa340593106b1f6726f06b7ce7358edbcf801ead959438a42f94cdb467b3cd5b17fbbcf75739805f9eadc869c33c604cc58f81591b0b8bf4d42bd53a801f0f829a31af6c129fb4f20f1250f959754eff8c629b85a716b6a18465b6495798c0c5166c8c 00203d77fac64591eb9a18de20a9d5eacaa1c3ec58a5ecdb3008c2d642e197141d16b3a9fdffe61429264f5b420f5e9926659a4c 86764f42231abb8efa570d30a3d1cb63dd0b221d3675f9ff6189ac1468beaeee2c46ec126cbffee30cde0c80c01157a1 +01451c4f09720cd53377a5ed04c907a735477378ed960235a833049d6bad6e6e89958b4c4249bf0f6d4f043530c9e5426deb0ec3a12b7feb4860757b41bf602ca95655155356ec35a2db8e2657998f56529be4b714364f83a140846308a2973907ed7b08e935173ebbce5e29afe1444cd51c92824ede960056439555e7e74450 0057a2e6a59d4871c3d547690237dd9846d6d5dc4ec0678aafc9c8669af8a641eed67bfea4b05fd6b3b5357ec4d0caf352691ea4 b6059ffd256676b05dc09ed280aa0002e244d4781f188a6910ec6d40d8ba6b21e79297160787c6ed13d212c29794ca11 +ccd494ca005ad706db03a3df6d5c6e876ef859ec77a54de11fe20d104377df1900b6b192126c598944d19a2364b2ae87ad7fd32265d59e1f22be5833f20767793677b628f18e9619f8ca32f3af3b41c31e87a98d1527e5e781bff33c1a8be3a82ea503e76afec5768d7f7dd1f17dc98a9e7f92fd8c96fca0db518bd143d82e6d 000a3da7a6633608fcee9ce4253bbcec08d41ee6b00178ceb017de74e24d48fd89107c9f2db3556063abe3cb011938f4b4871795 a4245e5c4dd361ae71b840950bf5972ff20e60a15244600364523ef83d9a24844041c31cff1ac6845d8a4412845532e0 +5719e50d939a8d74efb444eb5a77cda48cbb59e7f976cdb2ea2848bfc558718b39ce27b893c229db94bf77992222d1746f8f52f858f85124a28193ae0da039c53d484681785f3367f6516fbb8a86560aea9e3428551facc98cdb1e9df8e2f37db823a7abc589f667b5c93c4c47061400220a2014197d514217fc252cef5a2433 00384723c8b4a316b450d1fce0b2645912b8acaeb3cad50860cca43bdc0206ed5b3b60ebdc29b3eda305d0d60eeaec261edc24d5 b8466e2f7236d666847857c2ff0e5d1eb9d7d72a6318146e5456d2195f9d405414fd705ad9f2bef07a63c51bcf9f9299 +c84e5702a339259a61b5ba8ec1957f23ffc4f1eeef3a58f383d3731bbaabfcf49ce2ebb597960ac5115a2af1c62b193d4ab6c24433d5f168a1752e40145f19aeb6dee889a53a4fadd13eef60e28fcc7ed6a9b8b0ca286c1b3d66a4b2c327a629d15c148049e3a0ccdccf05cf22c31956014595e417060627c8125bd7c00f8850 00bd3136647572fef3de51b12e64b36460bd3a27dc660c164fc705417339cab21f9e1f9be0f3da926df459c5ba58b701d306e67a aeed4cf2cc34f3492b60ccd884cdf140384af877a24f27f5e7bf42cf221a0a5c6a44b637a9dca412024422abc6e53016 +c90bf11d04a708e64b6f94d4cca64b92463eae878c377b188c82c1c5f05a038be20eca2e18034d46f00d9a6fc73c4084981748ee9d2915d87aee4e2321f4f9e11c176f01281913e324700d9cb474b7134fcc408fb4a7006acd9e63d4578ed4c2729d8e0d01b1e6174a43a024ad261eb644ae98979c3cdab75af357f6dbdf5db1 00495be0b0a9d357f6155fac008cec90442200bb842d89292fde38b7256e4117284a60249b3101b3f19f778b680c0d1d7422b84a 8c50e9e808ceb78efed6aada538f07ea019132d53f3ff923f4865ffaf57a701e0c5e767dfda522fc86e989c6fcbb1d73 +e9b2a33906a1079280100039787377c2971c378b92e70a38ab41dc23979d6fb0c41e53a21b37632407adac6f212341cf6af8605b4978c85c9c16960e1674247f1795cd73b99ff28cdca024f5078490513c77114c2f52288f5376872c331151d7b2c08f7794f2c1f9e0d849d32d73636f0aa899988ca561a76f74543b37cbf3a3 0079626354dfc4eeeb51fcf232ee9e6b0130c9bd40f15ed45606bb7faeca8f359e0c3e18bf12769254522fd4077eb24bd5454871 8d98752479a178947d3fab5c3c39df0fa2605da10eafa5412761020e464530dae30f0d40590abaa005204ab709b04e16 +672db3fb8cc8e5f831be700498d3ab3aef14b7548e8011b21351215fb6dfa09460d18f52c02c8815baf396d856a429bb9afd602a10c213af34db80447f4c06ab4bd28873c88eb9639b199042d4b2cb13cc364f734fd4ab7bebede7dd4da63decc0cc1f84e34d760013f66d71641073f16c08078880b67230f2d6c6bfe17d206b 00ab42bc7d0e3c23f8bcf928e25f9f027b56f270398a1d37bea0ee5426b944a9c9ba6d0d7796899543feedb470f70b2ab148234f 8e1c6e6c0382bd06d9a30792096a9a868076ce669664d4a35dfb1b43043cd34cd26c9e0b291991596f267bf563209d77 +d7fd06b89226cfd66671ce5b4b656228c52d986afa7f6f30161680eb0c9cca177992a8a8c40167a64165c518c55f678702125709361b536bd928567c97737bd750d0e2e6e0c00296a6ca565f7c05cc8c54ae7a4e0c334c6a968fc18a959c18ebbd924457701316a4e999fb11084520dac68dc2d69187134c40891af0355ba89b 007f7aa2216164ba689459ee5d5ca29e70ef75a5b2a4416ab588df1dcb9164330c0b405a9d80c3acc41c19f58e24e17ecbc0fa7b ae4d362fbf02553c6a05d43dcf1e919d8bebae9e780bc363207aa1e5cf7f1215875136c6fc674f94785506450ecb67df +83b7e9d3ec638fef51d2885fff5490c94e2509c126608f82660e5fc523032f3e85d69d9b76af145f6bd916dda35775abbb6d1902bf38880f8b9259822055c5b1bc726c51029972cf7474cf2a812f3251aa71813476bff55598d079f075a40c6c41498bd865ce960c518bef75a873b9d010965f342dc4b35ef5c5972efe6fdd18 0021d84f070c6823a70f1a74225a472118c93ce9dc509aa6064051ca4574939dcfa96be862069424bdf1a23f62f2868326422e64 b3f37c7213cdda09889e138e7cfbc7e6e06b23bbd757e0b4c752889aad522f7d62e8b641006a512a8ed02b7682b68a5d +c62c7bcc860f0e175128e1127dacf935ce62ae794cc4a0ce7966bceb023ac0498641d7281fbc86f9ef470bbc77f608f83f8d0dd6299cf08f2cdacc7a9642e4246df131820220e5c05d0dbfceda7f16b86add4793e9b6244d96b5c07cfa23574ceb43e8e8b5483192a92b301aa3b37702b8f94f0129d8af1617896b34990c9b02 00b6645344d17528968c719091b6e2072388881dc10bdb4c7fbf41906cadf3699b30f9c1dbfb4796d009480664e6276c0359e5db 8616220c08a965051f17b2fd4a2380238400e53752108053efdfe4216a212e261e6232b04f68004cedf5b0a740860171 +b5bf38fd9e822925254418475a1ce762a94e336f12b156b1625a4574fee11ee472d537ef94b4a4b1c0a73b0140d0b818cd06636653e6c07f0f100118242a7703756f1cb1119b3477c4ced99cf45e07e83b7f2749c1a5f8d8c9272d221fe17f7c6a5fb0f8a16af46f232ce406aaf565c6b2766a2f6528c82e74fa1c0a7fcfd49e 00f8c2f770cf5f8e1f900e996ecdcd84fcff5cd959777fd005d721a419123221a3237e39834b270d37752470deaa6cea023c5058 b7ec1ccde69bcc6fe75d9e9e33e0870db536f3a75ab604bee63e7c082692a40cc87b25941ca9874b413f0f9892327bfd +6d3474770933ec01b76be789304b6fda423b12a0ae8c87a5ea8d7ee9f71300f39440e1c7f5aa4b47c1a8628cfc3a490b15ef292a741344f40a8fcdd02cf3863bf3e32d53031f503703deab17fc52b3d4032f4e237dcc27231b85d3fd60b49ed7ee40c3344948d87c3f47564d20a11d50e4e520bd16c8701694fc70901a5da625 00144adae951fe897d5812ee4a16c0be4c86c5e57e615c398f5768a1223a9be20fa82ceccf8a16a31432bbfd17e594a4cd8a6a07 ae36470623c9ea9a1267a6083fd10424a5f771095a14d49ccaa2d8647cf7980dce47105f4bf07a6fcc2d38af1bbdd4c7 +92ba7aaf71f625f7a2e024058dc8739da3567c306da4a812ed9e1542b7d1e982c16082166a59720203f4524c3bd463a662c26a82ec7b4376545206e650eed0d3dd7909dfe3810981393070d15c45dc4a75a8c5bdeba533cad1ec34fd20466a61e4cde3b25af9a80a9a54afdd7de1cf2a74ba32d4ea0082a037775413c61a8d1f 00a51f065fb32c55bf4ff6f18ba9d488d35d9f8da593adb0ab1632533284e0adc43ccdbda9d9507b9862ac63b5ae7b0f78b479bb aab4a53d979da98b5a4748f845452c383a311887729cacbc19afede2c2ba5acb2d9bedff1963adf966b28e6780ee25e9 +b3fb9e48c333201324755a81f3ae5d4f0e2ae7cd24238fcc66d858e3aeb1ee03328660d6399676eb1b7d8285ba571e214d935bb45516fccfab57b8eb4c3d5f1d7357c768eb7b5e7b5710f599614bd4e92706eaba31f8a5e7e57af7ed13066af50b4540ccdc126b677789920cef8543907f0ba9dc92aae343d3425bd784ef483d 0095351c0bc07acfabe6477fe85f97eab520dc96bdd58b44b036328ceadaa56a1904d2217c5fd25155ff2aaf9005a3e2687fec81 87993e0c95efeadfc370ff5d7202c785f06d6ffc94ff30e08b6b3c98397d74e5acf0212691fb8b93a8d6cd8f5df29d18 +9ec5f7d65082264b8a50be772c44277a73ed19199eb275fe5976f9799d8629fcb4a59a8d55074cd2eb2a0e02062d3f7cdeb05e62931a24fd1aaf14c257944d1b42eebd52726d6fe281211b39038e52baae077ea4df89675d860d6ba5a0f998d049614201b872e134367acc90066ac602e478ac3e43c3ddf4b0ca0aac1a68591a 0050245c1682344fef23bd549ac8d1e8e44b2840c43eec1cecd33daa4e9ef6b53f496104d7432e14248682cfd6f5b4853b65adac 8cceff3242f9602b0c3e5c116dc5665a83eb567e06ac42ebb5dbca404bf882d945a07160dc5946eb26f13eb1d0309c05 +61d657bf472676301503f6784b7286fb39fb4186bb88abf1edacb4a2693d0a1e2b77bbf2758c84f2cbfd1753e20841b1cd4b456400d53f4d686e666943f9b6ffcdb77f510be97536e9698fc84ae347d483bc8984548d1cf86b9b40d360f9c0dc5bd1c55868e26fce1460ba94ef5e94eb63c9f0776a0f446c0cfd4106d9f36352 008d3b0277f0e9fe54581d3a9499ccd7f015c08339591326859af969d2a26284e3b3beac4a0b74d324ce5cb5f38c7995e4e3a41f a16fbadbbdabfca8a1e9686723c57c0bfb511e0f478a8de7690b041d2c94b42dcad243a0c1d3efd1f27b292f85ee5cd1 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B571 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B571 new file mode 100644 index 000000000000..d768f6a20fbd --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B571 @@ -0,0 +1,60 @@ +8e14f713a2c427b1f79491033994f76acbead614d12e73ac6f3f518f2052a10c1273aabe628ab38e0d3d5f8ff254802e9f44a51367bf80325b6fc39d907a37f731372864747b10749ea5cb3d3a83da39c21a7b02885a8c1770e4397cedc958e4baa21d5007569dc9dd1e45d2181709d900a394454090badbd0cd9c2cd2369aad 00f42afce7f7b3d45f3f925ab29fc3882a89c9f585177887584703cf8bd8fc572e677adfa55b402446fe1e90dc855358d92c3267c35be9674b40c2ad5ce8dbe6a533c44b0ad8d2b2 a9867b008eb69c08cf199e6ff8a6e5541dfdabe7d18fcbac48ec901fd24f8bf6b7a27691cb89d3cfc16adb76c68114f6 +38b60d27ff08fb191811036dbfd5b39e1cc3427ff70efb67c851e9cb407f9fac6f348d289df98d055eec73299fcac068bd0fd9ffa3c5d244659e4f714a58d79f6727f323a7ee26369000e90e34e106f99f5ae2ae1b64ee89e5a1d304ef20c071a7773e9b977ed3d49f467d300a881c8371041394910f9c366942449045568f01 02f36613043cbf53ad36e2b38998bb867503359ae082d07d040e5a10a43e06ba9c91e7c73308e41e2391b65e634f83b162cbdf4e7a44ad818fb93a978af00f06be06731d8c5886c6 ab2d73ca8cc11eb948f665329f99b907f465866af7547bee8c7e296881c6e1347d4b4ca8094376449740791537ac6215 +21709eeaf9e1953822294a478dfacfb205fc25f447a73a76a32601c00784cbf2f9ebd41c22721d70cdb3842dcaff4a4f208d41c0816990e421cc4b8538ac2f347cdd0aa2a39f1aa26ace8cb6a606b23f6244894d4594a0f6a5b8f6a695fd66e1a41e2eb6a377017177fec56bb58c837e311cd04c5b50575faee32606b9636ec1 02e74948c46930cbcd9dbe2325539c7dfdd910f309fd610e6599d425aad9ae230a8d4681970a14f2a71fd08030d0a40ff40dade7de1b06a80441bbf7e2fcf1809cff39c7ef88bf9f 815a9f63e5fd5909e94e7b6024c6cca5c39b1b739f305d6bd78da42e297351f340533745df6381b5df61467f906def11 +3a131fabf3dc97334f212fce41c44300440d16de1d6060450875f7276f53c026e2a511681b5a8d75fc0d578546339542833145f7ee13c708df33e584445a75a5538829286480d339be7c777c03c998a6d3f037b25799ab2d541021502a0b02a9b9c337a8b176c4f30e5b186485a6103b1d1563ad4ae73ca806a5e4daa92e9100 01b5fab1d36f6f6d559f65d8b01edba610620fc3a38307b1fb1c5bd63e7ffbd4a9098cb8bdf50975a873f5d047ee2b627b090897a7fb5f56d3f4a0f3528179e7c969926fc0d3b0e5 af98a669051cf7ec2193e7b1081f910520064f8f48ae9084fb7c2e9e83a2a13fa5c0d8f177e0c8a5937414bc830e3c9f +679d85a762f2574b0b31b516270b7d33d5e166c83e91a0f48e0f3db20b52f42f9e6ee9648cf58267ffe3b713723cf3df52b5fab5c14db1e7189f7cb7170bc6ec7cc71946745e152b39180f828688a5b6c0b2957ab94283b90052a3c6e36843c391aa8810f9253b639a8d5a69aec10070603ad7a99dcedb544858d057a1d66b89 0383e70c71b431eedd4574f65d01fb0304f7744d668408c847f7899eae44770a7f3243109740f177d7146a27748886b7b77ecf3792b512e8d8e37c3bf4ecef2b1253df7066498f01 82edd490749c8a3891c5341a9c5d1b9cccaaf6eb87813f745c8a1bcc27b826c4ba5915e432a1e7b38abd0f0cb8ae5afa +236152ad31ce2ffc0dead3c142cf6c770672cd2e75af4a82fda1a72e1c775cec9b481c6f3e411644df7e7ee901c501405620af4b6e9667dfd46091788daa95ef2c6c9f5c240c06b15cb0df51f5f058d8a7934bd7845f007a35f99fa97200b20f3b5b14fbf1e372507f3b2f377e8d07d30fd3e222f398f26d8f428e320327f901 002261d4ead21f02fab19bbb0da8c272286704c8f0c6842ba47ded121e5cddef79fb34e6b9694f725ca502949faecfb21e3cc062a2b4c654bd542d9a1fe8d97bdd0905c510aa0999 866f4cb6a4dcd3d2f8dc8aba5399245408d66f8666774b75ab6908dc7e8dacddc925ce564f63115554709717f4f4fae5 +ba3f02c4847fae035d747db246fe4e82fb9224ff9cf568a6ae548f5dc2befb2079541d2cf9aaa6b18c281a05e7ddfcdbcefb25f41dd91cb3092b3343e16985e91c912215cd99ae4a099baf628e33a7b277e3c36a13aaef85418fca99f64d73b789f23ecbb76c3095ade0a5f7f34836a98c5be933b44a94a2eaa3f99b1d8e7937 0316c78f289e1860bb623082be9d9238b88e38c5e978a868bb90f776235bdff4eff591877b7f350cf14c40356922b2b6aa51d64990360b2b0e44d6941b5dd9492b4f4e1f42ca163a 8d35073ee61ed31395c50a73e4bf3ca79c9aacd325d7a19141709e9e2b83bcf37f2ce5a5a3f698d85cbce7824a4500d5 +6d0372b40559e075af56af853cbe18ba2d471b0fc8917764abcc69102b03d5bbe1fc12458215be66409c26c89f67c72a8933677a07f88993af6918acb074fa915fe883b24bc3d191ff1b08852f07eda98977e70eba072d8bf189cd545230f59559ac05f1fa3f4e65886d0bc274a6e02e2399812b2bf91abae81e21279c5de996 02c1bc13f8320d97a82f3d9354e195481902214e16a4fd89332a0499208e91d50e5cabeb4927ba030cb42f5bc53b10f500fa646a8c88508cb0d63ebfce5c4bd574c527d686c735ce b6d98c8fb7fa90aa8678a26ca3650b6ee1570288927da9d24dba1313e4493c761e96b945917a235b4f53404ffb3ef638 +bbfe66c82bc060bd14fd0e40769d9b3a026eb447550dd9f118c30d8448f725f8366edef042447962ba7f7f833b9e9094d0ff600714697e632626e7d12a592e040bdcee166dcda93952323191021bd12f3b1647d0f25a41739994659dcbb19333ca30f46f539c6f0a5c354cda8969a1eda572a309950c84c7607eb8ac20163912 013bd80eafa67663e75d7ae139bf285d2b9f1e03d8e32153c73e26d06e86d7acad22bde9f121a3f1ea674dcc1fe67bc7f5398d5e92555056bc046a02b0ba86c2a0dfe32e91add5b6 b742fa78a2094b6dd35bb37957846e44d7621bf2bd890bfe70dd77c8fa64ba62bcd4771ff60b4e1b6d73ecab6f830f2d +b35e9bf686717ce3b16a59963a32a2116130453b161a4e7ceb27b755856add836d779696edcaee3b5c986523891c8836109d431e55c23afbca022437ad19e6777efabb6da3bba1f5f44f905395b4cc7c9210590fd38da621582d059598e5e4569e904358e0dfc0dbfda4ce75538aa97480912852bccd433a9b96c9c66e9597d2 030834b0a4284097cdda2ada6947c6c281f7290a49b56becefea1e2788ea3ef78fb96807633c47c25138341768b241164ce0d42f7301728b928be2c047f2eb60fc2f844ab77306d2 98c2dac464b03587967c73f6f80601174dce84ab1722d749c42a2663f4b951caaf63c11ada96bc832365f2fdb01d443c +57b5ae7e95c638b258d1e09b3fcb4341e203f5706862e199b103c8fdac72cbc5155e5cf8b300a0b3fb0ce1f897c45f7aefcc528182f73dd450cd84d5fe9eadff3f704dc2a01b4e847c22df430efd1c66b0199f3e5b59348af5386962a5ef25204fd230b54d58d7fae801c086f8f405d3d0aa7a9a9da15c22b868817cd897d853 00c81a79ced1eaaafc31b69a40d9939f4e484d625db6364a8e589b6b4d336d458b44287ea6c6aa7661113fc07806b147ff98216fa0c08708dc9d651821b922741deda522b4e436ad 92a1c245f7821a60d8f42132633bb479620dd35a57b25bd9924f40c4404b8d1d9a1908f3070d9209ac0aee385163bbd9 +daebfef74b452f039c999ba0528be3bd9e16deb5f46f6eae87b63db8b89952c949fd7db08311871eb2596865eed107aa065f030226ea675ee3256c31a3f85ddf4c21760582144e07af208f33c5f47cc026db5403186a65a47940691ea2d74ffb1245676260ef5717dd879d8b5b72d96f87fef5f762d4fd17454cb5ed83d8a11f 02f24670c0f77d2ca0266a743023d2c7413d56d0b5ec77b454ac59087efc4ea4d46179e10278e4ba416ffd8c3f9786ed202faf8251c0ef5a9ea5371fbb35b7afe3d15a9cb4bad975 a2e24ec3be60ddc3b184c0ce786111dfbc6214849a62adbe97371fb793110ca97bbd289f8d1c698be354eb3d023afddd +62af0493ae79d71b552c4647d1fb7ab2f282a91cd44aebd8ef344dfd77b521b0c0a3f72e4513c8ecc0e4b84efef3df9482a07ccc1b740c571c5e69cb913740a792aa231b9dc87edfb72bac188293c6c6e788cb3dff32e8f483f8f34e21ee7efec71302cc3bdbfa47908a135f6ef3ff179dcef26d1a3987f7be967a6c0f799b0c 020985f2c6fe3ea04bdbab66a8b6167e5969c073b9d53cf3c77cebbf73f4dbf75e601620ec9c3107bf3fbfc6c79f8f063409bf8fe1d14b19e323d857e23dc05157d270c7514137e4 94e0d0df8f1ed71a712050fc2a9d37a7d9d6160ed1af4e16cba2abf847dc880d9752945bf6fd952935b98307e1d8ea48 +566f17851951777ebea3f8285610cd8ee5f882a68e7a4205e6fc9e2d66d210ee2505ee73d6503169f7b903012d43e7e99efa493a8e6ef926b16b9ad8f52156840ab561fc6b680120a88714fd66d1d0742189bf06c155e1138ee5314707173f7352e2cea0fc26e1553643f2490428718e44afd8372cbb7bf5b88234318ebf4355 02b3d641607b8a141f876f6d285ee46aea543880e772dadd5dd83d595b9643191d9597218e1d6adb081df133304037bcd2c05c24a54e6c4cca64fb2cc4569d6882315360059496d8 a37a047264a75dbf7d21b4dab56528338a076d93b457fb29879cb9aa9b5940105a8e213d833a64552375620e5630a55a +25155825fc4f9a1c4dd1db837008e7e2594a879052431f5bfc76d0d2565b8fa726008befaeddceef73f3c60fa2cdf6d9a70e56d27210bd013034b38861ae49640ef208d3fe294ac4362f8eea44f58af3af8a9167a36b5acafb7ec95652d5885a0e08067ce1dfbb45a0c89ad1acb53eb404bf88fa5c3c463a0f912b5a2522a0d9 01afeb5ca87c81025ddf09c2b2c5ee22ba0105c0e619b67a324467485bd839030d149fee44d8bac6f5902a1245a50c3437046b7c89a84116b2147cddc645b6d2fd24d68e8d53bf5b a4b4272d2a7242332760f1ba78b095a2e88f954d40d9575b2012f2262b480b4bedb7a6f43ba3f3fe9c97671e84641a72 +29acb0fca27e2a10d7b9e7e84a79af73e420abdb0f80dd2665696638951b52dd39ca028166b47a3b6a2eaeceb1a11c152383f0bec64e862db1c249672b3770909f775b794e0b9b28a5ec8635a996d912d837a5f22471b40ec2e84701a8804127a9f1a0b3c96ff654700bad3167240c2518fb5dedcc1be9f56a807083e587bc56 032c97639b69c7cdbf419286d0a1b406d9b1f2886521a8b979a36118d2a368aace5b02dd8c515f2041e6fb9f026d1e82e789dc826a56d2ef732b1bb0f49be2b696ab5d3d5694a2de 80898de14385fb732b8ff10007bd99c0d9a7c6ced1864ea915d18b8fc69bbac7d55616e31b1c12a6ad43b081dbad0d89 +c92d67cf6536f5046e15b02158da698bcbba4ff1e4e9e9c882cda67f817210402ef917ae93682c9c3dd817b21b73c6c00b7bf92ea80ecbbef2e67f4f4379d078a2b0f297742b2bb9c3fa3297a7e8079f488555bd37715eec92b4b1cbf897640ae8a1d2a0fbcee5423ab31a37629f98630275e35094a896cc574be0a449bb1bc3 00f93672159276c5a293582b9f49607bbdb970112f6c63b2b3b5d32ad3c8240c86b1af13a8dff6502c6b6a17712cfd988f8cd23a60693d64104143b3f91adb37f852e9e11a0ef110 b95bc22b9d73785511d1c969d34a823767d7bca07b05e3a1a03579221e67ed79cdd3ccbe8afc0481acd1520e0c5e9f71 +15413f614c4551e3b138b64f66d15f8964c40326a42b0afce820778eee4a88edb127fbf575da5263e5a2627b5461d311813ea868e6417615e7c4938313675009caac28bc7a2f4c0bc37572d9bf36a3b1794294e09c0121ceecaa4b916df45b0dd31225415e6c87cfeeb092a008fce2c543cd62365779ae28f29fa02a15d9dcd5 03db080bc99c5fe7e06d5032167af56783cb423fae59fb5b3c6bce5fbedf56b7b39b17810e48ea9a172881aa1f42f5e267349b60294d4a208b4437666b44abcfee5a1829e9467908 8062b7d1764b1fd5e9e83b6b572a51be74c9825935ce57927d9b5bb89bf88c89dbe829b0ce344806c7aba88307be7565 +9f901557451ae2f8ec79b6d4adc794cbfd9b2e6d28f19409532d91682820205308b41498a4e1ca247a2baa8da93de95e3c0f7afd6ca46bafdbdcc6d3374a12684676a50988b86a960a82180648c8c1e38f8fd9af604c7be3be4b24799f4544ac96d6360cdb83d1d0847fda21642934fd6cf65385b50d86d4656987901fb88d0c 006ee767f6f36bb8f364f324d8346455c899a49237d759003dd52cfa13b9baa4c71347b134b24ecaee32d247c34e3787a0c64bc5d299b55c86f64b47521d22f2c09db225b0c84cc6 9290ff03385f7f2553ae56f6b7945239109a0c98c94f2ebd974b5f87a5bab210eac3e69c0999f3f92bb339454404d2fd +959fe5a19d7aea2ba611c7203e19f8e3f3cc101e03a98f91adfef602c424c580d5a868659368a930f9883d699fc633bd07f6cf8de474937db0bea86fa7cd140ec2f202663813033a757b93bd72afba15be5e47a4eb93e8a666aa1c72c241ca3922547d63fa3732fec54afea7ade84302e2f044275bb67433fb6b125b7913143c 038e2571d9f22309a636586d62863ed67a70538287f3ef88b88c3c2fa1a2900d48c342b6f15c26b8e7fb4875cda4093b7de7ceda48fe1e2cc2975afe958040881de61f309931e48d a8c94ffba603296846c15ea170f97d1cbc8b2ef86bff8cf223470f50d50f4e873baa9d4b9b2fafaf0e7f3a3a8f7e489b +97b9688d9ed5101b8cfb19e84b89cd644262ca1c7ee18944e29ddd3b4cca78e06338b270385b00a5e8b91ca5e628de3bba50e36ecc695b3ea737a9cf8b36871c473a54ba17819f49e730c0f253b0c769aefa6c16366fd2dd612f330e95fb119fcf3bf7f3e254438c0ab635ec04a8b2424a05b483ecf65b74a93636fbab7bf1d8 00c8f5736f1ae65592f3ca850f43d06441aaad8c03820f3b08d8a6db46488dcfb828459f8b3f34af73cce8dc7a5e3834e085a64523d890028e194214cef4003210e6eb530005b01a 9035477cc77da660ba865648b0acc5a2703b0cf92ef17e69c4a108e73e89027104c11ed1ebe2df5452e44a5195cef94d +f08b250bf4a3980cb455338b3f4173723b3f44c97bacc9cf550149794a71426e398cb4a74bde141d8b7b4a72942f1c069676a9918e27792cb8f085ee037c78e3c468adea5123c4c64d8ca6a39f2f90140c5d2d80b669cbf0d1ccb466b18ded83a1d5f042c36188a04111c34ff769abba9aedda40a87be1e24b700225e2078056 01ee68c3994adaaa9e0d61bfcd3bc1cdf198d3fbfe28a44e5dd518867ea04b20e795eadacc48bfcf8e8216dceeaa069b756e8e99ed87b6b1d31154cc9310bc3b4555162a890b0c6c aecb38d3bdddd956f55843ce211b9a42bae31356779e81d2e104409c7c958150db2dfdd646bba1ccfe10b810eede77ef +1cabd16fc29d7d919622810dc8b23c770b790b98b119eeab1b20900fa94fc2ebaf76be4f5eea91fc5276c5621c8677d4d117c4a5a782ee2ca1d5b0db997fdc8a05b6b3fbb833d7a7b81c3c615c2a662929760a96feefcf89e46b563314c9b77c86bf34438458b43b694ceba741b97dfcdacc0ed57652ae62856ce10ed2690770 03a6fbf66ebc1365ea7699c72cdac2dd85907ec59cd26e2d18713354b619ccb83b7fc0db9193aa8493c1855f1a83fd987cbbb65de17c59fbe79256aa5392f4eba045346e9ba26592 8cdb80050d67342674e7ec043f42cc7f0e8e8d939132cc30f3ea18187281709bfd183c068528c4372597d3a27bb9e345 +7bc8bbf5ebeacf40b3c82eb6eba5d994dcc6a3f2e12ef741f90f90e176d20c21e006ecdaf14cb5beef35bff46b2c374d9ee224516679b1a9e9255cd8ad8e60ed234f8ee7e0fc53c9021488158217d4b4369cc597d6053746efa1e73340bdd73c1bd2eed57b92426fd4d278d6a86e8be0f0a66ab3dfadefca8831b2f488636251 0145748871a0b5c1cee628de04a12fd68ff2b154fda96e47afaa96389d66d22802968584f6753d36618d49ed205260f09d3f5ccc2b27a34390ce58179b9834ff92a86d66ea0a97ca afcfee08a4022336ee667b4a984915bc6549f85ce609baeeb305bdc05db580a91af051de3a0dfdd6ef1860f5fa0655e2 +0cd2a45392871c0c262e7e6f036946354bb41f9c2187b8c4d399231280682f3e0a09731fbfd52c76ee63b9828c2d731f4cefee0a8c46419c398205b2ff80c67d7756db300a0a8385fa287dd37d9126f75998ae1cbab5136560592118db52fbf102b7ff0a1ed45b8a91a7d99d13a0f7fd4366392264aa1248d7324901467457ca 03c71911d24ad19c20fc1d8a044d63c9bb417abc3778d7e6234c6af79b898cbfc2f2787244708d2fe203be786edbdc4c9b12b413156b7b0bab0be8af895d191d853cd58aafe1ccce b5d5a7a646f7be61423fba3dbd1fdc9fc3d57a88d223b05da21c830de35e6f0ff89ac6c6b1db0fd3e44ac8ab884bc29a +e97092625b09c9ae6e152e1cbee207d83361f34cb9b0e727c816a5ed851f12f91fbf88ad9d4c8f9d07350f5d828fd8574eafc768bc72a2b18aaf4d2b48fb10f7c3431137b51850154de9706487d69a40a8f4cb2c799f48c5d8f518aff752500de93cbb94ab04ae1e0c7183a32d79a27291dd07b5fb6e6a4fab76e85c3a8607e2 018bd74698bac36ef11add6b3e3fad227ecd868f370ec04569462565d2f0af2340bf793486953a7b79ab04f0ab1f0e4fd16bf6b576cce677d543e73aa8edb0e50372f24ddfbff966 95da3de14fe21720d68cd712fa28d0a3a0068b7aec777630ed676126eb20646c35aff22119c6a8b87e09260754108a6d +ae6723b8df5d6ab5fcfaa22d32fdf106d211514cb1892c7c43ca6cd85c2532f85929c8a259ed251215063cf92e1502528d1e22d5cf67efa0b8ef21e8eb2f5dff881ba1433e8bcf2b6af8742ecb2bccde081e534615a305562cc22d3398f61f277d8ca785842bda85d8a40438d9bf1aceaedcfc22c85533794a69cfc320931d3f 0335699bfd058ee2e6163f55d1816bf3669acea8b73be9c4ddfe775230925e6093cff7a66813adf22222c8376faa106d85ac9f3c67929bc58d8986795b6d35d5b9fa546dceabbedc b8fffb88a736dd1f2e2a9e90b1e4c400cfaf7275a7db73ae88c1822c35a174d8d50ae88be61cf1fa70beae5f8b8d3d6a +ee20c6b61886e02ed94359dff3559522ff550ca126fed4b2240ea7d999a182b7bb618c50528fcbd261d5e497a991fbac0cf4c105c0f664d6a00a9001c1ed522962fb44dd4159677ce8f1531019f86457c055c9cea6247086cdfe0442485cbbc4386ad002b4bd39a1a187752437f04569705cb7adc0c68f0fd059d946deb63f0b 02c3eaf801330b3f1b0504f2399f1d24455db29911f750c246ba0a134c3b59da8b3562911197764699a92ea1d95a2aac587e24f743df1dad3e1cf7edf955203e24a0225717f8d2df 99c25029517c811d3b1877926806bf333309cbaecc6ceb13c6ef045f471ce2730d75a43576e7f940b7e518797ad9f533 +734a9eb8288e32f5a67cc1d88704523ca2c68b798d90e188d871d9f50d2da2063baf1ee6685c45832a1818aabc9afc0bc935e97969dc983a484f16d2bedb3c7c0b8221408be2480a5562d5d1e5d8763d1e474bf2826aa93a68c3b870e3bf34f4941cf590d88e1f5a8cd782a33992213f3f6b4b4f6dbfb3c3c8f21f5eaf4ef609 01c3ff067497e5d387f31f0ecc9c67b3c0dd6ec8c81318c492aad83c9dec6c99e4fa47447f6f7082d636c2591d0df940b947d0a4ae3778e2b7cc8fb92214638399def894ada276b8 81aa30e2b2e7f4dee5add85a6e6c0ab6aeddba84030b475990b0d987fd0d70730c271e45270ba9b42ed454f263f2f4f7 +68e27cc72fec8f3f1f3882c6efa08efdf21d74d13be5171da35ef2855666ad2ea6919d21dbc1cb6d296663dcbceeba2fe47a2c6507d3d4a67a61b55b0f81c93412d7e1fbe15a590e342a05f55daa55f8591171303154e615e81189a523b855829a5c96621ad118f522e397e2eea05c2603eeae6e3591215e29b2289bc384d8d4 004b4e04281b210fe78d516a5b69f878b7fa058941ee9ae8cc63b061d1eb9e12c3e0ecb8717ff4623ff5bbbcdb53c48adbd9c69636506ab929c5507d7ebafae5654aad65a263e48d 8114fd9772c5340db6d88991bac89a02686b81a6772018aacac873b7a232f5406d9b35a96e1c19bd6a107502e141a337 +e67cecedf35058b80787589514a9c81c6b9f4bced4260411d2af75bc46b8b2c962dc9d260dc99ebbf8ee64950766efc0e394184bdc8e2891d66bd3300ecc880e9d6a3d0eb615322378afc3dba89938704e9a8d0c949d4bae9838805c00377e3fe5ec6a1a98ad7eaaba6b500973dac48b26b7fb2e1b9889f8c387de535d4b2363 030f2849a713aeac95fde5ce3af853e9d070ee60709eccf35a076567be2c43f0fa34420b0fc097ff577221275a3a56e759efc32183be2d76058a7d20e5dd59f00415114d73a15b8f 9054a0bad667a5c796af33fae47a6c050e751125680d13fbfb18455cd2d08c1fae114f968091b95ab0920bac1dfcde9e +2baa1ac3f07e34b67b6af087400f261e138b070c8475378063286c16fa73578303380236a4af2484ea01ba56c1c619f6ae4e5e6ac2594c8e5aae7e7f196f96fc5d0f507bebedd4d818e77b9120e5b4bc01c7ab6339e88b71d0886631cc7fd89659bf513faf149c61eb14d55060c8dfc7e6e4c2b4ec8edaaa6bc36eca50a6feef 02ebb73d04e6e5361e20629e3ad119b33db5163ed91fd9a8aec4b774898784b6822a08992118a8fe6013094bad0be1e9bf01b27c069e4335bff7e0abd28a10443818f6b825e9cef1 998cba019c3d359478d419fe31de104828b249b5d858eedd509730b72efb45d527ea22feb31f561bed605624f679295c +0e640581f573068d8ebd2899a6aaeed0bf987ee11e22b05d25e88e9a1c3451f45ee3800d976f4603c18a041febef07a01086832a6f7ecd5d498d52e796a9d90758c87c36f4a5b704a39c456aaee2d5278183d5815d619c193da9fbc427d701bab0874bded848cb4bb066f56e119b637c78aeb6eaa387c41bec6cdd4bf7b2061a 01bfab717d6f6e16d9bc6e89d2ffac7cbe0f808cc8ca2eb515af7ecce5f3b230303775710a21bd25c2cc4566bb53c78c78e3774a9f306c751cc6e149929e45eef60f56c1d2388c6d a43c1d06e08447a34710745e48baeb858b94b50124df34747db170fb75b4bfe5922b39145576ed672f1582fbbc847d85 +51a2a560ba226d629127ce1ea7e812219ceaddd23561256331458c9f11fe73990f21d0dcd974a3773040090cfdc8e0f01692d951a0cbb60f8448a016c67abf46a9c150466ac77e656ea827b0ea7d1e77ea32071ba8314fc8a2edf69008f498bd1c18061d7d00f3340a7e2cd73e9766862378d8702e804a1870b442beb2d0aa14 000cc53bf7f1cad5e3dede4b4f4b082831604c92dd2b147869cdf1107259305b1d50359647f9f3d7d4e1e608865c65dc7c9ea46bc324dcb8423b554dc369d621743cbfb592b70eb5 b227f2c17fab51a3d54f35d23a12c03233d33d0c6601b69b7e6c5ac5d2e209d8f8c31697d1da3306c15eaacc0b00b3b9 +90eeecff0a2e37df318c441df220dfea013ef29774ee92a56b213e13a798858f31e52b6ccb7599e7314f12b48a89884b113c1ba0526a54f3e9a33c940944319e084bff320cf5f391c02c731c4c4f8b05afa273374a1705d6c85337782ba7d36b9c00767180cad6422c11c581672ff631fa4c49d41b02481568ec87ea97220400 02b009530cb9d586e35dd8951ccb686833afb7a37ec253e547e85b253ba999f0f186b6d4ba41091615fe57678e9801b4dc94fa683511da25637b2acc9fe60936be15af16234c4ee7 862c0a949eb059868204d98cfdd71fdf19078029d481ed860dea1597e325ba2afcd165dd1404d59dac25c2695559631e +d3740cad41e2e365d80ae81da97fdf06d8b6c278b505e34cb683fb55ddc5189da543540914c0accd405dbf0063f6222885fda4b316dad4a83fd03e8d7b7e936f87fc0a5b095defc8a4b22fa97f00b394e672d5efd3e0a230c7e44dfeebda88641143502a400ed62e2a51f9561e5d652a43d616f16699e875deb9610c77de8e1c 02cc2d0d7189cc8fb3565a039aee7633ddc00ff427cafad32fd2010b10fe249c9724d91785e7080203626038109158e3a61a3970aa3e51688aa7f5184b22f63af63f80d3540ec023 89452825b0cd2a399e2e321c7c3be00496de69f1c10be5231cf464210bf6dab3c5d2d54dabdba822b1e41deaaca03bf9 +5eb53b5f92121396c5ff30e0c92da48db4fbbdbf27297f9bc82614ab78f7fd863e34096c615a02e349d8bc7ae4b0700130704bedf32756b5ee6af10da1cd717d624fadc57a9aa6db4a6c5d6254c0e8f8c3c0d4d03c264eeeafd52cac2c1968d9d85b106167a49d0ccdbefb20bdc10a2555f8149203af52853169a02db94e5e2a 03d8936c00c131e38c6566d2464c4e207c878070bbf681695a6cd98cab2c6e80fe98cda80c66a5cf584e90a071144dda59c07b8fc7bb42464dbee5b6f739b0f2ee5fdff7e5a4e7cf a85c1c0765541aa17f5b8c188e24a35aa389e5bfd6a9820e1867807282de479137ac94640fab391078a517b1c303000f +5aced64f702a57ed7fabd045a40c967a485d2a70b0a5e82561d5141ef329469b2da5964a34df203a980111a77adca376c643b9030aa74516f054648c1534d912ea66582adf3c655dbd71ca55e47412315df5e2893e43b2e2dfe6e4dedf426f11846ebef34a99f5615460ce0475f7bc54b4a4fd99e83c982097c3136ac6188a5c 03dc7de970bce28a943d7599f2a9010fc99435b93bc4ba884d42503ac2941aa63fd07db34bcbb1127d56d6a4e277d6ca32051ea3467e376f74f98c3999d2f276b282ef8a28cf0cbc a8de2ade65d6889c7955e109088f854e47959a4ef676881611e815316067aa6bbf9651d2b32204776eb1d483329d262a +43c24aea343d4e088bea25be69a332c631275c36677093e057de69cc83a4c5e70ab270e5a8930f55846f1a22ec10e03007dcf0942c6761e89c65c6a4f032eed97dc3a2c7f7ed1e82552fe48828a132ba16c41f6bd82a49335428a24fa1679522000e6a1d12c646e0e4b4c584398577ea9493bb334fa3cee8bfdb6c2e66f46436 02de6ee12eefa7a4a736484b19b42a513dfc059a060976edc3b0aa4b50e98d72df6506fed0499ff8480986748e938289e54a5e86c0c29733a9bcf5985aa63d8a2b57933a04a8e8e0 a69aaaa7d48e50ddbe38b77adfadc36c37c15bcc2f5a98c2f4ca38cd4508151b4d9c805b7b365521c7ae74840655a2dd +e89210565959d93b483659e62cf41f0a0147ea23890c2f1a694c377a826165e363860e4b084016cda878a43eb68465f81f397ecd50087a25215ce7c4ededa3552218071fa3acd7ae380655fc8fa884998209ffc8a2c26f1ca19dfcfee455dad35a4e72caecd8da47eb9ee21b889162f5d3032724abfd1a31e68612e18bfa9006 005468f0df2c9854f5f655743e79c750fd8812db28b096d97207bae7f5aafc6b6090c9c636ead9e0fde32a1ff8d539b53813733ca812b41b58ff85a941abe4f128d59fdf9847baa4 9232d419657c2d79693551e48db50506fe8a3c2f78244bc912509efe5b3add49cebe4f7406f3feab6bfa0154c9537107 +48629ec97f56273599cd9903f8a84ac2ba74275b40e1e42fa47649568babe05cf63c8417d828251acc2eec525b56dc9082b68d51b0c2bbaa7389fbee15d058cf482993b2bedc5a9101f1afdc79989a812478245d191550109fc17215679553c508c84e3d4cfdea377088d09eb214e6f92410facee4790beeecafe72b2e3ed192 03d3c6a7ab9450c94aa3b8a1ffb678e5b647af24cbfd66ee3944e6f264f406295b803767471fc67936fdfed1714b4b8761a07eec86543b7c4da6bd2fcb33fa8cda4077737f398e18 a3dd478f1f49c86b563442c9e1ddd669bebdd33fce9a434713d994174e37a265f5cd5f31851499ff2c1645c368a0fd06 +aa3a9fe467b1ca638dd0622c9ea235a418b39b2e15ad81fee01b6892b240783d8db3c72e16c13df8016dac6addbfb85232158325bd7432fca3b8bf5db3abd0b4c5ccd0999609dc42199ca4680692a0805cdd68108bcb493a558ab507cec0a2782a9e976928985352edb2abc0c07078b59d2fd86fda7fc76cfe573181d934c46c 001ce010ea8e6e1a0c26ab22eb90f0700dc73b232c429d36371e68e429792afb7223f10327708bcff779ea55fb5f22ad87aa054e84d10f5450f1bc9a89279062ea2173f55ab0f76c 95da076e41d0c4c238dda094a91a6d8eeb5492f9829eda9061c14680668f404a3e389f307453c0034e94a850e2a5e112 +6c3937014361799f1461f652841b5137eb0dcaf01dd293298d002f27e9a770b9e1a30367e35c04603881f0c814cf8ecfbe1619cc49cd516b1d60d27de37ed52a5e1cc300e2face4669f308ebe6747255a3d386f16778e494a7cdd10b45171b2bfcdabd91b805bf24857708c1b75e368edb2874321324f83a19154d3a1578c767 01e7410d012aeef02b3723346d24ebafd684c99087ecccaea1cf3735d52c4c81dda41812c09f1e874dc964d858ca240a19963d5dc89451f5dd6764426ae41cb23f19cbfdca0fc562 819318b8c26aa6a18524b598a54b98ee942f10257514e16b23aa4ff59d8053c18812b772fb3a81859a89bb55a18bdaa1 +12fea55ffda15db902aa6a4388b9807c89c193cbf75b5d2a4c95206fa43dedc45974c80079933451bdc5b3ea015ed3ca2c54156dc61afb1bc82adefed1491302a48b9d3d2f474ab45343c611677d360515b93fb36da7a1c1b2341c9cce185c881c0beef33d43967134a190c09034ae3261f3295b79aebd3fe123616f73cf2089 02139839ce38eb879d266065dde5e5ea227244323b330e3ad5a0bc690f3c210f794cf18f0d730693887548bfbc434f48ee10ed34cb41d52172b06e448df938170a5e17311cab8e88 97622b8864232afc7024a961a797846b93fb13aa61c1449010e9755ddd5dc4bbd4deac5e546a9a04c2af7a305e17b0d1 +c8395546842ddb545d8ea3db4efe970453dcb06025ac3b7a25aa5ef62070f3021b9a1fea91ff7055b6c398073e7886a6f71afe53c82c47b71377dfe291972503bbeb25bd477bf0e7adc8a5d3f8b34ccd0080d61e121214e1b29802b711cdd8a6bb2275a2395c467ec2c1571952992e448d736d8bd70ee629c75b5e32b8323a00 0274f70fe69e4dbb55c5d404e39f5196335047113087f8711f2f67f2be4964e4fbcb865680758df1c401cd677b0971654b7a6aeb7bee0d6d80ac0de14d4f46f356b2d5545c185aa6 b81dfd704324b9ab1fbd559133a5a73369da10d97fb0a3f7e708e1779616037130a51a6b11ca3d92a77ab270a8e5c272 +10d2e00ae57176c79cdfc746c0c887abe799ee445b151b008e3d9f81eb69be40298ddf37b5c45a9b6e5ff83785d8c140cf11e6a4c3879a2845796872363da24b10f1f8d9cc48f8af20681dceb60dd62095d6d3b1779a4a805de3d74e38983b24c0748618e2f92ef7cac257ff4bd1f41113f2891eb13c47930e69ddbe91f270fb 003e1b03ffca4399d5b439fac8f87a5cb06930f00d304193d7daf83d5947d0c1e293f74aef8e56849f16147133c37a6b3d1b1883e5d61d6b871ea036c5291d9a74541f28878cb986 8b76bb6b0c4af9f35d957ae0fda24c1bff6ff5a5b15b20e7017d57b261fa9a5630875fb16abd4d6788564520f07c8968 +b61a0849a28672cb536fcf61ea2eb389d02ff7a09aa391744cae6597bd56703c40c50ca2dee5f7ee796acfd47322f03d8dbe4d99dc8eec588b4e5467f123075b2d74b2a0b0bbfd3ac5487a905fad6d6ac1421c2e564c0cf15e1f0f10bc31c249b7b46edd2462a55f85560d99bde9d5b06b97817d1dbe0a67c701d6e6e7878272 02e09ffd8b434bb7f67d1d3ccf482164f1653c6e4ec64dec2517aa21b7a93b2b21ea1eebb54734882f29303e489f02e3b741a87287e2dcdf3858eb6d2ec668f8b5b26f442ce513a2 b74f58f79d3a5cc901a88081dc014d2e3986073672f25b40c5564cc142a67c1140be50a5cc219d9d4dd511038dc610b8 +ba6be551bc60653192401ed8ff9e1acd9013d8811a7a1389528bf07438366f5772cd7aedad010c19c47622cec03a4d35b8003b39ed901b720629ab59de55a03c1ca50a62987f8da159e356245df58d5ae1936e65f3cd3acbe03ad1d0fcab4aaf2a7a947549ae776772201efbc6fab1aebfa1d99994d4f43dc28f39c0f279b992 02a69bc1df069c6e89722521a63675f318252be629e7558f3716917998e660ac960b0b750562846fe6c12ef492951e51e224754bab84a6eacd4147a5f26ae85ee4381bb14ec2a8c7 b17de1aa54af349a2b48f97f2c41a3a656aa9e7ea821382b34b18734063f969ccd6cc627042d3bc944fe757b8e0a2c63 +295720a79ac8201f40a66b06ae5d970afb15f36582897eed25cd92edcd00f70ac8e31c556eed4375ea044c2e8b227a8e02c0a3e996c9272d52ac7b3ad43b80f217295dddc84b177cf1e800ad08bf7fdd021fb2f49b54162092f8d628679c4ee335abbc90c027264c8b288c6e16eca3172eaa297ba50626b00fe0a0ad3a9dbeeb 00d11ed1b78b22b3420df4ddc4acc7c2286d9569dd6dd88e0fa3ecae69bcced68bb81bbb4ca6e9b54e67856e7fdf39155aa27aecb9cc827ccb9cdcf9ac633561b27d8eebfc261aee ac6f93cb154b225031d84f602412b3befbf32c6267998491c106c832b8113131ed7680753e264a67a9ae52139d5a7584 +a9cff41c6dfdc4a12f31dc375a5455950077ae323d0b7a3d9a8dde73b76e9d7b94ddf9c88ae8e6c262d704052ac47681fc35adfc56c904baaa6e146eb653984369d76a85596cb744941aa7b558c945ff2e81bd5ef7f00ecb4f43af23b4cea3bd4ba7b1899f1868a0c0ecfc62ccb1d588955597ffbbaf34cab2838efc2b866669 02c36ef754b5bd065e9eadde684750acc52795be80f54dd3d7a7d743d968a18f7e404bd71f8a76eb0395f396df5a7c2ff7e0ab6de35df34282fda6ee01fe5b9b68ecb4e378dbe32e a6c9d0fbbe0de86963b85dc5b46b9ed902ae96e266ffeb3d60c488acfad36eac87a9df7915debb1a74f941b1536ff0de +efa6c582d7fcf5e431aa89b3b00180c0e78efd7ccb0384d90b80e59a115a13e55001d951528c42860132531c9b8ab29dda7a657c53c2ce96fd85549f6f1810e121eb89961295335eaa0e40532d85814a4206e6fffdf9bff76599da9b2e71a22ed572910b0e3bae38ad72c7042579f106739a8628dea5a745168bd918736e488a 019ffee50be5496507e3ef5c40ee88a49625e46d1dd1686a52b09ad4a8e3ee9ef364f953bfcd97c52104eecb6138067192997cd4ebadaccb73c7b2560879289a46353a756b73cc43 b309289aaa77ef23bc595eb57cb3250a50296a1a6e34d73c3b41f305e3f8bd9f1bc0e6ced32a2c73e678dfe386a6e3ec +211acebfaf13bba33a9dd16722ec53baab92a140127d61372cbf1850f2fc894e942e25d780778235f880743953d04eca7a9205602e388172aec2abf35412b483490751f93b51239b6701cb0aab14e5179b0d7f55d8586358381dd83e3e436bf69a6820317d1701750cb1fea1293467ba589eec5f5779c2dbf2a9b8f28c4dc239 03129e96fd28c4198cc5242c1e3531a3979fae643d527044e98d7721aa56b5b4b45dfddfa17a4115e10a2b4f46d92f81cbdd7e86e588a4c6d8c2b3a83f54cebcee1d1dd33e85d81a aeaf4df0a9dd2a4eb7790fbb230836a0c777e513505a3abecd00b8599ea48b00110036156621c078f780459476be86db +ee592e20e0a45c18089c2e41460e65a7d22ed9714379f095d43a308bdd383128aaa6fb24e9d35fd28fc95c5b792ad75c980d2cdf0f460ac60b12c5919d3cb28dac4d488196be6c2dfe462b1b0ce59f8501692255840f5215c0fd8b74b1996a267a5e3b22d2841cf0a0b6315ef4ec7180f1c8494f4c07d5869c01fa2711739efc 03d723d2697cd07dd8444f992f2ab4a063db334034c25ea9be99fd7a1f495e3a644e5ea033a41264e0d24a911e55741d0cab80a0bd678eaec2bd1e60424d4491eb86d664900d907e 8bde1ca6b3ee9808750dfefb409af66fd75e6fbc09ba1b30285f3d31300479a8cf1384e83b953ebcc1098f4ec463fb0b +fffca41927debbd53455821441d9115db99fb31bfc69752a382f57bc7abe021f148346ee29e17512c64b4918ab2391d12d6e5643bee6b5682885dc28177b292e23a37ff99b359b9cf7578432af56e0ad1028a6cce7428980654c145af8daf09addbb3be11228d3c742defca9d3b1667f48c63091fe3307ecf72667b02e008f24 01999ab45d66cd1d3a0fe6aa43bf5ef1e2a67637d53674f6fbbfb9b582be91fc42a12cdcad94b50b0fc7ac55030de24a0b99fbc4314fa743ef4b5198bcc5f54d8b669fbed78e2e91 814ded94bd9e0727fbd776d1d76159bfc4e3c9ccd6dd5d94d22ac2f9755db0b12a28b889fc53564e2edcf1e1c3f1da19 +a2f71619ea04f7057e6943c2cece8594b341ec3b96c3915d924f94ba13fd7aaeed41ffa0e842ade414784f1ef825fcf2dbcf7bd8263b802def45f94de596aec0c121fc06558c7bb06b9f27a9bf56c42090b5dc344e82b69c4f528d33be166764a593483f6fda0cf56e6000ff363ba220f5ea0ea2c3191615c7ae3bb4fa575324 02ce1cae0716205330d730e6bc6dbfb6b951dc83ee3b4a7dae75d057e32e8a46e22be75b5f09135452b29c34dfe81a9be2e8dcd243fbd946a0ed14a832a7802e20cfe1abfd3d6e4b 92c4308df40986a1b563fe9922d3db8d2c3905315eae8eb227cca77e078bcd8c110ddaa6d382e50a1843b960fd357478 +b60415a831eca2cf60c79a334ef2f327a76d290846ee588d5d33d0a826bb0c7ec3e11dbb384a7f89c8d180425dfae7463e0ea6497d2eec1dde112f1c1efccb532a2e2b66a28e2d36d4252a4c3b12850d465fe21bddc441b92e6a7b0f67744f7f6e7812a0603211a26518b311a5b190ed890ad852bed4f6ed13377cab3eebedf4 02c9d0fcfcee7e75c3245ba955ae04188b1033c55ec9c821d8de7685276bda3e9a93c3ae1b003e5ea722913e7b169d67b1aa2dc8cd42adbd9368672a3f81a6817bf3e5529dcb0c8b b1c426d2ab81c4a6b75fe06879bc6bbc05bd76ffb2c3c47fa08f9b375df37d5859972fced56d9e348f09050aa8bf07c2 +5d15a08226cc74cf495be681b795d0bde26b19f29aca1a8c6ef77d50271ebdcb4e5fa2df23961fe11620b1c6580183f6ebdceb2c09516c8127be576496fb71449bbbf0a9d3d1c48a25024619b97c3e0d8b165897db96ae9758d13ac28441d7cbfb75b23cb423e0002046358bb6d64779974a5995dfe54b398f95f7d64fc52d96 010c057bbaa44ef0f565edc288bfe66d4f6acd8686899359bca418ba89fb690429489a37bd3c6c9f3a8714b2ca225868c6a45fee360e378a676f7ea39321790f32a4b005b81dce43 964c718e9086a10fad52ba749e7434bfde08f487792c61a735dc527f2f5add8c0b22e1e3706b002c80f30bd4df331d77 +9eca4bd88200baf61b901fca53dc1f1e7e3f83b94d58a6cc6a2adbc9b1a35fe3f8ec61787c76ed9a0d696167cd4fe46e1a0883fda564666131753c576a720125e0b712db1da0278067cb899bdb14eec08737e864544663abb1d62f34a2114be07e8e3cf56e2d17099299ce6b6d83b1a34e6153d7c6a32a72c7b1bf4583fcbcf7 02c182df7976ea93d996f3ba5d2221f3cb755cc7847bc3fe9e022fa4285046f5bfb426bafa3580beea206de36f87593ae561b4b74a03fcd61fbd0e8d6fd5668f2148819a88a650aa 95143ecf62131451fc0142753ba4efc4fc9222ad0c4b3e2b43403f40322a519054678b4c575e98090b571cfe47458b97 +707450bd84141f3b61beb12ffa5ae89d812dd11badcdf6a88a2d50fc70e23f6d822ff4477047abc58cdfa28f97ad7f4911ae0773c04ebed1f51bb2308cf6e5712c4aaed461edd6987fdd1796aab70198276b601241f6a14225dce575830ff60f935fd9f567d1d210652e4710922fa793da78c8fdc30c273cb08365c9fc887f50 02d3a65bbe133cc98cf0eb56ee1362195968b4eab960a1d55d8b762f1361fc21348d6f275d4bea1de7158fb97c995e20b92a9c887a3e332d154667ad167acc632eb88a0ead6113a2 8d2414fdb13aa3e105e25144640d29801f0db00cd5f250d2e255467bf1b8a7cb04f4d2f8e745466279d0924d3887a328 +d5ce9d59391cdc47ef942dd2a818d024ae3917deea8a5a4214e4db6a0c5e6b0936f3e632fdb68a3f0006e05c44b7232013e1da5f877cd197f44fd6f60c1fd2378995e9a47534948c5a09e33750f07a7165072ab38095373b07a50bc1391eb6b650ee13acd63d0352e7d9c31695ea1ec6323f9b5f57b426ace56aa7fdbf419be0 02a920e8dc928acdd56e3655b2340d4371c793e66f67405fb7a90f31e9c4ef466cc44331d1d2fe3ff7391d2576dc6640772166ef8c154a5ff1808f5dab2f03061070ec8b3f786c36 98d142e177c22f91ed5d9be82ac6d93fcac670fd58331c3ad9d2d9e35e73afcace13631c38a282ecf202e062a06f6942 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B571_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B571_blst new file mode 100644 index 000000000000..3369dcdecb2b --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_B571_blst @@ -0,0 +1,60 @@ +8e14f713a2c427b1f79491033994f76acbead614d12e73ac6f3f518f2052a10c1273aabe628ab38e0d3d5f8ff254802e9f44a51367bf80325b6fc39d907a37f731372864747b10749ea5cb3d3a83da39c21a7b02885a8c1770e4397cedc958e4baa21d5007569dc9dd1e45d2181709d900a394454090badbd0cd9c2cd2369aad 00f42afce7f7b3d45f3f925ab29fc3882a89c9f585177887584703cf8bd8fc572e677adfa55b402446fe1e90dc855358d92c3267c35be9674b40c2ad5ce8dbe6a533c44b0ad8d2b2 aee4c46aa7e3a3da8845eee8a75d8e43961a36da7b7ac9e295803a67414c80f13a3510d7b8f79d5e308e3e538469f09d +38b60d27ff08fb191811036dbfd5b39e1cc3427ff70efb67c851e9cb407f9fac6f348d289df98d055eec73299fcac068bd0fd9ffa3c5d244659e4f714a58d79f6727f323a7ee26369000e90e34e106f99f5ae2ae1b64ee89e5a1d304ef20c071a7773e9b977ed3d49f467d300a881c8371041394910f9c366942449045568f01 02f36613043cbf53ad36e2b38998bb867503359ae082d07d040e5a10a43e06ba9c91e7c73308e41e2391b65e634f83b162cbdf4e7a44ad818fb93a978af00f06be06731d8c5886c6 b796bf705ffbc596eb04cc2fe7ae4c7ca62287d1a0634781c4cf057f922db01edbda96286fe1ec958db1c127be0f17f1 +21709eeaf9e1953822294a478dfacfb205fc25f447a73a76a32601c00784cbf2f9ebd41c22721d70cdb3842dcaff4a4f208d41c0816990e421cc4b8538ac2f347cdd0aa2a39f1aa26ace8cb6a606b23f6244894d4594a0f6a5b8f6a695fd66e1a41e2eb6a377017177fec56bb58c837e311cd04c5b50575faee32606b9636ec1 02e74948c46930cbcd9dbe2325539c7dfdd910f309fd610e6599d425aad9ae230a8d4681970a14f2a71fd08030d0a40ff40dade7de1b06a80441bbf7e2fcf1809cff39c7ef88bf9f b3891f824dc4333f0974419c2ac983dbe27646bd722306955cd746902d668bda4a1f050cf3eef36f951187bbbe464999 +3a131fabf3dc97334f212fce41c44300440d16de1d6060450875f7276f53c026e2a511681b5a8d75fc0d578546339542833145f7ee13c708df33e584445a75a5538829286480d339be7c777c03c998a6d3f037b25799ab2d541021502a0b02a9b9c337a8b176c4f30e5b186485a6103b1d1563ad4ae73ca806a5e4daa92e9100 01b5fab1d36f6f6d559f65d8b01edba610620fc3a38307b1fb1c5bd63e7ffbd4a9098cb8bdf50975a873f5d047ee2b627b090897a7fb5f56d3f4a0f3528179e7c969926fc0d3b0e5 93046981f776143fb1b2a619c647547370fbf76d8c86acce41104c657b20c48a13cec7960629dd62da2e6bf4bc93ae98 +679d85a762f2574b0b31b516270b7d33d5e166c83e91a0f48e0f3db20b52f42f9e6ee9648cf58267ffe3b713723cf3df52b5fab5c14db1e7189f7cb7170bc6ec7cc71946745e152b39180f828688a5b6c0b2957ab94283b90052a3c6e36843c391aa8810f9253b639a8d5a69aec10070603ad7a99dcedb544858d057a1d66b89 0383e70c71b431eedd4574f65d01fb0304f7744d668408c847f7899eae44770a7f3243109740f177d7146a27748886b7b77ecf3792b512e8d8e37c3bf4ecef2b1253df7066498f01 a1e7a6da80adc2bde1deb608e8b9b58edbcfbc57e86e5a41696ca8989a86d9db2254d98c7a6a4ef369143dff811abcec +236152ad31ce2ffc0dead3c142cf6c770672cd2e75af4a82fda1a72e1c775cec9b481c6f3e411644df7e7ee901c501405620af4b6e9667dfd46091788daa95ef2c6c9f5c240c06b15cb0df51f5f058d8a7934bd7845f007a35f99fa97200b20f3b5b14fbf1e372507f3b2f377e8d07d30fd3e222f398f26d8f428e320327f901 002261d4ead21f02fab19bbb0da8c272286704c8f0c6842ba47ded121e5cddef79fb34e6b9694f725ca502949faecfb21e3cc062a2b4c654bd542d9a1fe8d97bdd0905c510aa0999 a43bbf67f08415a5196ddaa1d030f5b28d8cb1c67d460fa840c1d41044e4f60fd42150acbf4b22ea34302745b8efc106 +ba3f02c4847fae035d747db246fe4e82fb9224ff9cf568a6ae548f5dc2befb2079541d2cf9aaa6b18c281a05e7ddfcdbcefb25f41dd91cb3092b3343e16985e91c912215cd99ae4a099baf628e33a7b277e3c36a13aaef85418fca99f64d73b789f23ecbb76c3095ade0a5f7f34836a98c5be933b44a94a2eaa3f99b1d8e7937 0316c78f289e1860bb623082be9d9238b88e38c5e978a868bb90f776235bdff4eff591877b7f350cf14c40356922b2b6aa51d64990360b2b0e44d6941b5dd9492b4f4e1f42ca163a 8c7969c4c8e9033dd942c5b023382dc5ef133c65eb927fa840319572b3061bd2b04370697d9c49375698eb62732dfc32 +6d0372b40559e075af56af853cbe18ba2d471b0fc8917764abcc69102b03d5bbe1fc12458215be66409c26c89f67c72a8933677a07f88993af6918acb074fa915fe883b24bc3d191ff1b08852f07eda98977e70eba072d8bf189cd545230f59559ac05f1fa3f4e65886d0bc274a6e02e2399812b2bf91abae81e21279c5de996 02c1bc13f8320d97a82f3d9354e195481902214e16a4fd89332a0499208e91d50e5cabeb4927ba030cb42f5bc53b10f500fa646a8c88508cb0d63ebfce5c4bd574c527d686c735ce a848094cbe61fadb62ee676dd47e9361a920c33601d1703e81b41e1a568bf2bebf92b44d8dc95fca72d59d19d3d34b71 +bbfe66c82bc060bd14fd0e40769d9b3a026eb447550dd9f118c30d8448f725f8366edef042447962ba7f7f833b9e9094d0ff600714697e632626e7d12a592e040bdcee166dcda93952323191021bd12f3b1647d0f25a41739994659dcbb19333ca30f46f539c6f0a5c354cda8969a1eda572a309950c84c7607eb8ac20163912 013bd80eafa67663e75d7ae139bf285d2b9f1e03d8e32153c73e26d06e86d7acad22bde9f121a3f1ea674dcc1fe67bc7f5398d5e92555056bc046a02b0ba86c2a0dfe32e91add5b6 a759ade83c75d5cbef80a736a33ae91ceab4a9dfb84ca4e8aa356f3ee375bc6c73c02ce9a369152fe611707ca3708a7c +b35e9bf686717ce3b16a59963a32a2116130453b161a4e7ceb27b755856add836d779696edcaee3b5c986523891c8836109d431e55c23afbca022437ad19e6777efabb6da3bba1f5f44f905395b4cc7c9210590fd38da621582d059598e5e4569e904358e0dfc0dbfda4ce75538aa97480912852bccd433a9b96c9c66e9597d2 030834b0a4284097cdda2ada6947c6c281f7290a49b56becefea1e2788ea3ef78fb96807633c47c25138341768b241164ce0d42f7301728b928be2c047f2eb60fc2f844ab77306d2 89964472b391291c7fa365feb60070fa01a8b5f155fc3f8fcff745f75aec75db78cb5f97acd2b9a312d56705373c607d +57b5ae7e95c638b258d1e09b3fcb4341e203f5706862e199b103c8fdac72cbc5155e5cf8b300a0b3fb0ce1f897c45f7aefcc528182f73dd450cd84d5fe9eadff3f704dc2a01b4e847c22df430efd1c66b0199f3e5b59348af5386962a5ef25204fd230b54d58d7fae801c086f8f405d3d0aa7a9a9da15c22b868817cd897d853 00c81a79ced1eaaafc31b69a40d9939f4e484d625db6364a8e589b6b4d336d458b44287ea6c6aa7661113fc07806b147ff98216fa0c08708dc9d651821b922741deda522b4e436ad a75561611f45ff6f98f6086eca868a415f5181324cf4a94d4bf40daa1a9a5d2ba75a317cee84aa3074df524bb10e97f6 +daebfef74b452f039c999ba0528be3bd9e16deb5f46f6eae87b63db8b89952c949fd7db08311871eb2596865eed107aa065f030226ea675ee3256c31a3f85ddf4c21760582144e07af208f33c5f47cc026db5403186a65a47940691ea2d74ffb1245676260ef5717dd879d8b5b72d96f87fef5f762d4fd17454cb5ed83d8a11f 02f24670c0f77d2ca0266a743023d2c7413d56d0b5ec77b454ac59087efc4ea4d46179e10278e4ba416ffd8c3f9786ed202faf8251c0ef5a9ea5371fbb35b7afe3d15a9cb4bad975 ab72dbe6efb74a39e20a5bd2a25ae82a56d606f1600f21a9135f1135cd1ad14764db1d7f8f0d788d2f91ce11b092fa8a +62af0493ae79d71b552c4647d1fb7ab2f282a91cd44aebd8ef344dfd77b521b0c0a3f72e4513c8ecc0e4b84efef3df9482a07ccc1b740c571c5e69cb913740a792aa231b9dc87edfb72bac188293c6c6e788cb3dff32e8f483f8f34e21ee7efec71302cc3bdbfa47908a135f6ef3ff179dcef26d1a3987f7be967a6c0f799b0c 020985f2c6fe3ea04bdbab66a8b6167e5969c073b9d53cf3c77cebbf73f4dbf75e601620ec9c3107bf3fbfc6c79f8f063409bf8fe1d14b19e323d857e23dc05157d270c7514137e4 8749dc4465c5421af860b75238523b586d9d51dfa5284190257ddaf3bbce304ce016515790ed318fe95195fc16f7d23b +566f17851951777ebea3f8285610cd8ee5f882a68e7a4205e6fc9e2d66d210ee2505ee73d6503169f7b903012d43e7e99efa493a8e6ef926b16b9ad8f52156840ab561fc6b680120a88714fd66d1d0742189bf06c155e1138ee5314707173f7352e2cea0fc26e1553643f2490428718e44afd8372cbb7bf5b88234318ebf4355 02b3d641607b8a141f876f6d285ee46aea543880e772dadd5dd83d595b9643191d9597218e1d6adb081df133304037bcd2c05c24a54e6c4cca64fb2cc4569d6882315360059496d8 827ea90bd0b69068bcded26456724007369b39aea8f27e19b8be160986b0c360953013ba5f5b26d0f341e5b248eaa95f +25155825fc4f9a1c4dd1db837008e7e2594a879052431f5bfc76d0d2565b8fa726008befaeddceef73f3c60fa2cdf6d9a70e56d27210bd013034b38861ae49640ef208d3fe294ac4362f8eea44f58af3af8a9167a36b5acafb7ec95652d5885a0e08067ce1dfbb45a0c89ad1acb53eb404bf88fa5c3c463a0f912b5a2522a0d9 01afeb5ca87c81025ddf09c2b2c5ee22ba0105c0e619b67a324467485bd839030d149fee44d8bac6f5902a1245a50c3437046b7c89a84116b2147cddc645b6d2fd24d68e8d53bf5b 88655f735099682f87cb1f275fd5a7560e860f922310622a6d5b0a5f4049aeff954d93af6e1036d78c5b0b6e315367a2 +29acb0fca27e2a10d7b9e7e84a79af73e420abdb0f80dd2665696638951b52dd39ca028166b47a3b6a2eaeceb1a11c152383f0bec64e862db1c249672b3770909f775b794e0b9b28a5ec8635a996d912d837a5f22471b40ec2e84701a8804127a9f1a0b3c96ff654700bad3167240c2518fb5dedcc1be9f56a807083e587bc56 032c97639b69c7cdbf419286d0a1b406d9b1f2886521a8b979a36118d2a368aace5b02dd8c515f2041e6fb9f026d1e82e789dc826a56d2ef732b1bb0f49be2b696ab5d3d5694a2de abbe8e7a5a0d895392b142a26358cb440644f08661a5314a70d8ea8953ad3d77d3fdb131ab845892e8afe3ebe97f701a +c92d67cf6536f5046e15b02158da698bcbba4ff1e4e9e9c882cda67f817210402ef917ae93682c9c3dd817b21b73c6c00b7bf92ea80ecbbef2e67f4f4379d078a2b0f297742b2bb9c3fa3297a7e8079f488555bd37715eec92b4b1cbf897640ae8a1d2a0fbcee5423ab31a37629f98630275e35094a896cc574be0a449bb1bc3 00f93672159276c5a293582b9f49607bbdb970112f6c63b2b3b5d32ad3c8240c86b1af13a8dff6502c6b6a17712cfd988f8cd23a60693d64104143b3f91adb37f852e9e11a0ef110 b1dadcc5169ab1d5f95562b0ea0ae12f31e53568eccb47ba8da842b294301c7dce56b655b1518e2fdc2ea466b6a74bb9 +15413f614c4551e3b138b64f66d15f8964c40326a42b0afce820778eee4a88edb127fbf575da5263e5a2627b5461d311813ea868e6417615e7c4938313675009caac28bc7a2f4c0bc37572d9bf36a3b1794294e09c0121ceecaa4b916df45b0dd31225415e6c87cfeeb092a008fce2c543cd62365779ae28f29fa02a15d9dcd5 03db080bc99c5fe7e06d5032167af56783cb423fae59fb5b3c6bce5fbedf56b7b39b17810e48ea9a172881aa1f42f5e267349b60294d4a208b4437666b44abcfee5a1829e9467908 8b27659c5c25dbff12e85e13252067436b051f892b913419db8dc0040fe7a4e3a94feba0a20f9bfd9f5aa65eea377ee2 +9f901557451ae2f8ec79b6d4adc794cbfd9b2e6d28f19409532d91682820205308b41498a4e1ca247a2baa8da93de95e3c0f7afd6ca46bafdbdcc6d3374a12684676a50988b86a960a82180648c8c1e38f8fd9af604c7be3be4b24799f4544ac96d6360cdb83d1d0847fda21642934fd6cf65385b50d86d4656987901fb88d0c 006ee767f6f36bb8f364f324d8346455c899a49237d759003dd52cfa13b9baa4c71347b134b24ecaee32d247c34e3787a0c64bc5d299b55c86f64b47521d22f2c09db225b0c84cc6 80b35a76a16aa2424487588ef8332c0d23efab0fb667ebd5532d1fca0018391efb5cab39034c1aa9816f9e10da18bf54 +959fe5a19d7aea2ba611c7203e19f8e3f3cc101e03a98f91adfef602c424c580d5a868659368a930f9883d699fc633bd07f6cf8de474937db0bea86fa7cd140ec2f202663813033a757b93bd72afba15be5e47a4eb93e8a666aa1c72c241ca3922547d63fa3732fec54afea7ade84302e2f044275bb67433fb6b125b7913143c 038e2571d9f22309a636586d62863ed67a70538287f3ef88b88c3c2fa1a2900d48c342b6f15c26b8e7fb4875cda4093b7de7ceda48fe1e2cc2975afe958040881de61f309931e48d 9153f33a89a18dc35c4d75dc8c9986d256a32f533702a601223a602537c1f48b41718583f70030eb7b55653d2a67624b +97b9688d9ed5101b8cfb19e84b89cd644262ca1c7ee18944e29ddd3b4cca78e06338b270385b00a5e8b91ca5e628de3bba50e36ecc695b3ea737a9cf8b36871c473a54ba17819f49e730c0f253b0c769aefa6c16366fd2dd612f330e95fb119fcf3bf7f3e254438c0ab635ec04a8b2424a05b483ecf65b74a93636fbab7bf1d8 00c8f5736f1ae65592f3ca850f43d06441aaad8c03820f3b08d8a6db46488dcfb828459f8b3f34af73cce8dc7a5e3834e085a64523d890028e194214cef4003210e6eb530005b01a 8fd85ccb5540eb59f633921048efd355fd8234a5e88319b1105eecb5db6ca681ba50637c7738779265a398424ccfb8f3 +f08b250bf4a3980cb455338b3f4173723b3f44c97bacc9cf550149794a71426e398cb4a74bde141d8b7b4a72942f1c069676a9918e27792cb8f085ee037c78e3c468adea5123c4c64d8ca6a39f2f90140c5d2d80b669cbf0d1ccb466b18ded83a1d5f042c36188a04111c34ff769abba9aedda40a87be1e24b700225e2078056 01ee68c3994adaaa9e0d61bfcd3bc1cdf198d3fbfe28a44e5dd518867ea04b20e795eadacc48bfcf8e8216dceeaa069b756e8e99ed87b6b1d31154cc9310bc3b4555162a890b0c6c 88e5dc448658caa8d89c5f49b46f818a9e8fa7057878f9b6a40ab9c96c2ebae82f49d16c80fcc64ab6cc8c61f9479b8f +1cabd16fc29d7d919622810dc8b23c770b790b98b119eeab1b20900fa94fc2ebaf76be4f5eea91fc5276c5621c8677d4d117c4a5a782ee2ca1d5b0db997fdc8a05b6b3fbb833d7a7b81c3c615c2a662929760a96feefcf89e46b563314c9b77c86bf34438458b43b694ceba741b97dfcdacc0ed57652ae62856ce10ed2690770 03a6fbf66ebc1365ea7699c72cdac2dd85907ec59cd26e2d18713354b619ccb83b7fc0db9193aa8493c1855f1a83fd987cbbb65de17c59fbe79256aa5392f4eba045346e9ba26592 ab6cc2348841b069790cd28d8f99cabdbc856a233f34475c0530cb984bee448bf0a54af3c01ff69472388878ee00d755 +7bc8bbf5ebeacf40b3c82eb6eba5d994dcc6a3f2e12ef741f90f90e176d20c21e006ecdaf14cb5beef35bff46b2c374d9ee224516679b1a9e9255cd8ad8e60ed234f8ee7e0fc53c9021488158217d4b4369cc597d6053746efa1e73340bdd73c1bd2eed57b92426fd4d278d6a86e8be0f0a66ab3dfadefca8831b2f488636251 0145748871a0b5c1cee628de04a12fd68ff2b154fda96e47afaa96389d66d22802968584f6753d36618d49ed205260f09d3f5ccc2b27a34390ce58179b9834ff92a86d66ea0a97ca aeb40f65abfc7415cc2cf7df92a8d1a7b7c21d5f00339fca040cfec0245be05cd53d01d70ff908c14949d189c8910d40 +0cd2a45392871c0c262e7e6f036946354bb41f9c2187b8c4d399231280682f3e0a09731fbfd52c76ee63b9828c2d731f4cefee0a8c46419c398205b2ff80c67d7756db300a0a8385fa287dd37d9126f75998ae1cbab5136560592118db52fbf102b7ff0a1ed45b8a91a7d99d13a0f7fd4366392264aa1248d7324901467457ca 03c71911d24ad19c20fc1d8a044d63c9bb417abc3778d7e6234c6af79b898cbfc2f2787244708d2fe203be786edbdc4c9b12b413156b7b0bab0be8af895d191d853cd58aafe1ccce aae6a1d31029478962791350fd2927bf132d0dc46a9c0aefaeb92f8d7aa1d77004ca7464bd0206b10673198fc1168256 +e97092625b09c9ae6e152e1cbee207d83361f34cb9b0e727c816a5ed851f12f91fbf88ad9d4c8f9d07350f5d828fd8574eafc768bc72a2b18aaf4d2b48fb10f7c3431137b51850154de9706487d69a40a8f4cb2c799f48c5d8f518aff752500de93cbb94ab04ae1e0c7183a32d79a27291dd07b5fb6e6a4fab76e85c3a8607e2 018bd74698bac36ef11add6b3e3fad227ecd868f370ec04569462565d2f0af2340bf793486953a7b79ab04f0ab1f0e4fd16bf6b576cce677d543e73aa8edb0e50372f24ddfbff966 8749aa145d9cac6c2014a74e51ea425561ab9049a2818b252e9c95c96efdbd6432fb7c5a2bf33046973dc1248c477f01 +ae6723b8df5d6ab5fcfaa22d32fdf106d211514cb1892c7c43ca6cd85c2532f85929c8a259ed251215063cf92e1502528d1e22d5cf67efa0b8ef21e8eb2f5dff881ba1433e8bcf2b6af8742ecb2bccde081e534615a305562cc22d3398f61f277d8ca785842bda85d8a40438d9bf1aceaedcfc22c85533794a69cfc320931d3f 0335699bfd058ee2e6163f55d1816bf3669acea8b73be9c4ddfe775230925e6093cff7a66813adf22222c8376faa106d85ac9f3c67929bc58d8986795b6d35d5b9fa546dceabbedc b3b7bbcb6fc4b32ec30eadf448ec0ce78eb36a1a60c0669bae2adbbfa468bc762bcd68ae2ed2b30ee79e17caf5921267 +ee20c6b61886e02ed94359dff3559522ff550ca126fed4b2240ea7d999a182b7bb618c50528fcbd261d5e497a991fbac0cf4c105c0f664d6a00a9001c1ed522962fb44dd4159677ce8f1531019f86457c055c9cea6247086cdfe0442485cbbc4386ad002b4bd39a1a187752437f04569705cb7adc0c68f0fd059d946deb63f0b 02c3eaf801330b3f1b0504f2399f1d24455db29911f750c246ba0a134c3b59da8b3562911197764699a92ea1d95a2aac587e24f743df1dad3e1cf7edf955203e24a0225717f8d2df 81b8ab8ae2aad23b6c6101a2276cbd19af874d0f013304c2170cfcb71cc7ab6b21df0d35152019d4b2a33974aba6db72 +734a9eb8288e32f5a67cc1d88704523ca2c68b798d90e188d871d9f50d2da2063baf1ee6685c45832a1818aabc9afc0bc935e97969dc983a484f16d2bedb3c7c0b8221408be2480a5562d5d1e5d8763d1e474bf2826aa93a68c3b870e3bf34f4941cf590d88e1f5a8cd782a33992213f3f6b4b4f6dbfb3c3c8f21f5eaf4ef609 01c3ff067497e5d387f31f0ecc9c67b3c0dd6ec8c81318c492aad83c9dec6c99e4fa47447f6f7082d636c2591d0df940b947d0a4ae3778e2b7cc8fb92214638399def894ada276b8 a5f2beea67c4ef12f38c44934169062d8b4e79db19425d30abdbfe1d6819ce21b97577252778147ac01323716dfb2843 +68e27cc72fec8f3f1f3882c6efa08efdf21d74d13be5171da35ef2855666ad2ea6919d21dbc1cb6d296663dcbceeba2fe47a2c6507d3d4a67a61b55b0f81c93412d7e1fbe15a590e342a05f55daa55f8591171303154e615e81189a523b855829a5c96621ad118f522e397e2eea05c2603eeae6e3591215e29b2289bc384d8d4 004b4e04281b210fe78d516a5b69f878b7fa058941ee9ae8cc63b061d1eb9e12c3e0ecb8717ff4623ff5bbbcdb53c48adbd9c69636506ab929c5507d7ebafae5654aad65a263e48d a662ca07b906a69b4752c902a99b0c0a7b0c96c8e8d2c271d4c83bc97c4cbf4a992e50047c4a481df51c671112b3ff98 +e67cecedf35058b80787589514a9c81c6b9f4bced4260411d2af75bc46b8b2c962dc9d260dc99ebbf8ee64950766efc0e394184bdc8e2891d66bd3300ecc880e9d6a3d0eb615322378afc3dba89938704e9a8d0c949d4bae9838805c00377e3fe5ec6a1a98ad7eaaba6b500973dac48b26b7fb2e1b9889f8c387de535d4b2363 030f2849a713aeac95fde5ce3af853e9d070ee60709eccf35a076567be2c43f0fa34420b0fc097ff577221275a3a56e759efc32183be2d76058a7d20e5dd59f00415114d73a15b8f b41901681bc8f104b482749456ad0974945d4a87b6bdb0e885b857de11601ef5e9ec858847b359b623e4350aa1f69e7e +2baa1ac3f07e34b67b6af087400f261e138b070c8475378063286c16fa73578303380236a4af2484ea01ba56c1c619f6ae4e5e6ac2594c8e5aae7e7f196f96fc5d0f507bebedd4d818e77b9120e5b4bc01c7ab6339e88b71d0886631cc7fd89659bf513faf149c61eb14d55060c8dfc7e6e4c2b4ec8edaaa6bc36eca50a6feef 02ebb73d04e6e5361e20629e3ad119b33db5163ed91fd9a8aec4b774898784b6822a08992118a8fe6013094bad0be1e9bf01b27c069e4335bff7e0abd28a10443818f6b825e9cef1 9518274fcdb51c4e0473ffec87631dd2af0e0469730932435fef021cfeff5211de62a8ae3e44d214ed3bb1867eacd84b +0e640581f573068d8ebd2899a6aaeed0bf987ee11e22b05d25e88e9a1c3451f45ee3800d976f4603c18a041febef07a01086832a6f7ecd5d498d52e796a9d90758c87c36f4a5b704a39c456aaee2d5278183d5815d619c193da9fbc427d701bab0874bded848cb4bb066f56e119b637c78aeb6eaa387c41bec6cdd4bf7b2061a 01bfab717d6f6e16d9bc6e89d2ffac7cbe0f808cc8ca2eb515af7ecce5f3b230303775710a21bd25c2cc4566bb53c78c78e3774a9f306c751cc6e149929e45eef60f56c1d2388c6d 884f0f6e02d2b7ec1b8235b67431b210d519b9d8f3f3b4a3419aae5188a76bc8f9a3c1395b7a8e2c99620220a7055911 +51a2a560ba226d629127ce1ea7e812219ceaddd23561256331458c9f11fe73990f21d0dcd974a3773040090cfdc8e0f01692d951a0cbb60f8448a016c67abf46a9c150466ac77e656ea827b0ea7d1e77ea32071ba8314fc8a2edf69008f498bd1c18061d7d00f3340a7e2cd73e9766862378d8702e804a1870b442beb2d0aa14 000cc53bf7f1cad5e3dede4b4f4b082831604c92dd2b147869cdf1107259305b1d50359647f9f3d7d4e1e608865c65dc7c9ea46bc324dcb8423b554dc369d621743cbfb592b70eb5 98a5f43d26dbb3620288042835ad91ede886f6ec6cf16f7873bb37529c4394d6c7d1a6941d2324af6cef6cc63738b55f +90eeecff0a2e37df318c441df220dfea013ef29774ee92a56b213e13a798858f31e52b6ccb7599e7314f12b48a89884b113c1ba0526a54f3e9a33c940944319e084bff320cf5f391c02c731c4c4f8b05afa273374a1705d6c85337782ba7d36b9c00767180cad6422c11c581672ff631fa4c49d41b02481568ec87ea97220400 02b009530cb9d586e35dd8951ccb686833afb7a37ec253e547e85b253ba999f0f186b6d4ba41091615fe57678e9801b4dc94fa683511da25637b2acc9fe60936be15af16234c4ee7 8cf0953f42d72e56d43bed62139330a7784460c43bb1bf8d9a8e0cde46fb64437e6db41e10e07047e573f9c9a93b6ac6 +d3740cad41e2e365d80ae81da97fdf06d8b6c278b505e34cb683fb55ddc5189da543540914c0accd405dbf0063f6222885fda4b316dad4a83fd03e8d7b7e936f87fc0a5b095defc8a4b22fa97f00b394e672d5efd3e0a230c7e44dfeebda88641143502a400ed62e2a51f9561e5d652a43d616f16699e875deb9610c77de8e1c 02cc2d0d7189cc8fb3565a039aee7633ddc00ff427cafad32fd2010b10fe249c9724d91785e7080203626038109158e3a61a3970aa3e51688aa7f5184b22f63af63f80d3540ec023 914cc13486a9d19fe6faf389f3879888d4c665eac221aa063bdec3668104cef97df8a1b633bd9aad1eaec2bff9e0187e +5eb53b5f92121396c5ff30e0c92da48db4fbbdbf27297f9bc82614ab78f7fd863e34096c615a02e349d8bc7ae4b0700130704bedf32756b5ee6af10da1cd717d624fadc57a9aa6db4a6c5d6254c0e8f8c3c0d4d03c264eeeafd52cac2c1968d9d85b106167a49d0ccdbefb20bdc10a2555f8149203af52853169a02db94e5e2a 03d8936c00c131e38c6566d2464c4e207c878070bbf681695a6cd98cab2c6e80fe98cda80c66a5cf584e90a071144dda59c07b8fc7bb42464dbee5b6f739b0f2ee5fdff7e5a4e7cf 86daf5a154c86da7351e509a5e5264b5e9d3b0ccaf7e5fd5a92d65976fbd8cce081e508faac03197badcf88077f09c6f +5aced64f702a57ed7fabd045a40c967a485d2a70b0a5e82561d5141ef329469b2da5964a34df203a980111a77adca376c643b9030aa74516f054648c1534d912ea66582adf3c655dbd71ca55e47412315df5e2893e43b2e2dfe6e4dedf426f11846ebef34a99f5615460ce0475f7bc54b4a4fd99e83c982097c3136ac6188a5c 03dc7de970bce28a943d7599f2a9010fc99435b93bc4ba884d42503ac2941aa63fd07db34bcbb1127d56d6a4e277d6ca32051ea3467e376f74f98c3999d2f276b282ef8a28cf0cbc 9127be8750efa9f74e604cb6a2cbe6caffbc9e32ddd17f96f588c8847209154420c48910c0cde13d72f187636f148170 +43c24aea343d4e088bea25be69a332c631275c36677093e057de69cc83a4c5e70ab270e5a8930f55846f1a22ec10e03007dcf0942c6761e89c65c6a4f032eed97dc3a2c7f7ed1e82552fe48828a132ba16c41f6bd82a49335428a24fa1679522000e6a1d12c646e0e4b4c584398577ea9493bb334fa3cee8bfdb6c2e66f46436 02de6ee12eefa7a4a736484b19b42a513dfc059a060976edc3b0aa4b50e98d72df6506fed0499ff8480986748e938289e54a5e86c0c29733a9bcf5985aa63d8a2b57933a04a8e8e0 a7af2fdc4562fa726142961bdd7011b7c3ac05714d556a6e2acf29e3f85f239a7a6983ff90526cbf9f749d0fecfb04d0 +e89210565959d93b483659e62cf41f0a0147ea23890c2f1a694c377a826165e363860e4b084016cda878a43eb68465f81f397ecd50087a25215ce7c4ededa3552218071fa3acd7ae380655fc8fa884998209ffc8a2c26f1ca19dfcfee455dad35a4e72caecd8da47eb9ee21b889162f5d3032724abfd1a31e68612e18bfa9006 005468f0df2c9854f5f655743e79c750fd8812db28b096d97207bae7f5aafc6b6090c9c636ead9e0fde32a1ff8d539b53813733ca812b41b58ff85a941abe4f128d59fdf9847baa4 a6451f59f7f4697acf897d4d08e86a2409cd92551c761fd4c98ee0efdd45948a0f456c4e9ac6eb7c5550c1ed1030d81a +48629ec97f56273599cd9903f8a84ac2ba74275b40e1e42fa47649568babe05cf63c8417d828251acc2eec525b56dc9082b68d51b0c2bbaa7389fbee15d058cf482993b2bedc5a9101f1afdc79989a812478245d191550109fc17215679553c508c84e3d4cfdea377088d09eb214e6f92410facee4790beeecafe72b2e3ed192 03d3c6a7ab9450c94aa3b8a1ffb678e5b647af24cbfd66ee3944e6f264f406295b803767471fc67936fdfed1714b4b8761a07eec86543b7c4da6bd2fcb33fa8cda4077737f398e18 8cea5cd8af64fe84cd864f3969089d6130eac87a2bd5c6329931feec9cba2844c7456fcf9286252ea90ed7836307756b +aa3a9fe467b1ca638dd0622c9ea235a418b39b2e15ad81fee01b6892b240783d8db3c72e16c13df8016dac6addbfb85232158325bd7432fca3b8bf5db3abd0b4c5ccd0999609dc42199ca4680692a0805cdd68108bcb493a558ab507cec0a2782a9e976928985352edb2abc0c07078b59d2fd86fda7fc76cfe573181d934c46c 001ce010ea8e6e1a0c26ab22eb90f0700dc73b232c429d36371e68e429792afb7223f10327708bcff779ea55fb5f22ad87aa054e84d10f5450f1bc9a89279062ea2173f55ab0f76c b0e7b6a6fc840f98742147176cdee046fa2217a4d8459dc1405b9d611d5ab5de82f84cf4a33ee323af0b1606fe63856c +6c3937014361799f1461f652841b5137eb0dcaf01dd293298d002f27e9a770b9e1a30367e35c04603881f0c814cf8ecfbe1619cc49cd516b1d60d27de37ed52a5e1cc300e2face4669f308ebe6747255a3d386f16778e494a7cdd10b45171b2bfcdabd91b805bf24857708c1b75e368edb2874321324f83a19154d3a1578c767 01e7410d012aeef02b3723346d24ebafd684c99087ecccaea1cf3735d52c4c81dda41812c09f1e874dc964d858ca240a19963d5dc89451f5dd6764426ae41cb23f19cbfdca0fc562 8de43cec455f7110f367b38e9eb4733f2fe8bae4fdbd117c48f4d556784ebbdd1bac489d364dd50c42dcd826924156ce +12fea55ffda15db902aa6a4388b9807c89c193cbf75b5d2a4c95206fa43dedc45974c80079933451bdc5b3ea015ed3ca2c54156dc61afb1bc82adefed1491302a48b9d3d2f474ab45343c611677d360515b93fb36da7a1c1b2341c9cce185c881c0beef33d43967134a190c09034ae3261f3295b79aebd3fe123616f73cf2089 02139839ce38eb879d266065dde5e5ea227244323b330e3ad5a0bc690f3c210f794cf18f0d730693887548bfbc434f48ee10ed34cb41d52172b06e448df938170a5e17311cab8e88 b4e5396571c427c21e82a0df46544ede08dd03f27c47407a0f43fb16989b58b6d6e222918f156ce29ee57340714ebcd6 +c8395546842ddb545d8ea3db4efe970453dcb06025ac3b7a25aa5ef62070f3021b9a1fea91ff7055b6c398073e7886a6f71afe53c82c47b71377dfe291972503bbeb25bd477bf0e7adc8a5d3f8b34ccd0080d61e121214e1b29802b711cdd8a6bb2275a2395c467ec2c1571952992e448d736d8bd70ee629c75b5e32b8323a00 0274f70fe69e4dbb55c5d404e39f5196335047113087f8711f2f67f2be4964e4fbcb865680758df1c401cd677b0971654b7a6aeb7bee0d6d80ac0de14d4f46f356b2d5545c185aa6 b9c08008d0d8d4bfde7f346c53558c0dab8301ba7c3c88752319f65fca87f65fc27548e45282bc37fd01d377269ff97d +10d2e00ae57176c79cdfc746c0c887abe799ee445b151b008e3d9f81eb69be40298ddf37b5c45a9b6e5ff83785d8c140cf11e6a4c3879a2845796872363da24b10f1f8d9cc48f8af20681dceb60dd62095d6d3b1779a4a805de3d74e38983b24c0748618e2f92ef7cac257ff4bd1f41113f2891eb13c47930e69ddbe91f270fb 003e1b03ffca4399d5b439fac8f87a5cb06930f00d304193d7daf83d5947d0c1e293f74aef8e56849f16147133c37a6b3d1b1883e5d61d6b871ea036c5291d9a74541f28878cb986 acccb0c2b3027f7cf8f1f3100da80c78e4a7fdd022618f8f43c0e79257d3adf676bb1d20155f658b56a5c0849e21be1e +b61a0849a28672cb536fcf61ea2eb389d02ff7a09aa391744cae6597bd56703c40c50ca2dee5f7ee796acfd47322f03d8dbe4d99dc8eec588b4e5467f123075b2d74b2a0b0bbfd3ac5487a905fad6d6ac1421c2e564c0cf15e1f0f10bc31c249b7b46edd2462a55f85560d99bde9d5b06b97817d1dbe0a67c701d6e6e7878272 02e09ffd8b434bb7f67d1d3ccf482164f1653c6e4ec64dec2517aa21b7a93b2b21ea1eebb54734882f29303e489f02e3b741a87287e2dcdf3858eb6d2ec668f8b5b26f442ce513a2 94be6231019b0285ba2a924baa0fffcbc0562480208dd7578852ad2535ddee276b37f24309a61b7fde148bb33b93028a +ba6be551bc60653192401ed8ff9e1acd9013d8811a7a1389528bf07438366f5772cd7aedad010c19c47622cec03a4d35b8003b39ed901b720629ab59de55a03c1ca50a62987f8da159e356245df58d5ae1936e65f3cd3acbe03ad1d0fcab4aaf2a7a947549ae776772201efbc6fab1aebfa1d99994d4f43dc28f39c0f279b992 02a69bc1df069c6e89722521a63675f318252be629e7558f3716917998e660ac960b0b750562846fe6c12ef492951e51e224754bab84a6eacd4147a5f26ae85ee4381bb14ec2a8c7 b6b6c174a563f24915e9ec1d8c849c53a61c18b7f920444ef8f5f16788c7b35732934d918bddd53dcfcb580de5df2031 +295720a79ac8201f40a66b06ae5d970afb15f36582897eed25cd92edcd00f70ac8e31c556eed4375ea044c2e8b227a8e02c0a3e996c9272d52ac7b3ad43b80f217295dddc84b177cf1e800ad08bf7fdd021fb2f49b54162092f8d628679c4ee335abbc90c027264c8b288c6e16eca3172eaa297ba50626b00fe0a0ad3a9dbeeb 00d11ed1b78b22b3420df4ddc4acc7c2286d9569dd6dd88e0fa3ecae69bcced68bb81bbb4ca6e9b54e67856e7fdf39155aa27aecb9cc827ccb9cdcf9ac633561b27d8eebfc261aee 860c210fd6c6c2c89658df3a4f168bcc8c1bc86a473829702f23781f9f40816873514b325a2a961728b42260a73b0c92 +a9cff41c6dfdc4a12f31dc375a5455950077ae323d0b7a3d9a8dde73b76e9d7b94ddf9c88ae8e6c262d704052ac47681fc35adfc56c904baaa6e146eb653984369d76a85596cb744941aa7b558c945ff2e81bd5ef7f00ecb4f43af23b4cea3bd4ba7b1899f1868a0c0ecfc62ccb1d588955597ffbbaf34cab2838efc2b866669 02c36ef754b5bd065e9eadde684750acc52795be80f54dd3d7a7d743d968a18f7e404bd71f8a76eb0395f396df5a7c2ff7e0ab6de35df34282fda6ee01fe5b9b68ecb4e378dbe32e 8402c4ee33ab0417840169b556fb6bae6c3af172d8292009676f145cb882598596ca2c92167a2a3521020edb6b817187 +efa6c582d7fcf5e431aa89b3b00180c0e78efd7ccb0384d90b80e59a115a13e55001d951528c42860132531c9b8ab29dda7a657c53c2ce96fd85549f6f1810e121eb89961295335eaa0e40532d85814a4206e6fffdf9bff76599da9b2e71a22ed572910b0e3bae38ad72c7042579f106739a8628dea5a745168bd918736e488a 019ffee50be5496507e3ef5c40ee88a49625e46d1dd1686a52b09ad4a8e3ee9ef364f953bfcd97c52104eecb6138067192997cd4ebadaccb73c7b2560879289a46353a756b73cc43 8a3abdd18d969c162afd0272977cab487862e668a74e2006eb1b9284a7c4081026d2939840e393eb620e12861ed16f76 +211acebfaf13bba33a9dd16722ec53baab92a140127d61372cbf1850f2fc894e942e25d780778235f880743953d04eca7a9205602e388172aec2abf35412b483490751f93b51239b6701cb0aab14e5179b0d7f55d8586358381dd83e3e436bf69a6820317d1701750cb1fea1293467ba589eec5f5779c2dbf2a9b8f28c4dc239 03129e96fd28c4198cc5242c1e3531a3979fae643d527044e98d7721aa56b5b4b45dfddfa17a4115e10a2b4f46d92f81cbdd7e86e588a4c6d8c2b3a83f54cebcee1d1dd33e85d81a 96eb73f41f6bfa00df5711469ca54d06cda1dc26bc7bbe4c9420e1d18896376c0c7bd0d1ee47bbdb3d372b5af6259e1a +ee592e20e0a45c18089c2e41460e65a7d22ed9714379f095d43a308bdd383128aaa6fb24e9d35fd28fc95c5b792ad75c980d2cdf0f460ac60b12c5919d3cb28dac4d488196be6c2dfe462b1b0ce59f8501692255840f5215c0fd8b74b1996a267a5e3b22d2841cf0a0b6315ef4ec7180f1c8494f4c07d5869c01fa2711739efc 03d723d2697cd07dd8444f992f2ab4a063db334034c25ea9be99fd7a1f495e3a644e5ea033a41264e0d24a911e55741d0cab80a0bd678eaec2bd1e60424d4491eb86d664900d907e 87dcaad35fc25245e6e29ad9dacaca0f721e4d5d0d1655c4255f043e99adc14c45a59a780b8e5867cf18e006900ec7a6 +fffca41927debbd53455821441d9115db99fb31bfc69752a382f57bc7abe021f148346ee29e17512c64b4918ab2391d12d6e5643bee6b5682885dc28177b292e23a37ff99b359b9cf7578432af56e0ad1028a6cce7428980654c145af8daf09addbb3be11228d3c742defca9d3b1667f48c63091fe3307ecf72667b02e008f24 01999ab45d66cd1d3a0fe6aa43bf5ef1e2a67637d53674f6fbbfb9b582be91fc42a12cdcad94b50b0fc7ac55030de24a0b99fbc4314fa743ef4b5198bcc5f54d8b669fbed78e2e91 96b716f9f3596de75f37ae053dba2d6c013fd098ecf8cadb2d3b7fc8ca99453204a61db43805b6e3c3da42e4b4d1b713 +a2f71619ea04f7057e6943c2cece8594b341ec3b96c3915d924f94ba13fd7aaeed41ffa0e842ade414784f1ef825fcf2dbcf7bd8263b802def45f94de596aec0c121fc06558c7bb06b9f27a9bf56c42090b5dc344e82b69c4f528d33be166764a593483f6fda0cf56e6000ff363ba220f5ea0ea2c3191615c7ae3bb4fa575324 02ce1cae0716205330d730e6bc6dbfb6b951dc83ee3b4a7dae75d057e32e8a46e22be75b5f09135452b29c34dfe81a9be2e8dcd243fbd946a0ed14a832a7802e20cfe1abfd3d6e4b b7ebfb4d7cb961ffab77d2313ec177e2652559927dd3e7647e66863b2d969c95312ddcdf2a2e522f2da39555156c2653 +b60415a831eca2cf60c79a334ef2f327a76d290846ee588d5d33d0a826bb0c7ec3e11dbb384a7f89c8d180425dfae7463e0ea6497d2eec1dde112f1c1efccb532a2e2b66a28e2d36d4252a4c3b12850d465fe21bddc441b92e6a7b0f67744f7f6e7812a0603211a26518b311a5b190ed890ad852bed4f6ed13377cab3eebedf4 02c9d0fcfcee7e75c3245ba955ae04188b1033c55ec9c821d8de7685276bda3e9a93c3ae1b003e5ea722913e7b169d67b1aa2dc8cd42adbd9368672a3f81a6817bf3e5529dcb0c8b 8a7e66a13be93db69f33f38575f3b75403da5e29538c8284ecec3dba70d64dcc10ea8f0329c6e59e369d81e3d3dd8d44 +5d15a08226cc74cf495be681b795d0bde26b19f29aca1a8c6ef77d50271ebdcb4e5fa2df23961fe11620b1c6580183f6ebdceb2c09516c8127be576496fb71449bbbf0a9d3d1c48a25024619b97c3e0d8b165897db96ae9758d13ac28441d7cbfb75b23cb423e0002046358bb6d64779974a5995dfe54b398f95f7d64fc52d96 010c057bbaa44ef0f565edc288bfe66d4f6acd8686899359bca418ba89fb690429489a37bd3c6c9f3a8714b2ca225868c6a45fee360e378a676f7ea39321790f32a4b005b81dce43 91787da8ecca66752ab7435fcc0660258c4d156ab515c15947fc8f262165f58f042a526cd132d8a6152d69518b35b2d9 +9eca4bd88200baf61b901fca53dc1f1e7e3f83b94d58a6cc6a2adbc9b1a35fe3f8ec61787c76ed9a0d696167cd4fe46e1a0883fda564666131753c576a720125e0b712db1da0278067cb899bdb14eec08737e864544663abb1d62f34a2114be07e8e3cf56e2d17099299ce6b6d83b1a34e6153d7c6a32a72c7b1bf4583fcbcf7 02c182df7976ea93d996f3ba5d2221f3cb755cc7847bc3fe9e022fa4285046f5bfb426bafa3580beea206de36f87593ae561b4b74a03fcd61fbd0e8d6fd5668f2148819a88a650aa 863d9226f90b4ad8a45255a7935541c357cbf7f0425ac67c722adae87e6ad755eb9b576ddebfb7e5849878fa2ddb770e +707450bd84141f3b61beb12ffa5ae89d812dd11badcdf6a88a2d50fc70e23f6d822ff4477047abc58cdfa28f97ad7f4911ae0773c04ebed1f51bb2308cf6e5712c4aaed461edd6987fdd1796aab70198276b601241f6a14225dce575830ff60f935fd9f567d1d210652e4710922fa793da78c8fdc30c273cb08365c9fc887f50 02d3a65bbe133cc98cf0eb56ee1362195968b4eab960a1d55d8b762f1361fc21348d6f275d4bea1de7158fb97c995e20b92a9c887a3e332d154667ad167acc632eb88a0ead6113a2 9531fa8ad96ee80d6014972062c9a4d2e1757ab197e3eeec9444694f0ff67d23f41ec8b380fb1f8edc3aa7d48b155674 +d5ce9d59391cdc47ef942dd2a818d024ae3917deea8a5a4214e4db6a0c5e6b0936f3e632fdb68a3f0006e05c44b7232013e1da5f877cd197f44fd6f60c1fd2378995e9a47534948c5a09e33750f07a7165072ab38095373b07a50bc1391eb6b650ee13acd63d0352e7d9c31695ea1ec6323f9b5f57b426ace56aa7fdbf419be0 02a920e8dc928acdd56e3655b2340d4371c793e66f67405fb7a90f31e9c4ef466cc44331d1d2fe3ff7391d2576dc6640772166ef8c154a5ff1808f5dab2f03061070ec8b3f786c36 8548dcdcbe5f1fe5be0633e66e88c1ed2b5f5d735aeed7881537384d5c1642828322892abb1e9a4f66f759f6a4d94389 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K233 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K233 new file mode 100644 index 000000000000..8956680e5cdb --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K233 @@ -0,0 +1,60 @@ +f23f784fe136c9fc0d169503d361e9c6148b0f1fbdcae0a97fae1af7033ddef25cb7489c9963cfcb009a8cbfe44a8510a64a073eb1deae4c324ceb9302008c92c69b2dafcc9077fd3cc3c7c119edc3ced36d176ceaa55ac036bf7f07f6fa215e8bb8196e59a5e1c9af4f98b90ab4970885bd7015fa26a09e03c7cf6b4b23d929 004c1d414696cc3657dd9df73ace56eda2636769ce7082e064c260be45a5 918cdf817861e8bee5ee63f2d6894c17a76523a01e803e95ecf36b1618f2afceb8f660608271a439d5db4666dcba7f88 +400bcb297552bb37f2f8135a9314a35f5126788bb6fa4dc74152731ff64c5dab4b902103d85443dec20e16b1d6629930cdc2bd183d4099f0e96295a63c2fe266f5e9d050c401a8681b4a438efe53cbd8f2f43e2a31e9f88926a9c82917d873f6e8cd5ff5eb8c1ca36126b0bfc8c2b0e85a7c9e7a45f1875ca9c82019ebedb729 0027cb1d84865a16992476c9e353283d5d6a40c349a8e9179d1b1f403531 ab5e8bfb5230b02721eaf9caf85b95880cfadead09a3217759f60bffd15767d85a17393a83ee7fd2969fcce0d96c696f +5f74d4b35c49fa454c97c05fdb6b9f6822cf1a2295f15bd766dbcb413d77c910bd8f4147e8f317fac2300fa21cb80134d1b6f8ae8e50518c1f648a28506e419f5a6e8f05abffdb3dd2587606c7e9c223ecff4f46b121216730ea13202b59128a7616bb2fd23a7e4a5aa08641cc07b669641313febfc88d64d99447353dae3f06 0031b443f46c4b5224237fac1022ee1570173f664aba0c84dbaa4246bdc1 aca837d12c5c37753cf2be54e22cc486b8178424b11d92d00dca06d2f9e797ce4c4f60b5ff5bb2197d5ae4377d8525ca +8f92096876d9f81bcd992369d42d0b5877ac969004d17c8627c58d8b8b7bbf7a37e8cb6afa962b9b043bbbaa5bef4a5ee38d8bd31cb5866b828265a2f4102a616f87009cd346fcb8af5519fb577c60d8792472232f33dc615655e53d2b715b15a2697b492f108b7906e1e3597c6911f8cc30c7121ae338a6b747ec368f8e4a36 0048f6ca29f35f253a4962734357c995920967b9eeff1ba5fd2080bfede5 a46f7483a8312e7a184d787cf2e13907f107c8e583d28ac970908ecd4133caae25df137963563c4424e547df52cf75ec +3d275dbde44494c45fc15fe89e2ae32aa26426a17e923e895c7941a5582fb95df4d49873ab1bde358017f336b911b886b626b744806ab8113418473c441f1964159ded1b12122d53ac56573167588e4b55f36b8bca8c67823883a51fb6e7f204d1c6b07ea49b577bfab9ca6b8d51f72268b022e3a4db6f9d265ee8382f9b7b66 0019b940eabbe682f961d9f3d90432e347fef3910e641656825d775705b1 95010440ef31dc0499ae4826f5d377a31025d79c0cf135912f33c38d596a824b420f9ec188361cf3985325fd887a5d88 +d2fa68e1f7dad02916b12fa38f1849d6d409dbad0344438520b4dd9b77d62d39ac9ae3cdeab03ccbcfd4de703c6e798873671731c108f322b9f2a68145e3e210c9b15b879798e5c53c5022742e9819b99edabb2f44d89ae221f7a99dc84421a6905695ff91928db608f861745f17584d56e34b75c47281435b1b0b34e490692d 007a884b22e29fa9fe945e9ba13c0df8d786dc87cef0f77f069e182dd56c 82f6b163c286cd931704c1042eca1a94213f74d500ac8c24e175878eee786f7443d11fde96077cca3ecafbb908d7f696 +3830f75cf9df4eb2998c7c1b5fe11c1476bcf849c3a8fa7d3d0b5bc2292e5d07465ab8cc9381c575d909e509c5dac49c78817c04e4bef18bd51bb09aa5897f21634633a5ce6d20bb4638cb6c3927351eaec7b62cf4a33956916045c392f325adafb10a88a5f86d7e41dd77908fa7284210071c22aa40ef40da6339c02da05392 005da61f881d5a0dc085bb93764f584352882923cd237d878220ec624c1a b039a2a2feec0a86eb7ae39bf7372f5d2caff4753704d9c77be191e97b9dbf4e3ce9aaa8aafa6620732d32c3ab6c4496 +65b9fe15e6c35d453caa6bad39ee78a720a04b60d8a0a0f049186d2f777e48ae2d657e174df53edb7beb9f7d8f21904ed674add0cda5b62a7308de76c324a144021e8c6d387daaba4ce48bf7dfe9c8aeee2c64e434ece1fa5ddcafcf3e5d0013a1eeec1742a00d384cc2ec0d7eda83bb4dccfb0e57045ebfc27a4f404d03da37 003fe9f04647f6d82b13ec1ae5a8c2e49bc66b05649ad778eb16149ad83a 8c5a9b1957ef64bf6533e942d1f30c0f521dfa3a8b148627ce00ac50ae9a696a16b7721a0e1009f7165fc9d041a91431 +d26521fd41eb5d46ece6836e188bf9cb1b461d011c41e002a935d256654d01725378e845920ec4a7fd3f379df54772493df50d312c7c6aa4e909e7b83f2442c3a5e85c37d68aa015098ecfb0a5e077370f4576f4bc63bf37e1dee06d780a3b6949af5e21c2a0960fcd20821ef5f17bebf5fd5b3bdda260842cbbfad45667287a 005ebce648ace4cd555413de6a456fc487d14bf4b0b9a72311ef480d2f26 88365c483f072a10c0af5030293129165d35de4a74da448250f516263b568f6de95d2c4e569d7c6ff6025c0e898530ca +b778c021b1a92c41dbd09963da07018075d73e54d62df5c2b7bf8abe137151650d1c1c6abce7eebd8f32e8c3e6d1433773f257bb3ba4a4fb6a02c0db1e47d03c27d3a90898ebd1927c21df24c4c5443ca5b81f8ef2cc0f5e8b3d08f472bf07085df737adaedec63d99acd77b87ba98225f198b791124ac2d9b191cb9251b4b00 0056653c2f85593f789a926ba49fa3da9d7f946d8f1020508c5a527ce813 8010774508dac706e2bdb643cfeeae66f2612bc590929a11799fbfc7715013e5fdb74ffd0ced00e15f7471f07a62b37f +ec14e07f615960015a489ef999e308b42a4c571473b9bd64b433dabd9a1b1ad02e33eee9100064405175928a94543a80f440040afa2965b4e5f95f768e7fab6d3c0a5f5e1bf1df7822f78384e80f2955ea85f044ac60537d895747979f935bb0cd3673193c4a32dd7803e48d7daf70a71bc2aa97236615b6411e28fc9a652145 0049a91d320783cc70a5952c32036cfc75d41f1aa84127db2dc759fb291c a0e3454ff3dbc79c5b1f3e20827864b45ff4d175c892b5194ec471eb347011e727859a95f5913daefd4161083ad61f3b +89c645339ad0eb850e4e2fe583cee175b35feb02ed7541d7e9aace24cdd3939584f73ad39526de6399c86b36de77a018e2c70b532bd0f032f9137d10480acc30c49f9baaa86f9df0033b77e98b485bf7a69cb5c281e527d3ccd1fce2415f0dda4a268ce68a0a34b16afda54ed922cd6810ac8dc766df2a3a6c5e55972e9786fc 0016a20016602fc7088a60469843e1d29ad67e3c3cb9500b1e2a00d4050a 88aa91eaa52270762388d657a384f73241b5360a6781c9791f35736f58dc3c1b9749b0b68efdf89aa81ca2198b08596d +ace14c4b101d2d8453c2bc22b756af016b5de537df9c3e639d208ad04ae0bf6232dc90b90c33228dc85de956db771ffde05fb4d0b15e4f218ed2771d703ae5bf981252a5bcd60c16f14483131a481cbe04dc0adb1fb8aa32cb48bb5008e8a8e5c7b7465be2fd7afbc811cf5ea6293b1a464669b49f55f57b93a8707e6042fda6 000ba922149bada2551b7be1c3df076f3f97ce93c13c50c285fef3f42363 a8bb0cf00975c822c4f592186726733953c8a16333dc8bf12e2ad21c954999fe8683d6041e90e3b3c64b315d7de44ad7 +cec2ba0d1772c87e87d5bbbd67220692bea4301aa1a66e8dbdd7e651d45c26dc2a0d45cfc32c34d76ae3e1c61db7b0fe1863457b93937d929e6ece7462ebd16adfd708353d6f7c27aafe06593c76da7149b0cc574a4290b0d8fe219f3eada7082aca38dba3f78ed0d5942d095fa5556fc8bcef331ff0a6d5d1f4e6c51d4ff5af 002d635e12a58cc6dea44e71e87c37f91e8d08659f0b7955d24f65ab55ba b66a9970abdd31900d62647faf4fc9d4e8af4e02c8c6a603b9d049da21bc62b59a91cc0a682504574ab23151e611c869 +ffa13cd0f51ae2643d5d4edecb493ddd653e9faddcffc370e7e958abf726a5d67a2ab36cef42ea8ebe22a6f01b9c31f6ffad01e6894487d979acb5e618f765ac0ec3550ac5dbbcede8f9fdbe52fbaba5c087ff382b6d7a09b2b5084227d324d98ff98793040884799b96d2ca593201f4414f18c43b51c53c5e5059e0641aca02 00073883e5064e06814fc4de32e15f7a6cf825d2daf6eb1df8c83e25d80a ae947a170811a4230dada6374c63c3800f10bde8d36b4a79abae7b0c74f7cef9c5870e29f43055f7e7a7ee77a009f4da +c73e3dbac9513d0361dabe94071faf03a11cba18c06d131a172d5f0125b01a5eeb6055bf72c7106fe3f4be3bd2b1771cbe7f85366dccfbc3bac20538510c3f51179cc540ddafb2f3b05a0d276899674ab1d7d8fb4f6838f04e4f9e26b8c6af31540f63f4953c85840af4c57dfa78c704f637dfc8dd750fe45e2c1e149986d127 001532271bfae8d4dfe60f69b88d3006d58e28aacfa701861cde8d624db6 b011abd29930c2d367a55cab7021f8b08092fc790a61503a6e0c255c95b3bed10f3cb8fb75a8beab9a7a0a46de94c61d +d00dcd0f3212a3167403abed91c20e76f5e7a7678a4fd970f944d11e6a8cd149d0aa6fd3164c5a74c0f55193a4fa3d8ba6f99cabed10544625a7bd92b3e0b46edbd4a269bbc10518c5268c3910a2aea567ccd32d4c7a0cbef09ea42c20b636d1f711d220e23dacdb9d1146e0494401349749e5ed88e38295232a7effbae3aed6 00550406c0db882c6aee6cf3b6baf377375208c3e90cc44a067cee43efcf 97b994a280f00e40419f5d0495436ad67258b0756fe69ffebc3f49a71feb410b418005bbc2e16954a7b22e629ccc9dd8 +3d36221f87157ca4db84884b8666660c4e2b6af330480c516cded9f3bfe132543626a39bb6aed1964eb5c33ea0b95b9841665417679fceb95d199d55accfce35dd3f2283c1a7ced57d0c4b9ebe3da6e1ff2f979b6440db27caf9f6a4bbfa47e20d29ae304f4d0551fce9cc4097eb2fbedb9b24680bb17d207bdccdbe799d5b0d 00257dc63752920b6854d6c2d1cca68589a38418c3d036e73760a12214ab a5609da6a18ab945680895cfb1a601a81dccb927a44118bf2a535ad6f42fc8107ca37c01a5f357e526c07180552f5c88 +033d82a42d0eddf58fbe3e91ddff7190e3f9fc2b1e2eede977d2c0473b358b5fce1f981ca6f88fd61ce2f79e453e3a2b77d1baab2b970ed28d5dcff58873a620e195085e61c4b8480d829525a1a944e8a4b63352f0291f0311f1f98ceb262804beec1c74947618f8e3b067866255878c2502966cefcdda4f5fa2b13d92ce7840 0029025352297a7be850f8852411c09259b83219135e0e8949c1bd5b94c1 b56308f3d3aaf47e9ff54e8ea521dc4f1a7a88c6d88d93656cfc86a2d02efff049abe26bd6d558ef6f8f8e8661d74596 +671a7c81b64b2919722d7b258bdbd90165bb757b53106e0af03d0eef27452942f40cf52bc95cc7f6567df2613cce795f8bcfc723b2735efc35375c001d37c58480d89343697146b524835df3dbd333f7c06c98e36d3c4592ecd1f34ab57c341bb0f4c785f5b8372775f74b4bce60763fad1788e77ea158d735a64861320b36c6 002dc82d0e69e498528925c0e62a13fda9af8cefd047c10c3ffc2e41da3e a05e0757d9cbcc3c2049af83c5af5c94dfbabf56802d70ec46aa7688186eb97deff15648d6a8ceac16b8c3c55d1d860e +0ef677f4799298f4aab73b7393598041f56e902ced1726af49657b6601a06186212e3ee8cd4bd33b760dfa2ea3c38884f94358d51dd479f2ccc8b0b352fa4e44fcfdcfbb24919d04e6ee1108527b8e8d60e8d1b467c30c18c5455e5835d483161d3fc26b4a67d6df9e3ddd9331247cb18450188752a1ca219f3396a872cb13d8 0041535fff5d279bcd744b04e643458ce20b81df8a9e01b1181d52bb14e4 86d2ad7f2c88f19fa4457bf072fdd9f295e81dba683ae222e0dce0be7d20e5b7849b1cdeaad44a5a6026330e7dc12c1b +9290df0cc50c3cab6655f3a6de1f4cf613d9bc06ea7c99f38038369ff2fadefa57a3c7ae7940c1b98bb1d03503cc271f7a891bf38eec93c31dcec7892dfd2e1ab337bedde3e5325ed8d9cb7fa3096f6fafc3beb3a66cba66ba826d1032debfb4908cc9dded8c0099c85072daac4373fbc428fcaa9a6da02181ebc33f0cf926fb 0000ecfe580a624df66c25e87e7689fc3b471d205970ff9ab51a64aa12ed a0e7b3f266f115e69b98bdbee48e92972f1eec0948371b29cebbd10c9e1c34cfc2e3849b18422ade6e3c696d7025b949 +855c7be75fda372f062709827f333630acf28954a62a5193ff675f0dfeb63f32bca418f7cbdb346bf388d62315b19a592267ca407120db93d4e3d7125b867c4c4670b7a57a76f61734cead2caf2425eb9ff0a63293e8cd6defc9648257b401463f4533a2425e0024f1ea93365eeee3c6da20d25928602ec8b426f9b39f97f3fe 0013c72c73358ffa168423149ecdd897f0a5f75a641de008649f00134944 a3ec20ac9eb9ec56497af86c9abcf5a5368b74746ac583d8254d8733669a3d265a9384afe7c9d2106bed3edfcc451716 +9c896f800281812ed57d31623d563377a5c725cec84313472b90e73f77d400f5d4fb236255741b73d46f7e5254d04099bec274db8a9af5fc7cc220d42cc172cbd3c3595c49ff74bfaab7b5e46c90855b611f74753ccdbbabf92e011d52e9ba753b83ed2a251a632e1bd5c6d346e38e743950c8ce0f394a837028575fa44bcc26 000ac60e2e70b7c4cda64071c7738f68773c94df9456a8ec3bbb468fa7f8 b14cf1f155db08cacad5be9f82f6068752c0ca45837defce9471b3e5185a6fe8a066e2b43a9af34e55a4f88133b25809 +139a14ead998d1a962fa47c47ef2953aa136bd912fe940709b8c560bc2a0c4bf8f3aab30a8e21b7d5f487d30b0097e3da723f11b5cb4e8c5724f5a2fe0d68ee4bacbb85e5eacf18094d2a8ec4506cf8497836a4a905059a998ea750adc54c27c69cbd0b0c1f9743a62f3d988f3fa0a9865a73fc071f526623085a2ef12838888 0060bf720052e8b9508a801340c213cf53bbecf4975faee63d4b44fc647a a457fad8bddc5088e30c381e6264339fedd5bafdf57643866d9798cb76ca236c10e510a449f0e09943e72ac763350fd9 +cf4a8e754b23d0fffc1c5c80b0cb11deeaba3064b315bc2cee96db5b9881baf90d30af4b69066f757b3020706def77a5fc1632d96bafba22a9c8cd3b52d535d941b3c7cc02b7fe6b51639d5e2084478ab3a29d2f5e0e16639fc2833a47b58e2c3fb5b2ea1830fe2ff68e571a8f281617a23d9a28db1c64ddfb1083d055030e5a 007cf3c216592febd8630a478b5b3e3a605084020322adb13ac0a626bc7b a8f59c32d4b54b42636b3f595a740b78ffb15480bb65a509273fdf6abc377138fb8501d61f0995edad7b13b86c14496c +ae64030d4af9b36c8d3a6af0aff34e5ab201df04274691fb420b7d5c40c401ed7f3ade96065d34f2490d17943e27156e7bed83cd7222d0d5a73d167855fbe7ff6c3ed87f20986ad8bbbd80fed5f9705c6c783b423f641d40ff1f367f9648af5a79ea3cea0236997558bd9dcb011ea4dc64d61ea1e1f85b4f696ed586bc7705be 0061eda5999e5a9ed4485d2a0ac5510549b76ca37df858ea5d95aeed571b b09a3a09d6eb58b8670101cbbbb1bb974f83f0bf79e645de07c68d518cd60b070827cfaf507f413a863fca13031d9cee +94a9d9cd9efa3e4ccf2a37f904dd9cab5624ec9393cf8816ea591c5e70cccd2f105388ae133708fb974998ae61d218c71785f9eb808d1c28d953cc7eed00dd9854b6b4568c5ed5ee3df3b58a1e04c64f1c87fee4365ec9aa41b08a6bae234dc43a0bf2f61420acdb891a40f17f246972afee75a4c0b249dee0fc8f9b9c8a243d 007e7e73171e4d2f2989dc024757c186485435b82544a448f5cfca05f281 a54d7fbe89a33a8f7e2c45b208a5ccaa14b1665f6b6082a7ec1c55355f5cb34e89177f04e4682d0db4d3200333bfdc0f +4db998df7b90678b8aa4ec6233c9b4629800ad1f3e2cf8f7afcac62fc6982dcb290e44587015eca8dfe77dbb4a80f9bffe75b11e961e70deed14555db6dae47d49e73004f000eb8677c18f7e8234bf0a5a104266167a05ef07152e7acc2f0368b37efe69c0c2feb51eedf7338cf9ed398f066cf1f66bacd89ab9376d41da35a2 005f7270764a0444c7159d2db867930fdb0fb9fa6b8fc80ca02e11753095 95792ef4bd9e22cb7d89accb92115ec4173e46162d4989f60fa6f693e601177795d7d845f8a3d430dfa2b14fd8c7f0a0 +dbf9b8a4ae316bd2df0c80db1cb5d7038364a2634925ff957d7c03511b57d486274b2ecf191746827c325a14dc94daacd66ad86d369e3f598f176c4f0eadec7e9edd13e34043efbe0a801b75b8186b4a6d89ceae4fb250ab570d65b6dd7c04382738fe3f6f6c867a7d84b35b20720cb0036a5d81a87126f236833831d9ff00b1 00179b924afa4acf30ecbe2b3c12de533a1f9675687876a7e5e5ddc8e03b 80d52c06e8b98822f57b2461b5e0df2c0334c76fa56b1eaf2a1ae482aa3ac2ee20b434ed348d851a7cac5952cf95f89f +986d9e5d636526f4deb7545c037fe81b09c74496ddb8e42e61650c74b6fe348593f0cf8f8eca5e839baf62f17bf6ad96ec0c71dc44fdf11259dbfe7499157e402f6bd5076972354150723afb632799a990c44cd0a4fa9609ec4db133e3b4700be3ea4a338e8ba1873d345e80163ed60d0de274d7617a8382980bc2138b0a2a01 002c9eb4d392d7f2eef606e1861183acb1fc753d666225f0f154d9eda147 a09031d0af7a0b9227e0f3202b887ad3a5669594dbe3d6c3d06d66e4bd58fbeb1e03ae2cce2d11781369b8490992fb2e +68d0be2883598bfb1433886aff118349157708690380c42b8919859d96db069c7fde6e117a3669f2cff94a0f1b66b27b09e3f1b24d26299e11552a084be428446f3174da2e0414655bdceb38e58fcb065b6661190862db39c6545dead34a03584632e988d0459659dc7c7c78d4d00fc2aa10465cf24b2410f14e2a62173c9962 0024661c89b77b2c743cc175a6130904461138ddc4ef771ffb9fc2c8679a a67d3cf8429c9ba37d53806d77c34f5182a9f6e9be9f6d901a7f5bcc93c276324bb7ea785312600aa2a9b9267af5ce56 +f0ba0407485fecd7337f4b22236533a926cc744a5f06dd08276750196f1bf7ea7984278f789f92dd07e36895a8bfe297ea43d4a1177c0368900e3b969d3083cbe626f0e27e7ab38e185c923dff46d9ba187b2acb9cf4b23ec8eedbb8044b96b5263d956e50cd6240c66d5d96517130c743752404ed09473f05d0004dc5971ff5 00065e20e5ce534576d7c17616cd4ede3bf4f500894850723bcc9f895f4b b4dbd953a779c3ed070aa0a9c86af6aad708b13014ebe1d114c31c182aec6f2ca94e07ccb8fba8bee0a1f56318928b65 +3827276694e413c886129c452c9a66e7d09dee84f5f09bf34e4baa308b4627e096c7d45cf6ef45ba1d9a4019a60399feec10fa80e333e2aff1251c85ca48574d9b9e1affb9666828dff5afcef3edaf5e8cae823505a0c73afe76c1bf130399fb06b092ba34ab0ae15ac6c682f9ee8479b065ce75b57213b8aae0f55e4e386de5 0014c85f66fbbd653f1e4e590cffe62c343ba6062df4b271fbd02e5d42f7 98389700e3cdc372239183bb332dd60d7acdfc2cd7a4eb979dffa6b319a8552352e295876e3ceadf23e54239ccacb8a1 +d1afb8965b48d66b9acb1ece674d9548f83395275f2d8135554cfcc7ceb96450d850dd874529433883709483d0743798db5e0dee955a4f30ba328c7934b8dd9207f3c336cf89141a175ebe23d2faed629eb4236a8aea8300604c3eb7704512f240fda66acedf1494a85058dc6a31bf9531958c332b93cfe5545046876c6b99e0 0030ac7a78593b570b29f6d3d267abb6ba7e5870ee1c8ee4f1ab2f141051 8fc81b2aebdf174dc9057a1be1904e2ff312dca6f6c4f90d37b132e6701a75f6fd1e28a467040c0e3e7bc7499a89eafa +4f95b71669fdfe5dc46d4b951b085e099de349fc740535175337127910acf24e9a0e4b2f23196ad23880da47b740d77d74fe9bcfdcc44dd7d8d1a181ac290de5cf4da22d5034cda3d8020bcc776dde8cef1786c9ce4d2c2cfb035da61406af745efb7ef1a55f2eccc5000319cf1d6380963025dcea641cfd15a3106751fec286 006d7516aa040f7d559cae248e485834e8d9bb608279ed4d4f7e1dbcd2b3 895809f905eec74aadb64979792fbe3d5bc4b3b5bce48fbac85b063d97923f737b497e414cfc9ce14e1960faed22d025 +2ad9e17780c824c4f2d1e1cbf19ab85638f2f71cb4fa3518f08085b8b358f54d4f08394a5ac29cbb3cab828c5f07f41eec51e6cd61a5f2cf44dbfa46834370cebdeb328fd3bf681e61011b5c2ebc8945ac7a2a8467606051008b15c89390e111999255bfe28634ce9bc2850a2b55a4af1c4c2f94403c78aba1ebc87386ab7b32 00137050d7b455f43a8dc2516cfff5a91062c1a2727b27df41488f3dcf18 b356cf537fabb410fb6a5095b9a7b6c59ea5ea68fb0fce845b3a8636247b96ed601e7a899a277b4a93832646208d1a02 +958773c37d3eba003aa5c489f72118b3022c52b93399e9d8001695664918b86893f4922c7b6e55b1855ed0fd1d8de5dc61af403ad660fec60d7c44bd0102c069957ed804d0d416facdc1a95355ef58554606579ef89b1842f1055cfa2ae118abbc485356824cc09dddb77d0671cb3011b33bc86cac526e3f6bb3293c7bdca1ff 0001fd447b33a2ee3595b9f885c290d241422afdd74c3dc4981955a7e9ad b5307cce9ceb3da73e3e6fea8212b70024632955b0b7a453d1982307accd2df671c89df4a4a43bb3ec478f918857bc68 +9cb2c496b1bc7f040228571e005e7e936e48e8f469e295edf914f5648701249a20bff6b98b5e862603dd9f12bb71c160aafe9df02e2e383e9b8a9a9d700f4425ce408feabbf754be543f52204c849fed6c9d3e36e03dfbd9e35c18d7bb2295f1c484a66e73440a0a5aece5fe80b9ade9321ef18cde3eb2db15e4b18e788b0441 006a061e10b4a6e7001d95411cb31bdea9c84670a59ed61b14fbbb05c8e7 97f665036c5af2303a53d662392817347bdf3aab4184e96a5462b5104a81553fb4f1af135dd17f2436c84c0e0b8274bd +9a4bc0a029e97742ed3bca207d5912cb568e4403cda106b00247520ea02008b14c041b8c9b976294252da835f4ff27456039d79d90315abcb0b9b6958a22352672e229665457ec79571ca80447c8ff2a86e6af3dabe7427c8bdcae65e3c6746a56079ce2cf8d22235180f46646a21cd9e86032cfad874cb9c67f882fb037a13f 0027ec31ca31acb4d2fbacb49fc085f1261b0042cc755cc97f9b199e7a37 849bc6f70ce9dd97682ca13a6b4868143f76ada5a84e6218f17d60c5b33275b66fe6df2f5e7c9afc3ab0b81be47d00be +8d89e22cf802dc68ff22d43c436c79311e705ff6fd845e77c880f399f403e6d5e9e2b35511553c978171189e288cb2200fd95f84ec5ee9865c0eb9190aff6dacf783ef200e82027fa992741876456472bdf27f2bd8ee55db15408c957a120eb64cd24d299818726a73fbb0697eba726a326719765735b37a2dcff0c853c906bd 004c6f4d88e5a4f4f83196f2dda9dcf2a66eaf94d50c851f59bfcea1d876 a7838e41e0e533daa32874c76e63177c8c8f3b189062de5ff8d18f4bf5bf71c534a33fa725f809d3b7a1634a542f218f +aa1bf5a79e5339fb9ef6c2817bd95725551d064bc5064d6586c5a879901adf808dc2ef7c78ec3b434b84569988db58b5e8e9782b1cbc2cc7c9b68e66f32d4ac4ebe7e75b345f654c7b8a5e650acc9f170f75b7aaa3957cce248cc69cf93faf8d72abc6fc1cfa9ae2d18a7b31ce720147e88e84f6563b2197882fe302449ac5ce 001aa169ea84365c22981bb766bfdad27e373440850569957544b0f9332a a1049d501f207f932c5d88a58e8bff593a06312c69620ca6328b09e8e9eafe556cefdc70b6131fba52a340012af657be +475664d5e22cbe0da0d0289ca9a666a37270dc71c81cffac91f6229fa39315c1d55f7e0a89b6a7a07df7d391dbdf8fb7af63d2da46ecc3b60110dbcd842da97f98d2b67f562b0364ef8e1c589519024177c8ea079794f271f6d35554c0e9d0a39062383c95721b72f4e74eaafb6fbfbda02cb670a7c4c94f67b8ebc6442e84e3 004a665b92c0c33a3f8b9eb4b0ec061d40b603de36c87096455102ffe57b 8e4ca1575e842a3a4846b8d755ac81952b2dafb999a162b96cc7c40a101c87adec97f4354b4c402d8a90b3902f8ccee4 +9e5397d94465390a82a3c07e3ebf21b515776d18b4463aa5810e6b2f96ca61e92d13e034fa853c3fa45411f51f79df6f799a2c6906e6a5b7896a4576a4464f9e0be2b529a43e1f503fb640d79db6b68f3a3a7deac1b5832fbe86673784ff6db1f8438f7dd332cdd1e7ad9df8b6731aad1b6a72bde52e6bc62d80b8da57822c48 000531540d94823e19ab2b95cbc6e7492e1effcbabce875de6ba96f53aa9 8bac7e0bb4f62f196a2c19b05e26752844a45b02be5218b296dcbc3f2d08fea66263c4ed5db28a3b108067b201016dea +3cc4c4192f317e52df6f8cefba6d4cd823c942aaee11b9a0ef5de5c2d181073b7085a55805e9554def8dc13eb978e7396044d4f4a14be2c7605998c062095c929b9c23b2b1b2fa73dd19a0c0af44ca4789f9841fa62dee8a5f91b3cc4b3264f5f67334c3f0772b30bd7431c3fbbf1f34318ce1889b6e8a76ce6d42079a451e56 0022a89addd8b85809e87e0aa2c038593ec277054842854de1197833a51c b497cdcf48e74074d15777d7c5cfb0161862a06b89e827ddcc80e1468c345805f1230f5cad0a13bd4d7467e46e6e7e78 +72cdef5bdf710978e0aa334b86b8ff4a58630da314eabe98b4d611aab56f55c526983d54d19bbbf9ddba30a84b18aa0bae9f9503e9b222f842f084db83aa39625403213ca321cc0d9c8a136c826e6ea4ec108b913dd0a9ce9d5b8c7e3af53c3876e56a2037ebd6d99f037a097111c837647bedfe4c494e4288ed6427c15969e3 001df252a11ff97b4421b3a2361db94e908e8243cd50d9179f9e03e331f1 ae7039e466a7929a1b051a49fa02ab3226bcfd14fb3cdae2be268107924176a859b6fb52e7dd88bae3d9791a01910a71 +8e4eb88c0b2d525b2c58b8e00f32def90e6dd382301de49e0ac053dbc6b61afe926d85193e2c4948f7402a3d7c614cb2c58e060362b0516a1ba4a7425f1b3d09aa20d4c3c8993a387a3248aeec51e6efa8f558dbdcfcaa13ee08413227c8351e3107e9a3e3ac124224aaea91bfe50c11c1c8ae582e718f50bc5d5c06076517d6 001d7125c299ebd0dbcc050f07de931c7ad0450af590d0a2d0228a66ac5d a096044428225bedfa8397011625af825b2659d091c7253c844bcd91124f215938520974b62c8b42608ad71f9ff6b8e1 +370fdd80f330311dbb3959666001bba61cdacf20f72f78953d946fa6cba02d24b5003f5452d535609e489b9434f192011f99f918defe877d51349870e7e75502f61145f7c261dbd2a0840926d824ebe9be3c5a77a3a84340aea930378367ed3615a47e3f792c7773f83f91ebea718a05fc62e9ed1d78629b2c27ae44fe8f8d4e 0021238e66119844b146d40e48341f522f6ac2f9c8a0b33aaf95a3099a41 a303b30aeef726af5665a6ffd8212f9725f00fa2da3b2efb0bd13af44cd27119035179d458e8359768044a5a7416fc8e +f86c4433787c3ec3cb1663389ccf53d62f9425274ccef05fd14b1b8fef676208867764eb98d16d006ee6ebdc27b8d9a8ddd303d941fdd82b630694cdc698bbe6bd524411907834286c94b24ee199fe6d646064277f244b7df3ea2d9d52a9dc6a33d7c8d6dbc919da0fa987a67621ef0829e48310e0ea2bb86fedcf4effc0b94b 0015e1bdfdacd87c42ed439f3e243abf27fd42e54f3ebdfb47f60dbae5fe aee156528ad60533c419a9cde03f7daf3d4493318440d314296d167146da4c9c1b45c46fb6c7f8eb2b96fa930a02222a +4117d593aa92e3eae1124ec7482737cd3573fe5f0f2a5051a7ce86946a2abb9e47a0c6ea75b262689b0b486476d2ab09a20efc2fb921419b1811b51a2e15891ae9e45a17ab4b96c665c6c423fc00e2d66df5804a164f0f3c958df6f25d7da6829b1fe162a0a8cf130858c83f3555d6ad627db70cb41303cc6380f7b3fed2563e 000e09410548c17bbbf28a68c3963a52d39743a4f1ac28e6dfe7a6ede281 a4572f3c81ffcbde4a47bc37af204d2ea6846a045ebfdacf2820a9291e2fb30fc599f60786c16ce5375117dc949a6922 +882ecaff3ec8f4023df5397167f238869f78a5c499be19aea85c7486e73f66f0e08e71cf85f3f1b6f6a70796bf46a18e6b555a0a87c2088640ca73051b3dd59ebfef922be0372208fce602d8001681297b285701dbbe24ccb42541b5db4aac1a1c7f407e11c83db15b38cdbc25e930fdc6558f64d9503e214571a435d890169b 0049f5bea6e72d98579b78cb07d89f64503f8759dd7a73cd73713c120428 a9528d2e6116fe6ae5d6b0b31b83247112296ac83e72de4fa18902911ec196bd916059f633eeb0400a9e1eb9fb5e5bd7 +99b3b8f876f8359bd6369ce84f9261581c52d744b90261a1427ab9e447e6d833b6b3e89af8dc770f1dd55692d01c8bbc4277a729fddfa7cbdb2ec99133201dde44ac691a77904ca816feb0a1aaacbb9fba85048bc63d73506eb908ecd697caf582747051a3a38ac8930c9a4365f407ed94ca7f2d26913c53f4c010c7ed9d7ca4 0005eaa818690d1ca4838f0bc667be5721d178c3869884260fb230277c3b b16484e02e4bdd0981cf66e6159f07e3d03c7349bbd5ca8d9488e894414bdaa5a1ce2477dccf1787eb6a50f1f06817d1 +8c1a83023930a85c5b2f9930521b8b8963d5523a3323d87f862a17d3505ccee01246ee1029b8b8c2b608772c4096d1e914cb398f027d91184a8e94e4feeae121eabb504a2a35c8bc9294edd15ddd979946c14c792ad787dc2d4deffa284830fc90b3f8c0ced6a99fc6de7c41b9ed261402a6b3d702ff86a9392731ecc37430c0 00603d89cd2f741d734587e77554fe6bbb1e5739d5ff73084d4de8ed69c4 a5784cc3b9ddcaea6e01ab28bd74b370f3f0c27a248ae40fbae2de72b8aef37d91d1efc5d8579eac41a161156325243e +f3c9dedd7115339dd3ede7d8d06a44de66bf80b4888ab7bc386cd40a92789042440a13d2cc90dbcacca5feeec1e0e3c51724146e2c4904ed6b05c7b4e9b49d7f458ada695c5d2fc36f1193329b87c1268aa38eda9151430aa0bc004e5d2a61b9390accfc699f2efabfec785eb34f52b1beff1e4c5492e922acc348667d2a3986 007977b3aba53616dac27b4d74930da23966a88ad98f1769674789c0be3d b05d4500a26d89041063adfc7ef3c148c6763bb92b85ab53da9d51be451c1ca5e537a6bdeb1f71a4ebec87f65cdeec7a +d878c4ee0bd6c84652d7f9e68df7b90cc78776d8d1b60f3e4d7465032bf401f1527ca7bfd4a3dd916e13e93fadaa5e5f20c9f47d12f8fc922a9a3aaeeeef294c221ca1adf7df85b888faec8002f17ff202da1be837827619904121167bee2d2cd694a263d9a99062cada3399dcbfcb283597a96ebec129c65e0850ec4cb4e2d7 0050cd20e7eabd29008cc977d0a17e1195d79587b8f15ac2447e15daafc0 8718e0f1d4bb26a82b5aef622c73fba779304cc317143832a1ba66a8273f0ad8e74b8d31e724b8141a260056a854fe24 +ac3c118cc9cbc8eb3b74d8ccc9ecbd81d1996fb25ca43c8a43bffeb244f722b93c9e969241d45d5b81fda0b399f1e3623687190e428dae077e54cad1eff75ec2f7fbb9434bf716833421bc2634885677579c237340f76787b2eb19b446d56c0f2206099b81493349f4db0ecad0e2dbe85dbff7d7070abb3d3b12ef0cec828af4 002dbb24fcaf9f3cd5d50d209937f0e2d134fa20ee3c9c2f1fff3dfbf302 a25187e1fe79048fb3e416dc0690b4189eadbc35a4456e005a4df901a85d5f937fee49a0170b28445bd369b5916c17cc +700313698cdfdcf0044ca07bf9e5f0702ece7cc66e35decb28d5f8cb7e7e5367a95cc1728a90cc9a53a2b5fcd4702028b742538e9b386f5d8b4a2411579ed9553021a95bd00a73f03c4184a6145aaa367e3af76659d677fe7a2e98f9ddf4aa20eb8d1a1db72c3f5590598801be7ebf44255fd7376d89d998b7068bd1296fdc38 00047142197d3d43fa46545b547968680ec81688589d1ec8d7c7e90eb969 8a844aefd55ab32ff88b54f1ea627923cef66319a1e736a513c3bde0f89edd8ab9c63737b723b9044d36aea7d36d453b +0374673e1a685bdee55504ce3cd333f70084dd4ae685464a16924eccea34531663fda60229166478b30193459a3113253cd6494dc26154156252dc6e822552c7c04d790eb9f8fcef2ea8dd79e72f881f7f20fff93cd73ad303c0918ec27c6486c4da61f82bcd55422d16650cc68bfd4b0132c1e7075bbf17dad919095860d445 0031352b49ecde5434aac05f898e6ce4337304845d748f114c14319fe97f 95e459d4f733e901e389e3275855a7ca9677ed7e905572162b9cf755974495794eebb7b760e9155d3871221f676feeb1 +8b237085f135d6e94592f8d855ca397c8c1028236a3b412adefdac888245874f586d06950ee18118f751bfe26f4c31465ec34b578caa44cf1b7109ac4f6eab7f97ff9699b34271df035d3bf58a2ed4bcbf7577cf8e5792b1945ebb9389b680baeb8518c8fdc5540e192aa4fde0eed0d7c82be2e362b286f582d65752c8db7038 00176f124c24e4420f6e726a6ca25f09dfa0c5a37e5bf879e7bdd36c3b65 883637622443162c99adfdc41e02d8743c74ae8be42ddcc769738dfd24cfcba89afa1f3a79606abb1d4228a973fd8cf8 +e3a086ec15574f7017b3cd5f5a47ab7a73980f11074333490dfe9f8ad8926f9ea7c82271aaa74e77133b1025b0b22a6900fbb71251bb6549341a23d194e79d03462cdad52ee0d1b6f5d0d14e1136026961fa3467ccf0864bf7ae3fcc3b68cb35df7324bd9bbe58fc8aa9f63c19feedf19d935b71bf5981c74fb2a487f84e453c 00755c48c3dbaf71042c58cb137f3632e3cf9d90b7b9a58fd378feef3d19 ac6f6231d519d895fce1a3ef65047a36b8a18e3daa5477d7daf2791adc1eaf03f0a5cd2bd3c2adeb6c7b15a540a5abe8 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K233_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K233_blst new file mode 100644 index 000000000000..8956680e5cdb --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K233_blst @@ -0,0 +1,60 @@ +f23f784fe136c9fc0d169503d361e9c6148b0f1fbdcae0a97fae1af7033ddef25cb7489c9963cfcb009a8cbfe44a8510a64a073eb1deae4c324ceb9302008c92c69b2dafcc9077fd3cc3c7c119edc3ced36d176ceaa55ac036bf7f07f6fa215e8bb8196e59a5e1c9af4f98b90ab4970885bd7015fa26a09e03c7cf6b4b23d929 004c1d414696cc3657dd9df73ace56eda2636769ce7082e064c260be45a5 918cdf817861e8bee5ee63f2d6894c17a76523a01e803e95ecf36b1618f2afceb8f660608271a439d5db4666dcba7f88 +400bcb297552bb37f2f8135a9314a35f5126788bb6fa4dc74152731ff64c5dab4b902103d85443dec20e16b1d6629930cdc2bd183d4099f0e96295a63c2fe266f5e9d050c401a8681b4a438efe53cbd8f2f43e2a31e9f88926a9c82917d873f6e8cd5ff5eb8c1ca36126b0bfc8c2b0e85a7c9e7a45f1875ca9c82019ebedb729 0027cb1d84865a16992476c9e353283d5d6a40c349a8e9179d1b1f403531 ab5e8bfb5230b02721eaf9caf85b95880cfadead09a3217759f60bffd15767d85a17393a83ee7fd2969fcce0d96c696f +5f74d4b35c49fa454c97c05fdb6b9f6822cf1a2295f15bd766dbcb413d77c910bd8f4147e8f317fac2300fa21cb80134d1b6f8ae8e50518c1f648a28506e419f5a6e8f05abffdb3dd2587606c7e9c223ecff4f46b121216730ea13202b59128a7616bb2fd23a7e4a5aa08641cc07b669641313febfc88d64d99447353dae3f06 0031b443f46c4b5224237fac1022ee1570173f664aba0c84dbaa4246bdc1 aca837d12c5c37753cf2be54e22cc486b8178424b11d92d00dca06d2f9e797ce4c4f60b5ff5bb2197d5ae4377d8525ca +8f92096876d9f81bcd992369d42d0b5877ac969004d17c8627c58d8b8b7bbf7a37e8cb6afa962b9b043bbbaa5bef4a5ee38d8bd31cb5866b828265a2f4102a616f87009cd346fcb8af5519fb577c60d8792472232f33dc615655e53d2b715b15a2697b492f108b7906e1e3597c6911f8cc30c7121ae338a6b747ec368f8e4a36 0048f6ca29f35f253a4962734357c995920967b9eeff1ba5fd2080bfede5 a46f7483a8312e7a184d787cf2e13907f107c8e583d28ac970908ecd4133caae25df137963563c4424e547df52cf75ec +3d275dbde44494c45fc15fe89e2ae32aa26426a17e923e895c7941a5582fb95df4d49873ab1bde358017f336b911b886b626b744806ab8113418473c441f1964159ded1b12122d53ac56573167588e4b55f36b8bca8c67823883a51fb6e7f204d1c6b07ea49b577bfab9ca6b8d51f72268b022e3a4db6f9d265ee8382f9b7b66 0019b940eabbe682f961d9f3d90432e347fef3910e641656825d775705b1 95010440ef31dc0499ae4826f5d377a31025d79c0cf135912f33c38d596a824b420f9ec188361cf3985325fd887a5d88 +d2fa68e1f7dad02916b12fa38f1849d6d409dbad0344438520b4dd9b77d62d39ac9ae3cdeab03ccbcfd4de703c6e798873671731c108f322b9f2a68145e3e210c9b15b879798e5c53c5022742e9819b99edabb2f44d89ae221f7a99dc84421a6905695ff91928db608f861745f17584d56e34b75c47281435b1b0b34e490692d 007a884b22e29fa9fe945e9ba13c0df8d786dc87cef0f77f069e182dd56c 82f6b163c286cd931704c1042eca1a94213f74d500ac8c24e175878eee786f7443d11fde96077cca3ecafbb908d7f696 +3830f75cf9df4eb2998c7c1b5fe11c1476bcf849c3a8fa7d3d0b5bc2292e5d07465ab8cc9381c575d909e509c5dac49c78817c04e4bef18bd51bb09aa5897f21634633a5ce6d20bb4638cb6c3927351eaec7b62cf4a33956916045c392f325adafb10a88a5f86d7e41dd77908fa7284210071c22aa40ef40da6339c02da05392 005da61f881d5a0dc085bb93764f584352882923cd237d878220ec624c1a b039a2a2feec0a86eb7ae39bf7372f5d2caff4753704d9c77be191e97b9dbf4e3ce9aaa8aafa6620732d32c3ab6c4496 +65b9fe15e6c35d453caa6bad39ee78a720a04b60d8a0a0f049186d2f777e48ae2d657e174df53edb7beb9f7d8f21904ed674add0cda5b62a7308de76c324a144021e8c6d387daaba4ce48bf7dfe9c8aeee2c64e434ece1fa5ddcafcf3e5d0013a1eeec1742a00d384cc2ec0d7eda83bb4dccfb0e57045ebfc27a4f404d03da37 003fe9f04647f6d82b13ec1ae5a8c2e49bc66b05649ad778eb16149ad83a 8c5a9b1957ef64bf6533e942d1f30c0f521dfa3a8b148627ce00ac50ae9a696a16b7721a0e1009f7165fc9d041a91431 +d26521fd41eb5d46ece6836e188bf9cb1b461d011c41e002a935d256654d01725378e845920ec4a7fd3f379df54772493df50d312c7c6aa4e909e7b83f2442c3a5e85c37d68aa015098ecfb0a5e077370f4576f4bc63bf37e1dee06d780a3b6949af5e21c2a0960fcd20821ef5f17bebf5fd5b3bdda260842cbbfad45667287a 005ebce648ace4cd555413de6a456fc487d14bf4b0b9a72311ef480d2f26 88365c483f072a10c0af5030293129165d35de4a74da448250f516263b568f6de95d2c4e569d7c6ff6025c0e898530ca +b778c021b1a92c41dbd09963da07018075d73e54d62df5c2b7bf8abe137151650d1c1c6abce7eebd8f32e8c3e6d1433773f257bb3ba4a4fb6a02c0db1e47d03c27d3a90898ebd1927c21df24c4c5443ca5b81f8ef2cc0f5e8b3d08f472bf07085df737adaedec63d99acd77b87ba98225f198b791124ac2d9b191cb9251b4b00 0056653c2f85593f789a926ba49fa3da9d7f946d8f1020508c5a527ce813 8010774508dac706e2bdb643cfeeae66f2612bc590929a11799fbfc7715013e5fdb74ffd0ced00e15f7471f07a62b37f +ec14e07f615960015a489ef999e308b42a4c571473b9bd64b433dabd9a1b1ad02e33eee9100064405175928a94543a80f440040afa2965b4e5f95f768e7fab6d3c0a5f5e1bf1df7822f78384e80f2955ea85f044ac60537d895747979f935bb0cd3673193c4a32dd7803e48d7daf70a71bc2aa97236615b6411e28fc9a652145 0049a91d320783cc70a5952c32036cfc75d41f1aa84127db2dc759fb291c a0e3454ff3dbc79c5b1f3e20827864b45ff4d175c892b5194ec471eb347011e727859a95f5913daefd4161083ad61f3b +89c645339ad0eb850e4e2fe583cee175b35feb02ed7541d7e9aace24cdd3939584f73ad39526de6399c86b36de77a018e2c70b532bd0f032f9137d10480acc30c49f9baaa86f9df0033b77e98b485bf7a69cb5c281e527d3ccd1fce2415f0dda4a268ce68a0a34b16afda54ed922cd6810ac8dc766df2a3a6c5e55972e9786fc 0016a20016602fc7088a60469843e1d29ad67e3c3cb9500b1e2a00d4050a 88aa91eaa52270762388d657a384f73241b5360a6781c9791f35736f58dc3c1b9749b0b68efdf89aa81ca2198b08596d +ace14c4b101d2d8453c2bc22b756af016b5de537df9c3e639d208ad04ae0bf6232dc90b90c33228dc85de956db771ffde05fb4d0b15e4f218ed2771d703ae5bf981252a5bcd60c16f14483131a481cbe04dc0adb1fb8aa32cb48bb5008e8a8e5c7b7465be2fd7afbc811cf5ea6293b1a464669b49f55f57b93a8707e6042fda6 000ba922149bada2551b7be1c3df076f3f97ce93c13c50c285fef3f42363 a8bb0cf00975c822c4f592186726733953c8a16333dc8bf12e2ad21c954999fe8683d6041e90e3b3c64b315d7de44ad7 +cec2ba0d1772c87e87d5bbbd67220692bea4301aa1a66e8dbdd7e651d45c26dc2a0d45cfc32c34d76ae3e1c61db7b0fe1863457b93937d929e6ece7462ebd16adfd708353d6f7c27aafe06593c76da7149b0cc574a4290b0d8fe219f3eada7082aca38dba3f78ed0d5942d095fa5556fc8bcef331ff0a6d5d1f4e6c51d4ff5af 002d635e12a58cc6dea44e71e87c37f91e8d08659f0b7955d24f65ab55ba b66a9970abdd31900d62647faf4fc9d4e8af4e02c8c6a603b9d049da21bc62b59a91cc0a682504574ab23151e611c869 +ffa13cd0f51ae2643d5d4edecb493ddd653e9faddcffc370e7e958abf726a5d67a2ab36cef42ea8ebe22a6f01b9c31f6ffad01e6894487d979acb5e618f765ac0ec3550ac5dbbcede8f9fdbe52fbaba5c087ff382b6d7a09b2b5084227d324d98ff98793040884799b96d2ca593201f4414f18c43b51c53c5e5059e0641aca02 00073883e5064e06814fc4de32e15f7a6cf825d2daf6eb1df8c83e25d80a ae947a170811a4230dada6374c63c3800f10bde8d36b4a79abae7b0c74f7cef9c5870e29f43055f7e7a7ee77a009f4da +c73e3dbac9513d0361dabe94071faf03a11cba18c06d131a172d5f0125b01a5eeb6055bf72c7106fe3f4be3bd2b1771cbe7f85366dccfbc3bac20538510c3f51179cc540ddafb2f3b05a0d276899674ab1d7d8fb4f6838f04e4f9e26b8c6af31540f63f4953c85840af4c57dfa78c704f637dfc8dd750fe45e2c1e149986d127 001532271bfae8d4dfe60f69b88d3006d58e28aacfa701861cde8d624db6 b011abd29930c2d367a55cab7021f8b08092fc790a61503a6e0c255c95b3bed10f3cb8fb75a8beab9a7a0a46de94c61d +d00dcd0f3212a3167403abed91c20e76f5e7a7678a4fd970f944d11e6a8cd149d0aa6fd3164c5a74c0f55193a4fa3d8ba6f99cabed10544625a7bd92b3e0b46edbd4a269bbc10518c5268c3910a2aea567ccd32d4c7a0cbef09ea42c20b636d1f711d220e23dacdb9d1146e0494401349749e5ed88e38295232a7effbae3aed6 00550406c0db882c6aee6cf3b6baf377375208c3e90cc44a067cee43efcf 97b994a280f00e40419f5d0495436ad67258b0756fe69ffebc3f49a71feb410b418005bbc2e16954a7b22e629ccc9dd8 +3d36221f87157ca4db84884b8666660c4e2b6af330480c516cded9f3bfe132543626a39bb6aed1964eb5c33ea0b95b9841665417679fceb95d199d55accfce35dd3f2283c1a7ced57d0c4b9ebe3da6e1ff2f979b6440db27caf9f6a4bbfa47e20d29ae304f4d0551fce9cc4097eb2fbedb9b24680bb17d207bdccdbe799d5b0d 00257dc63752920b6854d6c2d1cca68589a38418c3d036e73760a12214ab a5609da6a18ab945680895cfb1a601a81dccb927a44118bf2a535ad6f42fc8107ca37c01a5f357e526c07180552f5c88 +033d82a42d0eddf58fbe3e91ddff7190e3f9fc2b1e2eede977d2c0473b358b5fce1f981ca6f88fd61ce2f79e453e3a2b77d1baab2b970ed28d5dcff58873a620e195085e61c4b8480d829525a1a944e8a4b63352f0291f0311f1f98ceb262804beec1c74947618f8e3b067866255878c2502966cefcdda4f5fa2b13d92ce7840 0029025352297a7be850f8852411c09259b83219135e0e8949c1bd5b94c1 b56308f3d3aaf47e9ff54e8ea521dc4f1a7a88c6d88d93656cfc86a2d02efff049abe26bd6d558ef6f8f8e8661d74596 +671a7c81b64b2919722d7b258bdbd90165bb757b53106e0af03d0eef27452942f40cf52bc95cc7f6567df2613cce795f8bcfc723b2735efc35375c001d37c58480d89343697146b524835df3dbd333f7c06c98e36d3c4592ecd1f34ab57c341bb0f4c785f5b8372775f74b4bce60763fad1788e77ea158d735a64861320b36c6 002dc82d0e69e498528925c0e62a13fda9af8cefd047c10c3ffc2e41da3e a05e0757d9cbcc3c2049af83c5af5c94dfbabf56802d70ec46aa7688186eb97deff15648d6a8ceac16b8c3c55d1d860e +0ef677f4799298f4aab73b7393598041f56e902ced1726af49657b6601a06186212e3ee8cd4bd33b760dfa2ea3c38884f94358d51dd479f2ccc8b0b352fa4e44fcfdcfbb24919d04e6ee1108527b8e8d60e8d1b467c30c18c5455e5835d483161d3fc26b4a67d6df9e3ddd9331247cb18450188752a1ca219f3396a872cb13d8 0041535fff5d279bcd744b04e643458ce20b81df8a9e01b1181d52bb14e4 86d2ad7f2c88f19fa4457bf072fdd9f295e81dba683ae222e0dce0be7d20e5b7849b1cdeaad44a5a6026330e7dc12c1b +9290df0cc50c3cab6655f3a6de1f4cf613d9bc06ea7c99f38038369ff2fadefa57a3c7ae7940c1b98bb1d03503cc271f7a891bf38eec93c31dcec7892dfd2e1ab337bedde3e5325ed8d9cb7fa3096f6fafc3beb3a66cba66ba826d1032debfb4908cc9dded8c0099c85072daac4373fbc428fcaa9a6da02181ebc33f0cf926fb 0000ecfe580a624df66c25e87e7689fc3b471d205970ff9ab51a64aa12ed a0e7b3f266f115e69b98bdbee48e92972f1eec0948371b29cebbd10c9e1c34cfc2e3849b18422ade6e3c696d7025b949 +855c7be75fda372f062709827f333630acf28954a62a5193ff675f0dfeb63f32bca418f7cbdb346bf388d62315b19a592267ca407120db93d4e3d7125b867c4c4670b7a57a76f61734cead2caf2425eb9ff0a63293e8cd6defc9648257b401463f4533a2425e0024f1ea93365eeee3c6da20d25928602ec8b426f9b39f97f3fe 0013c72c73358ffa168423149ecdd897f0a5f75a641de008649f00134944 a3ec20ac9eb9ec56497af86c9abcf5a5368b74746ac583d8254d8733669a3d265a9384afe7c9d2106bed3edfcc451716 +9c896f800281812ed57d31623d563377a5c725cec84313472b90e73f77d400f5d4fb236255741b73d46f7e5254d04099bec274db8a9af5fc7cc220d42cc172cbd3c3595c49ff74bfaab7b5e46c90855b611f74753ccdbbabf92e011d52e9ba753b83ed2a251a632e1bd5c6d346e38e743950c8ce0f394a837028575fa44bcc26 000ac60e2e70b7c4cda64071c7738f68773c94df9456a8ec3bbb468fa7f8 b14cf1f155db08cacad5be9f82f6068752c0ca45837defce9471b3e5185a6fe8a066e2b43a9af34e55a4f88133b25809 +139a14ead998d1a962fa47c47ef2953aa136bd912fe940709b8c560bc2a0c4bf8f3aab30a8e21b7d5f487d30b0097e3da723f11b5cb4e8c5724f5a2fe0d68ee4bacbb85e5eacf18094d2a8ec4506cf8497836a4a905059a998ea750adc54c27c69cbd0b0c1f9743a62f3d988f3fa0a9865a73fc071f526623085a2ef12838888 0060bf720052e8b9508a801340c213cf53bbecf4975faee63d4b44fc647a a457fad8bddc5088e30c381e6264339fedd5bafdf57643866d9798cb76ca236c10e510a449f0e09943e72ac763350fd9 +cf4a8e754b23d0fffc1c5c80b0cb11deeaba3064b315bc2cee96db5b9881baf90d30af4b69066f757b3020706def77a5fc1632d96bafba22a9c8cd3b52d535d941b3c7cc02b7fe6b51639d5e2084478ab3a29d2f5e0e16639fc2833a47b58e2c3fb5b2ea1830fe2ff68e571a8f281617a23d9a28db1c64ddfb1083d055030e5a 007cf3c216592febd8630a478b5b3e3a605084020322adb13ac0a626bc7b a8f59c32d4b54b42636b3f595a740b78ffb15480bb65a509273fdf6abc377138fb8501d61f0995edad7b13b86c14496c +ae64030d4af9b36c8d3a6af0aff34e5ab201df04274691fb420b7d5c40c401ed7f3ade96065d34f2490d17943e27156e7bed83cd7222d0d5a73d167855fbe7ff6c3ed87f20986ad8bbbd80fed5f9705c6c783b423f641d40ff1f367f9648af5a79ea3cea0236997558bd9dcb011ea4dc64d61ea1e1f85b4f696ed586bc7705be 0061eda5999e5a9ed4485d2a0ac5510549b76ca37df858ea5d95aeed571b b09a3a09d6eb58b8670101cbbbb1bb974f83f0bf79e645de07c68d518cd60b070827cfaf507f413a863fca13031d9cee +94a9d9cd9efa3e4ccf2a37f904dd9cab5624ec9393cf8816ea591c5e70cccd2f105388ae133708fb974998ae61d218c71785f9eb808d1c28d953cc7eed00dd9854b6b4568c5ed5ee3df3b58a1e04c64f1c87fee4365ec9aa41b08a6bae234dc43a0bf2f61420acdb891a40f17f246972afee75a4c0b249dee0fc8f9b9c8a243d 007e7e73171e4d2f2989dc024757c186485435b82544a448f5cfca05f281 a54d7fbe89a33a8f7e2c45b208a5ccaa14b1665f6b6082a7ec1c55355f5cb34e89177f04e4682d0db4d3200333bfdc0f +4db998df7b90678b8aa4ec6233c9b4629800ad1f3e2cf8f7afcac62fc6982dcb290e44587015eca8dfe77dbb4a80f9bffe75b11e961e70deed14555db6dae47d49e73004f000eb8677c18f7e8234bf0a5a104266167a05ef07152e7acc2f0368b37efe69c0c2feb51eedf7338cf9ed398f066cf1f66bacd89ab9376d41da35a2 005f7270764a0444c7159d2db867930fdb0fb9fa6b8fc80ca02e11753095 95792ef4bd9e22cb7d89accb92115ec4173e46162d4989f60fa6f693e601177795d7d845f8a3d430dfa2b14fd8c7f0a0 +dbf9b8a4ae316bd2df0c80db1cb5d7038364a2634925ff957d7c03511b57d486274b2ecf191746827c325a14dc94daacd66ad86d369e3f598f176c4f0eadec7e9edd13e34043efbe0a801b75b8186b4a6d89ceae4fb250ab570d65b6dd7c04382738fe3f6f6c867a7d84b35b20720cb0036a5d81a87126f236833831d9ff00b1 00179b924afa4acf30ecbe2b3c12de533a1f9675687876a7e5e5ddc8e03b 80d52c06e8b98822f57b2461b5e0df2c0334c76fa56b1eaf2a1ae482aa3ac2ee20b434ed348d851a7cac5952cf95f89f +986d9e5d636526f4deb7545c037fe81b09c74496ddb8e42e61650c74b6fe348593f0cf8f8eca5e839baf62f17bf6ad96ec0c71dc44fdf11259dbfe7499157e402f6bd5076972354150723afb632799a990c44cd0a4fa9609ec4db133e3b4700be3ea4a338e8ba1873d345e80163ed60d0de274d7617a8382980bc2138b0a2a01 002c9eb4d392d7f2eef606e1861183acb1fc753d666225f0f154d9eda147 a09031d0af7a0b9227e0f3202b887ad3a5669594dbe3d6c3d06d66e4bd58fbeb1e03ae2cce2d11781369b8490992fb2e +68d0be2883598bfb1433886aff118349157708690380c42b8919859d96db069c7fde6e117a3669f2cff94a0f1b66b27b09e3f1b24d26299e11552a084be428446f3174da2e0414655bdceb38e58fcb065b6661190862db39c6545dead34a03584632e988d0459659dc7c7c78d4d00fc2aa10465cf24b2410f14e2a62173c9962 0024661c89b77b2c743cc175a6130904461138ddc4ef771ffb9fc2c8679a a67d3cf8429c9ba37d53806d77c34f5182a9f6e9be9f6d901a7f5bcc93c276324bb7ea785312600aa2a9b9267af5ce56 +f0ba0407485fecd7337f4b22236533a926cc744a5f06dd08276750196f1bf7ea7984278f789f92dd07e36895a8bfe297ea43d4a1177c0368900e3b969d3083cbe626f0e27e7ab38e185c923dff46d9ba187b2acb9cf4b23ec8eedbb8044b96b5263d956e50cd6240c66d5d96517130c743752404ed09473f05d0004dc5971ff5 00065e20e5ce534576d7c17616cd4ede3bf4f500894850723bcc9f895f4b b4dbd953a779c3ed070aa0a9c86af6aad708b13014ebe1d114c31c182aec6f2ca94e07ccb8fba8bee0a1f56318928b65 +3827276694e413c886129c452c9a66e7d09dee84f5f09bf34e4baa308b4627e096c7d45cf6ef45ba1d9a4019a60399feec10fa80e333e2aff1251c85ca48574d9b9e1affb9666828dff5afcef3edaf5e8cae823505a0c73afe76c1bf130399fb06b092ba34ab0ae15ac6c682f9ee8479b065ce75b57213b8aae0f55e4e386de5 0014c85f66fbbd653f1e4e590cffe62c343ba6062df4b271fbd02e5d42f7 98389700e3cdc372239183bb332dd60d7acdfc2cd7a4eb979dffa6b319a8552352e295876e3ceadf23e54239ccacb8a1 +d1afb8965b48d66b9acb1ece674d9548f83395275f2d8135554cfcc7ceb96450d850dd874529433883709483d0743798db5e0dee955a4f30ba328c7934b8dd9207f3c336cf89141a175ebe23d2faed629eb4236a8aea8300604c3eb7704512f240fda66acedf1494a85058dc6a31bf9531958c332b93cfe5545046876c6b99e0 0030ac7a78593b570b29f6d3d267abb6ba7e5870ee1c8ee4f1ab2f141051 8fc81b2aebdf174dc9057a1be1904e2ff312dca6f6c4f90d37b132e6701a75f6fd1e28a467040c0e3e7bc7499a89eafa +4f95b71669fdfe5dc46d4b951b085e099de349fc740535175337127910acf24e9a0e4b2f23196ad23880da47b740d77d74fe9bcfdcc44dd7d8d1a181ac290de5cf4da22d5034cda3d8020bcc776dde8cef1786c9ce4d2c2cfb035da61406af745efb7ef1a55f2eccc5000319cf1d6380963025dcea641cfd15a3106751fec286 006d7516aa040f7d559cae248e485834e8d9bb608279ed4d4f7e1dbcd2b3 895809f905eec74aadb64979792fbe3d5bc4b3b5bce48fbac85b063d97923f737b497e414cfc9ce14e1960faed22d025 +2ad9e17780c824c4f2d1e1cbf19ab85638f2f71cb4fa3518f08085b8b358f54d4f08394a5ac29cbb3cab828c5f07f41eec51e6cd61a5f2cf44dbfa46834370cebdeb328fd3bf681e61011b5c2ebc8945ac7a2a8467606051008b15c89390e111999255bfe28634ce9bc2850a2b55a4af1c4c2f94403c78aba1ebc87386ab7b32 00137050d7b455f43a8dc2516cfff5a91062c1a2727b27df41488f3dcf18 b356cf537fabb410fb6a5095b9a7b6c59ea5ea68fb0fce845b3a8636247b96ed601e7a899a277b4a93832646208d1a02 +958773c37d3eba003aa5c489f72118b3022c52b93399e9d8001695664918b86893f4922c7b6e55b1855ed0fd1d8de5dc61af403ad660fec60d7c44bd0102c069957ed804d0d416facdc1a95355ef58554606579ef89b1842f1055cfa2ae118abbc485356824cc09dddb77d0671cb3011b33bc86cac526e3f6bb3293c7bdca1ff 0001fd447b33a2ee3595b9f885c290d241422afdd74c3dc4981955a7e9ad b5307cce9ceb3da73e3e6fea8212b70024632955b0b7a453d1982307accd2df671c89df4a4a43bb3ec478f918857bc68 +9cb2c496b1bc7f040228571e005e7e936e48e8f469e295edf914f5648701249a20bff6b98b5e862603dd9f12bb71c160aafe9df02e2e383e9b8a9a9d700f4425ce408feabbf754be543f52204c849fed6c9d3e36e03dfbd9e35c18d7bb2295f1c484a66e73440a0a5aece5fe80b9ade9321ef18cde3eb2db15e4b18e788b0441 006a061e10b4a6e7001d95411cb31bdea9c84670a59ed61b14fbbb05c8e7 97f665036c5af2303a53d662392817347bdf3aab4184e96a5462b5104a81553fb4f1af135dd17f2436c84c0e0b8274bd +9a4bc0a029e97742ed3bca207d5912cb568e4403cda106b00247520ea02008b14c041b8c9b976294252da835f4ff27456039d79d90315abcb0b9b6958a22352672e229665457ec79571ca80447c8ff2a86e6af3dabe7427c8bdcae65e3c6746a56079ce2cf8d22235180f46646a21cd9e86032cfad874cb9c67f882fb037a13f 0027ec31ca31acb4d2fbacb49fc085f1261b0042cc755cc97f9b199e7a37 849bc6f70ce9dd97682ca13a6b4868143f76ada5a84e6218f17d60c5b33275b66fe6df2f5e7c9afc3ab0b81be47d00be +8d89e22cf802dc68ff22d43c436c79311e705ff6fd845e77c880f399f403e6d5e9e2b35511553c978171189e288cb2200fd95f84ec5ee9865c0eb9190aff6dacf783ef200e82027fa992741876456472bdf27f2bd8ee55db15408c957a120eb64cd24d299818726a73fbb0697eba726a326719765735b37a2dcff0c853c906bd 004c6f4d88e5a4f4f83196f2dda9dcf2a66eaf94d50c851f59bfcea1d876 a7838e41e0e533daa32874c76e63177c8c8f3b189062de5ff8d18f4bf5bf71c534a33fa725f809d3b7a1634a542f218f +aa1bf5a79e5339fb9ef6c2817bd95725551d064bc5064d6586c5a879901adf808dc2ef7c78ec3b434b84569988db58b5e8e9782b1cbc2cc7c9b68e66f32d4ac4ebe7e75b345f654c7b8a5e650acc9f170f75b7aaa3957cce248cc69cf93faf8d72abc6fc1cfa9ae2d18a7b31ce720147e88e84f6563b2197882fe302449ac5ce 001aa169ea84365c22981bb766bfdad27e373440850569957544b0f9332a a1049d501f207f932c5d88a58e8bff593a06312c69620ca6328b09e8e9eafe556cefdc70b6131fba52a340012af657be +475664d5e22cbe0da0d0289ca9a666a37270dc71c81cffac91f6229fa39315c1d55f7e0a89b6a7a07df7d391dbdf8fb7af63d2da46ecc3b60110dbcd842da97f98d2b67f562b0364ef8e1c589519024177c8ea079794f271f6d35554c0e9d0a39062383c95721b72f4e74eaafb6fbfbda02cb670a7c4c94f67b8ebc6442e84e3 004a665b92c0c33a3f8b9eb4b0ec061d40b603de36c87096455102ffe57b 8e4ca1575e842a3a4846b8d755ac81952b2dafb999a162b96cc7c40a101c87adec97f4354b4c402d8a90b3902f8ccee4 +9e5397d94465390a82a3c07e3ebf21b515776d18b4463aa5810e6b2f96ca61e92d13e034fa853c3fa45411f51f79df6f799a2c6906e6a5b7896a4576a4464f9e0be2b529a43e1f503fb640d79db6b68f3a3a7deac1b5832fbe86673784ff6db1f8438f7dd332cdd1e7ad9df8b6731aad1b6a72bde52e6bc62d80b8da57822c48 000531540d94823e19ab2b95cbc6e7492e1effcbabce875de6ba96f53aa9 8bac7e0bb4f62f196a2c19b05e26752844a45b02be5218b296dcbc3f2d08fea66263c4ed5db28a3b108067b201016dea +3cc4c4192f317e52df6f8cefba6d4cd823c942aaee11b9a0ef5de5c2d181073b7085a55805e9554def8dc13eb978e7396044d4f4a14be2c7605998c062095c929b9c23b2b1b2fa73dd19a0c0af44ca4789f9841fa62dee8a5f91b3cc4b3264f5f67334c3f0772b30bd7431c3fbbf1f34318ce1889b6e8a76ce6d42079a451e56 0022a89addd8b85809e87e0aa2c038593ec277054842854de1197833a51c b497cdcf48e74074d15777d7c5cfb0161862a06b89e827ddcc80e1468c345805f1230f5cad0a13bd4d7467e46e6e7e78 +72cdef5bdf710978e0aa334b86b8ff4a58630da314eabe98b4d611aab56f55c526983d54d19bbbf9ddba30a84b18aa0bae9f9503e9b222f842f084db83aa39625403213ca321cc0d9c8a136c826e6ea4ec108b913dd0a9ce9d5b8c7e3af53c3876e56a2037ebd6d99f037a097111c837647bedfe4c494e4288ed6427c15969e3 001df252a11ff97b4421b3a2361db94e908e8243cd50d9179f9e03e331f1 ae7039e466a7929a1b051a49fa02ab3226bcfd14fb3cdae2be268107924176a859b6fb52e7dd88bae3d9791a01910a71 +8e4eb88c0b2d525b2c58b8e00f32def90e6dd382301de49e0ac053dbc6b61afe926d85193e2c4948f7402a3d7c614cb2c58e060362b0516a1ba4a7425f1b3d09aa20d4c3c8993a387a3248aeec51e6efa8f558dbdcfcaa13ee08413227c8351e3107e9a3e3ac124224aaea91bfe50c11c1c8ae582e718f50bc5d5c06076517d6 001d7125c299ebd0dbcc050f07de931c7ad0450af590d0a2d0228a66ac5d a096044428225bedfa8397011625af825b2659d091c7253c844bcd91124f215938520974b62c8b42608ad71f9ff6b8e1 +370fdd80f330311dbb3959666001bba61cdacf20f72f78953d946fa6cba02d24b5003f5452d535609e489b9434f192011f99f918defe877d51349870e7e75502f61145f7c261dbd2a0840926d824ebe9be3c5a77a3a84340aea930378367ed3615a47e3f792c7773f83f91ebea718a05fc62e9ed1d78629b2c27ae44fe8f8d4e 0021238e66119844b146d40e48341f522f6ac2f9c8a0b33aaf95a3099a41 a303b30aeef726af5665a6ffd8212f9725f00fa2da3b2efb0bd13af44cd27119035179d458e8359768044a5a7416fc8e +f86c4433787c3ec3cb1663389ccf53d62f9425274ccef05fd14b1b8fef676208867764eb98d16d006ee6ebdc27b8d9a8ddd303d941fdd82b630694cdc698bbe6bd524411907834286c94b24ee199fe6d646064277f244b7df3ea2d9d52a9dc6a33d7c8d6dbc919da0fa987a67621ef0829e48310e0ea2bb86fedcf4effc0b94b 0015e1bdfdacd87c42ed439f3e243abf27fd42e54f3ebdfb47f60dbae5fe aee156528ad60533c419a9cde03f7daf3d4493318440d314296d167146da4c9c1b45c46fb6c7f8eb2b96fa930a02222a +4117d593aa92e3eae1124ec7482737cd3573fe5f0f2a5051a7ce86946a2abb9e47a0c6ea75b262689b0b486476d2ab09a20efc2fb921419b1811b51a2e15891ae9e45a17ab4b96c665c6c423fc00e2d66df5804a164f0f3c958df6f25d7da6829b1fe162a0a8cf130858c83f3555d6ad627db70cb41303cc6380f7b3fed2563e 000e09410548c17bbbf28a68c3963a52d39743a4f1ac28e6dfe7a6ede281 a4572f3c81ffcbde4a47bc37af204d2ea6846a045ebfdacf2820a9291e2fb30fc599f60786c16ce5375117dc949a6922 +882ecaff3ec8f4023df5397167f238869f78a5c499be19aea85c7486e73f66f0e08e71cf85f3f1b6f6a70796bf46a18e6b555a0a87c2088640ca73051b3dd59ebfef922be0372208fce602d8001681297b285701dbbe24ccb42541b5db4aac1a1c7f407e11c83db15b38cdbc25e930fdc6558f64d9503e214571a435d890169b 0049f5bea6e72d98579b78cb07d89f64503f8759dd7a73cd73713c120428 a9528d2e6116fe6ae5d6b0b31b83247112296ac83e72de4fa18902911ec196bd916059f633eeb0400a9e1eb9fb5e5bd7 +99b3b8f876f8359bd6369ce84f9261581c52d744b90261a1427ab9e447e6d833b6b3e89af8dc770f1dd55692d01c8bbc4277a729fddfa7cbdb2ec99133201dde44ac691a77904ca816feb0a1aaacbb9fba85048bc63d73506eb908ecd697caf582747051a3a38ac8930c9a4365f407ed94ca7f2d26913c53f4c010c7ed9d7ca4 0005eaa818690d1ca4838f0bc667be5721d178c3869884260fb230277c3b b16484e02e4bdd0981cf66e6159f07e3d03c7349bbd5ca8d9488e894414bdaa5a1ce2477dccf1787eb6a50f1f06817d1 +8c1a83023930a85c5b2f9930521b8b8963d5523a3323d87f862a17d3505ccee01246ee1029b8b8c2b608772c4096d1e914cb398f027d91184a8e94e4feeae121eabb504a2a35c8bc9294edd15ddd979946c14c792ad787dc2d4deffa284830fc90b3f8c0ced6a99fc6de7c41b9ed261402a6b3d702ff86a9392731ecc37430c0 00603d89cd2f741d734587e77554fe6bbb1e5739d5ff73084d4de8ed69c4 a5784cc3b9ddcaea6e01ab28bd74b370f3f0c27a248ae40fbae2de72b8aef37d91d1efc5d8579eac41a161156325243e +f3c9dedd7115339dd3ede7d8d06a44de66bf80b4888ab7bc386cd40a92789042440a13d2cc90dbcacca5feeec1e0e3c51724146e2c4904ed6b05c7b4e9b49d7f458ada695c5d2fc36f1193329b87c1268aa38eda9151430aa0bc004e5d2a61b9390accfc699f2efabfec785eb34f52b1beff1e4c5492e922acc348667d2a3986 007977b3aba53616dac27b4d74930da23966a88ad98f1769674789c0be3d b05d4500a26d89041063adfc7ef3c148c6763bb92b85ab53da9d51be451c1ca5e537a6bdeb1f71a4ebec87f65cdeec7a +d878c4ee0bd6c84652d7f9e68df7b90cc78776d8d1b60f3e4d7465032bf401f1527ca7bfd4a3dd916e13e93fadaa5e5f20c9f47d12f8fc922a9a3aaeeeef294c221ca1adf7df85b888faec8002f17ff202da1be837827619904121167bee2d2cd694a263d9a99062cada3399dcbfcb283597a96ebec129c65e0850ec4cb4e2d7 0050cd20e7eabd29008cc977d0a17e1195d79587b8f15ac2447e15daafc0 8718e0f1d4bb26a82b5aef622c73fba779304cc317143832a1ba66a8273f0ad8e74b8d31e724b8141a260056a854fe24 +ac3c118cc9cbc8eb3b74d8ccc9ecbd81d1996fb25ca43c8a43bffeb244f722b93c9e969241d45d5b81fda0b399f1e3623687190e428dae077e54cad1eff75ec2f7fbb9434bf716833421bc2634885677579c237340f76787b2eb19b446d56c0f2206099b81493349f4db0ecad0e2dbe85dbff7d7070abb3d3b12ef0cec828af4 002dbb24fcaf9f3cd5d50d209937f0e2d134fa20ee3c9c2f1fff3dfbf302 a25187e1fe79048fb3e416dc0690b4189eadbc35a4456e005a4df901a85d5f937fee49a0170b28445bd369b5916c17cc +700313698cdfdcf0044ca07bf9e5f0702ece7cc66e35decb28d5f8cb7e7e5367a95cc1728a90cc9a53a2b5fcd4702028b742538e9b386f5d8b4a2411579ed9553021a95bd00a73f03c4184a6145aaa367e3af76659d677fe7a2e98f9ddf4aa20eb8d1a1db72c3f5590598801be7ebf44255fd7376d89d998b7068bd1296fdc38 00047142197d3d43fa46545b547968680ec81688589d1ec8d7c7e90eb969 8a844aefd55ab32ff88b54f1ea627923cef66319a1e736a513c3bde0f89edd8ab9c63737b723b9044d36aea7d36d453b +0374673e1a685bdee55504ce3cd333f70084dd4ae685464a16924eccea34531663fda60229166478b30193459a3113253cd6494dc26154156252dc6e822552c7c04d790eb9f8fcef2ea8dd79e72f881f7f20fff93cd73ad303c0918ec27c6486c4da61f82bcd55422d16650cc68bfd4b0132c1e7075bbf17dad919095860d445 0031352b49ecde5434aac05f898e6ce4337304845d748f114c14319fe97f 95e459d4f733e901e389e3275855a7ca9677ed7e905572162b9cf755974495794eebb7b760e9155d3871221f676feeb1 +8b237085f135d6e94592f8d855ca397c8c1028236a3b412adefdac888245874f586d06950ee18118f751bfe26f4c31465ec34b578caa44cf1b7109ac4f6eab7f97ff9699b34271df035d3bf58a2ed4bcbf7577cf8e5792b1945ebb9389b680baeb8518c8fdc5540e192aa4fde0eed0d7c82be2e362b286f582d65752c8db7038 00176f124c24e4420f6e726a6ca25f09dfa0c5a37e5bf879e7bdd36c3b65 883637622443162c99adfdc41e02d8743c74ae8be42ddcc769738dfd24cfcba89afa1f3a79606abb1d4228a973fd8cf8 +e3a086ec15574f7017b3cd5f5a47ab7a73980f11074333490dfe9f8ad8926f9ea7c82271aaa74e77133b1025b0b22a6900fbb71251bb6549341a23d194e79d03462cdad52ee0d1b6f5d0d14e1136026961fa3467ccf0864bf7ae3fcc3b68cb35df7324bd9bbe58fc8aa9f63c19feedf19d935b71bf5981c74fb2a487f84e453c 00755c48c3dbaf71042c58cb137f3632e3cf9d90b7b9a58fd378feef3d19 ac6f6231d519d895fce1a3ef65047a36b8a18e3daa5477d7daf2791adc1eaf03f0a5cd2bd3c2adeb6c7b15a540a5abe8 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K283 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K283 new file mode 100644 index 000000000000..8291b65b7d66 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K283 @@ -0,0 +1,60 @@ +ef90f85fbda05e693006e4c64e1dac56223becaf0890f73b5274e6e289a5a1de2c141b825c24d595b3fd18ca855b5c1aa60dac6b5356275b11be670692cdbe5f282f93ac7b2e410a96cb9e9f80defcde98f3449f99e192bfd62040421a0ab8f99acb85369f25e5efbf81439efa8a5e1d9cf781355a0f47b037b09fe4086389a0 01e846c830a8ec04e8572d1a9d2df044ab47352fb346f67403a3bf87243871b164511c53 8411acb7ce2bb1a0f1b1862beb23732d3faf92a566963b3aa97bd6438599ecb9537da81db338b13351f823daa5ceee43 +a3ebc17c867cc9c7c28797f6364f6574b80c7ec5b2d8e1542a6f5db8568c15032f92cfbceefa3fe4ee654f690b0455ee5d38dd84bb8665ffc1ff8c849bdbc4aa0ddfdbbca4eb37972fcbcee8cecc1aae21ec736ef61781716b60247b7551ec4e552d0b59a53cec5964c67cf7988787cedf769eabcc9cd5243f58034d96f0e43d 0101c5ed48231a56ca0ea85eb45de0e395e6df2efd4987a226ae36489dd8b2dfbf7c465c afe402b361b9c9b4807e27d790bc9a1e788910103131d7b72c1df2a713c5fcf6fbbb966cece7786ec5e6247e0d167d28 +60269efa4d0ffafbbc655f6f00578eadce7fc0a7eb7db923dca49b6f2bf3e13f7f829cc6133e022c3c92143c075ab9ced0531a91e6e79848194ab98bb852f40c84e7aebe71fb8bc0fd1f97ed5bb6bad6783d8dc048df42738e841d978456e055e1b8a781dfecfce2218701c7af77e7894ccac5bfff360aab0b6136b978bc39c4 0019679dc589440b11f82b3716e5b2a2bd42c3b1c83e88a28e304cf5148877faf760b4de 8505382ee6962a963e79546dc098fe38aba12f82ca7f692c1ae7de9f5d16e2b2be736b49f8e8d6ef19b74d55ecee24e5 +59d704d5b1f3a0605f1497f22f71b8f45b26138bc86371f00a4517554e7f6e7fa5d35189fc656ce68bd2cb8510fa3e3c3df815dfdd749b2b6ac997d443f3954c7a927e138b579801ffd035cea90840733e7884ccfe43d8d3a4a26b430673274aae312abe4ac1e1d7c67b73580fedf2d8de46572493c9205ebf0e8b4d75ccc88c 01703c21fb1e09f8947e12fddf166fda6f685221fbd803d75a0ae377a54a1e494e6c5e7b 8942faf87dedefd165a8d4dfc412fb3d426301ac719cace16a3aa2f867d316a4efbf9900cb216cb2251282a5f865d415 +12c8fdba3bc5f68e13f7ff8e7bee876fa68a970afc6924314dae0c2482763ced8d4752cec29ea288d350acd8a06c69289ae41ad345a1b88bcccaac903f2bff39015c289a8ad608606bfd65270a7bcdb5fb10c89bbc2d16dcb91fc9735d66103f6b1f3575622cf4d8209290315b033ee1f79968939410f465a2d37add46af2d59 0071de8eb14cbfb88e61b908990ce08b81e624ef4f2cd9cdf3dd7ca9097d5ffed9ae9a71 b8a1b4e21d2c0d9c122fd799a3fa00dde1d4842f2e0ab86d6b63e0cfb23646058ddc27c9a46e9aac4dd253d1df3ef1d0 +26013a3ddf687bb2f37d9700923906f118d5cba5d8ed5113a0e3e84cff00918125108f74f4b243e351aa5d07fa7c6ece29f5700f23e50286447883d2a058c3258a12e4ed8770cabe627ebea7ef6e8c77811ed7d9a19c53287093e39226236587ddbc63b7ad5e7ad9895c64d1d03ee432d45a067afe27d4cca920ae88a7a68db1 01d156eb15762ed00c4021884adbfc2426e910b18a5bc474268196f4b74e593a8f38702b 972ab59d42b7669cf6303860c55b89d5a3f3163c83272dfc7bf0006032440e718b3e9200654a904520c6a9d32807a519 +c4dbf70b9a2165e7279122460d05ceb8e43e03fbe2ae7c314007fe2b1d8567cac727a10fba5cbead0ddb167d387da8e8f3d6bc0ad851cc32885809d07a776fd4a95a979fe3833610af89df0f454d9edfabe12495a118fe83add5eabb2acf54ba7ba7c4be20fc77478c0a0f0726c4e60317422a612a234a7567648603b63f1c12 017d6eb1219cab8577168be86b61f372b27ca70fb1f1a767947895c185344e966db17aea 90b9bd8d73a66f92ed185bcd512497a2895c879d39d45ba97c4225b171917b998744e2c77d81882a22f304a13f7597e8 +b1d53b6af1face9b59af11c726b0099111d1adb3666209ba46b1744a528ed0f72be5a1b82423153b896384faebef0362343e2a4599803c08b8513708938aa8a498145fca1c63ba41aff06d1a18aa2a045fce7fcd7e5552a2b98d0df97b6876f06a9cf52a7a40fb737996adda97c3cedf7fe421235ac6951060eba9c0377e72a2 010ede9be6615b3b2a294d67da78127ffbf3a15bdba6f4fd78be7a60415b5d1a097c0cff 89c4f5413d7adddf17aa17c99a087d835998285eb9ccca9e85deff76e03e5469fe0ee80fbb7f0830a06766ada5bb76bd +e78f538b1ac21602b00a09e3db243ef4803b447329c94a1476cd91a88ff790da71421b60092c8a6e55327c7982e7655eb1fd6e40fa9b9fd2f10107dfc585994dfc5bc2143d18794a39f7f69ae679b27dd11ed22040d5e93aa83f71783525a4db0c3fd7b43e57dafd0033d5317680df19c2ecaadcb37ef896c61a758a5e455206 014f237cface123b64e8578ff33f86bfd2a8181b9c81f36b9ca31e2a446f0d91dbbe2249 8d43ab54bff7edcdd0b4fa31b5be6bcb2a7802da34072c434c15757b731fea53b7aa8d927a6ca9eb4105febb222d99d2 +8a6ca8ec436d2c706fcbec6486b5665b21c174edee7ebe108211c388b1219a8224179f7438e0bb7d6e41ac4a67337b52d4cd9a069fe6c88960ae20be29c8060efd7c62cb7a9a37136a250e68f253e7f27755df53ce7c570135641ad49b43507e5483e17b919cedffdc0d4913b1d5e0ca0629876c0a551841a0fc2090d2857cce 008dbecb26587cb2ed7df2404e680fcfa5bf8cf6a58e87a350a1600211b3c844ca86daa5 adba849e156541d0e6fc1ae1fc98a203d63defcf877951438ac9153c7e587fb30160ca7bf9e3f6521e832c01ffbd75e5 +95bee02b423d2c6e60252da4632f693a2d8f6597b4f9c6e356f670c3a9e4e80063e92facb6421d0325b99dc150464ed2ec1d0bac72a042b35d56d33d2fda686a75d582d4756522218b4ddd25ed45503d90d3d185cba6cf0ac211b22aa4e1318a8316c369186f7130446dafad64f7966f5414f43af37a87127534060a23c6165f 0191badec2d28cbbe62c072c6b57eb5d4644d0c0b3283951bb66096cd15edd43a1bbde53 84d8d9a61f6e06e14989c424499d1db11a03d02d5cc0ff3b757ab7857aec03d564fe58abb178562ba8b5620b3a474391 +ccd7f7c0e04d1ef9a3c5617d77480bc624beed6582bc28e9e3a369b12144fcd96b735ee41713f4173b64b28c6102d82dcfc7876e06e76fc497d1d238bf6d85bb5feca630bbd0c0f0fa7c0c72e28e9259087698973ac66244bc6e69c04deb22eaeaee7b20da239ab6333576f01349c76f594498620933b8969450ac2bae66db8b 00ff5e3d66eb57fd35ba4472effd6e7a016ca461e39000a7125e99080f6ab6ef4380dd7a 8bce477da541bbceaf7fae70240b5769cab3d9527322438731687e8048128598f0b75ff31144456f48e79c655586ff18 +65e9124a2606c8784c9489add2999f4cbe6186395df20838d653b263a207ec46995d2685b55d1874e7ef05a6a3bb5b60a7be6751ad568cef1bcea2debfc494d1e2ece0dc8028c88f1b2c6e4ee26b639c5e81f6448bd25b73ec4608a8e8cf4e0155c29b6f0a62781493b03bb7384c9808529d5f87da6564ae196a365bd282f46f 01f3591eec4a8a3fe6ae6debe230d238a6b73cf3791cb735add1abee64239bb100f15166 a214325c41047ce42e370d729e89e5b24ebf645d785eb5bf7cb942e6ce67b982708ecae0e3221e286119cf383abaf0d6 +e793c60fc725fd537d5fd38e9b4fb52e268722ae6bde5a058de8d20db301f5e8d8e1ad85532198835a04b76f27ca3c972be5617a55677cffa8219eb64fe53ced242efe1b889990979227dbaaa15ed39d3b6be8c5a3237ebe12bd96f333d947f80048463d3859e34f865d83faf03894c2243a06cc96788ed952e606c2d8948271 005af03cdb45961e7ff35fb0146904ddd6c2bfd3cce814073d3aa56eaa9f13b4f7423926 a5702a97b82bc607161d8c18dd2b98f6b53242d52e42c27064e9db127b3bf114cdcb8279532c3da8e3b81485938e5a2d +a57682d21cebb48190199e9f57493696eae3a59acd22f64d5ef4729decf6c2615b326817a6bc118bb7234bebfc7276dd998838c009a7348e46431574638dadc48538d6048d572e50d9c5974d2049ebe1837dd857bcd1447b1514b62808a4e7a88162ae1bb08a0f6d3db6f25874c6cd0cd4ca6333f1bd57bd192ef67e4616d182 01ec9710ada06e6270720692a06d488ae2ba863b905dd2fc323e7ce68dedacb35fc8c7d8 ab50f3193837d33a64f23e61168b57a4e387d23036d91deef73568b03fa1b64d76de4083b00a00db427d2ca1ee4a0197 +f646e7334e191c2bf0056d3bfd23f03ef7f0777b923f962519a8399d311b8f68414c689ca34b96871fae99eb7ea534fcd83e788e56eeef817cbfe33677283c736b99bf6a626f9515291e842bf99f694e4e8aa7c9911c591a87d5f112b3d96b064594e2b368e6d1bf1a1cd343d54916a66da22c26355266aa2884120fffb8b94d 00668de088c6913640fbefbe6d2c44ab26e481802dbf957044a4957c3c5d0a0fde331501 8d149381df396f51754f24e19b40e0dd2421aa0a9424f05c36c4fcdadc329fbe22b7faabc218c1e900bcc76647faa1f7 +a2d7e69ea381d3edfde4664c56c4cb140d01cc4425df757975cedc995b89640dc016ab419b137ff25a6a6d64a309b23890439d2ba157262393cf93d15ca1b1ffd19373ef12367f8898aaf56d5544c2f019a4854f69b3d8d320e03135bb7b675e588a5c3fe4b703938fa0f964916501297cee2fd04af767155c7739419f9dbb7b 00e6af57cf47de1e6f07041eb5e1a413fb7ddd82f8c7f7ce957eb28a118004930bec4dbd 845aaeaf9845dc968e8c3a0dcbb83ff867920fee0bf3befec23aeadef52750d6d34d56b454f035636762a6e494258286 +7088f60e9375ec6a42f705f851fc76cc833c4dcbb3352adcce9f59197c1b7121e7aa661c4f8ad9f4ef280af3a2981e90c01291f7d1cf7d3ae2d96b37fe6975e11b7c6c02b8ef044d1470b1a26b9c72e8c4e7b1dd83c8acc9542e2fc7d211b87841dcceea2ab8128d0ff7bb622b60faa4a89ea7008f7d55f8f9de675bc4596fd8 019f9b63fde8c6aa6177f2a38981505d04f8ac62bcc21007b05615d028cfe851ab9cbbc6 a7769e6a1fbccf984d12f181a3bfcf9c49f2be341c476b8bd7e1a3b6f3cc35483b0104f8cd1adedc0b991d4ba86fbaef +ffd6044ab991849939e8a29184b4d0ac3e07acb63c7e6b886df9e8254073fa800d5910b9fe34fceb547565a2344eed4de394ce2251ed51ec882ee9207eb7340464c742d9d140fa0964f6bcb1efcc2d13919af4f727953de41b20728ab975c1ae0ce784865f23ed1325c68daa95ed5c932893610179be94f13b9a4149f09833b3 017704c1f436beb52f7ec97192e23e206ec09f9e8986e06bef71467c192bad6f0066b3c2 82f4d6e5c37d30c2904218c5296b998598022c55cd3771d0e693c4899ce6ce03f1f6e19123807086765d905f04f6f251 +c9f81c9ff7d80011fd41f2de97a6c1e6a22cc2da7b2b9e4c50e1354c3e139b44529ac786ce795fc501dcbf11a935d4728a7bba44b4e86b5e5990fed4d3e24fa5ab6f303e1842918f156e00dccebed6897c852207ae5941c630014a41696882066c2b296d39cd8658cb5830eee78e29a00335a99a0ba90722ceca5a2e9a99a2c6 00c7d1ac8faa689698f5c6325a3b3f35e7730bdbddabd0693f2bfdc5c838bd62f84508d4 8a22cba30c1562e6af0b2ffe1304c4ef14a3f1870c3b8d4dd9aa0f61b8ff5474d8e250bd281bc6b746f79ec7733f87ae +a60de761eb32490184dc1d29e21fa33889295ca587b994746874c7289eb9c83e9c7bacbb4066c761a06b65ecd78d701bd41f305cd7eb258c630f3febfbb0a367ad16737b146fd793dab23562e8001cd113135b1c981d1ca23eb3be0fe3e24fe3fe1089caf9fd8f4f0d1f90dcc7dbea4a9e2357793b65daf342b8e6d109c6dd10 01a173d158866db0ec665ee632b5fc397893f6a44ee17c348e7452800aadd8ce676e7fdc 86f409b8864a4551ddad486d247cd4f7b755fd52432cfb72197f06d9c5f740873d391f0617c338fb5ce26acb01816c4e +2cd0320cc73120ef13e83c8144b270c9a1f2049a9250ef7ee83ccc7584025140a51e2227a5ebb824deff55b3affcda63ecb1fd3f337c67c08054dc82fdace0c4bb9cef1bea9dd792635f655363d05903cd6b5ed50ee669bcd8157509366cd85aa40d19593265da26e5641590ccf04672a6df52badd4b99964a8643d9687b499d 005523cfacf4ed3b74ebc30f608292e45173001d80cc801f729c5f71fc213b243f041ad5 a09b280b42a0bf367c8b76d05cce687a745a26be1e2d85bf62f01df5de47982176384aadda535c627dff876b7f7b3217 +a743d8337bdefc4753f937e869a36439da1f8c75e1278c3f6a4a969d93787dac93293818b1cbef5b8636e1a6cb3acaac1e15dbe0841c8001512b689292f3f4805997ae26ff52f7fe1842512a020c448ed01af2a061f3638689446ed5f6bed9fc70726ce4104bc11142de63873fa7039830223e8f152996388417c48e0c1fa81b 009f6bd008c04b8823ccc3ee7d5aca535c211f35e9d9e7cfaec518b98647fbe6d28283de 923e92b00d9df3b2376a01009e8e4f74ebae1432bf0569b282988ff566c094a22a8d435e1d4867ed3a7b77deca4ee9ef +6a7a3ad614a3a09d2dc5a80204815d0c6471057acc0fa73f3cbbf1801902c3e1cba3c1134a79a8ce61994a94a5afa85ae1a44b2cdcf5153f8625713c872da36aba0afcc5c2f26636dc3f60e04c256a5b023e20e2e7a3f7305bd5b3033fcf05368589f19021f8c9096a88679904b657bbe5b9bee67d6e53d176fce1de9e54c64b 0150d2812505c82584201e93f6e0cb875d29dc7bd99d9c0f98e0ed20128886e67e1f1071 93fa246a99112c71cb4650c74431f6eb475a8f1aedcadbb77ea89622c514ac33042a594319be53b0869629770784c554 +65bcd77a3ab345cc99b9c1300755288102a6ccf140bc7d1ad25df246ef01fd57a8614b352033b88cc6ffffe5b38b99ecf03baa365ab5529d6751a3c020d0198561969aade09091434d84ffe13b46df043d0a61e20a08e9c32b646771fea1b29e202d40aae1c7079873c3af494ecf6ef5eda855736c9338b4a5c29a086a8266fa 01b3fb9e1ff70f94bc9d7742ea535ca982215af3df381b5ebdf1db40c7c849a7978ceb98 93a940f28c61158d84f4b2aefc22cfa57d9bb1b480efd98e60084add960820a6da6718bc57795fc2b749678d07fad8f4 +ed1acc360d02ee6c36bbc223d91bc1d2009a3e8f8dfc4c3796cd8555b0d2b46716f4c8058bf34c2d4954e098274ab9c2cbacff46a0578a14e77fe104196cbc6d2753e3bb5422b8b79fd004ac0aa920eea94925c016ece16ed4dea916fd92563ec65692a61b28ee84bef0007120bb1e31bb75b8ecf68406a71af9a18b4edf5320 0147fa46fccf0805d14c1b84ea59bb8b8283d54ca0ceefb29b5585e7141340c55b7232f7 b0893e50f8d4b6a7a5c9bca2ec2072bba99bf4ca773b1be3e76da8dea3b3e7d89e99f0f96a532e21875d3e41278e3b5f +2debdb95a21d72b69c545988727366a42b819ca6398a82129c5e3772aea93fac0aae9a27b11969ff0ffb9dc0301132ca2452cd863316cf24ae7696422d4dc68e37316161abc146e86f04b72d9a27a350d8545cca245b2be43c33bb822dd813d13e08a718f784845df8a4ef49b02529871ec76bb3fc1ba31089359f2ede73e767 00fae097ea56b35a517be5480802f450eb832b244558d0cc922cd4a5b40b84d02ef11216 a7cc3681706e8041f8169048c867e6ab44b3eb903361f4eba144a633f29c926acb64afb368440f2bd197699b6f25ac0e +e4e0c6c8fc01244abf81e139c961b6a6e2d95de5dff1083e8a48b40e3e5b9ed909152c92b1cf2263179629cdf76ae553b58bb2e9223ce4f9ffb5f170f5f0c5ec97294c34a7529a897e9397f71198cbcd68bb4055cb8cd6b690290761b3b73303f82788379df145358afe28f2997d191d968929b7a4b9a0f6228797dfaa17c613 0026cd72e6ae19b3f4c53493fba1e8082a8df1fb7da6dc111b47a41f713f49b33f618d0c 9858b7a5d6c2eb9f5b017f814e859b1ce5d7695b29a2849cca5116f6d080beb4a8aa566206a3a0369d59b5b3c065caaf +04710947b7c90855ba4e59107b919d4a1df22b503c5c4c33b286b6b08e451e6fbef8ba40852f9f0ee62c9217abe6156bed46ad6f0e25f70f528f3a73d099338c578bebd6879d810e6e173c2b0af1f7caacb3531ff0e6a7856e4c84db355d110febdb21c683223eb5990ef2038d462ddb7962bc0feea5f850954943d53041f66a 0198e13c7d95bbbb6e226688719639bda988867764ffa9b029018b5547850daecf58fe1f 943d38668695665baa95ab80692af02f75bf413b543d8a7277b8bfdbf231a5ae89c2abe98c3d56f75580ca61d50e7294 +c62d07bb1ef756b6b2fad355c66b5be086b6dc387b37cbc4a63c841dba3fce65b09d3de8f239e3649382d172f065b78f8a53e0283cf345de06b4ee0b4b7d8611bfce92a7d993b1938419afe817611bc6df3ef74191e7e39ca2339fcb5b5cfee3166d09cd52a1a7d3779722aec328d326a11bbafb6aa417920225ac453146b9b7 019098a39956747de24ded56435fa1e6c30cc2b8088fe9a75f5d07b2f5939c7a60db64ad 8b28c9e73c3d2481451876216c04c284418e7534802aa9ca6dedfa5cf1c2172988d1daa68baf9770d50f4b7df9bb6b3d +e4d8d49c9bc566261d9134d5e237d9cbd6b67d2619a9bd06b7c9c139e091aa10682cbede114e1d4777d9cd67a16b7d64278e99eed62bbf25ec5a5a8fabcb0a3468b0e73fd02ac6533e04b1110d29da3e34f33eaa228b78341b357a5d892a61beb2168c3bd5e66bffe3f2080a1e246f55a41ebf9d579e188d16991aa060460d6a 01636bd2be121e07ee83ac5e880cfdfca6a56f2b9d0badff003e872348368c7c2cd96b6c 8741cc48273eee24d2d4a247cb1d74666864cb03604d9d64a58df7cc988a8f48d6cd02be5495870a36810441cbedfeb3 +2d1358fdffc14630fbc421b443d3c22ba10ef34f15c6c5bb3c73a9b8714e4c411de69b9cd6628fe2eba5efc4862af66ff916505023e0514f564164b389ea422d0f1beb92adcd65baf43556614eba25e43852ba65af78f62d64b36696519ef8284ef7316ea52c365b99f63a39e6701f81ad520d7445cfc0113c38ecdad4bf5b7a 015e5f555119c19b055b15b0c0d2813068bfc184f864e250b202384f5728bbbda1cb0f5a 89fe1b5abd066b4d409cc240fc9d4518f7ac0f84f8fda497573d3b4bb97d5aed7dae3f2d6744da91c6cf258229ba78d2 +d6336faa5c3e838f4fa58626eb353d4cff9ba8f0aa0e6c3d0d850e8b22f5b0f047afc97767f1afe2040b85d4e401ba688a4da7a0caca7fac450899092c4fea789231ba9b07782010720f45d16d353798867dd7fef4a324520014ad5cb32684ec50cab742b750e05db040ff51140e8d740f6774a059feeb493b10d8ac722f23fa 0190c8f17bdd38669e345440d2c7631d67cee9c6548c4e7b9452377adb9303430efeda0e b235b552b6493a53c0b1df484ea6357a191e670d9fe0b2e6f9b84612e8e9f0137632f9941c213f4ce49e38d3f46cb2c4 +07384a3f650bd270b14ca388a441af201b7767a2d47e9033f50cefd3af8257ecb38f5267e141cbbb2ab7327d8fc78cf27198ca3543d39553e178390bf1b921618432ad895e4f8153783a7ac22f4ca3cad4560e64f1ee4a7bcad05df98ea49a3847dc2143b27c243e48be59c869a547988e2205358e8db98b635ca21b745df4d2 00dbbc2a0409ca58a9e39e33b95fdd15080443c1dbdb5874bee991bd1b127047f08ec9f3 aadabe6b751724c5d8627f70ac4b23796efe16259e0d235c5eb1d9bc7b5282b4b2329173eb9abdbe39855a6e7596ec22 +824f26dcb4ce0ca020982814d5c727e629cbeeaa818c49668f8f6d743f0d0ad362b24cbac48027898f386889ca5411d7d1f9afc69493b1d9ae4d7b695c9fa0a30bb59e6be2cbff79231767e96cd8bba349fa2f97955d56f05430ab4ebd007064e3d5add94dfe255b6deff19650883ce9966e1a2affaf84d9540f65c87ab1f936 005495e6c59ca1873f36b756579632fd47f9fb95b64f52589d70f2739aa6a3bf8cf8c198 a5ebe1e7413b97f2e80dd34afc20e1bbf29f7dd6ad635cf56079cb1c23cb487fae19144c98348f5a703e9a8cd7509325 +07de1e4bb9be15a710a74806d4447b093bc08ed04392d1bd5abb414f5f4b4d9d43520d0e46fc81c2a97e71086b28e53242449ed37fd7ed1c5772dbabc430fcf82ad20437b38eac15820421e51912325c872894452c3f8a10ddb040b35308e583c155c3707b52df467c4945f4e1071126ed46611a3253c297f5cbca9e27f58448 01724987c9b698519b6c225cf1261b77d0300045e5fd774dcbf13f285e6bd74512cb7edf a0de182cd5074e5b2dea732cad5f6d28a514c471fbc5cdc785a348427675b185ae31aaf2d18da3b277829bc1b3a138f0 +1edbbbe71057bf7d0bfda922be21a3a4dff57b017ebf6fa99651246cd173bdc9b11eefd048ea599c1f98e907932aa04f64ed0a007831f30daf186c88807400970904d6090b2cf181e0f65f03b4234aceeb420867812562e47f452152bb1ddaaa48487170d06e47c5e9a7c0faa4fe494663d2fec22f7665ceffffc214b21c6b8f 01a5489091cfd51a0970508ee3e8449081ed175928ff8386592c83043a7911bbc2f8778b 8f5007b314cd1401825b814fde2c0b5fe427aafdede265cc6c1065bb23b185231885519a422fcc6c1cff4bcf4dfc86e9 +db5cf1de38a5187af11c1f0f19a36db52f8417de997229e83072fb51a3b7152a3b383e9919c1b8427582e53d4e7e25433d46cdf01492021c237ea0a87d38c71634743115a6b2aba66d3faa8003158340a5078171e0bd55a6e5d8c7fb2631a31c1204e1479bbfe79ac70d5e5823af502922a900576f0088a33e42ec3e26c0089e 01a45ecda0788fbd7cb7a716dcf4c6e83d4148bf63ed58078690ebd238c00329c462590a b49d6dbdd7ce6cfa246620c1ce3c9edd1718537f055f4ec4621f7307392c6596c7577c98dbe6e130ef7d695b5c3a1ebd +4adaa850eec8272d25d76600aacf2cf66e754f6c5efa65c55a2a31b7bc69437d9a7e47c6f51c5da93895a45221f5f92c2e20ee6a95eed3cc7249688261a35d82872284900eb54dd1df6024ec48963ce43e8ed8b8cca8ed22beee8f0aadeae53726cca05443316537840ab824cd1b595f36064e9a19333748d4f4972178e7f5ae 011461776c33f20b176dc8f2b0cb2446a9b69e55b6c7bc7457a7fb4639116b452b79661a 822ffa25918bf0d21a19cc4abf9d192cb7cae4a03b0a2a9b1065f20f6efbfada1cb8ac0f1bdb27cfa5b3ad9ec4d52eb9 +11d212a99c39fb5e4ca0096bbe6c81ae1490e1b8e07374b4e773bee4fdd24a3c13d653919db663d2c32aa4db140c4ae2d472d4f878946e527ad33b3dc93012d97458f96cb622ddb56f1ce7c2474ad0d5291dc35545de47b7053d137a8e79dabe06757ab53e26eaf751111bd27690e57ffdab5337eb6f81889e9d1b1ac729012f 0025a65f627db2b4d6cf83c5b0c00265b9b63f7656c5e3382139e4992bcdf3cab502844a 8291378d16e0ff870925cd13e65aef2ae00431c2b6f3e77fa5bd5d0fb72bf03e5e0c9e789923b8b41aa993d1eb254889 +9e4ec74c09528fdf3153a0f6955f20c70915ff524b2e19c991ec4c5b41ea9185e3e876a02ed6f27c9b3479dba951bee8680c4c99be1a626808114408856994be7444ccbd5ef9859fa479b1050bb836034e20c531b4d618f5843fe1d4b613a731895b489a2363f3f5397d5ff964cf037e9b11e3ff5e1c3d403e5a46b8387c1241 0173b28fc29f10245221a907778708b3ee62e0480aa9051d4c3eb4e8d552e6aad5509943 ab1dbdd6cc9310c7392791915879dbf6a80e134f8490c2449a34d08ec6a3cddaea78ff4ce02be96e16295bf1962e7a18 +5fe8253d2134c434cb0866796013722e82184638b024a5a30938039929ccd8415c71f71f239c5c5a81f7a9cb493dde209f189bcf766c17c6d9589cd0c7de7f07ff9f24d2320669b589d084f8a8ea71127b9760b7355b162616afb34bcdcd416f1a062035102e29b70069b2b4dbf70179b8d60bc2ee5a455efd40194533bf560a 00624616adcd45e1fdc6cfeab2b17230d73d91fe0b39f4664f3c6891554f9b8e238257f7 a6c17114aa88c85f089004eac573682a8a321e62f0ac21a4923ac98b582c848cf20249da9d706775c01f12d260c48923 +db49891838fe23f0530abd4a4fbba5ea970afa5747f6a0a10d2cf4d841581ea2178705c1203f00cafec91d0a72d25448072c9cf7d7ca5580b39f8589ec63128faa95cb0689574a6bebd515049a1eb9699922cde0366b5cd58aa8f3d3e847706896f7e1cac667fbfe94b2eca9e7be79a810806ca4bf53f219bb30532ca2254c11 0199757ffaa2c59e198d66824eaad37cc42d49b2e241b6a60382d05e425e800eaaf32470 8da80b4c31f8efaf994b224ce25bf13b0486ede1d4bd5bb5413cbb28b16be3a038a0ec19b4463fd688ad4a4a91b7d383 +29d385d09c1142a7c181fe4b6e6132e414c15aa8605b44208c0399464613b966edcc2d46cf203a3f85d943d8eae658695dac74366224a0d0348083bec0106f5eb8809ae8d07f792fdd7c48fb1a25d5ef3bb9acd40b20c61c821024a9acb2ede321bd2d0dda849c22d76f421cbd8d51565d3c4266f666455ca1c0c3777aa44107 006e51381dcf21050aef2e9b97e35303cf3bd91956854ecf9b6b9827871d2efbe8201c5e b8a142f30fcbf0a16e8f844a7bcffaf4d86d17738075de169bc2734dbcc09deb7cdeb60e57de3dc1df85722d327d6823 +774c1cb8fb4f69ecfb5c7857d46415568d88f1f9f05a4bf64a1e1ff6d64aec16e1d09292010d1f067c68dddbcde06ea49be2ad3838053f0b9c0c2383edc451ef0188565118e7b3c66a4fa372b96633dc8a753106283b02d0322df273d58cc9bd061ec219f1e1a9c8ca1400e5e39c1b2c254273377dc98a1a2c44e5c2a5b89167 0018adcc22cb9a2db64bad3d60f1608c353e091637b948914115ebd43679904f955c8732 b34f46ffc26834b7a45a37dfc391c67603e6bb45c072dbad5b6b0a212e8877f74320869f5e3e16e311b2c68c6a54d2c7 +c406aa4295f85c854b4db2de5a7a2defae53a319866921a3673af5b48c85ef22f6eb4cef892c790d8e64530fc20c729b2821b5f5e515560b1ac764106560c3a6a05657e34cd6deadfe2884bd288cef4ca92e1f25adde7d68a30fb0a1b3678156ced62e466718e68e9d67099ad82613b8d06bdda1a7b867c2455422818ae9eeac 01898276f159c10d92d8d4b6ae214d68c72792a4b5f1f79936ca3c063dc8d9a88be439e2 85270ff347bfe3a13f6be2bd84096be752aa15604f4afd828129ec72caf3a3e2c52cc4111835db9354477f9b9c6afb84 +cb2809152f8258660933472c06ddcdb65f6d5221fa29d5b0efec9c2a7914dbbf9ce0a468ce146fb333d26f510a87a6bb01bf8816756a1b5df81c5f65360957cae84ba038e37e88777580e91c34e2f5aef4fb55af7b81ad28aeba05e0b1c64a15381a6719fd2c16e38a441516e1b394952d984baf9e051b1dc1bda2e12f8ba5b8 012ff37c808c3cc029a9cfbb67a5ed21f3bf362b49270d4ed0f1e38fad25ebd79f112a50 8afa693fe728e0c11748c977875065e2ac8068c914f83ae1e0ba0d411a6a6e37db174407ef4458fa0dffe9ba19723aeb +e060af96d4a7fe512bbf26be9a27bb6a8ff37547d4a7bbbfa710db24cffcfc760dac120f89f642880db2df6307f9ea5441d5932d49762d182b29d8e7fb067a61ab0df622f75cecc917e27d0326085d34581e052c85f50a37713e27518aed7c4434f86970e00a0a4b8503989e72614131b7164c1bdc82d2b6aeac0787f9838476 002b8c1fef9c6def32b5f4127273ce384b6add4aecec957c1662f52334f5ee97f49852d4 934e11c03ab0e5287f24272455a0a67178d0afebb213ad8a7d0093374ac8399538c3d2d155054a7b83b612b218470bc8 +d235c31f0a82957a087c7597673970aa39321d4c2640685a03df8388b5eae4825d1fee29926f416d5e62a2e9ca1ea7cefffd31607e750fa9675983608e0f8dc895371b190574d065c5c0c23ffdaf49e65362914363a3fffbc2c1bb487cbd4f69ec22dda5c7dc3bbab805c81faa85787cc176bc0e5703924f395d8c9e7e7701e2 00afb1c45e9a9f02942b8e04da4b815498454dde6643de186625a98b3c1c6993abc8bba4 9133a1bb819cb00ccfc76fdc467394168193177a9030d6440261e19c2f8906f50df7ca4137c6449902331f95e945b9e2 +1a2559777a5fd8f269048feda82c4d9fceca95803f84a813789d6ed070422240e443789c5231d63d5268ddebc060dfb99c4eff2ff115d2984d8bbc5c05314562ea6864fd543e7e0a3b8572c017d8ae3563027d79bbe164d40a5bab354720e45094b9b26391ceb55339592fc2f10b97dc9c2649f7227648f5cd2fc46d78d31c0e 00ff537d73a4da0ae3a4894016b71dccef3bc886f3d24a5abb7dd96cf8fdcbdf0fdc5e51 afdf8d5cc81637634d89ee3efcc9fbbd523aff3048c358b08897b47bb09c18bb7b9fa3a7d99c87ba0b89993ea5565a0e +658c0d3f764bbc952fa55a258bac16a5bb5184bfa76cee06baf9ee6b9ac3f116e08bb2406b1dd4be487b057f3b29c2043ebc33019b2017c4deccb86f50ff15fc9248ea5fb64261120b1960525aec3cc18827c23291722c5add8a3761ff8516c61956c62b8cbb13f3d92bf3eb45a70704c01bb3625d21c38ffa83a6db086ee968 016000d2e879906d1040b32eb6ba3caff700e5565871ac75f10c5c15b509964bbe5e14c7 96bfb5818de1bf51e5aecb3fe45fedbb2771008997b56409723b752f3b3f6d6c21873ec582c8916220722e7ee58d9f27 +4f10001e3517c2c1f973b555f4827681e096d860c4db08f1f4aef8000c9c24bebe59f8bf3d7d3cac959a1a5477bb0ea43f2e746b5d14ed48a58ef35484b0ac786d2fec669f945e846ad73e6b77a9e47012a951b398941566330d89125eb3c1fbb2f06adb951ff5f047d102fdf28b5cadb4a3e1a10412eb3474d2ed5c3fce78f5 0019528d505bf0584628d0214bc857150a929d3f59619bf8f3acab545fff0977c9bcdc97 a6cbc79ad5643a8445645fc2d710397a170d6f5123974d0ec9d8c610055782388438ecbb6bfbb3bd0b6fffec000d94d7 +c43ec3c3232cae59bdea7cfaf18a4672035dbd2b8b6b1b44ede376b36cc2d8baeb921e416aa177f5977da8bf1d713509e5251278b6622790056271715cd5feac58bee5baf50b216e8eb886279c5a384cdb696470275b7487fe9ac4c506706f6b0f9809d1ccb102546a4297d2017c2a8df9f02f30d3d1bd9aebf6a92a02e0d202 0067795ce117bc0a389397fc22a01cfd9422cfbfb5aa44131938a8c45e48e1d5a718539c 98b53e4f892853d3565e7f625e830281857e2bc9dae4ee2939083210502ffbb3f59980917833f1c62bce4fc157f0fe93 +9b7d675a3d2cdeb280ea28289b5fc2a3ef6b535ebee8ad242fb031e2e1f364e8ee806568b2f8627c5a5b4f51f4f65c71acdc1152c08b9211b81907b551e0ff47f5a6aca45dcfa06f09bf195d19d7b165b52111b601fbd97b192f62465f8ba20773b1599c8041e91448eac7a5763ca0628f40768324c5304e1119ca6a1fdb0778 019269dbfe4184249952a651a507584746c5b62c64cb3b17e0158aaf4d086a4afb0330c1 8581ff2530840b0cbe0675d72eb98e0996bf6dc41a2b74d35aa46adf33b9f612494ae98bf10308e73a7720620c2681db +f4a08daf8f66ce57a986f14b918099bcadcc4308bcde7c169ce8536a40d94a928cfc0968180a2c2a242c59df73ff79a03687998c421cf9a0e661630378779a4744ae2a6cd24ff61d7fcd6c11a4c8bcaf358075e96f864df0998ee98ee393b37bb38747b70bb7a208740959b45174a60153ee566e0f62528e9a5e4466186fa650 003835814de0d6441cd80a44e40350cc8bd62ffcc81e939a4410bb9c9259e30463c453b5 afdbea3c7f91bd22b44988a0d871ab842dd327e67796a5996b67d880d5de6c4425445541df89f135e85497f97cf7aadd +864647405c70939fdb4c026bcad53218ba1d438d82c9138f0f0ecac815dbfb242307cca52c84826cf6556c51082a23f14252dfaea43ba229f7493db2bf8ae9cdb0228dab9e25cf385b504b92cca94f813acceaa1f18de851b8936c4dfe9e4e17002f02dded6b4c231ea5e614ab46fcdd637b8c6193e8d0c2df1b3d883b97e1e8 00aee83dbed3b703cb6e60d51e373eb20e298ac005fa6a572d02fa1e6da0345558ad2a46 b6a33ba2c381a779a8227bced547bb8f0bd77a320d592701c204cd8b6e8491e2ce98a01a03a9fd759017387fc9af8edd +c87c8f3ad5c28a027b28ae5021dbe8d425f74181d519451f1fead7a1f9dd102fa6785b147b610610cb59bfa91fa363bb79ea602a7d7e1439f874c5dce748e5c320560c2d9676f3a948754c72b6db249478b7e19c9829ab4de2e344535d3e0b7c20c272f82556a280ef491524b255c4fafb9c8ecb87b0149ddd9d7bf6159e3337 017b65c66514019ff935e9d571a4e68e9ee4463b7b9a754b93f4f7741693f4399879fa8a a93df3a32e37119d47e68971d6ebc8524857a2b50bee76dddf9bedc96374281297d38d18dc0c8751fc410115db109ff3 +ac7da7611e2ade20aad64b418a16e02e79ab4894d758550210eb10013a9b5533132be701f8843c840807c4167c38d21dff168d3baa65d5bcf285b73dcbb75819f8d7a20a849de335e19bae2aab2ca560b93d340731f291599a5b28afd7737460d291105cbba6d0290e836f6f6c1113d1b2faf90ac5de7c64e25206d79380a4ed 017d2071f39ba35515a8ec977ddd36ca15983e15bcda626f15af61d87d58114f4c80a8be 8c3b1c067fa412bbe2a7bc18eb3864819c6da81609e7c89314df82a426ed618c2aec98d1d1c82f472324f5d3a3559e2c +5757c472fa2f81430dd920f39b61066a28c870b80e6c96f822f8f19b398c3574d159cc22120454dcd7e97be8211916e4bc8db365b2dbb99a6e597d06e6645046a0abdccbd06741e9c0eedf33cb78d78a540c2a390719acc498331e694e6b0118cf4f787b51c7b7237458a6149d6dbd0a08bae8097e919f970fde920485e9a0ac 011504659e12235855fe55220287a101e511d39a627f8a0d414446385d4a88f31507fe74 b62c18a259b25326918144b719625fc876d8731b4549b2a8073572ec579bca3d457ff1ed38c82493ff6ebe718224ab2b +e350383d04af0f4081bf09b95d1d53040e7acc64e56b13b653df31dd119617b800e0cdfeb935dfa5d94f1d7814688d8ce41021810958759cec76560e1e5c0581456acd1a020165849b2203f1c11d318d816697f36a86b59f160faeac7dba71682d3c031d0d547725ef69cbaa28345512e38b75ab011911d8924b2d17a857a96b 016e4cbabb03215767249ba2a608708b78d7387be9e77f5efd2462467fa05e8dcde2c036 815e6b98c08f4b0f50d78c222150f6eb27d71b920d95fd7021cf1a398574facfb824e78aff8746ee7ff1ce1a43f68c0e diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K283_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K283_blst new file mode 100644 index 000000000000..498fc42c2efa --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K283_blst @@ -0,0 +1,60 @@ +ef90f85fbda05e693006e4c64e1dac56223becaf0890f73b5274e6e289a5a1de2c141b825c24d595b3fd18ca855b5c1aa60dac6b5356275b11be670692cdbe5f282f93ac7b2e410a96cb9e9f80defcde98f3449f99e192bfd62040421a0ab8f99acb85369f25e5efbf81439efa8a5e1d9cf781355a0f47b037b09fe4086389a0 01e846c830a8ec04e8572d1a9d2df044ab47352fb346f67403a3bf87243871b164511c53 84c2454a65e4ee369937a730a28ea2ea34dfb66093e4072e975c11123b71ef9a8cfd3f8683caa265a012b45a712b250e +a3ebc17c867cc9c7c28797f6364f6574b80c7ec5b2d8e1542a6f5db8568c15032f92cfbceefa3fe4ee654f690b0455ee5d38dd84bb8665ffc1ff8c849bdbc4aa0ddfdbbca4eb37972fcbcee8cecc1aae21ec736ef61781716b60247b7551ec4e552d0b59a53cec5964c67cf7988787cedf769eabcc9cd5243f58034d96f0e43d 0101c5ed48231a56ca0ea85eb45de0e395e6df2efd4987a226ae36489dd8b2dfbf7c465c a18b1a306e5a9483c9b2c7c3690d0411945d1028e15508f1ee162cfa8bcc329205252e267eb6b20b971cc48e9aa440c6 +60269efa4d0ffafbbc655f6f00578eadce7fc0a7eb7db923dca49b6f2bf3e13f7f829cc6133e022c3c92143c075ab9ced0531a91e6e79848194ab98bb852f40c84e7aebe71fb8bc0fd1f97ed5bb6bad6783d8dc048df42738e841d978456e055e1b8a781dfecfce2218701c7af77e7894ccac5bfff360aab0b6136b978bc39c4 0019679dc589440b11f82b3716e5b2a2bd42c3b1c83e88a28e304cf5148877faf760b4de b5aa932be0d32ff37c2f1776bcdaf22f6c268d064c884b0d010f924ffe782af3fb1ca8ea24b4374906c0f3ccff7d20ed +59d704d5b1f3a0605f1497f22f71b8f45b26138bc86371f00a4517554e7f6e7fa5d35189fc656ce68bd2cb8510fa3e3c3df815dfdd749b2b6ac997d443f3954c7a927e138b579801ffd035cea90840733e7884ccfe43d8d3a4a26b430673274aae312abe4ac1e1d7c67b73580fedf2d8de46572493c9205ebf0e8b4d75ccc88c 01703c21fb1e09f8947e12fddf166fda6f685221fbd803d75a0ae377a54a1e494e6c5e7b 94cfb53dbdbe405c0de7a94abd4ffc7d964359a6a2ee1e11dccdac1996587357c537ec457a8c4e574b010db5ac87a1e3 +12c8fdba3bc5f68e13f7ff8e7bee876fa68a970afc6924314dae0c2482763ced8d4752cec29ea288d350acd8a06c69289ae41ad345a1b88bcccaac903f2bff39015c289a8ad608606bfd65270a7bcdb5fb10c89bbc2d16dcb91fc9735d66103f6b1f3575622cf4d8209290315b033ee1f79968939410f465a2d37add46af2d59 0071de8eb14cbfb88e61b908990ce08b81e624ef4f2cd9cdf3dd7ca9097d5ffed9ae9a71 990b7d2354b043e5e5842631fc7a6dc1ebefc9937e83b124ec440c6a852da242b12b45e636eb92e3a41f5e3615b43aaa +26013a3ddf687bb2f37d9700923906f118d5cba5d8ed5113a0e3e84cff00918125108f74f4b243e351aa5d07fa7c6ece29f5700f23e50286447883d2a058c3258a12e4ed8770cabe627ebea7ef6e8c77811ed7d9a19c53287093e39226236587ddbc63b7ad5e7ad9895c64d1d03ee432d45a067afe27d4cca920ae88a7a68db1 01d156eb15762ed00c4021884adbfc2426e910b18a5bc474268196f4b74e593a8f38702b 8d78c6ce38b631c4bdc0061ad84bd63676cdea5100436b832d5d39ab176127b84f0c5a0607e2d93b9969df212257a176 +c4dbf70b9a2165e7279122460d05ceb8e43e03fbe2ae7c314007fe2b1d8567cac727a10fba5cbead0ddb167d387da8e8f3d6bc0ad851cc32885809d07a776fd4a95a979fe3833610af89df0f454d9edfabe12495a118fe83add5eabb2acf54ba7ba7c4be20fc77478c0a0f0726c4e60317422a612a234a7567648603b63f1c12 017d6eb1219cab8577168be86b61f372b27ca70fb1f1a767947895c185344e966db17aea a5ac86a16488de913481efc0b9657e402c2b08fb30b2da68c60005d80e6ac85add2f91b51a5373bdab2fccf91d7e8f89 +b1d53b6af1face9b59af11c726b0099111d1adb3666209ba46b1744a528ed0f72be5a1b82423153b896384faebef0362343e2a4599803c08b8513708938aa8a498145fca1c63ba41aff06d1a18aa2a045fce7fcd7e5552a2b98d0df97b6876f06a9cf52a7a40fb737996adda97c3cedf7fe421235ac6951060eba9c0377e72a2 010ede9be6615b3b2a294d67da78127ffbf3a15bdba6f4fd78be7a60415b5d1a097c0cff b4edf9e71c83e7e3a8213afdb118b4d93e8f5c82a97dbeaffe677221bb872846c2c52fcbfa571457f73164798dab38ec +e78f538b1ac21602b00a09e3db243ef4803b447329c94a1476cd91a88ff790da71421b60092c8a6e55327c7982e7655eb1fd6e40fa9b9fd2f10107dfc585994dfc5bc2143d18794a39f7f69ae679b27dd11ed22040d5e93aa83f71783525a4db0c3fd7b43e57dafd0033d5317680df19c2ecaadcb37ef896c61a758a5e455206 014f237cface123b64e8578ff33f86bfd2a8181b9c81f36b9ca31e2a446f0d91dbbe2249 b42527b8d489d2cc1c5c613d00a9a60be8bae66bb09c3c7bb0b22135c8337acc6c3b84f1f01faf8e428ff230cd540c37 +8a6ca8ec436d2c706fcbec6486b5665b21c174edee7ebe108211c388b1219a8224179f7438e0bb7d6e41ac4a67337b52d4cd9a069fe6c88960ae20be29c8060efd7c62cb7a9a37136a250e68f253e7f27755df53ce7c570135641ad49b43507e5483e17b919cedffdc0d4913b1d5e0ca0629876c0a551841a0fc2090d2857cce 008dbecb26587cb2ed7df2404e680fcfa5bf8cf6a58e87a350a1600211b3c844ca86daa5 80c61bef7024872164c85a51bc12ea7bbd8f4ec144160c902fc3e713680f835d9f01cfe4c0f66f7376e2ec95e19c9308 +95bee02b423d2c6e60252da4632f693a2d8f6597b4f9c6e356f670c3a9e4e80063e92facb6421d0325b99dc150464ed2ec1d0bac72a042b35d56d33d2fda686a75d582d4756522218b4ddd25ed45503d90d3d185cba6cf0ac211b22aa4e1318a8316c369186f7130446dafad64f7966f5414f43af37a87127534060a23c6165f 0191badec2d28cbbe62c072c6b57eb5d4644d0c0b3283951bb66096cd15edd43a1bbde53 ac25989a9ec9baf8f70b00c60190f344736f644bc232040c5f94f8e94c95dc8a7a7e335ff9cda5b2998f2d605650c2c6 +ccd7f7c0e04d1ef9a3c5617d77480bc624beed6582bc28e9e3a369b12144fcd96b735ee41713f4173b64b28c6102d82dcfc7876e06e76fc497d1d238bf6d85bb5feca630bbd0c0f0fa7c0c72e28e9259087698973ac66244bc6e69c04deb22eaeaee7b20da239ab6333576f01349c76f594498620933b8969450ac2bae66db8b 00ff5e3d66eb57fd35ba4472effd6e7a016ca461e39000a7125e99080f6ab6ef4380dd7a ad04cc19c63cdddde97e1318fb914b9e34cd2f70d1e9a9a556d7b1e309e4ff96614159a00050612b2da7e3a4926cc38e +65e9124a2606c8784c9489add2999f4cbe6186395df20838d653b263a207ec46995d2685b55d1874e7ef05a6a3bb5b60a7be6751ad568cef1bcea2debfc494d1e2ece0dc8028c88f1b2c6e4ee26b639c5e81f6448bd25b73ec4608a8e8cf4e0155c29b6f0a62781493b03bb7384c9808529d5f87da6564ae196a365bd282f46f 01f3591eec4a8a3fe6ae6debe230d238a6b73cf3791cb735add1abee64239bb100f15166 a4a3b16e5855e47b29508e3b92821d68bb2118a52347f6e44c69c2dba35007f07d98d002fd694c14bea1f5c2557bfe72 +e793c60fc725fd537d5fd38e9b4fb52e268722ae6bde5a058de8d20db301f5e8d8e1ad85532198835a04b76f27ca3c972be5617a55677cffa8219eb64fe53ced242efe1b889990979227dbaaa15ed39d3b6be8c5a3237ebe12bd96f333d947f80048463d3859e34f865d83faf03894c2243a06cc96788ed952e606c2d8948271 005af03cdb45961e7ff35fb0146904ddd6c2bfd3cce814073d3aa56eaa9f13b4f7423926 b61b9709486cb6268908c0cfa0a060e139d5a5b8fce88446eb0ac6f4ffc543d956001a7fbe7e9af87dd89f8046540abf +a57682d21cebb48190199e9f57493696eae3a59acd22f64d5ef4729decf6c2615b326817a6bc118bb7234bebfc7276dd998838c009a7348e46431574638dadc48538d6048d572e50d9c5974d2049ebe1837dd857bcd1447b1514b62808a4e7a88162ae1bb08a0f6d3db6f25874c6cd0cd4ca6333f1bd57bd192ef67e4616d182 01ec9710ada06e6270720692a06d488ae2ba863b905dd2fc323e7ce68dedacb35fc8c7d8 94a62a3c608480c7bdb39fca1fac129042024255005d6ac1f48f856e34e42a1cdc506f0806f5f3b875263cea3960e33e +f646e7334e191c2bf0056d3bfd23f03ef7f0777b923f962519a8399d311b8f68414c689ca34b96871fae99eb7ea534fcd83e788e56eeef817cbfe33677283c736b99bf6a626f9515291e842bf99f694e4e8aa7c9911c591a87d5f112b3d96b064594e2b368e6d1bf1a1cd343d54916a66da22c26355266aa2884120fffb8b94d 00668de088c6913640fbefbe6d2c44ab26e481802dbf957044a4957c3c5d0a0fde331501 a7d0d9d4d482c238971947a121d0f844f3978b67934ac363a25375ca23700970393eda06e53d0fe7a029f870b8e9f55f +a2d7e69ea381d3edfde4664c56c4cb140d01cc4425df757975cedc995b89640dc016ab419b137ff25a6a6d64a309b23890439d2ba157262393cf93d15ca1b1ffd19373ef12367f8898aaf56d5544c2f019a4854f69b3d8d320e03135bb7b675e588a5c3fe4b703938fa0f964916501297cee2fd04af767155c7739419f9dbb7b 00e6af57cf47de1e6f07041eb5e1a413fb7ddd82f8c7f7ce957eb28a118004930bec4dbd b855e00f2880bcdb9d24cd16815f94d01833d66671fe8f27627f7ab1e94c02a08a84c54d04bf13451ffec36217361211 +7088f60e9375ec6a42f705f851fc76cc833c4dcbb3352adcce9f59197c1b7121e7aa661c4f8ad9f4ef280af3a2981e90c01291f7d1cf7d3ae2d96b37fe6975e11b7c6c02b8ef044d1470b1a26b9c72e8c4e7b1dd83c8acc9542e2fc7d211b87841dcceea2ab8128d0ff7bb622b60faa4a89ea7008f7d55f8f9de675bc4596fd8 019f9b63fde8c6aa6177f2a38981505d04f8ac62bcc21007b05615d028cfe851ab9cbbc6 8620373bb2ff9d86bf43e686bbb0bcc2a34043507961e88b68645618af95d970185783025ceb28185477d2674ff60c00 +ffd6044ab991849939e8a29184b4d0ac3e07acb63c7e6b886df9e8254073fa800d5910b9fe34fceb547565a2344eed4de394ce2251ed51ec882ee9207eb7340464c742d9d140fa0964f6bcb1efcc2d13919af4f727953de41b20728ab975c1ae0ce784865f23ed1325c68daa95ed5c932893610179be94f13b9a4149f09833b3 017704c1f436beb52f7ec97192e23e206ec09f9e8986e06bef71467c192bad6f0066b3c2 a0cd19fdb1f87dc6afdd9dd797ba86578701131c0775fc1fdc705610ee24702b83718fc86475fa8e3ce98c931a4bf03d +c9f81c9ff7d80011fd41f2de97a6c1e6a22cc2da7b2b9e4c50e1354c3e139b44529ac786ce795fc501dcbf11a935d4728a7bba44b4e86b5e5990fed4d3e24fa5ab6f303e1842918f156e00dccebed6897c852207ae5941c630014a41696882066c2b296d39cd8658cb5830eee78e29a00335a99a0ba90722ceca5a2e9a99a2c6 00c7d1ac8faa689698f5c6325a3b3f35e7730bdbddabd0693f2bfdc5c838bd62f84508d4 a9d85ce014059998ae985a427671d3d68e02c0385fb7368e72c2e863f7245b80924b608b20c30bbcce298e504f80c293 +a60de761eb32490184dc1d29e21fa33889295ca587b994746874c7289eb9c83e9c7bacbb4066c761a06b65ecd78d701bd41f305cd7eb258c630f3febfbb0a367ad16737b146fd793dab23562e8001cd113135b1c981d1ca23eb3be0fe3e24fe3fe1089caf9fd8f4f0d1f90dcc7dbea4a9e2357793b65daf342b8e6d109c6dd10 01a173d158866db0ec665ee632b5fc397893f6a44ee17c348e7452800aadd8ce676e7fdc a360796652e5379dbb02bafc8bb884a132aa7de9fd41066580327c249b028dc9baf84de4f79c04af3646bb625a36048a +2cd0320cc73120ef13e83c8144b270c9a1f2049a9250ef7ee83ccc7584025140a51e2227a5ebb824deff55b3affcda63ecb1fd3f337c67c08054dc82fdace0c4bb9cef1bea9dd792635f655363d05903cd6b5ed50ee669bcd8157509366cd85aa40d19593265da26e5641590ccf04672a6df52badd4b99964a8643d9687b499d 005523cfacf4ed3b74ebc30f608292e45173001d80cc801f729c5f71fc213b243f041ad5 b3430bd1fd984f2af467cd3674bfd42186fec0ab90e99c2ed43205a53f6430e9ffb2ca56933b48b5491128995d54b60a +a743d8337bdefc4753f937e869a36439da1f8c75e1278c3f6a4a969d93787dac93293818b1cbef5b8636e1a6cb3acaac1e15dbe0841c8001512b689292f3f4805997ae26ff52f7fe1842512a020c448ed01af2a061f3638689446ed5f6bed9fc70726ce4104bc11142de63873fa7039830223e8f152996388417c48e0c1fa81b 009f6bd008c04b8823ccc3ee7d5aca535c211f35e9d9e7cfaec518b98647fbe6d28283de 812fe4ebf923e25e7b45016620dabec7720725ab908d792e01f021ea3b8a356f77aac23de3c8a8adb34d5cee950f43aa +6a7a3ad614a3a09d2dc5a80204815d0c6471057acc0fa73f3cbbf1801902c3e1cba3c1134a79a8ce61994a94a5afa85ae1a44b2cdcf5153f8625713c872da36aba0afcc5c2f26636dc3f60e04c256a5b023e20e2e7a3f7305bd5b3033fcf05368589f19021f8c9096a88679904b657bbe5b9bee67d6e53d176fce1de9e54c64b 0150d2812505c82584201e93f6e0cb875d29dc7bd99d9c0f98e0ed20128886e67e1f1071 a47ed35986f3c9ebf1950d73cf2bd9173ecf9414bcc81d06d834c0afc29e9182b73f8c54b3592635c38956dabecbf519 +65bcd77a3ab345cc99b9c1300755288102a6ccf140bc7d1ad25df246ef01fd57a8614b352033b88cc6ffffe5b38b99ecf03baa365ab5529d6751a3c020d0198561969aade09091434d84ffe13b46df043d0a61e20a08e9c32b646771fea1b29e202d40aae1c7079873c3af494ecf6ef5eda855736c9338b4a5c29a086a8266fa 01b3fb9e1ff70f94bc9d7742ea535ca982215af3df381b5ebdf1db40c7c849a7978ceb98 a3758cafe8c56a90bd4378697905083e80bd9f5fe02a630d9a4e8a12a7f86ec4118536a4059987c13829e1f8626d32cd +ed1acc360d02ee6c36bbc223d91bc1d2009a3e8f8dfc4c3796cd8555b0d2b46716f4c8058bf34c2d4954e098274ab9c2cbacff46a0578a14e77fe104196cbc6d2753e3bb5422b8b79fd004ac0aa920eea94925c016ece16ed4dea916fd92563ec65692a61b28ee84bef0007120bb1e31bb75b8ecf68406a71af9a18b4edf5320 0147fa46fccf0805d14c1b84ea59bb8b8283d54ca0ceefb29b5585e7141340c55b7232f7 b51c2bf32264763abb4c43304ba1ce8fb228f1cc9e2149e7dbab898eee7c840efed469528ecbdcdee16c9ae5bcd6edf5 +2debdb95a21d72b69c545988727366a42b819ca6398a82129c5e3772aea93fac0aae9a27b11969ff0ffb9dc0301132ca2452cd863316cf24ae7696422d4dc68e37316161abc146e86f04b72d9a27a350d8545cca245b2be43c33bb822dd813d13e08a718f784845df8a4ef49b02529871ec76bb3fc1ba31089359f2ede73e767 00fae097ea56b35a517be5480802f450eb832b244558d0cc922cd4a5b40b84d02ef11216 9755ad8689e9e1ab1a8b1d81272d6d497651305fc98f38ee4e276e5e2f8e499035366c55542835607c8c063befb114b1 +e4e0c6c8fc01244abf81e139c961b6a6e2d95de5dff1083e8a48b40e3e5b9ed909152c92b1cf2263179629cdf76ae553b58bb2e9223ce4f9ffb5f170f5f0c5ec97294c34a7529a897e9397f71198cbcd68bb4055cb8cd6b690290761b3b73303f82788379df145358afe28f2997d191d968929b7a4b9a0f6228797dfaa17c613 0026cd72e6ae19b3f4c53493fba1e8082a8df1fb7da6dc111b47a41f713f49b33f618d0c 976e308da3ae834798f886dc55e237ededf76a1f18c0236e1d88cfabe4c6fa4ecfa346366d593ff4a46427da597ea2fa +04710947b7c90855ba4e59107b919d4a1df22b503c5c4c33b286b6b08e451e6fbef8ba40852f9f0ee62c9217abe6156bed46ad6f0e25f70f528f3a73d099338c578bebd6879d810e6e173c2b0af1f7caacb3531ff0e6a7856e4c84db355d110febdb21c683223eb5990ef2038d462ddb7962bc0feea5f850954943d53041f66a 0198e13c7d95bbbb6e226688719639bda988867764ffa9b029018b5547850daecf58fe1f b76eb15fe30fb324d47f466ef189947b2a15bba8912fcccfe04940653bc2ef6309294161a0db79f4dc3e64435e7e8a18 +c62d07bb1ef756b6b2fad355c66b5be086b6dc387b37cbc4a63c841dba3fce65b09d3de8f239e3649382d172f065b78f8a53e0283cf345de06b4ee0b4b7d8611bfce92a7d993b1938419afe817611bc6df3ef74191e7e39ca2339fcb5b5cfee3166d09cd52a1a7d3779722aec328d326a11bbafb6aa417920225ac453146b9b7 019098a39956747de24ded56435fa1e6c30cc2b8088fe9a75f5d07b2f5939c7a60db64ad a2cfca2f3d6e2ecece6c21a2e81c3b6f58c2462a54618e6e8dc570a7351d7c609c6d9b63902f8c26697a0171658110dd +e4d8d49c9bc566261d9134d5e237d9cbd6b67d2619a9bd06b7c9c139e091aa10682cbede114e1d4777d9cd67a16b7d64278e99eed62bbf25ec5a5a8fabcb0a3468b0e73fd02ac6533e04b1110d29da3e34f33eaa228b78341b357a5d892a61beb2168c3bd5e66bffe3f2080a1e246f55a41ebf9d579e188d16991aa060460d6a 01636bd2be121e07ee83ac5e880cfdfca6a56f2b9d0badff003e872348368c7c2cd96b6c 993a167bfd270b7cc05e7655101f407c2081abcb03ff20f13f1d92f1e77364709a7ce0d7ac37c8202eff4e0ddd984487 +2d1358fdffc14630fbc421b443d3c22ba10ef34f15c6c5bb3c73a9b8714e4c411de69b9cd6628fe2eba5efc4862af66ff916505023e0514f564164b389ea422d0f1beb92adcd65baf43556614eba25e43852ba65af78f62d64b36696519ef8284ef7316ea52c365b99f63a39e6701f81ad520d7445cfc0113c38ecdad4bf5b7a 015e5f555119c19b055b15b0c0d2813068bfc184f864e250b202384f5728bbbda1cb0f5a a2f8f47b17c76a064d299f0e2bb035a5eb229d3c3ebeaebac01144c215892be5aaa6c7ca60950aece290e7fdaf97adb8 +d6336faa5c3e838f4fa58626eb353d4cff9ba8f0aa0e6c3d0d850e8b22f5b0f047afc97767f1afe2040b85d4e401ba688a4da7a0caca7fac450899092c4fea789231ba9b07782010720f45d16d353798867dd7fef4a324520014ad5cb32684ec50cab742b750e05db040ff51140e8d740f6774a059feeb493b10d8ac722f23fa 0190c8f17bdd38669e345440d2c7631d67cee9c6548c4e7b9452377adb9303430efeda0e b8a937673fda3894eb3950745f30af746ebb095d2e81c6467049312ad5492ae9425080541c3c4eb9661fea8de23679f9 +07384a3f650bd270b14ca388a441af201b7767a2d47e9033f50cefd3af8257ecb38f5267e141cbbb2ab7327d8fc78cf27198ca3543d39553e178390bf1b921618432ad895e4f8153783a7ac22f4ca3cad4560e64f1ee4a7bcad05df98ea49a3847dc2143b27c243e48be59c869a547988e2205358e8db98b635ca21b745df4d2 00dbbc2a0409ca58a9e39e33b95fdd15080443c1dbdb5874bee991bd1b127047f08ec9f3 8177a322d19282ea6862e8415100ca77b92d8d9464bebd14e4d786fa99d45d41fe45403c74fd0c02704d5be7f05309b2 +824f26dcb4ce0ca020982814d5c727e629cbeeaa818c49668f8f6d743f0d0ad362b24cbac48027898f386889ca5411d7d1f9afc69493b1d9ae4d7b695c9fa0a30bb59e6be2cbff79231767e96cd8bba349fa2f97955d56f05430ab4ebd007064e3d5add94dfe255b6deff19650883ce9966e1a2affaf84d9540f65c87ab1f936 005495e6c59ca1873f36b756579632fd47f9fb95b64f52589d70f2739aa6a3bf8cf8c198 add1fae5fd6d4c235f85416ec9f0c22141320118c8093ceebcf633b87936a5d5957c33dd02735ac5d549accf57d6b41c +07de1e4bb9be15a710a74806d4447b093bc08ed04392d1bd5abb414f5f4b4d9d43520d0e46fc81c2a97e71086b28e53242449ed37fd7ed1c5772dbabc430fcf82ad20437b38eac15820421e51912325c872894452c3f8a10ddb040b35308e583c155c3707b52df467c4945f4e1071126ed46611a3253c297f5cbca9e27f58448 01724987c9b698519b6c225cf1261b77d0300045e5fd774dcbf13f285e6bd74512cb7edf b8a5e461feba420cfb1907db1f435f9b537cf1f9db4d17be10d4de74b63067d0170a7b5c84bcbbe98b15a0e4a076f5ef +1edbbbe71057bf7d0bfda922be21a3a4dff57b017ebf6fa99651246cd173bdc9b11eefd048ea599c1f98e907932aa04f64ed0a007831f30daf186c88807400970904d6090b2cf181e0f65f03b4234aceeb420867812562e47f452152bb1ddaaa48487170d06e47c5e9a7c0faa4fe494663d2fec22f7665ceffffc214b21c6b8f 01a5489091cfd51a0970508ee3e8449081ed175928ff8386592c83043a7911bbc2f8778b b222a6c81f8f61050ef69a51a331acb35adfed25a093b7d8a85de678aed858bf5e55997facd4d169b0a2d301735775b4 +db5cf1de38a5187af11c1f0f19a36db52f8417de997229e83072fb51a3b7152a3b383e9919c1b8427582e53d4e7e25433d46cdf01492021c237ea0a87d38c71634743115a6b2aba66d3faa8003158340a5078171e0bd55a6e5d8c7fb2631a31c1204e1479bbfe79ac70d5e5823af502922a900576f0088a33e42ec3e26c0089e 01a45ecda0788fbd7cb7a716dcf4c6e83d4148bf63ed58078690ebd238c00329c462590a a4ea07d0b9e48c50d1c16fb73dcd497dba2af2c472c1be776a92e9e0610410ee87d0da53e915f6feef815bb6e18ed73e +4adaa850eec8272d25d76600aacf2cf66e754f6c5efa65c55a2a31b7bc69437d9a7e47c6f51c5da93895a45221f5f92c2e20ee6a95eed3cc7249688261a35d82872284900eb54dd1df6024ec48963ce43e8ed8b8cca8ed22beee8f0aadeae53726cca05443316537840ab824cd1b595f36064e9a19333748d4f4972178e7f5ae 011461776c33f20b176dc8f2b0cb2446a9b69e55b6c7bc7457a7fb4639116b452b79661a 83433047d7e6185536c0c9284d1c30d90e2318ed54d1bed2d13ea0a658984dcae6b520b06638604087b7868218b4d702 +11d212a99c39fb5e4ca0096bbe6c81ae1490e1b8e07374b4e773bee4fdd24a3c13d653919db663d2c32aa4db140c4ae2d472d4f878946e527ad33b3dc93012d97458f96cb622ddb56f1ce7c2474ad0d5291dc35545de47b7053d137a8e79dabe06757ab53e26eaf751111bd27690e57ffdab5337eb6f81889e9d1b1ac729012f 0025a65f627db2b4d6cf83c5b0c00265b9b63f7656c5e3382139e4992bcdf3cab502844a 810c2edae93b8146ec43598050c3b686a20b10ccb199f5b48f830f732eead6a3e54745368d15862b70d4a67870ee30ce +9e4ec74c09528fdf3153a0f6955f20c70915ff524b2e19c991ec4c5b41ea9185e3e876a02ed6f27c9b3479dba951bee8680c4c99be1a626808114408856994be7444ccbd5ef9859fa479b1050bb836034e20c531b4d618f5843fe1d4b613a731895b489a2363f3f5397d5ff964cf037e9b11e3ff5e1c3d403e5a46b8387c1241 0173b28fc29f10245221a907778708b3ee62e0480aa9051d4c3eb4e8d552e6aad5509943 a4368f44c448791bcfda7c5f07db2cbb5006c7274cd6c584c5b980f4fa75d3f28cb1e70fdb07a5bb58286796fe67f92e +5fe8253d2134c434cb0866796013722e82184638b024a5a30938039929ccd8415c71f71f239c5c5a81f7a9cb493dde209f189bcf766c17c6d9589cd0c7de7f07ff9f24d2320669b589d084f8a8ea71127b9760b7355b162616afb34bcdcd416f1a062035102e29b70069b2b4dbf70179b8d60bc2ee5a455efd40194533bf560a 00624616adcd45e1fdc6cfeab2b17230d73d91fe0b39f4664f3c6891554f9b8e238257f7 8d51f14d5c628f1a8bca75ef1c057ecbc2cdf82764f7aac7eadcccb73907c8d5a78651bcee0145c8225f750ca444df5b +db49891838fe23f0530abd4a4fbba5ea970afa5747f6a0a10d2cf4d841581ea2178705c1203f00cafec91d0a72d25448072c9cf7d7ca5580b39f8589ec63128faa95cb0689574a6bebd515049a1eb9699922cde0366b5cd58aa8f3d3e847706896f7e1cac667fbfe94b2eca9e7be79a810806ca4bf53f219bb30532ca2254c11 0199757ffaa2c59e198d66824eaad37cc42d49b2e241b6a60382d05e425e800eaaf32470 ace884e8473bfc13417bd8bdc55ce5e6660e8742ef9c9bf0d4757a25bfaf4f7ddf0841203ed4a253d667fbebfe14fa5a +29d385d09c1142a7c181fe4b6e6132e414c15aa8605b44208c0399464613b966edcc2d46cf203a3f85d943d8eae658695dac74366224a0d0348083bec0106f5eb8809ae8d07f792fdd7c48fb1a25d5ef3bb9acd40b20c61c821024a9acb2ede321bd2d0dda849c22d76f421cbd8d51565d3c4266f666455ca1c0c3777aa44107 006e51381dcf21050aef2e9b97e35303cf3bd91956854ecf9b6b9827871d2efbe8201c5e b8a0bf235523744a18fa2e8e15dcac38e853da4cd88913336ae4f5758516fae3a77160ec250d4634ea775ef08672185f +774c1cb8fb4f69ecfb5c7857d46415568d88f1f9f05a4bf64a1e1ff6d64aec16e1d09292010d1f067c68dddbcde06ea49be2ad3838053f0b9c0c2383edc451ef0188565118e7b3c66a4fa372b96633dc8a753106283b02d0322df273d58cc9bd061ec219f1e1a9c8ca1400e5e39c1b2c254273377dc98a1a2c44e5c2a5b89167 0018adcc22cb9a2db64bad3d60f1608c353e091637b948914115ebd43679904f955c8732 a7762bd4e9a260fcd886a29c27a746297b156dd7182e378d1c468dbfa8c607a0d00d7c4b0168dfee195276c86b2b81c9 +c406aa4295f85c854b4db2de5a7a2defae53a319866921a3673af5b48c85ef22f6eb4cef892c790d8e64530fc20c729b2821b5f5e515560b1ac764106560c3a6a05657e34cd6deadfe2884bd288cef4ca92e1f25adde7d68a30fb0a1b3678156ced62e466718e68e9d67099ad82613b8d06bdda1a7b867c2455422818ae9eeac 01898276f159c10d92d8d4b6ae214d68c72792a4b5f1f79936ca3c063dc8d9a88be439e2 85aecc802e105476fb857c4454d7d07d9aec62275165bd2f5888f22aefc2e2d0cc91591bb3d40aedf8db4ad69298b694 +cb2809152f8258660933472c06ddcdb65f6d5221fa29d5b0efec9c2a7914dbbf9ce0a468ce146fb333d26f510a87a6bb01bf8816756a1b5df81c5f65360957cae84ba038e37e88777580e91c34e2f5aef4fb55af7b81ad28aeba05e0b1c64a15381a6719fd2c16e38a441516e1b394952d984baf9e051b1dc1bda2e12f8ba5b8 012ff37c808c3cc029a9cfbb67a5ed21f3bf362b49270d4ed0f1e38fad25ebd79f112a50 84cfa6fe0b85397b59d68228e2c3ccbdb6b7a47d02f173b52134c96edba1a79b869a3e85a8ef3f60458cd78eb349d252 +e060af96d4a7fe512bbf26be9a27bb6a8ff37547d4a7bbbfa710db24cffcfc760dac120f89f642880db2df6307f9ea5441d5932d49762d182b29d8e7fb067a61ab0df622f75cecc917e27d0326085d34581e052c85f50a37713e27518aed7c4434f86970e00a0a4b8503989e72614131b7164c1bdc82d2b6aeac0787f9838476 002b8c1fef9c6def32b5f4127273ce384b6add4aecec957c1662f52334f5ee97f49852d4 a5cdd9666dec127c3389affb472482c1daaba7a266b17b6a05628b2fe3e0512fc4ecb096306d1d965cf875b20de096ea +d235c31f0a82957a087c7597673970aa39321d4c2640685a03df8388b5eae4825d1fee29926f416d5e62a2e9ca1ea7cefffd31607e750fa9675983608e0f8dc895371b190574d065c5c0c23ffdaf49e65362914363a3fffbc2c1bb487cbd4f69ec22dda5c7dc3bbab805c81faa85787cc176bc0e5703924f395d8c9e7e7701e2 00afb1c45e9a9f02942b8e04da4b815498454dde6643de186625a98b3c1c6993abc8bba4 8b86a13554460ebf9b034b56754df354b940c79f1b8dd5c3ff59aa0584bed6664a8ae006796d30a88593bff7c4231431 +1a2559777a5fd8f269048feda82c4d9fceca95803f84a813789d6ed070422240e443789c5231d63d5268ddebc060dfb99c4eff2ff115d2984d8bbc5c05314562ea6864fd543e7e0a3b8572c017d8ae3563027d79bbe164d40a5bab354720e45094b9b26391ceb55339592fc2f10b97dc9c2649f7227648f5cd2fc46d78d31c0e 00ff537d73a4da0ae3a4894016b71dccef3bc886f3d24a5abb7dd96cf8fdcbdf0fdc5e51 95fea1d88040240f177bedf138da2f335c633e6b98856b9bf3fc09e5eca9bfdd9f654bde1f28a3fe26195728e6f86edd +658c0d3f764bbc952fa55a258bac16a5bb5184bfa76cee06baf9ee6b9ac3f116e08bb2406b1dd4be487b057f3b29c2043ebc33019b2017c4deccb86f50ff15fc9248ea5fb64261120b1960525aec3cc18827c23291722c5add8a3761ff8516c61956c62b8cbb13f3d92bf3eb45a70704c01bb3625d21c38ffa83a6db086ee968 016000d2e879906d1040b32eb6ba3caff700e5565871ac75f10c5c15b509964bbe5e14c7 897511a10c5a8e1748fce33b0cb608fdb37e78da01a6fd632799adb5b5fab53ebe712e8f92f623ce8c4a16afa83fc403 +4f10001e3517c2c1f973b555f4827681e096d860c4db08f1f4aef8000c9c24bebe59f8bf3d7d3cac959a1a5477bb0ea43f2e746b5d14ed48a58ef35484b0ac786d2fec669f945e846ad73e6b77a9e47012a951b398941566330d89125eb3c1fbb2f06adb951ff5f047d102fdf28b5cadb4a3e1a10412eb3474d2ed5c3fce78f5 0019528d505bf0584628d0214bc857150a929d3f59619bf8f3acab545fff0977c9bcdc97 aa8d575dee27697b2254ba75f767f88dc90a2c182a8873ec0a4a5dce566dd22239451aa23c409d20840e2835d46d27fb +c43ec3c3232cae59bdea7cfaf18a4672035dbd2b8b6b1b44ede376b36cc2d8baeb921e416aa177f5977da8bf1d713509e5251278b6622790056271715cd5feac58bee5baf50b216e8eb886279c5a384cdb696470275b7487fe9ac4c506706f6b0f9809d1ccb102546a4297d2017c2a8df9f02f30d3d1bd9aebf6a92a02e0d202 0067795ce117bc0a389397fc22a01cfd9422cfbfb5aa44131938a8c45e48e1d5a718539c 999e59fa4ef9d8f59687ffc6700a39b783ef4a4abfc7b417e57beb263761c7d4b3990c0a2c25d4c89c450066b33c37f6 +9b7d675a3d2cdeb280ea28289b5fc2a3ef6b535ebee8ad242fb031e2e1f364e8ee806568b2f8627c5a5b4f51f4f65c71acdc1152c08b9211b81907b551e0ff47f5a6aca45dcfa06f09bf195d19d7b165b52111b601fbd97b192f62465f8ba20773b1599c8041e91448eac7a5763ca0628f40768324c5304e1119ca6a1fdb0778 019269dbfe4184249952a651a507584746c5b62c64cb3b17e0158aaf4d086a4afb0330c1 959b117701afa659b4ccc5ceb138a213bb42bac9a19936f5c3fb9d7e7d720f662634dbfc09f6806c950ac4003cedb4f7 +f4a08daf8f66ce57a986f14b918099bcadcc4308bcde7c169ce8536a40d94a928cfc0968180a2c2a242c59df73ff79a03687998c421cf9a0e661630378779a4744ae2a6cd24ff61d7fcd6c11a4c8bcaf358075e96f864df0998ee98ee393b37bb38747b70bb7a208740959b45174a60153ee566e0f62528e9a5e4466186fa650 003835814de0d6441cd80a44e40350cc8bd62ffcc81e939a4410bb9c9259e30463c453b5 81c923fc3511cb98721ac68ba20a747834baf6c82bcb37c22ac58bd91cfcc1a0d449bcd1b915f1c59f4693e4409def4e +864647405c70939fdb4c026bcad53218ba1d438d82c9138f0f0ecac815dbfb242307cca52c84826cf6556c51082a23f14252dfaea43ba229f7493db2bf8ae9cdb0228dab9e25cf385b504b92cca94f813acceaa1f18de851b8936c4dfe9e4e17002f02dded6b4c231ea5e614ab46fcdd637b8c6193e8d0c2df1b3d883b97e1e8 00aee83dbed3b703cb6e60d51e373eb20e298ac005fa6a572d02fa1e6da0345558ad2a46 a94eabd4f43e5c994c336af6a425d5eb80fea854cba8a37c0d27d1671bc95f778e4db989210fdebe7e3394d1a139d922 +c87c8f3ad5c28a027b28ae5021dbe8d425f74181d519451f1fead7a1f9dd102fa6785b147b610610cb59bfa91fa363bb79ea602a7d7e1439f874c5dce748e5c320560c2d9676f3a948754c72b6db249478b7e19c9829ab4de2e344535d3e0b7c20c272f82556a280ef491524b255c4fafb9c8ecb87b0149ddd9d7bf6159e3337 017b65c66514019ff935e9d571a4e68e9ee4463b7b9a754b93f4f7741693f4399879fa8a aa601a56d07e887a100d595aa8d06e0e0510d51e394721cad8278b3e0aa183cfda134bd598da04aec895d6944c21d72f +ac7da7611e2ade20aad64b418a16e02e79ab4894d758550210eb10013a9b5533132be701f8843c840807c4167c38d21dff168d3baa65d5bcf285b73dcbb75819f8d7a20a849de335e19bae2aab2ca560b93d340731f291599a5b28afd7737460d291105cbba6d0290e836f6f6c1113d1b2faf90ac5de7c64e25206d79380a4ed 017d2071f39ba35515a8ec977ddd36ca15983e15bcda626f15af61d87d58114f4c80a8be ab939f98e670c7f80f7a1528e5053e01eb8b06f889b3f14d369cb13c2929948b9b55d8dc245ab5a97b4acd436e8c0b77 +5757c472fa2f81430dd920f39b61066a28c870b80e6c96f822f8f19b398c3574d159cc22120454dcd7e97be8211916e4bc8db365b2dbb99a6e597d06e6645046a0abdccbd06741e9c0eedf33cb78d78a540c2a390719acc498331e694e6b0118cf4f787b51c7b7237458a6149d6dbd0a08bae8097e919f970fde920485e9a0ac 011504659e12235855fe55220287a101e511d39a627f8a0d414446385d4a88f31507fe74 a0035b18ab6ff1906b155aa10bd08a33178d2f2515aecc66283354efd494056bf05d9db6e3448259c5f537f07deb58f7 +e350383d04af0f4081bf09b95d1d53040e7acc64e56b13b653df31dd119617b800e0cdfeb935dfa5d94f1d7814688d8ce41021810958759cec76560e1e5c0581456acd1a020165849b2203f1c11d318d816697f36a86b59f160faeac7dba71682d3c031d0d547725ef69cbaa28345512e38b75ab011911d8924b2d17a857a96b 016e4cbabb03215767249ba2a608708b78d7387be9e77f5efd2462467fa05e8dcde2c036 92b4a72b4d63098101969c1be52e78b53fd31cdff152585445ce4fdbf8356a210659f9e8150782a05643cad182e6137e diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K409 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K409 new file mode 100644 index 000000000000..94151b46a5b3 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K409 @@ -0,0 +1,60 @@ +f153cc61981a46d8a47d17d29ec157fa93fcf644beb84558db7c99c57fb131dcbc5b65581ced5ff0b29bfdc66ff703ecdd4290f7c353c02a3e6d6867f33f3dccd1a0b6752b8a35fa143f8921a5078af9c85b212564c5b795da9858c7955095938fcd10c21e35e1abe905e84c8b4bc05f2a06091ce876d9519b96951d08c7ac9e 0011c6528939672bed3e8c905b7ba594c3ce95f37fb28044f210cccd01dfdb42c10e8e1a0b5d6fc757834ca7f08e98cbc52b0edd 85592ff0ce6721f352997e09287cf788b5be88789afc61f9e0adeca984225926781cb2e90cb11c1d842391f7cc5a6516 +258c91524423b5c876432b1930c7b07b56eb5e3945f1e2296a4e5bfb9b9123f800ad195d6104641b1f1970bca553c2032f83d17252e52403a9381c1fc18eaffdf026f7537aa27d84c5e3d6e39e651a92a41139cec5181fe794457f556b390943093be719acd23fa1ddf7ff0aaf0479484a381a309b4f681af74bf97caef08c22 007e3b714496dd118d8f3f597961eec5c43d0265bf85723b0b9b0616977e0acc2cf686cb6afa6cdc19114e27ab000e762dfe467b 85160cb592ef956959bfc2828d04172fc2354b74c33191296105fa5023c9783620871c41675df2facd3bb5ecdc3c3b74 +a16a0d6fd57240fe88c7c36b9f7f9040cfcaa9afc4beeb8300818c5f90cce73b819a12c31d42af33146399cdfa4ed4954d068dbb0f1f342269dd29f1fe357e7224304b67b0f924b794780fe7e6aa9dfa3380252fe7177b43e7b1789718949b9ec1b943c83ed4399491482f0f59d2cb8050ab6f8b5854d76c50651428cd29c40a 00182d1e937b037bf7f84144f7d4c94c935269c9aae7d500aa459a7a0ec113b232dcf282908eee4c84b8106cd38cdc41db3f89e1 8d070a0e8501f845f796df59a2ea9b459ca3da215a96f4a00b89310d598c707bce9ede0c8b751bd2cf2c2123e4017a56 +d02ff569828fd1add21f6bd1c50cbdcd09222e458ee79fd5dfdba3cbb84e9d926fcf196cccedece77d5aa17f8c8cbf3a9facf0f02c71d5c1c8aeda9d75f6fd7b6f2c5c70dff992ef6e02c438fb3c66da5a503b3c39acbe2a069da457595b542190d818015d462670b0807c401e36b1bfe05baff3a8ccf8d1f5f8de7840e87993 007ed09428f460724c8a5225a31151e031d9949493fff5703369c401762345d002c4ce424294baab22d9e71edc4f854510cf0e6a 968cd2f1994ab17014f8653d3b632fe82be00e1194a99598c26d6eb0db8616e6ed47da8c1bed04287164012cf7145fe7 +57befce973b225cfce7f996fa5a1a43acd160681b88a87b7de04544eb7b6a719718f1ca7f559b6531bfc18fca3836d2be7f7a6e48387b7579a6845796d30e46f0dda9d82680f8c96c5f0989741adef9762c3db763cae2699cb6c112543635e20ed5cfb4b55ca2ccb32d2d13936085a8ff95ed658a54be73f80c912ccfe5f0ca0 00390f05b9619c27b800e99aeaf61ef7f6249367d5cfaeae3c7b523a8b29153eb8a77132f6c4412545a842d6deb7b7aea7e2bda5 89a75d9e471de7c1a60b2262a8d1a700ed28e799189365fb6a22bee1af0f2ff9657006983b36786854340487c96e51aa +4277ba40cb462860ca722cb4ee71c61836d2ceba18bc91f3fad7dea478972c6da0ebc02815eaaada1d1a5e93d7ab353855ccfdfc94a5742fe18daee2328871e06c1ab0a9a989d1239df2d2d27f96c415e7ef9a941f06c6790675361173cc229aac7045f49eaca207f59c497619ba32e932b5c1c6576812ee5b146e2cc7de5e62 0007d18652732596add3db31f7a0ce6020d03f3df58131b0c7c633faf619b8210cd309d6c0c4083aef1a1b6d2a756adad0bfe344 a73ed865a59d223cadc9217605eeeef00615cbd36b295efdd29df364a0a738ebbf305e57228dd0046f33111982c91ad4 +57ff6792ed4b12220d179bc0ea57ff217f322c85bd3676a681d32d7e4a3e0c8e891fd267df17caba5992f68c35ff670b60b4bbdfff82404f6ed996c30539bc395120f97d4d7a652eaee82bd8f9360bf8bb73748b8bbda9f9480eb54f7eaf2609d4259329e8a5ea020521e7dbd3ec56f23c849932cbdf2875f5d5c774a9d6b0c9 002a91244ea4623b63403dba807d60b914ca3b901a2523244c322f2f11251446d3f15e869d086ebecfa1a39ce304e8b5c8de23e2 ae91b57c12c9a9cf6a6ad066af46af50a2bc7435821cae92ae722a1a30acc8ba822d21a3149c5a7aa61f37d738c9d4d0 +f85113eda64478f460b60f8084220134933de049200a5f37884da7901471542e26690a5fabc3cbf9e679ade71b6e54d869bc136c3d34cc4a9efcafb777abf046b5ae5429136112a9a36a475121eb1f33f1f43481286fc1ada98a41064a1fa38c89e99a93065bb2a119348a9e452497fd5a0d2b83a66b09da9f47a0583732adf4 00068c56c6b5d50d1d4e13d3837d8c5e8ba2f825e121b63e97603fdfe78bb6899600ff0dc87b6b3b6868ad0d2f62b7b7a31603ff a7c01ac3f9fc6b7db046aa603ae06809356c96958c9e208366f6f5a25a39e109f1ef7ec0b2ffcb4962c94b181781391a +42811e9ee6dc509572e1cddbe5baf00afeb0c5c13e3755b922eee9e210001676082bc9edc3d78db2b5bebea7a2c0cd2b369226c2b8f83b28f33fb513407ab9d287d14b112d6c3be2493805ace5cf6fd366d03cfb28f4ce3f0f060880db64d6962e997463ba7c05b6fcd1e66babe4b94afc5c2d38c7050c69571d27b66ef0090b 003c88084f8b78446db431bd6e240a0c050813d2a763675b0ea869cbe183df697146cf29c03479af3d34587a95cd257027fbeed8 b7cbabce3a3ecc3bdd4f3b0bd3df9e0b1da6aa3bf6ffc5603fcb56087f60705a66a497b05c08dcf5aa0263cb0251da88 +b38f76ede7441ae0887e689d556f43155b38dab7cde487ce9ef9a46f2957c830d4d28006873fe2368197a6931f6fcaad755102686a457a7edccc8d344e2d2a9162e3d71d41c09a022539ae6d404955a6ad748231aee1f974d4f159940532fb3b1fa0254bfc5805d2fc68696856fadea386c542d3cefd1be3af04ca595e54be25 0051af7b63bf3297ae20517faaa1552f4fde65819dbbff6a52721611e5b7dc1242ed6e69768cdc37ea8cdfd1a5971f06b84b5803 ae6bc321e7985d0a6050a1367a30a175f2d578a5b6bc96b712d26e0eacaf94119d5cf2fe2171c1c875bdeb8b7bc28293 +356dc86cef7979148e995fc5abe2b14a7d5e4e42c9b3509b4363bb80c581a66f4e7e4aa53a4bfd37f9a7eccf75fdd726f348f6a3f779e6599f61bd1d668517f40453b39bcf35db0852a6a6218198f52b7ceda2ec55fca5abe8e5d93af9a42b9ae4de9530c5870211bacc27c39aa094013db703de2fd3121f08d7e97dbd4e8946 003d65bdec48972d03811b78150a06956eb22d337dbec5416bbd8185a6322cd8c0ff8000210dbd1326422289071cab65175f5d10 9785c5e19f177ccf3525f75f33ec0af25d97abe314fdbc308bfe8ffeb0ed4fb1492e1ff55fe1840b70994072f9da84fd +06fd39a50bf25e89f1071ff81fec5d1e35b6dd68990414ee403dfdebb792627b6a4ae3d2236c159e4441ff90b61ec87b1592c538515f0486b19e58583394a05e6411e69b4285d6d6589982ac0eeb2c912c4948789cad741183663fc070943389d4e9a1150b8f6088fc50605915e9e24b2d98a1f539024770e4820e14ae42ea8e 001f1a8b5f35dbbf82c102df550c72216a243f986f0325920f6186a16d1da74228cc02be6024c7411160c183c923c743354f9438 80d326fdfcec6252b5463f83b5695d71b1695e1b39d105ecc4476812cc9fb8da512376e5b1a12fb8bf792d06d2b31033 +6daaa41150ea252a3e966a338377307d909b95080e006f13027f2be5059d9208930c5a329994c0b794ef50eb059bc6c215f68cf42260bd410f9bd86d2ad5ab7179c7c92de4a93a5f6aa17de5aefea815e7c0b78a8cc53c21dc4dee037b29c9df4e12343109283ffd5d8a3b81fba1b5e95506c7e01ac056c86dd0ee23bc21af0a 0031dc621200cd174193d95e9092ffb86189c52cdbb9ed937593f2cde7c4a0264b9100e1b8407336c8dfb5520d28a18dc4e39a89 a4f7b867c0f0c18ac220d48d57164fea7d436bc98e90799e4c2b56926576c9519cdfff4c5122d38d0f7f14a0f84db38b +6378dd1c12c5197b57d47dc46a67949bdd1e0809004e94d49b0234126a08ad5bf8723ebfd132145813136d8b7dd096f56c34248f09a65c34f60c2f80f9a51b3795f3d2518b11aaeaf6dd45a323794080b78f85d629e5fa719b6ab0b14c78cd908befeaef0dbfaa08cec9318bbcb376d48b11b68735c9554a45293db5e9239ae1 0016e6750245a88340b0f0665b890459f8038e9b1366f2fc1326245a88d4c523ec94429f21869ce3dbf75126e58f77241c99efaa b254478bb2014fbf52edf40aee037ef660092d39115ede7f77c640c6b0068c01b40800d2f89b4a7fb53d6ab0630ca4ae +b898d0f9bd80e083fa541f457d14d853bba55b120424a95e1d9511c8833f48444329e0349d68204c4b4581ef1c4dee23ed0a4445727a72e1e6cde422f7c10ae132a3fe681f9d741fda263e73f7cdf10759467c9d76164086abf6780ad474772771eee22d195339bb8f6235e0d992bbe282b13ce4fe01417f507a2c4fa155e108 00788fabdafeebb72f6385301e30024b56639e629a400f9c50d402cfc9b5817844f06a451fbda29c7ece41dc9ffcfc625fe0ff0a 90ceaebea29318707c35f368b6a9855b4e6081e406e9a17074f21bf1bce5b80ca2a57466b3d29e620ae927faea470794 +dbe04561ea8579672a2b3afa94426a3cbc274b55263989d41a778bcb082da797d84d930ca847a481789524940701cd5f1d11b460bdac0bffb0b3a3abe1ab689c519700de85a0a571494ba0cfc3c865450eba7a9e916b7fa9df55e8a1c246c992e6a0b44b78274e008472bed8d8411633e6520e1a906c5d0c8aafd572fe6f1f64 001b8dfd64563dc219d6eeb53f2e3ad1d771140d0960b211dc1f757af5e297dc7548d6133ddb574711d466688f80dbd65a7bbcdc a05ca496bd4ffd7c98ba52651af6ea786c9a6fcedf50d466bd3a893a8cac2d857744e97f7a6d53282653af17946a34a7 +48a8300820fea2ad83c83f7d6b24192715329c3f159d56644e11ed25efcbd3d31600a813b909812987b97d1087e74a63b4494cc031c63492b6615e9d6e5b36f62cb2ef88b9f736595800de465789f43811165a5fc093ee6d776008739de8de2a84e878748641be8bd52e5b891c4145f52bbd46644852a43108e93d86352b2a3c 00422131829608ff730c24ddf7e8b4a2600eaa9681eaf45432daa7d41fe2fb488fd0199d431a1ed823801ce21f4f01a4dd4248ca af8dfcb70f470c1f584046138b23ac872834dc4628df88723aa885a38b67ac809f0fdc8ec87ec3a17a152c40d4e85162 +276e3a986ce33256014aaa3e55cc1f4c75fe831746b342eadb017676b0cba7c353b3a2b554522c12e6aeaf1364cd2eb765a404b3d0aa61258194a30219d76d2bfa98ad20e7e91756cf65e50d7914157f283f2ba3930c0ad3a97532cc747b1cb9c806fff497f0322025a3d02ff407fc7b5808585b91d95523c9d5864efdf7d983 00095ae8e4c7e55eb5da01acc05ecfe72a4dcd8ec152f1c8dc165014f70eb4e4a7861aeb2b96c418b2d4db58659e76184e013a49 a3a7381cfa612207d9817241f0bc477c53d532963a96f3f42a82a7aad128ff96702c561479e20911b3836956ee5b21a8 +6a4fc1827c3a7256faa8ec6a0f3d23559d6949f8cc20e7f76111dc4ebd59213951cbf0eadacaeb8862d6baa0cb298645e4314b1c303bd0d5e9893304d4b7fbd36ab05fb6a5edc3fef763e3a4124d61539eb616b359c5cb55b5e2bec50c91dd95fc39ddf521aa854216eb5a707819fa6f067b316a17a3b146e7cc2dd517f7d63f 0006f2075bd730f34df111ebda919167b1d3358ada32cd6747cb3353bcfb814a77ac70cd51b31a0e538539453bf9eaf9d8b384c9 a5245e88714617b8e43b59efcf6ed0aa1ac90bc7d49ac93d5da849263656953491046e87d089f7b7208358faf4bf7170 +4b088199bd8c94775d8ee508377d672dbf50f6d2c7370e99821ec8f9387492fb2eebdbea473ea18465565f79e2af418555f10c4a527e05a9e20c9c00b807dc8b350cd4ccc2d87e91f66addf02ce4f43597aa258ac6fbe9365cc2c8e8bbe5c884abc929710e8423cd6722a8f473bb55804159a92a3d8b6661a536b4fb9293bb0a 003887d284e9ad17d38bc6da9d83c192a434c509340a7f233cebb032b09ab7c4c6e8730b4a80844898616c9abcd16b753c6bb4c5 8820ae009fc843c6c9f754e4dc264f653f48756c8b8218903b62a8c6cfe4b27d391041efe17a82374d7aa71517aad8e0 +848a13465ddcfb2dc14f7bc0db0756832c22dde1e31e4d8b3ae0dd1aafbdf15e954889e95d3bdfd6e5ebb6171fad62592c23277a89e8ba53978c9b1afedfef7e1c3f6d9f31077530460b47834b30bbd84a4da601be988738aa815d3d7e72043243a5288751ee08b4815a017fb5d9bd55833698a0d526b1ed79da35ef0fac93da 002ea5430610864257c9dc393c3addcd0d8d5bc8aab1067643b08857210464428aa85cf1ae6c743fd2682255d4c8eaa46ca21e73 a7dea3990ed1c13e9a0bc869790f94a7800e043048f0469414a170138b79d62120b312aceab5f5b45c9276d1b2b184fb +d1850545c04ea65528849973c220205c35eae98826d169348970d1420b4d872ce233af1daa9e62f6a562544ae3a0633a954a493e9766dd5d87e47486559fdf86229a7c9e1726de21895abdcf2422d438f4ad98d88b45c56742694ad5e11894253270997c049f0f419842482f21c792fbe5613e2defecd485585f1835b6f4c578 0062c757c92eaef41f5d81169ec4968145b5aa2bc1d2a3a5fd000634777748ecb93677b3da12e3be33272a8f0a52300f4a5a37c4 b26577e26207dfc9ab9607508fafae9edd125cf1f1499d69777bdc4db5466b4fcbedc5e7820ddb3ed5cd686f774a9356 +421c9784d6fd507c82904e1054edf9bdd1efb58a0b211340086069ad38b7b0dd15c2345fa8767ef71254ed1bd5c35f742b1d3f4765ff9007a5477ba9e5d3d5a5cb5fab4efc1cad73701d4776c6c4343f42b5d94a9eb78ae428dfe5fbdd8e6ece09d5b75cf4346cf27db856352225ab04e6ea56661554fbc39916accebecb3935 0048a313c0c11489939fc0cffc6ccb9f179093c4e13141b92dbbaac441b7ae878c9d412066e95615174a24692555cbbe904a14cf 9849fcd742dea0d46be45ca2d430b8565d47b146cd80c693ec1b2cd0da273ec51b60cec6844a158b102c952aa5922aeb +7910bab15b6429947655e33a67f41b76f1d7b71534f8904d6a0472c2faded038565272d0b5f51aa915e0d624e9ff48d50ebfa2f09324864f26c29ab73eb39b436c5c459c7cff4d2b62992e3489cb4ddfc05d7366b161a463aa1b782641d93507de43c8cd0a0a0a9d1c644f4554e3edaf7fd794248110ca9387e73ae5d00d299e 0046e2adfe5d3549e1e6fa1fe69a7cbb4ac9b111c8903d544268f8318b0b47d4b78fe3e56eb5e639ad5382e7cd5bd4b2c3e70ef6 b38bc77f501ac161d0ace2edd373170aa9b8788012c9d5af7847451ed401cfc5a732f3ab53c8bade54c175be46ffadfe +e6fc96e060b956c25d50ad25443f3c30a12d199a47451a49ce88307201dfb15ed816982e8888a28daa92eaf3c5584ca6ab2ca9e14577f84396de2e0ac214b24a2279f5e7b344fb7387e9afc8f0a2b77a4d024a20ce6183499b17096947444bbb753d9b39e5c694239d28f9c454bb05468d17ab564ee6cea3741747ccb7f108af 00480103fd6180a431c837643566706e2b9597de0a1346a224d176a5b2c54aa4d064418ed654a5d39f4773fb509f86473ebb373f 82cdd733aed32840835fc4ea3648fb83ef460a6874a957297f3ddb2f276efc0827d5103420ec39771cc8a770b1d56925 +c8a8a0d41f35537e6fd523ee099eb45e1ad6ab54bed4d3e315e20227db03292e39dc1a91bab439c0d20e36e7fea6ef08983f390a6b5551ac3b4f1895220b2867fab95552cef9bd8702962839bd9b2c72772640e7d3be3c5889d226acbefdcb448432bc503e5a5fe7ae9ae7696c720a799f9882c64ae0385f656074dd8a6821f5 0013c489e8311c6bef02c8f58903b2ba2a98a27cb935d75a30d320af9a14fa3cbc6adcce09235a9eaf333dd05f4b2f1694985dc4 86013de5e668f9335743547fbc414e4ab7c885efa96773750dcb115ddeaaac632bef7f0daafaff6a0678e6f342941b8f +3407cd6d2845197cd7414a30fc3df7184da204222ffd65c4d16a12cadabf603de8043ea14f5e6ddcc22d3572dc06dec1a23cd924e1847ae285ecf01754e2d1247876431eb98e897e47412a2330bb32990f9714122109e94b38f82cfdbbf2eeb4c6f88f5dbf9f0ccb47939df8be321dcd9bfd9bb99cac9f94885fee7d443fbd87 002419bd2200f8e1d87db848b0379741685e680d9affe693eed49d82931030b6cb05d21a4965f4e1df2045c8513a8f574ca9f2e7 abbad862124e71e24a96cebb1a11cf3c38228589cc972cf5196966233d31d7f177ca0d84b6d2ced038804ed7105d94e2 +ad43f8440071285d01fd79244907803601aff4bc5d14c77483a87cd742144d41c68269d76c9a83c09d2178bbcbdf99f927b378497ffdc907a75a3b0ad019e69758dfffa480871eb6e1e17c8539373de611a557fad120d0bd147f8debe5f09a02e56fb607e9c1253ed592071f042e42fee39775b407225a2b86a950d81bb7d7ef 00722951879a65bfcb414e11712ee9431eeb32319e0ff28601112f89276ffc2b96eb65c7fd77d023f09914a53e2aae2c84652bad a170bafd5f12e4996b65f420f361ad3bccc4c9a493f44bcd5b0bb18cdf72cf0260d8c544d3ba6c9a163783fab752b311 +d61a3765229dcd0b4fa6c57280f851ec2bd54d3ee2436935cd6d94e0120d0844adda163995fbc4cd9d7275da859ad8ebf30af9efbdcfc31c7c9ef42bce9011d37cf9d15fb018e117bbc102f7d05750e5072f73d02c2f45509a55627a78cbd9082cbf36807759d1fe2ecbb92ab30cf28434941712d38bdd100955d611987b5968 003f5b5a772d24bd5454bf26759dbd433fcc7bae4f5c593664c4d75da0cdf9430d7d9162bce3d7f6e13a344259da5a7d6a1635bb aced76d64efb77461147fdcce9c96658c1b57710bb6f9b15982bb0d367be42b3178b2a49a0befa1301995b26f49829bf +1f3c23636414ced48fab6763eed5b22537968e6bf08c178b3d31fb1f6ea773c6979759701d94bc1bee7c354272811edec58eff50c93331b22723d460e56dbee90466b894354777b23b13a37d15a84c762caca70c01518bf34d0c2f072145d274b3b6c932b48bd815fe81161d8507ffbc2f783bd212c29b2887af6d2ffa9d2b4d 0046bb4a141c9099d531dd23ac440eff1f5b10f7cf34920b6b702311d490d25344c665ed5211d401def24986c8094165d10f8934 89ffa386627074afc97a30277d8f3f927ab28f7edad038f48b0b8a03e9a38ab0f047f7ee6c3d5fd9d762564c24a6906d +ec69f2937ec793aaa3486d59d0c960ee50f640a9ce98a3becffc12d6a6c1c6c2f255d37d29f9b4d068373a96beadac98fd5203a9f229bfc70bcd449640165ae5128e3f8d057769e28356e73e35d8e9af7876f608390090892c67391ddfcc1c332aa61efbf72d54bc615998b3be8ab0a9d372784bea48c9fab244482c75cb2de3 006f2c6e9ea8109223d9a349fce14927618fc4fa95e05ecf9aba1546619eaeaca7b5815cc07e97ae8cd1e9973ac603f84d838393 940ae59682673a64a94fc8f5318d3730eeee8a3ef6a38fe477739b008d7ef701cfb58459727985e84f3d2218d1cc798b +70e11efc78d7f079ae41ac3c31c96d3220f4abfe23814a2a4a78d9b1a25e838c3408bd416062e4b0a5cdadf0c6e16a11e00f59711b417751f5e4b43ecad99efbdb2a81c91a034e89edc94eb552c3eba62808563cdf64453a1db07daff8742aea4a9fa738e1322da316b26dbca2954b2bc0de6da7518d28e6677dec6ba8af4285 0004212b7fd913d794fc6bb33e0276e349c052c969ecbf6afc89b28f75a599a9242acf74dec9f374361ba296ba42a38407f9b7d6 916979789372690d6876f955536433d1c802238f2d01ac4da3248c146158d1c327596afa2355b6c51fcf58015dcfbbd9 +d922fa515e3bed60b517a2d37cafe4c041e5ab4b5c8d8d4011bf9fc4013dd8abf7add71fcfde5e71d6abe76bd0f749e960cbed55711c87b5629a2c39cff48ed7d0feaf5cc4765e576a4959521f9a45fcba0dc65ae618826447e02ce6e1cab5ce8d6c96c3211adbb0660de7df7453f3aa726016941d00d8ee536cc106a603d126 006baeebb5ffc89c94c3e8b37b9b0904e7c4b251d204894655bf3b1235710215c29820b9d401c9ca7df1404d2d62d708aafe208a b939f9aec9c43ade9b369ede043a7e8ade77ed6b19263299789ae11b085f8134c3a9bfaa6ef184b2d91cd52163251a46 +4f64d0f6bfc542a0d4347576935bd68ca88524ead03b8d2c494061d0658e6c3e14576b5bcea5f2f992f54cfb52b5c7cf1dfc517205e0454510eef1b7054a8cd06ab53ed2468193f98ff0dd62faf076549ab2a270f259276d5729996c120792c6f466a74ab65035bf38ff2c055b43e2a8b8e2449a2375ddbfc18242157bd905f8 0008e5f66ba53e7caad1feda122a80c32c82d2c32a7237b8ee8ead44ea8f2f01d77c7056b9dd60b92d051f060da8532c1fd0e8f4 a58027816ded24af5d6da3a1ffd97271d603cb8f1664ce479f680ca2724ff363a6849f576ce2dcd120361b8b3f1e01ab +7047d478ec5282d55db8c19c97af10951982d908c759ff590f27d57e2664f08d526cbb2bfde39bdbb1aa3dca5a8d3feb50b868be6651f197abccc9d8040b623de367e2ea1d20ecd302afb9e273f4be9f3f64f2c2eb3f92d5e0e375db6549da2a589f0604bc7146562ccefd15995a7c4208f640e7a17afbca69cda4e173380523 004ecb22b44e809f89b16abb10be062c89b41ee34e110403e42a20ce59a99afdc22f6f6dda56e1d9d1b8ce1d057f390db111def3 b425762048c686968e863b29bafc7dc4503f48a9bf1aa6b84ddcda6c0cc889acba6d840da00705c5b7afc5a2deeef2b4 +1a8384b4771a410663e56eb36c5d9ede8d161a8fb0e31d3f74bcb017b9e31232bb2e2f4c65a2d85bcd1cedd93ef08d4bb4af0095731574ab3f2762788a1ba3bf0ee46684da8d9dd384432fee99ed3c69213d790a5d81b351063eaf2bda71ca4868ac36be1b571024a8bf09039b347fa996d5d161078314e24b7d073e05cb3d48 0051f9500c15ae73d6d479b9f3d2caccc2039d8d03820befc2aae3bbaf65d59bd9cb3c4e3aa8bed5b3acb70a5566047ffad80729 9589bfb5a0e614cc8c850f2bbbd17d6b6e4515e9019a9166df86780037ecb0eb30d30503d001d82efbb3254613136c30 +43513d6dd8bb0af7a6f5a2b35f99957d335a48d54f2c4019ce9518b35441d4935518976ab1df37110b5b53532cd9e2c66d9f87ae7f683d7efdbe1775a6c15eecee84c6f879999d0706f6779dc158c111fe8d7201983883bc8334f51dec60004eb1087347bfdab20f8f2f260556681e05fdbb8a6139857fd3bb2df5bc1f2dc143 000cf01dc4462cca764f4f8cbef48c51980737b9b98d1384b8de9f4c733829db7718a9b5eaa46a8475c2144fe4454cb8eeb0a443 8e217734b3e83790554b26244f40a65b1ef4fd2f1db6f2cd653b13df3040eb2adc7a2c4704eb219dc083ffba01d37ba7 +752300bc5066d0efaf807183a41725e349907b7339d77c79921ead3c685b616b0eb97e708f3880fce0136c510c8cb53b22cb424af6f1c34633600939a0647c02d8f9601f9416f1d24a51657241fb559c25dfba91402cea43bca1a13718b3945b048725f3df560e6717cfc6ebd894e29bff1e0c7763f15b8ea93e67385f059598 0063a9a565497974c6dd459bea0d1196d74f263f333c31b7e8591499960e1cd79e2ef4cc8709f6d54713f873b16e7b0be42f71c8 91e1c9aca071a6c6b8e39524533496c6311160b030ed38cbc614746f9751fa4d70411da813d4c3a4f2014d1582c467e6 +f620603489944769c02e2f902c2299dd5f32b5fb463c841b7e1fc0249a85d2c31684bd3daacd97de8291c5d39e84d6e59d3dde1b30c181bfe8d31b8d8e080bd191690a67fa00024ac8c1b10981b40d4f88789ecc58fc69b15417fff34834e23453bb9933a43d08afab74d056f366b40ad167b51ee5f008db151a12b467d3eaa2 0041074dc186193d30aac7cc6d269b938ab40b257d095e54ba79967a377a91b8f73671470cd07f0a3d1db7cf0a31ba9070625e43 a281f6eea08e7da60445d1759b5665706c3c21fed45196237440a82de012ebdd2845f06ed6e8d49066c4578e2978f94a +5575f610762b42ce4e98d7bcf45a7a6a0d66ec7f27d6b8b17f1961249d905bc7e58e2ce0806d467f106b16285dce4544c72666d08b5e2276cd0c4e13187cbda8aecf57b1855afedf8fad39ee4fe009f204e60bdbec79b123456ec2d85631d382b8a2f2c7634af3992e4707f7b4215e2c9d3b0aa8fb08267953883a4213669d33 0010820db54ccf0226161aeaee79cfd2797f87702b4ee91adf8543b3c9e79579d0df8a889e366ec1e0718e039b87a37c24d620e9 89599c23b40799880777afd7f37b9f2113efd2e5f27f9c50ca3e1d1e2592c0c4ce6975e1427227138c798e764d56fb01 +81cf067411dde2d0ab04fe5fa1e28e6975cdcc571588de60a35bd956a535fbbda4affd0803d244f3f7e6902a2c9a7ef2488691b6bef7f8ffb33be09ccae4c5285265e4957f7928ea5cbabd6823297f59a7cfc9939a49f26bde74c4c69e2d38c1efbacbcfdef011213843158072be84ed3c1781f67a0e2d4e9ba76a585c17fc0a 0059d2a06e8bfd5e14a9bc8777958b85be5e97af892d2cdeb0ecbd2d5017952b5042349db5fedba2e26e7b85bbb31ad313d99434 880f435880c5eb25b64f567bb15b1885486b4ccaee47fcdcfefeba8f5098812cf08f8c13cdf3dee38276319627033224 +8ea18387940035cff2f37278d321b344231075db43c7fa7fee9bd3fdefe5e8f03e7af9deafa1022eb108e19ec11fae34536a4fbac2e8c8139a081a997c080cbe8f3e2d2a72ff26edcc5338b21372fa1498e439e4d9bb12d51cc539f859047957b1b1f1fc30b90231eb06b365a4d404a1fd5a0e5cef171fc95b04d0b557d78ebf 00405590893cbbe18f4ad99df28b5f9d17f8f1882269aff0b7eee9392859d68927a99c942a3075269ddec6d69c0df2d76ab9d801 a68fb52caf55cbdb5c22ff70edd12182a0aac77d495548ba865f8bf96372e64445cbbe1835d38c1ec4d6dc06fcd9beb5 +6a253c1aa17b2b1e6624afc8e7456d366ef5b1bd78e740538260f395481148a64da0b6a58cd53d7e06c691beae1a616547cd95c4d259a371e51c2c0e334c8a5311ae31e4c7af325686ff9f7a36f731010ee1a9b8a29169ceac36a060dd23611dc9713c615424888bb574ad5f5755d7311bd169336ae986c977a394bf16487c4e 0062bbb4f565aa0f23b88ab9029d33b995729d10fcfc33ba7c4051e2fbc72f15636a834e3ebfe604b927cdfc89f53c57f36890db a475731aee1381ea2bbd4014fe3e9ae2cb0db6597f01c68a85140d41139d56d70d3818d2b5b1c8d2858b4390e11b7229 +0f91d0f0139faf3b90a3d4bebd7e96ff6bb6f90f6c68321fb392637d8ab2a60d649a7b7364ee6e4e274e1a8d342caee36cc11c56c54247fb0a8e8ef81ac4322b454dc9a195dc54567bf47ec8d4fa4cd32e76d78ea2d08bcbce3edbb68fd8597e56d5a9f2df4e47b2701046df89615961db601bd8204584a6a6cfbb627e2a1190 003fad7031cf8810544a3e4bd1382c0a2e22c5a9fe4804ce67b27591fc516ee81dbac841d399327168aa6abd79e2b5ef85df1528 809a897512f1cd0e61ac35e295d59acf12b137cca5f3a8364b9f87f86963ad6e385e17477a7d90a6f971967829e1cb80 +50c17c1fe4dc84648e5c3c3ab8f7c971d4c58d8d56d2b5ddd92e35e6792111ed8dac7644ac8a07ca8bb4e38e071aa47b22ffe495e9083f9bf781ac1b5fba571862c909c7aaa7b8d05ddfb7ef61c99700de734d5658f44ae9fc908c85a2dac8e7f854d6d24be805fcd7f873a91252985c5c73129c60177ba8fd99daa87b25a073 003db41b4f637fe7977c90e4f1a21799baaddd1826c667102414877138436cfae1b9959842b8097b5276f15f2b982ee59df263c8 91eb369df6b95781361defb04a1cfc46b289848e65e45b859b954ca10ab6e947f1ef45066caf749c7cdd73f6a55e1ba1 +3583a3226e2dc463a462fefa97024e6e969c1b13bdc1d228e2d7823d9f7c09012390c2535baf086588000e908309090daac6e6d2b06d2ede6fae838ed47f30b5b481185f607a3586f6dea47c8f84e9d3b96d5b0ebae2462fde1e49d84d36658e87dccf5e30c0937feefd8862dcdb1a1ca373f6ae41641502ac54df6633a8cec1 0065b76c6093d9c49591293471286df1a4444e60d9d06cfa114e175afb5f119d2abeb273b0596019a0ec5db5b5869f2cc827b364 8d846479aa76c14888c376c809bbbb62ee6b01f7a6a3f6818db445f457f9528a90cb7e4bc09d63e2f6e67cd0cc31fe66 +60ca58462d53d074b370127132f4e59f5eb8d15594dc721a94286afd082a8934e52462c9c1c3910f8b50d7aa3671dafa5972958d876d7992467b2fee3795a6f9d8a7bd3003a8582ea8c003aa1e02c08ab6804d85bcfa13a815d75c938671f0af0706c68bc70a6155708ca755cac2fbb68b2952208d63e0e2e3d816f04c61bc03 007e9993f3fc1fdc4c376ef77ecded96006ac1159740bd1b2dc6ae3d97e15a67383f1fc931e460b9af3fe14a54e47919667ed06c 893b5e6b290ac1e3359517e146cb96c7f17e36732467537779cf99f96549b2603725c4ce25e7e7ebb3028fcd1a952ea7 +c749f9bb92ca9957ca6d0124206ebf65e860ff38a225e241950bf4526cef3f4fa9184ec83f71f813fe852dc08eca6b45b14fc7f2c6a19296529bfda007efe9d0d26492de2a902b45ed39603e22f0a763dfa5deadd97ef6feb859d860baa2cfd1d066c0be0f9f4e0e2fafa69cc51b12e814ad2e33b0acc0bcbe1df8cf018dcd4f 000c11e2979498695c660a2bdfd105b115bc4ff8664ea15cfb40c725406c6fc9a13027bd1d72ffff6258f29e4e19b845243444a7 8f48c892c6a3b95c9cbb8febab9124c854a1e554f84436d1a5a9f7167740d016004f777579032a5a552c75ee2c5618ea +4de8414780ea20f7943b1f1adae5e3962d96e828fee43bdbf2831bd71bd25df2976a3be37a7a667c7fbe1200de578920090d131a750c9bc09bd95b261234ea8cc25423c4ddfff5656d6b32da6e2f6f530e6673a8660aeca31273bb9a3a21bbd7031a2fa71ba37c004d3d1c64b2c0798783e47b2efe1a208959ac16e35d444245 0068dfc23c6635bd1fa1076dcbd456ad6e8df7ce7c1370fe275803befc4ffad007fd062a61cf1d50b93aeb9afe1aab47a65af82a 8bde25c6974d406b6015dd9a430f8e052dd2e434599b2cfcf21bfb71ed903af8387181c1107b231ddc26e27177187d38 +a081d54232f84bb19dbd52ec3812748e2e6486f6cf1b177b27929504ca878036547eb43531bb5b3edc81bfe105370427e92831d2239cca0106d031d9fa8da9cf89c6fb6401377d5936b6329ccad854e5567181b8f16a37c35f333eaa0ffe91d727d183fbab935fdac2d5670dafb3fba59e4fa2df1746c58dd8360fa08af7f4e6 0040807fb888e1d9fd33604546656a493629d94d4a0a9de2608962225ed158167f9e2438abe2d12a11e2adb6c2b66ed78215b0b1 abb00354c33ae9f92da117516f7aa7a53e201fe936a5e43bd60145e321762fb2ca56a4d77b7f873bf0b83c9403aa65e5 +ea60266f1538565b3ff42fa4bbfe319be070329059c52c8bc04a7da2824f209c1145a05e551ea59ded8ca8439c328f6907da4e81d658937df614be98c7b8648818ea80ef40e49aaa4431f4a211d62acf2611f5d60c446b2b25745078c643859be1b12b3141a09ab765dd63ea1f2a2df015eca0840087a5db378c4c4cce76cba7 0033bda0a02badae08fe40c239b9d59e5bfe1c4d4b9b7a5acda6790bfd77ad08dde5e93a2da80ec54a7f88146d72218bbb88aa10 b0d31cfd0cf53bcae7df01c74a1cff5c05b14ca634fa0fbb658f87dd409ad65ce6b6625eaa64f3309e1e0516ba511bc2 +82f38c9405ef0d26bcdd5b3fce4fb0060c3095f61403418e17c337933f0563c03691fabd32ab5e896c593439e7492a9970ae325c67196d9e83fe0f9780409a930326f7e6efae035ef8c321cb9ad12461edd5cde66c04739fe079db65406b3c2d22f2d04b1a4335285513d4ceb901d2ca2ad10c508302266c2cd6079ff14eff4b 004ff431769d26b8837d3e1295f5464fe82be29edefba76323e92078a6483ea0daa96221549102509a1bdcfd46a5a2e5de10c39f 8933cda966398292d3fc2765fb1a1f864c061f311cecc342285adbbe45c915cf3f8322d034600d913a65f482fb9ff018 +d8506fab4f681ba4ae86066aed447571eba4fe04e6585fe3be6af2ab1000a3da68c5b0c711a85ddf3a40cb7c8944eef81f2094650459e14f5b848e6add7e580b0198070f873eb3ed5d0728eabd92bc1398764b94cbb4cdd7cc2027b9762dd10782658cd9e8a5022ac062fec535d892198c8a387b3d2b6f7c92b1af6ab7dd9e4a 003f85ca1169ca7e9df44cbc6bc7d2868c9d94e8f8b699a42ca492dca0914eb5789a9032218dcef7f95f959c9554a1cd83360439 92f754a342c58ceccb6c4822b80cefd80cd1d11ca97010ef264a391b9b864bb8193faee1a95b8802f61e74728cc3cb7a +b3f30d34f252a4c26f396079e773142bf61c0981d912333ade3de4e27cbc72cd8a16b31807f0c46116f87accb854487d83ec8c6a61565e6fca145eab70048245db08616779d7047db63aabd90dd15acbb05eaa510072c151c0518f1b34582b95f43ec7b9484b2993c176de79e84566764467f72392ef31619426d159c91816d4 003a97deb36d68f81f50c8829d412ee5de7f9d775633cb69c09dac558182039e275fc258240517a7c4aa592e364765321f27cb12 a94c6ae5ffb1c5a720b0a522631dae42846cb2bd265c6120bfd0de4318dc5ecfb9f62ac27595b512a83a125febac4f54 +0fb13b7c09467ad203852738eda5ddd25b17d330e82c279630b0e1f0c86681f67f6e537fb00da9419114973c8559306de58b0387d86e52d821d982a60769d2f15fd5ac2ee6dc55d8ac04ee247282cb2866b8cb8b4d7b4b6cfb33bfefdff09a73d727193e5fb939ff66ac5fcb644a44f9083a790888cc538c5eb435243c6a34a8 003b1da0ffed24e1a3b5ba22bd684337f6b08053591620541bdad50c761d66201a2cf21a4cc636426456525b598e96baf97d9851 a1456aba61424e9039d7c662d4a47e33201d9f1199cc9b07bf49303542988ff630603abc93e8041dbe6278d8263def9c +f9b8124281628cf4e1da0cb4f021c8d19d815644cd80c7c8de4cc62722904ec4cddd26cc4891f30b15098a25ba6923c6abf4774deb6e1883fbb409862f94467e75a725e7154be860fd58347577c83adbf18535c54b102220197afa062cc1c84f6094490ce488af4a08d2c5b808a2572e18a59de96c87162f88413795351cedc1 0040bac7e0d3b54c7753c79d43469e310d876015d948fac4e3a9765444754476af72330e88d79ee6119697aafac8435ab5690754 9700ba22b064a6f4b67fea4f20ae30ba362fd365b39362537a561f090cb6b72401a6363148aac303da97916e08594898 +4e3cd6100520db050af0daa69fe3cfe6603a223d4f2a6318fc5836db8640d4c7fb80bb781302036d2d6fb8e552b4eaef3133b98ba2d36b9ef0b86243b0391413c73d48ecbf1d19170f1b3b781b35ffd316afb1d55d1dda8e91eed5553780cb2714a93e7ece698b832e853e2589c5ba2b8a997bbbbf625071ded66762af8cad42 0025b7eb3bdefba3c5134438caf968f615b315204f348006f82e8d61057a8a8a853230cf0500f9d0b8c1551a59b9184862dd2ed9 834150fee56a46cefb5fb02b4d048a08a45f9faba8f02e5eeef908681ba017684e2a6d3a4ca44b421f23a87a1103b7fa +5411708381a65bef4381c9e13a04cdd5ba0c15829f7f25ccadf695f635384d8e4704cb562741747831b33852567f42fedbd190d2980f1bc921ce01c17d659d4bdd7eb787b3927fcee659dd3b65132496c687f2249272a473d46326e66b3cb78dafbb522390162c168f73bdec88adb145e6afecd561979846ea4c8cee38dc1686 00673b3a2985c95904732632e5d988d8d437a60db13215bb6aa880b348f011c609a1e860461427a8cf0d622abc47f910f5c97ffa 8db633ac2b2ea86f7bb2a17892a15d1ac8aeab7657f6dcd3c6980cfa5912c1e4f2b10f3ed2eefdc13bf5a4399cacea8c +23757fa60fcabf543e603d8b31ef0cc99b3ed16b4816a84e01dbfc858872fcb79fd03d2f8a1d4f28c25dc42a39e20c34f81ebccda1682ee9bd22fe323e7f8ea90cf4a2a6ebb634cd1153cdc35f7306f28a2efd822bf23131baa1543d0ed5ab4c8168d3199983fbee117085f90550ec3ffa2b06070d3add1d707fc2593285ff58 000db7dcac414010b816236cad584dabeaec1da76c97182d1b62f87bb7fe2946a64d10430571b2b29ccf2ef72c969a9f045f1f3b 96f608876ecf545732f4bd911e198e8afb1d1a378532138e7781281dd56933465716547a820fcd7be60117e25f7f6c83 +b976314d2f066f8893307a726f450dcf2cf865c170e90e6908ce9787eec48e1e2119a731b2bec3c12fd4e6282a393774251bcaef91af6ce57c63a8b45bedd72ab862cd169b7c84b8f6a72084ff823a96f2f8eff3483a7ebfabdabf0998377c5a6836d88135cf61c65a0ca7ca57727da68047dc635c17ad13731035fe9a6402af 004717efef16e1ae267e155aa1daabafc68515aa391dfeb73c13d01f3132bd22c984228dddc4dff4c39979e7585acd3f730cfcfa 83da00615113ec75cd18f42773ab7778c6accfcc230c18a4d91f00f1a1461d4e972f53c2fdf7b965487599bbb2fd18e5 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K409_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K409_blst new file mode 100644 index 000000000000..b0cc17b45baa --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K409_blst @@ -0,0 +1,60 @@ +f153cc61981a46d8a47d17d29ec157fa93fcf644beb84558db7c99c57fb131dcbc5b65581ced5ff0b29bfdc66ff703ecdd4290f7c353c02a3e6d6867f33f3dccd1a0b6752b8a35fa143f8921a5078af9c85b212564c5b795da9858c7955095938fcd10c21e35e1abe905e84c8b4bc05f2a06091ce876d9519b96951d08c7ac9e 0011c6528939672bed3e8c905b7ba594c3ce95f37fb28044f210cccd01dfdb42c10e8e1a0b5d6fc757834ca7f08e98cbc52b0edd 8a473f80d18e81a5605ad53e04168cf84badd9c5269bf0a1d53d07854a04ac9223c143a02f70686769429091daafba95 +258c91524423b5c876432b1930c7b07b56eb5e3945f1e2296a4e5bfb9b9123f800ad195d6104641b1f1970bca553c2032f83d17252e52403a9381c1fc18eaffdf026f7537aa27d84c5e3d6e39e651a92a41139cec5181fe794457f556b390943093be719acd23fa1ddf7ff0aaf0479484a381a309b4f681af74bf97caef08c22 007e3b714496dd118d8f3f597961eec5c43d0265bf85723b0b9b0616977e0acc2cf686cb6afa6cdc19114e27ab000e762dfe467b ab8b92eca0e9c248a88c9362f58a1ec248048c679977ba6acfecc6c305595b140bc24dae7ceeac703db1d6ccc26241c8 +a16a0d6fd57240fe88c7c36b9f7f9040cfcaa9afc4beeb8300818c5f90cce73b819a12c31d42af33146399cdfa4ed4954d068dbb0f1f342269dd29f1fe357e7224304b67b0f924b794780fe7e6aa9dfa3380252fe7177b43e7b1789718949b9ec1b943c83ed4399491482f0f59d2cb8050ab6f8b5854d76c50651428cd29c40a 00182d1e937b037bf7f84144f7d4c94c935269c9aae7d500aa459a7a0ec113b232dcf282908eee4c84b8106cd38cdc41db3f89e1 ae7272c78d4534dbc4b8afe86aa32d2bce209f0489990d08dc6a8b78fc2f193c82e20666105d2d9d7a462757f5a1b494 +d02ff569828fd1add21f6bd1c50cbdcd09222e458ee79fd5dfdba3cbb84e9d926fcf196cccedece77d5aa17f8c8cbf3a9facf0f02c71d5c1c8aeda9d75f6fd7b6f2c5c70dff992ef6e02c438fb3c66da5a503b3c39acbe2a069da457595b542190d818015d462670b0807c401e36b1bfe05baff3a8ccf8d1f5f8de7840e87993 007ed09428f460724c8a5225a31151e031d9949493fff5703369c401762345d002c4ce424294baab22d9e71edc4f854510cf0e6a a596b3665cb8eea475938dd94f3b9ca79188a92f19b849c4d5161754e6bf807803b6814dccda02c2fbfe57be168c3b90 +57befce973b225cfce7f996fa5a1a43acd160681b88a87b7de04544eb7b6a719718f1ca7f559b6531bfc18fca3836d2be7f7a6e48387b7579a6845796d30e46f0dda9d82680f8c96c5f0989741adef9762c3db763cae2699cb6c112543635e20ed5cfb4b55ca2ccb32d2d13936085a8ff95ed658a54be73f80c912ccfe5f0ca0 00390f05b9619c27b800e99aeaf61ef7f6249367d5cfaeae3c7b523a8b29153eb8a77132f6c4412545a842d6deb7b7aea7e2bda5 9514fd1275296b9ffdd8b23087ff2b8b21e87d48529826eeae7fc1e5e7cfe9bdb4eae4ff8b7fea82297ea12915990bcf +4277ba40cb462860ca722cb4ee71c61836d2ceba18bc91f3fad7dea478972c6da0ebc02815eaaada1d1a5e93d7ab353855ccfdfc94a5742fe18daee2328871e06c1ab0a9a989d1239df2d2d27f96c415e7ef9a941f06c6790675361173cc229aac7045f49eaca207f59c497619ba32e932b5c1c6576812ee5b146e2cc7de5e62 0007d18652732596add3db31f7a0ce6020d03f3df58131b0c7c633faf619b8210cd309d6c0c4083aef1a1b6d2a756adad0bfe344 a002fe94c53dc06b94374f7ff7276c6d57d6eb9bed0b5728fef25b3f9e1d6312c8aa024a899bedd58d3e5796e57ed361 +57ff6792ed4b12220d179bc0ea57ff217f322c85bd3676a681d32d7e4a3e0c8e891fd267df17caba5992f68c35ff670b60b4bbdfff82404f6ed996c30539bc395120f97d4d7a652eaee82bd8f9360bf8bb73748b8bbda9f9480eb54f7eaf2609d4259329e8a5ea020521e7dbd3ec56f23c849932cbdf2875f5d5c774a9d6b0c9 002a91244ea4623b63403dba807d60b914ca3b901a2523244c322f2f11251446d3f15e869d086ebecfa1a39ce304e8b5c8de23e2 ac142ffa86eb29ca0c1b785f73a503453ffd46b3c1fb1f22f6e34963c2e08df07f54d1d3fb2438acf286e3acfff611d0 +f85113eda64478f460b60f8084220134933de049200a5f37884da7901471542e26690a5fabc3cbf9e679ade71b6e54d869bc136c3d34cc4a9efcafb777abf046b5ae5429136112a9a36a475121eb1f33f1f43481286fc1ada98a41064a1fa38c89e99a93065bb2a119348a9e452497fd5a0d2b83a66b09da9f47a0583732adf4 00068c56c6b5d50d1d4e13d3837d8c5e8ba2f825e121b63e97603fdfe78bb6899600ff0dc87b6b3b6868ad0d2f62b7b7a31603ff 8b56044c36eaf337299fde955aeac5bbfa86c13543cc2605ee8e047ad0f750882070f34a9716160da6490e8a5d0e59b2 +42811e9ee6dc509572e1cddbe5baf00afeb0c5c13e3755b922eee9e210001676082bc9edc3d78db2b5bebea7a2c0cd2b369226c2b8f83b28f33fb513407ab9d287d14b112d6c3be2493805ace5cf6fd366d03cfb28f4ce3f0f060880db64d6962e997463ba7c05b6fcd1e66babe4b94afc5c2d38c7050c69571d27b66ef0090b 003c88084f8b78446db431bd6e240a0c050813d2a763675b0ea869cbe183df697146cf29c03479af3d34587a95cd257027fbeed8 b10d6f80b487924db742b33d51beee8fe811c6fb24a535b85235493a1f617027f7465ec06dc83359e6b2c680b064a031 +b38f76ede7441ae0887e689d556f43155b38dab7cde487ce9ef9a46f2957c830d4d28006873fe2368197a6931f6fcaad755102686a457a7edccc8d344e2d2a9162e3d71d41c09a022539ae6d404955a6ad748231aee1f974d4f159940532fb3b1fa0254bfc5805d2fc68696856fadea386c542d3cefd1be3af04ca595e54be25 0051af7b63bf3297ae20517faaa1552f4fde65819dbbff6a52721611e5b7dc1242ed6e69768cdc37ea8cdfd1a5971f06b84b5803 a27904990093274e385533194847bf1ef27e5a90e896a0eab9b7ea7382baaae8a9f963fb403ed784b7f6a9f6c651017d +356dc86cef7979148e995fc5abe2b14a7d5e4e42c9b3509b4363bb80c581a66f4e7e4aa53a4bfd37f9a7eccf75fdd726f348f6a3f779e6599f61bd1d668517f40453b39bcf35db0852a6a6218198f52b7ceda2ec55fca5abe8e5d93af9a42b9ae4de9530c5870211bacc27c39aa094013db703de2fd3121f08d7e97dbd4e8946 003d65bdec48972d03811b78150a06956eb22d337dbec5416bbd8185a6322cd8c0ff8000210dbd1326422289071cab65175f5d10 974d43432f364a6934ff114392f45ba687c2c09ca54502d7a1cc16608627e99d08534dda71be54baaa8b32d128b56adf +06fd39a50bf25e89f1071ff81fec5d1e35b6dd68990414ee403dfdebb792627b6a4ae3d2236c159e4441ff90b61ec87b1592c538515f0486b19e58583394a05e6411e69b4285d6d6589982ac0eeb2c912c4948789cad741183663fc070943389d4e9a1150b8f6088fc50605915e9e24b2d98a1f539024770e4820e14ae42ea8e 001f1a8b5f35dbbf82c102df550c72216a243f986f0325920f6186a16d1da74228cc02be6024c7411160c183c923c743354f9438 95bec45bd6de8c449c484282935d0f7cd814f95c3340d06f0690d07334151c8c4d2dd597aa5a51a2d0dbef9c26d033c8 +6daaa41150ea252a3e966a338377307d909b95080e006f13027f2be5059d9208930c5a329994c0b794ef50eb059bc6c215f68cf42260bd410f9bd86d2ad5ab7179c7c92de4a93a5f6aa17de5aefea815e7c0b78a8cc53c21dc4dee037b29c9df4e12343109283ffd5d8a3b81fba1b5e95506c7e01ac056c86dd0ee23bc21af0a 0031dc621200cd174193d95e9092ffb86189c52cdbb9ed937593f2cde7c4a0264b9100e1b8407336c8dfb5520d28a18dc4e39a89 93855fc18284d7e89cd85bf3f14183d1b120199eed6ad8630d8f93d93277bcc4a53ab88daf4a9d93b0230848dda7d2ed +6378dd1c12c5197b57d47dc46a67949bdd1e0809004e94d49b0234126a08ad5bf8723ebfd132145813136d8b7dd096f56c34248f09a65c34f60c2f80f9a51b3795f3d2518b11aaeaf6dd45a323794080b78f85d629e5fa719b6ab0b14c78cd908befeaef0dbfaa08cec9318bbcb376d48b11b68735c9554a45293db5e9239ae1 0016e6750245a88340b0f0665b890459f8038e9b1366f2fc1326245a88d4c523ec94429f21869ce3dbf75126e58f77241c99efaa b9b97218c4783440f4ec71f6fdb1828c41e18849a59d840c6d7ced56dab0da39a00ee1519cebdcd6df905f630df9fe5c +b898d0f9bd80e083fa541f457d14d853bba55b120424a95e1d9511c8833f48444329e0349d68204c4b4581ef1c4dee23ed0a4445727a72e1e6cde422f7c10ae132a3fe681f9d741fda263e73f7cdf10759467c9d76164086abf6780ad474772771eee22d195339bb8f6235e0d992bbe282b13ce4fe01417f507a2c4fa155e108 00788fabdafeebb72f6385301e30024b56639e629a400f9c50d402cfc9b5817844f06a451fbda29c7ece41dc9ffcfc625fe0ff0a 90f06834440b377c69f652c7e596829b4f6f30bd48fa96166f0fdf3f3ae339eb8c0982116cc3a9f36f7d830a9a276395 +dbe04561ea8579672a2b3afa94426a3cbc274b55263989d41a778bcb082da797d84d930ca847a481789524940701cd5f1d11b460bdac0bffb0b3a3abe1ab689c519700de85a0a571494ba0cfc3c865450eba7a9e916b7fa9df55e8a1c246c992e6a0b44b78274e008472bed8d8411633e6520e1a906c5d0c8aafd572fe6f1f64 001b8dfd64563dc219d6eeb53f2e3ad1d771140d0960b211dc1f757af5e297dc7548d6133ddb574711d466688f80dbd65a7bbcdc 86f47f2948e642df9921667ad58b2c276f9f4f8fb173582854c72178d7d476bef74c8e2c309d3190bf174154f03b8434 +48a8300820fea2ad83c83f7d6b24192715329c3f159d56644e11ed25efcbd3d31600a813b909812987b97d1087e74a63b4494cc031c63492b6615e9d6e5b36f62cb2ef88b9f736595800de465789f43811165a5fc093ee6d776008739de8de2a84e878748641be8bd52e5b891c4145f52bbd46644852a43108e93d86352b2a3c 00422131829608ff730c24ddf7e8b4a2600eaa9681eaf45432daa7d41fe2fb488fd0199d431a1ed823801ce21f4f01a4dd4248ca 8618806d05b7f453ef3cae3355de7f9be467e3107f40ce083f3ece328cccf24a043d60c297df0da668202e69a94cc37b +276e3a986ce33256014aaa3e55cc1f4c75fe831746b342eadb017676b0cba7c353b3a2b554522c12e6aeaf1364cd2eb765a404b3d0aa61258194a30219d76d2bfa98ad20e7e91756cf65e50d7914157f283f2ba3930c0ad3a97532cc747b1cb9c806fff497f0322025a3d02ff407fc7b5808585b91d95523c9d5864efdf7d983 00095ae8e4c7e55eb5da01acc05ecfe72a4dcd8ec152f1c8dc165014f70eb4e4a7861aeb2b96c418b2d4db58659e76184e013a49 a8aefaca948205ddf33713c996af0c64964290bd5f644a1b2fcc9156584c9ed8dd5ee319b0f3bc97c18afe9b0250fd2c +6a4fc1827c3a7256faa8ec6a0f3d23559d6949f8cc20e7f76111dc4ebd59213951cbf0eadacaeb8862d6baa0cb298645e4314b1c303bd0d5e9893304d4b7fbd36ab05fb6a5edc3fef763e3a4124d61539eb616b359c5cb55b5e2bec50c91dd95fc39ddf521aa854216eb5a707819fa6f067b316a17a3b146e7cc2dd517f7d63f 0006f2075bd730f34df111ebda919167b1d3358ada32cd6747cb3353bcfb814a77ac70cd51b31a0e538539453bf9eaf9d8b384c9 88cdd43f9c6d751af0302e2f216a8e34105d7e9b9f7261e0659a7a56e48ab480d5e7bd83e3eb1d5a2aadc2e67b67f3eb +4b088199bd8c94775d8ee508377d672dbf50f6d2c7370e99821ec8f9387492fb2eebdbea473ea18465565f79e2af418555f10c4a527e05a9e20c9c00b807dc8b350cd4ccc2d87e91f66addf02ce4f43597aa258ac6fbe9365cc2c8e8bbe5c884abc929710e8423cd6722a8f473bb55804159a92a3d8b6661a536b4fb9293bb0a 003887d284e9ad17d38bc6da9d83c192a434c509340a7f233cebb032b09ab7c4c6e8730b4a80844898616c9abcd16b753c6bb4c5 b2d66afba0d9b1dbcb5e596dc91aab9ff4e6641ef78b7c44d9dfad4ae82fd9536b2579d5785db8c98dfb06d0d8ac8026 +848a13465ddcfb2dc14f7bc0db0756832c22dde1e31e4d8b3ae0dd1aafbdf15e954889e95d3bdfd6e5ebb6171fad62592c23277a89e8ba53978c9b1afedfef7e1c3f6d9f31077530460b47834b30bbd84a4da601be988738aa815d3d7e72043243a5288751ee08b4815a017fb5d9bd55833698a0d526b1ed79da35ef0fac93da 002ea5430610864257c9dc393c3addcd0d8d5bc8aab1067643b08857210464428aa85cf1ae6c743fd2682255d4c8eaa46ca21e73 a9f926856517f5c7d7e68e5cc7e62eae1894b47d39326bb33c5ee33396bad6419906267825db76ddf49979ea1759ba08 +d1850545c04ea65528849973c220205c35eae98826d169348970d1420b4d872ce233af1daa9e62f6a562544ae3a0633a954a493e9766dd5d87e47486559fdf86229a7c9e1726de21895abdcf2422d438f4ad98d88b45c56742694ad5e11894253270997c049f0f419842482f21c792fbe5613e2defecd485585f1835b6f4c578 0062c757c92eaef41f5d81169ec4968145b5aa2bc1d2a3a5fd000634777748ecb93677b3da12e3be33272a8f0a52300f4a5a37c4 aed51c405ce1ff6e128bf4b2869427a082376bb3dc293ad3fc169c42d26be1726cf416bf03eefa4360daf550402322ab +421c9784d6fd507c82904e1054edf9bdd1efb58a0b211340086069ad38b7b0dd15c2345fa8767ef71254ed1bd5c35f742b1d3f4765ff9007a5477ba9e5d3d5a5cb5fab4efc1cad73701d4776c6c4343f42b5d94a9eb78ae428dfe5fbdd8e6ece09d5b75cf4346cf27db856352225ab04e6ea56661554fbc39916accebecb3935 0048a313c0c11489939fc0cffc6ccb9f179093c4e13141b92dbbaac441b7ae878c9d412066e95615174a24692555cbbe904a14cf a152f6795ea2cffa1c6cbc146ce580dafade35e1a9052bc247f03f71f0245b18c04068563696f410b69329e13da373df +7910bab15b6429947655e33a67f41b76f1d7b71534f8904d6a0472c2faded038565272d0b5f51aa915e0d624e9ff48d50ebfa2f09324864f26c29ab73eb39b436c5c459c7cff4d2b62992e3489cb4ddfc05d7366b161a463aa1b782641d93507de43c8cd0a0a0a9d1c644f4554e3edaf7fd794248110ca9387e73ae5d00d299e 0046e2adfe5d3549e1e6fa1fe69a7cbb4ac9b111c8903d544268f8318b0b47d4b78fe3e56eb5e639ad5382e7cd5bd4b2c3e70ef6 897c415e39661a783b147a70cb212aad8e9a1d53a7976182e2598b4a32c391786ac6b0cb9f73aef6449e2b7221dd94ae +e6fc96e060b956c25d50ad25443f3c30a12d199a47451a49ce88307201dfb15ed816982e8888a28daa92eaf3c5584ca6ab2ca9e14577f84396de2e0ac214b24a2279f5e7b344fb7387e9afc8f0a2b77a4d024a20ce6183499b17096947444bbb753d9b39e5c694239d28f9c454bb05468d17ab564ee6cea3741747ccb7f108af 00480103fd6180a431c837643566706e2b9597de0a1346a224d176a5b2c54aa4d064418ed654a5d39f4773fb509f86473ebb373f 9711e36f01efa06b96e60df23d8975631d3651296bb1d7ebb75b3afe8946507b706e20dc44023e4416a73cc86f907cc1 +c8a8a0d41f35537e6fd523ee099eb45e1ad6ab54bed4d3e315e20227db03292e39dc1a91bab439c0d20e36e7fea6ef08983f390a6b5551ac3b4f1895220b2867fab95552cef9bd8702962839bd9b2c72772640e7d3be3c5889d226acbefdcb448432bc503e5a5fe7ae9ae7696c720a799f9882c64ae0385f656074dd8a6821f5 0013c489e8311c6bef02c8f58903b2ba2a98a27cb935d75a30d320af9a14fa3cbc6adcce09235a9eaf333dd05f4b2f1694985dc4 9029b6d5764a3d0d1c7aef4bbdb9d11430ff2a8d4694818bc4816eaa64513f0c439626e27900ebc6842103f761c8ae60 +3407cd6d2845197cd7414a30fc3df7184da204222ffd65c4d16a12cadabf603de8043ea14f5e6ddcc22d3572dc06dec1a23cd924e1847ae285ecf01754e2d1247876431eb98e897e47412a2330bb32990f9714122109e94b38f82cfdbbf2eeb4c6f88f5dbf9f0ccb47939df8be321dcd9bfd9bb99cac9f94885fee7d443fbd87 002419bd2200f8e1d87db848b0379741685e680d9affe693eed49d82931030b6cb05d21a4965f4e1df2045c8513a8f574ca9f2e7 a3c17a7fb58f833728f196732c0605841420311a25e259e04d1b1d874eaa7cf4dde7606bf67335607566cb0b5e39e4d9 +ad43f8440071285d01fd79244907803601aff4bc5d14c77483a87cd742144d41c68269d76c9a83c09d2178bbcbdf99f927b378497ffdc907a75a3b0ad019e69758dfffa480871eb6e1e17c8539373de611a557fad120d0bd147f8debe5f09a02e56fb607e9c1253ed592071f042e42fee39775b407225a2b86a950d81bb7d7ef 00722951879a65bfcb414e11712ee9431eeb32319e0ff28601112f89276ffc2b96eb65c7fd77d023f09914a53e2aae2c84652bad b7b62d59fbf631f1acd2ee28f01a56e22f16ddd1bf5c0cf0382457652601cc84c20d0b80df8dd623fd941ec7bed0e1c1 +d61a3765229dcd0b4fa6c57280f851ec2bd54d3ee2436935cd6d94e0120d0844adda163995fbc4cd9d7275da859ad8ebf30af9efbdcfc31c7c9ef42bce9011d37cf9d15fb018e117bbc102f7d05750e5072f73d02c2f45509a55627a78cbd9082cbf36807759d1fe2ecbb92ab30cf28434941712d38bdd100955d611987b5968 003f5b5a772d24bd5454bf26759dbd433fcc7bae4f5c593664c4d75da0cdf9430d7d9162bce3d7f6e13a344259da5a7d6a1635bb a3f1fd714cda34410d610248e54eeef5a3d8d97070d15fb0e9774cf8f4ec4390fb588cdc4855cf12a75309cd38071e2f +1f3c23636414ced48fab6763eed5b22537968e6bf08c178b3d31fb1f6ea773c6979759701d94bc1bee7c354272811edec58eff50c93331b22723d460e56dbee90466b894354777b23b13a37d15a84c762caca70c01518bf34d0c2f072145d274b3b6c932b48bd815fe81161d8507ffbc2f783bd212c29b2887af6d2ffa9d2b4d 0046bb4a141c9099d531dd23ac440eff1f5b10f7cf34920b6b702311d490d25344c665ed5211d401def24986c8094165d10f8934 adbdbf341995abf119f9f26511181cca81ff62269e147a25e2c9e597d0bc985ca88c1a638eb480a255bce066043f820c +ec69f2937ec793aaa3486d59d0c960ee50f640a9ce98a3becffc12d6a6c1c6c2f255d37d29f9b4d068373a96beadac98fd5203a9f229bfc70bcd449640165ae5128e3f8d057769e28356e73e35d8e9af7876f608390090892c67391ddfcc1c332aa61efbf72d54bc615998b3be8ab0a9d372784bea48c9fab244482c75cb2de3 006f2c6e9ea8109223d9a349fce14927618fc4fa95e05ecf9aba1546619eaeaca7b5815cc07e97ae8cd1e9973ac603f84d838393 a9f7d56c794299e76b0bd1a6010671818c3adb636286f078e4678886e96f56fef29a370baab795c588adb70d5781daaa +70e11efc78d7f079ae41ac3c31c96d3220f4abfe23814a2a4a78d9b1a25e838c3408bd416062e4b0a5cdadf0c6e16a11e00f59711b417751f5e4b43ecad99efbdb2a81c91a034e89edc94eb552c3eba62808563cdf64453a1db07daff8742aea4a9fa738e1322da316b26dbca2954b2bc0de6da7518d28e6677dec6ba8af4285 0004212b7fd913d794fc6bb33e0276e349c052c969ecbf6afc89b28f75a599a9242acf74dec9f374361ba296ba42a38407f9b7d6 9620752b76d05cfd205a349e3ea9e4b608d132cd0e2e9726a385aa0403c728dc7bf1ad7bce1f0e3707169b335a253eb1 +d922fa515e3bed60b517a2d37cafe4c041e5ab4b5c8d8d4011bf9fc4013dd8abf7add71fcfde5e71d6abe76bd0f749e960cbed55711c87b5629a2c39cff48ed7d0feaf5cc4765e576a4959521f9a45fcba0dc65ae618826447e02ce6e1cab5ce8d6c96c3211adbb0660de7df7453f3aa726016941d00d8ee536cc106a603d126 006baeebb5ffc89c94c3e8b37b9b0904e7c4b251d204894655bf3b1235710215c29820b9d401c9ca7df1404d2d62d708aafe208a afb254445ad47f619fcd3812edcf7621cb8bd590a340dc448608cdd8e222ecd49d20f624917a955d6bf2ce5b140ad3fc +4f64d0f6bfc542a0d4347576935bd68ca88524ead03b8d2c494061d0658e6c3e14576b5bcea5f2f992f54cfb52b5c7cf1dfc517205e0454510eef1b7054a8cd06ab53ed2468193f98ff0dd62faf076549ab2a270f259276d5729996c120792c6f466a74ab65035bf38ff2c055b43e2a8b8e2449a2375ddbfc18242157bd905f8 0008e5f66ba53e7caad1feda122a80c32c82d2c32a7237b8ee8ead44ea8f2f01d77c7056b9dd60b92d051f060da8532c1fd0e8f4 92fd979b988b8581cfb0e655ec7173808cce85d5fd887fbc196d9a57ee75cc5a67de4738309c486f20468428efd2f563 +7047d478ec5282d55db8c19c97af10951982d908c759ff590f27d57e2664f08d526cbb2bfde39bdbb1aa3dca5a8d3feb50b868be6651f197abccc9d8040b623de367e2ea1d20ecd302afb9e273f4be9f3f64f2c2eb3f92d5e0e375db6549da2a589f0604bc7146562ccefd15995a7c4208f640e7a17afbca69cda4e173380523 004ecb22b44e809f89b16abb10be062c89b41ee34e110403e42a20ce59a99afdc22f6f6dda56e1d9d1b8ce1d057f390db111def3 ab7d219c8b500619f2bdb3925ae9c9757cea47d3d5e2e062453fd483b6368110040ba09c6d0afd680a9baf18e76e095d +1a8384b4771a410663e56eb36c5d9ede8d161a8fb0e31d3f74bcb017b9e31232bb2e2f4c65a2d85bcd1cedd93ef08d4bb4af0095731574ab3f2762788a1ba3bf0ee46684da8d9dd384432fee99ed3c69213d790a5d81b351063eaf2bda71ca4868ac36be1b571024a8bf09039b347fa996d5d161078314e24b7d073e05cb3d48 0051f9500c15ae73d6d479b9f3d2caccc2039d8d03820befc2aae3bbaf65d59bd9cb3c4e3aa8bed5b3acb70a5566047ffad80729 a781f04e8ab947bba8136ae2ae0ce6fc78acff7e6772b7d610e6819b8003bd9e464ac923c89607ec5005010c2224eda6 +43513d6dd8bb0af7a6f5a2b35f99957d335a48d54f2c4019ce9518b35441d4935518976ab1df37110b5b53532cd9e2c66d9f87ae7f683d7efdbe1775a6c15eecee84c6f879999d0706f6779dc158c111fe8d7201983883bc8334f51dec60004eb1087347bfdab20f8f2f260556681e05fdbb8a6139857fd3bb2df5bc1f2dc143 000cf01dc4462cca764f4f8cbef48c51980737b9b98d1384b8de9f4c733829db7718a9b5eaa46a8475c2144fe4454cb8eeb0a443 8be5e1db98dc669502810cd04b507e075b89fad8d4496203a3b70d905170250f4bacfcca5acb9627739c2f93a8998369 +752300bc5066d0efaf807183a41725e349907b7339d77c79921ead3c685b616b0eb97e708f3880fce0136c510c8cb53b22cb424af6f1c34633600939a0647c02d8f9601f9416f1d24a51657241fb559c25dfba91402cea43bca1a13718b3945b048725f3df560e6717cfc6ebd894e29bff1e0c7763f15b8ea93e67385f059598 0063a9a565497974c6dd459bea0d1196d74f263f333c31b7e8591499960e1cd79e2ef4cc8709f6d54713f873b16e7b0be42f71c8 91d7dd8ec5ea0f3b78c1219e3f8490568d51ecba51ad9bc63994cabbc2e27abf3f21cfba7b330ee24b16a25c7ea65bc6 +f620603489944769c02e2f902c2299dd5f32b5fb463c841b7e1fc0249a85d2c31684bd3daacd97de8291c5d39e84d6e59d3dde1b30c181bfe8d31b8d8e080bd191690a67fa00024ac8c1b10981b40d4f88789ecc58fc69b15417fff34834e23453bb9933a43d08afab74d056f366b40ad167b51ee5f008db151a12b467d3eaa2 0041074dc186193d30aac7cc6d269b938ab40b257d095e54ba79967a377a91b8f73671470cd07f0a3d1db7cf0a31ba9070625e43 94547eab6cfe91c870d87f05ef5cd227303f959e0fe786936b43cacb9b6987b5b4702cac58de50941206a61532de7165 +5575f610762b42ce4e98d7bcf45a7a6a0d66ec7f27d6b8b17f1961249d905bc7e58e2ce0806d467f106b16285dce4544c72666d08b5e2276cd0c4e13187cbda8aecf57b1855afedf8fad39ee4fe009f204e60bdbec79b123456ec2d85631d382b8a2f2c7634af3992e4707f7b4215e2c9d3b0aa8fb08267953883a4213669d33 0010820db54ccf0226161aeaee79cfd2797f87702b4ee91adf8543b3c9e79579d0df8a889e366ec1e0718e039b87a37c24d620e9 964af10ef909b0eeb295f16f60a348867b6641b48b0797c5fda2fe58e4adf5ad9b608f054a4a5610b226f36b2ebd46d5 +81cf067411dde2d0ab04fe5fa1e28e6975cdcc571588de60a35bd956a535fbbda4affd0803d244f3f7e6902a2c9a7ef2488691b6bef7f8ffb33be09ccae4c5285265e4957f7928ea5cbabd6823297f59a7cfc9939a49f26bde74c4c69e2d38c1efbacbcfdef011213843158072be84ed3c1781f67a0e2d4e9ba76a585c17fc0a 0059d2a06e8bfd5e14a9bc8777958b85be5e97af892d2cdeb0ecbd2d5017952b5042349db5fedba2e26e7b85bbb31ad313d99434 b6a980dead5afe4be7bb6cd6a772930df8849a6eb7cb2f18c45cc373da5fc5184c796c16b913821b7437912947daab08 +8ea18387940035cff2f37278d321b344231075db43c7fa7fee9bd3fdefe5e8f03e7af9deafa1022eb108e19ec11fae34536a4fbac2e8c8139a081a997c080cbe8f3e2d2a72ff26edcc5338b21372fa1498e439e4d9bb12d51cc539f859047957b1b1f1fc30b90231eb06b365a4d404a1fd5a0e5cef171fc95b04d0b557d78ebf 00405590893cbbe18f4ad99df28b5f9d17f8f1882269aff0b7eee9392859d68927a99c942a3075269ddec6d69c0df2d76ab9d801 a53f1def2c9474ea671507c00a11d279b950e47d6a5a90652666934ada03661a59d731079d6965746625aea801137716 +6a253c1aa17b2b1e6624afc8e7456d366ef5b1bd78e740538260f395481148a64da0b6a58cd53d7e06c691beae1a616547cd95c4d259a371e51c2c0e334c8a5311ae31e4c7af325686ff9f7a36f731010ee1a9b8a29169ceac36a060dd23611dc9713c615424888bb574ad5f5755d7311bd169336ae986c977a394bf16487c4e 0062bbb4f565aa0f23b88ab9029d33b995729d10fcfc33ba7c4051e2fbc72f15636a834e3ebfe604b927cdfc89f53c57f36890db 8656745e6845edc37a05bce9c161ccf5704e7061731e0c7843d72958b9754d561a9e14012f1a98529ec45be12445341f +0f91d0f0139faf3b90a3d4bebd7e96ff6bb6f90f6c68321fb392637d8ab2a60d649a7b7364ee6e4e274e1a8d342caee36cc11c56c54247fb0a8e8ef81ac4322b454dc9a195dc54567bf47ec8d4fa4cd32e76d78ea2d08bcbce3edbb68fd8597e56d5a9f2df4e47b2701046df89615961db601bd8204584a6a6cfbb627e2a1190 003fad7031cf8810544a3e4bd1382c0a2e22c5a9fe4804ce67b27591fc516ee81dbac841d399327168aa6abd79e2b5ef85df1528 a8ae52d65adffbad20f640d6651dbbe78a2760d42aa11ecfeeda6b912a7d989e96377ab468512309196e47cc085130e4 +50c17c1fe4dc84648e5c3c3ab8f7c971d4c58d8d56d2b5ddd92e35e6792111ed8dac7644ac8a07ca8bb4e38e071aa47b22ffe495e9083f9bf781ac1b5fba571862c909c7aaa7b8d05ddfb7ef61c99700de734d5658f44ae9fc908c85a2dac8e7f854d6d24be805fcd7f873a91252985c5c73129c60177ba8fd99daa87b25a073 003db41b4f637fe7977c90e4f1a21799baaddd1826c667102414877138436cfae1b9959842b8097b5276f15f2b982ee59df263c8 afdbe936a5283c7390ec6c411a2c15d13fa7f0eb54305c0472fc98afd4caa1938bee3c97e60bc26a1287804aab96b47f +3583a3226e2dc463a462fefa97024e6e969c1b13bdc1d228e2d7823d9f7c09012390c2535baf086588000e908309090daac6e6d2b06d2ede6fae838ed47f30b5b481185f607a3586f6dea47c8f84e9d3b96d5b0ebae2462fde1e49d84d36658e87dccf5e30c0937feefd8862dcdb1a1ca373f6ae41641502ac54df6633a8cec1 0065b76c6093d9c49591293471286df1a4444e60d9d06cfa114e175afb5f119d2abeb273b0596019a0ec5db5b5869f2cc827b364 809fc0401a43d5a2b7262a57cc7cf4438b988e17b4f4c83ef6c7daf421897b4664c7f994c0525173aac62320c4717f52 +60ca58462d53d074b370127132f4e59f5eb8d15594dc721a94286afd082a8934e52462c9c1c3910f8b50d7aa3671dafa5972958d876d7992467b2fee3795a6f9d8a7bd3003a8582ea8c003aa1e02c08ab6804d85bcfa13a815d75c938671f0af0706c68bc70a6155708ca755cac2fbb68b2952208d63e0e2e3d816f04c61bc03 007e9993f3fc1fdc4c376ef77ecded96006ac1159740bd1b2dc6ae3d97e15a67383f1fc931e460b9af3fe14a54e47919667ed06c 955da1d63a51514afa270f0b81c2673cee9aaaa5200617b2272563f3b3e77e3ae448f28a5af46c5326c71c6c070e4212 +c749f9bb92ca9957ca6d0124206ebf65e860ff38a225e241950bf4526cef3f4fa9184ec83f71f813fe852dc08eca6b45b14fc7f2c6a19296529bfda007efe9d0d26492de2a902b45ed39603e22f0a763dfa5deadd97ef6feb859d860baa2cfd1d066c0be0f9f4e0e2fafa69cc51b12e814ad2e33b0acc0bcbe1df8cf018dcd4f 000c11e2979498695c660a2bdfd105b115bc4ff8664ea15cfb40c725406c6fc9a13027bd1d72ffff6258f29e4e19b845243444a7 909a74f8bff8915ced5872542273347cea5cab79a8c2fa640f04c686bd8f42af08a7e4c05dec12a067d21cb9c123f347 +4de8414780ea20f7943b1f1adae5e3962d96e828fee43bdbf2831bd71bd25df2976a3be37a7a667c7fbe1200de578920090d131a750c9bc09bd95b261234ea8cc25423c4ddfff5656d6b32da6e2f6f530e6673a8660aeca31273bb9a3a21bbd7031a2fa71ba37c004d3d1c64b2c0798783e47b2efe1a208959ac16e35d444245 0068dfc23c6635bd1fa1076dcbd456ad6e8df7ce7c1370fe275803befc4ffad007fd062a61cf1d50b93aeb9afe1aab47a65af82a 874c1bf2874ec3f34ce31a22b651ba4d854715193df7b075a95c2c3b5ab5c814db94852798e926f0f805cf4a00fbcfc9 +a081d54232f84bb19dbd52ec3812748e2e6486f6cf1b177b27929504ca878036547eb43531bb5b3edc81bfe105370427e92831d2239cca0106d031d9fa8da9cf89c6fb6401377d5936b6329ccad854e5567181b8f16a37c35f333eaa0ffe91d727d183fbab935fdac2d5670dafb3fba59e4fa2df1746c58dd8360fa08af7f4e6 0040807fb888e1d9fd33604546656a493629d94d4a0a9de2608962225ed158167f9e2438abe2d12a11e2adb6c2b66ed78215b0b1 b491ee9357910436dce0d682f80046f6336115c6025e4fc764d96a4331070657244d4299d5e9881f36e25ce99767d12e +ea60266f1538565b3ff42fa4bbfe319be070329059c52c8bc04a7da2824f209c1145a05e551ea59ded8ca8439c328f6907da4e81d658937df614be98c7b8648818ea80ef40e49aaa4431f4a211d62acf2611f5d60c446b2b25745078c643859be1b12b3141a09ab765dd63ea1f2a2df015eca0840087a5db378c4c4cce76cba7 0033bda0a02badae08fe40c239b9d59e5bfe1c4d4b9b7a5acda6790bfd77ad08dde5e93a2da80ec54a7f88146d72218bbb88aa10 8e5f01ee2b7ddcae72493b2ee57b700aec9f607eb4469e402abdec8c6cd69b3ae38bd32fb282516ba4ca3e986605db20 +82f38c9405ef0d26bcdd5b3fce4fb0060c3095f61403418e17c337933f0563c03691fabd32ab5e896c593439e7492a9970ae325c67196d9e83fe0f9780409a930326f7e6efae035ef8c321cb9ad12461edd5cde66c04739fe079db65406b3c2d22f2d04b1a4335285513d4ceb901d2ca2ad10c508302266c2cd6079ff14eff4b 004ff431769d26b8837d3e1295f5464fe82be29edefba76323e92078a6483ea0daa96221549102509a1bdcfd46a5a2e5de10c39f ab08b8fde2ba8937672585caa6754c6775d6c8459785bf533775648b0e57b399cc3e1897c9d07a28b4d574ebb7a3de2d +d8506fab4f681ba4ae86066aed447571eba4fe04e6585fe3be6af2ab1000a3da68c5b0c711a85ddf3a40cb7c8944eef81f2094650459e14f5b848e6add7e580b0198070f873eb3ed5d0728eabd92bc1398764b94cbb4cdd7cc2027b9762dd10782658cd9e8a5022ac062fec535d892198c8a387b3d2b6f7c92b1af6ab7dd9e4a 003f85ca1169ca7e9df44cbc6bc7d2868c9d94e8f8b699a42ca492dca0914eb5789a9032218dcef7f95f959c9554a1cd83360439 81ca7b02710261cff798302d16ce8a2ccda9066919af8b1168ad7933ddd43f28dc2096a28d539fb3681e914d6f44b2dd +b3f30d34f252a4c26f396079e773142bf61c0981d912333ade3de4e27cbc72cd8a16b31807f0c46116f87accb854487d83ec8c6a61565e6fca145eab70048245db08616779d7047db63aabd90dd15acbb05eaa510072c151c0518f1b34582b95f43ec7b9484b2993c176de79e84566764467f72392ef31619426d159c91816d4 003a97deb36d68f81f50c8829d412ee5de7f9d775633cb69c09dac558182039e275fc258240517a7c4aa592e364765321f27cb12 a4cfe23e88281e8d3f4d7f80e29e430061beda5d48a8554cfc2e64a9a67c1e7997989cb78f0e6ed63661c791df7ba77c +0fb13b7c09467ad203852738eda5ddd25b17d330e82c279630b0e1f0c86681f67f6e537fb00da9419114973c8559306de58b0387d86e52d821d982a60769d2f15fd5ac2ee6dc55d8ac04ee247282cb2866b8cb8b4d7b4b6cfb33bfefdff09a73d727193e5fb939ff66ac5fcb644a44f9083a790888cc538c5eb435243c6a34a8 003b1da0ffed24e1a3b5ba22bd684337f6b08053591620541bdad50c761d66201a2cf21a4cc636426456525b598e96baf97d9851 93f4f2a6887bb9282398e783cc50dbd9d0da7342ccd2fb00421983b849d81a4989315f0d2ac3c25e7b539e165c3c7fa5 +f9b8124281628cf4e1da0cb4f021c8d19d815644cd80c7c8de4cc62722904ec4cddd26cc4891f30b15098a25ba6923c6abf4774deb6e1883fbb409862f94467e75a725e7154be860fd58347577c83adbf18535c54b102220197afa062cc1c84f6094490ce488af4a08d2c5b808a2572e18a59de96c87162f88413795351cedc1 0040bac7e0d3b54c7753c79d43469e310d876015d948fac4e3a9765444754476af72330e88d79ee6119697aafac8435ab5690754 b31288c291f779091c4fb1cc74adbaa2500afe4a97bcc0471c4749f37ac51e6fc3784621a6deda334ec83e7553dd483c +4e3cd6100520db050af0daa69fe3cfe6603a223d4f2a6318fc5836db8640d4c7fb80bb781302036d2d6fb8e552b4eaef3133b98ba2d36b9ef0b86243b0391413c73d48ecbf1d19170f1b3b781b35ffd316afb1d55d1dda8e91eed5553780cb2714a93e7ece698b832e853e2589c5ba2b8a997bbbbf625071ded66762af8cad42 0025b7eb3bdefba3c5134438caf968f615b315204f348006f82e8d61057a8a8a853230cf0500f9d0b8c1551a59b9184862dd2ed9 899385e2c254aeaf93fa17e27945ced30c5167deda5f46d4a9e5acecc9258f06588d38fd32a82e135f0d73c42edd60d3 +5411708381a65bef4381c9e13a04cdd5ba0c15829f7f25ccadf695f635384d8e4704cb562741747831b33852567f42fedbd190d2980f1bc921ce01c17d659d4bdd7eb787b3927fcee659dd3b65132496c687f2249272a473d46326e66b3cb78dafbb522390162c168f73bdec88adb145e6afecd561979846ea4c8cee38dc1686 00673b3a2985c95904732632e5d988d8d437a60db13215bb6aa880b348f011c609a1e860461427a8cf0d622abc47f910f5c97ffa 89d9447883bd20242b6ccb0631305af4657599d2f48fa6f99063f600435ab777605e0b968b8916841d36e61aa690a015 +23757fa60fcabf543e603d8b31ef0cc99b3ed16b4816a84e01dbfc858872fcb79fd03d2f8a1d4f28c25dc42a39e20c34f81ebccda1682ee9bd22fe323e7f8ea90cf4a2a6ebb634cd1153cdc35f7306f28a2efd822bf23131baa1543d0ed5ab4c8168d3199983fbee117085f90550ec3ffa2b06070d3add1d707fc2593285ff58 000db7dcac414010b816236cad584dabeaec1da76c97182d1b62f87bb7fe2946a64d10430571b2b29ccf2ef72c969a9f045f1f3b 897f8fb390aea6b543e19caa0ed8c95d46fff4156d7d044a19826ea936494224050fabe1499dd886426020fb0392f4d3 +b976314d2f066f8893307a726f450dcf2cf865c170e90e6908ce9787eec48e1e2119a731b2bec3c12fd4e6282a393774251bcaef91af6ce57c63a8b45bedd72ab862cd169b7c84b8f6a72084ff823a96f2f8eff3483a7ebfabdabf0998377c5a6836d88135cf61c65a0ca7ca57727da68047dc635c17ad13731035fe9a6402af 004717efef16e1ae267e155aa1daabafc68515aa391dfeb73c13d01f3132bd22c984228dddc4dff4c39979e7585acd3f730cfcfa a502e64ebbc98b0122e44216d3da8027f0028a25f1561a1c1e2d7c5635b743dcc85db054858978b833fbe9f38ed37936 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K571 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K571 new file mode 100644 index 000000000000..c28a5daf27b2 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K571 @@ -0,0 +1,60 @@ +964ad0b5acc1c4db6674e86035139f179a9d5ec711b5bae57d2988456bb136d3aade7ac9ef10813e651ae4b9602308b071d75a934a6c012eb90c5eb9b2947b50fc97b1d36c5bf9eb13a7b06c94212c3dcdab402a563262298defff62b836ead1f78f9d20713710fb48115cc5045ba15140fbb4bdf516e4150d830d02cf30963d 019cf4f4d06825499949f9e0b442586fe1bfe3459813a2b92cd8de0f775a4735e02655702ead8e60824180761808d9e816d60bdb0238e1e8039ca7bb63c92e1cf8433ef447e64ead 889f3f49f3994b2f4522e47b6652e1bd88712cd43812b7ceb5e195df305600d428c303b7c4eacdfc7268faa157ccfd59 +baddec4794effa668cde267016dda67bc70b847919a9aa595f93ba9dc27354399ef7a607fbead31e57a8ce698beabb10f313d393980425e67cf95be45d512f00e950c0c5409573ddc3d556f23daf056259ee8914e860562a674311452fed780b3e0317a7fe93baa81fb98df3ae4328b28ad0ac8f8ea33efe24faee658ad026f6 0098521a732e72ed945a549afc92318fef7156ed1d1ed9bab93b581478cb2339eb32bcef705c9bf61cf2873ddbadff8ff3806740a2e30ce67d1807a8179dfd5d952e6f8a583baf81 b7e0998b2c179040be4d02912cadd174610c71cab1863b6d962b6b07bac77a1e6205559c613ff8dd5fe1033907792457 +7ef7138fc657492d229054f8a50dcafcfcd1dc06f1c16640af3f658907e2969248b54416066eb119adbfa23b8dc578aef18bba79610b9cc109394b900a25e55a779230bb858b2ddd9499a7775d392328db9177aa9571c2f61dd52010b48502154e914a0c55a54edcc04a6713cf7bda8744a893926118b09df877d1a4f3d95e8c 00336fb21549e397a190beac38a1ee10f0551952da15f71e11dfda415e5ee08da2356f114d450c661f52b2b32cfc7b9be61732672691a079f0927989b7e9f4efe6095a242155b641 b61bf73572b9e402f0d75bb8f88196bd7f4f9742d6744ccaa09e0e50179c352ca2b31c88aef14933e686d569d22a7823 +d58e1ff1d49a471d0567ecf8f29173dab5fe5f6184ab4cdd095c231fa7b82551f99a482994a46c3d8ebc07297fc9e952a5dee7d5f199b119f6f8b250f8fba45701ac252db725e75c4da27ad77d59a4eac448e54a277986740dfee6596811e59afc9755e53d24b826c09e497e29e69a22bbc85be11763064e9ecad7ae66458ca0 00e287ebfd9ba294128cbd484fc5121d271cd33e685bb1804f09b40aaacf64b5a9f2cde9b30a4a02d3a9bda97d92f46bb8787b3c61f280b1e1a0680f1f0679d3bb34d53725d62e52 a2740b05bc93efab0d801d706a249f18e356bdf12550b8f1998faa81243d6093015a9cc92fc512975707447ca723409c +4949ba765c14c31f68ee0ca26bb42ba2edee63537de4a6f5c42bbd862c21288d6ff48145260365193c6fd2b56dfb014da26b8a483776b717c6874f627c9a622154b824565b23e178240f53ee9748c45759ba5c035b584df0f09504e95eb9bce0301653aadb860bb25e6ea6b9606e0ec3bdb8089e6aa0d5763d331757490715f9 0149de496fa8f88b2741864d0c35b3df666b87179b7bd06cd426a45f13bc87ea9f50dea85e1fd02a532630e0e3a231cc3e7fbb7c7ba85b40cff1124e72c677c6a3ea6aa40ffc64b7 8d6ae4a2b7c17d9f94c9f192e2c95a5ed79197a8873d6b8b24e6405446b2d774cbe350d670d0accfb1841781f2bb2a4e +5bc63e5c50b1650f0ed4a599960f1e4e11f6c151b2123fd71d9e3c44662312a74b6854290628e20b30eaba81555acb2fb49b640bdab2528619c7fcad0f2a2880c7ea232d427d7c935fba2313370fda8863a7e7e203d63ea15d0cfa083e716ce6068c63fa616ddc225c9e413e694cdf6b355cb1293af5d6cdea51168f5634e878 017605d7c5873d870462375d741b4bc6375f3d47f7f5e9d998917adf2137a81e63b66917b3dda8968930c4b850f2270eb3187fc756e2beeaa67fe0d73053e6cc0ff0004a21250551 900178a5f33806ebf05b9e7222d35a35de4380559173b780a7beda6aa3d140c33f0657b1ba8336bf82375d2bd2729400 +610f6633718e49d232b3798654095e2efa0de11f41258b27aa01956480c870d901efa77e109d5f95f1f5101d3c90fc51312d9b3019d2e42e0067eed7b457dc7fbe5466923b62c83d7347e4dada571b57813bb9c21d5e308519b8eedb7a7706508ad04aa69698e03636eb30fd9fb363ef3a185756494ee01175b16847f5b68076 009214dc2da0967912c31995cb8f5bcf4bfa832c5a2d3610f3a9857e5eee7c77100d599d9ed003b4106013155dffd6c48859b846e45e0ddbc5fe24f4891c9b2df51407e9cddbd974 a5955ca203db02c26b751ead359eb3128b6aad7117ad811d01ace76a19df9a21f4720e28b8afea01b5b1800e485828f7 +c548f0546cee0c0400401cd540a0aa9377f27ac64492e6baaf38e794db4df83e64ca3d83b67bbb46a6c269c04c2725287cce0dee984a0d468c9ce495a7e554a6835d72c7493bfe88dbd5a044a148c89001b8087fb03e57c2b7212d0b175d616333a9affd8a1802dd49ba9be3ab6c6d9f99a5578d26cc4707a5860c6c804d69ce 0042f2682e9ac8b76f3c0880e12c292524601dce9ea6982dcf68bfdb0d3fbfb50dc9229e54149ef09b95bbf624eb04ce1427077f30d8536be9f69970ddb449ca22ab8368d2689ed4 91d0eab23cbc3974887eaeed4ea9dd7334d7ba781675bd681756858d0728022c02c27a06339cc4428c401217d0f18964 +9431c6c5237f6b4b35682a0c32f68752035c8b295a1763c5dbdfd73466cea64a00ecc11356d02d2a9211dc54548f5db1651e4471898402c887fbf45005a3bda271df0158c98319d4d6751b8ca6b07100182957d5fe0d97c4e2294406f83e9afcae4850bb089f2252490417b5afd8f07f4c795fa84c9c7cdcce26bd97273c0072 017ed9a9c75cf66528428e85b0f019e3488af8b893b12023ff1b4ca9c3691b74e594539afa0f4d7c3863d15399b862f15e27bb077392d6bbd546ddfd46728c75177338466eb2f4ff 8eea1d422449e637679b9722427628ee9bbc31486c0cafc2ff30d7a764c9f6118110a9b32527dc9f63a40cd22f4de92f +417cd5f60416f17081d2c70e9a510114e08be83573bf9deae75fbc3095dffc8a7f7325f61f9d6565381710eda871388cb17619e4448836076338ee309a2bba5f737319002e259b4a875cce1bb97996101c9a7abe0278dcac203a712f0809eb3c4b85a9c380550ab0bbc5067a8edfa78abf03c09b5c08f21714e1022ebfcada4a 01bcc09b3f2f1d26ab9955bff7e8c0f85c8a61293511a196b53d7963f4a4503849c96fb4daa68c9852ad9185e01a35f0bf298e34a09ec352cb6da34f89a1f23e8ea27712a8f43aa7 8c65fcbc82aac0916a27fda048ac1cd580c4ffbbfb8f6fc8ad4c603bf5f1f0af13b0fefcda32a3ed6883146780988484 +eced8c412a153a643ccd69596389f83b6a36880286f8aeede503452bef8305942d95734fb5733f37ffeceb1c2dae7b1396c3323de11089082745c28a1756f784423fa7ad68bbfbf0d93ff8b7ad62220500df6d6895788402c1f5c69c06dd9ef55e2401cf297184e411be87c1bba657f847208c0e750f94a3df92f253b377b4da 00ec52fc3d9c272ca80623e06b15c35f349b13548ef7ee400bbfa04196850b3b8cc7b239238c827f9b0a3160cd97969ce21d66752791f5896e0385b0527d4d77e4b9fc70f04d73b2 8f17e205285b3bcaa6b6978309e7456e166efd5ee60ca2ea83f23b43784cde8ded664a5e5f37543a49b2b1e0a9549059 +30e83ea39a92036e22b7bed7639eab5e5be1d00c20b4a9b9afa9a0d1653369cbef363c119cc6f921c8f84663949c8b8dc9b743ac2b1861a480476e9b64c8f333f34b6fa0e1ddf09d49618ee4f3c1f46751b5595f0aea413d4ca46f3c26b974b112cbe99c813a96a4423764c069454946f213c5f066ec38108f947abeeeb02fb8 006403de7627de22d1dcf6b8da5af62f9ec59ec065cc1ca1311bb98aa439a6d5985619b17c17a70f59e17cf180ea6828ef57f5f1f8ef05680a9fc12ab7faad5af61e4e11fb45d341 b0dd29d83d1f2998cd554e01b19531ff2c9f48881a3165e37c7244848f0da232ce388621bff2a333e7819a110fc60ab6 +3ed244dc16a5cb292db4b1433b0ca3226913f07377faa20c6c1402cb4d026de808ca74a6d4ecdd7c4e662105bff6edb9fae0117c50aa053aef677c0750c7a446edbb879110030758912e8fa666489d702d8fceb719963b24a256429bbcc869a1f4ab9de9db89263e3684d4daa1df2ed94bb59dde2abba63793e5f82aa2e4db83 001fb980aef64254aeb9bb613ff2fc6967503db4bc1f337882f1566cbeb57489cf32e34f310549f41cba1b951f487453c29753a184e33330e90d4b973d2e406c99a239a5c3f96233 930f8357e0d24d7a7a3a5f84e660dc1066b69db41b12b09896916918074329533fe5e4cdb44f16b581de0f2a1a5a5565 +40343935d9423ad30f3fb1832bb08a5d20ddb3a55b59057cd275320db4a5835471c96cfb7d67f41ef860cf5879897b8dcf307bd1a52a6226847b768ea38ff1858f59e64cd635b51e6863773cc6c64b363ec47ca39266422406264668415c189e2f92447ac4c63ee5d74e95d1e6af05016917ad237f482ea0b02aecadd370a8bb 01d96dc09dfaf602789c1dffa5c9ba130832badcf180429660daadf4cf1be5cca92fe9713173861670eebfe3a0ba25bcc76aecac60a756f07b69687e05c7e25984a39556469f62b4 937de894b73fd5ce36862f753951a93d1ff320e869b3ead2480e4cb13237a37cca5b319ea4f0d33ed3a9fd4d26e4c748 +274567f8841183e68c4f6c6b36c5a52fb0e88492e4076b9cd768bf571facf39dad6affeb68941ee326ee461ce1f33c26e4bfb3c9e0cae8241fbcc14cc69c1af68701fd0be3def1e87b7d52b682ebbe1cc225c1bd177b0886e3698a06d0e410a1f92c9bdf7239189f6acde0d0653815a72987671b415d1e8a70e685d6e5b14c33 009d98b32c8eacd135ffb8e13223690ef02c0c1f29ea8b4da193502c8cb3f39f9eed608c02fd457f2fb685ec4595e8fc8f388d26778d225d2b18c9bc8b199d8b65c0d1a6af33854a 9092b1831315c17201e03333223449052941900c6739d675260bc241ce18257ecedf8b9af5723be2e639d4c76036ea11 +d9c99b8da92d3c2e40dea3c4025dc37770e867c4d2746c4d726b6de24250591a586c166c88acb8ed340e161d4c81b9d14c919a1b06f1feb22c5ce5fca2693bdaf4994ac72c8983c87f331473fd094eccb3d5f3528e69d487562fb5a65c150a8217192f8aabfa7adcfd0b6916d5000248fbbddf1ca2f38e3d9ed2b388998b7cfc 004d873ac744c4f68bb044783ad69e1a733cb8b8f483f2695bbd90c4211282036ad7914a53b25c3e890c6824643cffbdc4138d7ff457e3fbb99387494eb5cf2bdf1ad243a3a1e644 88de6f0cfa9aec229dc237cd8917e2833df03f8e16f7d544b71cb8e4d3a1200d43345eef71d99930635af0bf04814871 +d2b88a01fa17703c99e5b867c645e98feec0d6d1afaa20a97b5fce9c23f0594460142af4e36a5739b8d26d3ba35a0263caa5429b4abba157f359fce701c43372500fd2ae1bc2ed80bfcaf8cab7016ff93d4a27f565b7e67fe7dde22bf02c48be12114fbff2421517c825019c0ccc72d927bef156140d7f0e9b6ee37af78c3efa 018d2eb947297a054f8a789771dd875b12b26ef057fb91235dff3b062916f85aab3365609bd2a38a861439c8514e33f174c198139354e63766942f605107cb1b9709b782622b295a a599187bb872ac1fdedc827b2c47db258d036108a99231f7694f13f517986779c49837ca7199e1b8d837dda72e20b266 +a704a1428cc894f958774368979fe075353b56790555386e3b043dc6a2919b94a11c7f85883f46b4d47b324d349c28c667bf9a000daaca1d7191f2a0fd97a4867aa9f72422134a690625408a9ea4b723704690b69152655f9e9dd5fa3dd94814d97dd4f13e85c3f9bca769491c2461fbd17e28afac00bfa81371d5039013da8c 00594fc0b7a5cc0216d2e78eeeb6394c8225de795f4b73bec48b2f4ede185ba622b59a16dd3eedf8cf2c94f2ccd6dcd205f64c97cf1b7f1e34129e94b5129502909f43940dba0746 a496be88c520dcefb5c3485f3bdd8637ee03ffc934c579aad62cd0ecf2883eca36c3f37fae1043498ab76ccb6d40955a +f8a87c4acadee27a908718461e3b45060ae4ebb009b10a15926460bf219cb7e75dc3a993fb9a741b94e2fd71615c50f6df958568f452b2cc284f0516816bc0d2e2d45f663155660a26326f63f4aa42a6e1cc8462a2ec620a365257ec042f55e4047b62af689592a1a072553ff174dd629a4f51837780ca232cf479a68c1ebdda 00f000631106c5851e8ae0802b01e7a8a8540b427a8a3956a1d36f0600be89318032320cc420931d825cc964e823745c60aad3437ebc1c91d32004472e9677605fb708e5a71a0d83 b1b790133705d5fddbe9d86bae3fc461bf6c47fe3b461a96b8c83e38ba71427e5b0e659478f4416bc7dc16c72015e842 +10b5438294a77c7e517ecfe8f8cd58d75297b14116aa93e574996ec4acb21837e6297cc0e7e7b5861e862062f192f2206a01b1caf42c6d7181d02c7d62b76c2881f8479449b02d32c6f792714d8f70f0c75e81c7d9abb996be87f5ad9a01fe42b75855558d5f00df392b62ae0d258f3f67dbeaf07208952e679a2c573aca941b 01023997206341c6147c536d034a9c38b4012035dc2c9b7ef0bb9cfe65e7d788296f055d508a1fd957b2dc7f9eb10c27790f15f30d81670945e54a508c57b70b46b4a09f4c769289 962938bbeadd0046ff8ea210902e76c32faa8e19b87a492238646eae308b03315228137ba2b21e245a3b9e89e6bcaef2 +d83a52d43216fdb16b1b40469863ca8eff4df9fa358deccb5ffd18b3e22a9d654aedc98f3dbdc4f5b4e56b4299e25d8a5a38d01b34eb93de382df1ae4d1c7f966e84b84c393d167aecc6f1192c4b42cae83748b1ee3d9147ce7de74cebd122695b455e8082f86e3e488fb0f51b3b7edcd579940d1cb9d045296e5e38f201b7ef 011ebf320ecf6a908ea5b868afb8e22246ce84e743e1076d6185ec65dd79043380708bf8da4ba802c3b93b8d15509bb7d7de9dc29f1e9fb0f0f2cb97a26698f955b1f7ef668122be b33175fa5376581416d57585d454410781f182bda53668706c8b7d606267c8aa52cf61fefdbf606ef5b5e263f01212f1 +eddf5553ed4db6e8ce72cbcb59fb1eb80671c884ebd68e24bd7abe98bb1f40806de646f4d509be50a3fabfa85c5630905ce81abfad8a55f4cd80208afffb9056bc67d9dd7f4660a5f924af2a3745eec2daec39a3fe36131fe9eea444b92d31f6a125f12125159ba095f89968a7028549466f41ad45668a861f671050d2a6f343 00746d5c824d78f42a1fd63d8fcca61f154ba3e75788b7a0b87f53e5420e23a935b02eaf67bace8dd8a8e7c1caee30154c2428e0a437cf12e235f41c416f92fb54528865fd4766d1 8c07cd0ba8a7bd357f69bbb6aeb9a0c63470837088a92a437f9cff74e4c1892b05cd404f29c5532adf77c9be571086c8 +3db94335f6d1a125309622c0a9d71bde1da09371f0285a93bd0aac255fa8f10a56074e0f6057f1b1aecf2d86a2319590ead96a2ad1336fe844e09339b456be32374ba2e659fbe9d0f2cdd83444d117d2ce3204ce4b4294dd05405634b84747ffb4227160c4e5c2c9da9815b0c6d20f55705f16cdbaa13d107ae666d707ccbe6c 000670e72ac2de50dd2cdd975a6cdab10ac45e37ef7a28c685d77447051496b5e161f8b1b93f6c7f32fce8ea05e94ed35fd7cb28c44bf51ea29cbaf5aaa31d6abca30a89430323dc b96fb6caf0ccd565f9f256dc3f8d98d938dc2899382fce54d5ac112726450fc5a2bd8e601096d9485dcbdb6a15718ac8 +69166ba40768d0a3930325405edfd85f3272f7b8e600b0b319f070274c91f9f03d0e6ec4bfc7b4445e91b87cecabfecf5e77c7301ee3c6b0affca2fa02c92216698705eb75443eecc25438db2d2fb4b24f4195d6b9c05c53e0868d3e58477100607ffdc31b18c40b4ad7202bb034e58653daec0f6b33c024d42a3fc84bd8f86b 00369a3bb96f884983c23281bcd04e24a3e5f6359f81e3c8e46f3f6b865eb6bdf98a630e90646275c587e41b546d3ca7688cc207afda15cf9b25cf83bd6ad27908647f3f9de59de7 a0ac580031773d95a19455de2c6857e9b3cbe4c77924e49f945487f5280d6c02c6e1cf60f80e84717900e80d13845d9d +f64cb668b72f1e6dd026a478505c0eb33446ae9a2993bc7648aaed02e172fa9a0e05eeec61e756ba246c1dad7e85d3f01baf734b1905c5bbd1b08d833c2cf1e079eca75b866d705c407eea8618d23ebbaf269c7185984b3bd4117ecfb295ee6b47eecc8d3a78bb96552f6be314656f91caff793838226662c75cd7804b6bef79 0026717b039df834855511815d5665ff9b654facab469390ae257b7f0eb4dfe66ea0dc037242ed0c13bf229b8f7ff26da9b55fe4750d3451c62804aad493c179ae45d08ece5af085 ac175b76c76759eca699accd9b7faefbff50bb2fc452dfd39c2d0230af4c76ea746f37ba63310dc94328a4150267d329 +51ee0b98eb6a3e3c1afcb35a33697c048dbf61374629ac5702a57801fafbea4d6fa5a26c9d1b79d1c58257ac0106387fab2d4a1b7f8c0dadcbe7c830613531b3c209bc17f792bdba1c1fae1b7528aac53dc86c2094b40194577325c05d2258303a2d17c854e7449489c43991b6877a50692a6340a528a6b188440ac0cddd4c4b 01d642f2d393ed4abea37173e4a79534af87adf534ead4a0a1c46fb047619221e3577e6b8bcc776114d01159c736ab78af3e53feac339d7afe58be8e7a8ed290f1dad960f1b5de94 acea1866094cc7aeacaad23c422cd1ee4da464a98fe7960f2d6644b837425d34f45f19ce074776aad8ede984c4fbc9f3 +feee50aeacaccb6b1c3d95c6524044edb78322ee836d8159c4a4c2cc6982480567c4c6cc4806a564876622266e1ebd45f2f4be851b79da025bd57d0e6acce1ec1c8c255eb89713a1e4897d4ee0f7a248b9d4bd3ad5dc0e57f60ebfb65691e164bc908956a019083e923cfd33dcf37c735af3462768a1e14a8051d7aee74d5228 008cb70be29e83f697a3e2f67d86f1c1ec9a163b5335cb4a06004b6634948bf60b8ad9df9b27d2bedc4975265ce44a7884e57082d521320ca4372d38fc77b18d3fa05ad8aa5c43d6 a8dc79118a9bc35edac23aae5867fc3176eaeacf9d1fe5232d9dcdc7f8e60d760f2f27f8b841869a1c1e5077c15fec46 +b115f7370d6a93a90fd9dfdfb292956be34b61992ce1fa5627c5e928d74bcdeea66d4040c473306a0070fa8363c4303bea32f73ea3639b5c6676fa5a1d68a2cc1f91f00580d7453a23ae70af4cb1f1657aa82c5b305374effe5d67d559e46a6cee6360503d21070506f1af30bb000d2f2f85caa6465810f89968f33abae81cb3 01eef463771f9c6285f3257691dea0844687606d4dd00b6020517f190891cc1be97cfad21d147ed8881b5a6e19b22ceeae30e1132476325f2de0e9af2e14c80b8c780a9d2d6c96de b6bde787d2faf5d633c6ea42eba980b7984530ffe13b24f624267f2e8939d660500e519a608e6a6a64a1ebb9759b4239 +726782eb0d9720daa64e4a77b5d8dd67a1a193f15eb6b5162e3d89c925ba63b7c7e1c4bfc8d6f11915b0e14d16ab53ab015317bd5958b0beb6074199e05181915496575768d026c23e92e06016598de008c3718aaabcda8b68bebca0a73ecfc7327e8d3646106b7d114dabc46cfe56265c326ee56fd2ca87abb5bed8f997c735 013bd452b0880b101df1aa65724fb60d5d85b37ed5419027481661a3617e0fb37bda1151b9b5b41f908ba832011f7850b75a07b678e5b8cb35c5fc8b94a625e4398cd5ada2b04cc9 95d37c6bf4f6642725d34af4f8d2c016083e81bffbb335993367be7360e30fc1cd01db6f7af60eb3d44fe8fcc9a2dae5 +1c2418243fcd89c6382b7c3b2a8c341f26d08174a9e9296c4a5c98c5793a0fa48dce51e30811a96b515aa22bf9af89a43de06d696be1e531c5dece1f69fa6ecb7f20be063c602a16454ddafb14385ae3f8246c3f989d0566e06e7ed1864502896ea19df8393259c4dab3b3380a4a80b4103cbef4f38cb69198b7cf74ce94883b 01288141ec2244e4bb3f62daf4ee588aed09ce22be55e3d42e9085a947c1f8cd16533635d170bd64ae0b417346fa4670c25d41387acb2a8e14407a1931d9f7c5358a14eca40974bb 801a70fc9b55a54ae7521e171633deb088f618ff84388b6dad21177dbecc910f4bc2ede2d637d767f5912fcb71c388ff +1de4b642ec7220c64b91561caed7832044d6e811ac909f3b199cceb0d8a7db91bcdc801412044f5c34b355b95a2c6170fe497f6d5259bc20715a38cb0341c88e93029137e94d895bab464bca6568b852340a5c5d6a225475f6eefe2fc71ffa42f857d9bab768ccaf4793c80c4751a5583269ddcfccf8283c46a1b34d84463e61 001fe06b94a27d551d409b0eb9db0b163fadcf0486e2a6074bafe167f9a3b4ce8ac11f42cf72f9a1833a126b9473163d29bca2ad139dd1a5e7fedf54798bf56507326fae73a3e9a2 a5ce17e7f2a48c16ad0fb42a0d2f458abe426824b7909341481de3d29b95beb3bc32dfcc371800f763eae23d7fd04db4 +70279be7d7ac72a32606642ecd81b5d4d0f95fbc3c0b07d85c16adf2788601e44dedb8e55e0f9e0b4ca3ca35f5be7511b0e69224a05204af67aae11ce154af6d594d47f6e3142ad183969544aa95cae1edf42bc699137f60178c12b10a67698e37ab9f3edbfb3acdf1b3513d62fe3db33b16cbb4e1f9dfe732c107f9d0c953f6 009cdc7e4945c485a41728f83d5188f539e372ff4fe38fffcaacbcb4522428e4f93ef4972556f4398fe17bdd885768f0fb5590df495badc794d4d274e22f2f4a2535555922fa43f9 b2382ac79e99788327b8d47602265d19b331fa207f62c0c159d85033b5512e49a93dbc6fab4f3e7f9ba68d589dfb261c +4d7e0ad520445b6a5cb46b7c77fbd367614044ae6004494c2b3a89089287e2836c73b799cd8c90139eac427ebe335804c3788f3728ffb8edd7f49a4bcc76a9e24ce3c2299cea88c04645b82033115380f81b0c1d823e470631008d350cf0c0dba1915519985b8a389ccd8c809dbd5bb5051a79e631916e0d052d9b6cca18e0ef 002bc753d007c4491cfb8ce0a6c96455acd16d37e02c982db216b8cc1afd6d10c6be4e15a3988b8b8b86b2b5b59a5c1939889024849317f27ee08a06bd8e7524d4ad83a1de208564 98dfeeb9e214c526e1e19f8e1c6ecfc88cd31ca019efe3ea16f9fe75729737570dc29025192d02ef1e6ba858ba4bdaa5 +d49903f38b5c9b17542310425e59377f61f5b4f4740cd97371ee2116083f7758e69e7e2c1b0950ec6b76f96e3c91c721d6f2843afde8c7505a559c8a64bca2e665aa1131b75bdf86fb5b90581c7d3b61c2cff88f3fccf356ddf5ed282e27727be061b6925c51ea7f1a495f471dc8a5ca1a88bbe29e92338d3c9361460398965a 002082c6e61d0d72f040905d8c1c20d47b029f41ec68d6cbf43ce97c3b2a0a770557a33cb803c432cfbd3958fda30ec1bba77a6613c318597a85ad02b26c44bb77ca96d9cc1194ea 8740ab748660e01199551a94f07bf71e304d4f1be36682355c1221330532f63090032aabe9b41d3fc84016e3fc501da4 +0e3f4afc3e7b25c1bf2d98098a5a87db1224d9bb45adc6e434732b8722a708ab80a1f3f6ef3c5aa70d2e1dad3e4416b12cc59171f05736c4b58bd084602c344f2f0bf3cfdcfe04c64e87597a99de23ded64b33607f7c273ec321f6462518715b11e91361e89ce5415bfc2ef520bfec378244a3bd2a4b9b6b3d68815f2f75baf6 00e298c93351323e2c5304015a4878997ae4e79d1c32f1dc64262e534d4f2c4b3e222356ffce746763373fdfb936fd330d3214a18c07f1205b20c9a941331cd676040ba1fe3dbce7 b9078d778a162fa9ae7e203c896637526bd28cec729cede39d50fd361cf0d6ffba34b1bb662f9ff97ea4eaebff270f71 +8fe32671f6927272fd3cd8dd4e34d44d27fac8c88b41bf9a48039e914990bf06d1633b38b9200ce1c2a275b9c55498e5da2d0707322c3ea0a0fd7aff598fb801628264e13047c8008153e8595a0dc95d54e70b882ac2ac9314d2b78e7b93922da818d7075215e354708994af66958954c92c074d132dbb2488e5a531c755a8e2 0104f4ad56594c5cec2a988c5596d73adaa5a81802b40110dbae698ddb1f0b271fd1479c38abcdb9b234e69cd0da8a0328d2135c287d5b130a09fa0b899058e7800eb2dfcee95c1a 89122f176172fd58b5e56efbd9907f87537c88a8e6a5064be3053e42b2d3fc8d42e7cc5543bead69fe87b9de23991c8c +a8fa01136a0a78313a5d160c32fe5d1805eeb3730c18ca0c47818e82c48eb4c9e5b2dfe3ee5facef9ec59b68f4e6f3213f77fba9f8ba06dcde546ae348d343233883894f4423331b536f62373a495852977a51cb192cfbec04b5582b4ece69f345979e234de32da7a120138a057a7119735c4cb19099bf48bb202e7ffac04def 00c4989bf33b3136bcb4ba67906eaff2bcbc6567635aa4b057acb7353ee87ba3cb4cb9838f8f679729d5c6ed98e6c4199cf58605f009c6873a1b8321f83cd3c0973b7a3cfd9dbaa5 947b5cb6d9a83ffe1105c6e69832d50a30dee4c4e4776829996e62a1849689ffc62049de5b14ad40cd5d142df7c9b773 +ba2d83b21c783d6ef2f3b7b10e910a418a9b9f49ae0fd37990335b3a3d15627846c9a12a1f31a3d0e062ad1bec5650606ed4dd06c30e50c1e8761a29f4ea1a20f74635d5dac22e5b787ac10f4ee82b338a641484f91771c128c84d31cdab0a6b9616078c898665655ee9dd4ae73d33b94bf091b064928b959623aa71ff73b4db 01a96f2ad56e31397e236cafc108087479c9823589a5fbc3dc7488d0e5d1199cf245d7f21f524cc0e8b47feca14c93fb760e631434a91188b32965053942f3bd39b3714f9d6f1a11 b77046fec1e11184e8a789784c5df974a0b680b7222b267ed79fd9cc801ec5b8a58bdaca752e9d51ebe158eb11f9b1c9 +ea2d5f4e9797bfc2f33f0fccaf530db2bdf8abcec00f09a0338eefdba318221ec0e050cad1a85c3f76b784c6e8c18da2b062f333eeff18b7b781e67d6d0a4368b8231a892e0f4103012348e5df53ac745e4d34e2cd1ee9369f97d4801ff485fc144b2007008036bbc07cb1c302a00054b54f3713919191e1d5052978c9c2895e 00c08ed8e0e0f8b0d0714b46a2164b933f8147692f18da97e5a108c44d5a5cf221cb50536e41832b83bff4026c6df156386235cf5e3e9a67b7cf9b2fa7707c5e0ff33a91601b8e34 8ceaa55b4a8c59ad44ce088610eb1bf22707bc80968cbd236d7539e98915f525b03df49c77b10a7fc2b28a1dc88c0788 +b2293b0a09f41decd9d8e637b1b08c2efe612f33c9c0beebb6e05033c6103b958f8aacd125d7c810b4c287349f5f922d2c6ed554be597fb8b3ba0e5a8c385ed8ae70d5ae19685298f20e8d844fb5ad98db12ba7e5f45baed9045c3e86b3cac9bd55b614b82fd075954fc59bfc6124cbd68edae988596575f379d8921b594c75d 0144090a0ee38cfa21fabcc24d35139a99656911ad4f6dbffb77dbe74e7993edfa9fd63d2c4f6bbdbc8ec21ba13c9f4a3576b5d6e3abeab5af5ac81b1f2bb6d4c42dde645d854d9c 8937c876bba98eed7f55d2f157e8f8cf79336358b222987f5113a92da80d0ff1d6734282b75bef62e17a9d94939adfd1 +acce54270252e7d9e983c08c993cd6b7e3caf482a9149036afe4665bd3d0662a6818047187872862d5718b8ac063477f693caf1a9baa8bdf2f36d411a796f2b46ab56f66bc94924229f8264016d6769c85d9bbb7d6bb042fefdb8fde1be026b86af2017aacfe38c97309b4689b23fff94f1de880064f1d3ad9d74dc804c41f41 01df26b672b2e3617b6b6c631d3c6be0cb49c0a690de49643e0f416215bcdaefc03fa9c708471f1d87476d58c8f147517ec8a14aa945ef001fa01984d5c3d81f7083ea500558fef4 b65914f77080c1e1c12405b523d5cce63339b7cc466df4fa5973ab6a2b9be077cab876d3a74ef9eb5bdbd8afbca6d605 +e25274ded4840df0d71d3369007118f002b83e2d375c78f7e29ade067db15cce21842611f3f015db2efec57da77cb9d16eb1e00a8c1444d48dfda569e29fca1ebf40a22fc646a9fd44460f0e473bde487634bfbdac2c312f66a1c2982c6fe76c54ac72b6c8cc9345e47cb319a974b3cc4bb40634df74b4ad7e18adfa9a71ddd5 0189918b832e9fa30161fdd927bfc267f6405335df3d66d225e17173af52a671138883bcb94c4403ca3e001fcf09ef4c6488934d6775af2b1da30a8f331579af2d0fbb530298d8f9 95d0a1f0c65062156981252fc60ce7a37ea4288d57e73cba80fb6db4f8899a46b98699d466f18b4a2a5626c461c12689 +d8a4aed87c316012482819b03a1d91691f2ad11a2f46082497ea8f64880d686891f7da550b2ac17199c657d4eb9d04d5cb8eaa180f743b87d23b1c86103f9e9bb60f4e19f0ff9d160f180aed7735130c03adb62502e69be5c624ed7bda2301f30580ae0921b02e103a638f5623c02c186e3bfe6ff134c762a2bcac1f879a9353 00bdcc175eca3a399b944eb0334ff33c4fd130999c8ac0e7b52ac5b774fbad53ccc3a31024f5262b2eecfeb2104b14bb244307effe3dbe8ed25686dbf46a42c4b6f8e34010ad826a b9828bb11a2bf8e1943d35d8804ba08958adb92da1f97cda39e34bbcc4e2afd35bc45daef758fcbc7483cd34a64d9927 +acbaa5ffc4eee0850075c0e502a70cc7a897a919f5e7bca4e798385601a26f411fdae5466ba9f6b6d8d7f819a749b799fbf4a3bda9105063e74914e8583ed8b31ea4d22164bee6f14bf53afca269b901c80cb3265be32ffd4ca4bc4ddb83e11eff82ead6d75dc4aec8e5c67f35d58a8a156cd1c0351abdccc0c5396c8fbe6920 0007ab5a55a1d8ecb7f5dca2afdf9ef465569a4b0374716f604ad42a6e0271e934b09655e8e2529784b69b2894bb399b02aeeae30e9e7ae70a2a8e56b9e775bd978a04c728e3951e 828e5f3b1c91e1c0aafa7c85410f5f87e818808d1374283b8851b30ca33fae50bf2485df1e6769b1e0b7f3ea9f1fd026 +9a57b63a4f418404e8f5dcf3052b9bc04a4f6d2c33bde8651506d9cbc5542ffb9023292dea463111fb78913ccdcd182faabbff9164219b8900c7f9fb394f7d9678f77b18f8d58526ec64d7c1328953b983a7c416583e05a069cd76aefe26e5f5687b70abfbf9f58f052dc0863b4fc3bef805cc3bb05bf76a83235af9d6adfe66 01e7d4da72b1d82e17a066fe387f2a0a7fa4c60ab993ee09710531789186077f2f32b42ddda497d5fb57356383e1f96973df043307f0b6519430c3f0d40d62954032872fceb7dce9 8c693f3fa5d0905b6ee2ae714ebbca8066a15cf84fc49a1dceed96d33e26f68ffbd1c9b7cf58c71cb720cc02f883538c +97b79c76d9c637f51294369e0bb52c4189f2fd3bd0607f91834aa71b3555605a89ff68e84fb5bda603f502f620e14e8b0c7affefafa2f0b303009ee99653ae4550a05315e551dd12a4d8328279b8150d030b03c5650ed4f8d3ba7c3a5361f472f436b200b321e7863c771e20ddd7bdf739c51de3676f953a5501e4477aed1bd8 015b7271d4319db5743119c8103a7d4c6d57e9c62f3eb93762156d2ebd159980aa57cea948e416717d715a2e458851f1b2e9ad4172bbcc53861db29c3ee0ba8e82617a5866170847 9656c8362330467b12a4801d8438cb0042c33d90f7969fc5cd337b195e11a563dfaef7a17c9d64a8fbb9896563651fd6 +564ad0e37c9c37a60872a4780a723d08d1159ddc77bd834d74c1025cdf3cbd5338c3fc07a904fcad9b979b2a2ceb1a0139af35e5112305fd662a57af6312624b9bdd3a64849f95f59a46ca8feb2ed56f87f258518947474c1729275c4d89b7dd286ed65f286cbac76002cc63b92a73ab6bd13c4adef282f32297e441bdd8fd36 007219ea7917d174a5386df985d0dca798ac9f8e215ab2f0003aee929a2dbd91e37fedead0ed95b1e8aabcf516bdf54337b4aff7ace4c6b3179f2e919a49db50a41c9d4d58d4f636 87f3ec30b5c47aae826268009ffd2fd3355bf5cbe6a759d31b7a37bc1723da07639d99517afdbb1a203b275a8757b35f +072ed5b14754fddaf54e20da42432df49bef38f4a3b1841b2db457ff86c44880727aca945770adb41269df41fc17f6a687bcaffaa45a3e59070526ed53b8dc3b78cf9a80a85461eaf4b477e44d5ec4c2bab9c05aa747a5a520b35fd09e8b44539d060ba1c3470267e0dda111b15dbb587614a46e1e477127f963a16cf3a43ee5 00bc623152253da24bf8d752bd78aedf7d5f6a2f889453ccdec14e10753335ea8bea83fd181a1f3680ed50f2324fbeaadae160cc85831750e021f3e44121ea1b1efc29a7d0069479 a9fcb93f59805623632bd80b6e4169471b654ba9c2db9032a0a6057cf37cefa6e4e5c534436e956924047dcb4ae298a5 +e660dbdf3e61af39b83b95d3f1970f66d616f03273f7dddb98f768452b21cd39604a31cf80590d4a5e4b0d4917519e10fd325dd4ab7a52d70d154506329baefe0d5816f514ae109483122b4fa8fa1ebd7fdf1fc4e21e8d278a50c05d81c8f489596633d949c6c8fea96fe91430c01522a5afbd5042be8aa47da04581b2bd21cc 00645947d981d258f2954558c31022a3b6ba5fa7b675312f794cb61bfff1d9ce87267e4a1dacb7c8fc58624d31c85ebe22f80d26a620fed5df5bf38515e0903f0b69a606048197d8 8c16b1c6e07070ae960f01f302596aac69d647b6a274b7017023a30fcecc1907295406414c2ac2280db341e46111ce7f +8c9acbdc431565feae60e08bc7da113e12372ed373f1e1fdd581f98c8a7b0c79ac4aa42c7ffbc963fb4970fe26c5b5dd314b7051fe971c1186ebcb5650f7f7011a924de893f06961b8c75da7bff331847feead4abd2e8b9d6ecbedac18f4eac207b948e6e4215e4d5cb483e5c66ce7ad788cb89604d3a3e051539094079e7bdb 014cf93ca69d94ee8fbea0c8da9d76aea092b73073d8f5385b65c6dd4d567fe86bc2cfb8e8be890c3c6cd9abf7dc3a17eaecee3d7a9455887863e496c48dc3e47821bd3d825b6bed a1cb66a80d430a6b05be6eac895c82a4ba5ff8f830e4ab65219367f92421ca94523083506eaf87c8c58862f90c7cbd0b +53ef87d6ac7b9698f40b3ea9f3442e7b64207b140b7f66f73fb7d5f8f98452d30a4e493b6c0e3268371e88e612b818d4d847f032ed4983817d020411a52d81fd2a17b58ebdec199d817c2a8ba77042bbd747a6fd4bcc7e844ea829fd8461b389aa0b5957d92962b6d4e86385a8fbca90b8fac40944607117e9a4ef6dccb8fc1e 0033feeaaaa28f16bfaf5ea9c7319cf4561ba4fc55327a8477b6cd58ef6ccad3962ee1f3edb243f3a04e7e49c8e23509fa2d63252adb186b8bc7e9255cd61fa9bc45242d42da3a68 ad7986527ca15d4cbda3201a658b8ece83349aea9752dea5b372f5370f5884c387e13e72078bef602d4d2fbee4f91140 +dca1b7a9a313ead11c2d54739d9017ae27f9d08b3544e418aee862bb57e427636cb6aedda28e10f12aa15d2355f4f8ef112a86fec5dc46e6acef693cb8fc37c3e4885f3be3d3ab31ea4d73a0de904e95c7135a149f77b621d642f9bd8ba192d39cfc58b6f19a797c4f3b4f3a87054298e3ce5eda0ff7f44f8134c9a108285dfa 005613dfb53149bf5fdc4e08ccc1c752b0b66ab43aef2d008ed40f3df40fcbb2938d2c41e3ea2dd4428aeba9059a97efe5593119673866a19d27a2ee37dd357e22b6bc849e7e22cc b05bc1d8abdb24fe6c86d7a4273c30c80e32630100b0981f9ee8d33258dac0261ca338c13ca69cc1ae106a89e959122c +aff61d62c8f5c31bbb7d0a64a6ac589e918bbf2f13e7ad13abb9ac26405e267249a7c9922139bc28140833e10976b87e91cf28285274b2b48b63d24ac94c85c70fafa78f8ad05955c0ce6c02b841ee196dab12306e3e3d6138371217e2b474f7e67a80bbb78a47e374ffe2c9f86292e471c551da50d46e7b5c8331029f369767 011b92c8b72b86c51903387a65aa206988d443d1988253329ad3a89c902ff1ef8cf73b7f2e4aaa352443bcb833712d94c3e637ec12cbe4c2d4606878576b17fae1512fc77785b737 8698edb11048fe80d6af8346082d3a4d7e01e123d87406f54c1ad9972b79d91e97633c739172304cb66876a10459e5ba +721017294f17ef351e41256b57a64a79f3636628c4bcbe676ac9a2d96076b913dc4b246c9945183ec9bd2d251441b5101eac44e2fa1bef59dec03ccd7fa5accf3b7d094d68dcf78c8de4e2f19f56bf0dcb3b66b9421ec3f8b353b9fd74feb2e9affe0bf9aa421b6f03eeba3ffd58fba56b3ebd094880e50de01ee62a108a24cf 00c3c90d5ce4375a08b85575faa78ee6bbd9e5571ce5a90582042617b807339c282cdc3b003d82006264b1c08c20af4ad4549fbde53d262facb98d923d81b8eb6093374b6a1e84cb 925690b2e70468a7bd44479ba213073b85b6ecd381189cd96552a75c0949b06147b3020eea814bb9517a742583bb4129 +e2d1f33681759adb7954bb5248b0db3c3885fea0d4c1c0c226eb1e6d2d3ef1b9ac281a0f1c2fe5175b67114b6a501e2426d1454bd5790dcbc4c232cf06b017de8a9bb39e6033f1edb5003e8de3b44cc3d6150c3c952afb442952483cc688908337b7c1a8b5c9da70937ccfa98b2b0098c530ff848010b8e8ee0a8d65283481a8 010f184c16228d9034271332178ed485d10b6aa76003efc160d63fea26fbbdf5552205ac7df0d8c852a1210cf0ba512f20b798827b36ad56b12a826fa7dc1db45aed264ca6822659 a6995d7d2833134cbe369a0a34a222f508d4214c768ce8ed38089b012ea11970e464a812e665e31b6d5d374a4cc9ccd1 +414fc5d2bd56b30040e105cb891788792da595583b11b8fcc7320f40dbf64d9263532dc57344dd17573c95eedf851668b5d552e8796af205f3a0043af1a829fabc2e93d9af9091fdd9e0fcbcc9d6d9ec960aa60e4e2964c29a2f375400366480e513f63d124db7745847310e69a38c8455e4e602056a6a4a14a8694155e0a9bf 0181baf9d497159f837cba58a11ca435c442e5ca792ea559bff9f6a1f562c05bf6bb5914afbd1bcaea75b35f88bdd832314b249a5298622c89462344d3f28a44ba3d059df432fc71 a49b6c71c53055757f90e79459cddb9ff9894f3cc01808951b6bf17afbd988fbd8a48d4a3284794d91b4821fd5485731 +3b592cc8972a4782870e079b82a50f84b4c2d8ca90bd500d1ce5678982e266c391c556d8162ac3aab967154d072dbc0ba1dab5545cf2651753dee2881eca5abd412fe624bf3f9d17d33692d21ce23ad15ccffdfd250cb1949e73c9e40a64ebebb03852e92692dad1d7baef97fe109f35b7a492b343d4b643a4a7b1723eaecb64 0083fae86ab96bce99a53e50b7eecff38e4e25b21c4b0f6a4986915de245eae24f16b6a00a4db159ebc27f5a6a072da94ab6be5bf75f5eb3f75c4452bf4ea7014392eb1e02706fb4 91906ebab411806e492a1c4bbe36de4a3e7b370e6358239097e652c8009d96e79c1fe3b04b92918950b8de35684dced9 +0079a02cbab3dc02601fcb5c8607d555beef7cd71a66911ab6514a4ae21c5a9c0e166f8cf5fb198ec5a49a96e17cf041f35f00406b79270ebfe56dc6b8417d2529fd625686ffbc8f69685aefa2fd30a937c02f25b48be4679e6fde821de928b33b12470867def874bb8c7c8038ab6594346a2c44b39210d3610994ba60a05e06 01a663efa7bf4d8479bc535fad71e9b5e4f4281aec55967baa008ba17ac2f89cc3398d30573edef29d590fddce8cb157f655e92779f59e7a18d0327d02e7daf4c1216143b3688fed 8941a6fbcebca87542c3c428bf0855fd1b9ad5545bb8a13e4fd727c5241b9a86980c552522f4333104afe0a44308d744 +88573bd94ef50459814806efa868ebf92b066fbc2f7a4be9d2fa06b9dc1a72f72d783a6bcbc107b18a6314511bff217037a2252e7a5cd34cf9d5b2fe9c7846931f0133b2e95876cb800dc4ed7c4a4e4cc4f1195acf99fb0ec224b1f8fa8af71f72d390eca9d6be3879032a318734a63fec336c79035a43f70271def10c4955d3 00088d1a2c0219696a94337cd56516252b74139ea0733b17fdcbf7692c3e5f6c3989e5da2aaed7468e65a5d578571928ca273ec3b6aa72cd196f560f05095cdc8346e5d31c4c2e0c b6e3618e2d6fcced76ebb098fdffcacdd4236647c3af5e7dca83d0ccdb7a977f918f29f9135730b57df26fecd69023b1 +d0e02045ece6e338cc8ab41d4a064c982ccb1748c48fc2fe0a6f10bdc876094358a6a90a45facec798a83cc95c6795cf0f0d7c66b77e22cb114c1432bfdaa1485ff35b6a58107cac3b7e58cb4f6c87c68db60b751e78f1fdfa54b8923b98caad0a4f31226956d065c083ace5f1e9e91944dcca51879d782e40358d58ca758750 016cc8a0fd59455ed8d4de561fd518df2e008f7dfaa5f7f29ac2489a411e233917b43eb3ebe2596fc824be58871949545e667dbcf240dfb5e0c615ade0179d9ea2a1b1ebb8ab9384 8da6033dad791d21ce4d720cfe06dc508618fa423b7dd6cbf78ce23d6fe6fa6a006d404d996e50fab0530df8c427fb80 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K571_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K571_blst new file mode 100644 index 000000000000..e4f389c25811 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_K571_blst @@ -0,0 +1,60 @@ +964ad0b5acc1c4db6674e86035139f179a9d5ec711b5bae57d2988456bb136d3aade7ac9ef10813e651ae4b9602308b071d75a934a6c012eb90c5eb9b2947b50fc97b1d36c5bf9eb13a7b06c94212c3dcdab402a563262298defff62b836ead1f78f9d20713710fb48115cc5045ba15140fbb4bdf516e4150d830d02cf30963d 019cf4f4d06825499949f9e0b442586fe1bfe3459813a2b92cd8de0f775a4735e02655702ead8e60824180761808d9e816d60bdb0238e1e8039ca7bb63c92e1cf8433ef447e64ead 85433e738a656aa00a4eac9bc5ecd8d1ae5c14f8c56736bd7abffbe3141af64a43b07b9bc56b2b44a8857a3515b1dc4e +baddec4794effa668cde267016dda67bc70b847919a9aa595f93ba9dc27354399ef7a607fbead31e57a8ce698beabb10f313d393980425e67cf95be45d512f00e950c0c5409573ddc3d556f23daf056259ee8914e860562a674311452fed780b3e0317a7fe93baa81fb98df3ae4328b28ad0ac8f8ea33efe24faee658ad026f6 0098521a732e72ed945a549afc92318fef7156ed1d1ed9bab93b581478cb2339eb32bcef705c9bf61cf2873ddbadff8ff3806740a2e30ce67d1807a8179dfd5d952e6f8a583baf81 99519e02e33c1e57753009f4ca2556d83c9fd26821340416547c6f2de0cfa70f934faf911ca9bd4cd1d5e5827767b025 +7ef7138fc657492d229054f8a50dcafcfcd1dc06f1c16640af3f658907e2969248b54416066eb119adbfa23b8dc578aef18bba79610b9cc109394b900a25e55a779230bb858b2ddd9499a7775d392328db9177aa9571c2f61dd52010b48502154e914a0c55a54edcc04a6713cf7bda8744a893926118b09df877d1a4f3d95e8c 00336fb21549e397a190beac38a1ee10f0551952da15f71e11dfda415e5ee08da2356f114d450c661f52b2b32cfc7b9be61732672691a079f0927989b7e9f4efe6095a242155b641 a78f2e391ac149fc310ca468e07ab06fbb0df5bbc3a08e3751f649f55a8394ccfa50d4411051e8bfea9582f3f14a1269 +d58e1ff1d49a471d0567ecf8f29173dab5fe5f6184ab4cdd095c231fa7b82551f99a482994a46c3d8ebc07297fc9e952a5dee7d5f199b119f6f8b250f8fba45701ac252db725e75c4da27ad77d59a4eac448e54a277986740dfee6596811e59afc9755e53d24b826c09e497e29e69a22bbc85be11763064e9ecad7ae66458ca0 00e287ebfd9ba294128cbd484fc5121d271cd33e685bb1804f09b40aaacf64b5a9f2cde9b30a4a02d3a9bda97d92f46bb8787b3c61f280b1e1a0680f1f0679d3bb34d53725d62e52 a4e5745875b941314945f8f3f28960c74fc8ba9e2a6c3e023ee9b0b65f1c67592ec515ee540672a4cee66a31e4d31c3b +4949ba765c14c31f68ee0ca26bb42ba2edee63537de4a6f5c42bbd862c21288d6ff48145260365193c6fd2b56dfb014da26b8a483776b717c6874f627c9a622154b824565b23e178240f53ee9748c45759ba5c035b584df0f09504e95eb9bce0301653aadb860bb25e6ea6b9606e0ec3bdb8089e6aa0d5763d331757490715f9 0149de496fa8f88b2741864d0c35b3df666b87179b7bd06cd426a45f13bc87ea9f50dea85e1fd02a532630e0e3a231cc3e7fbb7c7ba85b40cff1124e72c677c6a3ea6aa40ffc64b7 a4e1d20aff59e210425570d50a73863d9ec317807c6c476b8861595b95186bb5cef5924645a1726ab6ee809849891772 +5bc63e5c50b1650f0ed4a599960f1e4e11f6c151b2123fd71d9e3c44662312a74b6854290628e20b30eaba81555acb2fb49b640bdab2528619c7fcad0f2a2880c7ea232d427d7c935fba2313370fda8863a7e7e203d63ea15d0cfa083e716ce6068c63fa616ddc225c9e413e694cdf6b355cb1293af5d6cdea51168f5634e878 017605d7c5873d870462375d741b4bc6375f3d47f7f5e9d998917adf2137a81e63b66917b3dda8968930c4b850f2270eb3187fc756e2beeaa67fe0d73053e6cc0ff0004a21250551 a1fa533323bbe90ede4c77b638d96ae9ea139ed757b80cb6f57d00a093676ea1ec801f104df64e41a3c97a55c55d084d +610f6633718e49d232b3798654095e2efa0de11f41258b27aa01956480c870d901efa77e109d5f95f1f5101d3c90fc51312d9b3019d2e42e0067eed7b457dc7fbe5466923b62c83d7347e4dada571b57813bb9c21d5e308519b8eedb7a7706508ad04aa69698e03636eb30fd9fb363ef3a185756494ee01175b16847f5b68076 009214dc2da0967912c31995cb8f5bcf4bfa832c5a2d3610f3a9857e5eee7c77100d599d9ed003b4106013155dffd6c48859b846e45e0ddbc5fe24f4891c9b2df51407e9cddbd974 8bea55ffcb865c6f8ff6a054efde446d91c77944491fe3cf5335955cc2380e17dadb670c55a56479dfd6f65fcd615775 +c548f0546cee0c0400401cd540a0aa9377f27ac64492e6baaf38e794db4df83e64ca3d83b67bbb46a6c269c04c2725287cce0dee984a0d468c9ce495a7e554a6835d72c7493bfe88dbd5a044a148c89001b8087fb03e57c2b7212d0b175d616333a9affd8a1802dd49ba9be3ab6c6d9f99a5578d26cc4707a5860c6c804d69ce 0042f2682e9ac8b76f3c0880e12c292524601dce9ea6982dcf68bfdb0d3fbfb50dc9229e54149ef09b95bbf624eb04ce1427077f30d8536be9f69970ddb449ca22ab8368d2689ed4 963b6856fae0a9fe45bc0355ef5d55490b98da60a409dedc7f222887fe9920ec7bca691d40b5b6e0feed46c4bc87e541 +9431c6c5237f6b4b35682a0c32f68752035c8b295a1763c5dbdfd73466cea64a00ecc11356d02d2a9211dc54548f5db1651e4471898402c887fbf45005a3bda271df0158c98319d4d6751b8ca6b07100182957d5fe0d97c4e2294406f83e9afcae4850bb089f2252490417b5afd8f07f4c795fa84c9c7cdcce26bd97273c0072 017ed9a9c75cf66528428e85b0f019e3488af8b893b12023ff1b4ca9c3691b74e594539afa0f4d7c3863d15399b862f15e27bb077392d6bbd546ddfd46728c75177338466eb2f4ff 85e3ff29543d19bf398f78b2dfb6fe76e46b1ef51eac8ac16523bf4ba6df73f7c2a1765d7541081e8a7f04f0e5809c37 +417cd5f60416f17081d2c70e9a510114e08be83573bf9deae75fbc3095dffc8a7f7325f61f9d6565381710eda871388cb17619e4448836076338ee309a2bba5f737319002e259b4a875cce1bb97996101c9a7abe0278dcac203a712f0809eb3c4b85a9c380550ab0bbc5067a8edfa78abf03c09b5c08f21714e1022ebfcada4a 01bcc09b3f2f1d26ab9955bff7e8c0f85c8a61293511a196b53d7963f4a4503849c96fb4daa68c9852ad9185e01a35f0bf298e34a09ec352cb6da34f89a1f23e8ea27712a8f43aa7 8b0793811122e53239301e39f4f6a7de6b14bc3ee8dd4189a248330fd41ccd6d9d3ba22eb8eb9e05bb98f06d1ca235c6 +eced8c412a153a643ccd69596389f83b6a36880286f8aeede503452bef8305942d95734fb5733f37ffeceb1c2dae7b1396c3323de11089082745c28a1756f784423fa7ad68bbfbf0d93ff8b7ad62220500df6d6895788402c1f5c69c06dd9ef55e2401cf297184e411be87c1bba657f847208c0e750f94a3df92f253b377b4da 00ec52fc3d9c272ca80623e06b15c35f349b13548ef7ee400bbfa04196850b3b8cc7b239238c827f9b0a3160cd97969ce21d66752791f5896e0385b0527d4d77e4b9fc70f04d73b2 8d566016a522bdd5eceb4dcb25b621bf8d1f299129e0073664443378a513a05a095abade8533fac691428d1ccc4acffb +30e83ea39a92036e22b7bed7639eab5e5be1d00c20b4a9b9afa9a0d1653369cbef363c119cc6f921c8f84663949c8b8dc9b743ac2b1861a480476e9b64c8f333f34b6fa0e1ddf09d49618ee4f3c1f46751b5595f0aea413d4ca46f3c26b974b112cbe99c813a96a4423764c069454946f213c5f066ec38108f947abeeeb02fb8 006403de7627de22d1dcf6b8da5af62f9ec59ec065cc1ca1311bb98aa439a6d5985619b17c17a70f59e17cf180ea6828ef57f5f1f8ef05680a9fc12ab7faad5af61e4e11fb45d341 8f855e26f8be92377ad1469b207fde017b5ed9b29c98f5e5753c5f6fb6145ef4820d6584cdf51198c29d26dde3ee901e +3ed244dc16a5cb292db4b1433b0ca3226913f07377faa20c6c1402cb4d026de808ca74a6d4ecdd7c4e662105bff6edb9fae0117c50aa053aef677c0750c7a446edbb879110030758912e8fa666489d702d8fceb719963b24a256429bbcc869a1f4ab9de9db89263e3684d4daa1df2ed94bb59dde2abba63793e5f82aa2e4db83 001fb980aef64254aeb9bb613ff2fc6967503db4bc1f337882f1566cbeb57489cf32e34f310549f41cba1b951f487453c29753a184e33330e90d4b973d2e406c99a239a5c3f96233 b6c7dac453073f03744019d4abcdc56b52b7e4f549e45304be50941b923e69bad835ba83d3b6df3cff26e5888b28c08e +40343935d9423ad30f3fb1832bb08a5d20ddb3a55b59057cd275320db4a5835471c96cfb7d67f41ef860cf5879897b8dcf307bd1a52a6226847b768ea38ff1858f59e64cd635b51e6863773cc6c64b363ec47ca39266422406264668415c189e2f92447ac4c63ee5d74e95d1e6af05016917ad237f482ea0b02aecadd370a8bb 01d96dc09dfaf602789c1dffa5c9ba130832badcf180429660daadf4cf1be5cca92fe9713173861670eebfe3a0ba25bcc76aecac60a756f07b69687e05c7e25984a39556469f62b4 90b7eb34f57aa9f04fe9da56b7b968e354a8687a47e5f8d8e875050ec051faeb7678739bf75cd268ab07f52df36f308a +274567f8841183e68c4f6c6b36c5a52fb0e88492e4076b9cd768bf571facf39dad6affeb68941ee326ee461ce1f33c26e4bfb3c9e0cae8241fbcc14cc69c1af68701fd0be3def1e87b7d52b682ebbe1cc225c1bd177b0886e3698a06d0e410a1f92c9bdf7239189f6acde0d0653815a72987671b415d1e8a70e685d6e5b14c33 009d98b32c8eacd135ffb8e13223690ef02c0c1f29ea8b4da193502c8cb3f39f9eed608c02fd457f2fb685ec4595e8fc8f388d26778d225d2b18c9bc8b199d8b65c0d1a6af33854a 848670542f7c62921241e6c3dd0f7b3ea0842eb82d8849d78a881be5a5979ff64c1f80e165810d143dc10028c8a6a80a +d9c99b8da92d3c2e40dea3c4025dc37770e867c4d2746c4d726b6de24250591a586c166c88acb8ed340e161d4c81b9d14c919a1b06f1feb22c5ce5fca2693bdaf4994ac72c8983c87f331473fd094eccb3d5f3528e69d487562fb5a65c150a8217192f8aabfa7adcfd0b6916d5000248fbbddf1ca2f38e3d9ed2b388998b7cfc 004d873ac744c4f68bb044783ad69e1a733cb8b8f483f2695bbd90c4211282036ad7914a53b25c3e890c6824643cffbdc4138d7ff457e3fbb99387494eb5cf2bdf1ad243a3a1e644 a9f9446f87ae24e3a39b274dcce8d19aeed249f70c14a98a0f8a00c007760c13b9e37a3c607f388f6e83401ec9a00a2a +d2b88a01fa17703c99e5b867c645e98feec0d6d1afaa20a97b5fce9c23f0594460142af4e36a5739b8d26d3ba35a0263caa5429b4abba157f359fce701c43372500fd2ae1bc2ed80bfcaf8cab7016ff93d4a27f565b7e67fe7dde22bf02c48be12114fbff2421517c825019c0ccc72d927bef156140d7f0e9b6ee37af78c3efa 018d2eb947297a054f8a789771dd875b12b26ef057fb91235dff3b062916f85aab3365609bd2a38a861439c8514e33f174c198139354e63766942f605107cb1b9709b782622b295a a69088cca54cc70bd26546e99095b875127fc8810cae39f705f6cfd48994e4413f3a536ca6ae2b1a5956d387b189c462 +a704a1428cc894f958774368979fe075353b56790555386e3b043dc6a2919b94a11c7f85883f46b4d47b324d349c28c667bf9a000daaca1d7191f2a0fd97a4867aa9f72422134a690625408a9ea4b723704690b69152655f9e9dd5fa3dd94814d97dd4f13e85c3f9bca769491c2461fbd17e28afac00bfa81371d5039013da8c 00594fc0b7a5cc0216d2e78eeeb6394c8225de795f4b73bec48b2f4ede185ba622b59a16dd3eedf8cf2c94f2ccd6dcd205f64c97cf1b7f1e34129e94b5129502909f43940dba0746 89f88f49b14e21835904b12de40f5bad79ed6af44cd851e8938e0f063f4df373e40306d895a52d3b5106706f71c62615 +f8a87c4acadee27a908718461e3b45060ae4ebb009b10a15926460bf219cb7e75dc3a993fb9a741b94e2fd71615c50f6df958568f452b2cc284f0516816bc0d2e2d45f663155660a26326f63f4aa42a6e1cc8462a2ec620a365257ec042f55e4047b62af689592a1a072553ff174dd629a4f51837780ca232cf479a68c1ebdda 00f000631106c5851e8ae0802b01e7a8a8540b427a8a3956a1d36f0600be89318032320cc420931d825cc964e823745c60aad3437ebc1c91d32004472e9677605fb708e5a71a0d83 8a68a8df1688084f1b6b11e7379857f12ffc5532942165928760686da8fa71161315316f0e2230275462d984dfaa4d41 +10b5438294a77c7e517ecfe8f8cd58d75297b14116aa93e574996ec4acb21837e6297cc0e7e7b5861e862062f192f2206a01b1caf42c6d7181d02c7d62b76c2881f8479449b02d32c6f792714d8f70f0c75e81c7d9abb996be87f5ad9a01fe42b75855558d5f00df392b62ae0d258f3f67dbeaf07208952e679a2c573aca941b 01023997206341c6147c536d034a9c38b4012035dc2c9b7ef0bb9cfe65e7d788296f055d508a1fd957b2dc7f9eb10c27790f15f30d81670945e54a508c57b70b46b4a09f4c769289 8652cab6d4d4d4b5344156a14caf32496bfca001f307df3eba1b534cddc7e666e7051461538da8862a77bbf339211e0a +d83a52d43216fdb16b1b40469863ca8eff4df9fa358deccb5ffd18b3e22a9d654aedc98f3dbdc4f5b4e56b4299e25d8a5a38d01b34eb93de382df1ae4d1c7f966e84b84c393d167aecc6f1192c4b42cae83748b1ee3d9147ce7de74cebd122695b455e8082f86e3e488fb0f51b3b7edcd579940d1cb9d045296e5e38f201b7ef 011ebf320ecf6a908ea5b868afb8e22246ce84e743e1076d6185ec65dd79043380708bf8da4ba802c3b93b8d15509bb7d7de9dc29f1e9fb0f0f2cb97a26698f955b1f7ef668122be a5892eaa11e722e2364171b652babb00f7d615054a4ed2aa0c7c2f6bd9349fd7b7dc93e8c0eb26f7e58d36ea158d74eb +eddf5553ed4db6e8ce72cbcb59fb1eb80671c884ebd68e24bd7abe98bb1f40806de646f4d509be50a3fabfa85c5630905ce81abfad8a55f4cd80208afffb9056bc67d9dd7f4660a5f924af2a3745eec2daec39a3fe36131fe9eea444b92d31f6a125f12125159ba095f89968a7028549466f41ad45668a861f671050d2a6f343 00746d5c824d78f42a1fd63d8fcca61f154ba3e75788b7a0b87f53e5420e23a935b02eaf67bace8dd8a8e7c1caee30154c2428e0a437cf12e235f41c416f92fb54528865fd4766d1 935f4cfa7d3e72b4d96bd6c754376cf3cfb4f9b3791222fc65c0b4b3fa5727cef7ecc4dcf6d137e1f3aa8a200ab32efa +3db94335f6d1a125309622c0a9d71bde1da09371f0285a93bd0aac255fa8f10a56074e0f6057f1b1aecf2d86a2319590ead96a2ad1336fe844e09339b456be32374ba2e659fbe9d0f2cdd83444d117d2ce3204ce4b4294dd05405634b84747ffb4227160c4e5c2c9da9815b0c6d20f55705f16cdbaa13d107ae666d707ccbe6c 000670e72ac2de50dd2cdd975a6cdab10ac45e37ef7a28c685d77447051496b5e161f8b1b93f6c7f32fce8ea05e94ed35fd7cb28c44bf51ea29cbaf5aaa31d6abca30a89430323dc a06ed193051a913cbd3a11dc2493d679e414c67c55766296cd245055fd024b033ad48a0d3bf02fad29e12443d37c5fa5 +69166ba40768d0a3930325405edfd85f3272f7b8e600b0b319f070274c91f9f03d0e6ec4bfc7b4445e91b87cecabfecf5e77c7301ee3c6b0affca2fa02c92216698705eb75443eecc25438db2d2fb4b24f4195d6b9c05c53e0868d3e58477100607ffdc31b18c40b4ad7202bb034e58653daec0f6b33c024d42a3fc84bd8f86b 00369a3bb96f884983c23281bcd04e24a3e5f6359f81e3c8e46f3f6b865eb6bdf98a630e90646275c587e41b546d3ca7688cc207afda15cf9b25cf83bd6ad27908647f3f9de59de7 8c3ee9557e465b4d95aa3cbdd911c154711f0db2fff8337bf35c2e1295732c78d998bb7fe4dd63efab89e8e514cb29da +f64cb668b72f1e6dd026a478505c0eb33446ae9a2993bc7648aaed02e172fa9a0e05eeec61e756ba246c1dad7e85d3f01baf734b1905c5bbd1b08d833c2cf1e079eca75b866d705c407eea8618d23ebbaf269c7185984b3bd4117ecfb295ee6b47eecc8d3a78bb96552f6be314656f91caff793838226662c75cd7804b6bef79 0026717b039df834855511815d5665ff9b654facab469390ae257b7f0eb4dfe66ea0dc037242ed0c13bf229b8f7ff26da9b55fe4750d3451c62804aad493c179ae45d08ece5af085 98ae695f6e3bd7c4f3dec9b095a54fbda8838e19192eae3ffd62112008c6bf57b94ad3a1a950523cf991666f75b23f95 +51ee0b98eb6a3e3c1afcb35a33697c048dbf61374629ac5702a57801fafbea4d6fa5a26c9d1b79d1c58257ac0106387fab2d4a1b7f8c0dadcbe7c830613531b3c209bc17f792bdba1c1fae1b7528aac53dc86c2094b40194577325c05d2258303a2d17c854e7449489c43991b6877a50692a6340a528a6b188440ac0cddd4c4b 01d642f2d393ed4abea37173e4a79534af87adf534ead4a0a1c46fb047619221e3577e6b8bcc776114d01159c736ab78af3e53feac339d7afe58be8e7a8ed290f1dad960f1b5de94 b7689d3dc4b052a3c573a6f1faa58efba682fa4ab147e76e4460611d9b064d6892af9c01bc2408a99da35a241a85bd7b +feee50aeacaccb6b1c3d95c6524044edb78322ee836d8159c4a4c2cc6982480567c4c6cc4806a564876622266e1ebd45f2f4be851b79da025bd57d0e6acce1ec1c8c255eb89713a1e4897d4ee0f7a248b9d4bd3ad5dc0e57f60ebfb65691e164bc908956a019083e923cfd33dcf37c735af3462768a1e14a8051d7aee74d5228 008cb70be29e83f697a3e2f67d86f1c1ec9a163b5335cb4a06004b6634948bf60b8ad9df9b27d2bedc4975265ce44a7884e57082d521320ca4372d38fc77b18d3fa05ad8aa5c43d6 a3462ec30e4b95501cf3a62b98873d68973ff54eec046e2c9af41f8cacfe0baef1dd6d107c6c1b146418692fa8ddf0e3 +b115f7370d6a93a90fd9dfdfb292956be34b61992ce1fa5627c5e928d74bcdeea66d4040c473306a0070fa8363c4303bea32f73ea3639b5c6676fa5a1d68a2cc1f91f00580d7453a23ae70af4cb1f1657aa82c5b305374effe5d67d559e46a6cee6360503d21070506f1af30bb000d2f2f85caa6465810f89968f33abae81cb3 01eef463771f9c6285f3257691dea0844687606d4dd00b6020517f190891cc1be97cfad21d147ed8881b5a6e19b22ceeae30e1132476325f2de0e9af2e14c80b8c780a9d2d6c96de 84f778114992527b7b126a9d3dfd3c50717f9bdc7f511d1afdfa46bb2b5327ea9e309e39fcf6c223e11fa9b641fcc706 +726782eb0d9720daa64e4a77b5d8dd67a1a193f15eb6b5162e3d89c925ba63b7c7e1c4bfc8d6f11915b0e14d16ab53ab015317bd5958b0beb6074199e05181915496575768d026c23e92e06016598de008c3718aaabcda8b68bebca0a73ecfc7327e8d3646106b7d114dabc46cfe56265c326ee56fd2ca87abb5bed8f997c735 013bd452b0880b101df1aa65724fb60d5d85b37ed5419027481661a3617e0fb37bda1151b9b5b41f908ba832011f7850b75a07b678e5b8cb35c5fc8b94a625e4398cd5ada2b04cc9 b27519e0df802eb95a7565bc0173644606b2caf4cb9b7fe20090f5dfdaefa9010e14e5f159eb4d4232a7d2076d5c5372 +1c2418243fcd89c6382b7c3b2a8c341f26d08174a9e9296c4a5c98c5793a0fa48dce51e30811a96b515aa22bf9af89a43de06d696be1e531c5dece1f69fa6ecb7f20be063c602a16454ddafb14385ae3f8246c3f989d0566e06e7ed1864502896ea19df8393259c4dab3b3380a4a80b4103cbef4f38cb69198b7cf74ce94883b 01288141ec2244e4bb3f62daf4ee588aed09ce22be55e3d42e9085a947c1f8cd16533635d170bd64ae0b417346fa4670c25d41387acb2a8e14407a1931d9f7c5358a14eca40974bb 8031d5d0938f2eaf515f9f12f6d6b386298437931a04e1f929e33b0627cba3305fdf31ea7be0a0c8488c6b48c9394683 +1de4b642ec7220c64b91561caed7832044d6e811ac909f3b199cceb0d8a7db91bcdc801412044f5c34b355b95a2c6170fe497f6d5259bc20715a38cb0341c88e93029137e94d895bab464bca6568b852340a5c5d6a225475f6eefe2fc71ffa42f857d9bab768ccaf4793c80c4751a5583269ddcfccf8283c46a1b34d84463e61 001fe06b94a27d551d409b0eb9db0b163fadcf0486e2a6074bafe167f9a3b4ce8ac11f42cf72f9a1833a126b9473163d29bca2ad139dd1a5e7fedf54798bf56507326fae73a3e9a2 b6ddf1b89222fb7dfef403413d2c7a4ac381c6b2e7136f91cf5c1d00d70a3380ed85ed3a7d1895b3d75626fcf8e53507 +70279be7d7ac72a32606642ecd81b5d4d0f95fbc3c0b07d85c16adf2788601e44dedb8e55e0f9e0b4ca3ca35f5be7511b0e69224a05204af67aae11ce154af6d594d47f6e3142ad183969544aa95cae1edf42bc699137f60178c12b10a67698e37ab9f3edbfb3acdf1b3513d62fe3db33b16cbb4e1f9dfe732c107f9d0c953f6 009cdc7e4945c485a41728f83d5188f539e372ff4fe38fffcaacbcb4522428e4f93ef4972556f4398fe17bdd885768f0fb5590df495badc794d4d274e22f2f4a2535555922fa43f9 b0dae0d74b68d34ce8dbcdfaa70cbe45df19d5e70cc6b16bfd606f1da3522e57838befabf7f361873121c738d584153c +4d7e0ad520445b6a5cb46b7c77fbd367614044ae6004494c2b3a89089287e2836c73b799cd8c90139eac427ebe335804c3788f3728ffb8edd7f49a4bcc76a9e24ce3c2299cea88c04645b82033115380f81b0c1d823e470631008d350cf0c0dba1915519985b8a389ccd8c809dbd5bb5051a79e631916e0d052d9b6cca18e0ef 002bc753d007c4491cfb8ce0a6c96455acd16d37e02c982db216b8cc1afd6d10c6be4e15a3988b8b8b86b2b5b59a5c1939889024849317f27ee08a06bd8e7524d4ad83a1de208564 ab2598136e210f5106680559d701eafcd23a634e4e6501ec1aa03d679e7e0ccb35f7e23eaa8920a55cd8a4ff62703550 +d49903f38b5c9b17542310425e59377f61f5b4f4740cd97371ee2116083f7758e69e7e2c1b0950ec6b76f96e3c91c721d6f2843afde8c7505a559c8a64bca2e665aa1131b75bdf86fb5b90581c7d3b61c2cff88f3fccf356ddf5ed282e27727be061b6925c51ea7f1a495f471dc8a5ca1a88bbe29e92338d3c9361460398965a 002082c6e61d0d72f040905d8c1c20d47b029f41ec68d6cbf43ce97c3b2a0a770557a33cb803c432cfbd3958fda30ec1bba77a6613c318597a85ad02b26c44bb77ca96d9cc1194ea aec3d1bc3d682904cc5928b11ef5d09cb7d585218d2ab190e0636558f08df1c15db8bd198146c98b97aa7fb5b4f9deb1 +0e3f4afc3e7b25c1bf2d98098a5a87db1224d9bb45adc6e434732b8722a708ab80a1f3f6ef3c5aa70d2e1dad3e4416b12cc59171f05736c4b58bd084602c344f2f0bf3cfdcfe04c64e87597a99de23ded64b33607f7c273ec321f6462518715b11e91361e89ce5415bfc2ef520bfec378244a3bd2a4b9b6b3d68815f2f75baf6 00e298c93351323e2c5304015a4878997ae4e79d1c32f1dc64262e534d4f2c4b3e222356ffce746763373fdfb936fd330d3214a18c07f1205b20c9a941331cd676040ba1fe3dbce7 830d71929c17668b3147a329b2bc50b419bcc24040950d44caf8dd1b9fad7402e26ae469443cd3e64ab8fb14ca423497 +8fe32671f6927272fd3cd8dd4e34d44d27fac8c88b41bf9a48039e914990bf06d1633b38b9200ce1c2a275b9c55498e5da2d0707322c3ea0a0fd7aff598fb801628264e13047c8008153e8595a0dc95d54e70b882ac2ac9314d2b78e7b93922da818d7075215e354708994af66958954c92c074d132dbb2488e5a531c755a8e2 0104f4ad56594c5cec2a988c5596d73adaa5a81802b40110dbae698ddb1f0b271fd1479c38abcdb9b234e69cd0da8a0328d2135c287d5b130a09fa0b899058e7800eb2dfcee95c1a b167677fac00021adf79a0becb7283aa288939e2653e1ff48b8f286a9399b33be7bd56567f2cec0ba19ad4cf096cb575 +a8fa01136a0a78313a5d160c32fe5d1805eeb3730c18ca0c47818e82c48eb4c9e5b2dfe3ee5facef9ec59b68f4e6f3213f77fba9f8ba06dcde546ae348d343233883894f4423331b536f62373a495852977a51cb192cfbec04b5582b4ece69f345979e234de32da7a120138a057a7119735c4cb19099bf48bb202e7ffac04def 00c4989bf33b3136bcb4ba67906eaff2bcbc6567635aa4b057acb7353ee87ba3cb4cb9838f8f679729d5c6ed98e6c4199cf58605f009c6873a1b8321f83cd3c0973b7a3cfd9dbaa5 abf7aafa1117ac724ce96af8ea436e4e021e07baf23013fcee2783a196f98ced080dbfd79f38197d2c638bcd11387974 +ba2d83b21c783d6ef2f3b7b10e910a418a9b9f49ae0fd37990335b3a3d15627846c9a12a1f31a3d0e062ad1bec5650606ed4dd06c30e50c1e8761a29f4ea1a20f74635d5dac22e5b787ac10f4ee82b338a641484f91771c128c84d31cdab0a6b9616078c898665655ee9dd4ae73d33b94bf091b064928b959623aa71ff73b4db 01a96f2ad56e31397e236cafc108087479c9823589a5fbc3dc7488d0e5d1199cf245d7f21f524cc0e8b47feca14c93fb760e631434a91188b32965053942f3bd39b3714f9d6f1a11 901e62d7b1255b54d294a84df6b8815fa650d0e30541dd5a1c5979a8f215b936d3f4b877e1ab9d6368586c87789c9a59 +ea2d5f4e9797bfc2f33f0fccaf530db2bdf8abcec00f09a0338eefdba318221ec0e050cad1a85c3f76b784c6e8c18da2b062f333eeff18b7b781e67d6d0a4368b8231a892e0f4103012348e5df53ac745e4d34e2cd1ee9369f97d4801ff485fc144b2007008036bbc07cb1c302a00054b54f3713919191e1d5052978c9c2895e 00c08ed8e0e0f8b0d0714b46a2164b933f8147692f18da97e5a108c44d5a5cf221cb50536e41832b83bff4026c6df156386235cf5e3e9a67b7cf9b2fa7707c5e0ff33a91601b8e34 8ec8a508afed903a32371e672d992b7c2d5ffb747cdfa49d01a91bee64e7cbd806929944522ebbb92c5ec70124c63a47 +b2293b0a09f41decd9d8e637b1b08c2efe612f33c9c0beebb6e05033c6103b958f8aacd125d7c810b4c287349f5f922d2c6ed554be597fb8b3ba0e5a8c385ed8ae70d5ae19685298f20e8d844fb5ad98db12ba7e5f45baed9045c3e86b3cac9bd55b614b82fd075954fc59bfc6124cbd68edae988596575f379d8921b594c75d 0144090a0ee38cfa21fabcc24d35139a99656911ad4f6dbffb77dbe74e7993edfa9fd63d2c4f6bbdbc8ec21ba13c9f4a3576b5d6e3abeab5af5ac81b1f2bb6d4c42dde645d854d9c ae75240e011aeba848177e4d3dc4cc6c4b40fb1483436bcaf0f2cd179a2e303585c4fe01d6f392c56054063a7aaf7c01 +acce54270252e7d9e983c08c993cd6b7e3caf482a9149036afe4665bd3d0662a6818047187872862d5718b8ac063477f693caf1a9baa8bdf2f36d411a796f2b46ab56f66bc94924229f8264016d6769c85d9bbb7d6bb042fefdb8fde1be026b86af2017aacfe38c97309b4689b23fff94f1de880064f1d3ad9d74dc804c41f41 01df26b672b2e3617b6b6c631d3c6be0cb49c0a690de49643e0f416215bcdaefc03fa9c708471f1d87476d58c8f147517ec8a14aa945ef001fa01984d5c3d81f7083ea500558fef4 903dcae5e7005a5800bdb3b5ef0e409889f835aff03088a1e7085dfd0ef5d32691de259b9acec1acf13278b748da2f35 +e25274ded4840df0d71d3369007118f002b83e2d375c78f7e29ade067db15cce21842611f3f015db2efec57da77cb9d16eb1e00a8c1444d48dfda569e29fca1ebf40a22fc646a9fd44460f0e473bde487634bfbdac2c312f66a1c2982c6fe76c54ac72b6c8cc9345e47cb319a974b3cc4bb40634df74b4ad7e18adfa9a71ddd5 0189918b832e9fa30161fdd927bfc267f6405335df3d66d225e17173af52a671138883bcb94c4403ca3e001fcf09ef4c6488934d6775af2b1da30a8f331579af2d0fbb530298d8f9 81d62be23da328aa4c4b49f80a3e6a7391ce02496cf3bf8d8e7c1246fb084aeeb3b90479c3d227dbfc8426ba3502398d +d8a4aed87c316012482819b03a1d91691f2ad11a2f46082497ea8f64880d686891f7da550b2ac17199c657d4eb9d04d5cb8eaa180f743b87d23b1c86103f9e9bb60f4e19f0ff9d160f180aed7735130c03adb62502e69be5c624ed7bda2301f30580ae0921b02e103a638f5623c02c186e3bfe6ff134c762a2bcac1f879a9353 00bdcc175eca3a399b944eb0334ff33c4fd130999c8ac0e7b52ac5b774fbad53ccc3a31024f5262b2eecfeb2104b14bb244307effe3dbe8ed25686dbf46a42c4b6f8e34010ad826a 940aa3393491fe434499ecb25af0b3a9ce6d0435f95b602f863674ac393adcb16c1734f4350404031a3ad26b221ec3a2 +acbaa5ffc4eee0850075c0e502a70cc7a897a919f5e7bca4e798385601a26f411fdae5466ba9f6b6d8d7f819a749b799fbf4a3bda9105063e74914e8583ed8b31ea4d22164bee6f14bf53afca269b901c80cb3265be32ffd4ca4bc4ddb83e11eff82ead6d75dc4aec8e5c67f35d58a8a156cd1c0351abdccc0c5396c8fbe6920 0007ab5a55a1d8ecb7f5dca2afdf9ef465569a4b0374716f604ad42a6e0271e934b09655e8e2529784b69b2894bb399b02aeeae30e9e7ae70a2a8e56b9e775bd978a04c728e3951e 95c68dcad5b0a37797cb1537c7643e0d0efc5156e65ba2d2bec613ce16bddb33d05a4cdaa40657104c0cef7b019fdedf +9a57b63a4f418404e8f5dcf3052b9bc04a4f6d2c33bde8651506d9cbc5542ffb9023292dea463111fb78913ccdcd182faabbff9164219b8900c7f9fb394f7d9678f77b18f8d58526ec64d7c1328953b983a7c416583e05a069cd76aefe26e5f5687b70abfbf9f58f052dc0863b4fc3bef805cc3bb05bf76a83235af9d6adfe66 01e7d4da72b1d82e17a066fe387f2a0a7fa4c60ab993ee09710531789186077f2f32b42ddda497d5fb57356383e1f96973df043307f0b6519430c3f0d40d62954032872fceb7dce9 821250148913734e99d093ee9123d50c0dc15abfcd0338c5b0aa9356b34d7e847fd3e6e34c26e44959125a99c67850d6 +97b79c76d9c637f51294369e0bb52c4189f2fd3bd0607f91834aa71b3555605a89ff68e84fb5bda603f502f620e14e8b0c7affefafa2f0b303009ee99653ae4550a05315e551dd12a4d8328279b8150d030b03c5650ed4f8d3ba7c3a5361f472f436b200b321e7863c771e20ddd7bdf739c51de3676f953a5501e4477aed1bd8 015b7271d4319db5743119c8103a7d4c6d57e9c62f3eb93762156d2ebd159980aa57cea948e416717d715a2e458851f1b2e9ad4172bbcc53861db29c3ee0ba8e82617a5866170847 a60d96ee11347a1b8550f29a0cf2045f2af92069fe72a1cef016c7a650582a2a38dc22bfcf35a8c28aa237b0fff4d98f +564ad0e37c9c37a60872a4780a723d08d1159ddc77bd834d74c1025cdf3cbd5338c3fc07a904fcad9b979b2a2ceb1a0139af35e5112305fd662a57af6312624b9bdd3a64849f95f59a46ca8feb2ed56f87f258518947474c1729275c4d89b7dd286ed65f286cbac76002cc63b92a73ab6bd13c4adef282f32297e441bdd8fd36 007219ea7917d174a5386df985d0dca798ac9f8e215ab2f0003aee929a2dbd91e37fedead0ed95b1e8aabcf516bdf54337b4aff7ace4c6b3179f2e919a49db50a41c9d4d58d4f636 a7c0afbf91f19ad44cf529968520af911797146169f1051f23b3e649229c27469bcef1f2852b050a091b10e80d7c304a +072ed5b14754fddaf54e20da42432df49bef38f4a3b1841b2db457ff86c44880727aca945770adb41269df41fc17f6a687bcaffaa45a3e59070526ed53b8dc3b78cf9a80a85461eaf4b477e44d5ec4c2bab9c05aa747a5a520b35fd09e8b44539d060ba1c3470267e0dda111b15dbb587614a46e1e477127f963a16cf3a43ee5 00bc623152253da24bf8d752bd78aedf7d5f6a2f889453ccdec14e10753335ea8bea83fd181a1f3680ed50f2324fbeaadae160cc85831750e021f3e44121ea1b1efc29a7d0069479 975ba52780934d246ff9c241b87d5ddf19877f79f4f4f88fb60ca9969cb7ad29f6b7cc2bfd05b1819a9e334b7c3568b2 +e660dbdf3e61af39b83b95d3f1970f66d616f03273f7dddb98f768452b21cd39604a31cf80590d4a5e4b0d4917519e10fd325dd4ab7a52d70d154506329baefe0d5816f514ae109483122b4fa8fa1ebd7fdf1fc4e21e8d278a50c05d81c8f489596633d949c6c8fea96fe91430c01522a5afbd5042be8aa47da04581b2bd21cc 00645947d981d258f2954558c31022a3b6ba5fa7b675312f794cb61bfff1d9ce87267e4a1dacb7c8fc58624d31c85ebe22f80d26a620fed5df5bf38515e0903f0b69a606048197d8 ac7366ea8635ee917a2a767977b218f571045b904935e9c2d50fc0f9bf9e3a277d70cb4c2a260365cd6b924e7b184dad +8c9acbdc431565feae60e08bc7da113e12372ed373f1e1fdd581f98c8a7b0c79ac4aa42c7ffbc963fb4970fe26c5b5dd314b7051fe971c1186ebcb5650f7f7011a924de893f06961b8c75da7bff331847feead4abd2e8b9d6ecbedac18f4eac207b948e6e4215e4d5cb483e5c66ce7ad788cb89604d3a3e051539094079e7bdb 014cf93ca69d94ee8fbea0c8da9d76aea092b73073d8f5385b65c6dd4d567fe86bc2cfb8e8be890c3c6cd9abf7dc3a17eaecee3d7a9455887863e496c48dc3e47821bd3d825b6bed 9982b8b51a545f7026f053faeddce5a059031624ad8fe964c32147d850a7b2045524a6558041658164bcdcb2730afec4 +53ef87d6ac7b9698f40b3ea9f3442e7b64207b140b7f66f73fb7d5f8f98452d30a4e493b6c0e3268371e88e612b818d4d847f032ed4983817d020411a52d81fd2a17b58ebdec199d817c2a8ba77042bbd747a6fd4bcc7e844ea829fd8461b389aa0b5957d92962b6d4e86385a8fbca90b8fac40944607117e9a4ef6dccb8fc1e 0033feeaaaa28f16bfaf5ea9c7319cf4561ba4fc55327a8477b6cd58ef6ccad3962ee1f3edb243f3a04e7e49c8e23509fa2d63252adb186b8bc7e9255cd61fa9bc45242d42da3a68 98756a5cdcfb998bf05f4c96fc4d6d382b1e665d5c53d4414cbece92863ecc846e4978bf5981d6942271603afce369f8 +dca1b7a9a313ead11c2d54739d9017ae27f9d08b3544e418aee862bb57e427636cb6aedda28e10f12aa15d2355f4f8ef112a86fec5dc46e6acef693cb8fc37c3e4885f3be3d3ab31ea4d73a0de904e95c7135a149f77b621d642f9bd8ba192d39cfc58b6f19a797c4f3b4f3a87054298e3ce5eda0ff7f44f8134c9a108285dfa 005613dfb53149bf5fdc4e08ccc1c752b0b66ab43aef2d008ed40f3df40fcbb2938d2c41e3ea2dd4428aeba9059a97efe5593119673866a19d27a2ee37dd357e22b6bc849e7e22cc b57162e71617f178265c962a3774b6dfd8157f9573178ac324cd4363cc13f68fe46fabd6f7c4a034b36ce028f574225b +aff61d62c8f5c31bbb7d0a64a6ac589e918bbf2f13e7ad13abb9ac26405e267249a7c9922139bc28140833e10976b87e91cf28285274b2b48b63d24ac94c85c70fafa78f8ad05955c0ce6c02b841ee196dab12306e3e3d6138371217e2b474f7e67a80bbb78a47e374ffe2c9f86292e471c551da50d46e7b5c8331029f369767 011b92c8b72b86c51903387a65aa206988d443d1988253329ad3a89c902ff1ef8cf73b7f2e4aaa352443bcb833712d94c3e637ec12cbe4c2d4606878576b17fae1512fc77785b737 822b37e4f410b2d06bad3494e96a17e030c65f5be020ffb63cf6e0dab3092faffdfc97944afe5890e1bfdedd1d38985f +721017294f17ef351e41256b57a64a79f3636628c4bcbe676ac9a2d96076b913dc4b246c9945183ec9bd2d251441b5101eac44e2fa1bef59dec03ccd7fa5accf3b7d094d68dcf78c8de4e2f19f56bf0dcb3b66b9421ec3f8b353b9fd74feb2e9affe0bf9aa421b6f03eeba3ffd58fba56b3ebd094880e50de01ee62a108a24cf 00c3c90d5ce4375a08b85575faa78ee6bbd9e5571ce5a90582042617b807339c282cdc3b003d82006264b1c08c20af4ad4549fbde53d262facb98d923d81b8eb6093374b6a1e84cb b23f4b5e10fd3c4fc3c74d5dc9292bd90f4901727b5590091d839d6373f6e81fed9e1c97c83f72ed7417eb22d8cdd19e +e2d1f33681759adb7954bb5248b0db3c3885fea0d4c1c0c226eb1e6d2d3ef1b9ac281a0f1c2fe5175b67114b6a501e2426d1454bd5790dcbc4c232cf06b017de8a9bb39e6033f1edb5003e8de3b44cc3d6150c3c952afb442952483cc688908337b7c1a8b5c9da70937ccfa98b2b0098c530ff848010b8e8ee0a8d65283481a8 010f184c16228d9034271332178ed485d10b6aa76003efc160d63fea26fbbdf5552205ac7df0d8c852a1210cf0ba512f20b798827b36ad56b12a826fa7dc1db45aed264ca6822659 b087bd9647543d9b81665aca613c5728e64e1e415808c6302153d938345782505c4189b80e684fa8d6b5dd49767ebed0 +414fc5d2bd56b30040e105cb891788792da595583b11b8fcc7320f40dbf64d9263532dc57344dd17573c95eedf851668b5d552e8796af205f3a0043af1a829fabc2e93d9af9091fdd9e0fcbcc9d6d9ec960aa60e4e2964c29a2f375400366480e513f63d124db7745847310e69a38c8455e4e602056a6a4a14a8694155e0a9bf 0181baf9d497159f837cba58a11ca435c442e5ca792ea559bff9f6a1f562c05bf6bb5914afbd1bcaea75b35f88bdd832314b249a5298622c89462344d3f28a44ba3d059df432fc71 a6416254adb8ef6dcbcb9e6c54458fb1c967ca2ec3567ebac053cca1c7dca93ffa37b98037f1f6d2cc5ffc164f583bd1 +3b592cc8972a4782870e079b82a50f84b4c2d8ca90bd500d1ce5678982e266c391c556d8162ac3aab967154d072dbc0ba1dab5545cf2651753dee2881eca5abd412fe624bf3f9d17d33692d21ce23ad15ccffdfd250cb1949e73c9e40a64ebebb03852e92692dad1d7baef97fe109f35b7a492b343d4b643a4a7b1723eaecb64 0083fae86ab96bce99a53e50b7eecff38e4e25b21c4b0f6a4986915de245eae24f16b6a00a4db159ebc27f5a6a072da94ab6be5bf75f5eb3f75c4452bf4ea7014392eb1e02706fb4 96f8df143291d0223e55155c6ba5310fc326b4b5a1e843dd84537ed4ddd80391e2b936f47a8d022c8f8cdbe7290bfe0d +0079a02cbab3dc02601fcb5c8607d555beef7cd71a66911ab6514a4ae21c5a9c0e166f8cf5fb198ec5a49a96e17cf041f35f00406b79270ebfe56dc6b8417d2529fd625686ffbc8f69685aefa2fd30a937c02f25b48be4679e6fde821de928b33b12470867def874bb8c7c8038ab6594346a2c44b39210d3610994ba60a05e06 01a663efa7bf4d8479bc535fad71e9b5e4f4281aec55967baa008ba17ac2f89cc3398d30573edef29d590fddce8cb157f655e92779f59e7a18d0327d02e7daf4c1216143b3688fed a64a6c39e6ee70b2888d4ed3c1814581b838fae1013081b13a8c32b9dbf0b403658b0a2240f6c3a377a2de6e1d8a0923 +88573bd94ef50459814806efa868ebf92b066fbc2f7a4be9d2fa06b9dc1a72f72d783a6bcbc107b18a6314511bff217037a2252e7a5cd34cf9d5b2fe9c7846931f0133b2e95876cb800dc4ed7c4a4e4cc4f1195acf99fb0ec224b1f8fa8af71f72d390eca9d6be3879032a318734a63fec336c79035a43f70271def10c4955d3 00088d1a2c0219696a94337cd56516252b74139ea0733b17fdcbf7692c3e5f6c3989e5da2aaed7468e65a5d578571928ca273ec3b6aa72cd196f560f05095cdc8346e5d31c4c2e0c 8b58144db1f09d5c6ffa58abe3e75b001e38e3d894cd969f4bc7538277ca3ce87c16c6457ea4a3eac07c4e61211eb85b +d0e02045ece6e338cc8ab41d4a064c982ccb1748c48fc2fe0a6f10bdc876094358a6a90a45facec798a83cc95c6795cf0f0d7c66b77e22cb114c1432bfdaa1485ff35b6a58107cac3b7e58cb4f6c87c68db60b751e78f1fdfa54b8923b98caad0a4f31226956d065c083ace5f1e9e91944dcca51879d782e40358d58ca758750 016cc8a0fd59455ed8d4de561fd518df2e008f7dfaa5f7f29ac2489a411e233917b43eb3ebe2596fc824be58871949545e667dbcf240dfb5e0c615ade0179d9ea2a1b1ebb8ab9384 a134069846151614b819b8d7aedaead7e1727466873f7a7cdfbef1af01d5beaaf5974ff251f6a1d8e4513cbe9f5e17d7 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P224 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P224 new file mode 100644 index 000000000000..63da90cb406f --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P224 @@ -0,0 +1,60 @@ +699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615 8c35d211d6be65c6033d87e78e3e85600722649fd0f3d6241511d0a07d5a5bb43b5cca2993ced34904c08b73c9ba57db +7de42b44db0aa8bfdcdac9add227e8f0cc7ad1d94693beb5e1d325e5f3f85b3bd033fc25e9469a89733a65d1fa641f7e67d668e7c71d736233c4cba20eb83c368c506affe77946b5e2ec693798aecd7ff943cd8fab90affddf5ad5b8d1af332e6c5fe4a2df16837700b2781e08821d4fbdd8373517f5b19f9e63b89cfeeeef6f cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5 8cc1eb920e1dd33cd0f0f01dc022a3d8c13c35544711595c92da8bca2b181ecf4772942bc777be8b6eef79c56539fb36 +af0da3adab82784909e2b3dadcecba21eced3c60d7572023dea171044d9a10e8ba67d31b04904541b87fff32a10ccc6580869055fec6216a00320a28899859a6b61faba58a0bc10c2ba07ea16f214c3ddcc9fc5622ad1253b63fe7e95227ae3c9caa9962cffc8b1c4e8260036469d25ab0c8e3643a820b8b3a4d8d43e4b728f9 dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73 b15219895e2ea6b081a6f5e1d242067b65ebdb7aa68b5309d3888fb3bae343ba316dcc97f25539f3ce9ec3ddaedb59c9 +cfa56ae89727df6b7266f69d6636bf738f9e4f15f49c42a0123edac4b3743f32ea52389f919ceb90575c4184897773b2f2fc5b3fcb354880f15c93383215d3c2551fcc1b4180a1ac0f69c969bbc306acd115ce3976eff518540f43ad4076dbb5fbad9ce9b3234f1148b8f5e059192ff480fc4bcbd00d25f4d9f5ed4ba5693b6c aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e b6e8199bea33673f60903c541bbd19f67f3265e76e5187da229e5abf82ad222cf742f01b995e2a4df3a6c463186b10c2 +c223c8009018321b987a615c3414d2bb15954933569ca989de32d6bf11107bc47a330ab6d88d9b50d106cf5777d1b736b14bc48deda1bc573a9a7dd42cd061860645306dce7a5ba8c60f135a6a21999421ce8c4670fe7287a7e9ea3aa1e0fa82721f33e6e823957fe86e2283c89ef92b13cd0333c4bb70865ae1919bf538ea34 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4 8d9bdce8566aca85c2e17bcad45e52de6e99b0fa0fb64996014be10878ca2164214122dca0bb1821c0e5ba8a43698440 +1c27273d95182c74c100d85b5c08f4b26874c2abc87f127f304aedbf52ef6540eba16dd664ae1e9e30ea1e66ff9cc9ab5a80b5bcbd19dde88a29ff10b50a6abd73388e8071306c68d0c9f6caa26b7e68de29312be959b9f4a5481f5a2ad2070a396ed3de21096541cf58c4a13308e08867565bf2df9d649357a83cdcf18d2cd9 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131 b4c157e682438e96f8381b50e34b20a0549023e59c27a93f4b500795a8ee1fac2cf1be1a7db6672738ebc025e8db7f9c +069ae374971627f6b8503f3aa63ab52bcf4f3fcae65b98cdbbf917a5b08a10dc760056714db279806a8d43485320e6fee0f1e0562e077ee270ace8d3c478d79bcdff9cf8b92fdea68421d4a276f8e62ae379387ae06b60af9eb3c40bd7a768aeffccdc8a08bc78ca2eca18061058043a0e441209c5c594842838a4d9d778a053 d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974 ace3769c8ecfc9c79e12b516823b6e2bb9cbd31ce46460b7b4f3801091dc8f51ecbaf236c41adb6e42d2a32f9271e46d +d0d5ae3e33600aa21c1606caec449eee678c87cb593594be1fbb048cc7cfd076e5cc7132ebe290c4c014e7a517a0d5972759acfa1438d9d2e5d236d19ac92136f6252b7e5bea7588dcba6522b6b18128f003ecab5cb4908832fb5a375cf820f8f0e9ee870653a73dc2282f2d45622a2f0e85cba05c567baf1b9862b79a4b244e 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8 8d528733be07aba1bd517857625e0ae6c7cdc5cd240c775b061b6d7f10ca7ba9c9462ad02c7765714f73b172da6c8e60 +79b7375ae7a4f2e4adad8765d14c1540cd9979db38076c157c1837c760ca6febbb18fd42152335929b735e1a08041bd38d315cd4c6b7dd2729de8752f531f07fe4ddc4f1899debc0311eef0019170b58e08895b439ddf09fbf0aeb1e2fd35c2ef7ae402308c3637733802601dd218fb14c22f57870835b10818369d57d318405 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2 b086681bb2c6ca94c37d975b613285c8657c6cfa3f982ae3857c06921117298697c947d0dd8b63117645b78d1b6f8608 +8c7de96e6880d5b6efc19646b9d3d56490775cb3faab342e64db2e388c4bd9e94c4e69a63ccdb7e007a19711e69c06f106b71c983a6d97c4589045666c6ab5ea7b5b6d096ddf6fd35b819f1506a3c37ddd40929504f9f079c8d83820fc8493f97b2298aebe48fdb4ff472b29018fc2b1163a22bfbb1de413e8645e871291a9f6 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7 91167bc0a4e7a973e6f8277f579c9a60ae72b71d749710d5f62bdf0c43bd4834f976449b5b4ccfbd638d8a5ef8574d8b +c89766374c5a5ccef5823e7a9b54af835ac56afbbb517bd77bfecf3fea876bd0cc9ea486e3d685cfe3fb05f25d9c67992cd7863c80a55c7a263249eb3996c4698ad7381131bf3700b7b24d7ca281a100cf2b750e7f0f933e662a08d9f9e47d779fb03754bd20931262ff381a2fe7d1dc94f4a0520de73fa72020494d3133ecf7 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b b8be20b0787dade1c72593790b134010df9993c9b22759f380c78d373d41210237100b56f75734f4ab5b625a48cdaf94 +30f0e3b502eec5646929d48fd46aa73991d82079c7bd50a38b38ec0bd84167c8cf5ba39bec26999e70208af9b445046cd9d20c82b7629ca1e51bdd00daddbc35f9eb036a15ac57898642d9db09479a38cc80a2e41e380c8a766b2d623de2de798e1eabc02234b89b85d60154460c3bf12764f3fbf17fcccc82df516a2fbe4ecf c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6 b3db045cc31c0a3011b9fa650265cbfd60ec4991ed79a5130e6acdecde6e2da0f86c392b4411cd32ae683508c504b8fe +6bbb4bf987c8e5069e47c1a541b48b8a3e6d14bfd9ac6dfaa7503b64ab5e1a55f63e91cf5c3e703ac27ad88756dd7fb2d73b909fc15302d0592b974d47e72e60ed339a40b34d39a49b69ea4a5d26ce86f3ca00a70f1cd416a6a5722e8f39d1f0e966981803d6f46dac34e4c7640204cd0d9f1e53fc3acf30096cd00fa80b3ae9 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc 9a00f8ec260030e4945edc5ffbdf613e56dbe457f0acc3de39b01c2fc436b6b1f5f7c4cbcc967aca245857399020eddd +05b8f8e56214d4217323f2066f974f638f0b83689fc4ed1201848230efdc1fbca8f70359cecc921050141d3b02c2f17aa306fc2ce5fc06e7d0f4be162fcd985a0b687b4ba09b681cb52ffe890bf5bb4a104cb2e770c04df433013605eb8c72a09902f4246d6c22b8c191ef1b0bece10d5ce2744fc7345307dd1b41b6eff0ca89 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3 93842d9535aa268b550e8f697c53ddb5761da5907c2c0c3ac1d6c902f572d1f4838d92ef97858c2e763b73b3a90d8b94 +e5c979f0832242b143077bce6ef146a53bb4c53abfc033473c59f3c4095a68b7a504b609f2ab163b5f88f374f0f3bff8762278b1f1c37323b9ed448e3de33e6443796a9ecaa466aa75175375418186c352018a57ce874e44ae72401d5c0f401b5a51804724c10653fded9066e8994d36a137fdeb9364601daeef09fd174dde4a 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912 91eef2327d4d0df276aedcd35764b47cd2c6e615653b68dd50a0799b049519f68c47ca58bef81c5bbf874268874a41fd +2b49de971bb0f705a3fb5914eb7638d72884a6c3550667dbfdf301adf26bde02f387fd426a31be6c9ff8bfe8690c8113c88576427f1466508458349fc86036afcfb66448b947707e791e71f558b2bf4e7e7507773aaf4e9af51eda95cbce0a0f752b216f8a54a045d47801ff410ee411a1b66a516f278327df2462fb5619470e 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa 8f4db2ed03c428e0499c5235c9ee48036da22b50ee3cd4d044bdca57d08c12c7dc3094e83b15c8d73fb2d89743278ed4 +1fa7201d96ad4d190415f2656d1387fa886afc38e5cd18b8c60da367acf32c627d2c9ea19ef3f030e559fc2a21695cdbb65ddf6ba36a70af0d3fa292a32de31da6acc6108ab2be8bd37843338f0c37c2d62648d3d49013edeb9e179dadf78bf885f95e712fcdfcc8a172e47c09ab159f3a00ed7b930f628c3c48257e92fc7407 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972 90759b5c37f27b385789d663d104ab61ea4f44a35c38ae88568b2b31043257280259ddb46025c7e7f490ec69267210c4 +74715fe10748a5b98b138f390f7ca9629c584c5d6ad268fc455c8de2e800b73fa1ea9aaee85de58baa2ce9ce68d822fc31842c6b153baef3a12bf6b4541f74af65430ae931a64c8b4950ad1c76b31aea8c229b3623390e233c112586aa5907bbe419841f54f0a7d6d19c003b91dc84bbb59b14ec477a1e9d194c137e21c75bbb f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170 a20db20bea6ada631b8a5993e11b45ccf0f09d158d10d833e2de7b870892a1a086fb0479e7d8ce2eb24d335e7e68326f +d10131982dd1a1d839aba383cd72855bf41061c0cb04dfa1acad3181f240341d744ca6002b52f25fb3c63f16d050c4a4ef2c0ebf5f16ce987558f4b9d4a5ad3c6b81b617de00e04ba32282d8bf223bfedbb325b741dfdc8f56fa85c65d42f05f6a1330d8cc6664ad32050dd7b9e3993f4d6c91e5e12cbd9e82196e009ad22560 c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85 8dc6db776ec46d7d73468fa00f04252f802b1f9df3ed7ad874c22e099b7652219f21900e816ff86f20ddb6949043f33f +ef9dbd90ded96ad627a0a987ab90537a3e7acc1fdfa991088e9d999fd726e3ce1e1bd89a7df08d8c2bf51085254c89dc67bc21e8a1a93f33a38c18c0ce3880e958ac3e3dbe8aec49f981821c4ac6812dd29fab3a9ebe7fbd799fb50f12021b48d1d9abca8842547b3b99befa612cc8b4ca5f9412e0352e72ab1344a0ac2913db 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6 8f68ee37242a45bb173b9a9f609a968dfa576a2b9ec7051e042cae175522a3bb3eeb0c819efc8fe88aef0d43581ba185 +4cc91f744ac858d3577e48813219aa3538dd813b186b42d1e6218376f07cc1cc448ddd6b37240e98bf953f49cf54d65c12878b33c0bf6eb1c60254f0b6fa974f847e53abc56773eef6f29885dfc619e6a48fc15a667ca94001a0c945b6357a53221b0f4b266181456b0d2d25e90708777f1a6f85971c00140c631c1991e0fd06 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39 a6364e17dfb3558ff62daf617e1d82322a991aca2fd0645be55d234c5ff9e401ebd4b216bae2117e2a07717d8f8c50d0 +58f43cc1924de4bc5867664adbc9d26b4f096a43aca47c27c52851b006dc2a658919ef9ce5b5ac48372703be15ac51631c2bd84b88f479f113b0569a9a09e230ec1e8e573474c6075284d3e57d973829af35325d9e7dab4a5f9b065155bbcaff3642a82ef4c9b9e127d3575c050721653da3b087d3fa394192897a5519527d19 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6 a4f2eab127c0bf40136b4e17cd9811224823b664eeef829a982cf5a2c6d03b7c57229082396b56b15f410153bb0e62e1 +113a2806b052fde683ee09453098e402204155afb3776fd1cad3a9103421d327eab8f9ec0dd050ffcc83f93b34ea707705fabeccfe43ab1a71c95298fd3ec769d99ead1066950eee677d225816e0faad19cf69e1b35d16771689e2092cafe16d7c0dd7b0db73fffb8d0f3eaed83004dd21e753530ec939c89ba25578fa5f785b 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b b30db7e1ac38df53beb1aa2fb8f3354442ee0fe71bdecfb9abc7fd2c1e4ba4d44bd87554edbece95f80fe7d2bc701c77 +64cbfc8f2e2149a31b3e8a80c4a552f6c62aaeb7990b6e0ee55500a9d17be04213406578caf315951086dff5c2af3b5ce17d425d185101ef26f86396ba3a129a4f3f8e2dd595f59efb6c0f5c2dcc394569d7268695e9ac7daa84203f1f1895f1f9e4b514a5c9cd23baa63454710144fe735ad9b8f42d8c43267aa434a26d7e5f 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b 8c0ae14b112e2c09767e9225f7781aa3e1bd3b8d8f14fba26a7d11ce8eb96eb88b1e83453f044a021a247e431ef33d76 +a10a11c8e30fff118d371daf824f16c08200b83ea059436466a4611ccac93b2dea2de8c1006f946196aef7fe9b0c251a391b0340f21797798278b412ff2b53842eec6450728e2bca062f8337a2c204b9ea04ff660cd4d4db559f2f11c4d8ef199021339fcc82396f7a93926cf5f247e37d8067fe50692de54f102bd5ab51925c 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8 963c86dabbd1c9688e2d075a62644f84d3591de72734a645128c37b8488ab1ffa3ba3fb7616d7883ad27150b8a20595d +b3f720bf566ffa369259f4361959ae0641d2755ec264a4c4349981df2b02563275b2b9adb5aee47f7a456760a971991ffed6b17809bb9694138d1677fa916123795239353158fc6b22d10f20d26f5d2dcd8c56c44373eea5b93067dba2d7c5318dac2e9e8714873cb1b37f58c011fd14fa1e535554efe05f468bfc8e11cd8b99 e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784 8cbde575886fe1095d62709cd08fa31c8a619fa7d6f9d42c63b3833f508c5ef0d66f19d087af1259525fb2e0c80bf06b +0a398a46df7ccc48d1e7833f8bbc67100f1ef77a62dc78bbc115b2a662f9591fbaaa91ad3d788e2fdd1b3164e45293d4f5686c151296901768028ac80ded4bf89c647ad35f0c7c4cb318c0c757c1d83c44d850e5fd4677281b3f13b1ee54de79c8c042813f9d3312dcc6111a68299cb7e829557d7f3d96e702f65aefc6499415 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c a2b2bbafaab384644d83d543fbc1ce79e6b2884bf5fa756dabd6727eeb3cf56e0f21ac8e0d97503882d7aa321acf93e1 +8c33616821a6038b448d8918668977fcf1ef5aa0cf7c341837b39bbcc9bca875a3757f4b392630e9995b9bbe4eb66978b877586adaa02f99d2344dae082a7603351d8ffcfca081ab403cd0acb90d078dd1d0789c2eb3185c62bff2d9f04cd38e509e3b83c12ed0a5c6808fc42f7ba5b06acdc496c8ad9be648ee6a4505f8560f 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583 a5d7f6554ec007fabf069f209438ffee7e0dc09d7addcf7c3fdcdc03a0faa082d84da9657be48279c2719cb285244043 +94d56535fd4edfe67a0daa6579f9d53bf6b7b8830ae2aeb62892ff59f18756ddf2811b449c7d20d65d54f8507de4e7c50eaa084830637812aa4b250a4d61ab67845be36e4a41cdc0a70f8d6e3a63d4514f0dc197e6486015046a316153d5f3a3a4a0ae1ed7ea5fa55e12e73d333333685c02e0eb636234ea7e6d4b76b4b76b5a 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2 8854bcdc34da4e2be7ca0f5cb9b604757e2c447db1c7302b3e6cb097886a74320a89064f086dc0c6f996b6c747a83846 +5d8ebdf9eb28b47bdafaa36bf0b66a9eaf99b6c83959da4f2b1151b4f4ecd28fb115a64c0cb9491093a7e9b9c53ec423e4c72e7765bb9c818da0e8c428667e44474a71db4867130c77c40bfd8544b2d7b9d6464d2b8e6a48482153256a32437c3a747231f51134dd14c703407e31146a6fcde23bededcf16950486e90ca69ac0 f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc a05ad8028d7bbc779fffea72c1e459ad29b2ea2e989f3b2dbc39b3498e462761c9df5fae32ca7aedf7744b2f5f083baa +25e4416695f77551fdce276355528ccf1ddc2483821c5d22d751d50111ca2fadc6593b52c74f4b5957494f1df25b0b2f86950d0d19229ec6506fee8581d2dd09d48418b146ff16bd84a17ca0dc83b1888eb407376da6c8a88fa1e60b8c2a2471dfde4b3996ef673d5bde3d70c434dc9f2488e9de16ae657d29e5e59ec922a1ec 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd b36fc4c34fbbd15f7e639d0395662276519fb992588e10979e090474e6390fac934b694d30ca1ca88c8f22ee95a69fa2 +9164d633a553deccf3cbd2effccf1387fa3177cd28c95d94a7d1a3e159c5e5c027758cc26493301b2f4d141d8d07a5fe5fead987ce5f30abeafcb48c302afc6c2309f0e93d9b6818cbb6972d222cb7b01302dfe202ae83b89f53150ae4a0e2b8fc0fd1091f19b4ab2e6ab213ab322d04f2c5f57113bfad3c5675227237abf773 e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3 921e67e869bf8088c6c570e05413d25eb3ea8835afbb8ca9e5c7b384db6f1af881809ff7032e902eb47a42cc6187712e +019df05929321ecea7ee1de4f412aba1c8d3c24437db04b194a68a0a59dd871be10bd3a4be6edf551350ea49fc7155a4d887e1221486291abe77a30633a4c4f7868fe2df24311cba0c73804883954460e122387ed414111ff96ff1aebac8b6a6491d8a0d16e48a63bf3d027c0f68ee4a4b234d73b412196706af8ea022b4dcef b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17 ac87821a476706f666285206367f1596d9d08e70c77c6286d1913ec15b69e8080e3eee3113e2974a9e6a55178fb2a3d2 +5d09d2b1d3fa6e12c10d8b26dc9aabc8dc02bd06e63ff33f8bb91ede4b8694592a69e4ed4cdf6820069e2b9c7803658949e877ffe23bf90bcf5ce1409c06c71d86885a94048b05ac0ec9db193e489a5a2bfa367caf6aa8ecdb032be366174343f6875d2fe1785e8d77334f5f469cec64998e08d3303e5c9a1923b34fdc105d65 efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085 a8362b5e1c8f42a003b7475c5a82cc79c8407dbdc00682c9f99205911cc92b62c8766c55d7413c5cd7c4374daac9640e +50f6dfc81c6cf189e0a310f992907fe93356cee9dea9a41c7671a8daf3f4cfe0c459ce6122c1e731dbf7593419d7114cb73b46956158a982c5d52c72f43f0f822046093c69aeff1f7e4cd8af00ba655c5baa2e7b6a400b4be1f6fd51b3e4cfb35a69c80a28c5cafb771b6c2e52e0aeef0e3fd045e8d40745f3f8b74fd969f816 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd a9f2c051f61d5c2e6dff8bd0ea7cf64d38d48461544875ef1848557e9621d05da90744e99575f205b1d7b80c9d1f01da +e90129ac6672c85bb7b6b18e9dc199c96c81fd65034b53c77818364d512366fb9cd1bc7c82404c451e561fc1ed916c0948f6ac561b33a1ccca093f07684b8c2bafa9e966377bd208556018a5bafb9edcecf70498c7140fe9c8cf3ad8b8c3b0aa489df797944465047465415bb0e24333235fcdd59a98829a3941eaaf62033e82 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d 88f20afb45a1f10eab9488edbc201854463e8de22356473255fe9cb6f4119064a78284dad362c4d46a9e4290f4daa4ad +3c9a483c9bee33b601549c592a82e95b4319b1e74b777877f0971bcb4273716b268e8f99f876e42f942f4cf08284896bbc1ffbf094ac0956c3cedfc3580cffa8c74fc6db29a371f2da2d05edb9185ece741fe0d3fabfe9d5b4d373755ebed13dc6840cfa3283b9ea46ec8b95c434f253ae86998182e9cc0e95ee64f323fc74b0 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0 ae1fd8c305f79d6b1bfed746180f40773367a67295267ffd8581389d1bbb6e7e2b6cfd187ef0e3b19577a0edd2de1ec8 +bfc073fdda63c5fccaa0ca8770c293e8154e7aec56128bbac4fdbd541d602216ebf7ca1e02b514d6e396f20683802ba3f334310a9226576926e3bb19ceee27738d13377cbafeb09d091043501702a07aa31d1f29d50ddc55adcf16ffd40578e734a4e6cb6535f26ad48e0c62ad90e79720000e87d419e92dca3e11f943655b03 e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d b155351e8eb66381426f31f61fb2233a4256f92aa780ac5ceb07ea1c1b1ccbb772aad38070400e8ace19d551dedc0513 +08079955d1a1f33728128c73673ec9f21a6ce138dcab5adc4dc068e6ab57314b9fbd8b013123b2fdafa9524fbdd0288777a233de8055cccfad83046ada6a19f01c47817496667bba8fc8b9456fc0e044a562d931dab1adcb66af8b66325bdf28d83ded3e2937958ccd19da540d70ef2c189f55a506c9c0d63406394c5bd3823b f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7 91a289b8bade7907fdc50e5aacf942326e1e864e41508a8e4ecc9cd358276ac1e7ef0aa80980865f319fd10d32015633 +23900b768f6cd42b8a8df0dcbc9cb5daec8de36b9d5c619adcc1ba2b649103d5af123746cdf19c3fd0665a6fb9338156182aa06181e3c6e37ce56979612af2927440424f89cef43fc754854b8a5c43370808cf5f9929cf47712512ce2f8a2a20d2e9f568c2848b27dfbe09142843c83905ffa5da3b15501761b03dbc2c5398b6 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c a124fd751dd22a42259777d5bac4ac3bcd323c0b3caf606948fb972ea868c1660fcd708c3163fc11db8bdf8e6a6f55e6 +1eb28c0bcdd18f73e347f957ece15b4cc83a771b0877e1feaac38e24028fb38ccea8b54ee017dc7c3d5a1327bc6f40b294aa65d7dc487f278846cd101ee84202f14b38aa2c275046aa2577f65ebaea41cd383e8def2fd0b4444dcf426fa75c4082cd7fa035cdb1e0d34a3c79d42130f5b0273eae75bc701dda3aebe7358f41b5 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18 8aec1cf2fa650d765dc3130e24204409fcdc54fd23e98ca254bac1787de2ed1ce4dc4d82024206f349b95b7a29f00fe8 +efab51855407438fd5c250670366bca3c026ecec4a59394f00d8a4b51746d0c4564366656d507e3e13e62fe7abeb976b8859895848dbaecf6582f1898ea06f00d4247702ed9721bd375aa83ae4c67c2eaa6e080777ea5ecf2cf787d785389560ac91cf63a52f0373c3185e18a3b8a466e21b61a239f1b77624eb1acacc76c4e1 bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a 89e3a31e17bed27a57e296d10a1178f3544bdebe93e2b2584ed48327701461104da8522a73f5d92a261f3090b0e4b402 +31c29ca10279a417f0cc9b1382cf54dbfdfc89f2e6ef08c403c11f580cbf8674b141ed1a417563282d99a55fc616d836421cde9424815c95e7fb7668bf3f137b29937f14882d74e034b732d78d91af7721aac4950734f5fa5d4b4d35534974f8cab6d2e6dca75ddb57e99148c8a59df9fc5bcd723e546e8356f671cf2f65640a dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738 89b8e20e9ca01d523833ee5bd0e4d80045892be9145b7d5ce2aec662838d6ceb6b4a73fcb549cd98db1052525faca2dc +8db476f92e332519c1a0ece5d8deded6efbd2d8e8784eea0a6b4c3b4296c35f5f8de4317e5c1627b91fb1973fee86c06e4992aa5a20cb7475c8808ff1da354d07a488dffa7838c6ec1e3f99e3acba831f27bee8434eeda3eb36d0c6df3658883cd40068b1bed841310f6eb38d4a3d07d85848770ff7933c054cd8b34662660b1 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01 aca88b4206bbaccd8cacd1d79b4acbe7a5df4176e598577f3e22b8cdd5d3464c4d76fc4519e96df165ab66de6af6f2f8 +fcb272c828fe8fd3c6f8de9410c7b6e2b36717c1b0e5e359e9109bd7fc378978aa98182a9d99961898ed88999b050d3b64d1457d7a899d6d273b9f4dde2aafa36d76329d62509043c338f265fc4c7d938459b7fa3b230a9f6cb632b61489546bb4181a5ad7f0d7369b8caced48eb374b075b2b325bc86add0f3b680cd9e80acd 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28 a34bdf52664a5cb56f8a0985e5a53dab4dc834dfa678ce0930f5eb5af93d2fa2911f46bb2fe7360af4b43e4cba74214d +7522492bdb916a597b8121f3e5c273b1d2800ef8c1db4f7dcbae633b60d7da5193ba53a63d7a377b351897c3b24903ae1cd1994211b259be3e6ae2cbc8970e4957fdf782c7d1bc7a91c80c8ef65468d4ef35428f26e2940ae8b0bd9b8074236bf6c00d0ebe83f9ddb2ade0f835138d39f33b59f244e0037c171f1ba7045a96f5 ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6 869c0e3eec5082a9af07cc87c72681ceca4748a9a6094e7625bc94b227214023a4c06832cff8ed8ae977e7b8e9f44f89 +61097114ff855c3e34a62d9b853f8982d35f29cfa4a89893badbca7849e5fb437a1a38d6451bf0ca5a0d528e352b8e4b57f2ea359a7fc8841d49dd3e570f9b016f14156b0bbc4be822e260bd147ec081454969e11cb0034b7450ef4deb7ed6edb977e2f4ed60121aa095fb0ab40240dc329ecc917f5c64b4410612af065ee9dd 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc 92fbfac9d45c5147282f21e9d48344fc94f3335bb9a474d42c27d14fa855b137670303109f9a967c54b1a3d151833b64 +dd09ae6c982bb1440ca175a87766fefeacc49393ff797c446200662744f37a6e30c5d33ba70cbd8f12277fd6cc0704c17478bbab2a3047469e9618e3c340a9c8caaff5ce7c8a4d90ecae6a9b84b813419dec14460298e7521c9b7fdb7a2089328005bd51d57f92a1bcbeecd34aa40482b549e006bbf6c4ce66d34a22dda4e0e0 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b b0e3e25f55cc66103750b074bd227b3aedc88b3d12d6621a01ef7f470c06a8fe1fed4af4c62d9f96033c8d7d85948cec +37a73e2774d3b274db426c89b945696daa96035031f72cea01894b24508c7f81961ec254d36ed6a0f448e11cf7950af769dc6cd2c47e52c6caf0ea92c270974f0214b4db436c36a60fb722060a6bb544462a82e1714f5906ec32886f7d59ebf289541c3a00ec1e004892ef2b1286a0194f55d083c6ec92c64b8fd1452e1c68ba afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc 97c8272804022e111b004a78198ad8ebdc9f31a15d29e88fdebcb7684161dabe55df9fb19328fb403015fe553ec28b8a +9dc2046ffdc6804544db964481abe5d2d276a2a9eeec4c7ad40215b1de23561d402db69bd0f6eec2254711eea4487c64d9a6b62c3ebaf5ffa8db6e7e3a6e17154d126967a47a853a6f8339bdca9be306a13c7f992ded7619b0da59909a49b1e0930360e05b47f18628a36d69b2f87f2bfddd6a5d4a72f84dc76dbdd43f3a6a35 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c 8262bd756a63c9e10f293bdc65a818b421970da9a40472ba87cad9a2df9b8b478dfb3ba486cc54a19a3325b7d09ac545 +d9c6847fce688c5e7525a1098b545cb6c15dcd21a02761fc82fc664372a667390680135f91c01a2fa5430c634b1a6d1cd6002d8aa021e7bf5956a7901c2f81bc25d502ba5f55a55f30c0323dc68205cbefec0538e68654e7b327ac1743641896c3e740d8f66f400902b304eafaa4e0d8cffae140536f0922444cc3216a675697 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc b5ec2c90e0caf88d9fb50298b7dd895e5e06886df1c34e001bebdcf64121163b4417894ada4fd7807f7638e625994805 +69df8a01b66f04930efd2012ff2243874f256ca8758145d2a9e4ecc84d0dbdbd0dc494ae06db0ccbe819918137c90957114558580d6623efbafdd342b38dad9f08708084d32f874fba04782ce26aaab78de2102ad171f8a8f2b30b5bd3d55fdac5fa3acd6f7def7e61c2533938572b331ba6d1c02bd74bfdbf7337ade8f4a190 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4 a661da4539b9838910ca2e7dbc039e0f78559e40c6c1b22a791309d8593dc2a0619c7bf185054b670ffd5919866918b8 +927524982b8d60777c1105c86fac05f634abf58c73f84fb95d81ba0b86e1e43592c4fcad2e395a40fbe7005697d86088e2fb3bb7287eb3f917d4f2dc281f5cbe65d05b4f9623bca849b10a03beca6aa2056a12ebb91cf257ac448c5e9a78f8349a6a29b17c8978bef43a443cbb8a149eb23f794844fc41693f2dbb97181444be a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916 a8c0cd6f7a272ed6d7b81e9ae8e32749bfa5c62b9211254b2c81004157c8e3b08f5ad5f08fd9ced7799bdebb1f2e08ce +5f9042283561e7f19a436d01c7ef5a950a6d77ede5629cd7e43c0a5d58e8c5673c37945a453291d12938253c71dbe12c8b022ba7276eda6be034ef5ec1ec77dbd1e08f0d7b8e7725b7ec671c075e008a20f77f4ab266f97079b0aa6337df59a33b881954084057b21f294dd14bcb0869a4a6f1f597955ec7bf9d19bb3537a66a fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b a0e52700f891a51a744150f490a6b5508213c8829f56bb2919198718b8202a7169ca5568a679be9e4393acb834e4da89 +c2ae5573d3bf396523bfb703db8502fd0760cd1be528f6ddbfb95aad399e0b19f3bd9e0fabdb05d49e3f893dffec5b627c9c2f7ad5f32e92e4e27a38cb5c28657657377fdfa1b66cd7ac3d15c6d49df92d284db99f69744f37dc7cb4e7d52920fdb200a7942623a7057ba82e467dcccaa5da416b48510d8364446a6a5e2a5aa8 a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea a73e1dcc3f22bbd9588229c7e83573015bb1cfceda889c2047b416a6815dc345a4bb54c5d46942cbfb9732b187a429b2 +03c1a1cd30a039d0dcb22fee2450a7fa79495a0d0f4f43d2de4d75bce003c0334a8860f5c164dbd94888a9f751235a3e570d31070e3e1293a7be616af7176600585d36ac013600157d2569d491da4b8a3bf3630c26e0b9925412189f50b0ae6f04c86477932e2ecd8c3546106ae1ebc684cc3adb27ed665eddece886adea4ce3 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0 b2297410d3ea8a5d51e9f00e0f5fc209dc54e7949127fa5c24462450f15d58c729adbe082af2ca668119a8ea811321e3 +888f6d9bc7c86c0079fbfd42d8c08d6958f40f6e570fb0b1f03d2f8f8a63df4fcc87b379a222cf835820a999d34996e08961f13b86b075e7fd1c303cd3baa44de42168561589012f7e5300da4f8bdf470c07119a5d9f7ba7293568cd7c6a1b7fc1e41cda40bed7d46e5a28af67ae2aabfefe67a86a1c601e6f5ee543e09bd7b6 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294 a5188ffe13b590ae72a4651386b26222a6eb2006b3dc43e188a00984aa99c05d203aede68d51a08daa1b1235ef27e341 +48453340f1317769e6ee6e103153714365731163dc18f84e9f2fa4b120f9c5a9645ee2f9b66c84c26d95912b422b009b64af96aa418b2427a4209f2e7513ba8e43ec8cf20b34e7529b22eb1199545afe9a9f7d9bcb320aec9ee0162f91c0d1dd9674c9c284f25199c5e109f6f84d7ed0d269cc6413edb81bc2c83e37d644d8b9 b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a b35642d05483c7bbf9a45d6413beabc8a954598b12bafea0cd93c18b21b4413c286d6e58ec295940fb1fee0eb67d251a +4bdfd3b91d83108409ad765b256e0c9b9937ecf647f8e6f9fc807e2e72af8246178b3fe046b4ea10170450d71a4eec790ecb05f03d7077341de26c4db7eeae24d55c9a9093e837dfdb38168fe8230cb9605825a1282fecd741989bfcdb34678fe077477927f66bd26d003e5dda22043341a14dd31841ba483ad5ce2701e0f68e 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4 a9593277a548058549b9207b8feb6099713273dbb66d9b1b5514e7b151ef9763fa04153d61d0502813b5a6e37c3164d4 +e6cdee8558bc1eacc24e82f0624ce8d02cc8d925b4dd3dec3a72f4a4e0fb76076bfa3ef2e2c33bdd7c27b322bdc09bbfee8fe46f75dbd7bbd2af09690b7137943efe21706e0a1b6d3089540fc58d85ddb55ea836616db573e36c521be008893f40a0a7c349602cc178ea43be59d31ec6449e7ff2c5379379f7d7645134df1bc3 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04 9473e67ec02d0d1c4d11b002af71e6be9800685f38c4d483160bcfb8b310bf42e77a25099c78017521f44b28c23c35d9 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P224_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P224_blst new file mode 100644 index 000000000000..63da90cb406f --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P224_blst @@ -0,0 +1,60 @@ +699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615 8c35d211d6be65c6033d87e78e3e85600722649fd0f3d6241511d0a07d5a5bb43b5cca2993ced34904c08b73c9ba57db +7de42b44db0aa8bfdcdac9add227e8f0cc7ad1d94693beb5e1d325e5f3f85b3bd033fc25e9469a89733a65d1fa641f7e67d668e7c71d736233c4cba20eb83c368c506affe77946b5e2ec693798aecd7ff943cd8fab90affddf5ad5b8d1af332e6c5fe4a2df16837700b2781e08821d4fbdd8373517f5b19f9e63b89cfeeeef6f cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5 8cc1eb920e1dd33cd0f0f01dc022a3d8c13c35544711595c92da8bca2b181ecf4772942bc777be8b6eef79c56539fb36 +af0da3adab82784909e2b3dadcecba21eced3c60d7572023dea171044d9a10e8ba67d31b04904541b87fff32a10ccc6580869055fec6216a00320a28899859a6b61faba58a0bc10c2ba07ea16f214c3ddcc9fc5622ad1253b63fe7e95227ae3c9caa9962cffc8b1c4e8260036469d25ab0c8e3643a820b8b3a4d8d43e4b728f9 dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73 b15219895e2ea6b081a6f5e1d242067b65ebdb7aa68b5309d3888fb3bae343ba316dcc97f25539f3ce9ec3ddaedb59c9 +cfa56ae89727df6b7266f69d6636bf738f9e4f15f49c42a0123edac4b3743f32ea52389f919ceb90575c4184897773b2f2fc5b3fcb354880f15c93383215d3c2551fcc1b4180a1ac0f69c969bbc306acd115ce3976eff518540f43ad4076dbb5fbad9ce9b3234f1148b8f5e059192ff480fc4bcbd00d25f4d9f5ed4ba5693b6c aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e b6e8199bea33673f60903c541bbd19f67f3265e76e5187da229e5abf82ad222cf742f01b995e2a4df3a6c463186b10c2 +c223c8009018321b987a615c3414d2bb15954933569ca989de32d6bf11107bc47a330ab6d88d9b50d106cf5777d1b736b14bc48deda1bc573a9a7dd42cd061860645306dce7a5ba8c60f135a6a21999421ce8c4670fe7287a7e9ea3aa1e0fa82721f33e6e823957fe86e2283c89ef92b13cd0333c4bb70865ae1919bf538ea34 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4 8d9bdce8566aca85c2e17bcad45e52de6e99b0fa0fb64996014be10878ca2164214122dca0bb1821c0e5ba8a43698440 +1c27273d95182c74c100d85b5c08f4b26874c2abc87f127f304aedbf52ef6540eba16dd664ae1e9e30ea1e66ff9cc9ab5a80b5bcbd19dde88a29ff10b50a6abd73388e8071306c68d0c9f6caa26b7e68de29312be959b9f4a5481f5a2ad2070a396ed3de21096541cf58c4a13308e08867565bf2df9d649357a83cdcf18d2cd9 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131 b4c157e682438e96f8381b50e34b20a0549023e59c27a93f4b500795a8ee1fac2cf1be1a7db6672738ebc025e8db7f9c +069ae374971627f6b8503f3aa63ab52bcf4f3fcae65b98cdbbf917a5b08a10dc760056714db279806a8d43485320e6fee0f1e0562e077ee270ace8d3c478d79bcdff9cf8b92fdea68421d4a276f8e62ae379387ae06b60af9eb3c40bd7a768aeffccdc8a08bc78ca2eca18061058043a0e441209c5c594842838a4d9d778a053 d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974 ace3769c8ecfc9c79e12b516823b6e2bb9cbd31ce46460b7b4f3801091dc8f51ecbaf236c41adb6e42d2a32f9271e46d +d0d5ae3e33600aa21c1606caec449eee678c87cb593594be1fbb048cc7cfd076e5cc7132ebe290c4c014e7a517a0d5972759acfa1438d9d2e5d236d19ac92136f6252b7e5bea7588dcba6522b6b18128f003ecab5cb4908832fb5a375cf820f8f0e9ee870653a73dc2282f2d45622a2f0e85cba05c567baf1b9862b79a4b244e 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8 8d528733be07aba1bd517857625e0ae6c7cdc5cd240c775b061b6d7f10ca7ba9c9462ad02c7765714f73b172da6c8e60 +79b7375ae7a4f2e4adad8765d14c1540cd9979db38076c157c1837c760ca6febbb18fd42152335929b735e1a08041bd38d315cd4c6b7dd2729de8752f531f07fe4ddc4f1899debc0311eef0019170b58e08895b439ddf09fbf0aeb1e2fd35c2ef7ae402308c3637733802601dd218fb14c22f57870835b10818369d57d318405 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2 b086681bb2c6ca94c37d975b613285c8657c6cfa3f982ae3857c06921117298697c947d0dd8b63117645b78d1b6f8608 +8c7de96e6880d5b6efc19646b9d3d56490775cb3faab342e64db2e388c4bd9e94c4e69a63ccdb7e007a19711e69c06f106b71c983a6d97c4589045666c6ab5ea7b5b6d096ddf6fd35b819f1506a3c37ddd40929504f9f079c8d83820fc8493f97b2298aebe48fdb4ff472b29018fc2b1163a22bfbb1de413e8645e871291a9f6 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7 91167bc0a4e7a973e6f8277f579c9a60ae72b71d749710d5f62bdf0c43bd4834f976449b5b4ccfbd638d8a5ef8574d8b +c89766374c5a5ccef5823e7a9b54af835ac56afbbb517bd77bfecf3fea876bd0cc9ea486e3d685cfe3fb05f25d9c67992cd7863c80a55c7a263249eb3996c4698ad7381131bf3700b7b24d7ca281a100cf2b750e7f0f933e662a08d9f9e47d779fb03754bd20931262ff381a2fe7d1dc94f4a0520de73fa72020494d3133ecf7 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b b8be20b0787dade1c72593790b134010df9993c9b22759f380c78d373d41210237100b56f75734f4ab5b625a48cdaf94 +30f0e3b502eec5646929d48fd46aa73991d82079c7bd50a38b38ec0bd84167c8cf5ba39bec26999e70208af9b445046cd9d20c82b7629ca1e51bdd00daddbc35f9eb036a15ac57898642d9db09479a38cc80a2e41e380c8a766b2d623de2de798e1eabc02234b89b85d60154460c3bf12764f3fbf17fcccc82df516a2fbe4ecf c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6 b3db045cc31c0a3011b9fa650265cbfd60ec4991ed79a5130e6acdecde6e2da0f86c392b4411cd32ae683508c504b8fe +6bbb4bf987c8e5069e47c1a541b48b8a3e6d14bfd9ac6dfaa7503b64ab5e1a55f63e91cf5c3e703ac27ad88756dd7fb2d73b909fc15302d0592b974d47e72e60ed339a40b34d39a49b69ea4a5d26ce86f3ca00a70f1cd416a6a5722e8f39d1f0e966981803d6f46dac34e4c7640204cd0d9f1e53fc3acf30096cd00fa80b3ae9 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc 9a00f8ec260030e4945edc5ffbdf613e56dbe457f0acc3de39b01c2fc436b6b1f5f7c4cbcc967aca245857399020eddd +05b8f8e56214d4217323f2066f974f638f0b83689fc4ed1201848230efdc1fbca8f70359cecc921050141d3b02c2f17aa306fc2ce5fc06e7d0f4be162fcd985a0b687b4ba09b681cb52ffe890bf5bb4a104cb2e770c04df433013605eb8c72a09902f4246d6c22b8c191ef1b0bece10d5ce2744fc7345307dd1b41b6eff0ca89 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3 93842d9535aa268b550e8f697c53ddb5761da5907c2c0c3ac1d6c902f572d1f4838d92ef97858c2e763b73b3a90d8b94 +e5c979f0832242b143077bce6ef146a53bb4c53abfc033473c59f3c4095a68b7a504b609f2ab163b5f88f374f0f3bff8762278b1f1c37323b9ed448e3de33e6443796a9ecaa466aa75175375418186c352018a57ce874e44ae72401d5c0f401b5a51804724c10653fded9066e8994d36a137fdeb9364601daeef09fd174dde4a 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912 91eef2327d4d0df276aedcd35764b47cd2c6e615653b68dd50a0799b049519f68c47ca58bef81c5bbf874268874a41fd +2b49de971bb0f705a3fb5914eb7638d72884a6c3550667dbfdf301adf26bde02f387fd426a31be6c9ff8bfe8690c8113c88576427f1466508458349fc86036afcfb66448b947707e791e71f558b2bf4e7e7507773aaf4e9af51eda95cbce0a0f752b216f8a54a045d47801ff410ee411a1b66a516f278327df2462fb5619470e 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa 8f4db2ed03c428e0499c5235c9ee48036da22b50ee3cd4d044bdca57d08c12c7dc3094e83b15c8d73fb2d89743278ed4 +1fa7201d96ad4d190415f2656d1387fa886afc38e5cd18b8c60da367acf32c627d2c9ea19ef3f030e559fc2a21695cdbb65ddf6ba36a70af0d3fa292a32de31da6acc6108ab2be8bd37843338f0c37c2d62648d3d49013edeb9e179dadf78bf885f95e712fcdfcc8a172e47c09ab159f3a00ed7b930f628c3c48257e92fc7407 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972 90759b5c37f27b385789d663d104ab61ea4f44a35c38ae88568b2b31043257280259ddb46025c7e7f490ec69267210c4 +74715fe10748a5b98b138f390f7ca9629c584c5d6ad268fc455c8de2e800b73fa1ea9aaee85de58baa2ce9ce68d822fc31842c6b153baef3a12bf6b4541f74af65430ae931a64c8b4950ad1c76b31aea8c229b3623390e233c112586aa5907bbe419841f54f0a7d6d19c003b91dc84bbb59b14ec477a1e9d194c137e21c75bbb f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170 a20db20bea6ada631b8a5993e11b45ccf0f09d158d10d833e2de7b870892a1a086fb0479e7d8ce2eb24d335e7e68326f +d10131982dd1a1d839aba383cd72855bf41061c0cb04dfa1acad3181f240341d744ca6002b52f25fb3c63f16d050c4a4ef2c0ebf5f16ce987558f4b9d4a5ad3c6b81b617de00e04ba32282d8bf223bfedbb325b741dfdc8f56fa85c65d42f05f6a1330d8cc6664ad32050dd7b9e3993f4d6c91e5e12cbd9e82196e009ad22560 c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85 8dc6db776ec46d7d73468fa00f04252f802b1f9df3ed7ad874c22e099b7652219f21900e816ff86f20ddb6949043f33f +ef9dbd90ded96ad627a0a987ab90537a3e7acc1fdfa991088e9d999fd726e3ce1e1bd89a7df08d8c2bf51085254c89dc67bc21e8a1a93f33a38c18c0ce3880e958ac3e3dbe8aec49f981821c4ac6812dd29fab3a9ebe7fbd799fb50f12021b48d1d9abca8842547b3b99befa612cc8b4ca5f9412e0352e72ab1344a0ac2913db 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6 8f68ee37242a45bb173b9a9f609a968dfa576a2b9ec7051e042cae175522a3bb3eeb0c819efc8fe88aef0d43581ba185 +4cc91f744ac858d3577e48813219aa3538dd813b186b42d1e6218376f07cc1cc448ddd6b37240e98bf953f49cf54d65c12878b33c0bf6eb1c60254f0b6fa974f847e53abc56773eef6f29885dfc619e6a48fc15a667ca94001a0c945b6357a53221b0f4b266181456b0d2d25e90708777f1a6f85971c00140c631c1991e0fd06 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39 a6364e17dfb3558ff62daf617e1d82322a991aca2fd0645be55d234c5ff9e401ebd4b216bae2117e2a07717d8f8c50d0 +58f43cc1924de4bc5867664adbc9d26b4f096a43aca47c27c52851b006dc2a658919ef9ce5b5ac48372703be15ac51631c2bd84b88f479f113b0569a9a09e230ec1e8e573474c6075284d3e57d973829af35325d9e7dab4a5f9b065155bbcaff3642a82ef4c9b9e127d3575c050721653da3b087d3fa394192897a5519527d19 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6 a4f2eab127c0bf40136b4e17cd9811224823b664eeef829a982cf5a2c6d03b7c57229082396b56b15f410153bb0e62e1 +113a2806b052fde683ee09453098e402204155afb3776fd1cad3a9103421d327eab8f9ec0dd050ffcc83f93b34ea707705fabeccfe43ab1a71c95298fd3ec769d99ead1066950eee677d225816e0faad19cf69e1b35d16771689e2092cafe16d7c0dd7b0db73fffb8d0f3eaed83004dd21e753530ec939c89ba25578fa5f785b 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b b30db7e1ac38df53beb1aa2fb8f3354442ee0fe71bdecfb9abc7fd2c1e4ba4d44bd87554edbece95f80fe7d2bc701c77 +64cbfc8f2e2149a31b3e8a80c4a552f6c62aaeb7990b6e0ee55500a9d17be04213406578caf315951086dff5c2af3b5ce17d425d185101ef26f86396ba3a129a4f3f8e2dd595f59efb6c0f5c2dcc394569d7268695e9ac7daa84203f1f1895f1f9e4b514a5c9cd23baa63454710144fe735ad9b8f42d8c43267aa434a26d7e5f 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b 8c0ae14b112e2c09767e9225f7781aa3e1bd3b8d8f14fba26a7d11ce8eb96eb88b1e83453f044a021a247e431ef33d76 +a10a11c8e30fff118d371daf824f16c08200b83ea059436466a4611ccac93b2dea2de8c1006f946196aef7fe9b0c251a391b0340f21797798278b412ff2b53842eec6450728e2bca062f8337a2c204b9ea04ff660cd4d4db559f2f11c4d8ef199021339fcc82396f7a93926cf5f247e37d8067fe50692de54f102bd5ab51925c 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8 963c86dabbd1c9688e2d075a62644f84d3591de72734a645128c37b8488ab1ffa3ba3fb7616d7883ad27150b8a20595d +b3f720bf566ffa369259f4361959ae0641d2755ec264a4c4349981df2b02563275b2b9adb5aee47f7a456760a971991ffed6b17809bb9694138d1677fa916123795239353158fc6b22d10f20d26f5d2dcd8c56c44373eea5b93067dba2d7c5318dac2e9e8714873cb1b37f58c011fd14fa1e535554efe05f468bfc8e11cd8b99 e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784 8cbde575886fe1095d62709cd08fa31c8a619fa7d6f9d42c63b3833f508c5ef0d66f19d087af1259525fb2e0c80bf06b +0a398a46df7ccc48d1e7833f8bbc67100f1ef77a62dc78bbc115b2a662f9591fbaaa91ad3d788e2fdd1b3164e45293d4f5686c151296901768028ac80ded4bf89c647ad35f0c7c4cb318c0c757c1d83c44d850e5fd4677281b3f13b1ee54de79c8c042813f9d3312dcc6111a68299cb7e829557d7f3d96e702f65aefc6499415 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c a2b2bbafaab384644d83d543fbc1ce79e6b2884bf5fa756dabd6727eeb3cf56e0f21ac8e0d97503882d7aa321acf93e1 +8c33616821a6038b448d8918668977fcf1ef5aa0cf7c341837b39bbcc9bca875a3757f4b392630e9995b9bbe4eb66978b877586adaa02f99d2344dae082a7603351d8ffcfca081ab403cd0acb90d078dd1d0789c2eb3185c62bff2d9f04cd38e509e3b83c12ed0a5c6808fc42f7ba5b06acdc496c8ad9be648ee6a4505f8560f 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583 a5d7f6554ec007fabf069f209438ffee7e0dc09d7addcf7c3fdcdc03a0faa082d84da9657be48279c2719cb285244043 +94d56535fd4edfe67a0daa6579f9d53bf6b7b8830ae2aeb62892ff59f18756ddf2811b449c7d20d65d54f8507de4e7c50eaa084830637812aa4b250a4d61ab67845be36e4a41cdc0a70f8d6e3a63d4514f0dc197e6486015046a316153d5f3a3a4a0ae1ed7ea5fa55e12e73d333333685c02e0eb636234ea7e6d4b76b4b76b5a 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2 8854bcdc34da4e2be7ca0f5cb9b604757e2c447db1c7302b3e6cb097886a74320a89064f086dc0c6f996b6c747a83846 +5d8ebdf9eb28b47bdafaa36bf0b66a9eaf99b6c83959da4f2b1151b4f4ecd28fb115a64c0cb9491093a7e9b9c53ec423e4c72e7765bb9c818da0e8c428667e44474a71db4867130c77c40bfd8544b2d7b9d6464d2b8e6a48482153256a32437c3a747231f51134dd14c703407e31146a6fcde23bededcf16950486e90ca69ac0 f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc a05ad8028d7bbc779fffea72c1e459ad29b2ea2e989f3b2dbc39b3498e462761c9df5fae32ca7aedf7744b2f5f083baa +25e4416695f77551fdce276355528ccf1ddc2483821c5d22d751d50111ca2fadc6593b52c74f4b5957494f1df25b0b2f86950d0d19229ec6506fee8581d2dd09d48418b146ff16bd84a17ca0dc83b1888eb407376da6c8a88fa1e60b8c2a2471dfde4b3996ef673d5bde3d70c434dc9f2488e9de16ae657d29e5e59ec922a1ec 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd b36fc4c34fbbd15f7e639d0395662276519fb992588e10979e090474e6390fac934b694d30ca1ca88c8f22ee95a69fa2 +9164d633a553deccf3cbd2effccf1387fa3177cd28c95d94a7d1a3e159c5e5c027758cc26493301b2f4d141d8d07a5fe5fead987ce5f30abeafcb48c302afc6c2309f0e93d9b6818cbb6972d222cb7b01302dfe202ae83b89f53150ae4a0e2b8fc0fd1091f19b4ab2e6ab213ab322d04f2c5f57113bfad3c5675227237abf773 e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3 921e67e869bf8088c6c570e05413d25eb3ea8835afbb8ca9e5c7b384db6f1af881809ff7032e902eb47a42cc6187712e +019df05929321ecea7ee1de4f412aba1c8d3c24437db04b194a68a0a59dd871be10bd3a4be6edf551350ea49fc7155a4d887e1221486291abe77a30633a4c4f7868fe2df24311cba0c73804883954460e122387ed414111ff96ff1aebac8b6a6491d8a0d16e48a63bf3d027c0f68ee4a4b234d73b412196706af8ea022b4dcef b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17 ac87821a476706f666285206367f1596d9d08e70c77c6286d1913ec15b69e8080e3eee3113e2974a9e6a55178fb2a3d2 +5d09d2b1d3fa6e12c10d8b26dc9aabc8dc02bd06e63ff33f8bb91ede4b8694592a69e4ed4cdf6820069e2b9c7803658949e877ffe23bf90bcf5ce1409c06c71d86885a94048b05ac0ec9db193e489a5a2bfa367caf6aa8ecdb032be366174343f6875d2fe1785e8d77334f5f469cec64998e08d3303e5c9a1923b34fdc105d65 efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085 a8362b5e1c8f42a003b7475c5a82cc79c8407dbdc00682c9f99205911cc92b62c8766c55d7413c5cd7c4374daac9640e +50f6dfc81c6cf189e0a310f992907fe93356cee9dea9a41c7671a8daf3f4cfe0c459ce6122c1e731dbf7593419d7114cb73b46956158a982c5d52c72f43f0f822046093c69aeff1f7e4cd8af00ba655c5baa2e7b6a400b4be1f6fd51b3e4cfb35a69c80a28c5cafb771b6c2e52e0aeef0e3fd045e8d40745f3f8b74fd969f816 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd a9f2c051f61d5c2e6dff8bd0ea7cf64d38d48461544875ef1848557e9621d05da90744e99575f205b1d7b80c9d1f01da +e90129ac6672c85bb7b6b18e9dc199c96c81fd65034b53c77818364d512366fb9cd1bc7c82404c451e561fc1ed916c0948f6ac561b33a1ccca093f07684b8c2bafa9e966377bd208556018a5bafb9edcecf70498c7140fe9c8cf3ad8b8c3b0aa489df797944465047465415bb0e24333235fcdd59a98829a3941eaaf62033e82 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d 88f20afb45a1f10eab9488edbc201854463e8de22356473255fe9cb6f4119064a78284dad362c4d46a9e4290f4daa4ad +3c9a483c9bee33b601549c592a82e95b4319b1e74b777877f0971bcb4273716b268e8f99f876e42f942f4cf08284896bbc1ffbf094ac0956c3cedfc3580cffa8c74fc6db29a371f2da2d05edb9185ece741fe0d3fabfe9d5b4d373755ebed13dc6840cfa3283b9ea46ec8b95c434f253ae86998182e9cc0e95ee64f323fc74b0 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0 ae1fd8c305f79d6b1bfed746180f40773367a67295267ffd8581389d1bbb6e7e2b6cfd187ef0e3b19577a0edd2de1ec8 +bfc073fdda63c5fccaa0ca8770c293e8154e7aec56128bbac4fdbd541d602216ebf7ca1e02b514d6e396f20683802ba3f334310a9226576926e3bb19ceee27738d13377cbafeb09d091043501702a07aa31d1f29d50ddc55adcf16ffd40578e734a4e6cb6535f26ad48e0c62ad90e79720000e87d419e92dca3e11f943655b03 e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d b155351e8eb66381426f31f61fb2233a4256f92aa780ac5ceb07ea1c1b1ccbb772aad38070400e8ace19d551dedc0513 +08079955d1a1f33728128c73673ec9f21a6ce138dcab5adc4dc068e6ab57314b9fbd8b013123b2fdafa9524fbdd0288777a233de8055cccfad83046ada6a19f01c47817496667bba8fc8b9456fc0e044a562d931dab1adcb66af8b66325bdf28d83ded3e2937958ccd19da540d70ef2c189f55a506c9c0d63406394c5bd3823b f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7 91a289b8bade7907fdc50e5aacf942326e1e864e41508a8e4ecc9cd358276ac1e7ef0aa80980865f319fd10d32015633 +23900b768f6cd42b8a8df0dcbc9cb5daec8de36b9d5c619adcc1ba2b649103d5af123746cdf19c3fd0665a6fb9338156182aa06181e3c6e37ce56979612af2927440424f89cef43fc754854b8a5c43370808cf5f9929cf47712512ce2f8a2a20d2e9f568c2848b27dfbe09142843c83905ffa5da3b15501761b03dbc2c5398b6 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c a124fd751dd22a42259777d5bac4ac3bcd323c0b3caf606948fb972ea868c1660fcd708c3163fc11db8bdf8e6a6f55e6 +1eb28c0bcdd18f73e347f957ece15b4cc83a771b0877e1feaac38e24028fb38ccea8b54ee017dc7c3d5a1327bc6f40b294aa65d7dc487f278846cd101ee84202f14b38aa2c275046aa2577f65ebaea41cd383e8def2fd0b4444dcf426fa75c4082cd7fa035cdb1e0d34a3c79d42130f5b0273eae75bc701dda3aebe7358f41b5 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18 8aec1cf2fa650d765dc3130e24204409fcdc54fd23e98ca254bac1787de2ed1ce4dc4d82024206f349b95b7a29f00fe8 +efab51855407438fd5c250670366bca3c026ecec4a59394f00d8a4b51746d0c4564366656d507e3e13e62fe7abeb976b8859895848dbaecf6582f1898ea06f00d4247702ed9721bd375aa83ae4c67c2eaa6e080777ea5ecf2cf787d785389560ac91cf63a52f0373c3185e18a3b8a466e21b61a239f1b77624eb1acacc76c4e1 bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a 89e3a31e17bed27a57e296d10a1178f3544bdebe93e2b2584ed48327701461104da8522a73f5d92a261f3090b0e4b402 +31c29ca10279a417f0cc9b1382cf54dbfdfc89f2e6ef08c403c11f580cbf8674b141ed1a417563282d99a55fc616d836421cde9424815c95e7fb7668bf3f137b29937f14882d74e034b732d78d91af7721aac4950734f5fa5d4b4d35534974f8cab6d2e6dca75ddb57e99148c8a59df9fc5bcd723e546e8356f671cf2f65640a dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738 89b8e20e9ca01d523833ee5bd0e4d80045892be9145b7d5ce2aec662838d6ceb6b4a73fcb549cd98db1052525faca2dc +8db476f92e332519c1a0ece5d8deded6efbd2d8e8784eea0a6b4c3b4296c35f5f8de4317e5c1627b91fb1973fee86c06e4992aa5a20cb7475c8808ff1da354d07a488dffa7838c6ec1e3f99e3acba831f27bee8434eeda3eb36d0c6df3658883cd40068b1bed841310f6eb38d4a3d07d85848770ff7933c054cd8b34662660b1 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01 aca88b4206bbaccd8cacd1d79b4acbe7a5df4176e598577f3e22b8cdd5d3464c4d76fc4519e96df165ab66de6af6f2f8 +fcb272c828fe8fd3c6f8de9410c7b6e2b36717c1b0e5e359e9109bd7fc378978aa98182a9d99961898ed88999b050d3b64d1457d7a899d6d273b9f4dde2aafa36d76329d62509043c338f265fc4c7d938459b7fa3b230a9f6cb632b61489546bb4181a5ad7f0d7369b8caced48eb374b075b2b325bc86add0f3b680cd9e80acd 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28 a34bdf52664a5cb56f8a0985e5a53dab4dc834dfa678ce0930f5eb5af93d2fa2911f46bb2fe7360af4b43e4cba74214d +7522492bdb916a597b8121f3e5c273b1d2800ef8c1db4f7dcbae633b60d7da5193ba53a63d7a377b351897c3b24903ae1cd1994211b259be3e6ae2cbc8970e4957fdf782c7d1bc7a91c80c8ef65468d4ef35428f26e2940ae8b0bd9b8074236bf6c00d0ebe83f9ddb2ade0f835138d39f33b59f244e0037c171f1ba7045a96f5 ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6 869c0e3eec5082a9af07cc87c72681ceca4748a9a6094e7625bc94b227214023a4c06832cff8ed8ae977e7b8e9f44f89 +61097114ff855c3e34a62d9b853f8982d35f29cfa4a89893badbca7849e5fb437a1a38d6451bf0ca5a0d528e352b8e4b57f2ea359a7fc8841d49dd3e570f9b016f14156b0bbc4be822e260bd147ec081454969e11cb0034b7450ef4deb7ed6edb977e2f4ed60121aa095fb0ab40240dc329ecc917f5c64b4410612af065ee9dd 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc 92fbfac9d45c5147282f21e9d48344fc94f3335bb9a474d42c27d14fa855b137670303109f9a967c54b1a3d151833b64 +dd09ae6c982bb1440ca175a87766fefeacc49393ff797c446200662744f37a6e30c5d33ba70cbd8f12277fd6cc0704c17478bbab2a3047469e9618e3c340a9c8caaff5ce7c8a4d90ecae6a9b84b813419dec14460298e7521c9b7fdb7a2089328005bd51d57f92a1bcbeecd34aa40482b549e006bbf6c4ce66d34a22dda4e0e0 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b b0e3e25f55cc66103750b074bd227b3aedc88b3d12d6621a01ef7f470c06a8fe1fed4af4c62d9f96033c8d7d85948cec +37a73e2774d3b274db426c89b945696daa96035031f72cea01894b24508c7f81961ec254d36ed6a0f448e11cf7950af769dc6cd2c47e52c6caf0ea92c270974f0214b4db436c36a60fb722060a6bb544462a82e1714f5906ec32886f7d59ebf289541c3a00ec1e004892ef2b1286a0194f55d083c6ec92c64b8fd1452e1c68ba afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc 97c8272804022e111b004a78198ad8ebdc9f31a15d29e88fdebcb7684161dabe55df9fb19328fb403015fe553ec28b8a +9dc2046ffdc6804544db964481abe5d2d276a2a9eeec4c7ad40215b1de23561d402db69bd0f6eec2254711eea4487c64d9a6b62c3ebaf5ffa8db6e7e3a6e17154d126967a47a853a6f8339bdca9be306a13c7f992ded7619b0da59909a49b1e0930360e05b47f18628a36d69b2f87f2bfddd6a5d4a72f84dc76dbdd43f3a6a35 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c 8262bd756a63c9e10f293bdc65a818b421970da9a40472ba87cad9a2df9b8b478dfb3ba486cc54a19a3325b7d09ac545 +d9c6847fce688c5e7525a1098b545cb6c15dcd21a02761fc82fc664372a667390680135f91c01a2fa5430c634b1a6d1cd6002d8aa021e7bf5956a7901c2f81bc25d502ba5f55a55f30c0323dc68205cbefec0538e68654e7b327ac1743641896c3e740d8f66f400902b304eafaa4e0d8cffae140536f0922444cc3216a675697 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc b5ec2c90e0caf88d9fb50298b7dd895e5e06886df1c34e001bebdcf64121163b4417894ada4fd7807f7638e625994805 +69df8a01b66f04930efd2012ff2243874f256ca8758145d2a9e4ecc84d0dbdbd0dc494ae06db0ccbe819918137c90957114558580d6623efbafdd342b38dad9f08708084d32f874fba04782ce26aaab78de2102ad171f8a8f2b30b5bd3d55fdac5fa3acd6f7def7e61c2533938572b331ba6d1c02bd74bfdbf7337ade8f4a190 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4 a661da4539b9838910ca2e7dbc039e0f78559e40c6c1b22a791309d8593dc2a0619c7bf185054b670ffd5919866918b8 +927524982b8d60777c1105c86fac05f634abf58c73f84fb95d81ba0b86e1e43592c4fcad2e395a40fbe7005697d86088e2fb3bb7287eb3f917d4f2dc281f5cbe65d05b4f9623bca849b10a03beca6aa2056a12ebb91cf257ac448c5e9a78f8349a6a29b17c8978bef43a443cbb8a149eb23f794844fc41693f2dbb97181444be a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916 a8c0cd6f7a272ed6d7b81e9ae8e32749bfa5c62b9211254b2c81004157c8e3b08f5ad5f08fd9ced7799bdebb1f2e08ce +5f9042283561e7f19a436d01c7ef5a950a6d77ede5629cd7e43c0a5d58e8c5673c37945a453291d12938253c71dbe12c8b022ba7276eda6be034ef5ec1ec77dbd1e08f0d7b8e7725b7ec671c075e008a20f77f4ab266f97079b0aa6337df59a33b881954084057b21f294dd14bcb0869a4a6f1f597955ec7bf9d19bb3537a66a fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b a0e52700f891a51a744150f490a6b5508213c8829f56bb2919198718b8202a7169ca5568a679be9e4393acb834e4da89 +c2ae5573d3bf396523bfb703db8502fd0760cd1be528f6ddbfb95aad399e0b19f3bd9e0fabdb05d49e3f893dffec5b627c9c2f7ad5f32e92e4e27a38cb5c28657657377fdfa1b66cd7ac3d15c6d49df92d284db99f69744f37dc7cb4e7d52920fdb200a7942623a7057ba82e467dcccaa5da416b48510d8364446a6a5e2a5aa8 a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea a73e1dcc3f22bbd9588229c7e83573015bb1cfceda889c2047b416a6815dc345a4bb54c5d46942cbfb9732b187a429b2 +03c1a1cd30a039d0dcb22fee2450a7fa79495a0d0f4f43d2de4d75bce003c0334a8860f5c164dbd94888a9f751235a3e570d31070e3e1293a7be616af7176600585d36ac013600157d2569d491da4b8a3bf3630c26e0b9925412189f50b0ae6f04c86477932e2ecd8c3546106ae1ebc684cc3adb27ed665eddece886adea4ce3 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0 b2297410d3ea8a5d51e9f00e0f5fc209dc54e7949127fa5c24462450f15d58c729adbe082af2ca668119a8ea811321e3 +888f6d9bc7c86c0079fbfd42d8c08d6958f40f6e570fb0b1f03d2f8f8a63df4fcc87b379a222cf835820a999d34996e08961f13b86b075e7fd1c303cd3baa44de42168561589012f7e5300da4f8bdf470c07119a5d9f7ba7293568cd7c6a1b7fc1e41cda40bed7d46e5a28af67ae2aabfefe67a86a1c601e6f5ee543e09bd7b6 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294 a5188ffe13b590ae72a4651386b26222a6eb2006b3dc43e188a00984aa99c05d203aede68d51a08daa1b1235ef27e341 +48453340f1317769e6ee6e103153714365731163dc18f84e9f2fa4b120f9c5a9645ee2f9b66c84c26d95912b422b009b64af96aa418b2427a4209f2e7513ba8e43ec8cf20b34e7529b22eb1199545afe9a9f7d9bcb320aec9ee0162f91c0d1dd9674c9c284f25199c5e109f6f84d7ed0d269cc6413edb81bc2c83e37d644d8b9 b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a b35642d05483c7bbf9a45d6413beabc8a954598b12bafea0cd93c18b21b4413c286d6e58ec295940fb1fee0eb67d251a +4bdfd3b91d83108409ad765b256e0c9b9937ecf647f8e6f9fc807e2e72af8246178b3fe046b4ea10170450d71a4eec790ecb05f03d7077341de26c4db7eeae24d55c9a9093e837dfdb38168fe8230cb9605825a1282fecd741989bfcdb34678fe077477927f66bd26d003e5dda22043341a14dd31841ba483ad5ce2701e0f68e 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4 a9593277a548058549b9207b8feb6099713273dbb66d9b1b5514e7b151ef9763fa04153d61d0502813b5a6e37c3164d4 +e6cdee8558bc1eacc24e82f0624ce8d02cc8d925b4dd3dec3a72f4a4e0fb76076bfa3ef2e2c33bdd7c27b322bdc09bbfee8fe46f75dbd7bbd2af09690b7137943efe21706e0a1b6d3089540fc58d85ddb55ea836616db573e36c521be008893f40a0a7c349602cc178ea43be59d31ec6449e7ff2c5379379f7d7645134df1bc3 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04 9473e67ec02d0d1c4d11b002af71e6be9800685f38c4d483160bcfb8b310bf42e77a25099c78017521f44b28c23c35d9 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P256 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P256 new file mode 100644 index 000000000000..2709b488112c --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P256 @@ -0,0 +1,60 @@ +ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590 b268c26cd96e7153a12b530ad1916803f3ba2852d7b7b121572d0959fc2d42f31182de4a510f268b09ee2c7c7f591c08 +9155e91fd9155eeed15afd83487ea1a3af04c5998b77c0fe8c43dcc479440a8a9a89efe883d9385cb9edfde10b43bce61fb63669935ad39419cf29ef3a936931733bfc2378e253e73b7ae9a3ec7a6a7932ab10f1e5b94d05160c053988f3bdc9167155d069337d42c9a7056619efc031fa5ec7310d29bd28980b1e3559757578 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98 97bfdba94119312825aed4c04434edea6af8a9891663d646be2dfc1c59bf5ecf4b2d895e936c18d2d10edf782de2bada +b242a7586a1383368a33c88264889adfa3be45422fbef4a2df4e3c5325a9c7757017e0d5cf4bbf4de7f99d189f81f1fd2f0dd645574d1eb0d547eead9375677819297c1abe62526ae29fc54cdd11bfe17714f2fbd2d0d0e8d297ff98535980482dd5c1ebdc5a7274aabf1382c9f2315ca61391e3943856e4c5e616c2f1f7be0d a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870 885cf376f62fb69ed5c96353b2689c4507047fb10e9e54896a97562a58f4e02c9ccb5edf2ff1b6d065bbe4e4110641af +b64005da76b24715880af94dba379acc25a047b06066c9bedc8f17b8c74e74f4fc720d9f4ef0e2a659e0756931c080587ebdcd0f85e819aea6dacb327a9d96496da53ea21aef3b2e793a9c0def5196acec99891f46ead78a85bc7ab644765781d3543da9fbf9fec916dca975ef3b4271e50ecc68bf79b2d8935e2b25fc063358 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f b87c8607b4b1106e3222cb2e77f90c1ebdb2e12414d0519be66fc4b73d12920806a96d3d162a6407bfba97372070c42f +fe6e1ea477640655eaa1f6e3352d4bce53eb3d95424df7f238e93d8531da8f36bc35fa6be4bf5a6a382e06e855139eb617a9cc9376b4dafacbd80876343b12628619d7cbe1bff6757e3706111ed53898c0219823adbc044eaf8c6ad449df8f6aab9d444dadb5c3380eec0d91694df5fc4b30280d4b87d27e67ae58a1df828963 daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d a507f255ac81e5550868ead70359325445ddb7f0302ad0e1859e3be1bca65e2ec0669c4955e13872efa6160ab54c5d15 +907c0c00dc080a688548957b5b8b1f33ba378de1368023dcad43242411f554eb7d392d3e5c1668fad3944ff9634105343d83b8c85d2a988da5f5dc60ee0518327caed6dd5cf4e9bc6222deb46d00abde745f9b71d6e7aee6c7fdfc9ed053f2c0b611d4c6863088bd012ea9810ee94f8e58905970ebd07353f1f409a371ed03e3 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5 8c1c76ff5d32de7e733cb438729348ee4eb0ac68df6dd8c92452535cc7a3f16d7daa5d46f29baff05db20d049d533e5c +771c4d7bce05610a3e71b272096b57f0d1efcce33a1cb4f714d6ebc0865b2773ec5eedc25fae81dee1d256474dbd9676623614c150916e6ed92ce4430b26037d28fa5252ef6b10c09dc2f7ee5a36a1ea7897b69f389d9f5075e271d92f4eb97b148f3abcb1e5be0b4feb8278613d18abf6da60bfe448238aa04d7f11b71f44c5 f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96 8599e79ad18aae1c7f57e273c2fa54fe2117048dab27fe2bf6dddd7acea228690ac012ea8e9ad7eafb4e2a7aa51711f1 +a3b2825235718fc679b942e8ac38fb4f54415a213c65875b5453d18ca012320ddfbbc58b991eaebadfc2d1a28d4f0cd82652b12e4d5bfda89eda3be12ac52188e38e8cce32a264a300c0e463631f525ae501348594f980392c76b4a12ddc88e5ca086cb8685d03895919a8627725a3e00c4728e2b7c6f6a14fc342b2937fc3dd 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d 8e85ca826e92838e902c169378e2b6bcd83c9635b42d48b42806880fcd96aa949d7500a50c86b5b2b41fed9461666455 +3e6e2a9bffd729ee5d4807849cd4250021d8184cda723df6ab0e5c939d39237c8e58af9d869fe62d3c97b3298a99e891e5e11aa68b11a087573a40a3e83c7965e7910d72f81cad0f42accc5c25a4fd3cdd8cee63757bbbfbdae98be2bc867d3bcb1333c4632cb0a55dffeb77d8b119c466cd889ec468454fabe6fbee7102deaf 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9 90d1851adb0c004512492d23530bd490f655e94a203442eb7316dec7a20b445e22117eaab66e26f2f8696455219dbc40 +52e5c308e70329a17c71eaedb66bbee303c8ec48a6f1a2efb235d308563cd58553d434e12f353227a9ea28608ec9c820ed83c95124e7a886f7e832a2de1032e78dc059208f9ec354170b2b1cab992b52ac01e6c0e4e1b0112686962edc53ab226dafcc9fc7baed2cd9307160e8572edb125935db49289b178f35a8ad23f4f801 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634 a834d8e3706dc41a3db65b95cf8f1a7548214835bd026a148c90d3f2fd9bbcffd6c02940ccb2561be3b9dd9bdc90804d +d3e9e82051d4c84d699453c9ff44c7c09f6523bb92232bcf30bf3c380224249de2964e871d56a364d6955c81ef91d06482a6c7c61bc70f66ef22fad128d15416e7174312619134f968f1009f92cbf99248932efb533ff113fb6d949e21d6b80dfbbe69010c8d1ccb0f3808ea309bb0bac1a222168c95b088847e613749b19d04 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27 afffd6737254b240e7215e10d62f7222611409f2b19a30ec249e2c62acc8beed0cb2218f24fa0ac8c8e8dba429215955 +968951c2c1918436fe19fa2fe2152656a08f9a6b8aa6201920f1b424da98cee71928897ff087620cc5c551320b1e75a1e98d7d98a5bd5361c9393759614a6087cc0f7fb01fcb173783eb4c4c23961a8231ac4a07d72e683b0c1bd4c51ef1b031df875e7b8d5a6e0628949f5b8f157f43dccaea3b2a4fc11181e6b451e06ceb37 cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d a432a0e73f5f01b48ab408ab1c1fe310760bcb8241f77efee48d03575a8774635b064b475283016a920435e152c6d0df +78048628932e1c1cdd1e70932bd7b76f704ba08d7e7d825d3de763bf1a062315f4af16eccefe0b6ebadccaf403d013f50833ce2c54e24eea8345e25f93b69bb048988d102240225ceacf5003e2abdcc90299f4bf2c101585d36ecdd7a155953c674789d070480d1ef47cc7858e97a6d87c41c6922a00ea12539f251826e141b4 b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c 891a11d20058b7007663f19c4a38b517e22792631d8103a64e0d9f8983e2b1f314839197a9cda32584e30eb7562a374a +9b0800c443e693067591737fdbcf0966fdfa50872d41d0c189d87cbc34c2771ee5e1255fd604f09fcf167fda16437c245d299147299c69046895d22482db29aba37ff57f756716cd3d6223077f747c4caffbecc0a7c9dfaaafd9a9817470ded8777e6355838ac54d11b2f0fc3f43668ff949cc31de0c2d15af5ef17884e4d66a 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48 85748352538ca4cfa2bf83bb8adb3f3fb5e33d7776fe4fef3f3eb6bd95b98df66294b2ebe8fbf872d0c5caaa316b3b7f +fc3b8291c172dae635a6859f525beaf01cf683765d7c86f1a4d768df7cae055f639eccc08d7a0272394d949f82d5e12d69c08e2483e11a1d28a4c61f18193106e12e5de4a9d0b4bf341e2acd6b715dc83ae5ff63328f8346f35521ca378b311299947f63ec593a5e32e6bd11ec4edb0e75302a9f54d21226d23314729e061016 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f 9064f0640e03b687297835c46fa975d9949da5723edc61fb4ce4e510577df10fcddcc93d5f34094c58b96f4be70c4d23 +5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 b6368deaf5a24092b3b190bc3a4cf6737d27b6c231aff45183e8eca313b01fa6b307dafa4cd96995a1e855964e747636 +c35e2f092553c55772926bdbe87c9796827d17024dbb9233a545366e2e5987dd344deb72df987144b8c6c43bc41b654b94cc856e16b96d7a821c8ec039b503e3d86728c494a967d83011a0e090b5d54cd47f4e366c0912bc808fbb2ea96efac88fb3ebec9342738e225f7c7c2b011ce375b56621a20642b4d36e060db4524af1 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 b9cc4882f9f982d13ee5222c8e76ab320be736d85f558412588d99a7cfdb56fbbdc714cf5246cc1e75ef3a32af8b5d7b +3c054e333a94259c36af09ab5b4ff9beb3492f8d5b4282d16801daccb29f70fe61a0b37ffef5c04cd1b70e85b1f549a1c4dc672985e50f43ea037efa9964f096b5f62f7ffdf8d6bfb2cc859558f5a393cb949dbd48f269343b5263dcdb9c556eca074f2e98e6d94c2c29a677afaf806edf79b15a3fcd46e7067b7669f83188ee e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef b254b3a0ea58612ca0055f4daf29f3035bcb96997c7c6123bbb038c36ab180a609e5dac12cf824f16b9c4c4eaedf9065 +0989122410d522af64ceb07da2c865219046b4c3d9d99b01278c07ff63eaf1039cb787ae9e2dd46436cc0415f280c562bebb83a23e639e476a02ec8cff7ea06cd12c86dcc3adefbf1a9e9a9b6646c7599ec631b0da9a60debeb9b3e19324977f3b4f36892c8a38671c8e1cc8e50fcd50f9e51deaf98272f9266fc702e4e57c30 a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 80f5dd050b1d5b8de24fedfb262703436e93020b4d486bf2f4c7800591cd2f71e6c09242c928c3c37ed713d17b0c6911 +dc66e39f9bbfd9865318531ffe9207f934fa615a5b285708a5e9c46b7775150e818d7f24d2a123df3672fff2094e3fd3df6fbe259e3989dd5edfcccbe7d45e26a775a5c4329a084f057c42c13f3248e3fd6f0c76678f890f513c32292dd306eaa84a59abe34b16cb5e38d0e885525d10336ca443e1682aa04a7af832b0eee4e7 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d 9573df73440078a44a70dbcbc8782aef2654c148cd18010d42648b856be6050bc44cfd795c95b38094abcb129cee84bb +600974e7d8c5508e2c1aab0783ad0d7c4494ab2b4da265c2fe496421c4df238b0be25f25659157c8a225fb03953607f7df996acfd402f147e37aee2f1693e3bf1c35eab3ae360a2bd91d04622ea47f83d863d2dfecb618e8b8bdc39e17d15d672eee03bb4ce2cc5cf6b217e5faf3f336fdd87d972d3a8b8a593ba85955cc9d71 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d b66aa2884fdc5edb2139f4338a7f94b722aff90fbf52a119dcf3e15241511a1bf726bf6b8eefdd879f534e2bf1a56ba6 +dfa6cb9b39adda6c74cc8b2a8b53a12c499ab9dee01b4123642b4f11af336a91a5c9ce0520eb2395a6190ecbf6169c4cba81941de8e76c9c908eb843b98ce95e0da29c5d4388040264e05e07030a577cc5d176387154eabae2af52a83e85c61c7c61da930c9b19e45d7e34c8516dc3c238fddd6e450a77455d534c48a152010b 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab a9eaed98bf2e22f473c862a8deb49f6cbb41c4effaaeed0bded6819d438bac3d5cc046f62322254ccfa2d603d72d04db +51d2547cbff92431174aa7fc7302139519d98071c755ff1c92e4694b58587ea560f72f32fc6dd4dee7d22bb7387381d0256e2862d0644cdf2c277c5d740fa089830eb52bf79d1e75b8596ecf0ea58a0b9df61e0c9754bfcd62efab6ea1bd216bf181c5593da79f10135a9bc6e164f1854bc8859734341aad237ba29a81a3fc8b 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a ab1222adb19dcfd47d363bd9e13f8467492157fad744d95bd08d97cf09670d83523002981554c6de043fefded661cfa6 +558c2ac13026402bad4a0a83ebc9468e50f7ffab06d6f981e5db1d082098065bcff6f21a7a74558b1e8612914b8b5a0aa28ed5b574c36ac4ea5868432a62bb8ef0695d27c1e3ceaf75c7b251c65ddb268696f07c16d2767973d85beb443f211e6445e7fe5d46f0dce70d58a4cd9fe70688c035688ea8c6baec65a5fc7e2c93e8 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 b2c4b320254966e2b6e3719f2d42789f80b8dea5be1354da41ee4e392be804a8e556dc69137c0edf7f043db867ab8df8 +4d55c99ef6bd54621662c3d110c3cb627c03d6311393b264ab97b90a4b15214a5593ba2510a53d63fb34be251facb697c973e11b665cb7920f1684b0031b4dd370cb927ca7168b0bf8ad285e05e9e31e34bc24024739fdc10b78586f29eff94412034e3b606ed850ec2c1900e8e68151fc4aee5adebb066eb6da4eaa5681378e f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 a3c74f2a2857c3adb254b1fe3adc3896d8f8808ee5e6cc3a88098880b330812e52ac11a0f005aa0fa2bdd380ae7bddd7 +f8248ad47d97c18c984f1f5c10950dc1404713c56b6ea397e01e6dd925e903b4fadfe2c9e877169e71ce3c7fe5ce70ee4255d9cdc26f6943bf48687874de64f6cf30a012512e787b88059bbf561162bdcc23a3742c835ac144cc14167b1bd6727e940540a9c99f3cbb41fb1dcb00d76dda04995847c657f4c19d303eb09eb48a b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 b2be36b6fe0b5bff1213f94f0091c25fe94d0648a8312e82043aa873020d9d076544d8fb52ae2b7078a523426a5b68f9 +3b6ee2425940b3d240d35b97b6dcd61ed3423d8e71a0ada35d47b322d17b35ea0472f35edd1d252f87b8b65ef4b716669fc9ac28b00d34a9d66ad118c9d94e7f46d0b4f6c2b2d339fd6bcd351241a387cc82609057048c12c4ec3d85c661975c45b300cb96930d89370a327c98b67defaa89497aa8ef994c77f1130f752f94a4 d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 897b7db762b061fa0190f64c16154ebb5827232eef5ac7a8e0ca3cce082a3d578586cc95087dd12c43e2ba31d0f9ab65 +c5204b81ec0a4df5b7e9fda3dc245f98082ae7f4efe81998dcaa286bd4507ca840a53d21b01e904f55e38f78c3757d5a5a4a44b1d5d4e480be3afb5b394a5d2840af42b1b4083d40afbfe22d702f370d32dbfd392e128ea4724d66a3701da41ae2f03bb4d91bb946c7969404cb544f71eb7a49eb4c4ec55799bda1eb545143a7 b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c 83610dfaf9f41fdbb38e0f6ed3502a61c60d012968f9d69bbeca599d7e013315e60dd0bef2be5d9c73ae7ebd8fef08a9 +72e81fe221fb402148d8b7ab03549f1180bcc03d41ca59d7653801f0ba853add1f6d29edd7f9abc621b2d548f8dbf8979bd16608d2d8fc3260b4ebc0dd42482481d548c7075711b5759649c41f439fad69954956c9326841ea6492956829f9e0dc789f73633b40f6ac77bcae6dfc7930cfe89e526d1684365c5b0be2437fdb01 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 996476551ef9e944f3b1b436e7d5dc47e5ea67225d3c1d487b42d5ae17089d636796f52008945c1327d4366bc7b49c9a +21188c3edd5de088dacc1076b9e1bcecd79de1003c2414c3866173054dc82dde85169baa77993adb20c269f60a5226111828578bcc7c29e6e8d2dae81806152c8ba0c6ada1986a1983ebeec1473a73a04795b6319d48662d40881c1723a706f516fe75300f92408aa1dc6ae4288d2046f23c1aa2e54b7fb6448a0da922bd7f34 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 84b5fb5b9c06309491c3bba54b8fd5d523fff70308e41b53f6ab1f3a1da2b3973780bfb80e5323fd3a11eff41dff3e1c +e0b8596b375f3306bbc6e77a0b42f7469d7e83635990e74aa6d713594a3a24498feff5006790742d9c2e9b47d714bee932435db747c6e733e3d8de41f2f91311f2e9fd8e025651631ffd84f66732d3473fbd1627e63dc7194048ebec93c95c159b5039ab5e79e42c80b484a943f125de3da1e04e5bf9c16671ad55a1117d3306 b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced b3671d3bc6790b5709c7ddf8bc7bdec6b198e8c6ce5bec69b5c8159cbd778ca7346ad40db9ad3f8e198bb2edabd8c880 +099a0131179fff4c6928e49886d2fdb3a9f239b7dd5fa828a52cbbe3fcfabecfbba3e192159b887b5d13aa1e14e6a07ccbb21f6ad8b7e88fee6bea9b86dea40ffb962f38554056fb7c5bb486418915f7e7e9b9033fe3baaf9a069db98bc02fa8af3d3d1859a11375d6f98aa2ce632606d0800dff7f55b40f971a8586ed6b39e9 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181 a8819e67d84be520723395a412238225c91a73197b47d85eac124cbc4aa3b3ab8adeea7f477b669f9bc46f7b8cdfbc2e +0fbc07ea947c946bea26afa10c51511039b94ddbc4e2e4184ca3559260da24a14522d1497ca5e77a5d1a8e86583aeea1f5d4ff9b04a6aa0de79cd88fdb85e01f171143535f2f7c23b050289d7e05cebccdd131888572534bae0061bdcc3015206b9270b0d5af9f1da2f9de91772d178a632c3261a1e7b3fb255608b3801962f9 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431 a6928810ac7020722f4d37330386a90cbb1ef46908c53f7d36b499a8cea0e6f63fa9b63904dba78891a3b82cfba57a37 +1e38d750d936d8522e9db1873fb4996bef97f8da3c6674a1223d29263f1234a90b751785316444e9ba698bc8ab6cd010638d182c9adad4e334b2bd7529f0ae8e9a52ad60f59804b2d780ed52bdd33b0bf5400147c28b4304e5e3434505ae7ce30d4b239e7e6f0ecf058badd5b388eddbad64d24d2430dd04b4ddee98f972988f 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd aaefbf183af167d2a28956247fe1b2b34576b0d3149a248691ccb4a8c27afbaca7ab535d3948e7da79d5a65b7b2b62b3 +abcf0e0f046b2e0672d1cc6c0a114905627cbbdefdf9752f0c31660aa95f2d0ede72d17919a9e9b1add3213164e0c9b5ae3c76f1a2f79d3eeb444e6741521019d8bd5ca391b28c1063347f07afcfbb705be4b52261c19ebaf1d6f054a74d86fb5d091fa7f229450996b76f0ada5f977b09b58488eebfb5f5e9539a8fd89662ab 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de b68fea5f4d2c3436a67f4c579f6c1db5de691457014d9944a408e92041c5da2b3fd05786938f9c7521f5617b794f13f7 +dc3d4884c741a4a687593c79fb4e35c5c13c781dca16db561d7e393577f7b62ca41a6e259fc1fb8d0c4e1e062517a0fdf95558b7799f20c211796167953e6372c11829beec64869d67bf3ee1f1455dd87acfbdbcc597056e7fb347a17688ad32fda7ccc3572da7677d7255c261738f07763cd45973c728c6e9adbeecadc3d961 ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566 a5dc831f090a2927c97791b78837237b59ce825165733467598775a8296095a96a07077045afc918ee3a8c199399c1a8 +719bf1911ae5b5e08f1d97b92a5089c0ab9d6f1c175ac7199086aeeaa416a17e6d6f8486c711d386f284f096296689a54d330c8efb0f5fa1c5ba128d3234a3da856c2a94667ef7103616a64c913135f4e1dc50e38daa60610f732ad1bedfcc396f87169392520314a6b6b9af6793dbabad4599525228cc7c9c32c4d8e097ddf6 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee b31a0d318a06ab3a25485d7cf7893e208f6bfde3c6b8461a2cb77c76e919af4c809f6c21e127622f1b7bc8e6bf2faace +7cf19f4c851e97c5bca11a39f0074c3b7bd3274e7dd75d0447b7b84995dfc9f716bf08c25347f56fcc5e5149cb3f9cfb39d408ace5a5c47e75f7a827fa0bb9921bb5b23a6053dbe1fa2bba341ac874d9b1333fc4dc224854949f5c8d8a5fedd02fb26fdfcd3be351aec0fcbef18972956c6ec0effaf057eb4420b6d28e0c008c 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd 8adcabaec61af828f2485f39195c3c60df755a7917c1be5dee7a00793431af0e432d24fdc3950c1e426d099c21c4cca6 +b892ffabb809e98a99b0a79895445fc734fa1b6159f9cddb6d21e510708bdab6076633ac30aaef43db566c0d21f4381db46711fe3812c5ce0fb4a40e3d5d8ab24e4e82d3560c6dc7c37794ee17d4a144065ef99c8d1c88bc22ad8c4c27d85ad518fa5747ae35276fc104829d3f5c72fc2a9ea55a1c3a87007cd133263f79e405 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666 97b4346e1d8fb129ea7bc2b9da0e503dee48da7879cebb9bbed2fabe9be5dd1ed39565b4a82f2903674034fd8d867520 +8144e37014c95e13231cbd6fa64772771f93b44e37f7b02f592099cc146343edd4f4ec9fa1bc68d7f2e9ee78fc370443aa2803ff4ca52ee49a2f4daf2c8181ea7b8475b3a0f608fc3279d09e2d057fbe3f2ffbe5133796124781299c6da60cfe7ecea3abc30706ded2cdf18f9d788e59f2c31662df3abe01a9b12304fb8d5c8c bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67 84f48b7fe306ee282b51fa296f1342aef8e9cd9eb26aee42b0e1920919d07411c6cfc9a94aeff062ebb7adc2ff77fb4a +a3683d120807f0a030feed679785326698c3702f1983eaba1b70ddfa7f0b3188060b845e2b67ed57ee68087746710450f7427cb34655d719c0acbc09ac696adb4b22aba1b9322b7111076e67053a55f62b501a4bca0ad9d50a868f51aeeb4ef27823236f5267e8da83e143047422ce140d66e05e44dc84fb3a4506b2a5d7caa8 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9 a6771698dece73bb09987158dddb8d5525a5c9841c1b5caa1432548831cf3d999e4fac32866e21c878a7f001a733e8b5 +b1df8051b213fc5f636537e37e212eb20b2423e6467a9c7081336a870e6373fc835899d59e546c0ac668cc81ce4921e88f42e6da2a109a03b4f4e819a17c955b8d099ec6b282fb495258dca13ec779c459da909475519a3477223c06b99afbd77f9922e7cbef844b93f3ce5f50db816b2e0d8b1575d2e17a6b8db9111d6da578 f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce 96afbb6ae40c587a9baf2f56b29c711384943ddd8ce67d3e67266257faf1076c89de151221edb7bb72451a8c4bab2d16 +0b918ede985b5c491797d0a81446b2933be312f419b212e3aae9ba5914c00af431747a9d287a7c7761e9bcbc8a12aaf9d4a76d13dad59fc742f8f218ef66eb67035220a07acc1a357c5b562ecb6b895cf725c4230412fefac72097f2c2b829ed58742d7c327cad0f1058df1bddd4ae9c6d2aba25480424308684cecd6517cdd8 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f b216a0b591410449c000f518577173a37089918483bd443d5a47f8fc291a1796304aa43b70cdef236d690d17b6db4c3b +0fab26fde1a4467ca930dbe513ccc3452b70313cccde2994eead2fde85c8da1db84d7d06a024c9e88629d5344224a4eae01b21a2665d5f7f36d5524bf5367d7f8b6a71ea05d413d4afde33777f0a3be49c9e6aa29ea447746a9e77ce27232a550b31dd4e7c9bc8913485f2dc83a56298051c92461fd46b14cc895c300a4fb874 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b a9079836141734c7c0eca9279a38e65fcb2058d08545a643591ec0fcbb31a4824d02560cfad65294377d3fa587a1ee0d +7843f157ef8566722a7d69da67de7599ee65cb3975508f70c612b3289190e364141781e0b832f2d9627122742f4b5871ceeafcd09ba5ec90cae6bcc01ae32b50f13f63918dfb5177df9797c6273b92d103c3f7a3fc2050d2b196cc872c57b77f9bdb1782d4195445fcc6236dd8bd14c8bcbc8223a6739f6a17c9a861e8c821a6 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388 8469f36f83877eac01d0980bbb7b3eb6d203142a2ba6e7adb28132665f74364db75a2cfbba9b1e17a6b855b658d8688e +6c8572b6a3a4a9e8e03dbeed99334d41661b8a8417074f335ab1845f6cc852adb8c01d9820fcf8e10699cc827a8fbdca2cbd46cc66e4e6b7ba41ec3efa733587e4a30ec552cd8ddab8163e148e50f4d090782897f3ddac84a41e1fcfe8c56b6152c0097b0d634b41011471ffd004f43eb4aafc038197ec6bae2b4470e869bded 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499 ab7d73037e81a08dec97ad63644c3a155a3a9d91a0d051fbe87c5911b85cc488086482c8a81aebc58e5f7c71f7757959 +7e3c8fe162d48cc8c5b11b5e5ebc05ebc45c439bdbc0b0902145921b8383037cb0812222031598cd1a56fa71694fbd304cc62938233465ec39c6e49f57dfe823983b6923c4e865633949183e6b90e9e06d8275f3907d97967d47b6239fe2847b7d49cf16ba69d2862083cf1bccf7afe34fdc90e21998964107b64abe6b89d126 f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6 894c13598eb18c9b3aed2b86455277b6263f88dcec983f75d2d5975780ad53c1392d6a936c21f01aaee8c36fe7ac5fb4 +d5aa8ac9218ca661cd177756af6fbb5a40a3fecfd4eea6d5872fbb9a2884784aa9b5f0c023a6e0da5cf6364754ee6465b4ee2d0ddc745b02994c98427a213c849537da5a4477b3abfe02648be67f26e80b56a33150490d062aaac137aa47f11cfeddba855bab9e4e028532a563326d927f9e6e3292b1fb248ee90b6f429798db 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead 800bb1d8643b4279902995548a17f0a131e873b40ca62af31c661066b1378301d06d718f8b3a418ebe2780b14e43c596 +790b06054afc9c3fc4dfe72df19dd5d68d108cfcfca6212804f6d534fd2fbe489bd8f64bf205ce04bcb50124a12ce5238fc3fe7dd76e6fa640206af52549f133d593a1bfd423ab737f3326fa79433cde293236f90d4238f0dd38ed69492ddbd9c3eae583b6325a95dec3166fe52b21658293d8c137830ef45297d67813b7a508 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd a5e803df14ec655d8bfadb6479c8f40e6973bed4da79ccfd7595e4c4bd9ec8205f1083c6f5342fe4282f69dffd2f4d48 +6d549aa87afdb8bfa60d22a68e2783b27e8db46041e4df04be0c261c4734b608a96f198d1cdb8d082ae48579ec9defcf21fbc72803764a58c31e5323d5452b9fb57c8991d31749140da7ef067b18bf0d7dfbae6eefd0d8064f334bf7e9ec1e028daed4e86e17635ec2e409a3ed1238048a45882c5c57501b314e636b9bc81cbe 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117 a7e438c2ae4b2b8d945cba723870a1b8952b9547785086705129a3890308e8e9e58d3fec6fb296243cadee50f9e6a812 +1906e48b7f889ee3ff7ab0807a7aa88f53f4018808870bfed6372a77330c737647961324c2b4d46f6ee8b01190474951a701b048ae86579ff8e3fc889fecf926b17f98958ac7534e6e781ca2db2baa380dec766cfb2a3eca2a9d5818967d64dfab84f768d24ec122eebacaab0a4dc3a75f37331bb1c43dd8966cc09ec4945bbd 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61 b80fb1498644d46082d3c1e9a5bb65d8f2c76d6c39d72252cf0acd059ae7c0adc7a5a684fdc53f2af2aa3d6b0835c3f9 +7b59fef13daf01afec35dea3276541be681c4916767f34d4e874464d20979863ee77ad0fd1635bcdf93e9f62ed69ae52ec90aab5bbf87f8951213747ccec9f38c775c1df1e9d7f735c2ce39b42edb3b0c5086247556cfea539995c5d9689765288ec600848ecf085c01ca738bbef11f5d12d4457db988b4add90be00781024ad 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2 85df3c423d18eb45e74627fe7768eabd6520e89e84e8f490a37e873fbf494df8762e91a73b6bedc1c0cfd9018bb36472 +041a6767a935dc3d8985eb4e608b0cbfebe7f93789d4200bcfe595277ac2b0f402889b580b72def5da778a680fd380c955421f626d52dd9a83ea180187b850e1b72a4ec6dd63235e598fd15a9b19f8ce9aec1d23f0bd6ea4d92360d50f951152bc9a01354732ba0cf90aaed33c307c1de8fa3d14f9489151b8377b57c7215f0b 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7 93134141153d4ec8c6f7d936cb307be26805f8d6fc7af3c0037b08ba293f31fd582c88f371e9a2e194f5403fe9a86a15 +7905a9036e022c78b2c9efd40b77b0a194fbc1d45462779b0b76ad30dc52c564e48a493d8249a061e62f26f453ba566538a4d43c64fb9fdbd1f36409316433c6f074e1b47b544a847de25fc67d81ac801ed9f7371a43da39001c90766f943e629d74d0436ba1240c3d7fab990d586a6d6ef1771786722df56448815f2feda48f 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870 a59f8c12daa4285ca9da0e65a7ee09d7fb7f761cb3e2c8a5fa1fd27f2124b79ec47ce59ee3ee2dbc94d8cfb1925cb32c +cf25e4642d4f39d15afb7aec79469d82fc9aedb8f89964e79b749a852d931d37436502804e39555f5a3c75dd958fd5291ada647c1a5e38fe7b1048f16f2b711fdd5d39acc0812ca65bd50d7f8119f2fd195ab16633503a78ee9102c1f9c4c22568e0b54bd4fa3f5ff7b49160bf23e7e2231b1ebebbdaf0e4a7d4484158a87e07 e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf b9c620ccad4b1c893b5a371dadaacdd357961f53da5fb0c71295218581e8fde7bfa2cddfa3104a82f32e6ac029d814c6 +7562c445b35883cc937be6349b4cefc3556a80255d70f09e28c3f393daac19442a7eecedcdfbe8f7628e30cd8939537ec56d5c9645d43340eb4e78fc5dd4322de8a07966b262770d7ff13a071ff3dce560718e60ed3086b7e0003a6abafe91af90af86733ce8689440bf73d2aa0acfe9776036e877599acbabfcb03bb3b50faa 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c 84ad4229ed854ab713818285bff897b8c4112e697d490be18191e34c12f494fc511edf70db58424c2c28e2132da0ac7a +051c2db8e71e44653ea1cb0afc9e0abdf12658e9e761bfb767c20c7ab4adfcb18ed9b5c372a3ac11d8a43c55f7f99b33355437891686d42362abd71db8b6d84dd694d6982f0612178a937aa934b9ac3c0794c39027bdd767841c4370666c80dbc0f8132ca27474f553d266deefd7c9dbad6d734f9006bb557567701bb7e6a7c9 f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9 ad18a239a701c3f010f063a24afd0c9c7af20bda52e380dd797998c8e66e53de51e861f5429b19eb4554e4fd83168a6c +4dcb7b62ba31b866fce7c1feedf0be1f67bf611dbc2e2e86f004422f67b3bc1839c6958eb1dc3ead137c3d7f88aa97244577a775c8021b1642a8647bba82871e3c15d0749ed343ea6cad38f123835d8ef66b0719273105e924e8685b65fd5dc430efbc35b05a6097f17ebc5943cdcd9abcba752b7f8f37027409bd6e11cd158f f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5 98492a07aafd5cabc015ab0c87edf709cfbfca78e97e0672c4ee444ed800cc8cc4f112300b5f3491b23429b7bb54cb48 +efe55737771070d5ac79236b04e3fbaf4f2e9bed187d1930680fcf1aba769674bf426310f21245006f528779347d28b8aeacd2b1d5e3456dcbf188b2be8c07f19219e4067c1e7c9714784285d8bac79a76b56f2e2676ea93994f11eb573af1d03fc8ed1118eafc7f07a82f3263c33eb85e497e18f435d4076a774f42d276c323 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628 937801a93e18ccdb8c61b55b6515cd15054664419c11dc5a9d8e078ac3933e38b705b8df61378d5bb117f4738be2233e +ea95859cc13cccb37198d919803be89c2ee10befdcaf5d5afa09dcc529d333ae1e4ffd3bd8ba8642203badd7a80a3f77eeee9402eed365d53f05c1a995c536f8236ba6b6ff8897393506660cc8ea82b2163aa6a1855251c87d935e23857fe35b889427b449de7274d7754bdeace960b4303c5dd5f745a5cfd580293d6548c832 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49 a42fbf8cf98710ccfe7acf76099b474c2c809386ad047a9388f807f1ba7522e522a1f78194e224a1e299fe7347eece3e diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P256_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P256_blst new file mode 100644 index 000000000000..fc7e4356eaeb --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P256_blst @@ -0,0 +1,60 @@ +ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590 b858c053d81e961d218af0ae99fc772c413f3b51e4951d7a4d444712546fdae35e3a0b8caad95caf6ce0492e5b0293ee +9155e91fd9155eeed15afd83487ea1a3af04c5998b77c0fe8c43dcc479440a8a9a89efe883d9385cb9edfde10b43bce61fb63669935ad39419cf29ef3a936931733bfc2378e253e73b7ae9a3ec7a6a7932ab10f1e5b94d05160c053988f3bdc9167155d069337d42c9a7056619efc031fa5ec7310d29bd28980b1e3559757578 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98 aa6bea87ebe6a3f5d3ad1c85cb0ff3fca0d0a68a893c0eec9494f4a51c50a9b469331ef7751ca0d4c6f300a1d22edfdf +b242a7586a1383368a33c88264889adfa3be45422fbef4a2df4e3c5325a9c7757017e0d5cf4bbf4de7f99d189f81f1fd2f0dd645574d1eb0d547eead9375677819297c1abe62526ae29fc54cdd11bfe17714f2fbd2d0d0e8d297ff98535980482dd5c1ebdc5a7274aabf1382c9f2315ca61391e3943856e4c5e616c2f1f7be0d a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870 b79be260c5f3dfc078e177e18099b5190af2a5d6c18e8cba33c6470aa6d369cc3c746fdf0d2464eaade038346442be56 +b64005da76b24715880af94dba379acc25a047b06066c9bedc8f17b8c74e74f4fc720d9f4ef0e2a659e0756931c080587ebdcd0f85e819aea6dacb327a9d96496da53ea21aef3b2e793a9c0def5196acec99891f46ead78a85bc7ab644765781d3543da9fbf9fec916dca975ef3b4271e50ecc68bf79b2d8935e2b25fc063358 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f a927929feaad46833020384f4c9b045527aa0eb1efe1d5636bad04ca9a891f9045a51a3b6027a0f8257e608c223b343e +fe6e1ea477640655eaa1f6e3352d4bce53eb3d95424df7f238e93d8531da8f36bc35fa6be4bf5a6a382e06e855139eb617a9cc9376b4dafacbd80876343b12628619d7cbe1bff6757e3706111ed53898c0219823adbc044eaf8c6ad449df8f6aab9d444dadb5c3380eec0d91694df5fc4b30280d4b87d27e67ae58a1df828963 daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d 95526b2adeff6070a84886299bc00aead55848dae7dfc669ccd29554e1ac727bcc4ef1a224d312f740dac44139581532 +907c0c00dc080a688548957b5b8b1f33ba378de1368023dcad43242411f554eb7d392d3e5c1668fad3944ff9634105343d83b8c85d2a988da5f5dc60ee0518327caed6dd5cf4e9bc6222deb46d00abde745f9b71d6e7aee6c7fdfc9ed053f2c0b611d4c6863088bd012ea9810ee94f8e58905970ebd07353f1f409a371ed03e3 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5 ab1231ee920b61527420eeb759f091680190758373b64c787fb71180dc706d264e81461d266f61d6e28dc71decc4cf20 +771c4d7bce05610a3e71b272096b57f0d1efcce33a1cb4f714d6ebc0865b2773ec5eedc25fae81dee1d256474dbd9676623614c150916e6ed92ce4430b26037d28fa5252ef6b10c09dc2f7ee5a36a1ea7897b69f389d9f5075e271d92f4eb97b148f3abcb1e5be0b4feb8278613d18abf6da60bfe448238aa04d7f11b71f44c5 f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96 aa8908d7c8a7418a7f716a0b2053307fe8d627cfa0ecbaeb4510e335e0647117fbdfb1093833ee29b4aa0cb11165fe19 +a3b2825235718fc679b942e8ac38fb4f54415a213c65875b5453d18ca012320ddfbbc58b991eaebadfc2d1a28d4f0cd82652b12e4d5bfda89eda3be12ac52188e38e8cce32a264a300c0e463631f525ae501348594f980392c76b4a12ddc88e5ca086cb8685d03895919a8627725a3e00c4728e2b7c6f6a14fc342b2937fc3dd 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d a48dc97d7473d2e12c12a2d24954628d136fa51d6760a48b35af7296ef5ca685b47229e15898c6c16b04b6c50e25c96f +3e6e2a9bffd729ee5d4807849cd4250021d8184cda723df6ab0e5c939d39237c8e58af9d869fe62d3c97b3298a99e891e5e11aa68b11a087573a40a3e83c7965e7910d72f81cad0f42accc5c25a4fd3cdd8cee63757bbbfbdae98be2bc867d3bcb1333c4632cb0a55dffeb77d8b119c466cd889ec468454fabe6fbee7102deaf 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9 b596b191278aca9bc110479c2811086e712b49cd0b6c53cacfa73c89eb3b786ca0f792e542ad3373d7733f81bd330009 +52e5c308e70329a17c71eaedb66bbee303c8ec48a6f1a2efb235d308563cd58553d434e12f353227a9ea28608ec9c820ed83c95124e7a886f7e832a2de1032e78dc059208f9ec354170b2b1cab992b52ac01e6c0e4e1b0112686962edc53ab226dafcc9fc7baed2cd9307160e8572edb125935db49289b178f35a8ad23f4f801 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634 9612c9a1d955b247925d0fbd6f2f31d9ac138d6ce79ca6c758c7c092cc74b1e7950c68d3cd4ae64f494b788fefd3f7c9 +d3e9e82051d4c84d699453c9ff44c7c09f6523bb92232bcf30bf3c380224249de2964e871d56a364d6955c81ef91d06482a6c7c61bc70f66ef22fad128d15416e7174312619134f968f1009f92cbf99248932efb533ff113fb6d949e21d6b80dfbbe69010c8d1ccb0f3808ea309bb0bac1a222168c95b088847e613749b19d04 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27 a134a5b84aced4661a1cb86c1b5ac95831d05c39335f8d40c03019c6ed14f728ca2c398cf23808d33e3cc29418be13b7 +968951c2c1918436fe19fa2fe2152656a08f9a6b8aa6201920f1b424da98cee71928897ff087620cc5c551320b1e75a1e98d7d98a5bd5361c9393759614a6087cc0f7fb01fcb173783eb4c4c23961a8231ac4a07d72e683b0c1bd4c51ef1b031df875e7b8d5a6e0628949f5b8f157f43dccaea3b2a4fc11181e6b451e06ceb37 cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d a883d1b5fac0396fc39d4686276572e32cf0f22b98021ae0dd8233566580cd133ec067d8ea05ca351c2630c06517ec1b +78048628932e1c1cdd1e70932bd7b76f704ba08d7e7d825d3de763bf1a062315f4af16eccefe0b6ebadccaf403d013f50833ce2c54e24eea8345e25f93b69bb048988d102240225ceacf5003e2abdcc90299f4bf2c101585d36ecdd7a155953c674789d070480d1ef47cc7858e97a6d87c41c6922a00ea12539f251826e141b4 b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c 8fba22fb7485c06cdb4f237abc909392ac4b2de35c5d761d2233575446fbaa4fee626d1387b6d07f358fa1e2712b9f16 +9b0800c443e693067591737fdbcf0966fdfa50872d41d0c189d87cbc34c2771ee5e1255fd604f09fcf167fda16437c245d299147299c69046895d22482db29aba37ff57f756716cd3d6223077f747c4caffbecc0a7c9dfaaafd9a9817470ded8777e6355838ac54d11b2f0fc3f43668ff949cc31de0c2d15af5ef17884e4d66a 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48 aa6149681711284f00020023594bf8c751116ab55c87c1039119654871b58acb3ef30e77f36ea1e5c45aba05248e5226 +fc3b8291c172dae635a6859f525beaf01cf683765d7c86f1a4d768df7cae055f639eccc08d7a0272394d949f82d5e12d69c08e2483e11a1d28a4c61f18193106e12e5de4a9d0b4bf341e2acd6b715dc83ae5ff63328f8346f35521ca378b311299947f63ec593a5e32e6bd11ec4edb0e75302a9f54d21226d23314729e061016 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f 92c284fa3e8888b11f6a0161c98b9130a3740e72e0d5b2ef864fc08c80aed8a697cdb12a4f2e2d5ee3cd28938cf383a6 +5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 b643ea2b8e6f42d2707a477b46d63958e96b5163c9fd974bb6200ae34536497cc339d222caf039fe69ffaf648485e955 +c35e2f092553c55772926bdbe87c9796827d17024dbb9233a545366e2e5987dd344deb72df987144b8c6c43bc41b654b94cc856e16b96d7a821c8ec039b503e3d86728c494a967d83011a0e090b5d54cd47f4e366c0912bc808fbb2ea96efac88fb3ebec9342738e225f7c7c2b011ce375b56621a20642b4d36e060db4524af1 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 98883229c07317b0738314dd81c43fef8e68173d613b07979fffce652e0ae733d5f6e81a18166ae75385c360736a54a2 +3c054e333a94259c36af09ab5b4ff9beb3492f8d5b4282d16801daccb29f70fe61a0b37ffef5c04cd1b70e85b1f549a1c4dc672985e50f43ea037efa9964f096b5f62f7ffdf8d6bfb2cc859558f5a393cb949dbd48f269343b5263dcdb9c556eca074f2e98e6d94c2c29a677afaf806edf79b15a3fcd46e7067b7669f83188ee e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef b8218f3b74c867ea03e3c784d864b987b5138fe66cc2ae0a98e175736b344542924169e46aecdd9e0ea2a5b645143e20 +0989122410d522af64ceb07da2c865219046b4c3d9d99b01278c07ff63eaf1039cb787ae9e2dd46436cc0415f280c562bebb83a23e639e476a02ec8cff7ea06cd12c86dcc3adefbf1a9e9a9b6646c7599ec631b0da9a60debeb9b3e19324977f3b4f36892c8a38671c8e1cc8e50fcd50f9e51deaf98272f9266fc702e4e57c30 a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 8ef4299fa93aee6d4e24a23792c4f3a809238974d853e9e88bb2ec12818b2dd0e536961dc99e84d545f4dcc4c0bf14ad +dc66e39f9bbfd9865318531ffe9207f934fa615a5b285708a5e9c46b7775150e818d7f24d2a123df3672fff2094e3fd3df6fbe259e3989dd5edfcccbe7d45e26a775a5c4329a084f057c42c13f3248e3fd6f0c76678f890f513c32292dd306eaa84a59abe34b16cb5e38d0e885525d10336ca443e1682aa04a7af832b0eee4e7 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d b09a5b57b958344ae6a1f620a0f333056ba67959c75f057f0b0ae448e20c8ad17957f296822e9f0708a80f88c52a3e57 +600974e7d8c5508e2c1aab0783ad0d7c4494ab2b4da265c2fe496421c4df238b0be25f25659157c8a225fb03953607f7df996acfd402f147e37aee2f1693e3bf1c35eab3ae360a2bd91d04622ea47f83d863d2dfecb618e8b8bdc39e17d15d672eee03bb4ce2cc5cf6b217e5faf3f336fdd87d972d3a8b8a593ba85955cc9d71 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d a2113ccf5ca243ffeaee5f818368a72cfc3e97e366d50021e1718c4d5b252a676cbec8db12711b5cbff6ff7dd9992c89 +dfa6cb9b39adda6c74cc8b2a8b53a12c499ab9dee01b4123642b4f11af336a91a5c9ce0520eb2395a6190ecbf6169c4cba81941de8e76c9c908eb843b98ce95e0da29c5d4388040264e05e07030a577cc5d176387154eabae2af52a83e85c61c7c61da930c9b19e45d7e34c8516dc3c238fddd6e450a77455d534c48a152010b 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab ac98349eda176ca189e8403cee0525b01862843143c45178d6fbd6b3d3a2684f67ca70956028280866bc69c95a188ece +51d2547cbff92431174aa7fc7302139519d98071c755ff1c92e4694b58587ea560f72f32fc6dd4dee7d22bb7387381d0256e2862d0644cdf2c277c5d740fa089830eb52bf79d1e75b8596ecf0ea58a0b9df61e0c9754bfcd62efab6ea1bd216bf181c5593da79f10135a9bc6e164f1854bc8859734341aad237ba29a81a3fc8b 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a af8fb52998c5bd19d2739d3ec61439bfa17e1664fb185d10d917e52f132dcdc9373136e7f5f74b4b5a1e474a9eb2b1eb +558c2ac13026402bad4a0a83ebc9468e50f7ffab06d6f981e5db1d082098065bcff6f21a7a74558b1e8612914b8b5a0aa28ed5b574c36ac4ea5868432a62bb8ef0695d27c1e3ceaf75c7b251c65ddb268696f07c16d2767973d85beb443f211e6445e7fe5d46f0dce70d58a4cd9fe70688c035688ea8c6baec65a5fc7e2c93e8 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 818e1d53ae3c322874f585d97813f16a8788f4b435006d17f375d0bd729db3dfa547c094e1b6772e1490433b5d832983 +4d55c99ef6bd54621662c3d110c3cb627c03d6311393b264ab97b90a4b15214a5593ba2510a53d63fb34be251facb697c973e11b665cb7920f1684b0031b4dd370cb927ca7168b0bf8ad285e05e9e31e34bc24024739fdc10b78586f29eff94412034e3b606ed850ec2c1900e8e68151fc4aee5adebb066eb6da4eaa5681378e f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 80b48677747abc211fdef413efa930c71fb95b9a14e51ed245092c9c2b5c4438579e12131e5775208aca92b09191ed74 +f8248ad47d97c18c984f1f5c10950dc1404713c56b6ea397e01e6dd925e903b4fadfe2c9e877169e71ce3c7fe5ce70ee4255d9cdc26f6943bf48687874de64f6cf30a012512e787b88059bbf561162bdcc23a3742c835ac144cc14167b1bd6727e940540a9c99f3cbb41fb1dcb00d76dda04995847c657f4c19d303eb09eb48a b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 87644f8e6bee84aea725d7d9dee9e691fbc8958f3bf5beddf398defb9f19bd0a7120e042f86d2fcf5c373c83f275eac1 +3b6ee2425940b3d240d35b97b6dcd61ed3423d8e71a0ada35d47b322d17b35ea0472f35edd1d252f87b8b65ef4b716669fc9ac28b00d34a9d66ad118c9d94e7f46d0b4f6c2b2d339fd6bcd351241a387cc82609057048c12c4ec3d85c661975c45b300cb96930d89370a327c98b67defaa89497aa8ef994c77f1130f752f94a4 d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 8e252a4979986139d4c0465f0485a638902452f422e668bf256a9a097863bfdf2bb8e55dbc8b0fac67a003e0015f7248 +c5204b81ec0a4df5b7e9fda3dc245f98082ae7f4efe81998dcaa286bd4507ca840a53d21b01e904f55e38f78c3757d5a5a4a44b1d5d4e480be3afb5b394a5d2840af42b1b4083d40afbfe22d702f370d32dbfd392e128ea4724d66a3701da41ae2f03bb4d91bb946c7969404cb544f71eb7a49eb4c4ec55799bda1eb545143a7 b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c 8a3f3e726659926e19bb848b8ac3982da83c428ba3c08bf5d54578afb1947b05f16341679ae174778d5c13f7b3962ea4 +72e81fe221fb402148d8b7ab03549f1180bcc03d41ca59d7653801f0ba853add1f6d29edd7f9abc621b2d548f8dbf8979bd16608d2d8fc3260b4ebc0dd42482481d548c7075711b5759649c41f439fad69954956c9326841ea6492956829f9e0dc789f73633b40f6ac77bcae6dfc7930cfe89e526d1684365c5b0be2437fdb01 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 8074ecf825c398e2de6480c268703a1833a1320ac654a0af23819fd86990902e2f850f7e8de06af69ee3af8aa6a245d0 +21188c3edd5de088dacc1076b9e1bcecd79de1003c2414c3866173054dc82dde85169baa77993adb20c269f60a5226111828578bcc7c29e6e8d2dae81806152c8ba0c6ada1986a1983ebeec1473a73a04795b6319d48662d40881c1723a706f516fe75300f92408aa1dc6ae4288d2046f23c1aa2e54b7fb6448a0da922bd7f34 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 a6669eb331a35fa1c78fa36ef2255511e6edcc51ad40f9316ad079197b8a66adf4b54149686734145077982858ce6c8a +e0b8596b375f3306bbc6e77a0b42f7469d7e83635990e74aa6d713594a3a24498feff5006790742d9c2e9b47d714bee932435db747c6e733e3d8de41f2f91311f2e9fd8e025651631ffd84f66732d3473fbd1627e63dc7194048ebec93c95c159b5039ab5e79e42c80b484a943f125de3da1e04e5bf9c16671ad55a1117d3306 b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced 80ac9ab190bb09bb4a70af3ac4874e6c102b7d8a81709d796fbaa06a17798bbbd2563e17f78f0173bb570c76aa348ac6 +099a0131179fff4c6928e49886d2fdb3a9f239b7dd5fa828a52cbbe3fcfabecfbba3e192159b887b5d13aa1e14e6a07ccbb21f6ad8b7e88fee6bea9b86dea40ffb962f38554056fb7c5bb486418915f7e7e9b9033fe3baaf9a069db98bc02fa8af3d3d1859a11375d6f98aa2ce632606d0800dff7f55b40f971a8586ed6b39e9 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181 a81afea74d7c55fd1a7a31d0df76864786443819fa69c53c024beb3a9a3e9a69a4f68aaf62f3f0a2386beb6f5c392e5e +0fbc07ea947c946bea26afa10c51511039b94ddbc4e2e4184ca3559260da24a14522d1497ca5e77a5d1a8e86583aeea1f5d4ff9b04a6aa0de79cd88fdb85e01f171143535f2f7c23b050289d7e05cebccdd131888572534bae0061bdcc3015206b9270b0d5af9f1da2f9de91772d178a632c3261a1e7b3fb255608b3801962f9 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431 8a4f706dbb32920f43c14b264e323f5494a0d9f572dbbbd708f7c7652812d7ce7fcc4797787801f85f971fca1f093469 +1e38d750d936d8522e9db1873fb4996bef97f8da3c6674a1223d29263f1234a90b751785316444e9ba698bc8ab6cd010638d182c9adad4e334b2bd7529f0ae8e9a52ad60f59804b2d780ed52bdd33b0bf5400147c28b4304e5e3434505ae7ce30d4b239e7e6f0ecf058badd5b388eddbad64d24d2430dd04b4ddee98f972988f 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd a5eea2bc7178b1ba3f020a0878ec3ee3f6aa52de7d36c9d1a5c4c37cda0f936143aa1a055fe46c7cc9b9d41e52cc4f87 +abcf0e0f046b2e0672d1cc6c0a114905627cbbdefdf9752f0c31660aa95f2d0ede72d17919a9e9b1add3213164e0c9b5ae3c76f1a2f79d3eeb444e6741521019d8bd5ca391b28c1063347f07afcfbb705be4b52261c19ebaf1d6f054a74d86fb5d091fa7f229450996b76f0ada5f977b09b58488eebfb5f5e9539a8fd89662ab 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de b21bbd2949c72f67cc3e12cc1f5fedba702df255a375f30cdd93b43a56af2ab587c741a2ecdb5d7c5b052b600c3c3782 +dc3d4884c741a4a687593c79fb4e35c5c13c781dca16db561d7e393577f7b62ca41a6e259fc1fb8d0c4e1e062517a0fdf95558b7799f20c211796167953e6372c11829beec64869d67bf3ee1f1455dd87acfbdbcc597056e7fb347a17688ad32fda7ccc3572da7677d7255c261738f07763cd45973c728c6e9adbeecadc3d961 ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566 a230824341eca4efdfc56561fcfb97677a0fa6a1795bb312a3d5ca7178df533d699ec8001f0e59da6bb9404ec388b27d +719bf1911ae5b5e08f1d97b92a5089c0ab9d6f1c175ac7199086aeeaa416a17e6d6f8486c711d386f284f096296689a54d330c8efb0f5fa1c5ba128d3234a3da856c2a94667ef7103616a64c913135f4e1dc50e38daa60610f732ad1bedfcc396f87169392520314a6b6b9af6793dbabad4599525228cc7c9c32c4d8e097ddf6 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee 91de1320176eaa091f474783f7b3220c441c41a7fca587834e322c1826100f066306128cbf4a7a3c5b8d2cd1c51b703a +7cf19f4c851e97c5bca11a39f0074c3b7bd3274e7dd75d0447b7b84995dfc9f716bf08c25347f56fcc5e5149cb3f9cfb39d408ace5a5c47e75f7a827fa0bb9921bb5b23a6053dbe1fa2bba341ac874d9b1333fc4dc224854949f5c8d8a5fedd02fb26fdfcd3be351aec0fcbef18972956c6ec0effaf057eb4420b6d28e0c008c 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd 83599657411e5efe1a51ccd6b8f468a6e9d0834814bd07732ba7401761c6c97e7224e6bf248c28e49f7be8c841ceadcd +b892ffabb809e98a99b0a79895445fc734fa1b6159f9cddb6d21e510708bdab6076633ac30aaef43db566c0d21f4381db46711fe3812c5ce0fb4a40e3d5d8ab24e4e82d3560c6dc7c37794ee17d4a144065ef99c8d1c88bc22ad8c4c27d85ad518fa5747ae35276fc104829d3f5c72fc2a9ea55a1c3a87007cd133263f79e405 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666 86be12f7568c8534597d75f1d036f8f6dee9fddb7ca9ea825f891a01e5557537e92f751b7a8c843db8542e0738a8536c +8144e37014c95e13231cbd6fa64772771f93b44e37f7b02f592099cc146343edd4f4ec9fa1bc68d7f2e9ee78fc370443aa2803ff4ca52ee49a2f4daf2c8181ea7b8475b3a0f608fc3279d09e2d057fbe3f2ffbe5133796124781299c6da60cfe7ecea3abc30706ded2cdf18f9d788e59f2c31662df3abe01a9b12304fb8d5c8c bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67 88364cdf37213f797fe3cb16230acdc784b0e2736afc29b3e0987b8747e7808683d0f40a31c4bf03bc0a82efde6dbaca +a3683d120807f0a030feed679785326698c3702f1983eaba1b70ddfa7f0b3188060b845e2b67ed57ee68087746710450f7427cb34655d719c0acbc09ac696adb4b22aba1b9322b7111076e67053a55f62b501a4bca0ad9d50a868f51aeeb4ef27823236f5267e8da83e143047422ce140d66e05e44dc84fb3a4506b2a5d7caa8 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9 ad2f20492b6dcddcb9bd227bae1599db0326f661e77be01725e879bf718f158378927b04a158ef9168e6e8e7fd805095 +b1df8051b213fc5f636537e37e212eb20b2423e6467a9c7081336a870e6373fc835899d59e546c0ac668cc81ce4921e88f42e6da2a109a03b4f4e819a17c955b8d099ec6b282fb495258dca13ec779c459da909475519a3477223c06b99afbd77f9922e7cbef844b93f3ce5f50db816b2e0d8b1575d2e17a6b8db9111d6da578 f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce b37dcfaf0c7548127cefcaa60f0139fca9d5393c5c8cc4acd98735cdaa3a616cab1c346cb0de4c915837ddba37a4e6ec +0b918ede985b5c491797d0a81446b2933be312f419b212e3aae9ba5914c00af431747a9d287a7c7761e9bcbc8a12aaf9d4a76d13dad59fc742f8f218ef66eb67035220a07acc1a357c5b562ecb6b895cf725c4230412fefac72097f2c2b829ed58742d7c327cad0f1058df1bddd4ae9c6d2aba25480424308684cecd6517cdd8 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f b70a63888a7c8eaf9e91ddf982b69ac49f850dc664b97afe610e548981c2aa155cbcf3a71d9b3b0bf03cb4301b21bed4 +0fab26fde1a4467ca930dbe513ccc3452b70313cccde2994eead2fde85c8da1db84d7d06a024c9e88629d5344224a4eae01b21a2665d5f7f36d5524bf5367d7f8b6a71ea05d413d4afde33777f0a3be49c9e6aa29ea447746a9e77ce27232a550b31dd4e7c9bc8913485f2dc83a56298051c92461fd46b14cc895c300a4fb874 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b b9db8b53f9d796f36c3faf786d5d731be4789eec4adc00d671588e13de00ef9e085a1a6418c8069063468ce5c9bf6512 +7843f157ef8566722a7d69da67de7599ee65cb3975508f70c612b3289190e364141781e0b832f2d9627122742f4b5871ceeafcd09ba5ec90cae6bcc01ae32b50f13f63918dfb5177df9797c6273b92d103c3f7a3fc2050d2b196cc872c57b77f9bdb1782d4195445fcc6236dd8bd14c8bcbc8223a6739f6a17c9a861e8c821a6 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388 975b73e4bac53f440246ea3dea3e65a176b1b6da6d0664fa142b12dcd095928cbe7ebfab3923545a06e898d27f73b8b1 +6c8572b6a3a4a9e8e03dbeed99334d41661b8a8417074f335ab1845f6cc852adb8c01d9820fcf8e10699cc827a8fbdca2cbd46cc66e4e6b7ba41ec3efa733587e4a30ec552cd8ddab8163e148e50f4d090782897f3ddac84a41e1fcfe8c56b6152c0097b0d634b41011471ffd004f43eb4aafc038197ec6bae2b4470e869bded 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499 96ef8b87c5ba0af57fa5e719c562fb2d2f6f02e875754c5880cec16275855b8b1c4888ccc80ab099560e125e267c99ba +7e3c8fe162d48cc8c5b11b5e5ebc05ebc45c439bdbc0b0902145921b8383037cb0812222031598cd1a56fa71694fbd304cc62938233465ec39c6e49f57dfe823983b6923c4e865633949183e6b90e9e06d8275f3907d97967d47b6239fe2847b7d49cf16ba69d2862083cf1bccf7afe34fdc90e21998964107b64abe6b89d126 f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6 99081a7fcb373b31e1f716583934a3a9e2e31ddb1d819fa0ecb4a9de3e8d9b14005f7931b1955d366b65cdaab02c20dd +d5aa8ac9218ca661cd177756af6fbb5a40a3fecfd4eea6d5872fbb9a2884784aa9b5f0c023a6e0da5cf6364754ee6465b4ee2d0ddc745b02994c98427a213c849537da5a4477b3abfe02648be67f26e80b56a33150490d062aaac137aa47f11cfeddba855bab9e4e028532a563326d927f9e6e3292b1fb248ee90b6f429798db 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead a319bba11b4f4ddccada34f21247b812da3133f1633b09dd564685c482fe973f10fbd11a4b7baa545661daf2d39c3de4 +790b06054afc9c3fc4dfe72df19dd5d68d108cfcfca6212804f6d534fd2fbe489bd8f64bf205ce04bcb50124a12ce5238fc3fe7dd76e6fa640206af52549f133d593a1bfd423ab737f3326fa79433cde293236f90d4238f0dd38ed69492ddbd9c3eae583b6325a95dec3166fe52b21658293d8c137830ef45297d67813b7a508 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd b435b0936467d0fb54cdc24227c76f30458665c1d17ee2364f18212a34efa279043fa9afe061e227c85bf970ac27dc50 +6d549aa87afdb8bfa60d22a68e2783b27e8db46041e4df04be0c261c4734b608a96f198d1cdb8d082ae48579ec9defcf21fbc72803764a58c31e5323d5452b9fb57c8991d31749140da7ef067b18bf0d7dfbae6eefd0d8064f334bf7e9ec1e028daed4e86e17635ec2e409a3ed1238048a45882c5c57501b314e636b9bc81cbe 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117 a8c502c21cf92e5d53ac4bf2c519c2eb73d12ea36aaef1ef2850d02f0f8594052ba1c7eac130ed8fddfa9c218b2b37ec +1906e48b7f889ee3ff7ab0807a7aa88f53f4018808870bfed6372a77330c737647961324c2b4d46f6ee8b01190474951a701b048ae86579ff8e3fc889fecf926b17f98958ac7534e6e781ca2db2baa380dec766cfb2a3eca2a9d5818967d64dfab84f768d24ec122eebacaab0a4dc3a75f37331bb1c43dd8966cc09ec4945bbd 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61 883680081c637f7f635af90cc6d3f028ef8f993a8e595a7fefeb7bfa54b104bf95b24837de348ceeec27c4db9b340068 +7b59fef13daf01afec35dea3276541be681c4916767f34d4e874464d20979863ee77ad0fd1635bcdf93e9f62ed69ae52ec90aab5bbf87f8951213747ccec9f38c775c1df1e9d7f735c2ce39b42edb3b0c5086247556cfea539995c5d9689765288ec600848ecf085c01ca738bbef11f5d12d4457db988b4add90be00781024ad 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2 8ffb62444fed33574b6edd9ecb45432ebf381f6334b767a1062a6932d62ef2060b8d1905f7a49580ef13a0f2c02f5706 +041a6767a935dc3d8985eb4e608b0cbfebe7f93789d4200bcfe595277ac2b0f402889b580b72def5da778a680fd380c955421f626d52dd9a83ea180187b850e1b72a4ec6dd63235e598fd15a9b19f8ce9aec1d23f0bd6ea4d92360d50f951152bc9a01354732ba0cf90aaed33c307c1de8fa3d14f9489151b8377b57c7215f0b 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7 a8ff90b32fdf9d375bf18f0549ff83e427f06829bf88853c847e03af72fa6180b603356faa24ae482d42c170005bc71f +7905a9036e022c78b2c9efd40b77b0a194fbc1d45462779b0b76ad30dc52c564e48a493d8249a061e62f26f453ba566538a4d43c64fb9fdbd1f36409316433c6f074e1b47b544a847de25fc67d81ac801ed9f7371a43da39001c90766f943e629d74d0436ba1240c3d7fab990d586a6d6ef1771786722df56448815f2feda48f 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870 b6d763102e002a7dd00cd52039cea4e9e5a8e2f892b6637d979e5d417a8c81f4b9658dac708560fee8deb3e7c72f2849 +cf25e4642d4f39d15afb7aec79469d82fc9aedb8f89964e79b749a852d931d37436502804e39555f5a3c75dd958fd5291ada647c1a5e38fe7b1048f16f2b711fdd5d39acc0812ca65bd50d7f8119f2fd195ab16633503a78ee9102c1f9c4c22568e0b54bd4fa3f5ff7b49160bf23e7e2231b1ebebbdaf0e4a7d4484158a87e07 e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf a9e01ffd154784124807e7cbd07666929ad857f771ed5fda31e322b717d721055597534f8f8a101242c2dd9788c09b5e +7562c445b35883cc937be6349b4cefc3556a80255d70f09e28c3f393daac19442a7eecedcdfbe8f7628e30cd8939537ec56d5c9645d43340eb4e78fc5dd4322de8a07966b262770d7ff13a071ff3dce560718e60ed3086b7e0003a6abafe91af90af86733ce8689440bf73d2aa0acfe9776036e877599acbabfcb03bb3b50faa 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c a52eb66360c0596d7e7fdd2c3016ab90a8d583176c70f9b37fadf43d7fcf6839a82c9463096a2598eb7325248e5a102b +051c2db8e71e44653ea1cb0afc9e0abdf12658e9e761bfb767c20c7ab4adfcb18ed9b5c372a3ac11d8a43c55f7f99b33355437891686d42362abd71db8b6d84dd694d6982f0612178a937aa934b9ac3c0794c39027bdd767841c4370666c80dbc0f8132ca27474f553d266deefd7c9dbad6d734f9006bb557567701bb7e6a7c9 f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9 89ec259f827e555f5954fd6617d00281bcd4db8f0f440f117c72671bcbc162fc5134158d83245154b871cf83c7c4f56b +4dcb7b62ba31b866fce7c1feedf0be1f67bf611dbc2e2e86f004422f67b3bc1839c6958eb1dc3ead137c3d7f88aa97244577a775c8021b1642a8647bba82871e3c15d0749ed343ea6cad38f123835d8ef66b0719273105e924e8685b65fd5dc430efbc35b05a6097f17ebc5943cdcd9abcba752b7f8f37027409bd6e11cd158f f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5 8de88662cc2d29605cd88bd30bb7e1540b1b148bc5252c0fea91e7754efd93467e56b74bc7f296b3a0fd9ab5bcbc9b62 +efe55737771070d5ac79236b04e3fbaf4f2e9bed187d1930680fcf1aba769674bf426310f21245006f528779347d28b8aeacd2b1d5e3456dcbf188b2be8c07f19219e4067c1e7c9714784285d8bac79a76b56f2e2676ea93994f11eb573af1d03fc8ed1118eafc7f07a82f3263c33eb85e497e18f435d4076a774f42d276c323 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628 95181f923e6e2002a20a0b45c36a67e553daf1f3026f8b65314c717ff630ae820690e0642196ccacdc2a39fa7f4baa35 +ea95859cc13cccb37198d919803be89c2ee10befdcaf5d5afa09dcc529d333ae1e4ffd3bd8ba8642203badd7a80a3f77eeee9402eed365d53f05c1a995c536f8236ba6b6ff8897393506660cc8ea82b2163aa6a1855251c87d935e23857fe35b889427b449de7274d7754bdeace960b4303c5dd5f745a5cfd580293d6548c832 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49 ac7c57f2136abf121f5fc06ba25f0f2077d8bfa0297b96efde24f35ee85bac99a1a20b5e22ebadf09fee6cf31d0aece3 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P384 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P384 new file mode 100644 index 000000000000..c7628e9999a2 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P384 @@ -0,0 +1,60 @@ +39f0b25d4c15b09a0692b22fbacbb5f8aee184cb75887e2ebe0cd3be5d3815d29f9b587e10b3168c939054a89df11068e5c3fac21af742bf4c3e9512f5569674e7ad8b39042bcd73e4b7ce3e64fbea1c434ed01ad4ad8b5b569f6a0b9a1144f94097925672e59ba97bc4d33be2fa21b46c3dadbfb3a1f89afa199d4b44189938 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727 b1540ba6944520f930c84b12324e060523330ef32c3948b026c9df9879ac62fdfa85ea6299b8488eef4029af3536ee8a +5a3c80e608ed3ac75a6e45f6e94d374271a6d42b67a481860d5d309cc8b37c79cb61f1716dc8aa84cb309ef9d68eb7fc6cf4b42333f316a5c30e74198c8b340926e340c5de47674a707293c4aa2a1a2274a602f01c26b156e895499c60b38ef53fc2032e7485c168d73700d6fa14232596a0e4997854a0b05d02e351b9d3de96 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246 a5e9642aa5ebf20c1272b78732703589b885a9a8c32f6e514f8d88d561f58c006f10f2e2a5e022cda1788c43caa18385 +e7d974c5dbd3bfb8a2fb92fdd782f997d04be79e9713944ce13c5eb6f75dfdec811b7ee4b3859114b07f263846ae13f795eec8f3cb5b7565baff68e0fdd5e09ba8b176d5a71cb03fbc5546e6937fba560acb4db24bd42de1851432b96e8ca4078313cb849bce29c9d805258601d67cd0259e255f3048682e8fdbdda3398c3e31 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83 998a015adabb9682b1b793887ee4912a1c48e9807020770b8d701ddb96b7cea564f3bd34a73111346cf45ad393fa5ff7 +a670fda4d1d56c70de1d8680328043b2b7029633caf0ee59ffe1421c914bb937133d5a0f9214846b2e0b350455a74c4ab434c56de65a17139bb8212bf1c76071a37536fa29348f871dbb26baa92eb93d97e923a6d2ffd9be25cbc33075e494e6db657bd8dc053fe4e17148d8cf6e2058164f2b5766750eb01bbe7b361cdb848c dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659 8833813d94361b6edd3e6f61b183e0917460d3cce66e097cf86f8635dcd6b50488b549766183cdace593097a7e072bc0 +7843f918fe2588bcfe756e1f05b491d913523255aa006818be20b676c957f4edb8df863c6f5f8c15b3b80c7a2aa277b70d53f210bdfb856337980c406ea140e439dd321471407f374f69877b2d82367eed51e3c82c13948616dcb301d0c31f8f0352f2846abd9e72071f446a2f1bd3339a09ae41b84e150fd18f4ba5d3c6bfa0 df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718 92de3409b24390f46ceffe17ac787a6c339ff8dd1c902d5325269a9038748bbaf5cb5b1edad02425dbb0ce07fc4282b2 +caa83d5ab07febbd2e0fe2d63738b9b7b8752594bea7aaf50345b3d2f316653a8c9222f2b7877b64679e9573e81461a426029e45b8873a575094a1d572e0d32a9f0a9c6bcb9a2868543b7d8bbe4a69a09e7321f05f8366cced1b72df526f895b60aed2c39c249653c7839538770d4e5f47d3926ec0d168ab6a1af15bf1dca1f7 ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f 9413e11647313c0fe03daccf59753face54a0d1603593cada151cb4dbc773a4603a934938f89b8d3e34dfa384c345813 +594603458d6534974aeeafba919c4d0f4cb6843a3af41204bbb88aeb2fca2772d305163dba863da050aabedbaf89db521955d1715de95bbcef979ecdc0c976181ece00355385f8a8f8cce127c9eac15ce3e958a3ed686184674ec9a50eb63271606ee7fdcb1323da3c3db8e89cad1fb42139a32d08abcfbf0d4ccfca18c89a86 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829 8788a1ec009a47a1d5f9f46534ea554f0dfa8bafe9340559d8bda63f31888b4864e9b889fac37f55adfcccc77f5eefbc +733252d2bd35547838be22656cc7aa67eff0af0b13b428f77267a513c6824c3dbae533068b6817e82665f009560affcfe4b2ddb5b667a644fc1a42d24f24e0947e0dc50fb62c919bc1fe4e7ded5e28f2e6d80fcf66a081fb2763526f8def5a81a4ddd38be0b59ee839da1643eeeaee7b1927cec12cf3da67c02bc5465151e346 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1 951f0809b2f4fa760c774d09d92c26faa79cb5c13118ad62c1d509abfad133ced60701a9b017efea9ad8e34fe73ca2c4 +5a182bd174feb038dfae3346267156bf663167f713dea1ce936b0edb815cd9b8c8e4d411c786ba2494a81442617255db7158b142e720d86c9b56680fb9efd4298cdd69079a28153494c42a24251c7ad42ecf7e97eabc1b3997529b2a297cbad2474269b87a0b1e385f2d7f8b6eb8d1cd75eaf7e91d1acbecd45d7b2bfbbe3216 e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d a2a8687c7b131a6bd40fec264bcfa1da213430c502dc8ca8da411cc3ffe3343c818d3da99c2b48738506558c7a884936 +aaa99fb1c71340d785a18f6f668e898c25cf7a0ac31d13c5b388b7233408493a5a109af6d07065376b96f4903df7aba2b2af671a18772bb0472490d1240cde28967680727dd4acd47e0308920a75da857a6eeedee5b6586d45dff3d8a680599665aa895c89dd7770b824b7dee477ac5e7602d409d3cc553090c970b50811dbab 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead 804877f963fc327688fc2445e1976d524b9fbe63252f5ae18f0083e6c0df22c69a4ed4b628f3590ec03f14c07426bdaa +1fadfa8254d3a0b82d137cfdd82043d5dc1fef195d5297b09cc5cfb061f59c933451c0dc2a11b4037f34f88dacb803251f8880c4b72585c3c196e6fb23484ca43a191f8e41b9b9a37e2e6fcaab6738c3c62d1c98e1c620bb788b7b51a04f998a510efdba0d3418622fe8ce203b3fcd553b9b4206365a39031797ad11e49745ec 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0 a349ad6f4ff609a7912feffb0a28d2caf15a8ea19fd2a0902a31a2981e6d412fcff9d9ef282b316608b63fad4810d7fc +9ecb6f5ed3ba666a8536a81ef65012c2cb8b433508798d84708abb06dfb75503886f78384fb8c7a4d2d49ef539d9b8a0b60938c7f07471dda91f258b0d99691b38a8403a2bb3f956bdfd09baba16d9b6877097a9b6213481b47a06e139d23ec7abad5668d21f912fdb70d31bb9adf9b3ce80e308252fa81a51674f88d02db72b f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1 b31d71da84adac68a4755ac61561e1738b271928dc9d3cc79028fb40a622518ec729d2873fe10e4523d883ffbcf2c945 +e55bfca78d98e68d1b63688db12485578f36c489766f4d0bfaa0088433ff12133aaca455805095f2e655940860958b3ead111d9070778ee3bbf3e47e43d9eba8b8d9b1fdf72f793fcde2bcaa334f3e35fa2cca531ea7cf27fe9ccba741e38ac26129b2d612bf54a34e0ae6c166c0fef07fcd2b9ac253d7e041a500f7be7b8369 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb 85e422cb3205b8697a65e9e171d4f2932aa0d6d77496ecbdbf38bc272271498994fba409aa92ef951ba7c1d288180090 +02c6b3c83bd34b288d96409162aa4ff114e9d134bf948046eb5ebcc0c7fe9dfceadda83ed69da2fac00c8840f6c702a3fc5e6959d70f7e8af923e99e4937232ae3b841ffefd2e62fab3671a7c94a0281b8ea5bc176add57c5c9b6893fe7f5d48ce7256b96510810c4e046168a3c5be9843b84d5268a50349b3444341aa5490dd 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6 b3f4b5a33b318a1f5e533b92fc1d7792a0144a7d8a0534c2e768dd5281bb4ce2f52a398d1005c1037b6c21be29b15785 +94f8bfbb9dd6c9b6193e84c2023a27dea00fd48356909faec2161972439686c146184f80686bc09e1a698af7df9dea3d24d9e9fd6d7348a146339c839282cf8984345dc6a51096d74ad238c35233012ad729f262481ec7cd6488f13a6ebac3f3d23438c7ccb5a66e2bf820e92b71c730bb12fd64ea1770d1f892e5b1e14a9e5c cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd a49de5bcea77710ac6ef6138566b71a2d0a5a15241de4bc208404a1fa24ccdc535bec2c90df08f6fa4adeca220be0ff6 +663b12ebf44b7ed3872b385477381f4b11adeb0aec9e0e2478776313d536376dc8fd5f3c715bb6ddf32c01ee1d6f8b731785732c0d8441df636d8145577e7b3138e43c32a61bc1242e0e73d62d624cdc924856076bdbbf1ec04ad4420732ef0c53d42479a08235fcfc4db4d869c4eb2828c73928cdc3e3758362d1b770809997 c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b 899505ff354f8529115ebe137368c5bf83a53f823c2a8cf9a45ab18d647d21f346f9a469a60a9fe349699a25f4841057 +784d7f4686c01bea32cb6cab8c089fb25c341080d9832e04feac6ea63a341079cbd562a75365c63cf7e63e7e1dddc9e99db75ccee59c5295340c2bba36f457690a8f05c62ab001e3d6b333780117d1456a9c8b27d6c2504db9c1428dad8ba797a4419914fcc636f0f14ede3fba49b023b12a77a2176b0b8ff55a895dcaf8dbce 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9 a1b0745c31ca77817434613efe34db7ea2f383839625d91bbbfeb1dbd540c330b3bb15b56f34ffed547029c924aa9b64 +45e47fccc5bd6801f237cdbeac8f66ebc75f8b71a6da556d2e002352bd85bf269b6bc7c928d7bb1b0422601e4dd80b29d5906f8fcac212fe0eaaf52eda552303259cbcbe532e60abd3d38d786a45e39a2875bce675800a3eaeb9e42983d9fd9031180abd9adccc9ba30c6c198b4202c4dd70f241e969a3c412724b9b595bc28a d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f 87aa69ee35f2e3f2e81eaa054bd8d3d13e937f51e4fa33715e22ab083c3fc2215ca78fb14877c0c2b8e68e5737621b7d +c33ff63b4e6891e00b2349b3f2907c417ca355560544a91e24a7a0ee260d6850aeded29fc0176b6039ca6187e8333391047cceaf14b1077df8f147dad84d36b2dac5666dc2f69dc9b58b88cc73956efdb3b47f91831d5875051c76b0c4e9fc087012a1f03eeee85d6745b46aa50bd9cb0110c2c94508765cec162ee1aa841d73 d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3 8ce3ba0c1637d6498328e6beac04481f231a3e52ffd4b0d0fa605a1e383b7079e1c9ff9f566205291e651ee59d91b5d3 +f562f2b9d84b0e96a52532c3b43c39c8018c738bd8dc3797a7de7353971b2729d522d6961b1f2e4df3f6a4bd3653e6d72b74fc0dba92ab939c4b542e994e5db6dd8ed4f56f651e699052e791237ae1f552f990ad156226ae8f7bf17fcbfa564f749604f97e9df0879d50985747d981422a23040fe52f5ec74caf1d4aaad8a710 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93 aa0a1c5f45fcd35d855bfe7561a79bfd29e4e99d61076b42151c72603ee6b1a68f3b8c67af68ea50dd75122965f8d2ae +ace953ae851f571d71779aa120915f27450b236da23e9106f8d0756abdd25861937941228d225d5fb1aa1b1ebf759b1e326aeb3b6cd0cd87edd2ab9f6a7ad67b63d2c501d6a550edb2e7c9d216cc8af78dd33546af64d00abed4d0d2cfc5c9a7b5a055dbe8f7547902d185cf46937314832bc5c602419a82ab83dbd9d3bd5aff e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1 a78689e374f3032d050cc6e140ab977040eeafdad87d766a24d08beeff41028160517f3b22d7f0d044828f8992a5a902 +9635ab832240be95301bedb94c5aec169eedc198cbbdfedcf41e9b586143d829b4597a6b2a81902828332825fd84a785f187a3894e21bd99d22c4f94dcf34453fc052f15ec64d1447c932cb38fcdd30b7be851963409c11881438cbaad7e96f9efbde317f2235d66af804477a5dfe9f0c51448383830050ecf228889f83631e1 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960 962a1e195c7b29cd9535d5d7cb102e1f69dcfe1cd976edab32e3443d8f6f72e0bbca247d2de93bb50ea8a24e2f6fede5 +d98b9a7d4fe9d0fd95de5056af164a8b7882cd34ab5bde83a2abb32dc361eb56a479a3a6119db3b91dcad26a42d2206749567f0d97c34a981a91fc734921821a429f6a53401743a5c406ba9d560f956203abc9d1f32f1a13e7d7b290f75c95fdbf857ea597021461c06a3aacfa554ede3d69e4ff03bbbee5b7463ec77de2b3b2 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57 886509ba0631b8562137e3ccb3645791dd6ac79e17baebea2c826c73155731eeabc50b87a0c34401725b7f2487622aae +1b4c754ac1c28dc415a71eac816bde68de7e8db66409af835838c5bb2c605111108a3bf13606ed5d8ade5ed72e50503e0de664416393d178ea4eec834d8d6f15039847b410080fd5529b426e5aadd8451c20ebd92d787921f33e147bcbeb327b104d4aab1157fc1df33e4d768404b5ccb7110055c2508c600f429fd0c21b5784 a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1 8a04444074a205538de1e6fba8f63775c8eb689cd1a1ea7d5c20b6135339f7c1b92b57d8f03826cd09ace66ac4e7b007 +3cd8c053741dd9f974c6c5dbf8a1e5728e9b5eafb1cbcfc3452f5fbbda32a8c7564dee157e8d902c52514361da6d972934a56b3276e2a9379e328e24282e0db697c5bc29090fc489ec46b7b188325dd4e96494c250de0f4a89fe2ccf919eaefcfb50c288113e6df92714feb7f46e0822478c796d0f4ff3447a32997e892693ce 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3 88ad35ba901a479fabb5ed0d619493afac805d09d36952eca6b8d3af6f22d009961bde61acc58dcb054b091409c8311f +ed955dda6d9650124804d3deb6aeef900e520faf98b1ef6f14efcada7ca2433f09329b70897305e59c89024d76e466b28fe02cb2a9b12e2478c66470259d7c282137a19e5a04ffadea55245c0f34a681593fedc42931d8b3321b3d82e9cc102cd00540ad311ec7bd8c9d06db21bea4ca3dc74d98931ae0d40494aefc2345132c 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907 a1279e8757022508f9b70ba0eb79f7de63d863bfe190fde871e30c1dbc98320b06bb7c4278b08bd09e0ec46614245daf +ce395b001da2a58e49691605d44af4206306f62f561bf2394060d2a5591a350277166bed043819035f1e60b5b3fb5ae113ddd0473f8ef6b2b050c472c2a264e1d8b3ca82a4f158c40f2d78d9ce5e5ea6de243f2e1f13f47f6c6f403b270912c81c636be35b396ca58468b3fb60aa83911d61441a0528d973bc31f965d4059080 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245 a9542b7be128f2705fd0ad9e28bcf8068a34ac2a976ff67ad4fea72eefb21a148e2b1ebb8d512035d940ecc8c5861e62 +ffefe316455ae4ffdb890bb804bf7d31424ea060ecacff419d0f7134ff76ad434063c0ec0f8bb7059584d3a03f3625bb9e9f66ace1a47ac4b8f3e76fc7c420c55edb1427d1fa15b387ad73d02b0595c4e74321be8822752230a0dcfb85d60bfa186da7623a8ec3eb1633f0a294b23ae87216b14ccee9ef56418dcfab9427371e 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7 ae06e57ecb5edcadfd1f91a9bb3511eb8839fb02a0630a7982e93bd621b4af2ef2036e8b4371d11f03889f5848659f4e +304bccb718b3a9e12669913490cc5bcc1979287b56c628fad706c354241e88d10e81445a2853e3fc32ece094ba1abc3fdcab61da27f9a0fca739371049fed462ee6b08fa31cde12720f8144a6f00ce9b1a7a6eadd231f126717074b4efb5c72ce673ca5859000a436f67a338d698759f12c461247c45a361fb6cb661fdbe6714 d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5 a4c48e3706a6c0a2e8737912491e5f0ec7c88784005b36903d1cd5f933aa3c4a4ffc833d6212d4a1c20250b8ffcb16d3 +64f9f05c2805acf59c047b5f5d2e20c39277b6d6380f70f87b72327a76170b872bfe4b25c451602acfb6a631bb885e2655aee8abe44f69c90fb21ffde03cef2a452c468c6369867dfd8aa26ac24e16aa53b292375a8d8fbf988e302bf00088e4c061aa12c421d8fe3cbd7273b0e8993701df1c59431f436a08b8e15bd123d133 b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224 8856abab2f17a5058e428b7f68017f3b5822ec4c9a04d03996657ebfa3998b1c8ae93fb1b5f51484baa65fee8e031004 +6b45d88037392e1371d9fd1cd174e9c1838d11c3d6133dc17e65fa0c485dcca9f52d41b60161246039e42ec784d49400bffdb51459f5de654091301a09378f93464d52118b48d44b30d781eb1dbed09da11fb4c818dbd442d161aba4b9edc79f05e4b7e401651395b53bd8b5bd3f2aaa6a00877fa9b45cadb8e648550b4c6cbe 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 af7bd800dd8d11052f57c0ecfaed3f6038588d3424269b34d3c8a51d837284aa24b10c95b240d243c19b70a680ed91ab +d768f41e6e8ec2125d6cf5786d1ba96668ac6566c5cdbbe407f7f2051f3ad6b1acdbfe13edf0d0a86fa110f405406b69085219b5a234ebdb93153241f785d45811b3540d1c37424cc7194424787a51b79679266484c787fb1ded6d1a26b9567d5ea68f04be416caf3be9bd2cafa208fe2a9e234d3ae557c65d3fe6da4cb48da4 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 a046520026ea70136de7d8f7fb1c4be5eedf326692230eab50f8ad11104585a2ea44cb1c38036a5265bcdef2153e27c3 +6af6652e92a17b7898e40b6776fabaf0d74cf88d8f0ebfa6088309cbe09fac472eeac2aa8ea96b8c12e993d14c93f8ef4e8b547afe7ae5e4f3973170b35deb3239898918c70c1056332c3f894cd643d2d9b93c2561aac069577bbab45803250a31cd62226cab94d8cba7261dce9fe88c210c212b54329d76a273522c8ba91ddf b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 b29f07816bacf8c2186570e63f98c4dd96cd5a1aeecdc1f17e2c8998267e21036998e99c8a51a8726df2a3d7579ca037 +b96d74b2265dd895d94e25092fb9262dc4f2f7a328a3c0c3da134b2d0a4e2058ca994e3445c5ff4f812738e1b0c0f7a126486942a12e674a21f22d0886d68df2375f41685d694d487a718024933a7c4306f33f1a4267d469c530b0fed4e7dea520a19dd68bf0203cc87cad652260ed43b7b23f6ed140d3085875190191a0381a de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 b874e7b642b2e734315b250473486952b6af8b316beb200172eae40ae81bfdb0e938746c36f85f7312905cd41b193ee4 +7cec7480a037ff40c232c1d2d6e8cd4c080bbeecdaf3886fccc9f129bb6d202c316eca76c8ad4e76079afe622f833a16f4907e817260c1fa68b10c7a151a37eb8c036b057ed4652c353db4b4a34b37c9a2b300fb5f5fcfb8aa8adae13db359160f70a9241546140e550af0073468683377e6771b6508327408c245d78911c2cc 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc 974171f38a1d5b683f958f60d42c19b21b6ea3e166d696bce0a7d612f820644effd6ac7bd9ec20835e9d04fbaf583ea6 +00ce978603229710345c9ad7c1c2dba3596b196528eea25bd822d43ca8f76a024e29217703dd0652c8a615284fc3edcc1c5ad1c8d5a8521c8e104c016a24e50c2e25066dcb56596f913b872767e3627aa3e55ec812e9fdac7c2f1beade83aef093e24c9c953982adf431a776880ae4583be158e11cdab1cbca3ad3a66900213d 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 b80dfcbd032ac86b0321897edafd8206dae6b981cb2f197d9ec1dd5eeefcdfbeb9a8198e8c9456a3178c44988ece7a9d +54a255c18692c6162a46add176a0ae8361dcb8948f092d8d7bac83e160431794d3b9812849bf1994bcdcfba56e8540c8a9ee5b93414548f2a653191b6bb28bda8dc70d45cc1b92a489f58a2d54f85766cb3c90de7dd88e690d8ebc9a79987eee1989df35af5e35522f83d85c48dda89863171c8b0bf4853ae28c2ac45c764416 ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 8a4d51eb34b0a176f0eb6a96d28f7ed2a36e76fe9ad91d17c67f5d426334edb5d00917a962a746d8b282f644fbc9b2ff +692a78f90d4f9d5aee5da536314a78d68c1feabbfe5d1ccea7f6059a66c4b310f8051c411c409ccf6e19a0cbd8b8e100c48317fe8c6d4f8a638b9551ce7ee178020f04f7da3001a0e6855225fb3c9b375e4ed964588a1a41a095f3f476c42d52ffd23ce1702c93b56d4425d3befcf75d0951b6fd5c05b05455bdaf205fe70ca2 adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 b404f07a8ef2dd171a02b08cc1ba27b74c087d6d5d5d7b3fea24efa31f6da23c5a825d8c399fc5f665c4d5f3f263865e +3b309bb912ab2a51681451ed18ad79e95d968abc35423a67036a02af92f575a0c89f1b668afe22c7037ad1199e757a8f06b281c33e9a40bab69c9874e0bb680b905d909b9dc24a9fe89bb3d7f7d47082b25093c59754f8c19d1f81f30334a8cdd50a3cb72f96d4b3c305e60a439a7e93aeb640dd3c8de37d63c60fb469c2d3ed 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d ae355a82584ccfe2c8ce56a190980e7861896fa2e49a3b649c88c5c2a6712ca8bae6385409f6529a797bd6f0c6203057 +f072b72b8783289463da118613c43824d11441dba364c289de03ff5fab3a6f60e85957d8ff211f1cb62fa90216fb727106f692e5ae0844b11b710e5a12c69df3ed895b94e8769ecd15ff433762d6e8e94d8e6a72645b213b0231344e2c968056766c5dd6b5a5df41971858b85e99afbf859400f839b42cd129068efabeea4a26 e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 8967fd15a64be352b653a89c4d6a2a573fd1a9c4aad1eb6a6cf5d6bbf3431e6a8657826c6bfd08af7d1a0f5dae420abe +cf4945350be8133b575c4ad6c9585e0b83ff1ed17989b6cd6c71b41b5264e828b4e115995b1ae77528e7e9002ac1b5669064442645929f9d7dd70927cb93f95edeb73e8624f4bc897ec4c2c7581cb626916f29b2d6e6c2fba8c59a71e30754b459d81b912a12798182bcff4019c7bdfe929cc769bcc2414befe7d2906add4271 d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca abcaba06bee52e9b8c01446a15cfd5f7aaf2f0d088a1ccf5df58d2be50f31f3e0a116e76e77c88a24b9c765d15640e47 +d9b5cf0b50416573ff3c63133275a18394dd4326be2041e8d97e6e4e3855a4a177e9d26dfd223fe8aa74564edb49bd72de19916fb6f001f44530d5c18e2c332bce1b7415df5927ece5f3824f34d174b963136b53aef1fb78fb0c06a201a40b2db38e4d8216fc1e392a798c8ab4b3a314496b7f1087804ebfa89bf96e9cdb80c0 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d a70aac81bdfebbff30f0af1bf160bb19e157265cb9e2f8496ac0a4aed5f8c1f287bf5414fc7b1b481b36dcdac86532f7 +9e4042d8438a405475b7dab1cd783eb6ce1d1bffa46ac9dfda622b23ac31057b922eced8e2ed7b3241efeafd7c9ab372bf16230f7134647f2956fb793989d3c885a5ae064e85ed971b64f5f561e7ddb79d49aa6ebe727c671c67879b794554c04de0e05d68264855745ef3c9567bd646d5c5f8728b797c181b6b6a876e167663 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 999d8cb1c11212be20eb1fc843c0ba0bd238fec9703d2d37fe49228ac106325354790fbda0c3a6714138027a3ca930be +0b14a7484a40b68a3ce1273b8a48b8fdb65ba900d98541c4bbd07b97e31bcc4c85545a03e9deab3c563f47a036ff60d0361684ba241b5aa68bb46f440da22181ee328a011de98eff34ba235ec10612b07bdfa6b3dc4ccc5e82d3a8d057e1862fef3def5a1804696f84699fda2ec4175a54a4d08bcb4f0406fdac4eddadf5e29b ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 9783ff5a77ee446b33b50af13d8324ae7e71a0602bd4fa4fc46ef452e78371fb60b13a87929acd3155a7128f790faf27 +0e646c6c3cc0f9fdedef934b7195fe3837836a9f6f263968af95ef84cd035750f3cdb649de745c874a6ef66b3dd83b66068b4335bc0a97184182e3965c722b3b1aee488c3620adb835a8140e199f4fc83a88b02881816b366a09316e25685217f9221157fc05b2d8d2bc855372183da7af3f0a14148a09def37a332f8eb40dc9 e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb 845715c219ffa78000689c533bd905deee232f1806b2628f75f647efcc51677dd53b25a97b0e26adf4ebc9a3d3714df1 +67d9eb88f289454d61def4764d1573db49b875cfb11e139d7eacc4b7a79d3db3bf7208191b2b2078cbbcc974ec0da1ed5e0c10ec37f6181bf81c0f32972a125df64e3b3e1d838ec7da8dfe0b7fcc911e43159a79c73df5fa252b98790be511d8a732fcbf011aacc7d45d8027d50a347703d613ceda09f650c6104c9459537c8f 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c b862ca927935b84dca95c9ce7a0c53868f2eb117370a279cfc8688ee8f83f57e5764edf97ed5bc6541b897a4f2ffe811 +45db86829c363c80160659e3c5c7d7971abb1f6f0d495709bba908d7aa99c9df64b3408a51bd69aba8870e2aaff488ef138f3123cf94391d081f357e21906a4e2f311defe527c55e0231579957c51def507f835cceb466eb2593a509dcbee2f09e0dde6693b2bfe17697c9e86dd672f5797339cbe9ea8a7c6309b061eca7aef5 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f 934a05a8e0df3ae15d8a76c29c6744deefb7613adae255d2408c7856d6253f4673cfb7f1ef192363ffb9af746a78cf28 +4672fce0721d37c5be166bffa4b30d753bcf104b9b414db994b3ed33f36af4935ea59a0bb92db66448b3f57dad4fc67cef10ce141bf82c536be604b89a0bc0e8bca605b867880049d97142d30538fc543bd9d4fab7fdbe2f703815cdb6361beb66acff764bc275f910d1662445b07b92830db69a5994857f53657ed5ca282648 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7 afaf3f02351595a25f8adb47a7c11c8b134bdb17e47e185363922dbbeb67c1801747445dafc9dee5051e34430440a514 +9ae48fdd9bfc5cb0f4d4761e28b2073bda05a3e3fe82c212e66701dc4573cc67a829b0f82d7520b1bf11db0c6d1743822bbe41bb0adbd7222aa5fae70fbd1a31f2d4453a01c81e064d775388468be96f6063f8673b7b8d4455fe1bd4c801ad5e625a015eaa4a1a18da490d2af8642201eaba3c611cbd65f861d8e19ca82a1ee6 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf 8e08c188cebb00533360848462e67a95d6cd830b68fa54ee29c33b6c262de770930a13b7ddbb923f2acf1276b6d4bac5 +817d6a110a8fd0ca7b4d565558f68b59a156744d4c5aac5c6610c95451793de2a756f774558c61d21818d3ebeeeb71d132da1c23a02f4b305eccc5cd46bd21dfc173a8a91098354f10ffbb21bf63d9f4c3feb231c736504549a78fd76d39f3ad35c36178f5c233742d2917d5611d2073124845f1e3615b2ef25199a7a547e882 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b 882847106f96bae5b34e5f3ea2e54981aa7aed52a019346b0a835a770c0bfb75b6adb03676217bae00de048db1db417b +464f10ec6fb229a51db5fd0e122f2cb8a9a022117e2987f4007bf5565b2c16aba0714e2e3cdd0c100d55ac3017e36fc7501ad8309ab9572aa65424c9eb2e580a119c55777676ec498df53ef6ae78fd8a988130ee0e6082bf1ef71cd4c946021018a8ca7154d13b174c638912613b0bdb9001c302bf7e443ad2124ab2c1cce212 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69 b39827c9c634d18cde82df854c67993cd9b535dcaac9486a37c3113ef07604d8032f6ee39e271c030c1d93ee07ac1b2c +4e3e0fb96320ddccde8b463c273654c4f7164920b1d63430921d2e808dee403e6420eedda0a557b911d00736a4f8798dd4ef26673efd6d190988ad4929ec64f8685cfb76070a36cd6a3a4bf2f54fb08a349d44642b6f614043fef9b2813b63457c76537d23da7b37310334f7ba76edf1999dad86f72aa3446445a65952ac4e50 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db 9186d8417d0f2d798b1a7300ffa1caf2e5e90ec16cd45ae0a4d253b1c0ec26076c276b48043a81a9723efd4d2fdd5fc4 +c466b6b6baf7e6ffa876ec06105e2d43534e0517c07b1c4c9fb67ba81ce09525a7721ec3c290f2b1f65b6463d41598e7a25b2238501629953a5ca955b644354fb6856733a2e5bb8f5bc21a0c803493f5539f9fb83aab3dba2c982989c2270c61ab244b68bfe1b948d00c2ed975e09c29b5f8a7effcad8652a148cc880d503217 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d 866b3194551c39b3cd76badb9a2dbebd3d4ae374db05c84b7f349027160791b9f08505165885970e488eab0c8b4b115c +feac892b7720af80b3c9eede51e923f18d3d0c5de4c31f4aa75e36df7c7c2fd8f41778851a24b69e67dccb65e159dd5c383243bad7cfedcc5e85c8a01c34b0b94ba8e07e4c024c09d279b3731e8b62f9562d3c4f5042567efe42a9d0eaaabab28bc6f11232fc8ceaaf4518d9f3b2bebf020294496b7f6b879e69503f75fecd3d 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476 89a0e699a2c8602e146069f9d8a815fd2e747536598a3afb038d1005c398c17f8045340adbe49c2f5da9e6763525ef3f +cf2982e3bf174ce547741b969403cd11e9553067e6af8177d89511a0eb040db924530bdba65d8b1ff714228db0737c1756f509e1506014a10736e65be2f91980a73891496e90ff2714a3601c7565cdcef5a395e2e0e1652f138d90d61eaa9cba993b823245647f6e07cec9b8b4449cd68a29741cd1579c66e548ca0d0acf33aa ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa 8e99b051c265c5c1124ae80acd9a9a8c7272f8316d100bd76495e37220ceedecf06bd9aa85d8dd1004a6d1bcdc4ce97d +bf9fdd4107ef5a6070108771ac9eee4f0c8043bf0d04db772a47294f4137e2439d94b337114b074e57e0cb78d0ccf352a2833e9788ee2a1a9ffeacd34f38fcefb86653d70c7dadd4cf6548d608e70acdef6c7530974b92c813798add659752a8c72b05e1ad9c65c21834ce6fbe49d8a1426b5a54270794436d284364fac6ec1a 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f b6eb1381db9a84c912f11af1c24cf4f9fdc14d6dfe9348687f75163b7c292015adeeb88ee0fbdaef4c6eb8570bd9fdb2 +5d634fb39a2239256107dc68db19751540b4badac9ecf2fce644724401d6d632b3ae3b2e6d05746b77ddc0c899878032248c263eda08d3d004d35952ad7a9cfe19343d14b37f9f632245e7b7b5fae3cb31c5231f82b9f1884f2de7578fbf156c430257031ba97bc6579843bc7f59fcb9a6449a4cd942dffa6adb929cf219f0ad e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1 854f63860b039c59296b7accb237634df8db25acc86287715fbc9c22af7b50ca45a356383f32673d262f6bd81ad9ae3c +c9b4ff721b3e886f0dc05856ffff0aabb64a8504b1746a47fdd73e6b7ebc068f06ac7ffa44c757e4de207fc3cbfaf0469d3ac6795d40630bcafe8c658627e4bc6b86fd6a2135afbc18ccc8e6d0e1e86016930ca92edc5aa3fbe2c57de136d0ea5f41642b6a5d0ddeb380f2454d76a16639d663687f2a2e29fb9304243900d26d 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c 85901ad75699a000de039a4489ff722d568b2e853e8f23ad502f9a115620e4d0c13194e5fc219c9c6a61f86d4d736cc9 +db2ad659cf21bc9c1f7e6469c5f262b73261d49f7b1755fc137636e8ce0202f929dca4466c422284c10be8f351f36333ebc04b1888cba217c0fec872b2dfc3aa0d544e5e06a9518a8cfe3df5b20fbcb14a9bf218e3bf6a8e024530a17bab50906be34d9f9bba69af0b11d8ed426b9ec75c3bd1f2e5b8756e4a72ff846bc9e498 e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c 87b428b993fa8a15d14e0fbc7e2a494b0575529a230a8cfe0a47c99428bf0683bc1c1f350c15c3c9ebd1a0ac1f3de018 +dbd8ddc02771a5ff7359d5216536b2e524a2d0b6ff180fa29a41a8847b6f45f1b1d52344d32aea62a23ea3d8584deaaea38ee92d1314fdb4fbbecdad27ac810f02de0452332939f644aa9fe526d313cea81b9c3f6a8dbbeafc899d0cdaeb1dca05160a8a039662c4c845a3dbb07be2bc8c9150e344103e404411668c48aa7792 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855 8bec34091b63dfe24364da4db5c3f600d78832cdd72636c1c678c61da456f010f9f4400d690c32be2c859b5628630992 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P384_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P384_blst new file mode 100644 index 000000000000..b738eb81463c --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P384_blst @@ -0,0 +1,60 @@ +39f0b25d4c15b09a0692b22fbacbb5f8aee184cb75887e2ebe0cd3be5d3815d29f9b587e10b3168c939054a89df11068e5c3fac21af742bf4c3e9512f5569674e7ad8b39042bcd73e4b7ce3e64fbea1c434ed01ad4ad8b5b569f6a0b9a1144f94097925672e59ba97bc4d33be2fa21b46c3dadbfb3a1f89afa199d4b44189938 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727 aff8612c6d3536e2901b8b7cb32ed6a4bf78f85cb7a03d14f299b3c80caff3f8d153b1864d50c338fcd40d964eb36270 +5a3c80e608ed3ac75a6e45f6e94d374271a6d42b67a481860d5d309cc8b37c79cb61f1716dc8aa84cb309ef9d68eb7fc6cf4b42333f316a5c30e74198c8b340926e340c5de47674a707293c4aa2a1a2274a602f01c26b156e895499c60b38ef53fc2032e7485c168d73700d6fa14232596a0e4997854a0b05d02e351b9d3de96 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246 ac95f242ea5071669ab126c3c30e8a41dac5306a982c97b1b1af4c0bb9cca40817b2fb54badf73a1a08358109ae6ad06 +e7d974c5dbd3bfb8a2fb92fdd782f997d04be79e9713944ce13c5eb6f75dfdec811b7ee4b3859114b07f263846ae13f795eec8f3cb5b7565baff68e0fdd5e09ba8b176d5a71cb03fbc5546e6937fba560acb4db24bd42de1851432b96e8ca4078313cb849bce29c9d805258601d67cd0259e255f3048682e8fdbdda3398c3e31 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83 af59766d2fbcbe7110ebcd41b193e4049437f210684f57292f162b279f1266590efb67481dd38bd5b36ca3696a0bdc21 +a670fda4d1d56c70de1d8680328043b2b7029633caf0ee59ffe1421c914bb937133d5a0f9214846b2e0b350455a74c4ab434c56de65a17139bb8212bf1c76071a37536fa29348f871dbb26baa92eb93d97e923a6d2ffd9be25cbc33075e494e6db657bd8dc053fe4e17148d8cf6e2058164f2b5766750eb01bbe7b361cdb848c dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659 b521a174581a7fc532ec21f12526743f47294308fabd8bb50be4913156f10f795f42261c84fd9bb97c4cad18b7146f78 +7843f918fe2588bcfe756e1f05b491d913523255aa006818be20b676c957f4edb8df863c6f5f8c15b3b80c7a2aa277b70d53f210bdfb856337980c406ea140e439dd321471407f374f69877b2d82367eed51e3c82c13948616dcb301d0c31f8f0352f2846abd9e72071f446a2f1bd3339a09ae41b84e150fd18f4ba5d3c6bfa0 df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718 b81dc4b792adec72bf416635820ee486b36cf2589397108edc8819af82ee3959bbf067301040f53fc2e5b44cba0c7ec2 +caa83d5ab07febbd2e0fe2d63738b9b7b8752594bea7aaf50345b3d2f316653a8c9222f2b7877b64679e9573e81461a426029e45b8873a575094a1d572e0d32a9f0a9c6bcb9a2868543b7d8bbe4a69a09e7321f05f8366cced1b72df526f895b60aed2c39c249653c7839538770d4e5f47d3926ec0d168ab6a1af15bf1dca1f7 ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f b4ef8ee88265d32ab5b64749b74e8b8c5be0a8c17aa32f8e813b4d3a20e36ee1280ff91f9aeec8755d3f59d3790f1048 +594603458d6534974aeeafba919c4d0f4cb6843a3af41204bbb88aeb2fca2772d305163dba863da050aabedbaf89db521955d1715de95bbcef979ecdc0c976181ece00355385f8a8f8cce127c9eac15ce3e958a3ed686184674ec9a50eb63271606ee7fdcb1323da3c3db8e89cad1fb42139a32d08abcfbf0d4ccfca18c89a86 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829 b2511d1c0f52c9f15fdb26b694a0ada7bbbe14e47804af6e7a3acaf8c3d096a073a1b319b8682ef96f804fb9bd92cfd2 +733252d2bd35547838be22656cc7aa67eff0af0b13b428f77267a513c6824c3dbae533068b6817e82665f009560affcfe4b2ddb5b667a644fc1a42d24f24e0947e0dc50fb62c919bc1fe4e7ded5e28f2e6d80fcf66a081fb2763526f8def5a81a4ddd38be0b59ee839da1643eeeaee7b1927cec12cf3da67c02bc5465151e346 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1 b8a9578d8df94865dde3dd03e2b2c0c0c80a733f8d235eac77fb8d7b745622b84d6683da17c6e713240d9f9d84cd0417 +5a182bd174feb038dfae3346267156bf663167f713dea1ce936b0edb815cd9b8c8e4d411c786ba2494a81442617255db7158b142e720d86c9b56680fb9efd4298cdd69079a28153494c42a24251c7ad42ecf7e97eabc1b3997529b2a297cbad2474269b87a0b1e385f2d7f8b6eb8d1cd75eaf7e91d1acbecd45d7b2bfbbe3216 e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d 8b648bf79dc1951f99eaf6931eb1d78637d9aec4eb2d212910fa825eef86de11d00e1c26dde3a0fa1e8543f697f40233 +aaa99fb1c71340d785a18f6f668e898c25cf7a0ac31d13c5b388b7233408493a5a109af6d07065376b96f4903df7aba2b2af671a18772bb0472490d1240cde28967680727dd4acd47e0308920a75da857a6eeedee5b6586d45dff3d8a680599665aa895c89dd7770b824b7dee477ac5e7602d409d3cc553090c970b50811dbab 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead 8fdf0afca997edc5fb2a50c48a449aab78d9db69c108914cf9ce328344882716326996665ff8025300623f2b6d24d2a4 +1fadfa8254d3a0b82d137cfdd82043d5dc1fef195d5297b09cc5cfb061f59c933451c0dc2a11b4037f34f88dacb803251f8880c4b72585c3c196e6fb23484ca43a191f8e41b9b9a37e2e6fcaab6738c3c62d1c98e1c620bb788b7b51a04f998a510efdba0d3418622fe8ce203b3fcd553b9b4206365a39031797ad11e49745ec 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0 96d07826e954905316091b6838cdbc3aa67e1498fa90df07381f0380a391ecf692af316e5d1de0d4fad10f4520395543 +9ecb6f5ed3ba666a8536a81ef65012c2cb8b433508798d84708abb06dfb75503886f78384fb8c7a4d2d49ef539d9b8a0b60938c7f07471dda91f258b0d99691b38a8403a2bb3f956bdfd09baba16d9b6877097a9b6213481b47a06e139d23ec7abad5668d21f912fdb70d31bb9adf9b3ce80e308252fa81a51674f88d02db72b f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1 8e61489b1c24c90266728dfa542905fca6eb05e94fc9e52e0977dfe1d15362ea3892ffe2fe7ec01bcfb3b404bd9fc0d9 +e55bfca78d98e68d1b63688db12485578f36c489766f4d0bfaa0088433ff12133aaca455805095f2e655940860958b3ead111d9070778ee3bbf3e47e43d9eba8b8d9b1fdf72f793fcde2bcaa334f3e35fa2cca531ea7cf27fe9ccba741e38ac26129b2d612bf54a34e0ae6c166c0fef07fcd2b9ac253d7e041a500f7be7b8369 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb a03ca4cd862b84dcdc1d59c81cc37c3cf1c6ec1ca4a961be064239062e440b0b516507de38309e90ba9a31054f9f63bf +02c6b3c83bd34b288d96409162aa4ff114e9d134bf948046eb5ebcc0c7fe9dfceadda83ed69da2fac00c8840f6c702a3fc5e6959d70f7e8af923e99e4937232ae3b841ffefd2e62fab3671a7c94a0281b8ea5bc176add57c5c9b6893fe7f5d48ce7256b96510810c4e046168a3c5be9843b84d5268a50349b3444341aa5490dd 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6 a28b61f02d471139a34d2c8f74dd725cca3b60ba04765d60c2f5b0af515ac7451aa925f22f75f1c948cc8295d9e9de42 +94f8bfbb9dd6c9b6193e84c2023a27dea00fd48356909faec2161972439686c146184f80686bc09e1a698af7df9dea3d24d9e9fd6d7348a146339c839282cf8984345dc6a51096d74ad238c35233012ad729f262481ec7cd6488f13a6ebac3f3d23438c7ccb5a66e2bf820e92b71c730bb12fd64ea1770d1f892e5b1e14a9e5c cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd a78dafcbf561522d408a16cc9ce881ea5c6fb989ce7e6fc4f6c535211012f168c0d80e0a345ca9bc77a19db5bbdeb5be +663b12ebf44b7ed3872b385477381f4b11adeb0aec9e0e2478776313d536376dc8fd5f3c715bb6ddf32c01ee1d6f8b731785732c0d8441df636d8145577e7b3138e43c32a61bc1242e0e73d62d624cdc924856076bdbbf1ec04ad4420732ef0c53d42479a08235fcfc4db4d869c4eb2828c73928cdc3e3758362d1b770809997 c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b b642c3c78f944252a65dc1b0b98c37f4049459022837c034d8bab32962a5bc41d981814f914f1d099aa6e21691f123b8 +784d7f4686c01bea32cb6cab8c089fb25c341080d9832e04feac6ea63a341079cbd562a75365c63cf7e63e7e1dddc9e99db75ccee59c5295340c2bba36f457690a8f05c62ab001e3d6b333780117d1456a9c8b27d6c2504db9c1428dad8ba797a4419914fcc636f0f14ede3fba49b023b12a77a2176b0b8ff55a895dcaf8dbce 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9 994cba6378bc744ee8d402c1413e99147ed55e8b356b2c387139d12a6cfa2a482da6fd74df80fcfd655638baa94aa303 +45e47fccc5bd6801f237cdbeac8f66ebc75f8b71a6da556d2e002352bd85bf269b6bc7c928d7bb1b0422601e4dd80b29d5906f8fcac212fe0eaaf52eda552303259cbcbe532e60abd3d38d786a45e39a2875bce675800a3eaeb9e42983d9fd9031180abd9adccc9ba30c6c198b4202c4dd70f241e969a3c412724b9b595bc28a d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f 929d56498e1af92564a30d83378cc83dfb96abf21c41020790fcb057074668319ead1ed0695622f57c850d74933c82da +c33ff63b4e6891e00b2349b3f2907c417ca355560544a91e24a7a0ee260d6850aeded29fc0176b6039ca6187e8333391047cceaf14b1077df8f147dad84d36b2dac5666dc2f69dc9b58b88cc73956efdb3b47f91831d5875051c76b0c4e9fc087012a1f03eeee85d6745b46aa50bd9cb0110c2c94508765cec162ee1aa841d73 d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3 849706bb14887553bf79c14f44973bc31e67698bdee3e96067afb74dc790e48771da361544792547a53a4034952037c8 +f562f2b9d84b0e96a52532c3b43c39c8018c738bd8dc3797a7de7353971b2729d522d6961b1f2e4df3f6a4bd3653e6d72b74fc0dba92ab939c4b542e994e5db6dd8ed4f56f651e699052e791237ae1f552f990ad156226ae8f7bf17fcbfa564f749604f97e9df0879d50985747d981422a23040fe52f5ec74caf1d4aaad8a710 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93 97e466da9074f3b6b4e7a913a0675980d4557e17b5cefec9e92f1359b653ce2abc91c5e554fbf2ba363c98d4ccdd557f +ace953ae851f571d71779aa120915f27450b236da23e9106f8d0756abdd25861937941228d225d5fb1aa1b1ebf759b1e326aeb3b6cd0cd87edd2ab9f6a7ad67b63d2c501d6a550edb2e7c9d216cc8af78dd33546af64d00abed4d0d2cfc5c9a7b5a055dbe8f7547902d185cf46937314832bc5c602419a82ab83dbd9d3bd5aff e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1 997c0ae22b42782737188b77dc1b7f1bdebb9e62434be92f00840eeb38199ddbacba7a382d91d1f0193150f51ccaa711 +9635ab832240be95301bedb94c5aec169eedc198cbbdfedcf41e9b586143d829b4597a6b2a81902828332825fd84a785f187a3894e21bd99d22c4f94dcf34453fc052f15ec64d1447c932cb38fcdd30b7be851963409c11881438cbaad7e96f9efbde317f2235d66af804477a5dfe9f0c51448383830050ecf228889f83631e1 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960 8cebb0130cef81f5018232ec3cf86ffd4f4d5e1519e87e3c6cef78ce04a170d8dc6563adf28c4b8c77af30a9500feec8 +d98b9a7d4fe9d0fd95de5056af164a8b7882cd34ab5bde83a2abb32dc361eb56a479a3a6119db3b91dcad26a42d2206749567f0d97c34a981a91fc734921821a429f6a53401743a5c406ba9d560f956203abc9d1f32f1a13e7d7b290f75c95fdbf857ea597021461c06a3aacfa554ede3d69e4ff03bbbee5b7463ec77de2b3b2 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57 98046a5dfeaf688171e18e4a23611e88225d66e5e91806ae45ee788d1faa467f64f2167aecd4f9f22c01441fdd0556f4 +1b4c754ac1c28dc415a71eac816bde68de7e8db66409af835838c5bb2c605111108a3bf13606ed5d8ade5ed72e50503e0de664416393d178ea4eec834d8d6f15039847b410080fd5529b426e5aadd8451c20ebd92d787921f33e147bcbeb327b104d4aab1157fc1df33e4d768404b5ccb7110055c2508c600f429fd0c21b5784 a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1 adb3d3aeec52ca216357a38e6a40fbcdb9c5789b9e6fe2761ecf8f39dc17bda7bcc50022f169ad2f112f7b55f6b7fc79 +3cd8c053741dd9f974c6c5dbf8a1e5728e9b5eafb1cbcfc3452f5fbbda32a8c7564dee157e8d902c52514361da6d972934a56b3276e2a9379e328e24282e0db697c5bc29090fc489ec46b7b188325dd4e96494c250de0f4a89fe2ccf919eaefcfb50c288113e6df92714feb7f46e0822478c796d0f4ff3447a32997e892693ce 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3 8e1c5ac498ed6ea0d63a70767449e6f5d1c86979329cdb3a914a33ce17b2ca865f9e19bc73deeceda00df755fabb280c +ed955dda6d9650124804d3deb6aeef900e520faf98b1ef6f14efcada7ca2433f09329b70897305e59c89024d76e466b28fe02cb2a9b12e2478c66470259d7c282137a19e5a04ffadea55245c0f34a681593fedc42931d8b3321b3d82e9cc102cd00540ad311ec7bd8c9d06db21bea4ca3dc74d98931ae0d40494aefc2345132c 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907 ac37e8820146e919bb5328897edbe1143e422ad5143b9139c17099495284e9d064fce9e977a610863155bdb2ec6abf83 +ce395b001da2a58e49691605d44af4206306f62f561bf2394060d2a5591a350277166bed043819035f1e60b5b3fb5ae113ddd0473f8ef6b2b050c472c2a264e1d8b3ca82a4f158c40f2d78d9ce5e5ea6de243f2e1f13f47f6c6f403b270912c81c636be35b396ca58468b3fb60aa83911d61441a0528d973bc31f965d4059080 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245 945972085e12cf3e3c06807dfdc12befc3a0a009cd35058d0cb26223106bd06a63b61963a35eb492b498e093914e6143 +ffefe316455ae4ffdb890bb804bf7d31424ea060ecacff419d0f7134ff76ad434063c0ec0f8bb7059584d3a03f3625bb9e9f66ace1a47ac4b8f3e76fc7c420c55edb1427d1fa15b387ad73d02b0595c4e74321be8822752230a0dcfb85d60bfa186da7623a8ec3eb1633f0a294b23ae87216b14ccee9ef56418dcfab9427371e 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7 8fd696ec97e901b2b5d36bbc999620c8813a46db5aaa1b96bd37647c131096095d8c9a174fa96f8c3b8875bb7b453420 +304bccb718b3a9e12669913490cc5bcc1979287b56c628fad706c354241e88d10e81445a2853e3fc32ece094ba1abc3fdcab61da27f9a0fca739371049fed462ee6b08fa31cde12720f8144a6f00ce9b1a7a6eadd231f126717074b4efb5c72ce673ca5859000a436f67a338d698759f12c461247c45a361fb6cb661fdbe6714 d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5 b344c9cc49b94327f60c16322b037f2a4d407f2b9dba00a5b393e856f8ab5f4a853869e7f0ffd2e953452bfc0f53f882 +64f9f05c2805acf59c047b5f5d2e20c39277b6d6380f70f87b72327a76170b872bfe4b25c451602acfb6a631bb885e2655aee8abe44f69c90fb21ffde03cef2a452c468c6369867dfd8aa26ac24e16aa53b292375a8d8fbf988e302bf00088e4c061aa12c421d8fe3cbd7273b0e8993701df1c59431f436a08b8e15bd123d133 b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224 945fcabf37213809b4610b27c7c968bf92c616636b9db8532776e441f0e8121fe9613b3bc60fe68a0e309190bfaaff68 +6b45d88037392e1371d9fd1cd174e9c1838d11c3d6133dc17e65fa0c485dcca9f52d41b60161246039e42ec784d49400bffdb51459f5de654091301a09378f93464d52118b48d44b30d781eb1dbed09da11fb4c818dbd442d161aba4b9edc79f05e4b7e401651395b53bd8b5bd3f2aaa6a00877fa9b45cadb8e648550b4c6cbe 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 aa3b38106f99c01cdc9f96cb1bf7fe046911c06df1e236ef44b19a4410fd7370984ba31074fce7afa10dd5b936c79d55 +d768f41e6e8ec2125d6cf5786d1ba96668ac6566c5cdbbe407f7f2051f3ad6b1acdbfe13edf0d0a86fa110f405406b69085219b5a234ebdb93153241f785d45811b3540d1c37424cc7194424787a51b79679266484c787fb1ded6d1a26b9567d5ea68f04be416caf3be9bd2cafa208fe2a9e234d3ae557c65d3fe6da4cb48da4 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 905f23b50b76efbb990a0596cc3d72999b9206a74ff58a44066fa7e38a8794aa7ddf0e4c12de25fe121ecb7ee0d92d53 +6af6652e92a17b7898e40b6776fabaf0d74cf88d8f0ebfa6088309cbe09fac472eeac2aa8ea96b8c12e993d14c93f8ef4e8b547afe7ae5e4f3973170b35deb3239898918c70c1056332c3f894cd643d2d9b93c2561aac069577bbab45803250a31cd62226cab94d8cba7261dce9fe88c210c212b54329d76a273522c8ba91ddf b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 86242d658aa81faa15b5098541ec6220d047899b17ca75ff146e8cac44d8345d014cc890f9e7cf458fb3cfeee34bdbb0 +b96d74b2265dd895d94e25092fb9262dc4f2f7a328a3c0c3da134b2d0a4e2058ca994e3445c5ff4f812738e1b0c0f7a126486942a12e674a21f22d0886d68df2375f41685d694d487a718024933a7c4306f33f1a4267d469c530b0fed4e7dea520a19dd68bf0203cc87cad652260ed43b7b23f6ed140d3085875190191a0381a de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 8e53cff774ab91f2855617e702dfcfad2417e44744c810c777fffea867315fbd56e9275eaadeaa62cc000996a3586ff5 +7cec7480a037ff40c232c1d2d6e8cd4c080bbeecdaf3886fccc9f129bb6d202c316eca76c8ad4e76079afe622f833a16f4907e817260c1fa68b10c7a151a37eb8c036b057ed4652c353db4b4a34b37c9a2b300fb5f5fcfb8aa8adae13db359160f70a9241546140e550af0073468683377e6771b6508327408c245d78911c2cc 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc b4a9257fa868103a9c32821cb1a3998924d9fc8b7f016c9a40f7edd9bd8796f6eb7472495a24e714e01082eae69c7766 +00ce978603229710345c9ad7c1c2dba3596b196528eea25bd822d43ca8f76a024e29217703dd0652c8a615284fc3edcc1c5ad1c8d5a8521c8e104c016a24e50c2e25066dcb56596f913b872767e3627aa3e55ec812e9fdac7c2f1beade83aef093e24c9c953982adf431a776880ae4583be158e11cdab1cbca3ad3a66900213d 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 a4ee9433f50d6c9fce4bd1067e39d3e13a5404e17502f2752616a8fa6ea7f1a53900582892d39bac6f520205d29d73dd +54a255c18692c6162a46add176a0ae8361dcb8948f092d8d7bac83e160431794d3b9812849bf1994bcdcfba56e8540c8a9ee5b93414548f2a653191b6bb28bda8dc70d45cc1b92a489f58a2d54f85766cb3c90de7dd88e690d8ebc9a79987eee1989df35af5e35522f83d85c48dda89863171c8b0bf4853ae28c2ac45c764416 ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 aaab3adaaacab825b5aed4afd4138b808d851043303f10e1f73e2a9938182fc409c9f525e69d7f7ee1ab2d6f91270ca7 +692a78f90d4f9d5aee5da536314a78d68c1feabbfe5d1ccea7f6059a66c4b310f8051c411c409ccf6e19a0cbd8b8e100c48317fe8c6d4f8a638b9551ce7ee178020f04f7da3001a0e6855225fb3c9b375e4ed964588a1a41a095f3f476c42d52ffd23ce1702c93b56d4425d3befcf75d0951b6fd5c05b05455bdaf205fe70ca2 adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 85ff344d103f3d8bfeb7b4cdc263845b55bc9160738d77e5e1bc5139bab09ae1c82d8ffba49861a3d30eac7f61086eb9 +3b309bb912ab2a51681451ed18ad79e95d968abc35423a67036a02af92f575a0c89f1b668afe22c7037ad1199e757a8f06b281c33e9a40bab69c9874e0bb680b905d909b9dc24a9fe89bb3d7f7d47082b25093c59754f8c19d1f81f30334a8cdd50a3cb72f96d4b3c305e60a439a7e93aeb640dd3c8de37d63c60fb469c2d3ed 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d a399d2731c7a8096a03a3fd8ca6e3d456fa8a0bf0f8a21db5a9995e47bea472a34c3c09df2e152b22549c02b997fdd9b +f072b72b8783289463da118613c43824d11441dba364c289de03ff5fab3a6f60e85957d8ff211f1cb62fa90216fb727106f692e5ae0844b11b710e5a12c69df3ed895b94e8769ecd15ff433762d6e8e94d8e6a72645b213b0231344e2c968056766c5dd6b5a5df41971858b85e99afbf859400f839b42cd129068efabeea4a26 e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 a6f2cf0b3be715e6e633a78235baca5cd14be8e0ea2c8289ad10b1def043b1f61805abd273589a646256ab6da42a97bd +cf4945350be8133b575c4ad6c9585e0b83ff1ed17989b6cd6c71b41b5264e828b4e115995b1ae77528e7e9002ac1b5669064442645929f9d7dd70927cb93f95edeb73e8624f4bc897ec4c2c7581cb626916f29b2d6e6c2fba8c59a71e30754b459d81b912a12798182bcff4019c7bdfe929cc769bcc2414befe7d2906add4271 d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca 93523cb0db543844092c2a326e0fdb420386315b60af99e3f26e536e27c552733027a3f80e4818e1c912df75da0970f7 +d9b5cf0b50416573ff3c63133275a18394dd4326be2041e8d97e6e4e3855a4a177e9d26dfd223fe8aa74564edb49bd72de19916fb6f001f44530d5c18e2c332bce1b7415df5927ece5f3824f34d174b963136b53aef1fb78fb0c06a201a40b2db38e4d8216fc1e392a798c8ab4b3a314496b7f1087804ebfa89bf96e9cdb80c0 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d 87a475ece82d4ac201f3dc525b79e16de1eaf6c48ab0ce5140dfe95e94f816c0f85e3b05ba53f4d8401f8de38dd37a60 +9e4042d8438a405475b7dab1cd783eb6ce1d1bffa46ac9dfda622b23ac31057b922eced8e2ed7b3241efeafd7c9ab372bf16230f7134647f2956fb793989d3c885a5ae064e85ed971b64f5f561e7ddb79d49aa6ebe727c671c67879b794554c04de0e05d68264855745ef3c9567bd646d5c5f8728b797c181b6b6a876e167663 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 97866d73221b677f5402cf282a65450f9b314eeee52b350384fee9bc480cfd97b11d2d976819beff4a7d97ad8c9f689b +0b14a7484a40b68a3ce1273b8a48b8fdb65ba900d98541c4bbd07b97e31bcc4c85545a03e9deab3c563f47a036ff60d0361684ba241b5aa68bb46f440da22181ee328a011de98eff34ba235ec10612b07bdfa6b3dc4ccc5e82d3a8d057e1862fef3def5a1804696f84699fda2ec4175a54a4d08bcb4f0406fdac4eddadf5e29b ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 9730537839f65f25787476fc61a38b43e5534b1ae231b8911b24c2ecd561855fc1f0063cd5468d7cbaa087a7a33909e4 +0e646c6c3cc0f9fdedef934b7195fe3837836a9f6f263968af95ef84cd035750f3cdb649de745c874a6ef66b3dd83b66068b4335bc0a97184182e3965c722b3b1aee488c3620adb835a8140e199f4fc83a88b02881816b366a09316e25685217f9221157fc05b2d8d2bc855372183da7af3f0a14148a09def37a332f8eb40dc9 e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb 8cee52dc5752300b2d4abe5b03fe548e85b07278d09fb90e9b858918f8981911d4aec36f7054d6c248629d25c19a63de +67d9eb88f289454d61def4764d1573db49b875cfb11e139d7eacc4b7a79d3db3bf7208191b2b2078cbbcc974ec0da1ed5e0c10ec37f6181bf81c0f32972a125df64e3b3e1d838ec7da8dfe0b7fcc911e43159a79c73df5fa252b98790be511d8a732fcbf011aacc7d45d8027d50a347703d613ceda09f650c6104c9459537c8f 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c 95a166da9d8ce6db31ffc487b308b32c4226311484dfbc691838c17936e2722b6ad0b83cbcd1a52b06e6978811848480 +45db86829c363c80160659e3c5c7d7971abb1f6f0d495709bba908d7aa99c9df64b3408a51bd69aba8870e2aaff488ef138f3123cf94391d081f357e21906a4e2f311defe527c55e0231579957c51def507f835cceb466eb2593a509dcbee2f09e0dde6693b2bfe17697c9e86dd672f5797339cbe9ea8a7c6309b061eca7aef5 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f 82f93cdf1e7215e38c9df04f6d39f8073aa36a1b874865f5a230e1b828e4eb9203d908dc0e6e0971f4edaf1fc003d7b9 +4672fce0721d37c5be166bffa4b30d753bcf104b9b414db994b3ed33f36af4935ea59a0bb92db66448b3f57dad4fc67cef10ce141bf82c536be604b89a0bc0e8bca605b867880049d97142d30538fc543bd9d4fab7fdbe2f703815cdb6361beb66acff764bc275f910d1662445b07b92830db69a5994857f53657ed5ca282648 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7 96c3ff51d496b6fda6107646e80fa67da2bf41ed31f787ab8c5dcb6c7a429d5adf3b8832b803abc6a6b2272bc871fccd +9ae48fdd9bfc5cb0f4d4761e28b2073bda05a3e3fe82c212e66701dc4573cc67a829b0f82d7520b1bf11db0c6d1743822bbe41bb0adbd7222aa5fae70fbd1a31f2d4453a01c81e064d775388468be96f6063f8673b7b8d4455fe1bd4c801ad5e625a015eaa4a1a18da490d2af8642201eaba3c611cbd65f861d8e19ca82a1ee6 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf 85f714251310fed43d56ae63fe0d667572c8f6e4e83099f9d44bc8f1a45538447b66e6331b4d202441fc66f6ca4f0f22 +817d6a110a8fd0ca7b4d565558f68b59a156744d4c5aac5c6610c95451793de2a756f774558c61d21818d3ebeeeb71d132da1c23a02f4b305eccc5cd46bd21dfc173a8a91098354f10ffbb21bf63d9f4c3feb231c736504549a78fd76d39f3ad35c36178f5c233742d2917d5611d2073124845f1e3615b2ef25199a7a547e882 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b 96221a2d4c5bcaac82959b3072f9332559b5601bf041f4e91ad5c67eab38d1242c1adcd1de24736a83141f0af72e8247 +464f10ec6fb229a51db5fd0e122f2cb8a9a022117e2987f4007bf5565b2c16aba0714e2e3cdd0c100d55ac3017e36fc7501ad8309ab9572aa65424c9eb2e580a119c55777676ec498df53ef6ae78fd8a988130ee0e6082bf1ef71cd4c946021018a8ca7154d13b174c638912613b0bdb9001c302bf7e443ad2124ab2c1cce212 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69 b034f2ed14abb7715db3981b7851058975ee9e927bdf111c19093485e1a3bd37dd2528ddd1dab661ccee8f3a17a8d0c4 +4e3e0fb96320ddccde8b463c273654c4f7164920b1d63430921d2e808dee403e6420eedda0a557b911d00736a4f8798dd4ef26673efd6d190988ad4929ec64f8685cfb76070a36cd6a3a4bf2f54fb08a349d44642b6f614043fef9b2813b63457c76537d23da7b37310334f7ba76edf1999dad86f72aa3446445a65952ac4e50 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db 8a103a82cdfd8c7e9941e5be66fea646b82c36378ef33cc14fee8eeb692126b93c375dd8e83a9be032415738e8eeaf38 +c466b6b6baf7e6ffa876ec06105e2d43534e0517c07b1c4c9fb67ba81ce09525a7721ec3c290f2b1f65b6463d41598e7a25b2238501629953a5ca955b644354fb6856733a2e5bb8f5bc21a0c803493f5539f9fb83aab3dba2c982989c2270c61ab244b68bfe1b948d00c2ed975e09c29b5f8a7effcad8652a148cc880d503217 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d 96899fa38dd1fee525443dec9afa75fe3c7e1cb025a8475842997c73b445c434b7a24faed48e05b46cc36013619cfd6f +feac892b7720af80b3c9eede51e923f18d3d0c5de4c31f4aa75e36df7c7c2fd8f41778851a24b69e67dccb65e159dd5c383243bad7cfedcc5e85c8a01c34b0b94ba8e07e4c024c09d279b3731e8b62f9562d3c4f5042567efe42a9d0eaaabab28bc6f11232fc8ceaaf4518d9f3b2bebf020294496b7f6b879e69503f75fecd3d 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476 ad02c55b0221b2c518fdaf7905a00072266386201042898159919c3ab9f9d0598f5aeec7cc11e6b9fbefa6f839ea8280 +cf2982e3bf174ce547741b969403cd11e9553067e6af8177d89511a0eb040db924530bdba65d8b1ff714228db0737c1756f509e1506014a10736e65be2f91980a73891496e90ff2714a3601c7565cdcef5a395e2e0e1652f138d90d61eaa9cba993b823245647f6e07cec9b8b4449cd68a29741cd1579c66e548ca0d0acf33aa ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa 92c5eaee38e4a2b3b83d069a929725c218597ee36d0d2762a441dbfc28a090e5419c05a74aa40b1b023894d7ea16842e +bf9fdd4107ef5a6070108771ac9eee4f0c8043bf0d04db772a47294f4137e2439d94b337114b074e57e0cb78d0ccf352a2833e9788ee2a1a9ffeacd34f38fcefb86653d70c7dadd4cf6548d608e70acdef6c7530974b92c813798add659752a8c72b05e1ad9c65c21834ce6fbe49d8a1426b5a54270794436d284364fac6ec1a 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f b7fb35c750823212a1b3bf0ac0864c164b330aeb302ca178433283a2c8e53a40af8950686243eca3408c22bff15ccdc5 +5d634fb39a2239256107dc68db19751540b4badac9ecf2fce644724401d6d632b3ae3b2e6d05746b77ddc0c899878032248c263eda08d3d004d35952ad7a9cfe19343d14b37f9f632245e7b7b5fae3cb31c5231f82b9f1884f2de7578fbf156c430257031ba97bc6579843bc7f59fcb9a6449a4cd942dffa6adb929cf219f0ad e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1 b0167c7e2875d776eb522feb82e802c700d37c83eb9043aea6ca7d032d572afb2ee5f9886a6abbb8aa7879e37933056c +c9b4ff721b3e886f0dc05856ffff0aabb64a8504b1746a47fdd73e6b7ebc068f06ac7ffa44c757e4de207fc3cbfaf0469d3ac6795d40630bcafe8c658627e4bc6b86fd6a2135afbc18ccc8e6d0e1e86016930ca92edc5aa3fbe2c57de136d0ea5f41642b6a5d0ddeb380f2454d76a16639d663687f2a2e29fb9304243900d26d 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c 93834c3afe20782ac7e418031069eb632d7496585527ea7affdb2bb82668e929d412185598c6cc0635ce30bc2b038944 +db2ad659cf21bc9c1f7e6469c5f262b73261d49f7b1755fc137636e8ce0202f929dca4466c422284c10be8f351f36333ebc04b1888cba217c0fec872b2dfc3aa0d544e5e06a9518a8cfe3df5b20fbcb14a9bf218e3bf6a8e024530a17bab50906be34d9f9bba69af0b11d8ed426b9ec75c3bd1f2e5b8756e4a72ff846bc9e498 e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c a6628d10f8c883f4240fbbcccdb97457b7f2c7cdfc9b9c9e560de6fc3af30b043976350fa15d069f5324a219df32281a +dbd8ddc02771a5ff7359d5216536b2e524a2d0b6ff180fa29a41a8847b6f45f1b1d52344d32aea62a23ea3d8584deaaea38ee92d1314fdb4fbbecdad27ac810f02de0452332939f644aa9fe526d313cea81b9c3f6a8dbbeafc899d0cdaeb1dca05160a8a039662c4c845a3dbb07be2bc8c9150e344103e404411668c48aa7792 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855 950e05486e3309ad073c385c7891fd63507600d2a62c7112aa79b22d1c22d7572ee91e6458d43f2e1c20bc8b1a243f6a diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P521 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P521 new file mode 100644 index 000000000000..0e449a56fea7 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P521 @@ -0,0 +1,60 @@ +58ec2b2ceb80207ff51b17688bd5850f9388ce0b4a4f7316f5af6f52cfc4dde4192b6dbd97b56f93d1e4073517ac6c6140429b5484e266d07127e28b8e613ddf65888cbd5242b2f0eee4d5754eb11f25dfa5c3f87c790de371856c882731a157083a00d8eae29a57884dbbfcd98922c12cf5d73066daabe3bf3f42cfbdb9d853 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46 b84f9ce8cd01e16016bc5a546833d8bd01b6ef0ba955c1549278c217f2c78f23df39a6064caeaa2aacc590cd81f4169a +2449a53e0581f1b56d1e463b1c1686d33b3491efe1f3cc0443ba05d65694597cc7a2595bda9cae939166eb03cec624a788c9bbab69a39fb6554649131a56b26295683d8ac1aea969040413df405325425146c1e3a138d2f4f772ae2ed917cc36465acd66150058622440d7e77b3ad621e1c43a3f277da88d850d608079d9b911 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73 8ecb113428e56735421a2d594c4271722b4336a054ccb36e10e249a68fab1f44d97a2332a53e1a84a203579ea296d1b5 +7ba05797b5b67e1adfafb7fae20c0c0abe1543c94cee92d5021e1abc57720a6107999c70eacf3d4a79702cd4e6885fa1b7155398ac729d1ed6b45e51fe114c46caf444b20b406ad9cde6b9b2687aa645b46b51ab790b67047219e7290df1a797f35949aaf912a0a8556bb21018e7f70427c0fc018e461755378b981d0d9df3a9 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace 8931a191f1ec1c8a727c00582a06d5cae9d3f6c2b2fb7afde66fa71c07f901662f02827e0708070e1c5d93ea0ffd888e +716dabdb22a1c854ec60420249905a1d7ca68dd573efaff7542e76f0eae54a1828db69a39a1206cd05e10e681f24881b131e042ed9e19f5995c253840e937b809dfb8027fed71d541860f318691c13a2eb514daa5889410f256305f3b5b47cc16f7a7dad6359589b5f4568de4c4aae2357a8ea5e0ebaa5b89063eb3aa44eb952 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc b761265a22a64fe93c279589c234eba9d5ec13c6db14cb5ef0c92fc7dd964df0d36ff3d24b35f862f580dc6049e4a41d +9cc9c2f131fe3ac7ea91ae6d832c7788cbbf34f68e839269c336ceef7bef6f20c0a62ea8cc340a333a3002145d07eba4cf4026a0c4b26b0217a0046701de92d573d7c87a386a1ea68dc80525b7dcc9be41b451ad9f3d16819e2a0a0b5a0c56736da3709e64761f97cae2399de2a4022dc4c3d73c7a1735c36dbde86c4bc5b6f7 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549 9016fbc8ceec985c0d484215b444d56402c177db602fc3ec34b1af7e4f463be21d7ae22f7ae4f2cdfdb6e9cdf951a167 +14c69f8d660f7a6b37b13a6d9788eff16311b67598ab8368039ea1d9146e54f55a83b3d13d7ac9652135933c68fafd993a582253be0deea282d86046c2fb6fd3a7b2c80874ced28d8bed791bd4134c796bb7baf195bdd0dc6fa03fdb7f98755ca063fb1349e56fd0375cf94774df4203b34495404ebb86f1c7875b85174c574c 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4 b772e263d78a2d8c189308a6df66aa60217b320a7e0192caade44bec14a7b341594214c9a6c875c75ac09317fd39a754 +8d8e75df200c177dbfe61be61567b82177ea5ec58e2781168d2277d2fd42668f01248ca3eb29ffa2689b12ae40f9c429532b6d2e1f15891322b825a0a072a1c68fa09e78cfdef3e95ed6fdf7233a43cb68236560d49a3278f0b3f47cb08f475bd9ab2f60755ea4a1767de9313b71a1b9ea87ef33f34682efbda263b0f8cc2f52 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16 b609b58ec879484b06ac5a82f1d4cfa69378efbabaaf8c2da08eca16077ade8509328408e0858ee19873f34450d195cc +10631c3d438870f311c905e569a58e56d20a2a560e857f0f9bac2bb7233ec40c79de145294da0937e6b5e5c34fff4e6270823e5c8553c07d4adf25f614845b2eac731c5773ebbd716ab45698d156d043859945de57473389954d223522fbafecf560b07ef9ba861bcc1df9a7a89cdd6debf4cd9bf2cf28c193393569ccbd0398 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37 a092162b8346354c3d0f671c5e83f11e7fbad83e045bb2faa3168fd9e61b3f7716a5fd77e9f677a5eaa436a5c9fd25da +80aad6d696cbe654faa0d0a24d2f50d46e4f00a1b488ea1a98ed06c44d1d0c568beb4ab3674fc2b1d2d3da1053f28940e89ba1244899e8515cabdd66e99a77df31e90d93e37a8a240e803a998209988fc829e239150da058a300489e33bf3dcdaf7d06069e74569fee77f4e3875d0a713ccd2b7e9d7be62b34b6e375e84209ef 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256 aea3958fdbbc74d2ae28bb7f2ff3de09e48988a827cefd3b6a1608c5f1739653ee1e23ac8e387c3ce32f2d910def098d +8a7792a2870d2dd341cd9c4a2a9ec2da753dcb0f692b70b64cef2e22071389c70b3b188dea5f409fb435cbd09082f59de6bc2ff9e65f91b7acc51e6e7f8e513148cb3c7c4664f227d5c704626b0fda447aa87b9d47cd99789b88628eb642ed250312de5ba6b25f3d5342a3cbb7ebd69b0044ee2b4c9ba5e3f5195afb6bea823d 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7 906f0460d467bad958ce833f3e098bcf888de3d249f49e8fdfafb252a01985291b356a72317eddb5ec762866df883487 +f971bcd396efb8392207b5ca72ac62649b47732fba8feaa8e84f7fb36b3edb5d7b5333fbfa39a4f882cb42fe57cd1ace43d06aaad33d0603741a18bc261caa14f29ead389f7c20536d406e9d39c34079812ba26b39baedf5feb1ef1f79990496dd019c87e38c38c486ec1c251da2a8a9a57854b80fcd513285e8dee8c43a9890 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73 80fcecfe3829019dfe4dd7760dc8d1b733b3bc96faf43e04a0b6976dc67bd990740561942f663115c35b595d429e2385 +ec0d468447222506b4ead04ea1a17e2aa96eeb3e5f066367975dbaea426104f2111c45e206752896e5fa7594d74ed184493598783cb8079e0e915b638d5c317fa978d9011b44a76b28d752462adf305bde321431f7f34b017c9a35bae8786755a62e746480fa3524d398a6ff5fdc6cec54c07221cce61e46fd0a1af932fa8a33 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c 96535e527724c079f3d6cc615b25d02a2ddc35ea8dee4fed66c363bd4599a33a1438d7c1d2e60ada8e59e2ba96c34723 +d891da97d2b612fa6483ee7870e0f10fc12a89f9e33d636f587f72e0049f5888782ccde3ea737e2abca41492bac291e20de5b84157a43c5ea900aef761006a4471072ab6ae6d515ffe227695d3ff2341355b8398f72a723ae947f9618237c4b6642a36974860b452c0c6202688bc0814710cbbff4b8e0d1395e8671ae67ada01 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace 90be2dee7cdbdda758651904029f61f662f4bacb33bc96c2d402297723a589a86637534ca78ccd9ec6f1b6885f5e979e +924e4afc979d1fd1ec8ab17e02b69964a1f025882611d9ba57c772175926944e42c68422d15f9326285538a348f9301e593e02c35a9817b160c05e21003d202473db69df695191be22db05615561951867f8425f88c29ba8997a41a2f96b5cee791307369671543373ea91d5ed9d6a34794d33305db8975b061864e6b0fe775f 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8 a6422ad2d373bef2c4fa62175f9140e69865d4aa9c5a63e6f947f2de6d132189cfd3d2ef55850727e5d329d0be83662b +c64319c8aa1c1ae676630045ae488aedebca19d753704182c4bf3b306b75db98e9be438234233c2f14e3b97c2f55236950629885ac1e0bd015db0f912913ffb6f1361c4cc25c3cd434583b0f7a5a9e1a549aa523614268037973b65eb59c0c16a19a49bfaa13d507b29d5c7a146cd8da2917665100ac9de2d75fa48cb708ac79 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad 8a77180f37b6629973385701e3a42229eeb0010ebb82133d4a93f55a5b61b025e0c8a3d7a1964024b1a5f7ffee5fa264 +8ab8176b16278db54f84328ae0b75ef8f0cd18afdf40c04ad0927ed0f6d9e47470396c8e87cde7a9be2ffbfe6c9658c88b7de4d582111119c433b2e4a504493f0a1166e3a3ea0d7b93358f4a297d63f65a5e752f94e2ee7f49ebcc742fa3eb03a617d00c574245b77a20033854d82964b2949e2247637239ab00baf4d170d97c 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a 8f67e1d273cb9f5d57707d012ade027cc9f619f1dcefb6fb13142607c0eb3409e9ad8b5933968ca2a236d2e90fe44f6e +c4bc2cec829036469e55acdd277745034e4e3cc4fcd2f50ec8bd89055c19795a1e051ccf9aa178e12f9beab6a016a7257e391faa536eaa5c969396d4e1ade36795a82ebc709d9422de8497e5b68e7292538d4ccdc6dd66d27a3ece6a2844962b77db073df9489c9710585ba03d53fa430dbc6626dc03b61d53fc180b9af5dea6 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c 85b5140515c28306bddcdd51042177da238123ed00adb0a9e8ff2da057896f804a0b8228b1a8781babce909331667bab +1c1b641d0511a0625a4b33e7639d7a057e27f3a7f818e67f593286c8a4c827bb1f3e4f399027e57f18a45403a310c785b50e5a03517c72b45ef8c242a57b162debf2e80c1cf6c7b90237aede5f4ab1fcaf8187be3beb524c223cc0ceff24429eb181a5eea364a748c713214880d976c2cd497fd65ab3854ad0d6c2c1913d3a06 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d b5bddf85dca88cd1c703c3105cdd74aa020fbc81b8ac0fd91c6f79c983c62a41acc31b9e2888951d96b2a45f0a148b88 +adb5f069b2b501a3ebb83d4f1808eb07710ac4a7b12532996855a20bcc54b2f76812915f632163c3654ff13d187d007152617cf859200194b59c5e81fc6cc9eb1ceb75d654050f260caa79c265254089270ccd02607fdcf3246119738c496dc3a4bd5d3be15789fc3d29a08d6d921febe2f40aef286d5d4330b07198c7f4588e 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c b4cbbf5a27c48da4981402e67306383377651e67347ad626e01d6db1d6bbf14c64a02a34515fb40b0ef895a29bc27598 +f253484d121d1ce8a88def6a3e9e78c47f4025ead6f73285bf90647102645b0c32d4d86742a50b8b7a42d5f6156a6faf588212b7dc72c3ffd13973bdba732b554d8bffc57d04f8167aef21ee941ee6ffb6cce0f49445bd707da8deb35dca650aaf761c3aa66a5ebccddd15aee21293f63061a7f4bfc3787c2cd62c806a1a9985 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25 8210d680410c47f6a9f044cfca72ef5b9c8f76ddfa1b2c0dddae70d21dc23e6cb7aa9911e6cec8a1510bcacc1866e316 +33bab1c369c495db1610965bc0b0546a216e8dd00cd0e602a605d40bc8812bbf1ffa67143f896c436b8f7cf0bed308054f1e1ff77f4d0a13c1e831efbd0e2fcfb3eadab9f755f070ba9aeaceb0a5110f2f8b0c1f7b1aa96a7f2d038a1b72e26400819b1f73d925ea4e34d6acaf59d0a461a34ce5d65c9c937a80e844e323a16d 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf add6d5d46a9809db37579415b12c4010a16c2b50f25581f677e09c8ab4ff58f88e24108738670ab8b42d2dd33d936a4f +08c8b7faaac8e1154042d162dca1df0f66e0001b3c5ecf49b6a4334ce4e8a754a1a8e4daf8ec09cf1e521c96547aed5172ef852e82c03cddd851a9f992183ac5199594f288dbcc53a9bb6128561ff3236a7b4b0dce8eaf7d45e64e782955ee1b690ce6a73ece47dc4409b690de6b7928cbe60c42fc6a5ddf1d729faf1cc3885e 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570 913b914c676806bd618d828921918f1726e69dbfb8b8b150ed8ec57812b4edb713c1a176a9f99fbba342e23b01f6017c +ba74eed74282811631bd2069e862381e4e2a1e4e9a357b1c159a9ce69786f864b60fe90eeb32d8b72b099986fc594965a33285f7185b415df58fead7b8b50fc60d073680881d7435609ad1d22fd21e789b6730e232b0d2e888889fb82d6ad0337ab909308676164d4f47df44b21190eca8ba0f94995e60ad9bb02938461eee61 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6 a9965e82dd83d04a0256ace66cc0b13382b5abcb7cbf9aa3996cb966c3bd3cee867999b920a30bfc48a783264d4e79ce +dc71f171a28bdc30968c39f08f999b88dc04c550e261ecf1124d67f05edeae7e87fe9b8135a96fe2bc3996a4f47213d9d191184a76bd6310e1ee5cb67ea7fc3ef6f641a0ba165198040fa668192b75a4754fc02c224bd4a74aade5a8c814adf151c2bfeda65165a04ef359e39847c84e312afb66d4cd1db50d41ef3fe5f31296 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7 97d98b38e3531544fda3ee60a87da7356bf29c213cc6b7bd644797df91ca02313ad8ed2aa49e3cb55242b78f3d23cb10 +b895788d7828aaeace4f6b61a072ffa344d8ea324962ba6dab5efda93f65bf64a0f2ac6d5721d03ee70e2aef21cdba69fd29040199160e3a293b772ffb961ed694a8dc82800dab79367a4809a864e4aff6bc837aaa868e952b771b76591c0bb82249034e3208e593d85973d3fea753a95b16e221b2561644535c0131fe834ae7 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e a04deedcfb19bf8bf53bb99c4169d12c1540bd64cf8a227eccb3a82e9d3b0f45dff63d3bb7c6863eed85a584e502b589 +2c5bd848c476e34b427cfe5676692e588e1957957db7b5704492bd02104a38216535607f5d092dc40020130c04a3aaf0f1c52409834926d69a05d3f3188187a71d402a10ba34eac8629b4c6359b1095f30f710219298bf06b9f19bfc299981d7e251ca232a0a85338a7e02464731d1b25d4a1f68baf97064516590644820c998 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938 ab95be870ad54f6f49499819a1dceaa98bf0535062d6e0063c61db20d426a15e7ea8c25efbb34702930d6ca30516136b +65a0b97048067a0c9040acbb5d7f6e2e6ac462e1e0064a8ce5b5bbf8e57059e25a3ef8c80fc9037ae08f63e63f5bdb9378c322ad9b2daf839fad7a75b1027abb6f70f110247da7e971c7c52914e5a4f7761854432fa16b2a521e7bcaee2c735a87cad20c535bf6d04a87340c229bf9af8647eedca9e2dc0b5aa90f7fea3cdc0a 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662 82cf31f5e6b62080c3e3de6000c22be12f415ca89d3790e4362b7de022d8f951d70fb3a68a7c6c13e26904363dedca0e +d6e366a87808eea5d39fe77cac4b8c754e865a796062e2ec89f72165cd41fe04c48148068c570e0d29afe9011e7e7a2461f4d9897d8c1fa14b4ff88cab40059d17ab724f4039244e97fcecb07f9ffeec2fb9d6b1896700fe374104a8c44af01a10e93b268d25367bf2bef488b8abcc1ef0e14c3e6e1621b2d58753f21e28b86f 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721 b10343067c635062962e6acc32bde77a767707d8b61cd91f9d47baf4c161474e6c040f65c456a692220b339c77ed06e6 +f99e1d272d0f5fb9c4f986e873d070ec638422bc04b47c715595e2cf1a701cdf88bc6c4b20085b357bad12ccba67cac8a5ca07f31ba432f9154ff1fadefd487a83a9c37e49fb70a2f170e58889cab0552e0a3806ccfa2a60d96e346851d84b7de6d1a4b8cf37567dc161a84f13421e3412457d4bc27f6213453c8519a2d7daa2 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e 8d673cd46c860b5b86e5316af21e29dcba34fbb0e8bd0bd10e96ea924e6558b0c6f874d51d1b6466a4fce868f981b90b +91f1ca8ce6681f4e1f117b918ae787a888798a9df3afc9d0e922f51cdd6e7f7e55da996f7e3615f1d41e4292479859a44fa18a5a006662610f1aaa2884f843c2e73d441753e0ead51dffc366250616c706f07128940dd6312ff3eda6f0e2b4e441b3d74c592b97d9cd910f979d7f39767b379e7f36a7519f2a4a251ef5e8aae1 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418 aa067063d3983c5fcc19f9945dc370895ab1270be1f649e7f4caaa099a8c6934067d7d905ef4e6a21817d849b96cfe24 +dbc094402c5b559d53168c6f0c550d827499c6fb2186ae2db15b89b4e6f46220386d6f01bebde91b6ceb3ec7b4696e2cbfd14894dd0b7d656d23396ce920044f9ca514bf115cf98ecaa55b950a9e49365c2f3a05be5020e93db92c37437513044973e792af814d0ffad2c8ecc89ae4b35ccb19318f0b988a7d33ec5a4fe85dfe 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950 8fb71134e58d3877e331ffe5df58b84af8c073d3134c17325d02a2129421ed7003dbfeb4a0e20c038d8c775ab9b4a661 +114187efd1f6d6c46473fed0c1922987c79be2144439c6f61183caf2045bfb419f8cddc82267d14540624975f27232117729ccfeacccc7ecd5b71473c69d128152931865a60e6a104b67afe5ed443bdbcdc45372f1a85012bbc4614d4c0c534aacd9ab78664dda9b1f1e255878e8ac59e23c56a686f567e4b15c66f0e7c0931e 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b 949d54eac2eae26811efdff9421eb0d484dbb5e9c49aaaba433a6f0e0d225c87d3642349cd35b54c6aa0d8e17a13c07b +6744b69fc2420fe00f2352399bd58719e4ecdd6d602e2c80f194d607e58b27a0854745bfd6d504de2eb30b04cee0f44af710dd77e2f816ac3ac5692fad2d1d417893bb0edba2707a4c146a486f8728ca696d35cc52e9c7187c82d4bdb92eb954794e5ad15133f6bfea1f025da32ada710a3014cf11095b3ff69a94d087f17753 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f af3249ab0520c2bf9c0821d9f91d1a796d6a5a5f51b5ceead883b4dbab749722d47f28305d577fad2e31a6179f6a1e14 +16001f4dcf9e76aa134b12b867f252735144e523e40fba9b4811b07448a24ef4ccf3e81fe9d7f8097ae1d216a51b6eefc83880885e5b14a5eeee025c4232319c4b8bce26807d1b386ad6a964deb3bdca30ee196cfdd717facfad5c77d9b1d05fdd96875e9675e85029ecbf4f94c524624746b7c42870c14a9a1454acf3354474 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66 84869db19b5658871f0ef946d82dcb9a96c91323e7862587fc15970611a8c086c7ad26f2cb11d6d3f33c79fa38523571 +a9824a7b810aa16690083a00d422842971baf400c3563baa789c5653fc13416111c0236c67c68e95a13cec0df50324dcc9ae780ce4232607cb57dd9b2c61b382f0fa51fd4e283e2c55ffe272597651659fbd88cd03bfa9652cd54b01a7034c83a602709879e1325c77969bebfd93932ce09a23eae607374602201614ff84b141 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c 8e023507f910a8a71a3796631ab9adef4b74f57cf00155cfa8a0ab82c7c64b44f3c9bf069bcd4d3d8cf8428a724822e3 +90d8bbf714fd2120d2144022bf29520842d9fbd2dc8bb734b3e892ba0285c6a342d6e1e37cc11a62083566e45b039cc65506d20a7d8b51d763d25f0d9eaf3d38601af612c5798a8a2c712d968592b6ed689b88bbab95259ad34da26af9dda80f2f8a02960370bdb7e7595c0a4fffb465d7ad0c4665b5ec0e7d50c6a8238c7f53 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0 93fd18b7821959549032fc19f4b719f8c422165a952052944c3a2d4751f36c53e9e9dc789729a52bdf4d7cc1fc59406e +09952b1e09995e95bf0022e911c6ab1a463b0a1fdd0eec69117b34af1103c720b57600217de7cd178fef92de5391e550af72a8dcf7badf25b06dd039417f9a7d0f5be88fcd4e9655931d5b605452a667c9d1bae91d3476e7d51cff4108f116a49966fb3a7cff8df1c09734ce5620faf2dccb3dc5d94e7e9ac812da31f6d07a38 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9 92710335056ab6cf6d57c20c6b5729d44513a676bae09b4ae6d2507736cb800a0a9ffe62aee5d2b366e2794106da67e8 +0bb0f80cff309c65ff7729c59c517d50fc0ed5be405ef70cb910c3f62c328c90853d4473530b654dda6156e149bc2222a8a7f9be665240e2fbe9d03f78a2356af0bacd1edb84c4801adc8293a8a0bd6123d1cf6ba216aca807a7eb4dca76b493eb6e3dbb69d36f0f00f856222f24d9b93ec34c3b261be2fca0451c00571928e5 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d b5dd8c7e732c56c41a73c66208b9488732d89bedae49bf9f6e75430f768d802dab6ce9937d24829dbf4ee63417ef5923 +7efacf213382ce30804e78b7256854d759147dba9729c51b2759465715bf2c421034c23dc651c13d6cce95f71fe6a84dfbee5768163ac5789ac0474c5ddf4115684683c5f7c204b33b8bcc0c03ac58f66cef2f53b721fe2fac91ad841126101a88f512a7c2ded38549d9f050d4b7961dda48a1489f026c5d111701762418cfe3 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490 801d4574ebb92847441da82a284ea6c63d70a973cfa9d9d7730cd96c7e9aa2f500ea8d7b765c1840f89b0ebcd5cfc8c9 +28edff8b9d85f5f58499cc11f492abdfab25e8945975bbaeee910afa2b8fc1295ec61406309ce4e09f4ab4f462959fc2a2786802466eb26d3b01be6919893ae75d0fdc2dc8a82e662550f9fce9627dd364188aaba5c6faa1b2d8a2235adfa5ad0dc140f88a2b2f103f5690e877d07fe8fd30d02d2b2729bd3d8eb5b23a21f54c 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1 9014cd0f726e71e3faf6a81ebcfdb343a0f150616ea87670eab9c0abd59625af49df026c419279327abee973db076950 +bae2a8897c742fd99fbf813351cd009d3f2e18d825ca22e115276484bce8f82f8c7c0c21dd2af208404d8ef45bb5a6c41693912b630897d5246801bf0775aa9bbac8be98cb861d172c3563dc59e78a58ed13c66dea496471b3ad0eeae8995293e4ab97373edc1837ffc95ff1cc0c1e90e64ea8680b2ca5f1e09bf86b99b343b6 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745 b29ac2a6e8b69e463359d2f6e6e775cc55c64c62410309deba4cb109ead6e095ddef0f25cddf56a5a72793e1276aa0a2 +d57a26a9593e72bfc87322524639bcaae5f2252d18b99cdaa03b14445b0b8a4dd53928f66a2e4f202fb25b19cad0eb2f1bfda2ab9b0eb668cdcd0fe72f5d9ef2e45e0218590f7ab9d2c9342202610c698bc786cce108a7d4a6730a13e9ea1b470e781f1237d3f84f44abde808516975546bd89075ef9a9732bfd7ee33b6f4399 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f a8c601015cc0f66e0543b332c4a165fcfd607648e2a9cdd987a445fddaa2d654b9c3fbd4df4f065ee0bda8f8f040408e +8fdcf5084b12cfc043dd3416b46274e021bbed95d341d3c500c102a5609d3a34de29f8fa9f0adb611a1f47a97ad981f8129d718fc0d6c709eab1a3490db8d550f34eb905b9e00663543afc5bc155e368e0bc919a8b8c9fa42093603537a5614927efa6be819ed42ececbf1a80a61e6e0a7f9b5bc43b9238e62d5df0571fea152 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e 9396743b4e48dbd3a63867bfcdf9951fb49d9ff92a6541bfa7b9adc595e04ff9659a3231b30a0502cba6d38219f4e8eb +00669f433934992257bed55861df679804107d7fa491672574a7624949c60049b0533383c88d6896c8de860704c3e6a6aefce83efa57c4d57e9ab253da5d15e1f53ab6dce218b592772ab0bc01fee8e63368e85c0639301456fe2d44cd5396a7f2b22761cd03b80eba7883eede8249a2f5db2183bf00550c5c002f45a5e4fb31 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89 a33869e420fd80cd3047ed372fa0c5fbe87ac1c094603887425c4f4a958a3601336b038bae6db0298b40536f2d1b1ccc +4be81dcfab39a64d6f00c0d7fff94dabdf3473dc49f0e12900df328d6584b854fbaebaf3194c433e9e21743342e2dd056b445c8aa7d30a38504b366a8fa889dc8ecec35b3130070787e7bf0f22fab5bea54a07d3a75368605397ba74dbf2923ef20c37a0d9c64caebcc93157456b57b98d4becb13fecb7cc7f3740a6057af287 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a 97be781a35a841416867255b03543304fd39e45d1c7a969110ed1fa7a77bac268a3b015df2fd926cb815018435136131 +9ecd500c60e701404922e58ab20cc002651fdee7cbc9336adda33e4c1088fab1964ecb7904dc6856865d6c8e15041ccf2d5ac302e99d346ff2f686531d25521678d4fd3f76bbf2c893d246cb4d7693792fe18172108146853103a51f824acc621cb7311d2463c3361ea707254f2b052bc22cb8012873dcbb95bf1a5cc53ab89f 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926 9144f4ee73e47940577033b085aa2a63bd4d4d890bbd4b1f8ff0e88082741f51b7750561019ed451498a2388fb00d41e +b3c63e5f5a21c4bfe3dbc644354d9a949186d6a9e1dd873828782aa6a0f1df2f64114a430b1c13fe8a2e09099e1ed05ef70de698161039ded73bcb50b312673bb073f8a792ac140a78a8b7f3586dffb1fc8be4f54516d57418ccc9945025ce3acf1eb84f69ceee5e9bd10c18c251dbc481562cd3aae54b54ab618cb1eeda33cf 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6 a3af503ae9df5887054112dde46c8e5e92bbdb97bfc294671d098d290ff416c142e3c9b92a003b8c1d5afc4e43a92a3f +6e0f96d56505ffd2d005d5677dbf926345f0ff0a5da456bbcbcfdc2d33c8d878b0bc8511401c73168d161c23a88b04d7a9629a7a6fbcff241071b0d212248fcc2c94fa5c086909adb8f4b9772b4293b4acf5215ea2fc72f8cec57b5a13792d7859b6d40348fc3ba3f5e7062a19075a9edb713ddcd391aefc90f46bbd81e2557b 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f 935c1c3b785e78eaa4fc4d9570b5d79ec3d4f16be60e330f6eb945e4b32f021d86cddadf7b3fd6c4f0402313b43edcb0 +3f12ab17af3c3680aad22196337cedb0a9dba22387a7c555b46e84176a6f8418004552386ada4deec59fdabb0d25e1c6668a96f100b352f8dabd24b2262bd2a3d0f825602d54150bdc4bcbd5b8e0ca52bc8d2c70ff2af9b03e20730d6bd9ec1d091a3e5c877259bcff4fd2c17a12bfc4b08117ec39fe4762be128d0883a37e9d 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742 a55fd7c5cfe99c87ddfcc8a4c3c4d58c069d1c37a5825975010e41d9a1355d69b23c74d1b4d1381da5e1cb09f23bcd53 +a1eed24b3b7c33296c2491d6ee092ec6124f85cf566bb5bc35bffb5c734e34547242e57593e962fb76aee9e800eed2d702cc301499060b76406b347f3d1c86456978950737703c8159001e6778f69c734a56e5ce5938bd0e0de0877d55adeee48b0d8dfa4ac65fd2d3ce3e12878bac5c7014f9284d161b2a3e7d5c88569a45f6 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697 b044bd2730fc2723ae1ef955dda011cb2d23f1d25ce1e436d989f64ed3410887243fb488f566b2e425ac967d42f94451 +9aace26837695e6596007a54e4bccdd5ffb16dc6844140e2eeeb584b15acb2bbffd203c74440b6ee8db676fd200b4186a8c3e957c19e74d4d865ada83f80655323dfa3570907ed3ce853b6e8cc375ed2d758a2f5ad265dd3b47650517a49b3d02df9e0c60c21576378c2b3a08481eec129b2a75608e13e6420127a3a63c8a3f1 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04 aa0e2b68426f548d8aba237d29df792099fe34f41acac9946396ea305878a1de85a797f60c0956306b29844c82ae661b +ac2175940545d4fbab6e2e651c6830aba562e0c11c919e797c43eff9f187a68a9e5a128e3e2a330b955a3f4577d3f826529ad1b03d7b60f7ad678f005053b41dc0f8d267f3685c6abe1a0e9a733c44b2f3ca48b90806f935141c842e3a6c06a58f5343d75e3585971a734f4ae1074ce5b54f74bd9342f4bbca738d260393f43e 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6 89cfa62944ae396e591e2180da9b6f884c511f797840d01eb505a049a4326f944e8be907a990f486a9e04af951d48c24 +6266f09710e2434cb3da3b15396556765db2ddcd221dce257eab7399c7c490135925112932716af1434053b8b9fe340563e57a0b9776f9ac92cbb5fba18b05c0a2fafbed7240b3f93cd1780c980ff5fe92610e36c0177cabe82367c84cee9020cf26c1d74ae3eb9b9b512cb8b3cb3d81b17cf20dc76591b2b394ef1c62ac12ee 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e 94bec11f89928bbfe9e6b3b0dd46b40d123dc1ed76626d81d76675c03735275f963d43a9d7b8cfbdab098400723b8991 +3de9e617a6868dca1a1432d503f923535da3f9b34426b2a4822174399c73b1c1ee67311410a58c17202ac767844b2024d8aa21a205707d93865693ac25a24fc87034fa3a7a7e27c3344cb03b87602c15180a5fe6a9dd90cd11af4a0f150207bf2d83f55b12c088adae99aa8cfa659311b3a25beb99056643760d6a282126b9b2 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5 992e85c90f03b1cda2af63a1178c07075331e24d013d58f5e417cd576c655b77523243310331bee6de6c6c259f0f9a72 +aa48851af7ef17abe233163b7185130f4646203c205e22bcc2a5a3697bcab998c73a9ffe1d3ea0b7978ce7df937a72586eb5ca60b0d939a7d1c115c820171c89c8116b7e2c7b98cf0f14e4c4df3cb2f319ad3ab0ea25ff14526ddc037469f000bf82100acd4cdf94feb4eba4ea1726f0569336604a473aee67d71afebb569209 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a b8863a5012dd948374c2cb2d7aff119ed216a01d562215131f88aecd12ca2a365ff70f90b7dbd93c64390d172b83f877 +b0d5d52259af364eb2d1a5027e5f7d0afe4b999cc5dd2268cfe76f51d2f17b541bdd7867e23a1bb897705153d9432a24012108979c6a2c9e2567c9531d012f9e4be764419491a52eae2e127430b0ab58cb8e216515a821b3db206447c235bf44ee304201b483b2a88844abaa18bca0147dfff7e502397dd62e15524f67eb2df2 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb b36e7af4780cec76e1733a112c7959643cd5b26d2f94d5e582c98c7c66cfe807a9991de77d69fc1bd67baeedcee02090 +9599788344976779383a7a0812a096943a1f771ee484d586af1a06207478e4c0be9c200d42460fe837e24b266c8852d80d3c53cc52ffb1913fc3261145fc6da575611efd16c026059a2e64f802517ffd1b6b34de10ad2909c65c2155e8d939b8115400c1d793d23955b15f5d1c13c962ff92b4a815cee0e10f8e14e1f6e6cd38 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77 a9fd424580c7becf67f8ebbef57e7137ee9764869aebfe6e6ed7c70e20acf8da32e7b3c9bd64c210a2ce4b0a9342ef9f +fdde51acfd04eb0ad892ce9d6c0f90eb91ce765cbe3ce9d3f2defe8f691324d26b968b8b90e77706b068585f2a3ee7bf3e910528f7403c5af745a6f9d7ba6c53abd885c3b1be583415b128f4d3f224daf8563476bd9aa61e9c8518c144335f8f879c03696bddbe3ac37a8fbede29861611feaa87e325e2f60278b4893ed57fb0 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c 8b9635a34b822baf9ee7ed3e591e303fca838f1e12fb28e91d7ce590b6429396ea641a68d98014e091bd2d3851cb4466 +beb34c997f905c77451ac392f7957a0ab8b23325bd5c63ca31c109ac8f655a1e3094240cb8a99284f8091de2ab9a7db2504d16251980b86be89ec3a3f41162698bab51848880633e0b71a38f8896335853d8e836a2454ecab2acdcc052c8f659be1d703b13ae1b090334ac50ab0137ddb5e8b924c0e3d2e5789daaef2fdd4a1e 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63 a12c78e78e4df17a483b97b4c54dbec839c14db7ce31fa7b85f6298605061d0cf993f05292b8f84a5e2e97a96f18e117 +543c374af90c34f50ee195006d5f9d8dd986d09ad182fcbefa085567275eee1e742bfe0af3d058675adeb5b9f87f248b00a9fbd2aa779129123a5b983f2f26fc3caf2ea34277550c22fe8c814c739b46972d50232993cddd63a3c99e20f5c5067d9b57e2d5db94317a5a16b5c12b5c4cafbc79cbc2f9940f074bbc7d0dc71e90 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da a3d9d3e2785b57373e8d68c65d6983bc21456993e8c009546038fec63e790d09725af327ced771c5b88488c84c88ab7a diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P521_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P521_blst new file mode 100644 index 000000000000..0c675c1fee2e --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_fips_186_3_P521_blst @@ -0,0 +1,60 @@ +58ec2b2ceb80207ff51b17688bd5850f9388ce0b4a4f7316f5af6f52cfc4dde4192b6dbd97b56f93d1e4073517ac6c6140429b5484e266d07127e28b8e613ddf65888cbd5242b2f0eee4d5754eb11f25dfa5c3f87c790de371856c882731a157083a00d8eae29a57884dbbfcd98922c12cf5d73066daabe3bf3f42cfbdb9d853 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46 8e40854aa0dd82d5e15d5fa16e297c5d7a1851cf19a8aacbac6b7530fdfcace5506c1e50405a4345d0fafa855894a969 +2449a53e0581f1b56d1e463b1c1686d33b3491efe1f3cc0443ba05d65694597cc7a2595bda9cae939166eb03cec624a788c9bbab69a39fb6554649131a56b26295683d8ac1aea969040413df405325425146c1e3a138d2f4f772ae2ed917cc36465acd66150058622440d7e77b3ad621e1c43a3f277da88d850d608079d9b911 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73 8716f3c7e18478d817a248d0cb45d0f39d9a8744fc69430e011cc66cbef5791d0a617c975715fcdf423d935a3843f68d +7ba05797b5b67e1adfafb7fae20c0c0abe1543c94cee92d5021e1abc57720a6107999c70eacf3d4a79702cd4e6885fa1b7155398ac729d1ed6b45e51fe114c46caf444b20b406ad9cde6b9b2687aa645b46b51ab790b67047219e7290df1a797f35949aaf912a0a8556bb21018e7f70427c0fc018e461755378b981d0d9df3a9 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace b252a9c36f070c1e62d8b0d11312b86a7bd5fd5a5baa55af1bbc1ccb11088b1febfe3f008c5272322f359b59eef08a64 +716dabdb22a1c854ec60420249905a1d7ca68dd573efaff7542e76f0eae54a1828db69a39a1206cd05e10e681f24881b131e042ed9e19f5995c253840e937b809dfb8027fed71d541860f318691c13a2eb514daa5889410f256305f3b5b47cc16f7a7dad6359589b5f4568de4c4aae2357a8ea5e0ebaa5b89063eb3aa44eb952 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc 8125efccc447a29c074308cf4521192ffac0820401706de40bcfa493be11fa76f82d28f862465c32688d2e10c835a4ab +9cc9c2f131fe3ac7ea91ae6d832c7788cbbf34f68e839269c336ceef7bef6f20c0a62ea8cc340a333a3002145d07eba4cf4026a0c4b26b0217a0046701de92d573d7c87a386a1ea68dc80525b7dcc9be41b451ad9f3d16819e2a0a0b5a0c56736da3709e64761f97cae2399de2a4022dc4c3d73c7a1735c36dbde86c4bc5b6f7 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549 974aeda4e9c92867a8b3254aac3369a6404c8af2cf0f2431b715043ef9f82e53dbb810fcfc4de32f4c2edb70b354bbb7 +14c69f8d660f7a6b37b13a6d9788eff16311b67598ab8368039ea1d9146e54f55a83b3d13d7ac9652135933c68fafd993a582253be0deea282d86046c2fb6fd3a7b2c80874ced28d8bed791bd4134c796bb7baf195bdd0dc6fa03fdb7f98755ca063fb1349e56fd0375cf94774df4203b34495404ebb86f1c7875b85174c574c 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4 b3f2a1cb5a9bb8a3363957aa3966a1969438a4cb1937acf980549ccc5e15f1f2eccd023c3b9ff67fbc9966c3bffb4c29 +8d8e75df200c177dbfe61be61567b82177ea5ec58e2781168d2277d2fd42668f01248ca3eb29ffa2689b12ae40f9c429532b6d2e1f15891322b825a0a072a1c68fa09e78cfdef3e95ed6fdf7233a43cb68236560d49a3278f0b3f47cb08f475bd9ab2f60755ea4a1767de9313b71a1b9ea87ef33f34682efbda263b0f8cc2f52 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16 b5f0cda1f0c35113082c564816e2710db5d0275179ed5eaecd18ed6a77ca613c3e53fd16c9b986b2325120c86c1b0a7e +10631c3d438870f311c905e569a58e56d20a2a560e857f0f9bac2bb7233ec40c79de145294da0937e6b5e5c34fff4e6270823e5c8553c07d4adf25f614845b2eac731c5773ebbd716ab45698d156d043859945de57473389954d223522fbafecf560b07ef9ba861bcc1df9a7a89cdd6debf4cd9bf2cf28c193393569ccbd0398 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37 958524653cc127e6d9be2608d122f25c06129761b1a3eba34fe34844325a8f87bbca10354b1e243191357a7ceb635f7f +80aad6d696cbe654faa0d0a24d2f50d46e4f00a1b488ea1a98ed06c44d1d0c568beb4ab3674fc2b1d2d3da1053f28940e89ba1244899e8515cabdd66e99a77df31e90d93e37a8a240e803a998209988fc829e239150da058a300489e33bf3dcdaf7d06069e74569fee77f4e3875d0a713ccd2b7e9d7be62b34b6e375e84209ef 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256 8ddbc293a7ddf6870f5af40047c79c4a6aa4f4f37a85af44016c94556d9ad54ed88e21e68ac8932b7820efe129e49c14 +8a7792a2870d2dd341cd9c4a2a9ec2da753dcb0f692b70b64cef2e22071389c70b3b188dea5f409fb435cbd09082f59de6bc2ff9e65f91b7acc51e6e7f8e513148cb3c7c4664f227d5c704626b0fda447aa87b9d47cd99789b88628eb642ed250312de5ba6b25f3d5342a3cbb7ebd69b0044ee2b4c9ba5e3f5195afb6bea823d 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7 8a26177969ee52e9fbdd744ade3bcef78aceeb4cf3ab5ee7dedff1079aac8d98aeac0fab83b2f696903f242bdfce0f7a +f971bcd396efb8392207b5ca72ac62649b47732fba8feaa8e84f7fb36b3edb5d7b5333fbfa39a4f882cb42fe57cd1ace43d06aaad33d0603741a18bc261caa14f29ead389f7c20536d406e9d39c34079812ba26b39baedf5feb1ef1f79990496dd019c87e38c38c486ec1c251da2a8a9a57854b80fcd513285e8dee8c43a9890 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73 a5a99b43d7e2fe62266c090e113e79d84b8db879823846711fae76d2eaf01a37a019242710033eb0b39bd578335aea74 +ec0d468447222506b4ead04ea1a17e2aa96eeb3e5f066367975dbaea426104f2111c45e206752896e5fa7594d74ed184493598783cb8079e0e915b638d5c317fa978d9011b44a76b28d752462adf305bde321431f7f34b017c9a35bae8786755a62e746480fa3524d398a6ff5fdc6cec54c07221cce61e46fd0a1af932fa8a33 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c b92b0d10d5b721163127ad068bcc8439b2f42c162f28a65831128d4b31cc5fc27799108eaea8bc737da453dbc1133225 +d891da97d2b612fa6483ee7870e0f10fc12a89f9e33d636f587f72e0049f5888782ccde3ea737e2abca41492bac291e20de5b84157a43c5ea900aef761006a4471072ab6ae6d515ffe227695d3ff2341355b8398f72a723ae947f9618237c4b6642a36974860b452c0c6202688bc0814710cbbff4b8e0d1395e8671ae67ada01 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace a40d7b10018d2277e032cd415ee4de63cefc5a274e6b204b6ee3e446bed6165ff3f2da1c8ecc83c04bc8b268d29faf91 +924e4afc979d1fd1ec8ab17e02b69964a1f025882611d9ba57c772175926944e42c68422d15f9326285538a348f9301e593e02c35a9817b160c05e21003d202473db69df695191be22db05615561951867f8425f88c29ba8997a41a2f96b5cee791307369671543373ea91d5ed9d6a34794d33305db8975b061864e6b0fe775f 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8 861b7ed19c91bb93c50cd4b15fde719f0ff44cffd7e48205de7e47cfb3598b56522dffdf25bb088fc88742f2c7391415 +c64319c8aa1c1ae676630045ae488aedebca19d753704182c4bf3b306b75db98e9be438234233c2f14e3b97c2f55236950629885ac1e0bd015db0f912913ffb6f1361c4cc25c3cd434583b0f7a5a9e1a549aa523614268037973b65eb59c0c16a19a49bfaa13d507b29d5c7a146cd8da2917665100ac9de2d75fa48cb708ac79 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad 8a540279b8d287d9f5fe1b64c98fed10c2aca70c3de7efdd50f42c5d42afb90dbefad398c08880eb770ae81982ec2919 +8ab8176b16278db54f84328ae0b75ef8f0cd18afdf40c04ad0927ed0f6d9e47470396c8e87cde7a9be2ffbfe6c9658c88b7de4d582111119c433b2e4a504493f0a1166e3a3ea0d7b93358f4a297d63f65a5e752f94e2ee7f49ebcc742fa3eb03a617d00c574245b77a20033854d82964b2949e2247637239ab00baf4d170d97c 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a b2419fe0d02c623c79d57f9c4a8f08b1d9d3f11a5ebcde268935d4c1b17038fd64fda0d47c569b9f69300d13411b2347 +c4bc2cec829036469e55acdd277745034e4e3cc4fcd2f50ec8bd89055c19795a1e051ccf9aa178e12f9beab6a016a7257e391faa536eaa5c969396d4e1ade36795a82ebc709d9422de8497e5b68e7292538d4ccdc6dd66d27a3ece6a2844962b77db073df9489c9710585ba03d53fa430dbc6626dc03b61d53fc180b9af5dea6 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c 8ccb8592423a4e85b18aaa119e56c90a699a100be20db3d6dc3316227d191d74858a99163aa5500dcb372f45d5efe051 +1c1b641d0511a0625a4b33e7639d7a057e27f3a7f818e67f593286c8a4c827bb1f3e4f399027e57f18a45403a310c785b50e5a03517c72b45ef8c242a57b162debf2e80c1cf6c7b90237aede5f4ab1fcaf8187be3beb524c223cc0ceff24429eb181a5eea364a748c713214880d976c2cd497fd65ab3854ad0d6c2c1913d3a06 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d 86e0b68bcb132414bd0322b8e9b1f3607754c1628f404d17234d1edc80a98d8948806541e4a9084caf9b797c77110c72 +adb5f069b2b501a3ebb83d4f1808eb07710ac4a7b12532996855a20bcc54b2f76812915f632163c3654ff13d187d007152617cf859200194b59c5e81fc6cc9eb1ceb75d654050f260caa79c265254089270ccd02607fdcf3246119738c496dc3a4bd5d3be15789fc3d29a08d6d921febe2f40aef286d5d4330b07198c7f4588e 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c b6fb1a9146ad4dbec128f5f2d7a0a1023eaeb41f84fe37268caeb9499f87882028ff5b3d7d1e4e8ba45e272a1f59bac3 +f253484d121d1ce8a88def6a3e9e78c47f4025ead6f73285bf90647102645b0c32d4d86742a50b8b7a42d5f6156a6faf588212b7dc72c3ffd13973bdba732b554d8bffc57d04f8167aef21ee941ee6ffb6cce0f49445bd707da8deb35dca650aaf761c3aa66a5ebccddd15aee21293f63061a7f4bfc3787c2cd62c806a1a9985 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25 84b54ca5ed19fa1552c77c917477c16fc588d7a5ecddc60a0f792f53749574cdaf4d27fde75cdb5d81441c9d74032406 +33bab1c369c495db1610965bc0b0546a216e8dd00cd0e602a605d40bc8812bbf1ffa67143f896c436b8f7cf0bed308054f1e1ff77f4d0a13c1e831efbd0e2fcfb3eadab9f755f070ba9aeaceb0a5110f2f8b0c1f7b1aa96a7f2d038a1b72e26400819b1f73d925ea4e34d6acaf59d0a461a34ce5d65c9c937a80e844e323a16d 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf a1385e9ca3516ef69ff1cb9f40eb1f673665c05b395cdfa99d2d455e41d446e88b3c192f502145e617a97924545c6fb3 +08c8b7faaac8e1154042d162dca1df0f66e0001b3c5ecf49b6a4334ce4e8a754a1a8e4daf8ec09cf1e521c96547aed5172ef852e82c03cddd851a9f992183ac5199594f288dbcc53a9bb6128561ff3236a7b4b0dce8eaf7d45e64e782955ee1b690ce6a73ece47dc4409b690de6b7928cbe60c42fc6a5ddf1d729faf1cc3885e 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570 96b08e2fd5f75435c48df68a2952a27285075b96645e4ec8b45de704bbbda77301b97610d4d04171c65f746cc365fb5e +ba74eed74282811631bd2069e862381e4e2a1e4e9a357b1c159a9ce69786f864b60fe90eeb32d8b72b099986fc594965a33285f7185b415df58fead7b8b50fc60d073680881d7435609ad1d22fd21e789b6730e232b0d2e888889fb82d6ad0337ab909308676164d4f47df44b21190eca8ba0f94995e60ad9bb02938461eee61 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6 833b861f2bb2b5a781c22e0e1b209296537a05dd527bc53176483855dbb7b7d4041c7f1f20621f6b570cefc4850746ce +dc71f171a28bdc30968c39f08f999b88dc04c550e261ecf1124d67f05edeae7e87fe9b8135a96fe2bc3996a4f47213d9d191184a76bd6310e1ee5cb67ea7fc3ef6f641a0ba165198040fa668192b75a4754fc02c224bd4a74aade5a8c814adf151c2bfeda65165a04ef359e39847c84e312afb66d4cd1db50d41ef3fe5f31296 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7 975a82d4535ad3c66feda735ff0e198b55adc3f619748b965dcce0373a904cef03f9ef3fcc759d4f4a57a18df57c65b8 +b895788d7828aaeace4f6b61a072ffa344d8ea324962ba6dab5efda93f65bf64a0f2ac6d5721d03ee70e2aef21cdba69fd29040199160e3a293b772ffb961ed694a8dc82800dab79367a4809a864e4aff6bc837aaa868e952b771b76591c0bb82249034e3208e593d85973d3fea753a95b16e221b2561644535c0131fe834ae7 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e 9840d42a5c15d0df23511774176a7b3f2822468b04c2a7a425d2fc7d9dec2fb318e7361974d60d562e2078d583457abc +2c5bd848c476e34b427cfe5676692e588e1957957db7b5704492bd02104a38216535607f5d092dc40020130c04a3aaf0f1c52409834926d69a05d3f3188187a71d402a10ba34eac8629b4c6359b1095f30f710219298bf06b9f19bfc299981d7e251ca232a0a85338a7e02464731d1b25d4a1f68baf97064516590644820c998 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938 a5500c99d975cc20f0142f723228039519eadc4dd5e2b32ef10af7c91d90caaca3930cfa067a7a3a6f03bd162ed6da81 +65a0b97048067a0c9040acbb5d7f6e2e6ac462e1e0064a8ce5b5bbf8e57059e25a3ef8c80fc9037ae08f63e63f5bdb9378c322ad9b2daf839fad7a75b1027abb6f70f110247da7e971c7c52914e5a4f7761854432fa16b2a521e7bcaee2c735a87cad20c535bf6d04a87340c229bf9af8647eedca9e2dc0b5aa90f7fea3cdc0a 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662 a1ee3751289b00bd1244a9a812a0119cae76d0ec7c5aeb4625f601a05e2d2377f3383499c89f747b6398f9d9a236219a +d6e366a87808eea5d39fe77cac4b8c754e865a796062e2ec89f72165cd41fe04c48148068c570e0d29afe9011e7e7a2461f4d9897d8c1fa14b4ff88cab40059d17ab724f4039244e97fcecb07f9ffeec2fb9d6b1896700fe374104a8c44af01a10e93b268d25367bf2bef488b8abcc1ef0e14c3e6e1621b2d58753f21e28b86f 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721 b1db0d9e4efb0862bbe10da8503dfe0976df0cc86ef0ca8896a868b758416d4b8381f5ee46ad66d4a303a9099c65d410 +f99e1d272d0f5fb9c4f986e873d070ec638422bc04b47c715595e2cf1a701cdf88bc6c4b20085b357bad12ccba67cac8a5ca07f31ba432f9154ff1fadefd487a83a9c37e49fb70a2f170e58889cab0552e0a3806ccfa2a60d96e346851d84b7de6d1a4b8cf37567dc161a84f13421e3412457d4bc27f6213453c8519a2d7daa2 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e 81a9af62b57b5deb0e21ee7eeae865b9e1cc9304aca21b6fa5c9c71f33e64f03796f1eeb324234319303eee8e041b4ee +91f1ca8ce6681f4e1f117b918ae787a888798a9df3afc9d0e922f51cdd6e7f7e55da996f7e3615f1d41e4292479859a44fa18a5a006662610f1aaa2884f843c2e73d441753e0ead51dffc366250616c706f07128940dd6312ff3eda6f0e2b4e441b3d74c592b97d9cd910f979d7f39767b379e7f36a7519f2a4a251ef5e8aae1 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418 b04ec5a840ca35282e3ac0c3f666051b3f1c625cd97306da937601ddb78210d90101fab42ca24b7ae003e17291a84e5b +dbc094402c5b559d53168c6f0c550d827499c6fb2186ae2db15b89b4e6f46220386d6f01bebde91b6ceb3ec7b4696e2cbfd14894dd0b7d656d23396ce920044f9ca514bf115cf98ecaa55b950a9e49365c2f3a05be5020e93db92c37437513044973e792af814d0ffad2c8ecc89ae4b35ccb19318f0b988a7d33ec5a4fe85dfe 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950 b05f1de51a08e488d94676e2105af184d48e5876e28b76e2f69356f646f48872f02f220916d422fd7c855c4b72ba0fff +114187efd1f6d6c46473fed0c1922987c79be2144439c6f61183caf2045bfb419f8cddc82267d14540624975f27232117729ccfeacccc7ecd5b71473c69d128152931865a60e6a104b67afe5ed443bdbcdc45372f1a85012bbc4614d4c0c534aacd9ab78664dda9b1f1e255878e8ac59e23c56a686f567e4b15c66f0e7c0931e 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b 94cb27a52d8cb0cdeb3291a6049fac3bbce852efdbd5bba008c7c08370b89860121b46da02de670beff242cda706d647 +6744b69fc2420fe00f2352399bd58719e4ecdd6d602e2c80f194d607e58b27a0854745bfd6d504de2eb30b04cee0f44af710dd77e2f816ac3ac5692fad2d1d417893bb0edba2707a4c146a486f8728ca696d35cc52e9c7187c82d4bdb92eb954794e5ad15133f6bfea1f025da32ada710a3014cf11095b3ff69a94d087f17753 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f 99b80d6be518e4d5a652d364eb95e3e8aa916d75e017bc5e86bc26c7de477a860065c627923b24f65de0595ca4e194c6 +16001f4dcf9e76aa134b12b867f252735144e523e40fba9b4811b07448a24ef4ccf3e81fe9d7f8097ae1d216a51b6eefc83880885e5b14a5eeee025c4232319c4b8bce26807d1b386ad6a964deb3bdca30ee196cfdd717facfad5c77d9b1d05fdd96875e9675e85029ecbf4f94c524624746b7c42870c14a9a1454acf3354474 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66 89a98bc0f7555fc859984b16db0f4f12e190ba0153268e0a9fc3158b7166bc93bd3539844758d740f104391179eaab2b +a9824a7b810aa16690083a00d422842971baf400c3563baa789c5653fc13416111c0236c67c68e95a13cec0df50324dcc9ae780ce4232607cb57dd9b2c61b382f0fa51fd4e283e2c55ffe272597651659fbd88cd03bfa9652cd54b01a7034c83a602709879e1325c77969bebfd93932ce09a23eae607374602201614ff84b141 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c 9267423445a4350baaec10c4890c49d35b5fc3e212c2d61406ac8a39a7bf4ae1c37e431dd5ebdf484209b6a820736aa5 +90d8bbf714fd2120d2144022bf29520842d9fbd2dc8bb734b3e892ba0285c6a342d6e1e37cc11a62083566e45b039cc65506d20a7d8b51d763d25f0d9eaf3d38601af612c5798a8a2c712d968592b6ed689b88bbab95259ad34da26af9dda80f2f8a02960370bdb7e7595c0a4fffb465d7ad0c4665b5ec0e7d50c6a8238c7f53 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0 9969edc3587744e9fc88679a39f31d9999277837526de3199513d0d01375e569ccef4b12cdd62f39d8807104ad1620f3 +09952b1e09995e95bf0022e911c6ab1a463b0a1fdd0eec69117b34af1103c720b57600217de7cd178fef92de5391e550af72a8dcf7badf25b06dd039417f9a7d0f5be88fcd4e9655931d5b605452a667c9d1bae91d3476e7d51cff4108f116a49966fb3a7cff8df1c09734ce5620faf2dccb3dc5d94e7e9ac812da31f6d07a38 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9 830b74d443a83d159cd7022670707c0c07707939a750fe3f6c3e04276af07f894fa6198b8e2699604bb8e019f716d9d7 +0bb0f80cff309c65ff7729c59c517d50fc0ed5be405ef70cb910c3f62c328c90853d4473530b654dda6156e149bc2222a8a7f9be665240e2fbe9d03f78a2356af0bacd1edb84c4801adc8293a8a0bd6123d1cf6ba216aca807a7eb4dca76b493eb6e3dbb69d36f0f00f856222f24d9b93ec34c3b261be2fca0451c00571928e5 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d 8ab9197ce06dc38d2b3385c71b29018f6262ae2c8f78fb4563b934af0a610d34c5ddca2c7d328bf302618cf3097f10d0 +7efacf213382ce30804e78b7256854d759147dba9729c51b2759465715bf2c421034c23dc651c13d6cce95f71fe6a84dfbee5768163ac5789ac0474c5ddf4115684683c5f7c204b33b8bcc0c03ac58f66cef2f53b721fe2fac91ad841126101a88f512a7c2ded38549d9f050d4b7961dda48a1489f026c5d111701762418cfe3 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490 9636d1524c9aaf7a5c0cfda441516454f9a09673d607bf8fd0bb1d09d922a2281c4eff6a94b009837233d8458c9dc7ef +28edff8b9d85f5f58499cc11f492abdfab25e8945975bbaeee910afa2b8fc1295ec61406309ce4e09f4ab4f462959fc2a2786802466eb26d3b01be6919893ae75d0fdc2dc8a82e662550f9fce9627dd364188aaba5c6faa1b2d8a2235adfa5ad0dc140f88a2b2f103f5690e877d07fe8fd30d02d2b2729bd3d8eb5b23a21f54c 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1 b06ce974d56a651de9db629e17a9365d4cded9d06a0d43f70233779cc02273ae56fb2cc58805265ea823d47be578d59a +bae2a8897c742fd99fbf813351cd009d3f2e18d825ca22e115276484bce8f82f8c7c0c21dd2af208404d8ef45bb5a6c41693912b630897d5246801bf0775aa9bbac8be98cb861d172c3563dc59e78a58ed13c66dea496471b3ad0eeae8995293e4ab97373edc1837ffc95ff1cc0c1e90e64ea8680b2ca5f1e09bf86b99b343b6 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745 a20481de21cfa5d815af277206f2ada4555a58d2618492a731b940224f2035faf5acb6325554d74be67b598a0f3ef3c4 +d57a26a9593e72bfc87322524639bcaae5f2252d18b99cdaa03b14445b0b8a4dd53928f66a2e4f202fb25b19cad0eb2f1bfda2ab9b0eb668cdcd0fe72f5d9ef2e45e0218590f7ab9d2c9342202610c698bc786cce108a7d4a6730a13e9ea1b470e781f1237d3f84f44abde808516975546bd89075ef9a9732bfd7ee33b6f4399 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f a513639789dfc9353a3ef8a9999b591a856a18e07633382e8677bb7455c6ec17899401ea7e71516fdeb7e8b525459dc8 +8fdcf5084b12cfc043dd3416b46274e021bbed95d341d3c500c102a5609d3a34de29f8fa9f0adb611a1f47a97ad981f8129d718fc0d6c709eab1a3490db8d550f34eb905b9e00663543afc5bc155e368e0bc919a8b8c9fa42093603537a5614927efa6be819ed42ececbf1a80a61e6e0a7f9b5bc43b9238e62d5df0571fea152 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e 89b2612f7a5cfd8df0ac8da0ab4eaaf1e976ecdc66e7b01ae6719281af999ceb81c028ba7b88dbb8b3daa2f4c1d450eb +00669f433934992257bed55861df679804107d7fa491672574a7624949c60049b0533383c88d6896c8de860704c3e6a6aefce83efa57c4d57e9ab253da5d15e1f53ab6dce218b592772ab0bc01fee8e63368e85c0639301456fe2d44cd5396a7f2b22761cd03b80eba7883eede8249a2f5db2183bf00550c5c002f45a5e4fb31 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89 9582f049cf4f598fc8b818b908906820b3bd24ade1940350861621b479cb1b5b351164d4362d63f61fd33521661f0363 +4be81dcfab39a64d6f00c0d7fff94dabdf3473dc49f0e12900df328d6584b854fbaebaf3194c433e9e21743342e2dd056b445c8aa7d30a38504b366a8fa889dc8ecec35b3130070787e7bf0f22fab5bea54a07d3a75368605397ba74dbf2923ef20c37a0d9c64caebcc93157456b57b98d4becb13fecb7cc7f3740a6057af287 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a 87d90f8c0f27f46489e7470622eae6756f60c04c7c69cab8344465d7e321433865e8efd46e121ed08bd64f61309db8e7 +9ecd500c60e701404922e58ab20cc002651fdee7cbc9336adda33e4c1088fab1964ecb7904dc6856865d6c8e15041ccf2d5ac302e99d346ff2f686531d25521678d4fd3f76bbf2c893d246cb4d7693792fe18172108146853103a51f824acc621cb7311d2463c3361ea707254f2b052bc22cb8012873dcbb95bf1a5cc53ab89f 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926 93b77600c859843953c66eadb8abee1c32227f5862dc80881b063bc4e480812f5e61e4a11d812352002d5157111bb6bc +b3c63e5f5a21c4bfe3dbc644354d9a949186d6a9e1dd873828782aa6a0f1df2f64114a430b1c13fe8a2e09099e1ed05ef70de698161039ded73bcb50b312673bb073f8a792ac140a78a8b7f3586dffb1fc8be4f54516d57418ccc9945025ce3acf1eb84f69ceee5e9bd10c18c251dbc481562cd3aae54b54ab618cb1eeda33cf 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6 8b2d24ac6ed5b708bf3adfb3461464d84d296f757dd91149b83e943529a6305e6bb8d4e69f15793f6d82419b090fcced +6e0f96d56505ffd2d005d5677dbf926345f0ff0a5da456bbcbcfdc2d33c8d878b0bc8511401c73168d161c23a88b04d7a9629a7a6fbcff241071b0d212248fcc2c94fa5c086909adb8f4b9772b4293b4acf5215ea2fc72f8cec57b5a13792d7859b6d40348fc3ba3f5e7062a19075a9edb713ddcd391aefc90f46bbd81e2557b 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f 84ccea110213a2adeca11625637003d07b1943a1c6aee7e66ff4f05a5383f9c9d3a6c4d15cc8432c64a7c9d9cefc6ac4 +3f12ab17af3c3680aad22196337cedb0a9dba22387a7c555b46e84176a6f8418004552386ada4deec59fdabb0d25e1c6668a96f100b352f8dabd24b2262bd2a3d0f825602d54150bdc4bcbd5b8e0ca52bc8d2c70ff2af9b03e20730d6bd9ec1d091a3e5c877259bcff4fd2c17a12bfc4b08117ec39fe4762be128d0883a37e9d 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742 ab3bbe11820b06c74e5a88b20c3931238e286130ad4c113f2fb19017bf3c4d6c56027b5280cd4846cbcd328ac4fa5acd +a1eed24b3b7c33296c2491d6ee092ec6124f85cf566bb5bc35bffb5c734e34547242e57593e962fb76aee9e800eed2d702cc301499060b76406b347f3d1c86456978950737703c8159001e6778f69c734a56e5ce5938bd0e0de0877d55adeee48b0d8dfa4ac65fd2d3ce3e12878bac5c7014f9284d161b2a3e7d5c88569a45f6 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697 921f495763fb7bcd7d498bd8737e133383f5105cbb679e7f4caa1f120819c2e96312a19edbffa557954c469a7fb74126 +9aace26837695e6596007a54e4bccdd5ffb16dc6844140e2eeeb584b15acb2bbffd203c74440b6ee8db676fd200b4186a8c3e957c19e74d4d865ada83f80655323dfa3570907ed3ce853b6e8cc375ed2d758a2f5ad265dd3b47650517a49b3d02df9e0c60c21576378c2b3a08481eec129b2a75608e13e6420127a3a63c8a3f1 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04 8f920cc10516ae22833d1d784e9132e78b37c32b842e866e39ff26bf9d42ae2afa247673f31ae202fc51db07e414a4fc +ac2175940545d4fbab6e2e651c6830aba562e0c11c919e797c43eff9f187a68a9e5a128e3e2a330b955a3f4577d3f826529ad1b03d7b60f7ad678f005053b41dc0f8d267f3685c6abe1a0e9a733c44b2f3ca48b90806f935141c842e3a6c06a58f5343d75e3585971a734f4ae1074ce5b54f74bd9342f4bbca738d260393f43e 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6 a17baa5c0ff142b2f2a7523224284f0aa2ad3db40209eaa8e2e818ada3ad452a3354412f9fde77bc9a8fdf4c62336474 +6266f09710e2434cb3da3b15396556765db2ddcd221dce257eab7399c7c490135925112932716af1434053b8b9fe340563e57a0b9776f9ac92cbb5fba18b05c0a2fafbed7240b3f93cd1780c980ff5fe92610e36c0177cabe82367c84cee9020cf26c1d74ae3eb9b9b512cb8b3cb3d81b17cf20dc76591b2b394ef1c62ac12ee 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e 98b661675e116483c80e17a345bb6e8fb2555e62742fff71f8c5e1371a7d6f31d0485d8a59419a9befc929890b682db8 +3de9e617a6868dca1a1432d503f923535da3f9b34426b2a4822174399c73b1c1ee67311410a58c17202ac767844b2024d8aa21a205707d93865693ac25a24fc87034fa3a7a7e27c3344cb03b87602c15180a5fe6a9dd90cd11af4a0f150207bf2d83f55b12c088adae99aa8cfa659311b3a25beb99056643760d6a282126b9b2 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5 a907117d8df0b3ab96949e04c8f37b122144bfcf15dcbdf08a37ed943ba7ddeb0be618b5ce2cecbc8866516fb36faea8 +aa48851af7ef17abe233163b7185130f4646203c205e22bcc2a5a3697bcab998c73a9ffe1d3ea0b7978ce7df937a72586eb5ca60b0d939a7d1c115c820171c89c8116b7e2c7b98cf0f14e4c4df3cb2f319ad3ab0ea25ff14526ddc037469f000bf82100acd4cdf94feb4eba4ea1726f0569336604a473aee67d71afebb569209 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a b53ccbf0f6256a41ef46e0fe3314fa8d81ab73c57f92f515f8054b3065ebd8b262663f6a0edaa68540996d0d887734b2 +b0d5d52259af364eb2d1a5027e5f7d0afe4b999cc5dd2268cfe76f51d2f17b541bdd7867e23a1bb897705153d9432a24012108979c6a2c9e2567c9531d012f9e4be764419491a52eae2e127430b0ab58cb8e216515a821b3db206447c235bf44ee304201b483b2a88844abaa18bca0147dfff7e502397dd62e15524f67eb2df2 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb b6af208b8b8cbf788aba3a8a49ed6875e67e934f38a28d65f1511f62596321784f84c24d69750854aa1f57c6d8f1f10b +9599788344976779383a7a0812a096943a1f771ee484d586af1a06207478e4c0be9c200d42460fe837e24b266c8852d80d3c53cc52ffb1913fc3261145fc6da575611efd16c026059a2e64f802517ffd1b6b34de10ad2909c65c2155e8d939b8115400c1d793d23955b15f5d1c13c962ff92b4a815cee0e10f8e14e1f6e6cd38 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77 922f6124f2463451ab3d4308ae897fcff9d2c2d0e493fe540529396e782a1b58c4b3deef76b8ee844c1a3bf850d13860 +fdde51acfd04eb0ad892ce9d6c0f90eb91ce765cbe3ce9d3f2defe8f691324d26b968b8b90e77706b068585f2a3ee7bf3e910528f7403c5af745a6f9d7ba6c53abd885c3b1be583415b128f4d3f224daf8563476bd9aa61e9c8518c144335f8f879c03696bddbe3ac37a8fbede29861611feaa87e325e2f60278b4893ed57fb0 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c 849c2b2b13ad678128fb895a3e0badb06913ded658f882df93c8cb2bcb4da72aa33b626a4548812035c65c9ca59c2cd8 +beb34c997f905c77451ac392f7957a0ab8b23325bd5c63ca31c109ac8f655a1e3094240cb8a99284f8091de2ab9a7db2504d16251980b86be89ec3a3f41162698bab51848880633e0b71a38f8896335853d8e836a2454ecab2acdcc052c8f659be1d703b13ae1b090334ac50ab0137ddb5e8b924c0e3d2e5789daaef2fdd4a1e 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63 8bb86431d9fc4e9569a54dd3352c92d6240332cb43c9bd1b325dea71373d3b056cf1c772d4f1f69559bcd282e2b27ba2 +543c374af90c34f50ee195006d5f9d8dd986d09ad182fcbefa085567275eee1e742bfe0af3d058675adeb5b9f87f248b00a9fbd2aa779129123a5b983f2f26fc3caf2ea34277550c22fe8c814c739b46972d50232993cddd63a3c99e20f5c5067d9b57e2d5db94317a5a16b5c12b5c4cafbc79cbc2f9940f074bbc7d0dc71e90 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da b02f704a6e2f0737e39f2c4b11080548f1cfa1b5f5912e81f727e2c9be371e18c6fc0a697f5d1033630f961186f3a7bf diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_rfc6979 b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_rfc6979 new file mode 100644 index 000000000000..d5d21a1d5189 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_rfc6979 @@ -0,0 +1,34 @@ +73616d706c65 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 9197f17873b2f14e6d7b8b36f173361ad2151022f5136f1b45c90dd538968b0a849cd9f444d7c33e83b60336f2b46347 +74657374 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 af0ad491973830288098c904c5f481cae53e4ff6849f044dde0680d57f4d2bfbeedc56121862197f8c843f02eec44ff9 +73616d706c65 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc 9205ae3a9231f9f358ba9e3febecd8d4ce9077c6caa547bccba88e3275220583e1bb1b100932d442bf56de0093c209d3 +74657374 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc 9101726306fe21925ef2f6002c7bd3b916d418acfca253f06860af51f454b423e11635c7044af80480a7d204b36792a2 +73616d706c65 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 b3815874a7857efaece910f09d32481ef93f39a8da8358cd72c5fd777349e4e3cce85c2ac827d085e8c6a5e49fdd7cd7 +74657374 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 96a2bdb1a96eee00f5eac6791bfb2e9797da89b7f8413d6daa32d17ed4e2958b7d0949187340d291d9a333b713e17913 +73616d706c65 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 891ba770bfb3fb55bdd4b0cff38bc63fd91222072e63cfbc94976179c83c063437b740068992b48fba85c27ee51ff79b +74657374 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 97d56798d77881b561ce1c8d19ab0bed3a0776b4c3d2310fa5183b98aa35894c9c5344489415af0800ed25328f59aff7 +73616d706c65 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 9392341d252de17c047679fc4ed18efad2c810df9fc1219f3c4dc0da34fe24672094a5200e42b297642c9a57452892f9 +74657374 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 8cf39547cae5a8b54a8524a6bf7b85be6cd49df955c3ecaf2e57df8f132ee7be5eb49ee35558986f53c288862b693198 +73616d706c65 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 b6d098bbba54e9089d76da122844ce18b9c110a21f2d94ec3714eb135aef61854d3960e3564306f1a35309ad39d45c04 +74657374 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 8c05ae934f29d4a9649d948092ee15bfd7020c1824d6b44cf1097711baee2b7ab3b364348dd6ee2247eb2822206adcfb +73616d706c65 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 8dde1bc143b1b805d92e1d3c19716941edf48089ef6399ded0f68f06ca0356dbbb619a65917a1b30ca3c9ac4baaa39dd +74657374 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 8a63ffea1c354dab0a5149be7dfa1109a53a9ddaffdcc876ac3dfdcdffb05184396bbd4fa2591101da9b1fddf749b2f8 +73616d706c65 9a4d6792295a7f730fc3f2b49cbc0f62e862272f b8bd76003435fb648f2595ccbd0d744d94028bb87e9669bb4157af0c7871c835b76a5c6edf03c7cc45874dcb65da03db +74657374 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 8d637491236518360322b69cc5a0e6f7b5a5a87b053c4582c1a738513f008350bec144af1f83843a0366ca41e0728c65 +73616d706c65 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 a84732e5a77187abbe362c483bf233adb8025808693f79b18af470b98977fa8914689025d4e6e8ed8e819ba1f19897d1 +74657374 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 b08e596c9800e2ce0a127e96ad14dd90973bf33d5140f6972aceca402d0070d6460e39beaf670e4e0180c73e43469fb4 +73616d706c65 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a a5cdc6cbd689db535a5b9bbceb9548114ddce01d5aef764c632a93463c7ca9571c0475db5df3cef954f4adcc00b6ddbd +74657374 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a b962d92a028210a5f1240fd52ef95d23863c0fac6e6832294b7da3253f0256345bba8d88be165c7127e46a1765ac74b6 +73616d706c65 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 8c63e449ef0de36b2fb10a144c8f2f0a3207b0ff33d692e4cd15bcef02478d72f2db3c08992210b4962219ec553bef85 +74657374 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 a927f9fecff4a035b7b4d917d7a79ea991a07c0bfb9b5f877ebecebb2814eec542a57cc26d7b9cf8181ca25b97004034 +73616d706c65 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c b4994dd576c76a876645472688417140cbec7327243a189fec522be9f1405d0aa74ef6406c533179aee622ed5de38af5 +74657374 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c a33bca3982f485d37d015ffaf60053d2607c0c9bd8cc1d21f93e282fab85650dd9220f14de6be943de231a408e72fc6b +73616d706c65 035318fc447d48d7e6bc93b48617dddedf26aa658f 80456bdb0ec611ce36f71836854089f0baf8948e225bfa56619ce72d65bbe535bf439a4df95a16aebd4c6b3f1905b24c +74657374 035318fc447d48d7e6bc93b48617dddedf26aa658f 80cc25e9b149db4563c6ed69fe91759dcd3bac0253b37e53462b3962b2365118ab0cea1c84a81b68917a9827e3dfd03e +73616d706c65 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 86e1b9950fecabcdfa3e68848bd140764210760e2816b910b9d693e8dec072ec923f2a0731697252d29d31389aae41ca +74657374 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 abd8025f3cff51a6518d3fa2478c69e32784954e5cc129b09e1f1b961f25de633ccb0bf018331ac63bb7b54b4a22e0fd +73616d706c65 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e b132f32ec3468dc54b7d64f1da5d064d43fc4fe0f830a3f9b4c6fa0ce0671a819ac3c6cbb827d5849ed4166d37e456d9 +74657374 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e b1d242688845b6b04806502dc0a3d0fa6631121f00050570eb63a3f4beb412d26f735e285d7bd8eab72a427818df6b38 +73616d706c65 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 997b61a89e08262409942f369ff256e0cfe2d68e6a182f13e1f63dc6074d4f9c1991daf44253fc89ca5f3845a5f9537f +74657374 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 b5be7765c5c623342f56a7fd2a34e23230f47d2a127eaa629e1645119f92ffceecea5460e304d7283c37991d84d5cac3 +73616d706c65 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 82bc5e9488a191c1c22a074964b88f9793c8237f2a76edf27bf7d20410b663172d022497d2cc1e0a3b54f764c8384af5 +74657374 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 8c7d7f9047c346393e42c89750ba694ba45bc85a9817d33bf5590cf6f740de633e978de5c794ea7b153e4ccff1f8db31 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_rfc6979_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_rfc6979_blst new file mode 100644 index 000000000000..5715d61c0f7e --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g1_pop/sig_g1_pop_rfc6979_blst @@ -0,0 +1,34 @@ +73616d706c65 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 9197f17873b2f14e6d7b8b36f173361ad2151022f5136f1b45c90dd538968b0a849cd9f444d7c33e83b60336f2b46347 +74657374 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 af0ad491973830288098c904c5f481cae53e4ff6849f044dde0680d57f4d2bfbeedc56121862197f8c843f02eec44ff9 +73616d706c65 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc b3e88093f28e78a16a04d92e865f049ebc35a1130bdb3be3cbc224f859a348abe88c1c0bf985e84e8a03a220c2f1574c +74657374 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc 99445f34e81bba55f0954392a2bd14808b3040bd66523c24e3e5e08aada36e35aa3e0f5c99b52d1c5e43e8518a7a9460 +73616d706c65 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 b3815874a7857efaece910f09d32481ef93f39a8da8358cd72c5fd777349e4e3cce85c2ac827d085e8c6a5e49fdd7cd7 +74657374 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 96a2bdb1a96eee00f5eac6791bfb2e9797da89b7f8413d6daa32d17ed4e2958b7d0949187340d291d9a333b713e17913 +73616d706c65 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 891ba770bfb3fb55bdd4b0cff38bc63fd91222072e63cfbc94976179c83c063437b740068992b48fba85c27ee51ff79b +74657374 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 97d56798d77881b561ce1c8d19ab0bed3a0776b4c3d2310fa5183b98aa35894c9c5344489415af0800ed25328f59aff7 +73616d706c65 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 80ccceb3fc3c74b72691732605b5949ac1dbe98284fd71e47a4763b6f07d16b80de781dd08fdb878b2896c2cfe61b0b9 +74657374 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 a55cde6b18053e1a6c47767e9a18aa2fbacb7d5a37bf661cc7659c03a190a52e3ec02b531cb41b876b45d8a6d4018db3 +73616d706c65 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 91a41df26e575ee1b41aefbd2dd78483df3825b5636193132c81781e29824965c913b86318ece250d5fc424c66db2097 +74657374 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 96947b39fa7e350e8b51ed6451cbe2a470e6a485dd751c6149975372b6b6aa084f10c5fbdb729f9bbabba7c3feccec98 +73616d706c65 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 8185cbec1ada7fc889ba65eea626582b1a712d47048a50683e4b79828d1fa9418e1153e3c8489c70a3d15bbfcefd127f +74657374 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 8244de5ca40c182a195e242fb63e8b6b08b4e376ea0caac0d05b500664b4b8806277150c6355e3eb620bb82ee4e34392 +73616d706c65 9a4d6792295a7f730fc3f2b49cbc0f62e862272f b8bd76003435fb648f2595ccbd0d744d94028bb87e9669bb4157af0c7871c835b76a5c6edf03c7cc45874dcb65da03db +74657374 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 8d637491236518360322b69cc5a0e6f7b5a5a87b053c4582c1a738513f008350bec144af1f83843a0366ca41e0728c65 +73616d706c65 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 a84732e5a77187abbe362c483bf233adb8025808693f79b18af470b98977fa8914689025d4e6e8ed8e819ba1f19897d1 +74657374 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 b08e596c9800e2ce0a127e96ad14dd90973bf33d5140f6972aceca402d0070d6460e39beaf670e4e0180c73e43469fb4 +73616d706c65 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 91b9f17aabdfef1c51e6c705cc2fe918516e2a141464ba6f032ed2419eddb5aa6c0255ea74726dd0d2d9ed670fc88df0 +74657374 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 97a59888d2f5e0ad001f96f32330c50832ef850ff824c92bc2b5a9f6083d696c611fa095d53843c229aa75b570f29603 +73616d706c65 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 8caec8d11946d642c670b0588c77f404b99d4817e7bd818b1efdce46a5b7b37f49239ae7a3cbcc2218f1efc1e6382d7b +74657374 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 89a652f312db5fb96839d64f6ba6b5788903a602296c72b58786d6b5c14a4a1f74b9965a9730db9f47fbc8bdd1df90e7 +73616d706c65 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 8d225d1b91f6e62c76db84c729574a88c0e96591baf23749a74b8fbf3dd2b8f40d02f2b428d26c8a02b8e7257bedc2a7 +74657374 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 8ab9dab74c144f67e6bb971d6d8441c340b7359eabf300692e5a04596ced0ce93650826919bc8ea5c8f4695e58a0b9ec +73616d706c65 035318fc447d48d7e6bc93b48617dddedf26aa658f 80456bdb0ec611ce36f71836854089f0baf8948e225bfa56619ce72d65bbe535bf439a4df95a16aebd4c6b3f1905b24c +74657374 035318fc447d48d7e6bc93b48617dddedf26aa658f 80cc25e9b149db4563c6ed69fe91759dcd3bac0253b37e53462b3962b2365118ab0cea1c84a81b68917a9827e3dfd03e +73616d706c65 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 86e1b9950fecabcdfa3e68848bd140764210760e2816b910b9d693e8dec072ec923f2a0731697252d29d31389aae41ca +74657374 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 abd8025f3cff51a6518d3fa2478c69e32784954e5cc129b09e1f1b961f25de633ccb0bf018331ac63bb7b54b4a22e0fd +73616d706c65 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e a208d74312bdb343aaf2aa22af9da986e1156c34586eee9c769aa1bf08b124f539e6686213b2b64c971492c923d20bf7 +74657374 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e 949e76c0502708ab392e0f5855579ace69b198556abbb92f66d12793b9b32dfd0f5f9e7bc36e06377bda538543d460e2 +73616d706c65 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 8bc13e7338b2829a077331d48e923d4448359ce15c29f4090f418e7ab79ef5b6f8b155e66b4d9384041d4641d15bff43 +74657374 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 a67392d72df7eeb618b75950f773c0d9285d58e81e91a1409bb9f1e1467fc5d01664c028c607c5c8ca12ef963cd17a38 +73616d706c65 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 840ea5c1694b32fa6fe58ecca13f793672e23203d749e8908f3ee6df3c0c23c2858ebd7c1a23521e47712143446827b2 +74657374 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 89246e04b3e97aa5c3ac136cc8cde4949295626b0287908f8e16e07c199976e37249189ef638bfc63a73bf0b1c91315d diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B233 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B233 new file mode 100644 index 000000000000..bd09ad60cdad --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B233 @@ -0,0 +1,60 @@ +f1b67fde01e60e4bb7904d906e9436a330c5cb5721fd4e0a3c75b83dade868736bb1d21cfb1b5c6407c373e386ee68ec2239b700e763728eb675a153b8ac44cf2a87be85fe8ed6683430cf4b7d718891cbf8d583d0a37cc952cc25fe803a7aa4fda80f05541a2f1f2601cdd0c095f7110f2a84f7d641b8531572269b21cbe77b 0056673197bfeea9bd7a8b820b4ae51a50411bf118a692bb9ed3d304da53 a6ebd18d4b88be0b3fc825cf8fdb699d13ee80745ba4dc1108f4e971d8421fd02d66b8325bd38429bd3225d37f58f9fc019f5c43a54f7d44226f105f2f2af06391bf067608efa41e6a96cefdbb78794af5e341004d3e77a57e361ca12ccd9fc4 +1d496d96b533c632ed6a91f6e3653cdffaa5b8cc0008b35e49b2dd52fe261105c2ec7ee71a4ad5d51fdc3d36d688a3b7ccb3b3b0c3a65be17b8d8aa172e3005cfbf37a2d1b1a6e268c090c6f318e7e96f9ec9b9f5a8fbcc7558d89e840f7e76e44bed91c26ca48e6f5cbc253ca2fe8cb81c484cabd24070e488f9c00cd96ad4f 00468f01d483144e514ec257f2e5fdee28a927f2adb19714c1f3524dd0d3 8646f70ffc07d688aeaa2eb0eb383a34563c6490e7f51019b51663a8cd49ba80c5cd33b2186afc7b3151569595884105095c99736b9557539a5aad64b924b7a37eb8ea18cadc66a1086e46b9d53a7137f7232d42341be87ac761d9aa9b92aec3 +723400655027f474446843645757f7e2cd466bf97275067b4bc4c9d79bb3b19b2421835d69db916f24b77c381fa771fc1e7a19d2b4d09411ae55acccc615b16fd24705762b441ab67083a921fd4ae569ce0de69449aa96f5b977ac7dc022fdc8335656853796f54b3fbd118577f98920624eb0a00204f1ef83827245c06646cc 0074052d027f05465a8083a59cdbf32600224e1f563f653b34314651517f a96018dfcb9fa2d45c2527a2421225de897cc0524e74594c6df613a287f7f0ac8f525e0a0a4afb77458d9493dfc8e3bf0068c20719065043d9b2edd03377f6dc82573bcc086eda762fb3282250af4ba38e79e999635a4a1298e4902ba525d895 +155860cb31a142082bcc0bad828d747e916392d21f1873b3a3c1d28ca3ff9d45ddb66a712e3856b6afd07c8d2b2a7badab296a9775b03f6fec0befa2d8d6d00fe3938df244ab46e836a3e686c8b4f918da49f0bb3940bba34a9aa22c7caf02df7758b0de01d9f47af6146344b9be3842d9c055eaf0fb399cd8db95c544a62d8a 001856e7544223f55f80de72a6ef3822fa8fbd68eb397d06e2d76ddd35e0 a7b34971a9dee93b2b3ca2260bc44f191886334112e60b16c79585c09dff1a88e037bcb237abc213f6bd3b2d0214a24f05e5131eefd2b2beee11a207e5f15c30043e9a0853290b773fa5befb4ff98fffa0cb37b166754cc7379954d21747a44e +cbd6e305cc9f0dc90caee6e65a74582e9357bd25c78e33a7b14e1ac7e9397ff4466f192fb432143e6df6d61a0ab808ec0a361a6d95a357a38cd3e241fe03ed883ccc364b248ee2a08702110745c2688bdcefa33c1a45b9c8b200e45cddf3e3f66b8d37eff07fbb3366ea1558ef304085613c56707095724b3e134c7a7d3f8dbf 00860aa2b589f2defc617be73e191502e5d9952bf60547fef19eeccbca26 87ec09eefd7a25639c75c9738c8118c66479844a263e98bb992f97eeb83cd3266c8f178a2d3f7a5378950308902c09c418276dceae0774088d696efbc21f044992429d49a59c008931f4e29bce61a852520d851d9e4343103f0d2dd82e06b21b +812a218ff1ee1472c189f63386e5b8ab341671c3a4dad27a8c6249d1c0f9a29338b471b6179f17a078b6504e804ac55ca3b13e68a623041bc1a092ea2adf3fa1124bbfeb161e6d7c483433f1548763b84da00352a6386e1339f674d45dab13898147ede468e0e01d2c4e0ed66b395a16cc3ded3e952ac739205f35a83376cbce 00d0dec052a00ccebd0c0c5d9a08272f75744a2582cec7ddd924a2b022b2 95eaa01aead61140f7d9ca1cf984fc9f2f0c87b2941a899673b01f2b8bf93a0aed59df1df683f1e04dff603d5a37449e094f6f8a507b02ba9f1cd5db9826267ea8eb3fb0b9c5aae8d92cc756c79c0c8d09b47c9de75d103c5f2f1b7e672e7098 +0204b1fca831919e89e108cf140b3770f531a696b1d9a4d1fb68809eb10afccc257cc90cd36717c02b2f3d6d3d1d8a93cc5c48aa7ab9f9fddfe121ce9143376535a0c65e247c6558eac49fd1d6d1bf431ba918c471cb3d536ad485ec51f6471a340ac75f160c4c54cd3ffb9dcc123124b42df1fd2eaa005e3377c5d2d55938c6 008a017d717d6d1213f2b74c53281b07258738c0c7db649ea1ac46b9a3b6 848ac2ddf17a49a1dcde2c733e573b37b24395914be608c67fb7c5f3e1e8dd2c3e11021cbff68b2c2d8ea58adbe7825c05ecbcf2f15385df2b6ab2a7f71dde48cda154cf761fad16346a814f57bc89dbedb53f6d9eee156278033756fdab6b94 +2033eb48756638cb56e2cc39a3e775cfa11fce86cf71f04487dcdbc7f262bc8350a30ced54d1fcb697b28a6e96f88f782947c997872307ed963e1d68985f756435af77f57755cacbb4c6b50ed419deec9f39f0a549a13e54254fa0a5832dba2d943ad4aed8688889a2dd29dcb4ea12abd6a6c50eabcb3981c3a0c1ca5f0b9629 001b56c14442b084cfd22aeef0f8028ec57c8b571c9fc1e43de05c45e47f 877fdfe86ae8139fe061f5998513820dcb5c109b0131b09062af6bfbb40399393fced06dce39d8366843b5f10f3f291018d68c4e1100c234effe6b04318e7ec7d68a2da47b832dec4f23df8102e60cbfe95089bce79c071fe74f2f061299dd07 +2986ab1cfe8873009e932dc68d4727d77ccbbf378e43fe4aa7c54416346b036b89c0aad1b82977c9fbc39a00f1dc916c0561d8dd70298c02b6cbfe572e0ef2058641e841c6875e8515f3c1082765e046c90c956d984b76e0e8e6eb433ce26c1757ac5b13422479141971c20102e9621d18f51096ae3173c2753facee2862d66e 005afce37c5594586ac46a34ae291f591eacb9880a7de92701977f447fbf 89a23d1b98121ebeb30fdfa4060b7607be1bfaabec55b2e5e8a24bac684c4722178fcb639532f4cbf59896369a42b17d13c61cac3dd9443fcdd405734fb71a2d0d592e041dfb87e9397e0ea4a0db9501adfad7e420ceadcc91f1d2b2494804a9 +aabf5aa90ceef91c2155f90660adbcb0eedb996f5242cee15468ae217058ebeaad8cd4ff8cdc754a8ab85ba43c59fbab6386686fad5e27ad3848fe52191c7e4b203720841501792a625aef2acb6e36493b792fa55f253effca682946ad8c77e01f44e92ec3c258d0dd98d3183f4dc4a0bd3eca183794abd6232a6f9e4add8f57 000696df05dc7a54a9908a73eb18416a155cc8df4ab26032539d86eae537 8f6c056fa9125193a5587f65f62e90ebde8cb16ede77bc30151daeb6a888da5661711d3a063d7a983312f4935b9192e1018a3f0a104f0aa492e9a3fbf720d3f2d8a7ed268ce40c7d48df3a79d91b2387567f115b6c4369573e2401deb0fd27fa +29ff209eabbde02b10b3fd559671fa53e418750c32c4a18d31cc0186d1077581bbefb8770ed079f536e866414a07431ae6633955bf42a2389b6f8a565d6e4ffb4444336e0030093876a26d4e3106e9ac697788e41f8a21c755eeb86a7c60f18e5e1069f16408a4c375a6a68d42959f2fab7ac09736c7b37c80c05897d8566ce8 005ca31e88c5b2e96e433af2023a66095161710628e7bfa428944d6676b8 a589a40ca3df523dc65faf06255bce8bd2988f21a0cb13fa5fc34e3f58bb23e0dd091972852b2dcb70543aa7ce32444b086f230235000611570e41316d5ef2716f0b88ccd1bf27c68fc14e261b4c94a44206d09cfcdf9f2c09fc3765ac0f8379 +97765d876c80819f4004a36d09ccba78e600efc71eb7e869d3a00f658d2ace6769c7ab1ef590f41fb070aa8e08615e138df45ffbb6473d4a86ba5fdf17dd6dc9ea9ee19c0332563c99e6a3451c211d286d69102b47bfa6e07d468d9bde82e5c2063fb1ebbbed6086f542cf68ba46d4f214634afb1146dd5a6f3d50912ef5b824 00ef8fe84727a2ad8bf4e646ef28a492adfaf785a3a2ba6e6f985c649a8c 8eace5c0503ab724b5c326ec0db50e73665d41dbe6860e4fb2afe0149439259c1f0568e598600d6421c8cbda639e825d06fd02c238fbc6ced36af86bd8f26dcee2d9ceacf9bc51a57526d13a57874ea96dde86abfa85d83dc69a8538b888b3db +21cf768d087d1e4eaa8a05e2008020e243116206d675c09be42ef2bc93617ecbb0575c873c6510ede9979215531b62126552738862fc4323d487992754e39d8f0d7e111e165ff254200e05082f59a57ef649bccaef6f980094fad3b7ef93bceb161760e200f0a2e396fbb6b6142dc84d872311bf932b84616b22231747937d58 003edb94b8c62f9af30c14a790c0f5d65e362a21cd8569b9725916d534c0 8daa63b2baca8e6baaebc5601f02146f3682ba4f7030c67f01112d2abf19c9a8dbe1eca1e1841091d5854404cc9f8c4a0f4c5695ab617d47a61b42d26877637245026bf0a19506165c49da26897706c15446f0eafb80b884ca1a7b667b0e40ca +7b8e58eecdab3e40212bba6bf284f9379265b3d2baec3e4625aa08d0ced851da193c292ec793dab42732c07b4e94d8b19c83aed796a7e3a6c2b954a7a9a1ff9b2bd4ca62592c8b68f709f1ad38a5c8033ebb3f33d176945bfc68e9ef2b0cee2d45a13ce89d238a33c09ce2c0c63c4233aba5717b85c4c161dd7648a41a5e39d8 000a7519be62562318da1b67d22cf8e720353d22641e0cee11c7a352bb93 b8936e69a6662ca511acf0e7606eb63774b9995d432b469cb8e68a88cac66d3a6b4897a15381faee1236077b8f6e4da016180a4067fe427bed9ef97ee8c4c567e9c93f6f60143e72695e386833bdff6b3dd5a9541e16ebf3e7ab877f9d64b9f1 +f8f268d2b04fe47e5052c8d0d653787384b9654f0bd2138a6f52b80713feeed452b976a90eea4edcfbb62d04f3eafe172ddebd7cdc3701ecd6008e3d82e8eb217b13b5228839f61075159f3bd1e1409c08903874b6dfee2789dd72c208ae769ec8c7d52552a2b1fd73dad24de8b571f88e2184d0ee7d063a121187f97e746f2f 00264022fd7dc2328a6436b522793ad9406d7a586667a0daaf1bce927338 b62a3be744c256bd9a64f9f079d4236953032f4e3ca28df8f144dfec61948ba408a3963e32793be94746ea80a1b1415600fa000f99b3fe74fd2d21ba26f2775b6ffa150e953423a96e4fb4960e08d7ce4a17c96b796970eb82b68d32a2e4f5f6 +d288768cbd066fad4bb2500b5683fa9e4eaedfb3dbb519b083f6b802efda0a022355565c5fc6babeccb22f3adbbda450ce5d633193d1431e40c0fe631a295cf85965cd3f5937b31866bd6a5300eaef9941daf54d49832acfceed90e572ef34ccc94eacd0fd6b903fee3c572b963d21e2881656a214d2a4c125778dbe3bbeebca 00da43214e2efb7892cc1ccde6723946d2a8248a6b4d6c8872fad525ec3b 885cef629edda97d8b56e42f5f98876b85f956d6b93e71e1a554b0000466320ee2ae06b52864df7a6d6d6c69e344357310a5648eed0c71c93f5400fcff4b9a64fafd401b56086304eba157a4fe262b3de86c4791ca9dfb7886aa5fdb4fdbec7b +bf0ab46e0a756c11229b0ea961f8d57218be5b00ab8b0e91d7664cdf5e0341c412c0e992d26ab12115197db39df2d1a6e18ed26a91be461432a2dfc21d98cb16003e339b0b0b1f100e4e6f4824ddac5442f22a1fac26326ed8a89cc91343d7223986d485cc8c64424e84d56be536c57e4dc5faee459b1958efd79e07e90a9811 00aeafa49d776b61f6a30d66ff64bd40dd8d79891dd5293c1b5cd3b46a7c 85d41b7f26bd228c1d1662cf2b8df355d5ea3f900d6dd58f1dcabffb725e908e6a468859f4a62a04f913711b030dde5b0f1402b5868405572c66b76c4f02de9f96132a8d4522015a70c40b862e5ec24a64b55f2c4ed6be2852b5fce790081734 +c7b1eeb7c19eb16e7f42b61d79e421b71de797a6cab4e0baee522fee7acdb533f7bbf5855316544e1b82b4f2a18ad0a2311e7622549332122171f32fc62a90e408207e0fb90d1b052821dede9c41b15b6e07d84d5d7b9e31e6396a8ed229fb6232b3051298dc5321aa589f4e289d27169f14c8cc93644916d9b72dbc92c43488 00e95db309f4305b621f51f93588a2678cb19aad0932f365fa0aaa3a3895 961f1ebe9e2de17d7693efa79c9921943723afa1a1de731ad4e5d28842d90e97968b267717bda6ac8926263a16fcb12601b85c78cc1f979fc3dbc2f717cf0cfb724ddc0980861af16b7a6b02833100b0d202870d407436fbb87436322557f011 +a738eb074e1f277dc665118ca055e6328059ab26da188c16f56384c566e43df8cff3d2a10d2d15c3c1406de8f734b20be5dd1ce937a4289f0ddfd7bddabd03586556eb8233b8feefedaa1f49bdec6d45fd562c2a83fa9fcfc2013bdd77900857199e51fa9c7cbeab925ba8f6c3c5fae46bf8e9c574b302f1e5f9c44400152a78 00d4319cc8e409b8755880827f3200d3f0f1c64d6356fe74eb1f5aa42499 99bac445daa402d4fe8c63ffb16475655ef5d07f064f13c0cc9d6b1d091bbc313c2b7e349bc8e1f3008baca9b96b0b3817d6df1340290a2b2ae4687139561a2f5a7b6c8b61f14234fc85676f8a25b4f2cc352ab3a6ffa841becf50a0052225a2 +b28103d77e5457c42e026e713ea6ff03722a36512da17197140117442a976f9e2139c54a759fc26af5811b455e5a0d3a95362d9939c1e738045be9237b469ae2106ceed7e7842b44cc0a475d5af6d781e32ff1dd1f4e1833dbc7f82b27dc7e1562d0e29213fd8911105104a7a16f665b926aa137f70d868c90e72f8ee2c95b64 009e556c945052e5954915c773b2d47970c521fcc99139269c3ef46093b7 b67b80ac4d241b3711483c5796aa07d4a1faf1525277fe086e9d8ffd26c67f86f805c60506107933b0f96d1b73875f1f0f06aeab2a71faea7eaf6e559a15282b369fae9f6ded47fdcd0346d524a696aed5fc8cfec7516586294d9441a5fb05ed +463d04c84521ae671bb35c0a7acb3ae509b1b0470f39b8fe7ae5f3c9fbadbeb2bcc3a87e284cbdff07407a351f7ba743aeac50c4a1fef7375b90eb4af8ea2df040776bbf3e4389e7a80bea40530842642b9895ab9ef5ac8ed6c9ce7917d7b3ebcf80b801da845943313988c1970e7748cc306f914c37414f8247d648b580000f 00becc76f8a77615c4f92ae1f91645bf5bb908e75ef22fd544aae63a3c8e 81ee27d7b1a680e9899044f966ff0c2c7f26b15e9a52b42328de65abb66f849e2f47465b45d39683db3a90efc985c7cf0e2a3be109618ea1a5d7c063bd20c8b55ed17c7e8509360366f1bcbb2ebc6eead36f70d3d839982589e9c9e14bf06e25 +8b2379b5553ae7db6023cb010e26ae91322bc3f94dbaa369481936f90a886e5d3827d995ccf03ca59f46805fbac0337d31a8f117cc7044218a934d5bf507090e7e21178a7162c8fcb39111e6967803dbf9d752f3ae737ba024d0f4f7627e08be58efbe997a164106bfe37f67d2f19c0fcc7a6c7eebd96a72582a9c7bdf881896 0020572c2a3dc3ea430cd8cde9d642081c21658e8bda165550cd9a5d37d9 88d98c4e8c765001fa850e20ff6ede2240b269147eb26522cf010c2693b14c9a2a949680d8de0b09afc2da68b572448909b8eeb2328d049f63328e31090893a25a577a93209c4c76ea07c0ad9e1a0f4bde206325d1f0f2050d3c69e0c8c57460 +3090bf7373731cc44c00372c1ac59280b0f36e627ccf763fa68a7be37bb0ac8cbd4f70db54fc652566c78ad268f78f015e4bb1e41516fa56ac303a3bb4a52e1fe897d8338db5a6e37cad685e704b994504bd231c7dec0002dbd907a7ebfa809833e32eb23fffdb44fe4a18e11fa19d67356cfd703cf39a75b1a290b8a7c73afb 00769cfbf2dd8248ea1e0ac9b275c9d6ddcf923fe762079b9ed62ccbaa89 af11d37b44cc0d0ec74dd2330ea53b224b3d81e73f856d0b90c0621a63bfed82e1de78150baa469be7345e998eb2d74f0a49c127b0a1247cbe0d5e79b0bd6828a972031fb58ae9d89392a2fd32caee57d410ca02d96f2f930b78d32e7d1647bb +c37389cbe3f46eeebdda343e354ccd543e96b0c2a87e057aa6b9c4895a403de706d658bbc9066c140e50fef4b56af2db1f42efb70b8021254649983f1e11d04d6b10169d5a1c2093b6ab89227b88a30537c776bb7575749c3ed87bcb29effd8e4f17915b4d5dff6cab9678d88f33abead1e73dbdc5c3307ff3d3b2d5fd7bfa83 0040ea4a37b388f0cc464f7e2bf92173107b268ff77a8acf5f517b4ec0e4 b53b74669fb071110729035aee6a6a063c427daa9a9ac0912789c493bc72b1939e483e4d33af412f95e3a0bc84fb61d90726c581ba0dd7d37de624954796200b6b8fb8c7a57fb36a9e215bf608818834902f1e62bc684d65dd9b4fa6635a3899 +8884def8c3b9c5f856b9c2352c85ea71aae3c8d0e84ca74e70e404a21467159fc9826548d16dd1ec5a75dc2c23ca37b30312f25e1194e0f9385a0499db34c855412bbf58979ffce7fc3afeb7b8dbf9898df44023200d809f520db99eae315b5cf85674fab008a20340fae8f6974034fd3e55bf08c5522a460680218f9757e368 0037fc7898df9b37b5390537352f5c0b8de22659166c19d7d4df31c3938d b473bae28f0d2367d553d003278091a14c4e0d9fb68528cf9234b750062d7df15bc3414cc90120c8504ba00abc9b0b80014e7ed6d617da7d4b653eb300d8bdb8cee5ba064db173dfa4a94f36db1cff0a2eb0aa9c90ae4a251203dbb0941f83e8 +f1fc154d469433f56c2bd42aa52237a4a4bfc08fb6d2f3f0da70a62f54e94e3f29c629c837e7adf0474fa8f23251b9b349a16848942c0d9cf5db1d0fd99527020dbe21cf0b94a9aa21f376bf74da72d36f87b306b0696771efa7250c6182b426a4500ac14de4a1804b38db8d4f3beefb8c9bb619ac82cb63fb37c2e1d22951f7 005d5069425e7a9925d2cfc6360a708147b2c1b55ede243591885147ef3b 8c6d455bad28d597935cfbdcc67bd9594dc77c0f46f12dde521f0f056db08804b84418e0e96f34659df6d37ee16f952116561a8a062fc36ea8807784db24ec604a19fe060dda841ef6a156b155c88f52dc4ebe99d748af9e4b31a73b7eef75cc +885cd348f7983a0721f96c0e866821223d3e5a95178b16d18652b4062b1b2278aed6f54ab06f7e37ae6ce1020aa3eb812d215194bcd212302da5b971fd86aee1dcb23057dbedb569bd0bbef80df538da69ae2358cb03bb77c64d3ead475c8c5ae5bfbdd75684b421a26f1a7b0c37548fa32d805acdc91230dd70a48232a12846 00ffe3e7b82ca62b96e057ee072a4718ca20a6cc9a3e51e4fe8ed7b4b9f9 932a3ba88438c8a51a20f53703f69a9271fc94faf569b9b33773e2b8b7284f5ff8d19afb9e07962616d69e7bebf9e5940461085641e4821478619734a8f0c0238c4e04ea27b53b952749542a4033d8b7a67d846d7a6a8f16f8dae33da279e7be +ca3b0e2f1c7db4e73c699f06e432bb0f63705ba66954bec4a259bf31c161bb4861476e2f2f7dde9d841d1ea6bd0990cc793cd7a10432e38735c3eeda7a0d786e8821239bdd6c4972c96c2cf68ec5b935391f963a50fe16af2719c9029943b539ff0f1f5645962a6ac46c75d2037fa0c7cd46deadcdfc66e1ddcaada3a376acbf 0007a9cb5ce27c763646de414ca2a4dcdb774d69ed2bde7a817baddbc9de aa6cceaf28d9c3e782d13f164d677fda9920dc4646dfcec1ec68d7c2a68c564ea12e100da4b514f2dcc1996cb78bc23a08d007742f9b40c4f5533011ad62e6bd76f30920ab5a8f2a69eb278e6169040131be9a79dc609a4e2c4206d3c1e52005 +4b0a31b746763beee77cecd318b90acf50fac4172cf4bfb354e5a440f651cb89d7a515e09ab19e9850803ab9167c2aee3b395a5da10dc9aff799d73756dfb0a9961d93bc32f15a96bf13962a03d5bd42ddc8b5928def7fc48fb063f42866fc5f96cf88fe0eb125b7c01906ad6a7fdade28ccb0a421ceff50ae03a974671b2c27 00c03fa9e38dc1c697f70bc6381f2bacaf860bb5632fc837f728da959ac9 849907d47f6e361aafb58340c12f50a76a258e02e20f5c12ab1ec7ccadb3793f5e9cdbf82387927a17abd503a8e4bf4c150a170d9dea4e1edcb8eb3452390bfc855aef0de299e368749fbd4a27b24cada9488af2e5b363b52ccda4b698765da7 +3011d42792b21c0f1719faf6f744d576f72c5fdfd22b1a520d0e8d47e8c2b06823d853b13c9fa039fa30a6f2e3e27bb2100c6a35f55703806bbf0f79b09d0f629f8042ec63fa04062f15f2edb92b19237980005566f02bb12a40b4ec66e4ba6c599d928b33f72d7437c0e399a8e6a9068d1fef24917fc4f9ab5464ea6684dde9 0087dba00e3fe4802e01718017510094924496bd2785d4ac1a352c530473 b7ca3eb6402bc258e70a01df84448ce57642882241efb025d78d4ad9bdc972be50fce5eaee47e71a6437b5581d1ed7290c17c56609e2f350bf1da7727e73cd9578bdef14375ec9cc150ca3c9558251a9d1019c3862159b958651f21e3c80e752 +05a5d3a3b79f4e51b722e513620c88092a9bb02408f5f52a32e782fd4923f4fd3094fc5536caf4b645d830260eba91b5173f3833dd65600fb9e246aec968b1f6ebdfddb4059fb2de7e636ed60bb7affdb74aefd158e54485d5f26be373cf944c6570daf8fd7e4b77fad57300667d6decf5c65db99ab8763bb4ecbb09fdf47e3a 005a387e7affc54a8fbb9157b5ebd400c98e2d7bd5c3e095538987d4f8d9 9462960b480ad03938ba606b71dcf064fa23cbde5d33429963c5077ba9c1d1d05b952bdf949bb24071876121a831924e1696f6e586d2afc764357f8a1953e910a84ea1da3e64d990eafcf59df920c8c114a817392d8465e38fa110b8710a753f +247a101c8196eb93a440280650ad463795690bc620e46e8118db6900a71eb493d03fbcf2f73a79bb47aa8e2d8c87ef70e4cfae36fae5c45fe247d8cd0f7d0718dad106526945014b4f3bec324897d8e1fa2f457b8a68e61873b7fa0350fde3b87b7b001c13953c2050a24f71fb77eb455053e49200ebcbba7299485c0f1a40db 00adae709a930d6f5a5c0e3d8ef4aab004d741d23f0ffb8287f7059890c0 9512727344aa5b3ab465dd701cce3c599a0f1f549c0cd7d3cf38a46166e123cd5d0236acbb9d43d04f8436ce18d1682f0b098676105739e6b855403c93970da2ae038d94333b8bc8588c9626a6c5c1976126c40e6477ca983c7bfc0cd247e458 +a16678c71976a3ce3362ca379b3272b92e8ca7085b43752473db34e4d6b61eeed3875f49f3328366fc9d0644824e0104817de458e4c1036636b18b83dbaf063f2f99818959224906571c7b28873d9c702360888df151e9ad1a7003e6130033203acf8a69889be6ebd90816f2abf0764f10be68653b1e56766ecc3150bef8b042 0035d391411e6d679751092c4ea5a079c591e77ebdcb57c1d9006ae70d90 99a19b3d14d83830f501a7f647e04400741873879d797286edda7ae931fa92e56da082f1c0583865d2d81c59e1a9a8010a03d1c8a4b65d6dca1569b4d06d1a32487aeaa7ff31c118ac0f97a27a2097dfcef11c52bebb374a28a6699ceb9bd2dd +bc2f080a7f0b69a6b142b8f3fb481a43bd71d07418df4f3b802568073c1a8d35729ad197f34a4e941a6dd511c63f201d1f6c34a1b66545bd5f43508c10bda1d6ef60ee5bdd25dde975e50c61f76cd36d50ee3bd8dfa2dff59524db9ef12f1e28d109b552cb42f021963f559c843476b5c889fc567b7840297c5a480e18c221dc 0084e79093f1947d6ab9cf399782436e36ef87c59a4c090930c9a74ddb10 9202f2262d7409de359459c78e4c784dd84edf0fe0d746ab9c5067747b6227daa4cda2b3e08119cfd782eb4ae8ef83560b52e414887cfad5c7c9ffde8a1f40390aa383221ef3e8c8807ea4da58fe1cc9ce08f1ad02c12ab49c3e5e464eb31ee8 +ea71cede8b63ddc5648eb244184bae265cd65d50f77a9e25ff93f02b132487c08732544cb88936d4fff7c0fedb39685822dd1c9be1158f647c605c9bb5f6a1ae34722fa08882c14b36b6c93cab33c9a269c7c10f755b6453ed045ea3e56f29e95a9404ba189a0b48848120392b4dcac43148b706c3d9e4c03db410cbe5dca3da 0079b6be015b8006f86fd81c2792bec6b42c08bee2d295cf9dc214c326ab 829005f6a2816c76eabaef48ff6cf86b06cc066bc2d7760f4652f6003f20d72604acc52f715d513fa8464ff05dfde446002eda44d19556642a86d0c6dbcba7e7fb2c036d131b06d9d9b46097982d8d3635f42b324289b03ac66155911e9c0ea9 +319b41d16e18059a1324c37161c937e882192cd949c420ce9c59208a0ac208ebb06f894a7fd78df2a3c5f23f25dee6595d3dacb25a699f115dd482ccd36fc54ba29dda279335424c86b07a1b1fa76a5411bcecaf4d37065b229cdce0bac75b666c6626ec37a716e9841be93c907f87453ad91d36846561f284421a89013b88c3 00ca9d751a060fde64336cdc88122819f4b3cd1b4e7df42d495197787894 a9315613bb26d6a0ed81568363e5e1208eff9a7b511ee508b30ba3e9b38797ac35c43fc7aef336dc7b15c6b68d2b3b151827230123b7ea968fcf15ec6ad8de8bedd94987314596a711484462487feb5699c3408c897152f05a228cff3dccf488 +aebeee215e7b3d4c3b82db243a47506ffbf2263f6fe9de5b69286e8649d9218367c36ba95f55e48eebcbc99de3e652b0fecc4099714ee147d71b393de14a13e5044b1251e40c6791f533b310df9e70a746f4c68c604b41752eca9ce5ce67cdc574a742c694ada8f20b34d0eb467dce5566023f8533abfa9688d782646420c77b 001dde4b2d49338a10c8ebf475b3697e8480227b39bc04253a0055839e9e a821b9c01f108f86715843ccb9fdb1d296f5cd3b13eff5c99f3784d53326bed6c9fa0911352752aaeb73b9112fe085e5165cc831f29edc64025bc46996d6214729f4761fcd09040661cf9c9a820848cf24935a30a882298f2bf6850b22d2a010 +8d353a6b6f35590baef59b638914d3e934d0145b045d221d846517ceddc8ff5e3d28826d3459f8ce1260f705e80923f39abc73d5949aa7aa8ad1734be0e992bff0c9a8f4cc9bdfa430d4cf52e29d3737b0cd3231b72b16e15e1a9040b832e4a920b4a1d94c4964ac6c8abb75bbbdb10825f882ae44c534c7154c446421a04d87 002c8bea2803fd746c874fa110a716538c179c82712f38d33d0f6d037e7a a7fb8e538c2764aafab962f89fbe586b11290cf488fe23a5ccd6e053efa05bec645c3e8749d1c8d50c79cf4ccf9ac875012d0279235c983fc0be602750a4e696a1627bc5c91033f0e3cce90e5741f339c107a23187eb554c58610dc0244e5549 +847f134b90f10ba3636ec24f36a94111f26d58428fda5bba4501e58c7bb55809f52320cbe9e0df55af1e40bbac9f3eaa26a55d78b60621d4356d090d98363662f406367601eaa9eb9568b1a1b319730bad7bf6a7ddf1b45eb6922faf8d065c540b671c50df758ebf8c4aca6f01878e5e0012dd038c58833e2b13ebdb9a9f3fc3 00b9119b3b4b30cbfb98ddf0a4f6953417e515fcf0e5a94e83ebc1d1d14d 970dbbd81dd1620ca157a14cea593f6a24c10c927e54f2c1dc334bcb09d4de9ee44c45aadeec1b45e514edeee975a86b0773560bdafb994ae312fca5a484a03ccc9088f969e519f9b4bb2bdba67095e7a67a97ed03f5718d685800ebe134de42 +99d23950493bdd931915e9f9b65e4cd1329866c0071a19d4f7d6fd190689275b7b10fc07503dd1c27a4da274dbeb3aa5cb0e71e9b7b03fc2697729b7be913756e6760098951d7015df181cf14b1e0b954e6260276af553e3e59907794b863e941950718ef154669c5c262946ba120892e0239e05910c2194f712db46e37e53b7 00f4ab2a573f3771d1e4222e251faf14e06cefed544e804c299c9a8395f5 83133d1404ed5b91f7697de29af22401e68490deeb869a564831a4d59bc87eb36e66c09bce2671b5dfea39b659c4a92f1450aceaf08957ca3f1a2ac7206f42de2a670230bcd78d6b008ea5ae48d46817d5d1d8d4678bb00f339cf1009704c767 +7bef2487bc2bbbcbcc1570bbd4ed437c0dbcbbf63f666a3355aec49ea6ef593da25aefe9ae0d94db50692475425dee3c88cdea975794ac69142c25732f3541457d68d9101c8be069f2b515aadadea2019dc7abefa6c12cb3f76d9f4b5e46546f77eaf636aa8f2329130922111151a4df913d18b7cf9d0308f01ad84d878adde7 00f4649cf30d4a5269296a45977de2652cb06d3ca2aff4475bb24517b927 ab4f520da1a918c6334c2c82cba0643937e515a9d8796ad626f871a3bbaa724aea465b3cf42bc97073b7447ec69cdda7053d9db86151163c0c0078a8d8b828d55f0ef6fa2355bcf1bcde8c67db574d7aee360f9cbfcd26aea76a7aaec7c4f9d1 +87c717eef6dd3c7434b2c91de05723783bef603d170f654b49a04b067b077c405d2d757ce780101b930196ca4261efcfbd3fc1ebb762cc0eecf101072988aca508c41581936526d3f337053000dcf77b16172492c5d654c6612bbd2523a6ad5966d7091697a29ce882fe331f79a7eb59e5a3fe536263083cc59b8133bfd33c1d 00cca24ad914c24c011f41f80d27ea41caf41fcc8dc9dc6dff5248b2b474 ab16b7484347ef7818c201452d426928f44a591d0a76fc937cf4ac8fa30f4857170ab70c603b062194266b1609d6630f0735b73eef17aeabc2c3607c7b145dedcb4a45cd149894dcf6de2d316d07c2955f58cfd1094731be54955782ff9ba4bb +9bf48c2aebf473b3a4a928b3b6a4d2fb7e9193c9e60bc2067f9f03083a8cc7b892bdbf05601118bcc34dd283e7be996bf19b0bd36727eb9d65276b6517bf0c77ae0a9091e7a9e46182a2586eb22324939801034e5ba94ba30d1bde7d8fed51eb71036fab6224f8ff30a008422efcff7ea239ff23b9f462777e62b41b396c5dc5 00f5e12d536ef327e3b0ba65ac5fc3f7f4880f5968f3340eb8868c1d47da a7731c0a7dde81158d11a49c01b2af7052fb9e1cb280abea857b5fcf78c3ae7335dd9d346735ceaab0a4069e75de36cc178f912445a065fd6246a77f019f8b25c112f2346ec39f401ef79c9040d5f7383fa446429d4f406c8a208b286c078974 +716d25519ae8f3717da269902be4a7566d6f62b68cd0faae94bce98c8a4ac6f66215ebac5407d6f64adf9d53f79f02e50921b6f0e8c805926a839443d30d9294eaa802faa7c5471d81fd1db148cdc621a8dd0c096e06fb0b71943337d5325e1bca77062684873fe904ed9012474ceae5b138e079f941a665a995026d13d7eed9 008c30d93536b8cb132277645021775d86c2ba8f199816c7539d560ac6de 88eb8cada375ce7783d42d676a3daa3dd6301be085c6367e8ac6076fccb83755f7a925c8abf40a3711fb36f7cbbeffe10bb4f930cc7ba1fa63ad44363f0550733c8814e859a5dede0b0f60321ef45a7e906a2cf347931d4166289c6bda27271f +01e76755007b2ee5ac9e1d4c8adabad6d0f9c1c08ac6e2622b7c1ead89bd3ad0921b9525b49a780a262fe8fc0904a80391717ad7cac9607de55f7c744af8a132ec45ce79723f4a4a8c8b9ef658b360bd3890df164c9f1cd74eafb74feea251a34514ff2a57ae7a6d4bec2067cbf6ee4fdaabf13721bf9ae178b9034ac5e9665b 00fa3f15a506ccf7b50bbbad0a54d3223f5a95eb54f0d1f4e5d0cc21469b 966295f720935d148998d6db403e4d857b94bf112406bb57a996cc7e15a013f5e3f294026d10a808e2da5b1ca63a6248162d0ac9141b1a9937e48ccbca18c507f01ea325d17d57a7aa4539d80a5e6199a2e45167311c9d9fa02ff66d76f973a6 +e95abeeb2c51a8cb75ab74253dbe130b5560cd52e2a63d501d26e1458aa568aca6694be91eee5fdfcf582c47c1c727084ee2b2c810281cf9b095808bf7e7c668eff00a6e48b06df3fe6a445e092c24d5687d7d89acc8063275caac186c441bc697b2f67aa71b03294e1adeb7e557c296dd91304ba0587cda3c984619f1eb4f2b 006400a4830889115aa88b860b3fb65905b01fd126c4aec2785518c2543a b43fb82926455b7a023a23c25db9cb652cd84adbfb3fa0fff36ba2410e5b954bbe6b9ff0df98c3b6f5f639709811760117c68d12e2fb069901637444be46e97efc723cdb70aa1ba0d1c796fefc0be51c97d9355e6b8a62be172dc367805eaf20 +bb8d8515365d240b2071daef0d80558fd3d0e059be9f6abb7b7a0a5f47e2ddca7d1b3b5101d5c583143258520ce8db0a87f877a395615c9bf879ef46f2f20f68bbc9706f82781fad69019396b27f292cdc70fff1772e90205a2225f80889f9daece1d03914d8776ac5bad24d8fb190ba10a2ca17768b918c2e079d83734eb372 00c7b73c324250f14fac0edc941f79bdbc6933ee8f64bf94b847bee5eef6 a0669acd7f0d23a4e57413132a4701a53a0fa2296a815889a8937647afab6468537513c23b9d1434cd77a6b8682e1c8f16ef3eedd1a0ba563997c813ae80b99d9cfaf08562bcc5db781953fedd995f0ed4b8b0516b3a4718fff96b3f556661df +cd8b2403435fac9caeffa21b55eaba52d7efee0f89df7142340cdffeb89556303ca01a800429397e2ff6c746743b6bc60a87133274282d4cac02e4ca90ad95d80c93b84163b96296f67d40b2a1124b2b6534ab6b60fdee312fbcdf468d0e84eb85fce4ff360136bb31ced3998d29cfaa3ae685e638ee272058f123c4f35f8b6b 003db7f28e161abf52ab0adc8c4c8544fc989af081303b8688f22b7b2eb7 94ccb8c93763057a03ccdefbc283cf07c2ba8a84f89d754d2d7e6b78dcb517d1d564bb2eafa6f6bf72171b714f53cb9404e0737feeb5f56c265e330d5c4ef62c9cb2b82c67e802e5f65ada751b4bb27315b9f572fbc792b2f6bfe18ac0990961 +4bb08eeb202564efb5bda40777d71f1bcc4c7c10b611e803e5c570876f3e319e9e2bc2d32031c56a32fc0d1fcf620d4e4377d881e9e1695bcdb78acba370b849115b86c1c4b83edfa03299da8e7fd14c7cadb81a8e4911c8e427e32c8c9b67e317575331967cf58085cff0c0d48ee0b8e7dc0b49687bb1c70c703a5dad08ec81 007e9d2fdd017d6da6029e88f78927d9ac9437f542db1f1fa99e32bfcf1a abdf56362f4ce6eb7023d47ead5b848437e8773c9275c1b384ca58182fc41cbb54ef9daf66dd7d4f74c09994fd3481c811ffe5a32bbbad582612537e2c3e6ac310a6319768e6b7b9fc10f9a2e8e823c77f173686e3d4ce9e38de814baa5beda8 +0bce683d835fe64e6484328aa13e18b0956f6887b5e4442fce36ff09aed015889794e79da8aa60b4be565c78685674c51e1e7ac60db6a763c777198a56e382a03aff8b40862f961ae23e8b8683b76a5577769422418972ab0049119382edde9e752b42e8b93f403c1ef8665d7ce8530ce4ed9ebf6d397827cba6b7645e177231 00c94052760fc74c2b405ee4dd5dd2a7d38ebc16df9cc32df706075450b5 8cc67d2ea0d76c01a0a2dc115b780610a75e669020718e7ac45923ce3198cfb7e10ac4b531aba0d5498862bd2248152815b9766f1f3d02b962858f319d819c8356246ba9fce2d119b834d009ceb24c0a522c3e07e904322753a6148ed277311f +a6defc770426daad4dafba3bbd2a69881334f7c31269b297e440926db54cdad3fd7ad200f5ada2b72ad221ad99a06ecac9c2563a8deed89f0d0896991d1a652f6fa282affefbdb1c1985652300d1792725071631d75a182b683a48448063c7d2563ec3d430e0fd3acea33a35cd38ec0b5b07af96af71d0bfcd879d9864ededf3 004076b93487c2da8aeaeb4725fb53b7b41b465315335c18c6ca041175b4 b94deae49a3d0273a12a60d2dcefebcb35763c362f0570fe5091e4f760b707efeca44024f98ff0876c9b830ee8f6a95100fe7c5434b8aca3ce3c294d06d04850bfaf285d1fa58542262edcb864f53017bb5d89ecf70fb1197cc4b65666268f7b +7803cdf4758c199962b62943f475c6c31356f5d9b997a12e21146a2399cd0dd3b97a860b2ce639e2801571599136d4a8cdbfb12fd1a5ce22374991e090533ff42823a2c58d2076b772814eea7fd7a1fde68263ef912681c72c7aa3e5a7cc44ee8c65e72228b7631e600121ea35bfbbc783b6ae3c0c8f80198ada218be533760b 0076ddd73ee4fc1f5e6766e229cc7236cdfce312417ea291f7c3328d5ab1 b77619e2cea2c0c3b29b60c1851609ba930ee7735e179cbf70b4f887ef4dcae5f98ce15d752b9915c65e2224fd28441d10974d3385ff0bb1a49866e03faf6dec42a987896b250f97ca987fc7266ba327a328e6c424ce744fe1775a7a3dd8f836 +e789461e1dad0b6e21abeb6ae2e96385549d1bae39415188c8f833233da6a3328144c97ddb36e0ff4d9e19d84f869e79e609c51b32de59892fb0446dd28cc164a3e53534c950d26f87fb74e682db2038cde778bde06c3ee2eca2a077d8fcc2b0332e352e0e7e6487444a8ad60e78ff213b16fda9faf374dc6d27b7a3c4c6d196 007e1f8988ad804aae7d09a99be19384cc599e7652c02c391542be74b17b b6fdf3905d3e139c81cd8b4affe8e3518d78cebc3d7f5d8baf49fd4cc96628767850e056935c23e62f5ceccb35a84c7505a65df42fc4bfbb2817632b4fdf8100b085f481113e9cb859f9780c1b0db10e6626691204b211ed6997317704fab0ae +9b58c145d1b6c887f2b25fb672cd49c3a1117224be697c15182d4048be92968a6500f8bcf747fcf33145c13a8d72e891a6e0c4c7310c2b62f3181bf586fe32f1ecf4feee8c2c8bf6c2bfdf9d5f88981ce080095c93e49a772d8e7b59f9cffccec3ca2f212ef4c6748f64e224f4f098334d83108bf6f8c7b43c5eb549f1526897 009b2292b0244c2aabe8b43d95039984d504ebe05eaff318760e4dee739f acd69c547c2773c272c8b2ab15e4f315f1677f8fdbca0c590d8498ee5872929bd8516133d8ac97e758d3ce0108f9d2a817610e4f583f6e5c9b75db4e2063b2d30a4c4cd768edd9bcd3ddd0bffd83dd1af3d25c4ca52b7a02884a5a95d2c5320d +52310a901fe9681a23dd6e02f12974d57f2c4f653322d9a0ff8b338cc6c2bd9f4765c90c6b3c9fb17df3f492e67d204e39d81a8fdeb92c852a1dcc6151ed6c63049037235c6751c9a902748163a567b714725b4d3995e0edbde03215c645b1a1da3147f7406245432800c50f823a1f991c863427ff4c68e4e16d1b106ee40dd9 007ca463b50fdd92d9163f1c2bdfce2ee45ba1437b79162e3e959b814cab 87fce25d78aa6f585e983e8288625abb2896b0416b10ab26624bd567bb9bf62c01532f315e7b149fa2d887c6013182520763ab57fe46b917ca099c823476b728be0777c7e6321c1eba423f3fc3494be9ec32830d9876081fb71519eb157da43a +ff419c011601cfaf833067cf28dbe6e935ebeddf8b5111a97f6eebf3bb28376334f329cd877a134b074790a073db766efe018fce666a34650cbac285ae856fb6b3b8b96877282bc11cd9f9c8e510ed1f69bc2725a44a1d2b35de1edfd8bc9d20c7525ab0bbc27662a7cfc1bbd1e0f4fce5b88411521e3893e027cc8c73acdabd 00c3844750f63fe0c2e930bc38fe88522f4e72a2fd0db9778ade20e939b3 99eea2e74544a73f92c9fee1ef48a19672a7fc131d118057d8ef4eef89c19591eaee493996b84b8a4c79909f87faafae0b03529bd6e9a8b31e5f8c1c73792d705bcee7b453d867c690d2217facbaf9dd17d0898aea4c024192645c6f2ef0323e +05a89c4824c5de66587875011e704bc6e06e991ba8f3aed331cfffe55aa266a08c729f77b8d082dca4d286b2d451ea838d726cc2cf298fddf2d7376714c5e37b64506f353917caec525a1209391449c078c5197a371feade74f8fc8a1a1d67576edfda13c14ad324342fc0b09277941dc072ec0d39434ff1cb91fc59478fcde7 00a3bea235dea86506be4476eb7999dcb8e584a34238c4a894ad6823b93f b75f7dc9a6a4b830a0fb2ecf86cbec172511c4bfe0c9cb6db813eac0f085b59622bcb0294777b88e5955e87e12c0ccb715140462fd6907d12821c6c9daa8d2e9825be68e822fc3dc677423451e40f0bc008becc58f2906f9c290eda2571bb6e7 +13e6b5241365d9d0ef9e8b05cabb3248afd221ec02eab92284b98bda3d9272184bfe5251d35705defba5085381430e99b33a3ab77d7870e5102757d065862372df2434a25556b76e54ebc39d4e6c3aba5cd6acf0c335756f7d9385c1068d4cfa37526a9a58c0ccc7f87a8189176c5d4f201499236058ec061357dcdb5acdba40 009a367cd1cffd8dfcca179e167ea437ee48e9b6f42559dda9224701d3f6 a4062182b42963a0a5e8d73872485e6338c4eca5108f07f3787cd025a768f0b519bcaf2bc02b6b14fe315ea6636c14760bedf2e9642ec95bf9321da5da4523154c033ec1c898ca880d3e759beb316f2215e0dfb612204e5434a0d6d856932944 +139a1a5090b97afb8fecfff8745efacf7dcf91a4393a7b629564e598d58d5be39c05c5830d4c8ca85d29e9e2c31ad0447864e867d0ef4788ac734f8d871daebceda98d449308c2afbe97724c3af8a468f1925065f39e52ba4b7d15728a744b1252a20476dcfff7bcb82aa72c209e72abb3c24419bc26191390ffed340c1b9c6f 0046f4ad2522e78b9b35297d28f361fb0ce82306322aedc119251d8241be b851e5c3be8399a2139aa70bad566ca40ecd1d73ab632470d3fb85c9ac13a1ec88eeff1ca21e425b0e3932c010e49571189638984c9795197bd1c7424244333edb1708505153453a743aafc8d28f3c075285e2ba5c2f3950cfdb4a4ce8cbea15 +3315e5cda5f252e3291b61e493ab919c20a8af1286d9660cfa2f5ca38b6defe19ebecf820787fe692d04eae8a5f5d37abfb593309569cedf45efd0cecef6951b718924c8380ba52e8ab8c9bfb2261ed5f01cc5a5f9fc5fcdd269a0f122c597afdd9a836cf8f96838c3e8962c1788c3ce4128719b3ef4fc88569643dcad6da16f 00ac82137e9c7a5ecfb8b1a7df9ab50732934566a392a6c8915ee8ca8144 b75b5e710a5589c63df17b0c7c0b8a65903baa34b3a60574e6d6f57be3c6ee7ff11592a4736adaf3fbf5522e017c646f0534fb736a9c041e022fe45d8c17670e430d7bc4ef3c3ccb59052a8a3fcfe8f0038e91a363415d2d89c5e943ef790cf4 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B233_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B233_blst new file mode 100644 index 000000000000..bd09ad60cdad --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B233_blst @@ -0,0 +1,60 @@ +f1b67fde01e60e4bb7904d906e9436a330c5cb5721fd4e0a3c75b83dade868736bb1d21cfb1b5c6407c373e386ee68ec2239b700e763728eb675a153b8ac44cf2a87be85fe8ed6683430cf4b7d718891cbf8d583d0a37cc952cc25fe803a7aa4fda80f05541a2f1f2601cdd0c095f7110f2a84f7d641b8531572269b21cbe77b 0056673197bfeea9bd7a8b820b4ae51a50411bf118a692bb9ed3d304da53 a6ebd18d4b88be0b3fc825cf8fdb699d13ee80745ba4dc1108f4e971d8421fd02d66b8325bd38429bd3225d37f58f9fc019f5c43a54f7d44226f105f2f2af06391bf067608efa41e6a96cefdbb78794af5e341004d3e77a57e361ca12ccd9fc4 +1d496d96b533c632ed6a91f6e3653cdffaa5b8cc0008b35e49b2dd52fe261105c2ec7ee71a4ad5d51fdc3d36d688a3b7ccb3b3b0c3a65be17b8d8aa172e3005cfbf37a2d1b1a6e268c090c6f318e7e96f9ec9b9f5a8fbcc7558d89e840f7e76e44bed91c26ca48e6f5cbc253ca2fe8cb81c484cabd24070e488f9c00cd96ad4f 00468f01d483144e514ec257f2e5fdee28a927f2adb19714c1f3524dd0d3 8646f70ffc07d688aeaa2eb0eb383a34563c6490e7f51019b51663a8cd49ba80c5cd33b2186afc7b3151569595884105095c99736b9557539a5aad64b924b7a37eb8ea18cadc66a1086e46b9d53a7137f7232d42341be87ac761d9aa9b92aec3 +723400655027f474446843645757f7e2cd466bf97275067b4bc4c9d79bb3b19b2421835d69db916f24b77c381fa771fc1e7a19d2b4d09411ae55acccc615b16fd24705762b441ab67083a921fd4ae569ce0de69449aa96f5b977ac7dc022fdc8335656853796f54b3fbd118577f98920624eb0a00204f1ef83827245c06646cc 0074052d027f05465a8083a59cdbf32600224e1f563f653b34314651517f a96018dfcb9fa2d45c2527a2421225de897cc0524e74594c6df613a287f7f0ac8f525e0a0a4afb77458d9493dfc8e3bf0068c20719065043d9b2edd03377f6dc82573bcc086eda762fb3282250af4ba38e79e999635a4a1298e4902ba525d895 +155860cb31a142082bcc0bad828d747e916392d21f1873b3a3c1d28ca3ff9d45ddb66a712e3856b6afd07c8d2b2a7badab296a9775b03f6fec0befa2d8d6d00fe3938df244ab46e836a3e686c8b4f918da49f0bb3940bba34a9aa22c7caf02df7758b0de01d9f47af6146344b9be3842d9c055eaf0fb399cd8db95c544a62d8a 001856e7544223f55f80de72a6ef3822fa8fbd68eb397d06e2d76ddd35e0 a7b34971a9dee93b2b3ca2260bc44f191886334112e60b16c79585c09dff1a88e037bcb237abc213f6bd3b2d0214a24f05e5131eefd2b2beee11a207e5f15c30043e9a0853290b773fa5befb4ff98fffa0cb37b166754cc7379954d21747a44e +cbd6e305cc9f0dc90caee6e65a74582e9357bd25c78e33a7b14e1ac7e9397ff4466f192fb432143e6df6d61a0ab808ec0a361a6d95a357a38cd3e241fe03ed883ccc364b248ee2a08702110745c2688bdcefa33c1a45b9c8b200e45cddf3e3f66b8d37eff07fbb3366ea1558ef304085613c56707095724b3e134c7a7d3f8dbf 00860aa2b589f2defc617be73e191502e5d9952bf60547fef19eeccbca26 87ec09eefd7a25639c75c9738c8118c66479844a263e98bb992f97eeb83cd3266c8f178a2d3f7a5378950308902c09c418276dceae0774088d696efbc21f044992429d49a59c008931f4e29bce61a852520d851d9e4343103f0d2dd82e06b21b +812a218ff1ee1472c189f63386e5b8ab341671c3a4dad27a8c6249d1c0f9a29338b471b6179f17a078b6504e804ac55ca3b13e68a623041bc1a092ea2adf3fa1124bbfeb161e6d7c483433f1548763b84da00352a6386e1339f674d45dab13898147ede468e0e01d2c4e0ed66b395a16cc3ded3e952ac739205f35a83376cbce 00d0dec052a00ccebd0c0c5d9a08272f75744a2582cec7ddd924a2b022b2 95eaa01aead61140f7d9ca1cf984fc9f2f0c87b2941a899673b01f2b8bf93a0aed59df1df683f1e04dff603d5a37449e094f6f8a507b02ba9f1cd5db9826267ea8eb3fb0b9c5aae8d92cc756c79c0c8d09b47c9de75d103c5f2f1b7e672e7098 +0204b1fca831919e89e108cf140b3770f531a696b1d9a4d1fb68809eb10afccc257cc90cd36717c02b2f3d6d3d1d8a93cc5c48aa7ab9f9fddfe121ce9143376535a0c65e247c6558eac49fd1d6d1bf431ba918c471cb3d536ad485ec51f6471a340ac75f160c4c54cd3ffb9dcc123124b42df1fd2eaa005e3377c5d2d55938c6 008a017d717d6d1213f2b74c53281b07258738c0c7db649ea1ac46b9a3b6 848ac2ddf17a49a1dcde2c733e573b37b24395914be608c67fb7c5f3e1e8dd2c3e11021cbff68b2c2d8ea58adbe7825c05ecbcf2f15385df2b6ab2a7f71dde48cda154cf761fad16346a814f57bc89dbedb53f6d9eee156278033756fdab6b94 +2033eb48756638cb56e2cc39a3e775cfa11fce86cf71f04487dcdbc7f262bc8350a30ced54d1fcb697b28a6e96f88f782947c997872307ed963e1d68985f756435af77f57755cacbb4c6b50ed419deec9f39f0a549a13e54254fa0a5832dba2d943ad4aed8688889a2dd29dcb4ea12abd6a6c50eabcb3981c3a0c1ca5f0b9629 001b56c14442b084cfd22aeef0f8028ec57c8b571c9fc1e43de05c45e47f 877fdfe86ae8139fe061f5998513820dcb5c109b0131b09062af6bfbb40399393fced06dce39d8366843b5f10f3f291018d68c4e1100c234effe6b04318e7ec7d68a2da47b832dec4f23df8102e60cbfe95089bce79c071fe74f2f061299dd07 +2986ab1cfe8873009e932dc68d4727d77ccbbf378e43fe4aa7c54416346b036b89c0aad1b82977c9fbc39a00f1dc916c0561d8dd70298c02b6cbfe572e0ef2058641e841c6875e8515f3c1082765e046c90c956d984b76e0e8e6eb433ce26c1757ac5b13422479141971c20102e9621d18f51096ae3173c2753facee2862d66e 005afce37c5594586ac46a34ae291f591eacb9880a7de92701977f447fbf 89a23d1b98121ebeb30fdfa4060b7607be1bfaabec55b2e5e8a24bac684c4722178fcb639532f4cbf59896369a42b17d13c61cac3dd9443fcdd405734fb71a2d0d592e041dfb87e9397e0ea4a0db9501adfad7e420ceadcc91f1d2b2494804a9 +aabf5aa90ceef91c2155f90660adbcb0eedb996f5242cee15468ae217058ebeaad8cd4ff8cdc754a8ab85ba43c59fbab6386686fad5e27ad3848fe52191c7e4b203720841501792a625aef2acb6e36493b792fa55f253effca682946ad8c77e01f44e92ec3c258d0dd98d3183f4dc4a0bd3eca183794abd6232a6f9e4add8f57 000696df05dc7a54a9908a73eb18416a155cc8df4ab26032539d86eae537 8f6c056fa9125193a5587f65f62e90ebde8cb16ede77bc30151daeb6a888da5661711d3a063d7a983312f4935b9192e1018a3f0a104f0aa492e9a3fbf720d3f2d8a7ed268ce40c7d48df3a79d91b2387567f115b6c4369573e2401deb0fd27fa +29ff209eabbde02b10b3fd559671fa53e418750c32c4a18d31cc0186d1077581bbefb8770ed079f536e866414a07431ae6633955bf42a2389b6f8a565d6e4ffb4444336e0030093876a26d4e3106e9ac697788e41f8a21c755eeb86a7c60f18e5e1069f16408a4c375a6a68d42959f2fab7ac09736c7b37c80c05897d8566ce8 005ca31e88c5b2e96e433af2023a66095161710628e7bfa428944d6676b8 a589a40ca3df523dc65faf06255bce8bd2988f21a0cb13fa5fc34e3f58bb23e0dd091972852b2dcb70543aa7ce32444b086f230235000611570e41316d5ef2716f0b88ccd1bf27c68fc14e261b4c94a44206d09cfcdf9f2c09fc3765ac0f8379 +97765d876c80819f4004a36d09ccba78e600efc71eb7e869d3a00f658d2ace6769c7ab1ef590f41fb070aa8e08615e138df45ffbb6473d4a86ba5fdf17dd6dc9ea9ee19c0332563c99e6a3451c211d286d69102b47bfa6e07d468d9bde82e5c2063fb1ebbbed6086f542cf68ba46d4f214634afb1146dd5a6f3d50912ef5b824 00ef8fe84727a2ad8bf4e646ef28a492adfaf785a3a2ba6e6f985c649a8c 8eace5c0503ab724b5c326ec0db50e73665d41dbe6860e4fb2afe0149439259c1f0568e598600d6421c8cbda639e825d06fd02c238fbc6ced36af86bd8f26dcee2d9ceacf9bc51a57526d13a57874ea96dde86abfa85d83dc69a8538b888b3db +21cf768d087d1e4eaa8a05e2008020e243116206d675c09be42ef2bc93617ecbb0575c873c6510ede9979215531b62126552738862fc4323d487992754e39d8f0d7e111e165ff254200e05082f59a57ef649bccaef6f980094fad3b7ef93bceb161760e200f0a2e396fbb6b6142dc84d872311bf932b84616b22231747937d58 003edb94b8c62f9af30c14a790c0f5d65e362a21cd8569b9725916d534c0 8daa63b2baca8e6baaebc5601f02146f3682ba4f7030c67f01112d2abf19c9a8dbe1eca1e1841091d5854404cc9f8c4a0f4c5695ab617d47a61b42d26877637245026bf0a19506165c49da26897706c15446f0eafb80b884ca1a7b667b0e40ca +7b8e58eecdab3e40212bba6bf284f9379265b3d2baec3e4625aa08d0ced851da193c292ec793dab42732c07b4e94d8b19c83aed796a7e3a6c2b954a7a9a1ff9b2bd4ca62592c8b68f709f1ad38a5c8033ebb3f33d176945bfc68e9ef2b0cee2d45a13ce89d238a33c09ce2c0c63c4233aba5717b85c4c161dd7648a41a5e39d8 000a7519be62562318da1b67d22cf8e720353d22641e0cee11c7a352bb93 b8936e69a6662ca511acf0e7606eb63774b9995d432b469cb8e68a88cac66d3a6b4897a15381faee1236077b8f6e4da016180a4067fe427bed9ef97ee8c4c567e9c93f6f60143e72695e386833bdff6b3dd5a9541e16ebf3e7ab877f9d64b9f1 +f8f268d2b04fe47e5052c8d0d653787384b9654f0bd2138a6f52b80713feeed452b976a90eea4edcfbb62d04f3eafe172ddebd7cdc3701ecd6008e3d82e8eb217b13b5228839f61075159f3bd1e1409c08903874b6dfee2789dd72c208ae769ec8c7d52552a2b1fd73dad24de8b571f88e2184d0ee7d063a121187f97e746f2f 00264022fd7dc2328a6436b522793ad9406d7a586667a0daaf1bce927338 b62a3be744c256bd9a64f9f079d4236953032f4e3ca28df8f144dfec61948ba408a3963e32793be94746ea80a1b1415600fa000f99b3fe74fd2d21ba26f2775b6ffa150e953423a96e4fb4960e08d7ce4a17c96b796970eb82b68d32a2e4f5f6 +d288768cbd066fad4bb2500b5683fa9e4eaedfb3dbb519b083f6b802efda0a022355565c5fc6babeccb22f3adbbda450ce5d633193d1431e40c0fe631a295cf85965cd3f5937b31866bd6a5300eaef9941daf54d49832acfceed90e572ef34ccc94eacd0fd6b903fee3c572b963d21e2881656a214d2a4c125778dbe3bbeebca 00da43214e2efb7892cc1ccde6723946d2a8248a6b4d6c8872fad525ec3b 885cef629edda97d8b56e42f5f98876b85f956d6b93e71e1a554b0000466320ee2ae06b52864df7a6d6d6c69e344357310a5648eed0c71c93f5400fcff4b9a64fafd401b56086304eba157a4fe262b3de86c4791ca9dfb7886aa5fdb4fdbec7b +bf0ab46e0a756c11229b0ea961f8d57218be5b00ab8b0e91d7664cdf5e0341c412c0e992d26ab12115197db39df2d1a6e18ed26a91be461432a2dfc21d98cb16003e339b0b0b1f100e4e6f4824ddac5442f22a1fac26326ed8a89cc91343d7223986d485cc8c64424e84d56be536c57e4dc5faee459b1958efd79e07e90a9811 00aeafa49d776b61f6a30d66ff64bd40dd8d79891dd5293c1b5cd3b46a7c 85d41b7f26bd228c1d1662cf2b8df355d5ea3f900d6dd58f1dcabffb725e908e6a468859f4a62a04f913711b030dde5b0f1402b5868405572c66b76c4f02de9f96132a8d4522015a70c40b862e5ec24a64b55f2c4ed6be2852b5fce790081734 +c7b1eeb7c19eb16e7f42b61d79e421b71de797a6cab4e0baee522fee7acdb533f7bbf5855316544e1b82b4f2a18ad0a2311e7622549332122171f32fc62a90e408207e0fb90d1b052821dede9c41b15b6e07d84d5d7b9e31e6396a8ed229fb6232b3051298dc5321aa589f4e289d27169f14c8cc93644916d9b72dbc92c43488 00e95db309f4305b621f51f93588a2678cb19aad0932f365fa0aaa3a3895 961f1ebe9e2de17d7693efa79c9921943723afa1a1de731ad4e5d28842d90e97968b267717bda6ac8926263a16fcb12601b85c78cc1f979fc3dbc2f717cf0cfb724ddc0980861af16b7a6b02833100b0d202870d407436fbb87436322557f011 +a738eb074e1f277dc665118ca055e6328059ab26da188c16f56384c566e43df8cff3d2a10d2d15c3c1406de8f734b20be5dd1ce937a4289f0ddfd7bddabd03586556eb8233b8feefedaa1f49bdec6d45fd562c2a83fa9fcfc2013bdd77900857199e51fa9c7cbeab925ba8f6c3c5fae46bf8e9c574b302f1e5f9c44400152a78 00d4319cc8e409b8755880827f3200d3f0f1c64d6356fe74eb1f5aa42499 99bac445daa402d4fe8c63ffb16475655ef5d07f064f13c0cc9d6b1d091bbc313c2b7e349bc8e1f3008baca9b96b0b3817d6df1340290a2b2ae4687139561a2f5a7b6c8b61f14234fc85676f8a25b4f2cc352ab3a6ffa841becf50a0052225a2 +b28103d77e5457c42e026e713ea6ff03722a36512da17197140117442a976f9e2139c54a759fc26af5811b455e5a0d3a95362d9939c1e738045be9237b469ae2106ceed7e7842b44cc0a475d5af6d781e32ff1dd1f4e1833dbc7f82b27dc7e1562d0e29213fd8911105104a7a16f665b926aa137f70d868c90e72f8ee2c95b64 009e556c945052e5954915c773b2d47970c521fcc99139269c3ef46093b7 b67b80ac4d241b3711483c5796aa07d4a1faf1525277fe086e9d8ffd26c67f86f805c60506107933b0f96d1b73875f1f0f06aeab2a71faea7eaf6e559a15282b369fae9f6ded47fdcd0346d524a696aed5fc8cfec7516586294d9441a5fb05ed +463d04c84521ae671bb35c0a7acb3ae509b1b0470f39b8fe7ae5f3c9fbadbeb2bcc3a87e284cbdff07407a351f7ba743aeac50c4a1fef7375b90eb4af8ea2df040776bbf3e4389e7a80bea40530842642b9895ab9ef5ac8ed6c9ce7917d7b3ebcf80b801da845943313988c1970e7748cc306f914c37414f8247d648b580000f 00becc76f8a77615c4f92ae1f91645bf5bb908e75ef22fd544aae63a3c8e 81ee27d7b1a680e9899044f966ff0c2c7f26b15e9a52b42328de65abb66f849e2f47465b45d39683db3a90efc985c7cf0e2a3be109618ea1a5d7c063bd20c8b55ed17c7e8509360366f1bcbb2ebc6eead36f70d3d839982589e9c9e14bf06e25 +8b2379b5553ae7db6023cb010e26ae91322bc3f94dbaa369481936f90a886e5d3827d995ccf03ca59f46805fbac0337d31a8f117cc7044218a934d5bf507090e7e21178a7162c8fcb39111e6967803dbf9d752f3ae737ba024d0f4f7627e08be58efbe997a164106bfe37f67d2f19c0fcc7a6c7eebd96a72582a9c7bdf881896 0020572c2a3dc3ea430cd8cde9d642081c21658e8bda165550cd9a5d37d9 88d98c4e8c765001fa850e20ff6ede2240b269147eb26522cf010c2693b14c9a2a949680d8de0b09afc2da68b572448909b8eeb2328d049f63328e31090893a25a577a93209c4c76ea07c0ad9e1a0f4bde206325d1f0f2050d3c69e0c8c57460 +3090bf7373731cc44c00372c1ac59280b0f36e627ccf763fa68a7be37bb0ac8cbd4f70db54fc652566c78ad268f78f015e4bb1e41516fa56ac303a3bb4a52e1fe897d8338db5a6e37cad685e704b994504bd231c7dec0002dbd907a7ebfa809833e32eb23fffdb44fe4a18e11fa19d67356cfd703cf39a75b1a290b8a7c73afb 00769cfbf2dd8248ea1e0ac9b275c9d6ddcf923fe762079b9ed62ccbaa89 af11d37b44cc0d0ec74dd2330ea53b224b3d81e73f856d0b90c0621a63bfed82e1de78150baa469be7345e998eb2d74f0a49c127b0a1247cbe0d5e79b0bd6828a972031fb58ae9d89392a2fd32caee57d410ca02d96f2f930b78d32e7d1647bb +c37389cbe3f46eeebdda343e354ccd543e96b0c2a87e057aa6b9c4895a403de706d658bbc9066c140e50fef4b56af2db1f42efb70b8021254649983f1e11d04d6b10169d5a1c2093b6ab89227b88a30537c776bb7575749c3ed87bcb29effd8e4f17915b4d5dff6cab9678d88f33abead1e73dbdc5c3307ff3d3b2d5fd7bfa83 0040ea4a37b388f0cc464f7e2bf92173107b268ff77a8acf5f517b4ec0e4 b53b74669fb071110729035aee6a6a063c427daa9a9ac0912789c493bc72b1939e483e4d33af412f95e3a0bc84fb61d90726c581ba0dd7d37de624954796200b6b8fb8c7a57fb36a9e215bf608818834902f1e62bc684d65dd9b4fa6635a3899 +8884def8c3b9c5f856b9c2352c85ea71aae3c8d0e84ca74e70e404a21467159fc9826548d16dd1ec5a75dc2c23ca37b30312f25e1194e0f9385a0499db34c855412bbf58979ffce7fc3afeb7b8dbf9898df44023200d809f520db99eae315b5cf85674fab008a20340fae8f6974034fd3e55bf08c5522a460680218f9757e368 0037fc7898df9b37b5390537352f5c0b8de22659166c19d7d4df31c3938d b473bae28f0d2367d553d003278091a14c4e0d9fb68528cf9234b750062d7df15bc3414cc90120c8504ba00abc9b0b80014e7ed6d617da7d4b653eb300d8bdb8cee5ba064db173dfa4a94f36db1cff0a2eb0aa9c90ae4a251203dbb0941f83e8 +f1fc154d469433f56c2bd42aa52237a4a4bfc08fb6d2f3f0da70a62f54e94e3f29c629c837e7adf0474fa8f23251b9b349a16848942c0d9cf5db1d0fd99527020dbe21cf0b94a9aa21f376bf74da72d36f87b306b0696771efa7250c6182b426a4500ac14de4a1804b38db8d4f3beefb8c9bb619ac82cb63fb37c2e1d22951f7 005d5069425e7a9925d2cfc6360a708147b2c1b55ede243591885147ef3b 8c6d455bad28d597935cfbdcc67bd9594dc77c0f46f12dde521f0f056db08804b84418e0e96f34659df6d37ee16f952116561a8a062fc36ea8807784db24ec604a19fe060dda841ef6a156b155c88f52dc4ebe99d748af9e4b31a73b7eef75cc +885cd348f7983a0721f96c0e866821223d3e5a95178b16d18652b4062b1b2278aed6f54ab06f7e37ae6ce1020aa3eb812d215194bcd212302da5b971fd86aee1dcb23057dbedb569bd0bbef80df538da69ae2358cb03bb77c64d3ead475c8c5ae5bfbdd75684b421a26f1a7b0c37548fa32d805acdc91230dd70a48232a12846 00ffe3e7b82ca62b96e057ee072a4718ca20a6cc9a3e51e4fe8ed7b4b9f9 932a3ba88438c8a51a20f53703f69a9271fc94faf569b9b33773e2b8b7284f5ff8d19afb9e07962616d69e7bebf9e5940461085641e4821478619734a8f0c0238c4e04ea27b53b952749542a4033d8b7a67d846d7a6a8f16f8dae33da279e7be +ca3b0e2f1c7db4e73c699f06e432bb0f63705ba66954bec4a259bf31c161bb4861476e2f2f7dde9d841d1ea6bd0990cc793cd7a10432e38735c3eeda7a0d786e8821239bdd6c4972c96c2cf68ec5b935391f963a50fe16af2719c9029943b539ff0f1f5645962a6ac46c75d2037fa0c7cd46deadcdfc66e1ddcaada3a376acbf 0007a9cb5ce27c763646de414ca2a4dcdb774d69ed2bde7a817baddbc9de aa6cceaf28d9c3e782d13f164d677fda9920dc4646dfcec1ec68d7c2a68c564ea12e100da4b514f2dcc1996cb78bc23a08d007742f9b40c4f5533011ad62e6bd76f30920ab5a8f2a69eb278e6169040131be9a79dc609a4e2c4206d3c1e52005 +4b0a31b746763beee77cecd318b90acf50fac4172cf4bfb354e5a440f651cb89d7a515e09ab19e9850803ab9167c2aee3b395a5da10dc9aff799d73756dfb0a9961d93bc32f15a96bf13962a03d5bd42ddc8b5928def7fc48fb063f42866fc5f96cf88fe0eb125b7c01906ad6a7fdade28ccb0a421ceff50ae03a974671b2c27 00c03fa9e38dc1c697f70bc6381f2bacaf860bb5632fc837f728da959ac9 849907d47f6e361aafb58340c12f50a76a258e02e20f5c12ab1ec7ccadb3793f5e9cdbf82387927a17abd503a8e4bf4c150a170d9dea4e1edcb8eb3452390bfc855aef0de299e368749fbd4a27b24cada9488af2e5b363b52ccda4b698765da7 +3011d42792b21c0f1719faf6f744d576f72c5fdfd22b1a520d0e8d47e8c2b06823d853b13c9fa039fa30a6f2e3e27bb2100c6a35f55703806bbf0f79b09d0f629f8042ec63fa04062f15f2edb92b19237980005566f02bb12a40b4ec66e4ba6c599d928b33f72d7437c0e399a8e6a9068d1fef24917fc4f9ab5464ea6684dde9 0087dba00e3fe4802e01718017510094924496bd2785d4ac1a352c530473 b7ca3eb6402bc258e70a01df84448ce57642882241efb025d78d4ad9bdc972be50fce5eaee47e71a6437b5581d1ed7290c17c56609e2f350bf1da7727e73cd9578bdef14375ec9cc150ca3c9558251a9d1019c3862159b958651f21e3c80e752 +05a5d3a3b79f4e51b722e513620c88092a9bb02408f5f52a32e782fd4923f4fd3094fc5536caf4b645d830260eba91b5173f3833dd65600fb9e246aec968b1f6ebdfddb4059fb2de7e636ed60bb7affdb74aefd158e54485d5f26be373cf944c6570daf8fd7e4b77fad57300667d6decf5c65db99ab8763bb4ecbb09fdf47e3a 005a387e7affc54a8fbb9157b5ebd400c98e2d7bd5c3e095538987d4f8d9 9462960b480ad03938ba606b71dcf064fa23cbde5d33429963c5077ba9c1d1d05b952bdf949bb24071876121a831924e1696f6e586d2afc764357f8a1953e910a84ea1da3e64d990eafcf59df920c8c114a817392d8465e38fa110b8710a753f +247a101c8196eb93a440280650ad463795690bc620e46e8118db6900a71eb493d03fbcf2f73a79bb47aa8e2d8c87ef70e4cfae36fae5c45fe247d8cd0f7d0718dad106526945014b4f3bec324897d8e1fa2f457b8a68e61873b7fa0350fde3b87b7b001c13953c2050a24f71fb77eb455053e49200ebcbba7299485c0f1a40db 00adae709a930d6f5a5c0e3d8ef4aab004d741d23f0ffb8287f7059890c0 9512727344aa5b3ab465dd701cce3c599a0f1f549c0cd7d3cf38a46166e123cd5d0236acbb9d43d04f8436ce18d1682f0b098676105739e6b855403c93970da2ae038d94333b8bc8588c9626a6c5c1976126c40e6477ca983c7bfc0cd247e458 +a16678c71976a3ce3362ca379b3272b92e8ca7085b43752473db34e4d6b61eeed3875f49f3328366fc9d0644824e0104817de458e4c1036636b18b83dbaf063f2f99818959224906571c7b28873d9c702360888df151e9ad1a7003e6130033203acf8a69889be6ebd90816f2abf0764f10be68653b1e56766ecc3150bef8b042 0035d391411e6d679751092c4ea5a079c591e77ebdcb57c1d9006ae70d90 99a19b3d14d83830f501a7f647e04400741873879d797286edda7ae931fa92e56da082f1c0583865d2d81c59e1a9a8010a03d1c8a4b65d6dca1569b4d06d1a32487aeaa7ff31c118ac0f97a27a2097dfcef11c52bebb374a28a6699ceb9bd2dd +bc2f080a7f0b69a6b142b8f3fb481a43bd71d07418df4f3b802568073c1a8d35729ad197f34a4e941a6dd511c63f201d1f6c34a1b66545bd5f43508c10bda1d6ef60ee5bdd25dde975e50c61f76cd36d50ee3bd8dfa2dff59524db9ef12f1e28d109b552cb42f021963f559c843476b5c889fc567b7840297c5a480e18c221dc 0084e79093f1947d6ab9cf399782436e36ef87c59a4c090930c9a74ddb10 9202f2262d7409de359459c78e4c784dd84edf0fe0d746ab9c5067747b6227daa4cda2b3e08119cfd782eb4ae8ef83560b52e414887cfad5c7c9ffde8a1f40390aa383221ef3e8c8807ea4da58fe1cc9ce08f1ad02c12ab49c3e5e464eb31ee8 +ea71cede8b63ddc5648eb244184bae265cd65d50f77a9e25ff93f02b132487c08732544cb88936d4fff7c0fedb39685822dd1c9be1158f647c605c9bb5f6a1ae34722fa08882c14b36b6c93cab33c9a269c7c10f755b6453ed045ea3e56f29e95a9404ba189a0b48848120392b4dcac43148b706c3d9e4c03db410cbe5dca3da 0079b6be015b8006f86fd81c2792bec6b42c08bee2d295cf9dc214c326ab 829005f6a2816c76eabaef48ff6cf86b06cc066bc2d7760f4652f6003f20d72604acc52f715d513fa8464ff05dfde446002eda44d19556642a86d0c6dbcba7e7fb2c036d131b06d9d9b46097982d8d3635f42b324289b03ac66155911e9c0ea9 +319b41d16e18059a1324c37161c937e882192cd949c420ce9c59208a0ac208ebb06f894a7fd78df2a3c5f23f25dee6595d3dacb25a699f115dd482ccd36fc54ba29dda279335424c86b07a1b1fa76a5411bcecaf4d37065b229cdce0bac75b666c6626ec37a716e9841be93c907f87453ad91d36846561f284421a89013b88c3 00ca9d751a060fde64336cdc88122819f4b3cd1b4e7df42d495197787894 a9315613bb26d6a0ed81568363e5e1208eff9a7b511ee508b30ba3e9b38797ac35c43fc7aef336dc7b15c6b68d2b3b151827230123b7ea968fcf15ec6ad8de8bedd94987314596a711484462487feb5699c3408c897152f05a228cff3dccf488 +aebeee215e7b3d4c3b82db243a47506ffbf2263f6fe9de5b69286e8649d9218367c36ba95f55e48eebcbc99de3e652b0fecc4099714ee147d71b393de14a13e5044b1251e40c6791f533b310df9e70a746f4c68c604b41752eca9ce5ce67cdc574a742c694ada8f20b34d0eb467dce5566023f8533abfa9688d782646420c77b 001dde4b2d49338a10c8ebf475b3697e8480227b39bc04253a0055839e9e a821b9c01f108f86715843ccb9fdb1d296f5cd3b13eff5c99f3784d53326bed6c9fa0911352752aaeb73b9112fe085e5165cc831f29edc64025bc46996d6214729f4761fcd09040661cf9c9a820848cf24935a30a882298f2bf6850b22d2a010 +8d353a6b6f35590baef59b638914d3e934d0145b045d221d846517ceddc8ff5e3d28826d3459f8ce1260f705e80923f39abc73d5949aa7aa8ad1734be0e992bff0c9a8f4cc9bdfa430d4cf52e29d3737b0cd3231b72b16e15e1a9040b832e4a920b4a1d94c4964ac6c8abb75bbbdb10825f882ae44c534c7154c446421a04d87 002c8bea2803fd746c874fa110a716538c179c82712f38d33d0f6d037e7a a7fb8e538c2764aafab962f89fbe586b11290cf488fe23a5ccd6e053efa05bec645c3e8749d1c8d50c79cf4ccf9ac875012d0279235c983fc0be602750a4e696a1627bc5c91033f0e3cce90e5741f339c107a23187eb554c58610dc0244e5549 +847f134b90f10ba3636ec24f36a94111f26d58428fda5bba4501e58c7bb55809f52320cbe9e0df55af1e40bbac9f3eaa26a55d78b60621d4356d090d98363662f406367601eaa9eb9568b1a1b319730bad7bf6a7ddf1b45eb6922faf8d065c540b671c50df758ebf8c4aca6f01878e5e0012dd038c58833e2b13ebdb9a9f3fc3 00b9119b3b4b30cbfb98ddf0a4f6953417e515fcf0e5a94e83ebc1d1d14d 970dbbd81dd1620ca157a14cea593f6a24c10c927e54f2c1dc334bcb09d4de9ee44c45aadeec1b45e514edeee975a86b0773560bdafb994ae312fca5a484a03ccc9088f969e519f9b4bb2bdba67095e7a67a97ed03f5718d685800ebe134de42 +99d23950493bdd931915e9f9b65e4cd1329866c0071a19d4f7d6fd190689275b7b10fc07503dd1c27a4da274dbeb3aa5cb0e71e9b7b03fc2697729b7be913756e6760098951d7015df181cf14b1e0b954e6260276af553e3e59907794b863e941950718ef154669c5c262946ba120892e0239e05910c2194f712db46e37e53b7 00f4ab2a573f3771d1e4222e251faf14e06cefed544e804c299c9a8395f5 83133d1404ed5b91f7697de29af22401e68490deeb869a564831a4d59bc87eb36e66c09bce2671b5dfea39b659c4a92f1450aceaf08957ca3f1a2ac7206f42de2a670230bcd78d6b008ea5ae48d46817d5d1d8d4678bb00f339cf1009704c767 +7bef2487bc2bbbcbcc1570bbd4ed437c0dbcbbf63f666a3355aec49ea6ef593da25aefe9ae0d94db50692475425dee3c88cdea975794ac69142c25732f3541457d68d9101c8be069f2b515aadadea2019dc7abefa6c12cb3f76d9f4b5e46546f77eaf636aa8f2329130922111151a4df913d18b7cf9d0308f01ad84d878adde7 00f4649cf30d4a5269296a45977de2652cb06d3ca2aff4475bb24517b927 ab4f520da1a918c6334c2c82cba0643937e515a9d8796ad626f871a3bbaa724aea465b3cf42bc97073b7447ec69cdda7053d9db86151163c0c0078a8d8b828d55f0ef6fa2355bcf1bcde8c67db574d7aee360f9cbfcd26aea76a7aaec7c4f9d1 +87c717eef6dd3c7434b2c91de05723783bef603d170f654b49a04b067b077c405d2d757ce780101b930196ca4261efcfbd3fc1ebb762cc0eecf101072988aca508c41581936526d3f337053000dcf77b16172492c5d654c6612bbd2523a6ad5966d7091697a29ce882fe331f79a7eb59e5a3fe536263083cc59b8133bfd33c1d 00cca24ad914c24c011f41f80d27ea41caf41fcc8dc9dc6dff5248b2b474 ab16b7484347ef7818c201452d426928f44a591d0a76fc937cf4ac8fa30f4857170ab70c603b062194266b1609d6630f0735b73eef17aeabc2c3607c7b145dedcb4a45cd149894dcf6de2d316d07c2955f58cfd1094731be54955782ff9ba4bb +9bf48c2aebf473b3a4a928b3b6a4d2fb7e9193c9e60bc2067f9f03083a8cc7b892bdbf05601118bcc34dd283e7be996bf19b0bd36727eb9d65276b6517bf0c77ae0a9091e7a9e46182a2586eb22324939801034e5ba94ba30d1bde7d8fed51eb71036fab6224f8ff30a008422efcff7ea239ff23b9f462777e62b41b396c5dc5 00f5e12d536ef327e3b0ba65ac5fc3f7f4880f5968f3340eb8868c1d47da a7731c0a7dde81158d11a49c01b2af7052fb9e1cb280abea857b5fcf78c3ae7335dd9d346735ceaab0a4069e75de36cc178f912445a065fd6246a77f019f8b25c112f2346ec39f401ef79c9040d5f7383fa446429d4f406c8a208b286c078974 +716d25519ae8f3717da269902be4a7566d6f62b68cd0faae94bce98c8a4ac6f66215ebac5407d6f64adf9d53f79f02e50921b6f0e8c805926a839443d30d9294eaa802faa7c5471d81fd1db148cdc621a8dd0c096e06fb0b71943337d5325e1bca77062684873fe904ed9012474ceae5b138e079f941a665a995026d13d7eed9 008c30d93536b8cb132277645021775d86c2ba8f199816c7539d560ac6de 88eb8cada375ce7783d42d676a3daa3dd6301be085c6367e8ac6076fccb83755f7a925c8abf40a3711fb36f7cbbeffe10bb4f930cc7ba1fa63ad44363f0550733c8814e859a5dede0b0f60321ef45a7e906a2cf347931d4166289c6bda27271f +01e76755007b2ee5ac9e1d4c8adabad6d0f9c1c08ac6e2622b7c1ead89bd3ad0921b9525b49a780a262fe8fc0904a80391717ad7cac9607de55f7c744af8a132ec45ce79723f4a4a8c8b9ef658b360bd3890df164c9f1cd74eafb74feea251a34514ff2a57ae7a6d4bec2067cbf6ee4fdaabf13721bf9ae178b9034ac5e9665b 00fa3f15a506ccf7b50bbbad0a54d3223f5a95eb54f0d1f4e5d0cc21469b 966295f720935d148998d6db403e4d857b94bf112406bb57a996cc7e15a013f5e3f294026d10a808e2da5b1ca63a6248162d0ac9141b1a9937e48ccbca18c507f01ea325d17d57a7aa4539d80a5e6199a2e45167311c9d9fa02ff66d76f973a6 +e95abeeb2c51a8cb75ab74253dbe130b5560cd52e2a63d501d26e1458aa568aca6694be91eee5fdfcf582c47c1c727084ee2b2c810281cf9b095808bf7e7c668eff00a6e48b06df3fe6a445e092c24d5687d7d89acc8063275caac186c441bc697b2f67aa71b03294e1adeb7e557c296dd91304ba0587cda3c984619f1eb4f2b 006400a4830889115aa88b860b3fb65905b01fd126c4aec2785518c2543a b43fb82926455b7a023a23c25db9cb652cd84adbfb3fa0fff36ba2410e5b954bbe6b9ff0df98c3b6f5f639709811760117c68d12e2fb069901637444be46e97efc723cdb70aa1ba0d1c796fefc0be51c97d9355e6b8a62be172dc367805eaf20 +bb8d8515365d240b2071daef0d80558fd3d0e059be9f6abb7b7a0a5f47e2ddca7d1b3b5101d5c583143258520ce8db0a87f877a395615c9bf879ef46f2f20f68bbc9706f82781fad69019396b27f292cdc70fff1772e90205a2225f80889f9daece1d03914d8776ac5bad24d8fb190ba10a2ca17768b918c2e079d83734eb372 00c7b73c324250f14fac0edc941f79bdbc6933ee8f64bf94b847bee5eef6 a0669acd7f0d23a4e57413132a4701a53a0fa2296a815889a8937647afab6468537513c23b9d1434cd77a6b8682e1c8f16ef3eedd1a0ba563997c813ae80b99d9cfaf08562bcc5db781953fedd995f0ed4b8b0516b3a4718fff96b3f556661df +cd8b2403435fac9caeffa21b55eaba52d7efee0f89df7142340cdffeb89556303ca01a800429397e2ff6c746743b6bc60a87133274282d4cac02e4ca90ad95d80c93b84163b96296f67d40b2a1124b2b6534ab6b60fdee312fbcdf468d0e84eb85fce4ff360136bb31ced3998d29cfaa3ae685e638ee272058f123c4f35f8b6b 003db7f28e161abf52ab0adc8c4c8544fc989af081303b8688f22b7b2eb7 94ccb8c93763057a03ccdefbc283cf07c2ba8a84f89d754d2d7e6b78dcb517d1d564bb2eafa6f6bf72171b714f53cb9404e0737feeb5f56c265e330d5c4ef62c9cb2b82c67e802e5f65ada751b4bb27315b9f572fbc792b2f6bfe18ac0990961 +4bb08eeb202564efb5bda40777d71f1bcc4c7c10b611e803e5c570876f3e319e9e2bc2d32031c56a32fc0d1fcf620d4e4377d881e9e1695bcdb78acba370b849115b86c1c4b83edfa03299da8e7fd14c7cadb81a8e4911c8e427e32c8c9b67e317575331967cf58085cff0c0d48ee0b8e7dc0b49687bb1c70c703a5dad08ec81 007e9d2fdd017d6da6029e88f78927d9ac9437f542db1f1fa99e32bfcf1a abdf56362f4ce6eb7023d47ead5b848437e8773c9275c1b384ca58182fc41cbb54ef9daf66dd7d4f74c09994fd3481c811ffe5a32bbbad582612537e2c3e6ac310a6319768e6b7b9fc10f9a2e8e823c77f173686e3d4ce9e38de814baa5beda8 +0bce683d835fe64e6484328aa13e18b0956f6887b5e4442fce36ff09aed015889794e79da8aa60b4be565c78685674c51e1e7ac60db6a763c777198a56e382a03aff8b40862f961ae23e8b8683b76a5577769422418972ab0049119382edde9e752b42e8b93f403c1ef8665d7ce8530ce4ed9ebf6d397827cba6b7645e177231 00c94052760fc74c2b405ee4dd5dd2a7d38ebc16df9cc32df706075450b5 8cc67d2ea0d76c01a0a2dc115b780610a75e669020718e7ac45923ce3198cfb7e10ac4b531aba0d5498862bd2248152815b9766f1f3d02b962858f319d819c8356246ba9fce2d119b834d009ceb24c0a522c3e07e904322753a6148ed277311f +a6defc770426daad4dafba3bbd2a69881334f7c31269b297e440926db54cdad3fd7ad200f5ada2b72ad221ad99a06ecac9c2563a8deed89f0d0896991d1a652f6fa282affefbdb1c1985652300d1792725071631d75a182b683a48448063c7d2563ec3d430e0fd3acea33a35cd38ec0b5b07af96af71d0bfcd879d9864ededf3 004076b93487c2da8aeaeb4725fb53b7b41b465315335c18c6ca041175b4 b94deae49a3d0273a12a60d2dcefebcb35763c362f0570fe5091e4f760b707efeca44024f98ff0876c9b830ee8f6a95100fe7c5434b8aca3ce3c294d06d04850bfaf285d1fa58542262edcb864f53017bb5d89ecf70fb1197cc4b65666268f7b +7803cdf4758c199962b62943f475c6c31356f5d9b997a12e21146a2399cd0dd3b97a860b2ce639e2801571599136d4a8cdbfb12fd1a5ce22374991e090533ff42823a2c58d2076b772814eea7fd7a1fde68263ef912681c72c7aa3e5a7cc44ee8c65e72228b7631e600121ea35bfbbc783b6ae3c0c8f80198ada218be533760b 0076ddd73ee4fc1f5e6766e229cc7236cdfce312417ea291f7c3328d5ab1 b77619e2cea2c0c3b29b60c1851609ba930ee7735e179cbf70b4f887ef4dcae5f98ce15d752b9915c65e2224fd28441d10974d3385ff0bb1a49866e03faf6dec42a987896b250f97ca987fc7266ba327a328e6c424ce744fe1775a7a3dd8f836 +e789461e1dad0b6e21abeb6ae2e96385549d1bae39415188c8f833233da6a3328144c97ddb36e0ff4d9e19d84f869e79e609c51b32de59892fb0446dd28cc164a3e53534c950d26f87fb74e682db2038cde778bde06c3ee2eca2a077d8fcc2b0332e352e0e7e6487444a8ad60e78ff213b16fda9faf374dc6d27b7a3c4c6d196 007e1f8988ad804aae7d09a99be19384cc599e7652c02c391542be74b17b b6fdf3905d3e139c81cd8b4affe8e3518d78cebc3d7f5d8baf49fd4cc96628767850e056935c23e62f5ceccb35a84c7505a65df42fc4bfbb2817632b4fdf8100b085f481113e9cb859f9780c1b0db10e6626691204b211ed6997317704fab0ae +9b58c145d1b6c887f2b25fb672cd49c3a1117224be697c15182d4048be92968a6500f8bcf747fcf33145c13a8d72e891a6e0c4c7310c2b62f3181bf586fe32f1ecf4feee8c2c8bf6c2bfdf9d5f88981ce080095c93e49a772d8e7b59f9cffccec3ca2f212ef4c6748f64e224f4f098334d83108bf6f8c7b43c5eb549f1526897 009b2292b0244c2aabe8b43d95039984d504ebe05eaff318760e4dee739f acd69c547c2773c272c8b2ab15e4f315f1677f8fdbca0c590d8498ee5872929bd8516133d8ac97e758d3ce0108f9d2a817610e4f583f6e5c9b75db4e2063b2d30a4c4cd768edd9bcd3ddd0bffd83dd1af3d25c4ca52b7a02884a5a95d2c5320d +52310a901fe9681a23dd6e02f12974d57f2c4f653322d9a0ff8b338cc6c2bd9f4765c90c6b3c9fb17df3f492e67d204e39d81a8fdeb92c852a1dcc6151ed6c63049037235c6751c9a902748163a567b714725b4d3995e0edbde03215c645b1a1da3147f7406245432800c50f823a1f991c863427ff4c68e4e16d1b106ee40dd9 007ca463b50fdd92d9163f1c2bdfce2ee45ba1437b79162e3e959b814cab 87fce25d78aa6f585e983e8288625abb2896b0416b10ab26624bd567bb9bf62c01532f315e7b149fa2d887c6013182520763ab57fe46b917ca099c823476b728be0777c7e6321c1eba423f3fc3494be9ec32830d9876081fb71519eb157da43a +ff419c011601cfaf833067cf28dbe6e935ebeddf8b5111a97f6eebf3bb28376334f329cd877a134b074790a073db766efe018fce666a34650cbac285ae856fb6b3b8b96877282bc11cd9f9c8e510ed1f69bc2725a44a1d2b35de1edfd8bc9d20c7525ab0bbc27662a7cfc1bbd1e0f4fce5b88411521e3893e027cc8c73acdabd 00c3844750f63fe0c2e930bc38fe88522f4e72a2fd0db9778ade20e939b3 99eea2e74544a73f92c9fee1ef48a19672a7fc131d118057d8ef4eef89c19591eaee493996b84b8a4c79909f87faafae0b03529bd6e9a8b31e5f8c1c73792d705bcee7b453d867c690d2217facbaf9dd17d0898aea4c024192645c6f2ef0323e +05a89c4824c5de66587875011e704bc6e06e991ba8f3aed331cfffe55aa266a08c729f77b8d082dca4d286b2d451ea838d726cc2cf298fddf2d7376714c5e37b64506f353917caec525a1209391449c078c5197a371feade74f8fc8a1a1d67576edfda13c14ad324342fc0b09277941dc072ec0d39434ff1cb91fc59478fcde7 00a3bea235dea86506be4476eb7999dcb8e584a34238c4a894ad6823b93f b75f7dc9a6a4b830a0fb2ecf86cbec172511c4bfe0c9cb6db813eac0f085b59622bcb0294777b88e5955e87e12c0ccb715140462fd6907d12821c6c9daa8d2e9825be68e822fc3dc677423451e40f0bc008becc58f2906f9c290eda2571bb6e7 +13e6b5241365d9d0ef9e8b05cabb3248afd221ec02eab92284b98bda3d9272184bfe5251d35705defba5085381430e99b33a3ab77d7870e5102757d065862372df2434a25556b76e54ebc39d4e6c3aba5cd6acf0c335756f7d9385c1068d4cfa37526a9a58c0ccc7f87a8189176c5d4f201499236058ec061357dcdb5acdba40 009a367cd1cffd8dfcca179e167ea437ee48e9b6f42559dda9224701d3f6 a4062182b42963a0a5e8d73872485e6338c4eca5108f07f3787cd025a768f0b519bcaf2bc02b6b14fe315ea6636c14760bedf2e9642ec95bf9321da5da4523154c033ec1c898ca880d3e759beb316f2215e0dfb612204e5434a0d6d856932944 +139a1a5090b97afb8fecfff8745efacf7dcf91a4393a7b629564e598d58d5be39c05c5830d4c8ca85d29e9e2c31ad0447864e867d0ef4788ac734f8d871daebceda98d449308c2afbe97724c3af8a468f1925065f39e52ba4b7d15728a744b1252a20476dcfff7bcb82aa72c209e72abb3c24419bc26191390ffed340c1b9c6f 0046f4ad2522e78b9b35297d28f361fb0ce82306322aedc119251d8241be b851e5c3be8399a2139aa70bad566ca40ecd1d73ab632470d3fb85c9ac13a1ec88eeff1ca21e425b0e3932c010e49571189638984c9795197bd1c7424244333edb1708505153453a743aafc8d28f3c075285e2ba5c2f3950cfdb4a4ce8cbea15 +3315e5cda5f252e3291b61e493ab919c20a8af1286d9660cfa2f5ca38b6defe19ebecf820787fe692d04eae8a5f5d37abfb593309569cedf45efd0cecef6951b718924c8380ba52e8ab8c9bfb2261ed5f01cc5a5f9fc5fcdd269a0f122c597afdd9a836cf8f96838c3e8962c1788c3ce4128719b3ef4fc88569643dcad6da16f 00ac82137e9c7a5ecfb8b1a7df9ab50732934566a392a6c8915ee8ca8144 b75b5e710a5589c63df17b0c7c0b8a65903baa34b3a60574e6d6f57be3c6ee7ff11592a4736adaf3fbf5522e017c646f0534fb736a9c041e022fe45d8c17670e430d7bc4ef3c3ccb59052a8a3fcfe8f0038e91a363415d2d89c5e943ef790cf4 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B283 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B283 new file mode 100644 index 000000000000..03de21c04172 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B283 @@ -0,0 +1,60 @@ +067f27bbcecbad85277fa3629da11a24b2f19ba1e65a69d827fad430346c9d102e1b4452d04147c8133acc1e268490cd342a54065a1bd6470aabbad42fbddc54a9a76c68aceba397cb350327c5e6f5a6df0b5b5560f04700d536b384dd4b412e74fd1b8f782611e9426bf8ca77b2448d9a9f415bcfee30dda1ccb49737994f2d 0299ff06e019b5f78a1aec39706b22213abb601bd62b9979bf9bc89fb702e724e3ada994 905c02745f0f549b3c6e2c4f246a8f65a4062f8e3d82dc32a9c97607eac2ad749c01083e3e13cd573e8229e227d798861400b9ad2cfc91126059c1a097ae9762791e4940c5f11a686250f83565e78a111f2977bfad30ac15b5dc4828b34eb9d0 +44adcb7e2462247b44c59608cbe228ada574ecb9f6f38baf30e42b589fb9b157bb0560e5a2aa5523b71cc0d7f583b502bec45d9b8352f29ee1842f42a17a5b16136feaa2efa4a0ae306402940ecd6b71e57d1467c98e7960de2a97f88b43487e4f4016af1292381d70c18c7e6eed99a14cdeb5b3caf73688658e4c5b54c81e08 009c2804f8cab768248fb3fff8a055b3f4585c00de5c1615a19f9425b9432ea09afba8f2 aa16169aaaf4ea98f5a20d132dce6388f533c7f01ff7aaf015c9b78f6e1072a5642b3192119d7f169caca757e923b44b0381bf45909591455b750356fcdaba451f4293090322e5ddc9a3b17b91ed2550ec983314b7cc9f4f762dd57a07a8d4af +cffee6252c7eb6d91d8fe100a1e62f0ad9f862d78ca2b747a6c17b8c9ea8980dc239b3b673310e6e7483582399163e39d889abc1a613fe77849ebc09b4f7f4fe0688b8a9869ae918a88294c7ee199be50ee9460db14725ae70b449d0cb48f30e7d817ec02c0cd586119341dba0b74f0279330807cfccc99c8c340b72c1764a45 02e625a6bc6d0ce7c06231de827068bdb0abc8ffb57c82b35ee3a0f873b9473905974d34 a1abbf78718265c73643ac29aa823c8a11b02c34562c2b06a4a449fd964e19c57341d90e44f2db2849bea7d06a32b5bf114c80312057dd9eb3f46b8466233c52abbd6131314f1d5ec8aa277b58bbd09cedcf15d98dac3f723c534d56c9fef01d +d058ab5dc07228253707ef224897ea0fcd09c3d5cc91fdce9e03c1c59c53fb4596be2ed929c7455e67ac7f4891aed3eb06ad88f2c4aaaabff045b959f900d1019d706b60526375851bb891494e99995928e4cd51c9616aa651ec77bd7e398916bb9ed3156391bf7fb1e29181e2b011dae2edaf803607def2ac6b194929a57f45 0376ac24e1b86f8a55c052d92a0bdc6472fa03acdcdbccbf7c321ec0ccd97aa0a66b4181 a00990857bc78b952f7e1b8279de59ecad9b24367b6b03fa5d1d3bbf70d06e8895802faaefa41b514f3dae706d305a86048cd87a3d92da71979f220f4f6649fb6696804f581867b46961b1b10d368a4656386d6f0b52340902bd292157358445 +c86f2cc7ab5df5cf1a236fd83792769474cef464032800ffe98a44cf29dbfb6f24088160eb31a11a382ff2a49f3e05e983462f5304272f96c0a002b69af3d233aebe867ee63fa46666760a6889d022c18645b491f8d71b6a3b6b4ef058e280cf625198715b64b025bf0449445d3dd7e1f27153926e617bd2c96638345431d1ed 02b50a6395fc02b9ac1841323de4520292f913519bc0d6a471aa28021322fc4dbcd7b802 91f183d0c29ccf5cd8116ace89605a7ae0f4b6e980060dce7e87aa364b04506f59679e0c9d3305a8869ff067e39265780442756b48bcfc07eb5dd289b0fd4062e54d30cf0b4f9a5dd9dae41e7b2cb916266cd88e7c3380c638e9704a58ad025f +c1328d8d2e5b6ffc850a9600bd6482518ddd9cee3fc9140febb72bcd444b0cd7e8074587d51b62cce4b3d4f34ad3355353fabe363369cf790db2df9fdac3a0ec4757e2dfb3b683eaa3e26531691ce765742e1c0bdc0e1028d347b6085fc459df0989c6a144271454eaffe413cae2ad7c8b2371fd2df1afffe56df727009765a2 024e5889722f6c35e18ca47effa9e415b1ba790066a91fb3c9f7b001ce28fc732b09bc23 aae73e2545e97e4997f0b93846292b6086f0daf007f52b7df8f3e7668707b6844585e6bdd3a6b85ddfcf295f7029c647051a259f1127072d7676cc39059345ae1306d117f87a8505629d66e55360aba688f9e3326935a2c2c62c21f937cad8d5 +7176b7013ea27e94281977eacb976bb31c753bf80fa09680a29128a6fc15234f79f0e9900aff3217ce9be72c378042c6c34fced0158740073d1a985fa25987fb218002e425868fda5a47de51abfd04de34e2b8634cebfbdc98e80f93d94096193eaa82dc8778fc23f3765c7acdad94fdaa272df0ff0f28190c10a462ee78ac92 0056d15b81f40b6378588a5efe43e21b95e18120d514bfdda0e7759a1d0766a8a35ce5ac b564066de33f96d8004bd857683c0a0eb1cb10f33945bca4fdab1d268292be7b0227a2f843f34470f49be7aad686d18f03b568feb2a215f7561364cc227b8240c74639c4815b33065d0031e381f6c1fcd896a6c582fae4772c2e51866d7bca8c +4c3642ba040a9955b9d50dcd1c936688c17c363854358afa8ca49c6abd906dfdc4d89bb4cab0bbc363fb5b74e1f004d4b09ec9dfeed4c0bfb482a9061a1f487a3d79195ff7b65a0504bced3a28db0ebe8fcf8ab1ee4a3ae91324d15d890ac4c479144dd5538d2e36d3a587769ee9cd2d5c6f85a03362a022fe0efc4a3902b71a 012fb2fb5bf5f7e42a500154823a174ba2d05af71e3b0cf47fab46e673ea1822f1563def 99395db632ffbde09d7bc09e705d2e61a7275cbfa224832dd38004878fd7f646670df411cd3dc9e300f5d7e01443067e0f2b7d11a561de843de76d8249092fa499110c089c53118fdf5a1ca153d517bfe9685973482ceba2ef1c913ced3ddff4 +e471f39c18b081362adc7da47dec254dab8d765f005ac574640d78c14222639245563912d942f3be212ee3cef134407334c8fe3602fa0e1629de5331643d76715dc1b0ffcebd484d86c5211be4b285a31688b205fa988e6c15b36daf396ccdcc209c7dde2a732f5c31c84c7ea041408ebf15e56632583af0131bd7f531b5fc45 030096c54fd480647e017f8cdbbdef292e799f054e3279d228b09816a757566a744a8266 a8499d60d758e8455dfc7464f9fbfa242bb6cceb090bdaeffa2b56de3306e555d4dc2ce8651058211cb0edc2367999ef0e5edf7612a7af65aea874cc56926915fc24ea49841c4f36363c5eedc7250fbc30443f31c34c1cd972658b05bba99bd9 +8a93fe53e83075c4025228540af7e96a588520da34e3eadeb99a4ab2f3dbbb8f85fe63a3b86c1f4ec912e665ca05b43e869985eae3791b91205afb1380e16c25b74e6793fa63e4a55dcf25dc22d03f09deddeb9042b620434111afe08c5657c7d754af66ad91a1b5423301b1e8e6389a1404060d1b6a99fe0f89598482979e42 00a1b7e9c8c2dc25b494b5ef3195b294e41cd3c2c35235ab42542bd3e2a52d5826662bf9 89e0f2748e6203967daf15bba08079bc2c2c28e4b042fed76b614ae113ab3921daaea2898db1fb4bf2a1db50b07ffd751104b20b31540e8802544ca44f4068aa84a29cd5905dd54fa17a3be4bb46d56dd95c5aab6f3188cfd4c846c8c7bd9737 +e193a8ef6f454ca1aed38bb67aca6d08280d421b196d89938c0582b7cde74dafd71716f3818940af412d4a7ff3960a8517aee108ae03576b68ee7557d35e6f1ab823d124de7243dd02b542591f62c80d822608572889573e4c9dc62f99d68e07800da6f83cb6f5e03d1f2ac15f90e38b4f25e0a75e354e4b60cc81c0bbe81d39 0059b1a8fb84530bba7a607ee88310e31bc6ea6a6881603567a1081a05a3a9ff87e719ef 9147f38629dbabba453f5861ff2aff8821f758b490104610444c76b1b9910c11dacc9154e24e55f79c14a3aaa274ceaf16f62bcfc7150a1367889e5e19492f5d6f6cebe73a3c9e0d57cdfe305ee6af07a3bde178628e7ca93ed317d036ffdf76 +8a99b9db191f6cabc88b430bc2293e6774d5180f019d871839289e25aec29379f14606e742190b7aa062e3b29fe0254146d9614856c5140c7315015abb98ac00da2c7e33cbcc82c24b797366f12767322c4381454d9d1eeaedb616b0ea5c66d1422da459f18081f4f966d05ce279c6ee69b1bf94b8388d38d4b770d9ed69025f 030ddc2c7a4ce300cc2b75f0f977033f16c1f8bb13aae3d494c381f9a6dc8622499ae4df b2a8fb645b7eba2805c38f5ad603e0681f43601c9be270d538384df01d7f8f899728ab7314972f3b95f528afc93429f30257c70b9885fbc669f88ea4a2879ed28fc1f41cae12bd16b4f4764f9f7ff2481399651d5db7361d0d3d77ceb624685e +5c437b331831530aa94623b1736f00b986172699f0a02a5e5df0008bf25341787e2e66046f2c929dfe0058c3cb89fc5bebbe1025bb1edd1ee31522ed568e7b5b4ca3991afdc76a68cbc2c4f81863e27fdaf6a564fab2c6354e5c657de81390f8a4132669fd24a48580c716b5b7961a9c091f614d11cf45dfdaec8946a54a11d8 007899928922fbfdb5407517725edf231d15a8b62d90b7fb6d8c8d20424850dc44f797ed a6d8fee2ddd1505f64fc9a88ebe6231f6e69f95da62015466d4d91d5496a511d30427d9ecf2260abcf03b11ae3a9625a103f27bf5de03214489159b619fe520c5cdc37227ee75ccbb88566cafcbd5be44de37f09f8021a3586eec834c146fc3b +91aa08567d8da4c90684dc06068f69deae240212842ff1786f04ec41b40d9187aa92c76401f9fcedced62876a34df82ad7c1e63b68bb2a972257ea8542bda6a7f1a020c9b122943b6d651abda8b8d322a8fb762eee376daa2d3637a71ed6c4f5cf96f61c0da2d6e1dda3370d80e51da2cbd8aef3267168c67359523faf910dfb 02a2af63d1171930758bd3e5bfdac62cca1a83a3b55a49b3f80cf0d9ee4b2082757beac0 b3a3b393f0e76687aed2ea2c8190bb9f745f606da70d16e68e7a680ea056d6ccb27722cf0dc6f876dfe75800dec7462518fbc4135b627cf8538f4b45debaaa158b303130be0eaa40cc3d34ff2f203e984a4c28c9dab174318454a524eed68749 +eb5297bf408c1a55e400a20a3c10acbc5c2bc6d6ccfcc0941fb7a6fd4d2834415a6df86c3a6c4b867d1215aeb8222153da8cbbb1576c92c07ca2c36d8f243fd911f9a057e39ee25832454e28d7ed52a8d04169b9b9677a16b32d5d211b8573a8986e9bf36d7206417ad2771daa11bc21fd7ee1029b65ff7c9b2705a6dc9cf9cb 035994e89e13916ad82608f74a639e6aceb756ff913aec440519946d6434af9a60a6af49 98a404a2956b4116c3a523baa6d68ad7829de2ab6a2753aba20b707e7fc2b3a34a8b1542855af432c9addb8b0bf9a93e0c02eeb4a9a4cb20fbdc9447f90f23cc89fb2e30fbf4fe005386e430fa2e824a0f895e0a68af0068d6d0fc96d5fb4d43 +f415d0adcd533dd8318b94560f86732c262ad2c6dff9dc83e2435543f429a2158cd2fbab0d96c027f71008c4895ecc644c2ceaefa80937f6cc6338d15d36e459a16bd9387a361a6d800acfd834ad5aecf442e30b70f5bfa164747cf9f89325b80976052a83a5e896c00c54f81472b14329cf23bec10a8e693005de2a506ba83d 029639da33f48e4fb0d9efdf50bba550e739f0d2476385cba09d926e789191b6fb0a73ff af26de35f83cacec2bd75d1f49ee3ab9dda0861e6b97e385788a6135fe4f4120bea5b5000a7d02c1a862928a19daa81c03fa5d4e1172483939e1b52e8542a2f6723911910c20f836bf20ac95ae6fdc46bcffcae2598072324e18c287c3d9a9d8 +b178d86c9335b85e02178fc4551769db589ab91d823fac219c7e14e2f029753b203962389476723832f8d9631dd7764e6dd35da290afa42a794476f5c7727b3688aced848dabc9954201578cc7b25801710931f45cba1199d3788d64dc0188412e70723fb25b8ecb6718358150c4037b5b81466dac1686cb5270bb1c72d34bb1 00583a7ecbf2a975a32d07428d27ac82e5dc13d1466c4fdfc1e6a05a8d9a289f1010617d b19851108b3b5efbf9f027179e17d9f2fb542a0b996619c6fc9dd0cdb7066308eb380b075ff1e45ae5b24cd8d595a844042f6279a1b475723e663bd8ade00aad1cc5cb7d75db013543748c2dbbfeea64e26a68bb7416d61ccf9839189f9b977c +c8bfe9fa7c848531aa2762d48c153cd091100858aa0d79f994fd0e31b495ec662209a9c8761cd1d40c3d8c4262cf4dc83c4a2549a5cd477726ab6268b4b94a78b1c4a7e700812872d7f41912a723dd9abc305420ea1e1fb1fee41bf643f3a24abd6e8fbf6fde2475e290527724a6f99fd75374bf7cb01b34d3e60d8db33c4de1 00f817ab1b49131fb9bbe8c112c25a36f064efa85de7506fb9cd29d81b326bf276277f7f b585b12b2f40042d01ffa507abdb4f9f394af58829a5d391b1fb5b74b53cad9866c03466be1d8721f8212c68aa31e84905f7970db8ccc0c29f725fbe4b54b820ae0213301eb11078757debe1b838825dfd87de65ade87d8efc189bf96f0f5e6a +9a5f563d0f9fd1f31f3a822de628ae970954f4e71292492d727109036491c29e66b9b0f2c90c26abe94c08502f5e923a9ddaf6a7d91e9541ce90d0a49f03ce4e4769753d5b7d922e1ceaac4b4cfa4262732a09550aa076b8ff9d46a50fa17de17e3b6bd606698464d116fcd5f1ae11bf45b0c48d3b738427cb47b0d1272b03cc 02782af76ffebf3e2bfc0576b70e4f4bb87c762e2bb230d278ce776310a14f5b678f29af 847d42f5a9fa6e73e8b4227389d2a9455ca6a9b55636f3f07c62fb19cd6306d66920a90e180b2fd3cc479b0ebd0cd0751329188656c55b1b0b6d382e4b61e4e1c61d5bbc2be020dd8afdc527b56b75ad9492cedec52ee14975eb319018c9ee70 +3d6b065721da9de82cb33ec2c27107eb399b1e69ac8fa51145ed4147e20d72e27434104e76af988a3bc94f55e36677a05182fe2376dbe38195fc6a30673a4dca87336c7304f3f31d49216fbdfea00fd1e105d8b0c13ab11f8892e0045e915c17dfaab07b24ed21b06af5a8cad4f45fbee5a25bb6e87466a7bc422c0bb896440b 031b827b88f14d3822244809096157df3c0aa99da90c00cd9f0b18dfe306f6881834e6b6 ae37e94a3737bb1d10c7cdaec9a1a18973de707a6da3b526a052ca8427bbc12214dcf0bfb633b879de5f0a0d502cc2cb043297755243cfdd1514df41d3cc7a11a17f114d7579f3dba912a985793a3230d569d0ac93cb7087ddb0fc2861f2193d +d125f0e2e6135567adec9e77da2afc6862e28d618416632ced829d14ee8b61116da59dfb44098a40a0b927731125617e3d2f32cfbd1546a6e758c1ab6597e75db07add52ecb61d37da2e9ed04df95b36ac249f4cbd794cb561655cbbe4b34834c497b3d392d78ed0db8db683aff0076fb6e43acba3fa2b91210cc6cf3fa594b0 027da4916f1c471cff80bfa14d12aa10270fc3b26caed010c0111f6e5a40d914a3927763 a71caabd10c4ac58676a714f0f765c8197d42b77ac5972b46718be1b89f5b0c2e4f107797d25f8befce2ff2ec15904de0610fc6b8e5dda3c38b5c587fc937189d5ca4345e4c98d90ac840d8da5a0d9d9ff096b02e1ec84378f3ba419e07c1077 +b380f97687ba24d617a42df1b14e5506edc4b62dfec35ed9fd886bb769832cec7f9adae10c21b7cd9152588797b4efc6b2b30a873d3f25e683ea9be070dd69731949a51121e534fabfa3a2eae0ee90a454182248bedf2595cd47ad08614177d58f7a773f5023b538f5f568682c83fb60e3fb1aa859948d01bf7b214e7f2dc719 010608eb51dc0ee97d6e488a23c582ecf0ea1df9a24db77094d87b3fb6ca98507280a934 b3cb5ab9282dcf4c14b9789f0e14ab9f380d29209144f0ed84219c90a540e2593dcf815a44eca6996a818b70a797a6ff1138c1a7a41f5db28bf60fa918143633aa2f4ea53c90caebd5e8323a5a6f793291f920f340d452392ef305d7845726a4 +3f9ec57e4228e1a6ec49df02c58d756515305e48763ba1dc67298be9a1548576c28c82b4e9b3f62357d9b3c522b16d5c496a39effbdc8290edd2cadc0019e6b9fae1e61238b13b6265ad2ff413a5a0684babdb0013e7632051455e6fd943815213c555dba96cba8911e006bfddec6c3353065004538f37e48df9e339498d85c6 0123f9eb8babed548df08cc3afc1d3b3bbed52b538d4654f2088fe76062fbea75b85a560 86bc54c0d504700c3dd059529dfecb96c312c8ccefb4ad9e328deefa411c6f36152d855ba8bfd4eb11c15724ef818b5000303b03d6de73c7373ca05a9f555ce33550a0bb170fa726960479789fe9775ce646800b9d1e9ca79c15210dec508a34 +bdbd7b7bf3337bd9d21a3c6db379f95408c17e49dd394e94737ceae889f45dc0ff5d48cadc53703a16b5589939506b548f8dfd34c577c084f372166cbea320c8fd07c809b211e0749ea639e68f890affa1569b66bd763c7c710989e491011371eb1d93ed9479ff0216b7f79c901a2023e2cf80b565d1c0517e73117190cd2f02 006a18e626452111922e02e31d662f4301319946a204ae8a34f06b91dd1b5b96456365e3 b299cbdd16ff42f45ca5b7da40eea6978509ffbb0dc346466c845b11850745d8e3d9ed722b9d3a17aa4cb4e7c4848fc70001e93dca44c3f3e4cced227c58f17048a066dd9185afea0dd5f562e4f1cefbe36c7cd7933761f1419a77a68f7e8901 +436b288512ea57bc24f84fdd117da9dc1858bae8c11637f99295d88fa9d05e3c053a2584a6fe200ad190b3077d9a1608f660349dda405066c1562f6897ef69b6b674d6bc11fa470d0b96a7cf8f6e098c9ac03b0ef415aa045867ac7c11d16cee78ecf08850ccabf70f761682b561d0d0e4a889d840dc74932648ca2fb58259f7 03307fd717015b12a2dc76ada21442ac1d97519f66898b214c2ea317ab0f0905e819e4e9 a450be72368822d9421818a45cba7355e2e94726e4f3f12010dd4b7cbcaafc5b664cb7f6ff6b06aed5b48a5ba033b4080a9f505988b0822701074f967248a0fc8f93804348c22280a0db1e228fd60e8f324cd141babef868b46ea101172a5a3d +672faa156dc188bf16bf8933d65e091c633f294486049ce96a4a403dca28a149f4f840e8bef47412285363e9e89006614b013a41baad9885f1d9980cc897ffbd5f8a7d0e63feaeb42c07776efb307ed680ba1cebf470dd9bd8a2a9efc2b1daa569524394f9a50398add1a5bd2f7c263f9e63c2d49461acf98444fd23341ce78d 014f9f412e3c7d770626e800d43cfcbba3ae6aec8563af748e8a97b67d244334b6e6d2b3 8c54583f1527b99794d14d036e87b381142220ec7addc8a37c3ddc4d36556cfb777ddede2d1d397ee4562b7f11dae1fc0d8a7488ac2768cbac903ece9f313a62f198c164e25149d0dafb1cfdd7fcc216e9a93baf6d259dc96733d347c3ea75c7 +4321334cc8ee44f1cb392a4b280a95561809dd3639ddf43b6e11cb73067597988d95b8643d86c76c3c6b932d9262b9b8b55a04fba0666dd8b8ff1e8fdf799ae3945b6e30d3af3966f1a6d634d5e012710d66cb447fc3375130968a2e1e647780aada2609d87247c90338dd71c3bcc3902311caba27d5d4ea4d73ccea960d4bfa 03091a6a8bdac1e43542dce752694972e734dca31c061c7d1000754296d0748055db3f09 962a5dcb81709c4f9f0440c2e386142da03a181a7d3a7c9cf49b2e081e3c9f335fd482aa94e9763599aa650a39fa23b2168c65495c1733a8a1a94417f969c948be899ccc2ed8bf6afa16ac78f0e6120f2df718fff9a90e7f188592e1510386b7 +2087e22094570d39fa937f15a3ef0601709a66666344186a33b487d041793fbb9709a95af250b1df0762ea98e911aeb3ff1fa19f0aca53fd4179e454e0e91636e55cc5b17cad9e1575c82ad265dc34c4a66b7a31ecb9ef9dc756f2ac1d9dab35369a6bad4a0f47e629daab91addc6d297d1e5d81477b3966d8c3b607ed194d88 01195921b91353db9bcd00510efffe009c94f6bd8d790f5fb3e5a0101c9ca5d21c6ef2eb 8239ea8e648f6e19a8c0cba5b8027e5c2edd32cc54c7b4d528a9c7720cc9cdeddc646b7d14152df0a1dd1f58aaba335201b661b78d5691d8c44f854db1afe41ccd44283f289dd8ba8ea9d3b93837238a517a5afb902a70ae409f16183169d0e3 +15c7bca449a73b03bbfa783f5a91ca0b7916889a5d99d541e2e8593c3b176a5b634ba20b34407fbd94ae1c1398f5313cab7402f3bcd7ad277a8c66d09a6df5dd086b20a0a3823fbbb80980cd86bd13e527eee15656cc977103e80113539e26695addd9eef6a1f56986168d9a53f8b5de833f8962c3826cca106ae9e8c00208d2 029dc20446e9abacb43823e12a83737b46e6e577466b5a3925e0f9d496824dadb4d4b50c 8286fdb8aa944e6eba2c5866ea6939cced20bfafed7b6345f5a4a5c1596320b898b72c046ce4eeca09b5c060fe3ed90702ba8a6339d03b36401565be1c29b41612063acaf13aae0d72f4409e25233721f9a54f721596eb526976d742d515cecf +d12fbb82ee7a57eaf76b63fd6bc6c0a65c85f135f019d43ff7bc295cad15d53729d904fed63d69d3ffe8b82c0ebaf0399e2717ece40e011f710b5db46aa457c23b85545953398b814816a1e7a8ab5b0b14c4a0451b0bda9d0d2ec4a374bcaae208b7fe8056bfa17d6b7ffd4ba2e9179f49b9cd781b0c06f6ce3eec26cd428cb6 03b9b77d19a42e9a555da8ab70aa5638890b2ed21daefa28ca6323fc658662dabcbfaf52 b153525090109491be136de85cdccf1116361e888cdd81df7c43b63b7ba7c148139c0a6a90503dc8d1f2f241b327ad6e02c5d0ee595e83b5a3ee105962f616667ee3909d2f0b51af201d57c6a559fba165baab66a53209b429566882d9dec7a4 +eab0a37915c6b43b0d1e3ef92e6317b3afc8b8301b22f6059da8271fc5fe0e419ca6097daba213915855631af64e10d8382d70599d903d1535e25cbf74da3a12ba2f13c33a8562e0db03edce791f1d39af8850fd1feff0eb25f9ad0a86dfab627b96e65831bffc5f6d9693d20493bc9dd6eb3e9325dea50b055768e8aa30d49c 00b9f8f3e89e9c1ef835390612bfe26d714e878c1c864f0a50190e5d2281081c5083923b 8d9ad4a6fe42245b65fd150b64e4d884306809f3757d13f64d5385ebd208e2e2fbad212ec092d41554f9de78e122c72012753edb94f0f2aaf4fcd6fa06aab4dbc5f2b2e49a520c451df4639e1b90262edfb384476df9741bcd8b8dd4b7e22375 +fdb93afd5dd1e3eaf72c7ea9a6cddb07fc2054499ffe152cb2870163eee71ace5bd420b898cb4fa80ea53fbbaece2a1eef6427b632320e9c97e38acb16b62fdbf6585b54fabf0a703307ca50f86387bed1815a05b0c8991e0743d10cdf49c8facfd7ddeb8d4a7b706b5a29e1d00ac88b0ee88b3153185495ac8388cc70104154 03a30a1c15b9ed71e102341f97c223a9b5ea3e6a335861c3cf407ef691a18cc639dbe74c a9da75fce67ec44a916b0047de7e1fd0f6ccc2e341afb694144db6a0a620b87a84ef89a07c29090ba8465874400b95cc198b764566017ea4eec51c2738806407d326d49d20a9c0be86e21475012cc4762ed4ab181bd3e98c0d68a4302de16b06 +c78e35d1a5b1bbb0ec21e7ba7b7c74c859d88f3e100e40ae34128cf093885dae4e87cd09f3239dd8e79e25305220880dd352a650225d9bd193b9b84e488c458b0b5fde1af941c0c9fdf952d2fa41f665918dccae27ab7923da4710f8c27ac8ed424992568dd6f0a6c3ecead21650ed162e0292104eef3c2d8551be866a88d279 0083330123cc64c11888c1fd388629d0b329a50ef31a476b909a182c930ff02d0c389b93 890e251651727759b3bd929c8015fe8407af019d33033d7e54c870bd6cb486da45af4596ce3211e767b1c7b7a7c4760804a10e882fe43688e9411a10cb1ab64a5fe4cacc08730b6f24de36adf3401d2ca82dc7fcacdb7dfd1c447bac6ddbea63 +e05435f695997229cce314e50065f3c5f71981988dddccaae6efb81f936b22cb48813f506d1edf5ebd69b0be34f278592c5935f0f6db0cca1ef9d62834fbf3c4c03f4da0596cb4d67b7b767e85dde7b7c6fbef7d89babe6f97b876b33594a9e36ab87079861ee556fb03274ad4af527342a4794192b8933f28c6220f954c77de 01dc2b656c207eabc9e0d6272099babca8d149c9c4258b779c2f06de75f76d77505271c0 8ebdaed664e0eea4ed6a9d5698c91f22a544e26f4bb8da1b92228a7f0c5b09d05bee8d5c9d0ba4620e3394f48bde1bcf16b34af263205e18fdb83bd5f5516f286a179a572b40579c053876ea1cfb81c6aa007a64794cb7037422058bdef8c4b7 +0f9f36477076c4b5a7d1ceb314a397fb14646695b0803e36e98908c8a978770269f165a1fed8f4b655d4efd6ad283d7f5d51b6e1e302d360e8ebf4e887c7523a757ffd55384e114bbfc6b7a0ec8511079507b919065ca018573418f9e394854c5704227772161707b4d0246ebceb91192f0eb2ea994ce61fd98a6d14cc8246c5 00081772348ff2d7a3fd57fe703555ab2e14f5d203c4cf0292f944e827e884d95f3b1d83 8b0d64974c04e87a07844c9d77e5097ba7adc130bd7ccb3f4d4462c1bdc878a4ca65546e1e368ddbd791374149b4ab9b158f0448355c991cea9ba57268e2396d5afd5917798a49dde08e30349d267a85435b5fd684785b34a5a9178312fc3e07 +1d38b1c342b6611dbaf412a66c1c0b8397692755f576df33b31c2bd12b7f0707cc423376391f7b00aa4e7b7fe54532e2b39c3c5284b9c8ccce48eaf9308ed338992f1d4ecde6cbe352e46339d7d602942158387881d9b493fd40cc59d4f9b53ee4191d42352c6f7bf32c331f0c5afbd44a92901a4b713c7cf6ccddf7de4cc6e4 01eb6bf2ca1b5ffe6f6a795733eaeed12de6e87c53571e702635b9dbd0d96b47df4a005b 834e2f9ee408aab2b79b2c5855ed4397957a35d4f38a7f28a4f0b4b6db367b3f065e1cc7c2dbfeabac5e23935e29422c04cc92f04358302139839b22b204b44bb7aa89ead01cee038b4268c2bebf5d3b0dc3c64b50bae633b1c1e2480583c2a9 +3353ad05ef90e9762bcfedd6ef44a1e8ea0392ebef30cffd48ae620f3e567e1cd44882d514e7c6759200d4bcab18afd3038c3d3f8c50f7bba32a04eee5a4b1cfb8c349939e4efe0a46fd047d02ed000d8fa1b98b0af5586f120d9ad174b3aea33905b979ece1eb3660b1e070c8821b32df41904ad68bbd8ed247aabd94066f16 03b2a3e65e5a306bf8e3955b60e856dfa9bf68c1275a678ca056207a0ec67c96eb3f8309 a1d027f10becd25ee86b8b70b44e7588b2647a5a288809f98dfa4864c859dfea8a6a342c72bfe9882ef9f89acbcd5b1f0266040bcf49c6d61b09225e8daada45eaf982313830ff1ff6a2d36050e23592b465579d8409412019f50689537194bc +e7ec162185fe9a5803c6b03d98041422315ccdac67e48fbd07a1ef3c5661158710abc6791bd0a75d56791b4ac0e7695d53c5989d9fa6a3b037583b2a80d2b154b024f1c36b63548be9afe1d51f2f68b2ba94d4ca1e69a35ac10e15ba72242aac20f7526b12ff9d3cde9a9bfd70d55adf9bd92c66d092d7d08e9764c84bf7f329 01fd4d1af0bb7c79ed5fea7bb45574e46534387bd916649485ef15207352d7302e81dc01 86d0e5d9638186704048a778058293e7d9ff02aab8404b8e18db08870b285027cdd67aa4cd6d22b15ffe69155341e2c216cb2d55aa67f5e91eb632a14b563c51e014543d9cf636dd76edb14236c4b0fb2f41ead0a64e79555adf2b5283ce8e74 +87c8f2e3f4fdebce0ca9300fc1ebcaa934f51a12b6b8f2cb6bb6eb77965468663044afeb2a1334cb5a81e74b8427267f8b34b5e9ff0cf157a9f18be2b1942e32ca61dc23ea13c3f9fcfa16df8fe05e067938b6994982676463fb12842d4ec532cb904cf222aa805dd0d86ab9a33a83e294c6d81e8dfa273835e62e9041dc8ff6 020380b1136b5283e9b7f54b7535ebda33b129ceb177bf5d3d07b1daed5edd9fb3862530 ad9e30b131d3b8d6dd36883e730bd52a5b9463734b4b9d099522abd2293a018e4ac6946240373c2da02de748d59084e418a7726269f2d2b8a2023b733aaefe16b7fe42df0931ad72adc8f13843990bd88d83b876b40a45159c9006148178fab2 +2ac53e8a50c4afe3b38904255b7cbf150c5f79dc15932dc0ac9aa631521f68a0d4b6bc5a04d55c99a36531fd4886a23a8d99f262ecd2a9feea925d7a96ebe9b6979a207b7f9378afbe404fc8e959b0333572a2c911f8743c0ba64eebc7ef12fe5435d2cb0e5091ae518b6e4233489efe3c16c6f21abf4e2c6808b733914e5a7d 019f815b98836948e0a0dc9c30828c31b13e175f1e79f23d084ae1bbe64823f4866214b5 855e71d3e6e451ae2315f82c7d9bc84bf82f51bed4d345f79a0b49f29088609d2ab033ac4275e8e5957aef0491c9726d095db051729de50eb32772a41ef05edbafa211a606cf4e43fd466c1f01b1f995c030a527368b314c604c95bec9b7e266 +0b201469cac4c078f587edecdcdb6efd5752cb4a3f43ab540463c4d908c27527aa3592f2f9acad85dd94a3c056bd28618317ebdf2e7dd6c5ad26fa3c31dd8e5c50c60418d91c93bcbb59ec1adb1db791f485ded78a5cdcddd23dd1cfa4f13443468d8a5f2d648059b9c4470d0f4fe7733d56a28a2c24456b6923703ef32cf0b8 001854e954654e726cf4bebc0e5a840e8809fd716059211c6ffeaed36829808363164684 87b90d4139aa3f8479bbfb9276e51c5af090bfc2514b81c3f9215c811fdccc59603ddf872cd51cfd378fae5e98a6d12a1464049effe5edaf57f03b4ad1f331500cd5e181d2bdb16810f88031388c415d69dc8ac225b7aae82cbd6a4e7f33bdb9 +fc5e4dddf4c4a328b685035ee79069770fbebcc56c14e31afb4bbcdd5220e025f31eba794fd6c05e64f19678dab33ce4f084bc32790392f14bf35669d75b6466b4214ec30d58ca90ae285c9058f5804a1fc9d7a995958f2a0e84ee52e8a78b601bec04ab607ffc2091749cc548c6754ed14e2e5f92315bdacaa7a12823ef76bf 03548f8020819588b3202f4c1ac62eaec6a47c2a19b2900c5a3cf5b4ba5804231141c647 93405c46be691857d8dadd7a64fde2e7dd9feb6e4d17cff913465ae84501e953e153408b21b94bf7c4b4539b8f15527a19587ab1caad4bcce00130a9538ee78db755ac86de450deca19bf67b56ea7a31d3436aae9dac301561bed24bee619ba7 +284cad790e6207e451a6a469cee3befc3ec43e047cf91b9dff1485718aa29de36a43f7c51eacd8589f0c3a96ec18e8ccfa92941b50b2132e3612d5b45e16f60d411d1c53e373e1ba451352e28970ada9dcb9802102518a385dc571dcf6900971b00346098a58042e0d1d129bd6801fa640a895a458a45b31318fe63ebb30c6e3 03cc4505005c41142308f1489226b7b542e2e7f24f1d3089ff6b92a4b0013f490ad52e60 b1ad1b3e8ade45516e955cc1599152d756c77f94cc1faa5a34beef55eebe825393eab3ebe8b283b6d57a37464f9f434908e34ffd2fab263047a52fd81d849388cca27ca2c4e141dc5621a7e7a695bafefce17210a488c02943fd54699577e362 +6d46e57abea9d115deda48b69fe8e0b36144df2f6a659509ce1b514c8cc4769d46e5f71df2a084f1db4a22fdd3ef0c2f90394f2898ce291b9f279c0664aa01419f5f6bee1fc1299871b27ecd57a5ac548f99d01871b8c238a6b46044c953b2e78e22346a0c7663af4db62799038ffb5c21ee512e26d01e70a4ed967377ab8405 0144a2fc8e0aa63506e14e4307df36416f963dd9da78655832f5b991af8c3eb97df78efc 839baa56d3a16e8f45df999a4909aa831e61c6f25abcae2fddec59739257e05fbf9ef7130318bd6357427bd678ec4f420506abd23a940e2527031ecda14088c4803562a26ec4e3c0ed0e7ef14008092f388616edc97f016afb911f2458a2a155 +dd750b39bd8753f4e473c4484e2b36ce2da7576813ebe05861c339ffae1d029bc793173ed394091c00685ad82f0550cb21ed1c68f0c27cb7396922239cfb886647af204e88a9101b7453a8ab662e270b87a8a13f2fe61d695597382cabeb781933bebfd7d0dcd33f77266e43e32d937f2dc89f67525e522977ce73e9ad36c8e1 024ffeaf139043ff25a395e4c560c7680c1c2155191378917eb25194136b4a69597dc277 84de24ac8e04d5edaee6ccf5b733d0eee5e07e713a3f6aa0366f7ba37719e8648abee1771ed532e8b59ea10507420dfd038430fe793b9310f81e146dfd4f05a7f9d54d4674ea13398ab8480ebca569cd87548626fe4f013a7f9a94a4cbda0d75 +4736e59fe5812f63737eed57a570182c065538abd9fb0a1c9c2059199e7052ba57d84b5fa1cda2ad9f216610361ce1dfb9334816b6bea509283756a03aaae2e5b0597f492d078b6b015a40c9785dcc5d2ae266176980db04f5cffef40e16661a50ef871c5f531d73fd5d114fa19bae9dd2da4267a131fc31849da38c2b78d1af 01d1f2e0f044a416e1087d645f60c53cb67be2efe7944b29ac832142f13d39b08ac52931 83bd919cdd3916f16ca9a69544425a7e203667cd2e4856056029bf8cbf6705db2f9e2c3525f593e3f334c95aad8177e20a095ed56ca15e2008dd9896426cb5c8a75c3ac76ac56788a43db23b54571d06a5caba4e0350a32f1d784f320da3c4d9 +e573fa7d4bf5a5601e320130de91f4ad87eb7ca6b8998488afcef69c215b0cccd221b8b66eb0af9d699af9ad6c4b4a580e82941f31e4c0a9bd83995dd076c5ac9bebb34481061e7cb1b26f6e8c6b26ee4bdf9887f7ae2eb9fad3115a21dcc96acce85d23a040c0ebbe0a56e75714dbfa803d6e279b2f4280bcb993f96ba321e1 01337362609df74d25f7adee382225e6a04dd6ee4c6b45fa31499ce9edb0ec046325caf9 9774ec8dc7d12fff4cce5f1e3c97c68b51e2951c7076331e1de7516afafcdbf99bae298509af0b2a77576fc52045f840090ebcd8b5f1c3e23b9f5699c5a3d24528163ddbcb7501a62a344a6ab25450c55e4662a4842cf56c1f224e3cd489a1f2 +7862864d0d78b44e2a28af44a0a16d8e9b1b8c4b794db0410c0a863ba011018ef43e1e11f2fcda2f56fdb2a69cc817df425c9cb3b458922ba00d710190cae16d61af3c304a42fbb3d0c4a74a297253fccd70aca414865b41f68b01c561be281265fa89f63f975d3101334886e85929a5a47fa8dc459b663548faf8ed7484958d 01be00aa0afdfe92e24a2536594d4b41701ad4dfb223aab35ff49310bdba7566057fe8ac 8131a8912537ee8a8959a108b6ffc5c521325639f0c4b2d7a87249eb9a09ccd4db3db6e1684b824bfa5c239b745065731342e47b197e6d7a812a464d0d30e41b0bf1787bcda5a56c01f8f4ad111bafaaec69cd5009ddda6c341b9c94c7155c4e +e73c96d1a84cf7cc96065b3c6a45db9531cd86a397e434072a38d5eeb9a90f62bf5d20bae22b926cfe967647d2bbb5dd1f59d6d58183f2cf8d06f4ac002ead026409ca6a1f868b406c84ff8887d737f65f9664f94801b2cd1f11aec336c0dbd4ec236d1cc4fc257489dc9709dfa64eae3653ac66ab32344936c03eeb06d5852d 012ad0aa248db4fbc649f503e93f86104cb705d88c58e01d3ae0099590a69aa006aa7efb a38decb494325cd183bc97773038ae3e651b9933fadfb9bf3a107334c5d64100757514b5b8c5538f8fd471914c6dfa83080c08e195de8b3dbdc1d95fbbbf84a59aa92bc5ca5dd462e7dab36c5cebce76ccb3a18ef884973b68d640e10083d4fc +a73fb0aaec838d011110d49c5e94395ce07408917bacf7689d2cfe0948c582214b263c6b80e0a55f1e159086817605723740569eeaa1bae96b979679165c5c35ef2142525e943e595e6b4b160acd7ebe41de19775346363f779b1f80b6d5f0785b92a648028e456af8496102d19dc6526247a654bdae3368f075fa9ee92b2f4a 02cfbb8f340cae8e2e2322829148981cd9e509b0c65497fd8d9da5dee9dcfd39b0f7556c 8a3c98b9ead4d68c2a8624b1c82ab582dcc3dbb4b6738d5555a2d50211e33c20def286f940b0501c5717ac5a1b3138fd0a92f39bbbb276dd820ce7b71ffa3b99e4eee88cd7cc6b1803a44f2633b25a59d036a912319fe285691cc66dafa7e9c7 +eda775984c7c9f7db47af30dab314d070fb77e9b623baa6b73e2cbda800f167b20fdc2e7219391efacf908f4ceed9b9b6bd3541b52ea087177e18c97391214758cf6455311fad336ab56cfdce57a18add8cf85b0a0bd6fa7297dbaa34bfc8585b0f06a0aae055186658c227e19cddb65de88d260f09f805c2e8854dcc524189d 0070e82a1f3fa6158d15b7346dd56150faee5c98c9d07c996e01a06dc9b211b12ff62d60 8423ed462c73587986dc5f6b3a0e2f23761b7f7cc85dde0c4983c69ac31b77c14b488c2ab570b1e71d655ed4c01a9f9e0dd5264a3b3b15a4b9fe0fc635355f9a316092356f63a76ec81a4e0c8e5ad1a0bc5b797dd1ec19c61953606bfa140b38 +a4a13e0bfa761b9bf37fade6570d41c161e20558874911ff3bee38e5649849b159beccf321c6bc7243f99c01a2fadbab9e157e9952ca65d8ea676c74fdc976d00501c626b8465c6cf0e4fd1a7d1260aea987161b821528b0b423e62ecc5193a0a49442b0c3e4ec9c4786a3a86b199c07dd3a17033d430d2c83c100f54e0a7c31 00b471bbc5f7a07996e370da4a09e71e2119ab3a562a273f079401951fbe4df39a4493da b8fdea430656a9dbb7bdd3f50c5d34aa7f818c797650e5014a30133a314b30be79dfb2bfd3c6aa6d593b952a2302dddc1731eb60016e3627a3b8b2bb43f4b10f7ca8b212f062504a21f7d40e5d1c128f3d3a73dff5fa6ad01f44ca10c0c20aeb +7ceda7a7248640f7055309ae712c19d741375d6a7e0608e07f0135bb830dc3e8863ee9e7a75331a5e1bd38c42cdd484d4f45a26c2c1d4e05ce0d0ca941f4e94ecc6b371102f31633629e9861de558bcb6407d66eb91f1062ac0e0409db68b9f2855296a7f42fc92359a7dae16c73fd2dddea52bd866a4d501aedd8fe3b3ea733 03c65cf80bfb507dff52f9bf2f93df0642020d41619b3990009409e7210fd7130ac44ffe b7d13518c27c5fd664e1b61ae37c992f76fb2f4492bc953257bedf6b65dbfd8db693d13d37b995e007e03568bb8d923f08b37722f7d94907a833ce64da469bab0a0893cdc9625e90aeaea366984408bf8e7b204135efad37f29d7b0a65a9cf9b +609815edfd58c0e26a4b06dded831d2f33466a130754b96d8d7c3b4d99fd4b0789ec719bc25338d0ae8c5880560c02687d352d77c291e406eae865c3b26d00f2e63dc644ce7e01d6e96ceeac8bc1eeb257d36cbb25d89b5fff6e30b6051506a0ae54cfaf6214f30985d54cab78f708029c1fc0175bc58e888db89dea8d300abc 00f4d33a9c7e6744ab3c441828bf0f1866ae1c042cc54abc754e3801263a96cbb3955dfc 92a4cc49581dd17ca29c6634155db1496d3b0bd579e57c6ad8d7df16e2dcd51f88ae19f6415aa98b25bda3374fdde582000bc02517b34768e9dbdb859bcac177719483ee584574ae19ef3bb81976f85e19da81bed51a056ee6f706442f83e68f +82d8ebba707b72655497320200ce719520c1ae7f46f38122958fd99322c25c9f4d4344bcb77a6658df0eece5df163412ecdca58475d56b0c2d14a0361e4cef458df146925d473a43692b15e9bbec550f1bde3444f2a5b2ecb55d2abd273ae999f16a32333529d94455e485ca4585e6b07bedbfc2bd1eb766abf0d28bdb1ae6ec 03a4824bdcea6a144d85f1b194431724cc49849b6cb949b4766d641ae95477d1ec3d1464 92b94f02049cec9880694c8ef3f44c27b60af145f1cbc73f9bc7fe9eca05e2e5a168d08959942caff77e8d6cb639ff1a08db3e4ba756a7fd620f2e275d64b6bad60f6c72767d4e67b059155754e4a94ba14d1ff3db7cf010ae0450cb93f4843c +9c6fce18a6a96349b10c9f2f5f1505c8ab727a650b44bc0782a5f39fcb48b45fc7c1b82180d5f229b8abfc807071f931d333d265fc940c93fae7520d8d40ef59d7c6e3678c6a2ecde52b6a8827b1ffc6ed269cb9832feb20e593a7e3d4708309342875199eb2ffceba7ecd707b122516c815e83e27872eda812e3ea52ee3c4a8 027ba543ea785df1d53d4ae4c1bd0a3a994cddf0c25d2b4e8ff17ea7aa00619e858da1a5 b70f6f28bb120ede08c7c97fd828223b0319523bbae0ce8b466bcb9caea8aa6b5dc4a339f7b22775c8b5e7ab8d06f98a03e0588bbdbb9b1381672ab779c97e29d170b33696daf04e2bcb70dd2e50251d4cd6979242e8950804bde8daf9d635cd +5eac15a64c7653d125605869012b8f036804817aedacbb5a5248a595ee0c12329f91e8179c187192d3ed0d4ca2e202d8d4d9c93ad3f3ed931121c193af5b47a8a5dc39775b6c2d702708e5134f77a31bd62eaf87e39e6fd3f2b9f782c3057e162dd53b3addf92bf0ab99835c7f6649abd1c5322a1ebb2ba313df9464a74c14d3 00708d0907d14dcd5f40e2903e1e90e48a0ffaa6d4d9b84ca14df4e985c294f74eb9f2d2 8b39354734d7522a0f32aa4ddf7eee8d407f72484a2562f9f7c32d1bb86a956fd271ed51d559876b571e4d4354690e40035fd10374ffc846888e64fac665026e2ac9e68e031ce5b971d912c17603bb5334a55742ea326886baa0219d7f312412 +df735a7e60bc267b18f313ad56bff830be5ef119baf43ce27c6368ff1dd89f010afd4f48740b11c12101c5903bfa71d6cb3d6462cf875bbd55a570ffedf3564088dfe8c8d3148231b78b5adaa6c53696737d4704daa59eab8d986fc6e519e81540f201e77b923a6a4af65d7173635b3b19b2023022186a7b8e869e1ed51717ab 021fb0a6b94080da8b8299b87457dc09d21bc430ba5f3359d92aacc1151be9941739567e 8e2faa852dbaf24053197f41834e6423750c95255ed35ce19c7fc81e2d2cff2b7041477679d7b585c59df4ec2313b43811845cb4f4233b153ccb7f8af8af11969901dd4e7de593f3f5bbdcc1f7086266dffee90489819b0f06253f09d810d1f4 +bb107b0eeaf175a786a61db923bc6d51dad5e922e85e57536118e032167b197b1a1f62d9bbcde04922fde781665c1094181c16ac914cf6fbbfb27bb8346b2134f05c55a8c6b9b481273758e380666d6e22c28577c29446cecc5c3df9ed9f1be060ca55ab2b7fda36a147aeb46df0275bb923e0876b703452fab42f6b7ad2ceb0 02c80151f91301fb6b0c7685bd172f20515b46bf94dbc4160d0720fbaedd40ec00084447 af7d05a05fa1e22fd7125d696faf42ea45f5ef4df6a6df575aaab6cb96b9052dff83bb3187f870a7f917d401a1daba980293ca014c4e53b34a5b64ea4b8654b554de8928488b0b37b4ac7ab9c95f1358e12561bead27f6763cc8142e2ee77a48 +f47e49ae30b09b7666600b7a95e81b0afa1553da5e01fd917e4ce1b58dfaddb8dc8c03c0f5591f533610deb6a7bb5faf5dd1ec4103a587a1a4c58a110a706b0f301a5c408b3d984c210d5b4a0b347d2b5447271f25b527b3c7864f7cdfa735dfded47c63b723fa0f0413c57a24ffde9a95c35f743f892ab1ed1df704cde82d9c 01538abd7ce8a6028d01604b1b87db3aaf720e04220edf4d1d28c2d731aa25f509e58f2f 81dcfdb38a2470a64aa41028701a899353a1b5842c958246c3654dea65cb91790426182fb1f298370701afc58e53469d01597df82199b7fe1dd3b0eb0653e0c834635bdcd8d3fad5dc8273baac123aa0d3bdf958cd1dde66d558024b653a5790 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B283_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B283_blst new file mode 100644 index 000000000000..53ad8c79a69a --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B283_blst @@ -0,0 +1,60 @@ +067f27bbcecbad85277fa3629da11a24b2f19ba1e65a69d827fad430346c9d102e1b4452d04147c8133acc1e268490cd342a54065a1bd6470aabbad42fbddc54a9a76c68aceba397cb350327c5e6f5a6df0b5b5560f04700d536b384dd4b412e74fd1b8f782611e9426bf8ca77b2448d9a9f415bcfee30dda1ccb49737994f2d 0299ff06e019b5f78a1aec39706b22213abb601bd62b9979bf9bc89fb702e724e3ada994 b0e1b5304bdb87b200dccf995b9fc046a35ce99b3a9465b5a6ddfdbce24eaa082216997184cbfd2643dc8502f7a7d1d1169a984a3a9ee99d123df8de24505661bc3d3b8caf2e08bceeb8854ba4ad1978ea9dbb0b1be1ceaa4069206ca717fa82 +44adcb7e2462247b44c59608cbe228ada574ecb9f6f38baf30e42b589fb9b157bb0560e5a2aa5523b71cc0d7f583b502bec45d9b8352f29ee1842f42a17a5b16136feaa2efa4a0ae306402940ecd6b71e57d1467c98e7960de2a97f88b43487e4f4016af1292381d70c18c7e6eed99a14cdeb5b3caf73688658e4c5b54c81e08 009c2804f8cab768248fb3fff8a055b3f4585c00de5c1615a19f9425b9432ea09afba8f2 8f99e45fd9a29bf8e98e2e3a4f2acd6ff86c9156e639395438f66aeba78744a18126ed8d3b9ca719cdb5cdca5468bbb60daf36edd73238e391ab55cb44afd57d34962d9a9a4d27d553f2d380dcba89727e1d1b560ef412b659843a19ca5ed167 +cffee6252c7eb6d91d8fe100a1e62f0ad9f862d78ca2b747a6c17b8c9ea8980dc239b3b673310e6e7483582399163e39d889abc1a613fe77849ebc09b4f7f4fe0688b8a9869ae918a88294c7ee199be50ee9460db14725ae70b449d0cb48f30e7d817ec02c0cd586119341dba0b74f0279330807cfccc99c8c340b72c1764a45 02e625a6bc6d0ce7c06231de827068bdb0abc8ffb57c82b35ee3a0f873b9473905974d34 b2298c8739c76ab266e4b0108840f17675c92c5dc535da7b216a7141e09c0d2a788956647d5a5a26b622c9fb03c36d17087a2c7b4b204be1f5193ae7dc2bb7982a2c69e133e3b6c1505b6e1bbe613f398e210848f562387fbf9489896de8dfe6 +d058ab5dc07228253707ef224897ea0fcd09c3d5cc91fdce9e03c1c59c53fb4596be2ed929c7455e67ac7f4891aed3eb06ad88f2c4aaaabff045b959f900d1019d706b60526375851bb891494e99995928e4cd51c9616aa651ec77bd7e398916bb9ed3156391bf7fb1e29181e2b011dae2edaf803607def2ac6b194929a57f45 0376ac24e1b86f8a55c052d92a0bdc6472fa03acdcdbccbf7c321ec0ccd97aa0a66b4181 80fde0cd921ee9f075423c7d978245de7a007ca57478a08a972cf237ca129eeff6d1f0444242e2b7154d43b8d80c9b650a5f6e3aa8db2aaddfb59f051c9298173b5d41067dddf71070c170e6b7fa3b2ae421f344acecc3b793edab6bc09533e1 +c86f2cc7ab5df5cf1a236fd83792769474cef464032800ffe98a44cf29dbfb6f24088160eb31a11a382ff2a49f3e05e983462f5304272f96c0a002b69af3d233aebe867ee63fa46666760a6889d022c18645b491f8d71b6a3b6b4ef058e280cf625198715b64b025bf0449445d3dd7e1f27153926e617bd2c96638345431d1ed 02b50a6395fc02b9ac1841323de4520292f913519bc0d6a471aa28021322fc4dbcd7b802 a1d6426c9d493990f686a7ac58417266cfe280e8a57a6b0132810cbe17fa2c64175cb1540422f9b3e66e66f9f02bc23c0955b0b2e4af4ba4154c5a8fa4e05f88eaf9104ce18262025ca842f42439418b43555a65a8527b743390d60daf245961 +c1328d8d2e5b6ffc850a9600bd6482518ddd9cee3fc9140febb72bcd444b0cd7e8074587d51b62cce4b3d4f34ad3355353fabe363369cf790db2df9fdac3a0ec4757e2dfb3b683eaa3e26531691ce765742e1c0bdc0e1028d347b6085fc459df0989c6a144271454eaffe413cae2ad7c8b2371fd2df1afffe56df727009765a2 024e5889722f6c35e18ca47effa9e415b1ba790066a91fb3c9f7b001ce28fc732b09bc23 94075c7ce926a9ca44eedbcfbc4254a013d6674b46e2f3416376f5dedd3deccb3917cd171f859a90fb233caf182fc92506e5212bb6f8dada3013d7557fb1a6ea14260c1e2d4d55e7b18724083969846ac840f49f92d322f255a964c7b06f83b0 +7176b7013ea27e94281977eacb976bb31c753bf80fa09680a29128a6fc15234f79f0e9900aff3217ce9be72c378042c6c34fced0158740073d1a985fa25987fb218002e425868fda5a47de51abfd04de34e2b8634cebfbdc98e80f93d94096193eaa82dc8778fc23f3765c7acdad94fdaa272df0ff0f28190c10a462ee78ac92 0056d15b81f40b6378588a5efe43e21b95e18120d514bfdda0e7759a1d0766a8a35ce5ac ab755ff68290de1a4b06313df18b97cbe6aaa79ad8d9926c68013cb362f5d13a33bd210d5a4dd014609a90b24cdc0ad21022f8a06f34ea8bc6a1b1667eb47873466186abb655a84efbb5412db89e531d50d7c4cbbdd20dc37319b5d238698824 +4c3642ba040a9955b9d50dcd1c936688c17c363854358afa8ca49c6abd906dfdc4d89bb4cab0bbc363fb5b74e1f004d4b09ec9dfeed4c0bfb482a9061a1f487a3d79195ff7b65a0504bced3a28db0ebe8fcf8ab1ee4a3ae91324d15d890ac4c479144dd5538d2e36d3a587769ee9cd2d5c6f85a03362a022fe0efc4a3902b71a 012fb2fb5bf5f7e42a500154823a174ba2d05af71e3b0cf47fab46e673ea1822f1563def ad1972c31fdd40fe3735bcc741f44d03a9294ff409733ea5f4cf6d90a09fdbc783addc657e5cdd47a363f9917092cbd1004569ed7add452b63da4912feb23c685a4670a789f6b342ce44248b1ff8d7f567def70509315accfc44b17b7df3204a +e471f39c18b081362adc7da47dec254dab8d765f005ac574640d78c14222639245563912d942f3be212ee3cef134407334c8fe3602fa0e1629de5331643d76715dc1b0ffcebd484d86c5211be4b285a31688b205fa988e6c15b36daf396ccdcc209c7dde2a732f5c31c84c7ea041408ebf15e56632583af0131bd7f531b5fc45 030096c54fd480647e017f8cdbbdef292e799f054e3279d228b09816a757566a744a8266 b79278c184c5ac6ad37148ebfa93b6e4300d78b48835736812c86ddde64c03b431d65d624230af894160a8ac632080cf05b3aeb5310baf6cdf691233d090f247ef5f013387c52b66c2761a9c1131a68d50bf4c9c2a259192f2464b4ffcc8b70f +8a93fe53e83075c4025228540af7e96a588520da34e3eadeb99a4ab2f3dbbb8f85fe63a3b86c1f4ec912e665ca05b43e869985eae3791b91205afb1380e16c25b74e6793fa63e4a55dcf25dc22d03f09deddeb9042b620434111afe08c5657c7d754af66ad91a1b5423301b1e8e6389a1404060d1b6a99fe0f89598482979e42 00a1b7e9c8c2dc25b494b5ef3195b294e41cd3c2c35235ab42542bd3e2a52d5826662bf9 a9f573dd3dd1a82a3bf5fbed946db1870cc7a36111cd7c216b98442f866fd9ad4d609d846b533d20cdafdf67a76dda211540709fb9aec627f2ecb080cb4188e229e912d2e0190baa10e044c7cb28cb7001d4ed8dd145b69e81fa91536dc555fa +e193a8ef6f454ca1aed38bb67aca6d08280d421b196d89938c0582b7cde74dafd71716f3818940af412d4a7ff3960a8517aee108ae03576b68ee7557d35e6f1ab823d124de7243dd02b542591f62c80d822608572889573e4c9dc62f99d68e07800da6f83cb6f5e03d1f2ac15f90e38b4f25e0a75e354e4b60cc81c0bbe81d39 0059b1a8fb84530bba7a607ee88310e31bc6ea6a6881603567a1081a05a3a9ff87e719ef 8de3b46f8b1f44c5b0e93ba72ebcefa5ee6a149b542bddded11232e5b6962d13e3b9d41a6ffcee7368737ca137f90fc918500c0c3945f46b73223fce27cdacac19ca13256cf641c4242a4231c2993e042db54ba597ec63d5377cd904c2603b0a +8a99b9db191f6cabc88b430bc2293e6774d5180f019d871839289e25aec29379f14606e742190b7aa062e3b29fe0254146d9614856c5140c7315015abb98ac00da2c7e33cbcc82c24b797366f12767322c4381454d9d1eeaedb616b0ea5c66d1422da459f18081f4f966d05ce279c6ee69b1bf94b8388d38d4b770d9ed69025f 030ddc2c7a4ce300cc2b75f0f977033f16c1f8bb13aae3d494c381f9a6dc8622499ae4df a598324b0cdc8c2b4885ff7eae374ed56d244468ed86dda35aae97ed162726f29b113cee7139a80112a1813befd7edfe0242d821bd9d6af141ccbb1f78cfa80acfc51d0c74664b6c6ac5a4c4389cb0f2d776e42d181c6450650e081168ace267 +5c437b331831530aa94623b1736f00b986172699f0a02a5e5df0008bf25341787e2e66046f2c929dfe0058c3cb89fc5bebbe1025bb1edd1ee31522ed568e7b5b4ca3991afdc76a68cbc2c4f81863e27fdaf6a564fab2c6354e5c657de81390f8a4132669fd24a48580c716b5b7961a9c091f614d11cf45dfdaec8946a54a11d8 007899928922fbfdb5407517725edf231d15a8b62d90b7fb6d8c8d20424850dc44f797ed a5d0f2bd7659f04393563c87e309a3daa0ee981be3c4283d4b87183738358c07b2d009a0743c223933985e2a39aada451682c278466907f16d16b2bf3efd8996f236faed26d427facfa29e6b93602ca047da72687b5c89be2aea7cd103bf82c0 +91aa08567d8da4c90684dc06068f69deae240212842ff1786f04ec41b40d9187aa92c76401f9fcedced62876a34df82ad7c1e63b68bb2a972257ea8542bda6a7f1a020c9b122943b6d651abda8b8d322a8fb762eee376daa2d3637a71ed6c4f5cf96f61c0da2d6e1dda3370d80e51da2cbd8aef3267168c67359523faf910dfb 02a2af63d1171930758bd3e5bfdac62cca1a83a3b55a49b3f80cf0d9ee4b2082757beac0 a7347ad33844cdd4e33cbc5c103b24f8d63be2b32d9c92785c978cd830c8b7f308e83b70aaa2f92480bd344ab5b83e6417e62193c9de70362268d71d15fc3461043b4829ddc4bb001b10ac870ba7d4a2ecbcc13bba815f0bfbd4f9a23181db48 +eb5297bf408c1a55e400a20a3c10acbc5c2bc6d6ccfcc0941fb7a6fd4d2834415a6df86c3a6c4b867d1215aeb8222153da8cbbb1576c92c07ca2c36d8f243fd911f9a057e39ee25832454e28d7ed52a8d04169b9b9677a16b32d5d211b8573a8986e9bf36d7206417ad2771daa11bc21fd7ee1029b65ff7c9b2705a6dc9cf9cb 035994e89e13916ad82608f74a639e6aceb756ff913aec440519946d6434af9a60a6af49 a4b054a7c83422b196594bd6ee2662741eedc3826dfc1fe2589d7bf00463c6d39b6814df023b9e44778dbc0c5d8ce335148bb3cc9e97ce9bec5a044f5643f84af80c842db0cbbb818176b2b4cefec098f1f18819ac4167334f25f5c861b6846b +f415d0adcd533dd8318b94560f86732c262ad2c6dff9dc83e2435543f429a2158cd2fbab0d96c027f71008c4895ecc644c2ceaefa80937f6cc6338d15d36e459a16bd9387a361a6d800acfd834ad5aecf442e30b70f5bfa164747cf9f89325b80976052a83a5e896c00c54f81472b14329cf23bec10a8e693005de2a506ba83d 029639da33f48e4fb0d9efdf50bba550e739f0d2476385cba09d926e789191b6fb0a73ff 85eaf2d6b4c30a20a153ee6b34644876db99f8347b7a4bf8a2b3fab46d27a1860c56d35e77a17163e1390195c2c4ea6d12c7922b8542012fb3dd741086f8a182fa378f58a739ac6c58591fe24e484d98b27c00f0554611ff50c4b58cb65315b0 +b178d86c9335b85e02178fc4551769db589ab91d823fac219c7e14e2f029753b203962389476723832f8d9631dd7764e6dd35da290afa42a794476f5c7727b3688aced848dabc9954201578cc7b25801710931f45cba1199d3788d64dc0188412e70723fb25b8ecb6718358150c4037b5b81466dac1686cb5270bb1c72d34bb1 00583a7ecbf2a975a32d07428d27ac82e5dc13d1466c4fdfc1e6a05a8d9a289f1010617d b0f6d96f3b2916a0d5f889a5406b483a074441dcc50606a24419c9226fd36425147e0bd017a5b9194386b2b0c2f8306c0bdbe54e2011d11ea4ee325a32632554ea23f1671d6216827f0596edaf83a692b7e5b3def02503a73673958314449e0b +c8bfe9fa7c848531aa2762d48c153cd091100858aa0d79f994fd0e31b495ec662209a9c8761cd1d40c3d8c4262cf4dc83c4a2549a5cd477726ab6268b4b94a78b1c4a7e700812872d7f41912a723dd9abc305420ea1e1fb1fee41bf643f3a24abd6e8fbf6fde2475e290527724a6f99fd75374bf7cb01b34d3e60d8db33c4de1 00f817ab1b49131fb9bbe8c112c25a36f064efa85de7506fb9cd29d81b326bf276277f7f b0092c6b8a1ded4b4fcb4ea0bdbfcbe8d7c672c1edc1942a5573cff963411747e55e587d8d3108cab7436cabe4b628d012e978702e6ac92d2c666047708546274502ab0f5be63b6280d7b581f1afe19a2b20ea439646730470f0135b3e85ada2 +9a5f563d0f9fd1f31f3a822de628ae970954f4e71292492d727109036491c29e66b9b0f2c90c26abe94c08502f5e923a9ddaf6a7d91e9541ce90d0a49f03ce4e4769753d5b7d922e1ceaac4b4cfa4262732a09550aa076b8ff9d46a50fa17de17e3b6bd606698464d116fcd5f1ae11bf45b0c48d3b738427cb47b0d1272b03cc 02782af76ffebf3e2bfc0576b70e4f4bb87c762e2bb230d278ce776310a14f5b678f29af 98a20c099d0e32c8ac47439eebc433aa354a35143ccca56c73a42a46ac62669a4d59bc3ed87608e03f320b128bed9e06104e2b2c3633298623af41cd08f1f720b0a5d60558c18b3378a201df270688fc601d7f937c48e5f52b6ca45c45a7811a +3d6b065721da9de82cb33ec2c27107eb399b1e69ac8fa51145ed4147e20d72e27434104e76af988a3bc94f55e36677a05182fe2376dbe38195fc6a30673a4dca87336c7304f3f31d49216fbdfea00fd1e105d8b0c13ab11f8892e0045e915c17dfaab07b24ed21b06af5a8cad4f45fbee5a25bb6e87466a7bc422c0bb896440b 031b827b88f14d3822244809096157df3c0aa99da90c00cd9f0b18dfe306f6881834e6b6 89d580773a45ab313ea8911669ee025cfe758f606c2d1a056cb403528c12d54cdff1343f9146454ec8f72201c8a67d930c9602055ae525aad970d40c3a20914efb07682275705167f044ad48ef9386c99759ea4cee365b88d8a598f5e261c7f1 +d125f0e2e6135567adec9e77da2afc6862e28d618416632ced829d14ee8b61116da59dfb44098a40a0b927731125617e3d2f32cfbd1546a6e758c1ab6597e75db07add52ecb61d37da2e9ed04df95b36ac249f4cbd794cb561655cbbe4b34834c497b3d392d78ed0db8db683aff0076fb6e43acba3fa2b91210cc6cf3fa594b0 027da4916f1c471cff80bfa14d12aa10270fc3b26caed010c0111f6e5a40d914a3927763 8bb68632e67b98c89f1567c6af548681765c319a62136735561b77a74cc469ad00c20738b6b16d8c19257a0dcb6b1a2701a2b06530f750bd29536d33b6d4f2d5dd429eb7d47670d65a09cc07987fbab8cd70aeb1893280dbecbfdcf7f2b5e986 +b380f97687ba24d617a42df1b14e5506edc4b62dfec35ed9fd886bb769832cec7f9adae10c21b7cd9152588797b4efc6b2b30a873d3f25e683ea9be070dd69731949a51121e534fabfa3a2eae0ee90a454182248bedf2595cd47ad08614177d58f7a773f5023b538f5f568682c83fb60e3fb1aa859948d01bf7b214e7f2dc719 010608eb51dc0ee97d6e488a23c582ecf0ea1df9a24db77094d87b3fb6ca98507280a934 873cbf19dc46413652eaf33aca56a476f42c5d3071a391be75558196b640209f6561ab3871f849a4bcacdb5512118ce40b09536617d5184644c13b66567c1376777e056eb73e0c74f6fdc83c3eb0889e6e85e465d4a38715706ee789c04e3116 +3f9ec57e4228e1a6ec49df02c58d756515305e48763ba1dc67298be9a1548576c28c82b4e9b3f62357d9b3c522b16d5c496a39effbdc8290edd2cadc0019e6b9fae1e61238b13b6265ad2ff413a5a0684babdb0013e7632051455e6fd943815213c555dba96cba8911e006bfddec6c3353065004538f37e48df9e339498d85c6 0123f9eb8babed548df08cc3afc1d3b3bbed52b538d4654f2088fe76062fbea75b85a560 8d396b540fc29ec700fd67262d914c630e4a47c10ce9ba21adb85eaaad093402bdee78eac6e513e824603a3061fd349d0b2830d0ad33249adabf06faa5edb0250c0bda412d56017ee5e47d548570a6b27f5ee5acd9ac7f1378d0bc113c9d5f18 +bdbd7b7bf3337bd9d21a3c6db379f95408c17e49dd394e94737ceae889f45dc0ff5d48cadc53703a16b5589939506b548f8dfd34c577c084f372166cbea320c8fd07c809b211e0749ea639e68f890affa1569b66bd763c7c710989e491011371eb1d93ed9479ff0216b7f79c901a2023e2cf80b565d1c0517e73117190cd2f02 006a18e626452111922e02e31d662f4301319946a204ae8a34f06b91dd1b5b96456365e3 958bf26ed926b59a4f58460890b183096bbe68a8ba02154a0a9377951e4e17742cb135f577dbefb6c6fa60320e3c2b20116257beddb590df16dbcc9559b9b398b470568bdde9877d456eabc2ee6eb6882641d2fc84857166a2136a88a0c05e43 +436b288512ea57bc24f84fdd117da9dc1858bae8c11637f99295d88fa9d05e3c053a2584a6fe200ad190b3077d9a1608f660349dda405066c1562f6897ef69b6b674d6bc11fa470d0b96a7cf8f6e098c9ac03b0ef415aa045867ac7c11d16cee78ecf08850ccabf70f761682b561d0d0e4a889d840dc74932648ca2fb58259f7 03307fd717015b12a2dc76ada21442ac1d97519f66898b214c2ea317ab0f0905e819e4e9 ad022118c4b01a968dcabd737a984e5465bbd7e3c50538a6b25c014d5a8b32614a4a4d49b6038c5f79910359416ac91a007d08a5e915334c1894594228f25d60a27ff57f55ddd0eaca0cac6445ce8d5e49059197f3fd8ed9f23e9815b4430606 +672faa156dc188bf16bf8933d65e091c633f294486049ce96a4a403dca28a149f4f840e8bef47412285363e9e89006614b013a41baad9885f1d9980cc897ffbd5f8a7d0e63feaeb42c07776efb307ed680ba1cebf470dd9bd8a2a9efc2b1daa569524394f9a50398add1a5bd2f7c263f9e63c2d49461acf98444fd23341ce78d 014f9f412e3c7d770626e800d43cfcbba3ae6aec8563af748e8a97b67d244334b6e6d2b3 91f8c5fff945ffa68735fbf7848f4ede1c866c8c61d0565cababb45f769ea2eb43b11f5610e159978cae0edc282241a117cfd58594005c5b1f05d19fa794e1927602d7b37c49aa99f3f488b87e9ec7704252408ffb0c66c9759ff5984f12fdc1 +4321334cc8ee44f1cb392a4b280a95561809dd3639ddf43b6e11cb73067597988d95b8643d86c76c3c6b932d9262b9b8b55a04fba0666dd8b8ff1e8fdf799ae3945b6e30d3af3966f1a6d634d5e012710d66cb447fc3375130968a2e1e647780aada2609d87247c90338dd71c3bcc3902311caba27d5d4ea4d73ccea960d4bfa 03091a6a8bdac1e43542dce752694972e734dca31c061c7d1000754296d0748055db3f09 aeea9e6038093762d58043ade02d4c359aab6746d7a38cc54b23be9bf1eee47b83f9033f2f1489f55620c89adbdaa4251421c7e4293de9d75c6e1e71a287de5fb97529ba3676b9d2b8d283543d8b5cf7ac1b6f3600a0aa7e0380e02daea8543b +2087e22094570d39fa937f15a3ef0601709a66666344186a33b487d041793fbb9709a95af250b1df0762ea98e911aeb3ff1fa19f0aca53fd4179e454e0e91636e55cc5b17cad9e1575c82ad265dc34c4a66b7a31ecb9ef9dc756f2ac1d9dab35369a6bad4a0f47e629daab91addc6d297d1e5d81477b3966d8c3b607ed194d88 01195921b91353db9bcd00510efffe009c94f6bd8d790f5fb3e5a0101c9ca5d21c6ef2eb 908aebf17cfd16893eee10a636035380cd4bfbf0f1bff6b20312439d39026b43244f34fe4f889a13f58795bafd1d989a04cd8ada5ad942ce7280a81fae8af595826ef4dddbac8eed163bffc9706cafa48a3896629835f2a33813a5cbf1f46190 +15c7bca449a73b03bbfa783f5a91ca0b7916889a5d99d541e2e8593c3b176a5b634ba20b34407fbd94ae1c1398f5313cab7402f3bcd7ad277a8c66d09a6df5dd086b20a0a3823fbbb80980cd86bd13e527eee15656cc977103e80113539e26695addd9eef6a1f56986168d9a53f8b5de833f8962c3826cca106ae9e8c00208d2 029dc20446e9abacb43823e12a83737b46e6e577466b5a3925e0f9d496824dadb4d4b50c ad903f52613ed729fa4a2efbed232d7d5e62e86d369ddc23ed28d389c4a45bb37bdef13bc4094c26a2c240aeb14e7a551378dae4ee2e0f76148262677e66505fcd52bbe72ce95bbe88b4afef4ed1a6f6a0bb548cb761e06808e6d3745cffce67 +d12fbb82ee7a57eaf76b63fd6bc6c0a65c85f135f019d43ff7bc295cad15d53729d904fed63d69d3ffe8b82c0ebaf0399e2717ece40e011f710b5db46aa457c23b85545953398b814816a1e7a8ab5b0b14c4a0451b0bda9d0d2ec4a374bcaae208b7fe8056bfa17d6b7ffd4ba2e9179f49b9cd781b0c06f6ce3eec26cd428cb6 03b9b77d19a42e9a555da8ab70aa5638890b2ed21daefa28ca6323fc658662dabcbfaf52 aaab881509fcbd429c210194299d2061163c2616d833ff04095d7aa846dc7a67c9832c1dfea81664ec6ac4f897249ce31484da0214413720136ba1653e1eec20a0da0d6cc4156590d6a5baab76eb7021396ea99c001448f899ed810e97f4c001 +eab0a37915c6b43b0d1e3ef92e6317b3afc8b8301b22f6059da8271fc5fe0e419ca6097daba213915855631af64e10d8382d70599d903d1535e25cbf74da3a12ba2f13c33a8562e0db03edce791f1d39af8850fd1feff0eb25f9ad0a86dfab627b96e65831bffc5f6d9693d20493bc9dd6eb3e9325dea50b055768e8aa30d49c 00b9f8f3e89e9c1ef835390612bfe26d714e878c1c864f0a50190e5d2281081c5083923b 8493b4ac73e6aa5289b8713064d5c3f62568317fcd69b08ee6ce18f4d0d93f60603cc39dda7acec9bfcdb2d4c404211e18748f0c5f70bee8f39ab63acda30d60884b5f1bbcb1a955f3d9766e36902259cd1e1f472cdebe99d188d26bef39b1cc +fdb93afd5dd1e3eaf72c7ea9a6cddb07fc2054499ffe152cb2870163eee71ace5bd420b898cb4fa80ea53fbbaece2a1eef6427b632320e9c97e38acb16b62fdbf6585b54fabf0a703307ca50f86387bed1815a05b0c8991e0743d10cdf49c8facfd7ddeb8d4a7b706b5a29e1d00ac88b0ee88b3153185495ac8388cc70104154 03a30a1c15b9ed71e102341f97c223a9b5ea3e6a335861c3cf407ef691a18cc639dbe74c 8f36c121764fe442192c44f9f3e6d1987f341107b78d44a63a4d665de45406675da91d242a466be78f404da4971f8d5b12fc17c3bee90d60b063986f0bcf7b5075ae3cf1a9ec56518dca0d6e7e76437752e30e32a8775e3b39aaae0a0b94c848 +c78e35d1a5b1bbb0ec21e7ba7b7c74c859d88f3e100e40ae34128cf093885dae4e87cd09f3239dd8e79e25305220880dd352a650225d9bd193b9b84e488c458b0b5fde1af941c0c9fdf952d2fa41f665918dccae27ab7923da4710f8c27ac8ed424992568dd6f0a6c3ecead21650ed162e0292104eef3c2d8551be866a88d279 0083330123cc64c11888c1fd388629d0b329a50ef31a476b909a182c930ff02d0c389b93 8beb4faf4d3cbf95d12ed35597cbe6eee51e5415105f4aeb2caaa9265df2b17fef0f0ebf4bed062466358b65d8bd6979017b17207e561636852d352d002719f0e7a5d93af1653831525cc9fdd4dd2d88e26351d7f095902b21cc5be5ace3abf4 +e05435f695997229cce314e50065f3c5f71981988dddccaae6efb81f936b22cb48813f506d1edf5ebd69b0be34f278592c5935f0f6db0cca1ef9d62834fbf3c4c03f4da0596cb4d67b7b767e85dde7b7c6fbef7d89babe6f97b876b33594a9e36ab87079861ee556fb03274ad4af527342a4794192b8933f28c6220f954c77de 01dc2b656c207eabc9e0d6272099babca8d149c9c4258b779c2f06de75f76d77505271c0 91173dd047454570a332f86f18d83d5f1a32cb9be6644acf3800f2ce93aa69d125e716f6bc8cba3848c5530b875c08d716c28a3ee27de632d7401392eca7b65073130e3a986e29a266f595482fac7a993c807b1fe5faf083870b5a4b4b433f6a +0f9f36477076c4b5a7d1ceb314a397fb14646695b0803e36e98908c8a978770269f165a1fed8f4b655d4efd6ad283d7f5d51b6e1e302d360e8ebf4e887c7523a757ffd55384e114bbfc6b7a0ec8511079507b919065ca018573418f9e394854c5704227772161707b4d0246ebceb91192f0eb2ea994ce61fd98a6d14cc8246c5 00081772348ff2d7a3fd57fe703555ab2e14f5d203c4cf0292f944e827e884d95f3b1d83 8d01f8f55ff35470d1239fa1864c4c66bd459daccbecff34109b67c32528ea881de11da6be170481cc2f39df9800206a07864f6dc80a52b339023ccc2d5b402f1496dc81181bc0b2d7dfea83e2796a506a0a8518715c5546904d20966badece8 +1d38b1c342b6611dbaf412a66c1c0b8397692755f576df33b31c2bd12b7f0707cc423376391f7b00aa4e7b7fe54532e2b39c3c5284b9c8ccce48eaf9308ed338992f1d4ecde6cbe352e46339d7d602942158387881d9b493fd40cc59d4f9b53ee4191d42352c6f7bf32c331f0c5afbd44a92901a4b713c7cf6ccddf7de4cc6e4 01eb6bf2ca1b5ffe6f6a795733eaeed12de6e87c53571e702635b9dbd0d96b47df4a005b 91701b8eb72b919ad2fb5cfbf49c35aba774937fe2fa8add08b0e287872adc0764aceec2b3487c1671e8ac557624185b0fc905c92bb920186741045dbc666f797fcafd530877d73a00dfcd49f5b62dfb5ace8b34192092f74a56a28ceaa00aa9 +3353ad05ef90e9762bcfedd6ef44a1e8ea0392ebef30cffd48ae620f3e567e1cd44882d514e7c6759200d4bcab18afd3038c3d3f8c50f7bba32a04eee5a4b1cfb8c349939e4efe0a46fd047d02ed000d8fa1b98b0af5586f120d9ad174b3aea33905b979ece1eb3660b1e070c8821b32df41904ad68bbd8ed247aabd94066f16 03b2a3e65e5a306bf8e3955b60e856dfa9bf68c1275a678ca056207a0ec67c96eb3f8309 914597c1b97fbb7f4088433c30e661fff7d067e716b8b33e676430d63f70151f99b19464cef22820c2ceb9e3523917d0147dd14799f3a35f3f4731ef611395f137681b4c6e78b292496947156e7547cc6fdfcb6fb324e90959ff2859fa6ee48d +e7ec162185fe9a5803c6b03d98041422315ccdac67e48fbd07a1ef3c5661158710abc6791bd0a75d56791b4ac0e7695d53c5989d9fa6a3b037583b2a80d2b154b024f1c36b63548be9afe1d51f2f68b2ba94d4ca1e69a35ac10e15ba72242aac20f7526b12ff9d3cde9a9bfd70d55adf9bd92c66d092d7d08e9764c84bf7f329 01fd4d1af0bb7c79ed5fea7bb45574e46534387bd916649485ef15207352d7302e81dc01 b6b619534416afff13d0205c7b5a86b8100123d94adee85b4c9dc7c70d89f34aee17e72faf5883a60152aa07e2187be81210341445d9b939c808eac8268550cb89d63b1fa9c2433e63565e9edb1c3ad778637796a1c7987ab7258316acc822cb +87c8f2e3f4fdebce0ca9300fc1ebcaa934f51a12b6b8f2cb6bb6eb77965468663044afeb2a1334cb5a81e74b8427267f8b34b5e9ff0cf157a9f18be2b1942e32ca61dc23ea13c3f9fcfa16df8fe05e067938b6994982676463fb12842d4ec532cb904cf222aa805dd0d86ab9a33a83e294c6d81e8dfa273835e62e9041dc8ff6 020380b1136b5283e9b7f54b7535ebda33b129ceb177bf5d3d07b1daed5edd9fb3862530 ac1b41ae8f46fe63ed33177292b271383267d1de3e01ca39cfca9147badd62d59044548259f19bb0adac7ee96fdddba20d91a5f0151d079ec1044b1045dd6c42b420117dcdc928dd51ce735d2680b57f102056f103d94e3c93c0da9b1c590a02 +2ac53e8a50c4afe3b38904255b7cbf150c5f79dc15932dc0ac9aa631521f68a0d4b6bc5a04d55c99a36531fd4886a23a8d99f262ecd2a9feea925d7a96ebe9b6979a207b7f9378afbe404fc8e959b0333572a2c911f8743c0ba64eebc7ef12fe5435d2cb0e5091ae518b6e4233489efe3c16c6f21abf4e2c6808b733914e5a7d 019f815b98836948e0a0dc9c30828c31b13e175f1e79f23d084ae1bbe64823f4866214b5 b21bbfbc35f4091ff359e412f427517e1c10bbfbcc9d5a747c166cb7092a844497f76c9e12c731031401e70d20089c7d049d4cb090bbae8b1c486bbbeb7bfdd1c62531f99ae57d66810cf6fbcdd41d8b6b79391d9e6c57dbbcec556f2dbc5ceb +0b201469cac4c078f587edecdcdb6efd5752cb4a3f43ab540463c4d908c27527aa3592f2f9acad85dd94a3c056bd28618317ebdf2e7dd6c5ad26fa3c31dd8e5c50c60418d91c93bcbb59ec1adb1db791f485ded78a5cdcddd23dd1cfa4f13443468d8a5f2d648059b9c4470d0f4fe7733d56a28a2c24456b6923703ef32cf0b8 001854e954654e726cf4bebc0e5a840e8809fd716059211c6ffeaed36829808363164684 ad1860dfb397edb5c385262db1351867cea345cf8d16aec445a708bc1945d7f4a2f8d6a585036ee8c8b5d125003d3fcd0b049560ec76de886e9e02f58cc67a637f95696ddacf8440d9709122cfd73b03291e34cca226fb5ce009d4280f1af1ae +fc5e4dddf4c4a328b685035ee79069770fbebcc56c14e31afb4bbcdd5220e025f31eba794fd6c05e64f19678dab33ce4f084bc32790392f14bf35669d75b6466b4214ec30d58ca90ae285c9058f5804a1fc9d7a995958f2a0e84ee52e8a78b601bec04ab607ffc2091749cc548c6754ed14e2e5f92315bdacaa7a12823ef76bf 03548f8020819588b3202f4c1ac62eaec6a47c2a19b2900c5a3cf5b4ba5804231141c647 8459d421d1ab0057a4aed622ba9375270e5cc4ebbc08eb23a127a50f353f88781888f3954572d268c74c4d7194545e860225e86a7590b4c96033909ed2972770878f8c926f6fae4f194fac9bc25377414510c0e079308dd08130142cd42cec0f +284cad790e6207e451a6a469cee3befc3ec43e047cf91b9dff1485718aa29de36a43f7c51eacd8589f0c3a96ec18e8ccfa92941b50b2132e3612d5b45e16f60d411d1c53e373e1ba451352e28970ada9dcb9802102518a385dc571dcf6900971b00346098a58042e0d1d129bd6801fa640a895a458a45b31318fe63ebb30c6e3 03cc4505005c41142308f1489226b7b542e2e7f24f1d3089ff6b92a4b0013f490ad52e60 848740039b526a82ce95634903f768f1e0d8a52dbcc7387cbae6261516c482263d634b7a7f66ddb536735b449ef3834a18bccc88693a4400b18acb7b719db4673ccfd542ab4e73268272abe56eb3529846c44e0ae031c215e325d9de94369229 +6d46e57abea9d115deda48b69fe8e0b36144df2f6a659509ce1b514c8cc4769d46e5f71df2a084f1db4a22fdd3ef0c2f90394f2898ce291b9f279c0664aa01419f5f6bee1fc1299871b27ecd57a5ac548f99d01871b8c238a6b46044c953b2e78e22346a0c7663af4db62799038ffb5c21ee512e26d01e70a4ed967377ab8405 0144a2fc8e0aa63506e14e4307df36416f963dd9da78655832f5b991af8c3eb97df78efc ac1a7c555b2694fe36a3e2cde07b9a3f6c7c9f5204c3c2db33a760e0528f3888b48439999fae76986b196254999088a6029033e8bd26b2b6e27e6a07b1f6ff8ff6cbb4ce82bc5f610bfded1dfdc267ef802e1045bc78cd339221cdb24214aca3 +dd750b39bd8753f4e473c4484e2b36ce2da7576813ebe05861c339ffae1d029bc793173ed394091c00685ad82f0550cb21ed1c68f0c27cb7396922239cfb886647af204e88a9101b7453a8ab662e270b87a8a13f2fe61d695597382cabeb781933bebfd7d0dcd33f77266e43e32d937f2dc89f67525e522977ce73e9ad36c8e1 024ffeaf139043ff25a395e4c560c7680c1c2155191378917eb25194136b4a69597dc277 b66378ae4d7883a3883215903b27be2d5896d78c18b8903a45c8ca8926edaf3a6b344b8f74462cd1fda1d5ca458b50d9155f574624c0c37c496dc953eb11cba24a32dabc2f3d982d9d936d10053fb7fb8a80652d96fbace34e91d4e3cd4c6af6 +4736e59fe5812f63737eed57a570182c065538abd9fb0a1c9c2059199e7052ba57d84b5fa1cda2ad9f216610361ce1dfb9334816b6bea509283756a03aaae2e5b0597f492d078b6b015a40c9785dcc5d2ae266176980db04f5cffef40e16661a50ef871c5f531d73fd5d114fa19bae9dd2da4267a131fc31849da38c2b78d1af 01d1f2e0f044a416e1087d645f60c53cb67be2efe7944b29ac832142f13d39b08ac52931 94b76d1dc3cade8ffb1ccb46cfc2ada3da2eed88ff8f85df49b637d096b3bd96a002bfa1aef4f6aee8289cb831554d2205ebd4196c7e1acd0ac666580699e6024b7bb20a55b54cfaf75d2c3a64f066d760f73f36e19ce0a5ae016d54d22ba4a4 +e573fa7d4bf5a5601e320130de91f4ad87eb7ca6b8998488afcef69c215b0cccd221b8b66eb0af9d699af9ad6c4b4a580e82941f31e4c0a9bd83995dd076c5ac9bebb34481061e7cb1b26f6e8c6b26ee4bdf9887f7ae2eb9fad3115a21dcc96acce85d23a040c0ebbe0a56e75714dbfa803d6e279b2f4280bcb993f96ba321e1 01337362609df74d25f7adee382225e6a04dd6ee4c6b45fa31499ce9edb0ec046325caf9 b0c0e1e5bcbf8ea5a1d77afa01bc073438ac72743c6c8397b0ff1c7ea8bb55080bd252b9932fc280ce4ebb5e54b600de18373cf4730cfb69527e6466cb5e6221deafc3af791fa657a8d26649aecaa5a0f2e898beb6e9a45ac6d261c42581cd83 +7862864d0d78b44e2a28af44a0a16d8e9b1b8c4b794db0410c0a863ba011018ef43e1e11f2fcda2f56fdb2a69cc817df425c9cb3b458922ba00d710190cae16d61af3c304a42fbb3d0c4a74a297253fccd70aca414865b41f68b01c561be281265fa89f63f975d3101334886e85929a5a47fa8dc459b663548faf8ed7484958d 01be00aa0afdfe92e24a2536594d4b41701ad4dfb223aab35ff49310bdba7566057fe8ac b14b53715e4ea731cda0a5821482e738290ad913923e881979ea0ad302900a47e7c38abbc829ca0bb4f92e4bc6b4343317db64a331fc193fa592b75ece4500b3112988158f67abda86aea8c89daaade556dca740fdce2c32b59e5b99ab8c5c74 +e73c96d1a84cf7cc96065b3c6a45db9531cd86a397e434072a38d5eeb9a90f62bf5d20bae22b926cfe967647d2bbb5dd1f59d6d58183f2cf8d06f4ac002ead026409ca6a1f868b406c84ff8887d737f65f9664f94801b2cd1f11aec336c0dbd4ec236d1cc4fc257489dc9709dfa64eae3653ac66ab32344936c03eeb06d5852d 012ad0aa248db4fbc649f503e93f86104cb705d88c58e01d3ae0099590a69aa006aa7efb 87e20e7d43aaf22b57ffb647adf6a764b4b5ff862ba3331fdc6386c800982c808ba3450a1bf6565075c832eb1c25957c19c6781e60a63c770051a0d8a35591f17516f9d4fd61c8ddeafaf05044ddacfed5aa0c408217fb5dd4e40a41a53992f4 +a73fb0aaec838d011110d49c5e94395ce07408917bacf7689d2cfe0948c582214b263c6b80e0a55f1e159086817605723740569eeaa1bae96b979679165c5c35ef2142525e943e595e6b4b160acd7ebe41de19775346363f779b1f80b6d5f0785b92a648028e456af8496102d19dc6526247a654bdae3368f075fa9ee92b2f4a 02cfbb8f340cae8e2e2322829148981cd9e509b0c65497fd8d9da5dee9dcfd39b0f7556c a6d52069e21f0286e198c82ae1fda9138b4a3082174b0786d3b69a0d2657c036b46e67da53a069b998e57238e21d69a40432fb79371b9f1493bf8fcae3045edd7a59b95df8e33471572bdfb037c26d044841b3484e9d0dd28359a40cfb88a3d1 +eda775984c7c9f7db47af30dab314d070fb77e9b623baa6b73e2cbda800f167b20fdc2e7219391efacf908f4ceed9b9b6bd3541b52ea087177e18c97391214758cf6455311fad336ab56cfdce57a18add8cf85b0a0bd6fa7297dbaa34bfc8585b0f06a0aae055186658c227e19cddb65de88d260f09f805c2e8854dcc524189d 0070e82a1f3fa6158d15b7346dd56150faee5c98c9d07c996e01a06dc9b211b12ff62d60 a462bccf8feefeeb61174a2633d0b50cafe6c209307c9ef9b860deb3e4dee3fdda4b239d5284ed912e64210bf019b527026bfe8480127909eb35834f4611fe46bc79e941591323dcb3203fcdd6f6ad5c170d91371705d3ee961f5ed31241f087 +a4a13e0bfa761b9bf37fade6570d41c161e20558874911ff3bee38e5649849b159beccf321c6bc7243f99c01a2fadbab9e157e9952ca65d8ea676c74fdc976d00501c626b8465c6cf0e4fd1a7d1260aea987161b821528b0b423e62ecc5193a0a49442b0c3e4ec9c4786a3a86b199c07dd3a17033d430d2c83c100f54e0a7c31 00b471bbc5f7a07996e370da4a09e71e2119ab3a562a273f079401951fbe4df39a4493da 9787a5513bd51e587c4fc883b20e50861c839b6d3b319dc69761547c4059746bec94c290eaf207f8f89e0c12fd53f0c2018658153a9b43067dc4b5233ddcb180663f1bb3ca349d2e2be3e0b197a7e016d1d5bc8768ce12a6d868c7fe12dc686e +7ceda7a7248640f7055309ae712c19d741375d6a7e0608e07f0135bb830dc3e8863ee9e7a75331a5e1bd38c42cdd484d4f45a26c2c1d4e05ce0d0ca941f4e94ecc6b371102f31633629e9861de558bcb6407d66eb91f1062ac0e0409db68b9f2855296a7f42fc92359a7dae16c73fd2dddea52bd866a4d501aedd8fe3b3ea733 03c65cf80bfb507dff52f9bf2f93df0642020d41619b3990009409e7210fd7130ac44ffe a6bc5c20ca06d8bfd03440f35bbd0919341d712b324b40c4a24a4f4b9e1002ae98ed14747b5f3d16278c76db35e8cf05125906d894ed976c61193b30e7068474b03672d871f2667e64ef82534eb399a1637372fbf47209b7a25b5368fdb31327 +609815edfd58c0e26a4b06dded831d2f33466a130754b96d8d7c3b4d99fd4b0789ec719bc25338d0ae8c5880560c02687d352d77c291e406eae865c3b26d00f2e63dc644ce7e01d6e96ceeac8bc1eeb257d36cbb25d89b5fff6e30b6051506a0ae54cfaf6214f30985d54cab78f708029c1fc0175bc58e888db89dea8d300abc 00f4d33a9c7e6744ab3c441828bf0f1866ae1c042cc54abc754e3801263a96cbb3955dfc ab6d216340651caea473375df049ef89da872434511a1733f99fd0349332790a9bbc46ab80faf0462796b0552491947d07f48d55760bd42967ce290cb49c666e6f9a2886b0994320101f9446fd2da076eff6cde64277e423500d4594089515a8 +82d8ebba707b72655497320200ce719520c1ae7f46f38122958fd99322c25c9f4d4344bcb77a6658df0eece5df163412ecdca58475d56b0c2d14a0361e4cef458df146925d473a43692b15e9bbec550f1bde3444f2a5b2ecb55d2abd273ae999f16a32333529d94455e485ca4585e6b07bedbfc2bd1eb766abf0d28bdb1ae6ec 03a4824bdcea6a144d85f1b194431724cc49849b6cb949b4766d641ae95477d1ec3d1464 b9f9afa4e29c4447f79b73e3154c2496bb78ed4dfda0064731ac9de5fbe9c3c55a0d370012f3469df550924da87e065715bc3871d353f7cfd200b9bafe9236b41c63c59163700b76330a24ab17035d6100866806d2850af717dffc594944a46d +9c6fce18a6a96349b10c9f2f5f1505c8ab727a650b44bc0782a5f39fcb48b45fc7c1b82180d5f229b8abfc807071f931d333d265fc940c93fae7520d8d40ef59d7c6e3678c6a2ecde52b6a8827b1ffc6ed269cb9832feb20e593a7e3d4708309342875199eb2ffceba7ecd707b122516c815e83e27872eda812e3ea52ee3c4a8 027ba543ea785df1d53d4ae4c1bd0a3a994cddf0c25d2b4e8ff17ea7aa00619e858da1a5 aeee5c7082b8527b7b9f07074cbbdfb3b64dbc81c798c9fed7f7cc07959c73ddae6b80ddd689e0b5929cec8f47be49d014f5c62ff104cafaecda7e1e7122bf6b5f1a91ae8f02bda41b4595055ee48bb4b3c2168f7fe475c8af5a6114c392a9b3 +5eac15a64c7653d125605869012b8f036804817aedacbb5a5248a595ee0c12329f91e8179c187192d3ed0d4ca2e202d8d4d9c93ad3f3ed931121c193af5b47a8a5dc39775b6c2d702708e5134f77a31bd62eaf87e39e6fd3f2b9f782c3057e162dd53b3addf92bf0ab99835c7f6649abd1c5322a1ebb2ba313df9464a74c14d3 00708d0907d14dcd5f40e2903e1e90e48a0ffaa6d4d9b84ca14df4e985c294f74eb9f2d2 899277be56a99ecfc0d5e8707acc0e576410f545e514a4a9cbc2173798899eebe893fa9ac7c065a15d4483a6fe67ddb608389cdb405192503bce45c079e76af614bcf416d8179e4e889e05f303da318e33224c00d17388c793991dd2b4238607 +df735a7e60bc267b18f313ad56bff830be5ef119baf43ce27c6368ff1dd89f010afd4f48740b11c12101c5903bfa71d6cb3d6462cf875bbd55a570ffedf3564088dfe8c8d3148231b78b5adaa6c53696737d4704daa59eab8d986fc6e519e81540f201e77b923a6a4af65d7173635b3b19b2023022186a7b8e869e1ed51717ab 021fb0a6b94080da8b8299b87457dc09d21bc430ba5f3359d92aacc1151be9941739567e 8594e813fca83af74fc2ada51aa538faafc12e281e74c1480ccfc84a392c0c32e99c6d1c33ffb0bb52db27bf93eda4460eb848f0669910fbac965c03fc69d44f3ea0a0e3e8dc039dc81200bee28ac706aceaf779f3c5165020f7edb79222426f +bb107b0eeaf175a786a61db923bc6d51dad5e922e85e57536118e032167b197b1a1f62d9bbcde04922fde781665c1094181c16ac914cf6fbbfb27bb8346b2134f05c55a8c6b9b481273758e380666d6e22c28577c29446cecc5c3df9ed9f1be060ca55ab2b7fda36a147aeb46df0275bb923e0876b703452fab42f6b7ad2ceb0 02c80151f91301fb6b0c7685bd172f20515b46bf94dbc4160d0720fbaedd40ec00084447 954f46f640dffc8197ce4cc348703f7dab6bb07307e724987bdd520116e527f6facd4a806273b1fd0c2c39c1c843517700ae50aa4afa4f770e658a402a71c36ea0dfd011e1f8b5c4949352fd691ad30ac3c50ed5f8c89076df2d0020668c2a4b +f47e49ae30b09b7666600b7a95e81b0afa1553da5e01fd917e4ce1b58dfaddb8dc8c03c0f5591f533610deb6a7bb5faf5dd1ec4103a587a1a4c58a110a706b0f301a5c408b3d984c210d5b4a0b347d2b5447271f25b527b3c7864f7cdfa735dfded47c63b723fa0f0413c57a24ffde9a95c35f743f892ab1ed1df704cde82d9c 01538abd7ce8a6028d01604b1b87db3aaf720e04220edf4d1d28c2d731aa25f509e58f2f 8f61dd29a309d6d64d14d9f1927f8fe22ce052c5f2a4cece47b210d0e2d68a69b5be01e5b20aabe1d73b5de84b587beb170a66606e3d39859ed3f72de55a61ced236d90d6be8a35cb4aa12ef75f7cc2a821ed94519a4ff6ce2eb3802bb9124a2 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B409 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B409 new file mode 100644 index 000000000000..19c8e6980c5c --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B409 @@ -0,0 +1,60 @@ +f2380acb0d869d1cf2e25a6bd46ebe49d1c9270624c5507be4299fe773749596d07d10f7c2be1c0b27e86f27b4a6f8dff68cfe5c0b4c58dad1b4ebec7bd00ab195fdd635d9fa8a15acf81816868d737b8922379648ed70022b98c388ede5355e4d50e6bc9ec57737d8843fabda78054e92777c4b90466a5af35dd79e5d7a81ce 00beb0df3b0e05a4b5cf67abef2b1827f5f3ada4a0e6c3f23d698f15a3176cb40e85bf741c9fbc78c9e207fa7302657527fd92fb 96c853860ca3eb823d18ea4108565862d36dd515cd765e8768d5fa16ea3888d2e3e3c352a83f1982f6abae46d98b52f5134855034a993f9e8cc71aae0c85621ccae155bceb51f53633d5a568a7f74d05779444bb226bf5b3f0b7dc46cfc0c713 +22a97fc0a9694dabc6f274ab52eb592dbbe8beeb646ebe6cef60eff341a13017eef980aba6d24ab3afd976e2f6a84cf652654d4a54a36b2f2f62fab8858f8b0479a48fe9f47f8fd5a4a1f3141a91cbca186507b2bbfef5e4c4d2df525f04ef7c4720fb443ccad540f03a2be468d88c9545d1dad579fd7cbcd103bbebc9e9f961 00504865a30984a9b273d1bc289d734d10e0aa56e93ab14720f1a42a27d8cc932cb8804b963175de6fe57d8eafa8ab7ea0592dfa b309501c483e3e5f0ef2afd63772c0d2852763365f2af9e9340d423c715a3279b4867a23528b7e2387f9ecdca46d8afc117353e97ba02c33e71654c8d132ce94185b5472ce7461b728b27459e8793127f95c8aa9618b7778058dca225009b25e +af36c04af0e3fd64bf52dedf52fb788d2d1bd67fe05d98880cc7ad3c20436abf02f637fcec209fbf888903fdec8682717299f8a4386768153b7faeb6581db57fb9aaf4615b4ea8d924198fdd158363a1f40312527d6bd14c13d19985b668c6b88a7548104b1ff057d07082eea421f50062a315bc3866378f2d2d634f03fbc0cf 00cc08a4ea5ebe32027885a8c212870e7c45b6c610117994d6a42a284c05199414a3a0e8e6645ac5c2ebf21c505a601f69c62b85 a5e7687dd1fa7d4a5bf9e31dbb583f934f3fb1877cef1e551c1bfadc50653e44e26fadfdeed9800583b3156a0cdd9a3a159bd07fb06ddcdf352e2aef583f3621c91a50ccfd84e116d094d5b346c0797af56cc9c281860a482d993e58be68ff9e +6bd6f52a6204b60f37929aeff28c87ef61ddeecc231e52a7772275f9329add899c130956f8c50ac2698aad3654fdb49b74a6427a62a11eca0a8ee8b719b8c0df7b9f0bb0af5fef4918a8c83367d29fddd04b6a1ecad904471e5b59c8fe3cdb06b4f8f96419518dda960845d83c49a49f1b1f2fd1d2682a9d60c25fe3ce982cf7 007156ef0a74ee1119532a2a7e8c02be1559c3c21897af9d5b34553c3d0feca4a8d5929d1945df824478e0c0b92a6fac8c84f639 a91aa7d116aca617f1969d36594215319119a1b5317586acf534d1cdc897ad41573fe7f493a2a2154925773ec3f845e10cc5dbf0fa0447685880045facd3275f03e405b2ad04f2c76170a787f47250d22c5fe61b363acb69a54f629fd6ce4f6b +0eb8de25f63abc9cba16823270e9b6f3fdedf0fb90f6652a34688970932e3ae98f6d3bf0fefc5f247f72960a6975bff1f1acc2188a1775fe8974b2bb2b4c8d226ceb735113a14009e8ce66d58808fada4e6f697fd016829913352c0f659b6be354a067df00cf74919580750aa6064f21264d89dcb28b3b2d4d699115c36d1310 00a95c7abffa92e2c637611ccba66ff9d2ab121b40a85c5b71454cb0dca1f098ce1be8d9ea4933d1a91bcd270c5a33687835d6e4 a576c6499145523b17efb5793b6d6be68e5e7e027b82e5ba817b38a5cc4819143a22a0f80dd285a6977d9b61c195621610b8bd7d83710bc0ed06d9e0f36041a15bf5914f182f07843506b1bafb272edb0095e6d0c418615f297178b0b66862d0 +cad58ca7a3b9967dc0ab62a43037764f8074ef9177d60bd98f623d693333971c24a575ed03cb61f4dc2e3d6285fb1204502a540f3c0bbbf23f5bbbd1544f322ce35d949d8b1d8edeb82e90927ac67ad49c91007056bf5096bd690d15ac00e1874fe33293d8003a4a2b094078cf09af799dde384143350c54a99e1f99cc31f2d1 002c438b07c6e0685d1f94a4bbafc013f8f21265d893f54e54c3ac2071606ad1ffacace0b8367aad724b1d9508c65ce52282e397 b3aad9c4cb08d94d2724c4dda9e7efb249b025db5f45ce1c335113e3f8859bd66dcbac77ef1c723e4b5691a0e546f35300949d3cd55c6ef51bc7ff1302153c5a63e65ede31a953fdfd18172d1af7d7b8db29c1a7cd6fa4166295c60eada2227a +281ce2643799bbfacc7d5993683a4fa656040517854f3c2dc7c4f8848dc305382e34e894d433caf12d8b493020a6a08d1fa05b08bf6c53127ad5f33bbe75b9db0615e3dd94408d028dcf3cb7598f6e7cb4c787681dabac7cba2cc06fccb7506fece6c7c1c1bf622d525ae9737085ab4ac578905950002024f30159cf0d99f50c 009e8658f8f9e6cd98c0f4f0fd20d64d725653aeba339504def17f3ad12a63dc6157d80804e5f43f4ff48fc5573fde2c615ed31b b6aa016b27ac9ddc2719f307137fb7a4b85bcd6696822aec06ce4b9b84f94f29bb192992b1c5c319f40bc4ef8157169e151053d294aa73d64de97c0bcacddb2fdaca6d884eda8687decbc04895f85e1524aa434e96e0430ee0361c2804955acb +0c061da1a16f2be130ae3b20b89745e840bee09633fb49671db28ec9a051545f57ee07e2410ae7ebc61c9af79868d3047705bfc64ac0c04ef0b286e579b650c7165443631e49e6a53c84cefa5625b1e1035a6ed89b8e839540040151132a937666524265e099272c1849f806db0fdf2be64960d5b5853965099459968e5beb32 00c4c13f65eacce85a51881caa6f82d9e48ec2ac574947d2751823a7f072d38bd9da0cdf30b6f19084a6d291052e7bbc2e1349e1 a27ad1891102c83fea9351a72e37ce64d6b9aa4d8d6b9732218e19cdd9f460fe52601471c087bcfbb63ff44ba6738ad0059f9ffcd02b63d8d8165e1c1ed8e8d6744d0568a8b2a61175ba2c089451cfb5b5741e0fab6fe7208b276c90794628ed +74ac2e1303297efc3ed8e624722df505df55b7f33964cc0d270604cc48b58205d8a11952232a8feb0079baa30d7d33660268b56a5a3dd90105f0703abef8f6636a99bc63bd47d9df100351bee32d8205dab0dbd2af36fd173409ff8d1fb7b24570f3c1e968458f58aea5aa2f46731ee91ffd6d3a060af6b3d5020daf1362af3e 00da591461791ae7847e6d8dd8df46a63d3021644abe9520e158406c96540d8fd82ecfb1c3f6f5cfd7688c7656cc3e3dc94e586e b69818daad44472065b9c02012b285b8f9ee17f4340c1528c8ef7380bbebde62aecc2020bea9ade4f46463476d1551600acfd56c6a600f2e6f49472fae669b52395466a61e2501c59b3c15a8c153f34a308e326010fda6d91a0bb1c8f1113f66 +2afd17344552ccc577b0118caeb7dd56a0766e25f84df17c0505f9798931374b48df89a48c64e199108c36e00c0bf00a97ccde55787bb97c6765601765ab5417f3e75e35a9fe5e0f85a721d9f08440ed617afcdc200b318940a1e496040a6ad9090476b0fb4fcceee77b3fea11de09e7fb14853d1fff8ab12d66c101257e2d4f 00b5eb943f0dd390b737510e2bb703a67f2dd89dc9f6dca6790bc7a260cb2d0fb8e1a81ad6009ed51010e7686d5b48233c6c1686 92c68e472612a806bf38ee4e52b3a5af1eb90dfb019cad5ba01cc94f0fc09c46ee9fcc8e80b7efc5034745319895eff2087e6681f448af25cc38941b40e13fb43f40569dd4a1b495119b4b6c48ba4b2fe01204925bfe12b07ab0b8711f413ecd +174b2b083541f8284645a810801e72631a11bd7bb805f684a7159e055afc44357f2c80df2b7853678d34a04144e0ede2327d03db6df23769ec41194a8d9d86af74d51c5bc11ea878c6a80689af71d3fdaf1c651003385332a512e03dd040c33d9c328ca89ec7ee9026bbacf30a7f3a68e0d894fb9f7100ffbc64bf17679dedd1 009cc63f32152284fca27ab2837bf1343144336a1fdf15b9727c47e877ac69ac9cf4c97b4bf42f1ab10d73de8597a554ed099efa 8a7409706986b3cf861286388dc12cf83e6458e9e80fd597d494c4af3101118ad76dd7465dbe9b3c4ae74634e744c1fc180faeff9580c82af12f5b97c387f287299a83a08ba372efeb8d438773117b7c78d7c67dadae9398f3969aa0b8590c59 +758df71a952cdcffdc417b9fffdfb57582ab5c5473a8bdf0c2101953b023b77824263353dea0e2ede1f800a5757ec6ac0e1e4e3ab5a4cd85567d2d19acc6b7069a6e7368401cba2b6e642373654bec0ddd19fbf032794c15b7ef7e714e13e36875262c01e77766ed53cbcf735936dc9b33eaf2152a396349c82ca0297dbae4a5 009950355e8667bea8bbe3a2c4988436ab5394551b375e27fdc0c1a1d1b07ae957932f428f1aca0a486e54cd0b5bb0a5c5650641 89291a772cc8e0ef597f38ee333fbcc294c422cad92a65ea527827dfb5483d083d71811b4658ed806461f15afc443ca908882705f8ee4d2215e7d396c9f525595490ca652a79b4610672c58ef24cde6c3b03dd73ba05e6ee6e2aedd5247aebc4 +b96d9f66b2000e9408d602096f032b112f0e05ea874229ab9daf6e05bee49b4722e4f2d8bf2eeaab9dad94438c76b7cc64dcbb59cb4e03f9ac70487a1d24d8d6b72d7462fe738a17edf381d52179b3acc0c0177c113eb4d10e8e78041deac1d56abda0ddf892edb8be956d285e7236bc6794168f8a180f622dd5f2b9e690c275 00a995493d6971c2d7e8fac3da9f8c0b5afd877cfb94924cfecc167f9d87002136ab253e3a4f9ddf5c9c99bb1dc1af0c6a3a3c4c 8ee21d767fe58fca1448724d31025e90cef2f9a1d51bd4d5fd8bfddd27a5e67c36ee454ddf4b9105abfc9cde34d718ba15fa6e90d2144157bf5e3964d5831f9f5e42bac5585463f6d64642d4f32fc242da26aa55d25fb81c10800b6a504cd5ad +e7ae60ac55e6ba62a75d5328bbc15269d4638764169de0bf0df043d15f9152bed909b1fb8c7a8d8e88ac4f552c1092b62db00958a3a827f64896f6de4bbd8fa5258d6c36e3904d82d3eacf6eedba50b0242eb6b01212288448c3a9821c4fa493869c01149ff1850e8115cf9de1618cb8744626b1951d1de305745507c8b21045 0070daf435cdc26ad66c3186267ad12d10f28d32d863f950cbfcf042fe9dfce553750ad098f82f7f1650c1126b3e4451bee6e11f ab434df4a7832c7ace2c8f2b28c929ba49c85292fed726614ea6bf52d7ff33ebfce1fca6127da0a30248c83cda45f1970b966c175ae4aff3fae639baf7539886ca2ed6225f0bdaa5576e4f2ddfe40f50a167744eb0f9c07c7a97a99b8690c8d1 +666b0dc2ddffaa7ffd57ea3b2768f02d4b77c16fa007c6d1918400d195f068cae2dcaa69817e6e4c70d5b29c5598efe2d957bd12d0fafdcf5ac52dee80a2d46e77fc18cce2a49bfd787ff77b942c753974d22434742bdb494590d17c42af725b1309e54566276af3bcfbf5e174d3cf191b85903faafa1583282c97e66c5da6c4 00f8121980dfbe9ad0bf92383c7cab95fb72d5caba96e1de7772c6a179e85414802fbb86d725401451329287305570ec7fdd873a 945326c51c1c0052979cbd0c6e4394f58c63088a21089faad842cd1e62c20f68fa93f7590468598846c145a91bfe36a1066d709210e9bd682177b93af3df9525b0edb8c1b978110fe3ec3d926f34c88fd449076545c853c101a958b5e8b4f30b +3e967cbc2bd936e0b6125dc5cf885735bdcd2d95b2f764de6931c4578ac8e0e87abdf96375481df67dbe1b6c43537e84ec62bfca6672cc5f3ea4125abd4a4119edffe04e42411d338e8b10abb1f1f818c50a9631a3f89feb5be5367bdcb0a8a82c96a427ba6ce99f9631d4411a2b7f5b14d32cb3901dc9d285e4cf5508940942 0047682b2e3bcb5800a531858e8137692a9b1ee98ea74e929ce4c919c26ae3b3f1d4122d07fd9a70d8315fab727ccb67004187a3 b218de90f584b53b08308547de12faa688c3ecf7cbc72c2771302155e7b55e9ce0f0f1c71a97cc70647839aacd544a6e10614d90a1c253d08003dd7feb80759806e883c4a8e8eaf121bfb7a01e13ba97d52e3defd017319305c239e7047b8f1e +ca1c90012eba4e7c5f01d8cb3814c58f48c03a16be6ed86934014365eee547070b870d1d26a872cfd28b60d9ee0a66dea223e9eaa90ee28076188d6091f26f665684f4b486af70669555db9058d485c677b2a34d4a98aa8d6f43bf6f44aff2a23c5d765e98f0438ab81be0585a5be29daece5d4116f44ce6062753a3ddc505f3 0040cd1a06233ac27f3ddd108de7c6c0982793ee620d71982697713be9fd5143658929924cc88747a680779bb00da8a44e1e7d3f ac26a078cac5844327699c8649dc54597e0be6ce5120dec5c32b32da2697132225caf9eed22929bf09d9617366a9210b0d81e0e767bae761c983cd0494437dc47fd9a99221ef4c15d95df67c3ccd20e00198da34d8232ba9e567e10d178bc425 +a54c4351ebdb075d6a42a787647390f864b2bbfd8bb3d0e0ea9d767200fa344d1a9ff091bddb186acd69bcaecd767068efe4d752d185bfe63f6674279d0e7192d2077c400bbc0d5599ee28507c1253f05eae0687b965a015e1f3a292b4650106765266f5c95b77ad2d82a6a6e012f233169eb6b8d83576901cfd4a927c54d7f4 001ca6f752aae4eb7fc9c73a08d6fbd96bfde5030d759a2507bd45b6e1d1487e53abbe98fad4f41976364e0a1d830910ccf97abc 8e999ce2625f8c20e8f831f61238195eca4085dab3e0f286d8319bbd2cc389cabc27ed208d0ac75fad4094247fbee47d016e15b885c1d5537a8883c1093cded8e556571b7e1560a061e6360c46c21d6693ca2818762c509ef0020ac655974da1 +6723dbddc8720feeb75e2a061b7fc49079f999fbc79ec8a8e01ab8d35b438b7049da5a23c49a58101742791f84f45d5f5cf551cd7de6926a0e2c4ffa1e378f038da597368c62df8cd8349bf046de46d02183dc05b3a3575f5f232dd2970057200e2c9cb60eaa6b4d72f8b73d4d40b98d1cc801d1a69cb5ed780a75a4064623b2 00fb9b1a9597d216028902abf743d25944258b48c9762d4589fe660396130b75f6006cacfde60f6204463cb8c18b032de1dd68d2 9586fc7878969a2f656c536a5bc8e633e87fa18f6587624e994a6f94f8a750e1d8d30ca02744899047bea403d6dd93ce0b0b5809fd7c5b6c1c7b5cae978dbea155a63696590961aa06f6dbc2b4207c6db36b12140112edb29c0b358c0c8e64e7 +ed53cec5e5500d62d38c829002916c657674ede4439c6f405ba672327ec677490e656bdd698f114c2ab5e6a1fc94a1a8d64466cfe9eaabd23a8b5c37f76a3c0decdef73b3e7b751cbf3b0817f4079560b5ea34cead88ba374201236bffc48eaf289bbaa4e828afa7d732473c228ad00588c9b443d65b998f21c3d7a9e9196c08 0032109202d754da290c266f74f47805a06e6b5c3f721a72fc97a3bffeb8887e0c642d49a6bd034847d0a5ba09239c5dfdf0772d 92cad8957adad68ebfba35aa848cc8859de4706087fa221ea2e7953e6c3a1cc1bdea498885c014d5eaf0568b55347fc217da94c20c910cacaea25c0b8c7070a8c1af4900122e1d676a4b02c5ea069eb65118494bc11d8a5a59dc356679d6a54b +13829401bd41e9fe01329e9f5a002f90f1a6ecbf25fc63e7c1345f265ff02e496230f706c6ab377ea52d8707b54f8fc5c7f089044e2bec1dfc66a07da76ee12fb9ea0697d87706b0ebf677600bd2fe117f6cdefb8bd636a1b6b97549ee78f992c24acdf3a946053f06fd012a9c703efb8bd929a66aa74b05d61bff0395232b00 0080536e820fac59b3203aea928475043b2576446619001647e35693a9e65d15236c3cbc12e1bbe0eb305973535c882b70197a92 a84d28325ea3206d7f5aed4ef9253907a2749f6cd19c2dffe62be6dab5dd229126b9c720dc3989a9752e8349d2e9e4ea1545ed62dc9eec7ec745b1af650e8eda07bb261a0fc5e861375457cf190a16172b70084403d51287fd2c3422d4b1e542 +e696acdfcc96a6c088069b7595ea9516a36d8fe04dedeb789fbd965db0cc64b7017a821015f6210b6989e515def5a9605fec0d337e4ac59f3101a505168bf72ab6d98ec62a71d2f94071fc05b95e98d4efc59fedc138e3e49c5d0b44d1f48f7b1e7c1944ee189b242950d2bc804d31c7eeb45283c84638f043ab9533976433a4 00b05e5f0dad9583ea18fb8fc4d8c75fd2e3cf9e92cdd9b737485c953620d345006c31c288b380258b6500b84f729ce6730e5303 ac1ef6a1014502889f02b1ecf78cdc6ca7b016842d1043c752a481fed573694d07feabb98b17226f39dc69a8b522b9380e7d95a0a2dce6457e9a3a55e6bbec211862eddbabd89d8967db389a4172510c520e55a9261d25ab370251c73d1be8d2 +4058b9a8cc15ac148909eb97fa32aafbb6077b168dde91a411dbc973df7db056dc57ff78f0abcb70f70f800bd752197d681f44df4a7817c0e7f60f8f65489ecb6167c14b525e91fd2cc5d8b80ba380a83d031d5827c8b1262c687c90ef0e62723d9b565557f9f6fed0db48f3799274c2cd60a14303406c35802cba6261121296 00be1d277813e79051ca1611c783d66003ef759b9e104f32298017fb97667b94dcee1ce807dc6b4d62416e65d4120523bf6a4edc 87a0e88a5046e1d831cd51e848f0aeca8f2f8997e225e5c636053c2331df065b8b0477356a9e60679c35c1f05166beda0aa33999307f5198e34f70142ed3ab0f947ec60a91c99f5749364bcafc726d1f46c9ae02e0c1c988cb5c8b94f72ee7f0 +e793237d46e265ab84ba9929b196405faa3b0e4686e8693567e53f68e6991e57677974677682a2510c4c35b1968a90b32c4941af7813775c061c008a60f9f671cf7419c94253d6106b61e65034497f2d273a5058379bd986e3d917f708f0a2bebdba150f6d78a3af9c722a2430ab0f4bad602e91e18aaf258e3785fee78e4502 0073c807bd7e07379782ab790720de4ae5106f16d34e80ed70da5b1594e660c9b775db94066b93e74f855f57d88b6ecc6228aace b86e7c478cf7b35bc694841ab513743bde92d8d3cb177ece4cf54cbf7b229385cd3222b8024fa15b585f105a5e8151ad0efeff2d1216fc9c948cf63e7069c94b660be7d178b92fcc194be333c6e5d07d0e834121f9edd00e0b92ae4f0c7f20a2 +ffb8bc80e7619a562d8506eba7658bef0c25ace3dc1d01bdc2ef00933d4fa07b80364e5e5826074edd46a707dbc3b0ab19eec7ea8990839d7fc0a80b70661204c52bcbef57c1a7bdc861c10766033a82dafbead283d911a9502d5f9ef0a39d35ef26f3616212d4bafcd413ffd18b424fe09b48ba02ca5d97ec996205cd49d22e 00a68379b2296a6c944ad5dacb593b302d8ef0b05873ce12bbc371d705f308c739d21f343349524aa72f05341e64f7435daef112 ab4b641470d7a6cdf3d78ff7432d5703a71cad2f2d9de79b277c83b750337f7b855f147528bd2db0d3d8e0f9e2f88b8108bcfca8f7a658eb2497ab19ff55882f36f4ea5a2de89135f6c49a1d1f00f389aae0969a5b5229dcb85b44c8aac8dce0 +946bde90a5b903dd281a51d7fa93d80f3fed07eaf50c18fe9fac5acf67326bb18effa3144e25c151efc006a50a274ec6c6a5d573051c4e2d117ceb0fa125acad07a10fb6534a8e5f5b3da2a1136779c51377bf76c3a4a93c0c6158f729f2293e414fcb952c9509f228c804f0adc1daa327a8991d48ccf4f3957c5f8ccbe3ad4a 0026046bbb269ddb1ec14ade56175482343a21b7c265026cef3c7d6a1ae0f6a68166b9e6c49a6e733ad2ad64df7137ef230038fb abebd0c9eaf74d8075c6c7a468ef43c18e788f1e7b10493504edc5f8fa888a85bf3f4b163133049fa57c6036223b844f0b83f6326db0ce57fbf8852106c7c41abd1da78049783fc42d5d5b57f93025bdf5f41bec81b5278b6753913f8eb6b411 +07f3fe1369ebfcbcacd66675bd4ab22edbbff72e68709cb57d4f590e49440f01691f490c58b5117bd24aa2fe2101b59c61c417c918ea08ea34bbb9b8aa17491ae5d9329affe894f42d7586017877fae3ce35bb80c97f92a004380374ec91e151995166e14ac00505fd1fa810cf02981bacbcebf5f81b2e633d3a3db6737890f4 00bbcda66978ea526f7bd867c3303b625f11b94dd9ee6e2c2f8688ff07f2bba83c662949d47ad47fa882cb7d203a7f0ef5dbc52a b7b9d722438b0aeb7eb063a1a3838d1f46cf2522aabe6e7784ba679f7e473d9cd3c2aa67529f022890ecac2c60ccc391110a7411f4be4273637465f0d4b85dcdecc47980adde435f6ef83b6ade14bf70d23ed34106d49e22d20901b7adaa5b43 +3a1cb13438e3bac9ad4ab1d319e90e2c9f118dcf1eb54d6333c674a665d41451f93cd4a9334cd057a44c010edb668254517a63700a31eb0ca474c84873e486f2f8e158a1a7735362ea0cff8ef17d959ffd851b21a91412709b3c729474d2cb40f6ca0e397030eb2611b402916e4b656f0fd868247d80be3ce33d52054b7661f0 009be3dd3442e0330750f0a6252bf9cb317f32f942ae516a4038dea2c40ca6484fb33611bef016cc64baf166c122e87c15466fd8 a809de2ee5137a17e5f0d14648c04fa09820cc1236c1c0826977f150fa40ecd5490c25c6afedca5d14c1e69e69c921d90d5b9267319b336847188c8a566c26959d585c18513bf5667deaa6e0a4610d9c32920e10e491613f26a6ad7a868f201f +e58e7b881a563d54772125b2863718690a5276c93d9e1c5feabbdb5d6f7c7293ff0f89805b53663bb417fdd46874b8e6a466e7e3ff6737930a0662af1d5879b071b0dc4d014778dff26a2eca5992e763bf4c4698c382ac947215aa116515876008a56e5bf547857049c38a2d3737ed3393705fd346897c3beb80caab88e5b8cf 00ed321fa283c662e87eaab99b7715e6cdc9b42e14fa5bbe2c56fdfb381369191a42da7e574839f90a85577485f19446fccaf6cd 9703e2cce7c926d6bfb2e479b495ca0c5d7309a36d3c7c0c7e15be83b3ba8c968eee2ff92f32434957faff51c7e970181260fe9a44e8b5f32d9646fcb8509e16cf82aa159b15ef5b884ba1f47956624ab285427dc9122bcfe33e333a86fd666d +8889ea1da1cbed98963941f6ac24f47253ff6af52de920765214f2024aeb04f7ad46936830a8eb04d95aba64ed7cda6ef242f454b67bc2de38a46b6524bd5c96739c4b580e89829a61a8249ec8dc27a50f43b8554cfb6f4fa4ca6875983d4b60a1c6b49f32ddff6fac0cafb64d55c6f594b195c207a9bd920dcf20e0080920bf 00396b805073f3c3b552b1024dcf35559ac44f255b688871a3c6657f727a4b09f3806cbb75d26a00ae1728be632387e804775a8c b3dab3a9e9be33b978b609c402d3fea0d9ffafdcafdd3ed4d47526d46b364a720895fa7fcc0aa96bae8da73cd68d0f8b1133af190c9d7c7978e846f3873a74f55f9f4567cd70ef576540fe5fdcc148a32cb157a8fa53d07c7acc8380064d3ccd +55053af9370901e38622734a5bc5589f6a20e258627f381fb0c366f3dbe58394e5997e978eb7ebbc530f6e6186f48294149b8594fb551c31c50521a8c4d67e5862921695604afb23977b6a69b21abe75966fdd11bfbdb6b51ab0a474c5fa07c4de7872a3bd81acc417655090558dfcd5af449b3347e61fa9e839bb9457de64c1 00a8fe323f6736bcabe971c7d964e75dece70cb54561da48a11c40027ebddb23e41c7b48600f569500fe8ea2abebdf480171dde4 8863106307e4194bc3ddc52218c600ebb8ca7ec5ea92f17a76892ada14422f5978d5531efbf7771e8bcb4d2b5234e6cc112d728093b2252761c785d68a938feaeb3b98f5efdbe741e38c374d87b378ec2faf175634c0b8105ff19eb47607653e +c4264330534a6c2bbd8a3b757e0912558302ce302f835ad8c5474993832fd30036fdef40b10ee37293e871db5b0b149654f9e543e22111f9709ef45732125f713c031ccfbc9a2f3aba160c241d27be4dab87ab2fa9a795752ab2daf20f9d06a98d90d01c07133adfe83cb11d5176525e1bba6a9ba70ea48b224d46ddd8103f65 00105938ba9f25034da3e032dee121bdb192ac2128b50a2ed4bca042e96cfaf4660c9d35f3e67bafd4c99f9447e6dc408e0c4471 aed517c531a7f2cec22dca5e1b4f21144826f72c1229d45aa939c2be4c6f883fed6ab6bd2cd3c4d0668193e1f21a777505edda3b81955c00c64f10c8e8af6a5daea77402d47911f9f15448f13069063a4757befbf03bf17e67ab408c96f9e57c +3236f1ad164e1b25d828f5202e3513c80c72a577aa9af56f041fd96cf5a3363f4b827723b1511a2f16360e32eac90ac55f4ee1146791420ef9e2af333c17d157b00e43992ef6f2be2d2f211361e468413dd93fb69232f0a0d110bc5fff361c0410344aa0636bf809062c73a7ac7c142063912b6ad7e1626fd2a384f35faffaad 00ce11677ca818537dbaeb880fc967dc8bead203a2538a55e756679c4a9e7975b9b3e6aba4e6c6eab4152d0c0939027e9b0bd92a ac8defaa733ecf6574084f8fbe30ff01fd304d807a50e9b28212ba5649dca1cd6540a7f82ecff4f2aad69fd84803078b0e8655ced61d1f49ac14860f9d957d2e4c3e4e4eb0b0a46e915cbb14b73d85f9c402184ceca2cb338b5e2fb2b8a925bd +6c400ed098d8369dab6fde3553afbbd4d47836d0d12dd16015f15cb8d067a39391c85ca4e78c62b8b72c1592349ff8dc52db8ccb7fd80c085fae456dba6f4a2378e184dd59238c92cf04e40d43a66b342d2a1325a0bab12b1ac857f0564c27b35e6abed02ff5bbbdc3770ddbb2ee0513df48bcba925da6d61583076cd3129603 005a239ae0f40d76d8d3589f1662b5ca12176a4b2784faa8339b54e96a1e1294433a4d83bf904196f939bd8b33bdb4be340ec703 b6ebfce58df33d312b9975ccff247f7e89c15ff4f7d2597c47ce20e9de7b70a2b0900575b53000082334a38d2a5cd8bb1466329cfc795f59600a64e464163c6638f68606f21b0b58abb0ab834ef37f3425ae9f6ac1e7575ad76c99e6dc8bf844 +039a149eaef2de30b0ae457b376ce6fbf88afd4cfdec02d3c5e00400d3b0484c1cd6ba74db5de65d6f2fe39871349b30fdf1ef29bcbb9e182eb3ec5629d07d98354a5dfa82d7f0db3dd10d1510c0dce086848a198893ca5ad24a663494f0596b4eee86199ea85e7e8f2f76e7a6bd4a052c54287f61b391f1e52f96b606151c34 00077390c62ac41aca995640fde0c79c76f4ea8a8dbb22323ed812bee837ab8798c5d0ba976c7aa634d4b1c2c155de2709e7352c 9199d22f10df863f27704181b2ed00cd8749ec33cd927a95f89e1cb8ebf72221d0f65490ceb27fa3dc83b38b4484ee2119681203a3494725d4bf804da0205c8503b9ca42f4e6f395afca52bc9a52c1859ba2e2d4ea8240660cee9704a0cd03c4 +08617d04fffd6644c40f7dd57919f7dcf3c888f4147535d12ca658302305bb8e220bb17ccdc480254004b9035b357120580882ef86aa5a061b2850100285b7d61588a664dd4f5394f5478e68a80f610c9204d056009c1c9e902161eda33ef61aa902e96b6f094a9f053135692182943d38b9763055a38739a2a2d133c5dbee89 008bf23b09fbbed1b55769907aafb97f4759cec98649b2c9da5157517d4f85bb70157076b5e4aaa7a940af042302f8be06a84ab6 876eb7cf6366ae2750e62395798970cd32cdbfab076b2dca69aae9f417d2de7aa964a08b021bfd7db7981fc7e04602e5059d8f8aafd0b12f83346c35e37dbabc45f7caa930b94175771dac87a570689dac0c294558302961c8316bf3e2acd08c +34c959f549a307f21b850ae105f41299b8bc94fc292aefc61aefbe0a1bf57576ba8d9b80caac635e4edeb22530163fa9629665fcd43959f68eee32482f1845a78ed7278e6e43d09ed6fedf465001afc0d61f1d2e1d747623e82a762576b879c7024e34f43104593cdd691d53bccaeb8f212dc29bec6bc94cf69d0a8491db124a 00082ad05d19b8e16f80e53a4cccf6869ab5128c5e622ed146fa8555985ccd2aa3b9957dd374586115d4d75b1c01cf98ecfc3646 b3fb4fbbada673b145f330eb4fb40ace0ce30e294b03b71473f75415b1889d612155117c1c47914763716212d3553d0503d9253b18e6010e50d99d4d7b4935709697aff38099b6ec35d9c91724f19f771002bc9a2114ee571064482580f81bf8 +514f4de08a6f49edbb6797c9dad6d33bfa367cc1a1b58a5becfe646c7f3352d5c5d95f7456e7112c4ddc746b9076b9756ae3916c07bbe6d3823895774a42d25d44b3309d18bfe7e3ccb1f85dacfec1654778c19e2981a853c1f40a7eafd16d331093110698c957fe9f1d86582706a6885543248b944bb70cdf9d2ea89190cb02 00af7e581aa4f9be5815f0c447e39de00da9194eee5e5f609668b9b69930b5b48a948614c2250260d1917f0ebcb00ebda4bb52f8 95108eead023b0d61ec5d01f7a2075627fe8817981ecefe422b9b828966997f4a864a1216250fa934a28786eff0a738a0ab8bda6d2ec02ac59e15a24163da3e5914d65d510d793e1db7e675e05ccb0a4b7cdcc7128da2edf9a6c3e154e8954c9 +4e5d16cb1dcaa1abab1e371e1de02f31ef4e0944dfe1fdec45ab64326435b2af9aaf1a6ed8fdf1a6ab1182bb53a844c7cfd66da30aec0d41757f5988ada0017c4ca752597a9fd3637668bc1a92bb1556553f28d66805bb47f1ef91908ce098d452872da9800e77e1fbd43ffb0ed6fe6a62185d4be73ae96c9241b82cefb2da22 006d14107b08354e6a41d7d7d50c004419db8bdc50db43428df5e86084551237223c498bce71a17e25695bc438c5c09e009c60e2 81d9c398eb175529bafd73d6c33f8245988ca8bde0fef27f0e822a0a9d4f1eb118247445f001d7c24053f464bc85454b00fa29d259ea3a53aafa173c5408d48407807accadb736a8665f6a280f255fcbb2f27f81b1a38791c07262fea443e1bd +e29e75269754ec1194270f5c9e8267dfdd8c696008b5ebc92bb840981fd065672f07f6a0f1b19841adfc51b478371e1a0db9c3346a9f0a4ccbdecb7040191a00ddfd0a8faa0e69fcf544319c0155d02797eeef99fabbc55078f9d852927c23fd931685424249b87ed0c70a4a3e2d3b9a2f92830e7d8f7650c0bffa8f8986b7d5 0099d96d2dc9c79549f031bd5346cf6a8544c312a3fbfc560dc8e378efdfe025b0e6e61e09c04c8bf4133396f993b0906c33dd30 98ddd526c6de2c1ee49dfe775124cd4c908607f8ccf97184defa14ba045bd95bd68367213fe39c3e40005746934da679018c7ae23bbd8febcf1cfc9b32ce7e8201a39a57be31aa59062c98d363f26fa9185c6e22dfc726925ce50f1287420f92 +1a538eb447c18494ad5a5ad27be67fa60eb2c5cb2404eec1dbd7244cd802b17ca5497e779d5f779b981b165dab53ad19fd7bf2ea7dbb9b4baea782a43d758202f147e59d6b6b8ed54f4ea084bc18519943f6894d603e253ba3e8e339a6933bc3a0a47126087038e1c813c3f2997aae321b7c95a802b4b73fc7db95897b7c91e3 0049f347dfd361a65910e97fcefbf60013a54837f2ae657d65e02397f59dc6bca27704fed3affdc3d833fdc621cc5e5f99b92a63 96c2a9a48a7a2ab0527c9917e64afa26c88d3950453e1837e751d127953388284d02bf8f653492bcb783772b9689f8840557654e4c7e617df1d789ae2d42d493d717b1775af38139e9cf490f7b5030ca36c3b6485ecb2b9a507f491e455b7ae6 +7502c755bbd385079a4001b8cd653287dc3054f3b57de19d0ff8f63c0308c64c56f035117a8971d43654f89b52e923947e4760ac72be073136da70c5ad7ca1658cc0a2d2a880d3a0c0fe636fdb27b77ff260c4c1ef8a18da8e9fd777d732a37ae9906e6c4f381f0a3d941048d5a1f6f2cb8593873fa4bb1621a44bc2bebfbcd1 00dd226de602af4e9f8e25784bd1bbd4cadb0a8aef525d5e2d57b9f3555feb698765672c5099a7d6dd5faaded69d8d68b4804f26 86b4c05a0cf2994d7b251bb1ebcd0dda473edd2a451ebee7d68904d1853954ea3ce5b2a7c164ad41f511379e28e492af0ce549105c42f8cbe9560e08c7ea8b20b605dfa5aab0f40d7035ee3a9cc37e3ee6aa5fcd9a408f0afb4627efc37021e9 +95eca932d03f1df2e8bc90a27b9a1846963437cdafc49116ccf52e71e5a434cdb0aad5eccb2b692ca76e94f43a9f11fa2bdf94fe74af5c40e6bfd067a719523eea6b4e65730365ee498ac84c46e1588b9b954f1c218920cbf71b167fc977ee2a89429590f43bf637eecd91b0ce3be2d66bac5847205f76c06b914a970f543e59 00b6fdbc9c8c76cb2b822a940d8675889ca6f5132429da795462381ce29313a23bc132976fbeb346ed4c691e651028f873ce7971 a49f223536425841f7ea68e0704885f1f2202d8b5f8b5cf931e323638d5a5615fe8049c92a973e72c5193bf4c9f7337715846498a0b207ca3a4036ee2f8a2b642f63b230b40e9ca161ba66510593e3fccf0a21cbb757acdb55192ffbeb707f06 +8ff68cb00d03e730dddb05fe0b2344689529096c3da6eeecaf097f22c7fa340593106b1f6726f06b7ce7358edbcf801ead959438a42f94cdb467b3cd5b17fbbcf75739805f9eadc869c33c604cc58f81591b0b8bf4d42bd53a801f0f829a31af6c129fb4f20f1250f959754eff8c629b85a716b6a18465b6495798c0c5166c8c 00203d77fac64591eb9a18de20a9d5eacaa1c3ec58a5ecdb3008c2d642e197141d16b3a9fdffe61429264f5b420f5e9926659a4c a5ab11b4add934e324e0516d9c3e12eeadae2d086c4618eb705b572722a01de80f67efbad47037652bc6a58a9927518a17ef0f722b287471f0a1939fdb3c3ad1512bd48c0f277494a2361da9f4138f4938cf1395609470ba123dbceaab1cb197 +01451c4f09720cd53377a5ed04c907a735477378ed960235a833049d6bad6e6e89958b4c4249bf0f6d4f043530c9e5426deb0ec3a12b7feb4860757b41bf602ca95655155356ec35a2db8e2657998f56529be4b714364f83a140846308a2973907ed7b08e935173ebbce5e29afe1444cd51c92824ede960056439555e7e74450 0057a2e6a59d4871c3d547690237dd9846d6d5dc4ec0678aafc9c8669af8a641eed67bfea4b05fd6b3b5357ec4d0caf352691ea4 b321277715ed0b66a79411c28b65e17287a72b48f7984507bfc92dc96a41a06ba4da73d63415c7bf363cfa6957e1b5910499913e37f669bb8d37cd3d08d23e73f1569b89f9f364a31661a916e65a20ceedf4952f7f3d6e3b55016ec8fdbc8c08 +ccd494ca005ad706db03a3df6d5c6e876ef859ec77a54de11fe20d104377df1900b6b192126c598944d19a2364b2ae87ad7fd32265d59e1f22be5833f20767793677b628f18e9619f8ca32f3af3b41c31e87a98d1527e5e781bff33c1a8be3a82ea503e76afec5768d7f7dd1f17dc98a9e7f92fd8c96fca0db518bd143d82e6d 000a3da7a6633608fcee9ce4253bbcec08d41ee6b00178ceb017de74e24d48fd89107c9f2db3556063abe3cb011938f4b4871795 a209d36e6240aa1b5706ffc370618e01c02ccc11a24f98e458b57c6bb88b7be5eb6071b71e9d23fd21650da501504911038c531df20a5fec9453f1c9d33db8e7dde37b84f4b6c286b00d8773f1eab2ec6c34f0ba2c903e7f07a6aa79e1e87192 +5719e50d939a8d74efb444eb5a77cda48cbb59e7f976cdb2ea2848bfc558718b39ce27b893c229db94bf77992222d1746f8f52f858f85124a28193ae0da039c53d484681785f3367f6516fbb8a86560aea9e3428551facc98cdb1e9df8e2f37db823a7abc589f667b5c93c4c47061400220a2014197d514217fc252cef5a2433 00384723c8b4a316b450d1fce0b2645912b8acaeb3cad50860cca43bdc0206ed5b3b60ebdc29b3eda305d0d60eeaec261edc24d5 ac71a779099d6a16adb70358ed8b62459e9f69132388b01d1944561cfc2931f257947f358ee1a7be82bff60abb536b170b5e1d1b87d73d73de4a880109b596b3d899523ad583df6fa4ffa9e798329e90572eb311ac1bae3fefc9e9290f0c12c1 +c84e5702a339259a61b5ba8ec1957f23ffc4f1eeef3a58f383d3731bbaabfcf49ce2ebb597960ac5115a2af1c62b193d4ab6c24433d5f168a1752e40145f19aeb6dee889a53a4fadd13eef60e28fcc7ed6a9b8b0ca286c1b3d66a4b2c327a629d15c148049e3a0ccdccf05cf22c31956014595e417060627c8125bd7c00f8850 00bd3136647572fef3de51b12e64b36460bd3a27dc660c164fc705417339cab21f9e1f9be0f3da926df459c5ba58b701d306e67a 81ca50db329125b9e5abc73a8a62077ef49478560a32a332285788c7627ce10fa3cfb819ff79eadee05101193c43f67e16109501a2bbc572cb627aa342be6a85de8a868c6abaed94ef0d2c8d4065ba9527018802bebf4ea2febe73f717b05564 +c90bf11d04a708e64b6f94d4cca64b92463eae878c377b188c82c1c5f05a038be20eca2e18034d46f00d9a6fc73c4084981748ee9d2915d87aee4e2321f4f9e11c176f01281913e324700d9cb474b7134fcc408fb4a7006acd9e63d4578ed4c2729d8e0d01b1e6174a43a024ad261eb644ae98979c3cdab75af357f6dbdf5db1 00495be0b0a9d357f6155fac008cec90442200bb842d89292fde38b7256e4117284a60249b3101b3f19f778b680c0d1d7422b84a b22fadf3b4ea93d7e8417876b7df6befdeb7c3f4f4f851c093bbfd46d49aa69985018bd1f9679410c8c648de1da73f0d0693dd56441cce811a6f03f69cbb07397f323605068d7cfee4a75386531a69f0ff5011a15a05c791c05b8ecd1ee41c9f +e9b2a33906a1079280100039787377c2971c378b92e70a38ab41dc23979d6fb0c41e53a21b37632407adac6f212341cf6af8605b4978c85c9c16960e1674247f1795cd73b99ff28cdca024f5078490513c77114c2f52288f5376872c331151d7b2c08f7794f2c1f9e0d849d32d73636f0aa899988ca561a76f74543b37cbf3a3 0079626354dfc4eeeb51fcf232ee9e6b0130c9bd40f15ed45606bb7faeca8f359e0c3e18bf12769254522fd4077eb24bd5454871 ac49546f47141eb70a436750389d24800fa0a7ad740c9609202c6602a8b1d41d98c8fa04de8d901b167483b6a15e593e0d414484f43083e513dbbb09c786176e6a7448aead5424e9cb42f916b1e9ade2332b6b7c954a5c7c1c22a93d6f29f3bc +672db3fb8cc8e5f831be700498d3ab3aef14b7548e8011b21351215fb6dfa09460d18f52c02c8815baf396d856a429bb9afd602a10c213af34db80447f4c06ab4bd28873c88eb9639b199042d4b2cb13cc364f734fd4ab7bebede7dd4da63decc0cc1f84e34d760013f66d71641073f16c08078880b67230f2d6c6bfe17d206b 00ab42bc7d0e3c23f8bcf928e25f9f027b56f270398a1d37bea0ee5426b944a9c9ba6d0d7796899543feedb470f70b2ab148234f b81d30cd3f1ded0b985850317eddcc28e7dd442d421e1c8aedafc211e0a390fd3b24679b015469b5f804c09b12b8382f002af969fd47bac56eb024f7939e854e827444a9bba7b519c7c2bbbd81a3f5da4e97d67ab8912e2b8a4e7f1281cea4d3 +d7fd06b89226cfd66671ce5b4b656228c52d986afa7f6f30161680eb0c9cca177992a8a8c40167a64165c518c55f678702125709361b536bd928567c97737bd750d0e2e6e0c00296a6ca565f7c05cc8c54ae7a4e0c334c6a968fc18a959c18ebbd924457701316a4e999fb11084520dac68dc2d69187134c40891af0355ba89b 007f7aa2216164ba689459ee5d5ca29e70ef75a5b2a4416ab588df1dcb9164330c0b405a9d80c3acc41c19f58e24e17ecbc0fa7b b47d8314b19ff151072985785a7abe0b113398a900c8d616381174e37d73be0ceae1d6e660d2ce6b69f43fa9a71a91e40fa19f75a74d9ad9a4077c169f6f50fd2eb603ba2d920f6cbb41571160f391c12632b136c3b4b8df366d09e68e6cd2f5 +83b7e9d3ec638fef51d2885fff5490c94e2509c126608f82660e5fc523032f3e85d69d9b76af145f6bd916dda35775abbb6d1902bf38880f8b9259822055c5b1bc726c51029972cf7474cf2a812f3251aa71813476bff55598d079f075a40c6c41498bd865ce960c518bef75a873b9d010965f342dc4b35ef5c5972efe6fdd18 0021d84f070c6823a70f1a74225a472118c93ce9dc509aa6064051ca4574939dcfa96be862069424bdf1a23f62f2868326422e64 a9b79357232757c517c0bde3aca5543a562190e27884c4b328f3b0d8c2e58ea6f7804f5f85776de3f5b9c6f4bb835d06186e5fe006e8228cabea04f4054ddcbab1d93607997fb36315278210c69dbda9a75905aa5648a4563150701f21d7adfc +c62c7bcc860f0e175128e1127dacf935ce62ae794cc4a0ce7966bceb023ac0498641d7281fbc86f9ef470bbc77f608f83f8d0dd6299cf08f2cdacc7a9642e4246df131820220e5c05d0dbfceda7f16b86add4793e9b6244d96b5c07cfa23574ceb43e8e8b5483192a92b301aa3b37702b8f94f0129d8af1617896b34990c9b02 00b6645344d17528968c719091b6e2072388881dc10bdb4c7fbf41906cadf3699b30f9c1dbfb4796d009480664e6276c0359e5db b79d895d942917b46877e078c86506c8bea0d3579ef54fc7016e8ef0deb30d5504b42f45a639872d9a553e01afb8c6a4109fbc1603ba83d720a3217252fc283d14541334017e0be2c7ff13ab8b422a70fb817d42ab321cab93e21fa1807cbdb7 +b5bf38fd9e822925254418475a1ce762a94e336f12b156b1625a4574fee11ee472d537ef94b4a4b1c0a73b0140d0b818cd06636653e6c07f0f100118242a7703756f1cb1119b3477c4ced99cf45e07e83b7f2749c1a5f8d8c9272d221fe17f7c6a5fb0f8a16af46f232ce406aaf565c6b2766a2f6528c82e74fa1c0a7fcfd49e 00f8c2f770cf5f8e1f900e996ecdcd84fcff5cd959777fd005d721a419123221a3237e39834b270d37752470deaa6cea023c5058 a25f475625134cbfb0df90f121b6108c49d958da78725a1f36b1fa2f5e3a7391bcedfe46670be01fa6be48595ab6ebef118a6fc903a6879e353c382a27c27082c813a79b2779dce6234e90d3073239fe177d93295667c190cc54aeb3b6423538 +6d3474770933ec01b76be789304b6fda423b12a0ae8c87a5ea8d7ee9f71300f39440e1c7f5aa4b47c1a8628cfc3a490b15ef292a741344f40a8fcdd02cf3863bf3e32d53031f503703deab17fc52b3d4032f4e237dcc27231b85d3fd60b49ed7ee40c3344948d87c3f47564d20a11d50e4e520bd16c8701694fc70901a5da625 00144adae951fe897d5812ee4a16c0be4c86c5e57e615c398f5768a1223a9be20fa82ceccf8a16a31432bbfd17e594a4cd8a6a07 81040dbed9199cd362c6ee88daf76046603cf52e2df83deb1198025783a396773fcd3e21177a034592c9c1172ad84621093083240deb2bcc4f3f1396b0c01605fc808750653143a7bb31cabd1fadef9419df14e087e76071201dd7dee97ef35a +92ba7aaf71f625f7a2e024058dc8739da3567c306da4a812ed9e1542b7d1e982c16082166a59720203f4524c3bd463a662c26a82ec7b4376545206e650eed0d3dd7909dfe3810981393070d15c45dc4a75a8c5bdeba533cad1ec34fd20466a61e4cde3b25af9a80a9a54afdd7de1cf2a74ba32d4ea0082a037775413c61a8d1f 00a51f065fb32c55bf4ff6f18ba9d488d35d9f8da593adb0ab1632533284e0adc43ccdbda9d9507b9862ac63b5ae7b0f78b479bb 9084ec80cb8a2695a836a1e55217bec162d2e9d92ffb079918ca914948bec5b30ec0f7b3c19aa19f339985a53e98d8a10e045d9ddeddaa8cf056a73a4d002294945f093d94c891db1735bcb5a65326d62161ad83d5f8df4d6066250dfeeedd99 +b3fb9e48c333201324755a81f3ae5d4f0e2ae7cd24238fcc66d858e3aeb1ee03328660d6399676eb1b7d8285ba571e214d935bb45516fccfab57b8eb4c3d5f1d7357c768eb7b5e7b5710f599614bd4e92706eaba31f8a5e7e57af7ed13066af50b4540ccdc126b677789920cef8543907f0ba9dc92aae343d3425bd784ef483d 0095351c0bc07acfabe6477fe85f97eab520dc96bdd58b44b036328ceadaa56a1904d2217c5fd25155ff2aaf9005a3e2687fec81 826331d4e14487187020529326f89a1ec2a0e5e56969b95c01fe92f6b69403543c1fe80bb414d275bb45697461fa81eb03b8261361ad9389d9f4272551f35a3c1de899f51522deb2e93e823524e4ce0f69d21c7071ef34901d97bfe40de6e529 +9ec5f7d65082264b8a50be772c44277a73ed19199eb275fe5976f9799d8629fcb4a59a8d55074cd2eb2a0e02062d3f7cdeb05e62931a24fd1aaf14c257944d1b42eebd52726d6fe281211b39038e52baae077ea4df89675d860d6ba5a0f998d049614201b872e134367acc90066ac602e478ac3e43c3ddf4b0ca0aac1a68591a 0050245c1682344fef23bd549ac8d1e8e44b2840c43eec1cecd33daa4e9ef6b53f496104d7432e14248682cfd6f5b4853b65adac a917dabb876488315744c33c59d8e8c5d920de56a23128d2e22a44d8a70833d453d5b7384eb48ba62342adf714ed149b0cf19eaed42d2cc53a9435d10069df3b03cef97095a9b889bc16a8fe32fb73009f6a14faf87f4373fba7e487ec5a288d +61d657bf472676301503f6784b7286fb39fb4186bb88abf1edacb4a2693d0a1e2b77bbf2758c84f2cbfd1753e20841b1cd4b456400d53f4d686e666943f9b6ffcdb77f510be97536e9698fc84ae347d483bc8984548d1cf86b9b40d360f9c0dc5bd1c55868e26fce1460ba94ef5e94eb63c9f0776a0f446c0cfd4106d9f36352 008d3b0277f0e9fe54581d3a9499ccd7f015c08339591326859af969d2a26284e3b3beac4a0b74d324ce5cb5f38c7995e4e3a41f 8fa9670ea6e63c7fb3afe9d9582bc24fd196ac4c2ba088b2ddb47f8da66013aa6f70183cd4f0d779892a1811fc1ed4a8184ca9b7ade0f597d1ed8123db4212087415c48910866fc7b5a3c3e3fdf508a77f2a8c75303b89b95b92eb1ac813ad57 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B409_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B409_blst new file mode 100644 index 000000000000..608f70b5e533 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B409_blst @@ -0,0 +1,60 @@ +f2380acb0d869d1cf2e25a6bd46ebe49d1c9270624c5507be4299fe773749596d07d10f7c2be1c0b27e86f27b4a6f8dff68cfe5c0b4c58dad1b4ebec7bd00ab195fdd635d9fa8a15acf81816868d737b8922379648ed70022b98c388ede5355e4d50e6bc9ec57737d8843fabda78054e92777c4b90466a5af35dd79e5d7a81ce 00beb0df3b0e05a4b5cf67abef2b1827f5f3ada4a0e6c3f23d698f15a3176cb40e85bf741c9fbc78c9e207fa7302657527fd92fb b678397221aea67d76d3863c825d4884c7285af55963ac7e4313696590d7bfeaddcb899cbacc8e244719cdb9b6ac30670ce5da5246ea67dfb5825330836761c3b63ea12f17220658dea6dd8644bc5cb49063da1f26d77b3e213195bb2f987670 +22a97fc0a9694dabc6f274ab52eb592dbbe8beeb646ebe6cef60eff341a13017eef980aba6d24ab3afd976e2f6a84cf652654d4a54a36b2f2f62fab8858f8b0479a48fe9f47f8fd5a4a1f3141a91cbca186507b2bbfef5e4c4d2df525f04ef7c4720fb443ccad540f03a2be468d88c9545d1dad579fd7cbcd103bbebc9e9f961 00504865a30984a9b273d1bc289d734d10e0aa56e93ab14720f1a42a27d8cc932cb8804b963175de6fe57d8eafa8ab7ea0592dfa a9dcf1939c3056c220198c8d207f0f3e6ddd66f9f3c608da52af27f74b9702f875fa3c6c45dd303686fedda7c923126c18895fe681fab296c9142c83209269caef5b1a3635ed3e5f96de7c0c5752df44544467534383a4085df78d888488888b +af36c04af0e3fd64bf52dedf52fb788d2d1bd67fe05d98880cc7ad3c20436abf02f637fcec209fbf888903fdec8682717299f8a4386768153b7faeb6581db57fb9aaf4615b4ea8d924198fdd158363a1f40312527d6bd14c13d19985b668c6b88a7548104b1ff057d07082eea421f50062a315bc3866378f2d2d634f03fbc0cf 00cc08a4ea5ebe32027885a8c212870e7c45b6c610117994d6a42a284c05199414a3a0e8e6645ac5c2ebf21c505a601f69c62b85 b42e36ac78bbe8afee8d1f99f0607f04a7b83419f32ce5a3e2f7802a5b98eed5986a0353edc0d78f07d18f4131456e0b01939d19a431542c2261a012c74d385a26bd60a433613d83e3cfe0b30e3afca674a1e478b9e8b06b9a646e6ccbed58a4 +6bd6f52a6204b60f37929aeff28c87ef61ddeecc231e52a7772275f9329add899c130956f8c50ac2698aad3654fdb49b74a6427a62a11eca0a8ee8b719b8c0df7b9f0bb0af5fef4918a8c83367d29fddd04b6a1ecad904471e5b59c8fe3cdb06b4f8f96419518dda960845d83c49a49f1b1f2fd1d2682a9d60c25fe3ce982cf7 007156ef0a74ee1119532a2a7e8c02be1559c3c21897af9d5b34553c3d0feca4a8d5929d1945df824478e0c0b92a6fac8c84f639 b3732e529846a177fdc9452888510466a958592f6e8b6efdf79c641f3e9402a65ea508722cfb09edcb57f765ee143f3e194a8dd0d6e7e4d85fe2fffc9fcf19028c537609072ae129ed44635a3dd3ed40c345ad538057d8fadebacb99ade15f0b +0eb8de25f63abc9cba16823270e9b6f3fdedf0fb90f6652a34688970932e3ae98f6d3bf0fefc5f247f72960a6975bff1f1acc2188a1775fe8974b2bb2b4c8d226ceb735113a14009e8ce66d58808fada4e6f697fd016829913352c0f659b6be354a067df00cf74919580750aa6064f21264d89dcb28b3b2d4d699115c36d1310 00a95c7abffa92e2c637611ccba66ff9d2ab121b40a85c5b71454cb0dca1f098ce1be8d9ea4933d1a91bcd270c5a33687835d6e4 90baccc16f4448022a0cb52f13f467d3cebd7adbfb2f54dec719ec5d2b89c646e46b57eaa238c62da38dcddeb6c23bfc18aa10e57c70a3e0954d46df8989f42a1ea431a975276a1387394fb071279b6e0afb66c7cd27e9d2657c69683f834141 +cad58ca7a3b9967dc0ab62a43037764f8074ef9177d60bd98f623d693333971c24a575ed03cb61f4dc2e3d6285fb1204502a540f3c0bbbf23f5bbbd1544f322ce35d949d8b1d8edeb82e90927ac67ad49c91007056bf5096bd690d15ac00e1874fe33293d8003a4a2b094078cf09af799dde384143350c54a99e1f99cc31f2d1 002c438b07c6e0685d1f94a4bbafc013f8f21265d893f54e54c3ac2071606ad1ffacace0b8367aad724b1d9508c65ce52282e397 89b3db631baa65b61d002196fe8736445b123ce1005b7849447b6e89dea3f93c2b81d0e1f6d2d6afad59a5f19c8bdf6511c0908c68c8d54876a786ab058c32789fd7f64b05574a8a5646573018830b5ef36370a1cdcb09dff3c878d7782466cf +281ce2643799bbfacc7d5993683a4fa656040517854f3c2dc7c4f8848dc305382e34e894d433caf12d8b493020a6a08d1fa05b08bf6c53127ad5f33bbe75b9db0615e3dd94408d028dcf3cb7598f6e7cb4c787681dabac7cba2cc06fccb7506fece6c7c1c1bf622d525ae9737085ab4ac578905950002024f30159cf0d99f50c 009e8658f8f9e6cd98c0f4f0fd20d64d725653aeba339504def17f3ad12a63dc6157d80804e5f43f4ff48fc5573fde2c615ed31b 8d723a3bf9c122580657181fdd2d021fbe8e4f2ada4d3b8336aebd950ac92f98c96f19254d2abc66db55a86e92c3e41f0b933f79dc79f4f111854c94bf006b14b831bfb173e13a33f510782fee01f36a63e58121c8cd78c2c7a085ea345a7e28 +0c061da1a16f2be130ae3b20b89745e840bee09633fb49671db28ec9a051545f57ee07e2410ae7ebc61c9af79868d3047705bfc64ac0c04ef0b286e579b650c7165443631e49e6a53c84cefa5625b1e1035a6ed89b8e839540040151132a937666524265e099272c1849f806db0fdf2be64960d5b5853965099459968e5beb32 00c4c13f65eacce85a51881caa6f82d9e48ec2ac574947d2751823a7f072d38bd9da0cdf30b6f19084a6d291052e7bbc2e1349e1 b5c679ad9d8a44b4d127d3475a6cc4c672a9c28060e8230313914ef0682b83fb0efc269346fd1dccd5131ff1f0067cc61873b668e29c0049bc94b70bc3941592bf84aa536a666206d0da96202142f1f0539b652c1bd82e98eb6ae147c387a6c6 +74ac2e1303297efc3ed8e624722df505df55b7f33964cc0d270604cc48b58205d8a11952232a8feb0079baa30d7d33660268b56a5a3dd90105f0703abef8f6636a99bc63bd47d9df100351bee32d8205dab0dbd2af36fd173409ff8d1fb7b24570f3c1e968458f58aea5aa2f46731ee91ffd6d3a060af6b3d5020daf1362af3e 00da591461791ae7847e6d8dd8df46a63d3021644abe9520e158406c96540d8fd82ecfb1c3f6f5cfd7688c7656cc3e3dc94e586e 8ec13543d614afd5df421576cf61cbd560351331dc8d4b0e4f62c9f244fde3070e113e457bfa1d4bc00637b71a54577b19212e8ff16ab5d58d89730094741d6705d3e8e4c3cdbe39e7f18d97dfd84e52db5efaec6254850b79313a1cb39247e3 +2afd17344552ccc577b0118caeb7dd56a0766e25f84df17c0505f9798931374b48df89a48c64e199108c36e00c0bf00a97ccde55787bb97c6765601765ab5417f3e75e35a9fe5e0f85a721d9f08440ed617afcdc200b318940a1e496040a6ad9090476b0fb4fcceee77b3fea11de09e7fb14853d1fff8ab12d66c101257e2d4f 00b5eb943f0dd390b737510e2bb703a67f2dd89dc9f6dca6790bc7a260cb2d0fb8e1a81ad6009ed51010e7686d5b48233c6c1686 a8edfe982c5b05048296379997b020f989699705bac807cd967a31eeed3e7d6b5d0103649ac5f87d53b6b078da553aff09ec10357501f592c9b5b7cda9f0162d2ed77809649bf361b76deca2a29b446a898c0de5e1cceace73bd3800ac86022f +174b2b083541f8284645a810801e72631a11bd7bb805f684a7159e055afc44357f2c80df2b7853678d34a04144e0ede2327d03db6df23769ec41194a8d9d86af74d51c5bc11ea878c6a80689af71d3fdaf1c651003385332a512e03dd040c33d9c328ca89ec7ee9026bbacf30a7f3a68e0d894fb9f7100ffbc64bf17679dedd1 009cc63f32152284fca27ab2837bf1343144336a1fdf15b9727c47e877ac69ac9cf4c97b4bf42f1ab10d73de8597a554ed099efa a96e9721d338a2fa0d1b74e81960f470d27feb1a61c52d5d66519fb83691ba1c77637dfb97e3925aaa2f8cf118a4004d141e4b35accaeb651648062daacb54fed55e76c0b492d2c9118888489be5dc828deed53a10437eb24e39cf7c8ce0c027 +758df71a952cdcffdc417b9fffdfb57582ab5c5473a8bdf0c2101953b023b77824263353dea0e2ede1f800a5757ec6ac0e1e4e3ab5a4cd85567d2d19acc6b7069a6e7368401cba2b6e642373654bec0ddd19fbf032794c15b7ef7e714e13e36875262c01e77766ed53cbcf735936dc9b33eaf2152a396349c82ca0297dbae4a5 009950355e8667bea8bbe3a2c4988436ab5394551b375e27fdc0c1a1d1b07ae957932f428f1aca0a486e54cd0b5bb0a5c5650641 954f8f5190bf42662e99614454de523a3a50bf65e23238e7546e20a4515358e721a6a618d8a5bb8b58eb9da6f5e651bc1355d42d64ea527e770b16a7f352a70b57a3be68102b4468072834892a3e725523455b4858720d2835abdfed8ac7dcf1 +b96d9f66b2000e9408d602096f032b112f0e05ea874229ab9daf6e05bee49b4722e4f2d8bf2eeaab9dad94438c76b7cc64dcbb59cb4e03f9ac70487a1d24d8d6b72d7462fe738a17edf381d52179b3acc0c0177c113eb4d10e8e78041deac1d56abda0ddf892edb8be956d285e7236bc6794168f8a180f622dd5f2b9e690c275 00a995493d6971c2d7e8fac3da9f8c0b5afd877cfb94924cfecc167f9d87002136ab253e3a4f9ddf5c9c99bb1dc1af0c6a3a3c4c a0e529317a787f86eeafe36a8f15973819e38c942a9d5e33c05ac8d756dec478ce4acf2b38387f9353bdf6ce628346f911288af52a52a7906475e73743c482aa7408cb820260a55a9f651e65cc41c6b5f1eadbdd4e8be9e5e6b9d866234e6a2d +e7ae60ac55e6ba62a75d5328bbc15269d4638764169de0bf0df043d15f9152bed909b1fb8c7a8d8e88ac4f552c1092b62db00958a3a827f64896f6de4bbd8fa5258d6c36e3904d82d3eacf6eedba50b0242eb6b01212288448c3a9821c4fa493869c01149ff1850e8115cf9de1618cb8744626b1951d1de305745507c8b21045 0070daf435cdc26ad66c3186267ad12d10f28d32d863f950cbfcf042fe9dfce553750ad098f82f7f1650c1126b3e4451bee6e11f b875d7ec8ec7c75876464ae82837bc0d19902c2e26f2dbec6b5a85551984341a94c91696c46960cae79b98470968a438030fefcf9d5e0e14cf85a710b71c2cc0ce8bd0e657f4f83ab7c7504249f1ca8c0f4f25bd6d035cc1b3740bbf59aa0d00 +666b0dc2ddffaa7ffd57ea3b2768f02d4b77c16fa007c6d1918400d195f068cae2dcaa69817e6e4c70d5b29c5598efe2d957bd12d0fafdcf5ac52dee80a2d46e77fc18cce2a49bfd787ff77b942c753974d22434742bdb494590d17c42af725b1309e54566276af3bcfbf5e174d3cf191b85903faafa1583282c97e66c5da6c4 00f8121980dfbe9ad0bf92383c7cab95fb72d5caba96e1de7772c6a179e85414802fbb86d725401451329287305570ec7fdd873a a7d29e1da336e6f226985616f5294867d4848f5a40c3dc28fa3b7e47dc2e0cc5f416d1ea4463b6991316b324bedca956141dc50d8797234f81c7ce78bc62dc419a57050811e4716892ef415a61f32be00e1808d8221547fc2c76675400640f4d +3e967cbc2bd936e0b6125dc5cf885735bdcd2d95b2f764de6931c4578ac8e0e87abdf96375481df67dbe1b6c43537e84ec62bfca6672cc5f3ea4125abd4a4119edffe04e42411d338e8b10abb1f1f818c50a9631a3f89feb5be5367bdcb0a8a82c96a427ba6ce99f9631d4411a2b7f5b14d32cb3901dc9d285e4cf5508940942 0047682b2e3bcb5800a531858e8137692a9b1ee98ea74e929ce4c919c26ae3b3f1d4122d07fd9a70d8315fab727ccb67004187a3 a965b6a9833faaaa447116607b55d3049c23e28956f600200da3ab1d006b8e6e7cdc2cd49d33ae6eb72d6e31d380c2ca0853a3ba9e8c02016b6a1aab7805dcaf4705d7dd94e7fbd2e282c4e95347a64f351e12dc91df31c765f4c93c3235047e +ca1c90012eba4e7c5f01d8cb3814c58f48c03a16be6ed86934014365eee547070b870d1d26a872cfd28b60d9ee0a66dea223e9eaa90ee28076188d6091f26f665684f4b486af70669555db9058d485c677b2a34d4a98aa8d6f43bf6f44aff2a23c5d765e98f0438ab81be0585a5be29daece5d4116f44ce6062753a3ddc505f3 0040cd1a06233ac27f3ddd108de7c6c0982793ee620d71982697713be9fd5143658929924cc88747a680779bb00da8a44e1e7d3f 926cd115bd9621d7a2af8815fe63bd9e6a4965a5e3e8d5148aa61229aa0b6c621f843c1b702d41c37518d5756ecd328216efa8dec43b63b1c0c294367ef841a743de20a26b9e43978f2b8645921d47c8b88ec2e904251dedd211ad81b2fd238c +a54c4351ebdb075d6a42a787647390f864b2bbfd8bb3d0e0ea9d767200fa344d1a9ff091bddb186acd69bcaecd767068efe4d752d185bfe63f6674279d0e7192d2077c400bbc0d5599ee28507c1253f05eae0687b965a015e1f3a292b4650106765266f5c95b77ad2d82a6a6e012f233169eb6b8d83576901cfd4a927c54d7f4 001ca6f752aae4eb7fc9c73a08d6fbd96bfde5030d759a2507bd45b6e1d1487e53abbe98fad4f41976364e0a1d830910ccf97abc b5182729c9a69ed07d3585aacac3f3d4798f418edc573890a68d876546dbb66d111fbf01265901e504c44e23fa19c07f0eaf14f48dd6eae797dc7879a307f5d36e41cff5c77a9b1e31ed3c8001d3282cf8c93ce36bd3b70cfcf80f77ba7e4686 +6723dbddc8720feeb75e2a061b7fc49079f999fbc79ec8a8e01ab8d35b438b7049da5a23c49a58101742791f84f45d5f5cf551cd7de6926a0e2c4ffa1e378f038da597368c62df8cd8349bf046de46d02183dc05b3a3575f5f232dd2970057200e2c9cb60eaa6b4d72f8b73d4d40b98d1cc801d1a69cb5ed780a75a4064623b2 00fb9b1a9597d216028902abf743d25944258b48c9762d4589fe660396130b75f6006cacfde60f6204463cb8c18b032de1dd68d2 ac746b017a1f3267d146e394af18410dc284a8e0141a33c8c0f5db6df804ed4ccae5507ae446d4334cbadc4b2a43e9cc1446a37ee715592990e73e6a2fc0424774234981f17f5c0a9fff20e9bada7e5b9e41f85ab187ceaa8257b5b6937c8025 +ed53cec5e5500d62d38c829002916c657674ede4439c6f405ba672327ec677490e656bdd698f114c2ab5e6a1fc94a1a8d64466cfe9eaabd23a8b5c37f76a3c0decdef73b3e7b751cbf3b0817f4079560b5ea34cead88ba374201236bffc48eaf289bbaa4e828afa7d732473c228ad00588c9b443d65b998f21c3d7a9e9196c08 0032109202d754da290c266f74f47805a06e6b5c3f721a72fc97a3bffeb8887e0c642d49a6bd034847d0a5ba09239c5dfdf0772d b52c0850e51d10264aae3339755cc6fd06d4b80155bed6903bf887f5ac29ed0b388ef1af5530db3bda7bc8bf968fab9410597865fdf2158168afe17aaf1c972ca87d938f79e405ce72dd6f2aa3649e3c80fe0a7b4359fbaeb200982a073c5617 +13829401bd41e9fe01329e9f5a002f90f1a6ecbf25fc63e7c1345f265ff02e496230f706c6ab377ea52d8707b54f8fc5c7f089044e2bec1dfc66a07da76ee12fb9ea0697d87706b0ebf677600bd2fe117f6cdefb8bd636a1b6b97549ee78f992c24acdf3a946053f06fd012a9c703efb8bd929a66aa74b05d61bff0395232b00 0080536e820fac59b3203aea928475043b2576446619001647e35693a9e65d15236c3cbc12e1bbe0eb305973535c882b70197a92 92d987627b82e02c0a2c6599c79f40f5fc35e2635e3c98284b6566021fa533989c9c41080dc971421ef105343965d6db14d57ab30802c7b928f588a904863cc4e724ffbbb939e61b420b10deb620e3fa1d91dfa046595ed9557bc68498a62a1e +e696acdfcc96a6c088069b7595ea9516a36d8fe04dedeb789fbd965db0cc64b7017a821015f6210b6989e515def5a9605fec0d337e4ac59f3101a505168bf72ab6d98ec62a71d2f94071fc05b95e98d4efc59fedc138e3e49c5d0b44d1f48f7b1e7c1944ee189b242950d2bc804d31c7eeb45283c84638f043ab9533976433a4 00b05e5f0dad9583ea18fb8fc4d8c75fd2e3cf9e92cdd9b737485c953620d345006c31c288b380258b6500b84f729ce6730e5303 8e38383afb2cb74ffff2c0b58fd36c2a32e18d80b42054e9602407523c52e56166f01ab103c481b79ac4e3d86aa220f9144ace286a044eb1709d0bc5428e750048e595dafc801d7aced2cfbf1b33d49674186f6af0b59643a7d8898f1625c52f +4058b9a8cc15ac148909eb97fa32aafbb6077b168dde91a411dbc973df7db056dc57ff78f0abcb70f70f800bd752197d681f44df4a7817c0e7f60f8f65489ecb6167c14b525e91fd2cc5d8b80ba380a83d031d5827c8b1262c687c90ef0e62723d9b565557f9f6fed0db48f3799274c2cd60a14303406c35802cba6261121296 00be1d277813e79051ca1611c783d66003ef759b9e104f32298017fb97667b94dcee1ce807dc6b4d62416e65d4120523bf6a4edc 89a7532bbe3c87d5c37aa105cdcbc938776c1bdc8d0035049d7377a67f0f0de45511396d6b095a11e6487d015208ebc4132da6db9d298b73e5303cb7d4c90abc2385eacb900ea2e85c87a5af51f9d34b9c5be4769429a8363ffba44ffe7b5790 +e793237d46e265ab84ba9929b196405faa3b0e4686e8693567e53f68e6991e57677974677682a2510c4c35b1968a90b32c4941af7813775c061c008a60f9f671cf7419c94253d6106b61e65034497f2d273a5058379bd986e3d917f708f0a2bebdba150f6d78a3af9c722a2430ab0f4bad602e91e18aaf258e3785fee78e4502 0073c807bd7e07379782ab790720de4ae5106f16d34e80ed70da5b1594e660c9b775db94066b93e74f855f57d88b6ecc6228aace 8e6e73aff28d3262cef6cdf48ace6133efbaf659d576b9a962a7acb20c58bb88346b90850f9f2c0f6e3017c8760f4c0e113bc94d15ca390fae727a1b9a299352fe06ed9f632c729430ef525370a25570d3563afb8baac6c2259ac98fe10a96c9 +ffb8bc80e7619a562d8506eba7658bef0c25ace3dc1d01bdc2ef00933d4fa07b80364e5e5826074edd46a707dbc3b0ab19eec7ea8990839d7fc0a80b70661204c52bcbef57c1a7bdc861c10766033a82dafbead283d911a9502d5f9ef0a39d35ef26f3616212d4bafcd413ffd18b424fe09b48ba02ca5d97ec996205cd49d22e 00a68379b2296a6c944ad5dacb593b302d8ef0b05873ce12bbc371d705f308c739d21f343349524aa72f05341e64f7435daef112 b8b8ad91ed7e0cf7a27ea5d968597ce4eddc39ab79b2a97b36f31126558c1df33929369f13c4797c56f8704a0bf0e4a9122741a6de7459106b2a82c706da1723961e8f84626dc9afdf156cf599d348c253651f80b34330073f27f9d3fc37bbc5 +946bde90a5b903dd281a51d7fa93d80f3fed07eaf50c18fe9fac5acf67326bb18effa3144e25c151efc006a50a274ec6c6a5d573051c4e2d117ceb0fa125acad07a10fb6534a8e5f5b3da2a1136779c51377bf76c3a4a93c0c6158f729f2293e414fcb952c9509f228c804f0adc1daa327a8991d48ccf4f3957c5f8ccbe3ad4a 0026046bbb269ddb1ec14ade56175482343a21b7c265026cef3c7d6a1ae0f6a68166b9e6c49a6e733ad2ad64df7137ef230038fb a4798386c6b886fa4f8e7209f36991424d0f307ea3d16a4df45835ea9e8e089e2efb5edfbaa9173a6c290532fcb9ac0313cc16a0e55c1bcde5ceea0777abcc98e13200c1374dd428a047ae9592cae7d1fdbe47bc2d864591205ea7c46785aa5c +07f3fe1369ebfcbcacd66675bd4ab22edbbff72e68709cb57d4f590e49440f01691f490c58b5117bd24aa2fe2101b59c61c417c918ea08ea34bbb9b8aa17491ae5d9329affe894f42d7586017877fae3ce35bb80c97f92a004380374ec91e151995166e14ac00505fd1fa810cf02981bacbcebf5f81b2e633d3a3db6737890f4 00bbcda66978ea526f7bd867c3303b625f11b94dd9ee6e2c2f8688ff07f2bba83c662949d47ad47fa882cb7d203a7f0ef5dbc52a ab24f89d1bbc78881c158cbf84cd86b57e783329b39537eb84a37d2b3d05078f8ace5f32e1e7b8cbeeb0fdc8b803c49e1840c2ec29044a8dfde3fdefafea84cc59bdf37895200692e2c51da2ab5770e5ec2ba8cf037321259d8726da42619e9b +3a1cb13438e3bac9ad4ab1d319e90e2c9f118dcf1eb54d6333c674a665d41451f93cd4a9334cd057a44c010edb668254517a63700a31eb0ca474c84873e486f2f8e158a1a7735362ea0cff8ef17d959ffd851b21a91412709b3c729474d2cb40f6ca0e397030eb2611b402916e4b656f0fd868247d80be3ce33d52054b7661f0 009be3dd3442e0330750f0a6252bf9cb317f32f942ae516a4038dea2c40ca6484fb33611bef016cc64baf166c122e87c15466fd8 ac00be7daecd48ee5e087614d7efd9538caed9654d2bad06d36477e9dcdb42b8ac3e32be3df53a4aa311ca8828c45eed063388ba02297ca30a513afc4ff31b04b67a317a6e7b2b7a649df4d034f0f5ce0aa5643080741bea4f4dd3c412cd2eeb +e58e7b881a563d54772125b2863718690a5276c93d9e1c5feabbdb5d6f7c7293ff0f89805b53663bb417fdd46874b8e6a466e7e3ff6737930a0662af1d5879b071b0dc4d014778dff26a2eca5992e763bf4c4698c382ac947215aa116515876008a56e5bf547857049c38a2d3737ed3393705fd346897c3beb80caab88e5b8cf 00ed321fa283c662e87eaab99b7715e6cdc9b42e14fa5bbe2c56fdfb381369191a42da7e574839f90a85577485f19446fccaf6cd ae5908a119bbf276c3d99d4d95fe4b988de7cf692480db3a287fa12cbefa77a51a9f6d21e9dd53b7c29926d2237e31a61112dddc6f6fecd27a861cab40e4f461138fffbad2948ec8e063e25c92ab5a924cded11798f49874ad53110bd11392c0 +8889ea1da1cbed98963941f6ac24f47253ff6af52de920765214f2024aeb04f7ad46936830a8eb04d95aba64ed7cda6ef242f454b67bc2de38a46b6524bd5c96739c4b580e89829a61a8249ec8dc27a50f43b8554cfb6f4fa4ca6875983d4b60a1c6b49f32ddff6fac0cafb64d55c6f594b195c207a9bd920dcf20e0080920bf 00396b805073f3c3b552b1024dcf35559ac44f255b688871a3c6657f727a4b09f3806cbb75d26a00ae1728be632387e804775a8c 86fec99023313cafbae5d5aaa920f387b19337f57a45efb3eecec321fbd4d6f90c2b6fa81ec50e695e9b84efb4b0db3b18fecc4ba895466b39bea647c443070b14c8bfdb7ab05e8f44df6240dfb10f3107e1f356793517e868fc2d9ea2b87a45 +55053af9370901e38622734a5bc5589f6a20e258627f381fb0c366f3dbe58394e5997e978eb7ebbc530f6e6186f48294149b8594fb551c31c50521a8c4d67e5862921695604afb23977b6a69b21abe75966fdd11bfbdb6b51ab0a474c5fa07c4de7872a3bd81acc417655090558dfcd5af449b3347e61fa9e839bb9457de64c1 00a8fe323f6736bcabe971c7d964e75dece70cb54561da48a11c40027ebddb23e41c7b48600f569500fe8ea2abebdf480171dde4 938516fbf51ec9a1f9d840f7537af1c552fdd33f4e98802ea22d511472ceed261423115f1dafc0510249676a085f9911050843422eddebd87a78b1d710a3e2550514351992021d4c3d9b2b4fd0ddea01988d52a8a5221c5617e2a554002935a0 +c4264330534a6c2bbd8a3b757e0912558302ce302f835ad8c5474993832fd30036fdef40b10ee37293e871db5b0b149654f9e543e22111f9709ef45732125f713c031ccfbc9a2f3aba160c241d27be4dab87ab2fa9a795752ab2daf20f9d06a98d90d01c07133adfe83cb11d5176525e1bba6a9ba70ea48b224d46ddd8103f65 00105938ba9f25034da3e032dee121bdb192ac2128b50a2ed4bca042e96cfaf4660c9d35f3e67bafd4c99f9447e6dc408e0c4471 a54d142b6da6fed253c975696239b20b9ca27627654930db63704214e22e33b07d4f7d92a76aeecab3ecfe2ea301e4c10fbdd8045fd93d3e4516ff10c285b1e5f1a6c38cb722f819baf750c7e0d8fbf5dd1b63c0a3b0bf26f79426bfa4010ad2 +3236f1ad164e1b25d828f5202e3513c80c72a577aa9af56f041fd96cf5a3363f4b827723b1511a2f16360e32eac90ac55f4ee1146791420ef9e2af333c17d157b00e43992ef6f2be2d2f211361e468413dd93fb69232f0a0d110bc5fff361c0410344aa0636bf809062c73a7ac7c142063912b6ad7e1626fd2a384f35faffaad 00ce11677ca818537dbaeb880fc967dc8bead203a2538a55e756679c4a9e7975b9b3e6aba4e6c6eab4152d0c0939027e9b0bd92a 946a5f63fc541836d014865518d379482f06f65fae7685a803c55adbae8b4b12cc8a529675b7749f493db0c455af152802a7100456dac7c08e2288399f1abdbba9e714ff8be1b0f90abd3577c47c729f85bebd8781fc4719ea1de879e1ac4bff +6c400ed098d8369dab6fde3553afbbd4d47836d0d12dd16015f15cb8d067a39391c85ca4e78c62b8b72c1592349ff8dc52db8ccb7fd80c085fae456dba6f4a2378e184dd59238c92cf04e40d43a66b342d2a1325a0bab12b1ac857f0564c27b35e6abed02ff5bbbdc3770ddbb2ee0513df48bcba925da6d61583076cd3129603 005a239ae0f40d76d8d3589f1662b5ca12176a4b2784faa8339b54e96a1e1294433a4d83bf904196f939bd8b33bdb4be340ec703 8b25089f297a547361940df18d411db01d0780c7283e0519435ba621a18d67c4f8bbc91f869102f335adacee09b7c39f04d558a976a025577447485d2b56484eb03366beeea8377fcb9c60b3dded4a20a043ddfacbc278e7b3ea753e9b3baa77 +039a149eaef2de30b0ae457b376ce6fbf88afd4cfdec02d3c5e00400d3b0484c1cd6ba74db5de65d6f2fe39871349b30fdf1ef29bcbb9e182eb3ec5629d07d98354a5dfa82d7f0db3dd10d1510c0dce086848a198893ca5ad24a663494f0596b4eee86199ea85e7e8f2f76e7a6bd4a052c54287f61b391f1e52f96b606151c34 00077390c62ac41aca995640fde0c79c76f4ea8a8dbb22323ed812bee837ab8798c5d0ba976c7aa634d4b1c2c155de2709e7352c b7aefaf5b5c4b14fd6d0df36a3839b097b1ae7de9025f000c6509177f745b74aff25137db158c0e03a79fe5acd52be38074f330d5b60906332544540f83eff74848e89d14063848632b30b07d07c2d3f5f41982da9a708bbf2a8052e4914322a +08617d04fffd6644c40f7dd57919f7dcf3c888f4147535d12ca658302305bb8e220bb17ccdc480254004b9035b357120580882ef86aa5a061b2850100285b7d61588a664dd4f5394f5478e68a80f610c9204d056009c1c9e902161eda33ef61aa902e96b6f094a9f053135692182943d38b9763055a38739a2a2d133c5dbee89 008bf23b09fbbed1b55769907aafb97f4759cec98649b2c9da5157517d4f85bb70157076b5e4aaa7a940af042302f8be06a84ab6 a6ce13ba93dc19d5b8f5f246aa4241b09c35158b2f51c4f41d4b287d55c42afc4eb476c381712253af1b46734124649512b993341d18cb4e159bb2b64301e201dda89ee5c9cfd3cfb56186886de7b8abb5c1d6f48abecd05337ec5f46f0a363d +34c959f549a307f21b850ae105f41299b8bc94fc292aefc61aefbe0a1bf57576ba8d9b80caac635e4edeb22530163fa9629665fcd43959f68eee32482f1845a78ed7278e6e43d09ed6fedf465001afc0d61f1d2e1d747623e82a762576b879c7024e34f43104593cdd691d53bccaeb8f212dc29bec6bc94cf69d0a8491db124a 00082ad05d19b8e16f80e53a4cccf6869ab5128c5e622ed146fa8555985ccd2aa3b9957dd374586115d4d75b1c01cf98ecfc3646 896ce1bc5ffeffd2def8743f5f0d4cfd0144c3dea46c9c4d3a4f14d0f73ecb49bed7920a67608b7fa5d8fcefed8ceb3d0f3e87cccae5d4d700c7a95d4ddf745f04f5c5e8ed14555a506a7744bf97b238eed0dd3b66454f1336a2f4225da4fce2 +514f4de08a6f49edbb6797c9dad6d33bfa367cc1a1b58a5becfe646c7f3352d5c5d95f7456e7112c4ddc746b9076b9756ae3916c07bbe6d3823895774a42d25d44b3309d18bfe7e3ccb1f85dacfec1654778c19e2981a853c1f40a7eafd16d331093110698c957fe9f1d86582706a6885543248b944bb70cdf9d2ea89190cb02 00af7e581aa4f9be5815f0c447e39de00da9194eee5e5f609668b9b69930b5b48a948614c2250260d1917f0ebcb00ebda4bb52f8 9887ae7cb85a1732d780b9112ae13b2329f66537de35205acd9e42591581f024a455bf87490213e815a494fc4b333ca20f659aa56d5fe345d017d436a0ea1217bad8d59dd7d57e0d18200b061470a5c2b57d288a22d48346158e657829211bdd +4e5d16cb1dcaa1abab1e371e1de02f31ef4e0944dfe1fdec45ab64326435b2af9aaf1a6ed8fdf1a6ab1182bb53a844c7cfd66da30aec0d41757f5988ada0017c4ca752597a9fd3637668bc1a92bb1556553f28d66805bb47f1ef91908ce098d452872da9800e77e1fbd43ffb0ed6fe6a62185d4be73ae96c9241b82cefb2da22 006d14107b08354e6a41d7d7d50c004419db8bdc50db43428df5e86084551237223c498bce71a17e25695bc438c5c09e009c60e2 845ac141f1121113b392211da60702da943cf1feea911c80c8ad2c23559ef736fae386cb056b45183e8f4a248c6d0a691547a47883a83413b03d1050922a4228efe871437fa352af7120ffca987fd8422ceed2638ed15eb48f7d23f592710f86 +e29e75269754ec1194270f5c9e8267dfdd8c696008b5ebc92bb840981fd065672f07f6a0f1b19841adfc51b478371e1a0db9c3346a9f0a4ccbdecb7040191a00ddfd0a8faa0e69fcf544319c0155d02797eeef99fabbc55078f9d852927c23fd931685424249b87ed0c70a4a3e2d3b9a2f92830e7d8f7650c0bffa8f8986b7d5 0099d96d2dc9c79549f031bd5346cf6a8544c312a3fbfc560dc8e378efdfe025b0e6e61e09c04c8bf4133396f993b0906c33dd30 ab9862149843687d5f2619df65615b3e0f01dad3894032c0c779a0d3e386a54326bae023699c10a45df48d1bff2610b6016d4d5b8d688d92d629755cab79b63072d20a256bcc5a146f443486a9136d55d685508a306834fd37e4ffe57264e808 +1a538eb447c18494ad5a5ad27be67fa60eb2c5cb2404eec1dbd7244cd802b17ca5497e779d5f779b981b165dab53ad19fd7bf2ea7dbb9b4baea782a43d758202f147e59d6b6b8ed54f4ea084bc18519943f6894d603e253ba3e8e339a6933bc3a0a47126087038e1c813c3f2997aae321b7c95a802b4b73fc7db95897b7c91e3 0049f347dfd361a65910e97fcefbf60013a54837f2ae657d65e02397f59dc6bca27704fed3affdc3d833fdc621cc5e5f99b92a63 8c565d97c75d0f18ed98e356159e9c63d36438b029111e4440c191ede60fd0eb7ec74840768bdfa1a70b1db1bd15d6d207946cffb14412f10225e8c322f6914dbe2ef342a02d5f0697c6666450edf0de7aeed603731028d2b49bca4125fabef4 +7502c755bbd385079a4001b8cd653287dc3054f3b57de19d0ff8f63c0308c64c56f035117a8971d43654f89b52e923947e4760ac72be073136da70c5ad7ca1658cc0a2d2a880d3a0c0fe636fdb27b77ff260c4c1ef8a18da8e9fd777d732a37ae9906e6c4f381f0a3d941048d5a1f6f2cb8593873fa4bb1621a44bc2bebfbcd1 00dd226de602af4e9f8e25784bd1bbd4cadb0a8aef525d5e2d57b9f3555feb698765672c5099a7d6dd5faaded69d8d68b4804f26 99cf32cd58acd81e0a9c7eaacb097e84b01e9fc5754ad184ce3d5a718a36c657dbcb5c367b74aadd19fa9a62393425e0031e96010a4c2489b6f768f5e730918172dc18f244debf26966eb675cc45624396d781f426ffd6dddc4d6ed9dfad7121 +95eca932d03f1df2e8bc90a27b9a1846963437cdafc49116ccf52e71e5a434cdb0aad5eccb2b692ca76e94f43a9f11fa2bdf94fe74af5c40e6bfd067a719523eea6b4e65730365ee498ac84c46e1588b9b954f1c218920cbf71b167fc977ee2a89429590f43bf637eecd91b0ce3be2d66bac5847205f76c06b914a970f543e59 00b6fdbc9c8c76cb2b822a940d8675889ca6f5132429da795462381ce29313a23bc132976fbeb346ed4c691e651028f873ce7971 afad5e176b0fb9b51ad254b8c2bb9f8e7996a344e30c438a7f0440a10347aa81886d8c389632e54ab813df64de75380b06cfe84baaa45dc2e1200f39be0e44df22fcf0165e431a834827ff52c3d9053673a40468332fc30a4f560398c02fb6f6 +8ff68cb00d03e730dddb05fe0b2344689529096c3da6eeecaf097f22c7fa340593106b1f6726f06b7ce7358edbcf801ead959438a42f94cdb467b3cd5b17fbbcf75739805f9eadc869c33c604cc58f81591b0b8bf4d42bd53a801f0f829a31af6c129fb4f20f1250f959754eff8c629b85a716b6a18465b6495798c0c5166c8c 00203d77fac64591eb9a18de20a9d5eacaa1c3ec58a5ecdb3008c2d642e197141d16b3a9fdffe61429264f5b420f5e9926659a4c 946b8a8ec048affcdaf64ba99e875730ab9aee9c4f5bf0bc8682d97ec5b58d4c8a935ba3e5cb67328b1b218873f5c191130dcfef49276927263d3118b5fec734792c619bcabb91a69debf15e9519741c8cb84c5d6aa5d4a0bb47436f904c336f +01451c4f09720cd53377a5ed04c907a735477378ed960235a833049d6bad6e6e89958b4c4249bf0f6d4f043530c9e5426deb0ec3a12b7feb4860757b41bf602ca95655155356ec35a2db8e2657998f56529be4b714364f83a140846308a2973907ed7b08e935173ebbce5e29afe1444cd51c92824ede960056439555e7e74450 0057a2e6a59d4871c3d547690237dd9846d6d5dc4ec0678aafc9c8669af8a641eed67bfea4b05fd6b3b5357ec4d0caf352691ea4 9461612b8748c504f5fff361e9de09eddf521865666984eca5bea990241e5781cd47c93b8282960a9793d68143b4abeb12269322f1a6de7827d66d7205e66e8ad83c102d6441e5bb164b47d888af956d4c72c5132edc3362cdabab5ede8be6b8 +ccd494ca005ad706db03a3df6d5c6e876ef859ec77a54de11fe20d104377df1900b6b192126c598944d19a2364b2ae87ad7fd32265d59e1f22be5833f20767793677b628f18e9619f8ca32f3af3b41c31e87a98d1527e5e781bff33c1a8be3a82ea503e76afec5768d7f7dd1f17dc98a9e7f92fd8c96fca0db518bd143d82e6d 000a3da7a6633608fcee9ce4253bbcec08d41ee6b00178ceb017de74e24d48fd89107c9f2db3556063abe3cb011938f4b4871795 960c6a4a8b8a7fb05b9539ff71d29b4aee4b840188d50b2f8474dc2f03af13ee3f00524b20b55f17c4b479d29a2e2c6f11e9cbcf115399be32e7cf0e4a91533074f0d7b2cafdf53bab73a8623f486b7fb7a07938eab9ff0b29c6a72fc010c52b +5719e50d939a8d74efb444eb5a77cda48cbb59e7f976cdb2ea2848bfc558718b39ce27b893c229db94bf77992222d1746f8f52f858f85124a28193ae0da039c53d484681785f3367f6516fbb8a86560aea9e3428551facc98cdb1e9df8e2f37db823a7abc589f667b5c93c4c47061400220a2014197d514217fc252cef5a2433 00384723c8b4a316b450d1fce0b2645912b8acaeb3cad50860cca43bdc0206ed5b3b60ebdc29b3eda305d0d60eeaec261edc24d5 91d5b70c291746019ab76c4c19e9cdbe82a18d0652ae06a2d82b7913a622380b189d9768fd26b5768e02221bba40d12311f8d9da6063a757d75a2c332edbe0630170f07bb73131b393094fe99fb45fe6826245ca1cb4a7850efe05f249ca7a19 +c84e5702a339259a61b5ba8ec1957f23ffc4f1eeef3a58f383d3731bbaabfcf49ce2ebb597960ac5115a2af1c62b193d4ab6c24433d5f168a1752e40145f19aeb6dee889a53a4fadd13eef60e28fcc7ed6a9b8b0ca286c1b3d66a4b2c327a629d15c148049e3a0ccdccf05cf22c31956014595e417060627c8125bd7c00f8850 00bd3136647572fef3de51b12e64b36460bd3a27dc660c164fc705417339cab21f9e1f9be0f3da926df459c5ba58b701d306e67a 98a3fccfc2f10185f74bc5cf006d754f263ab9d86d304c79fafd4236ae79495d84c15264fe6d8e17df20ea423fc6598314d8c58922423486dd9accbb99a607efc6c31331b91cfddb09339ece647fb3a1a1e5242b43578947860745c7095aa1e4 +c90bf11d04a708e64b6f94d4cca64b92463eae878c377b188c82c1c5f05a038be20eca2e18034d46f00d9a6fc73c4084981748ee9d2915d87aee4e2321f4f9e11c176f01281913e324700d9cb474b7134fcc408fb4a7006acd9e63d4578ed4c2729d8e0d01b1e6174a43a024ad261eb644ae98979c3cdab75af357f6dbdf5db1 00495be0b0a9d357f6155fac008cec90442200bb842d89292fde38b7256e4117284a60249b3101b3f19f778b680c0d1d7422b84a 8e9a378eb0c361a2ce4bef752d31e371956cd199de66dac5d00d227f4dff55ca64b57ee235c0cb906ef9407a83fb0e5307b2f838fc4fc0857ea242e834a08950f3ae0771a9eebd9cd73e1356007ecb4e201b5a42d5a2569bc3dc8cba52f64a24 +e9b2a33906a1079280100039787377c2971c378b92e70a38ab41dc23979d6fb0c41e53a21b37632407adac6f212341cf6af8605b4978c85c9c16960e1674247f1795cd73b99ff28cdca024f5078490513c77114c2f52288f5376872c331151d7b2c08f7794f2c1f9e0d849d32d73636f0aa899988ca561a76f74543b37cbf3a3 0079626354dfc4eeeb51fcf232ee9e6b0130c9bd40f15ed45606bb7faeca8f359e0c3e18bf12769254522fd4077eb24bd5454871 84ca5274551fe400be6ac73692e231e3ca5c9daac65fbb33f157f61f536c385f00fa0b7472bcb4364aae707def02f7de097c46d8687270dc029727fce22e7e051ab210e871711c423160c5f788e96787aeb6b8e40987755bcd6cb0575e89d09b +672db3fb8cc8e5f831be700498d3ab3aef14b7548e8011b21351215fb6dfa09460d18f52c02c8815baf396d856a429bb9afd602a10c213af34db80447f4c06ab4bd28873c88eb9639b199042d4b2cb13cc364f734fd4ab7bebede7dd4da63decc0cc1f84e34d760013f66d71641073f16c08078880b67230f2d6c6bfe17d206b 00ab42bc7d0e3c23f8bcf928e25f9f027b56f270398a1d37bea0ee5426b944a9c9ba6d0d7796899543feedb470f70b2ab148234f b451043eafa1634d5db8fe89a0ef1239152d2a923dda8a047368e3112731b4557945f2f91fdf86733a200358ba18566c01c53bd1271876b3b228b7d6b7d1bfc7435c61db6a1bd9b6c838a6b9a09236640d72ce87e98f565010502eb52455bea8 +d7fd06b89226cfd66671ce5b4b656228c52d986afa7f6f30161680eb0c9cca177992a8a8c40167a64165c518c55f678702125709361b536bd928567c97737bd750d0e2e6e0c00296a6ca565f7c05cc8c54ae7a4e0c334c6a968fc18a959c18ebbd924457701316a4e999fb11084520dac68dc2d69187134c40891af0355ba89b 007f7aa2216164ba689459ee5d5ca29e70ef75a5b2a4416ab588df1dcb9164330c0b405a9d80c3acc41c19f58e24e17ecbc0fa7b 864e741129a0201d2831bb9ddfd5910528281dec40bb73870345f92c7f3e575f5c66f62eff804e109aa76ce0e24324c6187e0d0ae6be69eececd7426d895c6ef659631bb433508eab34166750cda8d4b8e4d4b3e5918c85635de866de8f95247 +83b7e9d3ec638fef51d2885fff5490c94e2509c126608f82660e5fc523032f3e85d69d9b76af145f6bd916dda35775abbb6d1902bf38880f8b9259822055c5b1bc726c51029972cf7474cf2a812f3251aa71813476bff55598d079f075a40c6c41498bd865ce960c518bef75a873b9d010965f342dc4b35ef5c5972efe6fdd18 0021d84f070c6823a70f1a74225a472118c93ce9dc509aa6064051ca4574939dcfa96be862069424bdf1a23f62f2868326422e64 a8f8939df97c50cf7b08b50fdd5023ea97bd6cc77a876a3f94be888d79d2a735e946a786e1254e35a1a3ab703d1801d30208cbe4f38ff45bd4224c77f4dfbcab3887dfc5874246c6f30fb6fad0e01d02c16669537fe362c6463c4d78c3c8a08a +c62c7bcc860f0e175128e1127dacf935ce62ae794cc4a0ce7966bceb023ac0498641d7281fbc86f9ef470bbc77f608f83f8d0dd6299cf08f2cdacc7a9642e4246df131820220e5c05d0dbfceda7f16b86add4793e9b6244d96b5c07cfa23574ceb43e8e8b5483192a92b301aa3b37702b8f94f0129d8af1617896b34990c9b02 00b6645344d17528968c719091b6e2072388881dc10bdb4c7fbf41906cadf3699b30f9c1dbfb4796d009480664e6276c0359e5db b49278ff092b174ba09c3a003305fb0838b2c6e3ec31a35c2008914546e57da8da54361cc52de2f40ae9160d76abaf0f17d54aed2b014b309025f833a86ec7df8c8503d1c0d5ff64b16ba49cee96c11b9f468dbfea2c346154ff8e25b77a36e3 +b5bf38fd9e822925254418475a1ce762a94e336f12b156b1625a4574fee11ee472d537ef94b4a4b1c0a73b0140d0b818cd06636653e6c07f0f100118242a7703756f1cb1119b3477c4ced99cf45e07e83b7f2749c1a5f8d8c9272d221fe17f7c6a5fb0f8a16af46f232ce406aaf565c6b2766a2f6528c82e74fa1c0a7fcfd49e 00f8c2f770cf5f8e1f900e996ecdcd84fcff5cd959777fd005d721a419123221a3237e39834b270d37752470deaa6cea023c5058 8d057cc54d65447e57952a6cc4341f0e897175a2518c1296431e7b388d15a7115fafdc4c9946334d2b273a591f8d93d002ae7a7c1d36635345828e544e195f1f958385b9b98d52463eb8e9307c4b3049008bf48cf16eacede68b92478970e741 +6d3474770933ec01b76be789304b6fda423b12a0ae8c87a5ea8d7ee9f71300f39440e1c7f5aa4b47c1a8628cfc3a490b15ef292a741344f40a8fcdd02cf3863bf3e32d53031f503703deab17fc52b3d4032f4e237dcc27231b85d3fd60b49ed7ee40c3344948d87c3f47564d20a11d50e4e520bd16c8701694fc70901a5da625 00144adae951fe897d5812ee4a16c0be4c86c5e57e615c398f5768a1223a9be20fa82ceccf8a16a31432bbfd17e594a4cd8a6a07 985180b442ab682d64498cca3ededcb017f6c24a7fe67de46a68f3d16a2132778dd822e31a93e852e86b1cf2cd58d0ba03c68b3ce0da4ee21af26b0d7896870fe59c28598799cc9058b8084f1e9129ab566fe9ae5a2a7b76c51da046df841771 +92ba7aaf71f625f7a2e024058dc8739da3567c306da4a812ed9e1542b7d1e982c16082166a59720203f4524c3bd463a662c26a82ec7b4376545206e650eed0d3dd7909dfe3810981393070d15c45dc4a75a8c5bdeba533cad1ec34fd20466a61e4cde3b25af9a80a9a54afdd7de1cf2a74ba32d4ea0082a037775413c61a8d1f 00a51f065fb32c55bf4ff6f18ba9d488d35d9f8da593adb0ab1632533284e0adc43ccdbda9d9507b9862ac63b5ae7b0f78b479bb b2cace58758101f12e749fbbc3c969700cda7eac57f9457f00713debbd5246f6cf3da3ccb4b6d67ea11823a153504a600fe14e7e131deb3e0db40cf06d582b9c25e91939fc79bd4ee3d4700ca98947af4971144f81266db5e0d73da573c641df +b3fb9e48c333201324755a81f3ae5d4f0e2ae7cd24238fcc66d858e3aeb1ee03328660d6399676eb1b7d8285ba571e214d935bb45516fccfab57b8eb4c3d5f1d7357c768eb7b5e7b5710f599614bd4e92706eaba31f8a5e7e57af7ed13066af50b4540ccdc126b677789920cef8543907f0ba9dc92aae343d3425bd784ef483d 0095351c0bc07acfabe6477fe85f97eab520dc96bdd58b44b036328ceadaa56a1904d2217c5fd25155ff2aaf9005a3e2687fec81 b54b24a8fc6be8eb41997b471985e18159a59a76ecfabab9d4f517658f0980132a4c61bebdcdbe84dd478e7bfbb530ba0bab2d946f618465b8c41ceaffeea06af5f2a8a5699bb71c5fc38b29d356b6f10fa2537debb4fd5940d652fefa6891d4 +9ec5f7d65082264b8a50be772c44277a73ed19199eb275fe5976f9799d8629fcb4a59a8d55074cd2eb2a0e02062d3f7cdeb05e62931a24fd1aaf14c257944d1b42eebd52726d6fe281211b39038e52baae077ea4df89675d860d6ba5a0f998d049614201b872e134367acc90066ac602e478ac3e43c3ddf4b0ca0aac1a68591a 0050245c1682344fef23bd549ac8d1e8e44b2840c43eec1cecd33daa4e9ef6b53f496104d7432e14248682cfd6f5b4853b65adac 82ff4aad7ad8c7c3316d7e08e7a24fa265dba11179705efe79e6ba8df1086471e1c8a01b53b7e1d4a849e34810650e6d1360831ff844b7c57be5513fc95faf0434347b094ffdf47924560c16ee6eaa364aeeb0e19f08e6795e412a4137880fb1 +61d657bf472676301503f6784b7286fb39fb4186bb88abf1edacb4a2693d0a1e2b77bbf2758c84f2cbfd1753e20841b1cd4b456400d53f4d686e666943f9b6ffcdb77f510be97536e9698fc84ae347d483bc8984548d1cf86b9b40d360f9c0dc5bd1c55868e26fce1460ba94ef5e94eb63c9f0776a0f446c0cfd4106d9f36352 008d3b0277f0e9fe54581d3a9499ccd7f015c08339591326859af969d2a26284e3b3beac4a0b74d324ce5cb5f38c7995e4e3a41f a78b8c560ef0841a8b684913698fd2cb03dc42aa0f99d112e531aab9c7671f1378e148999eb78837ddaebae7e53d7c850ed5b0e5be9b72dd246ba0d5ad5a24043b8de81d60c5e854eefa1f33d32e23cbd92591c28a3d74159b4a8e6db37b7060 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B571 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B571 new file mode 100644 index 000000000000..e422488cee0e --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B571 @@ -0,0 +1,60 @@ +8e14f713a2c427b1f79491033994f76acbead614d12e73ac6f3f518f2052a10c1273aabe628ab38e0d3d5f8ff254802e9f44a51367bf80325b6fc39d907a37f731372864747b10749ea5cb3d3a83da39c21a7b02885a8c1770e4397cedc958e4baa21d5007569dc9dd1e45d2181709d900a394454090badbd0cd9c2cd2369aad 00f42afce7f7b3d45f3f925ab29fc3882a89c9f585177887584703cf8bd8fc572e677adfa55b402446fe1e90dc855358d92c3267c35be9674b40c2ad5ce8dbe6a533c44b0ad8d2b2 968318dccbe3c70bea85fb1fa1f0455e15d17664aa8269911ff591cc179f30576fbb4fdc67e9d060a72e1796f25af5601637ab9bc6258af4c80b3027614bea814c32c3d755b6e9023e692dae018aa6353f7662df2016a410421f6526de2be1f6 +38b60d27ff08fb191811036dbfd5b39e1cc3427ff70efb67c851e9cb407f9fac6f348d289df98d055eec73299fcac068bd0fd9ffa3c5d244659e4f714a58d79f6727f323a7ee26369000e90e34e106f99f5ae2ae1b64ee89e5a1d304ef20c071a7773e9b977ed3d49f467d300a881c8371041394910f9c366942449045568f01 02f36613043cbf53ad36e2b38998bb867503359ae082d07d040e5a10a43e06ba9c91e7c73308e41e2391b65e634f83b162cbdf4e7a44ad818fb93a978af00f06be06731d8c5886c6 b2c2ce22f3e04ce6837ee3adc7a2c60027407317baf7c5efa29235c4f694eacbccf962cbe6c8a67816940b606a01093d18bb3e677680a8eb9f4c174560ddd8ebf04582fb41337670d98d412b4d5120d2c330fcb315f0d3827f1a0522e1176794 +21709eeaf9e1953822294a478dfacfb205fc25f447a73a76a32601c00784cbf2f9ebd41c22721d70cdb3842dcaff4a4f208d41c0816990e421cc4b8538ac2f347cdd0aa2a39f1aa26ace8cb6a606b23f6244894d4594a0f6a5b8f6a695fd66e1a41e2eb6a377017177fec56bb58c837e311cd04c5b50575faee32606b9636ec1 02e74948c46930cbcd9dbe2325539c7dfdd910f309fd610e6599d425aad9ae230a8d4681970a14f2a71fd08030d0a40ff40dade7de1b06a80441bbf7e2fcf1809cff39c7ef88bf9f 866bbbb84bd6489a2b0d6a3a5d985a483edb7d27b7dfa692f9e00bb9cbeeac9c115eb213f037f900c802afa86688ba5509475ddbbd3e860c6eb43bb6f06afb10a47a52b261064e0db2eb63bfb7a7e2c4e472c4dcaf3765c740277abf44475c74 +3a131fabf3dc97334f212fce41c44300440d16de1d6060450875f7276f53c026e2a511681b5a8d75fc0d578546339542833145f7ee13c708df33e584445a75a5538829286480d339be7c777c03c998a6d3f037b25799ab2d541021502a0b02a9b9c337a8b176c4f30e5b186485a6103b1d1563ad4ae73ca806a5e4daa92e9100 01b5fab1d36f6f6d559f65d8b01edba610620fc3a38307b1fb1c5bd63e7ffbd4a9098cb8bdf50975a873f5d047ee2b627b090897a7fb5f56d3f4a0f3528179e7c969926fc0d3b0e5 b433c1398838da391e662cebe8deb1561e5d977637103e06909e6210fef56140146b315f244c9c586a5494db024dfbd30263f592cd62c26af0c6fc3d713ba1666f08eb2d7d6eda39a872eded33e75d789ee7a5a09c165410e4d94f5eb8ddc137 +679d85a762f2574b0b31b516270b7d33d5e166c83e91a0f48e0f3db20b52f42f9e6ee9648cf58267ffe3b713723cf3df52b5fab5c14db1e7189f7cb7170bc6ec7cc71946745e152b39180f828688a5b6c0b2957ab94283b90052a3c6e36843c391aa8810f9253b639a8d5a69aec10070603ad7a99dcedb544858d057a1d66b89 0383e70c71b431eedd4574f65d01fb0304f7744d668408c847f7899eae44770a7f3243109740f177d7146a27748886b7b77ecf3792b512e8d8e37c3bf4ecef2b1253df7066498f01 91fef2a77eaac3696018808d3d6e316452557fc2f534a3a0d4547709571189555de3f141ef732ca18c10e9319b0137d20c61736081d5647ab283c8a0d2eb87acbfd285f6c32605639b1fd662ea0d58c437e2108fec264f05d87c51ea51fbfcc6 +236152ad31ce2ffc0dead3c142cf6c770672cd2e75af4a82fda1a72e1c775cec9b481c6f3e411644df7e7ee901c501405620af4b6e9667dfd46091788daa95ef2c6c9f5c240c06b15cb0df51f5f058d8a7934bd7845f007a35f99fa97200b20f3b5b14fbf1e372507f3b2f377e8d07d30fd3e222f398f26d8f428e320327f901 002261d4ead21f02fab19bbb0da8c272286704c8f0c6842ba47ded121e5cddef79fb34e6b9694f725ca502949faecfb21e3cc062a2b4c654bd542d9a1fe8d97bdd0905c510aa0999 ac2e1c3d2c5c0d789c6be063a2be5115f2b49ea16d5db2908eb60c7af23267583923ae1ce69e2732c5c7d84a5e8fba9d14075ca95b3bcd5295f3fd883054574905ea7aceec0e994d9b5f0adea1c04d97f4023f0c3710f2c9c1f257fdda971edd +ba3f02c4847fae035d747db246fe4e82fb9224ff9cf568a6ae548f5dc2befb2079541d2cf9aaa6b18c281a05e7ddfcdbcefb25f41dd91cb3092b3343e16985e91c912215cd99ae4a099baf628e33a7b277e3c36a13aaef85418fca99f64d73b789f23ecbb76c3095ade0a5f7f34836a98c5be933b44a94a2eaa3f99b1d8e7937 0316c78f289e1860bb623082be9d9238b88e38c5e978a868bb90f776235bdff4eff591877b7f350cf14c40356922b2b6aa51d64990360b2b0e44d6941b5dd9492b4f4e1f42ca163a af68701618cb8b508e61154926d3e91036383240d56b67ed3c17891f79f3e7334ae7547c1f5d1f05837873edfb0e1ada13fb451270081d19a2e22779c685c11b96160a9d1803952c2ca77e227eaebe420a947fd7a1b4a8128c76776492594d68 +6d0372b40559e075af56af853cbe18ba2d471b0fc8917764abcc69102b03d5bbe1fc12458215be66409c26c89f67c72a8933677a07f88993af6918acb074fa915fe883b24bc3d191ff1b08852f07eda98977e70eba072d8bf189cd545230f59559ac05f1fa3f4e65886d0bc274a6e02e2399812b2bf91abae81e21279c5de996 02c1bc13f8320d97a82f3d9354e195481902214e16a4fd89332a0499208e91d50e5cabeb4927ba030cb42f5bc53b10f500fa646a8c88508cb0d63ebfce5c4bd574c527d686c735ce 913b1050a178cf1b2bc6424f6cf48402ea30110ca2d3567aa4f12b2cbbff51484f8d544e4255a0b6e03386fefbbf368018f5b68d2c6d6eecfefa663c262f85a469ed8dada54bc672bd5e58bccb73dff081051066c948075de221faf104e0feac +bbfe66c82bc060bd14fd0e40769d9b3a026eb447550dd9f118c30d8448f725f8366edef042447962ba7f7f833b9e9094d0ff600714697e632626e7d12a592e040bdcee166dcda93952323191021bd12f3b1647d0f25a41739994659dcbb19333ca30f46f539c6f0a5c354cda8969a1eda572a309950c84c7607eb8ac20163912 013bd80eafa67663e75d7ae139bf285d2b9f1e03d8e32153c73e26d06e86d7acad22bde9f121a3f1ea674dcc1fe67bc7f5398d5e92555056bc046a02b0ba86c2a0dfe32e91add5b6 8b2ba08910062dee66fcecefe99fa3848e6fb466ec036c863747be250c85c2ce5b0eb83c66175c45e3652609a9fa4da1166053efdd65dc45afcc9ddfe17fc97abd31ee8e52dcfd9ea77080a52ca9511c2be69605b263d986d3cf938cf8c01bfb +b35e9bf686717ce3b16a59963a32a2116130453b161a4e7ceb27b755856add836d779696edcaee3b5c986523891c8836109d431e55c23afbca022437ad19e6777efabb6da3bba1f5f44f905395b4cc7c9210590fd38da621582d059598e5e4569e904358e0dfc0dbfda4ce75538aa97480912852bccd433a9b96c9c66e9597d2 030834b0a4284097cdda2ada6947c6c281f7290a49b56becefea1e2788ea3ef78fb96807633c47c25138341768b241164ce0d42f7301728b928be2c047f2eb60fc2f844ab77306d2 818af125710e5f668b187b8c3e115102026630e8868c876f784049c0f8e23b559696ebac3b7f92dbe82c48919292f0cf13cb216d5658e4fbed22b735feeec4e38fcdc90115b288ffc8f6329d34e58d4c1a53b555b3d9ab5fc780fe7ab00a4c91 +57b5ae7e95c638b258d1e09b3fcb4341e203f5706862e199b103c8fdac72cbc5155e5cf8b300a0b3fb0ce1f897c45f7aefcc528182f73dd450cd84d5fe9eadff3f704dc2a01b4e847c22df430efd1c66b0199f3e5b59348af5386962a5ef25204fd230b54d58d7fae801c086f8f405d3d0aa7a9a9da15c22b868817cd897d853 00c81a79ced1eaaafc31b69a40d9939f4e484d625db6364a8e589b6b4d336d458b44287ea6c6aa7661113fc07806b147ff98216fa0c08708dc9d651821b922741deda522b4e436ad a1cd64573ae6295a5dacbc8fcebaf15b753197900265e653bef77d48c7110d3968169af1ea08c246018c6daba8986fe9193176353ea18c1eb44375dd58e1ab72cc12f4f1342f16c00d5fa7d3bb8b8697b9e98581196240bc9a83717bd0143c54 +daebfef74b452f039c999ba0528be3bd9e16deb5f46f6eae87b63db8b89952c949fd7db08311871eb2596865eed107aa065f030226ea675ee3256c31a3f85ddf4c21760582144e07af208f33c5f47cc026db5403186a65a47940691ea2d74ffb1245676260ef5717dd879d8b5b72d96f87fef5f762d4fd17454cb5ed83d8a11f 02f24670c0f77d2ca0266a743023d2c7413d56d0b5ec77b454ac59087efc4ea4d46179e10278e4ba416ffd8c3f9786ed202faf8251c0ef5a9ea5371fbb35b7afe3d15a9cb4bad975 86e8a559d49a4c114261e652877f9b8075f6b9f19a29114e757451b2ca6bcda8a96b31bbe8fda609547a06a1dd32ebe605ec6b281d2bb6fcbe70d731d09cd5addc72ea6c1772eaa6f923e562a9c71e474e54801b94fe45ce4bd9f1b63820a055 +62af0493ae79d71b552c4647d1fb7ab2f282a91cd44aebd8ef344dfd77b521b0c0a3f72e4513c8ecc0e4b84efef3df9482a07ccc1b740c571c5e69cb913740a792aa231b9dc87edfb72bac188293c6c6e788cb3dff32e8f483f8f34e21ee7efec71302cc3bdbfa47908a135f6ef3ff179dcef26d1a3987f7be967a6c0f799b0c 020985f2c6fe3ea04bdbab66a8b6167e5969c073b9d53cf3c77cebbf73f4dbf75e601620ec9c3107bf3fbfc6c79f8f063409bf8fe1d14b19e323d857e23dc05157d270c7514137e4 a002e8c6753021bad120c10590ea8dcc30d5f290f89bdb0484dc7f9a3f7ac33f4a5c8636c7cc12c3d60843527cc9daed1747e6cfd7c755283be02878bbe76f0ac155a93defa5b5b8b2892bdf0840026cc0258cfd1dad7087f66adc7cb7063cc4 +566f17851951777ebea3f8285610cd8ee5f882a68e7a4205e6fc9e2d66d210ee2505ee73d6503169f7b903012d43e7e99efa493a8e6ef926b16b9ad8f52156840ab561fc6b680120a88714fd66d1d0742189bf06c155e1138ee5314707173f7352e2cea0fc26e1553643f2490428718e44afd8372cbb7bf5b88234318ebf4355 02b3d641607b8a141f876f6d285ee46aea543880e772dadd5dd83d595b9643191d9597218e1d6adb081df133304037bcd2c05c24a54e6c4cca64fb2cc4569d6882315360059496d8 907b6fff8ff61f81c8e060de1fc4652e9b9d79c92f48d4251e990d9e292d191c31627aeebe00bac1735805a23f7ec2d9073967aa18962f1bd7a21b4c328656aa7dd48d3fbcfc9632702d8c95a9a6033f4026c6333215445fa06ca971e036ee80 +25155825fc4f9a1c4dd1db837008e7e2594a879052431f5bfc76d0d2565b8fa726008befaeddceef73f3c60fa2cdf6d9a70e56d27210bd013034b38861ae49640ef208d3fe294ac4362f8eea44f58af3af8a9167a36b5acafb7ec95652d5885a0e08067ce1dfbb45a0c89ad1acb53eb404bf88fa5c3c463a0f912b5a2522a0d9 01afeb5ca87c81025ddf09c2b2c5ee22ba0105c0e619b67a324467485bd839030d149fee44d8bac6f5902a1245a50c3437046b7c89a84116b2147cddc645b6d2fd24d68e8d53bf5b b396ad072bf8eb4e98c949c527d0c7d2e261b443a8bcf43b022ee8b7a2b03b582ea6bcd737e401daaf51a449963a0365106ce397cf6450e8acf1869783cb86a67aa2a69eece432e8c3f5c64a4e3e88ebf7592f0ed3b70d00a8ef6b517c4c7896 +29acb0fca27e2a10d7b9e7e84a79af73e420abdb0f80dd2665696638951b52dd39ca028166b47a3b6a2eaeceb1a11c152383f0bec64e862db1c249672b3770909f775b794e0b9b28a5ec8635a996d912d837a5f22471b40ec2e84701a8804127a9f1a0b3c96ff654700bad3167240c2518fb5dedcc1be9f56a807083e587bc56 032c97639b69c7cdbf419286d0a1b406d9b1f2886521a8b979a36118d2a368aace5b02dd8c515f2041e6fb9f026d1e82e789dc826a56d2ef732b1bb0f49be2b696ab5d3d5694a2de a8196d9a4d644eda452444e709e1565aca6c6af998d8ce1c988198998bd9dd332d49c2a65eaecdcaed0159f5a1e3a1910686c28f2c4b7b2529132bcfc7d797ac1ad270cd5ac3ff8db3a221f5f190bec6b90d17b1c718accaca3f3b187bb0e7b1 +c92d67cf6536f5046e15b02158da698bcbba4ff1e4e9e9c882cda67f817210402ef917ae93682c9c3dd817b21b73c6c00b7bf92ea80ecbbef2e67f4f4379d078a2b0f297742b2bb9c3fa3297a7e8079f488555bd37715eec92b4b1cbf897640ae8a1d2a0fbcee5423ab31a37629f98630275e35094a896cc574be0a449bb1bc3 00f93672159276c5a293582b9f49607bbdb970112f6c63b2b3b5d32ad3c8240c86b1af13a8dff6502c6b6a17712cfd988f8cd23a60693d64104143b3f91adb37f852e9e11a0ef110 8ac6a42e45d919e6fe448a23598d82392660707a23d4c551f1e2f0a504bd99d4c3549f2f6e7169ca801eb4588d7b765100d23f93d7eae857f26deacfba267e712527bb4494c39ae9965d7b4fd3f9357e982177bcae46255681d88e564bc6fbf0 +15413f614c4551e3b138b64f66d15f8964c40326a42b0afce820778eee4a88edb127fbf575da5263e5a2627b5461d311813ea868e6417615e7c4938313675009caac28bc7a2f4c0bc37572d9bf36a3b1794294e09c0121ceecaa4b916df45b0dd31225415e6c87cfeeb092a008fce2c543cd62365779ae28f29fa02a15d9dcd5 03db080bc99c5fe7e06d5032167af56783cb423fae59fb5b3c6bce5fbedf56b7b39b17810e48ea9a172881aa1f42f5e267349b60294d4a208b4437666b44abcfee5a1829e9467908 88e6c6e87269f7c9670cd0d286063d7d26c8a829d970f017935aceaa886219df8d28898bde85502d6974ccf0a7e53c0b15255d88ef9693ad7e262e8dd058f563ab60dda6a5b59c0481c8050d731666bb3c8c7b6462d13a785b19d8749f600e6d +9f901557451ae2f8ec79b6d4adc794cbfd9b2e6d28f19409532d91682820205308b41498a4e1ca247a2baa8da93de95e3c0f7afd6ca46bafdbdcc6d3374a12684676a50988b86a960a82180648c8c1e38f8fd9af604c7be3be4b24799f4544ac96d6360cdb83d1d0847fda21642934fd6cf65385b50d86d4656987901fb88d0c 006ee767f6f36bb8f364f324d8346455c899a49237d759003dd52cfa13b9baa4c71347b134b24ecaee32d247c34e3787a0c64bc5d299b55c86f64b47521d22f2c09db225b0c84cc6 aff4011d98f17b4f4569f4fae22e3971316e4660f943fa8d2d3170c814f268446a619681b26ccc4991f31fd4284fbfb2177c9fcb8e8d4d61030936156b49a330615c3cf98b155be3e3b3e7c080702b2f484fb25c6ad84bab2fef7d32d252a21e +959fe5a19d7aea2ba611c7203e19f8e3f3cc101e03a98f91adfef602c424c580d5a868659368a930f9883d699fc633bd07f6cf8de474937db0bea86fa7cd140ec2f202663813033a757b93bd72afba15be5e47a4eb93e8a666aa1c72c241ca3922547d63fa3732fec54afea7ade84302e2f044275bb67433fb6b125b7913143c 038e2571d9f22309a636586d62863ed67a70538287f3ef88b88c3c2fa1a2900d48c342b6f15c26b8e7fb4875cda4093b7de7ceda48fe1e2cc2975afe958040881de61f309931e48d 8b9bd76306e7c4c7a2e2c1fcabffbdb6a096921c18c85f04c49a20126fff7efecdbb4f62db575a99f534969bb292f7410372e44988cc3291716332867f1f6681f67ba61aa23ed7f8f3bc51ce75823d0f51ae4cca06270d96a75d1a8cae1ea1bb +97b9688d9ed5101b8cfb19e84b89cd644262ca1c7ee18944e29ddd3b4cca78e06338b270385b00a5e8b91ca5e628de3bba50e36ecc695b3ea737a9cf8b36871c473a54ba17819f49e730c0f253b0c769aefa6c16366fd2dd612f330e95fb119fcf3bf7f3e254438c0ab635ec04a8b2424a05b483ecf65b74a93636fbab7bf1d8 00c8f5736f1ae65592f3ca850f43d06441aaad8c03820f3b08d8a6db46488dcfb828459f8b3f34af73cce8dc7a5e3834e085a64523d890028e194214cef4003210e6eb530005b01a b57f6779a7cb9f2b126c06ac23b1ccda783bc2dbbbbf66cbe03147bb75a17298c4d8421bc9bc355c7e9c5572688bc9c5099ef73945be6110d9a803363ed24e02f919b60aff41ad60fad74713070da8aba8858849e96d2142fd16f49e15724144 +f08b250bf4a3980cb455338b3f4173723b3f44c97bacc9cf550149794a71426e398cb4a74bde141d8b7b4a72942f1c069676a9918e27792cb8f085ee037c78e3c468adea5123c4c64d8ca6a39f2f90140c5d2d80b669cbf0d1ccb466b18ded83a1d5f042c36188a04111c34ff769abba9aedda40a87be1e24b700225e2078056 01ee68c3994adaaa9e0d61bfcd3bc1cdf198d3fbfe28a44e5dd518867ea04b20e795eadacc48bfcf8e8216dceeaa069b756e8e99ed87b6b1d31154cc9310bc3b4555162a890b0c6c 9207438e608dccbfa193b0bdcd22abccaf7bf63e675d9330c28a77f404640aa34412a325ce074870c5e440f9f59d158809882fe0f5450072d3eb284a4b806ef55027db2c338ec8a0df3c0374e7eed3e0363ef5356dbe49bc2fcac0cd6cf3f773 +1cabd16fc29d7d919622810dc8b23c770b790b98b119eeab1b20900fa94fc2ebaf76be4f5eea91fc5276c5621c8677d4d117c4a5a782ee2ca1d5b0db997fdc8a05b6b3fbb833d7a7b81c3c615c2a662929760a96feefcf89e46b563314c9b77c86bf34438458b43b694ceba741b97dfcdacc0ed57652ae62856ce10ed2690770 03a6fbf66ebc1365ea7699c72cdac2dd85907ec59cd26e2d18713354b619ccb83b7fc0db9193aa8493c1855f1a83fd987cbbb65de17c59fbe79256aa5392f4eba045346e9ba26592 ac926404669988bb7d5ca99852d9a794b1cb2c1c1f8f73492c6368612d66111c103d2b2e7f778c7182e388d70802ac0e0f69d94676bce0ffd540f57cd27e0a288d433c8148448aa32af3174f390a78a55009bebd0a99c3e21fb452fa8836e43f +7bc8bbf5ebeacf40b3c82eb6eba5d994dcc6a3f2e12ef741f90f90e176d20c21e006ecdaf14cb5beef35bff46b2c374d9ee224516679b1a9e9255cd8ad8e60ed234f8ee7e0fc53c9021488158217d4b4369cc597d6053746efa1e73340bdd73c1bd2eed57b92426fd4d278d6a86e8be0f0a66ab3dfadefca8831b2f488636251 0145748871a0b5c1cee628de04a12fd68ff2b154fda96e47afaa96389d66d22802968584f6753d36618d49ed205260f09d3f5ccc2b27a34390ce58179b9834ff92a86d66ea0a97ca a8282c26e87036bc57b16bc4f89319ab9df46d63c850e64e69f6d17e857ea96fa21a5d027e2a93bb0bda9d612d0bb90b0895f87a1428ecd9bbdfd194fe575cbffb147f5f47180600be1c44b438bfd7c16fdfe5df26db89e48d888b35fc61aed0 +0cd2a45392871c0c262e7e6f036946354bb41f9c2187b8c4d399231280682f3e0a09731fbfd52c76ee63b9828c2d731f4cefee0a8c46419c398205b2ff80c67d7756db300a0a8385fa287dd37d9126f75998ae1cbab5136560592118db52fbf102b7ff0a1ed45b8a91a7d99d13a0f7fd4366392264aa1248d7324901467457ca 03c71911d24ad19c20fc1d8a044d63c9bb417abc3778d7e6234c6af79b898cbfc2f2787244708d2fe203be786edbdc4c9b12b413156b7b0bab0be8af895d191d853cd58aafe1ccce 8391dce060cb4ab80bad2d865b1cba65e66fc2e4b97b0aca0c0458fd27865cd4fb664037c9a520e4cfe3b300ecd8c12c1869db8f15bf56ef64ee035ef966541032af71f7f4ddd0d98a3716807d43756c749c780c3792ebf4eba241dcf6716a0b +e97092625b09c9ae6e152e1cbee207d83361f34cb9b0e727c816a5ed851f12f91fbf88ad9d4c8f9d07350f5d828fd8574eafc768bc72a2b18aaf4d2b48fb10f7c3431137b51850154de9706487d69a40a8f4cb2c799f48c5d8f518aff752500de93cbb94ab04ae1e0c7183a32d79a27291dd07b5fb6e6a4fab76e85c3a8607e2 018bd74698bac36ef11add6b3e3fad227ecd868f370ec04569462565d2f0af2340bf793486953a7b79ab04f0ab1f0e4fd16bf6b576cce677d543e73aa8edb0e50372f24ddfbff966 83eb082ae297e10f91a9e0248154b35bb390892e24151f711d242b2ad87f309da8213fdb863e67c912f60ff10e1a82721658cd7da3f3cf69b632e10213f2047a72c5b27d9aee60866750c1b191647a1c0e0e58c5312199bd3441eed83222432f +ae6723b8df5d6ab5fcfaa22d32fdf106d211514cb1892c7c43ca6cd85c2532f85929c8a259ed251215063cf92e1502528d1e22d5cf67efa0b8ef21e8eb2f5dff881ba1433e8bcf2b6af8742ecb2bccde081e534615a305562cc22d3398f61f277d8ca785842bda85d8a40438d9bf1aceaedcfc22c85533794a69cfc320931d3f 0335699bfd058ee2e6163f55d1816bf3669acea8b73be9c4ddfe775230925e6093cff7a66813adf22222c8376faa106d85ac9f3c67929bc58d8986795b6d35d5b9fa546dceabbedc 8c7f4a7a1abee1a2572abb014a85200172e100fdecfa56173b1d23f4a97f3335e6baae59d0e071da455578eb65665ac50d3b8e0f04a8afd46209f38882e853752cd5e96ff8808a0b34aa604a134f441865febea8f7b4feebeac8e0bafe6f2696 +ee20c6b61886e02ed94359dff3559522ff550ca126fed4b2240ea7d999a182b7bb618c50528fcbd261d5e497a991fbac0cf4c105c0f664d6a00a9001c1ed522962fb44dd4159677ce8f1531019f86457c055c9cea6247086cdfe0442485cbbc4386ad002b4bd39a1a187752437f04569705cb7adc0c68f0fd059d946deb63f0b 02c3eaf801330b3f1b0504f2399f1d24455db29911f750c246ba0a134c3b59da8b3562911197764699a92ea1d95a2aac587e24f743df1dad3e1cf7edf955203e24a0225717f8d2df b0f63e4f1b6e9839b758cd9ef32ac054abfb1ae178ed63aaf01bcb289e9ae7a9ad389c04d3f9db6b2696b508f418dacd12e31aa1f324e7a9499d91bf5ec05437c4d137671ff60d7aaa0974dc3a1032cd6c7308d276f4fef4ae73d9cfa8d6d7b5 +734a9eb8288e32f5a67cc1d88704523ca2c68b798d90e188d871d9f50d2da2063baf1ee6685c45832a1818aabc9afc0bc935e97969dc983a484f16d2bedb3c7c0b8221408be2480a5562d5d1e5d8763d1e474bf2826aa93a68c3b870e3bf34f4941cf590d88e1f5a8cd782a33992213f3f6b4b4f6dbfb3c3c8f21f5eaf4ef609 01c3ff067497e5d387f31f0ecc9c67b3c0dd6ec8c81318c492aad83c9dec6c99e4fa47447f6f7082d636c2591d0df940b947d0a4ae3778e2b7cc8fb92214638399def894ada276b8 a87aaaa77ea832489c4a4dab6110372e904b6bec3dc798ada53339bd70f011dea2db0836dd01bb513a0b39272220d4b310b3ffb21a079266af4ecd27e437d28d419f946dfccb18f0aa00c8c568f45b79492103507a4d7a9c644c3fbb82c14a4c +68e27cc72fec8f3f1f3882c6efa08efdf21d74d13be5171da35ef2855666ad2ea6919d21dbc1cb6d296663dcbceeba2fe47a2c6507d3d4a67a61b55b0f81c93412d7e1fbe15a590e342a05f55daa55f8591171303154e615e81189a523b855829a5c96621ad118f522e397e2eea05c2603eeae6e3591215e29b2289bc384d8d4 004b4e04281b210fe78d516a5b69f878b7fa058941ee9ae8cc63b061d1eb9e12c3e0ecb8717ff4623ff5bbbcdb53c48adbd9c69636506ab929c5507d7ebafae5654aad65a263e48d 93e2366c1fcc1a03094f755bfc21c9223d6f6bd788b43c12090b0adb3ac230a8335fd8dac6623e987d7788f0edd3d8010f3344c8b991aced992f745e8e7d841cdfe8c0cca3473cff4b4e78bad5daae5184f8a23eb17fdf4d8cfb1baf0a72b3ea +e67cecedf35058b80787589514a9c81c6b9f4bced4260411d2af75bc46b8b2c962dc9d260dc99ebbf8ee64950766efc0e394184bdc8e2891d66bd3300ecc880e9d6a3d0eb615322378afc3dba89938704e9a8d0c949d4bae9838805c00377e3fe5ec6a1a98ad7eaaba6b500973dac48b26b7fb2e1b9889f8c387de535d4b2363 030f2849a713aeac95fde5ce3af853e9d070ee60709eccf35a076567be2c43f0fa34420b0fc097ff577221275a3a56e759efc32183be2d76058a7d20e5dd59f00415114d73a15b8f a5128b8ac750c4867f1d42619c90307bb6ea66e77ea750b5b6c51457b3b7f30393a2de5fc280934237ecc495d4e1faf2088ff02cb230274141b5a95b7d02a254ab1d75c932a0adb7d7e7803f9577547467eb604f46f11902012285c3ce85a4f6 +2baa1ac3f07e34b67b6af087400f261e138b070c8475378063286c16fa73578303380236a4af2484ea01ba56c1c619f6ae4e5e6ac2594c8e5aae7e7f196f96fc5d0f507bebedd4d818e77b9120e5b4bc01c7ab6339e88b71d0886631cc7fd89659bf513faf149c61eb14d55060c8dfc7e6e4c2b4ec8edaaa6bc36eca50a6feef 02ebb73d04e6e5361e20629e3ad119b33db5163ed91fd9a8aec4b774898784b6822a08992118a8fe6013094bad0be1e9bf01b27c069e4335bff7e0abd28a10443818f6b825e9cef1 87d5d996981622f39a41d3d9cc2f83e684ad27484fc6400ba19e1e2ea24c7ffe99ffb91c29134dd7a79011f52a97fa7e01ccee9a03127e2fb354bafc253fb2547532a7956946abd90a849e8f12015fd7ac7717acdbdb7dcaec9c13a14e4c0111 +0e640581f573068d8ebd2899a6aaeed0bf987ee11e22b05d25e88e9a1c3451f45ee3800d976f4603c18a041febef07a01086832a6f7ecd5d498d52e796a9d90758c87c36f4a5b704a39c456aaee2d5278183d5815d619c193da9fbc427d701bab0874bded848cb4bb066f56e119b637c78aeb6eaa387c41bec6cdd4bf7b2061a 01bfab717d6f6e16d9bc6e89d2ffac7cbe0f808cc8ca2eb515af7ecce5f3b230303775710a21bd25c2cc4566bb53c78c78e3774a9f306c751cc6e149929e45eef60f56c1d2388c6d ac3c1d5f3e6c66193f72ca06dce42880938502694befd71cc8ee217698e27ac3639a5ddadfd9dc0693b0242350b459d307421ac9110f959a6461e2a3912872833d973ab884fef48ec2614e47552c62b59c2557bdf5b8c2e5d31e5c267cf98ea3 +51a2a560ba226d629127ce1ea7e812219ceaddd23561256331458c9f11fe73990f21d0dcd974a3773040090cfdc8e0f01692d951a0cbb60f8448a016c67abf46a9c150466ac77e656ea827b0ea7d1e77ea32071ba8314fc8a2edf69008f498bd1c18061d7d00f3340a7e2cd73e9766862378d8702e804a1870b442beb2d0aa14 000cc53bf7f1cad5e3dede4b4f4b082831604c92dd2b147869cdf1107259305b1d50359647f9f3d7d4e1e608865c65dc7c9ea46bc324dcb8423b554dc369d621743cbfb592b70eb5 92dc4a90a5e33f9de61ba58f5582a71265cec77b17f860a5e46ddcae4fdda458c70bea5ffc892fb7c1063a06d631d41b0d260a685a80d20fd38c5134982142a0c6f96703ffed8771d4ef447eab4eb3cf920cb0f546b25e7b29df877a4af46ca7 +90eeecff0a2e37df318c441df220dfea013ef29774ee92a56b213e13a798858f31e52b6ccb7599e7314f12b48a89884b113c1ba0526a54f3e9a33c940944319e084bff320cf5f391c02c731c4c4f8b05afa273374a1705d6c85337782ba7d36b9c00767180cad6422c11c581672ff631fa4c49d41b02481568ec87ea97220400 02b009530cb9d586e35dd8951ccb686833afb7a37ec253e547e85b253ba999f0f186b6d4ba41091615fe57678e9801b4dc94fa683511da25637b2acc9fe60936be15af16234c4ee7 ac319ae2d362cf9582bed5bda7faf501686323ce5f573932c5218604a7982878ac326db2326dae92410e242691aef64711b4a8126058eb1f8690263d23a6d71b6868a026b1aace43504fd891c54b176a797d385daa81450ef46433c9073cdea1 +d3740cad41e2e365d80ae81da97fdf06d8b6c278b505e34cb683fb55ddc5189da543540914c0accd405dbf0063f6222885fda4b316dad4a83fd03e8d7b7e936f87fc0a5b095defc8a4b22fa97f00b394e672d5efd3e0a230c7e44dfeebda88641143502a400ed62e2a51f9561e5d652a43d616f16699e875deb9610c77de8e1c 02cc2d0d7189cc8fb3565a039aee7633ddc00ff427cafad32fd2010b10fe249c9724d91785e7080203626038109158e3a61a3970aa3e51688aa7f5184b22f63af63f80d3540ec023 a681df3a4ab27a6d7566c678b430edcbba6c4b67adfdf43a370f50203bc7be28c5dd26c42dd4493fc0f8b2957c7577f816124076900bfe145be9839721a5ea66adff6d39edc33daf2cd3ef127635985659690ed68d1b99d064d73d3530ecad83 +5eb53b5f92121396c5ff30e0c92da48db4fbbdbf27297f9bc82614ab78f7fd863e34096c615a02e349d8bc7ae4b0700130704bedf32756b5ee6af10da1cd717d624fadc57a9aa6db4a6c5d6254c0e8f8c3c0d4d03c264eeeafd52cac2c1968d9d85b106167a49d0ccdbefb20bdc10a2555f8149203af52853169a02db94e5e2a 03d8936c00c131e38c6566d2464c4e207c878070bbf681695a6cd98cab2c6e80fe98cda80c66a5cf584e90a071144dda59c07b8fc7bb42464dbee5b6f739b0f2ee5fdff7e5a4e7cf b82b5453be8d0bdf341d92bf7bd2fb0ed9ab89dac2fcb40099decc8a8990c2975c63c1ced4e90350371b02dd161813cf098a1d152e5e5ffe395aa6f0b2ffbc472855d4e3ebf863ae7977a113e5ed4f368a7adafd9cd3908b761928bfb8ad5a2c +5aced64f702a57ed7fabd045a40c967a485d2a70b0a5e82561d5141ef329469b2da5964a34df203a980111a77adca376c643b9030aa74516f054648c1534d912ea66582adf3c655dbd71ca55e47412315df5e2893e43b2e2dfe6e4dedf426f11846ebef34a99f5615460ce0475f7bc54b4a4fd99e83c982097c3136ac6188a5c 03dc7de970bce28a943d7599f2a9010fc99435b93bc4ba884d42503ac2941aa63fd07db34bcbb1127d56d6a4e277d6ca32051ea3467e376f74f98c3999d2f276b282ef8a28cf0cbc 956ab5f4536bade15985c607e4f5ba70ab4d71506874dff7d0c411689958c6c9fa824e5412438b824e3ec348ee4e3b9e1347d42d4ddb9958e648f39e5043b0e1e314cab269501130e356e68d85553533dac2a54c4e6a60d4c62533dd158e4e76 +43c24aea343d4e088bea25be69a332c631275c36677093e057de69cc83a4c5e70ab270e5a8930f55846f1a22ec10e03007dcf0942c6761e89c65c6a4f032eed97dc3a2c7f7ed1e82552fe48828a132ba16c41f6bd82a49335428a24fa1679522000e6a1d12c646e0e4b4c584398577ea9493bb334fa3cee8bfdb6c2e66f46436 02de6ee12eefa7a4a736484b19b42a513dfc059a060976edc3b0aa4b50e98d72df6506fed0499ff8480986748e938289e54a5e86c0c29733a9bcf5985aa63d8a2b57933a04a8e8e0 84704a28d40bbc93cb32473f3bee47f34a1e2492c9bd67beb5b2c6b6053474f218c2e7dbb361f6573f27d0b9f3fcff631846cef7039f09a79b779cb39a4aaf03a9f226f79efe149c2ba91c233ae89a1bd501ec68c3fc3dcfe0692fa6d5257314 +e89210565959d93b483659e62cf41f0a0147ea23890c2f1a694c377a826165e363860e4b084016cda878a43eb68465f81f397ecd50087a25215ce7c4ededa3552218071fa3acd7ae380655fc8fa884998209ffc8a2c26f1ca19dfcfee455dad35a4e72caecd8da47eb9ee21b889162f5d3032724abfd1a31e68612e18bfa9006 005468f0df2c9854f5f655743e79c750fd8812db28b096d97207bae7f5aafc6b6090c9c636ead9e0fde32a1ff8d539b53813733ca812b41b58ff85a941abe4f128d59fdf9847baa4 961310b36d167c8774313656094ea2779764132887163c19fbd6ec4390c17d848776dab98d7d8022fa961370b6ea7a7c0ee13e8536be5f3d11d2060f7761e3d329600ab27051a607e481ce81fa23d24d6d226e4871690437ade86018460c57ca +48629ec97f56273599cd9903f8a84ac2ba74275b40e1e42fa47649568babe05cf63c8417d828251acc2eec525b56dc9082b68d51b0c2bbaa7389fbee15d058cf482993b2bedc5a9101f1afdc79989a812478245d191550109fc17215679553c508c84e3d4cfdea377088d09eb214e6f92410facee4790beeecafe72b2e3ed192 03d3c6a7ab9450c94aa3b8a1ffb678e5b647af24cbfd66ee3944e6f264f406295b803767471fc67936fdfed1714b4b8761a07eec86543b7c4da6bd2fcb33fa8cda4077737f398e18 a322a3c48a4cba71fde02cf5e267d296eb1d143e183361c4cf9e9b949c721c6fd78773eaf66d45ead3b969e967f20cda11b545eefc50c59a3df6585582c171b1083959e128c56e6a31eeb8f84a429c9929ed311088aa3b8071555739369dd3b3 +aa3a9fe467b1ca638dd0622c9ea235a418b39b2e15ad81fee01b6892b240783d8db3c72e16c13df8016dac6addbfb85232158325bd7432fca3b8bf5db3abd0b4c5ccd0999609dc42199ca4680692a0805cdd68108bcb493a558ab507cec0a2782a9e976928985352edb2abc0c07078b59d2fd86fda7fc76cfe573181d934c46c 001ce010ea8e6e1a0c26ab22eb90f0700dc73b232c429d36371e68e429792afb7223f10327708bcff779ea55fb5f22ad87aa054e84d10f5450f1bc9a89279062ea2173f55ab0f76c 97d862942f606f5daf3b2f970f8e6caaf9e0d89b58823a85a9e91043edf8ac813b182810bec279edae16c982705f0fc312642f12d08f42796120f16cec83c51bfe66c7129e10579f68cc23f38f3f670fa414d47563ca117dfc87c245777be649 +6c3937014361799f1461f652841b5137eb0dcaf01dd293298d002f27e9a770b9e1a30367e35c04603881f0c814cf8ecfbe1619cc49cd516b1d60d27de37ed52a5e1cc300e2face4669f308ebe6747255a3d386f16778e494a7cdd10b45171b2bfcdabd91b805bf24857708c1b75e368edb2874321324f83a19154d3a1578c767 01e7410d012aeef02b3723346d24ebafd684c99087ecccaea1cf3735d52c4c81dda41812c09f1e874dc964d858ca240a19963d5dc89451f5dd6764426ae41cb23f19cbfdca0fc562 8c17cbec19fc3e0ccba1a1692d5500c542ae06d3ea4e41641d34d6e10e637f2f25e06712af6aef386bd18a82a5418a5e0c8e0bf24e13c0d066a7c3c2a3aee8010f6f4b0be7d46033c213d6c5ab1828e621c8d39d3398671c9e73c7d457e76fb0 +12fea55ffda15db902aa6a4388b9807c89c193cbf75b5d2a4c95206fa43dedc45974c80079933451bdc5b3ea015ed3ca2c54156dc61afb1bc82adefed1491302a48b9d3d2f474ab45343c611677d360515b93fb36da7a1c1b2341c9cce185c881c0beef33d43967134a190c09034ae3261f3295b79aebd3fe123616f73cf2089 02139839ce38eb879d266065dde5e5ea227244323b330e3ad5a0bc690f3c210f794cf18f0d730693887548bfbc434f48ee10ed34cb41d52172b06e448df938170a5e17311cab8e88 b0e68dc710fa7636f39e808b71c5d66719f2f5db3d1f42904bf2e3daf9f5e53f63c2a791bb80b92c51d79888c9bb43b7160281113846435446562075ddaaac7d656b8082fd3c7e8df42405660f4686dfc13535287ff48c476993a9d28c452cb3 +c8395546842ddb545d8ea3db4efe970453dcb06025ac3b7a25aa5ef62070f3021b9a1fea91ff7055b6c398073e7886a6f71afe53c82c47b71377dfe291972503bbeb25bd477bf0e7adc8a5d3f8b34ccd0080d61e121214e1b29802b711cdd8a6bb2275a2395c467ec2c1571952992e448d736d8bd70ee629c75b5e32b8323a00 0274f70fe69e4dbb55c5d404e39f5196335047113087f8711f2f67f2be4964e4fbcb865680758df1c401cd677b0971654b7a6aeb7bee0d6d80ac0de14d4f46f356b2d5545c185aa6 b15a763248f00ad82c8d8d56302793a95cac9213060f0479368f4c26053b69c2187077ab7980e6615a3b43c17a459cd20e130ac45d586260b85c19c0875862b37fb345d5203df9873abcf83c0f7d07ddf0e1179c14dd300a39ba191cb8eca89e +10d2e00ae57176c79cdfc746c0c887abe799ee445b151b008e3d9f81eb69be40298ddf37b5c45a9b6e5ff83785d8c140cf11e6a4c3879a2845796872363da24b10f1f8d9cc48f8af20681dceb60dd62095d6d3b1779a4a805de3d74e38983b24c0748618e2f92ef7cac257ff4bd1f41113f2891eb13c47930e69ddbe91f270fb 003e1b03ffca4399d5b439fac8f87a5cb06930f00d304193d7daf83d5947d0c1e293f74aef8e56849f16147133c37a6b3d1b1883e5d61d6b871ea036c5291d9a74541f28878cb986 906c27750260a45d83759c395d56eaed1970d25eb617f80cca24a005dc8551647d9b7124f88d9395cad8412f25f4fb3e1814bf9a2750e80d9092541a73b1d4862a9e646e7a140360f5f4679ec99d0c1e9197c6b9752f2d33ce8a50e57dc565c2 +b61a0849a28672cb536fcf61ea2eb389d02ff7a09aa391744cae6597bd56703c40c50ca2dee5f7ee796acfd47322f03d8dbe4d99dc8eec588b4e5467f123075b2d74b2a0b0bbfd3ac5487a905fad6d6ac1421c2e564c0cf15e1f0f10bc31c249b7b46edd2462a55f85560d99bde9d5b06b97817d1dbe0a67c701d6e6e7878272 02e09ffd8b434bb7f67d1d3ccf482164f1653c6e4ec64dec2517aa21b7a93b2b21ea1eebb54734882f29303e489f02e3b741a87287e2dcdf3858eb6d2ec668f8b5b26f442ce513a2 a63036ebaa925ff2d16ac74e99eda72c51f094873631dbe03083622b0645a376c2f474198b58e2bb0fa3cd5f3e00d8250eb50f0414b3058567d7cfd2fa583146cecb788d26afddc1f5aeb06b3e3e508a232b57fc0a22d1c1ae8e5db292628265 +ba6be551bc60653192401ed8ff9e1acd9013d8811a7a1389528bf07438366f5772cd7aedad010c19c47622cec03a4d35b8003b39ed901b720629ab59de55a03c1ca50a62987f8da159e356245df58d5ae1936e65f3cd3acbe03ad1d0fcab4aaf2a7a947549ae776772201efbc6fab1aebfa1d99994d4f43dc28f39c0f279b992 02a69bc1df069c6e89722521a63675f318252be629e7558f3716917998e660ac960b0b750562846fe6c12ef492951e51e224754bab84a6eacd4147a5f26ae85ee4381bb14ec2a8c7 b0c76b80133b7ec0542b46a0174aba03b8ae92a372fd4d5fe6577b0ad7c991b52865a41be86838bd6c8447c9b78ee95700478c4ed274dd47ba80a1c31e6adfbcfaab4d5fbacace56301f90cc850cfefb1a716de8af5b2ff3a5e9ffbbb49352bb +295720a79ac8201f40a66b06ae5d970afb15f36582897eed25cd92edcd00f70ac8e31c556eed4375ea044c2e8b227a8e02c0a3e996c9272d52ac7b3ad43b80f217295dddc84b177cf1e800ad08bf7fdd021fb2f49b54162092f8d628679c4ee335abbc90c027264c8b288c6e16eca3172eaa297ba50626b00fe0a0ad3a9dbeeb 00d11ed1b78b22b3420df4ddc4acc7c2286d9569dd6dd88e0fa3ecae69bcced68bb81bbb4ca6e9b54e67856e7fdf39155aa27aecb9cc827ccb9cdcf9ac633561b27d8eebfc261aee 8b9148453f32083c2085203676b0973c9ffa4f8131c65aafa7821ac287965084784f540a07ef40a5fcdc052ad9fde2db0c272d48ccbe3d008caf5c0337d2eda8817e87428aec6055fdf931ce81c2e2250fcd9362019ac668dfccc8f7aee4779a +a9cff41c6dfdc4a12f31dc375a5455950077ae323d0b7a3d9a8dde73b76e9d7b94ddf9c88ae8e6c262d704052ac47681fc35adfc56c904baaa6e146eb653984369d76a85596cb744941aa7b558c945ff2e81bd5ef7f00ecb4f43af23b4cea3bd4ba7b1899f1868a0c0ecfc62ccb1d588955597ffbbaf34cab2838efc2b866669 02c36ef754b5bd065e9eadde684750acc52795be80f54dd3d7a7d743d968a18f7e404bd71f8a76eb0395f396df5a7c2ff7e0ab6de35df34282fda6ee01fe5b9b68ecb4e378dbe32e 8699f091d108123a114f417728bb4980cc58c0689502fe5fa2c5ce7b508fb32462596376b328141be80190ce362bdb89178f1e8642a3cfd1a28fa3807a63ac58bbfeb388db73b95785abcab0a4f58798e09ede4bba8f04338a2eeea6374ad23e +efa6c582d7fcf5e431aa89b3b00180c0e78efd7ccb0384d90b80e59a115a13e55001d951528c42860132531c9b8ab29dda7a657c53c2ce96fd85549f6f1810e121eb89961295335eaa0e40532d85814a4206e6fffdf9bff76599da9b2e71a22ed572910b0e3bae38ad72c7042579f106739a8628dea5a745168bd918736e488a 019ffee50be5496507e3ef5c40ee88a49625e46d1dd1686a52b09ad4a8e3ee9ef364f953bfcd97c52104eecb6138067192997cd4ebadaccb73c7b2560879289a46353a756b73cc43 ace20660f15487f57e19ada5c87fe87c65d22a0d13a48cba531e34d1daa0856fbe44a8bf89737f9162494e0f6f1611f7093810698d13221d497b8922a844b84f078ef433e7fae0ad6a7ddf53810d624702500897d6b6521a465773c389cb35ce +211acebfaf13bba33a9dd16722ec53baab92a140127d61372cbf1850f2fc894e942e25d780778235f880743953d04eca7a9205602e388172aec2abf35412b483490751f93b51239b6701cb0aab14e5179b0d7f55d8586358381dd83e3e436bf69a6820317d1701750cb1fea1293467ba589eec5f5779c2dbf2a9b8f28c4dc239 03129e96fd28c4198cc5242c1e3531a3979fae643d527044e98d7721aa56b5b4b45dfddfa17a4115e10a2b4f46d92f81cbdd7e86e588a4c6d8c2b3a83f54cebcee1d1dd33e85d81a b02417f1f20195605fffbf7862b550efb8769398e9fec8cb3f3445d1dadec86d0d5a51e91509d9643a7ca54d82c112100e13a792bcf07185f5ee106ea483967a92ab7123c89df854eb4470bfceb855f7f94ffdc6d66944fdcc65e30875f34497 +ee592e20e0a45c18089c2e41460e65a7d22ed9714379f095d43a308bdd383128aaa6fb24e9d35fd28fc95c5b792ad75c980d2cdf0f460ac60b12c5919d3cb28dac4d488196be6c2dfe462b1b0ce59f8501692255840f5215c0fd8b74b1996a267a5e3b22d2841cf0a0b6315ef4ec7180f1c8494f4c07d5869c01fa2711739efc 03d723d2697cd07dd8444f992f2ab4a063db334034c25ea9be99fd7a1f495e3a644e5ea033a41264e0d24a911e55741d0cab80a0bd678eaec2bd1e60424d4491eb86d664900d907e 86a2c78ba848c06c952f75d4ded5e5d0a1b0d50d5777ae45ef48ebd8ed75ed36ce14833aac4839a500294a3fd2a5dc5815c026b5d96f223358a7fe408bc75ef797dadc7d1010bd2187713de64a3d095a5427196a42572539e059c433c2acfb6c +fffca41927debbd53455821441d9115db99fb31bfc69752a382f57bc7abe021f148346ee29e17512c64b4918ab2391d12d6e5643bee6b5682885dc28177b292e23a37ff99b359b9cf7578432af56e0ad1028a6cce7428980654c145af8daf09addbb3be11228d3c742defca9d3b1667f48c63091fe3307ecf72667b02e008f24 01999ab45d66cd1d3a0fe6aa43bf5ef1e2a67637d53674f6fbbfb9b582be91fc42a12cdcad94b50b0fc7ac55030de24a0b99fbc4314fa743ef4b5198bcc5f54d8b669fbed78e2e91 a02530732a03f1707cc4103c6b1c3de0d93de82d3a334e33abc90a52667f3c7e83f5ae02e823dbd10ae1f5e16458494e08ebc55e3e6a0b9728bf6ca4cf06b9bfd268e8133ca42afcaa9317dd3116c3676844ab4eabebaea9e0f830c5ba0b1d3c +a2f71619ea04f7057e6943c2cece8594b341ec3b96c3915d924f94ba13fd7aaeed41ffa0e842ade414784f1ef825fcf2dbcf7bd8263b802def45f94de596aec0c121fc06558c7bb06b9f27a9bf56c42090b5dc344e82b69c4f528d33be166764a593483f6fda0cf56e6000ff363ba220f5ea0ea2c3191615c7ae3bb4fa575324 02ce1cae0716205330d730e6bc6dbfb6b951dc83ee3b4a7dae75d057e32e8a46e22be75b5f09135452b29c34dfe81a9be2e8dcd243fbd946a0ed14a832a7802e20cfe1abfd3d6e4b 89949552f870b3fc41ce766549eec01248d656f94840408359f3cfdc808f484ce06cffe6244b326fc1dd1ce83e79351c0834ada68aa4c0f42aa5f009b24c7b647beb9845f88e8d89e2ceb9f6bd855eddc3c25dd91e5b3b5eee3691600e639688 +b60415a831eca2cf60c79a334ef2f327a76d290846ee588d5d33d0a826bb0c7ec3e11dbb384a7f89c8d180425dfae7463e0ea6497d2eec1dde112f1c1efccb532a2e2b66a28e2d36d4252a4c3b12850d465fe21bddc441b92e6a7b0f67744f7f6e7812a0603211a26518b311a5b190ed890ad852bed4f6ed13377cab3eebedf4 02c9d0fcfcee7e75c3245ba955ae04188b1033c55ec9c821d8de7685276bda3e9a93c3ae1b003e5ea722913e7b169d67b1aa2dc8cd42adbd9368672a3f81a6817bf3e5529dcb0c8b b26c3f6c2690fbee16c9cd894be08fa6cb1e2d595527f95f2b96d8ac47121a44f0fd5ef37ccc84280d3ed7ca5083a0670aa05a49019d565c317094cd61c7b27b9593a3c27cd75f6c5b1ed40ecfd452b191b734bd93c698e382e65420c21066a8 +5d15a08226cc74cf495be681b795d0bde26b19f29aca1a8c6ef77d50271ebdcb4e5fa2df23961fe11620b1c6580183f6ebdceb2c09516c8127be576496fb71449bbbf0a9d3d1c48a25024619b97c3e0d8b165897db96ae9758d13ac28441d7cbfb75b23cb423e0002046358bb6d64779974a5995dfe54b398f95f7d64fc52d96 010c057bbaa44ef0f565edc288bfe66d4f6acd8686899359bca418ba89fb690429489a37bd3c6c9f3a8714b2ca225868c6a45fee360e378a676f7ea39321790f32a4b005b81dce43 b5a5a660a69bff7cd99c2d89d581d883814cb0e154b5e5e2b9bdd20a7330afad51916c82f306dded9b4a239df16d026b002540a7a09b084c34b282a6305f29523607449095080ef257ead2c30e359ddc6522a7ecc4ee2f12924589270fa21d46 +9eca4bd88200baf61b901fca53dc1f1e7e3f83b94d58a6cc6a2adbc9b1a35fe3f8ec61787c76ed9a0d696167cd4fe46e1a0883fda564666131753c576a720125e0b712db1da0278067cb899bdb14eec08737e864544663abb1d62f34a2114be07e8e3cf56e2d17099299ce6b6d83b1a34e6153d7c6a32a72c7b1bf4583fcbcf7 02c182df7976ea93d996f3ba5d2221f3cb755cc7847bc3fe9e022fa4285046f5bfb426bafa3580beea206de36f87593ae561b4b74a03fcd61fbd0e8d6fd5668f2148819a88a650aa b1a3d206df49e029ddb9d845ffeeb20efc42f7f9cdc2b1079ea178e09616b948968eaab4d01a0d227206246837288f15170458ba69f2eea084d6955707564eed7672ad862d9d03153491e6b9a782940a9aa9aa51cbec8176dd39dcbee7239e3b +707450bd84141f3b61beb12ffa5ae89d812dd11badcdf6a88a2d50fc70e23f6d822ff4477047abc58cdfa28f97ad7f4911ae0773c04ebed1f51bb2308cf6e5712c4aaed461edd6987fdd1796aab70198276b601241f6a14225dce575830ff60f935fd9f567d1d210652e4710922fa793da78c8fdc30c273cb08365c9fc887f50 02d3a65bbe133cc98cf0eb56ee1362195968b4eab960a1d55d8b762f1361fc21348d6f275d4bea1de7158fb97c995e20b92a9c887a3e332d154667ad167acc632eb88a0ead6113a2 964ae7060a28d335c9f014a8b73e8c949bf6cd1246dd8b3c3946a96d0a6fa6b2ba656d8bfa7fb881d39a32cdd493253a06f207e5e1ae7534667955958a4bff12bbc58d89a3a268b2244638d24e1258df452a716a9446e89d8a69f07569e8d993 +d5ce9d59391cdc47ef942dd2a818d024ae3917deea8a5a4214e4db6a0c5e6b0936f3e632fdb68a3f0006e05c44b7232013e1da5f877cd197f44fd6f60c1fd2378995e9a47534948c5a09e33750f07a7165072ab38095373b07a50bc1391eb6b650ee13acd63d0352e7d9c31695ea1ec6323f9b5f57b426ace56aa7fdbf419be0 02a920e8dc928acdd56e3655b2340d4371c793e66f67405fb7a90f31e9c4ef466cc44331d1d2fe3ff7391d2576dc6640772166ef8c154a5ff1808f5dab2f03061070ec8b3f786c36 a2c4ac0296de4325a2e31561e9f8a3404008b620f607283a9590a1fb5ff1fe8f3942f8ade7c65a5fa412d0da07c8a724008835aa081ed4f47b4957a08ae32bf99e4ff2d14268df19c5c6af4e2e5dcde132497412f677df905e935fe87d2848dd diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B571_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B571_blst new file mode 100644 index 000000000000..31531acf9243 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_B571_blst @@ -0,0 +1,60 @@ +8e14f713a2c427b1f79491033994f76acbead614d12e73ac6f3f518f2052a10c1273aabe628ab38e0d3d5f8ff254802e9f44a51367bf80325b6fc39d907a37f731372864747b10749ea5cb3d3a83da39c21a7b02885a8c1770e4397cedc958e4baa21d5007569dc9dd1e45d2181709d900a394454090badbd0cd9c2cd2369aad 00f42afce7f7b3d45f3f925ab29fc3882a89c9f585177887584703cf8bd8fc572e677adfa55b402446fe1e90dc855358d92c3267c35be9674b40c2ad5ce8dbe6a533c44b0ad8d2b2 a1520222b6fea7b74c58f9b46c2a2c25dbbcfd55161d0102595387ea228cc5669fa95e8b5300aa8bfd94a3c1cfcdd6090b180fd143002b5a244d85c9286c86c652e433d5a09429ceba5c96627c6afaf4700dc61bed94dd639401a90d44d0fd02 +38b60d27ff08fb191811036dbfd5b39e1cc3427ff70efb67c851e9cb407f9fac6f348d289df98d055eec73299fcac068bd0fd9ffa3c5d244659e4f714a58d79f6727f323a7ee26369000e90e34e106f99f5ae2ae1b64ee89e5a1d304ef20c071a7773e9b977ed3d49f467d300a881c8371041394910f9c366942449045568f01 02f36613043cbf53ad36e2b38998bb867503359ae082d07d040e5a10a43e06ba9c91e7c73308e41e2391b65e634f83b162cbdf4e7a44ad818fb93a978af00f06be06731d8c5886c6 b5336860aea26413808c48dddd23a62090b72e15785efaec4b1f61dc544f4df847cefff782b35c71a14a11d9cfbbd1be101b41fd535849776b94e06642e75865aafe5532d58a01513f92fb78bf67a7e72815d40d1cc816309e482febc844b6b8 +21709eeaf9e1953822294a478dfacfb205fc25f447a73a76a32601c00784cbf2f9ebd41c22721d70cdb3842dcaff4a4f208d41c0816990e421cc4b8538ac2f347cdd0aa2a39f1aa26ace8cb6a606b23f6244894d4594a0f6a5b8f6a695fd66e1a41e2eb6a377017177fec56bb58c837e311cd04c5b50575faee32606b9636ec1 02e74948c46930cbcd9dbe2325539c7dfdd910f309fd610e6599d425aad9ae230a8d4681970a14f2a71fd08030d0a40ff40dade7de1b06a80441bbf7e2fcf1809cff39c7ef88bf9f ae21a5581894846fb5a585a63d169cc9ef4f69b6570b63d54bc445fc34985e21fd8dc7843a4b24adffbd60e8f84b4f3e148e342ad42c9321375df49d8c4aa622e0cc9426d29ce26f8420a7d4984565c65cbc6410a7ee7ff0db8af95fb35ef7e7 +3a131fabf3dc97334f212fce41c44300440d16de1d6060450875f7276f53c026e2a511681b5a8d75fc0d578546339542833145f7ee13c708df33e584445a75a5538829286480d339be7c777c03c998a6d3f037b25799ab2d541021502a0b02a9b9c337a8b176c4f30e5b186485a6103b1d1563ad4ae73ca806a5e4daa92e9100 01b5fab1d36f6f6d559f65d8b01edba610620fc3a38307b1fb1c5bd63e7ffbd4a9098cb8bdf50975a873f5d047ee2b627b090897a7fb5f56d3f4a0f3528179e7c969926fc0d3b0e5 872de2185d4ad5953dd8670c87b5071d08567c0ef413ae3cba5bfc560043a42c55e593d2a505f576b0f91dfb958249820fa3d8cabadb22a79b95b395a361e0b151bdb2e3bfe4371c5b57caf103c1b86a27ae05aa2406f20654410c068b5475dc +679d85a762f2574b0b31b516270b7d33d5e166c83e91a0f48e0f3db20b52f42f9e6ee9648cf58267ffe3b713723cf3df52b5fab5c14db1e7189f7cb7170bc6ec7cc71946745e152b39180f828688a5b6c0b2957ab94283b90052a3c6e36843c391aa8810f9253b639a8d5a69aec10070603ad7a99dcedb544858d057a1d66b89 0383e70c71b431eedd4574f65d01fb0304f7744d668408c847f7899eae44770a7f3243109740f177d7146a27748886b7b77ecf3792b512e8d8e37c3bf4ecef2b1253df7066498f01 91872d8efafbf2008565590488fda7ecc342fc00fd94a8ae585be8f586464b65210e38601efbed38524ecda2542800230811da0ee26e4baf6c70bb14b3b1e3e5fccb072637ac6a103fc61c34e8a0dfe8d615fc0980670cc13431aa23507ac48d +236152ad31ce2ffc0dead3c142cf6c770672cd2e75af4a82fda1a72e1c775cec9b481c6f3e411644df7e7ee901c501405620af4b6e9667dfd46091788daa95ef2c6c9f5c240c06b15cb0df51f5f058d8a7934bd7845f007a35f99fa97200b20f3b5b14fbf1e372507f3b2f377e8d07d30fd3e222f398f26d8f428e320327f901 002261d4ead21f02fab19bbb0da8c272286704c8f0c6842ba47ded121e5cddef79fb34e6b9694f725ca502949faecfb21e3cc062a2b4c654bd542d9a1fe8d97bdd0905c510aa0999 8faadc11301173e3bb1c09dc8327af72a6727958c75273e5b81095a77499d49d775694e16cf71b03d193f2306625cd4e060d4031068a2e8ea081ae46fc0da13dc5a2d51e541cedf680f0e1430c2281969b03206950f9348d874ae8bae2786a26 +ba3f02c4847fae035d747db246fe4e82fb9224ff9cf568a6ae548f5dc2befb2079541d2cf9aaa6b18c281a05e7ddfcdbcefb25f41dd91cb3092b3343e16985e91c912215cd99ae4a099baf628e33a7b277e3c36a13aaef85418fca99f64d73b789f23ecbb76c3095ade0a5f7f34836a98c5be933b44a94a2eaa3f99b1d8e7937 0316c78f289e1860bb623082be9d9238b88e38c5e978a868bb90f776235bdff4eff591877b7f350cf14c40356922b2b6aa51d64990360b2b0e44d6941b5dd9492b4f4e1f42ca163a b484d89acc1fb9a624cab4a1cec397e7210f00824c113c9bc9efafce87c4866c18046d122add45cdae30f0f346d077200749b42c4077083ea7e358b5faad205d60fc2ae355a055601a5f97e09e9a25c1da5fc68bd5d1a8e91757a549b05dbbe0 +6d0372b40559e075af56af853cbe18ba2d471b0fc8917764abcc69102b03d5bbe1fc12458215be66409c26c89f67c72a8933677a07f88993af6918acb074fa915fe883b24bc3d191ff1b08852f07eda98977e70eba072d8bf189cd545230f59559ac05f1fa3f4e65886d0bc274a6e02e2399812b2bf91abae81e21279c5de996 02c1bc13f8320d97a82f3d9354e195481902214e16a4fd89332a0499208e91d50e5cabeb4927ba030cb42f5bc53b10f500fa646a8c88508cb0d63ebfce5c4bd574c527d686c735ce a1af553a81644f55ab78259609d7338366d87cee23d25cafde40acadcc668091d5db22531c816dce1b1be4cde6cd14d0175213e078274331ef00ad2e3cb9c8f286004b505bbdeb589d0ace70df62411513e68af97d472362019d851c45156ae8 +bbfe66c82bc060bd14fd0e40769d9b3a026eb447550dd9f118c30d8448f725f8366edef042447962ba7f7f833b9e9094d0ff600714697e632626e7d12a592e040bdcee166dcda93952323191021bd12f3b1647d0f25a41739994659dcbb19333ca30f46f539c6f0a5c354cda8969a1eda572a309950c84c7607eb8ac20163912 013bd80eafa67663e75d7ae139bf285d2b9f1e03d8e32153c73e26d06e86d7acad22bde9f121a3f1ea674dcc1fe67bc7f5398d5e92555056bc046a02b0ba86c2a0dfe32e91add5b6 b73a7e7e6b20b2bcbcdc18c7ad10606c85640d2919b4bde94f0f293d9927af71dda52351b0a7ea17b45da44cc1d673df1730c7cd3c5f0f67a16ca48fcf25ca1c6cc2a491551321358ca3824f93bb97a7916e086f8fdfec207252325d73c35a31 +b35e9bf686717ce3b16a59963a32a2116130453b161a4e7ceb27b755856add836d779696edcaee3b5c986523891c8836109d431e55c23afbca022437ad19e6777efabb6da3bba1f5f44f905395b4cc7c9210590fd38da621582d059598e5e4569e904358e0dfc0dbfda4ce75538aa97480912852bccd433a9b96c9c66e9597d2 030834b0a4284097cdda2ada6947c6c281f7290a49b56becefea1e2788ea3ef78fb96807633c47c25138341768b241164ce0d42f7301728b928be2c047f2eb60fc2f844ab77306d2 b43cd751a3ee2850fc2d8d492792eb9c07200a777690adb271842b314e119d55a9a24929252010fb1d60526841b150610cad194b5c5fe76d6b4af43082bcf08b3ca422de8c0c9d96437ce5b0e66a629efb50bff68193b10c7ab0960252f1ffdc +57b5ae7e95c638b258d1e09b3fcb4341e203f5706862e199b103c8fdac72cbc5155e5cf8b300a0b3fb0ce1f897c45f7aefcc528182f73dd450cd84d5fe9eadff3f704dc2a01b4e847c22df430efd1c66b0199f3e5b59348af5386962a5ef25204fd230b54d58d7fae801c086f8f405d3d0aa7a9a9da15c22b868817cd897d853 00c81a79ced1eaaafc31b69a40d9939f4e484d625db6364a8e589b6b4d336d458b44287ea6c6aa7661113fc07806b147ff98216fa0c08708dc9d651821b922741deda522b4e436ad 8ae938e85a757c89426392fbf114a5f258ffba265059f0f96375ddbd7eb6836ff7292b710b4e81ef56bc90cb367c238d184d160a3600ba01f98264abcbf81fae29aad6bd1e1d0c9d4c2f4a17dfa85772a6f27cbd02f4b46c7a7405e416524bb2 +daebfef74b452f039c999ba0528be3bd9e16deb5f46f6eae87b63db8b89952c949fd7db08311871eb2596865eed107aa065f030226ea675ee3256c31a3f85ddf4c21760582144e07af208f33c5f47cc026db5403186a65a47940691ea2d74ffb1245676260ef5717dd879d8b5b72d96f87fef5f762d4fd17454cb5ed83d8a11f 02f24670c0f77d2ca0266a743023d2c7413d56d0b5ec77b454ac59087efc4ea4d46179e10278e4ba416ffd8c3f9786ed202faf8251c0ef5a9ea5371fbb35b7afe3d15a9cb4bad975 a0f25bbd441472d6f773bac7310781584312c0fb12639da3b7b8264d835229f8a6d3fb673ae578951d52fddeac34f90103acc8f4305f24497aa3fe7a53f0046e356098ca91f24a2b28e5948dc11d5d6a5f91f3881607681f497d4beb190d479e +62af0493ae79d71b552c4647d1fb7ab2f282a91cd44aebd8ef344dfd77b521b0c0a3f72e4513c8ecc0e4b84efef3df9482a07ccc1b740c571c5e69cb913740a792aa231b9dc87edfb72bac188293c6c6e788cb3dff32e8f483f8f34e21ee7efec71302cc3bdbfa47908a135f6ef3ff179dcef26d1a3987f7be967a6c0f799b0c 020985f2c6fe3ea04bdbab66a8b6167e5969c073b9d53cf3c77cebbf73f4dbf75e601620ec9c3107bf3fbfc6c79f8f063409bf8fe1d14b19e323d857e23dc05157d270c7514137e4 a419368e61429bbd36c4a4fea4f331f626c5f50c0850d1d13dc9828233498391587da5ffac5ba8f20f4d87732ccea5cc000599e659762c7ca286ef327cd411f70ee9c306e5c753e61025e3c1acbbdabc1fba217147ff8b63a795f786e26ee3a2 +566f17851951777ebea3f8285610cd8ee5f882a68e7a4205e6fc9e2d66d210ee2505ee73d6503169f7b903012d43e7e99efa493a8e6ef926b16b9ad8f52156840ab561fc6b680120a88714fd66d1d0742189bf06c155e1138ee5314707173f7352e2cea0fc26e1553643f2490428718e44afd8372cbb7bf5b88234318ebf4355 02b3d641607b8a141f876f6d285ee46aea543880e772dadd5dd83d595b9643191d9597218e1d6adb081df133304037bcd2c05c24a54e6c4cca64fb2cc4569d6882315360059496d8 82eab50cfee82bb711dae8b98494b0b4179c15ccd655bc829afc5ecb85f242fe5fcd3218679b8cf5162ce08ac5dccd570122b1052559884c46c27aa3389fe4933292f20a8577a8c77ddf6c029ddc74d21628ab86b13ead7a61abef7b8bb0ffdc +25155825fc4f9a1c4dd1db837008e7e2594a879052431f5bfc76d0d2565b8fa726008befaeddceef73f3c60fa2cdf6d9a70e56d27210bd013034b38861ae49640ef208d3fe294ac4362f8eea44f58af3af8a9167a36b5acafb7ec95652d5885a0e08067ce1dfbb45a0c89ad1acb53eb404bf88fa5c3c463a0f912b5a2522a0d9 01afeb5ca87c81025ddf09c2b2c5ee22ba0105c0e619b67a324467485bd839030d149fee44d8bac6f5902a1245a50c3437046b7c89a84116b2147cddc645b6d2fd24d68e8d53bf5b b9ca0658ddb3d63f4daab6b7bd7d036dea3b32368e9dc84451331328c1f657e4c9affbae30b91bb667071335df430d19052dc3fb41db21abdad04648dc365ff293c1072f580ad84e7d0716d09c57cc979d65d87707239dd0a9cf0594c907aacc +29acb0fca27e2a10d7b9e7e84a79af73e420abdb0f80dd2665696638951b52dd39ca028166b47a3b6a2eaeceb1a11c152383f0bec64e862db1c249672b3770909f775b794e0b9b28a5ec8635a996d912d837a5f22471b40ec2e84701a8804127a9f1a0b3c96ff654700bad3167240c2518fb5dedcc1be9f56a807083e587bc56 032c97639b69c7cdbf419286d0a1b406d9b1f2886521a8b979a36118d2a368aace5b02dd8c515f2041e6fb9f026d1e82e789dc826a56d2ef732b1bb0f49be2b696ab5d3d5694a2de 8b24ca59f9d8dbcb81c3c1b1d70066b26965f4a1a853a9c4616d5e6232d590ae0e3035aa304df71f99f26a83bc1b4dcc175032d812b0e10a7d66d4ea8be28f7d795382ea4f62d08d8904c68f9a657fb4c7bdb70fcd668c099bea7073c0806ae3 +c92d67cf6536f5046e15b02158da698bcbba4ff1e4e9e9c882cda67f817210402ef917ae93682c9c3dd817b21b73c6c00b7bf92ea80ecbbef2e67f4f4379d078a2b0f297742b2bb9c3fa3297a7e8079f488555bd37715eec92b4b1cbf897640ae8a1d2a0fbcee5423ab31a37629f98630275e35094a896cc574be0a449bb1bc3 00f93672159276c5a293582b9f49607bbdb970112f6c63b2b3b5d32ad3c8240c86b1af13a8dff6502c6b6a17712cfd988f8cd23a60693d64104143b3f91adb37f852e9e11a0ef110 954c593b38b9b95a298fe68d1e492cf85e9b2dbae0458b65613e7dc42c05818838ff4022e34e6f428e4bd1d8fbd9b6bd098c87f436dc8321c4b433f0efb9a254eb106a38d036606e7e724fa110c01fe8656ac1cc6d3edf38d29ce87f559ad5a0 +15413f614c4551e3b138b64f66d15f8964c40326a42b0afce820778eee4a88edb127fbf575da5263e5a2627b5461d311813ea868e6417615e7c4938313675009caac28bc7a2f4c0bc37572d9bf36a3b1794294e09c0121ceecaa4b916df45b0dd31225415e6c87cfeeb092a008fce2c543cd62365779ae28f29fa02a15d9dcd5 03db080bc99c5fe7e06d5032167af56783cb423fae59fb5b3c6bce5fbedf56b7b39b17810e48ea9a172881aa1f42f5e267349b60294d4a208b4437666b44abcfee5a1829e9467908 b90f18b4d9fb02cad903e7846df20fd49e7bc15ed0d0dbe413be193e716e7edb1d8c5f825b67bbf4ef7a68ddd1a880ed1744909ae928068b63bf006ab5a269c33e38b20253a64a2f496a92478fcb83145650170f4bcd39d48d334ae10347bf71 +9f901557451ae2f8ec79b6d4adc794cbfd9b2e6d28f19409532d91682820205308b41498a4e1ca247a2baa8da93de95e3c0f7afd6ca46bafdbdcc6d3374a12684676a50988b86a960a82180648c8c1e38f8fd9af604c7be3be4b24799f4544ac96d6360cdb83d1d0847fda21642934fd6cf65385b50d86d4656987901fb88d0c 006ee767f6f36bb8f364f324d8346455c899a49237d759003dd52cfa13b9baa4c71347b134b24ecaee32d247c34e3787a0c64bc5d299b55c86f64b47521d22f2c09db225b0c84cc6 9846e669722f5f236baf7d4b5abf4c18da7584a765e3a2e4dd9edf0096dc669f2de78deff764e81950571e952ae29a6f1179b2e95b3acbccb4047b5b59f0904a0bb2e85d2f3dcaf2f844d8cd06f387951acddb30cd2d3957228e10476f154092 +959fe5a19d7aea2ba611c7203e19f8e3f3cc101e03a98f91adfef602c424c580d5a868659368a930f9883d699fc633bd07f6cf8de474937db0bea86fa7cd140ec2f202663813033a757b93bd72afba15be5e47a4eb93e8a666aa1c72c241ca3922547d63fa3732fec54afea7ade84302e2f044275bb67433fb6b125b7913143c 038e2571d9f22309a636586d62863ed67a70538287f3ef88b88c3c2fa1a2900d48c342b6f15c26b8e7fb4875cda4093b7de7ceda48fe1e2cc2975afe958040881de61f309931e48d b18bdec9a8dde928aca5a3e354cada9d48591db984be8dab4c3a21fc09fbccd24c9bcb25f952189d9cd9d2314889cb70150063edba26b62081953c8b33d7d846dfc708b63126aa77667424afab23ec868211df134999a95f938a8d4f5654dd3f +97b9688d9ed5101b8cfb19e84b89cd644262ca1c7ee18944e29ddd3b4cca78e06338b270385b00a5e8b91ca5e628de3bba50e36ecc695b3ea737a9cf8b36871c473a54ba17819f49e730c0f253b0c769aefa6c16366fd2dd612f330e95fb119fcf3bf7f3e254438c0ab635ec04a8b2424a05b483ecf65b74a93636fbab7bf1d8 00c8f5736f1ae65592f3ca850f43d06441aaad8c03820f3b08d8a6db46488dcfb828459f8b3f34af73cce8dc7a5e3834e085a64523d890028e194214cef4003210e6eb530005b01a b482ff3c2e751eee4b79b13fe4062a92321dd59729e34d4dd0e6c2a83764289dc6feaaff7b2b191d3a355a2caeabf33808bddd92725e37c69a41ae4636bf51136fe35a717485bb106e83699301fb5c5f9f7d11af355f112d0b795f54138dfd70 +f08b250bf4a3980cb455338b3f4173723b3f44c97bacc9cf550149794a71426e398cb4a74bde141d8b7b4a72942f1c069676a9918e27792cb8f085ee037c78e3c468adea5123c4c64d8ca6a39f2f90140c5d2d80b669cbf0d1ccb466b18ded83a1d5f042c36188a04111c34ff769abba9aedda40a87be1e24b700225e2078056 01ee68c3994adaaa9e0d61bfcd3bc1cdf198d3fbfe28a44e5dd518867ea04b20e795eadacc48bfcf8e8216dceeaa069b756e8e99ed87b6b1d31154cc9310bc3b4555162a890b0c6c 88cbf1cde7ca32e65cb65f4d2e3851dcc2da68872bca3485922cd29db0563db03631a680deb56c73a62ac26ca7bfbee4091f34bad7606363ede387ed30a92b796fff5ed1762ce8003f9325c2c540b6228856403e9116f5a904acf98b1ecea961 +1cabd16fc29d7d919622810dc8b23c770b790b98b119eeab1b20900fa94fc2ebaf76be4f5eea91fc5276c5621c8677d4d117c4a5a782ee2ca1d5b0db997fdc8a05b6b3fbb833d7a7b81c3c615c2a662929760a96feefcf89e46b563314c9b77c86bf34438458b43b694ceba741b97dfcdacc0ed57652ae62856ce10ed2690770 03a6fbf66ebc1365ea7699c72cdac2dd85907ec59cd26e2d18713354b619ccb83b7fc0db9193aa8493c1855f1a83fd987cbbb65de17c59fbe79256aa5392f4eba045346e9ba26592 a7fcb23a7787f43f3ffacb24ee5d044a9ceef6c238219a93eb0dcd98c7077cd0da5de702a5a3eca535910fa7f5c78cf517fb46a7336628429bffb8bb8b20e046cd5951ed0da288cbba4f26fff3be490ab425e41bbe2ddcbe78222643f0614547 +7bc8bbf5ebeacf40b3c82eb6eba5d994dcc6a3f2e12ef741f90f90e176d20c21e006ecdaf14cb5beef35bff46b2c374d9ee224516679b1a9e9255cd8ad8e60ed234f8ee7e0fc53c9021488158217d4b4369cc597d6053746efa1e73340bdd73c1bd2eed57b92426fd4d278d6a86e8be0f0a66ab3dfadefca8831b2f488636251 0145748871a0b5c1cee628de04a12fd68ff2b154fda96e47afaa96389d66d22802968584f6753d36618d49ed205260f09d3f5ccc2b27a34390ce58179b9834ff92a86d66ea0a97ca 8003eeacd4035aed818d0768a0accfee60f9da49145ea8598ff48d44be7515b7052355d545710449954d6e1251e8609a0cb4b6dad013df3fb053d1900613c97109ca190cd86e37866d1a2b759cd7eaf87e95232691576ee8f87055a5bfa99b1c +0cd2a45392871c0c262e7e6f036946354bb41f9c2187b8c4d399231280682f3e0a09731fbfd52c76ee63b9828c2d731f4cefee0a8c46419c398205b2ff80c67d7756db300a0a8385fa287dd37d9126f75998ae1cbab5136560592118db52fbf102b7ff0a1ed45b8a91a7d99d13a0f7fd4366392264aa1248d7324901467457ca 03c71911d24ad19c20fc1d8a044d63c9bb417abc3778d7e6234c6af79b898cbfc2f2787244708d2fe203be786edbdc4c9b12b413156b7b0bab0be8af895d191d853cd58aafe1ccce a804010e4c210b1246c79c6de275d10c4b6ac264c8645e9d4a241bad75e13dd1bac8cbe34b7c315e5bbf890e2e141fe106718918379a46026e7a547a4b2853d47eb815e2bd12512ef3ce6fa194523caeb2e889af2d245e667781aee802cffeeb +e97092625b09c9ae6e152e1cbee207d83361f34cb9b0e727c816a5ed851f12f91fbf88ad9d4c8f9d07350f5d828fd8574eafc768bc72a2b18aaf4d2b48fb10f7c3431137b51850154de9706487d69a40a8f4cb2c799f48c5d8f518aff752500de93cbb94ab04ae1e0c7183a32d79a27291dd07b5fb6e6a4fab76e85c3a8607e2 018bd74698bac36ef11add6b3e3fad227ecd868f370ec04569462565d2f0af2340bf793486953a7b79ab04f0ab1f0e4fd16bf6b576cce677d543e73aa8edb0e50372f24ddfbff966 ab3764cff780ba943f70b49f4d098c21fd0520175ce47067b48e798d0e3ddc122ccfb89f25eb8f7e366f90e3de90d665056dad38d66643982277c1eb34b4ccd1035b973d8d7960594e7e368513eb0959382fa088ea2e637349626346de5dafb1 +ae6723b8df5d6ab5fcfaa22d32fdf106d211514cb1892c7c43ca6cd85c2532f85929c8a259ed251215063cf92e1502528d1e22d5cf67efa0b8ef21e8eb2f5dff881ba1433e8bcf2b6af8742ecb2bccde081e534615a305562cc22d3398f61f277d8ca785842bda85d8a40438d9bf1aceaedcfc22c85533794a69cfc320931d3f 0335699bfd058ee2e6163f55d1816bf3669acea8b73be9c4ddfe775230925e6093cff7a66813adf22222c8376faa106d85ac9f3c67929bc58d8986795b6d35d5b9fa546dceabbedc a464f818c203d463ca8a43aa36fd037222f4fe7cac908450832277d9d352a60258a48de311330ce7b44ae69724ca82ca0b244affeff6c738765a92430e05ed4dd9d9478eb62a78c440a5db5faea4938ca138b6b3f0861289357a84deabc56168 +ee20c6b61886e02ed94359dff3559522ff550ca126fed4b2240ea7d999a182b7bb618c50528fcbd261d5e497a991fbac0cf4c105c0f664d6a00a9001c1ed522962fb44dd4159677ce8f1531019f86457c055c9cea6247086cdfe0442485cbbc4386ad002b4bd39a1a187752437f04569705cb7adc0c68f0fd059d946deb63f0b 02c3eaf801330b3f1b0504f2399f1d24455db29911f750c246ba0a134c3b59da8b3562911197764699a92ea1d95a2aac587e24f743df1dad3e1cf7edf955203e24a0225717f8d2df a128ec0ea03b63b71b8511f6ee5bd303f7cc045690197fa42afe29429267e5f785b46cf0fca0c14e91b5a2905414626a0beb634fc1f34543144b74fefced0e62d27d7e7ab7671f8733cd129134b0d4a161865e7bc1507a88e8dd3d78a7ba41b5 +734a9eb8288e32f5a67cc1d88704523ca2c68b798d90e188d871d9f50d2da2063baf1ee6685c45832a1818aabc9afc0bc935e97969dc983a484f16d2bedb3c7c0b8221408be2480a5562d5d1e5d8763d1e474bf2826aa93a68c3b870e3bf34f4941cf590d88e1f5a8cd782a33992213f3f6b4b4f6dbfb3c3c8f21f5eaf4ef609 01c3ff067497e5d387f31f0ecc9c67b3c0dd6ec8c81318c492aad83c9dec6c99e4fa47447f6f7082d636c2591d0df940b947d0a4ae3778e2b7cc8fb92214638399def894ada276b8 b63dbd4da5876ce0280094c3557d9f2065c4ce556c9a3a8738f3c5ef0879f167cdb21d38220574bc850f91e617bcd2cc0e8ed21188f54b2ceee824182c99c864efc0bedb2d16df2cde0f5ab9f34c1574d93b12343b0fb20edb7293b103dc45d1 +68e27cc72fec8f3f1f3882c6efa08efdf21d74d13be5171da35ef2855666ad2ea6919d21dbc1cb6d296663dcbceeba2fe47a2c6507d3d4a67a61b55b0f81c93412d7e1fbe15a590e342a05f55daa55f8591171303154e615e81189a523b855829a5c96621ad118f522e397e2eea05c2603eeae6e3591215e29b2289bc384d8d4 004b4e04281b210fe78d516a5b69f878b7fa058941ee9ae8cc63b061d1eb9e12c3e0ecb8717ff4623ff5bbbcdb53c48adbd9c69636506ab929c5507d7ebafae5654aad65a263e48d a41c8caae62040d3b3347ac26a6b6f9f7f830afb88eaaeab757d5245eed0fadc432c12eb152c8e9b2c4c422e3cfdfe0c0ca1a89725b852af5fbedd71bc62b9458a524e8be2c3981d86c46470d794fa67cae23cf8b994144179f36541f549bf86 +e67cecedf35058b80787589514a9c81c6b9f4bced4260411d2af75bc46b8b2c962dc9d260dc99ebbf8ee64950766efc0e394184bdc8e2891d66bd3300ecc880e9d6a3d0eb615322378afc3dba89938704e9a8d0c949d4bae9838805c00377e3fe5ec6a1a98ad7eaaba6b500973dac48b26b7fb2e1b9889f8c387de535d4b2363 030f2849a713aeac95fde5ce3af853e9d070ee60709eccf35a076567be2c43f0fa34420b0fc097ff577221275a3a56e759efc32183be2d76058a7d20e5dd59f00415114d73a15b8f 86ddef5a64b7801fb754617a51e981066041b369a91c245c8c12d55e41f722dd4e2b5560a416f3f0df89efb9819f1ebd1377358e1cd3a6364fc8feef471e1963543cbdebd5de1600dc6fd19002939e2eb6051347c1e857cbbc5cff3727dc674e +2baa1ac3f07e34b67b6af087400f261e138b070c8475378063286c16fa73578303380236a4af2484ea01ba56c1c619f6ae4e5e6ac2594c8e5aae7e7f196f96fc5d0f507bebedd4d818e77b9120e5b4bc01c7ab6339e88b71d0886631cc7fd89659bf513faf149c61eb14d55060c8dfc7e6e4c2b4ec8edaaa6bc36eca50a6feef 02ebb73d04e6e5361e20629e3ad119b33db5163ed91fd9a8aec4b774898784b6822a08992118a8fe6013094bad0be1e9bf01b27c069e4335bff7e0abd28a10443818f6b825e9cef1 8a58cfc30b7e5e7bc400278990b745b8016e6e4b98b27fc6b58f0bb353ef26900e900c1d5bdc3ca0c8ff51c8ccb8861b126f54b2deabb1ec8cbf4f9a78a57cffe16bbc30be93f128a5ce817c8d4aa691b690704b7c75f12a65f28faf6827c366 +0e640581f573068d8ebd2899a6aaeed0bf987ee11e22b05d25e88e9a1c3451f45ee3800d976f4603c18a041febef07a01086832a6f7ecd5d498d52e796a9d90758c87c36f4a5b704a39c456aaee2d5278183d5815d619c193da9fbc427d701bab0874bded848cb4bb066f56e119b637c78aeb6eaa387c41bec6cdd4bf7b2061a 01bfab717d6f6e16d9bc6e89d2ffac7cbe0f808cc8ca2eb515af7ecce5f3b230303775710a21bd25c2cc4566bb53c78c78e3774a9f306c751cc6e149929e45eef60f56c1d2388c6d b78ffbcc717da17e11540d1af7b41a50c4437f5f3a14fd19865800d938f6b9f699678781259ee1ce09417dcc7c8def8d0d2e1adf07eab3af86b304698571f5f5045e0a7b61b03d3bfcfeb1dd175445e400dfb19604a284f39cc9f8534f146523 +51a2a560ba226d629127ce1ea7e812219ceaddd23561256331458c9f11fe73990f21d0dcd974a3773040090cfdc8e0f01692d951a0cbb60f8448a016c67abf46a9c150466ac77e656ea827b0ea7d1e77ea32071ba8314fc8a2edf69008f498bd1c18061d7d00f3340a7e2cd73e9766862378d8702e804a1870b442beb2d0aa14 000cc53bf7f1cad5e3dede4b4f4b082831604c92dd2b147869cdf1107259305b1d50359647f9f3d7d4e1e608865c65dc7c9ea46bc324dcb8423b554dc369d621743cbfb592b70eb5 b20dc2c61f0612b099e337fb666996ba1d1122b46c61d0ca1f9462f6d8c98070185cc9a6438775fcc2ba50510b1374071783094e2ef5f7e7152ca2e204988d2b100557ef89d1f99675b9d12144f6b5efbdcd793206694f3e8879675a107a426d +90eeecff0a2e37df318c441df220dfea013ef29774ee92a56b213e13a798858f31e52b6ccb7599e7314f12b48a89884b113c1ba0526a54f3e9a33c940944319e084bff320cf5f391c02c731c4c4f8b05afa273374a1705d6c85337782ba7d36b9c00767180cad6422c11c581672ff631fa4c49d41b02481568ec87ea97220400 02b009530cb9d586e35dd8951ccb686833afb7a37ec253e547e85b253ba999f0f186b6d4ba41091615fe57678e9801b4dc94fa683511da25637b2acc9fe60936be15af16234c4ee7 96109a6d3ddc4698681c5e3b8eab19226e57e4acc61e88fbfb9cb32f94aa50460dafecad61a1491106a4a8a81c494132066347af4e35efcde35c621c014630e34ec18aa0f77c12a97a49cf4ed8edce3db6eb3c86c31477b02c6216d6a160137c +d3740cad41e2e365d80ae81da97fdf06d8b6c278b505e34cb683fb55ddc5189da543540914c0accd405dbf0063f6222885fda4b316dad4a83fd03e8d7b7e936f87fc0a5b095defc8a4b22fa97f00b394e672d5efd3e0a230c7e44dfeebda88641143502a400ed62e2a51f9561e5d652a43d616f16699e875deb9610c77de8e1c 02cc2d0d7189cc8fb3565a039aee7633ddc00ff427cafad32fd2010b10fe249c9724d91785e7080203626038109158e3a61a3970aa3e51688aa7f5184b22f63af63f80d3540ec023 b0c5a4205cebe96e6f7327d7892093501b37e603a1c277c862381eac6f71d82602d349117d21353ff39bccf32d6bcec20dc70ffa01bcf2b4ae7f86f20b7336eec7df6547076f3a2f5c13c65fb82f59752e524c56f634142477afcb288398ec04 +5eb53b5f92121396c5ff30e0c92da48db4fbbdbf27297f9bc82614ab78f7fd863e34096c615a02e349d8bc7ae4b0700130704bedf32756b5ee6af10da1cd717d624fadc57a9aa6db4a6c5d6254c0e8f8c3c0d4d03c264eeeafd52cac2c1968d9d85b106167a49d0ccdbefb20bdc10a2555f8149203af52853169a02db94e5e2a 03d8936c00c131e38c6566d2464c4e207c878070bbf681695a6cd98cab2c6e80fe98cda80c66a5cf584e90a071144dda59c07b8fc7bb42464dbee5b6f739b0f2ee5fdff7e5a4e7cf b5d465baec1f79e3dd51c045f1d1c5ace2873fa53beefeda31b7dda183b8150d8c5fbb4c1eb49a2f60a526ab2705d956079d21dce44fcd7d7c6a63bb4502ec88bed03b2fee7b476e944a7fa467f96ffa1771729cce7c4f5775a71069ac55a2b9 +5aced64f702a57ed7fabd045a40c967a485d2a70b0a5e82561d5141ef329469b2da5964a34df203a980111a77adca376c643b9030aa74516f054648c1534d912ea66582adf3c655dbd71ca55e47412315df5e2893e43b2e2dfe6e4dedf426f11846ebef34a99f5615460ce0475f7bc54b4a4fd99e83c982097c3136ac6188a5c 03dc7de970bce28a943d7599f2a9010fc99435b93bc4ba884d42503ac2941aa63fd07db34bcbb1127d56d6a4e277d6ca32051ea3467e376f74f98c3999d2f276b282ef8a28cf0cbc aa1a3be37a64a583ca77e2dea716bfc903ecb732b577020564cf67451bac724029b76abcc1a47a42da4d3af232beb96f15e0d664706802084ab434bac82d71a94767dba0157a9d32772f4ad2e8393457672995207e6650708e9adfc937925085 +43c24aea343d4e088bea25be69a332c631275c36677093e057de69cc83a4c5e70ab270e5a8930f55846f1a22ec10e03007dcf0942c6761e89c65c6a4f032eed97dc3a2c7f7ed1e82552fe48828a132ba16c41f6bd82a49335428a24fa1679522000e6a1d12c646e0e4b4c584398577ea9493bb334fa3cee8bfdb6c2e66f46436 02de6ee12eefa7a4a736484b19b42a513dfc059a060976edc3b0aa4b50e98d72df6506fed0499ff8480986748e938289e54a5e86c0c29733a9bcf5985aa63d8a2b57933a04a8e8e0 b8e419ce7c7f520f13fe888054699cab44f5f709f5abbcf376a8951fd73a724f633fe8dd96c11baa5e11ba57840c9d55048db5742ada46a745b3379fc10897d427a89ed843b91cf157d94d8f19e0fc3a366645618f015a1b0ca72c0e98a9aebc +e89210565959d93b483659e62cf41f0a0147ea23890c2f1a694c377a826165e363860e4b084016cda878a43eb68465f81f397ecd50087a25215ce7c4ededa3552218071fa3acd7ae380655fc8fa884998209ffc8a2c26f1ca19dfcfee455dad35a4e72caecd8da47eb9ee21b889162f5d3032724abfd1a31e68612e18bfa9006 005468f0df2c9854f5f655743e79c750fd8812db28b096d97207bae7f5aafc6b6090c9c636ead9e0fde32a1ff8d539b53813733ca812b41b58ff85a941abe4f128d59fdf9847baa4 ab41a283585a43e58f0656d030ce64609922ad34fbc8c7aaea94a4adac85283b65dfaa32220f60e72d537697cd3601f0037127f9edd48370eab6482a17f0dc0c6273a3623d7fc6cfb4b266bc02182f45deeffd211301895b0067768ed4ea3ac3 +48629ec97f56273599cd9903f8a84ac2ba74275b40e1e42fa47649568babe05cf63c8417d828251acc2eec525b56dc9082b68d51b0c2bbaa7389fbee15d058cf482993b2bedc5a9101f1afdc79989a812478245d191550109fc17215679553c508c84e3d4cfdea377088d09eb214e6f92410facee4790beeecafe72b2e3ed192 03d3c6a7ab9450c94aa3b8a1ffb678e5b647af24cbfd66ee3944e6f264f406295b803767471fc67936fdfed1714b4b8761a07eec86543b7c4da6bd2fcb33fa8cda4077737f398e18 a564bda0c6110ea586062b3bafe4c37438b5a8cb187b1b017c0ab46a3cc028987e3538a926692857d3124663e6940ce216f2dda3c08deabdd22cfbbedcb3ad7dab547e7daf314993db576668883d3a6538599a9e1bae45e5af250fb81e434782 +aa3a9fe467b1ca638dd0622c9ea235a418b39b2e15ad81fee01b6892b240783d8db3c72e16c13df8016dac6addbfb85232158325bd7432fca3b8bf5db3abd0b4c5ccd0999609dc42199ca4680692a0805cdd68108bcb493a558ab507cec0a2782a9e976928985352edb2abc0c07078b59d2fd86fda7fc76cfe573181d934c46c 001ce010ea8e6e1a0c26ab22eb90f0700dc73b232c429d36371e68e429792afb7223f10327708bcff779ea55fb5f22ad87aa054e84d10f5450f1bc9a89279062ea2173f55ab0f76c 996839a485e489c528f0098c0342f7f70f1a2fdc51326f306d28f970e6385aacd69159f87dfd5098c4c2b910e51b4b54044b1b1df33d16f6ac28c971dc4b793adcdaf9c72589374f7d83ef969179f45827f55ce748cbd31f49fd078ac0982779 +6c3937014361799f1461f652841b5137eb0dcaf01dd293298d002f27e9a770b9e1a30367e35c04603881f0c814cf8ecfbe1619cc49cd516b1d60d27de37ed52a5e1cc300e2face4669f308ebe6747255a3d386f16778e494a7cdd10b45171b2bfcdabd91b805bf24857708c1b75e368edb2874321324f83a19154d3a1578c767 01e7410d012aeef02b3723346d24ebafd684c99087ecccaea1cf3735d52c4c81dda41812c09f1e874dc964d858ca240a19963d5dc89451f5dd6764426ae41cb23f19cbfdca0fc562 865d254de8d4418ebd2a03b428a7d1672d32c41b924d257bdedbbb9369a41e598473129468c5b78c734096843027a1db16d245a9362e86a2947c699d72cbe22f288c914daee4a158290fff1cf0c22483fd49f2cc5fcd9f22ac103baa962e47ce +12fea55ffda15db902aa6a4388b9807c89c193cbf75b5d2a4c95206fa43dedc45974c80079933451bdc5b3ea015ed3ca2c54156dc61afb1bc82adefed1491302a48b9d3d2f474ab45343c611677d360515b93fb36da7a1c1b2341c9cce185c881c0beef33d43967134a190c09034ae3261f3295b79aebd3fe123616f73cf2089 02139839ce38eb879d266065dde5e5ea227244323b330e3ad5a0bc690f3c210f794cf18f0d730693887548bfbc434f48ee10ed34cb41d52172b06e448df938170a5e17311cab8e88 b642c6c2d647e8c2b11f2fc5aecb4dd23b2da9c8298f7652fc93f2e844f964fe2ec4e03d343db0047d23591581bbd7be16cd22250b6eb214683d1055cce4be433b5034178ef03d72830d54ad7c3ac03f68a7594c182a487eb962bb07066962a1 +c8395546842ddb545d8ea3db4efe970453dcb06025ac3b7a25aa5ef62070f3021b9a1fea91ff7055b6c398073e7886a6f71afe53c82c47b71377dfe291972503bbeb25bd477bf0e7adc8a5d3f8b34ccd0080d61e121214e1b29802b711cdd8a6bb2275a2395c467ec2c1571952992e448d736d8bd70ee629c75b5e32b8323a00 0274f70fe69e4dbb55c5d404e39f5196335047113087f8711f2f67f2be4964e4fbcb865680758df1c401cd677b0971654b7a6aeb7bee0d6d80ac0de14d4f46f356b2d5545c185aa6 a63b38eafa9c831a46c37924a9a20091dd48545e0a0a956a16dc005aaa4cd27e036649cf00b3000208a5529ee0efd67412c4ac505ac45daa8f06e156f1699dff5d9ff7debeed0ab84b47666813183d234bab6f623ffab4a957a327115af5821a +10d2e00ae57176c79cdfc746c0c887abe799ee445b151b008e3d9f81eb69be40298ddf37b5c45a9b6e5ff83785d8c140cf11e6a4c3879a2845796872363da24b10f1f8d9cc48f8af20681dceb60dd62095d6d3b1779a4a805de3d74e38983b24c0748618e2f92ef7cac257ff4bd1f41113f2891eb13c47930e69ddbe91f270fb 003e1b03ffca4399d5b439fac8f87a5cb06930f00d304193d7daf83d5947d0c1e293f74aef8e56849f16147133c37a6b3d1b1883e5d61d6b871ea036c5291d9a74541f28878cb986 a3dac1eb9dee7bc1129af1e2f610ff4d9747cc0ecbc155c05df0b120adb799e21767f27b2cd7ebd47091f7c30c45061810a084787b7bfd95d3d83b51722d889de3b5b14bac4de76aee414ff6b7af86059f380a1ccfc6498af63e063cfcb8fbe1 +b61a0849a28672cb536fcf61ea2eb389d02ff7a09aa391744cae6597bd56703c40c50ca2dee5f7ee796acfd47322f03d8dbe4d99dc8eec588b4e5467f123075b2d74b2a0b0bbfd3ac5487a905fad6d6ac1421c2e564c0cf15e1f0f10bc31c249b7b46edd2462a55f85560d99bde9d5b06b97817d1dbe0a67c701d6e6e7878272 02e09ffd8b434bb7f67d1d3ccf482164f1653c6e4ec64dec2517aa21b7a93b2b21ea1eebb54734882f29303e489f02e3b741a87287e2dcdf3858eb6d2ec668f8b5b26f442ce513a2 99ece6aa52104409c6510d9dbf0234d2dd3b9ba614afae5b25d397d84cad3f9a63639c702570bb43bd646a803566f5c01269f49d6ef9e1363afe969d85a45fc5c311199d6668267aa872c0b2c09d75cab907987beb4657683e19b0005c5dbdd4 +ba6be551bc60653192401ed8ff9e1acd9013d8811a7a1389528bf07438366f5772cd7aedad010c19c47622cec03a4d35b8003b39ed901b720629ab59de55a03c1ca50a62987f8da159e356245df58d5ae1936e65f3cd3acbe03ad1d0fcab4aaf2a7a947549ae776772201efbc6fab1aebfa1d99994d4f43dc28f39c0f279b992 02a69bc1df069c6e89722521a63675f318252be629e7558f3716917998e660ac960b0b750562846fe6c12ef492951e51e224754bab84a6eacd4147a5f26ae85ee4381bb14ec2a8c7 a967870e2ccba7804a71fbd012666ecbb22ba9e22fb3f2e3516cdf4eba18cc9d91bb94de4a1898894f18205f53018076039abacb465e27055f24e46694dedcfba9fa8e874fa110839922e2fb900e6bce68ea408609a60bdbe9182d2a500a2216 +295720a79ac8201f40a66b06ae5d970afb15f36582897eed25cd92edcd00f70ac8e31c556eed4375ea044c2e8b227a8e02c0a3e996c9272d52ac7b3ad43b80f217295dddc84b177cf1e800ad08bf7fdd021fb2f49b54162092f8d628679c4ee335abbc90c027264c8b288c6e16eca3172eaa297ba50626b00fe0a0ad3a9dbeeb 00d11ed1b78b22b3420df4ddc4acc7c2286d9569dd6dd88e0fa3ecae69bcced68bb81bbb4ca6e9b54e67856e7fdf39155aa27aecb9cc827ccb9cdcf9ac633561b27d8eebfc261aee 8e20bcc24900cdd9440558f9a0fad1dedcb659577f49346347176e482720f9c350aba6ea880feeb0dae5d46b197bfba916cc7bcb38a509e14b237a4b4472b853a00dd51599c52a06f0f2bdce7a4b62c6fb9a73bb9761d4669f61f26c6c644bfb +a9cff41c6dfdc4a12f31dc375a5455950077ae323d0b7a3d9a8dde73b76e9d7b94ddf9c88ae8e6c262d704052ac47681fc35adfc56c904baaa6e146eb653984369d76a85596cb744941aa7b558c945ff2e81bd5ef7f00ecb4f43af23b4cea3bd4ba7b1899f1868a0c0ecfc62ccb1d588955597ffbbaf34cab2838efc2b866669 02c36ef754b5bd065e9eadde684750acc52795be80f54dd3d7a7d743d968a18f7e404bd71f8a76eb0395f396df5a7c2ff7e0ab6de35df34282fda6ee01fe5b9b68ecb4e378dbe32e 8d0c366c7b084868c6a3dc4f92c3fa059c055d08c80a953cfd87d129885b800c01e178bc26a5089b8330eb19426bff760b6b70da5ef187bbcbce744d7ecd7804982ae4777beb34ce7fd2aff2cd0a17fcac790b98325f38c38805a0f15730d4ee +efa6c582d7fcf5e431aa89b3b00180c0e78efd7ccb0384d90b80e59a115a13e55001d951528c42860132531c9b8ab29dda7a657c53c2ce96fd85549f6f1810e121eb89961295335eaa0e40532d85814a4206e6fffdf9bff76599da9b2e71a22ed572910b0e3bae38ad72c7042579f106739a8628dea5a745168bd918736e488a 019ffee50be5496507e3ef5c40ee88a49625e46d1dd1686a52b09ad4a8e3ee9ef364f953bfcd97c52104eecb6138067192997cd4ebadaccb73c7b2560879289a46353a756b73cc43 aec3d527c4731535ca8449078e429ec60d7e515270202a0acc60413b3d58daaaef468b929f8c0aa61d2a8be84342d8d417bce1fed779b53a1ff44857aa537e1b9511bbed776176dbdc637aba70e2e52c86ce5132a4c13631553434cfc8147281 +211acebfaf13bba33a9dd16722ec53baab92a140127d61372cbf1850f2fc894e942e25d780778235f880743953d04eca7a9205602e388172aec2abf35412b483490751f93b51239b6701cb0aab14e5179b0d7f55d8586358381dd83e3e436bf69a6820317d1701750cb1fea1293467ba589eec5f5779c2dbf2a9b8f28c4dc239 03129e96fd28c4198cc5242c1e3531a3979fae643d527044e98d7721aa56b5b4b45dfddfa17a4115e10a2b4f46d92f81cbdd7e86e588a4c6d8c2b3a83f54cebcee1d1dd33e85d81a 86ca58f6a322a00e2ca54dbc6f19f1e90e34448709bae48b92b0289fd9a2b1c24daf09bc3065600d0527a4e30d8b5ebc128126a7e4a0c2774dcb52cdbf492cd108e649035531d7f2f04908fab450a580495fa3c6c4c9ed9eab95b63f26027924 +ee592e20e0a45c18089c2e41460e65a7d22ed9714379f095d43a308bdd383128aaa6fb24e9d35fd28fc95c5b792ad75c980d2cdf0f460ac60b12c5919d3cb28dac4d488196be6c2dfe462b1b0ce59f8501692255840f5215c0fd8b74b1996a267a5e3b22d2841cf0a0b6315ef4ec7180f1c8494f4c07d5869c01fa2711739efc 03d723d2697cd07dd8444f992f2ab4a063db334034c25ea9be99fd7a1f495e3a644e5ea033a41264e0d24a911e55741d0cab80a0bd678eaec2bd1e60424d4491eb86d664900d907e 878c431be067da133514184491ae57fcec94194fb888e413d1c5c297319af776e7819ccc339367c260444efedb974ba1011b1d67a6b0d41323abba52356c487b7c8f2352ae4d39ef8b6d6e670e406ba7aaca4a299ddb6e8ab0c8e15bd2a8d8f9 +fffca41927debbd53455821441d9115db99fb31bfc69752a382f57bc7abe021f148346ee29e17512c64b4918ab2391d12d6e5643bee6b5682885dc28177b292e23a37ff99b359b9cf7578432af56e0ad1028a6cce7428980654c145af8daf09addbb3be11228d3c742defca9d3b1667f48c63091fe3307ecf72667b02e008f24 01999ab45d66cd1d3a0fe6aa43bf5ef1e2a67637d53674f6fbbfb9b582be91fc42a12cdcad94b50b0fc7ac55030de24a0b99fbc4314fa743ef4b5198bcc5f54d8b669fbed78e2e91 98082b9d41aa2003a0f8cbb8278ed1e5728d637fcc107322f8097ea52d919051134d788aa6beee60ef5721525cf49d150e63c15edd2febffd1b66d25008acea8dd223dc04389b0a12bb3b880949dffdfce5687dfe5fc569b520d18ffb4c15522 +a2f71619ea04f7057e6943c2cece8594b341ec3b96c3915d924f94ba13fd7aaeed41ffa0e842ade414784f1ef825fcf2dbcf7bd8263b802def45f94de596aec0c121fc06558c7bb06b9f27a9bf56c42090b5dc344e82b69c4f528d33be166764a593483f6fda0cf56e6000ff363ba220f5ea0ea2c3191615c7ae3bb4fa575324 02ce1cae0716205330d730e6bc6dbfb6b951dc83ee3b4a7dae75d057e32e8a46e22be75b5f09135452b29c34dfe81a9be2e8dcd243fbd946a0ed14a832a7802e20cfe1abfd3d6e4b abac43f991e0ec17148b9231e920e6b6c3d4fde25d935f94c421fe245c49928a358cbf52ce191a7e0ecdff6630544d1a1009b4cf1cf919d6a5e6202b4cc2a220ae18b471128fe32c58acaf719d17582e8bc22b6acd130c52e455f3236b995859 +b60415a831eca2cf60c79a334ef2f327a76d290846ee588d5d33d0a826bb0c7ec3e11dbb384a7f89c8d180425dfae7463e0ea6497d2eec1dde112f1c1efccb532a2e2b66a28e2d36d4252a4c3b12850d465fe21bddc441b92e6a7b0f67744f7f6e7812a0603211a26518b311a5b190ed890ad852bed4f6ed13377cab3eebedf4 02c9d0fcfcee7e75c3245ba955ae04188b1033c55ec9c821d8de7685276bda3e9a93c3ae1b003e5ea722913e7b169d67b1aa2dc8cd42adbd9368672a3f81a6817bf3e5529dcb0c8b 9994bc41239ea35b8635287382a4c94bd0445e0df40c6a6b2c60a123b061e963da4cd67c00f8bb6b05e1adfef69974fb06eb0a25407537897b9879f22e958dee468d00e2d175a11505adf97387644a26cb40fef93d6b33de8443bedb4e05d4d9 +5d15a08226cc74cf495be681b795d0bde26b19f29aca1a8c6ef77d50271ebdcb4e5fa2df23961fe11620b1c6580183f6ebdceb2c09516c8127be576496fb71449bbbf0a9d3d1c48a25024619b97c3e0d8b165897db96ae9758d13ac28441d7cbfb75b23cb423e0002046358bb6d64779974a5995dfe54b398f95f7d64fc52d96 010c057bbaa44ef0f565edc288bfe66d4f6acd8686899359bca418ba89fb690429489a37bd3c6c9f3a8714b2ca225868c6a45fee360e378a676f7ea39321790f32a4b005b81dce43 97972f8e8e6626fbc678d66b7c843d3373c9dcd35ec809f9fbd4a5fc2ff741412279c32b11c581001619d04bd6bbeba40c7fe2905eec0c034fe608efd8177ffb1ac4b1a1f8de99c00468b9fbd84eaf7d87f83d9ed237e4fe393bc459400f9ece +9eca4bd88200baf61b901fca53dc1f1e7e3f83b94d58a6cc6a2adbc9b1a35fe3f8ec61787c76ed9a0d696167cd4fe46e1a0883fda564666131753c576a720125e0b712db1da0278067cb899bdb14eec08737e864544663abb1d62f34a2114be07e8e3cf56e2d17099299ce6b6d83b1a34e6153d7c6a32a72c7b1bf4583fcbcf7 02c182df7976ea93d996f3ba5d2221f3cb755cc7847bc3fe9e022fa4285046f5bfb426bafa3580beea206de36f87593ae561b4b74a03fcd61fbd0e8d6fd5668f2148819a88a650aa 89c6a1f3f0f1963b26500b80149d1c5ce6c981e09657f8c5aaafbaaa09f385d25b5b7a3f1a5088fd36062c5a88e505e80db5fc8b6f8c6f20d891b3db7737e29de093d7d126d4026142190fa506bab716417bbcf94f092ee695824509e00f2f5a +707450bd84141f3b61beb12ffa5ae89d812dd11badcdf6a88a2d50fc70e23f6d822ff4477047abc58cdfa28f97ad7f4911ae0773c04ebed1f51bb2308cf6e5712c4aaed461edd6987fdd1796aab70198276b601241f6a14225dce575830ff60f935fd9f567d1d210652e4710922fa793da78c8fdc30c273cb08365c9fc887f50 02d3a65bbe133cc98cf0eb56ee1362195968b4eab960a1d55d8b762f1361fc21348d6f275d4bea1de7158fb97c995e20b92a9c887a3e332d154667ad167acc632eb88a0ead6113a2 8ac9ab6aeee066c4be29707436858582fd3a94af65e91a1f82fedaefb131563f854f4dfc024d6b0906a666dab6626bbe11786e558f02b03a3795f88127dd19dbed885f3aced2cfda4ea5a6212a78d5c5cb650fefe625d0b2569f3332513cbc8f +d5ce9d59391cdc47ef942dd2a818d024ae3917deea8a5a4214e4db6a0c5e6b0936f3e632fdb68a3f0006e05c44b7232013e1da5f877cd197f44fd6f60c1fd2378995e9a47534948c5a09e33750f07a7165072ab38095373b07a50bc1391eb6b650ee13acd63d0352e7d9c31695ea1ec6323f9b5f57b426ace56aa7fdbf419be0 02a920e8dc928acdd56e3655b2340d4371c793e66f67405fb7a90f31e9c4ef466cc44331d1d2fe3ff7391d2576dc6640772166ef8c154a5ff1808f5dab2f03061070ec8b3f786c36 a3e04fa2d5774e3ba902150146d0dd2618a5baf06f9475d52a1c940c9e2d76365bba366ce36af99482b35815afe701b10b245c8e53ad730506a7327a17669970578926d89e72d1264aa0cb615857db784b58977bc16ef2ea59fbee4286b20742 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K233 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K233 new file mode 100644 index 000000000000..6ff8a7435f6f --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K233 @@ -0,0 +1,60 @@ +f23f784fe136c9fc0d169503d361e9c6148b0f1fbdcae0a97fae1af7033ddef25cb7489c9963cfcb009a8cbfe44a8510a64a073eb1deae4c324ceb9302008c92c69b2dafcc9077fd3cc3c7c119edc3ced36d176ceaa55ac036bf7f07f6fa215e8bb8196e59a5e1c9af4f98b90ab4970885bd7015fa26a09e03c7cf6b4b23d929 004c1d414696cc3657dd9df73ace56eda2636769ce7082e064c260be45a5 ac2b0b4ee7f0af443500670c72c311c2342041b46ddda334c2877f632174c7411242e87d7fbcf6e9cdead4c7114366791418046fc2e3847119aabc1eb965097fc0b1e05c256cf4034d377eab2796adab79b3cf6066251ca3aee7d4b1324d009f +400bcb297552bb37f2f8135a9314a35f5126788bb6fa4dc74152731ff64c5dab4b902103d85443dec20e16b1d6629930cdc2bd183d4099f0e96295a63c2fe266f5e9d050c401a8681b4a438efe53cbd8f2f43e2a31e9f88926a9c82917d873f6e8cd5ff5eb8c1ca36126b0bfc8c2b0e85a7c9e7a45f1875ca9c82019ebedb729 0027cb1d84865a16992476c9e353283d5d6a40c349a8e9179d1b1f403531 8c1eb6435debb3a6b34c5bd2d958d3a33837441ffd1ed90c3b7fcccc5c5cd9e39408e0c0c7ab447b6eb2678fb9367f6618a00bcb6366361cf22599e234c0e11342c4ae15f1674da7c09d128b1fb861cf7c975325bb3b2ac813faac7ed1cf9464 +5f74d4b35c49fa454c97c05fdb6b9f6822cf1a2295f15bd766dbcb413d77c910bd8f4147e8f317fac2300fa21cb80134d1b6f8ae8e50518c1f648a28506e419f5a6e8f05abffdb3dd2587606c7e9c223ecff4f46b121216730ea13202b59128a7616bb2fd23a7e4a5aa08641cc07b669641313febfc88d64d99447353dae3f06 0031b443f46c4b5224237fac1022ee1570173f664aba0c84dbaa4246bdc1 88b56ad86ffa33e3dab90edbd9cd2722e8469e468820ce7dacd6edfb98f10a2e524131d47eea7ca332e3b6977e2883a91224d8a4774bf4e2324c8b7113328c1050e6292a795ac7ad70622dfb892d41e1dfa9a01ef92542c4de88d8a32621992f +8f92096876d9f81bcd992369d42d0b5877ac969004d17c8627c58d8b8b7bbf7a37e8cb6afa962b9b043bbbaa5bef4a5ee38d8bd31cb5866b828265a2f4102a616f87009cd346fcb8af5519fb577c60d8792472232f33dc615655e53d2b715b15a2697b492f108b7906e1e3597c6911f8cc30c7121ae338a6b747ec368f8e4a36 0048f6ca29f35f253a4962734357c995920967b9eeff1ba5fd2080bfede5 88bf4eda1b582162f4a5ea78861e2ef7efb5ddb18cd6a0042ad3d2becf3fc060a93870f4db9dbdb66560fb6f9ef1513d19e4c8fd5d719df84d4ad9f2fb515524a2432c42fd11d4302cce137284840a6d8aac6192570e63e2274676eb3458c2b9 +3d275dbde44494c45fc15fe89e2ae32aa26426a17e923e895c7941a5582fb95df4d49873ab1bde358017f336b911b886b626b744806ab8113418473c441f1964159ded1b12122d53ac56573167588e4b55f36b8bca8c67823883a51fb6e7f204d1c6b07ea49b577bfab9ca6b8d51f72268b022e3a4db6f9d265ee8382f9b7b66 0019b940eabbe682f961d9f3d90432e347fef3910e641656825d775705b1 ab2bae85001c66edd10d72667fc5d10728fc851865b1cd0de23723adbe464bf3eaf5f06d8dbdd1b40884782b562b6fb210678719ce606596b6b142f89db96f5a59c47ea9ba91434e210b750c1fbd79f307bbe35de524938661d73f45ba644ce2 +d2fa68e1f7dad02916b12fa38f1849d6d409dbad0344438520b4dd9b77d62d39ac9ae3cdeab03ccbcfd4de703c6e798873671731c108f322b9f2a68145e3e210c9b15b879798e5c53c5022742e9819b99edabb2f44d89ae221f7a99dc84421a6905695ff91928db608f861745f17584d56e34b75c47281435b1b0b34e490692d 007a884b22e29fa9fe945e9ba13c0df8d786dc87cef0f77f069e182dd56c b6cceda7ff898e0c52556fabab6b0f1d27210182e83845d5988261a9d6d0620e79cf10916db1791317fd20b669bbfece0013cb86b7e3ca48e1bff2da75e82a2d2123cd0a95261c9d58c10f408de627bfbf279bea869d49be2d8ead89bc0a0a26 +3830f75cf9df4eb2998c7c1b5fe11c1476bcf849c3a8fa7d3d0b5bc2292e5d07465ab8cc9381c575d909e509c5dac49c78817c04e4bef18bd51bb09aa5897f21634633a5ce6d20bb4638cb6c3927351eaec7b62cf4a33956916045c392f325adafb10a88a5f86d7e41dd77908fa7284210071c22aa40ef40da6339c02da05392 005da61f881d5a0dc085bb93764f584352882923cd237d878220ec624c1a 8bf32783d15625c95d302ed5baa89be4da1f8b809e4435367b47ddad6374669799bfc2e93c471e103bfcb8b2fb5eb64a1931e2f99ba2490feb3156c0970bbe5efa7a8468b796b22014c3c654f1b0ddbe361be4d44a8dc2d5145de40a39a4315d +65b9fe15e6c35d453caa6bad39ee78a720a04b60d8a0a0f049186d2f777e48ae2d657e174df53edb7beb9f7d8f21904ed674add0cda5b62a7308de76c324a144021e8c6d387daaba4ce48bf7dfe9c8aeee2c64e434ece1fa5ddcafcf3e5d0013a1eeec1742a00d384cc2ec0d7eda83bb4dccfb0e57045ebfc27a4f404d03da37 003fe9f04647f6d82b13ec1ae5a8c2e49bc66b05649ad778eb16149ad83a 89bf5a1f8f6074519164016eeb11580aed8b5fd79477d73663cf6a626f7ad7434bfd050a7f2c286de16cdf5ec2281fd1151ef5a6b5c46426a245df583e0ed3b24b9119d1bbc1ce41a5f766c4c8d7af07e053e96e90e3db6064055a5f01ae6aab +d26521fd41eb5d46ece6836e188bf9cb1b461d011c41e002a935d256654d01725378e845920ec4a7fd3f379df54772493df50d312c7c6aa4e909e7b83f2442c3a5e85c37d68aa015098ecfb0a5e077370f4576f4bc63bf37e1dee06d780a3b6949af5e21c2a0960fcd20821ef5f17bebf5fd5b3bdda260842cbbfad45667287a 005ebce648ace4cd555413de6a456fc487d14bf4b0b9a72311ef480d2f26 95f55a19f773a8970b3103e2ee7b4e736f49a97d2cd5a05b5ed1933abe2c056136b7bf0c53fc9a407e3bd5430ed396b912545da553ebb1e5a0a4a5272c56a677fa4581bfeb6ff0c96eb8be5b1ac384a947f5897c7236df6a17fb94cc4ea4c2e4 +b778c021b1a92c41dbd09963da07018075d73e54d62df5c2b7bf8abe137151650d1c1c6abce7eebd8f32e8c3e6d1433773f257bb3ba4a4fb6a02c0db1e47d03c27d3a90898ebd1927c21df24c4c5443ca5b81f8ef2cc0f5e8b3d08f472bf07085df737adaedec63d99acd77b87ba98225f198b791124ac2d9b191cb9251b4b00 0056653c2f85593f789a926ba49fa3da9d7f946d8f1020508c5a527ce813 85064fb78b75b002dba924018c53124bb31e8d40db4eb5973c395d6ffa8268500c2d3d3014d201b85eb8ff442e81300f1413246ab50bb0a599525ecaed55fb961ccafae7d954ba36edccf7b1dc541a6742d4a42eed8c417309a83d74393c1172 +ec14e07f615960015a489ef999e308b42a4c571473b9bd64b433dabd9a1b1ad02e33eee9100064405175928a94543a80f440040afa2965b4e5f95f768e7fab6d3c0a5f5e1bf1df7822f78384e80f2955ea85f044ac60537d895747979f935bb0cd3673193c4a32dd7803e48d7daf70a71bc2aa97236615b6411e28fc9a652145 0049a91d320783cc70a5952c32036cfc75d41f1aa84127db2dc759fb291c b11e72b4bc8181cc4a4a0c4f71293da64122c491f8f4b4127764ab89b3ed09fe175b7a9a6e1ad1c080a163319569cbc703785f220ba127fa6ed482eb609fe0977dab484f44a65bfec6debceabfa497dcb442cc62b4bb76f2b5f6f16133b26e08 +89c645339ad0eb850e4e2fe583cee175b35feb02ed7541d7e9aace24cdd3939584f73ad39526de6399c86b36de77a018e2c70b532bd0f032f9137d10480acc30c49f9baaa86f9df0033b77e98b485bf7a69cb5c281e527d3ccd1fce2415f0dda4a268ce68a0a34b16afda54ed922cd6810ac8dc766df2a3a6c5e55972e9786fc 0016a20016602fc7088a60469843e1d29ad67e3c3cb9500b1e2a00d4050a a773a1d40619c974d6ad22048647bbfe4897088e1a3d57bb00d5836ad5695aad68921974f519dab45d980e42b442734e147107abb656a433fba7ec7b9edb8529d4974059b75afb6325a123a8777e1d2592a868b6a9fa7338147c87aaabeda3b4 +ace14c4b101d2d8453c2bc22b756af016b5de537df9c3e639d208ad04ae0bf6232dc90b90c33228dc85de956db771ffde05fb4d0b15e4f218ed2771d703ae5bf981252a5bcd60c16f14483131a481cbe04dc0adb1fb8aa32cb48bb5008e8a8e5c7b7465be2fd7afbc811cf5ea6293b1a464669b49f55f57b93a8707e6042fda6 000ba922149bada2551b7be1c3df076f3f97ce93c13c50c285fef3f42363 95178b9a697889ac3b05286ccb5de281ba8a06956a65394c94a9f0939c58b9d5868f839dcceabf3740b7821f092a6d12066f45ee8bbc5d6c5d78ff3e8a0b777e03e7ff62b5864e7f624a781732b71374218cc12ebdfce2d13366d169eb0aba1e +cec2ba0d1772c87e87d5bbbd67220692bea4301aa1a66e8dbdd7e651d45c26dc2a0d45cfc32c34d76ae3e1c61db7b0fe1863457b93937d929e6ece7462ebd16adfd708353d6f7c27aafe06593c76da7149b0cc574a4290b0d8fe219f3eada7082aca38dba3f78ed0d5942d095fa5556fc8bcef331ff0a6d5d1f4e6c51d4ff5af 002d635e12a58cc6dea44e71e87c37f91e8d08659f0b7955d24f65ab55ba b31828c3860df6eb18888d43fdcbe7ddccab06d1294e9de62ab4908d5f0dea0c15ccfd1699fc872fefc992f601ffaa090f977a5ac4856aa0698992a67e3831c07396c713bb9af0a38fcfebc14e72fc9847ae50fd2de748270ec275539cbbe289 +ffa13cd0f51ae2643d5d4edecb493ddd653e9faddcffc370e7e958abf726a5d67a2ab36cef42ea8ebe22a6f01b9c31f6ffad01e6894487d979acb5e618f765ac0ec3550ac5dbbcede8f9fdbe52fbaba5c087ff382b6d7a09b2b5084227d324d98ff98793040884799b96d2ca593201f4414f18c43b51c53c5e5059e0641aca02 00073883e5064e06814fc4de32e15f7a6cf825d2daf6eb1df8c83e25d80a 8c86ef6cd4964626cff3e5a5eac814e0e5efb95fc77c6b599f10c6d610d2dabae4a611cda0b2d02a37284ca772c7f0b416ed20915674691f7980c8bbd8bfd3b51aa5c3f5aba88dc6fb459ae567282aced491616393dd3e952fdeb1e41e53b950 +c73e3dbac9513d0361dabe94071faf03a11cba18c06d131a172d5f0125b01a5eeb6055bf72c7106fe3f4be3bd2b1771cbe7f85366dccfbc3bac20538510c3f51179cc540ddafb2f3b05a0d276899674ab1d7d8fb4f6838f04e4f9e26b8c6af31540f63f4953c85840af4c57dfa78c704f637dfc8dd750fe45e2c1e149986d127 001532271bfae8d4dfe60f69b88d3006d58e28aacfa701861cde8d624db6 9763f8c93cc5da6d3bf671bd1d174636507b033276bce576feb3b509ccab82f80f8f71bf38d0c69db7dd30de73129b990b09014865da70582b77b87699d38bee103d7f31abf4ed842c19376607211523aee7019bd90b1b5bed64e4ceb19d4407 +d00dcd0f3212a3167403abed91c20e76f5e7a7678a4fd970f944d11e6a8cd149d0aa6fd3164c5a74c0f55193a4fa3d8ba6f99cabed10544625a7bd92b3e0b46edbd4a269bbc10518c5268c3910a2aea567ccd32d4c7a0cbef09ea42c20b636d1f711d220e23dacdb9d1146e0494401349749e5ed88e38295232a7effbae3aed6 00550406c0db882c6aee6cf3b6baf377375208c3e90cc44a067cee43efcf a5498f1e271d96fa2cf870857fd252022aacf54818ae435d108694c363f45e72e267f235c85f825391186898ad32ec7e175d9cf92d96ffffea1ae48bea8d86d4402037634a502f8461247610a55958b7ea62106311b30b4c54c34bcfdf9fcca7 +3d36221f87157ca4db84884b8666660c4e2b6af330480c516cded9f3bfe132543626a39bb6aed1964eb5c33ea0b95b9841665417679fceb95d199d55accfce35dd3f2283c1a7ced57d0c4b9ebe3da6e1ff2f979b6440db27caf9f6a4bbfa47e20d29ae304f4d0551fce9cc4097eb2fbedb9b24680bb17d207bdccdbe799d5b0d 00257dc63752920b6854d6c2d1cca68589a38418c3d036e73760a12214ab af6e60e5c903224f0823396bcdeb36db0d1603f0a56c7fda906d345f9ddeb0b3f9ce4f0473a5661b17e1d8f5a8475fa214a4b8617b8d244f88ed3fbe15c1bf499ede1382ce924b0266d8e5633ded6e1d483f7165719a238f47b1afcf4a41e1ab +033d82a42d0eddf58fbe3e91ddff7190e3f9fc2b1e2eede977d2c0473b358b5fce1f981ca6f88fd61ce2f79e453e3a2b77d1baab2b970ed28d5dcff58873a620e195085e61c4b8480d829525a1a944e8a4b63352f0291f0311f1f98ceb262804beec1c74947618f8e3b067866255878c2502966cefcdda4f5fa2b13d92ce7840 0029025352297a7be850f8852411c09259b83219135e0e8949c1bd5b94c1 86d8ae68da86a2a785b4f6d2cc93cef86afcd84e579ee4f8b3336be0c409e338bb8d5d1950f391e3926b48e81602e16001de7d57ecd6a6c58558786ac0e4d14adaa68d6dbfae1338114d0b0f73e3bf518a6180e1345ec526d616f1cee3c20b4a +671a7c81b64b2919722d7b258bdbd90165bb757b53106e0af03d0eef27452942f40cf52bc95cc7f6567df2613cce795f8bcfc723b2735efc35375c001d37c58480d89343697146b524835df3dbd333f7c06c98e36d3c4592ecd1f34ab57c341bb0f4c785f5b8372775f74b4bce60763fad1788e77ea158d735a64861320b36c6 002dc82d0e69e498528925c0e62a13fda9af8cefd047c10c3ffc2e41da3e 8dabbc43df61f77e4329913f48bb9d4d0e2e4d6e21feaedcf248b369e78e2e49eaed50c8b70cc111d30f97c930ed56960d1476c597a60807be04fc1f1f49d900bf15412dad134b39cb3acb71332bee310cb8fb0ed92decd3698a24e242c6486d +0ef677f4799298f4aab73b7393598041f56e902ced1726af49657b6601a06186212e3ee8cd4bd33b760dfa2ea3c38884f94358d51dd479f2ccc8b0b352fa4e44fcfdcfbb24919d04e6ee1108527b8e8d60e8d1b467c30c18c5455e5835d483161d3fc26b4a67d6df9e3ddd9331247cb18450188752a1ca219f3396a872cb13d8 0041535fff5d279bcd744b04e643458ce20b81df8a9e01b1181d52bb14e4 8b11e5a97a65f5acef35fc24ee101204f6f9f398d1439a47a1b3c97a7c89bf37be22104092a9e446d9d3596a0693cdd801647002af50db6ffc7eeac8cef31a041a378b4ee7a056a290045ccd117dcabd22f364b8a5e66f370e98621f12917b4e +9290df0cc50c3cab6655f3a6de1f4cf613d9bc06ea7c99f38038369ff2fadefa57a3c7ae7940c1b98bb1d03503cc271f7a891bf38eec93c31dcec7892dfd2e1ab337bedde3e5325ed8d9cb7fa3096f6fafc3beb3a66cba66ba826d1032debfb4908cc9dded8c0099c85072daac4373fbc428fcaa9a6da02181ebc33f0cf926fb 0000ecfe580a624df66c25e87e7689fc3b471d205970ff9ab51a64aa12ed 85d2d825ab86b434baa70e3c63fbaeaca689878955f2c0f7f4469bef4e0fc31f6ff122b3a8aa4d8d9ca8487e40a30f6413cd9d6364d2c3df5478d0dd3a0cb0457b53fb74bfdccd735c65bea845868a9ada79aef70e2cf2812455e2498a0bae6a +855c7be75fda372f062709827f333630acf28954a62a5193ff675f0dfeb63f32bca418f7cbdb346bf388d62315b19a592267ca407120db93d4e3d7125b867c4c4670b7a57a76f61734cead2caf2425eb9ff0a63293e8cd6defc9648257b401463f4533a2425e0024f1ea93365eeee3c6da20d25928602ec8b426f9b39f97f3fe 0013c72c73358ffa168423149ecdd897f0a5f75a641de008649f00134944 997fa409232a63cacbb7d9fb0de5972beaec6601d85551f4a1bf36c3736df451b9d872925eb7036b84b5865a9ee6b74b13de6b83b6b85f9316bd0b0f81d3d471a8ef91f68bef15ca04b1feb3e88570649037470c5c1c31d1efff0fdcc444a9e3 +9c896f800281812ed57d31623d563377a5c725cec84313472b90e73f77d400f5d4fb236255741b73d46f7e5254d04099bec274db8a9af5fc7cc220d42cc172cbd3c3595c49ff74bfaab7b5e46c90855b611f74753ccdbbabf92e011d52e9ba753b83ed2a251a632e1bd5c6d346e38e743950c8ce0f394a837028575fa44bcc26 000ac60e2e70b7c4cda64071c7738f68773c94df9456a8ec3bbb468fa7f8 98e3e03db8dbaa69a60a2d5c9a084a30d4ca60cfc25c1a85a7be9d9cab4f8a864e496c5b36432ec22ee4883f83bf43c8051e5d74219a9d0424668a7386cd92c3b9d40513998f48979dc6207a20e71efb88c8d302c2022b36be0ce72113b9d6f1 +139a14ead998d1a962fa47c47ef2953aa136bd912fe940709b8c560bc2a0c4bf8f3aab30a8e21b7d5f487d30b0097e3da723f11b5cb4e8c5724f5a2fe0d68ee4bacbb85e5eacf18094d2a8ec4506cf8497836a4a905059a998ea750adc54c27c69cbd0b0c1f9743a62f3d988f3fa0a9865a73fc071f526623085a2ef12838888 0060bf720052e8b9508a801340c213cf53bbecf4975faee63d4b44fc647a b2ed21cc77dd42ac5eaf71174b591b5ba6f90ee38a37e15e8de3974f1a3af982415c2252976b6f7672460a3c5ee5f680167c4f1d90e3d15f3fc6ee2c17523c922e74897f600e9eeaa9c20cead8076ebd8c12aaa278881b6b3e59986fde035dd8 +cf4a8e754b23d0fffc1c5c80b0cb11deeaba3064b315bc2cee96db5b9881baf90d30af4b69066f757b3020706def77a5fc1632d96bafba22a9c8cd3b52d535d941b3c7cc02b7fe6b51639d5e2084478ab3a29d2f5e0e16639fc2833a47b58e2c3fb5b2ea1830fe2ff68e571a8f281617a23d9a28db1c64ddfb1083d055030e5a 007cf3c216592febd8630a478b5b3e3a605084020322adb13ac0a626bc7b 96b8732929e4d7d81cce1e1c328cdebf79336dd462beeba57d8df448327bd47230c5d70d44acc75bf21f02653cc459430bba21a92906aa0cd89a55f10635be1fbc1a355b45c3840ded6487bdbd2f9711bbcc33ee821d0a421daf15e96d14a34c +ae64030d4af9b36c8d3a6af0aff34e5ab201df04274691fb420b7d5c40c401ed7f3ade96065d34f2490d17943e27156e7bed83cd7222d0d5a73d167855fbe7ff6c3ed87f20986ad8bbbd80fed5f9705c6c783b423f641d40ff1f367f9648af5a79ea3cea0236997558bd9dcb011ea4dc64d61ea1e1f85b4f696ed586bc7705be 0061eda5999e5a9ed4485d2a0ac5510549b76ca37df858ea5d95aeed571b 914e681a7a89081fd9d731ee8087e04998c561d2a8f124782dd8f4cb2967fde3371c3c927f8fcc0be1df2bf3dfc8673805366da351035e9958185af3ec728e6d74c03dcfc61fbe1d63effd662dc131eaf8ec3ed6e7798c9398397b0f0eefe9ae +94a9d9cd9efa3e4ccf2a37f904dd9cab5624ec9393cf8816ea591c5e70cccd2f105388ae133708fb974998ae61d218c71785f9eb808d1c28d953cc7eed00dd9854b6b4568c5ed5ee3df3b58a1e04c64f1c87fee4365ec9aa41b08a6bae234dc43a0bf2f61420acdb891a40f17f246972afee75a4c0b249dee0fc8f9b9c8a243d 007e7e73171e4d2f2989dc024757c186485435b82544a448f5cfca05f281 a74c7a143b7b45841ac88fabb5c0b5fed874840c3e72755ffe79c1b5b252ca13bf4cfe832f3fae24cd46cfb2ad5ba8ba13817046265f96f771a31557f10fdde421be442cf277bb3a1b5b6659ce83a34c5f95383a8e1f979d9260f31dd73af733 +4db998df7b90678b8aa4ec6233c9b4629800ad1f3e2cf8f7afcac62fc6982dcb290e44587015eca8dfe77dbb4a80f9bffe75b11e961e70deed14555db6dae47d49e73004f000eb8677c18f7e8234bf0a5a104266167a05ef07152e7acc2f0368b37efe69c0c2feb51eedf7338cf9ed398f066cf1f66bacd89ab9376d41da35a2 005f7270764a0444c7159d2db867930fdb0fb9fa6b8fc80ca02e11753095 8ab79dd2ab59534f54a919a86b8d7033854541ac53ff74a3086bdbfa4cbb01785e05add4c7757ad69dac693492e2fdc01977391793abc4e56955e83a2db3a6fd8151231df2752cf69b8a673ae4d9b495cc4d443db11171b292cf54164440118d +dbf9b8a4ae316bd2df0c80db1cb5d7038364a2634925ff957d7c03511b57d486274b2ecf191746827c325a14dc94daacd66ad86d369e3f598f176c4f0eadec7e9edd13e34043efbe0a801b75b8186b4a6d89ceae4fb250ab570d65b6dd7c04382738fe3f6f6c867a7d84b35b20720cb0036a5d81a87126f236833831d9ff00b1 00179b924afa4acf30ecbe2b3c12de533a1f9675687876a7e5e5ddc8e03b 88641e1f6a910c8b7b1161a7d83164bc2a57415930784ca7681745578b20bdda8c6724d9942ee7b8c1e8af0493c4b72901a4d099a39b14f94650723a0910adfa635c3b38d5bc9b77d42621864328f075914aa3c3ad13d0916d02c73be331778e +986d9e5d636526f4deb7545c037fe81b09c74496ddb8e42e61650c74b6fe348593f0cf8f8eca5e839baf62f17bf6ad96ec0c71dc44fdf11259dbfe7499157e402f6bd5076972354150723afb632799a990c44cd0a4fa9609ec4db133e3b4700be3ea4a338e8ba1873d345e80163ed60d0de274d7617a8382980bc2138b0a2a01 002c9eb4d392d7f2eef606e1861183acb1fc753d666225f0f154d9eda147 841559ecd6b8528f07620d4b347b9e7c66c17a479d14e8e0f039cb1baf8e92a8df963226a10be5e61bc269b0afcbdf3a0068c6498c384d2f050e04207dc8f3df9b0971077c6e01c168b14e53e64f4dc99c904b4b568f60c6b422db0cba546638 +68d0be2883598bfb1433886aff118349157708690380c42b8919859d96db069c7fde6e117a3669f2cff94a0f1b66b27b09e3f1b24d26299e11552a084be428446f3174da2e0414655bdceb38e58fcb065b6661190862db39c6545dead34a03584632e988d0459659dc7c7c78d4d00fc2aa10465cf24b2410f14e2a62173c9962 0024661c89b77b2c743cc175a6130904461138ddc4ef771ffb9fc2c8679a a105ce3ac5516812f6cd3ff5e0a8c48df6113d8d3f7010d2e9dfa522e1f368a7eb507b1374f6d7724fe8c1b8f2be4f5502eafa5cda31ab3ee0aa0e7c36ac5804866fbb9e501fa571761250ff61bceb13621f7458119af1c3d0bc30b0e0a5eddc +f0ba0407485fecd7337f4b22236533a926cc744a5f06dd08276750196f1bf7ea7984278f789f92dd07e36895a8bfe297ea43d4a1177c0368900e3b969d3083cbe626f0e27e7ab38e185c923dff46d9ba187b2acb9cf4b23ec8eedbb8044b96b5263d956e50cd6240c66d5d96517130c743752404ed09473f05d0004dc5971ff5 00065e20e5ce534576d7c17616cd4ede3bf4f500894850723bcc9f895f4b 874c637e3c418e1686f20c49fdca2c812f7d1ee0d46a9ca4a1b2103dac0bdf5b605161bbb3a73a2a65b18be456b07ab0103448596169518fceddbf7697aa260a45545a7f84041ef17cb64cceaca97ce70b154fd395f51a081ff5afce77c6c660 +3827276694e413c886129c452c9a66e7d09dee84f5f09bf34e4baa308b4627e096c7d45cf6ef45ba1d9a4019a60399feec10fa80e333e2aff1251c85ca48574d9b9e1affb9666828dff5afcef3edaf5e8cae823505a0c73afe76c1bf130399fb06b092ba34ab0ae15ac6c682f9ee8479b065ce75b57213b8aae0f55e4e386de5 0014c85f66fbbd653f1e4e590cffe62c343ba6062df4b271fbd02e5d42f7 8426301aeca20c41ef258561b45a944ea57cc5242916ae057315b7ec7139b36c8ba126eab51466b99b3d0660968444d3001be1aa9de160eb2a1e63841edbabc4a11b49c0a90ab206ff7d0acf6c684b123e628a07d1d8fb04957207e176ed935f +d1afb8965b48d66b9acb1ece674d9548f83395275f2d8135554cfcc7ceb96450d850dd874529433883709483d0743798db5e0dee955a4f30ba328c7934b8dd9207f3c336cf89141a175ebe23d2faed629eb4236a8aea8300604c3eb7704512f240fda66acedf1494a85058dc6a31bf9531958c332b93cfe5545046876c6b99e0 0030ac7a78593b570b29f6d3d267abb6ba7e5870ee1c8ee4f1ab2f141051 aa55b656484ff9e6a4cffe3af44ae618856d0d8c7cd596a9081ffc3215b3a9c290b475d6bfd962e5a8e5c29087e2e5ca108569e15ee0eb4c2b45f8a39f23b8ab368991d3895af594116a56ab1b5ef39fadb77827afd9efcedc04bfea178c85ee +4f95b71669fdfe5dc46d4b951b085e099de349fc740535175337127910acf24e9a0e4b2f23196ad23880da47b740d77d74fe9bcfdcc44dd7d8d1a181ac290de5cf4da22d5034cda3d8020bcc776dde8cef1786c9ce4d2c2cfb035da61406af745efb7ef1a55f2eccc5000319cf1d6380963025dcea641cfd15a3106751fec286 006d7516aa040f7d559cae248e485834e8d9bb608279ed4d4f7e1dbcd2b3 8d68c94d357984b965fe820b8137335c02f3943c318237c0e2b8502ab522c450b6fd056407d584fce4d2843cd192380404da0f27ff43de522f220a059c30feef33e782aa96afc5ecf62876f57a00fd727497fa3f788d10b984dc30142fdb670f +2ad9e17780c824c4f2d1e1cbf19ab85638f2f71cb4fa3518f08085b8b358f54d4f08394a5ac29cbb3cab828c5f07f41eec51e6cd61a5f2cf44dbfa46834370cebdeb328fd3bf681e61011b5c2ebc8945ac7a2a8467606051008b15c89390e111999255bfe28634ce9bc2850a2b55a4af1c4c2f94403c78aba1ebc87386ab7b32 00137050d7b455f43a8dc2516cfff5a91062c1a2727b27df41488f3dcf18 8dd98c40d5beed598cf877c45b76ec1a3f6a8813cacbac9b12df3114937dcd74cb39f4e88aba1607276bf0a1a7b1fbdb071c3485ffea204e023af9e1ab1d91b9ae3616bbf27fc1094aaf32d61bdbe93a346fa56b1b6285f0f17a754b0128f75c +958773c37d3eba003aa5c489f72118b3022c52b93399e9d8001695664918b86893f4922c7b6e55b1855ed0fd1d8de5dc61af403ad660fec60d7c44bd0102c069957ed804d0d416facdc1a95355ef58554606579ef89b1842f1055cfa2ae118abbc485356824cc09dddb77d0671cb3011b33bc86cac526e3f6bb3293c7bdca1ff 0001fd447b33a2ee3595b9f885c290d241422afdd74c3dc4981955a7e9ad b4bf55482f6bebbffe912f53b8ba7f5808efdda1c00be0012a585cd93760c5a7ea0c03dcfcc39c3a0b5057c26aaa2b6107f7a086e3d15a53305c5e44bff3e23c12773d494d97c9466fb3f8212ec3e2e296141c569906c7fb89b044fd150dbac3 +9cb2c496b1bc7f040228571e005e7e936e48e8f469e295edf914f5648701249a20bff6b98b5e862603dd9f12bb71c160aafe9df02e2e383e9b8a9a9d700f4425ce408feabbf754be543f52204c849fed6c9d3e36e03dfbd9e35c18d7bb2295f1c484a66e73440a0a5aece5fe80b9ade9321ef18cde3eb2db15e4b18e788b0441 006a061e10b4a6e7001d95411cb31bdea9c84670a59ed61b14fbbb05c8e7 8f4fe5e01c3d8c511b1979436169ae5641b16df6d1212a25c56270e51e6d8e9458a2ea0b9ec67994e3f908221e59a7550d27639b24f004d615391cbde768acb333e674482cf7d31a1f362ee4b46ec793872a9962fefb6d945f5f7a1276121964 +9a4bc0a029e97742ed3bca207d5912cb568e4403cda106b00247520ea02008b14c041b8c9b976294252da835f4ff27456039d79d90315abcb0b9b6958a22352672e229665457ec79571ca80447c8ff2a86e6af3dabe7427c8bdcae65e3c6746a56079ce2cf8d22235180f46646a21cd9e86032cfad874cb9c67f882fb037a13f 0027ec31ca31acb4d2fbacb49fc085f1261b0042cc755cc97f9b199e7a37 8b16d767af5923a2f969ffb0871b29477b264e0243c75500d70372a4d3f6da455620c7981e5feeba029f056ad899e3dd197edf6da71bafbc7cbf6508683447233b623747ec9a5437c144cb808fe3a88b6bd8c86e74e08c9553d6c0d092639c19 +8d89e22cf802dc68ff22d43c436c79311e705ff6fd845e77c880f399f403e6d5e9e2b35511553c978171189e288cb2200fd95f84ec5ee9865c0eb9190aff6dacf783ef200e82027fa992741876456472bdf27f2bd8ee55db15408c957a120eb64cd24d299818726a73fbb0697eba726a326719765735b37a2dcff0c853c906bd 004c6f4d88e5a4f4f83196f2dda9dcf2a66eaf94d50c851f59bfcea1d876 b10a53b0928a16cc75b54809b33f0cb42436118c35b35c7e7431528f1f80384bccd092038b322b1b420098f622e963ca05c164c6e91fb7f92078eb11a0a2953acd31db07f02efa8aaf01736cec9e72660500cc66b932f805ab113337cb0a676d +aa1bf5a79e5339fb9ef6c2817bd95725551d064bc5064d6586c5a879901adf808dc2ef7c78ec3b434b84569988db58b5e8e9782b1cbc2cc7c9b68e66f32d4ac4ebe7e75b345f654c7b8a5e650acc9f170f75b7aaa3957cce248cc69cf93faf8d72abc6fc1cfa9ae2d18a7b31ce720147e88e84f6563b2197882fe302449ac5ce 001aa169ea84365c22981bb766bfdad27e373440850569957544b0f9332a 8d96b69fd1c0f5f041f44d552d74439d264d7305e8c05425a4c5e022534c6c7f4b7f8ad3aee18e19a9ae28c04d4b5bfc1811dc2035251e18af051736a73d227ae0cf9ea786add9756e3e3b0fbe59f558292a5ce663fca383aabee2e2dc76d583 +475664d5e22cbe0da0d0289ca9a666a37270dc71c81cffac91f6229fa39315c1d55f7e0a89b6a7a07df7d391dbdf8fb7af63d2da46ecc3b60110dbcd842da97f98d2b67f562b0364ef8e1c589519024177c8ea079794f271f6d35554c0e9d0a39062383c95721b72f4e74eaafb6fbfbda02cb670a7c4c94f67b8ebc6442e84e3 004a665b92c0c33a3f8b9eb4b0ec061d40b603de36c87096455102ffe57b 844bdd24c7fc10cccfedf506fdb155ceaab9bebdb83fe76155793a1378319e86a8a820d09ea9281243505870fa2853d1102e9d7552ea8a6e709b8fe058f63c7dcc30bc2db1844bdb5320fea6c15ed6acb1da14e88cfe717ae5e829889a4f106c +9e5397d94465390a82a3c07e3ebf21b515776d18b4463aa5810e6b2f96ca61e92d13e034fa853c3fa45411f51f79df6f799a2c6906e6a5b7896a4576a4464f9e0be2b529a43e1f503fb640d79db6b68f3a3a7deac1b5832fbe86673784ff6db1f8438f7dd332cdd1e7ad9df8b6731aad1b6a72bde52e6bc62d80b8da57822c48 000531540d94823e19ab2b95cbc6e7492e1effcbabce875de6ba96f53aa9 b36c7186891037d1794c752fe7b380662f6f593961aea78ee1345ffba5366b5435e3bcfb5baad8ffdf55ea2c1af71f2f003bf9b8e55f5524bb25cce18cb5be6890ceb6055eba1a31a8ca122e96a3cf169945476825c8b0674d902637d5d38bb7 +3cc4c4192f317e52df6f8cefba6d4cd823c942aaee11b9a0ef5de5c2d181073b7085a55805e9554def8dc13eb978e7396044d4f4a14be2c7605998c062095c929b9c23b2b1b2fa73dd19a0c0af44ca4789f9841fa62dee8a5f91b3cc4b3264f5f67334c3f0772b30bd7431c3fbbf1f34318ce1889b6e8a76ce6d42079a451e56 0022a89addd8b85809e87e0aa2c038593ec277054842854de1197833a51c b128d68c5656c31c3b248fd3345966483dafdbf512d7453388d1a1b9c14680fa2b115f8c2728b69035af64d1124a53b000d61680018fbcdb955d883f4d3cd330d214cc8601987c6f55fcecb51391024bd79a01def41cc1e8c744678bbeaac402 +72cdef5bdf710978e0aa334b86b8ff4a58630da314eabe98b4d611aab56f55c526983d54d19bbbf9ddba30a84b18aa0bae9f9503e9b222f842f084db83aa39625403213ca321cc0d9c8a136c826e6ea4ec108b913dd0a9ce9d5b8c7e3af53c3876e56a2037ebd6d99f037a097111c837647bedfe4c494e4288ed6427c15969e3 001df252a11ff97b4421b3a2361db94e908e8243cd50d9179f9e03e331f1 b22b7940c2694d18811cc9f9b254dc3228924341608c46689ab4fce817cedd4c37ab5097d4b05a3e3e3c924a44d4733b05c6bf32c45402a2e295e5e0879a6fb115e03a2234743ac71414eebe6599caf4dd8c569681422332d2cdd169d831e44d +8e4eb88c0b2d525b2c58b8e00f32def90e6dd382301de49e0ac053dbc6b61afe926d85193e2c4948f7402a3d7c614cb2c58e060362b0516a1ba4a7425f1b3d09aa20d4c3c8993a387a3248aeec51e6efa8f558dbdcfcaa13ee08413227c8351e3107e9a3e3ac124224aaea91bfe50c11c1c8ae582e718f50bc5d5c06076517d6 001d7125c299ebd0dbcc050f07de931c7ad0450af590d0a2d0228a66ac5d b6c559a7bf9a228e29da5fd6678a1d93bd62d2717062728a8da4e2fd92958f3b53bfce7f8f4c596142f044884a2ddbf30fe7b3e27de39138bbb54bd7e84a29e2db48e196d7a765e25dfaa1cf289df3f8b30a35633bacb6086bee48b2d1889e03 +370fdd80f330311dbb3959666001bba61cdacf20f72f78953d946fa6cba02d24b5003f5452d535609e489b9434f192011f99f918defe877d51349870e7e75502f61145f7c261dbd2a0840926d824ebe9be3c5a77a3a84340aea930378367ed3615a47e3f792c7773f83f91ebea718a05fc62e9ed1d78629b2c27ae44fe8f8d4e 0021238e66119844b146d40e48341f522f6ac2f9c8a0b33aaf95a3099a41 a23a51353271fbcb8ed75b37f6be008b07eda95e9a10484f256f658063927add0ea9d66faff66a475ff39a37171af14a09c6d8d8d1fad6f9ed2df2cbd3e3ae827ac49afdccd09c2ef7415b4b1de580970d6969e0a8ccdcaa10d8ebf311033db7 +f86c4433787c3ec3cb1663389ccf53d62f9425274ccef05fd14b1b8fef676208867764eb98d16d006ee6ebdc27b8d9a8ddd303d941fdd82b630694cdc698bbe6bd524411907834286c94b24ee199fe6d646064277f244b7df3ea2d9d52a9dc6a33d7c8d6dbc919da0fa987a67621ef0829e48310e0ea2bb86fedcf4effc0b94b 0015e1bdfdacd87c42ed439f3e243abf27fd42e54f3ebdfb47f60dbae5fe a1b88a2542c9af44b4770566d87c6321099e4a1a84efa4c61bd40360cc094d176bf0cb5aca800f249041893083c99037063705f66c06d43a366e997c3730b5ad1209d0f0a11c59b477f2b41205b95b800570f392b54c59dfb7163ea8c5725cdd +4117d593aa92e3eae1124ec7482737cd3573fe5f0f2a5051a7ce86946a2abb9e47a0c6ea75b262689b0b486476d2ab09a20efc2fb921419b1811b51a2e15891ae9e45a17ab4b96c665c6c423fc00e2d66df5804a164f0f3c958df6f25d7da6829b1fe162a0a8cf130858c83f3555d6ad627db70cb41303cc6380f7b3fed2563e 000e09410548c17bbbf28a68c3963a52d39743a4f1ac28e6dfe7a6ede281 b3a92f25fa5eff7e844b8d3924139a3db4136a25ec71fbca0641840c4a5ad8a1c02fce68f0b2aa2216e608ab50b275b6018b11b20511bb3496fdd7472dcc3a7e485338e0c453c8d58d5cdde6984a9a0a2acb6d6a03812e77a7f7b259be5edbab +882ecaff3ec8f4023df5397167f238869f78a5c499be19aea85c7486e73f66f0e08e71cf85f3f1b6f6a70796bf46a18e6b555a0a87c2088640ca73051b3dd59ebfef922be0372208fce602d8001681297b285701dbbe24ccb42541b5db4aac1a1c7f407e11c83db15b38cdbc25e930fdc6558f64d9503e214571a435d890169b 0049f5bea6e72d98579b78cb07d89f64503f8759dd7a73cd73713c120428 a1486f2fdb961ca91c00fe1ee34e2ccb28b53f1c0f20cd67dfcd536198274a3c0214fc9ff409dfe9c97987271671bab60daf87c65dda2fcedffb011807d21ab3504a250efebaf638874e420b0c58c2ebbf8030eea9fda84e932786a12301b70b +99b3b8f876f8359bd6369ce84f9261581c52d744b90261a1427ab9e447e6d833b6b3e89af8dc770f1dd55692d01c8bbc4277a729fddfa7cbdb2ec99133201dde44ac691a77904ca816feb0a1aaacbb9fba85048bc63d73506eb908ecd697caf582747051a3a38ac8930c9a4365f407ed94ca7f2d26913c53f4c010c7ed9d7ca4 0005eaa818690d1ca4838f0bc667be5721d178c3869884260fb230277c3b 8933d293b71cab5c8bed8bdd4ae88fe72bde2fb219b3e3b8b34094a8e89177fb65b8a7c9403742b140b83fea4a2555a50c919f0c1c4c23f7b9fe7cae0f2a400091623887ad09126bfaef3c5b3b1996de73de8b3bd2a8c2409d5b0dbf0eda51ad +8c1a83023930a85c5b2f9930521b8b8963d5523a3323d87f862a17d3505ccee01246ee1029b8b8c2b608772c4096d1e914cb398f027d91184a8e94e4feeae121eabb504a2a35c8bc9294edd15ddd979946c14c792ad787dc2d4deffa284830fc90b3f8c0ced6a99fc6de7c41b9ed261402a6b3d702ff86a9392731ecc37430c0 00603d89cd2f741d734587e77554fe6bbb1e5739d5ff73084d4de8ed69c4 8b2ab0fb7e6d5702d11f0ff6b1b3a5702554cba98533c90042e74139f0ec00cf473ca2442fbc173a91c81b50f0daa88a074a834857668a26fcce89abcfd768dc566f0f65cc2d51a498e8b1d9cb6c775c81049ea337f06bde47e60d35e57c7f9f +f3c9dedd7115339dd3ede7d8d06a44de66bf80b4888ab7bc386cd40a92789042440a13d2cc90dbcacca5feeec1e0e3c51724146e2c4904ed6b05c7b4e9b49d7f458ada695c5d2fc36f1193329b87c1268aa38eda9151430aa0bc004e5d2a61b9390accfc699f2efabfec785eb34f52b1beff1e4c5492e922acc348667d2a3986 007977b3aba53616dac27b4d74930da23966a88ad98f1769674789c0be3d a8ac27504617effd5199ee09675f955ec8b45f4551c38f5e2ebc78fb96ba9c915229235ce102e8dc4203d98275ade66d146c549271dc4cdbf3a0b5d5fe4e66a95664427e37eb79eded781daffddd74a646f57e87bc13c7d136acc4eda0416304 +d878c4ee0bd6c84652d7f9e68df7b90cc78776d8d1b60f3e4d7465032bf401f1527ca7bfd4a3dd916e13e93fadaa5e5f20c9f47d12f8fc922a9a3aaeeeef294c221ca1adf7df85b888faec8002f17ff202da1be837827619904121167bee2d2cd694a263d9a99062cada3399dcbfcb283597a96ebec129c65e0850ec4cb4e2d7 0050cd20e7eabd29008cc977d0a17e1195d79587b8f15ac2447e15daafc0 95c3040355199510d052258b474aba7fe8b014bab6c4f35a8302a72218ce141414664de2d999cdec0a7b766f39cbb3830193d70788e46630586502699f47007f75899a32a8ad9319dc4f53e8b5061f915300b37e8d21295e4d90c8654ab4a557 +ac3c118cc9cbc8eb3b74d8ccc9ecbd81d1996fb25ca43c8a43bffeb244f722b93c9e969241d45d5b81fda0b399f1e3623687190e428dae077e54cad1eff75ec2f7fbb9434bf716833421bc2634885677579c237340f76787b2eb19b446d56c0f2206099b81493349f4db0ecad0e2dbe85dbff7d7070abb3d3b12ef0cec828af4 002dbb24fcaf9f3cd5d50d209937f0e2d134fa20ee3c9c2f1fff3dfbf302 8e764fecf6705fba1a4cea49dba469826b07e2fe7d49a2c67a35e20667d7d40e5a991abe93f2149961589678ef1661f80447583ed004c570e24dc8b72548b963c513e571d29b339a0de1efbc570d2d690ddfc6c08d5c557e3b1a4ecd27edab20 +700313698cdfdcf0044ca07bf9e5f0702ece7cc66e35decb28d5f8cb7e7e5367a95cc1728a90cc9a53a2b5fcd4702028b742538e9b386f5d8b4a2411579ed9553021a95bd00a73f03c4184a6145aaa367e3af76659d677fe7a2e98f9ddf4aa20eb8d1a1db72c3f5590598801be7ebf44255fd7376d89d998b7068bd1296fdc38 00047142197d3d43fa46545b547968680ec81688589d1ec8d7c7e90eb969 ad4a40f0456988eaf977f6e44f3bf70f7ca9a049b7d4ef7f2d31ad174e1562b46f14a72fbf6fc47139f9c10fdf39ad820aca024a8f48146865ceac87396aac65598acd139130e7795e7d2485bf58fdadf7359d1ac7d9b9d4f8a94e777b7f42f7 +0374673e1a685bdee55504ce3cd333f70084dd4ae685464a16924eccea34531663fda60229166478b30193459a3113253cd6494dc26154156252dc6e822552c7c04d790eb9f8fcef2ea8dd79e72f881f7f20fff93cd73ad303c0918ec27c6486c4da61f82bcd55422d16650cc68bfd4b0132c1e7075bbf17dad919095860d445 0031352b49ecde5434aac05f898e6ce4337304845d748f114c14319fe97f a51de6a968036b0b94172c97f96165e8b9cac1d4638242c4840ef395982c99028952eb575f28d3a64dce5bd2b16ed33405654161e1de3d4e226268a9009f7b2572950c0f5d88e17d06a23c579e695a6e2b6fb338f0cb841e831a879dce2548e5 +8b237085f135d6e94592f8d855ca397c8c1028236a3b412adefdac888245874f586d06950ee18118f751bfe26f4c31465ec34b578caa44cf1b7109ac4f6eab7f97ff9699b34271df035d3bf58a2ed4bcbf7577cf8e5792b1945ebb9389b680baeb8518c8fdc5540e192aa4fde0eed0d7c82be2e362b286f582d65752c8db7038 00176f124c24e4420f6e726a6ca25f09dfa0c5a37e5bf879e7bdd36c3b65 b75a440dfc2e2e69ebe645de03d6353b6ff275fa3754b16ca18dcb87fb7752e8030a518cc31ee59eb9907c08a41de875172ae6cf8d0ae1197abfd4ac61473f43f359b9f242520bfa2b776d422c1c184a2d2d62fe20e0d7553fdb26593c7ee266 +e3a086ec15574f7017b3cd5f5a47ab7a73980f11074333490dfe9f8ad8926f9ea7c82271aaa74e77133b1025b0b22a6900fbb71251bb6549341a23d194e79d03462cdad52ee0d1b6f5d0d14e1136026961fa3467ccf0864bf7ae3fcc3b68cb35df7324bd9bbe58fc8aa9f63c19feedf19d935b71bf5981c74fb2a487f84e453c 00755c48c3dbaf71042c58cb137f3632e3cf9d90b7b9a58fd378feef3d19 b38e11cded6ed28c428f434ca615e9b508fe694d9838c6e0c348c9f06b73d091fd1e0fa3993a4b59650ff7d645a36aa00fee60af9e2acdad796ff369cb1c520994a0e4dc0f4d90b895a827b5358c66bebba354144f1202183a0e8f988f63676d diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K233_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K233_blst new file mode 100644 index 000000000000..6ff8a7435f6f --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K233_blst @@ -0,0 +1,60 @@ +f23f784fe136c9fc0d169503d361e9c6148b0f1fbdcae0a97fae1af7033ddef25cb7489c9963cfcb009a8cbfe44a8510a64a073eb1deae4c324ceb9302008c92c69b2dafcc9077fd3cc3c7c119edc3ced36d176ceaa55ac036bf7f07f6fa215e8bb8196e59a5e1c9af4f98b90ab4970885bd7015fa26a09e03c7cf6b4b23d929 004c1d414696cc3657dd9df73ace56eda2636769ce7082e064c260be45a5 ac2b0b4ee7f0af443500670c72c311c2342041b46ddda334c2877f632174c7411242e87d7fbcf6e9cdead4c7114366791418046fc2e3847119aabc1eb965097fc0b1e05c256cf4034d377eab2796adab79b3cf6066251ca3aee7d4b1324d009f +400bcb297552bb37f2f8135a9314a35f5126788bb6fa4dc74152731ff64c5dab4b902103d85443dec20e16b1d6629930cdc2bd183d4099f0e96295a63c2fe266f5e9d050c401a8681b4a438efe53cbd8f2f43e2a31e9f88926a9c82917d873f6e8cd5ff5eb8c1ca36126b0bfc8c2b0e85a7c9e7a45f1875ca9c82019ebedb729 0027cb1d84865a16992476c9e353283d5d6a40c349a8e9179d1b1f403531 8c1eb6435debb3a6b34c5bd2d958d3a33837441ffd1ed90c3b7fcccc5c5cd9e39408e0c0c7ab447b6eb2678fb9367f6618a00bcb6366361cf22599e234c0e11342c4ae15f1674da7c09d128b1fb861cf7c975325bb3b2ac813faac7ed1cf9464 +5f74d4b35c49fa454c97c05fdb6b9f6822cf1a2295f15bd766dbcb413d77c910bd8f4147e8f317fac2300fa21cb80134d1b6f8ae8e50518c1f648a28506e419f5a6e8f05abffdb3dd2587606c7e9c223ecff4f46b121216730ea13202b59128a7616bb2fd23a7e4a5aa08641cc07b669641313febfc88d64d99447353dae3f06 0031b443f46c4b5224237fac1022ee1570173f664aba0c84dbaa4246bdc1 88b56ad86ffa33e3dab90edbd9cd2722e8469e468820ce7dacd6edfb98f10a2e524131d47eea7ca332e3b6977e2883a91224d8a4774bf4e2324c8b7113328c1050e6292a795ac7ad70622dfb892d41e1dfa9a01ef92542c4de88d8a32621992f +8f92096876d9f81bcd992369d42d0b5877ac969004d17c8627c58d8b8b7bbf7a37e8cb6afa962b9b043bbbaa5bef4a5ee38d8bd31cb5866b828265a2f4102a616f87009cd346fcb8af5519fb577c60d8792472232f33dc615655e53d2b715b15a2697b492f108b7906e1e3597c6911f8cc30c7121ae338a6b747ec368f8e4a36 0048f6ca29f35f253a4962734357c995920967b9eeff1ba5fd2080bfede5 88bf4eda1b582162f4a5ea78861e2ef7efb5ddb18cd6a0042ad3d2becf3fc060a93870f4db9dbdb66560fb6f9ef1513d19e4c8fd5d719df84d4ad9f2fb515524a2432c42fd11d4302cce137284840a6d8aac6192570e63e2274676eb3458c2b9 +3d275dbde44494c45fc15fe89e2ae32aa26426a17e923e895c7941a5582fb95df4d49873ab1bde358017f336b911b886b626b744806ab8113418473c441f1964159ded1b12122d53ac56573167588e4b55f36b8bca8c67823883a51fb6e7f204d1c6b07ea49b577bfab9ca6b8d51f72268b022e3a4db6f9d265ee8382f9b7b66 0019b940eabbe682f961d9f3d90432e347fef3910e641656825d775705b1 ab2bae85001c66edd10d72667fc5d10728fc851865b1cd0de23723adbe464bf3eaf5f06d8dbdd1b40884782b562b6fb210678719ce606596b6b142f89db96f5a59c47ea9ba91434e210b750c1fbd79f307bbe35de524938661d73f45ba644ce2 +d2fa68e1f7dad02916b12fa38f1849d6d409dbad0344438520b4dd9b77d62d39ac9ae3cdeab03ccbcfd4de703c6e798873671731c108f322b9f2a68145e3e210c9b15b879798e5c53c5022742e9819b99edabb2f44d89ae221f7a99dc84421a6905695ff91928db608f861745f17584d56e34b75c47281435b1b0b34e490692d 007a884b22e29fa9fe945e9ba13c0df8d786dc87cef0f77f069e182dd56c b6cceda7ff898e0c52556fabab6b0f1d27210182e83845d5988261a9d6d0620e79cf10916db1791317fd20b669bbfece0013cb86b7e3ca48e1bff2da75e82a2d2123cd0a95261c9d58c10f408de627bfbf279bea869d49be2d8ead89bc0a0a26 +3830f75cf9df4eb2998c7c1b5fe11c1476bcf849c3a8fa7d3d0b5bc2292e5d07465ab8cc9381c575d909e509c5dac49c78817c04e4bef18bd51bb09aa5897f21634633a5ce6d20bb4638cb6c3927351eaec7b62cf4a33956916045c392f325adafb10a88a5f86d7e41dd77908fa7284210071c22aa40ef40da6339c02da05392 005da61f881d5a0dc085bb93764f584352882923cd237d878220ec624c1a 8bf32783d15625c95d302ed5baa89be4da1f8b809e4435367b47ddad6374669799bfc2e93c471e103bfcb8b2fb5eb64a1931e2f99ba2490feb3156c0970bbe5efa7a8468b796b22014c3c654f1b0ddbe361be4d44a8dc2d5145de40a39a4315d +65b9fe15e6c35d453caa6bad39ee78a720a04b60d8a0a0f049186d2f777e48ae2d657e174df53edb7beb9f7d8f21904ed674add0cda5b62a7308de76c324a144021e8c6d387daaba4ce48bf7dfe9c8aeee2c64e434ece1fa5ddcafcf3e5d0013a1eeec1742a00d384cc2ec0d7eda83bb4dccfb0e57045ebfc27a4f404d03da37 003fe9f04647f6d82b13ec1ae5a8c2e49bc66b05649ad778eb16149ad83a 89bf5a1f8f6074519164016eeb11580aed8b5fd79477d73663cf6a626f7ad7434bfd050a7f2c286de16cdf5ec2281fd1151ef5a6b5c46426a245df583e0ed3b24b9119d1bbc1ce41a5f766c4c8d7af07e053e96e90e3db6064055a5f01ae6aab +d26521fd41eb5d46ece6836e188bf9cb1b461d011c41e002a935d256654d01725378e845920ec4a7fd3f379df54772493df50d312c7c6aa4e909e7b83f2442c3a5e85c37d68aa015098ecfb0a5e077370f4576f4bc63bf37e1dee06d780a3b6949af5e21c2a0960fcd20821ef5f17bebf5fd5b3bdda260842cbbfad45667287a 005ebce648ace4cd555413de6a456fc487d14bf4b0b9a72311ef480d2f26 95f55a19f773a8970b3103e2ee7b4e736f49a97d2cd5a05b5ed1933abe2c056136b7bf0c53fc9a407e3bd5430ed396b912545da553ebb1e5a0a4a5272c56a677fa4581bfeb6ff0c96eb8be5b1ac384a947f5897c7236df6a17fb94cc4ea4c2e4 +b778c021b1a92c41dbd09963da07018075d73e54d62df5c2b7bf8abe137151650d1c1c6abce7eebd8f32e8c3e6d1433773f257bb3ba4a4fb6a02c0db1e47d03c27d3a90898ebd1927c21df24c4c5443ca5b81f8ef2cc0f5e8b3d08f472bf07085df737adaedec63d99acd77b87ba98225f198b791124ac2d9b191cb9251b4b00 0056653c2f85593f789a926ba49fa3da9d7f946d8f1020508c5a527ce813 85064fb78b75b002dba924018c53124bb31e8d40db4eb5973c395d6ffa8268500c2d3d3014d201b85eb8ff442e81300f1413246ab50bb0a599525ecaed55fb961ccafae7d954ba36edccf7b1dc541a6742d4a42eed8c417309a83d74393c1172 +ec14e07f615960015a489ef999e308b42a4c571473b9bd64b433dabd9a1b1ad02e33eee9100064405175928a94543a80f440040afa2965b4e5f95f768e7fab6d3c0a5f5e1bf1df7822f78384e80f2955ea85f044ac60537d895747979f935bb0cd3673193c4a32dd7803e48d7daf70a71bc2aa97236615b6411e28fc9a652145 0049a91d320783cc70a5952c32036cfc75d41f1aa84127db2dc759fb291c b11e72b4bc8181cc4a4a0c4f71293da64122c491f8f4b4127764ab89b3ed09fe175b7a9a6e1ad1c080a163319569cbc703785f220ba127fa6ed482eb609fe0977dab484f44a65bfec6debceabfa497dcb442cc62b4bb76f2b5f6f16133b26e08 +89c645339ad0eb850e4e2fe583cee175b35feb02ed7541d7e9aace24cdd3939584f73ad39526de6399c86b36de77a018e2c70b532bd0f032f9137d10480acc30c49f9baaa86f9df0033b77e98b485bf7a69cb5c281e527d3ccd1fce2415f0dda4a268ce68a0a34b16afda54ed922cd6810ac8dc766df2a3a6c5e55972e9786fc 0016a20016602fc7088a60469843e1d29ad67e3c3cb9500b1e2a00d4050a a773a1d40619c974d6ad22048647bbfe4897088e1a3d57bb00d5836ad5695aad68921974f519dab45d980e42b442734e147107abb656a433fba7ec7b9edb8529d4974059b75afb6325a123a8777e1d2592a868b6a9fa7338147c87aaabeda3b4 +ace14c4b101d2d8453c2bc22b756af016b5de537df9c3e639d208ad04ae0bf6232dc90b90c33228dc85de956db771ffde05fb4d0b15e4f218ed2771d703ae5bf981252a5bcd60c16f14483131a481cbe04dc0adb1fb8aa32cb48bb5008e8a8e5c7b7465be2fd7afbc811cf5ea6293b1a464669b49f55f57b93a8707e6042fda6 000ba922149bada2551b7be1c3df076f3f97ce93c13c50c285fef3f42363 95178b9a697889ac3b05286ccb5de281ba8a06956a65394c94a9f0939c58b9d5868f839dcceabf3740b7821f092a6d12066f45ee8bbc5d6c5d78ff3e8a0b777e03e7ff62b5864e7f624a781732b71374218cc12ebdfce2d13366d169eb0aba1e +cec2ba0d1772c87e87d5bbbd67220692bea4301aa1a66e8dbdd7e651d45c26dc2a0d45cfc32c34d76ae3e1c61db7b0fe1863457b93937d929e6ece7462ebd16adfd708353d6f7c27aafe06593c76da7149b0cc574a4290b0d8fe219f3eada7082aca38dba3f78ed0d5942d095fa5556fc8bcef331ff0a6d5d1f4e6c51d4ff5af 002d635e12a58cc6dea44e71e87c37f91e8d08659f0b7955d24f65ab55ba b31828c3860df6eb18888d43fdcbe7ddccab06d1294e9de62ab4908d5f0dea0c15ccfd1699fc872fefc992f601ffaa090f977a5ac4856aa0698992a67e3831c07396c713bb9af0a38fcfebc14e72fc9847ae50fd2de748270ec275539cbbe289 +ffa13cd0f51ae2643d5d4edecb493ddd653e9faddcffc370e7e958abf726a5d67a2ab36cef42ea8ebe22a6f01b9c31f6ffad01e6894487d979acb5e618f765ac0ec3550ac5dbbcede8f9fdbe52fbaba5c087ff382b6d7a09b2b5084227d324d98ff98793040884799b96d2ca593201f4414f18c43b51c53c5e5059e0641aca02 00073883e5064e06814fc4de32e15f7a6cf825d2daf6eb1df8c83e25d80a 8c86ef6cd4964626cff3e5a5eac814e0e5efb95fc77c6b599f10c6d610d2dabae4a611cda0b2d02a37284ca772c7f0b416ed20915674691f7980c8bbd8bfd3b51aa5c3f5aba88dc6fb459ae567282aced491616393dd3e952fdeb1e41e53b950 +c73e3dbac9513d0361dabe94071faf03a11cba18c06d131a172d5f0125b01a5eeb6055bf72c7106fe3f4be3bd2b1771cbe7f85366dccfbc3bac20538510c3f51179cc540ddafb2f3b05a0d276899674ab1d7d8fb4f6838f04e4f9e26b8c6af31540f63f4953c85840af4c57dfa78c704f637dfc8dd750fe45e2c1e149986d127 001532271bfae8d4dfe60f69b88d3006d58e28aacfa701861cde8d624db6 9763f8c93cc5da6d3bf671bd1d174636507b033276bce576feb3b509ccab82f80f8f71bf38d0c69db7dd30de73129b990b09014865da70582b77b87699d38bee103d7f31abf4ed842c19376607211523aee7019bd90b1b5bed64e4ceb19d4407 +d00dcd0f3212a3167403abed91c20e76f5e7a7678a4fd970f944d11e6a8cd149d0aa6fd3164c5a74c0f55193a4fa3d8ba6f99cabed10544625a7bd92b3e0b46edbd4a269bbc10518c5268c3910a2aea567ccd32d4c7a0cbef09ea42c20b636d1f711d220e23dacdb9d1146e0494401349749e5ed88e38295232a7effbae3aed6 00550406c0db882c6aee6cf3b6baf377375208c3e90cc44a067cee43efcf a5498f1e271d96fa2cf870857fd252022aacf54818ae435d108694c363f45e72e267f235c85f825391186898ad32ec7e175d9cf92d96ffffea1ae48bea8d86d4402037634a502f8461247610a55958b7ea62106311b30b4c54c34bcfdf9fcca7 +3d36221f87157ca4db84884b8666660c4e2b6af330480c516cded9f3bfe132543626a39bb6aed1964eb5c33ea0b95b9841665417679fceb95d199d55accfce35dd3f2283c1a7ced57d0c4b9ebe3da6e1ff2f979b6440db27caf9f6a4bbfa47e20d29ae304f4d0551fce9cc4097eb2fbedb9b24680bb17d207bdccdbe799d5b0d 00257dc63752920b6854d6c2d1cca68589a38418c3d036e73760a12214ab af6e60e5c903224f0823396bcdeb36db0d1603f0a56c7fda906d345f9ddeb0b3f9ce4f0473a5661b17e1d8f5a8475fa214a4b8617b8d244f88ed3fbe15c1bf499ede1382ce924b0266d8e5633ded6e1d483f7165719a238f47b1afcf4a41e1ab +033d82a42d0eddf58fbe3e91ddff7190e3f9fc2b1e2eede977d2c0473b358b5fce1f981ca6f88fd61ce2f79e453e3a2b77d1baab2b970ed28d5dcff58873a620e195085e61c4b8480d829525a1a944e8a4b63352f0291f0311f1f98ceb262804beec1c74947618f8e3b067866255878c2502966cefcdda4f5fa2b13d92ce7840 0029025352297a7be850f8852411c09259b83219135e0e8949c1bd5b94c1 86d8ae68da86a2a785b4f6d2cc93cef86afcd84e579ee4f8b3336be0c409e338bb8d5d1950f391e3926b48e81602e16001de7d57ecd6a6c58558786ac0e4d14adaa68d6dbfae1338114d0b0f73e3bf518a6180e1345ec526d616f1cee3c20b4a +671a7c81b64b2919722d7b258bdbd90165bb757b53106e0af03d0eef27452942f40cf52bc95cc7f6567df2613cce795f8bcfc723b2735efc35375c001d37c58480d89343697146b524835df3dbd333f7c06c98e36d3c4592ecd1f34ab57c341bb0f4c785f5b8372775f74b4bce60763fad1788e77ea158d735a64861320b36c6 002dc82d0e69e498528925c0e62a13fda9af8cefd047c10c3ffc2e41da3e 8dabbc43df61f77e4329913f48bb9d4d0e2e4d6e21feaedcf248b369e78e2e49eaed50c8b70cc111d30f97c930ed56960d1476c597a60807be04fc1f1f49d900bf15412dad134b39cb3acb71332bee310cb8fb0ed92decd3698a24e242c6486d +0ef677f4799298f4aab73b7393598041f56e902ced1726af49657b6601a06186212e3ee8cd4bd33b760dfa2ea3c38884f94358d51dd479f2ccc8b0b352fa4e44fcfdcfbb24919d04e6ee1108527b8e8d60e8d1b467c30c18c5455e5835d483161d3fc26b4a67d6df9e3ddd9331247cb18450188752a1ca219f3396a872cb13d8 0041535fff5d279bcd744b04e643458ce20b81df8a9e01b1181d52bb14e4 8b11e5a97a65f5acef35fc24ee101204f6f9f398d1439a47a1b3c97a7c89bf37be22104092a9e446d9d3596a0693cdd801647002af50db6ffc7eeac8cef31a041a378b4ee7a056a290045ccd117dcabd22f364b8a5e66f370e98621f12917b4e +9290df0cc50c3cab6655f3a6de1f4cf613d9bc06ea7c99f38038369ff2fadefa57a3c7ae7940c1b98bb1d03503cc271f7a891bf38eec93c31dcec7892dfd2e1ab337bedde3e5325ed8d9cb7fa3096f6fafc3beb3a66cba66ba826d1032debfb4908cc9dded8c0099c85072daac4373fbc428fcaa9a6da02181ebc33f0cf926fb 0000ecfe580a624df66c25e87e7689fc3b471d205970ff9ab51a64aa12ed 85d2d825ab86b434baa70e3c63fbaeaca689878955f2c0f7f4469bef4e0fc31f6ff122b3a8aa4d8d9ca8487e40a30f6413cd9d6364d2c3df5478d0dd3a0cb0457b53fb74bfdccd735c65bea845868a9ada79aef70e2cf2812455e2498a0bae6a +855c7be75fda372f062709827f333630acf28954a62a5193ff675f0dfeb63f32bca418f7cbdb346bf388d62315b19a592267ca407120db93d4e3d7125b867c4c4670b7a57a76f61734cead2caf2425eb9ff0a63293e8cd6defc9648257b401463f4533a2425e0024f1ea93365eeee3c6da20d25928602ec8b426f9b39f97f3fe 0013c72c73358ffa168423149ecdd897f0a5f75a641de008649f00134944 997fa409232a63cacbb7d9fb0de5972beaec6601d85551f4a1bf36c3736df451b9d872925eb7036b84b5865a9ee6b74b13de6b83b6b85f9316bd0b0f81d3d471a8ef91f68bef15ca04b1feb3e88570649037470c5c1c31d1efff0fdcc444a9e3 +9c896f800281812ed57d31623d563377a5c725cec84313472b90e73f77d400f5d4fb236255741b73d46f7e5254d04099bec274db8a9af5fc7cc220d42cc172cbd3c3595c49ff74bfaab7b5e46c90855b611f74753ccdbbabf92e011d52e9ba753b83ed2a251a632e1bd5c6d346e38e743950c8ce0f394a837028575fa44bcc26 000ac60e2e70b7c4cda64071c7738f68773c94df9456a8ec3bbb468fa7f8 98e3e03db8dbaa69a60a2d5c9a084a30d4ca60cfc25c1a85a7be9d9cab4f8a864e496c5b36432ec22ee4883f83bf43c8051e5d74219a9d0424668a7386cd92c3b9d40513998f48979dc6207a20e71efb88c8d302c2022b36be0ce72113b9d6f1 +139a14ead998d1a962fa47c47ef2953aa136bd912fe940709b8c560bc2a0c4bf8f3aab30a8e21b7d5f487d30b0097e3da723f11b5cb4e8c5724f5a2fe0d68ee4bacbb85e5eacf18094d2a8ec4506cf8497836a4a905059a998ea750adc54c27c69cbd0b0c1f9743a62f3d988f3fa0a9865a73fc071f526623085a2ef12838888 0060bf720052e8b9508a801340c213cf53bbecf4975faee63d4b44fc647a b2ed21cc77dd42ac5eaf71174b591b5ba6f90ee38a37e15e8de3974f1a3af982415c2252976b6f7672460a3c5ee5f680167c4f1d90e3d15f3fc6ee2c17523c922e74897f600e9eeaa9c20cead8076ebd8c12aaa278881b6b3e59986fde035dd8 +cf4a8e754b23d0fffc1c5c80b0cb11deeaba3064b315bc2cee96db5b9881baf90d30af4b69066f757b3020706def77a5fc1632d96bafba22a9c8cd3b52d535d941b3c7cc02b7fe6b51639d5e2084478ab3a29d2f5e0e16639fc2833a47b58e2c3fb5b2ea1830fe2ff68e571a8f281617a23d9a28db1c64ddfb1083d055030e5a 007cf3c216592febd8630a478b5b3e3a605084020322adb13ac0a626bc7b 96b8732929e4d7d81cce1e1c328cdebf79336dd462beeba57d8df448327bd47230c5d70d44acc75bf21f02653cc459430bba21a92906aa0cd89a55f10635be1fbc1a355b45c3840ded6487bdbd2f9711bbcc33ee821d0a421daf15e96d14a34c +ae64030d4af9b36c8d3a6af0aff34e5ab201df04274691fb420b7d5c40c401ed7f3ade96065d34f2490d17943e27156e7bed83cd7222d0d5a73d167855fbe7ff6c3ed87f20986ad8bbbd80fed5f9705c6c783b423f641d40ff1f367f9648af5a79ea3cea0236997558bd9dcb011ea4dc64d61ea1e1f85b4f696ed586bc7705be 0061eda5999e5a9ed4485d2a0ac5510549b76ca37df858ea5d95aeed571b 914e681a7a89081fd9d731ee8087e04998c561d2a8f124782dd8f4cb2967fde3371c3c927f8fcc0be1df2bf3dfc8673805366da351035e9958185af3ec728e6d74c03dcfc61fbe1d63effd662dc131eaf8ec3ed6e7798c9398397b0f0eefe9ae +94a9d9cd9efa3e4ccf2a37f904dd9cab5624ec9393cf8816ea591c5e70cccd2f105388ae133708fb974998ae61d218c71785f9eb808d1c28d953cc7eed00dd9854b6b4568c5ed5ee3df3b58a1e04c64f1c87fee4365ec9aa41b08a6bae234dc43a0bf2f61420acdb891a40f17f246972afee75a4c0b249dee0fc8f9b9c8a243d 007e7e73171e4d2f2989dc024757c186485435b82544a448f5cfca05f281 a74c7a143b7b45841ac88fabb5c0b5fed874840c3e72755ffe79c1b5b252ca13bf4cfe832f3fae24cd46cfb2ad5ba8ba13817046265f96f771a31557f10fdde421be442cf277bb3a1b5b6659ce83a34c5f95383a8e1f979d9260f31dd73af733 +4db998df7b90678b8aa4ec6233c9b4629800ad1f3e2cf8f7afcac62fc6982dcb290e44587015eca8dfe77dbb4a80f9bffe75b11e961e70deed14555db6dae47d49e73004f000eb8677c18f7e8234bf0a5a104266167a05ef07152e7acc2f0368b37efe69c0c2feb51eedf7338cf9ed398f066cf1f66bacd89ab9376d41da35a2 005f7270764a0444c7159d2db867930fdb0fb9fa6b8fc80ca02e11753095 8ab79dd2ab59534f54a919a86b8d7033854541ac53ff74a3086bdbfa4cbb01785e05add4c7757ad69dac693492e2fdc01977391793abc4e56955e83a2db3a6fd8151231df2752cf69b8a673ae4d9b495cc4d443db11171b292cf54164440118d +dbf9b8a4ae316bd2df0c80db1cb5d7038364a2634925ff957d7c03511b57d486274b2ecf191746827c325a14dc94daacd66ad86d369e3f598f176c4f0eadec7e9edd13e34043efbe0a801b75b8186b4a6d89ceae4fb250ab570d65b6dd7c04382738fe3f6f6c867a7d84b35b20720cb0036a5d81a87126f236833831d9ff00b1 00179b924afa4acf30ecbe2b3c12de533a1f9675687876a7e5e5ddc8e03b 88641e1f6a910c8b7b1161a7d83164bc2a57415930784ca7681745578b20bdda8c6724d9942ee7b8c1e8af0493c4b72901a4d099a39b14f94650723a0910adfa635c3b38d5bc9b77d42621864328f075914aa3c3ad13d0916d02c73be331778e +986d9e5d636526f4deb7545c037fe81b09c74496ddb8e42e61650c74b6fe348593f0cf8f8eca5e839baf62f17bf6ad96ec0c71dc44fdf11259dbfe7499157e402f6bd5076972354150723afb632799a990c44cd0a4fa9609ec4db133e3b4700be3ea4a338e8ba1873d345e80163ed60d0de274d7617a8382980bc2138b0a2a01 002c9eb4d392d7f2eef606e1861183acb1fc753d666225f0f154d9eda147 841559ecd6b8528f07620d4b347b9e7c66c17a479d14e8e0f039cb1baf8e92a8df963226a10be5e61bc269b0afcbdf3a0068c6498c384d2f050e04207dc8f3df9b0971077c6e01c168b14e53e64f4dc99c904b4b568f60c6b422db0cba546638 +68d0be2883598bfb1433886aff118349157708690380c42b8919859d96db069c7fde6e117a3669f2cff94a0f1b66b27b09e3f1b24d26299e11552a084be428446f3174da2e0414655bdceb38e58fcb065b6661190862db39c6545dead34a03584632e988d0459659dc7c7c78d4d00fc2aa10465cf24b2410f14e2a62173c9962 0024661c89b77b2c743cc175a6130904461138ddc4ef771ffb9fc2c8679a a105ce3ac5516812f6cd3ff5e0a8c48df6113d8d3f7010d2e9dfa522e1f368a7eb507b1374f6d7724fe8c1b8f2be4f5502eafa5cda31ab3ee0aa0e7c36ac5804866fbb9e501fa571761250ff61bceb13621f7458119af1c3d0bc30b0e0a5eddc +f0ba0407485fecd7337f4b22236533a926cc744a5f06dd08276750196f1bf7ea7984278f789f92dd07e36895a8bfe297ea43d4a1177c0368900e3b969d3083cbe626f0e27e7ab38e185c923dff46d9ba187b2acb9cf4b23ec8eedbb8044b96b5263d956e50cd6240c66d5d96517130c743752404ed09473f05d0004dc5971ff5 00065e20e5ce534576d7c17616cd4ede3bf4f500894850723bcc9f895f4b 874c637e3c418e1686f20c49fdca2c812f7d1ee0d46a9ca4a1b2103dac0bdf5b605161bbb3a73a2a65b18be456b07ab0103448596169518fceddbf7697aa260a45545a7f84041ef17cb64cceaca97ce70b154fd395f51a081ff5afce77c6c660 +3827276694e413c886129c452c9a66e7d09dee84f5f09bf34e4baa308b4627e096c7d45cf6ef45ba1d9a4019a60399feec10fa80e333e2aff1251c85ca48574d9b9e1affb9666828dff5afcef3edaf5e8cae823505a0c73afe76c1bf130399fb06b092ba34ab0ae15ac6c682f9ee8479b065ce75b57213b8aae0f55e4e386de5 0014c85f66fbbd653f1e4e590cffe62c343ba6062df4b271fbd02e5d42f7 8426301aeca20c41ef258561b45a944ea57cc5242916ae057315b7ec7139b36c8ba126eab51466b99b3d0660968444d3001be1aa9de160eb2a1e63841edbabc4a11b49c0a90ab206ff7d0acf6c684b123e628a07d1d8fb04957207e176ed935f +d1afb8965b48d66b9acb1ece674d9548f83395275f2d8135554cfcc7ceb96450d850dd874529433883709483d0743798db5e0dee955a4f30ba328c7934b8dd9207f3c336cf89141a175ebe23d2faed629eb4236a8aea8300604c3eb7704512f240fda66acedf1494a85058dc6a31bf9531958c332b93cfe5545046876c6b99e0 0030ac7a78593b570b29f6d3d267abb6ba7e5870ee1c8ee4f1ab2f141051 aa55b656484ff9e6a4cffe3af44ae618856d0d8c7cd596a9081ffc3215b3a9c290b475d6bfd962e5a8e5c29087e2e5ca108569e15ee0eb4c2b45f8a39f23b8ab368991d3895af594116a56ab1b5ef39fadb77827afd9efcedc04bfea178c85ee +4f95b71669fdfe5dc46d4b951b085e099de349fc740535175337127910acf24e9a0e4b2f23196ad23880da47b740d77d74fe9bcfdcc44dd7d8d1a181ac290de5cf4da22d5034cda3d8020bcc776dde8cef1786c9ce4d2c2cfb035da61406af745efb7ef1a55f2eccc5000319cf1d6380963025dcea641cfd15a3106751fec286 006d7516aa040f7d559cae248e485834e8d9bb608279ed4d4f7e1dbcd2b3 8d68c94d357984b965fe820b8137335c02f3943c318237c0e2b8502ab522c450b6fd056407d584fce4d2843cd192380404da0f27ff43de522f220a059c30feef33e782aa96afc5ecf62876f57a00fd727497fa3f788d10b984dc30142fdb670f +2ad9e17780c824c4f2d1e1cbf19ab85638f2f71cb4fa3518f08085b8b358f54d4f08394a5ac29cbb3cab828c5f07f41eec51e6cd61a5f2cf44dbfa46834370cebdeb328fd3bf681e61011b5c2ebc8945ac7a2a8467606051008b15c89390e111999255bfe28634ce9bc2850a2b55a4af1c4c2f94403c78aba1ebc87386ab7b32 00137050d7b455f43a8dc2516cfff5a91062c1a2727b27df41488f3dcf18 8dd98c40d5beed598cf877c45b76ec1a3f6a8813cacbac9b12df3114937dcd74cb39f4e88aba1607276bf0a1a7b1fbdb071c3485ffea204e023af9e1ab1d91b9ae3616bbf27fc1094aaf32d61bdbe93a346fa56b1b6285f0f17a754b0128f75c +958773c37d3eba003aa5c489f72118b3022c52b93399e9d8001695664918b86893f4922c7b6e55b1855ed0fd1d8de5dc61af403ad660fec60d7c44bd0102c069957ed804d0d416facdc1a95355ef58554606579ef89b1842f1055cfa2ae118abbc485356824cc09dddb77d0671cb3011b33bc86cac526e3f6bb3293c7bdca1ff 0001fd447b33a2ee3595b9f885c290d241422afdd74c3dc4981955a7e9ad b4bf55482f6bebbffe912f53b8ba7f5808efdda1c00be0012a585cd93760c5a7ea0c03dcfcc39c3a0b5057c26aaa2b6107f7a086e3d15a53305c5e44bff3e23c12773d494d97c9466fb3f8212ec3e2e296141c569906c7fb89b044fd150dbac3 +9cb2c496b1bc7f040228571e005e7e936e48e8f469e295edf914f5648701249a20bff6b98b5e862603dd9f12bb71c160aafe9df02e2e383e9b8a9a9d700f4425ce408feabbf754be543f52204c849fed6c9d3e36e03dfbd9e35c18d7bb2295f1c484a66e73440a0a5aece5fe80b9ade9321ef18cde3eb2db15e4b18e788b0441 006a061e10b4a6e7001d95411cb31bdea9c84670a59ed61b14fbbb05c8e7 8f4fe5e01c3d8c511b1979436169ae5641b16df6d1212a25c56270e51e6d8e9458a2ea0b9ec67994e3f908221e59a7550d27639b24f004d615391cbde768acb333e674482cf7d31a1f362ee4b46ec793872a9962fefb6d945f5f7a1276121964 +9a4bc0a029e97742ed3bca207d5912cb568e4403cda106b00247520ea02008b14c041b8c9b976294252da835f4ff27456039d79d90315abcb0b9b6958a22352672e229665457ec79571ca80447c8ff2a86e6af3dabe7427c8bdcae65e3c6746a56079ce2cf8d22235180f46646a21cd9e86032cfad874cb9c67f882fb037a13f 0027ec31ca31acb4d2fbacb49fc085f1261b0042cc755cc97f9b199e7a37 8b16d767af5923a2f969ffb0871b29477b264e0243c75500d70372a4d3f6da455620c7981e5feeba029f056ad899e3dd197edf6da71bafbc7cbf6508683447233b623747ec9a5437c144cb808fe3a88b6bd8c86e74e08c9553d6c0d092639c19 +8d89e22cf802dc68ff22d43c436c79311e705ff6fd845e77c880f399f403e6d5e9e2b35511553c978171189e288cb2200fd95f84ec5ee9865c0eb9190aff6dacf783ef200e82027fa992741876456472bdf27f2bd8ee55db15408c957a120eb64cd24d299818726a73fbb0697eba726a326719765735b37a2dcff0c853c906bd 004c6f4d88e5a4f4f83196f2dda9dcf2a66eaf94d50c851f59bfcea1d876 b10a53b0928a16cc75b54809b33f0cb42436118c35b35c7e7431528f1f80384bccd092038b322b1b420098f622e963ca05c164c6e91fb7f92078eb11a0a2953acd31db07f02efa8aaf01736cec9e72660500cc66b932f805ab113337cb0a676d +aa1bf5a79e5339fb9ef6c2817bd95725551d064bc5064d6586c5a879901adf808dc2ef7c78ec3b434b84569988db58b5e8e9782b1cbc2cc7c9b68e66f32d4ac4ebe7e75b345f654c7b8a5e650acc9f170f75b7aaa3957cce248cc69cf93faf8d72abc6fc1cfa9ae2d18a7b31ce720147e88e84f6563b2197882fe302449ac5ce 001aa169ea84365c22981bb766bfdad27e373440850569957544b0f9332a 8d96b69fd1c0f5f041f44d552d74439d264d7305e8c05425a4c5e022534c6c7f4b7f8ad3aee18e19a9ae28c04d4b5bfc1811dc2035251e18af051736a73d227ae0cf9ea786add9756e3e3b0fbe59f558292a5ce663fca383aabee2e2dc76d583 +475664d5e22cbe0da0d0289ca9a666a37270dc71c81cffac91f6229fa39315c1d55f7e0a89b6a7a07df7d391dbdf8fb7af63d2da46ecc3b60110dbcd842da97f98d2b67f562b0364ef8e1c589519024177c8ea079794f271f6d35554c0e9d0a39062383c95721b72f4e74eaafb6fbfbda02cb670a7c4c94f67b8ebc6442e84e3 004a665b92c0c33a3f8b9eb4b0ec061d40b603de36c87096455102ffe57b 844bdd24c7fc10cccfedf506fdb155ceaab9bebdb83fe76155793a1378319e86a8a820d09ea9281243505870fa2853d1102e9d7552ea8a6e709b8fe058f63c7dcc30bc2db1844bdb5320fea6c15ed6acb1da14e88cfe717ae5e829889a4f106c +9e5397d94465390a82a3c07e3ebf21b515776d18b4463aa5810e6b2f96ca61e92d13e034fa853c3fa45411f51f79df6f799a2c6906e6a5b7896a4576a4464f9e0be2b529a43e1f503fb640d79db6b68f3a3a7deac1b5832fbe86673784ff6db1f8438f7dd332cdd1e7ad9df8b6731aad1b6a72bde52e6bc62d80b8da57822c48 000531540d94823e19ab2b95cbc6e7492e1effcbabce875de6ba96f53aa9 b36c7186891037d1794c752fe7b380662f6f593961aea78ee1345ffba5366b5435e3bcfb5baad8ffdf55ea2c1af71f2f003bf9b8e55f5524bb25cce18cb5be6890ceb6055eba1a31a8ca122e96a3cf169945476825c8b0674d902637d5d38bb7 +3cc4c4192f317e52df6f8cefba6d4cd823c942aaee11b9a0ef5de5c2d181073b7085a55805e9554def8dc13eb978e7396044d4f4a14be2c7605998c062095c929b9c23b2b1b2fa73dd19a0c0af44ca4789f9841fa62dee8a5f91b3cc4b3264f5f67334c3f0772b30bd7431c3fbbf1f34318ce1889b6e8a76ce6d42079a451e56 0022a89addd8b85809e87e0aa2c038593ec277054842854de1197833a51c b128d68c5656c31c3b248fd3345966483dafdbf512d7453388d1a1b9c14680fa2b115f8c2728b69035af64d1124a53b000d61680018fbcdb955d883f4d3cd330d214cc8601987c6f55fcecb51391024bd79a01def41cc1e8c744678bbeaac402 +72cdef5bdf710978e0aa334b86b8ff4a58630da314eabe98b4d611aab56f55c526983d54d19bbbf9ddba30a84b18aa0bae9f9503e9b222f842f084db83aa39625403213ca321cc0d9c8a136c826e6ea4ec108b913dd0a9ce9d5b8c7e3af53c3876e56a2037ebd6d99f037a097111c837647bedfe4c494e4288ed6427c15969e3 001df252a11ff97b4421b3a2361db94e908e8243cd50d9179f9e03e331f1 b22b7940c2694d18811cc9f9b254dc3228924341608c46689ab4fce817cedd4c37ab5097d4b05a3e3e3c924a44d4733b05c6bf32c45402a2e295e5e0879a6fb115e03a2234743ac71414eebe6599caf4dd8c569681422332d2cdd169d831e44d +8e4eb88c0b2d525b2c58b8e00f32def90e6dd382301de49e0ac053dbc6b61afe926d85193e2c4948f7402a3d7c614cb2c58e060362b0516a1ba4a7425f1b3d09aa20d4c3c8993a387a3248aeec51e6efa8f558dbdcfcaa13ee08413227c8351e3107e9a3e3ac124224aaea91bfe50c11c1c8ae582e718f50bc5d5c06076517d6 001d7125c299ebd0dbcc050f07de931c7ad0450af590d0a2d0228a66ac5d b6c559a7bf9a228e29da5fd6678a1d93bd62d2717062728a8da4e2fd92958f3b53bfce7f8f4c596142f044884a2ddbf30fe7b3e27de39138bbb54bd7e84a29e2db48e196d7a765e25dfaa1cf289df3f8b30a35633bacb6086bee48b2d1889e03 +370fdd80f330311dbb3959666001bba61cdacf20f72f78953d946fa6cba02d24b5003f5452d535609e489b9434f192011f99f918defe877d51349870e7e75502f61145f7c261dbd2a0840926d824ebe9be3c5a77a3a84340aea930378367ed3615a47e3f792c7773f83f91ebea718a05fc62e9ed1d78629b2c27ae44fe8f8d4e 0021238e66119844b146d40e48341f522f6ac2f9c8a0b33aaf95a3099a41 a23a51353271fbcb8ed75b37f6be008b07eda95e9a10484f256f658063927add0ea9d66faff66a475ff39a37171af14a09c6d8d8d1fad6f9ed2df2cbd3e3ae827ac49afdccd09c2ef7415b4b1de580970d6969e0a8ccdcaa10d8ebf311033db7 +f86c4433787c3ec3cb1663389ccf53d62f9425274ccef05fd14b1b8fef676208867764eb98d16d006ee6ebdc27b8d9a8ddd303d941fdd82b630694cdc698bbe6bd524411907834286c94b24ee199fe6d646064277f244b7df3ea2d9d52a9dc6a33d7c8d6dbc919da0fa987a67621ef0829e48310e0ea2bb86fedcf4effc0b94b 0015e1bdfdacd87c42ed439f3e243abf27fd42e54f3ebdfb47f60dbae5fe a1b88a2542c9af44b4770566d87c6321099e4a1a84efa4c61bd40360cc094d176bf0cb5aca800f249041893083c99037063705f66c06d43a366e997c3730b5ad1209d0f0a11c59b477f2b41205b95b800570f392b54c59dfb7163ea8c5725cdd +4117d593aa92e3eae1124ec7482737cd3573fe5f0f2a5051a7ce86946a2abb9e47a0c6ea75b262689b0b486476d2ab09a20efc2fb921419b1811b51a2e15891ae9e45a17ab4b96c665c6c423fc00e2d66df5804a164f0f3c958df6f25d7da6829b1fe162a0a8cf130858c83f3555d6ad627db70cb41303cc6380f7b3fed2563e 000e09410548c17bbbf28a68c3963a52d39743a4f1ac28e6dfe7a6ede281 b3a92f25fa5eff7e844b8d3924139a3db4136a25ec71fbca0641840c4a5ad8a1c02fce68f0b2aa2216e608ab50b275b6018b11b20511bb3496fdd7472dcc3a7e485338e0c453c8d58d5cdde6984a9a0a2acb6d6a03812e77a7f7b259be5edbab +882ecaff3ec8f4023df5397167f238869f78a5c499be19aea85c7486e73f66f0e08e71cf85f3f1b6f6a70796bf46a18e6b555a0a87c2088640ca73051b3dd59ebfef922be0372208fce602d8001681297b285701dbbe24ccb42541b5db4aac1a1c7f407e11c83db15b38cdbc25e930fdc6558f64d9503e214571a435d890169b 0049f5bea6e72d98579b78cb07d89f64503f8759dd7a73cd73713c120428 a1486f2fdb961ca91c00fe1ee34e2ccb28b53f1c0f20cd67dfcd536198274a3c0214fc9ff409dfe9c97987271671bab60daf87c65dda2fcedffb011807d21ab3504a250efebaf638874e420b0c58c2ebbf8030eea9fda84e932786a12301b70b +99b3b8f876f8359bd6369ce84f9261581c52d744b90261a1427ab9e447e6d833b6b3e89af8dc770f1dd55692d01c8bbc4277a729fddfa7cbdb2ec99133201dde44ac691a77904ca816feb0a1aaacbb9fba85048bc63d73506eb908ecd697caf582747051a3a38ac8930c9a4365f407ed94ca7f2d26913c53f4c010c7ed9d7ca4 0005eaa818690d1ca4838f0bc667be5721d178c3869884260fb230277c3b 8933d293b71cab5c8bed8bdd4ae88fe72bde2fb219b3e3b8b34094a8e89177fb65b8a7c9403742b140b83fea4a2555a50c919f0c1c4c23f7b9fe7cae0f2a400091623887ad09126bfaef3c5b3b1996de73de8b3bd2a8c2409d5b0dbf0eda51ad +8c1a83023930a85c5b2f9930521b8b8963d5523a3323d87f862a17d3505ccee01246ee1029b8b8c2b608772c4096d1e914cb398f027d91184a8e94e4feeae121eabb504a2a35c8bc9294edd15ddd979946c14c792ad787dc2d4deffa284830fc90b3f8c0ced6a99fc6de7c41b9ed261402a6b3d702ff86a9392731ecc37430c0 00603d89cd2f741d734587e77554fe6bbb1e5739d5ff73084d4de8ed69c4 8b2ab0fb7e6d5702d11f0ff6b1b3a5702554cba98533c90042e74139f0ec00cf473ca2442fbc173a91c81b50f0daa88a074a834857668a26fcce89abcfd768dc566f0f65cc2d51a498e8b1d9cb6c775c81049ea337f06bde47e60d35e57c7f9f +f3c9dedd7115339dd3ede7d8d06a44de66bf80b4888ab7bc386cd40a92789042440a13d2cc90dbcacca5feeec1e0e3c51724146e2c4904ed6b05c7b4e9b49d7f458ada695c5d2fc36f1193329b87c1268aa38eda9151430aa0bc004e5d2a61b9390accfc699f2efabfec785eb34f52b1beff1e4c5492e922acc348667d2a3986 007977b3aba53616dac27b4d74930da23966a88ad98f1769674789c0be3d a8ac27504617effd5199ee09675f955ec8b45f4551c38f5e2ebc78fb96ba9c915229235ce102e8dc4203d98275ade66d146c549271dc4cdbf3a0b5d5fe4e66a95664427e37eb79eded781daffddd74a646f57e87bc13c7d136acc4eda0416304 +d878c4ee0bd6c84652d7f9e68df7b90cc78776d8d1b60f3e4d7465032bf401f1527ca7bfd4a3dd916e13e93fadaa5e5f20c9f47d12f8fc922a9a3aaeeeef294c221ca1adf7df85b888faec8002f17ff202da1be837827619904121167bee2d2cd694a263d9a99062cada3399dcbfcb283597a96ebec129c65e0850ec4cb4e2d7 0050cd20e7eabd29008cc977d0a17e1195d79587b8f15ac2447e15daafc0 95c3040355199510d052258b474aba7fe8b014bab6c4f35a8302a72218ce141414664de2d999cdec0a7b766f39cbb3830193d70788e46630586502699f47007f75899a32a8ad9319dc4f53e8b5061f915300b37e8d21295e4d90c8654ab4a557 +ac3c118cc9cbc8eb3b74d8ccc9ecbd81d1996fb25ca43c8a43bffeb244f722b93c9e969241d45d5b81fda0b399f1e3623687190e428dae077e54cad1eff75ec2f7fbb9434bf716833421bc2634885677579c237340f76787b2eb19b446d56c0f2206099b81493349f4db0ecad0e2dbe85dbff7d7070abb3d3b12ef0cec828af4 002dbb24fcaf9f3cd5d50d209937f0e2d134fa20ee3c9c2f1fff3dfbf302 8e764fecf6705fba1a4cea49dba469826b07e2fe7d49a2c67a35e20667d7d40e5a991abe93f2149961589678ef1661f80447583ed004c570e24dc8b72548b963c513e571d29b339a0de1efbc570d2d690ddfc6c08d5c557e3b1a4ecd27edab20 +700313698cdfdcf0044ca07bf9e5f0702ece7cc66e35decb28d5f8cb7e7e5367a95cc1728a90cc9a53a2b5fcd4702028b742538e9b386f5d8b4a2411579ed9553021a95bd00a73f03c4184a6145aaa367e3af76659d677fe7a2e98f9ddf4aa20eb8d1a1db72c3f5590598801be7ebf44255fd7376d89d998b7068bd1296fdc38 00047142197d3d43fa46545b547968680ec81688589d1ec8d7c7e90eb969 ad4a40f0456988eaf977f6e44f3bf70f7ca9a049b7d4ef7f2d31ad174e1562b46f14a72fbf6fc47139f9c10fdf39ad820aca024a8f48146865ceac87396aac65598acd139130e7795e7d2485bf58fdadf7359d1ac7d9b9d4f8a94e777b7f42f7 +0374673e1a685bdee55504ce3cd333f70084dd4ae685464a16924eccea34531663fda60229166478b30193459a3113253cd6494dc26154156252dc6e822552c7c04d790eb9f8fcef2ea8dd79e72f881f7f20fff93cd73ad303c0918ec27c6486c4da61f82bcd55422d16650cc68bfd4b0132c1e7075bbf17dad919095860d445 0031352b49ecde5434aac05f898e6ce4337304845d748f114c14319fe97f a51de6a968036b0b94172c97f96165e8b9cac1d4638242c4840ef395982c99028952eb575f28d3a64dce5bd2b16ed33405654161e1de3d4e226268a9009f7b2572950c0f5d88e17d06a23c579e695a6e2b6fb338f0cb841e831a879dce2548e5 +8b237085f135d6e94592f8d855ca397c8c1028236a3b412adefdac888245874f586d06950ee18118f751bfe26f4c31465ec34b578caa44cf1b7109ac4f6eab7f97ff9699b34271df035d3bf58a2ed4bcbf7577cf8e5792b1945ebb9389b680baeb8518c8fdc5540e192aa4fde0eed0d7c82be2e362b286f582d65752c8db7038 00176f124c24e4420f6e726a6ca25f09dfa0c5a37e5bf879e7bdd36c3b65 b75a440dfc2e2e69ebe645de03d6353b6ff275fa3754b16ca18dcb87fb7752e8030a518cc31ee59eb9907c08a41de875172ae6cf8d0ae1197abfd4ac61473f43f359b9f242520bfa2b776d422c1c184a2d2d62fe20e0d7553fdb26593c7ee266 +e3a086ec15574f7017b3cd5f5a47ab7a73980f11074333490dfe9f8ad8926f9ea7c82271aaa74e77133b1025b0b22a6900fbb71251bb6549341a23d194e79d03462cdad52ee0d1b6f5d0d14e1136026961fa3467ccf0864bf7ae3fcc3b68cb35df7324bd9bbe58fc8aa9f63c19feedf19d935b71bf5981c74fb2a487f84e453c 00755c48c3dbaf71042c58cb137f3632e3cf9d90b7b9a58fd378feef3d19 b38e11cded6ed28c428f434ca615e9b508fe694d9838c6e0c348c9f06b73d091fd1e0fa3993a4b59650ff7d645a36aa00fee60af9e2acdad796ff369cb1c520994a0e4dc0f4d90b895a827b5358c66bebba354144f1202183a0e8f988f63676d diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K283 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K283 new file mode 100644 index 000000000000..9f9b0f369c90 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K283 @@ -0,0 +1,60 @@ +ef90f85fbda05e693006e4c64e1dac56223becaf0890f73b5274e6e289a5a1de2c141b825c24d595b3fd18ca855b5c1aa60dac6b5356275b11be670692cdbe5f282f93ac7b2e410a96cb9e9f80defcde98f3449f99e192bfd62040421a0ab8f99acb85369f25e5efbf81439efa8a5e1d9cf781355a0f47b037b09fe4086389a0 01e846c830a8ec04e8572d1a9d2df044ab47352fb346f67403a3bf87243871b164511c53 80cd74651a3f9ee42b474873a22abec8a355f19a27771a1ee93e5cc15e4970d0d2214c001ed8ff831931beaa6274321d02da925db107f5f67928d2ce321eb141579948cdb0577aaad60749e9feb3a8a46269aa4d173f703ebb8fecfb4e1fb64c +a3ebc17c867cc9c7c28797f6364f6574b80c7ec5b2d8e1542a6f5db8568c15032f92cfbceefa3fe4ee654f690b0455ee5d38dd84bb8665ffc1ff8c849bdbc4aa0ddfdbbca4eb37972fcbcee8cecc1aae21ec736ef61781716b60247b7551ec4e552d0b59a53cec5964c67cf7988787cedf769eabcc9cd5243f58034d96f0e43d 0101c5ed48231a56ca0ea85eb45de0e395e6df2efd4987a226ae36489dd8b2dfbf7c465c 8900710e94addb5b98580b61fd74d9c2460f010d4a10980e687344f32fc6bf7425e3446c8409a80489595d1eb6a9290711e54369fd45a78f14f8d1824d119f5dc78fb9fa858ba149fd24c7a60cfc0f8c93b855669dd05823a3348ea9cc0e74ff +60269efa4d0ffafbbc655f6f00578eadce7fc0a7eb7db923dca49b6f2bf3e13f7f829cc6133e022c3c92143c075ab9ced0531a91e6e79848194ab98bb852f40c84e7aebe71fb8bc0fd1f97ed5bb6bad6783d8dc048df42738e841d978456e055e1b8a781dfecfce2218701c7af77e7894ccac5bfff360aab0b6136b978bc39c4 0019679dc589440b11f82b3716e5b2a2bd42c3b1c83e88a28e304cf5148877faf760b4de a788f53a1a930d84897d433bab245c39239550c10643915fa333ec53a3b629cee731affc4339328fd18bce5f8223e5021428ea86a5289e50dd876d13766dc9b46b442893e9907c2b12d59032b6a45c01a0ecc52949b8275db9ddd0a1b08dc039 +59d704d5b1f3a0605f1497f22f71b8f45b26138bc86371f00a4517554e7f6e7fa5d35189fc656ce68bd2cb8510fa3e3c3df815dfdd749b2b6ac997d443f3954c7a927e138b579801ffd035cea90840733e7884ccfe43d8d3a4a26b430673274aae312abe4ac1e1d7c67b73580fedf2d8de46572493c9205ebf0e8b4d75ccc88c 01703c21fb1e09f8947e12fddf166fda6f685221fbd803d75a0ae377a54a1e494e6c5e7b b2d3a5117b14ddd723f9682e297e448e6147045e505b4f895d778c4638c52828f3d1ab56aa4461dbea9e572ecc5ec97a0158cb025c5f726509e3b9166c48f97ecc70d8988606d16001f6a8e5c6c9ed03940a36fe0703e2da294a7165e6ca4af4 +12c8fdba3bc5f68e13f7ff8e7bee876fa68a970afc6924314dae0c2482763ced8d4752cec29ea288d350acd8a06c69289ae41ad345a1b88bcccaac903f2bff39015c289a8ad608606bfd65270a7bcdb5fb10c89bbc2d16dcb91fc9735d66103f6b1f3575622cf4d8209290315b033ee1f79968939410f465a2d37add46af2d59 0071de8eb14cbfb88e61b908990ce08b81e624ef4f2cd9cdf3dd7ca9097d5ffed9ae9a71 ac205d40bd307aa3c137830fe6284d2b174a9394eec1690c64d47e25bd26fc2486c701c9e3bdeac853f0e73f29f2bf770aab613c600a748f9932c28c9107e82ba1164b28a3985672af967dfa38d20ca10f44837dd59b3281240a1c2a856dfbd0 +26013a3ddf687bb2f37d9700923906f118d5cba5d8ed5113a0e3e84cff00918125108f74f4b243e351aa5d07fa7c6ece29f5700f23e50286447883d2a058c3258a12e4ed8770cabe627ebea7ef6e8c77811ed7d9a19c53287093e39226236587ddbc63b7ad5e7ad9895c64d1d03ee432d45a067afe27d4cca920ae88a7a68db1 01d156eb15762ed00c4021884adbfc2426e910b18a5bc474268196f4b74e593a8f38702b 95bf0107af5f88c41e5199be825fe038df221735c3449c5d21d706c78fd42b4a4d9c34b9c17d975845bb671de6e956021606106a47a3b24fc2f9c1ab4fddd909e1cbdc863aea0186464d5627c8bbcbb6213171c7160298893eada31ec9a256dc +c4dbf70b9a2165e7279122460d05ceb8e43e03fbe2ae7c314007fe2b1d8567cac727a10fba5cbead0ddb167d387da8e8f3d6bc0ad851cc32885809d07a776fd4a95a979fe3833610af89df0f454d9edfabe12495a118fe83add5eabb2acf54ba7ba7c4be20fc77478c0a0f0726c4e60317422a612a234a7567648603b63f1c12 017d6eb1219cab8577168be86b61f372b27ca70fb1f1a767947895c185344e966db17aea 94bd53636369c05bd06496aebf1ed136e1affb486df07a9b014f5461f13c1be6e27d77340c7fd79437a82111d8beb97e1800dd737822a79f93deb38de8fe335c478dc9a1f83610303fe1dafdad5153bee7074e21455ccb103bfe8957dcb11a57 +b1d53b6af1face9b59af11c726b0099111d1adb3666209ba46b1744a528ed0f72be5a1b82423153b896384faebef0362343e2a4599803c08b8513708938aa8a498145fca1c63ba41aff06d1a18aa2a045fce7fcd7e5552a2b98d0df97b6876f06a9cf52a7a40fb737996adda97c3cedf7fe421235ac6951060eba9c0377e72a2 010ede9be6615b3b2a294d67da78127ffbf3a15bdba6f4fd78be7a60415b5d1a097c0cff a0340e20033f8a3cde1040f2df7a11386bb200dcb9817ee0ba6a4365b5d5529aa2bb7ccd41e4ae6b541361418335b8600685c149ccf90b3babb9fa9158e13d3a5416929b9d8c1d8136a7e43ba9fa9df7ced9402afe9eaea273b39833398c0d68 +e78f538b1ac21602b00a09e3db243ef4803b447329c94a1476cd91a88ff790da71421b60092c8a6e55327c7982e7655eb1fd6e40fa9b9fd2f10107dfc585994dfc5bc2143d18794a39f7f69ae679b27dd11ed22040d5e93aa83f71783525a4db0c3fd7b43e57dafd0033d5317680df19c2ecaadcb37ef896c61a758a5e455206 014f237cface123b64e8578ff33f86bfd2a8181b9c81f36b9ca31e2a446f0d91dbbe2249 b6b1f4de5cda84450837df8a59167509ec378141927b9e650aad5f161d8c326288fc4d7ca7126bb5cc75d88861f804670d9c4c5dbb2d02de1cf97ee3cdee6885742e2634455341c6af4fffdf8cf3ab13ed6606abca435f1fcae831b4e04b0ad9 +8a6ca8ec436d2c706fcbec6486b5665b21c174edee7ebe108211c388b1219a8224179f7438e0bb7d6e41ac4a67337b52d4cd9a069fe6c88960ae20be29c8060efd7c62cb7a9a37136a250e68f253e7f27755df53ce7c570135641ad49b43507e5483e17b919cedffdc0d4913b1d5e0ca0629876c0a551841a0fc2090d2857cce 008dbecb26587cb2ed7df2404e680fcfa5bf8cf6a58e87a350a1600211b3c844ca86daa5 998f0a38183115e6ba1261effe69aa2aceb70465437c62b4574145a480742ae3be7fceaa3b9309ef63a0e4148d53353415f1df67c6999655e7ef7ef1f0e15ccd4d36314bd163fd19f65218b353ea9bf7d058b37c2597cd7ae9873b5e7ed19a66 +95bee02b423d2c6e60252da4632f693a2d8f6597b4f9c6e356f670c3a9e4e80063e92facb6421d0325b99dc150464ed2ec1d0bac72a042b35d56d33d2fda686a75d582d4756522218b4ddd25ed45503d90d3d185cba6cf0ac211b22aa4e1318a8316c369186f7130446dafad64f7966f5414f43af37a87127534060a23c6165f 0191badec2d28cbbe62c072c6b57eb5d4644d0c0b3283951bb66096cd15edd43a1bbde53 8a9c32c8cfd8c5355db9493b930142ba1462b41e2d45a37a23c2be096668b2ac54e0c56b73d29e87942d1f719ab8e375154600e0f4daba6896cea8c2d53a7c2e9984aca643cfbb6be42d18eae9394687d597dfd6cd1b9af573529195cfa76628 +ccd7f7c0e04d1ef9a3c5617d77480bc624beed6582bc28e9e3a369b12144fcd96b735ee41713f4173b64b28c6102d82dcfc7876e06e76fc497d1d238bf6d85bb5feca630bbd0c0f0fa7c0c72e28e9259087698973ac66244bc6e69c04deb22eaeaee7b20da239ab6333576f01349c76f594498620933b8969450ac2bae66db8b 00ff5e3d66eb57fd35ba4472effd6e7a016ca461e39000a7125e99080f6ab6ef4380dd7a 81e6328191ebbd10c8634c95796886c1ba51b095f7bfe46bbb9f8584fb7eb00d2494f5425056bd650f9ca5248bdff75e05d77a82ec67fcb2f577d4ce73cd4815884fb1307c35a5cd414c192e503661a270f2d3fc1aec4df073844a3ae75180b0 +65e9124a2606c8784c9489add2999f4cbe6186395df20838d653b263a207ec46995d2685b55d1874e7ef05a6a3bb5b60a7be6751ad568cef1bcea2debfc494d1e2ece0dc8028c88f1b2c6e4ee26b639c5e81f6448bd25b73ec4608a8e8cf4e0155c29b6f0a62781493b03bb7384c9808529d5f87da6564ae196a365bd282f46f 01f3591eec4a8a3fe6ae6debe230d238a6b73cf3791cb735add1abee64239bb100f15166 92356b0468b2f23c7d20c2494607c95659c9eb2397fe149e1d0be2b3ca2fc0f2ec47a1ba9d89cd3340c588c89023f586097bc15d02567a552d91459bddb66635759db08f752a13d420d9b72e05e85e56c1917bb3df69dadc4668178e46d7a719 +e793c60fc725fd537d5fd38e9b4fb52e268722ae6bde5a058de8d20db301f5e8d8e1ad85532198835a04b76f27ca3c972be5617a55677cffa8219eb64fe53ced242efe1b889990979227dbaaa15ed39d3b6be8c5a3237ebe12bd96f333d947f80048463d3859e34f865d83faf03894c2243a06cc96788ed952e606c2d8948271 005af03cdb45961e7ff35fb0146904ddd6c2bfd3cce814073d3aa56eaa9f13b4f7423926 82772270e55ce0888031a941bc501fc0f07d025b94d431a9b4134abf111e4d3d0c95be19a2fb3a53552bed5b8bd279291235e428db62a8dcd96330845b89f75bab603f818e1de29cf820371783d6eae687dfbedd4771f25c38fef724b3a0f627 +a57682d21cebb48190199e9f57493696eae3a59acd22f64d5ef4729decf6c2615b326817a6bc118bb7234bebfc7276dd998838c009a7348e46431574638dadc48538d6048d572e50d9c5974d2049ebe1837dd857bcd1447b1514b62808a4e7a88162ae1bb08a0f6d3db6f25874c6cd0cd4ca6333f1bd57bd192ef67e4616d182 01ec9710ada06e6270720692a06d488ae2ba863b905dd2fc323e7ce68dedacb35fc8c7d8 a856fd4402c091502ef21cf3563a36904d8e5531ca3f26224ffab3b843285d166539474d63ccbda17fc91bef75bc295507cb38a6159a1ceac32f202b22601b96a484c2a2234543e4f01f4f85b680e4056ce0515185277ad2cb0f5dfa053c1a22 +f646e7334e191c2bf0056d3bfd23f03ef7f0777b923f962519a8399d311b8f68414c689ca34b96871fae99eb7ea534fcd83e788e56eeef817cbfe33677283c736b99bf6a626f9515291e842bf99f694e4e8aa7c9911c591a87d5f112b3d96b064594e2b368e6d1bf1a1cd343d54916a66da22c26355266aa2884120fffb8b94d 00668de088c6913640fbefbe6d2c44ab26e481802dbf957044a4957c3c5d0a0fde331501 8548e1aadf7dbe9e38f81711786a4ce5a3cf0da97d0e180c363db7bef950078203c2269d831d586b19d62172d395311a1354cbfbc5428ebf6eb0e6477afd35f59761e20e87c07f3967a4c306eb4036ed9249401bff2b843453db0a2173aafa85 +a2d7e69ea381d3edfde4664c56c4cb140d01cc4425df757975cedc995b89640dc016ab419b137ff25a6a6d64a309b23890439d2ba157262393cf93d15ca1b1ffd19373ef12367f8898aaf56d5544c2f019a4854f69b3d8d320e03135bb7b675e588a5c3fe4b703938fa0f964916501297cee2fd04af767155c7739419f9dbb7b 00e6af57cf47de1e6f07041eb5e1a413fb7ddd82f8c7f7ce957eb28a118004930bec4dbd a7d3e0afa6fec336227062324998c2533fd21d95b84ee7e98d8f6f58b5ed5c6ee5ba71a7ed97aeb273b2ad52d644f56600b520e89c048c46d6c8b668f8cadf6f056c4d81b429c99308e4e3336c5c9a6101776a368e9da0cd507424765c354302 +7088f60e9375ec6a42f705f851fc76cc833c4dcbb3352adcce9f59197c1b7121e7aa661c4f8ad9f4ef280af3a2981e90c01291f7d1cf7d3ae2d96b37fe6975e11b7c6c02b8ef044d1470b1a26b9c72e8c4e7b1dd83c8acc9542e2fc7d211b87841dcceea2ab8128d0ff7bb622b60faa4a89ea7008f7d55f8f9de675bc4596fd8 019f9b63fde8c6aa6177f2a38981505d04f8ac62bcc21007b05615d028cfe851ab9cbbc6 8d91d9cea80126335292a8c26e473060a542afaa3d85e52fd7113f6b7975adf3321aed297555d9d8b2101875eeb67c2e0c5fc8e5094d8d00f83227e5b34485c0e7ba8e8a722a3058d53894dd974ea368ae0fe4c36248bee20b0dc22e3124d87c +ffd6044ab991849939e8a29184b4d0ac3e07acb63c7e6b886df9e8254073fa800d5910b9fe34fceb547565a2344eed4de394ce2251ed51ec882ee9207eb7340464c742d9d140fa0964f6bcb1efcc2d13919af4f727953de41b20728ab975c1ae0ce784865f23ed1325c68daa95ed5c932893610179be94f13b9a4149f09833b3 017704c1f436beb52f7ec97192e23e206ec09f9e8986e06bef71467c192bad6f0066b3c2 9829d81db019fa1a9b8487a2d3a23a56e782323a7534fd6b876c46012c5bc91169f2e875940d450af92361de7c5bc5ca18328230c3ae9499ff9c4efb91352d6863eb9460474927087bb9aadc74ded16ed3bdcce4594fd47f22284e7145d361bd +c9f81c9ff7d80011fd41f2de97a6c1e6a22cc2da7b2b9e4c50e1354c3e139b44529ac786ce795fc501dcbf11a935d4728a7bba44b4e86b5e5990fed4d3e24fa5ab6f303e1842918f156e00dccebed6897c852207ae5941c630014a41696882066c2b296d39cd8658cb5830eee78e29a00335a99a0ba90722ceca5a2e9a99a2c6 00c7d1ac8faa689698f5c6325a3b3f35e7730bdbddabd0693f2bfdc5c838bd62f84508d4 b89eafc43e02882bfa538f7eaf81d242b0f9d66eda1be71da223d6ee53949d9ef0f650fd22e133e231306a39e69e1250022aeb9b8cb4680872e94fbef3fd7fdc5dc8adc518d3d5c0a0c93587b8f1bbe3f5ca6895a7bfd057a0ef4dd4c814a54a +a60de761eb32490184dc1d29e21fa33889295ca587b994746874c7289eb9c83e9c7bacbb4066c761a06b65ecd78d701bd41f305cd7eb258c630f3febfbb0a367ad16737b146fd793dab23562e8001cd113135b1c981d1ca23eb3be0fe3e24fe3fe1089caf9fd8f4f0d1f90dcc7dbea4a9e2357793b65daf342b8e6d109c6dd10 01a173d158866db0ec665ee632b5fc397893f6a44ee17c348e7452800aadd8ce676e7fdc 8df2939cb581f3e5ac7caa7ae541aa347e96cbf6b913b193fa3521311f21d87d8a2034975307a05585722968fd613d3d0a93f71b52db1b3dc36671a3c912cfd9e197283aa1cbff43df508fc966093b21f683ec940a34a22b53ac583114382556 +2cd0320cc73120ef13e83c8144b270c9a1f2049a9250ef7ee83ccc7584025140a51e2227a5ebb824deff55b3affcda63ecb1fd3f337c67c08054dc82fdace0c4bb9cef1bea9dd792635f655363d05903cd6b5ed50ee669bcd8157509366cd85aa40d19593265da26e5641590ccf04672a6df52badd4b99964a8643d9687b499d 005523cfacf4ed3b74ebc30f608292e45173001d80cc801f729c5f71fc213b243f041ad5 aee2ca18ebed9b9d35a32f17e0e625768a49c2e91cb8fb98db5eb729a7ff27e7639a78cfda402fa3bfc5ba24f521803f0a180ef9fc6e6c419257dee60f543d82a0f6ca3ae2fbccd510d4176742bfb3cdcbab6a19e35ec02b9c8abb0ac6bffe42 +a743d8337bdefc4753f937e869a36439da1f8c75e1278c3f6a4a969d93787dac93293818b1cbef5b8636e1a6cb3acaac1e15dbe0841c8001512b689292f3f4805997ae26ff52f7fe1842512a020c448ed01af2a061f3638689446ed5f6bed9fc70726ce4104bc11142de63873fa7039830223e8f152996388417c48e0c1fa81b 009f6bd008c04b8823ccc3ee7d5aca535c211f35e9d9e7cfaec518b98647fbe6d28283de b7bad3d1d84e6b119c5d7947710beedd217a7b210222f9bacacfce4e72aa95f269444cd311e112c044991da768ae66ff08c0896709e3eacded8b941461bd181c2e8297656c2c55842fc7681aaf7b01a190ca38412274609ee53d3db8c0c93738 +6a7a3ad614a3a09d2dc5a80204815d0c6471057acc0fa73f3cbbf1801902c3e1cba3c1134a79a8ce61994a94a5afa85ae1a44b2cdcf5153f8625713c872da36aba0afcc5c2f26636dc3f60e04c256a5b023e20e2e7a3f7305bd5b3033fcf05368589f19021f8c9096a88679904b657bbe5b9bee67d6e53d176fce1de9e54c64b 0150d2812505c82584201e93f6e0cb875d29dc7bd99d9c0f98e0ed20128886e67e1f1071 b886d2b53d6ac9e47c703749da99c1164956b3d225f296542486031660032f62edffc3a0e1edb0c2fe35355f7c0373f3004766842a6e69599837fca013d84598309d7431ff43f79e48ec369978e40471d70f78d0cffbab1ef93aba352883d517 +65bcd77a3ab345cc99b9c1300755288102a6ccf140bc7d1ad25df246ef01fd57a8614b352033b88cc6ffffe5b38b99ecf03baa365ab5529d6751a3c020d0198561969aade09091434d84ffe13b46df043d0a61e20a08e9c32b646771fea1b29e202d40aae1c7079873c3af494ecf6ef5eda855736c9338b4a5c29a086a8266fa 01b3fb9e1ff70f94bc9d7742ea535ca982215af3df381b5ebdf1db40c7c849a7978ceb98 80ad4bc1bec04ed3ae469bdf07d4b6c43eb495af6a33a3eef0bd308963837fa7599273134c81d2958361ea0e73d875f70147cd718e6ee7417795769143cf8ad44dd9f283eaa68e65e93ad096b02d359a987da06b51cd42dff0fa830c85d5256a +ed1acc360d02ee6c36bbc223d91bc1d2009a3e8f8dfc4c3796cd8555b0d2b46716f4c8058bf34c2d4954e098274ab9c2cbacff46a0578a14e77fe104196cbc6d2753e3bb5422b8b79fd004ac0aa920eea94925c016ece16ed4dea916fd92563ec65692a61b28ee84bef0007120bb1e31bb75b8ecf68406a71af9a18b4edf5320 0147fa46fccf0805d14c1b84ea59bb8b8283d54ca0ceefb29b5585e7141340c55b7232f7 ad15b95c07815c987a559ba4f46347eeefd4a4f54d9cedddc5383c192b82253cd76c2723618f40e48a3eefa79ec8f85213c84b53213373695746cec73107fdd90e01903a2888e48560e3259237c2e383c7590cad3d401d0afe013f67581f0755 +2debdb95a21d72b69c545988727366a42b819ca6398a82129c5e3772aea93fac0aae9a27b11969ff0ffb9dc0301132ca2452cd863316cf24ae7696422d4dc68e37316161abc146e86f04b72d9a27a350d8545cca245b2be43c33bb822dd813d13e08a718f784845df8a4ef49b02529871ec76bb3fc1ba31089359f2ede73e767 00fae097ea56b35a517be5480802f450eb832b244558d0cc922cd4a5b40b84d02ef11216 abe720de8b3923bdb97f6d6fdb833573b3b00561ac5d8d4bc6cc30eabdb4526995fb1514249dd95af718e500c3fda7f2088fa2edbeda11ec34d4a11299efbadbc2c9be213cd23fe907ee033ce76e76c7f07ade8aab104ad6b138cfcf829cbfa9 +e4e0c6c8fc01244abf81e139c961b6a6e2d95de5dff1083e8a48b40e3e5b9ed909152c92b1cf2263179629cdf76ae553b58bb2e9223ce4f9ffb5f170f5f0c5ec97294c34a7529a897e9397f71198cbcd68bb4055cb8cd6b690290761b3b73303f82788379df145358afe28f2997d191d968929b7a4b9a0f6228797dfaa17c613 0026cd72e6ae19b3f4c53493fba1e8082a8df1fb7da6dc111b47a41f713f49b33f618d0c a7846c38697c328d83f38f209fc40985148167ca6432944f0f0ae054aeee17a3a3a774daaad8116504fa87b629d71ae50c70890f578e7e40f2389de3a320822e2340ac545476c4db25acf9a9b0c6c2f1ee59d4557eef220c4509bc061f35d3fc +04710947b7c90855ba4e59107b919d4a1df22b503c5c4c33b286b6b08e451e6fbef8ba40852f9f0ee62c9217abe6156bed46ad6f0e25f70f528f3a73d099338c578bebd6879d810e6e173c2b0af1f7caacb3531ff0e6a7856e4c84db355d110febdb21c683223eb5990ef2038d462ddb7962bc0feea5f850954943d53041f66a 0198e13c7d95bbbb6e226688719639bda988867764ffa9b029018b5547850daecf58fe1f ab96f133be37370d6acb2aab80d432f5a80b697ff4eaa020607913c983fc98946052c1572a797a7c8ddee12d51df72c0021ba5c3954be3fdb010176f22eb7cc8d21936cffa811eb8cc5de7b3745e735997c4b8f1cc01a2940dc07bda8e12615e +c62d07bb1ef756b6b2fad355c66b5be086b6dc387b37cbc4a63c841dba3fce65b09d3de8f239e3649382d172f065b78f8a53e0283cf345de06b4ee0b4b7d8611bfce92a7d993b1938419afe817611bc6df3ef74191e7e39ca2339fcb5b5cfee3166d09cd52a1a7d3779722aec328d326a11bbafb6aa417920225ac453146b9b7 019098a39956747de24ded56435fa1e6c30cc2b8088fe9a75f5d07b2f5939c7a60db64ad 85dc675fc525c18ff78e9fdf78929193e9867aa2dbfd33c89380e57f1980d66c82341367a51aaecc047ba329c1045b980aba207044f80607768c023e2a699b2b2b91e103e8d60a245f724c5b2866584255eeae3f005c33a2b966354f7d122860 +e4d8d49c9bc566261d9134d5e237d9cbd6b67d2619a9bd06b7c9c139e091aa10682cbede114e1d4777d9cd67a16b7d64278e99eed62bbf25ec5a5a8fabcb0a3468b0e73fd02ac6533e04b1110d29da3e34f33eaa228b78341b357a5d892a61beb2168c3bd5e66bffe3f2080a1e246f55a41ebf9d579e188d16991aa060460d6a 01636bd2be121e07ee83ac5e880cfdfca6a56f2b9d0badff003e872348368c7c2cd96b6c 910df0d5a0409e3ee971d796d272945f82885213034d9307d92e1f3133fc7eae13a5674d5cab38b5598c0c947c4adcf102fd8dbaef66c8e6052ae0f8ab7817766d864c1a52918690f454e989de5a72991c6e2ea428e76f64fe8aa44dfbcbd0e0 +2d1358fdffc14630fbc421b443d3c22ba10ef34f15c6c5bb3c73a9b8714e4c411de69b9cd6628fe2eba5efc4862af66ff916505023e0514f564164b389ea422d0f1beb92adcd65baf43556614eba25e43852ba65af78f62d64b36696519ef8284ef7316ea52c365b99f63a39e6701f81ad520d7445cfc0113c38ecdad4bf5b7a 015e5f555119c19b055b15b0c0d2813068bfc184f864e250b202384f5728bbbda1cb0f5a 976a821b2caee1f024899b95272bd05c6193b90ff0755a97b3989f74d4e91ae9a8781d1009a871fc58e51e6552372af10790162d12a9cfe5be8f8b5d179657733140a7ef8bc582b0e0e5f0ab8f11dbde62184025c62b6355c6496a12443a26c3 +d6336faa5c3e838f4fa58626eb353d4cff9ba8f0aa0e6c3d0d850e8b22f5b0f047afc97767f1afe2040b85d4e401ba688a4da7a0caca7fac450899092c4fea789231ba9b07782010720f45d16d353798867dd7fef4a324520014ad5cb32684ec50cab742b750e05db040ff51140e8d740f6774a059feeb493b10d8ac722f23fa 0190c8f17bdd38669e345440d2c7631d67cee9c6548c4e7b9452377adb9303430efeda0e a3879f4c7cb5b0722c1f09f47d65e5a2864f0e485c76776ed7d483a775a4650a35872337cc101eb599f4fb4406302206152995f8c7c199c6a0a3210bad4969bf956281b91671393dc73761975793499e654e94a98425e092dd27569811e0055f +07384a3f650bd270b14ca388a441af201b7767a2d47e9033f50cefd3af8257ecb38f5267e141cbbb2ab7327d8fc78cf27198ca3543d39553e178390bf1b921618432ad895e4f8153783a7ac22f4ca3cad4560e64f1ee4a7bcad05df98ea49a3847dc2143b27c243e48be59c869a547988e2205358e8db98b635ca21b745df4d2 00dbbc2a0409ca58a9e39e33b95fdd15080443c1dbdb5874bee991bd1b127047f08ec9f3 a0df4e00a7df95461c8da29f15d104ad2c20c38cb9e2e056f16a9bb8e3b7a51afd08987afc4906730ca2bfe2082c40e70cff246513810344b55bfedf2dcd6b354fb5291d92a043911a7e0720443c33952a74690eae55f1efaf12f6d702684c32 +824f26dcb4ce0ca020982814d5c727e629cbeeaa818c49668f8f6d743f0d0ad362b24cbac48027898f386889ca5411d7d1f9afc69493b1d9ae4d7b695c9fa0a30bb59e6be2cbff79231767e96cd8bba349fa2f97955d56f05430ab4ebd007064e3d5add94dfe255b6deff19650883ce9966e1a2affaf84d9540f65c87ab1f936 005495e6c59ca1873f36b756579632fd47f9fb95b64f52589d70f2739aa6a3bf8cf8c198 b019aabb5042e6a4b12efd537ffb555ae5e6bcee0b9137103d924934a90e9ff0f62a659f1e2e8611a890be75be5d79080e6cc46e400b9a6b561d14cf2aeac454a78800cbaca42a39611d3e6a9587ad06e4941e80ee4ef4f87e38a868083d7746 +07de1e4bb9be15a710a74806d4447b093bc08ed04392d1bd5abb414f5f4b4d9d43520d0e46fc81c2a97e71086b28e53242449ed37fd7ed1c5772dbabc430fcf82ad20437b38eac15820421e51912325c872894452c3f8a10ddb040b35308e583c155c3707b52df467c4945f4e1071126ed46611a3253c297f5cbca9e27f58448 01724987c9b698519b6c225cf1261b77d0300045e5fd774dcbf13f285e6bd74512cb7edf 98517299de1d73e2dc20cc6953e3aaa2d714da2741260fc1cf81d605e364453594be8618ea2004421c6fc2787aa4e182014b401ae11b40c1ff837c8f6ca89dde468a1d1eb8e38b20cb3e3d2003330de03b115ed686c46c7af6b654e3ba0a59e0 +1edbbbe71057bf7d0bfda922be21a3a4dff57b017ebf6fa99651246cd173bdc9b11eefd048ea599c1f98e907932aa04f64ed0a007831f30daf186c88807400970904d6090b2cf181e0f65f03b4234aceeb420867812562e47f452152bb1ddaaa48487170d06e47c5e9a7c0faa4fe494663d2fec22f7665ceffffc214b21c6b8f 01a5489091cfd51a0970508ee3e8449081ed175928ff8386592c83043a7911bbc2f8778b a55c3b9e66a99b5a035a04970de59a896edf2b35689e56c19a342b2c20d4d48815604c6ebb58dfbe092478e7e3504b3f020a33756a2783f614f7e267b32368a8c9dc86d2dbacd6be296205eccd399c2884b6c6f9f51d043801c049499e628f9c +db5cf1de38a5187af11c1f0f19a36db52f8417de997229e83072fb51a3b7152a3b383e9919c1b8427582e53d4e7e25433d46cdf01492021c237ea0a87d38c71634743115a6b2aba66d3faa8003158340a5078171e0bd55a6e5d8c7fb2631a31c1204e1479bbfe79ac70d5e5823af502922a900576f0088a33e42ec3e26c0089e 01a45ecda0788fbd7cb7a716dcf4c6e83d4148bf63ed58078690ebd238c00329c462590a 88c3012590c7a417ecd6b608c1f5009e1a866d0062ba659b856ec8ef5a6801262fd3c012d037a2d4accd5197d4dc3ea70c5326d861a333f39d31c8e104e40fcf10c4b4764f85a0dbd04930fcf033e6bfb7cfe3275c65bb96e63e55cc7cd313e0 +4adaa850eec8272d25d76600aacf2cf66e754f6c5efa65c55a2a31b7bc69437d9a7e47c6f51c5da93895a45221f5f92c2e20ee6a95eed3cc7249688261a35d82872284900eb54dd1df6024ec48963ce43e8ed8b8cca8ed22beee8f0aadeae53726cca05443316537840ab824cd1b595f36064e9a19333748d4f4972178e7f5ae 011461776c33f20b176dc8f2b0cb2446a9b69e55b6c7bc7457a7fb4639116b452b79661a 99825736efb2bdf9c540fad6d584f3da67f17ad85d8033f95b400c671631520631278f304630023af14ca4195e936b2e0f58a3557a46b7880953ac9da44b986bb549bc6e02673878add13eb7275ce4418fcd2fe7034b4181094930ba36eeb1bb +11d212a99c39fb5e4ca0096bbe6c81ae1490e1b8e07374b4e773bee4fdd24a3c13d653919db663d2c32aa4db140c4ae2d472d4f878946e527ad33b3dc93012d97458f96cb622ddb56f1ce7c2474ad0d5291dc35545de47b7053d137a8e79dabe06757ab53e26eaf751111bd27690e57ffdab5337eb6f81889e9d1b1ac729012f 0025a65f627db2b4d6cf83c5b0c00265b9b63f7656c5e3382139e4992bcdf3cab502844a a58f62754f634504fa86a8a50a4345468fb1d436dd510dd0148607c2b44434febc80bad10551e56811e86d0639dd8c1915e8c91bf656a840b402d5c59f0f88de3b94513da415094b9b816f560e7a407903d20e0085cd98a74f1b41d708f2de11 +9e4ec74c09528fdf3153a0f6955f20c70915ff524b2e19c991ec4c5b41ea9185e3e876a02ed6f27c9b3479dba951bee8680c4c99be1a626808114408856994be7444ccbd5ef9859fa479b1050bb836034e20c531b4d618f5843fe1d4b613a731895b489a2363f3f5397d5ff964cf037e9b11e3ff5e1c3d403e5a46b8387c1241 0173b28fc29f10245221a907778708b3ee62e0480aa9051d4c3eb4e8d552e6aad5509943 9333cfd0dcdd2ee304b38da2da76daba53f14306dbc9fc9ba7e2276cc1d7da0b7879c1e088d195bd3fdffbc408956e1e1019aaf2473b298720b05623259ce8560d6054a92774f5e009f339608b053ad33b7653551f9f6f3b486d31e20b574f5e +5fe8253d2134c434cb0866796013722e82184638b024a5a30938039929ccd8415c71f71f239c5c5a81f7a9cb493dde209f189bcf766c17c6d9589cd0c7de7f07ff9f24d2320669b589d084f8a8ea71127b9760b7355b162616afb34bcdcd416f1a062035102e29b70069b2b4dbf70179b8d60bc2ee5a455efd40194533bf560a 00624616adcd45e1fdc6cfeab2b17230d73d91fe0b39f4664f3c6891554f9b8e238257f7 9086c99bcd7f1274b20319c7defbbf3fd8843b87cdb24fa4637ddccc1bc5f7db84442a528dca53ec0465418a6a67741e05f98c14119cb2ca9f9f83604c169e666efedbdc6756ba43b0de9453160128cc43e5eddadd7dfc415831228abf1d741c +db49891838fe23f0530abd4a4fbba5ea970afa5747f6a0a10d2cf4d841581ea2178705c1203f00cafec91d0a72d25448072c9cf7d7ca5580b39f8589ec63128faa95cb0689574a6bebd515049a1eb9699922cde0366b5cd58aa8f3d3e847706896f7e1cac667fbfe94b2eca9e7be79a810806ca4bf53f219bb30532ca2254c11 0199757ffaa2c59e198d66824eaad37cc42d49b2e241b6a60382d05e425e800eaaf32470 b11e0514ca502b625498b3f70cb4d783c95a331d5bdcaa86c210c55759700c35c09b640b236db0f03b12a88899b989c2032efb39f2f64a8a7df50233b865e9fdb36d80a801c20270d95c86caaf0a16dc906fe10447ed5fd662417a8e63cc890f +29d385d09c1142a7c181fe4b6e6132e414c15aa8605b44208c0399464613b966edcc2d46cf203a3f85d943d8eae658695dac74366224a0d0348083bec0106f5eb8809ae8d07f792fdd7c48fb1a25d5ef3bb9acd40b20c61c821024a9acb2ede321bd2d0dda849c22d76f421cbd8d51565d3c4266f666455ca1c0c3777aa44107 006e51381dcf21050aef2e9b97e35303cf3bd91956854ecf9b6b9827871d2efbe8201c5e b42180b7847ca01bcecdf2f6cd74ef84b8f0abc543a1fa3f80a00a249699e80943c31254a2e5797e88bb9829c3dbd96515c1009d746c86a33300f8259bbc85c99c74ed600766268a53242e1b1f1d79494a21e80cb31cfeb1a252ad49323e3115 +774c1cb8fb4f69ecfb5c7857d46415568d88f1f9f05a4bf64a1e1ff6d64aec16e1d09292010d1f067c68dddbcde06ea49be2ad3838053f0b9c0c2383edc451ef0188565118e7b3c66a4fa372b96633dc8a753106283b02d0322df273d58cc9bd061ec219f1e1a9c8ca1400e5e39c1b2c254273377dc98a1a2c44e5c2a5b89167 0018adcc22cb9a2db64bad3d60f1608c353e091637b948914115ebd43679904f955c8732 90abc6ebcebdc061fc6105ef9e4af8e44206a8f3071e3a64bc7a16244525a681f832602d5dda8451674de4bf36bd509a0798fbcd7d5ea254791211cae093f6849708cbbd64fd2e8b79428468462b3add3303dfd4c15195b6e9f4621b045c3272 +c406aa4295f85c854b4db2de5a7a2defae53a319866921a3673af5b48c85ef22f6eb4cef892c790d8e64530fc20c729b2821b5f5e515560b1ac764106560c3a6a05657e34cd6deadfe2884bd288cef4ca92e1f25adde7d68a30fb0a1b3678156ced62e466718e68e9d67099ad82613b8d06bdda1a7b867c2455422818ae9eeac 01898276f159c10d92d8d4b6ae214d68c72792a4b5f1f79936ca3c063dc8d9a88be439e2 8e226ecad22b0454a20b9e5a542c3e783bb1f32b9a193f5ba56f5d25c61017fb5a86438729487557428343c6adb46d2210470b3cd18ad9ec6244b706adf479b01865c8aacf5ab4d54d73929ce22ac4fbd33c7580fd6f27e437ac49175b4e77d9 +cb2809152f8258660933472c06ddcdb65f6d5221fa29d5b0efec9c2a7914dbbf9ce0a468ce146fb333d26f510a87a6bb01bf8816756a1b5df81c5f65360957cae84ba038e37e88777580e91c34e2f5aef4fb55af7b81ad28aeba05e0b1c64a15381a6719fd2c16e38a441516e1b394952d984baf9e051b1dc1bda2e12f8ba5b8 012ff37c808c3cc029a9cfbb67a5ed21f3bf362b49270d4ed0f1e38fad25ebd79f112a50 97f292273245056336f6fb5e33e40d56d377a9320707b41994a4768b53d1bcb1d7abd8ff8a2adaef9ff25ecb19d370c203b015b728c55aaa2ac6058b1ccd07df0cd359be6b35ca2ec6c0b34cbff2b87c7550606088e317087537aacb0f87202f +e060af96d4a7fe512bbf26be9a27bb6a8ff37547d4a7bbbfa710db24cffcfc760dac120f89f642880db2df6307f9ea5441d5932d49762d182b29d8e7fb067a61ab0df622f75cecc917e27d0326085d34581e052c85f50a37713e27518aed7c4434f86970e00a0a4b8503989e72614131b7164c1bdc82d2b6aeac0787f9838476 002b8c1fef9c6def32b5f4127273ce384b6add4aecec957c1662f52334f5ee97f49852d4 923552b058b80313163d601719347e4656254afcb0cdffcb8b988095f57157dae5def9e2bb58f07588acc3150de07ac711015e3ccc92737a0f227c700eea83f2835deb51ef6a94783ec32ee3744f40408e9e08a539ac5a601745c31efcc6163d +d235c31f0a82957a087c7597673970aa39321d4c2640685a03df8388b5eae4825d1fee29926f416d5e62a2e9ca1ea7cefffd31607e750fa9675983608e0f8dc895371b190574d065c5c0c23ffdaf49e65362914363a3fffbc2c1bb487cbd4f69ec22dda5c7dc3bbab805c81faa85787cc176bc0e5703924f395d8c9e7e7701e2 00afb1c45e9a9f02942b8e04da4b815498454dde6643de186625a98b3c1c6993abc8bba4 8608426970d02d6a118e62de2a6a1df35c4fc823a158056737c1278fc1c6180e2ec07ee6ae27b71b1a2d15d15a05f5af137febd3294212109583b320b5f1a5cefc1cc8d18271ecd98647a86fed786d97211505169567b37763a2617f73accd2e +1a2559777a5fd8f269048feda82c4d9fceca95803f84a813789d6ed070422240e443789c5231d63d5268ddebc060dfb99c4eff2ff115d2984d8bbc5c05314562ea6864fd543e7e0a3b8572c017d8ae3563027d79bbe164d40a5bab354720e45094b9b26391ceb55339592fc2f10b97dc9c2649f7227648f5cd2fc46d78d31c0e 00ff537d73a4da0ae3a4894016b71dccef3bc886f3d24a5abb7dd96cf8fdcbdf0fdc5e51 a87eee11d0fd7e158985e0e492a7c05f485521db83aa2a1067fe97ba0201f9f05d8a726404d2420fbb2ba53a6834a27319e33a2183f93d2c9218df59b3b4f106dba4e025fb0c4c16f1e721c62deeb5a57c45e6edc31e9f29d43904734244b880 +658c0d3f764bbc952fa55a258bac16a5bb5184bfa76cee06baf9ee6b9ac3f116e08bb2406b1dd4be487b057f3b29c2043ebc33019b2017c4deccb86f50ff15fc9248ea5fb64261120b1960525aec3cc18827c23291722c5add8a3761ff8516c61956c62b8cbb13f3d92bf3eb45a70704c01bb3625d21c38ffa83a6db086ee968 016000d2e879906d1040b32eb6ba3caff700e5565871ac75f10c5c15b509964bbe5e14c7 b7c83621fcc5d999a1e56fc3eaac997fb7fe7d2be32f1a0bca8f8a4433f1c4a86e4f244fbcf5490163a0688246666c9f067ba65207468061e1df7ffce21b070f4a20d12b6bdd354c02ec76771da03d25b96289c5e1b34f3330e955371c0e13e5 +4f10001e3517c2c1f973b555f4827681e096d860c4db08f1f4aef8000c9c24bebe59f8bf3d7d3cac959a1a5477bb0ea43f2e746b5d14ed48a58ef35484b0ac786d2fec669f945e846ad73e6b77a9e47012a951b398941566330d89125eb3c1fbb2f06adb951ff5f047d102fdf28b5cadb4a3e1a10412eb3474d2ed5c3fce78f5 0019528d505bf0584628d0214bc857150a929d3f59619bf8f3acab545fff0977c9bcdc97 ac7abcfeb1935a93d366e839942a2c5cf4d7959c9b7b2cec7934a0c9b7265ac24170353dd402f9b5a34de7765638af760671d822fa9c882c45c1ed813c044e7eec21a4d2591cf1ecbb4ab9adf43328fc1051cc865a3420fdd91ce6ac7c502da9 +c43ec3c3232cae59bdea7cfaf18a4672035dbd2b8b6b1b44ede376b36cc2d8baeb921e416aa177f5977da8bf1d713509e5251278b6622790056271715cd5feac58bee5baf50b216e8eb886279c5a384cdb696470275b7487fe9ac4c506706f6b0f9809d1ccb102546a4297d2017c2a8df9f02f30d3d1bd9aebf6a92a02e0d202 0067795ce117bc0a389397fc22a01cfd9422cfbfb5aa44131938a8c45e48e1d5a718539c a537617d739de8b6cbb846c7b1b37f30500e738ab94e55441bbac2c9697383258f4e231bc5bbe47a15a4a0c06bc37eab12a1e79d08175b6ec5e2935665add79424b2ad1734ba9df7b4c15a3d9ff8b968d8a1d67f52fddbd1afe173f5d87befe2 +9b7d675a3d2cdeb280ea28289b5fc2a3ef6b535ebee8ad242fb031e2e1f364e8ee806568b2f8627c5a5b4f51f4f65c71acdc1152c08b9211b81907b551e0ff47f5a6aca45dcfa06f09bf195d19d7b165b52111b601fbd97b192f62465f8ba20773b1599c8041e91448eac7a5763ca0628f40768324c5304e1119ca6a1fdb0778 019269dbfe4184249952a651a507584746c5b62c64cb3b17e0158aaf4d086a4afb0330c1 952e0ed5b0ac8c62cb8390faaacfcb3266003a82934ad5ca38934f741718c063bc9e523e1d660920793c6640fd0843d0149e552ae85fc7d5debcfb4bc44cb1691e090cd7085cff764e95030411b306f51eb07ca7107a9acf0549f3aceefd6239 +f4a08daf8f66ce57a986f14b918099bcadcc4308bcde7c169ce8536a40d94a928cfc0968180a2c2a242c59df73ff79a03687998c421cf9a0e661630378779a4744ae2a6cd24ff61d7fcd6c11a4c8bcaf358075e96f864df0998ee98ee393b37bb38747b70bb7a208740959b45174a60153ee566e0f62528e9a5e4466186fa650 003835814de0d6441cd80a44e40350cc8bd62ffcc81e939a4410bb9c9259e30463c453b5 8c24f31e663298c13defa03fe22d8432eeffda3f1e52b33acb03adf9c701b0234b60106b3f8a90bc351057f3bfff81e0076f0f532804b376580c1068661f6122438c563951b47cf388cf678da875af45caa1c6647b3ba4bd92b7f232769424e0 +864647405c70939fdb4c026bcad53218ba1d438d82c9138f0f0ecac815dbfb242307cca52c84826cf6556c51082a23f14252dfaea43ba229f7493db2bf8ae9cdb0228dab9e25cf385b504b92cca94f813acceaa1f18de851b8936c4dfe9e4e17002f02dded6b4c231ea5e614ab46fcdd637b8c6193e8d0c2df1b3d883b97e1e8 00aee83dbed3b703cb6e60d51e373eb20e298ac005fa6a572d02fa1e6da0345558ad2a46 b2c6da25cd649cdf325f984c09ba6e7a74a4f279edd21b5c922f80619b0367b32725681edb1d53881352ac581a3910291144670851c29403710cb2abc14d4e2f168a63d199ea55524c9a986ead258e2550644c565adf134dc1c796baa6e354f4 +c87c8f3ad5c28a027b28ae5021dbe8d425f74181d519451f1fead7a1f9dd102fa6785b147b610610cb59bfa91fa363bb79ea602a7d7e1439f874c5dce748e5c320560c2d9676f3a948754c72b6db249478b7e19c9829ab4de2e344535d3e0b7c20c272f82556a280ef491524b255c4fafb9c8ecb87b0149ddd9d7bf6159e3337 017b65c66514019ff935e9d571a4e68e9ee4463b7b9a754b93f4f7741693f4399879fa8a b80d7b0866a6948e5f427c1b298d1fbaece49acbcda434f7da1f58febe44f018f1a46714cebb56ce8000cf665da4190c15952214cb472438a13d85939f4aa2bf1dbbee3e2e580f51f8d5d7d36431179c62ee1ad670d7718a6c604efd90c62152 +ac7da7611e2ade20aad64b418a16e02e79ab4894d758550210eb10013a9b5533132be701f8843c840807c4167c38d21dff168d3baa65d5bcf285b73dcbb75819f8d7a20a849de335e19bae2aab2ca560b93d340731f291599a5b28afd7737460d291105cbba6d0290e836f6f6c1113d1b2faf90ac5de7c64e25206d79380a4ed 017d2071f39ba35515a8ec977ddd36ca15983e15bcda626f15af61d87d58114f4c80a8be a443a2247857197ad94d536abdca6303d7f4a5057674674a40a598a84716cd43838dce8358a37430acb65e59e69e2cc40ab6c650efbc98d3301fa85a993e78bd12f8648262d42d2cbb02ae023db1e9332492643eb9f309e7e764d1209f4aa65c +5757c472fa2f81430dd920f39b61066a28c870b80e6c96f822f8f19b398c3574d159cc22120454dcd7e97be8211916e4bc8db365b2dbb99a6e597d06e6645046a0abdccbd06741e9c0eedf33cb78d78a540c2a390719acc498331e694e6b0118cf4f787b51c7b7237458a6149d6dbd0a08bae8097e919f970fde920485e9a0ac 011504659e12235855fe55220287a101e511d39a627f8a0d414446385d4a88f31507fe74 a626883a62c4d2e7af086cd25e6f350a90f7086efd0251306cf4cd3f4f2779608884b196e996611fb4983176be2d9156154e739c0cddceebad44c1619d4214c74dd879b8c204a1a8a86eb447e7ab40353746142feec0e2170a72515d90a619b2 +e350383d04af0f4081bf09b95d1d53040e7acc64e56b13b653df31dd119617b800e0cdfeb935dfa5d94f1d7814688d8ce41021810958759cec76560e1e5c0581456acd1a020165849b2203f1c11d318d816697f36a86b59f160faeac7dba71682d3c031d0d547725ef69cbaa28345512e38b75ab011911d8924b2d17a857a96b 016e4cbabb03215767249ba2a608708b78d7387be9e77f5efd2462467fa05e8dcde2c036 a86d0cc1ad71f091f6d6af31a3d66d7c54dcdfe655b84c2fb3ad7730987631bbb61d2b7ca32db2d7ce51e479aa43f71206fee3b92a19a8561234245a16a56866d9b1bf6ad6f098a97e90f60e3094b22bd16a1ba5e1b766a875211e0ab4a10a40 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K409 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K409 new file mode 100644 index 000000000000..14915177c239 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K409 @@ -0,0 +1,60 @@ +f153cc61981a46d8a47d17d29ec157fa93fcf644beb84558db7c99c57fb131dcbc5b65581ced5ff0b29bfdc66ff703ecdd4290f7c353c02a3e6d6867f33f3dccd1a0b6752b8a35fa143f8921a5078af9c85b212564c5b795da9858c7955095938fcd10c21e35e1abe905e84c8b4bc05f2a06091ce876d9519b96951d08c7ac9e 0011c6528939672bed3e8c905b7ba594c3ce95f37fb28044f210cccd01dfdb42c10e8e1a0b5d6fc757834ca7f08e98cbc52b0edd 843fb070808f16229e1a253439ee8ea0911b48a2e76e3474955a810bff10abbc4cdf4f352bbed73a4d136ee631bac1260f0923d5cff80f63efa14a7c8d99da312d38d0a933eec4d0f6a29ffff2e52b91ae83cf5402293b6148d0e0284f511f2f +258c91524423b5c876432b1930c7b07b56eb5e3945f1e2296a4e5bfb9b9123f800ad195d6104641b1f1970bca553c2032f83d17252e52403a9381c1fc18eaffdf026f7537aa27d84c5e3d6e39e651a92a41139cec5181fe794457f556b390943093be719acd23fa1ddf7ff0aaf0479484a381a309b4f681af74bf97caef08c22 007e3b714496dd118d8f3f597961eec5c43d0265bf85723b0b9b0616977e0acc2cf686cb6afa6cdc19114e27ab000e762dfe467b 952f19b247cb33e3f77fc4f91209e13bec7cd0c0e7a1e1d1db90d8999e929dd618f408efa0af3c3aa45d1f9760531acc0e8aea84159c94ce4ca3faf686df1cddf6f4d81cfa757b7f6d231d92789534686c941d91bc8b1891e990beb47f27f8a8 +a16a0d6fd57240fe88c7c36b9f7f9040cfcaa9afc4beeb8300818c5f90cce73b819a12c31d42af33146399cdfa4ed4954d068dbb0f1f342269dd29f1fe357e7224304b67b0f924b794780fe7e6aa9dfa3380252fe7177b43e7b1789718949b9ec1b943c83ed4399491482f0f59d2cb8050ab6f8b5854d76c50651428cd29c40a 00182d1e937b037bf7f84144f7d4c94c935269c9aae7d500aa459a7a0ec113b232dcf282908eee4c84b8106cd38cdc41db3f89e1 a584937d972bb3f9534399d9bee4da7992f13b5758f00dcea11d32e7ed8854bbc45e8df5ed35f82e66d8103d1a4ce9680fbb9ecdb70ddf336735d2554a15e0096f41020124ccf86c0cffad99bfb350f2c443818161101a20c5a1722eec3e3c4d +d02ff569828fd1add21f6bd1c50cbdcd09222e458ee79fd5dfdba3cbb84e9d926fcf196cccedece77d5aa17f8c8cbf3a9facf0f02c71d5c1c8aeda9d75f6fd7b6f2c5c70dff992ef6e02c438fb3c66da5a503b3c39acbe2a069da457595b542190d818015d462670b0807c401e36b1bfe05baff3a8ccf8d1f5f8de7840e87993 007ed09428f460724c8a5225a31151e031d9949493fff5703369c401762345d002c4ce424294baab22d9e71edc4f854510cf0e6a 8ca885659e71e5eee93480a4f487b3bc30ef1d528fe35a2eb57a77eea568a93edacf2a5141d85987d1c2465d761dd72f151e616cfcf2de2f20621d4c2c8695fad8f01e543ac489d4c0777486863b62260e0dffe683cda7c2d3b14706d44013d2 +57befce973b225cfce7f996fa5a1a43acd160681b88a87b7de04544eb7b6a719718f1ca7f559b6531bfc18fca3836d2be7f7a6e48387b7579a6845796d30e46f0dda9d82680f8c96c5f0989741adef9762c3db763cae2699cb6c112543635e20ed5cfb4b55ca2ccb32d2d13936085a8ff95ed658a54be73f80c912ccfe5f0ca0 00390f05b9619c27b800e99aeaf61ef7f6249367d5cfaeae3c7b523a8b29153eb8a77132f6c4412545a842d6deb7b7aea7e2bda5 980d759d124aa151a41f1ba94f405e9b4c884e850444d0e8518967f49a971ddd91ac6a4407330d627c9ddf322268e8d911dec429bad2339e22a4c23d1b4c7fd5b5db7f2662aad8af8296d27cbc7cda639e28900f6bbc2bd2eb7b594e1b329bcf +4277ba40cb462860ca722cb4ee71c61836d2ceba18bc91f3fad7dea478972c6da0ebc02815eaaada1d1a5e93d7ab353855ccfdfc94a5742fe18daee2328871e06c1ab0a9a989d1239df2d2d27f96c415e7ef9a941f06c6790675361173cc229aac7045f49eaca207f59c497619ba32e932b5c1c6576812ee5b146e2cc7de5e62 0007d18652732596add3db31f7a0ce6020d03f3df58131b0c7c633faf619b8210cd309d6c0c4083aef1a1b6d2a756adad0bfe344 90dcb8abc84ca534321f0f8462329c572332947d44bc27d64bb2530e32014707cba2ca5ab7551dce2544a3fc32d313a8035bfaf28a72bb6230d73d3e39ef24ef10b1a8746d42f218e96ac0a6f258d459d973818e6322ec5f2e74227a110df448 +57ff6792ed4b12220d179bc0ea57ff217f322c85bd3676a681d32d7e4a3e0c8e891fd267df17caba5992f68c35ff670b60b4bbdfff82404f6ed996c30539bc395120f97d4d7a652eaee82bd8f9360bf8bb73748b8bbda9f9480eb54f7eaf2609d4259329e8a5ea020521e7dbd3ec56f23c849932cbdf2875f5d5c774a9d6b0c9 002a91244ea4623b63403dba807d60b914ca3b901a2523244c322f2f11251446d3f15e869d086ebecfa1a39ce304e8b5c8de23e2 8a2b1209e0fb99c7c432dd866561e17ff809e96a87a4b99f0b7124e483a19aa062dd5653f10fe3de458ae5b5f53e27e40360497e194c5c5f3200e0af4936312a4defe66763f4fe35910fa92e07f0d7c7263f68c5688ecf0f6ad21b2d0bbe3a91 +f85113eda64478f460b60f8084220134933de049200a5f37884da7901471542e26690a5fabc3cbf9e679ade71b6e54d869bc136c3d34cc4a9efcafb777abf046b5ae5429136112a9a36a475121eb1f33f1f43481286fc1ada98a41064a1fa38c89e99a93065bb2a119348a9e452497fd5a0d2b83a66b09da9f47a0583732adf4 00068c56c6b5d50d1d4e13d3837d8c5e8ba2f825e121b63e97603fdfe78bb6899600ff0dc87b6b3b6868ad0d2f62b7b7a31603ff 8cd7ed9f2c2af1a751ef9f15bebeae1a78e32ce4f0cb1d28665810168f661ab9ec0f26c73c388090848a2eaed98ee0e70282d03b53ee7bb26e25d747a644f15f71c207c6dc448281d9de8252c65be0bb40bc595e77dd5312b161230bf3cbe139 +42811e9ee6dc509572e1cddbe5baf00afeb0c5c13e3755b922eee9e210001676082bc9edc3d78db2b5bebea7a2c0cd2b369226c2b8f83b28f33fb513407ab9d287d14b112d6c3be2493805ace5cf6fd366d03cfb28f4ce3f0f060880db64d6962e997463ba7c05b6fcd1e66babe4b94afc5c2d38c7050c69571d27b66ef0090b 003c88084f8b78446db431bd6e240a0c050813d2a763675b0ea869cbe183df697146cf29c03479af3d34587a95cd257027fbeed8 9649e1621e806eacc96ee533491a7b7c6d4c61c6a74044116163bac4842989e946a88b976552c92f1505cac57ccaca3b112e6a0388001e0e93dc68f10e5650862855001150b0367f7470f1a4a0414e0b8cef87b022b9dc353513c0a57b5db127 +b38f76ede7441ae0887e689d556f43155b38dab7cde487ce9ef9a46f2957c830d4d28006873fe2368197a6931f6fcaad755102686a457a7edccc8d344e2d2a9162e3d71d41c09a022539ae6d404955a6ad748231aee1f974d4f159940532fb3b1fa0254bfc5805d2fc68696856fadea386c542d3cefd1be3af04ca595e54be25 0051af7b63bf3297ae20517faaa1552f4fde65819dbbff6a52721611e5b7dc1242ed6e69768cdc37ea8cdfd1a5971f06b84b5803 82aa885fae8e83260a1e001bcdfdef5ed9284f140937e2a41e6b19be0a88dd234faec61811b4b691129f9713c2bb68f80b832da67a990d31d8d9e5938758a23bef1301a501d9a33974e42aaef509e0345c46264a6756dbc5a2739c971f951ad8 +356dc86cef7979148e995fc5abe2b14a7d5e4e42c9b3509b4363bb80c581a66f4e7e4aa53a4bfd37f9a7eccf75fdd726f348f6a3f779e6599f61bd1d668517f40453b39bcf35db0852a6a6218198f52b7ceda2ec55fca5abe8e5d93af9a42b9ae4de9530c5870211bacc27c39aa094013db703de2fd3121f08d7e97dbd4e8946 003d65bdec48972d03811b78150a06956eb22d337dbec5416bbd8185a6322cd8c0ff8000210dbd1326422289071cab65175f5d10 93b42a4a2dcac2d1d70f9cbbe465dfa43f1a65e5807dd08248e4370a5998f1cd53652bdd83df1c85f7f2921328122078100abcf52c8656a4fe8b0ba9a8089ff249a3d0011dde36b6360de9ee6df23edc0e4fa1ec6a5ee2f393a1c80ce728258b +06fd39a50bf25e89f1071ff81fec5d1e35b6dd68990414ee403dfdebb792627b6a4ae3d2236c159e4441ff90b61ec87b1592c538515f0486b19e58583394a05e6411e69b4285d6d6589982ac0eeb2c912c4948789cad741183663fc070943389d4e9a1150b8f6088fc50605915e9e24b2d98a1f539024770e4820e14ae42ea8e 001f1a8b5f35dbbf82c102df550c72216a243f986f0325920f6186a16d1da74228cc02be6024c7411160c183c923c743354f9438 804e37e973e5d7926be3814fe8d5a82b8c945572271d041fc43e8dec24138fc5f9c3f40c15026a0039e859cb0f6b788e0afe01350f314a43896766d8bb605cae4608d0ef9c67256af57909e7cdf14723721d518e21e151325754a1dfbb7c0c05 +6daaa41150ea252a3e966a338377307d909b95080e006f13027f2be5059d9208930c5a329994c0b794ef50eb059bc6c215f68cf42260bd410f9bd86d2ad5ab7179c7c92de4a93a5f6aa17de5aefea815e7c0b78a8cc53c21dc4dee037b29c9df4e12343109283ffd5d8a3b81fba1b5e95506c7e01ac056c86dd0ee23bc21af0a 0031dc621200cd174193d95e9092ffb86189c52cdbb9ed937593f2cde7c4a0264b9100e1b8407336c8dfb5520d28a18dc4e39a89 8ba0b3853a49f20bd29f916e16a67bd242f461b8ca550e640ef76843b7a1fac23a505463eee8c979c6f095d6490fac5110281409e25c7ee683da9b6f38099384e1e98d38160980c81052f696ea8a24f64bc50b072ad36a40029bd21fecfcfa80 +6378dd1c12c5197b57d47dc46a67949bdd1e0809004e94d49b0234126a08ad5bf8723ebfd132145813136d8b7dd096f56c34248f09a65c34f60c2f80f9a51b3795f3d2518b11aaeaf6dd45a323794080b78f85d629e5fa719b6ab0b14c78cd908befeaef0dbfaa08cec9318bbcb376d48b11b68735c9554a45293db5e9239ae1 0016e6750245a88340b0f0665b890459f8038e9b1366f2fc1326245a88d4c523ec94429f21869ce3dbf75126e58f77241c99efaa a6771ff7df7688b001237a67e3d8f8799653c582b64d135237a5badb9392b31d1329e8b57480e1b277ef6b858d8d656c005e1db6f4c9562a3261f01c9e04fa5bd87246440eaed098f89aa9b58f741eb47cd078435e17d219e35c98397f97307d +b898d0f9bd80e083fa541f457d14d853bba55b120424a95e1d9511c8833f48444329e0349d68204c4b4581ef1c4dee23ed0a4445727a72e1e6cde422f7c10ae132a3fe681f9d741fda263e73f7cdf10759467c9d76164086abf6780ad474772771eee22d195339bb8f6235e0d992bbe282b13ce4fe01417f507a2c4fa155e108 00788fabdafeebb72f6385301e30024b56639e629a400f9c50d402cfc9b5817844f06a451fbda29c7ece41dc9ffcfc625fe0ff0a 977f48209dd95e38e650aa04697276ff55041531d494b7adb1fc878de63712310c260090d6593fe0fb0e185a8b7210570ce963e27514aa7a3a5c01aa8ac451a0601e23f1ed17b90a494ab42b80022bea7e5d390fcf46bb3b4097ba3029879f37 +dbe04561ea8579672a2b3afa94426a3cbc274b55263989d41a778bcb082da797d84d930ca847a481789524940701cd5f1d11b460bdac0bffb0b3a3abe1ab689c519700de85a0a571494ba0cfc3c865450eba7a9e916b7fa9df55e8a1c246c992e6a0b44b78274e008472bed8d8411633e6520e1a906c5d0c8aafd572fe6f1f64 001b8dfd64563dc219d6eeb53f2e3ad1d771140d0960b211dc1f757af5e297dc7548d6133ddb574711d466688f80dbd65a7bbcdc 914650fb90e6f0cef041c9bda30eee248a1f99f295a0fcd13e7fb53f0a907e7facb65da1681fe0b51fdc29c4b4b0c5950ccbad61a4a49f22aae4eae1295545604bfdfd4e3f1d3f113905864ace53ef8f699b6ff89cf5e31545946090bc8d0382 +48a8300820fea2ad83c83f7d6b24192715329c3f159d56644e11ed25efcbd3d31600a813b909812987b97d1087e74a63b4494cc031c63492b6615e9d6e5b36f62cb2ef88b9f736595800de465789f43811165a5fc093ee6d776008739de8de2a84e878748641be8bd52e5b891c4145f52bbd46644852a43108e93d86352b2a3c 00422131829608ff730c24ddf7e8b4a2600eaa9681eaf45432daa7d41fe2fb488fd0199d431a1ed823801ce21f4f01a4dd4248ca a07fdc4189dacff7867c4dfb6b85271d99941c7086bad260731aea1b2378709eef648c4fb52d0bbc9c2d4cc9db225184030acd67a123a2108f6711f69b8cc384822b7118b192d586e7b92729791b26b8e42add0b5c52342e3bf6cfe1e89f7987 +276e3a986ce33256014aaa3e55cc1f4c75fe831746b342eadb017676b0cba7c353b3a2b554522c12e6aeaf1364cd2eb765a404b3d0aa61258194a30219d76d2bfa98ad20e7e91756cf65e50d7914157f283f2ba3930c0ad3a97532cc747b1cb9c806fff497f0322025a3d02ff407fc7b5808585b91d95523c9d5864efdf7d983 00095ae8e4c7e55eb5da01acc05ecfe72a4dcd8ec152f1c8dc165014f70eb4e4a7861aeb2b96c418b2d4db58659e76184e013a49 9073efb1639f14a31b064f6dbb4606e686c3a19d3577717adee1335a0bc66efa34ca43a22a2e2eb7a80e9e885c4196ab15c3109ec8a98d46edab033824dfaab18ef184daf112e6c509d5065bcf5cd6545b6e38cde7512271c7d4763f6e6115bb +6a4fc1827c3a7256faa8ec6a0f3d23559d6949f8cc20e7f76111dc4ebd59213951cbf0eadacaeb8862d6baa0cb298645e4314b1c303bd0d5e9893304d4b7fbd36ab05fb6a5edc3fef763e3a4124d61539eb616b359c5cb55b5e2bec50c91dd95fc39ddf521aa854216eb5a707819fa6f067b316a17a3b146e7cc2dd517f7d63f 0006f2075bd730f34df111ebda919167b1d3358ada32cd6747cb3353bcfb814a77ac70cd51b31a0e538539453bf9eaf9d8b384c9 b48ec5f2706778f1367f1c9186b5234fc3b6b124625de55cad0e3e0e7a2177f5503cf878b0b31e27183cd0ab0296768a081281a9b7473a864ed7ba3faa39a9fef2d5d0ab6de4d0665561d7ee2f15051c9afce97a489eaba08b92705c6dbf97f0 +4b088199bd8c94775d8ee508377d672dbf50f6d2c7370e99821ec8f9387492fb2eebdbea473ea18465565f79e2af418555f10c4a527e05a9e20c9c00b807dc8b350cd4ccc2d87e91f66addf02ce4f43597aa258ac6fbe9365cc2c8e8bbe5c884abc929710e8423cd6722a8f473bb55804159a92a3d8b6661a536b4fb9293bb0a 003887d284e9ad17d38bc6da9d83c192a434c509340a7f233cebb032b09ab7c4c6e8730b4a80844898616c9abcd16b753c6bb4c5 8dae50dfef194a66dfe85944fbbbdbe0dbe585a99d664961b1ce7298126e5585accb6c50118fa18d00aa776ef974751905734ab54d2626d6b73a7743269edfc0982a7f7d7ea6ed40a39bcdb8e0b006567b393bc903e9bf97e39bcfe5518655fe +848a13465ddcfb2dc14f7bc0db0756832c22dde1e31e4d8b3ae0dd1aafbdf15e954889e95d3bdfd6e5ebb6171fad62592c23277a89e8ba53978c9b1afedfef7e1c3f6d9f31077530460b47834b30bbd84a4da601be988738aa815d3d7e72043243a5288751ee08b4815a017fb5d9bd55833698a0d526b1ed79da35ef0fac93da 002ea5430610864257c9dc393c3addcd0d8d5bc8aab1067643b08857210464428aa85cf1ae6c743fd2682255d4c8eaa46ca21e73 89aee39d533c9e68e78b63fa5d0a38b7243c182017fdbdd7a80a981dca622b16b176dc9202aa0b66efe4ca1ce93a19540b81b2754db2c04fca4ae3494c2bb00599b22f85d1c534e2813ca639d56423845c0ee76834dde5c18b382a25342662a4 +d1850545c04ea65528849973c220205c35eae98826d169348970d1420b4d872ce233af1daa9e62f6a562544ae3a0633a954a493e9766dd5d87e47486559fdf86229a7c9e1726de21895abdcf2422d438f4ad98d88b45c56742694ad5e11894253270997c049f0f419842482f21c792fbe5613e2defecd485585f1835b6f4c578 0062c757c92eaef41f5d81169ec4968145b5aa2bc1d2a3a5fd000634777748ecb93677b3da12e3be33272a8f0a52300f4a5a37c4 8d08f6bd144565157a3301b8b0f8d8f1d9bba6bfe681ce11fd0be225423e9854c34e888c5abe84aa532d82a273470c4509256c4420d455ed1fa0bf784e31c3752c118c0301ca7b9853a8db27506bd716dd0b1d2f062e1ae78fdef04e934af9fa +421c9784d6fd507c82904e1054edf9bdd1efb58a0b211340086069ad38b7b0dd15c2345fa8767ef71254ed1bd5c35f742b1d3f4765ff9007a5477ba9e5d3d5a5cb5fab4efc1cad73701d4776c6c4343f42b5d94a9eb78ae428dfe5fbdd8e6ece09d5b75cf4346cf27db856352225ab04e6ea56661554fbc39916accebecb3935 0048a313c0c11489939fc0cffc6ccb9f179093c4e13141b92dbbaac441b7ae878c9d412066e95615174a24692555cbbe904a14cf a30a592ef8fc00605293fd15b3c58fc4d07589d71fea3c0fb58afe27acde25baabee13da875dd7373ff3c262ae84414e16fe83d6d350395be83236576429ab24ce578c375368a4c3b93215b4d82b77a256450afd489d84d1d5f4b47e47e2ea5f +7910bab15b6429947655e33a67f41b76f1d7b71534f8904d6a0472c2faded038565272d0b5f51aa915e0d624e9ff48d50ebfa2f09324864f26c29ab73eb39b436c5c459c7cff4d2b62992e3489cb4ddfc05d7366b161a463aa1b782641d93507de43c8cd0a0a0a9d1c644f4554e3edaf7fd794248110ca9387e73ae5d00d299e 0046e2adfe5d3549e1e6fa1fe69a7cbb4ac9b111c8903d544268f8318b0b47d4b78fe3e56eb5e639ad5382e7cd5bd4b2c3e70ef6 8e80f1ab6cf1a72422502512073bca68241830321a6985a798a53acdabacf26c0381c1f53d3915d09d4d6d5c54b7019411e89a03bebed3017c6ecfe7c3b2e1dc0f34161d617af122534e8f043b16c049b051df4a19ba888f7cee27ca7d60cca2 +e6fc96e060b956c25d50ad25443f3c30a12d199a47451a49ce88307201dfb15ed816982e8888a28daa92eaf3c5584ca6ab2ca9e14577f84396de2e0ac214b24a2279f5e7b344fb7387e9afc8f0a2b77a4d024a20ce6183499b17096947444bbb753d9b39e5c694239d28f9c454bb05468d17ab564ee6cea3741747ccb7f108af 00480103fd6180a431c837643566706e2b9597de0a1346a224d176a5b2c54aa4d064418ed654a5d39f4773fb509f86473ebb373f b95046e3fd9781cec57448edc2e8d0d26ad5154bf962fb52e4410305ae1de691d21ce6c03f2a1eedb045f0d867af02620249427796d3e6f31e688cd4756d6c7c53f961234bd5f65d628136e65d7c07d48fe8c0ca1d652253c1a27acd5cf93640 +c8a8a0d41f35537e6fd523ee099eb45e1ad6ab54bed4d3e315e20227db03292e39dc1a91bab439c0d20e36e7fea6ef08983f390a6b5551ac3b4f1895220b2867fab95552cef9bd8702962839bd9b2c72772640e7d3be3c5889d226acbefdcb448432bc503e5a5fe7ae9ae7696c720a799f9882c64ae0385f656074dd8a6821f5 0013c489e8311c6bef02c8f58903b2ba2a98a27cb935d75a30d320af9a14fa3cbc6adcce09235a9eaf333dd05f4b2f1694985dc4 af992e97b6bf9a43f5365242d2ab6639562e4596b27c1a8cfa128aa532a34dc2358ef0f713b24f950bb755ad7ee43d500b67b891af7b2dc6c2a6bc5ac9387864e523aa2db225028bb0619303fec8e4673569557d1b903bd28722a38dfe1d6326 +3407cd6d2845197cd7414a30fc3df7184da204222ffd65c4d16a12cadabf603de8043ea14f5e6ddcc22d3572dc06dec1a23cd924e1847ae285ecf01754e2d1247876431eb98e897e47412a2330bb32990f9714122109e94b38f82cfdbbf2eeb4c6f88f5dbf9f0ccb47939df8be321dcd9bfd9bb99cac9f94885fee7d443fbd87 002419bd2200f8e1d87db848b0379741685e680d9affe693eed49d82931030b6cb05d21a4965f4e1df2045c8513a8f574ca9f2e7 b7ad1feaf98cdf4e3c5d9f55036decfdddbdbf086cba355b633dcf79cee2bd3e3dacf2bbb2882f6c7a9099e2303a70890a5b6e00eb1c6f23f7d1c90554e4818882af0576c3b77ad01222d3bd9435b504c015e4e1c226f52e345a3aa3b65cede9 +ad43f8440071285d01fd79244907803601aff4bc5d14c77483a87cd742144d41c68269d76c9a83c09d2178bbcbdf99f927b378497ffdc907a75a3b0ad019e69758dfffa480871eb6e1e17c8539373de611a557fad120d0bd147f8debe5f09a02e56fb607e9c1253ed592071f042e42fee39775b407225a2b86a950d81bb7d7ef 00722951879a65bfcb414e11712ee9431eeb32319e0ff28601112f89276ffc2b96eb65c7fd77d023f09914a53e2aae2c84652bad b15920c579de22f28731b92154281ddc871f7207976a7fe1f4bcad744f1e590f8cb9943e22f57a00def8de4aead517b900c2532d69e3cd15efb241f4b1ec2d67bb56277ff476cf86a50d1f3104eb74e64ba5b5dd6ca27853e92f8cb5f96f226d +d61a3765229dcd0b4fa6c57280f851ec2bd54d3ee2436935cd6d94e0120d0844adda163995fbc4cd9d7275da859ad8ebf30af9efbdcfc31c7c9ef42bce9011d37cf9d15fb018e117bbc102f7d05750e5072f73d02c2f45509a55627a78cbd9082cbf36807759d1fe2ecbb92ab30cf28434941712d38bdd100955d611987b5968 003f5b5a772d24bd5454bf26759dbd433fcc7bae4f5c593664c4d75da0cdf9430d7d9162bce3d7f6e13a344259da5a7d6a1635bb a24e2b8a1f950e2e2f180f5ad7c71fc4ea2a46e533e2bd987ad739b3f817799374f9bad5640f558c9daeb1f858a209ba13e0183ce4d0111c4e36544c61d030f4bb9c750f05b9cbc9c5f67c19b5002cd8a7c4a27a9804d9bd45e67af9556fc841 +1f3c23636414ced48fab6763eed5b22537968e6bf08c178b3d31fb1f6ea773c6979759701d94bc1bee7c354272811edec58eff50c93331b22723d460e56dbee90466b894354777b23b13a37d15a84c762caca70c01518bf34d0c2f072145d274b3b6c932b48bd815fe81161d8507ffbc2f783bd212c29b2887af6d2ffa9d2b4d 0046bb4a141c9099d531dd23ac440eff1f5b10f7cf34920b6b702311d490d25344c665ed5211d401def24986c8094165d10f8934 80f8effac0d71cfbd042f2ed5ccb91c1d328363f0dd37d8f92e98ecba0d8860457fcc5d2e68a2305e1280c99d09ed6a201df137e44d48341285b6c60e870cdc1c3b7d15143c5e517d4467b067f907e95814eacc22eb4c8ab8e3cafb617451d2e +ec69f2937ec793aaa3486d59d0c960ee50f640a9ce98a3becffc12d6a6c1c6c2f255d37d29f9b4d068373a96beadac98fd5203a9f229bfc70bcd449640165ae5128e3f8d057769e28356e73e35d8e9af7876f608390090892c67391ddfcc1c332aa61efbf72d54bc615998b3be8ab0a9d372784bea48c9fab244482c75cb2de3 006f2c6e9ea8109223d9a349fce14927618fc4fa95e05ecf9aba1546619eaeaca7b5815cc07e97ae8cd1e9973ac603f84d838393 8e4e8cd37c4b73f9c49bff17c0dd3b73671c6cda8157c7fe8b1822d76e1e1758cdea0b724e299af163cbb1c4ae5d5e6408647eb116139a9fbf1080cf0aec1a1d585ab581b2bacda63493ab960af503a3cd23c4a12dc000740bb52f275ab9c65c +70e11efc78d7f079ae41ac3c31c96d3220f4abfe23814a2a4a78d9b1a25e838c3408bd416062e4b0a5cdadf0c6e16a11e00f59711b417751f5e4b43ecad99efbdb2a81c91a034e89edc94eb552c3eba62808563cdf64453a1db07daff8742aea4a9fa738e1322da316b26dbca2954b2bc0de6da7518d28e6677dec6ba8af4285 0004212b7fd913d794fc6bb33e0276e349c052c969ecbf6afc89b28f75a599a9242acf74dec9f374361ba296ba42a38407f9b7d6 918e42f54f7d0647c6c4b6a07a06b5c843a73612f2f12b6a2eda13d332eba2e3847b08e89a2b116e8f997f389813f4cd0201a9eb284e6870685283baa9243517a6e098c0d64a8acdb1e7f2dd7832fa696bbaffef722b6765c33a7615676210ae +d922fa515e3bed60b517a2d37cafe4c041e5ab4b5c8d8d4011bf9fc4013dd8abf7add71fcfde5e71d6abe76bd0f749e960cbed55711c87b5629a2c39cff48ed7d0feaf5cc4765e576a4959521f9a45fcba0dc65ae618826447e02ce6e1cab5ce8d6c96c3211adbb0660de7df7453f3aa726016941d00d8ee536cc106a603d126 006baeebb5ffc89c94c3e8b37b9b0904e7c4b251d204894655bf3b1235710215c29820b9d401c9ca7df1404d2d62d708aafe208a 975ed403681d0267ea961fca118abe843e3004e8ef8a09679c76232738f738307bd3cffa522129115e56024afa3d0d6a003b5a0099587d39b7cc97d93336ff562bb203cc6a1f5eeb4119bbbdd4e0df8049dffd7cad4888acae17f6c69bd8cffb +4f64d0f6bfc542a0d4347576935bd68ca88524ead03b8d2c494061d0658e6c3e14576b5bcea5f2f992f54cfb52b5c7cf1dfc517205e0454510eef1b7054a8cd06ab53ed2468193f98ff0dd62faf076549ab2a270f259276d5729996c120792c6f466a74ab65035bf38ff2c055b43e2a8b8e2449a2375ddbfc18242157bd905f8 0008e5f66ba53e7caad1feda122a80c32c82d2c32a7237b8ee8ead44ea8f2f01d77c7056b9dd60b92d051f060da8532c1fd0e8f4 87b7d9a2ec689623237c8b08e50ead7decff686ff62c303a9e9a1343edac154b5640a659c0858beb46d9a01547be63ab053488fa33be91d44f1823c19250c02d7c7f67b510933f1f4a0c13616e52f28afb30fbfc837876d12d4d6b0ad02cedd0 +7047d478ec5282d55db8c19c97af10951982d908c759ff590f27d57e2664f08d526cbb2bfde39bdbb1aa3dca5a8d3feb50b868be6651f197abccc9d8040b623de367e2ea1d20ecd302afb9e273f4be9f3f64f2c2eb3f92d5e0e375db6549da2a589f0604bc7146562ccefd15995a7c4208f640e7a17afbca69cda4e173380523 004ecb22b44e809f89b16abb10be062c89b41ee34e110403e42a20ce59a99afdc22f6f6dda56e1d9d1b8ce1d057f390db111def3 aff4ecd1cf21a4727894936afa175152adb26771031da4ccf8c13d2de66e56d6cf46d97aefadd94c292a051e1448ab3a04b878e544443569c396b6c9f5e59cf5c25f65517d452c4c6a71a4bde46b8100ef830fc4b99165a5eac9a93216ce2c72 +1a8384b4771a410663e56eb36c5d9ede8d161a8fb0e31d3f74bcb017b9e31232bb2e2f4c65a2d85bcd1cedd93ef08d4bb4af0095731574ab3f2762788a1ba3bf0ee46684da8d9dd384432fee99ed3c69213d790a5d81b351063eaf2bda71ca4868ac36be1b571024a8bf09039b347fa996d5d161078314e24b7d073e05cb3d48 0051f9500c15ae73d6d479b9f3d2caccc2039d8d03820befc2aae3bbaf65d59bd9cb3c4e3aa8bed5b3acb70a5566047ffad80729 af85cd00e011ba6c30e4e02896730a8f9f9d5c4d8967459f82f5fc17995fb1828688d63796c3e2ec5fc83f89d1547e2b0dce15a83de52a543985a227f16d48e2654abd52bc095a7d31bd9e00527a37df3c4e5d6e64b902f339d6a3c4533342c0 +43513d6dd8bb0af7a6f5a2b35f99957d335a48d54f2c4019ce9518b35441d4935518976ab1df37110b5b53532cd9e2c66d9f87ae7f683d7efdbe1775a6c15eecee84c6f879999d0706f6779dc158c111fe8d7201983883bc8334f51dec60004eb1087347bfdab20f8f2f260556681e05fdbb8a6139857fd3bb2df5bc1f2dc143 000cf01dc4462cca764f4f8cbef48c51980737b9b98d1384b8de9f4c733829db7718a9b5eaa46a8475c2144fe4454cb8eeb0a443 9769cef7ea3ea7de6df34d86efd30d05851c610fd12cb2520f83f309d6460b698e8c8cf3b714a5938b629287dde281e2111356b0f38e5a5d7916870191fef82ddb78a7c87368307e6b449e0d54ccf4cb273b14a2a67ce4c8bdf7040b55697e5f +752300bc5066d0efaf807183a41725e349907b7339d77c79921ead3c685b616b0eb97e708f3880fce0136c510c8cb53b22cb424af6f1c34633600939a0647c02d8f9601f9416f1d24a51657241fb559c25dfba91402cea43bca1a13718b3945b048725f3df560e6717cfc6ebd894e29bff1e0c7763f15b8ea93e67385f059598 0063a9a565497974c6dd459bea0d1196d74f263f333c31b7e8591499960e1cd79e2ef4cc8709f6d54713f873b16e7b0be42f71c8 a06db892526100e7a351039ad404df18c7b37e8881c1ed9d08e6ca97be68790dfc21621567e1fb46cc16b2c34bafa0d806e44ffde81ecbbe215e7bafde967f5b6cbfc4a147b353f5fcdac41f1aba938acc5c45c0f30553cbf3a4be5b4b13d630 +f620603489944769c02e2f902c2299dd5f32b5fb463c841b7e1fc0249a85d2c31684bd3daacd97de8291c5d39e84d6e59d3dde1b30c181bfe8d31b8d8e080bd191690a67fa00024ac8c1b10981b40d4f88789ecc58fc69b15417fff34834e23453bb9933a43d08afab74d056f366b40ad167b51ee5f008db151a12b467d3eaa2 0041074dc186193d30aac7cc6d269b938ab40b257d095e54ba79967a377a91b8f73671470cd07f0a3d1db7cf0a31ba9070625e43 97f29beabefe4fe90d3728a2967b11cce4155f88e7764063ebd352737ee8bb6f25fc874762488fcdf607ca11908d44b218fd705f558e0f5b90580f61dfc39db694f2207a86c78d771d8a9bdeb1033627a36108467f5f1d698512c5b019f506c9 +5575f610762b42ce4e98d7bcf45a7a6a0d66ec7f27d6b8b17f1961249d905bc7e58e2ce0806d467f106b16285dce4544c72666d08b5e2276cd0c4e13187cbda8aecf57b1855afedf8fad39ee4fe009f204e60bdbec79b123456ec2d85631d382b8a2f2c7634af3992e4707f7b4215e2c9d3b0aa8fb08267953883a4213669d33 0010820db54ccf0226161aeaee79cfd2797f87702b4ee91adf8543b3c9e79579d0df8a889e366ec1e0718e039b87a37c24d620e9 816bff6e09f743cb2c5541480d005966616bf34c3d7674f6c9d7f76cea46718b82356f38f417bef0dabfa3bdea217e40081f78c941634ce21cb64162673bbe8ba1ce9bb2ad5fe98cc2829a95a7d3463e2aede39354f86fe3cbe8d6839723886c +81cf067411dde2d0ab04fe5fa1e28e6975cdcc571588de60a35bd956a535fbbda4affd0803d244f3f7e6902a2c9a7ef2488691b6bef7f8ffb33be09ccae4c5285265e4957f7928ea5cbabd6823297f59a7cfc9939a49f26bde74c4c69e2d38c1efbacbcfdef011213843158072be84ed3c1781f67a0e2d4e9ba76a585c17fc0a 0059d2a06e8bfd5e14a9bc8777958b85be5e97af892d2cdeb0ecbd2d5017952b5042349db5fedba2e26e7b85bbb31ad313d99434 841c651176b94ca4a873777bff4cf759d31b612ee7fc3954e8b0b035f680a3e9af03a45b1e7fb7a9a226a88c09e1aba80f2c0e3a1d7ff1640224a95ac71bca9b0f4de53a9967d5fbcac357f139b541354d6ea066dede74f1822aeb3eb2c67672 +8ea18387940035cff2f37278d321b344231075db43c7fa7fee9bd3fdefe5e8f03e7af9deafa1022eb108e19ec11fae34536a4fbac2e8c8139a081a997c080cbe8f3e2d2a72ff26edcc5338b21372fa1498e439e4d9bb12d51cc539f859047957b1b1f1fc30b90231eb06b365a4d404a1fd5a0e5cef171fc95b04d0b557d78ebf 00405590893cbbe18f4ad99df28b5f9d17f8f1882269aff0b7eee9392859d68927a99c942a3075269ddec6d69c0df2d76ab9d801 86c3533231b620f39cf93958ab3525f4bb0927098fcf6101f45bacfc00a4dc2fc297718f56cc35966949b1f356ecf5da026ff3b7f89230d83e54517142bdd5ca776464793abae876cfd2dfda9eeea0ed14c3f8cb53c1f08a5952fa242f84fbfe +6a253c1aa17b2b1e6624afc8e7456d366ef5b1bd78e740538260f395481148a64da0b6a58cd53d7e06c691beae1a616547cd95c4d259a371e51c2c0e334c8a5311ae31e4c7af325686ff9f7a36f731010ee1a9b8a29169ceac36a060dd23611dc9713c615424888bb574ad5f5755d7311bd169336ae986c977a394bf16487c4e 0062bbb4f565aa0f23b88ab9029d33b995729d10fcfc33ba7c4051e2fbc72f15636a834e3ebfe604b927cdfc89f53c57f36890db b8e4d6377705ddc0f3e5972fa4ff483c2cc15e65b5b43356e294425c7d393a77267971d5f1206cdc496891322fe3273b0b3f7d5d4b7a9656007f97975ebba31ee8455baf54ee437130c890a8cab097e1bdaab828559edf8df7a67c70967c0924 +0f91d0f0139faf3b90a3d4bebd7e96ff6bb6f90f6c68321fb392637d8ab2a60d649a7b7364ee6e4e274e1a8d342caee36cc11c56c54247fb0a8e8ef81ac4322b454dc9a195dc54567bf47ec8d4fa4cd32e76d78ea2d08bcbce3edbb68fd8597e56d5a9f2df4e47b2701046df89615961db601bd8204584a6a6cfbb627e2a1190 003fad7031cf8810544a3e4bd1382c0a2e22c5a9fe4804ce67b27591fc516ee81dbac841d399327168aa6abd79e2b5ef85df1528 981c4d085099bc7ad59734ee7e695c734c7c0e6db1e519d637f3bdb993ffd05818aa0f690bf589e2c4dce8cde499f4e70c979e0b1bd26796079f145788afff9de8fd8cf226d6a74331ee914f3f3000f4ff344e28519d02da708437ce8e968e91 +50c17c1fe4dc84648e5c3c3ab8f7c971d4c58d8d56d2b5ddd92e35e6792111ed8dac7644ac8a07ca8bb4e38e071aa47b22ffe495e9083f9bf781ac1b5fba571862c909c7aaa7b8d05ddfb7ef61c99700de734d5658f44ae9fc908c85a2dac8e7f854d6d24be805fcd7f873a91252985c5c73129c60177ba8fd99daa87b25a073 003db41b4f637fe7977c90e4f1a21799baaddd1826c667102414877138436cfae1b9959842b8097b5276f15f2b982ee59df263c8 88f02eed1a4b8ba057e78d207d1b634bc930335594c5d8e44578a62e90878c5b00a1bc94843bbcd4056499c594a3c50d02bf5c9a43b7d320e38fa149c991252293449a9a28cc0c42f0dcc4eefa855658423a8c1d52c5d22abcd455efd0ebe509 +3583a3226e2dc463a462fefa97024e6e969c1b13bdc1d228e2d7823d9f7c09012390c2535baf086588000e908309090daac6e6d2b06d2ede6fae838ed47f30b5b481185f607a3586f6dea47c8f84e9d3b96d5b0ebae2462fde1e49d84d36658e87dccf5e30c0937feefd8862dcdb1a1ca373f6ae41641502ac54df6633a8cec1 0065b76c6093d9c49591293471286df1a4444e60d9d06cfa114e175afb5f119d2abeb273b0596019a0ec5db5b5869f2cc827b364 935e3c1f91de090a5cb3f89ab228f97d9c9cdee44e0a3c51310f5d03fd77f3901631e37944ae0bda933b784e3b27960413f5d6b7c923569dffe74ae4db7e1cbb578ff55eb91753fc162b02b4a0aa653a95fb6b92566ceb41fede1a172e5fa648 +60ca58462d53d074b370127132f4e59f5eb8d15594dc721a94286afd082a8934e52462c9c1c3910f8b50d7aa3671dafa5972958d876d7992467b2fee3795a6f9d8a7bd3003a8582ea8c003aa1e02c08ab6804d85bcfa13a815d75c938671f0af0706c68bc70a6155708ca755cac2fbb68b2952208d63e0e2e3d816f04c61bc03 007e9993f3fc1fdc4c376ef77ecded96006ac1159740bd1b2dc6ae3d97e15a67383f1fc931e460b9af3fe14a54e47919667ed06c 940841db1c66ea5bf7bbbed22d688130c1f4e7f43c4aab230f5471361c7fd307f6bccbb6c23e8ec30f4a2630be412c18075ed5fc95412c5a9539c1f571ad36fab7fd3930cc3bf19e03e628a4166e7a9ff16978346b6a557385bfc3bec991c0f9 +c749f9bb92ca9957ca6d0124206ebf65e860ff38a225e241950bf4526cef3f4fa9184ec83f71f813fe852dc08eca6b45b14fc7f2c6a19296529bfda007efe9d0d26492de2a902b45ed39603e22f0a763dfa5deadd97ef6feb859d860baa2cfd1d066c0be0f9f4e0e2fafa69cc51b12e814ad2e33b0acc0bcbe1df8cf018dcd4f 000c11e2979498695c660a2bdfd105b115bc4ff8664ea15cfb40c725406c6fc9a13027bd1d72ffff6258f29e4e19b845243444a7 a3eafbb6a3d1cacee3ec0cc04d45ac8c5742eacf0ba31e296e050c4d59cc75fc5de87f582d1427e4ad427697a9d3d26d168bba0559ae1c349329a1342bf061df52ebab37bd669e8b08c016672edb0fc859c42eb993a50ba5cf1bd3c183221781 +4de8414780ea20f7943b1f1adae5e3962d96e828fee43bdbf2831bd71bd25df2976a3be37a7a667c7fbe1200de578920090d131a750c9bc09bd95b261234ea8cc25423c4ddfff5656d6b32da6e2f6f530e6673a8660aeca31273bb9a3a21bbd7031a2fa71ba37c004d3d1c64b2c0798783e47b2efe1a208959ac16e35d444245 0068dfc23c6635bd1fa1076dcbd456ad6e8df7ce7c1370fe275803befc4ffad007fd062a61cf1d50b93aeb9afe1aab47a65af82a 8afbc5041de7976658ab5765939377ca462742a0cf04e75222ba50a1200b428d5e18cebe942c221205a67befa326ff12057983e7ade30f5dc294d1376fa9bb0fe86e09a494ea7d8f6cb2a011d87715ffc0700511fe1844514ba7d00fac02e2ea +a081d54232f84bb19dbd52ec3812748e2e6486f6cf1b177b27929504ca878036547eb43531bb5b3edc81bfe105370427e92831d2239cca0106d031d9fa8da9cf89c6fb6401377d5936b6329ccad854e5567181b8f16a37c35f333eaa0ffe91d727d183fbab935fdac2d5670dafb3fba59e4fa2df1746c58dd8360fa08af7f4e6 0040807fb888e1d9fd33604546656a493629d94d4a0a9de2608962225ed158167f9e2438abe2d12a11e2adb6c2b66ed78215b0b1 82c8d39be33f5170b14ee432ade3539844dffa76a1b2e7d0673e6b5de82400a5917e63e08c23eac4e74c5dbabe416a7508d232c34f85c90f52e5415c45dc73da9fced07294c8fa330b26112fd36f0dd4119113f945871d7434ad77d5751890ec +ea60266f1538565b3ff42fa4bbfe319be070329059c52c8bc04a7da2824f209c1145a05e551ea59ded8ca8439c328f6907da4e81d658937df614be98c7b8648818ea80ef40e49aaa4431f4a211d62acf2611f5d60c446b2b25745078c643859be1b12b3141a09ab765dd63ea1f2a2df015eca0840087a5db378c4c4cce76cba7 0033bda0a02badae08fe40c239b9d59e5bfe1c4d4b9b7a5acda6790bfd77ad08dde5e93a2da80ec54a7f88146d72218bbb88aa10 b930a7d95e5d1f03166f3f5320e86761cad869cb51b1f17dd0fb750c08a65f6a613c99ef7d26eb118c9963e37fe137e90c604bb5587f0ff05bfcdedd821ff4c31461a0356c598ae915942a466a741358d5c117e051984b7e7f6903f2ad568878 +82f38c9405ef0d26bcdd5b3fce4fb0060c3095f61403418e17c337933f0563c03691fabd32ab5e896c593439e7492a9970ae325c67196d9e83fe0f9780409a930326f7e6efae035ef8c321cb9ad12461edd5cde66c04739fe079db65406b3c2d22f2d04b1a4335285513d4ceb901d2ca2ad10c508302266c2cd6079ff14eff4b 004ff431769d26b8837d3e1295f5464fe82be29edefba76323e92078a6483ea0daa96221549102509a1bdcfd46a5a2e5de10c39f 99be42fadbb63a2bf581a3640f430c70e6428611f2b17a9e84c89371fd377aff757e56bfc1a8452a43d5b7550f1feefa09bedeb996fbc074135e6d4c49f05d00ad858ff58df59e1215a8eee6f1814c57c425f043bd41860c54fbcbbbd9308230 +d8506fab4f681ba4ae86066aed447571eba4fe04e6585fe3be6af2ab1000a3da68c5b0c711a85ddf3a40cb7c8944eef81f2094650459e14f5b848e6add7e580b0198070f873eb3ed5d0728eabd92bc1398764b94cbb4cdd7cc2027b9762dd10782658cd9e8a5022ac062fec535d892198c8a387b3d2b6f7c92b1af6ab7dd9e4a 003f85ca1169ca7e9df44cbc6bc7d2868c9d94e8f8b699a42ca492dca0914eb5789a9032218dcef7f95f959c9554a1cd83360439 99b9d749a43b7edb870af6be966d1dc0a1c498253c0e2635ac96ece024584de6f67ff6c86c1ba78b46142553f382798716441f2c6021fa19916a127fd6bdf0f61922277605af2b13682b9d74c3f58871041058805bd1752246a19a5053bdd29e +b3f30d34f252a4c26f396079e773142bf61c0981d912333ade3de4e27cbc72cd8a16b31807f0c46116f87accb854487d83ec8c6a61565e6fca145eab70048245db08616779d7047db63aabd90dd15acbb05eaa510072c151c0518f1b34582b95f43ec7b9484b2993c176de79e84566764467f72392ef31619426d159c91816d4 003a97deb36d68f81f50c8829d412ee5de7f9d775633cb69c09dac558182039e275fc258240517a7c4aa592e364765321f27cb12 9848dc1402e13f5543343e741559b52e6e2c7572d260444916f5df871981117b829b80c5b085addf2c7a3e03828b76020df3110be2f3ea3937516a8c12007e127d22969ae093d3d23f02d0850e7d615b4880ed7fc8afb36c05c9c595719a7b7b +0fb13b7c09467ad203852738eda5ddd25b17d330e82c279630b0e1f0c86681f67f6e537fb00da9419114973c8559306de58b0387d86e52d821d982a60769d2f15fd5ac2ee6dc55d8ac04ee247282cb2866b8cb8b4d7b4b6cfb33bfefdff09a73d727193e5fb939ff66ac5fcb644a44f9083a790888cc538c5eb435243c6a34a8 003b1da0ffed24e1a3b5ba22bd684337f6b08053591620541bdad50c761d66201a2cf21a4cc636426456525b598e96baf97d9851 af0dbe358280b957fc0203d48efbc7ab8d423e383dd0b9f602cc9317a17ab2f907ac449430c6318aba44ae7e7ad6c3a80ac4ccd35768a7b2def2ab26c8f1aebee201551022e6191727d3507e235ef1c102dbc8ee14b564137108263b0b797852 +f9b8124281628cf4e1da0cb4f021c8d19d815644cd80c7c8de4cc62722904ec4cddd26cc4891f30b15098a25ba6923c6abf4774deb6e1883fbb409862f94467e75a725e7154be860fd58347577c83adbf18535c54b102220197afa062cc1c84f6094490ce488af4a08d2c5b808a2572e18a59de96c87162f88413795351cedc1 0040bac7e0d3b54c7753c79d43469e310d876015d948fac4e3a9765444754476af72330e88d79ee6119697aafac8435ab5690754 95383d491c3ce60908210772ccf92a7bc7d52fee14332f5cd06205d773229b8e502b121ad0ea9335ba78b16d943e87db052f694064c318dc83cb2302673f5bf12f6cb15516e658c95fac290f689bef5f1d9f1bf234db7b718b4b2cd15bae9c77 +4e3cd6100520db050af0daa69fe3cfe6603a223d4f2a6318fc5836db8640d4c7fb80bb781302036d2d6fb8e552b4eaef3133b98ba2d36b9ef0b86243b0391413c73d48ecbf1d19170f1b3b781b35ffd316afb1d55d1dda8e91eed5553780cb2714a93e7ece698b832e853e2589c5ba2b8a997bbbbf625071ded66762af8cad42 0025b7eb3bdefba3c5134438caf968f615b315204f348006f82e8d61057a8a8a853230cf0500f9d0b8c1551a59b9184862dd2ed9 a1e3f0b6fc7757b398cf9814c11db94885076634ac6284973b57a96e2d842d51fe13c64b0996389c6a606afd95c81da812c55f215c82de4918528a5ec7ec2cc4b0d9b6196394872c3485d02f7d245ab766d78fe4f3073a7f71687f4a9a6c0716 +5411708381a65bef4381c9e13a04cdd5ba0c15829f7f25ccadf695f635384d8e4704cb562741747831b33852567f42fedbd190d2980f1bc921ce01c17d659d4bdd7eb787b3927fcee659dd3b65132496c687f2249272a473d46326e66b3cb78dafbb522390162c168f73bdec88adb145e6afecd561979846ea4c8cee38dc1686 00673b3a2985c95904732632e5d988d8d437a60db13215bb6aa880b348f011c609a1e860461427a8cf0d622abc47f910f5c97ffa 80000e5d4e0ad9bc9610bddc558ccc9bde79f9a027ce21f28132601c89ddfd0da97ca66f92d0ed088a47ace8e74cc6621400eeb73397fc62dc0961fa4a5572aa53d430142013e78eabfd97c83e6cf2d3e94db1ab4e8f838ee06277322ee8677f +23757fa60fcabf543e603d8b31ef0cc99b3ed16b4816a84e01dbfc858872fcb79fd03d2f8a1d4f28c25dc42a39e20c34f81ebccda1682ee9bd22fe323e7f8ea90cf4a2a6ebb634cd1153cdc35f7306f28a2efd822bf23131baa1543d0ed5ab4c8168d3199983fbee117085f90550ec3ffa2b06070d3add1d707fc2593285ff58 000db7dcac414010b816236cad584dabeaec1da76c97182d1b62f87bb7fe2946a64d10430571b2b29ccf2ef72c969a9f045f1f3b a15d810ed27802fd85cea7757dd49af6eb2f33e1c7df041e0c05a67d681a632ef840e4a4aec2a3e13d199c4e8344d69c051c12f6ac6746259d92eb92f657232d195d396b982132eba6a0fe2f64dccabb1fd277157665a3e8713e3725b5e8bb84 +b976314d2f066f8893307a726f450dcf2cf865c170e90e6908ce9787eec48e1e2119a731b2bec3c12fd4e6282a393774251bcaef91af6ce57c63a8b45bedd72ab862cd169b7c84b8f6a72084ff823a96f2f8eff3483a7ebfabdabf0998377c5a6836d88135cf61c65a0ca7ca57727da68047dc635c17ad13731035fe9a6402af 004717efef16e1ae267e155aa1daabafc68515aa391dfeb73c13d01f3132bd22c984228dddc4dff4c39979e7585acd3f730cfcfa 88c7c7453b25e9b2e405cd4d44ba6e67e7257613bc6f5a84960cf9481db26d632a9aa4f53e8f9987fcc4fb2f9dd54b50134793e776f91ba158b05aa82317fb2c058c2c78a174cce5e6e50f227b67793c7d7b9ba52af2de61ecf1fd05f0d7c592 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K409_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K409_blst new file mode 100644 index 000000000000..d67e6638bd63 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K409_blst @@ -0,0 +1,60 @@ +f153cc61981a46d8a47d17d29ec157fa93fcf644beb84558db7c99c57fb131dcbc5b65581ced5ff0b29bfdc66ff703ecdd4290f7c353c02a3e6d6867f33f3dccd1a0b6752b8a35fa143f8921a5078af9c85b212564c5b795da9858c7955095938fcd10c21e35e1abe905e84c8b4bc05f2a06091ce876d9519b96951d08c7ac9e 0011c6528939672bed3e8c905b7ba594c3ce95f37fb28044f210cccd01dfdb42c10e8e1a0b5d6fc757834ca7f08e98cbc52b0edd 9366f8d7db208fe3a9e66c28e307c1d44a2088cb143abe57a4de9c7cadd264ce2a48b931018d9bec1eadf49085f959ed0b1679c717e81733f82c671c78de7c7150e98dacd4de4f432b70402881a970930a4f19edd4199283b84857738c642422 +258c91524423b5c876432b1930c7b07b56eb5e3945f1e2296a4e5bfb9b9123f800ad195d6104641b1f1970bca553c2032f83d17252e52403a9381c1fc18eaffdf026f7537aa27d84c5e3d6e39e651a92a41139cec5181fe794457f556b390943093be719acd23fa1ddf7ff0aaf0479484a381a309b4f681af74bf97caef08c22 007e3b714496dd118d8f3f597961eec5c43d0265bf85723b0b9b0616977e0acc2cf686cb6afa6cdc19114e27ab000e762dfe467b b2dd7527f73a7f746f365ab740626fa3569c9c3d539e0597132b685f67eb0324ab016ddabc865efee1721b4d55b298bb1675688fe664e22896cf2f05916bc713b33d687db8673c06183abb3c2d8a07625d4463b4f0bb1da19e4c90fbe29866b6 +a16a0d6fd57240fe88c7c36b9f7f9040cfcaa9afc4beeb8300818c5f90cce73b819a12c31d42af33146399cdfa4ed4954d068dbb0f1f342269dd29f1fe357e7224304b67b0f924b794780fe7e6aa9dfa3380252fe7177b43e7b1789718949b9ec1b943c83ed4399491482f0f59d2cb8050ab6f8b5854d76c50651428cd29c40a 00182d1e937b037bf7f84144f7d4c94c935269c9aae7d500aa459a7a0ec113b232dcf282908eee4c84b8106cd38cdc41db3f89e1 a58daac3d61712524da56f3714a803ad484154f4fd30d62732907980b77ffa488a871052903526fc014c3341eed511740f847e29ba158504519efcf89184b727e0c7900f5b6469328c4b23f5932a25ea29241b6a05b0a740cad6ecd554d9335f +d02ff569828fd1add21f6bd1c50cbdcd09222e458ee79fd5dfdba3cbb84e9d926fcf196cccedece77d5aa17f8c8cbf3a9facf0f02c71d5c1c8aeda9d75f6fd7b6f2c5c70dff992ef6e02c438fb3c66da5a503b3c39acbe2a069da457595b542190d818015d462670b0807c401e36b1bfe05baff3a8ccf8d1f5f8de7840e87993 007ed09428f460724c8a5225a31151e031d9949493fff5703369c401762345d002c4ce424294baab22d9e71edc4f854510cf0e6a 866d45d01c70c06216e3556e7f0120db62fc5893dfb2d06b69cc2329fae0ec7d072d137caac384f1c4c31d3e8be881b80eb492cc1f95ccd78677e1b68ab5122a4111763c94bcd7ae28d7c7b5992492f97615190532e0f3000912ca2b34f7f7b0 +57befce973b225cfce7f996fa5a1a43acd160681b88a87b7de04544eb7b6a719718f1ca7f559b6531bfc18fca3836d2be7f7a6e48387b7579a6845796d30e46f0dda9d82680f8c96c5f0989741adef9762c3db763cae2699cb6c112543635e20ed5cfb4b55ca2ccb32d2d13936085a8ff95ed658a54be73f80c912ccfe5f0ca0 00390f05b9619c27b800e99aeaf61ef7f6249367d5cfaeae3c7b523a8b29153eb8a77132f6c4412545a842d6deb7b7aea7e2bda5 83dd92e1d2a017f3cb7ed4af59e778d2c95a38e026d0be4d84484ec86a97d7082d67ba17a009d47580941e94bd7279e407faa670ded605ede7e9902c3288a2cd0893c6a8e0586e4a82be439f35ec65aef4b68cb9d57d94119ff4da275be92631 +4277ba40cb462860ca722cb4ee71c61836d2ceba18bc91f3fad7dea478972c6da0ebc02815eaaada1d1a5e93d7ab353855ccfdfc94a5742fe18daee2328871e06c1ab0a9a989d1239df2d2d27f96c415e7ef9a941f06c6790675361173cc229aac7045f49eaca207f59c497619ba32e932b5c1c6576812ee5b146e2cc7de5e62 0007d18652732596add3db31f7a0ce6020d03f3df58131b0c7c633faf619b8210cd309d6c0c4083aef1a1b6d2a756adad0bfe344 8cece3f01f93823ee89382148c2dbc2acc5e03e86fbe57b36d7b99b256c1af0556c90aec68939a2c924439bda37f8a4f0bb83edff45bc98fcb999e41bd11ac0bdc38a590c59cbb50c8fd1ead5918468e8564c8a4deb014f2183a69bfa0267dbb +57ff6792ed4b12220d179bc0ea57ff217f322c85bd3676a681d32d7e4a3e0c8e891fd267df17caba5992f68c35ff670b60b4bbdfff82404f6ed996c30539bc395120f97d4d7a652eaee82bd8f9360bf8bb73748b8bbda9f9480eb54f7eaf2609d4259329e8a5ea020521e7dbd3ec56f23c849932cbdf2875f5d5c774a9d6b0c9 002a91244ea4623b63403dba807d60b914ca3b901a2523244c322f2f11251446d3f15e869d086ebecfa1a39ce304e8b5c8de23e2 8ba2fd45dada1f624c1d6546534204eab72113956bacb984d99c6f4a82c579131829f5de05ddf6bfeabbe3a444514de403f4d31e42bd01656b6d3b9920af23ff7d1081be1c7dc5e1eef1239013e7fa405a29c2b7e8c153825355c34113f32f82 +f85113eda64478f460b60f8084220134933de049200a5f37884da7901471542e26690a5fabc3cbf9e679ade71b6e54d869bc136c3d34cc4a9efcafb777abf046b5ae5429136112a9a36a475121eb1f33f1f43481286fc1ada98a41064a1fa38c89e99a93065bb2a119348a9e452497fd5a0d2b83a66b09da9f47a0583732adf4 00068c56c6b5d50d1d4e13d3837d8c5e8ba2f825e121b63e97603fdfe78bb6899600ff0dc87b6b3b6868ad0d2f62b7b7a31603ff 8fde885b3293afc4989afda4f0143dccd981a5f5f33440f1bb463fece4b1f428cfe37e59d86a5bf009223a644a671cb60ab03909d32de1bfd2135865f578f1d55a2a0442dd59504e45e7321b80f218e9a59a11e992416a435c3ae4dc64acda51 +42811e9ee6dc509572e1cddbe5baf00afeb0c5c13e3755b922eee9e210001676082bc9edc3d78db2b5bebea7a2c0cd2b369226c2b8f83b28f33fb513407ab9d287d14b112d6c3be2493805ace5cf6fd366d03cfb28f4ce3f0f060880db64d6962e997463ba7c05b6fcd1e66babe4b94afc5c2d38c7050c69571d27b66ef0090b 003c88084f8b78446db431bd6e240a0c050813d2a763675b0ea869cbe183df697146cf29c03479af3d34587a95cd257027fbeed8 b3b3df404f11d7fa9f1de583fdf4be374cd40cbb0cee927063411df3ea9d23792c2401aad91ee26acf4401f1abf9678b106ee72226e0c7ee75fdb15fd3b23a95421e549656f70540a13ca3ec93f1fcde8c4ccf475c1934485f93ef54129d980f +b38f76ede7441ae0887e689d556f43155b38dab7cde487ce9ef9a46f2957c830d4d28006873fe2368197a6931f6fcaad755102686a457a7edccc8d344e2d2a9162e3d71d41c09a022539ae6d404955a6ad748231aee1f974d4f159940532fb3b1fa0254bfc5805d2fc68696856fadea386c542d3cefd1be3af04ca595e54be25 0051af7b63bf3297ae20517faaa1552f4fde65819dbbff6a52721611e5b7dc1242ed6e69768cdc37ea8cdfd1a5971f06b84b5803 8ed02c5a7adf2cef413000a872ab596b425ae4021f55fb210d0d3e7f0469758ae30cc99b0ffbbebfb2dbd7b6924081ea1747c6045467669017053ff1b4ee4fb13cfdeff9106d3589f75567c25be5008fcaa3cb474a02cfef7bc392a54bdb0489 +356dc86cef7979148e995fc5abe2b14a7d5e4e42c9b3509b4363bb80c581a66f4e7e4aa53a4bfd37f9a7eccf75fdd726f348f6a3f779e6599f61bd1d668517f40453b39bcf35db0852a6a6218198f52b7ceda2ec55fca5abe8e5d93af9a42b9ae4de9530c5870211bacc27c39aa094013db703de2fd3121f08d7e97dbd4e8946 003d65bdec48972d03811b78150a06956eb22d337dbec5416bbd8185a6322cd8c0ff8000210dbd1326422289071cab65175f5d10 b9957c6bf9f78c87732ab8e2f17d3c2525f5be2c8ef51c31bb223431fc698ed9c86f2b0b224a3e848ba7e5c3e0a5367f02b8b73fe9ec5e03e2cc861ea853d855dc778715c9154edea9d808aa681031d8bce7fbb5ec449df3ad8bcad2dc9809b2 +06fd39a50bf25e89f1071ff81fec5d1e35b6dd68990414ee403dfdebb792627b6a4ae3d2236c159e4441ff90b61ec87b1592c538515f0486b19e58583394a05e6411e69b4285d6d6589982ac0eeb2c912c4948789cad741183663fc070943389d4e9a1150b8f6088fc50605915e9e24b2d98a1f539024770e4820e14ae42ea8e 001f1a8b5f35dbbf82c102df550c72216a243f986f0325920f6186a16d1da74228cc02be6024c7411160c183c923c743354f9438 8a83911ebde9f8c0e0f773c7b5ddca04f931b119e330d03252a725dfb300ca858d64e203dc231276a471d9d143834ad503b06cb9dbb7c069b533290764e8f3e0b63b602ad5184b6237e8a4da4e245bb432f2e2bea69ddb0eba78e246a1ab8f17 +6daaa41150ea252a3e966a338377307d909b95080e006f13027f2be5059d9208930c5a329994c0b794ef50eb059bc6c215f68cf42260bd410f9bd86d2ad5ab7179c7c92de4a93a5f6aa17de5aefea815e7c0b78a8cc53c21dc4dee037b29c9df4e12343109283ffd5d8a3b81fba1b5e95506c7e01ac056c86dd0ee23bc21af0a 0031dc621200cd174193d95e9092ffb86189c52cdbb9ed937593f2cde7c4a0264b9100e1b8407336c8dfb5520d28a18dc4e39a89 896fed404f41d5290e2385c566fb3486279c68103a42934391ad3cbae58c004b62c9d86f479f6c5359ba2ef9fd79484e01d7b1bc924bd8d61b0ed21fe1fd8e9499317fc79c5e8f8975c478135a17419e4ba59359453d11c8c1c26de5dd4d6d80 +6378dd1c12c5197b57d47dc46a67949bdd1e0809004e94d49b0234126a08ad5bf8723ebfd132145813136d8b7dd096f56c34248f09a65c34f60c2f80f9a51b3795f3d2518b11aaeaf6dd45a323794080b78f85d629e5fa719b6ab0b14c78cd908befeaef0dbfaa08cec9318bbcb376d48b11b68735c9554a45293db5e9239ae1 0016e6750245a88340b0f0665b890459f8038e9b1366f2fc1326245a88d4c523ec94429f21869ce3dbf75126e58f77241c99efaa ab4e90231ac85a671d595636b94ee8b645b84b7e9468f1ad7e785728c262c83b22e224d396295066eb32edc3e2fae96016c38553325905f5231d33fba785a365fdd86fe046876298e40055b5a46de35e9502c7210186a97cedc7fda1ce686464 +b898d0f9bd80e083fa541f457d14d853bba55b120424a95e1d9511c8833f48444329e0349d68204c4b4581ef1c4dee23ed0a4445727a72e1e6cde422f7c10ae132a3fe681f9d741fda263e73f7cdf10759467c9d76164086abf6780ad474772771eee22d195339bb8f6235e0d992bbe282b13ce4fe01417f507a2c4fa155e108 00788fabdafeebb72f6385301e30024b56639e629a400f9c50d402cfc9b5817844f06a451fbda29c7ece41dc9ffcfc625fe0ff0a 8d6dc739b4193a87bb34c7b93d5645ca70d728082795f1748f72b43f26c2337e5c545a33bbe8e307144b766fdc00b6b41023c73e5cc1806096415d69efa3db1e547b1ba3b3cd59a842ece6d207f65a385ce97d9c68c91bedaed6c6a7be3076ad +dbe04561ea8579672a2b3afa94426a3cbc274b55263989d41a778bcb082da797d84d930ca847a481789524940701cd5f1d11b460bdac0bffb0b3a3abe1ab689c519700de85a0a571494ba0cfc3c865450eba7a9e916b7fa9df55e8a1c246c992e6a0b44b78274e008472bed8d8411633e6520e1a906c5d0c8aafd572fe6f1f64 001b8dfd64563dc219d6eeb53f2e3ad1d771140d0960b211dc1f757af5e297dc7548d6133ddb574711d466688f80dbd65a7bbcdc b259f8c119d342ac025192ad7e728f36008fd0a77708a8f6937467fbe78540e828ada195ff6a93cb566ce9ace42af1c80f971278785ceb71d11c3b1db3bfc55bf1e19e7fccf47836d6e4c77584f1ddd5399a7c65d877d8caa389fc8aa8396765 +48a8300820fea2ad83c83f7d6b24192715329c3f159d56644e11ed25efcbd3d31600a813b909812987b97d1087e74a63b4494cc031c63492b6615e9d6e5b36f62cb2ef88b9f736595800de465789f43811165a5fc093ee6d776008739de8de2a84e878748641be8bd52e5b891c4145f52bbd46644852a43108e93d86352b2a3c 00422131829608ff730c24ddf7e8b4a2600eaa9681eaf45432daa7d41fe2fb488fd0199d431a1ed823801ce21f4f01a4dd4248ca 830ff44af572e16947312d42eabb3330f188a5823bc57bc42f1bf9b8ba28717373121be1c0511e708abe58036e04f521106c373376c5c559f655266b792dec0cc2370715c19b9586961535255c37a31d47c1c4835ee823e5f627f169847f4ff4 +276e3a986ce33256014aaa3e55cc1f4c75fe831746b342eadb017676b0cba7c353b3a2b554522c12e6aeaf1364cd2eb765a404b3d0aa61258194a30219d76d2bfa98ad20e7e91756cf65e50d7914157f283f2ba3930c0ad3a97532cc747b1cb9c806fff497f0322025a3d02ff407fc7b5808585b91d95523c9d5864efdf7d983 00095ae8e4c7e55eb5da01acc05ecfe72a4dcd8ec152f1c8dc165014f70eb4e4a7861aeb2b96c418b2d4db58659e76184e013a49 b877bf28d7fc5ceae3b45fb99b2e6b37a196be5d9f80a0452abfff972d47c7d1a635bd1b48de956be3246c494c34d9f4165a2fc677b0a4317b77d3455d536be949c32f1d18d1af251e3ebeb43dd47ff0696dd751fe87806bfc15fdff1130fadc +6a4fc1827c3a7256faa8ec6a0f3d23559d6949f8cc20e7f76111dc4ebd59213951cbf0eadacaeb8862d6baa0cb298645e4314b1c303bd0d5e9893304d4b7fbd36ab05fb6a5edc3fef763e3a4124d61539eb616b359c5cb55b5e2bec50c91dd95fc39ddf521aa854216eb5a707819fa6f067b316a17a3b146e7cc2dd517f7d63f 0006f2075bd730f34df111ebda919167b1d3358ada32cd6747cb3353bcfb814a77ac70cd51b31a0e538539453bf9eaf9d8b384c9 91419af61150a46f365708688ca6d109accc23e7f5c34f522b1de5d8999ddfd4bec21a2337ce042517de330c2bbceb7f10d3011fdcb63e111c8527ca8e61850e3f0df17b17b1388ad5b20ae4f42a2e765e0f810d2594c74c22fbc057f765fcc0 +4b088199bd8c94775d8ee508377d672dbf50f6d2c7370e99821ec8f9387492fb2eebdbea473ea18465565f79e2af418555f10c4a527e05a9e20c9c00b807dc8b350cd4ccc2d87e91f66addf02ce4f43597aa258ac6fbe9365cc2c8e8bbe5c884abc929710e8423cd6722a8f473bb55804159a92a3d8b6661a536b4fb9293bb0a 003887d284e9ad17d38bc6da9d83c192a434c509340a7f233cebb032b09ab7c4c6e8730b4a80844898616c9abcd16b753c6bb4c5 a3aaa0710de68f8540f505cef765de344f28a76d0823fbb2112d6b715cbb4337f378d2cbe4d23824cc36a9107f4f111e14e8a7f881ea5bc00e7f94dd3f0a2def30b72dc72edb9520f228c893cf8dec7cf53a5e108dbc18097ed6ea117f2f88f1 +848a13465ddcfb2dc14f7bc0db0756832c22dde1e31e4d8b3ae0dd1aafbdf15e954889e95d3bdfd6e5ebb6171fad62592c23277a89e8ba53978c9b1afedfef7e1c3f6d9f31077530460b47834b30bbd84a4da601be988738aa815d3d7e72043243a5288751ee08b4815a017fb5d9bd55833698a0d526b1ed79da35ef0fac93da 002ea5430610864257c9dc393c3addcd0d8d5bc8aab1067643b08857210464428aa85cf1ae6c743fd2682255d4c8eaa46ca21e73 917dc5d9802520b9e4bb557e3333fcb60185930c4881ce4d5fc9fc46dfa154c02328d1792786f655e60eae3718e1b7a90ee09c5dca8cab3397353a09d184a60d089bb0be36c1e32984658c17b6320851173621bec44950df8dbeadc95760b2a7 +d1850545c04ea65528849973c220205c35eae98826d169348970d1420b4d872ce233af1daa9e62f6a562544ae3a0633a954a493e9766dd5d87e47486559fdf86229a7c9e1726de21895abdcf2422d438f4ad98d88b45c56742694ad5e11894253270997c049f0f419842482f21c792fbe5613e2defecd485585f1835b6f4c578 0062c757c92eaef41f5d81169ec4968145b5aa2bc1d2a3a5fd000634777748ecb93677b3da12e3be33272a8f0a52300f4a5a37c4 acc904024a97f95ba9646368e8a35895a7f07dd513868198bcf452798ed89ec3a2be982f2033ae8a55ddf8f6d1bbbe6a0a20fc6b566ed69a3577ab4799e67b07ba3b22f8f59e38d1d70b246add5a891b6f21ad4b0afab5e0e10e061cc258b991 +421c9784d6fd507c82904e1054edf9bdd1efb58a0b211340086069ad38b7b0dd15c2345fa8767ef71254ed1bd5c35f742b1d3f4765ff9007a5477ba9e5d3d5a5cb5fab4efc1cad73701d4776c6c4343f42b5d94a9eb78ae428dfe5fbdd8e6ece09d5b75cf4346cf27db856352225ab04e6ea56661554fbc39916accebecb3935 0048a313c0c11489939fc0cffc6ccb9f179093c4e13141b92dbbaac441b7ae878c9d412066e95615174a24692555cbbe904a14cf 8a2984e322bdbb2358833b0aaf671f79e6ae45fca71e70384627acdaca60e793dc0c9e25e66ad7ea0818f6fb7f8494f40e030c3b7654bc4f26f3df0f81582d20768f124dffab578d92b909bad8296a86aab1b44dc50b4d0b000a08059ff10bb3 +7910bab15b6429947655e33a67f41b76f1d7b71534f8904d6a0472c2faded038565272d0b5f51aa915e0d624e9ff48d50ebfa2f09324864f26c29ab73eb39b436c5c459c7cff4d2b62992e3489cb4ddfc05d7366b161a463aa1b782641d93507de43c8cd0a0a0a9d1c644f4554e3edaf7fd794248110ca9387e73ae5d00d299e 0046e2adfe5d3549e1e6fa1fe69a7cbb4ac9b111c8903d544268f8318b0b47d4b78fe3e56eb5e639ad5382e7cd5bd4b2c3e70ef6 8a959c9183cdaa9d7626459974fc563f578bac3b6290ae6321ce80f1c4fab35348e036168efadc21c8d30da5656f46e60d2478186f16c06a8ffd3d47e76c4d753f39d55b50f3dd5be46c3a8dabe821259a9f57a13893bc75984739a477e182c2 +e6fc96e060b956c25d50ad25443f3c30a12d199a47451a49ce88307201dfb15ed816982e8888a28daa92eaf3c5584ca6ab2ca9e14577f84396de2e0ac214b24a2279f5e7b344fb7387e9afc8f0a2b77a4d024a20ce6183499b17096947444bbb753d9b39e5c694239d28f9c454bb05468d17ab564ee6cea3741747ccb7f108af 00480103fd6180a431c837643566706e2b9597de0a1346a224d176a5b2c54aa4d064418ed654a5d39f4773fb509f86473ebb373f 8cb5e515b384cc01d6c89fdaa644148ccd28006bd9fcc2311fdd48264b97b1edb104761301896a8ea3ffcb49ace9766018ebc2a3a7ab806b987320664e68e4c7fed897fff98e009ababb379a24739b2973c9c5f6b058318a805fe62a8eab1100 +c8a8a0d41f35537e6fd523ee099eb45e1ad6ab54bed4d3e315e20227db03292e39dc1a91bab439c0d20e36e7fea6ef08983f390a6b5551ac3b4f1895220b2867fab95552cef9bd8702962839bd9b2c72772640e7d3be3c5889d226acbefdcb448432bc503e5a5fe7ae9ae7696c720a799f9882c64ae0385f656074dd8a6821f5 0013c489e8311c6bef02c8f58903b2ba2a98a27cb935d75a30d320af9a14fa3cbc6adcce09235a9eaf333dd05f4b2f1694985dc4 81eabb1c92d6f82cc52b39345a2bfe789892a9a77207222698d9d6c92c67446e038b0fa99ff66328df02cfc32539c17e0283dd034313b5671a4e8c7578dad5a18e51423e89cc2512d5c4813d0065f48654c01176d36e4e7afe5729bc92b830ad +3407cd6d2845197cd7414a30fc3df7184da204222ffd65c4d16a12cadabf603de8043ea14f5e6ddcc22d3572dc06dec1a23cd924e1847ae285ecf01754e2d1247876431eb98e897e47412a2330bb32990f9714122109e94b38f82cfdbbf2eeb4c6f88f5dbf9f0ccb47939df8be321dcd9bfd9bb99cac9f94885fee7d443fbd87 002419bd2200f8e1d87db848b0379741685e680d9affe693eed49d82931030b6cb05d21a4965f4e1df2045c8513a8f574ca9f2e7 a7a69e3a5ee975bee51aa39ed811f62ed4086ec5a2676fcd5ffffaaa2f6fb1d633a237baa4a94e9a2bf9bdbfbdd509d00eeafbbd616a843d9d181e1d23b70e7347302abe97338b3e03323bd51a2bb671819f3d506de1a2c93e8c14f961949247 +ad43f8440071285d01fd79244907803601aff4bc5d14c77483a87cd742144d41c68269d76c9a83c09d2178bbcbdf99f927b378497ffdc907a75a3b0ad019e69758dfffa480871eb6e1e17c8539373de611a557fad120d0bd147f8debe5f09a02e56fb607e9c1253ed592071f042e42fee39775b407225a2b86a950d81bb7d7ef 00722951879a65bfcb414e11712ee9431eeb32319e0ff28601112f89276ffc2b96eb65c7fd77d023f09914a53e2aae2c84652bad a0deb5369347c9b151bd0a5185ad5316bf7488f61462272adebcfa104c815fcfecf49b817bed0431bafba856f62aa9de167107b6e108870908d923cb528e1c8247038a1ddb7d4be63ef4a694505c09fdd4e93c92153e0d6e72ed207e5ba06dc8 +d61a3765229dcd0b4fa6c57280f851ec2bd54d3ee2436935cd6d94e0120d0844adda163995fbc4cd9d7275da859ad8ebf30af9efbdcfc31c7c9ef42bce9011d37cf9d15fb018e117bbc102f7d05750e5072f73d02c2f45509a55627a78cbd9082cbf36807759d1fe2ecbb92ab30cf28434941712d38bdd100955d611987b5968 003f5b5a772d24bd5454bf26759dbd433fcc7bae4f5c593664c4d75da0cdf9430d7d9162bce3d7f6e13a344259da5a7d6a1635bb 8a2de9d9396047e3cbf512fbc2ce61b408290b2bc5bebeb16d66310980bd2a24fc8e244e56b140e5f382e3788089d1a50510242f80992016db84d5c52639bb89f1903b3fb09cfb4031321cf3eaf702271ef1623c76d508657039c2efd9ee4bc5 +1f3c23636414ced48fab6763eed5b22537968e6bf08c178b3d31fb1f6ea773c6979759701d94bc1bee7c354272811edec58eff50c93331b22723d460e56dbee90466b894354777b23b13a37d15a84c762caca70c01518bf34d0c2f072145d274b3b6c932b48bd815fe81161d8507ffbc2f783bd212c29b2887af6d2ffa9d2b4d 0046bb4a141c9099d531dd23ac440eff1f5b10f7cf34920b6b702311d490d25344c665ed5211d401def24986c8094165d10f8934 81e2d7878c68197e0b1e763a7944e6714f9fd5b663660d28e85cfaf4f48916c8dc07a535ad4d12f9c2f175ef0d5aa8b9193802932dadebeb7f7ac6742ece8b9e9ac8eb7fd9fbd27065b25ae1884b0fa40d19c4651eeda821ff486c5fd7f64419 +ec69f2937ec793aaa3486d59d0c960ee50f640a9ce98a3becffc12d6a6c1c6c2f255d37d29f9b4d068373a96beadac98fd5203a9f229bfc70bcd449640165ae5128e3f8d057769e28356e73e35d8e9af7876f608390090892c67391ddfcc1c332aa61efbf72d54bc615998b3be8ab0a9d372784bea48c9fab244482c75cb2de3 006f2c6e9ea8109223d9a349fce14927618fc4fa95e05ecf9aba1546619eaeaca7b5815cc07e97ae8cd1e9973ac603f84d838393 abfac9e08790bb14c4b9311b4ed19c5695c0099a3a793c9899f5f1ad350606d0cadb259d95ddf87f0e5ffffe4e0e1b9501ce8261349b10051dfceb49ecd61078a23778a46c0a1c93c270e02cc7b871180bedf1c6629555b74ee46d9a7bb2b0ec +70e11efc78d7f079ae41ac3c31c96d3220f4abfe23814a2a4a78d9b1a25e838c3408bd416062e4b0a5cdadf0c6e16a11e00f59711b417751f5e4b43ecad99efbdb2a81c91a034e89edc94eb552c3eba62808563cdf64453a1db07daff8742aea4a9fa738e1322da316b26dbca2954b2bc0de6da7518d28e6677dec6ba8af4285 0004212b7fd913d794fc6bb33e0276e349c052c969ecbf6afc89b28f75a599a9242acf74dec9f374361ba296ba42a38407f9b7d6 b7340816d81a7e36023d53dff97f09c1e0ebdf334e6940b2f3e76fe3c162f98698be7af2a81f74632c56b1a3491f3a3e0876d0f3e0e25934f875356c6111e8283790004ebae8efa22dfa5e1dfe3f1630bb3dd5933dacf8fed630735bbbd3f46c +d922fa515e3bed60b517a2d37cafe4c041e5ab4b5c8d8d4011bf9fc4013dd8abf7add71fcfde5e71d6abe76bd0f749e960cbed55711c87b5629a2c39cff48ed7d0feaf5cc4765e576a4959521f9a45fcba0dc65ae618826447e02ce6e1cab5ce8d6c96c3211adbb0660de7df7453f3aa726016941d00d8ee536cc106a603d126 006baeebb5ffc89c94c3e8b37b9b0904e7c4b251d204894655bf3b1235710215c29820b9d401c9ca7df1404d2d62d708aafe208a 84abdde5e79894039cdde9bc11953d82eecc51d6524fb87f1f56129b63e58508c45ad9951d0fa8ecb4e7b050bd8e20a613e0d48f3a8c6fd8f559453ea7f0046c15015142e422ba453b8813525d4b7acf7da087bb1e48843a12f9b8b4e0b5d1c0 +4f64d0f6bfc542a0d4347576935bd68ca88524ead03b8d2c494061d0658e6c3e14576b5bcea5f2f992f54cfb52b5c7cf1dfc517205e0454510eef1b7054a8cd06ab53ed2468193f98ff0dd62faf076549ab2a270f259276d5729996c120792c6f466a74ab65035bf38ff2c055b43e2a8b8e2449a2375ddbfc18242157bd905f8 0008e5f66ba53e7caad1feda122a80c32c82d2c32a7237b8ee8ead44ea8f2f01d77c7056b9dd60b92d051f060da8532c1fd0e8f4 a8fdecae1b2c6f2ec30a41cdceb59e49cbb177f03debe09b49f4a3a202cd980cca7d25fd028a314d25a6d5b4ebbfdfae182502fe3ce0a729ccf5fe9a875503a7526407a87a11b61604c7147785e01fa8c901abbdd912ed557b4a513e2a088ad5 +7047d478ec5282d55db8c19c97af10951982d908c759ff590f27d57e2664f08d526cbb2bfde39bdbb1aa3dca5a8d3feb50b868be6651f197abccc9d8040b623de367e2ea1d20ecd302afb9e273f4be9f3f64f2c2eb3f92d5e0e375db6549da2a589f0604bc7146562ccefd15995a7c4208f640e7a17afbca69cda4e173380523 004ecb22b44e809f89b16abb10be062c89b41ee34e110403e42a20ce59a99afdc22f6f6dda56e1d9d1b8ce1d057f390db111def3 b83558d11f95b8a035a030c4a348fe197136f8cf772ee9546ecf840db6d58d3485517d72980244bf507323e32101e1a9056ce730eb33739a5d7a9b4af0caf819e04f584510252b9c6d5b358567c5571f27c913e5d1d13cd43dc2defb15e7497d +1a8384b4771a410663e56eb36c5d9ede8d161a8fb0e31d3f74bcb017b9e31232bb2e2f4c65a2d85bcd1cedd93ef08d4bb4af0095731574ab3f2762788a1ba3bf0ee46684da8d9dd384432fee99ed3c69213d790a5d81b351063eaf2bda71ca4868ac36be1b571024a8bf09039b347fa996d5d161078314e24b7d073e05cb3d48 0051f9500c15ae73d6d479b9f3d2caccc2039d8d03820befc2aae3bbaf65d59bd9cb3c4e3aa8bed5b3acb70a5566047ffad80729 84ffa707ccd2a2db18362eeb7f8dbcbb911b1a295453301c9ef3be5bb6cbb8ab5be39599f7709163b1ba23db4388069803321af5d1e5b13d31ea2d9459d56549dba924cfae970fe54044cd3c6ccd29639bfe3bc504513fb9b1b85cb3aab24257 +43513d6dd8bb0af7a6f5a2b35f99957d335a48d54f2c4019ce9518b35441d4935518976ab1df37110b5b53532cd9e2c66d9f87ae7f683d7efdbe1775a6c15eecee84c6f879999d0706f6779dc158c111fe8d7201983883bc8334f51dec60004eb1087347bfdab20f8f2f260556681e05fdbb8a6139857fd3bb2df5bc1f2dc143 000cf01dc4462cca764f4f8cbef48c51980737b9b98d1384b8de9f4c733829db7718a9b5eaa46a8475c2144fe4454cb8eeb0a443 84cec876bbac6662f9fcd4331206a59628720a28681d0befc751b500cbe8cd4e53a38a332ff64e2ecf42c7ef5c0d7dd4050391c7b56241e332e453bca4491237b77bf8a80405b34821fec4132be8c85e64eff330322294366ffb8a0f1b506e90 +752300bc5066d0efaf807183a41725e349907b7339d77c79921ead3c685b616b0eb97e708f3880fce0136c510c8cb53b22cb424af6f1c34633600939a0647c02d8f9601f9416f1d24a51657241fb559c25dfba91402cea43bca1a13718b3945b048725f3df560e6717cfc6ebd894e29bff1e0c7763f15b8ea93e67385f059598 0063a9a565497974c6dd459bea0d1196d74f263f333c31b7e8591499960e1cd79e2ef4cc8709f6d54713f873b16e7b0be42f71c8 b4c717e80e487570f2f21387d4830f001b41b577a4831b4bb7338362e52c60c842e0439b21b5b779b68ff39cacd3cf781210425b7a87b7ea739d0fd0e84a25294d851cc570f11469ae6d1101b21b72161804f725a8b90852e373590e1a85354d +f620603489944769c02e2f902c2299dd5f32b5fb463c841b7e1fc0249a85d2c31684bd3daacd97de8291c5d39e84d6e59d3dde1b30c181bfe8d31b8d8e080bd191690a67fa00024ac8c1b10981b40d4f88789ecc58fc69b15417fff34834e23453bb9933a43d08afab74d056f366b40ad167b51ee5f008db151a12b467d3eaa2 0041074dc186193d30aac7cc6d269b938ab40b257d095e54ba79967a377a91b8f73671470cd07f0a3d1db7cf0a31ba9070625e43 8c54c9f2855e6d5b06f781dd3031ddd363dbcf53a3c1a618434d9c79f855a060611fc55447ad4ff837c953b2045a676f08ba0cccd2eb524e99f12d9f8c7cf4d764c8d1c415b75d48e71f2849828e752a91aba6b2e60c04a4984320eeeec5a028 +5575f610762b42ce4e98d7bcf45a7a6a0d66ec7f27d6b8b17f1961249d905bc7e58e2ce0806d467f106b16285dce4544c72666d08b5e2276cd0c4e13187cbda8aecf57b1855afedf8fad39ee4fe009f204e60bdbec79b123456ec2d85631d382b8a2f2c7634af3992e4707f7b4215e2c9d3b0aa8fb08267953883a4213669d33 0010820db54ccf0226161aeaee79cfd2797f87702b4ee91adf8543b3c9e79579d0df8a889e366ec1e0718e039b87a37c24d620e9 804e36866ba45e47f3190502bae515a26f3171be97f611e4000592133f2b5944519e551350ddcc67cd924c4a23a25c4517d59b2a57e6f0d6e0777752f67cfd97aadc8464b625d5f89f0e58403db24fec9e64007d446bbea3cc32ae4ba7c0bf5c +81cf067411dde2d0ab04fe5fa1e28e6975cdcc571588de60a35bd956a535fbbda4affd0803d244f3f7e6902a2c9a7ef2488691b6bef7f8ffb33be09ccae4c5285265e4957f7928ea5cbabd6823297f59a7cfc9939a49f26bde74c4c69e2d38c1efbacbcfdef011213843158072be84ed3c1781f67a0e2d4e9ba76a585c17fc0a 0059d2a06e8bfd5e14a9bc8777958b85be5e97af892d2cdeb0ecbd2d5017952b5042349db5fedba2e26e7b85bbb31ad313d99434 b33253ea7b8349fcb7e5c5d2293ecdcf765366ddda78fee747b417cbfef2fb11d803ac0bdf8c01a2fe4972519d3580850ae28a34e0ddfb3913794109115b17c1d3d1901226de89f381a4eb9b897e47ff6a13e57868c95e41e0299f3293ee0a65 +8ea18387940035cff2f37278d321b344231075db43c7fa7fee9bd3fdefe5e8f03e7af9deafa1022eb108e19ec11fae34536a4fbac2e8c8139a081a997c080cbe8f3e2d2a72ff26edcc5338b21372fa1498e439e4d9bb12d51cc539f859047957b1b1f1fc30b90231eb06b365a4d404a1fd5a0e5cef171fc95b04d0b557d78ebf 00405590893cbbe18f4ad99df28b5f9d17f8f1882269aff0b7eee9392859d68927a99c942a3075269ddec6d69c0df2d76ab9d801 a451d83b66e8009fd3f5085efff58aed8c919cb492f101b96a2ff37ede6b12c448ff8f6768716ecd57bd17e2d8c5cbe706d65e27e5f739e91e823985880ffa2038c19db3a7ef8e6df69e982634274262d466d1e7af1846364d4287cf2141dbd5 +6a253c1aa17b2b1e6624afc8e7456d366ef5b1bd78e740538260f395481148a64da0b6a58cd53d7e06c691beae1a616547cd95c4d259a371e51c2c0e334c8a5311ae31e4c7af325686ff9f7a36f731010ee1a9b8a29169ceac36a060dd23611dc9713c615424888bb574ad5f5755d7311bd169336ae986c977a394bf16487c4e 0062bbb4f565aa0f23b88ab9029d33b995729d10fcfc33ba7c4051e2fbc72f15636a834e3ebfe604b927cdfc89f53c57f36890db 88067e4accb742f9815b0c8a60bfd42d77ca353907ea9ba46c0f77d2f27343e3905aae30037e81ed820e03cb9d9c5ccf033be197c47f183fd7fb73f66f56ed140a55a13401017fa81bf4456ccd8fcc758cfd5b8edd0c8107004b69dcf7fe5242 +0f91d0f0139faf3b90a3d4bebd7e96ff6bb6f90f6c68321fb392637d8ab2a60d649a7b7364ee6e4e274e1a8d342caee36cc11c56c54247fb0a8e8ef81ac4322b454dc9a195dc54567bf47ec8d4fa4cd32e76d78ea2d08bcbce3edbb68fd8597e56d5a9f2df4e47b2701046df89615961db601bd8204584a6a6cfbb627e2a1190 003fad7031cf8810544a3e4bd1382c0a2e22c5a9fe4804ce67b27591fc516ee81dbac841d399327168aa6abd79e2b5ef85df1528 9194c5e20c277ce9e3879fd43d18a62964179f57d7b5b7a9bb19faabee18852b1f5472d8efcd3027ecf42de6429f98e105790dddb84f9f8986b79712fff1366055c8fefd40b54f14dfba6021a4eaad5857b76f249fc70a05e77d6eee49095427 +50c17c1fe4dc84648e5c3c3ab8f7c971d4c58d8d56d2b5ddd92e35e6792111ed8dac7644ac8a07ca8bb4e38e071aa47b22ffe495e9083f9bf781ac1b5fba571862c909c7aaa7b8d05ddfb7ef61c99700de734d5658f44ae9fc908c85a2dac8e7f854d6d24be805fcd7f873a91252985c5c73129c60177ba8fd99daa87b25a073 003db41b4f637fe7977c90e4f1a21799baaddd1826c667102414877138436cfae1b9959842b8097b5276f15f2b982ee59df263c8 912ce356f25554f2e2fb2875e1794fdbe36a6978818bc5ab7af1b94acb0be57e2542558c1b8d049415b6a5dc42f7cae3179fa7dbcf125bb4f8acdb813774496e4d4c16ad26289e45d677ae13a295ad8918cfbe379e6e45781c1493bec6b83446 +3583a3226e2dc463a462fefa97024e6e969c1b13bdc1d228e2d7823d9f7c09012390c2535baf086588000e908309090daac6e6d2b06d2ede6fae838ed47f30b5b481185f607a3586f6dea47c8f84e9d3b96d5b0ebae2462fde1e49d84d36658e87dccf5e30c0937feefd8862dcdb1a1ca373f6ae41641502ac54df6633a8cec1 0065b76c6093d9c49591293471286df1a4444e60d9d06cfa114e175afb5f119d2abeb273b0596019a0ec5db5b5869f2cc827b364 8221ff5e7947a6dcda1ccb8ae05d74f774f3b4a03d57e57dd885eae86198c2eb07eca7d534da5fd6be0f7a7840050ccf15a256c26e0d5b4c645dd335af35f423deb5f9bd3869177c8f9cda7083d33ef169bb208f98f3d22d1826b1e700b703e1 +60ca58462d53d074b370127132f4e59f5eb8d15594dc721a94286afd082a8934e52462c9c1c3910f8b50d7aa3671dafa5972958d876d7992467b2fee3795a6f9d8a7bd3003a8582ea8c003aa1e02c08ab6804d85bcfa13a815d75c938671f0af0706c68bc70a6155708ca755cac2fbb68b2952208d63e0e2e3d816f04c61bc03 007e9993f3fc1fdc4c376ef77ecded96006ac1159740bd1b2dc6ae3d97e15a67383f1fc931e460b9af3fe14a54e47919667ed06c 8f66feddebc4e4235a531f101a3ba9eec62c399b038513b81817069412161041a0ffe9aaa4e5fe0247959fb790a2d89c18a600015c420b1c89f06f316c1f196a0fc948ab3407a227f7c3696453cbd9f7caa4749bbb292804499900061608ceb1 +c749f9bb92ca9957ca6d0124206ebf65e860ff38a225e241950bf4526cef3f4fa9184ec83f71f813fe852dc08eca6b45b14fc7f2c6a19296529bfda007efe9d0d26492de2a902b45ed39603e22f0a763dfa5deadd97ef6feb859d860baa2cfd1d066c0be0f9f4e0e2fafa69cc51b12e814ad2e33b0acc0bcbe1df8cf018dcd4f 000c11e2979498695c660a2bdfd105b115bc4ff8664ea15cfb40c725406c6fc9a13027bd1d72ffff6258f29e4e19b845243444a7 b757a7bd0a92300ff77090ea56af862844cd9b997ca854da86ec405a5575d0d0df6cac82a4d45b926453d2e49d84fbd202a3706c1ee91f721c17b90dd5947a8919649cc16762f3f67bef0127b6b733db77cba54eed99b990042a7b1cde6771ff +4de8414780ea20f7943b1f1adae5e3962d96e828fee43bdbf2831bd71bd25df2976a3be37a7a667c7fbe1200de578920090d131a750c9bc09bd95b261234ea8cc25423c4ddfff5656d6b32da6e2f6f530e6673a8660aeca31273bb9a3a21bbd7031a2fa71ba37c004d3d1c64b2c0798783e47b2efe1a208959ac16e35d444245 0068dfc23c6635bd1fa1076dcbd456ad6e8df7ce7c1370fe275803befc4ffad007fd062a61cf1d50b93aeb9afe1aab47a65af82a 973eb847137b1649fc2555a89dfaa86eb0861fe8abc81671304d51b8c1c9d991a0b96ff5ccfe8b69d3063a1c09ecec0515c0ba10c440617795734640d8f1a79065e9059567a943d45e596e0e6457f557faeaca30a2a83f23a0b873200de7b02d +a081d54232f84bb19dbd52ec3812748e2e6486f6cf1b177b27929504ca878036547eb43531bb5b3edc81bfe105370427e92831d2239cca0106d031d9fa8da9cf89c6fb6401377d5936b6329ccad854e5567181b8f16a37c35f333eaa0ffe91d727d183fbab935fdac2d5670dafb3fba59e4fa2df1746c58dd8360fa08af7f4e6 0040807fb888e1d9fd33604546656a493629d94d4a0a9de2608962225ed158167f9e2438abe2d12a11e2adb6c2b66ed78215b0b1 96679c737a5d473a92f97afab5f42f49686844f6b36522021bcec6508299dffa184fc103137e383f45af35d2d57913d903920cf9f9926e23888551d6edc7abfb95b026242f2a4f951e6b66195779787f8fab1fbf17b43bf780e8f498797d154c +ea60266f1538565b3ff42fa4bbfe319be070329059c52c8bc04a7da2824f209c1145a05e551ea59ded8ca8439c328f6907da4e81d658937df614be98c7b8648818ea80ef40e49aaa4431f4a211d62acf2611f5d60c446b2b25745078c643859be1b12b3141a09ab765dd63ea1f2a2df015eca0840087a5db378c4c4cce76cba7 0033bda0a02badae08fe40c239b9d59e5bfe1c4d4b9b7a5acda6790bfd77ad08dde5e93a2da80ec54a7f88146d72218bbb88aa10 863bb046f3bd42850b248202eb079217013a5c9df490e730de4f30602c65179dfb7114d955179745c46fffef254907a5120b5f287635af21c80ea65166d3be7b7d552da16f5af086dac2fe5f546d84080e3b62b2f1731e78f1c7dcd2288caa0c +82f38c9405ef0d26bcdd5b3fce4fb0060c3095f61403418e17c337933f0563c03691fabd32ab5e896c593439e7492a9970ae325c67196d9e83fe0f9780409a930326f7e6efae035ef8c321cb9ad12461edd5cde66c04739fe079db65406b3c2d22f2d04b1a4335285513d4ceb901d2ca2ad10c508302266c2cd6079ff14eff4b 004ff431769d26b8837d3e1295f5464fe82be29edefba76323e92078a6483ea0daa96221549102509a1bdcfd46a5a2e5de10c39f 879b51dff1566aceb20b4d81362e0ca9915b7f780519d72b7b93a528040f1b9f98319c22640d8cf1e981d475093dd63915cf6d29b73a996f2ed6fc9732e58d2640a215cdfeced0e7b0a55cb6ba184ba78f9f73e4e0e4d369326038285a0605d7 +d8506fab4f681ba4ae86066aed447571eba4fe04e6585fe3be6af2ab1000a3da68c5b0c711a85ddf3a40cb7c8944eef81f2094650459e14f5b848e6add7e580b0198070f873eb3ed5d0728eabd92bc1398764b94cbb4cdd7cc2027b9762dd10782658cd9e8a5022ac062fec535d892198c8a387b3d2b6f7c92b1af6ab7dd9e4a 003f85ca1169ca7e9df44cbc6bc7d2868c9d94e8f8b699a42ca492dca0914eb5789a9032218dcef7f95f959c9554a1cd83360439 8b732c90034f96f89425b13b0bced6ad9541f538118a5c7b8c71d0617d9b0c408e5264a32ca07c74fa2eefd89228c315098d8eb8cfe37db37305a60476d4cd61231ab4df6b1f1542ab49e3fab14135df901d11f508f0a910a9071bfbcbced19f +b3f30d34f252a4c26f396079e773142bf61c0981d912333ade3de4e27cbc72cd8a16b31807f0c46116f87accb854487d83ec8c6a61565e6fca145eab70048245db08616779d7047db63aabd90dd15acbb05eaa510072c151c0518f1b34582b95f43ec7b9484b2993c176de79e84566764467f72392ef31619426d159c91816d4 003a97deb36d68f81f50c8829d412ee5de7f9d775633cb69c09dac558182039e275fc258240517a7c4aa592e364765321f27cb12 b5aceb54e6e83115ee7c5eb439e0531b8badd3faa71183d3a9b39ee7ab135290ea19b93c0a904c245bcdb09bfda75e35092494664b453b819bb5869329973cf4e72a40a6dd4936dccf7b043c29f8cf00cd0459a9ca08a2be0c6b7a9fdd1078d0 +0fb13b7c09467ad203852738eda5ddd25b17d330e82c279630b0e1f0c86681f67f6e537fb00da9419114973c8559306de58b0387d86e52d821d982a60769d2f15fd5ac2ee6dc55d8ac04ee247282cb2866b8cb8b4d7b4b6cfb33bfefdff09a73d727193e5fb939ff66ac5fcb644a44f9083a790888cc538c5eb435243c6a34a8 003b1da0ffed24e1a3b5ba22bd684337f6b08053591620541bdad50c761d66201a2cf21a4cc636426456525b598e96baf97d9851 8ae1b203f69fcfe0043b5cb7ecfac53201030974560ecf75b493a60cd3f37db7d6cfd54cc87b873f432506d6d4aa5570190ba4a64c0ad3e101fe5c440946c8d92e03bcffd6799d7344bbc85ad4bab1e23dabaa4fc25cb545da29853a83450307 +f9b8124281628cf4e1da0cb4f021c8d19d815644cd80c7c8de4cc62722904ec4cddd26cc4891f30b15098a25ba6923c6abf4774deb6e1883fbb409862f94467e75a725e7154be860fd58347577c83adbf18535c54b102220197afa062cc1c84f6094490ce488af4a08d2c5b808a2572e18a59de96c87162f88413795351cedc1 0040bac7e0d3b54c7753c79d43469e310d876015d948fac4e3a9765444754476af72330e88d79ee6119697aafac8435ab5690754 adce6d64bf41351daccbef6433906d64d097f4538a8f2ecbf38d4996c2a7ffa135c24adc0a506bb31a953eabbe78e18f12535c381d700dbb5e7894d3b5ff5a57e6434cf2e162933e1d1e7df55f6091841543052db7f49f94af8710b1337f3621 +4e3cd6100520db050af0daa69fe3cfe6603a223d4f2a6318fc5836db8640d4c7fb80bb781302036d2d6fb8e552b4eaef3133b98ba2d36b9ef0b86243b0391413c73d48ecbf1d19170f1b3b781b35ffd316afb1d55d1dda8e91eed5553780cb2714a93e7ece698b832e853e2589c5ba2b8a997bbbbf625071ded66762af8cad42 0025b7eb3bdefba3c5134438caf968f615b315204f348006f82e8d61057a8a8a853230cf0500f9d0b8c1551a59b9184862dd2ed9 951119562c530a7f1a7e2d751b6433a05c729916d6eca97fab997b0d562e5e11f2a068817f87c8d5a8d2b21b5649fadb085cfa8bdec8f8a3de029cef08339b5878f26d6e38bcb5e60f4cf4cca2a097ae3146c206b2afeb21eaabd3655c9727c8 +5411708381a65bef4381c9e13a04cdd5ba0c15829f7f25ccadf695f635384d8e4704cb562741747831b33852567f42fedbd190d2980f1bc921ce01c17d659d4bdd7eb787b3927fcee659dd3b65132496c687f2249272a473d46326e66b3cb78dafbb522390162c168f73bdec88adb145e6afecd561979846ea4c8cee38dc1686 00673b3a2985c95904732632e5d988d8d437a60db13215bb6aa880b348f011c609a1e860461427a8cf0d622abc47f910f5c97ffa b0ef02663473b182f6b0ef234bb73c02d8cd076d395fe9fabbc62105f48a05ff179fc826f0935916d93fc221ea5f5d92098cf384ed49d95cdbba478f2165a94814bb7989681f82d09d85f9efe4d4cc4fb13311598e27e40f698b469b3943fb8a +23757fa60fcabf543e603d8b31ef0cc99b3ed16b4816a84e01dbfc858872fcb79fd03d2f8a1d4f28c25dc42a39e20c34f81ebccda1682ee9bd22fe323e7f8ea90cf4a2a6ebb634cd1153cdc35f7306f28a2efd822bf23131baa1543d0ed5ab4c8168d3199983fbee117085f90550ec3ffa2b06070d3add1d707fc2593285ff58 000db7dcac414010b816236cad584dabeaec1da76c97182d1b62f87bb7fe2946a64d10430571b2b29ccf2ef72c969a9f045f1f3b a2ae4fceaf6373be80c4dd8e8ad7b1d4c312bb01e87375f58f111937c7fc5e6778534136f24c238a132fb324f217a65515bd289adf9e161f863797b1e627b56e5d52dcc1e07df6ff277c165a7268e69ba16a6a0b5b6334d6f253e0bf141e1737 +b976314d2f066f8893307a726f450dcf2cf865c170e90e6908ce9787eec48e1e2119a731b2bec3c12fd4e6282a393774251bcaef91af6ce57c63a8b45bedd72ab862cd169b7c84b8f6a72084ff823a96f2f8eff3483a7ebfabdabf0998377c5a6836d88135cf61c65a0ca7ca57727da68047dc635c17ad13731035fe9a6402af 004717efef16e1ae267e155aa1daabafc68515aa391dfeb73c13d01f3132bd22c984228dddc4dff4c39979e7585acd3f730cfcfa a92528d8b66ac23db0fbf367085d1e93f7a54bc72491a8df7c538001da840b7be786a269e07803f4f8f344be69f589420f44bda36e5ba541a1b99ea5f5d8392bea0759fc17aeff45ee82bb3565f2f371029a86d7596dff5193aae1f265a0a4ab diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K571 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K571 new file mode 100644 index 000000000000..ddd56a2d2b70 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K571 @@ -0,0 +1,60 @@ +964ad0b5acc1c4db6674e86035139f179a9d5ec711b5bae57d2988456bb136d3aade7ac9ef10813e651ae4b9602308b071d75a934a6c012eb90c5eb9b2947b50fc97b1d36c5bf9eb13a7b06c94212c3dcdab402a563262298defff62b836ead1f78f9d20713710fb48115cc5045ba15140fbb4bdf516e4150d830d02cf30963d 019cf4f4d06825499949f9e0b442586fe1bfe3459813a2b92cd8de0f775a4735e02655702ead8e60824180761808d9e816d60bdb0238e1e8039ca7bb63c92e1cf8433ef447e64ead ad0430864086f8a8db854c1b6444ed101ba47f8a9f772aa9f07c7b6ebe83b8bdc6b6d60a826edc9524a7792db512479715217497d3412e8271b68960a3481f7ecbd5423f59b858803892f9fbf3faf5575026c8024cc4fadf4cbb256703156eb2 +baddec4794effa668cde267016dda67bc70b847919a9aa595f93ba9dc27354399ef7a607fbead31e57a8ce698beabb10f313d393980425e67cf95be45d512f00e950c0c5409573ddc3d556f23daf056259ee8914e860562a674311452fed780b3e0317a7fe93baa81fb98df3ae4328b28ad0ac8f8ea33efe24faee658ad026f6 0098521a732e72ed945a549afc92318fef7156ed1d1ed9bab93b581478cb2339eb32bcef705c9bf61cf2873ddbadff8ff3806740a2e30ce67d1807a8179dfd5d952e6f8a583baf81 901a34c31b012ff8f62837b9b45710ce599101979f826393ae068a687a9893a729decca7da25b676f4804b53a426f89b16be0532bfab56b020573bb112dfd9147ae4c1e0d920f8b4b37d1c78ab8fe989e1b25ab4d5dcc16dff0ef2e93ae2fbe3 +7ef7138fc657492d229054f8a50dcafcfcd1dc06f1c16640af3f658907e2969248b54416066eb119adbfa23b8dc578aef18bba79610b9cc109394b900a25e55a779230bb858b2ddd9499a7775d392328db9177aa9571c2f61dd52010b48502154e914a0c55a54edcc04a6713cf7bda8744a893926118b09df877d1a4f3d95e8c 00336fb21549e397a190beac38a1ee10f0551952da15f71e11dfda415e5ee08da2356f114d450c661f52b2b32cfc7b9be61732672691a079f0927989b7e9f4efe6095a242155b641 83e310e617affb5545884a61464129b3c0aad0ef75eacc3a027c29b1d12be31e5cb07d99f5f274ae69b7cb4a2bc3919d0f8b0f8f991ee3af2ba992f079bf7c2f6f5941bf558b4447b9953403a728580a596f6453594cf2bd86c193d148698e8d +d58e1ff1d49a471d0567ecf8f29173dab5fe5f6184ab4cdd095c231fa7b82551f99a482994a46c3d8ebc07297fc9e952a5dee7d5f199b119f6f8b250f8fba45701ac252db725e75c4da27ad77d59a4eac448e54a277986740dfee6596811e59afc9755e53d24b826c09e497e29e69a22bbc85be11763064e9ecad7ae66458ca0 00e287ebfd9ba294128cbd484fc5121d271cd33e685bb1804f09b40aaacf64b5a9f2cde9b30a4a02d3a9bda97d92f46bb8787b3c61f280b1e1a0680f1f0679d3bb34d53725d62e52 a5ed1a865b222027e486937b2f75cdbd954e9df643dbd74177895591f4abd57844da8083a8ccb39b161e26a7eea1eb6717ed7e444127c44fd4d57584cfb5931d2e33719f907463eacb1e6d9db040349ec45e2a1f8b6e60a2f71d590bffc6792e +4949ba765c14c31f68ee0ca26bb42ba2edee63537de4a6f5c42bbd862c21288d6ff48145260365193c6fd2b56dfb014da26b8a483776b717c6874f627c9a622154b824565b23e178240f53ee9748c45759ba5c035b584df0f09504e95eb9bce0301653aadb860bb25e6ea6b9606e0ec3bdb8089e6aa0d5763d331757490715f9 0149de496fa8f88b2741864d0c35b3df666b87179b7bd06cd426a45f13bc87ea9f50dea85e1fd02a532630e0e3a231cc3e7fbb7c7ba85b40cff1124e72c677c6a3ea6aa40ffc64b7 b8401866415242c05fc8175a0cf88d9ea3d5ca30e17296fde58e7e5e89d80b827a36ea714703f102923e2c56b5ccf16c18637b09c54209b0ee80c906d91fc4b96598b7a52cc1a03fba6a1743239d9c8c064c90d5b5f6ca44be1add2c0f355444 +5bc63e5c50b1650f0ed4a599960f1e4e11f6c151b2123fd71d9e3c44662312a74b6854290628e20b30eaba81555acb2fb49b640bdab2528619c7fcad0f2a2880c7ea232d427d7c935fba2313370fda8863a7e7e203d63ea15d0cfa083e716ce6068c63fa616ddc225c9e413e694cdf6b355cb1293af5d6cdea51168f5634e878 017605d7c5873d870462375d741b4bc6375f3d47f7f5e9d998917adf2137a81e63b66917b3dda8968930c4b850f2270eb3187fc756e2beeaa67fe0d73053e6cc0ff0004a21250551 987dd8d87b56695cff6cc2fb58455e35aed28f82dccf4232bc235ac5839baf338500e974002a8f4aab78915aed0cbe8f099d61fce6baf398015c7dbfab7b0ed77382e5f947623c855259294925445a3c6ffba06e7a47a862f61d048424e0d2d5 +610f6633718e49d232b3798654095e2efa0de11f41258b27aa01956480c870d901efa77e109d5f95f1f5101d3c90fc51312d9b3019d2e42e0067eed7b457dc7fbe5466923b62c83d7347e4dada571b57813bb9c21d5e308519b8eedb7a7706508ad04aa69698e03636eb30fd9fb363ef3a185756494ee01175b16847f5b68076 009214dc2da0967912c31995cb8f5bcf4bfa832c5a2d3610f3a9857e5eee7c77100d599d9ed003b4106013155dffd6c48859b846e45e0ddbc5fe24f4891c9b2df51407e9cddbd974 a521a215dda9506c714242657fd7cd529f5b5bb6a8659d0d0809891260c60905632cf48c34e33c3c25d29d1cc861fe0b018b53f33c9ed88c7cc042caf5284b5d2b0d996921020b8a87e9fab9ae29e6630b433ea22a45a0bfe8c8f28991a6f595 +c548f0546cee0c0400401cd540a0aa9377f27ac64492e6baaf38e794db4df83e64ca3d83b67bbb46a6c269c04c2725287cce0dee984a0d468c9ce495a7e554a6835d72c7493bfe88dbd5a044a148c89001b8087fb03e57c2b7212d0b175d616333a9affd8a1802dd49ba9be3ab6c6d9f99a5578d26cc4707a5860c6c804d69ce 0042f2682e9ac8b76f3c0880e12c292524601dce9ea6982dcf68bfdb0d3fbfb50dc9229e54149ef09b95bbf624eb04ce1427077f30d8536be9f69970ddb449ca22ab8368d2689ed4 a873b94769e521d38be3e35fbf3570ad36d473a3566a52e3b8048ea01de52d1207ad8f0563773a69d5a6765ab9dc49040f8cadfc98b73a7964c6b226309f4009521a4d6b6637c3e69ac8dbe3dac5c4ce564da37936707703b419f5e7ca5bbbf5 +9431c6c5237f6b4b35682a0c32f68752035c8b295a1763c5dbdfd73466cea64a00ecc11356d02d2a9211dc54548f5db1651e4471898402c887fbf45005a3bda271df0158c98319d4d6751b8ca6b07100182957d5fe0d97c4e2294406f83e9afcae4850bb089f2252490417b5afd8f07f4c795fa84c9c7cdcce26bd97273c0072 017ed9a9c75cf66528428e85b0f019e3488af8b893b12023ff1b4ca9c3691b74e594539afa0f4d7c3863d15399b862f15e27bb077392d6bbd546ddfd46728c75177338466eb2f4ff a613be011add6202c3384643ec5a1274553f2342b72ce2fe79d46cdee9d1702e9daf34eddc61a260cdda0a69193db7d20d292580cca39c2bd8e5a7c241107138a825be1f9fa578ccc974483413a8464069c3ea95ab7c8e4dcfb2419a68710f96 +417cd5f60416f17081d2c70e9a510114e08be83573bf9deae75fbc3095dffc8a7f7325f61f9d6565381710eda871388cb17619e4448836076338ee309a2bba5f737319002e259b4a875cce1bb97996101c9a7abe0278dcac203a712f0809eb3c4b85a9c380550ab0bbc5067a8edfa78abf03c09b5c08f21714e1022ebfcada4a 01bcc09b3f2f1d26ab9955bff7e8c0f85c8a61293511a196b53d7963f4a4503849c96fb4daa68c9852ad9185e01a35f0bf298e34a09ec352cb6da34f89a1f23e8ea27712a8f43aa7 8e4e27cf34b3b09a03f47dfa1c206f2277dae58bc08d506ff3085c9a725a824f3dd81a4b264b02539bb5035945ce7cdf19a3633a7b6dcd0f173185302930b9c74af4f5f14ceaeda4468c5d1cc3be20a22b72591a26df63266f3734b51f0e483d +eced8c412a153a643ccd69596389f83b6a36880286f8aeede503452bef8305942d95734fb5733f37ffeceb1c2dae7b1396c3323de11089082745c28a1756f784423fa7ad68bbfbf0d93ff8b7ad62220500df6d6895788402c1f5c69c06dd9ef55e2401cf297184e411be87c1bba657f847208c0e750f94a3df92f253b377b4da 00ec52fc3d9c272ca80623e06b15c35f349b13548ef7ee400bbfa04196850b3b8cc7b239238c827f9b0a3160cd97969ce21d66752791f5896e0385b0527d4d77e4b9fc70f04d73b2 b2a1de89428923d39dc335507e4b31ebe96eeb7451af7cf08469222164cb1ecc3255179c305836b1116f4662eee1a65800ca868aaf65e723fb2f994c764b32716af11e85f8c8008ecbc2336c222937392dbc9a5464893acd101b353ae374bccf +30e83ea39a92036e22b7bed7639eab5e5be1d00c20b4a9b9afa9a0d1653369cbef363c119cc6f921c8f84663949c8b8dc9b743ac2b1861a480476e9b64c8f333f34b6fa0e1ddf09d49618ee4f3c1f46751b5595f0aea413d4ca46f3c26b974b112cbe99c813a96a4423764c069454946f213c5f066ec38108f947abeeeb02fb8 006403de7627de22d1dcf6b8da5af62f9ec59ec065cc1ca1311bb98aa439a6d5985619b17c17a70f59e17cf180ea6828ef57f5f1f8ef05680a9fc12ab7faad5af61e4e11fb45d341 8bbc0995ee7f7ce731e942ba3f5982e5b4025e71740e2d5faabc8c81599443c60aa6e887f6eed317073817139fc1f056118d96192946168ee618e26798f6887ea074dba4cf2e760f4f45f4c5a7243a82be22fb37016abc915e4378e33b549c87 +3ed244dc16a5cb292db4b1433b0ca3226913f07377faa20c6c1402cb4d026de808ca74a6d4ecdd7c4e662105bff6edb9fae0117c50aa053aef677c0750c7a446edbb879110030758912e8fa666489d702d8fceb719963b24a256429bbcc869a1f4ab9de9db89263e3684d4daa1df2ed94bb59dde2abba63793e5f82aa2e4db83 001fb980aef64254aeb9bb613ff2fc6967503db4bc1f337882f1566cbeb57489cf32e34f310549f41cba1b951f487453c29753a184e33330e90d4b973d2e406c99a239a5c3f96233 8ef05d7f22fd346ea6cc010c1b31e5b0dfcdd938a0b061ee165e9cbc5cd6f1d3e9a16f6b08cb29967e23a0287c62731009d13f0bedf16568ba8d638a8a0ac71a7b875c2cd930590b2efe115e2aab55d670e20264b08d87eca255e97c7212272b +40343935d9423ad30f3fb1832bb08a5d20ddb3a55b59057cd275320db4a5835471c96cfb7d67f41ef860cf5879897b8dcf307bd1a52a6226847b768ea38ff1858f59e64cd635b51e6863773cc6c64b363ec47ca39266422406264668415c189e2f92447ac4c63ee5d74e95d1e6af05016917ad237f482ea0b02aecadd370a8bb 01d96dc09dfaf602789c1dffa5c9ba130832badcf180429660daadf4cf1be5cca92fe9713173861670eebfe3a0ba25bcc76aecac60a756f07b69687e05c7e25984a39556469f62b4 b2bedd1afb784fd2bd9df9f9780349524b97bd9cce4b81cbc4fed28bbf4255b5ff74a1d10c8c1c553c5f30d4382c58d4043bc9ea9efdcf1e415a2b212f623666792185d585c765c8e9f54059409c471784b6f4e3205c9dc1eb3709766ecd587a +274567f8841183e68c4f6c6b36c5a52fb0e88492e4076b9cd768bf571facf39dad6affeb68941ee326ee461ce1f33c26e4bfb3c9e0cae8241fbcc14cc69c1af68701fd0be3def1e87b7d52b682ebbe1cc225c1bd177b0886e3698a06d0e410a1f92c9bdf7239189f6acde0d0653815a72987671b415d1e8a70e685d6e5b14c33 009d98b32c8eacd135ffb8e13223690ef02c0c1f29ea8b4da193502c8cb3f39f9eed608c02fd457f2fb685ec4595e8fc8f388d26778d225d2b18c9bc8b199d8b65c0d1a6af33854a 8fd955d3d8660f5037c43289a65cc7c260578acfa44446d361ebefe4005f518da01835ded30dfbf699737c2a3fddc3d40b48a397c303e457f77ea5d844493f3261b3ca0791c75708032cbcab9efcdb620f98cf60edec489d97d5351420f50489 +d9c99b8da92d3c2e40dea3c4025dc37770e867c4d2746c4d726b6de24250591a586c166c88acb8ed340e161d4c81b9d14c919a1b06f1feb22c5ce5fca2693bdaf4994ac72c8983c87f331473fd094eccb3d5f3528e69d487562fb5a65c150a8217192f8aabfa7adcfd0b6916d5000248fbbddf1ca2f38e3d9ed2b388998b7cfc 004d873ac744c4f68bb044783ad69e1a733cb8b8f483f2695bbd90c4211282036ad7914a53b25c3e890c6824643cffbdc4138d7ff457e3fbb99387494eb5cf2bdf1ad243a3a1e644 81e14b33ba1d5209258cc6aee01b175624bf9997f5bda934576ef86bde7e665a3d9c3a55570d6e14fad29106eaf9921107cd024ab421e79f4fd174720da06448befa80c6a519536e94d39adad3b039842db2f50d611159eb1de14be3a7cd8cb3 +d2b88a01fa17703c99e5b867c645e98feec0d6d1afaa20a97b5fce9c23f0594460142af4e36a5739b8d26d3ba35a0263caa5429b4abba157f359fce701c43372500fd2ae1bc2ed80bfcaf8cab7016ff93d4a27f565b7e67fe7dde22bf02c48be12114fbff2421517c825019c0ccc72d927bef156140d7f0e9b6ee37af78c3efa 018d2eb947297a054f8a789771dd875b12b26ef057fb91235dff3b062916f85aab3365609bd2a38a861439c8514e33f174c198139354e63766942f605107cb1b9709b782622b295a 8355304a150276c95a3815ff4142d7070e7650c2dc850c76fb73532d5669e76f1e3548a2b9409138aa49fe1f4db76d3a183788c7729a8b79c98aac3c0f468c55e5a712d694e68e916a4df6d60fcf48f3fe8a69065f70091a88fef8465d008b69 +a704a1428cc894f958774368979fe075353b56790555386e3b043dc6a2919b94a11c7f85883f46b4d47b324d349c28c667bf9a000daaca1d7191f2a0fd97a4867aa9f72422134a690625408a9ea4b723704690b69152655f9e9dd5fa3dd94814d97dd4f13e85c3f9bca769491c2461fbd17e28afac00bfa81371d5039013da8c 00594fc0b7a5cc0216d2e78eeeb6394c8225de795f4b73bec48b2f4ede185ba622b59a16dd3eedf8cf2c94f2ccd6dcd205f64c97cf1b7f1e34129e94b5129502909f43940dba0746 a98165803bea3090d48c44fde2dffcd8a341e4f4b457220292b2ca97fe91bd44a0377ea54702be19784eb6b97d29db30153892d3b09ce69a5f039967b19b5824ad1d9969713403a673c35a68b56e58d7a3d5a722df22643c740320b83cad5b50 +f8a87c4acadee27a908718461e3b45060ae4ebb009b10a15926460bf219cb7e75dc3a993fb9a741b94e2fd71615c50f6df958568f452b2cc284f0516816bc0d2e2d45f663155660a26326f63f4aa42a6e1cc8462a2ec620a365257ec042f55e4047b62af689592a1a072553ff174dd629a4f51837780ca232cf479a68c1ebdda 00f000631106c5851e8ae0802b01e7a8a8540b427a8a3956a1d36f0600be89318032320cc420931d825cc964e823745c60aad3437ebc1c91d32004472e9677605fb708e5a71a0d83 b725710a1a0fd769e207536312459de78f2644c21ba190c9afe048ef6e71e9e646c7f01616b9fecdde531823f8373e481627255ad38a0522d88154018f609a265b2dc89ea4bf7889e31d16bb0ddee310f4f321f0389423434d01fbf1ec1aec63 +10b5438294a77c7e517ecfe8f8cd58d75297b14116aa93e574996ec4acb21837e6297cc0e7e7b5861e862062f192f2206a01b1caf42c6d7181d02c7d62b76c2881f8479449b02d32c6f792714d8f70f0c75e81c7d9abb996be87f5ad9a01fe42b75855558d5f00df392b62ae0d258f3f67dbeaf07208952e679a2c573aca941b 01023997206341c6147c536d034a9c38b4012035dc2c9b7ef0bb9cfe65e7d788296f055d508a1fd957b2dc7f9eb10c27790f15f30d81670945e54a508c57b70b46b4a09f4c769289 b342b3fc1e9f56d6502a5abbefb61a2499af5b1c379cbf65b7421cf58598259f919c98c943b4cb7a4c132fb53c937bd70e6304ee5de0896db78932cab47deb08aab0266b5886b101e7fc69dcfb94c20b875651f1a047d25f07b7fc0d412ca1ab +d83a52d43216fdb16b1b40469863ca8eff4df9fa358deccb5ffd18b3e22a9d654aedc98f3dbdc4f5b4e56b4299e25d8a5a38d01b34eb93de382df1ae4d1c7f966e84b84c393d167aecc6f1192c4b42cae83748b1ee3d9147ce7de74cebd122695b455e8082f86e3e488fb0f51b3b7edcd579940d1cb9d045296e5e38f201b7ef 011ebf320ecf6a908ea5b868afb8e22246ce84e743e1076d6185ec65dd79043380708bf8da4ba802c3b93b8d15509bb7d7de9dc29f1e9fb0f0f2cb97a26698f955b1f7ef668122be 9766dcf5d4596a75d64c9a8d39d2f6d21b94eb6eb987512b5ea36b2e46e4c7153e76a944a37f2e7849edb3e8c3282438038ab72ef8f5d134f49b487ee732f577ae3d3096005ea131ff540e90b7cc9db45abd738ad1c0ab5196dbdfa7d101a1c7 +eddf5553ed4db6e8ce72cbcb59fb1eb80671c884ebd68e24bd7abe98bb1f40806de646f4d509be50a3fabfa85c5630905ce81abfad8a55f4cd80208afffb9056bc67d9dd7f4660a5f924af2a3745eec2daec39a3fe36131fe9eea444b92d31f6a125f12125159ba095f89968a7028549466f41ad45668a861f671050d2a6f343 00746d5c824d78f42a1fd63d8fcca61f154ba3e75788b7a0b87f53e5420e23a935b02eaf67bace8dd8a8e7c1caee30154c2428e0a437cf12e235f41c416f92fb54528865fd4766d1 b1eaba74469f58ac863ebf9dfbf1d0657dc5d8d3bec52b6eacb528498c3e95968f364e82e401386a1d3005f00f96838f01abd989393b8577e1923bdcb7d902d6214e60271f8fff687ed306b11febf083dc2d37638ddb4e645b751bda17c4f883 +3db94335f6d1a125309622c0a9d71bde1da09371f0285a93bd0aac255fa8f10a56074e0f6057f1b1aecf2d86a2319590ead96a2ad1336fe844e09339b456be32374ba2e659fbe9d0f2cdd83444d117d2ce3204ce4b4294dd05405634b84747ffb4227160c4e5c2c9da9815b0c6d20f55705f16cdbaa13d107ae666d707ccbe6c 000670e72ac2de50dd2cdd975a6cdab10ac45e37ef7a28c685d77447051496b5e161f8b1b93f6c7f32fce8ea05e94ed35fd7cb28c44bf51ea29cbaf5aaa31d6abca30a89430323dc 8d106639a79fa7120b3247de65a8dab0781043f7ff4f0a55a0246418d953e5ef48c64f909fb662ca051433fdcb99452a01145c2db92c6009750aff1b18b522f184ef4f57dd58cc7dc8fe1f5657a092fa55d91c194745f08712c9e7501a0fb2f8 +69166ba40768d0a3930325405edfd85f3272f7b8e600b0b319f070274c91f9f03d0e6ec4bfc7b4445e91b87cecabfecf5e77c7301ee3c6b0affca2fa02c92216698705eb75443eecc25438db2d2fb4b24f4195d6b9c05c53e0868d3e58477100607ffdc31b18c40b4ad7202bb034e58653daec0f6b33c024d42a3fc84bd8f86b 00369a3bb96f884983c23281bcd04e24a3e5f6359f81e3c8e46f3f6b865eb6bdf98a630e90646275c587e41b546d3ca7688cc207afda15cf9b25cf83bd6ad27908647f3f9de59de7 8e69a4c617427eebe7b54f17c7950a3cf4ccdff6be462c98dbebc0ea8c68cb1f05f23e110882e62d043705e54f99ac7d196fb0693ed16330d67000e743bf45e89f43a3228eaf7e8bfe794e9149d241c1889fc67ad53b6bdb47f276e624448dc2 +f64cb668b72f1e6dd026a478505c0eb33446ae9a2993bc7648aaed02e172fa9a0e05eeec61e756ba246c1dad7e85d3f01baf734b1905c5bbd1b08d833c2cf1e079eca75b866d705c407eea8618d23ebbaf269c7185984b3bd4117ecfb295ee6b47eecc8d3a78bb96552f6be314656f91caff793838226662c75cd7804b6bef79 0026717b039df834855511815d5665ff9b654facab469390ae257b7f0eb4dfe66ea0dc037242ed0c13bf229b8f7ff26da9b55fe4750d3451c62804aad493c179ae45d08ece5af085 b73f12362da2ab6e05def5afe342e35099ce6e22f23445e709ea2f7c129c9730dc21e308197c97afa8916ff796dc8fdb02c6bd22919994c185132e9445e6378b1bd4dd9d6f797e0a0e0b47f674cbdeff1b0d343ced62d3b4cffda9d62aa60fd8 +51ee0b98eb6a3e3c1afcb35a33697c048dbf61374629ac5702a57801fafbea4d6fa5a26c9d1b79d1c58257ac0106387fab2d4a1b7f8c0dadcbe7c830613531b3c209bc17f792bdba1c1fae1b7528aac53dc86c2094b40194577325c05d2258303a2d17c854e7449489c43991b6877a50692a6340a528a6b188440ac0cddd4c4b 01d642f2d393ed4abea37173e4a79534af87adf534ead4a0a1c46fb047619221e3577e6b8bcc776114d01159c736ab78af3e53feac339d7afe58be8e7a8ed290f1dad960f1b5de94 84a7f9d305e99a2003e1f369bcb6d007ae8c2dd46c269ad68e500011a4909168c733c16e8e0d342d17c14251373af7200a04c72d77359a2ed48fc64fbaada5ec60ac1d65ba1caa80ce8c8433020026c4623b0341bbef5e020cd8f6d7136306e1 +feee50aeacaccb6b1c3d95c6524044edb78322ee836d8159c4a4c2cc6982480567c4c6cc4806a564876622266e1ebd45f2f4be851b79da025bd57d0e6acce1ec1c8c255eb89713a1e4897d4ee0f7a248b9d4bd3ad5dc0e57f60ebfb65691e164bc908956a019083e923cfd33dcf37c735af3462768a1e14a8051d7aee74d5228 008cb70be29e83f697a3e2f67d86f1c1ec9a163b5335cb4a06004b6634948bf60b8ad9df9b27d2bedc4975265ce44a7884e57082d521320ca4372d38fc77b18d3fa05ad8aa5c43d6 9800ba8f40b9b0399b35c5bddffa2a8ffe34d3fb17442f2459303501b42937ca2dfb9d795128554be34e16f5cf3d6ee317c553df7c62c8b6d1e226a751716b63969e5d270d052dadd6dc193560a3a37f50d722f24fe3487c321def5b6ce1855e +b115f7370d6a93a90fd9dfdfb292956be34b61992ce1fa5627c5e928d74bcdeea66d4040c473306a0070fa8363c4303bea32f73ea3639b5c6676fa5a1d68a2cc1f91f00580d7453a23ae70af4cb1f1657aa82c5b305374effe5d67d559e46a6cee6360503d21070506f1af30bb000d2f2f85caa6465810f89968f33abae81cb3 01eef463771f9c6285f3257691dea0844687606d4dd00b6020517f190891cc1be97cfad21d147ed8881b5a6e19b22ceeae30e1132476325f2de0e9af2e14c80b8c780a9d2d6c96de ab1d0e3864b13e876031aa9c5399638b9c3c9936af656984a4c1cccccb0f4246e065533a12658e4c8f3dd5533bf1ab0105546bf6f887ff659898c862cdbd928d7c71f73237cf1bc52b8c52bc92ab65a6d1128ed73d9d6853cebf5485d93234b3 +726782eb0d9720daa64e4a77b5d8dd67a1a193f15eb6b5162e3d89c925ba63b7c7e1c4bfc8d6f11915b0e14d16ab53ab015317bd5958b0beb6074199e05181915496575768d026c23e92e06016598de008c3718aaabcda8b68bebca0a73ecfc7327e8d3646106b7d114dabc46cfe56265c326ee56fd2ca87abb5bed8f997c735 013bd452b0880b101df1aa65724fb60d5d85b37ed5419027481661a3617e0fb37bda1151b9b5b41f908ba832011f7850b75a07b678e5b8cb35c5fc8b94a625e4398cd5ada2b04cc9 b47da91858a1ce0701f3d09f94bf54353d2dd110460ec7d435c9dbb5a68f4e1a6255a008470253583dc13f7f2fa9d637136d4bb0bf309add017030d945d1eb16e5d811c9b5bb83586acd4ea124ff8da4aa5920a348df0092573e5f77814c265d +1c2418243fcd89c6382b7c3b2a8c341f26d08174a9e9296c4a5c98c5793a0fa48dce51e30811a96b515aa22bf9af89a43de06d696be1e531c5dece1f69fa6ecb7f20be063c602a16454ddafb14385ae3f8246c3f989d0566e06e7ed1864502896ea19df8393259c4dab3b3380a4a80b4103cbef4f38cb69198b7cf74ce94883b 01288141ec2244e4bb3f62daf4ee588aed09ce22be55e3d42e9085a947c1f8cd16533635d170bd64ae0b417346fa4670c25d41387acb2a8e14407a1931d9f7c5358a14eca40974bb a8f473a1745a82ab4b35956a0300c7ac4018b87bd12ebfdc83f292e4d9166d949cf5ebb3c1545793e2db1e370f2a8a4209620860dc9a4c504c12e6c72ec85927e739a58e7fbfd0644982dfd4ede7b277bf59f33318fc6edf8e5adc55b48f39b9 +1de4b642ec7220c64b91561caed7832044d6e811ac909f3b199cceb0d8a7db91bcdc801412044f5c34b355b95a2c6170fe497f6d5259bc20715a38cb0341c88e93029137e94d895bab464bca6568b852340a5c5d6a225475f6eefe2fc71ffa42f857d9bab768ccaf4793c80c4751a5583269ddcfccf8283c46a1b34d84463e61 001fe06b94a27d551d409b0eb9db0b163fadcf0486e2a6074bafe167f9a3b4ce8ac11f42cf72f9a1833a126b9473163d29bca2ad139dd1a5e7fedf54798bf56507326fae73a3e9a2 a008751b01dfc7ff2d6933be6491e0fe634fe8dc8357fd824653f5a521729377bb0f18f19c01fc05fed90d87173214691082e353de79f006729023af174e32cdf470164c6a743afc1acd04e0e2f016641b300bff3914e452dab77311a406925d +70279be7d7ac72a32606642ecd81b5d4d0f95fbc3c0b07d85c16adf2788601e44dedb8e55e0f9e0b4ca3ca35f5be7511b0e69224a05204af67aae11ce154af6d594d47f6e3142ad183969544aa95cae1edf42bc699137f60178c12b10a67698e37ab9f3edbfb3acdf1b3513d62fe3db33b16cbb4e1f9dfe732c107f9d0c953f6 009cdc7e4945c485a41728f83d5188f539e372ff4fe38fffcaacbcb4522428e4f93ef4972556f4398fe17bdd885768f0fb5590df495badc794d4d274e22f2f4a2535555922fa43f9 a00665aaaf3f0760886cc7202639922309ba7a0d14cb8d03e8815dacf57e6876c98970b6e91ffebf515926fde0207ac80b6aee17fd0daa61d22a9350c95b7400782fd8c78dad289c9ad93ba46af21f4fa5b19ad2ce4b513a4e484e4c532d59dc +4d7e0ad520445b6a5cb46b7c77fbd367614044ae6004494c2b3a89089287e2836c73b799cd8c90139eac427ebe335804c3788f3728ffb8edd7f49a4bcc76a9e24ce3c2299cea88c04645b82033115380f81b0c1d823e470631008d350cf0c0dba1915519985b8a389ccd8c809dbd5bb5051a79e631916e0d052d9b6cca18e0ef 002bc753d007c4491cfb8ce0a6c96455acd16d37e02c982db216b8cc1afd6d10c6be4e15a3988b8b8b86b2b5b59a5c1939889024849317f27ee08a06bd8e7524d4ad83a1de208564 87cbf2a07a82cbafd1116aa306a4b0e854707de7315f39d5a66cd7ba1fac679e801cdee6540f56e7b72fb67e3fbecb6404b49b5dccc1b1ba1574472ad6d7e2888c055569492149e605a45f37f453e3b549b85d10afd101eb0c1008e29e153daa +d49903f38b5c9b17542310425e59377f61f5b4f4740cd97371ee2116083f7758e69e7e2c1b0950ec6b76f96e3c91c721d6f2843afde8c7505a559c8a64bca2e665aa1131b75bdf86fb5b90581c7d3b61c2cff88f3fccf356ddf5ed282e27727be061b6925c51ea7f1a495f471dc8a5ca1a88bbe29e92338d3c9361460398965a 002082c6e61d0d72f040905d8c1c20d47b029f41ec68d6cbf43ce97c3b2a0a770557a33cb803c432cfbd3958fda30ec1bba77a6613c318597a85ad02b26c44bb77ca96d9cc1194ea a2dfe8ce3727aeb4a8cd70ee8e20fa2c76baafc4bbaa3ebb1243c1003e8346c3daf8c289e651182444de41fe165889e310f84134683cf848d4737ee2919bdd7433960d38e379ef2447d1a9a585f1867080c06fc0c7512c850b39b56e807abd1d +0e3f4afc3e7b25c1bf2d98098a5a87db1224d9bb45adc6e434732b8722a708ab80a1f3f6ef3c5aa70d2e1dad3e4416b12cc59171f05736c4b58bd084602c344f2f0bf3cfdcfe04c64e87597a99de23ded64b33607f7c273ec321f6462518715b11e91361e89ce5415bfc2ef520bfec378244a3bd2a4b9b6b3d68815f2f75baf6 00e298c93351323e2c5304015a4878997ae4e79d1c32f1dc64262e534d4f2c4b3e222356ffce746763373fdfb936fd330d3214a18c07f1205b20c9a941331cd676040ba1fe3dbce7 988bb0348f50a878efc8e3bf14b408038ec97c0868a398890a5f32f6499b591aac922c4a592d3d7dff8c8d04962189cc17b8746b67a8b60fea365da0e16f7e29d5dfa8be398ab62072eb523fde92a1a699745594028cb056d4bf314d938a5ff0 +8fe32671f6927272fd3cd8dd4e34d44d27fac8c88b41bf9a48039e914990bf06d1633b38b9200ce1c2a275b9c55498e5da2d0707322c3ea0a0fd7aff598fb801628264e13047c8008153e8595a0dc95d54e70b882ac2ac9314d2b78e7b93922da818d7075215e354708994af66958954c92c074d132dbb2488e5a531c755a8e2 0104f4ad56594c5cec2a988c5596d73adaa5a81802b40110dbae698ddb1f0b271fd1479c38abcdb9b234e69cd0da8a0328d2135c287d5b130a09fa0b899058e7800eb2dfcee95c1a 8a90f9b0ee15bb979767fbe3e2e3a75735b75502bbc9cdf8ba2a060861c1681c35142a5c72d6492507c3e4c03b4ae7e80a97514c9875a982f5ec1fd730862ceffe27ef196362bebf2034a6e7c056cc485ff994cdd39ddffb50c0201d3c21d55c +a8fa01136a0a78313a5d160c32fe5d1805eeb3730c18ca0c47818e82c48eb4c9e5b2dfe3ee5facef9ec59b68f4e6f3213f77fba9f8ba06dcde546ae348d343233883894f4423331b536f62373a495852977a51cb192cfbec04b5582b4ece69f345979e234de32da7a120138a057a7119735c4cb19099bf48bb202e7ffac04def 00c4989bf33b3136bcb4ba67906eaff2bcbc6567635aa4b057acb7353ee87ba3cb4cb9838f8f679729d5c6ed98e6c4199cf58605f009c6873a1b8321f83cd3c0973b7a3cfd9dbaa5 890516ecee3a2e3af69da93234f37fdd842a239641a913b011888d338d59f5694db2bf4b581bc16c990b9c209b40be8c0f9dfd45b945ff738defd193e9d9358b624f7d5f54af0b9cddb5cacaeca6795aa6426a9f2239425104f7dee80a7c6816 +ba2d83b21c783d6ef2f3b7b10e910a418a9b9f49ae0fd37990335b3a3d15627846c9a12a1f31a3d0e062ad1bec5650606ed4dd06c30e50c1e8761a29f4ea1a20f74635d5dac22e5b787ac10f4ee82b338a641484f91771c128c84d31cdab0a6b9616078c898665655ee9dd4ae73d33b94bf091b064928b959623aa71ff73b4db 01a96f2ad56e31397e236cafc108087479c9823589a5fbc3dc7488d0e5d1199cf245d7f21f524cc0e8b47feca14c93fb760e631434a91188b32965053942f3bd39b3714f9d6f1a11 b7c2ea03a6d107d85c2ca6ea89fd697d66dc051c53abecab123dbe497d323c04b856722946a97d941f16de806a8c177a0e015493989dbf2cd683f7fb6ad6c7bf91c8e6eec7b1a25f5599968668067adfc2be59ccddb2d8312191068e61f6e86b +ea2d5f4e9797bfc2f33f0fccaf530db2bdf8abcec00f09a0338eefdba318221ec0e050cad1a85c3f76b784c6e8c18da2b062f333eeff18b7b781e67d6d0a4368b8231a892e0f4103012348e5df53ac745e4d34e2cd1ee9369f97d4801ff485fc144b2007008036bbc07cb1c302a00054b54f3713919191e1d5052978c9c2895e 00c08ed8e0e0f8b0d0714b46a2164b933f8147692f18da97e5a108c44d5a5cf221cb50536e41832b83bff4026c6df156386235cf5e3e9a67b7cf9b2fa7707c5e0ff33a91601b8e34 b8586317b0f581df8d98dde9afa0527306c388ffb4292c6eafb68aaee12bbe19c7101c52eaf0b62664fa99b29d2c895301bc5e1003ed2250fbbbe0f42195abc507a34ea45956e41d2bacd7455cf9c4a2f945e6293d91f30ef22c89b3457710e1 +b2293b0a09f41decd9d8e637b1b08c2efe612f33c9c0beebb6e05033c6103b958f8aacd125d7c810b4c287349f5f922d2c6ed554be597fb8b3ba0e5a8c385ed8ae70d5ae19685298f20e8d844fb5ad98db12ba7e5f45baed9045c3e86b3cac9bd55b614b82fd075954fc59bfc6124cbd68edae988596575f379d8921b594c75d 0144090a0ee38cfa21fabcc24d35139a99656911ad4f6dbffb77dbe74e7993edfa9fd63d2c4f6bbdbc8ec21ba13c9f4a3576b5d6e3abeab5af5ac81b1f2bb6d4c42dde645d854d9c b92026e84bd184acbf780b03c1d0bd96be60441ae64319c5c14c77d51a22f38dde28c569578f66498c11a580889aa0e316ff4bc079a9491649622761b0d369eff5465d547f71ec46a9860d263d3fabc885b304ce29f0b4f4fd26b7c40c939d1e +acce54270252e7d9e983c08c993cd6b7e3caf482a9149036afe4665bd3d0662a6818047187872862d5718b8ac063477f693caf1a9baa8bdf2f36d411a796f2b46ab56f66bc94924229f8264016d6769c85d9bbb7d6bb042fefdb8fde1be026b86af2017aacfe38c97309b4689b23fff94f1de880064f1d3ad9d74dc804c41f41 01df26b672b2e3617b6b6c631d3c6be0cb49c0a690de49643e0f416215bcdaefc03fa9c708471f1d87476d58c8f147517ec8a14aa945ef001fa01984d5c3d81f7083ea500558fef4 a47b06559d32d6d5d163b91314d93d5677f5140b9d6dd79e535213780226b8e07d7fedb0557a961d2f882331ed203c7a107b4c89afaf30fcd01f01f2df1c5bdf970c442791f5a0ed12e4e4f8c65825af0890f933b808d602ccbf30fe8ab4e0d2 +e25274ded4840df0d71d3369007118f002b83e2d375c78f7e29ade067db15cce21842611f3f015db2efec57da77cb9d16eb1e00a8c1444d48dfda569e29fca1ebf40a22fc646a9fd44460f0e473bde487634bfbdac2c312f66a1c2982c6fe76c54ac72b6c8cc9345e47cb319a974b3cc4bb40634df74b4ad7e18adfa9a71ddd5 0189918b832e9fa30161fdd927bfc267f6405335df3d66d225e17173af52a671138883bcb94c4403ca3e001fcf09ef4c6488934d6775af2b1da30a8f331579af2d0fbb530298d8f9 afac071db21d0930190e45e0ac0fb0d67b9c67a2f5188c3d522a3776912987482869dfb9f65c416aaa0bfb722f0f7295189a3ff3960a9fa5ca215b4e956559e67cfec5c325711b458fc5310f0b6ffe02ab756c85e6945dac7842e396c5b8125a +d8a4aed87c316012482819b03a1d91691f2ad11a2f46082497ea8f64880d686891f7da550b2ac17199c657d4eb9d04d5cb8eaa180f743b87d23b1c86103f9e9bb60f4e19f0ff9d160f180aed7735130c03adb62502e69be5c624ed7bda2301f30580ae0921b02e103a638f5623c02c186e3bfe6ff134c762a2bcac1f879a9353 00bdcc175eca3a399b944eb0334ff33c4fd130999c8ac0e7b52ac5b774fbad53ccc3a31024f5262b2eecfeb2104b14bb244307effe3dbe8ed25686dbf46a42c4b6f8e34010ad826a 8c701a0be0b2fb0dc02a6710aa9b6da10a60243be2b6b85ee0fba0bcca47747d7783af8543985b8d542ab1c9a38b6243022fc3332f20a2b30d116fc90dceff69ec3a863ad18575c24ecec197953b3dab67f76f5ebc4422610cd43c9771893dfc +acbaa5ffc4eee0850075c0e502a70cc7a897a919f5e7bca4e798385601a26f411fdae5466ba9f6b6d8d7f819a749b799fbf4a3bda9105063e74914e8583ed8b31ea4d22164bee6f14bf53afca269b901c80cb3265be32ffd4ca4bc4ddb83e11eff82ead6d75dc4aec8e5c67f35d58a8a156cd1c0351abdccc0c5396c8fbe6920 0007ab5a55a1d8ecb7f5dca2afdf9ef465569a4b0374716f604ad42a6e0271e934b09655e8e2529784b69b2894bb399b02aeeae30e9e7ae70a2a8e56b9e775bd978a04c728e3951e 973375d3de8a787f5fb9cbdbc474368673851abde7791b5aea382b6424e73db3f8f92ba3b7c637d51390eef1d2b252bf0a46a84b0b378bfcb24b1fa21c009e04d6ff1f041dc60447495f47909691bd242add05a08dc16533ff59fb63f3f47dc2 +9a57b63a4f418404e8f5dcf3052b9bc04a4f6d2c33bde8651506d9cbc5542ffb9023292dea463111fb78913ccdcd182faabbff9164219b8900c7f9fb394f7d9678f77b18f8d58526ec64d7c1328953b983a7c416583e05a069cd76aefe26e5f5687b70abfbf9f58f052dc0863b4fc3bef805cc3bb05bf76a83235af9d6adfe66 01e7d4da72b1d82e17a066fe387f2a0a7fa4c60ab993ee09710531789186077f2f32b42ddda497d5fb57356383e1f96973df043307f0b6519430c3f0d40d62954032872fceb7dce9 b05fbcbbf2610c9c6be3886145af0e09b763cbba1546933cca3ea7cae0855e4404ee4a800dc7ba959b3ef4890a3abf7618843c9946ce406677f9aece5d4bb4d1150c87db72a41adb57def12469ec1baff54fadfd76d1809c9007c893ffe954bc +97b79c76d9c637f51294369e0bb52c4189f2fd3bd0607f91834aa71b3555605a89ff68e84fb5bda603f502f620e14e8b0c7affefafa2f0b303009ee99653ae4550a05315e551dd12a4d8328279b8150d030b03c5650ed4f8d3ba7c3a5361f472f436b200b321e7863c771e20ddd7bdf739c51de3676f953a5501e4477aed1bd8 015b7271d4319db5743119c8103a7d4c6d57e9c62f3eb93762156d2ebd159980aa57cea948e416717d715a2e458851f1b2e9ad4172bbcc53861db29c3ee0ba8e82617a5866170847 8de7ea11c66780cd05390497959e2b944aae6ac0288dfda6dffb051c0359f9bc4b9a4180af41eb3fe193524573fce83c00f3aa3e5db19e4cdbd98f6ce8fe0c015c9b9d87cddda15ede603dba35af5314e74ba13f5f1b15ef2cb2d8b796187877 +564ad0e37c9c37a60872a4780a723d08d1159ddc77bd834d74c1025cdf3cbd5338c3fc07a904fcad9b979b2a2ceb1a0139af35e5112305fd662a57af6312624b9bdd3a64849f95f59a46ca8feb2ed56f87f258518947474c1729275c4d89b7dd286ed65f286cbac76002cc63b92a73ab6bd13c4adef282f32297e441bdd8fd36 007219ea7917d174a5386df985d0dca798ac9f8e215ab2f0003aee929a2dbd91e37fedead0ed95b1e8aabcf516bdf54337b4aff7ace4c6b3179f2e919a49db50a41c9d4d58d4f636 80f6f6e1bc3dfaaf7371b11ce0ef498156c658bfba9dcec4ceee391cbe0556e0271a25dc4f79127940628ccd89aa9f9c088b5aeb1bebe4e25cfeaa9172faa3587f172ecb52eb5e9cceece8bb1e4b3d72dbf21779f3fd05f5aeb436e51f907b54 +072ed5b14754fddaf54e20da42432df49bef38f4a3b1841b2db457ff86c44880727aca945770adb41269df41fc17f6a687bcaffaa45a3e59070526ed53b8dc3b78cf9a80a85461eaf4b477e44d5ec4c2bab9c05aa747a5a520b35fd09e8b44539d060ba1c3470267e0dda111b15dbb587614a46e1e477127f963a16cf3a43ee5 00bc623152253da24bf8d752bd78aedf7d5f6a2f889453ccdec14e10753335ea8bea83fd181a1f3680ed50f2324fbeaadae160cc85831750e021f3e44121ea1b1efc29a7d0069479 a8040c23e75814c65f61852d2454a0f107dee4c6c936f17f6f1a732be654fca34c20e91f6b7dbee424cb036a6d63530b0039e244d19af15c5fad21ef4e162c6fc2948f060a02cea85db8b3632f6f8308dd76331781d3b47c27224051d519c348 +e660dbdf3e61af39b83b95d3f1970f66d616f03273f7dddb98f768452b21cd39604a31cf80590d4a5e4b0d4917519e10fd325dd4ab7a52d70d154506329baefe0d5816f514ae109483122b4fa8fa1ebd7fdf1fc4e21e8d278a50c05d81c8f489596633d949c6c8fea96fe91430c01522a5afbd5042be8aa47da04581b2bd21cc 00645947d981d258f2954558c31022a3b6ba5fa7b675312f794cb61bfff1d9ce87267e4a1dacb7c8fc58624d31c85ebe22f80d26a620fed5df5bf38515e0903f0b69a606048197d8 86b565764afb41b8023cd96abae9d87976f02dae6a72f9f5d064c3106168c02412c5d4698a04f2348d020ff94375851f0852285b66e8cd1668bdff69cbce1b4ee2a0e6e1c27594a5024d137775290c0aa0a40c65b49b7c8adf5c855ae525a03b +8c9acbdc431565feae60e08bc7da113e12372ed373f1e1fdd581f98c8a7b0c79ac4aa42c7ffbc963fb4970fe26c5b5dd314b7051fe971c1186ebcb5650f7f7011a924de893f06961b8c75da7bff331847feead4abd2e8b9d6ecbedac18f4eac207b948e6e4215e4d5cb483e5c66ce7ad788cb89604d3a3e051539094079e7bdb 014cf93ca69d94ee8fbea0c8da9d76aea092b73073d8f5385b65c6dd4d567fe86bc2cfb8e8be890c3c6cd9abf7dc3a17eaecee3d7a9455887863e496c48dc3e47821bd3d825b6bed 8fdda0b23946d428372f38c26b28ac81b8b761ea128310941ffe60168fad9f987cff23f3e0e43a78ccc3b78045c511250f7f380c15827c8099fa2f99b9178bc374e7ffaba0309478eafc82569427b3d7cfc6c97fd79f53b69ff02459c6513eaf +53ef87d6ac7b9698f40b3ea9f3442e7b64207b140b7f66f73fb7d5f8f98452d30a4e493b6c0e3268371e88e612b818d4d847f032ed4983817d020411a52d81fd2a17b58ebdec199d817c2a8ba77042bbd747a6fd4bcc7e844ea829fd8461b389aa0b5957d92962b6d4e86385a8fbca90b8fac40944607117e9a4ef6dccb8fc1e 0033feeaaaa28f16bfaf5ea9c7319cf4561ba4fc55327a8477b6cd58ef6ccad3962ee1f3edb243f3a04e7e49c8e23509fa2d63252adb186b8bc7e9255cd61fa9bc45242d42da3a68 966e76322576eef32e4703141f6fa0c789eac491d1286acb6245bf3a30b1cbda50086c9161bf3c8f7a382d8ac78a111e0480b858c01da3382bd2388b7ce21b9b988ae3fa71424314c65c5ea773d9274f82f4cf66f4acc55ba927a7991d468c3d +dca1b7a9a313ead11c2d54739d9017ae27f9d08b3544e418aee862bb57e427636cb6aedda28e10f12aa15d2355f4f8ef112a86fec5dc46e6acef693cb8fc37c3e4885f3be3d3ab31ea4d73a0de904e95c7135a149f77b621d642f9bd8ba192d39cfc58b6f19a797c4f3b4f3a87054298e3ce5eda0ff7f44f8134c9a108285dfa 005613dfb53149bf5fdc4e08ccc1c752b0b66ab43aef2d008ed40f3df40fcbb2938d2c41e3ea2dd4428aeba9059a97efe5593119673866a19d27a2ee37dd357e22b6bc849e7e22cc 9948fdd4acf40144c4a47f08dbdf84afbc68bb941352d259c7d234c3a15a4263b3ae8415748b9804cbf2a047f2225c4c0dca3ee0a0df6377b2c809a7cc7dfb275c3f369495105df03e50c1ace35945c1285a541f837022135ab3c1d68c27a63f +aff61d62c8f5c31bbb7d0a64a6ac589e918bbf2f13e7ad13abb9ac26405e267249a7c9922139bc28140833e10976b87e91cf28285274b2b48b63d24ac94c85c70fafa78f8ad05955c0ce6c02b841ee196dab12306e3e3d6138371217e2b474f7e67a80bbb78a47e374ffe2c9f86292e471c551da50d46e7b5c8331029f369767 011b92c8b72b86c51903387a65aa206988d443d1988253329ad3a89c902ff1ef8cf73b7f2e4aaa352443bcb833712d94c3e637ec12cbe4c2d4606878576b17fae1512fc77785b737 9382de93c4295782f2549c6bcfbff1934799684e35278238c33f6e0fd9d5527ecbe569b1c4e1cdb0839192f8facae45f18d5bb4e56d888fa015d304c530ee8b8aed489478dc71b4c771f972be71f97e66105665fe034b88004f233f5e4552105 +721017294f17ef351e41256b57a64a79f3636628c4bcbe676ac9a2d96076b913dc4b246c9945183ec9bd2d251441b5101eac44e2fa1bef59dec03ccd7fa5accf3b7d094d68dcf78c8de4e2f19f56bf0dcb3b66b9421ec3f8b353b9fd74feb2e9affe0bf9aa421b6f03eeba3ffd58fba56b3ebd094880e50de01ee62a108a24cf 00c3c90d5ce4375a08b85575faa78ee6bbd9e5571ce5a90582042617b807339c282cdc3b003d82006264b1c08c20af4ad4549fbde53d262facb98d923d81b8eb6093374b6a1e84cb b8ddbc1867fc3c06565952467f8a651f5f508397cc7d9aae1d82345face1dd61f98f54bd35f08bd2caf835db9f623467154f9feb6fbfaa2c5a06c29b371068f037cef6b2ce9fe1cf85ef3a828c15f78781981e3da74ce512ec7b809e737d012a +e2d1f33681759adb7954bb5248b0db3c3885fea0d4c1c0c226eb1e6d2d3ef1b9ac281a0f1c2fe5175b67114b6a501e2426d1454bd5790dcbc4c232cf06b017de8a9bb39e6033f1edb5003e8de3b44cc3d6150c3c952afb442952483cc688908337b7c1a8b5c9da70937ccfa98b2b0098c530ff848010b8e8ee0a8d65283481a8 010f184c16228d9034271332178ed485d10b6aa76003efc160d63fea26fbbdf5552205ac7df0d8c852a1210cf0ba512f20b798827b36ad56b12a826fa7dc1db45aed264ca6822659 84a3429e2bd83dfc015e1cd3f1f0d605b3b8ea2ee4a3b51139ba86a6d52c6ce6ae5a0c678b173b30f007ba384e2e97ee1365329d0f96378203411c809e3a7b9128f6600ce532d7e7887712ccb1708ee01db4c4bc6ee2a87e85f5ea31a1f0386b +414fc5d2bd56b30040e105cb891788792da595583b11b8fcc7320f40dbf64d9263532dc57344dd17573c95eedf851668b5d552e8796af205f3a0043af1a829fabc2e93d9af9091fdd9e0fcbcc9d6d9ec960aa60e4e2964c29a2f375400366480e513f63d124db7745847310e69a38c8455e4e602056a6a4a14a8694155e0a9bf 0181baf9d497159f837cba58a11ca435c442e5ca792ea559bff9f6a1f562c05bf6bb5914afbd1bcaea75b35f88bdd832314b249a5298622c89462344d3f28a44ba3d059df432fc71 82ee3e73901c8ff60855279285a5cec70cac2bbb39318381fdc8094a2c823cc65efe37acdf731a4204890e6989a1e994138722199bdbedc59805dd335fe942a33cc0f44baad89935410c3117c843649948e56f06ba2e3bbdca837ad465d68c72 +3b592cc8972a4782870e079b82a50f84b4c2d8ca90bd500d1ce5678982e266c391c556d8162ac3aab967154d072dbc0ba1dab5545cf2651753dee2881eca5abd412fe624bf3f9d17d33692d21ce23ad15ccffdfd250cb1949e73c9e40a64ebebb03852e92692dad1d7baef97fe109f35b7a492b343d4b643a4a7b1723eaecb64 0083fae86ab96bce99a53e50b7eecff38e4e25b21c4b0f6a4986915de245eae24f16b6a00a4db159ebc27f5a6a072da94ab6be5bf75f5eb3f75c4452bf4ea7014392eb1e02706fb4 82eec77ab1908462f101b35bdd635e09e4ed95ca974ecb6317e010e1deeb2d0574cdfeb3377c0755d6dcea9aafdb7ab01207105fdc9fff82cd287a9536a77019d9dd8102a9e7b50d8a2c60e41bfc0d42d41ac8dd0c424786b40b2c06415a52e2 +0079a02cbab3dc02601fcb5c8607d555beef7cd71a66911ab6514a4ae21c5a9c0e166f8cf5fb198ec5a49a96e17cf041f35f00406b79270ebfe56dc6b8417d2529fd625686ffbc8f69685aefa2fd30a937c02f25b48be4679e6fde821de928b33b12470867def874bb8c7c8038ab6594346a2c44b39210d3610994ba60a05e06 01a663efa7bf4d8479bc535fad71e9b5e4f4281aec55967baa008ba17ac2f89cc3398d30573edef29d590fddce8cb157f655e92779f59e7a18d0327d02e7daf4c1216143b3688fed b4529ed613ebfce29edd7200d6f3e88a7703e715a34f725b252ef25223d98fda9013ee1994d193385aacb683991e470b13f14cedd9b140063fba7ad836b26d13c7f0a7a4e8df893151165042343e712619d30d78e9f48fc9da01317855f94f1e +88573bd94ef50459814806efa868ebf92b066fbc2f7a4be9d2fa06b9dc1a72f72d783a6bcbc107b18a6314511bff217037a2252e7a5cd34cf9d5b2fe9c7846931f0133b2e95876cb800dc4ed7c4a4e4cc4f1195acf99fb0ec224b1f8fa8af71f72d390eca9d6be3879032a318734a63fec336c79035a43f70271def10c4955d3 00088d1a2c0219696a94337cd56516252b74139ea0733b17fdcbf7692c3e5f6c3989e5da2aaed7468e65a5d578571928ca273ec3b6aa72cd196f560f05095cdc8346e5d31c4c2e0c 83dbb2a77eab438a5dce6c8cd25d35613c0d0a2357e2cbf62dc02b4d33cbcdff76e5060a95948469ff3dd10e1fa0c65a165036aa8acc8c6b6c40d77b4438ad0bdd60efc69c80be757aa7910d41c84695baa05d52b2b8f18c0afbca7502ddb95c +d0e02045ece6e338cc8ab41d4a064c982ccb1748c48fc2fe0a6f10bdc876094358a6a90a45facec798a83cc95c6795cf0f0d7c66b77e22cb114c1432bfdaa1485ff35b6a58107cac3b7e58cb4f6c87c68db60b751e78f1fdfa54b8923b98caad0a4f31226956d065c083ace5f1e9e91944dcca51879d782e40358d58ca758750 016cc8a0fd59455ed8d4de561fd518df2e008f7dfaa5f7f29ac2489a411e233917b43eb3ebe2596fc824be58871949545e667dbcf240dfb5e0c615ade0179d9ea2a1b1ebb8ab9384 90e44f5c59016010f7fed188710fdf47270d596cb1ce8112454a4d59fa647a6b74c0af889bc6829fcf281d32c3a54c9700e0586cd99859af1eed1d6d1a195206520d8f5f2c2ac93ccf496fe536eb7e11048d2e5424a82544883eb99dd55fd39c diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K571_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K571_blst new file mode 100644 index 000000000000..24a1052c7336 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_K571_blst @@ -0,0 +1,60 @@ +964ad0b5acc1c4db6674e86035139f179a9d5ec711b5bae57d2988456bb136d3aade7ac9ef10813e651ae4b9602308b071d75a934a6c012eb90c5eb9b2947b50fc97b1d36c5bf9eb13a7b06c94212c3dcdab402a563262298defff62b836ead1f78f9d20713710fb48115cc5045ba15140fbb4bdf516e4150d830d02cf30963d 019cf4f4d06825499949f9e0b442586fe1bfe3459813a2b92cd8de0f775a4735e02655702ead8e60824180761808d9e816d60bdb0238e1e8039ca7bb63c92e1cf8433ef447e64ead ad0110d31bae8bf0911733875da6a6f471e4d17d9e8d6e4bf50b531502354093b1ecbaaf730bce7311842ee1969a25e005dc1c86a051f38d075fa79123749308763a353c287a8a52a4f057259184b5fa25da546e17c364c737d47a9ea966eb4f +baddec4794effa668cde267016dda67bc70b847919a9aa595f93ba9dc27354399ef7a607fbead31e57a8ce698beabb10f313d393980425e67cf95be45d512f00e950c0c5409573ddc3d556f23daf056259ee8914e860562a674311452fed780b3e0317a7fe93baa81fb98df3ae4328b28ad0ac8f8ea33efe24faee658ad026f6 0098521a732e72ed945a549afc92318fef7156ed1d1ed9bab93b581478cb2339eb32bcef705c9bf61cf2873ddbadff8ff3806740a2e30ce67d1807a8179dfd5d952e6f8a583baf81 835c87bc83c5b4058e0ac61e544793cf5ddd0b78f1b7159fb37e98ede5a633360417ea99807844abdb90e20f90349771089e90a299df6d8e1c1a55470d05a360127db36bac62ae32c2deea93c87b6f609e1fcba9597fd5addcd0cb210e5221fe +7ef7138fc657492d229054f8a50dcafcfcd1dc06f1c16640af3f658907e2969248b54416066eb119adbfa23b8dc578aef18bba79610b9cc109394b900a25e55a779230bb858b2ddd9499a7775d392328db9177aa9571c2f61dd52010b48502154e914a0c55a54edcc04a6713cf7bda8744a893926118b09df877d1a4f3d95e8c 00336fb21549e397a190beac38a1ee10f0551952da15f71e11dfda415e5ee08da2356f114d450c661f52b2b32cfc7b9be61732672691a079f0927989b7e9f4efe6095a242155b641 8b5fd7b891fddadd9a1161b11e7515850f3b86a65e84e959ff86c69509971964ba544618d3a32275f7188ffbb387d87108fa7fef4923904efea2d53d40b975ae8f019c611603d87b361386bf9b8bfa4ea250d33f055fc0ea619ce9ff1a21fc4b +d58e1ff1d49a471d0567ecf8f29173dab5fe5f6184ab4cdd095c231fa7b82551f99a482994a46c3d8ebc07297fc9e952a5dee7d5f199b119f6f8b250f8fba45701ac252db725e75c4da27ad77d59a4eac448e54a277986740dfee6596811e59afc9755e53d24b826c09e497e29e69a22bbc85be11763064e9ecad7ae66458ca0 00e287ebfd9ba294128cbd484fc5121d271cd33e685bb1804f09b40aaacf64b5a9f2cde9b30a4a02d3a9bda97d92f46bb8787b3c61f280b1e1a0680f1f0679d3bb34d53725d62e52 962f7934810fe3e525f99ee6ce74fe2c8af337d293d96cb4f2fd31da5631f64cb8b0b945fe4f0d603be9a8629013713f051c91d0b1dcb0b789584580fa0f1a49a7edcf39aad74fbecd34557d63aad72757202415ae7413fb27f90f3ec176d309 +4949ba765c14c31f68ee0ca26bb42ba2edee63537de4a6f5c42bbd862c21288d6ff48145260365193c6fd2b56dfb014da26b8a483776b717c6874f627c9a622154b824565b23e178240f53ee9748c45759ba5c035b584df0f09504e95eb9bce0301653aadb860bb25e6ea6b9606e0ec3bdb8089e6aa0d5763d331757490715f9 0149de496fa8f88b2741864d0c35b3df666b87179b7bd06cd426a45f13bc87ea9f50dea85e1fd02a532630e0e3a231cc3e7fbb7c7ba85b40cff1124e72c677c6a3ea6aa40ffc64b7 930499b3ba25b72c28c7429af35ef632339a2e2894d69dc749f6ecbb1ffb1409db46eba1433858823d1fd2a600752e7810475b836498878dc8369d48eabc7d8626ad44febf76ef962550f26d9e76e41cae41cbf8a0c8deaa14d83929751fc121 +5bc63e5c50b1650f0ed4a599960f1e4e11f6c151b2123fd71d9e3c44662312a74b6854290628e20b30eaba81555acb2fb49b640bdab2528619c7fcad0f2a2880c7ea232d427d7c935fba2313370fda8863a7e7e203d63ea15d0cfa083e716ce6068c63fa616ddc225c9e413e694cdf6b355cb1293af5d6cdea51168f5634e878 017605d7c5873d870462375d741b4bc6375f3d47f7f5e9d998917adf2137a81e63b66917b3dda8968930c4b850f2270eb3187fc756e2beeaa67fe0d73053e6cc0ff0004a21250551 b80ce7503c232a4c7695dee77d48fb5d9a26e022160ade4daf05f9fa5e1129e21f3f80593ba5a32149cea751397d07270d4598a45cf577e7c3714a8164bce7a1d6168b7e1e4d1b18f59ccc099154cb4cc70affd36b967398e320e8144f084aaf +610f6633718e49d232b3798654095e2efa0de11f41258b27aa01956480c870d901efa77e109d5f95f1f5101d3c90fc51312d9b3019d2e42e0067eed7b457dc7fbe5466923b62c83d7347e4dada571b57813bb9c21d5e308519b8eedb7a7706508ad04aa69698e03636eb30fd9fb363ef3a185756494ee01175b16847f5b68076 009214dc2da0967912c31995cb8f5bcf4bfa832c5a2d3610f3a9857e5eee7c77100d599d9ed003b4106013155dffd6c48859b846e45e0ddbc5fe24f4891c9b2df51407e9cddbd974 936bfaa1713e3bcc99e7b035600c9edb00d0bf82c0d4caa54d35839ab76e0dbd691716a876eeb19e7844eb673b2e1fcc0fbb438ac77d87fa0562a9329e63fb89fd338f9af4442463cf574dd7c11358e3d35ffe6dd541eef13794ecfed70723cb +c548f0546cee0c0400401cd540a0aa9377f27ac64492e6baaf38e794db4df83e64ca3d83b67bbb46a6c269c04c2725287cce0dee984a0d468c9ce495a7e554a6835d72c7493bfe88dbd5a044a148c89001b8087fb03e57c2b7212d0b175d616333a9affd8a1802dd49ba9be3ab6c6d9f99a5578d26cc4707a5860c6c804d69ce 0042f2682e9ac8b76f3c0880e12c292524601dce9ea6982dcf68bfdb0d3fbfb50dc9229e54149ef09b95bbf624eb04ce1427077f30d8536be9f69970ddb449ca22ab8368d2689ed4 a97ecc888f04d6c8603b989c0c703ec1ea9eaeabb11fdd23b581754611a8872039bdbb30ced4b31030eb6b65800a14c5162bcb06b92297290562ac599e8ddba98b654be4abe1401219b6457e7a1d96f00fbf299407aad9d411ac7e92c331072d +9431c6c5237f6b4b35682a0c32f68752035c8b295a1763c5dbdfd73466cea64a00ecc11356d02d2a9211dc54548f5db1651e4471898402c887fbf45005a3bda271df0158c98319d4d6751b8ca6b07100182957d5fe0d97c4e2294406f83e9afcae4850bb089f2252490417b5afd8f07f4c795fa84c9c7cdcce26bd97273c0072 017ed9a9c75cf66528428e85b0f019e3488af8b893b12023ff1b4ca9c3691b74e594539afa0f4d7c3863d15399b862f15e27bb077392d6bbd546ddfd46728c75177338466eb2f4ff 83bc439eebfba922359a685f2e3547a07aa4a484d0fe30558a07ec1b98a08d02591b7dd35ac8aea46675d1087aea2c7219ff3b9dff80e93ecbe11ba5ab55970bdce5ccd28dbad89abf68980443e16597444ff43f79cb8dc6d68e00ce002892d1 +417cd5f60416f17081d2c70e9a510114e08be83573bf9deae75fbc3095dffc8a7f7325f61f9d6565381710eda871388cb17619e4448836076338ee309a2bba5f737319002e259b4a875cce1bb97996101c9a7abe0278dcac203a712f0809eb3c4b85a9c380550ab0bbc5067a8edfa78abf03c09b5c08f21714e1022ebfcada4a 01bcc09b3f2f1d26ab9955bff7e8c0f85c8a61293511a196b53d7963f4a4503849c96fb4daa68c9852ad9185e01a35f0bf298e34a09ec352cb6da34f89a1f23e8ea27712a8f43aa7 a87273616e9cf65f446ea9c45136a7044a08713135cd6acefbf6cf7f232b130d52f4eb9f2875d31cb8f1c5daa410324e0813a1b50776cbf266ca9e5204e20911e8691100654136247a602b684eb273c990eb37e270a7ed588889288f3244646b +eced8c412a153a643ccd69596389f83b6a36880286f8aeede503452bef8305942d95734fb5733f37ffeceb1c2dae7b1396c3323de11089082745c28a1756f784423fa7ad68bbfbf0d93ff8b7ad62220500df6d6895788402c1f5c69c06dd9ef55e2401cf297184e411be87c1bba657f847208c0e750f94a3df92f253b377b4da 00ec52fc3d9c272ca80623e06b15c35f349b13548ef7ee400bbfa04196850b3b8cc7b239238c827f9b0a3160cd97969ce21d66752791f5896e0385b0527d4d77e4b9fc70f04d73b2 978ea4c10593cb31cae0449c169e73e170a8784b9c89ee807c7cf62cc75c25874fed504422a0198eb4146964f7502e3112b3def58215eed31b6cae9d821c3a5071a5658252f75f698bb72abcd438b7c8ed2ae43e2eab95ecd3f1b84f3ac46859 +30e83ea39a92036e22b7bed7639eab5e5be1d00c20b4a9b9afa9a0d1653369cbef363c119cc6f921c8f84663949c8b8dc9b743ac2b1861a480476e9b64c8f333f34b6fa0e1ddf09d49618ee4f3c1f46751b5595f0aea413d4ca46f3c26b974b112cbe99c813a96a4423764c069454946f213c5f066ec38108f947abeeeb02fb8 006403de7627de22d1dcf6b8da5af62f9ec59ec065cc1ca1311bb98aa439a6d5985619b17c17a70f59e17cf180ea6828ef57f5f1f8ef05680a9fc12ab7faad5af61e4e11fb45d341 97df7ad607638c3f5d325da17e8bcbdb86aa1e2471c2ea4bc5807459a98f30d4f3042c7463c92defa8c907931c5ee9910938d5a076001df99d967a46171792285f634ffb87e8cf097361fcde8964a088bd200002b526d148b2b51240f68678ad +3ed244dc16a5cb292db4b1433b0ca3226913f07377faa20c6c1402cb4d026de808ca74a6d4ecdd7c4e662105bff6edb9fae0117c50aa053aef677c0750c7a446edbb879110030758912e8fa666489d702d8fceb719963b24a256429bbcc869a1f4ab9de9db89263e3684d4daa1df2ed94bb59dde2abba63793e5f82aa2e4db83 001fb980aef64254aeb9bb613ff2fc6967503db4bc1f337882f1566cbeb57489cf32e34f310549f41cba1b951f487453c29753a184e33330e90d4b973d2e406c99a239a5c3f96233 b3cf5206ccd3700b8ff9d9568901540c17ee42a951220b03f6a3451bd71fe6c90035a0251b0037016529c858a23aaf7219d27f464297a70b2bf1efe1eb674e79d462ea1a7542775e77ade1a33a461600aaccbc0d9c8b92220e9adc1c0caeec70 +40343935d9423ad30f3fb1832bb08a5d20ddb3a55b59057cd275320db4a5835471c96cfb7d67f41ef860cf5879897b8dcf307bd1a52a6226847b768ea38ff1858f59e64cd635b51e6863773cc6c64b363ec47ca39266422406264668415c189e2f92447ac4c63ee5d74e95d1e6af05016917ad237f482ea0b02aecadd370a8bb 01d96dc09dfaf602789c1dffa5c9ba130832badcf180429660daadf4cf1be5cca92fe9713173861670eebfe3a0ba25bcc76aecac60a756f07b69687e05c7e25984a39556469f62b4 895ca299648b255596a0a1b7104d218029cb4e46197798ffc7fff8ab8e97457dbacf345ed4440335d7cc980b381dd62a0e81d1ff4805888997c50ec3c101ac7b72d52b1a17b0a5820c0ebc874e4a0e5a7815827d6c62ef75811ff29e32965d35 +274567f8841183e68c4f6c6b36c5a52fb0e88492e4076b9cd768bf571facf39dad6affeb68941ee326ee461ce1f33c26e4bfb3c9e0cae8241fbcc14cc69c1af68701fd0be3def1e87b7d52b682ebbe1cc225c1bd177b0886e3698a06d0e410a1f92c9bdf7239189f6acde0d0653815a72987671b415d1e8a70e685d6e5b14c33 009d98b32c8eacd135ffb8e13223690ef02c0c1f29ea8b4da193502c8cb3f39f9eed608c02fd457f2fb685ec4595e8fc8f388d26778d225d2b18c9bc8b199d8b65c0d1a6af33854a 82df56efcd82d3fb5bf5a631b02e776d185f7e2d85d5066a10e8d939fee92b3bd9b4cbf830b8f8955d124bb08c4b3d5f0e05b7f8d9c6224fa769321a7120bbe933f519ad5f867248af6ff183f635aab58f262bad9961af137cde849489aa9271 +d9c99b8da92d3c2e40dea3c4025dc37770e867c4d2746c4d726b6de24250591a586c166c88acb8ed340e161d4c81b9d14c919a1b06f1feb22c5ce5fca2693bdaf4994ac72c8983c87f331473fd094eccb3d5f3528e69d487562fb5a65c150a8217192f8aabfa7adcfd0b6916d5000248fbbddf1ca2f38e3d9ed2b388998b7cfc 004d873ac744c4f68bb044783ad69e1a733cb8b8f483f2695bbd90c4211282036ad7914a53b25c3e890c6824643cffbdc4138d7ff457e3fbb99387494eb5cf2bdf1ad243a3a1e644 aba6d7e90210c4ab5093b7b067f1b1aa5e54366c8d8b4fd35667d3b1fbe44a4f2423fd04fb7cb76d028a76780ecd98111681047933b212969bee9862ce90b68a8d4b80b72f5f4f743f6b3b662feb853e18352a0897fadb0f0b27f36ee3233c8b +d2b88a01fa17703c99e5b867c645e98feec0d6d1afaa20a97b5fce9c23f0594460142af4e36a5739b8d26d3ba35a0263caa5429b4abba157f359fce701c43372500fd2ae1bc2ed80bfcaf8cab7016ff93d4a27f565b7e67fe7dde22bf02c48be12114fbff2421517c825019c0ccc72d927bef156140d7f0e9b6ee37af78c3efa 018d2eb947297a054f8a789771dd875b12b26ef057fb91235dff3b062916f85aab3365609bd2a38a861439c8514e33f174c198139354e63766942f605107cb1b9709b782622b295a a6d75df63810bab1f629a28cc341b26b59ef4d0b68e36b08d42cef3e47b40ddae36f9c0f99834a69918034a37f8811e0140e376e8b472cdffc68aec78196db7cb6ee2b8c6f6d192427c50708ba83c1c8e2bdf90e58242e0f5110c57c84d0d57b +a704a1428cc894f958774368979fe075353b56790555386e3b043dc6a2919b94a11c7f85883f46b4d47b324d349c28c667bf9a000daaca1d7191f2a0fd97a4867aa9f72422134a690625408a9ea4b723704690b69152655f9e9dd5fa3dd94814d97dd4f13e85c3f9bca769491c2461fbd17e28afac00bfa81371d5039013da8c 00594fc0b7a5cc0216d2e78eeeb6394c8225de795f4b73bec48b2f4ede185ba622b59a16dd3eedf8cf2c94f2ccd6dcd205f64c97cf1b7f1e34129e94b5129502909f43940dba0746 b09eee59183d5f61803d85b244a22f31ac33ff682cd67ba2326c5172a3e77f0ceff28ff9f6dbbdc6fe334a682227f933161bff37fdfbe7ba433d9743b98ee50d2a8b099c090e769f948418e0e440e1111f86c9a5c532f3dde653f9e5ece32678 +f8a87c4acadee27a908718461e3b45060ae4ebb009b10a15926460bf219cb7e75dc3a993fb9a741b94e2fd71615c50f6df958568f452b2cc284f0516816bc0d2e2d45f663155660a26326f63f4aa42a6e1cc8462a2ec620a365257ec042f55e4047b62af689592a1a072553ff174dd629a4f51837780ca232cf479a68c1ebdda 00f000631106c5851e8ae0802b01e7a8a8540b427a8a3956a1d36f0600be89318032320cc420931d825cc964e823745c60aad3437ebc1c91d32004472e9677605fb708e5a71a0d83 965881c05adf1bf709b1ff6dee0db7d089ec9f4892d63765a7a1a88317e74c8b15e7b9716b24dc8b28a0faff4da77bd9054fd7711c808f7df7a0fdb56a05412de134443c9448220ed9cc06ebae29eb2fbd07da7b4890b4d8975959a0d89b6067 +10b5438294a77c7e517ecfe8f8cd58d75297b14116aa93e574996ec4acb21837e6297cc0e7e7b5861e862062f192f2206a01b1caf42c6d7181d02c7d62b76c2881f8479449b02d32c6f792714d8f70f0c75e81c7d9abb996be87f5ad9a01fe42b75855558d5f00df392b62ae0d258f3f67dbeaf07208952e679a2c573aca941b 01023997206341c6147c536d034a9c38b4012035dc2c9b7ef0bb9cfe65e7d788296f055d508a1fd957b2dc7f9eb10c27790f15f30d81670945e54a508c57b70b46b4a09f4c769289 84316ea8e3996dbd1777512cbc3bece0828d89660b32361537b9f202a23199b23d736e1f198e5c73ebd95bd1bc76050619c886070a02c94d360b4e4ecc8709a24f7ff48bbf671731a73894665d9c1b858deb277abc612f2b20125afd7879e98a +d83a52d43216fdb16b1b40469863ca8eff4df9fa358deccb5ffd18b3e22a9d654aedc98f3dbdc4f5b4e56b4299e25d8a5a38d01b34eb93de382df1ae4d1c7f966e84b84c393d167aecc6f1192c4b42cae83748b1ee3d9147ce7de74cebd122695b455e8082f86e3e488fb0f51b3b7edcd579940d1cb9d045296e5e38f201b7ef 011ebf320ecf6a908ea5b868afb8e22246ce84e743e1076d6185ec65dd79043380708bf8da4ba802c3b93b8d15509bb7d7de9dc29f1e9fb0f0f2cb97a26698f955b1f7ef668122be 8f96a18733c880502e19dbd6d920c166e11a4d9b68a2285629702f7d4afebd5562d7f3ae10e63c5800216f2fe01899b90a8b755b1478bd141ad75239017129a7dbbeabad76110ed6db729d4fdd2017995809a4d4523809735dcde5628585552a +eddf5553ed4db6e8ce72cbcb59fb1eb80671c884ebd68e24bd7abe98bb1f40806de646f4d509be50a3fabfa85c5630905ce81abfad8a55f4cd80208afffb9056bc67d9dd7f4660a5f924af2a3745eec2daec39a3fe36131fe9eea444b92d31f6a125f12125159ba095f89968a7028549466f41ad45668a861f671050d2a6f343 00746d5c824d78f42a1fd63d8fcca61f154ba3e75788b7a0b87f53e5420e23a935b02eaf67bace8dd8a8e7c1caee30154c2428e0a437cf12e235f41c416f92fb54528865fd4766d1 a1cb4126f91b6cedca4e864e885e4cbc7c77b64f9d0437f110abd19c12a074a408a1893b5ceb355fcde279b03ec5fe10128924217a6252d1e4720887702fcef1675ce0414accec8e3969c70e86f074fe7b908b90c3d0a82b57ed447ae437edce +3db94335f6d1a125309622c0a9d71bde1da09371f0285a93bd0aac255fa8f10a56074e0f6057f1b1aecf2d86a2319590ead96a2ad1336fe844e09339b456be32374ba2e659fbe9d0f2cdd83444d117d2ce3204ce4b4294dd05405634b84747ffb4227160c4e5c2c9da9815b0c6d20f55705f16cdbaa13d107ae666d707ccbe6c 000670e72ac2de50dd2cdd975a6cdab10ac45e37ef7a28c685d77447051496b5e161f8b1b93f6c7f32fce8ea05e94ed35fd7cb28c44bf51ea29cbaf5aaa31d6abca30a89430323dc a20819143ea473f9d2973fa59d0662cc2c24a9d2d88ba8ca99c846f2688977707990e0f755fe7800d114420931893275017041117e970a9fcd444d15576ba5f9f9cef7b916d856edc75a8c7e39af622b14c718f1c98d232a3bd48ba3a9f51a56 +69166ba40768d0a3930325405edfd85f3272f7b8e600b0b319f070274c91f9f03d0e6ec4bfc7b4445e91b87cecabfecf5e77c7301ee3c6b0affca2fa02c92216698705eb75443eecc25438db2d2fb4b24f4195d6b9c05c53e0868d3e58477100607ffdc31b18c40b4ad7202bb034e58653daec0f6b33c024d42a3fc84bd8f86b 00369a3bb96f884983c23281bcd04e24a3e5f6359f81e3c8e46f3f6b865eb6bdf98a630e90646275c587e41b546d3ca7688cc207afda15cf9b25cf83bd6ad27908647f3f9de59de7 8f53be963095b4e9fd113fdc13c74f5a4cdfeb8084462498d37f4c0bc8a6ab4a7a38b9bd9887faa563f75de48243a32603de0f5ef00ed4bc1e8cd924858f694b066f2819571c989c396105ada93b2f25f4ae55a39d1c12dcdf03c85112f10530 +f64cb668b72f1e6dd026a478505c0eb33446ae9a2993bc7648aaed02e172fa9a0e05eeec61e756ba246c1dad7e85d3f01baf734b1905c5bbd1b08d833c2cf1e079eca75b866d705c407eea8618d23ebbaf269c7185984b3bd4117ecfb295ee6b47eecc8d3a78bb96552f6be314656f91caff793838226662c75cd7804b6bef79 0026717b039df834855511815d5665ff9b654facab469390ae257b7f0eb4dfe66ea0dc037242ed0c13bf229b8f7ff26da9b55fe4750d3451c62804aad493c179ae45d08ece5af085 880dcd5dd8ed842c3351393fe40152c67dfbc93d68f8457cd2d9d9642393c0b2aff7deb29bf7f3a030a175c09428f44403ab2d68561a44a0698054d96d7230d498c02336e3105dd222514401fbe58cefd01d91d3960308aaacf55e50326d8cf8 +51ee0b98eb6a3e3c1afcb35a33697c048dbf61374629ac5702a57801fafbea4d6fa5a26c9d1b79d1c58257ac0106387fab2d4a1b7f8c0dadcbe7c830613531b3c209bc17f792bdba1c1fae1b7528aac53dc86c2094b40194577325c05d2258303a2d17c854e7449489c43991b6877a50692a6340a528a6b188440ac0cddd4c4b 01d642f2d393ed4abea37173e4a79534af87adf534ead4a0a1c46fb047619221e3577e6b8bcc776114d01159c736ab78af3e53feac339d7afe58be8e7a8ed290f1dad960f1b5de94 b624008ed54726ca14e09e079c9bc3ec29617821b27e2800fe024a3c046205476a9e0216a72fccfe9b4edb8fd3052be615846a0c2ad8ab104fc064b05566e6f9bae0842725d1d12695ee7272179356632df3d0dc97f1ff63d48b00fc2e4d657b +feee50aeacaccb6b1c3d95c6524044edb78322ee836d8159c4a4c2cc6982480567c4c6cc4806a564876622266e1ebd45f2f4be851b79da025bd57d0e6acce1ec1c8c255eb89713a1e4897d4ee0f7a248b9d4bd3ad5dc0e57f60ebfb65691e164bc908956a019083e923cfd33dcf37c735af3462768a1e14a8051d7aee74d5228 008cb70be29e83f697a3e2f67d86f1c1ec9a163b5335cb4a06004b6634948bf60b8ad9df9b27d2bedc4975265ce44a7884e57082d521320ca4372d38fc77b18d3fa05ad8aa5c43d6 a79d57bf262b6c284d52e26af00467871c0973f361da1554f682702ee34f6daf024342456cf25217ae4f4fb6139ee2a7039cd0d527745ec7dbfd76d44f1c4d2b1a06a2357b31d80095d62334f4494251e1e36c7bc007274d8a04af28e156041b +b115f7370d6a93a90fd9dfdfb292956be34b61992ce1fa5627c5e928d74bcdeea66d4040c473306a0070fa8363c4303bea32f73ea3639b5c6676fa5a1d68a2cc1f91f00580d7453a23ae70af4cb1f1657aa82c5b305374effe5d67d559e46a6cee6360503d21070506f1af30bb000d2f2f85caa6465810f89968f33abae81cb3 01eef463771f9c6285f3257691dea0844687606d4dd00b6020517f190891cc1be97cfad21d147ed8881b5a6e19b22ceeae30e1132476325f2de0e9af2e14c80b8c780a9d2d6c96de 84bff7f8b345441c30b026321b9d3ef743365f3dd4414f8c172763cf1ff3ff449a8147371b8edfe71e60305a8fb3232017ded0cbdabc1484425c324b2ff3d2c8f6c8b2207e74f0204996b77db5de0001aebbbb44ebaa5c43839b31698e89e706 +726782eb0d9720daa64e4a77b5d8dd67a1a193f15eb6b5162e3d89c925ba63b7c7e1c4bfc8d6f11915b0e14d16ab53ab015317bd5958b0beb6074199e05181915496575768d026c23e92e06016598de008c3718aaabcda8b68bebca0a73ecfc7327e8d3646106b7d114dabc46cfe56265c326ee56fd2ca87abb5bed8f997c735 013bd452b0880b101df1aa65724fb60d5d85b37ed5419027481661a3617e0fb37bda1151b9b5b41f908ba832011f7850b75a07b678e5b8cb35c5fc8b94a625e4398cd5ada2b04cc9 840fc7240a5e26bc7af6655ca2d4c0a0c54e99e6dc506e5e74a3feb6678382207fda05a5fba136287bff4370d729680b15fc088eff6d2d7939a710e98223c1436d26f28f6b2d03f112850f10032bc42dbcbe6e16936e0155a65a946a19e801b7 +1c2418243fcd89c6382b7c3b2a8c341f26d08174a9e9296c4a5c98c5793a0fa48dce51e30811a96b515aa22bf9af89a43de06d696be1e531c5dece1f69fa6ecb7f20be063c602a16454ddafb14385ae3f8246c3f989d0566e06e7ed1864502896ea19df8393259c4dab3b3380a4a80b4103cbef4f38cb69198b7cf74ce94883b 01288141ec2244e4bb3f62daf4ee588aed09ce22be55e3d42e9085a947c1f8cd16533635d170bd64ae0b417346fa4670c25d41387acb2a8e14407a1931d9f7c5358a14eca40974bb b0e19e870043f182324a970309725d6dceb05bfed6367dd282878a0915f3d6fb5612de24d158108eee67448eddb3099006c94c575d8aec55bfd07077492a3dbd525209155d355995ca91963bbd7c6ce10f1c9b10c3c4024a8573506a47008ab7 +1de4b642ec7220c64b91561caed7832044d6e811ac909f3b199cceb0d8a7db91bcdc801412044f5c34b355b95a2c6170fe497f6d5259bc20715a38cb0341c88e93029137e94d895bab464bca6568b852340a5c5d6a225475f6eefe2fc71ffa42f857d9bab768ccaf4793c80c4751a5583269ddcfccf8283c46a1b34d84463e61 001fe06b94a27d551d409b0eb9db0b163fadcf0486e2a6074bafe167f9a3b4ce8ac11f42cf72f9a1833a126b9473163d29bca2ad139dd1a5e7fedf54798bf56507326fae73a3e9a2 b4e7cd59d6b9b57288be09027ce611ec298e7a5c9cabb25b2ca1d0102caa7c68ed6f1708bdab7ca3908b92571ebbaea9081e2fc6ad11026fdbcb15a21099057bab06753d91e6ef8a3b3bff6dd2091727ff39c8c41f187f15d7f1b431701b15b9 +70279be7d7ac72a32606642ecd81b5d4d0f95fbc3c0b07d85c16adf2788601e44dedb8e55e0f9e0b4ca3ca35f5be7511b0e69224a05204af67aae11ce154af6d594d47f6e3142ad183969544aa95cae1edf42bc699137f60178c12b10a67698e37ab9f3edbfb3acdf1b3513d62fe3db33b16cbb4e1f9dfe732c107f9d0c953f6 009cdc7e4945c485a41728f83d5188f539e372ff4fe38fffcaacbcb4522428e4f93ef4972556f4398fe17bdd885768f0fb5590df495badc794d4d274e22f2f4a2535555922fa43f9 b983bf701711954452055c438225590fbad539615b96f520c252d5869721666e81aac0a5503e4ff63c073115697fb1811870c4cc8e2f90c001ca7f1266ecf68794717d761c07c799c816100a1cba836a9d0054717ba4abbd42cc690c132905c3 +4d7e0ad520445b6a5cb46b7c77fbd367614044ae6004494c2b3a89089287e2836c73b799cd8c90139eac427ebe335804c3788f3728ffb8edd7f49a4bcc76a9e24ce3c2299cea88c04645b82033115380f81b0c1d823e470631008d350cf0c0dba1915519985b8a389ccd8c809dbd5bb5051a79e631916e0d052d9b6cca18e0ef 002bc753d007c4491cfb8ce0a6c96455acd16d37e02c982db216b8cc1afd6d10c6be4e15a3988b8b8b86b2b5b59a5c1939889024849317f27ee08a06bd8e7524d4ad83a1de208564 876494e357bd3cdc625c189527c5367853d6326560c55d4f990804c470d008378763e687a412ba074dfc968f6f21fd900927396dc90b9e59813c07b3a4219a72c4c6810dd1623dedfb157b04a5a5bd5e9a5b6d625514c765fca25bc96f1fee62 +d49903f38b5c9b17542310425e59377f61f5b4f4740cd97371ee2116083f7758e69e7e2c1b0950ec6b76f96e3c91c721d6f2843afde8c7505a559c8a64bca2e665aa1131b75bdf86fb5b90581c7d3b61c2cff88f3fccf356ddf5ed282e27727be061b6925c51ea7f1a495f471dc8a5ca1a88bbe29e92338d3c9361460398965a 002082c6e61d0d72f040905d8c1c20d47b029f41ec68d6cbf43ce97c3b2a0a770557a33cb803c432cfbd3958fda30ec1bba77a6613c318597a85ad02b26c44bb77ca96d9cc1194ea 813c314d7dd910f4b2bb28392e5eae220aa7140e2fa1efa36139be090df648abbdb20dac8dfa18d8a60c3d95ee89eee5197df326f8167d8b5dc232f32eb19bbcbf551531899d7792213de4b4120c58dfa86752f15399d4935016f2792ca3b224 +0e3f4afc3e7b25c1bf2d98098a5a87db1224d9bb45adc6e434732b8722a708ab80a1f3f6ef3c5aa70d2e1dad3e4416b12cc59171f05736c4b58bd084602c344f2f0bf3cfdcfe04c64e87597a99de23ded64b33607f7c273ec321f6462518715b11e91361e89ce5415bfc2ef520bfec378244a3bd2a4b9b6b3d68815f2f75baf6 00e298c93351323e2c5304015a4878997ae4e79d1c32f1dc64262e534d4f2c4b3e222356ffce746763373fdfb936fd330d3214a18c07f1205b20c9a941331cd676040ba1fe3dbce7 8618fbbd2c66aae5f32d923276f9fccc6c89b46b0fffc6aa07f622d39ccd447a02d35e998b11555728ece96c2b0dd8080818bcd905d34ccedfc7db792d90ab198accbacfdf6210595c4a6826cec855d5ae59f40651a48ad5699b432183678842 +8fe32671f6927272fd3cd8dd4e34d44d27fac8c88b41bf9a48039e914990bf06d1633b38b9200ce1c2a275b9c55498e5da2d0707322c3ea0a0fd7aff598fb801628264e13047c8008153e8595a0dc95d54e70b882ac2ac9314d2b78e7b93922da818d7075215e354708994af66958954c92c074d132dbb2488e5a531c755a8e2 0104f4ad56594c5cec2a988c5596d73adaa5a81802b40110dbae698ddb1f0b271fd1479c38abcdb9b234e69cd0da8a0328d2135c287d5b130a09fa0b899058e7800eb2dfcee95c1a 87e4a9946ee006d0899ff075b51b318f7709f853227afeaf91430a7b6b0c7e59f9519422cee46c5d9b29da72c61bc8e018e708f4a5f959c5afd9b89338c1f6fe05f3c5041876bc27c1dc1253d76239d6a2d0e38d1ef5a1efcc65ea318ebecb83 +a8fa01136a0a78313a5d160c32fe5d1805eeb3730c18ca0c47818e82c48eb4c9e5b2dfe3ee5facef9ec59b68f4e6f3213f77fba9f8ba06dcde546ae348d343233883894f4423331b536f62373a495852977a51cb192cfbec04b5582b4ece69f345979e234de32da7a120138a057a7119735c4cb19099bf48bb202e7ffac04def 00c4989bf33b3136bcb4ba67906eaff2bcbc6567635aa4b057acb7353ee87ba3cb4cb9838f8f679729d5c6ed98e6c4199cf58605f009c6873a1b8321f83cd3c0973b7a3cfd9dbaa5 89b5762abdef11548fd9c5b327176da4053770f8f9e1bc1b574a3dd47b116d00a1f42d116b7badc763b68036da6da9d308353f801f97dde5c18c5dd33af322d9e7e4ad267727216f46d8a76256b1d52771133b474d400f2edf359c66887fccec +ba2d83b21c783d6ef2f3b7b10e910a418a9b9f49ae0fd37990335b3a3d15627846c9a12a1f31a3d0e062ad1bec5650606ed4dd06c30e50c1e8761a29f4ea1a20f74635d5dac22e5b787ac10f4ee82b338a641484f91771c128c84d31cdab0a6b9616078c898665655ee9dd4ae73d33b94bf091b064928b959623aa71ff73b4db 01a96f2ad56e31397e236cafc108087479c9823589a5fbc3dc7488d0e5d1199cf245d7f21f524cc0e8b47feca14c93fb760e631434a91188b32965053942f3bd39b3714f9d6f1a11 99f4e97e6aaef5bc6e1c45044524415bb2a098f93c8a6541e5f59735f39e70a9a8eab4c24bde3caed2c36f813dcc26fc010100f30edae0c7bea7270d77bf8cb981ef237a91cd479e23fd47cbe3f99563fdf8d2aec7cf2a623bbee3c48b4e3086 +ea2d5f4e9797bfc2f33f0fccaf530db2bdf8abcec00f09a0338eefdba318221ec0e050cad1a85c3f76b784c6e8c18da2b062f333eeff18b7b781e67d6d0a4368b8231a892e0f4103012348e5df53ac745e4d34e2cd1ee9369f97d4801ff485fc144b2007008036bbc07cb1c302a00054b54f3713919191e1d5052978c9c2895e 00c08ed8e0e0f8b0d0714b46a2164b933f8147692f18da97e5a108c44d5a5cf221cb50536e41832b83bff4026c6df156386235cf5e3e9a67b7cf9b2fa7707c5e0ff33a91601b8e34 8455935d7ac0b2c9714848d5d979251eb4b89bfc6e631fd755154cdfece7428d762db3f828f1149968b8921d2ea8531601c73a6252285072e2e294f21851a070eeb3b88fbc6f9d40514bf650d11e0db29fef63a7e927c067b96132557602a4f0 +b2293b0a09f41decd9d8e637b1b08c2efe612f33c9c0beebb6e05033c6103b958f8aacd125d7c810b4c287349f5f922d2c6ed554be597fb8b3ba0e5a8c385ed8ae70d5ae19685298f20e8d844fb5ad98db12ba7e5f45baed9045c3e86b3cac9bd55b614b82fd075954fc59bfc6124cbd68edae988596575f379d8921b594c75d 0144090a0ee38cfa21fabcc24d35139a99656911ad4f6dbffb77dbe74e7993edfa9fd63d2c4f6bbdbc8ec21ba13c9f4a3576b5d6e3abeab5af5ac81b1f2bb6d4c42dde645d854d9c ac9d92231713f2316358b814a86cc3658711492e04cae3dd1d41210fc0ea3504157bceaf940512b3791abc22e122877a096c88937db8e6f2072078e69d3005329455ebe999f1f59b7f5e0c7296e3f579f52777ff981143205af3f41b464818ff +acce54270252e7d9e983c08c993cd6b7e3caf482a9149036afe4665bd3d0662a6818047187872862d5718b8ac063477f693caf1a9baa8bdf2f36d411a796f2b46ab56f66bc94924229f8264016d6769c85d9bbb7d6bb042fefdb8fde1be026b86af2017aacfe38c97309b4689b23fff94f1de880064f1d3ad9d74dc804c41f41 01df26b672b2e3617b6b6c631d3c6be0cb49c0a690de49643e0f416215bcdaefc03fa9c708471f1d87476d58c8f147517ec8a14aa945ef001fa01984d5c3d81f7083ea500558fef4 a3026ff03c1c1803604f7667a30b39cf1b446a51584812a6d51b1254334464071e0d65ad86299265e06d72806cb7dc9c14c60260f3a6b5d1dc0ac10337874beb3d39be7a9952a42e6cba3a9299b8f037af09ed03e0106456e6af373e7d2f44d2 +e25274ded4840df0d71d3369007118f002b83e2d375c78f7e29ade067db15cce21842611f3f015db2efec57da77cb9d16eb1e00a8c1444d48dfda569e29fca1ebf40a22fc646a9fd44460f0e473bde487634bfbdac2c312f66a1c2982c6fe76c54ac72b6c8cc9345e47cb319a974b3cc4bb40634df74b4ad7e18adfa9a71ddd5 0189918b832e9fa30161fdd927bfc267f6405335df3d66d225e17173af52a671138883bcb94c4403ca3e001fcf09ef4c6488934d6775af2b1da30a8f331579af2d0fbb530298d8f9 a1de789427a48ebcaee4323635a90d0ff09e2b951f3618d1b0f702003a76c85bb27b8a4216e3c70603e67f4d65e4355610afd62d5d86d074a40cb90cf4b4555b60068da63c124b9df087ed6cb938cc2059927b6d4e247132a3ea0c251c2e94e5 +d8a4aed87c316012482819b03a1d91691f2ad11a2f46082497ea8f64880d686891f7da550b2ac17199c657d4eb9d04d5cb8eaa180f743b87d23b1c86103f9e9bb60f4e19f0ff9d160f180aed7735130c03adb62502e69be5c624ed7bda2301f30580ae0921b02e103a638f5623c02c186e3bfe6ff134c762a2bcac1f879a9353 00bdcc175eca3a399b944eb0334ff33c4fd130999c8ac0e7b52ac5b774fbad53ccc3a31024f5262b2eecfeb2104b14bb244307effe3dbe8ed25686dbf46a42c4b6f8e34010ad826a 93e8064f5428922c16ebb696ed9b293bf880403307a39ee58f1d7067f65513ee3cfa81c722c1234209340b277ca04a60164222d718e9497ebba5d1df60959b7419092c2640e06ea4b177c47a2efc2d46935caa574473608c3a2fb603ceee4973 +acbaa5ffc4eee0850075c0e502a70cc7a897a919f5e7bca4e798385601a26f411fdae5466ba9f6b6d8d7f819a749b799fbf4a3bda9105063e74914e8583ed8b31ea4d22164bee6f14bf53afca269b901c80cb3265be32ffd4ca4bc4ddb83e11eff82ead6d75dc4aec8e5c67f35d58a8a156cd1c0351abdccc0c5396c8fbe6920 0007ab5a55a1d8ecb7f5dca2afdf9ef465569a4b0374716f604ad42a6e0271e934b09655e8e2529784b69b2894bb399b02aeeae30e9e7ae70a2a8e56b9e775bd978a04c728e3951e ae1b3702a6c072acfaf21beaec22a55ee54715e042fb0110401b9e29353419d9036f41151ddb68edd8cdb9aa6fb91245092fc4b8c2920b72783568f54f388073d83eacf81c4ed0553663d27ec42fa1fc890872b6eb11554daa6e67e98f1421cc +9a57b63a4f418404e8f5dcf3052b9bc04a4f6d2c33bde8651506d9cbc5542ffb9023292dea463111fb78913ccdcd182faabbff9164219b8900c7f9fb394f7d9678f77b18f8d58526ec64d7c1328953b983a7c416583e05a069cd76aefe26e5f5687b70abfbf9f58f052dc0863b4fc3bef805cc3bb05bf76a83235af9d6adfe66 01e7d4da72b1d82e17a066fe387f2a0a7fa4c60ab993ee09710531789186077f2f32b42ddda497d5fb57356383e1f96973df043307f0b6519430c3f0d40d62954032872fceb7dce9 87d958c7d3ce3b1cdd667f7f5e96c082e1d57276346d607aff4246ebf77cf0d57b43c1e0188e2b459b907a104bdcb4371060195cc052a7abae78a3423ed2775b7cf4c7469297b29a1f575489f3e7028e94f67f809d51936e69bc4866e62d654e +97b79c76d9c637f51294369e0bb52c4189f2fd3bd0607f91834aa71b3555605a89ff68e84fb5bda603f502f620e14e8b0c7affefafa2f0b303009ee99653ae4550a05315e551dd12a4d8328279b8150d030b03c5650ed4f8d3ba7c3a5361f472f436b200b321e7863c771e20ddd7bdf739c51de3676f953a5501e4477aed1bd8 015b7271d4319db5743119c8103a7d4c6d57e9c62f3eb93762156d2ebd159980aa57cea948e416717d715a2e458851f1b2e9ad4172bbcc53861db29c3ee0ba8e82617a5866170847 ae44097d8e70bb3fd535dcc093d883c72df8ba8e8047038f9687ec09ca0988886e6c78c7f277e4a6985d41d7b7140f67159b6187c356e10aaf6c508040879b86f228bd99b86f3e7bd593d70493b00010203f24233fb2b74dc288aa1e8cfb0015 +564ad0e37c9c37a60872a4780a723d08d1159ddc77bd834d74c1025cdf3cbd5338c3fc07a904fcad9b979b2a2ceb1a0139af35e5112305fd662a57af6312624b9bdd3a64849f95f59a46ca8feb2ed56f87f258518947474c1729275c4d89b7dd286ed65f286cbac76002cc63b92a73ab6bd13c4adef282f32297e441bdd8fd36 007219ea7917d174a5386df985d0dca798ac9f8e215ab2f0003aee929a2dbd91e37fedead0ed95b1e8aabcf516bdf54337b4aff7ace4c6b3179f2e919a49db50a41c9d4d58d4f636 90862d48e2198ae35bdfe8c5ebda3072e77fc0b30c12c0f46266ace328c02c7b0b0d5c4205d8ea9d98ed1757abe70f040fc717ce912b0f36516cf123000fc9230dbd7de294e8d16c9a413b341a8c673313103521bf91d1c23fe39397bcb0bad0 +072ed5b14754fddaf54e20da42432df49bef38f4a3b1841b2db457ff86c44880727aca945770adb41269df41fc17f6a687bcaffaa45a3e59070526ed53b8dc3b78cf9a80a85461eaf4b477e44d5ec4c2bab9c05aa747a5a520b35fd09e8b44539d060ba1c3470267e0dda111b15dbb587614a46e1e477127f963a16cf3a43ee5 00bc623152253da24bf8d752bd78aedf7d5f6a2f889453ccdec14e10753335ea8bea83fd181a1f3680ed50f2324fbeaadae160cc85831750e021f3e44121ea1b1efc29a7d0069479 80c42eb5bb60d8d635dc3328899c167071ca26eb7afafa7661a4ca644ad57d9de5a385e870415c2a5d2e3b8c4e4d56af14f45f0dcc33aa3e9d5d23b91d7be110517ea69b3b930906735208d6cab96878dc6fb6b9ba804e485194787f001ef8a9 +e660dbdf3e61af39b83b95d3f1970f66d616f03273f7dddb98f768452b21cd39604a31cf80590d4a5e4b0d4917519e10fd325dd4ab7a52d70d154506329baefe0d5816f514ae109483122b4fa8fa1ebd7fdf1fc4e21e8d278a50c05d81c8f489596633d949c6c8fea96fe91430c01522a5afbd5042be8aa47da04581b2bd21cc 00645947d981d258f2954558c31022a3b6ba5fa7b675312f794cb61bfff1d9ce87267e4a1dacb7c8fc58624d31c85ebe22f80d26a620fed5df5bf38515e0903f0b69a606048197d8 b1d295ee366636df56ceecb17b6b072bb79b321b157701e7b55b00f469e8e612c1f3f16447f8f94941244748e1162d290ad528e1529092537beb1217aab18bec466d5307ad3398367e299aa3051d14dc949fc80f0c70c4f0be43ed333f6ba18c +8c9acbdc431565feae60e08bc7da113e12372ed373f1e1fdd581f98c8a7b0c79ac4aa42c7ffbc963fb4970fe26c5b5dd314b7051fe971c1186ebcb5650f7f7011a924de893f06961b8c75da7bff331847feead4abd2e8b9d6ecbedac18f4eac207b948e6e4215e4d5cb483e5c66ce7ad788cb89604d3a3e051539094079e7bdb 014cf93ca69d94ee8fbea0c8da9d76aea092b73073d8f5385b65c6dd4d567fe86bc2cfb8e8be890c3c6cd9abf7dc3a17eaecee3d7a9455887863e496c48dc3e47821bd3d825b6bed acce6dee3a4d9822139c329cd595b7afb4740e5f3e1a3e041725f05a17894ed1c86b1399fc39bbfa162b94293cb249e51593d83d507461ced53249626ccbc9eb500d8bf0e88811abb13d1e9ffb44d5b53859a82a89497de9d878857b639205cc +53ef87d6ac7b9698f40b3ea9f3442e7b64207b140b7f66f73fb7d5f8f98452d30a4e493b6c0e3268371e88e612b818d4d847f032ed4983817d020411a52d81fd2a17b58ebdec199d817c2a8ba77042bbd747a6fd4bcc7e844ea829fd8461b389aa0b5957d92962b6d4e86385a8fbca90b8fac40944607117e9a4ef6dccb8fc1e 0033feeaaaa28f16bfaf5ea9c7319cf4561ba4fc55327a8477b6cd58ef6ccad3962ee1f3edb243f3a04e7e49c8e23509fa2d63252adb186b8bc7e9255cd61fa9bc45242d42da3a68 a2b19416526ced2ab0a2da7b227303378b7f49038ea614b6b046024b001af4b1424f07df649d4826eea4ca4121a2777c0de1b3fd270a7645bf88f9788bf04d62977d7803daac51193bf9e8dee8161fbdd854028eb4d9343b4d3be878f35fe59e +dca1b7a9a313ead11c2d54739d9017ae27f9d08b3544e418aee862bb57e427636cb6aedda28e10f12aa15d2355f4f8ef112a86fec5dc46e6acef693cb8fc37c3e4885f3be3d3ab31ea4d73a0de904e95c7135a149f77b621d642f9bd8ba192d39cfc58b6f19a797c4f3b4f3a87054298e3ce5eda0ff7f44f8134c9a108285dfa 005613dfb53149bf5fdc4e08ccc1c752b0b66ab43aef2d008ed40f3df40fcbb2938d2c41e3ea2dd4428aeba9059a97efe5593119673866a19d27a2ee37dd357e22b6bc849e7e22cc 8a78d700e190e9abe8a3fc43504ce7f845a7a307b0fe72a8c84b0db689e8769f2c2ddd9f2d8fd41eb43c18d5d3c8b929137dec6055e93b9da58dcff955c1864da4c8b7d24861f36f95a8a13a92f942cb528a4384a38865c1bc66297c682025ff +aff61d62c8f5c31bbb7d0a64a6ac589e918bbf2f13e7ad13abb9ac26405e267249a7c9922139bc28140833e10976b87e91cf28285274b2b48b63d24ac94c85c70fafa78f8ad05955c0ce6c02b841ee196dab12306e3e3d6138371217e2b474f7e67a80bbb78a47e374ffe2c9f86292e471c551da50d46e7b5c8331029f369767 011b92c8b72b86c51903387a65aa206988d443d1988253329ad3a89c902ff1ef8cf73b7f2e4aaa352443bcb833712d94c3e637ec12cbe4c2d4606878576b17fae1512fc77785b737 929147fbf2b0a52f6a74a768d00adf44e40d6bf44b5c0303a21d77f81370b09f3907b7ba8383158d1fda4754686315270c54a77eeb5c991f3a892edb08649b046608303eb32017809868964e8033edf5051cddf3a498f13015e73f4f7a711331 +721017294f17ef351e41256b57a64a79f3636628c4bcbe676ac9a2d96076b913dc4b246c9945183ec9bd2d251441b5101eac44e2fa1bef59dec03ccd7fa5accf3b7d094d68dcf78c8de4e2f19f56bf0dcb3b66b9421ec3f8b353b9fd74feb2e9affe0bf9aa421b6f03eeba3ffd58fba56b3ebd094880e50de01ee62a108a24cf 00c3c90d5ce4375a08b85575faa78ee6bbd9e5571ce5a90582042617b807339c282cdc3b003d82006264b1c08c20af4ad4549fbde53d262facb98d923d81b8eb6093374b6a1e84cb a428ebdb4210dfc01c959d7c498a9016a7539d982b8ee99be0f75b5c9bb316ae2c06533498ab1d5fadc4315353c044bc107c849a5ac6c6338d5c4c76797de62e6d7fb741cb1bb381f4e60943663dc9aa11490a542246888ded49e0cfa0a66c09 +e2d1f33681759adb7954bb5248b0db3c3885fea0d4c1c0c226eb1e6d2d3ef1b9ac281a0f1c2fe5175b67114b6a501e2426d1454bd5790dcbc4c232cf06b017de8a9bb39e6033f1edb5003e8de3b44cc3d6150c3c952afb442952483cc688908337b7c1a8b5c9da70937ccfa98b2b0098c530ff848010b8e8ee0a8d65283481a8 010f184c16228d9034271332178ed485d10b6aa76003efc160d63fea26fbbdf5552205ac7df0d8c852a1210cf0ba512f20b798827b36ad56b12a826fa7dc1db45aed264ca6822659 b745a7bf3afa1499ff83b3276a0779c8c84585d8ad5227f71d4021432be341ffafdc070a993292b5d6fd0b9e4d354c280e3daad2f75abad506da281075f452bed5ff5c19953914f468b1d7c3787161f6293e0e724bb7b467962f230f24cffaa9 +414fc5d2bd56b30040e105cb891788792da595583b11b8fcc7320f40dbf64d9263532dc57344dd17573c95eedf851668b5d552e8796af205f3a0043af1a829fabc2e93d9af9091fdd9e0fcbcc9d6d9ec960aa60e4e2964c29a2f375400366480e513f63d124db7745847310e69a38c8455e4e602056a6a4a14a8694155e0a9bf 0181baf9d497159f837cba58a11ca435c442e5ca792ea559bff9f6a1f562c05bf6bb5914afbd1bcaea75b35f88bdd832314b249a5298622c89462344d3f28a44ba3d059df432fc71 90c7f5c82561155cfda44ad08fc4ba7538d863da9374096cabd0aff4998238af5e640a9b6d79a82f95bf281bf730e51512712e2f4fb2425484e42fa6188819a4dd88efdc1a538a37a57b773e005fb3356e7ebdb693414ecfb53133850dd75bc7 +3b592cc8972a4782870e079b82a50f84b4c2d8ca90bd500d1ce5678982e266c391c556d8162ac3aab967154d072dbc0ba1dab5545cf2651753dee2881eca5abd412fe624bf3f9d17d33692d21ce23ad15ccffdfd250cb1949e73c9e40a64ebebb03852e92692dad1d7baef97fe109f35b7a492b343d4b643a4a7b1723eaecb64 0083fae86ab96bce99a53e50b7eecff38e4e25b21c4b0f6a4986915de245eae24f16b6a00a4db159ebc27f5a6a072da94ab6be5bf75f5eb3f75c4452bf4ea7014392eb1e02706fb4 8e889409e284aaf6a4dac4b7a3e390637e8f1eabff1f6319da2ad2e7b990ed61f54c3cdcd1c46d1437ad8752468cb9690cc9b5dd451d552f6c6a9d38df8e0aca80346aa3c2801545a2e2d52c564ced08543ff904607c8a0a706c7ac77e470dda +0079a02cbab3dc02601fcb5c8607d555beef7cd71a66911ab6514a4ae21c5a9c0e166f8cf5fb198ec5a49a96e17cf041f35f00406b79270ebfe56dc6b8417d2529fd625686ffbc8f69685aefa2fd30a937c02f25b48be4679e6fde821de928b33b12470867def874bb8c7c8038ab6594346a2c44b39210d3610994ba60a05e06 01a663efa7bf4d8479bc535fad71e9b5e4f4281aec55967baa008ba17ac2f89cc3398d30573edef29d590fddce8cb157f655e92779f59e7a18d0327d02e7daf4c1216143b3688fed b61d21624dce86a46e112937128b3826959e40900488eeaf3668b4e1531fab46d5080cc656c914d0461cdc568b17802716f0c32eec4f61fabc90a3791b0c00fa096d7b14b40c4fbd6535a10573ed157650f9dad26d0c1237b2dddc0cccc4b7d4 +88573bd94ef50459814806efa868ebf92b066fbc2f7a4be9d2fa06b9dc1a72f72d783a6bcbc107b18a6314511bff217037a2252e7a5cd34cf9d5b2fe9c7846931f0133b2e95876cb800dc4ed7c4a4e4cc4f1195acf99fb0ec224b1f8fa8af71f72d390eca9d6be3879032a318734a63fec336c79035a43f70271def10c4955d3 00088d1a2c0219696a94337cd56516252b74139ea0733b17fdcbf7692c3e5f6c3989e5da2aaed7468e65a5d578571928ca273ec3b6aa72cd196f560f05095cdc8346e5d31c4c2e0c a3e7d82425900804bb92e2263af2aad3af05f0e2e0e508358b8bc9cb7098df5431b6c3b06631eeb91464c2da9bab937c09bb823397b3b4ae22fb054ac2f2905d6bba9d51e0b46b55bf4a13e7cedcfdb84be8047f348120d8b4e21fb12f72285e +d0e02045ece6e338cc8ab41d4a064c982ccb1748c48fc2fe0a6f10bdc876094358a6a90a45facec798a83cc95c6795cf0f0d7c66b77e22cb114c1432bfdaa1485ff35b6a58107cac3b7e58cb4f6c87c68db60b751e78f1fdfa54b8923b98caad0a4f31226956d065c083ace5f1e9e91944dcca51879d782e40358d58ca758750 016cc8a0fd59455ed8d4de561fd518df2e008f7dfaa5f7f29ac2489a411e233917b43eb3ebe2596fc824be58871949545e667dbcf240dfb5e0c615ade0179d9ea2a1b1ebb8ab9384 940d99c296f20dc71708db3774c04f1fd6fcb6912e5878c203f24d642a64370698aa66e14477bed19fac0ab13458c4ca0ed5eeff6aa34365ff170e5730a7d831f1079ed8f2c7c9c0083375d9b94c0558ba837aaff79ba493246b37a7ab60acfb diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P224 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P224 new file mode 100644 index 000000000000..44a690435aa2 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P224 @@ -0,0 +1,60 @@ +699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615 b619dd09796f426e8413930f99bb98cab43221719e2c6130fd2d941d86e2ac623990d20431fb9c327ed2817c4652d5560e2091bf219ebedb49ac463bfa0599c9f23906bbfafe4e2bbdee9168692bf55b29c5847ec313fbaf4f8705f38df6f6b5 +7de42b44db0aa8bfdcdac9add227e8f0cc7ad1d94693beb5e1d325e5f3f85b3bd033fc25e9469a89733a65d1fa641f7e67d668e7c71d736233c4cba20eb83c368c506affe77946b5e2ec693798aecd7ff943cd8fab90affddf5ad5b8d1af332e6c5fe4a2df16837700b2781e08821d4fbdd8373517f5b19f9e63b89cfeeeef6f cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5 b8a2661e1600b2d8d3dff2338dbe34b97c8d4dd999ac70d7ce4e8924c8e9bc6f5213ed1fb2e501f50737744c8678e15d05e1f2aaec89c02fa1872c3907918b9044a78901ac372af8ba4f4126e1ce482e7d54ffad4a2965b88ae99759cd0d0051 +af0da3adab82784909e2b3dadcecba21eced3c60d7572023dea171044d9a10e8ba67d31b04904541b87fff32a10ccc6580869055fec6216a00320a28899859a6b61faba58a0bc10c2ba07ea16f214c3ddcc9fc5622ad1253b63fe7e95227ae3c9caa9962cffc8b1c4e8260036469d25ab0c8e3643a820b8b3a4d8d43e4b728f9 dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73 8c8e4ab74fb222976b5b0a1665c5345719b1aafd9b1ffbf66174629bdd72a59deff7f88f01874357aad89738ad782fa50218e25d626139fef44648ed12fd39cbdec8b0933fc005fffa842e0f933fd84770c01b84ac2987943d069fbb9769e26e +cfa56ae89727df6b7266f69d6636bf738f9e4f15f49c42a0123edac4b3743f32ea52389f919ceb90575c4184897773b2f2fc5b3fcb354880f15c93383215d3c2551fcc1b4180a1ac0f69c969bbc306acd115ce3976eff518540f43ad4076dbb5fbad9ce9b3234f1148b8f5e059192ff480fc4bcbd00d25f4d9f5ed4ba5693b6c aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e 8c222b81662dd1b51d2e84994fe03e26b28d82d1b08876228267379413da00a7addc1f01e0c6ab18808c1fa98c592e9c1769349f6e6c483a2773d9a36fc00c550de5ad755cd2ac6e58124c4b5fdeb7faf2b73146410425a7e3827a855dfc4ffc +c223c8009018321b987a615c3414d2bb15954933569ca989de32d6bf11107bc47a330ab6d88d9b50d106cf5777d1b736b14bc48deda1bc573a9a7dd42cd061860645306dce7a5ba8c60f135a6a21999421ce8c4670fe7287a7e9ea3aa1e0fa82721f33e6e823957fe86e2283c89ef92b13cd0333c4bb70865ae1919bf538ea34 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4 ac3abc68757f0d31412bfd6758c0b431bf9f30ed6d87c4fcadc28719f68805a7af6e10106329bd3ba77fa843ca4580e80d50f490947cefbb0be88b0b0bfa16cc1c09909a257a8aa29379ef29333e2e3dbe520a5c3a332790c2bbfc8021497006 +1c27273d95182c74c100d85b5c08f4b26874c2abc87f127f304aedbf52ef6540eba16dd664ae1e9e30ea1e66ff9cc9ab5a80b5bcbd19dde88a29ff10b50a6abd73388e8071306c68d0c9f6caa26b7e68de29312be959b9f4a5481f5a2ad2070a396ed3de21096541cf58c4a13308e08867565bf2df9d649357a83cdcf18d2cd9 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131 a0994eb56e58d9b8f28a0f8888e3d241504aa3ae2993b2171b7e1c074a690466c79fcf543f5422d31b6daf95adc9f0690c494c639fa1524f520cdfe8662069fce3dfe77de5244162901cd4c936b42cf3348058ab0c627b13bb0f2f6436cfa70a +069ae374971627f6b8503f3aa63ab52bcf4f3fcae65b98cdbbf917a5b08a10dc760056714db279806a8d43485320e6fee0f1e0562e077ee270ace8d3c478d79bcdff9cf8b92fdea68421d4a276f8e62ae379387ae06b60af9eb3c40bd7a768aeffccdc8a08bc78ca2eca18061058043a0e441209c5c594842838a4d9d778a053 d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974 82a10c23edf40ee5e27f53e9d4caef1977805e587b9f8f6e30a74013b3dc8f577daac5e3683a54670b54186a320c2008188e5a903a2c6be964f6ea04f77eaab8aa231e7813c6a4daf4f15686c2bb1189dedca3026efe44402da715528b84e9f9 +d0d5ae3e33600aa21c1606caec449eee678c87cb593594be1fbb048cc7cfd076e5cc7132ebe290c4c014e7a517a0d5972759acfa1438d9d2e5d236d19ac92136f6252b7e5bea7588dcba6522b6b18128f003ecab5cb4908832fb5a375cf820f8f0e9ee870653a73dc2282f2d45622a2f0e85cba05c567baf1b9862b79a4b244e 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8 a70ebadd587baec7ff4f4b555350a94ae4e9451ea996c7430dfd61d1a2030543482b7fdbcc512bdb515890134c34c03808beef5c0aaeaefb9822e7016b716319166debec25993cedb0511dbd77bb1c74dda1e7124e6ecd452b94c56d08a02913 +79b7375ae7a4f2e4adad8765d14c1540cd9979db38076c157c1837c760ca6febbb18fd42152335929b735e1a08041bd38d315cd4c6b7dd2729de8752f531f07fe4ddc4f1899debc0311eef0019170b58e08895b439ddf09fbf0aeb1e2fd35c2ef7ae402308c3637733802601dd218fb14c22f57870835b10818369d57d318405 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2 915825b15124ef8824786481c9ab45b0c67e772dfb1e9f7b1058be62a4d902e3c84f8da584ff4d0ba709c20fe830cdbf043a5d19d6d739a0b8212607cd68c65a0b06895d6fb8b3f93e4587be56d1d8624e54f43589c0fbf083a714f5b9010824 +8c7de96e6880d5b6efc19646b9d3d56490775cb3faab342e64db2e388c4bd9e94c4e69a63ccdb7e007a19711e69c06f106b71c983a6d97c4589045666c6ab5ea7b5b6d096ddf6fd35b819f1506a3c37ddd40929504f9f079c8d83820fc8493f97b2298aebe48fdb4ff472b29018fc2b1163a22bfbb1de413e8645e871291a9f6 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7 97f00455c903c817be6f383fa465397be13d22f18909bd56cfb2f4272d02ba46c426e3126bb6575db0170162f99644f40a6e769f55e843df070019c0d3d52a46537657ec55c72312a49c311e52ebe9e72697454b77b0bd76ae1b6a4e57f27dea +c89766374c5a5ccef5823e7a9b54af835ac56afbbb517bd77bfecf3fea876bd0cc9ea486e3d685cfe3fb05f25d9c67992cd7863c80a55c7a263249eb3996c4698ad7381131bf3700b7b24d7ca281a100cf2b750e7f0f933e662a08d9f9e47d779fb03754bd20931262ff381a2fe7d1dc94f4a0520de73fa72020494d3133ecf7 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b 8d74ab1e1f8ef9fd4053b3625a1d23005aea05281d05822ce6b5d1a5980545f2d0ca7ed9c81ab39e7b87b6322b85b8170e83d0283bd8a1e1a666918bfd1f661809a05451934e69757cf2d4cf7d8c14635cdd8be98c0c2ef9ee75033864593c67 +30f0e3b502eec5646929d48fd46aa73991d82079c7bd50a38b38ec0bd84167c8cf5ba39bec26999e70208af9b445046cd9d20c82b7629ca1e51bdd00daddbc35f9eb036a15ac57898642d9db09479a38cc80a2e41e380c8a766b2d623de2de798e1eabc02234b89b85d60154460c3bf12764f3fbf17fcccc82df516a2fbe4ecf c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6 adaf8d0208d86808de6e6972fe87f01c5474c9dc1d1a42a0356e50f82211b4db21dcf54c04cbca3d61556234a0f06f4102fafc6fad10ad343571ef4370f2f91ce4c40806ca5e58bd23d21bb8ee991a9628a4c9a0b2f67abe0c4268b653771849 +6bbb4bf987c8e5069e47c1a541b48b8a3e6d14bfd9ac6dfaa7503b64ab5e1a55f63e91cf5c3e703ac27ad88756dd7fb2d73b909fc15302d0592b974d47e72e60ed339a40b34d39a49b69ea4a5d26ce86f3ca00a70f1cd416a6a5722e8f39d1f0e966981803d6f46dac34e4c7640204cd0d9f1e53fc3acf30096cd00fa80b3ae9 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc aedbc23bbe3bdcb1c141284cfd23ddccae4181865a9c258e23bda5920ba06910cc03044b2c6431ea46eda559b553aa3709217d2ff43398e27c337d255ae9cab9616ba5d4c36b73583fc6347652aafd3171a1af6bad6e54dd6cb90e455257ff37 +05b8f8e56214d4217323f2066f974f638f0b83689fc4ed1201848230efdc1fbca8f70359cecc921050141d3b02c2f17aa306fc2ce5fc06e7d0f4be162fcd985a0b687b4ba09b681cb52ffe890bf5bb4a104cb2e770c04df433013605eb8c72a09902f4246d6c22b8c191ef1b0bece10d5ce2744fc7345307dd1b41b6eff0ca89 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3 b2ebdc0b7845e7b5c92b23821788d32cb871568f6d115a8e16aa863153099d7ab9b400999cbc788be023cd8973871ddc169cc09384a3c8b031c9236eff89b3594ea90b44fdd21f246d93b85f382b306b0281760fda216397ffdfb9f7b9fbe499 +e5c979f0832242b143077bce6ef146a53bb4c53abfc033473c59f3c4095a68b7a504b609f2ab163b5f88f374f0f3bff8762278b1f1c37323b9ed448e3de33e6443796a9ecaa466aa75175375418186c352018a57ce874e44ae72401d5c0f401b5a51804724c10653fded9066e8994d36a137fdeb9364601daeef09fd174dde4a 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912 a5c37769fb86a4963758a98e4a13d3bf0364e12fa003cfc4f4eb08c2b1aea4fe300f35960def407903ac12bf7717c3dd1568eae7a06cfc497e6880b71a98f7b5a9961c000c94336a73f2f2e1014d56aef3a0af4a86caf91e15fbf73ab7e67d3c +2b49de971bb0f705a3fb5914eb7638d72884a6c3550667dbfdf301adf26bde02f387fd426a31be6c9ff8bfe8690c8113c88576427f1466508458349fc86036afcfb66448b947707e791e71f558b2bf4e7e7507773aaf4e9af51eda95cbce0a0f752b216f8a54a045d47801ff410ee411a1b66a516f278327df2462fb5619470e 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa 928b8041a787ac73c115fb54f54ded615e3795fda50bfec4467866a1b8ef0424b7178bed4b8fa60c0b99daafa8837dd812b7712eae06308c5a6af2917df98edac016634d71164f926c33660ac559b448ba60e09194d982a02dd5c524c511ea14 +1fa7201d96ad4d190415f2656d1387fa886afc38e5cd18b8c60da367acf32c627d2c9ea19ef3f030e559fc2a21695cdbb65ddf6ba36a70af0d3fa292a32de31da6acc6108ab2be8bd37843338f0c37c2d62648d3d49013edeb9e179dadf78bf885f95e712fcdfcc8a172e47c09ab159f3a00ed7b930f628c3c48257e92fc7407 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972 b5e8172cf3cd5c27292b1adf1920ed781778f170472583770f6d1ede376c24e372d6aa03ce1bffdff2069885333f32c80a48c745694121962a35471800b78ccaf12e30e94dceffe4fded3da46782ff78a067aeb9f70945fe9bb952209ab130e3 +74715fe10748a5b98b138f390f7ca9629c584c5d6ad268fc455c8de2e800b73fa1ea9aaee85de58baa2ce9ce68d822fc31842c6b153baef3a12bf6b4541f74af65430ae931a64c8b4950ad1c76b31aea8c229b3623390e233c112586aa5907bbe419841f54f0a7d6d19c003b91dc84bbb59b14ec477a1e9d194c137e21c75bbb f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170 a2f3eebd7c0e51d3ef59a4351ff00bf63df21a38db463b6442f3715b79cc9e3a14def74e335b19ca52e81dce21bfc2110ef6121bf0443b7994bb53961e625c261e902dbf5174f13c1ecf7b55fb6e55b7b2ab7345fd9c11359e6002323c22602a +d10131982dd1a1d839aba383cd72855bf41061c0cb04dfa1acad3181f240341d744ca6002b52f25fb3c63f16d050c4a4ef2c0ebf5f16ce987558f4b9d4a5ad3c6b81b617de00e04ba32282d8bf223bfedbb325b741dfdc8f56fa85c65d42f05f6a1330d8cc6664ad32050dd7b9e3993f4d6c91e5e12cbd9e82196e009ad22560 c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85 820c6927521f5b61116445c6d0e9464abb4f2522e6a40de4285395edfa843a68f717a1f7924623f3ee958ef7a94525b81658420adec58b66f424baa14871836f6388a001884d552854e55b976d8b637b5ae62e5088f372ffd84dcc9ffb2e542c +ef9dbd90ded96ad627a0a987ab90537a3e7acc1fdfa991088e9d999fd726e3ce1e1bd89a7df08d8c2bf51085254c89dc67bc21e8a1a93f33a38c18c0ce3880e958ac3e3dbe8aec49f981821c4ac6812dd29fab3a9ebe7fbd799fb50f12021b48d1d9abca8842547b3b99befa612cc8b4ca5f9412e0352e72ab1344a0ac2913db 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6 ae443d0e0a79ab13b3baf8ca00155d38b3fb0a2a58192aefbe2203b3b62a866c06efe76398041a79227a2301af50adb416e3755407177b5f77f55ae13cd80196881a5a7deb95ed0e5d517849b88bf2f966961e99dd314163cd85b78e7867478a +4cc91f744ac858d3577e48813219aa3538dd813b186b42d1e6218376f07cc1cc448ddd6b37240e98bf953f49cf54d65c12878b33c0bf6eb1c60254f0b6fa974f847e53abc56773eef6f29885dfc619e6a48fc15a667ca94001a0c945b6357a53221b0f4b266181456b0d2d25e90708777f1a6f85971c00140c631c1991e0fd06 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39 a82f4a95d84a54a2d2d211b02933246714525307324a425b31d6316842f02c16c3b5ba4a2d5700d4b36883eeb69771730a2f2c78ff30bfb299c308b902e8fd3b182942cd19687d0281724b2eb064c8518e6624f2e674557a2a03c58da8ba54be +58f43cc1924de4bc5867664adbc9d26b4f096a43aca47c27c52851b006dc2a658919ef9ce5b5ac48372703be15ac51631c2bd84b88f479f113b0569a9a09e230ec1e8e573474c6075284d3e57d973829af35325d9e7dab4a5f9b065155bbcaff3642a82ef4c9b9e127d3575c050721653da3b087d3fa394192897a5519527d19 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6 93f63e5e5b9f6ca80bb5e001579f687c43356fd4ddb5e022b6a0b8a2cd74c7b1914c0e8695378c7b4bcf9465d7f8d3d91345d93179ba9594ee27a1d5f3b17070a6da2481c986c04e5af8d24fb388ca922d95f63933122f271cd6d0df04a3d20e +113a2806b052fde683ee09453098e402204155afb3776fd1cad3a9103421d327eab8f9ec0dd050ffcc83f93b34ea707705fabeccfe43ab1a71c95298fd3ec769d99ead1066950eee677d225816e0faad19cf69e1b35d16771689e2092cafe16d7c0dd7b0db73fffb8d0f3eaed83004dd21e753530ec939c89ba25578fa5f785b 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b ac4ceeb2dfb1603683d316cd062d54ee9edea1ae6d8add666c1661be07bfd577ed0faca93ec10a6675f1b121dd8226ad0ede2ad8a169f6fdd62d6b754a97412a090be644202cfdef888133e5a6e13548044b8a52cf42320f260bc49ca4c81559 +64cbfc8f2e2149a31b3e8a80c4a552f6c62aaeb7990b6e0ee55500a9d17be04213406578caf315951086dff5c2af3b5ce17d425d185101ef26f86396ba3a129a4f3f8e2dd595f59efb6c0f5c2dcc394569d7268695e9ac7daa84203f1f1895f1f9e4b514a5c9cd23baa63454710144fe735ad9b8f42d8c43267aa434a26d7e5f 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b 8e11074e5749e53ba60590b27fd95edfb7585c1f345bcebd6fb94a695b57dd123fd7ba0531a4da9da3bfe95868d22feb19a177a660d1c5bcd82254f575ee2d54ac6338e471ee9d441247c896143dba9f700d596cad255a75ecb402f89fb78590 +a10a11c8e30fff118d371daf824f16c08200b83ea059436466a4611ccac93b2dea2de8c1006f946196aef7fe9b0c251a391b0340f21797798278b412ff2b53842eec6450728e2bca062f8337a2c204b9ea04ff660cd4d4db559f2f11c4d8ef199021339fcc82396f7a93926cf5f247e37d8067fe50692de54f102bd5ab51925c 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8 b5f11aa3c84b0478e833a220fbfccc29c58a10f105cbb2645600035a20125e13ab7e8a3bbe71e06de79086cbbaafebd40f49e0a940401d5c4402f1e202284767fbaaf2bacc6ec1c7ade1008daf742ca08b740050036ac908d6b5a2f22b2e6f31 +b3f720bf566ffa369259f4361959ae0641d2755ec264a4c4349981df2b02563275b2b9adb5aee47f7a456760a971991ffed6b17809bb9694138d1677fa916123795239353158fc6b22d10f20d26f5d2dcd8c56c44373eea5b93067dba2d7c5318dac2e9e8714873cb1b37f58c011fd14fa1e535554efe05f468bfc8e11cd8b99 e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784 910778fbdc923e83bb93b70bc1be310597140d4948a899f841897bfa73fe20dc2dc3962b34fd3b9462732a78ac5e0bff0c0ac5c06632aaf314fd5cabc5006a0e61c4f2631d81e04570826c7bd3b8596af36ca2729cbb086496112e8a28ba126f +0a398a46df7ccc48d1e7833f8bbc67100f1ef77a62dc78bbc115b2a662f9591fbaaa91ad3d788e2fdd1b3164e45293d4f5686c151296901768028ac80ded4bf89c647ad35f0c7c4cb318c0c757c1d83c44d850e5fd4677281b3f13b1ee54de79c8c042813f9d3312dcc6111a68299cb7e829557d7f3d96e702f65aefc6499415 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c 95a9767b66d33d54015a6db76520eb3b506d6aad7a1b4a781601fda12cf8e2bc7957447d855c2f167e318d6f4bb1e55015957a415267ea9073c5e125fe76bd3030309d73ce5ef9dbd661ea60a70ade1c53274483bbbc30ae5068278ab0225167 +8c33616821a6038b448d8918668977fcf1ef5aa0cf7c341837b39bbcc9bca875a3757f4b392630e9995b9bbe4eb66978b877586adaa02f99d2344dae082a7603351d8ffcfca081ab403cd0acb90d078dd1d0789c2eb3185c62bff2d9f04cd38e509e3b83c12ed0a5c6808fc42f7ba5b06acdc496c8ad9be648ee6a4505f8560f 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583 84d90ec55c553c98a6723e6878a65d4a52cec21024385f38f9e89f6071779a96b8016a7fb7657a96151d13e19ff4a8aa11ea6fc083cb9f42242f15b42a1cfa374883fd46cc19ef662e3ca07c0f4a64271daea0efd25cdf0b5095135028822375 +94d56535fd4edfe67a0daa6579f9d53bf6b7b8830ae2aeb62892ff59f18756ddf2811b449c7d20d65d54f8507de4e7c50eaa084830637812aa4b250a4d61ab67845be36e4a41cdc0a70f8d6e3a63d4514f0dc197e6486015046a316153d5f3a3a4a0ae1ed7ea5fa55e12e73d333333685c02e0eb636234ea7e6d4b76b4b76b5a 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2 82b085f4e886aea26ab2a065828e42e655e6fcafb2e211d0ae9833a1abb6a3ec5a90a6f089b05cb4d6ed9d91db9c54fe1221d8e1da5eff78a8d6f27d9e2cdf1a87fdd7b7373be1199b4fff302b71fcda32bd5262345133aeebd8a85ca2e3f5c8 +5d8ebdf9eb28b47bdafaa36bf0b66a9eaf99b6c83959da4f2b1151b4f4ecd28fb115a64c0cb9491093a7e9b9c53ec423e4c72e7765bb9c818da0e8c428667e44474a71db4867130c77c40bfd8544b2d7b9d6464d2b8e6a48482153256a32437c3a747231f51134dd14c703407e31146a6fcde23bededcf16950486e90ca69ac0 f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc a5a1344ee0638b70a3916a67331f2e131edb89310edad44e26d5a27f0905e05b92a8faef5dd646db7a4920f96b4a4c940faa17c2e6552a42ffcbccaf77970545401ba7c8ce0c97cac9aa1db47b88e580e814176d5e18608de752e4f75955ebdd +25e4416695f77551fdce276355528ccf1ddc2483821c5d22d751d50111ca2fadc6593b52c74f4b5957494f1df25b0b2f86950d0d19229ec6506fee8581d2dd09d48418b146ff16bd84a17ca0dc83b1888eb407376da6c8a88fa1e60b8c2a2471dfde4b3996ef673d5bde3d70c434dc9f2488e9de16ae657d29e5e59ec922a1ec 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd b4cfb87515929e1d91a43d623c1b4da12d194fddeff9e81a90d4b92a98f893aba78159b2092c3e98013b218cae557a7613a31643bf822e6ea02cf7b0094e38f6f8339f71389ab4ab6be664a829208da028f51708dbbba31b12be27165e234415 +9164d633a553deccf3cbd2effccf1387fa3177cd28c95d94a7d1a3e159c5e5c027758cc26493301b2f4d141d8d07a5fe5fead987ce5f30abeafcb48c302afc6c2309f0e93d9b6818cbb6972d222cb7b01302dfe202ae83b89f53150ae4a0e2b8fc0fd1091f19b4ab2e6ab213ab322d04f2c5f57113bfad3c5675227237abf773 e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3 821661d157e68e98cb0115f2a005bb0149e38048a3e8c86af18843a491f079aa8972e2ad4a0ad034ef48bb38a50496f00ae8509e3794dc53c6cd5047a6a7a7b4b70f68dd931c4f0e10c2ce57458bd06b537ba841b831d7108f5de8637d9d6679 +019df05929321ecea7ee1de4f412aba1c8d3c24437db04b194a68a0a59dd871be10bd3a4be6edf551350ea49fc7155a4d887e1221486291abe77a30633a4c4f7868fe2df24311cba0c73804883954460e122387ed414111ff96ff1aebac8b6a6491d8a0d16e48a63bf3d027c0f68ee4a4b234d73b412196706af8ea022b4dcef b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17 a9afde7a91afbef56aca3df2bfe95bb6c0a698232c9fddd9275f3daa234981daf6fa894f9d272f4b3d1ae785c7638a5e04060c888270246c7b4362149cc6384c201111a934f6f551d1370caef407651842740dfb3fb3daa1865b617271d45235 +5d09d2b1d3fa6e12c10d8b26dc9aabc8dc02bd06e63ff33f8bb91ede4b8694592a69e4ed4cdf6820069e2b9c7803658949e877ffe23bf90bcf5ce1409c06c71d86885a94048b05ac0ec9db193e489a5a2bfa367caf6aa8ecdb032be366174343f6875d2fe1785e8d77334f5f469cec64998e08d3303e5c9a1923b34fdc105d65 efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085 910605ebf6db4a6166f802f3b4c4484b10888b15e1d2f81c4f80d53cb38fbe41a827493bbc77c59e4dabdc0909b9756e0f028484693cca58dbbe1da9d40a57630d36bed39ba1b84d2c195b4fcad2fa9c07d9324488ac5f85bfe4736a6ab2bb91 +50f6dfc81c6cf189e0a310f992907fe93356cee9dea9a41c7671a8daf3f4cfe0c459ce6122c1e731dbf7593419d7114cb73b46956158a982c5d52c72f43f0f822046093c69aeff1f7e4cd8af00ba655c5baa2e7b6a400b4be1f6fd51b3e4cfb35a69c80a28c5cafb771b6c2e52e0aeef0e3fd045e8d40745f3f8b74fd969f816 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd 852b363b8e017789b4b078382ee4f724b367d22b22622208446c2594cad5bfaddfb3884da87f12ded0f0fd5b6ce067e20f4117538bfe53c1b9f062eddcdb14ed3fc8624a8e36fd15afa5b194e3f3ff2a805acf117c4a048b2d980ee7bfb3ecd2 +e90129ac6672c85bb7b6b18e9dc199c96c81fd65034b53c77818364d512366fb9cd1bc7c82404c451e561fc1ed916c0948f6ac561b33a1ccca093f07684b8c2bafa9e966377bd208556018a5bafb9edcecf70498c7140fe9c8cf3ad8b8c3b0aa489df797944465047465415bb0e24333235fcdd59a98829a3941eaaf62033e82 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d 97e119cb6545dcbf983b5eb7b54a9f5f6cce2caf4ac45f1293fa72424cf7777110263eccf5260dae4e4d7eca715770ad1345b7eb7a07c911c17bb22db2fcf73a110a41dbdf12154d169c7f47629882c75fcf86164cb9cf0dd2ea4b1b7524c7cb +3c9a483c9bee33b601549c592a82e95b4319b1e74b777877f0971bcb4273716b268e8f99f876e42f942f4cf08284896bbc1ffbf094ac0956c3cedfc3580cffa8c74fc6db29a371f2da2d05edb9185ece741fe0d3fabfe9d5b4d373755ebed13dc6840cfa3283b9ea46ec8b95c434f253ae86998182e9cc0e95ee64f323fc74b0 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0 93173d67ceadb5f1b56890eca3ae88040a77ce76da7651ceed1a0c347b95908bd3d9c97e072a482682c4139ce30637650feef49b0c9d9bbbc80e66bfbd363fb9744de5eebc07c47f0d22e544701d59153036d019e8a7068a88062f25b9fd29b0 +bfc073fdda63c5fccaa0ca8770c293e8154e7aec56128bbac4fdbd541d602216ebf7ca1e02b514d6e396f20683802ba3f334310a9226576926e3bb19ceee27738d13377cbafeb09d091043501702a07aa31d1f29d50ddc55adcf16ffd40578e734a4e6cb6535f26ad48e0c62ad90e79720000e87d419e92dca3e11f943655b03 e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d b3b52ec511ce43937cbc0ee6f2c316fcdd48d234fd5d3cd69d7bb691df88103ec31fafc378d6c24763f7a9ca5e53603a0881612452870bb523536933283093760b7e00dbc59fa976041163c0c69278a33038c4eaed4d0f68f1e66bba8ac0ce0e +08079955d1a1f33728128c73673ec9f21a6ce138dcab5adc4dc068e6ab57314b9fbd8b013123b2fdafa9524fbdd0288777a233de8055cccfad83046ada6a19f01c47817496667bba8fc8b9456fc0e044a562d931dab1adcb66af8b66325bdf28d83ded3e2937958ccd19da540d70ef2c189f55a506c9c0d63406394c5bd3823b f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7 8f18e66a6986eb3549fb5022f5431f1c08826c53d055931666834cbc174959c7a670ce546bb2375a423065bdb486489616d28b57007d238d7f8d2a5a326838194f6d8de8e6cf362f37854c05b7c7b9fed5c3dc547af5a77723fb1efe33c0cce4 +23900b768f6cd42b8a8df0dcbc9cb5daec8de36b9d5c619adcc1ba2b649103d5af123746cdf19c3fd0665a6fb9338156182aa06181e3c6e37ce56979612af2927440424f89cef43fc754854b8a5c43370808cf5f9929cf47712512ce2f8a2a20d2e9f568c2848b27dfbe09142843c83905ffa5da3b15501761b03dbc2c5398b6 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c a1998202456c1f111bc9cb86da0dcc4357cbfda5180d9f90739ce8b874ed7ac2835529eccd64aff747060e52257acde91158b3f33d65a4eec57883e5bd8a981e9b6546c8930b341a355a42233bfb20331509b12c9e3d734231ad2385ee0a7043 +1eb28c0bcdd18f73e347f957ece15b4cc83a771b0877e1feaac38e24028fb38ccea8b54ee017dc7c3d5a1327bc6f40b294aa65d7dc487f278846cd101ee84202f14b38aa2c275046aa2577f65ebaea41cd383e8def2fd0b4444dcf426fa75c4082cd7fa035cdb1e0d34a3c79d42130f5b0273eae75bc701dda3aebe7358f41b5 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18 a0041f24bf5c96f7940fd3392c07194c7e8c5bb0b8793e6cf6dddc9c5af435e97911fe62504f2ffc3d6d746aa13e116a03de53c469f399a0701eaab935d29835022ddcda987ba4c15f609147e528498dafa24b7e9401272bdd06b19d234e12bd +efab51855407438fd5c250670366bca3c026ecec4a59394f00d8a4b51746d0c4564366656d507e3e13e62fe7abeb976b8859895848dbaecf6582f1898ea06f00d4247702ed9721bd375aa83ae4c67c2eaa6e080777ea5ecf2cf787d785389560ac91cf63a52f0373c3185e18a3b8a466e21b61a239f1b77624eb1acacc76c4e1 bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a 8356988e890ac983a35861ac110a3258030b8b68b90d824f4fae618d07562978e97e60dc64ec6271d18d4357a07878800503ea30059e57a15d8c75002c0e4b7455f9637962ce57a5fd29673ee1af4f321c834ec04156e936c6b836e751b7eaf8 +31c29ca10279a417f0cc9b1382cf54dbfdfc89f2e6ef08c403c11f580cbf8674b141ed1a417563282d99a55fc616d836421cde9424815c95e7fb7668bf3f137b29937f14882d74e034b732d78d91af7721aac4950734f5fa5d4b4d35534974f8cab6d2e6dca75ddb57e99148c8a59df9fc5bcd723e546e8356f671cf2f65640a dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738 adecf04faa3d11b740c899814d1079018c9bd3de5837a442fb47201c76a337d2c89ccac8cd6ad23d1ba2992fef49166d0bcb8a580709138afb10d2c7b5c7c64a4a7a7f88646f2f25e82f6707f8e421ada6375a1260c9d9f1a329e55059347c32 +8db476f92e332519c1a0ece5d8deded6efbd2d8e8784eea0a6b4c3b4296c35f5f8de4317e5c1627b91fb1973fee86c06e4992aa5a20cb7475c8808ff1da354d07a488dffa7838c6ec1e3f99e3acba831f27bee8434eeda3eb36d0c6df3658883cd40068b1bed841310f6eb38d4a3d07d85848770ff7933c054cd8b34662660b1 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01 852daa7e63a1c68bde16e58b09b402e10c05d3fdd80f9729e7af4516834e79f7c4ae6f1fcfb92b3ba8895c3abbf137461047690022bc3a14e40a1e1d200bdddaed296edec67d9bb60766a2299822fe3955f09b7427156a2c0f61ebc0ef494e6f +fcb272c828fe8fd3c6f8de9410c7b6e2b36717c1b0e5e359e9109bd7fc378978aa98182a9d99961898ed88999b050d3b64d1457d7a899d6d273b9f4dde2aafa36d76329d62509043c338f265fc4c7d938459b7fa3b230a9f6cb632b61489546bb4181a5ad7f0d7369b8caced48eb374b075b2b325bc86add0f3b680cd9e80acd 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28 881c4d5e866413f813dd31ef74d4ef60e116f2412ba226aa0424294f67537eab2fc995790df4a9919aef7bdfb8616a69161d18b08eaee87222082113858116f0a96b88f068ce61a1fe8b160ffecf901a0097a5d18bf3caea088583c2f09e401c +7522492bdb916a597b8121f3e5c273b1d2800ef8c1db4f7dcbae633b60d7da5193ba53a63d7a377b351897c3b24903ae1cd1994211b259be3e6ae2cbc8970e4957fdf782c7d1bc7a91c80c8ef65468d4ef35428f26e2940ae8b0bd9b8074236bf6c00d0ebe83f9ddb2ade0f835138d39f33b59f244e0037c171f1ba7045a96f5 ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6 98fb9d3fd9a6105d4088d4b03a80007630177a6cfeb7a1f407d7cd5cc3ae5e9207c8640158c92935bd3675307449b18018eedf71c9b8ef975ae303ce0723e2e895ee985d744ceb37d7246666634b5b32aef1e3eb844f77b9dfdfc063f9f89954 +61097114ff855c3e34a62d9b853f8982d35f29cfa4a89893badbca7849e5fb437a1a38d6451bf0ca5a0d528e352b8e4b57f2ea359a7fc8841d49dd3e570f9b016f14156b0bbc4be822e260bd147ec081454969e11cb0034b7450ef4deb7ed6edb977e2f4ed60121aa095fb0ab40240dc329ecc917f5c64b4410612af065ee9dd 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc b3a7b323d4e91725b23545ce643856360f5b5d2e9739150079bd8454435131dc7623133579234db02b04dac3cd4bd9ca16a6074be692183455ed099fe45fba26bd9ff5f70122cc42f87befb858c8540938bb09d6f99237d59a98586a513d23ba +dd09ae6c982bb1440ca175a87766fefeacc49393ff797c446200662744f37a6e30c5d33ba70cbd8f12277fd6cc0704c17478bbab2a3047469e9618e3c340a9c8caaff5ce7c8a4d90ecae6a9b84b813419dec14460298e7521c9b7fdb7a2089328005bd51d57f92a1bcbeecd34aa40482b549e006bbf6c4ce66d34a22dda4e0e0 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b 863cc58c84a9407f815374ee6918d80ca3bd59c812de3c81a83f82c77e6118c5b25b0c9864b8273108a87fed506e0d9b03601f696e39e8cb958d3aca4d5ae1b1bd62c60f9a1303ba81e05d9f1a865ca4ed4d79a6e2dcb8f4180e5f575eba3625 +37a73e2774d3b274db426c89b945696daa96035031f72cea01894b24508c7f81961ec254d36ed6a0f448e11cf7950af769dc6cd2c47e52c6caf0ea92c270974f0214b4db436c36a60fb722060a6bb544462a82e1714f5906ec32886f7d59ebf289541c3a00ec1e004892ef2b1286a0194f55d083c6ec92c64b8fd1452e1c68ba afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc 854aa28e56c0506feee2333d6021018b908e2f3325fd22c84d79c10d1e64ad8a422e716fb21093bd5005063851b572e507644295c851ff2df31b9e4be6256d10819fb087ec1feded7081eb6543547d390652c05c0a1f84a811e8319aabab408e +9dc2046ffdc6804544db964481abe5d2d276a2a9eeec4c7ad40215b1de23561d402db69bd0f6eec2254711eea4487c64d9a6b62c3ebaf5ffa8db6e7e3a6e17154d126967a47a853a6f8339bdca9be306a13c7f992ded7619b0da59909a49b1e0930360e05b47f18628a36d69b2f87f2bfddd6a5d4a72f84dc76dbdd43f3a6a35 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c 902f2690b94bc5f87c7c76fb7b6993fa522f5fa75997541b1cd26caaafd0b8ebbbd561e367413e77d5d06d0f52b66d540654543b0d31af875f0acdf9fd4157a2b4679aa7b9c21cde9bbe29215428adb4ecc8aedb8a98b0697c3ebcf9fa7d5b11 +d9c6847fce688c5e7525a1098b545cb6c15dcd21a02761fc82fc664372a667390680135f91c01a2fa5430c634b1a6d1cd6002d8aa021e7bf5956a7901c2f81bc25d502ba5f55a55f30c0323dc68205cbefec0538e68654e7b327ac1743641896c3e740d8f66f400902b304eafaa4e0d8cffae140536f0922444cc3216a675697 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc a9151742fe15a9d1f372e6ffeecd617cd9ed740222fd446ce798cc389891e231cb0364150882141b0fdfc01535c2a335107b392fdc841f867231090e7d25ef0e0d13b88c6cfb6ba77a652f0e44f2729630a56a06a2c4e6b3c91dc7f0f74eb7dc +69df8a01b66f04930efd2012ff2243874f256ca8758145d2a9e4ecc84d0dbdbd0dc494ae06db0ccbe819918137c90957114558580d6623efbafdd342b38dad9f08708084d32f874fba04782ce26aaab78de2102ad171f8a8f2b30b5bd3d55fdac5fa3acd6f7def7e61c2533938572b331ba6d1c02bd74bfdbf7337ade8f4a190 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4 82df4d8a4676942620a4f02e235d4d25ceb98d73cc9a9698d812a798381fa5bc92e42f5bac73f55d0c570f844e16b6b4192e6b549846d467698dffd90abf674e78b9049d6a4a134b563dcf16f0c354254334f064b296113ab3bdf2b469c0f227 +927524982b8d60777c1105c86fac05f634abf58c73f84fb95d81ba0b86e1e43592c4fcad2e395a40fbe7005697d86088e2fb3bb7287eb3f917d4f2dc281f5cbe65d05b4f9623bca849b10a03beca6aa2056a12ebb91cf257ac448c5e9a78f8349a6a29b17c8978bef43a443cbb8a149eb23f794844fc41693f2dbb97181444be a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916 a4919cf6627cc94c19c65a298ccabc79efccc86afc3c99aea4d99010ca6f41d63d095aa5f20513cd883138c331c0f1f81939c6664373e6732b6d25d46434ed27a7d2d5a14288e935c740508dfbe075f40e8c39c36befe5cc5972fec1c035e44f +5f9042283561e7f19a436d01c7ef5a950a6d77ede5629cd7e43c0a5d58e8c5673c37945a453291d12938253c71dbe12c8b022ba7276eda6be034ef5ec1ec77dbd1e08f0d7b8e7725b7ec671c075e008a20f77f4ab266f97079b0aa6337df59a33b881954084057b21f294dd14bcb0869a4a6f1f597955ec7bf9d19bb3537a66a fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b 81b5a7e9f823bc374b8057f5f63695512d13e92c3bc38081283a7f13cd054da62081c4d18919d3f538977ecd113354730a483d91255866e500f56c67a884e2bb49d561330dfa81059e1f4bdfeaf7f39be4c3c25bdd783ac7960fcde0f054f0e3 +c2ae5573d3bf396523bfb703db8502fd0760cd1be528f6ddbfb95aad399e0b19f3bd9e0fabdb05d49e3f893dffec5b627c9c2f7ad5f32e92e4e27a38cb5c28657657377fdfa1b66cd7ac3d15c6d49df92d284db99f69744f37dc7cb4e7d52920fdb200a7942623a7057ba82e467dcccaa5da416b48510d8364446a6a5e2a5aa8 a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea a959fa8d1d032a4d9e37daeb4f5f0e67f0e478490a4e2ee865577ea89bb9f213b33e86871058b44978ce456c15de443209a15291a8442ceb10e2dcdc335f6b133d326958afcdd59b1add2d08d6f73208fa74d3352a37133b130459a0e9c1ccff +03c1a1cd30a039d0dcb22fee2450a7fa79495a0d0f4f43d2de4d75bce003c0334a8860f5c164dbd94888a9f751235a3e570d31070e3e1293a7be616af7176600585d36ac013600157d2569d491da4b8a3bf3630c26e0b9925412189f50b0ae6f04c86477932e2ecd8c3546106ae1ebc684cc3adb27ed665eddece886adea4ce3 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0 a42a7e21327e57856e682f7a1fa5897fb337a5742bc9ce8bbbb583335fe1592369dcf10fe50ee895e5f7a3d06a8d6dcd13a69946613e37d0891cff37b7a617cc7b9bb2ed7dd3a314b39f93927e8fd0bf83816462da52140fe402b8b88cbd93b9 +888f6d9bc7c86c0079fbfd42d8c08d6958f40f6e570fb0b1f03d2f8f8a63df4fcc87b379a222cf835820a999d34996e08961f13b86b075e7fd1c303cd3baa44de42168561589012f7e5300da4f8bdf470c07119a5d9f7ba7293568cd7c6a1b7fc1e41cda40bed7d46e5a28af67ae2aabfefe67a86a1c601e6f5ee543e09bd7b6 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294 acb347ef27c2576627b0595478fd1d3090a8b5e6bf08c588b2a0ac46b78a20f63b1b3e0c119c9190951aa96a5e9f3cbd0657d942f428a74b4d18c5def681e687e1b6d79512a116df420795b5b74e5f37abfcfbfb025e65f627edc760e44fbc4f +48453340f1317769e6ee6e103153714365731163dc18f84e9f2fa4b120f9c5a9645ee2f9b66c84c26d95912b422b009b64af96aa418b2427a4209f2e7513ba8e43ec8cf20b34e7529b22eb1199545afe9a9f7d9bcb320aec9ee0162f91c0d1dd9674c9c284f25199c5e109f6f84d7ed0d269cc6413edb81bc2c83e37d644d8b9 b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a aab5ed6ced23d6abb3a0e6bb6b487a42073bde9d2c7271b85c681305568db944e9a0c5d01740e861e53ba17b66a718890e384b522547ad9ae1177af717c6636934ec726cacd26110af96d50fe0905ab86b30677bb6fc12b2d2ea5cb58c5789b6 +4bdfd3b91d83108409ad765b256e0c9b9937ecf647f8e6f9fc807e2e72af8246178b3fe046b4ea10170450d71a4eec790ecb05f03d7077341de26c4db7eeae24d55c9a9093e837dfdb38168fe8230cb9605825a1282fecd741989bfcdb34678fe077477927f66bd26d003e5dda22043341a14dd31841ba483ad5ce2701e0f68e 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4 8a91d3171a91a60d5c77ca9544c8c3d57ffdcbe3ae24d6439b2617cbced8abbc5dc765942efeabedef199aaf991447fb1635d58358a2c3452f5888af4b463c25a6d31a6e0b965aeaf45acd96fc43140f7414a663aa8924bedff4840e3e81249d +e6cdee8558bc1eacc24e82f0624ce8d02cc8d925b4dd3dec3a72f4a4e0fb76076bfa3ef2e2c33bdd7c27b322bdc09bbfee8fe46f75dbd7bbd2af09690b7137943efe21706e0a1b6d3089540fc58d85ddb55ea836616db573e36c521be008893f40a0a7c349602cc178ea43be59d31ec6449e7ff2c5379379f7d7645134df1bc3 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04 b65870087fe6e3351856e7c031325e1e5a6c1db366d041620a4f6ad10cdd615b3f52a138caa1d41c5f3a8b6ddc30146f0d16ac6a108a7411df419bd40038903011a023b4b79fcd149a9768906532533159a63774bcedb2b394fb88902caceb1f diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P224_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P224_blst new file mode 100644 index 000000000000..44a690435aa2 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P224_blst @@ -0,0 +1,60 @@ +699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615 b619dd09796f426e8413930f99bb98cab43221719e2c6130fd2d941d86e2ac623990d20431fb9c327ed2817c4652d5560e2091bf219ebedb49ac463bfa0599c9f23906bbfafe4e2bbdee9168692bf55b29c5847ec313fbaf4f8705f38df6f6b5 +7de42b44db0aa8bfdcdac9add227e8f0cc7ad1d94693beb5e1d325e5f3f85b3bd033fc25e9469a89733a65d1fa641f7e67d668e7c71d736233c4cba20eb83c368c506affe77946b5e2ec693798aecd7ff943cd8fab90affddf5ad5b8d1af332e6c5fe4a2df16837700b2781e08821d4fbdd8373517f5b19f9e63b89cfeeeef6f cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5 b8a2661e1600b2d8d3dff2338dbe34b97c8d4dd999ac70d7ce4e8924c8e9bc6f5213ed1fb2e501f50737744c8678e15d05e1f2aaec89c02fa1872c3907918b9044a78901ac372af8ba4f4126e1ce482e7d54ffad4a2965b88ae99759cd0d0051 +af0da3adab82784909e2b3dadcecba21eced3c60d7572023dea171044d9a10e8ba67d31b04904541b87fff32a10ccc6580869055fec6216a00320a28899859a6b61faba58a0bc10c2ba07ea16f214c3ddcc9fc5622ad1253b63fe7e95227ae3c9caa9962cffc8b1c4e8260036469d25ab0c8e3643a820b8b3a4d8d43e4b728f9 dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73 8c8e4ab74fb222976b5b0a1665c5345719b1aafd9b1ffbf66174629bdd72a59deff7f88f01874357aad89738ad782fa50218e25d626139fef44648ed12fd39cbdec8b0933fc005fffa842e0f933fd84770c01b84ac2987943d069fbb9769e26e +cfa56ae89727df6b7266f69d6636bf738f9e4f15f49c42a0123edac4b3743f32ea52389f919ceb90575c4184897773b2f2fc5b3fcb354880f15c93383215d3c2551fcc1b4180a1ac0f69c969bbc306acd115ce3976eff518540f43ad4076dbb5fbad9ce9b3234f1148b8f5e059192ff480fc4bcbd00d25f4d9f5ed4ba5693b6c aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e 8c222b81662dd1b51d2e84994fe03e26b28d82d1b08876228267379413da00a7addc1f01e0c6ab18808c1fa98c592e9c1769349f6e6c483a2773d9a36fc00c550de5ad755cd2ac6e58124c4b5fdeb7faf2b73146410425a7e3827a855dfc4ffc +c223c8009018321b987a615c3414d2bb15954933569ca989de32d6bf11107bc47a330ab6d88d9b50d106cf5777d1b736b14bc48deda1bc573a9a7dd42cd061860645306dce7a5ba8c60f135a6a21999421ce8c4670fe7287a7e9ea3aa1e0fa82721f33e6e823957fe86e2283c89ef92b13cd0333c4bb70865ae1919bf538ea34 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4 ac3abc68757f0d31412bfd6758c0b431bf9f30ed6d87c4fcadc28719f68805a7af6e10106329bd3ba77fa843ca4580e80d50f490947cefbb0be88b0b0bfa16cc1c09909a257a8aa29379ef29333e2e3dbe520a5c3a332790c2bbfc8021497006 +1c27273d95182c74c100d85b5c08f4b26874c2abc87f127f304aedbf52ef6540eba16dd664ae1e9e30ea1e66ff9cc9ab5a80b5bcbd19dde88a29ff10b50a6abd73388e8071306c68d0c9f6caa26b7e68de29312be959b9f4a5481f5a2ad2070a396ed3de21096541cf58c4a13308e08867565bf2df9d649357a83cdcf18d2cd9 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131 a0994eb56e58d9b8f28a0f8888e3d241504aa3ae2993b2171b7e1c074a690466c79fcf543f5422d31b6daf95adc9f0690c494c639fa1524f520cdfe8662069fce3dfe77de5244162901cd4c936b42cf3348058ab0c627b13bb0f2f6436cfa70a +069ae374971627f6b8503f3aa63ab52bcf4f3fcae65b98cdbbf917a5b08a10dc760056714db279806a8d43485320e6fee0f1e0562e077ee270ace8d3c478d79bcdff9cf8b92fdea68421d4a276f8e62ae379387ae06b60af9eb3c40bd7a768aeffccdc8a08bc78ca2eca18061058043a0e441209c5c594842838a4d9d778a053 d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974 82a10c23edf40ee5e27f53e9d4caef1977805e587b9f8f6e30a74013b3dc8f577daac5e3683a54670b54186a320c2008188e5a903a2c6be964f6ea04f77eaab8aa231e7813c6a4daf4f15686c2bb1189dedca3026efe44402da715528b84e9f9 +d0d5ae3e33600aa21c1606caec449eee678c87cb593594be1fbb048cc7cfd076e5cc7132ebe290c4c014e7a517a0d5972759acfa1438d9d2e5d236d19ac92136f6252b7e5bea7588dcba6522b6b18128f003ecab5cb4908832fb5a375cf820f8f0e9ee870653a73dc2282f2d45622a2f0e85cba05c567baf1b9862b79a4b244e 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8 a70ebadd587baec7ff4f4b555350a94ae4e9451ea996c7430dfd61d1a2030543482b7fdbcc512bdb515890134c34c03808beef5c0aaeaefb9822e7016b716319166debec25993cedb0511dbd77bb1c74dda1e7124e6ecd452b94c56d08a02913 +79b7375ae7a4f2e4adad8765d14c1540cd9979db38076c157c1837c760ca6febbb18fd42152335929b735e1a08041bd38d315cd4c6b7dd2729de8752f531f07fe4ddc4f1899debc0311eef0019170b58e08895b439ddf09fbf0aeb1e2fd35c2ef7ae402308c3637733802601dd218fb14c22f57870835b10818369d57d318405 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2 915825b15124ef8824786481c9ab45b0c67e772dfb1e9f7b1058be62a4d902e3c84f8da584ff4d0ba709c20fe830cdbf043a5d19d6d739a0b8212607cd68c65a0b06895d6fb8b3f93e4587be56d1d8624e54f43589c0fbf083a714f5b9010824 +8c7de96e6880d5b6efc19646b9d3d56490775cb3faab342e64db2e388c4bd9e94c4e69a63ccdb7e007a19711e69c06f106b71c983a6d97c4589045666c6ab5ea7b5b6d096ddf6fd35b819f1506a3c37ddd40929504f9f079c8d83820fc8493f97b2298aebe48fdb4ff472b29018fc2b1163a22bfbb1de413e8645e871291a9f6 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7 97f00455c903c817be6f383fa465397be13d22f18909bd56cfb2f4272d02ba46c426e3126bb6575db0170162f99644f40a6e769f55e843df070019c0d3d52a46537657ec55c72312a49c311e52ebe9e72697454b77b0bd76ae1b6a4e57f27dea +c89766374c5a5ccef5823e7a9b54af835ac56afbbb517bd77bfecf3fea876bd0cc9ea486e3d685cfe3fb05f25d9c67992cd7863c80a55c7a263249eb3996c4698ad7381131bf3700b7b24d7ca281a100cf2b750e7f0f933e662a08d9f9e47d779fb03754bd20931262ff381a2fe7d1dc94f4a0520de73fa72020494d3133ecf7 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b 8d74ab1e1f8ef9fd4053b3625a1d23005aea05281d05822ce6b5d1a5980545f2d0ca7ed9c81ab39e7b87b6322b85b8170e83d0283bd8a1e1a666918bfd1f661809a05451934e69757cf2d4cf7d8c14635cdd8be98c0c2ef9ee75033864593c67 +30f0e3b502eec5646929d48fd46aa73991d82079c7bd50a38b38ec0bd84167c8cf5ba39bec26999e70208af9b445046cd9d20c82b7629ca1e51bdd00daddbc35f9eb036a15ac57898642d9db09479a38cc80a2e41e380c8a766b2d623de2de798e1eabc02234b89b85d60154460c3bf12764f3fbf17fcccc82df516a2fbe4ecf c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6 adaf8d0208d86808de6e6972fe87f01c5474c9dc1d1a42a0356e50f82211b4db21dcf54c04cbca3d61556234a0f06f4102fafc6fad10ad343571ef4370f2f91ce4c40806ca5e58bd23d21bb8ee991a9628a4c9a0b2f67abe0c4268b653771849 +6bbb4bf987c8e5069e47c1a541b48b8a3e6d14bfd9ac6dfaa7503b64ab5e1a55f63e91cf5c3e703ac27ad88756dd7fb2d73b909fc15302d0592b974d47e72e60ed339a40b34d39a49b69ea4a5d26ce86f3ca00a70f1cd416a6a5722e8f39d1f0e966981803d6f46dac34e4c7640204cd0d9f1e53fc3acf30096cd00fa80b3ae9 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc aedbc23bbe3bdcb1c141284cfd23ddccae4181865a9c258e23bda5920ba06910cc03044b2c6431ea46eda559b553aa3709217d2ff43398e27c337d255ae9cab9616ba5d4c36b73583fc6347652aafd3171a1af6bad6e54dd6cb90e455257ff37 +05b8f8e56214d4217323f2066f974f638f0b83689fc4ed1201848230efdc1fbca8f70359cecc921050141d3b02c2f17aa306fc2ce5fc06e7d0f4be162fcd985a0b687b4ba09b681cb52ffe890bf5bb4a104cb2e770c04df433013605eb8c72a09902f4246d6c22b8c191ef1b0bece10d5ce2744fc7345307dd1b41b6eff0ca89 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3 b2ebdc0b7845e7b5c92b23821788d32cb871568f6d115a8e16aa863153099d7ab9b400999cbc788be023cd8973871ddc169cc09384a3c8b031c9236eff89b3594ea90b44fdd21f246d93b85f382b306b0281760fda216397ffdfb9f7b9fbe499 +e5c979f0832242b143077bce6ef146a53bb4c53abfc033473c59f3c4095a68b7a504b609f2ab163b5f88f374f0f3bff8762278b1f1c37323b9ed448e3de33e6443796a9ecaa466aa75175375418186c352018a57ce874e44ae72401d5c0f401b5a51804724c10653fded9066e8994d36a137fdeb9364601daeef09fd174dde4a 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912 a5c37769fb86a4963758a98e4a13d3bf0364e12fa003cfc4f4eb08c2b1aea4fe300f35960def407903ac12bf7717c3dd1568eae7a06cfc497e6880b71a98f7b5a9961c000c94336a73f2f2e1014d56aef3a0af4a86caf91e15fbf73ab7e67d3c +2b49de971bb0f705a3fb5914eb7638d72884a6c3550667dbfdf301adf26bde02f387fd426a31be6c9ff8bfe8690c8113c88576427f1466508458349fc86036afcfb66448b947707e791e71f558b2bf4e7e7507773aaf4e9af51eda95cbce0a0f752b216f8a54a045d47801ff410ee411a1b66a516f278327df2462fb5619470e 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa 928b8041a787ac73c115fb54f54ded615e3795fda50bfec4467866a1b8ef0424b7178bed4b8fa60c0b99daafa8837dd812b7712eae06308c5a6af2917df98edac016634d71164f926c33660ac559b448ba60e09194d982a02dd5c524c511ea14 +1fa7201d96ad4d190415f2656d1387fa886afc38e5cd18b8c60da367acf32c627d2c9ea19ef3f030e559fc2a21695cdbb65ddf6ba36a70af0d3fa292a32de31da6acc6108ab2be8bd37843338f0c37c2d62648d3d49013edeb9e179dadf78bf885f95e712fcdfcc8a172e47c09ab159f3a00ed7b930f628c3c48257e92fc7407 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972 b5e8172cf3cd5c27292b1adf1920ed781778f170472583770f6d1ede376c24e372d6aa03ce1bffdff2069885333f32c80a48c745694121962a35471800b78ccaf12e30e94dceffe4fded3da46782ff78a067aeb9f70945fe9bb952209ab130e3 +74715fe10748a5b98b138f390f7ca9629c584c5d6ad268fc455c8de2e800b73fa1ea9aaee85de58baa2ce9ce68d822fc31842c6b153baef3a12bf6b4541f74af65430ae931a64c8b4950ad1c76b31aea8c229b3623390e233c112586aa5907bbe419841f54f0a7d6d19c003b91dc84bbb59b14ec477a1e9d194c137e21c75bbb f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170 a2f3eebd7c0e51d3ef59a4351ff00bf63df21a38db463b6442f3715b79cc9e3a14def74e335b19ca52e81dce21bfc2110ef6121bf0443b7994bb53961e625c261e902dbf5174f13c1ecf7b55fb6e55b7b2ab7345fd9c11359e6002323c22602a +d10131982dd1a1d839aba383cd72855bf41061c0cb04dfa1acad3181f240341d744ca6002b52f25fb3c63f16d050c4a4ef2c0ebf5f16ce987558f4b9d4a5ad3c6b81b617de00e04ba32282d8bf223bfedbb325b741dfdc8f56fa85c65d42f05f6a1330d8cc6664ad32050dd7b9e3993f4d6c91e5e12cbd9e82196e009ad22560 c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85 820c6927521f5b61116445c6d0e9464abb4f2522e6a40de4285395edfa843a68f717a1f7924623f3ee958ef7a94525b81658420adec58b66f424baa14871836f6388a001884d552854e55b976d8b637b5ae62e5088f372ffd84dcc9ffb2e542c +ef9dbd90ded96ad627a0a987ab90537a3e7acc1fdfa991088e9d999fd726e3ce1e1bd89a7df08d8c2bf51085254c89dc67bc21e8a1a93f33a38c18c0ce3880e958ac3e3dbe8aec49f981821c4ac6812dd29fab3a9ebe7fbd799fb50f12021b48d1d9abca8842547b3b99befa612cc8b4ca5f9412e0352e72ab1344a0ac2913db 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6 ae443d0e0a79ab13b3baf8ca00155d38b3fb0a2a58192aefbe2203b3b62a866c06efe76398041a79227a2301af50adb416e3755407177b5f77f55ae13cd80196881a5a7deb95ed0e5d517849b88bf2f966961e99dd314163cd85b78e7867478a +4cc91f744ac858d3577e48813219aa3538dd813b186b42d1e6218376f07cc1cc448ddd6b37240e98bf953f49cf54d65c12878b33c0bf6eb1c60254f0b6fa974f847e53abc56773eef6f29885dfc619e6a48fc15a667ca94001a0c945b6357a53221b0f4b266181456b0d2d25e90708777f1a6f85971c00140c631c1991e0fd06 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39 a82f4a95d84a54a2d2d211b02933246714525307324a425b31d6316842f02c16c3b5ba4a2d5700d4b36883eeb69771730a2f2c78ff30bfb299c308b902e8fd3b182942cd19687d0281724b2eb064c8518e6624f2e674557a2a03c58da8ba54be +58f43cc1924de4bc5867664adbc9d26b4f096a43aca47c27c52851b006dc2a658919ef9ce5b5ac48372703be15ac51631c2bd84b88f479f113b0569a9a09e230ec1e8e573474c6075284d3e57d973829af35325d9e7dab4a5f9b065155bbcaff3642a82ef4c9b9e127d3575c050721653da3b087d3fa394192897a5519527d19 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6 93f63e5e5b9f6ca80bb5e001579f687c43356fd4ddb5e022b6a0b8a2cd74c7b1914c0e8695378c7b4bcf9465d7f8d3d91345d93179ba9594ee27a1d5f3b17070a6da2481c986c04e5af8d24fb388ca922d95f63933122f271cd6d0df04a3d20e +113a2806b052fde683ee09453098e402204155afb3776fd1cad3a9103421d327eab8f9ec0dd050ffcc83f93b34ea707705fabeccfe43ab1a71c95298fd3ec769d99ead1066950eee677d225816e0faad19cf69e1b35d16771689e2092cafe16d7c0dd7b0db73fffb8d0f3eaed83004dd21e753530ec939c89ba25578fa5f785b 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b ac4ceeb2dfb1603683d316cd062d54ee9edea1ae6d8add666c1661be07bfd577ed0faca93ec10a6675f1b121dd8226ad0ede2ad8a169f6fdd62d6b754a97412a090be644202cfdef888133e5a6e13548044b8a52cf42320f260bc49ca4c81559 +64cbfc8f2e2149a31b3e8a80c4a552f6c62aaeb7990b6e0ee55500a9d17be04213406578caf315951086dff5c2af3b5ce17d425d185101ef26f86396ba3a129a4f3f8e2dd595f59efb6c0f5c2dcc394569d7268695e9ac7daa84203f1f1895f1f9e4b514a5c9cd23baa63454710144fe735ad9b8f42d8c43267aa434a26d7e5f 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b 8e11074e5749e53ba60590b27fd95edfb7585c1f345bcebd6fb94a695b57dd123fd7ba0531a4da9da3bfe95868d22feb19a177a660d1c5bcd82254f575ee2d54ac6338e471ee9d441247c896143dba9f700d596cad255a75ecb402f89fb78590 +a10a11c8e30fff118d371daf824f16c08200b83ea059436466a4611ccac93b2dea2de8c1006f946196aef7fe9b0c251a391b0340f21797798278b412ff2b53842eec6450728e2bca062f8337a2c204b9ea04ff660cd4d4db559f2f11c4d8ef199021339fcc82396f7a93926cf5f247e37d8067fe50692de54f102bd5ab51925c 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8 b5f11aa3c84b0478e833a220fbfccc29c58a10f105cbb2645600035a20125e13ab7e8a3bbe71e06de79086cbbaafebd40f49e0a940401d5c4402f1e202284767fbaaf2bacc6ec1c7ade1008daf742ca08b740050036ac908d6b5a2f22b2e6f31 +b3f720bf566ffa369259f4361959ae0641d2755ec264a4c4349981df2b02563275b2b9adb5aee47f7a456760a971991ffed6b17809bb9694138d1677fa916123795239353158fc6b22d10f20d26f5d2dcd8c56c44373eea5b93067dba2d7c5318dac2e9e8714873cb1b37f58c011fd14fa1e535554efe05f468bfc8e11cd8b99 e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784 910778fbdc923e83bb93b70bc1be310597140d4948a899f841897bfa73fe20dc2dc3962b34fd3b9462732a78ac5e0bff0c0ac5c06632aaf314fd5cabc5006a0e61c4f2631d81e04570826c7bd3b8596af36ca2729cbb086496112e8a28ba126f +0a398a46df7ccc48d1e7833f8bbc67100f1ef77a62dc78bbc115b2a662f9591fbaaa91ad3d788e2fdd1b3164e45293d4f5686c151296901768028ac80ded4bf89c647ad35f0c7c4cb318c0c757c1d83c44d850e5fd4677281b3f13b1ee54de79c8c042813f9d3312dcc6111a68299cb7e829557d7f3d96e702f65aefc6499415 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c 95a9767b66d33d54015a6db76520eb3b506d6aad7a1b4a781601fda12cf8e2bc7957447d855c2f167e318d6f4bb1e55015957a415267ea9073c5e125fe76bd3030309d73ce5ef9dbd661ea60a70ade1c53274483bbbc30ae5068278ab0225167 +8c33616821a6038b448d8918668977fcf1ef5aa0cf7c341837b39bbcc9bca875a3757f4b392630e9995b9bbe4eb66978b877586adaa02f99d2344dae082a7603351d8ffcfca081ab403cd0acb90d078dd1d0789c2eb3185c62bff2d9f04cd38e509e3b83c12ed0a5c6808fc42f7ba5b06acdc496c8ad9be648ee6a4505f8560f 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583 84d90ec55c553c98a6723e6878a65d4a52cec21024385f38f9e89f6071779a96b8016a7fb7657a96151d13e19ff4a8aa11ea6fc083cb9f42242f15b42a1cfa374883fd46cc19ef662e3ca07c0f4a64271daea0efd25cdf0b5095135028822375 +94d56535fd4edfe67a0daa6579f9d53bf6b7b8830ae2aeb62892ff59f18756ddf2811b449c7d20d65d54f8507de4e7c50eaa084830637812aa4b250a4d61ab67845be36e4a41cdc0a70f8d6e3a63d4514f0dc197e6486015046a316153d5f3a3a4a0ae1ed7ea5fa55e12e73d333333685c02e0eb636234ea7e6d4b76b4b76b5a 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2 82b085f4e886aea26ab2a065828e42e655e6fcafb2e211d0ae9833a1abb6a3ec5a90a6f089b05cb4d6ed9d91db9c54fe1221d8e1da5eff78a8d6f27d9e2cdf1a87fdd7b7373be1199b4fff302b71fcda32bd5262345133aeebd8a85ca2e3f5c8 +5d8ebdf9eb28b47bdafaa36bf0b66a9eaf99b6c83959da4f2b1151b4f4ecd28fb115a64c0cb9491093a7e9b9c53ec423e4c72e7765bb9c818da0e8c428667e44474a71db4867130c77c40bfd8544b2d7b9d6464d2b8e6a48482153256a32437c3a747231f51134dd14c703407e31146a6fcde23bededcf16950486e90ca69ac0 f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc a5a1344ee0638b70a3916a67331f2e131edb89310edad44e26d5a27f0905e05b92a8faef5dd646db7a4920f96b4a4c940faa17c2e6552a42ffcbccaf77970545401ba7c8ce0c97cac9aa1db47b88e580e814176d5e18608de752e4f75955ebdd +25e4416695f77551fdce276355528ccf1ddc2483821c5d22d751d50111ca2fadc6593b52c74f4b5957494f1df25b0b2f86950d0d19229ec6506fee8581d2dd09d48418b146ff16bd84a17ca0dc83b1888eb407376da6c8a88fa1e60b8c2a2471dfde4b3996ef673d5bde3d70c434dc9f2488e9de16ae657d29e5e59ec922a1ec 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd b4cfb87515929e1d91a43d623c1b4da12d194fddeff9e81a90d4b92a98f893aba78159b2092c3e98013b218cae557a7613a31643bf822e6ea02cf7b0094e38f6f8339f71389ab4ab6be664a829208da028f51708dbbba31b12be27165e234415 +9164d633a553deccf3cbd2effccf1387fa3177cd28c95d94a7d1a3e159c5e5c027758cc26493301b2f4d141d8d07a5fe5fead987ce5f30abeafcb48c302afc6c2309f0e93d9b6818cbb6972d222cb7b01302dfe202ae83b89f53150ae4a0e2b8fc0fd1091f19b4ab2e6ab213ab322d04f2c5f57113bfad3c5675227237abf773 e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3 821661d157e68e98cb0115f2a005bb0149e38048a3e8c86af18843a491f079aa8972e2ad4a0ad034ef48bb38a50496f00ae8509e3794dc53c6cd5047a6a7a7b4b70f68dd931c4f0e10c2ce57458bd06b537ba841b831d7108f5de8637d9d6679 +019df05929321ecea7ee1de4f412aba1c8d3c24437db04b194a68a0a59dd871be10bd3a4be6edf551350ea49fc7155a4d887e1221486291abe77a30633a4c4f7868fe2df24311cba0c73804883954460e122387ed414111ff96ff1aebac8b6a6491d8a0d16e48a63bf3d027c0f68ee4a4b234d73b412196706af8ea022b4dcef b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17 a9afde7a91afbef56aca3df2bfe95bb6c0a698232c9fddd9275f3daa234981daf6fa894f9d272f4b3d1ae785c7638a5e04060c888270246c7b4362149cc6384c201111a934f6f551d1370caef407651842740dfb3fb3daa1865b617271d45235 +5d09d2b1d3fa6e12c10d8b26dc9aabc8dc02bd06e63ff33f8bb91ede4b8694592a69e4ed4cdf6820069e2b9c7803658949e877ffe23bf90bcf5ce1409c06c71d86885a94048b05ac0ec9db193e489a5a2bfa367caf6aa8ecdb032be366174343f6875d2fe1785e8d77334f5f469cec64998e08d3303e5c9a1923b34fdc105d65 efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085 910605ebf6db4a6166f802f3b4c4484b10888b15e1d2f81c4f80d53cb38fbe41a827493bbc77c59e4dabdc0909b9756e0f028484693cca58dbbe1da9d40a57630d36bed39ba1b84d2c195b4fcad2fa9c07d9324488ac5f85bfe4736a6ab2bb91 +50f6dfc81c6cf189e0a310f992907fe93356cee9dea9a41c7671a8daf3f4cfe0c459ce6122c1e731dbf7593419d7114cb73b46956158a982c5d52c72f43f0f822046093c69aeff1f7e4cd8af00ba655c5baa2e7b6a400b4be1f6fd51b3e4cfb35a69c80a28c5cafb771b6c2e52e0aeef0e3fd045e8d40745f3f8b74fd969f816 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd 852b363b8e017789b4b078382ee4f724b367d22b22622208446c2594cad5bfaddfb3884da87f12ded0f0fd5b6ce067e20f4117538bfe53c1b9f062eddcdb14ed3fc8624a8e36fd15afa5b194e3f3ff2a805acf117c4a048b2d980ee7bfb3ecd2 +e90129ac6672c85bb7b6b18e9dc199c96c81fd65034b53c77818364d512366fb9cd1bc7c82404c451e561fc1ed916c0948f6ac561b33a1ccca093f07684b8c2bafa9e966377bd208556018a5bafb9edcecf70498c7140fe9c8cf3ad8b8c3b0aa489df797944465047465415bb0e24333235fcdd59a98829a3941eaaf62033e82 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d 97e119cb6545dcbf983b5eb7b54a9f5f6cce2caf4ac45f1293fa72424cf7777110263eccf5260dae4e4d7eca715770ad1345b7eb7a07c911c17bb22db2fcf73a110a41dbdf12154d169c7f47629882c75fcf86164cb9cf0dd2ea4b1b7524c7cb +3c9a483c9bee33b601549c592a82e95b4319b1e74b777877f0971bcb4273716b268e8f99f876e42f942f4cf08284896bbc1ffbf094ac0956c3cedfc3580cffa8c74fc6db29a371f2da2d05edb9185ece741fe0d3fabfe9d5b4d373755ebed13dc6840cfa3283b9ea46ec8b95c434f253ae86998182e9cc0e95ee64f323fc74b0 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0 93173d67ceadb5f1b56890eca3ae88040a77ce76da7651ceed1a0c347b95908bd3d9c97e072a482682c4139ce30637650feef49b0c9d9bbbc80e66bfbd363fb9744de5eebc07c47f0d22e544701d59153036d019e8a7068a88062f25b9fd29b0 +bfc073fdda63c5fccaa0ca8770c293e8154e7aec56128bbac4fdbd541d602216ebf7ca1e02b514d6e396f20683802ba3f334310a9226576926e3bb19ceee27738d13377cbafeb09d091043501702a07aa31d1f29d50ddc55adcf16ffd40578e734a4e6cb6535f26ad48e0c62ad90e79720000e87d419e92dca3e11f943655b03 e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d b3b52ec511ce43937cbc0ee6f2c316fcdd48d234fd5d3cd69d7bb691df88103ec31fafc378d6c24763f7a9ca5e53603a0881612452870bb523536933283093760b7e00dbc59fa976041163c0c69278a33038c4eaed4d0f68f1e66bba8ac0ce0e +08079955d1a1f33728128c73673ec9f21a6ce138dcab5adc4dc068e6ab57314b9fbd8b013123b2fdafa9524fbdd0288777a233de8055cccfad83046ada6a19f01c47817496667bba8fc8b9456fc0e044a562d931dab1adcb66af8b66325bdf28d83ded3e2937958ccd19da540d70ef2c189f55a506c9c0d63406394c5bd3823b f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7 8f18e66a6986eb3549fb5022f5431f1c08826c53d055931666834cbc174959c7a670ce546bb2375a423065bdb486489616d28b57007d238d7f8d2a5a326838194f6d8de8e6cf362f37854c05b7c7b9fed5c3dc547af5a77723fb1efe33c0cce4 +23900b768f6cd42b8a8df0dcbc9cb5daec8de36b9d5c619adcc1ba2b649103d5af123746cdf19c3fd0665a6fb9338156182aa06181e3c6e37ce56979612af2927440424f89cef43fc754854b8a5c43370808cf5f9929cf47712512ce2f8a2a20d2e9f568c2848b27dfbe09142843c83905ffa5da3b15501761b03dbc2c5398b6 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c a1998202456c1f111bc9cb86da0dcc4357cbfda5180d9f90739ce8b874ed7ac2835529eccd64aff747060e52257acde91158b3f33d65a4eec57883e5bd8a981e9b6546c8930b341a355a42233bfb20331509b12c9e3d734231ad2385ee0a7043 +1eb28c0bcdd18f73e347f957ece15b4cc83a771b0877e1feaac38e24028fb38ccea8b54ee017dc7c3d5a1327bc6f40b294aa65d7dc487f278846cd101ee84202f14b38aa2c275046aa2577f65ebaea41cd383e8def2fd0b4444dcf426fa75c4082cd7fa035cdb1e0d34a3c79d42130f5b0273eae75bc701dda3aebe7358f41b5 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18 a0041f24bf5c96f7940fd3392c07194c7e8c5bb0b8793e6cf6dddc9c5af435e97911fe62504f2ffc3d6d746aa13e116a03de53c469f399a0701eaab935d29835022ddcda987ba4c15f609147e528498dafa24b7e9401272bdd06b19d234e12bd +efab51855407438fd5c250670366bca3c026ecec4a59394f00d8a4b51746d0c4564366656d507e3e13e62fe7abeb976b8859895848dbaecf6582f1898ea06f00d4247702ed9721bd375aa83ae4c67c2eaa6e080777ea5ecf2cf787d785389560ac91cf63a52f0373c3185e18a3b8a466e21b61a239f1b77624eb1acacc76c4e1 bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a 8356988e890ac983a35861ac110a3258030b8b68b90d824f4fae618d07562978e97e60dc64ec6271d18d4357a07878800503ea30059e57a15d8c75002c0e4b7455f9637962ce57a5fd29673ee1af4f321c834ec04156e936c6b836e751b7eaf8 +31c29ca10279a417f0cc9b1382cf54dbfdfc89f2e6ef08c403c11f580cbf8674b141ed1a417563282d99a55fc616d836421cde9424815c95e7fb7668bf3f137b29937f14882d74e034b732d78d91af7721aac4950734f5fa5d4b4d35534974f8cab6d2e6dca75ddb57e99148c8a59df9fc5bcd723e546e8356f671cf2f65640a dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738 adecf04faa3d11b740c899814d1079018c9bd3de5837a442fb47201c76a337d2c89ccac8cd6ad23d1ba2992fef49166d0bcb8a580709138afb10d2c7b5c7c64a4a7a7f88646f2f25e82f6707f8e421ada6375a1260c9d9f1a329e55059347c32 +8db476f92e332519c1a0ece5d8deded6efbd2d8e8784eea0a6b4c3b4296c35f5f8de4317e5c1627b91fb1973fee86c06e4992aa5a20cb7475c8808ff1da354d07a488dffa7838c6ec1e3f99e3acba831f27bee8434eeda3eb36d0c6df3658883cd40068b1bed841310f6eb38d4a3d07d85848770ff7933c054cd8b34662660b1 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01 852daa7e63a1c68bde16e58b09b402e10c05d3fdd80f9729e7af4516834e79f7c4ae6f1fcfb92b3ba8895c3abbf137461047690022bc3a14e40a1e1d200bdddaed296edec67d9bb60766a2299822fe3955f09b7427156a2c0f61ebc0ef494e6f +fcb272c828fe8fd3c6f8de9410c7b6e2b36717c1b0e5e359e9109bd7fc378978aa98182a9d99961898ed88999b050d3b64d1457d7a899d6d273b9f4dde2aafa36d76329d62509043c338f265fc4c7d938459b7fa3b230a9f6cb632b61489546bb4181a5ad7f0d7369b8caced48eb374b075b2b325bc86add0f3b680cd9e80acd 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28 881c4d5e866413f813dd31ef74d4ef60e116f2412ba226aa0424294f67537eab2fc995790df4a9919aef7bdfb8616a69161d18b08eaee87222082113858116f0a96b88f068ce61a1fe8b160ffecf901a0097a5d18bf3caea088583c2f09e401c +7522492bdb916a597b8121f3e5c273b1d2800ef8c1db4f7dcbae633b60d7da5193ba53a63d7a377b351897c3b24903ae1cd1994211b259be3e6ae2cbc8970e4957fdf782c7d1bc7a91c80c8ef65468d4ef35428f26e2940ae8b0bd9b8074236bf6c00d0ebe83f9ddb2ade0f835138d39f33b59f244e0037c171f1ba7045a96f5 ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6 98fb9d3fd9a6105d4088d4b03a80007630177a6cfeb7a1f407d7cd5cc3ae5e9207c8640158c92935bd3675307449b18018eedf71c9b8ef975ae303ce0723e2e895ee985d744ceb37d7246666634b5b32aef1e3eb844f77b9dfdfc063f9f89954 +61097114ff855c3e34a62d9b853f8982d35f29cfa4a89893badbca7849e5fb437a1a38d6451bf0ca5a0d528e352b8e4b57f2ea359a7fc8841d49dd3e570f9b016f14156b0bbc4be822e260bd147ec081454969e11cb0034b7450ef4deb7ed6edb977e2f4ed60121aa095fb0ab40240dc329ecc917f5c64b4410612af065ee9dd 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc b3a7b323d4e91725b23545ce643856360f5b5d2e9739150079bd8454435131dc7623133579234db02b04dac3cd4bd9ca16a6074be692183455ed099fe45fba26bd9ff5f70122cc42f87befb858c8540938bb09d6f99237d59a98586a513d23ba +dd09ae6c982bb1440ca175a87766fefeacc49393ff797c446200662744f37a6e30c5d33ba70cbd8f12277fd6cc0704c17478bbab2a3047469e9618e3c340a9c8caaff5ce7c8a4d90ecae6a9b84b813419dec14460298e7521c9b7fdb7a2089328005bd51d57f92a1bcbeecd34aa40482b549e006bbf6c4ce66d34a22dda4e0e0 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b 863cc58c84a9407f815374ee6918d80ca3bd59c812de3c81a83f82c77e6118c5b25b0c9864b8273108a87fed506e0d9b03601f696e39e8cb958d3aca4d5ae1b1bd62c60f9a1303ba81e05d9f1a865ca4ed4d79a6e2dcb8f4180e5f575eba3625 +37a73e2774d3b274db426c89b945696daa96035031f72cea01894b24508c7f81961ec254d36ed6a0f448e11cf7950af769dc6cd2c47e52c6caf0ea92c270974f0214b4db436c36a60fb722060a6bb544462a82e1714f5906ec32886f7d59ebf289541c3a00ec1e004892ef2b1286a0194f55d083c6ec92c64b8fd1452e1c68ba afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc 854aa28e56c0506feee2333d6021018b908e2f3325fd22c84d79c10d1e64ad8a422e716fb21093bd5005063851b572e507644295c851ff2df31b9e4be6256d10819fb087ec1feded7081eb6543547d390652c05c0a1f84a811e8319aabab408e +9dc2046ffdc6804544db964481abe5d2d276a2a9eeec4c7ad40215b1de23561d402db69bd0f6eec2254711eea4487c64d9a6b62c3ebaf5ffa8db6e7e3a6e17154d126967a47a853a6f8339bdca9be306a13c7f992ded7619b0da59909a49b1e0930360e05b47f18628a36d69b2f87f2bfddd6a5d4a72f84dc76dbdd43f3a6a35 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c 902f2690b94bc5f87c7c76fb7b6993fa522f5fa75997541b1cd26caaafd0b8ebbbd561e367413e77d5d06d0f52b66d540654543b0d31af875f0acdf9fd4157a2b4679aa7b9c21cde9bbe29215428adb4ecc8aedb8a98b0697c3ebcf9fa7d5b11 +d9c6847fce688c5e7525a1098b545cb6c15dcd21a02761fc82fc664372a667390680135f91c01a2fa5430c634b1a6d1cd6002d8aa021e7bf5956a7901c2f81bc25d502ba5f55a55f30c0323dc68205cbefec0538e68654e7b327ac1743641896c3e740d8f66f400902b304eafaa4e0d8cffae140536f0922444cc3216a675697 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc a9151742fe15a9d1f372e6ffeecd617cd9ed740222fd446ce798cc389891e231cb0364150882141b0fdfc01535c2a335107b392fdc841f867231090e7d25ef0e0d13b88c6cfb6ba77a652f0e44f2729630a56a06a2c4e6b3c91dc7f0f74eb7dc +69df8a01b66f04930efd2012ff2243874f256ca8758145d2a9e4ecc84d0dbdbd0dc494ae06db0ccbe819918137c90957114558580d6623efbafdd342b38dad9f08708084d32f874fba04782ce26aaab78de2102ad171f8a8f2b30b5bd3d55fdac5fa3acd6f7def7e61c2533938572b331ba6d1c02bd74bfdbf7337ade8f4a190 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4 82df4d8a4676942620a4f02e235d4d25ceb98d73cc9a9698d812a798381fa5bc92e42f5bac73f55d0c570f844e16b6b4192e6b549846d467698dffd90abf674e78b9049d6a4a134b563dcf16f0c354254334f064b296113ab3bdf2b469c0f227 +927524982b8d60777c1105c86fac05f634abf58c73f84fb95d81ba0b86e1e43592c4fcad2e395a40fbe7005697d86088e2fb3bb7287eb3f917d4f2dc281f5cbe65d05b4f9623bca849b10a03beca6aa2056a12ebb91cf257ac448c5e9a78f8349a6a29b17c8978bef43a443cbb8a149eb23f794844fc41693f2dbb97181444be a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916 a4919cf6627cc94c19c65a298ccabc79efccc86afc3c99aea4d99010ca6f41d63d095aa5f20513cd883138c331c0f1f81939c6664373e6732b6d25d46434ed27a7d2d5a14288e935c740508dfbe075f40e8c39c36befe5cc5972fec1c035e44f +5f9042283561e7f19a436d01c7ef5a950a6d77ede5629cd7e43c0a5d58e8c5673c37945a453291d12938253c71dbe12c8b022ba7276eda6be034ef5ec1ec77dbd1e08f0d7b8e7725b7ec671c075e008a20f77f4ab266f97079b0aa6337df59a33b881954084057b21f294dd14bcb0869a4a6f1f597955ec7bf9d19bb3537a66a fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b 81b5a7e9f823bc374b8057f5f63695512d13e92c3bc38081283a7f13cd054da62081c4d18919d3f538977ecd113354730a483d91255866e500f56c67a884e2bb49d561330dfa81059e1f4bdfeaf7f39be4c3c25bdd783ac7960fcde0f054f0e3 +c2ae5573d3bf396523bfb703db8502fd0760cd1be528f6ddbfb95aad399e0b19f3bd9e0fabdb05d49e3f893dffec5b627c9c2f7ad5f32e92e4e27a38cb5c28657657377fdfa1b66cd7ac3d15c6d49df92d284db99f69744f37dc7cb4e7d52920fdb200a7942623a7057ba82e467dcccaa5da416b48510d8364446a6a5e2a5aa8 a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea a959fa8d1d032a4d9e37daeb4f5f0e67f0e478490a4e2ee865577ea89bb9f213b33e86871058b44978ce456c15de443209a15291a8442ceb10e2dcdc335f6b133d326958afcdd59b1add2d08d6f73208fa74d3352a37133b130459a0e9c1ccff +03c1a1cd30a039d0dcb22fee2450a7fa79495a0d0f4f43d2de4d75bce003c0334a8860f5c164dbd94888a9f751235a3e570d31070e3e1293a7be616af7176600585d36ac013600157d2569d491da4b8a3bf3630c26e0b9925412189f50b0ae6f04c86477932e2ecd8c3546106ae1ebc684cc3adb27ed665eddece886adea4ce3 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0 a42a7e21327e57856e682f7a1fa5897fb337a5742bc9ce8bbbb583335fe1592369dcf10fe50ee895e5f7a3d06a8d6dcd13a69946613e37d0891cff37b7a617cc7b9bb2ed7dd3a314b39f93927e8fd0bf83816462da52140fe402b8b88cbd93b9 +888f6d9bc7c86c0079fbfd42d8c08d6958f40f6e570fb0b1f03d2f8f8a63df4fcc87b379a222cf835820a999d34996e08961f13b86b075e7fd1c303cd3baa44de42168561589012f7e5300da4f8bdf470c07119a5d9f7ba7293568cd7c6a1b7fc1e41cda40bed7d46e5a28af67ae2aabfefe67a86a1c601e6f5ee543e09bd7b6 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294 acb347ef27c2576627b0595478fd1d3090a8b5e6bf08c588b2a0ac46b78a20f63b1b3e0c119c9190951aa96a5e9f3cbd0657d942f428a74b4d18c5def681e687e1b6d79512a116df420795b5b74e5f37abfcfbfb025e65f627edc760e44fbc4f +48453340f1317769e6ee6e103153714365731163dc18f84e9f2fa4b120f9c5a9645ee2f9b66c84c26d95912b422b009b64af96aa418b2427a4209f2e7513ba8e43ec8cf20b34e7529b22eb1199545afe9a9f7d9bcb320aec9ee0162f91c0d1dd9674c9c284f25199c5e109f6f84d7ed0d269cc6413edb81bc2c83e37d644d8b9 b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a aab5ed6ced23d6abb3a0e6bb6b487a42073bde9d2c7271b85c681305568db944e9a0c5d01740e861e53ba17b66a718890e384b522547ad9ae1177af717c6636934ec726cacd26110af96d50fe0905ab86b30677bb6fc12b2d2ea5cb58c5789b6 +4bdfd3b91d83108409ad765b256e0c9b9937ecf647f8e6f9fc807e2e72af8246178b3fe046b4ea10170450d71a4eec790ecb05f03d7077341de26c4db7eeae24d55c9a9093e837dfdb38168fe8230cb9605825a1282fecd741989bfcdb34678fe077477927f66bd26d003e5dda22043341a14dd31841ba483ad5ce2701e0f68e 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4 8a91d3171a91a60d5c77ca9544c8c3d57ffdcbe3ae24d6439b2617cbced8abbc5dc765942efeabedef199aaf991447fb1635d58358a2c3452f5888af4b463c25a6d31a6e0b965aeaf45acd96fc43140f7414a663aa8924bedff4840e3e81249d +e6cdee8558bc1eacc24e82f0624ce8d02cc8d925b4dd3dec3a72f4a4e0fb76076bfa3ef2e2c33bdd7c27b322bdc09bbfee8fe46f75dbd7bbd2af09690b7137943efe21706e0a1b6d3089540fc58d85ddb55ea836616db573e36c521be008893f40a0a7c349602cc178ea43be59d31ec6449e7ff2c5379379f7d7645134df1bc3 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04 b65870087fe6e3351856e7c031325e1e5a6c1db366d041620a4f6ad10cdd615b3f52a138caa1d41c5f3a8b6ddc30146f0d16ac6a108a7411df419bd40038903011a023b4b79fcd149a9768906532533159a63774bcedb2b394fb88902caceb1f diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P256 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P256 new file mode 100644 index 000000000000..f32e12fc462f --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P256 @@ -0,0 +1,60 @@ +ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590 af515e1e191f6623b17a60ed872ce88797133627759c623878d4151652b0955cf9a4fc93b1a3aa1f066dcfcec94d170e18f87c0de60ddfc6ad0b83150199cf9edfd6b7d24da70fe33d87815374bdef80facf83d8642cf8ad8f07f0172ab33c62 +9155e91fd9155eeed15afd83487ea1a3af04c5998b77c0fe8c43dcc479440a8a9a89efe883d9385cb9edfde10b43bce61fb63669935ad39419cf29ef3a936931733bfc2378e253e73b7ae9a3ec7a6a7932ab10f1e5b94d05160c053988f3bdc9167155d069337d42c9a7056619efc031fa5ec7310d29bd28980b1e3559757578 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98 a00cd6e811aa603a0d39d67de18abfcc1a4818f5a241c5025db534444caade4886157ee8162b1b167c9d3e1164a1d0ad19880f944e9e75e8a78eed068dc8489c778829ba85fa9bcefa4315dd6bb45aaa8163d258b01b23f159d3d2deb87a4fc6 +b242a7586a1383368a33c88264889adfa3be45422fbef4a2df4e3c5325a9c7757017e0d5cf4bbf4de7f99d189f81f1fd2f0dd645574d1eb0d547eead9375677819297c1abe62526ae29fc54cdd11bfe17714f2fbd2d0d0e8d297ff98535980482dd5c1ebdc5a7274aabf1382c9f2315ca61391e3943856e4c5e616c2f1f7be0d a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870 b0ba841da3264bfa9460becef738e66d46e7df97b81e1d7b6e25f159c1a846767569dd97bb4c364622eec7b18b22d63f08abad66f1bbfad2757deea4683ea800edc5d67da065d3e86506e3417e6b155bdc067b0194eb7891027c17318c417392 +b64005da76b24715880af94dba379acc25a047b06066c9bedc8f17b8c74e74f4fc720d9f4ef0e2a659e0756931c080587ebdcd0f85e819aea6dacb327a9d96496da53ea21aef3b2e793a9c0def5196acec99891f46ead78a85bc7ab644765781d3543da9fbf9fec916dca975ef3b4271e50ecc68bf79b2d8935e2b25fc063358 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f 922ffbe090bce198375d3d99c4948c18f5dd6f5acbde9abe1a555f566f1e06f673fb344001966377bc439f1acd7a08ff067d6b442309fc361d0f2acb15fc0b48ab0555ed394091bc70c20ab53767a77df2cfa37cefc4cf8a2ff0827335e96dd3 +fe6e1ea477640655eaa1f6e3352d4bce53eb3d95424df7f238e93d8531da8f36bc35fa6be4bf5a6a382e06e855139eb617a9cc9376b4dafacbd80876343b12628619d7cbe1bff6757e3706111ed53898c0219823adbc044eaf8c6ad449df8f6aab9d444dadb5c3380eec0d91694df5fc4b30280d4b87d27e67ae58a1df828963 daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d 988f99dc9cbf780adf4cb09ff8bf4ff09da88b0cffe8e3384529c95b1f6fa3224e2f319fe8599b3a2c48d125107efafc01c4e592201b9cc88c058c0b3fc983b69e4e498abfad9f0ca076f9a5481328a90de821a4f2d874f6fa45dc5506272d9f +907c0c00dc080a688548957b5b8b1f33ba378de1368023dcad43242411f554eb7d392d3e5c1668fad3944ff9634105343d83b8c85d2a988da5f5dc60ee0518327caed6dd5cf4e9bc6222deb46d00abde745f9b71d6e7aee6c7fdfc9ed053f2c0b611d4c6863088bd012ea9810ee94f8e58905970ebd07353f1f409a371ed03e3 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5 b45152619b78cb80054dda9ef94809fe9507636010928601ee063539ab4b1d87703d61fbf361a78225188027ef285ddc0b00a7bba604c016a3a099809573a4e0699fb0878e65b1e391950d6ed8cabfb802b367270a8d1d5e48a516b3f9891ac2 +771c4d7bce05610a3e71b272096b57f0d1efcce33a1cb4f714d6ebc0865b2773ec5eedc25fae81dee1d256474dbd9676623614c150916e6ed92ce4430b26037d28fa5252ef6b10c09dc2f7ee5a36a1ea7897b69f389d9f5075e271d92f4eb97b148f3abcb1e5be0b4feb8278613d18abf6da60bfe448238aa04d7f11b71f44c5 f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96 906b7a543a6faab4ad3e069fce59d584a4f165c332e5813d5fad48e866d3850d0361690c2c1e52d83a47b47875ace4800021c987f4c8b82baa58608083b543d1bb2d8b6299834eddc07657c75cacea5e7a7941bfa5e437269a2184963372296f +a3b2825235718fc679b942e8ac38fb4f54415a213c65875b5453d18ca012320ddfbbc58b991eaebadfc2d1a28d4f0cd82652b12e4d5bfda89eda3be12ac52188e38e8cce32a264a300c0e463631f525ae501348594f980392c76b4a12ddc88e5ca086cb8685d03895919a8627725a3e00c4728e2b7c6f6a14fc342b2937fc3dd 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d 8a458850af2aee09a620b7f96710d818ae6bee95b74e7cb993189cfdfffb600ec65b66ad7395e8f06692110f84c3842d005a2a673c56f655ca30d2fba63c0d9a5af4bc72e679a766a9a81f3501b88d4ad60ed0fed55580be22a51af06d8b6fd6 +3e6e2a9bffd729ee5d4807849cd4250021d8184cda723df6ab0e5c939d39237c8e58af9d869fe62d3c97b3298a99e891e5e11aa68b11a087573a40a3e83c7965e7910d72f81cad0f42accc5c25a4fd3cdd8cee63757bbbfbdae98be2bc867d3bcb1333c4632cb0a55dffeb77d8b119c466cd889ec468454fabe6fbee7102deaf 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9 a25ba98f9081d9b276e07ec8d3c5ece686c351c099a921a9e37c4405319ffbcbb5f6b1fefdcb64ccea7c15dfa6fbd5af161f77cd021573ca1afaebd63620fb1e5b3690be242def1b07ecd1585423865981413cff1aacbbb5e76ddef73d5083d3 +52e5c308e70329a17c71eaedb66bbee303c8ec48a6f1a2efb235d308563cd58553d434e12f353227a9ea28608ec9c820ed83c95124e7a886f7e832a2de1032e78dc059208f9ec354170b2b1cab992b52ac01e6c0e4e1b0112686962edc53ab226dafcc9fc7baed2cd9307160e8572edb125935db49289b178f35a8ad23f4f801 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634 b05110fa4dffb25aebe0e4ebdba576194f76b9a104bcdd4679540654f034bfd2ff2d3fdc42bb22ba7d3fe342f0280bab193ba6763718eb3580fa6d776729b542fbd508d6ec572adf4d9ecc6e3a4131a6efef1157f1c9d78af9c76b1db77eb4b8 +d3e9e82051d4c84d699453c9ff44c7c09f6523bb92232bcf30bf3c380224249de2964e871d56a364d6955c81ef91d06482a6c7c61bc70f66ef22fad128d15416e7174312619134f968f1009f92cbf99248932efb533ff113fb6d949e21d6b80dfbbe69010c8d1ccb0f3808ea309bb0bac1a222168c95b088847e613749b19d04 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27 9383a3bdda54a0fc36880ba707376f7c3b8142fd8fee34a284c40d48d78e48757f3a4687589462f7f969ecc1acf2da5f144995bf2da20daecef7ce65aca0474464ecc06db41f5d4eded3d5b1e8a746d9d7997e75fa14a6f1328673d993fe8fd9 +968951c2c1918436fe19fa2fe2152656a08f9a6b8aa6201920f1b424da98cee71928897ff087620cc5c551320b1e75a1e98d7d98a5bd5361c9393759614a6087cc0f7fb01fcb173783eb4c4c23961a8231ac4a07d72e683b0c1bd4c51ef1b031df875e7b8d5a6e0628949f5b8f157f43dccaea3b2a4fc11181e6b451e06ceb37 cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d b39d8ec11fa4a640e1c245ff47599b69bfb4a61cae64eedbec6b9c7385b81cc47f5df4ac4091f68d73144be8de1cb20a0f65524c63e1c93097aa4bbcbb446ff81550d49655589bdfb26c84457cfaec9788e6846ea99e5252ad0c730b999f9901 +78048628932e1c1cdd1e70932bd7b76f704ba08d7e7d825d3de763bf1a062315f4af16eccefe0b6ebadccaf403d013f50833ce2c54e24eea8345e25f93b69bb048988d102240225ceacf5003e2abdcc90299f4bf2c101585d36ecdd7a155953c674789d070480d1ef47cc7858e97a6d87c41c6922a00ea12539f251826e141b4 b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c 836717bad95d7e0fad2b7cb304779da3fdc465df18479c0f353a4dd8b6346c956b6a08a03254b806a28cff3b4455d82808336006ae190772765857097d5b340dd0d5d3d246ac6686be93f0ac9301a18a33a6d63a787a77398b5f241451ae9946 +9b0800c443e693067591737fdbcf0966fdfa50872d41d0c189d87cbc34c2771ee5e1255fd604f09fcf167fda16437c245d299147299c69046895d22482db29aba37ff57f756716cd3d6223077f747c4caffbecc0a7c9dfaaafd9a9817470ded8777e6355838ac54d11b2f0fc3f43668ff949cc31de0c2d15af5ef17884e4d66a 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48 87f7f1854c0910c5eae49766188fef911419ff8fb4fab7e9a49ab5ff571a06eed62810ecbfd34fa2ae191d2b9f1bc37c18bb6fdf896840fab0270cf64249302df68bf55ca92c09608a540a9b464b16bddaa01de6e797b65e82965c667c5c4d51 +fc3b8291c172dae635a6859f525beaf01cf683765d7c86f1a4d768df7cae055f639eccc08d7a0272394d949f82d5e12d69c08e2483e11a1d28a4c61f18193106e12e5de4a9d0b4bf341e2acd6b715dc83ae5ff63328f8346f35521ca378b311299947f63ec593a5e32e6bd11ec4edb0e75302a9f54d21226d23314729e061016 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f adfd2e59c609485047b1af87e0169a45d19b0800ffa86e1da88403311d0028c50678c4eebc9b1a3b56ced2a3d35d4cf50f4f5e37ced7ba374fa12c20861418f51e59b472b213a53d49df199283368f9477d9a4eb95afd1c6710658271b9fee78 +5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 883392d6364d8f84c50097b0f0575ae6a80ec74f2f5f7066b9a3f50039424bde6b8bf0132b14144f91ec4089a44dd3740352598a0725d346ec246597ef392add596545259670918decfababfe6cc45088d967bdd911f0c24abd36c033266a0c1 +c35e2f092553c55772926bdbe87c9796827d17024dbb9233a545366e2e5987dd344deb72df987144b8c6c43bc41b654b94cc856e16b96d7a821c8ec039b503e3d86728c494a967d83011a0e090b5d54cd47f4e366c0912bc808fbb2ea96efac88fb3ebec9342738e225f7c7c2b011ce375b56621a20642b4d36e060db4524af1 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 8729baa8b66885e4413eb5df250e367399d81d425be5f6604eee075b4befec9c30287fb0e16bc588f42e121acc5b60e8159c548aa1c85da591da75d7e271b4aaf2a4271584d3fb0a8f31abca37b5356da048b5cf8cfec126c206fbeb5ffb7afc +3c054e333a94259c36af09ab5b4ff9beb3492f8d5b4282d16801daccb29f70fe61a0b37ffef5c04cd1b70e85b1f549a1c4dc672985e50f43ea037efa9964f096b5f62f7ffdf8d6bfb2cc859558f5a393cb949dbd48f269343b5263dcdb9c556eca074f2e98e6d94c2c29a677afaf806edf79b15a3fcd46e7067b7669f83188ee e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef 970032da29c25a9bac73f7baebe1ef0ec7ad430644cdd7c280203289d1266cdc67ed549c08b773d7261c58a57c030f340d5d2b896fa21a37ccc04370e9d50bb95188317e4fa77d7a518994ceda0c7b3f13cb03c8d58fcc16a8ff797d9d925e10 +0989122410d522af64ceb07da2c865219046b4c3d9d99b01278c07ff63eaf1039cb787ae9e2dd46436cc0415f280c562bebb83a23e639e476a02ec8cff7ea06cd12c86dcc3adefbf1a9e9a9b6646c7599ec631b0da9a60debeb9b3e19324977f3b4f36892c8a38671c8e1cc8e50fcd50f9e51deaf98272f9266fc702e4e57c30 a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 a15ddeb0010e5bc5743531931ae66d1f83c3eef5652aaf3ed9a626faebb12982c686ef34cdb051c76faa631faf763cf108b87bddc414d7a293867eb4e32ebff12629ec431723ac2eef9bc9770260ea56641ebacbf4ba449c44faed46ab30232e +dc66e39f9bbfd9865318531ffe9207f934fa615a5b285708a5e9c46b7775150e818d7f24d2a123df3672fff2094e3fd3df6fbe259e3989dd5edfcccbe7d45e26a775a5c4329a084f057c42c13f3248e3fd6f0c76678f890f513c32292dd306eaa84a59abe34b16cb5e38d0e885525d10336ca443e1682aa04a7af832b0eee4e7 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d b152d344ed4bbc0e703d2bab7c815eb3c81966b0698cf10d07d7e055727806b6afbdcbc43c8105c37aaa78714d6dd72418ca5cfb38efd307d0c6136c65a75df273f915343b6ee66aa9a13560f5e61632fb91a4193baba1d5d128548ea154b463 +600974e7d8c5508e2c1aab0783ad0d7c4494ab2b4da265c2fe496421c4df238b0be25f25659157c8a225fb03953607f7df996acfd402f147e37aee2f1693e3bf1c35eab3ae360a2bd91d04622ea47f83d863d2dfecb618e8b8bdc39e17d15d672eee03bb4ce2cc5cf6b217e5faf3f336fdd87d972d3a8b8a593ba85955cc9d71 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d 92274c0a0bf5757d1770f1661bae442502c0c3c86887d573dce822808dece55a16a62a407dbdc7f03ceb5e71c561f897013e76d5b204aecce6087a5eec6e689ebbb5d1e845b5222b3537238b16da0a3d5a2d13ecdb7d6207944591193378cb8a +dfa6cb9b39adda6c74cc8b2a8b53a12c499ab9dee01b4123642b4f11af336a91a5c9ce0520eb2395a6190ecbf6169c4cba81941de8e76c9c908eb843b98ce95e0da29c5d4388040264e05e07030a577cc5d176387154eabae2af52a83e85c61c7c61da930c9b19e45d7e34c8516dc3c238fddd6e450a77455d534c48a152010b 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab 84eaeb6b9edba3b4a95ca7bf251665746d950113164afe676de41ba818701c8744531a15336f359afc80450a16b1be33036e0dcf0b3634ed74eb04adcb1950c0dd30a186411c3425d6be79242c1e2eb795a2226f3e4d52a04d630b55136a87c9 +51d2547cbff92431174aa7fc7302139519d98071c755ff1c92e4694b58587ea560f72f32fc6dd4dee7d22bb7387381d0256e2862d0644cdf2c277c5d740fa089830eb52bf79d1e75b8596ecf0ea58a0b9df61e0c9754bfcd62efab6ea1bd216bf181c5593da79f10135a9bc6e164f1854bc8859734341aad237ba29a81a3fc8b 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a 9986daeba17f9572e954932697ee98acceeb3f940544a1c7247dc0e3e577b84f4db5e423e0da063da24b92c63d4504060f8ea837d32e29deaec44352021d7eab2557ba9e7735430059c84d40c9113b2e0f2635dce261b274ae78d5f224626cc8 +558c2ac13026402bad4a0a83ebc9468e50f7ffab06d6f981e5db1d082098065bcff6f21a7a74558b1e8612914b8b5a0aa28ed5b574c36ac4ea5868432a62bb8ef0695d27c1e3ceaf75c7b251c65ddb268696f07c16d2767973d85beb443f211e6445e7fe5d46f0dce70d58a4cd9fe70688c035688ea8c6baec65a5fc7e2c93e8 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 8bcaf60af6e9014cfd7316c855df9fc230588e65c08bd593ceeb0819feba8e32ff19dd2e361208fc2996dc9d4762a66a18b3913c86da5a9fe248cb10dfad8ad7da9e939944ab41e0aecb01d179fa94ce24bf57ed96552642b917c3aff3c402d2 +4d55c99ef6bd54621662c3d110c3cb627c03d6311393b264ab97b90a4b15214a5593ba2510a53d63fb34be251facb697c973e11b665cb7920f1684b0031b4dd370cb927ca7168b0bf8ad285e05e9e31e34bc24024739fdc10b78586f29eff94412034e3b606ed850ec2c1900e8e68151fc4aee5adebb066eb6da4eaa5681378e f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 8a52680dea0a26774c31d08896c58df07c15a66d1fac2df383044f04c3010175a771a140e0c195f4cff69904ac550b5705641963a5f00af815d17f3ff34dc29d0a7adcf77606f704b047ba2ca389caf101bd893b5f443970409fd5e62516800d +f8248ad47d97c18c984f1f5c10950dc1404713c56b6ea397e01e6dd925e903b4fadfe2c9e877169e71ce3c7fe5ce70ee4255d9cdc26f6943bf48687874de64f6cf30a012512e787b88059bbf561162bdcc23a3742c835ac144cc14167b1bd6727e940540a9c99f3cbb41fb1dcb00d76dda04995847c657f4c19d303eb09eb48a b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 ab7b881dfb87e3088c6e5221df671e9582cd5d6085dd337d0cbc44aa31b4e95003064bef9cb7f2b5a548737f4077d81c0c4c00b6cc992ec38989f8bca21cfe91901bde714acb0d616872ffd6b7dc855e09de4d7f9daa45519676ab9862f746c5 +3b6ee2425940b3d240d35b97b6dcd61ed3423d8e71a0ada35d47b322d17b35ea0472f35edd1d252f87b8b65ef4b716669fc9ac28b00d34a9d66ad118c9d94e7f46d0b4f6c2b2d339fd6bcd351241a387cc82609057048c12c4ec3d85c661975c45b300cb96930d89370a327c98b67defaa89497aa8ef994c77f1130f752f94a4 d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 ae67537aab0601a5347880ecf3f5969489a0504fe0e5576ef890d7db5b5a74246626324ffee9d53f26a859666fe3fe32022c647b1a30443d0dd9dfc75c08b3c31e462ae0669cbfeca877c7043330ba4657710ab03c1fdd6949ab478f9d59b272 +c5204b81ec0a4df5b7e9fda3dc245f98082ae7f4efe81998dcaa286bd4507ca840a53d21b01e904f55e38f78c3757d5a5a4a44b1d5d4e480be3afb5b394a5d2840af42b1b4083d40afbfe22d702f370d32dbfd392e128ea4724d66a3701da41ae2f03bb4d91bb946c7969404cb544f71eb7a49eb4c4ec55799bda1eb545143a7 b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c b0821d0cafd5dd209e2688ee877761c37d67ec86c696c5ca601a462198aeba0cd485dcfd1d31910276dfa1218ba520e9053d842a5211150f36312489c395b5d97400846d6a026a2f5a92e86e7480e08f541a46b1cb9f0efc089eb0c00ff86004 +72e81fe221fb402148d8b7ab03549f1180bcc03d41ca59d7653801f0ba853add1f6d29edd7f9abc621b2d548f8dbf8979bd16608d2d8fc3260b4ebc0dd42482481d548c7075711b5759649c41f439fad69954956c9326841ea6492956829f9e0dc789f73633b40f6ac77bcae6dfc7930cfe89e526d1684365c5b0be2437fdb01 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 b7790d321ef7279f4492feda545f11b2733f698e109b159e72d154fd4ba7ca6dd9185bf88f73ea3f10607bdb1e0c4afa115c081745894fef93ded08e5e011f93245d5a5ab10eeb2dbc69aca52ee5855bb6d4b9aad455f3fdfcef53376eb193d0 +21188c3edd5de088dacc1076b9e1bcecd79de1003c2414c3866173054dc82dde85169baa77993adb20c269f60a5226111828578bcc7c29e6e8d2dae81806152c8ba0c6ada1986a1983ebeec1473a73a04795b6319d48662d40881c1723a706f516fe75300f92408aa1dc6ae4288d2046f23c1aa2e54b7fb6448a0da922bd7f34 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 b1fafde941f4829961c020820ba4b6fc3df4a647765a8782dbb4f269d63c70c04cb81e854f574d8140f10928c2d8296001fc86c67c286b40eef2154e5ef3dee98ed5c948c108f8456228ca3f7aecc94d68b55a5bb9e178554dc77260b77f0368 +e0b8596b375f3306bbc6e77a0b42f7469d7e83635990e74aa6d713594a3a24498feff5006790742d9c2e9b47d714bee932435db747c6e733e3d8de41f2f91311f2e9fd8e025651631ffd84f66732d3473fbd1627e63dc7194048ebec93c95c159b5039ab5e79e42c80b484a943f125de3da1e04e5bf9c16671ad55a1117d3306 b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced 825bed5e3626b058721ac87d1aef23aa3d9fe58f6481abfc0875b80cb35de1a80e6347d943b212cf121b57ae0e42db0407c5d2895e5c56f916cae95303ecd4fdbc37fc92f4fec550c9a518eeef106c6a976986da626c80f015137aa417ccf0cb +099a0131179fff4c6928e49886d2fdb3a9f239b7dd5fa828a52cbbe3fcfabecfbba3e192159b887b5d13aa1e14e6a07ccbb21f6ad8b7e88fee6bea9b86dea40ffb962f38554056fb7c5bb486418915f7e7e9b9033fe3baaf9a069db98bc02fa8af3d3d1859a11375d6f98aa2ce632606d0800dff7f55b40f971a8586ed6b39e9 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181 84d7757f1d32f83e20dc4cffe4d81cdf8e3bcfa3380a83af51f93dafb011d09cd28779974dc1e982772dffe10c5af9111671927ac0d5e18c1881c73e7bdd7f067a481b82771a23ad13079b397f8c4d1ffaceb18596dac44a7c44d62c6573548c +0fbc07ea947c946bea26afa10c51511039b94ddbc4e2e4184ca3559260da24a14522d1497ca5e77a5d1a8e86583aeea1f5d4ff9b04a6aa0de79cd88fdb85e01f171143535f2f7c23b050289d7e05cebccdd131888572534bae0061bdcc3015206b9270b0d5af9f1da2f9de91772d178a632c3261a1e7b3fb255608b3801962f9 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431 a46ad8ddd228bc3710e4933c893c44153ae6a6771d196ce3043bb0f8aec1df1dd0269363330c0731cef263657c85872b07b47528bf21d02fc911dbbcbaf7ec6957a5eb27819ffdd6944254f7840b2c54fa8dc5e40d48b03b2631cfa6bb7e9335 +1e38d750d936d8522e9db1873fb4996bef97f8da3c6674a1223d29263f1234a90b751785316444e9ba698bc8ab6cd010638d182c9adad4e334b2bd7529f0ae8e9a52ad60f59804b2d780ed52bdd33b0bf5400147c28b4304e5e3434505ae7ce30d4b239e7e6f0ecf058badd5b388eddbad64d24d2430dd04b4ddee98f972988f 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd 83af55e55f8cea2fdc460363490062e4c9673ea72a6b8b8ba9a2c75897438e4f7afb6e9861962b2b805c46043e73d1b40dbff18d7ae9ad4d5e72e99068db7ed7f1460eb5890e95844ad8947f82369db96f761dd6db0b833ce70fbf09b0356a8d +abcf0e0f046b2e0672d1cc6c0a114905627cbbdefdf9752f0c31660aa95f2d0ede72d17919a9e9b1add3213164e0c9b5ae3c76f1a2f79d3eeb444e6741521019d8bd5ca391b28c1063347f07afcfbb705be4b52261c19ebaf1d6f054a74d86fb5d091fa7f229450996b76f0ada5f977b09b58488eebfb5f5e9539a8fd89662ab 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de aec488b4e805d07d52ef5ade2729f24529398a4f6ab3616c5c643fac38c6fc1511872e6d1d41f17872f0be1613abf9f70f76c2cabcab3724c6c7879a7c9a3f21a419134bf2ccfcfa64f63caf452b119df95c8475916055bbc8fedb65883f5a3f +dc3d4884c741a4a687593c79fb4e35c5c13c781dca16db561d7e393577f7b62ca41a6e259fc1fb8d0c4e1e062517a0fdf95558b7799f20c211796167953e6372c11829beec64869d67bf3ee1f1455dd87acfbdbcc597056e7fb347a17688ad32fda7ccc3572da7677d7255c261738f07763cd45973c728c6e9adbeecadc3d961 ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566 b0304f20f37c3e358df87f624351350b036d2960ff1f0c36f8ccb0d2e12cd8f65c2fc27e197a6aadf5334af88e7bd6191159ab2b9bff52e485c52a0b17dcd0a23a58a85229e34c6333d3e8fbf826d8f9a2f04d7e08429388d464c02b28f4e41e +719bf1911ae5b5e08f1d97b92a5089c0ab9d6f1c175ac7199086aeeaa416a17e6d6f8486c711d386f284f096296689a54d330c8efb0f5fa1c5ba128d3234a3da856c2a94667ef7103616a64c913135f4e1dc50e38daa60610f732ad1bedfcc396f87169392520314a6b6b9af6793dbabad4599525228cc7c9c32c4d8e097ddf6 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee 8e3bfea5d6aba1aca2ebc144f76fed41b564198cd8277a1c9ade131762743d974a9d80801e4868ee7330676ea52f420f02bf754fbe92239e34c0d7bc05f9692c8673582e1dc2cb6bb93ea8db9994aac1df838aa7644a6cf9b0693ece6796ccea +7cf19f4c851e97c5bca11a39f0074c3b7bd3274e7dd75d0447b7b84995dfc9f716bf08c25347f56fcc5e5149cb3f9cfb39d408ace5a5c47e75f7a827fa0bb9921bb5b23a6053dbe1fa2bba341ac874d9b1333fc4dc224854949f5c8d8a5fedd02fb26fdfcd3be351aec0fcbef18972956c6ec0effaf057eb4420b6d28e0c008c 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd af2ef27d3b9156e5b30ba8f62755f5812318bd087887128c7143e458c1dda0d345f44d9eee305c4ad6a0352c92574fc90f8cb429a68b6d0f7b00e6ba4430a405d76327ed8ab093816225a218c43e1f3db6201769ff7c4852f67aa50a5b115a74 +b892ffabb809e98a99b0a79895445fc734fa1b6159f9cddb6d21e510708bdab6076633ac30aaef43db566c0d21f4381db46711fe3812c5ce0fb4a40e3d5d8ab24e4e82d3560c6dc7c37794ee17d4a144065ef99c8d1c88bc22ad8c4c27d85ad518fa5747ae35276fc104829d3f5c72fc2a9ea55a1c3a87007cd133263f79e405 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666 b9764c4d6b690bf6e75aba6df6641059aee0effdeaa7a17bb3589223b30102f05557620bac5acab46bef2f5aef925c7b0c4bd69b43694bd5b7b21a5aa1d7da33de8042663a682c3c0e2c6288b06e20e8039d7cac4e671c50b182ec628050cb58 +8144e37014c95e13231cbd6fa64772771f93b44e37f7b02f592099cc146343edd4f4ec9fa1bc68d7f2e9ee78fc370443aa2803ff4ca52ee49a2f4daf2c8181ea7b8475b3a0f608fc3279d09e2d057fbe3f2ffbe5133796124781299c6da60cfe7ecea3abc30706ded2cdf18f9d788e59f2c31662df3abe01a9b12304fb8d5c8c bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67 8d37e652b2ca4ab502b085867303f3cbed5fbad3d13763f986d63560f4bcc7645ceda79d386946acdf031329285567340715377114363f342cc992880f07a27354d062834a897790895c751ca4314c63ecd28e2a5b43981b05e3baa7b43bb4d2 +a3683d120807f0a030feed679785326698c3702f1983eaba1b70ddfa7f0b3188060b845e2b67ed57ee68087746710450f7427cb34655d719c0acbc09ac696adb4b22aba1b9322b7111076e67053a55f62b501a4bca0ad9d50a868f51aeeb4ef27823236f5267e8da83e143047422ce140d66e05e44dc84fb3a4506b2a5d7caa8 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9 933943fcedd0acbc4be2b451eff421c0c72f207566cbed89a79a613afe90820c6e6f589eae94d293e27504639fcf5aa60f9fc9e867546ed611a677bb707c7e493de189b0bf2a5eba951f926f0cb67fb5fc41d2861f0d537cd6fb135966c7603f +b1df8051b213fc5f636537e37e212eb20b2423e6467a9c7081336a870e6373fc835899d59e546c0ac668cc81ce4921e88f42e6da2a109a03b4f4e819a17c955b8d099ec6b282fb495258dca13ec779c459da909475519a3477223c06b99afbd77f9922e7cbef844b93f3ce5f50db816b2e0d8b1575d2e17a6b8db9111d6da578 f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce 89e54d2f4283f02493ad84d006635e65fef1b92c7752badce047a5c8f276327be03b5fd42b81de12f1e0b70adc7744ff042758efc0399d8bc8013eb1fa76cec57476c141b491d143d1adbea7a165eaf950da3cfbec02ce4e9c111788d9e654bc +0b918ede985b5c491797d0a81446b2933be312f419b212e3aae9ba5914c00af431747a9d287a7c7761e9bcbc8a12aaf9d4a76d13dad59fc742f8f218ef66eb67035220a07acc1a357c5b562ecb6b895cf725c4230412fefac72097f2c2b829ed58742d7c327cad0f1058df1bddd4ae9c6d2aba25480424308684cecd6517cdd8 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f 99fe8d5dc8f670beb8c6c2826f4bb77964cebc3d69fe3ea551a7edfeb963104aa8f054c465c35bd7b32db6484e7c362001c8ba8ef098504f9d2f57fbf6fee289f6960abb02147f7ff044e77eac3d7383788a8d6d809d0bbb4dd02da7333cb818 +0fab26fde1a4467ca930dbe513ccc3452b70313cccde2994eead2fde85c8da1db84d7d06a024c9e88629d5344224a4eae01b21a2665d5f7f36d5524bf5367d7f8b6a71ea05d413d4afde33777f0a3be49c9e6aa29ea447746a9e77ce27232a550b31dd4e7c9bc8913485f2dc83a56298051c92461fd46b14cc895c300a4fb874 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b 8ea98e8b26ad7c83addd0520c9778c057b0357b6079337b0737465dae199cdc9eb34a259c18369348b7423971a05239214d5d8b13df16c141aa483788cec5f0e4a6cbe87b09121e7575989338eb692ece90167f30e32d7da1d80e7b949abb2df +7843f157ef8566722a7d69da67de7599ee65cb3975508f70c612b3289190e364141781e0b832f2d9627122742f4b5871ceeafcd09ba5ec90cae6bcc01ae32b50f13f63918dfb5177df9797c6273b92d103c3f7a3fc2050d2b196cc872c57b77f9bdb1782d4195445fcc6236dd8bd14c8bcbc8223a6739f6a17c9a861e8c821a6 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388 80fa5b9d960d7023e836d4d420890fa8de5de017e1f6684b369854dcdcc761829403dfeddace564aa0fb121c38bd48e610300162cb76317d600d508e672e71d230f864a0d27e8ae93aadd80647d38678b72d3d493ea36aa45e033afa52a067d2 +6c8572b6a3a4a9e8e03dbeed99334d41661b8a8417074f335ab1845f6cc852adb8c01d9820fcf8e10699cc827a8fbdca2cbd46cc66e4e6b7ba41ec3efa733587e4a30ec552cd8ddab8163e148e50f4d090782897f3ddac84a41e1fcfe8c56b6152c0097b0d634b41011471ffd004f43eb4aafc038197ec6bae2b4470e869bded 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499 aa2e9e5ea656fcb94cba15974ac7e0266bc7117193245379a9f4567e3c8c3f18aa427500ec757fdb3d93c657585c635c18b16c80fd934afb1470f4624f667f295f532cd4c440ae1d24c85bf5dc8ae82cd5749d3711c259b7bebdf9ade8ef5386 +7e3c8fe162d48cc8c5b11b5e5ebc05ebc45c439bdbc0b0902145921b8383037cb0812222031598cd1a56fa71694fbd304cc62938233465ec39c6e49f57dfe823983b6923c4e865633949183e6b90e9e06d8275f3907d97967d47b6239fe2847b7d49cf16ba69d2862083cf1bccf7afe34fdc90e21998964107b64abe6b89d126 f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6 9170e8420be1819083bb3e4ce70c371aab8f5a12b1893bbba832126525c543f01ca5382995037b5faf1c6dc0087c306f09929f93ea98b1247571830189c2a4e83b54077552b6f4d199003c5644d54913d482d35563a04acb72ec744337e9ff98 +d5aa8ac9218ca661cd177756af6fbb5a40a3fecfd4eea6d5872fbb9a2884784aa9b5f0c023a6e0da5cf6364754ee6465b4ee2d0ddc745b02994c98427a213c849537da5a4477b3abfe02648be67f26e80b56a33150490d062aaac137aa47f11cfeddba855bab9e4e028532a563326d927f9e6e3292b1fb248ee90b6f429798db 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead 8866a135e98fd18200606de89d9b36a241f0046993291ff19d0decb93d78059309ba2ab1a6d58a4cccc71e84084e05191268a1f26c156a4e15431cca2e727da4e4103274ae724e831067bf83e8c84587d4fec89e9f78171f6aa5017fba04c71d +790b06054afc9c3fc4dfe72df19dd5d68d108cfcfca6212804f6d534fd2fbe489bd8f64bf205ce04bcb50124a12ce5238fc3fe7dd76e6fa640206af52549f133d593a1bfd423ab737f3326fa79433cde293236f90d4238f0dd38ed69492ddbd9c3eae583b6325a95dec3166fe52b21658293d8c137830ef45297d67813b7a508 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd 8d79266ca4032f57ee541ba36815a515e9a7f0403881ec90f29d4f5ced09ddb68171a4c1b8fc5c0dc648fe4270a25bed0340d23bb2bd17ac515b97c610978c565c60974cf57f8eb1a3efeb1e5941a0970f3067e874cf20338b8eb8eb0763e8df +6d549aa87afdb8bfa60d22a68e2783b27e8db46041e4df04be0c261c4734b608a96f198d1cdb8d082ae48579ec9defcf21fbc72803764a58c31e5323d5452b9fb57c8991d31749140da7ef067b18bf0d7dfbae6eefd0d8064f334bf7e9ec1e028daed4e86e17635ec2e409a3ed1238048a45882c5c57501b314e636b9bc81cbe 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117 ad8126bddb6c0e8be5d636ddfc91135d50af7897dc7c27779fc348c8f96766b68e911e9939cc87ed8dfd786135d5f90012f79ac150a8b3fba8f3af1d665b608d39b3ac20127ed8eaa11d7f4db38cee1f681f0355a61a24dd967332d4011983c4 +1906e48b7f889ee3ff7ab0807a7aa88f53f4018808870bfed6372a77330c737647961324c2b4d46f6ee8b01190474951a701b048ae86579ff8e3fc889fecf926b17f98958ac7534e6e781ca2db2baa380dec766cfb2a3eca2a9d5818967d64dfab84f768d24ec122eebacaab0a4dc3a75f37331bb1c43dd8966cc09ec4945bbd 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61 91728db35f136586d0c67728e5e846fd14d803bb695950e67a92d3871e527b23ed7ea2930ec0151e5747636c43d7b4f3145f9cc3f3fd4c33b8b7127d2effd01212881eee51c933aba2de1fb3fc50c498c145599deb6f21d9af94d121133efdf8 +7b59fef13daf01afec35dea3276541be681c4916767f34d4e874464d20979863ee77ad0fd1635bcdf93e9f62ed69ae52ec90aab5bbf87f8951213747ccec9f38c775c1df1e9d7f735c2ce39b42edb3b0c5086247556cfea539995c5d9689765288ec600848ecf085c01ca738bbef11f5d12d4457db988b4add90be00781024ad 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2 943abb1feb8c74d084297672a3c8fba06345ca85e0b42085587f3bb9e8130b8824cc0f64fe6798ede898e491c49dd6e114b8ccc181373d3cd885ccc52116fcf4515547edaf960a44f19727f78b834d28b4ffae1b4e75657603106114ff8ab1dd +041a6767a935dc3d8985eb4e608b0cbfebe7f93789d4200bcfe595277ac2b0f402889b580b72def5da778a680fd380c955421f626d52dd9a83ea180187b850e1b72a4ec6dd63235e598fd15a9b19f8ce9aec1d23f0bd6ea4d92360d50f951152bc9a01354732ba0cf90aaed33c307c1de8fa3d14f9489151b8377b57c7215f0b 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7 b2dfdd7f165138dc92202de2c975a0021d666fbbc7a1d1b45f67ea2dd08d0e7dcf81df2a388f8ff15d43d3ef6e40f4ec141348105e71ab2ab54f90006c69c8479876b2b866de995e4eb54bff8b21de7eb21959d76f77f79374283a9e92906b65 +7905a9036e022c78b2c9efd40b77b0a194fbc1d45462779b0b76ad30dc52c564e48a493d8249a061e62f26f453ba566538a4d43c64fb9fdbd1f36409316433c6f074e1b47b544a847de25fc67d81ac801ed9f7371a43da39001c90766f943e629d74d0436ba1240c3d7fab990d586a6d6ef1771786722df56448815f2feda48f 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870 8e2574af2f02023ee6359ffb3b2c4f97aeb751ca79c46ee166f0253af201cc5dd45f3b92de4b17ca9cf314c1d7fb6cd911639ad9f0ba8871c0ae64a6f827e2acac94acf00e292e2d98e9910bbb1b8877be2d394f27b6dba3f68277209f1e4eb2 +cf25e4642d4f39d15afb7aec79469d82fc9aedb8f89964e79b749a852d931d37436502804e39555f5a3c75dd958fd5291ada647c1a5e38fe7b1048f16f2b711fdd5d39acc0812ca65bd50d7f8119f2fd195ab16633503a78ee9102c1f9c4c22568e0b54bd4fa3f5ff7b49160bf23e7e2231b1ebebbdaf0e4a7d4484158a87e07 e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf 8cb065bcce18502733c0cc496875cbdc3686488710f39d172c424d0993641f6a037ecbd23a5d034082ba87f4e4865f690bc912844974d9c4a6444649165922c78a5f06d2a85c39d7191536898a3228613b2378b226b7b9a2308762f25bad7487 +7562c445b35883cc937be6349b4cefc3556a80255d70f09e28c3f393daac19442a7eecedcdfbe8f7628e30cd8939537ec56d5c9645d43340eb4e78fc5dd4322de8a07966b262770d7ff13a071ff3dce560718e60ed3086b7e0003a6abafe91af90af86733ce8689440bf73d2aa0acfe9776036e877599acbabfcb03bb3b50faa 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c 98fd8a15db24242740474230539a425491b532155ab420226692b1b801f5a035fa32c5445aceefc8ef6fdd161002e10410bfdb9d47e3eb35bf131db282b562d004891903ce91dd472877208cb02f2507227a73f7a629d521d3896349942d75f6 +051c2db8e71e44653ea1cb0afc9e0abdf12658e9e761bfb767c20c7ab4adfcb18ed9b5c372a3ac11d8a43c55f7f99b33355437891686d42362abd71db8b6d84dd694d6982f0612178a937aa934b9ac3c0794c39027bdd767841c4370666c80dbc0f8132ca27474f553d266deefd7c9dbad6d734f9006bb557567701bb7e6a7c9 f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9 82f058355e8167267f8055eff4feb5695e997acea538adc183395edd15b5bf6c701b6ec6223e2d66edd2ece401734f7a113b8436ab5d0693dbd3ce2c012353e0adb37395c4bb9218aabceb274e90795d007a3bcf6a485a091eb109b81fd871db +4dcb7b62ba31b866fce7c1feedf0be1f67bf611dbc2e2e86f004422f67b3bc1839c6958eb1dc3ead137c3d7f88aa97244577a775c8021b1642a8647bba82871e3c15d0749ed343ea6cad38f123835d8ef66b0719273105e924e8685b65fd5dc430efbc35b05a6097f17ebc5943cdcd9abcba752b7f8f37027409bd6e11cd158f f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5 97068a894a97aa951060cf8fe62606c3dda1640411701d0f784bf3dd96f553eab2037812b0cd4d8d1ce1f598f8d2ca9006ca8423a56932bfacd95cae7254060cd2ff0bb7291e5239573483717cd795ce1281abb97487c88eabd621e69a00db68 +efe55737771070d5ac79236b04e3fbaf4f2e9bed187d1930680fcf1aba769674bf426310f21245006f528779347d28b8aeacd2b1d5e3456dcbf188b2be8c07f19219e4067c1e7c9714784285d8bac79a76b56f2e2676ea93994f11eb573af1d03fc8ed1118eafc7f07a82f3263c33eb85e497e18f435d4076a774f42d276c323 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628 b2d10464a39db23fda346c78ae84da33480525b3457808eb129e4c9ecb9a06620a10a5fd3f471e40a734c2980168e4df006b51b80584b066871bf7b5bf82da2431942b72c2c703c160045051100d62be78df9f06c27f9953a486e6bf027d428b +ea95859cc13cccb37198d919803be89c2ee10befdcaf5d5afa09dcc529d333ae1e4ffd3bd8ba8642203badd7a80a3f77eeee9402eed365d53f05c1a995c536f8236ba6b6ff8897393506660cc8ea82b2163aa6a1855251c87d935e23857fe35b889427b449de7274d7754bdeace960b4303c5dd5f745a5cfd580293d6548c832 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49 997a2d963ddd5c49193887bd3b8a45e560ea931688ddf79f2786707f14b9c650277c6c0c1e2fd8809e48fdb92a7e81b813c85a3c3cd9527f44d9bdcad64873399ab17eae9c825936a9d68048fdf98dc5a21791928dc40739864912de6e0c46b4 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P256_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P256_blst new file mode 100644 index 000000000000..3c0d596fd910 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P256_blst @@ -0,0 +1,60 @@ +ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590 8d209ffe5262e9f0062893715ce159a5e4a78dbabdf69e556a5ec7f6bbc1d6f32b10bf71790c561c58512bc10f8346cc071044b2e10472d832d141dfcb437c5bdaade6770f7fcc66a8d030f8a2b38a7955fb57c4bf650468ce029d391bc801e0 +9155e91fd9155eeed15afd83487ea1a3af04c5998b77c0fe8c43dcc479440a8a9a89efe883d9385cb9edfde10b43bce61fb63669935ad39419cf29ef3a936931733bfc2378e253e73b7ae9a3ec7a6a7932ab10f1e5b94d05160c053988f3bdc9167155d069337d42c9a7056619efc031fa5ec7310d29bd28980b1e3559757578 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98 a7852cbff34fed03646c50e838ac0809175f57825376d5e5a8c02e977ba64534172aa6a3facdc579486d0eedaa61d9b114d9e5570de995b55425e70f7c84400a302fc53953435267ee1c8496548117ee0ead7246bd9b6ed5730bb0925f2344ba +b242a7586a1383368a33c88264889adfa3be45422fbef4a2df4e3c5325a9c7757017e0d5cf4bbf4de7f99d189f81f1fd2f0dd645574d1eb0d547eead9375677819297c1abe62526ae29fc54cdd11bfe17714f2fbd2d0d0e8d297ff98535980482dd5c1ebdc5a7274aabf1382c9f2315ca61391e3943856e4c5e616c2f1f7be0d a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870 9072480b2f8d79db4a5fbc2517d23c774c637e36b6914d20806b89dc6574a652c07bbd51dec60c7265fff20bcdec34c017f8cad5fc61c60493d8591c3002eda6d43343582ed7f5f26d0175b167c672918492e0370c84a0bde7fc6221ad26c450 +b64005da76b24715880af94dba379acc25a047b06066c9bedc8f17b8c74e74f4fc720d9f4ef0e2a659e0756931c080587ebdcd0f85e819aea6dacb327a9d96496da53ea21aef3b2e793a9c0def5196acec99891f46ead78a85bc7ab644765781d3543da9fbf9fec916dca975ef3b4271e50ecc68bf79b2d8935e2b25fc063358 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f 902df9f2dfe150b77d7807f4f3cca8e4ce2b82f19ea27382e6f2fe325e3c0ffc342ee5d0faacd87eb593baacc35842b515d8fa5bd40a3f0322e0c13fbe9563f719c128521556cd173b5c33f4b15f49e6be461595786a8fd7f67360b69a5bdc0f +fe6e1ea477640655eaa1f6e3352d4bce53eb3d95424df7f238e93d8531da8f36bc35fa6be4bf5a6a382e06e855139eb617a9cc9376b4dafacbd80876343b12628619d7cbe1bff6757e3706111ed53898c0219823adbc044eaf8c6ad449df8f6aab9d444dadb5c3380eec0d91694df5fc4b30280d4b87d27e67ae58a1df828963 daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d b29efcc3dacd4f41514e61b51cb37b65dbd39ba893c97ce2fbd6b6e99e3d2538063b01e0e6a472ebe9819893baed4c020c91ad0e94631bc348ec3ddbbe111ae5379210578261989d9448bb2887d30763e1335a9fadd0cc88b555b685c9654947 +907c0c00dc080a688548957b5b8b1f33ba378de1368023dcad43242411f554eb7d392d3e5c1668fad3944ff9634105343d83b8c85d2a988da5f5dc60ee0518327caed6dd5cf4e9bc6222deb46d00abde745f9b71d6e7aee6c7fdfc9ed053f2c0b611d4c6863088bd012ea9810ee94f8e58905970ebd07353f1f409a371ed03e3 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5 aadced6b9a7cac3eb992a194c9235e53d96d515630213de5f2c45c3e99d6e4b6eca2680cf4efcf517e7ee1061e0d86550eb33d43b1671acd84a52c52241466e92208799d25a2c85ac692011dc9af64bcf30c7f4156b1e3b5043dcbb88b3c2676 +771c4d7bce05610a3e71b272096b57f0d1efcce33a1cb4f714d6ebc0865b2773ec5eedc25fae81dee1d256474dbd9676623614c150916e6ed92ce4430b26037d28fa5252ef6b10c09dc2f7ee5a36a1ea7897b69f389d9f5075e271d92f4eb97b148f3abcb1e5be0b4feb8278613d18abf6da60bfe448238aa04d7f11b71f44c5 f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96 91736113a2bd597086a8866e7d0576af862fac220c8d0e3fb7ea6a1424578fa0b5f00bb362b733cd0550d39514065f2e0912b50ffde1d6b2b86e8abaebc6a00775958576d4569a50ba7b487fd0823884f204bb2f99690bcfb9fdc1bca3a491af +a3b2825235718fc679b942e8ac38fb4f54415a213c65875b5453d18ca012320ddfbbc58b991eaebadfc2d1a28d4f0cd82652b12e4d5bfda89eda3be12ac52188e38e8cce32a264a300c0e463631f525ae501348594f980392c76b4a12ddc88e5ca086cb8685d03895919a8627725a3e00c4728e2b7c6f6a14fc342b2937fc3dd 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d 8605c599ad549efb569d2ef7a4e73401e4e1a06c7f6d188fca20e350ca1c595f9ef13eb7491f66a92d480dcd82ee0a8d17c477d48bbfdf6e0a07ba60bc6588340c37784ce2782f9a42b204feaa451a79d7d72fc2a5b2f8beacd1f6ef4d2aa43e +3e6e2a9bffd729ee5d4807849cd4250021d8184cda723df6ab0e5c939d39237c8e58af9d869fe62d3c97b3298a99e891e5e11aa68b11a087573a40a3e83c7965e7910d72f81cad0f42accc5c25a4fd3cdd8cee63757bbbfbdae98be2bc867d3bcb1333c4632cb0a55dffeb77d8b119c466cd889ec468454fabe6fbee7102deaf 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9 90af1efe6e7a42a152362db5eb3307e191fcb71ae868d2fc8b3f20a0def9a1a7144939d4cc5b66fe7567913bf62a6cd204eb3e23a13d39f41bba6a204bd46c714aefaea07c5a975bfdfe77f24e4aa1d42fab914864e80f07b966f814d6d1e89d +52e5c308e70329a17c71eaedb66bbee303c8ec48a6f1a2efb235d308563cd58553d434e12f353227a9ea28608ec9c820ed83c95124e7a886f7e832a2de1032e78dc059208f9ec354170b2b1cab992b52ac01e6c0e4e1b0112686962edc53ab226dafcc9fc7baed2cd9307160e8572edb125935db49289b178f35a8ad23f4f801 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634 b1f29ea1e9b168f25ac6adb73277956d6298cb529bd7c9ef4b53505aad3ad47a36037218696c6e49e2e9d1f49ca8f5160c3a1ef3f3615c6ca1fa626fd2a8dbe49e28170844d342eb75969a3a8afb0dddb52de6a0e3a5bc1525c5b0ed32783c3f +d3e9e82051d4c84d699453c9ff44c7c09f6523bb92232bcf30bf3c380224249de2964e871d56a364d6955c81ef91d06482a6c7c61bc70f66ef22fad128d15416e7174312619134f968f1009f92cbf99248932efb533ff113fb6d949e21d6b80dfbbe69010c8d1ccb0f3808ea309bb0bac1a222168c95b088847e613749b19d04 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27 b1a6dbd1abf23320564fb269977a6ea53a7c5d30797775f0c8fb026580fd4e466c0b5527cdcbf15a58f5adf72bd9fe1800c230dbc16edd3b42999e1ca42d31ee299c2b368064d297deae30f7fcf8b9b47b1154a66f9375ba42719a296c76d586 +968951c2c1918436fe19fa2fe2152656a08f9a6b8aa6201920f1b424da98cee71928897ff087620cc5c551320b1e75a1e98d7d98a5bd5361c9393759614a6087cc0f7fb01fcb173783eb4c4c23961a8231ac4a07d72e683b0c1bd4c51ef1b031df875e7b8d5a6e0628949f5b8f157f43dccaea3b2a4fc11181e6b451e06ceb37 cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d 8d33ffe88bfbe0b2b0496d7ae19fb176e904bec797688b4dd52c3d0ae8cc8f334f94a187d87dcbbe97ba888c479cf86607227de09821eb0dd52e35122483f3571ac77ed90324708fcadee2b03297f04f9202f53b970dffcdfb65d4b03eaea1a6 +78048628932e1c1cdd1e70932bd7b76f704ba08d7e7d825d3de763bf1a062315f4af16eccefe0b6ebadccaf403d013f50833ce2c54e24eea8345e25f93b69bb048988d102240225ceacf5003e2abdcc90299f4bf2c101585d36ecdd7a155953c674789d070480d1ef47cc7858e97a6d87c41c6922a00ea12539f251826e141b4 b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c ac512584f5f78e2e5176ab097b9a0ce4a5dbc8bd676c4d33abdadbae9329ca03a54275c54bddf8ef2515bb75ffa5f6e207847216773d01eb759a3697544fc941772c8544d260c09f832e5417b685f0cfe412cd23d7e6103d0595c2c9e3d83608 +9b0800c443e693067591737fdbcf0966fdfa50872d41d0c189d87cbc34c2771ee5e1255fd604f09fcf167fda16437c245d299147299c69046895d22482db29aba37ff57f756716cd3d6223077f747c4caffbecc0a7c9dfaaafd9a9817470ded8777e6355838ac54d11b2f0fc3f43668ff949cc31de0c2d15af5ef17884e4d66a 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48 a7e2745f981bc48bed264bbf06d5baeea560b327ffcb157f1a3643c83200e569eebdf7a0d308aa3f3c40ddb8e6fabbb419b9f4079ed1aeace22650f3b7043a0e85658f7b8a29caf50d9b5543c573e35beba8410e0f33349bc488c03537756e7e +fc3b8291c172dae635a6859f525beaf01cf683765d7c86f1a4d768df7cae055f639eccc08d7a0272394d949f82d5e12d69c08e2483e11a1d28a4c61f18193106e12e5de4a9d0b4bf341e2acd6b715dc83ae5ff63328f8346f35521ca378b311299947f63ec593a5e32e6bd11ec4edb0e75302a9f54d21226d23314729e061016 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f b91685eecc37c1f2b4a0af9749faabef1257118704f7fa929fe371ad3722724bd428b31a2792f49ad1680d3d03668e3b0ba5dc46cbaa959ac8e4357b031dd6422fcb3614b316a7f6bd7413d9442322ff9d5f7abb0e392498daaf9f0edd47d12c +5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 aa1adfada7d382fac136eaa02eb50a0a0fb02daaf5e7db3f7d6f0520aeebd7d1c8d8878375350c671cf18646ce6a458c07fb201847cbfdf5ef39f9442ca492b67185b1c2dad2d7b9e82c26b349a9269ab05ac17bcbff4a180798f040ec6eb353 +c35e2f092553c55772926bdbe87c9796827d17024dbb9233a545366e2e5987dd344deb72df987144b8c6c43bc41b654b94cc856e16b96d7a821c8ec039b503e3d86728c494a967d83011a0e090b5d54cd47f4e366c0912bc808fbb2ea96efac88fb3ebec9342738e225f7c7c2b011ce375b56621a20642b4d36e060db4524af1 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 b932ba444ffad548577d2977625272da8e784577e7966e8d85b4c96c89dd4873d645529d2377e621d74ee7843d82499610c82a1c9082e7edfdd3d905b88910cef99f4b63656fc962f1b0f7f8fbff5efbbd9a339c662be72dafa41bca73ba78df +3c054e333a94259c36af09ab5b4ff9beb3492f8d5b4282d16801daccb29f70fe61a0b37ffef5c04cd1b70e85b1f549a1c4dc672985e50f43ea037efa9964f096b5f62f7ffdf8d6bfb2cc859558f5a393cb949dbd48f269343b5263dcdb9c556eca074f2e98e6d94c2c29a677afaf806edf79b15a3fcd46e7067b7669f83188ee e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef b144adea7f16868a83019332f330cfe4f1bd2f301c75afff4ce282e1c5c52b94e65f0130af04c4af742e1b5d9d7c810d033021846a33962f4f16c340dcd9557d4c5d7f977c0339268f7c3e6b495ec67f9a97244d4ef35a3d51a0515a0e73b726 +0989122410d522af64ceb07da2c865219046b4c3d9d99b01278c07ff63eaf1039cb787ae9e2dd46436cc0415f280c562bebb83a23e639e476a02ec8cff7ea06cd12c86dcc3adefbf1a9e9a9b6646c7599ec631b0da9a60debeb9b3e19324977f3b4f36892c8a38671c8e1cc8e50fcd50f9e51deaf98272f9266fc702e4e57c30 a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 b7162937548b8ec0f581e48db9b29267d666cff892665162c1d5e7c0a4122797d3406e5c5d565d666ba4fb6ed79a0546157d7629d86405aeeebd772bbc8bc14d6d1273b5f29c9287c01415a2f3cb4af4b555f17bc717c3275dfd3d1ba014f320 +dc66e39f9bbfd9865318531ffe9207f934fa615a5b285708a5e9c46b7775150e818d7f24d2a123df3672fff2094e3fd3df6fbe259e3989dd5edfcccbe7d45e26a775a5c4329a084f057c42c13f3248e3fd6f0c76678f890f513c32292dd306eaa84a59abe34b16cb5e38d0e885525d10336ca443e1682aa04a7af832b0eee4e7 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d 82f1188f95f6b79e01a93f8b1a79d4ccf092485c4ac9fbe99ab44919df3a69fe5109997c624abde487c571e658af91800305cf807891032f1e6d3e5d14f404cd9a5889168f08f4bc5c9f255253029b1ee05ba8a58511adf4d680631fa2e747f9 +600974e7d8c5508e2c1aab0783ad0d7c4494ab2b4da265c2fe496421c4df238b0be25f25659157c8a225fb03953607f7df996acfd402f147e37aee2f1693e3bf1c35eab3ae360a2bd91d04622ea47f83d863d2dfecb618e8b8bdc39e17d15d672eee03bb4ce2cc5cf6b217e5faf3f336fdd87d972d3a8b8a593ba85955cc9d71 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d 984d2594ddcad025fb7366bf5779779be65a802a9e01590fffd2d1492329fd2932a9d4de59b442daaaf983c92570f0d511170dfeae93ac54675a24f241882c9021aa0b9c77873e39687365a3b0727dcf2934680385d3d103ef91048676fb9c55 +dfa6cb9b39adda6c74cc8b2a8b53a12c499ab9dee01b4123642b4f11af336a91a5c9ce0520eb2395a6190ecbf6169c4cba81941de8e76c9c908eb843b98ce95e0da29c5d4388040264e05e07030a577cc5d176387154eabae2af52a83e85c61c7c61da930c9b19e45d7e34c8516dc3c238fddd6e450a77455d534c48a152010b 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab b82b9ecfb25f5d63f0ae4565e939a2370f0d6986991c7f61f4514596c87e307c5b3ecdbd2c4cd825b62cffb039c522eb0c50538ece97f6c3f42beb708acb705698bd43705bf52144785ed59dd83e6b00743ded5e3d254fbdfc73a5f033b0d3db +51d2547cbff92431174aa7fc7302139519d98071c755ff1c92e4694b58587ea560f72f32fc6dd4dee7d22bb7387381d0256e2862d0644cdf2c277c5d740fa089830eb52bf79d1e75b8596ecf0ea58a0b9df61e0c9754bfcd62efab6ea1bd216bf181c5593da79f10135a9bc6e164f1854bc8859734341aad237ba29a81a3fc8b 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a 85f63a82beb5873ea3cb8b1b68ffe7f55531dce3bdeb630259d9532aeff72b3717e545aa583d5ccf559c79ba1b2dac0504c31486b5641bb7231213a4514d1c7d596da7c83c98f3d1e12f1b1a0e454ac0ae2f6e00d230aed883682fad595ca88d +558c2ac13026402bad4a0a83ebc9468e50f7ffab06d6f981e5db1d082098065bcff6f21a7a74558b1e8612914b8b5a0aa28ed5b574c36ac4ea5868432a62bb8ef0695d27c1e3ceaf75c7b251c65ddb268696f07c16d2767973d85beb443f211e6445e7fe5d46f0dce70d58a4cd9fe70688c035688ea8c6baec65a5fc7e2c93e8 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 826d7716c691c41fddd036b86ece988c8432ce79d85f636d9e2cf66108345113fb9071adabaa05ebe55148c7364900b601c022ef329db60401b1601bbb093f43b03476ec7d7cbfc3845c84dfeada1b0d0095d0736b10f2899303bf6723a3b503 +4d55c99ef6bd54621662c3d110c3cb627c03d6311393b264ab97b90a4b15214a5593ba2510a53d63fb34be251facb697c973e11b665cb7920f1684b0031b4dd370cb927ca7168b0bf8ad285e05e9e31e34bc24024739fdc10b78586f29eff94412034e3b606ed850ec2c1900e8e68151fc4aee5adebb066eb6da4eaa5681378e f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 8683903071df448a73870e4c4906c92fb2c37e9ddaed447a832c632b88d182c0f54786a18ab7244b043ab591d90a24110177248a9859321de5748dcbcb12d51b81f6f75cd0300ff4028f2e203637c2475dba88aa0078cf2490e12b33b15e8bf8 +f8248ad47d97c18c984f1f5c10950dc1404713c56b6ea397e01e6dd925e903b4fadfe2c9e877169e71ce3c7fe5ce70ee4255d9cdc26f6943bf48687874de64f6cf30a012512e787b88059bbf561162bdcc23a3742c835ac144cc14167b1bd6727e940540a9c99f3cbb41fb1dcb00d76dda04995847c657f4c19d303eb09eb48a b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 b6b750c1fa06336fc665ca61e463780f032cdbc52a79ba9e023e52c643bcbe5214f13bad09971890c7426202b1cdffd5090b9dfe509030dadf00dc5653047bcf634c07bc200c4caedaa5d9f6e185aa1db3bcd0c1841de7694accb280a4de98e1 +3b6ee2425940b3d240d35b97b6dcd61ed3423d8e71a0ada35d47b322d17b35ea0472f35edd1d252f87b8b65ef4b716669fc9ac28b00d34a9d66ad118c9d94e7f46d0b4f6c2b2d339fd6bcd351241a387cc82609057048c12c4ec3d85c661975c45b300cb96930d89370a327c98b67defaa89497aa8ef994c77f1130f752f94a4 d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 83feb9d3c7483ef1b20d90012f523d6b5b6e42381d6d26a03b91ee03e8f8aeb0df50045e7666026240560628be77731e0261f273cc407ae0ac81c22bce12b935d1e52f6550ddc58b804d34ccad2a1917558e7e316557f5fc1f1589e2462be80e +c5204b81ec0a4df5b7e9fda3dc245f98082ae7f4efe81998dcaa286bd4507ca840a53d21b01e904f55e38f78c3757d5a5a4a44b1d5d4e480be3afb5b394a5d2840af42b1b4083d40afbfe22d702f370d32dbfd392e128ea4724d66a3701da41ae2f03bb4d91bb946c7969404cb544f71eb7a49eb4c4ec55799bda1eb545143a7 b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c 8899500ff0b717d346aa020bd91e6494a3dff191c4cb06172366e0fcd9eb85c956bb5b9ea30cde4500a23fed704120d6175ffe5ba0e394c6c2cc3d4dd2a8da02567cf014a024aba623900f3064bfa4d99da2ce943d6198018519513526fe4ad5 +72e81fe221fb402148d8b7ab03549f1180bcc03d41ca59d7653801f0ba853add1f6d29edd7f9abc621b2d548f8dbf8979bd16608d2d8fc3260b4ebc0dd42482481d548c7075711b5759649c41f439fad69954956c9326841ea6492956829f9e0dc789f73633b40f6ac77bcae6dfc7930cfe89e526d1684365c5b0be2437fdb01 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 b7cd7b9a5e0daf0774852f70d1a7e5dd57b9f04f0cf01f2807afe7c38dec619e58857598a09a60e71fa729e6a1c854a716bbb06c668c59479a3256d7f097ea6baa001210cb8d5a35b22950b9b092eab4eb5591f0cbc9fe741b5265318df3a26e +21188c3edd5de088dacc1076b9e1bcecd79de1003c2414c3866173054dc82dde85169baa77993adb20c269f60a5226111828578bcc7c29e6e8d2dae81806152c8ba0c6ada1986a1983ebeec1473a73a04795b6319d48662d40881c1723a706f516fe75300f92408aa1dc6ae4288d2046f23c1aa2e54b7fb6448a0da922bd7f34 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 89ee544daa255e31257808ec15a13f866e7ab84a400b37611f1347b2080d2f16eafe87bfcb0bb27a461608145d858448122b8dbf4e75628001bef39f565cbe86cd8e1e3c4e5641efae7605bef46d2f4da176009bd341dffec0227514100e6883 +e0b8596b375f3306bbc6e77a0b42f7469d7e83635990e74aa6d713594a3a24498feff5006790742d9c2e9b47d714bee932435db747c6e733e3d8de41f2f91311f2e9fd8e025651631ffd84f66732d3473fbd1627e63dc7194048ebec93c95c159b5039ab5e79e42c80b484a943f125de3da1e04e5bf9c16671ad55a1117d3306 b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced a837543a8f2b64c2a821cd83723ccc996bd219ab5af7d0ad45209198a6e25613b4c32fa2a6565732ddfdabe22450de170dff6d4e60b887e3ee8b79d56730c89579bbea6276e976af0b788456bf6a2144805a4f306469bbe69e26efe257cac28d +099a0131179fff4c6928e49886d2fdb3a9f239b7dd5fa828a52cbbe3fcfabecfbba3e192159b887b5d13aa1e14e6a07ccbb21f6ad8b7e88fee6bea9b86dea40ffb962f38554056fb7c5bb486418915f7e7e9b9033fe3baaf9a069db98bc02fa8af3d3d1859a11375d6f98aa2ce632606d0800dff7f55b40f971a8586ed6b39e9 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181 8d6b6ae5287b70a05c9df4b9d161e45109b71c9b4b43251c4e950a03e3e6151564a748ba585462135464d7302796293707e1b679483648910c83b6052274a99ead4cc9288fec8125af164d3bcea50cb2eb70d5620a25e922190a9fe2685743e3 +0fbc07ea947c946bea26afa10c51511039b94ddbc4e2e4184ca3559260da24a14522d1497ca5e77a5d1a8e86583aeea1f5d4ff9b04a6aa0de79cd88fdb85e01f171143535f2f7c23b050289d7e05cebccdd131888572534bae0061bdcc3015206b9270b0d5af9f1da2f9de91772d178a632c3261a1e7b3fb255608b3801962f9 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431 92eaddc2337f8d18cc99df78c09b1a4588c71c1a755880f5d3b44d62ee70dff93058ba072b2e5e3719ae7b9da336c8480a066d274408f663fb108ef1639bfd18f8cce5b4bbe8e8663ca22d16beadd6619cf91262527f47730135ba499a3d126c +1e38d750d936d8522e9db1873fb4996bef97f8da3c6674a1223d29263f1234a90b751785316444e9ba698bc8ab6cd010638d182c9adad4e334b2bd7529f0ae8e9a52ad60f59804b2d780ed52bdd33b0bf5400147c28b4304e5e3434505ae7ce30d4b239e7e6f0ecf058badd5b388eddbad64d24d2430dd04b4ddee98f972988f 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd a3d3abd25abfcd623fcb7b5c2d9cc6788aa20caded417317fc51079973845cffc000a01e332f3bb501cd935bc62b875f0e296e118a3a9e35431e54ce420cc2b7c929c4436c70da45fc86d40dc5ec39fea95955d96f00368a05b68a916cf4b988 +abcf0e0f046b2e0672d1cc6c0a114905627cbbdefdf9752f0c31660aa95f2d0ede72d17919a9e9b1add3213164e0c9b5ae3c76f1a2f79d3eeb444e6741521019d8bd5ca391b28c1063347f07afcfbb705be4b52261c19ebaf1d6f054a74d86fb5d091fa7f229450996b76f0ada5f977b09b58488eebfb5f5e9539a8fd89662ab 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de b3503ae85c9c95d58903608b599763bb3f620a7400a3cd9150ee07c068312bc6ca9570ddaf820a4adef6d83d06707c9c0f252fde5d0641f6c043b9d3816b0f44b427cad017a1f4158068fb95a521cacf6f945002f359210a70578a2766ec6c4b +dc3d4884c741a4a687593c79fb4e35c5c13c781dca16db561d7e393577f7b62ca41a6e259fc1fb8d0c4e1e062517a0fdf95558b7799f20c211796167953e6372c11829beec64869d67bf3ee1f1455dd87acfbdbcc597056e7fb347a17688ad32fda7ccc3572da7677d7255c261738f07763cd45973c728c6e9adbeecadc3d961 ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566 b4e9a0ecf406a0ed4adf0775d5601f88373169cfff158440d7c747795c829f0f6387ab0651abc1ca40d9f1e33586929716209312a134177be0126da885e72387d467f6509912ac6ddb53bc52294331bb18c84687ff4b503d6dec08c241b48617 +719bf1911ae5b5e08f1d97b92a5089c0ab9d6f1c175ac7199086aeeaa416a17e6d6f8486c711d386f284f096296689a54d330c8efb0f5fa1c5ba128d3234a3da856c2a94667ef7103616a64c913135f4e1dc50e38daa60610f732ad1bedfcc396f87169392520314a6b6b9af6793dbabad4599525228cc7c9c32c4d8e097ddf6 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee a2fc2dc8ce2a8a216e6b725df279f13bf2e7df6f12f68593fbeea4b63731c19acc1c78721815d888e6e1ac6ca45386ad07b8d86a0efdbeeb6489fae4488e752d5d040cb7fa6117110e2fe35caca282090905c8402d0083ca41bd149f6fa0e899 +7cf19f4c851e97c5bca11a39f0074c3b7bd3274e7dd75d0447b7b84995dfc9f716bf08c25347f56fcc5e5149cb3f9cfb39d408ace5a5c47e75f7a827fa0bb9921bb5b23a6053dbe1fa2bba341ac874d9b1333fc4dc224854949f5c8d8a5fedd02fb26fdfcd3be351aec0fcbef18972956c6ec0effaf057eb4420b6d28e0c008c 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd b2f36f4600f526bd91b38f591461d5d83906f89ffcd6a5cc9bda9bfb0921f6ccba655d9e1103149742103eabcaf1ad1411f1bd6f3d5e8f07b04d290039bc8ac8eab28a7f5465fe61a7535b59d3d13be097f577a316ed9549adee789b5a1e6c62 +b892ffabb809e98a99b0a79895445fc734fa1b6159f9cddb6d21e510708bdab6076633ac30aaef43db566c0d21f4381db46711fe3812c5ce0fb4a40e3d5d8ab24e4e82d3560c6dc7c37794ee17d4a144065ef99c8d1c88bc22ad8c4c27d85ad518fa5747ae35276fc104829d3f5c72fc2a9ea55a1c3a87007cd133263f79e405 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666 94c7015e308b49d96391c4c81b99165b0949364376c55799b42b6e9929fb23efc811f65b305e6c02231fb8e8a0d9607c197ec2efff2005591bd9405389ebb55e3ad8c8eeff6cc892233bb4bb3b57189b078af5666dfa2e879825555e25b99602 +8144e37014c95e13231cbd6fa64772771f93b44e37f7b02f592099cc146343edd4f4ec9fa1bc68d7f2e9ee78fc370443aa2803ff4ca52ee49a2f4daf2c8181ea7b8475b3a0f608fc3279d09e2d057fbe3f2ffbe5133796124781299c6da60cfe7ecea3abc30706ded2cdf18f9d788e59f2c31662df3abe01a9b12304fb8d5c8c bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67 92968f055f96d8564dff207cc7656a46bfce1ffb85ae4ca02ef85623da36e84788db5856fc78483e8e4c0a8c0763c43a0d93014143b8824168b1bfc47a6ce5fcd86ad9e1523a729b83e0b1155753149c126b259ce9286adbc1d46b03e0a62cfa +a3683d120807f0a030feed679785326698c3702f1983eaba1b70ddfa7f0b3188060b845e2b67ed57ee68087746710450f7427cb34655d719c0acbc09ac696adb4b22aba1b9322b7111076e67053a55f62b501a4bca0ad9d50a868f51aeeb4ef27823236f5267e8da83e143047422ce140d66e05e44dc84fb3a4506b2a5d7caa8 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9 b90d837dee9b20f490ab6d278b18d21600fcd17fe7c7e90cd8db41bf3970c18842ea644ac930cb03e221a383e07ac4b90e058a9c378b46b66ef2a8800bce089c53e401bf33965a7816fc70790dd3ecdff831b7c99d0c18f1cd95a91814e178a4 +b1df8051b213fc5f636537e37e212eb20b2423e6467a9c7081336a870e6373fc835899d59e546c0ac668cc81ce4921e88f42e6da2a109a03b4f4e819a17c955b8d099ec6b282fb495258dca13ec779c459da909475519a3477223c06b99afbd77f9922e7cbef844b93f3ce5f50db816b2e0d8b1575d2e17a6b8db9111d6da578 f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce 90da3bc1ceef50ced619bff5fb1bd2d675c4ce44dc81c6fb42790d464ed590bcc432cf831908dbb9b746c13f474fab8f0a156ee2620d0026ac64a75533d343dd7fab7bfd09382c9179d103ddf9a7ceb9fec8f52457ba90636d0056a78f3e8d7a +0b918ede985b5c491797d0a81446b2933be312f419b212e3aae9ba5914c00af431747a9d287a7c7761e9bcbc8a12aaf9d4a76d13dad59fc742f8f218ef66eb67035220a07acc1a357c5b562ecb6b895cf725c4230412fefac72097f2c2b829ed58742d7c327cad0f1058df1bddd4ae9c6d2aba25480424308684cecd6517cdd8 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f 8052c39a44c0bbb55f55c84944358ab0ff36544c828918a4f22cb15cdecaaf28ae102fdf07e85966e38c9f310f0688c108411fdafdc059e89b3aed44d62eef58a64ad818c7ca57bd1ac6bf075d70b598aae43d3f2b621d442007661120e2befb +0fab26fde1a4467ca930dbe513ccc3452b70313cccde2994eead2fde85c8da1db84d7d06a024c9e88629d5344224a4eae01b21a2665d5f7f36d5524bf5367d7f8b6a71ea05d413d4afde33777f0a3be49c9e6aa29ea447746a9e77ce27232a550b31dd4e7c9bc8913485f2dc83a56298051c92461fd46b14cc895c300a4fb874 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b 9786fddd108a7080531ec8dbebbbb52365f7a27da73005c513057a5600772f54d91b6227c7b44a732f075a446bbf772f08f4e96237122d07c1f699078e008bcd84041753e243489ac468bfe467202b2f90ed8ff7fe7c26f51ab89532ad607950 +7843f157ef8566722a7d69da67de7599ee65cb3975508f70c612b3289190e364141781e0b832f2d9627122742f4b5871ceeafcd09ba5ec90cae6bcc01ae32b50f13f63918dfb5177df9797c6273b92d103c3f7a3fc2050d2b196cc872c57b77f9bdb1782d4195445fcc6236dd8bd14c8bcbc8223a6739f6a17c9a861e8c821a6 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388 b742ddf4b9989f10f19151de86ef23629f537350748668ca6483f831fa533da2b63d530d47fd22baac603c5d63fbe1f003500340df05ee37915ebd4a50fcfcd2c5d81907c76f8006e206495b30b6dd44f6b7f71ae3c1ebc2d9d9842f03941758 +6c8572b6a3a4a9e8e03dbeed99334d41661b8a8417074f335ab1845f6cc852adb8c01d9820fcf8e10699cc827a8fbdca2cbd46cc66e4e6b7ba41ec3efa733587e4a30ec552cd8ddab8163e148e50f4d090782897f3ddac84a41e1fcfe8c56b6152c0097b0d634b41011471ffd004f43eb4aafc038197ec6bae2b4470e869bded 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499 b23eeda198b48428ba3d2d7a1c3669820923bdf5681dbab67d53edc6451915ef9376a242c01f3769f2701ac6c20d796a080b5b69c9888e0ecae1bec32fd9494ce89f6835a7042a30fd6dd3f5ff8a7fe5df946dde3f3973a2a35ee58bd89e62b6 +7e3c8fe162d48cc8c5b11b5e5ebc05ebc45c439bdbc0b0902145921b8383037cb0812222031598cd1a56fa71694fbd304cc62938233465ec39c6e49f57dfe823983b6923c4e865633949183e6b90e9e06d8275f3907d97967d47b6239fe2847b7d49cf16ba69d2862083cf1bccf7afe34fdc90e21998964107b64abe6b89d126 f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6 b378024a2f7da9c196e199fad019000610a427e93b8a50398e212a9496a87dcb1202e40a6ebc3c1bd0e30e18fc67a97510b88aa7dd49c3c7a491a0f3efbab66c8d418491a251134e9935b597c6ab2481a599ef14fd9c00aa45841b61c5329618 +d5aa8ac9218ca661cd177756af6fbb5a40a3fecfd4eea6d5872fbb9a2884784aa9b5f0c023a6e0da5cf6364754ee6465b4ee2d0ddc745b02994c98427a213c849537da5a4477b3abfe02648be67f26e80b56a33150490d062aaac137aa47f11cfeddba855bab9e4e028532a563326d927f9e6e3292b1fb248ee90b6f429798db 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead 9085aabd661119f5ace9969491549a19ee06738f8b9933c75534773b602dae57bbd102848e055c40f381a7752ad241040c967f741fe66dc45bc363f06136c867ab6ae587f1d35622492b75c5a3f8fb08bd1848f86be329dd0daf3e50041ae21f +790b06054afc9c3fc4dfe72df19dd5d68d108cfcfca6212804f6d534fd2fbe489bd8f64bf205ce04bcb50124a12ce5238fc3fe7dd76e6fa640206af52549f133d593a1bfd423ab737f3326fa79433cde293236f90d4238f0dd38ed69492ddbd9c3eae583b6325a95dec3166fe52b21658293d8c137830ef45297d67813b7a508 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd 938109a872edc48f2d8bb202662336c42c6a46a9d4a0905069c163bca5e7cf9eec2f90578610bcdd187192deb299db8902a6c50516d06ddd233f8fdd9700ef00a1e5a0234afacb143d9e5f09f0bbdab2dff58422d31367a07e118ec4dbeece34 +6d549aa87afdb8bfa60d22a68e2783b27e8db46041e4df04be0c261c4734b608a96f198d1cdb8d082ae48579ec9defcf21fbc72803764a58c31e5323d5452b9fb57c8991d31749140da7ef067b18bf0d7dfbae6eefd0d8064f334bf7e9ec1e028daed4e86e17635ec2e409a3ed1238048a45882c5c57501b314e636b9bc81cbe 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117 8c10fe9a309156ff70a0ca71b3909eac9d976eea3dd921d0311c64a62922799357528abb7bef15f83f6303f39f7628d71273a5eae85d32b415a106b6d1ba825984faf0d47b1a9a604a8323fee8385aae0a4d102b53225f27a23d68c8bb3f801b +1906e48b7f889ee3ff7ab0807a7aa88f53f4018808870bfed6372a77330c737647961324c2b4d46f6ee8b01190474951a701b048ae86579ff8e3fc889fecf926b17f98958ac7534e6e781ca2db2baa380dec766cfb2a3eca2a9d5818967d64dfab84f768d24ec122eebacaab0a4dc3a75f37331bb1c43dd8966cc09ec4945bbd 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61 8a94c51623cec9a6fc316000beffc61671258ad3fe3f5c558db362be82e0b924ccb00beef2258e781290423d8e34265b19fb70c7c344610c44eba0d8b39637ec40761b9ab0be5fc3dc029ffd3e4d9a881d252ec28dfdc036b49334288a4e6cce +7b59fef13daf01afec35dea3276541be681c4916767f34d4e874464d20979863ee77ad0fd1635bcdf93e9f62ed69ae52ec90aab5bbf87f8951213747ccec9f38c775c1df1e9d7f735c2ce39b42edb3b0c5086247556cfea539995c5d9689765288ec600848ecf085c01ca738bbef11f5d12d4457db988b4add90be00781024ad 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2 acc289ba3cdc9a6b5227b71778fd7151755dfe838b91aa8aefbeca23669dffc05ee187f61b4db14f1f4781ea3ad220d102ced55f95f1a9e87bafa04a4d58547c632e2cd19ef107666885bf41a4ecb2000c9b4e35d1245c9f5c75279851104fb2 +041a6767a935dc3d8985eb4e608b0cbfebe7f93789d4200bcfe595277ac2b0f402889b580b72def5da778a680fd380c955421f626d52dd9a83ea180187b850e1b72a4ec6dd63235e598fd15a9b19f8ce9aec1d23f0bd6ea4d92360d50f951152bc9a01354732ba0cf90aaed33c307c1de8fa3d14f9489151b8377b57c7215f0b 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7 b43f17d39eb1b00bea08cd2e4c1f4025b03a6a2c1fb2f6e9fcbd70bfb05de2ab584bc094428197c6ed0d7ef487885b9e0da9d9a038c95710ca97cdb7cf0f47040368ea59c3ffd7b2de99bf3a22ecabfe85f6352df08468ec283b413169daf124 +7905a9036e022c78b2c9efd40b77b0a194fbc1d45462779b0b76ad30dc52c564e48a493d8249a061e62f26f453ba566538a4d43c64fb9fdbd1f36409316433c6f074e1b47b544a847de25fc67d81ac801ed9f7371a43da39001c90766f943e629d74d0436ba1240c3d7fab990d586a6d6ef1771786722df56448815f2feda48f 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870 94da6cffbe1037fb66a3fffd589fbcae6b5923b7ae28774518ad73ad380ebd7a19ca834b7d6f82954bc04f6492c092bd13f93a5a3d3f205f9bb41fdc003c16202b3ee901cfc0fd17d9130c87671abf719e9163328873111b3fb49c6495113da1 +cf25e4642d4f39d15afb7aec79469d82fc9aedb8f89964e79b749a852d931d37436502804e39555f5a3c75dd958fd5291ada647c1a5e38fe7b1048f16f2b711fdd5d39acc0812ca65bd50d7f8119f2fd195ab16633503a78ee9102c1f9c4c22568e0b54bd4fa3f5ff7b49160bf23e7e2231b1ebebbdaf0e4a7d4484158a87e07 e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf b1fd03cb5922d86fda003242e7373107681a426d6d6810d6f37aaf57534d78b748054c3964ec199e01b16219ad6ec730144fddb2398ae5ea91bf91aedaa14f1d70ceabc0d7f217035ac07985396ea6b8986f3c9537d50b7ce91b3bff1241e0f0 +7562c445b35883cc937be6349b4cefc3556a80255d70f09e28c3f393daac19442a7eecedcdfbe8f7628e30cd8939537ec56d5c9645d43340eb4e78fc5dd4322de8a07966b262770d7ff13a071ff3dce560718e60ed3086b7e0003a6abafe91af90af86733ce8689440bf73d2aa0acfe9776036e877599acbabfcb03bb3b50faa 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c af31cc87da63b777ac0d7f7526e9c77f04b9dda080804beccd059d0943066aaba7e94605994f9b57f4504d50d4f57b1b19d20b793508dc0717eaf29dae0bff7bfcd5ebfd59e548f210307e85f43a06d65eab8e75ccc46428800fed7483ee3768 +051c2db8e71e44653ea1cb0afc9e0abdf12658e9e761bfb767c20c7ab4adfcb18ed9b5c372a3ac11d8a43c55f7f99b33355437891686d42362abd71db8b6d84dd694d6982f0612178a937aa934b9ac3c0794c39027bdd767841c4370666c80dbc0f8132ca27474f553d266deefd7c9dbad6d734f9006bb557567701bb7e6a7c9 f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9 a06f9cd2f5c56970bcdd1042bccbcb8e7c69630e8cc641a40b448d18f5521cb68cd42afb57edc51f538f8344b539e7300055150816b955657c098bae7b09d445103512eb3b0305ba3381861d44ac88a03639ed5f5d44334d2c16e77386eb32c5 +4dcb7b62ba31b866fce7c1feedf0be1f67bf611dbc2e2e86f004422f67b3bc1839c6958eb1dc3ead137c3d7f88aa97244577a775c8021b1642a8647bba82871e3c15d0749ed343ea6cad38f123835d8ef66b0719273105e924e8685b65fd5dc430efbc35b05a6097f17ebc5943cdcd9abcba752b7f8f37027409bd6e11cd158f f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5 b08d865576be535f6b99d7c53338533cc1084d6e2cd8f8a98b3c3b61fae2a3cc8117aac7099c49ebc9ed16e447e9878a1462b134676107c163a7d1b328b03c63ae5d7c3bfb0c5e6d875abe3b2c8210eddeb59978f6aa807efea5fedea1febc58 +efe55737771070d5ac79236b04e3fbaf4f2e9bed187d1930680fcf1aba769674bf426310f21245006f528779347d28b8aeacd2b1d5e3456dcbf188b2be8c07f19219e4067c1e7c9714784285d8bac79a76b56f2e2676ea93994f11eb573af1d03fc8ed1118eafc7f07a82f3263c33eb85e497e18f435d4076a774f42d276c323 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628 a93e057d46029267010370cbb042ec050692d89912d8093e4afb20baf38da4a7c02f994c74d6e9394810c4d7af78b76e0298ac9032521d8afa77ff5f22f9cd02f5d7b5d1c1458a48bb1a76c82a99549f7e19fd9b6116aadac2091cd89824c4ff +ea95859cc13cccb37198d919803be89c2ee10befdcaf5d5afa09dcc529d333ae1e4ffd3bd8ba8642203badd7a80a3f77eeee9402eed365d53f05c1a995c536f8236ba6b6ff8897393506660cc8ea82b2163aa6a1855251c87d935e23857fe35b889427b449de7274d7754bdeace960b4303c5dd5f745a5cfd580293d6548c832 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49 881978d2eb0797d94c2345603f3beccd10ae382696582e751bf9b3a63478484894a229eee5506c187c62dca5aa66cb9712415a8e544add4a638362424f1450b4aefafaf831fbb30b6141ae00e48167aeb2c63e7791170d151cd2b433d0b886da diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P384 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P384 new file mode 100644 index 000000000000..a1ff47625aa4 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P384 @@ -0,0 +1,60 @@ +39f0b25d4c15b09a0692b22fbacbb5f8aee184cb75887e2ebe0cd3be5d3815d29f9b587e10b3168c939054a89df11068e5c3fac21af742bf4c3e9512f5569674e7ad8b39042bcd73e4b7ce3e64fbea1c434ed01ad4ad8b5b569f6a0b9a1144f94097925672e59ba97bc4d33be2fa21b46c3dadbfb3a1f89afa199d4b44189938 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727 96126914786dde5af4ebc7d320aec6750e281ca44fbb6811c58c12f01d1a702bf9dc7701588e86123b63721b4edf6fb10b72f0b569e24a500ea5aa8095ba14092a159b44ca6aefd93ec0d43ee19e36459bfed84a1b161a25257baea9dee18653 +5a3c80e608ed3ac75a6e45f6e94d374271a6d42b67a481860d5d309cc8b37c79cb61f1716dc8aa84cb309ef9d68eb7fc6cf4b42333f316a5c30e74198c8b340926e340c5de47674a707293c4aa2a1a2274a602f01c26b156e895499c60b38ef53fc2032e7485c168d73700d6fa14232596a0e4997854a0b05d02e351b9d3de96 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246 85d09e48fecb55bef29a52172aa28fdb3ae8ca1a35eb364446519c4c32ca50f1c84b3847ec17136497e042127ec2da5310ead4208024b4ca192efdbbe44201c58a337260c914830f5d7bc0b470b54f82e6837019053568a58af96fb043ec44ac +e7d974c5dbd3bfb8a2fb92fdd782f997d04be79e9713944ce13c5eb6f75dfdec811b7ee4b3859114b07f263846ae13f795eec8f3cb5b7565baff68e0fdd5e09ba8b176d5a71cb03fbc5546e6937fba560acb4db24bd42de1851432b96e8ca4078313cb849bce29c9d805258601d67cd0259e255f3048682e8fdbdda3398c3e31 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83 8b40dbe218bf8d006e5f0dece1a30ba89c909d163400f1d965d8742ccc226d2b614aa73fa8fa029ac766804cd3c7d55105b992fb8965ec048f87a44c875bfcd497dca086b2f383bc9fd854d8d3113803bbc95338988d064d46c88a64988a777f +a670fda4d1d56c70de1d8680328043b2b7029633caf0ee59ffe1421c914bb937133d5a0f9214846b2e0b350455a74c4ab434c56de65a17139bb8212bf1c76071a37536fa29348f871dbb26baa92eb93d97e923a6d2ffd9be25cbc33075e494e6db657bd8dc053fe4e17148d8cf6e2058164f2b5766750eb01bbe7b361cdb848c dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659 8cc28370c52b54cfabee654de20bbd8b17afba6daa8d0fb551a5169ae5c1ba268a6f070b7e45abff67beb2a38c634d10047b52d4987952f16155808c042da6ac6acbe6e448f5ec88c07c245f867861d2261766f1cfecd8087f6e7be3e44eeb8a +7843f918fe2588bcfe756e1f05b491d913523255aa006818be20b676c957f4edb8df863c6f5f8c15b3b80c7a2aa277b70d53f210bdfb856337980c406ea140e439dd321471407f374f69877b2d82367eed51e3c82c13948616dcb301d0c31f8f0352f2846abd9e72071f446a2f1bd3339a09ae41b84e150fd18f4ba5d3c6bfa0 df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718 952ac0bc52ef8ea66eb0b0fed8e12652d5dbbbd4c8462b58c84c7e78361770427df7df429c80981d9e24a6011f65b6c3031a3c0b480ad724a087fa0393ce68373e3b4deee6ed164a4ba6c06322d1eb9133f6e22b0eb43f33fb7c3ecdc29c3e70 +caa83d5ab07febbd2e0fe2d63738b9b7b8752594bea7aaf50345b3d2f316653a8c9222f2b7877b64679e9573e81461a426029e45b8873a575094a1d572e0d32a9f0a9c6bcb9a2868543b7d8bbe4a69a09e7321f05f8366cced1b72df526f895b60aed2c39c249653c7839538770d4e5f47d3926ec0d168ab6a1af15bf1dca1f7 ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f aee76f2fa52e677d2e5d63afc1f37a6c3d004863d4a1fc02c7afe2c549ef1e679540d4fc2a6fe956369667a8ab1d659e06c8c754699ae642082bf3eaeb0bbdf611a939cca8ebf4f43e2823fcb4baeb2cb4425a921714949b5601647660088d54 +594603458d6534974aeeafba919c4d0f4cb6843a3af41204bbb88aeb2fca2772d305163dba863da050aabedbaf89db521955d1715de95bbcef979ecdc0c976181ece00355385f8a8f8cce127c9eac15ce3e958a3ed686184674ec9a50eb63271606ee7fdcb1323da3c3db8e89cad1fb42139a32d08abcfbf0d4ccfca18c89a86 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829 a9f31fe9dfdaa7de9b807557df7e071b9c670136eb4f1849130ee5e3ed87c42b61bcfdf1441b8e094b689fad2b61d9090ce82ca28114b746418486ac00036d402964ae82f5584d0d3b5cf4530beabd224d1d6d50d6b75aa9dbe4fe4e88630662 +733252d2bd35547838be22656cc7aa67eff0af0b13b428f77267a513c6824c3dbae533068b6817e82665f009560affcfe4b2ddb5b667a644fc1a42d24f24e0947e0dc50fb62c919bc1fe4e7ded5e28f2e6d80fcf66a081fb2763526f8def5a81a4ddd38be0b59ee839da1643eeeaee7b1927cec12cf3da67c02bc5465151e346 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1 a7bc9a500cc2d9becdfc06ad15bdad7a78b161bb3dc88e006d24b6ce312eb2ae470af923829b41cda99cad5c1308d5e6145b5b12a7532378affa1fd948b4f3ba13c5b0f1c143c92ef49e9ea03be6cfd084c474ff26d919e53f8a0a32ffb4e931 +5a182bd174feb038dfae3346267156bf663167f713dea1ce936b0edb815cd9b8c8e4d411c786ba2494a81442617255db7158b142e720d86c9b56680fb9efd4298cdd69079a28153494c42a24251c7ad42ecf7e97eabc1b3997529b2a297cbad2474269b87a0b1e385f2d7f8b6eb8d1cd75eaf7e91d1acbecd45d7b2bfbbe3216 e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d b6448089ae433453a341989e287e5bbe03cd088a928c45edda006ae41f774a03e9044ceb6387b4c9e6e475641b38a5f2137927716cf274fa4dfa30b73f30a9e595d7f098524bae5cad969a660bc06e0c00be7cf005a939701f2b2679f5c8ef6c +aaa99fb1c71340d785a18f6f668e898c25cf7a0ac31d13c5b388b7233408493a5a109af6d07065376b96f4903df7aba2b2af671a18772bb0472490d1240cde28967680727dd4acd47e0308920a75da857a6eeedee5b6586d45dff3d8a680599665aa895c89dd7770b824b7dee477ac5e7602d409d3cc553090c970b50811dbab 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead 8a3269d0142f7b978831ac9c68dd3df4767fb9741f753c72f9208b1e95e69959897905ca34e3bb132435b5eb9cd5daa31444537288a94e5e836cc4628fdad192a9bef614e99a6ff9921372b53197b5c08c52701c55a719c423fecdb6641719f1 +1fadfa8254d3a0b82d137cfdd82043d5dc1fef195d5297b09cc5cfb061f59c933451c0dc2a11b4037f34f88dacb803251f8880c4b72585c3c196e6fb23484ca43a191f8e41b9b9a37e2e6fcaab6738c3c62d1c98e1c620bb788b7b51a04f998a510efdba0d3418622fe8ce203b3fcd553b9b4206365a39031797ad11e49745ec 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0 8867bb01ab173dd9b45d864e087ca99b5a53ef748221a0ad3dbc75b17611e77646a55ba424a9c7c4ca7bb46db2854c2e00cf70b71701452d878e3f743a7f9847da0b8820fd6e0133070d4cbb5d6de07b65178c60bb3f7c5774fe926fff6d0cb0 +9ecb6f5ed3ba666a8536a81ef65012c2cb8b433508798d84708abb06dfb75503886f78384fb8c7a4d2d49ef539d9b8a0b60938c7f07471dda91f258b0d99691b38a8403a2bb3f956bdfd09baba16d9b6877097a9b6213481b47a06e139d23ec7abad5668d21f912fdb70d31bb9adf9b3ce80e308252fa81a51674f88d02db72b f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1 ad238a49702a7050374ac7dc33e79d99e29e0e3686c9be621fa3b30581cc2384257d9b345015d8c68aabed33eabec89a18f8ba3ee0650ffc14bb1d24a721291f5f4daa38c0ce8b6bb7dca81fe97582d9c5f4225cb3b3987e649985dec7a50719 +e55bfca78d98e68d1b63688db12485578f36c489766f4d0bfaa0088433ff12133aaca455805095f2e655940860958b3ead111d9070778ee3bbf3e47e43d9eba8b8d9b1fdf72f793fcde2bcaa334f3e35fa2cca531ea7cf27fe9ccba741e38ac26129b2d612bf54a34e0ae6c166c0fef07fcd2b9ac253d7e041a500f7be7b8369 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb ab82e681f1daa519eb359859551c593e2163d050a37a03dab4ae6bfaacc8d35f128b245cfd2d0d5b981f2fd1a6b41c8d0d9ae9086e74f946c3336b85288e7f8908fa4a360a75af1626d02b202fe70f26e3df3e3fc5009ea8c4324c8ad1d1af49 +02c6b3c83bd34b288d96409162aa4ff114e9d134bf948046eb5ebcc0c7fe9dfceadda83ed69da2fac00c8840f6c702a3fc5e6959d70f7e8af923e99e4937232ae3b841ffefd2e62fab3671a7c94a0281b8ea5bc176add57c5c9b6893fe7f5d48ce7256b96510810c4e046168a3c5be9843b84d5268a50349b3444341aa5490dd 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6 8d36442beb584667d80ba135da1c96b02eadb447ab8fd3d5aa0e7343e6380456ed74f7eb6eefa08ab0917be3ec2f1afa032df7c5844b3b1b77be5d974f39020f596f79e0753e6a01fa3a2a0ad57656af2b05c13e7d892034ea524bc31178c198 +94f8bfbb9dd6c9b6193e84c2023a27dea00fd48356909faec2161972439686c146184f80686bc09e1a698af7df9dea3d24d9e9fd6d7348a146339c839282cf8984345dc6a51096d74ad238c35233012ad729f262481ec7cd6488f13a6ebac3f3d23438c7ccb5a66e2bf820e92b71c730bb12fd64ea1770d1f892e5b1e14a9e5c cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd 874caf7db0088609b203be3fbaf7dfe2b01c0c814ae8e6e349e28daf554cae712087c2f588154d058b5c45ff1a13ce8403ac6cf6db84ee9fdfdd750e99b46593b086d25d2ce26a083be216609d199cfa7e41d2e1af20b9a60ccbf3459e389b27 +663b12ebf44b7ed3872b385477381f4b11adeb0aec9e0e2478776313d536376dc8fd5f3c715bb6ddf32c01ee1d6f8b731785732c0d8441df636d8145577e7b3138e43c32a61bc1242e0e73d62d624cdc924856076bdbbf1ec04ad4420732ef0c53d42479a08235fcfc4db4d869c4eb2828c73928cdc3e3758362d1b770809997 c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b 843d7903f71bb243ae6b4da5b64801a007fa24f15652c6835aab60f4eff87c14698fe859a0d10515e004dc576b2de571159ceb4191e5c092bc17e4f82d5888d3b124e87407eba540bab1a59995180717c4dd2bc54bd9c097f7242088053bae7a +784d7f4686c01bea32cb6cab8c089fb25c341080d9832e04feac6ea63a341079cbd562a75365c63cf7e63e7e1dddc9e99db75ccee59c5295340c2bba36f457690a8f05c62ab001e3d6b333780117d1456a9c8b27d6c2504db9c1428dad8ba797a4419914fcc636f0f14ede3fba49b023b12a77a2176b0b8ff55a895dcaf8dbce 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9 81dbdbc6b2b56d4cb3c5c53db0a08ae24d1c66cd8a7465a75c97d50c232e099365ac313b12a0de04b1fbde3d50dd08f906d8957905ee83f17165d8574734ac598b602d2d3b73295fc8d5a5ae8eea2d6172238736b4a68e078b0f1fb37b21dabf +45e47fccc5bd6801f237cdbeac8f66ebc75f8b71a6da556d2e002352bd85bf269b6bc7c928d7bb1b0422601e4dd80b29d5906f8fcac212fe0eaaf52eda552303259cbcbe532e60abd3d38d786a45e39a2875bce675800a3eaeb9e42983d9fd9031180abd9adccc9ba30c6c198b4202c4dd70f241e969a3c412724b9b595bc28a d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f afa5d71f7380617404211498ad5c6065781dc667233fc6e967ab84cfb3c2fd20d83e5c7193aab83994dac3dc587b5c5414cd5b5ef99f2950bcafb964ebaa8c4c43c348d63294f8890fe4400416195ca31fd3f87e6c8f0cd603ca38d021c4f481 +c33ff63b4e6891e00b2349b3f2907c417ca355560544a91e24a7a0ee260d6850aeded29fc0176b6039ca6187e8333391047cceaf14b1077df8f147dad84d36b2dac5666dc2f69dc9b58b88cc73956efdb3b47f91831d5875051c76b0c4e9fc087012a1f03eeee85d6745b46aa50bd9cb0110c2c94508765cec162ee1aa841d73 d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3 b6a2da7bfadc4891ddb052bd4528463a4e174775abbc667a5fcfd9ac42365c7eb9f5afc1995350a80e76dc24cc2ac87603128a97b34f1211024db9300525c7f1dff9e8ebcc444caa02104b44e2815d9db9ab16ec96da60d4dcbf84a769b04c69 +f562f2b9d84b0e96a52532c3b43c39c8018c738bd8dc3797a7de7353971b2729d522d6961b1f2e4df3f6a4bd3653e6d72b74fc0dba92ab939c4b542e994e5db6dd8ed4f56f651e699052e791237ae1f552f990ad156226ae8f7bf17fcbfa564f749604f97e9df0879d50985747d981422a23040fe52f5ec74caf1d4aaad8a710 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93 b64da4ad47fab96d0bba400f41419c9a6ac8c7b72b433e5d14245c192fd6b3b04cb1aa068e8f8e61c58b838208c8cce6173249a7a25e61071e049ad62bc6d35eecf9f681c72103ac0da073df56c1ea54b02008628cf9a5a4cd392339811c8d83 +ace953ae851f571d71779aa120915f27450b236da23e9106f8d0756abdd25861937941228d225d5fb1aa1b1ebf759b1e326aeb3b6cd0cd87edd2ab9f6a7ad67b63d2c501d6a550edb2e7c9d216cc8af78dd33546af64d00abed4d0d2cfc5c9a7b5a055dbe8f7547902d185cf46937314832bc5c602419a82ab83dbd9d3bd5aff e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1 83142030cc82ca9717abdc654ab0c05afc43ba1187f75463d8c60d61715d8b3de9b8e23cd20cedc2e3b13cd05e18fd2c13eb1aa3f00cbfa6cbeb1047ad64d51398b17580649f2d5cb47393732ed74a5b766bc8446fd01280e1c1b699a2aa8edf +9635ab832240be95301bedb94c5aec169eedc198cbbdfedcf41e9b586143d829b4597a6b2a81902828332825fd84a785f187a3894e21bd99d22c4f94dcf34453fc052f15ec64d1447c932cb38fcdd30b7be851963409c11881438cbaad7e96f9efbde317f2235d66af804477a5dfe9f0c51448383830050ecf228889f83631e1 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960 ad6a56fdd945faa3faa8f2effcd3dbf1a52fc23da8ac247720cbf4274ca79fb5f0d394aca37b07c194056efb66765a2613ed78c57281530e826baeb95f7d499781a12269adf8fe78eaa2d04228349338eb097dd5ccefbda928797f2480d57211 +d98b9a7d4fe9d0fd95de5056af164a8b7882cd34ab5bde83a2abb32dc361eb56a479a3a6119db3b91dcad26a42d2206749567f0d97c34a981a91fc734921821a429f6a53401743a5c406ba9d560f956203abc9d1f32f1a13e7d7b290f75c95fdbf857ea597021461c06a3aacfa554ede3d69e4ff03bbbee5b7463ec77de2b3b2 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57 8a4bcc1e9ceb87c6890ad6c9222b71f0e1fe9c6461cd627798ec9970c2733a9d0022d0b87a1e89a77c639e4fabb51bd403276dca916b52fc462de1ce615029b486dc179c36ed76c2b97fb84840303f20ebaf40f8493196854e516607e5ff27b6 +1b4c754ac1c28dc415a71eac816bde68de7e8db66409af835838c5bb2c605111108a3bf13606ed5d8ade5ed72e50503e0de664416393d178ea4eec834d8d6f15039847b410080fd5529b426e5aadd8451c20ebd92d787921f33e147bcbeb327b104d4aab1157fc1df33e4d768404b5ccb7110055c2508c600f429fd0c21b5784 a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1 b93ffe8841dffb410685fc0b133b15313373e02696a60d89bd123fd877a85940f520935382e615ad01460b1f4a62c8140d050d2d4a2a9aab0f13188143d0ca8fdadaa4c13e5e38a1a1a26a9d2d6023d6fedc04ac13ac7dd2303f2d6bdab41984 +3cd8c053741dd9f974c6c5dbf8a1e5728e9b5eafb1cbcfc3452f5fbbda32a8c7564dee157e8d902c52514361da6d972934a56b3276e2a9379e328e24282e0db697c5bc29090fc489ec46b7b188325dd4e96494c250de0f4a89fe2ccf919eaefcfb50c288113e6df92714feb7f46e0822478c796d0f4ff3447a32997e892693ce 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3 a4a53f67fa61638579803ab12f290fac3756b3b81962192acf7f1d8b0d5a138113f4240f7acc0e73428686434ffb5cb30da0b4aff2950f552c3fe8088c6e30f8b6927f19f82a28cca0d33a0950be0e8d9744e014e1f8d49e36f328d3a183fc80 +ed955dda6d9650124804d3deb6aeef900e520faf98b1ef6f14efcada7ca2433f09329b70897305e59c89024d76e466b28fe02cb2a9b12e2478c66470259d7c282137a19e5a04ffadea55245c0f34a681593fedc42931d8b3321b3d82e9cc102cd00540ad311ec7bd8c9d06db21bea4ca3dc74d98931ae0d40494aefc2345132c 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907 a5a7378ef2ca82f00f640cac61c226dd7d138aa84d615783512160590b1ea9f97f940c8de0d05c446c2eeea9c4a819d216f0ecd61716b440d48565037050273be73fcfb22e65efa0e0b22b0ae04c473d4cfec3a261b6044d871c9e0f221e9f01 +ce395b001da2a58e49691605d44af4206306f62f561bf2394060d2a5591a350277166bed043819035f1e60b5b3fb5ae113ddd0473f8ef6b2b050c472c2a264e1d8b3ca82a4f158c40f2d78d9ce5e5ea6de243f2e1f13f47f6c6f403b270912c81c636be35b396ca58468b3fb60aa83911d61441a0528d973bc31f965d4059080 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245 960052712aba456982e229088db18f690ff471786ed1cb8c8bd2267c529863c4eb1752b800e4fcff1c70767829e7fedd15057f5485aebaf9efdcb2910022a872994db73d4aaa348de9aab47b0cd0382f28fb39023738d00ad8871210cb252ed9 +ffefe316455ae4ffdb890bb804bf7d31424ea060ecacff419d0f7134ff76ad434063c0ec0f8bb7059584d3a03f3625bb9e9f66ace1a47ac4b8f3e76fc7c420c55edb1427d1fa15b387ad73d02b0595c4e74321be8822752230a0dcfb85d60bfa186da7623a8ec3eb1633f0a294b23ae87216b14ccee9ef56418dcfab9427371e 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7 b21135f762405f62faf1673a61415402d45cbd545f6ecfbec20d35801349aae5e823254a8f2ac2d5d0fc1b6617cb8d46141cb077c8fe1521175516b8add74fa0b24eccf1ce6115397cb1a43b546240faae1d34997ba4172b99535b1e54c1475b +304bccb718b3a9e12669913490cc5bcc1979287b56c628fad706c354241e88d10e81445a2853e3fc32ece094ba1abc3fdcab61da27f9a0fca739371049fed462ee6b08fa31cde12720f8144a6f00ce9b1a7a6eadd231f126717074b4efb5c72ce673ca5859000a436f67a338d698759f12c461247c45a361fb6cb661fdbe6714 d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5 984d7e0fad42bc1f4aed0e9fccb52fd8f8549bca786be697a3b785719365325c08d77054303c6233d751cf49aa9b2a411285009846aa1e60bbe971554d7df4a0c26eb18e2dea00bb01d5f0673f04a7f19e3c96d31e24bfba6db1d22270eb7117 +64f9f05c2805acf59c047b5f5d2e20c39277b6d6380f70f87b72327a76170b872bfe4b25c451602acfb6a631bb885e2655aee8abe44f69c90fb21ffde03cef2a452c468c6369867dfd8aa26ac24e16aa53b292375a8d8fbf988e302bf00088e4c061aa12c421d8fe3cbd7273b0e8993701df1c59431f436a08b8e15bd123d133 b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224 aca22c0f44c1af7f352284434a06726996c82ac97a2ea382978e4e342bb7098b243ad196c3a67a52d5d7fd57722501c012e4422ee342ecb7dbc7fc9071e2a34b59beedd129c0dbc333a4e42c2ff30c4ada2461a51c1e4ae3a5982a1a066f5dd8 +6b45d88037392e1371d9fd1cd174e9c1838d11c3d6133dc17e65fa0c485dcca9f52d41b60161246039e42ec784d49400bffdb51459f5de654091301a09378f93464d52118b48d44b30d781eb1dbed09da11fb4c818dbd442d161aba4b9edc79f05e4b7e401651395b53bd8b5bd3f2aaa6a00877fa9b45cadb8e648550b4c6cbe 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 84831f92d342a2f327ea9a0280b7d8381136026a4389e64be31cd1fad8a7f13eb3fa07d4759d8234b725fec691f4763813e78db2e9c5c7fdea97466a53f90d03bce55fa2d2bcff673854ed808704c8a517119fa2c95374e037144c85f43fc096 +d768f41e6e8ec2125d6cf5786d1ba96668ac6566c5cdbbe407f7f2051f3ad6b1acdbfe13edf0d0a86fa110f405406b69085219b5a234ebdb93153241f785d45811b3540d1c37424cc7194424787a51b79679266484c787fb1ded6d1a26b9567d5ea68f04be416caf3be9bd2cafa208fe2a9e234d3ae557c65d3fe6da4cb48da4 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 adaf85c0678eb75fc869982c9b5b938768b95e389c2c5ae60201bb6181b846243d5124bc30009f34046ddb20d68ca5db139d800ba41b95fa73c7b1923a7735a943cd4ea1558bdeed9f7246f25343b0e907efdb86022257fd9da4a0a88d02f446 +6af6652e92a17b7898e40b6776fabaf0d74cf88d8f0ebfa6088309cbe09fac472eeac2aa8ea96b8c12e993d14c93f8ef4e8b547afe7ae5e4f3973170b35deb3239898918c70c1056332c3f894cd643d2d9b93c2561aac069577bbab45803250a31cd62226cab94d8cba7261dce9fe88c210c212b54329d76a273522c8ba91ddf b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 92f6848097e8b86f365ec662b75fe2e4de9b7c0e37d13068b258a04d36022cc99981c7c86202c108ca75d5629fe820e21461aaeb66295697f9f2eb6a96a8b38471754032c25891a3cdd5701cb215d2f4a2406f63c6125aacb90d7ddc5dcd047f +b96d74b2265dd895d94e25092fb9262dc4f2f7a328a3c0c3da134b2d0a4e2058ca994e3445c5ff4f812738e1b0c0f7a126486942a12e674a21f22d0886d68df2375f41685d694d487a718024933a7c4306f33f1a4267d469c530b0fed4e7dea520a19dd68bf0203cc87cad652260ed43b7b23f6ed140d3085875190191a0381a de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 93633d31f80bde97f161e0807c2551a8dbfe59fc4853ee915110c668a65e666c3f22ef0b674529204880a1d338f1b6d716c148565d6d385918e9010c03d8dcb902a07f105775f5abc13935162acbe26a7d3acd763ca806b7d7fdcc8f522e9e4d +7cec7480a037ff40c232c1d2d6e8cd4c080bbeecdaf3886fccc9f129bb6d202c316eca76c8ad4e76079afe622f833a16f4907e817260c1fa68b10c7a151a37eb8c036b057ed4652c353db4b4a34b37c9a2b300fb5f5fcfb8aa8adae13db359160f70a9241546140e550af0073468683377e6771b6508327408c245d78911c2cc 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc b8f92d4785be3b262dc80eaaaf96c6ac0a88e0ddca34cb663cdee154e80ad6f3dd0577fbe5b5bb95f47604dfb1c551f6080189fe5d1306cb743478a265c6c741887e6c56291e5db754bce0347e155a6e117525bacf00d51d1733e80ef01b3449 +00ce978603229710345c9ad7c1c2dba3596b196528eea25bd822d43ca8f76a024e29217703dd0652c8a615284fc3edcc1c5ad1c8d5a8521c8e104c016a24e50c2e25066dcb56596f913b872767e3627aa3e55ec812e9fdac7c2f1beade83aef093e24c9c953982adf431a776880ae4583be158e11cdab1cbca3ad3a66900213d 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 82070db2b760e408d6ebaf8ec66425293cf57b52f970c9443789127db38acc48d8ab4a70e1b0b41bf44179893668ff4a1414fdadf5dd7871d70ed0d39d464d95417d1cb57c411b4e6a9fa98f874c2e91e398187a24ffa7da1337713f6bbba4af +54a255c18692c6162a46add176a0ae8361dcb8948f092d8d7bac83e160431794d3b9812849bf1994bcdcfba56e8540c8a9ee5b93414548f2a653191b6bb28bda8dc70d45cc1b92a489f58a2d54f85766cb3c90de7dd88e690d8ebc9a79987eee1989df35af5e35522f83d85c48dda89863171c8b0bf4853ae28c2ac45c764416 ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 b80596d5899b9de9ff10732bb510bb2804c270258e51678fa89148473b085eef4928baf26ae092c38d2a67708675a08410b094d8b0d84dbda12508095b7de474b21621ccc762eb90db1d16c09a1c2cb77563f0dfcb3bbcf92885f8ea478fb0fa +692a78f90d4f9d5aee5da536314a78d68c1feabbfe5d1ccea7f6059a66c4b310f8051c411c409ccf6e19a0cbd8b8e100c48317fe8c6d4f8a638b9551ce7ee178020f04f7da3001a0e6855225fb3c9b375e4ed964588a1a41a095f3f476c42d52ffd23ce1702c93b56d4425d3befcf75d0951b6fd5c05b05455bdaf205fe70ca2 adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 a864bd5de8fd96c00f305e177fb8b857392a6d6a3b550a3159f4ce059a1ccf7d7ad1fa55cf8996b86096ba834955996d03cfbe07687735bf183c736d6eb7f73c8eea9725bdd5bd9f6bf18c5ac3bafdb51a0bca2c38d3d5b41f960e1fc4ae3774 +3b309bb912ab2a51681451ed18ad79e95d968abc35423a67036a02af92f575a0c89f1b668afe22c7037ad1199e757a8f06b281c33e9a40bab69c9874e0bb680b905d909b9dc24a9fe89bb3d7f7d47082b25093c59754f8c19d1f81f30334a8cdd50a3cb72f96d4b3c305e60a439a7e93aeb640dd3c8de37d63c60fb469c2d3ed 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d adf825d911e57b33dadce9c0550ccec86cada5c2750451b2ba8f2b9ccbf6250c980e9cd7e8c568b2a215377c80c276d0057139df1ec6cb3544003d9587a63f0a44768dd848038877d69414a38d2530d9beb9bf24dc5dbea9f0e553e2be0a85fa +f072b72b8783289463da118613c43824d11441dba364c289de03ff5fab3a6f60e85957d8ff211f1cb62fa90216fb727106f692e5ae0844b11b710e5a12c69df3ed895b94e8769ecd15ff433762d6e8e94d8e6a72645b213b0231344e2c968056766c5dd6b5a5df41971858b85e99afbf859400f839b42cd129068efabeea4a26 e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 a757ca6c1cae7fe8dd343c305475aaaca4c3f375e8418c30ede6a3d2b2ba23154f32f157879baa3c8637236309485d72158a81fc3f09b5567e9ba541155dc8c4974c40afbb1fa38c7b80323224358796a4955420322511501ba669adedbc2368 +cf4945350be8133b575c4ad6c9585e0b83ff1ed17989b6cd6c71b41b5264e828b4e115995b1ae77528e7e9002ac1b5669064442645929f9d7dd70927cb93f95edeb73e8624f4bc897ec4c2c7581cb626916f29b2d6e6c2fba8c59a71e30754b459d81b912a12798182bcff4019c7bdfe929cc769bcc2414befe7d2906add4271 d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca 84494df62d64d3317e8119d3db15b50241ac2a886b340d4927e79c3e436931b11293d05bb04747c61ef92fd8d197e82813a5eb00204b01f479ca2661f258a057c14188664ac6ec647dbd8d501986281c15d3527f68cd3837f386660dbf214957 +d9b5cf0b50416573ff3c63133275a18394dd4326be2041e8d97e6e4e3855a4a177e9d26dfd223fe8aa74564edb49bd72de19916fb6f001f44530d5c18e2c332bce1b7415df5927ece5f3824f34d174b963136b53aef1fb78fb0c06a201a40b2db38e4d8216fc1e392a798c8ab4b3a314496b7f1087804ebfa89bf96e9cdb80c0 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d a84f3f73d4e60c5869a4c62897775dedb2850b090fc8fab186b23ea41669024508c5c8c47c79afcd12948cb9d3f6a91712c4ba83f8559c3f784aad59ad4d773d13e346272769310b34ee8ceb8001d407bef38956bfb1265c57fc5d5c810ed783 +9e4042d8438a405475b7dab1cd783eb6ce1d1bffa46ac9dfda622b23ac31057b922eced8e2ed7b3241efeafd7c9ab372bf16230f7134647f2956fb793989d3c885a5ae064e85ed971b64f5f561e7ddb79d49aa6ebe727c671c67879b794554c04de0e05d68264855745ef3c9567bd646d5c5f8728b797c181b6b6a876e167663 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 8a2d3145b66f9d0beb60a6ac6d07487e633f0ae2232bb21c9a64f60df4d93c07905befcc313c21f7b1926212869f14a219d0960894a04300128420b530650652071ecff0f4fccc95b23c69cac2a49ad282a13c7f1ca56b5f2ced98f9a38037be +0b14a7484a40b68a3ce1273b8a48b8fdb65ba900d98541c4bbd07b97e31bcc4c85545a03e9deab3c563f47a036ff60d0361684ba241b5aa68bb46f440da22181ee328a011de98eff34ba235ec10612b07bdfa6b3dc4ccc5e82d3a8d057e1862fef3def5a1804696f84699fda2ec4175a54a4d08bcb4f0406fdac4eddadf5e29b ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 8ebadfe82759a0e952894c898b6e83e4980f172e547e80a3855717a109ffcb5ce78a12495800079cf545763c5417c725103607a11fc678ad91d5c9ad82994811278ae515d051a07ecfd998f0a48fa6cab40b8dd59ffedd37723288dd799bbf6c +0e646c6c3cc0f9fdedef934b7195fe3837836a9f6f263968af95ef84cd035750f3cdb649de745c874a6ef66b3dd83b66068b4335bc0a97184182e3965c722b3b1aee488c3620adb835a8140e199f4fc83a88b02881816b366a09316e25685217f9221157fc05b2d8d2bc855372183da7af3f0a14148a09def37a332f8eb40dc9 e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb 90bf1b7ad7205890382481facbc52a2d3e4478c81b0372945b805b20f529c43ed326456307a6c385ef04ad43c7bc45de00f96b9d2d2c6b1f1f5eb3d4cf39badb1b7a2a107b98af93242d6b981a0848ffb947956ecd80463d32981e36505728ed +67d9eb88f289454d61def4764d1573db49b875cfb11e139d7eacc4b7a79d3db3bf7208191b2b2078cbbcc974ec0da1ed5e0c10ec37f6181bf81c0f32972a125df64e3b3e1d838ec7da8dfe0b7fcc911e43159a79c73df5fa252b98790be511d8a732fcbf011aacc7d45d8027d50a347703d613ceda09f650c6104c9459537c8f 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c 91dba04f4c13bea4430ff0899709a32c2d951badc6e6b4cc66e9c7507b82b2b2af4f8c9f33499193186c37e20ccd668f029cb75a8f72caf8a52455c9b936b2bd8f90924d4efa898b31dd2024b0264c8933b01df4af60e19f54bbb0301e36d93a +45db86829c363c80160659e3c5c7d7971abb1f6f0d495709bba908d7aa99c9df64b3408a51bd69aba8870e2aaff488ef138f3123cf94391d081f357e21906a4e2f311defe527c55e0231579957c51def507f835cceb466eb2593a509dcbee2f09e0dde6693b2bfe17697c9e86dd672f5797339cbe9ea8a7c6309b061eca7aef5 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f 954013a20adc37f13eb424093ab5b1fc26962fcbb7c6fcd979e62f64a72adffd5490bd7ae3cbed4ae3493d811d1b5f3016b80ed35f83ffab609691c451405146b2ef970e101706066d56df3081b50aeaae5304b00ea71312a7ab96f54a83c004 +4672fce0721d37c5be166bffa4b30d753bcf104b9b414db994b3ed33f36af4935ea59a0bb92db66448b3f57dad4fc67cef10ce141bf82c536be604b89a0bc0e8bca605b867880049d97142d30538fc543bd9d4fab7fdbe2f703815cdb6361beb66acff764bc275f910d1662445b07b92830db69a5994857f53657ed5ca282648 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7 848e105d445e19ff1be77202a0f1fa75c615b1a4c0e8726702408f61f63244b3dd73bed8c6c145dadb070ae7e081cc420300b23a9f09ca9ea243df9839d80d6a3f7f10ad071ccafba750b35426f66ad88b28f6099b2abc24f6cc989860878d1b +9ae48fdd9bfc5cb0f4d4761e28b2073bda05a3e3fe82c212e66701dc4573cc67a829b0f82d7520b1bf11db0c6d1743822bbe41bb0adbd7222aa5fae70fbd1a31f2d4453a01c81e064d775388468be96f6063f8673b7b8d4455fe1bd4c801ad5e625a015eaa4a1a18da490d2af8642201eaba3c611cbd65f861d8e19ca82a1ee6 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf b51817abf0de3819ba8f13133d9b39dd6e4023c0a14bb2a2bc97ec7c4a6481c4dbcd0918d2bc9c3beb085b6b2e38d24f12293b82af39a8b195207ae2a84fe2084d403512d243651c162731fea2d0c44494299391ab21e5d14281ec7282c20a2c +817d6a110a8fd0ca7b4d565558f68b59a156744d4c5aac5c6610c95451793de2a756f774558c61d21818d3ebeeeb71d132da1c23a02f4b305eccc5cd46bd21dfc173a8a91098354f10ffbb21bf63d9f4c3feb231c736504549a78fd76d39f3ad35c36178f5c233742d2917d5611d2073124845f1e3615b2ef25199a7a547e882 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b b2a4678b0a2a0f2706946cab22fe18de955afb59f2b1d5c8757fa53975137312123aab7516340ab47b57750ab124183f1816afa6bf7bcaa6beece6b1ca1cdb2a220e6daa4047cb7379ef5ab477d9f9ceffb7cd650e4dfa12929ee21a4361fc70 +464f10ec6fb229a51db5fd0e122f2cb8a9a022117e2987f4007bf5565b2c16aba0714e2e3cdd0c100d55ac3017e36fc7501ad8309ab9572aa65424c9eb2e580a119c55777676ec498df53ef6ae78fd8a988130ee0e6082bf1ef71cd4c946021018a8ca7154d13b174c638912613b0bdb9001c302bf7e443ad2124ab2c1cce212 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69 a38037ef3470be7dec9e5e216eb8693cf7d2d1e2d65adbbc101141651d8367d0adda8567bab0fe45d7561653aef6db4504fa93fe0b781c5c687010865c9b45d67a2fb3c41b7afcaaf91a2bf8993a2a17918ccb0fcbf0153b66105db5834113fe +4e3e0fb96320ddccde8b463c273654c4f7164920b1d63430921d2e808dee403e6420eedda0a557b911d00736a4f8798dd4ef26673efd6d190988ad4929ec64f8685cfb76070a36cd6a3a4bf2f54fb08a349d44642b6f614043fef9b2813b63457c76537d23da7b37310334f7ba76edf1999dad86f72aa3446445a65952ac4e50 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db 8821b3c38645d09c7b682d32167b5a4eb37629f4a36753ac37de398020b5adaf36bcaddabb09a02e80c875060cabe26207bca6e2c504996cc80e4cc3e1624e12d49a3de4d1b131b2ba760cf43f93906516047a66c972d304da1f39f9692feeeb +c466b6b6baf7e6ffa876ec06105e2d43534e0517c07b1c4c9fb67ba81ce09525a7721ec3c290f2b1f65b6463d41598e7a25b2238501629953a5ca955b644354fb6856733a2e5bb8f5bc21a0c803493f5539f9fb83aab3dba2c982989c2270c61ab244b68bfe1b948d00c2ed975e09c29b5f8a7effcad8652a148cc880d503217 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d b6efab298e09a1d764c3016ed14c021bbe17b7081fb931e0b489846aef495918bae6b913e8b96e9496683cf1415d334407e2bf95fec10f72e81830987607497e2588a3803f04d07640359198d8e1a63c257961cf037e67ff80c7962e76b2005b +feac892b7720af80b3c9eede51e923f18d3d0c5de4c31f4aa75e36df7c7c2fd8f41778851a24b69e67dccb65e159dd5c383243bad7cfedcc5e85c8a01c34b0b94ba8e07e4c024c09d279b3731e8b62f9562d3c4f5042567efe42a9d0eaaabab28bc6f11232fc8ceaaf4518d9f3b2bebf020294496b7f6b879e69503f75fecd3d 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476 a76877efca745cc6efb2794311941048f067903879c5a95477af9e7664495bb3817d48334ef9fa0f115ada53de5c0c4b0ebf1cff470705c8800e32ca2fae09f22d51b163521620c53d7f81140af69ea992f7d4893b80a117dee427804ab2248b +cf2982e3bf174ce547741b969403cd11e9553067e6af8177d89511a0eb040db924530bdba65d8b1ff714228db0737c1756f509e1506014a10736e65be2f91980a73891496e90ff2714a3601c7565cdcef5a395e2e0e1652f138d90d61eaa9cba993b823245647f6e07cec9b8b4449cd68a29741cd1579c66e548ca0d0acf33aa ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa 9508efe4d6dba0aec385e9f87897691d1da12c3247326066c4ce5e408093e358e69598ea5d2768877063ff7308e0bdf411bf95db50d1d70926aed0d61fb3326307226a18cfed3db8c8fbb72d82bd1c0b541a1273f593b24ac73c6d412c102319 +bf9fdd4107ef5a6070108771ac9eee4f0c8043bf0d04db772a47294f4137e2439d94b337114b074e57e0cb78d0ccf352a2833e9788ee2a1a9ffeacd34f38fcefb86653d70c7dadd4cf6548d608e70acdef6c7530974b92c813798add659752a8c72b05e1ad9c65c21834ce6fbe49d8a1426b5a54270794436d284364fac6ec1a 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f 8c4f904561b4415c3e8f212624740039a5268230f4625c6fa530e9c55dd109ccf19410a3f5c1e821dc008a13d0aa297c1506bb06d682092f87b1d45b4318b152ce6e7136935738417a11ab13cd2663052c9f27776e4cc2e5c4b2fa75b67a7146 +5d634fb39a2239256107dc68db19751540b4badac9ecf2fce644724401d6d632b3ae3b2e6d05746b77ddc0c899878032248c263eda08d3d004d35952ad7a9cfe19343d14b37f9f632245e7b7b5fae3cb31c5231f82b9f1884f2de7578fbf156c430257031ba97bc6579843bc7f59fcb9a6449a4cd942dffa6adb929cf219f0ad e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1 b6e9515f8a392935d8cb016d6c230406e57c33ef7d7261c6d83d535d9df81d4169aeed9c6d5f8aa5fbaf049191100fae142aab9e68c6013e6ff796e43f4f639399564456ba8fd47933032e104be5e7a304b233a011a365b11b9d8d8b156340f1 +c9b4ff721b3e886f0dc05856ffff0aabb64a8504b1746a47fdd73e6b7ebc068f06ac7ffa44c757e4de207fc3cbfaf0469d3ac6795d40630bcafe8c658627e4bc6b86fd6a2135afbc18ccc8e6d0e1e86016930ca92edc5aa3fbe2c57de136d0ea5f41642b6a5d0ddeb380f2454d76a16639d663687f2a2e29fb9304243900d26d 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c 882a28a63a2e31869b7b3ab04e55358afa748ace52b155fa17829808be225e2d4fb2fead5c75ae6ae35e91f7d50b168604d2866eb15583fcd00224196f54a7ed8acc85c75d0450cc42d5943189c549cd8f1602351987541234017b1831b7a13f +db2ad659cf21bc9c1f7e6469c5f262b73261d49f7b1755fc137636e8ce0202f929dca4466c422284c10be8f351f36333ebc04b1888cba217c0fec872b2dfc3aa0d544e5e06a9518a8cfe3df5b20fbcb14a9bf218e3bf6a8e024530a17bab50906be34d9f9bba69af0b11d8ed426b9ec75c3bd1f2e5b8756e4a72ff846bc9e498 e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c b75f2952d55805c5fda4a9e56e5d44abe3376e0f7fa26bbe952228ae421c8d934e6368a787ca1be56d73a1f45b338f1c168bc80ded57686f6ae967d5014c75f9715707da99de6acd06b464fa4de6e937fb231aeaac865b8ef873282342708402 +dbd8ddc02771a5ff7359d5216536b2e524a2d0b6ff180fa29a41a8847b6f45f1b1d52344d32aea62a23ea3d8584deaaea38ee92d1314fdb4fbbecdad27ac810f02de0452332939f644aa9fe526d313cea81b9c3f6a8dbbeafc899d0cdaeb1dca05160a8a039662c4c845a3dbb07be2bc8c9150e344103e404411668c48aa7792 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855 9746b10664e2fb86e3d2b661ff16e6f13690c6b1354d2dd75c2d45e125385b7b58f11a2a2dc573131821e86aaca481240f92d59746f7a3bf301e7334d20d2f54e84e559e7106ebeb067adc5aeecf1654107e62626a593804c81a7a5fe8959ae0 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P384_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P384_blst new file mode 100644 index 000000000000..44696e8c10bb --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P384_blst @@ -0,0 +1,60 @@ +39f0b25d4c15b09a0692b22fbacbb5f8aee184cb75887e2ebe0cd3be5d3815d29f9b587e10b3168c939054a89df11068e5c3fac21af742bf4c3e9512f5569674e7ad8b39042bcd73e4b7ce3e64fbea1c434ed01ad4ad8b5b569f6a0b9a1144f94097925672e59ba97bc4d33be2fa21b46c3dadbfb3a1f89afa199d4b44189938 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727 8a76538b46b3d8fd1688aa41789bc6fb4cb67b44fbe3ee2d0ba74d90331d3fbfea18d0603ea1286b291d0d44ff9d24160ecf69f0d1960bce0481ae7485a1cc6cda3fadd61ecfe38a6e5e7ef2ce41969cbced4875e77eab0c74036dec43b239a3 +5a3c80e608ed3ac75a6e45f6e94d374271a6d42b67a481860d5d309cc8b37c79cb61f1716dc8aa84cb309ef9d68eb7fc6cf4b42333f316a5c30e74198c8b340926e340c5de47674a707293c4aa2a1a2274a602f01c26b156e895499c60b38ef53fc2032e7485c168d73700d6fa14232596a0e4997854a0b05d02e351b9d3de96 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246 a90dcd172de75f3d6b98c1b418efed2e54d8d1cd75c9f0faf60ed7258a29b867041cf4d7ce652a2165eeec2e8774a9d01524cbe56c8cf309f2da120a2acc633c647c0c27a7fdc4e9b287bc32f05157facab4040914e08e849891e734e7f6bfbd +e7d974c5dbd3bfb8a2fb92fdd782f997d04be79e9713944ce13c5eb6f75dfdec811b7ee4b3859114b07f263846ae13f795eec8f3cb5b7565baff68e0fdd5e09ba8b176d5a71cb03fbc5546e6937fba560acb4db24bd42de1851432b96e8ca4078313cb849bce29c9d805258601d67cd0259e255f3048682e8fdbdda3398c3e31 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83 a5c22d19314f27801e205796783d51b5fb775e44b1ea48ea8488fd05634ae3dcf5b6dc3a7de1f421f31aad7b693e80e30c9bde7760772e736021bb8c06dd1982795281ab8465f6cca1388d623d44c6d5b2be7d8a344f9fc5d378414ba75ab274 +a670fda4d1d56c70de1d8680328043b2b7029633caf0ee59ffe1421c914bb937133d5a0f9214846b2e0b350455a74c4ab434c56de65a17139bb8212bf1c76071a37536fa29348f871dbb26baa92eb93d97e923a6d2ffd9be25cbc33075e494e6db657bd8dc053fe4e17148d8cf6e2058164f2b5766750eb01bbe7b361cdb848c dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659 8d43f5a3bbcf114676cc119802f0e20a83ff764f3c81aaa916159e34fa6bf1363e73cddc907192176cde105fdbfd5696028c78f1575cc89a39ffc9d45c31d6de73ce4916f15f2837f16485173e48065b3b45bbaab95eaa67ad97357883a076ee +7843f918fe2588bcfe756e1f05b491d913523255aa006818be20b676c957f4edb8df863c6f5f8c15b3b80c7a2aa277b70d53f210bdfb856337980c406ea140e439dd321471407f374f69877b2d82367eed51e3c82c13948616dcb301d0c31f8f0352f2846abd9e72071f446a2f1bd3339a09ae41b84e150fd18f4ba5d3c6bfa0 df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718 88b4ff872fe202508265577b59f5ca16e498149b3c57fcc73d853f7f2fd21205e7806ff7fdf781179b840fffe539b21c06a66c8f0e35ed8ab65a63f0c140eb0d39ba7b8cce4a68d6c7858c825a891b9acdec303814475a2c660e772cbc1512cd +caa83d5ab07febbd2e0fe2d63738b9b7b8752594bea7aaf50345b3d2f316653a8c9222f2b7877b64679e9573e81461a426029e45b8873a575094a1d572e0d32a9f0a9c6bcb9a2868543b7d8bbe4a69a09e7321f05f8366cced1b72df526f895b60aed2c39c249653c7839538770d4e5f47d3926ec0d168ab6a1af15bf1dca1f7 ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f a0cc5510e9393e9e5824ddb5c5eb74ffe0ad8ce83561ce92f32311db334aab64552a23ed34eb4cdb4b308a27dd50150c09debef6de235c3802b65b7f5eeee5be6b0bdb284dcd7f396a2a4490ba9538d34271d5233bcebd566db2815dd3b13c7f +594603458d6534974aeeafba919c4d0f4cb6843a3af41204bbb88aeb2fca2772d305163dba863da050aabedbaf89db521955d1715de95bbcef979ecdc0c976181ece00355385f8a8f8cce127c9eac15ce3e958a3ed686184674ec9a50eb63271606ee7fdcb1323da3c3db8e89cad1fb42139a32d08abcfbf0d4ccfca18c89a86 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829 83bc272809e56596655ec0ace3b918e360d434528ce28da996620bfc0a03789d5f06ba7463f06855c4758cde053bafed000c0393ce73f8d149b0b1722bf68349b4515d6e2b83d08384e4bc710b4af8b0c23cdc64eb7f9de55c0614b0d566614b +733252d2bd35547838be22656cc7aa67eff0af0b13b428f77267a513c6824c3dbae533068b6817e82665f009560affcfe4b2ddb5b667a644fc1a42d24f24e0947e0dc50fb62c919bc1fe4e7ded5e28f2e6d80fcf66a081fb2763526f8def5a81a4ddd38be0b59ee839da1643eeeaee7b1927cec12cf3da67c02bc5465151e346 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1 8d255e99483d9b654fa070895a24dbaf4e670580afe01d68c8873a81672b25841364d3524d53c25aac1654b04c08ebac178fa20d25a059ce027a36fc01bf6b6725bf457907832debfcf2fba34a447bd15724365b4d9b1784e78b206ab6e8f5c4 +5a182bd174feb038dfae3346267156bf663167f713dea1ce936b0edb815cd9b8c8e4d411c786ba2494a81442617255db7158b142e720d86c9b56680fb9efd4298cdd69079a28153494c42a24251c7ad42ecf7e97eabc1b3997529b2a297cbad2474269b87a0b1e385f2d7f8b6eb8d1cd75eaf7e91d1acbecd45d7b2bfbbe3216 e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d a797a0062fde082230d27a565cb8a37cf51e29760e7b0bab7b9111133a869632c8ad7c7cf3383c9a8d901c636a83e467124ad7f348ae9cc3ef02a6845915278a0ee49dc856b6f257e5acf11c8efe021feaee6935a277e4d3b830e1ceb424bf60 +aaa99fb1c71340d785a18f6f668e898c25cf7a0ac31d13c5b388b7233408493a5a109af6d07065376b96f4903df7aba2b2af671a18772bb0472490d1240cde28967680727dd4acd47e0308920a75da857a6eeedee5b6586d45dff3d8a680599665aa895c89dd7770b824b7dee477ac5e7602d409d3cc553090c970b50811dbab 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead 82dfe9beebf8135345ee37d7bf5709a6105ca9ca618c5e1188e9623d0afa574d35626bf7275e5e5848bc3eb23d006b6b06709f500044a53d3bd1572b347ca66a4f9dd4b6d34ba9adfa576171412359de4c06b0c1f35fc3b95ddceee048a1bbb5 +1fadfa8254d3a0b82d137cfdd82043d5dc1fef195d5297b09cc5cfb061f59c933451c0dc2a11b4037f34f88dacb803251f8880c4b72585c3c196e6fb23484ca43a191f8e41b9b9a37e2e6fcaab6738c3c62d1c98e1c620bb788b7b51a04f998a510efdba0d3418622fe8ce203b3fcd553b9b4206365a39031797ad11e49745ec 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0 b62d723311803143ee3be3ef23295d8c0d881c868bb69f42ef4738d2e07e77d44b966b2cfdb945125190b88a1c68c9f4151f2fcb0334629514c76499c55b67b02cf691ca6a6c75b200577d2f11f872e939f14ce9f4ca21c3c17cfcf156e787cf +9ecb6f5ed3ba666a8536a81ef65012c2cb8b433508798d84708abb06dfb75503886f78384fb8c7a4d2d49ef539d9b8a0b60938c7f07471dda91f258b0d99691b38a8403a2bb3f956bdfd09baba16d9b6877097a9b6213481b47a06e139d23ec7abad5668d21f912fdb70d31bb9adf9b3ce80e308252fa81a51674f88d02db72b f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1 97e4003948aad5d3775cd12541cf79d36e8b12ed934b082d043089f1db26bcc3d9ddc312d3af84ed649c35331153c62103c827c8d4909cc2b6e6f8866fa30afe1717f4032a827c080d936bb136cd676d0b686c39023fda656d16ab34774ef6b5 +e55bfca78d98e68d1b63688db12485578f36c489766f4d0bfaa0088433ff12133aaca455805095f2e655940860958b3ead111d9070778ee3bbf3e47e43d9eba8b8d9b1fdf72f793fcde2bcaa334f3e35fa2cca531ea7cf27fe9ccba741e38ac26129b2d612bf54a34e0ae6c166c0fef07fcd2b9ac253d7e041a500f7be7b8369 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb b21dc9984d42475ba37aa87fb3ef8452d38e93d32f65dbf4d3a7bc03b00fcbf95725bee5759dc12b13e48edabe340a7e1604edba1dd8d55665cce0e0037c66a73a0dc5d42254c84b8bc08fdff663f7f967cce65d9fb048d59844d8eb7657554c +02c6b3c83bd34b288d96409162aa4ff114e9d134bf948046eb5ebcc0c7fe9dfceadda83ed69da2fac00c8840f6c702a3fc5e6959d70f7e8af923e99e4937232ae3b841ffefd2e62fab3671a7c94a0281b8ea5bc176add57c5c9b6893fe7f5d48ce7256b96510810c4e046168a3c5be9843b84d5268a50349b3444341aa5490dd 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6 a46d088ed3bf2ffcdb706970a7885affad76963e51097033c26dd7b71538d9c0c84e98cbc2d5dedf555ef92346b8ba3402cf7ab4731eabba30e803a58f9eb4b6ecfb0fafc0f62bb463be139fdfd3fc7b91c46158f97e88474ad5b6a55f87f429 +94f8bfbb9dd6c9b6193e84c2023a27dea00fd48356909faec2161972439686c146184f80686bc09e1a698af7df9dea3d24d9e9fd6d7348a146339c839282cf8984345dc6a51096d74ad238c35233012ad729f262481ec7cd6488f13a6ebac3f3d23438c7ccb5a66e2bf820e92b71c730bb12fd64ea1770d1f892e5b1e14a9e5c cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd a173285adfd548200d436bdac745cd24871b5776bb58d78bf09c3d4f3c6a2cd46d46d7d5cf3f441e8229190df0c2de840685b95413917506fa4a1f91bf8465edc337cbc5a3c1d7156f42bf94d40e9aaf3d05ed7d2daacb96d1c5fbf331c96274 +663b12ebf44b7ed3872b385477381f4b11adeb0aec9e0e2478776313d536376dc8fd5f3c715bb6ddf32c01ee1d6f8b731785732c0d8441df636d8145577e7b3138e43c32a61bc1242e0e73d62d624cdc924856076bdbbf1ec04ad4420732ef0c53d42479a08235fcfc4db4d869c4eb2828c73928cdc3e3758362d1b770809997 c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b 980b467a2fce8b37b493b471e4361c12aaae16221f3c9f4e94ef5dc765a3eca1490500c193dc41ae06d99cc4063b94630449c8a7c5ef7a415ab5c7c30cab99160fc31b7049d841461a6d0b9cf919961d0d8eab67bde8e5591ca762bc784835c7 +784d7f4686c01bea32cb6cab8c089fb25c341080d9832e04feac6ea63a341079cbd562a75365c63cf7e63e7e1dddc9e99db75ccee59c5295340c2bba36f457690a8f05c62ab001e3d6b333780117d1456a9c8b27d6c2504db9c1428dad8ba797a4419914fcc636f0f14ede3fba49b023b12a77a2176b0b8ff55a895dcaf8dbce 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9 8f817d1f4fc48f5dcec1a40281c04d6808170e2f7d3b0b893e6601093836efa8ef66957b3af86b5115985e9e6e6f71c20c94873e409a2f7d2f8312fb235cb2105ea0b3b7aac87c929d04edc322355e6e46aea26bdaf116e536d46db82b3a955a +45e47fccc5bd6801f237cdbeac8f66ebc75f8b71a6da556d2e002352bd85bf269b6bc7c928d7bb1b0422601e4dd80b29d5906f8fcac212fe0eaaf52eda552303259cbcbe532e60abd3d38d786a45e39a2875bce675800a3eaeb9e42983d9fd9031180abd9adccc9ba30c6c198b4202c4dd70f241e969a3c412724b9b595bc28a d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f b45b2deb6d8fd0fb33dc45a910312a07ac7d9d999ad4fac64688b14c2044223b76bb75f1115cf7924c31e9d7708d3b4012d7add51807e1c57b7fe7a34bf822c638cb38c5775a040c56f1bcaead4b005641c827e004c74f3a3e76a08a68cce058 +c33ff63b4e6891e00b2349b3f2907c417ca355560544a91e24a7a0ee260d6850aeded29fc0176b6039ca6187e8333391047cceaf14b1077df8f147dad84d36b2dac5666dc2f69dc9b58b88cc73956efdb3b47f91831d5875051c76b0c4e9fc087012a1f03eeee85d6745b46aa50bd9cb0110c2c94508765cec162ee1aa841d73 d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3 ab01a21b568e81d2c476da2aada7da8928af62c8e351712845af7f0c7a347f916d898c566fd1ab6027bf6c5ab89c34bf0a1b21f3c3547957fbb509ef13def9434c8caaba6870a0ac7ea8534db89861f4ecc4699ff1f85cb22bc53d73b80938ae +f562f2b9d84b0e96a52532c3b43c39c8018c738bd8dc3797a7de7353971b2729d522d6961b1f2e4df3f6a4bd3653e6d72b74fc0dba92ab939c4b542e994e5db6dd8ed4f56f651e699052e791237ae1f552f990ad156226ae8f7bf17fcbfa564f749604f97e9df0879d50985747d981422a23040fe52f5ec74caf1d4aaad8a710 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93 a649b42ae88a123cdc6927e99300bce6a643064a537f3d11687b0642782817601875f0d298a01fe7ab5c71c05d288f010f9f8fd19fe3e7ef1a70d6e47e5521b66aae2fd2e97b2cb2c874a2137e62e633e95bbc3d8dc71ba06711f19b881a53f7 +ace953ae851f571d71779aa120915f27450b236da23e9106f8d0756abdd25861937941228d225d5fb1aa1b1ebf759b1e326aeb3b6cd0cd87edd2ab9f6a7ad67b63d2c501d6a550edb2e7c9d216cc8af78dd33546af64d00abed4d0d2cfc5c9a7b5a055dbe8f7547902d185cf46937314832bc5c602419a82ab83dbd9d3bd5aff e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1 8013e7d21e8821b343be9ab4cffa71cc675c066e022a8a97859043c30e66e1b3dd997a07aeec88595b745a6c9c00396a13de07ca9236777642846d2084dfaeb31c3ee9b4afa8882baa6f13f6fdacabfe7907fb6ef4a28843452fc68a53701689 +9635ab832240be95301bedb94c5aec169eedc198cbbdfedcf41e9b586143d829b4597a6b2a81902828332825fd84a785f187a3894e21bd99d22c4f94dcf34453fc052f15ec64d1447c932cb38fcdd30b7be851963409c11881438cbaad7e96f9efbde317f2235d66af804477a5dfe9f0c51448383830050ecf228889f83631e1 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960 b0bd9f524699b40f1f7e867daf39c1f8d0afc2a7624fb295538081b347861b54f6aa9a92f7f464e1084b4821b08f11e00503bc1a99ccea25286f9226fdf548549652fa223ebe919a8cf88ef1220f15e11ecc90a05ce588359e7c29794f04cd44 +d98b9a7d4fe9d0fd95de5056af164a8b7882cd34ab5bde83a2abb32dc361eb56a479a3a6119db3b91dcad26a42d2206749567f0d97c34a981a91fc734921821a429f6a53401743a5c406ba9d560f956203abc9d1f32f1a13e7d7b290f75c95fdbf857ea597021461c06a3aacfa554ede3d69e4ff03bbbee5b7463ec77de2b3b2 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57 a2ebc7468358f3c9fcf8f060113534025b2032e42107a8e9b2d65cb2a39ce52fe8abfb73eecdc5d2957496f3620ff3bd183793714a0521059c54ae12726b68297b8449109a082a80f730117f9bba3883748e20f72b57d7221adb66db16d6fbc2 +1b4c754ac1c28dc415a71eac816bde68de7e8db66409af835838c5bb2c605111108a3bf13606ed5d8ade5ed72e50503e0de664416393d178ea4eec834d8d6f15039847b410080fd5529b426e5aadd8451c20ebd92d787921f33e147bcbeb327b104d4aab1157fc1df33e4d768404b5ccb7110055c2508c600f429fd0c21b5784 a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1 913d29a2778876d1aaa8f3f43d320fa2399c535dc1145d75de909821fecbf4b17f71b309edc06e3cee2176ac6917976116e05e247cebf50baf070c51b1d065e30ebbc05a5f33e0cabe807be2030fe4b422b98c51f88a72744185fb95b77143bf +3cd8c053741dd9f974c6c5dbf8a1e5728e9b5eafb1cbcfc3452f5fbbda32a8c7564dee157e8d902c52514361da6d972934a56b3276e2a9379e328e24282e0db697c5bc29090fc489ec46b7b188325dd4e96494c250de0f4a89fe2ccf919eaefcfb50c288113e6df92714feb7f46e0822478c796d0f4ff3447a32997e892693ce 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3 8722e9ebb90645fb758040540d5ec393ea9d6970787a7452cca18fdff89699ffe6bd988f4173a9ab9f6754c8e82e7cb6184fdd00db7213d72f9b040fe2ff1fa0bec455cf66500b978796e02717bc5570cc5d52aa9c8b40b3b33d468bb258c3ce +ed955dda6d9650124804d3deb6aeef900e520faf98b1ef6f14efcada7ca2433f09329b70897305e59c89024d76e466b28fe02cb2a9b12e2478c66470259d7c282137a19e5a04ffadea55245c0f34a681593fedc42931d8b3321b3d82e9cc102cd00540ad311ec7bd8c9d06db21bea4ca3dc74d98931ae0d40494aefc2345132c 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907 9681c3d9574dcbf93423ba6b04906b7ded9c1f95343f40be49b7cbefff60c33f8edc509c4ed3f81b5b062a4f893c62460e2b6995f9192fa9bcaa04286a178c5ba99c7d88b87fd73aafdefd8b3f91822a2f46c3441c0f83d007c282cc3cc4d324 +ce395b001da2a58e49691605d44af4206306f62f561bf2394060d2a5591a350277166bed043819035f1e60b5b3fb5ae113ddd0473f8ef6b2b050c472c2a264e1d8b3ca82a4f158c40f2d78d9ce5e5ea6de243f2e1f13f47f6c6f403b270912c81c636be35b396ca58468b3fb60aa83911d61441a0528d973bc31f965d4059080 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245 a2fc95664f3167ce9b7929df41da43f389da9b104c715eeb268c820a0852b9f9dd09483d47fcfd772f117987f8b53c150b25c9add788f77300a38fb4b505a5321eb24d40470c4305f8f0709f728da471cb677f94d0c22b61bc54b2ad5b3412c6 +ffefe316455ae4ffdb890bb804bf7d31424ea060ecacff419d0f7134ff76ad434063c0ec0f8bb7059584d3a03f3625bb9e9f66ace1a47ac4b8f3e76fc7c420c55edb1427d1fa15b387ad73d02b0595c4e74321be8822752230a0dcfb85d60bfa186da7623a8ec3eb1633f0a294b23ae87216b14ccee9ef56418dcfab9427371e 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7 b662a3883ae0a83778722c1c062330956bcac55367e3b2fba95d53e553f3821de4de55a55688a90f7f9798e91b495a8114ceb6bec04a417fda0cdc4155a5b91a194e3b25c0ab9eb45adef184b5bf6bc2c123e5da3740c386db712b5b67f718b4 +304bccb718b3a9e12669913490cc5bcc1979287b56c628fad706c354241e88d10e81445a2853e3fc32ece094ba1abc3fdcab61da27f9a0fca739371049fed462ee6b08fa31cde12720f8144a6f00ce9b1a7a6eadd231f126717074b4efb5c72ce673ca5859000a436f67a338d698759f12c461247c45a361fb6cb661fdbe6714 d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5 acabd21b9a5f6ca67c84ad466ecbe816c392e69fa6a2aa36f47d2cda00f45248af8b82f168c5784057dedc64cc87c7900ffb905c6b14890b8f8d5b5a3e55c0700c4ccd9e6ae9215e6de85ed09aabc57e3b84c386a537fcdfd7b5ad04cd465ef0 +64f9f05c2805acf59c047b5f5d2e20c39277b6d6380f70f87b72327a76170b872bfe4b25c451602acfb6a631bb885e2655aee8abe44f69c90fb21ffde03cef2a452c468c6369867dfd8aa26ac24e16aa53b292375a8d8fbf988e302bf00088e4c061aa12c421d8fe3cbd7273b0e8993701df1c59431f436a08b8e15bd123d133 b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224 8b174ed91fbe991b002a7f7f037be48dbd5ac2c14bb4e3906b01fc1175e166ea02b3b44314e6c367da4cdd33b3559dcd0d3295a3d290c72b9994029cde0bc1a32afed9c0d78569f56bbc7d2f291c0ded29a2a6e373b80e33e93af9eb256d1d07 +6b45d88037392e1371d9fd1cd174e9c1838d11c3d6133dc17e65fa0c485dcca9f52d41b60161246039e42ec784d49400bffdb51459f5de654091301a09378f93464d52118b48d44b30d781eb1dbed09da11fb4c818dbd442d161aba4b9edc79f05e4b7e401651395b53bd8b5bd3f2aaa6a00877fa9b45cadb8e648550b4c6cbe 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 a0dc0569acb176abb03e648dc4b4d9c97f8d2e4013642561c10e818bd9d1f3a7749d974bf824706761597e7bcaf8aa6e05b9b30e99453bbd9c61fc9b49b33c4ea736e1a21e79907cd0824832c3b5f9867dbc5a398f791cc7b2c654cfb66d0038 +d768f41e6e8ec2125d6cf5786d1ba96668ac6566c5cdbbe407f7f2051f3ad6b1acdbfe13edf0d0a86fa110f405406b69085219b5a234ebdb93153241f785d45811b3540d1c37424cc7194424787a51b79679266484c787fb1ded6d1a26b9567d5ea68f04be416caf3be9bd2cafa208fe2a9e234d3ae557c65d3fe6da4cb48da4 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 8c0f1b01a40d05c5662abde9455186ad99f28ce63371062f77babfc8e81be8aa5aa4180318f2a2f745d6f047de225a05198d7882ac717d85c74a53d5508f71c81dad6bc7a7f40750530f13f85b6f3254d512907bc4e84accb0a8be9859858fb7 +6af6652e92a17b7898e40b6776fabaf0d74cf88d8f0ebfa6088309cbe09fac472eeac2aa8ea96b8c12e993d14c93f8ef4e8b547afe7ae5e4f3973170b35deb3239898918c70c1056332c3f894cd643d2d9b93c2561aac069577bbab45803250a31cd62226cab94d8cba7261dce9fe88c210c212b54329d76a273522c8ba91ddf b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 b27bef9cf63b68ac5f3da5bc637b8c115cc17e75f134ffc6e9933a45cdbd7044184a52cf940b2433db2debd8f008d06509cf62a9c055f1d207c05a3a82fe675d0248644c53bf889a6f498adbc5f96b7cfe3ec2e238dc31a16550215b9670b909 +b96d74b2265dd895d94e25092fb9262dc4f2f7a328a3c0c3da134b2d0a4e2058ca994e3445c5ff4f812738e1b0c0f7a126486942a12e674a21f22d0886d68df2375f41685d694d487a718024933a7c4306f33f1a4267d469c530b0fed4e7dea520a19dd68bf0203cc87cad652260ed43b7b23f6ed140d3085875190191a0381a de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 adcb08045bf82d5370746b414f4ab1ddc07e256f02cb46052a6dd645f78bcb4f6ad541dd42934231b6df2a2133023de01795ddd5ff45fa354e0c2e9994b7bbec79140215030c1e40c5901b8d58f350f45ed38252433a0e38fa9eb06d7ccb60f2 +7cec7480a037ff40c232c1d2d6e8cd4c080bbeecdaf3886fccc9f129bb6d202c316eca76c8ad4e76079afe622f833a16f4907e817260c1fa68b10c7a151a37eb8c036b057ed4652c353db4b4a34b37c9a2b300fb5f5fcfb8aa8adae13db359160f70a9241546140e550af0073468683377e6771b6508327408c245d78911c2cc 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc b165087da9dc78d6468b2bd988e7f7d3107ae53ddaed2c562f0746bbd225ab0d52b49a7a85006e0d88238e7de9d1adf716fd53ac0e0654303ef7c061e85d44b5ac050a2c7efd245b6df8d9ff5cb7b9b228878f1c9e42ad06d08ff2b4d41eabee +00ce978603229710345c9ad7c1c2dba3596b196528eea25bd822d43ca8f76a024e29217703dd0652c8a615284fc3edcc1c5ad1c8d5a8521c8e104c016a24e50c2e25066dcb56596f913b872767e3627aa3e55ec812e9fdac7c2f1beade83aef093e24c9c953982adf431a776880ae4583be158e11cdab1cbca3ad3a66900213d 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 952d8d4ddab828b666fced09d4f319ac7ba4107da8c90437fe67a58ab202f31d48ff1c06b899fec78e643c146974e85418761a7a87b21d74a35a42ca94b8db11fd83d29f855f91b3f0fbe802b1b2b8ad6e4e83e246a98bf5db17a1089d18caf9 +54a255c18692c6162a46add176a0ae8361dcb8948f092d8d7bac83e160431794d3b9812849bf1994bcdcfba56e8540c8a9ee5b93414548f2a653191b6bb28bda8dc70d45cc1b92a489f58a2d54f85766cb3c90de7dd88e690d8ebc9a79987eee1989df35af5e35522f83d85c48dda89863171c8b0bf4853ae28c2ac45c764416 ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 ae8bf035ffca2260ed1c79888e1f1fc65b1b942d31776dd41cab250e0e2ec5696ec73cb77a367be3b3ec6fd92821ac500e666545104626d8b5c90c1ac47a6d0c78d1477facd3d536d502690958efb78c48c5d092be12bb2c5a3d0ade3a9dccfc +692a78f90d4f9d5aee5da536314a78d68c1feabbfe5d1ccea7f6059a66c4b310f8051c411c409ccf6e19a0cbd8b8e100c48317fe8c6d4f8a638b9551ce7ee178020f04f7da3001a0e6855225fb3c9b375e4ed964588a1a41a095f3f476c42d52ffd23ce1702c93b56d4425d3befcf75d0951b6fd5c05b05455bdaf205fe70ca2 adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 92d13bf6757d4691ba301e6c5963524a7fd4ab38481c1b9825156977d1134db096bb3c98098c26b2925ecc06a4b8822e0e2e84dca08abf872ae35677c85e402a4bd27b29f8376ca7bfe37c0894ad0b1808ad995767a99a1af512e74d05a1c33d +3b309bb912ab2a51681451ed18ad79e95d968abc35423a67036a02af92f575a0c89f1b668afe22c7037ad1199e757a8f06b281c33e9a40bab69c9874e0bb680b905d909b9dc24a9fe89bb3d7f7d47082b25093c59754f8c19d1f81f30334a8cdd50a3cb72f96d4b3c305e60a439a7e93aeb640dd3c8de37d63c60fb469c2d3ed 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d 8da876f248529e31827283ed7bedc12140cd02bd14aa11b6419363bc55e6dd5fb959bb1c2131c748469bba7b0c9ddca5032d13fdb322d4799157472318be91d574cf7749ea8bacda23831a9389c582cc0aa5437d31af80474147b9c8d282a7f8 +f072b72b8783289463da118613c43824d11441dba364c289de03ff5fab3a6f60e85957d8ff211f1cb62fa90216fb727106f692e5ae0844b11b710e5a12c69df3ed895b94e8769ecd15ff433762d6e8e94d8e6a72645b213b0231344e2c968056766c5dd6b5a5df41971858b85e99afbf859400f839b42cd129068efabeea4a26 e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 b85f4fe9f8f5d8c446adff6cc3cf1b2b60de891c0bb04ff4efa2ee3c4037820f31dc4f5eb795215b68b9101edf98023d063b51d662ace98d5389bd8be0a3a4207afedb0eeba14d5d847291f339250af81fcdc2faa68ab0abd82ebed843fc449a +cf4945350be8133b575c4ad6c9585e0b83ff1ed17989b6cd6c71b41b5264e828b4e115995b1ae77528e7e9002ac1b5669064442645929f9d7dd70927cb93f95edeb73e8624f4bc897ec4c2c7581cb626916f29b2d6e6c2fba8c59a71e30754b459d81b912a12798182bcff4019c7bdfe929cc769bcc2414befe7d2906add4271 d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca af6e6e653b41f1cf727c01508186b82be8e9e9e285f66e24d862da5fe8044cb80eaeec6269e14edb64968073dd3b36560e047c30b65eb61bcd2aac087f457f03f5faa204fbb73c2a3a21f1b1a71ff95ade22433d853846e2c13478c6b6b10e62 +d9b5cf0b50416573ff3c63133275a18394dd4326be2041e8d97e6e4e3855a4a177e9d26dfd223fe8aa74564edb49bd72de19916fb6f001f44530d5c18e2c332bce1b7415df5927ece5f3824f34d174b963136b53aef1fb78fb0c06a201a40b2db38e4d8216fc1e392a798c8ab4b3a314496b7f1087804ebfa89bf96e9cdb80c0 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d acc6c43314b541a3ebfa03c57f143249ff3585726be2470322abe63b0c69345c90db6dc0088b933a17bcce035bf1d2ba0f6dd3aae1eb52b15576aea8a3bc778c1c96fecfebd7400418111c12de496ecec82bb9951e1d45c617c7b6505c322d17 +9e4042d8438a405475b7dab1cd783eb6ce1d1bffa46ac9dfda622b23ac31057b922eced8e2ed7b3241efeafd7c9ab372bf16230f7134647f2956fb793989d3c885a5ae064e85ed971b64f5f561e7ddb79d49aa6ebe727c671c67879b794554c04de0e05d68264855745ef3c9567bd646d5c5f8728b797c181b6b6a876e167663 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 9262960bc2d40bbe0863c218a3f1fd5fa3a9fbe6ac3e5b27429b59ef77522a3b98ea834e4e38f4f31d01879cf8372f05171771bf8a847058f67a05c977e5a83c2dccc66daf21c2d6cc9f30acb73026aa92eda6c1bff7d8559d5650ab999a8631 +0b14a7484a40b68a3ce1273b8a48b8fdb65ba900d98541c4bbd07b97e31bcc4c85545a03e9deab3c563f47a036ff60d0361684ba241b5aa68bb46f440da22181ee328a011de98eff34ba235ec10612b07bdfa6b3dc4ccc5e82d3a8d057e1862fef3def5a1804696f84699fda2ec4175a54a4d08bcb4f0406fdac4eddadf5e29b ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 afdf153463fbf5dd229d66c217e56adef3a75503dae8fbc53bdc81a8c1c7309df2fae8c84719293323a7ce65818a049e00756217f1cf75990024cfadc348e93ece061186faf423d06fefd0cccd094dcb7019b9aefb1463678f2455e162ba8dbf +0e646c6c3cc0f9fdedef934b7195fe3837836a9f6f263968af95ef84cd035750f3cdb649de745c874a6ef66b3dd83b66068b4335bc0a97184182e3965c722b3b1aee488c3620adb835a8140e199f4fc83a88b02881816b366a09316e25685217f9221157fc05b2d8d2bc855372183da7af3f0a14148a09def37a332f8eb40dc9 e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb 87ccf4e813db4a2caa7d123773d5de59fec259700f9808fb34353ec01971424931ef8f3a2f41e9ef0d8aac848029de240f487c229a8de906a5f4576973e8571d544b3293ef16d36fb4dcac8dbc290e866af6bfd773c656cea08aec8d609146c4 +67d9eb88f289454d61def4764d1573db49b875cfb11e139d7eacc4b7a79d3db3bf7208191b2b2078cbbcc974ec0da1ed5e0c10ec37f6181bf81c0f32972a125df64e3b3e1d838ec7da8dfe0b7fcc911e43159a79c73df5fa252b98790be511d8a732fcbf011aacc7d45d8027d50a347703d613ceda09f650c6104c9459537c8f 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c 89c22c76e2233d776ccfde5c53e7b67e8871a40f52726e99c28c5919594a1434acd638e5b00695f1233b9883959af769146e11206453772c7ccda5474dcbebcd928f0283d49685ba64e8261c617de5ed02baad82ac61ba7af8c9127d71a4e97c +45db86829c363c80160659e3c5c7d7971abb1f6f0d495709bba908d7aa99c9df64b3408a51bd69aba8870e2aaff488ef138f3123cf94391d081f357e21906a4e2f311defe527c55e0231579957c51def507f835cceb466eb2593a509dcbee2f09e0dde6693b2bfe17697c9e86dd672f5797339cbe9ea8a7c6309b061eca7aef5 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f 994692eebf85c895a13a9132897ac18f4c03bc46c8eee9d6e19ef4077456101868e194841510b2af757b4d895406bca115db10ada156d87509795c18ebb712c37ab54b13d0a3e70fb81e169acc027ea3e13e85a700d4fed52acfb5db4f1746ba +4672fce0721d37c5be166bffa4b30d753bcf104b9b414db994b3ed33f36af4935ea59a0bb92db66448b3f57dad4fc67cef10ce141bf82c536be604b89a0bc0e8bca605b867880049d97142d30538fc543bd9d4fab7fdbe2f703815cdb6361beb66acff764bc275f910d1662445b07b92830db69a5994857f53657ed5ca282648 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7 a8385e24c8bacc5522ea858966f843ccaf9aec2f8f12408486c129bf63456b1dc34dc6ec79d9e8a360ddc2991c58d89512a7c522f3a745021271a2a54585ad544700d3078dc66ba53da017036dce9a53f92b3b69811fcc19d1692121b2670661 +9ae48fdd9bfc5cb0f4d4761e28b2073bda05a3e3fe82c212e66701dc4573cc67a829b0f82d7520b1bf11db0c6d1743822bbe41bb0adbd7222aa5fae70fbd1a31f2d4453a01c81e064d775388468be96f6063f8673b7b8d4455fe1bd4c801ad5e625a015eaa4a1a18da490d2af8642201eaba3c611cbd65f861d8e19ca82a1ee6 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf a4c0d78c86d4c8d38a51390daab0307c92e4b085bb8f1dd75ce6c999deed79785a1d6c8f8aa8ad1bc29e2aaf210940df10859f5ed7a13f805d9c05da8de1ed4f611d5765a3134e868a68eaec28516f9318700a0e04baf6d09049d88c87f2dd7d +817d6a110a8fd0ca7b4d565558f68b59a156744d4c5aac5c6610c95451793de2a756f774558c61d21818d3ebeeeb71d132da1c23a02f4b305eccc5cd46bd21dfc173a8a91098354f10ffbb21bf63d9f4c3feb231c736504549a78fd76d39f3ad35c36178f5c233742d2917d5611d2073124845f1e3615b2ef25199a7a547e882 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b 8e7319a09d0042ff66708926ede35dbc57d4212c87e999d9225c8ae799ee4b213ef4fb6524336631f86e9b7ad02b28c01890a64059a4523f8d1735dcdec1c110aefe50172dd4763fdde3ef52a29567762879b531e2cd337cb5bf0cc9bdae1a4b +464f10ec6fb229a51db5fd0e122f2cb8a9a022117e2987f4007bf5565b2c16aba0714e2e3cdd0c100d55ac3017e36fc7501ad8309ab9572aa65424c9eb2e580a119c55777676ec498df53ef6ae78fd8a988130ee0e6082bf1ef71cd4c946021018a8ca7154d13b174c638912613b0bdb9001c302bf7e443ad2124ab2c1cce212 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69 adfca97bb6426cf9ae3b06055703ee18cb2919dc6699e8e0a6dedd2e7ea3653badf247d707c64df2d96e16e6f1db2a5217cde9675eb66494a0767fba9866b2895a2797c40b40a9b2f6d70d43e044e760ebbc448e4bc689c87434220b8a7e6fae +4e3e0fb96320ddccde8b463c273654c4f7164920b1d63430921d2e808dee403e6420eedda0a557b911d00736a4f8798dd4ef26673efd6d190988ad4929ec64f8685cfb76070a36cd6a3a4bf2f54fb08a349d44642b6f614043fef9b2813b63457c76537d23da7b37310334f7ba76edf1999dad86f72aa3446445a65952ac4e50 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db 94372d05be445cdf11e4e949900a349070ff78a85fa52e5ce5c3a556baf531ccc670c02f663ed4a212a9427517ffb9270d4a8a27d7604879b176721460a92244956c2a2436edf3cacc0ea90b1297fac824eef0f60c664a1d2e0d6f7109b5a0d1 +c466b6b6baf7e6ffa876ec06105e2d43534e0517c07b1c4c9fb67ba81ce09525a7721ec3c290f2b1f65b6463d41598e7a25b2238501629953a5ca955b644354fb6856733a2e5bb8f5bc21a0c803493f5539f9fb83aab3dba2c982989c2270c61ab244b68bfe1b948d00c2ed975e09c29b5f8a7effcad8652a148cc880d503217 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d 82f02516c3e9b3e13b80674d394452e65d2b089acf422ae7ebcb758305e8daad10b59d40a5b097ca96520df7ec2a78db1335c269b3d1c0ee1b3f4ebe1ac9ea44288e01a972cf35c00d11be877e86d8dac8098c9b0eb587914c372372f88f2553 +feac892b7720af80b3c9eede51e923f18d3d0c5de4c31f4aa75e36df7c7c2fd8f41778851a24b69e67dccb65e159dd5c383243bad7cfedcc5e85c8a01c34b0b94ba8e07e4c024c09d279b3731e8b62f9562d3c4f5042567efe42a9d0eaaabab28bc6f11232fc8ceaaf4518d9f3b2bebf020294496b7f6b879e69503f75fecd3d 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476 b1d5f2fc6e95959174fe352d40aa7e856feee09747135a5a65f7fd506f458752db77f534061c7e9c03e0058b27b6947418b471320e12f3efe8ffa1b2d0b65b321949d5217e48a75494de0ce12807e34695338fc5f4c9945c86c1878447ae670d +cf2982e3bf174ce547741b969403cd11e9553067e6af8177d89511a0eb040db924530bdba65d8b1ff714228db0737c1756f509e1506014a10736e65be2f91980a73891496e90ff2714a3601c7565cdcef5a395e2e0e1652f138d90d61eaa9cba993b823245647f6e07cec9b8b4449cd68a29741cd1579c66e548ca0d0acf33aa ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa b286781c61aae7da599f726a25b2b6da16c518be82630da8b26986e4c8f8bc8df78f2a37473326e9d1ebe5175365452b09fc466f7d3ac344362c8d805c366021dca759376606f3dc6dd891d553d63d95c8bb03c701ee82e8e97a10d6d0429cf2 +bf9fdd4107ef5a6070108771ac9eee4f0c8043bf0d04db772a47294f4137e2439d94b337114b074e57e0cb78d0ccf352a2833e9788ee2a1a9ffeacd34f38fcefb86653d70c7dadd4cf6548d608e70acdef6c7530974b92c813798add659752a8c72b05e1ad9c65c21834ce6fbe49d8a1426b5a54270794436d284364fac6ec1a 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f b6b5d45b1ee16811225aaa2da9692085eb68a5769addbdfe4e9482a6cdb433e21907c21fc32bf26415a49e7f0d80d2a90732d8d8254bc6c64b2ebc6a1e4bbe8a357fa6ada7091057c9d2cc91c05d05a7aef905f26a63b7cabba5785c0e48e0b9 +5d634fb39a2239256107dc68db19751540b4badac9ecf2fce644724401d6d632b3ae3b2e6d05746b77ddc0c899878032248c263eda08d3d004d35952ad7a9cfe19343d14b37f9f632245e7b7b5fae3cb31c5231f82b9f1884f2de7578fbf156c430257031ba97bc6579843bc7f59fcb9a6449a4cd942dffa6adb929cf219f0ad e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1 8ec3e09b180b770dcf07b5b3dcf16824ba9b18b2138c3819a78895a8b2efedb0497006a8e91fe912e60e47a009c104cd1128e7e480f6fd08acb5c95d0d19b59d0ee04fd0f9dd1dd878ee478270398a5d25589ba5f190bc6ce94eff54b6b6593b +c9b4ff721b3e886f0dc05856ffff0aabb64a8504b1746a47fdd73e6b7ebc068f06ac7ffa44c757e4de207fc3cbfaf0469d3ac6795d40630bcafe8c658627e4bc6b86fd6a2135afbc18ccc8e6d0e1e86016930ca92edc5aa3fbe2c57de136d0ea5f41642b6a5d0ddeb380f2454d76a16639d663687f2a2e29fb9304243900d26d 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c 8e9ba5f53d65d7956c322d2c286747f8dacd23f4da85168217d22f36b8751e3f7f639228c251812c5cb59e4a872e0cfb18e0677e8f6126f891fbea769c3c11ae8dd0a9fafebf211efa7d8dcd65eec8f7bbce86e39fd3f2221433ee6a32737ae8 +db2ad659cf21bc9c1f7e6469c5f262b73261d49f7b1755fc137636e8ce0202f929dca4466c422284c10be8f351f36333ebc04b1888cba217c0fec872b2dfc3aa0d544e5e06a9518a8cfe3df5b20fbcb14a9bf218e3bf6a8e024530a17bab50906be34d9f9bba69af0b11d8ed426b9ec75c3bd1f2e5b8756e4a72ff846bc9e498 e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c 87505959e14e5d6f039cac7e9551d3cff2ad9698727a7b75efff6c10c8c4fe608d2cb4516f824dd92c8d0d13839795e610621d2f5204762a64580df407cbde9986d0608f0634798ad7a961e3f9d1f46b4c6fba2e30daa22d31adf38838d569ca +dbd8ddc02771a5ff7359d5216536b2e524a2d0b6ff180fa29a41a8847b6f45f1b1d52344d32aea62a23ea3d8584deaaea38ee92d1314fdb4fbbecdad27ac810f02de0452332939f644aa9fe526d313cea81b9c3f6a8dbbeafc899d0cdaeb1dca05160a8a039662c4c845a3dbb07be2bc8c9150e344103e404411668c48aa7792 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855 adb56c65fe8ecf0fdfc3fa3f587692ef440d149468ce9c1c76f98d83939a7e59e0a9fc2a977877ab96ec4d905e4a05e80eb03275b5f20419335286de3a4fea71588fe133ccdf29051bb1ef4f0a5b415756d774427b4cc79cb004d0886c0c1eb1 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P521 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P521 new file mode 100644 index 000000000000..77b7538f0ab7 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P521 @@ -0,0 +1,60 @@ +58ec2b2ceb80207ff51b17688bd5850f9388ce0b4a4f7316f5af6f52cfc4dde4192b6dbd97b56f93d1e4073517ac6c6140429b5484e266d07127e28b8e613ddf65888cbd5242b2f0eee4d5754eb11f25dfa5c3f87c790de371856c882731a157083a00d8eae29a57884dbbfcd98922c12cf5d73066daabe3bf3f42cfbdb9d853 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46 a5d5e2d4791116922e8226085cc13ce0486ef83d9c17dc1ee1a32c9d9077f70fcfae1879b49b5677498bf5e1ab247082151c388279d3e74c253ba4349775c2d1f70a54a0c87730cf331681dc908c7d80c225358d3bc3bb1f2d6dc617290f8829 +2449a53e0581f1b56d1e463b1c1686d33b3491efe1f3cc0443ba05d65694597cc7a2595bda9cae939166eb03cec624a788c9bbab69a39fb6554649131a56b26295683d8ac1aea969040413df405325425146c1e3a138d2f4f772ae2ed917cc36465acd66150058622440d7e77b3ad621e1c43a3f277da88d850d608079d9b911 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73 8352e26a6c2f8de1ac768fd526a32aec5cd2b1929d30529c053ff187eb296bab8e2c4051270a7951e64ac8834f25b71e12135c48826b752d97200263bd686a5cf796fd7087f8c0994b0f686c39d6668d7d034d7a39ab12b2b8b2d1ccce56c685 +7ba05797b5b67e1adfafb7fae20c0c0abe1543c94cee92d5021e1abc57720a6107999c70eacf3d4a79702cd4e6885fa1b7155398ac729d1ed6b45e51fe114c46caf444b20b406ad9cde6b9b2687aa645b46b51ab790b67047219e7290df1a797f35949aaf912a0a8556bb21018e7f70427c0fc018e461755378b981d0d9df3a9 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace 90b3204841c1a3b8f6d1c3008e9ac82137f79f3c2727a872b30594e56210ded7ffeb347ef754962249df95a0c907d9d20856d921336a3700e4bb620adf4347b1ebdf2ca1177cc890a99f45c6ed94c301b015d48efa1f192c3da112672a8bc7fe +716dabdb22a1c854ec60420249905a1d7ca68dd573efaff7542e76f0eae54a1828db69a39a1206cd05e10e681f24881b131e042ed9e19f5995c253840e937b809dfb8027fed71d541860f318691c13a2eb514daa5889410f256305f3b5b47cc16f7a7dad6359589b5f4568de4c4aae2357a8ea5e0ebaa5b89063eb3aa44eb952 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc a1b4967641c549a8485d931f17994f669de5a92d0153f9f8b81fc0f32d7e8db5e9db2077d9387d01d9a8ba6905ec814409f816a6acc8d620944c90a64612e5aeb2ad5aa93838bf36c3d2f05b2ffaa26d2921626e634bb5540d0effc2077950a0 +9cc9c2f131fe3ac7ea91ae6d832c7788cbbf34f68e839269c336ceef7bef6f20c0a62ea8cc340a333a3002145d07eba4cf4026a0c4b26b0217a0046701de92d573d7c87a386a1ea68dc80525b7dcc9be41b451ad9f3d16819e2a0a0b5a0c56736da3709e64761f97cae2399de2a4022dc4c3d73c7a1735c36dbde86c4bc5b6f7 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549 879c78efea79e855f5f467871fb19a054afbc0fbcf24d52abe4ab845148b3a1c8cd1aef686cf569c5531e6b6c530da41125a6a70dccce4db609bc83b4ae53b91df4392712d54170f872288bec4b14bd9676093c286363a2d26fdabb47d13c639 +14c69f8d660f7a6b37b13a6d9788eff16311b67598ab8368039ea1d9146e54f55a83b3d13d7ac9652135933c68fafd993a582253be0deea282d86046c2fb6fd3a7b2c80874ced28d8bed791bd4134c796bb7baf195bdd0dc6fa03fdb7f98755ca063fb1349e56fd0375cf94774df4203b34495404ebb86f1c7875b85174c574c 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4 afaaab598f0d5acc75617922966e39d7e2aeba2d0aaa7fe8c90aa6afb3628dc288ede14213ccd89ae8966a8c510e0e010ced3d64e94061b23bce812bb276eb454d479d392f6a43bff969c34d62519a42bbac49b6d3482c6f42ebc1efb541693f +8d8e75df200c177dbfe61be61567b82177ea5ec58e2781168d2277d2fd42668f01248ca3eb29ffa2689b12ae40f9c429532b6d2e1f15891322b825a0a072a1c68fa09e78cfdef3e95ed6fdf7233a43cb68236560d49a3278f0b3f47cb08f475bd9ab2f60755ea4a1767de9313b71a1b9ea87ef33f34682efbda263b0f8cc2f52 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16 a7a1133416657ce6480ae29a6b1e6c1b90d0287524aa437d19f058525618c41554282781a1dc36446a66638e3a3f2449022ec880274f39340203762be33c627b6bfef96389c7bae4615b87f3c9b9f34d506bfe19c93632967441d18ea09070cd +10631c3d438870f311c905e569a58e56d20a2a560e857f0f9bac2bb7233ec40c79de145294da0937e6b5e5c34fff4e6270823e5c8553c07d4adf25f614845b2eac731c5773ebbd716ab45698d156d043859945de57473389954d223522fbafecf560b07ef9ba861bcc1df9a7a89cdd6debf4cd9bf2cf28c193393569ccbd0398 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37 a4b6e5119f8f1e5b1319e2c5c720f40fed0044912f1e17a9f2303d5872cc8f2634f596d12bfa2ea676f913f22d24207701ba0a5c8e563f1beac526520a3bd3540475605a29cea5c14d8497c0d168e84017edc27260876084b67469ce76879896 +80aad6d696cbe654faa0d0a24d2f50d46e4f00a1b488ea1a98ed06c44d1d0c568beb4ab3674fc2b1d2d3da1053f28940e89ba1244899e8515cabdd66e99a77df31e90d93e37a8a240e803a998209988fc829e239150da058a300489e33bf3dcdaf7d06069e74569fee77f4e3875d0a713ccd2b7e9d7be62b34b6e375e84209ef 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256 8ed24dd659e73225e6b36a567c96e63f328d67dad91c3ff2b21d88dcf02e7d4710e7d9c249fe8c8bad9986d4c992e4c90d22dd6064cbf42b1ca9a1ef1290f10770a323b0cba4f49507de26e1d59f14f9976443938f0bb33de4bb28693eda0749 +8a7792a2870d2dd341cd9c4a2a9ec2da753dcb0f692b70b64cef2e22071389c70b3b188dea5f409fb435cbd09082f59de6bc2ff9e65f91b7acc51e6e7f8e513148cb3c7c4664f227d5c704626b0fda447aa87b9d47cd99789b88628eb642ed250312de5ba6b25f3d5342a3cbb7ebd69b0044ee2b4c9ba5e3f5195afb6bea823d 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7 b5f075df8864fc1c61e1714c255745a45226e9506fad95abaa6db88685f33d9caad0b91613611c4cc8e846679aa346a20cc62153434ccca6705db75671f42d14a929dacee4e6ecc27ef5de841e3b6f4ee5148040ffb6c9e186146b032178577f +f971bcd396efb8392207b5ca72ac62649b47732fba8feaa8e84f7fb36b3edb5d7b5333fbfa39a4f882cb42fe57cd1ace43d06aaad33d0603741a18bc261caa14f29ead389f7c20536d406e9d39c34079812ba26b39baedf5feb1ef1f79990496dd019c87e38c38c486ec1c251da2a8a9a57854b80fcd513285e8dee8c43a9890 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73 8d93efbb52bb0f3e0ef46d89d766993b4807e1d1a7fe54da7b5e7049355e9536daffef6bed05bac54816916ce71d7ba400df99fccc9b2c2ac148f81fbcd31828bbed2d19c4f9a0ba8979419912ab50b3c54fc0135b48c40942223f141a359c23 +ec0d468447222506b4ead04ea1a17e2aa96eeb3e5f066367975dbaea426104f2111c45e206752896e5fa7594d74ed184493598783cb8079e0e915b638d5c317fa978d9011b44a76b28d752462adf305bde321431f7f34b017c9a35bae8786755a62e746480fa3524d398a6ff5fdc6cec54c07221cce61e46fd0a1af932fa8a33 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c b15e4c754601fd1588dc7bce69817a81f11296ed0fdf0c969e3aff7aa880e38b8ac0a0bbc21294fc64a3b55a9bbd793214ffbbeb4a5c6d2af8c2326b984f5558bece5581bc5126bc0fbef5d378b3e862f57d4e8a4d284c1dec76a8abd053731b +d891da97d2b612fa6483ee7870e0f10fc12a89f9e33d636f587f72e0049f5888782ccde3ea737e2abca41492bac291e20de5b84157a43c5ea900aef761006a4471072ab6ae6d515ffe227695d3ff2341355b8398f72a723ae947f9618237c4b6642a36974860b452c0c6202688bc0814710cbbff4b8e0d1395e8671ae67ada01 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace b269defe9b82355e7c5f3e55d4812f8e37ebe5f1cf03b80ddc9f1c0a26664eb1f0efea063cd3b38a06e26e7b4a8f7238112031407384fafa4efba0ae1749e3958a05f2b5fa765470442db74913cd885cdcd7e630a98f087f6e9d2306e9298e6c +924e4afc979d1fd1ec8ab17e02b69964a1f025882611d9ba57c772175926944e42c68422d15f9326285538a348f9301e593e02c35a9817b160c05e21003d202473db69df695191be22db05615561951867f8425f88c29ba8997a41a2f96b5cee791307369671543373ea91d5ed9d6a34794d33305db8975b061864e6b0fe775f 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8 a94e1f7b4c20fce8d4e1f637007759a319b734c63e4e7ee120d61942ccf4be4103c7933cd47e37e425f2421874da176c0d4d7831939b53f5bab880c49d525db39c533b96c1ae7209e52a921fb81358b747c0585f01920079311368289a5dd91b +c64319c8aa1c1ae676630045ae488aedebca19d753704182c4bf3b306b75db98e9be438234233c2f14e3b97c2f55236950629885ac1e0bd015db0f912913ffb6f1361c4cc25c3cd434583b0f7a5a9e1a549aa523614268037973b65eb59c0c16a19a49bfaa13d507b29d5c7a146cd8da2917665100ac9de2d75fa48cb708ac79 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad ad7eb0f9af4d7c0fc9ca3284910cdb1209c46f43c2ab42869dbe50411c0d4b63ef52aa4ea48e9071639dcb7c1549dcb90193d8cd28b8f68e9c241fc5e4ff048b036579393a399c9abee189d3b1fb4c5e96636fad3d7f84a968ad2f0afbb9c7fa +8ab8176b16278db54f84328ae0b75ef8f0cd18afdf40c04ad0927ed0f6d9e47470396c8e87cde7a9be2ffbfe6c9658c88b7de4d582111119c433b2e4a504493f0a1166e3a3ea0d7b93358f4a297d63f65a5e752f94e2ee7f49ebcc742fa3eb03a617d00c574245b77a20033854d82964b2949e2247637239ab00baf4d170d97c 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a abb3a8670a9d75260ef994373763100abb5cdc01dafb3f21d9a00ef3f0f130502c745660f75d693716a79ba44a3e423c0a5756834e5507ff43f310fd7623fe60cd5d557006208418b0c148c23f2f6d3fc4babc3324bed9a5aa79c3d70e1d7e5c +c4bc2cec829036469e55acdd277745034e4e3cc4fcd2f50ec8bd89055c19795a1e051ccf9aa178e12f9beab6a016a7257e391faa536eaa5c969396d4e1ade36795a82ebc709d9422de8497e5b68e7292538d4ccdc6dd66d27a3ece6a2844962b77db073df9489c9710585ba03d53fa430dbc6626dc03b61d53fc180b9af5dea6 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c 9488c0703bdb2426759a43ca244a6c10c494ce7f0eeb3bdf1a5528e956a0c48ca86c2c1be6822fc9a9d97b94ca15b0570c2decbdb519f20a32700760f6dd47df0f38bc773d465e838c209241748396ee9625b5df07e8cf0cdad581fa2471c20d +1c1b641d0511a0625a4b33e7639d7a057e27f3a7f818e67f593286c8a4c827bb1f3e4f399027e57f18a45403a310c785b50e5a03517c72b45ef8c242a57b162debf2e80c1cf6c7b90237aede5f4ab1fcaf8187be3beb524c223cc0ceff24429eb181a5eea364a748c713214880d976c2cd497fd65ab3854ad0d6c2c1913d3a06 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d 8451512258c2ab7acf2f8b75f825ac027d1ae6dde4ded4f62ba053300fe0f6ad77bf6eb8842ad369fe19d306e369d84d080eeac289462e34c4a4beedf83f444bbfd8bf11dbb98d573021092165f6770d5d8d7d5d30c0e943e22e3cbe23246a45 +adb5f069b2b501a3ebb83d4f1808eb07710ac4a7b12532996855a20bcc54b2f76812915f632163c3654ff13d187d007152617cf859200194b59c5e81fc6cc9eb1ceb75d654050f260caa79c265254089270ccd02607fdcf3246119738c496dc3a4bd5d3be15789fc3d29a08d6d921febe2f40aef286d5d4330b07198c7f4588e 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c 8cb69592f3f9f192c8f15c87395141faab188a90e78dbfa88c8b62832ff157a8b6f0aab01141afdbf48cd74c0265d43916527422ff75251d9b31f47ed6ba741b61b40557c2e377e0c144d6738f9572f06e04bda409295ea527a1d89769dbb181 +f253484d121d1ce8a88def6a3e9e78c47f4025ead6f73285bf90647102645b0c32d4d86742a50b8b7a42d5f6156a6faf588212b7dc72c3ffd13973bdba732b554d8bffc57d04f8167aef21ee941ee6ffb6cce0f49445bd707da8deb35dca650aaf761c3aa66a5ebccddd15aee21293f63061a7f4bfc3787c2cd62c806a1a9985 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25 a37f874d50d6e886c0af95b54e2d8efd6bc36fac9c9fa062db1226945290107bc44d173100e887afc33bb46941d0d53017b4b8da46d777631dc955fe807eaf327072211c05417a5d45eb25cdc6895d501357c06df8fe97cd0057fc305f604aee +33bab1c369c495db1610965bc0b0546a216e8dd00cd0e602a605d40bc8812bbf1ffa67143f896c436b8f7cf0bed308054f1e1ff77f4d0a13c1e831efbd0e2fcfb3eadab9f755f070ba9aeaceb0a5110f2f8b0c1f7b1aa96a7f2d038a1b72e26400819b1f73d925ea4e34d6acaf59d0a461a34ce5d65c9c937a80e844e323a16d 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf 9610c4f3e549038e37a225e56409a87fd6815d870800d96c9305d51298cefd3afa311a6d83440ee5a7c335fb08888a15031230468bff6f5b26e8a63d2783aa0ec33c63b8b15365586be9b14e36674e68eaa2ccbb01b7142b1471767febd48d5e +08c8b7faaac8e1154042d162dca1df0f66e0001b3c5ecf49b6a4334ce4e8a754a1a8e4daf8ec09cf1e521c96547aed5172ef852e82c03cddd851a9f992183ac5199594f288dbcc53a9bb6128561ff3236a7b4b0dce8eaf7d45e64e782955ee1b690ce6a73ece47dc4409b690de6b7928cbe60c42fc6a5ddf1d729faf1cc3885e 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570 b313a3c7a2ad6b9708e92f3744a263aa38fa2b35e41dba9e8c7e761203bfd27172b12e4c2f09c9e4aa72877d10a0ed770db53091e544bf27687c04e3f56540b8c5a3f35f4bafc14c6401154212fb15ebbadf536bb6e023d9d4e2f35c59fb4a2f +ba74eed74282811631bd2069e862381e4e2a1e4e9a357b1c159a9ce69786f864b60fe90eeb32d8b72b099986fc594965a33285f7185b415df58fead7b8b50fc60d073680881d7435609ad1d22fd21e789b6730e232b0d2e888889fb82d6ad0337ab909308676164d4f47df44b21190eca8ba0f94995e60ad9bb02938461eee61 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6 998a9fef1092c0163a95d6351d480496952faaee3569bc38f83ea7d37fa5b537df31ef2a3723463f1be5d818b5c792350638a5d8b82e851a8b6034d5828eba78f653a479cb5ff926a9783e1259f6f7f4abd8d4079f998c90f38a6d15262bc177 +dc71f171a28bdc30968c39f08f999b88dc04c550e261ecf1124d67f05edeae7e87fe9b8135a96fe2bc3996a4f47213d9d191184a76bd6310e1ee5cb67ea7fc3ef6f641a0ba165198040fa668192b75a4754fc02c224bd4a74aade5a8c814adf151c2bfeda65165a04ef359e39847c84e312afb66d4cd1db50d41ef3fe5f31296 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7 a379aab62cc023f649593faa8c75027c0e1d5d52816ec673c6024c870e2bb23f06d940f1174b6ffe8e67393e48a79d900a9a655ceeea8d9453fb32a62902ac3b67b98a7756befa92426aad10b56c6de1b0b82c8aed39e279841e39745fcfbbc7 +b895788d7828aaeace4f6b61a072ffa344d8ea324962ba6dab5efda93f65bf64a0f2ac6d5721d03ee70e2aef21cdba69fd29040199160e3a293b772ffb961ed694a8dc82800dab79367a4809a864e4aff6bc837aaa868e952b771b76591c0bb82249034e3208e593d85973d3fea753a95b16e221b2561644535c0131fe834ae7 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e b0568f1c60d5c727783e3cf47d417417861983389a8b5a5b1a9dc2f48b53bee7dc621271a88bf7bb1d06fb2da16b5b4f09e1f60e0878d5757633f3177b1738c6eb8e9b276bb69a638da6a2bce0b6a243bdf399fe34d55d6f265af50bd035421c +2c5bd848c476e34b427cfe5676692e588e1957957db7b5704492bd02104a38216535607f5d092dc40020130c04a3aaf0f1c52409834926d69a05d3f3188187a71d402a10ba34eac8629b4c6359b1095f30f710219298bf06b9f19bfc299981d7e251ca232a0a85338a7e02464731d1b25d4a1f68baf97064516590644820c998 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938 a56232902add3d5b28cf79331857e6b44b4b86f8254e0b9ef3fdce8f6710a691ae3bc9b2a60bcd7ce45de1efdd1eec3819bf250beb627311fc7bb6f399304bcae3bc32f6079471aef6e455e6bc69eccf40e1cc7e630a6f2c6b44403dcd9f2788 +65a0b97048067a0c9040acbb5d7f6e2e6ac462e1e0064a8ce5b5bbf8e57059e25a3ef8c80fc9037ae08f63e63f5bdb9378c322ad9b2daf839fad7a75b1027abb6f70f110247da7e971c7c52914e5a4f7761854432fa16b2a521e7bcaee2c735a87cad20c535bf6d04a87340c229bf9af8647eedca9e2dc0b5aa90f7fea3cdc0a 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662 86c504ecb17ab3fa1c6b11f38a2defbca9d69f772330595e2dc14c8830e05c47b88a16fff07a8cb935edd260b46999fe193bfb7ad625cf36ff686e749eba17899a03b2943ea894511ff714eda14da909bb00f294c5f4369c942c792a422c4b80 +d6e366a87808eea5d39fe77cac4b8c754e865a796062e2ec89f72165cd41fe04c48148068c570e0d29afe9011e7e7a2461f4d9897d8c1fa14b4ff88cab40059d17ab724f4039244e97fcecb07f9ffeec2fb9d6b1896700fe374104a8c44af01a10e93b268d25367bf2bef488b8abcc1ef0e14c3e6e1621b2d58753f21e28b86f 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721 850349566f1921d60f8a9641427a8648d6d4609f7a513930fb305f7afc1f98932524b4576d4242206fa499bc46aa09d3162ecdf4c987eb1c6808d4cf1d1d81e95e3d3339abf7a94b3c514d8f189f7752f0df83628ec87efa20fbc4601a1eb8c8 +f99e1d272d0f5fb9c4f986e873d070ec638422bc04b47c715595e2cf1a701cdf88bc6c4b20085b357bad12ccba67cac8a5ca07f31ba432f9154ff1fadefd487a83a9c37e49fb70a2f170e58889cab0552e0a3806ccfa2a60d96e346851d84b7de6d1a4b8cf37567dc161a84f13421e3412457d4bc27f6213453c8519a2d7daa2 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e 8af1ab8d0ffbfc1e67d15665ec51bb4cd8b1b150a205d82a266b9da095fad3c01f69d272a70472eaf4232616c205f830196526b95a983db527bd5b68712def013872b6fe72e18b2e08ae4afee25be9c3c0372b7e4cf34c452209536a524b9d40 +91f1ca8ce6681f4e1f117b918ae787a888798a9df3afc9d0e922f51cdd6e7f7e55da996f7e3615f1d41e4292479859a44fa18a5a006662610f1aaa2884f843c2e73d441753e0ead51dffc366250616c706f07128940dd6312ff3eda6f0e2b4e441b3d74c592b97d9cd910f979d7f39767b379e7f36a7519f2a4a251ef5e8aae1 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418 832fafebfe17002fed72eb140f102b1be5c3d7b91f84c5821fc36ca3805529a29fe85e8b681c2e5686e4d4bd9a7417a916015179be540a34b0dbe38980d0e6911404c4e89f2bec4698106eb54744dc3cac741cbffbd0f48dc41e6a04586daf7d +dbc094402c5b559d53168c6f0c550d827499c6fb2186ae2db15b89b4e6f46220386d6f01bebde91b6ceb3ec7b4696e2cbfd14894dd0b7d656d23396ce920044f9ca514bf115cf98ecaa55b950a9e49365c2f3a05be5020e93db92c37437513044973e792af814d0ffad2c8ecc89ae4b35ccb19318f0b988a7d33ec5a4fe85dfe 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950 84488bbb74755152f4b47e949c7789852509825e7313e595d988a438cb5d4c0d94464c93da4350aa18f0bee7fd2afbf9095b0599d32c085d179fec883801277d75d5bbc0f8e972188ee2e4784ed34040173689e8b9d3878968c203be09e67b55 +114187efd1f6d6c46473fed0c1922987c79be2144439c6f61183caf2045bfb419f8cddc82267d14540624975f27232117729ccfeacccc7ecd5b71473c69d128152931865a60e6a104b67afe5ed443bdbcdc45372f1a85012bbc4614d4c0c534aacd9ab78664dda9b1f1e255878e8ac59e23c56a686f567e4b15c66f0e7c0931e 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b a45adf39340eeda9cc8db8bfbdf9c53925048743f430e2ed322ac8fc4574aa709c9da6039597463d5884cba921e5a1c80ebe6761214d9fd5294d600920e0462d9bdf8f5cfb54e462889dc51aaa51bf5ad774c1703b6c8d33a57d32aa0622d85a +6744b69fc2420fe00f2352399bd58719e4ecdd6d602e2c80f194d607e58b27a0854745bfd6d504de2eb30b04cee0f44af710dd77e2f816ac3ac5692fad2d1d417893bb0edba2707a4c146a486f8728ca696d35cc52e9c7187c82d4bdb92eb954794e5ad15133f6bfea1f025da32ada710a3014cf11095b3ff69a94d087f17753 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f 91c69afab1900459cae0a06afd234f3ce0e360b25305f4fe75ecd5dd923da10963c5a007ca1763714927b2200278352707bb6ab7c218248ec55189cbcd6f0268f1fff7590788ab889de825238a848ae4387eaefa8ab33772daa6affaf83c6971 +16001f4dcf9e76aa134b12b867f252735144e523e40fba9b4811b07448a24ef4ccf3e81fe9d7f8097ae1d216a51b6eefc83880885e5b14a5eeee025c4232319c4b8bce26807d1b386ad6a964deb3bdca30ee196cfdd717facfad5c77d9b1d05fdd96875e9675e85029ecbf4f94c524624746b7c42870c14a9a1454acf3354474 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66 a34b624f900bb306f070611e097fc33f12595e5a1aac1a91a3e65e551d10b672852a1302f4dead0cf103eedd56a701920a6228ca80a8b6fe7339c40561f9481387c53d7c455167b3c2e6f0564e6826fab3f35a82d32e139364f41b4eb54f991e +a9824a7b810aa16690083a00d422842971baf400c3563baa789c5653fc13416111c0236c67c68e95a13cec0df50324dcc9ae780ce4232607cb57dd9b2c61b382f0fa51fd4e283e2c55ffe272597651659fbd88cd03bfa9652cd54b01a7034c83a602709879e1325c77969bebfd93932ce09a23eae607374602201614ff84b141 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c ab5a2279b7be132434751cebc9ba82b64a5b9e2a0871fd3bec56fd8ca3bb28d546d723496778cf56c8ae532fdb123ef3149cf05c5e1c4101cd79c264e46749bff9eadd6af6308497dab12b6d89ae977074f76c098749b70f7f5081e46856b512 +90d8bbf714fd2120d2144022bf29520842d9fbd2dc8bb734b3e892ba0285c6a342d6e1e37cc11a62083566e45b039cc65506d20a7d8b51d763d25f0d9eaf3d38601af612c5798a8a2c712d968592b6ed689b88bbab95259ad34da26af9dda80f2f8a02960370bdb7e7595c0a4fffb465d7ad0c4665b5ec0e7d50c6a8238c7f53 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0 a7d9213e96b63d84d42a974d6ae0c452f72df5711cb8bdb56436ea4888cd97da71d2e8780d35e6fa0f700d1f16cd3bd119e314cdc4cae109894bef0c915f7dd3b9213dc34d2b185507f63187e27372120df1ca64e83b90c4966d761dc8cfa5d2 +09952b1e09995e95bf0022e911c6ab1a463b0a1fdd0eec69117b34af1103c720b57600217de7cd178fef92de5391e550af72a8dcf7badf25b06dd039417f9a7d0f5be88fcd4e9655931d5b605452a667c9d1bae91d3476e7d51cff4108f116a49966fb3a7cff8df1c09734ce5620faf2dccb3dc5d94e7e9ac812da31f6d07a38 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9 b36848eb011fa313da134f68af41f59c2d6666fc910986b3212c9223a11a762d11d755f7ff46a0b120d14284c65f0002065aadd4860b72c714a2f9804a8aa30d2df23ca19cae3cbf347b776287feb440325b85dc0634389d898bd3ff47e62619 +0bb0f80cff309c65ff7729c59c517d50fc0ed5be405ef70cb910c3f62c328c90853d4473530b654dda6156e149bc2222a8a7f9be665240e2fbe9d03f78a2356af0bacd1edb84c4801adc8293a8a0bd6123d1cf6ba216aca807a7eb4dca76b493eb6e3dbb69d36f0f00f856222f24d9b93ec34c3b261be2fca0451c00571928e5 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d a9895ac5f6e83ba3aa497d2e610eb6340ccddb3236f04276e44dccde0dc5c2feb04581f053f12b35692343b8da412f060489248eff193424e7f1dd73c79cd7dd40abd27c420d932d70e460ddecc50084217afd2c0dadc7ea2517e370fbfe819f +7efacf213382ce30804e78b7256854d759147dba9729c51b2759465715bf2c421034c23dc651c13d6cce95f71fe6a84dfbee5768163ac5789ac0474c5ddf4115684683c5f7c204b33b8bcc0c03ac58f66cef2f53b721fe2fac91ad841126101a88f512a7c2ded38549d9f050d4b7961dda48a1489f026c5d111701762418cfe3 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490 b0e509c10cf4fd4a3ecfc12aec25262964d8987936d159ca8ff7e166565dca3de322767a497b1d43f667cb4323b7e2ef145d68cc39364decf1c634761e6f72538c492e75a83bbdc543e61d83575d34bc575ad2846cc878e0da30bad91269bf5d +28edff8b9d85f5f58499cc11f492abdfab25e8945975bbaeee910afa2b8fc1295ec61406309ce4e09f4ab4f462959fc2a2786802466eb26d3b01be6919893ae75d0fdc2dc8a82e662550f9fce9627dd364188aaba5c6faa1b2d8a2235adfa5ad0dc140f88a2b2f103f5690e877d07fe8fd30d02d2b2729bd3d8eb5b23a21f54c 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1 b787ec58de21511be00f9ab09973b60855f87c992f3c629cc87234f8014875f6dc93b97b7fd4ba0104199b7b664dbcd309b773cbb92e048b0e2649b59639e24b49d721fa8ed5c0334acf24964a6ab914acd6a580ad6d16d58e9010db658b92d3 +bae2a8897c742fd99fbf813351cd009d3f2e18d825ca22e115276484bce8f82f8c7c0c21dd2af208404d8ef45bb5a6c41693912b630897d5246801bf0775aa9bbac8be98cb861d172c3563dc59e78a58ed13c66dea496471b3ad0eeae8995293e4ab97373edc1837ffc95ff1cc0c1e90e64ea8680b2ca5f1e09bf86b99b343b6 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745 a1c9b613d013171455b861c9cc204e4d15f9321006b2fa9c8603e660ed31c5375ec574792e8e3d50addc816e9610d5621710529a5894bbb3b8e0c663500c9c4740c3b1bef3258982adf6f4f12a0fe91eb5c47bbce57d12621192df29b5a1f2fe +d57a26a9593e72bfc87322524639bcaae5f2252d18b99cdaa03b14445b0b8a4dd53928f66a2e4f202fb25b19cad0eb2f1bfda2ab9b0eb668cdcd0fe72f5d9ef2e45e0218590f7ab9d2c9342202610c698bc786cce108a7d4a6730a13e9ea1b470e781f1237d3f84f44abde808516975546bd89075ef9a9732bfd7ee33b6f4399 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f b85609748783c1f3168e389bb117830913f5d133bd9bff4671c0f2c83180e1abe80eecaac371e6f1e825cffbfd93f72e02152d9786069e3e4f121ff8e50112d4424310e6d93293efa5c91930e18734c4323838ffe58550a7fdcd005058c513c7 +8fdcf5084b12cfc043dd3416b46274e021bbed95d341d3c500c102a5609d3a34de29f8fa9f0adb611a1f47a97ad981f8129d718fc0d6c709eab1a3490db8d550f34eb905b9e00663543afc5bc155e368e0bc919a8b8c9fa42093603537a5614927efa6be819ed42ececbf1a80a61e6e0a7f9b5bc43b9238e62d5df0571fea152 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e 841181bb6c6abb1a2e99ced96af687ffc909a7ac435315e454dc85063037b67f05ab1291ff26a622bbfe3dd8f5422bc203bb5b425af8aecbde41845700e318500d6564720cc84052f915414eb967aec419c34a46a67cbe4607889305e4611142 +00669f433934992257bed55861df679804107d7fa491672574a7624949c60049b0533383c88d6896c8de860704c3e6a6aefce83efa57c4d57e9ab253da5d15e1f53ab6dce218b592772ab0bc01fee8e63368e85c0639301456fe2d44cd5396a7f2b22761cd03b80eba7883eede8249a2f5db2183bf00550c5c002f45a5e4fb31 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89 a2cd12c9a1d7477e2bde7b39868d5a5bd0f6571b3409b96ea55f18318155ebbaa5a11462dee9d8c21fbe80d4f196de5c0225bbf42b9204c9946e52e820b75ef52e55dda33335aa04b12eef2a6d57cc821cd573a76d0c60867a60bb63ce59175b +4be81dcfab39a64d6f00c0d7fff94dabdf3473dc49f0e12900df328d6584b854fbaebaf3194c433e9e21743342e2dd056b445c8aa7d30a38504b366a8fa889dc8ecec35b3130070787e7bf0f22fab5bea54a07d3a75368605397ba74dbf2923ef20c37a0d9c64caebcc93157456b57b98d4becb13fecb7cc7f3740a6057af287 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a b33950416bcc2840e98aae950b3169525e84d78bed283d18d519402ad87d407a8f088f50070ac8c9daa1956cf68c01a710183b86115e9a93fe94849ece5af7dde65eef522ae9f1d87b7d5aa0c72e0cec146aefda89a2139c61d875d35765a0c1 +9ecd500c60e701404922e58ab20cc002651fdee7cbc9336adda33e4c1088fab1964ecb7904dc6856865d6c8e15041ccf2d5ac302e99d346ff2f686531d25521678d4fd3f76bbf2c893d246cb4d7693792fe18172108146853103a51f824acc621cb7311d2463c3361ea707254f2b052bc22cb8012873dcbb95bf1a5cc53ab89f 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926 95b0ae99be5188978e0fb7a73a4d33ede58dc9c42fada20282ecc5234d2b2970262aae7ee7e336f0e6061d04080f24541878283dcc377aef39cc2f7b1ac94e4969ee3ddbdd0c78ac4832269446789df93395140e3c035f5ddbf6fdbb93e047fc +b3c63e5f5a21c4bfe3dbc644354d9a949186d6a9e1dd873828782aa6a0f1df2f64114a430b1c13fe8a2e09099e1ed05ef70de698161039ded73bcb50b312673bb073f8a792ac140a78a8b7f3586dffb1fc8be4f54516d57418ccc9945025ce3acf1eb84f69ceee5e9bd10c18c251dbc481562cd3aae54b54ab618cb1eeda33cf 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6 a62be5cd6c34f2b660628c5464d3dd7aa268975edc7b064456fa0c16bf7497abdd0fff8788fdd0637c3d26b0e41fd69904f364a5bb4655ab3f8e97787102de46d8c2912c2a48e8bc1e156970c63295f61cfcd19e7f40e2ce08fa02399bf207cf +6e0f96d56505ffd2d005d5677dbf926345f0ff0a5da456bbcbcfdc2d33c8d878b0bc8511401c73168d161c23a88b04d7a9629a7a6fbcff241071b0d212248fcc2c94fa5c086909adb8f4b9772b4293b4acf5215ea2fc72f8cec57b5a13792d7859b6d40348fc3ba3f5e7062a19075a9edb713ddcd391aefc90f46bbd81e2557b 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f a0077b356b9decc1640f298975cd72eb7da263f4555be7eb637823c2dfc15ed6c20ccee650edb17f2c7b69a912eb50b814d030220c6d6093cc68e3129efbd39ee30a99d3c95f4184cc4a4b61e03728a3ec147ffc7b2d227ab0b5ce751a559c63 +3f12ab17af3c3680aad22196337cedb0a9dba22387a7c555b46e84176a6f8418004552386ada4deec59fdabb0d25e1c6668a96f100b352f8dabd24b2262bd2a3d0f825602d54150bdc4bcbd5b8e0ca52bc8d2c70ff2af9b03e20730d6bd9ec1d091a3e5c877259bcff4fd2c17a12bfc4b08117ec39fe4762be128d0883a37e9d 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742 821a369b2ef36fbd313f27274faaf368e41df2eec73c82dd886af8e415ff33f7c84d23559b6d7d730f3010473dac3b97067b7db5dda8559e89e3dfea68ca8042bba3b4f5ede59f615bab2a424bb8c7814b4a29b01ed2ab73cfad6688290f16cb +a1eed24b3b7c33296c2491d6ee092ec6124f85cf566bb5bc35bffb5c734e34547242e57593e962fb76aee9e800eed2d702cc301499060b76406b347f3d1c86456978950737703c8159001e6778f69c734a56e5ce5938bd0e0de0877d55adeee48b0d8dfa4ac65fd2d3ce3e12878bac5c7014f9284d161b2a3e7d5c88569a45f6 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697 b7b4c71042b0f6f5dd9b2995253a2e53ae88039cc6321f12c0d66ac85cb1ae5b785ce8e2a1a845c7e0436bc3533c3a5c110620f621cf26a3d82cb905e15ff5c0bb24a4b175560de08201830429e86f35adb729fd510d1102ef6604799924249a +9aace26837695e6596007a54e4bccdd5ffb16dc6844140e2eeeb584b15acb2bbffd203c74440b6ee8db676fd200b4186a8c3e957c19e74d4d865ada83f80655323dfa3570907ed3ce853b6e8cc375ed2d758a2f5ad265dd3b47650517a49b3d02df9e0c60c21576378c2b3a08481eec129b2a75608e13e6420127a3a63c8a3f1 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04 a601f9e468d56058ba168293780d7fd2c96248a5b84170a8d1665ad87e3ac40324ba396ffffecc01a87442f8c29fbb1f102265e8c1b87c47b0f405985b058af0f7a7d150f91a25d683ea5abebf7b2b489d04b4e8439a93ffe39745daedfc8618 +ac2175940545d4fbab6e2e651c6830aba562e0c11c919e797c43eff9f187a68a9e5a128e3e2a330b955a3f4577d3f826529ad1b03d7b60f7ad678f005053b41dc0f8d267f3685c6abe1a0e9a733c44b2f3ca48b90806f935141c842e3a6c06a58f5343d75e3585971a734f4ae1074ce5b54f74bd9342f4bbca738d260393f43e 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6 83b2dfeea6e451cce689e60fdf57f4f8fbe26651e93c1bdb365673b0d932179693908e7e30eb797bb5356960405a85fa03aeb78517c96eb0beabe41543d40e06311335aac95b0d136b4ffec0f7a85905f997a15bd0cc813d9e0d3cdc47e70203 +6266f09710e2434cb3da3b15396556765db2ddcd221dce257eab7399c7c490135925112932716af1434053b8b9fe340563e57a0b9776f9ac92cbb5fba18b05c0a2fafbed7240b3f93cd1780c980ff5fe92610e36c0177cabe82367c84cee9020cf26c1d74ae3eb9b9b512cb8b3cb3d81b17cf20dc76591b2b394ef1c62ac12ee 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e ab359fade8d45d08b72bcfe05ea56b3555695dac229f59643a85cac9cd87dcaaca2310dc1f5f940e7932fe368d0fb4d61851650dde7e89296ec12aa42b843a48d2a036b7d57e2c24be0075e7b9c9afc4d8bd420c51724c85e05f4d7c604c51b0 +3de9e617a6868dca1a1432d503f923535da3f9b34426b2a4822174399c73b1c1ee67311410a58c17202ac767844b2024d8aa21a205707d93865693ac25a24fc87034fa3a7a7e27c3344cb03b87602c15180a5fe6a9dd90cd11af4a0f150207bf2d83f55b12c088adae99aa8cfa659311b3a25beb99056643760d6a282126b9b2 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5 898e69fce897a5bfb2a9ff0cdbf24a193dd176256fffaa51ce11abe0f98feef6b6fac30235a66abb001d324aa770537f091f7923ac53293828349379d7fee41fd446d04856c4c78edf9f6f6cb09fdd8b8a60f616ed0adc91aaa20ad6835f80dc +aa48851af7ef17abe233163b7185130f4646203c205e22bcc2a5a3697bcab998c73a9ffe1d3ea0b7978ce7df937a72586eb5ca60b0d939a7d1c115c820171c89c8116b7e2c7b98cf0f14e4c4df3cb2f319ad3ab0ea25ff14526ddc037469f000bf82100acd4cdf94feb4eba4ea1726f0569336604a473aee67d71afebb569209 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a 8e470351a13c66aa48b1a0fd80d123a709043922ce04f38f6814254fc83a1f782175bd7b9884510f0418dd2138e472b0174a345877c36218117c004cc79b8e2e66020edb68531b0d8b18421f5d555a9fe674813d6aaf844495f4a236fc9b4613 +b0d5d52259af364eb2d1a5027e5f7d0afe4b999cc5dd2268cfe76f51d2f17b541bdd7867e23a1bb897705153d9432a24012108979c6a2c9e2567c9531d012f9e4be764419491a52eae2e127430b0ab58cb8e216515a821b3db206447c235bf44ee304201b483b2a88844abaa18bca0147dfff7e502397dd62e15524f67eb2df2 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb 95f027174332cdb93afd8295bcfe20410e5f2408191337eb046c35d6f24ab61a7e8c4092f2679c518b62e370e67a22fb0c7ccc61a3d8d62855065990a4c1a51cb5bf814b1905101fe452cd47ca453229135f16d33119098df8244b5396dea5d1 +9599788344976779383a7a0812a096943a1f771ee484d586af1a06207478e4c0be9c200d42460fe837e24b266c8852d80d3c53cc52ffb1913fc3261145fc6da575611efd16c026059a2e64f802517ffd1b6b34de10ad2909c65c2155e8d939b8115400c1d793d23955b15f5d1c13c962ff92b4a815cee0e10f8e14e1f6e6cd38 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77 b7bcde943593ddb42a025052a8e66fe9874c7566ef74513cea86faaa81a2ec7ab6f8f888eb5a23cc3e385310f140166900e73c7ea73436698ea5d702b9ec485fa28204f98f251ae879abc6d1238e3f25fe88c7d3f31a2163c6e6d8f83ca92b39 +fdde51acfd04eb0ad892ce9d6c0f90eb91ce765cbe3ce9d3f2defe8f691324d26b968b8b90e77706b068585f2a3ee7bf3e910528f7403c5af745a6f9d7ba6c53abd885c3b1be583415b128f4d3f224daf8563476bd9aa61e9c8518c144335f8f879c03696bddbe3ac37a8fbede29861611feaa87e325e2f60278b4893ed57fb0 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c 8254d7e5cc6276f1b4053c319886fe706020986312886a41874dec7803468d7ac4a8544953348a146e845e575588cd5606b8a0d568bdfb58e8fe5f814748f3ca098b4aa11985502839a58be02dc591a0f63a528023256f232858733d1a35fe26 +beb34c997f905c77451ac392f7957a0ab8b23325bd5c63ca31c109ac8f655a1e3094240cb8a99284f8091de2ab9a7db2504d16251980b86be89ec3a3f41162698bab51848880633e0b71a38f8896335853d8e836a2454ecab2acdcc052c8f659be1d703b13ae1b090334ac50ab0137ddb5e8b924c0e3d2e5789daaef2fdd4a1e 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63 8d564f974f80755ebaaa01cf66fc71b6a9a5da3dc075bc010c0d0f6e3030ace873a0114e6d6bca7b927205b4249cfcd117014ff741e2d83aa926e21b4386f7c3bdf2ba351dbfd225f9e8861ea527785fcf8ce9b539559274d525ed79637c76c4 +543c374af90c34f50ee195006d5f9d8dd986d09ad182fcbefa085567275eee1e742bfe0af3d058675adeb5b9f87f248b00a9fbd2aa779129123a5b983f2f26fc3caf2ea34277550c22fe8c814c739b46972d50232993cddd63a3c99e20f5c5067d9b57e2d5db94317a5a16b5c12b5c4cafbc79cbc2f9940f074bbc7d0dc71e90 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da 980e8c4a9fa988cca30328ec177e0ca57e1daf1ab655e1f543b964da214484706117f840536c48a248495aedd07db406095dc370254c8c5be8726f28b1653aa658041d12ff8fc988c76dcc87972b24bff8b02e3611d00c78308aa557adf35f12 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P521_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P521_blst new file mode 100644 index 000000000000..41b5f23d29e0 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_fips_186_3_P521_blst @@ -0,0 +1,60 @@ +58ec2b2ceb80207ff51b17688bd5850f9388ce0b4a4f7316f5af6f52cfc4dde4192b6dbd97b56f93d1e4073517ac6c6140429b5484e266d07127e28b8e613ddf65888cbd5242b2f0eee4d5754eb11f25dfa5c3f87c790de371856c882731a157083a00d8eae29a57884dbbfcd98922c12cf5d73066daabe3bf3f42cfbdb9d853 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46 8d3a9513f0f64b5afd1d1658bc82ad77a08ebc510ef1e959d341170963988a17b8a4b0660459e986b72356013f6066dd15b1889b8b30f1ad3592f9a58a9c39bdf45ed41a50695e326781241fd94af7c456ebf7a472444d785562153a884b873f +2449a53e0581f1b56d1e463b1c1686d33b3491efe1f3cc0443ba05d65694597cc7a2595bda9cae939166eb03cec624a788c9bbab69a39fb6554649131a56b26295683d8ac1aea969040413df405325425146c1e3a138d2f4f772ae2ed917cc36465acd66150058622440d7e77b3ad621e1c43a3f277da88d850d608079d9b911 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73 843f469903faa25e218766aa8443bd9e2f11dfdafb18ec6838838c0b8f055cec629332f9fd8259743e761a9c8cb312c30694d7dffebae631a8fd1044eefea87c5b6773053120c3ee5bfda738f8029f824e42c37a26cab3a91e9d069a821d7d18 +7ba05797b5b67e1adfafb7fae20c0c0abe1543c94cee92d5021e1abc57720a6107999c70eacf3d4a79702cd4e6885fa1b7155398ac729d1ed6b45e51fe114c46caf444b20b406ad9cde6b9b2687aa645b46b51ab790b67047219e7290df1a797f35949aaf912a0a8556bb21018e7f70427c0fc018e461755378b981d0d9df3a9 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace 8004f8b27acaa969589e4d0fb49616a619c1bf357b52310082391b3f6f4bde24eb8da0db04563322b4a6970c852edd2001c981c5416c49a570c4d2134c279295debbca3a3dc197674f8703027436209339fae4f8558639861a0a9f61c74815db +716dabdb22a1c854ec60420249905a1d7ca68dd573efaff7542e76f0eae54a1828db69a39a1206cd05e10e681f24881b131e042ed9e19f5995c253840e937b809dfb8027fed71d541860f318691c13a2eb514daa5889410f256305f3b5b47cc16f7a7dad6359589b5f4568de4c4aae2357a8ea5e0ebaa5b89063eb3aa44eb952 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc 992861f59eb1a23b2ffa6f9ebe5ef20d6494d02960b6684abfa5ab1ba700bae50a79aa62ec45d9e6b1774404d96c55a010746a1b6c55a09d6a42ac6ec2dea8258f6d63dd0f39f52ce07b95ee2774447cfe3e3e9cd3d5d9b3a0fff08420b6f724 +9cc9c2f131fe3ac7ea91ae6d832c7788cbbf34f68e839269c336ceef7bef6f20c0a62ea8cc340a333a3002145d07eba4cf4026a0c4b26b0217a0046701de92d573d7c87a386a1ea68dc80525b7dcc9be41b451ad9f3d16819e2a0a0b5a0c56736da3709e64761f97cae2399de2a4022dc4c3d73c7a1735c36dbde86c4bc5b6f7 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549 b784f75d50ba043fc87cabebfac10387c309fc4ca2c7cc47688b7b3aa2f3902b80a3f416f8385f79049576858a2424ce092dfe88a478a03df364e443809450b8a12e5e9ca763a81031c6b834551017b3ac3e8d33c6b89dfd3ffbf2dc29bfd7f3 +14c69f8d660f7a6b37b13a6d9788eff16311b67598ab8368039ea1d9146e54f55a83b3d13d7ac9652135933c68fafd993a582253be0deea282d86046c2fb6fd3a7b2c80874ced28d8bed791bd4134c796bb7baf195bdd0dc6fa03fdb7f98755ca063fb1349e56fd0375cf94774df4203b34495404ebb86f1c7875b85174c574c 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4 88844d3c33fe439fed77512c9e20e0f494fd8b72e226694abc505218f7edae06e52025a59991a80e4a2742af98ccd5ee16ba97b8536fba7f0658941c0402d9a9b066babe97374eeee54906e89fa34d9f39aa58a974f9c96677ac2ccca61a4f74 +8d8e75df200c177dbfe61be61567b82177ea5ec58e2781168d2277d2fd42668f01248ca3eb29ffa2689b12ae40f9c429532b6d2e1f15891322b825a0a072a1c68fa09e78cfdef3e95ed6fdf7233a43cb68236560d49a3278f0b3f47cb08f475bd9ab2f60755ea4a1767de9313b71a1b9ea87ef33f34682efbda263b0f8cc2f52 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16 b35410e674d41f3ec2c9323474e28aeb6065cad31109a2d099ac75369674d725108b97ba0236a20adfb39aa7f913b3250d7fa2ec5030cb825b1abc8497cfeae42308b32b4a4f7825d27169d053c5a3799252f64f60a0ff78b10608cf9ce410ad +10631c3d438870f311c905e569a58e56d20a2a560e857f0f9bac2bb7233ec40c79de145294da0937e6b5e5c34fff4e6270823e5c8553c07d4adf25f614845b2eac731c5773ebbd716ab45698d156d043859945de57473389954d223522fbafecf560b07ef9ba861bcc1df9a7a89cdd6debf4cd9bf2cf28c193393569ccbd0398 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37 8b41529347e3cee5537b1a97a9a55ff48d5be3b42dc72cbb5a1529a8ca1b919ce0aa688c59bcad9181c0012d931c039317496ab3ebf4400a9575cccea97f8098231e438e60015511ec1df9eb84ce498d44f4714eaabdea392ee584c044e7e020 +80aad6d696cbe654faa0d0a24d2f50d46e4f00a1b488ea1a98ed06c44d1d0c568beb4ab3674fc2b1d2d3da1053f28940e89ba1244899e8515cabdd66e99a77df31e90d93e37a8a240e803a998209988fc829e239150da058a300489e33bf3dcdaf7d06069e74569fee77f4e3875d0a713ccd2b7e9d7be62b34b6e375e84209ef 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256 948532f8ac71cb61b754a98d3ac35bf9a225aa7e3124d49f152d4afd0396cb53f28cc2e0ca720beca6800bda57d325240dd8767be3a92a844cab05a234fb8e667ab01245466b45a8d924da3de7610bf983c1362d09796867d3af4254654ca807 +8a7792a2870d2dd341cd9c4a2a9ec2da753dcb0f692b70b64cef2e22071389c70b3b188dea5f409fb435cbd09082f59de6bc2ff9e65f91b7acc51e6e7f8e513148cb3c7c4664f227d5c704626b0fda447aa87b9d47cd99789b88628eb642ed250312de5ba6b25f3d5342a3cbb7ebd69b0044ee2b4c9ba5e3f5195afb6bea823d 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7 9691eebff38650ded19054a0db3b2f52bc892f059ac23ed07006941e10a585d5591cd3123e29ed038a509b67c5b15c4e0419c6b8d9ec6bc72f44f0472cd49e3259d6ed1ffc53aa561da8538cdefe177b6a01a03fa2f7ee6b0e1c43034f1654f1 +f971bcd396efb8392207b5ca72ac62649b47732fba8feaa8e84f7fb36b3edb5d7b5333fbfa39a4f882cb42fe57cd1ace43d06aaad33d0603741a18bc261caa14f29ead389f7c20536d406e9d39c34079812ba26b39baedf5feb1ef1f79990496dd019c87e38c38c486ec1c251da2a8a9a57854b80fcd513285e8dee8c43a9890 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73 a1af749e554c80e3fe51251437a708a90737a7874fda6731b60c5c5ad89c5bbd0284c7824ce8011a21e52227f107eecd047eca6dff427ffee3c3707da51e869070be7cd425b9dbdeecc7969692888f54565373c0d82d35074494dfa08c849812 +ec0d468447222506b4ead04ea1a17e2aa96eeb3e5f066367975dbaea426104f2111c45e206752896e5fa7594d74ed184493598783cb8079e0e915b638d5c317fa978d9011b44a76b28d752462adf305bde321431f7f34b017c9a35bae8786755a62e746480fa3524d398a6ff5fdc6cec54c07221cce61e46fd0a1af932fa8a33 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c adfda0acb726985ee3078145cf335d4bf78779baff3a986ecb774051788c45456184339d514ba2639654bcc5e9bed4850cc5cdae7874a781e87637b756106eba2a0b916b314336fdcfb67061d367463ed954dad1f242037c27a324ce7cbf0d49 +d891da97d2b612fa6483ee7870e0f10fc12a89f9e33d636f587f72e0049f5888782ccde3ea737e2abca41492bac291e20de5b84157a43c5ea900aef761006a4471072ab6ae6d515ffe227695d3ff2341355b8398f72a723ae947f9618237c4b6642a36974860b452c0c6202688bc0814710cbbff4b8e0d1395e8671ae67ada01 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace 8883bc18966e455e8876fb49f9c335c03dc00ee0f9171fe8a4cd29491e097acf0ed5408ce0b2cc89b7c1013ac0e34969011827aa80399a6ca038e6c8ca21c4839bcaa05a401cb84163aad1187fff13e89a0fc546a710a6d12e9141b3d42198c9 +924e4afc979d1fd1ec8ab17e02b69964a1f025882611d9ba57c772175926944e42c68422d15f9326285538a348f9301e593e02c35a9817b160c05e21003d202473db69df695191be22db05615561951867f8425f88c29ba8997a41a2f96b5cee791307369671543373ea91d5ed9d6a34794d33305db8975b061864e6b0fe775f 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8 8685c3dfaf0780eca9301aa5981a30f0911b32abe2e3126f4e70e67168d586207bbd61330d7e58d1c0a012b8a1bc0ad4097cd6ec1ab1786fbc54f8258722ef6697da353bb8ef8f4baa5c49364c4a5863cb9e76015ed4bfdde4593fe231904be8 +c64319c8aa1c1ae676630045ae488aedebca19d753704182c4bf3b306b75db98e9be438234233c2f14e3b97c2f55236950629885ac1e0bd015db0f912913ffb6f1361c4cc25c3cd434583b0f7a5a9e1a549aa523614268037973b65eb59c0c16a19a49bfaa13d507b29d5c7a146cd8da2917665100ac9de2d75fa48cb708ac79 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad 86563ccb8e8c0de1497626308dcec4dbab7b2c5abbe9e86b628461e91c99ffb999081b96ab997852cc5695c369547bea14a4b81d67706aeeccdc139a0e01ec2a9c815563b447752e7a7b84665fdd760bf285a8216141fd38590ee47f98ac0793 +8ab8176b16278db54f84328ae0b75ef8f0cd18afdf40c04ad0927ed0f6d9e47470396c8e87cde7a9be2ffbfe6c9658c88b7de4d582111119c433b2e4a504493f0a1166e3a3ea0d7b93358f4a297d63f65a5e752f94e2ee7f49ebcc742fa3eb03a617d00c574245b77a20033854d82964b2949e2247637239ab00baf4d170d97c 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a a1330dbf19f44c2020e03efae44189ffcd7f613c012d7fdc3f428cdc5310abd83c03f2c0c885a124286c4fa3ac5acf4308ba3e19f88f3ca41aa3cb1f9d3208397e17860c3357b66c9d0e5d07ba40ab0a781644e8772156b6d6bc88097bb80bfe +c4bc2cec829036469e55acdd277745034e4e3cc4fcd2f50ec8bd89055c19795a1e051ccf9aa178e12f9beab6a016a7257e391faa536eaa5c969396d4e1ade36795a82ebc709d9422de8497e5b68e7292538d4ccdc6dd66d27a3ece6a2844962b77db073df9489c9710585ba03d53fa430dbc6626dc03b61d53fc180b9af5dea6 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c 911455c8fb5645235b4ee769595a5f337680308ffcdc8ea86ff37a95b5009413406c9782d2a44dc8a2714abe1730235b13b0a42b88cc28ec94ed4ce0e1dd71de03b47dd05269a8d611ef268b676588d66e08e4f8d9ea0b68f714bb7b7bceca4f +1c1b641d0511a0625a4b33e7639d7a057e27f3a7f818e67f593286c8a4c827bb1f3e4f399027e57f18a45403a310c785b50e5a03517c72b45ef8c242a57b162debf2e80c1cf6c7b90237aede5f4ab1fcaf8187be3beb524c223cc0ceff24429eb181a5eea364a748c713214880d976c2cd497fd65ab3854ad0d6c2c1913d3a06 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d aae32a5a428f58f0a1ae510610bfc5be254c920f1aca26acc86d8e65ba4b32dd7625fd01d1d8d7ab613e77df4e0af5810eb2321d8865c4159e2ffaa8dc78f512fba473e585bd6a82554409c108feb25ec4927540e2ca37a403ac71e45aa91c36 +adb5f069b2b501a3ebb83d4f1808eb07710ac4a7b12532996855a20bcc54b2f76812915f632163c3654ff13d187d007152617cf859200194b59c5e81fc6cc9eb1ceb75d654050f260caa79c265254089270ccd02607fdcf3246119738c496dc3a4bd5d3be15789fc3d29a08d6d921febe2f40aef286d5d4330b07198c7f4588e 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c 8951f3b317da50f3d901a8e7eae39779365944a9d7cb7e53dab6cbaa45ebc3e494b3aafb8e695fba15c602c7999fbada02ae4b404e201e863dc71ff94940006372e95939eff02ca1afd4e9fd12a3d006cdd3418f456301d6387593145bbb714d +f253484d121d1ce8a88def6a3e9e78c47f4025ead6f73285bf90647102645b0c32d4d86742a50b8b7a42d5f6156a6faf588212b7dc72c3ffd13973bdba732b554d8bffc57d04f8167aef21ee941ee6ffb6cce0f49445bd707da8deb35dca650aaf761c3aa66a5ebccddd15aee21293f63061a7f4bfc3787c2cd62c806a1a9985 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25 8f8f329e92c18f58bf0a59b1fbc088bbc175c32de9ccc018deda56a4a0499e6b3a77de4f2b823e85a75f74916b09156d12572a5d3b102ea231f66c6e4498f5cc77d473a58954b516afaa4339a1dcceddff0cc1b4e76b0f4ea89c75e748ee9086 +33bab1c369c495db1610965bc0b0546a216e8dd00cd0e602a605d40bc8812bbf1ffa67143f896c436b8f7cf0bed308054f1e1ff77f4d0a13c1e831efbd0e2fcfb3eadab9f755f070ba9aeaceb0a5110f2f8b0c1f7b1aa96a7f2d038a1b72e26400819b1f73d925ea4e34d6acaf59d0a461a34ce5d65c9c937a80e844e323a16d 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf b3676051f2aba81dfd153dc0f8e9e020e45a762b1a2c7046725ebf5b6e954ef12d1229d1cfa13981c19e1b151aab7e350018052ba7f608d8ae2d22018da220923d1683d0b1296039a432d15a08e64aed5a9fd4cee8bdc38303dc6f8f72cd377b +08c8b7faaac8e1154042d162dca1df0f66e0001b3c5ecf49b6a4334ce4e8a754a1a8e4daf8ec09cf1e521c96547aed5172ef852e82c03cddd851a9f992183ac5199594f288dbcc53a9bb6128561ff3236a7b4b0dce8eaf7d45e64e782955ee1b690ce6a73ece47dc4409b690de6b7928cbe60c42fc6a5ddf1d729faf1cc3885e 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570 98d4751a1aa7d85dcc9dc4b8a3f465da2e208a2d605abab684216c8f76dcabd2cb1f7af98e6fae017387a158456cc92b119927e4a06f57941bee04d43850ae86bb312b9628a63fffde160e41ab1d103544e1f0e5f136a1c1b026d9ec73678979 +ba74eed74282811631bd2069e862381e4e2a1e4e9a357b1c159a9ce69786f864b60fe90eeb32d8b72b099986fc594965a33285f7185b415df58fead7b8b50fc60d073680881d7435609ad1d22fd21e789b6730e232b0d2e888889fb82d6ad0337ab909308676164d4f47df44b21190eca8ba0f94995e60ad9bb02938461eee61 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6 a4c3a2546ddb347dd8c39e971ebe2f93c6abbd742e02acd7bb7df5f8f147624f04071a0b9e8e8d2dfd59536e5359be3e071e6829687b259eaa9ea947a20e60f463b0d6ffd6dbc8e4008d0b6d16ac9adde7d3ca9f93dd3ddc9486c30e8ad36000 +dc71f171a28bdc30968c39f08f999b88dc04c550e261ecf1124d67f05edeae7e87fe9b8135a96fe2bc3996a4f47213d9d191184a76bd6310e1ee5cb67ea7fc3ef6f641a0ba165198040fa668192b75a4754fc02c224bd4a74aade5a8c814adf151c2bfeda65165a04ef359e39847c84e312afb66d4cd1db50d41ef3fe5f31296 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7 b2461fc3d52f4c08d4bd63abd5b74918172129525becaf3a3740307bc25b0171bff4cc3db19173eb9de194f18e132b4c07f7279ac1712138c7da1c9fd7318a7d607d7076ff1e4533fe21be7bea380a1702a0cb7ab1d88bf2647e2bc72d63f639 +b895788d7828aaeace4f6b61a072ffa344d8ea324962ba6dab5efda93f65bf64a0f2ac6d5721d03ee70e2aef21cdba69fd29040199160e3a293b772ffb961ed694a8dc82800dab79367a4809a864e4aff6bc837aaa868e952b771b76591c0bb82249034e3208e593d85973d3fea753a95b16e221b2561644535c0131fe834ae7 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e 8859d813e8cd7c4066e3450a7073c4b44b5b356806afd99ebe80b986354f06848c40c3e711bdaa64ebe35bc07c35388c15aace9de70cab80855184dd6afae38a05e76691b98ce9d33cb995f93a4420b9fde1e4f56f39c8fd3e9c396ac6cb4cdb +2c5bd848c476e34b427cfe5676692e588e1957957db7b5704492bd02104a38216535607f5d092dc40020130c04a3aaf0f1c52409834926d69a05d3f3188187a71d402a10ba34eac8629b4c6359b1095f30f710219298bf06b9f19bfc299981d7e251ca232a0a85338a7e02464731d1b25d4a1f68baf97064516590644820c998 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938 b33a5bd022132975e71241c2f19b942e449eb7595140bbdcc163d2cbbabcbf1371f7d2bb90aac555a2a007e7cbad54291881a096d0fd1062d8aa1a6869dc2833c90c606c5c6d98f8c776c21d88db2ee9ea2b12ed210bc9220c6ed7831d3ef4be +65a0b97048067a0c9040acbb5d7f6e2e6ac462e1e0064a8ce5b5bbf8e57059e25a3ef8c80fc9037ae08f63e63f5bdb9378c322ad9b2daf839fad7a75b1027abb6f70f110247da7e971c7c52914e5a4f7761854432fa16b2a521e7bcaee2c735a87cad20c535bf6d04a87340c229bf9af8647eedca9e2dc0b5aa90f7fea3cdc0a 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662 8c29dc077bc8b270987d3dd8139b9769bd8e6ade6e8176aab8c9f49639fdb7f1abe076b8a3e369b74cb21f4b07b20d0615d92b32c5892b919ba43b91ee854b3b3ddaadc0a22466e8d0ce9613d717e47dd85b2696fcc8c03cb2c20e2ff05ba660 +d6e366a87808eea5d39fe77cac4b8c754e865a796062e2ec89f72165cd41fe04c48148068c570e0d29afe9011e7e7a2461f4d9897d8c1fa14b4ff88cab40059d17ab724f4039244e97fcecb07f9ffeec2fb9d6b1896700fe374104a8c44af01a10e93b268d25367bf2bef488b8abcc1ef0e14c3e6e1621b2d58753f21e28b86f 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721 89d969731e8698b2f5dcba62119af700e016d6bb365fd63332975542240bc73e6257b9daa05bc3dbd6b8c31807c265c814e04e8ea038972a256615faa99c994916876f4bec237f4bb7a6159404fd4cdbf1a5a21f8808a42514cc8d5811f02816 +f99e1d272d0f5fb9c4f986e873d070ec638422bc04b47c715595e2cf1a701cdf88bc6c4b20085b357bad12ccba67cac8a5ca07f31ba432f9154ff1fadefd487a83a9c37e49fb70a2f170e58889cab0552e0a3806ccfa2a60d96e346851d84b7de6d1a4b8cf37567dc161a84f13421e3412457d4bc27f6213453c8519a2d7daa2 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e 8909177153207ba2b12adef560e485e01e0ca1806ce4785103bb923352c62659ab3248ad81ba2a64f04a88e09fda472d075833a4e99112d9e112476454957bb2169cc0fc6e336a9a0dcae3f2e6098af276f621f8a5c808375fd0d54c4f1a1f69 +91f1ca8ce6681f4e1f117b918ae787a888798a9df3afc9d0e922f51cdd6e7f7e55da996f7e3615f1d41e4292479859a44fa18a5a006662610f1aaa2884f843c2e73d441753e0ead51dffc366250616c706f07128940dd6312ff3eda6f0e2b4e441b3d74c592b97d9cd910f979d7f39767b379e7f36a7519f2a4a251ef5e8aae1 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418 84a1a0baeaf426239af05fe37b38721c7c92105fbfb56cf09bbd502a11f286c81183d72b8901b7e7bd65fcc2c46bbef70b0a662362fb7b903afbc0b6704e22ac7cef4bc956bd5b8a7704fb3dbdac016ca45ae1d53a053659697d261483ebfbc5 +dbc094402c5b559d53168c6f0c550d827499c6fb2186ae2db15b89b4e6f46220386d6f01bebde91b6ceb3ec7b4696e2cbfd14894dd0b7d656d23396ce920044f9ca514bf115cf98ecaa55b950a9e49365c2f3a05be5020e93db92c37437513044973e792af814d0ffad2c8ecc89ae4b35ccb19318f0b988a7d33ec5a4fe85dfe 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950 b12491e1045571a159d39f813ea5f61d5737ca1ea599be23a74ddce6d35eb68cdd4ff975134a1c387e3245ddcc4da54f042829974af716d47e0af3c67f94073df9e9d5695f61319fc2ba987de33ba9a236b4616a79f7c3665015364952f90489 +114187efd1f6d6c46473fed0c1922987c79be2144439c6f61183caf2045bfb419f8cddc82267d14540624975f27232117729ccfeacccc7ecd5b71473c69d128152931865a60e6a104b67afe5ed443bdbcdc45372f1a85012bbc4614d4c0c534aacd9ab78664dda9b1f1e255878e8ac59e23c56a686f567e4b15c66f0e7c0931e 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b a88e4e1ae725a40f6f97b8affe7ad1490c48f5436b2dc8ced6f95c5668ce6f4ab8431779e3562e99d9f392ce41bec39d05a93811f634b5953b74054d86c00f2ed2140bb542cd750c127959f04545a20812db29eb44253797b8eaed1bdf071f3e +6744b69fc2420fe00f2352399bd58719e4ecdd6d602e2c80f194d607e58b27a0854745bfd6d504de2eb30b04cee0f44af710dd77e2f816ac3ac5692fad2d1d417893bb0edba2707a4c146a486f8728ca696d35cc52e9c7187c82d4bdb92eb954794e5ad15133f6bfea1f025da32ada710a3014cf11095b3ff69a94d087f17753 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f adac8c7a0ab42df0dde65c1d959d36b420e6dc05f8b4b4aef6de172b7ef26e899007355afbbbe88997ec7c32755c3c0c0ad6019d25d35e3203575c2fa20c55351485edf95f9e7b8b7c9983659e44e0f3aff2153427b54893345cc71a37fc0839 +16001f4dcf9e76aa134b12b867f252735144e523e40fba9b4811b07448a24ef4ccf3e81fe9d7f8097ae1d216a51b6eefc83880885e5b14a5eeee025c4232319c4b8bce26807d1b386ad6a964deb3bdca30ee196cfdd717facfad5c77d9b1d05fdd96875e9675e85029ecbf4f94c524624746b7c42870c14a9a1454acf3354474 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66 b2314be7ffba59b0653e8cc6909d3a6ac514ded276852750cedf2ea95c5b8eccba13f263bb687a7d6029172e7535f30b0a6ab4e395929eb559b27faeaf71c3c60200a3fca3f8dd09e95c54b4ec0fadd397f455a99657c2af0f83d64e64c5f6f7 +a9824a7b810aa16690083a00d422842971baf400c3563baa789c5653fc13416111c0236c67c68e95a13cec0df50324dcc9ae780ce4232607cb57dd9b2c61b382f0fa51fd4e283e2c55ffe272597651659fbd88cd03bfa9652cd54b01a7034c83a602709879e1325c77969bebfd93932ce09a23eae607374602201614ff84b141 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c 93ad41d24bc132b5444b1f926f2c807f5069cea39e2274a56882f388daa13490908f752da447a1e3bc44a9b2db6ce2540af5e25c70b7a4969c9368c5230df108a736b710a1754aa32fbe4ff3e066457ce6ffc4934c598a7a23f79d1acd2ebc85 +90d8bbf714fd2120d2144022bf29520842d9fbd2dc8bb734b3e892ba0285c6a342d6e1e37cc11a62083566e45b039cc65506d20a7d8b51d763d25f0d9eaf3d38601af612c5798a8a2c712d968592b6ed689b88bbab95259ad34da26af9dda80f2f8a02960370bdb7e7595c0a4fffb465d7ad0c4665b5ec0e7d50c6a8238c7f53 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0 a3e4ae2969501deb0d0f5d2af25a042eb2961cf5f2bb3caf3fd45d29f520491d0c5bf23f1553342bdb178cee54db710018aa71b67738063786788ffea763a4bdaf494a49a1100e81b0c549a15968fcec7c41d1aa3542395470d11da7379c14ca +09952b1e09995e95bf0022e911c6ab1a463b0a1fdd0eec69117b34af1103c720b57600217de7cd178fef92de5391e550af72a8dcf7badf25b06dd039417f9a7d0f5be88fcd4e9655931d5b605452a667c9d1bae91d3476e7d51cff4108f116a49966fb3a7cff8df1c09734ce5620faf2dccb3dc5d94e7e9ac812da31f6d07a38 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9 a05a6324c8d5a599d9212761f9bf7634d44070dd858dc33486704ca647e5aef2918c33ca44b4a126407408633a15866a0c9e3e76da0304b5a52581f011fa72003f1c7b858621dc73ff9f4647dbe7ce25fdf68ed4a395b37320c7025b0a73854c +0bb0f80cff309c65ff7729c59c517d50fc0ed5be405ef70cb910c3f62c328c90853d4473530b654dda6156e149bc2222a8a7f9be665240e2fbe9d03f78a2356af0bacd1edb84c4801adc8293a8a0bd6123d1cf6ba216aca807a7eb4dca76b493eb6e3dbb69d36f0f00f856222f24d9b93ec34c3b261be2fca0451c00571928e5 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d 8a101ee62eda743fd5ffe8cd46242a3a7f2bd9a99f97bf9aff88c23a1f899e331ecaf66f882514af2e0d917ebffb2f440a308c20bd4db8a156c20d67926b424fc9478ba29ad9afd8e5a489c7a546b72c09e2ad6979132b665f917209abee089f +7efacf213382ce30804e78b7256854d759147dba9729c51b2759465715bf2c421034c23dc651c13d6cce95f71fe6a84dfbee5768163ac5789ac0474c5ddf4115684683c5f7c204b33b8bcc0c03ac58f66cef2f53b721fe2fac91ad841126101a88f512a7c2ded38549d9f050d4b7961dda48a1489f026c5d111701762418cfe3 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490 82e2eadf23dbc826f5d7bbac46f994dd9f7d027ea2d0bf16ad4cf67b2aec26d4b7e8c25e605047b58b8c3f8e7224043d04e80e329c2872d574e70677ffb271a1c4a53773a31b31acb141cdc41f019b038a11281fba89b1de7fcc39bc59d71318 +28edff8b9d85f5f58499cc11f492abdfab25e8945975bbaeee910afa2b8fc1295ec61406309ce4e09f4ab4f462959fc2a2786802466eb26d3b01be6919893ae75d0fdc2dc8a82e662550f9fce9627dd364188aaba5c6faa1b2d8a2235adfa5ad0dc140f88a2b2f103f5690e877d07fe8fd30d02d2b2729bd3d8eb5b23a21f54c 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1 a6a44c95c4a4cacb5a3d9bc03e34ab42977b12de05cfdf91c1fd2ee8600beeaf8ac5edd0178edfb34ff3fa19d4a3d2960cd06fdf59df36a89b04e64212a014084ec3a43b407be8f73268281f118672a60334b0cc8d445fea8f3663a9b347ec89 +bae2a8897c742fd99fbf813351cd009d3f2e18d825ca22e115276484bce8f82f8c7c0c21dd2af208404d8ef45bb5a6c41693912b630897d5246801bf0775aa9bbac8be98cb861d172c3563dc59e78a58ed13c66dea496471b3ad0eeae8995293e4ab97373edc1837ffc95ff1cc0c1e90e64ea8680b2ca5f1e09bf86b99b343b6 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745 93b36dd5cd9869c015c0917ee6e047e7a08eef8c24ce663b8f5275adf55ba039ac5dd5b95aa6a46171816604a410f2000510d22aaac18d3b620c97def1f4879b73cbc4741a4fea00e4e9961f0cd3650c6e426f6ffb23cfc1a4cf3e7bc74c0362 +d57a26a9593e72bfc87322524639bcaae5f2252d18b99cdaa03b14445b0b8a4dd53928f66a2e4f202fb25b19cad0eb2f1bfda2ab9b0eb668cdcd0fe72f5d9ef2e45e0218590f7ab9d2c9342202610c698bc786cce108a7d4a6730a13e9ea1b470e781f1237d3f84f44abde808516975546bd89075ef9a9732bfd7ee33b6f4399 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f 8b148b221b3a9fe69a3b9a7eee7a4fdf6d4ad25fac32ce656035fa647d615eabefee93c21998fb916ac1a6c80b1bdf48073e8529199c2895ee88b44bfebd787178788f444bd5eccb03c60d0306ed08da8489dd1e730fe8e4708322aa771d6028 +8fdcf5084b12cfc043dd3416b46274e021bbed95d341d3c500c102a5609d3a34de29f8fa9f0adb611a1f47a97ad981f8129d718fc0d6c709eab1a3490db8d550f34eb905b9e00663543afc5bc155e368e0bc919a8b8c9fa42093603537a5614927efa6be819ed42ececbf1a80a61e6e0a7f9b5bc43b9238e62d5df0571fea152 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e b732e91bc2a16c9787bd5410e51efaf1598589660bde2a25de4b0756edce6df0be6a6fa94cc08801cf7c42fbf320c893141504bbce934cce8a2432ff12050654a6479f1d0f13d78baedcf2344d1b82290ade85b9bda9579ffc9508feb6229be6 +00669f433934992257bed55861df679804107d7fa491672574a7624949c60049b0533383c88d6896c8de860704c3e6a6aefce83efa57c4d57e9ab253da5d15e1f53ab6dce218b592772ab0bc01fee8e63368e85c0639301456fe2d44cd5396a7f2b22761cd03b80eba7883eede8249a2f5db2183bf00550c5c002f45a5e4fb31 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89 b2e2de7794d8da6c59c787a6420458efded81f1ddb765cb6f2685c3fac35990e0f4b2012f8edc293c257d432747a366309afe5011772f36a13e86b483a2ef238bb7da20369c8d58942daec08384d286c346613aee555993d955471e243e5f5f1 +4be81dcfab39a64d6f00c0d7fff94dabdf3473dc49f0e12900df328d6584b854fbaebaf3194c433e9e21743342e2dd056b445c8aa7d30a38504b366a8fa889dc8ecec35b3130070787e7bf0f22fab5bea54a07d3a75368605397ba74dbf2923ef20c37a0d9c64caebcc93157456b57b98d4becb13fecb7cc7f3740a6057af287 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a a9f7b82347262f885748f696c692efb20b15c69e9b6be530b15273dcb9bdc4ba222c45bd51a1dba211406ea94ae874e9145b9662b5628c50d188e0371d3b760e6ef0dc287dc2e24476e31c35ecebea4285a2250da6584fcb0d3f1d85301bc3b4 +9ecd500c60e701404922e58ab20cc002651fdee7cbc9336adda33e4c1088fab1964ecb7904dc6856865d6c8e15041ccf2d5ac302e99d346ff2f686531d25521678d4fd3f76bbf2c893d246cb4d7693792fe18172108146853103a51f824acc621cb7311d2463c3361ea707254f2b052bc22cb8012873dcbb95bf1a5cc53ab89f 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926 aa8e736dccf9635e5ba3dbb5751f9f730d8ff8db0a758e6eccd68d68e6f6659abd3956011ee75e55af32c8b37924546819bbbf7aa196c4f245cc8bedec2d7d99a47a2ad2f58e293502ca27b47b55b65b0c326b3969072a70d2310f25cd128a95 +b3c63e5f5a21c4bfe3dbc644354d9a949186d6a9e1dd873828782aa6a0f1df2f64114a430b1c13fe8a2e09099e1ed05ef70de698161039ded73bcb50b312673bb073f8a792ac140a78a8b7f3586dffb1fc8be4f54516d57418ccc9945025ce3acf1eb84f69ceee5e9bd10c18c251dbc481562cd3aae54b54ab618cb1eeda33cf 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6 b8cdd91b4f4db55f84c98c4622626ed23feb0113dabf09bd4a31342d19c5d1145a7bdc068a8811c31ee2f73e2d2a106012c57ca3c00b98ab420251ee061b41f34893ac4dbbc3cc52839d6bf387d5903d88ed3774b68575b271ba074fea95232f +6e0f96d56505ffd2d005d5677dbf926345f0ff0a5da456bbcbcfdc2d33c8d878b0bc8511401c73168d161c23a88b04d7a9629a7a6fbcff241071b0d212248fcc2c94fa5c086909adb8f4b9772b4293b4acf5215ea2fc72f8cec57b5a13792d7859b6d40348fc3ba3f5e7062a19075a9edb713ddcd391aefc90f46bbd81e2557b 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f 957cf72b64602b5f34ae600105ef90b6aa7ff19a1bab8d8da64de6968b25c172ee33a35ecbc9b51a7fa055bd41414bfa094674a4eaedbb0ab1c41e0447aeef3067225b400b78bf88d45b3eca4b98a2522cb46668c5c72859bc71c7b108b56c18 +3f12ab17af3c3680aad22196337cedb0a9dba22387a7c555b46e84176a6f8418004552386ada4deec59fdabb0d25e1c6668a96f100b352f8dabd24b2262bd2a3d0f825602d54150bdc4bcbd5b8e0ca52bc8d2c70ff2af9b03e20730d6bd9ec1d091a3e5c877259bcff4fd2c17a12bfc4b08117ec39fe4762be128d0883a37e9d 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742 a4e41bf480da4a624b0010275c8759b975dc26cbcda46a19cb50631c1b36e7e0ed625e991db7e2e5aafc0a85c446abe311489373cfa0faaef4f30a5f4dd2d6ece0068fdf8e813dd547d91dc1bd299c95b4d253d1c717e03af4814f696b1e59bf +a1eed24b3b7c33296c2491d6ee092ec6124f85cf566bb5bc35bffb5c734e34547242e57593e962fb76aee9e800eed2d702cc301499060b76406b347f3d1c86456978950737703c8159001e6778f69c734a56e5ce5938bd0e0de0877d55adeee48b0d8dfa4ac65fd2d3ce3e12878bac5c7014f9284d161b2a3e7d5c88569a45f6 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697 a7ff07efd3e760b6410d875040c3232f43718e5c84fff09a44e1c7d091e9cfd985bea436706692a59c2c0779a80216ff0a413bf25964e83453d7174258b4ab68ca5e520e05a2712801f89d9bdcdcb0f60f03eb81136ea6b36ba3a8b152b08378 +9aace26837695e6596007a54e4bccdd5ffb16dc6844140e2eeeb584b15acb2bbffd203c74440b6ee8db676fd200b4186a8c3e957c19e74d4d865ada83f80655323dfa3570907ed3ce853b6e8cc375ed2d758a2f5ad265dd3b47650517a49b3d02df9e0c60c21576378c2b3a08481eec129b2a75608e13e6420127a3a63c8a3f1 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04 82a5265c4cc310fac8eea317cafdd5a109af99728e0950707a5e9701b1edd22749911f1250d53cebe854252cfb1d01f21654f77e61f0db51aeb157e04228f8908edde869c520c37bf8b0c4230faf78f4f30654d98ccbfdebb87641a50303bf63 +ac2175940545d4fbab6e2e651c6830aba562e0c11c919e797c43eff9f187a68a9e5a128e3e2a330b955a3f4577d3f826529ad1b03d7b60f7ad678f005053b41dc0f8d267f3685c6abe1a0e9a733c44b2f3ca48b90806f935141c842e3a6c06a58f5343d75e3585971a734f4ae1074ce5b54f74bd9342f4bbca738d260393f43e 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6 b8923d3308d833d690e33fc6789e8502155341876a84308a5470925123ad94095b2cafc073aa4e015aa506897fa746e717d65b026638b49837ab027d164f3aa0e5d5b974fd5d91375a54914a87d2e8165a45f733819f2e78687c9b5af4a9fb7e +6266f09710e2434cb3da3b15396556765db2ddcd221dce257eab7399c7c490135925112932716af1434053b8b9fe340563e57a0b9776f9ac92cbb5fba18b05c0a2fafbed7240b3f93cd1780c980ff5fe92610e36c0177cabe82367c84cee9020cf26c1d74ae3eb9b9b512cb8b3cb3d81b17cf20dc76591b2b394ef1c62ac12ee 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e ab6192b5adaeccb0967263b9749fa39b38dd3e206d48375921b69cc4163547f82ac289cf40eedffc70226ae3fede59b90f506651833ab129d18155f9d52ba98b2d3d3c4166e4df9c52e07456c954507f5b3ad89e13ad9f8888fbe7919894804e +3de9e617a6868dca1a1432d503f923535da3f9b34426b2a4822174399c73b1c1ee67311410a58c17202ac767844b2024d8aa21a205707d93865693ac25a24fc87034fa3a7a7e27c3344cb03b87602c15180a5fe6a9dd90cd11af4a0f150207bf2d83f55b12c088adae99aa8cfa659311b3a25beb99056643760d6a282126b9b2 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5 9764452535219ece49a054308e460206633cbbcf0df97e6a728ca41e6907eebdd3bf68c5673994e0bf1add53c0d4c37d1214df89172c289619ea89b2be8ff46266b902e59e9229bdb7ab175ebac5a3bdaecbcce8e0564e0de2c8eaef9457eabb +aa48851af7ef17abe233163b7185130f4646203c205e22bcc2a5a3697bcab998c73a9ffe1d3ea0b7978ce7df937a72586eb5ca60b0d939a7d1c115c820171c89c8116b7e2c7b98cf0f14e4c4df3cb2f319ad3ab0ea25ff14526ddc037469f000bf82100acd4cdf94feb4eba4ea1726f0569336604a473aee67d71afebb569209 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a b7fcffa68c0eb3a8b818e961fa8d91809e10c47a80aec8093b3a567f1e528be86b9026b91948c2a764106d6f34a4b7410c7fb05e19b892dd4048c4112edc01b47e1bf5f23f74a8af6e2b472a8eb9dbd97411dbdb204452088c9fda41810a8d93 +b0d5d52259af364eb2d1a5027e5f7d0afe4b999cc5dd2268cfe76f51d2f17b541bdd7867e23a1bb897705153d9432a24012108979c6a2c9e2567c9531d012f9e4be764419491a52eae2e127430b0ab58cb8e216515a821b3db206447c235bf44ee304201b483b2a88844abaa18bca0147dfff7e502397dd62e15524f67eb2df2 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb b656d0a142db0a2400f1c8b8be76ddddadf6abc76c4700c8f6aab6c8eb58a08810df2fc0c451cdbcf9b65c9e77f901f40fa71131cd0d98b8ec84f529fcc0be06ea4adf6b97f380b3e4480b7af7c2d96848dadaf00f60444316bec4d97b57330c +9599788344976779383a7a0812a096943a1f771ee484d586af1a06207478e4c0be9c200d42460fe837e24b266c8852d80d3c53cc52ffb1913fc3261145fc6da575611efd16c026059a2e64f802517ffd1b6b34de10ad2909c65c2155e8d939b8115400c1d793d23955b15f5d1c13c962ff92b4a815cee0e10f8e14e1f6e6cd38 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77 b1f749618863e32de0f105158e9f31824a06e84cca87cd92872c6ab3799c13474d37e889df7bfb1f897565247343ef5b0956361d41e80cfb9da91c85b67df9cc6d1b68488516f290c28c0e76d6ecf4fd95e0624513fd76457626837f3f6125e2 +fdde51acfd04eb0ad892ce9d6c0f90eb91ce765cbe3ce9d3f2defe8f691324d26b968b8b90e77706b068585f2a3ee7bf3e910528f7403c5af745a6f9d7ba6c53abd885c3b1be583415b128f4d3f224daf8563476bd9aa61e9c8518c144335f8f879c03696bddbe3ac37a8fbede29861611feaa87e325e2f60278b4893ed57fb0 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c a90a069a888c45d89097447e11a3b4b1602af851f8181b3ad5fd22939fd01fd379c0f01f332c32680da0b0b89f169f4f0cc9b5d911480331996fedd3c2d236b7d9d6acb721b944972d7712fd88d2b7e366060b1e3aec38137c3d31c36a52e391 +beb34c997f905c77451ac392f7957a0ab8b23325bd5c63ca31c109ac8f655a1e3094240cb8a99284f8091de2ab9a7db2504d16251980b86be89ec3a3f41162698bab51848880633e0b71a38f8896335853d8e836a2454ecab2acdcc052c8f659be1d703b13ae1b090334ac50ab0137ddb5e8b924c0e3d2e5789daaef2fdd4a1e 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63 84f725c728a4a523fcce7eb2a43f39e28701a1cc5008dbcfdebdbd5d55d4630c90cab9e4bd866196c246ced1e27e4c4a110db79b278005001b3cdab601cff4440d7e3f5cffb2505e7c421f65570498467cf2615fa48e348461bf83d4e144b37f +543c374af90c34f50ee195006d5f9d8dd986d09ad182fcbefa085567275eee1e742bfe0af3d058675adeb5b9f87f248b00a9fbd2aa779129123a5b983f2f26fc3caf2ea34277550c22fe8c814c739b46972d50232993cddd63a3c99e20f5c5067d9b57e2d5db94317a5a16b5c12b5c4cafbc79cbc2f9940f074bbc7d0dc71e90 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da 8898e9fdf66fecd90df5bfa7bb646eae6aaf485d84ba69c9323ab065d66b0d448313659a1797e9a8ea790b20682967d20e2221e683efa81d2d894101f00a3a243cfa2c04c756eee73dece0bfcaa457291a7de8252f57ce21f0726239fe3233d5 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_rfc6979 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_rfc6979 new file mode 100644 index 000000000000..2528a10d27a8 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_rfc6979 @@ -0,0 +1,34 @@ +73616d706c65 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 a860b85ea2404f3da457311824568d7dd8039de8ab17bc37b21189a67eb778318c6538a5b7a7d772e12c28eadcaa95ed031cef88364bbbb4c5f36862cc7003cf137a017f17ddb0038f7428f5650fd672a03cb1e0316eea4e02e878ac7f03a3de +74657374 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 b3def9f9589c1ef8dc06092024793f9c5c8760e10b1f656a065a9c3334e24f3a92b6d522b15c22e7a477565fa625bbec019a9d351f33a6efc54ebe33adfc1dabb4937db99dbb716269fc54c4794bb12476fb6422d559398296447bce3f9fac4b +73616d706c65 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc 83864d59a78bcb49a960f048c00cacdc698aee7cb0e0bd2688f56070059c70c9e6be0e5b1c4e22df2f431e6a8a5c0fdb10e413dc4a38f93026f741e0c9d8cfee5e4fd4d2f79baa8604572cf8fbf1ce4226388a7fb57d7fb2ac4d1acd3203ec4b +74657374 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc 8b8b465571ed78130f12268f4297597bf3dca5f99fa555aa875b749e34d8cdf5dd96d589b963f4642a47e71602aa9508029aaf29b49071bc06d0dacf3369db37d716a233c9780e4b436dbff78a15709647a9e70987eecc8aaae48f3d79314058 +73616d706c65 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 807ab333f3efebdb0b93d2e5a7fe166be1e62022d1f2571219e44cc9759ed4f46f4994aa64071aba5d519e3b1e507d8e16147034c0cf3ad7c0ada9a2d3f305f707f924561ffe9477f81641777dab2d65290b21901dd39fe93001742af441f50f +74657374 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 afc9c8047797a4d59e426cf2fce6a05842ec6bfc3467b8e99f8546c5f48ba310f6af6b9834214b1c1ff2ca71b6d53c1811c08229adc6324d97b7fb9f4fda283f32d3464976d7111c9eb4eacedf3228a95dac3cf9bb406cc865de627e3e7e20f3 +73616d706c65 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 89d8ea95bbd3e180599d634cb0eae4fbb08f756282862ff77acd210bc4f5cb8164e65178a85825f26a5a08ece46eede40cee491488c6d54586a0010282a3314881f25354952e6e25b5cf556a63fbd274412c2a36458f67d86d883a20791148ea +74657374 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 98f89fbee2815520244f79336e41c357f32d19e8158c11962ac812f6241963bf36eeb1821ff1fdd34fa71bad797f89e411f2b47e680b06460ff16dbbc3c497d988c05c62681c36f8008054434fe969a04cff981442c22c4cc36870c9577f217b +73616d706c65 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 b168302c7300b0e95cee012821455972f90184b17ef85d3875cea08a87919268d05b3a105d5592d2cf9dd1083794177711dcf0269e0ed32734546196629c2b3ec06fee37f3304a1699c6240ea377cd792a2aaa036342ed78a4ffc516129d9434 +74657374 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 83f18b890d8fc288a6ce15a7934e6ca5cbd806e5d4af592d90bd2352d06c82dc69ee3ba0a28a848aabe18af20ee45055085ffa3f95c725ea034c780f0d1793f182d65c82932152f96defefaacfa89ad27951319f9ae2113fe7c2d97d5ada0175 +73616d706c65 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 abfce0fd045169e4e794af589d09967673df2b191b28f1c67b6f48774f9c4fa090fedbad4bab05943bc517f487ec49ca149463b6f3c7910069fa0011e1177395e837c08fc8d3c8ebf7a28c9d7d5b0baf0969ed44a2bdd22b160e2a638781774a +74657374 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 b91448fa5dd13e370c0f3774ee0a530adadfe7579942c277c5d20a05c13cfd474b4d66a59c6436dd04bb024d7d49face04215f552f78aa584c4b901d9c3ab9f100a31735a7cf306913afdbf855b1567c3453f4b84fca3b54bc9288ec292f7c88 +73616d706c65 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 8db1c5dc67cd433e821041c9eb82ba56a3f3caccf11d0fa3945d36428fd0e342992a1f18ace92708b48d5c05a8567cfe00469ef9debb46af6ec91ad3313e26c4d89e4fcd67da722312c00debeb3edf72f16c5bdc05124350c325cb739d4848d4 +74657374 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c a006d7594f6398f0a40332cd64bfa3f43c76a7bc0ee0a79204e9aa6d6cd3fbadb50d17ec755a392f076620a175076fc8057ded78cec496884d6f98a473ef101a8379db98846de403cb6955b31b149d3539b6bb5382275ae94ef9777c06327272 +73616d706c65 9a4d6792295a7f730fc3f2b49cbc0f62e862272f aabe3fb351ccf7a34cc8e6e851f8c054911ae7e279af7796ed4ed24b4de172e7bc985640011248e69989d9e3f61885f815161dcf6551a861af7a58bd1f1a818ed971e26365ebd6f4f8c4d115400a156a14ae27559ff2cacb8896115c61954b7a +74657374 9a4d6792295a7f730fc3f2b49cbc0f62e862272f a3303ef87cc46cd0e3e5fa591f24b944fae0ff6d64f0c7614f900888f5d33dd47aa10f380f9ec1c126b813886cbd2608193aaae0b7b4f209e177b1e178e1b8c7bca521198f9468d3c101af7822a9457b96c441590d38d9e887e8d9497946320b +73616d706c65 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 8fc06f9ece2342724e8c87c78d36165a8afda696266608c0e725e909f096faa125f50306dc38652caa58548acc9fb01e1497a16d762bf2292bcf8163fe18692e26c5312d6e11db4b351d30a8564c767bd17fe5c6a604f361f76dff5d3a7de130 +74657374 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 9681c85999e1d675c780993419239f7fcbfbb2d36544811e3d8f1eaf2b1ec50ed3be2da0354b8e933836363a5fca03ff0471d172f07c9cb98c6c57e13e38b1319c390ee0c28af41f05833576d8b89c9bc9ce934e955b07299ac5f2668e1a660c +73616d706c65 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 8b03af776b27977010a3ebd6493ac880c5752564ba7226e5fa0648540c2047af4527ddc6d34d18a8ace7e75c5a7509730d2273020c88816d1a41da31e64ed1e721c9831baa3f1e30f1e22d38257153a856317ed893755588f8a76fb177660ff9 +74657374 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a a0c999f0d5f0eed159b4c5e4febb63b039a6d83722d765f7672ccb4cf2fd6672582c27550e8873ddb1d45412e61cea6604e7b764264603b8f318bc901634f10806d590b4a7b4a159be02633541c4a22cda92be883ec9cd3450b7443c96ba2b97 +73616d706c65 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 83126031a99c589d0b58e9341425d7ff51a0d54afa054229b39be38686dfdcee97c5738d21ca63ff8e079e5900626a981148b32773579554842b6a68a449fe53aedcc8dd72c72f6cd408abdd9b91132a831b07483b54b76715bce08a234106fe +74657374 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 8cda800cf64f8ec7016b508d886ba99387b6ec30ab322a9152727a0db3c8fd665e376281afc430d010eb2687a6fd7dd50bbbca59e404593af5273fb22945f92b570a896a09b6924732bf41daf8f4dc6dd5f5343fc188b3b8ee321b5207901dc0 +73616d706c65 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c b21fe977078d2810b25f55416bf71b82ef8bbad9b9a9819ab350d77c9e312e429908475f3ae05199e72dbda0d1b9979a184aee1e52577e85ab28467500325a278f3cd131be8be106c3c690239e6b20bbeb04b6eb643ad7c74f5674458bbdbe87 +74657374 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c b959f6870c63711ee771c5ea27332e4380ef9b927846340a069029bf6540d8e19389818224775a6704a212b9c16a44a4157a672de29b3c8d41a2af70fe89073c8058bef68f86ea0e7ca0a0a8675806fac3c7c98054c7c22f8cd53d9b291b560c +73616d706c65 035318fc447d48d7e6bc93b48617dddedf26aa658f 9380c190cb26089f6c4ff4eacbb03c3216420e3169f1a124bb6ef3fd4acb7b61af2634eb6052a8549339577f172543d518552cac08c1cf2b867767932ea91d515a56f92bfedaa36f1f7a943a08ad3e3c280168f349ee04f100590f00163265c6 +74657374 035318fc447d48d7e6bc93b48617dddedf26aa658f b4468d5fd2d0f8154aaba2f07b12f6d3f6e506d295b108003b0908b297c9ba1e4aa5670a88229b268ca47d0b7fea3897117bb4bcfc3825e4d4f9329244a4b7df467e808a1dfb597d4da48e040d94dc1cfaed54bd6ab9af8e1c270956ad06376f +73616d706c65 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 abfea2b33e8c2321b61cb83fed6ad2b478f5ba8a92a44a2e5ac03cfba4e9c4c6a6ec62740bd672358a001f069e426c08162559507a3f7430e552b7a6124a97a9c2e0b21ce2b6d24cb2f9746b56e73961e10f4a0ab9567031c26d14b36c107dd6 +74657374 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 b7fc3a1d60dafe446d83fc9060046221dcadedb72a0d8209877387025a23defb456f18b42684f3dcca75355c88ae97b80532aa274797bfcef1476ad4c7ce8e87c8f34e37c6fe472cfb7eef5999fcc7cb4a7208210aaa3af8f0342869d9ca44d8 +73616d706c65 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e a33f7123fad802faf992d2d395113d9aaf86c289138701ec537638378303647f40e1fc19ae2c078c09d417d128e0943401408809b2efdfb23bf99b1ffd40ff3932c7315c09252d4064caee30b21d1c03cb764d2746b9f835140e48893fdf25eb +74657374 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e 972746630e84a811913761dcae1846f517879d8a45b39981000935e098ca70ec8bd41c510adc8ad3cdc1a45ba15e139c0fed202a09ec538d8889115d17c8815b29a6177d1018e95921d4f531e157d97b693638faf0849f917146ea8be033c88c +73616d706c65 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 a8f29abf21ba28bb7ea4ce7d7277c1f4ed66d290cb07debaf307e92b27ca16c17b35754b75d6710bccd4af636dab9118026781f9cd50b5af97c1be0b34963fcc5bce721c958f784026e528dfa4a53798947a45e2f113f220acbac9ac2bd57022 +74657374 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 b8f218796b3fd4a0113fc5540f5e22ededfa641049509b350b9a1a38b2ba90ef70e1ab59d8383f19534894e4379e94d4008d1c7dbedb6b0ffd13c7b294552c89fe4a7c8ce9550221c5ba42bea2b77f19e55797f5a752637ca3297cb4987edfd2 +73616d706c65 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 b0597c40ce11d478571554b895ce3d5fcb2e2ee1713624fda6a0e8f15a14a131002fa63ef2c79d0531c4b0de7c0dc235066216cd16ee46533f0df0229129edd2f1f4045dae6dc40051a6082e44440b16e15b92db9b557c0ac2d93b4805f79c9d +74657374 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 93f761a8c133e3254c4fb9e7e5d39be95ef416d7ba95d7ffc3fd2ea6dc23510a101f11a4d8f1515cb9ba10277ec22b9c117683579df98abd3a8c95119757188bfd23b656dbb363c6b40266c848eb60380f5c82c20a3518029c447a4fe6eece15 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_rfc6979_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_rfc6979_blst new file mode 100644 index 000000000000..90c98b662afe --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_aug/sig_g2_aug_rfc6979_blst @@ -0,0 +1,34 @@ +73616d706c65 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 a860b85ea2404f3da457311824568d7dd8039de8ab17bc37b21189a67eb778318c6538a5b7a7d772e12c28eadcaa95ed031cef88364bbbb4c5f36862cc7003cf137a017f17ddb0038f7428f5650fd672a03cb1e0316eea4e02e878ac7f03a3de +74657374 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 b3def9f9589c1ef8dc06092024793f9c5c8760e10b1f656a065a9c3334e24f3a92b6d522b15c22e7a477565fa625bbec019a9d351f33a6efc54ebe33adfc1dabb4937db99dbb716269fc54c4794bb12476fb6422d559398296447bce3f9fac4b +73616d706c65 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc b007158392db510d0f151432c2768b0bf6aecfe8afed8e26f0ff67c7c9772cd93066f7580f38171e0cde8ef084f50ae916b9594d2317bac5f80901d525a857875720d53d58c49509a48be963629efe04018915b35893f345bc3ff70e4f1bf151 +74657374 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc 8328adfd9e50a532860eb201582fff0a5a85ef82bdf8dccf5a531843bcac2f7cd4e815972e839230d7026d88acebddb31368e153d9d4edd05e17d128f1fa085d8ed5cad7d6db123cdd5bc4910444c33fe4364a09650019dd56afda4aaf3b8ce6 +73616d706c65 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 807ab333f3efebdb0b93d2e5a7fe166be1e62022d1f2571219e44cc9759ed4f46f4994aa64071aba5d519e3b1e507d8e16147034c0cf3ad7c0ada9a2d3f305f707f924561ffe9477f81641777dab2d65290b21901dd39fe93001742af441f50f +74657374 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 afc9c8047797a4d59e426cf2fce6a05842ec6bfc3467b8e99f8546c5f48ba310f6af6b9834214b1c1ff2ca71b6d53c1811c08229adc6324d97b7fb9f4fda283f32d3464976d7111c9eb4eacedf3228a95dac3cf9bb406cc865de627e3e7e20f3 +73616d706c65 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 89d8ea95bbd3e180599d634cb0eae4fbb08f756282862ff77acd210bc4f5cb8164e65178a85825f26a5a08ece46eede40cee491488c6d54586a0010282a3314881f25354952e6e25b5cf556a63fbd274412c2a36458f67d86d883a20791148ea +74657374 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 98f89fbee2815520244f79336e41c357f32d19e8158c11962ac812f6241963bf36eeb1821ff1fdd34fa71bad797f89e411f2b47e680b06460ff16dbbc3c497d988c05c62681c36f8008054434fe969a04cff981442c22c4cc36870c9577f217b +73616d706c65 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 83ec771bd093f30410a75d6a05eb90824029a410b57d4bf4d5cb817890f720eb4926d4570d37669e1e51a330da89a5a1062ba1cef5c36aeb8bbef01b8331d44a4bb4b9e04c3df7f5e3ce47dc0afa7250d56bb39734d25a6fa2e22e741f2eee7a +74657374 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 b31ea34f01603ef3e8de28445ac5f9215c4257605304a0202a5b13a94682d59eb4a75c303bf785bbd42bc8a97a40a81006a1e2aa5d9c3a73f54857e5c6c67abb23dc9825a20783473f8801117593c81eb0959bf72169d1fba81b7f8ae96336fb +73616d706c65 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 840cae8ba043389472c47bb71765d58e222f1271a71a9e5952d9b0cc5f09c21543e4cf4aabd7ac501e94d7594a09ec430055ebe5d2385d00c2262ad1dcd1a382ce0c0715f28c1c4607e86ffafed4ebc9a46a10bbab1f6214debda2f2729c53a6 +74657374 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 b47806869a0856c030be6e4854ec05460f561f4fd2d8d4a2ef1fd9dc9294e24f5a1a8ca630f0fa98ccc6deab263b8dd70d77fe375c12325e2af1d847f0ff49cca5cfac594a32fc794e66a3ab0a68cf2f9bd75ae0a627aa753fcf8be0d5679566 +73616d706c65 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c a4eb78b175791169a0b5daebeb9c2ef45b7c6abc75079ebcc9d099ed2e4133756062912c5eefa7569fae3a5dcc69d629052b08b0e106fa6250168e0acdc76ce2a7a0aae2315f64ba07c3471a1a68016afc9c762237929851db94f7d33c16bfb4 +74657374 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c b5e4d39855b7b67e7261a5f23e098a50695d24ee5578876b93c5c59f385deb70b7271b1c20ff1a33c4529726897e3dfc1344feba92e0b08509ea8423cfa5125833ed0683b70ae32cf991c7251c86088ebfcc69e42f92814139f51765038c188b +73616d706c65 9a4d6792295a7f730fc3f2b49cbc0f62e862272f aabe3fb351ccf7a34cc8e6e851f8c054911ae7e279af7796ed4ed24b4de172e7bc985640011248e69989d9e3f61885f815161dcf6551a861af7a58bd1f1a818ed971e26365ebd6f4f8c4d115400a156a14ae27559ff2cacb8896115c61954b7a +74657374 9a4d6792295a7f730fc3f2b49cbc0f62e862272f a3303ef87cc46cd0e3e5fa591f24b944fae0ff6d64f0c7614f900888f5d33dd47aa10f380f9ec1c126b813886cbd2608193aaae0b7b4f209e177b1e178e1b8c7bca521198f9468d3c101af7822a9457b96c441590d38d9e887e8d9497946320b +73616d706c65 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 8fc06f9ece2342724e8c87c78d36165a8afda696266608c0e725e909f096faa125f50306dc38652caa58548acc9fb01e1497a16d762bf2292bcf8163fe18692e26c5312d6e11db4b351d30a8564c767bd17fe5c6a604f361f76dff5d3a7de130 +74657374 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 9681c85999e1d675c780993419239f7fcbfbb2d36544811e3d8f1eaf2b1ec50ed3be2da0354b8e933836363a5fca03ff0471d172f07c9cb98c6c57e13e38b1319c390ee0c28af41f05833576d8b89c9bc9ce934e955b07299ac5f2668e1a660c +73616d706c65 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 8932801642759407f27e695f0019303f33c639c009138ebfb47101ed0a141f40ebaa8cb3dc27ac9e7b616ccf08cfa5b501def62c6ce3192e9de042f11d36b6f1e51e93317fc2d551341d8547755cdb8a8988183e6d5c378301f9ad52bf736bea +74657374 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 81c6dca3e1997cbab4df74a2f601921829fe62d2f4a37fdb30b051fcc94b78a7ec279f42fe41982a9d6fe44260290b8711e5acbe4a4e7504930e73b6b4c214dbb3c1df1fd9f1ea63839d954b59c21f2754b2acccbf7d7a0d43c178e945c4241b +73616d706c65 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 87f91d1159ca7ec0baf04fa09ec6ea7dff2a3c303ae8d6a100eb046726f17b528f3141834afb7a34d7bee41d301ba3fb05107af474e6c8c2c883db81c1fd80b8bec0b5081ec2011318d04ec77f2c6da1a022663dd50301128e04115d9bedbe22 +74657374 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 981469866e51d82fcf27e693add4123e6eb8dd5ac2cf7c193c5581fa966f91ddc50350552c36ab4d12c711c91f8fb9d004b409cda6826d107eb2c16247fe8f385782965bfa817b965ae1ff0b7d5246cf2ed4e6cd0d0d07bbc4b680f503ce7b0b +73616d706c65 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 8928792700d6dc7c1420e390b9181f372f8fa1d20e48d3c398b86266e98f02fe824674758e4e29d4bad2f733f237493b01ca0883dd4d47bc9051a1eae1f23f0fa4ba454cf82cf3640959384ea317afe7593c15d704bc431e3df7129b6844bb41 +74657374 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 93667e916de3257c68bcf0770bf7288747800bce69523be5586fd81a77ee9d8b082619bbe90d73d36dc81077506e04960495fff3019c5f5a9ed51b34606ee757af690ac6667bc62110b241bd305c25b0b39493de1dde0065ca3ed895e4a05837 +73616d706c65 035318fc447d48d7e6bc93b48617dddedf26aa658f 9380c190cb26089f6c4ff4eacbb03c3216420e3169f1a124bb6ef3fd4acb7b61af2634eb6052a8549339577f172543d518552cac08c1cf2b867767932ea91d515a56f92bfedaa36f1f7a943a08ad3e3c280168f349ee04f100590f00163265c6 +74657374 035318fc447d48d7e6bc93b48617dddedf26aa658f b4468d5fd2d0f8154aaba2f07b12f6d3f6e506d295b108003b0908b297c9ba1e4aa5670a88229b268ca47d0b7fea3897117bb4bcfc3825e4d4f9329244a4b7df467e808a1dfb597d4da48e040d94dc1cfaed54bd6ab9af8e1c270956ad06376f +73616d706c65 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 abfea2b33e8c2321b61cb83fed6ad2b478f5ba8a92a44a2e5ac03cfba4e9c4c6a6ec62740bd672358a001f069e426c08162559507a3f7430e552b7a6124a97a9c2e0b21ce2b6d24cb2f9746b56e73961e10f4a0ab9567031c26d14b36c107dd6 +74657374 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 b7fc3a1d60dafe446d83fc9060046221dcadedb72a0d8209877387025a23defb456f18b42684f3dcca75355c88ae97b80532aa274797bfcef1476ad4c7ce8e87c8f34e37c6fe472cfb7eef5999fcc7cb4a7208210aaa3af8f0342869d9ca44d8 +73616d706c65 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e 824654670f0702abfb12f533dc24feb28c9d518223663e96d59e38f714fb540873ff53fffd1acc3c5b8e1d571e7037ec0a0c23f1c83230e1830d2ecfbf9cca09bd7cb1837d23ed6dff48d45351ea22f05c10b8490dedf08096e23c475e369307 +74657374 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e a7efea38435b32a248afed26703051693773fa2ade5c1d564360271b0248e39e101b45c29e791e51152a642792d51016123da18657fbb104b156b32ba20f3b61236d0dd0ca6e6cb8419ac3707e031be6fd2af0ea74ef9849d6ebba6a7eb5f03c +73616d706c65 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 b96d1d0ddb524126bc5d8121bb9f63095294b8110eccbc7472ca17417793296a495fd3c1d51058f00772076a9a92224c0a8140d1d6866999c92ab03b2c094e19fc8c8c3f494d2697de969568538617c7e89ae77fef6a94b4b9fc90a8fed6efe3 +74657374 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 a1256a0d7bd5936bf189bd9f3ca62d08a29ba43caa4fb1b21234664edf91c48862560bbb1f3a5a9be15f671ae745b1571276b7234c90d5bc39ad014367ad721555d6eccfff99c61604eabba2a0673c29a969f70fa381e0c2f9619cff2e848637 +73616d706c65 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 a00917e97522e4a778720543e7f47ce9be3cd99e712c3114c52ffb9671714fda9d878cb1f976c1e0b143d58a93a7cda20dd09e9e8049378f7be965c5078ddff8064d672aed766a1edc0c41dc0b68513b36fd543e5d81afbd7a39da8121fa081d +74657374 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 8efce6c04d29bc74c6cdf96478fe811251a3a61be3c561c3f3b09bb0a7ff1560ed79437c30901556136c20be4f29bbc50e5d6c2b3a1f009e6d6d3210557f1bbe405aac8d0f4aa5b26b29829ea20f30d1f11c74e4abae1c0264e1c2fa9cfb0966 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B233 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B233 new file mode 100644 index 000000000000..57a1683fad75 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B233 @@ -0,0 +1,60 @@ +f1b67fde01e60e4bb7904d906e9436a330c5cb5721fd4e0a3c75b83dade868736bb1d21cfb1b5c6407c373e386ee68ec2239b700e763728eb675a153b8ac44cf2a87be85fe8ed6683430cf4b7d718891cbf8d583d0a37cc952cc25fe803a7aa4fda80f05541a2f1f2601cdd0c095f7110f2a84f7d641b8531572269b21cbe77b 0056673197bfeea9bd7a8b820b4ae51a50411bf118a692bb9ed3d304da53 b8dee566effcf88ee86e0a318328be80763d7031ad303f491506a1cdc24106ffdf75db569ce958764079b78d45e2ee4305c58a3a5896bcc039e5d458ed5fba2892f81f241a37f9a454df926fd51de5620ecdb2d6449c346cd998d54f67098beb +1d496d96b533c632ed6a91f6e3653cdffaa5b8cc0008b35e49b2dd52fe261105c2ec7ee71a4ad5d51fdc3d36d688a3b7ccb3b3b0c3a65be17b8d8aa172e3005cfbf37a2d1b1a6e268c090c6f318e7e96f9ec9b9f5a8fbcc7558d89e840f7e76e44bed91c26ca48e6f5cbc253ca2fe8cb81c484cabd24070e488f9c00cd96ad4f 00468f01d483144e514ec257f2e5fdee28a927f2adb19714c1f3524dd0d3 95871893f161867f95e4a6f4fcd9590d1be4e969ff596a1515b003b4c777b9d9583260ab736870a42fa6988ab0d32807082f0bb338bc53351e63ebc13b9ebaf1bc25dc48b0a6bd62953653b28f88ce29747a729add41363fe97350b285b66056 +723400655027f474446843645757f7e2cd466bf97275067b4bc4c9d79bb3b19b2421835d69db916f24b77c381fa771fc1e7a19d2b4d09411ae55acccc615b16fd24705762b441ab67083a921fd4ae569ce0de69449aa96f5b977ac7dc022fdc8335656853796f54b3fbd118577f98920624eb0a00204f1ef83827245c06646cc 0074052d027f05465a8083a59cdbf32600224e1f563f653b34314651517f 972a8e92be7ce607fc1acafdf3cd238e42ed988fb166faf378b3d1585f2cbd0aa61d51aa0210a097da6f6ff66f88f4d308379e2e1848e223a9e873720440c53770d6fee0c3252f0c3a6b25a35f2fffa0631a76cf3d66bf8aad6e24015e64ac86 +155860cb31a142082bcc0bad828d747e916392d21f1873b3a3c1d28ca3ff9d45ddb66a712e3856b6afd07c8d2b2a7badab296a9775b03f6fec0befa2d8d6d00fe3938df244ab46e836a3e686c8b4f918da49f0bb3940bba34a9aa22c7caf02df7758b0de01d9f47af6146344b9be3842d9c055eaf0fb399cd8db95c544a62d8a 001856e7544223f55f80de72a6ef3822fa8fbd68eb397d06e2d76ddd35e0 975cdaac165d595bbf626c429f0e7bc9f077f0324d9d18ecaf1825c9d35c91889f48fab6a54fff79d46149ba4da4943910378b0013170fa544294800d15c47ec53415de73a020d1687c9b97639928b2e899e59bab5c7332188526251c8e17829 +cbd6e305cc9f0dc90caee6e65a74582e9357bd25c78e33a7b14e1ac7e9397ff4466f192fb432143e6df6d61a0ab808ec0a361a6d95a357a38cd3e241fe03ed883ccc364b248ee2a08702110745c2688bdcefa33c1a45b9c8b200e45cddf3e3f66b8d37eff07fbb3366ea1558ef304085613c56707095724b3e134c7a7d3f8dbf 00860aa2b589f2defc617be73e191502e5d9952bf60547fef19eeccbca26 b37010f02967dfbd0e762d395f9e4ffe06941bcf4b59a453ac0680be60bad3f1ecd040d01aaa28a8ac29f19cbb51cdcd1079dc545390506a9ee33276fd3706a51fc7b25e63a345896ed2c2fcd2eb1b85251d2373d0855abad40f77473950a0e1 +812a218ff1ee1472c189f63386e5b8ab341671c3a4dad27a8c6249d1c0f9a29338b471b6179f17a078b6504e804ac55ca3b13e68a623041bc1a092ea2adf3fa1124bbfeb161e6d7c483433f1548763b84da00352a6386e1339f674d45dab13898147ede468e0e01d2c4e0ed66b395a16cc3ded3e952ac739205f35a83376cbce 00d0dec052a00ccebd0c0c5d9a08272f75744a2582cec7ddd924a2b022b2 a3af7028f7f33a70d2f5bd42c470c0a82d16ec9f2dd42fcfbeb28b58b74472d83bad417f463a336157bb91fd4c083ec812fcecfbc611f36771bf339438ac0314c2c47352430bd07949ef2ce29a87cbb650cea8f7503080842fe5bf1219aeb2fa +0204b1fca831919e89e108cf140b3770f531a696b1d9a4d1fb68809eb10afccc257cc90cd36717c02b2f3d6d3d1d8a93cc5c48aa7ab9f9fddfe121ce9143376535a0c65e247c6558eac49fd1d6d1bf431ba918c471cb3d536ad485ec51f6471a340ac75f160c4c54cd3ffb9dcc123124b42df1fd2eaa005e3377c5d2d55938c6 008a017d717d6d1213f2b74c53281b07258738c0c7db649ea1ac46b9a3b6 a6f492bd6ca8d34b4385e8da75b52c97ccd1a72e118c5f14ee55ad0290407b8ce913217398dc4b996a2a5e002d88a25f010f84b1e89796c00e5f754abcef61b73649811b1790dc4fdedb9682646f1d3e194136676c6be7fa43ccdbf645d8285c +2033eb48756638cb56e2cc39a3e775cfa11fce86cf71f04487dcdbc7f262bc8350a30ced54d1fcb697b28a6e96f88f782947c997872307ed963e1d68985f756435af77f57755cacbb4c6b50ed419deec9f39f0a549a13e54254fa0a5832dba2d943ad4aed8688889a2dd29dcb4ea12abd6a6c50eabcb3981c3a0c1ca5f0b9629 001b56c14442b084cfd22aeef0f8028ec57c8b571c9fc1e43de05c45e47f 8948e67187df5333f5e8339a3144358948d50e25c3a8857367f44219d54613ec2cc1c725b7da16cfe2e2a13c78466547109408f34a8169f9d8bd5a4f77a877dde7300e2836adc78b536908c10021ebcb7276bebfeeef60cbe94f67db1817278a +2986ab1cfe8873009e932dc68d4727d77ccbbf378e43fe4aa7c54416346b036b89c0aad1b82977c9fbc39a00f1dc916c0561d8dd70298c02b6cbfe572e0ef2058641e841c6875e8515f3c1082765e046c90c956d984b76e0e8e6eb433ce26c1757ac5b13422479141971c20102e9621d18f51096ae3173c2753facee2862d66e 005afce37c5594586ac46a34ae291f591eacb9880a7de92701977f447fbf 879be792090dfb66af0eed437d99d7ffc89490f0c5068e07229db25ed1940e33cad8abb0052cee1fe2cf8454200e4a3a0b171b559f13dafe32f00eb6853c9d9ec0b1644f9c4fc6150d102d3cde611c72915306d8e1edb536812cb566c9d96903 +aabf5aa90ceef91c2155f90660adbcb0eedb996f5242cee15468ae217058ebeaad8cd4ff8cdc754a8ab85ba43c59fbab6386686fad5e27ad3848fe52191c7e4b203720841501792a625aef2acb6e36493b792fa55f253effca682946ad8c77e01f44e92ec3c258d0dd98d3183f4dc4a0bd3eca183794abd6232a6f9e4add8f57 000696df05dc7a54a9908a73eb18416a155cc8df4ab26032539d86eae537 b73a295f26ce7a559c298c20442f3173d859e733b62aa001a28ed7a1520738c13d23cb9db23a005062e2609dd980dea909001afe801ed91d46885a318aee32954daa9c9653474c66dc7bdae9527362dd1836bf960dad447e8e92a6a9df74c301 +29ff209eabbde02b10b3fd559671fa53e418750c32c4a18d31cc0186d1077581bbefb8770ed079f536e866414a07431ae6633955bf42a2389b6f8a565d6e4ffb4444336e0030093876a26d4e3106e9ac697788e41f8a21c755eeb86a7c60f18e5e1069f16408a4c375a6a68d42959f2fab7ac09736c7b37c80c05897d8566ce8 005ca31e88c5b2e96e433af2023a66095161710628e7bfa428944d6676b8 8de0a5fb01fc19892f84a025fcf743de384db628308bc823c4f4b9cb1a42ab6fbbc14142f762209994c724952796c5c20c4dbac7be849a0d63674e3f450dd471c479fe0b9c1ee6b739816c762328f932fb7235cd238692a8c1adf3f3580aeb83 +97765d876c80819f4004a36d09ccba78e600efc71eb7e869d3a00f658d2ace6769c7ab1ef590f41fb070aa8e08615e138df45ffbb6473d4a86ba5fdf17dd6dc9ea9ee19c0332563c99e6a3451c211d286d69102b47bfa6e07d468d9bde82e5c2063fb1ebbbed6086f542cf68ba46d4f214634afb1146dd5a6f3d50912ef5b824 00ef8fe84727a2ad8bf4e646ef28a492adfaf785a3a2ba6e6f985c649a8c b6bfedd7a1e3daca7e378bb6dcc5376b5b50b1e9a96e78049b8541093ecdb67cf99e585ca94b5df521101901dd0de0820f0ef580a095720684bf3c4297648ab891003ac3f9f226833e90ae9073da49cc1eadd6a02845f1fbb5047da0d71ca057 +21cf768d087d1e4eaa8a05e2008020e243116206d675c09be42ef2bc93617ecbb0575c873c6510ede9979215531b62126552738862fc4323d487992754e39d8f0d7e111e165ff254200e05082f59a57ef649bccaef6f980094fad3b7ef93bceb161760e200f0a2e396fbb6b6142dc84d872311bf932b84616b22231747937d58 003edb94b8c62f9af30c14a790c0f5d65e362a21cd8569b9725916d534c0 9798abb2c4737d0213f9631cb8347ee65cd7da7d07b0d1002fd3182b73335d65c9b90a88e73b0253579c4ef71729ad0a18cef3323122321026f4cb65a66b616c65bbcd9c0e4dad721f8ced7d71c7ad504e520defc2ae18b577e355f048017be0 +7b8e58eecdab3e40212bba6bf284f9379265b3d2baec3e4625aa08d0ced851da193c292ec793dab42732c07b4e94d8b19c83aed796a7e3a6c2b954a7a9a1ff9b2bd4ca62592c8b68f709f1ad38a5c8033ebb3f33d176945bfc68e9ef2b0cee2d45a13ce89d238a33c09ce2c0c63c4233aba5717b85c4c161dd7648a41a5e39d8 000a7519be62562318da1b67d22cf8e720353d22641e0cee11c7a352bb93 aaece2d779599057ba4cffe1374fc9f64e4abcb177b3f1152a8362b95f9785a13f047773792f150c420a430c6a53f0741831a393a1421577c7f16fa99ade9b439b96cae52162819ff4cbd68de080d95f1255de85e8ad428e673baa3165e8c41f +f8f268d2b04fe47e5052c8d0d653787384b9654f0bd2138a6f52b80713feeed452b976a90eea4edcfbb62d04f3eafe172ddebd7cdc3701ecd6008e3d82e8eb217b13b5228839f61075159f3bd1e1409c08903874b6dfee2789dd72c208ae769ec8c7d52552a2b1fd73dad24de8b571f88e2184d0ee7d063a121187f97e746f2f 00264022fd7dc2328a6436b522793ad9406d7a586667a0daaf1bce927338 b37507849866e0484657c52daf01e0f3d7570b148f4ee0ca9193e2e26ad255f5b7b1722f76c2b6d004f39b935bda7f690b8a63bdfa65b2dec052c2aa2182a3527fd3200b9962e6fc00ae5709b4d3c7e6aae35f31d2141d771e0a430b897a4ef4 +d288768cbd066fad4bb2500b5683fa9e4eaedfb3dbb519b083f6b802efda0a022355565c5fc6babeccb22f3adbbda450ce5d633193d1431e40c0fe631a295cf85965cd3f5937b31866bd6a5300eaef9941daf54d49832acfceed90e572ef34ccc94eacd0fd6b903fee3c572b963d21e2881656a214d2a4c125778dbe3bbeebca 00da43214e2efb7892cc1ccde6723946d2a8248a6b4d6c8872fad525ec3b a714015b6e1b5b08d92470dfe285ef92eb7f22b905c789244f0b9d11dec7d483b148bd9e09cfdd04e429ffe742a0967306e603047d7dedcb18bd9dcd5b27cd073ac806cf08c4fc98031b170be7b19ff8f1e63b994c7584a6184fdbcf74d5da36 +bf0ab46e0a756c11229b0ea961f8d57218be5b00ab8b0e91d7664cdf5e0341c412c0e992d26ab12115197db39df2d1a6e18ed26a91be461432a2dfc21d98cb16003e339b0b0b1f100e4e6f4824ddac5442f22a1fac26326ed8a89cc91343d7223986d485cc8c64424e84d56be536c57e4dc5faee459b1958efd79e07e90a9811 00aeafa49d776b61f6a30d66ff64bd40dd8d79891dd5293c1b5cd3b46a7c b1a77a6817b719010fb89cf43138f2b3c09f649cf690564f1cd46930ab4395479d2a45fc72fd9b40443d8f036d2ebdc70b3377cdf759934e9d93a2b4d060225a534fb92763aa70aa7b6c9b55c04f2554e1d0ee61ef3df488036e7a8613a53953 +c7b1eeb7c19eb16e7f42b61d79e421b71de797a6cab4e0baee522fee7acdb533f7bbf5855316544e1b82b4f2a18ad0a2311e7622549332122171f32fc62a90e408207e0fb90d1b052821dede9c41b15b6e07d84d5d7b9e31e6396a8ed229fb6232b3051298dc5321aa589f4e289d27169f14c8cc93644916d9b72dbc92c43488 00e95db309f4305b621f51f93588a2678cb19aad0932f365fa0aaa3a3895 a79c35355a95f6b2ae88ad5d2e6a036efde73de2b6cfa6f8e7fa10f377378877d7e2076144d79da2d329bd9b4979940b0b7a16530ea13e7ee5a30f481a5cf7b961253128fcda373e7ab3e7c9854728a152bc0984d8df16b4dc38dbdbde712db3 +a738eb074e1f277dc665118ca055e6328059ab26da188c16f56384c566e43df8cff3d2a10d2d15c3c1406de8f734b20be5dd1ce937a4289f0ddfd7bddabd03586556eb8233b8feefedaa1f49bdec6d45fd562c2a83fa9fcfc2013bdd77900857199e51fa9c7cbeab925ba8f6c3c5fae46bf8e9c574b302f1e5f9c44400152a78 00d4319cc8e409b8755880827f3200d3f0f1c64d6356fe74eb1f5aa42499 89996310f85a59d2dcece6467baffbc7f0677713dea07beb76c4107a6ef92ccc0f2381cbb2bfec57cf7a4804b15e5b311312cbeefae6c3d27350143354f15151ef4610fd6563a363f72dc78f42e51efbd89c71581f2ad62cdf7df77c7df937ce +b28103d77e5457c42e026e713ea6ff03722a36512da17197140117442a976f9e2139c54a759fc26af5811b455e5a0d3a95362d9939c1e738045be9237b469ae2106ceed7e7842b44cc0a475d5af6d781e32ff1dd1f4e1833dbc7f82b27dc7e1562d0e29213fd8911105104a7a16f665b926aa137f70d868c90e72f8ee2c95b64 009e556c945052e5954915c773b2d47970c521fcc99139269c3ef46093b7 90825424107e2bd6c260fb5075358ff0aa47f7f159540e9bddbb29cfcb9730bffde592718a56623906eadb082b9ebf3c0affc3dd2ccdb0d38130e9db3edea968cfad218470b8c1618e186f2c4bc070c44a2a01513ec739153423e8dcb36989d7 +463d04c84521ae671bb35c0a7acb3ae509b1b0470f39b8fe7ae5f3c9fbadbeb2bcc3a87e284cbdff07407a351f7ba743aeac50c4a1fef7375b90eb4af8ea2df040776bbf3e4389e7a80bea40530842642b9895ab9ef5ac8ed6c9ce7917d7b3ebcf80b801da845943313988c1970e7748cc306f914c37414f8247d648b580000f 00becc76f8a77615c4f92ae1f91645bf5bb908e75ef22fd544aae63a3c8e a993f88118354cc925ee5ac8019f624a6f2cc01e1da766b18180b404d451c5b2bc2401aad4e2ac9ea06381fa8d7509381365d9dd49d6fb7c7e148ab5791f9cdfa45b0f9491b6e1e21cb54d1b4a38d5f622f19dd5c991af3f712f9e662ca3ba62 +8b2379b5553ae7db6023cb010e26ae91322bc3f94dbaa369481936f90a886e5d3827d995ccf03ca59f46805fbac0337d31a8f117cc7044218a934d5bf507090e7e21178a7162c8fcb39111e6967803dbf9d752f3ae737ba024d0f4f7627e08be58efbe997a164106bfe37f67d2f19c0fcc7a6c7eebd96a72582a9c7bdf881896 0020572c2a3dc3ea430cd8cde9d642081c21658e8bda165550cd9a5d37d9 b027a47f0bd54ba60d1ca2d6d69658ed50b6c71d430913216f15b3134c2af48eca88c255f32b55c2824eac38701c395200aee740ac6567ee0fd617cb798bcc916edca14764c2feaa4b56a6486d0ff53fec8f83e3ed092311bff48d3c6f162e1f +3090bf7373731cc44c00372c1ac59280b0f36e627ccf763fa68a7be37bb0ac8cbd4f70db54fc652566c78ad268f78f015e4bb1e41516fa56ac303a3bb4a52e1fe897d8338db5a6e37cad685e704b994504bd231c7dec0002dbd907a7ebfa809833e32eb23fffdb44fe4a18e11fa19d67356cfd703cf39a75b1a290b8a7c73afb 00769cfbf2dd8248ea1e0ac9b275c9d6ddcf923fe762079b9ed62ccbaa89 a53c603bee062f5029f94fdf60aff80e3cae0c54233d23f4498aacbf0f33b212aad8468fb847ec6b8d80678b396e549910db900db43d14419a4f266d56188620569eb62675fb3d1537eccd88c801efa4931be868d9237c2f6424aafaa221aedc +c37389cbe3f46eeebdda343e354ccd543e96b0c2a87e057aa6b9c4895a403de706d658bbc9066c140e50fef4b56af2db1f42efb70b8021254649983f1e11d04d6b10169d5a1c2093b6ab89227b88a30537c776bb7575749c3ed87bcb29effd8e4f17915b4d5dff6cab9678d88f33abead1e73dbdc5c3307ff3d3b2d5fd7bfa83 0040ea4a37b388f0cc464f7e2bf92173107b268ff77a8acf5f517b4ec0e4 b2143a412949b6fbc6891ec4459e1d383b2c661abfb01acf2f8f543e780355bff368d23276eb99962cefd903548a2bb41458e7fd02212409b68d52e8846f6434ef278942693871ca80b9fd3a7d12ca9bda39a1f40ab11b93a9f9200b9f72be1a +8884def8c3b9c5f856b9c2352c85ea71aae3c8d0e84ca74e70e404a21467159fc9826548d16dd1ec5a75dc2c23ca37b30312f25e1194e0f9385a0499db34c855412bbf58979ffce7fc3afeb7b8dbf9898df44023200d809f520db99eae315b5cf85674fab008a20340fae8f6974034fd3e55bf08c5522a460680218f9757e368 0037fc7898df9b37b5390537352f5c0b8de22659166c19d7d4df31c3938d b8a05f431666e506062da3245c6f793da8deff764cf02102ee3a7ffca22ec54f72499f08103a6d1104e55faaca2a3fb01448a1f9d87f82943bf5d038dee9df753fb46f99c8249134b771eb650569252d59315fffcee14da584ff2e1b82c110a4 +f1fc154d469433f56c2bd42aa52237a4a4bfc08fb6d2f3f0da70a62f54e94e3f29c629c837e7adf0474fa8f23251b9b349a16848942c0d9cf5db1d0fd99527020dbe21cf0b94a9aa21f376bf74da72d36f87b306b0696771efa7250c6182b426a4500ac14de4a1804b38db8d4f3beefb8c9bb619ac82cb63fb37c2e1d22951f7 005d5069425e7a9925d2cfc6360a708147b2c1b55ede243591885147ef3b acb73d1d598d209f8088db5a634625414521638e801b3fdcb9a6edfd0fdfd36b2da7793f06a506d55155c0687a245d57049f973f917eef623e509d453b77d337ddac0aaf4c6d7f2b023f9a4c61604f35db5e40c75097406a47a83061f3ecdb22 +885cd348f7983a0721f96c0e866821223d3e5a95178b16d18652b4062b1b2278aed6f54ab06f7e37ae6ce1020aa3eb812d215194bcd212302da5b971fd86aee1dcb23057dbedb569bd0bbef80df538da69ae2358cb03bb77c64d3ead475c8c5ae5bfbdd75684b421a26f1a7b0c37548fa32d805acdc91230dd70a48232a12846 00ffe3e7b82ca62b96e057ee072a4718ca20a6cc9a3e51e4fe8ed7b4b9f9 a2943972da3019a6cad4fc11bbb268face44cc70fc261ffa035030f3a4c48e0ab97ccf52d4d8a2d2531cabda5c63a490152962c7f3a50d2f5a54a31ee15cbc7ea009912a979d5d3709527c64c925b382c7dc66f8c83e88c844edd822d0b6a55c +ca3b0e2f1c7db4e73c699f06e432bb0f63705ba66954bec4a259bf31c161bb4861476e2f2f7dde9d841d1ea6bd0990cc793cd7a10432e38735c3eeda7a0d786e8821239bdd6c4972c96c2cf68ec5b935391f963a50fe16af2719c9029943b539ff0f1f5645962a6ac46c75d2037fa0c7cd46deadcdfc66e1ddcaada3a376acbf 0007a9cb5ce27c763646de414ca2a4dcdb774d69ed2bde7a817baddbc9de a48b070268bc67e69427aa15beb0e749683912be5c7ce17610d61235bc266a6927fa4d5a489aa0c82cf38fe277b8122b085515b841c4a78ba0113162a7ff88b07bfb307acc920e80fc0ddb562fad01ae550959ef82a032f4b7db7a0fe5c7266e +4b0a31b746763beee77cecd318b90acf50fac4172cf4bfb354e5a440f651cb89d7a515e09ab19e9850803ab9167c2aee3b395a5da10dc9aff799d73756dfb0a9961d93bc32f15a96bf13962a03d5bd42ddc8b5928def7fc48fb063f42866fc5f96cf88fe0eb125b7c01906ad6a7fdade28ccb0a421ceff50ae03a974671b2c27 00c03fa9e38dc1c697f70bc6381f2bacaf860bb5632fc837f728da959ac9 a0b29f9d3dc95108df088e6e21060c0680748ea1747df23e99ac5afacb09e26e32e97978e2000b6c99f196660012e15114e02122058197ff639ca2cd8b0dc15080ad220cb5cc020084b0c5649971d05676f762ef04fbc7704a25e6505199acba +3011d42792b21c0f1719faf6f744d576f72c5fdfd22b1a520d0e8d47e8c2b06823d853b13c9fa039fa30a6f2e3e27bb2100c6a35f55703806bbf0f79b09d0f629f8042ec63fa04062f15f2edb92b19237980005566f02bb12a40b4ec66e4ba6c599d928b33f72d7437c0e399a8e6a9068d1fef24917fc4f9ab5464ea6684dde9 0087dba00e3fe4802e01718017510094924496bd2785d4ac1a352c530473 b8e7decc77c26e9fed1943dbace837a89e0d8233a05b57611c3f34095f163b8bf4e08720ff2eb61aeeb4683ffbcbcd2302c0640a7cfb605b29d63e21230b0439dc2ecc167d57f7e4c1e799381bb5cd5d9626b875ba22beec2e1ecaa6ef9dff1f +05a5d3a3b79f4e51b722e513620c88092a9bb02408f5f52a32e782fd4923f4fd3094fc5536caf4b645d830260eba91b5173f3833dd65600fb9e246aec968b1f6ebdfddb4059fb2de7e636ed60bb7affdb74aefd158e54485d5f26be373cf944c6570daf8fd7e4b77fad57300667d6decf5c65db99ab8763bb4ecbb09fdf47e3a 005a387e7affc54a8fbb9157b5ebd400c98e2d7bd5c3e095538987d4f8d9 82980ba887be67c4cce79e6512cf6b4944507ca081c2da9eaa11b3710de9c4528d1b42afa19843c00bbf03ae6df912e50f6c7a57f1617d95771b50f6aa75359ccd1c1aad2b2443f81516a115600bbafea54609e1158b784a134f93dc619c3919 +247a101c8196eb93a440280650ad463795690bc620e46e8118db6900a71eb493d03fbcf2f73a79bb47aa8e2d8c87ef70e4cfae36fae5c45fe247d8cd0f7d0718dad106526945014b4f3bec324897d8e1fa2f457b8a68e61873b7fa0350fde3b87b7b001c13953c2050a24f71fb77eb455053e49200ebcbba7299485c0f1a40db 00adae709a930d6f5a5c0e3d8ef4aab004d741d23f0ffb8287f7059890c0 9415eecbfb707c7c2ec51300e55783f7493753a60afc6dffc4b27c72f1d0acd70bad1f50e982749bcca8b508edca34920d7b7c9bd3b5c0b8b723df0d541956ea3ac0d4b2119d1dc644cac88464bcf45d72a46923e9c279b561b4616af0cf654d +a16678c71976a3ce3362ca379b3272b92e8ca7085b43752473db34e4d6b61eeed3875f49f3328366fc9d0644824e0104817de458e4c1036636b18b83dbaf063f2f99818959224906571c7b28873d9c702360888df151e9ad1a7003e6130033203acf8a69889be6ebd90816f2abf0764f10be68653b1e56766ecc3150bef8b042 0035d391411e6d679751092c4ea5a079c591e77ebdcb57c1d9006ae70d90 b96fb2adfd12effae9499a93bf5041c387a7a2b19e338389fdd4c31e363aaf3aa0d75f7b5f17fd70b62f182010436d4e093f33ea1c61535fff4eb77bfa70149e14e2ad3c5a9b79bf852b630af3742229f834117a8e1b8f9ad4f4847633add6ca +bc2f080a7f0b69a6b142b8f3fb481a43bd71d07418df4f3b802568073c1a8d35729ad197f34a4e941a6dd511c63f201d1f6c34a1b66545bd5f43508c10bda1d6ef60ee5bdd25dde975e50c61f76cd36d50ee3bd8dfa2dff59524db9ef12f1e28d109b552cb42f021963f559c843476b5c889fc567b7840297c5a480e18c221dc 0084e79093f1947d6ab9cf399782436e36ef87c59a4c090930c9a74ddb10 ab3ca9d5bee036950bea9a65d6665f57725a8616e60eb56ac86fbadc2e4289cd06316c2d2fa9043761a99d81ec19ab450a2f4f4f583577c7d3217bbe4a5d9a5bde2ef7af3f088526f02784b4cc3def2982ac9c9ad197f42fc03c6cc9a3276a59 +ea71cede8b63ddc5648eb244184bae265cd65d50f77a9e25ff93f02b132487c08732544cb88936d4fff7c0fedb39685822dd1c9be1158f647c605c9bb5f6a1ae34722fa08882c14b36b6c93cab33c9a269c7c10f755b6453ed045ea3e56f29e95a9404ba189a0b48848120392b4dcac43148b706c3d9e4c03db410cbe5dca3da 0079b6be015b8006f86fd81c2792bec6b42c08bee2d295cf9dc214c326ab b817cf5e2e44e35208baa4dba8637d48694a69f18ddb3b5f222abe14bbd6a927cc008d6c1692aa0a5c5f4c3e02b7a9970e51496ff04a6f260ef068280fe8ccc2a7678085a671daabcefd08cd8bef36a5af8c758366f6426d94ec0fd133de8789 +319b41d16e18059a1324c37161c937e882192cd949c420ce9c59208a0ac208ebb06f894a7fd78df2a3c5f23f25dee6595d3dacb25a699f115dd482ccd36fc54ba29dda279335424c86b07a1b1fa76a5411bcecaf4d37065b229cdce0bac75b666c6626ec37a716e9841be93c907f87453ad91d36846561f284421a89013b88c3 00ca9d751a060fde64336cdc88122819f4b3cd1b4e7df42d495197787894 98a18d8fdf2acd53ff780a782b57d400bc058f9f966c0b512848c5ed3a63b8d6a16b82b3d9b65735b0ab6c31b44af9e3070b53c9c759f89c003eb462eb258d82dd4f8d20961f85badb865108a8665f53ab69d8b2a8e0ccd15e6f639879b7097c +aebeee215e7b3d4c3b82db243a47506ffbf2263f6fe9de5b69286e8649d9218367c36ba95f55e48eebcbc99de3e652b0fecc4099714ee147d71b393de14a13e5044b1251e40c6791f533b310df9e70a746f4c68c604b41752eca9ce5ce67cdc574a742c694ada8f20b34d0eb467dce5566023f8533abfa9688d782646420c77b 001dde4b2d49338a10c8ebf475b3697e8480227b39bc04253a0055839e9e afed19d449f626b1399e55215b1241c854d12c26799dc73cec102019dc0d09bab6c501f05b27b6a8137fddd0525eb8d8174ad2743baeaa921b9d6c852a69b8404ec667c743ecdfb787ac1a1b033d9bf426dd79190173df4f607fb65748181b40 +8d353a6b6f35590baef59b638914d3e934d0145b045d221d846517ceddc8ff5e3d28826d3459f8ce1260f705e80923f39abc73d5949aa7aa8ad1734be0e992bff0c9a8f4cc9bdfa430d4cf52e29d3737b0cd3231b72b16e15e1a9040b832e4a920b4a1d94c4964ac6c8abb75bbbdb10825f882ae44c534c7154c446421a04d87 002c8bea2803fd746c874fa110a716538c179c82712f38d33d0f6d037e7a 89627f1acf11160581cc5d5f78a597dd8e4acb3ef08dcc11f999a377d8f2dece468e6e5cbdb3410d5eec376640c2f67a10f3ae7c8984a9dbba5c2b9c654af5f5a392d176bb0a152d1690f77f934a76f8dd241198eeca33a8a938bd47c81f22c4 +847f134b90f10ba3636ec24f36a94111f26d58428fda5bba4501e58c7bb55809f52320cbe9e0df55af1e40bbac9f3eaa26a55d78b60621d4356d090d98363662f406367601eaa9eb9568b1a1b319730bad7bf6a7ddf1b45eb6922faf8d065c540b671c50df758ebf8c4aca6f01878e5e0012dd038c58833e2b13ebdb9a9f3fc3 00b9119b3b4b30cbfb98ddf0a4f6953417e515fcf0e5a94e83ebc1d1d14d ad1ccb515407454e10db5013b2e2cb6d736466a3e4d2720a5f35fb1b98b00a6ab59e6db1307a1adb71a6f6711480f435119b30e41d1de6fc9a7fa68f1868bd18b4d8d4814baa45c1688c6dc166864b8ebac8381bdd56fd6e119a26a339059c87 +99d23950493bdd931915e9f9b65e4cd1329866c0071a19d4f7d6fd190689275b7b10fc07503dd1c27a4da274dbeb3aa5cb0e71e9b7b03fc2697729b7be913756e6760098951d7015df181cf14b1e0b954e6260276af553e3e59907794b863e941950718ef154669c5c262946ba120892e0239e05910c2194f712db46e37e53b7 00f4ab2a573f3771d1e4222e251faf14e06cefed544e804c299c9a8395f5 a5fe9348e2268570909e8db2286b04ccd33ea8b70a45ea5ff90fd2649b8805577aa9296b0bdd424397f418a0da5f271003dfb8f230103ea4d792dbf34de439d753a124a244175657a596e58bdb35084586a45370c0d6e15c8bc069612b1283b7 +7bef2487bc2bbbcbcc1570bbd4ed437c0dbcbbf63f666a3355aec49ea6ef593da25aefe9ae0d94db50692475425dee3c88cdea975794ac69142c25732f3541457d68d9101c8be069f2b515aadadea2019dc7abefa6c12cb3f76d9f4b5e46546f77eaf636aa8f2329130922111151a4df913d18b7cf9d0308f01ad84d878adde7 00f4649cf30d4a5269296a45977de2652cb06d3ca2aff4475bb24517b927 a32b14aaaf2e313c4fc130750bc105c6f16d0514a56218d408def4c887b56e8cbabedb44bd1848babbde17eea302c12e072155ce66f2402e38dc5253ab1d2562e2e5c90312cedc17d44be14371d1f4628040a1a66003ea60e82e0e0682383ffd +87c717eef6dd3c7434b2c91de05723783bef603d170f654b49a04b067b077c405d2d757ce780101b930196ca4261efcfbd3fc1ebb762cc0eecf101072988aca508c41581936526d3f337053000dcf77b16172492c5d654c6612bbd2523a6ad5966d7091697a29ce882fe331f79a7eb59e5a3fe536263083cc59b8133bfd33c1d 00cca24ad914c24c011f41f80d27ea41caf41fcc8dc9dc6dff5248b2b474 adce4504946e8b87921e4d0ad308932e4ad42dba76ce012d2f83526f3a92a1fde552348c7d1e8558e01aab98e943594b10d79e49f26348d4e4d3b7211cf2c11f1b7288ca0cd36b4c439868429b11a9139fe1667847b799cda6a9e5719e583484 +9bf48c2aebf473b3a4a928b3b6a4d2fb7e9193c9e60bc2067f9f03083a8cc7b892bdbf05601118bcc34dd283e7be996bf19b0bd36727eb9d65276b6517bf0c77ae0a9091e7a9e46182a2586eb22324939801034e5ba94ba30d1bde7d8fed51eb71036fab6224f8ff30a008422efcff7ea239ff23b9f462777e62b41b396c5dc5 00f5e12d536ef327e3b0ba65ac5fc3f7f4880f5968f3340eb8868c1d47da a09aa6b2bbd4a3153e0b030bd82f2f05d2c504d9b5756b9b66ad25a6d277cec64f4cca18e86b52b57bef44cfe065a93a15422a1ecf68c37a633c6df3cc3763f8e5b90595e6de21cc9ef16dd4487a77650ecd4882b8e96cf3b3b5b06423b17f4d +716d25519ae8f3717da269902be4a7566d6f62b68cd0faae94bce98c8a4ac6f66215ebac5407d6f64adf9d53f79f02e50921b6f0e8c805926a839443d30d9294eaa802faa7c5471d81fd1db148cdc621a8dd0c096e06fb0b71943337d5325e1bca77062684873fe904ed9012474ceae5b138e079f941a665a995026d13d7eed9 008c30d93536b8cb132277645021775d86c2ba8f199816c7539d560ac6de b9cf9d6c904cd63b97a9070ec8fbeb179e89994c5bf494ffecd4fcba9838d21fcd8e449d6a12f519a08d9b11832fc60011836be706e0b57b7c5a8565903b36fbedde52ebb58c1962dfd30f51aba236af77b3b5614059b86101ad7210d270739e +01e76755007b2ee5ac9e1d4c8adabad6d0f9c1c08ac6e2622b7c1ead89bd3ad0921b9525b49a780a262fe8fc0904a80391717ad7cac9607de55f7c744af8a132ec45ce79723f4a4a8c8b9ef658b360bd3890df164c9f1cd74eafb74feea251a34514ff2a57ae7a6d4bec2067cbf6ee4fdaabf13721bf9ae178b9034ac5e9665b 00fa3f15a506ccf7b50bbbad0a54d3223f5a95eb54f0d1f4e5d0cc21469b ab85af3765075e2fed789eb2b0756140ab06fa99fd816da68008ee55b7233cf49a762534a98168f723a6d0374237a6f40b99a34768b73a6fd0457d76273b7938a759be98a70c8e547e9e069294ed682e1670ee960630b1c30e4becd1a717bc1e +e95abeeb2c51a8cb75ab74253dbe130b5560cd52e2a63d501d26e1458aa568aca6694be91eee5fdfcf582c47c1c727084ee2b2c810281cf9b095808bf7e7c668eff00a6e48b06df3fe6a445e092c24d5687d7d89acc8063275caac186c441bc697b2f67aa71b03294e1adeb7e557c296dd91304ba0587cda3c984619f1eb4f2b 006400a4830889115aa88b860b3fb65905b01fd126c4aec2785518c2543a 86e9936a27f03a0870c2e133ff4a5ce795abfb522201bc5e007aba0d24e59d09a023dc4619a7fca9d696a20b6203f19301b4678a9c056fc7c6c4bee85d68675ae60a66c0f791f4761927a28f9136b4ddbd92539ba1c785a95967142cc75cd519 +bb8d8515365d240b2071daef0d80558fd3d0e059be9f6abb7b7a0a5f47e2ddca7d1b3b5101d5c583143258520ce8db0a87f877a395615c9bf879ef46f2f20f68bbc9706f82781fad69019396b27f292cdc70fff1772e90205a2225f80889f9daece1d03914d8776ac5bad24d8fb190ba10a2ca17768b918c2e079d83734eb372 00c7b73c324250f14fac0edc941f79bdbc6933ee8f64bf94b847bee5eef6 b1c6595137536c003bfe4e2f1f2a49cc2777062ddc2fe5bc714c9be94162213344ab7a423533625080db925530ccaa6615804a4d9bd090e44f7e517c01745eb83e801c31db082064f73d21af0be12af02956cbe210c0a0efa02607e203247824 +cd8b2403435fac9caeffa21b55eaba52d7efee0f89df7142340cdffeb89556303ca01a800429397e2ff6c746743b6bc60a87133274282d4cac02e4ca90ad95d80c93b84163b96296f67d40b2a1124b2b6534ab6b60fdee312fbcdf468d0e84eb85fce4ff360136bb31ced3998d29cfaa3ae685e638ee272058f123c4f35f8b6b 003db7f28e161abf52ab0adc8c4c8544fc989af081303b8688f22b7b2eb7 ade1ec35dd2cd7f74c1a211b62bf79c818ea0153169283727498e38c8551ff04ae4e18131970aa7a453266294ddede9814fc6d5ff99c4b6ce8ffe38d7e69801e9fec0e403cf3d40c7da92f88c1518ab0bc2a1eb8b29bae0df87af53f452f369e +4bb08eeb202564efb5bda40777d71f1bcc4c7c10b611e803e5c570876f3e319e9e2bc2d32031c56a32fc0d1fcf620d4e4377d881e9e1695bcdb78acba370b849115b86c1c4b83edfa03299da8e7fd14c7cadb81a8e4911c8e427e32c8c9b67e317575331967cf58085cff0c0d48ee0b8e7dc0b49687bb1c70c703a5dad08ec81 007e9d2fdd017d6da6029e88f78927d9ac9437f542db1f1fa99e32bfcf1a 94c1729304f7bf654520a5b29d1ddaedcb9d98b9117008898f841e7c19cf716ab9d010ab8bd83efdc59c03ea85d5b1b30ee3c449176e721657ce7f3ccaed2f41aa8a88c7f9729a527734a560a9b74ac1281daa4eb90ef236001a3a66d9253384 +0bce683d835fe64e6484328aa13e18b0956f6887b5e4442fce36ff09aed015889794e79da8aa60b4be565c78685674c51e1e7ac60db6a763c777198a56e382a03aff8b40862f961ae23e8b8683b76a5577769422418972ab0049119382edde9e752b42e8b93f403c1ef8665d7ce8530ce4ed9ebf6d397827cba6b7645e177231 00c94052760fc74c2b405ee4dd5dd2a7d38ebc16df9cc32df706075450b5 af9a5b9c4aa51f0943385e394733595799e3e59c01074ec31a14875970716e57a4fe4da61b7d4c5a456337750b5b142405424d5b204b4e1feb308bc2cfae7f764468bc845a5ae7fde2f3b8207a457cd3b4f258728e0340b5a7ce5679e15628bf +a6defc770426daad4dafba3bbd2a69881334f7c31269b297e440926db54cdad3fd7ad200f5ada2b72ad221ad99a06ecac9c2563a8deed89f0d0896991d1a652f6fa282affefbdb1c1985652300d1792725071631d75a182b683a48448063c7d2563ec3d430e0fd3acea33a35cd38ec0b5b07af96af71d0bfcd879d9864ededf3 004076b93487c2da8aeaeb4725fb53b7b41b465315335c18c6ca041175b4 b8a3c8df85bd3e0428dbe85ef91b65c82ec7538977479ceb0bebf198b3dd6f2b9ee53e2d36ca748574460b7c4425fba00c1ac7a568b38f50f5465269be587fdb69053363ab44e897bb557fa90f3ca001e686f9c03b071e9de4c2b39a154a77c0 +7803cdf4758c199962b62943f475c6c31356f5d9b997a12e21146a2399cd0dd3b97a860b2ce639e2801571599136d4a8cdbfb12fd1a5ce22374991e090533ff42823a2c58d2076b772814eea7fd7a1fde68263ef912681c72c7aa3e5a7cc44ee8c65e72228b7631e600121ea35bfbbc783b6ae3c0c8f80198ada218be533760b 0076ddd73ee4fc1f5e6766e229cc7236cdfce312417ea291f7c3328d5ab1 b282ddcc165bf0a3608ea1da73f12b8b67f9aca3c5500d8c1a16de96509b3157e219fbb34e69328ad7f283bc6338a4f8073f9643a7dbb0ee6141714ff1b39f86e4680539c0f8eba80ffa4d1e19c5a322edf0060e04ce951b1a7896cd7924ed6a +e789461e1dad0b6e21abeb6ae2e96385549d1bae39415188c8f833233da6a3328144c97ddb36e0ff4d9e19d84f869e79e609c51b32de59892fb0446dd28cc164a3e53534c950d26f87fb74e682db2038cde778bde06c3ee2eca2a077d8fcc2b0332e352e0e7e6487444a8ad60e78ff213b16fda9faf374dc6d27b7a3c4c6d196 007e1f8988ad804aae7d09a99be19384cc599e7652c02c391542be74b17b b507ebd22a10df5d5fdeb70260e6396adf6fcef35ee34a8cc1d24806e7d5620058ea6525500cfc5b857f1121e824bd9b03fee24b24e5361bea0f698e155261b3ca7bb1284e2f7d719106fdf732e62cabc19ac84a283fc8e2761bf34614ed938b +9b58c145d1b6c887f2b25fb672cd49c3a1117224be697c15182d4048be92968a6500f8bcf747fcf33145c13a8d72e891a6e0c4c7310c2b62f3181bf586fe32f1ecf4feee8c2c8bf6c2bfdf9d5f88981ce080095c93e49a772d8e7b59f9cffccec3ca2f212ef4c6748f64e224f4f098334d83108bf6f8c7b43c5eb549f1526897 009b2292b0244c2aabe8b43d95039984d504ebe05eaff318760e4dee739f 8ebe63ec3ae00155e77dc2cef77b48ff303e1c46cde6a50782fd028d4856075a3827fce7fcf9cc9f8e6dd49def6c2b4a135528fc61eae9eb898fba49506c58574a32fa60eae32df7589e7570b388cc80399f9b7baf5661eb965532ea1d73306a +52310a901fe9681a23dd6e02f12974d57f2c4f653322d9a0ff8b338cc6c2bd9f4765c90c6b3c9fb17df3f492e67d204e39d81a8fdeb92c852a1dcc6151ed6c63049037235c6751c9a902748163a567b714725b4d3995e0edbde03215c645b1a1da3147f7406245432800c50f823a1f991c863427ff4c68e4e16d1b106ee40dd9 007ca463b50fdd92d9163f1c2bdfce2ee45ba1437b79162e3e959b814cab 8216599acd0277e22658c2d4fa05daac911a9bcd1bb82b998b467b2c17841e4bff78e317bbf6ec22047a0999f5e289230f8ecd7f9b30900def9ffe1591fab16897f991fe847bddc72accfcf2c7d5d7a6b4ace69347ec462b244235ecfcbd5af8 +ff419c011601cfaf833067cf28dbe6e935ebeddf8b5111a97f6eebf3bb28376334f329cd877a134b074790a073db766efe018fce666a34650cbac285ae856fb6b3b8b96877282bc11cd9f9c8e510ed1f69bc2725a44a1d2b35de1edfd8bc9d20c7525ab0bbc27662a7cfc1bbd1e0f4fce5b88411521e3893e027cc8c73acdabd 00c3844750f63fe0c2e930bc38fe88522f4e72a2fd0db9778ade20e939b3 8a1f7334b9846a34fb5c6e0262ba990bd3405bbdd2a10b22f73effaea07a47a0720720236223cb7cedba4c37e272e9db045b3e500c49b38750bf5a732f90571a7e3976ad7f2724b801ca4b220441ad6ce8689377947aeddc20b20bf066dfab76 +05a89c4824c5de66587875011e704bc6e06e991ba8f3aed331cfffe55aa266a08c729f77b8d082dca4d286b2d451ea838d726cc2cf298fddf2d7376714c5e37b64506f353917caec525a1209391449c078c5197a371feade74f8fc8a1a1d67576edfda13c14ad324342fc0b09277941dc072ec0d39434ff1cb91fc59478fcde7 00a3bea235dea86506be4476eb7999dcb8e584a34238c4a894ad6823b93f 89dad141167d8c5258dd4e119ae231b8c22e528ee5fedd39da054e04706da3004409be1b5d091be8195107dcf16f9022144187330059c14c5d445176154b9a6dab5ad3ab55de062c0604cdb917683f4d19d394d982f74d487a04f398d1b57333 +13e6b5241365d9d0ef9e8b05cabb3248afd221ec02eab92284b98bda3d9272184bfe5251d35705defba5085381430e99b33a3ab77d7870e5102757d065862372df2434a25556b76e54ebc39d4e6c3aba5cd6acf0c335756f7d9385c1068d4cfa37526a9a58c0ccc7f87a8189176c5d4f201499236058ec061357dcdb5acdba40 009a367cd1cffd8dfcca179e167ea437ee48e9b6f42559dda9224701d3f6 adbd07bfeb15b7704131856fae3d6ac02af7266f85e7c747a409925417db72d808da6a9c69e540127a9f298bb6b4dedc0e01fee9567f5211ad760dc81d45bbf9d0f8b930b18ecdbad666557b891a239a2b8732d4060f372c895afc9083dfaaa8 +139a1a5090b97afb8fecfff8745efacf7dcf91a4393a7b629564e598d58d5be39c05c5830d4c8ca85d29e9e2c31ad0447864e867d0ef4788ac734f8d871daebceda98d449308c2afbe97724c3af8a468f1925065f39e52ba4b7d15728a744b1252a20476dcfff7bcb82aa72c209e72abb3c24419bc26191390ffed340c1b9c6f 0046f4ad2522e78b9b35297d28f361fb0ce82306322aedc119251d8241be 81af078acd7bed2c7fbd3790ed99e9f476f510e24859f9afa05dcc6a5c3f544e4ce1586914c381cd9114187f06d4f4b211ce320963ded4c21647480895af59a02e79a635e51607243bdf37a6f37edd202a514a68cfd5c62bf00e8db1f9fc418c +3315e5cda5f252e3291b61e493ab919c20a8af1286d9660cfa2f5ca38b6defe19ebecf820787fe692d04eae8a5f5d37abfb593309569cedf45efd0cecef6951b718924c8380ba52e8ab8c9bfb2261ed5f01cc5a5f9fc5fcdd269a0f122c597afdd9a836cf8f96838c3e8962c1788c3ce4128719b3ef4fc88569643dcad6da16f 00ac82137e9c7a5ecfb8b1a7df9ab50732934566a392a6c8915ee8ca8144 a9f7967689a4c4ff4ce871d91170017cd09d4a18cff997a92e04aee2c155fae73f0e74c789d0b15a4da9e2d09855017f0f7f9fce50f403b5b1349f3d9bb2f75532c1fd0bfef80c4cdb81cca86f26f41eb8b7ab2cb2350f76b9b49864491afd5a diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B233_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B233_blst new file mode 100644 index 000000000000..57a1683fad75 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B233_blst @@ -0,0 +1,60 @@ +f1b67fde01e60e4bb7904d906e9436a330c5cb5721fd4e0a3c75b83dade868736bb1d21cfb1b5c6407c373e386ee68ec2239b700e763728eb675a153b8ac44cf2a87be85fe8ed6683430cf4b7d718891cbf8d583d0a37cc952cc25fe803a7aa4fda80f05541a2f1f2601cdd0c095f7110f2a84f7d641b8531572269b21cbe77b 0056673197bfeea9bd7a8b820b4ae51a50411bf118a692bb9ed3d304da53 b8dee566effcf88ee86e0a318328be80763d7031ad303f491506a1cdc24106ffdf75db569ce958764079b78d45e2ee4305c58a3a5896bcc039e5d458ed5fba2892f81f241a37f9a454df926fd51de5620ecdb2d6449c346cd998d54f67098beb +1d496d96b533c632ed6a91f6e3653cdffaa5b8cc0008b35e49b2dd52fe261105c2ec7ee71a4ad5d51fdc3d36d688a3b7ccb3b3b0c3a65be17b8d8aa172e3005cfbf37a2d1b1a6e268c090c6f318e7e96f9ec9b9f5a8fbcc7558d89e840f7e76e44bed91c26ca48e6f5cbc253ca2fe8cb81c484cabd24070e488f9c00cd96ad4f 00468f01d483144e514ec257f2e5fdee28a927f2adb19714c1f3524dd0d3 95871893f161867f95e4a6f4fcd9590d1be4e969ff596a1515b003b4c777b9d9583260ab736870a42fa6988ab0d32807082f0bb338bc53351e63ebc13b9ebaf1bc25dc48b0a6bd62953653b28f88ce29747a729add41363fe97350b285b66056 +723400655027f474446843645757f7e2cd466bf97275067b4bc4c9d79bb3b19b2421835d69db916f24b77c381fa771fc1e7a19d2b4d09411ae55acccc615b16fd24705762b441ab67083a921fd4ae569ce0de69449aa96f5b977ac7dc022fdc8335656853796f54b3fbd118577f98920624eb0a00204f1ef83827245c06646cc 0074052d027f05465a8083a59cdbf32600224e1f563f653b34314651517f 972a8e92be7ce607fc1acafdf3cd238e42ed988fb166faf378b3d1585f2cbd0aa61d51aa0210a097da6f6ff66f88f4d308379e2e1848e223a9e873720440c53770d6fee0c3252f0c3a6b25a35f2fffa0631a76cf3d66bf8aad6e24015e64ac86 +155860cb31a142082bcc0bad828d747e916392d21f1873b3a3c1d28ca3ff9d45ddb66a712e3856b6afd07c8d2b2a7badab296a9775b03f6fec0befa2d8d6d00fe3938df244ab46e836a3e686c8b4f918da49f0bb3940bba34a9aa22c7caf02df7758b0de01d9f47af6146344b9be3842d9c055eaf0fb399cd8db95c544a62d8a 001856e7544223f55f80de72a6ef3822fa8fbd68eb397d06e2d76ddd35e0 975cdaac165d595bbf626c429f0e7bc9f077f0324d9d18ecaf1825c9d35c91889f48fab6a54fff79d46149ba4da4943910378b0013170fa544294800d15c47ec53415de73a020d1687c9b97639928b2e899e59bab5c7332188526251c8e17829 +cbd6e305cc9f0dc90caee6e65a74582e9357bd25c78e33a7b14e1ac7e9397ff4466f192fb432143e6df6d61a0ab808ec0a361a6d95a357a38cd3e241fe03ed883ccc364b248ee2a08702110745c2688bdcefa33c1a45b9c8b200e45cddf3e3f66b8d37eff07fbb3366ea1558ef304085613c56707095724b3e134c7a7d3f8dbf 00860aa2b589f2defc617be73e191502e5d9952bf60547fef19eeccbca26 b37010f02967dfbd0e762d395f9e4ffe06941bcf4b59a453ac0680be60bad3f1ecd040d01aaa28a8ac29f19cbb51cdcd1079dc545390506a9ee33276fd3706a51fc7b25e63a345896ed2c2fcd2eb1b85251d2373d0855abad40f77473950a0e1 +812a218ff1ee1472c189f63386e5b8ab341671c3a4dad27a8c6249d1c0f9a29338b471b6179f17a078b6504e804ac55ca3b13e68a623041bc1a092ea2adf3fa1124bbfeb161e6d7c483433f1548763b84da00352a6386e1339f674d45dab13898147ede468e0e01d2c4e0ed66b395a16cc3ded3e952ac739205f35a83376cbce 00d0dec052a00ccebd0c0c5d9a08272f75744a2582cec7ddd924a2b022b2 a3af7028f7f33a70d2f5bd42c470c0a82d16ec9f2dd42fcfbeb28b58b74472d83bad417f463a336157bb91fd4c083ec812fcecfbc611f36771bf339438ac0314c2c47352430bd07949ef2ce29a87cbb650cea8f7503080842fe5bf1219aeb2fa +0204b1fca831919e89e108cf140b3770f531a696b1d9a4d1fb68809eb10afccc257cc90cd36717c02b2f3d6d3d1d8a93cc5c48aa7ab9f9fddfe121ce9143376535a0c65e247c6558eac49fd1d6d1bf431ba918c471cb3d536ad485ec51f6471a340ac75f160c4c54cd3ffb9dcc123124b42df1fd2eaa005e3377c5d2d55938c6 008a017d717d6d1213f2b74c53281b07258738c0c7db649ea1ac46b9a3b6 a6f492bd6ca8d34b4385e8da75b52c97ccd1a72e118c5f14ee55ad0290407b8ce913217398dc4b996a2a5e002d88a25f010f84b1e89796c00e5f754abcef61b73649811b1790dc4fdedb9682646f1d3e194136676c6be7fa43ccdbf645d8285c +2033eb48756638cb56e2cc39a3e775cfa11fce86cf71f04487dcdbc7f262bc8350a30ced54d1fcb697b28a6e96f88f782947c997872307ed963e1d68985f756435af77f57755cacbb4c6b50ed419deec9f39f0a549a13e54254fa0a5832dba2d943ad4aed8688889a2dd29dcb4ea12abd6a6c50eabcb3981c3a0c1ca5f0b9629 001b56c14442b084cfd22aeef0f8028ec57c8b571c9fc1e43de05c45e47f 8948e67187df5333f5e8339a3144358948d50e25c3a8857367f44219d54613ec2cc1c725b7da16cfe2e2a13c78466547109408f34a8169f9d8bd5a4f77a877dde7300e2836adc78b536908c10021ebcb7276bebfeeef60cbe94f67db1817278a +2986ab1cfe8873009e932dc68d4727d77ccbbf378e43fe4aa7c54416346b036b89c0aad1b82977c9fbc39a00f1dc916c0561d8dd70298c02b6cbfe572e0ef2058641e841c6875e8515f3c1082765e046c90c956d984b76e0e8e6eb433ce26c1757ac5b13422479141971c20102e9621d18f51096ae3173c2753facee2862d66e 005afce37c5594586ac46a34ae291f591eacb9880a7de92701977f447fbf 879be792090dfb66af0eed437d99d7ffc89490f0c5068e07229db25ed1940e33cad8abb0052cee1fe2cf8454200e4a3a0b171b559f13dafe32f00eb6853c9d9ec0b1644f9c4fc6150d102d3cde611c72915306d8e1edb536812cb566c9d96903 +aabf5aa90ceef91c2155f90660adbcb0eedb996f5242cee15468ae217058ebeaad8cd4ff8cdc754a8ab85ba43c59fbab6386686fad5e27ad3848fe52191c7e4b203720841501792a625aef2acb6e36493b792fa55f253effca682946ad8c77e01f44e92ec3c258d0dd98d3183f4dc4a0bd3eca183794abd6232a6f9e4add8f57 000696df05dc7a54a9908a73eb18416a155cc8df4ab26032539d86eae537 b73a295f26ce7a559c298c20442f3173d859e733b62aa001a28ed7a1520738c13d23cb9db23a005062e2609dd980dea909001afe801ed91d46885a318aee32954daa9c9653474c66dc7bdae9527362dd1836bf960dad447e8e92a6a9df74c301 +29ff209eabbde02b10b3fd559671fa53e418750c32c4a18d31cc0186d1077581bbefb8770ed079f536e866414a07431ae6633955bf42a2389b6f8a565d6e4ffb4444336e0030093876a26d4e3106e9ac697788e41f8a21c755eeb86a7c60f18e5e1069f16408a4c375a6a68d42959f2fab7ac09736c7b37c80c05897d8566ce8 005ca31e88c5b2e96e433af2023a66095161710628e7bfa428944d6676b8 8de0a5fb01fc19892f84a025fcf743de384db628308bc823c4f4b9cb1a42ab6fbbc14142f762209994c724952796c5c20c4dbac7be849a0d63674e3f450dd471c479fe0b9c1ee6b739816c762328f932fb7235cd238692a8c1adf3f3580aeb83 +97765d876c80819f4004a36d09ccba78e600efc71eb7e869d3a00f658d2ace6769c7ab1ef590f41fb070aa8e08615e138df45ffbb6473d4a86ba5fdf17dd6dc9ea9ee19c0332563c99e6a3451c211d286d69102b47bfa6e07d468d9bde82e5c2063fb1ebbbed6086f542cf68ba46d4f214634afb1146dd5a6f3d50912ef5b824 00ef8fe84727a2ad8bf4e646ef28a492adfaf785a3a2ba6e6f985c649a8c b6bfedd7a1e3daca7e378bb6dcc5376b5b50b1e9a96e78049b8541093ecdb67cf99e585ca94b5df521101901dd0de0820f0ef580a095720684bf3c4297648ab891003ac3f9f226833e90ae9073da49cc1eadd6a02845f1fbb5047da0d71ca057 +21cf768d087d1e4eaa8a05e2008020e243116206d675c09be42ef2bc93617ecbb0575c873c6510ede9979215531b62126552738862fc4323d487992754e39d8f0d7e111e165ff254200e05082f59a57ef649bccaef6f980094fad3b7ef93bceb161760e200f0a2e396fbb6b6142dc84d872311bf932b84616b22231747937d58 003edb94b8c62f9af30c14a790c0f5d65e362a21cd8569b9725916d534c0 9798abb2c4737d0213f9631cb8347ee65cd7da7d07b0d1002fd3182b73335d65c9b90a88e73b0253579c4ef71729ad0a18cef3323122321026f4cb65a66b616c65bbcd9c0e4dad721f8ced7d71c7ad504e520defc2ae18b577e355f048017be0 +7b8e58eecdab3e40212bba6bf284f9379265b3d2baec3e4625aa08d0ced851da193c292ec793dab42732c07b4e94d8b19c83aed796a7e3a6c2b954a7a9a1ff9b2bd4ca62592c8b68f709f1ad38a5c8033ebb3f33d176945bfc68e9ef2b0cee2d45a13ce89d238a33c09ce2c0c63c4233aba5717b85c4c161dd7648a41a5e39d8 000a7519be62562318da1b67d22cf8e720353d22641e0cee11c7a352bb93 aaece2d779599057ba4cffe1374fc9f64e4abcb177b3f1152a8362b95f9785a13f047773792f150c420a430c6a53f0741831a393a1421577c7f16fa99ade9b439b96cae52162819ff4cbd68de080d95f1255de85e8ad428e673baa3165e8c41f +f8f268d2b04fe47e5052c8d0d653787384b9654f0bd2138a6f52b80713feeed452b976a90eea4edcfbb62d04f3eafe172ddebd7cdc3701ecd6008e3d82e8eb217b13b5228839f61075159f3bd1e1409c08903874b6dfee2789dd72c208ae769ec8c7d52552a2b1fd73dad24de8b571f88e2184d0ee7d063a121187f97e746f2f 00264022fd7dc2328a6436b522793ad9406d7a586667a0daaf1bce927338 b37507849866e0484657c52daf01e0f3d7570b148f4ee0ca9193e2e26ad255f5b7b1722f76c2b6d004f39b935bda7f690b8a63bdfa65b2dec052c2aa2182a3527fd3200b9962e6fc00ae5709b4d3c7e6aae35f31d2141d771e0a430b897a4ef4 +d288768cbd066fad4bb2500b5683fa9e4eaedfb3dbb519b083f6b802efda0a022355565c5fc6babeccb22f3adbbda450ce5d633193d1431e40c0fe631a295cf85965cd3f5937b31866bd6a5300eaef9941daf54d49832acfceed90e572ef34ccc94eacd0fd6b903fee3c572b963d21e2881656a214d2a4c125778dbe3bbeebca 00da43214e2efb7892cc1ccde6723946d2a8248a6b4d6c8872fad525ec3b a714015b6e1b5b08d92470dfe285ef92eb7f22b905c789244f0b9d11dec7d483b148bd9e09cfdd04e429ffe742a0967306e603047d7dedcb18bd9dcd5b27cd073ac806cf08c4fc98031b170be7b19ff8f1e63b994c7584a6184fdbcf74d5da36 +bf0ab46e0a756c11229b0ea961f8d57218be5b00ab8b0e91d7664cdf5e0341c412c0e992d26ab12115197db39df2d1a6e18ed26a91be461432a2dfc21d98cb16003e339b0b0b1f100e4e6f4824ddac5442f22a1fac26326ed8a89cc91343d7223986d485cc8c64424e84d56be536c57e4dc5faee459b1958efd79e07e90a9811 00aeafa49d776b61f6a30d66ff64bd40dd8d79891dd5293c1b5cd3b46a7c b1a77a6817b719010fb89cf43138f2b3c09f649cf690564f1cd46930ab4395479d2a45fc72fd9b40443d8f036d2ebdc70b3377cdf759934e9d93a2b4d060225a534fb92763aa70aa7b6c9b55c04f2554e1d0ee61ef3df488036e7a8613a53953 +c7b1eeb7c19eb16e7f42b61d79e421b71de797a6cab4e0baee522fee7acdb533f7bbf5855316544e1b82b4f2a18ad0a2311e7622549332122171f32fc62a90e408207e0fb90d1b052821dede9c41b15b6e07d84d5d7b9e31e6396a8ed229fb6232b3051298dc5321aa589f4e289d27169f14c8cc93644916d9b72dbc92c43488 00e95db309f4305b621f51f93588a2678cb19aad0932f365fa0aaa3a3895 a79c35355a95f6b2ae88ad5d2e6a036efde73de2b6cfa6f8e7fa10f377378877d7e2076144d79da2d329bd9b4979940b0b7a16530ea13e7ee5a30f481a5cf7b961253128fcda373e7ab3e7c9854728a152bc0984d8df16b4dc38dbdbde712db3 +a738eb074e1f277dc665118ca055e6328059ab26da188c16f56384c566e43df8cff3d2a10d2d15c3c1406de8f734b20be5dd1ce937a4289f0ddfd7bddabd03586556eb8233b8feefedaa1f49bdec6d45fd562c2a83fa9fcfc2013bdd77900857199e51fa9c7cbeab925ba8f6c3c5fae46bf8e9c574b302f1e5f9c44400152a78 00d4319cc8e409b8755880827f3200d3f0f1c64d6356fe74eb1f5aa42499 89996310f85a59d2dcece6467baffbc7f0677713dea07beb76c4107a6ef92ccc0f2381cbb2bfec57cf7a4804b15e5b311312cbeefae6c3d27350143354f15151ef4610fd6563a363f72dc78f42e51efbd89c71581f2ad62cdf7df77c7df937ce +b28103d77e5457c42e026e713ea6ff03722a36512da17197140117442a976f9e2139c54a759fc26af5811b455e5a0d3a95362d9939c1e738045be9237b469ae2106ceed7e7842b44cc0a475d5af6d781e32ff1dd1f4e1833dbc7f82b27dc7e1562d0e29213fd8911105104a7a16f665b926aa137f70d868c90e72f8ee2c95b64 009e556c945052e5954915c773b2d47970c521fcc99139269c3ef46093b7 90825424107e2bd6c260fb5075358ff0aa47f7f159540e9bddbb29cfcb9730bffde592718a56623906eadb082b9ebf3c0affc3dd2ccdb0d38130e9db3edea968cfad218470b8c1618e186f2c4bc070c44a2a01513ec739153423e8dcb36989d7 +463d04c84521ae671bb35c0a7acb3ae509b1b0470f39b8fe7ae5f3c9fbadbeb2bcc3a87e284cbdff07407a351f7ba743aeac50c4a1fef7375b90eb4af8ea2df040776bbf3e4389e7a80bea40530842642b9895ab9ef5ac8ed6c9ce7917d7b3ebcf80b801da845943313988c1970e7748cc306f914c37414f8247d648b580000f 00becc76f8a77615c4f92ae1f91645bf5bb908e75ef22fd544aae63a3c8e a993f88118354cc925ee5ac8019f624a6f2cc01e1da766b18180b404d451c5b2bc2401aad4e2ac9ea06381fa8d7509381365d9dd49d6fb7c7e148ab5791f9cdfa45b0f9491b6e1e21cb54d1b4a38d5f622f19dd5c991af3f712f9e662ca3ba62 +8b2379b5553ae7db6023cb010e26ae91322bc3f94dbaa369481936f90a886e5d3827d995ccf03ca59f46805fbac0337d31a8f117cc7044218a934d5bf507090e7e21178a7162c8fcb39111e6967803dbf9d752f3ae737ba024d0f4f7627e08be58efbe997a164106bfe37f67d2f19c0fcc7a6c7eebd96a72582a9c7bdf881896 0020572c2a3dc3ea430cd8cde9d642081c21658e8bda165550cd9a5d37d9 b027a47f0bd54ba60d1ca2d6d69658ed50b6c71d430913216f15b3134c2af48eca88c255f32b55c2824eac38701c395200aee740ac6567ee0fd617cb798bcc916edca14764c2feaa4b56a6486d0ff53fec8f83e3ed092311bff48d3c6f162e1f +3090bf7373731cc44c00372c1ac59280b0f36e627ccf763fa68a7be37bb0ac8cbd4f70db54fc652566c78ad268f78f015e4bb1e41516fa56ac303a3bb4a52e1fe897d8338db5a6e37cad685e704b994504bd231c7dec0002dbd907a7ebfa809833e32eb23fffdb44fe4a18e11fa19d67356cfd703cf39a75b1a290b8a7c73afb 00769cfbf2dd8248ea1e0ac9b275c9d6ddcf923fe762079b9ed62ccbaa89 a53c603bee062f5029f94fdf60aff80e3cae0c54233d23f4498aacbf0f33b212aad8468fb847ec6b8d80678b396e549910db900db43d14419a4f266d56188620569eb62675fb3d1537eccd88c801efa4931be868d9237c2f6424aafaa221aedc +c37389cbe3f46eeebdda343e354ccd543e96b0c2a87e057aa6b9c4895a403de706d658bbc9066c140e50fef4b56af2db1f42efb70b8021254649983f1e11d04d6b10169d5a1c2093b6ab89227b88a30537c776bb7575749c3ed87bcb29effd8e4f17915b4d5dff6cab9678d88f33abead1e73dbdc5c3307ff3d3b2d5fd7bfa83 0040ea4a37b388f0cc464f7e2bf92173107b268ff77a8acf5f517b4ec0e4 b2143a412949b6fbc6891ec4459e1d383b2c661abfb01acf2f8f543e780355bff368d23276eb99962cefd903548a2bb41458e7fd02212409b68d52e8846f6434ef278942693871ca80b9fd3a7d12ca9bda39a1f40ab11b93a9f9200b9f72be1a +8884def8c3b9c5f856b9c2352c85ea71aae3c8d0e84ca74e70e404a21467159fc9826548d16dd1ec5a75dc2c23ca37b30312f25e1194e0f9385a0499db34c855412bbf58979ffce7fc3afeb7b8dbf9898df44023200d809f520db99eae315b5cf85674fab008a20340fae8f6974034fd3e55bf08c5522a460680218f9757e368 0037fc7898df9b37b5390537352f5c0b8de22659166c19d7d4df31c3938d b8a05f431666e506062da3245c6f793da8deff764cf02102ee3a7ffca22ec54f72499f08103a6d1104e55faaca2a3fb01448a1f9d87f82943bf5d038dee9df753fb46f99c8249134b771eb650569252d59315fffcee14da584ff2e1b82c110a4 +f1fc154d469433f56c2bd42aa52237a4a4bfc08fb6d2f3f0da70a62f54e94e3f29c629c837e7adf0474fa8f23251b9b349a16848942c0d9cf5db1d0fd99527020dbe21cf0b94a9aa21f376bf74da72d36f87b306b0696771efa7250c6182b426a4500ac14de4a1804b38db8d4f3beefb8c9bb619ac82cb63fb37c2e1d22951f7 005d5069425e7a9925d2cfc6360a708147b2c1b55ede243591885147ef3b acb73d1d598d209f8088db5a634625414521638e801b3fdcb9a6edfd0fdfd36b2da7793f06a506d55155c0687a245d57049f973f917eef623e509d453b77d337ddac0aaf4c6d7f2b023f9a4c61604f35db5e40c75097406a47a83061f3ecdb22 +885cd348f7983a0721f96c0e866821223d3e5a95178b16d18652b4062b1b2278aed6f54ab06f7e37ae6ce1020aa3eb812d215194bcd212302da5b971fd86aee1dcb23057dbedb569bd0bbef80df538da69ae2358cb03bb77c64d3ead475c8c5ae5bfbdd75684b421a26f1a7b0c37548fa32d805acdc91230dd70a48232a12846 00ffe3e7b82ca62b96e057ee072a4718ca20a6cc9a3e51e4fe8ed7b4b9f9 a2943972da3019a6cad4fc11bbb268face44cc70fc261ffa035030f3a4c48e0ab97ccf52d4d8a2d2531cabda5c63a490152962c7f3a50d2f5a54a31ee15cbc7ea009912a979d5d3709527c64c925b382c7dc66f8c83e88c844edd822d0b6a55c +ca3b0e2f1c7db4e73c699f06e432bb0f63705ba66954bec4a259bf31c161bb4861476e2f2f7dde9d841d1ea6bd0990cc793cd7a10432e38735c3eeda7a0d786e8821239bdd6c4972c96c2cf68ec5b935391f963a50fe16af2719c9029943b539ff0f1f5645962a6ac46c75d2037fa0c7cd46deadcdfc66e1ddcaada3a376acbf 0007a9cb5ce27c763646de414ca2a4dcdb774d69ed2bde7a817baddbc9de a48b070268bc67e69427aa15beb0e749683912be5c7ce17610d61235bc266a6927fa4d5a489aa0c82cf38fe277b8122b085515b841c4a78ba0113162a7ff88b07bfb307acc920e80fc0ddb562fad01ae550959ef82a032f4b7db7a0fe5c7266e +4b0a31b746763beee77cecd318b90acf50fac4172cf4bfb354e5a440f651cb89d7a515e09ab19e9850803ab9167c2aee3b395a5da10dc9aff799d73756dfb0a9961d93bc32f15a96bf13962a03d5bd42ddc8b5928def7fc48fb063f42866fc5f96cf88fe0eb125b7c01906ad6a7fdade28ccb0a421ceff50ae03a974671b2c27 00c03fa9e38dc1c697f70bc6381f2bacaf860bb5632fc837f728da959ac9 a0b29f9d3dc95108df088e6e21060c0680748ea1747df23e99ac5afacb09e26e32e97978e2000b6c99f196660012e15114e02122058197ff639ca2cd8b0dc15080ad220cb5cc020084b0c5649971d05676f762ef04fbc7704a25e6505199acba +3011d42792b21c0f1719faf6f744d576f72c5fdfd22b1a520d0e8d47e8c2b06823d853b13c9fa039fa30a6f2e3e27bb2100c6a35f55703806bbf0f79b09d0f629f8042ec63fa04062f15f2edb92b19237980005566f02bb12a40b4ec66e4ba6c599d928b33f72d7437c0e399a8e6a9068d1fef24917fc4f9ab5464ea6684dde9 0087dba00e3fe4802e01718017510094924496bd2785d4ac1a352c530473 b8e7decc77c26e9fed1943dbace837a89e0d8233a05b57611c3f34095f163b8bf4e08720ff2eb61aeeb4683ffbcbcd2302c0640a7cfb605b29d63e21230b0439dc2ecc167d57f7e4c1e799381bb5cd5d9626b875ba22beec2e1ecaa6ef9dff1f +05a5d3a3b79f4e51b722e513620c88092a9bb02408f5f52a32e782fd4923f4fd3094fc5536caf4b645d830260eba91b5173f3833dd65600fb9e246aec968b1f6ebdfddb4059fb2de7e636ed60bb7affdb74aefd158e54485d5f26be373cf944c6570daf8fd7e4b77fad57300667d6decf5c65db99ab8763bb4ecbb09fdf47e3a 005a387e7affc54a8fbb9157b5ebd400c98e2d7bd5c3e095538987d4f8d9 82980ba887be67c4cce79e6512cf6b4944507ca081c2da9eaa11b3710de9c4528d1b42afa19843c00bbf03ae6df912e50f6c7a57f1617d95771b50f6aa75359ccd1c1aad2b2443f81516a115600bbafea54609e1158b784a134f93dc619c3919 +247a101c8196eb93a440280650ad463795690bc620e46e8118db6900a71eb493d03fbcf2f73a79bb47aa8e2d8c87ef70e4cfae36fae5c45fe247d8cd0f7d0718dad106526945014b4f3bec324897d8e1fa2f457b8a68e61873b7fa0350fde3b87b7b001c13953c2050a24f71fb77eb455053e49200ebcbba7299485c0f1a40db 00adae709a930d6f5a5c0e3d8ef4aab004d741d23f0ffb8287f7059890c0 9415eecbfb707c7c2ec51300e55783f7493753a60afc6dffc4b27c72f1d0acd70bad1f50e982749bcca8b508edca34920d7b7c9bd3b5c0b8b723df0d541956ea3ac0d4b2119d1dc644cac88464bcf45d72a46923e9c279b561b4616af0cf654d +a16678c71976a3ce3362ca379b3272b92e8ca7085b43752473db34e4d6b61eeed3875f49f3328366fc9d0644824e0104817de458e4c1036636b18b83dbaf063f2f99818959224906571c7b28873d9c702360888df151e9ad1a7003e6130033203acf8a69889be6ebd90816f2abf0764f10be68653b1e56766ecc3150bef8b042 0035d391411e6d679751092c4ea5a079c591e77ebdcb57c1d9006ae70d90 b96fb2adfd12effae9499a93bf5041c387a7a2b19e338389fdd4c31e363aaf3aa0d75f7b5f17fd70b62f182010436d4e093f33ea1c61535fff4eb77bfa70149e14e2ad3c5a9b79bf852b630af3742229f834117a8e1b8f9ad4f4847633add6ca +bc2f080a7f0b69a6b142b8f3fb481a43bd71d07418df4f3b802568073c1a8d35729ad197f34a4e941a6dd511c63f201d1f6c34a1b66545bd5f43508c10bda1d6ef60ee5bdd25dde975e50c61f76cd36d50ee3bd8dfa2dff59524db9ef12f1e28d109b552cb42f021963f559c843476b5c889fc567b7840297c5a480e18c221dc 0084e79093f1947d6ab9cf399782436e36ef87c59a4c090930c9a74ddb10 ab3ca9d5bee036950bea9a65d6665f57725a8616e60eb56ac86fbadc2e4289cd06316c2d2fa9043761a99d81ec19ab450a2f4f4f583577c7d3217bbe4a5d9a5bde2ef7af3f088526f02784b4cc3def2982ac9c9ad197f42fc03c6cc9a3276a59 +ea71cede8b63ddc5648eb244184bae265cd65d50f77a9e25ff93f02b132487c08732544cb88936d4fff7c0fedb39685822dd1c9be1158f647c605c9bb5f6a1ae34722fa08882c14b36b6c93cab33c9a269c7c10f755b6453ed045ea3e56f29e95a9404ba189a0b48848120392b4dcac43148b706c3d9e4c03db410cbe5dca3da 0079b6be015b8006f86fd81c2792bec6b42c08bee2d295cf9dc214c326ab b817cf5e2e44e35208baa4dba8637d48694a69f18ddb3b5f222abe14bbd6a927cc008d6c1692aa0a5c5f4c3e02b7a9970e51496ff04a6f260ef068280fe8ccc2a7678085a671daabcefd08cd8bef36a5af8c758366f6426d94ec0fd133de8789 +319b41d16e18059a1324c37161c937e882192cd949c420ce9c59208a0ac208ebb06f894a7fd78df2a3c5f23f25dee6595d3dacb25a699f115dd482ccd36fc54ba29dda279335424c86b07a1b1fa76a5411bcecaf4d37065b229cdce0bac75b666c6626ec37a716e9841be93c907f87453ad91d36846561f284421a89013b88c3 00ca9d751a060fde64336cdc88122819f4b3cd1b4e7df42d495197787894 98a18d8fdf2acd53ff780a782b57d400bc058f9f966c0b512848c5ed3a63b8d6a16b82b3d9b65735b0ab6c31b44af9e3070b53c9c759f89c003eb462eb258d82dd4f8d20961f85badb865108a8665f53ab69d8b2a8e0ccd15e6f639879b7097c +aebeee215e7b3d4c3b82db243a47506ffbf2263f6fe9de5b69286e8649d9218367c36ba95f55e48eebcbc99de3e652b0fecc4099714ee147d71b393de14a13e5044b1251e40c6791f533b310df9e70a746f4c68c604b41752eca9ce5ce67cdc574a742c694ada8f20b34d0eb467dce5566023f8533abfa9688d782646420c77b 001dde4b2d49338a10c8ebf475b3697e8480227b39bc04253a0055839e9e afed19d449f626b1399e55215b1241c854d12c26799dc73cec102019dc0d09bab6c501f05b27b6a8137fddd0525eb8d8174ad2743baeaa921b9d6c852a69b8404ec667c743ecdfb787ac1a1b033d9bf426dd79190173df4f607fb65748181b40 +8d353a6b6f35590baef59b638914d3e934d0145b045d221d846517ceddc8ff5e3d28826d3459f8ce1260f705e80923f39abc73d5949aa7aa8ad1734be0e992bff0c9a8f4cc9bdfa430d4cf52e29d3737b0cd3231b72b16e15e1a9040b832e4a920b4a1d94c4964ac6c8abb75bbbdb10825f882ae44c534c7154c446421a04d87 002c8bea2803fd746c874fa110a716538c179c82712f38d33d0f6d037e7a 89627f1acf11160581cc5d5f78a597dd8e4acb3ef08dcc11f999a377d8f2dece468e6e5cbdb3410d5eec376640c2f67a10f3ae7c8984a9dbba5c2b9c654af5f5a392d176bb0a152d1690f77f934a76f8dd241198eeca33a8a938bd47c81f22c4 +847f134b90f10ba3636ec24f36a94111f26d58428fda5bba4501e58c7bb55809f52320cbe9e0df55af1e40bbac9f3eaa26a55d78b60621d4356d090d98363662f406367601eaa9eb9568b1a1b319730bad7bf6a7ddf1b45eb6922faf8d065c540b671c50df758ebf8c4aca6f01878e5e0012dd038c58833e2b13ebdb9a9f3fc3 00b9119b3b4b30cbfb98ddf0a4f6953417e515fcf0e5a94e83ebc1d1d14d ad1ccb515407454e10db5013b2e2cb6d736466a3e4d2720a5f35fb1b98b00a6ab59e6db1307a1adb71a6f6711480f435119b30e41d1de6fc9a7fa68f1868bd18b4d8d4814baa45c1688c6dc166864b8ebac8381bdd56fd6e119a26a339059c87 +99d23950493bdd931915e9f9b65e4cd1329866c0071a19d4f7d6fd190689275b7b10fc07503dd1c27a4da274dbeb3aa5cb0e71e9b7b03fc2697729b7be913756e6760098951d7015df181cf14b1e0b954e6260276af553e3e59907794b863e941950718ef154669c5c262946ba120892e0239e05910c2194f712db46e37e53b7 00f4ab2a573f3771d1e4222e251faf14e06cefed544e804c299c9a8395f5 a5fe9348e2268570909e8db2286b04ccd33ea8b70a45ea5ff90fd2649b8805577aa9296b0bdd424397f418a0da5f271003dfb8f230103ea4d792dbf34de439d753a124a244175657a596e58bdb35084586a45370c0d6e15c8bc069612b1283b7 +7bef2487bc2bbbcbcc1570bbd4ed437c0dbcbbf63f666a3355aec49ea6ef593da25aefe9ae0d94db50692475425dee3c88cdea975794ac69142c25732f3541457d68d9101c8be069f2b515aadadea2019dc7abefa6c12cb3f76d9f4b5e46546f77eaf636aa8f2329130922111151a4df913d18b7cf9d0308f01ad84d878adde7 00f4649cf30d4a5269296a45977de2652cb06d3ca2aff4475bb24517b927 a32b14aaaf2e313c4fc130750bc105c6f16d0514a56218d408def4c887b56e8cbabedb44bd1848babbde17eea302c12e072155ce66f2402e38dc5253ab1d2562e2e5c90312cedc17d44be14371d1f4628040a1a66003ea60e82e0e0682383ffd +87c717eef6dd3c7434b2c91de05723783bef603d170f654b49a04b067b077c405d2d757ce780101b930196ca4261efcfbd3fc1ebb762cc0eecf101072988aca508c41581936526d3f337053000dcf77b16172492c5d654c6612bbd2523a6ad5966d7091697a29ce882fe331f79a7eb59e5a3fe536263083cc59b8133bfd33c1d 00cca24ad914c24c011f41f80d27ea41caf41fcc8dc9dc6dff5248b2b474 adce4504946e8b87921e4d0ad308932e4ad42dba76ce012d2f83526f3a92a1fde552348c7d1e8558e01aab98e943594b10d79e49f26348d4e4d3b7211cf2c11f1b7288ca0cd36b4c439868429b11a9139fe1667847b799cda6a9e5719e583484 +9bf48c2aebf473b3a4a928b3b6a4d2fb7e9193c9e60bc2067f9f03083a8cc7b892bdbf05601118bcc34dd283e7be996bf19b0bd36727eb9d65276b6517bf0c77ae0a9091e7a9e46182a2586eb22324939801034e5ba94ba30d1bde7d8fed51eb71036fab6224f8ff30a008422efcff7ea239ff23b9f462777e62b41b396c5dc5 00f5e12d536ef327e3b0ba65ac5fc3f7f4880f5968f3340eb8868c1d47da a09aa6b2bbd4a3153e0b030bd82f2f05d2c504d9b5756b9b66ad25a6d277cec64f4cca18e86b52b57bef44cfe065a93a15422a1ecf68c37a633c6df3cc3763f8e5b90595e6de21cc9ef16dd4487a77650ecd4882b8e96cf3b3b5b06423b17f4d +716d25519ae8f3717da269902be4a7566d6f62b68cd0faae94bce98c8a4ac6f66215ebac5407d6f64adf9d53f79f02e50921b6f0e8c805926a839443d30d9294eaa802faa7c5471d81fd1db148cdc621a8dd0c096e06fb0b71943337d5325e1bca77062684873fe904ed9012474ceae5b138e079f941a665a995026d13d7eed9 008c30d93536b8cb132277645021775d86c2ba8f199816c7539d560ac6de b9cf9d6c904cd63b97a9070ec8fbeb179e89994c5bf494ffecd4fcba9838d21fcd8e449d6a12f519a08d9b11832fc60011836be706e0b57b7c5a8565903b36fbedde52ebb58c1962dfd30f51aba236af77b3b5614059b86101ad7210d270739e +01e76755007b2ee5ac9e1d4c8adabad6d0f9c1c08ac6e2622b7c1ead89bd3ad0921b9525b49a780a262fe8fc0904a80391717ad7cac9607de55f7c744af8a132ec45ce79723f4a4a8c8b9ef658b360bd3890df164c9f1cd74eafb74feea251a34514ff2a57ae7a6d4bec2067cbf6ee4fdaabf13721bf9ae178b9034ac5e9665b 00fa3f15a506ccf7b50bbbad0a54d3223f5a95eb54f0d1f4e5d0cc21469b ab85af3765075e2fed789eb2b0756140ab06fa99fd816da68008ee55b7233cf49a762534a98168f723a6d0374237a6f40b99a34768b73a6fd0457d76273b7938a759be98a70c8e547e9e069294ed682e1670ee960630b1c30e4becd1a717bc1e +e95abeeb2c51a8cb75ab74253dbe130b5560cd52e2a63d501d26e1458aa568aca6694be91eee5fdfcf582c47c1c727084ee2b2c810281cf9b095808bf7e7c668eff00a6e48b06df3fe6a445e092c24d5687d7d89acc8063275caac186c441bc697b2f67aa71b03294e1adeb7e557c296dd91304ba0587cda3c984619f1eb4f2b 006400a4830889115aa88b860b3fb65905b01fd126c4aec2785518c2543a 86e9936a27f03a0870c2e133ff4a5ce795abfb522201bc5e007aba0d24e59d09a023dc4619a7fca9d696a20b6203f19301b4678a9c056fc7c6c4bee85d68675ae60a66c0f791f4761927a28f9136b4ddbd92539ba1c785a95967142cc75cd519 +bb8d8515365d240b2071daef0d80558fd3d0e059be9f6abb7b7a0a5f47e2ddca7d1b3b5101d5c583143258520ce8db0a87f877a395615c9bf879ef46f2f20f68bbc9706f82781fad69019396b27f292cdc70fff1772e90205a2225f80889f9daece1d03914d8776ac5bad24d8fb190ba10a2ca17768b918c2e079d83734eb372 00c7b73c324250f14fac0edc941f79bdbc6933ee8f64bf94b847bee5eef6 b1c6595137536c003bfe4e2f1f2a49cc2777062ddc2fe5bc714c9be94162213344ab7a423533625080db925530ccaa6615804a4d9bd090e44f7e517c01745eb83e801c31db082064f73d21af0be12af02956cbe210c0a0efa02607e203247824 +cd8b2403435fac9caeffa21b55eaba52d7efee0f89df7142340cdffeb89556303ca01a800429397e2ff6c746743b6bc60a87133274282d4cac02e4ca90ad95d80c93b84163b96296f67d40b2a1124b2b6534ab6b60fdee312fbcdf468d0e84eb85fce4ff360136bb31ced3998d29cfaa3ae685e638ee272058f123c4f35f8b6b 003db7f28e161abf52ab0adc8c4c8544fc989af081303b8688f22b7b2eb7 ade1ec35dd2cd7f74c1a211b62bf79c818ea0153169283727498e38c8551ff04ae4e18131970aa7a453266294ddede9814fc6d5ff99c4b6ce8ffe38d7e69801e9fec0e403cf3d40c7da92f88c1518ab0bc2a1eb8b29bae0df87af53f452f369e +4bb08eeb202564efb5bda40777d71f1bcc4c7c10b611e803e5c570876f3e319e9e2bc2d32031c56a32fc0d1fcf620d4e4377d881e9e1695bcdb78acba370b849115b86c1c4b83edfa03299da8e7fd14c7cadb81a8e4911c8e427e32c8c9b67e317575331967cf58085cff0c0d48ee0b8e7dc0b49687bb1c70c703a5dad08ec81 007e9d2fdd017d6da6029e88f78927d9ac9437f542db1f1fa99e32bfcf1a 94c1729304f7bf654520a5b29d1ddaedcb9d98b9117008898f841e7c19cf716ab9d010ab8bd83efdc59c03ea85d5b1b30ee3c449176e721657ce7f3ccaed2f41aa8a88c7f9729a527734a560a9b74ac1281daa4eb90ef236001a3a66d9253384 +0bce683d835fe64e6484328aa13e18b0956f6887b5e4442fce36ff09aed015889794e79da8aa60b4be565c78685674c51e1e7ac60db6a763c777198a56e382a03aff8b40862f961ae23e8b8683b76a5577769422418972ab0049119382edde9e752b42e8b93f403c1ef8665d7ce8530ce4ed9ebf6d397827cba6b7645e177231 00c94052760fc74c2b405ee4dd5dd2a7d38ebc16df9cc32df706075450b5 af9a5b9c4aa51f0943385e394733595799e3e59c01074ec31a14875970716e57a4fe4da61b7d4c5a456337750b5b142405424d5b204b4e1feb308bc2cfae7f764468bc845a5ae7fde2f3b8207a457cd3b4f258728e0340b5a7ce5679e15628bf +a6defc770426daad4dafba3bbd2a69881334f7c31269b297e440926db54cdad3fd7ad200f5ada2b72ad221ad99a06ecac9c2563a8deed89f0d0896991d1a652f6fa282affefbdb1c1985652300d1792725071631d75a182b683a48448063c7d2563ec3d430e0fd3acea33a35cd38ec0b5b07af96af71d0bfcd879d9864ededf3 004076b93487c2da8aeaeb4725fb53b7b41b465315335c18c6ca041175b4 b8a3c8df85bd3e0428dbe85ef91b65c82ec7538977479ceb0bebf198b3dd6f2b9ee53e2d36ca748574460b7c4425fba00c1ac7a568b38f50f5465269be587fdb69053363ab44e897bb557fa90f3ca001e686f9c03b071e9de4c2b39a154a77c0 +7803cdf4758c199962b62943f475c6c31356f5d9b997a12e21146a2399cd0dd3b97a860b2ce639e2801571599136d4a8cdbfb12fd1a5ce22374991e090533ff42823a2c58d2076b772814eea7fd7a1fde68263ef912681c72c7aa3e5a7cc44ee8c65e72228b7631e600121ea35bfbbc783b6ae3c0c8f80198ada218be533760b 0076ddd73ee4fc1f5e6766e229cc7236cdfce312417ea291f7c3328d5ab1 b282ddcc165bf0a3608ea1da73f12b8b67f9aca3c5500d8c1a16de96509b3157e219fbb34e69328ad7f283bc6338a4f8073f9643a7dbb0ee6141714ff1b39f86e4680539c0f8eba80ffa4d1e19c5a322edf0060e04ce951b1a7896cd7924ed6a +e789461e1dad0b6e21abeb6ae2e96385549d1bae39415188c8f833233da6a3328144c97ddb36e0ff4d9e19d84f869e79e609c51b32de59892fb0446dd28cc164a3e53534c950d26f87fb74e682db2038cde778bde06c3ee2eca2a077d8fcc2b0332e352e0e7e6487444a8ad60e78ff213b16fda9faf374dc6d27b7a3c4c6d196 007e1f8988ad804aae7d09a99be19384cc599e7652c02c391542be74b17b b507ebd22a10df5d5fdeb70260e6396adf6fcef35ee34a8cc1d24806e7d5620058ea6525500cfc5b857f1121e824bd9b03fee24b24e5361bea0f698e155261b3ca7bb1284e2f7d719106fdf732e62cabc19ac84a283fc8e2761bf34614ed938b +9b58c145d1b6c887f2b25fb672cd49c3a1117224be697c15182d4048be92968a6500f8bcf747fcf33145c13a8d72e891a6e0c4c7310c2b62f3181bf586fe32f1ecf4feee8c2c8bf6c2bfdf9d5f88981ce080095c93e49a772d8e7b59f9cffccec3ca2f212ef4c6748f64e224f4f098334d83108bf6f8c7b43c5eb549f1526897 009b2292b0244c2aabe8b43d95039984d504ebe05eaff318760e4dee739f 8ebe63ec3ae00155e77dc2cef77b48ff303e1c46cde6a50782fd028d4856075a3827fce7fcf9cc9f8e6dd49def6c2b4a135528fc61eae9eb898fba49506c58574a32fa60eae32df7589e7570b388cc80399f9b7baf5661eb965532ea1d73306a +52310a901fe9681a23dd6e02f12974d57f2c4f653322d9a0ff8b338cc6c2bd9f4765c90c6b3c9fb17df3f492e67d204e39d81a8fdeb92c852a1dcc6151ed6c63049037235c6751c9a902748163a567b714725b4d3995e0edbde03215c645b1a1da3147f7406245432800c50f823a1f991c863427ff4c68e4e16d1b106ee40dd9 007ca463b50fdd92d9163f1c2bdfce2ee45ba1437b79162e3e959b814cab 8216599acd0277e22658c2d4fa05daac911a9bcd1bb82b998b467b2c17841e4bff78e317bbf6ec22047a0999f5e289230f8ecd7f9b30900def9ffe1591fab16897f991fe847bddc72accfcf2c7d5d7a6b4ace69347ec462b244235ecfcbd5af8 +ff419c011601cfaf833067cf28dbe6e935ebeddf8b5111a97f6eebf3bb28376334f329cd877a134b074790a073db766efe018fce666a34650cbac285ae856fb6b3b8b96877282bc11cd9f9c8e510ed1f69bc2725a44a1d2b35de1edfd8bc9d20c7525ab0bbc27662a7cfc1bbd1e0f4fce5b88411521e3893e027cc8c73acdabd 00c3844750f63fe0c2e930bc38fe88522f4e72a2fd0db9778ade20e939b3 8a1f7334b9846a34fb5c6e0262ba990bd3405bbdd2a10b22f73effaea07a47a0720720236223cb7cedba4c37e272e9db045b3e500c49b38750bf5a732f90571a7e3976ad7f2724b801ca4b220441ad6ce8689377947aeddc20b20bf066dfab76 +05a89c4824c5de66587875011e704bc6e06e991ba8f3aed331cfffe55aa266a08c729f77b8d082dca4d286b2d451ea838d726cc2cf298fddf2d7376714c5e37b64506f353917caec525a1209391449c078c5197a371feade74f8fc8a1a1d67576edfda13c14ad324342fc0b09277941dc072ec0d39434ff1cb91fc59478fcde7 00a3bea235dea86506be4476eb7999dcb8e584a34238c4a894ad6823b93f 89dad141167d8c5258dd4e119ae231b8c22e528ee5fedd39da054e04706da3004409be1b5d091be8195107dcf16f9022144187330059c14c5d445176154b9a6dab5ad3ab55de062c0604cdb917683f4d19d394d982f74d487a04f398d1b57333 +13e6b5241365d9d0ef9e8b05cabb3248afd221ec02eab92284b98bda3d9272184bfe5251d35705defba5085381430e99b33a3ab77d7870e5102757d065862372df2434a25556b76e54ebc39d4e6c3aba5cd6acf0c335756f7d9385c1068d4cfa37526a9a58c0ccc7f87a8189176c5d4f201499236058ec061357dcdb5acdba40 009a367cd1cffd8dfcca179e167ea437ee48e9b6f42559dda9224701d3f6 adbd07bfeb15b7704131856fae3d6ac02af7266f85e7c747a409925417db72d808da6a9c69e540127a9f298bb6b4dedc0e01fee9567f5211ad760dc81d45bbf9d0f8b930b18ecdbad666557b891a239a2b8732d4060f372c895afc9083dfaaa8 +139a1a5090b97afb8fecfff8745efacf7dcf91a4393a7b629564e598d58d5be39c05c5830d4c8ca85d29e9e2c31ad0447864e867d0ef4788ac734f8d871daebceda98d449308c2afbe97724c3af8a468f1925065f39e52ba4b7d15728a744b1252a20476dcfff7bcb82aa72c209e72abb3c24419bc26191390ffed340c1b9c6f 0046f4ad2522e78b9b35297d28f361fb0ce82306322aedc119251d8241be 81af078acd7bed2c7fbd3790ed99e9f476f510e24859f9afa05dcc6a5c3f544e4ce1586914c381cd9114187f06d4f4b211ce320963ded4c21647480895af59a02e79a635e51607243bdf37a6f37edd202a514a68cfd5c62bf00e8db1f9fc418c +3315e5cda5f252e3291b61e493ab919c20a8af1286d9660cfa2f5ca38b6defe19ebecf820787fe692d04eae8a5f5d37abfb593309569cedf45efd0cecef6951b718924c8380ba52e8ab8c9bfb2261ed5f01cc5a5f9fc5fcdd269a0f122c597afdd9a836cf8f96838c3e8962c1788c3ce4128719b3ef4fc88569643dcad6da16f 00ac82137e9c7a5ecfb8b1a7df9ab50732934566a392a6c8915ee8ca8144 a9f7967689a4c4ff4ce871d91170017cd09d4a18cff997a92e04aee2c155fae73f0e74c789d0b15a4da9e2d09855017f0f7f9fce50f403b5b1349f3d9bb2f75532c1fd0bfef80c4cdb81cca86f26f41eb8b7ab2cb2350f76b9b49864491afd5a diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B283 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B283 new file mode 100644 index 000000000000..66f6691c834e --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B283 @@ -0,0 +1,60 @@ +067f27bbcecbad85277fa3629da11a24b2f19ba1e65a69d827fad430346c9d102e1b4452d04147c8133acc1e268490cd342a54065a1bd6470aabbad42fbddc54a9a76c68aceba397cb350327c5e6f5a6df0b5b5560f04700d536b384dd4b412e74fd1b8f782611e9426bf8ca77b2448d9a9f415bcfee30dda1ccb49737994f2d 0299ff06e019b5f78a1aec39706b22213abb601bd62b9979bf9bc89fb702e724e3ada994 a9285367fc83373703663146c2a533c2ebcfdb71dda9f031bb20ca3b168908ff12fe5ae086e4e1e0f74e85cacf4f3ef20ed98849c4c8d45d0536d1759cd6208a5ba3d1966422a908ef344af4d4742b8b09fa88711b7d2c957bc073c0072ebdf7 +44adcb7e2462247b44c59608cbe228ada574ecb9f6f38baf30e42b589fb9b157bb0560e5a2aa5523b71cc0d7f583b502bec45d9b8352f29ee1842f42a17a5b16136feaa2efa4a0ae306402940ecd6b71e57d1467c98e7960de2a97f88b43487e4f4016af1292381d70c18c7e6eed99a14cdeb5b3caf73688658e4c5b54c81e08 009c2804f8cab768248fb3fff8a055b3f4585c00de5c1615a19f9425b9432ea09afba8f2 a287aa25075030d5741ad7707f68ea61fe0b965bebc7bf6bff49be60c104a7abdf2de75cd53b9beb64f90acf667851a007d0547a0e25068afd3c52a45e5bebe7a4ab1a4de9dbed8a25bee03468265169512d6755bf6cc8e53b90d2bafd10934d +cffee6252c7eb6d91d8fe100a1e62f0ad9f862d78ca2b747a6c17b8c9ea8980dc239b3b673310e6e7483582399163e39d889abc1a613fe77849ebc09b4f7f4fe0688b8a9869ae918a88294c7ee199be50ee9460db14725ae70b449d0cb48f30e7d817ec02c0cd586119341dba0b74f0279330807cfccc99c8c340b72c1764a45 02e625a6bc6d0ce7c06231de827068bdb0abc8ffb57c82b35ee3a0f873b9473905974d34 b90b74be15b24343c7b0d8647ea4625bdba477fdee5b28e847ab451f19bba7b93abfb14a6fa3394dadc055e59bcb1fba056f721c4af27b6870371dde1750646e1a29194956b41a711c363a0fdc66609cdf812ec1e2a8723fe87acd1bae751704 +d058ab5dc07228253707ef224897ea0fcd09c3d5cc91fdce9e03c1c59c53fb4596be2ed929c7455e67ac7f4891aed3eb06ad88f2c4aaaabff045b959f900d1019d706b60526375851bb891494e99995928e4cd51c9616aa651ec77bd7e398916bb9ed3156391bf7fb1e29181e2b011dae2edaf803607def2ac6b194929a57f45 0376ac24e1b86f8a55c052d92a0bdc6472fa03acdcdbccbf7c321ec0ccd97aa0a66b4181 803e8f4be33388a272ff3a0f80986f7edd9ef35505d6754c2a63ca6a9296e0576f0b069b6761e9ae95006262f847e33b0cc660a0f0a05d19032e1a15d61c524da28869aa7aee963b4c35eaa8b2d4d3e4eeaa361619e8be911f97c5ef8c69df27 +c86f2cc7ab5df5cf1a236fd83792769474cef464032800ffe98a44cf29dbfb6f24088160eb31a11a382ff2a49f3e05e983462f5304272f96c0a002b69af3d233aebe867ee63fa46666760a6889d022c18645b491f8d71b6a3b6b4ef058e280cf625198715b64b025bf0449445d3dd7e1f27153926e617bd2c96638345431d1ed 02b50a6395fc02b9ac1841323de4520292f913519bc0d6a471aa28021322fc4dbcd7b802 8f8b7a649bb0eb1341eb9de65e94d9b3eade5173604a6b538771308d28d55d05615eb9dfd34a9e70dcf7f92c672854fa062d66edd7cb8b5391b799f2d4cf5cbd9555b61f26f4ab62b3589a0c4d9ee050597798cf7d6403a63403729de1b82e58 +c1328d8d2e5b6ffc850a9600bd6482518ddd9cee3fc9140febb72bcd444b0cd7e8074587d51b62cce4b3d4f34ad3355353fabe363369cf790db2df9fdac3a0ec4757e2dfb3b683eaa3e26531691ce765742e1c0bdc0e1028d347b6085fc459df0989c6a144271454eaffe413cae2ad7c8b2371fd2df1afffe56df727009765a2 024e5889722f6c35e18ca47effa9e415b1ba790066a91fb3c9f7b001ce28fc732b09bc23 b40f67dad34672df7b112dfe5ad541654191d4d75c34f476129548b18f98c52811201185fff7b5ea19c993c1e32757d00f928be44310d10a9a0866d13b8571d4fee06972ee3f997795b1e7263e990846adf10b59384b3cb025b00c2bcc7f023f +7176b7013ea27e94281977eacb976bb31c753bf80fa09680a29128a6fc15234f79f0e9900aff3217ce9be72c378042c6c34fced0158740073d1a985fa25987fb218002e425868fda5a47de51abfd04de34e2b8634cebfbdc98e80f93d94096193eaa82dc8778fc23f3765c7acdad94fdaa272df0ff0f28190c10a462ee78ac92 0056d15b81f40b6378588a5efe43e21b95e18120d514bfdda0e7759a1d0766a8a35ce5ac b2b8785b55f87bc018d187455a636e87907453c2e38e00d385609c861490525137db3e3870469e32a9f5f08cbfd344e6044cf13ca77c15e75de518345fe9cf615c78bc95150f1e778a74d995b66543c2f803170e8625bfbdf5d868c8d71f980d +4c3642ba040a9955b9d50dcd1c936688c17c363854358afa8ca49c6abd906dfdc4d89bb4cab0bbc363fb5b74e1f004d4b09ec9dfeed4c0bfb482a9061a1f487a3d79195ff7b65a0504bced3a28db0ebe8fcf8ab1ee4a3ae91324d15d890ac4c479144dd5538d2e36d3a587769ee9cd2d5c6f85a03362a022fe0efc4a3902b71a 012fb2fb5bf5f7e42a500154823a174ba2d05af71e3b0cf47fab46e673ea1822f1563def 81fa5b6be6630ca06312fba350e41821ecc5491aa33fa042fe61cbdeefa85dd69b8711d3894c4e9ed6e456848c2462c801640e1486af0f3bffb89f2077372944b50e1858fb7dfb4470345c9a6e5c88cced962b9b809208abae7ad6dfeb4337e7 +e471f39c18b081362adc7da47dec254dab8d765f005ac574640d78c14222639245563912d942f3be212ee3cef134407334c8fe3602fa0e1629de5331643d76715dc1b0ffcebd484d86c5211be4b285a31688b205fa988e6c15b36daf396ccdcc209c7dde2a732f5c31c84c7ea041408ebf15e56632583af0131bd7f531b5fc45 030096c54fd480647e017f8cdbbdef292e799f054e3279d228b09816a757566a744a8266 81d766e115a1babbab64c93599a027a247440981ed8894cf6e1a9d8bd597723e3f27c86b81e1b7123358638cf8ab1300151ff771323254c5eb6a5fbd3161d157545f76a61bb3fda140ff5b39c0f5f47b3225cfe4977227c60947c25616d5928c +8a93fe53e83075c4025228540af7e96a588520da34e3eadeb99a4ab2f3dbbb8f85fe63a3b86c1f4ec912e665ca05b43e869985eae3791b91205afb1380e16c25b74e6793fa63e4a55dcf25dc22d03f09deddeb9042b620434111afe08c5657c7d754af66ad91a1b5423301b1e8e6389a1404060d1b6a99fe0f89598482979e42 00a1b7e9c8c2dc25b494b5ef3195b294e41cd3c2c35235ab42542bd3e2a52d5826662bf9 843445e58a10ba20ce6bacd1a71c8ae19de378d409586d26250938ee59efb59529f7b38b1cf38a383bdb26ad10a96f5214b89c0f9872d50c12796ae7750198751fffbea9c676be6a5338201eb5b9e5445aec8920b2696841e0e3e39092c4858f +e193a8ef6f454ca1aed38bb67aca6d08280d421b196d89938c0582b7cde74dafd71716f3818940af412d4a7ff3960a8517aee108ae03576b68ee7557d35e6f1ab823d124de7243dd02b542591f62c80d822608572889573e4c9dc62f99d68e07800da6f83cb6f5e03d1f2ac15f90e38b4f25e0a75e354e4b60cc81c0bbe81d39 0059b1a8fb84530bba7a607ee88310e31bc6ea6a6881603567a1081a05a3a9ff87e719ef b78b3fd30b59cbd2d0309453f7af8d9c7d7f3ee35e90dbae82efcd5ea6cf426e3cf74515879bd9ab0c9cbeaf6dd92c440c2aecf156ee85796c4128f383c42a2a46f76b645db4e8b136d81afe8c1079d168c0dd3971fcfd6ad55c63ecabbb83cf +8a99b9db191f6cabc88b430bc2293e6774d5180f019d871839289e25aec29379f14606e742190b7aa062e3b29fe0254146d9614856c5140c7315015abb98ac00da2c7e33cbcc82c24b797366f12767322c4381454d9d1eeaedb616b0ea5c66d1422da459f18081f4f966d05ce279c6ee69b1bf94b8388d38d4b770d9ed69025f 030ddc2c7a4ce300cc2b75f0f977033f16c1f8bb13aae3d494c381f9a6dc8622499ae4df 8cbea84063328ede6693e883402a7d23a598b6d40197371f06c61aab58659442da466bbf4d373ca6cb2cea4f92bc7ddd04aff9add8ef591581fed8a9105906b97ccb03bcd75194a3216cb1548ed5329a5ee5b7909c7b09766075e454ecba436a +5c437b331831530aa94623b1736f00b986172699f0a02a5e5df0008bf25341787e2e66046f2c929dfe0058c3cb89fc5bebbe1025bb1edd1ee31522ed568e7b5b4ca3991afdc76a68cbc2c4f81863e27fdaf6a564fab2c6354e5c657de81390f8a4132669fd24a48580c716b5b7961a9c091f614d11cf45dfdaec8946a54a11d8 007899928922fbfdb5407517725edf231d15a8b62d90b7fb6d8c8d20424850dc44f797ed ac104d373198ac9b8442c548e776f64033361a4efb26913935321f13e4c0ae210f33f30678ec3dfd91ed79eee047150b10822866f211f43d76b7e9d81562d8aee458d2fbbf61142909fab4ff4f56c902154bb5796dfeaf6466fd239552d7ac58 +91aa08567d8da4c90684dc06068f69deae240212842ff1786f04ec41b40d9187aa92c76401f9fcedced62876a34df82ad7c1e63b68bb2a972257ea8542bda6a7f1a020c9b122943b6d651abda8b8d322a8fb762eee376daa2d3637a71ed6c4f5cf96f61c0da2d6e1dda3370d80e51da2cbd8aef3267168c67359523faf910dfb 02a2af63d1171930758bd3e5bfdac62cca1a83a3b55a49b3f80cf0d9ee4b2082757beac0 946277c02431cf35064a706fe1a591f461ae5a879c3f863e9b25196302733af231df170a27c9a864e8a0fd4eda4dbf3c0baed686c952f63cff1eeaaf29606c01f9a89cc7a765c18b34c535ff66437b90f473fdf92c355677f40a67fd5f1f0be6 +eb5297bf408c1a55e400a20a3c10acbc5c2bc6d6ccfcc0941fb7a6fd4d2834415a6df86c3a6c4b867d1215aeb8222153da8cbbb1576c92c07ca2c36d8f243fd911f9a057e39ee25832454e28d7ed52a8d04169b9b9677a16b32d5d211b8573a8986e9bf36d7206417ad2771daa11bc21fd7ee1029b65ff7c9b2705a6dc9cf9cb 035994e89e13916ad82608f74a639e6aceb756ff913aec440519946d6434af9a60a6af49 90f5dccd2ad05fd6149a821204834e9404482328c1ca232e4c9371741faa8e627269ff6d4340e4a7f6fc93e129bdf28108db0ba446eef6cdc873d0034ac06a74bc714626f76b13d24400e554dcc8b3e00187934ebd11864ae33e93feff6a0eab +f415d0adcd533dd8318b94560f86732c262ad2c6dff9dc83e2435543f429a2158cd2fbab0d96c027f71008c4895ecc644c2ceaefa80937f6cc6338d15d36e459a16bd9387a361a6d800acfd834ad5aecf442e30b70f5bfa164747cf9f89325b80976052a83a5e896c00c54f81472b14329cf23bec10a8e693005de2a506ba83d 029639da33f48e4fb0d9efdf50bba550e739f0d2476385cba09d926e789191b6fb0a73ff 80a18aae8c71e7e06d9d01f04e5efb9ef822dedf4df55eb89fa54cf8342cee21aacb1509bd3f1a7ce26ba57dd38c678f0f7220a7779daaa4b9131ce74b4b4ee32ddcca45521914b465918ef243f600301861444c83103fa5f3966ea328c6b8b3 +b178d86c9335b85e02178fc4551769db589ab91d823fac219c7e14e2f029753b203962389476723832f8d9631dd7764e6dd35da290afa42a794476f5c7727b3688aced848dabc9954201578cc7b25801710931f45cba1199d3788d64dc0188412e70723fb25b8ecb6718358150c4037b5b81466dac1686cb5270bb1c72d34bb1 00583a7ecbf2a975a32d07428d27ac82e5dc13d1466c4fdfc1e6a05a8d9a289f1010617d b94bd80d40e6db08dd5738b96fececd6901f1af14c64d2a66af97ded82eccf8ea257961293c008a74d3e9c24828675e51250ea762f781f65db35cc616faf3c657496ab9682bd0094b5ec79d46d914d9e4a4c6352bfe6cd6988c0005c3be75ff9 +c8bfe9fa7c848531aa2762d48c153cd091100858aa0d79f994fd0e31b495ec662209a9c8761cd1d40c3d8c4262cf4dc83c4a2549a5cd477726ab6268b4b94a78b1c4a7e700812872d7f41912a723dd9abc305420ea1e1fb1fee41bf643f3a24abd6e8fbf6fde2475e290527724a6f99fd75374bf7cb01b34d3e60d8db33c4de1 00f817ab1b49131fb9bbe8c112c25a36f064efa85de7506fb9cd29d81b326bf276277f7f 8b59aa171eb157906ae32e7fd4db2fb8f303053383edef9f0593de54948ce9dcd8bb7becfa4443d08a360c8e229d86b60c5ac34f291f4cdfb0841fb60f7cd46ae835ecc68196f94bd42e233647624db51657c9d8562d9ad4e281715c59948f38 +9a5f563d0f9fd1f31f3a822de628ae970954f4e71292492d727109036491c29e66b9b0f2c90c26abe94c08502f5e923a9ddaf6a7d91e9541ce90d0a49f03ce4e4769753d5b7d922e1ceaac4b4cfa4262732a09550aa076b8ff9d46a50fa17de17e3b6bd606698464d116fcd5f1ae11bf45b0c48d3b738427cb47b0d1272b03cc 02782af76ffebf3e2bfc0576b70e4f4bb87c762e2bb230d278ce776310a14f5b678f29af b1c3436248c4ddbec68c58ca13c4be75aff68881727afe745fdea76462f6ae3f6891a29408ef8387bcba54d45d0ad89016e149d0fa0c4b9499103e672bd3f4bbae102bfee47f4397bdbccd3a81f8f223263f4e84461e1fe08eff3ab17a8a55fc +3d6b065721da9de82cb33ec2c27107eb399b1e69ac8fa51145ed4147e20d72e27434104e76af988a3bc94f55e36677a05182fe2376dbe38195fc6a30673a4dca87336c7304f3f31d49216fbdfea00fd1e105d8b0c13ab11f8892e0045e915c17dfaab07b24ed21b06af5a8cad4f45fbee5a25bb6e87466a7bc422c0bb896440b 031b827b88f14d3822244809096157df3c0aa99da90c00cd9f0b18dfe306f6881834e6b6 8a348b5c503e7a8cd52f888728670469333a10d074e073454d0e43269bc505cf91a74e058e86ab8979325acbbb507a12077388287e6e245c27adc374916c0a13f72af86d977f4f5261c49076d8e20703060b344bb54f162db489d3f4f31a9148 +d125f0e2e6135567adec9e77da2afc6862e28d618416632ced829d14ee8b61116da59dfb44098a40a0b927731125617e3d2f32cfbd1546a6e758c1ab6597e75db07add52ecb61d37da2e9ed04df95b36ac249f4cbd794cb561655cbbe4b34834c497b3d392d78ed0db8db683aff0076fb6e43acba3fa2b91210cc6cf3fa594b0 027da4916f1c471cff80bfa14d12aa10270fc3b26caed010c0111f6e5a40d914a3927763 8289a6e3edd3390e098302f68a99d58b40376b8ad46e6c528e8b03ec8f423ee2e9dee64b6a56604ac4e3356f70ac9c86131f4bebd49bb38100205f04b9aaeab4763a95aeed06e07d390afbddee4387f30a7af59f10275f633bed75280f75aba1 +b380f97687ba24d617a42df1b14e5506edc4b62dfec35ed9fd886bb769832cec7f9adae10c21b7cd9152588797b4efc6b2b30a873d3f25e683ea9be070dd69731949a51121e534fabfa3a2eae0ee90a454182248bedf2595cd47ad08614177d58f7a773f5023b538f5f568682c83fb60e3fb1aa859948d01bf7b214e7f2dc719 010608eb51dc0ee97d6e488a23c582ecf0ea1df9a24db77094d87b3fb6ca98507280a934 a7aa4e2472fad6286e590f0ecd70f37c87c067b4bff3730a9bf24237a61e2e5dce41fc1e12c38cfd46d58fda73b2de9a17c6fb8e673681849b2b17af5004703c51549d19487f380c2a158034b01d4f08599ad92ea579cd9f4aff298c7b036dc1 +3f9ec57e4228e1a6ec49df02c58d756515305e48763ba1dc67298be9a1548576c28c82b4e9b3f62357d9b3c522b16d5c496a39effbdc8290edd2cadc0019e6b9fae1e61238b13b6265ad2ff413a5a0684babdb0013e7632051455e6fd943815213c555dba96cba8911e006bfddec6c3353065004538f37e48df9e339498d85c6 0123f9eb8babed548df08cc3afc1d3b3bbed52b538d4654f2088fe76062fbea75b85a560 8f0db1a1977d9313d43e699fe3893650bfc1628a7ad0d95fd4224eba0927d66a2258de7a5bc36f9ee26367277b3203381647eaad060b4cad788a884df2062959d9b9bf4343b3ea3c91fdc613107f7fb5f04d170d57494781b7034bba0502db57 +bdbd7b7bf3337bd9d21a3c6db379f95408c17e49dd394e94737ceae889f45dc0ff5d48cadc53703a16b5589939506b548f8dfd34c577c084f372166cbea320c8fd07c809b211e0749ea639e68f890affa1569b66bd763c7c710989e491011371eb1d93ed9479ff0216b7f79c901a2023e2cf80b565d1c0517e73117190cd2f02 006a18e626452111922e02e31d662f4301319946a204ae8a34f06b91dd1b5b96456365e3 a334b244f116f433ea01bf65f00915c47e2142b87f5026957ca16e47041c7a9d9240adf5c1d2f1661a2777348e25f02c09a91a2e4200ed2a1367a952eb63df466056e21129d1c49e7749a6182e152fd9cf1c115e39ebff6c82908f11173a63e2 +436b288512ea57bc24f84fdd117da9dc1858bae8c11637f99295d88fa9d05e3c053a2584a6fe200ad190b3077d9a1608f660349dda405066c1562f6897ef69b6b674d6bc11fa470d0b96a7cf8f6e098c9ac03b0ef415aa045867ac7c11d16cee78ecf08850ccabf70f761682b561d0d0e4a889d840dc74932648ca2fb58259f7 03307fd717015b12a2dc76ada21442ac1d97519f66898b214c2ea317ab0f0905e819e4e9 a90e26f5aff331fc96003e7ffc955de399d518d6d759efbde0c999190c5724de0068d4cf699d0f08a6665f1abd0a9e750c8cf0e18c33b4a913023feb9d71da42589c6883dee1baeef9ef5eeac90c6520018a573cbed060ddf01c7faf21bad4c0 +672faa156dc188bf16bf8933d65e091c633f294486049ce96a4a403dca28a149f4f840e8bef47412285363e9e89006614b013a41baad9885f1d9980cc897ffbd5f8a7d0e63feaeb42c07776efb307ed680ba1cebf470dd9bd8a2a9efc2b1daa569524394f9a50398add1a5bd2f7c263f9e63c2d49461acf98444fd23341ce78d 014f9f412e3c7d770626e800d43cfcbba3ae6aec8563af748e8a97b67d244334b6e6d2b3 a07318b528e5327e0a8425efc278c10b62e6f5b67b951128cf79958cf4ecdff0a56aedc484b8e317fe4074401e50a6a10970c851da3d0d40d36212fb7b4c56a90d7cc6a2f2119ecd80f47920b24b807795698d901188c6281c85b560a33bb65e +4321334cc8ee44f1cb392a4b280a95561809dd3639ddf43b6e11cb73067597988d95b8643d86c76c3c6b932d9262b9b8b55a04fba0666dd8b8ff1e8fdf799ae3945b6e30d3af3966f1a6d634d5e012710d66cb447fc3375130968a2e1e647780aada2609d87247c90338dd71c3bcc3902311caba27d5d4ea4d73ccea960d4bfa 03091a6a8bdac1e43542dce752694972e734dca31c061c7d1000754296d0748055db3f09 b6cc055d866d17549b47bca7913797821fb248da2e9d629593b2f8f482976244c1b8b73c2f7b7a5b58c4227115b3726c11891aa588676ff29d4b47ee37d155ad8ff5e70e898288e0fa7df9ed51b2d5d288bf5493fb3d05f738275dcba3e9204f +2087e22094570d39fa937f15a3ef0601709a66666344186a33b487d041793fbb9709a95af250b1df0762ea98e911aeb3ff1fa19f0aca53fd4179e454e0e91636e55cc5b17cad9e1575c82ad265dc34c4a66b7a31ecb9ef9dc756f2ac1d9dab35369a6bad4a0f47e629daab91addc6d297d1e5d81477b3966d8c3b607ed194d88 01195921b91353db9bcd00510efffe009c94f6bd8d790f5fb3e5a0101c9ca5d21c6ef2eb b1da58e5e0226693f4db6dbe9ac11ca9d99d71df11b0fe8387878851a3c7e2003cff5377b5444b8570b85dbfd86b7964159e83467fdb00d3501a71365ce311531b5f042be0596b9558d6f7eb413e6246320b758612bb0d9e023c8b38656b9ec9 +15c7bca449a73b03bbfa783f5a91ca0b7916889a5d99d541e2e8593c3b176a5b634ba20b34407fbd94ae1c1398f5313cab7402f3bcd7ad277a8c66d09a6df5dd086b20a0a3823fbbb80980cd86bd13e527eee15656cc977103e80113539e26695addd9eef6a1f56986168d9a53f8b5de833f8962c3826cca106ae9e8c00208d2 029dc20446e9abacb43823e12a83737b46e6e577466b5a3925e0f9d496824dadb4d4b50c b49a00e0115feb603d02c990fe65f9f0b44b0328c63e9d465b862472ceb46ff65f5e1dae43ddccaed11a55884b50492b0d4106b480bd4522e8b0db267dac9890f8ccd1ef870b73d4173e18c58c169259714861b0342f80b12637b321edcc7cd9 +d12fbb82ee7a57eaf76b63fd6bc6c0a65c85f135f019d43ff7bc295cad15d53729d904fed63d69d3ffe8b82c0ebaf0399e2717ece40e011f710b5db46aa457c23b85545953398b814816a1e7a8ab5b0b14c4a0451b0bda9d0d2ec4a374bcaae208b7fe8056bfa17d6b7ffd4ba2e9179f49b9cd781b0c06f6ce3eec26cd428cb6 03b9b77d19a42e9a555da8ab70aa5638890b2ed21daefa28ca6323fc658662dabcbfaf52 b54660fe456a9f3bef8e4f129884a8a3f7b94e9e5091ef35cb4606576e7225aa908b979f5d34791d355b196690819d650765e098e597adc011b11e203808b3e3d2ed5101129a05fbbf5a6dec961c645b986c04dabae26626587b7a4348e20100 +eab0a37915c6b43b0d1e3ef92e6317b3afc8b8301b22f6059da8271fc5fe0e419ca6097daba213915855631af64e10d8382d70599d903d1535e25cbf74da3a12ba2f13c33a8562e0db03edce791f1d39af8850fd1feff0eb25f9ad0a86dfab627b96e65831bffc5f6d9693d20493bc9dd6eb3e9325dea50b055768e8aa30d49c 00b9f8f3e89e9c1ef835390612bfe26d714e878c1c864f0a50190e5d2281081c5083923b b234160e4b6039031222c118a83d90129aa1aa72b0d600547468b1c934b8a47bc15b8411903d501116aa84745d99a89a0578459362333516600b65c1241172d058db5bbfd04eca87e91dddd161ca544b6ed717f3b72f849a695f613d691be913 +fdb93afd5dd1e3eaf72c7ea9a6cddb07fc2054499ffe152cb2870163eee71ace5bd420b898cb4fa80ea53fbbaece2a1eef6427b632320e9c97e38acb16b62fdbf6585b54fabf0a703307ca50f86387bed1815a05b0c8991e0743d10cdf49c8facfd7ddeb8d4a7b706b5a29e1d00ac88b0ee88b3153185495ac8388cc70104154 03a30a1c15b9ed71e102341f97c223a9b5ea3e6a335861c3cf407ef691a18cc639dbe74c 8e2ab058652ab65656b824528667ca3e45d53847c4c4b6afa8beb68f2e7cc1563398f918bae4d324a1fc5c05b9c9b5c81296daafb6ce14e1c3db5b3a2c381c184025fd60806e9d440220547d38894b5797b51d8ebc3488a486578d86dce6dfd9 +c78e35d1a5b1bbb0ec21e7ba7b7c74c859d88f3e100e40ae34128cf093885dae4e87cd09f3239dd8e79e25305220880dd352a650225d9bd193b9b84e488c458b0b5fde1af941c0c9fdf952d2fa41f665918dccae27ab7923da4710f8c27ac8ed424992568dd6f0a6c3ecead21650ed162e0292104eef3c2d8551be866a88d279 0083330123cc64c11888c1fd388629d0b329a50ef31a476b909a182c930ff02d0c389b93 977a8d054eaac856baeb351147421ee23d0f3bedbdc7a2a6bef65c32c16f584f3683ddacf1ce512b72180d8213af80c600f0128fd32ccb1f7c6996313160acca2ec37060237904135d7a3a639f2e37725a78c55081b52943e62420a45791a379 +e05435f695997229cce314e50065f3c5f71981988dddccaae6efb81f936b22cb48813f506d1edf5ebd69b0be34f278592c5935f0f6db0cca1ef9d62834fbf3c4c03f4da0596cb4d67b7b767e85dde7b7c6fbef7d89babe6f97b876b33594a9e36ab87079861ee556fb03274ad4af527342a4794192b8933f28c6220f954c77de 01dc2b656c207eabc9e0d6272099babca8d149c9c4258b779c2f06de75f76d77505271c0 b84a5994363fabc72e50009940da5df2b4d4d467aa20d3f607fbef65489d9714dd15a433b0101eccd6e49d06bb59e53c157e61d03e0513a45a16844ae72490962f88909d07cf0c3151bd237aa455aab6cd192d5b841c7770b4f4db7a8854ea95 +0f9f36477076c4b5a7d1ceb314a397fb14646695b0803e36e98908c8a978770269f165a1fed8f4b655d4efd6ad283d7f5d51b6e1e302d360e8ebf4e887c7523a757ffd55384e114bbfc6b7a0ec8511079507b919065ca018573418f9e394854c5704227772161707b4d0246ebceb91192f0eb2ea994ce61fd98a6d14cc8246c5 00081772348ff2d7a3fd57fe703555ab2e14f5d203c4cf0292f944e827e884d95f3b1d83 94881d8c28426e273fbbef541e4d8ec4b85e36e20d3629ade50247dcf6c81965bc76feb571b7f1302693c44b652b7050084504473da7fe8140b30cad65c1a4bd9a9986ef1183bd67fa124a35489451bbc1e6dd1e1179188d97d0c8cd56202ec4 +1d38b1c342b6611dbaf412a66c1c0b8397692755f576df33b31c2bd12b7f0707cc423376391f7b00aa4e7b7fe54532e2b39c3c5284b9c8ccce48eaf9308ed338992f1d4ecde6cbe352e46339d7d602942158387881d9b493fd40cc59d4f9b53ee4191d42352c6f7bf32c331f0c5afbd44a92901a4b713c7cf6ccddf7de4cc6e4 01eb6bf2ca1b5ffe6f6a795733eaeed12de6e87c53571e702635b9dbd0d96b47df4a005b 8e95e675f626bb81a25dcf3044007c7b232070bd65a62898f4ec98d0b608ddaad24ae636084a0c26d8416db7aa117b2419be86e269fdb56ec03a0bc7f25eba2eb762cdae0804df726bd286f810959acaff68ba0f30acbf90c94e76ed3110a065 +3353ad05ef90e9762bcfedd6ef44a1e8ea0392ebef30cffd48ae620f3e567e1cd44882d514e7c6759200d4bcab18afd3038c3d3f8c50f7bba32a04eee5a4b1cfb8c349939e4efe0a46fd047d02ed000d8fa1b98b0af5586f120d9ad174b3aea33905b979ece1eb3660b1e070c8821b32df41904ad68bbd8ed247aabd94066f16 03b2a3e65e5a306bf8e3955b60e856dfa9bf68c1275a678ca056207a0ec67c96eb3f8309 89b069632aff23e77393e653a013b01f3c3319942922753fc3f0a2e4f3397c4b390c3480ca791e2aa9dfbae66169f610054f1805fb276073b177ddfd83ec6fccc350b77076e77037bf11e649cf25a70f6311fa94f7bcf99aed4a27d6026ddc83 +e7ec162185fe9a5803c6b03d98041422315ccdac67e48fbd07a1ef3c5661158710abc6791bd0a75d56791b4ac0e7695d53c5989d9fa6a3b037583b2a80d2b154b024f1c36b63548be9afe1d51f2f68b2ba94d4ca1e69a35ac10e15ba72242aac20f7526b12ff9d3cde9a9bfd70d55adf9bd92c66d092d7d08e9764c84bf7f329 01fd4d1af0bb7c79ed5fea7bb45574e46534387bd916649485ef15207352d7302e81dc01 b8e42ea883f521ba9e4f790f8a08aa6f984a9c1426de58614c9534ceb6a60b4b51180b89cec33ff8202aa3bd43b1305b040f150c34582a75cb58d78709c80cdb79e3788b0a1c63e04e8295281ae252f50000f52876e7aafd2193323f75eef237 +87c8f2e3f4fdebce0ca9300fc1ebcaa934f51a12b6b8f2cb6bb6eb77965468663044afeb2a1334cb5a81e74b8427267f8b34b5e9ff0cf157a9f18be2b1942e32ca61dc23ea13c3f9fcfa16df8fe05e067938b6994982676463fb12842d4ec532cb904cf222aa805dd0d86ab9a33a83e294c6d81e8dfa273835e62e9041dc8ff6 020380b1136b5283e9b7f54b7535ebda33b129ceb177bf5d3d07b1daed5edd9fb3862530 8645df24757e91278990484e8a6b66e5af9f1d7140da8d3431aaefd9aff41b3f696cafdb05a4cd9467e9546af8ba166717fb8c17fbe4913f4556cef2e9ffa53ec779d5fb9c7178a1aeaec5dbededae8e97f510ea6232ca3128dbfae96e3f7adb +2ac53e8a50c4afe3b38904255b7cbf150c5f79dc15932dc0ac9aa631521f68a0d4b6bc5a04d55c99a36531fd4886a23a8d99f262ecd2a9feea925d7a96ebe9b6979a207b7f9378afbe404fc8e959b0333572a2c911f8743c0ba64eebc7ef12fe5435d2cb0e5091ae518b6e4233489efe3c16c6f21abf4e2c6808b733914e5a7d 019f815b98836948e0a0dc9c30828c31b13e175f1e79f23d084ae1bbe64823f4866214b5 8cde5e8ea9a82fd70cd5a1dcf1a63e25935dd763c295f8de71ff07e880c8680d0e28676db9d370d8a238b74d24a5886b073b8f2ffa6dca32ec15584c4c1d6738df34e87bf459a7aeec5b0da5eee2a7fb8c61318b0b9edb5e8b09d0da670012b8 +0b201469cac4c078f587edecdcdb6efd5752cb4a3f43ab540463c4d908c27527aa3592f2f9acad85dd94a3c056bd28618317ebdf2e7dd6c5ad26fa3c31dd8e5c50c60418d91c93bcbb59ec1adb1db791f485ded78a5cdcddd23dd1cfa4f13443468d8a5f2d648059b9c4470d0f4fe7733d56a28a2c24456b6923703ef32cf0b8 001854e954654e726cf4bebc0e5a840e8809fd716059211c6ffeaed36829808363164684 9533f1f10ce6f6dfa999c6dabb0c1427d72d9db49bc37cf2843d3e6b15b9115ac47530b532eb524bf25449c8421bf1ea018aad12fb86c566455162efb30c5a37cbb387541d228b0933e3396c56c86ccce842623d8889b0596bf62138e2b38ca5 +fc5e4dddf4c4a328b685035ee79069770fbebcc56c14e31afb4bbcdd5220e025f31eba794fd6c05e64f19678dab33ce4f084bc32790392f14bf35669d75b6466b4214ec30d58ca90ae285c9058f5804a1fc9d7a995958f2a0e84ee52e8a78b601bec04ab607ffc2091749cc548c6754ed14e2e5f92315bdacaa7a12823ef76bf 03548f8020819588b3202f4c1ac62eaec6a47c2a19b2900c5a3cf5b4ba5804231141c647 89cc6f1bed68883b4202f912d161a26c14ea4e7b6b410774fea12ac0557fa58e7037f503ea0ca48b6e2de807b812b80e0c0d89da63b5ede2d5b26682edfaeaa159c8bfad04511858d73bfefc5e8f4ec95254afb291ffc17ca849a6ab2f6654e1 +284cad790e6207e451a6a469cee3befc3ec43e047cf91b9dff1485718aa29de36a43f7c51eacd8589f0c3a96ec18e8ccfa92941b50b2132e3612d5b45e16f60d411d1c53e373e1ba451352e28970ada9dcb9802102518a385dc571dcf6900971b00346098a58042e0d1d129bd6801fa640a895a458a45b31318fe63ebb30c6e3 03cc4505005c41142308f1489226b7b542e2e7f24f1d3089ff6b92a4b0013f490ad52e60 81dec7d28ee81aebf79e41f58a9abd35121974947008798311b3ee8099696688f380ab3d6df52caca65d12afb523ad370ff364e831a250afef07958f61f69d456fec1f54e60bb546394e95a0e5c0f640a5a5928075f7641231e81225d0260a6a +6d46e57abea9d115deda48b69fe8e0b36144df2f6a659509ce1b514c8cc4769d46e5f71df2a084f1db4a22fdd3ef0c2f90394f2898ce291b9f279c0664aa01419f5f6bee1fc1299871b27ecd57a5ac548f99d01871b8c238a6b46044c953b2e78e22346a0c7663af4db62799038ffb5c21ee512e26d01e70a4ed967377ab8405 0144a2fc8e0aa63506e14e4307df36416f963dd9da78655832f5b991af8c3eb97df78efc a19f30b63ac5a0e46980070af1bf0a7330acb83e6673d531d50ca704b1fe8906648108d3432bf7a8db3ed69228f1a2b70348ad811e1a54da878ae929c5995fa550c58ff61afa8ab058f5a605430645d37af71cbe9ce0c4f97989593f2db12ab9 +dd750b39bd8753f4e473c4484e2b36ce2da7576813ebe05861c339ffae1d029bc793173ed394091c00685ad82f0550cb21ed1c68f0c27cb7396922239cfb886647af204e88a9101b7453a8ab662e270b87a8a13f2fe61d695597382cabeb781933bebfd7d0dcd33f77266e43e32d937f2dc89f67525e522977ce73e9ad36c8e1 024ffeaf139043ff25a395e4c560c7680c1c2155191378917eb25194136b4a69597dc277 b93620e83abe8690abd6ac965e3f8021e74d1949b1588208c5740cfc27e81543869b118a6fdfabc576fda4204d0c4a0905bcf250eb676bec0c281b3dbc80357fea0e86839b59264308b39c8b89ed150ab8a75ffdf3451e62947ad62a60faba47 +4736e59fe5812f63737eed57a570182c065538abd9fb0a1c9c2059199e7052ba57d84b5fa1cda2ad9f216610361ce1dfb9334816b6bea509283756a03aaae2e5b0597f492d078b6b015a40c9785dcc5d2ae266176980db04f5cffef40e16661a50ef871c5f531d73fd5d114fa19bae9dd2da4267a131fc31849da38c2b78d1af 01d1f2e0f044a416e1087d645f60c53cb67be2efe7944b29ac832142f13d39b08ac52931 a692451c69765858e39eec96cc03dadcedce11ac86fa705e163af06bac856d9f2dd69a330c6a9c7e5c578e046e92b5f419b956c308edaeb4d17bf9549eb56e804c1addac9b4ff1b85312660c19c5b9ec1fd7a5bc1e2a4642e6fc0609d77ced64 +e573fa7d4bf5a5601e320130de91f4ad87eb7ca6b8998488afcef69c215b0cccd221b8b66eb0af9d699af9ad6c4b4a580e82941f31e4c0a9bd83995dd076c5ac9bebb34481061e7cb1b26f6e8c6b26ee4bdf9887f7ae2eb9fad3115a21dcc96acce85d23a040c0ebbe0a56e75714dbfa803d6e279b2f4280bcb993f96ba321e1 01337362609df74d25f7adee382225e6a04dd6ee4c6b45fa31499ce9edb0ec046325caf9 867821b6d2ffcc16552180cbd8775cb1aa4e9e83128d9409ff80fd37cfe593279b7ae0216941f4a5b402dc2df7a4b2b915e49cabd06cdca3f97f00992ca55ed94c729209489bcde0103cad269d3177a85a5f0ec51c139ebdc2b06939f7504e1e +7862864d0d78b44e2a28af44a0a16d8e9b1b8c4b794db0410c0a863ba011018ef43e1e11f2fcda2f56fdb2a69cc817df425c9cb3b458922ba00d710190cae16d61af3c304a42fbb3d0c4a74a297253fccd70aca414865b41f68b01c561be281265fa89f63f975d3101334886e85929a5a47fa8dc459b663548faf8ed7484958d 01be00aa0afdfe92e24a2536594d4b41701ad4dfb223aab35ff49310bdba7566057fe8ac a0a3d4e3c56bb47a97c4412a09f60d02d9ec8574b9ceb4938d5a60f9251156346dbc23d4d5290801a36da6afd83710dd0055c4517e923988e6441d7eca8a6aefb18e41e692c427d6ebc2b9b70a820a8f041089a4e009dc9f57f1adba9e883a4f +e73c96d1a84cf7cc96065b3c6a45db9531cd86a397e434072a38d5eeb9a90f62bf5d20bae22b926cfe967647d2bbb5dd1f59d6d58183f2cf8d06f4ac002ead026409ca6a1f868b406c84ff8887d737f65f9664f94801b2cd1f11aec336c0dbd4ec236d1cc4fc257489dc9709dfa64eae3653ac66ab32344936c03eeb06d5852d 012ad0aa248db4fbc649f503e93f86104cb705d88c58e01d3ae0099590a69aa006aa7efb 87ac05f94de932a1e26e9911f521fbe55486e11a794c57681649e05fc1c717bf33c29b1ef1b224da8a3449894896e0130d5b703a80e4f0a673dfce4469f2c6ca634e5d5e6a3ad6cb5beda585095a5599c589fb514be6767fde076b3f8bccb545 +a73fb0aaec838d011110d49c5e94395ce07408917bacf7689d2cfe0948c582214b263c6b80e0a55f1e159086817605723740569eeaa1bae96b979679165c5c35ef2142525e943e595e6b4b160acd7ebe41de19775346363f779b1f80b6d5f0785b92a648028e456af8496102d19dc6526247a654bdae3368f075fa9ee92b2f4a 02cfbb8f340cae8e2e2322829148981cd9e509b0c65497fd8d9da5dee9dcfd39b0f7556c a07e74fcc291427edb73d37a25701cad9ad3d1694e6cd8832bf124aaf200f19f720e3e684da28f686372b740eec232ca0e004b0c4787b9f1055f71d69ff3d994d62eb1057f7583957e9ecfd9d9f3655ee3a69e372ea18250f6c9a152e85de1c2 +eda775984c7c9f7db47af30dab314d070fb77e9b623baa6b73e2cbda800f167b20fdc2e7219391efacf908f4ceed9b9b6bd3541b52ea087177e18c97391214758cf6455311fad336ab56cfdce57a18add8cf85b0a0bd6fa7297dbaa34bfc8585b0f06a0aae055186658c227e19cddb65de88d260f09f805c2e8854dcc524189d 0070e82a1f3fa6158d15b7346dd56150faee5c98c9d07c996e01a06dc9b211b12ff62d60 a2d80373d1338f5b2f4cfcd8f69e2db5790888b270c88dc93aa491473d4234b75a4da671f64b49e673266601042400430dc525694a2c6f072f69f898625dea7fb50c88fcff7a13aa87c2361109cae06508a550c79cf458cad460be842fe0fc22 +a4a13e0bfa761b9bf37fade6570d41c161e20558874911ff3bee38e5649849b159beccf321c6bc7243f99c01a2fadbab9e157e9952ca65d8ea676c74fdc976d00501c626b8465c6cf0e4fd1a7d1260aea987161b821528b0b423e62ecc5193a0a49442b0c3e4ec9c4786a3a86b199c07dd3a17033d430d2c83c100f54e0a7c31 00b471bbc5f7a07996e370da4a09e71e2119ab3a562a273f079401951fbe4df39a4493da 93bc4504707de598c47f1298028828824baf731a036ce5ddeaefbeae224f77a1d7ddeed83db6139a4f153ebf043ffcdc01684484d9537799cc9d0ea107a146df43d3969e4c250f0b19a5e993a4218495ee883f41f26432f47b813a95200b1260 +7ceda7a7248640f7055309ae712c19d741375d6a7e0608e07f0135bb830dc3e8863ee9e7a75331a5e1bd38c42cdd484d4f45a26c2c1d4e05ce0d0ca941f4e94ecc6b371102f31633629e9861de558bcb6407d66eb91f1062ac0e0409db68b9f2855296a7f42fc92359a7dae16c73fd2dddea52bd866a4d501aedd8fe3b3ea733 03c65cf80bfb507dff52f9bf2f93df0642020d41619b3990009409e7210fd7130ac44ffe a5fa6f41ba929761be7026fd93252d3a3470c99ccf427e2d086288eca36447a92f0b26323baab57d940dc2195ff1165a018d1f8a8f9a115f4e34ad62f908a0aa92645e0d325fc1beba080a1d5fb29f42bea2304f59404ffb059f7521ee2489c6 +609815edfd58c0e26a4b06dded831d2f33466a130754b96d8d7c3b4d99fd4b0789ec719bc25338d0ae8c5880560c02687d352d77c291e406eae865c3b26d00f2e63dc644ce7e01d6e96ceeac8bc1eeb257d36cbb25d89b5fff6e30b6051506a0ae54cfaf6214f30985d54cab78f708029c1fc0175bc58e888db89dea8d300abc 00f4d33a9c7e6744ab3c441828bf0f1866ae1c042cc54abc754e3801263a96cbb3955dfc b04bd3d97b4dec105296d5c2ff62a5910788d61cbff9bb972dac9d79617a51c5a7aaaf73cdd2b143c63b29efe0f4a8ca15ba711dad5a3c718aa39978582ce8c1eb5a4daa61e93e5d9664f7593d168e0a8595c3366871079c6ea706bd3bd87765 +82d8ebba707b72655497320200ce719520c1ae7f46f38122958fd99322c25c9f4d4344bcb77a6658df0eece5df163412ecdca58475d56b0c2d14a0361e4cef458df146925d473a43692b15e9bbec550f1bde3444f2a5b2ecb55d2abd273ae999f16a32333529d94455e485ca4585e6b07bedbfc2bd1eb766abf0d28bdb1ae6ec 03a4824bdcea6a144d85f1b194431724cc49849b6cb949b4766d641ae95477d1ec3d1464 b495cb6f6fc5c67f181cfed758e4093553ec1e1de0a8fcc5e08bec7bd91cb2c05483038b12c0f31950ada55404586a7208a923fd3579aa00efd7d5c0549de46d8dd568ec822da2f6bb38bc1256657a014364189a19e436f251991a705591db23 +9c6fce18a6a96349b10c9f2f5f1505c8ab727a650b44bc0782a5f39fcb48b45fc7c1b82180d5f229b8abfc807071f931d333d265fc940c93fae7520d8d40ef59d7c6e3678c6a2ecde52b6a8827b1ffc6ed269cb9832feb20e593a7e3d4708309342875199eb2ffceba7ecd707b122516c815e83e27872eda812e3ea52ee3c4a8 027ba543ea785df1d53d4ae4c1bd0a3a994cddf0c25d2b4e8ff17ea7aa00619e858da1a5 a44873f9b5b1685362b30687abca43c6fb3f200183598e362bec33b0b08871a773f639370e90bc847a52c0dceb6d28371661813957c5410439d7ff0484757cc8f7f83efc3ff2f2f9ccfd08f128685800cd6c2d048bf6de0fb7a982635e6cac8f +5eac15a64c7653d125605869012b8f036804817aedacbb5a5248a595ee0c12329f91e8179c187192d3ed0d4ca2e202d8d4d9c93ad3f3ed931121c193af5b47a8a5dc39775b6c2d702708e5134f77a31bd62eaf87e39e6fd3f2b9f782c3057e162dd53b3addf92bf0ab99835c7f6649abd1c5322a1ebb2ba313df9464a74c14d3 00708d0907d14dcd5f40e2903e1e90e48a0ffaa6d4d9b84ca14df4e985c294f74eb9f2d2 a6067361e5792213a3c70ff491a9569775a7e5c26478deafbfb46b5659a528b1068e59e6c0cf3e281785b1475876d68908ee2b1e8b4b62ddc84cfbb7df7fc5ce2bcb33c47fc14d2d09743446c5fa80206a0feeeb36728fb7aa4fab49a0be07cd +df735a7e60bc267b18f313ad56bff830be5ef119baf43ce27c6368ff1dd89f010afd4f48740b11c12101c5903bfa71d6cb3d6462cf875bbd55a570ffedf3564088dfe8c8d3148231b78b5adaa6c53696737d4704daa59eab8d986fc6e519e81540f201e77b923a6a4af65d7173635b3b19b2023022186a7b8e869e1ed51717ab 021fb0a6b94080da8b8299b87457dc09d21bc430ba5f3359d92aacc1151be9941739567e 93a253f10bf1878f55de8671b306790b3b77c07e13bb65e07f06685be3d46e2c0623b60c5eac0eb25e430b9773392e471786a48a05e08384350463fb378d5883d170fbad5d42dfb467dfe1ee0eebabed20b7c8b88551b8dc0766d13cd360fb63 +bb107b0eeaf175a786a61db923bc6d51dad5e922e85e57536118e032167b197b1a1f62d9bbcde04922fde781665c1094181c16ac914cf6fbbfb27bb8346b2134f05c55a8c6b9b481273758e380666d6e22c28577c29446cecc5c3df9ed9f1be060ca55ab2b7fda36a147aeb46df0275bb923e0876b703452fab42f6b7ad2ceb0 02c80151f91301fb6b0c7685bd172f20515b46bf94dbc4160d0720fbaedd40ec00084447 96cad25267ee5f20032cf45bcec848aaa0660b2afbf9b6b9b7c7d80b5eb6842686c2782f67d2cc62c7c8a911739b5f9b133038a73f25d9966f41674b4daeefba38cb4f8e239788d3d51b5625b85e4c08dd2c1a018db97d76c482ce8fea487e42 +f47e49ae30b09b7666600b7a95e81b0afa1553da5e01fd917e4ce1b58dfaddb8dc8c03c0f5591f533610deb6a7bb5faf5dd1ec4103a587a1a4c58a110a706b0f301a5c408b3d984c210d5b4a0b347d2b5447271f25b527b3c7864f7cdfa735dfded47c63b723fa0f0413c57a24ffde9a95c35f743f892ab1ed1df704cde82d9c 01538abd7ce8a6028d01604b1b87db3aaf720e04220edf4d1d28c2d731aa25f509e58f2f a70f4da1665ee5bdd9759157726d29c932897544fcf003c0f82aad0825be266e31e3d9a5065041c8e902762c38c30e550b5eb7929a39f52dd0649d23744e13cdfe0ddc97987bd75e59871d82e9f7d5bfecda0622370264cad5231c947cdb71f9 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B283_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B283_blst new file mode 100644 index 000000000000..3ef6b97f87a3 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B283_blst @@ -0,0 +1,60 @@ +067f27bbcecbad85277fa3629da11a24b2f19ba1e65a69d827fad430346c9d102e1b4452d04147c8133acc1e268490cd342a54065a1bd6470aabbad42fbddc54a9a76c68aceba397cb350327c5e6f5a6df0b5b5560f04700d536b384dd4b412e74fd1b8f782611e9426bf8ca77b2448d9a9f415bcfee30dda1ccb49737994f2d 0299ff06e019b5f78a1aec39706b22213abb601bd62b9979bf9bc89fb702e724e3ada994 8265cecbc4475ee3f01e2234c44759af9ac5425c88ccddd0c2a7ea6d41c1bfe7f196d7a962dcc7c6ab0375f8e1d8551e058cbd896e59df64966633642cf053d0a7b3f90dc8553bf44ffdf9d28778389b2957cec11f873a2b1b25b6f1f849157f +44adcb7e2462247b44c59608cbe228ada574ecb9f6f38baf30e42b589fb9b157bb0560e5a2aa5523b71cc0d7f583b502bec45d9b8352f29ee1842f42a17a5b16136feaa2efa4a0ae306402940ecd6b71e57d1467c98e7960de2a97f88b43487e4f4016af1292381d70c18c7e6eed99a14cdeb5b3caf73688658e4c5b54c81e08 009c2804f8cab768248fb3fff8a055b3f4585c00de5c1615a19f9425b9432ea09afba8f2 80ffde882ff37c19e84e6fe9ad4f32e98338605204d9fd0f4712734fa21a456d66724ff2435735e2b9989f456841be4801a12b63e921167009ef29f24b449a1a1a285c12fa7e7497b7ed66089a7157e28143c6fbcee2de1a20da3888331cccb0 +cffee6252c7eb6d91d8fe100a1e62f0ad9f862d78ca2b747a6c17b8c9ea8980dc239b3b673310e6e7483582399163e39d889abc1a613fe77849ebc09b4f7f4fe0688b8a9869ae918a88294c7ee199be50ee9460db14725ae70b449d0cb48f30e7d817ec02c0cd586119341dba0b74f0279330807cfccc99c8c340b72c1764a45 02e625a6bc6d0ce7c06231de827068bdb0abc8ffb57c82b35ee3a0f873b9473905974d34 863256bc63f8a60dfab281771fc2ce762a0db98bb1749bdc2021ed651c1ef6d9673689c9fc13723f7070a141dd79253503a11c801614a0d8cf57e6f27fe6bb86d2ce01049eedc40fd69e3a0c1d3d81fad72f4603d0a4429c6b00f5aebddc320e +d058ab5dc07228253707ef224897ea0fcd09c3d5cc91fdce9e03c1c59c53fb4596be2ed929c7455e67ac7f4891aed3eb06ad88f2c4aaaabff045b959f900d1019d706b60526375851bb891494e99995928e4cd51c9616aa651ec77bd7e398916bb9ed3156391bf7fb1e29181e2b011dae2edaf803607def2ac6b194929a57f45 0376ac24e1b86f8a55c052d92a0bdc6472fa03acdcdbccbf7c321ec0ccd97aa0a66b4181 adb8a0270d6f8b7d97e34b4d5c8a9a01dcf1639be4bb7ccecdf64b29b2fb30e15e9fee091c96b89b90a45c8d33a59d9b009ec335e202d6f19761222001ede00b5a494ecfbec0cdc5480b652259940af23d57304a164ed5c9e38c546bb18ccce7 +c86f2cc7ab5df5cf1a236fd83792769474cef464032800ffe98a44cf29dbfb6f24088160eb31a11a382ff2a49f3e05e983462f5304272f96c0a002b69af3d233aebe867ee63fa46666760a6889d022c18645b491f8d71b6a3b6b4ef058e280cf625198715b64b025bf0449445d3dd7e1f27153926e617bd2c96638345431d1ed 02b50a6395fc02b9ac1841323de4520292f913519bc0d6a471aa28021322fc4dbcd7b802 88955f04b1a8edf95b78bac47a71fef6007588d41bccefef0b62792ef1cbcc38a7ca362541e6b4e5299c975ebf92cb2b0f10131dc5505fecd8654ccc76b045d273e0fd43afabd87d0d1a34cf69774f2b80d9b24511a574d2862b58eba20b2ad4 +c1328d8d2e5b6ffc850a9600bd6482518ddd9cee3fc9140febb72bcd444b0cd7e8074587d51b62cce4b3d4f34ad3355353fabe363369cf790db2df9fdac3a0ec4757e2dfb3b683eaa3e26531691ce765742e1c0bdc0e1028d347b6085fc459df0989c6a144271454eaffe413cae2ad7c8b2371fd2df1afffe56df727009765a2 024e5889722f6c35e18ca47effa9e415b1ba790066a91fb3c9f7b001ce28fc732b09bc23 837aeebcaee93188a5da32bf637f4e447c54fd153bad88e03fc4c02f27c293325dc2f151d4fa6b844a7b803240d683ed18d85b4ad00be2789e128f4f6377498d8579135d9e81ba770dc81f4867827baabb063727be921800f0a0e9a56c8b866a +7176b7013ea27e94281977eacb976bb31c753bf80fa09680a29128a6fc15234f79f0e9900aff3217ce9be72c378042c6c34fced0158740073d1a985fa25987fb218002e425868fda5a47de51abfd04de34e2b8634cebfbdc98e80f93d94096193eaa82dc8778fc23f3765c7acdad94fdaa272df0ff0f28190c10a462ee78ac92 0056d15b81f40b6378588a5efe43e21b95e18120d514bfdda0e7759a1d0766a8a35ce5ac b9f01626812b734f0e2975e096cea390d1a0f63d3714bfefa73dc4cdaa7ac2c257c0d22eeb73e9b70337aa2e10546454199379577cf9d5a8447793b7389b7dea96f852d26d5a6b9c3e5f5c6ffb0df87524a74d3d96c77d37019682e392024e11 +4c3642ba040a9955b9d50dcd1c936688c17c363854358afa8ca49c6abd906dfdc4d89bb4cab0bbc363fb5b74e1f004d4b09ec9dfeed4c0bfb482a9061a1f487a3d79195ff7b65a0504bced3a28db0ebe8fcf8ab1ee4a3ae91324d15d890ac4c479144dd5538d2e36d3a587769ee9cd2d5c6f85a03362a022fe0efc4a3902b71a 012fb2fb5bf5f7e42a500154823a174ba2d05af71e3b0cf47fab46e673ea1822f1563def 95c5970cd69d1fdcf5483f7b2d6cf84cd4329a21ab1cd4f31b760d9f730544d4b70747db11b36b763017e974a2e3874802edf0241de66f97db3e0481209260a4d13a2d70f897c9f2c2e43110ea8c7c90d8d007b47eb92a026db8c4b33a6bac21 +e471f39c18b081362adc7da47dec254dab8d765f005ac574640d78c14222639245563912d942f3be212ee3cef134407334c8fe3602fa0e1629de5331643d76715dc1b0ffcebd484d86c5211be4b285a31688b205fa988e6c15b36daf396ccdcc209c7dde2a732f5c31c84c7ea041408ebf15e56632583af0131bd7f531b5fc45 030096c54fd480647e017f8cdbbdef292e799f054e3279d228b09816a757566a744a8266 93746cdad56b693552505a5bd7e6331feb5096d3296ae5c99bcfdba63389dc55fcd02c5b3058bfed863d359d8b89165009f9b1d349153b323f8c5727ea64021fa01501909c902fc2c5f3a9cc92f7ebb1df5391752cc99da507486f3488735e4b +8a93fe53e83075c4025228540af7e96a588520da34e3eadeb99a4ab2f3dbbb8f85fe63a3b86c1f4ec912e665ca05b43e869985eae3791b91205afb1380e16c25b74e6793fa63e4a55dcf25dc22d03f09deddeb9042b620434111afe08c5657c7d754af66ad91a1b5423301b1e8e6389a1404060d1b6a99fe0f89598482979e42 00a1b7e9c8c2dc25b494b5ef3195b294e41cd3c2c35235ab42542bd3e2a52d5826662bf9 a7161aab960b93553a73ec6a84294ba9e86ecc185972dd68ecad9f863026c3c12ab2c7d0db3b7132cb2184b0391885520058f6b84e89d5a76fef804ef2f8a006f3ce1e2dc7da564c909c2802fa693fc2d788eafb1f4489f8a4b4acb6bacc774f +e193a8ef6f454ca1aed38bb67aca6d08280d421b196d89938c0582b7cde74dafd71716f3818940af412d4a7ff3960a8517aee108ae03576b68ee7557d35e6f1ab823d124de7243dd02b542591f62c80d822608572889573e4c9dc62f99d68e07800da6f83cb6f5e03d1f2ac15f90e38b4f25e0a75e354e4b60cc81c0bbe81d39 0059b1a8fb84530bba7a607ee88310e31bc6ea6a6881603567a1081a05a3a9ff87e719ef 91a55fea5e7e93a86ab89c2842b6daa76dec545405300c0611b1f85bdad3cf78df5fdea0068c095d19585bf6fe00608319e10b890259a08098f37591b34d8af2b478cde221130dd99dc945beadf86aac3cf60fb120ad91ea8341037439a9e8e5 +8a99b9db191f6cabc88b430bc2293e6774d5180f019d871839289e25aec29379f14606e742190b7aa062e3b29fe0254146d9614856c5140c7315015abb98ac00da2c7e33cbcc82c24b797366f12767322c4381454d9d1eeaedb616b0ea5c66d1422da459f18081f4f966d05ce279c6ee69b1bf94b8388d38d4b770d9ed69025f 030ddc2c7a4ce300cc2b75f0f977033f16c1f8bb13aae3d494c381f9a6dc8622499ae4df 880bb5d2becc46882b1c314d380c7bc1aa0ced770aa5f311e130ecd7b4cb984c6b2b640b903a4a3d4fca40420fbbd97103a27bb051bf0e230cae3dee6b833d2a1ed7440912e5dce580537435258bddb0cca4c5186bb013271126afcdec3f8c41 +5c437b331831530aa94623b1736f00b986172699f0a02a5e5df0008bf25341787e2e66046f2c929dfe0058c3cb89fc5bebbe1025bb1edd1ee31522ed568e7b5b4ca3991afdc76a68cbc2c4f81863e27fdaf6a564fab2c6354e5c657de81390f8a4132669fd24a48580c716b5b7961a9c091f614d11cf45dfdaec8946a54a11d8 007899928922fbfdb5407517725edf231d15a8b62d90b7fb6d8c8d20424850dc44f797ed b064878d68cd8dc497b7e6e94f92cff5a0a2dd637cda85905dfd6cabf7ab4634440fbf2c3e36a28e08669ded309d754f14fe074975934f14646e3e79ed497039b73282810c9a48d0f47044c85b2f3c0ab5e5b2fc86f9e5c9501143669d1e037d +91aa08567d8da4c90684dc06068f69deae240212842ff1786f04ec41b40d9187aa92c76401f9fcedced62876a34df82ad7c1e63b68bb2a972257ea8542bda6a7f1a020c9b122943b6d651abda8b8d322a8fb762eee376daa2d3637a71ed6c4f5cf96f61c0da2d6e1dda3370d80e51da2cbd8aef3267168c67359523faf910dfb 02a2af63d1171930758bd3e5bfdac62cca1a83a3b55a49b3f80cf0d9ee4b2082757beac0 8a9328c951ece62e9990cf373ae39ff950f50dccdb24226c4ef828499933799a20ba92cda9529c3f70a265faec0a25aa1636de485045a66c70c71d2794b61b45d194e9d378c1cca856008a2023dcb8cc9dd03669c3ba895b1c394e5ca099fcb1 +eb5297bf408c1a55e400a20a3c10acbc5c2bc6d6ccfcc0941fb7a6fd4d2834415a6df86c3a6c4b867d1215aeb8222153da8cbbb1576c92c07ca2c36d8f243fd911f9a057e39ee25832454e28d7ed52a8d04169b9b9677a16b32d5d211b8573a8986e9bf36d7206417ad2771daa11bc21fd7ee1029b65ff7c9b2705a6dc9cf9cb 035994e89e13916ad82608f74a639e6aceb756ff913aec440519946d6434af9a60a6af49 83af941e09bdb3899fb86a0fd235be1b144b1a30faf4c2adaa838895dec9efb71e6184403a5e220974e33da3a27bb4700455bc76052f302007eb84579304a58ae11d6894986a2dc95741d7228cfdc5f9da103d4eb80fc691a25cd82d5db34e8a +f415d0adcd533dd8318b94560f86732c262ad2c6dff9dc83e2435543f429a2158cd2fbab0d96c027f71008c4895ecc644c2ceaefa80937f6cc6338d15d36e459a16bd9387a361a6d800acfd834ad5aecf442e30b70f5bfa164747cf9f89325b80976052a83a5e896c00c54f81472b14329cf23bec10a8e693005de2a506ba83d 029639da33f48e4fb0d9efdf50bba550e739f0d2476385cba09d926e789191b6fb0a73ff a98b5cec762aae75a7e0ee9643446398ff4448f380172b0ca3aeecee9a70d1a3f1abdfb08902c3a11af8abb46fb56e070f7c8af2eb1e3e21ef9dd6bf21bfa71a8f0d4393111f1a0815f8df36fe5d74393290aa62262d5c4a2981b82753d5110b +b178d86c9335b85e02178fc4551769db589ab91d823fac219c7e14e2f029753b203962389476723832f8d9631dd7764e6dd35da290afa42a794476f5c7727b3688aced848dabc9954201578cc7b25801710931f45cba1199d3788d64dc0188412e70723fb25b8ecb6718358150c4037b5b81466dac1686cb5270bb1c72d34bb1 00583a7ecbf2a975a32d07428d27ac82e5dc13d1466c4fdfc1e6a05a8d9a289f1010617d a72d0defa6e774fdf4950d13b0fb57d58f761d4fe00fdb573bb2690bcef1940117490545de61a22f087894f8ce111fcc0c7950a536ca7b83e87f9bffd37676d1a0351924576485044549e8d707b6adf4e6c84b761bf1dde324cb8a4296663eb5 +c8bfe9fa7c848531aa2762d48c153cd091100858aa0d79f994fd0e31b495ec662209a9c8761cd1d40c3d8c4262cf4dc83c4a2549a5cd477726ab6268b4b94a78b1c4a7e700812872d7f41912a723dd9abc305420ea1e1fb1fee41bf643f3a24abd6e8fbf6fde2475e290527724a6f99fd75374bf7cb01b34d3e60d8db33c4de1 00f817ab1b49131fb9bbe8c112c25a36f064efa85de7506fb9cd29d81b326bf276277f7f 848ccd2d98328c37007a5f6dc79b937fe8f08870cbe19463e201a4cae2fad984e22960b6c5482e26be214e89815aee4705caafa5e7ed9983844d0d6637cb2ea3559a2bad41eb7664aaf50fe783395c9c227ad7e0b45499917f12c640770c6c6a +9a5f563d0f9fd1f31f3a822de628ae970954f4e71292492d727109036491c29e66b9b0f2c90c26abe94c08502f5e923a9ddaf6a7d91e9541ce90d0a49f03ce4e4769753d5b7d922e1ceaac4b4cfa4262732a09550aa076b8ff9d46a50fa17de17e3b6bd606698464d116fcd5f1ae11bf45b0c48d3b738427cb47b0d1272b03cc 02782af76ffebf3e2bfc0576b70e4f4bb87c762e2bb230d278ce776310a14f5b678f29af 930730b13737d8ac0fab22f6c11507c1d539bf9958fa6d7f968bbae6fa1261b54337a7849d0031ccdd2519b6f6414e270bc1bd33df67ccd85a11eb226bce913c69fe2641070677b76fb447a6af444cd52ffac0e76277e0a329cc7d51c2ef085e +3d6b065721da9de82cb33ec2c27107eb399b1e69ac8fa51145ed4147e20d72e27434104e76af988a3bc94f55e36677a05182fe2376dbe38195fc6a30673a4dca87336c7304f3f31d49216fbdfea00fd1e105d8b0c13ab11f8892e0045e915c17dfaab07b24ed21b06af5a8cad4f45fbee5a25bb6e87466a7bc422c0bb896440b 031b827b88f14d3822244809096157df3c0aa99da90c00cd9f0b18dfe306f6881834e6b6 8996e2539d18896dac734266b6b73b4fda3ce6a335cc203228b853f8a08f58a676d49f5e50d749ae49d72a8d51ca16bd1305c4a077830cde9a63de6a29b3a961b09b0b2570c95696a54957f5886c1ca12ede3ce3fdc00c6c59b41ac913dbf802 +d125f0e2e6135567adec9e77da2afc6862e28d618416632ced829d14ee8b61116da59dfb44098a40a0b927731125617e3d2f32cfbd1546a6e758c1ab6597e75db07add52ecb61d37da2e9ed04df95b36ac249f4cbd794cb561655cbbe4b34834c497b3d392d78ed0db8db683aff0076fb6e43acba3fa2b91210cc6cf3fa594b0 027da4916f1c471cff80bfa14d12aa10270fc3b26caed010c0111f6e5a40d914a3927763 b66ea99376b5cc54b60c76116c5ef62a15e0864a6955ad98d965a0ae08698049cbf41b7174c0951265111012f1fad7c110c7f3f511e706f3f0c18b90d6e307285215414f3f2baff623d8aeffe87421e0f7c08a217efe6b9119150aa1e9ffaf85 +b380f97687ba24d617a42df1b14e5506edc4b62dfec35ed9fd886bb769832cec7f9adae10c21b7cd9152588797b4efc6b2b30a873d3f25e683ea9be070dd69731949a51121e534fabfa3a2eae0ee90a454182248bedf2595cd47ad08614177d58f7a773f5023b538f5f568682c83fb60e3fb1aa859948d01bf7b214e7f2dc719 010608eb51dc0ee97d6e488a23c582ecf0ea1df9a24db77094d87b3fb6ca98507280a934 825036e584150492293c42002da0378559293e33640f412e980688ce37ca25920f7c4c2c8f0bf1e95be23ea1d7d8665b05e96cd5afcc42e12c52daf3389503e7545a5b812a8dc6742dc928805241485028cc0a966ceb4625a30e10025e502d9c +3f9ec57e4228e1a6ec49df02c58d756515305e48763ba1dc67298be9a1548576c28c82b4e9b3f62357d9b3c522b16d5c496a39effbdc8290edd2cadc0019e6b9fae1e61238b13b6265ad2ff413a5a0684babdb0013e7632051455e6fd943815213c555dba96cba8911e006bfddec6c3353065004538f37e48df9e339498d85c6 0123f9eb8babed548df08cc3afc1d3b3bbed52b538d4654f2088fe76062fbea75b85a560 808057e88b1c15771136da48e990632e629dcdb97fc4b0b2f36298cd1f1a49923154e72ce21e80bc2b07df10a5a51ad617289c8a71684672d46927042a140a908a501317da8d48d60ac775f06a62fb8ad626cd98bac40edb01b337c74f62a34c +bdbd7b7bf3337bd9d21a3c6db379f95408c17e49dd394e94737ceae889f45dc0ff5d48cadc53703a16b5589939506b548f8dfd34c577c084f372166cbea320c8fd07c809b211e0749ea639e68f890affa1569b66bd763c7c710989e491011371eb1d93ed9479ff0216b7f79c901a2023e2cf80b565d1c0517e73117190cd2f02 006a18e626452111922e02e31d662f4301319946a204ae8a34f06b91dd1b5b96456365e3 a156ebfc1eeec99bab22c7cd5980cb6288148f3304725ca5ca7ce28f538184d9ba70057ea252823e634bcaf716ee5f510e073bcb2ab8f364fab89df22383523592ff63ff4d6e2308b238e479c6ec40a4a2c550c46aad43fed82e86b5a55cac75 +436b288512ea57bc24f84fdd117da9dc1858bae8c11637f99295d88fa9d05e3c053a2584a6fe200ad190b3077d9a1608f660349dda405066c1562f6897ef69b6b674d6bc11fa470d0b96a7cf8f6e098c9ac03b0ef415aa045867ac7c11d16cee78ecf08850ccabf70f761682b561d0d0e4a889d840dc74932648ca2fb58259f7 03307fd717015b12a2dc76ada21442ac1d97519f66898b214c2ea317ab0f0905e819e4e9 88663c4bfe11df568e084afda18d78cdc7b0f67f958d32b2fe2f3553ff538a05c6c8c0098c328758ec63742ed02ed607181ec2e0d3425907fc27015bb558525d17d7133ec287c44e3e5afeb5dd21bc5cf09cf1fb3c47570035a8bac860c97d74 +672faa156dc188bf16bf8933d65e091c633f294486049ce96a4a403dca28a149f4f840e8bef47412285363e9e89006614b013a41baad9885f1d9980cc897ffbd5f8a7d0e63feaeb42c07776efb307ed680ba1cebf470dd9bd8a2a9efc2b1daa569524394f9a50398add1a5bd2f7c263f9e63c2d49461acf98444fd23341ce78d 014f9f412e3c7d770626e800d43cfcbba3ae6aec8563af748e8a97b67d244334b6e6d2b3 b37b8f3586c522c1787517e468d299ce67215cfb320acc5a91a9bedece394e934ac2cad649fd18a3d21ba080de09c09419adab90442057e49b44e80343d1234414ec5c86763113fd61d7f6941ff4547decf521640a50e1ee553157f5d7145aa5 +4321334cc8ee44f1cb392a4b280a95561809dd3639ddf43b6e11cb73067597988d95b8643d86c76c3c6b932d9262b9b8b55a04fba0666dd8b8ff1e8fdf799ae3945b6e30d3af3966f1a6d634d5e012710d66cb447fc3375130968a2e1e647780aada2609d87247c90338dd71c3bcc3902311caba27d5d4ea4d73ccea960d4bfa 03091a6a8bdac1e43542dce752694972e734dca31c061c7d1000754296d0748055db3f09 94c4ff4c4b666054fa52241e4ba24d5a24777bbc166bda8bc9a1d33298e9d01930b8f6e289ec26973fb6758a8ce60a6a15e1f5621f03a6f6be897af791eaafbca40bcf44c7634a6cc6fd06bdb2f9878bde1a9267d8f9a648862d4938c6d245c3 +2087e22094570d39fa937f15a3ef0601709a66666344186a33b487d041793fbb9709a95af250b1df0762ea98e911aeb3ff1fa19f0aca53fd4179e454e0e91636e55cc5b17cad9e1575c82ad265dc34c4a66b7a31ecb9ef9dc756f2ac1d9dab35369a6bad4a0f47e629daab91addc6d297d1e5d81477b3966d8c3b607ed194d88 01195921b91353db9bcd00510efffe009c94f6bd8d790f5fb3e5a0101c9ca5d21c6ef2eb b189415bf2342a174d408c238522a0430c02ef5bc11cae5d25cc93fc4c6b35be65cbcc87f4f196dd34513c5da0a94514013b4cdabe5f9357ec03dc8cebb1737d1c474f51bf01fe2a7538e3a73e124f270eddac096006728a6e9466f3a59572df +15c7bca449a73b03bbfa783f5a91ca0b7916889a5d99d541e2e8593c3b176a5b634ba20b34407fbd94ae1c1398f5313cab7402f3bcd7ad277a8c66d09a6df5dd086b20a0a3823fbbb80980cd86bd13e527eee15656cc977103e80113539e26695addd9eef6a1f56986168d9a53f8b5de833f8962c3826cca106ae9e8c00208d2 029dc20446e9abacb43823e12a83737b46e6e577466b5a3925e0f9d496824dadb4d4b50c a05603294a20ceebec092ab10d429fc8be77a74d8ba0492e85fb307942f60d3e415b6a2de263fa8cb1df445e540332560246f12d01decd6d63acdeb45a8f5272eae215c3b07cd90d651bdfb6fa51572b0602b29deea8dd1c4649d884838008f5 +d12fbb82ee7a57eaf76b63fd6bc6c0a65c85f135f019d43ff7bc295cad15d53729d904fed63d69d3ffe8b82c0ebaf0399e2717ece40e011f710b5db46aa457c23b85545953398b814816a1e7a8ab5b0b14c4a0451b0bda9d0d2ec4a374bcaae208b7fe8056bfa17d6b7ffd4ba2e9179f49b9cd781b0c06f6ce3eec26cd428cb6 03b9b77d19a42e9a555da8ab70aa5638890b2ed21daefa28ca6323fc658662dabcbfaf52 ac79b8d3dccff152c04d8e7fc96dd454e98e63eabf5ea24c9d60c4001b04d0c1848e80bae4ed3b58b707ec2335729a60115ba2ef32ab7be6fabecccbd3560e9fcf41311207d11900684ef54e83e956905d94dcc581d3b39c8896c517b1fdbd4d +eab0a37915c6b43b0d1e3ef92e6317b3afc8b8301b22f6059da8271fc5fe0e419ca6097daba213915855631af64e10d8382d70599d903d1535e25cbf74da3a12ba2f13c33a8562e0db03edce791f1d39af8850fd1feff0eb25f9ad0a86dfab627b96e65831bffc5f6d9693d20493bc9dd6eb3e9325dea50b055768e8aa30d49c 00b9f8f3e89e9c1ef835390612bfe26d714e878c1c864f0a50190e5d2281081c5083923b 87ed8fc8fd09fdee49443df152236d8db11b01359fd59fbf6e8b9d5e9bf986060243d208bb94897e68a19f64204482c101ed90f525242022dfcda5e4791cef35b6f0db71aec2a1de216a9f45f0cf3b0a8e1b1028efe1a65daf985984a4ae2370 +fdb93afd5dd1e3eaf72c7ea9a6cddb07fc2054499ffe152cb2870163eee71ace5bd420b898cb4fa80ea53fbbaece2a1eef6427b632320e9c97e38acb16b62fdbf6585b54fabf0a703307ca50f86387bed1815a05b0c8991e0743d10cdf49c8facfd7ddeb8d4a7b706b5a29e1d00ac88b0ee88b3153185495ac8388cc70104154 03a30a1c15b9ed71e102341f97c223a9b5ea3e6a335861c3cf407ef691a18cc639dbe74c ac12adb098cf76b13e7a1bc7511d45cdbbcac20f82b96d890fee150390a4aa04fa8353f7dce7276a1c82bfe70699f7e213eec7bd3a1bf06de9f6afa345cecbe67539e78e7fe1542cda7eea551e2a24ee7206238fa24a365daf3b09c06955781f +c78e35d1a5b1bbb0ec21e7ba7b7c74c859d88f3e100e40ae34128cf093885dae4e87cd09f3239dd8e79e25305220880dd352a650225d9bd193b9b84e488c458b0b5fde1af941c0c9fdf952d2fa41f665918dccae27ab7923da4710f8c27ac8ed424992568dd6f0a6c3ecead21650ed162e0292104eef3c2d8551be866a88d279 0083330123cc64c11888c1fd388629d0b329a50ef31a476b909a182c930ff02d0c389b93 ab19023561566bd5151264e0e5f97b91c5355fdfe88698189e829c59c0f2372b95cb2830ed288d6c401de7fe2be4c4390c23bb4fea90e37ad9b910ba2d2b36e64495ea5cc3e31258393d3fefef535454766745621ea386b7a93bb2ccf477d902 +e05435f695997229cce314e50065f3c5f71981988dddccaae6efb81f936b22cb48813f506d1edf5ebd69b0be34f278592c5935f0f6db0cca1ef9d62834fbf3c4c03f4da0596cb4d67b7b767e85dde7b7c6fbef7d89babe6f97b876b33594a9e36ab87079861ee556fb03274ad4af527342a4794192b8933f28c6220f954c77de 01dc2b656c207eabc9e0d6272099babca8d149c9c4258b779c2f06de75f76d77505271c0 88b3d3556c08aff6d1d46f5e7b291f758f7c9d394073946d1e9a57ae7f51bfa2fa5b5c7ee6c8261e4086491922dabcbe08134af5f2734e4b83fa709aeb952e63917d3442a8e663b6c86a49a80b5ba641767cc8558da000627027a567694a4604 +0f9f36477076c4b5a7d1ceb314a397fb14646695b0803e36e98908c8a978770269f165a1fed8f4b655d4efd6ad283d7f5d51b6e1e302d360e8ebf4e887c7523a757ffd55384e114bbfc6b7a0ec8511079507b919065ca018573418f9e394854c5704227772161707b4d0246ebceb91192f0eb2ea994ce61fd98a6d14cc8246c5 00081772348ff2d7a3fd57fe703555ab2e14f5d203c4cf0292f944e827e884d95f3b1d83 a5121bd9c4777190ccbb810a648e9da19eaf352e2bd2b296cbc4c2b6b37cfcbe011930b75cc33ea383205a4dc965362719cd1791527d2972df6745a19b72d6c2be15b10a8c6e817e05c6b82deb4d8adc20aa22fded793d9d8bc98c3500b336b9 +1d38b1c342b6611dbaf412a66c1c0b8397692755f576df33b31c2bd12b7f0707cc423376391f7b00aa4e7b7fe54532e2b39c3c5284b9c8ccce48eaf9308ed338992f1d4ecde6cbe352e46339d7d602942158387881d9b493fd40cc59d4f9b53ee4191d42352c6f7bf32c331f0c5afbd44a92901a4b713c7cf6ccddf7de4cc6e4 01eb6bf2ca1b5ffe6f6a795733eaeed12de6e87c53571e702635b9dbd0d96b47df4a005b a117eb9570cba8a1bd18753ddabc9fd2675fc16879a6eee0b0fc2eaf29c26bc69c3bbcf1073af6e620635403bdd6a3de0ecc506a736aed2a9ead58035861aa9aafff97d768c11a8518b75b941da50839a03b2f24f8b7d6afa794d086b85b095e +3353ad05ef90e9762bcfedd6ef44a1e8ea0392ebef30cffd48ae620f3e567e1cd44882d514e7c6759200d4bcab18afd3038c3d3f8c50f7bba32a04eee5a4b1cfb8c349939e4efe0a46fd047d02ed000d8fa1b98b0af5586f120d9ad174b3aea33905b979ece1eb3660b1e070c8821b32df41904ad68bbd8ed247aabd94066f16 03b2a3e65e5a306bf8e3955b60e856dfa9bf68c1275a678ca056207a0ec67c96eb3f8309 a2ed9553f68a420c3573c5ab2fdbc4f2ee5910d62d067aed0d4c7af4e602d52d9c86c1e6e097b2889aa396112c43826407ebae703ddcd51eabecbaea272039349c3fb355ffecb1bfdd7d117b2bff988120fd60b5417bf5164c2d0d838fd66082 +e7ec162185fe9a5803c6b03d98041422315ccdac67e48fbd07a1ef3c5661158710abc6791bd0a75d56791b4ac0e7695d53c5989d9fa6a3b037583b2a80d2b154b024f1c36b63548be9afe1d51f2f68b2ba94d4ca1e69a35ac10e15ba72242aac20f7526b12ff9d3cde9a9bfd70d55adf9bd92c66d092d7d08e9764c84bf7f329 01fd4d1af0bb7c79ed5fea7bb45574e46534387bd916649485ef15207352d7302e81dc01 92201a426b189f53fc243ae754c9dfc95ccbaa20248528db2075304f6d144407bcaf8f60f6c0945acbb44bea9caf9b820b1f1bf7cc77aeec4898928ff4e7a983451b74d3a331de07c758864d0328a51e745a89a6115e6a7c269096582a45fa63 +87c8f2e3f4fdebce0ca9300fc1ebcaa934f51a12b6b8f2cb6bb6eb77965468663044afeb2a1334cb5a81e74b8427267f8b34b5e9ff0cf157a9f18be2b1942e32ca61dc23ea13c3f9fcfa16df8fe05e067938b6994982676463fb12842d4ec532cb904cf222aa805dd0d86ab9a33a83e294c6d81e8dfa273835e62e9041dc8ff6 020380b1136b5283e9b7f54b7535ebda33b129ceb177bf5d3d07b1daed5edd9fb3862530 820174752645abd3a821cc0f9faf2f4722c687738cd52e372d264d1b01c7bee98abc5587fe1407ecd0e8e15ace387f2f136346d3c631c7c24a0cce7a106375a36edd06fd26a7d9b2a4980be18cee8c9ad737bded94d7cbd1b9d8d87e7c039f50 +2ac53e8a50c4afe3b38904255b7cbf150c5f79dc15932dc0ac9aa631521f68a0d4b6bc5a04d55c99a36531fd4886a23a8d99f262ecd2a9feea925d7a96ebe9b6979a207b7f9378afbe404fc8e959b0333572a2c911f8743c0ba64eebc7ef12fe5435d2cb0e5091ae518b6e4233489efe3c16c6f21abf4e2c6808b733914e5a7d 019f815b98836948e0a0dc9c30828c31b13e175f1e79f23d084ae1bbe64823f4866214b5 adbeaf85ead7411c03cd4eb4522a6ff0aaf191615806097593f377d8317a5d034b4ff89f08b17e8ad85c23ed1193c65d03f65a9540dff0d31477c7840faa830caf1d28755d8d3ed8d8c64fa84a660dce996bc38a1456575608b82aefa0ea38e9 +0b201469cac4c078f587edecdcdb6efd5752cb4a3f43ab540463c4d908c27527aa3592f2f9acad85dd94a3c056bd28618317ebdf2e7dd6c5ad26fa3c31dd8e5c50c60418d91c93bcbb59ec1adb1db791f485ded78a5cdcddd23dd1cfa4f13443468d8a5f2d648059b9c4470d0f4fe7733d56a28a2c24456b6923703ef32cf0b8 001854e954654e726cf4bebc0e5a840e8809fd716059211c6ffeaed36829808363164684 a9f2a42feff19cb38e5adcc1c6ec5815ee273b9b55812f2b19272887cec1eaed2c2aae2f890cf02133b30692f6a3d79e0d2e0d86cd6b540d9a7c6e2345d478f65460efa04371e25df7f02851c9f7acc08332b133468b1fdf25bf4dd01236f503 +fc5e4dddf4c4a328b685035ee79069770fbebcc56c14e31afb4bbcdd5220e025f31eba794fd6c05e64f19678dab33ce4f084bc32790392f14bf35669d75b6466b4214ec30d58ca90ae285c9058f5804a1fc9d7a995958f2a0e84ee52e8a78b601bec04ab607ffc2091749cc548c6754ed14e2e5f92315bdacaa7a12823ef76bf 03548f8020819588b3202f4c1ac62eaec6a47c2a19b2900c5a3cf5b4ba5804231141c647 84d1c32120943ebd44b724166917a5d53365e8c992b22635c5c33fac3139cc8bba9a67f4c1b1686d65586ea1d235c24203c951ee202c81a46a527cb9336048f64a093e63764292563c099171c12b88cbae956395ee7320395a740dac121b45be +284cad790e6207e451a6a469cee3befc3ec43e047cf91b9dff1485718aa29de36a43f7c51eacd8589f0c3a96ec18e8ccfa92941b50b2132e3612d5b45e16f60d411d1c53e373e1ba451352e28970ada9dcb9802102518a385dc571dcf6900971b00346098a58042e0d1d129bd6801fa640a895a458a45b31318fe63ebb30c6e3 03cc4505005c41142308f1489226b7b542e2e7f24f1d3089ff6b92a4b0013f490ad52e60 b1d00d57005359b98038e89d885528110fd059093dbcf623ed13663f97111a33a98678f5b105872766a6659167834041055ed6658e69b87ae98ae92b314be7bcaf3692092c34022ca4f4c933356d3b0ca8794ddb99993315ca716c87529da80c +6d46e57abea9d115deda48b69fe8e0b36144df2f6a659509ce1b514c8cc4769d46e5f71df2a084f1db4a22fdd3ef0c2f90394f2898ce291b9f279c0664aa01419f5f6bee1fc1299871b27ecd57a5ac548f99d01871b8c238a6b46044c953b2e78e22346a0c7663af4db62799038ffb5c21ee512e26d01e70a4ed967377ab8405 0144a2fc8e0aa63506e14e4307df36416f963dd9da78655832f5b991af8c3eb97df78efc afab87379f4afe75f26ee749ff76317d2bc445d8d54bc738898e8020a985826de4ad0dbe0e333ce0c7563ca73e6b1f0c07d85b78d1f67befd5787671d37405f5763b3eaaf95c91c99bcea6cfc8bf101263eafd7dd51da0f07802c7ddc7eca129 +dd750b39bd8753f4e473c4484e2b36ce2da7576813ebe05861c339ffae1d029bc793173ed394091c00685ad82f0550cb21ed1c68f0c27cb7396922239cfb886647af204e88a9101b7453a8ab662e270b87a8a13f2fe61d695597382cabeb781933bebfd7d0dcd33f77266e43e32d937f2dc89f67525e522977ce73e9ad36c8e1 024ffeaf139043ff25a395e4c560c7680c1c2155191378917eb25194136b4a69597dc277 832290765defd7104122e22ef76844296e30ecba5b8e50697e226d881a3972f645972dfe1c24fceea298dd5f86c6e77112567deba0311f065be1dec7a76ea1d95d2b0e47b42f6a32f60b3e468fe4fa9a64c081cd1fc8d9defeebb173f0efeedf +4736e59fe5812f63737eed57a570182c065538abd9fb0a1c9c2059199e7052ba57d84b5fa1cda2ad9f216610361ce1dfb9334816b6bea509283756a03aaae2e5b0597f492d078b6b015a40c9785dcc5d2ae266176980db04f5cffef40e16661a50ef871c5f531d73fd5d114fa19bae9dd2da4267a131fc31849da38c2b78d1af 01d1f2e0f044a416e1087d645f60c53cb67be2efe7944b29ac832142f13d39b08ac52931 993f07acd0ea45823e8d5229a203d3491097c00d6f895575b978e4abe23d9a8b17864a7b26867dbbe371d15c969ea8690042934ec0bd1496cda06e924b95b7f1c232359b1af4be5c2fd18e59090013b1285c6635fd7b770ed666660da3977519 +e573fa7d4bf5a5601e320130de91f4ad87eb7ca6b8998488afcef69c215b0cccd221b8b66eb0af9d699af9ad6c4b4a580e82941f31e4c0a9bd83995dd076c5ac9bebb34481061e7cb1b26f6e8c6b26ee4bdf9887f7ae2eb9fad3115a21dcc96acce85d23a040c0ebbe0a56e75714dbfa803d6e279b2f4280bcb993f96ba321e1 01337362609df74d25f7adee382225e6a04dd6ee4c6b45fa31499ce9edb0ec046325caf9 a8b93c8d6ffe8daa4aa14030034a04dea32a60fca7b0aa0236bcb9c3cd6ed78d928d404e19118ff8d3dcd00cae3bd6a305c5892b87f49dc3d376e2669d02cdc5ab4c15b42443ce5de04490d323ac52867d0f262ad1afa4ad6d763ed3b5449274 +7862864d0d78b44e2a28af44a0a16d8e9b1b8c4b794db0410c0a863ba011018ef43e1e11f2fcda2f56fdb2a69cc817df425c9cb3b458922ba00d710190cae16d61af3c304a42fbb3d0c4a74a297253fccd70aca414865b41f68b01c561be281265fa89f63f975d3101334886e85929a5a47fa8dc459b663548faf8ed7484958d 01be00aa0afdfe92e24a2536594d4b41701ad4dfb223aab35ff49310bdba7566057fe8ac 96812326c8799655ec55f44ebe618ec22b403af8afbb7fdb50392938416571337d613d0328ea0f96a2796819fa02429919b072f33a16d662fc02c49483a12d009d3f69a544747c23c597ca7c98ed499d96c93f8aede542045536fd1ea0552e82 +e73c96d1a84cf7cc96065b3c6a45db9531cd86a397e434072a38d5eeb9a90f62bf5d20bae22b926cfe967647d2bbb5dd1f59d6d58183f2cf8d06f4ac002ead026409ca6a1f868b406c84ff8887d737f65f9664f94801b2cd1f11aec336c0dbd4ec236d1cc4fc257489dc9709dfa64eae3653ac66ab32344936c03eeb06d5852d 012ad0aa248db4fbc649f503e93f86104cb705d88c58e01d3ae0099590a69aa006aa7efb a3b4c24a860e004f71beabbbf59c0a4394d584f4b34964d53378ffe33ecdd6468d59e7b1332aa6cd4c14251e89b0210612b6e9c9200babd3c88914252f8376e74b5cbaf8ef5d6ab00e99637e13a5ce6b2286fe223316dd02b0bd0214fd04db0b +a73fb0aaec838d011110d49c5e94395ce07408917bacf7689d2cfe0948c582214b263c6b80e0a55f1e159086817605723740569eeaa1bae96b979679165c5c35ef2142525e943e595e6b4b160acd7ebe41de19775346363f779b1f80b6d5f0785b92a648028e456af8496102d19dc6526247a654bdae3368f075fa9ee92b2f4a 02cfbb8f340cae8e2e2322829148981cd9e509b0c65497fd8d9da5dee9dcfd39b0f7556c aa8cba761245b092f64d09bc905d26777d5b7d83baea7018f31e21034a053b25b9d3e9d7eeeaece0092a4633024580dd0592203ccdf65a9f6903c66e4a20237eecb4fcbc49b674aba10a1ba7b17d59d29a5ebab1549097bec1558cc12d914e9f +eda775984c7c9f7db47af30dab314d070fb77e9b623baa6b73e2cbda800f167b20fdc2e7219391efacf908f4ceed9b9b6bd3541b52ea087177e18c97391214758cf6455311fad336ab56cfdce57a18add8cf85b0a0bd6fa7297dbaa34bfc8585b0f06a0aae055186658c227e19cddb65de88d260f09f805c2e8854dcc524189d 0070e82a1f3fa6158d15b7346dd56150faee5c98c9d07c996e01a06dc9b211b12ff62d60 8414cfe7e64f05b56052ae559b461d495709d80c43bde4ca555fd5a9c57b43c2b33c306aeb32da740aa56d510988725b0e10260ee03e3c7b3e4c020f7b361e4f0889207dea7171731e37a014b63666033cc3b47b1ffcd3129a45fcbd81e6f4ba +a4a13e0bfa761b9bf37fade6570d41c161e20558874911ff3bee38e5649849b159beccf321c6bc7243f99c01a2fadbab9e157e9952ca65d8ea676c74fdc976d00501c626b8465c6cf0e4fd1a7d1260aea987161b821528b0b423e62ecc5193a0a49442b0c3e4ec9c4786a3a86b199c07dd3a17033d430d2c83c100f54e0a7c31 00b471bbc5f7a07996e370da4a09e71e2119ab3a562a273f079401951fbe4df39a4493da b109584abe22fdd2fd02857cb3567b4d2155bb40105a1681930a0ffe01ac3fbef70834dbe4c4fcacc27f3461328155db02cbeae03edd05433061011a4c0b8ad6895127d0e4ddc1837eef47cecb42c8a8c33c119d91c1394d08269514f01c0568 +7ceda7a7248640f7055309ae712c19d741375d6a7e0608e07f0135bb830dc3e8863ee9e7a75331a5e1bd38c42cdd484d4f45a26c2c1d4e05ce0d0ca941f4e94ecc6b371102f31633629e9861de558bcb6407d66eb91f1062ac0e0409db68b9f2855296a7f42fc92359a7dae16c73fd2dddea52bd866a4d501aedd8fe3b3ea733 03c65cf80bfb507dff52f9bf2f93df0642020d41619b3990009409e7210fd7130ac44ffe b6d7123996de784aa09c2d962eef666d18ca561b732d2b2653a65d816bc3c9e8c04533fdc40141c84031a5a98701505d17b92042c936a1bb088df8d2cebdcd2273aecf1668fade51bfdfd8bb5916162f92f4520969eb8902e7eab9f64570c4ca +609815edfd58c0e26a4b06dded831d2f33466a130754b96d8d7c3b4d99fd4b0789ec719bc25338d0ae8c5880560c02687d352d77c291e406eae865c3b26d00f2e63dc644ce7e01d6e96ceeac8bc1eeb257d36cbb25d89b5fff6e30b6051506a0ae54cfaf6214f30985d54cab78f708029c1fc0175bc58e888db89dea8d300abc 00f4d33a9c7e6744ab3c441828bf0f1866ae1c042cc54abc754e3801263a96cbb3955dfc b2c49e7801dce85b46cffd266f0c2e7df4f93ba6f9bcc51c4363b5ed39058239cc6e92b65dd692441d0007793bddb28708a56fe60c29d611f88d8e5abd348ac9d188729ece13d2b468555bdeaf07785024928be767fbdb1b4541b86d3ff82b82 +82d8ebba707b72655497320200ce719520c1ae7f46f38122958fd99322c25c9f4d4344bcb77a6658df0eece5df163412ecdca58475d56b0c2d14a0361e4cef458df146925d473a43692b15e9bbec550f1bde3444f2a5b2ecb55d2abd273ae999f16a32333529d94455e485ca4585e6b07bedbfc2bd1eb766abf0d28bdb1ae6ec 03a4824bdcea6a144d85f1b194431724cc49849b6cb949b4766d641ae95477d1ec3d1464 901aaf344a7686665b48bce5e10b757351838ef5d0f207cd9f745507e9d1f1a010ad2c60ad94edf66ca5d26a338ce61806a414a02a23f63300c4206134aed5b4cea2f43461e7ae02801630b5f230709bbb8551a6a8429faedf9c6c9e9e41bb04 +9c6fce18a6a96349b10c9f2f5f1505c8ab727a650b44bc0782a5f39fcb48b45fc7c1b82180d5f229b8abfc807071f931d333d265fc940c93fae7520d8d40ef59d7c6e3678c6a2ecde52b6a8827b1ffc6ed269cb9832feb20e593a7e3d4708309342875199eb2ffceba7ecd707b122516c815e83e27872eda812e3ea52ee3c4a8 027ba543ea785df1d53d4ae4c1bd0a3a994cddf0c25d2b4e8ff17ea7aa00619e858da1a5 94e2e8ac098986cbbe9439d6434adf6439f37033b70aa8c0834395e1c9fc9b819e1dbeb0a4fba9757508aa748bc67c9c0716f89050d395c645b5f6fb29d02647bdeebc3a27ec466c4814244bb77dae329b16032d3d31ff8dba8dd0882d8dd9dc +5eac15a64c7653d125605869012b8f036804817aedacbb5a5248a595ee0c12329f91e8179c187192d3ed0d4ca2e202d8d4d9c93ad3f3ed931121c193af5b47a8a5dc39775b6c2d702708e5134f77a31bd62eaf87e39e6fd3f2b9f782c3057e162dd53b3addf92bf0ab99835c7f6649abd1c5322a1ebb2ba313df9464a74c14d3 00708d0907d14dcd5f40e2903e1e90e48a0ffaa6d4d9b84ca14df4e985c294f74eb9f2d2 8284e3d694ab5a8f473b72ff088f05e5deb028ab6a1bce9855bc1dc9880f4a295c79a4c4510137c95025c14351ade2fb0e2cf5612fc8393fb457880d9a08fe835de25d15f17e8b8d137b5ca17af00bfb9afb2d32364050d03a94b2d354310f3b +df735a7e60bc267b18f313ad56bff830be5ef119baf43ce27c6368ff1dd89f010afd4f48740b11c12101c5903bfa71d6cb3d6462cf875bbd55a570ffedf3564088dfe8c8d3148231b78b5adaa6c53696737d4704daa59eab8d986fc6e519e81540f201e77b923a6a4af65d7173635b3b19b2023022186a7b8e869e1ed51717ab 021fb0a6b94080da8b8299b87457dc09d21bc430ba5f3359d92aacc1151be9941739567e b7cfe8b4b2fd064d81e2d8dd68b170fe65cfb5e14b63aa6b20a92daeb492c146d12e0c0fc9eb061a326a4aa945df94bf0e5daa73a87f8271b4d429dc10859ebd3e98fa04e9f07893705f21f90bd642b50496fee8f1bb9e7c59c4ae486c4f66c5 +bb107b0eeaf175a786a61db923bc6d51dad5e922e85e57536118e032167b197b1a1f62d9bbcde04922fde781665c1094181c16ac914cf6fbbfb27bb8346b2134f05c55a8c6b9b481273758e380666d6e22c28577c29446cecc5c3df9ed9f1be060ca55ab2b7fda36a147aeb46df0275bb923e0876b703452fab42f6b7ad2ceb0 02c80151f91301fb6b0c7685bd172f20515b46bf94dbc4160d0720fbaedd40ec00084447 94461b6568c826044f58c94ea2c2d37c597449bf8d782905f4cc711af1e0843d829b6228b07e22326215c0a4eece8da6034eb980a2148230b6c5300940bd75ebe550fd6ab92ccf32030b68873ff56de348b34a7ebbe0689791278b2beed6b6ec +f47e49ae30b09b7666600b7a95e81b0afa1553da5e01fd917e4ce1b58dfaddb8dc8c03c0f5591f533610deb6a7bb5faf5dd1ec4103a587a1a4c58a110a706b0f301a5c408b3d984c210d5b4a0b347d2b5447271f25b527b3c7864f7cdfa735dfded47c63b723fa0f0413c57a24ffde9a95c35f743f892ab1ed1df704cde82d9c 01538abd7ce8a6028d01604b1b87db3aaf720e04220edf4d1d28c2d731aa25f509e58f2f 8b6bd2528badfe655e0f907516ee81330fba0c658c5636e6222b06c4293dd0280a6b80f74ddb7fec2c16c92e70d7d2b20e9dbc9cc0e71c245bee32d180ab80454f7e91a148d732050ae8a59e4d30f05566abaa581bd31b3d19bbbca44a1a7b6e diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B409 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B409 new file mode 100644 index 000000000000..ba4f070621e7 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B409 @@ -0,0 +1,60 @@ +f2380acb0d869d1cf2e25a6bd46ebe49d1c9270624c5507be4299fe773749596d07d10f7c2be1c0b27e86f27b4a6f8dff68cfe5c0b4c58dad1b4ebec7bd00ab195fdd635d9fa8a15acf81816868d737b8922379648ed70022b98c388ede5355e4d50e6bc9ec57737d8843fabda78054e92777c4b90466a5af35dd79e5d7a81ce 00beb0df3b0e05a4b5cf67abef2b1827f5f3ada4a0e6c3f23d698f15a3176cb40e85bf741c9fbc78c9e207fa7302657527fd92fb b6447d755280963752070e0743f6af17f5358c7a68ef2f2f14b56cc2c634e1980ea172d6ef9c9a9d0334cab0487e7e9c0f4bf1ac572639d5be2d9829284c2772550b8bbe3bde2a172ddabcf4ac521301da17f1f0db6996719d68a009ead2c480 +22a97fc0a9694dabc6f274ab52eb592dbbe8beeb646ebe6cef60eff341a13017eef980aba6d24ab3afd976e2f6a84cf652654d4a54a36b2f2f62fab8858f8b0479a48fe9f47f8fd5a4a1f3141a91cbca186507b2bbfef5e4c4d2df525f04ef7c4720fb443ccad540f03a2be468d88c9545d1dad579fd7cbcd103bbebc9e9f961 00504865a30984a9b273d1bc289d734d10e0aa56e93ab14720f1a42a27d8cc932cb8804b963175de6fe57d8eafa8ab7ea0592dfa 92ebf367b4e675a89617d1b05c4677e2196c5f9e994a5633f61bc91e8ffba675a35a67f62df925c435b3c4e2fc2b41ea0057b04f2ac8ff85ad4f81ec2fb7bae3c5c57958fd2e3b2e54b184001baafd5e4f4d150c2176b7ba5ae1c5f728c3fc0d +af36c04af0e3fd64bf52dedf52fb788d2d1bd67fe05d98880cc7ad3c20436abf02f637fcec209fbf888903fdec8682717299f8a4386768153b7faeb6581db57fb9aaf4615b4ea8d924198fdd158363a1f40312527d6bd14c13d19985b668c6b88a7548104b1ff057d07082eea421f50062a315bc3866378f2d2d634f03fbc0cf 00cc08a4ea5ebe32027885a8c212870e7c45b6c610117994d6a42a284c05199414a3a0e8e6645ac5c2ebf21c505a601f69c62b85 86dc3d79883cf9717ae535402d41856c8993745cb2e7ffba4ceb65e96267bae0c10ab4dd008403770106a2ce9057da46030a52de5358f346a244b3927a4f419849111825ad12939605510a92fc9ca7f490cb3be511c70e402013eb67e23aa020 +6bd6f52a6204b60f37929aeff28c87ef61ddeecc231e52a7772275f9329add899c130956f8c50ac2698aad3654fdb49b74a6427a62a11eca0a8ee8b719b8c0df7b9f0bb0af5fef4918a8c83367d29fddd04b6a1ecad904471e5b59c8fe3cdb06b4f8f96419518dda960845d83c49a49f1b1f2fd1d2682a9d60c25fe3ce982cf7 007156ef0a74ee1119532a2a7e8c02be1559c3c21897af9d5b34553c3d0feca4a8d5929d1945df824478e0c0b92a6fac8c84f639 a40f6927fb306c0f53e62a44427135f38515d10413702fdf72af9ec59681d9bc191a7f1f692edceec25dea0d0d7caa28162465212111a21a7433cb0ee2e2075da64a72349dead7f9cd3572c9bac82d56f9a2fc64d1dc25afe3eea2573b1dbe10 +0eb8de25f63abc9cba16823270e9b6f3fdedf0fb90f6652a34688970932e3ae98f6d3bf0fefc5f247f72960a6975bff1f1acc2188a1775fe8974b2bb2b4c8d226ceb735113a14009e8ce66d58808fada4e6f697fd016829913352c0f659b6be354a067df00cf74919580750aa6064f21264d89dcb28b3b2d4d699115c36d1310 00a95c7abffa92e2c637611ccba66ff9d2ab121b40a85c5b71454cb0dca1f098ce1be8d9ea4933d1a91bcd270c5a33687835d6e4 857a75505f5ddddf0cec2c7dca7c1ce47e6b11ea353c73930d41bf7b4c9a06e56e38402cd3e00377cb8ac793aaac9e7d07c164a81d3711e1b8e226c68034faa75c33581acd57c230addf403b477a943d828b6255d19c87bfcf55f113424af632 +cad58ca7a3b9967dc0ab62a43037764f8074ef9177d60bd98f623d693333971c24a575ed03cb61f4dc2e3d6285fb1204502a540f3c0bbbf23f5bbbd1544f322ce35d949d8b1d8edeb82e90927ac67ad49c91007056bf5096bd690d15ac00e1874fe33293d8003a4a2b094078cf09af799dde384143350c54a99e1f99cc31f2d1 002c438b07c6e0685d1f94a4bbafc013f8f21265d893f54e54c3ac2071606ad1ffacace0b8367aad724b1d9508c65ce52282e397 abe29b0977f51eba0cf186cf8896a7a90863d84a22c859658d6eacab077e357b38684f77525bf51e77b25b01a689aa16013a06a1a3875af0c53b05c73752c45c48c9febc709edee16dd4719e981196ce8fd995a1f53becf0867bf45433852611 +281ce2643799bbfacc7d5993683a4fa656040517854f3c2dc7c4f8848dc305382e34e894d433caf12d8b493020a6a08d1fa05b08bf6c53127ad5f33bbe75b9db0615e3dd94408d028dcf3cb7598f6e7cb4c787681dabac7cba2cc06fccb7506fece6c7c1c1bf622d525ae9737085ab4ac578905950002024f30159cf0d99f50c 009e8658f8f9e6cd98c0f4f0fd20d64d725653aeba339504def17f3ad12a63dc6157d80804e5f43f4ff48fc5573fde2c615ed31b 964e4eac0af0551ba490e24979f9d1c9fab859f032e5b082de80a2edbde38feb106ec23c635e3f181729910120261dfc119ba6b55c971624b657163dbf79b8e4fac7db5eb7b7e3e19b11110b32f3902f731e06dd4885ac9a6a2242a9f5229cde +0c061da1a16f2be130ae3b20b89745e840bee09633fb49671db28ec9a051545f57ee07e2410ae7ebc61c9af79868d3047705bfc64ac0c04ef0b286e579b650c7165443631e49e6a53c84cefa5625b1e1035a6ed89b8e839540040151132a937666524265e099272c1849f806db0fdf2be64960d5b5853965099459968e5beb32 00c4c13f65eacce85a51881caa6f82d9e48ec2ac574947d2751823a7f072d38bd9da0cdf30b6f19084a6d291052e7bbc2e1349e1 87596dbf1d14d507e1ecb14ad00569ef4b49e65f24efacb3123a5e86efddcbb796ea599c7c8c4f034f3e81ca242c10b00dae87a3da3500b37df9733746b05dfcddc0f435cdf208ebb7b42d394988a616d57ee83febb59661b5b9ceec2adfd9ad +74ac2e1303297efc3ed8e624722df505df55b7f33964cc0d270604cc48b58205d8a11952232a8feb0079baa30d7d33660268b56a5a3dd90105f0703abef8f6636a99bc63bd47d9df100351bee32d8205dab0dbd2af36fd173409ff8d1fb7b24570f3c1e968458f58aea5aa2f46731ee91ffd6d3a060af6b3d5020daf1362af3e 00da591461791ae7847e6d8dd8df46a63d3021644abe9520e158406c96540d8fd82ecfb1c3f6f5cfd7688c7656cc3e3dc94e586e aceb3ba8784e0577fadff157b9064c16150a1d6bfc9e1d7d54f0f091ca66d3239a3b77fe341ef8414220c2702c0ed3641174e32fbf78f0e5e6c59452dcb5374068545e057a0d6e19b07cc61e699c89b6f29feaa6d21a6a53ec1873ff3f199d23 +2afd17344552ccc577b0118caeb7dd56a0766e25f84df17c0505f9798931374b48df89a48c64e199108c36e00c0bf00a97ccde55787bb97c6765601765ab5417f3e75e35a9fe5e0f85a721d9f08440ed617afcdc200b318940a1e496040a6ad9090476b0fb4fcceee77b3fea11de09e7fb14853d1fff8ab12d66c101257e2d4f 00b5eb943f0dd390b737510e2bb703a67f2dd89dc9f6dca6790bc7a260cb2d0fb8e1a81ad6009ed51010e7686d5b48233c6c1686 a3d0d2d74c99f635f9b82b291d9991627f3dcbd45e35904d4bfc1322909f93437dce1cbe3094ac1eb8eb31620a07783f08529aba059f02f0c402f73ae3ed82bda1a7ae17507409f70e74d7561e9593960bf1cfb1b940fedafba68a3a18bca9bc +174b2b083541f8284645a810801e72631a11bd7bb805f684a7159e055afc44357f2c80df2b7853678d34a04144e0ede2327d03db6df23769ec41194a8d9d86af74d51c5bc11ea878c6a80689af71d3fdaf1c651003385332a512e03dd040c33d9c328ca89ec7ee9026bbacf30a7f3a68e0d894fb9f7100ffbc64bf17679dedd1 009cc63f32152284fca27ab2837bf1343144336a1fdf15b9727c47e877ac69ac9cf4c97b4bf42f1ab10d73de8597a554ed099efa a8ade8eee8342e7b5540affe397d8c7350e18f4698caf23bb61e126b8930f39b705d6671651f2bcd0b1ffac6813fbadb01f0a01428fa4386d886c78a0a3a0ddfe299d691b8684eea01642f16da8a844e6793e6fc7d1c298a9085dbf58c303caf +758df71a952cdcffdc417b9fffdfb57582ab5c5473a8bdf0c2101953b023b77824263353dea0e2ede1f800a5757ec6ac0e1e4e3ab5a4cd85567d2d19acc6b7069a6e7368401cba2b6e642373654bec0ddd19fbf032794c15b7ef7e714e13e36875262c01e77766ed53cbcf735936dc9b33eaf2152a396349c82ca0297dbae4a5 009950355e8667bea8bbe3a2c4988436ab5394551b375e27fdc0c1a1d1b07ae957932f428f1aca0a486e54cd0b5bb0a5c5650641 92055cf5ee57bd46e25a0e0be7fbb13d856d9a03709fa1a6c2ad725f5758f8076ab3d0e927f88b9e6236f699e416af6203804d19e145ace87952fe0dcfa304cf0d212185777b40ab9217ced4deb79dea0425306a48cc179a4c40525e3fbb0bdb +b96d9f66b2000e9408d602096f032b112f0e05ea874229ab9daf6e05bee49b4722e4f2d8bf2eeaab9dad94438c76b7cc64dcbb59cb4e03f9ac70487a1d24d8d6b72d7462fe738a17edf381d52179b3acc0c0177c113eb4d10e8e78041deac1d56abda0ddf892edb8be956d285e7236bc6794168f8a180f622dd5f2b9e690c275 00a995493d6971c2d7e8fac3da9f8c0b5afd877cfb94924cfecc167f9d87002136ab253e3a4f9ddf5c9c99bb1dc1af0c6a3a3c4c b08851d6946fad89a324779379d10e9819c96076184e30006017f26c9b3756bbc6afcf7bfdc45bfb0709072ded28ad1f144155ff40cce9f60ddb1f216b7fefa25abdcd592e12d84928ddcb1f5e0b7c86734fb752457330535d8033ea6631f401 +e7ae60ac55e6ba62a75d5328bbc15269d4638764169de0bf0df043d15f9152bed909b1fb8c7a8d8e88ac4f552c1092b62db00958a3a827f64896f6de4bbd8fa5258d6c36e3904d82d3eacf6eedba50b0242eb6b01212288448c3a9821c4fa493869c01149ff1850e8115cf9de1618cb8744626b1951d1de305745507c8b21045 0070daf435cdc26ad66c3186267ad12d10f28d32d863f950cbfcf042fe9dfce553750ad098f82f7f1650c1126b3e4451bee6e11f a5fe5079123f967cf45c5baea50ce60fcd3928f21d47ad7f7953b63c937318b18ab976cabc9dab14cbb821e17dd3d6f60b22176215a31341b617246b496bab3cd0cb578ee8ab9409d6dad65bf2eaa93dc1111011dc6b34d15e40efba306208e8 +666b0dc2ddffaa7ffd57ea3b2768f02d4b77c16fa007c6d1918400d195f068cae2dcaa69817e6e4c70d5b29c5598efe2d957bd12d0fafdcf5ac52dee80a2d46e77fc18cce2a49bfd787ff77b942c753974d22434742bdb494590d17c42af725b1309e54566276af3bcfbf5e174d3cf191b85903faafa1583282c97e66c5da6c4 00f8121980dfbe9ad0bf92383c7cab95fb72d5caba96e1de7772c6a179e85414802fbb86d725401451329287305570ec7fdd873a 8d5a7e6e8b702a743ec31726c61836c954666f1eac2b2bec4b4b59043dcaa55e0423fb5968e6efe3c6b90c0e46e1635313ae7dc9af1fbf55fd95887d650d58389f9af469f451032a6bef4c9e6aeb94919896be6b24590c21696a0e2ecd1fa428 +3e967cbc2bd936e0b6125dc5cf885735bdcd2d95b2f764de6931c4578ac8e0e87abdf96375481df67dbe1b6c43537e84ec62bfca6672cc5f3ea4125abd4a4119edffe04e42411d338e8b10abb1f1f818c50a9631a3f89feb5be5367bdcb0a8a82c96a427ba6ce99f9631d4411a2b7f5b14d32cb3901dc9d285e4cf5508940942 0047682b2e3bcb5800a531858e8137692a9b1ee98ea74e929ce4c919c26ae3b3f1d4122d07fd9a70d8315fab727ccb67004187a3 adad5ec7c2a920c94853891d1b031f77aa803dbd6c9b80f769348cf4a3c88f6b9153fe32c7b6bcbee3e5713e1b66dd3e0017feb068bde69fc642899c2dc7a7fbbd8989963789c272c59eeee5a4d638fb3906b20a3038d292ccec122a9a803d68 +ca1c90012eba4e7c5f01d8cb3814c58f48c03a16be6ed86934014365eee547070b870d1d26a872cfd28b60d9ee0a66dea223e9eaa90ee28076188d6091f26f665684f4b486af70669555db9058d485c677b2a34d4a98aa8d6f43bf6f44aff2a23c5d765e98f0438ab81be0585a5be29daece5d4116f44ce6062753a3ddc505f3 0040cd1a06233ac27f3ddd108de7c6c0982793ee620d71982697713be9fd5143658929924cc88747a680779bb00da8a44e1e7d3f 8e59fda078a0e3604c974b3a6201dc57423f16615d81e3d6dcdd97d724ccd9fbab4f28709db1e2cd5c102df2201fa72a0b50bc81e11dea167bc75e566048ebecefb8d4a80403f7f45c95d99f9e09e1c642a8a1f42c0c5a72292fea6482949afd +a54c4351ebdb075d6a42a787647390f864b2bbfd8bb3d0e0ea9d767200fa344d1a9ff091bddb186acd69bcaecd767068efe4d752d185bfe63f6674279d0e7192d2077c400bbc0d5599ee28507c1253f05eae0687b965a015e1f3a292b4650106765266f5c95b77ad2d82a6a6e012f233169eb6b8d83576901cfd4a927c54d7f4 001ca6f752aae4eb7fc9c73a08d6fbd96bfde5030d759a2507bd45b6e1d1487e53abbe98fad4f41976364e0a1d830910ccf97abc a40c148e22d7c04f9dd2178bd0bd35ea015beb9d8cba9826ac201930858588cc9c7640e4d912c83949b9a753b2e0e64c061d1df09d8206bf90f206e97a05e04c28cec92ef177834577eef0db220b1308e80c9948d125b1e90f1e7eefd95aab4e +6723dbddc8720feeb75e2a061b7fc49079f999fbc79ec8a8e01ab8d35b438b7049da5a23c49a58101742791f84f45d5f5cf551cd7de6926a0e2c4ffa1e378f038da597368c62df8cd8349bf046de46d02183dc05b3a3575f5f232dd2970057200e2c9cb60eaa6b4d72f8b73d4d40b98d1cc801d1a69cb5ed780a75a4064623b2 00fb9b1a9597d216028902abf743d25944258b48c9762d4589fe660396130b75f6006cacfde60f6204463cb8c18b032de1dd68d2 a62b0d29bae5ca188ad4b06acddc441b01f8fe9ff531736ad1bd99ac97e97fed2e8cf0c23bcd621fe7274fb0119922110a6bface59a0e83919fe832d257625b8e248e1f37f97ff3b5ade2ca1f4411172c41e676515d19f93f41b244fe3fcee36 +ed53cec5e5500d62d38c829002916c657674ede4439c6f405ba672327ec677490e656bdd698f114c2ab5e6a1fc94a1a8d64466cfe9eaabd23a8b5c37f76a3c0decdef73b3e7b751cbf3b0817f4079560b5ea34cead88ba374201236bffc48eaf289bbaa4e828afa7d732473c228ad00588c9b443d65b998f21c3d7a9e9196c08 0032109202d754da290c266f74f47805a06e6b5c3f721a72fc97a3bffeb8887e0c642d49a6bd034847d0a5ba09239c5dfdf0772d b60a72b1197ff36b46e22b8c76cde42cee4973e0401e096b9bccc2c06da4dce4f6227f56bfd3ab113e173641e8a6f73014e1b76099db22253cc282678a825c7cfb060629ebf889e6e910f46c9b14232109fab3a79626749b21d11afe4f6e1d45 +13829401bd41e9fe01329e9f5a002f90f1a6ecbf25fc63e7c1345f265ff02e496230f706c6ab377ea52d8707b54f8fc5c7f089044e2bec1dfc66a07da76ee12fb9ea0697d87706b0ebf677600bd2fe117f6cdefb8bd636a1b6b97549ee78f992c24acdf3a946053f06fd012a9c703efb8bd929a66aa74b05d61bff0395232b00 0080536e820fac59b3203aea928475043b2576446619001647e35693a9e65d15236c3cbc12e1bbe0eb305973535c882b70197a92 aaf03bebb1a41f73abe460bb887638aa91cc27897500d124c534a6ec019e0ea65202aa794220e3d63364dec2adcc194f0687691aff346538cc5b7837db7ec5b04e9fc01216ea07274d01abde21cf843619acf4259fa11038549dd305905fd264 +e696acdfcc96a6c088069b7595ea9516a36d8fe04dedeb789fbd965db0cc64b7017a821015f6210b6989e515def5a9605fec0d337e4ac59f3101a505168bf72ab6d98ec62a71d2f94071fc05b95e98d4efc59fedc138e3e49c5d0b44d1f48f7b1e7c1944ee189b242950d2bc804d31c7eeb45283c84638f043ab9533976433a4 00b05e5f0dad9583ea18fb8fc4d8c75fd2e3cf9e92cdd9b737485c953620d345006c31c288b380258b6500b84f729ce6730e5303 a3c55a8fddbf0b246b8413e5554bc8d3606396350dfc48586400966ab6a821743431b104ab3cc5dd6a190162f478e10905ee609b64e30593c194c3b8f70eb8c101164dbcc49ca60a30627145b20ede48112061ddf52b62781da81cfafefeb36d +4058b9a8cc15ac148909eb97fa32aafbb6077b168dde91a411dbc973df7db056dc57ff78f0abcb70f70f800bd752197d681f44df4a7817c0e7f60f8f65489ecb6167c14b525e91fd2cc5d8b80ba380a83d031d5827c8b1262c687c90ef0e62723d9b565557f9f6fed0db48f3799274c2cd60a14303406c35802cba6261121296 00be1d277813e79051ca1611c783d66003ef759b9e104f32298017fb97667b94dcee1ce807dc6b4d62416e65d4120523bf6a4edc a5d4c275d24d8fb4a675bcc39abfff6dcdd92482eea777050f072452683bbc9640c3854155a1d69c226d7345897d00a90efbf7c3e066b71f387b471268797b7c4b11cba46183a8e6d3169021d7b0f9d8104265d6ad573df174930e1f8c31af89 +e793237d46e265ab84ba9929b196405faa3b0e4686e8693567e53f68e6991e57677974677682a2510c4c35b1968a90b32c4941af7813775c061c008a60f9f671cf7419c94253d6106b61e65034497f2d273a5058379bd986e3d917f708f0a2bebdba150f6d78a3af9c722a2430ab0f4bad602e91e18aaf258e3785fee78e4502 0073c807bd7e07379782ab790720de4ae5106f16d34e80ed70da5b1594e660c9b775db94066b93e74f855f57d88b6ecc6228aace ac6168ceffe0be895eaa5ceba3847bae1816657b5321bdf4fa9c8c2a0dcf069893308a13a4ca38cd4520b749692b1bd10badab001b830dea565c1a4a6a83291121def0ef5ea13eb77168d30442998cf97f096370a1b205c6142eebf8348c6768 +ffb8bc80e7619a562d8506eba7658bef0c25ace3dc1d01bdc2ef00933d4fa07b80364e5e5826074edd46a707dbc3b0ab19eec7ea8990839d7fc0a80b70661204c52bcbef57c1a7bdc861c10766033a82dafbead283d911a9502d5f9ef0a39d35ef26f3616212d4bafcd413ffd18b424fe09b48ba02ca5d97ec996205cd49d22e 00a68379b2296a6c944ad5dacb593b302d8ef0b05873ce12bbc371d705f308c739d21f343349524aa72f05341e64f7435daef112 b67e4b0cb935689becb6f164b69afbe6c65c6bfef6885174d6a35d3e2c9d1240a276d046d79ca52970e45b990172e39514b54aee06fae3e66c74508ae544884a42a08c987f34014929a370e0a56c42ea21ff7cfe3021a9c207c7a924ceee6913 +946bde90a5b903dd281a51d7fa93d80f3fed07eaf50c18fe9fac5acf67326bb18effa3144e25c151efc006a50a274ec6c6a5d573051c4e2d117ceb0fa125acad07a10fb6534a8e5f5b3da2a1136779c51377bf76c3a4a93c0c6158f729f2293e414fcb952c9509f228c804f0adc1daa327a8991d48ccf4f3957c5f8ccbe3ad4a 0026046bbb269ddb1ec14ade56175482343a21b7c265026cef3c7d6a1ae0f6a68166b9e6c49a6e733ad2ad64df7137ef230038fb b332906236a0e78048ce1cf0422a34dd0a584f07246c8e5ef8cafc0a962db5d0ad163719a826ad7ed6e80fd5b90e817e1082d966ed9b88185b0e7ca8fd20ff99578f9b88e46114064147581f9fd5558ea0cb0ec57e47a39b96c23204182c393f +07f3fe1369ebfcbcacd66675bd4ab22edbbff72e68709cb57d4f590e49440f01691f490c58b5117bd24aa2fe2101b59c61c417c918ea08ea34bbb9b8aa17491ae5d9329affe894f42d7586017877fae3ce35bb80c97f92a004380374ec91e151995166e14ac00505fd1fa810cf02981bacbcebf5f81b2e633d3a3db6737890f4 00bbcda66978ea526f7bd867c3303b625f11b94dd9ee6e2c2f8688ff07f2bba83c662949d47ad47fa882cb7d203a7f0ef5dbc52a b8e18bf06157a685e50a6c72d0529c5e9f2ad061c56cc5d4e08f2b8ec71d7038007bbf8e15a5fbf9ad38700391ddc51f0176078745d00ed53e70671873faac845a91481db618b94e05427b56808de172c0269ee254a01848a5051475d6b7fdac +3a1cb13438e3bac9ad4ab1d319e90e2c9f118dcf1eb54d6333c674a665d41451f93cd4a9334cd057a44c010edb668254517a63700a31eb0ca474c84873e486f2f8e158a1a7735362ea0cff8ef17d959ffd851b21a91412709b3c729474d2cb40f6ca0e397030eb2611b402916e4b656f0fd868247d80be3ce33d52054b7661f0 009be3dd3442e0330750f0a6252bf9cb317f32f942ae516a4038dea2c40ca6484fb33611bef016cc64baf166c122e87c15466fd8 901d97b1dec829710cfb48e28b80ed1c9d4a70a5613d43e6024ba1f6b751a886c2ce24729d6e9cb360ce1f90c074e87903642f0573311c9d2e06e5afbb1b8987cbd5af32bcc6dd9c6f2c403c7fe0f7ac11028e41bcab36be048dff14cfc6fc76 +e58e7b881a563d54772125b2863718690a5276c93d9e1c5feabbdb5d6f7c7293ff0f89805b53663bb417fdd46874b8e6a466e7e3ff6737930a0662af1d5879b071b0dc4d014778dff26a2eca5992e763bf4c4698c382ac947215aa116515876008a56e5bf547857049c38a2d3737ed3393705fd346897c3beb80caab88e5b8cf 00ed321fa283c662e87eaab99b7715e6cdc9b42e14fa5bbe2c56fdfb381369191a42da7e574839f90a85577485f19446fccaf6cd 8d3c518822590c72d486aad6872b8cb1b1af5057c6582ed0423b09ea1def4cdd3fe2500551316ad87aefdbe916462a0d038ad0cbcd7b647d336a405e05e9da65e4fdce9a5a9a7f11a2dcf9493605051f9e0246112278976b79e13813de8bb85c +8889ea1da1cbed98963941f6ac24f47253ff6af52de920765214f2024aeb04f7ad46936830a8eb04d95aba64ed7cda6ef242f454b67bc2de38a46b6524bd5c96739c4b580e89829a61a8249ec8dc27a50f43b8554cfb6f4fa4ca6875983d4b60a1c6b49f32ddff6fac0cafb64d55c6f594b195c207a9bd920dcf20e0080920bf 00396b805073f3c3b552b1024dcf35559ac44f255b688871a3c6657f727a4b09f3806cbb75d26a00ae1728be632387e804775a8c 8c266de6ca4d38139f8d526184a3177f25052da23352deb74bdf088e8a7050519b4cc31e376b92faccdafdfcca52621d0e154e4eb9e73bfffd435b87c5fd8b92b557d4d074b411b9a02d04f75d9ccb6aea8a94e0de538d267f1d640f9620c7ae +55053af9370901e38622734a5bc5589f6a20e258627f381fb0c366f3dbe58394e5997e978eb7ebbc530f6e6186f48294149b8594fb551c31c50521a8c4d67e5862921695604afb23977b6a69b21abe75966fdd11bfbdb6b51ab0a474c5fa07c4de7872a3bd81acc417655090558dfcd5af449b3347e61fa9e839bb9457de64c1 00a8fe323f6736bcabe971c7d964e75dece70cb54561da48a11c40027ebddb23e41c7b48600f569500fe8ea2abebdf480171dde4 a28d4a99345524c4233057bfdf00d492e875e0fa24c4bdb603f535a211fe3cd50d7332269a609a75caee42fb33cc1c7c0c3f2202634a9c7677675c93dd9d5d9a151233c5720f3d087f0f6fda5cd8bcce3b2df512f4f160b887c70cd96438bc29 +c4264330534a6c2bbd8a3b757e0912558302ce302f835ad8c5474993832fd30036fdef40b10ee37293e871db5b0b149654f9e543e22111f9709ef45732125f713c031ccfbc9a2f3aba160c241d27be4dab87ab2fa9a795752ab2daf20f9d06a98d90d01c07133adfe83cb11d5176525e1bba6a9ba70ea48b224d46ddd8103f65 00105938ba9f25034da3e032dee121bdb192ac2128b50a2ed4bca042e96cfaf4660c9d35f3e67bafd4c99f9447e6dc408e0c4471 a9fd1a6303962eb276d98ede0ed087d6fcbfc0c2354c8c9c1a7c6117276ca6fc6607bcb74fefa9b0937503e1e79d548802ca9a11b88ebbb0eb354d9aca93159d0f75c0a1bf70fc86c83b5553ffd2f3467bca1be1eb0df8dfc7c17cdf3193cd60 +3236f1ad164e1b25d828f5202e3513c80c72a577aa9af56f041fd96cf5a3363f4b827723b1511a2f16360e32eac90ac55f4ee1146791420ef9e2af333c17d157b00e43992ef6f2be2d2f211361e468413dd93fb69232f0a0d110bc5fff361c0410344aa0636bf809062c73a7ac7c142063912b6ad7e1626fd2a384f35faffaad 00ce11677ca818537dbaeb880fc967dc8bead203a2538a55e756679c4a9e7975b9b3e6aba4e6c6eab4152d0c0939027e9b0bd92a ac319e7d7193ec777b2b55c9ce9ac239565214ff4b573a52e1f03f0d5bc8d77dd59007f400e9085dbee844fb385b6562052526ae66200a03ff8e82955c27408abc57d2837617bb969fe713c350f15cb9821aedcf5e619394d8968578e735f843 +6c400ed098d8369dab6fde3553afbbd4d47836d0d12dd16015f15cb8d067a39391c85ca4e78c62b8b72c1592349ff8dc52db8ccb7fd80c085fae456dba6f4a2378e184dd59238c92cf04e40d43a66b342d2a1325a0bab12b1ac857f0564c27b35e6abed02ff5bbbdc3770ddbb2ee0513df48bcba925da6d61583076cd3129603 005a239ae0f40d76d8d3589f1662b5ca12176a4b2784faa8339b54e96a1e1294433a4d83bf904196f939bd8b33bdb4be340ec703 96d8b3045498de16f333312c05b71edcc9bb67a0af11dd30eec72533847d03db5d7c9f139100222a4ef97be2239c88930426d9d880dc57180f0d68c3da00f83570aa9aebc3ca4591d48eae3f857105c9a6c936ac8632e8abad28d126b90cb807 +039a149eaef2de30b0ae457b376ce6fbf88afd4cfdec02d3c5e00400d3b0484c1cd6ba74db5de65d6f2fe39871349b30fdf1ef29bcbb9e182eb3ec5629d07d98354a5dfa82d7f0db3dd10d1510c0dce086848a198893ca5ad24a663494f0596b4eee86199ea85e7e8f2f76e7a6bd4a052c54287f61b391f1e52f96b606151c34 00077390c62ac41aca995640fde0c79c76f4ea8a8dbb22323ed812bee837ab8798c5d0ba976c7aa634d4b1c2c155de2709e7352c b4c95a6c018c6d9dc285cb8666b16886a3adba0ea6b6a46ad03dabf2df143c875e14a4b7bcc4a518f9e5b7bcfa1faccd0507eee75af953e5766a7269bdf358e6b62fa914fd0021e3a4079fb862d57b4521287817305a5f46d96c07e92850ea91 +08617d04fffd6644c40f7dd57919f7dcf3c888f4147535d12ca658302305bb8e220bb17ccdc480254004b9035b357120580882ef86aa5a061b2850100285b7d61588a664dd4f5394f5478e68a80f610c9204d056009c1c9e902161eda33ef61aa902e96b6f094a9f053135692182943d38b9763055a38739a2a2d133c5dbee89 008bf23b09fbbed1b55769907aafb97f4759cec98649b2c9da5157517d4f85bb70157076b5e4aaa7a940af042302f8be06a84ab6 a41c355e75c1a042f734119de2cfe1694724ea8cc5828d178575e4dae0f9cc0ddf73cc6ba8cc0c2d239ffeb421a9ead710b6a949a3a2da8de62f0c3da6e4094806838fdbcfabc3c591b0e41275a3cbae25411635dbb65fdc65d611070df77498 +34c959f549a307f21b850ae105f41299b8bc94fc292aefc61aefbe0a1bf57576ba8d9b80caac635e4edeb22530163fa9629665fcd43959f68eee32482f1845a78ed7278e6e43d09ed6fedf465001afc0d61f1d2e1d747623e82a762576b879c7024e34f43104593cdd691d53bccaeb8f212dc29bec6bc94cf69d0a8491db124a 00082ad05d19b8e16f80e53a4cccf6869ab5128c5e622ed146fa8555985ccd2aa3b9957dd374586115d4d75b1c01cf98ecfc3646 af59b98197ce63986e11bd0fd73360ad3be5c14e081c9f23df3e95f38873b5d5e7339eb487a3c1c791c3d951fd84d6c40637c31a59ae851b3a703f7e7311d0364f5bb094633b612d6d8061f00526ace470adbcd91b5b7ad1821430168645cb47 +514f4de08a6f49edbb6797c9dad6d33bfa367cc1a1b58a5becfe646c7f3352d5c5d95f7456e7112c4ddc746b9076b9756ae3916c07bbe6d3823895774a42d25d44b3309d18bfe7e3ccb1f85dacfec1654778c19e2981a853c1f40a7eafd16d331093110698c957fe9f1d86582706a6885543248b944bb70cdf9d2ea89190cb02 00af7e581aa4f9be5815f0c447e39de00da9194eee5e5f609668b9b69930b5b48a948614c2250260d1917f0ebcb00ebda4bb52f8 add265202b1b4235605802a6c472ee096e933b1dba9bdefdab29b77c331ff686d9ba2e5841af89d038ffce7df6dfd3cb115de828fa550f949e62c3e0ce150f3e36bf6e1c4b385e9ff4933b3fb66037dd352644458fd5804a7b26c1e04d8fc00e +4e5d16cb1dcaa1abab1e371e1de02f31ef4e0944dfe1fdec45ab64326435b2af9aaf1a6ed8fdf1a6ab1182bb53a844c7cfd66da30aec0d41757f5988ada0017c4ca752597a9fd3637668bc1a92bb1556553f28d66805bb47f1ef91908ce098d452872da9800e77e1fbd43ffb0ed6fe6a62185d4be73ae96c9241b82cefb2da22 006d14107b08354e6a41d7d7d50c004419db8bdc50db43428df5e86084551237223c498bce71a17e25695bc438c5c09e009c60e2 89f7b8c5a12fa6c4ece665274ecb3de114fd6905ccb213348c8e746912ce7bb0bc5aea8950ce4d6782a2257337af0ba3174f2a809fe669bd30432a70b0a4ba52a9e75f9dc706eb47cfa04a2d742f5a391a21349bcee2411ee7606c829e5ee6bd +e29e75269754ec1194270f5c9e8267dfdd8c696008b5ebc92bb840981fd065672f07f6a0f1b19841adfc51b478371e1a0db9c3346a9f0a4ccbdecb7040191a00ddfd0a8faa0e69fcf544319c0155d02797eeef99fabbc55078f9d852927c23fd931685424249b87ed0c70a4a3e2d3b9a2f92830e7d8f7650c0bffa8f8986b7d5 0099d96d2dc9c79549f031bd5346cf6a8544c312a3fbfc560dc8e378efdfe025b0e6e61e09c04c8bf4133396f993b0906c33dd30 99c33a873425d7da228f46000689d2289fe801795359188b09db78ef12c3ea79ec5048aa30ddb8dc18b4514764df1b2d08a3072826125561f3682a9df7fdab3449a1e12373d2e849af2a389bef24f1f3b621b7604f018a96e61f2a40589d93f7 +1a538eb447c18494ad5a5ad27be67fa60eb2c5cb2404eec1dbd7244cd802b17ca5497e779d5f779b981b165dab53ad19fd7bf2ea7dbb9b4baea782a43d758202f147e59d6b6b8ed54f4ea084bc18519943f6894d603e253ba3e8e339a6933bc3a0a47126087038e1c813c3f2997aae321b7c95a802b4b73fc7db95897b7c91e3 0049f347dfd361a65910e97fcefbf60013a54837f2ae657d65e02397f59dc6bca27704fed3affdc3d833fdc621cc5e5f99b92a63 958620360e2df4c2db0b9774696cee211e4b47abf84d5c8ef9b1d8732e26497507fa2216ee23ce1d0d9e3306847e45a500cb1270a27256e4cad58c1790924d5b707541c00e05ee1dfec4c1165f247cc41586f4267f99f2ded5289f07dca4f4a9 +7502c755bbd385079a4001b8cd653287dc3054f3b57de19d0ff8f63c0308c64c56f035117a8971d43654f89b52e923947e4760ac72be073136da70c5ad7ca1658cc0a2d2a880d3a0c0fe636fdb27b77ff260c4c1ef8a18da8e9fd777d732a37ae9906e6c4f381f0a3d941048d5a1f6f2cb8593873fa4bb1621a44bc2bebfbcd1 00dd226de602af4e9f8e25784bd1bbd4cadb0a8aef525d5e2d57b9f3555feb698765672c5099a7d6dd5faaded69d8d68b4804f26 8d14fd36f066e8fff64c2422f88a1d2877e1d06c0c84b33413af34113d14a32f41a7186c8a59b5c4b4f1d44d937125ed0cafa7e62308b9d1a7af921c5e9a426538c2071d647c659937802fb20c5e82369007b02fffeec93771d9262a9ebd83f3 +95eca932d03f1df2e8bc90a27b9a1846963437cdafc49116ccf52e71e5a434cdb0aad5eccb2b692ca76e94f43a9f11fa2bdf94fe74af5c40e6bfd067a719523eea6b4e65730365ee498ac84c46e1588b9b954f1c218920cbf71b167fc977ee2a89429590f43bf637eecd91b0ce3be2d66bac5847205f76c06b914a970f543e59 00b6fdbc9c8c76cb2b822a940d8675889ca6f5132429da795462381ce29313a23bc132976fbeb346ed4c691e651028f873ce7971 8cf6238a67660b463652345f8cca591e582d20dcfb3d10111bd5f133e11261d58c43983f9fdf4e8dc9a870a13c8156501868fa66abcce370731b6afff0cab2974e0e0701d5f6ac9a63d985490c8e1fe48fe691732234ae6e5176f978bcd4b641 +8ff68cb00d03e730dddb05fe0b2344689529096c3da6eeecaf097f22c7fa340593106b1f6726f06b7ce7358edbcf801ead959438a42f94cdb467b3cd5b17fbbcf75739805f9eadc869c33c604cc58f81591b0b8bf4d42bd53a801f0f829a31af6c129fb4f20f1250f959754eff8c629b85a716b6a18465b6495798c0c5166c8c 00203d77fac64591eb9a18de20a9d5eacaa1c3ec58a5ecdb3008c2d642e197141d16b3a9fdffe61429264f5b420f5e9926659a4c b4362fd1e371991fff15bd39a0f70732ed2c3dcf621cedd66586091d6b87dcdd8fd87e0388c8519aa0613618f39ec32b19f0e523c14c3ce428f8809e5fb7bddde2a9ab03bb6ebbe0c1b46e3d62abf3517337db3794847b7c3a50cd18b149ce8f +01451c4f09720cd53377a5ed04c907a735477378ed960235a833049d6bad6e6e89958b4c4249bf0f6d4f043530c9e5426deb0ec3a12b7feb4860757b41bf602ca95655155356ec35a2db8e2657998f56529be4b714364f83a140846308a2973907ed7b08e935173ebbce5e29afe1444cd51c92824ede960056439555e7e74450 0057a2e6a59d4871c3d547690237dd9846d6d5dc4ec0678aafc9c8669af8a641eed67bfea4b05fd6b3b5357ec4d0caf352691ea4 8ead10b1d4b6b3f63c8c1c79d1575bb4432767b2dfda12e87ea82ca5369b4959358a04ad93a2bcdb959474e919fbbdeb054698a93d98988c5b15d00761e5c06eea315d69b7ece7eb220f03270e98321044748d0162c05863daf5baedab1c5f98 +ccd494ca005ad706db03a3df6d5c6e876ef859ec77a54de11fe20d104377df1900b6b192126c598944d19a2364b2ae87ad7fd32265d59e1f22be5833f20767793677b628f18e9619f8ca32f3af3b41c31e87a98d1527e5e781bff33c1a8be3a82ea503e76afec5768d7f7dd1f17dc98a9e7f92fd8c96fca0db518bd143d82e6d 000a3da7a6633608fcee9ce4253bbcec08d41ee6b00178ceb017de74e24d48fd89107c9f2db3556063abe3cb011938f4b4871795 99c5656b9389703a54f808668f9fa9c05390d590216092df542929ae6f2a84f14fc73cca9b23c41563b52982f770dd85098b448150b5f981ade87cd62fcc9ae8ee9dd2e0d5fd5ad395aecf207d51f0aad72553c0a52238d555d2404884e612cb +5719e50d939a8d74efb444eb5a77cda48cbb59e7f976cdb2ea2848bfc558718b39ce27b893c229db94bf77992222d1746f8f52f858f85124a28193ae0da039c53d484681785f3367f6516fbb8a86560aea9e3428551facc98cdb1e9df8e2f37db823a7abc589f667b5c93c4c47061400220a2014197d514217fc252cef5a2433 00384723c8b4a316b450d1fce0b2645912b8acaeb3cad50860cca43bdc0206ed5b3b60ebdc29b3eda305d0d60eeaec261edc24d5 a8660dc3b54358b937c94f43274ad7fc8adc448a48824fc5d3c9fd56569e6e43b9372b552787a5583aaff004921a2bdb14329647132803e8272dbfde9d7a5426f4b53f765bb88bcf3080ead4fd1809d0c6e262fc58f84c5e0e4dac1d39fa72ac +c84e5702a339259a61b5ba8ec1957f23ffc4f1eeef3a58f383d3731bbaabfcf49ce2ebb597960ac5115a2af1c62b193d4ab6c24433d5f168a1752e40145f19aeb6dee889a53a4fadd13eef60e28fcc7ed6a9b8b0ca286c1b3d66a4b2c327a629d15c148049e3a0ccdccf05cf22c31956014595e417060627c8125bd7c00f8850 00bd3136647572fef3de51b12e64b36460bd3a27dc660c164fc705417339cab21f9e1f9be0f3da926df459c5ba58b701d306e67a 830abc808a2c36ae8f7c6b535c0f1c33cafbbbbe43be02f784b41e04219b10ce3b4f8ed34d7a1c2771e6a918f7edd6dd03309e7cfa0b44fd8b055f88f1610db03c887c4a40f952f5750fc609b4d6ee84cb09e74b3a0e160036afafad9b8f9141 +c90bf11d04a708e64b6f94d4cca64b92463eae878c377b188c82c1c5f05a038be20eca2e18034d46f00d9a6fc73c4084981748ee9d2915d87aee4e2321f4f9e11c176f01281913e324700d9cb474b7134fcc408fb4a7006acd9e63d4578ed4c2729d8e0d01b1e6174a43a024ad261eb644ae98979c3cdab75af357f6dbdf5db1 00495be0b0a9d357f6155fac008cec90442200bb842d89292fde38b7256e4117284a60249b3101b3f19f778b680c0d1d7422b84a a729d9bfe9fce3f9990ea696717c23b8537b632ca0a19a4ea7991c4736034c6f6b04cabd1d1d4bb46f9020ea7d2fcef208e722561ef964470d4a6a441899abffa81500b64c516418c3ef766eb69a54e0e3d9f5f4f4865110e7acb51b9283c74b +e9b2a33906a1079280100039787377c2971c378b92e70a38ab41dc23979d6fb0c41e53a21b37632407adac6f212341cf6af8605b4978c85c9c16960e1674247f1795cd73b99ff28cdca024f5078490513c77114c2f52288f5376872c331151d7b2c08f7794f2c1f9e0d849d32d73636f0aa899988ca561a76f74543b37cbf3a3 0079626354dfc4eeeb51fcf232ee9e6b0130c9bd40f15ed45606bb7faeca8f359e0c3e18bf12769254522fd4077eb24bd5454871 913040d0ed45571663417ea0d170c4cd2dcabbca7ef4b707949f0b3a3e4ca18dfa0904d62975e162d4fbfc741d14252007c766297ea3d36b12c87e473a9cc7356cb6f8282a47846e922ccf3f7b78cdeaf43b4eeb45fa1a5de904ad83fdd5e2e1 +672db3fb8cc8e5f831be700498d3ab3aef14b7548e8011b21351215fb6dfa09460d18f52c02c8815baf396d856a429bb9afd602a10c213af34db80447f4c06ab4bd28873c88eb9639b199042d4b2cb13cc364f734fd4ab7bebede7dd4da63decc0cc1f84e34d760013f66d71641073f16c08078880b67230f2d6c6bfe17d206b 00ab42bc7d0e3c23f8bcf928e25f9f027b56f270398a1d37bea0ee5426b944a9c9ba6d0d7796899543feedb470f70b2ab148234f 8feb569b8a601a023f68c03af53df38422fdba5de471a64472543852e1e9ca386e733864295d280dffe315b4a2c6bc1c0fdfa26e498a124dd7e32db15290542ca702c47ad4cb920ac3ac8f163bacd0cf0fd14048576d4e039c5ad9c98e973caa +d7fd06b89226cfd66671ce5b4b656228c52d986afa7f6f30161680eb0c9cca177992a8a8c40167a64165c518c55f678702125709361b536bd928567c97737bd750d0e2e6e0c00296a6ca565f7c05cc8c54ae7a4e0c334c6a968fc18a959c18ebbd924457701316a4e999fb11084520dac68dc2d69187134c40891af0355ba89b 007f7aa2216164ba689459ee5d5ca29e70ef75a5b2a4416ab588df1dcb9164330c0b405a9d80c3acc41c19f58e24e17ecbc0fa7b ad4e4b8072f0626174d96626ce89c8f55d73fde6894a4c7673e75ba433ae2c043df4b68b46031e83ee55ee49c125a2b90a6e920b5e76f9320b416b7960dd50df7a47dc43a5da59a36663a8a72c17f4f7c68c4b7c7549a7652dcbbbd9aab2366e +83b7e9d3ec638fef51d2885fff5490c94e2509c126608f82660e5fc523032f3e85d69d9b76af145f6bd916dda35775abbb6d1902bf38880f8b9259822055c5b1bc726c51029972cf7474cf2a812f3251aa71813476bff55598d079f075a40c6c41498bd865ce960c518bef75a873b9d010965f342dc4b35ef5c5972efe6fdd18 0021d84f070c6823a70f1a74225a472118c93ce9dc509aa6064051ca4574939dcfa96be862069424bdf1a23f62f2868326422e64 86c9652808a8d1793126b948a5ff5e2d8a1cf2dd52793d761d8dff5892c84ba21cdd54c2d24dc3cfed960d7d0b3ed88310a16da79914cb3df93fffa627861eb93c175e34a13141f3d79c581355f24ca1a134d11c4a157f86dad1020bcb37cf75 +c62c7bcc860f0e175128e1127dacf935ce62ae794cc4a0ce7966bceb023ac0498641d7281fbc86f9ef470bbc77f608f83f8d0dd6299cf08f2cdacc7a9642e4246df131820220e5c05d0dbfceda7f16b86add4793e9b6244d96b5c07cfa23574ceb43e8e8b5483192a92b301aa3b37702b8f94f0129d8af1617896b34990c9b02 00b6645344d17528968c719091b6e2072388881dc10bdb4c7fbf41906cadf3699b30f9c1dbfb4796d009480664e6276c0359e5db a128f05e61c2ab754911eaf50805fb4fb392d99fcf884a39aef591eaf3ca411aa3e5241253c5b4e5f963b47453343e8415786b16251bf3871d5d0470b264041be3c3449cc85a29fcda53ccc5a1bd45e88f52467ed4614fc454b7bec56229ae6b +b5bf38fd9e822925254418475a1ce762a94e336f12b156b1625a4574fee11ee472d537ef94b4a4b1c0a73b0140d0b818cd06636653e6c07f0f100118242a7703756f1cb1119b3477c4ced99cf45e07e83b7f2749c1a5f8d8c9272d221fe17f7c6a5fb0f8a16af46f232ce406aaf565c6b2766a2f6528c82e74fa1c0a7fcfd49e 00f8c2f770cf5f8e1f900e996ecdcd84fcff5cd959777fd005d721a419123221a3237e39834b270d37752470deaa6cea023c5058 94e64901aa9941d91caf6142933c288d4a50b4ab98a5cc557da504ca07226039834e865eb619407a99dff66702102f43007533b3948c07535d07a09adc6e4d90501e6b9081efb4c38f2a0ce67668aa5f57b13fc17ce92ad2db778ec964a8611a +6d3474770933ec01b76be789304b6fda423b12a0ae8c87a5ea8d7ee9f71300f39440e1c7f5aa4b47c1a8628cfc3a490b15ef292a741344f40a8fcdd02cf3863bf3e32d53031f503703deab17fc52b3d4032f4e237dcc27231b85d3fd60b49ed7ee40c3344948d87c3f47564d20a11d50e4e520bd16c8701694fc70901a5da625 00144adae951fe897d5812ee4a16c0be4c86c5e57e615c398f5768a1223a9be20fa82ceccf8a16a31432bbfd17e594a4cd8a6a07 a74ae127a7fc02a65b6db20c6486f70ca78b12ba3e97e5df9eb87d5a0112def504569f8ebbdebc054cf49c815ebb8b1009d67e7a8b5be8c8bfef973668a705d87f576d73333b1a4465a890f1d45dbc1293180ead7beb43510927a28923794299 +92ba7aaf71f625f7a2e024058dc8739da3567c306da4a812ed9e1542b7d1e982c16082166a59720203f4524c3bd463a662c26a82ec7b4376545206e650eed0d3dd7909dfe3810981393070d15c45dc4a75a8c5bdeba533cad1ec34fd20466a61e4cde3b25af9a80a9a54afdd7de1cf2a74ba32d4ea0082a037775413c61a8d1f 00a51f065fb32c55bf4ff6f18ba9d488d35d9f8da593adb0ab1632533284e0adc43ccdbda9d9507b9862ac63b5ae7b0f78b479bb 92a84021b559354a4c9e85809921d073814af3121b5fded79a34bddcfef827df103c08c31444753a19d1bfbf54cffc5c0fd9fea8bc2128da39c741bcc61f6925af1b1fde21137b4a33779a9f16c6743b667c802e67d19222f1aad30e934d7fa8 +b3fb9e48c333201324755a81f3ae5d4f0e2ae7cd24238fcc66d858e3aeb1ee03328660d6399676eb1b7d8285ba571e214d935bb45516fccfab57b8eb4c3d5f1d7357c768eb7b5e7b5710f599614bd4e92706eaba31f8a5e7e57af7ed13066af50b4540ccdc126b677789920cef8543907f0ba9dc92aae343d3425bd784ef483d 0095351c0bc07acfabe6477fe85f97eab520dc96bdd58b44b036328ceadaa56a1904d2217c5fd25155ff2aaf9005a3e2687fec81 a53feacbc9b90d4e36c20d58eaf616a61f04e29eafb75b829cbd7eddfcdfd40a26e82dad0a1bf14311529b89e2f74a5f08fe23da9e8edb8a03c46706891dfc763a4a820dfbd2d9d41ecdb807aafa538033b1877ff349b19c2d39aaf552a3bbdf +9ec5f7d65082264b8a50be772c44277a73ed19199eb275fe5976f9799d8629fcb4a59a8d55074cd2eb2a0e02062d3f7cdeb05e62931a24fd1aaf14c257944d1b42eebd52726d6fe281211b39038e52baae077ea4df89675d860d6ba5a0f998d049614201b872e134367acc90066ac602e478ac3e43c3ddf4b0ca0aac1a68591a 0050245c1682344fef23bd549ac8d1e8e44b2840c43eec1cecd33daa4e9ef6b53f496104d7432e14248682cfd6f5b4853b65adac 91c18d69cc31483e33add3433969f1ad52bcc688bb77160e7cbe84bbf5581e0a036c65c05dfa11cc902804983e57189f1818cba4e8eb70f289bdcc2f48e3fb211d6b3bb62252e93d3264c84c4daa3ab6988b5681f94c65b79c3ba8aae1674542 +61d657bf472676301503f6784b7286fb39fb4186bb88abf1edacb4a2693d0a1e2b77bbf2758c84f2cbfd1753e20841b1cd4b456400d53f4d686e666943f9b6ffcdb77f510be97536e9698fc84ae347d483bc8984548d1cf86b9b40d360f9c0dc5bd1c55868e26fce1460ba94ef5e94eb63c9f0776a0f446c0cfd4106d9f36352 008d3b0277f0e9fe54581d3a9499ccd7f015c08339591326859af969d2a26284e3b3beac4a0b74d324ce5cb5f38c7995e4e3a41f 8c401f95c09f772c3616005ad8dbf6c9281b15db06993fad7de6011cf2aaa3e165a5bcd962e03c903cb0a8983501a002063cd845691584b7244c8db283b1bb8adee695920bd9335e35bbfc4a6bda52894b1a59cdbe4a175294e7978fe3d13636 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B409_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B409_blst new file mode 100644 index 000000000000..377d386fb74f --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B409_blst @@ -0,0 +1,60 @@ +f2380acb0d869d1cf2e25a6bd46ebe49d1c9270624c5507be4299fe773749596d07d10f7c2be1c0b27e86f27b4a6f8dff68cfe5c0b4c58dad1b4ebec7bd00ab195fdd635d9fa8a15acf81816868d737b8922379648ed70022b98c388ede5355e4d50e6bc9ec57737d8843fabda78054e92777c4b90466a5af35dd79e5d7a81ce 00beb0df3b0e05a4b5cf67abef2b1827f5f3ada4a0e6c3f23d698f15a3176cb40e85bf741c9fbc78c9e207fa7302657527fd92fb afb8a67d0e30b4986f105f61e78e3eec9de979e4579fde0c3a746eb710928570887d2781b909eb274631ecbae430280503345a8cb899bdbfa1bea2ab240c17d6d730ed55ec83ba6b40b57ee8ea03041895ff3e96a18baca615ca2e4ff9364d9b +22a97fc0a9694dabc6f274ab52eb592dbbe8beeb646ebe6cef60eff341a13017eef980aba6d24ab3afd976e2f6a84cf652654d4a54a36b2f2f62fab8858f8b0479a48fe9f47f8fd5a4a1f3141a91cbca186507b2bbfef5e4c4d2df525f04ef7c4720fb443ccad540f03a2be468d88c9545d1dad579fd7cbcd103bbebc9e9f961 00504865a30984a9b273d1bc289d734d10e0aa56e93ab14720f1a42a27d8cc932cb8804b963175de6fe57d8eafa8ab7ea0592dfa b5d22cdd07e696c461a52852ddba9bb804d1082d6feff06fee80af683939b1237a9639f4195fc465830bd6a23c0b666e1534d8bcdf3f1a68505468d84ddbbc9f3466f722dc335c6ff75d2dbdf946943ab712dd725aaac1cbdd8d482496887569 +af36c04af0e3fd64bf52dedf52fb788d2d1bd67fe05d98880cc7ad3c20436abf02f637fcec209fbf888903fdec8682717299f8a4386768153b7faeb6581db57fb9aaf4615b4ea8d924198fdd158363a1f40312527d6bd14c13d19985b668c6b88a7548104b1ff057d07082eea421f50062a315bc3866378f2d2d634f03fbc0cf 00cc08a4ea5ebe32027885a8c212870e7c45b6c610117994d6a42a284c05199414a3a0e8e6645ac5c2ebf21c505a601f69c62b85 b2932484979ccab827ef6c55d91484786e2571888eb0caedc0eb98321d180e0aa969b581ce7c9c0deb7261920e08239202ed039b3e6d847455cd3a396f53b5ff5841fbd5590a98044a72994c1a19da02a844741c19dfa19f58768195871006c9 +6bd6f52a6204b60f37929aeff28c87ef61ddeecc231e52a7772275f9329add899c130956f8c50ac2698aad3654fdb49b74a6427a62a11eca0a8ee8b719b8c0df7b9f0bb0af5fef4918a8c83367d29fddd04b6a1ecad904471e5b59c8fe3cdb06b4f8f96419518dda960845d83c49a49f1b1f2fd1d2682a9d60c25fe3ce982cf7 007156ef0a74ee1119532a2a7e8c02be1559c3c21897af9d5b34553c3d0feca4a8d5929d1945df824478e0c0b92a6fac8c84f639 9805f04ea77c33f28cb59e0e8810a0caf43497e9121575532f52b2be27d1a415e876596c1af159934eafdf885789850b174b935d414a8125b65b36c014fbaa18625565d7fe88159d0b5a23ce0686069d83f5f6fd9b5dec2b01457d5d4ce5e73c +0eb8de25f63abc9cba16823270e9b6f3fdedf0fb90f6652a34688970932e3ae98f6d3bf0fefc5f247f72960a6975bff1f1acc2188a1775fe8974b2bb2b4c8d226ceb735113a14009e8ce66d58808fada4e6f697fd016829913352c0f659b6be354a067df00cf74919580750aa6064f21264d89dcb28b3b2d4d699115c36d1310 00a95c7abffa92e2c637611ccba66ff9d2ab121b40a85c5b71454cb0dca1f098ce1be8d9ea4933d1a91bcd270c5a33687835d6e4 ae39568caf8b46803f89f38ea73752b1459ca5bb4cad26ecd08407a4ad6bb790355293b86b4a7bcbc111745ac52257dd0fbd7e0e3c9d006fc6bcaecd29dfbbb644dee4561707f03df8095acc163c813539c70c222f929189b146566a65b25ad2 +cad58ca7a3b9967dc0ab62a43037764f8074ef9177d60bd98f623d693333971c24a575ed03cb61f4dc2e3d6285fb1204502a540f3c0bbbf23f5bbbd1544f322ce35d949d8b1d8edeb82e90927ac67ad49c91007056bf5096bd690d15ac00e1874fe33293d8003a4a2b094078cf09af799dde384143350c54a99e1f99cc31f2d1 002c438b07c6e0685d1f94a4bbafc013f8f21265d893f54e54c3ac2071606ad1ffacace0b8367aad724b1d9508c65ce52282e397 a1cfeecf6f2956dc0975836c0a8c57e9542ffe9d9132caa583d99f64b5f3c7e6c0baf83122a56fc2ef30a1761f7a917501feaf4264e4f76ba3ccd44f45137d80cf7ed18268b9c4b1ad6a5a69f11bdca0e0defed8ac87a5f44fa975ab4b9b056a +281ce2643799bbfacc7d5993683a4fa656040517854f3c2dc7c4f8848dc305382e34e894d433caf12d8b493020a6a08d1fa05b08bf6c53127ad5f33bbe75b9db0615e3dd94408d028dcf3cb7598f6e7cb4c787681dabac7cba2cc06fccb7506fece6c7c1c1bf622d525ae9737085ab4ac578905950002024f30159cf0d99f50c 009e8658f8f9e6cd98c0f4f0fd20d64d725653aeba339504def17f3ad12a63dc6157d80804e5f43f4ff48fc5573fde2c615ed31b b3aede08100fadec9fa10e00ebb005fb25ee4498d00fd14d3f7807b92464dc76d7065672ee2cbd9872ff2b7616727788081c5ffd42a6d5e7edd58f9befbcc6c41b4c80d48b31b185c863f3dc43bcbbcc426a65dda74f42f9a71064265538befd +0c061da1a16f2be130ae3b20b89745e840bee09633fb49671db28ec9a051545f57ee07e2410ae7ebc61c9af79868d3047705bfc64ac0c04ef0b286e579b650c7165443631e49e6a53c84cefa5625b1e1035a6ed89b8e839540040151132a937666524265e099272c1849f806db0fdf2be64960d5b5853965099459968e5beb32 00c4c13f65eacce85a51881caa6f82d9e48ec2ac574947d2751823a7f072d38bd9da0cdf30b6f19084a6d291052e7bbc2e1349e1 839f3aaa60303b8849b7eb1262697f0f4190e2f468d5f210807e9be0671be0541cd2c038d0caa6e3e7b6eb75cff31d600d41a1b1df629aef1a1aefe1c64b781603e82ee49080e54e063c71ccb09b852617e03aafcd3ca42beda5f4a724b26762 +74ac2e1303297efc3ed8e624722df505df55b7f33964cc0d270604cc48b58205d8a11952232a8feb0079baa30d7d33660268b56a5a3dd90105f0703abef8f6636a99bc63bd47d9df100351bee32d8205dab0dbd2af36fd173409ff8d1fb7b24570f3c1e968458f58aea5aa2f46731ee91ffd6d3a060af6b3d5020daf1362af3e 00da591461791ae7847e6d8dd8df46a63d3021644abe9520e158406c96540d8fd82ecfb1c3f6f5cfd7688c7656cc3e3dc94e586e aa7e891d5cd76a37a53ec8e1a8a5fab436df6583b3a572c5490362bd59685787822629c9d08bcfffb200effb1a04183c01657b39ceb478e8120e03a29ecd83ef311144c1c4292a64f60954aab45475bd7bfd7cb3ab56183ccd633fdef6717c6a +2afd17344552ccc577b0118caeb7dd56a0766e25f84df17c0505f9798931374b48df89a48c64e199108c36e00c0bf00a97ccde55787bb97c6765601765ab5417f3e75e35a9fe5e0f85a721d9f08440ed617afcdc200b318940a1e496040a6ad9090476b0fb4fcceee77b3fea11de09e7fb14853d1fff8ab12d66c101257e2d4f 00b5eb943f0dd390b737510e2bb703a67f2dd89dc9f6dca6790bc7a260cb2d0fb8e1a81ad6009ed51010e7686d5b48233c6c1686 ae9add6a6789779805a0e4fb010c305e6ccfd61521affc1976e47040ee354a894750064d45445ab781998e0d9f4b412c152247eba4dd3d7887158ed9c3b34c18585aba2d72a89c7ab8769b11f9e9b2989cbdaef0a91eb60304d4d9a65639fb57 +174b2b083541f8284645a810801e72631a11bd7bb805f684a7159e055afc44357f2c80df2b7853678d34a04144e0ede2327d03db6df23769ec41194a8d9d86af74d51c5bc11ea878c6a80689af71d3fdaf1c651003385332a512e03dd040c33d9c328ca89ec7ee9026bbacf30a7f3a68e0d894fb9f7100ffbc64bf17679dedd1 009cc63f32152284fca27ab2837bf1343144336a1fdf15b9727c47e877ac69ac9cf4c97b4bf42f1ab10d73de8597a554ed099efa 81fd584fa44551af01b426507694126e8760bcc106dfdcd7bbb3b9737b8df0fdcfce03ef495de27241d127aefb9ea22b11862f94c2320e12c004ea137fc773b2534c6607468fe3d141a8c5fc2d98f6d2e28efb36fdbeed91ac52f4e84f90aeb4 +758df71a952cdcffdc417b9fffdfb57582ab5c5473a8bdf0c2101953b023b77824263353dea0e2ede1f800a5757ec6ac0e1e4e3ab5a4cd85567d2d19acc6b7069a6e7368401cba2b6e642373654bec0ddd19fbf032794c15b7ef7e714e13e36875262c01e77766ed53cbcf735936dc9b33eaf2152a396349c82ca0297dbae4a5 009950355e8667bea8bbe3a2c4988436ab5394551b375e27fdc0c1a1d1b07ae957932f428f1aca0a486e54cd0b5bb0a5c5650641 8c270e84c5379e117c0ed356abf2e34fcc4d821dae44b5548c9e608b8a460433ea935c83365eb05bc85ce9a68e245aec0e946478853e07f252b1387c60844be2d5b141eab454a522321457c6a829f3a6260da5278d48b9f7766e212eea315526 +b96d9f66b2000e9408d602096f032b112f0e05ea874229ab9daf6e05bee49b4722e4f2d8bf2eeaab9dad94438c76b7cc64dcbb59cb4e03f9ac70487a1d24d8d6b72d7462fe738a17edf381d52179b3acc0c0177c113eb4d10e8e78041deac1d56abda0ddf892edb8be956d285e7236bc6794168f8a180f622dd5f2b9e690c275 00a995493d6971c2d7e8fac3da9f8c0b5afd877cfb94924cfecc167f9d87002136ab253e3a4f9ddf5c9c99bb1dc1af0c6a3a3c4c ac406757ff9b5f6a4ecd1a6824d592941a09e63155ea439a8209a74bf537049d52e3b1bb09111beac7596ea032e9ce0f0c612f82a40001dc209df29f37aaf511fc1c0a0976cb73e8f64502e33d1b97346b30321e2268f9fc7b8f3b984ed240fb +e7ae60ac55e6ba62a75d5328bbc15269d4638764169de0bf0df043d15f9152bed909b1fb8c7a8d8e88ac4f552c1092b62db00958a3a827f64896f6de4bbd8fa5258d6c36e3904d82d3eacf6eedba50b0242eb6b01212288448c3a9821c4fa493869c01149ff1850e8115cf9de1618cb8744626b1951d1de305745507c8b21045 0070daf435cdc26ad66c3186267ad12d10f28d32d863f950cbfcf042fe9dfce553750ad098f82f7f1650c1126b3e4451bee6e11f ad0162b9807e2e766bef56e9c36925d319fffe9825ec26e815fecb6de0a35a239f84057e4eb32c4a2fe5b2495592376a0bbbb9530d9cce1efc3933199fa1c9a7ce7bcd68c7800f11b9ac064d07322067dcfd831ece50570da0cacb0487a34750 +666b0dc2ddffaa7ffd57ea3b2768f02d4b77c16fa007c6d1918400d195f068cae2dcaa69817e6e4c70d5b29c5598efe2d957bd12d0fafdcf5ac52dee80a2d46e77fc18cce2a49bfd787ff77b942c753974d22434742bdb494590d17c42af725b1309e54566276af3bcfbf5e174d3cf191b85903faafa1583282c97e66c5da6c4 00f8121980dfbe9ad0bf92383c7cab95fb72d5caba96e1de7772c6a179e85414802fbb86d725401451329287305570ec7fdd873a 8eff1e2a67861e19a29606e48abac93c4113bc26496d91f35d70e6b4f9cd9fb734e224c4aa950fdc3521ae83be87fe2917ba86b4ddf66d64368fce14567c1908dff200e983ea9506b276de28895bdd6258a3b5c34014652a7f0be1cf06c52623 +3e967cbc2bd936e0b6125dc5cf885735bdcd2d95b2f764de6931c4578ac8e0e87abdf96375481df67dbe1b6c43537e84ec62bfca6672cc5f3ea4125abd4a4119edffe04e42411d338e8b10abb1f1f818c50a9631a3f89feb5be5367bdcb0a8a82c96a427ba6ce99f9631d4411a2b7f5b14d32cb3901dc9d285e4cf5508940942 0047682b2e3bcb5800a531858e8137692a9b1ee98ea74e929ce4c919c26ae3b3f1d4122d07fd9a70d8315fab727ccb67004187a3 a80d4ed4b0950382062c01920cfdedfca9be809a54cd58af565f4e17f5f5e097cd2c0c3a34cf76f44c29b7b6fd368869182cc90cce01a446cb584267456eda32e248feb1b69b4f3732bbafb757699a97f054dcbc4c965d4b34c09d4df392e6af +ca1c90012eba4e7c5f01d8cb3814c58f48c03a16be6ed86934014365eee547070b870d1d26a872cfd28b60d9ee0a66dea223e9eaa90ee28076188d6091f26f665684f4b486af70669555db9058d485c677b2a34d4a98aa8d6f43bf6f44aff2a23c5d765e98f0438ab81be0585a5be29daece5d4116f44ce6062753a3ddc505f3 0040cd1a06233ac27f3ddd108de7c6c0982793ee620d71982697713be9fd5143658929924cc88747a680779bb00da8a44e1e7d3f 849f698b1764e486d6ae20fbbdb45a1ff56e0be8e27df3830eaab755f38c702d2bbbeee711db22d73b82df3c94c4c33e06fc1ec6cf04f36ded2a6aa9b8e87c0070ff66106061c4a2a381d5943daf19014281913585d3670b2a0fde584c5d039b +a54c4351ebdb075d6a42a787647390f864b2bbfd8bb3d0e0ea9d767200fa344d1a9ff091bddb186acd69bcaecd767068efe4d752d185bfe63f6674279d0e7192d2077c400bbc0d5599ee28507c1253f05eae0687b965a015e1f3a292b4650106765266f5c95b77ad2d82a6a6e012f233169eb6b8d83576901cfd4a927c54d7f4 001ca6f752aae4eb7fc9c73a08d6fbd96bfde5030d759a2507bd45b6e1d1487e53abbe98fad4f41976364e0a1d830910ccf97abc 94959743eddf802176bddfdc6d5f1bdb8a495233c493845f81f807d5fbfa55a416a6d8b40944190a803000b442c173a018a5a9ac1b9d272f16279d49f62e7cde1fd86a30737c7488219b0dc18a8e7cebe29fbcdef5f0dee0e62b319b873b3f2d +6723dbddc8720feeb75e2a061b7fc49079f999fbc79ec8a8e01ab8d35b438b7049da5a23c49a58101742791f84f45d5f5cf551cd7de6926a0e2c4ffa1e378f038da597368c62df8cd8349bf046de46d02183dc05b3a3575f5f232dd2970057200e2c9cb60eaa6b4d72f8b73d4d40b98d1cc801d1a69cb5ed780a75a4064623b2 00fb9b1a9597d216028902abf743d25944258b48c9762d4589fe660396130b75f6006cacfde60f6204463cb8c18b032de1dd68d2 8c03a65328d28660f5f7679fc21ee1b16ce8c505b889d9e2c5695dcb8d39bc6ba85d9ed38621b6541c5068f8c74d528602b90bf166781c50119f41f8307e6505dcf0b2d2a9fc30662bb7457439f9733261a1e927d06c28538e40c9cbdcacbff7 +ed53cec5e5500d62d38c829002916c657674ede4439c6f405ba672327ec677490e656bdd698f114c2ab5e6a1fc94a1a8d64466cfe9eaabd23a8b5c37f76a3c0decdef73b3e7b751cbf3b0817f4079560b5ea34cead88ba374201236bffc48eaf289bbaa4e828afa7d732473c228ad00588c9b443d65b998f21c3d7a9e9196c08 0032109202d754da290c266f74f47805a06e6b5c3f721a72fc97a3bffeb8887e0c642d49a6bd034847d0a5ba09239c5dfdf0772d a62c7bb40060c6eb55a90974970f1336303c4b694937da85ee42dfdd5ed329d3db138399942f798c9e6b8571fb154d8d076790282b020d43be22c8c643ca171ce24142375a85555c5a44d0dbb4cab0711a90b0ae0d6c9909f3be1798132b00c1 +13829401bd41e9fe01329e9f5a002f90f1a6ecbf25fc63e7c1345f265ff02e496230f706c6ab377ea52d8707b54f8fc5c7f089044e2bec1dfc66a07da76ee12fb9ea0697d87706b0ebf677600bd2fe117f6cdefb8bd636a1b6b97549ee78f992c24acdf3a946053f06fd012a9c703efb8bd929a66aa74b05d61bff0395232b00 0080536e820fac59b3203aea928475043b2576446619001647e35693a9e65d15236c3cbc12e1bbe0eb305973535c882b70197a92 9194dee11730ac6756011a98b9dcfc0cd40595759336cbb1f1fa698088b2c1ea626842c3823d07831d6720c8811ee6810978481bee7eeab30a5d753da7da9291156ce9c279adcb983e2e8d22f86e6d96fbc530caa63040f82cfa10bad92b1502 +e696acdfcc96a6c088069b7595ea9516a36d8fe04dedeb789fbd965db0cc64b7017a821015f6210b6989e515def5a9605fec0d337e4ac59f3101a505168bf72ab6d98ec62a71d2f94071fc05b95e98d4efc59fedc138e3e49c5d0b44d1f48f7b1e7c1944ee189b242950d2bc804d31c7eeb45283c84638f043ab9533976433a4 00b05e5f0dad9583ea18fb8fc4d8c75fd2e3cf9e92cdd9b737485c953620d345006c31c288b380258b6500b84f729ce6730e5303 a23ee2b7779dae940b50c4f601b702f4249c727cb5d8e1b38fc43885c22c17f450b3cfbcc9510c35d4a6ce35b7bf400b18542874e3f84d60fc0da6407b0754ad5dee64878766a2024c64b0cb15d6d8f20e976031acd6f3a22f522a1f97bb2b65 +4058b9a8cc15ac148909eb97fa32aafbb6077b168dde91a411dbc973df7db056dc57ff78f0abcb70f70f800bd752197d681f44df4a7817c0e7f60f8f65489ecb6167c14b525e91fd2cc5d8b80ba380a83d031d5827c8b1262c687c90ef0e62723d9b565557f9f6fed0db48f3799274c2cd60a14303406c35802cba6261121296 00be1d277813e79051ca1611c783d66003ef759b9e104f32298017fb97667b94dcee1ce807dc6b4d62416e65d4120523bf6a4edc ac57cd10006a725da85e95d50f7bcbc3de62c57c092bdc55b3248162c440af1d7c76e76feed2faaab2584e1d88062f4d18ef1ce289c67a6fe30da00319c0fa5fd31a8f7abccbacb9e64f5b825764af6df541eb3f4fc889fd4fa8b341c5e3a6f3 +e793237d46e265ab84ba9929b196405faa3b0e4686e8693567e53f68e6991e57677974677682a2510c4c35b1968a90b32c4941af7813775c061c008a60f9f671cf7419c94253d6106b61e65034497f2d273a5058379bd986e3d917f708f0a2bebdba150f6d78a3af9c722a2430ab0f4bad602e91e18aaf258e3785fee78e4502 0073c807bd7e07379782ab790720de4ae5106f16d34e80ed70da5b1594e660c9b775db94066b93e74f855f57d88b6ecc6228aace af1e84d35f6f8c945d5b45b7eb53fa72521a481a862e8aa9997db04f5f0f8d163c7f143acf57d660cae74a610265aae60aa4cc66c7c87c7e41423b7cfe4439748b86379f62f5236be386a69fdf462f1c83c5fe82c800ed9f0054aa172a55a15e +ffb8bc80e7619a562d8506eba7658bef0c25ace3dc1d01bdc2ef00933d4fa07b80364e5e5826074edd46a707dbc3b0ab19eec7ea8990839d7fc0a80b70661204c52bcbef57c1a7bdc861c10766033a82dafbead283d911a9502d5f9ef0a39d35ef26f3616212d4bafcd413ffd18b424fe09b48ba02ca5d97ec996205cd49d22e 00a68379b2296a6c944ad5dacb593b302d8ef0b05873ce12bbc371d705f308c739d21f343349524aa72f05341e64f7435daef112 803960f24248f8eda1249a71cd0f7ada5194670a87468489ab8ff79c0b511ebecfb68cede056ba7a44753a259a4c9c890aeb340458b1a84358ccd04921c5705f8344f5b833ee2fc9aa1b188e110505882ef5ce437a75ffcdef40070451b2554d +946bde90a5b903dd281a51d7fa93d80f3fed07eaf50c18fe9fac5acf67326bb18effa3144e25c151efc006a50a274ec6c6a5d573051c4e2d117ceb0fa125acad07a10fb6534a8e5f5b3da2a1136779c51377bf76c3a4a93c0c6158f729f2293e414fcb952c9509f228c804f0adc1daa327a8991d48ccf4f3957c5f8ccbe3ad4a 0026046bbb269ddb1ec14ade56175482343a21b7c265026cef3c7d6a1ae0f6a68166b9e6c49a6e733ad2ad64df7137ef230038fb a3eafc5ab35c241fda6cab7a301beb64907e2cd7288f80ca9133fb1a3c45c56858fa760b2fe12762f0d1bbb5e9baf6a311bf56e5f99d44012b65d8e653dafc1c71accd1e4891d73df2e7eede34a81f6b65d09306be04c89b1dc79ce30be49184 +07f3fe1369ebfcbcacd66675bd4ab22edbbff72e68709cb57d4f590e49440f01691f490c58b5117bd24aa2fe2101b59c61c417c918ea08ea34bbb9b8aa17491ae5d9329affe894f42d7586017877fae3ce35bb80c97f92a004380374ec91e151995166e14ac00505fd1fa810cf02981bacbcebf5f81b2e633d3a3db6737890f4 00bbcda66978ea526f7bd867c3303b625f11b94dd9ee6e2c2f8688ff07f2bba83c662949d47ad47fa882cb7d203a7f0ef5dbc52a 8907ca3963da08e13f6d3fca2b31050bfb8444d15e6acee1af10f2fb9b49ff5f777456a3efba004a3f61eb8f171d094a061a860b565e1a27a53d7cabe6938410a594ca0dae1c5be4cdf188151bab5de8fa0722cc542f9dabcf6c532687f66399 +3a1cb13438e3bac9ad4ab1d319e90e2c9f118dcf1eb54d6333c674a665d41451f93cd4a9334cd057a44c010edb668254517a63700a31eb0ca474c84873e486f2f8e158a1a7735362ea0cff8ef17d959ffd851b21a91412709b3c729474d2cb40f6ca0e397030eb2611b402916e4b656f0fd868247d80be3ce33d52054b7661f0 009be3dd3442e0330750f0a6252bf9cb317f32f942ae516a4038dea2c40ca6484fb33611bef016cc64baf166c122e87c15466fd8 806f17eee9c743597275d5fd1a08bdb78e52fd33ce0fd87f9d737f9601cedea2214b93dd711ac7e4a32e719dea9e6d41150ec4100fbebbaeca5a41cd8e7b05abbf79422e210d568f342ec99633bb79ac8fb030b217cc55e741be9666ad645687 +e58e7b881a563d54772125b2863718690a5276c93d9e1c5feabbdb5d6f7c7293ff0f89805b53663bb417fdd46874b8e6a466e7e3ff6737930a0662af1d5879b071b0dc4d014778dff26a2eca5992e763bf4c4698c382ac947215aa116515876008a56e5bf547857049c38a2d3737ed3393705fd346897c3beb80caab88e5b8cf 00ed321fa283c662e87eaab99b7715e6cdc9b42e14fa5bbe2c56fdfb381369191a42da7e574839f90a85577485f19446fccaf6cd a269fae89093933a64b71e188b98f6454505d2df2b5457e73d084dce6b8f7b84c6d8968b98115b1dc0d7bb4c0afcabf7073c6490b561a20086c23333f24d9ac01aacbeab4143d85a0b313b8583af23657100cdf715c674d1d66e066f9889b222 +8889ea1da1cbed98963941f6ac24f47253ff6af52de920765214f2024aeb04f7ad46936830a8eb04d95aba64ed7cda6ef242f454b67bc2de38a46b6524bd5c96739c4b580e89829a61a8249ec8dc27a50f43b8554cfb6f4fa4ca6875983d4b60a1c6b49f32ddff6fac0cafb64d55c6f594b195c207a9bd920dcf20e0080920bf 00396b805073f3c3b552b1024dcf35559ac44f255b688871a3c6657f727a4b09f3806cbb75d26a00ae1728be632387e804775a8c 90526980a09ecafdee0d6b7a3dfc52882eb599d0c9bb458ed1d020f71e912409046fba37e8823fd7d13c04ca1ef3c0a80de5106c279b872d76bb4bb7189ce27b1ac64b3537d8069a0207955621bf18c38f153d8040427f98a4d140e19b0a280f +55053af9370901e38622734a5bc5589f6a20e258627f381fb0c366f3dbe58394e5997e978eb7ebbc530f6e6186f48294149b8594fb551c31c50521a8c4d67e5862921695604afb23977b6a69b21abe75966fdd11bfbdb6b51ab0a474c5fa07c4de7872a3bd81acc417655090558dfcd5af449b3347e61fa9e839bb9457de64c1 00a8fe323f6736bcabe971c7d964e75dece70cb54561da48a11c40027ebddb23e41c7b48600f569500fe8ea2abebdf480171dde4 9111dc8104e489c9ba62d1c3a4ab9ee028f81d0d284dc54ef5023362988669eef27307b512615fdb579caa880dadce7e101614bc478a3f6d32991deb66ef1584362e72e1e4c229d15729bb2d1e33b366b302d5fb403579e1992e6d2d6f835842 +c4264330534a6c2bbd8a3b757e0912558302ce302f835ad8c5474993832fd30036fdef40b10ee37293e871db5b0b149654f9e543e22111f9709ef45732125f713c031ccfbc9a2f3aba160c241d27be4dab87ab2fa9a795752ab2daf20f9d06a98d90d01c07133adfe83cb11d5176525e1bba6a9ba70ea48b224d46ddd8103f65 00105938ba9f25034da3e032dee121bdb192ac2128b50a2ed4bca042e96cfaf4660c9d35f3e67bafd4c99f9447e6dc408e0c4471 95241a06569b5cbf8ccb413a82c17880e96d179498d9cd38e90557f2b1659fbd3de5c01ab3e3b9f342cc16f951f5d98516eab9cfb0e8a7262fbe98784f23e46e99e1ad38b3fc84a199cd24d469bf25823955453ade65050fb69da9b72dc88763 +3236f1ad164e1b25d828f5202e3513c80c72a577aa9af56f041fd96cf5a3363f4b827723b1511a2f16360e32eac90ac55f4ee1146791420ef9e2af333c17d157b00e43992ef6f2be2d2f211361e468413dd93fb69232f0a0d110bc5fff361c0410344aa0636bf809062c73a7ac7c142063912b6ad7e1626fd2a384f35faffaad 00ce11677ca818537dbaeb880fc967dc8bead203a2538a55e756679c4a9e7975b9b3e6aba4e6c6eab4152d0c0939027e9b0bd92a 8c61a49cdc5dc7d04d78b5353421b66b0d0d67c22918e67955b091a6fd6441c5244c00de781ac4252e4cbe4ccacf98fa10e6e43d8386c243873e28853b6c0e7148cc14fde654782ba6613d4593479662b3a77fa3b04358a5149a796682be8285 +6c400ed098d8369dab6fde3553afbbd4d47836d0d12dd16015f15cb8d067a39391c85ca4e78c62b8b72c1592349ff8dc52db8ccb7fd80c085fae456dba6f4a2378e184dd59238c92cf04e40d43a66b342d2a1325a0bab12b1ac857f0564c27b35e6abed02ff5bbbdc3770ddbb2ee0513df48bcba925da6d61583076cd3129603 005a239ae0f40d76d8d3589f1662b5ca12176a4b2784faa8339b54e96a1e1294433a4d83bf904196f939bd8b33bdb4be340ec703 84c2b78ac2ca8b8dee625e678a6e15eb1b5413e7ddddef3b98152a42b75eba2a27ed071c5a8ba1137c56c4b4f19183410a4c9622dfa42a8a8661fb56b461e89b1097a078791a520e32433f4619a6f91d7db8449a1cb0681628410f20ef4af680 +039a149eaef2de30b0ae457b376ce6fbf88afd4cfdec02d3c5e00400d3b0484c1cd6ba74db5de65d6f2fe39871349b30fdf1ef29bcbb9e182eb3ec5629d07d98354a5dfa82d7f0db3dd10d1510c0dce086848a198893ca5ad24a663494f0596b4eee86199ea85e7e8f2f76e7a6bd4a052c54287f61b391f1e52f96b606151c34 00077390c62ac41aca995640fde0c79c76f4ea8a8dbb22323ed812bee837ab8798c5d0ba976c7aa634d4b1c2c155de2709e7352c b88737d086b73a76da6f9422bef7b59ef00c66d6985e599158d7ade4f1a19b5c4f8ebeab098275c727e752e525d61071122cb7b83616273c31d49872db67731c909cbc4dd9fe5b906c4edabdfcc43db99062a20c973e1e80aa2f38a1f714a78c +08617d04fffd6644c40f7dd57919f7dcf3c888f4147535d12ca658302305bb8e220bb17ccdc480254004b9035b357120580882ef86aa5a061b2850100285b7d61588a664dd4f5394f5478e68a80f610c9204d056009c1c9e902161eda33ef61aa902e96b6f094a9f053135692182943d38b9763055a38739a2a2d133c5dbee89 008bf23b09fbbed1b55769907aafb97f4759cec98649b2c9da5157517d4f85bb70157076b5e4aaa7a940af042302f8be06a84ab6 8993253c96909de8fa39094da1c0d395f66f0be7e40fd560aaad590aa32e573184a13479fd59ff19f96ed7496a78ca141396af8eb33f802f64083c8b608c9143c1064a0afec8feff9784bef9f40f00c5abaac70e5d45d7b0a72e13f2052f19a2 +34c959f549a307f21b850ae105f41299b8bc94fc292aefc61aefbe0a1bf57576ba8d9b80caac635e4edeb22530163fa9629665fcd43959f68eee32482f1845a78ed7278e6e43d09ed6fedf465001afc0d61f1d2e1d747623e82a762576b879c7024e34f43104593cdd691d53bccaeb8f212dc29bec6bc94cf69d0a8491db124a 00082ad05d19b8e16f80e53a4cccf6869ab5128c5e622ed146fa8555985ccd2aa3b9957dd374586115d4d75b1c01cf98ecfc3646 af6cc8af6914ae92dcd33e8c86983c4d3266ad98f2a8e69b22e1a6091e3435525b62e21156c37f03cba288d659a21bb212a4ec0507114caf96655bfe144b46d11e8ea95650873bde0f7233618134a5e6875d9ad8d914795df4eac5c52d4bc9e2 +514f4de08a6f49edbb6797c9dad6d33bfa367cc1a1b58a5becfe646c7f3352d5c5d95f7456e7112c4ddc746b9076b9756ae3916c07bbe6d3823895774a42d25d44b3309d18bfe7e3ccb1f85dacfec1654778c19e2981a853c1f40a7eafd16d331093110698c957fe9f1d86582706a6885543248b944bb70cdf9d2ea89190cb02 00af7e581aa4f9be5815f0c447e39de00da9194eee5e5f609668b9b69930b5b48a948614c2250260d1917f0ebcb00ebda4bb52f8 9159ee265ad7f4376e1de949175068c65fa26969c8a23890571e5f61d634cb88f0b39b2c28fb0b497cea82019fc8a6e103e476933fb175a6f71b089925d02acc026b1fa65a3cbed448c1312a0916a48382776b0c39179ada00c4591ab228479a +4e5d16cb1dcaa1abab1e371e1de02f31ef4e0944dfe1fdec45ab64326435b2af9aaf1a6ed8fdf1a6ab1182bb53a844c7cfd66da30aec0d41757f5988ada0017c4ca752597a9fd3637668bc1a92bb1556553f28d66805bb47f1ef91908ce098d452872da9800e77e1fbd43ffb0ed6fe6a62185d4be73ae96c9241b82cefb2da22 006d14107b08354e6a41d7d7d50c004419db8bdc50db43428df5e86084551237223c498bce71a17e25695bc438c5c09e009c60e2 a08535a0c03df99dc118d8d40b232d121690b66d373a1098badb1da3c341c72f966d8fbe15b8cc2f2b0f390a981fc91e010b75fea38bb8eb7feb6e9910406f005d3d7e09df262898a26026ea50032b48f5f59b9f7847dd4ec6545affb2983c02 +e29e75269754ec1194270f5c9e8267dfdd8c696008b5ebc92bb840981fd065672f07f6a0f1b19841adfc51b478371e1a0db9c3346a9f0a4ccbdecb7040191a00ddfd0a8faa0e69fcf544319c0155d02797eeef99fabbc55078f9d852927c23fd931685424249b87ed0c70a4a3e2d3b9a2f92830e7d8f7650c0bffa8f8986b7d5 0099d96d2dc9c79549f031bd5346cf6a8544c312a3fbfc560dc8e378efdfe025b0e6e61e09c04c8bf4133396f993b0906c33dd30 853605217120d4f3dd87ab5bf2ae39483d43e1edf0a2f42b0c4efe489972938c777493b866c1261e2fe28a64ef0bd81414f1b357f483274393465cd8764013e0c5692aed75c7ae34d5c0e3bf642ebde2a0fb5746d3b4ac5bebe46d813ce314c3 +1a538eb447c18494ad5a5ad27be67fa60eb2c5cb2404eec1dbd7244cd802b17ca5497e779d5f779b981b165dab53ad19fd7bf2ea7dbb9b4baea782a43d758202f147e59d6b6b8ed54f4ea084bc18519943f6894d603e253ba3e8e339a6933bc3a0a47126087038e1c813c3f2997aae321b7c95a802b4b73fc7db95897b7c91e3 0049f347dfd361a65910e97fcefbf60013a54837f2ae657d65e02397f59dc6bca27704fed3affdc3d833fdc621cc5e5f99b92a63 96f71e27d10f4ff9a5d74a370fb9d0e4e2b9ea6a8a8df9ff7826fe45259c673c8bf72ec61b96541f353facc0ea279bb815c3877a10ac9cef5c2296159e115c6f36e295e6d0fd31dc9731773593c5159bff1c12f501d45db96f590305bd572b8e +7502c755bbd385079a4001b8cd653287dc3054f3b57de19d0ff8f63c0308c64c56f035117a8971d43654f89b52e923947e4760ac72be073136da70c5ad7ca1658cc0a2d2a880d3a0c0fe636fdb27b77ff260c4c1ef8a18da8e9fd777d732a37ae9906e6c4f381f0a3d941048d5a1f6f2cb8593873fa4bb1621a44bc2bebfbcd1 00dd226de602af4e9f8e25784bd1bbd4cadb0a8aef525d5e2d57b9f3555feb698765672c5099a7d6dd5faaded69d8d68b4804f26 88213e103489f775ad595271a22614baed00056d76ffbf8d6dd9943077dfb92fc0d3b824eb4fcf5f727edae2c401455815f6a435f765e4c84422e74cc149640e58d3b9606bf00d65925974e4f9a1001157aa5c6d1856c85cc7d58a691509d295 +95eca932d03f1df2e8bc90a27b9a1846963437cdafc49116ccf52e71e5a434cdb0aad5eccb2b692ca76e94f43a9f11fa2bdf94fe74af5c40e6bfd067a719523eea6b4e65730365ee498ac84c46e1588b9b954f1c218920cbf71b167fc977ee2a89429590f43bf637eecd91b0ce3be2d66bac5847205f76c06b914a970f543e59 00b6fdbc9c8c76cb2b822a940d8675889ca6f5132429da795462381ce29313a23bc132976fbeb346ed4c691e651028f873ce7971 96b8f449bef4b98afdfa841899e83354fd224967b4e91e3e2317757b3153503a23fa6c22c6e233090eae59dfaca967580afa875f4b421e334ffa010017a62270f77de12f80a37f6493cbf8575fe9340c44fabe4ebaf6ccb4d2242f30cc7e90dc +8ff68cb00d03e730dddb05fe0b2344689529096c3da6eeecaf097f22c7fa340593106b1f6726f06b7ce7358edbcf801ead959438a42f94cdb467b3cd5b17fbbcf75739805f9eadc869c33c604cc58f81591b0b8bf4d42bd53a801f0f829a31af6c129fb4f20f1250f959754eff8c629b85a716b6a18465b6495798c0c5166c8c 00203d77fac64591eb9a18de20a9d5eacaa1c3ec58a5ecdb3008c2d642e197141d16b3a9fdffe61429264f5b420f5e9926659a4c 87a83ff3dea5387cd2ff86a8e88a9e1ffc767992e4b2ec22a6da19e4a229b58e2c5a54bfa2676a819d2a9252d1acee6b16db8db0185f97bc31c8fffee149c2a92373ab06ca2ba1808198c2c7b2c12ffbb2e5c940b99144c479232257bad497c6 +01451c4f09720cd53377a5ed04c907a735477378ed960235a833049d6bad6e6e89958b4c4249bf0f6d4f043530c9e5426deb0ec3a12b7feb4860757b41bf602ca95655155356ec35a2db8e2657998f56529be4b714364f83a140846308a2973907ed7b08e935173ebbce5e29afe1444cd51c92824ede960056439555e7e74450 0057a2e6a59d4871c3d547690237dd9846d6d5dc4ec0678aafc9c8669af8a641eed67bfea4b05fd6b3b5357ec4d0caf352691ea4 ad6f79c5bfed3e0c451dcca29b551ca48431f611b16e4c73645ed1fb77079d3c99568c16ece10c58f44d4a1d4263b12b15ad815576a3ef667682b5c18dbdfee605f6799656a33b98dae5b31a96673fb77e280552fc743e32ff05d3fdfd4159d9 +ccd494ca005ad706db03a3df6d5c6e876ef859ec77a54de11fe20d104377df1900b6b192126c598944d19a2364b2ae87ad7fd32265d59e1f22be5833f20767793677b628f18e9619f8ca32f3af3b41c31e87a98d1527e5e781bff33c1a8be3a82ea503e76afec5768d7f7dd1f17dc98a9e7f92fd8c96fca0db518bd143d82e6d 000a3da7a6633608fcee9ce4253bbcec08d41ee6b00178ceb017de74e24d48fd89107c9f2db3556063abe3cb011938f4b4871795 b1653bd8cba44afd120c349094e4b66f994c2a2818beb3c4835ce94afc68f7bbb1fb31e3758b737f40d3d544b88b0c0e1765b0ec683a333643bbf814d4255b3d5bca489e95aba53f57b0ade85c2f6983a2a8df9557c87c6acecf9bf142adcee4 +5719e50d939a8d74efb444eb5a77cda48cbb59e7f976cdb2ea2848bfc558718b39ce27b893c229db94bf77992222d1746f8f52f858f85124a28193ae0da039c53d484681785f3367f6516fbb8a86560aea9e3428551facc98cdb1e9df8e2f37db823a7abc589f667b5c93c4c47061400220a2014197d514217fc252cef5a2433 00384723c8b4a316b450d1fce0b2645912b8acaeb3cad50860cca43bdc0206ed5b3b60ebdc29b3eda305d0d60eeaec261edc24d5 a3174f4694dfc3f3d916be480850b4a7324904418450bc2746843456deeb254fb9f50191bf5f4b73b4b4978fe5619b9009578ad7f4aeabdaa0ae843451e276b260720c77da7b07666f63079f4c11a9657bbc9220d1c3dc6c084a1e8cba826538 +c84e5702a339259a61b5ba8ec1957f23ffc4f1eeef3a58f383d3731bbaabfcf49ce2ebb597960ac5115a2af1c62b193d4ab6c24433d5f168a1752e40145f19aeb6dee889a53a4fadd13eef60e28fcc7ed6a9b8b0ca286c1b3d66a4b2c327a629d15c148049e3a0ccdccf05cf22c31956014595e417060627c8125bd7c00f8850 00bd3136647572fef3de51b12e64b36460bd3a27dc660c164fc705417339cab21f9e1f9be0f3da926df459c5ba58b701d306e67a b7083c62f7281661062dd58658f5c5a00500f7ffa458eb70c211163b367a8b1a5637184adbcc19cb94a7ec5f48b6e5a1050b7c0352bbbf00a772904ce00a0d7db2e77b5c5ac3f5cdc43ae894ef4e907b04bdeaeaefb812f7054444f5e71c014e +c90bf11d04a708e64b6f94d4cca64b92463eae878c377b188c82c1c5f05a038be20eca2e18034d46f00d9a6fc73c4084981748ee9d2915d87aee4e2321f4f9e11c176f01281913e324700d9cb474b7134fcc408fb4a7006acd9e63d4578ed4c2729d8e0d01b1e6174a43a024ad261eb644ae98979c3cdab75af357f6dbdf5db1 00495be0b0a9d357f6155fac008cec90442200bb842d89292fde38b7256e4117284a60249b3101b3f19f778b680c0d1d7422b84a ac09338ab83605aa84bae9cd95258577865e363e66d37cc7f70877ec4b0c5cdc1fd47553d177356ef9954ebcfc3fbdbf014b84c24f1fb6c7f069703d4666864b64b5efd5a13d286813ea825284b604b77e7bb5d1513d180aa6b5ae34df01d653 +e9b2a33906a1079280100039787377c2971c378b92e70a38ab41dc23979d6fb0c41e53a21b37632407adac6f212341cf6af8605b4978c85c9c16960e1674247f1795cd73b99ff28cdca024f5078490513c77114c2f52288f5376872c331151d7b2c08f7794f2c1f9e0d849d32d73636f0aa899988ca561a76f74543b37cbf3a3 0079626354dfc4eeeb51fcf232ee9e6b0130c9bd40f15ed45606bb7faeca8f359e0c3e18bf12769254522fd4077eb24bd5454871 ade9ef20d05dd15c1a69b836e226fe3ab66449afad53190be931d382813cc391e13925a08f79d094d3b5f4ad7056af4d09f0dd9d3d9c4ba1b4017785bac91371008b46ea8ff41a3b0c9678c1e4697cae4e5d30197ea07743808123a2a3f35007 +672db3fb8cc8e5f831be700498d3ab3aef14b7548e8011b21351215fb6dfa09460d18f52c02c8815baf396d856a429bb9afd602a10c213af34db80447f4c06ab4bd28873c88eb9639b199042d4b2cb13cc364f734fd4ab7bebede7dd4da63decc0cc1f84e34d760013f66d71641073f16c08078880b67230f2d6c6bfe17d206b 00ab42bc7d0e3c23f8bcf928e25f9f027b56f270398a1d37bea0ee5426b944a9c9ba6d0d7796899543feedb470f70b2ab148234f 8d94d9f8336e9d85323a743e33bbc4d38a40d86aedb73574ae5cccc519a1eea29a4cd5188d3e69a916d1fd27b2c4bb06173ce8413c67a1943d876ab35d16c9672759a296ff73fe7054afb54d2b525bea95bf67fab0a119f09834c6d3eb2f70b9 +d7fd06b89226cfd66671ce5b4b656228c52d986afa7f6f30161680eb0c9cca177992a8a8c40167a64165c518c55f678702125709361b536bd928567c97737bd750d0e2e6e0c00296a6ca565f7c05cc8c54ae7a4e0c334c6a968fc18a959c18ebbd924457701316a4e999fb11084520dac68dc2d69187134c40891af0355ba89b 007f7aa2216164ba689459ee5d5ca29e70ef75a5b2a4416ab588df1dcb9164330c0b405a9d80c3acc41c19f58e24e17ecbc0fa7b a0de7e0558ee55939e2ed10e290e934e7ead1bc7cef63ea4bdcea1d2b63cc30f39f0087fda46b0e8e6f89dc6ceaad08d1123c570c8b420e71e59c0a66be10f96c620d64c3d81e48b5307683e9653abe854fcaeceae910a9fcc1ad563f5715ddb +83b7e9d3ec638fef51d2885fff5490c94e2509c126608f82660e5fc523032f3e85d69d9b76af145f6bd916dda35775abbb6d1902bf38880f8b9259822055c5b1bc726c51029972cf7474cf2a812f3251aa71813476bff55598d079f075a40c6c41498bd865ce960c518bef75a873b9d010965f342dc4b35ef5c5972efe6fdd18 0021d84f070c6823a70f1a74225a472118c93ce9dc509aa6064051ca4574939dcfa96be862069424bdf1a23f62f2868326422e64 85c85d01b7cb5465be4fcbe9cfb77002ebd368af4254d4cf432a6f7d961634234389ff3888617b7b2c15736b966791510c1288da7e4ce230f4720f2fd4fbff65785edf37949ac2e03887521e1573570e1b837ea6c06987a658dd5214ffd0636d +c62c7bcc860f0e175128e1127dacf935ce62ae794cc4a0ce7966bceb023ac0498641d7281fbc86f9ef470bbc77f608f83f8d0dd6299cf08f2cdacc7a9642e4246df131820220e5c05d0dbfceda7f16b86add4793e9b6244d96b5c07cfa23574ceb43e8e8b5483192a92b301aa3b37702b8f94f0129d8af1617896b34990c9b02 00b6645344d17528968c719091b6e2072388881dc10bdb4c7fbf41906cadf3699b30f9c1dbfb4796d009480664e6276c0359e5db 86d162b4f91aa9a4eb3e1d0b86b645a0ec902ef07ad00403f00268bdca9a7a70f4a2e2239997d19243ad236a5a8bb4a20a9168c2d01ca21ca6260016dae9a74e3818e08b81c5fbd4004ea24a0709e689aa27f61759c336ccb27a73193a4aa7a3 +b5bf38fd9e822925254418475a1ce762a94e336f12b156b1625a4574fee11ee472d537ef94b4a4b1c0a73b0140d0b818cd06636653e6c07f0f100118242a7703756f1cb1119b3477c4ced99cf45e07e83b7f2749c1a5f8d8c9272d221fe17f7c6a5fb0f8a16af46f232ce406aaf565c6b2766a2f6528c82e74fa1c0a7fcfd49e 00f8c2f770cf5f8e1f900e996ecdcd84fcff5cd959777fd005d721a419123221a3237e39834b270d37752470deaa6cea023c5058 939dcb55fbb5a49d529e5cfb2d628122288093747bb77e41ba709c40821c91854406595d7105d3403d1a14c343d0789a1862558291c5287224a5eb2684359ec917c0b10db11ff190a6876813c5e930c44711c04884cbe07639588d1559f1b828 +6d3474770933ec01b76be789304b6fda423b12a0ae8c87a5ea8d7ee9f71300f39440e1c7f5aa4b47c1a8628cfc3a490b15ef292a741344f40a8fcdd02cf3863bf3e32d53031f503703deab17fc52b3d4032f4e237dcc27231b85d3fd60b49ed7ee40c3344948d87c3f47564d20a11d50e4e520bd16c8701694fc70901a5da625 00144adae951fe897d5812ee4a16c0be4c86c5e57e615c398f5768a1223a9be20fa82ceccf8a16a31432bbfd17e594a4cd8a6a07 b2b9fb9d3b75a39cbd76a032e71283fb0302b2db2a37bcbb4610a7df69718518ddeaff6eb1f6ad4956e23bbc4eddf44901fa773dbb09f1ce4e983f82c00f962a5c44b6698b26ffc5a09195673a6ec60657aa61cace4e86e59b4ce81d0a3756cb +92ba7aaf71f625f7a2e024058dc8739da3567c306da4a812ed9e1542b7d1e982c16082166a59720203f4524c3bd463a662c26a82ec7b4376545206e650eed0d3dd7909dfe3810981393070d15c45dc4a75a8c5bdeba533cad1ec34fd20466a61e4cde3b25af9a80a9a54afdd7de1cf2a74ba32d4ea0082a037775413c61a8d1f 00a51f065fb32c55bf4ff6f18ba9d488d35d9f8da593adb0ab1632533284e0adc43ccdbda9d9507b9862ac63b5ae7b0f78b479bb 91e5acc0c74ff0f640384f4cbf0f79d098713622b7013c50d80e64c79ca25546e074aba76e82961a66bac741617e391501b1135f9db4baaf1b9e1fc95ecb4e8cb12b3088cae7baaa17e161b9519f1af0f736649e8b360347db7f55f12a5a58b6 +b3fb9e48c333201324755a81f3ae5d4f0e2ae7cd24238fcc66d858e3aeb1ee03328660d6399676eb1b7d8285ba571e214d935bb45516fccfab57b8eb4c3d5f1d7357c768eb7b5e7b5710f599614bd4e92706eaba31f8a5e7e57af7ed13066af50b4540ccdc126b677789920cef8543907f0ba9dc92aae343d3425bd784ef483d 0095351c0bc07acfabe6477fe85f97eab520dc96bdd58b44b036328ceadaa56a1904d2217c5fd25155ff2aaf9005a3e2687fec81 94fe924dd377ff79aa65376a93d1f6828b2aa8bd7b5044cee33644d7890b6c1f8dc884d5f2117e39445cd807242756d50b2b6118674ddb50460fc219244784b0d4f90859b2ea8b4d5c1ec35486df4afc7c5e25b1d678c8dfec8cfa8fb5f349e1 +9ec5f7d65082264b8a50be772c44277a73ed19199eb275fe5976f9799d8629fcb4a59a8d55074cd2eb2a0e02062d3f7cdeb05e62931a24fd1aaf14c257944d1b42eebd52726d6fe281211b39038e52baae077ea4df89675d860d6ba5a0f998d049614201b872e134367acc90066ac602e478ac3e43c3ddf4b0ca0aac1a68591a 0050245c1682344fef23bd549ac8d1e8e44b2840c43eec1cecd33daa4e9ef6b53f496104d7432e14248682cfd6f5b4853b65adac 922fa26e4fbdcb3a96175f32efa9608944f93cc539a446084f07a692569a9939a59ea2666511143b198425ae0fb23c490ea1cfd8850354047d0794b0e5d4c79de099991a785cc47e7cddcfb5dba710d5e24485c5788a3df1a15177371764c622 +61d657bf472676301503f6784b7286fb39fb4186bb88abf1edacb4a2693d0a1e2b77bbf2758c84f2cbfd1753e20841b1cd4b456400d53f4d686e666943f9b6ffcdb77f510be97536e9698fc84ae347d483bc8984548d1cf86b9b40d360f9c0dc5bd1c55868e26fce1460ba94ef5e94eb63c9f0776a0f446c0cfd4106d9f36352 008d3b0277f0e9fe54581d3a9499ccd7f015c08339591326859af969d2a26284e3b3beac4a0b74d324ce5cb5f38c7995e4e3a41f 8489225845437c9537e65f1befa3581af3afff38bd020ac28d73c1abd35fe302cf1e4c291a6c816b672b684c3cc1e1d701d72a1a4468f281ec8d625024eb7258738e807563f2cc040c9f4c163fa4c9cbda3b6a60c7958dbc61543b02820f3e9d diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B571 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B571 new file mode 100644 index 000000000000..994186265893 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B571 @@ -0,0 +1,60 @@ +8e14f713a2c427b1f79491033994f76acbead614d12e73ac6f3f518f2052a10c1273aabe628ab38e0d3d5f8ff254802e9f44a51367bf80325b6fc39d907a37f731372864747b10749ea5cb3d3a83da39c21a7b02885a8c1770e4397cedc958e4baa21d5007569dc9dd1e45d2181709d900a394454090badbd0cd9c2cd2369aad 00f42afce7f7b3d45f3f925ab29fc3882a89c9f585177887584703cf8bd8fc572e677adfa55b402446fe1e90dc855358d92c3267c35be9674b40c2ad5ce8dbe6a533c44b0ad8d2b2 841d4c46be12646a477706068dc16e15941eb3356bd246601d2fe2ae674762490650c32d88d4b419a09794edab59c8ab085b618dc630e002476424f1d194b872294482cff067cb4a6ee3ade943ad2ad7c17f5d914ea23da72c603f2076ab4481 +38b60d27ff08fb191811036dbfd5b39e1cc3427ff70efb67c851e9cb407f9fac6f348d289df98d055eec73299fcac068bd0fd9ffa3c5d244659e4f714a58d79f6727f323a7ee26369000e90e34e106f99f5ae2ae1b64ee89e5a1d304ef20c071a7773e9b977ed3d49f467d300a881c8371041394910f9c366942449045568f01 02f36613043cbf53ad36e2b38998bb867503359ae082d07d040e5a10a43e06ba9c91e7c73308e41e2391b65e634f83b162cbdf4e7a44ad818fb93a978af00f06be06731d8c5886c6 b704f548348e2067de7b27085f6b5452380b62b528530c5f19f89c5c2250f62f0a30180ef3aac2d97c12e85f081390ce1491e271582cea1b61c722f5ab1f12419f83f7a6396c0be1e49a0be502bc09b5d50c064bee176995a72034cef8646d8e +21709eeaf9e1953822294a478dfacfb205fc25f447a73a76a32601c00784cbf2f9ebd41c22721d70cdb3842dcaff4a4f208d41c0816990e421cc4b8538ac2f347cdd0aa2a39f1aa26ace8cb6a606b23f6244894d4594a0f6a5b8f6a695fd66e1a41e2eb6a377017177fec56bb58c837e311cd04c5b50575faee32606b9636ec1 02e74948c46930cbcd9dbe2325539c7dfdd910f309fd610e6599d425aad9ae230a8d4681970a14f2a71fd08030d0a40ff40dade7de1b06a80441bbf7e2fcf1809cff39c7ef88bf9f 9641df41ffd3103237eb7c3332118b50bb7cbcf2f8faa1415f2ecaacf179d2ee141395af78e0016193b82cc9e77a5439122ed1dfb723ea2e5509c0d043e0f0346f28846536ad91671b511e0613c35da7ec49dd3c3b304e5affd2584dbdb9dc5d +3a131fabf3dc97334f212fce41c44300440d16de1d6060450875f7276f53c026e2a511681b5a8d75fc0d578546339542833145f7ee13c708df33e584445a75a5538829286480d339be7c777c03c998a6d3f037b25799ab2d541021502a0b02a9b9c337a8b176c4f30e5b186485a6103b1d1563ad4ae73ca806a5e4daa92e9100 01b5fab1d36f6f6d559f65d8b01edba610620fc3a38307b1fb1c5bd63e7ffbd4a9098cb8bdf50975a873f5d047ee2b627b090897a7fb5f56d3f4a0f3528179e7c969926fc0d3b0e5 b89105d09d2021d6c92bf9cbd54dfdb875bf98fc1b191bdf24b9a910b3bb449e20521ff4816ca2a13fda183502c0ad310db939449b04d5d6c3a9d070ee8a1a3d48cde8bca1e99c50902e032ab5a95886aef9910c1b43a1d2575dc8d33b1dcf64 +679d85a762f2574b0b31b516270b7d33d5e166c83e91a0f48e0f3db20b52f42f9e6ee9648cf58267ffe3b713723cf3df52b5fab5c14db1e7189f7cb7170bc6ec7cc71946745e152b39180f828688a5b6c0b2957ab94283b90052a3c6e36843c391aa8810f9253b639a8d5a69aec10070603ad7a99dcedb544858d057a1d66b89 0383e70c71b431eedd4574f65d01fb0304f7744d668408c847f7899eae44770a7f3243109740f177d7146a27748886b7b77ecf3792b512e8d8e37c3bf4ecef2b1253df7066498f01 91592afe46e12162b2c7b438cd85bf3bcd28f60bff54462f5e31243e3736c9f9273d518db6d6f5318c1339d8d0a3fb201560f1d424b54ff6887fc4852a63e3373fa29a3895684916c95b0ac661e25e3f61f367aa6c99d1ebaa4e0c181365e051 +236152ad31ce2ffc0dead3c142cf6c770672cd2e75af4a82fda1a72e1c775cec9b481c6f3e411644df7e7ee901c501405620af4b6e9667dfd46091788daa95ef2c6c9f5c240c06b15cb0df51f5f058d8a7934bd7845f007a35f99fa97200b20f3b5b14fbf1e372507f3b2f377e8d07d30fd3e222f398f26d8f428e320327f901 002261d4ead21f02fab19bbb0da8c272286704c8f0c6842ba47ded121e5cddef79fb34e6b9694f725ca502949faecfb21e3cc062a2b4c654bd542d9a1fe8d97bdd0905c510aa0999 8eb91dce8b9a08920bd5f4b762e0f4a8ff535625064732107fc6ff9cc704bcf429e47a8f8d4563d01fb2a3ec058967e2109cd8c177d4be3de8efb04841a4fc204b9e56fa2bd24540435afb0ab7ffc40a78eab629763a15bf06fc08321d744ec2 +ba3f02c4847fae035d747db246fe4e82fb9224ff9cf568a6ae548f5dc2befb2079541d2cf9aaa6b18c281a05e7ddfcdbcefb25f41dd91cb3092b3343e16985e91c912215cd99ae4a099baf628e33a7b277e3c36a13aaef85418fca99f64d73b789f23ecbb76c3095ade0a5f7f34836a98c5be933b44a94a2eaa3f99b1d8e7937 0316c78f289e1860bb623082be9d9238b88e38c5e978a868bb90f776235bdff4eff591877b7f350cf14c40356922b2b6aa51d64990360b2b0e44d6941b5dd9492b4f4e1f42ca163a 8b3335edfc5d45d6a588214ebfab8a1f968713d27aa25aa1c16c389d1aff6ca1d1b5e4aa4c3d854487653d891823732a0ff1f84ac44eb0bf7b602834a374c7aac945f1b355f3dfe9c94b517aa3e1aaaae29da64f592f28b2d2c985de0bbf84b0 +6d0372b40559e075af56af853cbe18ba2d471b0fc8917764abcc69102b03d5bbe1fc12458215be66409c26c89f67c72a8933677a07f88993af6918acb074fa915fe883b24bc3d191ff1b08852f07eda98977e70eba072d8bf189cd545230f59559ac05f1fa3f4e65886d0bc274a6e02e2399812b2bf91abae81e21279c5de996 02c1bc13f8320d97a82f3d9354e195481902214e16a4fd89332a0499208e91d50e5cabeb4927ba030cb42f5bc53b10f500fa646a8c88508cb0d63ebfce5c4bd574c527d686c735ce b7340c56dfbb61c59cb15e6a6a657d6c8f503ac92d00047149dcae9fa1b920d8d938eef58d9d0ade99945a5a927db53e1979096513b2707cbd465f2f0f28f9571305fb4abec22c472948e0b1c42f4ff1f5f626f6bf23b2fabed8dd66b0a624ec +bbfe66c82bc060bd14fd0e40769d9b3a026eb447550dd9f118c30d8448f725f8366edef042447962ba7f7f833b9e9094d0ff600714697e632626e7d12a592e040bdcee166dcda93952323191021bd12f3b1647d0f25a41739994659dcbb19333ca30f46f539c6f0a5c354cda8969a1eda572a309950c84c7607eb8ac20163912 013bd80eafa67663e75d7ae139bf285d2b9f1e03d8e32153c73e26d06e86d7acad22bde9f121a3f1ea674dcc1fe67bc7f5398d5e92555056bc046a02b0ba86c2a0dfe32e91add5b6 b89fbdccf400871ed1e0f8d71b49af15d740e2c76aa27183fcfee003b48c20fcdf9bf5c9c42d21fbf7ec2990a3af692c048ee06d81069cebc4b8d7e82428bb8fba6c3d0ab404907f5491300ecc492830778a758a94f4cc33b1b53b0f785747a1 +b35e9bf686717ce3b16a59963a32a2116130453b161a4e7ceb27b755856add836d779696edcaee3b5c986523891c8836109d431e55c23afbca022437ad19e6777efabb6da3bba1f5f44f905395b4cc7c9210590fd38da621582d059598e5e4569e904358e0dfc0dbfda4ce75538aa97480912852bccd433a9b96c9c66e9597d2 030834b0a4284097cdda2ada6947c6c281f7290a49b56becefea1e2788ea3ef78fb96807633c47c25138341768b241164ce0d42f7301728b928be2c047f2eb60fc2f844ab77306d2 988277c2a02b99116ba8fb18a08c31fda5bde327f6e264d06d41cec43c26cdc60cc9301bcd2683ee78d95a464d11650204cdc78c5f054a136254edbd4151b76e42ac8668705bd5c19b1e72e137b508a8c13b7b80060561ead66fc0c461fc2075 +57b5ae7e95c638b258d1e09b3fcb4341e203f5706862e199b103c8fdac72cbc5155e5cf8b300a0b3fb0ce1f897c45f7aefcc528182f73dd450cd84d5fe9eadff3f704dc2a01b4e847c22df430efd1c66b0199f3e5b59348af5386962a5ef25204fd230b54d58d7fae801c086f8f405d3d0aa7a9a9da15c22b868817cd897d853 00c81a79ced1eaaafc31b69a40d9939f4e484d625db6364a8e589b6b4d336d458b44287ea6c6aa7661113fc07806b147ff98216fa0c08708dc9d651821b922741deda522b4e436ad b8c7e62cb15302c7647d61640b4ee58f2b1628b98a2b3a7d21b606a6fead1b9f7217e9a345c54a92bde05e169790738d099ff0f7a27432d9ea84b590d9d084b97754fd41cded162eda5e45de81ce39e2a5ad4daea121db3d7f4537c43fa595bc +daebfef74b452f039c999ba0528be3bd9e16deb5f46f6eae87b63db8b89952c949fd7db08311871eb2596865eed107aa065f030226ea675ee3256c31a3f85ddf4c21760582144e07af208f33c5f47cc026db5403186a65a47940691ea2d74ffb1245676260ef5717dd879d8b5b72d96f87fef5f762d4fd17454cb5ed83d8a11f 02f24670c0f77d2ca0266a743023d2c7413d56d0b5ec77b454ac59087efc4ea4d46179e10278e4ba416ffd8c3f9786ed202faf8251c0ef5a9ea5371fbb35b7afe3d15a9cb4bad975 8ba23c88e7d07c9a33021ba78b5e7ddb1162fc4b8b016ed63763d6804ce56ec05e0659be6f42ea11f7c909f257fe4342014d279004feafd22834eaa612d3d685fe52794d33fa01d3caf3918ea3b9a8e143d6c13721f74e1858f265a1a92ecdc6 +62af0493ae79d71b552c4647d1fb7ab2f282a91cd44aebd8ef344dfd77b521b0c0a3f72e4513c8ecc0e4b84efef3df9482a07ccc1b740c571c5e69cb913740a792aa231b9dc87edfb72bac188293c6c6e788cb3dff32e8f483f8f34e21ee7efec71302cc3bdbfa47908a135f6ef3ff179dcef26d1a3987f7be967a6c0f799b0c 020985f2c6fe3ea04bdbab66a8b6167e5969c073b9d53cf3c77cebbf73f4dbf75e601620ec9c3107bf3fbfc6c79f8f063409bf8fe1d14b19e323d857e23dc05157d270c7514137e4 a7683fecb597f790c2cdab563786a4ccb57baa024cb756b36d8027dc8907c30c59431786bc3328928240b05a8648350c09008f3f3bd9140cdd4bce32aca9d89814ba337aa8fc946d03b958be8193cc920f7e450bf77f5e6228a6c7456d57990c +566f17851951777ebea3f8285610cd8ee5f882a68e7a4205e6fc9e2d66d210ee2505ee73d6503169f7b903012d43e7e99efa493a8e6ef926b16b9ad8f52156840ab561fc6b680120a88714fd66d1d0742189bf06c155e1138ee5314707173f7352e2cea0fc26e1553643f2490428718e44afd8372cbb7bf5b88234318ebf4355 02b3d641607b8a141f876f6d285ee46aea543880e772dadd5dd83d595b9643191d9597218e1d6adb081df133304037bcd2c05c24a54e6c4cca64fb2cc4569d6882315360059496d8 879d4d1a9e9e973589b34c15d8a4bb7e090e206c4706691a3e4986154b79c9304efe0925aa23d95757202cf75ef20dad0461fcfb25ce19670e49b4aab0de27c61a35dfeb7e0cbae757549f30a77eb4186fdae1b748d5687389d61551264f6df1 +25155825fc4f9a1c4dd1db837008e7e2594a879052431f5bfc76d0d2565b8fa726008befaeddceef73f3c60fa2cdf6d9a70e56d27210bd013034b38861ae49640ef208d3fe294ac4362f8eea44f58af3af8a9167a36b5acafb7ec95652d5885a0e08067ce1dfbb45a0c89ad1acb53eb404bf88fa5c3c463a0f912b5a2522a0d9 01afeb5ca87c81025ddf09c2b2c5ee22ba0105c0e619b67a324467485bd839030d149fee44d8bac6f5902a1245a50c3437046b7c89a84116b2147cddc645b6d2fd24d68e8d53bf5b a382d6ac1876dfcb342439121701060c6f1ab232cf1bcc923a3d85daf877e308fbec047c289513b7340766ead8e9e5e90c037d2a2c8968c9018eca785955bf1a2ddf0dc27f1c9e9321d6fa9fe94fa549b6dd510326f45d1b3532ac2d6bd220f6 +29acb0fca27e2a10d7b9e7e84a79af73e420abdb0f80dd2665696638951b52dd39ca028166b47a3b6a2eaeceb1a11c152383f0bec64e862db1c249672b3770909f775b794e0b9b28a5ec8635a996d912d837a5f22471b40ec2e84701a8804127a9f1a0b3c96ff654700bad3167240c2518fb5dedcc1be9f56a807083e587bc56 032c97639b69c7cdbf419286d0a1b406d9b1f2886521a8b979a36118d2a368aace5b02dd8c515f2041e6fb9f026d1e82e789dc826a56d2ef732b1bb0f49be2b696ab5d3d5694a2de 819a3459628db06189f46302600d733d532ed0d3b6ff23d92d6f66714a16303498612cf3fc314895a40e789d8109031910ae1f8eaddb4ff8286f89e6546405d5ef4a78d4e861486a930b3b40b81224d65901b23f020f9e7f5862671b28d54fe6 +c92d67cf6536f5046e15b02158da698bcbba4ff1e4e9e9c882cda67f817210402ef917ae93682c9c3dd817b21b73c6c00b7bf92ea80ecbbef2e67f4f4379d078a2b0f297742b2bb9c3fa3297a7e8079f488555bd37715eec92b4b1cbf897640ae8a1d2a0fbcee5423ab31a37629f98630275e35094a896cc574be0a449bb1bc3 00f93672159276c5a293582b9f49607bbdb970112f6c63b2b3b5d32ad3c8240c86b1af13a8dff6502c6b6a17712cfd988f8cd23a60693d64104143b3f91adb37f852e9e11a0ef110 a83839af58019ed643e69aa63604a6b2f021b10b8bedded1904a0a9cecbcc198028684d3bfe58745d67985d12e93971b0e9c0e487c264e4b7bc15fd005108f8c2b8ff256e7787fb8ef883d4daa6e7e751d78e280e35b3c6ab311232ba0b008b4 +15413f614c4551e3b138b64f66d15f8964c40326a42b0afce820778eee4a88edb127fbf575da5263e5a2627b5461d311813ea868e6417615e7c4938313675009caac28bc7a2f4c0bc37572d9bf36a3b1794294e09c0121ceecaa4b916df45b0dd31225415e6c87cfeeb092a008fce2c543cd62365779ae28f29fa02a15d9dcd5 03db080bc99c5fe7e06d5032167af56783cb423fae59fb5b3c6bce5fbedf56b7b39b17810e48ea9a172881aa1f42f5e267349b60294d4a208b4437666b44abcfee5a1829e9467908 a92b4767e2bdfc26fa3c31a17bae2472773471543afbec6f7174293313c9a9f760ead84a4157033e966910ad03a8a6a51406f00afc9789ccf9324babf2824e6d11a9483a2f53dc258d72b3cf7167f8ce31302c3edf4f5ee3ee9cb7a61bf4bbd1 +9f901557451ae2f8ec79b6d4adc794cbfd9b2e6d28f19409532d91682820205308b41498a4e1ca247a2baa8da93de95e3c0f7afd6ca46bafdbdcc6d3374a12684676a50988b86a960a82180648c8c1e38f8fd9af604c7be3be4b24799f4544ac96d6360cdb83d1d0847fda21642934fd6cf65385b50d86d4656987901fb88d0c 006ee767f6f36bb8f364f324d8346455c899a49237d759003dd52cfa13b9baa4c71347b134b24ecaee32d247c34e3787a0c64bc5d299b55c86f64b47521d22f2c09db225b0c84cc6 a0fd3f8f35fb871a74ed3b6f25dd33d398dd5d8256ff9f5b18c3f1c417656e83d8da776689faed538bf2d0c6b3bfadcc0da0d3847dc2f6d9768935ee9ea9acadd85bd1bb96b0e925ff356dfbd7310bcef0fd36f62ba19df97f4bfeb37b4c4f95 +959fe5a19d7aea2ba611c7203e19f8e3f3cc101e03a98f91adfef602c424c580d5a868659368a930f9883d699fc633bd07f6cf8de474937db0bea86fa7cd140ec2f202663813033a757b93bd72afba15be5e47a4eb93e8a666aa1c72c241ca3922547d63fa3732fec54afea7ade84302e2f044275bb67433fb6b125b7913143c 038e2571d9f22309a636586d62863ed67a70538287f3ef88b88c3c2fa1a2900d48c342b6f15c26b8e7fb4875cda4093b7de7ceda48fe1e2cc2975afe958040881de61f309931e48d a1a7f1862d68807ef465c19d9b5f7110a717b793903b649d2744b0c2c49cbff68448e25b663ba118ef578fa0f811077f16b39526c18d6cefd804f805395399f5163211c1478d09d2c7767b02c44112138071872814261c248cfcdb6f7890596a +97b9688d9ed5101b8cfb19e84b89cd644262ca1c7ee18944e29ddd3b4cca78e06338b270385b00a5e8b91ca5e628de3bba50e36ecc695b3ea737a9cf8b36871c473a54ba17819f49e730c0f253b0c769aefa6c16366fd2dd612f330e95fb119fcf3bf7f3e254438c0ab635ec04a8b2424a05b483ecf65b74a93636fbab7bf1d8 00c8f5736f1ae65592f3ca850f43d06441aaad8c03820f3b08d8a6db46488dcfb828459f8b3f34af73cce8dc7a5e3834e085a64523d890028e194214cef4003210e6eb530005b01a 99bc316ca2578a657f7c8545985d69edea29c6e96ad51c841f99e26c78de06ec7f1a598c049f7d6ca8794f97d48084540afca5d68f78a72f974dc673d60006b217fadcee154beb99176c7242e876a45ed4f2d960830880cb409323212c3ea68c +f08b250bf4a3980cb455338b3f4173723b3f44c97bacc9cf550149794a71426e398cb4a74bde141d8b7b4a72942f1c069676a9918e27792cb8f085ee037c78e3c468adea5123c4c64d8ca6a39f2f90140c5d2d80b669cbf0d1ccb466b18ded83a1d5f042c36188a04111c34ff769abba9aedda40a87be1e24b700225e2078056 01ee68c3994adaaa9e0d61bfcd3bc1cdf198d3fbfe28a44e5dd518867ea04b20e795eadacc48bfcf8e8216dceeaa069b756e8e99ed87b6b1d31154cc9310bc3b4555162a890b0c6c 981e93b3b0a6997fc0101e31f296604cfbe1bde73a8594d7ac6a5ef6e4409da1488021267aa744e197f662b1d022619607bb86e5176332447fd03bcc71368421e5eccd28dea9cfc227bc9ad213de61ff5faab06d70cf9060cbf86f7eaa95b6c5 +1cabd16fc29d7d919622810dc8b23c770b790b98b119eeab1b20900fa94fc2ebaf76be4f5eea91fc5276c5621c8677d4d117c4a5a782ee2ca1d5b0db997fdc8a05b6b3fbb833d7a7b81c3c615c2a662929760a96feefcf89e46b563314c9b77c86bf34438458b43b694ceba741b97dfcdacc0ed57652ae62856ce10ed2690770 03a6fbf66ebc1365ea7699c72cdac2dd85907ec59cd26e2d18713354b619ccb83b7fc0db9193aa8493c1855f1a83fd987cbbb65de17c59fbe79256aa5392f4eba045346e9ba26592 992adc39f7b297e420c42aec5435abf09df27252689635cf947ea5725052efd1bbffb7ca9102075c1f78e83f128b414f03a3bf7ca71f990a49f0e28f2d50cb3e2cf43797f48864761bc41d22c94cb133e037a188dcb7fda4b7738de40ea13858 +7bc8bbf5ebeacf40b3c82eb6eba5d994dcc6a3f2e12ef741f90f90e176d20c21e006ecdaf14cb5beef35bff46b2c374d9ee224516679b1a9e9255cd8ad8e60ed234f8ee7e0fc53c9021488158217d4b4369cc597d6053746efa1e73340bdd73c1bd2eed57b92426fd4d278d6a86e8be0f0a66ab3dfadefca8831b2f488636251 0145748871a0b5c1cee628de04a12fd68ff2b154fda96e47afaa96389d66d22802968584f6753d36618d49ed205260f09d3f5ccc2b27a34390ce58179b9834ff92a86d66ea0a97ca aef0806b1783ac628d9cf435cf63ad2bff0d3c52a3a139b2c6da8902de243b16a7f16ab81daf6748ef8ab96ecb22851514cd66ad2565870c3cc6c72f970137efb1d86cefeb0225de491b0f4c29301a9cd9c8b8bd594f7aa962aa41f34c81b64c +0cd2a45392871c0c262e7e6f036946354bb41f9c2187b8c4d399231280682f3e0a09731fbfd52c76ee63b9828c2d731f4cefee0a8c46419c398205b2ff80c67d7756db300a0a8385fa287dd37d9126f75998ae1cbab5136560592118db52fbf102b7ff0a1ed45b8a91a7d99d13a0f7fd4366392264aa1248d7324901467457ca 03c71911d24ad19c20fc1d8a044d63c9bb417abc3778d7e6234c6af79b898cbfc2f2787244708d2fe203be786edbdc4c9b12b413156b7b0bab0be8af895d191d853cd58aafe1ccce 91f4b6ac7d583664e19a72892f696da1849c6064269e82e5a2bcabfc3d707760f9ea1d9cc7f350f983bb8cccce2ae9ed12fda1c320262ae3a0ea4eaf8a72614e255de3acd1e27d331ae1e1617608757974100ec9379e62a9ac2a3c81c293b353 +e97092625b09c9ae6e152e1cbee207d83361f34cb9b0e727c816a5ed851f12f91fbf88ad9d4c8f9d07350f5d828fd8574eafc768bc72a2b18aaf4d2b48fb10f7c3431137b51850154de9706487d69a40a8f4cb2c799f48c5d8f518aff752500de93cbb94ab04ae1e0c7183a32d79a27291dd07b5fb6e6a4fab76e85c3a8607e2 018bd74698bac36ef11add6b3e3fad227ecd868f370ec04569462565d2f0af2340bf793486953a7b79ab04f0ab1f0e4fd16bf6b576cce677d543e73aa8edb0e50372f24ddfbff966 88c703a80eba0dffb44e79599b45a9bb1305a26ad85a7158ceb7e88294dae8fc9aab2583527b198eb3834366514739db092707c16e0991e59e76cc79987faeb2457604cdfeecf13a5e36508d66de8a1296e9661cd16c4e98d805efceba89cce4 +ae6723b8df5d6ab5fcfaa22d32fdf106d211514cb1892c7c43ca6cd85c2532f85929c8a259ed251215063cf92e1502528d1e22d5cf67efa0b8ef21e8eb2f5dff881ba1433e8bcf2b6af8742ecb2bccde081e534615a305562cc22d3398f61f277d8ca785842bda85d8a40438d9bf1aceaedcfc22c85533794a69cfc320931d3f 0335699bfd058ee2e6163f55d1816bf3669acea8b73be9c4ddfe775230925e6093cff7a66813adf22222c8376faa106d85ac9f3c67929bc58d8986795b6d35d5b9fa546dceabbedc aa1fb3c06693511f04641f4f8a231288e8e4fe97258932a21bf6407016f4625b48af201e886b72d2818a1704978fa51e0cf5bc4caaaa5e07e7d01f8e15bc891260349376e4f6d42e37548f059aaa1287e3261e36f0198a75d8187f7f8cc77334 +ee20c6b61886e02ed94359dff3559522ff550ca126fed4b2240ea7d999a182b7bb618c50528fcbd261d5e497a991fbac0cf4c105c0f664d6a00a9001c1ed522962fb44dd4159677ce8f1531019f86457c055c9cea6247086cdfe0442485cbbc4386ad002b4bd39a1a187752437f04569705cb7adc0c68f0fd059d946deb63f0b 02c3eaf801330b3f1b0504f2399f1d24455db29911f750c246ba0a134c3b59da8b3562911197764699a92ea1d95a2aac587e24f743df1dad3e1cf7edf955203e24a0225717f8d2df 895a0b08371b5edf9f5c0d85c481a899204236f4eca972a9a0c3449a2aeba05add3443b54b4902c001bd129f3c30f79f121779c7e9b58fe5750e0155e734cc742af5ad070860ae385489ce2010e0bb9acf7064179d5346726359d1fe96849b14 +734a9eb8288e32f5a67cc1d88704523ca2c68b798d90e188d871d9f50d2da2063baf1ee6685c45832a1818aabc9afc0bc935e97969dc983a484f16d2bedb3c7c0b8221408be2480a5562d5d1e5d8763d1e474bf2826aa93a68c3b870e3bf34f4941cf590d88e1f5a8cd782a33992213f3f6b4b4f6dbfb3c3c8f21f5eaf4ef609 01c3ff067497e5d387f31f0ecc9c67b3c0dd6ec8c81318c492aad83c9dec6c99e4fa47447f6f7082d636c2591d0df940b947d0a4ae3778e2b7cc8fb92214638399def894ada276b8 a62450324066e92111591eb0f2a4472166e2d061342821e4c737e2110e5fab45f7d632498775f4bdddd4f06d1dbb93a80827212d7c97e1a7b510a3ec20af9e49091e16efc5c9315c57525c7093cca4d06bac99e445fc871bfbada4961cb199da +68e27cc72fec8f3f1f3882c6efa08efdf21d74d13be5171da35ef2855666ad2ea6919d21dbc1cb6d296663dcbceeba2fe47a2c6507d3d4a67a61b55b0f81c93412d7e1fbe15a590e342a05f55daa55f8591171303154e615e81189a523b855829a5c96621ad118f522e397e2eea05c2603eeae6e3591215e29b2289bc384d8d4 004b4e04281b210fe78d516a5b69f878b7fa058941ee9ae8cc63b061d1eb9e12c3e0ecb8717ff4623ff5bbbcdb53c48adbd9c69636506ab929c5507d7ebafae5654aad65a263e48d b05bbb97a7823ed11cfe50c95ed755a2dea06be7c88458c4fdb8349879cb433ad65105e2a9820bcb60c4520b58005baa0389463086047a769d21c0080c14bcd0665e84c04c550d7a9412886ab3cdca1d77f730c7842dc6e28d97ab443a042365 +e67cecedf35058b80787589514a9c81c6b9f4bced4260411d2af75bc46b8b2c962dc9d260dc99ebbf8ee64950766efc0e394184bdc8e2891d66bd3300ecc880e9d6a3d0eb615322378afc3dba89938704e9a8d0c949d4bae9838805c00377e3fe5ec6a1a98ad7eaaba6b500973dac48b26b7fb2e1b9889f8c387de535d4b2363 030f2849a713aeac95fde5ce3af853e9d070ee60709eccf35a076567be2c43f0fa34420b0fc097ff577221275a3a56e759efc32183be2d76058a7d20e5dd59f00415114d73a15b8f 92834f5c38e045702189230cd0a214588bb5483b36978c4487056188db2deb4777b536136f6551b8b55728661667e107116c2c188fdc0307613b84a1c5246194441162a2b84318cf30fce68912cca2935875b20078aeb9725708068d15746327 +2baa1ac3f07e34b67b6af087400f261e138b070c8475378063286c16fa73578303380236a4af2484ea01ba56c1c619f6ae4e5e6ac2594c8e5aae7e7f196f96fc5d0f507bebedd4d818e77b9120e5b4bc01c7ab6339e88b71d0886631cc7fd89659bf513faf149c61eb14d55060c8dfc7e6e4c2b4ec8edaaa6bc36eca50a6feef 02ebb73d04e6e5361e20629e3ad119b33db5163ed91fd9a8aec4b774898784b6822a08992118a8fe6013094bad0be1e9bf01b27c069e4335bff7e0abd28a10443818f6b825e9cef1 b0bc5a8bf0f34e7d6342e34daa0047b2144190dd0577dbe975fa42a6d5c0184e70869839a4a412ca02dacbd2a17f4ab4176ee93fb0fefcb8a38a3f6857313435aa59e93df928f8ee917c210ca240af78746a3c7f673c0f2c5293c0529a28f507 +0e640581f573068d8ebd2899a6aaeed0bf987ee11e22b05d25e88e9a1c3451f45ee3800d976f4603c18a041febef07a01086832a6f7ecd5d498d52e796a9d90758c87c36f4a5b704a39c456aaee2d5278183d5815d619c193da9fbc427d701bab0874bded848cb4bb066f56e119b637c78aeb6eaa387c41bec6cdd4bf7b2061a 01bfab717d6f6e16d9bc6e89d2ffac7cbe0f808cc8ca2eb515af7ecce5f3b230303775710a21bd25c2cc4566bb53c78c78e3774a9f306c751cc6e149929e45eef60f56c1d2388c6d b9e69ca036c78fa34fc319de8f1e9b052a3f6b3dff38a6b00e70622b979e97ceff06c0be4ad7bb8816c19104916b46e60163383f8364fbc0650e51aaea05b415b667549caa1827fa80880d528619904bbbc490cfe0f7d18994562e491bd49930 +51a2a560ba226d629127ce1ea7e812219ceaddd23561256331458c9f11fe73990f21d0dcd974a3773040090cfdc8e0f01692d951a0cbb60f8448a016c67abf46a9c150466ac77e656ea827b0ea7d1e77ea32071ba8314fc8a2edf69008f498bd1c18061d7d00f3340a7e2cd73e9766862378d8702e804a1870b442beb2d0aa14 000cc53bf7f1cad5e3dede4b4f4b082831604c92dd2b147869cdf1107259305b1d50359647f9f3d7d4e1e608865c65dc7c9ea46bc324dcb8423b554dc369d621743cbfb592b70eb5 9935de3b0bd0d6415a3d0f06b681a26d9109c1139e89241723978f99104d10028c81919cdac80779f7fdd265fbaf8e5e07f4e0a758d41646b7978be2d0bda0cf34793a817fc858326c28b40d9bd6fe1d9572574ffd1cd218c8286a0b15a97bd2 +90eeecff0a2e37df318c441df220dfea013ef29774ee92a56b213e13a798858f31e52b6ccb7599e7314f12b48a89884b113c1ba0526a54f3e9a33c940944319e084bff320cf5f391c02c731c4c4f8b05afa273374a1705d6c85337782ba7d36b9c00767180cad6422c11c581672ff631fa4c49d41b02481568ec87ea97220400 02b009530cb9d586e35dd8951ccb686833afb7a37ec253e547e85b253ba999f0f186b6d4ba41091615fe57678e9801b4dc94fa683511da25637b2acc9fe60936be15af16234c4ee7 ac85cd071cc45ca454bf4e23d150dce446b4b200e6eafddcaaa91d9f102bd70d6741ab9790f897821d731ae4578a69650f08c9cd8a193e986bba9d05554102b8037a605efeb3cad42c2ffbb394b16383d3280394ea01ffbc4822ac44120ded64 +d3740cad41e2e365d80ae81da97fdf06d8b6c278b505e34cb683fb55ddc5189da543540914c0accd405dbf0063f6222885fda4b316dad4a83fd03e8d7b7e936f87fc0a5b095defc8a4b22fa97f00b394e672d5efd3e0a230c7e44dfeebda88641143502a400ed62e2a51f9561e5d652a43d616f16699e875deb9610c77de8e1c 02cc2d0d7189cc8fb3565a039aee7633ddc00ff427cafad32fd2010b10fe249c9724d91785e7080203626038109158e3a61a3970aa3e51688aa7f5184b22f63af63f80d3540ec023 889817363ef355092ffef44f6d13136d44ab712c6e9fdacc3df4090b8acdfee9a03ada7e484927a0250db6ec8de23ade044f230af5d50e0142f9bf7abe721ecc627f4f004687749de0cd14ca9bb3639a0d472d6dc183afee9c6621dc3bc10855 +5eb53b5f92121396c5ff30e0c92da48db4fbbdbf27297f9bc82614ab78f7fd863e34096c615a02e349d8bc7ae4b0700130704bedf32756b5ee6af10da1cd717d624fadc57a9aa6db4a6c5d6254c0e8f8c3c0d4d03c264eeeafd52cac2c1968d9d85b106167a49d0ccdbefb20bdc10a2555f8149203af52853169a02db94e5e2a 03d8936c00c131e38c6566d2464c4e207c878070bbf681695a6cd98cab2c6e80fe98cda80c66a5cf584e90a071144dda59c07b8fc7bb42464dbee5b6f739b0f2ee5fdff7e5a4e7cf 888c4981899673516e494a9db87beca38bf68ada652c5913598ab7e7dc2c3de983f2158e7f91e6f7de01c917b5450cab058aed258ffc9ab4fc85534758f2fbe4b77cdd2ec1eea5bb7ae956245817cc9a3faa70cf15c87b3fd48a086453c6a10c +5aced64f702a57ed7fabd045a40c967a485d2a70b0a5e82561d5141ef329469b2da5964a34df203a980111a77adca376c643b9030aa74516f054648c1534d912ea66582adf3c655dbd71ca55e47412315df5e2893e43b2e2dfe6e4dedf426f11846ebef34a99f5615460ce0475f7bc54b4a4fd99e83c982097c3136ac6188a5c 03dc7de970bce28a943d7599f2a9010fc99435b93bc4ba884d42503ac2941aa63fd07db34bcbb1127d56d6a4e277d6ca32051ea3467e376f74f98c3999d2f276b282ef8a28cf0cbc a4b019003517329982eaa68dcff01b4d9c51ddd16d57c91cdd1e26224f71aae6bcdf48cacfce736c53be341f4e2c4ea81728534d5d2a02f65a4649df34633784037958199e43a05fead2994162b8ec7360ce7ad8e9311936310052a4a4d0de2e +43c24aea343d4e088bea25be69a332c631275c36677093e057de69cc83a4c5e70ab270e5a8930f55846f1a22ec10e03007dcf0942c6761e89c65c6a4f032eed97dc3a2c7f7ed1e82552fe48828a132ba16c41f6bd82a49335428a24fa1679522000e6a1d12c646e0e4b4c584398577ea9493bb334fa3cee8bfdb6c2e66f46436 02de6ee12eefa7a4a736484b19b42a513dfc059a060976edc3b0aa4b50e98d72df6506fed0499ff8480986748e938289e54a5e86c0c29733a9bcf5985aa63d8a2b57933a04a8e8e0 9978dea9e8beab8c7a2b39e877d497f208b4934a19fe6575de522089c9193109fcf37fc489a8efed6102ce94e1d62b8e05a328a48bd1d2d3416cfe4e07e128ce8e14ff65629a76f2502fab89ca98c8c451d6b5116d6f31b6e30a4bd54aacf0c5 +e89210565959d93b483659e62cf41f0a0147ea23890c2f1a694c377a826165e363860e4b084016cda878a43eb68465f81f397ecd50087a25215ce7c4ededa3552218071fa3acd7ae380655fc8fa884998209ffc8a2c26f1ca19dfcfee455dad35a4e72caecd8da47eb9ee21b889162f5d3032724abfd1a31e68612e18bfa9006 005468f0df2c9854f5f655743e79c750fd8812db28b096d97207bae7f5aafc6b6090c9c636ead9e0fde32a1ff8d539b53813733ca812b41b58ff85a941abe4f128d59fdf9847baa4 a2e18f0074f3be0fcbc8b1698d3bc1984dfe361ea7f37410534ca58871d0757e0a7ed8003113cc9c790d07b02ff815c5174caca0aef65977932215aed6df65dfa1687156e8d98ed934a02f14888242e818e7599f23f853bb091b49c821d73c40 +48629ec97f56273599cd9903f8a84ac2ba74275b40e1e42fa47649568babe05cf63c8417d828251acc2eec525b56dc9082b68d51b0c2bbaa7389fbee15d058cf482993b2bedc5a9101f1afdc79989a812478245d191550109fc17215679553c508c84e3d4cfdea377088d09eb214e6f92410facee4790beeecafe72b2e3ed192 03d3c6a7ab9450c94aa3b8a1ffb678e5b647af24cbfd66ee3944e6f264f406295b803767471fc67936fdfed1714b4b8761a07eec86543b7c4da6bd2fcb33fa8cda4077737f398e18 a4282624a8c7b5a1ce95f4d9e6c782e1144bf7321849940ca5ca3699cafda0543c737ff7c44c25b2d84ce9098683e90c175e71d40b8aeca4ca87df73d2888894f1b798ff87cfc726b5c272be79521ff7f24e06ae99e28f5e6eb483574d4d3bf6 +aa3a9fe467b1ca638dd0622c9ea235a418b39b2e15ad81fee01b6892b240783d8db3c72e16c13df8016dac6addbfb85232158325bd7432fca3b8bf5db3abd0b4c5ccd0999609dc42199ca4680692a0805cdd68108bcb493a558ab507cec0a2782a9e976928985352edb2abc0c07078b59d2fd86fda7fc76cfe573181d934c46c 001ce010ea8e6e1a0c26ab22eb90f0700dc73b232c429d36371e68e429792afb7223f10327708bcff779ea55fb5f22ad87aa054e84d10f5450f1bc9a89279062ea2173f55ab0f76c 81c44fd6af2490ef4a4776a273e747d0a2c27643704d5ba16400a7b119a93fb9abae4f6888dc7fe22cb561d96dd4196c054e73fdfdf4ed9bfd18e9b2d09cfb4e9ccfedbeab9efc241d17a679f2e3dd2858580ff21578877768ff1ca31734f684 +6c3937014361799f1461f652841b5137eb0dcaf01dd293298d002f27e9a770b9e1a30367e35c04603881f0c814cf8ecfbe1619cc49cd516b1d60d27de37ed52a5e1cc300e2face4669f308ebe6747255a3d386f16778e494a7cdd10b45171b2bfcdabd91b805bf24857708c1b75e368edb2874321324f83a19154d3a1578c767 01e7410d012aeef02b3723346d24ebafd684c99087ecccaea1cf3735d52c4c81dda41812c09f1e874dc964d858ca240a19963d5dc89451f5dd6764426ae41cb23f19cbfdca0fc562 95bff8dccb944b34a6630facddb440e0bca5345106fd6a9767bdf0f6c7526c84f8eb95a6f7ec8577c5be981349df27bd1260b13256398c48534a8b6b173b5fed6af1ae862939bf6e2d9d03c9a41080e0d1fc615da8c38fde4ac97fc26a9c3d1e +12fea55ffda15db902aa6a4388b9807c89c193cbf75b5d2a4c95206fa43dedc45974c80079933451bdc5b3ea015ed3ca2c54156dc61afb1bc82adefed1491302a48b9d3d2f474ab45343c611677d360515b93fb36da7a1c1b2341c9cce185c881c0beef33d43967134a190c09034ae3261f3295b79aebd3fe123616f73cf2089 02139839ce38eb879d266065dde5e5ea227244323b330e3ad5a0bc690f3c210f794cf18f0d730693887548bfbc434f48ee10ed34cb41d52172b06e448df938170a5e17311cab8e88 86c82ed642bfae50a527b38ca31d3f5f5085d10bab862e6b43e14121d66b7ca2e944b1dff6e1ca9ed83d51a304fafb8f0b99d1c0639cbfac5f8c1df91823c8ebb51b02b231ba0a25bfe85f2241c05610a0db69e1f9d799c5aacfc008a77c2656 +c8395546842ddb545d8ea3db4efe970453dcb06025ac3b7a25aa5ef62070f3021b9a1fea91ff7055b6c398073e7886a6f71afe53c82c47b71377dfe291972503bbeb25bd477bf0e7adc8a5d3f8b34ccd0080d61e121214e1b29802b711cdd8a6bb2275a2395c467ec2c1571952992e448d736d8bd70ee629c75b5e32b8323a00 0274f70fe69e4dbb55c5d404e39f5196335047113087f8711f2f67f2be4964e4fbcb865680758df1c401cd677b0971654b7a6aeb7bee0d6d80ac0de14d4f46f356b2d5545c185aa6 93e226b6bdede30d08b889e95e035445485117645ee187126ff9adfbf896c280dacb35f421d23ff954cfea889781ad2818aa51f6a575323e6959665054307baea5f9b441cd6f5fde77afabc509ee30253eff8738b27e0374aaef589f38db1066 +10d2e00ae57176c79cdfc746c0c887abe799ee445b151b008e3d9f81eb69be40298ddf37b5c45a9b6e5ff83785d8c140cf11e6a4c3879a2845796872363da24b10f1f8d9cc48f8af20681dceb60dd62095d6d3b1779a4a805de3d74e38983b24c0748618e2f92ef7cac257ff4bd1f41113f2891eb13c47930e69ddbe91f270fb 003e1b03ffca4399d5b439fac8f87a5cb06930f00d304193d7daf83d5947d0c1e293f74aef8e56849f16147133c37a6b3d1b1883e5d61d6b871ea036c5291d9a74541f28878cb986 ab353a7924f79c67866fb68ba8104dfaad95c47304061397c735ffa757b2433b92b8c6bafc73139bf5e412bf7a9473ec0c5cf8c04b290b401f78a8fb65fc8a97a4c5155e3bd8123f66ab23bb81e52eeda4eff37acfd6c5552b57c90d65c2a8dc +b61a0849a28672cb536fcf61ea2eb389d02ff7a09aa391744cae6597bd56703c40c50ca2dee5f7ee796acfd47322f03d8dbe4d99dc8eec588b4e5467f123075b2d74b2a0b0bbfd3ac5487a905fad6d6ac1421c2e564c0cf15e1f0f10bc31c249b7b46edd2462a55f85560d99bde9d5b06b97817d1dbe0a67c701d6e6e7878272 02e09ffd8b434bb7f67d1d3ccf482164f1653c6e4ec64dec2517aa21b7a93b2b21ea1eebb54734882f29303e489f02e3b741a87287e2dcdf3858eb6d2ec668f8b5b26f442ce513a2 a6ccfe12a0d7df4d6db32d7221313c51f5d584c6c0f839a1ec5690c723ddf5c491d6b8e4ddeb79e8dc5f11919f91ac87166502963a95ee25d5b16933c65c069c51936dcf1d695de046e9130712dbbe7871a191359a56d63409fcc417cf39f0a8 +ba6be551bc60653192401ed8ff9e1acd9013d8811a7a1389528bf07438366f5772cd7aedad010c19c47622cec03a4d35b8003b39ed901b720629ab59de55a03c1ca50a62987f8da159e356245df58d5ae1936e65f3cd3acbe03ad1d0fcab4aaf2a7a947549ae776772201efbc6fab1aebfa1d99994d4f43dc28f39c0f279b992 02a69bc1df069c6e89722521a63675f318252be629e7558f3716917998e660ac960b0b750562846fe6c12ef492951e51e224754bab84a6eacd4147a5f26ae85ee4381bb14ec2a8c7 b28388c617d93192c0d9560ee28c92afe332ba5decdbda8aff90e5b08e20b95944fb8cf37d01716d642e126ee5976bfe083dd5c46a13c39ab672fe8fa820b0060751bce9d1cae9eda04a5f7e9d37044330319bf8508fd59b94479eab0ddf94a2 +295720a79ac8201f40a66b06ae5d970afb15f36582897eed25cd92edcd00f70ac8e31c556eed4375ea044c2e8b227a8e02c0a3e996c9272d52ac7b3ad43b80f217295dddc84b177cf1e800ad08bf7fdd021fb2f49b54162092f8d628679c4ee335abbc90c027264c8b288c6e16eca3172eaa297ba50626b00fe0a0ad3a9dbeeb 00d11ed1b78b22b3420df4ddc4acc7c2286d9569dd6dd88e0fa3ecae69bcced68bb81bbb4ca6e9b54e67856e7fdf39155aa27aecb9cc827ccb9cdcf9ac633561b27d8eebfc261aee 996beb8a55e220672014bcfc24b9d3b3cf74fb1979819dea8f3f72e1de9d016ac82b16e64c46c4e067392790b1490f6305ab76299ced7f3503d9e182869ebfd8740f1ff5fd15fc91fb2a29ffbdc07be7c86b77057432c24b6b5929f6914435be +a9cff41c6dfdc4a12f31dc375a5455950077ae323d0b7a3d9a8dde73b76e9d7b94ddf9c88ae8e6c262d704052ac47681fc35adfc56c904baaa6e146eb653984369d76a85596cb744941aa7b558c945ff2e81bd5ef7f00ecb4f43af23b4cea3bd4ba7b1899f1868a0c0ecfc62ccb1d588955597ffbbaf34cab2838efc2b866669 02c36ef754b5bd065e9eadde684750acc52795be80f54dd3d7a7d743d968a18f7e404bd71f8a76eb0395f396df5a7c2ff7e0ab6de35df34282fda6ee01fe5b9b68ecb4e378dbe32e b616226cd799e461165b9dc38a9755b56d6c2183641bca5e9413f15ff2d4805bdb5dc1f93dc425219f0238182ec1f5fa066b3e31669cc7222b20eb7d621c008b1d9a8a2dbb50795a030abfb24dc624e329e51757a5641ffd568296e32fabeac0 +efa6c582d7fcf5e431aa89b3b00180c0e78efd7ccb0384d90b80e59a115a13e55001d951528c42860132531c9b8ab29dda7a657c53c2ce96fd85549f6f1810e121eb89961295335eaa0e40532d85814a4206e6fffdf9bff76599da9b2e71a22ed572910b0e3bae38ad72c7042579f106739a8628dea5a745168bd918736e488a 019ffee50be5496507e3ef5c40ee88a49625e46d1dd1686a52b09ad4a8e3ee9ef364f953bfcd97c52104eecb6138067192997cd4ebadaccb73c7b2560879289a46353a756b73cc43 ae814f8cb2fb2f573c7e507f9119a58530f14ff9cb49e1280679c5831fd213724e05bb43a155b1d9f425d2f52e1c37e9085dcf9116c5c429a910d68544fe53060421596b01bf4fb3e8c59af6d8e5586020cc896ecea5c69529cb317cd0a96967 +211acebfaf13bba33a9dd16722ec53baab92a140127d61372cbf1850f2fc894e942e25d780778235f880743953d04eca7a9205602e388172aec2abf35412b483490751f93b51239b6701cb0aab14e5179b0d7f55d8586358381dd83e3e436bf69a6820317d1701750cb1fea1293467ba589eec5f5779c2dbf2a9b8f28c4dc239 03129e96fd28c4198cc5242c1e3531a3979fae643d527044e98d7721aa56b5b4b45dfddfa17a4115e10a2b4f46d92f81cbdd7e86e588a4c6d8c2b3a83f54cebcee1d1dd33e85d81a 87a0efba886f8e31d9d3ba2f9e0a19b0b94657e1e8cc100e253ff02a9a18a3ec417d2b1e613e8204d0e908166c7308210525b1837bc739a9844f4af561725916c628b41a2413ed79ce67e44cda395fb3457ee3735743c44d3e3fc421ce24d0bb +ee592e20e0a45c18089c2e41460e65a7d22ed9714379f095d43a308bdd383128aaa6fb24e9d35fd28fc95c5b792ad75c980d2cdf0f460ac60b12c5919d3cb28dac4d488196be6c2dfe462b1b0ce59f8501692255840f5215c0fd8b74b1996a267a5e3b22d2841cf0a0b6315ef4ec7180f1c8494f4c07d5869c01fa2711739efc 03d723d2697cd07dd8444f992f2ab4a063db334034c25ea9be99fd7a1f495e3a644e5ea033a41264e0d24a911e55741d0cab80a0bd678eaec2bd1e60424d4491eb86d664900d907e 81af63edae3997e7f2dcb5d40720477fa4e7266f327319bb17cc67be10f59ea0cca4a2fdf9d3899689a89a0ef29d248201f161f5303feaa124cf903cc99c6d50e80482230a8c5a912cd0418d75d3e93c31fc0e56750e659fc4e4da986abf25fc +fffca41927debbd53455821441d9115db99fb31bfc69752a382f57bc7abe021f148346ee29e17512c64b4918ab2391d12d6e5643bee6b5682885dc28177b292e23a37ff99b359b9cf7578432af56e0ad1028a6cce7428980654c145af8daf09addbb3be11228d3c742defca9d3b1667f48c63091fe3307ecf72667b02e008f24 01999ab45d66cd1d3a0fe6aa43bf5ef1e2a67637d53674f6fbbfb9b582be91fc42a12cdcad94b50b0fc7ac55030de24a0b99fbc4314fa743ef4b5198bcc5f54d8b669fbed78e2e91 80e90d329a7975d232c0d6f79063f53db81e4e4c731e61aaa56fabb63459213e9b06b906bcb5e235c1f163b3d4d136d60de425172c22a757f6181a12a9d5e627ec933a34c30b3184ccdd50919d174015102162d4f0413a6f10a99244a832890e +a2f71619ea04f7057e6943c2cece8594b341ec3b96c3915d924f94ba13fd7aaeed41ffa0e842ade414784f1ef825fcf2dbcf7bd8263b802def45f94de596aec0c121fc06558c7bb06b9f27a9bf56c42090b5dc344e82b69c4f528d33be166764a593483f6fda0cf56e6000ff363ba220f5ea0ea2c3191615c7ae3bb4fa575324 02ce1cae0716205330d730e6bc6dbfb6b951dc83ee3b4a7dae75d057e32e8a46e22be75b5f09135452b29c34dfe81a9be2e8dcd243fbd946a0ed14a832a7802e20cfe1abfd3d6e4b 9165904f7c6f426d0fa0f875d29edaa526c17efd78fc500ae4994ebad7387f665467b50a09641c9c57c2a42fbb89eecc0a218cb204fbd848f916148e79a7de4af58652eba8f397f0b3693dbdb41c05363d817d1c42984304fa1d03f53c3ba1e5 +b60415a831eca2cf60c79a334ef2f327a76d290846ee588d5d33d0a826bb0c7ec3e11dbb384a7f89c8d180425dfae7463e0ea6497d2eec1dde112f1c1efccb532a2e2b66a28e2d36d4252a4c3b12850d465fe21bddc441b92e6a7b0f67744f7f6e7812a0603211a26518b311a5b190ed890ad852bed4f6ed13377cab3eebedf4 02c9d0fcfcee7e75c3245ba955ae04188b1033c55ec9c821d8de7685276bda3e9a93c3ae1b003e5ea722913e7b169d67b1aa2dc8cd42adbd9368672a3f81a6817bf3e5529dcb0c8b ad7522f969b3d549b233bd522fb402c0d4db99bbc95362c47f06c5a325475ed4756109d8bc055d4da8ecddd6e73a6ab903d69c9dd796070fcf448cca71b1bf0b4d1fd381a83b9479df35b34c00553019a5a2a8031b463751a40761698ed29469 +5d15a08226cc74cf495be681b795d0bde26b19f29aca1a8c6ef77d50271ebdcb4e5fa2df23961fe11620b1c6580183f6ebdceb2c09516c8127be576496fb71449bbbf0a9d3d1c48a25024619b97c3e0d8b165897db96ae9758d13ac28441d7cbfb75b23cb423e0002046358bb6d64779974a5995dfe54b398f95f7d64fc52d96 010c057bbaa44ef0f565edc288bfe66d4f6acd8686899359bca418ba89fb690429489a37bd3c6c9f3a8714b2ca225868c6a45fee360e378a676f7ea39321790f32a4b005b81dce43 b0494cb450b31d15af3d2f010a120dfa016b76a525dc067916cde34ceb9bd67bcb76cf69b4253f297aa6e50868f0171f0297d415fc07ff6b6fe80b8df3be5567d5bc9712ae6beec75b5ffe58d03df05f3f8d00e876033faea2fb79580ff1b5bb +9eca4bd88200baf61b901fca53dc1f1e7e3f83b94d58a6cc6a2adbc9b1a35fe3f8ec61787c76ed9a0d696167cd4fe46e1a0883fda564666131753c576a720125e0b712db1da0278067cb899bdb14eec08737e864544663abb1d62f34a2114be07e8e3cf56e2d17099299ce6b6d83b1a34e6153d7c6a32a72c7b1bf4583fcbcf7 02c182df7976ea93d996f3ba5d2221f3cb755cc7847bc3fe9e022fa4285046f5bfb426bafa3580beea206de36f87593ae561b4b74a03fcd61fbd0e8d6fd5668f2148819a88a650aa b83ca41e95ef574dc155a7523cda7610e86f7cc4a0eb87e12ba5dc049f2801686cf18e0e15d821e42e508c31c3d32d921863f515eaa5c66dbcbca6d369a640cb4aac85bc34ec4382f4c7a6c9e8e59f51f5fe07f26aeff008002070d879b71a3a +707450bd84141f3b61beb12ffa5ae89d812dd11badcdf6a88a2d50fc70e23f6d822ff4477047abc58cdfa28f97ad7f4911ae0773c04ebed1f51bb2308cf6e5712c4aaed461edd6987fdd1796aab70198276b601241f6a14225dce575830ff60f935fd9f567d1d210652e4710922fa793da78c8fdc30c273cb08365c9fc887f50 02d3a65bbe133cc98cf0eb56ee1362195968b4eab960a1d55d8b762f1361fc21348d6f275d4bea1de7158fb97c995e20b92a9c887a3e332d154667ad167acc632eb88a0ead6113a2 a73a0c000966a8a80417bc1b5539f055c9b5206fa725f1c3c094f558c08742d994618f75af818c5ae2943b2a2db5cab1105286dbfcb76bf4a1b727b737cc561a458c8b44a70717d0f1c8eabcb32acbcf11de0e70e816c7f77e08cd30f16555b7 +d5ce9d59391cdc47ef942dd2a818d024ae3917deea8a5a4214e4db6a0c5e6b0936f3e632fdb68a3f0006e05c44b7232013e1da5f877cd197f44fd6f60c1fd2378995e9a47534948c5a09e33750f07a7165072ab38095373b07a50bc1391eb6b650ee13acd63d0352e7d9c31695ea1ec6323f9b5f57b426ace56aa7fdbf419be0 02a920e8dc928acdd56e3655b2340d4371c793e66f67405fb7a90f31e9c4ef466cc44331d1d2fe3ff7391d2576dc6640772166ef8c154a5ff1808f5dab2f03061070ec8b3f786c36 931695f4541692db20ecde739c643cf868fa713ecadcac8a6b8cd0bb005294a19c2dde9a1c6824bfc04995e8ddf7c6140ea974028f4a829dd6bbdb0af57edf4d7441addcbf9472d5312ca00081fe305d0d59fbd9b5cdc7d0614a5afffe8cf269 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B571_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B571_blst new file mode 100644 index 000000000000..20f3f358aba9 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_B571_blst @@ -0,0 +1,60 @@ +8e14f713a2c427b1f79491033994f76acbead614d12e73ac6f3f518f2052a10c1273aabe628ab38e0d3d5f8ff254802e9f44a51367bf80325b6fc39d907a37f731372864747b10749ea5cb3d3a83da39c21a7b02885a8c1770e4397cedc958e4baa21d5007569dc9dd1e45d2181709d900a394454090badbd0cd9c2cd2369aad 00f42afce7f7b3d45f3f925ab29fc3882a89c9f585177887584703cf8bd8fc572e677adfa55b402446fe1e90dc855358d92c3267c35be9674b40c2ad5ce8dbe6a533c44b0ad8d2b2 88de872b41a771b12d004369d59a4107dc66f011bb2ae43059b9eeef4d70045cfc2981653879b694eaa9ae2e7c57b7440fd25d24b1a68d1e64420c65b9a45930b037e6842d32347e518958bb81920aa01dcd4370ea8fe235a85db6e47c6c3a33 +38b60d27ff08fb191811036dbfd5b39e1cc3427ff70efb67c851e9cb407f9fac6f348d289df98d055eec73299fcac068bd0fd9ffa3c5d244659e4f714a58d79f6727f323a7ee26369000e90e34e106f99f5ae2ae1b64ee89e5a1d304ef20c071a7773e9b977ed3d49f467d300a881c8371041394910f9c366942449045568f01 02f36613043cbf53ad36e2b38998bb867503359ae082d07d040e5a10a43e06ba9c91e7c73308e41e2391b65e634f83b162cbdf4e7a44ad818fb93a978af00f06be06731d8c5886c6 90ed870ad6897041787c31fa855a8a52e1684af42a75a38a24132609c63d4873d599c83950c0c178b0745d85a37c7782070c9c44e665ab4bcb96a3e9c2f13753ec1e40de63c83c48b5f195987299e39572c0a254716ea66fcbcaba88a6bfb092 +21709eeaf9e1953822294a478dfacfb205fc25f447a73a76a32601c00784cbf2f9ebd41c22721d70cdb3842dcaff4a4f208d41c0816990e421cc4b8538ac2f347cdd0aa2a39f1aa26ace8cb6a606b23f6244894d4594a0f6a5b8f6a695fd66e1a41e2eb6a377017177fec56bb58c837e311cd04c5b50575faee32606b9636ec1 02e74948c46930cbcd9dbe2325539c7dfdd910f309fd610e6599d425aad9ae230a8d4681970a14f2a71fd08030d0a40ff40dade7de1b06a80441bbf7e2fcf1809cff39c7ef88bf9f 8bf2bd3a8577c179b9cbdafa3be5e3b0021ff78a45eaf82fce4e21b3c797d43d6f35e085900ed82b1d81e14ef5b07973156bc807f4168167266846ab7c7f18577007226c4100bb40d9fcb47d9229bdb9e4c92da3a3515ad40e6ed9351de29a6e +3a131fabf3dc97334f212fce41c44300440d16de1d6060450875f7276f53c026e2a511681b5a8d75fc0d578546339542833145f7ee13c708df33e584445a75a5538829286480d339be7c777c03c998a6d3f037b25799ab2d541021502a0b02a9b9c337a8b176c4f30e5b186485a6103b1d1563ad4ae73ca806a5e4daa92e9100 01b5fab1d36f6f6d559f65d8b01edba610620fc3a38307b1fb1c5bd63e7ffbd4a9098cb8bdf50975a873f5d047ee2b627b090897a7fb5f56d3f4a0f3528179e7c969926fc0d3b0e5 ab1f94707049bbbfa78a2840b91976610b92f55a5f8ca0b0359d9691f3fc74019fe04aa4bcfc78753ba7855adecf55f90327e12d63209a5da02daa8790c0dd79109a111532dbf5737d49c873e2abf9a9924e83cc689874f9159d926367f4752a +679d85a762f2574b0b31b516270b7d33d5e166c83e91a0f48e0f3db20b52f42f9e6ee9648cf58267ffe3b713723cf3df52b5fab5c14db1e7189f7cb7170bc6ec7cc71946745e152b39180f828688a5b6c0b2957ab94283b90052a3c6e36843c391aa8810f9253b639a8d5a69aec10070603ad7a99dcedb544858d057a1d66b89 0383e70c71b431eedd4574f65d01fb0304f7744d668408c847f7899eae44770a7f3243109740f177d7146a27748886b7b77ecf3792b512e8d8e37c3bf4ecef2b1253df7066498f01 87f0364d90728149fe60440a72467fdfe131b9ed9aa10b59378f0bc4e475fd3de0a33741b890e5ba353dbf5af206bdcf171a293b7eed887b3c5a176155aa0e7d147fa8a9122696175a4eea10a6165f202f1d1dfb9a3a9c123ec717fbf3e94a2b +236152ad31ce2ffc0dead3c142cf6c770672cd2e75af4a82fda1a72e1c775cec9b481c6f3e411644df7e7ee901c501405620af4b6e9667dfd46091788daa95ef2c6c9f5c240c06b15cb0df51f5f058d8a7934bd7845f007a35f99fa97200b20f3b5b14fbf1e372507f3b2f377e8d07d30fd3e222f398f26d8f428e320327f901 002261d4ead21f02fab19bbb0da8c272286704c8f0c6842ba47ded121e5cddef79fb34e6b9694f725ca502949faecfb21e3cc062a2b4c654bd542d9a1fe8d97bdd0905c510aa0999 840e33b800e6433d2c6718304a552ff8ff2bb541c5a0d7bd69b08993ca8fe32b281229b3490e5fbe4ef6a1e0c5afdccc18489b26bd57ff567eb86138b3bd913a1d274e9f3bc4b871c2c3b1cfe1e5df9db59c969dcc1ac410505ea893f08501ef +ba3f02c4847fae035d747db246fe4e82fb9224ff9cf568a6ae548f5dc2befb2079541d2cf9aaa6b18c281a05e7ddfcdbcefb25f41dd91cb3092b3343e16985e91c912215cd99ae4a099baf628e33a7b277e3c36a13aaef85418fca99f64d73b789f23ecbb76c3095ade0a5f7f34836a98c5be933b44a94a2eaa3f99b1d8e7937 0316c78f289e1860bb623082be9d9238b88e38c5e978a868bb90f776235bdff4eff591877b7f350cf14c40356922b2b6aa51d64990360b2b0e44d6941b5dd9492b4f4e1f42ca163a b89aef832aca2e5ba59fd99938c5fc2b0dd929f234d7ca6e1f0867fa2bbb5e9cb8805025347cf30ea2860ddbfeccd8f30bea0fce84dd7ab340d9bea679f9b6bfd98bb28a9e4d6924a689b65b3ced8cf4260a825d79b60fb1655ac81ba3fc5670 +6d0372b40559e075af56af853cbe18ba2d471b0fc8917764abcc69102b03d5bbe1fc12458215be66409c26c89f67c72a8933677a07f88993af6918acb074fa915fe883b24bc3d191ff1b08852f07eda98977e70eba072d8bf189cd545230f59559ac05f1fa3f4e65886d0bc274a6e02e2399812b2bf91abae81e21279c5de996 02c1bc13f8320d97a82f3d9354e195481902214e16a4fd89332a0499208e91d50e5cabeb4927ba030cb42f5bc53b10f500fa646a8c88508cb0d63ebfce5c4bd574c527d686c735ce 92d072b681c8174b465f97c7c2256b0e838a5f978a7301ef94a21e3f0521b4a41d23ad0ed7a5bbf873075afc342119dc0763f393b5d88cb2176a6c56d14e779365b2e4b37060ededdbc3dece01496f007025b73ae288ead409af5eeadfeb2cea +bbfe66c82bc060bd14fd0e40769d9b3a026eb447550dd9f118c30d8448f725f8366edef042447962ba7f7f833b9e9094d0ff600714697e632626e7d12a592e040bdcee166dcda93952323191021bd12f3b1647d0f25a41739994659dcbb19333ca30f46f539c6f0a5c354cda8969a1eda572a309950c84c7607eb8ac20163912 013bd80eafa67663e75d7ae139bf285d2b9f1e03d8e32153c73e26d06e86d7acad22bde9f121a3f1ea674dcc1fe67bc7f5398d5e92555056bc046a02b0ba86c2a0dfe32e91add5b6 9906c213e9e4d8684b4c874679eebc3f45950eb50693eb66030a839a77852e2e6159243f330a902efbd8ed4aefe22d7f0b75d632990e0f970f2d22296fb414f149946c3ec1129f290ed1b7a34c270ba3f77fa7c76334a7f2058ff60fc34e4e84 +b35e9bf686717ce3b16a59963a32a2116130453b161a4e7ceb27b755856add836d779696edcaee3b5c986523891c8836109d431e55c23afbca022437ad19e6777efabb6da3bba1f5f44f905395b4cc7c9210590fd38da621582d059598e5e4569e904358e0dfc0dbfda4ce75538aa97480912852bccd433a9b96c9c66e9597d2 030834b0a4284097cdda2ada6947c6c281f7290a49b56becefea1e2788ea3ef78fb96807633c47c25138341768b241164ce0d42f7301728b928be2c047f2eb60fc2f844ab77306d2 b39ed849159709dcabb5489598497d3329d54e8bccbc114f672745a2ddc2aa91feb0c9a908be3a06df1ad207a34070720d82b1a22e201da32ac90200627af5e3a7e0604ccf2df5da8ba11aae20f65ec886196a1006e2e924a5994b09f9be58b4 +57b5ae7e95c638b258d1e09b3fcb4341e203f5706862e199b103c8fdac72cbc5155e5cf8b300a0b3fb0ce1f897c45f7aefcc528182f73dd450cd84d5fe9eadff3f704dc2a01b4e847c22df430efd1c66b0199f3e5b59348af5386962a5ef25204fd230b54d58d7fae801c086f8f405d3d0aa7a9a9da15c22b868817cd897d853 00c81a79ced1eaaafc31b69a40d9939f4e484d625db6364a8e589b6b4d336d458b44287ea6c6aa7661113fc07806b147ff98216fa0c08708dc9d651821b922741deda522b4e436ad 91d172d6f0ba5edc71f0110ddc76c42a67cb1fb82ad6d1736c9d05e41610d9e44028684034f840470d2de5d76ef8c1fb046660e11468bba0d75a7fc71f593edbd3dfc22c334f3828a752be060408ebb20ef09aeacf8c769776f093f9230d5473 +daebfef74b452f039c999ba0528be3bd9e16deb5f46f6eae87b63db8b89952c949fd7db08311871eb2596865eed107aa065f030226ea675ee3256c31a3f85ddf4c21760582144e07af208f33c5f47cc026db5403186a65a47940691ea2d74ffb1245676260ef5717dd879d8b5b72d96f87fef5f762d4fd17454cb5ed83d8a11f 02f24670c0f77d2ca0266a743023d2c7413d56d0b5ec77b454ac59087efc4ea4d46179e10278e4ba416ffd8c3f9786ed202faf8251c0ef5a9ea5371fbb35b7afe3d15a9cb4bad975 a940e8ce188b78f254b2bfc772410f5855f6fc168039d336f49f8dd50ca0f96a3dcc5335ba1a6283e5833cc8064c1d100d322e548d63224db642de0d30013c1729c5ae7b7a8d1656b4c445b727a40ab13b957127a95ee90b5050ba199795a621 +62af0493ae79d71b552c4647d1fb7ab2f282a91cd44aebd8ef344dfd77b521b0c0a3f72e4513c8ecc0e4b84efef3df9482a07ccc1b740c571c5e69cb913740a792aa231b9dc87edfb72bac188293c6c6e788cb3dff32e8f483f8f34e21ee7efec71302cc3bdbfa47908a135f6ef3ff179dcef26d1a3987f7be967a6c0f799b0c 020985f2c6fe3ea04bdbab66a8b6167e5969c073b9d53cf3c77cebbf73f4dbf75e601620ec9c3107bf3fbfc6c79f8f063409bf8fe1d14b19e323d857e23dc05157d270c7514137e4 b6faf61a04fffb044cd20d6ef95431980e0acf871a68bd14626071c67d139f781a123968b71b9479237fb57033e85b6a15deef8db22a71fa2f5818eb2a6e99432fe03fc5bbbc02a08f862f1b26dfa22d74e43abaf63b7b9cbd97f55b1ac7a762 +566f17851951777ebea3f8285610cd8ee5f882a68e7a4205e6fc9e2d66d210ee2505ee73d6503169f7b903012d43e7e99efa493a8e6ef926b16b9ad8f52156840ab561fc6b680120a88714fd66d1d0742189bf06c155e1138ee5314707173f7352e2cea0fc26e1553643f2490428718e44afd8372cbb7bf5b88234318ebf4355 02b3d641607b8a141f876f6d285ee46aea543880e772dadd5dd83d595b9643191d9597218e1d6adb081df133304037bcd2c05c24a54e6c4cca64fb2cc4569d6882315360059496d8 ae4878396259a744a213d770ca930b25f3acbc1f0a02ba5a924267639b9c5e4a9c84b32983f24158c6981ee7ab06eae7177394d2f8aad175bd32b9d028885dd331d37dd25ad468060ee876ba35dcd2aab93d3ee6c63dda3c0fd4744adbaa2d1f +25155825fc4f9a1c4dd1db837008e7e2594a879052431f5bfc76d0d2565b8fa726008befaeddceef73f3c60fa2cdf6d9a70e56d27210bd013034b38861ae49640ef208d3fe294ac4362f8eea44f58af3af8a9167a36b5acafb7ec95652d5885a0e08067ce1dfbb45a0c89ad1acb53eb404bf88fa5c3c463a0f912b5a2522a0d9 01afeb5ca87c81025ddf09c2b2c5ee22ba0105c0e619b67a324467485bd839030d149fee44d8bac6f5902a1245a50c3437046b7c89a84116b2147cddc645b6d2fd24d68e8d53bf5b 99cafbaef1bdf87d21a2f492e5889cf664d3c1174d5336c7c9856c815b9a63caa06c8d801ce62402f5aeee4f93e8874c07e7e44df1454114281deda318882574a82978842c7f9edca6f91e4045b8b60a4ec9abbfedc9fa24d8e9bf8464052edd +29acb0fca27e2a10d7b9e7e84a79af73e420abdb0f80dd2665696638951b52dd39ca028166b47a3b6a2eaeceb1a11c152383f0bec64e862db1c249672b3770909f775b794e0b9b28a5ec8635a996d912d837a5f22471b40ec2e84701a8804127a9f1a0b3c96ff654700bad3167240c2518fb5dedcc1be9f56a807083e587bc56 032c97639b69c7cdbf419286d0a1b406d9b1f2886521a8b979a36118d2a368aace5b02dd8c515f2041e6fb9f026d1e82e789dc826a56d2ef732b1bb0f49be2b696ab5d3d5694a2de a51a09f6688250cf27aea30758671fbde2c3981356fdad471b15abfcd161394fb0f060b0b1fffce4eb6921fe0da428630abf5beb4792bcdbcc4d577576ff36ea2acdf7fa731db8f393133f4a2746e591afe7876cee8a1963760339c838dbaab4 +c92d67cf6536f5046e15b02158da698bcbba4ff1e4e9e9c882cda67f817210402ef917ae93682c9c3dd817b21b73c6c00b7bf92ea80ecbbef2e67f4f4379d078a2b0f297742b2bb9c3fa3297a7e8079f488555bd37715eec92b4b1cbf897640ae8a1d2a0fbcee5423ab31a37629f98630275e35094a896cc574be0a449bb1bc3 00f93672159276c5a293582b9f49607bbdb970112f6c63b2b3b5d32ad3c8240c86b1af13a8dff6502c6b6a17712cfd988f8cd23a60693d64104143b3f91adb37f852e9e11a0ef110 ad92a5132a24b0634d709307f2fce21776d7bfbadf8de6ae8256229c17c9cd464fd6dbae292813ec72306c681b83a2c007b5168d3b0896c115e5255b6fc52e215c167dafb6b36f247654bfbe3e02094744394cd105964f07deed754aa5da0b3b +15413f614c4551e3b138b64f66d15f8964c40326a42b0afce820778eee4a88edb127fbf575da5263e5a2627b5461d311813ea868e6417615e7c4938313675009caac28bc7a2f4c0bc37572d9bf36a3b1794294e09c0121ceecaa4b916df45b0dd31225415e6c87cfeeb092a008fce2c543cd62365779ae28f29fa02a15d9dcd5 03db080bc99c5fe7e06d5032167af56783cb423fae59fb5b3c6bce5fbedf56b7b39b17810e48ea9a172881aa1f42f5e267349b60294d4a208b4437666b44abcfee5a1829e9467908 9249d7c66eaa3fd4161da79bb1ca679f89b27316bfb465b629d3bee73f1fa7f9e3a5ce2f07b21be4755cea10580157190d223a79f76ecfb51dec50eed9d6840d488f69cbd7b09dd7ae3d5397a9108f6007c41bd2bc90b1e32346a684c3e5a138 +9f901557451ae2f8ec79b6d4adc794cbfd9b2e6d28f19409532d91682820205308b41498a4e1ca247a2baa8da93de95e3c0f7afd6ca46bafdbdcc6d3374a12684676a50988b86a960a82180648c8c1e38f8fd9af604c7be3be4b24799f4544ac96d6360cdb83d1d0847fda21642934fd6cf65385b50d86d4656987901fb88d0c 006ee767f6f36bb8f364f324d8346455c899a49237d759003dd52cfa13b9baa4c71347b134b24ecaee32d247c34e3787a0c64bc5d299b55c86f64b47521d22f2c09db225b0c84cc6 983959ab68732f47180a10d72bf9a84db1ef63c5b2b1bd4afe4a34d9cc3b6fc787e5c3c906bd19dee252438adf3699170598ffd8a9680dcaad9701f0f570d3f8db1d6d94564896bd4d330a415534bc099cdb953e3258f6343a42ac1bae2e89a4 +959fe5a19d7aea2ba611c7203e19f8e3f3cc101e03a98f91adfef602c424c580d5a868659368a930f9883d699fc633bd07f6cf8de474937db0bea86fa7cd140ec2f202663813033a757b93bd72afba15be5e47a4eb93e8a666aa1c72c241ca3922547d63fa3732fec54afea7ade84302e2f044275bb67433fb6b125b7913143c 038e2571d9f22309a636586d62863ed67a70538287f3ef88b88c3c2fa1a2900d48c342b6f15c26b8e7fb4875cda4093b7de7ceda48fe1e2cc2975afe958040881de61f309931e48d 94cff868154649b6ca1b5a6e9fd754877664dfafefaec5ca03c31f2ec87061c82bafedc5804950c02b1b54f7e506a8b813008bf98bc05d0a96ae3478f2247ff3d464ad29a508e00edfc8e7fd5771d29055cc8d35ea017f870a50df39f46f505d +97b9688d9ed5101b8cfb19e84b89cd644262ca1c7ee18944e29ddd3b4cca78e06338b270385b00a5e8b91ca5e628de3bba50e36ecc695b3ea737a9cf8b36871c473a54ba17819f49e730c0f253b0c769aefa6c16366fd2dd612f330e95fb119fcf3bf7f3e254438c0ab635ec04a8b2424a05b483ecf65b74a93636fbab7bf1d8 00c8f5736f1ae65592f3ca850f43d06441aaad8c03820f3b08d8a6db46488dcfb828459f8b3f34af73cce8dc7a5e3834e085a64523d890028e194214cef4003210e6eb530005b01a af302d056212cd0f7242c143ea37eb5143e5a32353f935bec51241b903db20214dc1afc7d8544dbf456257a001dac7c300233728bf96f95523eef6ef8b7301688ccb480fb537abfef12f27ddb6ec354587512beb11efa6ee74d15f09b05796c9 +f08b250bf4a3980cb455338b3f4173723b3f44c97bacc9cf550149794a71426e398cb4a74bde141d8b7b4a72942f1c069676a9918e27792cb8f085ee037c78e3c468adea5123c4c64d8ca6a39f2f90140c5d2d80b669cbf0d1ccb466b18ded83a1d5f042c36188a04111c34ff769abba9aedda40a87be1e24b700225e2078056 01ee68c3994adaaa9e0d61bfcd3bc1cdf198d3fbfe28a44e5dd518867ea04b20e795eadacc48bfcf8e8216dceeaa069b756e8e99ed87b6b1d31154cc9310bc3b4555162a890b0c6c b51f3d485f888027408784afa1029e26b2460595e5bd7e0ceedf5a113dc4cd56128138e4497f19c2cedcc67e34e629790f2d52b11daba62e1758e96be4f8edbb254f18edb428ee8fb26178c94a0d49d7f5825215e47620e8c2f3d1623965945b +1cabd16fc29d7d919622810dc8b23c770b790b98b119eeab1b20900fa94fc2ebaf76be4f5eea91fc5276c5621c8677d4d117c4a5a782ee2ca1d5b0db997fdc8a05b6b3fbb833d7a7b81c3c615c2a662929760a96feefcf89e46b563314c9b77c86bf34438458b43b694ceba741b97dfcdacc0ed57652ae62856ce10ed2690770 03a6fbf66ebc1365ea7699c72cdac2dd85907ec59cd26e2d18713354b619ccb83b7fc0db9193aa8493c1855f1a83fd987cbbb65de17c59fbe79256aa5392f4eba045346e9ba26592 b4fe10a0fe0c3dc400095dd071478ff6fe616f01f03b5c6cf8c9d33e76e62ef0d66b5642dd7c1918a06717079844be2e043831ef75a11d87462a0a10ddcabac891a81a0d5271539ff9a3ce233cf4f371120cb5e74c14b1d266e772a6cdf580e9 +7bc8bbf5ebeacf40b3c82eb6eba5d994dcc6a3f2e12ef741f90f90e176d20c21e006ecdaf14cb5beef35bff46b2c374d9ee224516679b1a9e9255cd8ad8e60ed234f8ee7e0fc53c9021488158217d4b4369cc597d6053746efa1e73340bdd73c1bd2eed57b92426fd4d278d6a86e8be0f0a66ab3dfadefca8831b2f488636251 0145748871a0b5c1cee628de04a12fd68ff2b154fda96e47afaa96389d66d22802968584f6753d36618d49ed205260f09d3f5ccc2b27a34390ce58179b9834ff92a86d66ea0a97ca 8aa8bbc912e163b5fd26470bc4a782fb2a6c6e8f0f9737307d9190543be805ebe604bf577d0c8869958c21e5fbbdab890fa34ce4736551476035f0214a607c3e3dafacdf1f65c6ef199275fb43edb6fe2dd646b26f8e3b362019d101e63923c4 +0cd2a45392871c0c262e7e6f036946354bb41f9c2187b8c4d399231280682f3e0a09731fbfd52c76ee63b9828c2d731f4cefee0a8c46419c398205b2ff80c67d7756db300a0a8385fa287dd37d9126f75998ae1cbab5136560592118db52fbf102b7ff0a1ed45b8a91a7d99d13a0f7fd4366392264aa1248d7324901467457ca 03c71911d24ad19c20fc1d8a044d63c9bb417abc3778d7e6234c6af79b898cbfc2f2787244708d2fe203be786edbdc4c9b12b413156b7b0bab0be8af895d191d853cd58aafe1ccce b7015307228ab27396e150acd25036faeaf641c8fc554ea842abfd23030c735368d7730d8f636fb1f5eb59639b6f9be50b8acba0e1fc15db65a8a0a9d663b36bdf19a2d17bb58918bb4c0acda92cf37728674d885cc3acd156572564832c212c +e97092625b09c9ae6e152e1cbee207d83361f34cb9b0e727c816a5ed851f12f91fbf88ad9d4c8f9d07350f5d828fd8574eafc768bc72a2b18aaf4d2b48fb10f7c3431137b51850154de9706487d69a40a8f4cb2c799f48c5d8f518aff752500de93cbb94ab04ae1e0c7183a32d79a27291dd07b5fb6e6a4fab76e85c3a8607e2 018bd74698bac36ef11add6b3e3fad227ecd868f370ec04569462565d2f0af2340bf793486953a7b79ab04f0ab1f0e4fd16bf6b576cce677d543e73aa8edb0e50372f24ddfbff966 b945013a2094b1bef6b062e564785d3bf2b4040cbe435800c4e13f97c66845e463d15b3af3b4bdf418fd0b40f7e6bb8a0b60a225b7d23de1cc097d5d3f092392fa998d2846183739fd37b233224c761635a5a05f57886870bb1234e1c6ab8c22 +ae6723b8df5d6ab5fcfaa22d32fdf106d211514cb1892c7c43ca6cd85c2532f85929c8a259ed251215063cf92e1502528d1e22d5cf67efa0b8ef21e8eb2f5dff881ba1433e8bcf2b6af8742ecb2bccde081e534615a305562cc22d3398f61f277d8ca785842bda85d8a40438d9bf1aceaedcfc22c85533794a69cfc320931d3f 0335699bfd058ee2e6163f55d1816bf3669acea8b73be9c4ddfe775230925e6093cff7a66813adf22222c8376faa106d85ac9f3c67929bc58d8986795b6d35d5b9fa546dceabbedc 8ade0d4ee2bb37657d24981070b4d38d2a45d07edd35677f87db77939e3cea1d4ac6782c86efb7d5e47b8831a759cd110537c2400f901e2922a93cd234045a44bedeef4d9c9b99acf8704914b77586240400bb77e44ff833208dc8310f7e36cf +ee20c6b61886e02ed94359dff3559522ff550ca126fed4b2240ea7d999a182b7bb618c50528fcbd261d5e497a991fbac0cf4c105c0f664d6a00a9001c1ed522962fb44dd4159677ce8f1531019f86457c055c9cea6247086cdfe0442485cbbc4386ad002b4bd39a1a187752437f04569705cb7adc0c68f0fd059d946deb63f0b 02c3eaf801330b3f1b0504f2399f1d24455db29911f750c246ba0a134c3b59da8b3562911197764699a92ea1d95a2aac587e24f743df1dad3e1cf7edf955203e24a0225717f8d2df 8dcf1343c1b66a05aa3f4533be557223d58306244114f9005ad926703dab9a51484ccaa1ffdd5c63bd0827c975207ed608c4856febd51a88dc574df05b7f757d42d89c11304c87786d6fe5d7b9c233cd40e4292c3efc7bc7f78fae0820b038d2 +734a9eb8288e32f5a67cc1d88704523ca2c68b798d90e188d871d9f50d2da2063baf1ee6685c45832a1818aabc9afc0bc935e97969dc983a484f16d2bedb3c7c0b8221408be2480a5562d5d1e5d8763d1e474bf2826aa93a68c3b870e3bf34f4941cf590d88e1f5a8cd782a33992213f3f6b4b4f6dbfb3c3c8f21f5eaf4ef609 01c3ff067497e5d387f31f0ecc9c67b3c0dd6ec8c81318c492aad83c9dec6c99e4fa47447f6f7082d636c2591d0df940b947d0a4ae3778e2b7cc8fb92214638399def894ada276b8 a34ec06a5e374bb5627175f88f090f8c96263d9fb34906b89c579585c76c6bd4f519c45a1a7ae91750a71023510b369c14daf5c462b10d0b1393f310c065d1bd8a43fbf3cd17fd17ddfd98fa33dd8349694c47a210381c5435f54e553746a76c +68e27cc72fec8f3f1f3882c6efa08efdf21d74d13be5171da35ef2855666ad2ea6919d21dbc1cb6d296663dcbceeba2fe47a2c6507d3d4a67a61b55b0f81c93412d7e1fbe15a590e342a05f55daa55f8591171303154e615e81189a523b855829a5c96621ad118f522e397e2eea05c2603eeae6e3591215e29b2289bc384d8d4 004b4e04281b210fe78d516a5b69f878b7fa058941ee9ae8cc63b061d1eb9e12c3e0ecb8717ff4623ff5bbbcdb53c48adbd9c69636506ab929c5507d7ebafae5654aad65a263e48d 8dda7e2a91f6d9b4f83bce775fabef5614fb6991fd8c31b9cfdb2f6aef9f02e1d5a60778f0ba13c2af7acccf1778e04c01e3b1c1bbdb11f43bab0f700b82f677c4c2a9c908e3ec85dadfb38fb1d1a3e54a38ac8992ddb5b4a8a5e1ed1976a7f4 +e67cecedf35058b80787589514a9c81c6b9f4bced4260411d2af75bc46b8b2c962dc9d260dc99ebbf8ee64950766efc0e394184bdc8e2891d66bd3300ecc880e9d6a3d0eb615322378afc3dba89938704e9a8d0c949d4bae9838805c00377e3fe5ec6a1a98ad7eaaba6b500973dac48b26b7fb2e1b9889f8c387de535d4b2363 030f2849a713aeac95fde5ce3af853e9d070ee60709eccf35a076567be2c43f0fa34420b0fc097ff577221275a3a56e759efc32183be2d76058a7d20e5dd59f00415114d73a15b8f 97615943cd249beab827d077d742cdde5914342c261b690005e6db809cee20b4895c4bfa038eefd10b85f01eb9324b4219903eb1cf4bb5e183fbd7d827f8c708004e16d934e1655b9fc57a332b05b2df36b9cab7a09d51c60f0ecdf3be54b181 +2baa1ac3f07e34b67b6af087400f261e138b070c8475378063286c16fa73578303380236a4af2484ea01ba56c1c619f6ae4e5e6ac2594c8e5aae7e7f196f96fc5d0f507bebedd4d818e77b9120e5b4bc01c7ab6339e88b71d0886631cc7fd89659bf513faf149c61eb14d55060c8dfc7e6e4c2b4ec8edaaa6bc36eca50a6feef 02ebb73d04e6e5361e20629e3ad119b33db5163ed91fd9a8aec4b774898784b6822a08992118a8fe6013094bad0be1e9bf01b27c069e4335bff7e0abd28a10443818f6b825e9cef1 ab639ebd5e091b5e10f033a3e4ac4fd3e28e923ffe52a5e59ee32a6a5b5cfbec27040aafdd7b5c3c6bb3693faad2cbdd07cabbd89f8750dedda6ddccd29f4273bd4fc6e51e9c3923a0f4baf9b924df0a4389f5a0b43117af3c946392fd342530 +0e640581f573068d8ebd2899a6aaeed0bf987ee11e22b05d25e88e9a1c3451f45ee3800d976f4603c18a041febef07a01086832a6f7ecd5d498d52e796a9d90758c87c36f4a5b704a39c456aaee2d5278183d5815d619c193da9fbc427d701bab0874bded848cb4bb066f56e119b637c78aeb6eaa387c41bec6cdd4bf7b2061a 01bfab717d6f6e16d9bc6e89d2ffac7cbe0f808cc8ca2eb515af7ecce5f3b230303775710a21bd25c2cc4566bb53c78c78e3774a9f306c751cc6e149929e45eef60f56c1d2388c6d aa0185b492451058003f54cba769e053fe347e1dbad04c36cad3146e9b286ae45ead8b7120d07eedf2b9e436a9f2d69d1684fa3c41e3317d7d1da4eaa22d9f64bb8992f2c7c7f04f924175128100708047cd206f2cd4c3f5b23d775f6b44f318 +51a2a560ba226d629127ce1ea7e812219ceaddd23561256331458c9f11fe73990f21d0dcd974a3773040090cfdc8e0f01692d951a0cbb60f8448a016c67abf46a9c150466ac77e656ea827b0ea7d1e77ea32071ba8314fc8a2edf69008f498bd1c18061d7d00f3340a7e2cd73e9766862378d8702e804a1870b442beb2d0aa14 000cc53bf7f1cad5e3dede4b4f4b082831604c92dd2b147869cdf1107259305b1d50359647f9f3d7d4e1e608865c65dc7c9ea46bc324dcb8423b554dc369d621743cbfb592b70eb5 aff1042e0b953c157716dd26ac5ee41443cfafb5454d27aa7241c434c14406aa866a6805fce17df4b94f7eb81413fe7707a616e49d7bf8e092bffff28313da866ea28156b42e1851506e53851062812b754a3c781107d4bdcd40c3029b6b542b +90eeecff0a2e37df318c441df220dfea013ef29774ee92a56b213e13a798858f31e52b6ccb7599e7314f12b48a89884b113c1ba0526a54f3e9a33c940944319e084bff320cf5f391c02c731c4c4f8b05afa273374a1705d6c85337782ba7d36b9c00767180cad6422c11c581672ff631fa4c49d41b02481568ec87ea97220400 02b009530cb9d586e35dd8951ccb686833afb7a37ec253e547e85b253ba999f0f186b6d4ba41091615fe57678e9801b4dc94fa683511da25637b2acc9fe60936be15af16234c4ee7 a3607c6107e9dd99893b427e5535558eba2b4e8f16459e6f7c138d1a1d0d1098a542493efe5ca1fd025179317740c0130af6d6bdfee7130a519f1348730c4e2f04050ba8723ae54e3c222653f4f142a47462c333bb264f74f672a5ff1c3ce8ce +d3740cad41e2e365d80ae81da97fdf06d8b6c278b505e34cb683fb55ddc5189da543540914c0accd405dbf0063f6222885fda4b316dad4a83fd03e8d7b7e936f87fc0a5b095defc8a4b22fa97f00b394e672d5efd3e0a230c7e44dfeebda88641143502a400ed62e2a51f9561e5d652a43d616f16699e875deb9610c77de8e1c 02cc2d0d7189cc8fb3565a039aee7633ddc00ff427cafad32fd2010b10fe249c9724d91785e7080203626038109158e3a61a3970aa3e51688aa7f5184b22f63af63f80d3540ec023 aa33d510fdc2f2cf18ed1faff8bf0b994c7b9c924de919f63b83d0851f32727499b4ec02d601eee6c6d3d2818e1868db10cabbf0e9caf97bfe2e7d18e17256b46463836b32e504fa5c33b3fe7a4462ff3d45742172c0790fd7f12999e08e8227 +5eb53b5f92121396c5ff30e0c92da48db4fbbdbf27297f9bc82614ab78f7fd863e34096c615a02e349d8bc7ae4b0700130704bedf32756b5ee6af10da1cd717d624fadc57a9aa6db4a6c5d6254c0e8f8c3c0d4d03c264eeeafd52cac2c1968d9d85b106167a49d0ccdbefb20bdc10a2555f8149203af52853169a02db94e5e2a 03d8936c00c131e38c6566d2464c4e207c878070bbf681695a6cd98cab2c6e80fe98cda80c66a5cf584e90a071144dda59c07b8fc7bb42464dbee5b6f739b0f2ee5fdff7e5a4e7cf acc1e643aba3d011f820422686f306503b050f56297901c9e42e8438d5641eed92da4006b9ef2e2ecfbdbbcfe07fa2ad0a312e5672a3562b98aa8d8aac5ed1417047d8483ea0284008a59845a16eb45fca3a874e6f56c23310fcc5dc8419e7d3 +5aced64f702a57ed7fabd045a40c967a485d2a70b0a5e82561d5141ef329469b2da5964a34df203a980111a77adca376c643b9030aa74516f054648c1534d912ea66582adf3c655dbd71ca55e47412315df5e2893e43b2e2dfe6e4dedf426f11846ebef34a99f5615460ce0475f7bc54b4a4fd99e83c982097c3136ac6188a5c 03dc7de970bce28a943d7599f2a9010fc99435b93bc4ba884d42503ac2941aa63fd07db34bcbb1127d56d6a4e277d6ca32051ea3467e376f74f98c3999d2f276b282ef8a28cf0cbc a7c198d861f0610e3b0cca95b749e7b37264eaa92497203dce89bb2a1aadb684b967a07b1302f1456ac8c9fab6096aaf16a9d4d86bdb14ee17dc23879af494390259418c884ba50467d34502a3ac957a3f50d967d12866b30493b3800157e005 +43c24aea343d4e088bea25be69a332c631275c36677093e057de69cc83a4c5e70ab270e5a8930f55846f1a22ec10e03007dcf0942c6761e89c65c6a4f032eed97dc3a2c7f7ed1e82552fe48828a132ba16c41f6bd82a49335428a24fa1679522000e6a1d12c646e0e4b4c584398577ea9493bb334fa3cee8bfdb6c2e66f46436 02de6ee12eefa7a4a736484b19b42a513dfc059a060976edc3b0aa4b50e98d72df6506fed0499ff8480986748e938289e54a5e86c0c29733a9bcf5985aa63d8a2b57933a04a8e8e0 8857a9bfc982e396e55b9958240aa55ebffb444edc9796bf43f34267d4d66291c8fe971217d15aebb034a7bd639c29ca02093ec0692b754cb71a22a573e15bb11f4b6f7a3cd6ea0921afdc3819367287c0e87e584fe5dace10147a6f7f35685f +e89210565959d93b483659e62cf41f0a0147ea23890c2f1a694c377a826165e363860e4b084016cda878a43eb68465f81f397ecd50087a25215ce7c4ededa3552218071fa3acd7ae380655fc8fa884998209ffc8a2c26f1ca19dfcfee455dad35a4e72caecd8da47eb9ee21b889162f5d3032724abfd1a31e68612e18bfa9006 005468f0df2c9854f5f655743e79c750fd8812db28b096d97207bae7f5aafc6b6090c9c636ead9e0fde32a1ff8d539b53813733ca812b41b58ff85a941abe4f128d59fdf9847baa4 afa14e0947d7dea01b3576eaf571fd2aba2febdfc29c82e9d67b33e8cd52cd2dfde8f9aa034f906fe82113e8a8b0f99700c923d36f5ef2571368d96dc1aaeff6d4cbdac2cfa9cbc31b80739961232261ad5dcf0ce548c4539f839b394f291e80 +48629ec97f56273599cd9903f8a84ac2ba74275b40e1e42fa47649568babe05cf63c8417d828251acc2eec525b56dc9082b68d51b0c2bbaa7389fbee15d058cf482993b2bedc5a9101f1afdc79989a812478245d191550109fc17215679553c508c84e3d4cfdea377088d09eb214e6f92410facee4790beeecafe72b2e3ed192 03d3c6a7ab9450c94aa3b8a1ffb678e5b647af24cbfd66ee3944e6f264f406295b803767471fc67936fdfed1714b4b8761a07eec86543b7c4da6bd2fcb33fa8cda4077737f398e18 8f060d3d97daae62d9f6d9332096509bea2e92d63ede79d948b67def98e1d06a373e59b9bb63fcb7c8611d29f7f06c6a18e716d316fdc1e827df4f77a0e219202f4cc65c2c0f63487668ff2a704b219625ffb15355f21f7f312421ce193882c5 +aa3a9fe467b1ca638dd0622c9ea235a418b39b2e15ad81fee01b6892b240783d8db3c72e16c13df8016dac6addbfb85232158325bd7432fca3b8bf5db3abd0b4c5ccd0999609dc42199ca4680692a0805cdd68108bcb493a558ab507cec0a2782a9e976928985352edb2abc0c07078b59d2fd86fda7fc76cfe573181d934c46c 001ce010ea8e6e1a0c26ab22eb90f0700dc73b232c429d36371e68e429792afb7223f10327708bcff779ea55fb5f22ad87aa054e84d10f5450f1bc9a89279062ea2173f55ab0f76c a3ccc2cec7b3923ced90428f6eb76a86734680ba47cf702543899f333b67149c11c43faa6e7d9828c3a74de00b74929108d6bbf3e4121b994bed6be5adec661fe1b21f99c670b7b34321f8b92b9dda5717ebb1b3f8b215c3d1d0266f09a6b13f +6c3937014361799f1461f652841b5137eb0dcaf01dd293298d002f27e9a770b9e1a30367e35c04603881f0c814cf8ecfbe1619cc49cd516b1d60d27de37ed52a5e1cc300e2face4669f308ebe6747255a3d386f16778e494a7cdd10b45171b2bfcdabd91b805bf24857708c1b75e368edb2874321324f83a19154d3a1578c767 01e7410d012aeef02b3723346d24ebafd684c99087ecccaea1cf3735d52c4c81dda41812c09f1e874dc964d858ca240a19963d5dc89451f5dd6764426ae41cb23f19cbfdca0fc562 b521782975f13ba940be7d8e75ad2badcf10c4fe098450be758f68be85c42372ff3ea707594cc5dde21fa0bf8414b7ed0e6762bacb64913452d6de7dda6a0270f9a2ec5a7c3df14fd301b5e87595b82c1f2aebfbc2e534503a8171b78b8ce1f7 +12fea55ffda15db902aa6a4388b9807c89c193cbf75b5d2a4c95206fa43dedc45974c80079933451bdc5b3ea015ed3ca2c54156dc61afb1bc82adefed1491302a48b9d3d2f474ab45343c611677d360515b93fb36da7a1c1b2341c9cce185c881c0beef33d43967134a190c09034ae3261f3295b79aebd3fe123616f73cf2089 02139839ce38eb879d266065dde5e5ea227244323b330e3ad5a0bc690f3c210f794cf18f0d730693887548bfbc434f48ee10ed34cb41d52172b06e448df938170a5e17311cab8e88 94b90ca78d36c921071bfb783638f260897589b324593d0b669c65e0231c7f0c2e477345068790f5fa7bb4b82b44c8a707be472bbb1d5315ef9a07d527135fa066def96a73fdc790900e49c9875f20c1c34dd2ea09da7c3f2146c7209b519ad6 +c8395546842ddb545d8ea3db4efe970453dcb06025ac3b7a25aa5ef62070f3021b9a1fea91ff7055b6c398073e7886a6f71afe53c82c47b71377dfe291972503bbeb25bd477bf0e7adc8a5d3f8b34ccd0080d61e121214e1b29802b711cdd8a6bb2275a2395c467ec2c1571952992e448d736d8bd70ee629c75b5e32b8323a00 0274f70fe69e4dbb55c5d404e39f5196335047113087f8711f2f67f2be4964e4fbcb865680758df1c401cd677b0971654b7a6aeb7bee0d6d80ac0de14d4f46f356b2d5545c185aa6 b6048fce6c66643130fcb6eab722684b07557110887b1a132d78374f7697e4d75cee596c719a2ccc53f6d519ce95bdfb066508f005a883be57c67769f7685ebc2d83fa450b2a405dd81e37913b23a6c909e42ffc53ba7193648cb67de154fa86 +10d2e00ae57176c79cdfc746c0c887abe799ee445b151b008e3d9f81eb69be40298ddf37b5c45a9b6e5ff83785d8c140cf11e6a4c3879a2845796872363da24b10f1f8d9cc48f8af20681dceb60dd62095d6d3b1779a4a805de3d74e38983b24c0748618e2f92ef7cac257ff4bd1f41113f2891eb13c47930e69ddbe91f270fb 003e1b03ffca4399d5b439fac8f87a5cb06930f00d304193d7daf83d5947d0c1e293f74aef8e56849f16147133c37a6b3d1b1883e5d61d6b871ea036c5291d9a74541f28878cb986 85729017eb438baef4bd4bd8a69e6c2ec8878b16d78f69ff17690ae3698d95bddb3acfccf7cdcdb69707008d15212006026133662dfe3d816a0b342d04017f54f3d5e02a09568c92decb3f6935d80ceba0e3b9ed40f48d97819df26fb670247d +b61a0849a28672cb536fcf61ea2eb389d02ff7a09aa391744cae6597bd56703c40c50ca2dee5f7ee796acfd47322f03d8dbe4d99dc8eec588b4e5467f123075b2d74b2a0b0bbfd3ac5487a905fad6d6ac1421c2e564c0cf15e1f0f10bc31c249b7b46edd2462a55f85560d99bde9d5b06b97817d1dbe0a67c701d6e6e7878272 02e09ffd8b434bb7f67d1d3ccf482164f1653c6e4ec64dec2517aa21b7a93b2b21ea1eebb54734882f29303e489f02e3b741a87287e2dcdf3858eb6d2ec668f8b5b26f442ce513a2 a3140c39fed21dc3c2a69d2ed93a3b45eb4850c58acd7dc57bdd0e8714b8e991fc9b415d5cc2eb0ce17e9ea7d049614d104b19de75d2614170b7bc119d0fd1defa90102dcf607d813d74194cbc85b7003f56459cf135de1c8fe1beb7a0e3d302 +ba6be551bc60653192401ed8ff9e1acd9013d8811a7a1389528bf07438366f5772cd7aedad010c19c47622cec03a4d35b8003b39ed901b720629ab59de55a03c1ca50a62987f8da159e356245df58d5ae1936e65f3cd3acbe03ad1d0fcab4aaf2a7a947549ae776772201efbc6fab1aebfa1d99994d4f43dc28f39c0f279b992 02a69bc1df069c6e89722521a63675f318252be629e7558f3716917998e660ac960b0b750562846fe6c12ef492951e51e224754bab84a6eacd4147a5f26ae85ee4381bb14ec2a8c7 b7d9e78fabf6f2ecbce9ff9c5b84abeda5ba5a473228b62e6def31f74f073fcbb37f557a153572f38c928e2d4e72dce4015ff41ced49a33cb327fc54937f104b29e1712ec4cd52f567bd3e7ad0df49e8dff5873bbbc9254322489077594ba3c3 +295720a79ac8201f40a66b06ae5d970afb15f36582897eed25cd92edcd00f70ac8e31c556eed4375ea044c2e8b227a8e02c0a3e996c9272d52ac7b3ad43b80f217295dddc84b177cf1e800ad08bf7fdd021fb2f49b54162092f8d628679c4ee335abbc90c027264c8b288c6e16eca3172eaa297ba50626b00fe0a0ad3a9dbeeb 00d11ed1b78b22b3420df4ddc4acc7c2286d9569dd6dd88e0fa3ecae69bcced68bb81bbb4ca6e9b54e67856e7fdf39155aa27aecb9cc827ccb9cdcf9ac633561b27d8eebfc261aee a0bc8713771c8c6476e11cfd585db0786e6b80da236e7745fa942d360310d8101302a11986234437951505e56ff29e270731d06d223d3f6ef7b40c069c5e0d8334cd52bb968536d88decb9ece2085d2b332ba06d6991116ce77c9bd6ccf5f12f +a9cff41c6dfdc4a12f31dc375a5455950077ae323d0b7a3d9a8dde73b76e9d7b94ddf9c88ae8e6c262d704052ac47681fc35adfc56c904baaa6e146eb653984369d76a85596cb744941aa7b558c945ff2e81bd5ef7f00ecb4f43af23b4cea3bd4ba7b1899f1868a0c0ecfc62ccb1d588955597ffbbaf34cab2838efc2b866669 02c36ef754b5bd065e9eadde684750acc52795be80f54dd3d7a7d743d968a18f7e404bd71f8a76eb0395f396df5a7c2ff7e0ab6de35df34282fda6ee01fe5b9b68ecb4e378dbe32e 871c40285e9f707c85d0867f88a8e722fefcdc9986625cbbf068292ed7fb51507fe852584d18689483598421628246a20e0add47ba9a5041ed7f614fde28c3cb91c26f75b1df2c1cd1fe14ea38fc3949dc1a96b36998c4fdfbb9a4c5960d43ae +efa6c582d7fcf5e431aa89b3b00180c0e78efd7ccb0384d90b80e59a115a13e55001d951528c42860132531c9b8ab29dda7a657c53c2ce96fd85549f6f1810e121eb89961295335eaa0e40532d85814a4206e6fffdf9bff76599da9b2e71a22ed572910b0e3bae38ad72c7042579f106739a8628dea5a745168bd918736e488a 019ffee50be5496507e3ef5c40ee88a49625e46d1dd1686a52b09ad4a8e3ee9ef364f953bfcd97c52104eecb6138067192997cd4ebadaccb73c7b2560879289a46353a756b73cc43 b696b525a61b63745f52a2a0e0fc11a94445cfdb0134baee5559417cef79ff5d10604beb4f156551ca5449c7c5b6883a04aedb3c334f4aaec62f6c31ea95d462a4f542116b600a126873d41735341d8b567736518cf775072864a9bd96343668 +211acebfaf13bba33a9dd16722ec53baab92a140127d61372cbf1850f2fc894e942e25d780778235f880743953d04eca7a9205602e388172aec2abf35412b483490751f93b51239b6701cb0aab14e5179b0d7f55d8586358381dd83e3e436bf69a6820317d1701750cb1fea1293467ba589eec5f5779c2dbf2a9b8f28c4dc239 03129e96fd28c4198cc5242c1e3531a3979fae643d527044e98d7721aa56b5b4b45dfddfa17a4115e10a2b4f46d92f81cbdd7e86e588a4c6d8c2b3a83f54cebcee1d1dd33e85d81a aaadbe6e43be993ffc02f03e433992f2a0c1a6cc1bb59934bcec8689cbaa0d2fa9245f5b6ac101e0bc0df59077ba86121152707719016a427bbb76801e81b6972f872844bf7d0955283e40b34b1a427c67b27283c4763f51314f5b0e1b407778 +ee592e20e0a45c18089c2e41460e65a7d22ed9714379f095d43a308bdd383128aaa6fb24e9d35fd28fc95c5b792ad75c980d2cdf0f460ac60b12c5919d3cb28dac4d488196be6c2dfe462b1b0ce59f8501692255840f5215c0fd8b74b1996a267a5e3b22d2841cf0a0b6315ef4ec7180f1c8494f4c07d5869c01fa2711739efc 03d723d2697cd07dd8444f992f2ab4a063db334034c25ea9be99fd7a1f495e3a644e5ea033a41264e0d24a911e55741d0cab80a0bd678eaec2bd1e60424d4491eb86d664900d907e 912b2926b77c128d23064bfdded3196442f1487db30e086a8eaf184cfda8b100db981c7c1760501db9c227472fc7ece1161acb5b80e7b04896cfc45dc54e2a763fe212c1981b33be7e808ae47399833f8303ab250a9d5870262c854647ea7fff +fffca41927debbd53455821441d9115db99fb31bfc69752a382f57bc7abe021f148346ee29e17512c64b4918ab2391d12d6e5643bee6b5682885dc28177b292e23a37ff99b359b9cf7578432af56e0ad1028a6cce7428980654c145af8daf09addbb3be11228d3c742defca9d3b1667f48c63091fe3307ecf72667b02e008f24 01999ab45d66cd1d3a0fe6aa43bf5ef1e2a67637d53674f6fbbfb9b582be91fc42a12cdcad94b50b0fc7ac55030de24a0b99fbc4314fa743ef4b5198bcc5f54d8b669fbed78e2e91 8fc2e68cf40045c6f8c77a9a7538b559a9449e262649329a36902fdd123f31c542deb71710750454e3b1ee51731e63e106a124f88b73e6ad449b3ede90e1b0766c8e8003dc7b2f45296152fe5b52bcdf908e8bc9a1f9ec65050ab064e3163dbc +a2f71619ea04f7057e6943c2cece8594b341ec3b96c3915d924f94ba13fd7aaeed41ffa0e842ade414784f1ef825fcf2dbcf7bd8263b802def45f94de596aec0c121fc06558c7bb06b9f27a9bf56c42090b5dc344e82b69c4f528d33be166764a593483f6fda0cf56e6000ff363ba220f5ea0ea2c3191615c7ae3bb4fa575324 02ce1cae0716205330d730e6bc6dbfb6b951dc83ee3b4a7dae75d057e32e8a46e22be75b5f09135452b29c34dfe81a9be2e8dcd243fbd946a0ed14a832a7802e20cfe1abfd3d6e4b 9863ae6ddf73353662ce624534b7103bcae0e6c1295cca519f7513a36f2b61f83500974fbdec0b2eee4d106d2e9d7676148c34323a9cad7ee2dd9cfa0f033881aeb20c985546ff47b8f4ff3510788ba583ba8bbbb85f5ed225d8b21bb620acce +b60415a831eca2cf60c79a334ef2f327a76d290846ee588d5d33d0a826bb0c7ec3e11dbb384a7f89c8d180425dfae7463e0ea6497d2eec1dde112f1c1efccb532a2e2b66a28e2d36d4252a4c3b12850d465fe21bddc441b92e6a7b0f67744f7f6e7812a0603211a26518b311a5b190ed890ad852bed4f6ed13377cab3eebedf4 02c9d0fcfcee7e75c3245ba955ae04188b1033c55ec9c821d8de7685276bda3e9a93c3ae1b003e5ea722913e7b169d67b1aa2dc8cd42adbd9368672a3f81a6817bf3e5529dcb0c8b a01f59c57a4ef8bcacbb0cb13858513aa229f4a33d4bfaa8d14da58d027dfb0fbd15e6436ffc5aeaafd3f07e66ca542507e540a1a64585f8c9a7f3d8388742c8e99ad01d359c0ccf4d1ea7fa0b8227f8e1d77088d787c564500dc0d3045a23f0 +5d15a08226cc74cf495be681b795d0bde26b19f29aca1a8c6ef77d50271ebdcb4e5fa2df23961fe11620b1c6580183f6ebdceb2c09516c8127be576496fb71449bbbf0a9d3d1c48a25024619b97c3e0d8b165897db96ae9758d13ac28441d7cbfb75b23cb423e0002046358bb6d64779974a5995dfe54b398f95f7d64fc52d96 010c057bbaa44ef0f565edc288bfe66d4f6acd8686899359bca418ba89fb690429489a37bd3c6c9f3a8714b2ca225868c6a45fee360e378a676f7ea39321790f32a4b005b81dce43 af6494dcb51b60924dbca5e66505dd7d184cb059d1ef047f9427c10b958d365c4996a3a428810d58757963361c86e93c0c1300e6eb378038dc0d58b6935c6f00f601c06393727a65c2df73f6bfcb2dfff9ddafb7e724eba5ae4d07dd647bc82a +9eca4bd88200baf61b901fca53dc1f1e7e3f83b94d58a6cc6a2adbc9b1a35fe3f8ec61787c76ed9a0d696167cd4fe46e1a0883fda564666131753c576a720125e0b712db1da0278067cb899bdb14eec08737e864544663abb1d62f34a2114be07e8e3cf56e2d17099299ce6b6d83b1a34e6153d7c6a32a72c7b1bf4583fcbcf7 02c182df7976ea93d996f3ba5d2221f3cb755cc7847bc3fe9e022fa4285046f5bfb426bafa3580beea206de36f87593ae561b4b74a03fcd61fbd0e8d6fd5668f2148819a88a650aa ad6bd1d6166de96d0e9882b5f0c29a7b5f7bd54fafa9d6edbdd9ab7866dcd014557364c71bd8eb5ab7edb26a9693a2ed08dc97399d040e99d257a520a730ceb52ead13acfface4261d1e07e5fb955684ea0bd89121c035264dcadfa1730a0ef3 +707450bd84141f3b61beb12ffa5ae89d812dd11badcdf6a88a2d50fc70e23f6d822ff4477047abc58cdfa28f97ad7f4911ae0773c04ebed1f51bb2308cf6e5712c4aaed461edd6987fdd1796aab70198276b601241f6a14225dce575830ff60f935fd9f567d1d210652e4710922fa793da78c8fdc30c273cb08365c9fc887f50 02d3a65bbe133cc98cf0eb56ee1362195968b4eab960a1d55d8b762f1361fc21348d6f275d4bea1de7158fb97c995e20b92a9c887a3e332d154667ad167acc632eb88a0ead6113a2 945bbe3fbce1b1a5f4c582869753250fda320d66940b57df4fe4faf228c5e240d3d9ce0f80642c89665b7393e8d66e5d0ae4a4f9796f1712716153738f3897c98a6938208c824622ac70c4f276ad02d5d49622fe31dc6e0154542d2702294906 +d5ce9d59391cdc47ef942dd2a818d024ae3917deea8a5a4214e4db6a0c5e6b0936f3e632fdb68a3f0006e05c44b7232013e1da5f877cd197f44fd6f60c1fd2378995e9a47534948c5a09e33750f07a7165072ab38095373b07a50bc1391eb6b650ee13acd63d0352e7d9c31695ea1ec6323f9b5f57b426ace56aa7fdbf419be0 02a920e8dc928acdd56e3655b2340d4371c793e66f67405fb7a90f31e9c4ef466cc44331d1d2fe3ff7391d2576dc6640772166ef8c154a5ff1808f5dab2f03061070ec8b3f786c36 aee2ef95642e59ed208329ea5f2d455f471c6e8ea8f5562bc797a1bac6e6ff85c263cc3ab496a86d2d0c6e33e0467e2c0977e623835c28dce105fd458798a85bf47417c097c05cbcf1326d520cce1665a6a515a44b0111b7754775c1c88568e4 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K233 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K233 new file mode 100644 index 000000000000..39e7a1ba1773 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K233 @@ -0,0 +1,60 @@ +f23f784fe136c9fc0d169503d361e9c6148b0f1fbdcae0a97fae1af7033ddef25cb7489c9963cfcb009a8cbfe44a8510a64a073eb1deae4c324ceb9302008c92c69b2dafcc9077fd3cc3c7c119edc3ced36d176ceaa55ac036bf7f07f6fa215e8bb8196e59a5e1c9af4f98b90ab4970885bd7015fa26a09e03c7cf6b4b23d929 004c1d414696cc3657dd9df73ace56eda2636769ce7082e064c260be45a5 8b7877429032da24fae3ed5a4cbbaaede07d39fd4bc3e00eb75c4181507f99c6b181538b3f196789fe7b00135dcd237d1415022cebb87e8cee32549bddbd313cab0ef20a0f601f6db16ba51b37303f4e5845a314091fd27ba1c668d98bb98980 +400bcb297552bb37f2f8135a9314a35f5126788bb6fa4dc74152731ff64c5dab4b902103d85443dec20e16b1d6629930cdc2bd183d4099f0e96295a63c2fe266f5e9d050c401a8681b4a438efe53cbd8f2f43e2a31e9f88926a9c82917d873f6e8cd5ff5eb8c1ca36126b0bfc8c2b0e85a7c9e7a45f1875ca9c82019ebedb729 0027cb1d84865a16992476c9e353283d5d6a40c349a8e9179d1b1f403531 a9aeb5b8dc0588ad44eec268dc50df1692fef251bfa86a7dab5ed5f53d8a9dd24da5f86ed21d31d2930e2d05a5fe633002a560dc16f437a33453215444abef03a03173c6c0ed55c82616a6a8457b779155f2b21762aee5f95f89fbe55bc586dd +5f74d4b35c49fa454c97c05fdb6b9f6822cf1a2295f15bd766dbcb413d77c910bd8f4147e8f317fac2300fa21cb80134d1b6f8ae8e50518c1f648a28506e419f5a6e8f05abffdb3dd2587606c7e9c223ecff4f46b121216730ea13202b59128a7616bb2fd23a7e4a5aa08641cc07b669641313febfc88d64d99447353dae3f06 0031b443f46c4b5224237fac1022ee1570173f664aba0c84dbaa4246bdc1 a97a9893d398fd0c3bdeea1b54d4b4be9b0fccfa23c3a7944a96ae115f1415e0ea592f3f670cfa2dd6371506027d62160fb20080c209babc90190f51b43d248c64bcf6ef7d9499298207ca8f3e43f1584aa2a651d1a22fcc6120808cda2cfe4b +8f92096876d9f81bcd992369d42d0b5877ac969004d17c8627c58d8b8b7bbf7a37e8cb6afa962b9b043bbbaa5bef4a5ee38d8bd31cb5866b828265a2f4102a616f87009cd346fcb8af5519fb577c60d8792472232f33dc615655e53d2b715b15a2697b492f108b7906e1e3597c6911f8cc30c7121ae338a6b747ec368f8e4a36 0048f6ca29f35f253a4962734357c995920967b9eeff1ba5fd2080bfede5 90b0d13f2790005e2f3f48a4eca5e37000e83c89de2735c7b74186e75d6b1e7a232c86cb72c2c3eacb9f505638f30b2b18b480d276b78424d8c91b2da75ae0d859d56cb5b40c4f79e82eee5d77f2f84def9f73ee9031d10e2b98f3b2e5ff6fd5 +3d275dbde44494c45fc15fe89e2ae32aa26426a17e923e895c7941a5582fb95df4d49873ab1bde358017f336b911b886b626b744806ab8113418473c441f1964159ded1b12122d53ac56573167588e4b55f36b8bca8c67823883a51fb6e7f204d1c6b07ea49b577bfab9ca6b8d51f72268b022e3a4db6f9d265ee8382f9b7b66 0019b940eabbe682f961d9f3d90432e347fef3910e641656825d775705b1 95259048cb58661b5adbfff6d81586682cae416e9647e9c6e78550ede87bb3dc2bfddee68bc54b10a26f32d304cb109104a3b8c6c3ef4d1901e90c67e7dff0130ced3cf9809b1d3b7d72524b5ac6b3085d8bf5f452b7be97a89edc9c157bfa09 +d2fa68e1f7dad02916b12fa38f1849d6d409dbad0344438520b4dd9b77d62d39ac9ae3cdeab03ccbcfd4de703c6e798873671731c108f322b9f2a68145e3e210c9b15b879798e5c53c5022742e9819b99edabb2f44d89ae221f7a99dc84421a6905695ff91928db608f861745f17584d56e34b75c47281435b1b0b34e490692d 007a884b22e29fa9fe945e9ba13c0df8d786dc87cef0f77f069e182dd56c b53fd33b02322a18494fe7f55b8784684befffbe62012df15035473ce42e24a053c6383f724dc95c6e9b1cd3536a47c903fb6d58e0961fed54f98bba9c1d7bd956b4a51f679ad9fcf228ad010bfab1204e5a928c917ea8f5e4611049b1696e2f +3830f75cf9df4eb2998c7c1b5fe11c1476bcf849c3a8fa7d3d0b5bc2292e5d07465ab8cc9381c575d909e509c5dac49c78817c04e4bef18bd51bb09aa5897f21634633a5ce6d20bb4638cb6c3927351eaec7b62cf4a33956916045c392f325adafb10a88a5f86d7e41dd77908fa7284210071c22aa40ef40da6339c02da05392 005da61f881d5a0dc085bb93764f584352882923cd237d878220ec624c1a acbb80e9f67b65127c1b810ba94cb32e63d61b2434c13ab66e8e86adbecebfe1a9d20d2d6ac1a464cd3929212d9046b308cc584e57daf900215113574b76cb77f3cabf488135721c861efee18b1a9cc1f609eaf9fedcb6ba38ec8eb3824e4619 +65b9fe15e6c35d453caa6bad39ee78a720a04b60d8a0a0f049186d2f777e48ae2d657e174df53edb7beb9f7d8f21904ed674add0cda5b62a7308de76c324a144021e8c6d387daaba4ce48bf7dfe9c8aeee2c64e434ece1fa5ddcafcf3e5d0013a1eeec1742a00d384cc2ec0d7eda83bb4dccfb0e57045ebfc27a4f404d03da37 003fe9f04647f6d82b13ec1ae5a8c2e49bc66b05649ad778eb16149ad83a 86c204bdf666b9624fbd739ac7d8c7b24596aa391c6d5d395072fa1176dffe8b709146c26d541e99881d9142dd63689e02c5f1c1b97be19b26a5b10db2024d9daf3d93b480daa94118301cb6159cb7989e92ee3468f76491ce2859359200a3e6 +d26521fd41eb5d46ece6836e188bf9cb1b461d011c41e002a935d256654d01725378e845920ec4a7fd3f379df54772493df50d312c7c6aa4e909e7b83f2442c3a5e85c37d68aa015098ecfb0a5e077370f4576f4bc63bf37e1dee06d780a3b6949af5e21c2a0960fcd20821ef5f17bebf5fd5b3bdda260842cbbfad45667287a 005ebce648ace4cd555413de6a456fc487d14bf4b0b9a72311ef480d2f26 b22299e86bd3ec54d883135d68638f3e0958177ab3d155efaa66060fc6c810afd66289bdb8c94e5a330fed5aeb8fb8fb0161ab207332c399f081d69c672c7091362fb70b13661cd906fee139235980525c9b3ffccf0b1633c72fca74a1ea8e13 +b778c021b1a92c41dbd09963da07018075d73e54d62df5c2b7bf8abe137151650d1c1c6abce7eebd8f32e8c3e6d1433773f257bb3ba4a4fb6a02c0db1e47d03c27d3a90898ebd1927c21df24c4c5443ca5b81f8ef2cc0f5e8b3d08f472bf07085df737adaedec63d99acd77b87ba98225f198b791124ac2d9b191cb9251b4b00 0056653c2f85593f789a926ba49fa3da9d7f946d8f1020508c5a527ce813 b6709e2cf0b4df46141068061ee7758edc3fd160f675ccf7932b549c5614e7b9d028ce1ee04d1e983d2d16382e09ae2018f53e7654d70afd2bf5b84fb78c804203beb86bd27418990f84b77a79bd54a1153adb30bd23608d08325fa01aed28fc +ec14e07f615960015a489ef999e308b42a4c571473b9bd64b433dabd9a1b1ad02e33eee9100064405175928a94543a80f440040afa2965b4e5f95f768e7fab6d3c0a5f5e1bf1df7822f78384e80f2955ea85f044ac60537d895747979f935bb0cd3673193c4a32dd7803e48d7daf70a71bc2aa97236615b6411e28fc9a652145 0049a91d320783cc70a5952c32036cfc75d41f1aa84127db2dc759fb291c a185628da124be3903cd4b49ad2fb657d0b55afcc5328a1d44e3f40814af2e382fbc194ea79bb2141cb6f328ac0f8c0d10b0cb0b410e93bbdc0fc9094a77685b32425d07c15cc4c99018c4f94134086a80778ba9e695e36b4063bf037a7afebd +89c645339ad0eb850e4e2fe583cee175b35feb02ed7541d7e9aace24cdd3939584f73ad39526de6399c86b36de77a018e2c70b532bd0f032f9137d10480acc30c49f9baaa86f9df0033b77e98b485bf7a69cb5c281e527d3ccd1fce2415f0dda4a268ce68a0a34b16afda54ed922cd6810ac8dc766df2a3a6c5e55972e9786fc 0016a20016602fc7088a60469843e1d29ad67e3c3cb9500b1e2a00d4050a ac8aa5f817d7206ea3613810006dbb097641840abde4dedb37836686a8fdc4209d4048c28eca0a4187b93641de3fb3750f1e6a264b7c1a5bc5263ca6443e8f8ba2a0198c06031008a2312ac7684022c593ad40ea4d026aa5f346d15b7b205e72 +ace14c4b101d2d8453c2bc22b756af016b5de537df9c3e639d208ad04ae0bf6232dc90b90c33228dc85de956db771ffde05fb4d0b15e4f218ed2771d703ae5bf981252a5bcd60c16f14483131a481cbe04dc0adb1fb8aa32cb48bb5008e8a8e5c7b7465be2fd7afbc811cf5ea6293b1a464669b49f55f57b93a8707e6042fda6 000ba922149bada2551b7be1c3df076f3f97ce93c13c50c285fef3f42363 b066ffeccd956a1b7efb65366e6bb8d2ae3cd13bf6961cd2c75c92c155f68782a036e05710d16f94973c50249d52fde3108cc3e9073f776ba1d51ec806dccf5b38691850ed2234923bc0ad09451fb3736bf2af9851dcc4094a4b655c2d7f913f +cec2ba0d1772c87e87d5bbbd67220692bea4301aa1a66e8dbdd7e651d45c26dc2a0d45cfc32c34d76ae3e1c61db7b0fe1863457b93937d929e6ece7462ebd16adfd708353d6f7c27aafe06593c76da7149b0cc574a4290b0d8fe219f3eada7082aca38dba3f78ed0d5942d095fa5556fc8bcef331ff0a6d5d1f4e6c51d4ff5af 002d635e12a58cc6dea44e71e87c37f91e8d08659f0b7955d24f65ab55ba b62c1fa1901cabdaf18a80bcb3c894159b93542009c129a05d84237f9353e786bd6a2d9f0e670918644e19f11664e860082dfb09e1a3f9c82c601dd58fff0f48a54d4b51ea73d8a0d8b845be4c346617b02abb0ee0a9d60040ffca35b44861a4 +ffa13cd0f51ae2643d5d4edecb493ddd653e9faddcffc370e7e958abf726a5d67a2ab36cef42ea8ebe22a6f01b9c31f6ffad01e6894487d979acb5e618f765ac0ec3550ac5dbbcede8f9fdbe52fbaba5c087ff382b6d7a09b2b5084227d324d98ff98793040884799b96d2ca593201f4414f18c43b51c53c5e5059e0641aca02 00073883e5064e06814fc4de32e15f7a6cf825d2daf6eb1df8c83e25d80a a8536c1879e93bf18143e38c6f2d2addf96bf8efa17f2213d56dfa24068ba75b2e0316810893bb5acef89dcc088b280014ad63f323f2f0b77e1006f4553417eaa987b6fcdad5f802933cbe0b68685df7a69fc3c2c8f78f161956deffb2ba34a3 +c73e3dbac9513d0361dabe94071faf03a11cba18c06d131a172d5f0125b01a5eeb6055bf72c7106fe3f4be3bd2b1771cbe7f85366dccfbc3bac20538510c3f51179cc540ddafb2f3b05a0d276899674ab1d7d8fb4f6838f04e4f9e26b8c6af31540f63f4953c85840af4c57dfa78c704f637dfc8dd750fe45e2c1e149986d127 001532271bfae8d4dfe60f69b88d3006d58e28aacfa701861cde8d624db6 a0b44b02937ca5fb886013817658da4f258eb8fb60b180e12f9c0551a1f4518dee631cdf3d8c98a09a545f8e7d47077b13b2cb195267b9fc2915daaab0b934b1890d200004aecd9c5dd6ff1f6bdee67ad1e8eb59cbe4628eede27ddd37e98a8a +d00dcd0f3212a3167403abed91c20e76f5e7a7678a4fd970f944d11e6a8cd149d0aa6fd3164c5a74c0f55193a4fa3d8ba6f99cabed10544625a7bd92b3e0b46edbd4a269bbc10518c5268c3910a2aea567ccd32d4c7a0cbef09ea42c20b636d1f711d220e23dacdb9d1146e0494401349749e5ed88e38295232a7effbae3aed6 00550406c0db882c6aee6cf3b6baf377375208c3e90cc44a067cee43efcf 835f950c422ecfcecb283de3cf5cadb21a7c67d88afb0a00a6e93df1913162be68a292123e78614faf0d98350db3ae2f00d0c14b47a9b929e95fe2ea076619348ea63ee58fad30810aeac2ce9d499ba5a55edf064bab88fb8fcf95fe4c556510 +3d36221f87157ca4db84884b8666660c4e2b6af330480c516cded9f3bfe132543626a39bb6aed1964eb5c33ea0b95b9841665417679fceb95d199d55accfce35dd3f2283c1a7ced57d0c4b9ebe3da6e1ff2f979b6440db27caf9f6a4bbfa47e20d29ae304f4d0551fce9cc4097eb2fbedb9b24680bb17d207bdccdbe799d5b0d 00257dc63752920b6854d6c2d1cca68589a38418c3d036e73760a12214ab 80e14ca7798ab2ae97e04b4b16de3241b0d0141ae44e4cbbb1e43ab2fed31b7b1cc5db3a68b846a12ce6bae69ce1be39178a03fb093d2eff2e0eb2756f937ad805fcde3a076af10d4d0174656d1591339541b7d3b234bcf7003547c112a96529 +033d82a42d0eddf58fbe3e91ddff7190e3f9fc2b1e2eede977d2c0473b358b5fce1f981ca6f88fd61ce2f79e453e3a2b77d1baab2b970ed28d5dcff58873a620e195085e61c4b8480d829525a1a944e8a4b63352f0291f0311f1f98ceb262804beec1c74947618f8e3b067866255878c2502966cefcdda4f5fa2b13d92ce7840 0029025352297a7be850f8852411c09259b83219135e0e8949c1bd5b94c1 969f8a2dab6ff2a3aec8d8e8278dc087614bffa37e449ff93a5f5c345d311ef87cf5cdb4eff4f06194fbf159bc9ce4640ee0fe1c270451b13b99ad05886518ae14167efefada8df8642586dcc1f129c58bf99c89a82118fd679050e2497ed721 +671a7c81b64b2919722d7b258bdbd90165bb757b53106e0af03d0eef27452942f40cf52bc95cc7f6567df2613cce795f8bcfc723b2735efc35375c001d37c58480d89343697146b524835df3dbd333f7c06c98e36d3c4592ecd1f34ab57c341bb0f4c785f5b8372775f74b4bce60763fad1788e77ea158d735a64861320b36c6 002dc82d0e69e498528925c0e62a13fda9af8cefd047c10c3ffc2e41da3e a1ece54f8fcc97660f90e1114094a78f1a14a71a7c724b0d6da05cd91ec664bcf0defd06963dc2f8d5f03c01ef356eea1658525cc37dacb019519538d64e522235ff3ed58b884864af89425904f6b968b406b977a7d29b5326dac9e6c1a307ef +0ef677f4799298f4aab73b7393598041f56e902ced1726af49657b6601a06186212e3ee8cd4bd33b760dfa2ea3c38884f94358d51dd479f2ccc8b0b352fa4e44fcfdcfbb24919d04e6ee1108527b8e8d60e8d1b467c30c18c5455e5835d483161d3fc26b4a67d6df9e3ddd9331247cb18450188752a1ca219f3396a872cb13d8 0041535fff5d279bcd744b04e643458ce20b81df8a9e01b1181d52bb14e4 a1a9f62e45ac1da1af136b9f374d62f0706ad76e14afa7d26f751e006a8aa0439861cf506a5e8c767280a185a97b14e80fc75d1e999073bea04ed9b564dd788dd82baf2a8a913b92fa9986501df9ea3592721a99edc9060a6a314225c92ea843 +9290df0cc50c3cab6655f3a6de1f4cf613d9bc06ea7c99f38038369ff2fadefa57a3c7ae7940c1b98bb1d03503cc271f7a891bf38eec93c31dcec7892dfd2e1ab337bedde3e5325ed8d9cb7fa3096f6fafc3beb3a66cba66ba826d1032debfb4908cc9dded8c0099c85072daac4373fbc428fcaa9a6da02181ebc33f0cf926fb 0000ecfe580a624df66c25e87e7689fc3b471d205970ff9ab51a64aa12ed 92adbff7530f61ce1c725c95bd74cedb89c0a111d2c1e493777dd5122a88c7b496f9b86501d23fb5a1372511312bd85f001006c55482f0bb39ce4935f7bea108ef2f558b5d122e4a95389ee66c3d6d99c9583bbfbf418798e7e89f5586d52a73 +855c7be75fda372f062709827f333630acf28954a62a5193ff675f0dfeb63f32bca418f7cbdb346bf388d62315b19a592267ca407120db93d4e3d7125b867c4c4670b7a57a76f61734cead2caf2425eb9ff0a63293e8cd6defc9648257b401463f4533a2425e0024f1ea93365eeee3c6da20d25928602ec8b426f9b39f97f3fe 0013c72c73358ffa168423149ecdd897f0a5f75a641de008649f00134944 8c5cad063894cc225e5ac722a10f4d395be2347710f6f9c8b4a9422b1cfee645e1e176996df2c951b0c452bb215026a3080500fce8b22ebbd109d40a15b4f274eeaf071154364506d3e133c28f73fe703ecc51443d586ca7500146eb655acb86 +9c896f800281812ed57d31623d563377a5c725cec84313472b90e73f77d400f5d4fb236255741b73d46f7e5254d04099bec274db8a9af5fc7cc220d42cc172cbd3c3595c49ff74bfaab7b5e46c90855b611f74753ccdbbabf92e011d52e9ba753b83ed2a251a632e1bd5c6d346e38e743950c8ce0f394a837028575fa44bcc26 000ac60e2e70b7c4cda64071c7738f68773c94df9456a8ec3bbb468fa7f8 8ca9257c2f81e469fb6d2af3704038aea229c2958b7864a8eae0dd6b61f15665f476d81473e6e91d21b58bc8d9bf183e17561ffb705b568c6a4ba48d3621c1be6a9953c39011ddfda92b60f6abf410cbd7cb00d1dd9d850685af236e325dbc04 +139a14ead998d1a962fa47c47ef2953aa136bd912fe940709b8c560bc2a0c4bf8f3aab30a8e21b7d5f487d30b0097e3da723f11b5cb4e8c5724f5a2fe0d68ee4bacbb85e5eacf18094d2a8ec4506cf8497836a4a905059a998ea750adc54c27c69cbd0b0c1f9743a62f3d988f3fa0a9865a73fc071f526623085a2ef12838888 0060bf720052e8b9508a801340c213cf53bbecf4975faee63d4b44fc647a a50ec1f82bf0811da069ca381bc4d62a7e6ecf54f8ee970732f25d8f642069f855089441bbc924b5acc4105a64f303420e0a690830534da5a18ecfff188011595d170268a143ee004e7c62926df1957657865038fe4e3cd73953317e1775c798 +cf4a8e754b23d0fffc1c5c80b0cb11deeaba3064b315bc2cee96db5b9881baf90d30af4b69066f757b3020706def77a5fc1632d96bafba22a9c8cd3b52d535d941b3c7cc02b7fe6b51639d5e2084478ab3a29d2f5e0e16639fc2833a47b58e2c3fb5b2ea1830fe2ff68e571a8f281617a23d9a28db1c64ddfb1083d055030e5a 007cf3c216592febd8630a478b5b3e3a605084020322adb13ac0a626bc7b b059e1f927f404ce5c225faaf7141f45a16424a576defcb9bcef4b980e65ec00e49713868ba148ba2512fdf0d37cfd6b09523e262ae5e99e5bc12d09146000f0355155d42a84dc4c79781e84f56f2d4cc298162af110126d628eed278418cf5f +ae64030d4af9b36c8d3a6af0aff34e5ab201df04274691fb420b7d5c40c401ed7f3ade96065d34f2490d17943e27156e7bed83cd7222d0d5a73d167855fbe7ff6c3ed87f20986ad8bbbd80fed5f9705c6c783b423f641d40ff1f367f9648af5a79ea3cea0236997558bd9dcb011ea4dc64d61ea1e1f85b4f696ed586bc7705be 0061eda5999e5a9ed4485d2a0ac5510549b76ca37df858ea5d95aeed571b 91d39508f72de5f69a25499fa0b6093c73ddb5f5a54e886e0c4b77161a27084b0804ceaf18c0c9b90c810b8907036e3e0c077b6bf711278c16d76ccb1d37e4746ec5767254f70010963f0399b7caa76a933cbc9de98a9e4071fd2d0aa671b8eb +94a9d9cd9efa3e4ccf2a37f904dd9cab5624ec9393cf8816ea591c5e70cccd2f105388ae133708fb974998ae61d218c71785f9eb808d1c28d953cc7eed00dd9854b6b4568c5ed5ee3df3b58a1e04c64f1c87fee4365ec9aa41b08a6bae234dc43a0bf2f61420acdb891a40f17f246972afee75a4c0b249dee0fc8f9b9c8a243d 007e7e73171e4d2f2989dc024757c186485435b82544a448f5cfca05f281 86c452aaf030777fa1261a50e3234f53f5099b6983de2b51dca1dc8c3e7390dee02901f373ec570cffb8e8c75889655603c0ae54c9d2e6963b247a5ed9cfb365b7c13d931b0c4bc7c107123ab4da01b5519db30997b6ece9dc383797c59fdc22 +4db998df7b90678b8aa4ec6233c9b4629800ad1f3e2cf8f7afcac62fc6982dcb290e44587015eca8dfe77dbb4a80f9bffe75b11e961e70deed14555db6dae47d49e73004f000eb8677c18f7e8234bf0a5a104266167a05ef07152e7acc2f0368b37efe69c0c2feb51eedf7338cf9ed398f066cf1f66bacd89ab9376d41da35a2 005f7270764a0444c7159d2db867930fdb0fb9fa6b8fc80ca02e11753095 826dab85aa526a4675058b54114fc0fc5c614d8ef34b6fb9ab991748df6766b0c9bd9a1e55f558dffdbdf1261806a4010cb2484b40eb6eba8b3f9e963b184705f4dc98739e2c97f5f5d6fdd75c53e293092e499a915c64e98663e1bdf686e813 +dbf9b8a4ae316bd2df0c80db1cb5d7038364a2634925ff957d7c03511b57d486274b2ecf191746827c325a14dc94daacd66ad86d369e3f598f176c4f0eadec7e9edd13e34043efbe0a801b75b8186b4a6d89ceae4fb250ab570d65b6dd7c04382738fe3f6f6c867a7d84b35b20720cb0036a5d81a87126f236833831d9ff00b1 00179b924afa4acf30ecbe2b3c12de533a1f9675687876a7e5e5ddc8e03b 89c5d3230ac26a3d2e23c82d8616abb68f849e07bb66b31bd4435e0b26397aa650c3ab4d4d7244318aa6f7def0a56a1f01d11c26afbbe690184714f2c524b0a4f7e715ad61134ac8f4aa4246268da59bc79ca86396dfe144652f7d22acb9e20c +986d9e5d636526f4deb7545c037fe81b09c74496ddb8e42e61650c74b6fe348593f0cf8f8eca5e839baf62f17bf6ad96ec0c71dc44fdf11259dbfe7499157e402f6bd5076972354150723afb632799a990c44cd0a4fa9609ec4db133e3b4700be3ea4a338e8ba1873d345e80163ed60d0de274d7617a8382980bc2138b0a2a01 002c9eb4d392d7f2eef606e1861183acb1fc753d666225f0f154d9eda147 b0e50393603a2a50e074ee58674dec03f33db79cddb002a9452a84c121baa7f8a5c22a2db606a6b0f932a704fb76f1151171acac25ab150c26afe8c8222c29aae65dbd11e07b047fc8e77c1c902348e8338400ce7d40d3d4d2ed512bee91aa10 +68d0be2883598bfb1433886aff118349157708690380c42b8919859d96db069c7fde6e117a3669f2cff94a0f1b66b27b09e3f1b24d26299e11552a084be428446f3174da2e0414655bdceb38e58fcb065b6661190862db39c6545dead34a03584632e988d0459659dc7c7c78d4d00fc2aa10465cf24b2410f14e2a62173c9962 0024661c89b77b2c743cc175a6130904461138ddc4ef771ffb9fc2c8679a a01f8600153c0655e5d2246b8e54f68d4d2805e5e0d3a854699e58c15f6acaaac505358e03927b107f50a9eab767c510151782881031c5701ace01dd2564d3bb400db6d26421fb81f7030beab97e4cd99be51ca21be4b3929c234f6dea6f441e +f0ba0407485fecd7337f4b22236533a926cc744a5f06dd08276750196f1bf7ea7984278f789f92dd07e36895a8bfe297ea43d4a1177c0368900e3b969d3083cbe626f0e27e7ab38e185c923dff46d9ba187b2acb9cf4b23ec8eedbb8044b96b5263d956e50cd6240c66d5d96517130c743752404ed09473f05d0004dc5971ff5 00065e20e5ce534576d7c17616cd4ede3bf4f500894850723bcc9f895f4b aa37d5157e07861da9657bd64ca7a45c02e98523a405c37f6dc892a8cb445064d6557964aeb35a5f482e2d222edf7ad7044b8c95a24f7de6e9be4edfc0547b1580f0ff91f998c6e95295766515803924ed5c5a24c292980feb5f2b2793d3c404 +3827276694e413c886129c452c9a66e7d09dee84f5f09bf34e4baa308b4627e096c7d45cf6ef45ba1d9a4019a60399feec10fa80e333e2aff1251c85ca48574d9b9e1affb9666828dff5afcef3edaf5e8cae823505a0c73afe76c1bf130399fb06b092ba34ab0ae15ac6c682f9ee8479b065ce75b57213b8aae0f55e4e386de5 0014c85f66fbbd653f1e4e590cffe62c343ba6062df4b271fbd02e5d42f7 b10ae9c9477dfbde8e9979a68ebb97592767ebc65b3b2a4cf4fd4adba76dcaa01fcc017b258cb4e32d94ad4e290aaad011788745791b3c3a06e598eb864ab901696603e86c05bc26f53716dbf7011a38b3461abc6568afc488af7fcda7711ccd +d1afb8965b48d66b9acb1ece674d9548f83395275f2d8135554cfcc7ceb96450d850dd874529433883709483d0743798db5e0dee955a4f30ba328c7934b8dd9207f3c336cf89141a175ebe23d2faed629eb4236a8aea8300604c3eb7704512f240fda66acedf1494a85058dc6a31bf9531958c332b93cfe5545046876c6b99e0 0030ac7a78593b570b29f6d3d267abb6ba7e5870ee1c8ee4f1ab2f141051 89dd6eda456420317a1bf29cd58a63f4641d9bc0ec4234c0df2e1708bb1b1ffa597fc417f812a80f8db45e84fc1f82300194176413639e552ebd21ebad186551aec060580ad1057ad919b07b9aece7612e5bef3a55e0fdb91866f140945f001d +4f95b71669fdfe5dc46d4b951b085e099de349fc740535175337127910acf24e9a0e4b2f23196ad23880da47b740d77d74fe9bcfdcc44dd7d8d1a181ac290de5cf4da22d5034cda3d8020bcc776dde8cef1786c9ce4d2c2cfb035da61406af745efb7ef1a55f2eccc5000319cf1d6380963025dcea641cfd15a3106751fec286 006d7516aa040f7d559cae248e485834e8d9bb608279ed4d4f7e1dbcd2b3 aa1251884c18249df921826c648c1dad0d59e89456b9402293f043f44dc777715f1bb270d3edbd04f17cb8ef1959e49817e9391fab971cc9597cd446237507ad8be3023e5e19846226d10a30b0e722bdbd7cb52580994c3fec2ba245632fb18b +2ad9e17780c824c4f2d1e1cbf19ab85638f2f71cb4fa3518f08085b8b358f54d4f08394a5ac29cbb3cab828c5f07f41eec51e6cd61a5f2cf44dbfa46834370cebdeb328fd3bf681e61011b5c2ebc8945ac7a2a8467606051008b15c89390e111999255bfe28634ce9bc2850a2b55a4af1c4c2f94403c78aba1ebc87386ab7b32 00137050d7b455f43a8dc2516cfff5a91062c1a2727b27df41488f3dcf18 ae22d31fff71784d351c6d6e437ea7d9e06b7b2c69e762f6f19d89b1ab57b07db57bb16bbfd1ff8e88fcec63845b6c0c190417ce36aae7aaeeecb7b5ae875e3e91d7c7614c6a0f1664e7a5db536b4809c3b5ebe7c3183b05222037ccddac9dc8 +958773c37d3eba003aa5c489f72118b3022c52b93399e9d8001695664918b86893f4922c7b6e55b1855ed0fd1d8de5dc61af403ad660fec60d7c44bd0102c069957ed804d0d416facdc1a95355ef58554606579ef89b1842f1055cfa2ae118abbc485356824cc09dddb77d0671cb3011b33bc86cac526e3f6bb3293c7bdca1ff 0001fd447b33a2ee3595b9f885c290d241422afdd74c3dc4981955a7e9ad a43581a0f0ade647034d7ecbaef1f7912802fac683f02e10bb60ea7c9440214b3d16b256ff81b7b02a0e06845b72efc5088926d932b5d2690a5d5f282d1b4143ca4f0e138d4695b65b527be02c64b38bb7e3651950026a681e781c13bb729021 +9cb2c496b1bc7f040228571e005e7e936e48e8f469e295edf914f5648701249a20bff6b98b5e862603dd9f12bb71c160aafe9df02e2e383e9b8a9a9d700f4425ce408feabbf754be543f52204c849fed6c9d3e36e03dfbd9e35c18d7bb2295f1c484a66e73440a0a5aece5fe80b9ade9321ef18cde3eb2db15e4b18e788b0441 006a061e10b4a6e7001d95411cb31bdea9c84670a59ed61b14fbbb05c8e7 ad233901fa7fa2f921e706dc2363498fd9bada1c0bf02f5ec49d1ac4a2711ba41199ec743dab07abe74221dadceef891136a1a491da16214c2ccf0fe38e937ee74a2e142315ce3f4bea1defd6bdc9297ce06e10531e43be7051539638333db1b +9a4bc0a029e97742ed3bca207d5912cb568e4403cda106b00247520ea02008b14c041b8c9b976294252da835f4ff27456039d79d90315abcb0b9b6958a22352672e229665457ec79571ca80447c8ff2a86e6af3dabe7427c8bdcae65e3c6746a56079ce2cf8d22235180f46646a21cd9e86032cfad874cb9c67f882fb037a13f 0027ec31ca31acb4d2fbacb49fc085f1261b0042cc755cc97f9b199e7a37 b8e08e8766eeaa74a2514bbcc17b242e436b789d3f228a4cb8a9f6b9d7891446c3d313d3d6d4b784ec7826104b7f956611059ad223e44ba69e24e4df8d4b4e3f9d8498e0ec4dff114d4b546a33ecb38cbf24ac48a19e83c0906be36da0f91c34 +8d89e22cf802dc68ff22d43c436c79311e705ff6fd845e77c880f399f403e6d5e9e2b35511553c978171189e288cb2200fd95f84ec5ee9865c0eb9190aff6dacf783ef200e82027fa992741876456472bdf27f2bd8ee55db15408c957a120eb64cd24d299818726a73fbb0697eba726a326719765735b37a2dcff0c853c906bd 004c6f4d88e5a4f4f83196f2dda9dcf2a66eaf94d50c851f59bfcea1d876 806a2bc11b0a26fec2f425e957493b0bcbda89dde95b894286c1310d47f82d97626aa64d5d0a01a7c962156d2a917dcf16b52babc50c63e49a8094d17a6be4b392d50a507ff5aa8727bdea39a0fde049329bd8ba5d4ee1415edad9585cc4c99e +aa1bf5a79e5339fb9ef6c2817bd95725551d064bc5064d6586c5a879901adf808dc2ef7c78ec3b434b84569988db58b5e8e9782b1cbc2cc7c9b68e66f32d4ac4ebe7e75b345f654c7b8a5e650acc9f170f75b7aaa3957cce248cc69cf93faf8d72abc6fc1cfa9ae2d18a7b31ce720147e88e84f6563b2197882fe302449ac5ce 001aa169ea84365c22981bb766bfdad27e373440850569957544b0f9332a 8c66ab469e348ab6661ed0b3b9491cc54e03c458c1bdc799c9c25429dd7333e6b3c4822cbb366f16e932b4ded23cbf7b055449079a0bb0a0e1895795589a6c695123d86352a6fd51fd5354efa71928d50d99c34c870c61f14f6c5cce1d566e51 +475664d5e22cbe0da0d0289ca9a666a37270dc71c81cffac91f6229fa39315c1d55f7e0a89b6a7a07df7d391dbdf8fb7af63d2da46ecc3b60110dbcd842da97f98d2b67f562b0364ef8e1c589519024177c8ea079794f271f6d35554c0e9d0a39062383c95721b72f4e74eaafb6fbfbda02cb670a7c4c94f67b8ebc6442e84e3 004a665b92c0c33a3f8b9eb4b0ec061d40b603de36c87096455102ffe57b b5ea8652a2a3afa45acadec38c5aacdc2ae70dbfabe8e78be055b665787a1cfe341374cbd4fc979310390d6150891bb00e201f56fbd0ad42d2e33d0117215a9757e8bef4bd5f1513fabb7fe8239f573d2107256ef3e0617534ed9f5e1aacdd86 +9e5397d94465390a82a3c07e3ebf21b515776d18b4463aa5810e6b2f96ca61e92d13e034fa853c3fa45411f51f79df6f799a2c6906e6a5b7896a4576a4464f9e0be2b529a43e1f503fb640d79db6b68f3a3a7deac1b5832fbe86673784ff6db1f8438f7dd332cdd1e7ad9df8b6731aad1b6a72bde52e6bc62d80b8da57822c48 000531540d94823e19ab2b95cbc6e7492e1effcbabce875de6ba96f53aa9 895bddf887ac7c6f091ed40c9a9a4c8f45fbefbfda05e077eb0713a9b71a6eac525e8692fbd59950a7239d3d82a34ae300b7dd75aad7eb1e0054882abe88f88b65a7743d99f38055e97599d8dca190bd6365106de6e1e468fe710493f4f88d55 +3cc4c4192f317e52df6f8cefba6d4cd823c942aaee11b9a0ef5de5c2d181073b7085a55805e9554def8dc13eb978e7396044d4f4a14be2c7605998c062095c929b9c23b2b1b2fa73dd19a0c0af44ca4789f9841fa62dee8a5f91b3cc4b3264f5f67334c3f0772b30bd7431c3fbbf1f34318ce1889b6e8a76ce6d42079a451e56 0022a89addd8b85809e87e0aa2c038593ec277054842854de1197833a51c 9906f606cbb99930e949dadbac5fbf22fcde36c07c12a8fce621764b49887a7a03f07306a77e52374429802ba396fc910d3764e7ff4a1343cb9107f3c6b2ef0f17621d57a40394b325a8141e84870c61c6221133b9a92f52b77a7315d65535d7 +72cdef5bdf710978e0aa334b86b8ff4a58630da314eabe98b4d611aab56f55c526983d54d19bbbf9ddba30a84b18aa0bae9f9503e9b222f842f084db83aa39625403213ca321cc0d9c8a136c826e6ea4ec108b913dd0a9ce9d5b8c7e3af53c3876e56a2037ebd6d99f037a097111c837647bedfe4c494e4288ed6427c15969e3 001df252a11ff97b4421b3a2361db94e908e8243cd50d9179f9e03e331f1 8f4f660f9268e702bad54d889d17b4a8a7daba26a16e26e982113a46bb7568f6c39b7a47d846d773c09c880b074f07a308626657a8dbd2421ee86b418b594574d49ac1d733eee90d923ad9e968311d70398250fcc1f53e7a6ebedab11f18c202 +8e4eb88c0b2d525b2c58b8e00f32def90e6dd382301de49e0ac053dbc6b61afe926d85193e2c4948f7402a3d7c614cb2c58e060362b0516a1ba4a7425f1b3d09aa20d4c3c8993a387a3248aeec51e6efa8f558dbdcfcaa13ee08413227c8351e3107e9a3e3ac124224aaea91bfe50c11c1c8ae582e718f50bc5d5c06076517d6 001d7125c299ebd0dbcc050f07de931c7ad0450af590d0a2d0228a66ac5d 954e43dbe288c02a36f14c10a97aac415c4498f571e93532cd49779d93482080512c1b32021f0c842c53cf5a4a2255ca07941591e44749259f5826ead64441f21044c025dc017b559a23dfeb84469954fb6507f787d2e303bbdbf0bf6b1a625d +370fdd80f330311dbb3959666001bba61cdacf20f72f78953d946fa6cba02d24b5003f5452d535609e489b9434f192011f99f918defe877d51349870e7e75502f61145f7c261dbd2a0840926d824ebe9be3c5a77a3a84340aea930378367ed3615a47e3f792c7773f83f91ebea718a05fc62e9ed1d78629b2c27ae44fe8f8d4e 0021238e66119844b146d40e48341f522f6ac2f9c8a0b33aaf95a3099a41 b1252a8e2d63ad74708ddffd31975e628661e0164081ff48a4d4663729e30b1baafa77f3df594fb0d40c0c9d7cf9012d081294d77592e2fa29d631cf09d093ea77345c9b45b7a987644de5eaa54f630f3e2d66caea0acd866832e319d843e4e3 +f86c4433787c3ec3cb1663389ccf53d62f9425274ccef05fd14b1b8fef676208867764eb98d16d006ee6ebdc27b8d9a8ddd303d941fdd82b630694cdc698bbe6bd524411907834286c94b24ee199fe6d646064277f244b7df3ea2d9d52a9dc6a33d7c8d6dbc919da0fa987a67621ef0829e48310e0ea2bb86fedcf4effc0b94b 0015e1bdfdacd87c42ed439f3e243abf27fd42e54f3ebdfb47f60dbae5fe a3a3dbe7034aea1e4daaf62bf944436981c932d38a70c004a1a8ace2ad1ab5e5ee9b954c2ebdcf51448ea4dd67a935a80c668dd556b5318cbc914111ffcc356f008d31ace45c798c6a80d95725faad4206b06d8dc830c25a2a93e81a65e19f3d +4117d593aa92e3eae1124ec7482737cd3573fe5f0f2a5051a7ce86946a2abb9e47a0c6ea75b262689b0b486476d2ab09a20efc2fb921419b1811b51a2e15891ae9e45a17ab4b96c665c6c423fc00e2d66df5804a164f0f3c958df6f25d7da6829b1fe162a0a8cf130858c83f3555d6ad627db70cb41303cc6380f7b3fed2563e 000e09410548c17bbbf28a68c3963a52d39743a4f1ac28e6dfe7a6ede281 843f173c1d5101b96719f1b5d8a66d3bdaa17961ee09b90313e564288918407f77adb5aa09febee9a604523ba105e9c205571233fd97e70abefa9ea6b7222b6e09d854c26f1d5eb609b26cc58255429a82bef0eb0050cba5f10f68d6fa63172e +882ecaff3ec8f4023df5397167f238869f78a5c499be19aea85c7486e73f66f0e08e71cf85f3f1b6f6a70796bf46a18e6b555a0a87c2088640ca73051b3dd59ebfef922be0372208fce602d8001681297b285701dbbe24ccb42541b5db4aac1a1c7f407e11c83db15b38cdbc25e930fdc6558f64d9503e214571a435d890169b 0049f5bea6e72d98579b78cb07d89f64503f8759dd7a73cd73713c120428 8e5df12ed21562460b5b1d5971488f4a4b00eddbfa4168940d5450aeae8d02abbbe70b53e1e475158350c4d102ed02940cc6b3090f8e00342a28d1ad4340ce26fda50441b07d22bba94d8d9d43f715061565a508deed6ad9cf11261904c23c7a +99b3b8f876f8359bd6369ce84f9261581c52d744b90261a1427ab9e447e6d833b6b3e89af8dc770f1dd55692d01c8bbc4277a729fddfa7cbdb2ec99133201dde44ac691a77904ca816feb0a1aaacbb9fba85048bc63d73506eb908ecd697caf582747051a3a38ac8930c9a4365f407ed94ca7f2d26913c53f4c010c7ed9d7ca4 0005eaa818690d1ca4838f0bc667be5721d178c3869884260fb230277c3b 85c2e036376d3e9bbd736001c6fc26a7b388e268885a1bd88e6ea62bbe4e8f9424663ce898d004639650b8ee03714bcb0b09aca57f64afa56df9801d8d2dc66f9db1b6123368ec4928d5ad5b13cde7f97f7fd7b169bd6cb1084049a1fe419605 +8c1a83023930a85c5b2f9930521b8b8963d5523a3323d87f862a17d3505ccee01246ee1029b8b8c2b608772c4096d1e914cb398f027d91184a8e94e4feeae121eabb504a2a35c8bc9294edd15ddd979946c14c792ad787dc2d4deffa284830fc90b3f8c0ced6a99fc6de7c41b9ed261402a6b3d702ff86a9392731ecc37430c0 00603d89cd2f741d734587e77554fe6bbb1e5739d5ff73084d4de8ed69c4 ad3a5f9f476cc929848727a0df5eb7c19ad4d59705835ddca11288583e55660b096e2a88f7cd2cc79c45e467760ecbfb10dbaabdb441b08222002f993e9e564cc7e3c5efe6fea6bce5da6a6f1544c98693fd1dcfd285332213a62863a9921722 +f3c9dedd7115339dd3ede7d8d06a44de66bf80b4888ab7bc386cd40a92789042440a13d2cc90dbcacca5feeec1e0e3c51724146e2c4904ed6b05c7b4e9b49d7f458ada695c5d2fc36f1193329b87c1268aa38eda9151430aa0bc004e5d2a61b9390accfc699f2efabfec785eb34f52b1beff1e4c5492e922acc348667d2a3986 007977b3aba53616dac27b4d74930da23966a88ad98f1769674789c0be3d 839cefc0cb33f414f7ca4001dd138d5961f827aca006ffe456bcc98bdde905649e737222ee2dd0560dbce0b48514e47d0d17963e0207b78d293dd3e8015bb81ba0d6277f49180e0807340b0e566737b47f491ecb6b9335346dc6d135c3cd0447 +d878c4ee0bd6c84652d7f9e68df7b90cc78776d8d1b60f3e4d7465032bf401f1527ca7bfd4a3dd916e13e93fadaa5e5f20c9f47d12f8fc922a9a3aaeeeef294c221ca1adf7df85b888faec8002f17ff202da1be837827619904121167bee2d2cd694a263d9a99062cada3399dcbfcb283597a96ebec129c65e0850ec4cb4e2d7 0050cd20e7eabd29008cc977d0a17e1195d79587b8f15ac2447e15daafc0 87e530d082a103691e8bba424e88a464de4fb119a6e979d6ce767ece4c952d8f56177e4589742674c0611ff80472164a03a9fba243b8e20280d765fa2c3ec19b90c3b8c468361b7b43dd79aa32c17f13ac33b84c338390e2b170df97e61cee75 +ac3c118cc9cbc8eb3b74d8ccc9ecbd81d1996fb25ca43c8a43bffeb244f722b93c9e969241d45d5b81fda0b399f1e3623687190e428dae077e54cad1eff75ec2f7fbb9434bf716833421bc2634885677579c237340f76787b2eb19b446d56c0f2206099b81493349f4db0ecad0e2dbe85dbff7d7070abb3d3b12ef0cec828af4 002dbb24fcaf9f3cd5d50d209937f0e2d134fa20ee3c9c2f1fff3dfbf302 9541a1f1517b3b145c45be9c9ac48190480b892eee1781a7893a8cb4a9a1e6104b693c6237179c6de6b613ef23e71b2316b4e2d1d3f992b675a9c3d7fdf6ad8d031ea3b0cb281a3dc01af5008e08629799d9a8193f4492de514cf115f48c8cd9 +700313698cdfdcf0044ca07bf9e5f0702ece7cc66e35decb28d5f8cb7e7e5367a95cc1728a90cc9a53a2b5fcd4702028b742538e9b386f5d8b4a2411579ed9553021a95bd00a73f03c4184a6145aaa367e3af76659d677fe7a2e98f9ddf4aa20eb8d1a1db72c3f5590598801be7ebf44255fd7376d89d998b7068bd1296fdc38 00047142197d3d43fa46545b547968680ec81688589d1ec8d7c7e90eb969 82781887069711573f834338c70a1c8fb378a7b2eb241a793436d602f848f54eea87ec06451cceea5f8b79456ae1345f02afb02986738bdf313afd0a1b5c65f0b8e4c7b85cb351545b7afb4eb9992b11f63ecc1b5573a26567088bd10a9a4066 +0374673e1a685bdee55504ce3cd333f70084dd4ae685464a16924eccea34531663fda60229166478b30193459a3113253cd6494dc26154156252dc6e822552c7c04d790eb9f8fcef2ea8dd79e72f881f7f20fff93cd73ad303c0918ec27c6486c4da61f82bcd55422d16650cc68bfd4b0132c1e7075bbf17dad919095860d445 0031352b49ecde5434aac05f898e6ce4337304845d748f114c14319fe97f 90eee94ed7454f009b1859ab3f2e71037fdb1709150134d595e9266065758460910dbcbf1d255dd1df24511268f800980291d194c4b068690d8134d8b1f1a06973199869bd74fbb9b3720cadefb720dacd01c4ded0f9fa56afac6246f3398364 +8b237085f135d6e94592f8d855ca397c8c1028236a3b412adefdac888245874f586d06950ee18118f751bfe26f4c31465ec34b578caa44cf1b7109ac4f6eab7f97ff9699b34271df035d3bf58a2ed4bcbf7577cf8e5792b1945ebb9389b680baeb8518c8fdc5540e192aa4fde0eed0d7c82be2e362b286f582d65752c8db7038 00176f124c24e4420f6e726a6ca25f09dfa0c5a37e5bf879e7bdd36c3b65 829f7b26fd8b53c298f29907e9dbf27efd261a4d85de1da3d1b42d67ffa40cb8ca9afd5cfdf47bc9b18302be48db1ac705469fe6f7132e7adb86f8d323e269e7e09d77fedb853118c473cf6124786e9eaa20c1bd039337ba68654a75e1cda113 +e3a086ec15574f7017b3cd5f5a47ab7a73980f11074333490dfe9f8ad8926f9ea7c82271aaa74e77133b1025b0b22a6900fbb71251bb6549341a23d194e79d03462cdad52ee0d1b6f5d0d14e1136026961fa3467ccf0864bf7ae3fcc3b68cb35df7324bd9bbe58fc8aa9f63c19feedf19d935b71bf5981c74fb2a487f84e453c 00755c48c3dbaf71042c58cb137f3632e3cf9d90b7b9a58fd378feef3d19 a22fb388e5f75b4cafe631fffb5b10deadd12bc93fb8254b27f9e49acf2f930364c3952144ee6132e3f6c9b7b16d7628078f1a589bda2e78ecbc5fe8efe43356615556bfe654108d99fe935b99aa2b7dcebf725740b13bedaf8066f848a7ee56 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K233_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K233_blst new file mode 100644 index 000000000000..39e7a1ba1773 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K233_blst @@ -0,0 +1,60 @@ +f23f784fe136c9fc0d169503d361e9c6148b0f1fbdcae0a97fae1af7033ddef25cb7489c9963cfcb009a8cbfe44a8510a64a073eb1deae4c324ceb9302008c92c69b2dafcc9077fd3cc3c7c119edc3ced36d176ceaa55ac036bf7f07f6fa215e8bb8196e59a5e1c9af4f98b90ab4970885bd7015fa26a09e03c7cf6b4b23d929 004c1d414696cc3657dd9df73ace56eda2636769ce7082e064c260be45a5 8b7877429032da24fae3ed5a4cbbaaede07d39fd4bc3e00eb75c4181507f99c6b181538b3f196789fe7b00135dcd237d1415022cebb87e8cee32549bddbd313cab0ef20a0f601f6db16ba51b37303f4e5845a314091fd27ba1c668d98bb98980 +400bcb297552bb37f2f8135a9314a35f5126788bb6fa4dc74152731ff64c5dab4b902103d85443dec20e16b1d6629930cdc2bd183d4099f0e96295a63c2fe266f5e9d050c401a8681b4a438efe53cbd8f2f43e2a31e9f88926a9c82917d873f6e8cd5ff5eb8c1ca36126b0bfc8c2b0e85a7c9e7a45f1875ca9c82019ebedb729 0027cb1d84865a16992476c9e353283d5d6a40c349a8e9179d1b1f403531 a9aeb5b8dc0588ad44eec268dc50df1692fef251bfa86a7dab5ed5f53d8a9dd24da5f86ed21d31d2930e2d05a5fe633002a560dc16f437a33453215444abef03a03173c6c0ed55c82616a6a8457b779155f2b21762aee5f95f89fbe55bc586dd +5f74d4b35c49fa454c97c05fdb6b9f6822cf1a2295f15bd766dbcb413d77c910bd8f4147e8f317fac2300fa21cb80134d1b6f8ae8e50518c1f648a28506e419f5a6e8f05abffdb3dd2587606c7e9c223ecff4f46b121216730ea13202b59128a7616bb2fd23a7e4a5aa08641cc07b669641313febfc88d64d99447353dae3f06 0031b443f46c4b5224237fac1022ee1570173f664aba0c84dbaa4246bdc1 a97a9893d398fd0c3bdeea1b54d4b4be9b0fccfa23c3a7944a96ae115f1415e0ea592f3f670cfa2dd6371506027d62160fb20080c209babc90190f51b43d248c64bcf6ef7d9499298207ca8f3e43f1584aa2a651d1a22fcc6120808cda2cfe4b +8f92096876d9f81bcd992369d42d0b5877ac969004d17c8627c58d8b8b7bbf7a37e8cb6afa962b9b043bbbaa5bef4a5ee38d8bd31cb5866b828265a2f4102a616f87009cd346fcb8af5519fb577c60d8792472232f33dc615655e53d2b715b15a2697b492f108b7906e1e3597c6911f8cc30c7121ae338a6b747ec368f8e4a36 0048f6ca29f35f253a4962734357c995920967b9eeff1ba5fd2080bfede5 90b0d13f2790005e2f3f48a4eca5e37000e83c89de2735c7b74186e75d6b1e7a232c86cb72c2c3eacb9f505638f30b2b18b480d276b78424d8c91b2da75ae0d859d56cb5b40c4f79e82eee5d77f2f84def9f73ee9031d10e2b98f3b2e5ff6fd5 +3d275dbde44494c45fc15fe89e2ae32aa26426a17e923e895c7941a5582fb95df4d49873ab1bde358017f336b911b886b626b744806ab8113418473c441f1964159ded1b12122d53ac56573167588e4b55f36b8bca8c67823883a51fb6e7f204d1c6b07ea49b577bfab9ca6b8d51f72268b022e3a4db6f9d265ee8382f9b7b66 0019b940eabbe682f961d9f3d90432e347fef3910e641656825d775705b1 95259048cb58661b5adbfff6d81586682cae416e9647e9c6e78550ede87bb3dc2bfddee68bc54b10a26f32d304cb109104a3b8c6c3ef4d1901e90c67e7dff0130ced3cf9809b1d3b7d72524b5ac6b3085d8bf5f452b7be97a89edc9c157bfa09 +d2fa68e1f7dad02916b12fa38f1849d6d409dbad0344438520b4dd9b77d62d39ac9ae3cdeab03ccbcfd4de703c6e798873671731c108f322b9f2a68145e3e210c9b15b879798e5c53c5022742e9819b99edabb2f44d89ae221f7a99dc84421a6905695ff91928db608f861745f17584d56e34b75c47281435b1b0b34e490692d 007a884b22e29fa9fe945e9ba13c0df8d786dc87cef0f77f069e182dd56c b53fd33b02322a18494fe7f55b8784684befffbe62012df15035473ce42e24a053c6383f724dc95c6e9b1cd3536a47c903fb6d58e0961fed54f98bba9c1d7bd956b4a51f679ad9fcf228ad010bfab1204e5a928c917ea8f5e4611049b1696e2f +3830f75cf9df4eb2998c7c1b5fe11c1476bcf849c3a8fa7d3d0b5bc2292e5d07465ab8cc9381c575d909e509c5dac49c78817c04e4bef18bd51bb09aa5897f21634633a5ce6d20bb4638cb6c3927351eaec7b62cf4a33956916045c392f325adafb10a88a5f86d7e41dd77908fa7284210071c22aa40ef40da6339c02da05392 005da61f881d5a0dc085bb93764f584352882923cd237d878220ec624c1a acbb80e9f67b65127c1b810ba94cb32e63d61b2434c13ab66e8e86adbecebfe1a9d20d2d6ac1a464cd3929212d9046b308cc584e57daf900215113574b76cb77f3cabf488135721c861efee18b1a9cc1f609eaf9fedcb6ba38ec8eb3824e4619 +65b9fe15e6c35d453caa6bad39ee78a720a04b60d8a0a0f049186d2f777e48ae2d657e174df53edb7beb9f7d8f21904ed674add0cda5b62a7308de76c324a144021e8c6d387daaba4ce48bf7dfe9c8aeee2c64e434ece1fa5ddcafcf3e5d0013a1eeec1742a00d384cc2ec0d7eda83bb4dccfb0e57045ebfc27a4f404d03da37 003fe9f04647f6d82b13ec1ae5a8c2e49bc66b05649ad778eb16149ad83a 86c204bdf666b9624fbd739ac7d8c7b24596aa391c6d5d395072fa1176dffe8b709146c26d541e99881d9142dd63689e02c5f1c1b97be19b26a5b10db2024d9daf3d93b480daa94118301cb6159cb7989e92ee3468f76491ce2859359200a3e6 +d26521fd41eb5d46ece6836e188bf9cb1b461d011c41e002a935d256654d01725378e845920ec4a7fd3f379df54772493df50d312c7c6aa4e909e7b83f2442c3a5e85c37d68aa015098ecfb0a5e077370f4576f4bc63bf37e1dee06d780a3b6949af5e21c2a0960fcd20821ef5f17bebf5fd5b3bdda260842cbbfad45667287a 005ebce648ace4cd555413de6a456fc487d14bf4b0b9a72311ef480d2f26 b22299e86bd3ec54d883135d68638f3e0958177ab3d155efaa66060fc6c810afd66289bdb8c94e5a330fed5aeb8fb8fb0161ab207332c399f081d69c672c7091362fb70b13661cd906fee139235980525c9b3ffccf0b1633c72fca74a1ea8e13 +b778c021b1a92c41dbd09963da07018075d73e54d62df5c2b7bf8abe137151650d1c1c6abce7eebd8f32e8c3e6d1433773f257bb3ba4a4fb6a02c0db1e47d03c27d3a90898ebd1927c21df24c4c5443ca5b81f8ef2cc0f5e8b3d08f472bf07085df737adaedec63d99acd77b87ba98225f198b791124ac2d9b191cb9251b4b00 0056653c2f85593f789a926ba49fa3da9d7f946d8f1020508c5a527ce813 b6709e2cf0b4df46141068061ee7758edc3fd160f675ccf7932b549c5614e7b9d028ce1ee04d1e983d2d16382e09ae2018f53e7654d70afd2bf5b84fb78c804203beb86bd27418990f84b77a79bd54a1153adb30bd23608d08325fa01aed28fc +ec14e07f615960015a489ef999e308b42a4c571473b9bd64b433dabd9a1b1ad02e33eee9100064405175928a94543a80f440040afa2965b4e5f95f768e7fab6d3c0a5f5e1bf1df7822f78384e80f2955ea85f044ac60537d895747979f935bb0cd3673193c4a32dd7803e48d7daf70a71bc2aa97236615b6411e28fc9a652145 0049a91d320783cc70a5952c32036cfc75d41f1aa84127db2dc759fb291c a185628da124be3903cd4b49ad2fb657d0b55afcc5328a1d44e3f40814af2e382fbc194ea79bb2141cb6f328ac0f8c0d10b0cb0b410e93bbdc0fc9094a77685b32425d07c15cc4c99018c4f94134086a80778ba9e695e36b4063bf037a7afebd +89c645339ad0eb850e4e2fe583cee175b35feb02ed7541d7e9aace24cdd3939584f73ad39526de6399c86b36de77a018e2c70b532bd0f032f9137d10480acc30c49f9baaa86f9df0033b77e98b485bf7a69cb5c281e527d3ccd1fce2415f0dda4a268ce68a0a34b16afda54ed922cd6810ac8dc766df2a3a6c5e55972e9786fc 0016a20016602fc7088a60469843e1d29ad67e3c3cb9500b1e2a00d4050a ac8aa5f817d7206ea3613810006dbb097641840abde4dedb37836686a8fdc4209d4048c28eca0a4187b93641de3fb3750f1e6a264b7c1a5bc5263ca6443e8f8ba2a0198c06031008a2312ac7684022c593ad40ea4d026aa5f346d15b7b205e72 +ace14c4b101d2d8453c2bc22b756af016b5de537df9c3e639d208ad04ae0bf6232dc90b90c33228dc85de956db771ffde05fb4d0b15e4f218ed2771d703ae5bf981252a5bcd60c16f14483131a481cbe04dc0adb1fb8aa32cb48bb5008e8a8e5c7b7465be2fd7afbc811cf5ea6293b1a464669b49f55f57b93a8707e6042fda6 000ba922149bada2551b7be1c3df076f3f97ce93c13c50c285fef3f42363 b066ffeccd956a1b7efb65366e6bb8d2ae3cd13bf6961cd2c75c92c155f68782a036e05710d16f94973c50249d52fde3108cc3e9073f776ba1d51ec806dccf5b38691850ed2234923bc0ad09451fb3736bf2af9851dcc4094a4b655c2d7f913f +cec2ba0d1772c87e87d5bbbd67220692bea4301aa1a66e8dbdd7e651d45c26dc2a0d45cfc32c34d76ae3e1c61db7b0fe1863457b93937d929e6ece7462ebd16adfd708353d6f7c27aafe06593c76da7149b0cc574a4290b0d8fe219f3eada7082aca38dba3f78ed0d5942d095fa5556fc8bcef331ff0a6d5d1f4e6c51d4ff5af 002d635e12a58cc6dea44e71e87c37f91e8d08659f0b7955d24f65ab55ba b62c1fa1901cabdaf18a80bcb3c894159b93542009c129a05d84237f9353e786bd6a2d9f0e670918644e19f11664e860082dfb09e1a3f9c82c601dd58fff0f48a54d4b51ea73d8a0d8b845be4c346617b02abb0ee0a9d60040ffca35b44861a4 +ffa13cd0f51ae2643d5d4edecb493ddd653e9faddcffc370e7e958abf726a5d67a2ab36cef42ea8ebe22a6f01b9c31f6ffad01e6894487d979acb5e618f765ac0ec3550ac5dbbcede8f9fdbe52fbaba5c087ff382b6d7a09b2b5084227d324d98ff98793040884799b96d2ca593201f4414f18c43b51c53c5e5059e0641aca02 00073883e5064e06814fc4de32e15f7a6cf825d2daf6eb1df8c83e25d80a a8536c1879e93bf18143e38c6f2d2addf96bf8efa17f2213d56dfa24068ba75b2e0316810893bb5acef89dcc088b280014ad63f323f2f0b77e1006f4553417eaa987b6fcdad5f802933cbe0b68685df7a69fc3c2c8f78f161956deffb2ba34a3 +c73e3dbac9513d0361dabe94071faf03a11cba18c06d131a172d5f0125b01a5eeb6055bf72c7106fe3f4be3bd2b1771cbe7f85366dccfbc3bac20538510c3f51179cc540ddafb2f3b05a0d276899674ab1d7d8fb4f6838f04e4f9e26b8c6af31540f63f4953c85840af4c57dfa78c704f637dfc8dd750fe45e2c1e149986d127 001532271bfae8d4dfe60f69b88d3006d58e28aacfa701861cde8d624db6 a0b44b02937ca5fb886013817658da4f258eb8fb60b180e12f9c0551a1f4518dee631cdf3d8c98a09a545f8e7d47077b13b2cb195267b9fc2915daaab0b934b1890d200004aecd9c5dd6ff1f6bdee67ad1e8eb59cbe4628eede27ddd37e98a8a +d00dcd0f3212a3167403abed91c20e76f5e7a7678a4fd970f944d11e6a8cd149d0aa6fd3164c5a74c0f55193a4fa3d8ba6f99cabed10544625a7bd92b3e0b46edbd4a269bbc10518c5268c3910a2aea567ccd32d4c7a0cbef09ea42c20b636d1f711d220e23dacdb9d1146e0494401349749e5ed88e38295232a7effbae3aed6 00550406c0db882c6aee6cf3b6baf377375208c3e90cc44a067cee43efcf 835f950c422ecfcecb283de3cf5cadb21a7c67d88afb0a00a6e93df1913162be68a292123e78614faf0d98350db3ae2f00d0c14b47a9b929e95fe2ea076619348ea63ee58fad30810aeac2ce9d499ba5a55edf064bab88fb8fcf95fe4c556510 +3d36221f87157ca4db84884b8666660c4e2b6af330480c516cded9f3bfe132543626a39bb6aed1964eb5c33ea0b95b9841665417679fceb95d199d55accfce35dd3f2283c1a7ced57d0c4b9ebe3da6e1ff2f979b6440db27caf9f6a4bbfa47e20d29ae304f4d0551fce9cc4097eb2fbedb9b24680bb17d207bdccdbe799d5b0d 00257dc63752920b6854d6c2d1cca68589a38418c3d036e73760a12214ab 80e14ca7798ab2ae97e04b4b16de3241b0d0141ae44e4cbbb1e43ab2fed31b7b1cc5db3a68b846a12ce6bae69ce1be39178a03fb093d2eff2e0eb2756f937ad805fcde3a076af10d4d0174656d1591339541b7d3b234bcf7003547c112a96529 +033d82a42d0eddf58fbe3e91ddff7190e3f9fc2b1e2eede977d2c0473b358b5fce1f981ca6f88fd61ce2f79e453e3a2b77d1baab2b970ed28d5dcff58873a620e195085e61c4b8480d829525a1a944e8a4b63352f0291f0311f1f98ceb262804beec1c74947618f8e3b067866255878c2502966cefcdda4f5fa2b13d92ce7840 0029025352297a7be850f8852411c09259b83219135e0e8949c1bd5b94c1 969f8a2dab6ff2a3aec8d8e8278dc087614bffa37e449ff93a5f5c345d311ef87cf5cdb4eff4f06194fbf159bc9ce4640ee0fe1c270451b13b99ad05886518ae14167efefada8df8642586dcc1f129c58bf99c89a82118fd679050e2497ed721 +671a7c81b64b2919722d7b258bdbd90165bb757b53106e0af03d0eef27452942f40cf52bc95cc7f6567df2613cce795f8bcfc723b2735efc35375c001d37c58480d89343697146b524835df3dbd333f7c06c98e36d3c4592ecd1f34ab57c341bb0f4c785f5b8372775f74b4bce60763fad1788e77ea158d735a64861320b36c6 002dc82d0e69e498528925c0e62a13fda9af8cefd047c10c3ffc2e41da3e a1ece54f8fcc97660f90e1114094a78f1a14a71a7c724b0d6da05cd91ec664bcf0defd06963dc2f8d5f03c01ef356eea1658525cc37dacb019519538d64e522235ff3ed58b884864af89425904f6b968b406b977a7d29b5326dac9e6c1a307ef +0ef677f4799298f4aab73b7393598041f56e902ced1726af49657b6601a06186212e3ee8cd4bd33b760dfa2ea3c38884f94358d51dd479f2ccc8b0b352fa4e44fcfdcfbb24919d04e6ee1108527b8e8d60e8d1b467c30c18c5455e5835d483161d3fc26b4a67d6df9e3ddd9331247cb18450188752a1ca219f3396a872cb13d8 0041535fff5d279bcd744b04e643458ce20b81df8a9e01b1181d52bb14e4 a1a9f62e45ac1da1af136b9f374d62f0706ad76e14afa7d26f751e006a8aa0439861cf506a5e8c767280a185a97b14e80fc75d1e999073bea04ed9b564dd788dd82baf2a8a913b92fa9986501df9ea3592721a99edc9060a6a314225c92ea843 +9290df0cc50c3cab6655f3a6de1f4cf613d9bc06ea7c99f38038369ff2fadefa57a3c7ae7940c1b98bb1d03503cc271f7a891bf38eec93c31dcec7892dfd2e1ab337bedde3e5325ed8d9cb7fa3096f6fafc3beb3a66cba66ba826d1032debfb4908cc9dded8c0099c85072daac4373fbc428fcaa9a6da02181ebc33f0cf926fb 0000ecfe580a624df66c25e87e7689fc3b471d205970ff9ab51a64aa12ed 92adbff7530f61ce1c725c95bd74cedb89c0a111d2c1e493777dd5122a88c7b496f9b86501d23fb5a1372511312bd85f001006c55482f0bb39ce4935f7bea108ef2f558b5d122e4a95389ee66c3d6d99c9583bbfbf418798e7e89f5586d52a73 +855c7be75fda372f062709827f333630acf28954a62a5193ff675f0dfeb63f32bca418f7cbdb346bf388d62315b19a592267ca407120db93d4e3d7125b867c4c4670b7a57a76f61734cead2caf2425eb9ff0a63293e8cd6defc9648257b401463f4533a2425e0024f1ea93365eeee3c6da20d25928602ec8b426f9b39f97f3fe 0013c72c73358ffa168423149ecdd897f0a5f75a641de008649f00134944 8c5cad063894cc225e5ac722a10f4d395be2347710f6f9c8b4a9422b1cfee645e1e176996df2c951b0c452bb215026a3080500fce8b22ebbd109d40a15b4f274eeaf071154364506d3e133c28f73fe703ecc51443d586ca7500146eb655acb86 +9c896f800281812ed57d31623d563377a5c725cec84313472b90e73f77d400f5d4fb236255741b73d46f7e5254d04099bec274db8a9af5fc7cc220d42cc172cbd3c3595c49ff74bfaab7b5e46c90855b611f74753ccdbbabf92e011d52e9ba753b83ed2a251a632e1bd5c6d346e38e743950c8ce0f394a837028575fa44bcc26 000ac60e2e70b7c4cda64071c7738f68773c94df9456a8ec3bbb468fa7f8 8ca9257c2f81e469fb6d2af3704038aea229c2958b7864a8eae0dd6b61f15665f476d81473e6e91d21b58bc8d9bf183e17561ffb705b568c6a4ba48d3621c1be6a9953c39011ddfda92b60f6abf410cbd7cb00d1dd9d850685af236e325dbc04 +139a14ead998d1a962fa47c47ef2953aa136bd912fe940709b8c560bc2a0c4bf8f3aab30a8e21b7d5f487d30b0097e3da723f11b5cb4e8c5724f5a2fe0d68ee4bacbb85e5eacf18094d2a8ec4506cf8497836a4a905059a998ea750adc54c27c69cbd0b0c1f9743a62f3d988f3fa0a9865a73fc071f526623085a2ef12838888 0060bf720052e8b9508a801340c213cf53bbecf4975faee63d4b44fc647a a50ec1f82bf0811da069ca381bc4d62a7e6ecf54f8ee970732f25d8f642069f855089441bbc924b5acc4105a64f303420e0a690830534da5a18ecfff188011595d170268a143ee004e7c62926df1957657865038fe4e3cd73953317e1775c798 +cf4a8e754b23d0fffc1c5c80b0cb11deeaba3064b315bc2cee96db5b9881baf90d30af4b69066f757b3020706def77a5fc1632d96bafba22a9c8cd3b52d535d941b3c7cc02b7fe6b51639d5e2084478ab3a29d2f5e0e16639fc2833a47b58e2c3fb5b2ea1830fe2ff68e571a8f281617a23d9a28db1c64ddfb1083d055030e5a 007cf3c216592febd8630a478b5b3e3a605084020322adb13ac0a626bc7b b059e1f927f404ce5c225faaf7141f45a16424a576defcb9bcef4b980e65ec00e49713868ba148ba2512fdf0d37cfd6b09523e262ae5e99e5bc12d09146000f0355155d42a84dc4c79781e84f56f2d4cc298162af110126d628eed278418cf5f +ae64030d4af9b36c8d3a6af0aff34e5ab201df04274691fb420b7d5c40c401ed7f3ade96065d34f2490d17943e27156e7bed83cd7222d0d5a73d167855fbe7ff6c3ed87f20986ad8bbbd80fed5f9705c6c783b423f641d40ff1f367f9648af5a79ea3cea0236997558bd9dcb011ea4dc64d61ea1e1f85b4f696ed586bc7705be 0061eda5999e5a9ed4485d2a0ac5510549b76ca37df858ea5d95aeed571b 91d39508f72de5f69a25499fa0b6093c73ddb5f5a54e886e0c4b77161a27084b0804ceaf18c0c9b90c810b8907036e3e0c077b6bf711278c16d76ccb1d37e4746ec5767254f70010963f0399b7caa76a933cbc9de98a9e4071fd2d0aa671b8eb +94a9d9cd9efa3e4ccf2a37f904dd9cab5624ec9393cf8816ea591c5e70cccd2f105388ae133708fb974998ae61d218c71785f9eb808d1c28d953cc7eed00dd9854b6b4568c5ed5ee3df3b58a1e04c64f1c87fee4365ec9aa41b08a6bae234dc43a0bf2f61420acdb891a40f17f246972afee75a4c0b249dee0fc8f9b9c8a243d 007e7e73171e4d2f2989dc024757c186485435b82544a448f5cfca05f281 86c452aaf030777fa1261a50e3234f53f5099b6983de2b51dca1dc8c3e7390dee02901f373ec570cffb8e8c75889655603c0ae54c9d2e6963b247a5ed9cfb365b7c13d931b0c4bc7c107123ab4da01b5519db30997b6ece9dc383797c59fdc22 +4db998df7b90678b8aa4ec6233c9b4629800ad1f3e2cf8f7afcac62fc6982dcb290e44587015eca8dfe77dbb4a80f9bffe75b11e961e70deed14555db6dae47d49e73004f000eb8677c18f7e8234bf0a5a104266167a05ef07152e7acc2f0368b37efe69c0c2feb51eedf7338cf9ed398f066cf1f66bacd89ab9376d41da35a2 005f7270764a0444c7159d2db867930fdb0fb9fa6b8fc80ca02e11753095 826dab85aa526a4675058b54114fc0fc5c614d8ef34b6fb9ab991748df6766b0c9bd9a1e55f558dffdbdf1261806a4010cb2484b40eb6eba8b3f9e963b184705f4dc98739e2c97f5f5d6fdd75c53e293092e499a915c64e98663e1bdf686e813 +dbf9b8a4ae316bd2df0c80db1cb5d7038364a2634925ff957d7c03511b57d486274b2ecf191746827c325a14dc94daacd66ad86d369e3f598f176c4f0eadec7e9edd13e34043efbe0a801b75b8186b4a6d89ceae4fb250ab570d65b6dd7c04382738fe3f6f6c867a7d84b35b20720cb0036a5d81a87126f236833831d9ff00b1 00179b924afa4acf30ecbe2b3c12de533a1f9675687876a7e5e5ddc8e03b 89c5d3230ac26a3d2e23c82d8616abb68f849e07bb66b31bd4435e0b26397aa650c3ab4d4d7244318aa6f7def0a56a1f01d11c26afbbe690184714f2c524b0a4f7e715ad61134ac8f4aa4246268da59bc79ca86396dfe144652f7d22acb9e20c +986d9e5d636526f4deb7545c037fe81b09c74496ddb8e42e61650c74b6fe348593f0cf8f8eca5e839baf62f17bf6ad96ec0c71dc44fdf11259dbfe7499157e402f6bd5076972354150723afb632799a990c44cd0a4fa9609ec4db133e3b4700be3ea4a338e8ba1873d345e80163ed60d0de274d7617a8382980bc2138b0a2a01 002c9eb4d392d7f2eef606e1861183acb1fc753d666225f0f154d9eda147 b0e50393603a2a50e074ee58674dec03f33db79cddb002a9452a84c121baa7f8a5c22a2db606a6b0f932a704fb76f1151171acac25ab150c26afe8c8222c29aae65dbd11e07b047fc8e77c1c902348e8338400ce7d40d3d4d2ed512bee91aa10 +68d0be2883598bfb1433886aff118349157708690380c42b8919859d96db069c7fde6e117a3669f2cff94a0f1b66b27b09e3f1b24d26299e11552a084be428446f3174da2e0414655bdceb38e58fcb065b6661190862db39c6545dead34a03584632e988d0459659dc7c7c78d4d00fc2aa10465cf24b2410f14e2a62173c9962 0024661c89b77b2c743cc175a6130904461138ddc4ef771ffb9fc2c8679a a01f8600153c0655e5d2246b8e54f68d4d2805e5e0d3a854699e58c15f6acaaac505358e03927b107f50a9eab767c510151782881031c5701ace01dd2564d3bb400db6d26421fb81f7030beab97e4cd99be51ca21be4b3929c234f6dea6f441e +f0ba0407485fecd7337f4b22236533a926cc744a5f06dd08276750196f1bf7ea7984278f789f92dd07e36895a8bfe297ea43d4a1177c0368900e3b969d3083cbe626f0e27e7ab38e185c923dff46d9ba187b2acb9cf4b23ec8eedbb8044b96b5263d956e50cd6240c66d5d96517130c743752404ed09473f05d0004dc5971ff5 00065e20e5ce534576d7c17616cd4ede3bf4f500894850723bcc9f895f4b aa37d5157e07861da9657bd64ca7a45c02e98523a405c37f6dc892a8cb445064d6557964aeb35a5f482e2d222edf7ad7044b8c95a24f7de6e9be4edfc0547b1580f0ff91f998c6e95295766515803924ed5c5a24c292980feb5f2b2793d3c404 +3827276694e413c886129c452c9a66e7d09dee84f5f09bf34e4baa308b4627e096c7d45cf6ef45ba1d9a4019a60399feec10fa80e333e2aff1251c85ca48574d9b9e1affb9666828dff5afcef3edaf5e8cae823505a0c73afe76c1bf130399fb06b092ba34ab0ae15ac6c682f9ee8479b065ce75b57213b8aae0f55e4e386de5 0014c85f66fbbd653f1e4e590cffe62c343ba6062df4b271fbd02e5d42f7 b10ae9c9477dfbde8e9979a68ebb97592767ebc65b3b2a4cf4fd4adba76dcaa01fcc017b258cb4e32d94ad4e290aaad011788745791b3c3a06e598eb864ab901696603e86c05bc26f53716dbf7011a38b3461abc6568afc488af7fcda7711ccd +d1afb8965b48d66b9acb1ece674d9548f83395275f2d8135554cfcc7ceb96450d850dd874529433883709483d0743798db5e0dee955a4f30ba328c7934b8dd9207f3c336cf89141a175ebe23d2faed629eb4236a8aea8300604c3eb7704512f240fda66acedf1494a85058dc6a31bf9531958c332b93cfe5545046876c6b99e0 0030ac7a78593b570b29f6d3d267abb6ba7e5870ee1c8ee4f1ab2f141051 89dd6eda456420317a1bf29cd58a63f4641d9bc0ec4234c0df2e1708bb1b1ffa597fc417f812a80f8db45e84fc1f82300194176413639e552ebd21ebad186551aec060580ad1057ad919b07b9aece7612e5bef3a55e0fdb91866f140945f001d +4f95b71669fdfe5dc46d4b951b085e099de349fc740535175337127910acf24e9a0e4b2f23196ad23880da47b740d77d74fe9bcfdcc44dd7d8d1a181ac290de5cf4da22d5034cda3d8020bcc776dde8cef1786c9ce4d2c2cfb035da61406af745efb7ef1a55f2eccc5000319cf1d6380963025dcea641cfd15a3106751fec286 006d7516aa040f7d559cae248e485834e8d9bb608279ed4d4f7e1dbcd2b3 aa1251884c18249df921826c648c1dad0d59e89456b9402293f043f44dc777715f1bb270d3edbd04f17cb8ef1959e49817e9391fab971cc9597cd446237507ad8be3023e5e19846226d10a30b0e722bdbd7cb52580994c3fec2ba245632fb18b +2ad9e17780c824c4f2d1e1cbf19ab85638f2f71cb4fa3518f08085b8b358f54d4f08394a5ac29cbb3cab828c5f07f41eec51e6cd61a5f2cf44dbfa46834370cebdeb328fd3bf681e61011b5c2ebc8945ac7a2a8467606051008b15c89390e111999255bfe28634ce9bc2850a2b55a4af1c4c2f94403c78aba1ebc87386ab7b32 00137050d7b455f43a8dc2516cfff5a91062c1a2727b27df41488f3dcf18 ae22d31fff71784d351c6d6e437ea7d9e06b7b2c69e762f6f19d89b1ab57b07db57bb16bbfd1ff8e88fcec63845b6c0c190417ce36aae7aaeeecb7b5ae875e3e91d7c7614c6a0f1664e7a5db536b4809c3b5ebe7c3183b05222037ccddac9dc8 +958773c37d3eba003aa5c489f72118b3022c52b93399e9d8001695664918b86893f4922c7b6e55b1855ed0fd1d8de5dc61af403ad660fec60d7c44bd0102c069957ed804d0d416facdc1a95355ef58554606579ef89b1842f1055cfa2ae118abbc485356824cc09dddb77d0671cb3011b33bc86cac526e3f6bb3293c7bdca1ff 0001fd447b33a2ee3595b9f885c290d241422afdd74c3dc4981955a7e9ad a43581a0f0ade647034d7ecbaef1f7912802fac683f02e10bb60ea7c9440214b3d16b256ff81b7b02a0e06845b72efc5088926d932b5d2690a5d5f282d1b4143ca4f0e138d4695b65b527be02c64b38bb7e3651950026a681e781c13bb729021 +9cb2c496b1bc7f040228571e005e7e936e48e8f469e295edf914f5648701249a20bff6b98b5e862603dd9f12bb71c160aafe9df02e2e383e9b8a9a9d700f4425ce408feabbf754be543f52204c849fed6c9d3e36e03dfbd9e35c18d7bb2295f1c484a66e73440a0a5aece5fe80b9ade9321ef18cde3eb2db15e4b18e788b0441 006a061e10b4a6e7001d95411cb31bdea9c84670a59ed61b14fbbb05c8e7 ad233901fa7fa2f921e706dc2363498fd9bada1c0bf02f5ec49d1ac4a2711ba41199ec743dab07abe74221dadceef891136a1a491da16214c2ccf0fe38e937ee74a2e142315ce3f4bea1defd6bdc9297ce06e10531e43be7051539638333db1b +9a4bc0a029e97742ed3bca207d5912cb568e4403cda106b00247520ea02008b14c041b8c9b976294252da835f4ff27456039d79d90315abcb0b9b6958a22352672e229665457ec79571ca80447c8ff2a86e6af3dabe7427c8bdcae65e3c6746a56079ce2cf8d22235180f46646a21cd9e86032cfad874cb9c67f882fb037a13f 0027ec31ca31acb4d2fbacb49fc085f1261b0042cc755cc97f9b199e7a37 b8e08e8766eeaa74a2514bbcc17b242e436b789d3f228a4cb8a9f6b9d7891446c3d313d3d6d4b784ec7826104b7f956611059ad223e44ba69e24e4df8d4b4e3f9d8498e0ec4dff114d4b546a33ecb38cbf24ac48a19e83c0906be36da0f91c34 +8d89e22cf802dc68ff22d43c436c79311e705ff6fd845e77c880f399f403e6d5e9e2b35511553c978171189e288cb2200fd95f84ec5ee9865c0eb9190aff6dacf783ef200e82027fa992741876456472bdf27f2bd8ee55db15408c957a120eb64cd24d299818726a73fbb0697eba726a326719765735b37a2dcff0c853c906bd 004c6f4d88e5a4f4f83196f2dda9dcf2a66eaf94d50c851f59bfcea1d876 806a2bc11b0a26fec2f425e957493b0bcbda89dde95b894286c1310d47f82d97626aa64d5d0a01a7c962156d2a917dcf16b52babc50c63e49a8094d17a6be4b392d50a507ff5aa8727bdea39a0fde049329bd8ba5d4ee1415edad9585cc4c99e +aa1bf5a79e5339fb9ef6c2817bd95725551d064bc5064d6586c5a879901adf808dc2ef7c78ec3b434b84569988db58b5e8e9782b1cbc2cc7c9b68e66f32d4ac4ebe7e75b345f654c7b8a5e650acc9f170f75b7aaa3957cce248cc69cf93faf8d72abc6fc1cfa9ae2d18a7b31ce720147e88e84f6563b2197882fe302449ac5ce 001aa169ea84365c22981bb766bfdad27e373440850569957544b0f9332a 8c66ab469e348ab6661ed0b3b9491cc54e03c458c1bdc799c9c25429dd7333e6b3c4822cbb366f16e932b4ded23cbf7b055449079a0bb0a0e1895795589a6c695123d86352a6fd51fd5354efa71928d50d99c34c870c61f14f6c5cce1d566e51 +475664d5e22cbe0da0d0289ca9a666a37270dc71c81cffac91f6229fa39315c1d55f7e0a89b6a7a07df7d391dbdf8fb7af63d2da46ecc3b60110dbcd842da97f98d2b67f562b0364ef8e1c589519024177c8ea079794f271f6d35554c0e9d0a39062383c95721b72f4e74eaafb6fbfbda02cb670a7c4c94f67b8ebc6442e84e3 004a665b92c0c33a3f8b9eb4b0ec061d40b603de36c87096455102ffe57b b5ea8652a2a3afa45acadec38c5aacdc2ae70dbfabe8e78be055b665787a1cfe341374cbd4fc979310390d6150891bb00e201f56fbd0ad42d2e33d0117215a9757e8bef4bd5f1513fabb7fe8239f573d2107256ef3e0617534ed9f5e1aacdd86 +9e5397d94465390a82a3c07e3ebf21b515776d18b4463aa5810e6b2f96ca61e92d13e034fa853c3fa45411f51f79df6f799a2c6906e6a5b7896a4576a4464f9e0be2b529a43e1f503fb640d79db6b68f3a3a7deac1b5832fbe86673784ff6db1f8438f7dd332cdd1e7ad9df8b6731aad1b6a72bde52e6bc62d80b8da57822c48 000531540d94823e19ab2b95cbc6e7492e1effcbabce875de6ba96f53aa9 895bddf887ac7c6f091ed40c9a9a4c8f45fbefbfda05e077eb0713a9b71a6eac525e8692fbd59950a7239d3d82a34ae300b7dd75aad7eb1e0054882abe88f88b65a7743d99f38055e97599d8dca190bd6365106de6e1e468fe710493f4f88d55 +3cc4c4192f317e52df6f8cefba6d4cd823c942aaee11b9a0ef5de5c2d181073b7085a55805e9554def8dc13eb978e7396044d4f4a14be2c7605998c062095c929b9c23b2b1b2fa73dd19a0c0af44ca4789f9841fa62dee8a5f91b3cc4b3264f5f67334c3f0772b30bd7431c3fbbf1f34318ce1889b6e8a76ce6d42079a451e56 0022a89addd8b85809e87e0aa2c038593ec277054842854de1197833a51c 9906f606cbb99930e949dadbac5fbf22fcde36c07c12a8fce621764b49887a7a03f07306a77e52374429802ba396fc910d3764e7ff4a1343cb9107f3c6b2ef0f17621d57a40394b325a8141e84870c61c6221133b9a92f52b77a7315d65535d7 +72cdef5bdf710978e0aa334b86b8ff4a58630da314eabe98b4d611aab56f55c526983d54d19bbbf9ddba30a84b18aa0bae9f9503e9b222f842f084db83aa39625403213ca321cc0d9c8a136c826e6ea4ec108b913dd0a9ce9d5b8c7e3af53c3876e56a2037ebd6d99f037a097111c837647bedfe4c494e4288ed6427c15969e3 001df252a11ff97b4421b3a2361db94e908e8243cd50d9179f9e03e331f1 8f4f660f9268e702bad54d889d17b4a8a7daba26a16e26e982113a46bb7568f6c39b7a47d846d773c09c880b074f07a308626657a8dbd2421ee86b418b594574d49ac1d733eee90d923ad9e968311d70398250fcc1f53e7a6ebedab11f18c202 +8e4eb88c0b2d525b2c58b8e00f32def90e6dd382301de49e0ac053dbc6b61afe926d85193e2c4948f7402a3d7c614cb2c58e060362b0516a1ba4a7425f1b3d09aa20d4c3c8993a387a3248aeec51e6efa8f558dbdcfcaa13ee08413227c8351e3107e9a3e3ac124224aaea91bfe50c11c1c8ae582e718f50bc5d5c06076517d6 001d7125c299ebd0dbcc050f07de931c7ad0450af590d0a2d0228a66ac5d 954e43dbe288c02a36f14c10a97aac415c4498f571e93532cd49779d93482080512c1b32021f0c842c53cf5a4a2255ca07941591e44749259f5826ead64441f21044c025dc017b559a23dfeb84469954fb6507f787d2e303bbdbf0bf6b1a625d +370fdd80f330311dbb3959666001bba61cdacf20f72f78953d946fa6cba02d24b5003f5452d535609e489b9434f192011f99f918defe877d51349870e7e75502f61145f7c261dbd2a0840926d824ebe9be3c5a77a3a84340aea930378367ed3615a47e3f792c7773f83f91ebea718a05fc62e9ed1d78629b2c27ae44fe8f8d4e 0021238e66119844b146d40e48341f522f6ac2f9c8a0b33aaf95a3099a41 b1252a8e2d63ad74708ddffd31975e628661e0164081ff48a4d4663729e30b1baafa77f3df594fb0d40c0c9d7cf9012d081294d77592e2fa29d631cf09d093ea77345c9b45b7a987644de5eaa54f630f3e2d66caea0acd866832e319d843e4e3 +f86c4433787c3ec3cb1663389ccf53d62f9425274ccef05fd14b1b8fef676208867764eb98d16d006ee6ebdc27b8d9a8ddd303d941fdd82b630694cdc698bbe6bd524411907834286c94b24ee199fe6d646064277f244b7df3ea2d9d52a9dc6a33d7c8d6dbc919da0fa987a67621ef0829e48310e0ea2bb86fedcf4effc0b94b 0015e1bdfdacd87c42ed439f3e243abf27fd42e54f3ebdfb47f60dbae5fe a3a3dbe7034aea1e4daaf62bf944436981c932d38a70c004a1a8ace2ad1ab5e5ee9b954c2ebdcf51448ea4dd67a935a80c668dd556b5318cbc914111ffcc356f008d31ace45c798c6a80d95725faad4206b06d8dc830c25a2a93e81a65e19f3d +4117d593aa92e3eae1124ec7482737cd3573fe5f0f2a5051a7ce86946a2abb9e47a0c6ea75b262689b0b486476d2ab09a20efc2fb921419b1811b51a2e15891ae9e45a17ab4b96c665c6c423fc00e2d66df5804a164f0f3c958df6f25d7da6829b1fe162a0a8cf130858c83f3555d6ad627db70cb41303cc6380f7b3fed2563e 000e09410548c17bbbf28a68c3963a52d39743a4f1ac28e6dfe7a6ede281 843f173c1d5101b96719f1b5d8a66d3bdaa17961ee09b90313e564288918407f77adb5aa09febee9a604523ba105e9c205571233fd97e70abefa9ea6b7222b6e09d854c26f1d5eb609b26cc58255429a82bef0eb0050cba5f10f68d6fa63172e +882ecaff3ec8f4023df5397167f238869f78a5c499be19aea85c7486e73f66f0e08e71cf85f3f1b6f6a70796bf46a18e6b555a0a87c2088640ca73051b3dd59ebfef922be0372208fce602d8001681297b285701dbbe24ccb42541b5db4aac1a1c7f407e11c83db15b38cdbc25e930fdc6558f64d9503e214571a435d890169b 0049f5bea6e72d98579b78cb07d89f64503f8759dd7a73cd73713c120428 8e5df12ed21562460b5b1d5971488f4a4b00eddbfa4168940d5450aeae8d02abbbe70b53e1e475158350c4d102ed02940cc6b3090f8e00342a28d1ad4340ce26fda50441b07d22bba94d8d9d43f715061565a508deed6ad9cf11261904c23c7a +99b3b8f876f8359bd6369ce84f9261581c52d744b90261a1427ab9e447e6d833b6b3e89af8dc770f1dd55692d01c8bbc4277a729fddfa7cbdb2ec99133201dde44ac691a77904ca816feb0a1aaacbb9fba85048bc63d73506eb908ecd697caf582747051a3a38ac8930c9a4365f407ed94ca7f2d26913c53f4c010c7ed9d7ca4 0005eaa818690d1ca4838f0bc667be5721d178c3869884260fb230277c3b 85c2e036376d3e9bbd736001c6fc26a7b388e268885a1bd88e6ea62bbe4e8f9424663ce898d004639650b8ee03714bcb0b09aca57f64afa56df9801d8d2dc66f9db1b6123368ec4928d5ad5b13cde7f97f7fd7b169bd6cb1084049a1fe419605 +8c1a83023930a85c5b2f9930521b8b8963d5523a3323d87f862a17d3505ccee01246ee1029b8b8c2b608772c4096d1e914cb398f027d91184a8e94e4feeae121eabb504a2a35c8bc9294edd15ddd979946c14c792ad787dc2d4deffa284830fc90b3f8c0ced6a99fc6de7c41b9ed261402a6b3d702ff86a9392731ecc37430c0 00603d89cd2f741d734587e77554fe6bbb1e5739d5ff73084d4de8ed69c4 ad3a5f9f476cc929848727a0df5eb7c19ad4d59705835ddca11288583e55660b096e2a88f7cd2cc79c45e467760ecbfb10dbaabdb441b08222002f993e9e564cc7e3c5efe6fea6bce5da6a6f1544c98693fd1dcfd285332213a62863a9921722 +f3c9dedd7115339dd3ede7d8d06a44de66bf80b4888ab7bc386cd40a92789042440a13d2cc90dbcacca5feeec1e0e3c51724146e2c4904ed6b05c7b4e9b49d7f458ada695c5d2fc36f1193329b87c1268aa38eda9151430aa0bc004e5d2a61b9390accfc699f2efabfec785eb34f52b1beff1e4c5492e922acc348667d2a3986 007977b3aba53616dac27b4d74930da23966a88ad98f1769674789c0be3d 839cefc0cb33f414f7ca4001dd138d5961f827aca006ffe456bcc98bdde905649e737222ee2dd0560dbce0b48514e47d0d17963e0207b78d293dd3e8015bb81ba0d6277f49180e0807340b0e566737b47f491ecb6b9335346dc6d135c3cd0447 +d878c4ee0bd6c84652d7f9e68df7b90cc78776d8d1b60f3e4d7465032bf401f1527ca7bfd4a3dd916e13e93fadaa5e5f20c9f47d12f8fc922a9a3aaeeeef294c221ca1adf7df85b888faec8002f17ff202da1be837827619904121167bee2d2cd694a263d9a99062cada3399dcbfcb283597a96ebec129c65e0850ec4cb4e2d7 0050cd20e7eabd29008cc977d0a17e1195d79587b8f15ac2447e15daafc0 87e530d082a103691e8bba424e88a464de4fb119a6e979d6ce767ece4c952d8f56177e4589742674c0611ff80472164a03a9fba243b8e20280d765fa2c3ec19b90c3b8c468361b7b43dd79aa32c17f13ac33b84c338390e2b170df97e61cee75 +ac3c118cc9cbc8eb3b74d8ccc9ecbd81d1996fb25ca43c8a43bffeb244f722b93c9e969241d45d5b81fda0b399f1e3623687190e428dae077e54cad1eff75ec2f7fbb9434bf716833421bc2634885677579c237340f76787b2eb19b446d56c0f2206099b81493349f4db0ecad0e2dbe85dbff7d7070abb3d3b12ef0cec828af4 002dbb24fcaf9f3cd5d50d209937f0e2d134fa20ee3c9c2f1fff3dfbf302 9541a1f1517b3b145c45be9c9ac48190480b892eee1781a7893a8cb4a9a1e6104b693c6237179c6de6b613ef23e71b2316b4e2d1d3f992b675a9c3d7fdf6ad8d031ea3b0cb281a3dc01af5008e08629799d9a8193f4492de514cf115f48c8cd9 +700313698cdfdcf0044ca07bf9e5f0702ece7cc66e35decb28d5f8cb7e7e5367a95cc1728a90cc9a53a2b5fcd4702028b742538e9b386f5d8b4a2411579ed9553021a95bd00a73f03c4184a6145aaa367e3af76659d677fe7a2e98f9ddf4aa20eb8d1a1db72c3f5590598801be7ebf44255fd7376d89d998b7068bd1296fdc38 00047142197d3d43fa46545b547968680ec81688589d1ec8d7c7e90eb969 82781887069711573f834338c70a1c8fb378a7b2eb241a793436d602f848f54eea87ec06451cceea5f8b79456ae1345f02afb02986738bdf313afd0a1b5c65f0b8e4c7b85cb351545b7afb4eb9992b11f63ecc1b5573a26567088bd10a9a4066 +0374673e1a685bdee55504ce3cd333f70084dd4ae685464a16924eccea34531663fda60229166478b30193459a3113253cd6494dc26154156252dc6e822552c7c04d790eb9f8fcef2ea8dd79e72f881f7f20fff93cd73ad303c0918ec27c6486c4da61f82bcd55422d16650cc68bfd4b0132c1e7075bbf17dad919095860d445 0031352b49ecde5434aac05f898e6ce4337304845d748f114c14319fe97f 90eee94ed7454f009b1859ab3f2e71037fdb1709150134d595e9266065758460910dbcbf1d255dd1df24511268f800980291d194c4b068690d8134d8b1f1a06973199869bd74fbb9b3720cadefb720dacd01c4ded0f9fa56afac6246f3398364 +8b237085f135d6e94592f8d855ca397c8c1028236a3b412adefdac888245874f586d06950ee18118f751bfe26f4c31465ec34b578caa44cf1b7109ac4f6eab7f97ff9699b34271df035d3bf58a2ed4bcbf7577cf8e5792b1945ebb9389b680baeb8518c8fdc5540e192aa4fde0eed0d7c82be2e362b286f582d65752c8db7038 00176f124c24e4420f6e726a6ca25f09dfa0c5a37e5bf879e7bdd36c3b65 829f7b26fd8b53c298f29907e9dbf27efd261a4d85de1da3d1b42d67ffa40cb8ca9afd5cfdf47bc9b18302be48db1ac705469fe6f7132e7adb86f8d323e269e7e09d77fedb853118c473cf6124786e9eaa20c1bd039337ba68654a75e1cda113 +e3a086ec15574f7017b3cd5f5a47ab7a73980f11074333490dfe9f8ad8926f9ea7c82271aaa74e77133b1025b0b22a6900fbb71251bb6549341a23d194e79d03462cdad52ee0d1b6f5d0d14e1136026961fa3467ccf0864bf7ae3fcc3b68cb35df7324bd9bbe58fc8aa9f63c19feedf19d935b71bf5981c74fb2a487f84e453c 00755c48c3dbaf71042c58cb137f3632e3cf9d90b7b9a58fd378feef3d19 a22fb388e5f75b4cafe631fffb5b10deadd12bc93fb8254b27f9e49acf2f930364c3952144ee6132e3f6c9b7b16d7628078f1a589bda2e78ecbc5fe8efe43356615556bfe654108d99fe935b99aa2b7dcebf725740b13bedaf8066f848a7ee56 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K283 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K283 new file mode 100644 index 000000000000..447c65df46cd --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K283 @@ -0,0 +1,60 @@ +ef90f85fbda05e693006e4c64e1dac56223becaf0890f73b5274e6e289a5a1de2c141b825c24d595b3fd18ca855b5c1aa60dac6b5356275b11be670692cdbe5f282f93ac7b2e410a96cb9e9f80defcde98f3449f99e192bfd62040421a0ab8f99acb85369f25e5efbf81439efa8a5e1d9cf781355a0f47b037b09fe4086389a0 01e846c830a8ec04e8572d1a9d2df044ab47352fb346f67403a3bf87243871b164511c53 b5904943de99efea54da40e1f254ecfddfa29444b46e3aaa750d40ec573ca7da8ca295b7a4a0d67266a2fa6c2a52abc50ffab0a1d2230f43d9668722b3bc92452bb8467fc39fb2aef53df6b098642fa68c03a5730d512c19d7a92e63f3c57429 +a3ebc17c867cc9c7c28797f6364f6574b80c7ec5b2d8e1542a6f5db8568c15032f92cfbceefa3fe4ee654f690b0455ee5d38dd84bb8665ffc1ff8c849bdbc4aa0ddfdbbca4eb37972fcbcee8cecc1aae21ec736ef61781716b60247b7551ec4e552d0b59a53cec5964c67cf7988787cedf769eabcc9cd5243f58034d96f0e43d 0101c5ed48231a56ca0ea85eb45de0e395e6df2efd4987a226ae36489dd8b2dfbf7c465c 94c877115be475b3a8dfe383b81ed1836bba150d7c4250b47500749761591991ab5ac112343b3243f0a7b49e211ea7ec14f8e63e1d3c6fed4f819ee36fc45fe80ddd3f0fa1ae88200ffc35c534bb0f2202778b82032487524914c0f4cecc9300 +60269efa4d0ffafbbc655f6f00578eadce7fc0a7eb7db923dca49b6f2bf3e13f7f829cc6133e022c3c92143c075ab9ced0531a91e6e79848194ab98bb852f40c84e7aebe71fb8bc0fd1f97ed5bb6bad6783d8dc048df42738e841d978456e055e1b8a781dfecfce2218701c7af77e7894ccac5bfff360aab0b6136b978bc39c4 0019679dc589440b11f82b3716e5b2a2bd42c3b1c83e88a28e304cf5148877faf760b4de 88bcb1dbf536277b465ee053f13ec37fd47f7b92da2633b15ac14180c13e8f32acff5072a32a95539296e9704b6ffc051648e59a5f9f5a488da8e3a95f2b59af27eb0820c6a8d1afe5855e5ec34a819152adca60f50df41fdad5963d114e53a5 +59d704d5b1f3a0605f1497f22f71b8f45b26138bc86371f00a4517554e7f6e7fa5d35189fc656ce68bd2cb8510fa3e3c3df815dfdd749b2b6ac997d443f3954c7a927e138b579801ffd035cea90840733e7884ccfe43d8d3a4a26b430673274aae312abe4ac1e1d7c67b73580fedf2d8de46572493c9205ebf0e8b4d75ccc88c 01703c21fb1e09f8947e12fddf166fda6f685221fbd803d75a0ae377a54a1e494e6c5e7b 900e53ef943706bd973f8cca2456149a580c1a9ba0e3d5b705afdc7f33119df5dd5225e3d9bb438bc254bae1c6e9b7dd155ebf4767b726ff53217343ac28dfd96b3058bf60943faf17447ae37888da5fd8d548f68f1650a0d4c1de678ce585ed +12c8fdba3bc5f68e13f7ff8e7bee876fa68a970afc6924314dae0c2482763ced8d4752cec29ea288d350acd8a06c69289ae41ad345a1b88bcccaac903f2bff39015c289a8ad608606bfd65270a7bcdb5fb10c89bbc2d16dcb91fc9735d66103f6b1f3575622cf4d8209290315b033ee1f79968939410f465a2d37add46af2d59 0071de8eb14cbfb88e61b908990ce08b81e624ef4f2cd9cdf3dd7ca9097d5ffed9ae9a71 92c1c874b5260338c917be9b776112c81457b6b1934e4a80e4c39587071562541ff3b9e43e4c1a594555b4c8692e74d8135258256def0da7b9335a03b06a64e78c63261597894b3732e446ecc01f4a2f24091e6d0cab0cc01ca3f40cb2a2738f +26013a3ddf687bb2f37d9700923906f118d5cba5d8ed5113a0e3e84cff00918125108f74f4b243e351aa5d07fa7c6ece29f5700f23e50286447883d2a058c3258a12e4ed8770cabe627ebea7ef6e8c77811ed7d9a19c53287093e39226236587ddbc63b7ad5e7ad9895c64d1d03ee432d45a067afe27d4cca920ae88a7a68db1 01d156eb15762ed00c4021884adbfc2426e910b18a5bc474268196f4b74e593a8f38702b a70a55e74b987820e6fb959f21060af82f366aff6e527fad305186e3acf04fbf5ad6625d9f80c8fa98540b2baaca894103093e021128e91e1a03dac2d44b711e5351de68fef21dd70efa4e5ff2c6530fd8783f689606be2776c705bb7c8c2714 +c4dbf70b9a2165e7279122460d05ceb8e43e03fbe2ae7c314007fe2b1d8567cac727a10fba5cbead0ddb167d387da8e8f3d6bc0ad851cc32885809d07a776fd4a95a979fe3833610af89df0f454d9edfabe12495a118fe83add5eabb2acf54ba7ba7c4be20fc77478c0a0f0726c4e60317422a612a234a7567648603b63f1c12 017d6eb1219cab8577168be86b61f372b27ca70fb1f1a767947895c185344e966db17aea 80f07216d1ae602f5c1b486fff5fab8809bd28b664c6be16e8d01436c978b9d4bdb424820e7ff8d2609b4af3ef14679b1035ef702f3c4118216493d9b40d1950cfd933de0e65b4d82f4ffe41ba49a836a24a4023dce7124e2be3ed72dac30f39 +b1d53b6af1face9b59af11c726b0099111d1adb3666209ba46b1744a528ed0f72be5a1b82423153b896384faebef0362343e2a4599803c08b8513708938aa8a498145fca1c63ba41aff06d1a18aa2a045fce7fcd7e5552a2b98d0df97b6876f06a9cf52a7a40fb737996adda97c3cedf7fe421235ac6951060eba9c0377e72a2 010ede9be6615b3b2a294d67da78127ffbf3a15bdba6f4fd78be7a60415b5d1a097c0cff 9237066c742552bfaf5a0992ef77b97c0bc3308683bc0ee33ee424d234d6477bfb8899eeee03e34fa5ae71dea8db3a551042ad1edc07443eab348c685bc6a33b471527afbb029ce50f54f2111c6718c77cf37b96add29af3971fe31a64e516b2 +e78f538b1ac21602b00a09e3db243ef4803b447329c94a1476cd91a88ff790da71421b60092c8a6e55327c7982e7655eb1fd6e40fa9b9fd2f10107dfc585994dfc5bc2143d18794a39f7f69ae679b27dd11ed22040d5e93aa83f71783525a4db0c3fd7b43e57dafd0033d5317680df19c2ecaadcb37ef896c61a758a5e455206 014f237cface123b64e8578ff33f86bfd2a8181b9c81f36b9ca31e2a446f0d91dbbe2249 930b3876844e171ec80aff268a29cd5d87656958f656c09ad613b2938acc923f23df780ec4f4aee17a4b3bd0e4d84926016ec90bcba2fe0387ffa12a01bc21cb7f83861957b8da62cc60adca67dd9536c0516105506a8b887da7dc64429cdcac +8a6ca8ec436d2c706fcbec6486b5665b21c174edee7ebe108211c388b1219a8224179f7438e0bb7d6e41ac4a67337b52d4cd9a069fe6c88960ae20be29c8060efd7c62cb7a9a37136a250e68f253e7f27755df53ce7c570135641ad49b43507e5483e17b919cedffdc0d4913b1d5e0ca0629876c0a551841a0fc2090d2857cce 008dbecb26587cb2ed7df2404e680fcfa5bf8cf6a58e87a350a1600211b3c844ca86daa5 acde970fcc14bd60e6bf61faf8408bddd1c550b79c659fb1b55d1ec5fbe4bf5a7c41a295d74027ec29fd51f5d4ef0ab21620cf055f81d6c5abe61e1c584e0dca1efc0464ee686ec3a380944437f7385b578668ef58b59cd3d82748c9beb9a9c2 +95bee02b423d2c6e60252da4632f693a2d8f6597b4f9c6e356f670c3a9e4e80063e92facb6421d0325b99dc150464ed2ec1d0bac72a042b35d56d33d2fda686a75d582d4756522218b4ddd25ed45503d90d3d185cba6cf0ac211b22aa4e1318a8316c369186f7130446dafad64f7966f5414f43af37a87127534060a23c6165f 0191badec2d28cbbe62c072c6b57eb5d4644d0c0b3283951bb66096cd15edd43a1bbde53 b5d4a52dd00df9c39dcab68ca8eb7715cc34ad4ee8805a8b7732bd9eb85438d8b49c0db419e62d8bcb006d0c33a09e920eb3a7b86c96f9eb5bfa0a24d3c2d1c85433c03d67ef4aeb8599530dbc0771ff4aec3af34604b24b8db560674d2b11bc +ccd7f7c0e04d1ef9a3c5617d77480bc624beed6582bc28e9e3a369b12144fcd96b735ee41713f4173b64b28c6102d82dcfc7876e06e76fc497d1d238bf6d85bb5feca630bbd0c0f0fa7c0c72e28e9259087698973ac66244bc6e69c04deb22eaeaee7b20da239ab6333576f01349c76f594498620933b8969450ac2bae66db8b 00ff5e3d66eb57fd35ba4472effd6e7a016ca461e39000a7125e99080f6ab6ef4380dd7a b1b1634912988c1671f828fde2f03b2e56b468d519d396a4fde00b8134e737961850d45fef503c6b116cc59f82d90da902b79f3f428a4ae0eb6dbb0c07ccb4d96d7f113a34d19ded96e884f16e48c35c217fee9b6921520fbf3de9e429226a66 +65e9124a2606c8784c9489add2999f4cbe6186395df20838d653b263a207ec46995d2685b55d1874e7ef05a6a3bb5b60a7be6751ad568cef1bcea2debfc494d1e2ece0dc8028c88f1b2c6e4ee26b639c5e81f6448bd25b73ec4608a8e8cf4e0155c29b6f0a62781493b03bb7384c9808529d5f87da6564ae196a365bd282f46f 01f3591eec4a8a3fe6ae6debe230d238a6b73cf3791cb735add1abee64239bb100f15166 b96a5957e1a066be6d251599651f162f5ea3cce0ed538da19af2825d9840aedae998b3b4fa8ed55c256d3c989b1dff2607c61e78fc5801243af631895fe06db3f85ba0152170758ab0ff6548549f9727d74018316be3d8cfca2b9296fb270356 +e793c60fc725fd537d5fd38e9b4fb52e268722ae6bde5a058de8d20db301f5e8d8e1ad85532198835a04b76f27ca3c972be5617a55677cffa8219eb64fe53ced242efe1b889990979227dbaaa15ed39d3b6be8c5a3237ebe12bd96f333d947f80048463d3859e34f865d83faf03894c2243a06cc96788ed952e606c2d8948271 005af03cdb45961e7ff35fb0146904ddd6c2bfd3cce814073d3aa56eaa9f13b4f7423926 ab1945ca0b1482b5c53ebacbab4b6b78dd97fafb81dddd6714fa3b697e770785e0a46becb05a4a65a8604a8b92bf953001d60b15e78f1107774b1213f6ad386535a6d482c06ae8657169bb55870151f7374d92d788a00bdfc3e1a584b6316d8d +a57682d21cebb48190199e9f57493696eae3a59acd22f64d5ef4729decf6c2615b326817a6bc118bb7234bebfc7276dd998838c009a7348e46431574638dadc48538d6048d572e50d9c5974d2049ebe1837dd857bcd1447b1514b62808a4e7a88162ae1bb08a0f6d3db6f25874c6cd0cd4ca6333f1bd57bd192ef67e4616d182 01ec9710ada06e6270720692a06d488ae2ba863b905dd2fc323e7ce68dedacb35fc8c7d8 8055d013c9ca322a7547d309489bffb44b8b8cc95a88d11a65205f4ff8bd3524a8ecd3d8f945e91f6fcb252b6965d60f0616933d77a6d4c9fed50a8d9ded4a15d21875bfb2110722aa463ed1a445e403ab15019c37b073eeac1ffcae45a46528 +f646e7334e191c2bf0056d3bfd23f03ef7f0777b923f962519a8399d311b8f68414c689ca34b96871fae99eb7ea534fcd83e788e56eeef817cbfe33677283c736b99bf6a626f9515291e842bf99f694e4e8aa7c9911c591a87d5f112b3d96b064594e2b368e6d1bf1a1cd343d54916a66da22c26355266aa2884120fffb8b94d 00668de088c6913640fbefbe6d2c44ab26e481802dbf957044a4957c3c5d0a0fde331501 892b338ca7999f2096ae7a5818876d96b5d8b5d19fe90d7718d26226a98a15e0e3fc1f64cc4bda8f30963582080c92660e8210f8393e7ce6a7aa6d65278865dfd8dd4bebf41864975417a16189a7386159621b6d802f24723a1725f2ca0da5e4 +a2d7e69ea381d3edfde4664c56c4cb140d01cc4425df757975cedc995b89640dc016ab419b137ff25a6a6d64a309b23890439d2ba157262393cf93d15ca1b1ffd19373ef12367f8898aaf56d5544c2f019a4854f69b3d8d320e03135bb7b675e588a5c3fe4b703938fa0f964916501297cee2fd04af767155c7739419f9dbb7b 00e6af57cf47de1e6f07041eb5e1a413fb7ddd82f8c7f7ce957eb28a118004930bec4dbd b5c80ba9f152b2c7857bad92dce69f4df6f9bfa3cf46b8242c6027a04623c65e51919c96b3d8dc6cb0b85dc9c3becf610c6353cb67ca131ca26aef167917dbd5bd6e57ca4666e1f35452c33abd126bff4bce7bfce3bbe94ec7305728e25026c4 +7088f60e9375ec6a42f705f851fc76cc833c4dcbb3352adcce9f59197c1b7121e7aa661c4f8ad9f4ef280af3a2981e90c01291f7d1cf7d3ae2d96b37fe6975e11b7c6c02b8ef044d1470b1a26b9c72e8c4e7b1dd83c8acc9542e2fc7d211b87841dcceea2ab8128d0ff7bb622b60faa4a89ea7008f7d55f8f9de675bc4596fd8 019f9b63fde8c6aa6177f2a38981505d04f8ac62bcc21007b05615d028cfe851ab9cbbc6 a35424931748924181dae92de17eb81aae25ae273c854aec8ca824a88cdc551fe876baa6388651d624c473c84800bad309ca7ef6a7b88713d354f1f175283c15f4a036ea6dff2e1da480aa2c1ba134a84c5feceed4d6b81d5fca6825722c20c2 +ffd6044ab991849939e8a29184b4d0ac3e07acb63c7e6b886df9e8254073fa800d5910b9fe34fceb547565a2344eed4de394ce2251ed51ec882ee9207eb7340464c742d9d140fa0964f6bcb1efcc2d13919af4f727953de41b20728ab975c1ae0ce784865f23ed1325c68daa95ed5c932893610179be94f13b9a4149f09833b3 017704c1f436beb52f7ec97192e23e206ec09f9e8986e06bef71467c192bad6f0066b3c2 b53673a11871d243ef9ae368756b176b15fd52ac2989eb7cebbedcc810cda1cfb9403f3c06ecb656da45b9149fd8118911db0d9064401732bffbd3731d1268a4b4ef4eb49dc6b48047505cffcb0d5064d9b331fb3bb67c0d19ad7518d1b32fb0 +c9f81c9ff7d80011fd41f2de97a6c1e6a22cc2da7b2b9e4c50e1354c3e139b44529ac786ce795fc501dcbf11a935d4728a7bba44b4e86b5e5990fed4d3e24fa5ab6f303e1842918f156e00dccebed6897c852207ae5941c630014a41696882066c2b296d39cd8658cb5830eee78e29a00335a99a0ba90722ceca5a2e9a99a2c6 00c7d1ac8faa689698f5c6325a3b3f35e7730bdbddabd0693f2bfdc5c838bd62f84508d4 81e3193d641690e0194b63e2f17cb00a900874476411f1d25f23284018c5e9025511f5329f9df7217e1c3ec170231bf419457b60dca2618d2b1c5c65ccbf531fe14b96de74f8314a109ca5d188dfd8116c17c5038982d5f90c22122305ac281d +a60de761eb32490184dc1d29e21fa33889295ca587b994746874c7289eb9c83e9c7bacbb4066c761a06b65ecd78d701bd41f305cd7eb258c630f3febfbb0a367ad16737b146fd793dab23562e8001cd113135b1c981d1ca23eb3be0fe3e24fe3fe1089caf9fd8f4f0d1f90dcc7dbea4a9e2357793b65daf342b8e6d109c6dd10 01a173d158866db0ec665ee632b5fc397893f6a44ee17c348e7452800aadd8ce676e7fdc a79e86bc09a78ee91f46b06e09462071d8c6c161ad3e3524c8f866a7d830acc11e5c3c8ce3719139d7ff84ec1e51b6c505eb02d8a7d3e9f135ffda22ce203d20140021da406d73a005f58a21798e38520247de8a221a105524fc402907ac93dd +2cd0320cc73120ef13e83c8144b270c9a1f2049a9250ef7ee83ccc7584025140a51e2227a5ebb824deff55b3affcda63ecb1fd3f337c67c08054dc82fdace0c4bb9cef1bea9dd792635f655363d05903cd6b5ed50ee669bcd8157509366cd85aa40d19593265da26e5641590ccf04672a6df52badd4b99964a8643d9687b499d 005523cfacf4ed3b74ebc30f608292e45173001d80cc801f729c5f71fc213b243f041ad5 b101f2e355448cd3fed4ba415f74a47a1f5351225540c0b4254d7fa61763ff4dcd545140b2b8673280adeca6f46899fa13f540ad556a66f7a20edad5d4eb2f28049d4016bea60ced038bafc05e0b1facc3270c0dce552964810e89518e8d7164 +a743d8337bdefc4753f937e869a36439da1f8c75e1278c3f6a4a969d93787dac93293818b1cbef5b8636e1a6cb3acaac1e15dbe0841c8001512b689292f3f4805997ae26ff52f7fe1842512a020c448ed01af2a061f3638689446ed5f6bed9fc70726ce4104bc11142de63873fa7039830223e8f152996388417c48e0c1fa81b 009f6bd008c04b8823ccc3ee7d5aca535c211f35e9d9e7cfaec518b98647fbe6d28283de 81f44d0228dbe2912d09c42fa6526dff3d20bcc97afd9edbd29fa6d70bab676e66e752bc16d4b4b3cb11a46f2dfe328b0543f8055766e3fd5f976d6aa7030ccf4dd8deab22db371492211d123404bd6cebc7075c99a651dc8588fe0a6858315d +6a7a3ad614a3a09d2dc5a80204815d0c6471057acc0fa73f3cbbf1801902c3e1cba3c1134a79a8ce61994a94a5afa85ae1a44b2cdcf5153f8625713c872da36aba0afcc5c2f26636dc3f60e04c256a5b023e20e2e7a3f7305bd5b3033fcf05368589f19021f8c9096a88679904b657bbe5b9bee67d6e53d176fce1de9e54c64b 0150d2812505c82584201e93f6e0cb875d29dc7bd99d9c0f98e0ed20128886e67e1f1071 8f14ab053f60c2bffb8eed3ab875ec778cd7f9356bb2177a646f699525bb60a2e071b0b1f3a492238fc806ae20be117a13f26ca7496fff6c1fbd7bca78d8d91d2507137c4758b2745561c99d9d8de1091e791e06e332b37073a546046c03f8b7 +65bcd77a3ab345cc99b9c1300755288102a6ccf140bc7d1ad25df246ef01fd57a8614b352033b88cc6ffffe5b38b99ecf03baa365ab5529d6751a3c020d0198561969aade09091434d84ffe13b46df043d0a61e20a08e9c32b646771fea1b29e202d40aae1c7079873c3af494ecf6ef5eda855736c9338b4a5c29a086a8266fa 01b3fb9e1ff70f94bc9d7742ea535ca982215af3df381b5ebdf1db40c7c849a7978ceb98 8fe1cb087e7a5f01c2835e2c7854da9240c7609a4317a59fafa4af191e93142ca7fbea136d6019cb165741a139feb1060393757525e703e14034c282f5a7bc09f06d934fb6f1a732dfa74076ad871104e3e794a3b8741df3fcc4af82b46a4f9f +ed1acc360d02ee6c36bbc223d91bc1d2009a3e8f8dfc4c3796cd8555b0d2b46716f4c8058bf34c2d4954e098274ab9c2cbacff46a0578a14e77fe104196cbc6d2753e3bb5422b8b79fd004ac0aa920eea94925c016ece16ed4dea916fd92563ec65692a61b28ee84bef0007120bb1e31bb75b8ecf68406a71af9a18b4edf5320 0147fa46fccf0805d14c1b84ea59bb8b8283d54ca0ceefb29b5585e7141340c55b7232f7 aca92458c2aefcc636ca2e2defcc7cea542ec5c1a93a54c8cb51c9e35259c0f42ab5df37f78eb4f0eb14d6f1ab82652f126f4dac383a0172b6b34fe04481cb7c7b47e25306f15944cf30717ff70a228c7bb7330725bccc47559e47816f9be62b +2debdb95a21d72b69c545988727366a42b819ca6398a82129c5e3772aea93fac0aae9a27b11969ff0ffb9dc0301132ca2452cd863316cf24ae7696422d4dc68e37316161abc146e86f04b72d9a27a350d8545cca245b2be43c33bb822dd813d13e08a718f784845df8a4ef49b02529871ec76bb3fc1ba31089359f2ede73e767 00fae097ea56b35a517be5480802f450eb832b244558d0cc922cd4a5b40b84d02ef11216 9530467c936c9dbae174a8d5cfbde5a35413646fc5dc163b669b829698755e3cdda9e6885a6078ea2c542ae779fae66c0c80057573331f7b0d38c2bf6a7afb090bf80d1045368aef9907ae7a92236a56dbda06c66e2238a3facf8c1624dd5835 +e4e0c6c8fc01244abf81e139c961b6a6e2d95de5dff1083e8a48b40e3e5b9ed909152c92b1cf2263179629cdf76ae553b58bb2e9223ce4f9ffb5f170f5f0c5ec97294c34a7529a897e9397f71198cbcd68bb4055cb8cd6b690290761b3b73303f82788379df145358afe28f2997d191d968929b7a4b9a0f6228797dfaa17c613 0026cd72e6ae19b3f4c53493fba1e8082a8df1fb7da6dc111b47a41f713f49b33f618d0c b266806abccb8fb89012d663d275cfb2a87590689835b4a0f6fce812a350443170ac173fcb063418f2eadea9311054810a7233452db3f928138b2046d2994eb86403fef953e22fe35ca1e85b64f6779d720fb7a677f1a3cbd0943d127536b665 +04710947b7c90855ba4e59107b919d4a1df22b503c5c4c33b286b6b08e451e6fbef8ba40852f9f0ee62c9217abe6156bed46ad6f0e25f70f528f3a73d099338c578bebd6879d810e6e173c2b0af1f7caacb3531ff0e6a7856e4c84db355d110febdb21c683223eb5990ef2038d462ddb7962bc0feea5f850954943d53041f66a 0198e13c7d95bbbb6e226688719639bda988867764ffa9b029018b5547850daecf58fe1f 8eab3b00cba6d8b4ac29ca4dd8884ae7a112f082cb3c81f7d4207afe2920958ed13d138432091f20f44850eedb52bb430ae1c9094461ba2ddcdd8d44f80e75508f8849729e71e35de9f6542f42109277d899c6bc874cb4fc45348c3ab4e8f3dc +c62d07bb1ef756b6b2fad355c66b5be086b6dc387b37cbc4a63c841dba3fce65b09d3de8f239e3649382d172f065b78f8a53e0283cf345de06b4ee0b4b7d8611bfce92a7d993b1938419afe817611bc6df3ef74191e7e39ca2339fcb5b5cfee3166d09cd52a1a7d3779722aec328d326a11bbafb6aa417920225ac453146b9b7 019098a39956747de24ded56435fa1e6c30cc2b8088fe9a75f5d07b2f5939c7a60db64ad 90d470b787c4e2f483bb758f449f6e3dde7876392f7ff58ee80ed37ac1efd7fcdbffcb117e5f8091dc6c8945b4e65aea139c65299ad4e38c4225682ea23bf51f42e5321627ffa459a4d8ce9ab39baa32719d9a583709ddfef7162904f1cac183 +e4d8d49c9bc566261d9134d5e237d9cbd6b67d2619a9bd06b7c9c139e091aa10682cbede114e1d4777d9cd67a16b7d64278e99eed62bbf25ec5a5a8fabcb0a3468b0e73fd02ac6533e04b1110d29da3e34f33eaa228b78341b357a5d892a61beb2168c3bd5e66bffe3f2080a1e246f55a41ebf9d579e188d16991aa060460d6a 01636bd2be121e07ee83ac5e880cfdfca6a56f2b9d0badff003e872348368c7c2cd96b6c 84e3b0db0f33066d7ef684c92cef971dd5df6f2a149df5b4d1aded0da8211f05de63e35fd7d0484195b996cfc0205c481390be55706c061c9bb004e4d6eea556aaa8449868fd8188d5f5c6b2357ecf4ecd2bb77169914402221dbe86a7d74d5a +2d1358fdffc14630fbc421b443d3c22ba10ef34f15c6c5bb3c73a9b8714e4c411de69b9cd6628fe2eba5efc4862af66ff916505023e0514f564164b389ea422d0f1beb92adcd65baf43556614eba25e43852ba65af78f62d64b36696519ef8284ef7316ea52c365b99f63a39e6701f81ad520d7445cfc0113c38ecdad4bf5b7a 015e5f555119c19b055b15b0c0d2813068bfc184f864e250b202384f5728bbbda1cb0f5a b39c3d32cf8578090fd015fcbd58e8e27dbc33b20e2621d71ea14b0ecef7a4b443569bdcc762b193045f9d77340427ba14e192776bb283f19328965a2435229d1a146df02afb25646dc6df9a388a3ff8d03f9c4756a89674f701b00389d823ef +d6336faa5c3e838f4fa58626eb353d4cff9ba8f0aa0e6c3d0d850e8b22f5b0f047afc97767f1afe2040b85d4e401ba688a4da7a0caca7fac450899092c4fea789231ba9b07782010720f45d16d353798867dd7fef4a324520014ad5cb32684ec50cab742b750e05db040ff51140e8d740f6774a059feeb493b10d8ac722f23fa 0190c8f17bdd38669e345440d2c7631d67cee9c6548c4e7b9452377adb9303430efeda0e a8b166ac7f27cc1d33b8b89691b6c61efec84628e824f598a5bbe8604c374a763c2eb9a8b525977341d7ed6bb9c57e3703daebfdf9ac2e0eed36c817adb7399f5f831f4a1fd8a4ca6cf39fe1ba240c3ddc1b489b24ce51c01822e09c39107e27 +07384a3f650bd270b14ca388a441af201b7767a2d47e9033f50cefd3af8257ecb38f5267e141cbbb2ab7327d8fc78cf27198ca3543d39553e178390bf1b921618432ad895e4f8153783a7ac22f4ca3cad4560e64f1ee4a7bcad05df98ea49a3847dc2143b27c243e48be59c869a547988e2205358e8db98b635ca21b745df4d2 00dbbc2a0409ca58a9e39e33b95fdd15080443c1dbdb5874bee991bd1b127047f08ec9f3 b3ef21172776d415af2329de74145a436e90ec90335d88a44052273f850dd5f9fca89658f93940629ce361b7ad19c26f150f4b84b4e3384a6f67e96fb7dacfe1c165e676e2853cf82f96db7baa5a876fe3b1ee10e95ed2034d74a78064626056 +824f26dcb4ce0ca020982814d5c727e629cbeeaa818c49668f8f6d743f0d0ad362b24cbac48027898f386889ca5411d7d1f9afc69493b1d9ae4d7b695c9fa0a30bb59e6be2cbff79231767e96cd8bba349fa2f97955d56f05430ab4ebd007064e3d5add94dfe255b6deff19650883ce9966e1a2affaf84d9540f65c87ab1f936 005495e6c59ca1873f36b756579632fd47f9fb95b64f52589d70f2739aa6a3bf8cf8c198 a785ae6d6070d1d0aeeb142fab12a9205c37147ba1a3bfa6571a0c3796c82d3a2268c8ed1af2a14624c0d3ae7b4356c204dff4de6b079b746503232b7d6d291cb98b15655e332e089009145e176bec47c9cbf8f45b0d23786c98c3842f22ebb4 +07de1e4bb9be15a710a74806d4447b093bc08ed04392d1bd5abb414f5f4b4d9d43520d0e46fc81c2a97e71086b28e53242449ed37fd7ed1c5772dbabc430fcf82ad20437b38eac15820421e51912325c872894452c3f8a10ddb040b35308e583c155c3707b52df467c4945f4e1071126ed46611a3253c297f5cbca9e27f58448 01724987c9b698519b6c225cf1261b77d0300045e5fd774dcbf13f285e6bd74512cb7edf 830c0d15a77ec84a01e403ea4c2623add24842c81e943a4b859e77e0de8a6bb523267c45a233441227776891ea73d25b023d603acd626d59c690356549229959946184d417aa95b0d288dbc21064c06f2866dde023671dd8fee2a5d6e070e6f4 +1edbbbe71057bf7d0bfda922be21a3a4dff57b017ebf6fa99651246cd173bdc9b11eefd048ea599c1f98e907932aa04f64ed0a007831f30daf186c88807400970904d6090b2cf181e0f65f03b4234aceeb420867812562e47f452152bb1ddaaa48487170d06e47c5e9a7c0faa4fe494663d2fec22f7665ceffffc214b21c6b8f 01a5489091cfd51a0970508ee3e8449081ed175928ff8386592c83043a7911bbc2f8778b 83eb4a131190da7db137c9a805682ffe5c9de4fa98e627f80f7b87f3a15fc75739780ecf189b45ee8f20e352ee8f4d9a125eaae44410dd22dc421cffa8bc3c65c6ab12db2e50aa38f580fe85c9504ca73948374838554cf2c076b4b6e39e9814 +db5cf1de38a5187af11c1f0f19a36db52f8417de997229e83072fb51a3b7152a3b383e9919c1b8427582e53d4e7e25433d46cdf01492021c237ea0a87d38c71634743115a6b2aba66d3faa8003158340a5078171e0bd55a6e5d8c7fb2631a31c1204e1479bbfe79ac70d5e5823af502922a900576f0088a33e42ec3e26c0089e 01a45ecda0788fbd7cb7a716dcf4c6e83d4148bf63ed58078690ebd238c00329c462590a a1be1038628ccdb4489c9a6c624351b0610a986bb05df8754c011b521cad38f93b5b50d99762c1f93f5060c2d91e519f06ae6ca5d3d30b2b008b9df0129289e9d112d9583ac51d72125721af20fa1f7b575ebe00cab19273c8160bff7aeb16b5 +4adaa850eec8272d25d76600aacf2cf66e754f6c5efa65c55a2a31b7bc69437d9a7e47c6f51c5da93895a45221f5f92c2e20ee6a95eed3cc7249688261a35d82872284900eb54dd1df6024ec48963ce43e8ed8b8cca8ed22beee8f0aadeae53726cca05443316537840ab824cd1b595f36064e9a19333748d4f4972178e7f5ae 011461776c33f20b176dc8f2b0cb2446a9b69e55b6c7bc7457a7fb4639116b452b79661a a72344661293b34c27b74a7d83eb167fffd115059c7ce97f62464c2fb6a590a89101ff159e0a2b07a396a28267dc4a6713396e6402083b5a6fc04a568a6967d17070a0f2c60557891cebac59064bec2c2b0a6d71328d122a633543bd72d8b7b6 +11d212a99c39fb5e4ca0096bbe6c81ae1490e1b8e07374b4e773bee4fdd24a3c13d653919db663d2c32aa4db140c4ae2d472d4f878946e527ad33b3dc93012d97458f96cb622ddb56f1ce7c2474ad0d5291dc35545de47b7053d137a8e79dabe06757ab53e26eaf751111bd27690e57ffdab5337eb6f81889e9d1b1ac729012f 0025a65f627db2b4d6cf83c5b0c00265b9b63f7656c5e3382139e4992bcdf3cab502844a 89be983f44b68db10c5a3343f152579747a38789b3d3e3b88b0fbfb8040300767f21866d397f5538440e5289cd987a6603783c64c387dc668f82a797f3817a19b7a836db2cc82bfee22cd24074657c03931c57166d9a94636234c56d45c58df7 +9e4ec74c09528fdf3153a0f6955f20c70915ff524b2e19c991ec4c5b41ea9185e3e876a02ed6f27c9b3479dba951bee8680c4c99be1a626808114408856994be7444ccbd5ef9859fa479b1050bb836034e20c531b4d618f5843fe1d4b613a731895b489a2363f3f5397d5ff964cf037e9b11e3ff5e1c3d403e5a46b8387c1241 0173b28fc29f10245221a907778708b3ee62e0480aa9051d4c3eb4e8d552e6aad5509943 a8e6d3abddd5b5751ec7921f5602bc686c4114792864139d986cd6852a772060494381328b71321ce41d8e5fb77dda920dd024d269d41ff44280e8986d47c6bd483b5f442f6d0230a3bb107d217fcb32cfd884cfa3a686626fa784101ae99e48 +5fe8253d2134c434cb0866796013722e82184638b024a5a30938039929ccd8415c71f71f239c5c5a81f7a9cb493dde209f189bcf766c17c6d9589cd0c7de7f07ff9f24d2320669b589d084f8a8ea71127b9760b7355b162616afb34bcdcd416f1a062035102e29b70069b2b4dbf70179b8d60bc2ee5a455efd40194533bf560a 00624616adcd45e1fdc6cfeab2b17230d73d91fe0b39f4664f3c6891554f9b8e238257f7 93bf5948934bcc591d1c4a7b101772ab34e60b53b87f04057014c4860c60b67422de1cf0f331bd64d763ab5bd8a11a2f18e2c464b73a522a44e2c07c7a7e8235cdc06bbb463fba4105a887f98668bca2e90f6d625ad162c945fd0ef04cbeff89 +db49891838fe23f0530abd4a4fbba5ea970afa5747f6a0a10d2cf4d841581ea2178705c1203f00cafec91d0a72d25448072c9cf7d7ca5580b39f8589ec63128faa95cb0689574a6bebd515049a1eb9699922cde0366b5cd58aa8f3d3e847706896f7e1cac667fbfe94b2eca9e7be79a810806ca4bf53f219bb30532ca2254c11 0199757ffaa2c59e198d66824eaad37cc42d49b2e241b6a60382d05e425e800eaaf32470 898fb7f17dd5462284d707cdb4a6044f23b1ad88eb308263e5cf92b02e0c2da48ad0e6fc3694e84c8fa8ade8972e5e77186575c7b092ae53cdd20544a1aa50acc705423c2bf14aa75ccba01bf5f5e938b589188f3636941b0be56e5c649311ee +29d385d09c1142a7c181fe4b6e6132e414c15aa8605b44208c0399464613b966edcc2d46cf203a3f85d943d8eae658695dac74366224a0d0348083bec0106f5eb8809ae8d07f792fdd7c48fb1a25d5ef3bb9acd40b20c61c821024a9acb2ede321bd2d0dda849c22d76f421cbd8d51565d3c4266f666455ca1c0c3777aa44107 006e51381dcf21050aef2e9b97e35303cf3bd91956854ecf9b6b9827871d2efbe8201c5e 854758305f1c4825cae6394a8004275f6c65c9242b80d4bc69640535f0363bd5a0e48db0200ef7140277514f57a73d2e0eff1a85e5b99f2e91df2fd8413dea88b4a01ba6a83390e5f0f3ef7f471aace58b42a4a054339339902e88f4272a2b8d +774c1cb8fb4f69ecfb5c7857d46415568d88f1f9f05a4bf64a1e1ff6d64aec16e1d09292010d1f067c68dddbcde06ea49be2ad3838053f0b9c0c2383edc451ef0188565118e7b3c66a4fa372b96633dc8a753106283b02d0322df273d58cc9bd061ec219f1e1a9c8ca1400e5e39c1b2c254273377dc98a1a2c44e5c2a5b89167 0018adcc22cb9a2db64bad3d60f1608c353e091637b948914115ebd43679904f955c8732 a595485f3b0526cdce5804bbd5a95730732fd9d13d923a9d688913ebcdb75108259281e839694b158f534414abbdbc4000c544fcaf1de92ea46c0d08a3bf0d62b5d567a77004faa99e453dd62ed8451db168eb413f05a4dc2139b0b3519cb970 +c406aa4295f85c854b4db2de5a7a2defae53a319866921a3673af5b48c85ef22f6eb4cef892c790d8e64530fc20c729b2821b5f5e515560b1ac764106560c3a6a05657e34cd6deadfe2884bd288cef4ca92e1f25adde7d68a30fb0a1b3678156ced62e466718e68e9d67099ad82613b8d06bdda1a7b867c2455422818ae9eeac 01898276f159c10d92d8d4b6ae214d68c72792a4b5f1f79936ca3c063dc8d9a88be439e2 ad7c88f0be8745765953d7d1113d14757399981c143be1dee7dfc86e33f7a33a83c8ad68afc0f564286aa43d215e8e4519fc331ce910c9e5fa532a96fddf90c5fca93f2fc81bfa21edb8bcd9bd94c0a3553f54812f0b3cb9b05053e13c80538f +cb2809152f8258660933472c06ddcdb65f6d5221fa29d5b0efec9c2a7914dbbf9ce0a468ce146fb333d26f510a87a6bb01bf8816756a1b5df81c5f65360957cae84ba038e37e88777580e91c34e2f5aef4fb55af7b81ad28aeba05e0b1c64a15381a6719fd2c16e38a441516e1b394952d984baf9e051b1dc1bda2e12f8ba5b8 012ff37c808c3cc029a9cfbb67a5ed21f3bf362b49270d4ed0f1e38fad25ebd79f112a50 8dc74ff615b2236f04c79562eec1395a5cd91c2655382630f102137fb734866da71803be77537260d3716fa991e433cc1402a0298de735afa4cec4323c01da2df8527646c73b5aef75010313d007f7d836c88aff04ed8014c10bab8a806df7d6 +e060af96d4a7fe512bbf26be9a27bb6a8ff37547d4a7bbbfa710db24cffcfc760dac120f89f642880db2df6307f9ea5441d5932d49762d182b29d8e7fb067a61ab0df622f75cecc917e27d0326085d34581e052c85f50a37713e27518aed7c4434f86970e00a0a4b8503989e72614131b7164c1bdc82d2b6aeac0787f9838476 002b8c1fef9c6def32b5f4127273ce384b6add4aecec957c1662f52334f5ee97f49852d4 af11d16b29ae43fdf4309927151b44bb89259057f71357f25f6610df7ce172666b39c0e34c449948caefaff5eac659c51180be67037d97bb440aca0f92d69586a569cebb7cb47e36dc990715d65287d250ae44fdbff181272aa6795b740dd703 +d235c31f0a82957a087c7597673970aa39321d4c2640685a03df8388b5eae4825d1fee29926f416d5e62a2e9ca1ea7cefffd31607e750fa9675983608e0f8dc895371b190574d065c5c0c23ffdaf49e65362914363a3fffbc2c1bb487cbd4f69ec22dda5c7dc3bbab805c81faa85787cc176bc0e5703924f395d8c9e7e7701e2 00afb1c45e9a9f02942b8e04da4b815498454dde6643de186625a98b3c1c6993abc8bba4 b849ef1045e406f485a913be24c954d73b4b53de76c4ce3e8d7bfaa46a4bb09fc35d5ba858c5cb2930b529b7173612481175359733ea3734397e95113f4e9b83c8423ffdbcb06d1a62aed8ef72a5928532d8652ac16de2acdea181ff6b418e19 +1a2559777a5fd8f269048feda82c4d9fceca95803f84a813789d6ed070422240e443789c5231d63d5268ddebc060dfb99c4eff2ff115d2984d8bbc5c05314562ea6864fd543e7e0a3b8572c017d8ae3563027d79bbe164d40a5bab354720e45094b9b26391ceb55339592fc2f10b97dc9c2649f7227648f5cd2fc46d78d31c0e 00ff537d73a4da0ae3a4894016b71dccef3bc886f3d24a5abb7dd96cf8fdcbdf0fdc5e51 b9c672924829aabdb5c0c12a079f5c0af0474fc40f4bb608c826e5d2d74614834c4da3d800677e981b744724c7d1900100550268cb471ad64cde9f966c18bf5f77db27ab22b0e0f6010fc143d8cb1de3d40438da88d9d9c4df9b9060632cacf0 +658c0d3f764bbc952fa55a258bac16a5bb5184bfa76cee06baf9ee6b9ac3f116e08bb2406b1dd4be487b057f3b29c2043ebc33019b2017c4deccb86f50ff15fc9248ea5fb64261120b1960525aec3cc18827c23291722c5add8a3761ff8516c61956c62b8cbb13f3d92bf3eb45a70704c01bb3625d21c38ffa83a6db086ee968 016000d2e879906d1040b32eb6ba3caff700e5565871ac75f10c5c15b509964bbe5e14c7 b311ee0d1d2fa6e1398b078ba890903ce24ffb5b8d76794378ede9f9f9e52db1e69af763ab092cce65e5e19bb1aee43e17d1384b9dffa0cd8da5dc340d02393fa1f36f5340de4377e24f4d8683febd66d681255204f54271eabb07d61147143b +4f10001e3517c2c1f973b555f4827681e096d860c4db08f1f4aef8000c9c24bebe59f8bf3d7d3cac959a1a5477bb0ea43f2e746b5d14ed48a58ef35484b0ac786d2fec669f945e846ad73e6b77a9e47012a951b398941566330d89125eb3c1fbb2f06adb951ff5f047d102fdf28b5cadb4a3e1a10412eb3474d2ed5c3fce78f5 0019528d505bf0584628d0214bc857150a929d3f59619bf8f3acab545fff0977c9bcdc97 93122274bd500f3d277e7a4ca2c6cdc17eda8901ff464c5ebfe6fa148ea2f88ba5863a14d2a77225c981058e047e00691973e36f47a16dea4f8898fa4edcebb59750ea44da7450e38e1bf110fad009942c240d81cf4473228ba7e7a1f21ad7dd +c43ec3c3232cae59bdea7cfaf18a4672035dbd2b8b6b1b44ede376b36cc2d8baeb921e416aa177f5977da8bf1d713509e5251278b6622790056271715cd5feac58bee5baf50b216e8eb886279c5a384cdb696470275b7487fe9ac4c506706f6b0f9809d1ccb102546a4297d2017c2a8df9f02f30d3d1bd9aebf6a92a02e0d202 0067795ce117bc0a389397fc22a01cfd9422cfbfb5aa44131938a8c45e48e1d5a718539c b03c46e88417c612e3130e1d4ccb3c304051fbf2b28f7c6e9a00da2352ea9afd87d6758a78b0bea74e4ee636bd8b14610f1b95442bd6f2464d12cdff2a1c026f5fd1f561e267378ae934b0e1677dc90ed08e0bd94b08ee27512a280451e4b02f +9b7d675a3d2cdeb280ea28289b5fc2a3ef6b535ebee8ad242fb031e2e1f364e8ee806568b2f8627c5a5b4f51f4f65c71acdc1152c08b9211b81907b551e0ff47f5a6aca45dcfa06f09bf195d19d7b165b52111b601fbd97b192f62465f8ba20773b1599c8041e91448eac7a5763ca0628f40768324c5304e1119ca6a1fdb0778 019269dbfe4184249952a651a507584746c5b62c64cb3b17e0158aaf4d086a4afb0330c1 b7e73e4a61ca5a1e248ed8cd8acf7c745e642178c5f5e69b0f86b0e4f01db12c7951f27e99b1c4b801002bf36a998db41179186025b0e251754603dfe7aab79cd7e2f466c2b05993d1f12c2ec6c21d89c67ed8d75a8908c04272f70e8a7b0097 +f4a08daf8f66ce57a986f14b918099bcadcc4308bcde7c169ce8536a40d94a928cfc0968180a2c2a242c59df73ff79a03687998c421cf9a0e661630378779a4744ae2a6cd24ff61d7fcd6c11a4c8bcaf358075e96f864df0998ee98ee393b37bb38747b70bb7a208740959b45174a60153ee566e0f62528e9a5e4466186fa650 003835814de0d6441cd80a44e40350cc8bd62ffcc81e939a4410bb9c9259e30463c453b5 8d9f1caa08264e330f7325dda7eaf3f0379af42a09c2f0263db967be1eb474827f0483d96cddab0b2792e2d0db09a50e0feef7271faa85206179866a2c51d32a823b58e9d975b865956b05925d8e6b66ad185542fd6172da00e44e13ebd62a49 +864647405c70939fdb4c026bcad53218ba1d438d82c9138f0f0ecac815dbfb242307cca52c84826cf6556c51082a23f14252dfaea43ba229f7493db2bf8ae9cdb0228dab9e25cf385b504b92cca94f813acceaa1f18de851b8936c4dfe9e4e17002f02dded6b4c231ea5e614ab46fcdd637b8c6193e8d0c2df1b3d883b97e1e8 00aee83dbed3b703cb6e60d51e373eb20e298ac005fa6a572d02fa1e6da0345558ad2a46 b0551deaefc189f27599ba9891c617b7c8e415560f2dba67235afdd091edfff096ecac3090ff61b885999a8b1d52215602b04ee034dcff281d16e906e54b6d62ea997dde734f84c8a8d8a04b946004893a421c79a6839d6b822624d688f1515b +c87c8f3ad5c28a027b28ae5021dbe8d425f74181d519451f1fead7a1f9dd102fa6785b147b610610cb59bfa91fa363bb79ea602a7d7e1439f874c5dce748e5c320560c2d9676f3a948754c72b6db249478b7e19c9829ab4de2e344535d3e0b7c20c272f82556a280ef491524b255c4fafb9c8ecb87b0149ddd9d7bf6159e3337 017b65c66514019ff935e9d571a4e68e9ee4463b7b9a754b93f4f7741693f4399879fa8a a73799f82ff05a97332508e23b2641f24ea393fc73adb3ab95b51707a59c1cb86329b795291286110b311f9ddfd9649d14a92b591f00ba6f862038f19e847c2a3b4a8829cf19777752da4b0747268bedda08243843fcc17eaeba6c0703cb3992 +ac7da7611e2ade20aad64b418a16e02e79ab4894d758550210eb10013a9b5533132be701f8843c840807c4167c38d21dff168d3baa65d5bcf285b73dcbb75819f8d7a20a849de335e19bae2aab2ca560b93d340731f291599a5b28afd7737460d291105cbba6d0290e836f6f6c1113d1b2faf90ac5de7c64e25206d79380a4ed 017d2071f39ba35515a8ec977ddd36ca15983e15bcda626f15af61d87d58114f4c80a8be a20ced67e18a4dc98fd502c2a4240af0066e3f37d093d246eebfc37083fe9a1f4f8f7ae823fff178da17c9869aa644fd0953fb2aa9e8a11458f1e93f46160a9ce8f59811e5bbe4996baf4e0434ef40048c39d825285852dc328107d9c8d9c869 +5757c472fa2f81430dd920f39b61066a28c870b80e6c96f822f8f19b398c3574d159cc22120454dcd7e97be8211916e4bc8db365b2dbb99a6e597d06e6645046a0abdccbd06741e9c0eedf33cb78d78a540c2a390719acc498331e694e6b0118cf4f787b51c7b7237458a6149d6dbd0a08bae8097e919f970fde920485e9a0ac 011504659e12235855fe55220287a101e511d39a627f8a0d414446385d4a88f31507fe74 a90ebf5c2b50f867b318c716b6947d980da945b0e0d4417df63fe802284d43894e2e1f718a5df5a5327fd273e12c9c8d143e43f2f83469fbdb9a3b025a01b2878822590d1da36dc0a0a07d19d019d496fa61b544bae8d5b90a84ecfbf503a9fd +e350383d04af0f4081bf09b95d1d53040e7acc64e56b13b653df31dd119617b800e0cdfeb935dfa5d94f1d7814688d8ce41021810958759cec76560e1e5c0581456acd1a020165849b2203f1c11d318d816697f36a86b59f160faeac7dba71682d3c031d0d547725ef69cbaa28345512e38b75ab011911d8924b2d17a857a96b 016e4cbabb03215767249ba2a608708b78d7387be9e77f5efd2462467fa05e8dcde2c036 99ddc2a36d133ecb85e25357dfb98cd9d7e166d309f066119014708cdf8b291ed0c9f83727ec8cd073f376ee7f7910ec0e1556a3fce1348b0f253d86f93e9fceb98c536ca6af77258ef67aa9f9e25cad4635d2a81dadb9e7c31f17e84cd5841e diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K409 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K409 new file mode 100644 index 000000000000..bf9763607500 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K409 @@ -0,0 +1,60 @@ +f153cc61981a46d8a47d17d29ec157fa93fcf644beb84558db7c99c57fb131dcbc5b65581ced5ff0b29bfdc66ff703ecdd4290f7c353c02a3e6d6867f33f3dccd1a0b6752b8a35fa143f8921a5078af9c85b212564c5b795da9858c7955095938fcd10c21e35e1abe905e84c8b4bc05f2a06091ce876d9519b96951d08c7ac9e 0011c6528939672bed3e8c905b7ba594c3ce95f37fb28044f210cccd01dfdb42c10e8e1a0b5d6fc757834ca7f08e98cbc52b0edd a301162fbf98c2f5d41b2bd6ac9b80d76e7017318bf396504e3211680aae5d9a7ae94636aa1ae838eb728c3abff9f51115ba157a6d453d383785c2b02c128997fa559169af09b9e66bf4fbc98c4ed7b854ff26e111ea59976dbc2b89e521cb6a +258c91524423b5c876432b1930c7b07b56eb5e3945f1e2296a4e5bfb9b9123f800ad195d6104641b1f1970bca553c2032f83d17252e52403a9381c1fc18eaffdf026f7537aa27d84c5e3d6e39e651a92a41139cec5181fe794457f556b390943093be719acd23fa1ddf7ff0aaf0479484a381a309b4f681af74bf97caef08c22 007e3b714496dd118d8f3f597961eec5c43d0265bf85723b0b9b0616977e0acc2cf686cb6afa6cdc19114e27ab000e762dfe467b 8abfb7cb804d45c3461faf9eb1241bebe4943413d2c58ff113da485d60a76feaec1cc0c87a00a419375149068cdbb76c06706f70e78965a2011ec1a9ed957874b9c6fa1141e72756488291022a00d4ccead9b1e2ed258d7afc863d4ed59ceaba +a16a0d6fd57240fe88c7c36b9f7f9040cfcaa9afc4beeb8300818c5f90cce73b819a12c31d42af33146399cdfa4ed4954d068dbb0f1f342269dd29f1fe357e7224304b67b0f924b794780fe7e6aa9dfa3380252fe7177b43e7b1789718949b9ec1b943c83ed4399491482f0f59d2cb8050ab6f8b5854d76c50651428cd29c40a 00182d1e937b037bf7f84144f7d4c94c935269c9aae7d500aa459a7a0ec113b232dcf282908eee4c84b8106cd38cdc41db3f89e1 a2fddc5cde4de3e5a1944fedecc5169de8cf8ef4d0e3fd1748d5348bf64f4f167c0bc55402ff51b317d2132158b3bd1a14af90ba2fa1125ac7284bb9935ab38aa1cb152fee26dd715301c9cf9fc9ff2273f82c877f243f934bf0df64b40c22a4 +d02ff569828fd1add21f6bd1c50cbdcd09222e458ee79fd5dfdba3cbb84e9d926fcf196cccedece77d5aa17f8c8cbf3a9facf0f02c71d5c1c8aeda9d75f6fd7b6f2c5c70dff992ef6e02c438fb3c66da5a503b3c39acbe2a069da457595b542190d818015d462670b0807c401e36b1bfe05baff3a8ccf8d1f5f8de7840e87993 007ed09428f460724c8a5225a31151e031d9949493fff5703369c401762345d002c4ce424294baab22d9e71edc4f854510cf0e6a 97dd910b51e5ba67efe0485396dad10cbf3f77a101ff58a6ab5501b77917b4bc9ec39aa17bfa19b701c5acdaa99a29260f55595047daee04790ea57a4bac750652530a4bc7673a265f77a5d10b234c103c148f9737214e3f486d7bbe196a00b3 +57befce973b225cfce7f996fa5a1a43acd160681b88a87b7de04544eb7b6a719718f1ca7f559b6531bfc18fca3836d2be7f7a6e48387b7579a6845796d30e46f0dda9d82680f8c96c5f0989741adef9762c3db763cae2699cb6c112543635e20ed5cfb4b55ca2ccb32d2d13936085a8ff95ed658a54be73f80c912ccfe5f0ca0 00390f05b9619c27b800e99aeaf61ef7f6249367d5cfaeae3c7b523a8b29153eb8a77132f6c4412545a842d6deb7b7aea7e2bda5 83b7464521076ade87130b80eaa4d58932a7b614d9b8eb40618a5a3d0c13f0af9454219d19da7979f2622fba0520074e0d1067b771c7177b469fb11fd1eb67454e317ac704db3ecc7b74b10670e4510c757fdd1d2dba1175b801185011e0d43f +4277ba40cb462860ca722cb4ee71c61836d2ceba18bc91f3fad7dea478972c6da0ebc02815eaaada1d1a5e93d7ab353855ccfdfc94a5742fe18daee2328871e06c1ab0a9a989d1239df2d2d27f96c415e7ef9a941f06c6790675361173cc229aac7045f49eaca207f59c497619ba32e932b5c1c6576812ee5b146e2cc7de5e62 0007d18652732596add3db31f7a0ce6020d03f3df58131b0c7c633faf619b8210cd309d6c0c4083aef1a1b6d2a756adad0bfe344 90bad3030e8704b375930f4bebd6b0b3cacbd0c8f97ecbe4f6cafb63bcf23d3a285cc3f7d591305d88a2adc1f5bfd51d19fec436cad4290a80b86d306b8205816ccabbbccf14416405d5f94a5e0353fba98ad8e5b818c637d44b04656c6960ce +57ff6792ed4b12220d179bc0ea57ff217f322c85bd3676a681d32d7e4a3e0c8e891fd267df17caba5992f68c35ff670b60b4bbdfff82404f6ed996c30539bc395120f97d4d7a652eaee82bd8f9360bf8bb73748b8bbda9f9480eb54f7eaf2609d4259329e8a5ea020521e7dbd3ec56f23c849932cbdf2875f5d5c774a9d6b0c9 002a91244ea4623b63403dba807d60b914ca3b901a2523244c322f2f11251446d3f15e869d086ebecfa1a39ce304e8b5c8de23e2 90f7c3a236c83e72651bf9afcc20024f20982491431e6fa641dd0039f514f49f5b4f56507f98e4cbc62c4d9f47405422054db3aba3a19c3e1f33a6262403f90c22b4acdf64f80dc438b159d56d18ea723fa7ad478c14a0fe0d0d3fefba42214f +f85113eda64478f460b60f8084220134933de049200a5f37884da7901471542e26690a5fabc3cbf9e679ade71b6e54d869bc136c3d34cc4a9efcafb777abf046b5ae5429136112a9a36a475121eb1f33f1f43481286fc1ada98a41064a1fa38c89e99a93065bb2a119348a9e452497fd5a0d2b83a66b09da9f47a0583732adf4 00068c56c6b5d50d1d4e13d3837d8c5e8ba2f825e121b63e97603fdfe78bb6899600ff0dc87b6b3b6868ad0d2f62b7b7a31603ff 8d250df85c477c23a78f432e672e04ff24da048840389fd54c0367c2832052c923ad2367a4a09cb740b654296df30f6c146901136dd68caf3a1ba9f3b0db02d4b03428a81f35aa3a3d7f6996a5e54d01ba8fb410bc9de867a0a97d31a9d22388 +42811e9ee6dc509572e1cddbe5baf00afeb0c5c13e3755b922eee9e210001676082bc9edc3d78db2b5bebea7a2c0cd2b369226c2b8f83b28f33fb513407ab9d287d14b112d6c3be2493805ace5cf6fd366d03cfb28f4ce3f0f060880db64d6962e997463ba7c05b6fcd1e66babe4b94afc5c2d38c7050c69571d27b66ef0090b 003c88084f8b78446db431bd6e240a0c050813d2a763675b0ea869cbe183df697146cf29c03479af3d34587a95cd257027fbeed8 86e01a465747e6e87b6dbd2e3f0d41710c7a278f16de846960def9e6f8d6dda9c6e22c1d00b2d75681bea986a556a56808c90b25d1ce2fbea5f76c902c4d5b47fd8fa898e7694fdaea8fd66e8376e3d5569e365971835c5a0db86655ad698753 +b38f76ede7441ae0887e689d556f43155b38dab7cde487ce9ef9a46f2957c830d4d28006873fe2368197a6931f6fcaad755102686a457a7edccc8d344e2d2a9162e3d71d41c09a022539ae6d404955a6ad748231aee1f974d4f159940532fb3b1fa0254bfc5805d2fc68696856fadea386c542d3cefd1be3af04ca595e54be25 0051af7b63bf3297ae20517faaa1552f4fde65819dbbff6a52721611e5b7dc1242ed6e69768cdc37ea8cdfd1a5971f06b84b5803 b906b397a8eebdef5da609b93bc5d650b80d9d917fb7cd26a2f8aac3e46c966a863bab7232c8efeafb4c4e88d1a8089418a0e1b91c294bfaa73f4817ad85f0adb486764f7574f922ccf231990fda0ff6bf21034b2f7668baf83a7e49f7b6074b +356dc86cef7979148e995fc5abe2b14a7d5e4e42c9b3509b4363bb80c581a66f4e7e4aa53a4bfd37f9a7eccf75fdd726f348f6a3f779e6599f61bd1d668517f40453b39bcf35db0852a6a6218198f52b7ceda2ec55fca5abe8e5d93af9a42b9ae4de9530c5870211bacc27c39aa094013db703de2fd3121f08d7e97dbd4e8946 003d65bdec48972d03811b78150a06956eb22d337dbec5416bbd8185a6322cd8c0ff8000210dbd1326422289071cab65175f5d10 930fa5e96d956b26a915b4188c8d6512742d7ff44598f4ff01a98ba9eae898e7fac3cac34bd746c05270274d919dc63709f30a0ec1bbb495bd91d4e5d4fa894bc292be14e8fe3c7e8ace2d6c6df702fb9471f7cc5ab08c872a7c66a1f03de4d5 +06fd39a50bf25e89f1071ff81fec5d1e35b6dd68990414ee403dfdebb792627b6a4ae3d2236c159e4441ff90b61ec87b1592c538515f0486b19e58583394a05e6411e69b4285d6d6589982ac0eeb2c912c4948789cad741183663fc070943389d4e9a1150b8f6088fc50605915e9e24b2d98a1f539024770e4820e14ae42ea8e 001f1a8b5f35dbbf82c102df550c72216a243f986f0325920f6186a16d1da74228cc02be6024c7411160c183c923c743354f9438 89a0e0325bc67d621aac3b5c640fb02c82a33774e7e1f66d7fcb946871ad77464f8d25ad6e2295d540d913b875ccc4e61821e072742b1d7d3c2df994937ee6699d9e0a964bb5588f103dba2ef9fa3c7e31a91066bc400df85d28e85a7b370dc7 +6daaa41150ea252a3e966a338377307d909b95080e006f13027f2be5059d9208930c5a329994c0b794ef50eb059bc6c215f68cf42260bd410f9bd86d2ad5ab7179c7c92de4a93a5f6aa17de5aefea815e7c0b78a8cc53c21dc4dee037b29c9df4e12343109283ffd5d8a3b81fba1b5e95506c7e01ac056c86dd0ee23bc21af0a 0031dc621200cd174193d95e9092ffb86189c52cdbb9ed937593f2cde7c4a0264b9100e1b8407336c8dfb5520d28a18dc4e39a89 8b3c2b288e1c4a149af7796024eb58f08cca249e35ac6b27483991577b5f6c1bc19a8d9f515f2e354f048d96fb66cf4e15a9d68d38f83b382a891558e391bdc8673d0a0511ccbbfc70690e5a5a34ea0af455824bf753d09cabfd0fbe8883c069 +6378dd1c12c5197b57d47dc46a67949bdd1e0809004e94d49b0234126a08ad5bf8723ebfd132145813136d8b7dd096f56c34248f09a65c34f60c2f80f9a51b3795f3d2518b11aaeaf6dd45a323794080b78f85d629e5fa719b6ab0b14c78cd908befeaef0dbfaa08cec9318bbcb376d48b11b68735c9554a45293db5e9239ae1 0016e6750245a88340b0f0665b890459f8038e9b1366f2fc1326245a88d4c523ec94429f21869ce3dbf75126e58f77241c99efaa b311e904500426c703235312ed50cb83b44349a24d5779b7fbbcb9fdf1ab624420b4aa16e4f9f27163923f9199eb286718ae2a20497dd3d800cae572f3e2d692cfb7616927b584e5af0b51412809057d2bdd8fa82cbd0b514cf5bd805b562e38 +b898d0f9bd80e083fa541f457d14d853bba55b120424a95e1d9511c8833f48444329e0349d68204c4b4581ef1c4dee23ed0a4445727a72e1e6cde422f7c10ae132a3fe681f9d741fda263e73f7cdf10759467c9d76164086abf6780ad474772771eee22d195339bb8f6235e0d992bbe282b13ce4fe01417f507a2c4fa155e108 00788fabdafeebb72f6385301e30024b56639e629a400f9c50d402cfc9b5817844f06a451fbda29c7ece41dc9ffcfc625fe0ff0a 994bbf9199c0b19bcf0d19b681b329c1a3a1f22122190582adf742bec2ae126a9fcb75b4b6f579b0bf6c8688ab743c6916f260f59143cdd45eb0d1bf8d6e9a2ca61da918f026c01bbfa5dc9294927f9f85a28f5354b2394b14345419524f5d24 +dbe04561ea8579672a2b3afa94426a3cbc274b55263989d41a778bcb082da797d84d930ca847a481789524940701cd5f1d11b460bdac0bffb0b3a3abe1ab689c519700de85a0a571494ba0cfc3c865450eba7a9e916b7fa9df55e8a1c246c992e6a0b44b78274e008472bed8d8411633e6520e1a906c5d0c8aafd572fe6f1f64 001b8dfd64563dc219d6eeb53f2e3ad1d771140d0960b211dc1f757af5e297dc7548d6133ddb574711d466688f80dbd65a7bbcdc ab83c006e973164b5e046cec75a88a434b72264a2515f6cf6f6fc77d5efa35bb0d534e5e33b2e4b948d57aeb713e1d80168247d0e0e103565a1a4a276db3f722ad8a35c8373df1ef026b8159b797ce5c4600f145f5e2284b856a67e670d55dcc +48a8300820fea2ad83c83f7d6b24192715329c3f159d56644e11ed25efcbd3d31600a813b909812987b97d1087e74a63b4494cc031c63492b6615e9d6e5b36f62cb2ef88b9f736595800de465789f43811165a5fc093ee6d776008739de8de2a84e878748641be8bd52e5b891c4145f52bbd46644852a43108e93d86352b2a3c 00422131829608ff730c24ddf7e8b4a2600eaa9681eaf45432daa7d41fe2fb488fd0199d431a1ed823801ce21f4f01a4dd4248ca 826ce5449b1be15b987fc28fba1d8fc6b9b6d50970e51657f622e6b10355c8cab97f9119aac2a09f8a2a8f310973093409b9b2384a297430e65ad3f0b1a8bf5a49177519db201a85a95ec5c65cbb602a48744b4cda68e07968f1bd9e4a9293b9 +276e3a986ce33256014aaa3e55cc1f4c75fe831746b342eadb017676b0cba7c353b3a2b554522c12e6aeaf1364cd2eb765a404b3d0aa61258194a30219d76d2bfa98ad20e7e91756cf65e50d7914157f283f2ba3930c0ad3a97532cc747b1cb9c806fff497f0322025a3d02ff407fc7b5808585b91d95523c9d5864efdf7d983 00095ae8e4c7e55eb5da01acc05ecfe72a4dcd8ec152f1c8dc165014f70eb4e4a7861aeb2b96c418b2d4db58659e76184e013a49 b1dcd97af8ec751b67b2c1223ecd9723444cf16ebd243e180842489215ae68cb84be03990771816bc158672ccfb15aa7030c79a0cc8b8352e74259801a387e243bc96ff76ff417d8a4b9a46d3428efea12463171ae77b722a18688ba9faf95f3 +6a4fc1827c3a7256faa8ec6a0f3d23559d6949f8cc20e7f76111dc4ebd59213951cbf0eadacaeb8862d6baa0cb298645e4314b1c303bd0d5e9893304d4b7fbd36ab05fb6a5edc3fef763e3a4124d61539eb616b359c5cb55b5e2bec50c91dd95fc39ddf521aa854216eb5a707819fa6f067b316a17a3b146e7cc2dd517f7d63f 0006f2075bd730f34df111ebda919167b1d3358ada32cd6747cb3353bcfb814a77ac70cd51b31a0e538539453bf9eaf9d8b384c9 9725944e69004e07de23551ba9774234c80934d582d780a363d4f3d77118a0c933f3ee6c2c4fdc8ecfa3b9504780b26a109bc3e68a1e3c121a64556a3414861e90ad15ba534b57482b9f9662c3a3f4ea7be4d4244ef3ec110d922bb77b81523a +4b088199bd8c94775d8ee508377d672dbf50f6d2c7370e99821ec8f9387492fb2eebdbea473ea18465565f79e2af418555f10c4a527e05a9e20c9c00b807dc8b350cd4ccc2d87e91f66addf02ce4f43597aa258ac6fbe9365cc2c8e8bbe5c884abc929710e8423cd6722a8f473bb55804159a92a3d8b6661a536b4fb9293bb0a 003887d284e9ad17d38bc6da9d83c192a434c509340a7f233cebb032b09ab7c4c6e8730b4a80844898616c9abcd16b753c6bb4c5 8227ab4ab6a7a22d9a376a72e1bcba5d31c291efcc765e9f79c1e89166b036ccb5d9625a9cf146dd0801a4084b5999771027b43bafa5acf2a8a9686573b6d0df99d547c14108704992b04e1ff9f548e60203e06b98f95939b8c3995e108ff082 +848a13465ddcfb2dc14f7bc0db0756832c22dde1e31e4d8b3ae0dd1aafbdf15e954889e95d3bdfd6e5ebb6171fad62592c23277a89e8ba53978c9b1afedfef7e1c3f6d9f31077530460b47834b30bbd84a4da601be988738aa815d3d7e72043243a5288751ee08b4815a017fb5d9bd55833698a0d526b1ed79da35ef0fac93da 002ea5430610864257c9dc393c3addcd0d8d5bc8aab1067643b08857210464428aa85cf1ae6c743fd2682255d4c8eaa46ca21e73 860e8828b00298dae434305c7d671a07099cb030be37ec7a7098c58735cf5f61655873949b0af2b0cd3b153061dbce131285cec7d6cfd05f99c40bae7d20f1db1de77db5eeacc15850d2033260557e0ebf7789aa30441f443411c6f27158a7bc +d1850545c04ea65528849973c220205c35eae98826d169348970d1420b4d872ce233af1daa9e62f6a562544ae3a0633a954a493e9766dd5d87e47486559fdf86229a7c9e1726de21895abdcf2422d438f4ad98d88b45c56742694ad5e11894253270997c049f0f419842482f21c792fbe5613e2defecd485585f1835b6f4c578 0062c757c92eaef41f5d81169ec4968145b5aa2bc1d2a3a5fd000634777748ecb93677b3da12e3be33272a8f0a52300f4a5a37c4 a31dc15fec167672e4af280e06035732fd4b15c70647bbad8760c46ce5c5e46de7f8ea3ceaeda35ac07041028403a02200a25364cf76e641b8c14e763848e8319bd17c2845d5dc86b681ad98a66ebcd65fab69a26da718161b7bfd9b3376e072 +421c9784d6fd507c82904e1054edf9bdd1efb58a0b211340086069ad38b7b0dd15c2345fa8767ef71254ed1bd5c35f742b1d3f4765ff9007a5477ba9e5d3d5a5cb5fab4efc1cad73701d4776c6c4343f42b5d94a9eb78ae428dfe5fbdd8e6ece09d5b75cf4346cf27db856352225ab04e6ea56661554fbc39916accebecb3935 0048a313c0c11489939fc0cffc6ccb9f179093c4e13141b92dbbaac441b7ae878c9d412066e95615174a24692555cbbe904a14cf 800fe79817c020daad6ad01a12278a836e9abcade8137360af660a57d159e9f966fb7ee97b00d4bbc2fab15a527913d4131cc54bda273c0629558cf5590f1f03415cf7d2ec69850e785633c2ae19a797e7f3ac356e0e5ddbb096bed63ded90ef +7910bab15b6429947655e33a67f41b76f1d7b71534f8904d6a0472c2faded038565272d0b5f51aa915e0d624e9ff48d50ebfa2f09324864f26c29ab73eb39b436c5c459c7cff4d2b62992e3489cb4ddfc05d7366b161a463aa1b782641d93507de43c8cd0a0a0a9d1c644f4554e3edaf7fd794248110ca9387e73ae5d00d299e 0046e2adfe5d3549e1e6fa1fe69a7cbb4ac9b111c8903d544268f8318b0b47d4b78fe3e56eb5e639ad5382e7cd5bd4b2c3e70ef6 acc34d131c4917ded24428fbd34a631f162c05491c9d22ebc8d3f7fb60406184d252898c506e299d4448c53e97be1bbc19dfca4e6956f226e0092833c90f0434c3c1cbd31df0ab65eb36fc5448184be4bb2a6a71c81f9871a03c2da0e79e810c +e6fc96e060b956c25d50ad25443f3c30a12d199a47451a49ce88307201dfb15ed816982e8888a28daa92eaf3c5584ca6ab2ca9e14577f84396de2e0ac214b24a2279f5e7b344fb7387e9afc8f0a2b77a4d024a20ce6183499b17096947444bbb753d9b39e5c694239d28f9c454bb05468d17ab564ee6cea3741747ccb7f108af 00480103fd6180a431c837643566706e2b9597de0a1346a224d176a5b2c54aa4d064418ed654a5d39f4773fb509f86473ebb373f ab005220ae4f33673e7ce50253feacffecc66196b4dc3492ccd44f58a2f1f7b271757b1c41e4dce35838f0dacd4f0d0809476922a8face790edf9d3611d598b26beb0da4b9fbf3988c9698dfc17134fe8122a5638ca7c1a0ad2f7d5304b138c2 +c8a8a0d41f35537e6fd523ee099eb45e1ad6ab54bed4d3e315e20227db03292e39dc1a91bab439c0d20e36e7fea6ef08983f390a6b5551ac3b4f1895220b2867fab95552cef9bd8702962839bd9b2c72772640e7d3be3c5889d226acbefdcb448432bc503e5a5fe7ae9ae7696c720a799f9882c64ae0385f656074dd8a6821f5 0013c489e8311c6bef02c8f58903b2ba2a98a27cb935d75a30d320af9a14fa3cbc6adcce09235a9eaf333dd05f4b2f1694985dc4 b796e2a232257c765896c56c0cb3882435222927814147aab8b1fdd8de78db579eccfd24b6f66f8eb56b9c6f8e2e7168090c76961b452d57420b8f62d1e049ff0ca504f7b75123109838314aabaa1618082dd793e555e5d9b4578aa505ad470d +3407cd6d2845197cd7414a30fc3df7184da204222ffd65c4d16a12cadabf603de8043ea14f5e6ddcc22d3572dc06dec1a23cd924e1847ae285ecf01754e2d1247876431eb98e897e47412a2330bb32990f9714122109e94b38f82cfdbbf2eeb4c6f88f5dbf9f0ccb47939df8be321dcd9bfd9bb99cac9f94885fee7d443fbd87 002419bd2200f8e1d87db848b0379741685e680d9affe693eed49d82931030b6cb05d21a4965f4e1df2045c8513a8f574ca9f2e7 81832ca18df65baac3974f633ac8e16204c7f59fa77d708452f1e3deebb9d2929c30a9c3154ba4d1c3258b43b43b5a3c044c352e1a3d1a60f36c7d58c072ace24777936d02a8ee0ee69dfe60a9a6447b9d98045689f1b3049fde2477e6c19c24 +ad43f8440071285d01fd79244907803601aff4bc5d14c77483a87cd742144d41c68269d76c9a83c09d2178bbcbdf99f927b378497ffdc907a75a3b0ad019e69758dfffa480871eb6e1e17c8539373de611a557fad120d0bd147f8debe5f09a02e56fb607e9c1253ed592071f042e42fee39775b407225a2b86a950d81bb7d7ef 00722951879a65bfcb414e11712ee9431eeb32319e0ff28601112f89276ffc2b96eb65c7fd77d023f09914a53e2aae2c84652bad 87353c98faed8427d0d078df2cd0c2fe01d21a06c1d5a83feb9ec9192967ec3f71bff6105409ab969504fc301eeaa8c51563c46afe33a638c9917d42e22a7560b39cd473cadcc4038dad1116b47999483b57affaafe443d42fd2b116f0344f65 +d61a3765229dcd0b4fa6c57280f851ec2bd54d3ee2436935cd6d94e0120d0844adda163995fbc4cd9d7275da859ad8ebf30af9efbdcfc31c7c9ef42bce9011d37cf9d15fb018e117bbc102f7d05750e5072f73d02c2f45509a55627a78cbd9082cbf36807759d1fe2ecbb92ab30cf28434941712d38bdd100955d611987b5968 003f5b5a772d24bd5454bf26759dbd433fcc7bae4f5c593664c4d75da0cdf9430d7d9162bce3d7f6e13a344259da5a7d6a1635bb 8115af59c3d1c5a33fe82c6d9b54fcec2fe5e99c61154054b1f2f0b0aa945d1676db319e4b3e5101ac28921a4dedc07512f266520ef8cc106781bed70523fd21f8a75091368b5a45096a8787da223393e132d753134e3813603e06fd45fa6d38 +1f3c23636414ced48fab6763eed5b22537968e6bf08c178b3d31fb1f6ea773c6979759701d94bc1bee7c354272811edec58eff50c93331b22723d460e56dbee90466b894354777b23b13a37d15a84c762caca70c01518bf34d0c2f072145d274b3b6c932b48bd815fe81161d8507ffbc2f783bd212c29b2887af6d2ffa9d2b4d 0046bb4a141c9099d531dd23ac440eff1f5b10f7cf34920b6b702311d490d25344c665ed5211d401def24986c8094165d10f8934 b408fcb70d05a4fc9ec97c62a5257a62fcd0b20a2a85dc541a8c5dd831ac126ce4a312ebc0188e40aa8a88039cbe0b5001d17717110a58de4358e23ecebdfe3160a397c1a757e0b6bc9d67c0dceb57602c7abcabcf1bdee9902cee5df04cebd0 +ec69f2937ec793aaa3486d59d0c960ee50f640a9ce98a3becffc12d6a6c1c6c2f255d37d29f9b4d068373a96beadac98fd5203a9f229bfc70bcd449640165ae5128e3f8d057769e28356e73e35d8e9af7876f608390090892c67391ddfcc1c332aa61efbf72d54bc615998b3be8ab0a9d372784bea48c9fab244482c75cb2de3 006f2c6e9ea8109223d9a349fce14927618fc4fa95e05ecf9aba1546619eaeaca7b5815cc07e97ae8cd1e9973ac603f84d838393 8436a25de27d32cfa563abd5f9e2d731d68a1474aad48ee0d65d069b27b967ffd0795f7e7814cbf0f33a05e2378427c919b7d20c96fe2407b84bdc1d5326fc48ce339bb6ee3495b5ea71935950b604d8b7c89137bca7de4ed83bf2f9b6b0d575 +70e11efc78d7f079ae41ac3c31c96d3220f4abfe23814a2a4a78d9b1a25e838c3408bd416062e4b0a5cdadf0c6e16a11e00f59711b417751f5e4b43ecad99efbdb2a81c91a034e89edc94eb552c3eba62808563cdf64453a1db07daff8742aea4a9fa738e1322da316b26dbca2954b2bc0de6da7518d28e6677dec6ba8af4285 0004212b7fd913d794fc6bb33e0276e349c052c969ecbf6afc89b28f75a599a9242acf74dec9f374361ba296ba42a38407f9b7d6 a5d1f1cc0b2f5d5835c1c35f56c95321daf3d226d50767c08dd96d167686717ae8692ed7d3b4005ffb55e389ef8834b10c1dd33d049fffa9258400d6df519e70610e6150462fcf5d5771bfbf9c16fa21185ace531f316eee16de45652932e114 +d922fa515e3bed60b517a2d37cafe4c041e5ab4b5c8d8d4011bf9fc4013dd8abf7add71fcfde5e71d6abe76bd0f749e960cbed55711c87b5629a2c39cff48ed7d0feaf5cc4765e576a4959521f9a45fcba0dc65ae618826447e02ce6e1cab5ce8d6c96c3211adbb0660de7df7453f3aa726016941d00d8ee536cc106a603d126 006baeebb5ffc89c94c3e8b37b9b0904e7c4b251d204894655bf3b1235710215c29820b9d401c9ca7df1404d2d62d708aafe208a ac0505c83cb2df3ba6d42277f51ab103c41f3628164db6b1ebcdbabb89103dc33c675f06a18d11c08859fd703781f5390463aa32ffbaae1628370904ecc807d1ffef3e3e5b56496b34b6bf489d53918eaa1e446ad0582b3cc2197ec30bcab911 +4f64d0f6bfc542a0d4347576935bd68ca88524ead03b8d2c494061d0658e6c3e14576b5bcea5f2f992f54cfb52b5c7cf1dfc517205e0454510eef1b7054a8cd06ab53ed2468193f98ff0dd62faf076549ab2a270f259276d5729996c120792c6f466a74ab65035bf38ff2c055b43e2a8b8e2449a2375ddbfc18242157bd905f8 0008e5f66ba53e7caad1feda122a80c32c82d2c32a7237b8ee8ead44ea8f2f01d77c7056b9dd60b92d051f060da8532c1fd0e8f4 a236d24532b13cf52e151067565e128c46869b25a6eea41ca3630e8f0bfd0b61bf6d21906baf6ee46b2e7342782e78c80a93d6dc3de7a841842bbb353f61b2756a8928895298e0d7e58093926ae0bbdce5a52675e12cf5b8eff55c67a77cc098 +7047d478ec5282d55db8c19c97af10951982d908c759ff590f27d57e2664f08d526cbb2bfde39bdbb1aa3dca5a8d3feb50b868be6651f197abccc9d8040b623de367e2ea1d20ecd302afb9e273f4be9f3f64f2c2eb3f92d5e0e375db6549da2a589f0604bc7146562ccefd15995a7c4208f640e7a17afbca69cda4e173380523 004ecb22b44e809f89b16abb10be062c89b41ee34e110403e42a20ce59a99afdc22f6f6dda56e1d9d1b8ce1d057f390db111def3 960a148809ccfd640b0a2b1caf36f4e8969afc8d1f35f21871d119843cd39d5f3c022ab0685035b247991446d08d1e8f117ffc6c15313ff1cdff230e95829145458e49b6abff607fabe2101aa8fbf781406f9089562091e58a6d1248e6cf3d40 +1a8384b4771a410663e56eb36c5d9ede8d161a8fb0e31d3f74bcb017b9e31232bb2e2f4c65a2d85bcd1cedd93ef08d4bb4af0095731574ab3f2762788a1ba3bf0ee46684da8d9dd384432fee99ed3c69213d790a5d81b351063eaf2bda71ca4868ac36be1b571024a8bf09039b347fa996d5d161078314e24b7d073e05cb3d48 0051f9500c15ae73d6d479b9f3d2caccc2039d8d03820befc2aae3bbaf65d59bd9cb3c4e3aa8bed5b3acb70a5566047ffad80729 a5e8798d9693d5062b0ce539b9d2effe29eadf8e9f4678c3e5031d9666d7b576cb3af81ac2a2fae251b93f90b0537adc14fbc25ecb869cf6b6fd4880b094426ea22f99b8c7d31872f15702efa444df57a9bfbdd9c3f4eb7ee68f6ced6fc8b924 +43513d6dd8bb0af7a6f5a2b35f99957d335a48d54f2c4019ce9518b35441d4935518976ab1df37110b5b53532cd9e2c66d9f87ae7f683d7efdbe1775a6c15eecee84c6f879999d0706f6779dc158c111fe8d7201983883bc8334f51dec60004eb1087347bfdab20f8f2f260556681e05fdbb8a6139857fd3bb2df5bc1f2dc143 000cf01dc4462cca764f4f8cbef48c51980737b9b98d1384b8de9f4c733829db7718a9b5eaa46a8475c2144fe4454cb8eeb0a443 a8447d58df79de1de7d533666bb53baab0676ff5c407b69d36fbfe8eb95ff3382482be0e06ef42f3a41436a0030bca5e07256d546f7afa2de6bb7c930d887c5339140b3298a126fe5740dbc3f84a6cef4eba12f5b5815094d26d2e382ee0de15 +752300bc5066d0efaf807183a41725e349907b7339d77c79921ead3c685b616b0eb97e708f3880fce0136c510c8cb53b22cb424af6f1c34633600939a0647c02d8f9601f9416f1d24a51657241fb559c25dfba91402cea43bca1a13718b3945b048725f3df560e6717cfc6ebd894e29bff1e0c7763f15b8ea93e67385f059598 0063a9a565497974c6dd459bea0d1196d74f263f333c31b7e8591499960e1cd79e2ef4cc8709f6d54713f873b16e7b0be42f71c8 8437cd6425fca518cc9a772a15db9bff9365051d2495bcfffd936df3df9be3a0f9a4e761b7e6d60bac7fc156db1d24e619c80bcc9b8380fcf649b2623f0b17fe28aef04b8f3601f022a4c340a53c2acb048c9c4825119e1ef9996f17789ff58f +f620603489944769c02e2f902c2299dd5f32b5fb463c841b7e1fc0249a85d2c31684bd3daacd97de8291c5d39e84d6e59d3dde1b30c181bfe8d31b8d8e080bd191690a67fa00024ac8c1b10981b40d4f88789ecc58fc69b15417fff34834e23453bb9933a43d08afab74d056f366b40ad167b51ee5f008db151a12b467d3eaa2 0041074dc186193d30aac7cc6d269b938ab40b257d095e54ba79967a377a91b8f73671470cd07f0a3d1db7cf0a31ba9070625e43 b9e0c2b390841f41ef830fe0bded46ddc89f0194f86c3387dbdee0151524ee07fd4024a605ea0f6c75400cd739e4fbd910b20ab82a3e9c97346ca2dc67de10c0be0ee1aa976d70dfb9db432635dbe8e8ce065b75e146469fcd8e1cdc99192980 +5575f610762b42ce4e98d7bcf45a7a6a0d66ec7f27d6b8b17f1961249d905bc7e58e2ce0806d467f106b16285dce4544c72666d08b5e2276cd0c4e13187cbda8aecf57b1855afedf8fad39ee4fe009f204e60bdbec79b123456ec2d85631d382b8a2f2c7634af3992e4707f7b4215e2c9d3b0aa8fb08267953883a4213669d33 0010820db54ccf0226161aeaee79cfd2797f87702b4ee91adf8543b3c9e79579d0df8a889e366ec1e0718e039b87a37c24d620e9 82b45ac1e0b96c8aa3c4850f5defc6e1588cf2b12e343212ea65b6d772847224c34c73e242f58ceb8cb437e95731c9b60e7357e3c4db6a1ce9ecd7f09a600769ef040dddd246cd63695f0367f8f83a0833104d0647def629219f24d19d153908 +81cf067411dde2d0ab04fe5fa1e28e6975cdcc571588de60a35bd956a535fbbda4affd0803d244f3f7e6902a2c9a7ef2488691b6bef7f8ffb33be09ccae4c5285265e4957f7928ea5cbabd6823297f59a7cfc9939a49f26bde74c4c69e2d38c1efbacbcfdef011213843158072be84ed3c1781f67a0e2d4e9ba76a585c17fc0a 0059d2a06e8bfd5e14a9bc8777958b85be5e97af892d2cdeb0ecbd2d5017952b5042349db5fedba2e26e7b85bbb31ad313d99434 a9f9b420addda760785f21ebba70029a2516b94406da571e5cd97cf9d1c1c87957db36d685602edab795d66e5b1e707a1311ce38343c8b4eb0454a6e100725ef73ae96e154f22125e9ab3d1c7e8125bc9fbfd54360e6d270b2179c960f490b89 +8ea18387940035cff2f37278d321b344231075db43c7fa7fee9bd3fdefe5e8f03e7af9deafa1022eb108e19ec11fae34536a4fbac2e8c8139a081a997c080cbe8f3e2d2a72ff26edcc5338b21372fa1498e439e4d9bb12d51cc539f859047957b1b1f1fc30b90231eb06b365a4d404a1fd5a0e5cef171fc95b04d0b557d78ebf 00405590893cbbe18f4ad99df28b5f9d17f8f1882269aff0b7eee9392859d68927a99c942a3075269ddec6d69c0df2d76ab9d801 93f9dc9481e99b63738ded9d76c31c9ac840965a092ac5526aa63fe2042b4f4b6227646b7dd5e97341edf0bcd29adbcf10b4ca3408e8c4ed04b5f521e8fb750427aa558f928500248534abe1d2eedbf29106af6e8269402c51de712bc3152271 +6a253c1aa17b2b1e6624afc8e7456d366ef5b1bd78e740538260f395481148a64da0b6a58cd53d7e06c691beae1a616547cd95c4d259a371e51c2c0e334c8a5311ae31e4c7af325686ff9f7a36f731010ee1a9b8a29169ceac36a060dd23611dc9713c615424888bb574ad5f5755d7311bd169336ae986c977a394bf16487c4e 0062bbb4f565aa0f23b88ab9029d33b995729d10fcfc33ba7c4051e2fbc72f15636a834e3ebfe604b927cdfc89f53c57f36890db 82fde0637794c78f7df6f7b65fb17e0fd671deddd471fb13a68ed7964fe9afd8c241abc40828456c12e0c15bd94c47f50407be275accd954cabcf9cc04c0976214ff517834bf7cc5dd44759ba5c0d5fca7aed8b0ae6bde7f27e1f91db5a472c4 +0f91d0f0139faf3b90a3d4bebd7e96ff6bb6f90f6c68321fb392637d8ab2a60d649a7b7364ee6e4e274e1a8d342caee36cc11c56c54247fb0a8e8ef81ac4322b454dc9a195dc54567bf47ec8d4fa4cd32e76d78ea2d08bcbce3edbb68fd8597e56d5a9f2df4e47b2701046df89615961db601bd8204584a6a6cfbb627e2a1190 003fad7031cf8810544a3e4bd1382c0a2e22c5a9fe4804ce67b27591fc516ee81dbac841d399327168aa6abd79e2b5ef85df1528 863b19495564c47d2df6bb31fec91deaf587ac7c273011fc2725f704b27745cea9aa664f6321d0475547c4a0569d635619424ba18b5eceec25f88fccd0b7344f21be42af122387723a628028bde31c7e011b174ebc622d3e7aca8c3e5e218837 +50c17c1fe4dc84648e5c3c3ab8f7c971d4c58d8d56d2b5ddd92e35e6792111ed8dac7644ac8a07ca8bb4e38e071aa47b22ffe495e9083f9bf781ac1b5fba571862c909c7aaa7b8d05ddfb7ef61c99700de734d5658f44ae9fc908c85a2dac8e7f854d6d24be805fcd7f873a91252985c5c73129c60177ba8fd99daa87b25a073 003db41b4f637fe7977c90e4f1a21799baaddd1826c667102414877138436cfae1b9959842b8097b5276f15f2b982ee59df263c8 968ddb7ab962af00673940e880e7c61573b5c9d71fe7fa0543aef89724c833d9fa7d7c812ccc69a745bdfb2ab479e76819dbeaf04a96d0128d6e2225c7edfdae5318989f2cd55a542acdc158627f44a715dcdadc43ff2ad623a812e9d5f8896b +3583a3226e2dc463a462fefa97024e6e969c1b13bdc1d228e2d7823d9f7c09012390c2535baf086588000e908309090daac6e6d2b06d2ede6fae838ed47f30b5b481185f607a3586f6dea47c8f84e9d3b96d5b0ebae2462fde1e49d84d36658e87dccf5e30c0937feefd8862dcdb1a1ca373f6ae41641502ac54df6633a8cec1 0065b76c6093d9c49591293471286df1a4444e60d9d06cfa114e175afb5f119d2abeb273b0596019a0ec5db5b5869f2cc827b364 8efc8cf3e763fdba7159ef25b690067e1780d4cb698fdf3d864dd05b134ed1a439bd6b3ceb0ac68ae7471d1c90162a9e033722eddf8ceec9b3300d4a763bd55f85fc637992b1b04506d9de06f5b47f40af471f7a8956e421fc4b222cf5230058 +60ca58462d53d074b370127132f4e59f5eb8d15594dc721a94286afd082a8934e52462c9c1c3910f8b50d7aa3671dafa5972958d876d7992467b2fee3795a6f9d8a7bd3003a8582ea8c003aa1e02c08ab6804d85bcfa13a815d75c938671f0af0706c68bc70a6155708ca755cac2fbb68b2952208d63e0e2e3d816f04c61bc03 007e9993f3fc1fdc4c376ef77ecded96006ac1159740bd1b2dc6ae3d97e15a67383f1fc931e460b9af3fe14a54e47919667ed06c a52b5c246551ddad401a834926923fd1938ac670e5babe4756aba6e60e4443c35255662f3db7956461f03ab167d9626d1347e1e5f18704046a2a38280a96f591dc45411d1834656f4750f6382e58fc3bfcd823ca708ca96f46ed0ad4ed9b9109 +c749f9bb92ca9957ca6d0124206ebf65e860ff38a225e241950bf4526cef3f4fa9184ec83f71f813fe852dc08eca6b45b14fc7f2c6a19296529bfda007efe9d0d26492de2a902b45ed39603e22f0a763dfa5deadd97ef6feb859d860baa2cfd1d066c0be0f9f4e0e2fafa69cc51b12e814ad2e33b0acc0bcbe1df8cf018dcd4f 000c11e2979498695c660a2bdfd105b115bc4ff8664ea15cfb40c725406c6fc9a13027bd1d72ffff6258f29e4e19b845243444a7 8f330365c098601e0ce4b6b5be40c428daca2260f65b585ceea9abd86a0ae6a87a8f18866487e5e8fe279e971cb0f526020e64b2d15451bd3655f40f3578a96f9982d5372269665cc5d7190727d75b9df0fb26a7527c18d8dd973c586ef564f7 +4de8414780ea20f7943b1f1adae5e3962d96e828fee43bdbf2831bd71bd25df2976a3be37a7a667c7fbe1200de578920090d131a750c9bc09bd95b261234ea8cc25423c4ddfff5656d6b32da6e2f6f530e6673a8660aeca31273bb9a3a21bbd7031a2fa71ba37c004d3d1c64b2c0798783e47b2efe1a208959ac16e35d444245 0068dfc23c6635bd1fa1076dcbd456ad6e8df7ce7c1370fe275803befc4ffad007fd062a61cf1d50b93aeb9afe1aab47a65af82a 8406f2bb535d0ef48cd98d7dbc57f35a9b82ea240c10d02e518eb9255abe4be8b0bbb5a29ea5cac231a8ccc0af9e0def0ac08efd1051581c3867f7c9b46aa51da9b0aa8e9c2899900765b61025d066a65e617527f119249666e54dfa76e15399 +a081d54232f84bb19dbd52ec3812748e2e6486f6cf1b177b27929504ca878036547eb43531bb5b3edc81bfe105370427e92831d2239cca0106d031d9fa8da9cf89c6fb6401377d5936b6329ccad854e5567181b8f16a37c35f333eaa0ffe91d727d183fbab935fdac2d5670dafb3fba59e4fa2df1746c58dd8360fa08af7f4e6 0040807fb888e1d9fd33604546656a493629d94d4a0a9de2608962225ed158167f9e2438abe2d12a11e2adb6c2b66ed78215b0b1 866a24a5b7049391ed1cd0d3ad37a96a161fce8ef44cb6c04545be83d675fd59dbc72003879305dd364fe07d573283c31688f3c1d0d0ff589a4f78a037b8da3ec560be0891c9e315e0b61209ecd3a8f28c64ba65f5f4a2fbd588d64ae4557996 +ea60266f1538565b3ff42fa4bbfe319be070329059c52c8bc04a7da2824f209c1145a05e551ea59ded8ca8439c328f6907da4e81d658937df614be98c7b8648818ea80ef40e49aaa4431f4a211d62acf2611f5d60c446b2b25745078c643859be1b12b3141a09ab765dd63ea1f2a2df015eca0840087a5db378c4c4cce76cba7 0033bda0a02badae08fe40c239b9d59e5bfe1c4d4b9b7a5acda6790bfd77ad08dde5e93a2da80ec54a7f88146d72218bbb88aa10 a3e7d85bc37373282e0b003156c7ee1b397b45d402e14806c627842e9c783c05e8cc0a6de6700887b7aa5b9aa757269e10d6baaf28a540654f52953040859d4679ca276fb60a0747765eab230cb2fdf760e1eefc3ee593be2ba9b2d9d2a84cc8 +82f38c9405ef0d26bcdd5b3fce4fb0060c3095f61403418e17c337933f0563c03691fabd32ab5e896c593439e7492a9970ae325c67196d9e83fe0f9780409a930326f7e6efae035ef8c321cb9ad12461edd5cde66c04739fe079db65406b3c2d22f2d04b1a4335285513d4ceb901d2ca2ad10c508302266c2cd6079ff14eff4b 004ff431769d26b8837d3e1295f5464fe82be29edefba76323e92078a6483ea0daa96221549102509a1bdcfd46a5a2e5de10c39f aa7dd6021793344ac8d451d052627f16eeed6036d8d1434b5319a2b5df0b493104d20a6ac7719e187df73439bb7dbbc806eb2db9622c6af9e6d9f1d588378194c6534556337eb488c650e7dad2d961a5ee86bdcb91996feacc1ed247ad0a51a6 +d8506fab4f681ba4ae86066aed447571eba4fe04e6585fe3be6af2ab1000a3da68c5b0c711a85ddf3a40cb7c8944eef81f2094650459e14f5b848e6add7e580b0198070f873eb3ed5d0728eabd92bc1398764b94cbb4cdd7cc2027b9762dd10782658cd9e8a5022ac062fec535d892198c8a387b3d2b6f7c92b1af6ab7dd9e4a 003f85ca1169ca7e9df44cbc6bc7d2868c9d94e8f8b699a42ca492dca0914eb5789a9032218dcef7f95f959c9554a1cd83360439 892bbdc3182c8f6488f3f32f145150e5afff288e0a33c1c3db0a5b0bb134a2f4c2a54c096e3d930b5a4eb16a64a64224069a1ca0a7cd251ef0af11d08ca604f1b82c214cc863fe5bafbbf48f293e623389b4efe8ad17279b7309ff9619222d1f +b3f30d34f252a4c26f396079e773142bf61c0981d912333ade3de4e27cbc72cd8a16b31807f0c46116f87accb854487d83ec8c6a61565e6fca145eab70048245db08616779d7047db63aabd90dd15acbb05eaa510072c151c0518f1b34582b95f43ec7b9484b2993c176de79e84566764467f72392ef31619426d159c91816d4 003a97deb36d68f81f50c8829d412ee5de7f9d775633cb69c09dac558182039e275fc258240517a7c4aa592e364765321f27cb12 b572c0df6abbfe29e99c2c5fd554bc97875b1667e6648c96d3ae0ae84c430b2e34d9542d4f093505e108d4ed6f963dea0e9fa978ae314d436663d88095938a0d00a8652efee5047e82a61ab2e9513dfeff81b7a84a59df9b8cf8ffc275372152 +0fb13b7c09467ad203852738eda5ddd25b17d330e82c279630b0e1f0c86681f67f6e537fb00da9419114973c8559306de58b0387d86e52d821d982a60769d2f15fd5ac2ee6dc55d8ac04ee247282cb2866b8cb8b4d7b4b6cfb33bfefdff09a73d727193e5fb939ff66ac5fcb644a44f9083a790888cc538c5eb435243c6a34a8 003b1da0ffed24e1a3b5ba22bd684337f6b08053591620541bdad50c761d66201a2cf21a4cc636426456525b598e96baf97d9851 8fd77c8902a0e70a11fed09478c5373c12855c637b6f57697b9681b3605fdf67cf13cea49638d015991bc6ba019b798b07110ae485f11723212e7bd2af1700fcdd5156e0e3e7005f9bbd2ec4b8e3b765025e0f841afc29bfe1ca3cb69e26561d +f9b8124281628cf4e1da0cb4f021c8d19d815644cd80c7c8de4cc62722904ec4cddd26cc4891f30b15098a25ba6923c6abf4774deb6e1883fbb409862f94467e75a725e7154be860fd58347577c83adbf18535c54b102220197afa062cc1c84f6094490ce488af4a08d2c5b808a2572e18a59de96c87162f88413795351cedc1 0040bac7e0d3b54c7753c79d43469e310d876015d948fac4e3a9765444754476af72330e88d79ee6119697aafac8435ab5690754 b63d784e1aedff03b14f85aa658ec031e3cf403bccfdb902c072ffe7a1061918cf4d5657f213e65ebb2544a946315ec40d3a3413f40a14badf49172b603beffbfb0cd7ddeb183e65227ed70e4f8faf078a2017fc6ddbd56e4fae2da0c7df6f04 +4e3cd6100520db050af0daa69fe3cfe6603a223d4f2a6318fc5836db8640d4c7fb80bb781302036d2d6fb8e552b4eaef3133b98ba2d36b9ef0b86243b0391413c73d48ecbf1d19170f1b3b781b35ffd316afb1d55d1dda8e91eed5553780cb2714a93e7ece698b832e853e2589c5ba2b8a997bbbbf625071ded66762af8cad42 0025b7eb3bdefba3c5134438caf968f615b315204f348006f82e8d61057a8a8a853230cf0500f9d0b8c1551a59b9184862dd2ed9 8a73bf45184605c615fd7e8c49afdafab0cf643cb9fc672ce410f4caed1b82c60085ff0902bc001d1df81012e23c322f11456eb3dab5a2f75753cdc58b02ee4467e35fc02df563266b8442c9d94e348665c9ad48026ed46884f2e1b1abd4cf18 +5411708381a65bef4381c9e13a04cdd5ba0c15829f7f25ccadf695f635384d8e4704cb562741747831b33852567f42fedbd190d2980f1bc921ce01c17d659d4bdd7eb787b3927fcee659dd3b65132496c687f2249272a473d46326e66b3cb78dafbb522390162c168f73bdec88adb145e6afecd561979846ea4c8cee38dc1686 00673b3a2985c95904732632e5d988d8d437a60db13215bb6aa880b348f011c609a1e860461427a8cf0d622abc47f910f5c97ffa a5aa996458bbe6586f4d4ff8a428218058643fa18dc766791b1207802478b15a1faabce01c123d7a728abff70e4fdf9612347d22ee30d604d032eee2d1c686b9843d69b5e5a8dea34434d8efd70d67f9732081f16190231b7812d7dff5675138 +23757fa60fcabf543e603d8b31ef0cc99b3ed16b4816a84e01dbfc858872fcb79fd03d2f8a1d4f28c25dc42a39e20c34f81ebccda1682ee9bd22fe323e7f8ea90cf4a2a6ebb634cd1153cdc35f7306f28a2efd822bf23131baa1543d0ed5ab4c8168d3199983fbee117085f90550ec3ffa2b06070d3add1d707fc2593285ff58 000db7dcac414010b816236cad584dabeaec1da76c97182d1b62f87bb7fe2946a64d10430571b2b29ccf2ef72c969a9f045f1f3b 8bb80ef216da755bdf182413506c7f5a8b24d381f6b7048ec07391c317280507817310a0c484cb2c5b521da379dcb5e317a23b077f8f3805c6923115533b15279532511fba33dce8dad6e10c060b7e458b7516cb3701acc36370a10d201bfbb3 +b976314d2f066f8893307a726f450dcf2cf865c170e90e6908ce9787eec48e1e2119a731b2bec3c12fd4e6282a393774251bcaef91af6ce57c63a8b45bedd72ab862cd169b7c84b8f6a72084ff823a96f2f8eff3483a7ebfabdabf0998377c5a6836d88135cf61c65a0ca7ca57727da68047dc635c17ad13731035fe9a6402af 004717efef16e1ae267e155aa1daabafc68515aa391dfeb73c13d01f3132bd22c984228dddc4dff4c39979e7585acd3f730cfcfa 9343877ac35a19f5a40431a9425dfa8e7b78099f8cf4d9b6a53f28349027d8a1efccbcfa555ceae1bbc7cc05380ee1b012067c06f3c8bb95d058fb8ed81ee71fee9797f16f53404546e8a421b414b313b101d82e730e778ff787e66292e56143 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K409_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K409_blst new file mode 100644 index 000000000000..fb5af69b9876 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K409_blst @@ -0,0 +1,60 @@ +f153cc61981a46d8a47d17d29ec157fa93fcf644beb84558db7c99c57fb131dcbc5b65581ced5ff0b29bfdc66ff703ecdd4290f7c353c02a3e6d6867f33f3dccd1a0b6752b8a35fa143f8921a5078af9c85b212564c5b795da9858c7955095938fcd10c21e35e1abe905e84c8b4bc05f2a06091ce876d9519b96951d08c7ac9e 0011c6528939672bed3e8c905b7ba594c3ce95f37fb28044f210cccd01dfdb42c10e8e1a0b5d6fc757834ca7f08e98cbc52b0edd a42515b776e87c7e58a5092d2495f9efa923fc9523fcedd4410192b8e28aecdf04238ad5d675dc2a752390d96207d4821622329068cdb0f593308026320baee4e28e8e98046bdbb70d1d8298c3b17155576d661577d0be8527826ae99e6de7e6 +258c91524423b5c876432b1930c7b07b56eb5e3945f1e2296a4e5bfb9b9123f800ad195d6104641b1f1970bca553c2032f83d17252e52403a9381c1fc18eaffdf026f7537aa27d84c5e3d6e39e651a92a41139cec5181fe794457f556b390943093be719acd23fa1ddf7ff0aaf0479484a381a309b4f681af74bf97caef08c22 007e3b714496dd118d8f3f597961eec5c43d0265bf85723b0b9b0616977e0acc2cf686cb6afa6cdc19114e27ab000e762dfe467b b735714878d0dd158c9e0020f7c451f45513f561cbe21dd651211005cf78f84aae13973fe1407b2d49f03723744b6ff801194fc58d95d2aa19a96653b2a77fd031b227dadf3b51066886db7fddda534dd6c36e5c930fee933fe6655a439ef872 +a16a0d6fd57240fe88c7c36b9f7f9040cfcaa9afc4beeb8300818c5f90cce73b819a12c31d42af33146399cdfa4ed4954d068dbb0f1f342269dd29f1fe357e7224304b67b0f924b794780fe7e6aa9dfa3380252fe7177b43e7b1789718949b9ec1b943c83ed4399491482f0f59d2cb8050ab6f8b5854d76c50651428cd29c40a 00182d1e937b037bf7f84144f7d4c94c935269c9aae7d500aa459a7a0ec113b232dcf282908eee4c84b8106cd38cdc41db3f89e1 b5ad21b56138ab178d7ce6cdefcf16c1984c3ee3829dd8a67125359e6052fbc82d1dab12571a1f08fbf0a2b4fb4735380437395cc33ef29416d600933766d3a8d6e90e8f2896febeb42ebeb3d977e1c349463f8ea4429a72143b87e51a6a4204 +d02ff569828fd1add21f6bd1c50cbdcd09222e458ee79fd5dfdba3cbb84e9d926fcf196cccedece77d5aa17f8c8cbf3a9facf0f02c71d5c1c8aeda9d75f6fd7b6f2c5c70dff992ef6e02c438fb3c66da5a503b3c39acbe2a069da457595b542190d818015d462670b0807c401e36b1bfe05baff3a8ccf8d1f5f8de7840e87993 007ed09428f460724c8a5225a31151e031d9949493fff5703369c401762345d002c4ce424294baab22d9e71edc4f854510cf0e6a 911633fb92f23c2dce3ec312a33d8fe0c3b07adb490238dd6dc93372ce6a4e2ab4df5ed94a897f007bd6eb153c76ed4a0c33a6d3f125bed065c6e0a4f4e457f044a713b2a9c160d8941d0b4cbc80355de38ae7808ddbca4694c4660d8973186c +57befce973b225cfce7f996fa5a1a43acd160681b88a87b7de04544eb7b6a719718f1ca7f559b6531bfc18fca3836d2be7f7a6e48387b7579a6845796d30e46f0dda9d82680f8c96c5f0989741adef9762c3db763cae2699cb6c112543635e20ed5cfb4b55ca2ccb32d2d13936085a8ff95ed658a54be73f80c912ccfe5f0ca0 00390f05b9619c27b800e99aeaf61ef7f6249367d5cfaeae3c7b523a8b29153eb8a77132f6c4412545a842d6deb7b7aea7e2bda5 8057a3d90c29970f6914b23ad13726068e52af7cc362b471e111ec74455b656ebf5a315162205667ae55cf7f9ca9813a129c420f36aeedced08a6dbbb9e3cdc80e91a5d09229f61ec206d37f558933dee4f41fb57ad3afb7925406c877fca2ad +4277ba40cb462860ca722cb4ee71c61836d2ceba18bc91f3fad7dea478972c6da0ebc02815eaaada1d1a5e93d7ab353855ccfdfc94a5742fe18daee2328871e06c1ab0a9a989d1239df2d2d27f96c415e7ef9a941f06c6790675361173cc229aac7045f49eaca207f59c497619ba32e932b5c1c6576812ee5b146e2cc7de5e62 0007d18652732596add3db31f7a0ce6020d03f3df58131b0c7c633faf619b8210cd309d6c0c4083aef1a1b6d2a756adad0bfe344 8e76b3f9d13c4e19d6ee1a067a0df628ead57a3f6343c356dec415a793f627c1c1555289a5a8d94b9ebd4f147844ffa20e48873e014867f47272ce79a8a71fea026ea518b6aafaed3d1b06b12bf4e4f2d491806ae6f40e1809ff2bbfc49d35f6 +57ff6792ed4b12220d179bc0ea57ff217f322c85bd3676a681d32d7e4a3e0c8e891fd267df17caba5992f68c35ff670b60b4bbdfff82404f6ed996c30539bc395120f97d4d7a652eaee82bd8f9360bf8bb73748b8bbda9f9480eb54f7eaf2609d4259329e8a5ea020521e7dbd3ec56f23c849932cbdf2875f5d5c774a9d6b0c9 002a91244ea4623b63403dba807d60b914ca3b901a2523244c322f2f11251446d3f15e869d086ebecfa1a39ce304e8b5c8de23e2 906c947f1ab2e5e1725256c2dc6b4baf07c72956ab5ad0c42b79419ba4329baf4ace2316dcc46de94ea295559c6c0abe051728a276940515c716bf4853fe9704f0fab1a302f4b07c5625110ec793d61bcf62b455e24efe170d7180c1f48ee587 +f85113eda64478f460b60f8084220134933de049200a5f37884da7901471542e26690a5fabc3cbf9e679ade71b6e54d869bc136c3d34cc4a9efcafb777abf046b5ae5429136112a9a36a475121eb1f33f1f43481286fc1ada98a41064a1fa38c89e99a93065bb2a119348a9e452497fd5a0d2b83a66b09da9f47a0583732adf4 00068c56c6b5d50d1d4e13d3837d8c5e8ba2f825e121b63e97603fdfe78bb6899600ff0dc87b6b3b6868ad0d2f62b7b7a31603ff b3d3b2649e399115d5c5f0660edd65c106c9a6a7546730231f11bd338ecdec1b670666e4523ea4c39372a47648dc2c9b1203a2df80e06aeede0541013a7c9ce34559cb64bc2d41cd5f0211df7a873179afa9cbd3a0953db417d24befcbf19665 +42811e9ee6dc509572e1cddbe5baf00afeb0c5c13e3755b922eee9e210001676082bc9edc3d78db2b5bebea7a2c0cd2b369226c2b8f83b28f33fb513407ab9d287d14b112d6c3be2493805ace5cf6fd366d03cfb28f4ce3f0f060880db64d6962e997463ba7c05b6fcd1e66babe4b94afc5c2d38c7050c69571d27b66ef0090b 003c88084f8b78446db431bd6e240a0c050813d2a763675b0ea869cbe183df697146cf29c03479af3d34587a95cd257027fbeed8 b1b40656618f31ba013bcae68d49f0e3569582212207f8a2b17516a0a35f9911859298d32d6b352e867329187b1b818e07cf96e92c268de17829ffbd2ed12c8d998044fe1a323021dd59018bff42cfba1001f4d17c541ff85010eaddc29b0476 +b38f76ede7441ae0887e689d556f43155b38dab7cde487ce9ef9a46f2957c830d4d28006873fe2368197a6931f6fcaad755102686a457a7edccc8d344e2d2a9162e3d71d41c09a022539ae6d404955a6ad748231aee1f974d4f159940532fb3b1fa0254bfc5805d2fc68696856fadea386c542d3cefd1be3af04ca595e54be25 0051af7b63bf3297ae20517faaa1552f4fde65819dbbff6a52721611e5b7dc1242ed6e69768cdc37ea8cdfd1a5971f06b84b5803 b90a44bd306794bbebc7adfe73a4629b86a518f8ec31f35246d61569a57ee0bb3e7f5156650e28ab8361bb781acccb21007d772a5b135b9ffffafa9039dd10a0de3e85cb5bdc8a3070ed84aa200f2b6aa8dc816b9fdf4badeda8e82695a57592 +356dc86cef7979148e995fc5abe2b14a7d5e4e42c9b3509b4363bb80c581a66f4e7e4aa53a4bfd37f9a7eccf75fdd726f348f6a3f779e6599f61bd1d668517f40453b39bcf35db0852a6a6218198f52b7ceda2ec55fca5abe8e5d93af9a42b9ae4de9530c5870211bacc27c39aa094013db703de2fd3121f08d7e97dbd4e8946 003d65bdec48972d03811b78150a06956eb22d337dbec5416bbd8185a6322cd8c0ff8000210dbd1326422289071cab65175f5d10 87c485c0f33cbde8582b5abef0db32215a33300427ee2ddd8b265f45b50c61d498cd4813c98f45d3ede64db2d6c6413d15e3ea4f485f0ba58c3fcaee808947a91d6627ee683e48eaf1c87b37397f99d0df4a6be73221508d025f0fb3ee463977 +06fd39a50bf25e89f1071ff81fec5d1e35b6dd68990414ee403dfdebb792627b6a4ae3d2236c159e4441ff90b61ec87b1592c538515f0486b19e58583394a05e6411e69b4285d6d6589982ac0eeb2c912c4948789cad741183663fc070943389d4e9a1150b8f6088fc50605915e9e24b2d98a1f539024770e4820e14ae42ea8e 001f1a8b5f35dbbf82c102df550c72216a243f986f0325920f6186a16d1da74228cc02be6024c7411160c183c923c743354f9438 917e87b5f511d97e100f20462abed71ff1b3d42b7b2a4971ad336c671af17c74272c577e17189d4a45d82480e75b87020e68534ad0c0260a5fd9aaec6e13944fcb3cf42a23ebe83eb62f8c359af4045dfe31b534f6f8c567076efa0efe3cac25 +6daaa41150ea252a3e966a338377307d909b95080e006f13027f2be5059d9208930c5a329994c0b794ef50eb059bc6c215f68cf42260bd410f9bd86d2ad5ab7179c7c92de4a93a5f6aa17de5aefea815e7c0b78a8cc53c21dc4dee037b29c9df4e12343109283ffd5d8a3b81fba1b5e95506c7e01ac056c86dd0ee23bc21af0a 0031dc621200cd174193d95e9092ffb86189c52cdbb9ed937593f2cde7c4a0264b9100e1b8407336c8dfb5520d28a18dc4e39a89 acf670a5260cd33ce969a95a5e1d0732c604756e2780528739660264a8737f1d685510ffb80dbb8c151ad5808184c7051624be609efa47abdfab4d3e1d0d6b340abc82cd75429790b9fe42743752c94febe58542f6cf8a349c7e9e82eb33a28c +6378dd1c12c5197b57d47dc46a67949bdd1e0809004e94d49b0234126a08ad5bf8723ebfd132145813136d8b7dd096f56c34248f09a65c34f60c2f80f9a51b3795f3d2518b11aaeaf6dd45a323794080b78f85d629e5fa719b6ab0b14c78cd908befeaef0dbfaa08cec9318bbcb376d48b11b68735c9554a45293db5e9239ae1 0016e6750245a88340b0f0665b890459f8038e9b1366f2fc1326245a88d4c523ec94429f21869ce3dbf75126e58f77241c99efaa b9817504b1cad945d837f22d2744751f2efc3e40add69c248515683da5dc17acee1ae5311cbad22285f93b4aa35666310cd9f8782dad123c3ae23d83675e27d9e9795d64c70eff1d8f61bfb220c7fc220516c4e9e5fc291f53c8fe324b02d239 +b898d0f9bd80e083fa541f457d14d853bba55b120424a95e1d9511c8833f48444329e0349d68204c4b4581ef1c4dee23ed0a4445727a72e1e6cde422f7c10ae132a3fe681f9d741fda263e73f7cdf10759467c9d76164086abf6780ad474772771eee22d195339bb8f6235e0d992bbe282b13ce4fe01417f507a2c4fa155e108 00788fabdafeebb72f6385301e30024b56639e629a400f9c50d402cfc9b5817844f06a451fbda29c7ece41dc9ffcfc625fe0ff0a aad12d2d0ba33bc83983120b13f80d003eda37605e5a6eefaccaf3fe8bbd5ae281ee29c2eefa3db2e1a1f3cd7138cdcc1281cce2798d63d0e470718576059295ee86b2ba207b3d813ba4789d78b7c663d1c5c818b2e7d6a7199987d4a4bebfa9 +dbe04561ea8579672a2b3afa94426a3cbc274b55263989d41a778bcb082da797d84d930ca847a481789524940701cd5f1d11b460bdac0bffb0b3a3abe1ab689c519700de85a0a571494ba0cfc3c865450eba7a9e916b7fa9df55e8a1c246c992e6a0b44b78274e008472bed8d8411633e6520e1a906c5d0c8aafd572fe6f1f64 001b8dfd64563dc219d6eeb53f2e3ad1d771140d0960b211dc1f757af5e297dc7548d6133ddb574711d466688f80dbd65a7bbcdc b989954bfef5fd9f946558b82ffbfe1e1bb2a05c944b71e09aac41de915e4b13994ea5a856e7a1a02547a7b38b3e49340198188c7ebeb7df513464db5caac60ec304f839d5ff367625355e1ceda8f46bc90ead85f0f0a654a854d72eabaf223a +48a8300820fea2ad83c83f7d6b24192715329c3f159d56644e11ed25efcbd3d31600a813b909812987b97d1087e74a63b4494cc031c63492b6615e9d6e5b36f62cb2ef88b9f736595800de465789f43811165a5fc093ee6d776008739de8de2a84e878748641be8bd52e5b891c4145f52bbd46644852a43108e93d86352b2a3c 00422131829608ff730c24ddf7e8b4a2600eaa9681eaf45432daa7d41fe2fb488fd0199d431a1ed823801ce21f4f01a4dd4248ca ac0f5d8a84500957b36f262936e3e67a15a4ca9435bcfb4681a2a6754003c639bb38db78b42b0182cc161c4bcabbdaae18fe138404c873a1f29ebbe076f4a6d70afa9ed0efce6997137422eaa80785410c64eb4b5a0ed7d73baf3a4c00e461f8 +276e3a986ce33256014aaa3e55cc1f4c75fe831746b342eadb017676b0cba7c353b3a2b554522c12e6aeaf1364cd2eb765a404b3d0aa61258194a30219d76d2bfa98ad20e7e91756cf65e50d7914157f283f2ba3930c0ad3a97532cc747b1cb9c806fff497f0322025a3d02ff407fc7b5808585b91d95523c9d5864efdf7d983 00095ae8e4c7e55eb5da01acc05ecfe72a4dcd8ec152f1c8dc165014f70eb4e4a7861aeb2b96c418b2d4db58659e76184e013a49 92d7022147dcb3e2be11fece144d0566d9054169866fc361909701be424cd5e6c55452e11a600f3fefacb11bb509e5dd04379fe6af8ccd94b8b45846897745910acd9fd747683d01d626034e7a49f2e9ded9e585e7f333d14a6abd6a117ad535 +6a4fc1827c3a7256faa8ec6a0f3d23559d6949f8cc20e7f76111dc4ebd59213951cbf0eadacaeb8862d6baa0cb298645e4314b1c303bd0d5e9893304d4b7fbd36ab05fb6a5edc3fef763e3a4124d61539eb616b359c5cb55b5e2bec50c91dd95fc39ddf521aa854216eb5a707819fa6f067b316a17a3b146e7cc2dd517f7d63f 0006f2075bd730f34df111ebda919167b1d3358ada32cd6747cb3353bcfb814a77ac70cd51b31a0e538539453bf9eaf9d8b384c9 97f05a4f40a8009e1c1211d2ae7ea867c000f0f76fd3340711f7d156ad6eb5271f7ac13b6b3ff92c27a88b32554f3fb4057dc57f6e4a8bac71ecd54c4e5eec410f5243f14a926c18d3acc5afb57ce9d26a18f37828cd962f9883651f22006f92 +4b088199bd8c94775d8ee508377d672dbf50f6d2c7370e99821ec8f9387492fb2eebdbea473ea18465565f79e2af418555f10c4a527e05a9e20c9c00b807dc8b350cd4ccc2d87e91f66addf02ce4f43597aa258ac6fbe9365cc2c8e8bbe5c884abc929710e8423cd6722a8f473bb55804159a92a3d8b6661a536b4fb9293bb0a 003887d284e9ad17d38bc6da9d83c192a434c509340a7f233cebb032b09ab7c4c6e8730b4a80844898616c9abcd16b753c6bb4c5 a20347c43eb9355ed1e8526e956d211140589de744d2d866d6e5218e426a1f455fd325ea0b1e9627e7988b5b5b908c060f4a025462220bd4e76089d2758936b8ed66c7b23b387d8da570e4c9365c26d84fae6a9a609bf2dbfdd065431cb1a381 +848a13465ddcfb2dc14f7bc0db0756832c22dde1e31e4d8b3ae0dd1aafbdf15e954889e95d3bdfd6e5ebb6171fad62592c23277a89e8ba53978c9b1afedfef7e1c3f6d9f31077530460b47834b30bbd84a4da601be988738aa815d3d7e72043243a5288751ee08b4815a017fb5d9bd55833698a0d526b1ed79da35ef0fac93da 002ea5430610864257c9dc393c3addcd0d8d5bc8aab1067643b08857210464428aa85cf1ae6c743fd2682255d4c8eaa46ca21e73 a652f139484626ff6a5308f8c028896466314e6531c9d7e08ef229afb7e8b2eb071a381ffcf151f4e164628a3c55757c0331a617e764aac7a0dd9170e0a8bd1a32a77b91d80937c0e7f7742c1057492287147d7e9387cdfed35c2bd358c2f622 +d1850545c04ea65528849973c220205c35eae98826d169348970d1420b4d872ce233af1daa9e62f6a562544ae3a0633a954a493e9766dd5d87e47486559fdf86229a7c9e1726de21895abdcf2422d438f4ad98d88b45c56742694ad5e11894253270997c049f0f419842482f21c792fbe5613e2defecd485585f1835b6f4c578 0062c757c92eaef41f5d81169ec4968145b5aa2bc1d2a3a5fd000634777748ecb93677b3da12e3be33272a8f0a52300f4a5a37c4 92a79dae5cb1eb2f4d89daadb08323b691a92ce656c357d70875fa925d814aa326a92791a10be676b4a1dcd2f3b0f55e1094e49101e04c1f83093ee0b6410c370e9ce1a497cdc5f7ba6555f685d85bf1d7e087783af3c931f81b48ddef87d76c +421c9784d6fd507c82904e1054edf9bdd1efb58a0b211340086069ad38b7b0dd15c2345fa8767ef71254ed1bd5c35f742b1d3f4765ff9007a5477ba9e5d3d5a5cb5fab4efc1cad73701d4776c6c4343f42b5d94a9eb78ae428dfe5fbdd8e6ece09d5b75cf4346cf27db856352225ab04e6ea56661554fbc39916accebecb3935 0048a313c0c11489939fc0cffc6ccb9f179093c4e13141b92dbbaac441b7ae878c9d412066e95615174a24692555cbbe904a14cf 8e76b7d3973c38b20533974f0a6c118570aba577339fc6c70fb879f87183e22ce52334d8dbcdb0da2957e7af421082990d72177901c5d2a1cb3582a25904d6eaadf3bb61794d3d72054507864f4b412844a652952b7aaf24d9e32fc178346531 +7910bab15b6429947655e33a67f41b76f1d7b71534f8904d6a0472c2faded038565272d0b5f51aa915e0d624e9ff48d50ebfa2f09324864f26c29ab73eb39b436c5c459c7cff4d2b62992e3489cb4ddfc05d7366b161a463aa1b782641d93507de43c8cd0a0a0a9d1c644f4554e3edaf7fd794248110ca9387e73ae5d00d299e 0046e2adfe5d3549e1e6fa1fe69a7cbb4ac9b111c8903d544268f8318b0b47d4b78fe3e56eb5e639ad5382e7cd5bd4b2c3e70ef6 96604e50a1b9bb3d32dfd3c655991c02a2d4e35e6f2f5c7e5d298ea2536b304ab8b98668d26e52d12ed9a684d317c76c07c8a4eddfaa1ef97260e01937a832d0b8d498663480e0d44337f151f314e52ccec3d145e1e91d3fd24e905ed9d854d2 +e6fc96e060b956c25d50ad25443f3c30a12d199a47451a49ce88307201dfb15ed816982e8888a28daa92eaf3c5584ca6ab2ca9e14577f84396de2e0ac214b24a2279f5e7b344fb7387e9afc8f0a2b77a4d024a20ce6183499b17096947444bbb753d9b39e5c694239d28f9c454bb05468d17ab564ee6cea3741747ccb7f108af 00480103fd6180a431c837643566706e2b9597de0a1346a224d176a5b2c54aa4d064418ed654a5d39f4773fb509f86473ebb373f 85b9b75d820ae1398b8dcc639a4e8ac10b4250f84c11c18069a941a272615367d9e7fbc3dc66b69cb3621c10ed73cea9179fe9a813381c0ea973a14ba0a69691d28026b070e945286bc69705e1a039db1d489f4d5e35beda2d594af2bbd52368 +c8a8a0d41f35537e6fd523ee099eb45e1ad6ab54bed4d3e315e20227db03292e39dc1a91bab439c0d20e36e7fea6ef08983f390a6b5551ac3b4f1895220b2867fab95552cef9bd8702962839bd9b2c72772640e7d3be3c5889d226acbefdcb448432bc503e5a5fe7ae9ae7696c720a799f9882c64ae0385f656074dd8a6821f5 0013c489e8311c6bef02c8f58903b2ba2a98a27cb935d75a30d320af9a14fa3cbc6adcce09235a9eaf333dd05f4b2f1694985dc4 91689e080a268e28d036757a0a172ededa14f84db49e06d52d750e650aeba6ab604b65a74b62d041b998735f20934e0c032797e0fe2f5db3408df84b850f0765e47b4b953dfaf1ab2048a2ca61a167cfe57ec3ed8e9b44ad3a77cfb5917bfc3b +3407cd6d2845197cd7414a30fc3df7184da204222ffd65c4d16a12cadabf603de8043ea14f5e6ddcc22d3572dc06dec1a23cd924e1847ae285ecf01754e2d1247876431eb98e897e47412a2330bb32990f9714122109e94b38f82cfdbbf2eeb4c6f88f5dbf9f0ccb47939df8be321dcd9bfd9bb99cac9f94885fee7d443fbd87 002419bd2200f8e1d87db848b0379741685e680d9affe693eed49d82931030b6cb05d21a4965f4e1df2045c8513a8f574ca9f2e7 aae3a5b3c3643e3cd4cc1e2104c24fc2b25d85449000d21e7cce12f294a566da5234c93eae7d0c11cb227236764f8b34109a6601d13a5eed2da0e6de224bf42f2c0341c3f23f47fe6bc8fd1f4874cc7b609a6f0d9c3eb2412120b8e4a94b27ab +ad43f8440071285d01fd79244907803601aff4bc5d14c77483a87cd742144d41c68269d76c9a83c09d2178bbcbdf99f927b378497ffdc907a75a3b0ad019e69758dfffa480871eb6e1e17c8539373de611a557fad120d0bd147f8debe5f09a02e56fb607e9c1253ed592071f042e42fee39775b407225a2b86a950d81bb7d7ef 00722951879a65bfcb414e11712ee9431eeb32319e0ff28601112f89276ffc2b96eb65c7fd77d023f09914a53e2aae2c84652bad 9276930bdbdc905dab5ace9938585adab3acf37ea0b762b3da2c6bf174583f80f0e79dd3e44392ce3005d028716cf35704fa66ab3197f2585fd5a446c0b5bf844f352791e89920c4a84bdfc106ba62cdb6f059011515952efc016bbdbac3911b +d61a3765229dcd0b4fa6c57280f851ec2bd54d3ee2436935cd6d94e0120d0844adda163995fbc4cd9d7275da859ad8ebf30af9efbdcfc31c7c9ef42bce9011d37cf9d15fb018e117bbc102f7d05750e5072f73d02c2f45509a55627a78cbd9082cbf36807759d1fe2ecbb92ab30cf28434941712d38bdd100955d611987b5968 003f5b5a772d24bd5454bf26759dbd433fcc7bae4f5c593664c4d75da0cdf9430d7d9162bce3d7f6e13a344259da5a7d6a1635bb 8d6201a428d2063663d562581391029b99f27b8cbaa30e245502b402dcca57d0605b4d38f17550bc0a41dce68f889b3b0dec92649c8955811d6a2e38ec8bd835596a04664996f5a8196eaf5bd95deb556a0bc583c8b7b5ec187d60b4902e7738 +1f3c23636414ced48fab6763eed5b22537968e6bf08c178b3d31fb1f6ea773c6979759701d94bc1bee7c354272811edec58eff50c93331b22723d460e56dbee90466b894354777b23b13a37d15a84c762caca70c01518bf34d0c2f072145d274b3b6c932b48bd815fe81161d8507ffbc2f783bd212c29b2887af6d2ffa9d2b4d 0046bb4a141c9099d531dd23ac440eff1f5b10f7cf34920b6b702311d490d25344c665ed5211d401def24986c8094165d10f8934 b21f611ba6684c5b604304c8b40cc5167f91d978016eee029487e29af91aac0be210efe7c076c05bffb3cf3656eab09c0cad5aae32c4df5447d501bb6f7fbea1f986f0806d942750e71ba4c7d0c2ac102a4968cb76d6966ae9ad8adcc8384268 +ec69f2937ec793aaa3486d59d0c960ee50f640a9ce98a3becffc12d6a6c1c6c2f255d37d29f9b4d068373a96beadac98fd5203a9f229bfc70bcd449640165ae5128e3f8d057769e28356e73e35d8e9af7876f608390090892c67391ddfcc1c332aa61efbf72d54bc615998b3be8ab0a9d372784bea48c9fab244482c75cb2de3 006f2c6e9ea8109223d9a349fce14927618fc4fa95e05ecf9aba1546619eaeaca7b5815cc07e97ae8cd1e9973ac603f84d838393 8c53d5d246a8bc416d5fc1596961257f722a8ca41ee8a2dcd497243adbd7eadc8030d5e2088fc6b174e998966efc1d660eace1f00beb82105a01b0187c0d472e0ac7aa578657d9e12eae8e1c6839fc4e337ceb274b611d62d435f7279afe7efb +70e11efc78d7f079ae41ac3c31c96d3220f4abfe23814a2a4a78d9b1a25e838c3408bd416062e4b0a5cdadf0c6e16a11e00f59711b417751f5e4b43ecad99efbdb2a81c91a034e89edc94eb552c3eba62808563cdf64453a1db07daff8742aea4a9fa738e1322da316b26dbca2954b2bc0de6da7518d28e6677dec6ba8af4285 0004212b7fd913d794fc6bb33e0276e349c052c969ecbf6afc89b28f75a599a9242acf74dec9f374361ba296ba42a38407f9b7d6 a7b4a0fca3de5ceccaf5cfe83246cb22b485e6dceb6ff3e26fb3c07bc1bf6466971c464917be91a28a83276f8715d8380c9e980b050adc1d5b9cf01186f80194983bde601271cb35051659c0dc53b74a1da70692a85242c9d0a7934b6012d65a +d922fa515e3bed60b517a2d37cafe4c041e5ab4b5c8d8d4011bf9fc4013dd8abf7add71fcfde5e71d6abe76bd0f749e960cbed55711c87b5629a2c39cff48ed7d0feaf5cc4765e576a4959521f9a45fcba0dc65ae618826447e02ce6e1cab5ce8d6c96c3211adbb0660de7df7453f3aa726016941d00d8ee536cc106a603d126 006baeebb5ffc89c94c3e8b37b9b0904e7c4b251d204894655bf3b1235710215c29820b9d401c9ca7df1404d2d62d708aafe208a b9375d01eed4497eb705706269284db1593bc0bbb2a8fb5de6162321fee306534253cc54796fd7c2f03f7d4e403ecc0e057386d7b4956ee217675a9cbeb8f2f9d550ef2fc5623bf1539f1bae960fdd7178ef0f0561efd611532abd42b5cf18e2 +4f64d0f6bfc542a0d4347576935bd68ca88524ead03b8d2c494061d0658e6c3e14576b5bcea5f2f992f54cfb52b5c7cf1dfc517205e0454510eef1b7054a8cd06ab53ed2468193f98ff0dd62faf076549ab2a270f259276d5729996c120792c6f466a74ab65035bf38ff2c055b43e2a8b8e2449a2375ddbfc18242157bd905f8 0008e5f66ba53e7caad1feda122a80c32c82d2c32a7237b8ee8ead44ea8f2f01d77c7056b9dd60b92d051f060da8532c1fd0e8f4 95a264827b50d366afa5bfe9b276a1d63534d91902e887fb95f24f3611bf94f228efb9af37694f3d6241b1934425d7a007819e8a1c00e83832d3e76623b81e77306921707835ad0d5f487a0a0e4b8905387c4fe6254c58b8a6e8f586970729a4 +7047d478ec5282d55db8c19c97af10951982d908c759ff590f27d57e2664f08d526cbb2bfde39bdbb1aa3dca5a8d3feb50b868be6651f197abccc9d8040b623de367e2ea1d20ecd302afb9e273f4be9f3f64f2c2eb3f92d5e0e375db6549da2a589f0604bc7146562ccefd15995a7c4208f640e7a17afbca69cda4e173380523 004ecb22b44e809f89b16abb10be062c89b41ee34e110403e42a20ce59a99afdc22f6f6dda56e1d9d1b8ce1d057f390db111def3 8413c640ba3c54b16c5f8003d57c1d4d04f1216f55a1e6bbe3ce255d41ac2935b3f0da9ffa288f8853d7762dda0c2780181c2fb0be98e6569055ebb4a9a552d993a472c517af09d07299a4b56ddf017bec465ded39b3b318a47b5471d3cdc7b8 +1a8384b4771a410663e56eb36c5d9ede8d161a8fb0e31d3f74bcb017b9e31232bb2e2f4c65a2d85bcd1cedd93ef08d4bb4af0095731574ab3f2762788a1ba3bf0ee46684da8d9dd384432fee99ed3c69213d790a5d81b351063eaf2bda71ca4868ac36be1b571024a8bf09039b347fa996d5d161078314e24b7d073e05cb3d48 0051f9500c15ae73d6d479b9f3d2caccc2039d8d03820befc2aae3bbaf65d59bd9cb3c4e3aa8bed5b3acb70a5566047ffad80729 a4d96c140fc8a49d5aac8dfa2c17c378a49c55709ea0672357a0a8befcf3c0d9be9fc66252672a65bf3f20528acc377204d832df12c33908ddc4dd185db30e08f5cc1c09ca8f95ef7948a478cd390d1420254b656062c722a973a3ea3dda7c1b +43513d6dd8bb0af7a6f5a2b35f99957d335a48d54f2c4019ce9518b35441d4935518976ab1df37110b5b53532cd9e2c66d9f87ae7f683d7efdbe1775a6c15eecee84c6f879999d0706f6779dc158c111fe8d7201983883bc8334f51dec60004eb1087347bfdab20f8f2f260556681e05fdbb8a6139857fd3bb2df5bc1f2dc143 000cf01dc4462cca764f4f8cbef48c51980737b9b98d1384b8de9f4c733829db7718a9b5eaa46a8475c2144fe4454cb8eeb0a443 b65127304decba5e07e4c44b7424fbe6120a59a3e951493cb10a110b6d4409326e08d13507bc4e4469ad866a183cd25d14eab2972f5e3add43ffc08d6429413803675dae5525147dbe242fdc18d7cd18c0e81b2724bd48413ea9a8a4972ee8db +752300bc5066d0efaf807183a41725e349907b7339d77c79921ead3c685b616b0eb97e708f3880fce0136c510c8cb53b22cb424af6f1c34633600939a0647c02d8f9601f9416f1d24a51657241fb559c25dfba91402cea43bca1a13718b3945b048725f3df560e6717cfc6ebd894e29bff1e0c7763f15b8ea93e67385f059598 0063a9a565497974c6dd459bea0d1196d74f263f333c31b7e8591499960e1cd79e2ef4cc8709f6d54713f873b16e7b0be42f71c8 97e450b647e8a8502ee2d5593436e214c4cb4d9d176e9b80321f34c6d99573faf10f061537740f1e14e2f9856cc9dd560dee8f884d1f338bd26c7aacb99c9f4621d24a86991ad96f360f9bbb7569165b9fc8a16a4024e6674a0bbc38461f46ea +f620603489944769c02e2f902c2299dd5f32b5fb463c841b7e1fc0249a85d2c31684bd3daacd97de8291c5d39e84d6e59d3dde1b30c181bfe8d31b8d8e080bd191690a67fa00024ac8c1b10981b40d4f88789ecc58fc69b15417fff34834e23453bb9933a43d08afab74d056f366b40ad167b51ee5f008db151a12b467d3eaa2 0041074dc186193d30aac7cc6d269b938ab40b257d095e54ba79967a377a91b8f73671470cd07f0a3d1db7cf0a31ba9070625e43 a40a19c77aaf2bce04379a3658e0be2ec91aa0bb6afe023b900920eff0240eb4803dc03675268bc7b47b69f2d7b2bc751348ffa04fd521d630cd4148c4c28df6e83019a20e3bbc853c7f5505107c84de5c5644bdf6f22b752fb51ec3e1ae69c7 +5575f610762b42ce4e98d7bcf45a7a6a0d66ec7f27d6b8b17f1961249d905bc7e58e2ce0806d467f106b16285dce4544c72666d08b5e2276cd0c4e13187cbda8aecf57b1855afedf8fad39ee4fe009f204e60bdbec79b123456ec2d85631d382b8a2f2c7634af3992e4707f7b4215e2c9d3b0aa8fb08267953883a4213669d33 0010820db54ccf0226161aeaee79cfd2797f87702b4ee91adf8543b3c9e79579d0df8a889e366ec1e0718e039b87a37c24d620e9 b0a262cdf3415dc65247654061e814a66aea63a8323791b3d3c541e5380b81b82f52abab63f28bc7017c3ff830e46f1005c408b344cdd2d0c71caac635b1833a0e3b22f69485651888d4a9dfe0c8085b78f42022771a1b75a9fe65b85afff66a +81cf067411dde2d0ab04fe5fa1e28e6975cdcc571588de60a35bd956a535fbbda4affd0803d244f3f7e6902a2c9a7ef2488691b6bef7f8ffb33be09ccae4c5285265e4957f7928ea5cbabd6823297f59a7cfc9939a49f26bde74c4c69e2d38c1efbacbcfdef011213843158072be84ed3c1781f67a0e2d4e9ba76a585c17fc0a 0059d2a06e8bfd5e14a9bc8777958b85be5e97af892d2cdeb0ecbd2d5017952b5042349db5fedba2e26e7b85bbb31ad313d99434 a94f42204ad51687e0612c7717e081419cff5e3f5989cb7d7fd6915bf16af50fbd83ca87fe4f8b2937f27b3a411812831068459b8846f98ef37acf4250aef1ed49dce4424103a751893a46f1a89d87a18f64ae36f5725a2e3f789827608127ea +8ea18387940035cff2f37278d321b344231075db43c7fa7fee9bd3fdefe5e8f03e7af9deafa1022eb108e19ec11fae34536a4fbac2e8c8139a081a997c080cbe8f3e2d2a72ff26edcc5338b21372fa1498e439e4d9bb12d51cc539f859047957b1b1f1fc30b90231eb06b365a4d404a1fd5a0e5cef171fc95b04d0b557d78ebf 00405590893cbbe18f4ad99df28b5f9d17f8f1882269aff0b7eee9392859d68927a99c942a3075269ddec6d69c0df2d76ab9d801 9142d879e66004f0bc158f3275ac6d8752dbf2b57fd4b7d06aa140b6615359541457ac0a2d299a46b355add4b7bf31a4051a1fb87bf3cf8186de7ec74130d43f767e2da2572914d41b80b71755a19280ad930ef536423a884eebff7f674d6473 +6a253c1aa17b2b1e6624afc8e7456d366ef5b1bd78e740538260f395481148a64da0b6a58cd53d7e06c691beae1a616547cd95c4d259a371e51c2c0e334c8a5311ae31e4c7af325686ff9f7a36f731010ee1a9b8a29169ceac36a060dd23611dc9713c615424888bb574ad5f5755d7311bd169336ae986c977a394bf16487c4e 0062bbb4f565aa0f23b88ab9029d33b995729d10fcfc33ba7c4051e2fbc72f15636a834e3ebfe604b927cdfc89f53c57f36890db a8baa706cef991d141244ecaf02630e0353e1f6f3a65f08e4dc81c211f04f25d59072fb5e68ff0400ce3edb695e7e3a304feb8c1fb2d4449936988359868cd949f7a04967b9bc7127b71ebe84a85db8e378ad6999a28be4a14ca9457a470deed +0f91d0f0139faf3b90a3d4bebd7e96ff6bb6f90f6c68321fb392637d8ab2a60d649a7b7364ee6e4e274e1a8d342caee36cc11c56c54247fb0a8e8ef81ac4322b454dc9a195dc54567bf47ec8d4fa4cd32e76d78ea2d08bcbce3edbb68fd8597e56d5a9f2df4e47b2701046df89615961db601bd8204584a6a6cfbb627e2a1190 003fad7031cf8810544a3e4bd1382c0a2e22c5a9fe4804ce67b27591fc516ee81dbac841d399327168aa6abd79e2b5ef85df1528 98eb6880c54fae327184bc3b24359cdcec6f3e9d74b1aace21b61b3d1e05cdb0b3b3025d2f2b1355610689d2f19bdbb817490038e6c77001159292ea7bab3190c4eac61d8116fcb3c3c88981b0de4d27afcd442d0d251981c0df0a6a7e16d10a +50c17c1fe4dc84648e5c3c3ab8f7c971d4c58d8d56d2b5ddd92e35e6792111ed8dac7644ac8a07ca8bb4e38e071aa47b22ffe495e9083f9bf781ac1b5fba571862c909c7aaa7b8d05ddfb7ef61c99700de734d5658f44ae9fc908c85a2dac8e7f854d6d24be805fcd7f873a91252985c5c73129c60177ba8fd99daa87b25a073 003db41b4f637fe7977c90e4f1a21799baaddd1826c667102414877138436cfae1b9959842b8097b5276f15f2b982ee59df263c8 ab4499fcb72e88a107c268e10c44b9e1948fbb4be473b5877e527383f7a49584175660565cf71afd144b965f84d86a7618040e7b5b0bac2589803b3f8877ec03e5a144cd8ecb2c67d2b87ec65d15fe8e08e1590c1e5bd32eb3dc52054bd40621 +3583a3226e2dc463a462fefa97024e6e969c1b13bdc1d228e2d7823d9f7c09012390c2535baf086588000e908309090daac6e6d2b06d2ede6fae838ed47f30b5b481185f607a3586f6dea47c8f84e9d3b96d5b0ebae2462fde1e49d84d36658e87dccf5e30c0937feefd8862dcdb1a1ca373f6ae41641502ac54df6633a8cec1 0065b76c6093d9c49591293471286df1a4444e60d9d06cfa114e175afb5f119d2abeb273b0596019a0ec5db5b5869f2cc827b364 909853b98962b163d3c84d06789b8aa919a67cc933e3aabe5702e9e3e4fdf5d3034d7cb7a51ca5716d9c30c796af36da177c673cc1ef56db3e9794a1a048505a8e99941cefa436fefeb1113a902cf32ef3b28d1e0fe4a61e210b071c39a2d420 +60ca58462d53d074b370127132f4e59f5eb8d15594dc721a94286afd082a8934e52462c9c1c3910f8b50d7aa3671dafa5972958d876d7992467b2fee3795a6f9d8a7bd3003a8582ea8c003aa1e02c08ab6804d85bcfa13a815d75c938671f0af0706c68bc70a6155708ca755cac2fbb68b2952208d63e0e2e3d816f04c61bc03 007e9993f3fc1fdc4c376ef77ecded96006ac1159740bd1b2dc6ae3d97e15a67383f1fc931e460b9af3fe14a54e47919667ed06c b3456f02559b3e6fd473adf4363f6267843ceb84cadaa2ccbe57d19042e27438c0be4b7c3e37dc97c10803c8cfb0fdbe090519a9a3341d3482ee3b7259e4958b2513967ac224d8de7cd5b3110cc09f4c90abdaf3a19ef563b1ef81afc325211f +c749f9bb92ca9957ca6d0124206ebf65e860ff38a225e241950bf4526cef3f4fa9184ec83f71f813fe852dc08eca6b45b14fc7f2c6a19296529bfda007efe9d0d26492de2a902b45ed39603e22f0a763dfa5deadd97ef6feb859d860baa2cfd1d066c0be0f9f4e0e2fafa69cc51b12e814ad2e33b0acc0bcbe1df8cf018dcd4f 000c11e2979498695c660a2bdfd105b115bc4ff8664ea15cfb40c725406c6fc9a13027bd1d72ffff6258f29e4e19b845243444a7 a2dff5f28614b8fbb8fc77b73aec7ba6fb3a09d474a7886eb427bc8d04122472152cc1a1fc20a72e3ce5d602e54d9f3f00aed9fb2c57c079a95c22b74a51fe0767b446f81cdd5cf203a2dd3601d38ef0e24d78308241f0d6f6c94b6915b05350 +4de8414780ea20f7943b1f1adae5e3962d96e828fee43bdbf2831bd71bd25df2976a3be37a7a667c7fbe1200de578920090d131a750c9bc09bd95b261234ea8cc25423c4ddfff5656d6b32da6e2f6f530e6673a8660aeca31273bb9a3a21bbd7031a2fa71ba37c004d3d1c64b2c0798783e47b2efe1a208959ac16e35d444245 0068dfc23c6635bd1fa1076dcbd456ad6e8df7ce7c1370fe275803befc4ffad007fd062a61cf1d50b93aeb9afe1aab47a65af82a 85e7c106e5aafc5f041551eb9cc71de72652ac2171aa7ccf917b4c1de7b5819df1e6daa4cc8acb12d1730bf918180bb210cb4cdc4855103adcf21d5ee08ca1589469600e6f15cdd31c62e39b0554d2bbf684564457fe4cdf26aa499d8989873b +a081d54232f84bb19dbd52ec3812748e2e6486f6cf1b177b27929504ca878036547eb43531bb5b3edc81bfe105370427e92831d2239cca0106d031d9fa8da9cf89c6fb6401377d5936b6329ccad854e5567181b8f16a37c35f333eaa0ffe91d727d183fbab935fdac2d5670dafb3fba59e4fa2df1746c58dd8360fa08af7f4e6 0040807fb888e1d9fd33604546656a493629d94d4a0a9de2608962225ed158167f9e2438abe2d12a11e2adb6c2b66ed78215b0b1 8a06d959270ac04a5bf35f92b375caa21cc7c0da48aead7dfe695a8918e94333346df0da0a92e2c4c48ff45d91327b2708e2e5e0b882890341f3bad0ef6499c1690158395b09d38f5caaaf7a5a17149fc5390c3ac77b3e23e0146703f0309e87 +ea60266f1538565b3ff42fa4bbfe319be070329059c52c8bc04a7da2824f209c1145a05e551ea59ded8ca8439c328f6907da4e81d658937df614be98c7b8648818ea80ef40e49aaa4431f4a211d62acf2611f5d60c446b2b25745078c643859be1b12b3141a09ab765dd63ea1f2a2df015eca0840087a5db378c4c4cce76cba7 0033bda0a02badae08fe40c239b9d59e5bfe1c4d4b9b7a5acda6790bfd77ad08dde5e93a2da80ec54a7f88146d72218bbb88aa10 8873c5c0e1a213a079f5789f5a37ebb31cba3d3b5de787840b24c83ff1ac4c7c351339becd44d52649e7b7dadb7b4fd30b9077efef670de7780a7b9aab14f3e4395b9503a0ca4bc4582f98db7efeabc43f254da5929ae60876572fc44d00d6a9 +82f38c9405ef0d26bcdd5b3fce4fb0060c3095f61403418e17c337933f0563c03691fabd32ab5e896c593439e7492a9970ae325c67196d9e83fe0f9780409a930326f7e6efae035ef8c321cb9ad12461edd5cde66c04739fe079db65406b3c2d22f2d04b1a4335285513d4ceb901d2ca2ad10c508302266c2cd6079ff14eff4b 004ff431769d26b8837d3e1295f5464fe82be29edefba76323e92078a6483ea0daa96221549102509a1bdcfd46a5a2e5de10c39f 89be93de72fca81f0f9e21a4b4c84228e84eafed29f90717093a8297e0ee47a35fe3a6cc5e8537a068c8f8475515108f164addf43fe5b1dc840c60804a12bc89167fffdbf054abf9033f967aa7c6692d931b2d356460dc379a5fbafa05c69486 +d8506fab4f681ba4ae86066aed447571eba4fe04e6585fe3be6af2ab1000a3da68c5b0c711a85ddf3a40cb7c8944eef81f2094650459e14f5b848e6add7e580b0198070f873eb3ed5d0728eabd92bc1398764b94cbb4cdd7cc2027b9762dd10782658cd9e8a5022ac062fec535d892198c8a387b3d2b6f7c92b1af6ab7dd9e4a 003f85ca1169ca7e9df44cbc6bc7d2868c9d94e8f8b699a42ca492dca0914eb5789a9032218dcef7f95f959c9554a1cd83360439 ab9411551f9dcd96169cd5d5bcb5c871811f4abaddb388ad5a2bb6968d4445046bcc292aaeff316d9ddf61f82a105d210a4906b2833e9724c8b73b8da740024d282de2227d2d6d0fa2203b5d7f1f765ad7cef36ee17f5eace04d0126987ce4fa +b3f30d34f252a4c26f396079e773142bf61c0981d912333ade3de4e27cbc72cd8a16b31807f0c46116f87accb854487d83ec8c6a61565e6fca145eab70048245db08616779d7047db63aabd90dd15acbb05eaa510072c151c0518f1b34582b95f43ec7b9484b2993c176de79e84566764467f72392ef31619426d159c91816d4 003a97deb36d68f81f50c8829d412ee5de7f9d775633cb69c09dac558182039e275fc258240517a7c4aa592e364765321f27cb12 91491f09b5ff7674bd2c566a2de3c393eedc0976429bc8f1d04f89435d6c776d790c22baad27422153eb89af065d1cc001b2ca17a4745a785d5bd18c7cb3f3930648deb8acdcec72275050eb5cd37eb40b12744233d5e56439280ca9747c9848 +0fb13b7c09467ad203852738eda5ddd25b17d330e82c279630b0e1f0c86681f67f6e537fb00da9419114973c8559306de58b0387d86e52d821d982a60769d2f15fd5ac2ee6dc55d8ac04ee247282cb2866b8cb8b4d7b4b6cfb33bfefdff09a73d727193e5fb939ff66ac5fcb644a44f9083a790888cc538c5eb435243c6a34a8 003b1da0ffed24e1a3b5ba22bd684337f6b08053591620541bdad50c761d66201a2cf21a4cc636426456525b598e96baf97d9851 a8d36a581cd85dbdef5cf7e68e1f870116a49c726a8fb01c27f321df9c1a7e079ff03ce1a22b0726b531b29d8090655a0d2a2277409d5b6abb0d59ee5147f5c10fc88e6b7255f61a00f7b2e7ae6595e542548aeaf6433522cc0f8c9bfd6f814d +f9b8124281628cf4e1da0cb4f021c8d19d815644cd80c7c8de4cc62722904ec4cddd26cc4891f30b15098a25ba6923c6abf4774deb6e1883fbb409862f94467e75a725e7154be860fd58347577c83adbf18535c54b102220197afa062cc1c84f6094490ce488af4a08d2c5b808a2572e18a59de96c87162f88413795351cedc1 0040bac7e0d3b54c7753c79d43469e310d876015d948fac4e3a9765444754476af72330e88d79ee6119697aafac8435ab5690754 869381d817f3ff937931a0c57bd08edadab2bc4c7ee45248ca018f76c4abc071591f37021ef6d93f2309697b23befaca1783b6051a995a1e8ae0e1daa7aadef819dd9fe94179b4a05a011aa4ea933b7d134876d0d71d38c85d3b0c5f8c8203e2 +4e3cd6100520db050af0daa69fe3cfe6603a223d4f2a6318fc5836db8640d4c7fb80bb781302036d2d6fb8e552b4eaef3133b98ba2d36b9ef0b86243b0391413c73d48ecbf1d19170f1b3b781b35ffd316afb1d55d1dda8e91eed5553780cb2714a93e7ece698b832e853e2589c5ba2b8a997bbbbf625071ded66762af8cad42 0025b7eb3bdefba3c5134438caf968f615b315204f348006f82e8d61057a8a8a853230cf0500f9d0b8c1551a59b9184862dd2ed9 a7820925cdbb0fe9468ae62a081936ca2dc85ce62a4bc8f08ec5f229fd37d07efa6d040374da8bf3c0c7e7ec19e1f3a61335577c1a38d7e7afaad4d35ae240779720d20dca8e03fc8dd8fdfd10d07777d5d17a9adb4dd5bfd2b92cb3995566a7 +5411708381a65bef4381c9e13a04cdd5ba0c15829f7f25ccadf695f635384d8e4704cb562741747831b33852567f42fedbd190d2980f1bc921ce01c17d659d4bdd7eb787b3927fcee659dd3b65132496c687f2249272a473d46326e66b3cb78dafbb522390162c168f73bdec88adb145e6afecd561979846ea4c8cee38dc1686 00673b3a2985c95904732632e5d988d8d437a60db13215bb6aa880b348f011c609a1e860461427a8cf0d622abc47f910f5c97ffa b6d1a402b3efd11feb2fe14c1181adf78a28dfeb411315c86fdb4e1c8f324554c38c83e36755bce71df0babf932f6d3503055ba22448e460d7b2426a6a30a6f13cc5c7aa5f93f7810b5fdd2793f5c1c3706406253c23161734593bb0b8a15fb3 +23757fa60fcabf543e603d8b31ef0cc99b3ed16b4816a84e01dbfc858872fcb79fd03d2f8a1d4f28c25dc42a39e20c34f81ebccda1682ee9bd22fe323e7f8ea90cf4a2a6ebb634cd1153cdc35f7306f28a2efd822bf23131baa1543d0ed5ab4c8168d3199983fbee117085f90550ec3ffa2b06070d3add1d707fc2593285ff58 000db7dcac414010b816236cad584dabeaec1da76c97182d1b62f87bb7fe2946a64d10430571b2b29ccf2ef72c969a9f045f1f3b b2c1f9ead67f4354d52693ffbca6e2ef6581400fb3629c9ebe1e24863f35de475ec23c0a9e14dc2f2f6872df0dad356209ce0f5b7e7332a9cc5e9e9ec265ee2e1c5b3d471a8a3dc9d97074e5d5099669fc8541b46311eb12b1e0cf34bbfffec1 +b976314d2f066f8893307a726f450dcf2cf865c170e90e6908ce9787eec48e1e2119a731b2bec3c12fd4e6282a393774251bcaef91af6ce57c63a8b45bedd72ab862cd169b7c84b8f6a72084ff823a96f2f8eff3483a7ebfabdabf0998377c5a6836d88135cf61c65a0ca7ca57727da68047dc635c17ad13731035fe9a6402af 004717efef16e1ae267e155aa1daabafc68515aa391dfeb73c13d01f3132bd22c984228dddc4dff4c39979e7585acd3f730cfcfa aa20a97a222d3b5b7a0dc30cf09abb8b66f4d4a1810520e9896a6693b37869e679369d9de1e6259046143fe12e0d628b02173b63de08c4747c8fa1931f7ada6e3c180ce420e986ca02008a0036b42b1e2b7c50aba5acc3b7b3df0e6fac3c2367 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K571 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K571 new file mode 100644 index 000000000000..60fef0dcbb9c --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K571 @@ -0,0 +1,60 @@ +964ad0b5acc1c4db6674e86035139f179a9d5ec711b5bae57d2988456bb136d3aade7ac9ef10813e651ae4b9602308b071d75a934a6c012eb90c5eb9b2947b50fc97b1d36c5bf9eb13a7b06c94212c3dcdab402a563262298defff62b836ead1f78f9d20713710fb48115cc5045ba15140fbb4bdf516e4150d830d02cf30963d 019cf4f4d06825499949f9e0b442586fe1bfe3459813a2b92cd8de0f775a4735e02655702ead8e60824180761808d9e816d60bdb0238e1e8039ca7bb63c92e1cf8433ef447e64ead aee0f4199a0fb55d11245e9494f671c2fd382fae9b5b95a4e96d7d4a53728e7e315a90b890d2122b5e485208003711940d148795e128ffe6dc303d4611ffafc70af8bd26523b4afcbd5c6fb5d394a30b258b173a26f887b0de42d5200fad9d79 +baddec4794effa668cde267016dda67bc70b847919a9aa595f93ba9dc27354399ef7a607fbead31e57a8ce698beabb10f313d393980425e67cf95be45d512f00e950c0c5409573ddc3d556f23daf056259ee8914e860562a674311452fed780b3e0317a7fe93baa81fb98df3ae4328b28ad0ac8f8ea33efe24faee658ad026f6 0098521a732e72ed945a549afc92318fef7156ed1d1ed9bab93b581478cb2339eb32bcef705c9bf61cf2873ddbadff8ff3806740a2e30ce67d1807a8179dfd5d952e6f8a583baf81 921b9803d36fe01da4efd73f9ce53f6f7b06fabce78ab937a92b7ce88d1028dbefc9ae85adb2fef15ea74a8635851b500448cde9844d205ba3929090b7fd31e88ef116b0373508df5678a7c925766a8bbdc6b7f848a0c33788e04abc37d4a588 +7ef7138fc657492d229054f8a50dcafcfcd1dc06f1c16640af3f658907e2969248b54416066eb119adbfa23b8dc578aef18bba79610b9cc109394b900a25e55a779230bb858b2ddd9499a7775d392328db9177aa9571c2f61dd52010b48502154e914a0c55a54edcc04a6713cf7bda8744a893926118b09df877d1a4f3d95e8c 00336fb21549e397a190beac38a1ee10f0551952da15f71e11dfda415e5ee08da2356f114d450c661f52b2b32cfc7b9be61732672691a079f0927989b7e9f4efe6095a242155b641 8fd87d0248200e6fb61f0dea4d9d3b213f7415dd003f332fc149adc6c1822259c6d4e8567fc9ef5c9753bc2c48cfc4d1064a0ae58a01c0e238a757925d2f83e37027c0c3598f2071332ee997ffd4132490f254b4d4658e9557add2ca49387769 +d58e1ff1d49a471d0567ecf8f29173dab5fe5f6184ab4cdd095c231fa7b82551f99a482994a46c3d8ebc07297fc9e952a5dee7d5f199b119f6f8b250f8fba45701ac252db725e75c4da27ad77d59a4eac448e54a277986740dfee6596811e59afc9755e53d24b826c09e497e29e69a22bbc85be11763064e9ecad7ae66458ca0 00e287ebfd9ba294128cbd484fc5121d271cd33e685bb1804f09b40aaacf64b5a9f2cde9b30a4a02d3a9bda97d92f46bb8787b3c61f280b1e1a0680f1f0679d3bb34d53725d62e52 acf2377cffa8d715a2e659fa2330d6990dccd720f5b9ddcfe286e853e156aa57736bd99e59b92f11290234a0d4407d831246f9d0f353fae4d4689cd08e28e1faa501cf17e8f023c02dcf79dc480ad8d897bc222cf1c5d803b184e274d5dab663 +4949ba765c14c31f68ee0ca26bb42ba2edee63537de4a6f5c42bbd862c21288d6ff48145260365193c6fd2b56dfb014da26b8a483776b717c6874f627c9a622154b824565b23e178240f53ee9748c45759ba5c035b584df0f09504e95eb9bce0301653aadb860bb25e6ea6b9606e0ec3bdb8089e6aa0d5763d331757490715f9 0149de496fa8f88b2741864d0c35b3df666b87179b7bd06cd426a45f13bc87ea9f50dea85e1fd02a532630e0e3a231cc3e7fbb7c7ba85b40cff1124e72c677c6a3ea6aa40ffc64b7 88c7b9c98320bb66dc9898cf3b70c3ff29b614b141f7d6770cfcba233293b8952780593e82888cc9a36e8e90b285753916225f31381fef6708506bd9d7a3a570c5eb3be019d58961e086d39f278d989e248afbd5f09b13b5ce2edd101e715ad8 +5bc63e5c50b1650f0ed4a599960f1e4e11f6c151b2123fd71d9e3c44662312a74b6854290628e20b30eaba81555acb2fb49b640bdab2528619c7fcad0f2a2880c7ea232d427d7c935fba2313370fda8863a7e7e203d63ea15d0cfa083e716ce6068c63fa616ddc225c9e413e694cdf6b355cb1293af5d6cdea51168f5634e878 017605d7c5873d870462375d741b4bc6375f3d47f7f5e9d998917adf2137a81e63b66917b3dda8968930c4b850f2270eb3187fc756e2beeaa67fe0d73053e6cc0ff0004a21250551 adda5997e377a9a0d93be3d9d4df8567a4e5387161886deab774642713a1530dde4e338cbc14936af8d13982f0f5003704ecf78becc27900f29a5b304f6af3a9c146a58118cde59859a567af553c5210440f8d1e3b78d2aaa202e96f2633d88a +610f6633718e49d232b3798654095e2efa0de11f41258b27aa01956480c870d901efa77e109d5f95f1f5101d3c90fc51312d9b3019d2e42e0067eed7b457dc7fbe5466923b62c83d7347e4dada571b57813bb9c21d5e308519b8eedb7a7706508ad04aa69698e03636eb30fd9fb363ef3a185756494ee01175b16847f5b68076 009214dc2da0967912c31995cb8f5bcf4bfa832c5a2d3610f3a9857e5eee7c77100d599d9ed003b4106013155dffd6c48859b846e45e0ddbc5fe24f4891c9b2df51407e9cddbd974 b6b50b7465f482f45db39cf5dffa6781d0b9c7b12c259f962e8e4909b6cd3f3bb3ff268419cb41f302eae50ea8beeb3d01fd244bdd27f4f0c5a64e48ee71f551191e94827c8dd7a1a32e00c5323013001bfbb0990f4963f9f83c72a90a83f955 +c548f0546cee0c0400401cd540a0aa9377f27ac64492e6baaf38e794db4df83e64ca3d83b67bbb46a6c269c04c2725287cce0dee984a0d468c9ce495a7e554a6835d72c7493bfe88dbd5a044a148c89001b8087fb03e57c2b7212d0b175d616333a9affd8a1802dd49ba9be3ab6c6d9f99a5578d26cc4707a5860c6c804d69ce 0042f2682e9ac8b76f3c0880e12c292524601dce9ea6982dcf68bfdb0d3fbfb50dc9229e54149ef09b95bbf624eb04ce1427077f30d8536be9f69970ddb449ca22ab8368d2689ed4 a4c45d04e5c3b45c62dffccfda1156b1347540f38bcc3fd46b5d97df79f9baf5443a4b2e82893e1393adbbafd0f164860e3e2f5dd1cc3759a657067aa8fa9cfdc137b121eb4cf99d059222674d591bfbe30fabeaa0377309ae6ed0e77d5f1f79 +9431c6c5237f6b4b35682a0c32f68752035c8b295a1763c5dbdfd73466cea64a00ecc11356d02d2a9211dc54548f5db1651e4471898402c887fbf45005a3bda271df0158c98319d4d6751b8ca6b07100182957d5fe0d97c4e2294406f83e9afcae4850bb089f2252490417b5afd8f07f4c795fa84c9c7cdcce26bd97273c0072 017ed9a9c75cf66528428e85b0f019e3488af8b893b12023ff1b4ca9c3691b74e594539afa0f4d7c3863d15399b862f15e27bb077392d6bbd546ddfd46728c75177338466eb2f4ff 8a0ef0a46695f390ccbad34284dadf6f88b86f4f255e9469545d81f3f6ec49457a72c8aa3023a1d1a927f7ebec1b193906bca6ca4525b50527bad176d260207a70d99f3a9f35b10c1b3e80290cdce4bc722f8223b1724cc10079f111db305ae4 +417cd5f60416f17081d2c70e9a510114e08be83573bf9deae75fbc3095dffc8a7f7325f61f9d6565381710eda871388cb17619e4448836076338ee309a2bba5f737319002e259b4a875cce1bb97996101c9a7abe0278dcac203a712f0809eb3c4b85a9c380550ab0bbc5067a8edfa78abf03c09b5c08f21714e1022ebfcada4a 01bcc09b3f2f1d26ab9955bff7e8c0f85c8a61293511a196b53d7963f4a4503849c96fb4daa68c9852ad9185e01a35f0bf298e34a09ec352cb6da34f89a1f23e8ea27712a8f43aa7 97f3d6824837d79282630afd222e9201fcb973f6146b9da9b7b9da6645c497b7877b3ec8b6b3db4449225fd2b411010601580ae18858a1fa0b835159cca276487accfaddabf3e4bdf62fbecddd01cbea124577a7e83a281796b3fe54300a93bd +eced8c412a153a643ccd69596389f83b6a36880286f8aeede503452bef8305942d95734fb5733f37ffeceb1c2dae7b1396c3323de11089082745c28a1756f784423fa7ad68bbfbf0d93ff8b7ad62220500df6d6895788402c1f5c69c06dd9ef55e2401cf297184e411be87c1bba657f847208c0e750f94a3df92f253b377b4da 00ec52fc3d9c272ca80623e06b15c35f349b13548ef7ee400bbfa04196850b3b8cc7b239238c827f9b0a3160cd97969ce21d66752791f5896e0385b0527d4d77e4b9fc70f04d73b2 836e1b88f36db632974a83d89e788c9ce11e4ecd84c6ebb4bce0f68c5241ce0f128ce5eb758f7235420452b7c767954d188578f63ef196cc8a5537bc865e83fe3403b989afddff8275355e984bf0308243c2221ff8adea00ec9ab148e75f7b19 +30e83ea39a92036e22b7bed7639eab5e5be1d00c20b4a9b9afa9a0d1653369cbef363c119cc6f921c8f84663949c8b8dc9b743ac2b1861a480476e9b64c8f333f34b6fa0e1ddf09d49618ee4f3c1f46751b5595f0aea413d4ca46f3c26b974b112cbe99c813a96a4423764c069454946f213c5f066ec38108f947abeeeb02fb8 006403de7627de22d1dcf6b8da5af62f9ec59ec065cc1ca1311bb98aa439a6d5985619b17c17a70f59e17cf180ea6828ef57f5f1f8ef05680a9fc12ab7faad5af61e4e11fb45d341 91487b8ce3c0ef15bcba2aad7f5a4f9f707f222aefe609f996bcc269dcbe951bd76b79e6b534423ac8ea10327378a96f098694ad8c806ee237012fa48a44191617677905ab90351aa4223517d499287dada2334732e686f86c57708cff476942 +3ed244dc16a5cb292db4b1433b0ca3226913f07377faa20c6c1402cb4d026de808ca74a6d4ecdd7c4e662105bff6edb9fae0117c50aa053aef677c0750c7a446edbb879110030758912e8fa666489d702d8fceb719963b24a256429bbcc869a1f4ab9de9db89263e3684d4daa1df2ed94bb59dde2abba63793e5f82aa2e4db83 001fb980aef64254aeb9bb613ff2fc6967503db4bc1f337882f1566cbeb57489cf32e34f310549f41cba1b951f487453c29753a184e33330e90d4b973d2e406c99a239a5c3f96233 89d678ba437811ce7f79d5eb783802dfd65422d9879b70fc83914ac8fe311db003412e8e297ded8e2154ac5b9cf42b2a15b4c91d2b546716d174436ce29c1e6adec2f58ddb12daaa83d16a1fdb2811dde4d51b42eef8fc1a5b5f05a8951a1d39 +40343935d9423ad30f3fb1832bb08a5d20ddb3a55b59057cd275320db4a5835471c96cfb7d67f41ef860cf5879897b8dcf307bd1a52a6226847b768ea38ff1858f59e64cd635b51e6863773cc6c64b363ec47ca39266422406264668415c189e2f92447ac4c63ee5d74e95d1e6af05016917ad237f482ea0b02aecadd370a8bb 01d96dc09dfaf602789c1dffa5c9ba130832badcf180429660daadf4cf1be5cca92fe9713173861670eebfe3a0ba25bcc76aecac60a756f07b69687e05c7e25984a39556469f62b4 866681b15a6bfbdb070e23e58d7dd235a8fe2f022554238273f1e41f05f08b7bde5d6a073c786e82538787d859bdfc7f03e753dc8e871f943adc249dd96d303ab2b23a85f1ab870888c064da20241ed55aa4392df8635669b3cd4586308a0ba8 +274567f8841183e68c4f6c6b36c5a52fb0e88492e4076b9cd768bf571facf39dad6affeb68941ee326ee461ce1f33c26e4bfb3c9e0cae8241fbcc14cc69c1af68701fd0be3def1e87b7d52b682ebbe1cc225c1bd177b0886e3698a06d0e410a1f92c9bdf7239189f6acde0d0653815a72987671b415d1e8a70e685d6e5b14c33 009d98b32c8eacd135ffb8e13223690ef02c0c1f29ea8b4da193502c8cb3f39f9eed608c02fd457f2fb685ec4595e8fc8f388d26778d225d2b18c9bc8b199d8b65c0d1a6af33854a 90c1ba8b8bbdea5ca27745555991b0aa9d51dc6d93d9c069b819c00ad2bc97484ac89cf969d81519091bd24540f6331500766ce76a4d9b3fa453f702da12e2251d3ae73e6b1f6121d7cdac36696bce95151cb6333c150ee789bda709764c54bb +d9c99b8da92d3c2e40dea3c4025dc37770e867c4d2746c4d726b6de24250591a586c166c88acb8ed340e161d4c81b9d14c919a1b06f1feb22c5ce5fca2693bdaf4994ac72c8983c87f331473fd094eccb3d5f3528e69d487562fb5a65c150a8217192f8aabfa7adcfd0b6916d5000248fbbddf1ca2f38e3d9ed2b388998b7cfc 004d873ac744c4f68bb044783ad69e1a733cb8b8f483f2695bbd90c4211282036ad7914a53b25c3e890c6824643cffbdc4138d7ff457e3fbb99387494eb5cf2bdf1ad243a3a1e644 b39430494cc295f6053a050965cf4086ad585f6295a8cd40cfe32037a3de15d4fd49db0368bf63f50f8c543f8fb4ff7e0c62442f95b4ed3e1bdf3aad44e03352c9d83642d5752618496d69284df32cb021b9daa4361862cc41b3c35fad49a866 +d2b88a01fa17703c99e5b867c645e98feec0d6d1afaa20a97b5fce9c23f0594460142af4e36a5739b8d26d3ba35a0263caa5429b4abba157f359fce701c43372500fd2ae1bc2ed80bfcaf8cab7016ff93d4a27f565b7e67fe7dde22bf02c48be12114fbff2421517c825019c0ccc72d927bef156140d7f0e9b6ee37af78c3efa 018d2eb947297a054f8a789771dd875b12b26ef057fb91235dff3b062916f85aab3365609bd2a38a861439c8514e33f174c198139354e63766942f605107cb1b9709b782622b295a 974d3a4efeac7c142ff065dc9f0a2bcf8d7ff34bea95f166a4a26757508ee9be50f932676b31bd20fa6008c1fc949723172de6ee87a531417239f7600c1a5a2d5bdfcb23dbfc28ca653826b2a0eb6b687fc7ca7c409e86de1e51675c60df3309 +a704a1428cc894f958774368979fe075353b56790555386e3b043dc6a2919b94a11c7f85883f46b4d47b324d349c28c667bf9a000daaca1d7191f2a0fd97a4867aa9f72422134a690625408a9ea4b723704690b69152655f9e9dd5fa3dd94814d97dd4f13e85c3f9bca769491c2461fbd17e28afac00bfa81371d5039013da8c 00594fc0b7a5cc0216d2e78eeeb6394c8225de795f4b73bec48b2f4ede185ba622b59a16dd3eedf8cf2c94f2ccd6dcd205f64c97cf1b7f1e34129e94b5129502909f43940dba0746 8a855c3c9379b299354f1e9cc7ab7c121ca8135066297a61ebb18fa21f312d76ff33df3d92bf60f2a48f18b8d67ab3ff0bd39c13a1c71e6b9a696123120c02fe4dd6ec377295f3480f60ad0200e3bbb9116213d45cde4910c18b2bdcf5e34fe3 +f8a87c4acadee27a908718461e3b45060ae4ebb009b10a15926460bf219cb7e75dc3a993fb9a741b94e2fd71615c50f6df958568f452b2cc284f0516816bc0d2e2d45f663155660a26326f63f4aa42a6e1cc8462a2ec620a365257ec042f55e4047b62af689592a1a072553ff174dd629a4f51837780ca232cf479a68c1ebdda 00f000631106c5851e8ae0802b01e7a8a8540b427a8a3956a1d36f0600be89318032320cc420931d825cc964e823745c60aad3437ebc1c91d32004472e9677605fb708e5a71a0d83 aea3963d78487c99a21b03895e28c27dd556110799e37be11f0a208c5b61e3557b382f82972d89be30f9ab9797db5d5d18cac18e4246eac69697d0ae5288376216d2726bd3c4b93dba6a00fc13db00be7ab444b761b291896b072b59ca312521 +10b5438294a77c7e517ecfe8f8cd58d75297b14116aa93e574996ec4acb21837e6297cc0e7e7b5861e862062f192f2206a01b1caf42c6d7181d02c7d62b76c2881f8479449b02d32c6f792714d8f70f0c75e81c7d9abb996be87f5ad9a01fe42b75855558d5f00df392b62ae0d258f3f67dbeaf07208952e679a2c573aca941b 01023997206341c6147c536d034a9c38b4012035dc2c9b7ef0bb9cfe65e7d788296f055d508a1fd957b2dc7f9eb10c27790f15f30d81670945e54a508c57b70b46b4a09f4c769289 985ea8cbb6671673bf7882fb174a23762a986d20600e746a7a33b24606d3a270f86d93c956e03df401e79ebca94d09ec19be04d88455de672ff3f5e5a90a696b4d3dafba65c7b239f9ed90490b116dd76aa1a7ced26d2032807ec70f40ba88ba +d83a52d43216fdb16b1b40469863ca8eff4df9fa358deccb5ffd18b3e22a9d654aedc98f3dbdc4f5b4e56b4299e25d8a5a38d01b34eb93de382df1ae4d1c7f966e84b84c393d167aecc6f1192c4b42cae83748b1ee3d9147ce7de74cebd122695b455e8082f86e3e488fb0f51b3b7edcd579940d1cb9d045296e5e38f201b7ef 011ebf320ecf6a908ea5b868afb8e22246ce84e743e1076d6185ec65dd79043380708bf8da4ba802c3b93b8d15509bb7d7de9dc29f1e9fb0f0f2cb97a26698f955b1f7ef668122be 8edb6e1de9ccdfc78a1437f83a9f582a4c19307abae2309439e65c80c2f9cb32bddb1be31052b21ea3d0549361afa0d20777fcd64f4ef1ece780474b61022e48656900812bec563ac70afcba1f2b605e9635e1adb2ff040f00a2f1bd7e0f6808 +eddf5553ed4db6e8ce72cbcb59fb1eb80671c884ebd68e24bd7abe98bb1f40806de646f4d509be50a3fabfa85c5630905ce81abfad8a55f4cd80208afffb9056bc67d9dd7f4660a5f924af2a3745eec2daec39a3fe36131fe9eea444b92d31f6a125f12125159ba095f89968a7028549466f41ad45668a861f671050d2a6f343 00746d5c824d78f42a1fd63d8fcca61f154ba3e75788b7a0b87f53e5420e23a935b02eaf67bace8dd8a8e7c1caee30154c2428e0a437cf12e235f41c416f92fb54528865fd4766d1 880ecc847069ba5f0f27da3721b101d5966fd76c633c0bc76f4b8217a56f01364806b062c9d3ae21c6cb594b64673bbf0b18476f026828c9a5b8e1ec22b3a468eb918e2ffb6b13ae4334d70916751cd1a27abe9d71cd46d4412e9c78ee94e9b1 +3db94335f6d1a125309622c0a9d71bde1da09371f0285a93bd0aac255fa8f10a56074e0f6057f1b1aecf2d86a2319590ead96a2ad1336fe844e09339b456be32374ba2e659fbe9d0f2cdd83444d117d2ce3204ce4b4294dd05405634b84747ffb4227160c4e5c2c9da9815b0c6d20f55705f16cdbaa13d107ae666d707ccbe6c 000670e72ac2de50dd2cdd975a6cdab10ac45e37ef7a28c685d77447051496b5e161f8b1b93f6c7f32fce8ea05e94ed35fd7cb28c44bf51ea29cbaf5aaa31d6abca30a89430323dc 84bd5b369357cdabb1069ce321dde2116534b722fa9ceb77e42a4465cce1cf92a34a80908f09ca5b6d38573feae34def1240a79996cd93e754c0813398524b4b17367bb9979c9069603de31c82ac6afd99084acf7584760a95b22c6950c2f277 +69166ba40768d0a3930325405edfd85f3272f7b8e600b0b319f070274c91f9f03d0e6ec4bfc7b4445e91b87cecabfecf5e77c7301ee3c6b0affca2fa02c92216698705eb75443eecc25438db2d2fb4b24f4195d6b9c05c53e0868d3e58477100607ffdc31b18c40b4ad7202bb034e58653daec0f6b33c024d42a3fc84bd8f86b 00369a3bb96f884983c23281bcd04e24a3e5f6359f81e3c8e46f3f6b865eb6bdf98a630e90646275c587e41b546d3ca7688cc207afda15cf9b25cf83bd6ad27908647f3f9de59de7 b842446cd05edbdd8dfda6ee7fe5a9139962c95f7681d9e1705ca1131104ddeb86b6ca45e4a4d8e59a97ec0eab2fd9240f70dd79284e70475bf8f5fe5ef47784f6b349ac90d12f25dc27adff732ed0ded2741cd4e1e6e9a4f10330770f8aa878 +f64cb668b72f1e6dd026a478505c0eb33446ae9a2993bc7648aaed02e172fa9a0e05eeec61e756ba246c1dad7e85d3f01baf734b1905c5bbd1b08d833c2cf1e079eca75b866d705c407eea8618d23ebbaf269c7185984b3bd4117ecfb295ee6b47eecc8d3a78bb96552f6be314656f91caff793838226662c75cd7804b6bef79 0026717b039df834855511815d5665ff9b654facab469390ae257b7f0eb4dfe66ea0dc037242ed0c13bf229b8f7ff26da9b55fe4750d3451c62804aad493c179ae45d08ece5af085 907a7f1d1da4e7b6ce05ade2de79345775e893632d7f781d762704142cb5132e6497401748a7c0cabffef6ea1cea7e5c096383b2b39717e42c04fb63955b6a170edb1a1a6bc2600e3e62f14d1ce284d314ad8e265bb7aa3817fc3008645554c7 +51ee0b98eb6a3e3c1afcb35a33697c048dbf61374629ac5702a57801fafbea4d6fa5a26c9d1b79d1c58257ac0106387fab2d4a1b7f8c0dadcbe7c830613531b3c209bc17f792bdba1c1fae1b7528aac53dc86c2094b40194577325c05d2258303a2d17c854e7449489c43991b6877a50692a6340a528a6b188440ac0cddd4c4b 01d642f2d393ed4abea37173e4a79534af87adf534ead4a0a1c46fb047619221e3577e6b8bcc776114d01159c736ab78af3e53feac339d7afe58be8e7a8ed290f1dad960f1b5de94 a3c601e92e18e6dbd592133f50c66fbbf2cd06f24a4572cd7f1b856959301d1bbf768743d0301a4c2aceb5b4a7f97d100c9ebc86dafb629db44e5bcba8af84796fc9ecc9af17955178e9039cc6ef6dcc8b0ea3f0056ccd83a6bd4e58df9b2e25 +feee50aeacaccb6b1c3d95c6524044edb78322ee836d8159c4a4c2cc6982480567c4c6cc4806a564876622266e1ebd45f2f4be851b79da025bd57d0e6acce1ec1c8c255eb89713a1e4897d4ee0f7a248b9d4bd3ad5dc0e57f60ebfb65691e164bc908956a019083e923cfd33dcf37c735af3462768a1e14a8051d7aee74d5228 008cb70be29e83f697a3e2f67d86f1c1ec9a163b5335cb4a06004b6634948bf60b8ad9df9b27d2bedc4975265ce44a7884e57082d521320ca4372d38fc77b18d3fa05ad8aa5c43d6 af9be39a52e3bc42ccf0943a839a807dea8bc668222d5bb0091dc2d861444829e953c7b56782d5bc04de5c5de62850780d795faedab83f0773f9cd09ec7ba5930ed20a16a40e73e119109d64f6503b9d4a61ccadebdd61589d42e6e5909c7216 +b115f7370d6a93a90fd9dfdfb292956be34b61992ce1fa5627c5e928d74bcdeea66d4040c473306a0070fa8363c4303bea32f73ea3639b5c6676fa5a1d68a2cc1f91f00580d7453a23ae70af4cb1f1657aa82c5b305374effe5d67d559e46a6cee6360503d21070506f1af30bb000d2f2f85caa6465810f89968f33abae81cb3 01eef463771f9c6285f3257691dea0844687606d4dd00b6020517f190891cc1be97cfad21d147ed8881b5a6e19b22ceeae30e1132476325f2de0e9af2e14c80b8c780a9d2d6c96de a118fb09274582d4f9ba0cd092b99193392088cdf5236995f522bb9eb7b082212eef65844db5967ec8f767e51a829b8317e1c0e27d4db7f50d71282f2375d5a5d7f0598f18a702f7dbb726c60bef6aabac678dcd9d7dd9f53811e92b74a2574a +726782eb0d9720daa64e4a77b5d8dd67a1a193f15eb6b5162e3d89c925ba63b7c7e1c4bfc8d6f11915b0e14d16ab53ab015317bd5958b0beb6074199e05181915496575768d026c23e92e06016598de008c3718aaabcda8b68bebca0a73ecfc7327e8d3646106b7d114dabc46cfe56265c326ee56fd2ca87abb5bed8f997c735 013bd452b0880b101df1aa65724fb60d5d85b37ed5419027481661a3617e0fb37bda1151b9b5b41f908ba832011f7850b75a07b678e5b8cb35c5fc8b94a625e4398cd5ada2b04cc9 b0d843880a4a1763432f23411bd3e531db079b80e8e07124e8a655b0e94f75dd454fb491e73676c37c3aa723ff3bb59219c15bde0be6d68384af73047d73d84fee8bede988a84667b4bf146e7ac239463b28f08671da2d8c6af3c9e3e808bec1 +1c2418243fcd89c6382b7c3b2a8c341f26d08174a9e9296c4a5c98c5793a0fa48dce51e30811a96b515aa22bf9af89a43de06d696be1e531c5dece1f69fa6ecb7f20be063c602a16454ddafb14385ae3f8246c3f989d0566e06e7ed1864502896ea19df8393259c4dab3b3380a4a80b4103cbef4f38cb69198b7cf74ce94883b 01288141ec2244e4bb3f62daf4ee588aed09ce22be55e3d42e9085a947c1f8cd16533635d170bd64ae0b417346fa4670c25d41387acb2a8e14407a1931d9f7c5358a14eca40974bb a38ef4097c96517cd820be08bd6421ad22d11fa6203d249cf0e2588a7ace1998468b48a42ab289d0011826e1269396da1138afa9fbbb233abc8fcf40381819b9eea8524c601081d37a8ae236e5658aa83788023def170bcf8e5d834073d73c7e +1de4b642ec7220c64b91561caed7832044d6e811ac909f3b199cceb0d8a7db91bcdc801412044f5c34b355b95a2c6170fe497f6d5259bc20715a38cb0341c88e93029137e94d895bab464bca6568b852340a5c5d6a225475f6eefe2fc71ffa42f857d9bab768ccaf4793c80c4751a5583269ddcfccf8283c46a1b34d84463e61 001fe06b94a27d551d409b0eb9db0b163fadcf0486e2a6074bafe167f9a3b4ce8ac11f42cf72f9a1833a126b9473163d29bca2ad139dd1a5e7fedf54798bf56507326fae73a3e9a2 b88a2dfdb58fe7655e1e1fa3ca32f2a496ed93c755d2ec6723e30ec522dd7eeb792182a9ec5d2d7c7e3ff328f69de4f716a9ea622f31f076ce850bdf7cbaf651c2c6d3e886fea3dd3bbd93db87a4dfc6c91005ec89b19469626024db48aa60f0 +70279be7d7ac72a32606642ecd81b5d4d0f95fbc3c0b07d85c16adf2788601e44dedb8e55e0f9e0b4ca3ca35f5be7511b0e69224a05204af67aae11ce154af6d594d47f6e3142ad183969544aa95cae1edf42bc699137f60178c12b10a67698e37ab9f3edbfb3acdf1b3513d62fe3db33b16cbb4e1f9dfe732c107f9d0c953f6 009cdc7e4945c485a41728f83d5188f539e372ff4fe38fffcaacbcb4522428e4f93ef4972556f4398fe17bdd885768f0fb5590df495badc794d4d274e22f2f4a2535555922fa43f9 850cb627c572c63b5b17a43641651ab7513716d3ba466108a9c4d8d828b2ac4686e948ae7eb8ce284a05076eef3134320a4e5a71f4007b9d56baf77b8bac13db0d14df1f1d74b70b8469461fd1d4aaf04e86dc79947800bf960f5fef0f76971b +4d7e0ad520445b6a5cb46b7c77fbd367614044ae6004494c2b3a89089287e2836c73b799cd8c90139eac427ebe335804c3788f3728ffb8edd7f49a4bcc76a9e24ce3c2299cea88c04645b82033115380f81b0c1d823e470631008d350cf0c0dba1915519985b8a389ccd8c809dbd5bb5051a79e631916e0d052d9b6cca18e0ef 002bc753d007c4491cfb8ce0a6c96455acd16d37e02c982db216b8cc1afd6d10c6be4e15a3988b8b8b86b2b5b59a5c1939889024849317f27ee08a06bd8e7524d4ad83a1de208564 b899e7ebad4618edb98524563253a6b2e92dbb144a8382cc90823bc238360fef2880cb4aa37bbf1eb380cd3ab833fa92197e678a25895d41de16986e1797a65c9adda91852a328c7cf12438f63420b7528b054c7aba7ae84c79cadbcf5d18eee +d49903f38b5c9b17542310425e59377f61f5b4f4740cd97371ee2116083f7758e69e7e2c1b0950ec6b76f96e3c91c721d6f2843afde8c7505a559c8a64bca2e665aa1131b75bdf86fb5b90581c7d3b61c2cff88f3fccf356ddf5ed282e27727be061b6925c51ea7f1a495f471dc8a5ca1a88bbe29e92338d3c9361460398965a 002082c6e61d0d72f040905d8c1c20d47b029f41ec68d6cbf43ce97c3b2a0a770557a33cb803c432cfbd3958fda30ec1bba77a6613c318597a85ad02b26c44bb77ca96d9cc1194ea 9970c2ac9eeb9a4f69631fcaebd39ae578790bcc29ca6204b9d8764529fe41dba6596a1f93cee7d1cbfb4822998ee8c0122bcfd587dd288749e067a321cd765fdc5b1188c293b4b26e323b2cd8fbd058c55b56942010ec81f950f6e6a0a988ee +0e3f4afc3e7b25c1bf2d98098a5a87db1224d9bb45adc6e434732b8722a708ab80a1f3f6ef3c5aa70d2e1dad3e4416b12cc59171f05736c4b58bd084602c344f2f0bf3cfdcfe04c64e87597a99de23ded64b33607f7c273ec321f6462518715b11e91361e89ce5415bfc2ef520bfec378244a3bd2a4b9b6b3d68815f2f75baf6 00e298c93351323e2c5304015a4878997ae4e79d1c32f1dc64262e534d4f2c4b3e222356ffce746763373fdfb936fd330d3214a18c07f1205b20c9a941331cd676040ba1fe3dbce7 868f1b955fb8c1e95410770873031031f92b713e765ba23d16141c827a4c3ce84755f03abe32cb9fe7e19bda7f90b30d0bc1c70179989ab67526c16c6c4f488e9f17f6fc6ad21c90b5ba2db3fc5917f4abfee5828a0a7e2dc51293ea42279c28 +8fe32671f6927272fd3cd8dd4e34d44d27fac8c88b41bf9a48039e914990bf06d1633b38b9200ce1c2a275b9c55498e5da2d0707322c3ea0a0fd7aff598fb801628264e13047c8008153e8595a0dc95d54e70b882ac2ac9314d2b78e7b93922da818d7075215e354708994af66958954c92c074d132dbb2488e5a531c755a8e2 0104f4ad56594c5cec2a988c5596d73adaa5a81802b40110dbae698ddb1f0b271fd1479c38abcdb9b234e69cd0da8a0328d2135c287d5b130a09fa0b899058e7800eb2dfcee95c1a 94160f6474fd0d09b0492681f492d9351950cc1fe0014fe31b097d9578b341390e99ad8e73f52be3bff8ac5df7a86fd81495fcdebb1de37793b0fed5d5844f5f61484606f9fd2377ae26d9a39bbfdbc9696606cb815ab37a8f3fb2d3228c7850 +a8fa01136a0a78313a5d160c32fe5d1805eeb3730c18ca0c47818e82c48eb4c9e5b2dfe3ee5facef9ec59b68f4e6f3213f77fba9f8ba06dcde546ae348d343233883894f4423331b536f62373a495852977a51cb192cfbec04b5582b4ece69f345979e234de32da7a120138a057a7119735c4cb19099bf48bb202e7ffac04def 00c4989bf33b3136bcb4ba67906eaff2bcbc6567635aa4b057acb7353ee87ba3cb4cb9838f8f679729d5c6ed98e6c4199cf58605f009c6873a1b8321f83cd3c0973b7a3cfd9dbaa5 9673a5ee56d5b063d4fc555b03dc6dd1d43a01b9be17dd171961d9590c09badec9f5d947ad6013dff76de6bcb48e450a13e0e38e13041b2167986600bbe7a5b0a696772cebc4c72966a5571e5716ef702960d4b022b894c6e2cbf94103324fd3 +ba2d83b21c783d6ef2f3b7b10e910a418a9b9f49ae0fd37990335b3a3d15627846c9a12a1f31a3d0e062ad1bec5650606ed4dd06c30e50c1e8761a29f4ea1a20f74635d5dac22e5b787ac10f4ee82b338a641484f91771c128c84d31cdab0a6b9616078c898665655ee9dd4ae73d33b94bf091b064928b959623aa71ff73b4db 01a96f2ad56e31397e236cafc108087479c9823589a5fbc3dc7488d0e5d1199cf245d7f21f524cc0e8b47feca14c93fb760e631434a91188b32965053942f3bd39b3714f9d6f1a11 a7ea634addccd8b5fb41eb9f3ddd92b873ff9e26917a83098e77ef5e1234f28284cf7035b07c74089c04a133b2e0660f120b71510abf89603726fc3e0f7a49355dd6f1ae08be37cc6e9d12ac9a3dc472115e418466bcfb7666ed33e405ca292f +ea2d5f4e9797bfc2f33f0fccaf530db2bdf8abcec00f09a0338eefdba318221ec0e050cad1a85c3f76b784c6e8c18da2b062f333eeff18b7b781e67d6d0a4368b8231a892e0f4103012348e5df53ac745e4d34e2cd1ee9369f97d4801ff485fc144b2007008036bbc07cb1c302a00054b54f3713919191e1d5052978c9c2895e 00c08ed8e0e0f8b0d0714b46a2164b933f8147692f18da97e5a108c44d5a5cf221cb50536e41832b83bff4026c6df156386235cf5e3e9a67b7cf9b2fa7707c5e0ff33a91601b8e34 b4dda408561f72885b1e1b235f91a5a6706e9fa8dfb4a1336c5c2a2584286ce0822a4b8acd06b82d3c75afa5f771a6d0109e304b65e3e31f637a1f5233809009399ca6a316cc0294d45aec901db70dd8e76f30114214fee9add706951e449512 +b2293b0a09f41decd9d8e637b1b08c2efe612f33c9c0beebb6e05033c6103b958f8aacd125d7c810b4c287349f5f922d2c6ed554be597fb8b3ba0e5a8c385ed8ae70d5ae19685298f20e8d844fb5ad98db12ba7e5f45baed9045c3e86b3cac9bd55b614b82fd075954fc59bfc6124cbd68edae988596575f379d8921b594c75d 0144090a0ee38cfa21fabcc24d35139a99656911ad4f6dbffb77dbe74e7993edfa9fd63d2c4f6bbdbc8ec21ba13c9f4a3576b5d6e3abeab5af5ac81b1f2bb6d4c42dde645d854d9c 97af0a41bf6486a3e3a5605f8650bf1e675e1164859f4dd9db26bd18e9a63e764ca1d589bcc8e259cd1f1986d9bdc6710d2acda826e00e0fd790116b49decfe69ddeb9f3e59494dda29eb9328a547839338e3f22e59fafe504ca6d9b95b15f8d +acce54270252e7d9e983c08c993cd6b7e3caf482a9149036afe4665bd3d0662a6818047187872862d5718b8ac063477f693caf1a9baa8bdf2f36d411a796f2b46ab56f66bc94924229f8264016d6769c85d9bbb7d6bb042fefdb8fde1be026b86af2017aacfe38c97309b4689b23fff94f1de880064f1d3ad9d74dc804c41f41 01df26b672b2e3617b6b6c631d3c6be0cb49c0a690de49643e0f416215bcdaefc03fa9c708471f1d87476d58c8f147517ec8a14aa945ef001fa01984d5c3d81f7083ea500558fef4 add2e6eae3b24bf4a8192f458582c780136acf999aabe7316f8401b24e6dfd3ad123af6bc1592e2859e3d3e55e980c8415eb32247d420d3dabc2631dea699bab433c9e4c8da1f3342c46aadeb5b298e303be75c0b49cb20c12c5364ce1be3070 +e25274ded4840df0d71d3369007118f002b83e2d375c78f7e29ade067db15cce21842611f3f015db2efec57da77cb9d16eb1e00a8c1444d48dfda569e29fca1ebf40a22fc646a9fd44460f0e473bde487634bfbdac2c312f66a1c2982c6fe76c54ac72b6c8cc9345e47cb319a974b3cc4bb40634df74b4ad7e18adfa9a71ddd5 0189918b832e9fa30161fdd927bfc267f6405335df3d66d225e17173af52a671138883bcb94c4403ca3e001fcf09ef4c6488934d6775af2b1da30a8f331579af2d0fbb530298d8f9 8f77f706aaf5bb52850dd69167eadd689aa35f0bae83b89ea383ead83b90603ff358b87a57c6e8b623b9df4bcece4ad713e8ff8a85948214df970107248a53d072c5a11ace8c35cceabee695d83693fe2e3478931dbe20f7805f29c584c919fc +d8a4aed87c316012482819b03a1d91691f2ad11a2f46082497ea8f64880d686891f7da550b2ac17199c657d4eb9d04d5cb8eaa180f743b87d23b1c86103f9e9bb60f4e19f0ff9d160f180aed7735130c03adb62502e69be5c624ed7bda2301f30580ae0921b02e103a638f5623c02c186e3bfe6ff134c762a2bcac1f879a9353 00bdcc175eca3a399b944eb0334ff33c4fd130999c8ac0e7b52ac5b774fbad53ccc3a31024f5262b2eecfeb2104b14bb244307effe3dbe8ed25686dbf46a42c4b6f8e34010ad826a 80bf25f958c8946e9f6fe5ff873cdd799407b8ca525f0c5f1bb5c0422853c0fe3f406f8c46eac5bc213baa51ef5fa5ac02097b9cfcec32ce0acc5244167cda27f53a49e9f407543d1df38d13a696555c8fe7e0f6aebdf5a34f3fe024868ba89d +acbaa5ffc4eee0850075c0e502a70cc7a897a919f5e7bca4e798385601a26f411fdae5466ba9f6b6d8d7f819a749b799fbf4a3bda9105063e74914e8583ed8b31ea4d22164bee6f14bf53afca269b901c80cb3265be32ffd4ca4bc4ddb83e11eff82ead6d75dc4aec8e5c67f35d58a8a156cd1c0351abdccc0c5396c8fbe6920 0007ab5a55a1d8ecb7f5dca2afdf9ef465569a4b0374716f604ad42a6e0271e934b09655e8e2529784b69b2894bb399b02aeeae30e9e7ae70a2a8e56b9e775bd978a04c728e3951e a12f9c52deac15b5cc447a69501752c08c843caf79e7ef97a2d87c6861eeb93610e6ff1a889a99d2bb2aa5775017f3330e33adb01bf345d462ae72d3760254e0f7a28d91d3977e19c63624b32002cff9af52de9791946d0e938f22b9e6d989fe +9a57b63a4f418404e8f5dcf3052b9bc04a4f6d2c33bde8651506d9cbc5542ffb9023292dea463111fb78913ccdcd182faabbff9164219b8900c7f9fb394f7d9678f77b18f8d58526ec64d7c1328953b983a7c416583e05a069cd76aefe26e5f5687b70abfbf9f58f052dc0863b4fc3bef805cc3bb05bf76a83235af9d6adfe66 01e7d4da72b1d82e17a066fe387f2a0a7fa4c60ab993ee09710531789186077f2f32b42ddda497d5fb57356383e1f96973df043307f0b6519430c3f0d40d62954032872fceb7dce9 91a04ef5bb40f686d4b5795877b6419f75673aee5f934e8dcbf067f807fb8ee1d2494d2b97775b18d65739522a0c1f78041adfa63c691992c4d9c6b0bb5ac87cb502a2490bb25bb2dcc73bc6a326d24fc599623fb4daa7b785b16983c594407b +97b79c76d9c637f51294369e0bb52c4189f2fd3bd0607f91834aa71b3555605a89ff68e84fb5bda603f502f620e14e8b0c7affefafa2f0b303009ee99653ae4550a05315e551dd12a4d8328279b8150d030b03c5650ed4f8d3ba7c3a5361f472f436b200b321e7863c771e20ddd7bdf739c51de3676f953a5501e4477aed1bd8 015b7271d4319db5743119c8103a7d4c6d57e9c62f3eb93762156d2ebd159980aa57cea948e416717d715a2e458851f1b2e9ad4172bbcc53861db29c3ee0ba8e82617a5866170847 84167fe9bc58fa6cec66e8161006aa961aa8b0c54dc840011f534cc41cfb533a8074e86f14961102590d39eb1b462d40101b71cb99d032a7f5fd80592bb2d0aa73a74709886ec940b70ea7225ba296b8f84605ac523badb83a8d3d29eea65a76 +564ad0e37c9c37a60872a4780a723d08d1159ddc77bd834d74c1025cdf3cbd5338c3fc07a904fcad9b979b2a2ceb1a0139af35e5112305fd662a57af6312624b9bdd3a64849f95f59a46ca8feb2ed56f87f258518947474c1729275c4d89b7dd286ed65f286cbac76002cc63b92a73ab6bd13c4adef282f32297e441bdd8fd36 007219ea7917d174a5386df985d0dca798ac9f8e215ab2f0003aee929a2dbd91e37fedead0ed95b1e8aabcf516bdf54337b4aff7ace4c6b3179f2e919a49db50a41c9d4d58d4f636 b28c509f309313e2414c8e1ae806e8e2c587bdeda80ecfb903f6ee5b0d10f8726ecfaeb9d89f67f489c3958876d4e9c60c62701fc0d1a5d742e4b5565f577c6ca88dd10c5938b84a90e6877d7e9f47b31aa36fb258fe97baf4c017d3e6b48e21 +072ed5b14754fddaf54e20da42432df49bef38f4a3b1841b2db457ff86c44880727aca945770adb41269df41fc17f6a687bcaffaa45a3e59070526ed53b8dc3b78cf9a80a85461eaf4b477e44d5ec4c2bab9c05aa747a5a520b35fd09e8b44539d060ba1c3470267e0dda111b15dbb587614a46e1e477127f963a16cf3a43ee5 00bc623152253da24bf8d752bd78aedf7d5f6a2f889453ccdec14e10753335ea8bea83fd181a1f3680ed50f2324fbeaadae160cc85831750e021f3e44121ea1b1efc29a7d0069479 80db00c29c7abcb145ef5f14248f09b3dc59dea28d4cf4b49315a7966d88ecff07d0f463d22e692494540b81cc44ab7d04821144b11feb619e2cee892f4b55184223c4a4d6d406528b5ab265894fe90c4f71367325479624507c27956994dced +e660dbdf3e61af39b83b95d3f1970f66d616f03273f7dddb98f768452b21cd39604a31cf80590d4a5e4b0d4917519e10fd325dd4ab7a52d70d154506329baefe0d5816f514ae109483122b4fa8fa1ebd7fdf1fc4e21e8d278a50c05d81c8f489596633d949c6c8fea96fe91430c01522a5afbd5042be8aa47da04581b2bd21cc 00645947d981d258f2954558c31022a3b6ba5fa7b675312f794cb61bfff1d9ce87267e4a1dacb7c8fc58624d31c85ebe22f80d26a620fed5df5bf38515e0903f0b69a606048197d8 89d9cb0ba93da1e54544d36f861c8ce20410e909eb9f61e5296a3d8531855df5582dbe0da992b62f40eb59e188ecd4c00f5ec314b3e0fb3182abf14fa265aa1748de3b4f8597a8197ed74f950ef03ccac96c631a4d02c1e535a98e32c2b58bba +8c9acbdc431565feae60e08bc7da113e12372ed373f1e1fdd581f98c8a7b0c79ac4aa42c7ffbc963fb4970fe26c5b5dd314b7051fe971c1186ebcb5650f7f7011a924de893f06961b8c75da7bff331847feead4abd2e8b9d6ecbedac18f4eac207b948e6e4215e4d5cb483e5c66ce7ad788cb89604d3a3e051539094079e7bdb 014cf93ca69d94ee8fbea0c8da9d76aea092b73073d8f5385b65c6dd4d567fe86bc2cfb8e8be890c3c6cd9abf7dc3a17eaecee3d7a9455887863e496c48dc3e47821bd3d825b6bed 8a613fd786b0ff5a1bc1a42037be5ca2561c86aae80fcc7bcccca07260e71fda23948d1f2167053c4144f55cad086e520e798669aa928cdbc5f64c0bfa2951bbff0a63207edeb85d3269d7a21b9e1de383562b163be0c5ad40dca61c7d577f87 +53ef87d6ac7b9698f40b3ea9f3442e7b64207b140b7f66f73fb7d5f8f98452d30a4e493b6c0e3268371e88e612b818d4d847f032ed4983817d020411a52d81fd2a17b58ebdec199d817c2a8ba77042bbd747a6fd4bcc7e844ea829fd8461b389aa0b5957d92962b6d4e86385a8fbca90b8fac40944607117e9a4ef6dccb8fc1e 0033feeaaaa28f16bfaf5ea9c7319cf4561ba4fc55327a8477b6cd58ef6ccad3962ee1f3edb243f3a04e7e49c8e23509fa2d63252adb186b8bc7e9255cd61fa9bc45242d42da3a68 809cb1ecc20a4b56f67fe753122802dd5109534cabf5703bfc8928b64482a1ce180698295639801a4cb939898652f89008c8c798c68c9226c3bf6faa8ebbddbd99a3b3cc850c89f07d95524e422c0b4f5df0b24104dc8ecede815d85109084c4 +dca1b7a9a313ead11c2d54739d9017ae27f9d08b3544e418aee862bb57e427636cb6aedda28e10f12aa15d2355f4f8ef112a86fec5dc46e6acef693cb8fc37c3e4885f3be3d3ab31ea4d73a0de904e95c7135a149f77b621d642f9bd8ba192d39cfc58b6f19a797c4f3b4f3a87054298e3ce5eda0ff7f44f8134c9a108285dfa 005613dfb53149bf5fdc4e08ccc1c752b0b66ab43aef2d008ed40f3df40fcbb2938d2c41e3ea2dd4428aeba9059a97efe5593119673866a19d27a2ee37dd357e22b6bc849e7e22cc 8fd690abf16f1fa6e0791a235818a86cfd8e9a52d825e731877f16dd0f5912df3d729410f57f24314bc36d9f6d636d4f0bb700a8dd131793ef42909c28580770a69736626b5717a7aa787be612a66b9e204503b1e3324b33c99c49befa8b0b6f +aff61d62c8f5c31bbb7d0a64a6ac589e918bbf2f13e7ad13abb9ac26405e267249a7c9922139bc28140833e10976b87e91cf28285274b2b48b63d24ac94c85c70fafa78f8ad05955c0ce6c02b841ee196dab12306e3e3d6138371217e2b474f7e67a80bbb78a47e374ffe2c9f86292e471c551da50d46e7b5c8331029f369767 011b92c8b72b86c51903387a65aa206988d443d1988253329ad3a89c902ff1ef8cf73b7f2e4aaa352443bcb833712d94c3e637ec12cbe4c2d4606878576b17fae1512fc77785b737 b0d7d3776988dbd803382ad7e25443dcd164b4290799a6f2716f4af5ed28af2c1c415085aed03b9cc62b6e88d2c23c93062b691589637b0197d6de52893ec4d258fca47480cda98b2f2e60a1bb0edb0af2207e3124997efbb2981ddf360ba1fe +721017294f17ef351e41256b57a64a79f3636628c4bcbe676ac9a2d96076b913dc4b246c9945183ec9bd2d251441b5101eac44e2fa1bef59dec03ccd7fa5accf3b7d094d68dcf78c8de4e2f19f56bf0dcb3b66b9421ec3f8b353b9fd74feb2e9affe0bf9aa421b6f03eeba3ffd58fba56b3ebd094880e50de01ee62a108a24cf 00c3c90d5ce4375a08b85575faa78ee6bbd9e5571ce5a90582042617b807339c282cdc3b003d82006264b1c08c20af4ad4549fbde53d262facb98d923d81b8eb6093374b6a1e84cb a92561cc6336f0b44edb3400ca5d65d9da958bac98bf0f47a8de7abe6a5a78d58adcd4590da03fb78bf00c4559887c2118c233cb1b0114877cc6d15519d5d2da900fbc452069c5efaea2d030b720bf3d88524ce3ac6c438aff55dee8b392da16 +e2d1f33681759adb7954bb5248b0db3c3885fea0d4c1c0c226eb1e6d2d3ef1b9ac281a0f1c2fe5175b67114b6a501e2426d1454bd5790dcbc4c232cf06b017de8a9bb39e6033f1edb5003e8de3b44cc3d6150c3c952afb442952483cc688908337b7c1a8b5c9da70937ccfa98b2b0098c530ff848010b8e8ee0a8d65283481a8 010f184c16228d9034271332178ed485d10b6aa76003efc160d63fea26fbbdf5552205ac7df0d8c852a1210cf0ba512f20b798827b36ad56b12a826fa7dc1db45aed264ca6822659 b465cf99a0d38a87e71ce451e88acaaabf0e349ab3acb58649c42f90d8cd5cde2a51e412d9555ec4e47c1a0eee8108f0003c28093825591ea40af91830b059ecff93f6500764288db92e7403f4d40dfabf658169cd37445374362593afc711d3 +414fc5d2bd56b30040e105cb891788792da595583b11b8fcc7320f40dbf64d9263532dc57344dd17573c95eedf851668b5d552e8796af205f3a0043af1a829fabc2e93d9af9091fdd9e0fcbcc9d6d9ec960aa60e4e2964c29a2f375400366480e513f63d124db7745847310e69a38c8455e4e602056a6a4a14a8694155e0a9bf 0181baf9d497159f837cba58a11ca435c442e5ca792ea559bff9f6a1f562c05bf6bb5914afbd1bcaea75b35f88bdd832314b249a5298622c89462344d3f28a44ba3d059df432fc71 956f42eda5085d03cae4ce6a56d53af57da5a71c585d13681478bd0313dbc16d0bf2fca74bb08244aaca917be7ac470b195f132819f7596bd10a7ffa1395126e21514b9d70e70a2253afd759c0f4ff38fea566cf306daddc797bb400a3d3572a +3b592cc8972a4782870e079b82a50f84b4c2d8ca90bd500d1ce5678982e266c391c556d8162ac3aab967154d072dbc0ba1dab5545cf2651753dee2881eca5abd412fe624bf3f9d17d33692d21ce23ad15ccffdfd250cb1949e73c9e40a64ebebb03852e92692dad1d7baef97fe109f35b7a492b343d4b643a4a7b1723eaecb64 0083fae86ab96bce99a53e50b7eecff38e4e25b21c4b0f6a4986915de245eae24f16b6a00a4db159ebc27f5a6a072da94ab6be5bf75f5eb3f75c4452bf4ea7014392eb1e02706fb4 8e659cff9fdbd9d7b1d447141199bd49f81854f1ed6ab38646157a9aadb406d5b69e21d55d4668838846d741f26e57ca0f50d7f1e1e461567fde54706a5dcd7892c49a04b039efdc17027e0c4250df2ce50970d3efa7f23cafdc8cad40cfe982 +0079a02cbab3dc02601fcb5c8607d555beef7cd71a66911ab6514a4ae21c5a9c0e166f8cf5fb198ec5a49a96e17cf041f35f00406b79270ebfe56dc6b8417d2529fd625686ffbc8f69685aefa2fd30a937c02f25b48be4679e6fde821de928b33b12470867def874bb8c7c8038ab6594346a2c44b39210d3610994ba60a05e06 01a663efa7bf4d8479bc535fad71e9b5e4f4281aec55967baa008ba17ac2f89cc3398d30573edef29d590fddce8cb157f655e92779f59e7a18d0327d02e7daf4c1216143b3688fed 82899e8d1e7a4faf4599588d1012fc45155961ceb671e4b407d039411c0d7d46a57443a6a3a004f411da1a9c94bcd33b03b5607f647ff6cb93bec515384cdf5fd75c850f9abbd92e9be2203bb13b5549e050c70d55f72e150d70f80c07df5003 +88573bd94ef50459814806efa868ebf92b066fbc2f7a4be9d2fa06b9dc1a72f72d783a6bcbc107b18a6314511bff217037a2252e7a5cd34cf9d5b2fe9c7846931f0133b2e95876cb800dc4ed7c4a4e4cc4f1195acf99fb0ec224b1f8fa8af71f72d390eca9d6be3879032a318734a63fec336c79035a43f70271def10c4955d3 00088d1a2c0219696a94337cd56516252b74139ea0733b17fdcbf7692c3e5f6c3989e5da2aaed7468e65a5d578571928ca273ec3b6aa72cd196f560f05095cdc8346e5d31c4c2e0c 92127abfbdf4fdd99cb23dced7d16c3bfc0c9cc2d5d1ecf572cddb300d7519b98c87d67d53417a1849e577c811332fcb0134c1aa45f3bf0767e68654d0becfc3136680ce31ae23d931671bb361057215424d5abe2eca458ab90a9f79cb7fc8fe +d0e02045ece6e338cc8ab41d4a064c982ccb1748c48fc2fe0a6f10bdc876094358a6a90a45facec798a83cc95c6795cf0f0d7c66b77e22cb114c1432bfdaa1485ff35b6a58107cac3b7e58cb4f6c87c68db60b751e78f1fdfa54b8923b98caad0a4f31226956d065c083ace5f1e9e91944dcca51879d782e40358d58ca758750 016cc8a0fd59455ed8d4de561fd518df2e008f7dfaa5f7f29ac2489a411e233917b43eb3ebe2596fc824be58871949545e667dbcf240dfb5e0c615ade0179d9ea2a1b1ebb8ab9384 a3a523312dcae961852efc407f040efef7b29d6b491e82fada79273973f3ee685b10da2c5e4e686ee06e0ecd2f64798116a2558f0da083cb23a3e9b0e2175750e6d5366e1005ba4fe25c08cb1a6b9f578fc326d07f9c2e4c0de51b43f0441a8e diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K571_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K571_blst new file mode 100644 index 000000000000..89f91df187ab --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_K571_blst @@ -0,0 +1,60 @@ +964ad0b5acc1c4db6674e86035139f179a9d5ec711b5bae57d2988456bb136d3aade7ac9ef10813e651ae4b9602308b071d75a934a6c012eb90c5eb9b2947b50fc97b1d36c5bf9eb13a7b06c94212c3dcdab402a563262298defff62b836ead1f78f9d20713710fb48115cc5045ba15140fbb4bdf516e4150d830d02cf30963d 019cf4f4d06825499949f9e0b442586fe1bfe3459813a2b92cd8de0f775a4735e02655702ead8e60824180761808d9e816d60bdb0238e1e8039ca7bb63c92e1cf8433ef447e64ead b0948b305aa89defb906ea35546270520f6f5b469b30afbcbcaf47739ab6578602a589ec1efd46af8456689a6579e41514a17599d037cc1fa62cc49896db9b8c9df747986910dd173ff0095d15c83f604349e943f7eeeec41326d49896c03c98 +baddec4794effa668cde267016dda67bc70b847919a9aa595f93ba9dc27354399ef7a607fbead31e57a8ce698beabb10f313d393980425e67cf95be45d512f00e950c0c5409573ddc3d556f23daf056259ee8914e860562a674311452fed780b3e0317a7fe93baa81fb98df3ae4328b28ad0ac8f8ea33efe24faee658ad026f6 0098521a732e72ed945a549afc92318fef7156ed1d1ed9bab93b581478cb2339eb32bcef705c9bf61cf2873ddbadff8ff3806740a2e30ce67d1807a8179dfd5d952e6f8a583baf81 b8abbd964f8f2e6682a496808e2649113a9d7c0335e5cb252d08047bfbe5e418e67c29bfeece2f0462ae130effe3d81b0c8239ec37bc120d3732e7273723c8f146c3d80ca0bb4a48ade0095fae01271865f923c76aa5a4a4d2f2eea03b74abdb +7ef7138fc657492d229054f8a50dcafcfcd1dc06f1c16640af3f658907e2969248b54416066eb119adbfa23b8dc578aef18bba79610b9cc109394b900a25e55a779230bb858b2ddd9499a7775d392328db9177aa9571c2f61dd52010b48502154e914a0c55a54edcc04a6713cf7bda8744a893926118b09df877d1a4f3d95e8c 00336fb21549e397a190beac38a1ee10f0551952da15f71e11dfda415e5ee08da2356f114d450c661f52b2b32cfc7b9be61732672691a079f0927989b7e9f4efe6095a242155b641 95676f9d74028e90ee3e7779e697823567ea6992a8a3db5578aea4b22cd0a6a3e8fd94c6ad188c28c68408965602ceaf03a26f62116c2183baaad391b28bf310a4f5598438d89413a863a65d2f5119013ff3fff1c9de1f9013bddeef1fab43a2 +d58e1ff1d49a471d0567ecf8f29173dab5fe5f6184ab4cdd095c231fa7b82551f99a482994a46c3d8ebc07297fc9e952a5dee7d5f199b119f6f8b250f8fba45701ac252db725e75c4da27ad77d59a4eac448e54a277986740dfee6596811e59afc9755e53d24b826c09e497e29e69a22bbc85be11763064e9ecad7ae66458ca0 00e287ebfd9ba294128cbd484fc5121d271cd33e685bb1804f09b40aaacf64b5a9f2cde9b30a4a02d3a9bda97d92f46bb8787b3c61f280b1e1a0680f1f0679d3bb34d53725d62e52 b3a6c9df93c47927c69d7656e089fb397c67b266f58c44a5821dd69c9ac4308244b2c588d1d5c3a5b8ede67581dff77207f151e252366e4ec3920536b84fbcaf86f5ccbc49ec13f93c95b4861f822d9e98c56d97e850373321f3fbc84f419c1e +4949ba765c14c31f68ee0ca26bb42ba2edee63537de4a6f5c42bbd862c21288d6ff48145260365193c6fd2b56dfb014da26b8a483776b717c6874f627c9a622154b824565b23e178240f53ee9748c45759ba5c035b584df0f09504e95eb9bce0301653aadb860bb25e6ea6b9606e0ec3bdb8089e6aa0d5763d331757490715f9 0149de496fa8f88b2741864d0c35b3df666b87179b7bd06cd426a45f13bc87ea9f50dea85e1fd02a532630e0e3a231cc3e7fbb7c7ba85b40cff1124e72c677c6a3ea6aa40ffc64b7 b2a0d010bb407fc9531bf5eb7fa227e563d4b2c4075efee3e7c03e80bb6ec409e636827665f43354c366a0bb76d83a91047638f2210ed5811055b5932c00ff4adc6e0d683b06d97ea96256f82c679ff254295402524ef224001aa40f90dc2c06 +5bc63e5c50b1650f0ed4a599960f1e4e11f6c151b2123fd71d9e3c44662312a74b6854290628e20b30eaba81555acb2fb49b640bdab2528619c7fcad0f2a2880c7ea232d427d7c935fba2313370fda8863a7e7e203d63ea15d0cfa083e716ce6068c63fa616ddc225c9e413e694cdf6b355cb1293af5d6cdea51168f5634e878 017605d7c5873d870462375d741b4bc6375f3d47f7f5e9d998917adf2137a81e63b66917b3dda8968930c4b850f2270eb3187fc756e2beeaa67fe0d73053e6cc0ff0004a21250551 92ff130aeb2774e107103c5464f44a520570b477b9690b54e02f1a72bd5c5a3ad71ce1e6c43a99e4ad445a2c78a517a7101fe3a89067028f357200f2facd9c1e6127db9db339e80ada76d5a0bcd1a11cce136cc1328cda15c3a4cc46ede25766 +610f6633718e49d232b3798654095e2efa0de11f41258b27aa01956480c870d901efa77e109d5f95f1f5101d3c90fc51312d9b3019d2e42e0067eed7b457dc7fbe5466923b62c83d7347e4dada571b57813bb9c21d5e308519b8eedb7a7706508ad04aa69698e03636eb30fd9fb363ef3a185756494ee01175b16847f5b68076 009214dc2da0967912c31995cb8f5bcf4bfa832c5a2d3610f3a9857e5eee7c77100d599d9ed003b4106013155dffd6c48859b846e45e0ddbc5fe24f4891c9b2df51407e9cddbd974 a37da4dc4be6f04c68d4de71984718f7a2f242be4b3745b22dfc7d47d242948c20f5efe4319b996969fb86bfb26a29a60b60341450b3435029d596b210ecd6286c0f954c084f3f607c5fdbb6c43a7fb77ad07d6663a48c38fb7b774a8466e292 +c548f0546cee0c0400401cd540a0aa9377f27ac64492e6baaf38e794db4df83e64ca3d83b67bbb46a6c269c04c2725287cce0dee984a0d468c9ce495a7e554a6835d72c7493bfe88dbd5a044a148c89001b8087fb03e57c2b7212d0b175d616333a9affd8a1802dd49ba9be3ab6c6d9f99a5578d26cc4707a5860c6c804d69ce 0042f2682e9ac8b76f3c0880e12c292524601dce9ea6982dcf68bfdb0d3fbfb50dc9229e54149ef09b95bbf624eb04ce1427077f30d8536be9f69970ddb449ca22ab8368d2689ed4 b425afb7b31c4c535a1dbf6b388e508d5708022d350c691e91f6d2bf2ae5022585987b62d806ea8e961c274dd0f669ad15eb4099181b90fa40b6835d46581992c19e731269737bf6eb9ef60bbde90a543d92941bdf9e848f75f3522d420a9a63 +9431c6c5237f6b4b35682a0c32f68752035c8b295a1763c5dbdfd73466cea64a00ecc11356d02d2a9211dc54548f5db1651e4471898402c887fbf45005a3bda271df0158c98319d4d6751b8ca6b07100182957d5fe0d97c4e2294406f83e9afcae4850bb089f2252490417b5afd8f07f4c795fa84c9c7cdcce26bd97273c0072 017ed9a9c75cf66528428e85b0f019e3488af8b893b12023ff1b4ca9c3691b74e594539afa0f4d7c3863d15399b862f15e27bb077392d6bbd546ddfd46728c75177338466eb2f4ff 99d6b6de1cba89d4f8beb312687f48b6add3dc39e7ba4b1325e71db5016a839e033169397fe81a6942da3937e77af00d123dd31f9cb595ebb6a39936a7e936f0524646271a12294feae445c44f7b444e3846191800cf395d14cc51a12e1c2d9b +417cd5f60416f17081d2c70e9a510114e08be83573bf9deae75fbc3095dffc8a7f7325f61f9d6565381710eda871388cb17619e4448836076338ee309a2bba5f737319002e259b4a875cce1bb97996101c9a7abe0278dcac203a712f0809eb3c4b85a9c380550ab0bbc5067a8edfa78abf03c09b5c08f21714e1022ebfcada4a 01bcc09b3f2f1d26ab9955bff7e8c0f85c8a61293511a196b53d7963f4a4503849c96fb4daa68c9852ad9185e01a35f0bf298e34a09ec352cb6da34f89a1f23e8ea27712a8f43aa7 8784953c3ebb36f0f6178b9b451fa16ece5be7c1bed2b50cd498fb3a0b1072af08b694571e0e1656ef453c17769532e608f113ad91d32799a6b84bada64a30409b64175419dcde1bf31db57b14042c0e87c957751d4df2a824aee480c6941065 +eced8c412a153a643ccd69596389f83b6a36880286f8aeede503452bef8305942d95734fb5733f37ffeceb1c2dae7b1396c3323de11089082745c28a1756f784423fa7ad68bbfbf0d93ff8b7ad62220500df6d6895788402c1f5c69c06dd9ef55e2401cf297184e411be87c1bba657f847208c0e750f94a3df92f253b377b4da 00ec52fc3d9c272ca80623e06b15c35f349b13548ef7ee400bbfa04196850b3b8cc7b239238c827f9b0a3160cd97969ce21d66752791f5896e0385b0527d4d77e4b9fc70f04d73b2 93fd08fa06b45d88b6d9275b79ce45384b0b2f0d6a8da68b47dafa65875bba32c90c7c5d927c341e081274a4365bc22d0b7565635605afbcdef7c1146eaa9fd91655b8808bbfc0f68ce30786a428a09b28699b0c21fa307e73a584c8d734f3cd +30e83ea39a92036e22b7bed7639eab5e5be1d00c20b4a9b9afa9a0d1653369cbef363c119cc6f921c8f84663949c8b8dc9b743ac2b1861a480476e9b64c8f333f34b6fa0e1ddf09d49618ee4f3c1f46751b5595f0aea413d4ca46f3c26b974b112cbe99c813a96a4423764c069454946f213c5f066ec38108f947abeeeb02fb8 006403de7627de22d1dcf6b8da5af62f9ec59ec065cc1ca1311bb98aa439a6d5985619b17c17a70f59e17cf180ea6828ef57f5f1f8ef05680a9fc12ab7faad5af61e4e11fb45d341 a345367276f5c2f96eb2831f356bcbcd51c4d990f296c0ca63fb82dc5cec274fbf587c5c30f9be8857590b557c6b25d7013e7f421293af1d3f3018434b93ec1942b956bdcafbe3708ceb756ea1adcf22bd4b8a99a765e1c8fb727fdd347a97d5 +3ed244dc16a5cb292db4b1433b0ca3226913f07377faa20c6c1402cb4d026de808ca74a6d4ecdd7c4e662105bff6edb9fae0117c50aa053aef677c0750c7a446edbb879110030758912e8fa666489d702d8fceb719963b24a256429bbcc869a1f4ab9de9db89263e3684d4daa1df2ed94bb59dde2abba63793e5f82aa2e4db83 001fb980aef64254aeb9bb613ff2fc6967503db4bc1f337882f1566cbeb57489cf32e34f310549f41cba1b951f487453c29753a184e33330e90d4b973d2e406c99a239a5c3f96233 8a761db9a8a18a3ffc7c365f5748c9999b1823627cc932cd858d2fc112c3160f31b2f61890fc688304ea8222139691b51960c1ab22c48ab33032574ec9ebfe2c267d4270e0be4bff3b6974b5dad4a7325f1df1a9a4c86f7aa7e4383fe7cfe59c +40343935d9423ad30f3fb1832bb08a5d20ddb3a55b59057cd275320db4a5835471c96cfb7d67f41ef860cf5879897b8dcf307bd1a52a6226847b768ea38ff1858f59e64cd635b51e6863773cc6c64b363ec47ca39266422406264668415c189e2f92447ac4c63ee5d74e95d1e6af05016917ad237f482ea0b02aecadd370a8bb 01d96dc09dfaf602789c1dffa5c9ba130832badcf180429660daadf4cf1be5cca92fe9713173861670eebfe3a0ba25bcc76aecac60a756f07b69687e05c7e25984a39556469f62b4 8c102c66b1f3e3cb645d7f25dc68d03b2df1c64a220dc3c2979cf8d92cf283363eee0441d1d74e41df6ee71642aad4690fbbc66370a9fc5c17ed346fed18bb1f3ab5cf0169cd3bc8a162371cf6cbcb9f343dc6036d4828eb5a43de67b7a804c4 +274567f8841183e68c4f6c6b36c5a52fb0e88492e4076b9cd768bf571facf39dad6affeb68941ee326ee461ce1f33c26e4bfb3c9e0cae8241fbcc14cc69c1af68701fd0be3def1e87b7d52b682ebbe1cc225c1bd177b0886e3698a06d0e410a1f92c9bdf7239189f6acde0d0653815a72987671b415d1e8a70e685d6e5b14c33 009d98b32c8eacd135ffb8e13223690ef02c0c1f29ea8b4da193502c8cb3f39f9eed608c02fd457f2fb685ec4595e8fc8f388d26778d225d2b18c9bc8b199d8b65c0d1a6af33854a b07e32e7bc4855caf776cc1ce0fdc94143a0daee8b26d087ea0bae0e5e0c3fd2f0247b5c00bad44b0a74d3cd32512c400f82caa384759b4ac236f60b749d1b2e76e3d9e1581072d35e4447336b4b6dbfb76f3be268a3768d2d04f43c6566dd17 +d9c99b8da92d3c2e40dea3c4025dc37770e867c4d2746c4d726b6de24250591a586c166c88acb8ed340e161d4c81b9d14c919a1b06f1feb22c5ce5fca2693bdaf4994ac72c8983c87f331473fd094eccb3d5f3528e69d487562fb5a65c150a8217192f8aabfa7adcfd0b6916d5000248fbbddf1ca2f38e3d9ed2b388998b7cfc 004d873ac744c4f68bb044783ad69e1a733cb8b8f483f2695bbd90c4211282036ad7914a53b25c3e890c6824643cffbdc4138d7ff457e3fbb99387494eb5cf2bdf1ad243a3a1e644 8dac61d9fdb25e35d03e168251afc5025662e66d35273e24fb71069102366b1926e3359ea487832b5775b959f7fde320162c25d437b1f105c3ac49e832e20484756d866630e1947bec1005c5080384a0c9680c40dd21ab344f24c60ee75a2e1f +d2b88a01fa17703c99e5b867c645e98feec0d6d1afaa20a97b5fce9c23f0594460142af4e36a5739b8d26d3ba35a0263caa5429b4abba157f359fce701c43372500fd2ae1bc2ed80bfcaf8cab7016ff93d4a27f565b7e67fe7dde22bf02c48be12114fbff2421517c825019c0ccc72d927bef156140d7f0e9b6ee37af78c3efa 018d2eb947297a054f8a789771dd875b12b26ef057fb91235dff3b062916f85aab3365609bd2a38a861439c8514e33f174c198139354e63766942f605107cb1b9709b782622b295a a8704cb61dac755185165a2b2f1c655267c9f29ccea0894a0773d0abaa52355fad588a1ebb5d73c7030935fc3fab44870a167cd319ba8d12959f6ac73ad85f59de27a247fbddc91ea6644ebba1ec05b5e32e433c57c8e1c9f53742c973e449d9 +a704a1428cc894f958774368979fe075353b56790555386e3b043dc6a2919b94a11c7f85883f46b4d47b324d349c28c667bf9a000daaca1d7191f2a0fd97a4867aa9f72422134a690625408a9ea4b723704690b69152655f9e9dd5fa3dd94814d97dd4f13e85c3f9bca769491c2461fbd17e28afac00bfa81371d5039013da8c 00594fc0b7a5cc0216d2e78eeeb6394c8225de795f4b73bec48b2f4ede185ba622b59a16dd3eedf8cf2c94f2ccd6dcd205f64c97cf1b7f1e34129e94b5129502909f43940dba0746 90425d59023ed65f200a63df883c928ac6b4d7bd909ffd2b650bab6348b135d75f84a01792af7e6dc750b3ceb21d890a06aa605658401249be0b3c99b7aeac2f3bc9e14b89eef66789b28061b51f1991d64cc5f54f78bd93b9bac9067c74defa +f8a87c4acadee27a908718461e3b45060ae4ebb009b10a15926460bf219cb7e75dc3a993fb9a741b94e2fd71615c50f6df958568f452b2cc284f0516816bc0d2e2d45f663155660a26326f63f4aa42a6e1cc8462a2ec620a365257ec042f55e4047b62af689592a1a072553ff174dd629a4f51837780ca232cf479a68c1ebdda 00f000631106c5851e8ae0802b01e7a8a8540b427a8a3956a1d36f0600be89318032320cc420931d825cc964e823745c60aad3437ebc1c91d32004472e9677605fb708e5a71a0d83 acdd8166e4f22cd1367fb46883aa7ea99b416cd65d5d5b684c605771d3f4556d31af91576550ec07ab78dc264ec8a8330fc7c98c53262f3601e21ce88f27e3d971573b5a4f6fb4351fd3de5e0a9e0a96cdd951afee49a1feaae2f157b5112215 +10b5438294a77c7e517ecfe8f8cd58d75297b14116aa93e574996ec4acb21837e6297cc0e7e7b5861e862062f192f2206a01b1caf42c6d7181d02c7d62b76c2881f8479449b02d32c6f792714d8f70f0c75e81c7d9abb996be87f5ad9a01fe42b75855558d5f00df392b62ae0d258f3f67dbeaf07208952e679a2c573aca941b 01023997206341c6147c536d034a9c38b4012035dc2c9b7ef0bb9cfe65e7d788296f055d508a1fd957b2dc7f9eb10c27790f15f30d81670945e54a508c57b70b46b4a09f4c769289 8fde3292fa1369e4793454684c8ae2a6ffa434d41af61ed52eb8080b87f3ea14e5686b7a2a733db79fe245e3b641d3bc05756bc61fb929e14e04e13517003c4a2131eaf0faa464c2e42724b167a43d4b5547d14ba19542d812e38ec01f346bb4 +d83a52d43216fdb16b1b40469863ca8eff4df9fa358deccb5ffd18b3e22a9d654aedc98f3dbdc4f5b4e56b4299e25d8a5a38d01b34eb93de382df1ae4d1c7f966e84b84c393d167aecc6f1192c4b42cae83748b1ee3d9147ce7de74cebd122695b455e8082f86e3e488fb0f51b3b7edcd579940d1cb9d045296e5e38f201b7ef 011ebf320ecf6a908ea5b868afb8e22246ce84e743e1076d6185ec65dd79043380708bf8da4ba802c3b93b8d15509bb7d7de9dc29f1e9fb0f0f2cb97a26698f955b1f7ef668122be b4e0e50f4e4e3efb2c065584031ffe3a15a04203a87a0ca5eb838fd859523e1b1780631d11df14898b7bf5384df8860217c5379ace486b33915a9527cd88494b558ccc90c3dd8993c8ed1901053a7aaabbae4abc2c0d7420019a04dcbab7e8a0 +eddf5553ed4db6e8ce72cbcb59fb1eb80671c884ebd68e24bd7abe98bb1f40806de646f4d509be50a3fabfa85c5630905ce81abfad8a55f4cd80208afffb9056bc67d9dd7f4660a5f924af2a3745eec2daec39a3fe36131fe9eea444b92d31f6a125f12125159ba095f89968a7028549466f41ad45668a861f671050d2a6f343 00746d5c824d78f42a1fd63d8fcca61f154ba3e75788b7a0b87f53e5420e23a935b02eaf67bace8dd8a8e7c1caee30154c2428e0a437cf12e235f41c416f92fb54528865fd4766d1 83a8249e1b5ab95a862e64980e2eb0877c43fdd824336216c36959885bb7be37467a3ad3ea56c6a115234176a1a7072a0de723782def70c78e3c5047741af80fb7af382e161b307f7a07f524ecc581f83b2d2c913798c6fc8ed4db028d4a25d1 +3db94335f6d1a125309622c0a9d71bde1da09371f0285a93bd0aac255fa8f10a56074e0f6057f1b1aecf2d86a2319590ead96a2ad1336fe844e09339b456be32374ba2e659fbe9d0f2cdd83444d117d2ce3204ce4b4294dd05405634b84747ffb4227160c4e5c2c9da9815b0c6d20f55705f16cdbaa13d107ae666d707ccbe6c 000670e72ac2de50dd2cdd975a6cdab10ac45e37ef7a28c685d77447051496b5e161f8b1b93f6c7f32fce8ea05e94ed35fd7cb28c44bf51ea29cbaf5aaa31d6abca30a89430323dc b22d9f4526999e10817e3e48145cbd7ab97c0d8c159a29a024d5e0c06ae19bedca0844a02bc3903d5448cb77741bf89004d0c7c54c9a06466b9752a09e9fa640c236431aa56e155fdd1ae22228e7d46d39c88f96cdc1b62ad8c77a7c88e5cbd1 +69166ba40768d0a3930325405edfd85f3272f7b8e600b0b319f070274c91f9f03d0e6ec4bfc7b4445e91b87cecabfecf5e77c7301ee3c6b0affca2fa02c92216698705eb75443eecc25438db2d2fb4b24f4195d6b9c05c53e0868d3e58477100607ffdc31b18c40b4ad7202bb034e58653daec0f6b33c024d42a3fc84bd8f86b 00369a3bb96f884983c23281bcd04e24a3e5f6359f81e3c8e46f3f6b865eb6bdf98a630e90646275c587e41b546d3ca7688cc207afda15cf9b25cf83bd6ad27908647f3f9de59de7 ab2cd45e49add1c3c204d96e0d10ddee8a836d5908dacab4b66ea1d5adb65edbbe0789c80ed62960806b82befb28a9a40a4581d04ef2b4351a140d8959bb3fe1af898f56fef797daf8026672aa8fe9dbf68029e4bb1d3e0cc3089a172d9fbbac +f64cb668b72f1e6dd026a478505c0eb33446ae9a2993bc7648aaed02e172fa9a0e05eeec61e756ba246c1dad7e85d3f01baf734b1905c5bbd1b08d833c2cf1e079eca75b866d705c407eea8618d23ebbaf269c7185984b3bd4117ecfb295ee6b47eecc8d3a78bb96552f6be314656f91caff793838226662c75cd7804b6bef79 0026717b039df834855511815d5665ff9b654facab469390ae257b7f0eb4dfe66ea0dc037242ed0c13bf229b8f7ff26da9b55fe4750d3451c62804aad493c179ae45d08ece5af085 899a500ee7c2a72445969c3f6eb71667acc9c2cf56a3cb29094ffbc5e57cadf9cb0ff3abd3ef9c63864bdfc674fcc3fe1880d00767bd8a95d624d7bf214fce908895f632ae276e445d17f016244c277c18cff697acc901ce71800aa16d446c5a +51ee0b98eb6a3e3c1afcb35a33697c048dbf61374629ac5702a57801fafbea4d6fa5a26c9d1b79d1c58257ac0106387fab2d4a1b7f8c0dadcbe7c830613531b3c209bc17f792bdba1c1fae1b7528aac53dc86c2094b40194577325c05d2258303a2d17c854e7449489c43991b6877a50692a6340a528a6b188440ac0cddd4c4b 01d642f2d393ed4abea37173e4a79534af87adf534ead4a0a1c46fb047619221e3577e6b8bcc776114d01159c736ab78af3e53feac339d7afe58be8e7a8ed290f1dad960f1b5de94 887b12e6f120f4ece615e2355f8bbdd7ef3731b0995fa00f3fd5e0e2bfdaf03a4d001a82c970e5b331849fe9d8af5c870edc3373fd64aa857dbb00cd4049d15ee8d6660ceee788f20a4a75056898748996bb0373f75c4888add5b8863537ab24 +feee50aeacaccb6b1c3d95c6524044edb78322ee836d8159c4a4c2cc6982480567c4c6cc4806a564876622266e1ebd45f2f4be851b79da025bd57d0e6acce1ec1c8c255eb89713a1e4897d4ee0f7a248b9d4bd3ad5dc0e57f60ebfb65691e164bc908956a019083e923cfd33dcf37c735af3462768a1e14a8051d7aee74d5228 008cb70be29e83f697a3e2f67d86f1c1ec9a163b5335cb4a06004b6634948bf60b8ad9df9b27d2bedc4975265ce44a7884e57082d521320ca4372d38fc77b18d3fa05ad8aa5c43d6 a2d5bc577b90cd5244f4078ccfd3ef7de33318bb2892e43f1a104486656cc1b7d3e8373fe74ee0098adb2ae777a13c3103de23fab0984bab69d1a8133ee17b81a059dd236d143d37eb9ad0a2546a6c3aa022fe1755c06e755e20967e02743e8f +b115f7370d6a93a90fd9dfdfb292956be34b61992ce1fa5627c5e928d74bcdeea66d4040c473306a0070fa8363c4303bea32f73ea3639b5c6676fa5a1d68a2cc1f91f00580d7453a23ae70af4cb1f1657aa82c5b305374effe5d67d559e46a6cee6360503d21070506f1af30bb000d2f2f85caa6465810f89968f33abae81cb3 01eef463771f9c6285f3257691dea0844687606d4dd00b6020517f190891cc1be97cfad21d147ed8881b5a6e19b22ceeae30e1132476325f2de0e9af2e14c80b8c780a9d2d6c96de b35935dcdd396c7f3cba5667ebae916c661fd16eb6c8d90515275e3da90b59a0c88c96985e0b4720ef57c37b81120af0175404d0880d26ee8c2b3a397a9f78e55b34cdfb38f6ff0719392191d5a8f20cd1a8de1d573cf435f684b455856f8a16 +726782eb0d9720daa64e4a77b5d8dd67a1a193f15eb6b5162e3d89c925ba63b7c7e1c4bfc8d6f11915b0e14d16ab53ab015317bd5958b0beb6074199e05181915496575768d026c23e92e06016598de008c3718aaabcda8b68bebca0a73ecfc7327e8d3646106b7d114dabc46cfe56265c326ee56fd2ca87abb5bed8f997c735 013bd452b0880b101df1aa65724fb60d5d85b37ed5419027481661a3617e0fb37bda1151b9b5b41f908ba832011f7850b75a07b678e5b8cb35c5fc8b94a625e4398cd5ada2b04cc9 87cdb2aeba12cf5d50722bdd9ba6d4ec9fba6a57c03327e15ba77f853d78b057313f36cff529fd5d80ba5c880dc9ab720ef820daecf1354235b4c8a0d5b3c6eda3fe05652efeb3636684317a0fcf3e42da4b35bbffd35770fd380db61fda26d1 +1c2418243fcd89c6382b7c3b2a8c341f26d08174a9e9296c4a5c98c5793a0fa48dce51e30811a96b515aa22bf9af89a43de06d696be1e531c5dece1f69fa6ecb7f20be063c602a16454ddafb14385ae3f8246c3f989d0566e06e7ed1864502896ea19df8393259c4dab3b3380a4a80b4103cbef4f38cb69198b7cf74ce94883b 01288141ec2244e4bb3f62daf4ee588aed09ce22be55e3d42e9085a947c1f8cd16533635d170bd64ae0b417346fa4670c25d41387acb2a8e14407a1931d9f7c5358a14eca40974bb aa55eb6c559b9f8f71d4f422e9d40c284ddc6deb34a5b6bccef984eb5bf4d0719ead77c1e01a5d78040a2e1b37cdecb60506d28d4b71c2e37a42155c1ee01adf8b992e29328fef9c7e8c417825f0e24f4fe3ad2d22ee20cf14f631118943643e +1de4b642ec7220c64b91561caed7832044d6e811ac909f3b199cceb0d8a7db91bcdc801412044f5c34b355b95a2c6170fe497f6d5259bc20715a38cb0341c88e93029137e94d895bab464bca6568b852340a5c5d6a225475f6eefe2fc71ffa42f857d9bab768ccaf4793c80c4751a5583269ddcfccf8283c46a1b34d84463e61 001fe06b94a27d551d409b0eb9db0b163fadcf0486e2a6074bafe167f9a3b4ce8ac11f42cf72f9a1833a126b9473163d29bca2ad139dd1a5e7fedf54798bf56507326fae73a3e9a2 aa97fc7ec6c11ea853fbd8f992275799fc73debe4876a97335ae2ed9926f016983c26c64e108c056ba7d9a5138f8ff25119e08f283aee638a415807a4b4bd86990e34308143e32c449b92277b2d3931da7d94738bb8df19a7d6116d5b8f91383 +70279be7d7ac72a32606642ecd81b5d4d0f95fbc3c0b07d85c16adf2788601e44dedb8e55e0f9e0b4ca3ca35f5be7511b0e69224a05204af67aae11ce154af6d594d47f6e3142ad183969544aa95cae1edf42bc699137f60178c12b10a67698e37ab9f3edbfb3acdf1b3513d62fe3db33b16cbb4e1f9dfe732c107f9d0c953f6 009cdc7e4945c485a41728f83d5188f539e372ff4fe38fffcaacbcb4522428e4f93ef4972556f4398fe17bdd885768f0fb5590df495badc794d4d274e22f2f4a2535555922fa43f9 9403dade291bdd502cb694aff2d7e872098f5cc4b666350cb53bd3f3b40859bdd91365f9a5a68081fae78ffcf23aa1cd08b64862e7eb0ce4018c8d9029e93245ce834aa949e1b29770d08e473b3e4d6f5bdf279e2d604c139794e5c4f4d461b2 +4d7e0ad520445b6a5cb46b7c77fbd367614044ae6004494c2b3a89089287e2836c73b799cd8c90139eac427ebe335804c3788f3728ffb8edd7f49a4bcc76a9e24ce3c2299cea88c04645b82033115380f81b0c1d823e470631008d350cf0c0dba1915519985b8a389ccd8c809dbd5bb5051a79e631916e0d052d9b6cca18e0ef 002bc753d007c4491cfb8ce0a6c96455acd16d37e02c982db216b8cc1afd6d10c6be4e15a3988b8b8b86b2b5b59a5c1939889024849317f27ee08a06bd8e7524d4ad83a1de208564 b09cd8b25741b6c7e797c4bc048a14553ef26dab2c26ffc1e5f13fd0da91f354506753f2208b48be45a8fa871a63cce415a419ce8100c419c0523fb274238b58a3c2837c77fcb095288971c94c74f0d6ec55bb8af89a8a9c8171ab74c6124025 +d49903f38b5c9b17542310425e59377f61f5b4f4740cd97371ee2116083f7758e69e7e2c1b0950ec6b76f96e3c91c721d6f2843afde8c7505a559c8a64bca2e665aa1131b75bdf86fb5b90581c7d3b61c2cff88f3fccf356ddf5ed282e27727be061b6925c51ea7f1a495f471dc8a5ca1a88bbe29e92338d3c9361460398965a 002082c6e61d0d72f040905d8c1c20d47b029f41ec68d6cbf43ce97c3b2a0a770557a33cb803c432cfbd3958fda30ec1bba77a6613c318597a85ad02b26c44bb77ca96d9cc1194ea 83ef3fe932d916f2023144f632e01055a2b5dac8897e73436e473cb53bfccc6ad7f347aade65c02f0d1af1ce7e8012700151baf7c19d3f1f37a427c0e258c23bd3a9273eb3cd8d74688763e83a021e431227a2bcb37af4a700f81686dbd729d5 +0e3f4afc3e7b25c1bf2d98098a5a87db1224d9bb45adc6e434732b8722a708ab80a1f3f6ef3c5aa70d2e1dad3e4416b12cc59171f05736c4b58bd084602c344f2f0bf3cfdcfe04c64e87597a99de23ded64b33607f7c273ec321f6462518715b11e91361e89ce5415bfc2ef520bfec378244a3bd2a4b9b6b3d68815f2f75baf6 00e298c93351323e2c5304015a4878997ae4e79d1c32f1dc64262e534d4f2c4b3e222356ffce746763373fdfb936fd330d3214a18c07f1205b20c9a941331cd676040ba1fe3dbce7 a4fcd0f9599c0008fcc108672ffb4e85291143c0275311813f934cd0df709613f2649086692e01f9a26c4ca8601651f315c6e13b12fb8a5e2fdf176f058ea3ab4851ce89b4a6b55ef7164de5449645175f5bf0cef54c54a95aa41395b41d3ab9 +8fe32671f6927272fd3cd8dd4e34d44d27fac8c88b41bf9a48039e914990bf06d1633b38b9200ce1c2a275b9c55498e5da2d0707322c3ea0a0fd7aff598fb801628264e13047c8008153e8595a0dc95d54e70b882ac2ac9314d2b78e7b93922da818d7075215e354708994af66958954c92c074d132dbb2488e5a531c755a8e2 0104f4ad56594c5cec2a988c5596d73adaa5a81802b40110dbae698ddb1f0b271fd1479c38abcdb9b234e69cd0da8a0328d2135c287d5b130a09fa0b899058e7800eb2dfcee95c1a ae95951108bb1e04ad8f2ed193dde8da93d7ab34fbac03506d17fee744829d1a530341746cd2666e45864df1a13c8a69188a38a28021436f89815d6e7abe5b43cbb83b0ce75135be364a63dcca7b4c82677132754b1f7f12344ba0861a5a88fe +a8fa01136a0a78313a5d160c32fe5d1805eeb3730c18ca0c47818e82c48eb4c9e5b2dfe3ee5facef9ec59b68f4e6f3213f77fba9f8ba06dcde546ae348d343233883894f4423331b536f62373a495852977a51cb192cfbec04b5582b4ece69f345979e234de32da7a120138a057a7119735c4cb19099bf48bb202e7ffac04def 00c4989bf33b3136bcb4ba67906eaff2bcbc6567635aa4b057acb7353ee87ba3cb4cb9838f8f679729d5c6ed98e6c4199cf58605f009c6873a1b8321f83cd3c0973b7a3cfd9dbaa5 8e4a90da3459da716e45147c410c138f94ebad0eef2560f6c8108db4b962bb185394fdfcd6b7fd85e673ef9469fe374517507343caebf2759b39f0691edc1417f8f8ea482c7751bec68263443284d7d2afaccd9ecd15edc14f280f5bcafc77cc +ba2d83b21c783d6ef2f3b7b10e910a418a9b9f49ae0fd37990335b3a3d15627846c9a12a1f31a3d0e062ad1bec5650606ed4dd06c30e50c1e8761a29f4ea1a20f74635d5dac22e5b787ac10f4ee82b338a641484f91771c128c84d31cdab0a6b9616078c898665655ee9dd4ae73d33b94bf091b064928b959623aa71ff73b4db 01a96f2ad56e31397e236cafc108087479c9823589a5fbc3dc7488d0e5d1199cf245d7f21f524cc0e8b47feca14c93fb760e631434a91188b32965053942f3bd39b3714f9d6f1a11 af110cf237338bdabfea8115e98b1bb31f5f87c5f8a6583dfa8865e73ca6eb8042c0baeaf681ee4487a6ca955954f06f00e3877d37c60f69ccfa92d65cf50564ae7520e1a2c00ff078f144cc79b4ca9b46e775818fe18040ae5aa53ee8586215 +ea2d5f4e9797bfc2f33f0fccaf530db2bdf8abcec00f09a0338eefdba318221ec0e050cad1a85c3f76b784c6e8c18da2b062f333eeff18b7b781e67d6d0a4368b8231a892e0f4103012348e5df53ac745e4d34e2cd1ee9369f97d4801ff485fc144b2007008036bbc07cb1c302a00054b54f3713919191e1d5052978c9c2895e 00c08ed8e0e0f8b0d0714b46a2164b933f8147692f18da97e5a108c44d5a5cf221cb50536e41832b83bff4026c6df156386235cf5e3e9a67b7cf9b2fa7707c5e0ff33a91601b8e34 8b7bd3d03be80260404ebc1810947a3f620d1812db2c2f3694302dfc6212178de5b2019bd841522cb943cfbf221b1c7c00328693a52dcb8b15bd684d1e98589fac745258c3327db9b7131304dcde263576374ceaf64c9c454ecbbcc73e25dac6 +b2293b0a09f41decd9d8e637b1b08c2efe612f33c9c0beebb6e05033c6103b958f8aacd125d7c810b4c287349f5f922d2c6ed554be597fb8b3ba0e5a8c385ed8ae70d5ae19685298f20e8d844fb5ad98db12ba7e5f45baed9045c3e86b3cac9bd55b614b82fd075954fc59bfc6124cbd68edae988596575f379d8921b594c75d 0144090a0ee38cfa21fabcc24d35139a99656911ad4f6dbffb77dbe74e7993edfa9fd63d2c4f6bbdbc8ec21ba13c9f4a3576b5d6e3abeab5af5ac81b1f2bb6d4c42dde645d854d9c a8e0fd1aab5db7aea1b258636c396d706dada3a8f73195c6cd7ebf69f28478ec7acc66d5278f92d1a346f89d090400ee0182edf4c6923711a30ef9f876911f8a2e3061a4b20e2dbe1d3d0479e8a20b175e974953302f64810fce12e2849b018e +acce54270252e7d9e983c08c993cd6b7e3caf482a9149036afe4665bd3d0662a6818047187872862d5718b8ac063477f693caf1a9baa8bdf2f36d411a796f2b46ab56f66bc94924229f8264016d6769c85d9bbb7d6bb042fefdb8fde1be026b86af2017aacfe38c97309b4689b23fff94f1de880064f1d3ad9d74dc804c41f41 01df26b672b2e3617b6b6c631d3c6be0cb49c0a690de49643e0f416215bcdaefc03fa9c708471f1d87476d58c8f147517ec8a14aa945ef001fa01984d5c3d81f7083ea500558fef4 924951dd5e45f34246b25967e4940deb811484b09dbce336c464d6b8c0ad2bfc01ef0b91ad07ef36aa91753c96a95cb5006ae6efb751226c5937964fef5974d76e883d54351c6e07a30b819bebdc8513d23f366d229af870208b3af75875e9c7 +e25274ded4840df0d71d3369007118f002b83e2d375c78f7e29ade067db15cce21842611f3f015db2efec57da77cb9d16eb1e00a8c1444d48dfda569e29fca1ebf40a22fc646a9fd44460f0e473bde487634bfbdac2c312f66a1c2982c6fe76c54ac72b6c8cc9345e47cb319a974b3cc4bb40634df74b4ad7e18adfa9a71ddd5 0189918b832e9fa30161fdd927bfc267f6405335df3d66d225e17173af52a671138883bcb94c4403ca3e001fcf09ef4c6488934d6775af2b1da30a8f331579af2d0fbb530298d8f9 927ea2a5bcb71a8ecf1d0f82ef1e5281e39b5ceab09ff90134b7cd0b0454fac0b3a8c1bce19e5f03ed9ca2a7e76ef807061724c957a2424981d1866cd6a1c5c1547a92004c2871f860f54f8c7f52ac4f2d24c6a932b5ec202237458e5e82dd34 +d8a4aed87c316012482819b03a1d91691f2ad11a2f46082497ea8f64880d686891f7da550b2ac17199c657d4eb9d04d5cb8eaa180f743b87d23b1c86103f9e9bb60f4e19f0ff9d160f180aed7735130c03adb62502e69be5c624ed7bda2301f30580ae0921b02e103a638f5623c02c186e3bfe6ff134c762a2bcac1f879a9353 00bdcc175eca3a399b944eb0334ff33c4fd130999c8ac0e7b52ac5b774fbad53ccc3a31024f5262b2eecfeb2104b14bb244307effe3dbe8ed25686dbf46a42c4b6f8e34010ad826a 8a5aad82ca177d511e8cdae6c9251ad6f43c29aea75f3ebcb562a5ae44ddacdf5c44cef568767a0af425b8ab0f44d7a21329ee575ea7589805e63cdf91e6a4e37521efc250fa84f1a3b39eb47b67313aa6e6c59292e6eb486aa342288f8f9122 +acbaa5ffc4eee0850075c0e502a70cc7a897a919f5e7bca4e798385601a26f411fdae5466ba9f6b6d8d7f819a749b799fbf4a3bda9105063e74914e8583ed8b31ea4d22164bee6f14bf53afca269b901c80cb3265be32ffd4ca4bc4ddb83e11eff82ead6d75dc4aec8e5c67f35d58a8a156cd1c0351abdccc0c5396c8fbe6920 0007ab5a55a1d8ecb7f5dca2afdf9ef465569a4b0374716f604ad42a6e0271e934b09655e8e2529784b69b2894bb399b02aeeae30e9e7ae70a2a8e56b9e775bd978a04c728e3951e 985a0fcc7407de8cd8656c82c4ddca44156bb3c1acad0ea73d06cfc03726847a8898057a27f61efb656fe99d33ee8d180f85a70c4e712fe8d8f76238911b061903e6190badc3f470593f6b77e820fe857f1d3612a98dced6e561683f47978b18 +9a57b63a4f418404e8f5dcf3052b9bc04a4f6d2c33bde8651506d9cbc5542ffb9023292dea463111fb78913ccdcd182faabbff9164219b8900c7f9fb394f7d9678f77b18f8d58526ec64d7c1328953b983a7c416583e05a069cd76aefe26e5f5687b70abfbf9f58f052dc0863b4fc3bef805cc3bb05bf76a83235af9d6adfe66 01e7d4da72b1d82e17a066fe387f2a0a7fa4c60ab993ee09710531789186077f2f32b42ddda497d5fb57356383e1f96973df043307f0b6519430c3f0d40d62954032872fceb7dce9 84aa695e819b78deea0410e99d4cee4c750f6efd461ee49bb582f7b344e18955f7379cdd16a892a3b5e473ecfe7db3e11923a97299ec5e31f2e79efe8ee1e9abe5c648bbb2515d87a947cc0a34d26c6bf97541eecbfd5605ecee1c08d712ce46 +97b79c76d9c637f51294369e0bb52c4189f2fd3bd0607f91834aa71b3555605a89ff68e84fb5bda603f502f620e14e8b0c7affefafa2f0b303009ee99653ae4550a05315e551dd12a4d8328279b8150d030b03c5650ed4f8d3ba7c3a5361f472f436b200b321e7863c771e20ddd7bdf739c51de3676f953a5501e4477aed1bd8 015b7271d4319db5743119c8103a7d4c6d57e9c62f3eb93762156d2ebd159980aa57cea948e416717d715a2e458851f1b2e9ad4172bbcc53861db29c3ee0ba8e82617a5866170847 9146ccb45e97df88fbe5b76ba3b0e14271a0c235d5f89a5257e92d3722cda259a19f23084eb508d481677aef18679bcb06ba0584ee4746664d1ab6a9ce3a365ae97bed637c638f919bafdc97995395e8a18b6e42ec131c8ea6d0c42e9d7586f7 +564ad0e37c9c37a60872a4780a723d08d1159ddc77bd834d74c1025cdf3cbd5338c3fc07a904fcad9b979b2a2ceb1a0139af35e5112305fd662a57af6312624b9bdd3a64849f95f59a46ca8feb2ed56f87f258518947474c1729275c4d89b7dd286ed65f286cbac76002cc63b92a73ab6bd13c4adef282f32297e441bdd8fd36 007219ea7917d174a5386df985d0dca798ac9f8e215ab2f0003aee929a2dbd91e37fedead0ed95b1e8aabcf516bdf54337b4aff7ace4c6b3179f2e919a49db50a41c9d4d58d4f636 92fe64a3da2078924e2796ad8b0f3acaf12dc9b4fd45e218159ec860f5785d0ae3d8e012e842011dba3029d3c9f1920d0fef2d5d3a1e0b6fd5d4aac3556c6ee9392d10aa834f92bb8044acfde7d5a70e9d5b120e0e56ac80b6b4378685992097 +072ed5b14754fddaf54e20da42432df49bef38f4a3b1841b2db457ff86c44880727aca945770adb41269df41fc17f6a687bcaffaa45a3e59070526ed53b8dc3b78cf9a80a85461eaf4b477e44d5ec4c2bab9c05aa747a5a520b35fd09e8b44539d060ba1c3470267e0dda111b15dbb587614a46e1e477127f963a16cf3a43ee5 00bc623152253da24bf8d752bd78aedf7d5f6a2f889453ccdec14e10753335ea8bea83fd181a1f3680ed50f2324fbeaadae160cc85831750e021f3e44121ea1b1efc29a7d0069479 987da29b96023bd866cc00124fead8f53fbc724372ef6469193ad1c3f244a0184d329ad63e2093a0664ae4cb2f5787e304acd8bb9076c96997d77697fe5cab41516156efc25412da51a8ea7f46c5a0e08267d8ebab27d55e10bfe5a6da320523 +e660dbdf3e61af39b83b95d3f1970f66d616f03273f7dddb98f768452b21cd39604a31cf80590d4a5e4b0d4917519e10fd325dd4ab7a52d70d154506329baefe0d5816f514ae109483122b4fa8fa1ebd7fdf1fc4e21e8d278a50c05d81c8f489596633d949c6c8fea96fe91430c01522a5afbd5042be8aa47da04581b2bd21cc 00645947d981d258f2954558c31022a3b6ba5fa7b675312f794cb61bfff1d9ce87267e4a1dacb7c8fc58624d31c85ebe22f80d26a620fed5df5bf38515e0903f0b69a606048197d8 afe895bcbf2566ae94f090be450cd6e9cd98490c46d804b1354fa7430f51accd2d33b498fc0bbb9ca2dacc4a31177a0f04accb29052b24e239a5de1f85160fa68654ea6b12f8125c41e8202e750e4b65a651c0d1730967f8e6253b3fc9423932 +8c9acbdc431565feae60e08bc7da113e12372ed373f1e1fdd581f98c8a7b0c79ac4aa42c7ffbc963fb4970fe26c5b5dd314b7051fe971c1186ebcb5650f7f7011a924de893f06961b8c75da7bff331847feead4abd2e8b9d6ecbedac18f4eac207b948e6e4215e4d5cb483e5c66ce7ad788cb89604d3a3e051539094079e7bdb 014cf93ca69d94ee8fbea0c8da9d76aea092b73073d8f5385b65c6dd4d567fe86bc2cfb8e8be890c3c6cd9abf7dc3a17eaecee3d7a9455887863e496c48dc3e47821bd3d825b6bed a7e6ad83f1c153f5937e7229df9d83ebd993c44a54a4586607107967c6e5f1c483a1857f1b67ab00351b5de761c8cb5c030c590a399891d5933081b89f95a524fa72a3cbb340270ea2e9490db86ff69ea5cfd7204697ed43c7d8a791155850c5 +53ef87d6ac7b9698f40b3ea9f3442e7b64207b140b7f66f73fb7d5f8f98452d30a4e493b6c0e3268371e88e612b818d4d847f032ed4983817d020411a52d81fd2a17b58ebdec199d817c2a8ba77042bbd747a6fd4bcc7e844ea829fd8461b389aa0b5957d92962b6d4e86385a8fbca90b8fac40944607117e9a4ef6dccb8fc1e 0033feeaaaa28f16bfaf5ea9c7319cf4561ba4fc55327a8477b6cd58ef6ccad3962ee1f3edb243f3a04e7e49c8e23509fa2d63252adb186b8bc7e9255cd61fa9bc45242d42da3a68 ab76265d052482b65c48bad54a214631f5841c07b158313145b2b6e91a232b845d41e8660d937aa5ea06bd6ebea0070615d9aeaabe5e4162e84bdeb72927cea5c4ac7e2f2c014acf63873069b48b5ac67b077a2f8586f9ee3f064709c8bd2103 +dca1b7a9a313ead11c2d54739d9017ae27f9d08b3544e418aee862bb57e427636cb6aedda28e10f12aa15d2355f4f8ef112a86fec5dc46e6acef693cb8fc37c3e4885f3be3d3ab31ea4d73a0de904e95c7135a149f77b621d642f9bd8ba192d39cfc58b6f19a797c4f3b4f3a87054298e3ce5eda0ff7f44f8134c9a108285dfa 005613dfb53149bf5fdc4e08ccc1c752b0b66ab43aef2d008ed40f3df40fcbb2938d2c41e3ea2dd4428aeba9059a97efe5593119673866a19d27a2ee37dd357e22b6bc849e7e22cc 82f64b230e6995c40535b6b7ac058e8a8e88aa1bb12da0cfa5150261b4125c239c41f75e6f9d217bc1477eef9e699e4606600d4c29144a7ead770b7b84181835e898f16254c132ceb01415494dc27a469be2f420b833a0d9e2f1c2364832cba3 +aff61d62c8f5c31bbb7d0a64a6ac589e918bbf2f13e7ad13abb9ac26405e267249a7c9922139bc28140833e10976b87e91cf28285274b2b48b63d24ac94c85c70fafa78f8ad05955c0ce6c02b841ee196dab12306e3e3d6138371217e2b474f7e67a80bbb78a47e374ffe2c9f86292e471c551da50d46e7b5c8331029f369767 011b92c8b72b86c51903387a65aa206988d443d1988253329ad3a89c902ff1ef8cf73b7f2e4aaa352443bcb833712d94c3e637ec12cbe4c2d4606878576b17fae1512fc77785b737 b77938eae35ad0602b0db9bb0345da83ed2600359989116e29afb2f998a22a09e621fbf348ca7c9b38036d4d120cb0050320908b3ff2f17c16ca9f479800670481e15712a611b2134fed2799dfd14337fee921ef8d8307b8e5f345f3cceace09 +721017294f17ef351e41256b57a64a79f3636628c4bcbe676ac9a2d96076b913dc4b246c9945183ec9bd2d251441b5101eac44e2fa1bef59dec03ccd7fa5accf3b7d094d68dcf78c8de4e2f19f56bf0dcb3b66b9421ec3f8b353b9fd74feb2e9affe0bf9aa421b6f03eeba3ffd58fba56b3ebd094880e50de01ee62a108a24cf 00c3c90d5ce4375a08b85575faa78ee6bbd9e5571ce5a90582042617b807339c282cdc3b003d82006264b1c08c20af4ad4549fbde53d262facb98d923d81b8eb6093374b6a1e84cb b9e78f03b1c9ff4094962c6d5a6283a336adae743361768d4e92fb29a5ca71321c66027f42309be819cfbb801915b69d0007f6a5440c99bc51af09c3232d0bbdf2d48e616970616ba3e0c66f6bf3f5ee93d8e0cdc13209feb9efc4e2f85b43bb +e2d1f33681759adb7954bb5248b0db3c3885fea0d4c1c0c226eb1e6d2d3ef1b9ac281a0f1c2fe5175b67114b6a501e2426d1454bd5790dcbc4c232cf06b017de8a9bb39e6033f1edb5003e8de3b44cc3d6150c3c952afb442952483cc688908337b7c1a8b5c9da70937ccfa98b2b0098c530ff848010b8e8ee0a8d65283481a8 010f184c16228d9034271332178ed485d10b6aa76003efc160d63fea26fbbdf5552205ac7df0d8c852a1210cf0ba512f20b798827b36ad56b12a826fa7dc1db45aed264ca6822659 90675aef6ea206a7ac3e625c4750c9082bb8c576e62f8d24ab2dec9f6fa701c62e9f5a78591a06581f38977e32dc50a5183f6539183010dbc9bcfed74020215f5a40ca99bf0381aa55ef84b131c328ec5d1ab940b74a1217bdb944fe2975d6f6 +414fc5d2bd56b30040e105cb891788792da595583b11b8fcc7320f40dbf64d9263532dc57344dd17573c95eedf851668b5d552e8796af205f3a0043af1a829fabc2e93d9af9091fdd9e0fcbcc9d6d9ec960aa60e4e2964c29a2f375400366480e513f63d124db7745847310e69a38c8455e4e602056a6a4a14a8694155e0a9bf 0181baf9d497159f837cba58a11ca435c442e5ca792ea559bff9f6a1f562c05bf6bb5914afbd1bcaea75b35f88bdd832314b249a5298622c89462344d3f28a44ba3d059df432fc71 890c1d442984b851c9bc2b82f00c3cf455f41f450d2fff277a581a676d2894a6d15eb638b224b455c9972932285b81c0024f78aa41483d2c31c022e57ba9f046eddab05a20daab54a81d05c80c845bcbe75f8054faeda0a42ec97fc22af0196d +3b592cc8972a4782870e079b82a50f84b4c2d8ca90bd500d1ce5678982e266c391c556d8162ac3aab967154d072dbc0ba1dab5545cf2651753dee2881eca5abd412fe624bf3f9d17d33692d21ce23ad15ccffdfd250cb1949e73c9e40a64ebebb03852e92692dad1d7baef97fe109f35b7a492b343d4b643a4a7b1723eaecb64 0083fae86ab96bce99a53e50b7eecff38e4e25b21c4b0f6a4986915de245eae24f16b6a00a4db159ebc27f5a6a072da94ab6be5bf75f5eb3f75c4452bf4ea7014392eb1e02706fb4 94e26f2e4f3fef1aa75041af23614ea2a935af91e7c342a7558a6167c0099fbc4eca067337a8f71a68951fbfa1212c90094eb430d78a3a8630f769139eb3ceedebf52a803ff8e85f7e16308da12bca6b631490191eb4afcc7abd4d6a54aba5e2 +0079a02cbab3dc02601fcb5c8607d555beef7cd71a66911ab6514a4ae21c5a9c0e166f8cf5fb198ec5a49a96e17cf041f35f00406b79270ebfe56dc6b8417d2529fd625686ffbc8f69685aefa2fd30a937c02f25b48be4679e6fde821de928b33b12470867def874bb8c7c8038ab6594346a2c44b39210d3610994ba60a05e06 01a663efa7bf4d8479bc535fad71e9b5e4f4281aec55967baa008ba17ac2f89cc3398d30573edef29d590fddce8cb157f655e92779f59e7a18d0327d02e7daf4c1216143b3688fed 8cab0dc91b5d73f5aac5e9e40aca389be111bfaf000d12c5a5a73795049bb1dfb6dcf1861aef477726203a66e2bc078e14915a968911d2530230b458380bcd60f7fe8675915d8fc2f7bfae761cffde1f12f47553cf05299d0a900cd185c51c0b +88573bd94ef50459814806efa868ebf92b066fbc2f7a4be9d2fa06b9dc1a72f72d783a6bcbc107b18a6314511bff217037a2252e7a5cd34cf9d5b2fe9c7846931f0133b2e95876cb800dc4ed7c4a4e4cc4f1195acf99fb0ec224b1f8fa8af71f72d390eca9d6be3879032a318734a63fec336c79035a43f70271def10c4955d3 00088d1a2c0219696a94337cd56516252b74139ea0733b17fdcbf7692c3e5f6c3989e5da2aaed7468e65a5d578571928ca273ec3b6aa72cd196f560f05095cdc8346e5d31c4c2e0c 999ff073bbc633b4eb39d6746a0d30e3dbfa8fd85926f4146bd59800c5b9c3222c6b0547eb02c1fc8737ba3e3b2c22ee0d7ef4f4b5b9e7869363330f200cf8eb83aa17f92b974dd5d6ce0ef422cc1c45d54a9317e2381b4fea8a03bf279d06c8 +d0e02045ece6e338cc8ab41d4a064c982ccb1748c48fc2fe0a6f10bdc876094358a6a90a45facec798a83cc95c6795cf0f0d7c66b77e22cb114c1432bfdaa1485ff35b6a58107cac3b7e58cb4f6c87c68db60b751e78f1fdfa54b8923b98caad0a4f31226956d065c083ace5f1e9e91944dcca51879d782e40358d58ca758750 016cc8a0fd59455ed8d4de561fd518df2e008f7dfaa5f7f29ac2489a411e233917b43eb3ebe2596fc824be58871949545e667dbcf240dfb5e0c615ade0179d9ea2a1b1ebb8ab9384 84f3280cac0c3eb0def08619ffb1f737120cb4d81257e5edcc15f1c52d6249faa36642261811332a82cac2d0d39de8b10a9defb43f6d598ea2dca14bc765a894481f42ff21a4829de97bca39055de34402cb5799ee9052b3330902fa06f7b440 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P224 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P224 new file mode 100644 index 000000000000..7c6ec8fa5ab4 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P224 @@ -0,0 +1,60 @@ +699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615 8572a79a4b12e90bef62c7756f15ecfe2282b1bc446edf5034cdc09c8a158ccefc8f4c3a769bbf1f5952dc21d1729f260489dcf9dc4200f43c6563b8c733705529ed92d6f2b7a8e3ef33d5b5e04a53e77b085d75f8256d5b45f1a592e7f6c176 +7de42b44db0aa8bfdcdac9add227e8f0cc7ad1d94693beb5e1d325e5f3f85b3bd033fc25e9469a89733a65d1fa641f7e67d668e7c71d736233c4cba20eb83c368c506affe77946b5e2ec693798aecd7ff943cd8fab90affddf5ad5b8d1af332e6c5fe4a2df16837700b2781e08821d4fbdd8373517f5b19f9e63b89cfeeeef6f cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5 86018830eef64463f49db574a38bab2f611b5adaba16734938ee73f612546e0dad9e9e21f693d2e9605870c4bc777402019fa1294f08e8df1267cada8a3ca9fe122e4c6f47eb8f1d8641a9d42ea6221cad9ebf459e9a0d4d470f450380e36f72 +af0da3adab82784909e2b3dadcecba21eced3c60d7572023dea171044d9a10e8ba67d31b04904541b87fff32a10ccc6580869055fec6216a00320a28899859a6b61faba58a0bc10c2ba07ea16f214c3ddcc9fc5622ad1253b63fe7e95227ae3c9caa9962cffc8b1c4e8260036469d25ab0c8e3643a820b8b3a4d8d43e4b728f9 dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73 8b99d7b1c4839cbedc75b70270cffe786ada94f59cf55067ffce143014cf0a48da7e87aaff9fd442a7ff88e99965c47e00abe51446f6ff71ed78a05dfe832b699ed2e01f7a9b641bb9895ffdfb2a1c9ab85c7a601ccd4f659d8a6da3c031b4a9 +cfa56ae89727df6b7266f69d6636bf738f9e4f15f49c42a0123edac4b3743f32ea52389f919ceb90575c4184897773b2f2fc5b3fcb354880f15c93383215d3c2551fcc1b4180a1ac0f69c969bbc306acd115ce3976eff518540f43ad4076dbb5fbad9ce9b3234f1148b8f5e059192ff480fc4bcbd00d25f4d9f5ed4ba5693b6c aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e 91502679a725cf48cded9bbaddb455882e5e4662318ce7aa8cbd10c9732b8981f2ae6008079016f6bf6a92a08951377c061cb2b65fe099fa3c2aaa43a5b9b3fb2b9c42e97a6cf49321e49159b45e671bc021cb8a649401b371f4bb26babefa68 +c223c8009018321b987a615c3414d2bb15954933569ca989de32d6bf11107bc47a330ab6d88d9b50d106cf5777d1b736b14bc48deda1bc573a9a7dd42cd061860645306dce7a5ba8c60f135a6a21999421ce8c4670fe7287a7e9ea3aa1e0fa82721f33e6e823957fe86e2283c89ef92b13cd0333c4bb70865ae1919bf538ea34 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4 85c2833db3166cdafa76bfae5bfbdf959148ef201fb3a3dd30a36812a68c9162d074e859eee9f0903f9952b78ad1a2f008eb9f025ed464f55d7a479368909ce4f7d71602ba65849e294122cbd1442cbb5a2a3b11d544e01ef3173877a0291524 +1c27273d95182c74c100d85b5c08f4b26874c2abc87f127f304aedbf52ef6540eba16dd664ae1e9e30ea1e66ff9cc9ab5a80b5bcbd19dde88a29ff10b50a6abd73388e8071306c68d0c9f6caa26b7e68de29312be959b9f4a5481f5a2ad2070a396ed3de21096541cf58c4a13308e08867565bf2df9d649357a83cdcf18d2cd9 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131 b6e39c4e41a2d0defcacb5f82120269b6da55fc9a4bd76a3100a39bc4054b97574d0cb2a1f8274bd66cb6a9525cdb7ec01029eeb3f1f5c1be8741a8a851f5a6e89b6b28106a26cbd6df1757933eac3434daccc197cfca08153d1f6ca0d209214 +069ae374971627f6b8503f3aa63ab52bcf4f3fcae65b98cdbbf917a5b08a10dc760056714db279806a8d43485320e6fee0f1e0562e077ee270ace8d3c478d79bcdff9cf8b92fdea68421d4a276f8e62ae379387ae06b60af9eb3c40bd7a768aeffccdc8a08bc78ca2eca18061058043a0e441209c5c594842838a4d9d778a053 d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974 aded2edb8f2d77f46690ad759fef6a72652566c844db83676882f20bc3aa2a870e079c9244681cd3dc5ed6e6c55f2baf06e1a2b1c2490ac36768a23d659a2e0d06a63226774da40a2d7b9705330f48d0badefbb7688de3ca942674161daa65e4 +d0d5ae3e33600aa21c1606caec449eee678c87cb593594be1fbb048cc7cfd076e5cc7132ebe290c4c014e7a517a0d5972759acfa1438d9d2e5d236d19ac92136f6252b7e5bea7588dcba6522b6b18128f003ecab5cb4908832fb5a375cf820f8f0e9ee870653a73dc2282f2d45622a2f0e85cba05c567baf1b9862b79a4b244e 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8 a39cc8b1e2c39a4cd7e2be115a7de6595cf426fc33687c2e64711e01efa5c08c1ec533eae3014d9bed80076b8084420206dc02cea8af031b9c9b878c93ac976f7461283d8cc9ec255a2f44d8de93614db864984c6d6ab7f1a58138280110b523 +79b7375ae7a4f2e4adad8765d14c1540cd9979db38076c157c1837c760ca6febbb18fd42152335929b735e1a08041bd38d315cd4c6b7dd2729de8752f531f07fe4ddc4f1899debc0311eef0019170b58e08895b439ddf09fbf0aeb1e2fd35c2ef7ae402308c3637733802601dd218fb14c22f57870835b10818369d57d318405 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2 b39a88699fbb6d83884eba4eb7555086d9832be10e0f50cdb100c71692844e056ae01d9fbad44841cbe52987ab1dc55d0bef7c6fca8ba2078c41765a22b2eb05d27978d474e86546744dbfff381719218e9fd1a7e616dda6464113001a3f6ed0 +8c7de96e6880d5b6efc19646b9d3d56490775cb3faab342e64db2e388c4bd9e94c4e69a63ccdb7e007a19711e69c06f106b71c983a6d97c4589045666c6ab5ea7b5b6d096ddf6fd35b819f1506a3c37ddd40929504f9f079c8d83820fc8493f97b2298aebe48fdb4ff472b29018fc2b1163a22bfbb1de413e8645e871291a9f6 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7 a0759bf2389f53021b8dfdba580f60aa7c382ef33487582b8104ce0dd834259d907bc3efe7f319288e644d061fb0d9ae0a33315a8d8df55341251e9744f1a439ba55182e775832ca56d171f6b1f02116057d52e8b2c9606a722aeae6a42238a0 +c89766374c5a5ccef5823e7a9b54af835ac56afbbb517bd77bfecf3fea876bd0cc9ea486e3d685cfe3fb05f25d9c67992cd7863c80a55c7a263249eb3996c4698ad7381131bf3700b7b24d7ca281a100cf2b750e7f0f933e662a08d9f9e47d779fb03754bd20931262ff381a2fe7d1dc94f4a0520de73fa72020494d3133ecf7 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b 867a90edaa8e6f8335ef4b50cb91025b676b291ac0f6498ae6a199ddb64430aeaa0d899ca3ca3f855a3bb335225390020426177500a34962c6fe6eab50e121ea25bc002d42ea7620999109c1c6de66a79a8fd0e195483a83fa20a7243457614f +30f0e3b502eec5646929d48fd46aa73991d82079c7bd50a38b38ec0bd84167c8cf5ba39bec26999e70208af9b445046cd9d20c82b7629ca1e51bdd00daddbc35f9eb036a15ac57898642d9db09479a38cc80a2e41e380c8a766b2d623de2de798e1eabc02234b89b85d60154460c3bf12764f3fbf17fcccc82df516a2fbe4ecf c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6 842fca3f8beb84135711a65bc6cfa23c6e201ceacbe14ffcc04946b746da99775df69bb15f75c7827c4ca53b55dc94200c7a899e7a20a522be34654244d26b36f0b4dcf21c00b06423946e1565f3745ac8290b4b5be70a91c1af834af75c2e28 +6bbb4bf987c8e5069e47c1a541b48b8a3e6d14bfd9ac6dfaa7503b64ab5e1a55f63e91cf5c3e703ac27ad88756dd7fb2d73b909fc15302d0592b974d47e72e60ed339a40b34d39a49b69ea4a5d26ce86f3ca00a70f1cd416a6a5722e8f39d1f0e966981803d6f46dac34e4c7640204cd0d9f1e53fc3acf30096cd00fa80b3ae9 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc 81315e2fd023819796f1e007b5ce92ad1926820d0c003eb3bfd14f4f328311fa664ccaafdddf6cf73ee72284b9c968800fb7dcdd26831d33423241f9d7880cf591b5b3fc7621494be4df4179a0d4020cb72d810e7688268ad42fd3b6eacf4518 +05b8f8e56214d4217323f2066f974f638f0b83689fc4ed1201848230efdc1fbca8f70359cecc921050141d3b02c2f17aa306fc2ce5fc06e7d0f4be162fcd985a0b687b4ba09b681cb52ffe890bf5bb4a104cb2e770c04df433013605eb8c72a09902f4246d6c22b8c191ef1b0bece10d5ce2744fc7345307dd1b41b6eff0ca89 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3 b8a7a814008e21967fb0721bc50659259fbed9e6e3327d5156571531e58e0d1f9a332be8d2e5d0a4db57a28e59a0b6ab0ab99bc08ea718eba08c238201c7fe7de4ebecc91694a4649eadfea4961e41c80d7022c0d8dab9dc055ed85ea62ab193 +e5c979f0832242b143077bce6ef146a53bb4c53abfc033473c59f3c4095a68b7a504b609f2ab163b5f88f374f0f3bff8762278b1f1c37323b9ed448e3de33e6443796a9ecaa466aa75175375418186c352018a57ce874e44ae72401d5c0f401b5a51804724c10653fded9066e8994d36a137fdeb9364601daeef09fd174dde4a 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912 81cde15d13728049ecb2c5f85e2e57b33c928ecb3fcd7ef194accbbbbdb92a8369bba73de46927133e4da6d0ded43067071baaaa64f222202cdb9538fef2885a91fc7f980b1fd51f912f1be882220b8ccc26c0607c7d615b0138bdce5403715c +2b49de971bb0f705a3fb5914eb7638d72884a6c3550667dbfdf301adf26bde02f387fd426a31be6c9ff8bfe8690c8113c88576427f1466508458349fc86036afcfb66448b947707e791e71f558b2bf4e7e7507773aaf4e9af51eda95cbce0a0f752b216f8a54a045d47801ff410ee411a1b66a516f278327df2462fb5619470e 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa b411687166fd03a0168c83ca4b692f52b121be0025d373246e309a8b8167837cb84ab6dd579aaabeddab9f4a5e8132ea159c80f81ed671b58490a9d3ab7d563fd362808741cc5ef2168b8560855d9a062f7a35ce70381f641964b8755871dc88 +1fa7201d96ad4d190415f2656d1387fa886afc38e5cd18b8c60da367acf32c627d2c9ea19ef3f030e559fc2a21695cdbb65ddf6ba36a70af0d3fa292a32de31da6acc6108ab2be8bd37843338f0c37c2d62648d3d49013edeb9e179dadf78bf885f95e712fcdfcc8a172e47c09ab159f3a00ed7b930f628c3c48257e92fc7407 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972 a2499c8bce81951b8f9f24c7416f200558878769737c6964eb05119606bf518d1706279ad1e019d85212b19db31eea8409e3d740a34b97bf1224243394c72316568230a4228170bd3a150a192912c4233afbb4027bf4083c4fb9bdc9db173f29 +74715fe10748a5b98b138f390f7ca9629c584c5d6ad268fc455c8de2e800b73fa1ea9aaee85de58baa2ce9ce68d822fc31842c6b153baef3a12bf6b4541f74af65430ae931a64c8b4950ad1c76b31aea8c229b3623390e233c112586aa5907bbe419841f54f0a7d6d19c003b91dc84bbb59b14ec477a1e9d194c137e21c75bbb f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170 890ed85c8ddbcc5e7c44b0a138b37413553390dfc0bc8c5c5af8400a2edcc1d0090da2023604940676f10e77b1e04f3d08e25160b08ebdef8cef56c64cd6ca5693abfb5e5322172068b129538968e6cf098362c86af66a6bafd1a04a2443ffbe +d10131982dd1a1d839aba383cd72855bf41061c0cb04dfa1acad3181f240341d744ca6002b52f25fb3c63f16d050c4a4ef2c0ebf5f16ce987558f4b9d4a5ad3c6b81b617de00e04ba32282d8bf223bfedbb325b741dfdc8f56fa85c65d42f05f6a1330d8cc6664ad32050dd7b9e3993f4d6c91e5e12cbd9e82196e009ad22560 c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85 832e3151cd6c9b589b9834199e11f929034589a30d14775e46b1fef7dc8f6cd07c3a4b72337eb06760620451d767375503354c48374ba1da301e854218c72ac99190acf4b1b5bc7b43235b6c91f8c6ab0eb38b7a9740e585449a72375f8ae6d0 +ef9dbd90ded96ad627a0a987ab90537a3e7acc1fdfa991088e9d999fd726e3ce1e1bd89a7df08d8c2bf51085254c89dc67bc21e8a1a93f33a38c18c0ce3880e958ac3e3dbe8aec49f981821c4ac6812dd29fab3a9ebe7fbd799fb50f12021b48d1d9abca8842547b3b99befa612cc8b4ca5f9412e0352e72ab1344a0ac2913db 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6 b8e43081c7daef69b3d7ee01ac09c80c5d57dd8358eca3834d9d5d389aa8283b56bffa470a44f5e11d88384a9116cc530a28a9c86195c39a1a7852b7e26bd1d3cb0e6b9e7213777358076ccca0580449a1b48425943b0ad373f082fdf4030022 +4cc91f744ac858d3577e48813219aa3538dd813b186b42d1e6218376f07cc1cc448ddd6b37240e98bf953f49cf54d65c12878b33c0bf6eb1c60254f0b6fa974f847e53abc56773eef6f29885dfc619e6a48fc15a667ca94001a0c945b6357a53221b0f4b266181456b0d2d25e90708777f1a6f85971c00140c631c1991e0fd06 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39 985942685914fce95b607f89c657e9d0fb7dd2fc23eab1a6139ef777ce3b6f0cc7d834ed7a839d808e1577aa74c408c808a1593047d99fc401dab02a4b41f1d437794f9f68bd853e0efd28e151e05e8778428cf560b53a1d67bcac9fabfeafc2 +58f43cc1924de4bc5867664adbc9d26b4f096a43aca47c27c52851b006dc2a658919ef9ce5b5ac48372703be15ac51631c2bd84b88f479f113b0569a9a09e230ec1e8e573474c6075284d3e57d973829af35325d9e7dab4a5f9b065155bbcaff3642a82ef4c9b9e127d3575c050721653da3b087d3fa394192897a5519527d19 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6 acd8c546313e6004ef8a436ce145fb24e06c46327e9cd1a9df0d09067d5e3926d8f66471981142099c7273cdcb29b2800570b032b6a04946cfa8d4d1b7feaabbf7499949c761e3c5230165c035301349b24792f89f7c3191979e8bea349d6bd3 +113a2806b052fde683ee09453098e402204155afb3776fd1cad3a9103421d327eab8f9ec0dd050ffcc83f93b34ea707705fabeccfe43ab1a71c95298fd3ec769d99ead1066950eee677d225816e0faad19cf69e1b35d16771689e2092cafe16d7c0dd7b0db73fffb8d0f3eaed83004dd21e753530ec939c89ba25578fa5f785b 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b 8cdce9b02714ff80003508715471984b5e71b90170421cf2131cedacec08898fb8025efabc6c11484b16cd6faf8a66791846080ca15f180322d3a8ddef9db66b36b12d087ab7c5086af4950fd96f4080844d767492fcc221c9683bdc12f172a5 +64cbfc8f2e2149a31b3e8a80c4a552f6c62aaeb7990b6e0ee55500a9d17be04213406578caf315951086dff5c2af3b5ce17d425d185101ef26f86396ba3a129a4f3f8e2dd595f59efb6c0f5c2dcc394569d7268695e9ac7daa84203f1f1895f1f9e4b514a5c9cd23baa63454710144fe735ad9b8f42d8c43267aa434a26d7e5f 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b b2aca54fbcdb9b707418052dc3f27fbf73b9abc420f363f22889629074e76a1292f230d5f2e744d7ef064d09f88bdfb009cfa5d94a29fb1213a477fc9358228718f71c8d4b7d339acf31b4a993051e7544c81636c2866b7bf1c5ed2bd286936d +a10a11c8e30fff118d371daf824f16c08200b83ea059436466a4611ccac93b2dea2de8c1006f946196aef7fe9b0c251a391b0340f21797798278b412ff2b53842eec6450728e2bca062f8337a2c204b9ea04ff660cd4d4db559f2f11c4d8ef199021339fcc82396f7a93926cf5f247e37d8067fe50692de54f102bd5ab51925c 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8 90efebfef3133ebfa1f923176443090e87d871df028b0e9bba566e38c6d97d42d047b90c586a2f4fd60ae215cbcb256d12bc0c6bcd78f1e0e188f2dbcf63350e0f06437b50643c0cf4bd0ed2bf219936e7428f4fc677d863ceb2557634938c13 +b3f720bf566ffa369259f4361959ae0641d2755ec264a4c4349981df2b02563275b2b9adb5aee47f7a456760a971991ffed6b17809bb9694138d1677fa916123795239353158fc6b22d10f20d26f5d2dcd8c56c44373eea5b93067dba2d7c5318dac2e9e8714873cb1b37f58c011fd14fa1e535554efe05f468bfc8e11cd8b99 e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784 b882530ce59c6ae2fb16fd4c34b1d68cb59f8ce0115d4a50bd4482af2ba43f18ad6124a3f9b4ff19614ab102e366a70c02be9ab94a6ce3b075c0eca5d302231c5c81c71a7a5cf029ece39e2d73777581f57f8052b0870f10380e2d7acadee492 +0a398a46df7ccc48d1e7833f8bbc67100f1ef77a62dc78bbc115b2a662f9591fbaaa91ad3d788e2fdd1b3164e45293d4f5686c151296901768028ac80ded4bf89c647ad35f0c7c4cb318c0c757c1d83c44d850e5fd4677281b3f13b1ee54de79c8c042813f9d3312dcc6111a68299cb7e829557d7f3d96e702f65aefc6499415 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c ad110b12ae1ccc31273e77376c1045ac67ab7c3d20940a6b1eb65e4dd50de7086f7ecc625b9728655841e4300358078417967127cfc21d6e6aaf7c3d255c51a76484695063a720891c0b78fd7488acb1ae02a38039ff885612ddceebbde4bde2 +8c33616821a6038b448d8918668977fcf1ef5aa0cf7c341837b39bbcc9bca875a3757f4b392630e9995b9bbe4eb66978b877586adaa02f99d2344dae082a7603351d8ffcfca081ab403cd0acb90d078dd1d0789c2eb3185c62bff2d9f04cd38e509e3b83c12ed0a5c6808fc42f7ba5b06acdc496c8ad9be648ee6a4505f8560f 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583 abdd1ab2a6a8cd656be1da41c9b846b76d04976593714591ff89a679b6fd6ae6bb4c3fa22f82f2c7ea2518e2e58425e406b6a5d67021bf1dfba9016dc7189763dd2756df748ba69e9569f17ea6bed094f4839b6284f16e49e22f44c0d58c1054 +94d56535fd4edfe67a0daa6579f9d53bf6b7b8830ae2aeb62892ff59f18756ddf2811b449c7d20d65d54f8507de4e7c50eaa084830637812aa4b250a4d61ab67845be36e4a41cdc0a70f8d6e3a63d4514f0dc197e6486015046a316153d5f3a3a4a0ae1ed7ea5fa55e12e73d333333685c02e0eb636234ea7e6d4b76b4b76b5a 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2 a2bd2ac90cbb00f6dcbd145e53804e99ce03acf8303ecc70d8984d92b97f3c8a6a2e070976ba97c76d0abde10b450e700bd9a6782fe56f04ac9b099a8d93d726f12f55432f8ed1268e00c21ba05f6ae6fdc7bae8f40f4046d12e8d6c8ce7059f +5d8ebdf9eb28b47bdafaa36bf0b66a9eaf99b6c83959da4f2b1151b4f4ecd28fb115a64c0cb9491093a7e9b9c53ec423e4c72e7765bb9c818da0e8c428667e44474a71db4867130c77c40bfd8544b2d7b9d6464d2b8e6a48482153256a32437c3a747231f51134dd14c703407e31146a6fcde23bededcf16950486e90ca69ac0 f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc 961a01d4507509ee6abf36a62effba054807ab2ecff2032668f3b5baae59535eba78b1d6b93b1f13d75cce63c2e7601e010c267a9b8d31c47c1c7d89ed1073b0a76debd4c28dd0013e3d49eb7575d053d31312f575edbf8b6619e2d216ddae93 +25e4416695f77551fdce276355528ccf1ddc2483821c5d22d751d50111ca2fadc6593b52c74f4b5957494f1df25b0b2f86950d0d19229ec6506fee8581d2dd09d48418b146ff16bd84a17ca0dc83b1888eb407376da6c8a88fa1e60b8c2a2471dfde4b3996ef673d5bde3d70c434dc9f2488e9de16ae657d29e5e59ec922a1ec 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd 927ad1a3e960d197097b4a61e71763c4299395557738d0551d8662a18dad83940cda70de775400005cea9886bc63bb8a0bcd5544024c44b0956693448064a1f85fb93c706d5cfdb68d579462961ac8d76fd8e152c517498cd98a0bf024b5a1f4 +9164d633a553deccf3cbd2effccf1387fa3177cd28c95d94a7d1a3e159c5e5c027758cc26493301b2f4d141d8d07a5fe5fead987ce5f30abeafcb48c302afc6c2309f0e93d9b6818cbb6972d222cb7b01302dfe202ae83b89f53150ae4a0e2b8fc0fd1091f19b4ab2e6ab213ab322d04f2c5f57113bfad3c5675227237abf773 e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3 94299a5f72aa586a110af5031f1ae4df70ef816acb9ad8a4377d483894dd9b8e11e4bbeced2b9df9959114e7578686b30c5360b092ea2f1263267cc4ce0a7ae3c42afd7f1f9dbcde042f9eba50c43c76f5950356be90fb31e7852116eb0f8a48 +019df05929321ecea7ee1de4f412aba1c8d3c24437db04b194a68a0a59dd871be10bd3a4be6edf551350ea49fc7155a4d887e1221486291abe77a30633a4c4f7868fe2df24311cba0c73804883954460e122387ed414111ff96ff1aebac8b6a6491d8a0d16e48a63bf3d027c0f68ee4a4b234d73b412196706af8ea022b4dcef b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17 abfa4fbe69fe7553d4f8a6832e8f92a789020c597008407d1573e94308c579abc397a548f5d81d920e70e3c860c868fa0b808e2a8a8e1408f46ecb18b514730227d1924184ead6bab9ea0cd855a1cbe45b1ee35b5921c7f9610578791b728767 +5d09d2b1d3fa6e12c10d8b26dc9aabc8dc02bd06e63ff33f8bb91ede4b8694592a69e4ed4cdf6820069e2b9c7803658949e877ffe23bf90bcf5ce1409c06c71d86885a94048b05ac0ec9db193e489a5a2bfa367caf6aa8ecdb032be366174343f6875d2fe1785e8d77334f5f469cec64998e08d3303e5c9a1923b34fdc105d65 efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085 a96cf0e991ca2525da55325d0235f73e574223e6e28c6b7935ce59031e5cea6bc629adb39f6cfb7cee602e61cc1879fa04910ac5f7018cb4c1d0595343ae90eb89f6b6c456b50aa9cdaadaf19253a6b79013a9e11563e07d3bda2c078b014487 +50f6dfc81c6cf189e0a310f992907fe93356cee9dea9a41c7671a8daf3f4cfe0c459ce6122c1e731dbf7593419d7114cb73b46956158a982c5d52c72f43f0f822046093c69aeff1f7e4cd8af00ba655c5baa2e7b6a400b4be1f6fd51b3e4cfb35a69c80a28c5cafb771b6c2e52e0aeef0e3fd045e8d40745f3f8b74fd969f816 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd ade0d32a62a86e76cdaed86c5c3a53621a3449de52a499cde48c7da4f530f2a7d755b460a93a95a55e4145982309137314b6d7bee3428b87ad9bebbc6c64536c58594563682bdeeea559a51172e226eef4a95f2512c2d9dfc667b92e2ba156da +e90129ac6672c85bb7b6b18e9dc199c96c81fd65034b53c77818364d512366fb9cd1bc7c82404c451e561fc1ed916c0948f6ac561b33a1ccca093f07684b8c2bafa9e966377bd208556018a5bafb9edcecf70498c7140fe9c8cf3ad8b8c3b0aa489df797944465047465415bb0e24333235fcdd59a98829a3941eaaf62033e82 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d 98212324f012d94659b82fb7f0c38d4963dfe09aa5fea84b6b4ccb938f55b5f85e05908dca2847c1661da7ec4eea726312785db2d4cee85f1739ee803006fc05bb304b0268042dcc68ee2d19aff244a6bf3b38de931b5f121b1cf0233602b0a2 +3c9a483c9bee33b601549c592a82e95b4319b1e74b777877f0971bcb4273716b268e8f99f876e42f942f4cf08284896bbc1ffbf094ac0956c3cedfc3580cffa8c74fc6db29a371f2da2d05edb9185ece741fe0d3fabfe9d5b4d373755ebed13dc6840cfa3283b9ea46ec8b95c434f253ae86998182e9cc0e95ee64f323fc74b0 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0 8fbcefc63dc26ec7e5ccd0ee3c6d4cfc240862ecb8e0c83382ad745b0bde51e82aed8bfa094c55d7c49382f060cccafd18a62fd5e13b323fc35b7ab4149d228595a3f104805947718c4dd711dcf1f9ea300c9bd339db2fd39028ad538409f5a0 +bfc073fdda63c5fccaa0ca8770c293e8154e7aec56128bbac4fdbd541d602216ebf7ca1e02b514d6e396f20683802ba3f334310a9226576926e3bb19ceee27738d13377cbafeb09d091043501702a07aa31d1f29d50ddc55adcf16ffd40578e734a4e6cb6535f26ad48e0c62ad90e79720000e87d419e92dca3e11f943655b03 e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d b607e332d063fae94dfd32fb0aaaa4ac4619b9eb762e657aea6834ae97ddd9292624c499319b0dbc34df3832105fa3610101e6b5f332a4aa8b1e376667c389a1666f23f481bb28acd9ecdd80ce07719f06d4f050db18b1d5cce4bd3ef285dd09 +08079955d1a1f33728128c73673ec9f21a6ce138dcab5adc4dc068e6ab57314b9fbd8b013123b2fdafa9524fbdd0288777a233de8055cccfad83046ada6a19f01c47817496667bba8fc8b9456fc0e044a562d931dab1adcb66af8b66325bdf28d83ded3e2937958ccd19da540d70ef2c189f55a506c9c0d63406394c5bd3823b f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7 a62020961cef4b15321a6502563df35c3110ec1c76413b6663cc8bdabfaae983ebc5ae677de750cd14b30721ed92c93101ad5faef857ee87f2308d9c72e18f82fc304f78e860061ce07f41c5b9cddd9c5a2a7ee186ddf11e8c4bfdb2a24b6363 +23900b768f6cd42b8a8df0dcbc9cb5daec8de36b9d5c619adcc1ba2b649103d5af123746cdf19c3fd0665a6fb9338156182aa06181e3c6e37ce56979612af2927440424f89cef43fc754854b8a5c43370808cf5f9929cf47712512ce2f8a2a20d2e9f568c2848b27dfbe09142843c83905ffa5da3b15501761b03dbc2c5398b6 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c 92c96a06806c91bfe367287eabeda956703bfc04cfa0d3e6f6fc3981311e90de1210d54ad8f8df89136463c32962e682127e33475885028e9c374861881aeacc9a007316524a4e053418cb8b09b1eca70b0fab224ecd02247cb6c8f83ebb24af +1eb28c0bcdd18f73e347f957ece15b4cc83a771b0877e1feaac38e24028fb38ccea8b54ee017dc7c3d5a1327bc6f40b294aa65d7dc487f278846cd101ee84202f14b38aa2c275046aa2577f65ebaea41cd383e8def2fd0b4444dcf426fa75c4082cd7fa035cdb1e0d34a3c79d42130f5b0273eae75bc701dda3aebe7358f41b5 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18 8c4bbb1be1ede062b694f162ab5394b39bf0604c68549e8650f575884f5b57870e48fe34a44f7f19339a5723da2cba1f00077626978ba17c92e37406819c817340e4badc70a027110392863769f4e291867a778d40b2e17af2362e6680441898 +efab51855407438fd5c250670366bca3c026ecec4a59394f00d8a4b51746d0c4564366656d507e3e13e62fe7abeb976b8859895848dbaecf6582f1898ea06f00d4247702ed9721bd375aa83ae4c67c2eaa6e080777ea5ecf2cf787d785389560ac91cf63a52f0373c3185e18a3b8a466e21b61a239f1b77624eb1acacc76c4e1 bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a 9652620081783decd460b7b879887a72263058599bfe9adf5de99384d1a581d854e642a24c85df1a5130c8bc7a3541b2166a071aab2e45c9e127c1d31329acc1f55b611b3f18aad4758111190ef7f00c65a0651eb218d083ef794260690db671 +31c29ca10279a417f0cc9b1382cf54dbfdfc89f2e6ef08c403c11f580cbf8674b141ed1a417563282d99a55fc616d836421cde9424815c95e7fb7668bf3f137b29937f14882d74e034b732d78d91af7721aac4950734f5fa5d4b4d35534974f8cab6d2e6dca75ddb57e99148c8a59df9fc5bcd723e546e8356f671cf2f65640a dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738 990441c96f7c13c23bfd44f6d7b3fab86edd1999b45f48f9adcbf7211220ed00fdb4c7aaa518ebb218622c33635bb9b8102972286e9b6dce6b603f70fc3e4bb4bf63e865a240a7be06f2743c585ea2284fa700633ba6c07852d3b368e990a372 +8db476f92e332519c1a0ece5d8deded6efbd2d8e8784eea0a6b4c3b4296c35f5f8de4317e5c1627b91fb1973fee86c06e4992aa5a20cb7475c8808ff1da354d07a488dffa7838c6ec1e3f99e3acba831f27bee8434eeda3eb36d0c6df3658883cd40068b1bed841310f6eb38d4a3d07d85848770ff7933c054cd8b34662660b1 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01 a1825fb48219d90249dd035bf60962d37acb03c5bb51d31865209b03bceaa1cf35991019cbcdb5646b47cd79b1297c5f1967073192bd6da474337df93f75c2d34fa8df6f6e0d5a776b3b6331580f8f7ee4a549def4fd10379e53adc69c864930 +fcb272c828fe8fd3c6f8de9410c7b6e2b36717c1b0e5e359e9109bd7fc378978aa98182a9d99961898ed88999b050d3b64d1457d7a899d6d273b9f4dde2aafa36d76329d62509043c338f265fc4c7d938459b7fa3b230a9f6cb632b61489546bb4181a5ad7f0d7369b8caced48eb374b075b2b325bc86add0f3b680cd9e80acd 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28 8221ad3035e57e30b4c693a414777bb569284f911d7fed129093d0e52e2018dc4759db5060d396e7024f67a2e7be067711b4548e7ca43d6a11840d4b3ae3f1ef5ed23d4e298d842b789405ac7c56f6a28d3bf9f665dde47aa5c1feeb1e698f8a +7522492bdb916a597b8121f3e5c273b1d2800ef8c1db4f7dcbae633b60d7da5193ba53a63d7a377b351897c3b24903ae1cd1994211b259be3e6ae2cbc8970e4957fdf782c7d1bc7a91c80c8ef65468d4ef35428f26e2940ae8b0bd9b8074236bf6c00d0ebe83f9ddb2ade0f835138d39f33b59f244e0037c171f1ba7045a96f5 ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6 89ec332c15392aac2f61b19b55ec3f98bb103bdae8ba037e2ebafb6b5281f1bee644af58fee97e57d249fe5fa4164e1f19081210a89331907f9c5f908d769d510b11ce0d1f33a012ed77447705678b1ee997b6ec947d7db378e7fff6f554c7e2 +61097114ff855c3e34a62d9b853f8982d35f29cfa4a89893badbca7849e5fb437a1a38d6451bf0ca5a0d528e352b8e4b57f2ea359a7fc8841d49dd3e570f9b016f14156b0bbc4be822e260bd147ec081454969e11cb0034b7450ef4deb7ed6edb977e2f4ed60121aa095fb0ab40240dc329ecc917f5c64b4410612af065ee9dd 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc 816090af1ce3eb1026fcc3def5b12a38753881378c59226e7f606acf1194a549818f1586679ded0c2aecdcc950b176d3049f6df23195b11817b2ee2ca0bda3e30daac450a3ab0a98c12d81906d0f3c4663300d825913cf29278ab487c8fa3693 +dd09ae6c982bb1440ca175a87766fefeacc49393ff797c446200662744f37a6e30c5d33ba70cbd8f12277fd6cc0704c17478bbab2a3047469e9618e3c340a9c8caaff5ce7c8a4d90ecae6a9b84b813419dec14460298e7521c9b7fdb7a2089328005bd51d57f92a1bcbeecd34aa40482b549e006bbf6c4ce66d34a22dda4e0e0 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b 9487eaa0b04315132e8499db70bd89b07a2b7f1490456b4c880a1bc3b597e80b530ce9ccaba1df157e20ec4eb2cbe45d12d7f5373d9dff46349d1c7dcada99949d48e16354f59e05c1fa22698eeaf4f76f1bc41c8bffe46bebc5dcd44fb0e2dc +37a73e2774d3b274db426c89b945696daa96035031f72cea01894b24508c7f81961ec254d36ed6a0f448e11cf7950af769dc6cd2c47e52c6caf0ea92c270974f0214b4db436c36a60fb722060a6bb544462a82e1714f5906ec32886f7d59ebf289541c3a00ec1e004892ef2b1286a0194f55d083c6ec92c64b8fd1452e1c68ba afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc aec467b1d537318e355fa6be605eb52af22a4497498166a8c26ab306e23a49641b778fd461069a71c50fc1077b02a989128f3763be22e52709ee3dcc66cdde3ca98ec44bcad82fc827dda2827f0ec30d198ed8ecfebf84d05f62b56ad9e71ddb +9dc2046ffdc6804544db964481abe5d2d276a2a9eeec4c7ad40215b1de23561d402db69bd0f6eec2254711eea4487c64d9a6b62c3ebaf5ffa8db6e7e3a6e17154d126967a47a853a6f8339bdca9be306a13c7f992ded7619b0da59909a49b1e0930360e05b47f18628a36d69b2f87f2bfddd6a5d4a72f84dc76dbdd43f3a6a35 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c a50f5a5c226569d603ec848ed3f3ffa78bbaace8b066942adedb2bc2c2acc8a58f0ab43904f8bcd7a5f7b58ccd1bec82114a0e2e117d79a1c432edc0276bb53c568b763fc4dcb5002ab1477f1ba24c12f2ba12407dac7a2f5d96dc58aaf4fa8c +d9c6847fce688c5e7525a1098b545cb6c15dcd21a02761fc82fc664372a667390680135f91c01a2fa5430c634b1a6d1cd6002d8aa021e7bf5956a7901c2f81bc25d502ba5f55a55f30c0323dc68205cbefec0538e68654e7b327ac1743641896c3e740d8f66f400902b304eafaa4e0d8cffae140536f0922444cc3216a675697 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc a81855c3fb8e547fac501dd75f7f659162fba889f93e187cbe705725cfa92245e4b0ace97d2ed8cfe3fd1f5d84b608f70911e0ef52749bd9f742598d5647839756a94b70a563be10ea0c73631c9a6f6e4c8ae42da1838078369303aae3a91ef5 +69df8a01b66f04930efd2012ff2243874f256ca8758145d2a9e4ecc84d0dbdbd0dc494ae06db0ccbe819918137c90957114558580d6623efbafdd342b38dad9f08708084d32f874fba04782ce26aaab78de2102ad171f8a8f2b30b5bd3d55fdac5fa3acd6f7def7e61c2533938572b331ba6d1c02bd74bfdbf7337ade8f4a190 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4 8256d342e38e48d66a603aaca704f4f57c71dd008f9089d5d9a64baccef239a288a9edef79b1279d798a00c51a51b8880a317c45132f0d2d1d0217d6fdcd32d7a9750e5203633c12a5f631eaa81e7af1622012f6576f7bf32e29179f2bbbd0bd +927524982b8d60777c1105c86fac05f634abf58c73f84fb95d81ba0b86e1e43592c4fcad2e395a40fbe7005697d86088e2fb3bb7287eb3f917d4f2dc281f5cbe65d05b4f9623bca849b10a03beca6aa2056a12ebb91cf257ac448c5e9a78f8349a6a29b17c8978bef43a443cbb8a149eb23f794844fc41693f2dbb97181444be a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916 b0cacd44cb336667745487e9d2fda1d65f11835aaec325574d8e4afb7c0768fb7c9c1adb481291effeba9b9bbb283f3e0a5748fb779e3e83d9a2d2a8dbbe82b4351e53d07a4a096f6eabce677cab68d018b17259ad6a3a902b281a42e077d2ab +5f9042283561e7f19a436d01c7ef5a950a6d77ede5629cd7e43c0a5d58e8c5673c37945a453291d12938253c71dbe12c8b022ba7276eda6be034ef5ec1ec77dbd1e08f0d7b8e7725b7ec671c075e008a20f77f4ab266f97079b0aa6337df59a33b881954084057b21f294dd14bcb0869a4a6f1f597955ec7bf9d19bb3537a66a fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b 8af33bcfd106d5bce0edf78379627af0f8ef068e3d21c87462de5959a02e7bd1f1d95206bd93027e03faf27df4bdcc03089768c49e88b212600f49dde0aceabcd120253a1dad7b96e25a85bd270aea9314cb602d60b6be86dc85909eb4f34114 +c2ae5573d3bf396523bfb703db8502fd0760cd1be528f6ddbfb95aad399e0b19f3bd9e0fabdb05d49e3f893dffec5b627c9c2f7ad5f32e92e4e27a38cb5c28657657377fdfa1b66cd7ac3d15c6d49df92d284db99f69744f37dc7cb4e7d52920fdb200a7942623a7057ba82e467dcccaa5da416b48510d8364446a6a5e2a5aa8 a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea 8e1f7d71cd1b0b023baca58e3d05905aa9725a9a8db2370b23aa4b7b2ec7dfe9ebc968d7444069ab2772030ef54c13af0bf48892810e6aec032a85ca64e08bada600722d98e46edf5cdccf017667a9b15059882956a535305f5989f52b7f4cde +03c1a1cd30a039d0dcb22fee2450a7fa79495a0d0f4f43d2de4d75bce003c0334a8860f5c164dbd94888a9f751235a3e570d31070e3e1293a7be616af7176600585d36ac013600157d2569d491da4b8a3bf3630c26e0b9925412189f50b0ae6f04c86477932e2ecd8c3546106ae1ebc684cc3adb27ed665eddece886adea4ce3 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0 9517ea66899057986265d014afc775d9a003b495291e5ab08b4d8bcc9e4238cf2c2f01a5914bae0f6f694d2116fc0b9f0ec92ba42391bb2c7a595a87cbeb7dd6c5a6ec5cb638067018778c65b44002af34b6df4d475fbe4003c636f11d4255e6 +888f6d9bc7c86c0079fbfd42d8c08d6958f40f6e570fb0b1f03d2f8f8a63df4fcc87b379a222cf835820a999d34996e08961f13b86b075e7fd1c303cd3baa44de42168561589012f7e5300da4f8bdf470c07119a5d9f7ba7293568cd7c6a1b7fc1e41cda40bed7d46e5a28af67ae2aabfefe67a86a1c601e6f5ee543e09bd7b6 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294 ad4d2e09786db225a655f8894f23622c4ca02dcb1d057154a40d51c2b2f9db1acb01e6c32749e09a4008618e8ef6f8d31976ae66e68088b6e27244f1c27327076ec7e7307048d45ac6f4908da423b0a57e098f8730bc1c18d11e3f90755ebd83 +48453340f1317769e6ee6e103153714365731163dc18f84e9f2fa4b120f9c5a9645ee2f9b66c84c26d95912b422b009b64af96aa418b2427a4209f2e7513ba8e43ec8cf20b34e7529b22eb1199545afe9a9f7d9bcb320aec9ee0162f91c0d1dd9674c9c284f25199c5e109f6f84d7ed0d269cc6413edb81bc2c83e37d644d8b9 b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a b58494a19f758c5348bf977a700bca8874e690a5cb52b2ff4fb9622ad0cae7be697eb13ad9cf2c86d5371e3ad572bffc0f580a5cc3258204dca2dd9d8e7bc67fcc580ff14171e4446554ceef68109d8919ff6067d16719625a3c5bec00ac0910 +4bdfd3b91d83108409ad765b256e0c9b9937ecf647f8e6f9fc807e2e72af8246178b3fe046b4ea10170450d71a4eec790ecb05f03d7077341de26c4db7eeae24d55c9a9093e837dfdb38168fe8230cb9605825a1282fecd741989bfcdb34678fe077477927f66bd26d003e5dda22043341a14dd31841ba483ad5ce2701e0f68e 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4 868cbfce426a9bd415f8bbd0bfec0fb78af09ad070797596c19fe7f50a04f1da1e7a35fc66d56c69e58128483583607f0edf8d1c3773cfd93fa54341dd119da296d58ba171e9d8d35f43d925c1a5908d7fa571992ac3d4dd2733d54c78d08a8e +e6cdee8558bc1eacc24e82f0624ce8d02cc8d925b4dd3dec3a72f4a4e0fb76076bfa3ef2e2c33bdd7c27b322bdc09bbfee8fe46f75dbd7bbd2af09690b7137943efe21706e0a1b6d3089540fc58d85ddb55ea836616db573e36c521be008893f40a0a7c349602cc178ea43be59d31ec6449e7ff2c5379379f7d7645134df1bc3 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04 95c39396d88379d7566d941faf77455f53e257d02d68a018f500707928cc0a355ffa28a05166624e30ece4b1f7ef9d6a0d7520b12db5b5068fa10a068fbf36f660663c06a364e0b5b6ae1ee06fc832c6087e56d8cc651934a918482d759cd91d diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P224_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P224_blst new file mode 100644 index 000000000000..7c6ec8fa5ab4 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P224_blst @@ -0,0 +1,60 @@ +699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615 8572a79a4b12e90bef62c7756f15ecfe2282b1bc446edf5034cdc09c8a158ccefc8f4c3a769bbf1f5952dc21d1729f260489dcf9dc4200f43c6563b8c733705529ed92d6f2b7a8e3ef33d5b5e04a53e77b085d75f8256d5b45f1a592e7f6c176 +7de42b44db0aa8bfdcdac9add227e8f0cc7ad1d94693beb5e1d325e5f3f85b3bd033fc25e9469a89733a65d1fa641f7e67d668e7c71d736233c4cba20eb83c368c506affe77946b5e2ec693798aecd7ff943cd8fab90affddf5ad5b8d1af332e6c5fe4a2df16837700b2781e08821d4fbdd8373517f5b19f9e63b89cfeeeef6f cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5 86018830eef64463f49db574a38bab2f611b5adaba16734938ee73f612546e0dad9e9e21f693d2e9605870c4bc777402019fa1294f08e8df1267cada8a3ca9fe122e4c6f47eb8f1d8641a9d42ea6221cad9ebf459e9a0d4d470f450380e36f72 +af0da3adab82784909e2b3dadcecba21eced3c60d7572023dea171044d9a10e8ba67d31b04904541b87fff32a10ccc6580869055fec6216a00320a28899859a6b61faba58a0bc10c2ba07ea16f214c3ddcc9fc5622ad1253b63fe7e95227ae3c9caa9962cffc8b1c4e8260036469d25ab0c8e3643a820b8b3a4d8d43e4b728f9 dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73 8b99d7b1c4839cbedc75b70270cffe786ada94f59cf55067ffce143014cf0a48da7e87aaff9fd442a7ff88e99965c47e00abe51446f6ff71ed78a05dfe832b699ed2e01f7a9b641bb9895ffdfb2a1c9ab85c7a601ccd4f659d8a6da3c031b4a9 +cfa56ae89727df6b7266f69d6636bf738f9e4f15f49c42a0123edac4b3743f32ea52389f919ceb90575c4184897773b2f2fc5b3fcb354880f15c93383215d3c2551fcc1b4180a1ac0f69c969bbc306acd115ce3976eff518540f43ad4076dbb5fbad9ce9b3234f1148b8f5e059192ff480fc4bcbd00d25f4d9f5ed4ba5693b6c aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e 91502679a725cf48cded9bbaddb455882e5e4662318ce7aa8cbd10c9732b8981f2ae6008079016f6bf6a92a08951377c061cb2b65fe099fa3c2aaa43a5b9b3fb2b9c42e97a6cf49321e49159b45e671bc021cb8a649401b371f4bb26babefa68 +c223c8009018321b987a615c3414d2bb15954933569ca989de32d6bf11107bc47a330ab6d88d9b50d106cf5777d1b736b14bc48deda1bc573a9a7dd42cd061860645306dce7a5ba8c60f135a6a21999421ce8c4670fe7287a7e9ea3aa1e0fa82721f33e6e823957fe86e2283c89ef92b13cd0333c4bb70865ae1919bf538ea34 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4 85c2833db3166cdafa76bfae5bfbdf959148ef201fb3a3dd30a36812a68c9162d074e859eee9f0903f9952b78ad1a2f008eb9f025ed464f55d7a479368909ce4f7d71602ba65849e294122cbd1442cbb5a2a3b11d544e01ef3173877a0291524 +1c27273d95182c74c100d85b5c08f4b26874c2abc87f127f304aedbf52ef6540eba16dd664ae1e9e30ea1e66ff9cc9ab5a80b5bcbd19dde88a29ff10b50a6abd73388e8071306c68d0c9f6caa26b7e68de29312be959b9f4a5481f5a2ad2070a396ed3de21096541cf58c4a13308e08867565bf2df9d649357a83cdcf18d2cd9 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131 b6e39c4e41a2d0defcacb5f82120269b6da55fc9a4bd76a3100a39bc4054b97574d0cb2a1f8274bd66cb6a9525cdb7ec01029eeb3f1f5c1be8741a8a851f5a6e89b6b28106a26cbd6df1757933eac3434daccc197cfca08153d1f6ca0d209214 +069ae374971627f6b8503f3aa63ab52bcf4f3fcae65b98cdbbf917a5b08a10dc760056714db279806a8d43485320e6fee0f1e0562e077ee270ace8d3c478d79bcdff9cf8b92fdea68421d4a276f8e62ae379387ae06b60af9eb3c40bd7a768aeffccdc8a08bc78ca2eca18061058043a0e441209c5c594842838a4d9d778a053 d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974 aded2edb8f2d77f46690ad759fef6a72652566c844db83676882f20bc3aa2a870e079c9244681cd3dc5ed6e6c55f2baf06e1a2b1c2490ac36768a23d659a2e0d06a63226774da40a2d7b9705330f48d0badefbb7688de3ca942674161daa65e4 +d0d5ae3e33600aa21c1606caec449eee678c87cb593594be1fbb048cc7cfd076e5cc7132ebe290c4c014e7a517a0d5972759acfa1438d9d2e5d236d19ac92136f6252b7e5bea7588dcba6522b6b18128f003ecab5cb4908832fb5a375cf820f8f0e9ee870653a73dc2282f2d45622a2f0e85cba05c567baf1b9862b79a4b244e 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8 a39cc8b1e2c39a4cd7e2be115a7de6595cf426fc33687c2e64711e01efa5c08c1ec533eae3014d9bed80076b8084420206dc02cea8af031b9c9b878c93ac976f7461283d8cc9ec255a2f44d8de93614db864984c6d6ab7f1a58138280110b523 +79b7375ae7a4f2e4adad8765d14c1540cd9979db38076c157c1837c760ca6febbb18fd42152335929b735e1a08041bd38d315cd4c6b7dd2729de8752f531f07fe4ddc4f1899debc0311eef0019170b58e08895b439ddf09fbf0aeb1e2fd35c2ef7ae402308c3637733802601dd218fb14c22f57870835b10818369d57d318405 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2 b39a88699fbb6d83884eba4eb7555086d9832be10e0f50cdb100c71692844e056ae01d9fbad44841cbe52987ab1dc55d0bef7c6fca8ba2078c41765a22b2eb05d27978d474e86546744dbfff381719218e9fd1a7e616dda6464113001a3f6ed0 +8c7de96e6880d5b6efc19646b9d3d56490775cb3faab342e64db2e388c4bd9e94c4e69a63ccdb7e007a19711e69c06f106b71c983a6d97c4589045666c6ab5ea7b5b6d096ddf6fd35b819f1506a3c37ddd40929504f9f079c8d83820fc8493f97b2298aebe48fdb4ff472b29018fc2b1163a22bfbb1de413e8645e871291a9f6 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7 a0759bf2389f53021b8dfdba580f60aa7c382ef33487582b8104ce0dd834259d907bc3efe7f319288e644d061fb0d9ae0a33315a8d8df55341251e9744f1a439ba55182e775832ca56d171f6b1f02116057d52e8b2c9606a722aeae6a42238a0 +c89766374c5a5ccef5823e7a9b54af835ac56afbbb517bd77bfecf3fea876bd0cc9ea486e3d685cfe3fb05f25d9c67992cd7863c80a55c7a263249eb3996c4698ad7381131bf3700b7b24d7ca281a100cf2b750e7f0f933e662a08d9f9e47d779fb03754bd20931262ff381a2fe7d1dc94f4a0520de73fa72020494d3133ecf7 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b 867a90edaa8e6f8335ef4b50cb91025b676b291ac0f6498ae6a199ddb64430aeaa0d899ca3ca3f855a3bb335225390020426177500a34962c6fe6eab50e121ea25bc002d42ea7620999109c1c6de66a79a8fd0e195483a83fa20a7243457614f +30f0e3b502eec5646929d48fd46aa73991d82079c7bd50a38b38ec0bd84167c8cf5ba39bec26999e70208af9b445046cd9d20c82b7629ca1e51bdd00daddbc35f9eb036a15ac57898642d9db09479a38cc80a2e41e380c8a766b2d623de2de798e1eabc02234b89b85d60154460c3bf12764f3fbf17fcccc82df516a2fbe4ecf c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6 842fca3f8beb84135711a65bc6cfa23c6e201ceacbe14ffcc04946b746da99775df69bb15f75c7827c4ca53b55dc94200c7a899e7a20a522be34654244d26b36f0b4dcf21c00b06423946e1565f3745ac8290b4b5be70a91c1af834af75c2e28 +6bbb4bf987c8e5069e47c1a541b48b8a3e6d14bfd9ac6dfaa7503b64ab5e1a55f63e91cf5c3e703ac27ad88756dd7fb2d73b909fc15302d0592b974d47e72e60ed339a40b34d39a49b69ea4a5d26ce86f3ca00a70f1cd416a6a5722e8f39d1f0e966981803d6f46dac34e4c7640204cd0d9f1e53fc3acf30096cd00fa80b3ae9 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc 81315e2fd023819796f1e007b5ce92ad1926820d0c003eb3bfd14f4f328311fa664ccaafdddf6cf73ee72284b9c968800fb7dcdd26831d33423241f9d7880cf591b5b3fc7621494be4df4179a0d4020cb72d810e7688268ad42fd3b6eacf4518 +05b8f8e56214d4217323f2066f974f638f0b83689fc4ed1201848230efdc1fbca8f70359cecc921050141d3b02c2f17aa306fc2ce5fc06e7d0f4be162fcd985a0b687b4ba09b681cb52ffe890bf5bb4a104cb2e770c04df433013605eb8c72a09902f4246d6c22b8c191ef1b0bece10d5ce2744fc7345307dd1b41b6eff0ca89 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3 b8a7a814008e21967fb0721bc50659259fbed9e6e3327d5156571531e58e0d1f9a332be8d2e5d0a4db57a28e59a0b6ab0ab99bc08ea718eba08c238201c7fe7de4ebecc91694a4649eadfea4961e41c80d7022c0d8dab9dc055ed85ea62ab193 +e5c979f0832242b143077bce6ef146a53bb4c53abfc033473c59f3c4095a68b7a504b609f2ab163b5f88f374f0f3bff8762278b1f1c37323b9ed448e3de33e6443796a9ecaa466aa75175375418186c352018a57ce874e44ae72401d5c0f401b5a51804724c10653fded9066e8994d36a137fdeb9364601daeef09fd174dde4a 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912 81cde15d13728049ecb2c5f85e2e57b33c928ecb3fcd7ef194accbbbbdb92a8369bba73de46927133e4da6d0ded43067071baaaa64f222202cdb9538fef2885a91fc7f980b1fd51f912f1be882220b8ccc26c0607c7d615b0138bdce5403715c +2b49de971bb0f705a3fb5914eb7638d72884a6c3550667dbfdf301adf26bde02f387fd426a31be6c9ff8bfe8690c8113c88576427f1466508458349fc86036afcfb66448b947707e791e71f558b2bf4e7e7507773aaf4e9af51eda95cbce0a0f752b216f8a54a045d47801ff410ee411a1b66a516f278327df2462fb5619470e 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa b411687166fd03a0168c83ca4b692f52b121be0025d373246e309a8b8167837cb84ab6dd579aaabeddab9f4a5e8132ea159c80f81ed671b58490a9d3ab7d563fd362808741cc5ef2168b8560855d9a062f7a35ce70381f641964b8755871dc88 +1fa7201d96ad4d190415f2656d1387fa886afc38e5cd18b8c60da367acf32c627d2c9ea19ef3f030e559fc2a21695cdbb65ddf6ba36a70af0d3fa292a32de31da6acc6108ab2be8bd37843338f0c37c2d62648d3d49013edeb9e179dadf78bf885f95e712fcdfcc8a172e47c09ab159f3a00ed7b930f628c3c48257e92fc7407 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972 a2499c8bce81951b8f9f24c7416f200558878769737c6964eb05119606bf518d1706279ad1e019d85212b19db31eea8409e3d740a34b97bf1224243394c72316568230a4228170bd3a150a192912c4233afbb4027bf4083c4fb9bdc9db173f29 +74715fe10748a5b98b138f390f7ca9629c584c5d6ad268fc455c8de2e800b73fa1ea9aaee85de58baa2ce9ce68d822fc31842c6b153baef3a12bf6b4541f74af65430ae931a64c8b4950ad1c76b31aea8c229b3623390e233c112586aa5907bbe419841f54f0a7d6d19c003b91dc84bbb59b14ec477a1e9d194c137e21c75bbb f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170 890ed85c8ddbcc5e7c44b0a138b37413553390dfc0bc8c5c5af8400a2edcc1d0090da2023604940676f10e77b1e04f3d08e25160b08ebdef8cef56c64cd6ca5693abfb5e5322172068b129538968e6cf098362c86af66a6bafd1a04a2443ffbe +d10131982dd1a1d839aba383cd72855bf41061c0cb04dfa1acad3181f240341d744ca6002b52f25fb3c63f16d050c4a4ef2c0ebf5f16ce987558f4b9d4a5ad3c6b81b617de00e04ba32282d8bf223bfedbb325b741dfdc8f56fa85c65d42f05f6a1330d8cc6664ad32050dd7b9e3993f4d6c91e5e12cbd9e82196e009ad22560 c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85 832e3151cd6c9b589b9834199e11f929034589a30d14775e46b1fef7dc8f6cd07c3a4b72337eb06760620451d767375503354c48374ba1da301e854218c72ac99190acf4b1b5bc7b43235b6c91f8c6ab0eb38b7a9740e585449a72375f8ae6d0 +ef9dbd90ded96ad627a0a987ab90537a3e7acc1fdfa991088e9d999fd726e3ce1e1bd89a7df08d8c2bf51085254c89dc67bc21e8a1a93f33a38c18c0ce3880e958ac3e3dbe8aec49f981821c4ac6812dd29fab3a9ebe7fbd799fb50f12021b48d1d9abca8842547b3b99befa612cc8b4ca5f9412e0352e72ab1344a0ac2913db 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6 b8e43081c7daef69b3d7ee01ac09c80c5d57dd8358eca3834d9d5d389aa8283b56bffa470a44f5e11d88384a9116cc530a28a9c86195c39a1a7852b7e26bd1d3cb0e6b9e7213777358076ccca0580449a1b48425943b0ad373f082fdf4030022 +4cc91f744ac858d3577e48813219aa3538dd813b186b42d1e6218376f07cc1cc448ddd6b37240e98bf953f49cf54d65c12878b33c0bf6eb1c60254f0b6fa974f847e53abc56773eef6f29885dfc619e6a48fc15a667ca94001a0c945b6357a53221b0f4b266181456b0d2d25e90708777f1a6f85971c00140c631c1991e0fd06 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39 985942685914fce95b607f89c657e9d0fb7dd2fc23eab1a6139ef777ce3b6f0cc7d834ed7a839d808e1577aa74c408c808a1593047d99fc401dab02a4b41f1d437794f9f68bd853e0efd28e151e05e8778428cf560b53a1d67bcac9fabfeafc2 +58f43cc1924de4bc5867664adbc9d26b4f096a43aca47c27c52851b006dc2a658919ef9ce5b5ac48372703be15ac51631c2bd84b88f479f113b0569a9a09e230ec1e8e573474c6075284d3e57d973829af35325d9e7dab4a5f9b065155bbcaff3642a82ef4c9b9e127d3575c050721653da3b087d3fa394192897a5519527d19 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6 acd8c546313e6004ef8a436ce145fb24e06c46327e9cd1a9df0d09067d5e3926d8f66471981142099c7273cdcb29b2800570b032b6a04946cfa8d4d1b7feaabbf7499949c761e3c5230165c035301349b24792f89f7c3191979e8bea349d6bd3 +113a2806b052fde683ee09453098e402204155afb3776fd1cad3a9103421d327eab8f9ec0dd050ffcc83f93b34ea707705fabeccfe43ab1a71c95298fd3ec769d99ead1066950eee677d225816e0faad19cf69e1b35d16771689e2092cafe16d7c0dd7b0db73fffb8d0f3eaed83004dd21e753530ec939c89ba25578fa5f785b 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b 8cdce9b02714ff80003508715471984b5e71b90170421cf2131cedacec08898fb8025efabc6c11484b16cd6faf8a66791846080ca15f180322d3a8ddef9db66b36b12d087ab7c5086af4950fd96f4080844d767492fcc221c9683bdc12f172a5 +64cbfc8f2e2149a31b3e8a80c4a552f6c62aaeb7990b6e0ee55500a9d17be04213406578caf315951086dff5c2af3b5ce17d425d185101ef26f86396ba3a129a4f3f8e2dd595f59efb6c0f5c2dcc394569d7268695e9ac7daa84203f1f1895f1f9e4b514a5c9cd23baa63454710144fe735ad9b8f42d8c43267aa434a26d7e5f 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b b2aca54fbcdb9b707418052dc3f27fbf73b9abc420f363f22889629074e76a1292f230d5f2e744d7ef064d09f88bdfb009cfa5d94a29fb1213a477fc9358228718f71c8d4b7d339acf31b4a993051e7544c81636c2866b7bf1c5ed2bd286936d +a10a11c8e30fff118d371daf824f16c08200b83ea059436466a4611ccac93b2dea2de8c1006f946196aef7fe9b0c251a391b0340f21797798278b412ff2b53842eec6450728e2bca062f8337a2c204b9ea04ff660cd4d4db559f2f11c4d8ef199021339fcc82396f7a93926cf5f247e37d8067fe50692de54f102bd5ab51925c 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8 90efebfef3133ebfa1f923176443090e87d871df028b0e9bba566e38c6d97d42d047b90c586a2f4fd60ae215cbcb256d12bc0c6bcd78f1e0e188f2dbcf63350e0f06437b50643c0cf4bd0ed2bf219936e7428f4fc677d863ceb2557634938c13 +b3f720bf566ffa369259f4361959ae0641d2755ec264a4c4349981df2b02563275b2b9adb5aee47f7a456760a971991ffed6b17809bb9694138d1677fa916123795239353158fc6b22d10f20d26f5d2dcd8c56c44373eea5b93067dba2d7c5318dac2e9e8714873cb1b37f58c011fd14fa1e535554efe05f468bfc8e11cd8b99 e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784 b882530ce59c6ae2fb16fd4c34b1d68cb59f8ce0115d4a50bd4482af2ba43f18ad6124a3f9b4ff19614ab102e366a70c02be9ab94a6ce3b075c0eca5d302231c5c81c71a7a5cf029ece39e2d73777581f57f8052b0870f10380e2d7acadee492 +0a398a46df7ccc48d1e7833f8bbc67100f1ef77a62dc78bbc115b2a662f9591fbaaa91ad3d788e2fdd1b3164e45293d4f5686c151296901768028ac80ded4bf89c647ad35f0c7c4cb318c0c757c1d83c44d850e5fd4677281b3f13b1ee54de79c8c042813f9d3312dcc6111a68299cb7e829557d7f3d96e702f65aefc6499415 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c ad110b12ae1ccc31273e77376c1045ac67ab7c3d20940a6b1eb65e4dd50de7086f7ecc625b9728655841e4300358078417967127cfc21d6e6aaf7c3d255c51a76484695063a720891c0b78fd7488acb1ae02a38039ff885612ddceebbde4bde2 +8c33616821a6038b448d8918668977fcf1ef5aa0cf7c341837b39bbcc9bca875a3757f4b392630e9995b9bbe4eb66978b877586adaa02f99d2344dae082a7603351d8ffcfca081ab403cd0acb90d078dd1d0789c2eb3185c62bff2d9f04cd38e509e3b83c12ed0a5c6808fc42f7ba5b06acdc496c8ad9be648ee6a4505f8560f 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583 abdd1ab2a6a8cd656be1da41c9b846b76d04976593714591ff89a679b6fd6ae6bb4c3fa22f82f2c7ea2518e2e58425e406b6a5d67021bf1dfba9016dc7189763dd2756df748ba69e9569f17ea6bed094f4839b6284f16e49e22f44c0d58c1054 +94d56535fd4edfe67a0daa6579f9d53bf6b7b8830ae2aeb62892ff59f18756ddf2811b449c7d20d65d54f8507de4e7c50eaa084830637812aa4b250a4d61ab67845be36e4a41cdc0a70f8d6e3a63d4514f0dc197e6486015046a316153d5f3a3a4a0ae1ed7ea5fa55e12e73d333333685c02e0eb636234ea7e6d4b76b4b76b5a 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2 a2bd2ac90cbb00f6dcbd145e53804e99ce03acf8303ecc70d8984d92b97f3c8a6a2e070976ba97c76d0abde10b450e700bd9a6782fe56f04ac9b099a8d93d726f12f55432f8ed1268e00c21ba05f6ae6fdc7bae8f40f4046d12e8d6c8ce7059f +5d8ebdf9eb28b47bdafaa36bf0b66a9eaf99b6c83959da4f2b1151b4f4ecd28fb115a64c0cb9491093a7e9b9c53ec423e4c72e7765bb9c818da0e8c428667e44474a71db4867130c77c40bfd8544b2d7b9d6464d2b8e6a48482153256a32437c3a747231f51134dd14c703407e31146a6fcde23bededcf16950486e90ca69ac0 f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc 961a01d4507509ee6abf36a62effba054807ab2ecff2032668f3b5baae59535eba78b1d6b93b1f13d75cce63c2e7601e010c267a9b8d31c47c1c7d89ed1073b0a76debd4c28dd0013e3d49eb7575d053d31312f575edbf8b6619e2d216ddae93 +25e4416695f77551fdce276355528ccf1ddc2483821c5d22d751d50111ca2fadc6593b52c74f4b5957494f1df25b0b2f86950d0d19229ec6506fee8581d2dd09d48418b146ff16bd84a17ca0dc83b1888eb407376da6c8a88fa1e60b8c2a2471dfde4b3996ef673d5bde3d70c434dc9f2488e9de16ae657d29e5e59ec922a1ec 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd 927ad1a3e960d197097b4a61e71763c4299395557738d0551d8662a18dad83940cda70de775400005cea9886bc63bb8a0bcd5544024c44b0956693448064a1f85fb93c706d5cfdb68d579462961ac8d76fd8e152c517498cd98a0bf024b5a1f4 +9164d633a553deccf3cbd2effccf1387fa3177cd28c95d94a7d1a3e159c5e5c027758cc26493301b2f4d141d8d07a5fe5fead987ce5f30abeafcb48c302afc6c2309f0e93d9b6818cbb6972d222cb7b01302dfe202ae83b89f53150ae4a0e2b8fc0fd1091f19b4ab2e6ab213ab322d04f2c5f57113bfad3c5675227237abf773 e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3 94299a5f72aa586a110af5031f1ae4df70ef816acb9ad8a4377d483894dd9b8e11e4bbeced2b9df9959114e7578686b30c5360b092ea2f1263267cc4ce0a7ae3c42afd7f1f9dbcde042f9eba50c43c76f5950356be90fb31e7852116eb0f8a48 +019df05929321ecea7ee1de4f412aba1c8d3c24437db04b194a68a0a59dd871be10bd3a4be6edf551350ea49fc7155a4d887e1221486291abe77a30633a4c4f7868fe2df24311cba0c73804883954460e122387ed414111ff96ff1aebac8b6a6491d8a0d16e48a63bf3d027c0f68ee4a4b234d73b412196706af8ea022b4dcef b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17 abfa4fbe69fe7553d4f8a6832e8f92a789020c597008407d1573e94308c579abc397a548f5d81d920e70e3c860c868fa0b808e2a8a8e1408f46ecb18b514730227d1924184ead6bab9ea0cd855a1cbe45b1ee35b5921c7f9610578791b728767 +5d09d2b1d3fa6e12c10d8b26dc9aabc8dc02bd06e63ff33f8bb91ede4b8694592a69e4ed4cdf6820069e2b9c7803658949e877ffe23bf90bcf5ce1409c06c71d86885a94048b05ac0ec9db193e489a5a2bfa367caf6aa8ecdb032be366174343f6875d2fe1785e8d77334f5f469cec64998e08d3303e5c9a1923b34fdc105d65 efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085 a96cf0e991ca2525da55325d0235f73e574223e6e28c6b7935ce59031e5cea6bc629adb39f6cfb7cee602e61cc1879fa04910ac5f7018cb4c1d0595343ae90eb89f6b6c456b50aa9cdaadaf19253a6b79013a9e11563e07d3bda2c078b014487 +50f6dfc81c6cf189e0a310f992907fe93356cee9dea9a41c7671a8daf3f4cfe0c459ce6122c1e731dbf7593419d7114cb73b46956158a982c5d52c72f43f0f822046093c69aeff1f7e4cd8af00ba655c5baa2e7b6a400b4be1f6fd51b3e4cfb35a69c80a28c5cafb771b6c2e52e0aeef0e3fd045e8d40745f3f8b74fd969f816 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd ade0d32a62a86e76cdaed86c5c3a53621a3449de52a499cde48c7da4f530f2a7d755b460a93a95a55e4145982309137314b6d7bee3428b87ad9bebbc6c64536c58594563682bdeeea559a51172e226eef4a95f2512c2d9dfc667b92e2ba156da +e90129ac6672c85bb7b6b18e9dc199c96c81fd65034b53c77818364d512366fb9cd1bc7c82404c451e561fc1ed916c0948f6ac561b33a1ccca093f07684b8c2bafa9e966377bd208556018a5bafb9edcecf70498c7140fe9c8cf3ad8b8c3b0aa489df797944465047465415bb0e24333235fcdd59a98829a3941eaaf62033e82 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d 98212324f012d94659b82fb7f0c38d4963dfe09aa5fea84b6b4ccb938f55b5f85e05908dca2847c1661da7ec4eea726312785db2d4cee85f1739ee803006fc05bb304b0268042dcc68ee2d19aff244a6bf3b38de931b5f121b1cf0233602b0a2 +3c9a483c9bee33b601549c592a82e95b4319b1e74b777877f0971bcb4273716b268e8f99f876e42f942f4cf08284896bbc1ffbf094ac0956c3cedfc3580cffa8c74fc6db29a371f2da2d05edb9185ece741fe0d3fabfe9d5b4d373755ebed13dc6840cfa3283b9ea46ec8b95c434f253ae86998182e9cc0e95ee64f323fc74b0 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0 8fbcefc63dc26ec7e5ccd0ee3c6d4cfc240862ecb8e0c83382ad745b0bde51e82aed8bfa094c55d7c49382f060cccafd18a62fd5e13b323fc35b7ab4149d228595a3f104805947718c4dd711dcf1f9ea300c9bd339db2fd39028ad538409f5a0 +bfc073fdda63c5fccaa0ca8770c293e8154e7aec56128bbac4fdbd541d602216ebf7ca1e02b514d6e396f20683802ba3f334310a9226576926e3bb19ceee27738d13377cbafeb09d091043501702a07aa31d1f29d50ddc55adcf16ffd40578e734a4e6cb6535f26ad48e0c62ad90e79720000e87d419e92dca3e11f943655b03 e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d b607e332d063fae94dfd32fb0aaaa4ac4619b9eb762e657aea6834ae97ddd9292624c499319b0dbc34df3832105fa3610101e6b5f332a4aa8b1e376667c389a1666f23f481bb28acd9ecdd80ce07719f06d4f050db18b1d5cce4bd3ef285dd09 +08079955d1a1f33728128c73673ec9f21a6ce138dcab5adc4dc068e6ab57314b9fbd8b013123b2fdafa9524fbdd0288777a233de8055cccfad83046ada6a19f01c47817496667bba8fc8b9456fc0e044a562d931dab1adcb66af8b66325bdf28d83ded3e2937958ccd19da540d70ef2c189f55a506c9c0d63406394c5bd3823b f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7 a62020961cef4b15321a6502563df35c3110ec1c76413b6663cc8bdabfaae983ebc5ae677de750cd14b30721ed92c93101ad5faef857ee87f2308d9c72e18f82fc304f78e860061ce07f41c5b9cddd9c5a2a7ee186ddf11e8c4bfdb2a24b6363 +23900b768f6cd42b8a8df0dcbc9cb5daec8de36b9d5c619adcc1ba2b649103d5af123746cdf19c3fd0665a6fb9338156182aa06181e3c6e37ce56979612af2927440424f89cef43fc754854b8a5c43370808cf5f9929cf47712512ce2f8a2a20d2e9f568c2848b27dfbe09142843c83905ffa5da3b15501761b03dbc2c5398b6 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c 92c96a06806c91bfe367287eabeda956703bfc04cfa0d3e6f6fc3981311e90de1210d54ad8f8df89136463c32962e682127e33475885028e9c374861881aeacc9a007316524a4e053418cb8b09b1eca70b0fab224ecd02247cb6c8f83ebb24af +1eb28c0bcdd18f73e347f957ece15b4cc83a771b0877e1feaac38e24028fb38ccea8b54ee017dc7c3d5a1327bc6f40b294aa65d7dc487f278846cd101ee84202f14b38aa2c275046aa2577f65ebaea41cd383e8def2fd0b4444dcf426fa75c4082cd7fa035cdb1e0d34a3c79d42130f5b0273eae75bc701dda3aebe7358f41b5 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18 8c4bbb1be1ede062b694f162ab5394b39bf0604c68549e8650f575884f5b57870e48fe34a44f7f19339a5723da2cba1f00077626978ba17c92e37406819c817340e4badc70a027110392863769f4e291867a778d40b2e17af2362e6680441898 +efab51855407438fd5c250670366bca3c026ecec4a59394f00d8a4b51746d0c4564366656d507e3e13e62fe7abeb976b8859895848dbaecf6582f1898ea06f00d4247702ed9721bd375aa83ae4c67c2eaa6e080777ea5ecf2cf787d785389560ac91cf63a52f0373c3185e18a3b8a466e21b61a239f1b77624eb1acacc76c4e1 bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a 9652620081783decd460b7b879887a72263058599bfe9adf5de99384d1a581d854e642a24c85df1a5130c8bc7a3541b2166a071aab2e45c9e127c1d31329acc1f55b611b3f18aad4758111190ef7f00c65a0651eb218d083ef794260690db671 +31c29ca10279a417f0cc9b1382cf54dbfdfc89f2e6ef08c403c11f580cbf8674b141ed1a417563282d99a55fc616d836421cde9424815c95e7fb7668bf3f137b29937f14882d74e034b732d78d91af7721aac4950734f5fa5d4b4d35534974f8cab6d2e6dca75ddb57e99148c8a59df9fc5bcd723e546e8356f671cf2f65640a dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738 990441c96f7c13c23bfd44f6d7b3fab86edd1999b45f48f9adcbf7211220ed00fdb4c7aaa518ebb218622c33635bb9b8102972286e9b6dce6b603f70fc3e4bb4bf63e865a240a7be06f2743c585ea2284fa700633ba6c07852d3b368e990a372 +8db476f92e332519c1a0ece5d8deded6efbd2d8e8784eea0a6b4c3b4296c35f5f8de4317e5c1627b91fb1973fee86c06e4992aa5a20cb7475c8808ff1da354d07a488dffa7838c6ec1e3f99e3acba831f27bee8434eeda3eb36d0c6df3658883cd40068b1bed841310f6eb38d4a3d07d85848770ff7933c054cd8b34662660b1 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01 a1825fb48219d90249dd035bf60962d37acb03c5bb51d31865209b03bceaa1cf35991019cbcdb5646b47cd79b1297c5f1967073192bd6da474337df93f75c2d34fa8df6f6e0d5a776b3b6331580f8f7ee4a549def4fd10379e53adc69c864930 +fcb272c828fe8fd3c6f8de9410c7b6e2b36717c1b0e5e359e9109bd7fc378978aa98182a9d99961898ed88999b050d3b64d1457d7a899d6d273b9f4dde2aafa36d76329d62509043c338f265fc4c7d938459b7fa3b230a9f6cb632b61489546bb4181a5ad7f0d7369b8caced48eb374b075b2b325bc86add0f3b680cd9e80acd 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28 8221ad3035e57e30b4c693a414777bb569284f911d7fed129093d0e52e2018dc4759db5060d396e7024f67a2e7be067711b4548e7ca43d6a11840d4b3ae3f1ef5ed23d4e298d842b789405ac7c56f6a28d3bf9f665dde47aa5c1feeb1e698f8a +7522492bdb916a597b8121f3e5c273b1d2800ef8c1db4f7dcbae633b60d7da5193ba53a63d7a377b351897c3b24903ae1cd1994211b259be3e6ae2cbc8970e4957fdf782c7d1bc7a91c80c8ef65468d4ef35428f26e2940ae8b0bd9b8074236bf6c00d0ebe83f9ddb2ade0f835138d39f33b59f244e0037c171f1ba7045a96f5 ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6 89ec332c15392aac2f61b19b55ec3f98bb103bdae8ba037e2ebafb6b5281f1bee644af58fee97e57d249fe5fa4164e1f19081210a89331907f9c5f908d769d510b11ce0d1f33a012ed77447705678b1ee997b6ec947d7db378e7fff6f554c7e2 +61097114ff855c3e34a62d9b853f8982d35f29cfa4a89893badbca7849e5fb437a1a38d6451bf0ca5a0d528e352b8e4b57f2ea359a7fc8841d49dd3e570f9b016f14156b0bbc4be822e260bd147ec081454969e11cb0034b7450ef4deb7ed6edb977e2f4ed60121aa095fb0ab40240dc329ecc917f5c64b4410612af065ee9dd 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc 816090af1ce3eb1026fcc3def5b12a38753881378c59226e7f606acf1194a549818f1586679ded0c2aecdcc950b176d3049f6df23195b11817b2ee2ca0bda3e30daac450a3ab0a98c12d81906d0f3c4663300d825913cf29278ab487c8fa3693 +dd09ae6c982bb1440ca175a87766fefeacc49393ff797c446200662744f37a6e30c5d33ba70cbd8f12277fd6cc0704c17478bbab2a3047469e9618e3c340a9c8caaff5ce7c8a4d90ecae6a9b84b813419dec14460298e7521c9b7fdb7a2089328005bd51d57f92a1bcbeecd34aa40482b549e006bbf6c4ce66d34a22dda4e0e0 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b 9487eaa0b04315132e8499db70bd89b07a2b7f1490456b4c880a1bc3b597e80b530ce9ccaba1df157e20ec4eb2cbe45d12d7f5373d9dff46349d1c7dcada99949d48e16354f59e05c1fa22698eeaf4f76f1bc41c8bffe46bebc5dcd44fb0e2dc +37a73e2774d3b274db426c89b945696daa96035031f72cea01894b24508c7f81961ec254d36ed6a0f448e11cf7950af769dc6cd2c47e52c6caf0ea92c270974f0214b4db436c36a60fb722060a6bb544462a82e1714f5906ec32886f7d59ebf289541c3a00ec1e004892ef2b1286a0194f55d083c6ec92c64b8fd1452e1c68ba afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc aec467b1d537318e355fa6be605eb52af22a4497498166a8c26ab306e23a49641b778fd461069a71c50fc1077b02a989128f3763be22e52709ee3dcc66cdde3ca98ec44bcad82fc827dda2827f0ec30d198ed8ecfebf84d05f62b56ad9e71ddb +9dc2046ffdc6804544db964481abe5d2d276a2a9eeec4c7ad40215b1de23561d402db69bd0f6eec2254711eea4487c64d9a6b62c3ebaf5ffa8db6e7e3a6e17154d126967a47a853a6f8339bdca9be306a13c7f992ded7619b0da59909a49b1e0930360e05b47f18628a36d69b2f87f2bfddd6a5d4a72f84dc76dbdd43f3a6a35 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c a50f5a5c226569d603ec848ed3f3ffa78bbaace8b066942adedb2bc2c2acc8a58f0ab43904f8bcd7a5f7b58ccd1bec82114a0e2e117d79a1c432edc0276bb53c568b763fc4dcb5002ab1477f1ba24c12f2ba12407dac7a2f5d96dc58aaf4fa8c +d9c6847fce688c5e7525a1098b545cb6c15dcd21a02761fc82fc664372a667390680135f91c01a2fa5430c634b1a6d1cd6002d8aa021e7bf5956a7901c2f81bc25d502ba5f55a55f30c0323dc68205cbefec0538e68654e7b327ac1743641896c3e740d8f66f400902b304eafaa4e0d8cffae140536f0922444cc3216a675697 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc a81855c3fb8e547fac501dd75f7f659162fba889f93e187cbe705725cfa92245e4b0ace97d2ed8cfe3fd1f5d84b608f70911e0ef52749bd9f742598d5647839756a94b70a563be10ea0c73631c9a6f6e4c8ae42da1838078369303aae3a91ef5 +69df8a01b66f04930efd2012ff2243874f256ca8758145d2a9e4ecc84d0dbdbd0dc494ae06db0ccbe819918137c90957114558580d6623efbafdd342b38dad9f08708084d32f874fba04782ce26aaab78de2102ad171f8a8f2b30b5bd3d55fdac5fa3acd6f7def7e61c2533938572b331ba6d1c02bd74bfdbf7337ade8f4a190 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4 8256d342e38e48d66a603aaca704f4f57c71dd008f9089d5d9a64baccef239a288a9edef79b1279d798a00c51a51b8880a317c45132f0d2d1d0217d6fdcd32d7a9750e5203633c12a5f631eaa81e7af1622012f6576f7bf32e29179f2bbbd0bd +927524982b8d60777c1105c86fac05f634abf58c73f84fb95d81ba0b86e1e43592c4fcad2e395a40fbe7005697d86088e2fb3bb7287eb3f917d4f2dc281f5cbe65d05b4f9623bca849b10a03beca6aa2056a12ebb91cf257ac448c5e9a78f8349a6a29b17c8978bef43a443cbb8a149eb23f794844fc41693f2dbb97181444be a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916 b0cacd44cb336667745487e9d2fda1d65f11835aaec325574d8e4afb7c0768fb7c9c1adb481291effeba9b9bbb283f3e0a5748fb779e3e83d9a2d2a8dbbe82b4351e53d07a4a096f6eabce677cab68d018b17259ad6a3a902b281a42e077d2ab +5f9042283561e7f19a436d01c7ef5a950a6d77ede5629cd7e43c0a5d58e8c5673c37945a453291d12938253c71dbe12c8b022ba7276eda6be034ef5ec1ec77dbd1e08f0d7b8e7725b7ec671c075e008a20f77f4ab266f97079b0aa6337df59a33b881954084057b21f294dd14bcb0869a4a6f1f597955ec7bf9d19bb3537a66a fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b 8af33bcfd106d5bce0edf78379627af0f8ef068e3d21c87462de5959a02e7bd1f1d95206bd93027e03faf27df4bdcc03089768c49e88b212600f49dde0aceabcd120253a1dad7b96e25a85bd270aea9314cb602d60b6be86dc85909eb4f34114 +c2ae5573d3bf396523bfb703db8502fd0760cd1be528f6ddbfb95aad399e0b19f3bd9e0fabdb05d49e3f893dffec5b627c9c2f7ad5f32e92e4e27a38cb5c28657657377fdfa1b66cd7ac3d15c6d49df92d284db99f69744f37dc7cb4e7d52920fdb200a7942623a7057ba82e467dcccaa5da416b48510d8364446a6a5e2a5aa8 a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea 8e1f7d71cd1b0b023baca58e3d05905aa9725a9a8db2370b23aa4b7b2ec7dfe9ebc968d7444069ab2772030ef54c13af0bf48892810e6aec032a85ca64e08bada600722d98e46edf5cdccf017667a9b15059882956a535305f5989f52b7f4cde +03c1a1cd30a039d0dcb22fee2450a7fa79495a0d0f4f43d2de4d75bce003c0334a8860f5c164dbd94888a9f751235a3e570d31070e3e1293a7be616af7176600585d36ac013600157d2569d491da4b8a3bf3630c26e0b9925412189f50b0ae6f04c86477932e2ecd8c3546106ae1ebc684cc3adb27ed665eddece886adea4ce3 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0 9517ea66899057986265d014afc775d9a003b495291e5ab08b4d8bcc9e4238cf2c2f01a5914bae0f6f694d2116fc0b9f0ec92ba42391bb2c7a595a87cbeb7dd6c5a6ec5cb638067018778c65b44002af34b6df4d475fbe4003c636f11d4255e6 +888f6d9bc7c86c0079fbfd42d8c08d6958f40f6e570fb0b1f03d2f8f8a63df4fcc87b379a222cf835820a999d34996e08961f13b86b075e7fd1c303cd3baa44de42168561589012f7e5300da4f8bdf470c07119a5d9f7ba7293568cd7c6a1b7fc1e41cda40bed7d46e5a28af67ae2aabfefe67a86a1c601e6f5ee543e09bd7b6 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294 ad4d2e09786db225a655f8894f23622c4ca02dcb1d057154a40d51c2b2f9db1acb01e6c32749e09a4008618e8ef6f8d31976ae66e68088b6e27244f1c27327076ec7e7307048d45ac6f4908da423b0a57e098f8730bc1c18d11e3f90755ebd83 +48453340f1317769e6ee6e103153714365731163dc18f84e9f2fa4b120f9c5a9645ee2f9b66c84c26d95912b422b009b64af96aa418b2427a4209f2e7513ba8e43ec8cf20b34e7529b22eb1199545afe9a9f7d9bcb320aec9ee0162f91c0d1dd9674c9c284f25199c5e109f6f84d7ed0d269cc6413edb81bc2c83e37d644d8b9 b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a b58494a19f758c5348bf977a700bca8874e690a5cb52b2ff4fb9622ad0cae7be697eb13ad9cf2c86d5371e3ad572bffc0f580a5cc3258204dca2dd9d8e7bc67fcc580ff14171e4446554ceef68109d8919ff6067d16719625a3c5bec00ac0910 +4bdfd3b91d83108409ad765b256e0c9b9937ecf647f8e6f9fc807e2e72af8246178b3fe046b4ea10170450d71a4eec790ecb05f03d7077341de26c4db7eeae24d55c9a9093e837dfdb38168fe8230cb9605825a1282fecd741989bfcdb34678fe077477927f66bd26d003e5dda22043341a14dd31841ba483ad5ce2701e0f68e 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4 868cbfce426a9bd415f8bbd0bfec0fb78af09ad070797596c19fe7f50a04f1da1e7a35fc66d56c69e58128483583607f0edf8d1c3773cfd93fa54341dd119da296d58ba171e9d8d35f43d925c1a5908d7fa571992ac3d4dd2733d54c78d08a8e +e6cdee8558bc1eacc24e82f0624ce8d02cc8d925b4dd3dec3a72f4a4e0fb76076bfa3ef2e2c33bdd7c27b322bdc09bbfee8fe46f75dbd7bbd2af09690b7137943efe21706e0a1b6d3089540fc58d85ddb55ea836616db573e36c521be008893f40a0a7c349602cc178ea43be59d31ec6449e7ff2c5379379f7d7645134df1bc3 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04 95c39396d88379d7566d941faf77455f53e257d02d68a018f500707928cc0a355ffa28a05166624e30ece4b1f7ef9d6a0d7520b12db5b5068fa10a068fbf36f660663c06a364e0b5b6ae1ee06fc832c6087e56d8cc651934a918482d759cd91d diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P256 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P256 new file mode 100644 index 000000000000..a749664b1a39 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P256 @@ -0,0 +1,60 @@ +ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590 b1341b7f4fbaa9228ae3b98b8c070c8758d67e111fc20f11a49fac426384b148722791589aaacb4a1d48ec93fe838bca1217078d6b4ae284d985c1081a622b32e8122612bc0bab3596d052e82b7562fd48f7b2c78ac344ee784fd5f53d5a00ad +9155e91fd9155eeed15afd83487ea1a3af04c5998b77c0fe8c43dcc479440a8a9a89efe883d9385cb9edfde10b43bce61fb63669935ad39419cf29ef3a936931733bfc2378e253e73b7ae9a3ec7a6a7932ab10f1e5b94d05160c053988f3bdc9167155d069337d42c9a7056619efc031fa5ec7310d29bd28980b1e3559757578 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98 b33d55ac59b8ac68291f25cf2ee53d8a3bb2c6e969ae3803308fe300158016d12ca5da94fd57f55e15416fb04d76e97004a38ef44f889e5f9d079f52786b33d8ecd66e03675b1cd4c785fe087c746b7003cb6cdd828ba1106cf7405cc4f0485f +b242a7586a1383368a33c88264889adfa3be45422fbef4a2df4e3c5325a9c7757017e0d5cf4bbf4de7f99d189f81f1fd2f0dd645574d1eb0d547eead9375677819297c1abe62526ae29fc54cdd11bfe17714f2fbd2d0d0e8d297ff98535980482dd5c1ebdc5a7274aabf1382c9f2315ca61391e3943856e4c5e616c2f1f7be0d a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870 a3d39937ec047753c02c5fbc06a122a2491f55bbe4c5ef14f7c3d885fed4fdb12ab0cf6686f56d18054a90e82567c4630616f41b0beef580c589d52761380cbf208792b3ccefae457ed1487f03d0dbb2d78802b123ee9a6ae2c09466019ecb4f +b64005da76b24715880af94dba379acc25a047b06066c9bedc8f17b8c74e74f4fc720d9f4ef0e2a659e0756931c080587ebdcd0f85e819aea6dacb327a9d96496da53ea21aef3b2e793a9c0def5196acec99891f46ead78a85bc7ab644765781d3543da9fbf9fec916dca975ef3b4271e50ecc68bf79b2d8935e2b25fc063358 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f 99aa38d3f78f1b15b3ccbd87f62a71f614398c151078c9f8bdfc97ff5073ecc06371340e67d1faeabb088ff9ff1f54ce043ae45c4dd92d46676dc20e2dfd092953b9bdb6126999b32431e4e1e7fff57ec12ac1ed361ae10dd4e44a013fa09a09 +fe6e1ea477640655eaa1f6e3352d4bce53eb3d95424df7f238e93d8531da8f36bc35fa6be4bf5a6a382e06e855139eb617a9cc9376b4dafacbd80876343b12628619d7cbe1bff6757e3706111ed53898c0219823adbc044eaf8c6ad449df8f6aab9d444dadb5c3380eec0d91694df5fc4b30280d4b87d27e67ae58a1df828963 daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d b908c89c748618d15689651b50cb43c6a6e7b93d7d37f4b7d5e5f79415846dbff72824435cfbaf2400fc1af4dad4509c0fb67bf97bcc4a01c8838fe15e696339b9bf65a8fb4f8628bbb85bbf743195606b5a8afc5b18783dae3b27bc47d3aea9 +907c0c00dc080a688548957b5b8b1f33ba378de1368023dcad43242411f554eb7d392d3e5c1668fad3944ff9634105343d83b8c85d2a988da5f5dc60ee0518327caed6dd5cf4e9bc6222deb46d00abde745f9b71d6e7aee6c7fdfc9ed053f2c0b611d4c6863088bd012ea9810ee94f8e58905970ebd07353f1f409a371ed03e3 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5 97f9699947778e450813c643f515fdde6efd436661f10a619041ca54a3bdbcd62b2d9007e050407c3c45bbe4c834abeb159dfdaecf5777b22368c9d2566c5602223970728cbb2fbc50ba5beb2e90ab878f032af6161677025cd96164e98ec797 +771c4d7bce05610a3e71b272096b57f0d1efcce33a1cb4f714d6ebc0865b2773ec5eedc25fae81dee1d256474dbd9676623614c150916e6ed92ce4430b26037d28fa5252ef6b10c09dc2f7ee5a36a1ea7897b69f389d9f5075e271d92f4eb97b148f3abcb1e5be0b4feb8278613d18abf6da60bfe448238aa04d7f11b71f44c5 f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96 8133c5ca231de1545ffcc164b22283a28fd8af9725331609739e06ccba2618f70566d235a63129e24227fb5d53684eca0a7ddbdfe2effdc0d2d9f493c319770fbee6c5ce5657f4caea32478ea3c31aab45d504f28b056969389982c9a49ed6f1 +a3b2825235718fc679b942e8ac38fb4f54415a213c65875b5453d18ca012320ddfbbc58b991eaebadfc2d1a28d4f0cd82652b12e4d5bfda89eda3be12ac52188e38e8cce32a264a300c0e463631f525ae501348594f980392c76b4a12ddc88e5ca086cb8685d03895919a8627725a3e00c4728e2b7c6f6a14fc342b2937fc3dd 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d afe4666c7f9fab588aa3ec30a6fcc9221f66da0399b43a6b3e918bef219ad65e236c42ebab243954fff24c27e94d498c00e1089dfbf7dfcc9f0b55d197483ebd0ebc0f1985eb958f32668f7fae067e22c4e472b034355b5b504a527e275b424a +3e6e2a9bffd729ee5d4807849cd4250021d8184cda723df6ab0e5c939d39237c8e58af9d869fe62d3c97b3298a99e891e5e11aa68b11a087573a40a3e83c7965e7910d72f81cad0f42accc5c25a4fd3cdd8cee63757bbbfbdae98be2bc867d3bcb1333c4632cb0a55dffeb77d8b119c466cd889ec468454fabe6fbee7102deaf 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9 82ad28b83d22689d94a4be67a78ce1abe0d27547f9dc19fc789ac14f12cfd4b707356ea207cd2832e258807d5c2936c50e6ef733d84e5e3c6414e12956db99fadc53af0e77f28e4bd5d60bfe9483873b9500d3fedf46fbc816545f10f87d544e +52e5c308e70329a17c71eaedb66bbee303c8ec48a6f1a2efb235d308563cd58553d434e12f353227a9ea28608ec9c820ed83c95124e7a886f7e832a2de1032e78dc059208f9ec354170b2b1cab992b52ac01e6c0e4e1b0112686962edc53ab226dafcc9fc7baed2cd9307160e8572edb125935db49289b178f35a8ad23f4f801 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634 8257aae663c9e7e0995707f2ea748d4e4f17cc041ef95914d028aaaf0b8add30bf0d2ee0c51ceb2272b68d007792ebb70c7de7fb8cd113128284428b3bf21908d5f7a9ad7c05da4ee14a26f1bb22e2b61842a296f6961686655b7ef8b0e51a80 +d3e9e82051d4c84d699453c9ff44c7c09f6523bb92232bcf30bf3c380224249de2964e871d56a364d6955c81ef91d06482a6c7c61bc70f66ef22fad128d15416e7174312619134f968f1009f92cbf99248932efb533ff113fb6d949e21d6b80dfbbe69010c8d1ccb0f3808ea309bb0bac1a222168c95b088847e613749b19d04 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27 a264a50ae3f1e6dfe29cf0714bc379768d1c68ee23e9a2ce53d7aaced3bc747efc3a1cac036c59b2150601db517a520e1503342a9511701b55fcaee3cdab4c3f5a283c9bbb0bada206e18899ef775bc35e043e496dd9184ccd03d9e87159bd59 +968951c2c1918436fe19fa2fe2152656a08f9a6b8aa6201920f1b424da98cee71928897ff087620cc5c551320b1e75a1e98d7d98a5bd5361c9393759614a6087cc0f7fb01fcb173783eb4c4c23961a8231ac4a07d72e683b0c1bd4c51ef1b031df875e7b8d5a6e0628949f5b8f157f43dccaea3b2a4fc11181e6b451e06ceb37 cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d 8fb3f0796db12aaa12ccf32716f62250ef630b0d24e1ba0122fc281c24cf514bbbdb932ed2e72fab7a255c0ccb5028141590f179dbad37c4d5d32194441a87760edd7392ec098212cb2ba694481acd801300a4c31a560e80516ef2439c8a8bbc +78048628932e1c1cdd1e70932bd7b76f704ba08d7e7d825d3de763bf1a062315f4af16eccefe0b6ebadccaf403d013f50833ce2c54e24eea8345e25f93b69bb048988d102240225ceacf5003e2abdcc90299f4bf2c101585d36ecdd7a155953c674789d070480d1ef47cc7858e97a6d87c41c6922a00ea12539f251826e141b4 b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c a1e6580249c0bba01c73ff6080113617dc82da4cedd6a2de574ef05bdec0c287cb6dc664247de76fab1aa1d485750a3006c63557bbdebca55b46e1ab9e47b3803f9eaa6c859cd3a0e153ffeca47bfa5453417fb11b64d1af3635f5d4c91142fe +9b0800c443e693067591737fdbcf0966fdfa50872d41d0c189d87cbc34c2771ee5e1255fd604f09fcf167fda16437c245d299147299c69046895d22482db29aba37ff57f756716cd3d6223077f747c4caffbecc0a7c9dfaaafd9a9817470ded8777e6355838ac54d11b2f0fc3f43668ff949cc31de0c2d15af5ef17884e4d66a 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48 8c906e8ca14966ad26c5f309542d82f6ed0158d5d862576be5f26c68ca9d2157c0b774f7ff2b803c101721d3eda603a319729ef5c82d90a75b81031443c0a17ef03d8d141ca65b8df69d73834ea1823f0620448573d430adfdc8d6cfdf7266e3 +fc3b8291c172dae635a6859f525beaf01cf683765d7c86f1a4d768df7cae055f639eccc08d7a0272394d949f82d5e12d69c08e2483e11a1d28a4c61f18193106e12e5de4a9d0b4bf341e2acd6b715dc83ae5ff63328f8346f35521ca378b311299947f63ec593a5e32e6bd11ec4edb0e75302a9f54d21226d23314729e061016 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f a91cdea820e351c99c2fddedc34ebbf1e5f45261cfa30f2df5a266253bbcf38c9c1343ae69cebc1d8a281b5d30fc1dd00f1e53acbde314fdc7f622edbd929bbb36a557fa86b3fdcb4940af66084210e5e1701bfda641593da5b459f41d7043b1 +5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 981f919aa6b9036c4478b39bc1ceec1523ef3f2ae0e51a4de9fe4755b221e66eabe83af87e7d3dc882999d0cf102c68403813fc3796a01ae49268526ade8d461a90e2803642560006e0c8ae9dea45ff52b1a39ff18a7d037196d94158ebd6f8d +c35e2f092553c55772926bdbe87c9796827d17024dbb9233a545366e2e5987dd344deb72df987144b8c6c43bc41b654b94cc856e16b96d7a821c8ec039b503e3d86728c494a967d83011a0e090b5d54cd47f4e366c0912bc808fbb2ea96efac88fb3ebec9342738e225f7c7c2b011ce375b56621a20642b4d36e060db4524af1 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 982f08cfa9fc643eb45fa4c439071bab9faf1a4b330685c6e0bd824268dc7d9f0a5cb77d7c95f2b7a0bee68ee8904cb3169188e299c525d5a115f0bf1c9be4d9468b7415c6514fd0c09b66e96cb218750d8157b707ef1047abc178513b5d08b9 +3c054e333a94259c36af09ab5b4ff9beb3492f8d5b4282d16801daccb29f70fe61a0b37ffef5c04cd1b70e85b1f549a1c4dc672985e50f43ea037efa9964f096b5f62f7ffdf8d6bfb2cc859558f5a393cb949dbd48f269343b5263dcdb9c556eca074f2e98e6d94c2c29a677afaf806edf79b15a3fcd46e7067b7669f83188ee e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef a8db3d631469456fdc65db3bd81499adb95ec0c4c4a3ff07a9cdd0d4cc2f7c2e5e23b2387c4e61db1c2dada0c6d7cf94070c53de095aae070c7448a0fdc60bee902b2c4e87e2a70980a7ce9e379913a0909715b39dd82f1b5d7dbeada985253e +0989122410d522af64ceb07da2c865219046b4c3d9d99b01278c07ff63eaf1039cb787ae9e2dd46436cc0415f280c562bebb83a23e639e476a02ec8cff7ea06cd12c86dcc3adefbf1a9e9a9b6646c7599ec631b0da9a60debeb9b3e19324977f3b4f36892c8a38671c8e1cc8e50fcd50f9e51deaf98272f9266fc702e4e57c30 a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 84b95c67388990780054e25140b8e1ec83a9d29cef82c318bb2396e40283a1212a764f6037a556b99cfcea87f8e43ece15e6d1a40a52b16c8768054c9569ba0f5690a0424fcb3c7a0e8bfc2b3fc2bdee959a9942d137b09f4871c6273603d67e +dc66e39f9bbfd9865318531ffe9207f934fa615a5b285708a5e9c46b7775150e818d7f24d2a123df3672fff2094e3fd3df6fbe259e3989dd5edfcccbe7d45e26a775a5c4329a084f057c42c13f3248e3fd6f0c76678f890f513c32292dd306eaa84a59abe34b16cb5e38d0e885525d10336ca443e1682aa04a7af832b0eee4e7 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d b2bb00cc0bc01090239e05a675aeffd13f1b34a45625b22526189165389d0b9b12ca4038a4337b8834fa8c6611efa1aa03e2f6b035bf5b018944b31779f3297499321143d3c1cd58703e2a79204884349d173aba26e74624f4b59fabd8026e9d +600974e7d8c5508e2c1aab0783ad0d7c4494ab2b4da265c2fe496421c4df238b0be25f25659157c8a225fb03953607f7df996acfd402f147e37aee2f1693e3bf1c35eab3ae360a2bd91d04622ea47f83d863d2dfecb618e8b8bdc39e17d15d672eee03bb4ce2cc5cf6b217e5faf3f336fdd87d972d3a8b8a593ba85955cc9d71 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d 8b70a96376d80e1f6746e8aeda6263611520376ebece9a860a90de3e805e9ce337880dec160f9e93636affcc2cc765c00c96cca99b8de780c19aa5b79751c19cb10b5fd45bce060855cb6a4ae167f932e9ff69cce9be2e7e2b8c93dcd19daeae +dfa6cb9b39adda6c74cc8b2a8b53a12c499ab9dee01b4123642b4f11af336a91a5c9ce0520eb2395a6190ecbf6169c4cba81941de8e76c9c908eb843b98ce95e0da29c5d4388040264e05e07030a577cc5d176387154eabae2af52a83e85c61c7c61da930c9b19e45d7e34c8516dc3c238fddd6e450a77455d534c48a152010b 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab b4c16e523865723004d7bfb92178ef78fb42c9f3d97bac606c762afc8c2aabfc8ca2861cbf64a2a659f5a4b34f02eb320b8d07503d770cbfe2683c55a7af93ea5877dc2d0af3c73eaeeb0bdaba5e65f3724afcbd5e56477daa030910f6e16272 +51d2547cbff92431174aa7fc7302139519d98071c755ff1c92e4694b58587ea560f72f32fc6dd4dee7d22bb7387381d0256e2862d0644cdf2c277c5d740fa089830eb52bf79d1e75b8596ecf0ea58a0b9df61e0c9754bfcd62efab6ea1bd216bf181c5593da79f10135a9bc6e164f1854bc8859734341aad237ba29a81a3fc8b 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a 8a0d3d065a48aec09da664f51a24a2a73fc9717edd197eeaa5e56e56a5952b6234206c15ddf1ceb8a25b1bbcbe083f931754d9dd73f1c726f2b4adf5e330e8400cbb5fd6b0a6aed6a1264bfbc299f3bc53900fd78bc7d8f0395c9f98b403a472 +558c2ac13026402bad4a0a83ebc9468e50f7ffab06d6f981e5db1d082098065bcff6f21a7a74558b1e8612914b8b5a0aa28ed5b574c36ac4ea5868432a62bb8ef0695d27c1e3ceaf75c7b251c65ddb268696f07c16d2767973d85beb443f211e6445e7fe5d46f0dce70d58a4cd9fe70688c035688ea8c6baec65a5fc7e2c93e8 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 91808c1ce169cbd6f208c24c566984e85cf4d2a6ed321cf2f8ea86dd80d538b3a9342a2924a471b1f2d76b8dcfe6775e00afcbc51652dd83e6c7cc9d17e26569d721a3df2d6436a938137be542b5821404fa44882237335fd355c8a7dc8de23e +4d55c99ef6bd54621662c3d110c3cb627c03d6311393b264ab97b90a4b15214a5593ba2510a53d63fb34be251facb697c973e11b665cb7920f1684b0031b4dd370cb927ca7168b0bf8ad285e05e9e31e34bc24024739fdc10b78586f29eff94412034e3b606ed850ec2c1900e8e68151fc4aee5adebb066eb6da4eaa5681378e f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 ab321ec9f6e40bfb3acabb6fbb3f6cfb890123be9e71cc3e529b46e7f1b032c2c4e4479f171ba441312663fdb1bfa228075bbe4f968b16e11a639af9011a88336d2194cb6592c6ca7aaad4f76bdd2751b3ae0825698525b10a7732f5fd36750e +f8248ad47d97c18c984f1f5c10950dc1404713c56b6ea397e01e6dd925e903b4fadfe2c9e877169e71ce3c7fe5ce70ee4255d9cdc26f6943bf48687874de64f6cf30a012512e787b88059bbf561162bdcc23a3742c835ac144cc14167b1bd6727e940540a9c99f3cbb41fb1dcb00d76dda04995847c657f4c19d303eb09eb48a b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 95faa7b4859bfd76d8b37a10b859fb801b4916b20d9de3826dac4c5e49b67444a76b13edf85e978f43e645891791f0a30349c89b69593a8701dccaf8be68a00f5936cc3ce387e117178b64864128ccf75ee79b6b93c28b6e6687a921c48a5ded +3b6ee2425940b3d240d35b97b6dcd61ed3423d8e71a0ada35d47b322d17b35ea0472f35edd1d252f87b8b65ef4b716669fc9ac28b00d34a9d66ad118c9d94e7f46d0b4f6c2b2d339fd6bcd351241a387cc82609057048c12c4ec3d85c661975c45b300cb96930d89370a327c98b67defaa89497aa8ef994c77f1130f752f94a4 d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 a1eec6408229fca37416358ba1359c190b9e0d77c11281b1e807bdf2f8f941263eff2f7e24faae40693945d79664d0f70476fb029e207b840107f0b48c2f43cdf8ec235b09686af406e31f710f66f514fed322aa76d2e2699baca0d71d9241a3 +c5204b81ec0a4df5b7e9fda3dc245f98082ae7f4efe81998dcaa286bd4507ca840a53d21b01e904f55e38f78c3757d5a5a4a44b1d5d4e480be3afb5b394a5d2840af42b1b4083d40afbfe22d702f370d32dbfd392e128ea4724d66a3701da41ae2f03bb4d91bb946c7969404cb544f71eb7a49eb4c4ec55799bda1eb545143a7 b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c b79ed86928ec82662890d43ac343d1426dd4eb44d70d0902e07aed6f4e2b436119ce51ead5088ee52e514fcea19bb28110a97b2c1cdc8cf1363b30ca7a3bf2d3c3a20425eb08ec50c0f3ef01f4d7c67a3e39262ea551e2cde3bf165b88af0921 +72e81fe221fb402148d8b7ab03549f1180bcc03d41ca59d7653801f0ba853add1f6d29edd7f9abc621b2d548f8dbf8979bd16608d2d8fc3260b4ebc0dd42482481d548c7075711b5759649c41f439fad69954956c9326841ea6492956829f9e0dc789f73633b40f6ac77bcae6dfc7930cfe89e526d1684365c5b0be2437fdb01 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 b070ebc0a575715653f5bd71b0595a55a6ee3f530f70f8e8d782c99058ca926fe3aeaf9c493003a04ddef9941487082b129413850ddc30098812c9b21635efbc19a1d1688cc396ac85b586f4bcd4fc6ad8a8927e2205069d3eed2cbb35bd1f83 +21188c3edd5de088dacc1076b9e1bcecd79de1003c2414c3866173054dc82dde85169baa77993adb20c269f60a5226111828578bcc7c29e6e8d2dae81806152c8ba0c6ada1986a1983ebeec1473a73a04795b6319d48662d40881c1723a706f516fe75300f92408aa1dc6ae4288d2046f23c1aa2e54b7fb6448a0da922bd7f34 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 8a9b51614034bdf89d270d5d624ccad8a7811096afb7c555b27c87bd52c4fc516de7c8fdfab4d328b789500b820ab5e2006f643281a0ee4e5e1fed8f979381808542d160f554dbef8a9dbf0920b842fec93f213e0ae07f769477209fe9d78499 +e0b8596b375f3306bbc6e77a0b42f7469d7e83635990e74aa6d713594a3a24498feff5006790742d9c2e9b47d714bee932435db747c6e733e3d8de41f2f91311f2e9fd8e025651631ffd84f66732d3473fbd1627e63dc7194048ebec93c95c159b5039ab5e79e42c80b484a943f125de3da1e04e5bf9c16671ad55a1117d3306 b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced 89d76003ea4b781402508ae1dd2243e7b912e5db27041a3fc1107e360008f60fd37fcbb6635061b206f29d033b98d68b017f77003362a45bf6e2a14969bdeb76d797478d4510cb64bde135f9e9b5c2355072c008fb84875eef319a55968d5055 +099a0131179fff4c6928e49886d2fdb3a9f239b7dd5fa828a52cbbe3fcfabecfbba3e192159b887b5d13aa1e14e6a07ccbb21f6ad8b7e88fee6bea9b86dea40ffb962f38554056fb7c5bb486418915f7e7e9b9033fe3baaf9a069db98bc02fa8af3d3d1859a11375d6f98aa2ce632606d0800dff7f55b40f971a8586ed6b39e9 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181 a6329563dea196c302b590fb8c84609eefea1a68d8905d56852dacab4d180f9991d6afe13a619c5dd0443a6a8412134804bdd080e43a10b57fb39216717e14916b6148e945309a9b2f409f0c717c45bd73f70bafcb85d2fae01d8e6102510aba +0fbc07ea947c946bea26afa10c51511039b94ddbc4e2e4184ca3559260da24a14522d1497ca5e77a5d1a8e86583aeea1f5d4ff9b04a6aa0de79cd88fdb85e01f171143535f2f7c23b050289d7e05cebccdd131888572534bae0061bdcc3015206b9270b0d5af9f1da2f9de91772d178a632c3261a1e7b3fb255608b3801962f9 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431 a9832e788c2dbfe9c8c5b0e5432bcec625a4a7f395cdf2b6a881b164b81a63326e534b08c919f1e37903f5ba5aeb26c00293b7bcf42970bc20e925b21de97935ba029890eacd8ef509326158e99deff0a84e45f7e465a831f1a0bfba9330ac53 +1e38d750d936d8522e9db1873fb4996bef97f8da3c6674a1223d29263f1234a90b751785316444e9ba698bc8ab6cd010638d182c9adad4e334b2bd7529f0ae8e9a52ad60f59804b2d780ed52bdd33b0bf5400147c28b4304e5e3434505ae7ce30d4b239e7e6f0ecf058badd5b388eddbad64d24d2430dd04b4ddee98f972988f 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd ada21644fd10c88a962e5203d830aa1fd2b4bf670211d952bdf09893230745e74497e9152250478c884e14d067a27b190cf60edb9744d50b08db9bd645bea460ddf6953bd650871bf2c6d82b6067477243a747bdd33a6e248b9053cf081c084d +abcf0e0f046b2e0672d1cc6c0a114905627cbbdefdf9752f0c31660aa95f2d0ede72d17919a9e9b1add3213164e0c9b5ae3c76f1a2f79d3eeb444e6741521019d8bd5ca391b28c1063347f07afcfbb705be4b52261c19ebaf1d6f054a74d86fb5d091fa7f229450996b76f0ada5f977b09b58488eebfb5f5e9539a8fd89662ab 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de 914a6833232ecfb0cff9fd82e63815a2d99f4f28fb47805f0886c5bce05fa69833d5d46373566138cda72d297f7c334a06e72fd148f461c6882a695a6ceb84d74bdbcea974ae3b4511fad7f574ba9beac0a2913820a5a191c0150c37f5fd73b0 +dc3d4884c741a4a687593c79fb4e35c5c13c781dca16db561d7e393577f7b62ca41a6e259fc1fb8d0c4e1e062517a0fdf95558b7799f20c211796167953e6372c11829beec64869d67bf3ee1f1455dd87acfbdbcc597056e7fb347a17688ad32fda7ccc3572da7677d7255c261738f07763cd45973c728c6e9adbeecadc3d961 ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566 86568370ab96284160e3ffdc5a909fbb15e03f56e665685d979391ec2a92357bab005ed12539cea4d96fe2c7b40be9d30a8295f46eeaf620547ed72ed2eeba36d593f0c5e2700366be5a7bbfbd6abc1c5017b316b05972e14b03bd25c23dfa07 +719bf1911ae5b5e08f1d97b92a5089c0ab9d6f1c175ac7199086aeeaa416a17e6d6f8486c711d386f284f096296689a54d330c8efb0f5fa1c5ba128d3234a3da856c2a94667ef7103616a64c913135f4e1dc50e38daa60610f732ad1bedfcc396f87169392520314a6b6b9af6793dbabad4599525228cc7c9c32c4d8e097ddf6 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee 88b45b8b67e3adbd4bd29fba2689ae72d9c0186ce7de862de9b46bbe4e6a66d52e9f8b63fbf4046ef18c80cc873917de14e3749875c6754da60f4dc6e8b29449cdcb7135aeea4039c9e7bf2eca09dbea5b63ecd28f5336eaff0bc7478910bf61 +7cf19f4c851e97c5bca11a39f0074c3b7bd3274e7dd75d0447b7b84995dfc9f716bf08c25347f56fcc5e5149cb3f9cfb39d408ace5a5c47e75f7a827fa0bb9921bb5b23a6053dbe1fa2bba341ac874d9b1333fc4dc224854949f5c8d8a5fedd02fb26fdfcd3be351aec0fcbef18972956c6ec0effaf057eb4420b6d28e0c008c 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd a1b530d81820dc6edddada6d30f04146dea3c8df3b0a179f2c8e44ce85eeff3463c412ccfae8ab2c5312b45553e603a50564e10130aded1fb5d136f5bbe032e9165f03c56c07190f237633a1f8b3e910fb3c7f4af4471dc5b27e360bc874d48d +b892ffabb809e98a99b0a79895445fc734fa1b6159f9cddb6d21e510708bdab6076633ac30aaef43db566c0d21f4381db46711fe3812c5ce0fb4a40e3d5d8ab24e4e82d3560c6dc7c37794ee17d4a144065ef99c8d1c88bc22ad8c4c27d85ad518fa5747ae35276fc104829d3f5c72fc2a9ea55a1c3a87007cd133263f79e405 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666 b2d6a96bca517e7762d1647d8f38d2464cd2b39474c61c1e3cbd5815935bf69e10bb77d0fb78766a10327bd252b929e30ab4ece0a45d8b7264c078dac2ccc5aad2b7d2712d6159c7e84d35492026f6e5b0ad3491c972bce48b4345cad7ff1937 +8144e37014c95e13231cbd6fa64772771f93b44e37f7b02f592099cc146343edd4f4ec9fa1bc68d7f2e9ee78fc370443aa2803ff4ca52ee49a2f4daf2c8181ea7b8475b3a0f608fc3279d09e2d057fbe3f2ffbe5133796124781299c6da60cfe7ecea3abc30706ded2cdf18f9d788e59f2c31662df3abe01a9b12304fb8d5c8c bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67 aec86ef77ed6b54a094fcb607ff6dfa7c3e52cb8c80740b49013efd18daa9a0170bcf46d1c1153716298275d0b7b0ce618e96201c61fae2d0ba247923916ace633fa7181966bd735cb7acab2f597f391097304db30632b0402b32da2ed5ecca1 +a3683d120807f0a030feed679785326698c3702f1983eaba1b70ddfa7f0b3188060b845e2b67ed57ee68087746710450f7427cb34655d719c0acbc09ac696adb4b22aba1b9322b7111076e67053a55f62b501a4bca0ad9d50a868f51aeeb4ef27823236f5267e8da83e143047422ce140d66e05e44dc84fb3a4506b2a5d7caa8 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9 981372a54a956f6d47bb84cf7e61830826f03b8759f52bb54c4ff8b8e4a268e8848970ddb9aaaf7a44f35ebe611a236c16c5988f98724ed893d7d7063e9bee13f7af54b9ada477d435e9723d93acb93333f334d79d53e205bf882a609420dceb +b1df8051b213fc5f636537e37e212eb20b2423e6467a9c7081336a870e6373fc835899d59e546c0ac668cc81ce4921e88f42e6da2a109a03b4f4e819a17c955b8d099ec6b282fb495258dca13ec779c459da909475519a3477223c06b99afbd77f9922e7cbef844b93f3ce5f50db816b2e0d8b1575d2e17a6b8db9111d6da578 f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce b0c33933354f066c4b460956cedcb18da0f6d51b5ac9c222a0945bd128d096cc3bf5e791e23113ebca009beffb4c8c09111333af3c8fe57dff6ceea6c46ccef0c3e0e6b2ae47846fba5d672fc259d8c85235ee0bae503d1a632659f5ce3cf43b +0b918ede985b5c491797d0a81446b2933be312f419b212e3aae9ba5914c00af431747a9d287a7c7761e9bcbc8a12aaf9d4a76d13dad59fc742f8f218ef66eb67035220a07acc1a357c5b562ecb6b895cf725c4230412fefac72097f2c2b829ed58742d7c327cad0f1058df1bddd4ae9c6d2aba25480424308684cecd6517cdd8 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f a478cfd6de7282cbce078edc105805ad138003dec85d4076484e96fca11648d6867d1a1b1fc0048e4cbb17f0c11dad7316bb5c7728c44b90a78d627efc9c8291e5c5550c5831ca95fe406a2a5f2066699d572cf13ffd59ba30df447364047a01 +0fab26fde1a4467ca930dbe513ccc3452b70313cccde2994eead2fde85c8da1db84d7d06a024c9e88629d5344224a4eae01b21a2665d5f7f36d5524bf5367d7f8b6a71ea05d413d4afde33777f0a3be49c9e6aa29ea447746a9e77ce27232a550b31dd4e7c9bc8913485f2dc83a56298051c92461fd46b14cc895c300a4fb874 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b a0b6596225290116f1c62c77259405ffc097cb48c272254253dc234e16446ad6f51fbe6cbbc528863e460494e97bf11b0f8f309f3f5028d425b1c74609a940f4e33371db8cdb7604a7e386f358779429f98d8992966048d9d8df16f3a70f6dd8 +7843f157ef8566722a7d69da67de7599ee65cb3975508f70c612b3289190e364141781e0b832f2d9627122742f4b5871ceeafcd09ba5ec90cae6bcc01ae32b50f13f63918dfb5177df9797c6273b92d103c3f7a3fc2050d2b196cc872c57b77f9bdb1782d4195445fcc6236dd8bd14c8bcbc8223a6739f6a17c9a861e8c821a6 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388 97189cb21b8ce6cf9c65ddb6945a4cd1b2add065d582310bf1a4802f8ee0d1c7e1f4556704c104ed847fe7648acba5c90cec985504a2566afd955e115a20b75b883dfb728b21b32c82b10874155db1b945f33c5b337c9253d1f6f75fc0190bb7 +6c8572b6a3a4a9e8e03dbeed99334d41661b8a8417074f335ab1845f6cc852adb8c01d9820fcf8e10699cc827a8fbdca2cbd46cc66e4e6b7ba41ec3efa733587e4a30ec552cd8ddab8163e148e50f4d090782897f3ddac84a41e1fcfe8c56b6152c0097b0d634b41011471ffd004f43eb4aafc038197ec6bae2b4470e869bded 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499 97a7f02e503fd56f468849bfa643d5ab1e4e3fded3f09cfc4068ce335c8ed734fa813b2bbcc82f6013317f98948eab570efd0fdd7215727f4fffd18c46fd11a62187fc505803224b91ed78bb50df6c38147d1b15dbb549ef91d2ddeecd00bc88 +7e3c8fe162d48cc8c5b11b5e5ebc05ebc45c439bdbc0b0902145921b8383037cb0812222031598cd1a56fa71694fbd304cc62938233465ec39c6e49f57dfe823983b6923c4e865633949183e6b90e9e06d8275f3907d97967d47b6239fe2847b7d49cf16ba69d2862083cf1bccf7afe34fdc90e21998964107b64abe6b89d126 f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6 b4756f753f4597e46c4dae5c539bc133f947e8532d5dcbe9da3a222f4b88d2570a1ebe08de9079a5c382c5e65aeb737a07bbbfffaaf1f981d60df765c299ebb5f92bb7e434b30a0f383cc6222f2d2cfe101ddbea2c2a6afe6f77d6f6d8d749ab +d5aa8ac9218ca661cd177756af6fbb5a40a3fecfd4eea6d5872fbb9a2884784aa9b5f0c023a6e0da5cf6364754ee6465b4ee2d0ddc745b02994c98427a213c849537da5a4477b3abfe02648be67f26e80b56a33150490d062aaac137aa47f11cfeddba855bab9e4e028532a563326d927f9e6e3292b1fb248ee90b6f429798db 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead b184357188ada380f1f17e876607bee9321fa1c529d74ffdff84a5522c7e0672a9ce053f10540e7ad7fc975c6c662af70a31d94eff5847d2b37a5d30d3a323b2b4f23effb44c6872967cbb1a3f90bb476f1d083bbf52e5c73ddb6d75d6eac176 +790b06054afc9c3fc4dfe72df19dd5d68d108cfcfca6212804f6d534fd2fbe489bd8f64bf205ce04bcb50124a12ce5238fc3fe7dd76e6fa640206af52549f133d593a1bfd423ab737f3326fa79433cde293236f90d4238f0dd38ed69492ddbd9c3eae583b6325a95dec3166fe52b21658293d8c137830ef45297d67813b7a508 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd 91d90ce6559d358fccb3c89eecb78628e71a9ee4f850be854352fa5194ac4132e774c78239e1ba48f0ee620b85562a870016bcbb50d7c29b945d4889313ed20a353bee144e275c601bcbcc2511123c522b646108955eb15325ccc07f80beee3b +6d549aa87afdb8bfa60d22a68e2783b27e8db46041e4df04be0c261c4734b608a96f198d1cdb8d082ae48579ec9defcf21fbc72803764a58c31e5323d5452b9fb57c8991d31749140da7ef067b18bf0d7dfbae6eefd0d8064f334bf7e9ec1e028daed4e86e17635ec2e409a3ed1238048a45882c5c57501b314e636b9bc81cbe 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117 884d200ad4c5a71affabbdab70d99d1782f9f839385c151792df0f418dd1bdec940bcb4e87dc08eb2b0df3f73b5d5139002fe65a92733d50b37b7dc7b81a6f28fbced188856aafd5063bd0670e1c814b68a99fdd01c558758d4888e9aefe8802 +1906e48b7f889ee3ff7ab0807a7aa88f53f4018808870bfed6372a77330c737647961324c2b4d46f6ee8b01190474951a701b048ae86579ff8e3fc889fecf926b17f98958ac7534e6e781ca2db2baa380dec766cfb2a3eca2a9d5818967d64dfab84f768d24ec122eebacaab0a4dc3a75f37331bb1c43dd8966cc09ec4945bbd 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61 ab0fd752aa0b5eb23b2b762b78afee81054421c9be31c2ad1e3637bb1347ee725828e13522796155ff060f7a90652b0313e7197f2f113d471980c5d1848f07c7dfb5da083d37808ebd31b20660e93e2d96e521f91ea2077e29a07fdcf774568a +7b59fef13daf01afec35dea3276541be681c4916767f34d4e874464d20979863ee77ad0fd1635bcdf93e9f62ed69ae52ec90aab5bbf87f8951213747ccec9f38c775c1df1e9d7f735c2ce39b42edb3b0c5086247556cfea539995c5d9689765288ec600848ecf085c01ca738bbef11f5d12d4457db988b4add90be00781024ad 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2 8818a61f494276b949a6357cc7b4ed422df29ddb45445d1f676157ca468ce032fc35bcd97379c89873e03813c65859150a3488f086857bb468eee1aca891cd62b223ab1f6ce06914c1ddd8ba033011abec34b4ceecd6be2b5112c03c589c7a04 +041a6767a935dc3d8985eb4e608b0cbfebe7f93789d4200bcfe595277ac2b0f402889b580b72def5da778a680fd380c955421f626d52dd9a83ea180187b850e1b72a4ec6dd63235e598fd15a9b19f8ce9aec1d23f0bd6ea4d92360d50f951152bc9a01354732ba0cf90aaed33c307c1de8fa3d14f9489151b8377b57c7215f0b 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7 a3928f9552f071400c7761255dff7ec79d6a9eb20856bb40e5c2c9dbaaaaf54a0b08ca7c8622a9aaefc627c03ef79e4a017c0b5aee9ffcdeb73be9491467f1c05d10120dc23592fb7bec4bff8f9ea8dac77c762a9d7ebc1b02b2f95166ebb1fb +7905a9036e022c78b2c9efd40b77b0a194fbc1d45462779b0b76ad30dc52c564e48a493d8249a061e62f26f453ba566538a4d43c64fb9fdbd1f36409316433c6f074e1b47b544a847de25fc67d81ac801ed9f7371a43da39001c90766f943e629d74d0436ba1240c3d7fab990d586a6d6ef1771786722df56448815f2feda48f 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870 8041437e0f23376e8b3ddd6627eddc3611113acbcd5e4be3dca4275ad0b78ca8005288d4811e79012f9cf4342d1bbbbe0e8b033c54f5bf1e02f901957dbc7d6a0e30cf45a856dba134e72244fbe1a0a11ed13064212b7f07fc357de7db881f48 +cf25e4642d4f39d15afb7aec79469d82fc9aedb8f89964e79b749a852d931d37436502804e39555f5a3c75dd958fd5291ada647c1a5e38fe7b1048f16f2b711fdd5d39acc0812ca65bd50d7f8119f2fd195ab16633503a78ee9102c1f9c4c22568e0b54bd4fa3f5ff7b49160bf23e7e2231b1ebebbdaf0e4a7d4484158a87e07 e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf a22cae46aa8977ff28334b7c13744092edd1240279fe8508b64a2e46ca633a4c2a48cb1f29ac25a1275895326b29933e070b2ecb3d1f19af944a24baa93584a2fe4338d79898e256a04af8bfd386fcfd7832d7101bf89a273549a7c3a43d4fc9 +7562c445b35883cc937be6349b4cefc3556a80255d70f09e28c3f393daac19442a7eecedcdfbe8f7628e30cd8939537ec56d5c9645d43340eb4e78fc5dd4322de8a07966b262770d7ff13a071ff3dce560718e60ed3086b7e0003a6abafe91af90af86733ce8689440bf73d2aa0acfe9776036e877599acbabfcb03bb3b50faa 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c 93a631a7f0033289ddb29b234d6a8adadee798da21d24c09b1884139257f105243ce432d6eaed29d50835e54efd45f730bf54d974cd564d0bd30bd502f31993b6724c61d221ed047b54214256aefa9e3b0fd3d7791fb0335bdcca9f6cf892cf1 +051c2db8e71e44653ea1cb0afc9e0abdf12658e9e761bfb767c20c7ab4adfcb18ed9b5c372a3ac11d8a43c55f7f99b33355437891686d42362abd71db8b6d84dd694d6982f0612178a937aa934b9ac3c0794c39027bdd767841c4370666c80dbc0f8132ca27474f553d266deefd7c9dbad6d734f9006bb557567701bb7e6a7c9 f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9 98bb268a260e2cb7e4e05da9afc0e407c52fcc45299ec04cd9b6164fc56db2cee3ce821edb8dc25f3e9dc69a803843aa0263534c9cf59a1169e9d325cd0b0346764098937928a63f59a256526d539d39ed27d0cc4c7037cad668a8a3b06bb0b9 +4dcb7b62ba31b866fce7c1feedf0be1f67bf611dbc2e2e86f004422f67b3bc1839c6958eb1dc3ead137c3d7f88aa97244577a775c8021b1642a8647bba82871e3c15d0749ed343ea6cad38f123835d8ef66b0719273105e924e8685b65fd5dc430efbc35b05a6097f17ebc5943cdcd9abcba752b7f8f37027409bd6e11cd158f f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5 b15fd065d4a98ed592895600079d14ef54d5c27761a4b9774ae5482fdd655bc7398288a8a4da9b46faee846cddd5c3a002f863c9d66c92cf34f6661933521b2a7eefb0dcf35b6a28271a37b6d3a1003f7ee165bb50064ab735c5548817284458 +efe55737771070d5ac79236b04e3fbaf4f2e9bed187d1930680fcf1aba769674bf426310f21245006f528779347d28b8aeacd2b1d5e3456dcbf188b2be8c07f19219e4067c1e7c9714784285d8bac79a76b56f2e2676ea93994f11eb573af1d03fc8ed1118eafc7f07a82f3263c33eb85e497e18f435d4076a774f42d276c323 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628 8e1f22b90de76b545e73dc1bbb1ceefe3b9817f3f9bb19bd539d0a981287d571b236812f498edaf676a7f6635e9e417d02d61986dcfc2bef690ba78509581fd11ddee37eff5699c4432152f582d1668640876286fddfc26a45205d59470ba217 +ea95859cc13cccb37198d919803be89c2ee10befdcaf5d5afa09dcc529d333ae1e4ffd3bd8ba8642203badd7a80a3f77eeee9402eed365d53f05c1a995c536f8236ba6b6ff8897393506660cc8ea82b2163aa6a1855251c87d935e23857fe35b889427b449de7274d7754bdeace960b4303c5dd5f745a5cfd580293d6548c832 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49 975f87587ce1b0c458caea90e1c257812d064d5515c6589696794f4b9bdbe53f84929053c4a59d418e8c9684753d8bd41473c6fb76331da00abbbf6db9ab1c784340df604f816b53b4c793f9be6373f53c19942e09ae0ba692a691e8398ae5b3 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P256_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P256_blst new file mode 100644 index 000000000000..772b948e28aa --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P256_blst @@ -0,0 +1,60 @@ +ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590 920b14ec9fc839298e221666969d95c8e37372ef49edc394a2226597775b9de4759ace63160f0cac498ca115394802a111c1063930dff6f0e52ad3ce1188490365ec48a0c7c58dcc6ef136a1f1bfa57e7945d34d13e6b64bf32c560a25707f5c +9155e91fd9155eeed15afd83487ea1a3af04c5998b77c0fe8c43dcc479440a8a9a89efe883d9385cb9edfde10b43bce61fb63669935ad39419cf29ef3a936931733bfc2378e253e73b7ae9a3ec7a6a7932ab10f1e5b94d05160c053988f3bdc9167155d069337d42c9a7056619efc031fa5ec7310d29bd28980b1e3559757578 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98 9771bcb34e319779aae1b27f363d6690b9478b1b81beea93e9b63be32e04c1f3ea86daf0e260be5be7a2ad118cedf78c104a1fe0de022a25eb9d018969edd995bcde11be7384caaea93a34fa8a1eb11563cb565a2495e80fd845f7e28985e06c +b242a7586a1383368a33c88264889adfa3be45422fbef4a2df4e3c5325a9c7757017e0d5cf4bbf4de7f99d189f81f1fd2f0dd645574d1eb0d547eead9375677819297c1abe62526ae29fc54cdd11bfe17714f2fbd2d0d0e8d297ff98535980482dd5c1ebdc5a7274aabf1382c9f2315ca61391e3943856e4c5e616c2f1f7be0d a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870 a4c878b24891665f2014c12e0e41bf7ccb22204640e6ac953cfd50a8cbf64636d15a22aa4e9eb99cc23c98392ca0751e0f2e797b9b376371c2016aa35ce932755fa5de7cb66985f27b6a5278cb7f63037a9d872534a820cfd9ab6496031f7bd2 +b64005da76b24715880af94dba379acc25a047b06066c9bedc8f17b8c74e74f4fc720d9f4ef0e2a659e0756931c080587ebdcd0f85e819aea6dacb327a9d96496da53ea21aef3b2e793a9c0def5196acec99891f46ead78a85bc7ab644765781d3543da9fbf9fec916dca975ef3b4271e50ecc68bf79b2d8935e2b25fc063358 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f 85303ce4de5b803cf3d192f66d7b2d4a27f56591d8ec25510d98b09aa380e72c1bb43060926019282038781f0e8ec9260edc391a44151d49311a765e7c53b8420f8bb2a3f6cb8ead7121ff0b725c792ba54fc9337b664bee474235a02298de11 +fe6e1ea477640655eaa1f6e3352d4bce53eb3d95424df7f238e93d8531da8f36bc35fa6be4bf5a6a382e06e855139eb617a9cc9376b4dafacbd80876343b12628619d7cbe1bff6757e3706111ed53898c0219823adbc044eaf8c6ad449df8f6aab9d444dadb5c3380eec0d91694df5fc4b30280d4b87d27e67ae58a1df828963 daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d 846f2007e15116462920319cf4dbc7ab890517f0f7cf6ad691618a27b9413c49bd5b3a9c5116f8a5b9d62591243bcbee11d09ad81bc7559eddc4603834be6d8787028ff97c3f96a88dbe6a967b09f76c1f1526ed3f87bc3690368f8ec559ed66 +907c0c00dc080a688548957b5b8b1f33ba378de1368023dcad43242411f554eb7d392d3e5c1668fad3944ff9634105343d83b8c85d2a988da5f5dc60ee0518327caed6dd5cf4e9bc6222deb46d00abde745f9b71d6e7aee6c7fdfc9ed053f2c0b611d4c6863088bd012ea9810ee94f8e58905970ebd07353f1f409a371ed03e3 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5 b5ce7b8f8682f13bc50d0f36f3f9b3e098459a39b9dda4fb2d6a719a459364db7acf5306bc729aea282323773601a836039648ad9fad3b298307a7b1584ad958a430036c56eb765acc2617e825699d61053a03e44bdaf686319ddde4f7da7630 +771c4d7bce05610a3e71b272096b57f0d1efcce33a1cb4f714d6ebc0865b2773ec5eedc25fae81dee1d256474dbd9676623614c150916e6ed92ce4430b26037d28fa5252ef6b10c09dc2f7ee5a36a1ea7897b69f389d9f5075e271d92f4eb97b148f3abcb1e5be0b4feb8278613d18abf6da60bfe448238aa04d7f11b71f44c5 f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96 ab80f9d3aec89f9e8937e0eff8a10a8b2d1f9cc76cbd152a9691ecc7374c5a1d5ebf83a5e5a8b092d35287263d81e30f14d5e86cc8ab875fe0a4542df8a49f6319f67e08152349fd1822b23e832fa67839ae19753930921264a84cbd0725fe08 +a3b2825235718fc679b942e8ac38fb4f54415a213c65875b5453d18ca012320ddfbbc58b991eaebadfc2d1a28d4f0cd82652b12e4d5bfda89eda3be12ac52188e38e8cce32a264a300c0e463631f525ae501348594f980392c76b4a12ddc88e5ca086cb8685d03895919a8627725a3e00c4728e2b7c6f6a14fc342b2937fc3dd 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d ae693116a62ee83a9999ed3c2f4ee7c99a4d5c8f418be9011fe54f84f3152a4c74b14a699f6c70894ce2e4b40708bccb18f3ce05dc8b34ba7297210b20724859e9795bc6614b9b8ef96db6507f5bc51e9d8aed61231ea12575b8c7e3c429fcd9 +3e6e2a9bffd729ee5d4807849cd4250021d8184cda723df6ab0e5c939d39237c8e58af9d869fe62d3c97b3298a99e891e5e11aa68b11a087573a40a3e83c7965e7910d72f81cad0f42accc5c25a4fd3cdd8cee63757bbbfbdae98be2bc867d3bcb1333c4632cb0a55dffeb77d8b119c466cd889ec468454fabe6fbee7102deaf 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9 b7cf10633928748f6335b9c1808e29d513dbb032bda1334b464c0db48d7b5314873a6297a7294779867e8f1aab57796f074379f6f0717097a6f0c511b41b41aa0eaef2648309f35e26af6aa24aa4d99b7ec9e2f9762ec8f789efa5085436c652 +52e5c308e70329a17c71eaedb66bbee303c8ec48a6f1a2efb235d308563cd58553d434e12f353227a9ea28608ec9c820ed83c95124e7a886f7e832a2de1032e78dc059208f9ec354170b2b1cab992b52ac01e6c0e4e1b0112686962edc53ab226dafcc9fc7baed2cd9307160e8572edb125935db49289b178f35a8ad23f4f801 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634 a4cf4cc7b3905ef05a202204fe4c80c8341b070894f0574f15d3a044513d1383e0f0375a0cf92cb384b2c09d06de5eb80ebc1b54ab4e89b33ceaddde02db555369a05fe02ceb36fbf8d42cdae2e747274a3152de98445c71409bf9a8b8a92701 +d3e9e82051d4c84d699453c9ff44c7c09f6523bb92232bcf30bf3c380224249de2964e871d56a364d6955c81ef91d06482a6c7c61bc70f66ef22fad128d15416e7174312619134f968f1009f92cbf99248932efb533ff113fb6d949e21d6b80dfbbe69010c8d1ccb0f3808ea309bb0bac1a222168c95b088847e613749b19d04 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27 83448408fd091d091ab3a455a8db9a2e9f26635abf47dde0aaa8c0b0cb1b298d23d4c3d3ec70101097b0aabf03c4bfa31142fb6f4187920219acde98b57fe4c3f5e856df64ea9c67beb999e7a7a93ae636b5075011c2a51ef3582aff225ea143 +968951c2c1918436fe19fa2fe2152656a08f9a6b8aa6201920f1b424da98cee71928897ff087620cc5c551320b1e75a1e98d7d98a5bd5361c9393759614a6087cc0f7fb01fcb173783eb4c4c23961a8231ac4a07d72e683b0c1bd4c51ef1b031df875e7b8d5a6e0628949f5b8f157f43dccaea3b2a4fc11181e6b451e06ceb37 cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d a9f166f287de39e5002bf9bb5b374b73f945d6ea4f27999a4ad5033f991be786a606315e11320abca033a6f6b3e0f3e9086e69c8fc16a34a2a0e69df37afd4087f416f223fe551e35ae05125bee0bc549550978ca32b8f516171a2fb238f10ea +78048628932e1c1cdd1e70932bd7b76f704ba08d7e7d825d3de763bf1a062315f4af16eccefe0b6ebadccaf403d013f50833ce2c54e24eea8345e25f93b69bb048988d102240225ceacf5003e2abdcc90299f4bf2c101585d36ecdd7a155953c674789d070480d1ef47cc7858e97a6d87c41c6922a00ea12539f251826e141b4 b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c a0e224e634d90ffa1c64fd41daf7a77b752450bfc01beb978f60f92fe453370ff4895998811bfe692bcbc83abbe0203f029b95b725020653e239ea03f1917b4b8b9550e3214e36ff14c3751997973f3179e03e3c47730ae3d5db1dd6a27dd4d2 +9b0800c443e693067591737fdbcf0966fdfa50872d41d0c189d87cbc34c2771ee5e1255fd604f09fcf167fda16437c245d299147299c69046895d22482db29aba37ff57f756716cd3d6223077f747c4caffbecc0a7c9dfaaafd9a9817470ded8777e6355838ac54d11b2f0fc3f43668ff949cc31de0c2d15af5ef17884e4d66a 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48 820a59a2f199beef518e257f5663a091148fc3b52c7971908b55e2dec8b068bca2767a9585564df29ea498175b42e8df023d7540209c49b792a7a20b5f036095f9c6c42b183c4d0ee6f47c3bff3cc018af0bf1f84af5aa267c0269b3b5923c55 +fc3b8291c172dae635a6859f525beaf01cf683765d7c86f1a4d768df7cae055f639eccc08d7a0272394d949f82d5e12d69c08e2483e11a1d28a4c61f18193106e12e5de4a9d0b4bf341e2acd6b715dc83ae5ff63328f8346f35521ca378b311299947f63ec593a5e32e6bd11ec4edb0e75302a9f54d21226d23314729e061016 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f ae7832c9413592868e4244186b7c701c233184c4acd8380a51e6f79eaab709632f40b28fcd8044b560f401f6ac87ae500fef406a6f0d1731193f79cb6f666b615e72f86184ca68153150e2fba7d487c2c6024879fd1dd1ed0b9da9d3e989df65 +5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 a1799a8f5bdfaa4ddfe565e88b6a71e44eef1e271c931bfb0dc66a0674af06cceb5b7976c7c0d5eb63afe3ea2af7c53f011fca85e1abf472116423ca3d72098246a9046f82ec3de6722f2ed1736203399d2fc97235d73180438933a826a635ab +c35e2f092553c55772926bdbe87c9796827d17024dbb9233a545366e2e5987dd344deb72df987144b8c6c43bc41b654b94cc856e16b96d7a821c8ec039b503e3d86728c494a967d83011a0e090b5d54cd47f4e366c0912bc808fbb2ea96efac88fb3ebec9342738e225f7c7c2b011ce375b56621a20642b4d36e060db4524af1 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 866dffbf2436639c43d7317962a370e5129928a9048e8c47709dbf04e85b49f22e9f4b1298d6d6c4ec6810c2468722c61206771d1737056e4b833e6a3b2adebcade5f28d40d9ea050ac09724a9c037132433f2bd0ec2fedabfea97c1ac5085e4 +3c054e333a94259c36af09ab5b4ff9beb3492f8d5b4282d16801daccb29f70fe61a0b37ffef5c04cd1b70e85b1f549a1c4dc672985e50f43ea037efa9964f096b5f62f7ffdf8d6bfb2cc859558f5a393cb949dbd48f269343b5263dcdb9c556eca074f2e98e6d94c2c29a677afaf806edf79b15a3fcd46e7067b7669f83188ee e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef a9cac8678fa92fd2a2ffce31489c1dd710ceb6487fae84a4086a9d8bbfc2641640ac34adc8fb31a6e0fd502b4e2ec36717efb770a8625147c42e927b395ece38fae084907bd03d3dff368da9ce37539342fc35818e400463894d39edd84b26ab +0989122410d522af64ceb07da2c865219046b4c3d9d99b01278c07ff63eaf1039cb787ae9e2dd46436cc0415f280c562bebb83a23e639e476a02ec8cff7ea06cd12c86dcc3adefbf1a9e9a9b6646c7599ec631b0da9a60debeb9b3e19324977f3b4f36892c8a38671c8e1cc8e50fcd50f9e51deaf98272f9266fc702e4e57c30 a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 8988f2d63a801c3ac511ae2965fc064293ae01fdf580d56cb62f2f6da31aef15fd19488b510caf12a9e1700a641045d014415b6def1b4f657e597927708e33c25b7528698877b5433ff4dcffa31ea400c0c377c9a1b172fd0780d921070dd662 +dc66e39f9bbfd9865318531ffe9207f934fa615a5b285708a5e9c46b7775150e818d7f24d2a123df3672fff2094e3fd3df6fbe259e3989dd5edfcccbe7d45e26a775a5c4329a084f057c42c13f3248e3fd6f0c76678f890f513c32292dd306eaa84a59abe34b16cb5e38d0e885525d10336ca443e1682aa04a7af832b0eee4e7 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d 91a4b5d45cf13c2b294f6a5a2b771d8fe0fdf699ae628d57cb246818db4df61d12b4d18791e020882b9f1608f00060c80fe38a18d47bc2dec8ce81faea9066ee828f692918b8eb50d95267f0817c4a3a68d6e0a0d0571df7264d71311edb0308 +600974e7d8c5508e2c1aab0783ad0d7c4494ab2b4da265c2fe496421c4df238b0be25f25659157c8a225fb03953607f7df996acfd402f147e37aee2f1693e3bf1c35eab3ae360a2bd91d04622ea47f83d863d2dfecb618e8b8bdc39e17d15d672eee03bb4ce2cc5cf6b217e5faf3f336fdd87d972d3a8b8a593ba85955cc9d71 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d 82959f89505a024a890245c0c9a2b185cfc48647ca84f0a05849d149a6123a82262001dcd16a6a06dd8d65b1ba8d825615994dc3d45e9a17aed3f73088c161a42f411ff14780b54f0f9e270ff9485bcb689b6dba7c4d41fe55d8c58e174aa1a7 +dfa6cb9b39adda6c74cc8b2a8b53a12c499ab9dee01b4123642b4f11af336a91a5c9ce0520eb2395a6190ecbf6169c4cba81941de8e76c9c908eb843b98ce95e0da29c5d4388040264e05e07030a577cc5d176387154eabae2af52a83e85c61c7c61da930c9b19e45d7e34c8516dc3c238fddd6e450a77455d534c48a152010b 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab a60314cd963123d62bc5b271db4a5afea1eec2b94a6490c2f4754fa7072e11e9be658eea54a508c47a3b414ffc0e9d7d129e61be956786d5fea07b5413612c6d6d5990c88ba3103fa002ca0c8d577bbb2b705a254dc9ada90a4a44c307c0d00b +51d2547cbff92431174aa7fc7302139519d98071c755ff1c92e4694b58587ea560f72f32fc6dd4dee7d22bb7387381d0256e2862d0644cdf2c277c5d740fa089830eb52bf79d1e75b8596ecf0ea58a0b9df61e0c9754bfcd62efab6ea1bd216bf181c5593da79f10135a9bc6e164f1854bc8859734341aad237ba29a81a3fc8b 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a ac2d003355f9ad39cb93e8cad4ffc94396b583c9f5f7f92062daa21619f39b7830d66fba93c7e3d71925d2673de5d60a0142e8e0f772c15c7de75548e02af46b681a0f6f2542311f8f57652ee15ca61cefbebe32cddd12782155faa5b34224e8 +558c2ac13026402bad4a0a83ebc9468e50f7ffab06d6f981e5db1d082098065bcff6f21a7a74558b1e8612914b8b5a0aa28ed5b574c36ac4ea5868432a62bb8ef0695d27c1e3ceaf75c7b251c65ddb268696f07c16d2767973d85beb443f211e6445e7fe5d46f0dce70d58a4cd9fe70688c035688ea8c6baec65a5fc7e2c93e8 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 98ad5e47f685a413887d8020a4fc956a8b2dd549dfccd5f038017ae8bd1fafc320a4f47a0c6f543f127f5ab4cb39d18214fe8d7353b8f6048fb605841f294afeb7b849b54d229fb0cd8d7f66c722f6b72efa75534cf26ffaf5bf305d8796e490 +4d55c99ef6bd54621662c3d110c3cb627c03d6311393b264ab97b90a4b15214a5593ba2510a53d63fb34be251facb697c973e11b665cb7920f1684b0031b4dd370cb927ca7168b0bf8ad285e05e9e31e34bc24024739fdc10b78586f29eff94412034e3b606ed850ec2c1900e8e68151fc4aee5adebb066eb6da4eaa5681378e f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 8fc0f1eae20f497af528678f2f6a2c5880c3559e4369bf1e22b9bef22bef5353a7003ba74e97005ea8a05b40fed077890fee079ad916396f182b328f4b526d05c48e2979d34e29e424a6630c76f3ce9e8d8126b2b9574bed301897cb3a6adf7a +f8248ad47d97c18c984f1f5c10950dc1404713c56b6ea397e01e6dd925e903b4fadfe2c9e877169e71ce3c7fe5ce70ee4255d9cdc26f6943bf48687874de64f6cf30a012512e787b88059bbf561162bdcc23a3742c835ac144cc14167b1bd6727e940540a9c99f3cbb41fb1dcb00d76dda04995847c657f4c19d303eb09eb48a b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 b5f33da79c3f849037c6994c0f8b0514ef93d0083209b0248c2cbc0cc199a5820937d67b715f091737fd4008365464aa0c7793e2a3be72f2236900b2eb46107140242c81d5a53f717eff46457824c0a9b65385740f1748bfa4c727c71226360e +3b6ee2425940b3d240d35b97b6dcd61ed3423d8e71a0ada35d47b322d17b35ea0472f35edd1d252f87b8b65ef4b716669fc9ac28b00d34a9d66ad118c9d94e7f46d0b4f6c2b2d339fd6bcd351241a387cc82609057048c12c4ec3d85c661975c45b300cb96930d89370a327c98b67defaa89497aa8ef994c77f1130f752f94a4 d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 959339467eb5c06534f1bcd91b6f86473320301b4120a4a360246e0e1f57164e4eb9c25bdd54e783e5015e02f9d33e3e0858781dfce0cee7c8b0c5101de8bd8d351dfe1813ce569a6ee1eb1e7ef412f3242c082a74e5e87ea1fc40ad9ed30b55 +c5204b81ec0a4df5b7e9fda3dc245f98082ae7f4efe81998dcaa286bd4507ca840a53d21b01e904f55e38f78c3757d5a5a4a44b1d5d4e480be3afb5b394a5d2840af42b1b4083d40afbfe22d702f370d32dbfd392e128ea4724d66a3701da41ae2f03bb4d91bb946c7969404cb544f71eb7a49eb4c4ec55799bda1eb545143a7 b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c a7d0d1c740f88313ba304ffb26fe40b901cbb02c26601e82939bbeb030f6208676247d3756751be6ce18b4512ef997290c978feed00dd5bb7e81545830b2f54278b6ed429dbf6ba10bb52165cb9186ed49fa64fa3c09cfb1f0768e9170d6396d +72e81fe221fb402148d8b7ab03549f1180bcc03d41ca59d7653801f0ba853add1f6d29edd7f9abc621b2d548f8dbf8979bd16608d2d8fc3260b4ebc0dd42482481d548c7075711b5759649c41f439fad69954956c9326841ea6492956829f9e0dc789f73633b40f6ac77bcae6dfc7930cfe89e526d1684365c5b0be2437fdb01 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 953e48a66585ca2e9dbc751044f01318255c2fcbfd888d17b536f15e8c7b4541e325dc479ba6e221961011a49f841d49193b4ed7e045d67a2c04c63cdb95f1d076555499aec2df038be15992db09ed6512b67da749cebdb421203af4464654b0 +21188c3edd5de088dacc1076b9e1bcecd79de1003c2414c3866173054dc82dde85169baa77993adb20c269f60a5226111828578bcc7c29e6e8d2dae81806152c8ba0c6ada1986a1983ebeec1473a73a04795b6319d48662d40881c1723a706f516fe75300f92408aa1dc6ae4288d2046f23c1aa2e54b7fb6448a0da922bd7f34 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 a626c4a15f49ff6fcf7fe5c3496a658eb4e406924b2dc2c819ae6d9ace590dc9f1ffb53ed60b15b15c40143149ed8fcb05b43253c11e23d6da38a86320b6790e4806fb88a48ac857802d5ff7e100be92a97bc61305ecf63e3c9fd1e9d3ebfe3a +e0b8596b375f3306bbc6e77a0b42f7469d7e83635990e74aa6d713594a3a24498feff5006790742d9c2e9b47d714bee932435db747c6e733e3d8de41f2f91311f2e9fd8e025651631ffd84f66732d3473fbd1627e63dc7194048ebec93c95c159b5039ab5e79e42c80b484a943f125de3da1e04e5bf9c16671ad55a1117d3306 b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced b25cac5d250a4b0502f3b6b749f8fe5f3461360334eb1cc994b7acd2b7e2c6144d830d509ee1fd497bd9c2b8b27caee817e8487e3fc1cb4a4bca1119f852919622c11cb27b93bbc89738f070604a4873a11ac9e02e57574c2023de59ee1490c9 +099a0131179fff4c6928e49886d2fdb3a9f239b7dd5fa828a52cbbe3fcfabecfbba3e192159b887b5d13aa1e14e6a07ccbb21f6ad8b7e88fee6bea9b86dea40ffb962f38554056fb7c5bb486418915f7e7e9b9033fe3baaf9a069db98bc02fa8af3d3d1859a11375d6f98aa2ce632606d0800dff7f55b40f971a8586ed6b39e9 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181 87b35b43ad4e0d1fcf2356fde9046ed53e52fc880f6a169bfe0a052b9ac12be78ada9951c5c0e6820f4e3ce7b0887348186abc620ac8dbba0078fa9bee257e9e57dd73f66a9a67c624584b0ba7bdba66e2168990954d1a7ac5770c215c2ed462 +0fbc07ea947c946bea26afa10c51511039b94ddbc4e2e4184ca3559260da24a14522d1497ca5e77a5d1a8e86583aeea1f5d4ff9b04a6aa0de79cd88fdb85e01f171143535f2f7c23b050289d7e05cebccdd131888572534bae0061bdcc3015206b9270b0d5af9f1da2f9de91772d178a632c3261a1e7b3fb255608b3801962f9 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431 a4e43bbadaa9342e3597824f6fe6782f7cd21453d4b5c7c9d03d799c122da65a576da4660ae17c89687c6557a72e28990e8da34d3368a475ce766d053784c9df1740016abec5b548429c3710624869329296fbc5ccfbe130c9a8acecafac9df4 +1e38d750d936d8522e9db1873fb4996bef97f8da3c6674a1223d29263f1234a90b751785316444e9ba698bc8ab6cd010638d182c9adad4e334b2bd7529f0ae8e9a52ad60f59804b2d780ed52bdd33b0bf5400147c28b4304e5e3434505ae7ce30d4b239e7e6f0ecf058badd5b388eddbad64d24d2430dd04b4ddee98f972988f 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd 95233c6a0a450ea22795c298d11009fd469b3987c593f70858b80784118859043344cb252425098deeea28ba2fa2f7520b444188df8e649a72b62ffb0605afe5f6e3742207a2baab086fd0a7980183e94fe65132ca85b3f3f722ad60f4e12b1d +abcf0e0f046b2e0672d1cc6c0a114905627cbbdefdf9752f0c31660aa95f2d0ede72d17919a9e9b1add3213164e0c9b5ae3c76f1a2f79d3eeb444e6741521019d8bd5ca391b28c1063347f07afcfbb705be4b52261c19ebaf1d6f054a74d86fb5d091fa7f229450996b76f0ada5f977b09b58488eebfb5f5e9539a8fd89662ab 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de b3113115440e5c6d6b877615702c1985f3c4a661cd8588ac576827bd8c76f163c247a4bd5162aaff409498ad8b59cf6814864d7104ffe512baf8fc4280e7530ca1ae02521321b6d88eeb552fdd2c5d7f24a28ad9d675426e0073b81639fb81b9 +dc3d4884c741a4a687593c79fb4e35c5c13c781dca16db561d7e393577f7b62ca41a6e259fc1fb8d0c4e1e062517a0fdf95558b7799f20c211796167953e6372c11829beec64869d67bf3ee1f1455dd87acfbdbcc597056e7fb347a17688ad32fda7ccc3572da7677d7255c261738f07763cd45973c728c6e9adbeecadc3d961 ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566 859f8b9ac544a62ca66905904a34c6175ad321294066d1837b8f4b99890ee580e360d202fa6ab4b9902f55f7e4cad4e0023b9bee2f3e02045e7ac8456f82b0442a2d1b080ee1904f3d9410d9391da9d8caffd36ed45ad2bcab951cde0921383e +719bf1911ae5b5e08f1d97b92a5089c0ab9d6f1c175ac7199086aeeaa416a17e6d6f8486c711d386f284f096296689a54d330c8efb0f5fa1c5ba128d3234a3da856c2a94667ef7103616a64c913135f4e1dc50e38daa60610f732ad1bedfcc396f87169392520314a6b6b9af6793dbabad4599525228cc7c9c32c4d8e097ddf6 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee 8983a3f39b3f794105760b282ab14279668ae68230e7a3a48a5469a8924736d5093fb86fadce4cb2b108d467c380831c00ce56d8d6539d6a615df94d22427f827478b164b051f322484112dcf95aa6238c3f3786faa48c090f54a2eb6a9aaa9e +7cf19f4c851e97c5bca11a39f0074c3b7bd3274e7dd75d0447b7b84995dfc9f716bf08c25347f56fcc5e5149cb3f9cfb39d408ace5a5c47e75f7a827fa0bb9921bb5b23a6053dbe1fa2bba341ac874d9b1333fc4dc224854949f5c8d8a5fedd02fb26fdfcd3be351aec0fcbef18972956c6ec0effaf057eb4420b6d28e0c008c 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd 9024d388231f7f6eebb663015f8e1d150a2eb829f2cc7b975fcfee11cbf64bcc2f07589f585e62bddbf2602d4665e8eb0089b27e88249c941be99f8b5952d7eeeec6ff280fc6689aab85a0668446f37876d73546d3f900c79428721e0eb3a7af +b892ffabb809e98a99b0a79895445fc734fa1b6159f9cddb6d21e510708bdab6076633ac30aaef43db566c0d21f4381db46711fe3812c5ce0fb4a40e3d5d8ab24e4e82d3560c6dc7c37794ee17d4a144065ef99c8d1c88bc22ad8c4c27d85ad518fa5747ae35276fc104829d3f5c72fc2a9ea55a1c3a87007cd133263f79e405 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666 b90284143cc4cb17da6e6424158b483ff8bb2dae5651b36f925f4c37858c4a43336c6d349575b15181f592385073e823177a1b0abf28d3966b6504052c22784ea29c1367027f6c58ec820f5f215e407ed3526661aaec0fab9749ee808c95e80e +8144e37014c95e13231cbd6fa64772771f93b44e37f7b02f592099cc146343edd4f4ec9fa1bc68d7f2e9ee78fc370443aa2803ff4ca52ee49a2f4daf2c8181ea7b8475b3a0f608fc3279d09e2d057fbe3f2ffbe5133796124781299c6da60cfe7ecea3abc30706ded2cdf18f9d788e59f2c31662df3abe01a9b12304fb8d5c8c bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67 b2d160404233b8c7e65acda81376d2ea41c23fcb5d3a8517e8cba9e6b73a6ee1903461cf1c36119845151076020cfddc0ff0f8a39c899a3148b1ddb3fc25142b872938e55da3115c7239fe95331bf4c5b8faf40d28f85f1594cbd71c8eb2cb7a +a3683d120807f0a030feed679785326698c3702f1983eaba1b70ddfa7f0b3188060b845e2b67ed57ee68087746710450f7427cb34655d719c0acbc09ac696adb4b22aba1b9322b7111076e67053a55f62b501a4bca0ad9d50a868f51aeeb4ef27823236f5267e8da83e143047422ce140d66e05e44dc84fb3a4506b2a5d7caa8 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9 b27c98ca805a4bb210b86ff94f5d78e7263f8db94925f394ca07bde258fdd4582082eaa2c1ce0b521d407663e4f1458e128baa2f9d686e9bbdc36c37f671f5224a60d70b933368eac9addb3e7506385911c11a435b87f523a80b9f68c44390fd +b1df8051b213fc5f636537e37e212eb20b2423e6467a9c7081336a870e6373fc835899d59e546c0ac668cc81ce4921e88f42e6da2a109a03b4f4e819a17c955b8d099ec6b282fb495258dca13ec779c459da909475519a3477223c06b99afbd77f9922e7cbef844b93f3ce5f50db816b2e0d8b1575d2e17a6b8db9111d6da578 f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce ae246b8ca5f964ce86d9c911e761f226af82586b96f63d340109c8cee2a5bde026a477186eedfea89dab9ca3fe93be98048c729322de693e930869d273e4ed4f063cc6cdcfd8368752bf53a64e82704418d4c73bb84687ec034648de569a7b88 +0b918ede985b5c491797d0a81446b2933be312f419b212e3aae9ba5914c00af431747a9d287a7c7761e9bcbc8a12aaf9d4a76d13dad59fc742f8f218ef66eb67035220a07acc1a357c5b562ecb6b895cf725c4230412fefac72097f2c2b829ed58742d7c327cad0f1058df1bddd4ae9c6d2aba25480424308684cecd6517cdd8 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f 84cf42ade2a98ac8623bcc8fdda91d5f4dccec68b30b631af611d90e4942483e5309b58f137b2f0522734913e05623dc0994fed2c82ebf0f5838c959a0dc51df3c4377c2b3ca765d66c8ae9f54739dd43ea5d064a6e38c1ff4416594d10c7389 +0fab26fde1a4467ca930dbe513ccc3452b70313cccde2994eead2fde85c8da1db84d7d06a024c9e88629d5344224a4eae01b21a2665d5f7f36d5524bf5367d7f8b6a71ea05d413d4afde33777f0a3be49c9e6aa29ea447746a9e77ce27232a550b31dd4e7c9bc8913485f2dc83a56298051c92461fd46b14cc895c300a4fb874 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b b22a806e416bd5311bbfc506321f5e26ca6e23a84ad520b603457619daef19c09eb8ffc6db4701d3e53e1f4f3625a6f9160f0721c0c9a72c9f99c751fd3fb19d9162dfd961248476885518724a40eb47d6241996972987226bc315a96802b03b +7843f157ef8566722a7d69da67de7599ee65cb3975508f70c612b3289190e364141781e0b832f2d9627122742f4b5871ceeafcd09ba5ec90cae6bcc01ae32b50f13f63918dfb5177df9797c6273b92d103c3f7a3fc2050d2b196cc872c57b77f9bdb1782d4195445fcc6236dd8bd14c8bcbc8223a6739f6a17c9a861e8c821a6 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388 8227d0dc2e373071e759bf17b8997eafd0490ee6bc3e6db4db2872c459dd09bbcbd718f080b99a30eb21a65dc1b55a3e12554a2f7ef8a0b1941ab1f98ceebb3230a096a2de501302a467f8885870098f2e57357e3b11ca5b9fd39494d6906803 +6c8572b6a3a4a9e8e03dbeed99334d41661b8a8417074f335ab1845f6cc852adb8c01d9820fcf8e10699cc827a8fbdca2cbd46cc66e4e6b7ba41ec3efa733587e4a30ec552cd8ddab8163e148e50f4d090782897f3ddac84a41e1fcfe8c56b6152c0097b0d634b41011471ffd004f43eb4aafc038197ec6bae2b4470e869bded 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499 91c2cfe8891b41edd1b4b45a1d26f2e1956ba7dc556d554b13a5ce3dae9900b15bbf0b0295128588a909a19425e60b0a049cec243dd49a724cec522b14c963b161197ac3f587b39d2502ae71ff24285c494f122a4211e29735c0dd8994a59abe +7e3c8fe162d48cc8c5b11b5e5ebc05ebc45c439bdbc0b0902145921b8383037cb0812222031598cd1a56fa71694fbd304cc62938233465ec39c6e49f57dfe823983b6923c4e865633949183e6b90e9e06d8275f3907d97967d47b6239fe2847b7d49cf16ba69d2862083cf1bccf7afe34fdc90e21998964107b64abe6b89d126 f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6 8c46a2b342bcb6c8afcd27e1d26cc20cdb8f73d7216625e75d78f92143221cf1b8d01a8229b20d241750f1e2e8ab59e917bc302f9c957ad97896d45dba1f63c6d13f0bc0673a36b8e6c546c0059a089c3b60a00045aa36a03c3d1b7c3140c271 +d5aa8ac9218ca661cd177756af6fbb5a40a3fecfd4eea6d5872fbb9a2884784aa9b5f0c023a6e0da5cf6364754ee6465b4ee2d0ddc745b02994c98427a213c849537da5a4477b3abfe02648be67f26e80b56a33150490d062aaac137aa47f11cfeddba855bab9e4e028532a563326d927f9e6e3292b1fb248ee90b6f429798db 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead b5b2e970de363b4a6a0de61697b68f9b43d0f5968adf12070f66b2c0462255dad3f5003b2960a88d72efd6649cad09c20267e50ef9207648dd3df8b6d047d16d1b36ea5210aba20da5a0fc55b588b83d8919fc1576496d1b9c82ca121ab3f762 +790b06054afc9c3fc4dfe72df19dd5d68d108cfcfca6212804f6d534fd2fbe489bd8f64bf205ce04bcb50124a12ce5238fc3fe7dd76e6fa640206af52549f133d593a1bfd423ab737f3326fa79433cde293236f90d4238f0dd38ed69492ddbd9c3eae583b6325a95dec3166fe52b21658293d8c137830ef45297d67813b7a508 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd ac315e2e7cd3081d035d76b6eb200b316c55d4bee7a9afa7c5bce24941244bca50f82df2b2ee113505e982594cd829d319ff00b49b911f0083d243e502afc0a9e95eced7715bb12536783b776ca1ea58d81be997ae6d50ac1e7db977c4c35205 +6d549aa87afdb8bfa60d22a68e2783b27e8db46041e4df04be0c261c4734b608a96f198d1cdb8d082ae48579ec9defcf21fbc72803764a58c31e5323d5452b9fb57c8991d31749140da7ef067b18bf0d7dfbae6eefd0d8064f334bf7e9ec1e028daed4e86e17635ec2e409a3ed1238048a45882c5c57501b314e636b9bc81cbe 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117 b7f6874ec0b79657aacbf9775a6f80719db3b546e6cf6c85e16acf026aeae8ae9b02204e030ab4cdf486b41e34ec04f902a64875f89698154ee6163a3c527ee47bca7c705fa96a60fa1b422c20b5a6650750416cb7ea4a9d1f344ab8e4858e9b +1906e48b7f889ee3ff7ab0807a7aa88f53f4018808870bfed6372a77330c737647961324c2b4d46f6ee8b01190474951a701b048ae86579ff8e3fc889fecf926b17f98958ac7534e6e781ca2db2baa380dec766cfb2a3eca2a9d5818967d64dfab84f768d24ec122eebacaab0a4dc3a75f37331bb1c43dd8966cc09ec4945bbd 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61 ac15967f6fdbb454aadff8389708ebe4f558e300f61795f4b2830b1066702d0047c176bc9ea44c45d687d388c79eac070d28956d3d792dc76aecc31ae33ee3095e20cc062ce1d4a1687d2905d2f874a1eea6cc3d5ff6d928e68edebac9bb5614 +7b59fef13daf01afec35dea3276541be681c4916767f34d4e874464d20979863ee77ad0fd1635bcdf93e9f62ed69ae52ec90aab5bbf87f8951213747ccec9f38c775c1df1e9d7f735c2ce39b42edb3b0c5086247556cfea539995c5d9689765288ec600848ecf085c01ca738bbef11f5d12d4457db988b4add90be00781024ad 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2 957222f4c883eebb998aad06f3ceffbf4350e2058ce7e07406e45afbb100799d4f0746aa19145ee1a625abe8e1f4645312e4d445b7bd120f538578e47f5d129b32b6c2b0178042275384ce242a5a6a9fdbe0bdcfd2b6ab7c8d962ef2b3e81955 +041a6767a935dc3d8985eb4e608b0cbfebe7f93789d4200bcfe595277ac2b0f402889b580b72def5da778a680fd380c955421f626d52dd9a83ea180187b850e1b72a4ec6dd63235e598fd15a9b19f8ce9aec1d23f0bd6ea4d92360d50f951152bc9a01354732ba0cf90aaed33c307c1de8fa3d14f9489151b8377b57c7215f0b 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7 8f817001d9adf7ff6f08f8a033eb840111ba932dad1e098c86e4e91dde3751e18b6c98e2052640bd62ad06fffb15b6f010d557178c76caee52e986fc680eb64ee99d0f80d60fc5f2f186db45eec78fa8d5c71c77619ab8c2e0518bc541858d3c +7905a9036e022c78b2c9efd40b77b0a194fbc1d45462779b0b76ad30dc52c564e48a493d8249a061e62f26f453ba566538a4d43c64fb9fdbd1f36409316433c6f074e1b47b544a847de25fc67d81ac801ed9f7371a43da39001c90766f943e629d74d0436ba1240c3d7fab990d586a6d6ef1771786722df56448815f2feda48f 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870 83ed556543db66407c8ef1aea61b4e07a58da34540ad45c5c2e5d99a8cb3f390905eacf5012d9070c168cc52bbd4a56e0c0cd2aae15f0318136192b01dd4d3cc11f4a14bf623d531fb56244d61b0726e32107b5b3a837583e9727fc671c89b86 +cf25e4642d4f39d15afb7aec79469d82fc9aedb8f89964e79b749a852d931d37436502804e39555f5a3c75dd958fd5291ada647c1a5e38fe7b1048f16f2b711fdd5d39acc0812ca65bd50d7f8119f2fd195ab16633503a78ee9102c1f9c4c22568e0b54bd4fa3f5ff7b49160bf23e7e2231b1ebebbdaf0e4a7d4484158a87e07 e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf ab7b579938541039303a0c6b6fb763e813422f1d53177f0adb5fa3c47b47df1796f24373be0f0ca32a2ed4ce7256975a0554c086035559faa219b7eaf1e05347bcb202f6680dc56eac4c7133b5f09af0858ee44bac5a741aaa836e6886fb931b +7562c445b35883cc937be6349b4cefc3556a80255d70f09e28c3f393daac19442a7eecedcdfbe8f7628e30cd8939537ec56d5c9645d43340eb4e78fc5dd4322de8a07966b262770d7ff13a071ff3dce560718e60ed3086b7e0003a6abafe91af90af86733ce8689440bf73d2aa0acfe9776036e877599acbabfcb03bb3b50faa 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c b9118446550515878935e90333dbcfa10024f5acf8cb34f8325ff7533a413c6b5aaa7d3f8912856661fc63def5d83244028530a25a07c4a87689bdeff28de90ff5b840ec78b3e1d42b004d477751c638d3fee2b51dfe710850f95156249c3e72 +051c2db8e71e44653ea1cb0afc9e0abdf12658e9e761bfb767c20c7ab4adfcb18ed9b5c372a3ac11d8a43c55f7f99b33355437891686d42362abd71db8b6d84dd694d6982f0612178a937aa934b9ac3c0794c39027bdd767841c4370666c80dbc0f8132ca27474f553d266deefd7c9dbad6d734f9006bb557567701bb7e6a7c9 f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9 ad87eff10b3d15e5ab9f6595edea9a2e4b9a139c5446f396b50fe838773fb3d65cbf05d0e860a827cb62f1900a4058b4099cbf290d13df6e424ecae1532e755633f3fafccb3ed651f21f4306b6fd9f4a6cf5c4053ba28106366b58779c6be945 +4dcb7b62ba31b866fce7c1feedf0be1f67bf611dbc2e2e86f004422f67b3bc1839c6958eb1dc3ead137c3d7f88aa97244577a775c8021b1642a8647bba82871e3c15d0749ed343ea6cad38f123835d8ef66b0719273105e924e8685b65fd5dc430efbc35b05a6097f17ebc5943cdcd9abcba752b7f8f37027409bd6e11cd158f f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5 b755aa1aca14c769f487e80f732b27dc483177dd3260cdc5e180883ad099bc070fd69d729d28204aaf4274eb0fc5df1917fbd9ecb261f1a4e171d08643f6078d4dc81b71f531002e44e9f79295d5d35e9d5cdd5d37717bb0a836f77032e00f4a +efe55737771070d5ac79236b04e3fbaf4f2e9bed187d1930680fcf1aba769674bf426310f21245006f528779347d28b8aeacd2b1d5e3456dcbf188b2be8c07f19219e4067c1e7c9714784285d8bac79a76b56f2e2676ea93994f11eb573af1d03fc8ed1118eafc7f07a82f3263c33eb85e497e18f435d4076a774f42d276c323 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628 8fa7c5c6a698fc2cea8c0f2fe2e525ceb084928c2a49e68e69ed604e8880c941da8843f06ed714c1721136a6408f7f83109eced848cc67152167089af7ae5ebe5d6cd8be9cd90ed693ce782687ad0f53dd83387b1df087003c62daff12e0249d +ea95859cc13cccb37198d919803be89c2ee10befdcaf5d5afa09dcc529d333ae1e4ffd3bd8ba8642203badd7a80a3f77eeee9402eed365d53f05c1a995c536f8236ba6b6ff8897393506660cc8ea82b2163aa6a1855251c87d935e23857fe35b889427b449de7274d7754bdeace960b4303c5dd5f745a5cfd580293d6548c832 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49 8196c8918e31120863c0fef853edfaa107d12e216b906cf95ddc1db576393362cdfe791b33fb0767b489490dd889e372126dacf3ab6548237eafd9ef796fd8751f98cb33fc365e1754c1b829a9f25c8a12dd529e2e49a4a51ef00ac8b8795143 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P384 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P384 new file mode 100644 index 000000000000..adea7c0cc42f --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P384 @@ -0,0 +1,60 @@ +39f0b25d4c15b09a0692b22fbacbb5f8aee184cb75887e2ebe0cd3be5d3815d29f9b587e10b3168c939054a89df11068e5c3fac21af742bf4c3e9512f5569674e7ad8b39042bcd73e4b7ce3e64fbea1c434ed01ad4ad8b5b569f6a0b9a1144f94097925672e59ba97bc4d33be2fa21b46c3dadbfb3a1f89afa199d4b44189938 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727 a6625ae0268cb4ddf06cb5e57214e3e72c26f6408286518281a2720138025f27f4b59b3bd061579ceebac15277834909155075062d9f951eaf98851e5b972944319bfac6a173635ed8c9f44aa19663ceab96316e55b247afc4aecc44ea4559fb +5a3c80e608ed3ac75a6e45f6e94d374271a6d42b67a481860d5d309cc8b37c79cb61f1716dc8aa84cb309ef9d68eb7fc6cf4b42333f316a5c30e74198c8b340926e340c5de47674a707293c4aa2a1a2274a602f01c26b156e895499c60b38ef53fc2032e7485c168d73700d6fa14232596a0e4997854a0b05d02e351b9d3de96 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246 81b603d2bfc4116fe49a0b0ec260a61b50237818f98be906bda0676cece3acb217fff451b1c80214e042d9030faff4d9117ca83571f3d754abac2406b86c6165533eaf85fab3f1eddf6001a7abdfc322d4a2652e53ef26aa51cb80ea08ea656c +e7d974c5dbd3bfb8a2fb92fdd782f997d04be79e9713944ce13c5eb6f75dfdec811b7ee4b3859114b07f263846ae13f795eec8f3cb5b7565baff68e0fdd5e09ba8b176d5a71cb03fbc5546e6937fba560acb4db24bd42de1851432b96e8ca4078313cb849bce29c9d805258601d67cd0259e255f3048682e8fdbdda3398c3e31 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83 9243047134203cedd11ef7db0e1db09954e30a9b700df2b652510e5d6596756a951ad7e7badc36818fff6489526753ce192aaadaaf3bf547ccb24df6e56b5c5306859d9a61ad09d1ed8e14ae109f7b2c6bf52e972a7c29f8ba5cea0cab476315 +a670fda4d1d56c70de1d8680328043b2b7029633caf0ee59ffe1421c914bb937133d5a0f9214846b2e0b350455a74c4ab434c56de65a17139bb8212bf1c76071a37536fa29348f871dbb26baa92eb93d97e923a6d2ffd9be25cbc33075e494e6db657bd8dc053fe4e17148d8cf6e2058164f2b5766750eb01bbe7b361cdb848c dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659 b42d6a9406d6ec5e4e90d20945e92e5389a95fc171cdf18b335d62dbf050c198fb49b96cd454145137f3dfd303ad2bb9009e525ec35a28f8bcc7341b2f618c49a04afa26e65c2e891b7333d332ae2adc79f2bac914bc202efa0b6161071956f5 +7843f918fe2588bcfe756e1f05b491d913523255aa006818be20b676c957f4edb8df863c6f5f8c15b3b80c7a2aa277b70d53f210bdfb856337980c406ea140e439dd321471407f374f69877b2d82367eed51e3c82c13948616dcb301d0c31f8f0352f2846abd9e72071f446a2f1bd3339a09ae41b84e150fd18f4ba5d3c6bfa0 df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718 8d01db670239462b1dab3dd84cec0a8118857a90696189e7e597a5114f8a3037f0e850e91ee4afd3224577c35ebc76300bf1b9d0c2a41f39156157437d60312e41006ba2ce0af82ee98cde3998ad9ecc83e28e4de25eb7ac764f03f0695a7a1e +caa83d5ab07febbd2e0fe2d63738b9b7b8752594bea7aaf50345b3d2f316653a8c9222f2b7877b64679e9573e81461a426029e45b8873a575094a1d572e0d32a9f0a9c6bcb9a2868543b7d8bbe4a69a09e7321f05f8366cced1b72df526f895b60aed2c39c249653c7839538770d4e5f47d3926ec0d168ab6a1af15bf1dca1f7 ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f 960e798ce7fff42a4642d70678b62472550a96298d8257ca2ae4d140849b4cca5f4c275b267b71c42d5dd473056a42a10629ffb72ac20e6cb2871135719a1c5e8140a2dadb272af9ee8acff9d05453cbfafdb5998e80fcc8c2a074e27386d4c9 +594603458d6534974aeeafba919c4d0f4cb6843a3af41204bbb88aeb2fca2772d305163dba863da050aabedbaf89db521955d1715de95bbcef979ecdc0c976181ece00355385f8a8f8cce127c9eac15ce3e958a3ed686184674ec9a50eb63271606ee7fdcb1323da3c3db8e89cad1fb42139a32d08abcfbf0d4ccfca18c89a86 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829 92e5696ea8ab1d1643a0adbcd6f46d58ebf71b4591784448960f55241c1b8835a8f37c06d59b8778220bad0b0068906101d469b1f15c5795c05c8200118d95ebebd64b0a46b942764d80b679c5cab2bd59ce86a8c73ae90544a7217af8b460b3 +733252d2bd35547838be22656cc7aa67eff0af0b13b428f77267a513c6824c3dbae533068b6817e82665f009560affcfe4b2ddb5b667a644fc1a42d24f24e0947e0dc50fb62c919bc1fe4e7ded5e28f2e6d80fcf66a081fb2763526f8def5a81a4ddd38be0b59ee839da1643eeeaee7b1927cec12cf3da67c02bc5465151e346 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1 8f6285a08c82282f3de05dc9ccc34acf7654b98591454eb2ae7e3217dd2d25aac756a3608a955b76ef809e28b64305040676cf242edb19b84959d3526dfe9e46a8a2b225896e1e85430982c8a8dacf5145dee1fadd50ea52332324277fe11e5c +5a182bd174feb038dfae3346267156bf663167f713dea1ce936b0edb815cd9b8c8e4d411c786ba2494a81442617255db7158b142e720d86c9b56680fb9efd4298cdd69079a28153494c42a24251c7ad42ecf7e97eabc1b3997529b2a297cbad2474269b87a0b1e385f2d7f8b6eb8d1cd75eaf7e91d1acbecd45d7b2bfbbe3216 e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d 910583487f9a0ef4e53c5c366b7981082e974844066a79f421effedd24ba06b96a976e1c732b664b3d198318180dee6406c5f9e4d938686e7f3060a0915f859323acc468703d7a817a951d9584f86516154e5e664238c07ecb4754fc1f1e3d00 +aaa99fb1c71340d785a18f6f668e898c25cf7a0ac31d13c5b388b7233408493a5a109af6d07065376b96f4903df7aba2b2af671a18772bb0472490d1240cde28967680727dd4acd47e0308920a75da857a6eeedee5b6586d45dff3d8a680599665aa895c89dd7770b824b7dee477ac5e7602d409d3cc553090c970b50811dbab 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead 8bf9b5e79d79a9f519ceb1d0b1adb3a34f866327beed98a40f58e8a1e2652d836ba3e6446915b3c4974cfa67ec58f33b0277170338682f3a4d9bce3ea663df38de3a428d010304fa71f7f5c7a751a3203d52292b2d7c5057be301f9f3322297d +1fadfa8254d3a0b82d137cfdd82043d5dc1fef195d5297b09cc5cfb061f59c933451c0dc2a11b4037f34f88dacb803251f8880c4b72585c3c196e6fb23484ca43a191f8e41b9b9a37e2e6fcaab6738c3c62d1c98e1c620bb788b7b51a04f998a510efdba0d3418622fe8ce203b3fcd553b9b4206365a39031797ad11e49745ec 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0 8f42b2cfd4511ee52339553fbe59683d95e571de2f3d0796268e8ad9ad294f7ce8e626cc0a982444e1977424f920fb73171166ddb229fcdde571368551dca2ba8261096d5cc2665eb613b7eacc7cae6a40895e8d048f40e24f67111e139499bb +9ecb6f5ed3ba666a8536a81ef65012c2cb8b433508798d84708abb06dfb75503886f78384fb8c7a4d2d49ef539d9b8a0b60938c7f07471dda91f258b0d99691b38a8403a2bb3f956bdfd09baba16d9b6877097a9b6213481b47a06e139d23ec7abad5668d21f912fdb70d31bb9adf9b3ce80e308252fa81a51674f88d02db72b f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1 a1e9f22a35f5689dc33a2d9e19ae143b0b2f4c62d7b07d0a7418dd9094481b7e5dff0fa03afcb64358fb3501a6ecb21c0b83b9e2debe6b2355e1c8ed7b63e0261264789a4e8d057bd87c039fdc4c0470a15ebeea3d06a5b6d509b2c005b94ce7 +e55bfca78d98e68d1b63688db12485578f36c489766f4d0bfaa0088433ff12133aaca455805095f2e655940860958b3ead111d9070778ee3bbf3e47e43d9eba8b8d9b1fdf72f793fcde2bcaa334f3e35fa2cca531ea7cf27fe9ccba741e38ac26129b2d612bf54a34e0ae6c166c0fef07fcd2b9ac253d7e041a500f7be7b8369 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb ac49061c6de3e6f02698541dec2776dd3d4e86f2faba4ed08654532a483380325b272cda94e9a7ffc304b2b39247fb8b02a4277c85b788935e3999cf134c50e4bbe4f94fb8ea75d918c2d6c260db355436b8aae285948c654a26462cbcb80c77 +02c6b3c83bd34b288d96409162aa4ff114e9d134bf948046eb5ebcc0c7fe9dfceadda83ed69da2fac00c8840f6c702a3fc5e6959d70f7e8af923e99e4937232ae3b841ffefd2e62fab3671a7c94a0281b8ea5bc176add57c5c9b6893fe7f5d48ce7256b96510810c4e046168a3c5be9843b84d5268a50349b3444341aa5490dd 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6 b93c724eb645018720043cadcf813b4c42902ac5930628dc1838882848da9cab6ab9de9d0df671db5e36e40d72c47c73177d637d45115994ec48918b413ff4ce37b3337bc2001fdc65041a36ad97b20cc0f60d8e214ef02907ff2a12a181f7a5 +94f8bfbb9dd6c9b6193e84c2023a27dea00fd48356909faec2161972439686c146184f80686bc09e1a698af7df9dea3d24d9e9fd6d7348a146339c839282cf8984345dc6a51096d74ad238c35233012ad729f262481ec7cd6488f13a6ebac3f3d23438c7ccb5a66e2bf820e92b71c730bb12fd64ea1770d1f892e5b1e14a9e5c cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd aba7cfddd38db4921eddbc9d0dc6341ae33319855995d252e3461e8e1050e4f1fb8d44b9d609bd8860238dcc78741ea60d5199b9ceef7e73f6d0d02b450cec17e69a6aa28a5577e79e26cdef92665c5204e4c0095a284a3851034e91822bd6a1 +663b12ebf44b7ed3872b385477381f4b11adeb0aec9e0e2478776313d536376dc8fd5f3c715bb6ddf32c01ee1d6f8b731785732c0d8441df636d8145577e7b3138e43c32a61bc1242e0e73d62d624cdc924856076bdbbf1ec04ad4420732ef0c53d42479a08235fcfc4db4d869c4eb2828c73928cdc3e3758362d1b770809997 c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b 92b234688088e3531158b8a16d0fcef988407a0b616e386938210966bff87d318ce16998a370c1c36e24daebe3bca23c13a510623fb5308aa07ef81ecf70b0d9d4783c131da720885a04cd1916a2238c41224b78758e47622498bdee32709a43 +784d7f4686c01bea32cb6cab8c089fb25c341080d9832e04feac6ea63a341079cbd562a75365c63cf7e63e7e1dddc9e99db75ccee59c5295340c2bba36f457690a8f05c62ab001e3d6b333780117d1456a9c8b27d6c2504db9c1428dad8ba797a4419914fcc636f0f14ede3fba49b023b12a77a2176b0b8ff55a895dcaf8dbce 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9 a4d5606c1439fdedcbd0660c99683bc659c137b8bcc01dd401b989429d7270a712a336791bfd29cbee8ad892eed9eb9202b3384682a2d487d312062e6fa32385edb8b9c5811616ef1569e6e5ab8655e3c18effe6dfefc4bd50197bf3aa059a19 +45e47fccc5bd6801f237cdbeac8f66ebc75f8b71a6da556d2e002352bd85bf269b6bc7c928d7bb1b0422601e4dd80b29d5906f8fcac212fe0eaaf52eda552303259cbcbe532e60abd3d38d786a45e39a2875bce675800a3eaeb9e42983d9fd9031180abd9adccc9ba30c6c198b4202c4dd70f241e969a3c412724b9b595bc28a d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f 990aff68fe36d0b8087d3e3b8d1e5f89a8799bde3b393473568bbdd9ff6170e6d83c0e4122f61b4a7fc77c3a924cb0fc15b74495f2e37f5b1298adb13d0ef08fe9d17e26d690999998a78cf2fef225eddc96fad5b66c860fe7a18649868bf524 +c33ff63b4e6891e00b2349b3f2907c417ca355560544a91e24a7a0ee260d6850aeded29fc0176b6039ca6187e8333391047cceaf14b1077df8f147dad84d36b2dac5666dc2f69dc9b58b88cc73956efdb3b47f91831d5875051c76b0c4e9fc087012a1f03eeee85d6745b46aa50bd9cb0110c2c94508765cec162ee1aa841d73 d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3 88a68ab082c7963c3852ced60c3daddfa6b45849349a29ab60d37345ab387d9c86c5349c30f0ead5b087c8d2066dc8c60362326054e1a73e9934fbd2c45125c833dd237b5075d84d22b2e25c7e7fc7cff358a7406c042907faa0e00ec1737889 +f562f2b9d84b0e96a52532c3b43c39c8018c738bd8dc3797a7de7353971b2729d522d6961b1f2e4df3f6a4bd3653e6d72b74fc0dba92ab939c4b542e994e5db6dd8ed4f56f651e699052e791237ae1f552f990ad156226ae8f7bf17fcbfa564f749604f97e9df0879d50985747d981422a23040fe52f5ec74caf1d4aaad8a710 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93 807e3e5e2d2624c05af8ac5097cceb727c4cf375ffe404d870c63e3c99e996228e687c06dae55cc7d858d352f0f1cc520f3898b605b0ae0618d32d1e38275782bc3fe9e4df717666cd479e8fc9069e004ec331be3de348c595a67b7c24a85860 +ace953ae851f571d71779aa120915f27450b236da23e9106f8d0756abdd25861937941228d225d5fb1aa1b1ebf759b1e326aeb3b6cd0cd87edd2ab9f6a7ad67b63d2c501d6a550edb2e7c9d216cc8af78dd33546af64d00abed4d0d2cfc5c9a7b5a055dbe8f7547902d185cf46937314832bc5c602419a82ab83dbd9d3bd5aff e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1 ae1c17f020043a11e8bc2fa410bf87db153f5487778a2a6f33eea7efab25bf2de4faa3300a10d35c1a4ea0ffc74f20de014baa72b2a41f531cdb4bd0f7fb36444f8e444e10d975ca0233442727a0b1b608d92bbb7ecd0c99d6039c82b417f71d +9635ab832240be95301bedb94c5aec169eedc198cbbdfedcf41e9b586143d829b4597a6b2a81902828332825fd84a785f187a3894e21bd99d22c4f94dcf34453fc052f15ec64d1447c932cb38fcdd30b7be851963409c11881438cbaad7e96f9efbde317f2235d66af804477a5dfe9f0c51448383830050ecf228889f83631e1 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960 aee59a93df88c64af0108ea9c2d2a94b5200734f3c9fa37da9633bf24b93fff76d801d10a0390e2f2a17b3bb64b017100c53488ed675df641ee6bfa91ee91d088d603d69716e2bfa999dacdddd80ad0a031a684e927e95b65464b204257a26f4 +d98b9a7d4fe9d0fd95de5056af164a8b7882cd34ab5bde83a2abb32dc361eb56a479a3a6119db3b91dcad26a42d2206749567f0d97c34a981a91fc734921821a429f6a53401743a5c406ba9d560f956203abc9d1f32f1a13e7d7b290f75c95fdbf857ea597021461c06a3aacfa554ede3d69e4ff03bbbee5b7463ec77de2b3b2 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57 a779b77fa711b1b25e663e70a505a0f40889345bd6117acb050f7365c0accc477588265086f47be1e1b7bea60068d90016fb8a3f382e4089863d94b991e69143701b4f52356df96fdfcc17ff2e5508f13f076f5e4439213e1fc3f808a02c4a81 +1b4c754ac1c28dc415a71eac816bde68de7e8db66409af835838c5bb2c605111108a3bf13606ed5d8ade5ed72e50503e0de664416393d178ea4eec834d8d6f15039847b410080fd5529b426e5aadd8451c20ebd92d787921f33e147bcbeb327b104d4aab1157fc1df33e4d768404b5ccb7110055c2508c600f429fd0c21b5784 a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1 8c880e76da3ab29b68bd310f6d8f2a9f3d7488d5f69d4fabc9710c5af709f77b235bc87a0e97809e3d9640067c37ec8202c74f094f71033bf5a075318cb68560a6c5d9536da8312c1b06d89e2e5a4e48d68131b06003a619805f99ea808958f9 +3cd8c053741dd9f974c6c5dbf8a1e5728e9b5eafb1cbcfc3452f5fbbda32a8c7564dee157e8d902c52514361da6d972934a56b3276e2a9379e328e24282e0db697c5bc29090fc489ec46b7b188325dd4e96494c250de0f4a89fe2ccf919eaefcfb50c288113e6df92714feb7f46e0822478c796d0f4ff3447a32997e892693ce 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3 a540880adb7b6f1b85e89da201f26fc4785bb642b4ee6bc6fa7345efef17e04fbba2683a17d25004da2c21e2e151c9840eca32167b170811c78be7c705f2bd5d125e96d63ccc21658491717666e86e9e4abf94c97d05fde8755cea2959069919 +ed955dda6d9650124804d3deb6aeef900e520faf98b1ef6f14efcada7ca2433f09329b70897305e59c89024d76e466b28fe02cb2a9b12e2478c66470259d7c282137a19e5a04ffadea55245c0f34a681593fedc42931d8b3321b3d82e9cc102cd00540ad311ec7bd8c9d06db21bea4ca3dc74d98931ae0d40494aefc2345132c 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907 b64e0c7e93c147fe0e64f4e35634aa2806a44b755ded8e3c8f472c6008108b9bc38de639868839c42735b339ce08b45415f0486c42070e88c517cd27e408dd91aab015b7809f8cdd2c820619852a7154730cd1fe0eba4f1c017e4fdf4efc3586 +ce395b001da2a58e49691605d44af4206306f62f561bf2394060d2a5591a350277166bed043819035f1e60b5b3fb5ae113ddd0473f8ef6b2b050c472c2a264e1d8b3ca82a4f158c40f2d78d9ce5e5ea6de243f2e1f13f47f6c6f403b270912c81c636be35b396ca58468b3fb60aa83911d61441a0528d973bc31f965d4059080 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245 aa9701b1b15c8a94fbb85d265ae242612d1823c6110fd021c4e2437bea7b1630d24252571c4c66e5dd9f3f42817cc5d10812e5cf963d048e8618235a232626fe7d7d1de14d7fed77f5a026610fe174dd19e596d1fe402912b2a00938eede8871 +ffefe316455ae4ffdb890bb804bf7d31424ea060ecacff419d0f7134ff76ad434063c0ec0f8bb7059584d3a03f3625bb9e9f66ace1a47ac4b8f3e76fc7c420c55edb1427d1fa15b387ad73d02b0595c4e74321be8822752230a0dcfb85d60bfa186da7623a8ec3eb1633f0a294b23ae87216b14ccee9ef56418dcfab9427371e 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7 9645cf90275611143863d0e3e63fbb7d507696315ec921746045ac663d525c4c1ebfb8a25b8df39f13eabf8c676827e618335fcf0aa59d9723b0e5417a2b4de1e2562bfdf8b18c7413e1ae2b47e67519cf581464d77f915faf37436142cbb325 +304bccb718b3a9e12669913490cc5bcc1979287b56c628fad706c354241e88d10e81445a2853e3fc32ece094ba1abc3fdcab61da27f9a0fca739371049fed462ee6b08fa31cde12720f8144a6f00ce9b1a7a6eadd231f126717074b4efb5c72ce673ca5859000a436f67a338d698759f12c461247c45a361fb6cb661fdbe6714 d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5 b5d44f3bdc30f31789d18519d08afebecfa37dcc1678e4e1b2e1c1516c1c8324ddea8fe9f2adc29f85588669c112cc631888ded406a4d7b14e8235ab4867ad21e2532fc80c7c75fcf4d762a9585038f2908af132df1462047b2a831968fa00e2 +64f9f05c2805acf59c047b5f5d2e20c39277b6d6380f70f87b72327a76170b872bfe4b25c451602acfb6a631bb885e2655aee8abe44f69c90fb21ffde03cef2a452c468c6369867dfd8aa26ac24e16aa53b292375a8d8fbf988e302bf00088e4c061aa12c421d8fe3cbd7273b0e8993701df1c59431f436a08b8e15bd123d133 b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224 a499e161fcdd59c8242d490f134f68a2a6ea3cdbdae736d4de9af58231bce27c27b6bfe4fdc98c422d51449819662d950b2f9828ae6d3b6b173520554e238f354ee2a7ed66cb16121add196ed6ccc2d693580438fc9483f37d05b17978411260 +6b45d88037392e1371d9fd1cd174e9c1838d11c3d6133dc17e65fa0c485dcca9f52d41b60161246039e42ec784d49400bffdb51459f5de654091301a09378f93464d52118b48d44b30d781eb1dbed09da11fb4c818dbd442d161aba4b9edc79f05e4b7e401651395b53bd8b5bd3f2aaa6a00877fa9b45cadb8e648550b4c6cbe 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 968fffb2534ba84207edefce7a45d82263fa541f746faf048e4d041356c749e4c85637d5a3be23cba984b62af828263e03049d5432bf1e8918bdee5a05ebe5a6f8b003c6a57352603d993d95dcf8bef104e6a79a7742f79d60d88063e377e61c +d768f41e6e8ec2125d6cf5786d1ba96668ac6566c5cdbbe407f7f2051f3ad6b1acdbfe13edf0d0a86fa110f405406b69085219b5a234ebdb93153241f785d45811b3540d1c37424cc7194424787a51b79679266484c787fb1ded6d1a26b9567d5ea68f04be416caf3be9bd2cafa208fe2a9e234d3ae557c65d3fe6da4cb48da4 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 b9e36ae3780ae0db4e2a600280f2b49551c843dea83f7549db29c52543043dbe64e50dcb55f7bead8f4b11e9c5fceaf80465d80514c794f4f95d9c1d55e27be3123069183b8f5590adfe057c65667475a2bc77eb408b5bbf514fa6910402da56 +6af6652e92a17b7898e40b6776fabaf0d74cf88d8f0ebfa6088309cbe09fac472eeac2aa8ea96b8c12e993d14c93f8ef4e8b547afe7ae5e4f3973170b35deb3239898918c70c1056332c3f894cd643d2d9b93c2561aac069577bbab45803250a31cd62226cab94d8cba7261dce9fe88c210c212b54329d76a273522c8ba91ddf b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 80e540afd0ae0b2d056316b87335dbd0791531330b861df51613ae745f523c15452dcadff49329338873a6dafb1089b30a495055fad0b4b0e920a81d4f6c9ceaaf77b91d2012b403bd44e58cf5f57138fd8e3bfcc54a95cc61ecc174d28f3c28 +b96d74b2265dd895d94e25092fb9262dc4f2f7a328a3c0c3da134b2d0a4e2058ca994e3445c5ff4f812738e1b0c0f7a126486942a12e674a21f22d0886d68df2375f41685d694d487a718024933a7c4306f33f1a4267d469c530b0fed4e7dea520a19dd68bf0203cc87cad652260ed43b7b23f6ed140d3085875190191a0381a de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 a3c0e7dd3588404b3a49f9512716cf68717164b28301a6e043fb2e4be343507979038101794d195e3ea842be26cad5df0e8a34a196070c69d457eb09673827ca27382e4723ade3ae29e6450a7e3dc57b4e52f38b362fa5b82c262dc2a09b1c8f +7cec7480a037ff40c232c1d2d6e8cd4c080bbeecdaf3886fccc9f129bb6d202c316eca76c8ad4e76079afe622f833a16f4907e817260c1fa68b10c7a151a37eb8c036b057ed4652c353db4b4a34b37c9a2b300fb5f5fcfb8aa8adae13db359160f70a9241546140e550af0073468683377e6771b6508327408c245d78911c2cc 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc 89303b2c921708ec3b563157b08a365f6a95df6fbb0e82514fea7e840dc8c27192d845489ed1f17150ac8c50142ca7cd17ea32620a62b0c5ab82e785b40f04f17bb319089e9f35bcce3bfd5caadffedceff8ab86d1d47830fc75ec23e7a9f632 +00ce978603229710345c9ad7c1c2dba3596b196528eea25bd822d43ca8f76a024e29217703dd0652c8a615284fc3edcc1c5ad1c8d5a8521c8e104c016a24e50c2e25066dcb56596f913b872767e3627aa3e55ec812e9fdac7c2f1beade83aef093e24c9c953982adf431a776880ae4583be158e11cdab1cbca3ad3a66900213d 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 a5ec2a18592d017dd8cf2373f9064c33db53f2e9bb619aec092bfb73a7624cce52716467d4d570247fb2d55f243f828c10b45d5da58aa35bf13d7ad981db7267b34b5087e38a62d783d4c7abc59b77dafd064e8afc6629e8f8c722fbc82358de +54a255c18692c6162a46add176a0ae8361dcb8948f092d8d7bac83e160431794d3b9812849bf1994bcdcfba56e8540c8a9ee5b93414548f2a653191b6bb28bda8dc70d45cc1b92a489f58a2d54f85766cb3c90de7dd88e690d8ebc9a79987eee1989df35af5e35522f83d85c48dda89863171c8b0bf4853ae28c2ac45c764416 ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 b846e69841d9fd373f44dc5d0237158556ddbc0c9f647c37813b281170d3f84d16efba2ec74f4df8b3d257090daa86aa024be09a4f38c8fc61f3ed3665dcbf06f4207b9ebd61b4df434d9eafd50c72ae451d7818c156725763fa9b7c56773360 +692a78f90d4f9d5aee5da536314a78d68c1feabbfe5d1ccea7f6059a66c4b310f8051c411c409ccf6e19a0cbd8b8e100c48317fe8c6d4f8a638b9551ce7ee178020f04f7da3001a0e6855225fb3c9b375e4ed964588a1a41a095f3f476c42d52ffd23ce1702c93b56d4425d3befcf75d0951b6fd5c05b05455bdaf205fe70ca2 adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 8ec671c456fc03a57be2948ac80672280eab5bd0b96e45438013b5cf0ea8e51bee3f023a423a3cf583856d9451ca2ef0080f3c32ea58f976aa9c7e7cd9a081222a72c35080e2b43a2c2859e2602325377526a2b8f496a1c5d400aeb1a5673c9d +3b309bb912ab2a51681451ed18ad79e95d968abc35423a67036a02af92f575a0c89f1b668afe22c7037ad1199e757a8f06b281c33e9a40bab69c9874e0bb680b905d909b9dc24a9fe89bb3d7f7d47082b25093c59754f8c19d1f81f30334a8cdd50a3cb72f96d4b3c305e60a439a7e93aeb640dd3c8de37d63c60fb469c2d3ed 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d 8da01f11b48d056d8d2b49dbf463833eeb31ea75eb7a45db19b0d052962aa021d5c9f06d0241e1e8d52bb28c167eedf403ab1543c10ec6de1a7223c276614b5b24cc12ff33798944780ad9cb3c0fc9ce2cd99faf8623b4aa719d5684e849a300 +f072b72b8783289463da118613c43824d11441dba364c289de03ff5fab3a6f60e85957d8ff211f1cb62fa90216fb727106f692e5ae0844b11b710e5a12c69df3ed895b94e8769ecd15ff433762d6e8e94d8e6a72645b213b0231344e2c968056766c5dd6b5a5df41971858b85e99afbf859400f839b42cd129068efabeea4a26 e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 88c1d0098b7f67128d88d1c2a921a15da1171bf4303e3dd25d221dfe27154c8757895bfe94451559c23e5b83ed0895d10d6ee9904271db1da40bf005c9f34a375ce7dfaf0fe2524086b57d238abed7d41f305a512585b1c6efa64ec67cefc7e1 +cf4945350be8133b575c4ad6c9585e0b83ff1ed17989b6cd6c71b41b5264e828b4e115995b1ae77528e7e9002ac1b5669064442645929f9d7dd70927cb93f95edeb73e8624f4bc897ec4c2c7581cb626916f29b2d6e6c2fba8c59a71e30754b459d81b912a12798182bcff4019c7bdfe929cc769bcc2414befe7d2906add4271 d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca 9978ab3241ea949856d5c62fb6095c7e2e0639997cb39c2cebfad762e895322f7914d0aaa8fcaad6c4acaf44a86b1f420ec7d38493ddd9d36cb7e1ca77be46a795052a4724647277c32a7b751b834696179f8091fbc27178ab10da93a35bfdb5 +d9b5cf0b50416573ff3c63133275a18394dd4326be2041e8d97e6e4e3855a4a177e9d26dfd223fe8aa74564edb49bd72de19916fb6f001f44530d5c18e2c332bce1b7415df5927ece5f3824f34d174b963136b53aef1fb78fb0c06a201a40b2db38e4d8216fc1e392a798c8ab4b3a314496b7f1087804ebfa89bf96e9cdb80c0 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d 8d23820dc2010f0c829a9cdf191afff8090e5767de9cd609e0e9a8477387b21a8eaef36eb74acf8ec1003f5cac8cae7e1373b0cb6081a47045a52473f59bd193814d462eccc7e703007c5b80540f2df5d95a2615ad0cb4cb69ec0f8c26f01006 +9e4042d8438a405475b7dab1cd783eb6ce1d1bffa46ac9dfda622b23ac31057b922eced8e2ed7b3241efeafd7c9ab372bf16230f7134647f2956fb793989d3c885a5ae064e85ed971b64f5f561e7ddb79d49aa6ebe727c671c67879b794554c04de0e05d68264855745ef3c9567bd646d5c5f8728b797c181b6b6a876e167663 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 8ce73675e337f4b339e948e3ff4aa3f66f32264d4bdf123a197b75f65332566b3de649f95e90531e6e843ec740ee59640219fccc497ab68c8dc07bcb39bb9812a78fb34bd8628313fb720d58f4c794e49b54b5dc9940d1bedfc30595805a0489 +0b14a7484a40b68a3ce1273b8a48b8fdb65ba900d98541c4bbd07b97e31bcc4c85545a03e9deab3c563f47a036ff60d0361684ba241b5aa68bb46f440da22181ee328a011de98eff34ba235ec10612b07bdfa6b3dc4ccc5e82d3a8d057e1862fef3def5a1804696f84699fda2ec4175a54a4d08bcb4f0406fdac4eddadf5e29b ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 93d05bd7c35418e446e121d6d9b5dfa880baa93c9565722dfe01f8e86f640de3e336cd533cc1350f1f572768907f785515cfc863e6083b0a11eb62872b547b3b8ad05ed813ffd5f7dbb13cc0f162b41b699ccab456f6504214be15df058f6741 +0e646c6c3cc0f9fdedef934b7195fe3837836a9f6f263968af95ef84cd035750f3cdb649de745c874a6ef66b3dd83b66068b4335bc0a97184182e3965c722b3b1aee488c3620adb835a8140e199f4fc83a88b02881816b366a09316e25685217f9221157fc05b2d8d2bc855372183da7af3f0a14148a09def37a332f8eb40dc9 e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb 8253162d458ff2b5fbe9d0dce0277810afa1a6401722aa37cf2f76e30da65d06bf26482fcb960312bfc21f5cc774a1ad142a0d4da8aa72040e107a51018613b971cce9ef709662e80f29ffd9caa1b74a900ae64f4720bafb676bd6913e30ad5f +67d9eb88f289454d61def4764d1573db49b875cfb11e139d7eacc4b7a79d3db3bf7208191b2b2078cbbcc974ec0da1ed5e0c10ec37f6181bf81c0f32972a125df64e3b3e1d838ec7da8dfe0b7fcc911e43159a79c73df5fa252b98790be511d8a732fcbf011aacc7d45d8027d50a347703d613ceda09f650c6104c9459537c8f 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c a0419b4ca90a0d85b5b6068007cee5edbbfe87700b45f4b009ded07b3c2aef00c80ce7854dd5553e57c8d7317ff75211128e85de582bfa64d20d927306b64cdbe559ef4dfdbb25e951902dd09de4e8d2b63a992c731de2c4bc09ab29dfb61ed9 +45db86829c363c80160659e3c5c7d7971abb1f6f0d495709bba908d7aa99c9df64b3408a51bd69aba8870e2aaff488ef138f3123cf94391d081f357e21906a4e2f311defe527c55e0231579957c51def507f835cceb466eb2593a509dcbee2f09e0dde6693b2bfe17697c9e86dd672f5797339cbe9ea8a7c6309b061eca7aef5 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f 8fca7df73a98f6950bac95e9bcf45ba054a022545d846d5bab124cf056485f0b1c5217992597f572dbd015ee8781a2b105e43b599b510881bc23c03dc1afb61f8a3ec14c28c32544d4a853d268927bc96a54fbea5524da57794f7e17d6d4dfc2 +4672fce0721d37c5be166bffa4b30d753bcf104b9b414db994b3ed33f36af4935ea59a0bb92db66448b3f57dad4fc67cef10ce141bf82c536be604b89a0bc0e8bca605b867880049d97142d30538fc543bd9d4fab7fdbe2f703815cdb6361beb66acff764bc275f910d1662445b07b92830db69a5994857f53657ed5ca282648 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7 b605b5727e025703dbe19366e796e8df2d6a557824c945c51f66816ac67707a8f45fbf8a07f6ed336f90bc897536c0a70a0fe7e8bfc209f8ea4ec5127627477c74fdf87daea474921fef9c645b0fded4fd3d53c500eb2661899cc2c057a2b8b1 +9ae48fdd9bfc5cb0f4d4761e28b2073bda05a3e3fe82c212e66701dc4573cc67a829b0f82d7520b1bf11db0c6d1743822bbe41bb0adbd7222aa5fae70fbd1a31f2d4453a01c81e064d775388468be96f6063f8673b7b8d4455fe1bd4c801ad5e625a015eaa4a1a18da490d2af8642201eaba3c611cbd65f861d8e19ca82a1ee6 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf 815c3a7dc1cb97de41a9f14495c0a1f89ba3e03ef8dde6a4f845d36fcd41bdd1b1973fd518ce17d205e0fdc94198456b01064339b1627ef0b1c4a356407f4ad75703f6485f8c37bd3f5c4946cdab24163855cf16fdec79179771bd021c4d8bc3 +817d6a110a8fd0ca7b4d565558f68b59a156744d4c5aac5c6610c95451793de2a756f774558c61d21818d3ebeeeb71d132da1c23a02f4b305eccc5cd46bd21dfc173a8a91098354f10ffbb21bf63d9f4c3feb231c736504549a78fd76d39f3ad35c36178f5c233742d2917d5611d2073124845f1e3615b2ef25199a7a547e882 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b 862b63e7a7ff4cd2dd680b3e052c2c1c9a6455b176f8ba77d0d81bfa6315952af91f6fe9813e28c4750bbce9ade9080a16bf51da4771cb624d38828b92e79c755a91fe38778311880d2673d076e86754370b3c1698b1dd1e89a6da1f758dd4a6 +464f10ec6fb229a51db5fd0e122f2cb8a9a022117e2987f4007bf5565b2c16aba0714e2e3cdd0c100d55ac3017e36fc7501ad8309ab9572aa65424c9eb2e580a119c55777676ec498df53ef6ae78fd8a988130ee0e6082bf1ef71cd4c946021018a8ca7154d13b174c638912613b0bdb9001c302bf7e443ad2124ab2c1cce212 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69 b84d285bc9a6890bf177b62244a511b94d5824345d7dd4f5273f31bf680ffe1f4db4cf174dbc9db08de21a588d27a957118738ddfc0cca9841d34358962ad66df67bdf0b75b6c6a50e0fe8a0866018746efe236b0aa1e721eb9432eb2d547c26 +4e3e0fb96320ddccde8b463c273654c4f7164920b1d63430921d2e808dee403e6420eedda0a557b911d00736a4f8798dd4ef26673efd6d190988ad4929ec64f8685cfb76070a36cd6a3a4bf2f54fb08a349d44642b6f614043fef9b2813b63457c76537d23da7b37310334f7ba76edf1999dad86f72aa3446445a65952ac4e50 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db 966b4c7ea606a573c2d3cad5858380b7e87be8e77b249ccae22b0162b94b117418a287e3209f056aaf9c1e93901c2d3d138ced5567a0c7ea8a857bbaf55004b7e66eec30158153fdb3418206c6465cb8d69158967ffed034f45bbf236b23208b +c466b6b6baf7e6ffa876ec06105e2d43534e0517c07b1c4c9fb67ba81ce09525a7721ec3c290f2b1f65b6463d41598e7a25b2238501629953a5ca955b644354fb6856733a2e5bb8f5bc21a0c803493f5539f9fb83aab3dba2c982989c2270c61ab244b68bfe1b948d00c2ed975e09c29b5f8a7effcad8652a148cc880d503217 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d b30f6879a115a5e193bd238e1762778683f80fd501f2b6f03a9cae29b4dae3682ad0dc2b98d48309177fa79fec88df6d02e7aa786633f34e0b703fabdff81faab83ffc0103ad8e3cf61baecf98055db258ac1b7ef1a575ce5fc4928889a14d84 +feac892b7720af80b3c9eede51e923f18d3d0c5de4c31f4aa75e36df7c7c2fd8f41778851a24b69e67dccb65e159dd5c383243bad7cfedcc5e85c8a01c34b0b94ba8e07e4c024c09d279b3731e8b62f9562d3c4f5042567efe42a9d0eaaabab28bc6f11232fc8ceaaf4518d9f3b2bebf020294496b7f6b879e69503f75fecd3d 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476 97c056239eb395129ac5bdf7c7e7b78f9be9f3023d3de20707bec86e59febe0b8cd6db46fd2640195fe2f928d2c7f64c139ad964438a7351a9708730e6143430018366100e247e312f93502af01d407244202e7bbcd0f887213372d31d24cfac +cf2982e3bf174ce547741b969403cd11e9553067e6af8177d89511a0eb040db924530bdba65d8b1ff714228db0737c1756f509e1506014a10736e65be2f91980a73891496e90ff2714a3601c7565cdcef5a395e2e0e1652f138d90d61eaa9cba993b823245647f6e07cec9b8b4449cd68a29741cd1579c66e548ca0d0acf33aa ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa a216e77bca7866706e0b56859ea2ecf3215ae7878fd1c924933002cad7f302c5de49e2f0c5075ea3f66a7de8d2da2eed15c0937844318c6c022c26ca322c5d2855ab1c165eed548d4e8d8d606a7cbd75fcb4527a97b613cc36a7f10a0436a2cd +bf9fdd4107ef5a6070108771ac9eee4f0c8043bf0d04db772a47294f4137e2439d94b337114b074e57e0cb78d0ccf352a2833e9788ee2a1a9ffeacd34f38fcefb86653d70c7dadd4cf6548d608e70acdef6c7530974b92c813798add659752a8c72b05e1ad9c65c21834ce6fbe49d8a1426b5a54270794436d284364fac6ec1a 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f a2b4127551d4be6bd9f7ed0e4cde8e5c86e1edf2abc7df9ee0d6c5f757e6a0c807c1983a2f0628c2d2216d674fffa3d4112ff79fda552c3c5794b6f733fbbf218f8bf17960d4b62799408ac659055855660621801b45faf2bf73a2f20c1e225f +5d634fb39a2239256107dc68db19751540b4badac9ecf2fce644724401d6d632b3ae3b2e6d05746b77ddc0c899878032248c263eda08d3d004d35952ad7a9cfe19343d14b37f9f632245e7b7b5fae3cb31c5231f82b9f1884f2de7578fbf156c430257031ba97bc6579843bc7f59fcb9a6449a4cd942dffa6adb929cf219f0ad e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1 8d82d056c030263f4a1c717f9dab22720c87c0c524d8557c44d08061b308729859ed2f198b6181259a221845da739edf0f3d6e681ba9c2fdb2e94e1e15cfa004896e2dd24e4fcb07fdc9aac6d8f00620ade76b0c62d28d4f1da1b27b752e65eb +c9b4ff721b3e886f0dc05856ffff0aabb64a8504b1746a47fdd73e6b7ebc068f06ac7ffa44c757e4de207fc3cbfaf0469d3ac6795d40630bcafe8c658627e4bc6b86fd6a2135afbc18ccc8e6d0e1e86016930ca92edc5aa3fbe2c57de136d0ea5f41642b6a5d0ddeb380f2454d76a16639d663687f2a2e29fb9304243900d26d 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c b3b4be845e5981b565caa4e41f635e80bcfaca4b31e1b6e3267ec80243098ba1fb3eec1c8678c467841503bb986573cb196b2e69a53345061cd78e0974a08c9835774c2c0c81f5ed1808dc8b39b90908b38bd99cee597c6aaef046b9bbffd04d +db2ad659cf21bc9c1f7e6469c5f262b73261d49f7b1755fc137636e8ce0202f929dca4466c422284c10be8f351f36333ebc04b1888cba217c0fec872b2dfc3aa0d544e5e06a9518a8cfe3df5b20fbcb14a9bf218e3bf6a8e024530a17bab50906be34d9f9bba69af0b11d8ed426b9ec75c3bd1f2e5b8756e4a72ff846bc9e498 e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c ad1cb060fa9f7d2b01fd0fcde8172da324515dd4871fb8918b7d6ed76c7ad44533cfc4a59085bf6982feca65419261520f2b623e66281057b594c52d60aad888fa88dc615948308a42d5d3619a3e6acf477d6c3b958f8cbae7cd00c5a4e0b386 +dbd8ddc02771a5ff7359d5216536b2e524a2d0b6ff180fa29a41a8847b6f45f1b1d52344d32aea62a23ea3d8584deaaea38ee92d1314fdb4fbbecdad27ac810f02de0452332939f644aa9fe526d313cea81b9c3f6a8dbbeafc899d0cdaeb1dca05160a8a039662c4c845a3dbb07be2bc8c9150e344103e404411668c48aa7792 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855 910b98f42a6c063254ea563fb7483a4ce5b7088d67893ffcb8c9c5745e284b734e4f1fbf5fc65c241aa470e5810eaa7b18bbc6522931ec20809bb4facfdd864c3a61aade4fc7bb359041fb29798144de747c98b24c3f1011a572c4353d0d44c5 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P384_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P384_blst new file mode 100644 index 000000000000..3394b523cead --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P384_blst @@ -0,0 +1,60 @@ +39f0b25d4c15b09a0692b22fbacbb5f8aee184cb75887e2ebe0cd3be5d3815d29f9b587e10b3168c939054a89df11068e5c3fac21af742bf4c3e9512f5569674e7ad8b39042bcd73e4b7ce3e64fbea1c434ed01ad4ad8b5b569f6a0b9a1144f94097925672e59ba97bc4d33be2fa21b46c3dadbfb3a1f89afa199d4b44189938 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727 81e2920282569f2d703b7389f3e3aa8b8433df04b362813910154fccf60c08875e63f98742a05d70baf56f4d1a26ffcd063ae5f5f3dbd379d876cef18b4fd6779fce833457a37a2e70556ae6dc4c104e6390512effaa31a88c9eec5860ea9e62 +5a3c80e608ed3ac75a6e45f6e94d374271a6d42b67a481860d5d309cc8b37c79cb61f1716dc8aa84cb309ef9d68eb7fc6cf4b42333f316a5c30e74198c8b340926e340c5de47674a707293c4aa2a1a2274a602f01c26b156e895499c60b38ef53fc2032e7485c168d73700d6fa14232596a0e4997854a0b05d02e351b9d3de96 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246 93ec9ea1b3878dd20b839c96a37001f2b5b9bae2a0eade9ba81840bcf9eb443404bbe4468650222ef9dd36df13f3cf280eec51f0288b71b85590e20fb1ece8c4d69f9b9af84d3ee032ca2fc8a3da6d7b68d472c17c80107fa412d45ea84d78b9 +e7d974c5dbd3bfb8a2fb92fdd782f997d04be79e9713944ce13c5eb6f75dfdec811b7ee4b3859114b07f263846ae13f795eec8f3cb5b7565baff68e0fdd5e09ba8b176d5a71cb03fbc5546e6937fba560acb4db24bd42de1851432b96e8ca4078313cb849bce29c9d805258601d67cd0259e255f3048682e8fdbdda3398c3e31 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83 b1f01a69ea863d8cbc2408257e708f365c08043c47fbbef032491c0d5d9c1d9ea13c07f212aa9629afd6ababb3d8046511dea6e12b56894e9cb207232dde380e2a24bb47a0cb20d9982d534d6b124ba37fb69a74118851a24b684e8216c01769 +a670fda4d1d56c70de1d8680328043b2b7029633caf0ee59ffe1421c914bb937133d5a0f9214846b2e0b350455a74c4ab434c56de65a17139bb8212bf1c76071a37536fa29348f871dbb26baa92eb93d97e923a6d2ffd9be25cbc33075e494e6db657bd8dc053fe4e17148d8cf6e2058164f2b5766750eb01bbe7b361cdb848c dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659 82a2db729dbe40435b6abc6dd72545aa3c910ef5f25ee7727d9113b35c5138f324dd3d11a5ddfda49741de8ed292989518ba23a23e74da3a69240a1c0c1f82f0e1b9e3c3ce68673af1f53c36d17b60311bb67cc3fa97d36fed08db151c76380a +7843f918fe2588bcfe756e1f05b491d913523255aa006818be20b676c957f4edb8df863c6f5f8c15b3b80c7a2aa277b70d53f210bdfb856337980c406ea140e439dd321471407f374f69877b2d82367eed51e3c82c13948616dcb301d0c31f8f0352f2846abd9e72071f446a2f1bd3339a09ae41b84e150fd18f4ba5d3c6bfa0 df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718 8b313157728c696b5587aac9406ea7255b009563fd52ac746ecfbd5ec1a7d739107975bf434c7459513dd2cadef357cf0ec8ebf153f4342bd2835b6d9b21366b1dbb7d25afb4a2a884a1a023bf0fee69b534738da79707f2e3b181260c6e11eb +caa83d5ab07febbd2e0fe2d63738b9b7b8752594bea7aaf50345b3d2f316653a8c9222f2b7877b64679e9573e81461a426029e45b8873a575094a1d572e0d32a9f0a9c6bcb9a2868543b7d8bbe4a69a09e7321f05f8366cced1b72df526f895b60aed2c39c249653c7839538770d4e5f47d3926ec0d168ab6a1af15bf1dca1f7 ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f 92c6c3080ca9c09c2a11313a623ca0edadb0dcebcce33ac131c21ffdf843913cd2a4d56da4fbabba1c5c9c193e479124160980efccf96fdd13f99dab109bea248c44d411948d84978a7e780592ff1e7c7bf09362ab654ea419a92550c4c557d5 +594603458d6534974aeeafba919c4d0f4cb6843a3af41204bbb88aeb2fca2772d305163dba863da050aabedbaf89db521955d1715de95bbcef979ecdc0c976181ece00355385f8a8f8cce127c9eac15ce3e958a3ed686184674ec9a50eb63271606ee7fdcb1323da3c3db8e89cad1fb42139a32d08abcfbf0d4ccfca18c89a86 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829 acfebd85e1035916e69a4253c3f50238e1b915db695a3c92055f9287b54a5ecf243f57d2aa4dcfa5ee6c2408bd7e20550442e2ad36a502f15ae8c02405e79aa2bab5673a3d196a9215c2569b56e38858de7c9779b6910d847e4b211594fc3e61 +733252d2bd35547838be22656cc7aa67eff0af0b13b428f77267a513c6824c3dbae533068b6817e82665f009560affcfe4b2ddb5b667a644fc1a42d24f24e0947e0dc50fb62c919bc1fe4e7ded5e28f2e6d80fcf66a081fb2763526f8def5a81a4ddd38be0b59ee839da1643eeeaee7b1927cec12cf3da67c02bc5465151e346 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1 a929313d7c7e00725c3db924ba71fd4a687417dec1d9999a07283561a9d9516a65edb3c3ffb1b15f9c06db9733447965135e1018c671adbe128d4ef6fa24f0bae2cba866e9c442e04882091cb0dcf12d035c5adbb77edbb7aacb3b7d5f7a691e +5a182bd174feb038dfae3346267156bf663167f713dea1ce936b0edb815cd9b8c8e4d411c786ba2494a81442617255db7158b142e720d86c9b56680fb9efd4298cdd69079a28153494c42a24251c7ad42ecf7e97eabc1b3997529b2a297cbad2474269b87a0b1e385f2d7f8b6eb8d1cd75eaf7e91d1acbecd45d7b2bfbbe3216 e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d 960b07ec819050d4520dec75aeadc48f3b0e84c971218af8ac8a3ff20d6fd949c6ec19c9feeb4b6826f9246fc8a9f3a0063448f1eeb2a81704c9526ce5472044c4198e35bbf76a3af07392fb793e207d0426fdbe0bd231451053d085c4fe9fc9 +aaa99fb1c71340d785a18f6f668e898c25cf7a0ac31d13c5b388b7233408493a5a109af6d07065376b96f4903df7aba2b2af671a18772bb0472490d1240cde28967680727dd4acd47e0308920a75da857a6eeedee5b6586d45dff3d8a680599665aa895c89dd7770b824b7dee477ac5e7602d409d3cc553090c970b50811dbab 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead a76b80534514fbe5fddf765e1bed11c75035b53aa66c6cfe6ff88a3d64d86a8ecae51236b3af125beb1ea1c73fd3b0701534d62ec7e17591b8cb3a03c13106fc8682f81ef1ba0b9455766c9c8751f5b2c5c1cfb8be8c57bd089e7d7532c404b8 +1fadfa8254d3a0b82d137cfdd82043d5dc1fef195d5297b09cc5cfb061f59c933451c0dc2a11b4037f34f88dacb803251f8880c4b72585c3c196e6fb23484ca43a191f8e41b9b9a37e2e6fcaab6738c3c62d1c98e1c620bb788b7b51a04f998a510efdba0d3418622fe8ce203b3fcd553b9b4206365a39031797ad11e49745ec 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0 98f841933a8614e21bb1dc6227d680b19ce44dc49f99e9e270a639a8e457961d246496da34a3cb67a3cbbc196b7e77a200e15614bfdadabbeffb357546ed103a8f4663abb44f941adcfee6a677871df6493cc042e332fef3268694e130c919ca +9ecb6f5ed3ba666a8536a81ef65012c2cb8b433508798d84708abb06dfb75503886f78384fb8c7a4d2d49ef539d9b8a0b60938c7f07471dda91f258b0d99691b38a8403a2bb3f956bdfd09baba16d9b6877097a9b6213481b47a06e139d23ec7abad5668d21f912fdb70d31bb9adf9b3ce80e308252fa81a51674f88d02db72b f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1 ac18328de02538f481d9272e96a171781cb0d59377b4a99c1ede1b8d15cd06e03728f42382c486a2efd9ac90b95b99aa1579d6d585881845971c4663a557bde2fb2667f945fbedcb83571095d4e6dc7e0ed6cf2e5707c87bff41bda026a2ae20 +e55bfca78d98e68d1b63688db12485578f36c489766f4d0bfaa0088433ff12133aaca455805095f2e655940860958b3ead111d9070778ee3bbf3e47e43d9eba8b8d9b1fdf72f793fcde2bcaa334f3e35fa2cca531ea7cf27fe9ccba741e38ac26129b2d612bf54a34e0ae6c166c0fef07fcd2b9ac253d7e041a500f7be7b8369 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb 871eb50c74210fec2ad87cf9f993e23a70ba372597ef4ce1d419233d323ffec4b0da9726eb2fa4fdd1c9cc28f022140006c13a4a612fc995d4dfa77500b2f54e91392504a31c2dcead3a1f0c54c824a14654748d763fb9b5c398bf12e0d486d0 +02c6b3c83bd34b288d96409162aa4ff114e9d134bf948046eb5ebcc0c7fe9dfceadda83ed69da2fac00c8840f6c702a3fc5e6959d70f7e8af923e99e4937232ae3b841ffefd2e62fab3671a7c94a0281b8ea5bc176add57c5c9b6893fe7f5d48ce7256b96510810c4e046168a3c5be9843b84d5268a50349b3444341aa5490dd 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6 a8f82b8c6ea42c9bf5dc879f6416bc85c60ee852ceeb7302ebff78dbf8e5acc17635078e4e453d69a06969487ea1d3080c092117d29125d604e247a14d1aa8514d6a84b6831756faf798129a68ea0188174a1b07bf2f0018b8a7b026cc0fb3a1 +94f8bfbb9dd6c9b6193e84c2023a27dea00fd48356909faec2161972439686c146184f80686bc09e1a698af7df9dea3d24d9e9fd6d7348a146339c839282cf8984345dc6a51096d74ad238c35233012ad729f262481ec7cd6488f13a6ebac3f3d23438c7ccb5a66e2bf820e92b71c730bb12fd64ea1770d1f892e5b1e14a9e5c cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd 8527a781caca608830a9fe87e2d6ebfbba80c45a80d458e35a34ce3c842304355e7d7c573eb301e16f9c7cc5532d1dcc0893d30c5e2be0251c02955d53010ef6bb44be194dafd8e36d0a6bcdfeb374f63a55d3502d9ef14b037d0741e4925bce +663b12ebf44b7ed3872b385477381f4b11adeb0aec9e0e2478776313d536376dc8fd5f3c715bb6ddf32c01ee1d6f8b731785732c0d8441df636d8145577e7b3138e43c32a61bc1242e0e73d62d624cdc924856076bdbbf1ec04ad4420732ef0c53d42479a08235fcfc4db4d869c4eb2828c73928cdc3e3758362d1b770809997 c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b 826023e7b438b1e8df6389a3cab94966cb7e0ac1c5e7685a80f310fbfa8512c578c55bdb1f3f5e730aa57469169e443c024ab066d58ccd738abdc6f8b821b10ccebdba86a2fce579d60a013cb7b01ecdf946294b730bbb55f8d89352a886f4a3 +784d7f4686c01bea32cb6cab8c089fb25c341080d9832e04feac6ea63a341079cbd562a75365c63cf7e63e7e1dddc9e99db75ccee59c5295340c2bba36f457690a8f05c62ab001e3d6b333780117d1456a9c8b27d6c2504db9c1428dad8ba797a4419914fcc636f0f14ede3fba49b023b12a77a2176b0b8ff55a895dcaf8dbce 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9 87df337f550a29ab1696aa8c5f3fad653c11b0c35f002d1cf39ecc90ae28dbb7aaaaaf43c33a9df7dae7137efa615b2a0a1ad7a16d1fcfe80469053bb13237ff1702c078ee09c2f115f45c8860f69b2bbedef424de89e0331cb7d8ae54cfb940 +45e47fccc5bd6801f237cdbeac8f66ebc75f8b71a6da556d2e002352bd85bf269b6bc7c928d7bb1b0422601e4dd80b29d5906f8fcac212fe0eaaf52eda552303259cbcbe532e60abd3d38d786a45e39a2875bce675800a3eaeb9e42983d9fd9031180abd9adccc9ba30c6c198b4202c4dd70f241e969a3c412724b9b595bc28a d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f a2e6eefc69c9b6ee2584354ca0f80b7fae9e5c5e333f170b8122f5709bf865795de32e614bf9cdafab7305cd28a0985c119256f8c71c23cc211d9f73d786092b99a97044db4812d98330b12e8034dae513c0e7ef47b6d1ad14fc30daf98599ed +c33ff63b4e6891e00b2349b3f2907c417ca355560544a91e24a7a0ee260d6850aeded29fc0176b6039ca6187e8333391047cceaf14b1077df8f147dad84d36b2dac5666dc2f69dc9b58b88cc73956efdb3b47f91831d5875051c76b0c4e9fc087012a1f03eeee85d6745b46aa50bd9cb0110c2c94508765cec162ee1aa841d73 d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3 b2cdb71290fe5774fefe84e9af7d8ecc6ac6ddf6077134034f5740dc196848abc5dc26d068b7fa6432fe99a4abce6aaa02768e80b1edfc5e6ed8e884f345dca08f3cfb44d8504fe7e6be6453d96de2ab8c8377c769717dbacefc558b05b67dd1 +f562f2b9d84b0e96a52532c3b43c39c8018c738bd8dc3797a7de7353971b2729d522d6961b1f2e4df3f6a4bd3653e6d72b74fc0dba92ab939c4b542e994e5db6dd8ed4f56f651e699052e791237ae1f552f990ad156226ae8f7bf17fcbfa564f749604f97e9df0879d50985747d981422a23040fe52f5ec74caf1d4aaad8a710 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93 a1b09623fffaeb2310115b883698c8942c5ab68d6a0abe1636d47c4ef8fe968389be1cbed7a5b5599edb4506188f4021126065f29b0905b70060e67f7ca750f3b946c908299fd93382e7f8c81f882db41f322bfd67f3a4dcc805d97633d7cd8a +ace953ae851f571d71779aa120915f27450b236da23e9106f8d0756abdd25861937941228d225d5fb1aa1b1ebf759b1e326aeb3b6cd0cd87edd2ab9f6a7ad67b63d2c501d6a550edb2e7c9d216cc8af78dd33546af64d00abed4d0d2cfc5c9a7b5a055dbe8f7547902d185cf46937314832bc5c602419a82ab83dbd9d3bd5aff e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1 92d8757b6df3aedf288c6ca6b7c45cd424b15ce44feac8c57acefcf10dc4d0a6dc1b6f1db7f55e2694c5a7f8277e1cfb051df03b73fb0bc9fb20153bca53f08dc76276e4ae03d68fd9d0b71dbf12c83de2cd5a3660e810bb013b9d39eb01eaa4 +9635ab832240be95301bedb94c5aec169eedc198cbbdfedcf41e9b586143d829b4597a6b2a81902828332825fd84a785f187a3894e21bd99d22c4f94dcf34453fc052f15ec64d1447c932cb38fcdd30b7be851963409c11881438cbaad7e96f9efbde317f2235d66af804477a5dfe9f0c51448383830050ecf228889f83631e1 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960 b7a3f4e835d27f39f21a431ac57ac664def693dcfc8b95ffaa448bd09b558f44e81f91f96718298dfa732026d62229c00ffca00d40804876e0d59c755a426225ff3803b1ea5ac9a428b867714c1f8aa26368aafae031986c11060b218450067b +d98b9a7d4fe9d0fd95de5056af164a8b7882cd34ab5bde83a2abb32dc361eb56a479a3a6119db3b91dcad26a42d2206749567f0d97c34a981a91fc734921821a429f6a53401743a5c406ba9d560f956203abc9d1f32f1a13e7d7b290f75c95fdbf857ea597021461c06a3aacfa554ede3d69e4ff03bbbee5b7463ec77de2b3b2 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57 b26ca6f13d6db2aa0e2e61c1b8b6dfc1ef8ea33fb1bfd755564540d4eea45c5ce290560e852f915c8bd240b7128cc5fd02bf5bfcafef6c384343ff1e35b1f63e352a53076495182dc6352dde570a81aa9bebfb8fbbbf0e0aa1290e72a5eb20cc +1b4c754ac1c28dc415a71eac816bde68de7e8db66409af835838c5bb2c605111108a3bf13606ed5d8ade5ed72e50503e0de664416393d178ea4eec834d8d6f15039847b410080fd5529b426e5aadd8451c20ebd92d787921f33e147bcbeb327b104d4aab1157fc1df33e4d768404b5ccb7110055c2508c600f429fd0c21b5784 a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1 b45912e98ae900d90c75c1c5ba35fea6ec5b02a5afd4285b87b124d05220476cfa704b96d3437391f9192a986bcfdd480c5b3d4caddccc1ecd6272bfc49765c303446b1915a8aaaf8f9cd9cfc3b89a319b9f183e733c54bb83b20ec7b1686c7f +3cd8c053741dd9f974c6c5dbf8a1e5728e9b5eafb1cbcfc3452f5fbbda32a8c7564dee157e8d902c52514361da6d972934a56b3276e2a9379e328e24282e0db697c5bc29090fc489ec46b7b188325dd4e96494c250de0f4a89fe2ccf919eaefcfb50c288113e6df92714feb7f46e0822478c796d0f4ff3447a32997e892693ce 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3 a5231522968eadf5eff6c789a15b394454fcd8bb3bbf9ffc7caefd5573ba78c1b225777eb2b5eb9753e7fa90bb3d95c414f5320c3a232ed16d8f2f1b5b1d9195a3490c333b628241007e4041ef53c4201123450294cab0f79026bbd4d50de3e7 +ed955dda6d9650124804d3deb6aeef900e520faf98b1ef6f14efcada7ca2433f09329b70897305e59c89024d76e466b28fe02cb2a9b12e2478c66470259d7c282137a19e5a04ffadea55245c0f34a681593fedc42931d8b3321b3d82e9cc102cd00540ad311ec7bd8c9d06db21bea4ca3dc74d98931ae0d40494aefc2345132c 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907 830b6063dc0c29e3efd8dc1927c6695775d21412d902cfb686628cbb38f33db9632e1b89c3fc906227671b535720117f0d1c453f279e9375f6e19d1b14e28feac44cfd943daff00b8f7a333c5f169220fe57ae84a77194cc6219c61239a5ca74 +ce395b001da2a58e49691605d44af4206306f62f561bf2394060d2a5591a350277166bed043819035f1e60b5b3fb5ae113ddd0473f8ef6b2b050c472c2a264e1d8b3ca82a4f158c40f2d78d9ce5e5ea6de243f2e1f13f47f6c6f403b270912c81c636be35b396ca58468b3fb60aa83911d61441a0528d973bc31f965d4059080 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245 890a5c2b9432131786b2752c581ff843fa60ef89fe173aae29172483ea53db33c43b7b5742b85ba6eb04f2718d6aab9101bdd07eebb35ff4b810ce8a2a3af4ee9196d742166b723a555cbdc7a61da49f6bc028f8caf00e7149d4a6fc3dc5d174 +ffefe316455ae4ffdb890bb804bf7d31424ea060ecacff419d0f7134ff76ad434063c0ec0f8bb7059584d3a03f3625bb9e9f66ace1a47ac4b8f3e76fc7c420c55edb1427d1fa15b387ad73d02b0595c4e74321be8822752230a0dcfb85d60bfa186da7623a8ec3eb1633f0a294b23ae87216b14ccee9ef56418dcfab9427371e 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7 925c0b1097b37ab298245bf46379f65545a9cdebb9391c391a6555adcd95cfc2a9623407a918a4f08bae8e51566ed50d0e7267c55650c1c72ce7dfd1b2723482c141308df2bbc54fad9fdccbf6e81fdd8ccad4310ddb1abead2c552c6d414e8f +304bccb718b3a9e12669913490cc5bcc1979287b56c628fad706c354241e88d10e81445a2853e3fc32ece094ba1abc3fdcab61da27f9a0fca739371049fed462ee6b08fa31cde12720f8144a6f00ce9b1a7a6eadd231f126717074b4efb5c72ce673ca5859000a436f67a338d698759f12c461247c45a361fb6cb661fdbe6714 d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5 821af96e7ef553b2c9551ced3d6d016ca531098ff786e381d6bd0215230f9c6c8766632d2ee7a7893e34c0df2cc0eb9e03ebb159cacbb47426db68e2ad71bf2fc2fc37cef8756c93fb4295034bebbb1527904593e6c6712d6c08fc89c0f17971 +64f9f05c2805acf59c047b5f5d2e20c39277b6d6380f70f87b72327a76170b872bfe4b25c451602acfb6a631bb885e2655aee8abe44f69c90fb21ffde03cef2a452c468c6369867dfd8aa26ac24e16aa53b292375a8d8fbf988e302bf00088e4c061aa12c421d8fe3cbd7273b0e8993701df1c59431f436a08b8e15bd123d133 b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224 ad4d075dd3c6df74e7aae296e196b0c09d1833b9e8a1944353f3a04c8dd3943d052b3856b60acb365cb69b330cd941520f4dae5e84afac4550d354142c9986703dba6c64f39bbddf99bf1b574cfd194a594f2fa71521822dfe844fc6c810a520 +6b45d88037392e1371d9fd1cd174e9c1838d11c3d6133dc17e65fa0c485dcca9f52d41b60161246039e42ec784d49400bffdb51459f5de654091301a09378f93464d52118b48d44b30d781eb1dbed09da11fb4c818dbd442d161aba4b9edc79f05e4b7e401651395b53bd8b5bd3f2aaa6a00877fa9b45cadb8e648550b4c6cbe 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 aa5e2e20f3dc229c2c885ee529aa00d75453c2a6d18185e897ab559f33b9df6b1814b0220a5942ec0416e5e0f9195518180b4e89c2529ba2221f921070e9a1d688f427534b3c5e28f191b3b9591363fd948b091dacb817b9d604332a27c098f1 +d768f41e6e8ec2125d6cf5786d1ba96668ac6566c5cdbbe407f7f2051f3ad6b1acdbfe13edf0d0a86fa110f405406b69085219b5a234ebdb93153241f785d45811b3540d1c37424cc7194424787a51b79679266484c787fb1ded6d1a26b9567d5ea68f04be416caf3be9bd2cafa208fe2a9e234d3ae557c65d3fe6da4cb48da4 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 a8a56adba846d78cb0a5ae054228c19facadd8a7d41e736cd02f6984ad39ab2eead54403801f090843e3ec4dfdf582dd18ee596ba3c59abf4e4bad21a67016ae70178c312f722a71db9bfda55fa3a2af79120f164d49133133ddb4767ff7f20b +6af6652e92a17b7898e40b6776fabaf0d74cf88d8f0ebfa6088309cbe09fac472eeac2aa8ea96b8c12e993d14c93f8ef4e8b547afe7ae5e4f3973170b35deb3239898918c70c1056332c3f894cd643d2d9b93c2561aac069577bbab45803250a31cd62226cab94d8cba7261dce9fe88c210c212b54329d76a273522c8ba91ddf b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 a39804fd92554faad7b2ec9d419a71e6acfd3ab6555d92c7a58f5410a238418ffa64069b7e70ea289235b0b0a2921be610b194b056cc8b3f6951be1b715a2bd2e604d24a77ea1f8d544a9f59bce935cde05cf9441d7d88b671f65f1f1ecc2a49 +b96d74b2265dd895d94e25092fb9262dc4f2f7a328a3c0c3da134b2d0a4e2058ca994e3445c5ff4f812738e1b0c0f7a126486942a12e674a21f22d0886d68df2375f41685d694d487a718024933a7c4306f33f1a4267d469c530b0fed4e7dea520a19dd68bf0203cc87cad652260ed43b7b23f6ed140d3085875190191a0381a de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 b804c2501fd06a626791b59b567b99aa8bb5716c667ca23e283058f97fe28f9653519a9e48a8f12f4a8b542c47008aeb0119276e534b8d31174b01fa03f3e555ff81567ebb0d19a36719a9f25eaf3acd12d693a7b035f722c01632dd66c0bd31 +7cec7480a037ff40c232c1d2d6e8cd4c080bbeecdaf3886fccc9f129bb6d202c316eca76c8ad4e76079afe622f833a16f4907e817260c1fa68b10c7a151a37eb8c036b057ed4652c353db4b4a34b37c9a2b300fb5f5fcfb8aa8adae13db359160f70a9241546140e550af0073468683377e6771b6508327408c245d78911c2cc 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc 997f320a9d89eed83272668e53592449766eb30073e632ab32976abe9d8348d4aad9495ed30fb9d8a31d7159d91c2ab40b5ecd0775be046845be1245f078d22585329b19069eaa6f144698bba148c088988cedc8bac76320f97455c7bac9d331 +00ce978603229710345c9ad7c1c2dba3596b196528eea25bd822d43ca8f76a024e29217703dd0652c8a615284fc3edcc1c5ad1c8d5a8521c8e104c016a24e50c2e25066dcb56596f913b872767e3627aa3e55ec812e9fdac7c2f1beade83aef093e24c9c953982adf431a776880ae4583be158e11cdab1cbca3ad3a66900213d 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 b63f6ad5c217dcb5a07d6ea5cd17458fbef50dc70da4c890d4e5a2501db427f0c48b93b4f73bef89e2c539ea880f597d15ffbb68ccf3061c3809626a517594bb69550e682de187f921e1462b1a718e41769dd02e7c81c2a7329172dfbceb06b2 +54a255c18692c6162a46add176a0ae8361dcb8948f092d8d7bac83e160431794d3b9812849bf1994bcdcfba56e8540c8a9ee5b93414548f2a653191b6bb28bda8dc70d45cc1b92a489f58a2d54f85766cb3c90de7dd88e690d8ebc9a79987eee1989df35af5e35522f83d85c48dda89863171c8b0bf4853ae28c2ac45c764416 ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 9854178da566948cdd452dcb25a56dbd18bfc547e8b528690748d8f3476d36082b645aabac428e37a1a81af23e8944bd125f28053016489cc3421592331524b40ddb50aebcbd880246787d425c009a1dbab28306086d90b55b899b1d7525c73a +692a78f90d4f9d5aee5da536314a78d68c1feabbfe5d1ccea7f6059a66c4b310f8051c411c409ccf6e19a0cbd8b8e100c48317fe8c6d4f8a638b9551ce7ee178020f04f7da3001a0e6855225fb3c9b375e4ed964588a1a41a095f3f476c42d52ffd23ce1702c93b56d4425d3befcf75d0951b6fd5c05b05455bdaf205fe70ca2 adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 933804a61cd13dd67be71e73ddaf1605aed4d32f601f8330e1abb88aaf4308eac994056bd7f6ef5891ec057859bf8d1b125234d9340426c98e44f38d44d1226fc224dd4c73841caf20a9a84ef543df952af2beba40896646aa5a38b09812bf5b +3b309bb912ab2a51681451ed18ad79e95d968abc35423a67036a02af92f575a0c89f1b668afe22c7037ad1199e757a8f06b281c33e9a40bab69c9874e0bb680b905d909b9dc24a9fe89bb3d7f7d47082b25093c59754f8c19d1f81f30334a8cdd50a3cb72f96d4b3c305e60a439a7e93aeb640dd3c8de37d63c60fb469c2d3ed 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d b92e708875297ada910780ecd62daed4dd87357f8c772c1558b509b47e44cc4fd3e2e037e101f9537574a00024b9a9bc19711d125f1fbb14dbcd1d79941f128ee8814c30ce098030fbc31105e244080b181cce605b2cfec8b4e82001fe81cc12 +f072b72b8783289463da118613c43824d11441dba364c289de03ff5fab3a6f60e85957d8ff211f1cb62fa90216fb727106f692e5ae0844b11b710e5a12c69df3ed895b94e8769ecd15ff433762d6e8e94d8e6a72645b213b0231344e2c968056766c5dd6b5a5df41971858b85e99afbf859400f839b42cd129068efabeea4a26 e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 84d9e5797ff5c18fb4b13374bae0da0f523efd9964edb2892f809e2c6d4f16a9ef8c20465f97db1c046f6e76edab5f9817b93b36df4c327042fe5f3fd7dfc7629529d04f8ec51e7024e04a9c4bae4f1d0ee8749718d7538b532e5274993bec6b +cf4945350be8133b575c4ad6c9585e0b83ff1ed17989b6cd6c71b41b5264e828b4e115995b1ae77528e7e9002ac1b5669064442645929f9d7dd70927cb93f95edeb73e8624f4bc897ec4c2c7581cb626916f29b2d6e6c2fba8c59a71e30754b459d81b912a12798182bcff4019c7bdfe929cc769bcc2414befe7d2906add4271 d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca 97d59c14bcd8025b748bb6ecff7a05e439dd4c1fe7af746e9e7cedaf876dc28a130bbc84ee013e138b9f4a772ffc78d4142983ca8c3f5d03ecc9880fa22c7f7920a10f117d804f3b0ea8e52b0fd2f40defdd4fb752d4f6e3261f53ff73bafa75 +d9b5cf0b50416573ff3c63133275a18394dd4326be2041e8d97e6e4e3855a4a177e9d26dfd223fe8aa74564edb49bd72de19916fb6f001f44530d5c18e2c332bce1b7415df5927ece5f3824f34d174b963136b53aef1fb78fb0c06a201a40b2db38e4d8216fc1e392a798c8ab4b3a314496b7f1087804ebfa89bf96e9cdb80c0 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d b54bcf2044e7fa4b80158572af2b935f9098033de7e46f49034ec05b97225154118ab9e026f85d59927332394e939871182dde915fcd3561f4363b0624214d5c61abeb85f1bb91bb37205613bb044707a9e03c848b516cb05dfd5a42aed32cc2 +9e4042d8438a405475b7dab1cd783eb6ce1d1bffa46ac9dfda622b23ac31057b922eced8e2ed7b3241efeafd7c9ab372bf16230f7134647f2956fb793989d3c885a5ae064e85ed971b64f5f561e7ddb79d49aa6ebe727c671c67879b794554c04de0e05d68264855745ef3c9567bd646d5c5f8728b797c181b6b6a876e167663 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 a6ee89c35c0fb5f68444ffa36a30c123ef6ead4f647d4ec8863ba2c35746fb5224311cb829ff97ba7c05b5582e97581111689921f6100cced802a775fa41f8bc4db41c5c719cbd98ef552ffde76c30aeb54067e1806b819adea57399cd584328 +0b14a7484a40b68a3ce1273b8a48b8fdb65ba900d98541c4bbd07b97e31bcc4c85545a03e9deab3c563f47a036ff60d0361684ba241b5aa68bb46f440da22181ee328a011de98eff34ba235ec10612b07bdfa6b3dc4ccc5e82d3a8d057e1862fef3def5a1804696f84699fda2ec4175a54a4d08bcb4f0406fdac4eddadf5e29b ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 b2b66aa61dd2b6ea00601b8aa98c369f7c7b36b73f5d9699294c8c47a1eea55eac2f5d61ecfc40b7f0468a1c6e884a191333e3dbc82c31028755f0bf836afa45357a3806e3400e12879288aee50d78999c78a7cfda3520ad57e52488133d8430 +0e646c6c3cc0f9fdedef934b7195fe3837836a9f6f263968af95ef84cd035750f3cdb649de745c874a6ef66b3dd83b66068b4335bc0a97184182e3965c722b3b1aee488c3620adb835a8140e199f4fc83a88b02881816b366a09316e25685217f9221157fc05b2d8d2bc855372183da7af3f0a14148a09def37a332f8eb40dc9 e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb 984e656ddedda6020aaf0cc94aec903f5990fae1dc616fb95137693770729c1630c84d7c649cfd5f3b0e01ea6c0b45af0bb3193976ac52a64caf8b954700455ca4092e9534921afcfed744e46241cfed4ac1ade131a5dc6d0529045ada675ea9 +67d9eb88f289454d61def4764d1573db49b875cfb11e139d7eacc4b7a79d3db3bf7208191b2b2078cbbcc974ec0da1ed5e0c10ec37f6181bf81c0f32972a125df64e3b3e1d838ec7da8dfe0b7fcc911e43159a79c73df5fa252b98790be511d8a732fcbf011aacc7d45d8027d50a347703d613ceda09f650c6104c9459537c8f 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c 8bd11f2b7b4fd937c136c22480ee3a63cbcbd26b77686895441349bc198f919b2c8738dce306e668dd9aa2a61414f6ec106d9176a1fc93665061267c6276c78279fbc77295aed51d045240bc48b65cabb29d05308a09c96808984eea8f3e6c68 +45db86829c363c80160659e3c5c7d7971abb1f6f0d495709bba908d7aa99c9df64b3408a51bd69aba8870e2aaff488ef138f3123cf94391d081f357e21906a4e2f311defe527c55e0231579957c51def507f835cceb466eb2593a509dcbee2f09e0dde6693b2bfe17697c9e86dd672f5797339cbe9ea8a7c6309b061eca7aef5 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f a37b4fe2bc0540dc18a92a09b90881eeea4c58df40fef9446c91725f9508d75e9df059b4e96d70bbb58c91d4842bf04618ae51659f3c18b3c5a3a131bc6487d5f9a0508b2fcbfd1fe646ca7a05e50e4194a4dd74883d1df6c70985b243b49c3c +4672fce0721d37c5be166bffa4b30d753bcf104b9b414db994b3ed33f36af4935ea59a0bb92db66448b3f57dad4fc67cef10ce141bf82c536be604b89a0bc0e8bca605b867880049d97142d30538fc543bd9d4fab7fdbe2f703815cdb6361beb66acff764bc275f910d1662445b07b92830db69a5994857f53657ed5ca282648 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7 a89d352b1daa8b31cdef4c921e0ae76c47835d17b34c56756f351cacf5c188c240a5ca333c328dc1db592c7900bb7e9401ca7d58bd18a69184ff2c8c73dfdd8feed68fd9e27d8f80822a51bde48de20e9ccb8474d9cb267af10239ac690c64c3 +9ae48fdd9bfc5cb0f4d4761e28b2073bda05a3e3fe82c212e66701dc4573cc67a829b0f82d7520b1bf11db0c6d1743822bbe41bb0adbd7222aa5fae70fbd1a31f2d4453a01c81e064d775388468be96f6063f8673b7b8d4455fe1bd4c801ad5e625a015eaa4a1a18da490d2af8642201eaba3c611cbd65f861d8e19ca82a1ee6 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf 8cf9de4b6bf004a1472c10cbd19c9bbcbe4684c18706ac63d9f46ece09261fc8a3485331e531c6fa815abcdc893e74cf16ff69d19a4ff9b0b73d290070e024cf5765569643f20a9d2ff68bdbb735b8ed64ea4cc24deadb36a97e74a2909f3c16 +817d6a110a8fd0ca7b4d565558f68b59a156744d4c5aac5c6610c95451793de2a756f774558c61d21818d3ebeeeb71d132da1c23a02f4b305eccc5cd46bd21dfc173a8a91098354f10ffbb21bf63d9f4c3feb231c736504549a78fd76d39f3ad35c36178f5c233742d2917d5611d2073124845f1e3615b2ef25199a7a547e882 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b 99ac0391860cec61d91c47c3292ee8fedd51dcd9b19cc5d9326f30899832338afe83678c88ff9e25c762df2b9b457a4704ef0b4cd9f785e33885198bb95a25efd2c8271edd11f3fc8626a7fab942f199a7db0aec1c28f4c0f9dde31c1038c94b +464f10ec6fb229a51db5fd0e122f2cb8a9a022117e2987f4007bf5565b2c16aba0714e2e3cdd0c100d55ac3017e36fc7501ad8309ab9572aa65424c9eb2e580a119c55777676ec498df53ef6ae78fd8a988130ee0e6082bf1ef71cd4c946021018a8ca7154d13b174c638912613b0bdb9001c302bf7e443ad2124ab2c1cce212 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69 8d5860c9ecb79a732278d144afbdf6aafba470741eeec73a68c9a8837bc098df426aa374330d1c5181b68567d4e0bff60ed316abb506d62d564ba0058742d8b3d783bd1deb7de7df8c9cf7913975ae550b6af5e7c0fef1163dc5c824f30a0089 +4e3e0fb96320ddccde8b463c273654c4f7164920b1d63430921d2e808dee403e6420eedda0a557b911d00736a4f8798dd4ef26673efd6d190988ad4929ec64f8685cfb76070a36cd6a3a4bf2f54fb08a349d44642b6f614043fef9b2813b63457c76537d23da7b37310334f7ba76edf1999dad86f72aa3446445a65952ac4e50 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db 88ae89467e8840d2425b2747d8ef1c7cfcf6ecbacb0b7885acccc12f16d8d1a81cb5695f4e04b8c6809e8eecdb3a8a8813edbc396368a74eced4ba0ec587536ed329703154d120d25361df6a159e2da8c7429cca860e54c710b120c4a60ecb69 +c466b6b6baf7e6ffa876ec06105e2d43534e0517c07b1c4c9fb67ba81ce09525a7721ec3c290f2b1f65b6463d41598e7a25b2238501629953a5ca955b644354fb6856733a2e5bb8f5bc21a0c803493f5539f9fb83aab3dba2c982989c2270c61ab244b68bfe1b948d00c2ed975e09c29b5f8a7effcad8652a148cc880d503217 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d 94304ef2b290067f19306cb564c68e2e8089c07ef017f8cc1876a894f9a70d866d755e8c66310b0fbd1144ea983f3ca41339e16f33c4bab78596c50421d454e2ff6fd80ed416ef072dfb6e2ffd72738dc13406b1f1da75116a491af932c01042 +feac892b7720af80b3c9eede51e923f18d3d0c5de4c31f4aa75e36df7c7c2fd8f41778851a24b69e67dccb65e159dd5c383243bad7cfedcc5e85c8a01c34b0b94ba8e07e4c024c09d279b3731e8b62f9562d3c4f5042567efe42a9d0eaaabab28bc6f11232fc8ceaaf4518d9f3b2bebf020294496b7f6b879e69503f75fecd3d 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476 aee3d93cd22aa006a407990653b67d6851c3f30b016e55a903ab5e16f5b9acf260b6c499a33ac5f194d40c1c7129080a0095733f687e74701167435805a81eaf6d19a410eab1a86ca347a48b807402888a1be79bbd0387db144c915bb4f21819 +cf2982e3bf174ce547741b969403cd11e9553067e6af8177d89511a0eb040db924530bdba65d8b1ff714228db0737c1756f509e1506014a10736e65be2f91980a73891496e90ff2714a3601c7565cdcef5a395e2e0e1652f138d90d61eaa9cba993b823245647f6e07cec9b8b4449cd68a29741cd1579c66e548ca0d0acf33aa ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa a45355124487a512fc1688985a26460f22a94cd11ebbfd4d7b110cd731de127702930b8721d616e4170ee61c6bf587b510cb263115d4a77039b8c5af170e117f2d63fffb94c7451dfc2ecc418133c3dff23cd44790c78c3c764f4d6af7c99203 +bf9fdd4107ef5a6070108771ac9eee4f0c8043bf0d04db772a47294f4137e2439d94b337114b074e57e0cb78d0ccf352a2833e9788ee2a1a9ffeacd34f38fcefb86653d70c7dadd4cf6548d608e70acdef6c7530974b92c813798add659752a8c72b05e1ad9c65c21834ce6fbe49d8a1426b5a54270794436d284364fac6ec1a 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f a6b45179292149a32e91effa7f0be193d542942bdab52b2fdc0da58dd88c59b686349e82b458ceed4a69308c25976e5405b659c4fd4d1377d60340a849518b668f4e07651f67c3698d343f15e18d498ce5f4fcc8e043baba0694eaa9a8d249a1 +5d634fb39a2239256107dc68db19751540b4badac9ecf2fce644724401d6d632b3ae3b2e6d05746b77ddc0c899878032248c263eda08d3d004d35952ad7a9cfe19343d14b37f9f632245e7b7b5fae3cb31c5231f82b9f1884f2de7578fbf156c430257031ba97bc6579843bc7f59fcb9a6449a4cd942dffa6adb929cf219f0ad e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1 86b73fac47f0acc17ee89d3e09020335dbec1544424f2da8e6f4b5ced7716f797714e3593a3f1fe76738fbdfda4ca170169c8929fa09f4f88ee3d3464459899fb3858d4790ab6115c561aad0cd04e7c096fa227d918456bf97c61453cd12d84d +c9b4ff721b3e886f0dc05856ffff0aabb64a8504b1746a47fdd73e6b7ebc068f06ac7ffa44c757e4de207fc3cbfaf0469d3ac6795d40630bcafe8c658627e4bc6b86fd6a2135afbc18ccc8e6d0e1e86016930ca92edc5aa3fbe2c57de136d0ea5f41642b6a5d0ddeb380f2454d76a16639d663687f2a2e29fb9304243900d26d 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c 814ce7ea79366cfe4d659fa6c57c858c0c2700e434ffd427f4226dca45eec77be50f5e0aabf524a96b2fd173ef2c6bf315f3bfc2128dc0c11dacc73154c41df56fe50b2d72200281434a4f63d50aa613e3914faec5def34da703c3778a205503 +db2ad659cf21bc9c1f7e6469c5f262b73261d49f7b1755fc137636e8ce0202f929dca4466c422284c10be8f351f36333ebc04b1888cba217c0fec872b2dfc3aa0d544e5e06a9518a8cfe3df5b20fbcb14a9bf218e3bf6a8e024530a17bab50906be34d9f9bba69af0b11d8ed426b9ec75c3bd1f2e5b8756e4a72ff846bc9e498 e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c 87ba955decf2c1bf7ef08839394dc7f56fcbaca2bc6565207e8eac30cf160c2b8c134555c2376f63609185cab5d66d8017cfc5a701a2ce12c2fa3be669468755803bfcd05f9d65f89f03f42707f51ab1aaa59cbfa74915ceadb126a7e21a6977 +dbd8ddc02771a5ff7359d5216536b2e524a2d0b6ff180fa29a41a8847b6f45f1b1d52344d32aea62a23ea3d8584deaaea38ee92d1314fdb4fbbecdad27ac810f02de0452332939f644aa9fe526d313cea81b9c3f6a8dbbeafc899d0cdaeb1dca05160a8a039662c4c845a3dbb07be2bc8c9150e344103e404411668c48aa7792 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855 906375da430a34ab8a59c858449c0e15ff83bb90254260128034f5c4630162cc81f38d8551ee65562107144b81c2d6be09cf044f64870deb67eecb286bfbe008bba4bd7fa942be500c698bb680d5b8b47a1e247ab71f6733862e5d3c2dff6205 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P521 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P521 new file mode 100644 index 000000000000..70aa31833a53 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P521 @@ -0,0 +1,60 @@ +58ec2b2ceb80207ff51b17688bd5850f9388ce0b4a4f7316f5af6f52cfc4dde4192b6dbd97b56f93d1e4073517ac6c6140429b5484e266d07127e28b8e613ddf65888cbd5242b2f0eee4d5754eb11f25dfa5c3f87c790de371856c882731a157083a00d8eae29a57884dbbfcd98922c12cf5d73066daabe3bf3f42cfbdb9d853 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46 aae1905d01f781077e4ecb8f9a127335f3170fac18d5027e9a37296642cc5377b4921b153f6ccbf647e6e91a901fc331162aae3f48e28e90fd25f2fed45d431c24c04fd5766cb3db5121b22b530d96fefff89b48b093d648443eb629a4ffa7e6 +2449a53e0581f1b56d1e463b1c1686d33b3491efe1f3cc0443ba05d65694597cc7a2595bda9cae939166eb03cec624a788c9bbab69a39fb6554649131a56b26295683d8ac1aea969040413df405325425146c1e3a138d2f4f772ae2ed917cc36465acd66150058622440d7e77b3ad621e1c43a3f277da88d850d608079d9b911 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73 a0b1caefea99cb8f220bfd2c0171c390d2974aba31b830c3a1f0ce57088d088594d35a319179808f042a0b504d4c903d108786172335e79a7cffea45e66d0720f9a285c684fc8287e0c917a9841ce083687386627c2e0473d771bac63c1a6f18 +7ba05797b5b67e1adfafb7fae20c0c0abe1543c94cee92d5021e1abc57720a6107999c70eacf3d4a79702cd4e6885fa1b7155398ac729d1ed6b45e51fe114c46caf444b20b406ad9cde6b9b2687aa645b46b51ab790b67047219e7290df1a797f35949aaf912a0a8556bb21018e7f70427c0fc018e461755378b981d0d9df3a9 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace a7927e66eaec68919204effcc199557c2e56025ac5c896ba18d4a593eeb4cfbe8509506eee28c5a61d76f969381f0e3816194e6d7a9cbd422f79309d2049944a2fe4217b07b45d1cc810c8de9a9875f9712e11fbc3f7fdd7e7ad2989b231bcb4 +716dabdb22a1c854ec60420249905a1d7ca68dd573efaff7542e76f0eae54a1828db69a39a1206cd05e10e681f24881b131e042ed9e19f5995c253840e937b809dfb8027fed71d541860f318691c13a2eb514daa5889410f256305f3b5b47cc16f7a7dad6359589b5f4568de4c4aae2357a8ea5e0ebaa5b89063eb3aa44eb952 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc b90b8a82bf6b620d615a4a915da8c7914322aaf5a1c2dbc529c0634760678287163bd70d35a93d0960484c0d1922c8800a19a8a6078929b3b84a010d8b6be5b97e27642fe0629268d459b4ef7783a749508ebe792079e67ef5523029266490ce +9cc9c2f131fe3ac7ea91ae6d832c7788cbbf34f68e839269c336ceef7bef6f20c0a62ea8cc340a333a3002145d07eba4cf4026a0c4b26b0217a0046701de92d573d7c87a386a1ea68dc80525b7dcc9be41b451ad9f3d16819e2a0a0b5a0c56736da3709e64761f97cae2399de2a4022dc4c3d73c7a1735c36dbde86c4bc5b6f7 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549 b92abf729a2dffdc792cd3df7a556a316dd108bd3c34127dee418945380765e4eeb63060a4a78ddc7cdc99697afda2050dc6db17d592a0eaa4f187584ff500a73f0881a3fd1d5ba9f8a7eac293792f5e9a13508b137f9fa96c7447bdca3d6f45 +14c69f8d660f7a6b37b13a6d9788eff16311b67598ab8368039ea1d9146e54f55a83b3d13d7ac9652135933c68fafd993a582253be0deea282d86046c2fb6fd3a7b2c80874ced28d8bed791bd4134c796bb7baf195bdd0dc6fa03fdb7f98755ca063fb1349e56fd0375cf94774df4203b34495404ebb86f1c7875b85174c574c 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4 91ec5cd72188020f7c1259be28358951e4f38a5e86de2b9cf94c0e39787993a4b6eb9ed772626f1eb166690ef477bf480b78f0cb5b3354906c9626eb4950f23dd89733f05344fa55a557af957175c79a8c6a023dc7c120616b6c34f9172bb5bb +8d8e75df200c177dbfe61be61567b82177ea5ec58e2781168d2277d2fd42668f01248ca3eb29ffa2689b12ae40f9c429532b6d2e1f15891322b825a0a072a1c68fa09e78cfdef3e95ed6fdf7233a43cb68236560d49a3278f0b3f47cb08f475bd9ab2f60755ea4a1767de9313b71a1b9ea87ef33f34682efbda263b0f8cc2f52 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16 a6007d610dbd06e77848d14d5028c3ce297b586c754090724688bd803addb42ecd4a3f2321dacaa4b3b2873ebbd705850df89d93b90b7589819448fea9177a5d8110d6169ce9753b1047a75e62cdaac2a5084fecced6031915c1b678be3ecd66 +10631c3d438870f311c905e569a58e56d20a2a560e857f0f9bac2bb7233ec40c79de145294da0937e6b5e5c34fff4e6270823e5c8553c07d4adf25f614845b2eac731c5773ebbd716ab45698d156d043859945de57473389954d223522fbafecf560b07ef9ba861bcc1df9a7a89cdd6debf4cd9bf2cf28c193393569ccbd0398 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37 b09bcca3ee2e7754b92fe833d6bb302b684aa5bc6bb5825fec41f3c2abdb6422aa6e1812318fc25efba5b9e53620ad070e303500a53eadc1813f7dfbc9bb8c770a10cad3864c813afe5b3ac74a767da311af3a6a267071f8a67410af448955cb +80aad6d696cbe654faa0d0a24d2f50d46e4f00a1b488ea1a98ed06c44d1d0c568beb4ab3674fc2b1d2d3da1053f28940e89ba1244899e8515cabdd66e99a77df31e90d93e37a8a240e803a998209988fc829e239150da058a300489e33bf3dcdaf7d06069e74569fee77f4e3875d0a713ccd2b7e9d7be62b34b6e375e84209ef 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256 992401dae24eff3cc330df51e6c6dc75ceb877a22fc1bed8fe0ad130be2510660af8fc85661249cd889271338a42f65a05ca5354bc99dad329c9d535f7afebacd496d1114fe18af7545d6a9c86cff6048ada44b27284028619914130cd1e9df5 +8a7792a2870d2dd341cd9c4a2a9ec2da753dcb0f692b70b64cef2e22071389c70b3b188dea5f409fb435cbd09082f59de6bc2ff9e65f91b7acc51e6e7f8e513148cb3c7c4664f227d5c704626b0fda447aa87b9d47cd99789b88628eb642ed250312de5ba6b25f3d5342a3cbb7ebd69b0044ee2b4c9ba5e3f5195afb6bea823d 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7 af5cddc91a23fc678f1fbe5b348fd3d990135953592908ace6329d5b2608b0ca8e747e56bb3fd4cea978da82e13a6d470c89ea12414c8a02dccdbdd11ebefc3c8034e1e2cfdeb8277da602ade73bf42dafc1870d46d92acc800cd8f31f720bab +f971bcd396efb8392207b5ca72ac62649b47732fba8feaa8e84f7fb36b3edb5d7b5333fbfa39a4f882cb42fe57cd1ace43d06aaad33d0603741a18bc261caa14f29ead389f7c20536d406e9d39c34079812ba26b39baedf5feb1ef1f79990496dd019c87e38c38c486ec1c251da2a8a9a57854b80fcd513285e8dee8c43a9890 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73 afa0596ffff9645085e6453819c888c2b0c4a502dd0408d8df128e3036133168cf16550649896fd5ddaa367ab186a04809fe3e6f08dbbc7db43b8048417e3361fa412fcf4e25375a25342f5ee62303ebdf398623389ebd61545cb5537e628638 +ec0d468447222506b4ead04ea1a17e2aa96eeb3e5f066367975dbaea426104f2111c45e206752896e5fa7594d74ed184493598783cb8079e0e915b638d5c317fa978d9011b44a76b28d752462adf305bde321431f7f34b017c9a35bae8786755a62e746480fa3524d398a6ff5fdc6cec54c07221cce61e46fd0a1af932fa8a33 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c 8bb083220cc93dee24f4f239a6abfb78085cfd4fa159ec08c8278a95ffb4d9b8f1527ac20b7f0958eb7a826fd13a154900feacb19338fc689c337327ef1c7e1cd65d69e858a782e3e04c1bf3a63c2cce35b6c9fe6f3a560e38c68b71a54d17c9 +d891da97d2b612fa6483ee7870e0f10fc12a89f9e33d636f587f72e0049f5888782ccde3ea737e2abca41492bac291e20de5b84157a43c5ea900aef761006a4471072ab6ae6d515ffe227695d3ff2341355b8398f72a723ae947f9618237c4b6642a36974860b452c0c6202688bc0814710cbbff4b8e0d1395e8671ae67ada01 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace 84739f941b9f5c5457174763b581224a55eb00449270c6f7dce9e3ba713af4dcf98e66929d1182af45db45bd487a50d508cc5bdce8b9272c10d7840357255a00350dc651cbd5521c825a25d5e531fd9e954bda176ad6c8311db185267c7a19af +924e4afc979d1fd1ec8ab17e02b69964a1f025882611d9ba57c772175926944e42c68422d15f9326285538a348f9301e593e02c35a9817b160c05e21003d202473db69df695191be22db05615561951867f8425f88c29ba8997a41a2f96b5cee791307369671543373ea91d5ed9d6a34794d33305db8975b061864e6b0fe775f 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8 a725cc83304e83896bf4ebaf7ca9f482f89a2138e978778a6fbedd9e40ace49dd54ceed6a9a6374740ab36f468d63763175284b64402ecfc4a07430edfbd16193877ad12599eb0758e22fdc920fafae50eef26a6a4156755521292eeb7a82aa3 +c64319c8aa1c1ae676630045ae488aedebca19d753704182c4bf3b306b75db98e9be438234233c2f14e3b97c2f55236950629885ac1e0bd015db0f912913ffb6f1361c4cc25c3cd434583b0f7a5a9e1a549aa523614268037973b65eb59c0c16a19a49bfaa13d507b29d5c7a146cd8da2917665100ac9de2d75fa48cb708ac79 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad 823b60519d06a71572c54dfdc741f51ebbf5ae65052b4c9e4dfd2f5e69c829b0e69c2c3a8f33ecb41d4eb3516808f7ca012bb88904b14385e32151172d9d3cc14ece5c94244e22447feb8a5aee2e4f9d712a7a65e53388c148a30524206f031d +8ab8176b16278db54f84328ae0b75ef8f0cd18afdf40c04ad0927ed0f6d9e47470396c8e87cde7a9be2ffbfe6c9658c88b7de4d582111119c433b2e4a504493f0a1166e3a3ea0d7b93358f4a297d63f65a5e752f94e2ee7f49ebcc742fa3eb03a617d00c574245b77a20033854d82964b2949e2247637239ab00baf4d170d97c 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a 8951a624283cd13e51542255f0fd9b538c8d70444bb435ad2bab5fff5666160254d4bcecb1dcfec441d81963aa74d28e06d13700d493560db902e1e510bd643e46641f14f2013c9f3d6e8ede16d7381987dfb66ba746712e1ef8b4649feecd5a +c4bc2cec829036469e55acdd277745034e4e3cc4fcd2f50ec8bd89055c19795a1e051ccf9aa178e12f9beab6a016a7257e391faa536eaa5c969396d4e1ade36795a82ebc709d9422de8497e5b68e7292538d4ccdc6dd66d27a3ece6a2844962b77db073df9489c9710585ba03d53fa430dbc6626dc03b61d53fc180b9af5dea6 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c 996469352f5b525278061e4419fb3dd435e3ecb0b6cd935c3957a4b041dcb7096fee4fc730e2698625dd0a8e6ad860950de4e7a8dac4c8bc9125c55749e20227168aacd2e8101dd05f938659634a5fd114d7df5493a06ea9e509284e9fe6f17b +1c1b641d0511a0625a4b33e7639d7a057e27f3a7f818e67f593286c8a4c827bb1f3e4f399027e57f18a45403a310c785b50e5a03517c72b45ef8c242a57b162debf2e80c1cf6c7b90237aede5f4ab1fcaf8187be3beb524c223cc0ceff24429eb181a5eea364a748c713214880d976c2cd497fd65ab3854ad0d6c2c1913d3a06 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d a925edb76032bf28a34ca31f6ef3e6f0712a34c2af804cfcf040bfde3057e3c48f5306bde9669b5e781d3bb6c8c6d73d18e0afe8ae517011028cbb2155e93b07fc7997b5170f1131b66d122f49929f58271eb54569918d01827ec22730df13ce +adb5f069b2b501a3ebb83d4f1808eb07710ac4a7b12532996855a20bcc54b2f76812915f632163c3654ff13d187d007152617cf859200194b59c5e81fc6cc9eb1ceb75d654050f260caa79c265254089270ccd02607fdcf3246119738c496dc3a4bd5d3be15789fc3d29a08d6d921febe2f40aef286d5d4330b07198c7f4588e 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c b7b215fdabeb23f23ae1bfc2c1617d3b7658dc1a0609e85f85f68b5fa963585b273b9582bdca320961e3f260748fea3608f93bfc4ac93e60bcc05a0d1657b2f15c5c96a9e83526538ec2d9cfdbf8df6e6ce1048f1246d01c6581ac6c0fccda1e +f253484d121d1ce8a88def6a3e9e78c47f4025ead6f73285bf90647102645b0c32d4d86742a50b8b7a42d5f6156a6faf588212b7dc72c3ffd13973bdba732b554d8bffc57d04f8167aef21ee941ee6ffb6cce0f49445bd707da8deb35dca650aaf761c3aa66a5ebccddd15aee21293f63061a7f4bfc3787c2cd62c806a1a9985 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25 8ed8de26637edd60953064061bbda5f30fa9ec095a54e211683d11110d89e4c02a3d1b3dfda80bedd618f0bdb7f001c805d6f5f37a15a9270744060bd99ec5ba8846f336e916e42d378cd936febcbdbcd6b8543a42daa02c01b175cc98f25517 +33bab1c369c495db1610965bc0b0546a216e8dd00cd0e602a605d40bc8812bbf1ffa67143f896c436b8f7cf0bed308054f1e1ff77f4d0a13c1e831efbd0e2fcfb3eadab9f755f070ba9aeaceb0a5110f2f8b0c1f7b1aa96a7f2d038a1b72e26400819b1f73d925ea4e34d6acaf59d0a461a34ce5d65c9c937a80e844e323a16d 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf 918b7546a943754dda1b354d2cc97ed013d2e7471a945e8d6ae35bf3d98112e1d949827b8e2c5eca9296b9c597a94c610141142424371b8add81370bd2754b78fb8d9a83dc783566171dc700c41e85a2145e746d6a81ae2bbf62f3f73623731c +08c8b7faaac8e1154042d162dca1df0f66e0001b3c5ecf49b6a4334ce4e8a754a1a8e4daf8ec09cf1e521c96547aed5172ef852e82c03cddd851a9f992183ac5199594f288dbcc53a9bb6128561ff3236a7b4b0dce8eaf7d45e64e782955ee1b690ce6a73ece47dc4409b690de6b7928cbe60c42fc6a5ddf1d729faf1cc3885e 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570 8c8e32c61397acf121d39a34b7f2595a421392418873861ce409503db59e3789fdc5c740f225e7e710f439c05f27e24f02c448a947db77826ecca18f8fd26912cd9dfa5676845cdeeb5a40168fa3d0aaf125674b3c7282d047f3360450fe9ee7 +ba74eed74282811631bd2069e862381e4e2a1e4e9a357b1c159a9ce69786f864b60fe90eeb32d8b72b099986fc594965a33285f7185b415df58fead7b8b50fc60d073680881d7435609ad1d22fd21e789b6730e232b0d2e888889fb82d6ad0337ab909308676164d4f47df44b21190eca8ba0f94995e60ad9bb02938461eee61 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6 9899ca19be215ccb8af8ab08800cad64f9b0a92941824693d10e138eb39eb7651277ae3b318c1fc2eea9cde173015ff706cd83539664a468ac06180363e4dcecb1a6ee5865d419c270cdc37967549657053dd74a157230a2bcc5986d31a34115 +dc71f171a28bdc30968c39f08f999b88dc04c550e261ecf1124d67f05edeae7e87fe9b8135a96fe2bc3996a4f47213d9d191184a76bd6310e1ee5cb67ea7fc3ef6f641a0ba165198040fa668192b75a4754fc02c224bd4a74aade5a8c814adf151c2bfeda65165a04ef359e39847c84e312afb66d4cd1db50d41ef3fe5f31296 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7 a62b7bd9a593a99fd00c328871036879aaffa1e3ced1c0458206dbe473dab2d83f52842103218bf5efd57d1ec64010f315fdc585bd6be948bcc4a24437316168b7ddb59070c80e90421a7f46d96c4935c1c52bcef76969aae9950ec56b3cd7c5 +b895788d7828aaeace4f6b61a072ffa344d8ea324962ba6dab5efda93f65bf64a0f2ac6d5721d03ee70e2aef21cdba69fd29040199160e3a293b772ffb961ed694a8dc82800dab79367a4809a864e4aff6bc837aaa868e952b771b76591c0bb82249034e3208e593d85973d3fea753a95b16e221b2561644535c0131fe834ae7 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e a860a909de1b25880c8f858b4231cf64fa1a928ee391884e5c6641c488b3b6e81e81c8d1fa53fa3cdf2685c19bbadf420091f057a16225752b1dfe781b51b0e1b7cf8645b8b1a1a107db2b41a204328494584c7f0950d3be79395a9340b45a17 +2c5bd848c476e34b427cfe5676692e588e1957957db7b5704492bd02104a38216535607f5d092dc40020130c04a3aaf0f1c52409834926d69a05d3f3188187a71d402a10ba34eac8629b4c6359b1095f30f710219298bf06b9f19bfc299981d7e251ca232a0a85338a7e02464731d1b25d4a1f68baf97064516590644820c998 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938 b4e1a6779be43b18a7594999118012b20a010297f017db77c44edb0284c9553e17bd0fea3dc23a2de7fa21fd2e987fbb13ff84326040a5cb63a09d950e90eebd09a143e1786a330c4699f202e910b2a2580d0965321623317791b66a4178da96 +65a0b97048067a0c9040acbb5d7f6e2e6ac462e1e0064a8ce5b5bbf8e57059e25a3ef8c80fc9037ae08f63e63f5bdb9378c322ad9b2daf839fad7a75b1027abb6f70f110247da7e971c7c52914e5a4f7761854432fa16b2a521e7bcaee2c735a87cad20c535bf6d04a87340c229bf9af8647eedca9e2dc0b5aa90f7fea3cdc0a 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662 a4199271ca556d85f8a49f31d72cfe1f88c37fc02ebd243d1a2eb651fbe8c7eddb27d79ec838b6257affbde7da8f22c916370449aa30271d4f5f8f2a1272d639805b3a2a68f2f921e2968408f46af4c0d77363acd00bc02b9ef37e180ad8830c +d6e366a87808eea5d39fe77cac4b8c754e865a796062e2ec89f72165cd41fe04c48148068c570e0d29afe9011e7e7a2461f4d9897d8c1fa14b4ff88cab40059d17ab724f4039244e97fcecb07f9ffeec2fb9d6b1896700fe374104a8c44af01a10e93b268d25367bf2bef488b8abcc1ef0e14c3e6e1621b2d58753f21e28b86f 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721 918c98a6059d73d1c0f1abc4c7d3c23465534053e141d4231d6e1613a4adb0eefb5f6d3b76a75670526ce76264ab6a0c18cedb26ec3c859459734c3d89ac8084bee1ca7a8bcdf949ee6bd6a111a0ff830a45e171a4273a71f7c4625301f4e115 +f99e1d272d0f5fb9c4f986e873d070ec638422bc04b47c715595e2cf1a701cdf88bc6c4b20085b357bad12ccba67cac8a5ca07f31ba432f9154ff1fadefd487a83a9c37e49fb70a2f170e58889cab0552e0a3806ccfa2a60d96e346851d84b7de6d1a4b8cf37567dc161a84f13421e3412457d4bc27f6213453c8519a2d7daa2 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e 99973507c0eb750d475c53802d218576997b810187adb347eefad4b6d27ea8b4e0e258bfdf9413d734a785cfe0d4776511db82c3353f3b27218bf8c9f5f2b911165336134357f8133753b5de61ea35a3fb5648ee39f78effc6da089a8db6ba20 +91f1ca8ce6681f4e1f117b918ae787a888798a9df3afc9d0e922f51cdd6e7f7e55da996f7e3615f1d41e4292479859a44fa18a5a006662610f1aaa2884f843c2e73d441753e0ead51dffc366250616c706f07128940dd6312ff3eda6f0e2b4e441b3d74c592b97d9cd910f979d7f39767b379e7f36a7519f2a4a251ef5e8aae1 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418 919a563ab8da4cce4166ddaa5332c2ba841deba71125bfcd39bc5d8e4d0b7d473665e65d327dfaec73d501a6c73e186e0414f1cef4b4f309cc809a6c0d0e8978fbc88569b6a38e41364a62cb626b684625f4d51c5d02e185f0cfb48aeb6ceb87 +dbc094402c5b559d53168c6f0c550d827499c6fb2186ae2db15b89b4e6f46220386d6f01bebde91b6ceb3ec7b4696e2cbfd14894dd0b7d656d23396ce920044f9ca514bf115cf98ecaa55b950a9e49365c2f3a05be5020e93db92c37437513044973e792af814d0ffad2c8ecc89ae4b35ccb19318f0b988a7d33ec5a4fe85dfe 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950 a071aff26dacb31c91bee1a4c29873df687efc124ac3bee5180ffb2e304fe1ae1e98325172a5a9fd15fdd830703b9c2a13bb617520600cd66a059d92b51990f0f44e481ea292b7e2d270733ea67c8d84777b1daced13cc3fee3a7721de95cc8f +114187efd1f6d6c46473fed0c1922987c79be2144439c6f61183caf2045bfb419f8cddc82267d14540624975f27232117729ccfeacccc7ecd5b71473c69d128152931865a60e6a104b67afe5ed443bdbcdc45372f1a85012bbc4614d4c0c534aacd9ab78664dda9b1f1e255878e8ac59e23c56a686f567e4b15c66f0e7c0931e 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b a5250394821d010f6a4d31ecceb8c91551c885aeb55d9432ec4611e757df5428daabd1c02a3eae1f631b16d7b3ff82450480816dd7c8239f79e517c494c98ce835caec628c9c3fafd85c0589a75724f889b811e923ebeaba3b03bef1a26cd626 +6744b69fc2420fe00f2352399bd58719e4ecdd6d602e2c80f194d607e58b27a0854745bfd6d504de2eb30b04cee0f44af710dd77e2f816ac3ac5692fad2d1d417893bb0edba2707a4c146a486f8728ca696d35cc52e9c7187c82d4bdb92eb954794e5ad15133f6bfea1f025da32ada710a3014cf11095b3ff69a94d087f17753 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f ae9f7bd71fabaca7e0f8c9ae609bd15115f63bd0783c61a30adba0de8ef1a877931958492071a1e07edf95294eedc5570bafef15da3509840d11740a4b21a50adc7dd66720dc463ba7e129f78a470e5ec661375449b326fc86fcada9bc66f4da +16001f4dcf9e76aa134b12b867f252735144e523e40fba9b4811b07448a24ef4ccf3e81fe9d7f8097ae1d216a51b6eefc83880885e5b14a5eeee025c4232319c4b8bce26807d1b386ad6a964deb3bdca30ee196cfdd717facfad5c77d9b1d05fdd96875e9675e85029ecbf4f94c524624746b7c42870c14a9a1454acf3354474 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66 ad979b03f6d494e204280f3cdc695e55dd1649a7e2efcbe3531a8bd606734eaa30e549da363add690cbdb4a72b601d7e0481013a5cd55ed9ae5b4e6206d6b290d376ab777e03fe8e11ce5128daeea400bfce67ce255c889984cef5ccfb1f0825 +a9824a7b810aa16690083a00d422842971baf400c3563baa789c5653fc13416111c0236c67c68e95a13cec0df50324dcc9ae780ce4232607cb57dd9b2c61b382f0fa51fd4e283e2c55ffe272597651659fbd88cd03bfa9652cd54b01a7034c83a602709879e1325c77969bebfd93932ce09a23eae607374602201614ff84b141 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c ab3d69909505ba3203d7c6c35838a0f665ff7dcc1f86ef63166594d8fed0f831a7aa004dd6dcf8eca383369b7f24495c1247bfd5d81486637022b8cbf91f5b4e4071a55db9191b64903104ae450081241456070a424319022d59fa274a366062 +90d8bbf714fd2120d2144022bf29520842d9fbd2dc8bb734b3e892ba0285c6a342d6e1e37cc11a62083566e45b039cc65506d20a7d8b51d763d25f0d9eaf3d38601af612c5798a8a2c712d968592b6ed689b88bbab95259ad34da26af9dda80f2f8a02960370bdb7e7595c0a4fffb465d7ad0c4665b5ec0e7d50c6a8238c7f53 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0 87555a9338c349beff820d392c39be11069b5dce854951f85283f59dbab25be79d4901ac9577d5cf59f408960c002bea0efe0dbfa9f61cbda68d4e3c6da9a56f8299ab7bc07506017c25b898d17fe973d39ee2c01853afea7795502bc601aeda +09952b1e09995e95bf0022e911c6ab1a463b0a1fdd0eec69117b34af1103c720b57600217de7cd178fef92de5391e550af72a8dcf7badf25b06dd039417f9a7d0f5be88fcd4e9655931d5b605452a667c9d1bae91d3476e7d51cff4108f116a49966fb3a7cff8df1c09734ce5620faf2dccb3dc5d94e7e9ac812da31f6d07a38 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9 a5f69e852a8857ac87ab5715aa78dcb687ccda3e266abc4feedf598e074e02393c6a1c63cac9a23ad2fc03f1ffa0750202558c909aeaa02597ccb789af5dc93169e3b4870cd0ca1bd9180ed49317ba33b8770d52f1ae5691e7bc7e75655e5293 +0bb0f80cff309c65ff7729c59c517d50fc0ed5be405ef70cb910c3f62c328c90853d4473530b654dda6156e149bc2222a8a7f9be665240e2fbe9d03f78a2356af0bacd1edb84c4801adc8293a8a0bd6123d1cf6ba216aca807a7eb4dca76b493eb6e3dbb69d36f0f00f856222f24d9b93ec34c3b261be2fca0451c00571928e5 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d b7ec7185eca8a7aa4da3e43ddf2e753b83dd426827cf3cb1e75514fb1f19c5fb5d1869f53c0a0d628a85e142fabc8e660c1cdd61196e30f18e2c930f5361ced7107512c35ae6f4abe96a4d87a7fe2f8898632cd6e7c2c5530382e302b43b9897 +7efacf213382ce30804e78b7256854d759147dba9729c51b2759465715bf2c421034c23dc651c13d6cce95f71fe6a84dfbee5768163ac5789ac0474c5ddf4115684683c5f7c204b33b8bcc0c03ac58f66cef2f53b721fe2fac91ad841126101a88f512a7c2ded38549d9f050d4b7961dda48a1489f026c5d111701762418cfe3 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490 a4682e48ef733606697cccf24f7be15fe7177f46c6785e357f828aff19c2ce4b22686a18847d0ada2f1598df262cbe5b195dc030326505bae383e9e50390407db4271b0fe7dac15b7ce95037662e7c97e48564ff939950dd6eda9181df37a0b1 +28edff8b9d85f5f58499cc11f492abdfab25e8945975bbaeee910afa2b8fc1295ec61406309ce4e09f4ab4f462959fc2a2786802466eb26d3b01be6919893ae75d0fdc2dc8a82e662550f9fce9627dd364188aaba5c6faa1b2d8a2235adfa5ad0dc140f88a2b2f103f5690e877d07fe8fd30d02d2b2729bd3d8eb5b23a21f54c 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1 89e48d7021571e24d495deb822e2fe2ee930057b5d99e18cbc5787335f2f9d88ba8fa5287466e8c3b592eda7500844b90be78a75c47d0c8ad554f8c7a598cfae388361ffa3b4bc633413f1df193f9b1ab3351671642c3ff016340bb24430a918 +bae2a8897c742fd99fbf813351cd009d3f2e18d825ca22e115276484bce8f82f8c7c0c21dd2af208404d8ef45bb5a6c41693912b630897d5246801bf0775aa9bbac8be98cb861d172c3563dc59e78a58ed13c66dea496471b3ad0eeae8995293e4ab97373edc1837ffc95ff1cc0c1e90e64ea8680b2ca5f1e09bf86b99b343b6 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745 9511663f9d071cd3d3b0b9963dcad606efdd27904457d38321811ef73cc0bbd024128024180fa81d1bdd943ab1044def0d69dadac4e7d0546da0b3b13ea7f3010800573d0578f7c8de881c7982559c46385b3fa08c083d44dfa251629abb0936 +d57a26a9593e72bfc87322524639bcaae5f2252d18b99cdaa03b14445b0b8a4dd53928f66a2e4f202fb25b19cad0eb2f1bfda2ab9b0eb668cdcd0fe72f5d9ef2e45e0218590f7ab9d2c9342202610c698bc786cce108a7d4a6730a13e9ea1b470e781f1237d3f84f44abde808516975546bd89075ef9a9732bfd7ee33b6f4399 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f afe1a6eb83ecd23960f78b115e210069b1780b04a8d54a701aa94a5bc1d3b570680f71a0f33135044d7015157649f775050487d8ac880b5fa5eafd911b0eeb37eea989d4a078f442f90677ebba5ab3f8232128abb865c8a48c27900fd3aa97a0 +8fdcf5084b12cfc043dd3416b46274e021bbed95d341d3c500c102a5609d3a34de29f8fa9f0adb611a1f47a97ad981f8129d718fc0d6c709eab1a3490db8d550f34eb905b9e00663543afc5bc155e368e0bc919a8b8c9fa42093603537a5614927efa6be819ed42ececbf1a80a61e6e0a7f9b5bc43b9238e62d5df0571fea152 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e b6917de291d5fcf128b69bc0166f50d6dafa8887b14e4a46ee192dfeb4630397acdc64352a4424517794ead436369c0910f550a75566da21ad6315754b1731a5806099c705142a1da145c87a7e8a8b21ea8ccb2cf7fab98aa1719cc01fbfd56e +00669f433934992257bed55861df679804107d7fa491672574a7624949c60049b0533383c88d6896c8de860704c3e6a6aefce83efa57c4d57e9ab253da5d15e1f53ab6dce218b592772ab0bc01fee8e63368e85c0639301456fe2d44cd5396a7f2b22761cd03b80eba7883eede8249a2f5db2183bf00550c5c002f45a5e4fb31 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89 90afb68b6bb07d279ea6b0708368e77ea6eaff4b86a97e6cd71f39eb37107a417881b568454889aa080d38b1c8dc542712f6d92b6047235c0a4b1526e989d74ddbd9390a207f9b8fd88db35deef0c83a59ab5ff0fdcc2801fe9e38414b64af95 +4be81dcfab39a64d6f00c0d7fff94dabdf3473dc49f0e12900df328d6584b854fbaebaf3194c433e9e21743342e2dd056b445c8aa7d30a38504b366a8fa889dc8ecec35b3130070787e7bf0f22fab5bea54a07d3a75368605397ba74dbf2923ef20c37a0d9c64caebcc93157456b57b98d4becb13fecb7cc7f3740a6057af287 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a a71feb7daf6adde6f81f2f162a20477c7087a42d6ebdf75483251395fb0a09154c747c3a262df09af9ec2195a9cb71e4017399205a72a0e0425a7029406052ba8b1746388d9b37004b7bb2f9c4a79c92105eefb7cca688d6811dfd6f9db9f928 +9ecd500c60e701404922e58ab20cc002651fdee7cbc9336adda33e4c1088fab1964ecb7904dc6856865d6c8e15041ccf2d5ac302e99d346ff2f686531d25521678d4fd3f76bbf2c893d246cb4d7693792fe18172108146853103a51f824acc621cb7311d2463c3361ea707254f2b052bc22cb8012873dcbb95bf1a5cc53ab89f 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926 96d01e3b0afbd24532e45bcf9c2b80eb6f99a2acfca35d90b50e24fa9e72e575c41c369b2dc8b61d64365b13da30daa20b8cfded025685a190fd8efdb6fb1b670a7d9459f786cce8e2b106f349f7dfc07c147612169559488de9c15f7da16ac7 +b3c63e5f5a21c4bfe3dbc644354d9a949186d6a9e1dd873828782aa6a0f1df2f64114a430b1c13fe8a2e09099e1ed05ef70de698161039ded73bcb50b312673bb073f8a792ac140a78a8b7f3586dffb1fc8be4f54516d57418ccc9945025ce3acf1eb84f69ceee5e9bd10c18c251dbc481562cd3aae54b54ab618cb1eeda33cf 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6 9173bb0c75d4988d97c761461addaefa78c7367bd6f33ed668c1e1c3341b4b816d0c8f05dc0e5a805ef23d5ea95a350c121d9b98bea208d26b85f53cf2f19af185c8ebe9a6b4a1fcc56e57d27c1749cafc6829c47cffeb000741781367deee17 +6e0f96d56505ffd2d005d5677dbf926345f0ff0a5da456bbcbcfdc2d33c8d878b0bc8511401c73168d161c23a88b04d7a9629a7a6fbcff241071b0d212248fcc2c94fa5c086909adb8f4b9772b4293b4acf5215ea2fc72f8cec57b5a13792d7859b6d40348fc3ba3f5e7062a19075a9edb713ddcd391aefc90f46bbd81e2557b 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f 98ca711673851b01984953a30c1c6de4c1fe8c5d7b3c8e43a23ec0557de3b5563d41f3288445a11c371bd8ca727a4be60dfedeb95c8e6863eca7e6596db673997efabe618a82fbad311fd3fdd7e808309c378952d1f358f79881575417a9f403 +3f12ab17af3c3680aad22196337cedb0a9dba22387a7c555b46e84176a6f8418004552386ada4deec59fdabb0d25e1c6668a96f100b352f8dabd24b2262bd2a3d0f825602d54150bdc4bcbd5b8e0ca52bc8d2c70ff2af9b03e20730d6bd9ec1d091a3e5c877259bcff4fd2c17a12bfc4b08117ec39fe4762be128d0883a37e9d 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742 95df3ff88cce664647af42630cee9291c5ed23a615efd77c19f9c7c9a9eaea9ef736f43d6b283e91a42c92b9a145bf4611c61265409b85cb6f59c62028c734c6b33e357218bfcb7086be43ccaab2ae7757ae6bd8465a048454ffc7d3b89c9aff +a1eed24b3b7c33296c2491d6ee092ec6124f85cf566bb5bc35bffb5c734e34547242e57593e962fb76aee9e800eed2d702cc301499060b76406b347f3d1c86456978950737703c8159001e6778f69c734a56e5ce5938bd0e0de0877d55adeee48b0d8dfa4ac65fd2d3ce3e12878bac5c7014f9284d161b2a3e7d5c88569a45f6 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697 b6fa4d42a5c93244f8a6b582d648e80ca87adc53b07fddd76ac2d736167ad4899981a390a69c67efc20ba7b5872a9b320cec05796fa05cedeafb0b478a261b5313faf23a9f127dc92d2f2455d60f85af4078697cf0ff7e8a0d08f03fd3e1bfd5 +9aace26837695e6596007a54e4bccdd5ffb16dc6844140e2eeeb584b15acb2bbffd203c74440b6ee8db676fd200b4186a8c3e957c19e74d4d865ada83f80655323dfa3570907ed3ce853b6e8cc375ed2d758a2f5ad265dd3b47650517a49b3d02df9e0c60c21576378c2b3a08481eec129b2a75608e13e6420127a3a63c8a3f1 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04 90ab7426ddd9a3dd05f55dcca88ee5d2dfce9b68bb19ad5da355ad9846a021dfc9209797da9f1cc4a08ba0cd9c10b64e19b7af2073f356df10345629b96396fb882f97f886de4b00aabf7f945a3f495da10dd3aa68a1996116fc4da26c459fe1 +ac2175940545d4fbab6e2e651c6830aba562e0c11c919e797c43eff9f187a68a9e5a128e3e2a330b955a3f4577d3f826529ad1b03d7b60f7ad678f005053b41dc0f8d267f3685c6abe1a0e9a733c44b2f3ca48b90806f935141c842e3a6c06a58f5343d75e3585971a734f4ae1074ce5b54f74bd9342f4bbca738d260393f43e 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6 9225352575eff1409fee43c467e070ea5ac794aabcf3a08f7d8b1d0026d10f33a08edbf609e80aa3ee079de54f31e59005db199784c1aa460d777ef7840d47b53a1ac7a597cd8e3977a21c5a431288935c752ba62fc61c68aebc93f675eeefe1 +6266f09710e2434cb3da3b15396556765db2ddcd221dce257eab7399c7c490135925112932716af1434053b8b9fe340563e57a0b9776f9ac92cbb5fba18b05c0a2fafbed7240b3f93cd1780c980ff5fe92610e36c0177cabe82367c84cee9020cf26c1d74ae3eb9b9b512cb8b3cb3d81b17cf20dc76591b2b394ef1c62ac12ee 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e 831a212acb64e45e9df8c1bdbed007b1ebf08c3834192852fe2f787f8b80b185bf347e0b1be54778fc098e864a165eb00d017791f8023bc76845bf22a58f414485388258640951068acfa7be708c15a06bc9d50a3387a2524d6eb710079556b5 +3de9e617a6868dca1a1432d503f923535da3f9b34426b2a4822174399c73b1c1ee67311410a58c17202ac767844b2024d8aa21a205707d93865693ac25a24fc87034fa3a7a7e27c3344cb03b87602c15180a5fe6a9dd90cd11af4a0f150207bf2d83f55b12c088adae99aa8cfa659311b3a25beb99056643760d6a282126b9b2 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5 a51b8691820747aa3a113dd6a15829bb00b17fd4c57d4641c00551b3e581c9a148730da2fb82c728924019491e064935155d107a6d986f44c99bf11385965e038fdeaeacdf529f88c5c109399edc65e68f3933d7bcd9222d87f03e2d871c9a3d +aa48851af7ef17abe233163b7185130f4646203c205e22bcc2a5a3697bcab998c73a9ffe1d3ea0b7978ce7df937a72586eb5ca60b0d939a7d1c115c820171c89c8116b7e2c7b98cf0f14e4c4df3cb2f319ad3ab0ea25ff14526ddc037469f000bf82100acd4cdf94feb4eba4ea1726f0569336604a473aee67d71afebb569209 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a 9913f8844754fa022a375f9176cdfa8a3b3c2e4e994c7dbcada5b02044bdd800c501478502bd8467f1b7db30400171a60c2cf1c27492c2eb8c1fc19ed95d857dcef74a8638688681654f148eb66a584e2acbc081f6835c6db4d4ad1c5ba64eb1 +b0d5d52259af364eb2d1a5027e5f7d0afe4b999cc5dd2268cfe76f51d2f17b541bdd7867e23a1bb897705153d9432a24012108979c6a2c9e2567c9531d012f9e4be764419491a52eae2e127430b0ab58cb8e216515a821b3db206447c235bf44ee304201b483b2a88844abaa18bca0147dfff7e502397dd62e15524f67eb2df2 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb 8e6b55b281050667f86ffc9581da595382dcdd96ba4beaeced80259ef36b9c3a12d859fb67784c73ea8d32156bb5c6901300c193d7ae5bb36d986413c523cf916f0c0f8a1c9b29cb763d542921e113332d6daf2fa010ad6caf02dd8dc57d486c +9599788344976779383a7a0812a096943a1f771ee484d586af1a06207478e4c0be9c200d42460fe837e24b266c8852d80d3c53cc52ffb1913fc3261145fc6da575611efd16c026059a2e64f802517ffd1b6b34de10ad2909c65c2155e8d939b8115400c1d793d23955b15f5d1c13c962ff92b4a815cee0e10f8e14e1f6e6cd38 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77 b8eb05bd62e6e18fe3b3347088cf2a57950aa598258d6b0788a2e8a8a1b93bf2c6280c6d1328115490d22b93bf0d8b4405519e87652eddd8285abb33aaff524c0befd949ec5dc0ebf4721f61e115317ef1da10dd21ca93604681248b6af2d765 +fdde51acfd04eb0ad892ce9d6c0f90eb91ce765cbe3ce9d3f2defe8f691324d26b968b8b90e77706b068585f2a3ee7bf3e910528f7403c5af745a6f9d7ba6c53abd885c3b1be583415b128f4d3f224daf8563476bd9aa61e9c8518c144335f8f879c03696bddbe3ac37a8fbede29861611feaa87e325e2f60278b4893ed57fb0 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c b5e86efa616ce01778c95b433396b503ce6ef44a952ae4cbd2b9d1b24c42fca93945479a8e451c5cd4aba5098e934ac4079bedae8af11a638176fcbf35c42bce036b5e66cdf15cd8522992c078bd0cddd00a0f88e558864bd79289601e58eff3 +beb34c997f905c77451ac392f7957a0ab8b23325bd5c63ca31c109ac8f655a1e3094240cb8a99284f8091de2ab9a7db2504d16251980b86be89ec3a3f41162698bab51848880633e0b71a38f8896335853d8e836a2454ecab2acdcc052c8f659be1d703b13ae1b090334ac50ab0137ddb5e8b924c0e3d2e5789daaef2fdd4a1e 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63 aab46a0530b9786f68f16020a0bac7e8ec4c52845c3203eab44895e2f18f9c97db152f1748b1d10d006d27b9e0266b87032d4ec608648ac6e7360d43f8b0f43514901607f69ae12816400f95bba52bd00443caebc26767dd1471c3628190c3a1 +543c374af90c34f50ee195006d5f9d8dd986d09ad182fcbefa085567275eee1e742bfe0af3d058675adeb5b9f87f248b00a9fbd2aa779129123a5b983f2f26fc3caf2ea34277550c22fe8c814c739b46972d50232993cddd63a3c99e20f5c5067d9b57e2d5db94317a5a16b5c12b5c4cafbc79cbc2f9940f074bbc7d0dc71e90 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da b3146c12c2c96c6158d6c5d6b4d6204ec671f60a544c1890e9141fbdef1ef24cd0acf082b368c6ee02566af9e29017d80bbcf5e18f4e4aa7a147350f86f9f9df7288948261fee022e12392b2c15933bc27519b5ebeea9d85db2285d58ea083e4 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P521_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P521_blst new file mode 100644 index 000000000000..9be1fc053b69 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_fips_186_3_P521_blst @@ -0,0 +1,60 @@ +58ec2b2ceb80207ff51b17688bd5850f9388ce0b4a4f7316f5af6f52cfc4dde4192b6dbd97b56f93d1e4073517ac6c6140429b5484e266d07127e28b8e613ddf65888cbd5242b2f0eee4d5754eb11f25dfa5c3f87c790de371856c882731a157083a00d8eae29a57884dbbfcd98922c12cf5d73066daabe3bf3f42cfbdb9d853 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46 a321e0ea5919a07608ed8687692488be23a4c73cb833857b8ef72d597ebda1659b740202aaf81b344b12c0db469b2b0102c9b058bd5c82f2e3824f95f6ca3d5071a37f35c6c8600418751bd86a701f2bcbb83a66820448cfb3d8fb8abc9c459a +2449a53e0581f1b56d1e463b1c1686d33b3491efe1f3cc0443ba05d65694597cc7a2595bda9cae939166eb03cec624a788c9bbab69a39fb6554649131a56b26295683d8ac1aea969040413df405325425146c1e3a138d2f4f772ae2ed917cc36465acd66150058622440d7e77b3ad621e1c43a3f277da88d850d608079d9b911 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73 8bd613c557516a89b4573d0667a55f27e1d8c55832f4c3419040fed9c9a915e6f4e36a5484c5c40955cb4f379005e7b5189fa967461e3471ab595ce02ce0165fe528eff4b50a966740480867234bb50000541d3fcbb30eb0b9b71f1f56d87317 +7ba05797b5b67e1adfafb7fae20c0c0abe1543c94cee92d5021e1abc57720a6107999c70eacf3d4a79702cd4e6885fa1b7155398ac729d1ed6b45e51fe114c46caf444b20b406ad9cde6b9b2687aa645b46b51ab790b67047219e7290df1a797f35949aaf912a0a8556bb21018e7f70427c0fc018e461755378b981d0d9df3a9 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace a95cc3b7f074cb90f055f7539429c1ee1079c6705fc55af75cf8be1381a06f3e7d98b9771265a25494d725c068ce3bf50e5f01afefe40e5826313f0e0ea57d2c1cb20d9fbde0e75be752476a06544b567f8c0a5617afbca0c7caf00e4d267d78 +716dabdb22a1c854ec60420249905a1d7ca68dd573efaff7542e76f0eae54a1828db69a39a1206cd05e10e681f24881b131e042ed9e19f5995c253840e937b809dfb8027fed71d541860f318691c13a2eb514daa5889410f256305f3b5b47cc16f7a7dad6359589b5f4568de4c4aae2357a8ea5e0ebaa5b89063eb3aa44eb952 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc abb8b8d2f3d2e36b82ff3f101770c987d0b5aef2c9ba384e83b70eabc7e50e85883a5395e858cf0fb20a73d3b08da48105abcba441249a90a11674a755e23dcabc3c44bf01b9bb9c21285e5a2d0938b96d52e231d88a0bb5cc96847c9f912714 +9cc9c2f131fe3ac7ea91ae6d832c7788cbbf34f68e839269c336ceef7bef6f20c0a62ea8cc340a333a3002145d07eba4cf4026a0c4b26b0217a0046701de92d573d7c87a386a1ea68dc80525b7dcc9be41b451ad9f3d16819e2a0a0b5a0c56736da3709e64761f97cae2399de2a4022dc4c3d73c7a1735c36dbde86c4bc5b6f7 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549 8052ba320d828c8a8dbbc16c8dcf250a2c3d6c61cba593862519258675bb2b1a3445479ca59836700fa9def71a8b91291981c89b0bb028b1bb38599565a0c1880a75be459378e757c0cf5a98496a75883a9a0da7283fa8fd1b8cdb8db407225f +14c69f8d660f7a6b37b13a6d9788eff16311b67598ab8368039ea1d9146e54f55a83b3d13d7ac9652135933c68fafd993a582253be0deea282d86046c2fb6fd3a7b2c80874ced28d8bed791bd4134c796bb7baf195bdd0dc6fa03fdb7f98755ca063fb1349e56fd0375cf94774df4203b34495404ebb86f1c7875b85174c574c 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4 9845712b41cea8818f203edc35d667cd62efcea2840e27e7c8b000e042f046204e90428b975740843e3be8cb091cc0730d0c649cf54a6b3d7c9d641125e0fee33af6089136e11e1a60aeda2f7cb69324a8102b60c2b0fbc005d7cbef23a9b69a +8d8e75df200c177dbfe61be61567b82177ea5ec58e2781168d2277d2fd42668f01248ca3eb29ffa2689b12ae40f9c429532b6d2e1f15891322b825a0a072a1c68fa09e78cfdef3e95ed6fdf7233a43cb68236560d49a3278f0b3f47cb08f475bd9ab2f60755ea4a1767de9313b71a1b9ea87ef33f34682efbda263b0f8cc2f52 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16 8d426a52cfc40775db0189766384632e75960d7c4c98b3d938c6d7919f15489125c8b3777a182d188bc41d81d18265e50fb9bb05a8df2b956183abe32055cefecf6eaafd8e4143c29bacf37b8c632352ce56d589d6c37f84516b40092ed20cf9 +10631c3d438870f311c905e569a58e56d20a2a560e857f0f9bac2bb7233ec40c79de145294da0937e6b5e5c34fff4e6270823e5c8553c07d4adf25f614845b2eac731c5773ebbd716ab45698d156d043859945de57473389954d223522fbafecf560b07ef9ba861bcc1df9a7a89cdd6debf4cd9bf2cf28c193393569ccbd0398 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37 99cec645516bb673ad12b5c252437895bf4db6c7ad557d560a095437663300929030294055d89e4f93ca7621a39743de0aad82fd899cca19d95b86295e6356763fd49036195b422de57d9b8ba52b2afe26d58ada5d6e84b216696f6f76f2466c +80aad6d696cbe654faa0d0a24d2f50d46e4f00a1b488ea1a98ed06c44d1d0c568beb4ab3674fc2b1d2d3da1053f28940e89ba1244899e8515cabdd66e99a77df31e90d93e37a8a240e803a998209988fc829e239150da058a300489e33bf3dcdaf7d06069e74569fee77f4e3875d0a713ccd2b7e9d7be62b34b6e375e84209ef 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256 ab3ebbe654893ba6c4adafa12de8bbdea2f89b0d44dbacd51ddc2ed1998a928cdf7280111dc3c1376f479808e64f88d703334de780197f7e8bc11820b509bd18de644e54f162cab6e41c2ced6fd24217d0c232045b22348639f637b245ce6825 +8a7792a2870d2dd341cd9c4a2a9ec2da753dcb0f692b70b64cef2e22071389c70b3b188dea5f409fb435cbd09082f59de6bc2ff9e65f91b7acc51e6e7f8e513148cb3c7c4664f227d5c704626b0fda447aa87b9d47cd99789b88628eb642ed250312de5ba6b25f3d5342a3cbb7ebd69b0044ee2b4c9ba5e3f5195afb6bea823d 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7 b755331449574071a749b4f6e4154ca9f417dc6496b38e25acf7d79f8262d4a0265bb7986206159b21cf042461adfb0e0ce5425736794c5b3a9f87c854d97a1828c0a91d164087466f9ddde05f13d429682544689d9f77b9098c294aa16d96f6 +f971bcd396efb8392207b5ca72ac62649b47732fba8feaa8e84f7fb36b3edb5d7b5333fbfa39a4f882cb42fe57cd1ace43d06aaad33d0603741a18bc261caa14f29ead389f7c20536d406e9d39c34079812ba26b39baedf5feb1ef1f79990496dd019c87e38c38c486ec1c251da2a8a9a57854b80fcd513285e8dee8c43a9890 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73 9826d07f87aaf656444544244f8bd646ff14c10bb4296f0060ae6410811546080610f889bebaafa2ff76a0e71b959dbd17d2a44534ab2008fe4bba5a049e1b5be1e54fc0083331102bdb767a92518a1bcd5cb1c65c4b6215b20d9fdb72c73a71 +ec0d468447222506b4ead04ea1a17e2aa96eeb3e5f066367975dbaea426104f2111c45e206752896e5fa7594d74ed184493598783cb8079e0e915b638d5c317fa978d9011b44a76b28d752462adf305bde321431f7f34b017c9a35bae8786755a62e746480fa3524d398a6ff5fdc6cec54c07221cce61e46fd0a1af932fa8a33 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c a212a606219dfdea4e8374b8a42ed91bf7c2d6ad1ffcb09dea6544b8adeac09a2dc9455e3870e0aeba48d61bc355d27710760377a48da0912d1ec7522d51232e7bf2dd8a46c218b4bc5bf057ddd3a1a64df79538edf0bd02fa3608d908d4c22e +d891da97d2b612fa6483ee7870e0f10fc12a89f9e33d636f587f72e0049f5888782ccde3ea737e2abca41492bac291e20de5b84157a43c5ea900aef761006a4471072ab6ae6d515ffe227695d3ff2341355b8398f72a723ae947f9618237c4b6642a36974860b452c0c6202688bc0814710cbbff4b8e0d1395e8671ae67ada01 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace 88d6b424ad7da347ada0daaf4f908387e4ca913abf7beb5cbf6ad27b823099cdd9e8ff30cae59083a875a357781d13f709f3997a7b82438a3fd4465b97b7b178b3ab205ea429d0dea4eb9dd6e69ac5650c6bc749b347c763320d9514bc317f43 +924e4afc979d1fd1ec8ab17e02b69964a1f025882611d9ba57c772175926944e42c68422d15f9326285538a348f9301e593e02c35a9817b160c05e21003d202473db69df695191be22db05615561951867f8425f88c29ba8997a41a2f96b5cee791307369671543373ea91d5ed9d6a34794d33305db8975b061864e6b0fe775f 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8 97ca6bc05cb62fbc63ef0b2c098f6d2615ffc1ca567c91ff98af536ecc6341c57d19dd84f52c2fea13366370f6d211a312d39e19b818c5f67a8aa3e325e6ce65ecf92e8319917eac9c7070a74db9c96306ba761577f41fa5294f5e3d26267f50 +c64319c8aa1c1ae676630045ae488aedebca19d753704182c4bf3b306b75db98e9be438234233c2f14e3b97c2f55236950629885ac1e0bd015db0f912913ffb6f1361c4cc25c3cd434583b0f7a5a9e1a549aa523614268037973b65eb59c0c16a19a49bfaa13d507b29d5c7a146cd8da2917665100ac9de2d75fa48cb708ac79 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad adb87b9f9a9965b32c73eecc170e5753f71853c39f46f2293fda616d8fb3920b17c2fdadd00bb8c6fcc31c6e2249abfe07a78af605c4f928ea01581821a2bdf3d2f394896b671959bfa68fdc2cbd151d9ad50556f967c4e9d52dc0ca69bc8276 +8ab8176b16278db54f84328ae0b75ef8f0cd18afdf40c04ad0927ed0f6d9e47470396c8e87cde7a9be2ffbfe6c9658c88b7de4d582111119c433b2e4a504493f0a1166e3a3ea0d7b93358f4a297d63f65a5e752f94e2ee7f49ebcc742fa3eb03a617d00c574245b77a20033854d82964b2949e2247637239ab00baf4d170d97c 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a 8409191d8a11fdffa9f284a2c8e017fb081fca6515f93cdf2a01ac8c8874f12ba4b31c0688f3cf5de08a4b7186c7950910233349ea5ace31b2ad435cb2a2d4efea0c4531ad5abf8679fc930e9c06cbf4c2814161ed8223e4fe383adf07575044 +c4bc2cec829036469e55acdd277745034e4e3cc4fcd2f50ec8bd89055c19795a1e051ccf9aa178e12f9beab6a016a7257e391faa536eaa5c969396d4e1ade36795a82ebc709d9422de8497e5b68e7292538d4ccdc6dd66d27a3ece6a2844962b77db073df9489c9710585ba03d53fa430dbc6626dc03b61d53fc180b9af5dea6 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c 8b8545376ac66e51c39ed2e39aea333edd47f3a8f1144a5e1271223e6215563cee924743f37ffe3be0ea556bc6fc644116bf67e621c84bd0937635df2a6cc334e7f400448469a64e31cb30d1b5dbcb6547877dece2b78dbb0c770470ad28698f +1c1b641d0511a0625a4b33e7639d7a057e27f3a7f818e67f593286c8a4c827bb1f3e4f399027e57f18a45403a310c785b50e5a03517c72b45ef8c242a57b162debf2e80c1cf6c7b90237aede5f4ab1fcaf8187be3beb524c223cc0ceff24429eb181a5eea364a748c713214880d976c2cd497fd65ab3854ad0d6c2c1913d3a06 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d ad230f99b4a3ef27f4e0f133650c97cc7f49ddd7c9881f56647f97244b3dab3dc71330ed9f04de7cfc78c7ebe5ca62820e379502648fbd2e6de2450f5a1f1a1e44030b79985f04384f34506ac354901c1178f14ab5eb96c7a5dbc7929738f625 +adb5f069b2b501a3ebb83d4f1808eb07710ac4a7b12532996855a20bcc54b2f76812915f632163c3654ff13d187d007152617cf859200194b59c5e81fc6cc9eb1ceb75d654050f260caa79c265254089270ccd02607fdcf3246119738c496dc3a4bd5d3be15789fc3d29a08d6d921febe2f40aef286d5d4330b07198c7f4588e 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c 8d407ac32acdae5f085b0f92c4dec3eda7f3eca6def99958bbd3548c31e06dad27487bdc66a337ca22dfaf36bd38c5270bbb8cff5d76d2f767612e158a5c5c41254c77255e493be438c76c923264ebf8397980c19cf3459089b6da9990b411c5 +f253484d121d1ce8a88def6a3e9e78c47f4025ead6f73285bf90647102645b0c32d4d86742a50b8b7a42d5f6156a6faf588212b7dc72c3ffd13973bdba732b554d8bffc57d04f8167aef21ee941ee6ffb6cce0f49445bd707da8deb35dca650aaf761c3aa66a5ebccddd15aee21293f63061a7f4bfc3787c2cd62c806a1a9985 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25 b7421af895c8eab4432e7b9670df2519cddf930b49917a86c8d48395aab0e8bf6b25a5ff2cd5f4acb3b2c3933a817473195ef2c12858bd70138fb60d72c095e3f6c2581c13b0391be2f4b2926e59b0270c4084959685153dbc6d0503a945b621 +33bab1c369c495db1610965bc0b0546a216e8dd00cd0e602a605d40bc8812bbf1ffa67143f896c436b8f7cf0bed308054f1e1ff77f4d0a13c1e831efbd0e2fcfb3eadab9f755f070ba9aeaceb0a5110f2f8b0c1f7b1aa96a7f2d038a1b72e26400819b1f73d925ea4e34d6acaf59d0a461a34ce5d65c9c937a80e844e323a16d 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf 865e128891391f88741447985caeb805d5940f4c7f7934ae9fd4743c45cf52bcc2dc6d0a4753d682b9623d64c04325b80d1ab2ff0bdc2d906c0ab0f4a7ec5e1cb2c94b2ba59b99792f694a28d4e5c60ae73a9175b5e11eaa550a471f7b033527 +08c8b7faaac8e1154042d162dca1df0f66e0001b3c5ecf49b6a4334ce4e8a754a1a8e4daf8ec09cf1e521c96547aed5172ef852e82c03cddd851a9f992183ac5199594f288dbcc53a9bb6128561ff3236a7b4b0dce8eaf7d45e64e782955ee1b690ce6a73ece47dc4409b690de6b7928cbe60c42fc6a5ddf1d729faf1cc3885e 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570 8111373168214655ca02b344c45a716486ac7247f0c91a76ab8ee57592c7277916fe4bc20ed99df7561b8a8ec382c4b0137993b5b081a2a886c36895cdea675d297b4b33547b5c0e6abc646c5359c15f8e764a73c47f2c965b3b570c7f13b899 +ba74eed74282811631bd2069e862381e4e2a1e4e9a357b1c159a9ce69786f864b60fe90eeb32d8b72b099986fc594965a33285f7185b415df58fead7b8b50fc60d073680881d7435609ad1d22fd21e789b6730e232b0d2e888889fb82d6ad0337ab909308676164d4f47df44b21190eca8ba0f94995e60ad9bb02938461eee61 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6 b7bd86f61b5a06d530cbf60c0f9a858a4eceb4d3538133fb652f78903d65484978cedfea8d9f5a1e9954c22b0f3407d9158991c4a60f81506b59e4bfe45ac37de59a31d77ee5c3648c94ffd9d81c0039edd3e941e9979163e673d03f79870aed +dc71f171a28bdc30968c39f08f999b88dc04c550e261ecf1124d67f05edeae7e87fe9b8135a96fe2bc3996a4f47213d9d191184a76bd6310e1ee5cb67ea7fc3ef6f641a0ba165198040fa668192b75a4754fc02c224bd4a74aade5a8c814adf151c2bfeda65165a04ef359e39847c84e312afb66d4cd1db50d41ef3fe5f31296 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7 9107eca17c7c7fdd081a86b350c743213429c0ee84013b7956f557bcebee64f4e29339e918127ca1fd01b14d5fed86d6152fb7fed52520595bdb43996f5a48d39b85d507e1bac6fb0d0028c5f95eeed8ace3c057a944a885d41d81d14fd185c5 +b895788d7828aaeace4f6b61a072ffa344d8ea324962ba6dab5efda93f65bf64a0f2ac6d5721d03ee70e2aef21cdba69fd29040199160e3a293b772ffb961ed694a8dc82800dab79367a4809a864e4aff6bc837aaa868e952b771b76591c0bb82249034e3208e593d85973d3fea753a95b16e221b2561644535c0131fe834ae7 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e 8c6f6ae96b93b68bc61ab29ca5f1e80c6651929b825a82e752a0bf9789b2803c761d4880d19788625b6a83a06cb7ddc3151c4c4a68820a90ab5fcf7d2e429e14bd4ad7b8bd5be71f6626af900343088d6f3083be0a60a5e0f9c398f7bb78f81d +2c5bd848c476e34b427cfe5676692e588e1957957db7b5704492bd02104a38216535607f5d092dc40020130c04a3aaf0f1c52409834926d69a05d3f3188187a71d402a10ba34eac8629b4c6359b1095f30f710219298bf06b9f19bfc299981d7e251ca232a0a85338a7e02464731d1b25d4a1f68baf97064516590644820c998 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938 a92ae260ceb78b1b4e3b92f60a63f70157acf28e5443b7c1e80ff82db519add62772081208c794415b8c4890ae6a6c0f04d6981fca09338ad06b118af8c039032da00043a5ad150ba83ae32c5f8eae01ecf61fffba24619d38c1d9a973f75c9a +65a0b97048067a0c9040acbb5d7f6e2e6ac462e1e0064a8ce5b5bbf8e57059e25a3ef8c80fc9037ae08f63e63f5bdb9378c322ad9b2daf839fad7a75b1027abb6f70f110247da7e971c7c52914e5a4f7761854432fa16b2a521e7bcaee2c735a87cad20c535bf6d04a87340c229bf9af8647eedca9e2dc0b5aa90f7fea3cdc0a 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662 a61fd85ddd0d145b665291baf1898a0e21e810981b64f37e968bea6262cce5f35b21567c921be0ee3ab08355e5b5960211e0c8a1046680e8c7989ca10b225f78dc04ceae67d3ac3dcd38e950be6cbe54176d76b182de47cf1132b7873a18fb9d +d6e366a87808eea5d39fe77cac4b8c754e865a796062e2ec89f72165cd41fe04c48148068c570e0d29afe9011e7e7a2461f4d9897d8c1fa14b4ff88cab40059d17ab724f4039244e97fcecb07f9ffeec2fb9d6b1896700fe374104a8c44af01a10e93b268d25367bf2bef488b8abcc1ef0e14c3e6e1621b2d58753f21e28b86f 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721 96a881ec2f54f873248204dc3eb2f107a607e5c8e10d4a5411fb648b9cc925133a5d540465c247d0b08897dc6c8194ea0bb4c99e434a233c5d60bae2d06837da238ebcfc3c1dd041394882c7bd0425fc0d2716e5117bc9ba6aff9844fa7129af +f99e1d272d0f5fb9c4f986e873d070ec638422bc04b47c715595e2cf1a701cdf88bc6c4b20085b357bad12ccba67cac8a5ca07f31ba432f9154ff1fadefd487a83a9c37e49fb70a2f170e58889cab0552e0a3806ccfa2a60d96e346851d84b7de6d1a4b8cf37567dc161a84f13421e3412457d4bc27f6213453c8519a2d7daa2 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e 835ae5edf0ab577b86fe8fb4ef3357555ea97bef397e2a1623717f93e3d0c12e98f4190e8b788892575dabc04595b26606596feb51c0b5232a2bd3eeafefcb3fa06de33f0bdcc757279435be6fa7698d5627aee9e789fec283650dd4a98577a8 +91f1ca8ce6681f4e1f117b918ae787a888798a9df3afc9d0e922f51cdd6e7f7e55da996f7e3615f1d41e4292479859a44fa18a5a006662610f1aaa2884f843c2e73d441753e0ead51dffc366250616c706f07128940dd6312ff3eda6f0e2b4e441b3d74c592b97d9cd910f979d7f39767b379e7f36a7519f2a4a251ef5e8aae1 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418 8f112a78c336259263e88462090deb7bf04e9990d1e06620e450279212a32b04d10c004c58a66b3793a454c5069a3178089e891efc3392879696d5b7d28083bc43eae875b15e9e301f83271736833b138fbbe8d6563565f343a33d66dbdf542f +dbc094402c5b559d53168c6f0c550d827499c6fb2186ae2db15b89b4e6f46220386d6f01bebde91b6ceb3ec7b4696e2cbfd14894dd0b7d656d23396ce920044f9ca514bf115cf98ecaa55b950a9e49365c2f3a05be5020e93db92c37437513044973e792af814d0ffad2c8ecc89ae4b35ccb19318f0b988a7d33ec5a4fe85dfe 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950 94c16471e4a2e1eddaba3c018ea54fb7da47b63894e508a595bf242e6176ac52e1fb0c1b398dde614eb9dfb3a76ade74178564d5a153ac7b9ac2b2047a2f8c29bfad78c9897b391d5ebf36ac110d5edd0d69f40074c121b341e2dfcdd1e1eee3 +114187efd1f6d6c46473fed0c1922987c79be2144439c6f61183caf2045bfb419f8cddc82267d14540624975f27232117729ccfeacccc7ecd5b71473c69d128152931865a60e6a104b67afe5ed443bdbcdc45372f1a85012bbc4614d4c0c534aacd9ab78664dda9b1f1e255878e8ac59e23c56a686f567e4b15c66f0e7c0931e 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b adfade716e1617feae5f8e6307f3ba1cbeb144640f14d3cd25b6b9eae35dfc34d9835e4ec8e2c518ea764233d723513a156b2090da99bce6921f48474a68e0c566e6d512ca739fe3d3328f2495e4f69ad96ec75c37ea53878c02d00d6a78aefe +6744b69fc2420fe00f2352399bd58719e4ecdd6d602e2c80f194d607e58b27a0854745bfd6d504de2eb30b04cee0f44af710dd77e2f816ac3ac5692fad2d1d417893bb0edba2707a4c146a486f8728ca696d35cc52e9c7187c82d4bdb92eb954794e5ad15133f6bfea1f025da32ada710a3014cf11095b3ff69a94d087f17753 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f 8c42b99c6d7c2f55e46bef8b68f0cb008292e11990210f293c55ba08ac458825f43c3fab193bfeef7122e622fe334e1a0cc38c9e8cff96ff910a967dd8ba0ebdf886ff88e6d00090ce2c7bc902175104665c6715456b8b81ffe16b5c6c919ebe +16001f4dcf9e76aa134b12b867f252735144e523e40fba9b4811b07448a24ef4ccf3e81fe9d7f8097ae1d216a51b6eefc83880885e5b14a5eeee025c4232319c4b8bce26807d1b386ad6a964deb3bdca30ee196cfdd717facfad5c77d9b1d05fdd96875e9675e85029ecbf4f94c524624746b7c42870c14a9a1454acf3354474 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66 b5201df6da23d08e40139d770481aa7e70bb6989be624a28573574a9402a9e26f61de3010c84ab3e3315b1532836ab8c0db5bacbdcd52731a0a71b8825116b7a2085793732e1311406296ac551e616a513670063e9747a2a4706c47dff71b70c +a9824a7b810aa16690083a00d422842971baf400c3563baa789c5653fc13416111c0236c67c68e95a13cec0df50324dcc9ae780ce4232607cb57dd9b2c61b382f0fa51fd4e283e2c55ffe272597651659fbd88cd03bfa9652cd54b01a7034c83a602709879e1325c77969bebfd93932ce09a23eae607374602201614ff84b141 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c 8aef1f4237c6ee7841a814db018fc46253a01e431384b803c7cf5d0cd530f5da5f921fd62e1ff83eaed6dfd289f9267b10628837478d554a58ff8fdf417b9c60cb5eacbd695093844a6c1d758ca5de5d588455a61852ff1bc58f364159286e0d +90d8bbf714fd2120d2144022bf29520842d9fbd2dc8bb734b3e892ba0285c6a342d6e1e37cc11a62083566e45b039cc65506d20a7d8b51d763d25f0d9eaf3d38601af612c5798a8a2c712d968592b6ed689b88bbab95259ad34da26af9dda80f2f8a02960370bdb7e7595c0a4fffb465d7ad0c4665b5ec0e7d50c6a8238c7f53 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0 86859cb8f89e8f2305f4951f7fd7dd70d12638be5bb54bb58724623b102b56c24422f2fb2fa0518aa8718e87154ff44418aa02b5a362cab8d6ebb179ffd191ff809a8bc700ff99b5afab6f4fa911a517b72d5b0a4d71f235620a14e21f1be64d +09952b1e09995e95bf0022e911c6ab1a463b0a1fdd0eec69117b34af1103c720b57600217de7cd178fef92de5391e550af72a8dcf7badf25b06dd039417f9a7d0f5be88fcd4e9655931d5b605452a667c9d1bae91d3476e7d51cff4108f116a49966fb3a7cff8df1c09734ce5620faf2dccb3dc5d94e7e9ac812da31f6d07a38 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9 b770c3fbf4d7c94f4a2168fcf64ee0a5370d41055680fb884a08327b844015558e6c39e99aad48dca8c186af68d080f4042034c6bde4d8136baf995fea8da42189eddd20c0b3347d83edc2fd5e844d980b354606eb83674df610897d757d7e1d +0bb0f80cff309c65ff7729c59c517d50fc0ed5be405ef70cb910c3f62c328c90853d4473530b654dda6156e149bc2222a8a7f9be665240e2fbe9d03f78a2356af0bacd1edb84c4801adc8293a8a0bd6123d1cf6ba216aca807a7eb4dca76b493eb6e3dbb69d36f0f00f856222f24d9b93ec34c3b261be2fca0451c00571928e5 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d 951ba06bd2fffe2f20e0a19b1190110419a4b53474eabbbd59600f2fbe8d6710c2013f490d25c85f4d94e654473d567f12cdc057a3f04cea724e50db8431c750958846ceb2979cd8d8d7c414172870c742d7e97de5651b4275b52f11f53302b5 +7efacf213382ce30804e78b7256854d759147dba9729c51b2759465715bf2c421034c23dc651c13d6cce95f71fe6a84dfbee5768163ac5789ac0474c5ddf4115684683c5f7c204b33b8bcc0c03ac58f66cef2f53b721fe2fac91ad841126101a88f512a7c2ded38549d9f050d4b7961dda48a1489f026c5d111701762418cfe3 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490 84ba0c9c97ac398f1ff1dc31979f80c830cf2cc87f665229c6903247d53a78fab38c7e7fda7f03ee82e41ba46dfbb7980f8cce58678072f855040661e2dd83747f1ae85a4a9fef3a2bedbbce54e4401346676137650469bc9e5a01cc7ffae8c6 +28edff8b9d85f5f58499cc11f492abdfab25e8945975bbaeee910afa2b8fc1295ec61406309ce4e09f4ab4f462959fc2a2786802466eb26d3b01be6919893ae75d0fdc2dc8a82e662550f9fce9627dd364188aaba5c6faa1b2d8a2235adfa5ad0dc140f88a2b2f103f5690e877d07fe8fd30d02d2b2729bd3d8eb5b23a21f54c 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1 84053f2447c761374c954834d4eb43e6cdd384d248ecbead487e099612013e0a67b2d27ef0975a26a523818b8dc0ae5b013723873bc19cc35e15feba616b0c9f3b72872bde794fc95dabb2461eb55349189d4d72f5ec4d540ead3362570fdad8 +bae2a8897c742fd99fbf813351cd009d3f2e18d825ca22e115276484bce8f82f8c7c0c21dd2af208404d8ef45bb5a6c41693912b630897d5246801bf0775aa9bbac8be98cb861d172c3563dc59e78a58ed13c66dea496471b3ad0eeae8995293e4ab97373edc1837ffc95ff1cc0c1e90e64ea8680b2ca5f1e09bf86b99b343b6 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745 a488300d7e15328af3f67e8348de007096e524c2df32dbb4a2fd71a80fdf84d154734156864ff7b2f88049452c6cd91b054313f16f33a134bcb5579b8e1a6fd3fc9a05432592dd1879dea602ee66d48fd56c4cb5e599fba053443329fed5d2b0 +d57a26a9593e72bfc87322524639bcaae5f2252d18b99cdaa03b14445b0b8a4dd53928f66a2e4f202fb25b19cad0eb2f1bfda2ab9b0eb668cdcd0fe72f5d9ef2e45e0218590f7ab9d2c9342202610c698bc786cce108a7d4a6730a13e9ea1b470e781f1237d3f84f44abde808516975546bd89075ef9a9732bfd7ee33b6f4399 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f 92968ad8d07270e375e93ffae59393f4989d866b261245b96e30a41aad0f887f073c6cef8527856766c54bbe348d824a04cd5cb6a31338d2498c012069acc412959c70c47e17489b12aa9d3bbfa2a76ace000402846c1b8f6a218c6b998d5a42 +8fdcf5084b12cfc043dd3416b46274e021bbed95d341d3c500c102a5609d3a34de29f8fa9f0adb611a1f47a97ad981f8129d718fc0d6c709eab1a3490db8d550f34eb905b9e00663543afc5bc155e368e0bc919a8b8c9fa42093603537a5614927efa6be819ed42ececbf1a80a61e6e0a7f9b5bc43b9238e62d5df0571fea152 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e 984010517d53140bc2e788a0af26700ee02737e0b5567aff734b5e15db8a9598db5b9b8502bbb0196a6284414da6268519e40e3200408acf92507e640b28e05d05b2952c42b6aa18f160b8b3d03a802011f2ca514fc646bf4dc8d9848dbfc609 +00669f433934992257bed55861df679804107d7fa491672574a7624949c60049b0533383c88d6896c8de860704c3e6a6aefce83efa57c4d57e9ab253da5d15e1f53ab6dce218b592772ab0bc01fee8e63368e85c0639301456fe2d44cd5396a7f2b22761cd03b80eba7883eede8249a2f5db2183bf00550c5c002f45a5e4fb31 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89 82470b784a165bc28a4dc044e88c801d86b90968ca15cebe8e4eb244551684064fd54a93a3bf1d7aec37cca54d20c93d036aabecf8c6f4e38e887a019c369c0ffcffa6ee7174ea9c0dd6b51082b5775066f5531ff242231bd94ad95735ae497e +4be81dcfab39a64d6f00c0d7fff94dabdf3473dc49f0e12900df328d6584b854fbaebaf3194c433e9e21743342e2dd056b445c8aa7d30a38504b366a8fa889dc8ecec35b3130070787e7bf0f22fab5bea54a07d3a75368605397ba74dbf2923ef20c37a0d9c64caebcc93157456b57b98d4becb13fecb7cc7f3740a6057af287 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a 8596af1bc5dd5830bc940578c4fffd73dab1ced846cf89de1594adf4c0470bdd139d4758f9b34c95859edef4a0c960000676c5a0defc326921ea1b8954029e7320a3bec9aebf04ed103d2872ea46ee6a5a48ef3280418f7559bfe5e40ec82eb6 +9ecd500c60e701404922e58ab20cc002651fdee7cbc9336adda33e4c1088fab1964ecb7904dc6856865d6c8e15041ccf2d5ac302e99d346ff2f686531d25521678d4fd3f76bbf2c893d246cb4d7693792fe18172108146853103a51f824acc621cb7311d2463c3361ea707254f2b052bc22cb8012873dcbb95bf1a5cc53ab89f 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926 b34b3cce5503bf125b1a721b8674f52d33459ae87668e5fdc1cc498f06d037ed3de36bd3de3972865c924c085b97f68114c71c8eea4701f091087ed6dccf4d693a6b086d2a6a9678e08acc84807b6e1e39a5a5bc1e12d4a34077dd8607e06fcb +b3c63e5f5a21c4bfe3dbc644354d9a949186d6a9e1dd873828782aa6a0f1df2f64114a430b1c13fe8a2e09099e1ed05ef70de698161039ded73bcb50b312673bb073f8a792ac140a78a8b7f3586dffb1fc8be4f54516d57418ccc9945025ce3acf1eb84f69ceee5e9bd10c18c251dbc481562cd3aae54b54ab618cb1eeda33cf 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6 9471de19149b492e09c0da9bfd7f09abfeed152a97ec12f506f92addd5074aba8c2179f4e3f8988b195c71517625e8df08fc4ad602f731a5f6b1b037cd750e5c4cbaeb7e666c8fc1440cad63354032621bc9aa6c8d70f5a1bcdb07d41a74d8d0 +6e0f96d56505ffd2d005d5677dbf926345f0ff0a5da456bbcbcfdc2d33c8d878b0bc8511401c73168d161c23a88b04d7a9629a7a6fbcff241071b0d212248fcc2c94fa5c086909adb8f4b9772b4293b4acf5215ea2fc72f8cec57b5a13792d7859b6d40348fc3ba3f5e7062a19075a9edb713ddcd391aefc90f46bbd81e2557b 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f ae31ad7c200013da965617703267c9f0322c336dfc3ce90a527372d2a96f5f37bbe81fa7e3965807d05b6710e5ae63c8102d26b35a3f862f60134fa96c3ae434320116f46ad284f1dc3f7d73309f9a1f545f04bd60c665312b4501ac684d3e51 +3f12ab17af3c3680aad22196337cedb0a9dba22387a7c555b46e84176a6f8418004552386ada4deec59fdabb0d25e1c6668a96f100b352f8dabd24b2262bd2a3d0f825602d54150bdc4bcbd5b8e0ca52bc8d2c70ff2af9b03e20730d6bd9ec1d091a3e5c877259bcff4fd2c17a12bfc4b08117ec39fe4762be128d0883a37e9d 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742 b29c9cd6c51bf08258312a6e44c0abd73edabada7afa1d5b7a681ac86fed0064e28fe215cbad128f02b6a2811e1c44c317852aed434d5195c4828879bdaeb14688c8e772f6ba56d3c7941f143e843a8fd4aa3a935c7a70568c09e8e00b4f2d3a +a1eed24b3b7c33296c2491d6ee092ec6124f85cf566bb5bc35bffb5c734e34547242e57593e962fb76aee9e800eed2d702cc301499060b76406b347f3d1c86456978950737703c8159001e6778f69c734a56e5ce5938bd0e0de0877d55adeee48b0d8dfa4ac65fd2d3ce3e12878bac5c7014f9284d161b2a3e7d5c88569a45f6 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697 99797de1354af918033f8b0133078134ebb6759ae4c2d4ce90bcc6479fbe582b6e5cd33098e679cae23ad7c4dcef87e00f39eee9e1bd4c8b8f0f0aed42a770aae2259ee431b6021eb567da3ab2ccf32f6e5f41f0c294b679aac0c047a816368f +9aace26837695e6596007a54e4bccdd5ffb16dc6844140e2eeeb584b15acb2bbffd203c74440b6ee8db676fd200b4186a8c3e957c19e74d4d865ada83f80655323dfa3570907ed3ce853b6e8cc375ed2d758a2f5ad265dd3b47650517a49b3d02df9e0c60c21576378c2b3a08481eec129b2a75608e13e6420127a3a63c8a3f1 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04 b000927d7b86053b63748ed048af297c2bbc7f9997950fec8c6b19e43457641fb0dead6d0fabbb8515946f3bd7b0686d10b3fd7a4b6d5def540017bbcbcaf99556abd0d79d48db73c9d3d582f20ea0510606828a81dcb98c693135fc8690e0e0 +ac2175940545d4fbab6e2e651c6830aba562e0c11c919e797c43eff9f187a68a9e5a128e3e2a330b955a3f4577d3f826529ad1b03d7b60f7ad678f005053b41dc0f8d267f3685c6abe1a0e9a733c44b2f3ca48b90806f935141c842e3a6c06a58f5343d75e3585971a734f4ae1074ce5b54f74bd9342f4bbca738d260393f43e 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6 abe9617790a174008e60ddb68472a954fb95e1ed6a18450551809b24e1295d6af154b6ea7d24489fb12cff5ebdb94ed914262dac9596cf2b2f961ecc6b4019bfd786088de1508562a3a84b6dcdd8667ccd69b4e8425b16dfa0b23b5ce1b4363c +6266f09710e2434cb3da3b15396556765db2ddcd221dce257eab7399c7c490135925112932716af1434053b8b9fe340563e57a0b9776f9ac92cbb5fba18b05c0a2fafbed7240b3f93cd1780c980ff5fe92610e36c0177cabe82367c84cee9020cf26c1d74ae3eb9b9b512cb8b3cb3d81b17cf20dc76591b2b394ef1c62ac12ee 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e b3262ccc5e275f12c9380b863e9b71c4da6db8df5bab3f2f02b2a5065efd8ce87fafaac9a70ab6359ac369a235c914211244468a34e640a599cd9d3dfdaba2e9a3091630c2d3c02fbafaa31e064e6363a0f753a7597f3c1508bb42acc8274b12 +3de9e617a6868dca1a1432d503f923535da3f9b34426b2a4822174399c73b1c1ee67311410a58c17202ac767844b2024d8aa21a205707d93865693ac25a24fc87034fa3a7a7e27c3344cb03b87602c15180a5fe6a9dd90cd11af4a0f150207bf2d83f55b12c088adae99aa8cfa659311b3a25beb99056643760d6a282126b9b2 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5 b1cd38899b9ced28dcad934ae595715ef2c015ff5bd05f6a6f129960a8a4ffaa86c3401aaa1b43fd0cfd75dbeb6149030edfcb5c938c996d856ee05f28cc2d7b59aeac755a64fe3f3a7e54ba5185fd496455f40b6a6dd8cff0646f0b3217f746 +aa48851af7ef17abe233163b7185130f4646203c205e22bcc2a5a3697bcab998c73a9ffe1d3ea0b7978ce7df937a72586eb5ca60b0d939a7d1c115c820171c89c8116b7e2c7b98cf0f14e4c4df3cb2f319ad3ab0ea25ff14526ddc037469f000bf82100acd4cdf94feb4eba4ea1726f0569336604a473aee67d71afebb569209 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a af8f7b17caf5fe2ece6b96c442d59c7d3ef96cbd3eb7357343744b7d54d8e96664d782e16a9f658a8664f3a3d0a5003213758de890e733a3136bf444b08131c2671fb2e52b00bac45724a306c5d67836a5298932c8df796b7e1a2766dfebd07a +b0d5d52259af364eb2d1a5027e5f7d0afe4b999cc5dd2268cfe76f51d2f17b541bdd7867e23a1bb897705153d9432a24012108979c6a2c9e2567c9531d012f9e4be764419491a52eae2e127430b0ab58cb8e216515a821b3db206447c235bf44ee304201b483b2a88844abaa18bca0147dfff7e502397dd62e15524f67eb2df2 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb a2d116e9773b0814644fc197386730a229d43041637ab0194e78203a0e86da8fbe3ff394720563b7bf5ba2af5d553116146afb75e7b3fd5b15a66044120292c72eedce249f445788c5fe6bd6f0868912e66832ce2a3506b488899abf0ec5fc08 +9599788344976779383a7a0812a096943a1f771ee484d586af1a06207478e4c0be9c200d42460fe837e24b266c8852d80d3c53cc52ffb1913fc3261145fc6da575611efd16c026059a2e64f802517ffd1b6b34de10ad2909c65c2155e8d939b8115400c1d793d23955b15f5d1c13c962ff92b4a815cee0e10f8e14e1f6e6cd38 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77 b451c3ca3462a657568fbc471a1ebe89e3d1dc68bd759530198f0af8295202647204edb51e1f78224b518d885a98d12412ff947a5da4124ff2836a8faafddb9561c5e56d9114aa546b0fef9f12f848ac697982b23a44b2b9b8de394b96298fb1 +fdde51acfd04eb0ad892ce9d6c0f90eb91ce765cbe3ce9d3f2defe8f691324d26b968b8b90e77706b068585f2a3ee7bf3e910528f7403c5af745a6f9d7ba6c53abd885c3b1be583415b128f4d3f224daf8563476bd9aa61e9c8518c144335f8f879c03696bddbe3ac37a8fbede29861611feaa87e325e2f60278b4893ed57fb0 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c b52525d1d10204bd719e247822a7db30d4884b64e37dadf539af6cfa2df3ccc8793d3724ec76b7b3754b1bae7c14b2ae16ac9b34b498ae3fcc1ac0d43616b0f8c2cf474d4e41dbdce3ad6879d9b4f3e26b0fb84f3c3f1769eaf5d0638fcd532f +beb34c997f905c77451ac392f7957a0ab8b23325bd5c63ca31c109ac8f655a1e3094240cb8a99284f8091de2ab9a7db2504d16251980b86be89ec3a3f41162698bab51848880633e0b71a38f8896335853d8e836a2454ecab2acdcc052c8f659be1d703b13ae1b090334ac50ab0137ddb5e8b924c0e3d2e5789daaef2fdd4a1e 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63 a40cb3d588b540a6e107d04cd74cf4d3363dcc48f5eb88c373aae902c75ec80a62e433dbcaa146a1e00416567178314018881079664f325953fb09da7ce82a9037208ecad1b2a3ba7b71824d6b9400209999df9b388b872fa49dbf37a23b0c94 +543c374af90c34f50ee195006d5f9d8dd986d09ad182fcbefa085567275eee1e742bfe0af3d058675adeb5b9f87f248b00a9fbd2aa779129123a5b983f2f26fc3caf2ea34277550c22fe8c814c739b46972d50232993cddd63a3c99e20f5c5067d9b57e2d5db94317a5a16b5c12b5c4cafbc79cbc2f9940f074bbc7d0dc71e90 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da 8611510dd155b1778f16a7cab8a2cadffdec9c28ea395b13c8736814db134dd0d48e787610a23128f6d3518b1b71aed71058a6281dd07c79657f5438af317c522161c8aaf16603d93d0d626bf44483d3ce71939e8ffb2c2f16019337dcd2be32 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_rfc6979 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_rfc6979 new file mode 100644 index 000000000000..b110182c060f --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_rfc6979 @@ -0,0 +1,34 @@ +73616d706c65 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 ade4251a0136ccd502d441e47d2df8462a96cc85ed1720b85a8bf2be1aa49eedb96f73297302c5a85599225896aef1ce028a459addc39d8617b825c65119ff8d22b437b70c8c36def6411102278274816a8c585bd31f8ebfd0bbb3bd66a74a33 +74657374 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 b184d62fe3052488a4a56c7301988db544f12b4f8f34553f4cff2c3e39322893eb8e34943487c1d6eead742f6797dc730e22c4817114d69d3bdc83e3c8eb2242d8b844d5c7cb56f0ff14e6e2ce5892b842d7d653b02e8fc63bfefc2941f2855b +73616d706c65 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc a49dee0999240934e9a2d49b52e4b6b0f10a3ba51900a46cd110878cd9bc75860239ecfbe1fec097bfcdb243f931eb9309a849a26354fe58a87e3e1c640669fb445ccd90d7e8e064f265991261115257436f44d268f3b249d77ed0d15ed8ed0e +74657374 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc 950074853757536fa65d215ade813228f5fed1c94426302dc0380f21ce9d2c22d65ed92cbca41910cda40afcc46061ef051b042ff7e3b8277269ce687773b1f64b4fc3fa31292fad2bc4abe61fedd89a734701524db4778041f79994c85b6ed8 +73616d706c65 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 8891b7054f731cab4af712d3bcd51d23158c957c2a4f59da0c9fff50344f9ce756e9c7e11247838b3d3a21e28f863f0705c0957b81cf84dbc35c040c6cd2c706352d932592a53900e11c59345f4b53e60361d7fb4b5f9a56e6b06de73cba1f91 +74657374 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 b2be787378d0871fe5cfbe3118187fa14e1228abf8cae6f07370f0cd8e498f71747245f03b991d5f9542294a609234770ea5bbba854e37a87435dbd0e03f60cf1e5f16d5fd1a44b6908c56761b85e85c786913f0b490b4f85d1a5e0b679b2c25 +73616d706c65 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 8facd1d63ae37ef863fa91947bff40b6d108c55ba4a0b9808a8cc44cdd776a72ce28d61e8251cacaf9cede95cd0792be1750ffca14786689a55723b86a29cb223e85e2b03da184c4be7468e509f93c9184aefc7aa9bb155178c38ff86702dfdf +74657374 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 803ff119daba856fb81800fff41fb1e435bd3998904c342fa024ce7688c6b518f943568fc7af8803d804c47962e35b4b0bfcd5de1225f94c239ab7180fda593814618e4816897b8d6c82f9ecc2d9976742ec5f868ec63b72c6db25c986c3f339 +73616d706c65 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 a96761a5b79fa3d20d31ca04cbdb269ee6118c61b4e0f06bd6c348a4ddbe5f71da6206d6620eeea65ccf5dd36ceb316a1632620d5c509af48331480feb134ae815aa1918fa4d39d3d8c362aa86b5508cc1991b8ec11e962959f4d6e2a791402a +74657374 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 98687abc1ce9f3ab02ca85593bdbcb7ec208255546f6879fee48a9c66dec342d39a7dea254c02beefe7f152db28cdbe81321723f1b2160ea9d1efa0dd8a8fb46bfd4a1463f4e52e17300f27efec6d733fa1b015d4ae9c8484b3d75b075224b2d +73616d706c65 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 b490d32325ae0ef7d7e59a0c8085c1bb4b6c50f589ff6a99752a5af06fa099c0419591aece5b2d90362296a8a71c1d8b050ed2ad3b9ea731ba8af60378d3ba1f5786494446fcfc6a90c96d80eff2cd5f4ce4f34830d352047201fd09fca17cd6 +74657374 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 87a4b0dad15a83ed1f3f76a76628b33757939a020f714f3663258005df4807950d4d322bd563b9720457b36300409c4b0901688eca37fffd9a25b7a1d7aa8b04bde4b5a88b462a71b175654f2f03b0512eeecfe7ced731c07fdf40c4becadeda +73616d706c65 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c b5643d52af223d791b8ccac26aded0a3c275f6fef16d15bef7f86d6b51d7e04bafd0ae3f3a37b797518ec8b71fb61f830e655402e816412ae939c369fe3521f224c1602b0eae3029a1b6889ba2bbe10b02e20b0d0e4130ebc3f0c480aedddf10 +74657374 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c a3429ae4afab620ad4cd03934086d006040a6237d7fec53ca2973263df70a1beae97ad6a2fef3baf317da7241e608bdc161103e3b5e50d1d1b9deaa670c40f70d9dd05f7841dbbd027e530dedb0687dce9c88309062efb3f3afe7d695f25981b +73616d706c65 9a4d6792295a7f730fc3f2b49cbc0f62e862272f a722107028252d72d593b39a5fea68593918e22ec8a906ff15cc9dac55f6728ff3ad571b3131eeb39ea7431ab9cd107d11fe5f4e6bac7f0ab0618fcf3ccf4b42ffb39cdcad298b1aaa512f561f72bbe47237bcf6ea8a547ac22db36ef7e42a38 +74657374 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 8add99b019aeaf101044a6a5da041d0fcbf0e4dea24c3609230f01f24a98f818a484fa92ad38927398c55263fe0899690b9bb7f711881dcc93ef50bdd17efa61907e9ef1602eae552b9e9f7386570b5ace04dd7e5cba947733df750499be1e0f +73616d706c65 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 82087401a34e17daed757f8a6bb5c313053690e6d28009f0f976cdb7fded3d914f4cc9150ef32787add122b9bcbd8e1915d96d9bc436e548c86f7e227ed622a6337bf65ad8b994c1df1c21e198fd6e9aa41391db6e7a51bcd1ebf81eb77e1241 +74657374 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 b2f7469b7ffd2f9f2ff9d261eae13ea215f25a07fb0c0f074a6216aacfe1640b7287c6f81a2f0064c4d090021a20aa6416718faa36de5e7f151715c8bf4a22964c1d506ec9cf5b5a8a514f97107699182e304cef9d8f1e660c93fea186c01acc +73616d706c65 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 89a3557b792483dc667919c0cf0c5a31d91093e57c58206e169a078bca42521707444784402dcef656d5d81c6fa9997c18d23b2e84dd1c659080992463b3aef510383beafc1ea7c378ccaa125ab24a679a992c4b3231b0850e110f04a27f5e9e +74657374 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 898db0233b1868406cf088b3cf0143d012fad975ac112b43998dc6d0291adfd52c7ae6780ba02f95a18396dac792bf7a11f6df670b9041a14f576dca314e8c28866c70d7a877b7b14490d764e1c8797f38379195007fa9032f345a94f9846ad5 +73616d706c65 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 b4349ae5d54bcca086598750b684e0240dd780b0d2f6b8ba752f3bdd3f204e2dfa40da5b4cc9a8907bb4d2d70e41071d11cd75786978c44ce38e3a6658b0a0d13180a32c6ccbd99ce479dd0f204d2bfe07e3c0a7b35292a90464395a074eb4ce +74657374 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 b5415a542eef6072ea80f346c731835bfd0772774fc42559c363134516eb7fee34bdf9e744638d89e71d1726a2b5f6d7140fd9b6d76ba4d9a4aa79c889fceb2cc7b77bd56935fa3e4a34b79c148a919d2d718c0b544b1dc7ea4883a7f6659197 +73616d706c65 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 862e9a706cb8f5fa6fb1f824a8412a20781dded101fb5ffca0f2103deb0ad2651ae4fea1a05efac8e8e63fc5b6adcb080cc52b0db3f1c98d0bbb9c0fad3e1b55903837b1ea5efc4a8ccd4866ee0b602ca681443bc882f361793bd2976f5fe515 +74657374 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c b52c41b705ea23632b8d9ddf9dd9bb4b61c11a4496f925fc0cc0e79faa598f9ef40073b734dd8f4805a4f92e1fe148df19e6b1ea64476e1edb5df42104165f7d933adff693c4f715c8bd12f7b3c7468656832ed4dbce26bb9b361c2c2cb0fb2a +73616d706c65 035318fc447d48d7e6bc93b48617dddedf26aa658f 873b741c022225eb507d81087c7933ef4142bb78d8779f846b829c012ccf9694e5f32ab441dbe1e02952ed81b2542139137d243564c6a92e94562cc341c2e16a9c595bec474cfdcc5f953ed38c32fa8c5a713ce03be9b96ae08c4fcf26ac6bd5 +74657374 035318fc447d48d7e6bc93b48617dddedf26aa658f 81691649a6459b31c5b23050220492689fdcb19c628b4c1e23ef8ed0800831c3b5dc5d9545ab46bf3ae74a8d866a76130c43263d3abb8d8385714945db8fcac6af4ac02a9580d5f8f402146cc0f6cd62fbf841aff93a706f95cd2a976b271ca6 +73616d706c65 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 81c1cd77ca20a2972ef16a67373b18706a42afa3b593fe6d715756436f21b175c6cb5b5eb0f7803f047fafe3ced0578e10c46a6dc08d37b019d24db3a1cdf26344f06070e20df202e624df9c04373708f872dc5a47695b519c23844dfc723963 +74657374 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 94e51da577178a150d591b30d273d4de3722fa904a1fcfd13473c279116dac63a45b2cce6acfa48830bbacbb741d532f0c52a67fa3e78460442b0ac0e89acd282ed94300819b030eff5007f9e6410bb03d0ea0c6143060c288aaef84472646c5 +73616d706c65 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e 9508f59d6a25f0f009d4152142274428e8a97f534ef4cf8f76f0f05678b9e22fdeb133ab2140d03b86eeee2db8847e0a08873950b832e13be934b6fef299be291190787cb3177467622145c43d1d3c5d9f7542ef1fe08086def6c6fa75c03323 +74657374 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e a24d27296baf154aa84bf584d62859ae47b9dec9b367c2f5e5e08c31fa4e86a31e59fa0209f35c7f6b99a1f7b15095d008b73129768f4c8ffa5fb5d112e14236cf1383322335e9ae5dc3d365a70560816a4fdd0bcbc5c054397abbcd25f1b58d +73616d706c65 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 b2495e0e5041eb0bb51e8a516f50603aa77af4284cbf19f47215881952ba42c397952b909e9605343fe6431eca3b672719cfd7d25a49d315c0df688dbb97b3555c2083911365794214645edebfa2c937948ed998b164f657cfcb83f262f85d10 +74657374 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 b6d510c4534ed95a31c28c65d8f70f136f76442fcb629e5e8dbe10626512f79d0f9f3920ab3a57caf7edfa78311db1121735d7563d23f1f1a6542fc0171ed37953ac3e488d4bb235c05a5ca924a6c103fedd275cbbc129537b1fb767775d7bee +73616d706c65 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 8ff140c2251f3af0040d2cc29b506f60cc0f030e803e9b615ba6ec6852aa43f936811d3dc9770fb37f28a3172a2d22c51119bf85bade13352b23144462699dedb84b2090c54d6b77899c17300225d93c5bb7e3bd15d8cc57b729553b2423d8c8 +74657374 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 98ee28c6f071a33a4599c1e3c39dc3245e9f4da4936ca0e32a306ea1a6e166d1b0559fcfbb13a73f97911d8aef9ec809066313c5b8a8064ec7c3540f7ece7364a2eb2c8f5febda53d8b40b92d9c06ea91fa6b57ae19061b160ac498c6738054e diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_rfc6979_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_rfc6979_blst new file mode 100644 index 000000000000..54a06405aada --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_basic/sig_g2_basic_rfc6979_blst @@ -0,0 +1,34 @@ +73616d706c65 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 ade4251a0136ccd502d441e47d2df8462a96cc85ed1720b85a8bf2be1aa49eedb96f73297302c5a85599225896aef1ce028a459addc39d8617b825c65119ff8d22b437b70c8c36def6411102278274816a8c585bd31f8ebfd0bbb3bd66a74a33 +74657374 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 b184d62fe3052488a4a56c7301988db544f12b4f8f34553f4cff2c3e39322893eb8e34943487c1d6eead742f6797dc730e22c4817114d69d3bdc83e3c8eb2242d8b844d5c7cb56f0ff14e6e2ce5892b842d7d653b02e8fc63bfefc2941f2855b +73616d706c65 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc 95e3db8cc3c82a77a91d7b9a5b0130f0d30c13fad7f801dcfd1c4add5ac65cd8b60d10fbdb7723e48b4637ea8faf17420ac00950bd1831e0a0224cf47a6e1f7e25e05300b0b3d265e749033dadaf105b86003505c914de215347389cd4b84821 +74657374 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc ae508f75cc3de4ec889e8b6ad678ec707fd5c7841fcaf4ebe0631de2c24903df00970837c65879e637f2551d4485b4260956eb005e2d2c610d0dace228dbc8b09960e03398d474413eec474be929248692d50fff4eccbd30c35065b1d29828c2 +73616d706c65 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 8891b7054f731cab4af712d3bcd51d23158c957c2a4f59da0c9fff50344f9ce756e9c7e11247838b3d3a21e28f863f0705c0957b81cf84dbc35c040c6cd2c706352d932592a53900e11c59345f4b53e60361d7fb4b5f9a56e6b06de73cba1f91 +74657374 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 b2be787378d0871fe5cfbe3118187fa14e1228abf8cae6f07370f0cd8e498f71747245f03b991d5f9542294a609234770ea5bbba854e37a87435dbd0e03f60cf1e5f16d5fd1a44b6908c56761b85e85c786913f0b490b4f85d1a5e0b679b2c25 +73616d706c65 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 8facd1d63ae37ef863fa91947bff40b6d108c55ba4a0b9808a8cc44cdd776a72ce28d61e8251cacaf9cede95cd0792be1750ffca14786689a55723b86a29cb223e85e2b03da184c4be7468e509f93c9184aefc7aa9bb155178c38ff86702dfdf +74657374 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 803ff119daba856fb81800fff41fb1e435bd3998904c342fa024ce7688c6b518f943568fc7af8803d804c47962e35b4b0bfcd5de1225f94c239ab7180fda593814618e4816897b8d6c82f9ecc2d9976742ec5f868ec63b72c6db25c986c3f339 +73616d706c65 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 b101d0d41b3a063f18d78ab2075ac8ec5cdab4de1905c4b729b4603f4a3ac43ec14aa7009254fed90e65e97e8886d6031454ef4310f8b923540ee53c957228f3689ea98106b3145fcd825c376623bc74ed3e95becf088dea0e9cee101992d723 +74657374 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 b6df1b172cc95e44e7771ad0f6bfa25dea275c08a4ebbae69865f04c803d91368ee032754c290aa81c14916d8d1ef9b506e80447d1f3da165cf06007966b89e66805f327cb35d0690050b4847cd396f54ecee822db7fc4d63bee45fbb02fdf11 +73616d706c65 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 adb00da06ce1d7b96a41884209cc533bf157efe12811d9f81ef888f5d465a6d9241f1d79f568a3fe82b41dec9b50a8850a2edc91ad6e95869995dea4e186f33d0c92763d84dfd7ec9446f42da55f99ee375b726b982ae73a402cbb2f25e194b9 +74657374 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 a4969b7c5e1c378f0ef86c15855580156109f66d180bcd5205539ad412d620a3a4e7a62e8ed5e280d06f158b1ed3b03b0e6e8ee856f5b0f4bede0a2560e13530f44aa289a17229cfdfd592f3185618fe4a266ee77aef869797ebe25ec6122d71 +73616d706c65 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 86fbc850f1f8fd3cf430e49e4ae439e6ffd0f1d5ff88d2cea31c092fc08a7c29fe6c9b427f3452edd87f54a7f860a32214232336d0c0f81540857cc484626ba32d0e2f1f126c167b144d44ba4a08250086374a80fb2c531fee11c30c1648ab54 +74657374 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 8d44b1120e17908ae315f7890c1e380f40929f11d124e66d2c800ad8f57c3369f57bf2c4aef43d2f1fea5a7c7983cb8914f214898146ab07535f314c61e202b7faa4616a8cfa89cd56368658a0d7eb407f3250b57e19a1f15be461adfe978d4c +73616d706c65 9a4d6792295a7f730fc3f2b49cbc0f62e862272f a722107028252d72d593b39a5fea68593918e22ec8a906ff15cc9dac55f6728ff3ad571b3131eeb39ea7431ab9cd107d11fe5f4e6bac7f0ab0618fcf3ccf4b42ffb39cdcad298b1aaa512f561f72bbe47237bcf6ea8a547ac22db36ef7e42a38 +74657374 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 8add99b019aeaf101044a6a5da041d0fcbf0e4dea24c3609230f01f24a98f818a484fa92ad38927398c55263fe0899690b9bb7f711881dcc93ef50bdd17efa61907e9ef1602eae552b9e9f7386570b5ace04dd7e5cba947733df750499be1e0f +73616d706c65 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 82087401a34e17daed757f8a6bb5c313053690e6d28009f0f976cdb7fded3d914f4cc9150ef32787add122b9bcbd8e1915d96d9bc436e548c86f7e227ed622a6337bf65ad8b994c1df1c21e198fd6e9aa41391db6e7a51bcd1ebf81eb77e1241 +74657374 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 b2f7469b7ffd2f9f2ff9d261eae13ea215f25a07fb0c0f074a6216aacfe1640b7287c6f81a2f0064c4d090021a20aa6416718faa36de5e7f151715c8bf4a22964c1d506ec9cf5b5a8a514f97107699182e304cef9d8f1e660c93fea186c01acc +73616d706c65 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 8be0d607bca5185babff5d455ef7f7a30aada190c5858478157dc37f47d9480406d84da5f4cd72adf663fe9376666be10eea7c358c78cfba04030def2c4ec1192a276b77f2c085e5797107ef592727c2b1f863d948c3b1e4985e09f67a0abe61 +74657374 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a ae7d34deecc294253327754001967d790dfb6ad70cc3364197b00ed6d260d0f7882c8581203cf9dbe494e931e82f9dff019f9a4fac149e858a52be79fb38061440731a536a78140ee4137338c83089c656176d56b4a594619a73aeef2a93dec0 +73616d706c65 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 af5df79bc899bf24771492401d3ce9ce800e65ca34db46715d85d721c1dd9e98f627415b29246a833d4f180334b857db07aec58162b3578ca1d4f061b9e313bd924f45c0a41274af70d5ed88f28281b02f2c14f26a6fccb3545b42726c5bc0ce +74657374 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 aaf75df913d297b88ba928e3a88fea5dc5572c668e239dc4e345f36905ee02aa1c3344b4b0c11f924332a58fc2446b0613f0e0cf41e6373c9a2303e53bb4c20abc4d6d188f853aa1ab5deacb851cab5e70d9ce773f9475d26954f70491f78db4 +73616d706c65 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 807f6c6a6317df0137b0b0cdb3af9cdea4a5f7e5fc0eee2fc45ceb7007a05f58e2584656c5f8dfbd06ebd283a32d0ddb073296a741189baddcc94ba4c42f00b14a9866a3dffa4c9a8d8f4f7f47bf87f9423ee0d54ac57e088c0e310f1dd8c73e +74657374 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 97087003887afc5d9a5b11737d53fd414d8a2b6610124eafe883bd6bdf876899162ac7f71f56b5e2a5e784a7e5bac6c109edfc44ea895b24a205cbe24cd197ec6a16e83b13ced1083cfa6240128f8be6cadf79bfe106d58b678bf9598740af56 +73616d706c65 035318fc447d48d7e6bc93b48617dddedf26aa658f 873b741c022225eb507d81087c7933ef4142bb78d8779f846b829c012ccf9694e5f32ab441dbe1e02952ed81b2542139137d243564c6a92e94562cc341c2e16a9c595bec474cfdcc5f953ed38c32fa8c5a713ce03be9b96ae08c4fcf26ac6bd5 +74657374 035318fc447d48d7e6bc93b48617dddedf26aa658f 81691649a6459b31c5b23050220492689fdcb19c628b4c1e23ef8ed0800831c3b5dc5d9545ab46bf3ae74a8d866a76130c43263d3abb8d8385714945db8fcac6af4ac02a9580d5f8f402146cc0f6cd62fbf841aff93a706f95cd2a976b271ca6 +73616d706c65 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 81c1cd77ca20a2972ef16a67373b18706a42afa3b593fe6d715756436f21b175c6cb5b5eb0f7803f047fafe3ced0578e10c46a6dc08d37b019d24db3a1cdf26344f06070e20df202e624df9c04373708f872dc5a47695b519c23844dfc723963 +74657374 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 94e51da577178a150d591b30d273d4de3722fa904a1fcfd13473c279116dac63a45b2cce6acfa48830bbacbb741d532f0c52a67fa3e78460442b0ac0e89acd282ed94300819b030eff5007f9e6410bb03d0ea0c6143060c288aaef84472646c5 +73616d706c65 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e b7abf209f7fda828e120228046ef40b3805586dd4188ed5cc1b24a1e222e552c72bdb3fc23a0f3b577b328208143ac7f128cf444e4d3912b914ff9e2d335ad1edcdd974eae0968eed84110115f577d6d220b9189f36c34c725192c7ae8c78e4c +74657374 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e b058b7742326e8bfc91cd8f5e040719c645effc61ae15a104ca75eae0d1d2f690277e7308bba68eec30ea0b723e3cb931314eb5be051dfc4ffc9919e704368d5fe784afc5850fa373bde627f648725b662ac2c0d5cd0cddcb2520a9c2f2f8c74 +73616d706c65 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 8a3bbd53851bff42ce7b6a1288b9b5cc6cea48c7a0c92d8de5db95529e488e78e15e1e8b587dea6f0332d1c21ede6eeb161560167e96d0ea76c5778cdf29c0b022bbaef5f91aced96e0ff2e939578b6d04812ab32d0f14964c0d2853a9fe9f9f +74657374 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 a7c0383e4d0fb8c1ee08cc56316c327ec1be11bf86c878c4ec85659ffcc80c89fa91c5874af4fe136a3a507e8703f5181833b57bcb00ac553766148141e6cd11b6ec532a0f716ed1f8efa0abcfe5234e2d754c80343fa42c166bbdbde614f41d +73616d706c65 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 88a2de60790c221448cc501f67a598b9495ba9060b2f940db8b3ad2f8847dd91d344496a917c02490cda492e9b9c309e0cecefcc52fe66713976c9a1d23196e5810c6a5159ec30b194ef3eda8df262ba97fddf2e6db1a2baee3393f29ec2fdaf +74657374 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 9757de44177fe581dca6b21f1a526196402b593a8405abc6404afab0ef99479bdbdfac59203f42c420429c39ec12a03001597b4a62744b96b1fed2a422bb10854e5c511994843ff76daecec81c5c3622c6f8004145db62552d45a074ae08b0d9 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B233 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B233 new file mode 100644 index 000000000000..8440e4f8b358 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B233 @@ -0,0 +1,60 @@ +f1b67fde01e60e4bb7904d906e9436a330c5cb5721fd4e0a3c75b83dade868736bb1d21cfb1b5c6407c373e386ee68ec2239b700e763728eb675a153b8ac44cf2a87be85fe8ed6683430cf4b7d718891cbf8d583d0a37cc952cc25fe803a7aa4fda80f05541a2f1f2601cdd0c095f7110f2a84f7d641b8531572269b21cbe77b 0056673197bfeea9bd7a8b820b4ae51a50411bf118a692bb9ed3d304da53 99e7c4e4b49446b46635c58860c38c6ea0d692d542a6d5903bba46b5c2ad26ebed35b3b02297766256305f106b00e114101e0d631692df60bfc47677c70b4a35a65938304f8885d647b76e61df90f622159dc1547785889fffdc757e8fa4b3db +1d496d96b533c632ed6a91f6e3653cdffaa5b8cc0008b35e49b2dd52fe261105c2ec7ee71a4ad5d51fdc3d36d688a3b7ccb3b3b0c3a65be17b8d8aa172e3005cfbf37a2d1b1a6e268c090c6f318e7e96f9ec9b9f5a8fbcc7558d89e840f7e76e44bed91c26ca48e6f5cbc253ca2fe8cb81c484cabd24070e488f9c00cd96ad4f 00468f01d483144e514ec257f2e5fdee28a927f2adb19714c1f3524dd0d3 8893cdabee59ac858efdd48f4317a285fb6985103c1cfad8ad2a9f8e3400452a822c5cf019c2db9cc380471f2774331a0147f7f4733e1db535fedeb430f48dec11d72201bb997cc11bf36da3535293f7bb1c4bcea4cf762f6fb968438ea70b49 +723400655027f474446843645757f7e2cd466bf97275067b4bc4c9d79bb3b19b2421835d69db916f24b77c381fa771fc1e7a19d2b4d09411ae55acccc615b16fd24705762b441ab67083a921fd4ae569ce0de69449aa96f5b977ac7dc022fdc8335656853796f54b3fbd118577f98920624eb0a00204f1ef83827245c06646cc 0074052d027f05465a8083a59cdbf32600224e1f563f653b34314651517f b2b02653e069f8ffdf2914cfa03e7a0ea7cadab6d50d6e7858eaf00d521b7e62b23313ea7fa7d1601c0e524accb8bd87023a8ed7ffd136c418f44a1020854154622a060dc2a71eb338429175e446d27656c83a90837666645d7d0ef0571ddefd +155860cb31a142082bcc0bad828d747e916392d21f1873b3a3c1d28ca3ff9d45ddb66a712e3856b6afd07c8d2b2a7badab296a9775b03f6fec0befa2d8d6d00fe3938df244ab46e836a3e686c8b4f918da49f0bb3940bba34a9aa22c7caf02df7758b0de01d9f47af6146344b9be3842d9c055eaf0fb399cd8db95c544a62d8a 001856e7544223f55f80de72a6ef3822fa8fbd68eb397d06e2d76ddd35e0 87c88e142e56af0bfe7ffe8379bc36fc7a32eb72fe0be4e16053cebd81d93eda6aa60a680359f30f6d9bfe33470b04c5049926dfc984ba04bffe29d74d1fba795ad234fb013ea73c912ace005d15eea4b1772f190d5080b0e0c37b18856a8e44 +cbd6e305cc9f0dc90caee6e65a74582e9357bd25c78e33a7b14e1ac7e9397ff4466f192fb432143e6df6d61a0ab808ec0a361a6d95a357a38cd3e241fe03ed883ccc364b248ee2a08702110745c2688bdcefa33c1a45b9c8b200e45cddf3e3f66b8d37eff07fbb3366ea1558ef304085613c56707095724b3e134c7a7d3f8dbf 00860aa2b589f2defc617be73e191502e5d9952bf60547fef19eeccbca26 b8d110f9e14b6266383c801f78c5243c793aa109167e99b765418ebc1b939f1a148f2e11561ebd7bc5a8c933ec95514007d5d90d995a74358faf864ebeb2148d5078b63dd9da418d62d554cba8a38825ef323ba3242ee3e32c6bc1faaf92e943 +812a218ff1ee1472c189f63386e5b8ab341671c3a4dad27a8c6249d1c0f9a29338b471b6179f17a078b6504e804ac55ca3b13e68a623041bc1a092ea2adf3fa1124bbfeb161e6d7c483433f1548763b84da00352a6386e1339f674d45dab13898147ede468e0e01d2c4e0ed66b395a16cc3ded3e952ac739205f35a83376cbce 00d0dec052a00ccebd0c0c5d9a08272f75744a2582cec7ddd924a2b022b2 acca4ee203d6177073c62f5fe7af31433446764f7f5815fe7ab9dc5cd74be6d2ec50618aebdeffa6ca8b92c21070d4f00068d26f58c16bca09855e1a7d91e1f6c06e1942f614a3f450fe7f7c6150911b5996351c3c85c57ff0360e31de7cd754 +0204b1fca831919e89e108cf140b3770f531a696b1d9a4d1fb68809eb10afccc257cc90cd36717c02b2f3d6d3d1d8a93cc5c48aa7ab9f9fddfe121ce9143376535a0c65e247c6558eac49fd1d6d1bf431ba918c471cb3d536ad485ec51f6471a340ac75f160c4c54cd3ffb9dcc123124b42df1fd2eaa005e3377c5d2d55938c6 008a017d717d6d1213f2b74c53281b07258738c0c7db649ea1ac46b9a3b6 b110f99b369b259a1ab815b89c259e9f193306a63c0d7b340327dd258c29d39a5c03298abbf86f8bfd1c17f25dfe4c3404ecf88ca2a8d65bb3894ee1e961e8cb16d5f24231896a1845ddacd97b1bf50483c0b844c69e988d679b9c18215cab28 +2033eb48756638cb56e2cc39a3e775cfa11fce86cf71f04487dcdbc7f262bc8350a30ced54d1fcb697b28a6e96f88f782947c997872307ed963e1d68985f756435af77f57755cacbb4c6b50ed419deec9f39f0a549a13e54254fa0a5832dba2d943ad4aed8688889a2dd29dcb4ea12abd6a6c50eabcb3981c3a0c1ca5f0b9629 001b56c14442b084cfd22aeef0f8028ec57c8b571c9fc1e43de05c45e47f 81662ad31c6c88cd7b022ef6a2d8cd821cbf82da68630bd0d4ef9791511c25dcd66680e3130fd57f6247fd218cddf55f01f374206aa236f62f428c20028a26970823c1902b8cc4494edbe3e107dd3020ea08f071191b111ca08d5534192c9b57 +2986ab1cfe8873009e932dc68d4727d77ccbbf378e43fe4aa7c54416346b036b89c0aad1b82977c9fbc39a00f1dc916c0561d8dd70298c02b6cbfe572e0ef2058641e841c6875e8515f3c1082765e046c90c956d984b76e0e8e6eb433ce26c1757ac5b13422479141971c20102e9621d18f51096ae3173c2753facee2862d66e 005afce37c5594586ac46a34ae291f591eacb9880a7de92701977f447fbf 8cd8538ab0040b81619f4888b694e253e7e8e41159b0e4c56b949b46aa53071f4ec06834ebe3d65779a4e59467f87c590e791ac367ff4b755653a413befd9df89096e3b24399c3a98d05632794d9dfed71b13a4805bd9a5c4d4dcd60b9446ed0 +aabf5aa90ceef91c2155f90660adbcb0eedb996f5242cee15468ae217058ebeaad8cd4ff8cdc754a8ab85ba43c59fbab6386686fad5e27ad3848fe52191c7e4b203720841501792a625aef2acb6e36493b792fa55f253effca682946ad8c77e01f44e92ec3c258d0dd98d3183f4dc4a0bd3eca183794abd6232a6f9e4add8f57 000696df05dc7a54a9908a73eb18416a155cc8df4ab26032539d86eae537 845d56cadd40c8888cc3ba93fb2f19fd93c2ecc9b40df703e3221824729f18d73ca0badd7d7318b1c88c737e4b69d313055a0006778806ce1a0917f047ccdd7c0e554128b7694ac567e12ce3b24a2fce259abdb5af59ba3b5061a4668ecbf959 +29ff209eabbde02b10b3fd559671fa53e418750c32c4a18d31cc0186d1077581bbefb8770ed079f536e866414a07431ae6633955bf42a2389b6f8a565d6e4ffb4444336e0030093876a26d4e3106e9ac697788e41f8a21c755eeb86a7c60f18e5e1069f16408a4c375a6a68d42959f2fab7ac09736c7b37c80c05897d8566ce8 005ca31e88c5b2e96e433af2023a66095161710628e7bfa428944d6676b8 ad4b7fc367246120865dc2fd467a72f7b38365d3f1c3d66532220fb5a610528b9d5cd4834b707647c53220bf96a046050eafd359f85fe6fa3b95726bbf8666da4f0b652b5d58866a4bc6daa55a3dff87885d3c6ad2579803304ac50797c973e5 +97765d876c80819f4004a36d09ccba78e600efc71eb7e869d3a00f658d2ace6769c7ab1ef590f41fb070aa8e08615e138df45ffbb6473d4a86ba5fdf17dd6dc9ea9ee19c0332563c99e6a3451c211d286d69102b47bfa6e07d468d9bde82e5c2063fb1ebbbed6086f542cf68ba46d4f214634afb1146dd5a6f3d50912ef5b824 00ef8fe84727a2ad8bf4e646ef28a492adfaf785a3a2ba6e6f985c649a8c b7d4805239ad8017695f9f613ed4bb4149583a7ea4d97422c466b967126fe802803a29689f63d5dd7e5e8d2b2eec0f8305bc1e4b3c9b4feced3ae0d01206e66c8f77669edbc3fc06b3a3d24608689096edb1184c9f054e66b9318df2e9a97368 +21cf768d087d1e4eaa8a05e2008020e243116206d675c09be42ef2bc93617ecbb0575c873c6510ede9979215531b62126552738862fc4323d487992754e39d8f0d7e111e165ff254200e05082f59a57ef649bccaef6f980094fad3b7ef93bceb161760e200f0a2e396fbb6b6142dc84d872311bf932b84616b22231747937d58 003edb94b8c62f9af30c14a790c0f5d65e362a21cd8569b9725916d534c0 878bdbceeeacd5b738233f819ee94b3eb7e9fb8d7096cb825aee851ec0affa3f3f58d51a96959487eff99e1fef2373f4086cf2ef8390241eaf0e66a2141ca0094f137017ffdc25a982618e62005fb99674aa087883f1fc34675b348af80633d5 +7b8e58eecdab3e40212bba6bf284f9379265b3d2baec3e4625aa08d0ced851da193c292ec793dab42732c07b4e94d8b19c83aed796a7e3a6c2b954a7a9a1ff9b2bd4ca62592c8b68f709f1ad38a5c8033ebb3f33d176945bfc68e9ef2b0cee2d45a13ce89d238a33c09ce2c0c63c4233aba5717b85c4c161dd7648a41a5e39d8 000a7519be62562318da1b67d22cf8e720353d22641e0cee11c7a352bb93 8ffae5c4519cc722346428e1f1049008cf0099336b5136d1f134b71c5f690ddd9d6bafa418ee0946f11d77aaabca50ac0730243571c238c6270fc850221e7ead07ea248a123653b06b73213e949ccbc7d8e8bd0bc232c64cef5d3dea3bfedc0b +f8f268d2b04fe47e5052c8d0d653787384b9654f0bd2138a6f52b80713feeed452b976a90eea4edcfbb62d04f3eafe172ddebd7cdc3701ecd6008e3d82e8eb217b13b5228839f61075159f3bd1e1409c08903874b6dfee2789dd72c208ae769ec8c7d52552a2b1fd73dad24de8b571f88e2184d0ee7d063a121187f97e746f2f 00264022fd7dc2328a6436b522793ad9406d7a586667a0daaf1bce927338 ae79eca968cf3c841143bd50d882b2ced66a750cf59c5478f224fd88617a81fec513837cd3375e0f16d69bdede6f246e178140273cbbe357c9c6d15149f99b4a069959398bd6a4e65de94fb856dd649c18c106f9c2dbc13863ea09dcb54abfc7 +d288768cbd066fad4bb2500b5683fa9e4eaedfb3dbb519b083f6b802efda0a022355565c5fc6babeccb22f3adbbda450ce5d633193d1431e40c0fe631a295cf85965cd3f5937b31866bd6a5300eaef9941daf54d49832acfceed90e572ef34ccc94eacd0fd6b903fee3c572b963d21e2881656a214d2a4c125778dbe3bbeebca 00da43214e2efb7892cc1ccde6723946d2a8248a6b4d6c8872fad525ec3b b04de67542b15604cce9f35e41f1c3d8479578b10200a8a6887932aae60f5afe2962753711e1ee238d3522728c21bcfc165458b0f74992e3919e5f01133b0e4429143842550fcaf5b44e6561d3fc7673919e623f20800d1d6be972c57ec46c35 +bf0ab46e0a756c11229b0ea961f8d57218be5b00ab8b0e91d7664cdf5e0341c412c0e992d26ab12115197db39df2d1a6e18ed26a91be461432a2dfc21d98cb16003e339b0b0b1f100e4e6f4824ddac5442f22a1fac26326ed8a89cc91343d7223986d485cc8c64424e84d56be536c57e4dc5faee459b1958efd79e07e90a9811 00aeafa49d776b61f6a30d66ff64bd40dd8d79891dd5293c1b5cd3b46a7c 85d2b59057bf22de2476689d91f716095a719f644ad1dac00422aeb5475b2ad49f1f593c52e54bee2e48f5765b3167e20d37f2fdb7ee15459a13fee2fd12e2409f287835bbb21114c53cde13cfa033cc631be8bbb9d9276f125a860ae646c2dd +c7b1eeb7c19eb16e7f42b61d79e421b71de797a6cab4e0baee522fee7acdb533f7bbf5855316544e1b82b4f2a18ad0a2311e7622549332122171f32fc62a90e408207e0fb90d1b052821dede9c41b15b6e07d84d5d7b9e31e6396a8ed229fb6232b3051298dc5321aa589f4e289d27169f14c8cc93644916d9b72dbc92c43488 00e95db309f4305b621f51f93588a2678cb19aad0932f365fa0aaa3a3895 90a6bd9e795e3a39e86376def2a23d0ad17023d36be5e62904dc5a7637017465d971018bf2469d0a3b360e25dfbfa4270361d702d350b0380865c7fb8b556e28fe2ca9a15c0415ede417d0bca0da8730794be874156b8e0e5576b315f1118f18 +a738eb074e1f277dc665118ca055e6328059ab26da188c16f56384c566e43df8cff3d2a10d2d15c3c1406de8f734b20be5dd1ce937a4289f0ddfd7bddabd03586556eb8233b8feefedaa1f49bdec6d45fd562c2a83fa9fcfc2013bdd77900857199e51fa9c7cbeab925ba8f6c3c5fae46bf8e9c574b302f1e5f9c44400152a78 00d4319cc8e409b8755880827f3200d3f0f1c64d6356fe74eb1f5aa42499 b10de04bd342c010426573df9fc6be9a339609ea058a9169238f280d62ba399e2129e0c0f3ee1bc43ced0f8b13aa07d90273e5bc5490b0ec4594af0e335a1e61e961466ab56ef1d77ca391295435a26860a842b54ca29f288bc972ccd600a084 +b28103d77e5457c42e026e713ea6ff03722a36512da17197140117442a976f9e2139c54a759fc26af5811b455e5a0d3a95362d9939c1e738045be9237b469ae2106ceed7e7842b44cc0a475d5af6d781e32ff1dd1f4e1833dbc7f82b27dc7e1562d0e29213fd8911105104a7a16f665b926aa137f70d868c90e72f8ee2c95b64 009e556c945052e5954915c773b2d47970c521fcc99139269c3ef46093b7 82cca7c463f40eed5a43cb0f2a4d06ec842f88eb2b252a100b67f6e3a0ec9465fd15fab1046dd99d49b30cb5b1a6989e0acace7b8ef146b7880c01835345390a50d40581588c3fe0bc385a4508d6be5057f17c8d4a5a07477b187d2320456d49 +463d04c84521ae671bb35c0a7acb3ae509b1b0470f39b8fe7ae5f3c9fbadbeb2bcc3a87e284cbdff07407a351f7ba743aeac50c4a1fef7375b90eb4af8ea2df040776bbf3e4389e7a80bea40530842642b9895ab9ef5ac8ed6c9ce7917d7b3ebcf80b801da845943313988c1970e7748cc306f914c37414f8247d648b580000f 00becc76f8a77615c4f92ae1f91645bf5bb908e75ef22fd544aae63a3c8e 852bed5b5d3d3d97591644f7612db3dec04d6af6fda4b26258b444ae7c14f8c52f7ae8ed35f050d9391229d67ee2e3d414a7f4ed098b8e350e6eb9b2cd474e9306065f17a96d5b9d26c79f0ea1a705c43352b4dc315b631e05164fed791efc42 +8b2379b5553ae7db6023cb010e26ae91322bc3f94dbaa369481936f90a886e5d3827d995ccf03ca59f46805fbac0337d31a8f117cc7044218a934d5bf507090e7e21178a7162c8fcb39111e6967803dbf9d752f3ae737ba024d0f4f7627e08be58efbe997a164106bfe37f67d2f19c0fcc7a6c7eebd96a72582a9c7bdf881896 0020572c2a3dc3ea430cd8cde9d642081c21658e8bda165550cd9a5d37d9 95167da2037d4b1df20d3bc291fef42c6e5a40bb035758904a670ea881d0d1ba8592d516898fd4673eaaa505af4539750261da1aa1ef40c8754e6aedc140726b74e6acb529e694579fda2f1580e6bee399e08835a60a8816c31933d6538d0f65 +3090bf7373731cc44c00372c1ac59280b0f36e627ccf763fa68a7be37bb0ac8cbd4f70db54fc652566c78ad268f78f015e4bb1e41516fa56ac303a3bb4a52e1fe897d8338db5a6e37cad685e704b994504bd231c7dec0002dbd907a7ebfa809833e32eb23fffdb44fe4a18e11fa19d67356cfd703cf39a75b1a290b8a7c73afb 00769cfbf2dd8248ea1e0ac9b275c9d6ddcf923fe762079b9ed62ccbaa89 a6df7ff05895450cea6e089079967370117082a96b5fd5bd63cf32a980ec9cb26f10c4682a6afbe324c389de9c50d6f50beb30f178322b2760847f9dccd8a9afb6d428e9dca217d488a511eec658975cc7a9665b9c29eb3f6f5a6e61766d3a5d +c37389cbe3f46eeebdda343e354ccd543e96b0c2a87e057aa6b9c4895a403de706d658bbc9066c140e50fef4b56af2db1f42efb70b8021254649983f1e11d04d6b10169d5a1c2093b6ab89227b88a30537c776bb7575749c3ed87bcb29effd8e4f17915b4d5dff6cab9678d88f33abead1e73dbdc5c3307ff3d3b2d5fd7bfa83 0040ea4a37b388f0cc464f7e2bf92173107b268ff77a8acf5f517b4ec0e4 b60551c897eb453ec3a889ae562d523cdef7605fc216c1e1fd8897a43c3674b8e9109d5ee6fa8dc9fe51f8b1e8b4710d0075152d38d3063dd4f6184a860de0e9c2c033aa1a4495fe7da8f84fe293cd07f54b94bf77c25bb1042b32e51beab249 +8884def8c3b9c5f856b9c2352c85ea71aae3c8d0e84ca74e70e404a21467159fc9826548d16dd1ec5a75dc2c23ca37b30312f25e1194e0f9385a0499db34c855412bbf58979ffce7fc3afeb7b8dbf9898df44023200d809f520db99eae315b5cf85674fab008a20340fae8f6974034fd3e55bf08c5522a460680218f9757e368 0037fc7898df9b37b5390537352f5c0b8de22659166c19d7d4df31c3938d 99da8e381457d012a571b17f1f86e356265e9833067dc68b48b6af8533826304378b8bc5481ec1d315c426c4ab698b840a01577c184b2ea8ab43f6ab870121bae5dc8c394f6b1463ccd74167992db6e6fff25e6688fa94c80e8a747dffadfb09 +f1fc154d469433f56c2bd42aa52237a4a4bfc08fb6d2f3f0da70a62f54e94e3f29c629c837e7adf0474fa8f23251b9b349a16848942c0d9cf5db1d0fd99527020dbe21cf0b94a9aa21f376bf74da72d36f87b306b0696771efa7250c6182b426a4500ac14de4a1804b38db8d4f3beefb8c9bb619ac82cb63fb37c2e1d22951f7 005d5069425e7a9925d2cfc6360a708147b2c1b55ede243591885147ef3b b81aa3df8cc4d1db782686ff033341d72fe4ebb59a509540f33ea47e6591f452e0dfd99c547330225846b20526cc6edf08662d72d93b84f6412893ef8eb172338039abe081185ff34e3479ec8c958a9ff49ea78eb650d35e54475ceffb52def7 +885cd348f7983a0721f96c0e866821223d3e5a95178b16d18652b4062b1b2278aed6f54ab06f7e37ae6ce1020aa3eb812d215194bcd212302da5b971fd86aee1dcb23057dbedb569bd0bbef80df538da69ae2358cb03bb77c64d3ead475c8c5ae5bfbdd75684b421a26f1a7b0c37548fa32d805acdc91230dd70a48232a12846 00ffe3e7b82ca62b96e057ee072a4718ca20a6cc9a3e51e4fe8ed7b4b9f9 80b6974abae034a4c04b64899b5f9691ec70b87d0a5051e765ad89acbcb57ba11536a9bacc191023a40440c91d486b340fa9460005a166a5eed297d83faa0f1940b0161a883bf1eaa52eddbadf311b4adbf9bb3c2f1c5aa61b237f37b1b2081b +ca3b0e2f1c7db4e73c699f06e432bb0f63705ba66954bec4a259bf31c161bb4861476e2f2f7dde9d841d1ea6bd0990cc793cd7a10432e38735c3eeda7a0d786e8821239bdd6c4972c96c2cf68ec5b935391f963a50fe16af2719c9029943b539ff0f1f5645962a6ac46c75d2037fa0c7cd46deadcdfc66e1ddcaada3a376acbf 0007a9cb5ce27c763646de414ca2a4dcdb774d69ed2bde7a817baddbc9de 921d8fa0395e3770ed59e29c8a0516fa818ae017352d3bfa7d109fcf1bf093f492e21e41e5abfd64faff8f9a85a620b10be33eb650c3523fd6a92a0640d500ee449862a071c52eba26a351c46f2ea2a655ea6e2979211e08ffd0ed3db9a1e10e +4b0a31b746763beee77cecd318b90acf50fac4172cf4bfb354e5a440f651cb89d7a515e09ab19e9850803ab9167c2aee3b395a5da10dc9aff799d73756dfb0a9961d93bc32f15a96bf13962a03d5bd42ddc8b5928def7fc48fb063f42866fc5f96cf88fe0eb125b7c01906ad6a7fdade28ccb0a421ceff50ae03a974671b2c27 00c03fa9e38dc1c697f70bc6381f2bacaf860bb5632fc837f728da959ac9 981ca623c65d1c48b71bcf450816028110bceaad9c70270fddac57ee6165b77c235190cd59bbc05a6252464185fb0a180e6c2062b1e47822f9fc230b40a3e56b4c1b63b2309998fbd47527869a7b456d17e7013c4e96c705efda82ce8d11b9fd +3011d42792b21c0f1719faf6f744d576f72c5fdfd22b1a520d0e8d47e8c2b06823d853b13c9fa039fa30a6f2e3e27bb2100c6a35f55703806bbf0f79b09d0f629f8042ec63fa04062f15f2edb92b19237980005566f02bb12a40b4ec66e4ba6c599d928b33f72d7437c0e399a8e6a9068d1fef24917fc4f9ab5464ea6684dde9 0087dba00e3fe4802e01718017510094924496bd2785d4ac1a352c530473 87659842ac66ec6accdf759f4e09d3ee147b729fb25879160bce7ad4704db389d2f6fd4da7df17fcebd9efec4b83646e0032816ca3eeff8c39ed26c6661d1674fb65384b065d04e4dab8a7a7decfbc0d445e2c9ab93bed045a52805684bfb6f3 +05a5d3a3b79f4e51b722e513620c88092a9bb02408f5f52a32e782fd4923f4fd3094fc5536caf4b645d830260eba91b5173f3833dd65600fb9e246aec968b1f6ebdfddb4059fb2de7e636ed60bb7affdb74aefd158e54485d5f26be373cf944c6570daf8fd7e4b77fad57300667d6decf5c65db99ab8763bb4ecbb09fdf47e3a 005a387e7affc54a8fbb9157b5ebd400c98e2d7bd5c3e095538987d4f8d9 a5d26402cf4fcec30658c4e534956f89ab764d88899cce34bdd211d5101470d5dccc867ed3b50370010c9c141fd9586d155be9d3af74cbf8181c2343d20dbe845ca40a46781df64b5fbfc99506133a06082813241edc135f21fea17c990a917c +247a101c8196eb93a440280650ad463795690bc620e46e8118db6900a71eb493d03fbcf2f73a79bb47aa8e2d8c87ef70e4cfae36fae5c45fe247d8cd0f7d0718dad106526945014b4f3bec324897d8e1fa2f457b8a68e61873b7fa0350fde3b87b7b001c13953c2050a24f71fb77eb455053e49200ebcbba7299485c0f1a40db 00adae709a930d6f5a5c0e3d8ef4aab004d741d23f0ffb8287f7059890c0 ad2d46314c168dac680a27c8d3dfd387e10dfa9e7b6b52809fbbff06b6658feec81a41b2f6c2065cd91168030c18625511905bb75634f132c5b53d6dd99000e547c1a56bf33a5408fee17c587a7c631e643d6b2a34980179445e3ae79ab99ae3 +a16678c71976a3ce3362ca379b3272b92e8ca7085b43752473db34e4d6b61eeed3875f49f3328366fc9d0644824e0104817de458e4c1036636b18b83dbaf063f2f99818959224906571c7b28873d9c702360888df151e9ad1a7003e6130033203acf8a69889be6ebd90816f2abf0764f10be68653b1e56766ecc3150bef8b042 0035d391411e6d679751092c4ea5a079c591e77ebdcb57c1d9006ae70d90 865912dfe5b9fee2e1c870e3bbdbca02794f40b84e9b20caf32b5f1c4ed6c9f31e0830da9c9b1f783712ac336588d9f919b3d03f0360f790a90c56ae7b8bdb04105ff693cfd25ad082b25a6e6fcaa4a7e09f087c8cc54fd0b0b863c391a88101 +bc2f080a7f0b69a6b142b8f3fb481a43bd71d07418df4f3b802568073c1a8d35729ad197f34a4e941a6dd511c63f201d1f6c34a1b66545bd5f43508c10bda1d6ef60ee5bdd25dde975e50c61f76cd36d50ee3bd8dfa2dff59524db9ef12f1e28d109b552cb42f021963f559c843476b5c889fc567b7840297c5a480e18c221dc 0084e79093f1947d6ab9cf399782436e36ef87c59a4c090930c9a74ddb10 a5c827f375aa96bb6300891d46729cffa33f9d7fa1a2d20198297dbebf0a932d49c79972684c751ceb3862a3baa004230414804558c0950ec8f1e6a6788f879b6d39f8916194cb112f881c8e08547ffb226b74b2bc53f9857ef15518f6557c71 +ea71cede8b63ddc5648eb244184bae265cd65d50f77a9e25ff93f02b132487c08732544cb88936d4fff7c0fedb39685822dd1c9be1158f647c605c9bb5f6a1ae34722fa08882c14b36b6c93cab33c9a269c7c10f755b6453ed045ea3e56f29e95a9404ba189a0b48848120392b4dcac43148b706c3d9e4c03db410cbe5dca3da 0079b6be015b8006f86fd81c2792bec6b42c08bee2d295cf9dc214c326ab 885f8c5d6014ad0f04f6503f3a98f6ab879ba28a181fefe502b36b549c503f968125c42966c5c46218f53f4f1a7bfc760bed5594123bc0944f6e3e485d7b6cfd165e2a650ca5936d85e143b17ecfb974609f9723ce84b6b38dd2bfbec0550207 +319b41d16e18059a1324c37161c937e882192cd949c420ce9c59208a0ac208ebb06f894a7fd78df2a3c5f23f25dee6595d3dacb25a699f115dd482ccd36fc54ba29dda279335424c86b07a1b1fa76a5411bcecaf4d37065b229cdce0bac75b666c6626ec37a716e9841be93c907f87453ad91d36846561f284421a89013b88c3 00ca9d751a060fde64336cdc88122819f4b3cd1b4e7df42d495197787894 b69abda7a7247364c6c9106811612343406463d7cd6d93db229fcbd6299a029b3d167539085c9aa17f7a0175abd3e280114cd684a7e8169b7cc8eeb9ae1b687edaaae4d2d2b677c7aa6e016fc430936e4b335abe5d0a7ae64d7d4f79d0fec04c +aebeee215e7b3d4c3b82db243a47506ffbf2263f6fe9de5b69286e8649d9218367c36ba95f55e48eebcbc99de3e652b0fecc4099714ee147d71b393de14a13e5044b1251e40c6791f533b310df9e70a746f4c68c604b41752eca9ce5ce67cdc574a742c694ada8f20b34d0eb467dce5566023f8533abfa9688d782646420c77b 001dde4b2d49338a10c8ebf475b3697e8480227b39bc04253a0055839e9e 8a11ef7028b27568ee0d794816437e95d6c0906e98af7caf1e3564b70e4c1eb4f3a46226320398a4051d7343394386230fb78d502a211ac0eca0f93cb079be10fab5fc88d690bf489f3f60e435ffb2e8e39e8ee9b468787b9c552394b464bde0 +8d353a6b6f35590baef59b638914d3e934d0145b045d221d846517ceddc8ff5e3d28826d3459f8ce1260f705e80923f39abc73d5949aa7aa8ad1734be0e992bff0c9a8f4cc9bdfa430d4cf52e29d3737b0cd3231b72b16e15e1a9040b832e4a920b4a1d94c4964ac6c8abb75bbbdb10825f882ae44c534c7154c446421a04d87 002c8bea2803fd746c874fa110a716538c179c82712f38d33d0f6d037e7a 8ef0d893027f66e807c5b3a44d402b8ad580c463b2cced5da1a97dfd1927e695dc5bab1f7e0c15c7af5d56702311d543111b3aa0a8da194bac0a6b8472400be8d63a94237294cfc30f448463a583af4bc21bb573287663b22f12452d82a4f438 +847f134b90f10ba3636ec24f36a94111f26d58428fda5bba4501e58c7bb55809f52320cbe9e0df55af1e40bbac9f3eaa26a55d78b60621d4356d090d98363662f406367601eaa9eb9568b1a1b319730bad7bf6a7ddf1b45eb6922faf8d065c540b671c50df758ebf8c4aca6f01878e5e0012dd038c58833e2b13ebdb9a9f3fc3 00b9119b3b4b30cbfb98ddf0a4f6953417e515fcf0e5a94e83ebc1d1d14d 91c577e53701669ae41a5df3ef276c33dcff22541fb1f2fcf3e6d28efa7a587baac23afd1a77cc8a4fc189b29134f7d8031fc80ad1f0f6322debbe5d93fc31f74d614575c95a5d0f4d64011d42da312bb1383ece3b75e132a3009ebf3b5d2032 +99d23950493bdd931915e9f9b65e4cd1329866c0071a19d4f7d6fd190689275b7b10fc07503dd1c27a4da274dbeb3aa5cb0e71e9b7b03fc2697729b7be913756e6760098951d7015df181cf14b1e0b954e6260276af553e3e59907794b863e941950718ef154669c5c262946ba120892e0239e05910c2194f712db46e37e53b7 00f4ab2a573f3771d1e4222e251faf14e06cefed544e804c299c9a8395f5 b7066e2a7349bdf7e30162b89be35b0af3a17d28d3c97cea77fd5aed42d4e57fbb540bfa6324e31b6b3d2ce594ca7a3613281098ee51fc9bb1a5aa6d7785a3edd22960115ed82950c6b6481d1264e7daa9dc01fa30bc35cf3416ede101d6d244 +7bef2487bc2bbbcbcc1570bbd4ed437c0dbcbbf63f666a3355aec49ea6ef593da25aefe9ae0d94db50692475425dee3c88cdea975794ac69142c25732f3541457d68d9101c8be069f2b515aadadea2019dc7abefa6c12cb3f76d9f4b5e46546f77eaf636aa8f2329130922111151a4df913d18b7cf9d0308f01ad84d878adde7 00f4649cf30d4a5269296a45977de2652cb06d3ca2aff4475bb24517b927 b263fd4bdb752590b4c08092fd8b352b6e229dc1398d8b87ba68936786999027f0ad962cd12ba4690d46f457385531e50355f85f8b03f94faac7c570928afed28744e5dc5edbbeacbaeb6c667ef820340fa6b05e43155ecb984116d8296fccb4 +87c717eef6dd3c7434b2c91de05723783bef603d170f654b49a04b067b077c405d2d757ce780101b930196ca4261efcfbd3fc1ebb762cc0eecf101072988aca508c41581936526d3f337053000dcf77b16172492c5d654c6612bbd2523a6ad5966d7091697a29ce882fe331f79a7eb59e5a3fe536263083cc59b8133bfd33c1d 00cca24ad914c24c011f41f80d27ea41caf41fcc8dc9dc6dff5248b2b474 9290b1fc8abb8635cfe9f515007869304fef496c676bcea21158fcf2e61a140f7185533bb9272e4a6bba5b92e6c269c2029e5474acae547864f1525aefe74116dda4749c930268adafbd567babb285a51f96f28f8b9585902cfe033d21e83b92 +9bf48c2aebf473b3a4a928b3b6a4d2fb7e9193c9e60bc2067f9f03083a8cc7b892bdbf05601118bcc34dd283e7be996bf19b0bd36727eb9d65276b6517bf0c77ae0a9091e7a9e46182a2586eb22324939801034e5ba94ba30d1bde7d8fed51eb71036fab6224f8ff30a008422efcff7ea239ff23b9f462777e62b41b396c5dc5 00f5e12d536ef327e3b0ba65ac5fc3f7f4880f5968f3340eb8868c1d47da b7b4461b3843030301eaae02961df1dd8696f0ed56fb2bd4695d27ec607e17cd58da3abd1c14ba41916a39edc6089ea0115195c10ec8ba85140c2deef1b1e6c84b7c7b7e26f93fd5111fecc989bbd3f826b0aa072fad82fb4338c214f7b8eabe +716d25519ae8f3717da269902be4a7566d6f62b68cd0faae94bce98c8a4ac6f66215ebac5407d6f64adf9d53f79f02e50921b6f0e8c805926a839443d30d9294eaa802faa7c5471d81fd1db148cdc621a8dd0c096e06fb0b71943337d5325e1bca77062684873fe904ed9012474ceae5b138e079f941a665a995026d13d7eed9 008c30d93536b8cb132277645021775d86c2ba8f199816c7539d560ac6de 9521d88f1cb82a0fc6c26cf5e97403fd16e0868205264013fb05109f9ab1bed5ea3d97ff72e5202ab38296f94144751a02c50191cbf36755f0d183832fa5999c138ca0db90e14cec06a3315279f213e6b08585a648c043fa1c17066d8810e021 +01e76755007b2ee5ac9e1d4c8adabad6d0f9c1c08ac6e2622b7c1ead89bd3ad0921b9525b49a780a262fe8fc0904a80391717ad7cac9607de55f7c744af8a132ec45ce79723f4a4a8c8b9ef658b360bd3890df164c9f1cd74eafb74feea251a34514ff2a57ae7a6d4bec2067cbf6ee4fdaabf13721bf9ae178b9034ac5e9665b 00fa3f15a506ccf7b50bbbad0a54d3223f5a95eb54f0d1f4e5d0cc21469b a9575318ad42d081ad61241e4fa1f5d5b1799c2d97c0857748ddbf464403ea890a541d25cba419776ec0d64a0fda0af702db620085b3d6e5c1dc11aae86709f61cbb675346dbce85b06548ee38f7f93a7737c5a8a8f52e783ee32fcaf3dc305e +e95abeeb2c51a8cb75ab74253dbe130b5560cd52e2a63d501d26e1458aa568aca6694be91eee5fdfcf582c47c1c727084ee2b2c810281cf9b095808bf7e7c668eff00a6e48b06df3fe6a445e092c24d5687d7d89acc8063275caac186c441bc697b2f67aa71b03294e1adeb7e557c296dd91304ba0587cda3c984619f1eb4f2b 006400a4830889115aa88b860b3fb65905b01fd126c4aec2785518c2543a 9498f037f3397ed0c94e435ba68329815e8490f4c2a0d32da16639f96a6091643650c11364b200cef3fdca0fc2a1d20518635d70dff64f909384217b2f724aeaf82e9ad0e231b3b9fa95df513cc392a31a3b24a8edc0af084ed032218a1c507c +bb8d8515365d240b2071daef0d80558fd3d0e059be9f6abb7b7a0a5f47e2ddca7d1b3b5101d5c583143258520ce8db0a87f877a395615c9bf879ef46f2f20f68bbc9706f82781fad69019396b27f292cdc70fff1772e90205a2225f80889f9daece1d03914d8776ac5bad24d8fb190ba10a2ca17768b918c2e079d83734eb372 00c7b73c324250f14fac0edc941f79bdbc6933ee8f64bf94b847bee5eef6 b59db31fd47c50610fb51756a76bd10ff98095aba8c9fc106e50557d125f29930e14d71f01120a2cbbea7961120b3d8304190e4f3b418415790b1d9ada2ab95ee602d7298e962e8ad696c8b5695d0e1a21c4fb84663bddb34ff9d3f1e128ec5d +cd8b2403435fac9caeffa21b55eaba52d7efee0f89df7142340cdffeb89556303ca01a800429397e2ff6c746743b6bc60a87133274282d4cac02e4ca90ad95d80c93b84163b96296f67d40b2a1124b2b6534ab6b60fdee312fbcdf468d0e84eb85fce4ff360136bb31ced3998d29cfaa3ae685e638ee272058f123c4f35f8b6b 003db7f28e161abf52ab0adc8c4c8544fc989af081303b8688f22b7b2eb7 b19500f32c29d31b724a0c6cf35af78f7fc25015be05335efb06f4d74b689bf121ba32e5ff20f19c89d95a8476fb710805b67cbc1918835aa13ec188831fd6b70239c2c0ec9652ca8ba549728b5f13f91b977354f622da29a35cafc9b15389ad +4bb08eeb202564efb5bda40777d71f1bcc4c7c10b611e803e5c570876f3e319e9e2bc2d32031c56a32fc0d1fcf620d4e4377d881e9e1695bcdb78acba370b849115b86c1c4b83edfa03299da8e7fd14c7cadb81a8e4911c8e427e32c8c9b67e317575331967cf58085cff0c0d48ee0b8e7dc0b49687bb1c70c703a5dad08ec81 007e9d2fdd017d6da6029e88f78927d9ac9437f542db1f1fa99e32bfcf1a 89b468a4ad7ccc0f0f4e97416538ef9c1be90d4564156d534e926b11ca57a548ff51e3861b96be99ce38314c09cc0f7718f782aaee1aa8f8ee8cc22be7d53f7629370ee2410b6a87f874e0f633ff78d1e9d5ebb3c5f7143153731c36917940b2 +0bce683d835fe64e6484328aa13e18b0956f6887b5e4442fce36ff09aed015889794e79da8aa60b4be565c78685674c51e1e7ac60db6a763c777198a56e382a03aff8b40862f961ae23e8b8683b76a5577769422418972ab0049119382edde9e752b42e8b93f403c1ef8665d7ce8530ce4ed9ebf6d397827cba6b7645e177231 00c94052760fc74c2b405ee4dd5dd2a7d38ebc16df9cc32df706075450b5 afece22d603125e80222a883c7c6281e75ed38eb85160b9ebacd932548e8b1aacd5d49436923af34ad8e391a44624d6607c3c1ad924db385c839504b882b7c1f053801ae7ed0b916178f53ed068a109d8a80e3c88bd56af27e49175780741597 +a6defc770426daad4dafba3bbd2a69881334f7c31269b297e440926db54cdad3fd7ad200f5ada2b72ad221ad99a06ecac9c2563a8deed89f0d0896991d1a652f6fa282affefbdb1c1985652300d1792725071631d75a182b683a48448063c7d2563ec3d430e0fd3acea33a35cd38ec0b5b07af96af71d0bfcd879d9864ededf3 004076b93487c2da8aeaeb4725fb53b7b41b465315335c18c6ca041175b4 89405bfe28f2abed27d61d730e7a3e77286cce19467ed79837fb55975214416d71bef20129d50e81fa315f45305f0970020a351bc5a84f741ed21293b169c94c8f0122ef8b04129f1999280328a87b1f3eb0dd0b7d7eebae25bee3bf9ccfaa96 +7803cdf4758c199962b62943f475c6c31356f5d9b997a12e21146a2399cd0dd3b97a860b2ce639e2801571599136d4a8cdbfb12fd1a5ce22374991e090533ff42823a2c58d2076b772814eea7fd7a1fde68263ef912681c72c7aa3e5a7cc44ee8c65e72228b7631e600121ea35bfbbc783b6ae3c0c8f80198ada218be533760b 0076ddd73ee4fc1f5e6766e229cc7236cdfce312417ea291f7c3328d5ab1 a62d929a361f52cee180290263a6bfe5fd214bde2b061a59f3876ec036757def666eefb4848b1d26aa0916388708a03d0bcc3d5cc9749665c8c85eddbc71df7f0df27e28b0c8d38e492dd200bfe5510d73531eb1f764381aec1bc2402a8c5ff4 +e789461e1dad0b6e21abeb6ae2e96385549d1bae39415188c8f833233da6a3328144c97ddb36e0ff4d9e19d84f869e79e609c51b32de59892fb0446dd28cc164a3e53534c950d26f87fb74e682db2038cde778bde06c3ee2eca2a077d8fcc2b0332e352e0e7e6487444a8ad60e78ff213b16fda9faf374dc6d27b7a3c4c6d196 007e1f8988ad804aae7d09a99be19384cc599e7652c02c391542be74b17b 94f908c6f4cb3ea4d2f00802a44f1bffee3fa7ed0c24686d108d9f2e2405fcb95f45f2dedeb4c648b63d2402661597af07e3eef9a9a3074013f99715df55a819bb8cde2dd400d1f8d889c202cf2a537dbf27115d2d86b2bdc3f1ad4dd8371333 +9b58c145d1b6c887f2b25fb672cd49c3a1117224be697c15182d4048be92968a6500f8bcf747fcf33145c13a8d72e891a6e0c4c7310c2b62f3181bf586fe32f1ecf4feee8c2c8bf6c2bfdf9d5f88981ce080095c93e49a772d8e7b59f9cffccec3ca2f212ef4c6748f64e224f4f098334d83108bf6f8c7b43c5eb549f1526897 009b2292b0244c2aabe8b43d95039984d504ebe05eaff318760e4dee739f 9400754ad759d77d99f1414f183412cae1ab68c1d39150a521921ef17fbfa065aaf1b53e44e2340b52c8690534e00e9c0b87fda45e7b3adb30d3ce9224f16dbbd20f10c008c38540a914bab6001cedb3be9687c34ec364af37b20e670abaaef1 +52310a901fe9681a23dd6e02f12974d57f2c4f653322d9a0ff8b338cc6c2bd9f4765c90c6b3c9fb17df3f492e67d204e39d81a8fdeb92c852a1dcc6151ed6c63049037235c6751c9a902748163a567b714725b4d3995e0edbde03215c645b1a1da3147f7406245432800c50f823a1f991c863427ff4c68e4e16d1b106ee40dd9 007ca463b50fdd92d9163f1c2bdfce2ee45ba1437b79162e3e959b814cab 83da8f359b4dec3b40947b55122166f2a3ee407c2701f35aed1057921fa6f99c2f22886ca59bbc3726e3791f8edd5a5214235b612f65ca50be8e44aa14d670435c9d4d37b71ac8b2a66d5e8ed6492588d1c6054f83fa6336f263ce281a9ceaa2 +ff419c011601cfaf833067cf28dbe6e935ebeddf8b5111a97f6eebf3bb28376334f329cd877a134b074790a073db766efe018fce666a34650cbac285ae856fb6b3b8b96877282bc11cd9f9c8e510ed1f69bc2725a44a1d2b35de1edfd8bc9d20c7525ab0bbc27662a7cfc1bbd1e0f4fce5b88411521e3893e027cc8c73acdabd 00c3844750f63fe0c2e930bc38fe88522f4e72a2fd0db9778ade20e939b3 a7631b510af42ab185407e2393c94efb0415546a8ae02aa1eee6e9d45e45875a0f577f2ebeda8715d6c6b5e0f4f2bf2f0036e27b2e7f6a8b5054e61aebea64421698e0a1aa643736b69d902305fc2bc114d4637dd403fdad6f6df4e2bc2e01b9 +05a89c4824c5de66587875011e704bc6e06e991ba8f3aed331cfffe55aa266a08c729f77b8d082dca4d286b2d451ea838d726cc2cf298fddf2d7376714c5e37b64506f353917caec525a1209391449c078c5197a371feade74f8fc8a1a1d67576edfda13c14ad324342fc0b09277941dc072ec0d39434ff1cb91fc59478fcde7 00a3bea235dea86506be4476eb7999dcb8e584a34238c4a894ad6823b93f 897f8d3abda795b174ac9886f0ab3e7da7f11ecdbeff31f454255fb501485c0392368a035d578c93957ffe8562ba4f5703eaff201261f37ed8a2000519c48b7127847498ece0ed1caee85f1a888d97b79162b33bb1369851410d978be96e640d +13e6b5241365d9d0ef9e8b05cabb3248afd221ec02eab92284b98bda3d9272184bfe5251d35705defba5085381430e99b33a3ab77d7870e5102757d065862372df2434a25556b76e54ebc39d4e6c3aba5cd6acf0c335756f7d9385c1068d4cfa37526a9a58c0ccc7f87a8189176c5d4f201499236058ec061357dcdb5acdba40 009a367cd1cffd8dfcca179e167ea437ee48e9b6f42559dda9224701d3f6 8d3d26a4162ee8436cdafe0dc4cf571dc03de8115df7e477db297fc4c3143a1acacf3ff500b577afdad5d3fe8b59640d052c410c5b5a179331167e8d1377257f9fb2cf8e7cd4d3494b6d151ba36df9e5a3e6826ec9cf37a2c72a0608acf48920 +139a1a5090b97afb8fecfff8745efacf7dcf91a4393a7b629564e598d58d5be39c05c5830d4c8ca85d29e9e2c31ad0447864e867d0ef4788ac734f8d871daebceda98d449308c2afbe97724c3af8a468f1925065f39e52ba4b7d15728a744b1252a20476dcfff7bcb82aa72c209e72abb3c24419bc26191390ffed340c1b9c6f 0046f4ad2522e78b9b35297d28f361fb0ce82306322aedc119251d8241be 95ca97ea82d4557ff2ff5d656c7da45d906730260cff56ba94927714461fb94bf31ce3c385a34747de2e3f06824335a90fc9cfd23b72bf34d01ca9a7678dbaa3116e50ae0e2b85acd431829d1d8fe2c4a9bcfa2336793c6b0ca0e6fc26c0e777 +3315e5cda5f252e3291b61e493ab919c20a8af1286d9660cfa2f5ca38b6defe19ebecf820787fe692d04eae8a5f5d37abfb593309569cedf45efd0cecef6951b718924c8380ba52e8ab8c9bfb2261ed5f01cc5a5f9fc5fcdd269a0f122c597afdd9a836cf8f96838c3e8962c1788c3ce4128719b3ef4fc88569643dcad6da16f 00ac82137e9c7a5ecfb8b1a7df9ab50732934566a392a6c8915ee8ca8144 8a60d46c38eb21ec462915a4a9646c989ce06017b3f76840ecdd913dff9179cbdc4c61465f814aa627e8f9f7dfc01aa813323efac44018a39bc79ab076ccb2cfce1b9ad4e18f7845ac02c609077d98ce9aeeeea033388df65f2cbbe2598a044d diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B233_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B233_blst new file mode 100644 index 000000000000..8440e4f8b358 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B233_blst @@ -0,0 +1,60 @@ +f1b67fde01e60e4bb7904d906e9436a330c5cb5721fd4e0a3c75b83dade868736bb1d21cfb1b5c6407c373e386ee68ec2239b700e763728eb675a153b8ac44cf2a87be85fe8ed6683430cf4b7d718891cbf8d583d0a37cc952cc25fe803a7aa4fda80f05541a2f1f2601cdd0c095f7110f2a84f7d641b8531572269b21cbe77b 0056673197bfeea9bd7a8b820b4ae51a50411bf118a692bb9ed3d304da53 99e7c4e4b49446b46635c58860c38c6ea0d692d542a6d5903bba46b5c2ad26ebed35b3b02297766256305f106b00e114101e0d631692df60bfc47677c70b4a35a65938304f8885d647b76e61df90f622159dc1547785889fffdc757e8fa4b3db +1d496d96b533c632ed6a91f6e3653cdffaa5b8cc0008b35e49b2dd52fe261105c2ec7ee71a4ad5d51fdc3d36d688a3b7ccb3b3b0c3a65be17b8d8aa172e3005cfbf37a2d1b1a6e268c090c6f318e7e96f9ec9b9f5a8fbcc7558d89e840f7e76e44bed91c26ca48e6f5cbc253ca2fe8cb81c484cabd24070e488f9c00cd96ad4f 00468f01d483144e514ec257f2e5fdee28a927f2adb19714c1f3524dd0d3 8893cdabee59ac858efdd48f4317a285fb6985103c1cfad8ad2a9f8e3400452a822c5cf019c2db9cc380471f2774331a0147f7f4733e1db535fedeb430f48dec11d72201bb997cc11bf36da3535293f7bb1c4bcea4cf762f6fb968438ea70b49 +723400655027f474446843645757f7e2cd466bf97275067b4bc4c9d79bb3b19b2421835d69db916f24b77c381fa771fc1e7a19d2b4d09411ae55acccc615b16fd24705762b441ab67083a921fd4ae569ce0de69449aa96f5b977ac7dc022fdc8335656853796f54b3fbd118577f98920624eb0a00204f1ef83827245c06646cc 0074052d027f05465a8083a59cdbf32600224e1f563f653b34314651517f b2b02653e069f8ffdf2914cfa03e7a0ea7cadab6d50d6e7858eaf00d521b7e62b23313ea7fa7d1601c0e524accb8bd87023a8ed7ffd136c418f44a1020854154622a060dc2a71eb338429175e446d27656c83a90837666645d7d0ef0571ddefd +155860cb31a142082bcc0bad828d747e916392d21f1873b3a3c1d28ca3ff9d45ddb66a712e3856b6afd07c8d2b2a7badab296a9775b03f6fec0befa2d8d6d00fe3938df244ab46e836a3e686c8b4f918da49f0bb3940bba34a9aa22c7caf02df7758b0de01d9f47af6146344b9be3842d9c055eaf0fb399cd8db95c544a62d8a 001856e7544223f55f80de72a6ef3822fa8fbd68eb397d06e2d76ddd35e0 87c88e142e56af0bfe7ffe8379bc36fc7a32eb72fe0be4e16053cebd81d93eda6aa60a680359f30f6d9bfe33470b04c5049926dfc984ba04bffe29d74d1fba795ad234fb013ea73c912ace005d15eea4b1772f190d5080b0e0c37b18856a8e44 +cbd6e305cc9f0dc90caee6e65a74582e9357bd25c78e33a7b14e1ac7e9397ff4466f192fb432143e6df6d61a0ab808ec0a361a6d95a357a38cd3e241fe03ed883ccc364b248ee2a08702110745c2688bdcefa33c1a45b9c8b200e45cddf3e3f66b8d37eff07fbb3366ea1558ef304085613c56707095724b3e134c7a7d3f8dbf 00860aa2b589f2defc617be73e191502e5d9952bf60547fef19eeccbca26 b8d110f9e14b6266383c801f78c5243c793aa109167e99b765418ebc1b939f1a148f2e11561ebd7bc5a8c933ec95514007d5d90d995a74358faf864ebeb2148d5078b63dd9da418d62d554cba8a38825ef323ba3242ee3e32c6bc1faaf92e943 +812a218ff1ee1472c189f63386e5b8ab341671c3a4dad27a8c6249d1c0f9a29338b471b6179f17a078b6504e804ac55ca3b13e68a623041bc1a092ea2adf3fa1124bbfeb161e6d7c483433f1548763b84da00352a6386e1339f674d45dab13898147ede468e0e01d2c4e0ed66b395a16cc3ded3e952ac739205f35a83376cbce 00d0dec052a00ccebd0c0c5d9a08272f75744a2582cec7ddd924a2b022b2 acca4ee203d6177073c62f5fe7af31433446764f7f5815fe7ab9dc5cd74be6d2ec50618aebdeffa6ca8b92c21070d4f00068d26f58c16bca09855e1a7d91e1f6c06e1942f614a3f450fe7f7c6150911b5996351c3c85c57ff0360e31de7cd754 +0204b1fca831919e89e108cf140b3770f531a696b1d9a4d1fb68809eb10afccc257cc90cd36717c02b2f3d6d3d1d8a93cc5c48aa7ab9f9fddfe121ce9143376535a0c65e247c6558eac49fd1d6d1bf431ba918c471cb3d536ad485ec51f6471a340ac75f160c4c54cd3ffb9dcc123124b42df1fd2eaa005e3377c5d2d55938c6 008a017d717d6d1213f2b74c53281b07258738c0c7db649ea1ac46b9a3b6 b110f99b369b259a1ab815b89c259e9f193306a63c0d7b340327dd258c29d39a5c03298abbf86f8bfd1c17f25dfe4c3404ecf88ca2a8d65bb3894ee1e961e8cb16d5f24231896a1845ddacd97b1bf50483c0b844c69e988d679b9c18215cab28 +2033eb48756638cb56e2cc39a3e775cfa11fce86cf71f04487dcdbc7f262bc8350a30ced54d1fcb697b28a6e96f88f782947c997872307ed963e1d68985f756435af77f57755cacbb4c6b50ed419deec9f39f0a549a13e54254fa0a5832dba2d943ad4aed8688889a2dd29dcb4ea12abd6a6c50eabcb3981c3a0c1ca5f0b9629 001b56c14442b084cfd22aeef0f8028ec57c8b571c9fc1e43de05c45e47f 81662ad31c6c88cd7b022ef6a2d8cd821cbf82da68630bd0d4ef9791511c25dcd66680e3130fd57f6247fd218cddf55f01f374206aa236f62f428c20028a26970823c1902b8cc4494edbe3e107dd3020ea08f071191b111ca08d5534192c9b57 +2986ab1cfe8873009e932dc68d4727d77ccbbf378e43fe4aa7c54416346b036b89c0aad1b82977c9fbc39a00f1dc916c0561d8dd70298c02b6cbfe572e0ef2058641e841c6875e8515f3c1082765e046c90c956d984b76e0e8e6eb433ce26c1757ac5b13422479141971c20102e9621d18f51096ae3173c2753facee2862d66e 005afce37c5594586ac46a34ae291f591eacb9880a7de92701977f447fbf 8cd8538ab0040b81619f4888b694e253e7e8e41159b0e4c56b949b46aa53071f4ec06834ebe3d65779a4e59467f87c590e791ac367ff4b755653a413befd9df89096e3b24399c3a98d05632794d9dfed71b13a4805bd9a5c4d4dcd60b9446ed0 +aabf5aa90ceef91c2155f90660adbcb0eedb996f5242cee15468ae217058ebeaad8cd4ff8cdc754a8ab85ba43c59fbab6386686fad5e27ad3848fe52191c7e4b203720841501792a625aef2acb6e36493b792fa55f253effca682946ad8c77e01f44e92ec3c258d0dd98d3183f4dc4a0bd3eca183794abd6232a6f9e4add8f57 000696df05dc7a54a9908a73eb18416a155cc8df4ab26032539d86eae537 845d56cadd40c8888cc3ba93fb2f19fd93c2ecc9b40df703e3221824729f18d73ca0badd7d7318b1c88c737e4b69d313055a0006778806ce1a0917f047ccdd7c0e554128b7694ac567e12ce3b24a2fce259abdb5af59ba3b5061a4668ecbf959 +29ff209eabbde02b10b3fd559671fa53e418750c32c4a18d31cc0186d1077581bbefb8770ed079f536e866414a07431ae6633955bf42a2389b6f8a565d6e4ffb4444336e0030093876a26d4e3106e9ac697788e41f8a21c755eeb86a7c60f18e5e1069f16408a4c375a6a68d42959f2fab7ac09736c7b37c80c05897d8566ce8 005ca31e88c5b2e96e433af2023a66095161710628e7bfa428944d6676b8 ad4b7fc367246120865dc2fd467a72f7b38365d3f1c3d66532220fb5a610528b9d5cd4834b707647c53220bf96a046050eafd359f85fe6fa3b95726bbf8666da4f0b652b5d58866a4bc6daa55a3dff87885d3c6ad2579803304ac50797c973e5 +97765d876c80819f4004a36d09ccba78e600efc71eb7e869d3a00f658d2ace6769c7ab1ef590f41fb070aa8e08615e138df45ffbb6473d4a86ba5fdf17dd6dc9ea9ee19c0332563c99e6a3451c211d286d69102b47bfa6e07d468d9bde82e5c2063fb1ebbbed6086f542cf68ba46d4f214634afb1146dd5a6f3d50912ef5b824 00ef8fe84727a2ad8bf4e646ef28a492adfaf785a3a2ba6e6f985c649a8c b7d4805239ad8017695f9f613ed4bb4149583a7ea4d97422c466b967126fe802803a29689f63d5dd7e5e8d2b2eec0f8305bc1e4b3c9b4feced3ae0d01206e66c8f77669edbc3fc06b3a3d24608689096edb1184c9f054e66b9318df2e9a97368 +21cf768d087d1e4eaa8a05e2008020e243116206d675c09be42ef2bc93617ecbb0575c873c6510ede9979215531b62126552738862fc4323d487992754e39d8f0d7e111e165ff254200e05082f59a57ef649bccaef6f980094fad3b7ef93bceb161760e200f0a2e396fbb6b6142dc84d872311bf932b84616b22231747937d58 003edb94b8c62f9af30c14a790c0f5d65e362a21cd8569b9725916d534c0 878bdbceeeacd5b738233f819ee94b3eb7e9fb8d7096cb825aee851ec0affa3f3f58d51a96959487eff99e1fef2373f4086cf2ef8390241eaf0e66a2141ca0094f137017ffdc25a982618e62005fb99674aa087883f1fc34675b348af80633d5 +7b8e58eecdab3e40212bba6bf284f9379265b3d2baec3e4625aa08d0ced851da193c292ec793dab42732c07b4e94d8b19c83aed796a7e3a6c2b954a7a9a1ff9b2bd4ca62592c8b68f709f1ad38a5c8033ebb3f33d176945bfc68e9ef2b0cee2d45a13ce89d238a33c09ce2c0c63c4233aba5717b85c4c161dd7648a41a5e39d8 000a7519be62562318da1b67d22cf8e720353d22641e0cee11c7a352bb93 8ffae5c4519cc722346428e1f1049008cf0099336b5136d1f134b71c5f690ddd9d6bafa418ee0946f11d77aaabca50ac0730243571c238c6270fc850221e7ead07ea248a123653b06b73213e949ccbc7d8e8bd0bc232c64cef5d3dea3bfedc0b +f8f268d2b04fe47e5052c8d0d653787384b9654f0bd2138a6f52b80713feeed452b976a90eea4edcfbb62d04f3eafe172ddebd7cdc3701ecd6008e3d82e8eb217b13b5228839f61075159f3bd1e1409c08903874b6dfee2789dd72c208ae769ec8c7d52552a2b1fd73dad24de8b571f88e2184d0ee7d063a121187f97e746f2f 00264022fd7dc2328a6436b522793ad9406d7a586667a0daaf1bce927338 ae79eca968cf3c841143bd50d882b2ced66a750cf59c5478f224fd88617a81fec513837cd3375e0f16d69bdede6f246e178140273cbbe357c9c6d15149f99b4a069959398bd6a4e65de94fb856dd649c18c106f9c2dbc13863ea09dcb54abfc7 +d288768cbd066fad4bb2500b5683fa9e4eaedfb3dbb519b083f6b802efda0a022355565c5fc6babeccb22f3adbbda450ce5d633193d1431e40c0fe631a295cf85965cd3f5937b31866bd6a5300eaef9941daf54d49832acfceed90e572ef34ccc94eacd0fd6b903fee3c572b963d21e2881656a214d2a4c125778dbe3bbeebca 00da43214e2efb7892cc1ccde6723946d2a8248a6b4d6c8872fad525ec3b b04de67542b15604cce9f35e41f1c3d8479578b10200a8a6887932aae60f5afe2962753711e1ee238d3522728c21bcfc165458b0f74992e3919e5f01133b0e4429143842550fcaf5b44e6561d3fc7673919e623f20800d1d6be972c57ec46c35 +bf0ab46e0a756c11229b0ea961f8d57218be5b00ab8b0e91d7664cdf5e0341c412c0e992d26ab12115197db39df2d1a6e18ed26a91be461432a2dfc21d98cb16003e339b0b0b1f100e4e6f4824ddac5442f22a1fac26326ed8a89cc91343d7223986d485cc8c64424e84d56be536c57e4dc5faee459b1958efd79e07e90a9811 00aeafa49d776b61f6a30d66ff64bd40dd8d79891dd5293c1b5cd3b46a7c 85d2b59057bf22de2476689d91f716095a719f644ad1dac00422aeb5475b2ad49f1f593c52e54bee2e48f5765b3167e20d37f2fdb7ee15459a13fee2fd12e2409f287835bbb21114c53cde13cfa033cc631be8bbb9d9276f125a860ae646c2dd +c7b1eeb7c19eb16e7f42b61d79e421b71de797a6cab4e0baee522fee7acdb533f7bbf5855316544e1b82b4f2a18ad0a2311e7622549332122171f32fc62a90e408207e0fb90d1b052821dede9c41b15b6e07d84d5d7b9e31e6396a8ed229fb6232b3051298dc5321aa589f4e289d27169f14c8cc93644916d9b72dbc92c43488 00e95db309f4305b621f51f93588a2678cb19aad0932f365fa0aaa3a3895 90a6bd9e795e3a39e86376def2a23d0ad17023d36be5e62904dc5a7637017465d971018bf2469d0a3b360e25dfbfa4270361d702d350b0380865c7fb8b556e28fe2ca9a15c0415ede417d0bca0da8730794be874156b8e0e5576b315f1118f18 +a738eb074e1f277dc665118ca055e6328059ab26da188c16f56384c566e43df8cff3d2a10d2d15c3c1406de8f734b20be5dd1ce937a4289f0ddfd7bddabd03586556eb8233b8feefedaa1f49bdec6d45fd562c2a83fa9fcfc2013bdd77900857199e51fa9c7cbeab925ba8f6c3c5fae46bf8e9c574b302f1e5f9c44400152a78 00d4319cc8e409b8755880827f3200d3f0f1c64d6356fe74eb1f5aa42499 b10de04bd342c010426573df9fc6be9a339609ea058a9169238f280d62ba399e2129e0c0f3ee1bc43ced0f8b13aa07d90273e5bc5490b0ec4594af0e335a1e61e961466ab56ef1d77ca391295435a26860a842b54ca29f288bc972ccd600a084 +b28103d77e5457c42e026e713ea6ff03722a36512da17197140117442a976f9e2139c54a759fc26af5811b455e5a0d3a95362d9939c1e738045be9237b469ae2106ceed7e7842b44cc0a475d5af6d781e32ff1dd1f4e1833dbc7f82b27dc7e1562d0e29213fd8911105104a7a16f665b926aa137f70d868c90e72f8ee2c95b64 009e556c945052e5954915c773b2d47970c521fcc99139269c3ef46093b7 82cca7c463f40eed5a43cb0f2a4d06ec842f88eb2b252a100b67f6e3a0ec9465fd15fab1046dd99d49b30cb5b1a6989e0acace7b8ef146b7880c01835345390a50d40581588c3fe0bc385a4508d6be5057f17c8d4a5a07477b187d2320456d49 +463d04c84521ae671bb35c0a7acb3ae509b1b0470f39b8fe7ae5f3c9fbadbeb2bcc3a87e284cbdff07407a351f7ba743aeac50c4a1fef7375b90eb4af8ea2df040776bbf3e4389e7a80bea40530842642b9895ab9ef5ac8ed6c9ce7917d7b3ebcf80b801da845943313988c1970e7748cc306f914c37414f8247d648b580000f 00becc76f8a77615c4f92ae1f91645bf5bb908e75ef22fd544aae63a3c8e 852bed5b5d3d3d97591644f7612db3dec04d6af6fda4b26258b444ae7c14f8c52f7ae8ed35f050d9391229d67ee2e3d414a7f4ed098b8e350e6eb9b2cd474e9306065f17a96d5b9d26c79f0ea1a705c43352b4dc315b631e05164fed791efc42 +8b2379b5553ae7db6023cb010e26ae91322bc3f94dbaa369481936f90a886e5d3827d995ccf03ca59f46805fbac0337d31a8f117cc7044218a934d5bf507090e7e21178a7162c8fcb39111e6967803dbf9d752f3ae737ba024d0f4f7627e08be58efbe997a164106bfe37f67d2f19c0fcc7a6c7eebd96a72582a9c7bdf881896 0020572c2a3dc3ea430cd8cde9d642081c21658e8bda165550cd9a5d37d9 95167da2037d4b1df20d3bc291fef42c6e5a40bb035758904a670ea881d0d1ba8592d516898fd4673eaaa505af4539750261da1aa1ef40c8754e6aedc140726b74e6acb529e694579fda2f1580e6bee399e08835a60a8816c31933d6538d0f65 +3090bf7373731cc44c00372c1ac59280b0f36e627ccf763fa68a7be37bb0ac8cbd4f70db54fc652566c78ad268f78f015e4bb1e41516fa56ac303a3bb4a52e1fe897d8338db5a6e37cad685e704b994504bd231c7dec0002dbd907a7ebfa809833e32eb23fffdb44fe4a18e11fa19d67356cfd703cf39a75b1a290b8a7c73afb 00769cfbf2dd8248ea1e0ac9b275c9d6ddcf923fe762079b9ed62ccbaa89 a6df7ff05895450cea6e089079967370117082a96b5fd5bd63cf32a980ec9cb26f10c4682a6afbe324c389de9c50d6f50beb30f178322b2760847f9dccd8a9afb6d428e9dca217d488a511eec658975cc7a9665b9c29eb3f6f5a6e61766d3a5d +c37389cbe3f46eeebdda343e354ccd543e96b0c2a87e057aa6b9c4895a403de706d658bbc9066c140e50fef4b56af2db1f42efb70b8021254649983f1e11d04d6b10169d5a1c2093b6ab89227b88a30537c776bb7575749c3ed87bcb29effd8e4f17915b4d5dff6cab9678d88f33abead1e73dbdc5c3307ff3d3b2d5fd7bfa83 0040ea4a37b388f0cc464f7e2bf92173107b268ff77a8acf5f517b4ec0e4 b60551c897eb453ec3a889ae562d523cdef7605fc216c1e1fd8897a43c3674b8e9109d5ee6fa8dc9fe51f8b1e8b4710d0075152d38d3063dd4f6184a860de0e9c2c033aa1a4495fe7da8f84fe293cd07f54b94bf77c25bb1042b32e51beab249 +8884def8c3b9c5f856b9c2352c85ea71aae3c8d0e84ca74e70e404a21467159fc9826548d16dd1ec5a75dc2c23ca37b30312f25e1194e0f9385a0499db34c855412bbf58979ffce7fc3afeb7b8dbf9898df44023200d809f520db99eae315b5cf85674fab008a20340fae8f6974034fd3e55bf08c5522a460680218f9757e368 0037fc7898df9b37b5390537352f5c0b8de22659166c19d7d4df31c3938d 99da8e381457d012a571b17f1f86e356265e9833067dc68b48b6af8533826304378b8bc5481ec1d315c426c4ab698b840a01577c184b2ea8ab43f6ab870121bae5dc8c394f6b1463ccd74167992db6e6fff25e6688fa94c80e8a747dffadfb09 +f1fc154d469433f56c2bd42aa52237a4a4bfc08fb6d2f3f0da70a62f54e94e3f29c629c837e7adf0474fa8f23251b9b349a16848942c0d9cf5db1d0fd99527020dbe21cf0b94a9aa21f376bf74da72d36f87b306b0696771efa7250c6182b426a4500ac14de4a1804b38db8d4f3beefb8c9bb619ac82cb63fb37c2e1d22951f7 005d5069425e7a9925d2cfc6360a708147b2c1b55ede243591885147ef3b b81aa3df8cc4d1db782686ff033341d72fe4ebb59a509540f33ea47e6591f452e0dfd99c547330225846b20526cc6edf08662d72d93b84f6412893ef8eb172338039abe081185ff34e3479ec8c958a9ff49ea78eb650d35e54475ceffb52def7 +885cd348f7983a0721f96c0e866821223d3e5a95178b16d18652b4062b1b2278aed6f54ab06f7e37ae6ce1020aa3eb812d215194bcd212302da5b971fd86aee1dcb23057dbedb569bd0bbef80df538da69ae2358cb03bb77c64d3ead475c8c5ae5bfbdd75684b421a26f1a7b0c37548fa32d805acdc91230dd70a48232a12846 00ffe3e7b82ca62b96e057ee072a4718ca20a6cc9a3e51e4fe8ed7b4b9f9 80b6974abae034a4c04b64899b5f9691ec70b87d0a5051e765ad89acbcb57ba11536a9bacc191023a40440c91d486b340fa9460005a166a5eed297d83faa0f1940b0161a883bf1eaa52eddbadf311b4adbf9bb3c2f1c5aa61b237f37b1b2081b +ca3b0e2f1c7db4e73c699f06e432bb0f63705ba66954bec4a259bf31c161bb4861476e2f2f7dde9d841d1ea6bd0990cc793cd7a10432e38735c3eeda7a0d786e8821239bdd6c4972c96c2cf68ec5b935391f963a50fe16af2719c9029943b539ff0f1f5645962a6ac46c75d2037fa0c7cd46deadcdfc66e1ddcaada3a376acbf 0007a9cb5ce27c763646de414ca2a4dcdb774d69ed2bde7a817baddbc9de 921d8fa0395e3770ed59e29c8a0516fa818ae017352d3bfa7d109fcf1bf093f492e21e41e5abfd64faff8f9a85a620b10be33eb650c3523fd6a92a0640d500ee449862a071c52eba26a351c46f2ea2a655ea6e2979211e08ffd0ed3db9a1e10e +4b0a31b746763beee77cecd318b90acf50fac4172cf4bfb354e5a440f651cb89d7a515e09ab19e9850803ab9167c2aee3b395a5da10dc9aff799d73756dfb0a9961d93bc32f15a96bf13962a03d5bd42ddc8b5928def7fc48fb063f42866fc5f96cf88fe0eb125b7c01906ad6a7fdade28ccb0a421ceff50ae03a974671b2c27 00c03fa9e38dc1c697f70bc6381f2bacaf860bb5632fc837f728da959ac9 981ca623c65d1c48b71bcf450816028110bceaad9c70270fddac57ee6165b77c235190cd59bbc05a6252464185fb0a180e6c2062b1e47822f9fc230b40a3e56b4c1b63b2309998fbd47527869a7b456d17e7013c4e96c705efda82ce8d11b9fd +3011d42792b21c0f1719faf6f744d576f72c5fdfd22b1a520d0e8d47e8c2b06823d853b13c9fa039fa30a6f2e3e27bb2100c6a35f55703806bbf0f79b09d0f629f8042ec63fa04062f15f2edb92b19237980005566f02bb12a40b4ec66e4ba6c599d928b33f72d7437c0e399a8e6a9068d1fef24917fc4f9ab5464ea6684dde9 0087dba00e3fe4802e01718017510094924496bd2785d4ac1a352c530473 87659842ac66ec6accdf759f4e09d3ee147b729fb25879160bce7ad4704db389d2f6fd4da7df17fcebd9efec4b83646e0032816ca3eeff8c39ed26c6661d1674fb65384b065d04e4dab8a7a7decfbc0d445e2c9ab93bed045a52805684bfb6f3 +05a5d3a3b79f4e51b722e513620c88092a9bb02408f5f52a32e782fd4923f4fd3094fc5536caf4b645d830260eba91b5173f3833dd65600fb9e246aec968b1f6ebdfddb4059fb2de7e636ed60bb7affdb74aefd158e54485d5f26be373cf944c6570daf8fd7e4b77fad57300667d6decf5c65db99ab8763bb4ecbb09fdf47e3a 005a387e7affc54a8fbb9157b5ebd400c98e2d7bd5c3e095538987d4f8d9 a5d26402cf4fcec30658c4e534956f89ab764d88899cce34bdd211d5101470d5dccc867ed3b50370010c9c141fd9586d155be9d3af74cbf8181c2343d20dbe845ca40a46781df64b5fbfc99506133a06082813241edc135f21fea17c990a917c +247a101c8196eb93a440280650ad463795690bc620e46e8118db6900a71eb493d03fbcf2f73a79bb47aa8e2d8c87ef70e4cfae36fae5c45fe247d8cd0f7d0718dad106526945014b4f3bec324897d8e1fa2f457b8a68e61873b7fa0350fde3b87b7b001c13953c2050a24f71fb77eb455053e49200ebcbba7299485c0f1a40db 00adae709a930d6f5a5c0e3d8ef4aab004d741d23f0ffb8287f7059890c0 ad2d46314c168dac680a27c8d3dfd387e10dfa9e7b6b52809fbbff06b6658feec81a41b2f6c2065cd91168030c18625511905bb75634f132c5b53d6dd99000e547c1a56bf33a5408fee17c587a7c631e643d6b2a34980179445e3ae79ab99ae3 +a16678c71976a3ce3362ca379b3272b92e8ca7085b43752473db34e4d6b61eeed3875f49f3328366fc9d0644824e0104817de458e4c1036636b18b83dbaf063f2f99818959224906571c7b28873d9c702360888df151e9ad1a7003e6130033203acf8a69889be6ebd90816f2abf0764f10be68653b1e56766ecc3150bef8b042 0035d391411e6d679751092c4ea5a079c591e77ebdcb57c1d9006ae70d90 865912dfe5b9fee2e1c870e3bbdbca02794f40b84e9b20caf32b5f1c4ed6c9f31e0830da9c9b1f783712ac336588d9f919b3d03f0360f790a90c56ae7b8bdb04105ff693cfd25ad082b25a6e6fcaa4a7e09f087c8cc54fd0b0b863c391a88101 +bc2f080a7f0b69a6b142b8f3fb481a43bd71d07418df4f3b802568073c1a8d35729ad197f34a4e941a6dd511c63f201d1f6c34a1b66545bd5f43508c10bda1d6ef60ee5bdd25dde975e50c61f76cd36d50ee3bd8dfa2dff59524db9ef12f1e28d109b552cb42f021963f559c843476b5c889fc567b7840297c5a480e18c221dc 0084e79093f1947d6ab9cf399782436e36ef87c59a4c090930c9a74ddb10 a5c827f375aa96bb6300891d46729cffa33f9d7fa1a2d20198297dbebf0a932d49c79972684c751ceb3862a3baa004230414804558c0950ec8f1e6a6788f879b6d39f8916194cb112f881c8e08547ffb226b74b2bc53f9857ef15518f6557c71 +ea71cede8b63ddc5648eb244184bae265cd65d50f77a9e25ff93f02b132487c08732544cb88936d4fff7c0fedb39685822dd1c9be1158f647c605c9bb5f6a1ae34722fa08882c14b36b6c93cab33c9a269c7c10f755b6453ed045ea3e56f29e95a9404ba189a0b48848120392b4dcac43148b706c3d9e4c03db410cbe5dca3da 0079b6be015b8006f86fd81c2792bec6b42c08bee2d295cf9dc214c326ab 885f8c5d6014ad0f04f6503f3a98f6ab879ba28a181fefe502b36b549c503f968125c42966c5c46218f53f4f1a7bfc760bed5594123bc0944f6e3e485d7b6cfd165e2a650ca5936d85e143b17ecfb974609f9723ce84b6b38dd2bfbec0550207 +319b41d16e18059a1324c37161c937e882192cd949c420ce9c59208a0ac208ebb06f894a7fd78df2a3c5f23f25dee6595d3dacb25a699f115dd482ccd36fc54ba29dda279335424c86b07a1b1fa76a5411bcecaf4d37065b229cdce0bac75b666c6626ec37a716e9841be93c907f87453ad91d36846561f284421a89013b88c3 00ca9d751a060fde64336cdc88122819f4b3cd1b4e7df42d495197787894 b69abda7a7247364c6c9106811612343406463d7cd6d93db229fcbd6299a029b3d167539085c9aa17f7a0175abd3e280114cd684a7e8169b7cc8eeb9ae1b687edaaae4d2d2b677c7aa6e016fc430936e4b335abe5d0a7ae64d7d4f79d0fec04c +aebeee215e7b3d4c3b82db243a47506ffbf2263f6fe9de5b69286e8649d9218367c36ba95f55e48eebcbc99de3e652b0fecc4099714ee147d71b393de14a13e5044b1251e40c6791f533b310df9e70a746f4c68c604b41752eca9ce5ce67cdc574a742c694ada8f20b34d0eb467dce5566023f8533abfa9688d782646420c77b 001dde4b2d49338a10c8ebf475b3697e8480227b39bc04253a0055839e9e 8a11ef7028b27568ee0d794816437e95d6c0906e98af7caf1e3564b70e4c1eb4f3a46226320398a4051d7343394386230fb78d502a211ac0eca0f93cb079be10fab5fc88d690bf489f3f60e435ffb2e8e39e8ee9b468787b9c552394b464bde0 +8d353a6b6f35590baef59b638914d3e934d0145b045d221d846517ceddc8ff5e3d28826d3459f8ce1260f705e80923f39abc73d5949aa7aa8ad1734be0e992bff0c9a8f4cc9bdfa430d4cf52e29d3737b0cd3231b72b16e15e1a9040b832e4a920b4a1d94c4964ac6c8abb75bbbdb10825f882ae44c534c7154c446421a04d87 002c8bea2803fd746c874fa110a716538c179c82712f38d33d0f6d037e7a 8ef0d893027f66e807c5b3a44d402b8ad580c463b2cced5da1a97dfd1927e695dc5bab1f7e0c15c7af5d56702311d543111b3aa0a8da194bac0a6b8472400be8d63a94237294cfc30f448463a583af4bc21bb573287663b22f12452d82a4f438 +847f134b90f10ba3636ec24f36a94111f26d58428fda5bba4501e58c7bb55809f52320cbe9e0df55af1e40bbac9f3eaa26a55d78b60621d4356d090d98363662f406367601eaa9eb9568b1a1b319730bad7bf6a7ddf1b45eb6922faf8d065c540b671c50df758ebf8c4aca6f01878e5e0012dd038c58833e2b13ebdb9a9f3fc3 00b9119b3b4b30cbfb98ddf0a4f6953417e515fcf0e5a94e83ebc1d1d14d 91c577e53701669ae41a5df3ef276c33dcff22541fb1f2fcf3e6d28efa7a587baac23afd1a77cc8a4fc189b29134f7d8031fc80ad1f0f6322debbe5d93fc31f74d614575c95a5d0f4d64011d42da312bb1383ece3b75e132a3009ebf3b5d2032 +99d23950493bdd931915e9f9b65e4cd1329866c0071a19d4f7d6fd190689275b7b10fc07503dd1c27a4da274dbeb3aa5cb0e71e9b7b03fc2697729b7be913756e6760098951d7015df181cf14b1e0b954e6260276af553e3e59907794b863e941950718ef154669c5c262946ba120892e0239e05910c2194f712db46e37e53b7 00f4ab2a573f3771d1e4222e251faf14e06cefed544e804c299c9a8395f5 b7066e2a7349bdf7e30162b89be35b0af3a17d28d3c97cea77fd5aed42d4e57fbb540bfa6324e31b6b3d2ce594ca7a3613281098ee51fc9bb1a5aa6d7785a3edd22960115ed82950c6b6481d1264e7daa9dc01fa30bc35cf3416ede101d6d244 +7bef2487bc2bbbcbcc1570bbd4ed437c0dbcbbf63f666a3355aec49ea6ef593da25aefe9ae0d94db50692475425dee3c88cdea975794ac69142c25732f3541457d68d9101c8be069f2b515aadadea2019dc7abefa6c12cb3f76d9f4b5e46546f77eaf636aa8f2329130922111151a4df913d18b7cf9d0308f01ad84d878adde7 00f4649cf30d4a5269296a45977de2652cb06d3ca2aff4475bb24517b927 b263fd4bdb752590b4c08092fd8b352b6e229dc1398d8b87ba68936786999027f0ad962cd12ba4690d46f457385531e50355f85f8b03f94faac7c570928afed28744e5dc5edbbeacbaeb6c667ef820340fa6b05e43155ecb984116d8296fccb4 +87c717eef6dd3c7434b2c91de05723783bef603d170f654b49a04b067b077c405d2d757ce780101b930196ca4261efcfbd3fc1ebb762cc0eecf101072988aca508c41581936526d3f337053000dcf77b16172492c5d654c6612bbd2523a6ad5966d7091697a29ce882fe331f79a7eb59e5a3fe536263083cc59b8133bfd33c1d 00cca24ad914c24c011f41f80d27ea41caf41fcc8dc9dc6dff5248b2b474 9290b1fc8abb8635cfe9f515007869304fef496c676bcea21158fcf2e61a140f7185533bb9272e4a6bba5b92e6c269c2029e5474acae547864f1525aefe74116dda4749c930268adafbd567babb285a51f96f28f8b9585902cfe033d21e83b92 +9bf48c2aebf473b3a4a928b3b6a4d2fb7e9193c9e60bc2067f9f03083a8cc7b892bdbf05601118bcc34dd283e7be996bf19b0bd36727eb9d65276b6517bf0c77ae0a9091e7a9e46182a2586eb22324939801034e5ba94ba30d1bde7d8fed51eb71036fab6224f8ff30a008422efcff7ea239ff23b9f462777e62b41b396c5dc5 00f5e12d536ef327e3b0ba65ac5fc3f7f4880f5968f3340eb8868c1d47da b7b4461b3843030301eaae02961df1dd8696f0ed56fb2bd4695d27ec607e17cd58da3abd1c14ba41916a39edc6089ea0115195c10ec8ba85140c2deef1b1e6c84b7c7b7e26f93fd5111fecc989bbd3f826b0aa072fad82fb4338c214f7b8eabe +716d25519ae8f3717da269902be4a7566d6f62b68cd0faae94bce98c8a4ac6f66215ebac5407d6f64adf9d53f79f02e50921b6f0e8c805926a839443d30d9294eaa802faa7c5471d81fd1db148cdc621a8dd0c096e06fb0b71943337d5325e1bca77062684873fe904ed9012474ceae5b138e079f941a665a995026d13d7eed9 008c30d93536b8cb132277645021775d86c2ba8f199816c7539d560ac6de 9521d88f1cb82a0fc6c26cf5e97403fd16e0868205264013fb05109f9ab1bed5ea3d97ff72e5202ab38296f94144751a02c50191cbf36755f0d183832fa5999c138ca0db90e14cec06a3315279f213e6b08585a648c043fa1c17066d8810e021 +01e76755007b2ee5ac9e1d4c8adabad6d0f9c1c08ac6e2622b7c1ead89bd3ad0921b9525b49a780a262fe8fc0904a80391717ad7cac9607de55f7c744af8a132ec45ce79723f4a4a8c8b9ef658b360bd3890df164c9f1cd74eafb74feea251a34514ff2a57ae7a6d4bec2067cbf6ee4fdaabf13721bf9ae178b9034ac5e9665b 00fa3f15a506ccf7b50bbbad0a54d3223f5a95eb54f0d1f4e5d0cc21469b a9575318ad42d081ad61241e4fa1f5d5b1799c2d97c0857748ddbf464403ea890a541d25cba419776ec0d64a0fda0af702db620085b3d6e5c1dc11aae86709f61cbb675346dbce85b06548ee38f7f93a7737c5a8a8f52e783ee32fcaf3dc305e +e95abeeb2c51a8cb75ab74253dbe130b5560cd52e2a63d501d26e1458aa568aca6694be91eee5fdfcf582c47c1c727084ee2b2c810281cf9b095808bf7e7c668eff00a6e48b06df3fe6a445e092c24d5687d7d89acc8063275caac186c441bc697b2f67aa71b03294e1adeb7e557c296dd91304ba0587cda3c984619f1eb4f2b 006400a4830889115aa88b860b3fb65905b01fd126c4aec2785518c2543a 9498f037f3397ed0c94e435ba68329815e8490f4c2a0d32da16639f96a6091643650c11364b200cef3fdca0fc2a1d20518635d70dff64f909384217b2f724aeaf82e9ad0e231b3b9fa95df513cc392a31a3b24a8edc0af084ed032218a1c507c +bb8d8515365d240b2071daef0d80558fd3d0e059be9f6abb7b7a0a5f47e2ddca7d1b3b5101d5c583143258520ce8db0a87f877a395615c9bf879ef46f2f20f68bbc9706f82781fad69019396b27f292cdc70fff1772e90205a2225f80889f9daece1d03914d8776ac5bad24d8fb190ba10a2ca17768b918c2e079d83734eb372 00c7b73c324250f14fac0edc941f79bdbc6933ee8f64bf94b847bee5eef6 b59db31fd47c50610fb51756a76bd10ff98095aba8c9fc106e50557d125f29930e14d71f01120a2cbbea7961120b3d8304190e4f3b418415790b1d9ada2ab95ee602d7298e962e8ad696c8b5695d0e1a21c4fb84663bddb34ff9d3f1e128ec5d +cd8b2403435fac9caeffa21b55eaba52d7efee0f89df7142340cdffeb89556303ca01a800429397e2ff6c746743b6bc60a87133274282d4cac02e4ca90ad95d80c93b84163b96296f67d40b2a1124b2b6534ab6b60fdee312fbcdf468d0e84eb85fce4ff360136bb31ced3998d29cfaa3ae685e638ee272058f123c4f35f8b6b 003db7f28e161abf52ab0adc8c4c8544fc989af081303b8688f22b7b2eb7 b19500f32c29d31b724a0c6cf35af78f7fc25015be05335efb06f4d74b689bf121ba32e5ff20f19c89d95a8476fb710805b67cbc1918835aa13ec188831fd6b70239c2c0ec9652ca8ba549728b5f13f91b977354f622da29a35cafc9b15389ad +4bb08eeb202564efb5bda40777d71f1bcc4c7c10b611e803e5c570876f3e319e9e2bc2d32031c56a32fc0d1fcf620d4e4377d881e9e1695bcdb78acba370b849115b86c1c4b83edfa03299da8e7fd14c7cadb81a8e4911c8e427e32c8c9b67e317575331967cf58085cff0c0d48ee0b8e7dc0b49687bb1c70c703a5dad08ec81 007e9d2fdd017d6da6029e88f78927d9ac9437f542db1f1fa99e32bfcf1a 89b468a4ad7ccc0f0f4e97416538ef9c1be90d4564156d534e926b11ca57a548ff51e3861b96be99ce38314c09cc0f7718f782aaee1aa8f8ee8cc22be7d53f7629370ee2410b6a87f874e0f633ff78d1e9d5ebb3c5f7143153731c36917940b2 +0bce683d835fe64e6484328aa13e18b0956f6887b5e4442fce36ff09aed015889794e79da8aa60b4be565c78685674c51e1e7ac60db6a763c777198a56e382a03aff8b40862f961ae23e8b8683b76a5577769422418972ab0049119382edde9e752b42e8b93f403c1ef8665d7ce8530ce4ed9ebf6d397827cba6b7645e177231 00c94052760fc74c2b405ee4dd5dd2a7d38ebc16df9cc32df706075450b5 afece22d603125e80222a883c7c6281e75ed38eb85160b9ebacd932548e8b1aacd5d49436923af34ad8e391a44624d6607c3c1ad924db385c839504b882b7c1f053801ae7ed0b916178f53ed068a109d8a80e3c88bd56af27e49175780741597 +a6defc770426daad4dafba3bbd2a69881334f7c31269b297e440926db54cdad3fd7ad200f5ada2b72ad221ad99a06ecac9c2563a8deed89f0d0896991d1a652f6fa282affefbdb1c1985652300d1792725071631d75a182b683a48448063c7d2563ec3d430e0fd3acea33a35cd38ec0b5b07af96af71d0bfcd879d9864ededf3 004076b93487c2da8aeaeb4725fb53b7b41b465315335c18c6ca041175b4 89405bfe28f2abed27d61d730e7a3e77286cce19467ed79837fb55975214416d71bef20129d50e81fa315f45305f0970020a351bc5a84f741ed21293b169c94c8f0122ef8b04129f1999280328a87b1f3eb0dd0b7d7eebae25bee3bf9ccfaa96 +7803cdf4758c199962b62943f475c6c31356f5d9b997a12e21146a2399cd0dd3b97a860b2ce639e2801571599136d4a8cdbfb12fd1a5ce22374991e090533ff42823a2c58d2076b772814eea7fd7a1fde68263ef912681c72c7aa3e5a7cc44ee8c65e72228b7631e600121ea35bfbbc783b6ae3c0c8f80198ada218be533760b 0076ddd73ee4fc1f5e6766e229cc7236cdfce312417ea291f7c3328d5ab1 a62d929a361f52cee180290263a6bfe5fd214bde2b061a59f3876ec036757def666eefb4848b1d26aa0916388708a03d0bcc3d5cc9749665c8c85eddbc71df7f0df27e28b0c8d38e492dd200bfe5510d73531eb1f764381aec1bc2402a8c5ff4 +e789461e1dad0b6e21abeb6ae2e96385549d1bae39415188c8f833233da6a3328144c97ddb36e0ff4d9e19d84f869e79e609c51b32de59892fb0446dd28cc164a3e53534c950d26f87fb74e682db2038cde778bde06c3ee2eca2a077d8fcc2b0332e352e0e7e6487444a8ad60e78ff213b16fda9faf374dc6d27b7a3c4c6d196 007e1f8988ad804aae7d09a99be19384cc599e7652c02c391542be74b17b 94f908c6f4cb3ea4d2f00802a44f1bffee3fa7ed0c24686d108d9f2e2405fcb95f45f2dedeb4c648b63d2402661597af07e3eef9a9a3074013f99715df55a819bb8cde2dd400d1f8d889c202cf2a537dbf27115d2d86b2bdc3f1ad4dd8371333 +9b58c145d1b6c887f2b25fb672cd49c3a1117224be697c15182d4048be92968a6500f8bcf747fcf33145c13a8d72e891a6e0c4c7310c2b62f3181bf586fe32f1ecf4feee8c2c8bf6c2bfdf9d5f88981ce080095c93e49a772d8e7b59f9cffccec3ca2f212ef4c6748f64e224f4f098334d83108bf6f8c7b43c5eb549f1526897 009b2292b0244c2aabe8b43d95039984d504ebe05eaff318760e4dee739f 9400754ad759d77d99f1414f183412cae1ab68c1d39150a521921ef17fbfa065aaf1b53e44e2340b52c8690534e00e9c0b87fda45e7b3adb30d3ce9224f16dbbd20f10c008c38540a914bab6001cedb3be9687c34ec364af37b20e670abaaef1 +52310a901fe9681a23dd6e02f12974d57f2c4f653322d9a0ff8b338cc6c2bd9f4765c90c6b3c9fb17df3f492e67d204e39d81a8fdeb92c852a1dcc6151ed6c63049037235c6751c9a902748163a567b714725b4d3995e0edbde03215c645b1a1da3147f7406245432800c50f823a1f991c863427ff4c68e4e16d1b106ee40dd9 007ca463b50fdd92d9163f1c2bdfce2ee45ba1437b79162e3e959b814cab 83da8f359b4dec3b40947b55122166f2a3ee407c2701f35aed1057921fa6f99c2f22886ca59bbc3726e3791f8edd5a5214235b612f65ca50be8e44aa14d670435c9d4d37b71ac8b2a66d5e8ed6492588d1c6054f83fa6336f263ce281a9ceaa2 +ff419c011601cfaf833067cf28dbe6e935ebeddf8b5111a97f6eebf3bb28376334f329cd877a134b074790a073db766efe018fce666a34650cbac285ae856fb6b3b8b96877282bc11cd9f9c8e510ed1f69bc2725a44a1d2b35de1edfd8bc9d20c7525ab0bbc27662a7cfc1bbd1e0f4fce5b88411521e3893e027cc8c73acdabd 00c3844750f63fe0c2e930bc38fe88522f4e72a2fd0db9778ade20e939b3 a7631b510af42ab185407e2393c94efb0415546a8ae02aa1eee6e9d45e45875a0f577f2ebeda8715d6c6b5e0f4f2bf2f0036e27b2e7f6a8b5054e61aebea64421698e0a1aa643736b69d902305fc2bc114d4637dd403fdad6f6df4e2bc2e01b9 +05a89c4824c5de66587875011e704bc6e06e991ba8f3aed331cfffe55aa266a08c729f77b8d082dca4d286b2d451ea838d726cc2cf298fddf2d7376714c5e37b64506f353917caec525a1209391449c078c5197a371feade74f8fc8a1a1d67576edfda13c14ad324342fc0b09277941dc072ec0d39434ff1cb91fc59478fcde7 00a3bea235dea86506be4476eb7999dcb8e584a34238c4a894ad6823b93f 897f8d3abda795b174ac9886f0ab3e7da7f11ecdbeff31f454255fb501485c0392368a035d578c93957ffe8562ba4f5703eaff201261f37ed8a2000519c48b7127847498ece0ed1caee85f1a888d97b79162b33bb1369851410d978be96e640d +13e6b5241365d9d0ef9e8b05cabb3248afd221ec02eab92284b98bda3d9272184bfe5251d35705defba5085381430e99b33a3ab77d7870e5102757d065862372df2434a25556b76e54ebc39d4e6c3aba5cd6acf0c335756f7d9385c1068d4cfa37526a9a58c0ccc7f87a8189176c5d4f201499236058ec061357dcdb5acdba40 009a367cd1cffd8dfcca179e167ea437ee48e9b6f42559dda9224701d3f6 8d3d26a4162ee8436cdafe0dc4cf571dc03de8115df7e477db297fc4c3143a1acacf3ff500b577afdad5d3fe8b59640d052c410c5b5a179331167e8d1377257f9fb2cf8e7cd4d3494b6d151ba36df9e5a3e6826ec9cf37a2c72a0608acf48920 +139a1a5090b97afb8fecfff8745efacf7dcf91a4393a7b629564e598d58d5be39c05c5830d4c8ca85d29e9e2c31ad0447864e867d0ef4788ac734f8d871daebceda98d449308c2afbe97724c3af8a468f1925065f39e52ba4b7d15728a744b1252a20476dcfff7bcb82aa72c209e72abb3c24419bc26191390ffed340c1b9c6f 0046f4ad2522e78b9b35297d28f361fb0ce82306322aedc119251d8241be 95ca97ea82d4557ff2ff5d656c7da45d906730260cff56ba94927714461fb94bf31ce3c385a34747de2e3f06824335a90fc9cfd23b72bf34d01ca9a7678dbaa3116e50ae0e2b85acd431829d1d8fe2c4a9bcfa2336793c6b0ca0e6fc26c0e777 +3315e5cda5f252e3291b61e493ab919c20a8af1286d9660cfa2f5ca38b6defe19ebecf820787fe692d04eae8a5f5d37abfb593309569cedf45efd0cecef6951b718924c8380ba52e8ab8c9bfb2261ed5f01cc5a5f9fc5fcdd269a0f122c597afdd9a836cf8f96838c3e8962c1788c3ce4128719b3ef4fc88569643dcad6da16f 00ac82137e9c7a5ecfb8b1a7df9ab50732934566a392a6c8915ee8ca8144 8a60d46c38eb21ec462915a4a9646c989ce06017b3f76840ecdd913dff9179cbdc4c61465f814aa627e8f9f7dfc01aa813323efac44018a39bc79ab076ccb2cfce1b9ad4e18f7845ac02c609077d98ce9aeeeea033388df65f2cbbe2598a044d diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B283 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B283 new file mode 100644 index 000000000000..07f677d5e397 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B283 @@ -0,0 +1,60 @@ +067f27bbcecbad85277fa3629da11a24b2f19ba1e65a69d827fad430346c9d102e1b4452d04147c8133acc1e268490cd342a54065a1bd6470aabbad42fbddc54a9a76c68aceba397cb350327c5e6f5a6df0b5b5560f04700d536b384dd4b412e74fd1b8f782611e9426bf8ca77b2448d9a9f415bcfee30dda1ccb49737994f2d 0299ff06e019b5f78a1aec39706b22213abb601bd62b9979bf9bc89fb702e724e3ada994 b649e10a1b280ff469b4719750c177c4d155cd0b701e54331f5756ada2def1229d4f1e6557ffc5dbbb367397c5eb53ac0177884471d1393b81d2006a08a3cc29dd4c0a6331b8cba8e53051c6e1b611fcb83de500df622e8f3a9ae1f8808a4de8 +44adcb7e2462247b44c59608cbe228ada574ecb9f6f38baf30e42b589fb9b157bb0560e5a2aa5523b71cc0d7f583b502bec45d9b8352f29ee1842f42a17a5b16136feaa2efa4a0ae306402940ecd6b71e57d1467c98e7960de2a97f88b43487e4f4016af1292381d70c18c7e6eed99a14cdeb5b3caf73688658e4c5b54c81e08 009c2804f8cab768248fb3fff8a055b3f4585c00de5c1615a19f9425b9432ea09afba8f2 acd577cb52b4e8672cc70521d2a17d07784a61b5998af5a0883dee832d2211e9f6938f41b53f78a42512e7447f95a760067e8bd8025876838932620f85c64cae7ac4108f0af44295b4d3ec60d1bcafe2586d8383ebf5fde84e82a2fcaa8572c7 +cffee6252c7eb6d91d8fe100a1e62f0ad9f862d78ca2b747a6c17b8c9ea8980dc239b3b673310e6e7483582399163e39d889abc1a613fe77849ebc09b4f7f4fe0688b8a9869ae918a88294c7ee199be50ee9460db14725ae70b449d0cb48f30e7d817ec02c0cd586119341dba0b74f0279330807cfccc99c8c340b72c1764a45 02e625a6bc6d0ce7c06231de827068bdb0abc8ffb57c82b35ee3a0f873b9473905974d34 b30dab96aa258f2161232f918f88cf0d13180a982ae9f237fe7ebc932fe8cf418440ed5c7a5f77311ebcddb9190aaf6708bd0cfc7bc3bf80d4634fd03bdcbac5576260198ecfae5b913c62563708130772a76198e896cb1b1021651fed853c36 +d058ab5dc07228253707ef224897ea0fcd09c3d5cc91fdce9e03c1c59c53fb4596be2ed929c7455e67ac7f4891aed3eb06ad88f2c4aaaabff045b959f900d1019d706b60526375851bb891494e99995928e4cd51c9616aa651ec77bd7e398916bb9ed3156391bf7fb1e29181e2b011dae2edaf803607def2ac6b194929a57f45 0376ac24e1b86f8a55c052d92a0bdc6472fa03acdcdbccbf7c321ec0ccd97aa0a66b4181 a56ba778e37ffdea88ffdbb5b34be45722734494f0ee6a55e7d43d50dbe1c558d98a79b6ccae527e0ba260756fbaf08609a9cae0ba66d65efb99aff2f90b945252065ba1aa228a69eac14b5adcd51fb758253cc66075a42265b66cd294ab1079 +c86f2cc7ab5df5cf1a236fd83792769474cef464032800ffe98a44cf29dbfb6f24088160eb31a11a382ff2a49f3e05e983462f5304272f96c0a002b69af3d233aebe867ee63fa46666760a6889d022c18645b491f8d71b6a3b6b4ef058e280cf625198715b64b025bf0449445d3dd7e1f27153926e617bd2c96638345431d1ed 02b50a6395fc02b9ac1841323de4520292f913519bc0d6a471aa28021322fc4dbcd7b802 b90e5dc00ddb0beca248bc4fe085ae9256809431990dae40fd774258613bf7fb5c68ee64080b9b0af28e9a32d67108ef06e518f3114be7f66d9c4e4e744266ff0414ee976a99e9562642c2c64a160000971d412e703b593b172cd71f38ffbed4 +c1328d8d2e5b6ffc850a9600bd6482518ddd9cee3fc9140febb72bcd444b0cd7e8074587d51b62cce4b3d4f34ad3355353fabe363369cf790db2df9fdac3a0ec4757e2dfb3b683eaa3e26531691ce765742e1c0bdc0e1028d347b6085fc459df0989c6a144271454eaffe413cae2ad7c8b2371fd2df1afffe56df727009765a2 024e5889722f6c35e18ca47effa9e415b1ba790066a91fb3c9f7b001ce28fc732b09bc23 b54f2e76368392e6f112ad6cdea2645641460b9fec04c5f292af4d0722ec6c848ceb51b4c524504cb1d4c1e613b43367143c8b27447c05b2d48d7c788acae16f01d7f91dc8fdfc06c2929e327f34852a863cc7c718d6ed2f7de3ebc5f6c20cdb +7176b7013ea27e94281977eacb976bb31c753bf80fa09680a29128a6fc15234f79f0e9900aff3217ce9be72c378042c6c34fced0158740073d1a985fa25987fb218002e425868fda5a47de51abfd04de34e2b8634cebfbdc98e80f93d94096193eaa82dc8778fc23f3765c7acdad94fdaa272df0ff0f28190c10a462ee78ac92 0056d15b81f40b6378588a5efe43e21b95e18120d514bfdda0e7759a1d0766a8a35ce5ac 90cb2d319499b78599f0571d0d41b307e14037cf9ab00d4c6953d1a13d4c9249878ea2a375a48f78fdc1d896a9bb2db60be13c174bae79022fc70d52dab2e780e35e26422c3f2db113fa56a841974b02138221bf4966d72af04682a146f794c6 +4c3642ba040a9955b9d50dcd1c936688c17c363854358afa8ca49c6abd906dfdc4d89bb4cab0bbc363fb5b74e1f004d4b09ec9dfeed4c0bfb482a9061a1f487a3d79195ff7b65a0504bced3a28db0ebe8fcf8ab1ee4a3ae91324d15d890ac4c479144dd5538d2e36d3a587769ee9cd2d5c6f85a03362a022fe0efc4a3902b71a 012fb2fb5bf5f7e42a500154823a174ba2d05af71e3b0cf47fab46e673ea1822f1563def a0e7ed639f3cdae8f7696150c4ec1a9f402e56048521d36146866fe035e8ef1b7dc8bfa944538d928ba2cde83a066e5201d124fb4b155c8c9b4c4210046078e2d6d4de547fe64ce90c4b55b39339c901dff6f81fd64b76898f1be9b90d81a352 +e471f39c18b081362adc7da47dec254dab8d765f005ac574640d78c14222639245563912d942f3be212ee3cef134407334c8fe3602fa0e1629de5331643d76715dc1b0ffcebd484d86c5211be4b285a31688b205fa988e6c15b36daf396ccdcc209c7dde2a732f5c31c84c7ea041408ebf15e56632583af0131bd7f531b5fc45 030096c54fd480647e017f8cdbbdef292e799f054e3279d228b09816a757566a744a8266 8729ccb99f28fe12af22f2ebbd6d3dbf1669961856a4f0e4cc06535f80bbaef0bc0749d572343f7db53d86693e459b17127c182137c76e1b794472a420f6d4429a5919a7569476fe217d0f15c877e0ea073ac9d432312637e31eed78f435dbd7 +8a93fe53e83075c4025228540af7e96a588520da34e3eadeb99a4ab2f3dbbb8f85fe63a3b86c1f4ec912e665ca05b43e869985eae3791b91205afb1380e16c25b74e6793fa63e4a55dcf25dc22d03f09deddeb9042b620434111afe08c5657c7d754af66ad91a1b5423301b1e8e6389a1404060d1b6a99fe0f89598482979e42 00a1b7e9c8c2dc25b494b5ef3195b294e41cd3c2c35235ab42542bd3e2a52d5826662bf9 a98b520f84e21251678ef6bedeb1220edcb57f5a95c016cba56300fbf2de6679a73a93ced220ebffcb60d40d6055396209ea2fcd3faae30174da6685f480d365359fafff871bed6b91430e8612d4f328e67f86a40713f3f335dbb620adf73454 +e193a8ef6f454ca1aed38bb67aca6d08280d421b196d89938c0582b7cde74dafd71716f3818940af412d4a7ff3960a8517aee108ae03576b68ee7557d35e6f1ab823d124de7243dd02b542591f62c80d822608572889573e4c9dc62f99d68e07800da6f83cb6f5e03d1f2ac15f90e38b4f25e0a75e354e4b60cc81c0bbe81d39 0059b1a8fb84530bba7a607ee88310e31bc6ea6a6881603567a1081a05a3a9ff87e719ef 84d68a553dbb4e7f9543475b93d23a9921c0e8803e0889e6ae8cc74715d35844b0272774d3d5e4ca7774d6a8df2988320e277161489502d713511cea45b13731690e8d1d7f902937511be197141b046978293650bf3eb980da818a1f6489a441 +8a99b9db191f6cabc88b430bc2293e6774d5180f019d871839289e25aec29379f14606e742190b7aa062e3b29fe0254146d9614856c5140c7315015abb98ac00da2c7e33cbcc82c24b797366f12767322c4381454d9d1eeaedb616b0ea5c66d1422da459f18081f4f966d05ce279c6ee69b1bf94b8388d38d4b770d9ed69025f 030ddc2c7a4ce300cc2b75f0f977033f16c1f8bb13aae3d494c381f9a6dc8622499ae4df 84b5f1d6857cc248af8e003aeb1555319b5df1565487f78a3def517e42363c074bb62a68e51ba5f8d7b6a3d4b4d07e5214ec06869c82d28f80b084931f1613fbe95c93f4a5e924af687fada6ab58cf457f42143b8068c27a3b6445ae2b4c342e +5c437b331831530aa94623b1736f00b986172699f0a02a5e5df0008bf25341787e2e66046f2c929dfe0058c3cb89fc5bebbe1025bb1edd1ee31522ed568e7b5b4ca3991afdc76a68cbc2c4f81863e27fdaf6a564fab2c6354e5c657de81390f8a4132669fd24a48580c716b5b7961a9c091f614d11cf45dfdaec8946a54a11d8 007899928922fbfdb5407517725edf231d15a8b62d90b7fb6d8c8d20424850dc44f797ed 83bcc179537370ee2a0e4cf9af81c9883207d8b280698dbbaa411cafb49bfde660ce57d40ec26030da2b4043df92476711c8a0a39646260e7d14bea242dbe0c3e7c583840d6ce1718c871a7f06948588fab445088840510c75a3a1dc856b9159 +91aa08567d8da4c90684dc06068f69deae240212842ff1786f04ec41b40d9187aa92c76401f9fcedced62876a34df82ad7c1e63b68bb2a972257ea8542bda6a7f1a020c9b122943b6d651abda8b8d322a8fb762eee376daa2d3637a71ed6c4f5cf96f61c0da2d6e1dda3370d80e51da2cbd8aef3267168c67359523faf910dfb 02a2af63d1171930758bd3e5bfdac62cca1a83a3b55a49b3f80cf0d9ee4b2082757beac0 a28c55d28f846a33a3510d62ac0daf84bf4c46d45aea5d0bec7d730ef25b4374b93941f66c5701330a669e0aa2640e6707bc325e44fbfffd089954aa5eb4d8af88fccbb4fd4b505f4d3388e955860a406690162704763474d4d83fed2d00857d +eb5297bf408c1a55e400a20a3c10acbc5c2bc6d6ccfcc0941fb7a6fd4d2834415a6df86c3a6c4b867d1215aeb8222153da8cbbb1576c92c07ca2c36d8f243fd911f9a057e39ee25832454e28d7ed52a8d04169b9b9677a16b32d5d211b8573a8986e9bf36d7206417ad2771daa11bc21fd7ee1029b65ff7c9b2705a6dc9cf9cb 035994e89e13916ad82608f74a639e6aceb756ff913aec440519946d6434af9a60a6af49 a90990baf843f65082aa64d4dc15fc484c0c9935161bdb8f01a2396e910b708ca27be1cb160646ce2b29c22674c5184418a02fc30338e2b262afa76b6a4f46c9a7bdb820e1fa8f87a2daa8307734525be74f387264f4781112e6d118ed5a4b01 +f415d0adcd533dd8318b94560f86732c262ad2c6dff9dc83e2435543f429a2158cd2fbab0d96c027f71008c4895ecc644c2ceaefa80937f6cc6338d15d36e459a16bd9387a361a6d800acfd834ad5aecf442e30b70f5bfa164747cf9f89325b80976052a83a5e896c00c54f81472b14329cf23bec10a8e693005de2a506ba83d 029639da33f48e4fb0d9efdf50bba550e739f0d2476385cba09d926e789191b6fb0a73ff 8723e927ff4614d249f38cc8bdfa555b4088fbdbda5e76f5b79f5c3b31b9934044b96ae5c21b8c969a1cd94af3579cf20da26d5ab82794ff20311e0d8ad04ae27783b21e461f276df765bc9a9cb6e86a36a63d0437d10b98d7d9b0d59f79b5a7 +b178d86c9335b85e02178fc4551769db589ab91d823fac219c7e14e2f029753b203962389476723832f8d9631dd7764e6dd35da290afa42a794476f5c7727b3688aced848dabc9954201578cc7b25801710931f45cba1199d3788d64dc0188412e70723fb25b8ecb6718358150c4037b5b81466dac1686cb5270bb1c72d34bb1 00583a7ecbf2a975a32d07428d27ac82e5dc13d1466c4fdfc1e6a05a8d9a289f1010617d 8eece4300065485d1b930a14076e89b884db3dab1054a9c9e0d060665a4a4beb029750199076400a5645e0f9e0b570ba16406d6395a04c06649d091957308990ee847f41020ad87819121edab22c63dde6d4544ef8bbd0f08abe3e321913de28 +c8bfe9fa7c848531aa2762d48c153cd091100858aa0d79f994fd0e31b495ec662209a9c8761cd1d40c3d8c4262cf4dc83c4a2549a5cd477726ab6268b4b94a78b1c4a7e700812872d7f41912a723dd9abc305420ea1e1fb1fee41bf643f3a24abd6e8fbf6fde2475e290527724a6f99fd75374bf7cb01b34d3e60d8db33c4de1 00f817ab1b49131fb9bbe8c112c25a36f064efa85de7506fb9cd29d81b326bf276277f7f 87872ead9000e74cdb1e50716560bdbfdd2791864c246058c6a00edfd31d1a10f4518fc037a034e3ea5839557eb43a1b164135554909a7d1952c4b208cae91eabed6a9640e86fcc324bd9c2f1191b95a78775a7f8fea2a0bee888a8b5411ad9c +9a5f563d0f9fd1f31f3a822de628ae970954f4e71292492d727109036491c29e66b9b0f2c90c26abe94c08502f5e923a9ddaf6a7d91e9541ce90d0a49f03ce4e4769753d5b7d922e1ceaac4b4cfa4262732a09550aa076b8ff9d46a50fa17de17e3b6bd606698464d116fcd5f1ae11bf45b0c48d3b738427cb47b0d1272b03cc 02782af76ffebf3e2bfc0576b70e4f4bb87c762e2bb230d278ce776310a14f5b678f29af b50f921d0b29dadc47614f9596cfc081a4a9b7d608de91b7ad41b057bca6f90f14ce2ff750ea9d3739f9e1cf4731f501168ad8d25c474835954d96c879e804b12b5f293ed41835e34c9c091257d3eaebd7061af41a55e269c8b68960722c2288 +3d6b065721da9de82cb33ec2c27107eb399b1e69ac8fa51145ed4147e20d72e27434104e76af988a3bc94f55e36677a05182fe2376dbe38195fc6a30673a4dca87336c7304f3f31d49216fbdfea00fd1e105d8b0c13ab11f8892e0045e915c17dfaab07b24ed21b06af5a8cad4f45fbee5a25bb6e87466a7bc422c0bb896440b 031b827b88f14d3822244809096157df3c0aa99da90c00cd9f0b18dfe306f6881834e6b6 a7b783a4c9ceeb525067937c9a2b8b32cc7a7ca5874dee6dab4b82c58aea160ddf7091eff7bce9fdc9cabc6989180b340d813cd6f41799b987b5fd26212e11d6f57a1d35964a146972a600eff271757f10351cbac1a4a4a17420b3eb7ac99ecc +d125f0e2e6135567adec9e77da2afc6862e28d618416632ced829d14ee8b61116da59dfb44098a40a0b927731125617e3d2f32cfbd1546a6e758c1ab6597e75db07add52ecb61d37da2e9ed04df95b36ac249f4cbd794cb561655cbbe4b34834c497b3d392d78ed0db8db683aff0076fb6e43acba3fa2b91210cc6cf3fa594b0 027da4916f1c471cff80bfa14d12aa10270fc3b26caed010c0111f6e5a40d914a3927763 a967cf4dbb8acfc65e3acc14286fd152fb18a820e16c0bdd7c8b41d1c7176ecc7c26e6a549d7dae5f923a5c4c4084872181ab9bb6b796a8f04be8253e001ae730a190ec8868a6eba2bcc50897fac47f6dcfaddf6c1e9c8b27cb21182b865c10b +b380f97687ba24d617a42df1b14e5506edc4b62dfec35ed9fd886bb769832cec7f9adae10c21b7cd9152588797b4efc6b2b30a873d3f25e683ea9be070dd69731949a51121e534fabfa3a2eae0ee90a454182248bedf2595cd47ad08614177d58f7a773f5023b538f5f568682c83fb60e3fb1aa859948d01bf7b214e7f2dc719 010608eb51dc0ee97d6e488a23c582ecf0ea1df9a24db77094d87b3fb6ca98507280a934 960253aba091bcf72773251ca1d272a66fc1ceafbc0bd12bb669f80376feca0781bc34445859bd8c1aead89d420500670dfc1f0854c759d56786390a549e2cea98f15194939eed4703c3be0b486a41d44e507b48e1f6d7373f2722d10257738f +3f9ec57e4228e1a6ec49df02c58d756515305e48763ba1dc67298be9a1548576c28c82b4e9b3f62357d9b3c522b16d5c496a39effbdc8290edd2cadc0019e6b9fae1e61238b13b6265ad2ff413a5a0684babdb0013e7632051455e6fd943815213c555dba96cba8911e006bfddec6c3353065004538f37e48df9e339498d85c6 0123f9eb8babed548df08cc3afc1d3b3bbed52b538d4654f2088fe76062fbea75b85a560 b8f3bfe30e331dcd145e035c7b25d1419e530121fb3e07418f88a178034864dfa889972fb2cea39737c340b477a544f815bee7f0969d60dc0bf76766ae224e92089276d8cf42565de41757ba09698188a8bc2739e5ad11bd5f211de2037ffba4 +bdbd7b7bf3337bd9d21a3c6db379f95408c17e49dd394e94737ceae889f45dc0ff5d48cadc53703a16b5589939506b548f8dfd34c577c084f372166cbea320c8fd07c809b211e0749ea639e68f890affa1569b66bd763c7c710989e491011371eb1d93ed9479ff0216b7f79c901a2023e2cf80b565d1c0517e73117190cd2f02 006a18e626452111922e02e31d662f4301319946a204ae8a34f06b91dd1b5b96456365e3 a34e813312f15455838456cd143c5b262b86538a01eb421833e5c495d174a198e48375b6a7cf897b1efd32fc4adc7cca04868830b97edaea4c6e89b73fb716519a93435ddfa9f51d57b9ef2551145546dfbf5860d0077ccce106edd47fab14d3 +436b288512ea57bc24f84fdd117da9dc1858bae8c11637f99295d88fa9d05e3c053a2584a6fe200ad190b3077d9a1608f660349dda405066c1562f6897ef69b6b674d6bc11fa470d0b96a7cf8f6e098c9ac03b0ef415aa045867ac7c11d16cee78ecf08850ccabf70f761682b561d0d0e4a889d840dc74932648ca2fb58259f7 03307fd717015b12a2dc76ada21442ac1d97519f66898b214c2ea317ab0f0905e819e4e9 873079933c2f0f5814cd820a04ee6f9f060527d85b58394a0733c14f8f49dd41af9fe9f6c040c21bde00d0d93deedc4712fd6b88f367f92099e271554cb5f1d9e95e6203e3b087eafc739793aee6bd70caf82c4a47b823a9fe3f658b69fd7dde +672faa156dc188bf16bf8933d65e091c633f294486049ce96a4a403dca28a149f4f840e8bef47412285363e9e89006614b013a41baad9885f1d9980cc897ffbd5f8a7d0e63feaeb42c07776efb307ed680ba1cebf470dd9bd8a2a9efc2b1daa569524394f9a50398add1a5bd2f7c263f9e63c2d49461acf98444fd23341ce78d 014f9f412e3c7d770626e800d43cfcbba3ae6aec8563af748e8a97b67d244334b6e6d2b3 ad78d0775ff6e062c37d9299c4338d149d8a172b77e967af463c880d10fdebb1cc7882d92b1c9eef0efcc26ba7d9102109cdf7233a1afeb703032585cde4c7b884b4fdd3e09f28148558247fd6f7d698335389b85e4a0c08cdd075ec8236645c +4321334cc8ee44f1cb392a4b280a95561809dd3639ddf43b6e11cb73067597988d95b8643d86c76c3c6b932d9262b9b8b55a04fba0666dd8b8ff1e8fdf799ae3945b6e30d3af3966f1a6d634d5e012710d66cb447fc3375130968a2e1e647780aada2609d87247c90338dd71c3bcc3902311caba27d5d4ea4d73ccea960d4bfa 03091a6a8bdac1e43542dce752694972e734dca31c061c7d1000754296d0748055db3f09 a570d13ae233b033e23837320f8c60ece507c55234665b0ca0fb63b6c71b361bd7192f5aef7b78955dde30c2853594080eeb8b5923669fc8fa196b12bba48beaeb90c491c2eaced7c63ade817dee3064e2a3a844d866fd72dc7f4ea374c1d58e +2087e22094570d39fa937f15a3ef0601709a66666344186a33b487d041793fbb9709a95af250b1df0762ea98e911aeb3ff1fa19f0aca53fd4179e454e0e91636e55cc5b17cad9e1575c82ad265dc34c4a66b7a31ecb9ef9dc756f2ac1d9dab35369a6bad4a0f47e629daab91addc6d297d1e5d81477b3966d8c3b607ed194d88 01195921b91353db9bcd00510efffe009c94f6bd8d790f5fb3e5a0101c9ca5d21c6ef2eb b9b0844974e64fee4639fc06cfd1a2420365898a8b42a9551bdeba9ebcabbbf9125485af152cb358c95aad983449e0f3008240717cac903fad5cdb7e647d9c583fe86184194c7dcd9213b379b5d836e508df6fac878d5bcb832912765b24fca3 +15c7bca449a73b03bbfa783f5a91ca0b7916889a5d99d541e2e8593c3b176a5b634ba20b34407fbd94ae1c1398f5313cab7402f3bcd7ad277a8c66d09a6df5dd086b20a0a3823fbbb80980cd86bd13e527eee15656cc977103e80113539e26695addd9eef6a1f56986168d9a53f8b5de833f8962c3826cca106ae9e8c00208d2 029dc20446e9abacb43823e12a83737b46e6e577466b5a3925e0f9d496824dadb4d4b50c 8de7687ac46be25e47086553910419032c0c7e68f214ae84247796ddb4ec9c6c387fb22127b22082e6414cab65fb5c640aedaa83937ff5083db069f529afb29e55c2e072b485df3a65ad4df5b7d004c13d6d758d41ece6bed1b33042c5c1df94 +d12fbb82ee7a57eaf76b63fd6bc6c0a65c85f135f019d43ff7bc295cad15d53729d904fed63d69d3ffe8b82c0ebaf0399e2717ece40e011f710b5db46aa457c23b85545953398b814816a1e7a8ab5b0b14c4a0451b0bda9d0d2ec4a374bcaae208b7fe8056bfa17d6b7ffd4ba2e9179f49b9cd781b0c06f6ce3eec26cd428cb6 03b9b77d19a42e9a555da8ab70aa5638890b2ed21daefa28ca6323fc658662dabcbfaf52 ab7824dd61eb154ed05abd274fb0d86796797eabcbe27564e119c1933f6a84abd191977dee447002342d4dc1477723eb02c4ff6e4ba58462a6d4050e277e510c2455b46fa5162bc379b52cf5f7e33a725c20e5418c3b9c6ecb0e2cebdc54a5c4 +eab0a37915c6b43b0d1e3ef92e6317b3afc8b8301b22f6059da8271fc5fe0e419ca6097daba213915855631af64e10d8382d70599d903d1535e25cbf74da3a12ba2f13c33a8562e0db03edce791f1d39af8850fd1feff0eb25f9ad0a86dfab627b96e65831bffc5f6d9693d20493bc9dd6eb3e9325dea50b055768e8aa30d49c 00b9f8f3e89e9c1ef835390612bfe26d714e878c1c864f0a50190e5d2281081c5083923b 80d00b31b2230ff0bdcb0c9b92281bb5f34076c6e9f187a0066a1383d330b12803f00c5ede3d94841b3dbe0632996c5e04e40a11ce6143936c24b823db5d76d703678260ed8c46eceab27afb5f865c172efc91aa00e94c138610a3764eefd29a +fdb93afd5dd1e3eaf72c7ea9a6cddb07fc2054499ffe152cb2870163eee71ace5bd420b898cb4fa80ea53fbbaece2a1eef6427b632320e9c97e38acb16b62fdbf6585b54fabf0a703307ca50f86387bed1815a05b0c8991e0743d10cdf49c8facfd7ddeb8d4a7b706b5a29e1d00ac88b0ee88b3153185495ac8388cc70104154 03a30a1c15b9ed71e102341f97c223a9b5ea3e6a335861c3cf407ef691a18cc639dbe74c 8cf64ad1d98c62d093923205762f529de72a18ed77c1968f3890a2746fc3fc455767c107af7bbd949c9078e79876d7f00a5777f07573914e83c3627229be8c7efea3e2838aa4ba57b33bb9517f96ee0ef46c05a59b2982ed44dba86a6e4b2929 +c78e35d1a5b1bbb0ec21e7ba7b7c74c859d88f3e100e40ae34128cf093885dae4e87cd09f3239dd8e79e25305220880dd352a650225d9bd193b9b84e488c458b0b5fde1af941c0c9fdf952d2fa41f665918dccae27ab7923da4710f8c27ac8ed424992568dd6f0a6c3ecead21650ed162e0292104eef3c2d8551be866a88d279 0083330123cc64c11888c1fd388629d0b329a50ef31a476b909a182c930ff02d0c389b93 80272b170ed0cb14483cb02b08753ca9f90ec4b2a05b3b7372d8ea171ac6921d0211062c461675673e0cd1dc8189f6811447b8b19a611e9cc797c260129ddfa27b7b60c22dd988d96c1c055c186005fe60db28ee947427daae581bab23671578 +e05435f695997229cce314e50065f3c5f71981988dddccaae6efb81f936b22cb48813f506d1edf5ebd69b0be34f278592c5935f0f6db0cca1ef9d62834fbf3c4c03f4da0596cb4d67b7b767e85dde7b7c6fbef7d89babe6f97b876b33594a9e36ab87079861ee556fb03274ad4af527342a4794192b8933f28c6220f954c77de 01dc2b656c207eabc9e0d6272099babca8d149c9c4258b779c2f06de75f76d77505271c0 ac546b6f2e9d5f30f9339c7414bb0f0bca3947877329dcdfe4f850e09061510c6486313375c2b5acd02cbe782566cf01110ac288beede2bedf6ae03b730415965d8e2901d86abafdc46f93cd2e656cac3cfab3b46c877e730edc204e687a03cf +0f9f36477076c4b5a7d1ceb314a397fb14646695b0803e36e98908c8a978770269f165a1fed8f4b655d4efd6ad283d7f5d51b6e1e302d360e8ebf4e887c7523a757ffd55384e114bbfc6b7a0ec8511079507b919065ca018573418f9e394854c5704227772161707b4d0246ebceb91192f0eb2ea994ce61fd98a6d14cc8246c5 00081772348ff2d7a3fd57fe703555ab2e14f5d203c4cf0292f944e827e884d95f3b1d83 a160d29e44b198a6170e479ab81571144cf08790e2f30d23fe134270fc308bc8c8f46885c0488fcd88a1458cc40fdb9804f5bd2f7da85306b1b2e501cbde7e1de45d29e173bbb95c4a0124d2ffe650caca8d482dfd3b71acc980b56f440a1c2a +1d38b1c342b6611dbaf412a66c1c0b8397692755f576df33b31c2bd12b7f0707cc423376391f7b00aa4e7b7fe54532e2b39c3c5284b9c8ccce48eaf9308ed338992f1d4ecde6cbe352e46339d7d602942158387881d9b493fd40cc59d4f9b53ee4191d42352c6f7bf32c331f0c5afbd44a92901a4b713c7cf6ccddf7de4cc6e4 01eb6bf2ca1b5ffe6f6a795733eaeed12de6e87c53571e702635b9dbd0d96b47df4a005b b4e18b65cf884fba94cab47f08724552c317cd30420dd54a89266d1aae40f42b73ad3603d4d91cd89e769324dcbea80c19dd3295ebf4b5e0a5f81e5efbc0e410bc7ce0332915c47c4079393743e8d9be10c71060ef8f284067502d42029c2383 +3353ad05ef90e9762bcfedd6ef44a1e8ea0392ebef30cffd48ae620f3e567e1cd44882d514e7c6759200d4bcab18afd3038c3d3f8c50f7bba32a04eee5a4b1cfb8c349939e4efe0a46fd047d02ed000d8fa1b98b0af5586f120d9ad174b3aea33905b979ece1eb3660b1e070c8821b32df41904ad68bbd8ed247aabd94066f16 03b2a3e65e5a306bf8e3955b60e856dfa9bf68c1275a678ca056207a0ec67c96eb3f8309 8d470386f0120ea415eef46ce792ac95d1728484a2918cc85a6665ab72037375da146bbb980ae535322c8fb20d60ebf305411b2fbe69e58fb07eb8015f65db74cc863e6ee63de4306ee25fd125be25b5c353ac93a871f03c2b758a856ffb20be +e7ec162185fe9a5803c6b03d98041422315ccdac67e48fbd07a1ef3c5661158710abc6791bd0a75d56791b4ac0e7695d53c5989d9fa6a3b037583b2a80d2b154b024f1c36b63548be9afe1d51f2f68b2ba94d4ca1e69a35ac10e15ba72242aac20f7526b12ff9d3cde9a9bfd70d55adf9bd92c66d092d7d08e9764c84bf7f329 01fd4d1af0bb7c79ed5fea7bb45574e46534387bd916649485ef15207352d7302e81dc01 94ad992208258eef723f79e02776f29100862a67515aadbdc132a129129924283a30ae1ad4cc14b9ad1c0a01b42fd6d00ed65b14f086a4fcd304b26af430c47b011b47fea4e584d58d5886bf4bba0600f2d8b320dcc2ea3240bca7e7a7e979e2 +87c8f2e3f4fdebce0ca9300fc1ebcaa934f51a12b6b8f2cb6bb6eb77965468663044afeb2a1334cb5a81e74b8427267f8b34b5e9ff0cf157a9f18be2b1942e32ca61dc23ea13c3f9fcfa16df8fe05e067938b6994982676463fb12842d4ec532cb904cf222aa805dd0d86ab9a33a83e294c6d81e8dfa273835e62e9041dc8ff6 020380b1136b5283e9b7f54b7535ebda33b129ceb177bf5d3d07b1daed5edd9fb3862530 860251fecba835b91005b40744d7b3f0d023e7fd64dd3179a794f44620a88c9e7f3c3a08a4ff5d92c6ddf20a899790fb0e63ddf1e277bc2c04f30b6c080c9859045d56395dcb47f109bafe0d1d36e6bd6ec620ac4d779d712530cdc4cf28595a +2ac53e8a50c4afe3b38904255b7cbf150c5f79dc15932dc0ac9aa631521f68a0d4b6bc5a04d55c99a36531fd4886a23a8d99f262ecd2a9feea925d7a96ebe9b6979a207b7f9378afbe404fc8e959b0333572a2c911f8743c0ba64eebc7ef12fe5435d2cb0e5091ae518b6e4233489efe3c16c6f21abf4e2c6808b733914e5a7d 019f815b98836948e0a0dc9c30828c31b13e175f1e79f23d084ae1bbe64823f4866214b5 8ff351152ed94f7c0990d0012011fde648d87725f2527b514626ec11da91ab7a70d20dcabd2af620c027f172fc6e839a11b2c58c5c9547d24eb49ad66d11c8622f6a4ee8a9b225b0ceaf53a5811279d03dfa197dc8c9d2636aa138f4601e45c9 +0b201469cac4c078f587edecdcdb6efd5752cb4a3f43ab540463c4d908c27527aa3592f2f9acad85dd94a3c056bd28618317ebdf2e7dd6c5ad26fa3c31dd8e5c50c60418d91c93bcbb59ec1adb1db791f485ded78a5cdcddd23dd1cfa4f13443468d8a5f2d648059b9c4470d0f4fe7733d56a28a2c24456b6923703ef32cf0b8 001854e954654e726cf4bebc0e5a840e8809fd716059211c6ffeaed36829808363164684 961434aaa0d6563e65d030369526cbb3b0d9521939e73e53690a02bb5c216cb25f2e09e245c44774f96b69cb302715630e7c98cdc164a260d90007da3970655808f0f2542723a45f93e2c2aebbbde0382f0a243a3ac9298c34b70e25ac2d06df +fc5e4dddf4c4a328b685035ee79069770fbebcc56c14e31afb4bbcdd5220e025f31eba794fd6c05e64f19678dab33ce4f084bc32790392f14bf35669d75b6466b4214ec30d58ca90ae285c9058f5804a1fc9d7a995958f2a0e84ee52e8a78b601bec04ab607ffc2091749cc548c6754ed14e2e5f92315bdacaa7a12823ef76bf 03548f8020819588b3202f4c1ac62eaec6a47c2a19b2900c5a3cf5b4ba5804231141c647 99845fc6c8a32e4115d561b7123c01b0723de12d468c7ef60d31364fa26cf95d5436c21ccfaaa475e342a7d22eea957c0bbf3643f98861d2a02426ee9496d4ff761cb5273ae8efdb7d6ae290ace908e49db1fd9299796116d47e40521441922f +284cad790e6207e451a6a469cee3befc3ec43e047cf91b9dff1485718aa29de36a43f7c51eacd8589f0c3a96ec18e8ccfa92941b50b2132e3612d5b45e16f60d411d1c53e373e1ba451352e28970ada9dcb9802102518a385dc571dcf6900971b00346098a58042e0d1d129bd6801fa640a895a458a45b31318fe63ebb30c6e3 03cc4505005c41142308f1489226b7b542e2e7f24f1d3089ff6b92a4b0013f490ad52e60 a17a1af07e20ede915f86d5e4218f40fa28cc15aaf6ba20008f022e3626bea604ff6998ec9a25cb7b6be764ed76f2c420a244cfadb6554069dca439375001a65420a7364603e4043408f944885543e04e0ec75ce11f2771bfea572c01e7209c2 +6d46e57abea9d115deda48b69fe8e0b36144df2f6a659509ce1b514c8cc4769d46e5f71df2a084f1db4a22fdd3ef0c2f90394f2898ce291b9f279c0664aa01419f5f6bee1fc1299871b27ecd57a5ac548f99d01871b8c238a6b46044c953b2e78e22346a0c7663af4db62799038ffb5c21ee512e26d01e70a4ed967377ab8405 0144a2fc8e0aa63506e14e4307df36416f963dd9da78655832f5b991af8c3eb97df78efc 98199cd6f9b3abbb8bae8577fb5e05491df029f63efa32e3912e69e6ee63a1cf2d05cba04479cd9e0b15160a1056c913029fe1d11127a2efa0533dcc5884fe0b89bcea2be63c8c82240ffc5a3059c908ff529c0934354fdd5e23cb1d6e5e1c03 +dd750b39bd8753f4e473c4484e2b36ce2da7576813ebe05861c339ffae1d029bc793173ed394091c00685ad82f0550cb21ed1c68f0c27cb7396922239cfb886647af204e88a9101b7453a8ab662e270b87a8a13f2fe61d695597382cabeb781933bebfd7d0dcd33f77266e43e32d937f2dc89f67525e522977ce73e9ad36c8e1 024ffeaf139043ff25a395e4c560c7680c1c2155191378917eb25194136b4a69597dc277 af070c7e686fe8e9363637726a89d379f52d96bcdd713694a810bfd5e784354e02659f65eeb8985366dcd6a51608f6df02079dae3d28ee3c4049c112c053e155d7f06890f4f5041efe460f2079055dec0eb4f65412266820b2787ce3019f59f3 +4736e59fe5812f63737eed57a570182c065538abd9fb0a1c9c2059199e7052ba57d84b5fa1cda2ad9f216610361ce1dfb9334816b6bea509283756a03aaae2e5b0597f492d078b6b015a40c9785dcc5d2ae266176980db04f5cffef40e16661a50ef871c5f531d73fd5d114fa19bae9dd2da4267a131fc31849da38c2b78d1af 01d1f2e0f044a416e1087d645f60c53cb67be2efe7944b29ac832142f13d39b08ac52931 ad0f4d557643452404dc315cfd5b3a79953f66255c8e0efcaaff7357296817e81f82861a148c002e3b5a37476b31e14711fd4ad7cc11e58725be87fe3b44c4a8c5068b14e43455cb65f8bc1193529007574cebec7caef2fe8b53af1a02bde040 +e573fa7d4bf5a5601e320130de91f4ad87eb7ca6b8998488afcef69c215b0cccd221b8b66eb0af9d699af9ad6c4b4a580e82941f31e4c0a9bd83995dd076c5ac9bebb34481061e7cb1b26f6e8c6b26ee4bdf9887f7ae2eb9fad3115a21dcc96acce85d23a040c0ebbe0a56e75714dbfa803d6e279b2f4280bcb993f96ba321e1 01337362609df74d25f7adee382225e6a04dd6ee4c6b45fa31499ce9edb0ec046325caf9 a563d022f8cc10be7a505a7a8be7ce564bdbc2eee8f917e5e20746f723199d5faf51f05b7aa5d2e8a549c152116b586700aef434301e7c4c944a89ae6adbef5e8f172949699c82fbe59c387a8966993209ffc5e5a80753c4daa919191e14fad0 +7862864d0d78b44e2a28af44a0a16d8e9b1b8c4b794db0410c0a863ba011018ef43e1e11f2fcda2f56fdb2a69cc817df425c9cb3b458922ba00d710190cae16d61af3c304a42fbb3d0c4a74a297253fccd70aca414865b41f68b01c561be281265fa89f63f975d3101334886e85929a5a47fa8dc459b663548faf8ed7484958d 01be00aa0afdfe92e24a2536594d4b41701ad4dfb223aab35ff49310bdba7566057fe8ac 93b0d4fee1bfd3e700f23cc764db39d1f9e0dc40c1faff96812dba1283ab2fa46c09259f039e84b6c2a1ee5cbe5844e711320ac806438169c62bb5edafa741ec05677c9c64104e3a2b0b72b2aedc7a05a2136d8f1d663b7cf38cd6de753aeeea +e73c96d1a84cf7cc96065b3c6a45db9531cd86a397e434072a38d5eeb9a90f62bf5d20bae22b926cfe967647d2bbb5dd1f59d6d58183f2cf8d06f4ac002ead026409ca6a1f868b406c84ff8887d737f65f9664f94801b2cd1f11aec336c0dbd4ec236d1cc4fc257489dc9709dfa64eae3653ac66ab32344936c03eeb06d5852d 012ad0aa248db4fbc649f503e93f86104cb705d88c58e01d3ae0099590a69aa006aa7efb 899ce47927f2d3a9df93c71f557e1d0734184f8354a5a87e1a29a9dd2bcf62bbc0d8dfc0be7c50cbb20ba63fc439d92617fc349a7055d4198c1c19cfef1cfea7e17b13cae7760b6e756abef1390fa8fbf845c00f733dc1cec80ceb66be6a530b +a73fb0aaec838d011110d49c5e94395ce07408917bacf7689d2cfe0948c582214b263c6b80e0a55f1e159086817605723740569eeaa1bae96b979679165c5c35ef2142525e943e595e6b4b160acd7ebe41de19775346363f779b1f80b6d5f0785b92a648028e456af8496102d19dc6526247a654bdae3368f075fa9ee92b2f4a 02cfbb8f340cae8e2e2322829148981cd9e509b0c65497fd8d9da5dee9dcfd39b0f7556c 8b374465da64aa57f518862938c1ddeb3f05e7b3b1b4e45c443e735328b8f7ba2d529ffc6f9021c6b65010046714b12613a4557de7674e3654f01d4b7f37b60d4a3e616aa5a109055c758e3096711e8be672ed8c23bde12b2ea30b8c80f12b37 +eda775984c7c9f7db47af30dab314d070fb77e9b623baa6b73e2cbda800f167b20fdc2e7219391efacf908f4ceed9b9b6bd3541b52ea087177e18c97391214758cf6455311fad336ab56cfdce57a18add8cf85b0a0bd6fa7297dbaa34bfc8585b0f06a0aae055186658c227e19cddb65de88d260f09f805c2e8854dcc524189d 0070e82a1f3fa6158d15b7346dd56150faee5c98c9d07c996e01a06dc9b211b12ff62d60 937466242d2f58ded8f04f799c3f94f913de6b9295aa008d310c296b844c412e7e89168ae41642cd6508483510712be91628a87b31eeded0c287ee28f456d128adb97c200a103f5342a663a0cf434621fa05ac5b0decf1ab58fb4e56270c024e +a4a13e0bfa761b9bf37fade6570d41c161e20558874911ff3bee38e5649849b159beccf321c6bc7243f99c01a2fadbab9e157e9952ca65d8ea676c74fdc976d00501c626b8465c6cf0e4fd1a7d1260aea987161b821528b0b423e62ecc5193a0a49442b0c3e4ec9c4786a3a86b199c07dd3a17033d430d2c83c100f54e0a7c31 00b471bbc5f7a07996e370da4a09e71e2119ab3a562a273f079401951fbe4df39a4493da a84fd64ea2ed02f53ad94d04b705614ef583a77fff4d61fdd1185e3e1f896150b791f6ab1724426b189c0b25ee3c2c1e0563a6689c77a306c28b7b3da3ca8c4f80b92a3aa52b39549c927355d6e2eb5d53d3cca8aad6b35ee3506d109aa653ab +7ceda7a7248640f7055309ae712c19d741375d6a7e0608e07f0135bb830dc3e8863ee9e7a75331a5e1bd38c42cdd484d4f45a26c2c1d4e05ce0d0ca941f4e94ecc6b371102f31633629e9861de558bcb6407d66eb91f1062ac0e0409db68b9f2855296a7f42fc92359a7dae16c73fd2dddea52bd866a4d501aedd8fe3b3ea733 03c65cf80bfb507dff52f9bf2f93df0642020d41619b3990009409e7210fd7130ac44ffe 84c72a74dfbdcd3b4f2a6c74643aefa6f2be669f3e66b74eb874d11748fa7b61d063fc5923e5c2f8b03d4c7b31c42349135805dd3efb1845ef8ef11f21006d9adca007725ae495436dd5f4aee570d6248a7c88790ce521ca4d0823c8a297216e +609815edfd58c0e26a4b06dded831d2f33466a130754b96d8d7c3b4d99fd4b0789ec719bc25338d0ae8c5880560c02687d352d77c291e406eae865c3b26d00f2e63dc644ce7e01d6e96ceeac8bc1eeb257d36cbb25d89b5fff6e30b6051506a0ae54cfaf6214f30985d54cab78f708029c1fc0175bc58e888db89dea8d300abc 00f4d33a9c7e6744ab3c441828bf0f1866ae1c042cc54abc754e3801263a96cbb3955dfc a8fb6100da2753b6b864855a8afa55eb9bcf57224c7917d9a0e72d39ef6903a3f525ac0de0dde6ea498cdd2e11d9c14b0b317e0aa4ace11e4e9c3871b1e2f0d64dc2cd91923f69b66e37095a4cea2628001b481766814d23da37064c7e26cf58 +82d8ebba707b72655497320200ce719520c1ae7f46f38122958fd99322c25c9f4d4344bcb77a6658df0eece5df163412ecdca58475d56b0c2d14a0361e4cef458df146925d473a43692b15e9bbec550f1bde3444f2a5b2ecb55d2abd273ae999f16a32333529d94455e485ca4585e6b07bedbfc2bd1eb766abf0d28bdb1ae6ec 03a4824bdcea6a144d85f1b194431724cc49849b6cb949b4766d641ae95477d1ec3d1464 b29dfdb3a91859f5c1c40d4dc11dcd84e0540772f55637a24ea54a3af8841d607a5cee1cf3cbbafc4db5a87b70edcd39078b389cb82cb421482c4371a4dd073fe3af82a23f4b6099ea037540d905542818a870382aca4e046f631d571c5f284b +9c6fce18a6a96349b10c9f2f5f1505c8ab727a650b44bc0782a5f39fcb48b45fc7c1b82180d5f229b8abfc807071f931d333d265fc940c93fae7520d8d40ef59d7c6e3678c6a2ecde52b6a8827b1ffc6ed269cb9832feb20e593a7e3d4708309342875199eb2ffceba7ecd707b122516c815e83e27872eda812e3ea52ee3c4a8 027ba543ea785df1d53d4ae4c1bd0a3a994cddf0c25d2b4e8ff17ea7aa00619e858da1a5 ad7f8142fe799575e247b86d6107053e104a6adbf5d883c86f4e9b693ca019ae972c9f2c1a15345fced979aa8176431a16c797ebd3e30d04901d0c78edad91bedd1157a41b62d131914f0d9068edf50913def09b8722879813457a8a90c5f339 +5eac15a64c7653d125605869012b8f036804817aedacbb5a5248a595ee0c12329f91e8179c187192d3ed0d4ca2e202d8d4d9c93ad3f3ed931121c193af5b47a8a5dc39775b6c2d702708e5134f77a31bd62eaf87e39e6fd3f2b9f782c3057e162dd53b3addf92bf0ab99835c7f6649abd1c5322a1ebb2ba313df9464a74c14d3 00708d0907d14dcd5f40e2903e1e90e48a0ffaa6d4d9b84ca14df4e985c294f74eb9f2d2 a8d9f8a5708cab6b2b7f5c2390c887d00b21a21809a13d8254170524c43b5a547546fbded240a693507670865ae6d562070c36a5ca937fb5f91271b9bea54af91b031ece6a0767fd67f851bfed0d5550fc7c9dbbd38f859e9c9a6a3c9bb5e569 +df735a7e60bc267b18f313ad56bff830be5ef119baf43ce27c6368ff1dd89f010afd4f48740b11c12101c5903bfa71d6cb3d6462cf875bbd55a570ffedf3564088dfe8c8d3148231b78b5adaa6c53696737d4704daa59eab8d986fc6e519e81540f201e77b923a6a4af65d7173635b3b19b2023022186a7b8e869e1ed51717ab 021fb0a6b94080da8b8299b87457dc09d21bc430ba5f3359d92aacc1151be9941739567e a33fb2f3bbb056514ab560319e8b4acfdd975170fad567e9f64542234fb8953ca21a5d2951fe49d70cd4031f8d287ef7181f545113036632b7f5c81e12699e5a76ff49a1d31bf1816b8e2a32b738e17283ef512ba34e5f24b891d934565b2611 +bb107b0eeaf175a786a61db923bc6d51dad5e922e85e57536118e032167b197b1a1f62d9bbcde04922fde781665c1094181c16ac914cf6fbbfb27bb8346b2134f05c55a8c6b9b481273758e380666d6e22c28577c29446cecc5c3df9ed9f1be060ca55ab2b7fda36a147aeb46df0275bb923e0876b703452fab42f6b7ad2ceb0 02c80151f91301fb6b0c7685bd172f20515b46bf94dbc4160d0720fbaedd40ec00084447 b163d351853579ffc7db060c9e22507286ddcbd661c638486f690020189900e13524ef0d2a45c2a0dd079ae334fcbb2614b17292a85bff9d153a76ea82c8ed415a2b53650d292a14ef79ae18aa5407102729992105cb43f21c8f29a3ff0cfeea +f47e49ae30b09b7666600b7a95e81b0afa1553da5e01fd917e4ce1b58dfaddb8dc8c03c0f5591f533610deb6a7bb5faf5dd1ec4103a587a1a4c58a110a706b0f301a5c408b3d984c210d5b4a0b347d2b5447271f25b527b3c7864f7cdfa735dfded47c63b723fa0f0413c57a24ffde9a95c35f743f892ab1ed1df704cde82d9c 01538abd7ce8a6028d01604b1b87db3aaf720e04220edf4d1d28c2d731aa25f509e58f2f 80fdd60f263e69a8b424aa6d5cebaf06d7968c3507fb152b94a97378b9014bab3a9bd482cee4dd2d20343855fc5f2a2a0a4fa273cc4b5f88b236fad4c54e29877995636497eccea067cb0726f5343c614c79ed5c24e5641473fc62877e75b228 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B283_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B283_blst new file mode 100644 index 000000000000..569c0e5cf0d0 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B283_blst @@ -0,0 +1,60 @@ +067f27bbcecbad85277fa3629da11a24b2f19ba1e65a69d827fad430346c9d102e1b4452d04147c8133acc1e268490cd342a54065a1bd6470aabbad42fbddc54a9a76c68aceba397cb350327c5e6f5a6df0b5b5560f04700d536b384dd4b412e74fd1b8f782611e9426bf8ca77b2448d9a9f415bcfee30dda1ccb49737994f2d 0299ff06e019b5f78a1aec39706b22213abb601bd62b9979bf9bc89fb702e724e3ada994 ac656ba793cc6c486a06672c1e98569e838b0adfbf2a51d2fdeeeeccedcf4cb769032ad4edd70d3c97a811af637191e912255063dd99c2c74b88d5cd3affe84ea0ef559dd7db1d9c1569c3df2e55ab5340f6fd74915a4e65aae70914aed0de76 +44adcb7e2462247b44c59608cbe228ada574ecb9f6f38baf30e42b589fb9b157bb0560e5a2aa5523b71cc0d7f583b502bec45d9b8352f29ee1842f42a17a5b16136feaa2efa4a0ae306402940ecd6b71e57d1467c98e7960de2a97f88b43487e4f4016af1292381d70c18c7e6eed99a14cdeb5b3caf73688658e4c5b54c81e08 009c2804f8cab768248fb3fff8a055b3f4585c00de5c1615a19f9425b9432ea09afba8f2 90693b1360b7b22c9d4023c656eb4415eaac7c98317686effe18a251531a6ea06f261a30a46467e591ab03bae8cac58a0266b7339d5acc06bd65c2fd858781f82e162a81ea3cf6edda606ece4bb8bf9077ee150cbb1616363767593459e10623 +cffee6252c7eb6d91d8fe100a1e62f0ad9f862d78ca2b747a6c17b8c9ea8980dc239b3b673310e6e7483582399163e39d889abc1a613fe77849ebc09b4f7f4fe0688b8a9869ae918a88294c7ee199be50ee9460db14725ae70b449d0cb48f30e7d817ec02c0cd586119341dba0b74f0279330807cfccc99c8c340b72c1764a45 02e625a6bc6d0ce7c06231de827068bdb0abc8ffb57c82b35ee3a0f873b9473905974d34 a0f9031f12c527c171ea74718bf0b7d20eb55a23cd3393f827276d3476caccc4d3c0a5142f7d05ea47851d8a2267bd0119262cd016ac7fcf9bcc2cb7a12a83ee7dc83fa40a5ead31009f8aba271871b14a8af37bac42403786c03a604331f8ed +d058ab5dc07228253707ef224897ea0fcd09c3d5cc91fdce9e03c1c59c53fb4596be2ed929c7455e67ac7f4891aed3eb06ad88f2c4aaaabff045b959f900d1019d706b60526375851bb891494e99995928e4cd51c9616aa651ec77bd7e398916bb9ed3156391bf7fb1e29181e2b011dae2edaf803607def2ac6b194929a57f45 0376ac24e1b86f8a55c052d92a0bdc6472fa03acdcdbccbf7c321ec0ccd97aa0a66b4181 94c712fb165a1b4e539418e4f05e8328a987ade13bf10802e906b89255a86f0c16e6a72a2c0bfdbee24d7d689a8b44150fdd96946c61f17b5277e00de317874fbf60b1873f5b4ee65c31b2b200f81a9797da3350b0b5df7b1cef6dbd1775b58d +c86f2cc7ab5df5cf1a236fd83792769474cef464032800ffe98a44cf29dbfb6f24088160eb31a11a382ff2a49f3e05e983462f5304272f96c0a002b69af3d233aebe867ee63fa46666760a6889d022c18645b491f8d71b6a3b6b4ef058e280cf625198715b64b025bf0449445d3dd7e1f27153926e617bd2c96638345431d1ed 02b50a6395fc02b9ac1841323de4520292f913519bc0d6a471aa28021322fc4dbcd7b802 81586d8067ecbd99a72bf930b7a9384d8b198f30dd816bdde639bd9c56d625b894c3364b1acb23dcb11b3e826d7984c7065ceb2fb182bc2d4581e055a0fa250f973f507f0ec008c0ec80d190dd2c3770a46b398666953c9209f9251b39161fad +c1328d8d2e5b6ffc850a9600bd6482518ddd9cee3fc9140febb72bcd444b0cd7e8074587d51b62cce4b3d4f34ad3355353fabe363369cf790db2df9fdac3a0ec4757e2dfb3b683eaa3e26531691ce765742e1c0bdc0e1028d347b6085fc459df0989c6a144271454eaffe413cae2ad7c8b2371fd2df1afffe56df727009765a2 024e5889722f6c35e18ca47effa9e415b1ba790066a91fb3c9f7b001ce28fc732b09bc23 ab291cec66ace055abdfe92ea47982ed875822c2e5d916845d4db057a4e478ff1c977605a05624f736a4346f2d380ebc0ad98482dd349b6cf9fc8026ed5348b891ab687904ef50ef4e8a9383d43dd43ffd5d2ab3a5f12efa14e6e7e4507acb89 +7176b7013ea27e94281977eacb976bb31c753bf80fa09680a29128a6fc15234f79f0e9900aff3217ce9be72c378042c6c34fced0158740073d1a985fa25987fb218002e425868fda5a47de51abfd04de34e2b8634cebfbdc98e80f93d94096193eaa82dc8778fc23f3765c7acdad94fdaa272df0ff0f28190c10a462ee78ac92 0056d15b81f40b6378588a5efe43e21b95e18120d514bfdda0e7759a1d0766a8a35ce5ac a988398a38d273ea0307e5ceb8d18c6d09915694998fcd5a7462b94e0581a3bbf62b1ec3aa48cb93df59c78b2101adfd0086d3152c3b5d57d0362f36c8127b0affc2b2f658e2ab3601665ac5bca87ea1e2613e33330291a45593d32abac31085 +4c3642ba040a9955b9d50dcd1c936688c17c363854358afa8ca49c6abd906dfdc4d89bb4cab0bbc363fb5b74e1f004d4b09ec9dfeed4c0bfb482a9061a1f487a3d79195ff7b65a0504bced3a28db0ebe8fcf8ab1ee4a3ae91324d15d890ac4c479144dd5538d2e36d3a587769ee9cd2d5c6f85a03362a022fe0efc4a3902b71a 012fb2fb5bf5f7e42a500154823a174ba2d05af71e3b0cf47fab46e673ea1822f1563def 95307fb097ee2ea2cb84b56959b21b466886385ed498a77257917d3604028e7f8ec962396086cae8ff6927e6a382c2500e5a2b0b915d58adfada9d6b5a197f06f1e8a1f3de746384e1789f2285c4e6c2a8a4ecd9b57c96bbb6bc2dd7ba5907e1 +e471f39c18b081362adc7da47dec254dab8d765f005ac574640d78c14222639245563912d942f3be212ee3cef134407334c8fe3602fa0e1629de5331643d76715dc1b0ffcebd484d86c5211be4b285a31688b205fa988e6c15b36daf396ccdcc209c7dde2a732f5c31c84c7ea041408ebf15e56632583af0131bd7f531b5fc45 030096c54fd480647e017f8cdbbdef292e799f054e3279d228b09816a757566a744a8266 b103685442420b5e7fb8b7613d28a7ea6d81ea993328a4fcbc9524e752cfc661bfaf7ae959d7af9d9dd3b7830dbe7f55134b247d4ccfa09bb4f9dcd2c5a2966dff3ce0978ce6cbd476ee9b2e56d6fff1819fd3e849056dbd6e9304e37c58a034 +8a93fe53e83075c4025228540af7e96a588520da34e3eadeb99a4ab2f3dbbb8f85fe63a3b86c1f4ec912e665ca05b43e869985eae3791b91205afb1380e16c25b74e6793fa63e4a55dcf25dc22d03f09deddeb9042b620434111afe08c5657c7d754af66ad91a1b5423301b1e8e6389a1404060d1b6a99fe0f89598482979e42 00a1b7e9c8c2dc25b494b5ef3195b294e41cd3c2c35235ab42542bd3e2a52d5826662bf9 b7a8e4dd6f6be9e76a16e5a93a203f73e4a97de10e0cb8158ef94111d04908386e1ad6e9b31bfa15ae0036f88e791c7c16955dc68cf2f4338948239ad68e78eaacb74ae3c3969d0d78037c28e054d0fd1077b23ab447305b21dd4323d26a1fba +e193a8ef6f454ca1aed38bb67aca6d08280d421b196d89938c0582b7cde74dafd71716f3818940af412d4a7ff3960a8517aee108ae03576b68ee7557d35e6f1ab823d124de7243dd02b542591f62c80d822608572889573e4c9dc62f99d68e07800da6f83cb6f5e03d1f2ac15f90e38b4f25e0a75e354e4b60cc81c0bbe81d39 0059b1a8fb84530bba7a607ee88310e31bc6ea6a6881603567a1081a05a3a9ff87e719ef a4742b1260976c2720b61f744ec928a96b491f7710bcf6ea821bd054923fd7e45ea9199c0ad3443c55af89acec5eff791178d52dececbd3003ec6458ff5d6d992dde9b48a0a083aecb6cce2dcb673bfeb03d3e4bfb34541789c7a73138ff56ed +8a99b9db191f6cabc88b430bc2293e6774d5180f019d871839289e25aec29379f14606e742190b7aa062e3b29fe0254146d9614856c5140c7315015abb98ac00da2c7e33cbcc82c24b797366f12767322c4381454d9d1eeaedb616b0ea5c66d1422da459f18081f4f966d05ce279c6ee69b1bf94b8388d38d4b770d9ed69025f 030ddc2c7a4ce300cc2b75f0f977033f16c1f8bb13aae3d494c381f9a6dc8622499ae4df a9acd146a9a63eb0839d0d7d699101dc6f01a7422a1f925a5491648541ae6894c7f5c7bc06569c38b30ceb97a1bd501a02c60c3301b5e977efbf7f909d3797c7de35b7704697316a322cf1a0a05c92a59478d4d5482299246d87da54c558686e +5c437b331831530aa94623b1736f00b986172699f0a02a5e5df0008bf25341787e2e66046f2c929dfe0058c3cb89fc5bebbe1025bb1edd1ee31522ed568e7b5b4ca3991afdc76a68cbc2c4f81863e27fdaf6a564fab2c6354e5c657de81390f8a4132669fd24a48580c716b5b7961a9c091f614d11cf45dfdaec8946a54a11d8 007899928922fbfdb5407517725edf231d15a8b62d90b7fb6d8c8d20424850dc44f797ed 96967e5cbbfecc4dbe9d0f4205c40ba0fc4e07850e7275e169df4549b26adc6d9bacd8742fb369d5042919597cba572109b0c39f488e1e19abee832a49dab1b4cc16092c497f9ea10ddfc16c6bd79fbd815e14bfde802a9a5f28b21c36215ced +91aa08567d8da4c90684dc06068f69deae240212842ff1786f04ec41b40d9187aa92c76401f9fcedced62876a34df82ad7c1e63b68bb2a972257ea8542bda6a7f1a020c9b122943b6d651abda8b8d322a8fb762eee376daa2d3637a71ed6c4f5cf96f61c0da2d6e1dda3370d80e51da2cbd8aef3267168c67359523faf910dfb 02a2af63d1171930758bd3e5bfdac62cca1a83a3b55a49b3f80cf0d9ee4b2082757beac0 a21e22e03a8b12eec850dfd6109e51a2f0c85cc65c9b0892fa08b923df09e1dfb1b23685bd0fc4f5be030b01101e7b7b05d6e787c2853b5396d544691e7ab1e4c388c3d770b400c0881ec68e63d17985ed4095a59aada596d28768a6d13a2e11 +eb5297bf408c1a55e400a20a3c10acbc5c2bc6d6ccfcc0941fb7a6fd4d2834415a6df86c3a6c4b867d1215aeb8222153da8cbbb1576c92c07ca2c36d8f243fd911f9a057e39ee25832454e28d7ed52a8d04169b9b9677a16b32d5d211b8573a8986e9bf36d7206417ad2771daa11bc21fd7ee1029b65ff7c9b2705a6dc9cf9cb 035994e89e13916ad82608f74a639e6aceb756ff913aec440519946d6434af9a60a6af49 984eed45a9df63aa8b797bd822d8e8b8c76ecb831e514fe7a9d9dc655203519ecb06cfae3dccd9a3964a0b62f432e9ee044b69c8769653b8f5d6a882e8702264ab814bdff7442466c22aee105a0fd4a6ecaa2233716f06ff4a11e8ce6e6267e9 +f415d0adcd533dd8318b94560f86732c262ad2c6dff9dc83e2435543f429a2158cd2fbab0d96c027f71008c4895ecc644c2ceaefa80937f6cc6338d15d36e459a16bd9387a361a6d800acfd834ad5aecf442e30b70f5bfa164747cf9f89325b80976052a83a5e896c00c54f81472b14329cf23bec10a8e693005de2a506ba83d 029639da33f48e4fb0d9efdf50bba550e739f0d2476385cba09d926e789191b6fb0a73ff b0fcac4f40054d9aac80eb953d745a01fbfe995e08342d20575c898cb5ecf57197b28a2a59a4f64fbd9fc995e76e93720eefc33fc3e1560fd8dec8953d507b3b44616fb5274914e0a16ff14ce57a0a98c2e1eb4210ad3704834f9e1c9642be52 +b178d86c9335b85e02178fc4551769db589ab91d823fac219c7e14e2f029753b203962389476723832f8d9631dd7764e6dd35da290afa42a794476f5c7727b3688aced848dabc9954201578cc7b25801710931f45cba1199d3788d64dc0188412e70723fb25b8ecb6718358150c4037b5b81466dac1686cb5270bb1c72d34bb1 00583a7ecbf2a975a32d07428d27ac82e5dc13d1466c4fdfc1e6a05a8d9a289f1010617d 90ba19e1d2f60165dd12fe6a18c209fca49376f6a787f6b0d77c528ee21650bc3b3550781be5e29458488eeae4de2bec0d590da7c445506af89aa387beb2a94ba62dff25091e3082de2b584baccf6269664b7e56196eca3e71a0b8ec586eb275 +c8bfe9fa7c848531aa2762d48c153cd091100858aa0d79f994fd0e31b495ec662209a9c8761cd1d40c3d8c4262cf4dc83c4a2549a5cd477726ab6268b4b94a78b1c4a7e700812872d7f41912a723dd9abc305420ea1e1fb1fee41bf643f3a24abd6e8fbf6fde2475e290527724a6f99fd75374bf7cb01b34d3e60d8db33c4de1 00f817ab1b49131fb9bbe8c112c25a36f064efa85de7506fb9cd29d81b326bf276277f7f 8363a0dc64c4fe3e51427a7d128442f018d73e17eb5a5e3e28980359a038c0c834131f1188ef43bf949acf47ba85376b15f00446cea406039bc079fbac2c79d633eea07c75f89e9ea77a31216f91d229090402914368013276beaa56967ed367 +9a5f563d0f9fd1f31f3a822de628ae970954f4e71292492d727109036491c29e66b9b0f2c90c26abe94c08502f5e923a9ddaf6a7d91e9541ce90d0a49f03ce4e4769753d5b7d922e1ceaac4b4cfa4262732a09550aa076b8ff9d46a50fa17de17e3b6bd606698464d116fcd5f1ae11bf45b0c48d3b738427cb47b0d1272b03cc 02782af76ffebf3e2bfc0576b70e4f4bb87c762e2bb230d278ce776310a14f5b678f29af a141323c53a4cfe2ef28d64f2fe2908e03be1f8caa8958c027a627680881ed7f82655597aa4b22a14f6afd6100d78d4108c94f278caa36ffd96e9b86dcd5d215cab0095b077ce242a1638048ce9fc9fc98ec9d05e244b360f132b5b0eefd9f63 +3d6b065721da9de82cb33ec2c27107eb399b1e69ac8fa51145ed4147e20d72e27434104e76af988a3bc94f55e36677a05182fe2376dbe38195fc6a30673a4dca87336c7304f3f31d49216fbdfea00fd1e105d8b0c13ab11f8892e0045e915c17dfaab07b24ed21b06af5a8cad4f45fbee5a25bb6e87466a7bc422c0bb896440b 031b827b88f14d3822244809096157df3c0aa99da90c00cd9f0b18dfe306f6881834e6b6 9865a9d136751bc1e5d36331e26ecaedbe29055241087220726cf60fbab4e091edfd841647242b8b6b069c78f1ac59301345f919faeae88d6e324b9871bc7b51d93bde460aafffe47269c0dba0c0b9a44e98b9aaddf107d363e0b38c3d1aebba +d125f0e2e6135567adec9e77da2afc6862e28d618416632ced829d14ee8b61116da59dfb44098a40a0b927731125617e3d2f32cfbd1546a6e758c1ab6597e75db07add52ecb61d37da2e9ed04df95b36ac249f4cbd794cb561655cbbe4b34834c497b3d392d78ed0db8db683aff0076fb6e43acba3fa2b91210cc6cf3fa594b0 027da4916f1c471cff80bfa14d12aa10270fc3b26caed010c0111f6e5a40d914a3927763 ac2396070c31500869c1ee9237d7b4ec710078479d243eb740caa173830c0f97c2608276330c6fb4ac776c4e62d6bb7209bd73b92aaef1dcb07a2a672bafe99bdc067e23ff64465d75258e7dc2bb2e0ecefd04f4ead8bd623f032f9513010f7f +b380f97687ba24d617a42df1b14e5506edc4b62dfec35ed9fd886bb769832cec7f9adae10c21b7cd9152588797b4efc6b2b30a873d3f25e683ea9be070dd69731949a51121e534fabfa3a2eae0ee90a454182248bedf2595cd47ad08614177d58f7a773f5023b538f5f568682c83fb60e3fb1aa859948d01bf7b214e7f2dc719 010608eb51dc0ee97d6e488a23c582ecf0ea1df9a24db77094d87b3fb6ca98507280a934 827906da7ea349fff07bc416e1ea6ab7895f132ba52bdc61b845cb84483c215cc9d5576dc894e3629f91cfc14b23b39a04545ac856c98d07410c2b2a82a0a4e36564fc5bbef993132fd314f73a69ab395e7657a267f8b103f9536c72201e7384 +3f9ec57e4228e1a6ec49df02c58d756515305e48763ba1dc67298be9a1548576c28c82b4e9b3f62357d9b3c522b16d5c496a39effbdc8290edd2cadc0019e6b9fae1e61238b13b6265ad2ff413a5a0684babdb0013e7632051455e6fd943815213c555dba96cba8911e006bfddec6c3353065004538f37e48df9e339498d85c6 0123f9eb8babed548df08cc3afc1d3b3bbed52b538d4654f2088fe76062fbea75b85a560 a4fcad48fb3dceec76d3ec7ea7f8f5a52ab9070d95c54ae7ae5aed43a294fcd075f9245f52eb0b85d775daf5d3b66e4d0f94ab1eb4e4bba665ea1a81f1f4bfbf2013281d6e002e29c1daa8f630d87bff59a26407c0f97697b3f911bc637bbe3d +bdbd7b7bf3337bd9d21a3c6db379f95408c17e49dd394e94737ceae889f45dc0ff5d48cadc53703a16b5589939506b548f8dfd34c577c084f372166cbea320c8fd07c809b211e0749ea639e68f890affa1569b66bd763c7c710989e491011371eb1d93ed9479ff0216b7f79c901a2023e2cf80b565d1c0517e73117190cd2f02 006a18e626452111922e02e31d662f4301319946a204ae8a34f06b91dd1b5b96456365e3 b6eed5b22accd9adeeb6b1139ade0713a6771c73e946c548b773cb3f59368e8ec1eb5413665332c0ee67571a5c1b926b094a79a3bf2310d0fe78fe784b84319ba1bfcebc7cdc444192918cfa26c7cdc793c01916017619531e7f8b97a805bce3 +436b288512ea57bc24f84fdd117da9dc1858bae8c11637f99295d88fa9d05e3c053a2584a6fe200ad190b3077d9a1608f660349dda405066c1562f6897ef69b6b674d6bc11fa470d0b96a7cf8f6e098c9ac03b0ef415aa045867ac7c11d16cee78ecf08850ccabf70f761682b561d0d0e4a889d840dc74932648ca2fb58259f7 03307fd717015b12a2dc76ada21442ac1d97519f66898b214c2ea317ab0f0905e819e4e9 aa55532c30f421f3c546a3db5432096f7132f0dbf89954649128a834071bda53627c93e57486e089315cd033d85d56861789e551e20c6d6875a3f093f587ec2c54ab501c77bcae88b5edb86bcb39ad28462e8bb385c834e5a7fa8878ac6c7382 +672faa156dc188bf16bf8933d65e091c633f294486049ce96a4a403dca28a149f4f840e8bef47412285363e9e89006614b013a41baad9885f1d9980cc897ffbd5f8a7d0e63feaeb42c07776efb307ed680ba1cebf470dd9bd8a2a9efc2b1daa569524394f9a50398add1a5bd2f7c263f9e63c2d49461acf98444fd23341ce78d 014f9f412e3c7d770626e800d43cfcbba3ae6aec8563af748e8a97b67d244334b6e6d2b3 8bc8e07ec2ce5bca653fa1fbfd9bfb4e1f9d5525791da9616ba1a83ad562c067ccec0f0d54cc06e31b7aac1cdbc37ede0c7b4365e20e8c9556b3ab3bfd8f34ed1a9e9aee80acdcf9ea0525ebc6857fab75fddb307c2a16fcef65b2b6fb503d44 +4321334cc8ee44f1cb392a4b280a95561809dd3639ddf43b6e11cb73067597988d95b8643d86c76c3c6b932d9262b9b8b55a04fba0666dd8b8ff1e8fdf799ae3945b6e30d3af3966f1a6d634d5e012710d66cb447fc3375130968a2e1e647780aada2609d87247c90338dd71c3bcc3902311caba27d5d4ea4d73ccea960d4bfa 03091a6a8bdac1e43542dce752694972e734dca31c061c7d1000754296d0748055db3f09 aff83a048097c4bbe0bbb082a92885784e4707aa23cfbac105a9fd2371c16ebff956c7cb7c4c40d9d5cf72167430425018d84c915fde071832e4f65d642a96f6dd860d4121d748f9bbc6cb698d9192aa3639f8d3ac1f86ac6ba3f0b1351aafb7 +2087e22094570d39fa937f15a3ef0601709a66666344186a33b487d041793fbb9709a95af250b1df0762ea98e911aeb3ff1fa19f0aca53fd4179e454e0e91636e55cc5b17cad9e1575c82ad265dc34c4a66b7a31ecb9ef9dc756f2ac1d9dab35369a6bad4a0f47e629daab91addc6d297d1e5d81477b3966d8c3b607ed194d88 01195921b91353db9bcd00510efffe009c94f6bd8d790f5fb3e5a0101c9ca5d21c6ef2eb 96e1e1959a8a1e609b49a56ca9ea016c30d009e26c0cf4b3d9eab96f40b8c3c2cdeee657fd4e7e502f7eaa35e4640ffb1443b0edb94b822c8a3569a8a3105462f19df4d453a2d3142417ff5e9a2e7cbb4bfd41599cfc2988df6a2f57eddfc958 +15c7bca449a73b03bbfa783f5a91ca0b7916889a5d99d541e2e8593c3b176a5b634ba20b34407fbd94ae1c1398f5313cab7402f3bcd7ad277a8c66d09a6df5dd086b20a0a3823fbbb80980cd86bd13e527eee15656cc977103e80113539e26695addd9eef6a1f56986168d9a53f8b5de833f8962c3826cca106ae9e8c00208d2 029dc20446e9abacb43823e12a83737b46e6e577466b5a3925e0f9d496824dadb4d4b50c 95520cce52f997afce221b3133e3873b84b0ac22d6df9d00549168d52563cccf9999890d11ebd2751f14f131c5fe7f100f3aab69f6c3649fb715a5b0c472f3be34eede23183f6b4dea596e1015358373c48296c51719b4e81c83868d3c8e1c7c +d12fbb82ee7a57eaf76b63fd6bc6c0a65c85f135f019d43ff7bc295cad15d53729d904fed63d69d3ffe8b82c0ebaf0399e2717ece40e011f710b5db46aa457c23b85545953398b814816a1e7a8ab5b0b14c4a0451b0bda9d0d2ec4a374bcaae208b7fe8056bfa17d6b7ffd4ba2e9179f49b9cd781b0c06f6ce3eec26cd428cb6 03b9b77d19a42e9a555da8ab70aa5638890b2ed21daefa28ca6323fc658662dabcbfaf52 96da42b8b25a4db8acadd39a34d3fb1fe1e4bfb30bea7c1ee910bc4c864e6fd28407b99931354c7703df6d90e95b3d4e080a95566322f7ea55caf52ef53d2c980e81a1ce08fdf7f1afaf3c076f53b13a0cbabd44e6b2f9cc0af64e1ac0985b16 +eab0a37915c6b43b0d1e3ef92e6317b3afc8b8301b22f6059da8271fc5fe0e419ca6097daba213915855631af64e10d8382d70599d903d1535e25cbf74da3a12ba2f13c33a8562e0db03edce791f1d39af8850fd1feff0eb25f9ad0a86dfab627b96e65831bffc5f6d9693d20493bc9dd6eb3e9325dea50b055768e8aa30d49c 00b9f8f3e89e9c1ef835390612bfe26d714e878c1c864f0a50190e5d2281081c5083923b 9403d56f3dc180e4c1a0c51890bb0d2e9c5d2dca1ea2227c113930a589552ce0402a87739578034bfbe66d9f4930c945167828883d5f1049c84bcbf262427427d380fcd13db4960ddcf3d88087d0954f698d0d9be804dd9b3bb0c1a65dce208c +fdb93afd5dd1e3eaf72c7ea9a6cddb07fc2054499ffe152cb2870163eee71ace5bd420b898cb4fa80ea53fbbaece2a1eef6427b632320e9c97e38acb16b62fdbf6585b54fabf0a703307ca50f86387bed1815a05b0c8991e0743d10cdf49c8facfd7ddeb8d4a7b706b5a29e1d00ac88b0ee88b3153185495ac8388cc70104154 03a30a1c15b9ed71e102341f97c223a9b5ea3e6a335861c3cf407ef691a18cc639dbe74c b141a01d5ee6306e266601629de03eb923b1da5f966bb68e2a70386f59d6ba9d74e045ad920b6a92c7133977bcfe5f360a9ed048ce9f2a070db7c180d61ff5905dba675b8770048a05179de68104446d5fdbb3256ae64b7aa6eb501e79f26f12 +c78e35d1a5b1bbb0ec21e7ba7b7c74c859d88f3e100e40ae34128cf093885dae4e87cd09f3239dd8e79e25305220880dd352a650225d9bd193b9b84e488c458b0b5fde1af941c0c9fdf952d2fa41f665918dccae27ab7923da4710f8c27ac8ed424992568dd6f0a6c3ecead21650ed162e0292104eef3c2d8551be866a88d279 0083330123cc64c11888c1fd388629d0b329a50ef31a476b909a182c930ff02d0c389b93 86c17f62d76f956ff4597a24c55779908ac5bc8fb1036679b6c509186c7519bb66771f882dc8362c2a6804b7cfc198850fcc54773e3a751f23d437482cf629e5749647ec1f043aed77bfd40aa3247b9d2a874fbaf53f61c7843003de75394452 +e05435f695997229cce314e50065f3c5f71981988dddccaae6efb81f936b22cb48813f506d1edf5ebd69b0be34f278592c5935f0f6db0cca1ef9d62834fbf3c4c03f4da0596cb4d67b7b767e85dde7b7c6fbef7d89babe6f97b876b33594a9e36ab87079861ee556fb03274ad4af527342a4794192b8933f28c6220f954c77de 01dc2b656c207eabc9e0d6272099babca8d149c9c4258b779c2f06de75f76d77505271c0 b7799201057cafabfcf955a8c4b22a404cc7fb84f3e4e22107fe15785f60d536df97903ee11767b439351a78ed40b89a0a88f653350d65afd415d2af0a26ef404493f53ecb73efad82319f31df5bda7a1dc15dbba6ad7284bd471286ebf35833 +0f9f36477076c4b5a7d1ceb314a397fb14646695b0803e36e98908c8a978770269f165a1fed8f4b655d4efd6ad283d7f5d51b6e1e302d360e8ebf4e887c7523a757ffd55384e114bbfc6b7a0ec8511079507b919065ca018573418f9e394854c5704227772161707b4d0246ebceb91192f0eb2ea994ce61fd98a6d14cc8246c5 00081772348ff2d7a3fd57fe703555ab2e14f5d203c4cf0292f944e827e884d95f3b1d83 b564a5f27324d570491c8e27730e7a80d50ec67f6383c1a343987df0eac81f50912d68c971bc02b4169e69c2c8fc975c1939096e8817adfa87a00a3a5f8bae216977fd845c3f0993c24146d9e26242a751355406df44cd82321c450e553c15a9 +1d38b1c342b6611dbaf412a66c1c0b8397692755f576df33b31c2bd12b7f0707cc423376391f7b00aa4e7b7fe54532e2b39c3c5284b9c8ccce48eaf9308ed338992f1d4ecde6cbe352e46339d7d602942158387881d9b493fd40cc59d4f9b53ee4191d42352c6f7bf32c331f0c5afbd44a92901a4b713c7cf6ccddf7de4cc6e4 01eb6bf2ca1b5ffe6f6a795733eaeed12de6e87c53571e702635b9dbd0d96b47df4a005b ab2ec93cc3c95e9bbf3066ffc03fc66032cf3e93e0ba51416c3cbb66572b7594cb80fd851d873aaaa54b8d83a4ee1f5c064a8d2cc10b04d6e905601e70cb7008363d9fcb672d0dfd8e68de825e75efcbb4f3f2fc75339c4fd6ec5c9875a4b312 +3353ad05ef90e9762bcfedd6ef44a1e8ea0392ebef30cffd48ae620f3e567e1cd44882d514e7c6759200d4bcab18afd3038c3d3f8c50f7bba32a04eee5a4b1cfb8c349939e4efe0a46fd047d02ed000d8fa1b98b0af5586f120d9ad174b3aea33905b979ece1eb3660b1e070c8821b32df41904ad68bbd8ed247aabd94066f16 03b2a3e65e5a306bf8e3955b60e856dfa9bf68c1275a678ca056207a0ec67c96eb3f8309 8471301e4e7899133529bb8bceae130253e4c7cfc3c0138a01cbd4d0e58da9a9414acf63d2b38a03a97066d6b603b41202529d18b6732d41e2dea72945879119b47bded2192fea073aba99f4fbb0e814733a593d4b3a0102a762d9657bbba8c0 +e7ec162185fe9a5803c6b03d98041422315ccdac67e48fbd07a1ef3c5661158710abc6791bd0a75d56791b4ac0e7695d53c5989d9fa6a3b037583b2a80d2b154b024f1c36b63548be9afe1d51f2f68b2ba94d4ca1e69a35ac10e15ba72242aac20f7526b12ff9d3cde9a9bfd70d55adf9bd92c66d092d7d08e9764c84bf7f329 01fd4d1af0bb7c79ed5fea7bb45574e46534387bd916649485ef15207352d7302e81dc01 82032474e22a94b656604557782ba91025ce177b79af5286650f2af762e01439506b0857a135ac4a16216b37b9e76c5a12d32722c3f80034777a8840c7e77ebdedf2edb061454ad687165b5cb942328c6571ce53d4b6ebfd12daf84f95b17c77 +87c8f2e3f4fdebce0ca9300fc1ebcaa934f51a12b6b8f2cb6bb6eb77965468663044afeb2a1334cb5a81e74b8427267f8b34b5e9ff0cf157a9f18be2b1942e32ca61dc23ea13c3f9fcfa16df8fe05e067938b6994982676463fb12842d4ec532cb904cf222aa805dd0d86ab9a33a83e294c6d81e8dfa273835e62e9041dc8ff6 020380b1136b5283e9b7f54b7535ebda33b129ceb177bf5d3d07b1daed5edd9fb3862530 854e80ac6d68d398bcacee590a74ed71c38bf1e2f39492a7632d1a98f90158418bfe965904b1fdf5738b900ebf08e5ee0a9aa1f9367e1f8b1b6edb7abc062a843abaf1b495ba01e98aea9b3df6854a5ebb510204797a2c88d11b28a46ba7cf76 +2ac53e8a50c4afe3b38904255b7cbf150c5f79dc15932dc0ac9aa631521f68a0d4b6bc5a04d55c99a36531fd4886a23a8d99f262ecd2a9feea925d7a96ebe9b6979a207b7f9378afbe404fc8e959b0333572a2c911f8743c0ba64eebc7ef12fe5435d2cb0e5091ae518b6e4233489efe3c16c6f21abf4e2c6808b733914e5a7d 019f815b98836948e0a0dc9c30828c31b13e175f1e79f23d084ae1bbe64823f4866214b5 ab1ba7f64d739a5d79e1ae5c2b46e969a957fd9cb0b259ea1712a4d63e12946588234d823e27f9c893fe191ad902ccb803b12ada5d59bd619a7967fba6c9a3802e2e563346b2081eb8f3be31679f0694f69ff3a706fc7bce579092aa8369d123 +0b201469cac4c078f587edecdcdb6efd5752cb4a3f43ab540463c4d908c27527aa3592f2f9acad85dd94a3c056bd28618317ebdf2e7dd6c5ad26fa3c31dd8e5c50c60418d91c93bcbb59ec1adb1db791f485ded78a5cdcddd23dd1cfa4f13443468d8a5f2d648059b9c4470d0f4fe7733d56a28a2c24456b6923703ef32cf0b8 001854e954654e726cf4bebc0e5a840e8809fd716059211c6ffeaed36829808363164684 97ad66d062d0228e079b74894d1f163340b33db88fce59d9e0599a2007b5a403de6d864d9333219f70caa7b7329a95bd109cc88725ad5231f1df98ab8b6e5807b7fdf7cb72b4d6eef058916138ccfa9b98d3752bd436284cc9f3283ed1008b73 +fc5e4dddf4c4a328b685035ee79069770fbebcc56c14e31afb4bbcdd5220e025f31eba794fd6c05e64f19678dab33ce4f084bc32790392f14bf35669d75b6466b4214ec30d58ca90ae285c9058f5804a1fc9d7a995958f2a0e84ee52e8a78b601bec04ab607ffc2091749cc548c6754ed14e2e5f92315bdacaa7a12823ef76bf 03548f8020819588b3202f4c1ac62eaec6a47c2a19b2900c5a3cf5b4ba5804231141c647 8087cb1917aecf35c69e9e09a69f72367bdf9e9f05b9c6e7f9f2bfd2064f06a79b8192444a3d775e3b2905dda217168802951824b9a86c4686de5d0ccfad620edecf6d93c5fc142ac2dc761b26e2bcd3fcb1268dfe0266d0d20e3963c5c94a9b +284cad790e6207e451a6a469cee3befc3ec43e047cf91b9dff1485718aa29de36a43f7c51eacd8589f0c3a96ec18e8ccfa92941b50b2132e3612d5b45e16f60d411d1c53e373e1ba451352e28970ada9dcb9802102518a385dc571dcf6900971b00346098a58042e0d1d129bd6801fa640a895a458a45b31318fe63ebb30c6e3 03cc4505005c41142308f1489226b7b542e2e7f24f1d3089ff6b92a4b0013f490ad52e60 a2f5f41bc2d58b3c22cea41980bc4ee044a07e1bb03ecf5641b6f58527081f36b63888b0f49ac0772f96144ecb90c8fb10af10a83c1f28f33c83fd36c520121a81a0e330a3b4bc2164d7e8e069278fc1917f661d19a45c1ae55c8e393990381a +6d46e57abea9d115deda48b69fe8e0b36144df2f6a659509ce1b514c8cc4769d46e5f71df2a084f1db4a22fdd3ef0c2f90394f2898ce291b9f279c0664aa01419f5f6bee1fc1299871b27ecd57a5ac548f99d01871b8c238a6b46044c953b2e78e22346a0c7663af4db62799038ffb5c21ee512e26d01e70a4ed967377ab8405 0144a2fc8e0aa63506e14e4307df36416f963dd9da78655832f5b991af8c3eb97df78efc a13be2315b40303888b7a1b65522e6f8a07fc6d4cb65a93545fd1c6f8f761b35a805c7babad109a3482b751ecab6920007ffeb7d582d160a800490d5bfe86e79cc24750dd01fce17d931bd78f39756cbffca82e6b46f802d8638a0d3e2122eb2 +dd750b39bd8753f4e473c4484e2b36ce2da7576813ebe05861c339ffae1d029bc793173ed394091c00685ad82f0550cb21ed1c68f0c27cb7396922239cfb886647af204e88a9101b7453a8ab662e270b87a8a13f2fe61d695597382cabeb781933bebfd7d0dcd33f77266e43e32d937f2dc89f67525e522977ce73e9ad36c8e1 024ffeaf139043ff25a395e4c560c7680c1c2155191378917eb25194136b4a69597dc277 a51d5f9446aea95a7a3b180c8c9514258191f3157d5aed2f648e801d46f778faca859355b42bd7b7faed0d05271c8688007f18513cec01e04d5484e67c60e534198044b64eae33ddf99c6493c6e73548f2e5b6ef8d32524ca572578dd7412717 +4736e59fe5812f63737eed57a570182c065538abd9fb0a1c9c2059199e7052ba57d84b5fa1cda2ad9f216610361ce1dfb9334816b6bea509283756a03aaae2e5b0597f492d078b6b015a40c9785dcc5d2ae266176980db04f5cffef40e16661a50ef871c5f531d73fd5d114fa19bae9dd2da4267a131fc31849da38c2b78d1af 01d1f2e0f044a416e1087d645f60c53cb67be2efe7944b29ac832142f13d39b08ac52931 8633f35110e8e859dce8b51e38e7160832791b6673dd17fa4a833fc38625829815e226cbe51a9dae4d38a75c3f436b7c0d513d2a29288c6c0dc57bc655123ea1f9195c8f035b855a0e76c6b15e2dba3d1e4201e4776165932e7d7481b3657300 +e573fa7d4bf5a5601e320130de91f4ad87eb7ca6b8998488afcef69c215b0cccd221b8b66eb0af9d699af9ad6c4b4a580e82941f31e4c0a9bd83995dd076c5ac9bebb34481061e7cb1b26f6e8c6b26ee4bdf9887f7ae2eb9fad3115a21dcc96acce85d23a040c0ebbe0a56e75714dbfa803d6e279b2f4280bcb993f96ba321e1 01337362609df74d25f7adee382225e6a04dd6ee4c6b45fa31499ce9edb0ec046325caf9 8ce48b3cbba40be45c74f7e82041dc7f6a9b689d347f6412d6ced5de1c3ede20ea571055f0633f38accb0fb8bbb5e74902235bd121bf00d4a6b187d0fce21b1a83c195dac5810d05d1737c60e986c5445224f6761c7d84db6517981e32ce45db +7862864d0d78b44e2a28af44a0a16d8e9b1b8c4b794db0410c0a863ba011018ef43e1e11f2fcda2f56fdb2a69cc817df425c9cb3b458922ba00d710190cae16d61af3c304a42fbb3d0c4a74a297253fccd70aca414865b41f68b01c561be281265fa89f63f975d3101334886e85929a5a47fa8dc459b663548faf8ed7484958d 01be00aa0afdfe92e24a2536594d4b41701ad4dfb223aab35ff49310bdba7566057fe8ac 813d31bef90f26cc04be32bb3939639f3b912591abb68430bbce28681639bdefb5285cea838f85ac01d01cf1e6bdda480b63b8b10d4cbcf5f1f66ce4d86a2c53dc0a9675d7c88c8bcdca06b558c8ba16f465cc8e943df4fe633c5a48876f10ce +e73c96d1a84cf7cc96065b3c6a45db9531cd86a397e434072a38d5eeb9a90f62bf5d20bae22b926cfe967647d2bbb5dd1f59d6d58183f2cf8d06f4ac002ead026409ca6a1f868b406c84ff8887d737f65f9664f94801b2cd1f11aec336c0dbd4ec236d1cc4fc257489dc9709dfa64eae3653ac66ab32344936c03eeb06d5852d 012ad0aa248db4fbc649f503e93f86104cb705d88c58e01d3ae0099590a69aa006aa7efb 94043a73d3f53b643a9bc43bf5e5893aa8c2eb7869a4957a19c371c879edd54591cf28be23d7284cf8d65ab1503ae0940a73806d2a3e15d23c621f1f174527f4556c72ad0da0e5f422e875ba6d38ac3dbc1f3fd79797eb42764179d60c9a9a4e +a73fb0aaec838d011110d49c5e94395ce07408917bacf7689d2cfe0948c582214b263c6b80e0a55f1e159086817605723740569eeaa1bae96b979679165c5c35ef2142525e943e595e6b4b160acd7ebe41de19775346363f779b1f80b6d5f0785b92a648028e456af8496102d19dc6526247a654bdae3368f075fa9ee92b2f4a 02cfbb8f340cae8e2e2322829148981cd9e509b0c65497fd8d9da5dee9dcfd39b0f7556c 9190502b9e39f39dc1246b8388dfa19c03b9a65dc05b3ae21017f56dee6e2ec73eab8ec40e4ae711e0adfe387a528d2e13942fdebf25f97c9694d50a43b931b047c5778b81e08aee86a31232f4cb5ac56d8cc2c59bfdb0c5e8604696084e154e +eda775984c7c9f7db47af30dab314d070fb77e9b623baa6b73e2cbda800f167b20fdc2e7219391efacf908f4ceed9b9b6bd3541b52ea087177e18c97391214758cf6455311fad336ab56cfdce57a18add8cf85b0a0bd6fa7297dbaa34bfc8585b0f06a0aae055186658c227e19cddb65de88d260f09f805c2e8854dcc524189d 0070e82a1f3fa6158d15b7346dd56150faee5c98c9d07c996e01a06dc9b211b12ff62d60 add740a58178b174802a86ea1453ba7ebdfb86fc7f6a77c7b3eb4733450209ecdbc5a92410924f2d6ffcbc46421becb80f545bd3e3a562229203494428f0074036b3d887b1ce256ae87cacd0d9e0d02423cff03c5ea65e2be3bf3391171a47bf +a4a13e0bfa761b9bf37fade6570d41c161e20558874911ff3bee38e5649849b159beccf321c6bc7243f99c01a2fadbab9e157e9952ca65d8ea676c74fdc976d00501c626b8465c6cf0e4fd1a7d1260aea987161b821528b0b423e62ecc5193a0a49442b0c3e4ec9c4786a3a86b199c07dd3a17033d430d2c83c100f54e0a7c31 00b471bbc5f7a07996e370da4a09e71e2119ab3a562a273f079401951fbe4df39a4493da a065935cac8f3793e752cfec22d819b2ea12309268baab2bf38160263811189febd6ff659ee6020a1843ae1eb08713ea10c59f9504f7491c1dec113bdad764695b74e8d02ddc34d295cf921667f251b88433cba21161116e31684f06ca4377fc +7ceda7a7248640f7055309ae712c19d741375d6a7e0608e07f0135bb830dc3e8863ee9e7a75331a5e1bd38c42cdd484d4f45a26c2c1d4e05ce0d0ca941f4e94ecc6b371102f31633629e9861de558bcb6407d66eb91f1062ac0e0409db68b9f2855296a7f42fc92359a7dae16c73fd2dddea52bd866a4d501aedd8fe3b3ea733 03c65cf80bfb507dff52f9bf2f93df0642020d41619b3990009409e7210fd7130ac44ffe b22fe6049c2385ab85a066db3b4736e8107bfcccd6abee371b9f4489763d89819cec28e08a7c34e32b9b56ea24a77e99153c67620ba501c924fa751b110500571bca4458ae5eb15456ee30b7d346f4e0451fb727c3fbf64156772227aa08e3ae +609815edfd58c0e26a4b06dded831d2f33466a130754b96d8d7c3b4d99fd4b0789ec719bc25338d0ae8c5880560c02687d352d77c291e406eae865c3b26d00f2e63dc644ce7e01d6e96ceeac8bc1eeb257d36cbb25d89b5fff6e30b6051506a0ae54cfaf6214f30985d54cab78f708029c1fc0175bc58e888db89dea8d300abc 00f4d33a9c7e6744ab3c441828bf0f1866ae1c042cc54abc754e3801263a96cbb3955dfc b5dd18711ae6f8dea416bf6858a0c7e164758c703e275b1d34f344404b0cf11f630b65584e4fd3e2e4c026c61a87c773042181bcbfb0186822f280e196863dff34e80a02acd526cd0c7faa0dd50aa31e4265e659a2f7fead98198ce3f83e055e +82d8ebba707b72655497320200ce719520c1ae7f46f38122958fd99322c25c9f4d4344bcb77a6658df0eece5df163412ecdca58475d56b0c2d14a0361e4cef458df146925d473a43692b15e9bbec550f1bde3444f2a5b2ecb55d2abd273ae999f16a32333529d94455e485ca4585e6b07bedbfc2bd1eb766abf0d28bdb1ae6ec 03a4824bdcea6a144d85f1b194431724cc49849b6cb949b4766d641ae95477d1ec3d1464 a23480069b6f355a710e3d3baa1f31529bf62a19b2d19f2ef02a7995a49879ab6828ed0ccefc97e83a14c3174e73375013ed5a95dfacb86bb7a3d54846dd084aa572f4400ab0f2edcbeac7667d17cfad222007995fe53befcb7e12b53d0fb1d5 +9c6fce18a6a96349b10c9f2f5f1505c8ab727a650b44bc0782a5f39fcb48b45fc7c1b82180d5f229b8abfc807071f931d333d265fc940c93fae7520d8d40ef59d7c6e3678c6a2ecde52b6a8827b1ffc6ed269cb9832feb20e593a7e3d4708309342875199eb2ffceba7ecd707b122516c815e83e27872eda812e3ea52ee3c4a8 027ba543ea785df1d53d4ae4c1bd0a3a994cddf0c25d2b4e8ff17ea7aa00619e858da1a5 a96902a2568f65ad98cd55cc2eec7519b7d632b9b7301af947e429c9b381f3e720920376c72f7fc81c79f481decfa0710f28a63c1228d3eb10a3c35db6d4267b568cabfe440d775f520360e012512a234bfd4bf4b328abe88abf46d7a4add900 +5eac15a64c7653d125605869012b8f036804817aedacbb5a5248a595ee0c12329f91e8179c187192d3ed0d4ca2e202d8d4d9c93ad3f3ed931121c193af5b47a8a5dc39775b6c2d702708e5134f77a31bd62eaf87e39e6fd3f2b9f782c3057e162dd53b3addf92bf0ab99835c7f6649abd1c5322a1ebb2ba313df9464a74c14d3 00708d0907d14dcd5f40e2903e1e90e48a0ffaa6d4d9b84ca14df4e985c294f74eb9f2d2 8b0b17cc0509decab2c4924ca023d79ffbdbdac0773887efe3286d1ef12ce2dca1661cf94cf2dcf62e3e00451b8c51310cac264eb6a4685de94bf5314c75269a19bd8a9cded0e01db723c2f6b11a24c4e251577b5059f4323b86a4a9a85c758e +df735a7e60bc267b18f313ad56bff830be5ef119baf43ce27c6368ff1dd89f010afd4f48740b11c12101c5903bfa71d6cb3d6462cf875bbd55a570ffedf3564088dfe8c8d3148231b78b5adaa6c53696737d4704daa59eab8d986fc6e519e81540f201e77b923a6a4af65d7173635b3b19b2023022186a7b8e869e1ed51717ab 021fb0a6b94080da8b8299b87457dc09d21bc430ba5f3359d92aacc1151be9941739567e 85e6b308cb8dd0a738c9ddde9ea2a0e3dff5cb0fe376c2264eae92093df19b8ce0292d3e23e167a82cc2f26dc3bc246e151d1f62dc20fde3389c791acf9f4b1bef1e1611e722227de62c8d6f2a686b407d53a14977624b0d7172954184838aff +bb107b0eeaf175a786a61db923bc6d51dad5e922e85e57536118e032167b197b1a1f62d9bbcde04922fde781665c1094181c16ac914cf6fbbfb27bb8346b2134f05c55a8c6b9b481273758e380666d6e22c28577c29446cecc5c3df9ed9f1be060ca55ab2b7fda36a147aeb46df0275bb923e0876b703452fab42f6b7ad2ceb0 02c80151f91301fb6b0c7685bd172f20515b46bf94dbc4160d0720fbaedd40ec00084447 95a632bc515a9ebf47f52b58e673d8ab9750d99d8237f5a2e98ccf7b84695e86cef685405c7d4bec41e822e7612cdfbc04a2df093ec5d5dd6396ad964237bad080c2ba785b958748cf562e5a3746c0c66add499ba9669769ec53532c78afdf2a +f47e49ae30b09b7666600b7a95e81b0afa1553da5e01fd917e4ce1b58dfaddb8dc8c03c0f5591f533610deb6a7bb5faf5dd1ec4103a587a1a4c58a110a706b0f301a5c408b3d984c210d5b4a0b347d2b5447271f25b527b3c7864f7cdfa735dfded47c63b723fa0f0413c57a24ffde9a95c35f743f892ab1ed1df704cde82d9c 01538abd7ce8a6028d01604b1b87db3aaf720e04220edf4d1d28c2d731aa25f509e58f2f b21b04f251456d409be820e7fc1ddb83c78f39e3e510378b705df5ca034c4624962609dfda3ffde8d7e2ac297ae7c95e103cf581086c212bb4541a6586b3c009276874913b9e4b1852fa6a5a25474cf3d843d609d7434d376cca18549a00a6f7 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B409 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B409 new file mode 100644 index 000000000000..ad6184bbd0d6 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B409 @@ -0,0 +1,60 @@ +f2380acb0d869d1cf2e25a6bd46ebe49d1c9270624c5507be4299fe773749596d07d10f7c2be1c0b27e86f27b4a6f8dff68cfe5c0b4c58dad1b4ebec7bd00ab195fdd635d9fa8a15acf81816868d737b8922379648ed70022b98c388ede5355e4d50e6bc9ec57737d8843fabda78054e92777c4b90466a5af35dd79e5d7a81ce 00beb0df3b0e05a4b5cf67abef2b1827f5f3ada4a0e6c3f23d698f15a3176cb40e85bf741c9fbc78c9e207fa7302657527fd92fb a14d3a984e577886ff4784ae678a7fa6bbf2a35e266562b515bcb16af67931a814335759c9cb868a748c33b01ad3cd190030d7a674798fc04258e3629de50bff6750824df7fc8ff93fcc505fdcdace8f7d4578e7f44859e9c681c885aa0ea258 +22a97fc0a9694dabc6f274ab52eb592dbbe8beeb646ebe6cef60eff341a13017eef980aba6d24ab3afd976e2f6a84cf652654d4a54a36b2f2f62fab8858f8b0479a48fe9f47f8fd5a4a1f3141a91cbca186507b2bbfef5e4c4d2df525f04ef7c4720fb443ccad540f03a2be468d88c9545d1dad579fd7cbcd103bbebc9e9f961 00504865a30984a9b273d1bc289d734d10e0aa56e93ab14720f1a42a27d8cc932cb8804b963175de6fe57d8eafa8ab7ea0592dfa 83b621f62a489b9819937f2a385d951ffbc1c7302866c1271a0501a683f1902b02d658f3287b1375bd9713ccbf208ddc016c4d0d64d3aca3fd8af2847e42ac73fe5ae9fde499f3bafdfa1855d59edb232926950b09428202d28e4909fce05174 +af36c04af0e3fd64bf52dedf52fb788d2d1bd67fe05d98880cc7ad3c20436abf02f637fcec209fbf888903fdec8682717299f8a4386768153b7faeb6581db57fb9aaf4615b4ea8d924198fdd158363a1f40312527d6bd14c13d19985b668c6b88a7548104b1ff057d07082eea421f50062a315bc3866378f2d2d634f03fbc0cf 00cc08a4ea5ebe32027885a8c212870e7c45b6c610117994d6a42a284c05199414a3a0e8e6645ac5c2ebf21c505a601f69c62b85 8d02d70bd6e212f53c669fb4f237840fa909b91f78fbdad83bfb7980e2364f42ddedd4a82ee223b5fcafe99b2b03285014b61183e6fbcd972ee4edeced78f24f9471e2af9eee78f5a0c3a18a29b3b33e6944f006a8d2590fc6d10ba357b5264b +6bd6f52a6204b60f37929aeff28c87ef61ddeecc231e52a7772275f9329add899c130956f8c50ac2698aad3654fdb49b74a6427a62a11eca0a8ee8b719b8c0df7b9f0bb0af5fef4918a8c83367d29fddd04b6a1ecad904471e5b59c8fe3cdb06b4f8f96419518dda960845d83c49a49f1b1f2fd1d2682a9d60c25fe3ce982cf7 007156ef0a74ee1119532a2a7e8c02be1559c3c21897af9d5b34553c3d0feca4a8d5929d1945df824478e0c0b92a6fac8c84f639 863e2cd1c9b5f6be4399d0dc32f4776a59e7ea438c6cdb3714dbbb075662827347317dee8bbcc045167e67d19b9297831626783a55ce8ae8fa2875a7f0826bab57ad61873db06603b202f4e7d21b6359a92224e562b459f6c2e7490a8a6f2a24 +0eb8de25f63abc9cba16823270e9b6f3fdedf0fb90f6652a34688970932e3ae98f6d3bf0fefc5f247f72960a6975bff1f1acc2188a1775fe8974b2bb2b4c8d226ceb735113a14009e8ce66d58808fada4e6f697fd016829913352c0f659b6be354a067df00cf74919580750aa6064f21264d89dcb28b3b2d4d699115c36d1310 00a95c7abffa92e2c637611ccba66ff9d2ab121b40a85c5b71454cb0dca1f098ce1be8d9ea4933d1a91bcd270c5a33687835d6e4 b70fd2a643da1b719816e17d2988ba7de01208d4dcf5480dfe93f7431bf9e0075ac6506af2fb4c22ed9a2325fd64e8890c422a17c832ca51032206967d4e051be9a0ca47471131e64539c55bbf7c0f91e67cfc17ed22e1320f8ea6ce6e9fc98d +cad58ca7a3b9967dc0ab62a43037764f8074ef9177d60bd98f623d693333971c24a575ed03cb61f4dc2e3d6285fb1204502a540f3c0bbbf23f5bbbd1544f322ce35d949d8b1d8edeb82e90927ac67ad49c91007056bf5096bd690d15ac00e1874fe33293d8003a4a2b094078cf09af799dde384143350c54a99e1f99cc31f2d1 002c438b07c6e0685d1f94a4bbafc013f8f21265d893f54e54c3ac2071606ad1ffacace0b8367aad724b1d9508c65ce52282e397 89c60026c57894a44c0bb0b63926d5b5e51effe1a1874c2031515bd459fb05322c302204b6a18cdf9e5558758e11da810a068792f5f6a37fc431834eed1a518081d86d7310d124e666397a3b08dfbcbc3477bfb6ea99ba9cb2caca203153f79a +281ce2643799bbfacc7d5993683a4fa656040517854f3c2dc7c4f8848dc305382e34e894d433caf12d8b493020a6a08d1fa05b08bf6c53127ad5f33bbe75b9db0615e3dd94408d028dcf3cb7598f6e7cb4c787681dabac7cba2cc06fccb7506fece6c7c1c1bf622d525ae9737085ab4ac578905950002024f30159cf0d99f50c 009e8658f8f9e6cd98c0f4f0fd20d64d725653aeba339504def17f3ad12a63dc6157d80804e5f43f4ff48fc5573fde2c615ed31b 87dd167239a065d60d6c759433836e5ec495cbaebacb8d56a75ee026251ef5ebc758e397135cc4c19f2af4b6aa85300c13b92176edc1c5337b43fcbbbf529df2594441198684580583610fe36c95e0ae2c37e463a6c5976376956b803ac565c2 +0c061da1a16f2be130ae3b20b89745e840bee09633fb49671db28ec9a051545f57ee07e2410ae7ebc61c9af79868d3047705bfc64ac0c04ef0b286e579b650c7165443631e49e6a53c84cefa5625b1e1035a6ed89b8e839540040151132a937666524265e099272c1849f806db0fdf2be64960d5b5853965099459968e5beb32 00c4c13f65eacce85a51881caa6f82d9e48ec2ac574947d2751823a7f072d38bd9da0cdf30b6f19084a6d291052e7bbc2e1349e1 8fe3074702bed86ba8f7fac27665c8f410e5f161f6563ea2b85687010ec508293360122efd4649902d42db017c42132f16639c1eb3c3a0b4b3726dcb2208f421bb4c41b83e5d7cbd0e94438bb7a285e4e9e6bb7cb9981cf516295923f7203b8b +74ac2e1303297efc3ed8e624722df505df55b7f33964cc0d270604cc48b58205d8a11952232a8feb0079baa30d7d33660268b56a5a3dd90105f0703abef8f6636a99bc63bd47d9df100351bee32d8205dab0dbd2af36fd173409ff8d1fb7b24570f3c1e968458f58aea5aa2f46731ee91ffd6d3a060af6b3d5020daf1362af3e 00da591461791ae7847e6d8dd8df46a63d3021644abe9520e158406c96540d8fd82ecfb1c3f6f5cfd7688c7656cc3e3dc94e586e b7e52339d09993ffa08922a59a9bb79356585289dbe8090d27eab73318840456c206ae3cc81347535da9afde167ae4470af7f76396305a5ce406980f27db910996ea1afa0e36773a2c5bbac148b92953cc941231905f62a5ad342aed2bb7ffd1 +2afd17344552ccc577b0118caeb7dd56a0766e25f84df17c0505f9798931374b48df89a48c64e199108c36e00c0bf00a97ccde55787bb97c6765601765ab5417f3e75e35a9fe5e0f85a721d9f08440ed617afcdc200b318940a1e496040a6ad9090476b0fb4fcceee77b3fea11de09e7fb14853d1fff8ab12d66c101257e2d4f 00b5eb943f0dd390b737510e2bb703a67f2dd89dc9f6dca6790bc7a260cb2d0fb8e1a81ad6009ed51010e7686d5b48233c6c1686 982632964d2fd36f67afb8efb7a707ee72052d69caa18ce997fe986fa9e2cf94826b354515698640a1ae7b346749117600741e812d2c464cbc963ae925d88161a537f733372e8329dfa03747f725acb68700a3b9660e11fd11ced633fdd5dd50 +174b2b083541f8284645a810801e72631a11bd7bb805f684a7159e055afc44357f2c80df2b7853678d34a04144e0ede2327d03db6df23769ec41194a8d9d86af74d51c5bc11ea878c6a80689af71d3fdaf1c651003385332a512e03dd040c33d9c328ca89ec7ee9026bbacf30a7f3a68e0d894fb9f7100ffbc64bf17679dedd1 009cc63f32152284fca27ab2837bf1343144336a1fdf15b9727c47e877ac69ac9cf4c97b4bf42f1ab10d73de8597a554ed099efa 842e5747925cb7608a0d592e4dd06729153f193168d85ab39894ae327c76fcbd520bfd7d19578997476f9594a0cc4044018f6f1597029df35ed810bc2ca0a3faeb42ff3d1bc57224f2192d1333e4ab2fb24c006bdfcce1c12ce68a4b64d55383 +758df71a952cdcffdc417b9fffdfb57582ab5c5473a8bdf0c2101953b023b77824263353dea0e2ede1f800a5757ec6ac0e1e4e3ab5a4cd85567d2d19acc6b7069a6e7368401cba2b6e642373654bec0ddd19fbf032794c15b7ef7e714e13e36875262c01e77766ed53cbcf735936dc9b33eaf2152a396349c82ca0297dbae4a5 009950355e8667bea8bbe3a2c4988436ab5394551b375e27fdc0c1a1d1b07ae957932f428f1aca0a486e54cd0b5bb0a5c5650641 918ac63501b2db6ff475e1ad436f1dd15e121654c01c3817b2b79272c601c04bc9b86a649645e7444cf0933e2d1dd0060c5f2bc3e89852fec4e3d6e8de058ec7585cbfecda69e38b64b8b54a9e32449d3d49b692ecfc277da177a344d95fbdd5 +b96d9f66b2000e9408d602096f032b112f0e05ea874229ab9daf6e05bee49b4722e4f2d8bf2eeaab9dad94438c76b7cc64dcbb59cb4e03f9ac70487a1d24d8d6b72d7462fe738a17edf381d52179b3acc0c0177c113eb4d10e8e78041deac1d56abda0ddf892edb8be956d285e7236bc6794168f8a180f622dd5f2b9e690c275 00a995493d6971c2d7e8fac3da9f8c0b5afd877cfb94924cfecc167f9d87002136ab253e3a4f9ddf5c9c99bb1dc1af0c6a3a3c4c a1ad77944ca312894ef6d708dc46299e1ac3a4a1f626e0641a33fda7961b846e05e94eeee40dc8086b366a3c2be361d70380418269b40c5b249e0a923b06fd221299abdd40bd4432f47a081363bb0bf8fcb57802dc229e2d1371eb0d454960d0 +e7ae60ac55e6ba62a75d5328bbc15269d4638764169de0bf0df043d15f9152bed909b1fb8c7a8d8e88ac4f552c1092b62db00958a3a827f64896f6de4bbd8fa5258d6c36e3904d82d3eacf6eedba50b0242eb6b01212288448c3a9821c4fa493869c01149ff1850e8115cf9de1618cb8744626b1951d1de305745507c8b21045 0070daf435cdc26ad66c3186267ad12d10f28d32d863f950cbfcf042fe9dfce553750ad098f82f7f1650c1126b3e4451bee6e11f 8cc298a7a4d1348adb38d15c641b37cf5320571695fed4498c21da17a5e86ead35c22fd91d471dc6b8fae967e98f44ab08a4b1ca780eedd99e6e60766c326377e18cc9e03506354f3984603ccb6083f8e7f228c3bcccbd80d6e00eca5e1d21cf +666b0dc2ddffaa7ffd57ea3b2768f02d4b77c16fa007c6d1918400d195f068cae2dcaa69817e6e4c70d5b29c5598efe2d957bd12d0fafdcf5ac52dee80a2d46e77fc18cce2a49bfd787ff77b942c753974d22434742bdb494590d17c42af725b1309e54566276af3bcfbf5e174d3cf191b85903faafa1583282c97e66c5da6c4 00f8121980dfbe9ad0bf92383c7cab95fb72d5caba96e1de7772c6a179e85414802fbb86d725401451329287305570ec7fdd873a a76f568e4a46606e9b1845bf376ffe383090751a98751cdbae00989bd5e798bc9aca44683593814b47930ac31101de4811b91f2a3613894357569fbd668967401ab1a6c98dc1d5a83021340436fd60eefc4b6c889499f6479e9c6efa31a1b13e +3e967cbc2bd936e0b6125dc5cf885735bdcd2d95b2f764de6931c4578ac8e0e87abdf96375481df67dbe1b6c43537e84ec62bfca6672cc5f3ea4125abd4a4119edffe04e42411d338e8b10abb1f1f818c50a9631a3f89feb5be5367bdcb0a8a82c96a427ba6ce99f9631d4411a2b7f5b14d32cb3901dc9d285e4cf5508940942 0047682b2e3bcb5800a531858e8137692a9b1ee98ea74e929ce4c919c26ae3b3f1d4122d07fd9a70d8315fab727ccb67004187a3 8982f9f78491b924d7519867f681809835930764fafbc4d2dcb9b58766fcadaf6c9f37b1f5dad262230cf799021abaa312734b2c2e4c8af291caf771a5e35dfaa898b3c92417c11f0b7c28c3379e225b8f51cf6a0391119b8f8772f9fbcdf49d +ca1c90012eba4e7c5f01d8cb3814c58f48c03a16be6ed86934014365eee547070b870d1d26a872cfd28b60d9ee0a66dea223e9eaa90ee28076188d6091f26f665684f4b486af70669555db9058d485c677b2a34d4a98aa8d6f43bf6f44aff2a23c5d765e98f0438ab81be0585a5be29daece5d4116f44ce6062753a3ddc505f3 0040cd1a06233ac27f3ddd108de7c6c0982793ee620d71982697713be9fd5143658929924cc88747a680779bb00da8a44e1e7d3f 8251f677c8ab7938eeb1b2c4d85bb4e44798e4a80a4d00e6cbf7d47535a3fd617193103cad490f535373010b0d53e71a04177fccf515165ba852b1d768645dcada3903902e40e846a6a5a4c10ce1607891da967adcc92ff13b0e8348d28fc5b8 +a54c4351ebdb075d6a42a787647390f864b2bbfd8bb3d0e0ea9d767200fa344d1a9ff091bddb186acd69bcaecd767068efe4d752d185bfe63f6674279d0e7192d2077c400bbc0d5599ee28507c1253f05eae0687b965a015e1f3a292b4650106765266f5c95b77ad2d82a6a6e012f233169eb6b8d83576901cfd4a927c54d7f4 001ca6f752aae4eb7fc9c73a08d6fbd96bfde5030d759a2507bd45b6e1d1487e53abbe98fad4f41976364e0a1d830910ccf97abc a49610fce2fac71acbd84d63774c100b829efaf320d6278f3f59d4e9321c99a5b0300e9ef2ea29e0d007f0334199d42018e52c58cd7e0ea987103db1fda24fb68f5abff9a1a0acdf1ff12bf62e370e2df3ed725cc07d3579a513769346c635d5 +6723dbddc8720feeb75e2a061b7fc49079f999fbc79ec8a8e01ab8d35b438b7049da5a23c49a58101742791f84f45d5f5cf551cd7de6926a0e2c4ffa1e378f038da597368c62df8cd8349bf046de46d02183dc05b3a3575f5f232dd2970057200e2c9cb60eaa6b4d72f8b73d4d40b98d1cc801d1a69cb5ed780a75a4064623b2 00fb9b1a9597d216028902abf743d25944258b48c9762d4589fe660396130b75f6006cacfde60f6204463cb8c18b032de1dd68d2 972a342a8e3d4b12171b1e53dbef25aeaed79e81372094b78eb8dc7769c5059250d238b6831fc7bede49e6a3ed04d3080c9af6617d4c156570f1e283dbcdead8f187e6a3fda77643bc38a5e18fe61e82236af4e96ccf03f480dc7b352b6367d0 +ed53cec5e5500d62d38c829002916c657674ede4439c6f405ba672327ec677490e656bdd698f114c2ab5e6a1fc94a1a8d64466cfe9eaabd23a8b5c37f76a3c0decdef73b3e7b751cbf3b0817f4079560b5ea34cead88ba374201236bffc48eaf289bbaa4e828afa7d732473c228ad00588c9b443d65b998f21c3d7a9e9196c08 0032109202d754da290c266f74f47805a06e6b5c3f721a72fc97a3bffeb8887e0c642d49a6bd034847d0a5ba09239c5dfdf0772d 94fc428bc6c9664cadcaff0cca6ffdc41851619126f1c3f46254e234fc0bd5b0170508d040078cc8d27cee5e78c801d203f1223b1a28f65176034675389dcb9eac3be6b785557fea377689f4a24d3f663c1e8aa15bddd07365a151b35a3ce4ed +13829401bd41e9fe01329e9f5a002f90f1a6ecbf25fc63e7c1345f265ff02e496230f706c6ab377ea52d8707b54f8fc5c7f089044e2bec1dfc66a07da76ee12fb9ea0697d87706b0ebf677600bd2fe117f6cdefb8bd636a1b6b97549ee78f992c24acdf3a946053f06fd012a9c703efb8bd929a66aa74b05d61bff0395232b00 0080536e820fac59b3203aea928475043b2576446619001647e35693a9e65d15236c3cbc12e1bbe0eb305973535c882b70197a92 9380d14481a4e142090ab1148084c72aa08f256ccb565f22a6695a328b4578bd918c82f9ffc77e49a8acf4965fa430291739692ecb476f8e8c93074e5b1486b3cd57eb5c5c01c4eec8930a6d302f15b6b4fef0f325fc0e3711159aabab080e54 +e696acdfcc96a6c088069b7595ea9516a36d8fe04dedeb789fbd965db0cc64b7017a821015f6210b6989e515def5a9605fec0d337e4ac59f3101a505168bf72ab6d98ec62a71d2f94071fc05b95e98d4efc59fedc138e3e49c5d0b44d1f48f7b1e7c1944ee189b242950d2bc804d31c7eeb45283c84638f043ab9533976433a4 00b05e5f0dad9583ea18fb8fc4d8c75fd2e3cf9e92cdd9b737485c953620d345006c31c288b380258b6500b84f729ce6730e5303 a92f8c23384b629706a7d1563969243c55c363fdd992eaa41c42f8ac04fc03290a13c7f78e36425871691f57ba3cd606071b8102915122102805e4bb5a87a4e4bba7b0539666ee6cc65811f79039a38ce729de233dfd16a9a99c5663bd3ac095 +4058b9a8cc15ac148909eb97fa32aafbb6077b168dde91a411dbc973df7db056dc57ff78f0abcb70f70f800bd752197d681f44df4a7817c0e7f60f8f65489ecb6167c14b525e91fd2cc5d8b80ba380a83d031d5827c8b1262c687c90ef0e62723d9b565557f9f6fed0db48f3799274c2cd60a14303406c35802cba6261121296 00be1d277813e79051ca1611c783d66003ef759b9e104f32298017fb97667b94dcee1ce807dc6b4d62416e65d4120523bf6a4edc a8f7436294995d08e0b2991d7c0fa5ada32652cb96a80f8a50fb4b4f135e2d0d7b058c95efd0ef3ebb229395b1e12d690e6d6e2fcbde6df055bea2637ef107fb63727fa73a1aef46056a57de715db23fe2856d67e1bcdaaf817fc2680ea4518b +e793237d46e265ab84ba9929b196405faa3b0e4686e8693567e53f68e6991e57677974677682a2510c4c35b1968a90b32c4941af7813775c061c008a60f9f671cf7419c94253d6106b61e65034497f2d273a5058379bd986e3d917f708f0a2bebdba150f6d78a3af9c722a2430ab0f4bad602e91e18aaf258e3785fee78e4502 0073c807bd7e07379782ab790720de4ae5106f16d34e80ed70da5b1594e660c9b775db94066b93e74f855f57d88b6ecc6228aace 901c239524e90d5329cb4c7f63ea28c5cdda77db60da6f0551144e668461a4e9d03d0e4b512f26f8403486e755bc997c07f53156fb1a438b4ac20da4fc65d351e6dc66f81f6bfc592d04e18c232658600f7c8ec645b2bd812fc4d2c05942a4ce +ffb8bc80e7619a562d8506eba7658bef0c25ace3dc1d01bdc2ef00933d4fa07b80364e5e5826074edd46a707dbc3b0ab19eec7ea8990839d7fc0a80b70661204c52bcbef57c1a7bdc861c10766033a82dafbead283d911a9502d5f9ef0a39d35ef26f3616212d4bafcd413ffd18b424fe09b48ba02ca5d97ec996205cd49d22e 00a68379b2296a6c944ad5dacb593b302d8ef0b05873ce12bbc371d705f308c739d21f343349524aa72f05341e64f7435daef112 b933a56c402910d4c23debd566a26f2af4e6898e9d418061ef4bda5e1489fbe9246dee148da4e2906e009beb18068db8011f133fca6b8b8f3bb9967057ef076b26d107daa624f4a5ad87967594a3aae670aa95d63dd451d51436ecffc4a2fb24 +946bde90a5b903dd281a51d7fa93d80f3fed07eaf50c18fe9fac5acf67326bb18effa3144e25c151efc006a50a274ec6c6a5d573051c4e2d117ceb0fa125acad07a10fb6534a8e5f5b3da2a1136779c51377bf76c3a4a93c0c6158f729f2293e414fcb952c9509f228c804f0adc1daa327a8991d48ccf4f3957c5f8ccbe3ad4a 0026046bbb269ddb1ec14ade56175482343a21b7c265026cef3c7d6a1ae0f6a68166b9e6c49a6e733ad2ad64df7137ef230038fb 94497562cc9365c4b21df16ae4dfef1e30b41547bd160f09756f5904308a9f67af9405cf4467e5fb586947443d8aca65100c00492d691b8926bc67bcb32348461cb55ca642187baa2db6cf72581710c8c03e59d8a4ee3e6a47e582bea6774525 +07f3fe1369ebfcbcacd66675bd4ab22edbbff72e68709cb57d4f590e49440f01691f490c58b5117bd24aa2fe2101b59c61c417c918ea08ea34bbb9b8aa17491ae5d9329affe894f42d7586017877fae3ce35bb80c97f92a004380374ec91e151995166e14ac00505fd1fa810cf02981bacbcebf5f81b2e633d3a3db6737890f4 00bbcda66978ea526f7bd867c3303b625f11b94dd9ee6e2c2f8688ff07f2bba83c662949d47ad47fa882cb7d203a7f0ef5dbc52a 92ac0898c9042e37517e168886059e8ab0563433375dfa0f574126187fa5da9ff5817d60dafc7bd9f6ed276306301f8212dbcb9f13c32fedc1257b18f4fe1ffcc25685c9f914e129584c9482151f133c9431e44084fb1f60dec31eabd4291ee0 +3a1cb13438e3bac9ad4ab1d319e90e2c9f118dcf1eb54d6333c674a665d41451f93cd4a9334cd057a44c010edb668254517a63700a31eb0ca474c84873e486f2f8e158a1a7735362ea0cff8ef17d959ffd851b21a91412709b3c729474d2cb40f6ca0e397030eb2611b402916e4b656f0fd868247d80be3ce33d52054b7661f0 009be3dd3442e0330750f0a6252bf9cb317f32f942ae516a4038dea2c40ca6484fb33611bef016cc64baf166c122e87c15466fd8 b5a96f80a9dca1fa539e8d55bde75f9e1101e92cd6cb607c9c759631da53f59821d2aed460c6d4f162220cbb521fe52717a7a771e1de6acf9cf58293e7dd1e0d45d218bf8311b3138d105c28c71162f86d561e17446eafa0a2c120630c417637 +e58e7b881a563d54772125b2863718690a5276c93d9e1c5feabbdb5d6f7c7293ff0f89805b53663bb417fdd46874b8e6a466e7e3ff6737930a0662af1d5879b071b0dc4d014778dff26a2eca5992e763bf4c4698c382ac947215aa116515876008a56e5bf547857049c38a2d3737ed3393705fd346897c3beb80caab88e5b8cf 00ed321fa283c662e87eaab99b7715e6cdc9b42e14fa5bbe2c56fdfb381369191a42da7e574839f90a85577485f19446fccaf6cd 9306f1b42c2b2a20a40034a283d45e3867f50abb4138a47d45d5949c188c398ffd882bf4ca2a26e4f766c1bc29c4387f050b2f80306a67be382920980a98723500714e8c7a0cdc0b13407562d878610fe61fb0b64ebb85ebd09685608baf5327 +8889ea1da1cbed98963941f6ac24f47253ff6af52de920765214f2024aeb04f7ad46936830a8eb04d95aba64ed7cda6ef242f454b67bc2de38a46b6524bd5c96739c4b580e89829a61a8249ec8dc27a50f43b8554cfb6f4fa4ca6875983d4b60a1c6b49f32ddff6fac0cafb64d55c6f594b195c207a9bd920dcf20e0080920bf 00396b805073f3c3b552b1024dcf35559ac44f255b688871a3c6657f727a4b09f3806cbb75d26a00ae1728be632387e804775a8c b9d7c04db88e6156e67d05e2ca5eeb673931d24a85691d4a82084aa7003bc887e29ce838d306409094ce0934773f0b3302168db0909b57de036785a0606079a12aead4ff70cd5ddc36d88ec93c47d944588bb36df4786b73c833ccfd6cbd2843 +55053af9370901e38622734a5bc5589f6a20e258627f381fb0c366f3dbe58394e5997e978eb7ebbc530f6e6186f48294149b8594fb551c31c50521a8c4d67e5862921695604afb23977b6a69b21abe75966fdd11bfbdb6b51ab0a474c5fa07c4de7872a3bd81acc417655090558dfcd5af449b3347e61fa9e839bb9457de64c1 00a8fe323f6736bcabe971c7d964e75dece70cb54561da48a11c40027ebddb23e41c7b48600f569500fe8ea2abebdf480171dde4 96055499f34b0036137c088c10858fb5e56eea99972ed719e41392af6a6411d236f56a71512918e1d4f1fc4dafdf620f136d36955c3f7707a2a90be0b2591c8b50bf59a1423b35129795dc2aa66ae8bc3c6a264ac9fc823e6c62708835cb3cfe +c4264330534a6c2bbd8a3b757e0912558302ce302f835ad8c5474993832fd30036fdef40b10ee37293e871db5b0b149654f9e543e22111f9709ef45732125f713c031ccfbc9a2f3aba160c241d27be4dab87ab2fa9a795752ab2daf20f9d06a98d90d01c07133adfe83cb11d5176525e1bba6a9ba70ea48b224d46ddd8103f65 00105938ba9f25034da3e032dee121bdb192ac2128b50a2ed4bca042e96cfaf4660c9d35f3e67bafd4c99f9447e6dc408e0c4471 902d72940038a8a393e7dae514e5a0303892995b31d00a1cdfc4b8ec06580dfe850da6eeec9a5a1ef476fa4e043c7b1c00fe0649d1563835c03ec307c0c1dabb0757af0be0370e04f482f9229cafd4cbd4a4a5505fa99476b38a507ea93e0b56 +3236f1ad164e1b25d828f5202e3513c80c72a577aa9af56f041fd96cf5a3363f4b827723b1511a2f16360e32eac90ac55f4ee1146791420ef9e2af333c17d157b00e43992ef6f2be2d2f211361e468413dd93fb69232f0a0d110bc5fff361c0410344aa0636bf809062c73a7ac7c142063912b6ad7e1626fd2a384f35faffaad 00ce11677ca818537dbaeb880fc967dc8bead203a2538a55e756679c4a9e7975b9b3e6aba4e6c6eab4152d0c0939027e9b0bd92a b6f466509d42872a47b7139aac9f9ba027210aca2c68cb981ea32a69831156f0510dbd917075dbc35d81df2bf5006a920bced8ba44c158cc28bbd4b56a980821cb45276e18dd072dd09f240481cf0751e3176b51940097f0bdaf2365dbc89c4f +6c400ed098d8369dab6fde3553afbbd4d47836d0d12dd16015f15cb8d067a39391c85ca4e78c62b8b72c1592349ff8dc52db8ccb7fd80c085fae456dba6f4a2378e184dd59238c92cf04e40d43a66b342d2a1325a0bab12b1ac857f0564c27b35e6abed02ff5bbbdc3770ddbb2ee0513df48bcba925da6d61583076cd3129603 005a239ae0f40d76d8d3589f1662b5ca12176a4b2784faa8339b54e96a1e1294433a4d83bf904196f939bd8b33bdb4be340ec703 a76867a56482697967f1e6075b0ed43589e0357209c258b017c39d18d47f70d4412b04e94272c0dd68c2d9d3c99d04461436d521375e000a383036098feb6c9b664ebf6725eae847a23e3b032eb0ec7ea94f21297429eed89d46393fcfc0701e +039a149eaef2de30b0ae457b376ce6fbf88afd4cfdec02d3c5e00400d3b0484c1cd6ba74db5de65d6f2fe39871349b30fdf1ef29bcbb9e182eb3ec5629d07d98354a5dfa82d7f0db3dd10d1510c0dce086848a198893ca5ad24a663494f0596b4eee86199ea85e7e8f2f76e7a6bd4a052c54287f61b391f1e52f96b606151c34 00077390c62ac41aca995640fde0c79c76f4ea8a8dbb22323ed812bee837ab8798c5d0ba976c7aa634d4b1c2c155de2709e7352c aa6ace26b22ad640f6f3b938a8f968565ac2a04800a8309523d27f12fe20ffbf6a7ecad0da4ddd8a63dcb03a4ed33b4b0081579e72a4aea95fb3e71a71ecb6d63ff113a9a6a74303c174eb23023a593dd49cb812ecd92c290d52ace8a993ef29 +08617d04fffd6644c40f7dd57919f7dcf3c888f4147535d12ca658302305bb8e220bb17ccdc480254004b9035b357120580882ef86aa5a061b2850100285b7d61588a664dd4f5394f5478e68a80f610c9204d056009c1c9e902161eda33ef61aa902e96b6f094a9f053135692182943d38b9763055a38739a2a2d133c5dbee89 008bf23b09fbbed1b55769907aafb97f4759cec98649b2c9da5157517d4f85bb70157076b5e4aaa7a940af042302f8be06a84ab6 966e55cd0d7b89959585c670d3428504c99e1d62a1295a6e49ea43cd3107dd93460b6eac861cfe1952be1163d178b811009c0d832948c6bb78ef6705913f415abfaef5c1bb10e3161465f9dd8de17e361391b186f10c420c956d0ff39bebb655 +34c959f549a307f21b850ae105f41299b8bc94fc292aefc61aefbe0a1bf57576ba8d9b80caac635e4edeb22530163fa9629665fcd43959f68eee32482f1845a78ed7278e6e43d09ed6fedf465001afc0d61f1d2e1d747623e82a762576b879c7024e34f43104593cdd691d53bccaeb8f212dc29bec6bc94cf69d0a8491db124a 00082ad05d19b8e16f80e53a4cccf6869ab5128c5e622ed146fa8555985ccd2aa3b9957dd374586115d4d75b1c01cf98ecfc3646 a51e192696abacc75b1b794bf10677c349fb07847116d923eb699dba60638c5cedff5a5034f442f38baa56253e792a1b12594c76b69103a90382dbec8b05e7ac6c120211eea91278422e55c71cc277bea20168b7ca968ae25e14a6338ccfd6ef +514f4de08a6f49edbb6797c9dad6d33bfa367cc1a1b58a5becfe646c7f3352d5c5d95f7456e7112c4ddc746b9076b9756ae3916c07bbe6d3823895774a42d25d44b3309d18bfe7e3ccb1f85dacfec1654778c19e2981a853c1f40a7eafd16d331093110698c957fe9f1d86582706a6885543248b944bb70cdf9d2ea89190cb02 00af7e581aa4f9be5815f0c447e39de00da9194eee5e5f609668b9b69930b5b48a948614c2250260d1917f0ebcb00ebda4bb52f8 890721a2ba1f9846048a0b1b2f75cd266fdc172b94cf299670f4c5caf7bfe6210ed4113ab2afce25c1d737ee85d5ab8a0a0fcf5bd82acf75d1470780a36a5f58e10060539a0c95afb017927dd06139eccbae20b86cc06d2ab68f63d8aba0daaf +4e5d16cb1dcaa1abab1e371e1de02f31ef4e0944dfe1fdec45ab64326435b2af9aaf1a6ed8fdf1a6ab1182bb53a844c7cfd66da30aec0d41757f5988ada0017c4ca752597a9fd3637668bc1a92bb1556553f28d66805bb47f1ef91908ce098d452872da9800e77e1fbd43ffb0ed6fe6a62185d4be73ae96c9241b82cefb2da22 006d14107b08354e6a41d7d7d50c004419db8bdc50db43428df5e86084551237223c498bce71a17e25695bc438c5c09e009c60e2 af4f99343193f5119b9d6bfb6fe66d015f53a1ee1e15b7f1044d3426acf102b91e4d9c440416a368de979e1ec7f2d9231525d842437e4f03193aa37bd153199ee836ad3cad73edcadfec48051d8393ca2356a6d562b338af7474b4dfa1e9a65d +e29e75269754ec1194270f5c9e8267dfdd8c696008b5ebc92bb840981fd065672f07f6a0f1b19841adfc51b478371e1a0db9c3346a9f0a4ccbdecb7040191a00ddfd0a8faa0e69fcf544319c0155d02797eeef99fabbc55078f9d852927c23fd931685424249b87ed0c70a4a3e2d3b9a2f92830e7d8f7650c0bffa8f8986b7d5 0099d96d2dc9c79549f031bd5346cf6a8544c312a3fbfc560dc8e378efdfe025b0e6e61e09c04c8bf4133396f993b0906c33dd30 a6013b882bdb13b13d32cc5283e96e95ddfe4f2dafc4b510b0dc5631f84b434be266d39e816e4b064a1f3a8fd5a01f8c0a5a1da6f3a236715abc93109442b4bf58eb15375216275bb27e2b44b09bd1c28dd64d2032441614f4fbba9539da8e44 +1a538eb447c18494ad5a5ad27be67fa60eb2c5cb2404eec1dbd7244cd802b17ca5497e779d5f779b981b165dab53ad19fd7bf2ea7dbb9b4baea782a43d758202f147e59d6b6b8ed54f4ea084bc18519943f6894d603e253ba3e8e339a6933bc3a0a47126087038e1c813c3f2997aae321b7c95a802b4b73fc7db95897b7c91e3 0049f347dfd361a65910e97fcefbf60013a54837f2ae657d65e02397f59dc6bca27704fed3affdc3d833fdc621cc5e5f99b92a63 88a18a617247701ec0e385805a55294e26bc7b8f14b7876cc874fdc905afb049b4452474b942508473d7284cd1fab26c07b27374a1c350e2c0f8d0ee6845a34635b0462388cd696a1fafd148475c26c9acc752b1dbf682f43748d84cd319426a +7502c755bbd385079a4001b8cd653287dc3054f3b57de19d0ff8f63c0308c64c56f035117a8971d43654f89b52e923947e4760ac72be073136da70c5ad7ca1658cc0a2d2a880d3a0c0fe636fdb27b77ff260c4c1ef8a18da8e9fd777d732a37ae9906e6c4f381f0a3d941048d5a1f6f2cb8593873fa4bb1621a44bc2bebfbcd1 00dd226de602af4e9f8e25784bd1bbd4cadb0a8aef525d5e2d57b9f3555feb698765672c5099a7d6dd5faaded69d8d68b4804f26 85f1eaefad84f51801e55c9b698b32117fa2c0a73b2e327470982df5c53e02b531118671625308f68b0a3f8fd51207b5015068adcabad0b66101cc5630da46ff663537b6b2d154ed9ae392f6da998eb09271b54453ab694119436a87606a5402 +95eca932d03f1df2e8bc90a27b9a1846963437cdafc49116ccf52e71e5a434cdb0aad5eccb2b692ca76e94f43a9f11fa2bdf94fe74af5c40e6bfd067a719523eea6b4e65730365ee498ac84c46e1588b9b954f1c218920cbf71b167fc977ee2a89429590f43bf637eecd91b0ce3be2d66bac5847205f76c06b914a970f543e59 00b6fdbc9c8c76cb2b822a940d8675889ca6f5132429da795462381ce29313a23bc132976fbeb346ed4c691e651028f873ce7971 a6e6bd8553113cea8bd1cfbda62fdde0c4bfef3d63d727015763f6553c0b14d90cca462cb2bcf7c7c31d6ead0d3e8f3319a7f678427224088e5b87bd6c43309550061f9cb4492cb2852a57b2de0801033dc078c59e3285be060760e3b8673fc7 +8ff68cb00d03e730dddb05fe0b2344689529096c3da6eeecaf097f22c7fa340593106b1f6726f06b7ce7358edbcf801ead959438a42f94cdb467b3cd5b17fbbcf75739805f9eadc869c33c604cc58f81591b0b8bf4d42bd53a801f0f829a31af6c129fb4f20f1250f959754eff8c629b85a716b6a18465b6495798c0c5166c8c 00203d77fac64591eb9a18de20a9d5eacaa1c3ec58a5ecdb3008c2d642e197141d16b3a9fdffe61429264f5b420f5e9926659a4c 91d613ef67248b8d48b34c8389ab360722ede232d7c0029161e4876e7e0443cc9e0b28be63a197059405494b0417a39a04bec6fe1a72546e97f134f401e69a1dfd1aa231d0595f2b0c20bb709d222ae575d6bbdab28074bc733ac2e3fc71ba1a +01451c4f09720cd53377a5ed04c907a735477378ed960235a833049d6bad6e6e89958b4c4249bf0f6d4f043530c9e5426deb0ec3a12b7feb4860757b41bf602ca95655155356ec35a2db8e2657998f56529be4b714364f83a140846308a2973907ed7b08e935173ebbce5e29afe1444cd51c92824ede960056439555e7e74450 0057a2e6a59d4871c3d547690237dd9846d6d5dc4ec0678aafc9c8669af8a641eed67bfea4b05fd6b3b5357ec4d0caf352691ea4 88a493b006b699c1cde19de3dbd9b80812eb3ab6c3f04f89d076d838387a522251c620a08f2b070096a984bb267fb1b10f69f8742d12279666e1619c71f67bf9ed5bb7fa3ceed552987593bf7b49fabec14e018cf8236809a675453bfb647fa3 +ccd494ca005ad706db03a3df6d5c6e876ef859ec77a54de11fe20d104377df1900b6b192126c598944d19a2364b2ae87ad7fd32265d59e1f22be5833f20767793677b628f18e9619f8ca32f3af3b41c31e87a98d1527e5e781bff33c1a8be3a82ea503e76afec5768d7f7dd1f17dc98a9e7f92fd8c96fca0db518bd143d82e6d 000a3da7a6633608fcee9ce4253bbcec08d41ee6b00178ceb017de74e24d48fd89107c9f2db3556063abe3cb011938f4b4871795 84c26f409dd2b91aeefd8959ede2a9085b5e1826227271cb7f0546eb88ec1369ade975a34569c1be68dec19c733b2125166dd5d3010114f6b39f0e0fa3f166c103e5a797b117ad739a2b935180a86aca0c6566db1450385279eb2beb7eade447 +5719e50d939a8d74efb444eb5a77cda48cbb59e7f976cdb2ea2848bfc558718b39ce27b893c229db94bf77992222d1746f8f52f858f85124a28193ae0da039c53d484681785f3367f6516fbb8a86560aea9e3428551facc98cdb1e9df8e2f37db823a7abc589f667b5c93c4c47061400220a2014197d514217fc252cef5a2433 00384723c8b4a316b450d1fce0b2645912b8acaeb3cad50860cca43bdc0206ed5b3b60ebdc29b3eda305d0d60eeaec261edc24d5 abcad413da41a6a3527314d41bf0637954cc2975ac11e1c321c884f3f64d57f44f9e1daa2e91439eae0ab8e938d880510dce334d59755381063cf1d58dd677ff3e0575d0ed0747f743d2826aff17e5a4a734690e19b0cfb16720ce3de61f4918 +c84e5702a339259a61b5ba8ec1957f23ffc4f1eeef3a58f383d3731bbaabfcf49ce2ebb597960ac5115a2af1c62b193d4ab6c24433d5f168a1752e40145f19aeb6dee889a53a4fadd13eef60e28fcc7ed6a9b8b0ca286c1b3d66a4b2c327a629d15c148049e3a0ccdccf05cf22c31956014595e417060627c8125bd7c00f8850 00bd3136647572fef3de51b12e64b36460bd3a27dc660c164fc705417339cab21f9e1f9be0f3da926df459c5ba58b701d306e67a b1abd7037e7037c4c15fc3c9f68d1beca4db8352df486df0a9c928e6b578203054fecc454781e6507f5dc7ad917d5dc904c27ab3f1e43c6fee62e04c87bff903df9dfd11e4658ee3fe9c055f6165b79a70d8b7b720be3d2e4bf3560721964d92 +c90bf11d04a708e64b6f94d4cca64b92463eae878c377b188c82c1c5f05a038be20eca2e18034d46f00d9a6fc73c4084981748ee9d2915d87aee4e2321f4f9e11c176f01281913e324700d9cb474b7134fcc408fb4a7006acd9e63d4578ed4c2729d8e0d01b1e6174a43a024ad261eb644ae98979c3cdab75af357f6dbdf5db1 00495be0b0a9d357f6155fac008cec90442200bb842d89292fde38b7256e4117284a60249b3101b3f19f778b680c0d1d7422b84a 84d40ec5dd96dc16e846e51bf4f97f02c937a9d1653e9fc4251efd87390e97fa4578e38e94dc6469e60b10817de9f916109ba3cc7d2f164c3ab14d806797842bbd3e0e3677d08f05fef4c1f3a11ca93a10a4f8ae2900d4dbc4c598d7467be4f5 +e9b2a33906a1079280100039787377c2971c378b92e70a38ab41dc23979d6fb0c41e53a21b37632407adac6f212341cf6af8605b4978c85c9c16960e1674247f1795cd73b99ff28cdca024f5078490513c77114c2f52288f5376872c331151d7b2c08f7794f2c1f9e0d849d32d73636f0aa899988ca561a76f74543b37cbf3a3 0079626354dfc4eeeb51fcf232ee9e6b0130c9bd40f15ed45606bb7faeca8f359e0c3e18bf12769254522fd4077eb24bd5454871 832e9c3ef0e70f50c20bc2bcaa62ddd200e87763b8ebdf130eae04520e292e960958d4a09f48a1e99defbebfb7e34631185bffc12bb0d5a7c2425fc8d2ec5e5946f8675a0a173ec2fa5a7063205eaac12dbd6fc4472b3ed311cc6f2c76ca61e1 +672db3fb8cc8e5f831be700498d3ab3aef14b7548e8011b21351215fb6dfa09460d18f52c02c8815baf396d856a429bb9afd602a10c213af34db80447f4c06ab4bd28873c88eb9639b199042d4b2cb13cc364f734fd4ab7bebede7dd4da63decc0cc1f84e34d760013f66d71641073f16c08078880b67230f2d6c6bfe17d206b 00ab42bc7d0e3c23f8bcf928e25f9f027b56f270398a1d37bea0ee5426b944a9c9ba6d0d7796899543feedb470f70b2ab148234f 87c1c8ce0483acf159bf45313376df97d7e973ad9003e896c5d13f51ba5bc75c96ccc54c92a6d1049ebbb36fc7720951068a31580691c50e3d2f174deaaf6272ff33eb5b84ad70ef52f8574a4e6106c770a6427fd1c726e940f98ce2309d02a6 +d7fd06b89226cfd66671ce5b4b656228c52d986afa7f6f30161680eb0c9cca177992a8a8c40167a64165c518c55f678702125709361b536bd928567c97737bd750d0e2e6e0c00296a6ca565f7c05cc8c54ae7a4e0c334c6a968fc18a959c18ebbd924457701316a4e999fb11084520dac68dc2d69187134c40891af0355ba89b 007f7aa2216164ba689459ee5d5ca29e70ef75a5b2a4416ab588df1dcb9164330c0b405a9d80c3acc41c19f58e24e17ecbc0fa7b b32dafe1c33320d8c70d7a6230cf10c9aa9d7e961166757dc6b2fc3e31cb77f453fd0748d7018a1b0a2ed8ade11129f40d5470a9c6608f1c6fd57d57bf809786ca037563acd9009c54c57ba13a36acc09bf9920a57634e1d1650762a98cbad4a +83b7e9d3ec638fef51d2885fff5490c94e2509c126608f82660e5fc523032f3e85d69d9b76af145f6bd916dda35775abbb6d1902bf38880f8b9259822055c5b1bc726c51029972cf7474cf2a812f3251aa71813476bff55598d079f075a40c6c41498bd865ce960c518bef75a873b9d010965f342dc4b35ef5c5972efe6fdd18 0021d84f070c6823a70f1a74225a472118c93ce9dc509aa6064051ca4574939dcfa96be862069424bdf1a23f62f2868326422e64 87e6a603e3279535248350a137505ea0194905bb608b0eda9fc64989c13a6bf2e4b0f09810ae8285460199dd2ed794f80a4b014c1db99a04fff52a87cc40742e28aae0950733caab733685d103616c500f34f36c8a44b6aa73935f8a4d495bce +c62c7bcc860f0e175128e1127dacf935ce62ae794cc4a0ce7966bceb023ac0498641d7281fbc86f9ef470bbc77f608f83f8d0dd6299cf08f2cdacc7a9642e4246df131820220e5c05d0dbfceda7f16b86add4793e9b6244d96b5c07cfa23574ceb43e8e8b5483192a92b301aa3b37702b8f94f0129d8af1617896b34990c9b02 00b6645344d17528968c719091b6e2072388881dc10bdb4c7fbf41906cadf3699b30f9c1dbfb4796d009480664e6276c0359e5db b915622e6c7c5606f6838928ad42869b0cac7f5d370ae8274fcdd2864cd4fbad1420ed3d419f94027d1900ca3998f862130e02e9d86f4af18a0e93b3298f341f886214c89e77386a83164fd9a25dbf67400a4305102f76b1bd59b910e52579ec +b5bf38fd9e822925254418475a1ce762a94e336f12b156b1625a4574fee11ee472d537ef94b4a4b1c0a73b0140d0b818cd06636653e6c07f0f100118242a7703756f1cb1119b3477c4ced99cf45e07e83b7f2749c1a5f8d8c9272d221fe17f7c6a5fb0f8a16af46f232ce406aaf565c6b2766a2f6528c82e74fa1c0a7fcfd49e 00f8c2f770cf5f8e1f900e996ecdcd84fcff5cd959777fd005d721a419123221a3237e39834b270d37752470deaa6cea023c5058 97e112c4bd8139dc1a67e89b4a60bddb09fad4fe0d1ce647c0c9336af752f0ebb5933e435a6f64f7f52322e8f6d51a610e9c29065c450d893c28757d2cf5836b532ca14ee5d7360f8897e0d43c187801b567c1939a9e009ad8b3f2a5e63f35d6 +6d3474770933ec01b76be789304b6fda423b12a0ae8c87a5ea8d7ee9f71300f39440e1c7f5aa4b47c1a8628cfc3a490b15ef292a741344f40a8fcdd02cf3863bf3e32d53031f503703deab17fc52b3d4032f4e237dcc27231b85d3fd60b49ed7ee40c3344948d87c3f47564d20a11d50e4e520bd16c8701694fc70901a5da625 00144adae951fe897d5812ee4a16c0be4c86c5e57e615c398f5768a1223a9be20fa82ceccf8a16a31432bbfd17e594a4cd8a6a07 b41ff7ef9e9af18f89b074338854dc43fe5f59d336ac82ec76b0a035c77bfb6b7af4fa37631308189bdc2e1a2990775d18bef2349b8ff8e341a25a3e2dfd4ef08af90834a3ac0348b19c22e057095f6e68383bc7a5c558a9a0808f572b532674 +92ba7aaf71f625f7a2e024058dc8739da3567c306da4a812ed9e1542b7d1e982c16082166a59720203f4524c3bd463a662c26a82ec7b4376545206e650eed0d3dd7909dfe3810981393070d15c45dc4a75a8c5bdeba533cad1ec34fd20466a61e4cde3b25af9a80a9a54afdd7de1cf2a74ba32d4ea0082a037775413c61a8d1f 00a51f065fb32c55bf4ff6f18ba9d488d35d9f8da593adb0ab1632533284e0adc43ccdbda9d9507b9862ac63b5ae7b0f78b479bb 97002636f2c38fe7083857a0008a82e68e777d331de601bbd6acb96520262566a73a99e50583bf79665d75e25d9f2b88038a0a179fc27b0298e64fac3895ecfa1a34e5789ce6eaa65e26ff6ca371704acdae1cf520d62d13a27252d837ea705a +b3fb9e48c333201324755a81f3ae5d4f0e2ae7cd24238fcc66d858e3aeb1ee03328660d6399676eb1b7d8285ba571e214d935bb45516fccfab57b8eb4c3d5f1d7357c768eb7b5e7b5710f599614bd4e92706eaba31f8a5e7e57af7ed13066af50b4540ccdc126b677789920cef8543907f0ba9dc92aae343d3425bd784ef483d 0095351c0bc07acfabe6477fe85f97eab520dc96bdd58b44b036328ceadaa56a1904d2217c5fd25155ff2aaf9005a3e2687fec81 a3058156e8ca331822572685d1261c991fbdd44d118c9f022bdb167933441b1da7d14fd22f5b41c844de3a907626f7ff08ead95b356dbd1d37c658788ee64184a068fb88411ccfdfa0a5b6f1f46ed0dad5984fff81e849b0a495ddf7b0a4d0e7 +9ec5f7d65082264b8a50be772c44277a73ed19199eb275fe5976f9799d8629fcb4a59a8d55074cd2eb2a0e02062d3f7cdeb05e62931a24fd1aaf14c257944d1b42eebd52726d6fe281211b39038e52baae077ea4df89675d860d6ba5a0f998d049614201b872e134367acc90066ac602e478ac3e43c3ddf4b0ca0aac1a68591a 0050245c1682344fef23bd549ac8d1e8e44b2840c43eec1cecd33daa4e9ef6b53f496104d7432e14248682cfd6f5b4853b65adac acdc4703e32bfbaaf719b95c5ff7ea798de27e70e39abdd6dc5d4f7f9c7f65bd6462ca5adf63d3a588a67bd65a368eb20a6a6622b40418adfa032b38b960ff873953095ff573fb63747ed2eca3a272080614087704078c814180bf67d6534a25 +61d657bf472676301503f6784b7286fb39fb4186bb88abf1edacb4a2693d0a1e2b77bbf2758c84f2cbfd1753e20841b1cd4b456400d53f4d686e666943f9b6ffcdb77f510be97536e9698fc84ae347d483bc8984548d1cf86b9b40d360f9c0dc5bd1c55868e26fce1460ba94ef5e94eb63c9f0776a0f446c0cfd4106d9f36352 008d3b0277f0e9fe54581d3a9499ccd7f015c08339591326859af969d2a26284e3b3beac4a0b74d324ce5cb5f38c7995e4e3a41f b819dacf3ec8ac7cf7932b0c2787c20502c15a4c24ae0942d3062e8709298da4cb6694a4dba55a7ae89d40592a9e1bcb023562a260d67c5aca96998b2e27f2d4ea62ee40dad0acdfd73df107ca31e6783542d581fbf35b792156cc79261f6e43 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B409_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B409_blst new file mode 100644 index 000000000000..5ad1d9fc9cec --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B409_blst @@ -0,0 +1,60 @@ +f2380acb0d869d1cf2e25a6bd46ebe49d1c9270624c5507be4299fe773749596d07d10f7c2be1c0b27e86f27b4a6f8dff68cfe5c0b4c58dad1b4ebec7bd00ab195fdd635d9fa8a15acf81816868d737b8922379648ed70022b98c388ede5355e4d50e6bc9ec57737d8843fabda78054e92777c4b90466a5af35dd79e5d7a81ce 00beb0df3b0e05a4b5cf67abef2b1827f5f3ada4a0e6c3f23d698f15a3176cb40e85bf741c9fbc78c9e207fa7302657527fd92fb a5cc37b2f38f322c5a73e9ddf3395688279a2cb57347aefe8ab37adbeef5e0eda883138e1181218881875e8cfc0c9ca800dc026f81ee3b956831ab31bfd7f696230f0710a24df3be4d787af1faedd4ae33913e2e5e25c84ea9397ab0e360d106 +22a97fc0a9694dabc6f274ab52eb592dbbe8beeb646ebe6cef60eff341a13017eef980aba6d24ab3afd976e2f6a84cf652654d4a54a36b2f2f62fab8858f8b0479a48fe9f47f8fd5a4a1f3141a91cbca186507b2bbfef5e4c4d2df525f04ef7c4720fb443ccad540f03a2be468d88c9545d1dad579fd7cbcd103bbebc9e9f961 00504865a30984a9b273d1bc289d734d10e0aa56e93ab14720f1a42a27d8cc932cb8804b963175de6fe57d8eafa8ab7ea0592dfa 81fe5b4114432342da9b675aab3f661fa434ca3178381acc0e5525321a37067165563809769500f28aaa6c01a6edba531253a66953b78d7f53e27df6808754ad48c62c9c280ae1cabfc0ab0e468a9407ca6f217fcb210913b7493204621f3726 +af36c04af0e3fd64bf52dedf52fb788d2d1bd67fe05d98880cc7ad3c20436abf02f637fcec209fbf888903fdec8682717299f8a4386768153b7faeb6581db57fb9aaf4615b4ea8d924198fdd158363a1f40312527d6bd14c13d19985b668c6b88a7548104b1ff057d07082eea421f50062a315bc3866378f2d2d634f03fbc0cf 00cc08a4ea5ebe32027885a8c212870e7c45b6c610117994d6a42a284c05199414a3a0e8e6645ac5c2ebf21c505a601f69c62b85 b82274fb36a6175391a77752976f33b42933731dab1f46da6d83657210eb9189ee51c40031abb38997a2d8cce0707b950eae0610a9fc935530c4019cba8f74064e64163c6f45877d4b1e72550140c3aa23b871802627d1a7102e36a47f2f5ac8 +6bd6f52a6204b60f37929aeff28c87ef61ddeecc231e52a7772275f9329add899c130956f8c50ac2698aad3654fdb49b74a6427a62a11eca0a8ee8b719b8c0df7b9f0bb0af5fef4918a8c83367d29fddd04b6a1ecad904471e5b59c8fe3cdb06b4f8f96419518dda960845d83c49a49f1b1f2fd1d2682a9d60c25fe3ce982cf7 007156ef0a74ee1119532a2a7e8c02be1559c3c21897af9d5b34553c3d0feca4a8d5929d1945df824478e0c0b92a6fac8c84f639 b1e859db69d18b115835c827f4cad604ca07120df75be26aecae0aceac7b7a485e4684f88cdf6bb207c6ee24d0c2d0d813f9006b0abe6ab220a2372c6ab73fa9b5e6fc510a8a7a96ac99fb0f2628223c7fc440cbbb0b0d7912775d36d4b8b62a +0eb8de25f63abc9cba16823270e9b6f3fdedf0fb90f6652a34688970932e3ae98f6d3bf0fefc5f247f72960a6975bff1f1acc2188a1775fe8974b2bb2b4c8d226ceb735113a14009e8ce66d58808fada4e6f697fd016829913352c0f659b6be354a067df00cf74919580750aa6064f21264d89dcb28b3b2d4d699115c36d1310 00a95c7abffa92e2c637611ccba66ff9d2ab121b40a85c5b71454cb0dca1f098ce1be8d9ea4933d1a91bcd270c5a33687835d6e4 a515548a9c9d68f3791e7bcd90852777761bc3c1ebf7ee5940001f7511f82deef320ed7ae218f692d17a2f15e9bbd959130a9460729b622bdbb72e61f3e9e3b6ed32337e54b598efbb89811a3176e910d2a9af3a3b0cc34e8b38854cd25ae163 +cad58ca7a3b9967dc0ab62a43037764f8074ef9177d60bd98f623d693333971c24a575ed03cb61f4dc2e3d6285fb1204502a540f3c0bbbf23f5bbbd1544f322ce35d949d8b1d8edeb82e90927ac67ad49c91007056bf5096bd690d15ac00e1874fe33293d8003a4a2b094078cf09af799dde384143350c54a99e1f99cc31f2d1 002c438b07c6e0685d1f94a4bbafc013f8f21265d893f54e54c3ac2071606ad1ffacace0b8367aad724b1d9508c65ce52282e397 a0b06db10b1e41f5e98f0e46a09350220661f1846de02fd5f2ecf98cb43dcf830b563aed7eeb3eb4fcf5b0758a01be9b104164098bb7a42f62272d322a71c24e809115f1a4fbf5c62d4eb45973567e7d6133ec652718a0189c5dac9e3ef6bbe9 +281ce2643799bbfacc7d5993683a4fa656040517854f3c2dc7c4f8848dc305382e34e894d433caf12d8b493020a6a08d1fa05b08bf6c53127ad5f33bbe75b9db0615e3dd94408d028dcf3cb7598f6e7cb4c787681dabac7cba2cc06fccb7506fece6c7c1c1bf622d525ae9737085ab4ac578905950002024f30159cf0d99f50c 009e8658f8f9e6cd98c0f4f0fd20d64d725653aeba339504def17f3ad12a63dc6157d80804e5f43f4ff48fc5573fde2c615ed31b a0f6862e818b38f628194669605763153953a1bcc1fc118b1e0002ff3e80909cbb311fe5038d177610b7dca4d48c324e0ccc06ae6bb2ebf138914050d283cc632b7c17f3a6bbbe848733ed5f72057f0abd8293869ae69d816404f6935266dc18 +0c061da1a16f2be130ae3b20b89745e840bee09633fb49671db28ec9a051545f57ee07e2410ae7ebc61c9af79868d3047705bfc64ac0c04ef0b286e579b650c7165443631e49e6a53c84cefa5625b1e1035a6ed89b8e839540040151132a937666524265e099272c1849f806db0fdf2be64960d5b5853965099459968e5beb32 00c4c13f65eacce85a51881caa6f82d9e48ec2ac574947d2751823a7f072d38bd9da0cdf30b6f19084a6d291052e7bbc2e1349e1 a6264b04f2f6305822c30d0e9d138f19905764e7713a305657eb4ee700179711c99569367d04e27f70bb42cd71f7ad0d0c9416b9156979f1fc2ec6549f09b2277e3220920e70446b9eec426ffaaac6ff3314135968430c124f05f20a6f69dd3c +74ac2e1303297efc3ed8e624722df505df55b7f33964cc0d270604cc48b58205d8a11952232a8feb0079baa30d7d33660268b56a5a3dd90105f0703abef8f6636a99bc63bd47d9df100351bee32d8205dab0dbd2af36fd173409ff8d1fb7b24570f3c1e968458f58aea5aa2f46731ee91ffd6d3a060af6b3d5020daf1362af3e 00da591461791ae7847e6d8dd8df46a63d3021644abe9520e158406c96540d8fd82ecfb1c3f6f5cfd7688c7656cc3e3dc94e586e 8228cf3153ae336f90bd1aa32cdcb0228f82d508219f32e230e9dfa84ae07dd4a4c64a6f7efa528baf12734b5db0df0c17951a3b2fd738f3cc377144348d033ecc22ae316a5f808b2c1693819905d9e4894c32bcfe95ae5b892e63fb036f7f42 +2afd17344552ccc577b0118caeb7dd56a0766e25f84df17c0505f9798931374b48df89a48c64e199108c36e00c0bf00a97ccde55787bb97c6765601765ab5417f3e75e35a9fe5e0f85a721d9f08440ed617afcdc200b318940a1e496040a6ad9090476b0fb4fcceee77b3fea11de09e7fb14853d1fff8ab12d66c101257e2d4f 00b5eb943f0dd390b737510e2bb703a67f2dd89dc9f6dca6790bc7a260cb2d0fb8e1a81ad6009ed51010e7686d5b48233c6c1686 989e5d23e3881a7530a932554135183fc54b8d057a790864effecec36601546f659e74acffb748db977c2101f0ba2dde148054b33151d53a91e59b1729438fe0f54bdf7c36913e44e0513af96162ebbb79a7db84a123287a1ba4a0cedc67c433 +174b2b083541f8284645a810801e72631a11bd7bb805f684a7159e055afc44357f2c80df2b7853678d34a04144e0ede2327d03db6df23769ec41194a8d9d86af74d51c5bc11ea878c6a80689af71d3fdaf1c651003385332a512e03dd040c33d9c328ca89ec7ee9026bbacf30a7f3a68e0d894fb9f7100ffbc64bf17679dedd1 009cc63f32152284fca27ab2837bf1343144336a1fdf15b9727c47e877ac69ac9cf4c97b4bf42f1ab10d73de8597a554ed099efa 864062b044f42bd16bdaa99c76a0db4d734e1f5f5ce1fdb2f8171806afdc3b84b3154a46133a485c42adbf930e9e3bc8194a0277da346bb67506c08a3c465168e0726f016dc971366d50bb709f82314f005af5ac06fb30b435ca4ef7f5a04354 +758df71a952cdcffdc417b9fffdfb57582ab5c5473a8bdf0c2101953b023b77824263353dea0e2ede1f800a5757ec6ac0e1e4e3ab5a4cd85567d2d19acc6b7069a6e7368401cba2b6e642373654bec0ddd19fbf032794c15b7ef7e714e13e36875262c01e77766ed53cbcf735936dc9b33eaf2152a396349c82ca0297dbae4a5 009950355e8667bea8bbe3a2c4988436ab5394551b375e27fdc0c1a1d1b07ae957932f428f1aca0a486e54cd0b5bb0a5c5650641 a0df0f6667811748ec869f918a2a679144b746ea13f883334c31787d95b63ccf52494d71493de4ab0fba77f3ae9fb691032b2b28472e7c3948152f3b06c152a2beb1dfcfb219380ff5b0f5270953ce1dd7ab145f3f9572fdb21115c1ae15c0f3 +b96d9f66b2000e9408d602096f032b112f0e05ea874229ab9daf6e05bee49b4722e4f2d8bf2eeaab9dad94438c76b7cc64dcbb59cb4e03f9ac70487a1d24d8d6b72d7462fe738a17edf381d52179b3acc0c0177c113eb4d10e8e78041deac1d56abda0ddf892edb8be956d285e7236bc6794168f8a180f622dd5f2b9e690c275 00a995493d6971c2d7e8fac3da9f8c0b5afd877cfb94924cfecc167f9d87002136ab253e3a4f9ddf5c9c99bb1dc1af0c6a3a3c4c a1fd4b8f7d0cb464dd53f668b90dbe7ba7492cad9871ee4294b7dcb957b9bf70f3897bfea49acd8a7b145634ae7a2cb2122260770e646b987ccdd41eec061b3888e06a762adb751678b7b7defaeda110040dead1978a1aaefd87b15d03579b22 +e7ae60ac55e6ba62a75d5328bbc15269d4638764169de0bf0df043d15f9152bed909b1fb8c7a8d8e88ac4f552c1092b62db00958a3a827f64896f6de4bbd8fa5258d6c36e3904d82d3eacf6eedba50b0242eb6b01212288448c3a9821c4fa493869c01149ff1850e8115cf9de1618cb8744626b1951d1de305745507c8b21045 0070daf435cdc26ad66c3186267ad12d10f28d32d863f950cbfcf042fe9dfce553750ad098f82f7f1650c1126b3e4451bee6e11f 88a84b14ea179fa00e7a1dfa6938c046acbdeda8a89a03a19ce89d44bc98d3af2d590bb30b66bfba6bd0d1a6aea18d6a0d7e8e60b3aff37cfa4726ac9d2ea84426fb59b1d80e5d280097563be6383cf86f56c5234d0a8d307d889e7675fd8012 +666b0dc2ddffaa7ffd57ea3b2768f02d4b77c16fa007c6d1918400d195f068cae2dcaa69817e6e4c70d5b29c5598efe2d957bd12d0fafdcf5ac52dee80a2d46e77fc18cce2a49bfd787ff77b942c753974d22434742bdb494590d17c42af725b1309e54566276af3bcfbf5e174d3cf191b85903faafa1583282c97e66c5da6c4 00f8121980dfbe9ad0bf92383c7cab95fb72d5caba96e1de7772c6a179e85414802fbb86d725401451329287305570ec7fdd873a 8d3378b197134f897cf6b5a1cf5996c604f93b9319489ee42a1df22d69e37dd99233d3a95703d494bfbb0979287895e8196811aa5d8bfe06089c6721ab88b8f5cbf4e7bb7c3b365210b64863641173a3fed225d00a0ea74d9fc108ba3b0ea043 +3e967cbc2bd936e0b6125dc5cf885735bdcd2d95b2f764de6931c4578ac8e0e87abdf96375481df67dbe1b6c43537e84ec62bfca6672cc5f3ea4125abd4a4119edffe04e42411d338e8b10abb1f1f818c50a9631a3f89feb5be5367bdcb0a8a82c96a427ba6ce99f9631d4411a2b7f5b14d32cb3901dc9d285e4cf5508940942 0047682b2e3bcb5800a531858e8137692a9b1ee98ea74e929ce4c919c26ae3b3f1d4122d07fd9a70d8315fab727ccb67004187a3 96d589bfae71e2ffe8179f464eedab81dbcda908c58fd66f5af0f321813891ce1bf4610e496accd0bdaa44122cc7f5980161a1f0ebcc5529ffea1617774f58043937d3ddf8fc36bf73855ecea7b2aa8de07618dd01afc2e1f76842968438f53d +ca1c90012eba4e7c5f01d8cb3814c58f48c03a16be6ed86934014365eee547070b870d1d26a872cfd28b60d9ee0a66dea223e9eaa90ee28076188d6091f26f665684f4b486af70669555db9058d485c677b2a34d4a98aa8d6f43bf6f44aff2a23c5d765e98f0438ab81be0585a5be29daece5d4116f44ce6062753a3ddc505f3 0040cd1a06233ac27f3ddd108de7c6c0982793ee620d71982697713be9fd5143658929924cc88747a680779bb00da8a44e1e7d3f b44b9bdb74d8d4d918bc78a211898d19e465eb26136151c6d2e17edafce9dac3217c5f00904839696cd1b43f6b6363d016242f87cc0121a117466a7d3b7c57fffe411b3b3014b9dbb8c727fd4705f2c4da2b02261d7cfb886044bed7332cc428 +a54c4351ebdb075d6a42a787647390f864b2bbfd8bb3d0e0ea9d767200fa344d1a9ff091bddb186acd69bcaecd767068efe4d752d185bfe63f6674279d0e7192d2077c400bbc0d5599ee28507c1253f05eae0687b965a015e1f3a292b4650106765266f5c95b77ad2d82a6a6e012f233169eb6b8d83576901cfd4a927c54d7f4 001ca6f752aae4eb7fc9c73a08d6fbd96bfde5030d759a2507bd45b6e1d1487e53abbe98fad4f41976364e0a1d830910ccf97abc 910ee83bcda825f932ecec5e88bacb86bf259e7d28963b2a37c4b4cd9ca7a518016117d039480bc348976b8d7a3e32871940e61718d5b33722c79e6e2ea505f1e4ebae28dd88c97e267425cc701dd4873a4a982294f477ac2d72b6b4947bd657 +6723dbddc8720feeb75e2a061b7fc49079f999fbc79ec8a8e01ab8d35b438b7049da5a23c49a58101742791f84f45d5f5cf551cd7de6926a0e2c4ffa1e378f038da597368c62df8cd8349bf046de46d02183dc05b3a3575f5f232dd2970057200e2c9cb60eaa6b4d72f8b73d4d40b98d1cc801d1a69cb5ed780a75a4064623b2 00fb9b1a9597d216028902abf743d25944258b48c9762d4589fe660396130b75f6006cacfde60f6204463cb8c18b032de1dd68d2 8184f9f18a921f5e74753c20e62215b162bf764f74fcc773566a178ab3b23835666cd0e2e83fb7f8e99bc0bb9c25a2c918c25443732ed9312d7b2474e9ec1dbdc56ddf9aa455b47a52c15df107caad7fe0766b2a67b63789f2f729bb4b6b7444 +ed53cec5e5500d62d38c829002916c657674ede4439c6f405ba672327ec677490e656bdd698f114c2ab5e6a1fc94a1a8d64466cfe9eaabd23a8b5c37f76a3c0decdef73b3e7b751cbf3b0817f4079560b5ea34cead88ba374201236bffc48eaf289bbaa4e828afa7d732473c228ad00588c9b443d65b998f21c3d7a9e9196c08 0032109202d754da290c266f74f47805a06e6b5c3f721a72fc97a3bffeb8887e0c642d49a6bd034847d0a5ba09239c5dfdf0772d 88acf144a11ba09def03cce73b86bd68ac5722fcf9dbde532d6bd265d84edc09793aee84cbffe8ae559bdfb155e95a5b0901df8de83fadb5b465518fb97175f54c9bb4132882d6402a9cc2e97a7a242a07002ccfe222f81c3ca05fb57cd5b423 +13829401bd41e9fe01329e9f5a002f90f1a6ecbf25fc63e7c1345f265ff02e496230f706c6ab377ea52d8707b54f8fc5c7f089044e2bec1dfc66a07da76ee12fb9ea0697d87706b0ebf677600bd2fe117f6cdefb8bd636a1b6b97549ee78f992c24acdf3a946053f06fd012a9c703efb8bd929a66aa74b05d61bff0395232b00 0080536e820fac59b3203aea928475043b2576446619001647e35693a9e65d15236c3cbc12e1bbe0eb305973535c882b70197a92 80f7205466f72b5b158d89060e2c5241ebc6be0e827c5a9604dcb9318dfbb37870086b3f0f9a98da52e539f57716d0a906ae03a5cc7a6d0e2503ccbbd878bf1d3f4636c6800117838bdf04371bdb3b7e1f35eb083e9bcb9d920897a46743e68c +e696acdfcc96a6c088069b7595ea9516a36d8fe04dedeb789fbd965db0cc64b7017a821015f6210b6989e515def5a9605fec0d337e4ac59f3101a505168bf72ab6d98ec62a71d2f94071fc05b95e98d4efc59fedc138e3e49c5d0b44d1f48f7b1e7c1944ee189b242950d2bc804d31c7eeb45283c84638f043ab9533976433a4 00b05e5f0dad9583ea18fb8fc4d8c75fd2e3cf9e92cdd9b737485c953620d345006c31c288b380258b6500b84f729ce6730e5303 a3f5dd025d3784a12fcd73b939cf1feff9e2058cc785eb4c7a02a9fdcb9b2135ee3bd36d39549a50caa4b70551a62338198f27e19fa64dd579a2d4e3fe79605c4bb83d5c0a270b7b5e2dcb04c507a68e35f3ae5b4ef5565c9ae81cb6b87f80ab +4058b9a8cc15ac148909eb97fa32aafbb6077b168dde91a411dbc973df7db056dc57ff78f0abcb70f70f800bd752197d681f44df4a7817c0e7f60f8f65489ecb6167c14b525e91fd2cc5d8b80ba380a83d031d5827c8b1262c687c90ef0e62723d9b565557f9f6fed0db48f3799274c2cd60a14303406c35802cba6261121296 00be1d277813e79051ca1611c783d66003ef759b9e104f32298017fb97667b94dcee1ce807dc6b4d62416e65d4120523bf6a4edc 8d80721c2423450ca2926cdc90409e93a3100fee71f2c95a687a6fe277911985ba2e8b4333e54e11db9dda1c8531f92e101599e9c5e5fff9388f976d938a8e706a8d44e5f1bb1fed9eec10b128b2229fb1e60bca1046db119cfc47ff3b435c73 +e793237d46e265ab84ba9929b196405faa3b0e4686e8693567e53f68e6991e57677974677682a2510c4c35b1968a90b32c4941af7813775c061c008a60f9f671cf7419c94253d6106b61e65034497f2d273a5058379bd986e3d917f708f0a2bebdba150f6d78a3af9c722a2430ab0f4bad602e91e18aaf258e3785fee78e4502 0073c807bd7e07379782ab790720de4ae5106f16d34e80ed70da5b1594e660c9b775db94066b93e74f855f57d88b6ecc6228aace a33f9b216b18c2879d31957e41b0e02fc7460e892dcf353e78a9e0fb8241ced6cfc273d1cc299f0337039b24ee9c2d3416f88206e8f12299c28c612e18e97e020bbada03fdcc388e8d7777e63d219fce137d096a496fa5be38adacc062cec298 +ffb8bc80e7619a562d8506eba7658bef0c25ace3dc1d01bdc2ef00933d4fa07b80364e5e5826074edd46a707dbc3b0ab19eec7ea8990839d7fc0a80b70661204c52bcbef57c1a7bdc861c10766033a82dafbead283d911a9502d5f9ef0a39d35ef26f3616212d4bafcd413ffd18b424fe09b48ba02ca5d97ec996205cd49d22e 00a68379b2296a6c944ad5dacb593b302d8ef0b05873ce12bbc371d705f308c739d21f343349524aa72f05341e64f7435daef112 92fa5fd55367f49399869135511c9a8ecd87ba9738348dc967e2c79252c17759d3e3986219be58b5ab0e0a336acd350b0764439264710b98ac1751df228451eb3648ecf23c5db1d18bf4242c2a2379a1703541eaf86c9142eea490bd222a1ed8 +946bde90a5b903dd281a51d7fa93d80f3fed07eaf50c18fe9fac5acf67326bb18effa3144e25c151efc006a50a274ec6c6a5d573051c4e2d117ceb0fa125acad07a10fb6534a8e5f5b3da2a1136779c51377bf76c3a4a93c0c6158f729f2293e414fcb952c9509f228c804f0adc1daa327a8991d48ccf4f3957c5f8ccbe3ad4a 0026046bbb269ddb1ec14ade56175482343a21b7c265026cef3c7d6a1ae0f6a68166b9e6c49a6e733ad2ad64df7137ef230038fb 835696aa245a595b99ef20c9ba9ec3b55ea2eb963bef23ea074204376f88d783f7b49588ff9058e0810cc7ddbd46ebbd03a2b0284e43ba30fd888d0e8932bf972d3610eb42955c8c32277c180fce8cecc1104d0a551a013ff0b3981c25faa88b +07f3fe1369ebfcbcacd66675bd4ab22edbbff72e68709cb57d4f590e49440f01691f490c58b5117bd24aa2fe2101b59c61c417c918ea08ea34bbb9b8aa17491ae5d9329affe894f42d7586017877fae3ce35bb80c97f92a004380374ec91e151995166e14ac00505fd1fa810cf02981bacbcebf5f81b2e633d3a3db6737890f4 00bbcda66978ea526f7bd867c3303b625f11b94dd9ee6e2c2f8688ff07f2bba83c662949d47ad47fa882cb7d203a7f0ef5dbc52a 8695f2abc8dfa590873f7c0cab8cd2be083b6652c91e31fd24283063aaae785091115d01f2c834b349a065318d2492960670cadfd079a54ce95ea15e5e3d5d13c179243696fad922ed447d3375a17c7e3b53cf4381d5f0c70e538df39e605542 +3a1cb13438e3bac9ad4ab1d319e90e2c9f118dcf1eb54d6333c674a665d41451f93cd4a9334cd057a44c010edb668254517a63700a31eb0ca474c84873e486f2f8e158a1a7735362ea0cff8ef17d959ffd851b21a91412709b3c729474d2cb40f6ca0e397030eb2611b402916e4b656f0fd868247d80be3ce33d52054b7661f0 009be3dd3442e0330750f0a6252bf9cb317f32f942ae516a4038dea2c40ca6484fb33611bef016cc64baf166c122e87c15466fd8 91275a1684185b1e8eea56cb3f08055233aced5d26601166730d763e1df128a984be3834af8d7746b227b0892eae806111008583eede02f105496b57f79b06f21414561930f2a383b10d92f0a197b8bb96401e083213f7c5f6ded0d97e42f581 +e58e7b881a563d54772125b2863718690a5276c93d9e1c5feabbdb5d6f7c7293ff0f89805b53663bb417fdd46874b8e6a466e7e3ff6737930a0662af1d5879b071b0dc4d014778dff26a2eca5992e763bf4c4698c382ac947215aa116515876008a56e5bf547857049c38a2d3737ed3393705fd346897c3beb80caab88e5b8cf 00ed321fa283c662e87eaab99b7715e6cdc9b42e14fa5bbe2c56fdfb381369191a42da7e574839f90a85577485f19446fccaf6cd b13d1af9fcf33ca3720cb0b41d82622a7ac03c00c108b7f3f80af3e9aad3436ce02248362c8274d5fcda479e735530290c6dfe69235afdeb2ed46b40dd9c93332e8d7f732e350951c494ecd9cf22000b1eb72b477735b14d80e5384b5e28f342 +8889ea1da1cbed98963941f6ac24f47253ff6af52de920765214f2024aeb04f7ad46936830a8eb04d95aba64ed7cda6ef242f454b67bc2de38a46b6524bd5c96739c4b580e89829a61a8249ec8dc27a50f43b8554cfb6f4fa4ca6875983d4b60a1c6b49f32ddff6fac0cafb64d55c6f594b195c207a9bd920dcf20e0080920bf 00396b805073f3c3b552b1024dcf35559ac44f255b688871a3c6657f727a4b09f3806cbb75d26a00ae1728be632387e804775a8c b287e490f9dd051536468c21bcbd29a310b30e2a4731e1a018dd9b20242d29e6a71d084c12d2f2ad270aa19ee4b5ec0c0c34af6b1f11aec31143b04f9141d006beebb77b4fe5ed32f8152675de177251299aeb2c0064dd88914ea5bd63020541 +55053af9370901e38622734a5bc5589f6a20e258627f381fb0c366f3dbe58394e5997e978eb7ebbc530f6e6186f48294149b8594fb551c31c50521a8c4d67e5862921695604afb23977b6a69b21abe75966fdd11bfbdb6b51ab0a474c5fa07c4de7872a3bd81acc417655090558dfcd5af449b3347e61fa9e839bb9457de64c1 00a8fe323f6736bcabe971c7d964e75dece70cb54561da48a11c40027ebddb23e41c7b48600f569500fe8ea2abebdf480171dde4 89e6da8a352911b7c2a531dcea803d7af683326b91003d8920143dcc9cfda846863f93becc717fe40a5dc88f79640a5d134eff9f721a79f120353eafad80376f8fbb6a3f4939f0cc9ee2838ac6e8655a9974db6d57b311bbcd6452509fb87d18 +c4264330534a6c2bbd8a3b757e0912558302ce302f835ad8c5474993832fd30036fdef40b10ee37293e871db5b0b149654f9e543e22111f9709ef45732125f713c031ccfbc9a2f3aba160c241d27be4dab87ab2fa9a795752ab2daf20f9d06a98d90d01c07133adfe83cb11d5176525e1bba6a9ba70ea48b224d46ddd8103f65 00105938ba9f25034da3e032dee121bdb192ac2128b50a2ed4bca042e96cfaf4660c9d35f3e67bafd4c99f9447e6dc408e0c4471 966b109acd2c068978e4c73c1dbdc858a2fe76b65372b436f8c4ccd5c7659b830f57fde5309098f1e8ffb0f816478c60140c43cf3f76da577f2a74f3619fad39f11fde31be8192eca5175c90901b9a2eaf041dbd0cd5925860a4b9c79d73767c +3236f1ad164e1b25d828f5202e3513c80c72a577aa9af56f041fd96cf5a3363f4b827723b1511a2f16360e32eac90ac55f4ee1146791420ef9e2af333c17d157b00e43992ef6f2be2d2f211361e468413dd93fb69232f0a0d110bc5fff361c0410344aa0636bf809062c73a7ac7c142063912b6ad7e1626fd2a384f35faffaad 00ce11677ca818537dbaeb880fc967dc8bead203a2538a55e756679c4a9e7975b9b3e6aba4e6c6eab4152d0c0939027e9b0bd92a adeaebbedd2d02e991b8c66aa83621b8cec3fb10b34de581954ef8e4ed1cd7df6ba7eefb4abc7d1a2c9d703517dfd34f030fa4d1ca251092a54a0235c10f0a6fc2df1dbd523c2fc6e55170b2c647b84c10fdfef7bb66a48257ccdd44101b1673 +6c400ed098d8369dab6fde3553afbbd4d47836d0d12dd16015f15cb8d067a39391c85ca4e78c62b8b72c1592349ff8dc52db8ccb7fd80c085fae456dba6f4a2378e184dd59238c92cf04e40d43a66b342d2a1325a0bab12b1ac857f0564c27b35e6abed02ff5bbbdc3770ddbb2ee0513df48bcba925da6d61583076cd3129603 005a239ae0f40d76d8d3589f1662b5ca12176a4b2784faa8339b54e96a1e1294433a4d83bf904196f939bd8b33bdb4be340ec703 b32521e7d4a2317588db35fafe34f286e4decf586455a9ec3b1edba6f3e3d5303c9b0e3cea20554487f3a2727142dc98058bb57d859835bf0983ce0cb0d899fce52eb088e073690ea687c5a28003c4b6fda21214634338bedf5c11f45724721c +039a149eaef2de30b0ae457b376ce6fbf88afd4cfdec02d3c5e00400d3b0484c1cd6ba74db5de65d6f2fe39871349b30fdf1ef29bcbb9e182eb3ec5629d07d98354a5dfa82d7f0db3dd10d1510c0dce086848a198893ca5ad24a663494f0596b4eee86199ea85e7e8f2f76e7a6bd4a052c54287f61b391f1e52f96b606151c34 00077390c62ac41aca995640fde0c79c76f4ea8a8dbb22323ed812bee837ab8798c5d0ba976c7aa634d4b1c2c155de2709e7352c af3010016d57987a920095e7a5bc81afc70ceb660150000dba898b6d66168c6bf66a14342ddae2a2902105aef934f77f0ea539b522f743531051c1b3c6f088a6fdfa85240184c9a9a318e2f1a1cf55cd68406368bd7d7b20c0e500fd89cfdb8c +08617d04fffd6644c40f7dd57919f7dcf3c888f4147535d12ca658302305bb8e220bb17ccdc480254004b9035b357120580882ef86aa5a061b2850100285b7d61588a664dd4f5394f5478e68a80f610c9204d056009c1c9e902161eda33ef61aa902e96b6f094a9f053135692182943d38b9763055a38739a2a2d133c5dbee89 008bf23b09fbbed1b55769907aafb97f4759cec98649b2c9da5157517d4f85bb70157076b5e4aaa7a940af042302f8be06a84ab6 a0807e6ddfe1cc60c8853115a003940984b6fb53fe8e68093494d24015fb39c6ddc6e790770ffa1d2b6c440b71a2810b10aed08d58fce6d573af468f5c6998adb30787a9cadb559c0d860bed75f3d636df8ce59640d18703c5ebcbfcd260a91c +34c959f549a307f21b850ae105f41299b8bc94fc292aefc61aefbe0a1bf57576ba8d9b80caac635e4edeb22530163fa9629665fcd43959f68eee32482f1845a78ed7278e6e43d09ed6fedf465001afc0d61f1d2e1d747623e82a762576b879c7024e34f43104593cdd691d53bccaeb8f212dc29bec6bc94cf69d0a8491db124a 00082ad05d19b8e16f80e53a4cccf6869ab5128c5e622ed146fa8555985ccd2aa3b9957dd374586115d4d75b1c01cf98ecfc3646 acd74881ea220a4ce52c30b865cadf083260b767bfd522393c17c3096fab372889860d4dcda3ee9df6fd260d07273f3505279a49fcb10947fedbd995b1cce861e32bdce9f469cf95763c8342b62b47a2ed2396ad0190c0385fe1845233ab4532 +514f4de08a6f49edbb6797c9dad6d33bfa367cc1a1b58a5becfe646c7f3352d5c5d95f7456e7112c4ddc746b9076b9756ae3916c07bbe6d3823895774a42d25d44b3309d18bfe7e3ccb1f85dacfec1654778c19e2981a853c1f40a7eafd16d331093110698c957fe9f1d86582706a6885543248b944bb70cdf9d2ea89190cb02 00af7e581aa4f9be5815f0c447e39de00da9194eee5e5f609668b9b69930b5b48a948614c2250260d1917f0ebcb00ebda4bb52f8 a9d2e1db44c6e03fa946190d119572d5fc2925cc8974617ae75ae049a3b7bc8657aee1f0728b37b04c50bc009b5da42e14844cff020d26089b286ab8fda0ab2ad6a7e654434f01f5b4700f76f3bca8445bf284b3b0ce97f5bfc7e557fa6b9ce6 +4e5d16cb1dcaa1abab1e371e1de02f31ef4e0944dfe1fdec45ab64326435b2af9aaf1a6ed8fdf1a6ab1182bb53a844c7cfd66da30aec0d41757f5988ada0017c4ca752597a9fd3637668bc1a92bb1556553f28d66805bb47f1ef91908ce098d452872da9800e77e1fbd43ffb0ed6fe6a62185d4be73ae96c9241b82cefb2da22 006d14107b08354e6a41d7d7d50c004419db8bdc50db43428df5e86084551237223c498bce71a17e25695bc438c5c09e009c60e2 ade7201a665315ca6133d9183d9c0eebcc785bb4f7ebf21e8435a2ef6fa437dd74963ddce9c5ecf9f8705a684aef064b12ab896ad7f944805efa57bbd79be55c61f4fe41b6d117f7dae01a1c0bd95d3ee3026cca94dd2fd13d6ff19a23a7569a +e29e75269754ec1194270f5c9e8267dfdd8c696008b5ebc92bb840981fd065672f07f6a0f1b19841adfc51b478371e1a0db9c3346a9f0a4ccbdecb7040191a00ddfd0a8faa0e69fcf544319c0155d02797eeef99fabbc55078f9d852927c23fd931685424249b87ed0c70a4a3e2d3b9a2f92830e7d8f7650c0bffa8f8986b7d5 0099d96d2dc9c79549f031bd5346cf6a8544c312a3fbfc560dc8e378efdfe025b0e6e61e09c04c8bf4133396f993b0906c33dd30 82021dfbdcfcfbe9ecd877436cb121373435293bdd33ae283becec73ca9126165631dc352a31e4df5f62d7e86425284801f03cd521cefece1bf28b7a7c202a7c36c4a628db5fd238cf6e897a26789ed0fbf0acb939a32eb9005383506adaa0de +1a538eb447c18494ad5a5ad27be67fa60eb2c5cb2404eec1dbd7244cd802b17ca5497e779d5f779b981b165dab53ad19fd7bf2ea7dbb9b4baea782a43d758202f147e59d6b6b8ed54f4ea084bc18519943f6894d603e253ba3e8e339a6933bc3a0a47126087038e1c813c3f2997aae321b7c95a802b4b73fc7db95897b7c91e3 0049f347dfd361a65910e97fcefbf60013a54837f2ae657d65e02397f59dc6bca27704fed3affdc3d833fdc621cc5e5f99b92a63 a2c2a57bcac2f3fbef76dbfb8db80682bd790b33e20c32ef4c05a15828ecba70b120962e90eb056088c67c3493e915e810ff932291c4089d383dd297eb0cc4e2a8bf2ec5407e7d537c13d5a9ea32800e009a8d13570c2be1ce23956359a2547e +7502c755bbd385079a4001b8cd653287dc3054f3b57de19d0ff8f63c0308c64c56f035117a8971d43654f89b52e923947e4760ac72be073136da70c5ad7ca1658cc0a2d2a880d3a0c0fe636fdb27b77ff260c4c1ef8a18da8e9fd777d732a37ae9906e6c4f381f0a3d941048d5a1f6f2cb8593873fa4bb1621a44bc2bebfbcd1 00dd226de602af4e9f8e25784bd1bbd4cadb0a8aef525d5e2d57b9f3555feb698765672c5099a7d6dd5faaded69d8d68b4804f26 870e8811fbd6f0f95153a117aacc78745873c0b22229a56d6fb556bd73b7e39db72e21f8d23d2747ba07101c3c24722908ee0889a7f7c836d3aadab47a2d408f21fcde701de372152be96a8c115eb128f2537a2b3c1dd312eca08bfb565ed33b +95eca932d03f1df2e8bc90a27b9a1846963437cdafc49116ccf52e71e5a434cdb0aad5eccb2b692ca76e94f43a9f11fa2bdf94fe74af5c40e6bfd067a719523eea6b4e65730365ee498ac84c46e1588b9b954f1c218920cbf71b167fc977ee2a89429590f43bf637eecd91b0ce3be2d66bac5847205f76c06b914a970f543e59 00b6fdbc9c8c76cb2b822a940d8675889ca6f5132429da795462381ce29313a23bc132976fbeb346ed4c691e651028f873ce7971 8e2586b54eac7f7bd8137e1eb21c952e4febda5ff80b24890cacc6c67c4d076e60496fd17ae3864c9e93465d68c0a35908e79dc7bd0c8655d429101192dd8dacd77a7f2d95a772fe74f5facf3e598a37abfedebd89f4b652e2483081e3f6e61c +8ff68cb00d03e730dddb05fe0b2344689529096c3da6eeecaf097f22c7fa340593106b1f6726f06b7ce7358edbcf801ead959438a42f94cdb467b3cd5b17fbbcf75739805f9eadc869c33c604cc58f81591b0b8bf4d42bd53a801f0f829a31af6c129fb4f20f1250f959754eff8c629b85a716b6a18465b6495798c0c5166c8c 00203d77fac64591eb9a18de20a9d5eacaa1c3ec58a5ecdb3008c2d642e197141d16b3a9fdffe61429264f5b420f5e9926659a4c 9389a444dfa06aa85d0ecc489d0597a057b7492b47f24f7304fa8cd45635332e7007b3b0f1b0434793c40e72174bb5b5161af2e8f1c3980b6fd0ad411e79c67a793a786e5d1ff2631baefed0b0427ffc5a2c32a31e47ed69e64d461baab709f3 +01451c4f09720cd53377a5ed04c907a735477378ed960235a833049d6bad6e6e89958b4c4249bf0f6d4f043530c9e5426deb0ec3a12b7feb4860757b41bf602ca95655155356ec35a2db8e2657998f56529be4b714364f83a140846308a2973907ed7b08e935173ebbce5e29afe1444cd51c92824ede960056439555e7e74450 0057a2e6a59d4871c3d547690237dd9846d6d5dc4ec0678aafc9c8669af8a641eed67bfea4b05fd6b3b5357ec4d0caf352691ea4 9641809bc5075ee5c620362f8d74a266970748005bf37d0ddb7b0c0bd5f0bf58a8b75b9332147c197f0f6ada7f514e0115a12fabca68afd4af4d2cb02fa1d3485f5f758334303a891dced589cc66dc1eb7111dfc149b7d3171b351d234b66262 +ccd494ca005ad706db03a3df6d5c6e876ef859ec77a54de11fe20d104377df1900b6b192126c598944d19a2364b2ae87ad7fd32265d59e1f22be5833f20767793677b628f18e9619f8ca32f3af3b41c31e87a98d1527e5e781bff33c1a8be3a82ea503e76afec5768d7f7dd1f17dc98a9e7f92fd8c96fca0db518bd143d82e6d 000a3da7a6633608fcee9ce4253bbcec08d41ee6b00178ceb017de74e24d48fd89107c9f2db3556063abe3cb011938f4b4871795 8e2592184304a529fbfd4efdd6c582b037d3822aa3e1673fb10c4c12ca6cd395a6ea414bbaa5a6141fded9f30ffad5d615775f9c683edb8392c558a7a81c3782e488931f9b5f2e427163f7748991e2990be600d87330789f07c3011612ee6d1a +5719e50d939a8d74efb444eb5a77cda48cbb59e7f976cdb2ea2848bfc558718b39ce27b893c229db94bf77992222d1746f8f52f858f85124a28193ae0da039c53d484681785f3367f6516fbb8a86560aea9e3428551facc98cdb1e9df8e2f37db823a7abc589f667b5c93c4c47061400220a2014197d514217fc252cef5a2433 00384723c8b4a316b450d1fce0b2645912b8acaeb3cad50860cca43bdc0206ed5b3b60ebdc29b3eda305d0d60eeaec261edc24d5 b21a2285eeedf384342747200ece38f163d3d993cbf911e84f5fb5e66cb25e34ece58cc515658209e3defa04de58ca591312bcb28cfd063f4c200a7d93d76e6018455f01b535675ba5f8e36fe360546895dff376282a6e12fd35e57cde94d62e +c84e5702a339259a61b5ba8ec1957f23ffc4f1eeef3a58f383d3731bbaabfcf49ce2ebb597960ac5115a2af1c62b193d4ab6c24433d5f168a1752e40145f19aeb6dee889a53a4fadd13eef60e28fcc7ed6a9b8b0ca286c1b3d66a4b2c327a629d15c148049e3a0ccdccf05cf22c31956014595e417060627c8125bd7c00f8850 00bd3136647572fef3de51b12e64b36460bd3a27dc660c164fc705417339cab21f9e1f9be0f3da926df459c5ba58b701d306e67a 8797de9651015858eb0b7de5db63187c535e6e959e05380abd79160c453a66bb58c77f741969071856c2e02b1d6d68260bb64838fd41025c3121a0088b4c38a8e77ddaccc5c6002b4884b64eb64953987df77d0747885ea7a1c02874fab1cbe3 +c90bf11d04a708e64b6f94d4cca64b92463eae878c377b188c82c1c5f05a038be20eca2e18034d46f00d9a6fc73c4084981748ee9d2915d87aee4e2321f4f9e11c176f01281913e324700d9cb474b7134fcc408fb4a7006acd9e63d4578ed4c2729d8e0d01b1e6174a43a024ad261eb644ae98979c3cdab75af357f6dbdf5db1 00495be0b0a9d357f6155fac008cec90442200bb842d89292fde38b7256e4117284a60249b3101b3f19f778b680c0d1d7422b84a 846946fe1dfb8a777d5e26f898e9dfee1df85a0bdf29a4a16751400386a6ccb4a9aa5da83b0beb3b178d8635fddc1ecb11515c60edc0e2b9ced770533040639de2d5daff46b53d9ce89e416a8ee44d49403dcdb1e5a715b22c1f786b2fc96220 +e9b2a33906a1079280100039787377c2971c378b92e70a38ab41dc23979d6fb0c41e53a21b37632407adac6f212341cf6af8605b4978c85c9c16960e1674247f1795cd73b99ff28cdca024f5078490513c77114c2f52288f5376872c331151d7b2c08f7794f2c1f9e0d849d32d73636f0aa899988ca561a76f74543b37cbf3a3 0079626354dfc4eeeb51fcf232ee9e6b0130c9bd40f15ed45606bb7faeca8f359e0c3e18bf12769254522fd4077eb24bd5454871 aaa1f6b93a1c4e387996c0969f33b44985e1211253969025589746f104e8b1abf22ee90b2548469336d5920baea6f4970b2eb61b3aa02d15ebc127b74bf4fa169060f98be9deb27a42e82b3a53857f32e6a5944864c47749e48720f3154801ff +672db3fb8cc8e5f831be700498d3ab3aef14b7548e8011b21351215fb6dfa09460d18f52c02c8815baf396d856a429bb9afd602a10c213af34db80447f4c06ab4bd28873c88eb9639b199042d4b2cb13cc364f734fd4ab7bebede7dd4da63decc0cc1f84e34d760013f66d71641073f16c08078880b67230f2d6c6bfe17d206b 00ab42bc7d0e3c23f8bcf928e25f9f027b56f270398a1d37bea0ee5426b944a9c9ba6d0d7796899543feedb470f70b2ab148234f a6054993837f1fc7c54311956830f178cb65c4b9382eab7ce5cac2dec7b3c7cc6f6a43a9087edc842ff98d5e7a0d9e9d0cc0c655550864ef22be6d77161bfd8dfd810e0dee08821c813328e7e14c59a66fbb15086b3ec2ee1eb1e748f11c33d6 +d7fd06b89226cfd66671ce5b4b656228c52d986afa7f6f30161680eb0c9cca177992a8a8c40167a64165c518c55f678702125709361b536bd928567c97737bd750d0e2e6e0c00296a6ca565f7c05cc8c54ae7a4e0c334c6a968fc18a959c18ebbd924457701316a4e999fb11084520dac68dc2d69187134c40891af0355ba89b 007f7aa2216164ba689459ee5d5ca29e70ef75a5b2a4416ab588df1dcb9164330c0b405a9d80c3acc41c19f58e24e17ecbc0fa7b a2ba1e4f755c2fec1585e2733a95f627f549001338dece349bf5d6dcd9c1ea24bb371274fc5f45dc84e0b811e72fce880ebb0cbfb1bff3036df3cea18613128c6e0a54ea699f1207799223cc50bf2f6711fd8f1e2b8c9a84dde7877788f76767 +83b7e9d3ec638fef51d2885fff5490c94e2509c126608f82660e5fc523032f3e85d69d9b76af145f6bd916dda35775abbb6d1902bf38880f8b9259822055c5b1bc726c51029972cf7474cf2a812f3251aa71813476bff55598d079f075a40c6c41498bd865ce960c518bef75a873b9d010965f342dc4b35ef5c5972efe6fdd18 0021d84f070c6823a70f1a74225a472118c93ce9dc509aa6064051ca4574939dcfa96be862069424bdf1a23f62f2868326422e64 807c332f9ceb4618619c41cd9e4b5c8d08fc7e12377bcaa518373896445dae08233703384389ea6ac207fbf0b90b45531077f4c00603e60096edf11ee90daa53f75b4a70fe9548d756d38cf341dc7959e036ed18a3587480ec9d799cf254c046 +c62c7bcc860f0e175128e1127dacf935ce62ae794cc4a0ce7966bceb023ac0498641d7281fbc86f9ef470bbc77f608f83f8d0dd6299cf08f2cdacc7a9642e4246df131820220e5c05d0dbfceda7f16b86add4793e9b6244d96b5c07cfa23574ceb43e8e8b5483192a92b301aa3b37702b8f94f0129d8af1617896b34990c9b02 00b6645344d17528968c719091b6e2072388881dc10bdb4c7fbf41906cadf3699b30f9c1dbfb4796d009480664e6276c0359e5db 88a43c77647ee4dafba2d699115780079efbf5c205c0d61854b8534fad17747735f4bba494b9e06b7f3cce0e2c6c550703028ee3639b726bf15846c2f9c51d70dbf94218e10414c9ccf682d1ca1ba3b6ffec3729bc372e8b76fe185913f07bd1 +b5bf38fd9e822925254418475a1ce762a94e336f12b156b1625a4574fee11ee472d537ef94b4a4b1c0a73b0140d0b818cd06636653e6c07f0f100118242a7703756f1cb1119b3477c4ced99cf45e07e83b7f2749c1a5f8d8c9272d221fe17f7c6a5fb0f8a16af46f232ce406aaf565c6b2766a2f6528c82e74fa1c0a7fcfd49e 00f8c2f770cf5f8e1f900e996ecdcd84fcff5cd959777fd005d721a419123221a3237e39834b270d37752470deaa6cea023c5058 83027b46943d4224dc2f58dfdd54e88ac676860f4fed2c6fcd005e34080f8f106ce6c0491ade5ed46ea84bde890ac2720fea8092a2a7daf925ba3d88a2b9484000834fc7d70cdb973fd2000d1c6699d99cd2431bdf76fb69ec69b8d7b8d36e6d +6d3474770933ec01b76be789304b6fda423b12a0ae8c87a5ea8d7ee9f71300f39440e1c7f5aa4b47c1a8628cfc3a490b15ef292a741344f40a8fcdd02cf3863bf3e32d53031f503703deab17fc52b3d4032f4e237dcc27231b85d3fd60b49ed7ee40c3344948d87c3f47564d20a11d50e4e520bd16c8701694fc70901a5da625 00144adae951fe897d5812ee4a16c0be4c86c5e57e615c398f5768a1223a9be20fa82ceccf8a16a31432bbfd17e594a4cd8a6a07 b6d1ae428b112868598f009403035e494135e18b78ed4838f5ddc4421720d0ac7f3416be9a55c028cca86eed759998520681c0e86c1b2f6fec267dd407f16feb02adf27d6e54e632abd99956add493dd4fb03258a8a0a4a235c08bf2325a5295 +92ba7aaf71f625f7a2e024058dc8739da3567c306da4a812ed9e1542b7d1e982c16082166a59720203f4524c3bd463a662c26a82ec7b4376545206e650eed0d3dd7909dfe3810981393070d15c45dc4a75a8c5bdeba533cad1ec34fd20466a61e4cde3b25af9a80a9a54afdd7de1cf2a74ba32d4ea0082a037775413c61a8d1f 00a51f065fb32c55bf4ff6f18ba9d488d35d9f8da593adb0ab1632533284e0adc43ccdbda9d9507b9862ac63b5ae7b0f78b479bb b99c81e4df2e19c399152af69ddf71e871d016ffb4e22d8064f7e0e0d463a098d28485b360d59229bf7b4b36147f6787109825fa43c934a3dba4b8648f48b1438796c45cac00b6a00a2d4c921f681029981aaa5086fb45d5d6922e404eeed849 +b3fb9e48c333201324755a81f3ae5d4f0e2ae7cd24238fcc66d858e3aeb1ee03328660d6399676eb1b7d8285ba571e214d935bb45516fccfab57b8eb4c3d5f1d7357c768eb7b5e7b5710f599614bd4e92706eaba31f8a5e7e57af7ed13066af50b4540ccdc126b677789920cef8543907f0ba9dc92aae343d3425bd784ef483d 0095351c0bc07acfabe6477fe85f97eab520dc96bdd58b44b036328ceadaa56a1904d2217c5fd25155ff2aaf9005a3e2687fec81 92e0aa54f18baca88c034cb896d49e3d78b2291d7211f9d6a1f29efaf7ea83a1654ef35d3e650459a4ea1c4ce9a2b36a13c83f2b72416e10f699897883149c965b151df019cda57eae2d1aa6feb9d911ee409ff7413daee860dd17eef5e7e65d +9ec5f7d65082264b8a50be772c44277a73ed19199eb275fe5976f9799d8629fcb4a59a8d55074cd2eb2a0e02062d3f7cdeb05e62931a24fd1aaf14c257944d1b42eebd52726d6fe281211b39038e52baae077ea4df89675d860d6ba5a0f998d049614201b872e134367acc90066ac602e478ac3e43c3ddf4b0ca0aac1a68591a 0050245c1682344fef23bd549ac8d1e8e44b2840c43eec1cecd33daa4e9ef6b53f496104d7432e14248682cfd6f5b4853b65adac ae7b2e52be50cbefc4ef3823369f044ffb6192c789b69d3dbfd235a78cdbc93b73d2b62edc50a4a71fc67de3179c08dc001c638f10e6e45fe16a5ed1a49233f251f03d4179be91a7beeba942e56d7d5921d5782ea53b63ce5fd7e970cbe04119 +61d657bf472676301503f6784b7286fb39fb4186bb88abf1edacb4a2693d0a1e2b77bbf2758c84f2cbfd1753e20841b1cd4b456400d53f4d686e666943f9b6ffcdb77f510be97536e9698fc84ae347d483bc8984548d1cf86b9b40d360f9c0dc5bd1c55868e26fce1460ba94ef5e94eb63c9f0776a0f446c0cfd4106d9f36352 008d3b0277f0e9fe54581d3a9499ccd7f015c08339591326859af969d2a26284e3b3beac4a0b74d324ce5cb5f38c7995e4e3a41f 8c89b1092c9fea98749d1befab9aa5dffca6c63d6acec4adc983f9256662c6b9b44025ba6ee895c7d67a2116436f022f143f5b36d8153205402aa6f9129195d80b30085a79e584d5ce0623805daa022ca2a488e25cbf9f87baf82eccedda43ab diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B571 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B571 new file mode 100644 index 000000000000..67b26d36e406 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B571 @@ -0,0 +1,60 @@ +8e14f713a2c427b1f79491033994f76acbead614d12e73ac6f3f518f2052a10c1273aabe628ab38e0d3d5f8ff254802e9f44a51367bf80325b6fc39d907a37f731372864747b10749ea5cb3d3a83da39c21a7b02885a8c1770e4397cedc958e4baa21d5007569dc9dd1e45d2181709d900a394454090badbd0cd9c2cd2369aad 00f42afce7f7b3d45f3f925ab29fc3882a89c9f585177887584703cf8bd8fc572e677adfa55b402446fe1e90dc855358d92c3267c35be9674b40c2ad5ce8dbe6a533c44b0ad8d2b2 8c3278731b0cd331873ec3f4a9fab3d4a5a2f4cf29b2ab86880a91a0591fbbda873d901073b9112c79f51d5416cdd7a90dce6266d3c3c16ccd4dc12f1722c942dfcf2e1666a356e2a965838d72584fb418ff36caaba90d9659c578879bacb682 +38b60d27ff08fb191811036dbfd5b39e1cc3427ff70efb67c851e9cb407f9fac6f348d289df98d055eec73299fcac068bd0fd9ffa3c5d244659e4f714a58d79f6727f323a7ee26369000e90e34e106f99f5ae2ae1b64ee89e5a1d304ef20c071a7773e9b977ed3d49f467d300a881c8371041394910f9c366942449045568f01 02f36613043cbf53ad36e2b38998bb867503359ae082d07d040e5a10a43e06ba9c91e7c73308e41e2391b65e634f83b162cbdf4e7a44ad818fb93a978af00f06be06731d8c5886c6 a7be41b267d2feeb0cf3d05c128e303a49a9a8778a404cacbb3054596748de0932457e26e3b9ae6adfbc61b201ee3f6c1822156f88cc7a303c5b09a1c1d4006ad6340839933555f7590f2a799e4af19df7c0f55070edcee2e8ef773d0c3203a3 +21709eeaf9e1953822294a478dfacfb205fc25f447a73a76a32601c00784cbf2f9ebd41c22721d70cdb3842dcaff4a4f208d41c0816990e421cc4b8538ac2f347cdd0aa2a39f1aa26ace8cb6a606b23f6244894d4594a0f6a5b8f6a695fd66e1a41e2eb6a377017177fec56bb58c837e311cd04c5b50575faee32606b9636ec1 02e74948c46930cbcd9dbe2325539c7dfdd910f309fd610e6599d425aad9ae230a8d4681970a14f2a71fd08030d0a40ff40dade7de1b06a80441bbf7e2fcf1809cff39c7ef88bf9f b8ec9149235c280742d4754fd8635654a38177346fe24d012ce26b8b999cf0668b8c02f2b95ac65a600b376094a9cdc7002681d65676c2ca996427cd7477d0df707e32c3ebbeacec769774c768ede54c4ef9636f42f1e32afd3eeff5cf90b5a2 +3a131fabf3dc97334f212fce41c44300440d16de1d6060450875f7276f53c026e2a511681b5a8d75fc0d578546339542833145f7ee13c708df33e584445a75a5538829286480d339be7c777c03c998a6d3f037b25799ab2d541021502a0b02a9b9c337a8b176c4f30e5b186485a6103b1d1563ad4ae73ca806a5e4daa92e9100 01b5fab1d36f6f6d559f65d8b01edba610620fc3a38307b1fb1c5bd63e7ffbd4a9098cb8bdf50975a873f5d047ee2b627b090897a7fb5f56d3f4a0f3528179e7c969926fc0d3b0e5 b62e79131e1b471b4ea0311854f6061bf89a9351b97f98fd4366326a18ac214565233fe059e908bc46cca28b1b5e06b5172d40ed391a93c59e6243574377cf802cd5539d00468fa5f16e4c5efd52a16b74fd802a5c68d46d72e9406f20edda07 +679d85a762f2574b0b31b516270b7d33d5e166c83e91a0f48e0f3db20b52f42f9e6ee9648cf58267ffe3b713723cf3df52b5fab5c14db1e7189f7cb7170bc6ec7cc71946745e152b39180f828688a5b6c0b2957ab94283b90052a3c6e36843c391aa8810f9253b639a8d5a69aec10070603ad7a99dcedb544858d057a1d66b89 0383e70c71b431eedd4574f65d01fb0304f7744d668408c847f7899eae44770a7f3243109740f177d7146a27748886b7b77ecf3792b512e8d8e37c3bf4ecef2b1253df7066498f01 9062de7e8cb38d50786a9e3aeedf34e190698caa578efff96c9a01f406efc644afb961a23088f4bb88c50b2dd3429fd80d4fb6827426d234a368d34cb121798ade32eb0e548c79d76a3d1380f4754aa89d5c92f0629c45f07ad3114a4b00e4ee +236152ad31ce2ffc0dead3c142cf6c770672cd2e75af4a82fda1a72e1c775cec9b481c6f3e411644df7e7ee901c501405620af4b6e9667dfd46091788daa95ef2c6c9f5c240c06b15cb0df51f5f058d8a7934bd7845f007a35f99fa97200b20f3b5b14fbf1e372507f3b2f377e8d07d30fd3e222f398f26d8f428e320327f901 002261d4ead21f02fab19bbb0da8c272286704c8f0c6842ba47ded121e5cddef79fb34e6b9694f725ca502949faecfb21e3cc062a2b4c654bd542d9a1fe8d97bdd0905c510aa0999 8fd6d53dc6b492001103ca6f90f5f96fdcf1a049d8af4c0aa4aa0a901b2a02b8b9c774fb022ca386d76fc8cccb4c1f3917bc98891f105eacfa53588cb52a2d5205d27f4f1ab02ab18d2288ab121b1fdb3911fb13c9f99ddb2e8825beab62273f +ba3f02c4847fae035d747db246fe4e82fb9224ff9cf568a6ae548f5dc2befb2079541d2cf9aaa6b18c281a05e7ddfcdbcefb25f41dd91cb3092b3343e16985e91c912215cd99ae4a099baf628e33a7b277e3c36a13aaef85418fca99f64d73b789f23ecbb76c3095ade0a5f7f34836a98c5be933b44a94a2eaa3f99b1d8e7937 0316c78f289e1860bb623082be9d9238b88e38c5e978a868bb90f776235bdff4eff591877b7f350cf14c40356922b2b6aa51d64990360b2b0e44d6941b5dd9492b4f4e1f42ca163a b553ab08f768fc222281203614af63e4ff9ca574c837db0402ba1ef8d3aa6ae9375a846b47a1ef9fc11f8175ecca2d720c837163b3fc4ad3d279fc64e5a1a2c4196d60c649a5f9a87d066f4d7b88c089bf5a787315cb6796fbbb35203b3edf13 +6d0372b40559e075af56af853cbe18ba2d471b0fc8917764abcc69102b03d5bbe1fc12458215be66409c26c89f67c72a8933677a07f88993af6918acb074fa915fe883b24bc3d191ff1b08852f07eda98977e70eba072d8bf189cd545230f59559ac05f1fa3f4e65886d0bc274a6e02e2399812b2bf91abae81e21279c5de996 02c1bc13f8320d97a82f3d9354e195481902214e16a4fd89332a0499208e91d50e5cabeb4927ba030cb42f5bc53b10f500fa646a8c88508cb0d63ebfce5c4bd574c527d686c735ce a896ecd8fafa34e382dbd670204ba51c0002abc776f399e86562b50b02498938b17e03bfa9a9e40e8e9190e3451a40b014f342a80f65c00e16193631907a1d990a91046dac2c3b9f0699fa5ec53be10a1c82044ba53fa7bee2051b8a7f622d4c +bbfe66c82bc060bd14fd0e40769d9b3a026eb447550dd9f118c30d8448f725f8366edef042447962ba7f7f833b9e9094d0ff600714697e632626e7d12a592e040bdcee166dcda93952323191021bd12f3b1647d0f25a41739994659dcbb19333ca30f46f539c6f0a5c354cda8969a1eda572a309950c84c7607eb8ac20163912 013bd80eafa67663e75d7ae139bf285d2b9f1e03d8e32153c73e26d06e86d7acad22bde9f121a3f1ea674dcc1fe67bc7f5398d5e92555056bc046a02b0ba86c2a0dfe32e91add5b6 8c5f5466800dda96b3cf6efe28653ad1ceda56e06803145e72ce56dc2c472f6b75bece297af03b062b248077658e8a8c14c3da7a3caf893950b51142b1de5f6e48826550c70a7904cd1334c2f660f0159be84ae4684747516478f9a0a1165105 +b35e9bf686717ce3b16a59963a32a2116130453b161a4e7ceb27b755856add836d779696edcaee3b5c986523891c8836109d431e55c23afbca022437ad19e6777efabb6da3bba1f5f44f905395b4cc7c9210590fd38da621582d059598e5e4569e904358e0dfc0dbfda4ce75538aa97480912852bccd433a9b96c9c66e9597d2 030834b0a4284097cdda2ada6947c6c281f7290a49b56becefea1e2788ea3ef78fb96807633c47c25138341768b241164ce0d42f7301728b928be2c047f2eb60fc2f844ab77306d2 b759d6e5455177e456c27c2004bf092167fd8da5feb7d35ae50736ec070f8f3a628ed8ba3f581726506fe59915169893017d3d8fe6adc6bea5bf9b059e1be67ad3bc31d5e97e6f5be97aeb1f2ca811ccac4c475f21d3f793028d17e3936a0ac8 +57b5ae7e95c638b258d1e09b3fcb4341e203f5706862e199b103c8fdac72cbc5155e5cf8b300a0b3fb0ce1f897c45f7aefcc528182f73dd450cd84d5fe9eadff3f704dc2a01b4e847c22df430efd1c66b0199f3e5b59348af5386962a5ef25204fd230b54d58d7fae801c086f8f405d3d0aa7a9a9da15c22b868817cd897d853 00c81a79ced1eaaafc31b69a40d9939f4e484d625db6364a8e589b6b4d336d458b44287ea6c6aa7661113fc07806b147ff98216fa0c08708dc9d651821b922741deda522b4e436ad 80bbc5ca69e5cd0792f5173c31ad262bc6100def07503d292cf2068283ae1d6f8f59e40dea03eed230d35440f5e7d42f0c4e6fea2440186747903f0cfe7145ce3a14c4aa91ef825786a4ff77be13ce7f50b03ec2bad9e23100f433adecb2a830 +daebfef74b452f039c999ba0528be3bd9e16deb5f46f6eae87b63db8b89952c949fd7db08311871eb2596865eed107aa065f030226ea675ee3256c31a3f85ddf4c21760582144e07af208f33c5f47cc026db5403186a65a47940691ea2d74ffb1245676260ef5717dd879d8b5b72d96f87fef5f762d4fd17454cb5ed83d8a11f 02f24670c0f77d2ca0266a743023d2c7413d56d0b5ec77b454ac59087efc4ea4d46179e10278e4ba416ffd8c3f9786ed202faf8251c0ef5a9ea5371fbb35b7afe3d15a9cb4bad975 a350e4826d988db0a4ca3137ce21d6306b5d8e9456d65f9bdaa639bb79c55cb3138fd704494d7be9c823f4b396a208da0bb7de47086c6cb969bf70f189f24f168b73ee364d74c5917a478bc7cff57b74947d14e829dc99368b8cb201c1253ad5 +62af0493ae79d71b552c4647d1fb7ab2f282a91cd44aebd8ef344dfd77b521b0c0a3f72e4513c8ecc0e4b84efef3df9482a07ccc1b740c571c5e69cb913740a792aa231b9dc87edfb72bac188293c6c6e788cb3dff32e8f483f8f34e21ee7efec71302cc3bdbfa47908a135f6ef3ff179dcef26d1a3987f7be967a6c0f799b0c 020985f2c6fe3ea04bdbab66a8b6167e5969c073b9d53cf3c77cebbf73f4dbf75e601620ec9c3107bf3fbfc6c79f8f063409bf8fe1d14b19e323d857e23dc05157d270c7514137e4 aba2d7153ae6aae30623c8a56b8a9226339f831b3f4f23003ef1ea6ca9de899ce6ab9131ee2f5845018aa33824d0e49c05ef2edb28b66e31dab3eda805fb34243ec9735459a3fe4bf33093feaf7ea661e62099e1a89f5253d8d4ef4485e7f32b +566f17851951777ebea3f8285610cd8ee5f882a68e7a4205e6fc9e2d66d210ee2505ee73d6503169f7b903012d43e7e99efa493a8e6ef926b16b9ad8f52156840ab561fc6b680120a88714fd66d1d0742189bf06c155e1138ee5314707173f7352e2cea0fc26e1553643f2490428718e44afd8372cbb7bf5b88234318ebf4355 02b3d641607b8a141f876f6d285ee46aea543880e772dadd5dd83d595b9643191d9597218e1d6adb081df133304037bcd2c05c24a54e6c4cca64fb2cc4569d6882315360059496d8 8979f7786f790fe770a22fcca2f038ccc303a0d1027d986aa25142815c227cfba7ec2039ac9892514af2b571a45fc0be074a952933a66c2a00571d111fcab1bd25c86e9650336d7020ead5c824a25ea138ec48b9931871a0bde875db9f852efd +25155825fc4f9a1c4dd1db837008e7e2594a879052431f5bfc76d0d2565b8fa726008befaeddceef73f3c60fa2cdf6d9a70e56d27210bd013034b38861ae49640ef208d3fe294ac4362f8eea44f58af3af8a9167a36b5acafb7ec95652d5885a0e08067ce1dfbb45a0c89ad1acb53eb404bf88fa5c3c463a0f912b5a2522a0d9 01afeb5ca87c81025ddf09c2b2c5ee22ba0105c0e619b67a324467485bd839030d149fee44d8bac6f5902a1245a50c3437046b7c89a84116b2147cddc645b6d2fd24d68e8d53bf5b 8c678d5c3b59be2dafb7933679ef29e0374be55152417f7006819e641b435e2d93c459e3bcf947d03b5c83aa770a7624190699db534648ae55b4a89f271be86a2c57b41a6f6cf4d20e9e34aaf4eb6577b38987aa8fe376d201471a91f8897c43 +29acb0fca27e2a10d7b9e7e84a79af73e420abdb0f80dd2665696638951b52dd39ca028166b47a3b6a2eaeceb1a11c152383f0bec64e862db1c249672b3770909f775b794e0b9b28a5ec8635a996d912d837a5f22471b40ec2e84701a8804127a9f1a0b3c96ff654700bad3167240c2518fb5dedcc1be9f56a807083e587bc56 032c97639b69c7cdbf419286d0a1b406d9b1f2886521a8b979a36118d2a368aace5b02dd8c515f2041e6fb9f026d1e82e789dc826a56d2ef732b1bb0f49be2b696ab5d3d5694a2de 8b41e67f457c96054bd65b1c88e6340d9788f1c554fb647b3ce836f5681f75a03c66b06f2c4bff7b8d46b05563c35e6018c0eb53ea2a28336440e68eb43f74ecdfb4eb5f3ff336a60c970aa8fb62f0f23d93ac856cb08cdcb428a2a728266c5a +c92d67cf6536f5046e15b02158da698bcbba4ff1e4e9e9c882cda67f817210402ef917ae93682c9c3dd817b21b73c6c00b7bf92ea80ecbbef2e67f4f4379d078a2b0f297742b2bb9c3fa3297a7e8079f488555bd37715eec92b4b1cbf897640ae8a1d2a0fbcee5423ab31a37629f98630275e35094a896cc574be0a449bb1bc3 00f93672159276c5a293582b9f49607bbdb970112f6c63b2b3b5d32ad3c8240c86b1af13a8dff6502c6b6a17712cfd988f8cd23a60693d64104143b3f91adb37f852e9e11a0ef110 87900f6756ba0ded1671f9311ff478a320a1bb1cce173a52843e17298446bb5cb864328a52c29a532ff69e9cb3aeaf7406c5e42a88f79b623bd669727c2d057518cbe7c226099dccf6e70b8deeecb273e658a5718c7e36a9facdff0d324661d2 +15413f614c4551e3b138b64f66d15f8964c40326a42b0afce820778eee4a88edb127fbf575da5263e5a2627b5461d311813ea868e6417615e7c4938313675009caac28bc7a2f4c0bc37572d9bf36a3b1794294e09c0121ceecaa4b916df45b0dd31225415e6c87cfeeb092a008fce2c543cd62365779ae28f29fa02a15d9dcd5 03db080bc99c5fe7e06d5032167af56783cb423fae59fb5b3c6bce5fbedf56b7b39b17810e48ea9a172881aa1f42f5e267349b60294d4a208b4437666b44abcfee5a1829e9467908 b168c458edfb005775e4804f803ead512db4fdfbe0cf6ddb46d3e58d7f1b33db9ed5b30a905952c3d0528567acb1a8e8164586b656055915ca3504c9059e0857bc428a50dae3b1b13dab1736b35befa91f09775ac60fed56037122923b7b9e91 +9f901557451ae2f8ec79b6d4adc794cbfd9b2e6d28f19409532d91682820205308b41498a4e1ca247a2baa8da93de95e3c0f7afd6ca46bafdbdcc6d3374a12684676a50988b86a960a82180648c8c1e38f8fd9af604c7be3be4b24799f4544ac96d6360cdb83d1d0847fda21642934fd6cf65385b50d86d4656987901fb88d0c 006ee767f6f36bb8f364f324d8346455c899a49237d759003dd52cfa13b9baa4c71347b134b24ecaee32d247c34e3787a0c64bc5d299b55c86f64b47521d22f2c09db225b0c84cc6 8c462bf08dba59051a15aa2bd24b638b418214aed557af3d10ddb42cdca8c8ab9c47acaaf331d8e69ca153affb56c9a907c1941b6d981a5dd9935a07774ed5e3b85e86d35c857a17aab51aa3ab763673e85ebfb6fb593641eefbd6a8b7c6414d +959fe5a19d7aea2ba611c7203e19f8e3f3cc101e03a98f91adfef602c424c580d5a868659368a930f9883d699fc633bd07f6cf8de474937db0bea86fa7cd140ec2f202663813033a757b93bd72afba15be5e47a4eb93e8a666aa1c72c241ca3922547d63fa3732fec54afea7ade84302e2f044275bb67433fb6b125b7913143c 038e2571d9f22309a636586d62863ed67a70538287f3ef88b88c3c2fa1a2900d48c342b6f15c26b8e7fb4875cda4093b7de7ceda48fe1e2cc2975afe958040881de61f309931e48d 87b9e5d1ee99e33a4941ce796a1b7ff2319aeba9691899feca9fdb57641ac7afa5be2f9bca5c7c81e7ef81d968e3dc2c0412d10e94d6e282b169f026a734438997c1885663fad9831bb5900e902694d7cc41f38957ab13061a5a3b228e220a2b +97b9688d9ed5101b8cfb19e84b89cd644262ca1c7ee18944e29ddd3b4cca78e06338b270385b00a5e8b91ca5e628de3bba50e36ecc695b3ea737a9cf8b36871c473a54ba17819f49e730c0f253b0c769aefa6c16366fd2dd612f330e95fb119fcf3bf7f3e254438c0ab635ec04a8b2424a05b483ecf65b74a93636fbab7bf1d8 00c8f5736f1ae65592f3ca850f43d06441aaad8c03820f3b08d8a6db46488dcfb828459f8b3f34af73cce8dc7a5e3834e085a64523d890028e194214cef4003210e6eb530005b01a 93f032327f3126014e19833218b95845fefd36e2f63f4b403fbb66703444b6b95700804a5cd4025db54c6ca1e542523c05e1d8811b331db087877a5d189e1e707f57a5f4d323bfdbb7a7cd6be22658cfdc8c19afc621b927cd5881dc022acd4c +f08b250bf4a3980cb455338b3f4173723b3f44c97bacc9cf550149794a71426e398cb4a74bde141d8b7b4a72942f1c069676a9918e27792cb8f085ee037c78e3c468adea5123c4c64d8ca6a39f2f90140c5d2d80b669cbf0d1ccb466b18ded83a1d5f042c36188a04111c34ff769abba9aedda40a87be1e24b700225e2078056 01ee68c3994adaaa9e0d61bfcd3bc1cdf198d3fbfe28a44e5dd518867ea04b20e795eadacc48bfcf8e8216dceeaa069b756e8e99ed87b6b1d31154cc9310bc3b4555162a890b0c6c a88a4243f46f788095d5111b42ea88458dac0a5d122b8c73c41d66e9d0180661f119ce8cd0868fb0030944cc1ae544af05320e3ce40516a192e72e14fdacf1c17f4a86f9565c7de04ec91f8e6df203833bce860d4ab42ec72c7244a848663c16 +1cabd16fc29d7d919622810dc8b23c770b790b98b119eeab1b20900fa94fc2ebaf76be4f5eea91fc5276c5621c8677d4d117c4a5a782ee2ca1d5b0db997fdc8a05b6b3fbb833d7a7b81c3c615c2a662929760a96feefcf89e46b563314c9b77c86bf34438458b43b694ceba741b97dfcdacc0ed57652ae62856ce10ed2690770 03a6fbf66ebc1365ea7699c72cdac2dd85907ec59cd26e2d18713354b619ccb83b7fc0db9193aa8493c1855f1a83fd987cbbb65de17c59fbe79256aa5392f4eba045346e9ba26592 b780ce54ab9c798b5e9e2065ba199befc9c0ca95fce3b6da98d3b5ace3708ff99a9373f2051cf84c14c986c6519160d902f1c8a1761eca2cbc7ab53af06f80dffb0b4c08e28b0fbc5ec50370e22c5b06314622891f487247964a2a11ff15ac12 +7bc8bbf5ebeacf40b3c82eb6eba5d994dcc6a3f2e12ef741f90f90e176d20c21e006ecdaf14cb5beef35bff46b2c374d9ee224516679b1a9e9255cd8ad8e60ed234f8ee7e0fc53c9021488158217d4b4369cc597d6053746efa1e73340bdd73c1bd2eed57b92426fd4d278d6a86e8be0f0a66ab3dfadefca8831b2f488636251 0145748871a0b5c1cee628de04a12fd68ff2b154fda96e47afaa96389d66d22802968584f6753d36618d49ed205260f09d3f5ccc2b27a34390ce58179b9834ff92a86d66ea0a97ca b54caf0ef79b3f60c00942e737b9d4b3fb70d09ec93944b4b29f98ca1e863f3cb0dceb46f7d94df476cdf442853afc1f03f11a3b65411abe32fd8f6a5216b8769dce1f1d93e642ce0af89bbb8768b206f82573c174a8c15397d0531d317076e3 +0cd2a45392871c0c262e7e6f036946354bb41f9c2187b8c4d399231280682f3e0a09731fbfd52c76ee63b9828c2d731f4cefee0a8c46419c398205b2ff80c67d7756db300a0a8385fa287dd37d9126f75998ae1cbab5136560592118db52fbf102b7ff0a1ed45b8a91a7d99d13a0f7fd4366392264aa1248d7324901467457ca 03c71911d24ad19c20fc1d8a044d63c9bb417abc3778d7e6234c6af79b898cbfc2f2787244708d2fe203be786edbdc4c9b12b413156b7b0bab0be8af895d191d853cd58aafe1ccce 85700afda465ab6bdee9146a0b2380e8f6c2493762f3f7047b379507b8b5c60ac37031bcdc3a7d7aabc83085e894a6b119019887cdae2606d5d8be509a7ff9cbaf64f5178985415a62c72efacaace73421d66a0c78cea908882477a913b7ff18 +e97092625b09c9ae6e152e1cbee207d83361f34cb9b0e727c816a5ed851f12f91fbf88ad9d4c8f9d07350f5d828fd8574eafc768bc72a2b18aaf4d2b48fb10f7c3431137b51850154de9706487d69a40a8f4cb2c799f48c5d8f518aff752500de93cbb94ab04ae1e0c7183a32d79a27291dd07b5fb6e6a4fab76e85c3a8607e2 018bd74698bac36ef11add6b3e3fad227ecd868f370ec04569462565d2f0af2340bf793486953a7b79ab04f0ab1f0e4fd16bf6b576cce677d543e73aa8edb0e50372f24ddfbff966 aa30a5ff9b8eb769b0c21ca17ba5773fbe699d1ba3e7f1feca1be6646ac390eca8e9a8b53b0e8eb6508e837d12a8c318166b50610f5158b8398c0d7d011f5e13962da4e517320b6e8f7cd438c1aee8952473b0bee9694d0ff22ec7a508e5749e +ae6723b8df5d6ab5fcfaa22d32fdf106d211514cb1892c7c43ca6cd85c2532f85929c8a259ed251215063cf92e1502528d1e22d5cf67efa0b8ef21e8eb2f5dff881ba1433e8bcf2b6af8742ecb2bccde081e534615a305562cc22d3398f61f277d8ca785842bda85d8a40438d9bf1aceaedcfc22c85533794a69cfc320931d3f 0335699bfd058ee2e6163f55d1816bf3669acea8b73be9c4ddfe775230925e6093cff7a66813adf22222c8376faa106d85ac9f3c67929bc58d8986795b6d35d5b9fa546dceabbedc 8ae65b3beb9760a6be3ed85a3db8cdbd3bd48fd00e6f1e338c0ff91cf21637c371ee301d2aaf31afe4053e80544a7b2e0caec60b235f59efcce58e2235e3a97c2dee3c60ad703ea6b47866a997bdcd1a43bf46359185b1d1a1497607ee8953d7 +ee20c6b61886e02ed94359dff3559522ff550ca126fed4b2240ea7d999a182b7bb618c50528fcbd261d5e497a991fbac0cf4c105c0f664d6a00a9001c1ed522962fb44dd4159677ce8f1531019f86457c055c9cea6247086cdfe0442485cbbc4386ad002b4bd39a1a187752437f04569705cb7adc0c68f0fd059d946deb63f0b 02c3eaf801330b3f1b0504f2399f1d24455db29911f750c246ba0a134c3b59da8b3562911197764699a92ea1d95a2aac587e24f743df1dad3e1cf7edf955203e24a0225717f8d2df 8a7a42a798114e27c62d6364b098268af30a0bd66f613e3aa0179f48c55de3d3f56d150919394d1a4a484b083478de390022fd0ebe42c3f3dfe85210c9bd1adae56074bb2bfcbe7c7984543f3485bae37ccce382a3358146c19137529fe3029c +734a9eb8288e32f5a67cc1d88704523ca2c68b798d90e188d871d9f50d2da2063baf1ee6685c45832a1818aabc9afc0bc935e97969dc983a484f16d2bedb3c7c0b8221408be2480a5562d5d1e5d8763d1e474bf2826aa93a68c3b870e3bf34f4941cf590d88e1f5a8cd782a33992213f3f6b4b4f6dbfb3c3c8f21f5eaf4ef609 01c3ff067497e5d387f31f0ecc9c67b3c0dd6ec8c81318c492aad83c9dec6c99e4fa47447f6f7082d636c2591d0df940b947d0a4ae3778e2b7cc8fb92214638399def894ada276b8 94022f805610b6783f9fc3d36ac4ccc1e00c4512c44bf04d242f0a91661901180fb39ef822b652e6e451a49fe41587160bcff03c29785d4c3dca7b12a3bdecc8c78174debc1db89b0a4045cc165e861bc6ce6c3ca087890cf8aae02bf4ed2ee3 +68e27cc72fec8f3f1f3882c6efa08efdf21d74d13be5171da35ef2855666ad2ea6919d21dbc1cb6d296663dcbceeba2fe47a2c6507d3d4a67a61b55b0f81c93412d7e1fbe15a590e342a05f55daa55f8591171303154e615e81189a523b855829a5c96621ad118f522e397e2eea05c2603eeae6e3591215e29b2289bc384d8d4 004b4e04281b210fe78d516a5b69f878b7fa058941ee9ae8cc63b061d1eb9e12c3e0ecb8717ff4623ff5bbbcdb53c48adbd9c69636506ab929c5507d7ebafae5654aad65a263e48d a63ccc3aa4f3e70aff31c4ff538919f64f96e2c0d94542e20a709695df6e56ce5b28612c5017aac1a97f89756bc83c4f12fb0daad9d7997316029612f7bd413479196863c836f28d3e5ebe4d83104df7dc30dbb9c3da29f75a6a681551a0a167 +e67cecedf35058b80787589514a9c81c6b9f4bced4260411d2af75bc46b8b2c962dc9d260dc99ebbf8ee64950766efc0e394184bdc8e2891d66bd3300ecc880e9d6a3d0eb615322378afc3dba89938704e9a8d0c949d4bae9838805c00377e3fe5ec6a1a98ad7eaaba6b500973dac48b26b7fb2e1b9889f8c387de535d4b2363 030f2849a713aeac95fde5ce3af853e9d070ee60709eccf35a076567be2c43f0fa34420b0fc097ff577221275a3a56e759efc32183be2d76058a7d20e5dd59f00415114d73a15b8f b26eceaed52ff9f10e920574feee6de8cebc9b51f4b10b63cb39f30d1e4dcc25a952c032ead9cb4b68b3473fb0d6faaa0ec8f96ebaf9c986f592292a9220617da4d0cf33cc483dd636983d85e21ba1b7a8857924601cbd8396fa308ac567eb80 +2baa1ac3f07e34b67b6af087400f261e138b070c8475378063286c16fa73578303380236a4af2484ea01ba56c1c619f6ae4e5e6ac2594c8e5aae7e7f196f96fc5d0f507bebedd4d818e77b9120e5b4bc01c7ab6339e88b71d0886631cc7fd89659bf513faf149c61eb14d55060c8dfc7e6e4c2b4ec8edaaa6bc36eca50a6feef 02ebb73d04e6e5361e20629e3ad119b33db5163ed91fd9a8aec4b774898784b6822a08992118a8fe6013094bad0be1e9bf01b27c069e4335bff7e0abd28a10443818f6b825e9cef1 8795339bfe2240aec0807dd29474ed04af43504053f37a568e3a9ac4f0672342a22bcf14a2ef85d46d0258c684c6999508b08614ae263f102cc8989abbe82c3f49e4be116a3a28dd83d4750431946d3605014d082354b30777c53d7ee03f58ab +0e640581f573068d8ebd2899a6aaeed0bf987ee11e22b05d25e88e9a1c3451f45ee3800d976f4603c18a041febef07a01086832a6f7ecd5d498d52e796a9d90758c87c36f4a5b704a39c456aaee2d5278183d5815d619c193da9fbc427d701bab0874bded848cb4bb066f56e119b637c78aeb6eaa387c41bec6cdd4bf7b2061a 01bfab717d6f6e16d9bc6e89d2ffac7cbe0f808cc8ca2eb515af7ecce5f3b230303775710a21bd25c2cc4566bb53c78c78e3774a9f306c751cc6e149929e45eef60f56c1d2388c6d 817c30e90ea1b92933662b7f7450c94bf4052ec3380e32a240c96497ebedd53443ea3d40f61059b51568b27e6c7e04c9086f2a2798d14d2ffb4bdd9b92a22f4ff8707d5d40982006dad1f2de75876a31dafbea272e43afcdc17e5c594503e104 +51a2a560ba226d629127ce1ea7e812219ceaddd23561256331458c9f11fe73990f21d0dcd974a3773040090cfdc8e0f01692d951a0cbb60f8448a016c67abf46a9c150466ac77e656ea827b0ea7d1e77ea32071ba8314fc8a2edf69008f498bd1c18061d7d00f3340a7e2cd73e9766862378d8702e804a1870b442beb2d0aa14 000cc53bf7f1cad5e3dede4b4f4b082831604c92dd2b147869cdf1107259305b1d50359647f9f3d7d4e1e608865c65dc7c9ea46bc324dcb8423b554dc369d621743cbfb592b70eb5 925a77d5bc9d3797a4f3ffe0727c0d0d9574081477b2c521f354fd28c307788690bca09e962eed1f68594e07d0cb13a803ad85a9831264cc20c15dc48c75a8d1dc6f2eadb1b7567103d239f9527a5b6f3b1a6d31a6a368ff74d3c7b484acc421 +90eeecff0a2e37df318c441df220dfea013ef29774ee92a56b213e13a798858f31e52b6ccb7599e7314f12b48a89884b113c1ba0526a54f3e9a33c940944319e084bff320cf5f391c02c731c4c4f8b05afa273374a1705d6c85337782ba7d36b9c00767180cad6422c11c581672ff631fa4c49d41b02481568ec87ea97220400 02b009530cb9d586e35dd8951ccb686833afb7a37ec253e547e85b253ba999f0f186b6d4ba41091615fe57678e9801b4dc94fa683511da25637b2acc9fe60936be15af16234c4ee7 844bff50681fb019e06ccdfdd3d260c07b4cac83cc2c9c71bad61fc6cdb7066284b56817d1dd09c35c12392db113d0f00d1617fd92255d4e192162281229ab115480009e604f2f154f695a0e245d5ea00e565835e0192f5d5bd8b5536e6ae05d +d3740cad41e2e365d80ae81da97fdf06d8b6c278b505e34cb683fb55ddc5189da543540914c0accd405dbf0063f6222885fda4b316dad4a83fd03e8d7b7e936f87fc0a5b095defc8a4b22fa97f00b394e672d5efd3e0a230c7e44dfeebda88641143502a400ed62e2a51f9561e5d652a43d616f16699e875deb9610c77de8e1c 02cc2d0d7189cc8fb3565a039aee7633ddc00ff427cafad32fd2010b10fe249c9724d91785e7080203626038109158e3a61a3970aa3e51688aa7f5184b22f63af63f80d3540ec023 93ce44c3cca19bbb5293433af2f734f216a6b706630033ca58d8f85d2985a56267382970e28cb5e7e9a1b51a1674556b01c9d6d99c721c5ef0b1868d66632489452c3180b83de898af72935bfcbcb83603f8d1af9070aa810653216930758617 +5eb53b5f92121396c5ff30e0c92da48db4fbbdbf27297f9bc82614ab78f7fd863e34096c615a02e349d8bc7ae4b0700130704bedf32756b5ee6af10da1cd717d624fadc57a9aa6db4a6c5d6254c0e8f8c3c0d4d03c264eeeafd52cac2c1968d9d85b106167a49d0ccdbefb20bdc10a2555f8149203af52853169a02db94e5e2a 03d8936c00c131e38c6566d2464c4e207c878070bbf681695a6cd98cab2c6e80fe98cda80c66a5cf584e90a071144dda59c07b8fc7bb42464dbee5b6f739b0f2ee5fdff7e5a4e7cf 842756fefbcb7c21316dc829c594c48968ff24a8582fe15487af566dbb3c615f314049bde622276291a8a6cc94fe7f990bd51dd19227ab8c5a4ea0d4c41409a53780d18b3e853c32d28bb6d89c7144712b6d75a709d4c87378c74566bffa0670 +5aced64f702a57ed7fabd045a40c967a485d2a70b0a5e82561d5141ef329469b2da5964a34df203a980111a77adca376c643b9030aa74516f054648c1534d912ea66582adf3c655dbd71ca55e47412315df5e2893e43b2e2dfe6e4dedf426f11846ebef34a99f5615460ce0475f7bc54b4a4fd99e83c982097c3136ac6188a5c 03dc7de970bce28a943d7599f2a9010fc99435b93bc4ba884d42503ac2941aa63fd07db34bcbb1127d56d6a4e277d6ca32051ea3467e376f74f98c3999d2f276b282ef8a28cf0cbc a1a2ef3702ff963b7ef91f679fea5d55f029d9cbe75a3a5af57d5a41aafb28a5753a469bfd63529316fc9344335993280de8cb6c064ac894c2eaaef6ff991faf4f872afc13e09f0c5b97aa7a0b3795c8ebce24fc1002b535980fbf99c1ee9080 +43c24aea343d4e088bea25be69a332c631275c36677093e057de69cc83a4c5e70ab270e5a8930f55846f1a22ec10e03007dcf0942c6761e89c65c6a4f032eed97dc3a2c7f7ed1e82552fe48828a132ba16c41f6bd82a49335428a24fa1679522000e6a1d12c646e0e4b4c584398577ea9493bb334fa3cee8bfdb6c2e66f46436 02de6ee12eefa7a4a736484b19b42a513dfc059a060976edc3b0aa4b50e98d72df6506fed0499ff8480986748e938289e54a5e86c0c29733a9bcf5985aa63d8a2b57933a04a8e8e0 b7457be3bc4ffc24f1da7ff6bd0ca8ae4587328b211f5a6068b6d29d35ef11a67bc75c3f3d8be7d47d8827a7a0eabaf80049b250c6d5aee26db9505a10141127b934de6e707b97048be9fa92968c09431955e0aaff98ec212e305f043d4a41f8 +e89210565959d93b483659e62cf41f0a0147ea23890c2f1a694c377a826165e363860e4b084016cda878a43eb68465f81f397ecd50087a25215ce7c4ededa3552218071fa3acd7ae380655fc8fa884998209ffc8a2c26f1ca19dfcfee455dad35a4e72caecd8da47eb9ee21b889162f5d3032724abfd1a31e68612e18bfa9006 005468f0df2c9854f5f655743e79c750fd8812db28b096d97207bae7f5aafc6b6090c9c636ead9e0fde32a1ff8d539b53813733ca812b41b58ff85a941abe4f128d59fdf9847baa4 88d9ecb82fee404621daed0fe756e668437deb6b75f81d255811f9e3ffdfe7259326a00edb26c026423028afe46835dc1120575129f13ae3e1f6b03af61b015326f9e22ed810ee2c6d5b1f042a5f04c7831afd5f72dc9e067ae43b3f5dec4eeb +48629ec97f56273599cd9903f8a84ac2ba74275b40e1e42fa47649568babe05cf63c8417d828251acc2eec525b56dc9082b68d51b0c2bbaa7389fbee15d058cf482993b2bedc5a9101f1afdc79989a812478245d191550109fc17215679553c508c84e3d4cfdea377088d09eb214e6f92410facee4790beeecafe72b2e3ed192 03d3c6a7ab9450c94aa3b8a1ffb678e5b647af24cbfd66ee3944e6f264f406295b803767471fc67936fdfed1714b4b8761a07eec86543b7c4da6bd2fcb33fa8cda4077737f398e18 ae800c2b9f687c1e7dc563e2626131f0159546e6225f7bb0461ef1e91ccccf0b066badc8dbd3fcd3b9a455ba40ac848b13b880c894fb27b9b416919ab6ba67e9bf30c74ec8870a99af232b8bdeffa582201eb47ad120df19bd59337fa7b96633 +aa3a9fe467b1ca638dd0622c9ea235a418b39b2e15ad81fee01b6892b240783d8db3c72e16c13df8016dac6addbfb85232158325bd7432fca3b8bf5db3abd0b4c5ccd0999609dc42199ca4680692a0805cdd68108bcb493a558ab507cec0a2782a9e976928985352edb2abc0c07078b59d2fd86fda7fc76cfe573181d934c46c 001ce010ea8e6e1a0c26ab22eb90f0700dc73b232c429d36371e68e429792afb7223f10327708bcff779ea55fb5f22ad87aa054e84d10f5450f1bc9a89279062ea2173f55ab0f76c b3a961ac1ff29573f19571700fe3c58aa2a944e0aa8c74abad51059cff46fb9dfaea85fa0b1ded47e3f791207dddebe4102b5711a0cc309816e76b3f5e7d5d708d537410cf27f61b22b5e85fdcc08d72c29e057ec94385d2ca0a3b32f39dfdaf +6c3937014361799f1461f652841b5137eb0dcaf01dd293298d002f27e9a770b9e1a30367e35c04603881f0c814cf8ecfbe1619cc49cd516b1d60d27de37ed52a5e1cc300e2face4669f308ebe6747255a3d386f16778e494a7cdd10b45171b2bfcdabd91b805bf24857708c1b75e368edb2874321324f83a19154d3a1578c767 01e7410d012aeef02b3723346d24ebafd684c99087ecccaea1cf3735d52c4c81dda41812c09f1e874dc964d858ca240a19963d5dc89451f5dd6764426ae41cb23f19cbfdca0fc562 834ec544ed5f50151e7204018511ab22917becd1dfa8380ff647088460cd5abdb7c27681b43299363a4330c63bb0937d072697f4227b8bfcc8c768bc9b63a2ac206dc76e8456e03502d1cf54012f574d2f47170db59d2e8ef4134e9b2724f4bd +12fea55ffda15db902aa6a4388b9807c89c193cbf75b5d2a4c95206fa43dedc45974c80079933451bdc5b3ea015ed3ca2c54156dc61afb1bc82adefed1491302a48b9d3d2f474ab45343c611677d360515b93fb36da7a1c1b2341c9cce185c881c0beef33d43967134a190c09034ae3261f3295b79aebd3fe123616f73cf2089 02139839ce38eb879d266065dde5e5ea227244323b330e3ad5a0bc690f3c210f794cf18f0d730693887548bfbc434f48ee10ed34cb41d52172b06e448df938170a5e17311cab8e88 b2e12eaa06e3abb481b6b21f8e5c0979a5e504306fe4e752a7a38c03fb25af3aa6550ac5fdbe2c18818238c8194a87960d7e2ae174dad85b614c3426b71d64ae6d64943c027d8334673ddae40c54ce0f7ccc32a5dc77c85a0341c3735723c4b4 +c8395546842ddb545d8ea3db4efe970453dcb06025ac3b7a25aa5ef62070f3021b9a1fea91ff7055b6c398073e7886a6f71afe53c82c47b71377dfe291972503bbeb25bd477bf0e7adc8a5d3f8b34ccd0080d61e121214e1b29802b711cdd8a6bb2275a2395c467ec2c1571952992e448d736d8bd70ee629c75b5e32b8323a00 0274f70fe69e4dbb55c5d404e39f5196335047113087f8711f2f67f2be4964e4fbcb865680758df1c401cd677b0971654b7a6aeb7bee0d6d80ac0de14d4f46f356b2d5545c185aa6 b3e71622fdf6adff08187c4abf1be3a9e20006ed9e499e59ab00a52b0d5ec15915031505e4bf1b0087e85e2af869e40304fcb91119cf3effc10f5b814c46b177927010b23ea26e1f21f4e6bb37749da2407535eebb976cf74083d0c1685ae84b +10d2e00ae57176c79cdfc746c0c887abe799ee445b151b008e3d9f81eb69be40298ddf37b5c45a9b6e5ff83785d8c140cf11e6a4c3879a2845796872363da24b10f1f8d9cc48f8af20681dceb60dd62095d6d3b1779a4a805de3d74e38983b24c0748618e2f92ef7cac257ff4bd1f41113f2891eb13c47930e69ddbe91f270fb 003e1b03ffca4399d5b439fac8f87a5cb06930f00d304193d7daf83d5947d0c1e293f74aef8e56849f16147133c37a6b3d1b1883e5d61d6b871ea036c5291d9a74541f28878cb986 a538dc477bffb8e2b5756474bbf9e7c7e41436af92b772cec693f98eac29a41b5930dbbb2918d3cdad5b4e89a3a2c0380ace6574b7c1aaa32f923c74b022ce6cc5c04c21e991783502ec29122b50ca0017b4b4c8d933b5cd4e7042f3856db1c8 +b61a0849a28672cb536fcf61ea2eb389d02ff7a09aa391744cae6597bd56703c40c50ca2dee5f7ee796acfd47322f03d8dbe4d99dc8eec588b4e5467f123075b2d74b2a0b0bbfd3ac5487a905fad6d6ac1421c2e564c0cf15e1f0f10bc31c249b7b46edd2462a55f85560d99bde9d5b06b97817d1dbe0a67c701d6e6e7878272 02e09ffd8b434bb7f67d1d3ccf482164f1653c6e4ec64dec2517aa21b7a93b2b21ea1eebb54734882f29303e489f02e3b741a87287e2dcdf3858eb6d2ec668f8b5b26f442ce513a2 a32e4fde236a4865230a2b9830203df0a9a740b52c4b0e18796849c3824196a005674101652d6d43db0f519ad793cb200a26cce3160ca38ff2c29e02bfa9facdb67757a56cbb45de9ddc3dd16fdd9cc7fe222a7f2b2479ba16ce9a14550d9f72 +ba6be551bc60653192401ed8ff9e1acd9013d8811a7a1389528bf07438366f5772cd7aedad010c19c47622cec03a4d35b8003b39ed901b720629ab59de55a03c1ca50a62987f8da159e356245df58d5ae1936e65f3cd3acbe03ad1d0fcab4aaf2a7a947549ae776772201efbc6fab1aebfa1d99994d4f43dc28f39c0f279b992 02a69bc1df069c6e89722521a63675f318252be629e7558f3716917998e660ac960b0b750562846fe6c12ef492951e51e224754bab84a6eacd4147a5f26ae85ee4381bb14ec2a8c7 9912a43d8593018d188b31fd728a8c25e385af60875a23653b8d14f9e3fdf92489fecd571cde8ea1c9e0e16a644ac74c0037e1755949b378a4c492f92fac92ba1c3a19a08869673b887d576cbbbe53be1b8b96a2f2bef86c68226636fa99d581 +295720a79ac8201f40a66b06ae5d970afb15f36582897eed25cd92edcd00f70ac8e31c556eed4375ea044c2e8b227a8e02c0a3e996c9272d52ac7b3ad43b80f217295dddc84b177cf1e800ad08bf7fdd021fb2f49b54162092f8d628679c4ee335abbc90c027264c8b288c6e16eca3172eaa297ba50626b00fe0a0ad3a9dbeeb 00d11ed1b78b22b3420df4ddc4acc7c2286d9569dd6dd88e0fa3ecae69bcced68bb81bbb4ca6e9b54e67856e7fdf39155aa27aecb9cc827ccb9cdcf9ac633561b27d8eebfc261aee b92817d683bf34655a4208eb9697d1ce7c9ccb9cd7eb7bf4e7325678c0f499e8dbe9a206fe9d520b56fc0a2ebefe1a4814159fc95056f74122c07573b4c6c8872c4201ed5b210cdabd615201e9f2f82885b87a8376be1cf0801455724c9ecfe6 +a9cff41c6dfdc4a12f31dc375a5455950077ae323d0b7a3d9a8dde73b76e9d7b94ddf9c88ae8e6c262d704052ac47681fc35adfc56c904baaa6e146eb653984369d76a85596cb744941aa7b558c945ff2e81bd5ef7f00ecb4f43af23b4cea3bd4ba7b1899f1868a0c0ecfc62ccb1d588955597ffbbaf34cab2838efc2b866669 02c36ef754b5bd065e9eadde684750acc52795be80f54dd3d7a7d743d968a18f7e404bd71f8a76eb0395f396df5a7c2ff7e0ab6de35df34282fda6ee01fe5b9b68ecb4e378dbe32e b9cdf46a1c60e87d1aed66bec510777eaf0d6d78ad32f71817259bddfa0d72b3074a5038083ef1ab85ff1fce78b4592d15c9e3d418d407f1551188e365ba018d9733be23d840c37af98f99db261f5a11f47e5d24cfb0991d6a4a730b57fbb8b1 +efa6c582d7fcf5e431aa89b3b00180c0e78efd7ccb0384d90b80e59a115a13e55001d951528c42860132531c9b8ab29dda7a657c53c2ce96fd85549f6f1810e121eb89961295335eaa0e40532d85814a4206e6fffdf9bff76599da9b2e71a22ed572910b0e3bae38ad72c7042579f106739a8628dea5a745168bd918736e488a 019ffee50be5496507e3ef5c40ee88a49625e46d1dd1686a52b09ad4a8e3ee9ef364f953bfcd97c52104eecb6138067192997cd4ebadaccb73c7b2560879289a46353a756b73cc43 8d45bd74affd0113e1bf3062018beb68dc852dc1e8b505cd54371bf085e5d7602e6a8bbf93659465f5a433de1107385f05a7c586076034d2540074bae8db5a102b25c4b64295f136cc1144de04751f6f8632f4208cd94b0f4c3c9df19e67f36e +211acebfaf13bba33a9dd16722ec53baab92a140127d61372cbf1850f2fc894e942e25d780778235f880743953d04eca7a9205602e388172aec2abf35412b483490751f93b51239b6701cb0aab14e5179b0d7f55d8586358381dd83e3e436bf69a6820317d1701750cb1fea1293467ba589eec5f5779c2dbf2a9b8f28c4dc239 03129e96fd28c4198cc5242c1e3531a3979fae643d527044e98d7721aa56b5b4b45dfddfa17a4115e10a2b4f46d92f81cbdd7e86e588a4c6d8c2b3a83f54cebcee1d1dd33e85d81a 81996e12ee615dc4890344edf61216dfb68eb0b92c45de06ad6b95ccf0f38d63f7911a8774664ef2354aabe36ecee5270c74eb117e26af47faa598dca48cf168a4db7c7040d89ad70b17337082bbc2951e2310353d85723ff8becf4fedb32fd6 +ee592e20e0a45c18089c2e41460e65a7d22ed9714379f095d43a308bdd383128aaa6fb24e9d35fd28fc95c5b792ad75c980d2cdf0f460ac60b12c5919d3cb28dac4d488196be6c2dfe462b1b0ce59f8501692255840f5215c0fd8b74b1996a267a5e3b22d2841cf0a0b6315ef4ec7180f1c8494f4c07d5869c01fa2711739efc 03d723d2697cd07dd8444f992f2ab4a063db334034c25ea9be99fd7a1f495e3a644e5ea033a41264e0d24a911e55741d0cab80a0bd678eaec2bd1e60424d4491eb86d664900d907e 981217a0a37c841dc1bcd1645ba1f1d97ef0c2a1b5b084ab900a6261fd6459c822ed36a96727ad0366f2f43171958e9c1171ac2cd84bef6e3b9fb67f9ae83bb9d798b30cc353a717e32d2e9ccbb9eecab1a50c7c501393f15e98a78d85f0c065 +fffca41927debbd53455821441d9115db99fb31bfc69752a382f57bc7abe021f148346ee29e17512c64b4918ab2391d12d6e5643bee6b5682885dc28177b292e23a37ff99b359b9cf7578432af56e0ad1028a6cce7428980654c145af8daf09addbb3be11228d3c742defca9d3b1667f48c63091fe3307ecf72667b02e008f24 01999ab45d66cd1d3a0fe6aa43bf5ef1e2a67637d53674f6fbbfb9b582be91fc42a12cdcad94b50b0fc7ac55030de24a0b99fbc4314fa743ef4b5198bcc5f54d8b669fbed78e2e91 9795dafd813afa481f0b5aba79bc35a977e2e42bd4d8b2375b2cc9ffdf2fea777e3e966ce288f63b959334a4d67d471b08da8f7e72e6d90e8336d473614e7b484165d8e841c16105a00d915d11609ccbe56b5569f1d68776a0ee836fe41b66e5 +a2f71619ea04f7057e6943c2cece8594b341ec3b96c3915d924f94ba13fd7aaeed41ffa0e842ade414784f1ef825fcf2dbcf7bd8263b802def45f94de596aec0c121fc06558c7bb06b9f27a9bf56c42090b5dc344e82b69c4f528d33be166764a593483f6fda0cf56e6000ff363ba220f5ea0ea2c3191615c7ae3bb4fa575324 02ce1cae0716205330d730e6bc6dbfb6b951dc83ee3b4a7dae75d057e32e8a46e22be75b5f09135452b29c34dfe81a9be2e8dcd243fbd946a0ed14a832a7802e20cfe1abfd3d6e4b a9b59c3b8b59d49055bf10993730f6622b83d9138acf385ce4e39dd230b3d934eab28f1462976427e914fb6cb07c1a56089d37473100ba477e6801d2bd9a35d4f2679768bfe0c6edd6b768d8526922af30a3ab2a32840f89b1d639c5c6a11ed9 +b60415a831eca2cf60c79a334ef2f327a76d290846ee588d5d33d0a826bb0c7ec3e11dbb384a7f89c8d180425dfae7463e0ea6497d2eec1dde112f1c1efccb532a2e2b66a28e2d36d4252a4c3b12850d465fe21bddc441b92e6a7b0f67744f7f6e7812a0603211a26518b311a5b190ed890ad852bed4f6ed13377cab3eebedf4 02c9d0fcfcee7e75c3245ba955ae04188b1033c55ec9c821d8de7685276bda3e9a93c3ae1b003e5ea722913e7b169d67b1aa2dc8cd42adbd9368672a3f81a6817bf3e5529dcb0c8b a496a0eb162508b5a4a0685e1cada0ca7ed3414b2be5c00b51b618680bddd200aefcf8c374b53403f7f822ddf740b51c0faf1a23c6419b47d82818726d6bd7c688c54693675e5d8d09d034be01b44da4c5e62793d5e08afa3045c59d4663d52c +5d15a08226cc74cf495be681b795d0bde26b19f29aca1a8c6ef77d50271ebdcb4e5fa2df23961fe11620b1c6580183f6ebdceb2c09516c8127be576496fb71449bbbf0a9d3d1c48a25024619b97c3e0d8b165897db96ae9758d13ac28441d7cbfb75b23cb423e0002046358bb6d64779974a5995dfe54b398f95f7d64fc52d96 010c057bbaa44ef0f565edc288bfe66d4f6acd8686899359bca418ba89fb690429489a37bd3c6c9f3a8714b2ca225868c6a45fee360e378a676f7ea39321790f32a4b005b81dce43 97c279e5de8a3becb7854526a56a9e09bf8599ea4e8bcc12e5b4a8a0bc7015f5b859b78df3072f499ecb99769cec832418db8e4261e791dd0936961b3550ce7d951f0dd64ed9e20f2e32a3441d56c2f10919c8a917660d7fbf8ef6268fe04771 +9eca4bd88200baf61b901fca53dc1f1e7e3f83b94d58a6cc6a2adbc9b1a35fe3f8ec61787c76ed9a0d696167cd4fe46e1a0883fda564666131753c576a720125e0b712db1da0278067cb899bdb14eec08737e864544663abb1d62f34a2114be07e8e3cf56e2d17099299ce6b6d83b1a34e6153d7c6a32a72c7b1bf4583fcbcf7 02c182df7976ea93d996f3ba5d2221f3cb755cc7847bc3fe9e022fa4285046f5bfb426bafa3580beea206de36f87593ae561b4b74a03fcd61fbd0e8d6fd5668f2148819a88a650aa b988209bac2ec8971f135b9f05ac948e86291425a4220bdb63f41f75b5ba40b96ac53ceeff5bfc0c85c5bc285514f7260405359bf16dc6c782cec2d31221767a1d37281ac6c474bf7762d1066caab1202cefb8d5bb76fdb476dca9d5093efb5c +707450bd84141f3b61beb12ffa5ae89d812dd11badcdf6a88a2d50fc70e23f6d822ff4477047abc58cdfa28f97ad7f4911ae0773c04ebed1f51bb2308cf6e5712c4aaed461edd6987fdd1796aab70198276b601241f6a14225dce575830ff60f935fd9f567d1d210652e4710922fa793da78c8fdc30c273cb08365c9fc887f50 02d3a65bbe133cc98cf0eb56ee1362195968b4eab960a1d55d8b762f1361fc21348d6f275d4bea1de7158fb97c995e20b92a9c887a3e332d154667ad167acc632eb88a0ead6113a2 85fafb1de02f9085dc377d6d44f09683d1d9d03ca7b5c7644aaa41cff99c26e34d72c1bce6f8b98308f22f14baa8b09d096e6a49ff9208ce5bf6cd071d457e30a7a69a51e1d2e7d7cf3aa79bb2bdfe1c0e8d9f946c57c2c4a8ef7668984fb845 +d5ce9d59391cdc47ef942dd2a818d024ae3917deea8a5a4214e4db6a0c5e6b0936f3e632fdb68a3f0006e05c44b7232013e1da5f877cd197f44fd6f60c1fd2378995e9a47534948c5a09e33750f07a7165072ab38095373b07a50bc1391eb6b650ee13acd63d0352e7d9c31695ea1ec6323f9b5f57b426ace56aa7fdbf419be0 02a920e8dc928acdd56e3655b2340d4371c793e66f67405fb7a90f31e9c4ef466cc44331d1d2fe3ff7391d2576dc6640772166ef8c154a5ff1808f5dab2f03061070ec8b3f786c36 829a697554a6840d7bbba88756680efa7c7905d0937bbb052585c916830159d609022a042584272f5ff3e4b0b91b0f9115291b3ee37545e0c354ee33c0e0948e4505b6a7691fb86e2882da58ed75f8856e6efae35b915238a78caf45fd1cd223 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B571_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B571_blst new file mode 100644 index 000000000000..695558e8a3e9 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_B571_blst @@ -0,0 +1,60 @@ +8e14f713a2c427b1f79491033994f76acbead614d12e73ac6f3f518f2052a10c1273aabe628ab38e0d3d5f8ff254802e9f44a51367bf80325b6fc39d907a37f731372864747b10749ea5cb3d3a83da39c21a7b02885a8c1770e4397cedc958e4baa21d5007569dc9dd1e45d2181709d900a394454090badbd0cd9c2cd2369aad 00f42afce7f7b3d45f3f925ab29fc3882a89c9f585177887584703cf8bd8fc572e677adfa55b402446fe1e90dc855358d92c3267c35be9674b40c2ad5ce8dbe6a533c44b0ad8d2b2 858185a35c6b76fd5b6e91f159b33d02ee4c5449980a66009b5d56db93d87ccae6c1345fe27a95f8a28f2f97945c0ff01762aeda432eebb23a0c2b4ad393913780c0b27f1b06f2417334619211cd16b5bd19ff2bbb33b95fb9786c93298e9d02 +38b60d27ff08fb191811036dbfd5b39e1cc3427ff70efb67c851e9cb407f9fac6f348d289df98d055eec73299fcac068bd0fd9ffa3c5d244659e4f714a58d79f6727f323a7ee26369000e90e34e106f99f5ae2ae1b64ee89e5a1d304ef20c071a7773e9b977ed3d49f467d300a881c8371041394910f9c366942449045568f01 02f36613043cbf53ad36e2b38998bb867503359ae082d07d040e5a10a43e06ba9c91e7c73308e41e2391b65e634f83b162cbdf4e7a44ad818fb93a978af00f06be06731d8c5886c6 b54007f231196285e1402f9eb1bfec835830ddd7f6c0e9d7a8360062509fee254ec305455fec8a813913f721c7e296d711077a777ff4fc4a220933f4ad55fba6e77823d858895d0d5511439b44dbc39264957dace537d5d303254f2f221cd5b4 +21709eeaf9e1953822294a478dfacfb205fc25f447a73a76a32601c00784cbf2f9ebd41c22721d70cdb3842dcaff4a4f208d41c0816990e421cc4b8538ac2f347cdd0aa2a39f1aa26ace8cb6a606b23f6244894d4594a0f6a5b8f6a695fd66e1a41e2eb6a377017177fec56bb58c837e311cd04c5b50575faee32606b9636ec1 02e74948c46930cbcd9dbe2325539c7dfdd910f309fd610e6599d425aad9ae230a8d4681970a14f2a71fd08030d0a40ff40dade7de1b06a80441bbf7e2fcf1809cff39c7ef88bf9f 856f36ba3c776a7ab3fe8d3ef980f839f7ef7862201f55088c7a1e93d9b83558c65814c7844a8a1ad4330318bbd18f1a04c6fb3e6c0d7b991ca4a492ea9ef30b01c0d69f357f67541181c43760a7126e277a5b8444750532160927062908603a +3a131fabf3dc97334f212fce41c44300440d16de1d6060450875f7276f53c026e2a511681b5a8d75fc0d578546339542833145f7ee13c708df33e584445a75a5538829286480d339be7c777c03c998a6d3f037b25799ab2d541021502a0b02a9b9c337a8b176c4f30e5b186485a6103b1d1563ad4ae73ca806a5e4daa92e9100 01b5fab1d36f6f6d559f65d8b01edba610620fc3a38307b1fb1c5bd63e7ffbd4a9098cb8bdf50975a873f5d047ee2b627b090897a7fb5f56d3f4a0f3528179e7c969926fc0d3b0e5 b33e144064e026622170d07558aca1a9710d518945dfbdd3d76c7ed8943918cc36da72d3d25c22532bd0c2041394822c05bf4f454e77a24e5f04bee8f6fd26905dd2bb47ac38373de3f167985b3279a540f544dd9f94eef21f2bbd3e2021af19 +679d85a762f2574b0b31b516270b7d33d5e166c83e91a0f48e0f3db20b52f42f9e6ee9648cf58267ffe3b713723cf3df52b5fab5c14db1e7189f7cb7170bc6ec7cc71946745e152b39180f828688a5b6c0b2957ab94283b90052a3c6e36843c391aa8810f9253b639a8d5a69aec10070603ad7a99dcedb544858d057a1d66b89 0383e70c71b431eedd4574f65d01fb0304f7744d668408c847f7899eae44770a7f3243109740f177d7146a27748886b7b77ecf3792b512e8d8e37c3bf4ecef2b1253df7066498f01 a7b3982ecea917c3fe2bbc80dc5bc135203b89b54d4c08c61e8c8d4635ea41ab14d791b5968a2b33435036627b42a7751571c1601ec4f199892b97473ac0ab9267ae0696f90121f46dd8f914b6bab9c1da3b49f6e8a8323aff8812773ed4f8a3 +236152ad31ce2ffc0dead3c142cf6c770672cd2e75af4a82fda1a72e1c775cec9b481c6f3e411644df7e7ee901c501405620af4b6e9667dfd46091788daa95ef2c6c9f5c240c06b15cb0df51f5f058d8a7934bd7845f007a35f99fa97200b20f3b5b14fbf1e372507f3b2f377e8d07d30fd3e222f398f26d8f428e320327f901 002261d4ead21f02fab19bbb0da8c272286704c8f0c6842ba47ded121e5cddef79fb34e6b9694f725ca502949faecfb21e3cc062a2b4c654bd542d9a1fe8d97bdd0905c510aa0999 a121932578bc2d12d441dfdfe8b43f31165a34c1083bfda514f1e9d95f5025e51e9cbaeff165399e19165797d53ad048003f28caaccf56616e26c2e941c25a6c1ed6964f092e07501c2b303f2279df58dce4f7055f0d5bc0dbffc60369446691 +ba3f02c4847fae035d747db246fe4e82fb9224ff9cf568a6ae548f5dc2befb2079541d2cf9aaa6b18c281a05e7ddfcdbcefb25f41dd91cb3092b3343e16985e91c912215cd99ae4a099baf628e33a7b277e3c36a13aaef85418fca99f64d73b789f23ecbb76c3095ade0a5f7f34836a98c5be933b44a94a2eaa3f99b1d8e7937 0316c78f289e1860bb623082be9d9238b88e38c5e978a868bb90f776235bdff4eff591877b7f350cf14c40356922b2b6aa51d64990360b2b0e44d6941b5dd9492b4f4e1f42ca163a a438b5c14d7162c16006906f5262673a25d9d0bac4c7c7fea49f7b6267cef875c95d7dd0fce9cabc1fcd97e665ee1c6c0d5cce5f983378222d9918c62a377ca8bd31fb79bad1b3c07c07a1248deb2d63d080d442558fb6512efa4ebf1a8651f1 +6d0372b40559e075af56af853cbe18ba2d471b0fc8917764abcc69102b03d5bbe1fc12458215be66409c26c89f67c72a8933677a07f88993af6918acb074fa915fe883b24bc3d191ff1b08852f07eda98977e70eba072d8bf189cd545230f59559ac05f1fa3f4e65886d0bc274a6e02e2399812b2bf91abae81e21279c5de996 02c1bc13f8320d97a82f3d9354e195481902214e16a4fd89332a0499208e91d50e5cabeb4927ba030cb42f5bc53b10f500fa646a8c88508cb0d63ebfce5c4bd574c527d686c735ce a0dd6adb2e8c5d196f46be0ab1aad3ffb3ae31dd2e2a27333dc77452a24e30c092d026b9f8bee0a8de1ffd4041458b540700f7af98e440926e6374825a112059493f13b59c5504a8877d8665d8e15891a8f65a01da5e191f83f058b430aa8a79 +bbfe66c82bc060bd14fd0e40769d9b3a026eb447550dd9f118c30d8448f725f8366edef042447962ba7f7f833b9e9094d0ff600714697e632626e7d12a592e040bdcee166dcda93952323191021bd12f3b1647d0f25a41739994659dcbb19333ca30f46f539c6f0a5c354cda8969a1eda572a309950c84c7607eb8ac20163912 013bd80eafa67663e75d7ae139bf285d2b9f1e03d8e32153c73e26d06e86d7acad22bde9f121a3f1ea674dcc1fe67bc7f5398d5e92555056bc046a02b0ba86c2a0dfe32e91add5b6 a4c5c3120b89520c6add33d049a32ccc4f10a24ad2f003a9c3645f30e75997341b48482a1e5b1629cef2e828603120700ade3480725ce800901e57d81a6e00c9091a3ca414e7d9fa197546e3cd11032153d2a8bb470ed06417b90a7a6ccd69f4 +b35e9bf686717ce3b16a59963a32a2116130453b161a4e7ceb27b755856add836d779696edcaee3b5c986523891c8836109d431e55c23afbca022437ad19e6777efabb6da3bba1f5f44f905395b4cc7c9210590fd38da621582d059598e5e4569e904358e0dfc0dbfda4ce75538aa97480912852bccd433a9b96c9c66e9597d2 030834b0a4284097cdda2ada6947c6c281f7290a49b56becefea1e2788ea3ef78fb96807633c47c25138341768b241164ce0d42f7301728b928be2c047f2eb60fc2f844ab77306d2 8010aae996a421b448faff7c78ab8c27571ce5af71a8d1fb3a89d8250daed965fd9a323d058b2f2eefefe0d20b71f62417165a3c7f8a6f671bbd3e7c4b7dc318d598081a6569aac7ec4d2b300d5affbc2fa3af228be486ccf945847f54b27781 +57b5ae7e95c638b258d1e09b3fcb4341e203f5706862e199b103c8fdac72cbc5155e5cf8b300a0b3fb0ce1f897c45f7aefcc528182f73dd450cd84d5fe9eadff3f704dc2a01b4e847c22df430efd1c66b0199f3e5b59348af5386962a5ef25204fd230b54d58d7fae801c086f8f405d3d0aa7a9a9da15c22b868817cd897d853 00c81a79ced1eaaafc31b69a40d9939f4e484d625db6364a8e589b6b4d336d458b44287ea6c6aa7661113fc07806b147ff98216fa0c08708dc9d651821b922741deda522b4e436ad aa827bfa284f7e4c54443386123dc0e782ba3f602f8fbf4e60f227a182793360f7a74714b0376b80d2f129c9ec04a35916ee53172466952168abdae85e6069cac0fafac059f756a049c8981345b59b08ccf2cb1e6844a1c2ea6e4d35ac99b612 +daebfef74b452f039c999ba0528be3bd9e16deb5f46f6eae87b63db8b89952c949fd7db08311871eb2596865eed107aa065f030226ea675ee3256c31a3f85ddf4c21760582144e07af208f33c5f47cc026db5403186a65a47940691ea2d74ffb1245676260ef5717dd879d8b5b72d96f87fef5f762d4fd17454cb5ed83d8a11f 02f24670c0f77d2ca0266a743023d2c7413d56d0b5ec77b454ac59087efc4ea4d46179e10278e4ba416ffd8c3f9786ed202faf8251c0ef5a9ea5371fbb35b7afe3d15a9cb4bad975 ae6b82a0e718303da87ffc5e1816cc0cb4fe0b9b976df9e286bc8e176702e93ac6818a70640caa56f6552bf3592d6f0705e47a633dec85349872619c06c5c90be162c9cdc879e73a6ffd235725a0d8db34e149518c2582fe0372955959613768 +62af0493ae79d71b552c4647d1fb7ab2f282a91cd44aebd8ef344dfd77b521b0c0a3f72e4513c8ecc0e4b84efef3df9482a07ccc1b740c571c5e69cb913740a792aa231b9dc87edfb72bac188293c6c6e788cb3dff32e8f483f8f34e21ee7efec71302cc3bdbfa47908a135f6ef3ff179dcef26d1a3987f7be967a6c0f799b0c 020985f2c6fe3ea04bdbab66a8b6167e5969c073b9d53cf3c77cebbf73f4dbf75e601620ec9c3107bf3fbfc6c79f8f063409bf8fe1d14b19e323d857e23dc05157d270c7514137e4 8863bc4c81874b489a427665d851d259e66763eced4aa564cbc41c063f3e7b462bbc4e49b546b767fe47772d4f4434db16d3798a31d6a37085a704333b79131e49fadc2442e163c5148db834a693929a2ed886727f2a583bd469eb87e49b94d5 +566f17851951777ebea3f8285610cd8ee5f882a68e7a4205e6fc9e2d66d210ee2505ee73d6503169f7b903012d43e7e99efa493a8e6ef926b16b9ad8f52156840ab561fc6b680120a88714fd66d1d0742189bf06c155e1138ee5314707173f7352e2cea0fc26e1553643f2490428718e44afd8372cbb7bf5b88234318ebf4355 02b3d641607b8a141f876f6d285ee46aea543880e772dadd5dd83d595b9643191d9597218e1d6adb081df133304037bcd2c05c24a54e6c4cca64fb2cc4569d6882315360059496d8 ada86e2552d041fab19e7486063bfa64094ed57f94958317d0b90e482fc91a7c3d8701d1b7b009cb72fe9ea0c98affbb01b6706db4287000d13501779ef0e98ec2fec4893b09c7e3955fb4a5bcf53e3d13d4a2cc77f099e9d2dbf991ce8b118f +25155825fc4f9a1c4dd1db837008e7e2594a879052431f5bfc76d0d2565b8fa726008befaeddceef73f3c60fa2cdf6d9a70e56d27210bd013034b38861ae49640ef208d3fe294ac4362f8eea44f58af3af8a9167a36b5acafb7ec95652d5885a0e08067ce1dfbb45a0c89ad1acb53eb404bf88fa5c3c463a0f912b5a2522a0d9 01afeb5ca87c81025ddf09c2b2c5ee22ba0105c0e619b67a324467485bd839030d149fee44d8bac6f5902a1245a50c3437046b7c89a84116b2147cddc645b6d2fd24d68e8d53bf5b a760a5c9f042c27d501038fc17f9134b61988e1be86b2fcb193173f839466177da7cb89f996a262ac0d766e477b7bb210f595ed18b21ecc9912b271ed5c91ce6593b8b38b91673160aa475884c8b04e725ba9657e927e8f91742fcce6690f8e4 +29acb0fca27e2a10d7b9e7e84a79af73e420abdb0f80dd2665696638951b52dd39ca028166b47a3b6a2eaeceb1a11c152383f0bec64e862db1c249672b3770909f775b794e0b9b28a5ec8635a996d912d837a5f22471b40ec2e84701a8804127a9f1a0b3c96ff654700bad3167240c2518fb5dedcc1be9f56a807083e587bc56 032c97639b69c7cdbf419286d0a1b406d9b1f2886521a8b979a36118d2a368aace5b02dd8c515f2041e6fb9f026d1e82e789dc826a56d2ef732b1bb0f49be2b696ab5d3d5694a2de a9573be9efd8dd16342e9564a5ce60c509f492991c9aeac268681b33ee86e0ff6a903a6a8adf4a67b28400fb38bdb4be1872d863f4a975bad0d13ad978bcac81ccefe759215706b0a04ca3a3e11df168c2015528598cd4b398c6c75382fc9fdb +c92d67cf6536f5046e15b02158da698bcbba4ff1e4e9e9c882cda67f817210402ef917ae93682c9c3dd817b21b73c6c00b7bf92ea80ecbbef2e67f4f4379d078a2b0f297742b2bb9c3fa3297a7e8079f488555bd37715eec92b4b1cbf897640ae8a1d2a0fbcee5423ab31a37629f98630275e35094a896cc574be0a449bb1bc3 00f93672159276c5a293582b9f49607bbdb970112f6c63b2b3b5d32ad3c8240c86b1af13a8dff6502c6b6a17712cfd988f8cd23a60693d64104143b3f91adb37f852e9e11a0ef110 9618982bf1380dc6e7bd752901120a8e0bbee196926972556de93e2d604f1ecfe70a9c602f8d3e61d4c8adaca3a5ce640d9e4866efea25277ea3e99f01fc3046719ebca358cbae136f7b8ce7963a09a91eadcac539eb6bc9dab544cd3dfd9ddc +15413f614c4551e3b138b64f66d15f8964c40326a42b0afce820778eee4a88edb127fbf575da5263e5a2627b5461d311813ea868e6417615e7c4938313675009caac28bc7a2f4c0bc37572d9bf36a3b1794294e09c0121ceecaa4b916df45b0dd31225415e6c87cfeeb092a008fce2c543cd62365779ae28f29fa02a15d9dcd5 03db080bc99c5fe7e06d5032167af56783cb423fae59fb5b3c6bce5fbedf56b7b39b17810e48ea9a172881aa1f42f5e267349b60294d4a208b4437666b44abcfee5a1829e9467908 82c7a6ab258fa00e085f0fa12f2f8d0d28395e6f7604221b6a0529cfc7394753bec82f8858a1ee28f8f44ad8c99cffd30e4be6274cf0d57c2a133632d49396d0afd23c8bf898a3b1fd962866e9698f7f86f6c9506a6b2c29da8affea2bfae1d9 +9f901557451ae2f8ec79b6d4adc794cbfd9b2e6d28f19409532d91682820205308b41498a4e1ca247a2baa8da93de95e3c0f7afd6ca46bafdbdcc6d3374a12684676a50988b86a960a82180648c8c1e38f8fd9af604c7be3be4b24799f4544ac96d6360cdb83d1d0847fda21642934fd6cf65385b50d86d4656987901fb88d0c 006ee767f6f36bb8f364f324d8346455c899a49237d759003dd52cfa13b9baa4c71347b134b24ecaee32d247c34e3787a0c64bc5d299b55c86f64b47521d22f2c09db225b0c84cc6 82371dd26fc0047275a4c003f515101160e867078fb5b51d25b4bb8fe3582b595e1d057061ab8f9391e6722875047d08047a4550bcbf58667ecbb61c5b411f6aafda728d7759142427003e5f32f420661d2941aadc851cc4b50d45841a31dc18 +959fe5a19d7aea2ba611c7203e19f8e3f3cc101e03a98f91adfef602c424c580d5a868659368a930f9883d699fc633bd07f6cf8de474937db0bea86fa7cd140ec2f202663813033a757b93bd72afba15be5e47a4eb93e8a666aa1c72c241ca3922547d63fa3732fec54afea7ade84302e2f044275bb67433fb6b125b7913143c 038e2571d9f22309a636586d62863ed67a70538287f3ef88b88c3c2fa1a2900d48c342b6f15c26b8e7fb4875cda4093b7de7ceda48fe1e2cc2975afe958040881de61f309931e48d 8f824c1d7d396a68c5647f4c3550273b691960c0403d054ab90e0ed9e2823638d5b3a71c5feee6abfb683aaa30c2b87505efc8ad33d2cf62de57dac7887ffe0582564325537cd422d90df033e0f21db9da095434cfdbbabf978b759fed6643cb +97b9688d9ed5101b8cfb19e84b89cd644262ca1c7ee18944e29ddd3b4cca78e06338b270385b00a5e8b91ca5e628de3bba50e36ecc695b3ea737a9cf8b36871c473a54ba17819f49e730c0f253b0c769aefa6c16366fd2dd612f330e95fb119fcf3bf7f3e254438c0ab635ec04a8b2424a05b483ecf65b74a93636fbab7bf1d8 00c8f5736f1ae65592f3ca850f43d06441aaad8c03820f3b08d8a6db46488dcfb828459f8b3f34af73cce8dc7a5e3834e085a64523d890028e194214cef4003210e6eb530005b01a a328a15ab23eefeeab4f21db127a70014be5aed16879bb0c057a5281574997763308019b02be9813636dcc1f8db0c5de050edf67eaf068f19e1958d52a6b5e8fd5c423b376ebcc9bfcb5a044b0dbfd67412d7c964df934c44d2b885490b58073 +f08b250bf4a3980cb455338b3f4173723b3f44c97bacc9cf550149794a71426e398cb4a74bde141d8b7b4a72942f1c069676a9918e27792cb8f085ee037c78e3c468adea5123c4c64d8ca6a39f2f90140c5d2d80b669cbf0d1ccb466b18ded83a1d5f042c36188a04111c34ff769abba9aedda40a87be1e24b700225e2078056 01ee68c3994adaaa9e0d61bfcd3bc1cdf198d3fbfe28a44e5dd518867ea04b20e795eadacc48bfcf8e8216dceeaa069b756e8e99ed87b6b1d31154cc9310bc3b4555162a890b0c6c 907c5c0c8e366a9b3bcf81534dbe32419e056ef7fd8581119e4e0c13d53b938be0cb37487c0848b8c22f2e67d60db04314e51087fbef4432dbe47c1239c13bf9cbc32b43c82c64b6d52cdc345e2b9de97a939a633e01c77a907757f3cdf62eb0 +1cabd16fc29d7d919622810dc8b23c770b790b98b119eeab1b20900fa94fc2ebaf76be4f5eea91fc5276c5621c8677d4d117c4a5a782ee2ca1d5b0db997fdc8a05b6b3fbb833d7a7b81c3c615c2a662929760a96feefcf89e46b563314c9b77c86bf34438458b43b694ceba741b97dfcdacc0ed57652ae62856ce10ed2690770 03a6fbf66ebc1365ea7699c72cdac2dd85907ec59cd26e2d18713354b619ccb83b7fc0db9193aa8493c1855f1a83fd987cbbb65de17c59fbe79256aa5392f4eba045346e9ba26592 adb05ae19f71e97d822318d7e22fecfe4f5c010d3d9aebe0bbfa4263ab712866e7740b2c1264a6a809884304ac4a51e50fccfc5c4e355189eecc6b3c76c0b94eb17f24ce1a923b5aa86445a0edc9f12e29f2b36c7e1f272144d0a4500dd8fad6 +7bc8bbf5ebeacf40b3c82eb6eba5d994dcc6a3f2e12ef741f90f90e176d20c21e006ecdaf14cb5beef35bff46b2c374d9ee224516679b1a9e9255cd8ad8e60ed234f8ee7e0fc53c9021488158217d4b4369cc597d6053746efa1e73340bdd73c1bd2eed57b92426fd4d278d6a86e8be0f0a66ab3dfadefca8831b2f488636251 0145748871a0b5c1cee628de04a12fd68ff2b154fda96e47afaa96389d66d22802968584f6753d36618d49ed205260f09d3f5ccc2b27a34390ce58179b9834ff92a86d66ea0a97ca 96ae2c24a54a10f87232046123b42b9f0f9c7483f844da53def17d35050c8aef81b6dd726f3a8fbce8394beebd05296905301d0b7c8b0f605828f18b02cde38211407dec1cf2e92ced55c7898f00329a4bf366360eba20057042fb04c8f2460c +0cd2a45392871c0c262e7e6f036946354bb41f9c2187b8c4d399231280682f3e0a09731fbfd52c76ee63b9828c2d731f4cefee0a8c46419c398205b2ff80c67d7756db300a0a8385fa287dd37d9126f75998ae1cbab5136560592118db52fbf102b7ff0a1ed45b8a91a7d99d13a0f7fd4366392264aa1248d7324901467457ca 03c71911d24ad19c20fc1d8a044d63c9bb417abc3778d7e6234c6af79b898cbfc2f2787244708d2fe203be786edbdc4c9b12b413156b7b0bab0be8af895d191d853cd58aafe1ccce b3482008a4962c106cfae277870842c151f68f11c643fc720e615510bab190317071263e29b193062732d68fc43d48380a2663a529439e4cf87a5cea08998194b0c6b05f05989469f1ae420f0ba3ff0268b848eb8aa201b6340ffe062e75f2e8 +e97092625b09c9ae6e152e1cbee207d83361f34cb9b0e727c816a5ed851f12f91fbf88ad9d4c8f9d07350f5d828fd8574eafc768bc72a2b18aaf4d2b48fb10f7c3431137b51850154de9706487d69a40a8f4cb2c799f48c5d8f518aff752500de93cbb94ab04ae1e0c7183a32d79a27291dd07b5fb6e6a4fab76e85c3a8607e2 018bd74698bac36ef11add6b3e3fad227ecd868f370ec04569462565d2f0af2340bf793486953a7b79ab04f0ab1f0e4fd16bf6b576cce677d543e73aa8edb0e50372f24ddfbff966 b497edf181e41eea2f2810c2f0a2cfe834c17049c887330cb7eeff027dd35235cea171332e6a6335d95c9dada8c40e9f10f74c6e99e2378e228b4715e68004e371661c35d961bf6b9ad4e3b7215286ffa51a7b8444398da2a1684ef2b6541493 +ae6723b8df5d6ab5fcfaa22d32fdf106d211514cb1892c7c43ca6cd85c2532f85929c8a259ed251215063cf92e1502528d1e22d5cf67efa0b8ef21e8eb2f5dff881ba1433e8bcf2b6af8742ecb2bccde081e534615a305562cc22d3398f61f277d8ca785842bda85d8a40438d9bf1aceaedcfc22c85533794a69cfc320931d3f 0335699bfd058ee2e6163f55d1816bf3669acea8b73be9c4ddfe775230925e6093cff7a66813adf22222c8376faa106d85ac9f3c67929bc58d8986795b6d35d5b9fa546dceabbedc af33ec118bcdd5e523bde924062a582f1b519bc3d524b7851cdcf6938e2ab4085c066af6105a397bc4dc71f5f8d34cb4106c3f2147fc4044f84268339032c7ad578d008b6663e0265fee25549fc134a7aff4e67bffecb6d1f5558f3ef711d2d8 +ee20c6b61886e02ed94359dff3559522ff550ca126fed4b2240ea7d999a182b7bb618c50528fcbd261d5e497a991fbac0cf4c105c0f664d6a00a9001c1ed522962fb44dd4159677ce8f1531019f86457c055c9cea6247086cdfe0442485cbbc4386ad002b4bd39a1a187752437f04569705cb7adc0c68f0fd059d946deb63f0b 02c3eaf801330b3f1b0504f2399f1d24455db29911f750c246ba0a134c3b59da8b3562911197764699a92ea1d95a2aac587e24f743df1dad3e1cf7edf955203e24a0225717f8d2df 8b2eb167aaba9bf200774592051088678f18257e12c9ac2d5ce3bf4ee814c536a078b430097b0d68e3f2265d5abe902301b42cfb5484f54daf5255b2aca1d5af1119ca6658b5b917db8a5676dcd0cb8161cd256040cec75b8ce076ea1b4c377a +734a9eb8288e32f5a67cc1d88704523ca2c68b798d90e188d871d9f50d2da2063baf1ee6685c45832a1818aabc9afc0bc935e97969dc983a484f16d2bedb3c7c0b8221408be2480a5562d5d1e5d8763d1e474bf2826aa93a68c3b870e3bf34f4941cf590d88e1f5a8cd782a33992213f3f6b4b4f6dbfb3c3c8f21f5eaf4ef609 01c3ff067497e5d387f31f0ecc9c67b3c0dd6ec8c81318c492aad83c9dec6c99e4fa47447f6f7082d636c2591d0df940b947d0a4ae3778e2b7cc8fb92214638399def894ada276b8 9655957b8853ed1a1ff5549935e4505c1508225fb5b391023888b38c515835f0f6c1e730479cca209b834c55c8244af6167063bd7d83602eec7394cd32d9847996dc1683f2047bb7d0f6a6d51563d61c81092948f5c147fe888b34f88c6e2ba7 +68e27cc72fec8f3f1f3882c6efa08efdf21d74d13be5171da35ef2855666ad2ea6919d21dbc1cb6d296663dcbceeba2fe47a2c6507d3d4a67a61b55b0f81c93412d7e1fbe15a590e342a05f55daa55f8591171303154e615e81189a523b855829a5c96621ad118f522e397e2eea05c2603eeae6e3591215e29b2289bc384d8d4 004b4e04281b210fe78d516a5b69f878b7fa058941ee9ae8cc63b061d1eb9e12c3e0ecb8717ff4623ff5bbbcdb53c48adbd9c69636506ab929c5507d7ebafae5654aad65a263e48d b710077aaeae70eba50b26dca68f5d56f26b8f827353df1be96fd0ed9f16a21a0f8eb2391dce3931612a79f36fbf4983064bb27e99a1dc8ab1a1a06aa46066c0e8dea0ecc2a46229bf967d8c3fc64c548dd38f60d3e88da3c944f34fd48f3afe +e67cecedf35058b80787589514a9c81c6b9f4bced4260411d2af75bc46b8b2c962dc9d260dc99ebbf8ee64950766efc0e394184bdc8e2891d66bd3300ecc880e9d6a3d0eb615322378afc3dba89938704e9a8d0c949d4bae9838805c00377e3fe5ec6a1a98ad7eaaba6b500973dac48b26b7fb2e1b9889f8c387de535d4b2363 030f2849a713aeac95fde5ce3af853e9d070ee60709eccf35a076567be2c43f0fa34420b0fc097ff577221275a3a56e759efc32183be2d76058a7d20e5dd59f00415114d73a15b8f b7700506646b1ee2fee34cb7ae5ab73cb30e3f146c8792844a997d8d3444601bc4cb1342e6b4a466813c83f5cf3b8ee407a227447b33214c58f480e0d60a8a0530433e79f6ec621ee6efc23df9fbb2c6305bae898dd3d3451f12df16786f73d9 +2baa1ac3f07e34b67b6af087400f261e138b070c8475378063286c16fa73578303380236a4af2484ea01ba56c1c619f6ae4e5e6ac2594c8e5aae7e7f196f96fc5d0f507bebedd4d818e77b9120e5b4bc01c7ab6339e88b71d0886631cc7fd89659bf513faf149c61eb14d55060c8dfc7e6e4c2b4ec8edaaa6bc36eca50a6feef 02ebb73d04e6e5361e20629e3ad119b33db5163ed91fd9a8aec4b774898784b6822a08992118a8fe6013094bad0be1e9bf01b27c069e4335bff7e0abd28a10443818f6b825e9cef1 99f87683a2c41a74136b221b01bef7e953dcf9d2677ff4437f870a90a01c53fcc15ae5b167226174e47b33942dc1f8d10c3404399f401d26c6e83a6bc73f1802b5874d843dcb9da86e69b6c5415939ff899e8cd7d976e5f368c6fd36c64a1bdc +0e640581f573068d8ebd2899a6aaeed0bf987ee11e22b05d25e88e9a1c3451f45ee3800d976f4603c18a041febef07a01086832a6f7ecd5d498d52e796a9d90758c87c36f4a5b704a39c456aaee2d5278183d5815d619c193da9fbc427d701bab0874bded848cb4bb066f56e119b637c78aeb6eaa387c41bec6cdd4bf7b2061a 01bfab717d6f6e16d9bc6e89d2ffac7cbe0f808cc8ca2eb515af7ecce5f3b230303775710a21bd25c2cc4566bb53c78c78e3774a9f306c751cc6e149929e45eef60f56c1d2388c6d 8e0ae825cf7812501940a840e3a2200411e74aa1782fe4d0b940f3adad86bb97396c90dca117f9e7eb1d89a79fc600c80d1c13f7136702504e6be4f4434ad60c4cd2c06dddad39b6ab90a990d6794dc5a266c7515bcdd2365171c7606dcddd0d +51a2a560ba226d629127ce1ea7e812219ceaddd23561256331458c9f11fe73990f21d0dcd974a3773040090cfdc8e0f01692d951a0cbb60f8448a016c67abf46a9c150466ac77e656ea827b0ea7d1e77ea32071ba8314fc8a2edf69008f498bd1c18061d7d00f3340a7e2cd73e9766862378d8702e804a1870b442beb2d0aa14 000cc53bf7f1cad5e3dede4b4f4b082831604c92dd2b147869cdf1107259305b1d50359647f9f3d7d4e1e608865c65dc7c9ea46bc324dcb8423b554dc369d621743cbfb592b70eb5 b8556402e6e826a32ac4eee5efdf469f2ba2c5a97e4d92c6b6ff412d7ffdcc6b3d2e6c1f0f6e607e2756ee6e42a9e3220baff5ce6030ca1f270eb53238a7dd95439aee6a882476d003a3b8bfc3a9bd68bf87710386d02715bac297ec5b5842d8 +90eeecff0a2e37df318c441df220dfea013ef29774ee92a56b213e13a798858f31e52b6ccb7599e7314f12b48a89884b113c1ba0526a54f3e9a33c940944319e084bff320cf5f391c02c731c4c4f8b05afa273374a1705d6c85337782ba7d36b9c00767180cad6422c11c581672ff631fa4c49d41b02481568ec87ea97220400 02b009530cb9d586e35dd8951ccb686833afb7a37ec253e547e85b253ba999f0f186b6d4ba41091615fe57678e9801b4dc94fa683511da25637b2acc9fe60936be15af16234c4ee7 8a54af2aa2e82466544a10951f02cfd90690d4560e63153f1ecb7123b34281aa9f456a56f9e986bb2dcd1458b47d17500dabbba93e95f876bca85b36b48948cba5993653e4d3cb13dcd5ad857cc0e6138797cfc230b7e706f1f094d76c13a688 +d3740cad41e2e365d80ae81da97fdf06d8b6c278b505e34cb683fb55ddc5189da543540914c0accd405dbf0063f6222885fda4b316dad4a83fd03e8d7b7e936f87fc0a5b095defc8a4b22fa97f00b394e672d5efd3e0a230c7e44dfeebda88641143502a400ed62e2a51f9561e5d652a43d616f16699e875deb9610c77de8e1c 02cc2d0d7189cc8fb3565a039aee7633ddc00ff427cafad32fd2010b10fe249c9724d91785e7080203626038109158e3a61a3970aa3e51688aa7f5184b22f63af63f80d3540ec023 afd0368bf56f80e46e46d3dd8e577bd617d940e8513810e0b87e71cf4deb5d2d5d956840d1337edd4ade9ff69a4d8b2414c2c00f6f1324cc10993f8287c41dc31c3cde211b3c19d839d57ac88f890457a5cd0909cb9c85ef700039d69e47ebf9 +5eb53b5f92121396c5ff30e0c92da48db4fbbdbf27297f9bc82614ab78f7fd863e34096c615a02e349d8bc7ae4b0700130704bedf32756b5ee6af10da1cd717d624fadc57a9aa6db4a6c5d6254c0e8f8c3c0d4d03c264eeeafd52cac2c1968d9d85b106167a49d0ccdbefb20bdc10a2555f8149203af52853169a02db94e5e2a 03d8936c00c131e38c6566d2464c4e207c878070bbf681695a6cd98cab2c6e80fe98cda80c66a5cf584e90a071144dda59c07b8fc7bb42464dbee5b6f739b0f2ee5fdff7e5a4e7cf a6a8280df997925011e8ee8f6fff8fcb24b52151b06d664a304b9c504ef2510d00a7f756e14d1f85d377f129f2e65b4f05fbceabd84c6bf7c9c5c2bb36e13a50c08a670b2c07dc81f32f2b69547488e15dc8f6b5d656fb7bb124d70b0066170e +5aced64f702a57ed7fabd045a40c967a485d2a70b0a5e82561d5141ef329469b2da5964a34df203a980111a77adca376c643b9030aa74516f054648c1534d912ea66582adf3c655dbd71ca55e47412315df5e2893e43b2e2dfe6e4dedf426f11846ebef34a99f5615460ce0475f7bc54b4a4fd99e83c982097c3136ac6188a5c 03dc7de970bce28a943d7599f2a9010fc99435b93bc4ba884d42503ac2941aa63fd07db34bcbb1127d56d6a4e277d6ca32051ea3467e376f74f98c3999d2f276b282ef8a28cf0cbc 898ab3c69f38fcc45b52a52c9e00368a51e7d15848c290e59fbba15dbbda2b8eff98b401630134a3df3068fbd971c7ab1729a58d0b81604c235b5f2dc001d2a501f08796f5f83fc901d216ffccacb2f14c359f6726f26a1c1dab39a1568d7ede +43c24aea343d4e088bea25be69a332c631275c36677093e057de69cc83a4c5e70ab270e5a8930f55846f1a22ec10e03007dcf0942c6761e89c65c6a4f032eed97dc3a2c7f7ed1e82552fe48828a132ba16c41f6bd82a49335428a24fa1679522000e6a1d12c646e0e4b4c584398577ea9493bb334fa3cee8bfdb6c2e66f46436 02de6ee12eefa7a4a736484b19b42a513dfc059a060976edc3b0aa4b50e98d72df6506fed0499ff8480986748e938289e54a5e86c0c29733a9bcf5985aa63d8a2b57933a04a8e8e0 82ccc54291ed22464507f7e5bd35f4d7c5613a619eea1d44aaa1d74c6868f1133e57387482daf8ffa01e0279a78b8eb315ea8305461f540ff51e1a8a2a2c68abe68ef91c970b157abd31e2c6bb708edb424329137c5af454f177a00a4aedbe2a +e89210565959d93b483659e62cf41f0a0147ea23890c2f1a694c377a826165e363860e4b084016cda878a43eb68465f81f397ecd50087a25215ce7c4ededa3552218071fa3acd7ae380655fc8fa884998209ffc8a2c26f1ca19dfcfee455dad35a4e72caecd8da47eb9ee21b889162f5d3032724abfd1a31e68612e18bfa9006 005468f0df2c9854f5f655743e79c750fd8812db28b096d97207bae7f5aafc6b6090c9c636ead9e0fde32a1ff8d539b53813733ca812b41b58ff85a941abe4f128d59fdf9847baa4 82cddc4548a6350291c8f2d4192923b04483bdd3905818cf1c48a151fb9d94e29322ea102f7312e6881b5035148686d410953317a84a0a41648f698401dc3a2c51cf457f0c83511cc988ecc5e40727ff6ad9b5da95ae4c497dcd586edcaadab1 +48629ec97f56273599cd9903f8a84ac2ba74275b40e1e42fa47649568babe05cf63c8417d828251acc2eec525b56dc9082b68d51b0c2bbaa7389fbee15d058cf482993b2bedc5a9101f1afdc79989a812478245d191550109fc17215679553c508c84e3d4cfdea377088d09eb214e6f92410facee4790beeecafe72b2e3ed192 03d3c6a7ab9450c94aa3b8a1ffb678e5b647af24cbfd66ee3944e6f264f406295b803767471fc67936fdfed1714b4b8761a07eec86543b7c4da6bd2fcb33fa8cda4077737f398e18 b0dd80fafc2401549b9bcd207c57f8d4529b5ab332f1ed1113ad2574916ed7b4b5dda875b6b5bd4c2c48dcaf6eebade017bf05e2172b95fc339ceee64dbcfa02863ac1d6d632c7da331ef609b9ec750f71af1ec392f6587604bac9d279b44032 +aa3a9fe467b1ca638dd0622c9ea235a418b39b2e15ad81fee01b6892b240783d8db3c72e16c13df8016dac6addbfb85232158325bd7432fca3b8bf5db3abd0b4c5ccd0999609dc42199ca4680692a0805cdd68108bcb493a558ab507cec0a2782a9e976928985352edb2abc0c07078b59d2fd86fda7fc76cfe573181d934c46c 001ce010ea8e6e1a0c26ab22eb90f0700dc73b232c429d36371e68e429792afb7223f10327708bcff779ea55fb5f22ad87aa054e84d10f5450f1bc9a89279062ea2173f55ab0f76c 94bcb0655af8ecfa61b5d1cc608efc0fa9b018d4b09ddbf463d3efc7e9668812a27918bf56d0ba8bf0921d46ebacd2a0070a85f125c4d27d67b86c5be959568282ce52b140e9277f2155aa73c73377e179015d0d5753231491a15af3bafa1358 +6c3937014361799f1461f652841b5137eb0dcaf01dd293298d002f27e9a770b9e1a30367e35c04603881f0c814cf8ecfbe1619cc49cd516b1d60d27de37ed52a5e1cc300e2face4669f308ebe6747255a3d386f16778e494a7cdd10b45171b2bfcdabd91b805bf24857708c1b75e368edb2874321324f83a19154d3a1578c767 01e7410d012aeef02b3723346d24ebafd684c99087ecccaea1cf3735d52c4c81dda41812c09f1e874dc964d858ca240a19963d5dc89451f5dd6764426ae41cb23f19cbfdca0fc562 a3b056febbb960acaafdf2cd1f6cbf4ac0d743a6ad37ac207338738b913b1fc89459cb04f46cfa154b2b8a1f194cf7e91487ef3dabc2fd122975aecc33dbc4949dd92499f4387a369a33b314453709caa0361b88877428ab6f209c0f52f5f9d9 +12fea55ffda15db902aa6a4388b9807c89c193cbf75b5d2a4c95206fa43dedc45974c80079933451bdc5b3ea015ed3ca2c54156dc61afb1bc82adefed1491302a48b9d3d2f474ab45343c611677d360515b93fb36da7a1c1b2341c9cce185c881c0beef33d43967134a190c09034ae3261f3295b79aebd3fe123616f73cf2089 02139839ce38eb879d266065dde5e5ea227244323b330e3ad5a0bc690f3c210f794cf18f0d730693887548bfbc434f48ee10ed34cb41d52172b06e448df938170a5e17311cab8e88 a8b466c89aedf9705d05c3465329b5f082dfa6503f1ccb29fe627b4e2c09c3064a6159622fe4d4684a242414fba49b66185027c4218e09d07bb5316bad224379728631ea7e636a573a1dff88d58bb52dad3a37ce277ce28c91e0823561156cea +c8395546842ddb545d8ea3db4efe970453dcb06025ac3b7a25aa5ef62070f3021b9a1fea91ff7055b6c398073e7886a6f71afe53c82c47b71377dfe291972503bbeb25bd477bf0e7adc8a5d3f8b34ccd0080d61e121214e1b29802b711cdd8a6bb2275a2395c467ec2c1571952992e448d736d8bd70ee629c75b5e32b8323a00 0274f70fe69e4dbb55c5d404e39f5196335047113087f8711f2f67f2be4964e4fbcb865680758df1c401cd677b0971654b7a6aeb7bee0d6d80ac0de14d4f46f356b2d5545c185aa6 94fdfca0cc42d208c3160a3a1a2c06377b4d5d3b897134b392b5e8862745bea9d2561127a317177ac4cd345dfb11ad0a059212d8078cf42c80fa40b227e992b0b3021e5d66fb77470e709ea7e41a16b215fb8c285a95986c922f5747bdda4220 +10d2e00ae57176c79cdfc746c0c887abe799ee445b151b008e3d9f81eb69be40298ddf37b5c45a9b6e5ff83785d8c140cf11e6a4c3879a2845796872363da24b10f1f8d9cc48f8af20681dceb60dd62095d6d3b1779a4a805de3d74e38983b24c0748618e2f92ef7cac257ff4bd1f41113f2891eb13c47930e69ddbe91f270fb 003e1b03ffca4399d5b439fac8f87a5cb06930f00d304193d7daf83d5947d0c1e293f74aef8e56849f16147133c37a6b3d1b1883e5d61d6b871ea036c5291d9a74541f28878cb986 a85d2fe120787a7e80a32c26863d92ea5f0a963184116f36b5b63951e22654fa3e0c090791e8e4eb866db3d03a2e5954149118b9819c20b42db8383553802455b5d7ca857c00c2bc553ae3877864e7797bddaae5265ac0d209862ed36e288a1e +b61a0849a28672cb536fcf61ea2eb389d02ff7a09aa391744cae6597bd56703c40c50ca2dee5f7ee796acfd47322f03d8dbe4d99dc8eec588b4e5467f123075b2d74b2a0b0bbfd3ac5487a905fad6d6ac1421c2e564c0cf15e1f0f10bc31c249b7b46edd2462a55f85560d99bde9d5b06b97817d1dbe0a67c701d6e6e7878272 02e09ffd8b434bb7f67d1d3ccf482164f1653c6e4ec64dec2517aa21b7a93b2b21ea1eebb54734882f29303e489f02e3b741a87287e2dcdf3858eb6d2ec668f8b5b26f442ce513a2 b4e31f5592bb956b3367451521bdfee56a60fefcd9b9d22c98e83467facca5ca92f2c26cd80b7a8a6266eb2d2d17d9ae161de59a2763d04eeaf0f719548b41a49ababd675638af98866b360f21d6d4b1b03ca4bdd8e1f24b19184264cdbc3cba +ba6be551bc60653192401ed8ff9e1acd9013d8811a7a1389528bf07438366f5772cd7aedad010c19c47622cec03a4d35b8003b39ed901b720629ab59de55a03c1ca50a62987f8da159e356245df58d5ae1936e65f3cd3acbe03ad1d0fcab4aaf2a7a947549ae776772201efbc6fab1aebfa1d99994d4f43dc28f39c0f279b992 02a69bc1df069c6e89722521a63675f318252be629e7558f3716917998e660ac960b0b750562846fe6c12ef492951e51e224754bab84a6eacd4147a5f26ae85ee4381bb14ec2a8c7 b83e16eebd99c049b4506fd918ec34a3a66948deb3fedf94dd5a7d611a228673b9ae975341d50eaac0af84a1cf9820990c54f57eb9ac06c118c5bc745a07a6d4bbfb4261e7923648bfa055bf708c9af659420179717945ff1c9f4277711f85a8 +295720a79ac8201f40a66b06ae5d970afb15f36582897eed25cd92edcd00f70ac8e31c556eed4375ea044c2e8b227a8e02c0a3e996c9272d52ac7b3ad43b80f217295dddc84b177cf1e800ad08bf7fdd021fb2f49b54162092f8d628679c4ee335abbc90c027264c8b288c6e16eca3172eaa297ba50626b00fe0a0ad3a9dbeeb 00d11ed1b78b22b3420df4ddc4acc7c2286d9569dd6dd88e0fa3ecae69bcced68bb81bbb4ca6e9b54e67856e7fdf39155aa27aecb9cc827ccb9cdcf9ac633561b27d8eebfc261aee 94ed72711ba44da9fdd228954f91f561cd9e162511666fd52ab0928fca731b05794499a93418e13756b52d8c297eb17b066411b4dea650a621359c07a644442c33ff6481d0ca1740d9f01ed8e12da7d3dd087850cb81e6ae3ec5c40bffcf9eec +a9cff41c6dfdc4a12f31dc375a5455950077ae323d0b7a3d9a8dde73b76e9d7b94ddf9c88ae8e6c262d704052ac47681fc35adfc56c904baaa6e146eb653984369d76a85596cb744941aa7b558c945ff2e81bd5ef7f00ecb4f43af23b4cea3bd4ba7b1899f1868a0c0ecfc62ccb1d588955597ffbbaf34cab2838efc2b866669 02c36ef754b5bd065e9eadde684750acc52795be80f54dd3d7a7d743d968a18f7e404bd71f8a76eb0395f396df5a7c2ff7e0ab6de35df34282fda6ee01fe5b9b68ecb4e378dbe32e 96eba5d07d535d1e2d7144ae5bfeaaac64155cb9508c3883f1dee255ff0b9877c756c9e61091a9c59f589b63ed0f110d098e2366a0a30879e33af6c629e0e2f79c7b2c340c03949ba33c6350279034d960e71e36883627e736263e04280adbd5 +efa6c582d7fcf5e431aa89b3b00180c0e78efd7ccb0384d90b80e59a115a13e55001d951528c42860132531c9b8ab29dda7a657c53c2ce96fd85549f6f1810e121eb89961295335eaa0e40532d85814a4206e6fffdf9bff76599da9b2e71a22ed572910b0e3bae38ad72c7042579f106739a8628dea5a745168bd918736e488a 019ffee50be5496507e3ef5c40ee88a49625e46d1dd1686a52b09ad4a8e3ee9ef364f953bfcd97c52104eecb6138067192997cd4ebadaccb73c7b2560879289a46353a756b73cc43 ac842b8e7d0ad632451369a3e8e52c12d8b2baad45f3e621c27f08b68de086d6d4f2e804509c33069723bd4867d4056c0d51fe0b60af753a4e55c54f697d2b9d45d1b7433ff2852ca540f41ebb041db1c1e3b76a3bc500792673550f0a9484e4 +211acebfaf13bba33a9dd16722ec53baab92a140127d61372cbf1850f2fc894e942e25d780778235f880743953d04eca7a9205602e388172aec2abf35412b483490751f93b51239b6701cb0aab14e5179b0d7f55d8586358381dd83e3e436bf69a6820317d1701750cb1fea1293467ba589eec5f5779c2dbf2a9b8f28c4dc239 03129e96fd28c4198cc5242c1e3531a3979fae643d527044e98d7721aa56b5b4b45dfddfa17a4115e10a2b4f46d92f81cbdd7e86e588a4c6d8c2b3a83f54cebcee1d1dd33e85d81a 822f00cc5d3ef08e54ce1bbc4581ba8ec688bc2381d5053a30deaf11c348b024fbdf63f04ae3c8bc78c178566dca4b610c437f2fb6a6e73071ba96b7e9fa6723735378880ef6e04212c2ce11fb196454d04e8b41b12b0686821472287870fb27 +ee592e20e0a45c18089c2e41460e65a7d22ed9714379f095d43a308bdd383128aaa6fb24e9d35fd28fc95c5b792ad75c980d2cdf0f460ac60b12c5919d3cb28dac4d488196be6c2dfe462b1b0ce59f8501692255840f5215c0fd8b74b1996a267a5e3b22d2841cf0a0b6315ef4ec7180f1c8494f4c07d5869c01fa2711739efc 03d723d2697cd07dd8444f992f2ab4a063db334034c25ea9be99fd7a1f495e3a644e5ea033a41264e0d24a911e55741d0cab80a0bd678eaec2bd1e60424d4491eb86d664900d907e 8a10d7b80445432ed7924da0c8252b08c8e779f28606f2a683b1881316865b8ce2f1d83e1cc2b3efef5f06923df9c74713abad7fa0c02947de37fcd19496bef86c2f98ccae16a4e5f984282fbc5211754e7dd23eecc53237daa26b7fb885c3b1 +fffca41927debbd53455821441d9115db99fb31bfc69752a382f57bc7abe021f148346ee29e17512c64b4918ab2391d12d6e5643bee6b5682885dc28177b292e23a37ff99b359b9cf7578432af56e0ad1028a6cce7428980654c145af8daf09addbb3be11228d3c742defca9d3b1667f48c63091fe3307ecf72667b02e008f24 01999ab45d66cd1d3a0fe6aa43bf5ef1e2a67637d53674f6fbbfb9b582be91fc42a12cdcad94b50b0fc7ac55030de24a0b99fbc4314fa743ef4b5198bcc5f54d8b669fbed78e2e91 ad76c783739251fdab5cc74e7427762d218966484bed622cc2b3f33d3b8c9d98d2845d347c5fc2d5697d2fa32ad844200ac0d59c8b38b5a8edf99bada655fdaaef8105c6efc63537a637897dfe63cfce21f503e55640821667906a0b0298ec4a +a2f71619ea04f7057e6943c2cece8594b341ec3b96c3915d924f94ba13fd7aaeed41ffa0e842ade414784f1ef825fcf2dbcf7bd8263b802def45f94de596aec0c121fc06558c7bb06b9f27a9bf56c42090b5dc344e82b69c4f528d33be166764a593483f6fda0cf56e6000ff363ba220f5ea0ea2c3191615c7ae3bb4fa575324 02ce1cae0716205330d730e6bc6dbfb6b951dc83ee3b4a7dae75d057e32e8a46e22be75b5f09135452b29c34dfe81a9be2e8dcd243fbd946a0ed14a832a7802e20cfe1abfd3d6e4b b33b00b7678e0a99d69163b2dbb293068bed9f4f3f652157a45444613c8aba35e44605d005dacf61247fa6bfc772a84a0da38c3300ba1f4e48dd105a95c0ae8c7d7c27165597692e5c43921c7245f7301f1ac0a93747cc62b3d5eb381728e964 +b60415a831eca2cf60c79a334ef2f327a76d290846ee588d5d33d0a826bb0c7ec3e11dbb384a7f89c8d180425dfae7463e0ea6497d2eec1dde112f1c1efccb532a2e2b66a28e2d36d4252a4c3b12850d465fe21bddc441b92e6a7b0f67744f7f6e7812a0603211a26518b311a5b190ed890ad852bed4f6ed13377cab3eebedf4 02c9d0fcfcee7e75c3245ba955ae04188b1033c55ec9c821d8de7685276bda3e9a93c3ae1b003e5ea722913e7b169d67b1aa2dc8cd42adbd9368672a3f81a6817bf3e5529dcb0c8b a081a761b72d3a83ee85881528204f6fde7342ba7e59225e0d285b51a98f72b25a131bce2c7824bc3ef401828e03903011287d67f2838e98e98c17ea3719e9130fe51662a7b3a7f13317a92bf8896e8a40b74df64e7fffb13759e13c764882fd +5d15a08226cc74cf495be681b795d0bde26b19f29aca1a8c6ef77d50271ebdcb4e5fa2df23961fe11620b1c6580183f6ebdceb2c09516c8127be576496fb71449bbbf0a9d3d1c48a25024619b97c3e0d8b165897db96ae9758d13ac28441d7cbfb75b23cb423e0002046358bb6d64779974a5995dfe54b398f95f7d64fc52d96 010c057bbaa44ef0f565edc288bfe66d4f6acd8686899359bca418ba89fb690429489a37bd3c6c9f3a8714b2ca225868c6a45fee360e378a676f7ea39321790f32a4b005b81dce43 9861d2e0827e62e60aaf9bc6b05b896612aa1fe585411cce96891692b14af8ed7bc65645b2d81150509e62697db604330df1af753a82548cc3a92bb985a83b987d74912efcfec0a0f8c7582893413ca9701cac08867d60ae98fc0c04e26c885b +9eca4bd88200baf61b901fca53dc1f1e7e3f83b94d58a6cc6a2adbc9b1a35fe3f8ec61787c76ed9a0d696167cd4fe46e1a0883fda564666131753c576a720125e0b712db1da0278067cb899bdb14eec08737e864544663abb1d62f34a2114be07e8e3cf56e2d17099299ce6b6d83b1a34e6153d7c6a32a72c7b1bf4583fcbcf7 02c182df7976ea93d996f3ba5d2221f3cb755cc7847bc3fe9e022fa4285046f5bfb426bafa3580beea206de36f87593ae561b4b74a03fcd61fbd0e8d6fd5668f2148819a88a650aa 89b4357297b4d438bd12869e408ef8bbcfa7d40cc29e2bee18af8f1c2d123f16911f2fe0ab3ac925d5ce1e23d4904f9c098bcf2c8e91939db6a6031dce5b9db36f416de599208660f3054e1ed8b33211f368b9010096e14461b5e34d1a69dfde +707450bd84141f3b61beb12ffa5ae89d812dd11badcdf6a88a2d50fc70e23f6d822ff4477047abc58cdfa28f97ad7f4911ae0773c04ebed1f51bb2308cf6e5712c4aaed461edd6987fdd1796aab70198276b601241f6a14225dce575830ff60f935fd9f567d1d210652e4710922fa793da78c8fdc30c273cb08365c9fc887f50 02d3a65bbe133cc98cf0eb56ee1362195968b4eab960a1d55d8b762f1361fc21348d6f275d4bea1de7158fb97c995e20b92a9c887a3e332d154667ad167acc632eb88a0ead6113a2 b13fa3b45004b77eb6bbb80ca712bbed5133a930dbfa2de5efc681775f0e387e33b5ee430fb8c71763b8b9ae7fc163c7111c85e395dbeb96413d02eaa046b46441740fb75cd0212b0d960e72ee89ca2dd86852c4f2833f303b3db7b2f2bb899b +d5ce9d59391cdc47ef942dd2a818d024ae3917deea8a5a4214e4db6a0c5e6b0936f3e632fdb68a3f0006e05c44b7232013e1da5f877cd197f44fd6f60c1fd2378995e9a47534948c5a09e33750f07a7165072ab38095373b07a50bc1391eb6b650ee13acd63d0352e7d9c31695ea1ec6323f9b5f57b426ace56aa7fdbf419be0 02a920e8dc928acdd56e3655b2340d4371c793e66f67405fb7a90f31e9c4ef466cc44331d1d2fe3ff7391d2576dc6640772166ef8c154a5ff1808f5dab2f03061070ec8b3f786c36 b7bb75432d8866aaa68245cfef7995477d9f538f6d88d22e7d1697b36164d0b6c9b74a0570658d4fa857db6e6749cb540b371bafc27a039417f7ea5d15580190dfb9c995cf61165bccd27d54469952ba4ee835684aedfc72dedd0305d684d3ff diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K233 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K233 new file mode 100644 index 000000000000..8f4d2525a535 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K233 @@ -0,0 +1,60 @@ +f23f784fe136c9fc0d169503d361e9c6148b0f1fbdcae0a97fae1af7033ddef25cb7489c9963cfcb009a8cbfe44a8510a64a073eb1deae4c324ceb9302008c92c69b2dafcc9077fd3cc3c7c119edc3ced36d176ceaa55ac036bf7f07f6fa215e8bb8196e59a5e1c9af4f98b90ab4970885bd7015fa26a09e03c7cf6b4b23d929 004c1d414696cc3657dd9df73ace56eda2636769ce7082e064c260be45a5 8dff5a5a9809aa1187d9febc7ec3b8fe8cebf7ad69727a7b0d645fcbc0e7effca6db847b0fca823d25884c8712ee64f800ef4fc3a5d1c6217e9632ffe4c9a74d00d7e651699a31052e1afdd588cfb718acee0ec6bec959f20de0fd361acee909 +400bcb297552bb37f2f8135a9314a35f5126788bb6fa4dc74152731ff64c5dab4b902103d85443dec20e16b1d6629930cdc2bd183d4099f0e96295a63c2fe266f5e9d050c401a8681b4a438efe53cbd8f2f43e2a31e9f88926a9c82917d873f6e8cd5ff5eb8c1ca36126b0bfc8c2b0e85a7c9e7a45f1875ca9c82019ebedb729 0027cb1d84865a16992476c9e353283d5d6a40c349a8e9179d1b1f403531 80dd9b3c95b5c665bfa8061f0db031f492c5f20cd950969682b491ad07744c5c9652010c60e1f59c3163fb3a5d28451b11406464f7dd04a93e1112c6f7c5c9de1986e3441c7ac7c070f96e9bed1f26b0448c53b2824388dbdb1535f3cff0c83c +5f74d4b35c49fa454c97c05fdb6b9f6822cf1a2295f15bd766dbcb413d77c910bd8f4147e8f317fac2300fa21cb80134d1b6f8ae8e50518c1f648a28506e419f5a6e8f05abffdb3dd2587606c7e9c223ecff4f46b121216730ea13202b59128a7616bb2fd23a7e4a5aa08641cc07b669641313febfc88d64d99447353dae3f06 0031b443f46c4b5224237fac1022ee1570173f664aba0c84dbaa4246bdc1 a83e89825a4106b075876d5c12b3d72827e8d40b1876f4de239a44bd23e841782b8bb404f31f7185d3bcc77c1456561006166ac17b53de864ece00b50a47e4e7a8ee416728c023503383608d304eec9d17fa2dfe0ca33daf8d3c853f025f847b +8f92096876d9f81bcd992369d42d0b5877ac969004d17c8627c58d8b8b7bbf7a37e8cb6afa962b9b043bbbaa5bef4a5ee38d8bd31cb5866b828265a2f4102a616f87009cd346fcb8af5519fb577c60d8792472232f33dc615655e53d2b715b15a2697b492f108b7906e1e3597c6911f8cc30c7121ae338a6b747ec368f8e4a36 0048f6ca29f35f253a4962734357c995920967b9eeff1ba5fd2080bfede5 b17b6c16c719a2e6028762e0565f57c0a4a71a8df89c32aa3da0b9fd6bfb4cbb1098cf287b4bcc64419de29dbe37f7da115b76ed42ccf544b0c66c55553209fae0d6f319213b28d0180e99edfc6f1c9c60bfff39c99d2124ebba7acdcbe939b6 +3d275dbde44494c45fc15fe89e2ae32aa26426a17e923e895c7941a5582fb95df4d49873ab1bde358017f336b911b886b626b744806ab8113418473c441f1964159ded1b12122d53ac56573167588e4b55f36b8bca8c67823883a51fb6e7f204d1c6b07ea49b577bfab9ca6b8d51f72268b022e3a4db6f9d265ee8382f9b7b66 0019b940eabbe682f961d9f3d90432e347fef3910e641656825d775705b1 a1c9488fcb8f0947277a6ce5ca99b17a7b2fa08a7a9e8586148b99018d48ef2696db8a0c5011cf7dce5e22b598e3ea2e03cb79982802068057359bab556ffdbfb5ba1f8e7eb1ab9f318cde218cc19389b2e265f95f2fb22505dbeeb5456fdc9b +d2fa68e1f7dad02916b12fa38f1849d6d409dbad0344438520b4dd9b77d62d39ac9ae3cdeab03ccbcfd4de703c6e798873671731c108f322b9f2a68145e3e210c9b15b879798e5c53c5022742e9819b99edabb2f44d89ae221f7a99dc84421a6905695ff91928db608f861745f17584d56e34b75c47281435b1b0b34e490692d 007a884b22e29fa9fe945e9ba13c0df8d786dc87cef0f77f069e182dd56c 8122fc7204008118a6948751e416aa563158726500aa670b0ba375aa25e292a8def688ebb8957717fe0420eb7669892f02af116a378782289fc088aef31a22df8b71cb169473c919b23d31098c7c2a4903fce5d9fbc4b55b6fc310bf95f793b7 +3830f75cf9df4eb2998c7c1b5fe11c1476bcf849c3a8fa7d3d0b5bc2292e5d07465ab8cc9381c575d909e509c5dac49c78817c04e4bef18bd51bb09aa5897f21634633a5ce6d20bb4638cb6c3927351eaec7b62cf4a33956916045c392f325adafb10a88a5f86d7e41dd77908fa7284210071c22aa40ef40da6339c02da05392 005da61f881d5a0dc085bb93764f584352882923cd237d878220ec624c1a 8751721f095b444ade14510cb98ce60cdd121a8288c9ae7fe76c96d9ddb173ee782cf69522ba5b8ec9ff089be497165f13d1a226a20469160e919440f6d5af195f294eabf56b39e7186d5874500827077c173e06bcdf03ab3c3904dbeb7bbab2 +65b9fe15e6c35d453caa6bad39ee78a720a04b60d8a0a0f049186d2f777e48ae2d657e174df53edb7beb9f7d8f21904ed674add0cda5b62a7308de76c324a144021e8c6d387daaba4ce48bf7dfe9c8aeee2c64e434ece1fa5ddcafcf3e5d0013a1eeec1742a00d384cc2ec0d7eda83bb4dccfb0e57045ebfc27a4f404d03da37 003fe9f04647f6d82b13ec1ae5a8c2e49bc66b05649ad778eb16149ad83a 8c3cb17f752141d37fde988c0bebb422c9c329b13ff4a37d8cd1c0687e8660624516b90f7d0bfe2678714749e67fd2520cfd02e5f49add07207aafc8a4baac9e1201791df3e565461b3c62a8f8f33d5b8247bfad1b65df20e142fa81680c3790 +d26521fd41eb5d46ece6836e188bf9cb1b461d011c41e002a935d256654d01725378e845920ec4a7fd3f379df54772493df50d312c7c6aa4e909e7b83f2442c3a5e85c37d68aa015098ecfb0a5e077370f4576f4bc63bf37e1dee06d780a3b6949af5e21c2a0960fcd20821ef5f17bebf5fd5b3bdda260842cbbfad45667287a 005ebce648ace4cd555413de6a456fc487d14bf4b0b9a72311ef480d2f26 a747ec594a427c44ca8dd6437d23ef56d78dab6e308d80fa59cc9f24cf7062e1139523befff58cb72edc9925f77be8cb19340714616959bf06b26a760064c924c4b4b2adcb2e1ab2a417603b5517f390118b65cea9878753949436dacf3236d4 +b778c021b1a92c41dbd09963da07018075d73e54d62df5c2b7bf8abe137151650d1c1c6abce7eebd8f32e8c3e6d1433773f257bb3ba4a4fb6a02c0db1e47d03c27d3a90898ebd1927c21df24c4c5443ca5b81f8ef2cc0f5e8b3d08f472bf07085df737adaedec63d99acd77b87ba98225f198b791124ac2d9b191cb9251b4b00 0056653c2f85593f789a926ba49fa3da9d7f946d8f1020508c5a527ce813 83d92c9ff2389ef1282c88914dd875b4924c682fc1c4d807dbe2a8f32926599e2404ee1ac253076b8cca4b3445af71eb08bd8d762f03b6e35ba1c5db74527b4290733a806b0fe769f4646cff7195e0131b9cd6a8bd84bd0fc798a32d0a2a39b7 +ec14e07f615960015a489ef999e308b42a4c571473b9bd64b433dabd9a1b1ad02e33eee9100064405175928a94543a80f440040afa2965b4e5f95f768e7fab6d3c0a5f5e1bf1df7822f78384e80f2955ea85f044ac60537d895747979f935bb0cd3673193c4a32dd7803e48d7daf70a71bc2aa97236615b6411e28fc9a652145 0049a91d320783cc70a5952c32036cfc75d41f1aa84127db2dc759fb291c 81b547a1b308e3ac796c1503a9878cc1e0c7d81db03eab8495770837e1395a76d60035fdf636dfdb033cb72fff1ee7621609d8dfb4ba9b88d7bf697cddc4e697fdbacf43fd2581853a4434a53f48e7259cf43108bf960751624ee920cd67ca83 +89c645339ad0eb850e4e2fe583cee175b35feb02ed7541d7e9aace24cdd3939584f73ad39526de6399c86b36de77a018e2c70b532bd0f032f9137d10480acc30c49f9baaa86f9df0033b77e98b485bf7a69cb5c281e527d3ccd1fce2415f0dda4a268ce68a0a34b16afda54ed922cd6810ac8dc766df2a3a6c5e55972e9786fc 0016a20016602fc7088a60469843e1d29ad67e3c3cb9500b1e2a00d4050a 84efa55bfce692e5e0e1f63fb435d8c4e7bd680aa6005ea774d002abb3fe7de389b97f6416ac7d5968306dac5faf5e3409ce69cf29e971d79ed517bf92e3dd4a8cee755c75872ae958b08ae8f51ad62b122627c6bc446f9102305164adbe67e4 +ace14c4b101d2d8453c2bc22b756af016b5de537df9c3e639d208ad04ae0bf6232dc90b90c33228dc85de956db771ffde05fb4d0b15e4f218ed2771d703ae5bf981252a5bcd60c16f14483131a481cbe04dc0adb1fb8aa32cb48bb5008e8a8e5c7b7465be2fd7afbc811cf5ea6293b1a464669b49f55f57b93a8707e6042fda6 000ba922149bada2551b7be1c3df076f3f97ce93c13c50c285fef3f42363 b5c1dfa05ca887375f49e1bf1b2790b1df5d7608124837ac705baa0ebade6f016c38c681c319b558eb00dad3a77ea8bc172d76b688fd0e4afc0f35b5dc8e24fc0fcec16da64f7297d16b8117df1c29edf9148c991231f6974d409a898948eb39 +cec2ba0d1772c87e87d5bbbd67220692bea4301aa1a66e8dbdd7e651d45c26dc2a0d45cfc32c34d76ae3e1c61db7b0fe1863457b93937d929e6ece7462ebd16adfd708353d6f7c27aafe06593c76da7149b0cc574a4290b0d8fe219f3eada7082aca38dba3f78ed0d5942d095fa5556fc8bcef331ff0a6d5d1f4e6c51d4ff5af 002d635e12a58cc6dea44e71e87c37f91e8d08659f0b7955d24f65ab55ba 8e25791f684df90ac158e73c3f04ac6808e1b80e80071354ac451f058ef3404363d7dc426018e1976d243e71a2013b9b0e6922cbd35a98bc547d3820dac7bc9f3627ff4fded3200c770c3ce9f381c886910a44999232d799253586e37ded647f +ffa13cd0f51ae2643d5d4edecb493ddd653e9faddcffc370e7e958abf726a5d67a2ab36cef42ea8ebe22a6f01b9c31f6ffad01e6894487d979acb5e618f765ac0ec3550ac5dbbcede8f9fdbe52fbaba5c087ff382b6d7a09b2b5084227d324d98ff98793040884799b96d2ca593201f4414f18c43b51c53c5e5059e0641aca02 00073883e5064e06814fc4de32e15f7a6cf825d2daf6eb1df8c83e25d80a 891cc9e93eab7d6897b007c3442f06226ce0d0ecb0b24888df7ad0c28aaf1ffd3769c38b1d2efc17864c10aca966be3503402a27bc885911c19ebcfeedb8a7e03e5a738a7e2a51728ad80acba1e7bb12e2d279aa73cc8bbb763e7201559444eb +c73e3dbac9513d0361dabe94071faf03a11cba18c06d131a172d5f0125b01a5eeb6055bf72c7106fe3f4be3bd2b1771cbe7f85366dccfbc3bac20538510c3f51179cc540ddafb2f3b05a0d276899674ab1d7d8fb4f6838f04e4f9e26b8c6af31540f63f4953c85840af4c57dfa78c704f637dfc8dd750fe45e2c1e149986d127 001532271bfae8d4dfe60f69b88d3006d58e28aacfa701861cde8d624db6 b6be4d26bb54fa85f80b7600469fa3f8f4b3a33eca21d945879fa45734d5ce6fa74bffa0a8a22c7d846d1e91c30d7d101467a8404c3337d081b1419064c74ad722899cbb586e56f6951be7cbb50f954c6fd80fc60d65e207bf25b5110fb5ed15 +d00dcd0f3212a3167403abed91c20e76f5e7a7678a4fd970f944d11e6a8cd149d0aa6fd3164c5a74c0f55193a4fa3d8ba6f99cabed10544625a7bd92b3e0b46edbd4a269bbc10518c5268c3910a2aea567ccd32d4c7a0cbef09ea42c20b636d1f711d220e23dacdb9d1146e0494401349749e5ed88e38295232a7effbae3aed6 00550406c0db882c6aee6cf3b6baf377375208c3e90cc44a067cee43efcf b6cf4041cecd25a76d7a7ed02acea1e69b7e5922277234ca1dd3d2ecc881dedd01b55742701e6c5f8fc9eb38ed52522c167be92607b8ca90ba6c8111f3a94f23cd05b11d9c89e0d2c91e640eeba44f4e6ae86e0d97fcf87c9aca07a13cd61a5a +3d36221f87157ca4db84884b8666660c4e2b6af330480c516cded9f3bfe132543626a39bb6aed1964eb5c33ea0b95b9841665417679fceb95d199d55accfce35dd3f2283c1a7ced57d0c4b9ebe3da6e1ff2f979b6440db27caf9f6a4bbfa47e20d29ae304f4d0551fce9cc4097eb2fbedb9b24680bb17d207bdccdbe799d5b0d 00257dc63752920b6854d6c2d1cca68589a38418c3d036e73760a12214ab b4de1710cd0d69eaee41d0deeec3f13d7eec4410ed64703f051c07535ab2fa79905564e6a5414d3024f1dcfd95dc9c9d0cd98e3f18b27289a469584cea97b13fc02cc252fc0b8110b8b758c061d739ca6773f6a7253d90039ba19b35d0a3f6a2 +033d82a42d0eddf58fbe3e91ddff7190e3f9fc2b1e2eede977d2c0473b358b5fce1f981ca6f88fd61ce2f79e453e3a2b77d1baab2b970ed28d5dcff58873a620e195085e61c4b8480d829525a1a944e8a4b63352f0291f0311f1f98ceb262804beec1c74947618f8e3b067866255878c2502966cefcdda4f5fa2b13d92ce7840 0029025352297a7be850f8852411c09259b83219135e0e8949c1bd5b94c1 a5f854267d8cfc0137c71764ae0b60a929b150d85fccaf688ec32e84c18d7d126b271203b0d48c60cd436bb395c7b3e119e128419bd67dfe32452a15ff857a5ff680aec836e19435cccd842b497acfcf29cd68f2abb12540040417c6e212bf65 +671a7c81b64b2919722d7b258bdbd90165bb757b53106e0af03d0eef27452942f40cf52bc95cc7f6567df2613cce795f8bcfc723b2735efc35375c001d37c58480d89343697146b524835df3dbd333f7c06c98e36d3c4592ecd1f34ab57c341bb0f4c785f5b8372775f74b4bce60763fad1788e77ea158d735a64861320b36c6 002dc82d0e69e498528925c0e62a13fda9af8cefd047c10c3ffc2e41da3e a856fdcb32ae2effd338657bd3df8cefcbd2defb1e223c753fb23dcaa21dd3f4a5472d4f186346cfed8cd3ee49faf9f00fed3c91c00168b7f211c14283837187e2bc82b67d7a5898a86b5c9cb49d6e43b3233684fd4a06d056114bfbd60c961e +0ef677f4799298f4aab73b7393598041f56e902ced1726af49657b6601a06186212e3ee8cd4bd33b760dfa2ea3c38884f94358d51dd479f2ccc8b0b352fa4e44fcfdcfbb24919d04e6ee1108527b8e8d60e8d1b467c30c18c5455e5835d483161d3fc26b4a67d6df9e3ddd9331247cb18450188752a1ca219f3396a872cb13d8 0041535fff5d279bcd744b04e643458ce20b81df8a9e01b1181d52bb14e4 801f5c4e21224de5f8991cbbcf27553ecd279f8e80990072ac6484a026a1c64de38ff42ac2e15a57425b9b1b0f5579d71533275bf74d433d77b74bc5e9da9d8b4bca1c6db03907ec5d626bb54ca7ba9d8f004357f6085dc70c930fd459af482c +9290df0cc50c3cab6655f3a6de1f4cf613d9bc06ea7c99f38038369ff2fadefa57a3c7ae7940c1b98bb1d03503cc271f7a891bf38eec93c31dcec7892dfd2e1ab337bedde3e5325ed8d9cb7fa3096f6fafc3beb3a66cba66ba826d1032debfb4908cc9dded8c0099c85072daac4373fbc428fcaa9a6da02181ebc33f0cf926fb 0000ecfe580a624df66c25e87e7689fc3b471d205970ff9ab51a64aa12ed 94d4c7a5f86d58b69da43e070eeefc3a6e51f580ba390de8ea84e8425ab54e261cec03027c2ebd62a8ee6a27435cce730cbdcac6d0fffb55255fe9527c5d33910d7c2390873697a28ff8fe0c9a302393761ef55da1377de3a156345d9f7ea5b5 +855c7be75fda372f062709827f333630acf28954a62a5193ff675f0dfeb63f32bca418f7cbdb346bf388d62315b19a592267ca407120db93d4e3d7125b867c4c4670b7a57a76f61734cead2caf2425eb9ff0a63293e8cd6defc9648257b401463f4533a2425e0024f1ea93365eeee3c6da20d25928602ec8b426f9b39f97f3fe 0013c72c73358ffa168423149ecdd897f0a5f75a641de008649f00134944 b3b644d74fd188534c6767e029520af2bdcaa2f22c5815614d30f5962bbbb989588faf7ba358c31ec3aa860b222218f21832c382612a7b0c58778a06cfdc6a90b1656d46bea8b05ca60b173827528f2057090834323796bdf5ca49a9a9b01672 +9c896f800281812ed57d31623d563377a5c725cec84313472b90e73f77d400f5d4fb236255741b73d46f7e5254d04099bec274db8a9af5fc7cc220d42cc172cbd3c3595c49ff74bfaab7b5e46c90855b611f74753ccdbbabf92e011d52e9ba753b83ed2a251a632e1bd5c6d346e38e743950c8ce0f394a837028575fa44bcc26 000ac60e2e70b7c4cda64071c7738f68773c94df9456a8ec3bbb468fa7f8 93206a4a68f59d7752fcef0367fd91223d5959f439ba45281359f181209dc9779c718420c261b9b4e7f9d450d38e5a600ecf5b7a48b69597f3f5fff5e7d68c968876188fcabaf84022a791430356ecb39417f0c70725e4c2dd7c303d0ad2dc67 +139a14ead998d1a962fa47c47ef2953aa136bd912fe940709b8c560bc2a0c4bf8f3aab30a8e21b7d5f487d30b0097e3da723f11b5cb4e8c5724f5a2fe0d68ee4bacbb85e5eacf18094d2a8ec4506cf8497836a4a905059a998ea750adc54c27c69cbd0b0c1f9743a62f3d988f3fa0a9865a73fc071f526623085a2ef12838888 0060bf720052e8b9508a801340c213cf53bbecf4975faee63d4b44fc647a b53fbea97d4601d556d2f4db166cd9b1cc1f7b63924cb9f2d4de53465b7cf6278cf1a79da99980df30474b0e63b117081297356bdaea90db53ecc5ad21ae202b66e52313ffe1cf58b57691973f35cde0b426aefab5f4693388f966b4b902af33 +cf4a8e754b23d0fffc1c5c80b0cb11deeaba3064b315bc2cee96db5b9881baf90d30af4b69066f757b3020706def77a5fc1632d96bafba22a9c8cd3b52d535d941b3c7cc02b7fe6b51639d5e2084478ab3a29d2f5e0e16639fc2833a47b58e2c3fb5b2ea1830fe2ff68e571a8f281617a23d9a28db1c64ddfb1083d055030e5a 007cf3c216592febd8630a478b5b3e3a605084020322adb13ac0a626bc7b a8b78638bbb49c5a57f09c6f48da91bfb56e55e6b188020334963979660b3bf9ace2435d4ae4b31ff4b6917997fa88c304c083aad5a406e73696da3a2d0dff7710c230fbbedbf622789f75491e531182ed0393fc3a1ea49444df805a6d9d7eca +ae64030d4af9b36c8d3a6af0aff34e5ab201df04274691fb420b7d5c40c401ed7f3ade96065d34f2490d17943e27156e7bed83cd7222d0d5a73d167855fbe7ff6c3ed87f20986ad8bbbd80fed5f9705c6c783b423f641d40ff1f367f9648af5a79ea3cea0236997558bd9dcb011ea4dc64d61ea1e1f85b4f696ed586bc7705be 0061eda5999e5a9ed4485d2a0ac5510549b76ca37df858ea5d95aeed571b abe83495dcace734e89adae0f0313b174b6c5144c7730d8052e7bf064fbaccb9fb5c3475abaafb07936331f85ac913f20916e813967fcd1916cf8b9c2b8847fa8fb76f166699d9759d366d570a9fcfbf342a774704e8959e6434b25dea66b2a0 +94a9d9cd9efa3e4ccf2a37f904dd9cab5624ec9393cf8816ea591c5e70cccd2f105388ae133708fb974998ae61d218c71785f9eb808d1c28d953cc7eed00dd9854b6b4568c5ed5ee3df3b58a1e04c64f1c87fee4365ec9aa41b08a6bae234dc43a0bf2f61420acdb891a40f17f246972afee75a4c0b249dee0fc8f9b9c8a243d 007e7e73171e4d2f2989dc024757c186485435b82544a448f5cfca05f281 b526d2bbe03491c755f961f5024c1dc784b2cf5bad98d3a6223d7a251ed307eced1b53e305ec73666ddfa47451b3897918610180df40f65d1c7c67d627d8c16e7c32a76aecc5bb6a33944c3a33f60d2cd1958b70528ccacd97253e31bbb9d426 +4db998df7b90678b8aa4ec6233c9b4629800ad1f3e2cf8f7afcac62fc6982dcb290e44587015eca8dfe77dbb4a80f9bffe75b11e961e70deed14555db6dae47d49e73004f000eb8677c18f7e8234bf0a5a104266167a05ef07152e7acc2f0368b37efe69c0c2feb51eedf7338cf9ed398f066cf1f66bacd89ab9376d41da35a2 005f7270764a0444c7159d2db867930fdb0fb9fa6b8fc80ca02e11753095 a374c1c416e93574f5155cf28265de9c447d191b763ebb48110dc8e98eef7146058743855d32595c08d8d411c425ffac0312583f6307105c6897a146651a0875b6cc30fb87b7ca85a3f53e4e20d67e5d385c6b603841fcbf5ca3891df8d674c5 +dbf9b8a4ae316bd2df0c80db1cb5d7038364a2634925ff957d7c03511b57d486274b2ecf191746827c325a14dc94daacd66ad86d369e3f598f176c4f0eadec7e9edd13e34043efbe0a801b75b8186b4a6d89ceae4fb250ab570d65b6dd7c04382738fe3f6f6c867a7d84b35b20720cb0036a5d81a87126f236833831d9ff00b1 00179b924afa4acf30ecbe2b3c12de533a1f9675687876a7e5e5ddc8e03b 957d793f51924c189655301ebe025e38b35f8fb1b05fc26a8ae6763d73143035da3badd1d13224ec0c0a4e88a81527bd0c2061b6bba2e1c0abe73b3869285b5c8c3c6f2323c3f6769c606bda3368e2c4e619c119f113fffd993a9148ef14ef2c +986d9e5d636526f4deb7545c037fe81b09c74496ddb8e42e61650c74b6fe348593f0cf8f8eca5e839baf62f17bf6ad96ec0c71dc44fdf11259dbfe7499157e402f6bd5076972354150723afb632799a990c44cd0a4fa9609ec4db133e3b4700be3ea4a338e8ba1873d345e80163ed60d0de274d7617a8382980bc2138b0a2a01 002c9eb4d392d7f2eef606e1861183acb1fc753d666225f0f154d9eda147 a7160be260e04d34f38c9b201bb3ce69d7606016b323b78770b2772724630fc44b2b7f54a1bbf4b6dedbf7bb7d73ae5005d188cf8ce429d8832d4eef8c56b686713fbfd90db8d7467f021e55020fd92a0fd4f8069a02dbb0446e9a93e3437a84 +68d0be2883598bfb1433886aff118349157708690380c42b8919859d96db069c7fde6e117a3669f2cff94a0f1b66b27b09e3f1b24d26299e11552a084be428446f3174da2e0414655bdceb38e58fcb065b6661190862db39c6545dead34a03584632e988d0459659dc7c7c78d4d00fc2aa10465cf24b2410f14e2a62173c9962 0024661c89b77b2c743cc175a6130904461138ddc4ef771ffb9fc2c8679a b08e67d52de8178efa002f16f2b1b2b97b1b3cc41dff5c30f3d38591075c2bfa8ac21c45c3ca98ba6ce45ce791c031e20558cb353e5efb6dc2f255b5afa2880b4e89bffd2891b73abe539f66afa95d9eeaa97d8a68ecf145bae87b2b4c581c25 +f0ba0407485fecd7337f4b22236533a926cc744a5f06dd08276750196f1bf7ea7984278f789f92dd07e36895a8bfe297ea43d4a1177c0368900e3b969d3083cbe626f0e27e7ab38e185c923dff46d9ba187b2acb9cf4b23ec8eedbb8044b96b5263d956e50cd6240c66d5d96517130c743752404ed09473f05d0004dc5971ff5 00065e20e5ce534576d7c17616cd4ede3bf4f500894850723bcc9f895f4b 95bd5bcff2ac19089edf44ecd703d7befcfec0c5ae9722a462757d79b132c65c68dfe9715ac17cf10c4b46e7f0cdf8bc1499f41da580c70b4bc165672ca2956d3cb4496033a00c289f06170a14904183515ec72104159d9bdf2888f58d5d0fae +3827276694e413c886129c452c9a66e7d09dee84f5f09bf34e4baa308b4627e096c7d45cf6ef45ba1d9a4019a60399feec10fa80e333e2aff1251c85ca48574d9b9e1affb9666828dff5afcef3edaf5e8cae823505a0c73afe76c1bf130399fb06b092ba34ab0ae15ac6c682f9ee8479b065ce75b57213b8aae0f55e4e386de5 0014c85f66fbbd653f1e4e590cffe62c343ba6062df4b271fbd02e5d42f7 94d12602ef343df3188965d8203476aea0e64b83b3612626c0fe95344861d8d83bf7d7c239337999d86b9d2d8aa5a47209bd1810dc55f24104a63c6136d05bcbaba8c79a9ed3142dcf846fa372739d23cafa323ba415ed951744aa6338464f13 +d1afb8965b48d66b9acb1ece674d9548f83395275f2d8135554cfcc7ceb96450d850dd874529433883709483d0743798db5e0dee955a4f30ba328c7934b8dd9207f3c336cf89141a175ebe23d2faed629eb4236a8aea8300604c3eb7704512f240fda66acedf1494a85058dc6a31bf9531958c332b93cfe5545046876c6b99e0 0030ac7a78593b570b29f6d3d267abb6ba7e5870ee1c8ee4f1ab2f141051 8368fcfb4b59c1c2eb80a7718269d0fdb4a103a478b2243d5e7908ab7f3ba53fc928fe5672f0606957897219a8ede5780fa8cfc63ded5f3f116515424cc8b03480baed54d52224c625ac530ea7f7c64255f126ea6ba85367fe2281f611dff586 +4f95b71669fdfe5dc46d4b951b085e099de349fc740535175337127910acf24e9a0e4b2f23196ad23880da47b740d77d74fe9bcfdcc44dd7d8d1a181ac290de5cf4da22d5034cda3d8020bcc776dde8cef1786c9ce4d2c2cfb035da61406af745efb7ef1a55f2eccc5000319cf1d6380963025dcea641cfd15a3106751fec286 006d7516aa040f7d559cae248e485834e8d9bb608279ed4d4f7e1dbcd2b3 b24fb5d807a578ae38327c245148c915b8a2ba02f8e32843d80444e0a23f6a33a67fc971718a121e0a5e54254e4fa8f90965135d252bd54790cd449c70bc00064848b7aff5b8b390a74e5b5b2e09cdc2416ec2ccaa624aa25231715407bd3a50 +2ad9e17780c824c4f2d1e1cbf19ab85638f2f71cb4fa3518f08085b8b358f54d4f08394a5ac29cbb3cab828c5f07f41eec51e6cd61a5f2cf44dbfa46834370cebdeb328fd3bf681e61011b5c2ebc8945ac7a2a8467606051008b15c89390e111999255bfe28634ce9bc2850a2b55a4af1c4c2f94403c78aba1ebc87386ab7b32 00137050d7b455f43a8dc2516cfff5a91062c1a2727b27df41488f3dcf18 880c8a914a8289e1ad59f5942ad674b80847e603f71a076efdeab1873b6d71a838f5d4e6a42df318c756a45476cccbb204a1127fd04e4e1a9e725b4495c6cc6d151defbf940578a63a17452d9813b652e6a804473f8c1e2ac759fcb8950255d1 +958773c37d3eba003aa5c489f72118b3022c52b93399e9d8001695664918b86893f4922c7b6e55b1855ed0fd1d8de5dc61af403ad660fec60d7c44bd0102c069957ed804d0d416facdc1a95355ef58554606579ef89b1842f1055cfa2ae118abbc485356824cc09dddb77d0671cb3011b33bc86cac526e3f6bb3293c7bdca1ff 0001fd447b33a2ee3595b9f885c290d241422afdd74c3dc4981955a7e9ad a86f095a16dccda4ac640723a0f9386a712c591a9e458a5ac1faf4f9504dc33f23c23fca7513d8d2a073a3cf7cd4cd6b01afd755081bd968328658a854c6eab20eeee1d245708c9e48348573a068b882f245995afe652e42085235e409e27aab +9cb2c496b1bc7f040228571e005e7e936e48e8f469e295edf914f5648701249a20bff6b98b5e862603dd9f12bb71c160aafe9df02e2e383e9b8a9a9d700f4425ce408feabbf754be543f52204c849fed6c9d3e36e03dfbd9e35c18d7bb2295f1c484a66e73440a0a5aece5fe80b9ade9321ef18cde3eb2db15e4b18e788b0441 006a061e10b4a6e7001d95411cb31bdea9c84670a59ed61b14fbbb05c8e7 aaa4bfea34adcb463d3e559401799e777684d1b974e79c286b613716aded3061a7d7246f58f2eb020313bfaf087eff21124193b4655e6cd370ea16cb29330b7365f88c331bb9a5040c4e9322221bb9c0517f67ae1d863e728fb12b46725f89bb +9a4bc0a029e97742ed3bca207d5912cb568e4403cda106b00247520ea02008b14c041b8c9b976294252da835f4ff27456039d79d90315abcb0b9b6958a22352672e229665457ec79571ca80447c8ff2a86e6af3dabe7427c8bdcae65e3c6746a56079ce2cf8d22235180f46646a21cd9e86032cfad874cb9c67f882fb037a13f 0027ec31ca31acb4d2fbacb49fc085f1261b0042cc755cc97f9b199e7a37 99b34a7a25bd3882ecc8ac57adc46478f78374dc071997041f548faf09adc0add0e1958e6065a8dc2059e58fd932e3b205c4bfdd2016d22835f18938cb1cb90a0bf1225b97ff062f2f3de6f35dc3a22d72ae379faa270732adcb2bb952a568c8 +8d89e22cf802dc68ff22d43c436c79311e705ff6fd845e77c880f399f403e6d5e9e2b35511553c978171189e288cb2200fd95f84ec5ee9865c0eb9190aff6dacf783ef200e82027fa992741876456472bdf27f2bd8ee55db15408c957a120eb64cd24d299818726a73fbb0697eba726a326719765735b37a2dcff0c853c906bd 004c6f4d88e5a4f4f83196f2dda9dcf2a66eaf94d50c851f59bfcea1d876 8710a1dd775efc1961e7f1e445cef21ffe6297bc9268a7c197c16cad2e4fc3a197b1897714d2fc3a81bc77f6040ede5a02a25e10938fe14c6854887f36711edc6ed084cc43843c66f98b372d1bbda4d182211fef2de21d4b0727ca29de328dca +aa1bf5a79e5339fb9ef6c2817bd95725551d064bc5064d6586c5a879901adf808dc2ef7c78ec3b434b84569988db58b5e8e9782b1cbc2cc7c9b68e66f32d4ac4ebe7e75b345f654c7b8a5e650acc9f170f75b7aaa3957cce248cc69cf93faf8d72abc6fc1cfa9ae2d18a7b31ce720147e88e84f6563b2197882fe302449ac5ce 001aa169ea84365c22981bb766bfdad27e373440850569957544b0f9332a 93cd2463683d2ff047dedf0ce0c9fc36b8183fe273550cae4cedf4e2d1be0caabe31af68a07987ca992c1aca757ec4ef1987039996f067cc4c8c6d2d8d5b9d73035e29a1467d6cbab4ce4a9d2585392c15428af6421507e63c124a6b2cd65950 +475664d5e22cbe0da0d0289ca9a666a37270dc71c81cffac91f6229fa39315c1d55f7e0a89b6a7a07df7d391dbdf8fb7af63d2da46ecc3b60110dbcd842da97f98d2b67f562b0364ef8e1c589519024177c8ea079794f271f6d35554c0e9d0a39062383c95721b72f4e74eaafb6fbfbda02cb670a7c4c94f67b8ebc6442e84e3 004a665b92c0c33a3f8b9eb4b0ec061d40b603de36c87096455102ffe57b a94f6f828c4034a0e863d463a0379641c99ad5b5a03439698975a6dbd915665992e429eda0312447f3f7b5317461bf9d119cef1762060c48d2cdc42162f83d9e496ece8dce3870ca31e546e4f2dd645d61919d597d62f003ee98361997757abe +9e5397d94465390a82a3c07e3ebf21b515776d18b4463aa5810e6b2f96ca61e92d13e034fa853c3fa45411f51f79df6f799a2c6906e6a5b7896a4576a4464f9e0be2b529a43e1f503fb640d79db6b68f3a3a7deac1b5832fbe86673784ff6db1f8438f7dd332cdd1e7ad9df8b6731aad1b6a72bde52e6bc62d80b8da57822c48 000531540d94823e19ab2b95cbc6e7492e1effcbabce875de6ba96f53aa9 aade230bf1e6d29b6de09f3b0d6877e71b4d0a05fccddfc01c767af933b2eaa4821d490d67370eff72f11b3d6b61a7090df5c1fb4b4f12d3c8e143548bf8cad9205d6623789b7cb8dd1c887654c5e63e982b440b363f158fe221427f882235e3 +3cc4c4192f317e52df6f8cefba6d4cd823c942aaee11b9a0ef5de5c2d181073b7085a55805e9554def8dc13eb978e7396044d4f4a14be2c7605998c062095c929b9c23b2b1b2fa73dd19a0c0af44ca4789f9841fa62dee8a5f91b3cc4b3264f5f67334c3f0772b30bd7431c3fbbf1f34318ce1889b6e8a76ce6d42079a451e56 0022a89addd8b85809e87e0aa2c038593ec277054842854de1197833a51c aafbe68dfbf08741b6ed7c304c40b53e49ca4e13a33d24dddb6136655e87cdcedc0d51436a9a4555201b0f8c30d5244d0507aeaf598adc0a15c965f107bfc84f28de4ec98cf73331ef45aa797d2023321741dc48ed10c1dd5137637865d5ec02 +72cdef5bdf710978e0aa334b86b8ff4a58630da314eabe98b4d611aab56f55c526983d54d19bbbf9ddba30a84b18aa0bae9f9503e9b222f842f084db83aa39625403213ca321cc0d9c8a136c826e6ea4ec108b913dd0a9ce9d5b8c7e3af53c3876e56a2037ebd6d99f037a097111c837647bedfe4c494e4288ed6427c15969e3 001df252a11ff97b4421b3a2361db94e908e8243cd50d9179f9e03e331f1 8cacdb636bf1ad1a58e7d4603584e2bea9a24bc91213b1c385f1daedb2927b196a7c5755517a747633fefa14bdd17904088d7433395ebc11b78feef5b9d04036e8f4c8eb33da3dcf1fbe39d9f6d6ec1ecbc823e56559028614f59329eb56edac +8e4eb88c0b2d525b2c58b8e00f32def90e6dd382301de49e0ac053dbc6b61afe926d85193e2c4948f7402a3d7c614cb2c58e060362b0516a1ba4a7425f1b3d09aa20d4c3c8993a387a3248aeec51e6efa8f558dbdcfcaa13ee08413227c8351e3107e9a3e3ac124224aaea91bfe50c11c1c8ae582e718f50bc5d5c06076517d6 001d7125c299ebd0dbcc050f07de931c7ad0450af590d0a2d0228a66ac5d 874f933d661507e3e5b4343b9639bebc14c1c58a899715cd97e236d31011d2cb34957e561062a01e4640130494b30608013aff93e7c6c7240a43ebd3128fb8a439b033623d2a2018e6658c2096c9efec7ef905efbad33aac60444c14708170c8 +370fdd80f330311dbb3959666001bba61cdacf20f72f78953d946fa6cba02d24b5003f5452d535609e489b9434f192011f99f918defe877d51349870e7e75502f61145f7c261dbd2a0840926d824ebe9be3c5a77a3a84340aea930378367ed3615a47e3f792c7773f83f91ebea718a05fc62e9ed1d78629b2c27ae44fe8f8d4e 0021238e66119844b146d40e48341f522f6ac2f9c8a0b33aaf95a3099a41 96c60d8f9c02e6b7ac675d80d1a1cf4421d0da1608e252675e51c1b47aa46b11116cfdff1d8d66b9f38847b1813b2bbc163af4191ba329ee4ccdf22603fd052402b15641bb3bbfdbb852c2545e78af6c7e5430f4ed7c20d1086fb92e658fbb3a +f86c4433787c3ec3cb1663389ccf53d62f9425274ccef05fd14b1b8fef676208867764eb98d16d006ee6ebdc27b8d9a8ddd303d941fdd82b630694cdc698bbe6bd524411907834286c94b24ee199fe6d646064277f244b7df3ea2d9d52a9dc6a33d7c8d6dbc919da0fa987a67621ef0829e48310e0ea2bb86fedcf4effc0b94b 0015e1bdfdacd87c42ed439f3e243abf27fd42e54f3ebdfb47f60dbae5fe a9b55231add73358081267627363942a7dd403712cabfa3a85ec429384b54cb19bdbd26af709c104a0f474261feb834a16daab6c40a4892fb6f6abe7135e78bc1ed593680511f1deb45002df7f7020f921ac9a1549946b870f91484ad0fb6ea2 +4117d593aa92e3eae1124ec7482737cd3573fe5f0f2a5051a7ce86946a2abb9e47a0c6ea75b262689b0b486476d2ab09a20efc2fb921419b1811b51a2e15891ae9e45a17ab4b96c665c6c423fc00e2d66df5804a164f0f3c958df6f25d7da6829b1fe162a0a8cf130858c83f3555d6ad627db70cb41303cc6380f7b3fed2563e 000e09410548c17bbbf28a68c3963a52d39743a4f1ac28e6dfe7a6ede281 93703d9d854c0dcc014c8fa57a619e49f95aef9a4ec111997f808f5dd4cf50f773a9de6edca31e441a9bfb2a6992ab3e13d132cf0b36f7b69d933748311c566b61702334400c6619e4e8af284ddfe7c8722ffe0c361499eac0b8b5e950978f05 +882ecaff3ec8f4023df5397167f238869f78a5c499be19aea85c7486e73f66f0e08e71cf85f3f1b6f6a70796bf46a18e6b555a0a87c2088640ca73051b3dd59ebfef922be0372208fce602d8001681297b285701dbbe24ccb42541b5db4aac1a1c7f407e11c83db15b38cdbc25e930fdc6558f64d9503e214571a435d890169b 0049f5bea6e72d98579b78cb07d89f64503f8759dd7a73cd73713c120428 82986fec3f950eb21c322c002a37d0105c3e127c36e3559a7375699956cd7d7c5f6b04879e46e6e2d7607841132c2c3e1888de880cabde825b645647e44fe085e13cf13680491c62b9a28d2298a3b91caefb69642cdf5b6ede3b928411e7c7cf +99b3b8f876f8359bd6369ce84f9261581c52d744b90261a1427ab9e447e6d833b6b3e89af8dc770f1dd55692d01c8bbc4277a729fddfa7cbdb2ec99133201dde44ac691a77904ca816feb0a1aaacbb9fba85048bc63d73506eb908ecd697caf582747051a3a38ac8930c9a4365f407ed94ca7f2d26913c53f4c010c7ed9d7ca4 0005eaa818690d1ca4838f0bc667be5721d178c3869884260fb230277c3b 928b268b18e1e85af5e4538b81319eba637e529dfce1f4510d1babd561db4af6ebfaad54eac82410c4e0cdf51dbb18be0d1d162bbf038b34c8568f6c612b126cb13797b07226ae112e823c934331c8330cef826557bc4decc468e15c02daf70e +8c1a83023930a85c5b2f9930521b8b8963d5523a3323d87f862a17d3505ccee01246ee1029b8b8c2b608772c4096d1e914cb398f027d91184a8e94e4feeae121eabb504a2a35c8bc9294edd15ddd979946c14c792ad787dc2d4deffa284830fc90b3f8c0ced6a99fc6de7c41b9ed261402a6b3d702ff86a9392731ecc37430c0 00603d89cd2f741d734587e77554fe6bbb1e5739d5ff73084d4de8ed69c4 9057e4d99b95f581e40d2f050b000286d444c2e0becdbedda520b805aec2393a032b1be4dbc10cb9a8cfed85bd51d15905e28c7b9b7c708b1ad16267886499a6abe0ca7d12d2a547b0c7e0a5b3f33518355787d977f863565f3832e2824f3adc +f3c9dedd7115339dd3ede7d8d06a44de66bf80b4888ab7bc386cd40a92789042440a13d2cc90dbcacca5feeec1e0e3c51724146e2c4904ed6b05c7b4e9b49d7f458ada695c5d2fc36f1193329b87c1268aa38eda9151430aa0bc004e5d2a61b9390accfc699f2efabfec785eb34f52b1beff1e4c5492e922acc348667d2a3986 007977b3aba53616dac27b4d74930da23966a88ad98f1769674789c0be3d abafb3d55ae24e8c5cd36d04cef8d8916bceffda3dd8d8ee6f8bba9c8bc4e0d6e3e9451270aec70811a15b8db23777a20097174eda541c6d7f728f8aa58a8346c1180dd2d0462f332528838eb3b18dfbff0ec86eea33580b656bdb0a858e969f +d878c4ee0bd6c84652d7f9e68df7b90cc78776d8d1b60f3e4d7465032bf401f1527ca7bfd4a3dd916e13e93fadaa5e5f20c9f47d12f8fc922a9a3aaeeeef294c221ca1adf7df85b888faec8002f17ff202da1be837827619904121167bee2d2cd694a263d9a99062cada3399dcbfcb283597a96ebec129c65e0850ec4cb4e2d7 0050cd20e7eabd29008cc977d0a17e1195d79587b8f15ac2447e15daafc0 93d2337fc3aace9ea4cd2004ff48222aee870be652063de6b41530784ee880a85a36ba8ad8a359fb98bf732338c68133097c6b68928d2322eb17e1b24cc272973a1c5008a1af0e8995d3f463466a1eb7590f6dcaf1d986a5ac91c35cd4dce44b +ac3c118cc9cbc8eb3b74d8ccc9ecbd81d1996fb25ca43c8a43bffeb244f722b93c9e969241d45d5b81fda0b399f1e3623687190e428dae077e54cad1eff75ec2f7fbb9434bf716833421bc2634885677579c237340f76787b2eb19b446d56c0f2206099b81493349f4db0ecad0e2dbe85dbff7d7070abb3d3b12ef0cec828af4 002dbb24fcaf9f3cd5d50d209937f0e2d134fa20ee3c9c2f1fff3dfbf302 8e8d3acc78394a120892822342535c85f5559a8a1a86ef47218b8cf8b50627d19fe778c49cfdc5e7111a457bdf9fe9d60fd315433afe04ae970e6ff29cd282b03551a4919024d928352ea1ee4377d2e21dc738622f4f40873dc00a929a0cfbd1 +700313698cdfdcf0044ca07bf9e5f0702ece7cc66e35decb28d5f8cb7e7e5367a95cc1728a90cc9a53a2b5fcd4702028b742538e9b386f5d8b4a2411579ed9553021a95bd00a73f03c4184a6145aaa367e3af76659d677fe7a2e98f9ddf4aa20eb8d1a1db72c3f5590598801be7ebf44255fd7376d89d998b7068bd1296fdc38 00047142197d3d43fa46545b547968680ec81688589d1ec8d7c7e90eb969 b98972e946cc944d524f03c94eb6f9037838e934ca04e5c26bbb4eabfcb75ae17f2c051f98bcd225626f81a2d64db63806d43f048318222cad51f10746a816ede4d6ee95a65a1507f82acdf7d3c567c3523d33a8e2ad7ef6c1f7ef98caf7cd3c +0374673e1a685bdee55504ce3cd333f70084dd4ae685464a16924eccea34531663fda60229166478b30193459a3113253cd6494dc26154156252dc6e822552c7c04d790eb9f8fcef2ea8dd79e72f881f7f20fff93cd73ad303c0918ec27c6486c4da61f82bcd55422d16650cc68bfd4b0132c1e7075bbf17dad919095860d445 0031352b49ecde5434aac05f898e6ce4337304845d748f114c14319fe97f a7e4c6cf6f36cf77bafde1803cabbbebe8852b3688db6fc511917a76a5f75a6a809f885d32a6fef39ab132d715b6e4e21118452db3c591317bcea73e038740aa4187204ce5c88b15a2745fd45229786edd6a22d78988c880fec8c4befdac5dd4 +8b237085f135d6e94592f8d855ca397c8c1028236a3b412adefdac888245874f586d06950ee18118f751bfe26f4c31465ec34b578caa44cf1b7109ac4f6eab7f97ff9699b34271df035d3bf58a2ed4bcbf7577cf8e5792b1945ebb9389b680baeb8518c8fdc5540e192aa4fde0eed0d7c82be2e362b286f582d65752c8db7038 00176f124c24e4420f6e726a6ca25f09dfa0c5a37e5bf879e7bdd36c3b65 920432c5433d0812d6f840e6bb82dca16a2ebeca49e07f5e4cab9c8bbe7a1f39491f70bb9d63906a3644ad99f5443dcf000a6348dabfebf00ae6af8f8f469d825e179259524b7f2b6cea5cbae4457e3dd228a787d0eead156ad42b1c035e5156 +e3a086ec15574f7017b3cd5f5a47ab7a73980f11074333490dfe9f8ad8926f9ea7c82271aaa74e77133b1025b0b22a6900fbb71251bb6549341a23d194e79d03462cdad52ee0d1b6f5d0d14e1136026961fa3467ccf0864bf7ae3fcc3b68cb35df7324bd9bbe58fc8aa9f63c19feedf19d935b71bf5981c74fb2a487f84e453c 00755c48c3dbaf71042c58cb137f3632e3cf9d90b7b9a58fd378feef3d19 a14e656c4b5b5ca136179f603c36c7a08a356acefd7bd500d5352ceff41fa023887fde4da2d0b45fb760183b1f92523a0193ba2099fd5e0f1dde460d08337c0c29a2cd268a2c9be9e868223779020a69ddc4635621cfea8e95aeea6eda684688 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K233_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K233_blst new file mode 100644 index 000000000000..8f4d2525a535 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K233_blst @@ -0,0 +1,60 @@ +f23f784fe136c9fc0d169503d361e9c6148b0f1fbdcae0a97fae1af7033ddef25cb7489c9963cfcb009a8cbfe44a8510a64a073eb1deae4c324ceb9302008c92c69b2dafcc9077fd3cc3c7c119edc3ced36d176ceaa55ac036bf7f07f6fa215e8bb8196e59a5e1c9af4f98b90ab4970885bd7015fa26a09e03c7cf6b4b23d929 004c1d414696cc3657dd9df73ace56eda2636769ce7082e064c260be45a5 8dff5a5a9809aa1187d9febc7ec3b8fe8cebf7ad69727a7b0d645fcbc0e7effca6db847b0fca823d25884c8712ee64f800ef4fc3a5d1c6217e9632ffe4c9a74d00d7e651699a31052e1afdd588cfb718acee0ec6bec959f20de0fd361acee909 +400bcb297552bb37f2f8135a9314a35f5126788bb6fa4dc74152731ff64c5dab4b902103d85443dec20e16b1d6629930cdc2bd183d4099f0e96295a63c2fe266f5e9d050c401a8681b4a438efe53cbd8f2f43e2a31e9f88926a9c82917d873f6e8cd5ff5eb8c1ca36126b0bfc8c2b0e85a7c9e7a45f1875ca9c82019ebedb729 0027cb1d84865a16992476c9e353283d5d6a40c349a8e9179d1b1f403531 80dd9b3c95b5c665bfa8061f0db031f492c5f20cd950969682b491ad07744c5c9652010c60e1f59c3163fb3a5d28451b11406464f7dd04a93e1112c6f7c5c9de1986e3441c7ac7c070f96e9bed1f26b0448c53b2824388dbdb1535f3cff0c83c +5f74d4b35c49fa454c97c05fdb6b9f6822cf1a2295f15bd766dbcb413d77c910bd8f4147e8f317fac2300fa21cb80134d1b6f8ae8e50518c1f648a28506e419f5a6e8f05abffdb3dd2587606c7e9c223ecff4f46b121216730ea13202b59128a7616bb2fd23a7e4a5aa08641cc07b669641313febfc88d64d99447353dae3f06 0031b443f46c4b5224237fac1022ee1570173f664aba0c84dbaa4246bdc1 a83e89825a4106b075876d5c12b3d72827e8d40b1876f4de239a44bd23e841782b8bb404f31f7185d3bcc77c1456561006166ac17b53de864ece00b50a47e4e7a8ee416728c023503383608d304eec9d17fa2dfe0ca33daf8d3c853f025f847b +8f92096876d9f81bcd992369d42d0b5877ac969004d17c8627c58d8b8b7bbf7a37e8cb6afa962b9b043bbbaa5bef4a5ee38d8bd31cb5866b828265a2f4102a616f87009cd346fcb8af5519fb577c60d8792472232f33dc615655e53d2b715b15a2697b492f108b7906e1e3597c6911f8cc30c7121ae338a6b747ec368f8e4a36 0048f6ca29f35f253a4962734357c995920967b9eeff1ba5fd2080bfede5 b17b6c16c719a2e6028762e0565f57c0a4a71a8df89c32aa3da0b9fd6bfb4cbb1098cf287b4bcc64419de29dbe37f7da115b76ed42ccf544b0c66c55553209fae0d6f319213b28d0180e99edfc6f1c9c60bfff39c99d2124ebba7acdcbe939b6 +3d275dbde44494c45fc15fe89e2ae32aa26426a17e923e895c7941a5582fb95df4d49873ab1bde358017f336b911b886b626b744806ab8113418473c441f1964159ded1b12122d53ac56573167588e4b55f36b8bca8c67823883a51fb6e7f204d1c6b07ea49b577bfab9ca6b8d51f72268b022e3a4db6f9d265ee8382f9b7b66 0019b940eabbe682f961d9f3d90432e347fef3910e641656825d775705b1 a1c9488fcb8f0947277a6ce5ca99b17a7b2fa08a7a9e8586148b99018d48ef2696db8a0c5011cf7dce5e22b598e3ea2e03cb79982802068057359bab556ffdbfb5ba1f8e7eb1ab9f318cde218cc19389b2e265f95f2fb22505dbeeb5456fdc9b +d2fa68e1f7dad02916b12fa38f1849d6d409dbad0344438520b4dd9b77d62d39ac9ae3cdeab03ccbcfd4de703c6e798873671731c108f322b9f2a68145e3e210c9b15b879798e5c53c5022742e9819b99edabb2f44d89ae221f7a99dc84421a6905695ff91928db608f861745f17584d56e34b75c47281435b1b0b34e490692d 007a884b22e29fa9fe945e9ba13c0df8d786dc87cef0f77f069e182dd56c 8122fc7204008118a6948751e416aa563158726500aa670b0ba375aa25e292a8def688ebb8957717fe0420eb7669892f02af116a378782289fc088aef31a22df8b71cb169473c919b23d31098c7c2a4903fce5d9fbc4b55b6fc310bf95f793b7 +3830f75cf9df4eb2998c7c1b5fe11c1476bcf849c3a8fa7d3d0b5bc2292e5d07465ab8cc9381c575d909e509c5dac49c78817c04e4bef18bd51bb09aa5897f21634633a5ce6d20bb4638cb6c3927351eaec7b62cf4a33956916045c392f325adafb10a88a5f86d7e41dd77908fa7284210071c22aa40ef40da6339c02da05392 005da61f881d5a0dc085bb93764f584352882923cd237d878220ec624c1a 8751721f095b444ade14510cb98ce60cdd121a8288c9ae7fe76c96d9ddb173ee782cf69522ba5b8ec9ff089be497165f13d1a226a20469160e919440f6d5af195f294eabf56b39e7186d5874500827077c173e06bcdf03ab3c3904dbeb7bbab2 +65b9fe15e6c35d453caa6bad39ee78a720a04b60d8a0a0f049186d2f777e48ae2d657e174df53edb7beb9f7d8f21904ed674add0cda5b62a7308de76c324a144021e8c6d387daaba4ce48bf7dfe9c8aeee2c64e434ece1fa5ddcafcf3e5d0013a1eeec1742a00d384cc2ec0d7eda83bb4dccfb0e57045ebfc27a4f404d03da37 003fe9f04647f6d82b13ec1ae5a8c2e49bc66b05649ad778eb16149ad83a 8c3cb17f752141d37fde988c0bebb422c9c329b13ff4a37d8cd1c0687e8660624516b90f7d0bfe2678714749e67fd2520cfd02e5f49add07207aafc8a4baac9e1201791df3e565461b3c62a8f8f33d5b8247bfad1b65df20e142fa81680c3790 +d26521fd41eb5d46ece6836e188bf9cb1b461d011c41e002a935d256654d01725378e845920ec4a7fd3f379df54772493df50d312c7c6aa4e909e7b83f2442c3a5e85c37d68aa015098ecfb0a5e077370f4576f4bc63bf37e1dee06d780a3b6949af5e21c2a0960fcd20821ef5f17bebf5fd5b3bdda260842cbbfad45667287a 005ebce648ace4cd555413de6a456fc487d14bf4b0b9a72311ef480d2f26 a747ec594a427c44ca8dd6437d23ef56d78dab6e308d80fa59cc9f24cf7062e1139523befff58cb72edc9925f77be8cb19340714616959bf06b26a760064c924c4b4b2adcb2e1ab2a417603b5517f390118b65cea9878753949436dacf3236d4 +b778c021b1a92c41dbd09963da07018075d73e54d62df5c2b7bf8abe137151650d1c1c6abce7eebd8f32e8c3e6d1433773f257bb3ba4a4fb6a02c0db1e47d03c27d3a90898ebd1927c21df24c4c5443ca5b81f8ef2cc0f5e8b3d08f472bf07085df737adaedec63d99acd77b87ba98225f198b791124ac2d9b191cb9251b4b00 0056653c2f85593f789a926ba49fa3da9d7f946d8f1020508c5a527ce813 83d92c9ff2389ef1282c88914dd875b4924c682fc1c4d807dbe2a8f32926599e2404ee1ac253076b8cca4b3445af71eb08bd8d762f03b6e35ba1c5db74527b4290733a806b0fe769f4646cff7195e0131b9cd6a8bd84bd0fc798a32d0a2a39b7 +ec14e07f615960015a489ef999e308b42a4c571473b9bd64b433dabd9a1b1ad02e33eee9100064405175928a94543a80f440040afa2965b4e5f95f768e7fab6d3c0a5f5e1bf1df7822f78384e80f2955ea85f044ac60537d895747979f935bb0cd3673193c4a32dd7803e48d7daf70a71bc2aa97236615b6411e28fc9a652145 0049a91d320783cc70a5952c32036cfc75d41f1aa84127db2dc759fb291c 81b547a1b308e3ac796c1503a9878cc1e0c7d81db03eab8495770837e1395a76d60035fdf636dfdb033cb72fff1ee7621609d8dfb4ba9b88d7bf697cddc4e697fdbacf43fd2581853a4434a53f48e7259cf43108bf960751624ee920cd67ca83 +89c645339ad0eb850e4e2fe583cee175b35feb02ed7541d7e9aace24cdd3939584f73ad39526de6399c86b36de77a018e2c70b532bd0f032f9137d10480acc30c49f9baaa86f9df0033b77e98b485bf7a69cb5c281e527d3ccd1fce2415f0dda4a268ce68a0a34b16afda54ed922cd6810ac8dc766df2a3a6c5e55972e9786fc 0016a20016602fc7088a60469843e1d29ad67e3c3cb9500b1e2a00d4050a 84efa55bfce692e5e0e1f63fb435d8c4e7bd680aa6005ea774d002abb3fe7de389b97f6416ac7d5968306dac5faf5e3409ce69cf29e971d79ed517bf92e3dd4a8cee755c75872ae958b08ae8f51ad62b122627c6bc446f9102305164adbe67e4 +ace14c4b101d2d8453c2bc22b756af016b5de537df9c3e639d208ad04ae0bf6232dc90b90c33228dc85de956db771ffde05fb4d0b15e4f218ed2771d703ae5bf981252a5bcd60c16f14483131a481cbe04dc0adb1fb8aa32cb48bb5008e8a8e5c7b7465be2fd7afbc811cf5ea6293b1a464669b49f55f57b93a8707e6042fda6 000ba922149bada2551b7be1c3df076f3f97ce93c13c50c285fef3f42363 b5c1dfa05ca887375f49e1bf1b2790b1df5d7608124837ac705baa0ebade6f016c38c681c319b558eb00dad3a77ea8bc172d76b688fd0e4afc0f35b5dc8e24fc0fcec16da64f7297d16b8117df1c29edf9148c991231f6974d409a898948eb39 +cec2ba0d1772c87e87d5bbbd67220692bea4301aa1a66e8dbdd7e651d45c26dc2a0d45cfc32c34d76ae3e1c61db7b0fe1863457b93937d929e6ece7462ebd16adfd708353d6f7c27aafe06593c76da7149b0cc574a4290b0d8fe219f3eada7082aca38dba3f78ed0d5942d095fa5556fc8bcef331ff0a6d5d1f4e6c51d4ff5af 002d635e12a58cc6dea44e71e87c37f91e8d08659f0b7955d24f65ab55ba 8e25791f684df90ac158e73c3f04ac6808e1b80e80071354ac451f058ef3404363d7dc426018e1976d243e71a2013b9b0e6922cbd35a98bc547d3820dac7bc9f3627ff4fded3200c770c3ce9f381c886910a44999232d799253586e37ded647f +ffa13cd0f51ae2643d5d4edecb493ddd653e9faddcffc370e7e958abf726a5d67a2ab36cef42ea8ebe22a6f01b9c31f6ffad01e6894487d979acb5e618f765ac0ec3550ac5dbbcede8f9fdbe52fbaba5c087ff382b6d7a09b2b5084227d324d98ff98793040884799b96d2ca593201f4414f18c43b51c53c5e5059e0641aca02 00073883e5064e06814fc4de32e15f7a6cf825d2daf6eb1df8c83e25d80a 891cc9e93eab7d6897b007c3442f06226ce0d0ecb0b24888df7ad0c28aaf1ffd3769c38b1d2efc17864c10aca966be3503402a27bc885911c19ebcfeedb8a7e03e5a738a7e2a51728ad80acba1e7bb12e2d279aa73cc8bbb763e7201559444eb +c73e3dbac9513d0361dabe94071faf03a11cba18c06d131a172d5f0125b01a5eeb6055bf72c7106fe3f4be3bd2b1771cbe7f85366dccfbc3bac20538510c3f51179cc540ddafb2f3b05a0d276899674ab1d7d8fb4f6838f04e4f9e26b8c6af31540f63f4953c85840af4c57dfa78c704f637dfc8dd750fe45e2c1e149986d127 001532271bfae8d4dfe60f69b88d3006d58e28aacfa701861cde8d624db6 b6be4d26bb54fa85f80b7600469fa3f8f4b3a33eca21d945879fa45734d5ce6fa74bffa0a8a22c7d846d1e91c30d7d101467a8404c3337d081b1419064c74ad722899cbb586e56f6951be7cbb50f954c6fd80fc60d65e207bf25b5110fb5ed15 +d00dcd0f3212a3167403abed91c20e76f5e7a7678a4fd970f944d11e6a8cd149d0aa6fd3164c5a74c0f55193a4fa3d8ba6f99cabed10544625a7bd92b3e0b46edbd4a269bbc10518c5268c3910a2aea567ccd32d4c7a0cbef09ea42c20b636d1f711d220e23dacdb9d1146e0494401349749e5ed88e38295232a7effbae3aed6 00550406c0db882c6aee6cf3b6baf377375208c3e90cc44a067cee43efcf b6cf4041cecd25a76d7a7ed02acea1e69b7e5922277234ca1dd3d2ecc881dedd01b55742701e6c5f8fc9eb38ed52522c167be92607b8ca90ba6c8111f3a94f23cd05b11d9c89e0d2c91e640eeba44f4e6ae86e0d97fcf87c9aca07a13cd61a5a +3d36221f87157ca4db84884b8666660c4e2b6af330480c516cded9f3bfe132543626a39bb6aed1964eb5c33ea0b95b9841665417679fceb95d199d55accfce35dd3f2283c1a7ced57d0c4b9ebe3da6e1ff2f979b6440db27caf9f6a4bbfa47e20d29ae304f4d0551fce9cc4097eb2fbedb9b24680bb17d207bdccdbe799d5b0d 00257dc63752920b6854d6c2d1cca68589a38418c3d036e73760a12214ab b4de1710cd0d69eaee41d0deeec3f13d7eec4410ed64703f051c07535ab2fa79905564e6a5414d3024f1dcfd95dc9c9d0cd98e3f18b27289a469584cea97b13fc02cc252fc0b8110b8b758c061d739ca6773f6a7253d90039ba19b35d0a3f6a2 +033d82a42d0eddf58fbe3e91ddff7190e3f9fc2b1e2eede977d2c0473b358b5fce1f981ca6f88fd61ce2f79e453e3a2b77d1baab2b970ed28d5dcff58873a620e195085e61c4b8480d829525a1a944e8a4b63352f0291f0311f1f98ceb262804beec1c74947618f8e3b067866255878c2502966cefcdda4f5fa2b13d92ce7840 0029025352297a7be850f8852411c09259b83219135e0e8949c1bd5b94c1 a5f854267d8cfc0137c71764ae0b60a929b150d85fccaf688ec32e84c18d7d126b271203b0d48c60cd436bb395c7b3e119e128419bd67dfe32452a15ff857a5ff680aec836e19435cccd842b497acfcf29cd68f2abb12540040417c6e212bf65 +671a7c81b64b2919722d7b258bdbd90165bb757b53106e0af03d0eef27452942f40cf52bc95cc7f6567df2613cce795f8bcfc723b2735efc35375c001d37c58480d89343697146b524835df3dbd333f7c06c98e36d3c4592ecd1f34ab57c341bb0f4c785f5b8372775f74b4bce60763fad1788e77ea158d735a64861320b36c6 002dc82d0e69e498528925c0e62a13fda9af8cefd047c10c3ffc2e41da3e a856fdcb32ae2effd338657bd3df8cefcbd2defb1e223c753fb23dcaa21dd3f4a5472d4f186346cfed8cd3ee49faf9f00fed3c91c00168b7f211c14283837187e2bc82b67d7a5898a86b5c9cb49d6e43b3233684fd4a06d056114bfbd60c961e +0ef677f4799298f4aab73b7393598041f56e902ced1726af49657b6601a06186212e3ee8cd4bd33b760dfa2ea3c38884f94358d51dd479f2ccc8b0b352fa4e44fcfdcfbb24919d04e6ee1108527b8e8d60e8d1b467c30c18c5455e5835d483161d3fc26b4a67d6df9e3ddd9331247cb18450188752a1ca219f3396a872cb13d8 0041535fff5d279bcd744b04e643458ce20b81df8a9e01b1181d52bb14e4 801f5c4e21224de5f8991cbbcf27553ecd279f8e80990072ac6484a026a1c64de38ff42ac2e15a57425b9b1b0f5579d71533275bf74d433d77b74bc5e9da9d8b4bca1c6db03907ec5d626bb54ca7ba9d8f004357f6085dc70c930fd459af482c +9290df0cc50c3cab6655f3a6de1f4cf613d9bc06ea7c99f38038369ff2fadefa57a3c7ae7940c1b98bb1d03503cc271f7a891bf38eec93c31dcec7892dfd2e1ab337bedde3e5325ed8d9cb7fa3096f6fafc3beb3a66cba66ba826d1032debfb4908cc9dded8c0099c85072daac4373fbc428fcaa9a6da02181ebc33f0cf926fb 0000ecfe580a624df66c25e87e7689fc3b471d205970ff9ab51a64aa12ed 94d4c7a5f86d58b69da43e070eeefc3a6e51f580ba390de8ea84e8425ab54e261cec03027c2ebd62a8ee6a27435cce730cbdcac6d0fffb55255fe9527c5d33910d7c2390873697a28ff8fe0c9a302393761ef55da1377de3a156345d9f7ea5b5 +855c7be75fda372f062709827f333630acf28954a62a5193ff675f0dfeb63f32bca418f7cbdb346bf388d62315b19a592267ca407120db93d4e3d7125b867c4c4670b7a57a76f61734cead2caf2425eb9ff0a63293e8cd6defc9648257b401463f4533a2425e0024f1ea93365eeee3c6da20d25928602ec8b426f9b39f97f3fe 0013c72c73358ffa168423149ecdd897f0a5f75a641de008649f00134944 b3b644d74fd188534c6767e029520af2bdcaa2f22c5815614d30f5962bbbb989588faf7ba358c31ec3aa860b222218f21832c382612a7b0c58778a06cfdc6a90b1656d46bea8b05ca60b173827528f2057090834323796bdf5ca49a9a9b01672 +9c896f800281812ed57d31623d563377a5c725cec84313472b90e73f77d400f5d4fb236255741b73d46f7e5254d04099bec274db8a9af5fc7cc220d42cc172cbd3c3595c49ff74bfaab7b5e46c90855b611f74753ccdbbabf92e011d52e9ba753b83ed2a251a632e1bd5c6d346e38e743950c8ce0f394a837028575fa44bcc26 000ac60e2e70b7c4cda64071c7738f68773c94df9456a8ec3bbb468fa7f8 93206a4a68f59d7752fcef0367fd91223d5959f439ba45281359f181209dc9779c718420c261b9b4e7f9d450d38e5a600ecf5b7a48b69597f3f5fff5e7d68c968876188fcabaf84022a791430356ecb39417f0c70725e4c2dd7c303d0ad2dc67 +139a14ead998d1a962fa47c47ef2953aa136bd912fe940709b8c560bc2a0c4bf8f3aab30a8e21b7d5f487d30b0097e3da723f11b5cb4e8c5724f5a2fe0d68ee4bacbb85e5eacf18094d2a8ec4506cf8497836a4a905059a998ea750adc54c27c69cbd0b0c1f9743a62f3d988f3fa0a9865a73fc071f526623085a2ef12838888 0060bf720052e8b9508a801340c213cf53bbecf4975faee63d4b44fc647a b53fbea97d4601d556d2f4db166cd9b1cc1f7b63924cb9f2d4de53465b7cf6278cf1a79da99980df30474b0e63b117081297356bdaea90db53ecc5ad21ae202b66e52313ffe1cf58b57691973f35cde0b426aefab5f4693388f966b4b902af33 +cf4a8e754b23d0fffc1c5c80b0cb11deeaba3064b315bc2cee96db5b9881baf90d30af4b69066f757b3020706def77a5fc1632d96bafba22a9c8cd3b52d535d941b3c7cc02b7fe6b51639d5e2084478ab3a29d2f5e0e16639fc2833a47b58e2c3fb5b2ea1830fe2ff68e571a8f281617a23d9a28db1c64ddfb1083d055030e5a 007cf3c216592febd8630a478b5b3e3a605084020322adb13ac0a626bc7b a8b78638bbb49c5a57f09c6f48da91bfb56e55e6b188020334963979660b3bf9ace2435d4ae4b31ff4b6917997fa88c304c083aad5a406e73696da3a2d0dff7710c230fbbedbf622789f75491e531182ed0393fc3a1ea49444df805a6d9d7eca +ae64030d4af9b36c8d3a6af0aff34e5ab201df04274691fb420b7d5c40c401ed7f3ade96065d34f2490d17943e27156e7bed83cd7222d0d5a73d167855fbe7ff6c3ed87f20986ad8bbbd80fed5f9705c6c783b423f641d40ff1f367f9648af5a79ea3cea0236997558bd9dcb011ea4dc64d61ea1e1f85b4f696ed586bc7705be 0061eda5999e5a9ed4485d2a0ac5510549b76ca37df858ea5d95aeed571b abe83495dcace734e89adae0f0313b174b6c5144c7730d8052e7bf064fbaccb9fb5c3475abaafb07936331f85ac913f20916e813967fcd1916cf8b9c2b8847fa8fb76f166699d9759d366d570a9fcfbf342a774704e8959e6434b25dea66b2a0 +94a9d9cd9efa3e4ccf2a37f904dd9cab5624ec9393cf8816ea591c5e70cccd2f105388ae133708fb974998ae61d218c71785f9eb808d1c28d953cc7eed00dd9854b6b4568c5ed5ee3df3b58a1e04c64f1c87fee4365ec9aa41b08a6bae234dc43a0bf2f61420acdb891a40f17f246972afee75a4c0b249dee0fc8f9b9c8a243d 007e7e73171e4d2f2989dc024757c186485435b82544a448f5cfca05f281 b526d2bbe03491c755f961f5024c1dc784b2cf5bad98d3a6223d7a251ed307eced1b53e305ec73666ddfa47451b3897918610180df40f65d1c7c67d627d8c16e7c32a76aecc5bb6a33944c3a33f60d2cd1958b70528ccacd97253e31bbb9d426 +4db998df7b90678b8aa4ec6233c9b4629800ad1f3e2cf8f7afcac62fc6982dcb290e44587015eca8dfe77dbb4a80f9bffe75b11e961e70deed14555db6dae47d49e73004f000eb8677c18f7e8234bf0a5a104266167a05ef07152e7acc2f0368b37efe69c0c2feb51eedf7338cf9ed398f066cf1f66bacd89ab9376d41da35a2 005f7270764a0444c7159d2db867930fdb0fb9fa6b8fc80ca02e11753095 a374c1c416e93574f5155cf28265de9c447d191b763ebb48110dc8e98eef7146058743855d32595c08d8d411c425ffac0312583f6307105c6897a146651a0875b6cc30fb87b7ca85a3f53e4e20d67e5d385c6b603841fcbf5ca3891df8d674c5 +dbf9b8a4ae316bd2df0c80db1cb5d7038364a2634925ff957d7c03511b57d486274b2ecf191746827c325a14dc94daacd66ad86d369e3f598f176c4f0eadec7e9edd13e34043efbe0a801b75b8186b4a6d89ceae4fb250ab570d65b6dd7c04382738fe3f6f6c867a7d84b35b20720cb0036a5d81a87126f236833831d9ff00b1 00179b924afa4acf30ecbe2b3c12de533a1f9675687876a7e5e5ddc8e03b 957d793f51924c189655301ebe025e38b35f8fb1b05fc26a8ae6763d73143035da3badd1d13224ec0c0a4e88a81527bd0c2061b6bba2e1c0abe73b3869285b5c8c3c6f2323c3f6769c606bda3368e2c4e619c119f113fffd993a9148ef14ef2c +986d9e5d636526f4deb7545c037fe81b09c74496ddb8e42e61650c74b6fe348593f0cf8f8eca5e839baf62f17bf6ad96ec0c71dc44fdf11259dbfe7499157e402f6bd5076972354150723afb632799a990c44cd0a4fa9609ec4db133e3b4700be3ea4a338e8ba1873d345e80163ed60d0de274d7617a8382980bc2138b0a2a01 002c9eb4d392d7f2eef606e1861183acb1fc753d666225f0f154d9eda147 a7160be260e04d34f38c9b201bb3ce69d7606016b323b78770b2772724630fc44b2b7f54a1bbf4b6dedbf7bb7d73ae5005d188cf8ce429d8832d4eef8c56b686713fbfd90db8d7467f021e55020fd92a0fd4f8069a02dbb0446e9a93e3437a84 +68d0be2883598bfb1433886aff118349157708690380c42b8919859d96db069c7fde6e117a3669f2cff94a0f1b66b27b09e3f1b24d26299e11552a084be428446f3174da2e0414655bdceb38e58fcb065b6661190862db39c6545dead34a03584632e988d0459659dc7c7c78d4d00fc2aa10465cf24b2410f14e2a62173c9962 0024661c89b77b2c743cc175a6130904461138ddc4ef771ffb9fc2c8679a b08e67d52de8178efa002f16f2b1b2b97b1b3cc41dff5c30f3d38591075c2bfa8ac21c45c3ca98ba6ce45ce791c031e20558cb353e5efb6dc2f255b5afa2880b4e89bffd2891b73abe539f66afa95d9eeaa97d8a68ecf145bae87b2b4c581c25 +f0ba0407485fecd7337f4b22236533a926cc744a5f06dd08276750196f1bf7ea7984278f789f92dd07e36895a8bfe297ea43d4a1177c0368900e3b969d3083cbe626f0e27e7ab38e185c923dff46d9ba187b2acb9cf4b23ec8eedbb8044b96b5263d956e50cd6240c66d5d96517130c743752404ed09473f05d0004dc5971ff5 00065e20e5ce534576d7c17616cd4ede3bf4f500894850723bcc9f895f4b 95bd5bcff2ac19089edf44ecd703d7befcfec0c5ae9722a462757d79b132c65c68dfe9715ac17cf10c4b46e7f0cdf8bc1499f41da580c70b4bc165672ca2956d3cb4496033a00c289f06170a14904183515ec72104159d9bdf2888f58d5d0fae +3827276694e413c886129c452c9a66e7d09dee84f5f09bf34e4baa308b4627e096c7d45cf6ef45ba1d9a4019a60399feec10fa80e333e2aff1251c85ca48574d9b9e1affb9666828dff5afcef3edaf5e8cae823505a0c73afe76c1bf130399fb06b092ba34ab0ae15ac6c682f9ee8479b065ce75b57213b8aae0f55e4e386de5 0014c85f66fbbd653f1e4e590cffe62c343ba6062df4b271fbd02e5d42f7 94d12602ef343df3188965d8203476aea0e64b83b3612626c0fe95344861d8d83bf7d7c239337999d86b9d2d8aa5a47209bd1810dc55f24104a63c6136d05bcbaba8c79a9ed3142dcf846fa372739d23cafa323ba415ed951744aa6338464f13 +d1afb8965b48d66b9acb1ece674d9548f83395275f2d8135554cfcc7ceb96450d850dd874529433883709483d0743798db5e0dee955a4f30ba328c7934b8dd9207f3c336cf89141a175ebe23d2faed629eb4236a8aea8300604c3eb7704512f240fda66acedf1494a85058dc6a31bf9531958c332b93cfe5545046876c6b99e0 0030ac7a78593b570b29f6d3d267abb6ba7e5870ee1c8ee4f1ab2f141051 8368fcfb4b59c1c2eb80a7718269d0fdb4a103a478b2243d5e7908ab7f3ba53fc928fe5672f0606957897219a8ede5780fa8cfc63ded5f3f116515424cc8b03480baed54d52224c625ac530ea7f7c64255f126ea6ba85367fe2281f611dff586 +4f95b71669fdfe5dc46d4b951b085e099de349fc740535175337127910acf24e9a0e4b2f23196ad23880da47b740d77d74fe9bcfdcc44dd7d8d1a181ac290de5cf4da22d5034cda3d8020bcc776dde8cef1786c9ce4d2c2cfb035da61406af745efb7ef1a55f2eccc5000319cf1d6380963025dcea641cfd15a3106751fec286 006d7516aa040f7d559cae248e485834e8d9bb608279ed4d4f7e1dbcd2b3 b24fb5d807a578ae38327c245148c915b8a2ba02f8e32843d80444e0a23f6a33a67fc971718a121e0a5e54254e4fa8f90965135d252bd54790cd449c70bc00064848b7aff5b8b390a74e5b5b2e09cdc2416ec2ccaa624aa25231715407bd3a50 +2ad9e17780c824c4f2d1e1cbf19ab85638f2f71cb4fa3518f08085b8b358f54d4f08394a5ac29cbb3cab828c5f07f41eec51e6cd61a5f2cf44dbfa46834370cebdeb328fd3bf681e61011b5c2ebc8945ac7a2a8467606051008b15c89390e111999255bfe28634ce9bc2850a2b55a4af1c4c2f94403c78aba1ebc87386ab7b32 00137050d7b455f43a8dc2516cfff5a91062c1a2727b27df41488f3dcf18 880c8a914a8289e1ad59f5942ad674b80847e603f71a076efdeab1873b6d71a838f5d4e6a42df318c756a45476cccbb204a1127fd04e4e1a9e725b4495c6cc6d151defbf940578a63a17452d9813b652e6a804473f8c1e2ac759fcb8950255d1 +958773c37d3eba003aa5c489f72118b3022c52b93399e9d8001695664918b86893f4922c7b6e55b1855ed0fd1d8de5dc61af403ad660fec60d7c44bd0102c069957ed804d0d416facdc1a95355ef58554606579ef89b1842f1055cfa2ae118abbc485356824cc09dddb77d0671cb3011b33bc86cac526e3f6bb3293c7bdca1ff 0001fd447b33a2ee3595b9f885c290d241422afdd74c3dc4981955a7e9ad a86f095a16dccda4ac640723a0f9386a712c591a9e458a5ac1faf4f9504dc33f23c23fca7513d8d2a073a3cf7cd4cd6b01afd755081bd968328658a854c6eab20eeee1d245708c9e48348573a068b882f245995afe652e42085235e409e27aab +9cb2c496b1bc7f040228571e005e7e936e48e8f469e295edf914f5648701249a20bff6b98b5e862603dd9f12bb71c160aafe9df02e2e383e9b8a9a9d700f4425ce408feabbf754be543f52204c849fed6c9d3e36e03dfbd9e35c18d7bb2295f1c484a66e73440a0a5aece5fe80b9ade9321ef18cde3eb2db15e4b18e788b0441 006a061e10b4a6e7001d95411cb31bdea9c84670a59ed61b14fbbb05c8e7 aaa4bfea34adcb463d3e559401799e777684d1b974e79c286b613716aded3061a7d7246f58f2eb020313bfaf087eff21124193b4655e6cd370ea16cb29330b7365f88c331bb9a5040c4e9322221bb9c0517f67ae1d863e728fb12b46725f89bb +9a4bc0a029e97742ed3bca207d5912cb568e4403cda106b00247520ea02008b14c041b8c9b976294252da835f4ff27456039d79d90315abcb0b9b6958a22352672e229665457ec79571ca80447c8ff2a86e6af3dabe7427c8bdcae65e3c6746a56079ce2cf8d22235180f46646a21cd9e86032cfad874cb9c67f882fb037a13f 0027ec31ca31acb4d2fbacb49fc085f1261b0042cc755cc97f9b199e7a37 99b34a7a25bd3882ecc8ac57adc46478f78374dc071997041f548faf09adc0add0e1958e6065a8dc2059e58fd932e3b205c4bfdd2016d22835f18938cb1cb90a0bf1225b97ff062f2f3de6f35dc3a22d72ae379faa270732adcb2bb952a568c8 +8d89e22cf802dc68ff22d43c436c79311e705ff6fd845e77c880f399f403e6d5e9e2b35511553c978171189e288cb2200fd95f84ec5ee9865c0eb9190aff6dacf783ef200e82027fa992741876456472bdf27f2bd8ee55db15408c957a120eb64cd24d299818726a73fbb0697eba726a326719765735b37a2dcff0c853c906bd 004c6f4d88e5a4f4f83196f2dda9dcf2a66eaf94d50c851f59bfcea1d876 8710a1dd775efc1961e7f1e445cef21ffe6297bc9268a7c197c16cad2e4fc3a197b1897714d2fc3a81bc77f6040ede5a02a25e10938fe14c6854887f36711edc6ed084cc43843c66f98b372d1bbda4d182211fef2de21d4b0727ca29de328dca +aa1bf5a79e5339fb9ef6c2817bd95725551d064bc5064d6586c5a879901adf808dc2ef7c78ec3b434b84569988db58b5e8e9782b1cbc2cc7c9b68e66f32d4ac4ebe7e75b345f654c7b8a5e650acc9f170f75b7aaa3957cce248cc69cf93faf8d72abc6fc1cfa9ae2d18a7b31ce720147e88e84f6563b2197882fe302449ac5ce 001aa169ea84365c22981bb766bfdad27e373440850569957544b0f9332a 93cd2463683d2ff047dedf0ce0c9fc36b8183fe273550cae4cedf4e2d1be0caabe31af68a07987ca992c1aca757ec4ef1987039996f067cc4c8c6d2d8d5b9d73035e29a1467d6cbab4ce4a9d2585392c15428af6421507e63c124a6b2cd65950 +475664d5e22cbe0da0d0289ca9a666a37270dc71c81cffac91f6229fa39315c1d55f7e0a89b6a7a07df7d391dbdf8fb7af63d2da46ecc3b60110dbcd842da97f98d2b67f562b0364ef8e1c589519024177c8ea079794f271f6d35554c0e9d0a39062383c95721b72f4e74eaafb6fbfbda02cb670a7c4c94f67b8ebc6442e84e3 004a665b92c0c33a3f8b9eb4b0ec061d40b603de36c87096455102ffe57b a94f6f828c4034a0e863d463a0379641c99ad5b5a03439698975a6dbd915665992e429eda0312447f3f7b5317461bf9d119cef1762060c48d2cdc42162f83d9e496ece8dce3870ca31e546e4f2dd645d61919d597d62f003ee98361997757abe +9e5397d94465390a82a3c07e3ebf21b515776d18b4463aa5810e6b2f96ca61e92d13e034fa853c3fa45411f51f79df6f799a2c6906e6a5b7896a4576a4464f9e0be2b529a43e1f503fb640d79db6b68f3a3a7deac1b5832fbe86673784ff6db1f8438f7dd332cdd1e7ad9df8b6731aad1b6a72bde52e6bc62d80b8da57822c48 000531540d94823e19ab2b95cbc6e7492e1effcbabce875de6ba96f53aa9 aade230bf1e6d29b6de09f3b0d6877e71b4d0a05fccddfc01c767af933b2eaa4821d490d67370eff72f11b3d6b61a7090df5c1fb4b4f12d3c8e143548bf8cad9205d6623789b7cb8dd1c887654c5e63e982b440b363f158fe221427f882235e3 +3cc4c4192f317e52df6f8cefba6d4cd823c942aaee11b9a0ef5de5c2d181073b7085a55805e9554def8dc13eb978e7396044d4f4a14be2c7605998c062095c929b9c23b2b1b2fa73dd19a0c0af44ca4789f9841fa62dee8a5f91b3cc4b3264f5f67334c3f0772b30bd7431c3fbbf1f34318ce1889b6e8a76ce6d42079a451e56 0022a89addd8b85809e87e0aa2c038593ec277054842854de1197833a51c aafbe68dfbf08741b6ed7c304c40b53e49ca4e13a33d24dddb6136655e87cdcedc0d51436a9a4555201b0f8c30d5244d0507aeaf598adc0a15c965f107bfc84f28de4ec98cf73331ef45aa797d2023321741dc48ed10c1dd5137637865d5ec02 +72cdef5bdf710978e0aa334b86b8ff4a58630da314eabe98b4d611aab56f55c526983d54d19bbbf9ddba30a84b18aa0bae9f9503e9b222f842f084db83aa39625403213ca321cc0d9c8a136c826e6ea4ec108b913dd0a9ce9d5b8c7e3af53c3876e56a2037ebd6d99f037a097111c837647bedfe4c494e4288ed6427c15969e3 001df252a11ff97b4421b3a2361db94e908e8243cd50d9179f9e03e331f1 8cacdb636bf1ad1a58e7d4603584e2bea9a24bc91213b1c385f1daedb2927b196a7c5755517a747633fefa14bdd17904088d7433395ebc11b78feef5b9d04036e8f4c8eb33da3dcf1fbe39d9f6d6ec1ecbc823e56559028614f59329eb56edac +8e4eb88c0b2d525b2c58b8e00f32def90e6dd382301de49e0ac053dbc6b61afe926d85193e2c4948f7402a3d7c614cb2c58e060362b0516a1ba4a7425f1b3d09aa20d4c3c8993a387a3248aeec51e6efa8f558dbdcfcaa13ee08413227c8351e3107e9a3e3ac124224aaea91bfe50c11c1c8ae582e718f50bc5d5c06076517d6 001d7125c299ebd0dbcc050f07de931c7ad0450af590d0a2d0228a66ac5d 874f933d661507e3e5b4343b9639bebc14c1c58a899715cd97e236d31011d2cb34957e561062a01e4640130494b30608013aff93e7c6c7240a43ebd3128fb8a439b033623d2a2018e6658c2096c9efec7ef905efbad33aac60444c14708170c8 +370fdd80f330311dbb3959666001bba61cdacf20f72f78953d946fa6cba02d24b5003f5452d535609e489b9434f192011f99f918defe877d51349870e7e75502f61145f7c261dbd2a0840926d824ebe9be3c5a77a3a84340aea930378367ed3615a47e3f792c7773f83f91ebea718a05fc62e9ed1d78629b2c27ae44fe8f8d4e 0021238e66119844b146d40e48341f522f6ac2f9c8a0b33aaf95a3099a41 96c60d8f9c02e6b7ac675d80d1a1cf4421d0da1608e252675e51c1b47aa46b11116cfdff1d8d66b9f38847b1813b2bbc163af4191ba329ee4ccdf22603fd052402b15641bb3bbfdbb852c2545e78af6c7e5430f4ed7c20d1086fb92e658fbb3a +f86c4433787c3ec3cb1663389ccf53d62f9425274ccef05fd14b1b8fef676208867764eb98d16d006ee6ebdc27b8d9a8ddd303d941fdd82b630694cdc698bbe6bd524411907834286c94b24ee199fe6d646064277f244b7df3ea2d9d52a9dc6a33d7c8d6dbc919da0fa987a67621ef0829e48310e0ea2bb86fedcf4effc0b94b 0015e1bdfdacd87c42ed439f3e243abf27fd42e54f3ebdfb47f60dbae5fe a9b55231add73358081267627363942a7dd403712cabfa3a85ec429384b54cb19bdbd26af709c104a0f474261feb834a16daab6c40a4892fb6f6abe7135e78bc1ed593680511f1deb45002df7f7020f921ac9a1549946b870f91484ad0fb6ea2 +4117d593aa92e3eae1124ec7482737cd3573fe5f0f2a5051a7ce86946a2abb9e47a0c6ea75b262689b0b486476d2ab09a20efc2fb921419b1811b51a2e15891ae9e45a17ab4b96c665c6c423fc00e2d66df5804a164f0f3c958df6f25d7da6829b1fe162a0a8cf130858c83f3555d6ad627db70cb41303cc6380f7b3fed2563e 000e09410548c17bbbf28a68c3963a52d39743a4f1ac28e6dfe7a6ede281 93703d9d854c0dcc014c8fa57a619e49f95aef9a4ec111997f808f5dd4cf50f773a9de6edca31e441a9bfb2a6992ab3e13d132cf0b36f7b69d933748311c566b61702334400c6619e4e8af284ddfe7c8722ffe0c361499eac0b8b5e950978f05 +882ecaff3ec8f4023df5397167f238869f78a5c499be19aea85c7486e73f66f0e08e71cf85f3f1b6f6a70796bf46a18e6b555a0a87c2088640ca73051b3dd59ebfef922be0372208fce602d8001681297b285701dbbe24ccb42541b5db4aac1a1c7f407e11c83db15b38cdbc25e930fdc6558f64d9503e214571a435d890169b 0049f5bea6e72d98579b78cb07d89f64503f8759dd7a73cd73713c120428 82986fec3f950eb21c322c002a37d0105c3e127c36e3559a7375699956cd7d7c5f6b04879e46e6e2d7607841132c2c3e1888de880cabde825b645647e44fe085e13cf13680491c62b9a28d2298a3b91caefb69642cdf5b6ede3b928411e7c7cf +99b3b8f876f8359bd6369ce84f9261581c52d744b90261a1427ab9e447e6d833b6b3e89af8dc770f1dd55692d01c8bbc4277a729fddfa7cbdb2ec99133201dde44ac691a77904ca816feb0a1aaacbb9fba85048bc63d73506eb908ecd697caf582747051a3a38ac8930c9a4365f407ed94ca7f2d26913c53f4c010c7ed9d7ca4 0005eaa818690d1ca4838f0bc667be5721d178c3869884260fb230277c3b 928b268b18e1e85af5e4538b81319eba637e529dfce1f4510d1babd561db4af6ebfaad54eac82410c4e0cdf51dbb18be0d1d162bbf038b34c8568f6c612b126cb13797b07226ae112e823c934331c8330cef826557bc4decc468e15c02daf70e +8c1a83023930a85c5b2f9930521b8b8963d5523a3323d87f862a17d3505ccee01246ee1029b8b8c2b608772c4096d1e914cb398f027d91184a8e94e4feeae121eabb504a2a35c8bc9294edd15ddd979946c14c792ad787dc2d4deffa284830fc90b3f8c0ced6a99fc6de7c41b9ed261402a6b3d702ff86a9392731ecc37430c0 00603d89cd2f741d734587e77554fe6bbb1e5739d5ff73084d4de8ed69c4 9057e4d99b95f581e40d2f050b000286d444c2e0becdbedda520b805aec2393a032b1be4dbc10cb9a8cfed85bd51d15905e28c7b9b7c708b1ad16267886499a6abe0ca7d12d2a547b0c7e0a5b3f33518355787d977f863565f3832e2824f3adc +f3c9dedd7115339dd3ede7d8d06a44de66bf80b4888ab7bc386cd40a92789042440a13d2cc90dbcacca5feeec1e0e3c51724146e2c4904ed6b05c7b4e9b49d7f458ada695c5d2fc36f1193329b87c1268aa38eda9151430aa0bc004e5d2a61b9390accfc699f2efabfec785eb34f52b1beff1e4c5492e922acc348667d2a3986 007977b3aba53616dac27b4d74930da23966a88ad98f1769674789c0be3d abafb3d55ae24e8c5cd36d04cef8d8916bceffda3dd8d8ee6f8bba9c8bc4e0d6e3e9451270aec70811a15b8db23777a20097174eda541c6d7f728f8aa58a8346c1180dd2d0462f332528838eb3b18dfbff0ec86eea33580b656bdb0a858e969f +d878c4ee0bd6c84652d7f9e68df7b90cc78776d8d1b60f3e4d7465032bf401f1527ca7bfd4a3dd916e13e93fadaa5e5f20c9f47d12f8fc922a9a3aaeeeef294c221ca1adf7df85b888faec8002f17ff202da1be837827619904121167bee2d2cd694a263d9a99062cada3399dcbfcb283597a96ebec129c65e0850ec4cb4e2d7 0050cd20e7eabd29008cc977d0a17e1195d79587b8f15ac2447e15daafc0 93d2337fc3aace9ea4cd2004ff48222aee870be652063de6b41530784ee880a85a36ba8ad8a359fb98bf732338c68133097c6b68928d2322eb17e1b24cc272973a1c5008a1af0e8995d3f463466a1eb7590f6dcaf1d986a5ac91c35cd4dce44b +ac3c118cc9cbc8eb3b74d8ccc9ecbd81d1996fb25ca43c8a43bffeb244f722b93c9e969241d45d5b81fda0b399f1e3623687190e428dae077e54cad1eff75ec2f7fbb9434bf716833421bc2634885677579c237340f76787b2eb19b446d56c0f2206099b81493349f4db0ecad0e2dbe85dbff7d7070abb3d3b12ef0cec828af4 002dbb24fcaf9f3cd5d50d209937f0e2d134fa20ee3c9c2f1fff3dfbf302 8e8d3acc78394a120892822342535c85f5559a8a1a86ef47218b8cf8b50627d19fe778c49cfdc5e7111a457bdf9fe9d60fd315433afe04ae970e6ff29cd282b03551a4919024d928352ea1ee4377d2e21dc738622f4f40873dc00a929a0cfbd1 +700313698cdfdcf0044ca07bf9e5f0702ece7cc66e35decb28d5f8cb7e7e5367a95cc1728a90cc9a53a2b5fcd4702028b742538e9b386f5d8b4a2411579ed9553021a95bd00a73f03c4184a6145aaa367e3af76659d677fe7a2e98f9ddf4aa20eb8d1a1db72c3f5590598801be7ebf44255fd7376d89d998b7068bd1296fdc38 00047142197d3d43fa46545b547968680ec81688589d1ec8d7c7e90eb969 b98972e946cc944d524f03c94eb6f9037838e934ca04e5c26bbb4eabfcb75ae17f2c051f98bcd225626f81a2d64db63806d43f048318222cad51f10746a816ede4d6ee95a65a1507f82acdf7d3c567c3523d33a8e2ad7ef6c1f7ef98caf7cd3c +0374673e1a685bdee55504ce3cd333f70084dd4ae685464a16924eccea34531663fda60229166478b30193459a3113253cd6494dc26154156252dc6e822552c7c04d790eb9f8fcef2ea8dd79e72f881f7f20fff93cd73ad303c0918ec27c6486c4da61f82bcd55422d16650cc68bfd4b0132c1e7075bbf17dad919095860d445 0031352b49ecde5434aac05f898e6ce4337304845d748f114c14319fe97f a7e4c6cf6f36cf77bafde1803cabbbebe8852b3688db6fc511917a76a5f75a6a809f885d32a6fef39ab132d715b6e4e21118452db3c591317bcea73e038740aa4187204ce5c88b15a2745fd45229786edd6a22d78988c880fec8c4befdac5dd4 +8b237085f135d6e94592f8d855ca397c8c1028236a3b412adefdac888245874f586d06950ee18118f751bfe26f4c31465ec34b578caa44cf1b7109ac4f6eab7f97ff9699b34271df035d3bf58a2ed4bcbf7577cf8e5792b1945ebb9389b680baeb8518c8fdc5540e192aa4fde0eed0d7c82be2e362b286f582d65752c8db7038 00176f124c24e4420f6e726a6ca25f09dfa0c5a37e5bf879e7bdd36c3b65 920432c5433d0812d6f840e6bb82dca16a2ebeca49e07f5e4cab9c8bbe7a1f39491f70bb9d63906a3644ad99f5443dcf000a6348dabfebf00ae6af8f8f469d825e179259524b7f2b6cea5cbae4457e3dd228a787d0eead156ad42b1c035e5156 +e3a086ec15574f7017b3cd5f5a47ab7a73980f11074333490dfe9f8ad8926f9ea7c82271aaa74e77133b1025b0b22a6900fbb71251bb6549341a23d194e79d03462cdad52ee0d1b6f5d0d14e1136026961fa3467ccf0864bf7ae3fcc3b68cb35df7324bd9bbe58fc8aa9f63c19feedf19d935b71bf5981c74fb2a487f84e453c 00755c48c3dbaf71042c58cb137f3632e3cf9d90b7b9a58fd378feef3d19 a14e656c4b5b5ca136179f603c36c7a08a356acefd7bd500d5352ceff41fa023887fde4da2d0b45fb760183b1f92523a0193ba2099fd5e0f1dde460d08337c0c29a2cd268a2c9be9e868223779020a69ddc4635621cfea8e95aeea6eda684688 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K283 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K283 new file mode 100644 index 000000000000..736ef6b09899 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K283 @@ -0,0 +1,60 @@ +ef90f85fbda05e693006e4c64e1dac56223becaf0890f73b5274e6e289a5a1de2c141b825c24d595b3fd18ca855b5c1aa60dac6b5356275b11be670692cdbe5f282f93ac7b2e410a96cb9e9f80defcde98f3449f99e192bfd62040421a0ab8f99acb85369f25e5efbf81439efa8a5e1d9cf781355a0f47b037b09fe4086389a0 01e846c830a8ec04e8572d1a9d2df044ab47352fb346f67403a3bf87243871b164511c53 915a3625eb33a5884d4a22cccb422280712a56b1a0cd679a19af43c2fb18908ca4cfba3b57f29bd4385565f33a6db76e102325d80674ea1cedef4fa77461326772b79de34a21eb2aa16da000469f218dda903b8271156fb178e2120c68da98e2 +a3ebc17c867cc9c7c28797f6364f6574b80c7ec5b2d8e1542a6f5db8568c15032f92cfbceefa3fe4ee654f690b0455ee5d38dd84bb8665ffc1ff8c849bdbc4aa0ddfdbbca4eb37972fcbcee8cecc1aae21ec736ef61781716b60247b7551ec4e552d0b59a53cec5964c67cf7988787cedf769eabcc9cd5243f58034d96f0e43d 0101c5ed48231a56ca0ea85eb45de0e395e6df2efd4987a226ae36489dd8b2dfbf7c465c acda77e7c4dadd4bfeda4d7ad15ce0e045682b6394dd8e8c87bf34d45344ddc86baac174f878c176610d4b03aa28384e0edf538d2ec38df8c6700b1bf22406761378275ff02468a4fba3ec9a916e0ccf3c1f72ba8279bcf7878e10ba8fcc51ea +60269efa4d0ffafbbc655f6f00578eadce7fc0a7eb7db923dca49b6f2bf3e13f7f829cc6133e022c3c92143c075ab9ced0531a91e6e79848194ab98bb852f40c84e7aebe71fb8bc0fd1f97ed5bb6bad6783d8dc048df42738e841d978456e055e1b8a781dfecfce2218701c7af77e7894ccac5bfff360aab0b6136b978bc39c4 0019679dc589440b11f82b3716e5b2a2bd42c3b1c83e88a28e304cf5148877faf760b4de a5af615d897045af586e93526a29651cd179a1dcdfa2024ba17c1834713344ba255cccca26718f747e53b4e374c387370ec26284ceabdc5494ec047797ba7600fd97fe5030d9e7877e371a94d4bcc45ece7cc0bdfd6ccd3eadc33d1da4c1c0c2 +59d704d5b1f3a0605f1497f22f71b8f45b26138bc86371f00a4517554e7f6e7fa5d35189fc656ce68bd2cb8510fa3e3c3df815dfdd749b2b6ac997d443f3954c7a927e138b579801ffd035cea90840733e7884ccfe43d8d3a4a26b430673274aae312abe4ac1e1d7c67b73580fedf2d8de46572493c9205ebf0e8b4d75ccc88c 01703c21fb1e09f8947e12fddf166fda6f685221fbd803d75a0ae377a54a1e494e6c5e7b 871f44c0e486ddfd792d142b506ec27f33543a32be00b28c7f390060f7b15e6271a6994f4ecf9687c58f44a0d5d9716006d6e96cf70a7485d68f041caec602f40dfd135cc0abef2f235f13bae0f6e607ec5b5c3f2684b367213c225db653c3c1 +12c8fdba3bc5f68e13f7ff8e7bee876fa68a970afc6924314dae0c2482763ced8d4752cec29ea288d350acd8a06c69289ae41ad345a1b88bcccaac903f2bff39015c289a8ad608606bfd65270a7bcdb5fb10c89bbc2d16dcb91fc9735d66103f6b1f3575622cf4d8209290315b033ee1f79968939410f465a2d37add46af2d59 0071de8eb14cbfb88e61b908990ce08b81e624ef4f2cd9cdf3dd7ca9097d5ffed9ae9a71 b5cafa893991dab9e1482def068edb066a56a264eeaf0d7252094cc67a1ac6b0f54d40da56047f9a5e421eb7a17aa0b7186624caedd73b81c0c0fbb381c395c1464a7a03fac6185a3cb4b7b47f0bdefa32d126077c9e6b2cacc4ce8d9a757079 +26013a3ddf687bb2f37d9700923906f118d5cba5d8ed5113a0e3e84cff00918125108f74f4b243e351aa5d07fa7c6ece29f5700f23e50286447883d2a058c3258a12e4ed8770cabe627ebea7ef6e8c77811ed7d9a19c53287093e39226236587ddbc63b7ad5e7ad9895c64d1d03ee432d45a067afe27d4cca920ae88a7a68db1 01d156eb15762ed00c4021884adbfc2426e910b18a5bc474268196f4b74e593a8f38702b b0a7c7959b7e4fcecd859417aa9ace60b54f903342557ede99ecbd96462e83b51d203926beff8541dc71859c912c92660a3576814ba0641e9b61a08248ebe243a90287872d466925282c26f0917d21d5efeb22166149a77803869ca437f2648e +c4dbf70b9a2165e7279122460d05ceb8e43e03fbe2ae7c314007fe2b1d8567cac727a10fba5cbead0ddb167d387da8e8f3d6bc0ad851cc32885809d07a776fd4a95a979fe3833610af89df0f454d9edfabe12495a118fe83add5eabb2acf54ba7ba7c4be20fc77478c0a0f0726c4e60317422a612a234a7567648603b63f1c12 017d6eb1219cab8577168be86b61f372b27ca70fb1f1a767947895c185344e966db17aea b2081b86087191d2d68b449e9010206d092c6a84366f793f05130b17407a4091e65dcc0f46f5c22627fcaa90db7b49a01884adfd10fe24a626966016a0b8e2555d01c16320ee80d7cb542d57baecb14151090726553322feda3934fe2090da74 +b1d53b6af1face9b59af11c726b0099111d1adb3666209ba46b1744a528ed0f72be5a1b82423153b896384faebef0362343e2a4599803c08b8513708938aa8a498145fca1c63ba41aff06d1a18aa2a045fce7fcd7e5552a2b98d0df97b6876f06a9cf52a7a40fb737996adda97c3cedf7fe421235ac6951060eba9c0377e72a2 010ede9be6615b3b2a294d67da78127ffbf3a15bdba6f4fd78be7a60415b5d1a097c0cff adfebd8b59e7efd60e87325a3e472b2eaeef2b46aff358c415f7ddb8bbdcf9dad3957ee9397c438cce42ab96dedb72fc0fc290073e1a6f51a214da4478d165452dd0e2a5288f76ffacd200fb68723efed951d9e0343ae03a3b942c42abc06506 +e78f538b1ac21602b00a09e3db243ef4803b447329c94a1476cd91a88ff790da71421b60092c8a6e55327c7982e7655eb1fd6e40fa9b9fd2f10107dfc585994dfc5bc2143d18794a39f7f69ae679b27dd11ed22040d5e93aa83f71783525a4db0c3fd7b43e57dafd0033d5317680df19c2ecaadcb37ef896c61a758a5e455206 014f237cface123b64e8578ff33f86bfd2a8181b9c81f36b9ca31e2a446f0d91dbbe2249 8920154ec7dc73da801caaebb6a80525675375ce9f5ecd8a98f83f5f859742e8484881a6e415efcd3b191da63b80bc7903310d3220f7fa82e1febdb960ed4249469a475e22086e071e55ac9bc54080a62fe65da33d676691b633a00ea2f8478d +8a6ca8ec436d2c706fcbec6486b5665b21c174edee7ebe108211c388b1219a8224179f7438e0bb7d6e41ac4a67337b52d4cd9a069fe6c88960ae20be29c8060efd7c62cb7a9a37136a250e68f253e7f27755df53ce7c570135641ad49b43507e5483e17b919cedffdc0d4913b1d5e0ca0629876c0a551841a0fc2090d2857cce 008dbecb26587cb2ed7df2404e680fcfa5bf8cf6a58e87a350a1600211b3c844ca86daa5 8b8106db473652ce6fdf94389b315c5c17c90b53cc28c69d0d5263438e2b0d0042f77bfe402b826bd8b5abd8c656353002bc142e1e2ef1e65fdca5725f987450d48b9cd81c2ede4e1a520290309c07cee6d15012d74fa523fbe1da7748c5ae62 +95bee02b423d2c6e60252da4632f693a2d8f6597b4f9c6e356f670c3a9e4e80063e92facb6421d0325b99dc150464ed2ec1d0bac72a042b35d56d33d2fda686a75d582d4756522218b4ddd25ed45503d90d3d185cba6cf0ac211b22aa4e1318a8316c369186f7130446dafad64f7966f5414f43af37a87127534060a23c6165f 0191badec2d28cbbe62c072c6b57eb5d4644d0c0b3283951bb66096cd15edd43a1bbde53 a9d4de00932192b4031c255e77f240b0c98ef41c75429d63eeb1aabeb425f52b46c22dcfa442db2e682dd31567d6b3290c4e69bb3c8a4e49733e98e45f8938850d2c8e49ba56728e9ce44ea253ce079d219c36bc294618ba2473e5872c375138 +ccd7f7c0e04d1ef9a3c5617d77480bc624beed6582bc28e9e3a369b12144fcd96b735ee41713f4173b64b28c6102d82dcfc7876e06e76fc497d1d238bf6d85bb5feca630bbd0c0f0fa7c0c72e28e9259087698973ac66244bc6e69c04deb22eaeaee7b20da239ab6333576f01349c76f594498620933b8969450ac2bae66db8b 00ff5e3d66eb57fd35ba4472effd6e7a016ca461e39000a7125e99080f6ab6ef4380dd7a 8ba34b45f1ad58e4dc37bde1d6d090d5e48776c0be19ea806fe3e141825d7ec1ff62b075b29347aa92dc9e12cfb1c19e1313d6eaa4e0fe8f58502fb4f0b0f24c55260dfca3f4524ae1c8d8f6fe492a60c63c6e03b556abe9ecefc4c4b164097f +65e9124a2606c8784c9489add2999f4cbe6186395df20838d653b263a207ec46995d2685b55d1874e7ef05a6a3bb5b60a7be6751ad568cef1bcea2debfc494d1e2ece0dc8028c88f1b2c6e4ee26b639c5e81f6448bd25b73ec4608a8e8cf4e0155c29b6f0a62781493b03bb7384c9808529d5f87da6564ae196a365bd282f46f 01f3591eec4a8a3fe6ae6debe230d238a6b73cf3791cb735add1abee64239bb100f15166 863f07923e85ad42f94514cc9065085bfcff85647009d7280ecce6d895406b0ed5d5e49adb2f3ff3e9a2171babe890ca0f596a90c83a340779e7571106504c1547dfe645f2e8aadf936d887d963d7b7ae0a55f3d08122927912f40e004f4c6f3 +e793c60fc725fd537d5fd38e9b4fb52e268722ae6bde5a058de8d20db301f5e8d8e1ad85532198835a04b76f27ca3c972be5617a55677cffa8219eb64fe53ced242efe1b889990979227dbaaa15ed39d3b6be8c5a3237ebe12bd96f333d947f80048463d3859e34f865d83faf03894c2243a06cc96788ed952e606c2d8948271 005af03cdb45961e7ff35fb0146904ddd6c2bfd3cce814073d3aa56eaa9f13b4f7423926 a1a7325b42dc7630c2e0798a00e94078cf25c54cfc61fd80415b3c9e64594564ee544f253833a69885bbe92a829f32470c91f039027e05e873bf0f2e1699cef8b6907f5d47faae322957d1f22b0b7466443b4ca7de579beba7e96f172f55bd92 +a57682d21cebb48190199e9f57493696eae3a59acd22f64d5ef4729decf6c2615b326817a6bc118bb7234bebfc7276dd998838c009a7348e46431574638dadc48538d6048d572e50d9c5974d2049ebe1837dd857bcd1447b1514b62808a4e7a88162ae1bb08a0f6d3db6f25874c6cd0cd4ca6333f1bd57bd192ef67e4616d182 01ec9710ada06e6270720692a06d488ae2ba863b905dd2fc323e7ce68dedacb35fc8c7d8 912f1846fc7b230c2e983d0538102b0344c6421fe6502c11ee7a032696b1d20ea63318120e9a605d700faa0573180ece17c7657882eb5d2746ad82e9c93e4a7c92048d097bf1ca1d38616b62d9cbee1fd18da1f5863a0958bb185a50990aae39 +f646e7334e191c2bf0056d3bfd23f03ef7f0777b923f962519a8399d311b8f68414c689ca34b96871fae99eb7ea534fcd83e788e56eeef817cbfe33677283c736b99bf6a626f9515291e842bf99f694e4e8aa7c9911c591a87d5f112b3d96b064594e2b368e6d1bf1a1cd343d54916a66da22c26355266aa2884120fffb8b94d 00668de088c6913640fbefbe6d2c44ab26e481802dbf957044a4957c3c5d0a0fde331501 92a3e8de91bc31513c00fd9e99f7809f96d4b7a113c9b62fcfbfabdf09d09ba3924912cc2f1a8345af87dfa278c45dc6109264817e1bc6421fef6d3aca19994da0c2bfe36d0572a7e2ef3fafb0738e2d64114750966dd087159affa3f3cfe86f +a2d7e69ea381d3edfde4664c56c4cb140d01cc4425df757975cedc995b89640dc016ab419b137ff25a6a6d64a309b23890439d2ba157262393cf93d15ca1b1ffd19373ef12367f8898aaf56d5544c2f019a4854f69b3d8d320e03135bb7b675e588a5c3fe4b703938fa0f964916501297cee2fd04af767155c7739419f9dbb7b 00e6af57cf47de1e6f07041eb5e1a413fb7ddd82f8c7f7ce957eb28a118004930bec4dbd 8c2d5b78aca99bb70a0f09be6e0ed45c32b3dfdb7acea7eea1ee15a1124f5472c0a6eaed9ac35194f424abadaccece90120dac912ea88f804b399060216c53f03bd3bb19227d6d5612ab49564d9118e46d8a5a6ad9bce5146932fece4aa1be1d +7088f60e9375ec6a42f705f851fc76cc833c4dcbb3352adcce9f59197c1b7121e7aa661c4f8ad9f4ef280af3a2981e90c01291f7d1cf7d3ae2d96b37fe6975e11b7c6c02b8ef044d1470b1a26b9c72e8c4e7b1dd83c8acc9542e2fc7d211b87841dcceea2ab8128d0ff7bb622b60faa4a89ea7008f7d55f8f9de675bc4596fd8 019f9b63fde8c6aa6177f2a38981505d04f8ac62bcc21007b05615d028cfe851ab9cbbc6 8e2cd667b5de1c14836e05aa8ff2589ed1a4388b8f03b3545cd0adbc53d649a26de8ceac379ba34944bafc479314ee0001d9e0682d8781594332fab43876af238f230a8a0d542864dde12ecf7e7c1e046b3d8e03ce345dd50e952c98f33eb6ff +ffd6044ab991849939e8a29184b4d0ac3e07acb63c7e6b886df9e8254073fa800d5910b9fe34fceb547565a2344eed4de394ce2251ed51ec882ee9207eb7340464c742d9d140fa0964f6bcb1efcc2d13919af4f727953de41b20728ab975c1ae0ce784865f23ed1325c68daa95ed5c932893610179be94f13b9a4149f09833b3 017704c1f436beb52f7ec97192e23e206ec09f9e8986e06bef71467c192bad6f0066b3c2 9276e318d1e2d0f32309166d6fd25d35bb0228fd26c12cd1611c55e8a9b9500c3254dc2662f5e80eac4a6e11a556082e0b50a1cfe41205dd2746ec7cbc7792df685adf09c9d1fcc017c7e00c3842e5a4bfd1204826bee798c267bfba30af077d +c9f81c9ff7d80011fd41f2de97a6c1e6a22cc2da7b2b9e4c50e1354c3e139b44529ac786ce795fc501dcbf11a935d4728a7bba44b4e86b5e5990fed4d3e24fa5ab6f303e1842918f156e00dccebed6897c852207ae5941c630014a41696882066c2b296d39cd8658cb5830eee78e29a00335a99a0ba90722ceca5a2e9a99a2c6 00c7d1ac8faa689698f5c6325a3b3f35e7730bdbddabd0693f2bfdc5c838bd62f84508d4 acc5287d5d2b8002790e787ecec2ce67c11cda1ce9c31b2f3deb528cf8e63f8490ed6b254eb89c9beb8a26d4e23a780109fdef2a42fff7c721473007b495c321968e4ca1ef8a961d5c20fed61a1cccdb738ac84140bd4f6ebecd8f59edef94f2 +a60de761eb32490184dc1d29e21fa33889295ca587b994746874c7289eb9c83e9c7bacbb4066c761a06b65ecd78d701bd41f305cd7eb258c630f3febfbb0a367ad16737b146fd793dab23562e8001cd113135b1c981d1ca23eb3be0fe3e24fe3fe1089caf9fd8f4f0d1f90dcc7dbea4a9e2357793b65daf342b8e6d109c6dd10 01a173d158866db0ec665ee632b5fc397893f6a44ee17c348e7452800aadd8ce676e7fdc 8c5da4d7371aee4e956f8c2a495feeb5b6a7983e20c3b7513428a72ff2fccbae3ff2023f71b24fb1f412b49b6fc04ca510efa0a3e7a81be2b8c4a26ff9bb0b09db24d209229a6b9ddc768f0aa1b579b9ec6b217716fe9d6708086520597e51c7 +2cd0320cc73120ef13e83c8144b270c9a1f2049a9250ef7ee83ccc7584025140a51e2227a5ebb824deff55b3affcda63ecb1fd3f337c67c08054dc82fdace0c4bb9cef1bea9dd792635f655363d05903cd6b5ed50ee669bcd8157509366cd85aa40d19593265da26e5641590ccf04672a6df52badd4b99964a8643d9687b499d 005523cfacf4ed3b74ebc30f608292e45173001d80cc801f729c5f71fc213b243f041ad5 85b7a41571b278c911452b467f52d05b0cca2ee28f1fad5762cf6ea575fa3dd934ab0ef254691e660d0eb0ca66157aaa053436da4adcd2d2a7507d00e38ccb4da067986b6dd56fa888e47c50fab39b068e13af03bb8347e985be17b2ce6e46da +a743d8337bdefc4753f937e869a36439da1f8c75e1278c3f6a4a969d93787dac93293818b1cbef5b8636e1a6cb3acaac1e15dbe0841c8001512b689292f3f4805997ae26ff52f7fe1842512a020c448ed01af2a061f3638689446ed5f6bed9fc70726ce4104bc11142de63873fa7039830223e8f152996388417c48e0c1fa81b 009f6bd008c04b8823ccc3ee7d5aca535c211f35e9d9e7cfaec518b98647fbe6d28283de b1c73b4ae37c0403a9fd910792bedef2138da6dda51c4680b03e535b6b65c1d3d4a77cfb3fcb2db39de342be2a3daa3409b13cdc8b4c0e26109131c9698d9ae456d0a8a92ad7a4031ac30667e739f623e94963d79d59a7c8407c0194d72744cf +6a7a3ad614a3a09d2dc5a80204815d0c6471057acc0fa73f3cbbf1801902c3e1cba3c1134a79a8ce61994a94a5afa85ae1a44b2cdcf5153f8625713c872da36aba0afcc5c2f26636dc3f60e04c256a5b023e20e2e7a3f7305bd5b3033fcf05368589f19021f8c9096a88679904b657bbe5b9bee67d6e53d176fce1de9e54c64b 0150d2812505c82584201e93f6e0cb875d29dc7bd99d9c0f98e0ed20128886e67e1f1071 819143abddf101889ae381de7a2a5452ef012f873d55010852327e05146dc968d165aaa313ff7ef3f96df56b4363baeb14ed9cce38fbc71439c3d2775d80dc53ebe18c07c3f35a3d738203b4409af5a7c1d6dacfb9e2d074454e49eb2bbc10a9 +65bcd77a3ab345cc99b9c1300755288102a6ccf140bc7d1ad25df246ef01fd57a8614b352033b88cc6ffffe5b38b99ecf03baa365ab5529d6751a3c020d0198561969aade09091434d84ffe13b46df043d0a61e20a08e9c32b646771fea1b29e202d40aae1c7079873c3af494ecf6ef5eda855736c9338b4a5c29a086a8266fa 01b3fb9e1ff70f94bc9d7742ea535ca982215af3df381b5ebdf1db40c7c849a7978ceb98 8e8e8dc801a51959c8b588725aa937f525941df3879cba3239eb2ecefe43637da3d99ac5f37ff3243fbefc88411929c612b0b788028f3fa53fa3c44b951e1235b0989a4ade3262b5da3b321ac0746a53e2b72e0e72b881c025c458fd19236510 +ed1acc360d02ee6c36bbc223d91bc1d2009a3e8f8dfc4c3796cd8555b0d2b46716f4c8058bf34c2d4954e098274ab9c2cbacff46a0578a14e77fe104196cbc6d2753e3bb5422b8b79fd004ac0aa920eea94925c016ece16ed4dea916fd92563ec65692a61b28ee84bef0007120bb1e31bb75b8ecf68406a71af9a18b4edf5320 0147fa46fccf0805d14c1b84ea59bb8b8283d54ca0ceefb29b5585e7141340c55b7232f7 a5c84cb023d086a0aed220c36996e4045b0c90b43b846fdbfd752ee62b56f9ad1f820cbdc759eda6c4075c07b6587d7602a512fd3119f5ac092d1151071108c97928aadf250d789f7128a4e9cc670e2831d1acdd49ab08619af522740ada7655 +2debdb95a21d72b69c545988727366a42b819ca6398a82129c5e3772aea93fac0aae9a27b11969ff0ffb9dc0301132ca2452cd863316cf24ae7696422d4dc68e37316161abc146e86f04b72d9a27a350d8545cca245b2be43c33bb822dd813d13e08a718f784845df8a4ef49b02529871ec76bb3fc1ba31089359f2ede73e767 00fae097ea56b35a517be5480802f450eb832b244558d0cc922cd4a5b40b84d02ef11216 99f26953970c730aa34e392178f31111ccac36a34ad4dc100c3f37f3bafa3c02a872629919e0d6597e6e43fe707bdc7602e0cc2b4bed918c9812c618de7d8eefa978ae2fb1ee28aec7acfaaeb68af94ccc63fa9308f13ccf05534ace63254d35 +e4e0c6c8fc01244abf81e139c961b6a6e2d95de5dff1083e8a48b40e3e5b9ed909152c92b1cf2263179629cdf76ae553b58bb2e9223ce4f9ffb5f170f5f0c5ec97294c34a7529a897e9397f71198cbcd68bb4055cb8cd6b690290761b3b73303f82788379df145358afe28f2997d191d968929b7a4b9a0f6228797dfaa17c613 0026cd72e6ae19b3f4c53493fba1e8082a8df1fb7da6dc111b47a41f713f49b33f618d0c b3c540ed75cf1008c403483bec33c21ad59059c163b70ccf0e849ea9cc8f19106eb2f28d8134163341f514bdaf6b2ad80d01ad67aba6bbe0dd98fbfb0820b33985e36901a7a2851dbebe2e3c5cc679fc9cab2d74704d6e581ef05feb93334197 +04710947b7c90855ba4e59107b919d4a1df22b503c5c4c33b286b6b08e451e6fbef8ba40852f9f0ee62c9217abe6156bed46ad6f0e25f70f528f3a73d099338c578bebd6879d810e6e173c2b0af1f7caacb3531ff0e6a7856e4c84db355d110febdb21c683223eb5990ef2038d462ddb7962bc0feea5f850954943d53041f66a 0198e13c7d95bbbb6e226688719639bda988867764ffa9b029018b5547850daecf58fe1f 83be542ee15a1e6c4b65c9dfe9086af64bf89f2332b2e4477c78b165051e26ccb5e1a5f494df0ec81c5bb8ec2ceb463b0a756c36f98ec90dd35327a4c180f1492017fc9986c60c8b843ef96d05b867d9e24c44125d35a36cf044ad896a2a2079 +c62d07bb1ef756b6b2fad355c66b5be086b6dc387b37cbc4a63c841dba3fce65b09d3de8f239e3649382d172f065b78f8a53e0283cf345de06b4ee0b4b7d8611bfce92a7d993b1938419afe817611bc6df3ef74191e7e39ca2339fcb5b5cfee3166d09cd52a1a7d3779722aec328d326a11bbafb6aa417920225ac453146b9b7 019098a39956747de24ded56435fa1e6c30cc2b8088fe9a75f5d07b2f5939c7a60db64ad b79ddcd113dd973b92ff8440dde5f865025f69ae529515594db79a4fefaf7b47627779ab7938de1a4a520cf1c6a6cddf1914f893c2f834dd33dadd513611eab7c3bd2bbc6782193a17e13c41c04aeb0abff47698aa85d916efbf5e5f24ceb53b +e4d8d49c9bc566261d9134d5e237d9cbd6b67d2619a9bd06b7c9c139e091aa10682cbede114e1d4777d9cd67a16b7d64278e99eed62bbf25ec5a5a8fabcb0a3468b0e73fd02ac6533e04b1110d29da3e34f33eaa228b78341b357a5d892a61beb2168c3bd5e66bffe3f2080a1e246f55a41ebf9d579e188d16991aa060460d6a 01636bd2be121e07ee83ac5e880cfdfca6a56f2b9d0badff003e872348368c7c2cd96b6c 80f457ac1a2995a945b2b98b778c3bd9ab2ad8e7213ae5462cb05f6f4d3c653c366f01b6a22c38005ad2d6bf8d6df2c10319225f9c47544a99d149619fd0204a9f844226636a1a5b5c61f7a3187bd6e26e9acf804298540e2f864e9e1a8acb33 +2d1358fdffc14630fbc421b443d3c22ba10ef34f15c6c5bb3c73a9b8714e4c411de69b9cd6628fe2eba5efc4862af66ff916505023e0514f564164b389ea422d0f1beb92adcd65baf43556614eba25e43852ba65af78f62d64b36696519ef8284ef7316ea52c365b99f63a39e6701f81ad520d7445cfc0113c38ecdad4bf5b7a 015e5f555119c19b055b15b0c0d2813068bfc184f864e250b202384f5728bbbda1cb0f5a 8df1ff5f18fdb89299d6ccf177b8d1aa86ea3159da238435573eb59a61c9c31add0f307de4d88e3081d513902e48cc8a10849c6534cdf2506237fc4243b17deea234df68ec44bb21c7a44b8a01e423c78107f8ebf7bd2604661b25b4456a0ad6 +d6336faa5c3e838f4fa58626eb353d4cff9ba8f0aa0e6c3d0d850e8b22f5b0f047afc97767f1afe2040b85d4e401ba688a4da7a0caca7fac450899092c4fea789231ba9b07782010720f45d16d353798867dd7fef4a324520014ad5cb32684ec50cab742b750e05db040ff51140e8d740f6774a059feeb493b10d8ac722f23fa 0190c8f17bdd38669e345440d2c7631d67cee9c6548c4e7b9452377adb9303430efeda0e a150a7706ad2e0148a84ef0ea7009c0335605c7c9aa01328a2e52a155eae7bd1509524dd3893c0b66b532686a2359a1315f10ebf8244a2a8389b691dfd2c7cf049fb6e58d14f893bcfb1d4e1c52220b8b1734c5536b17049e520defc372b03fe +07384a3f650bd270b14ca388a441af201b7767a2d47e9033f50cefd3af8257ecb38f5267e141cbbb2ab7327d8fc78cf27198ca3543d39553e178390bf1b921618432ad895e4f8153783a7ac22f4ca3cad4560e64f1ee4a7bcad05df98ea49a3847dc2143b27c243e48be59c869a547988e2205358e8db98b635ca21b745df4d2 00dbbc2a0409ca58a9e39e33b95fdd15080443c1dbdb5874bee991bd1b127047f08ec9f3 b96d2e8c979b9d2e3e3c514051f2d046b8a5e1b5053dd1a6d00ca567212f020912133c771d558a6fd9e64b6200c4043c0015a3cda605c018862bb75938e8f29913502b76592646aaf972d0a10dbf08451aaa42777a35a58874968fab53b68d93 +824f26dcb4ce0ca020982814d5c727e629cbeeaa818c49668f8f6d743f0d0ad362b24cbac48027898f386889ca5411d7d1f9afc69493b1d9ae4d7b695c9fa0a30bb59e6be2cbff79231767e96cd8bba349fa2f97955d56f05430ab4ebd007064e3d5add94dfe255b6deff19650883ce9966e1a2affaf84d9540f65c87ab1f936 005495e6c59ca1873f36b756579632fd47f9fb95b64f52589d70f2739aa6a3bf8cf8c198 8d7dc266ded2d177d01ad48c34187e6fffd2b05ee4786865a34e664ffb6e52ca51ac0231004b18dffc97d3b750a5ddb114fe7dc100a5779bd8465c10ac5184abe2e3d4531fcd51656eb6a7a84fdadafb41c5bc79610ecea5ad43054913a04ae3 +07de1e4bb9be15a710a74806d4447b093bc08ed04392d1bd5abb414f5f4b4d9d43520d0e46fc81c2a97e71086b28e53242449ed37fd7ed1c5772dbabc430fcf82ad20437b38eac15820421e51912325c872894452c3f8a10ddb040b35308e583c155c3707b52df467c4945f4e1071126ed46611a3253c297f5cbca9e27f58448 01724987c9b698519b6c225cf1261b77d0300045e5fd774dcbf13f285e6bd74512cb7edf 8433f6717ae9821a71f2cb5b56dafbd6ba4026f7eb9a2c89b203d8600cfd9142494f431d937a30409e66ab073cfa427c1797245d45f30601a79c72276d9e61d422cb3b079b96cf118e966622b1034795c8f31b2f4659801f80fa6b5eb27a9d6f +1edbbbe71057bf7d0bfda922be21a3a4dff57b017ebf6fa99651246cd173bdc9b11eefd048ea599c1f98e907932aa04f64ed0a007831f30daf186c88807400970904d6090b2cf181e0f65f03b4234aceeb420867812562e47f452152bb1ddaaa48487170d06e47c5e9a7c0faa4fe494663d2fec22f7665ceffffc214b21c6b8f 01a5489091cfd51a0970508ee3e8449081ed175928ff8386592c83043a7911bbc2f8778b 9959254a0513eaa03fb99e4880238ce7cbc08566122a2ac37d037b0f05c0c1d1f86444c216a06a490a058fa33b29664d0e48f496b2f37234883562361cf27938485e6c5ab53398ea44a76cc2aa48f7c880c102f9337e19199dbac3b640dd2ed9 +db5cf1de38a5187af11c1f0f19a36db52f8417de997229e83072fb51a3b7152a3b383e9919c1b8427582e53d4e7e25433d46cdf01492021c237ea0a87d38c71634743115a6b2aba66d3faa8003158340a5078171e0bd55a6e5d8c7fb2631a31c1204e1479bbfe79ac70d5e5823af502922a900576f0088a33e42ec3e26c0089e 01a45ecda0788fbd7cb7a716dcf4c6e83d4148bf63ed58078690ebd238c00329c462590a a17e59d2c414c8bacb04d012c72050f08b9d2e1658dc982a7d78881e797df7fbb3fd9729ac1df73833192ce53c5d1ae110c8251bf2b939327566aab677a3b77f17e47640f1fb41c7b1144748358e417b07b8eb0255346f98b66c3e699444e7a2 +4adaa850eec8272d25d76600aacf2cf66e754f6c5efa65c55a2a31b7bc69437d9a7e47c6f51c5da93895a45221f5f92c2e20ee6a95eed3cc7249688261a35d82872284900eb54dd1df6024ec48963ce43e8ed8b8cca8ed22beee8f0aadeae53726cca05443316537840ab824cd1b595f36064e9a19333748d4f4972178e7f5ae 011461776c33f20b176dc8f2b0cb2446a9b69e55b6c7bc7457a7fb4639116b452b79661a ad5c8c7c9563e04fa7721c05c1ef561d825e7bccc6892ebcb3a5f0d8cc42bec7abe339db9da00c282798348bc434a2aa02479eb47de063891f3e48bc95f58ec2b1f6050defe4201eee4209232828d3c4ed17f6039abb27344df7d669ff3138e5 +11d212a99c39fb5e4ca0096bbe6c81ae1490e1b8e07374b4e773bee4fdd24a3c13d653919db663d2c32aa4db140c4ae2d472d4f878946e527ad33b3dc93012d97458f96cb622ddb56f1ce7c2474ad0d5291dc35545de47b7053d137a8e79dabe06757ab53e26eaf751111bd27690e57ffdab5337eb6f81889e9d1b1ac729012f 0025a65f627db2b4d6cf83c5b0c00265b9b63f7656c5e3382139e4992bcdf3cab502844a 812517e5c4d83be84f9d00f10608487a4e1922e17f40b696f1cadedb0c20130b10c665eee4ff9ac51e15fd8d8abe7b830137870fb3c694f124e6864dca172e2c1397310c26e05dc691a11a9914694ffc24558926b770efcc5092513b0229522e +9e4ec74c09528fdf3153a0f6955f20c70915ff524b2e19c991ec4c5b41ea9185e3e876a02ed6f27c9b3479dba951bee8680c4c99be1a626808114408856994be7444ccbd5ef9859fa479b1050bb836034e20c531b4d618f5843fe1d4b613a731895b489a2363f3f5397d5ff964cf037e9b11e3ff5e1c3d403e5a46b8387c1241 0173b28fc29f10245221a907778708b3ee62e0480aa9051d4c3eb4e8d552e6aad5509943 af4425bb08069437844c366ebff1724794ec635715a2399ad10bf783010cc2a65698754d228542be6b38ad1beff2f2741505e7352d885a052c75b143cf269da051e0142a182092e555489ed60e4be8dfe807a661dae2f56ebdf84b6e2bc99d88 +5fe8253d2134c434cb0866796013722e82184638b024a5a30938039929ccd8415c71f71f239c5c5a81f7a9cb493dde209f189bcf766c17c6d9589cd0c7de7f07ff9f24d2320669b589d084f8a8ea71127b9760b7355b162616afb34bcdcd416f1a062035102e29b70069b2b4dbf70179b8d60bc2ee5a455efd40194533bf560a 00624616adcd45e1fdc6cfeab2b17230d73d91fe0b39f4664f3c6891554f9b8e238257f7 ace4f2493ab868eb081594259e3d7010664e79ac268aebe370a5237db6b10309213b24ee0cd7636c29925f338b93f468049236a17b764d6921f76a4abd08326150da512d85a9723620d43e57ddcc837ea8f7b31cdf79d0497aed7f72c8a1e792 +db49891838fe23f0530abd4a4fbba5ea970afa5747f6a0a10d2cf4d841581ea2178705c1203f00cafec91d0a72d25448072c9cf7d7ca5580b39f8589ec63128faa95cb0689574a6bebd515049a1eb9699922cde0366b5cd58aa8f3d3e847706896f7e1cac667fbfe94b2eca9e7be79a810806ca4bf53f219bb30532ca2254c11 0199757ffaa2c59e198d66824eaad37cc42d49b2e241b6a60382d05e425e800eaaf32470 969df481ad2e922a41e47c2a65597255afd4abfaac518a9599499d37e78363d608b29ca5935c4638ba8e062f9a8037b4191058238db7a32066b3d86d9baff6243855dd6f1a4a556bdb4c92ae6c30053ca0758e1ef9ce09240e53ede515ef9a73 +29d385d09c1142a7c181fe4b6e6132e414c15aa8605b44208c0399464613b966edcc2d46cf203a3f85d943d8eae658695dac74366224a0d0348083bec0106f5eb8809ae8d07f792fdd7c48fb1a25d5ef3bb9acd40b20c61c821024a9acb2ede321bd2d0dda849c22d76f421cbd8d51565d3c4266f666455ca1c0c3777aa44107 006e51381dcf21050aef2e9b97e35303cf3bd91956854ecf9b6b9827871d2efbe8201c5e a27cf972003592c570c82d8eb2e5cd23c4c71e8f8df612e31acfd6733153a5d3bbd46150e188b7b4e219e398351d6f6b19f84543341ea6e949a2c5f1bea0ae0238eb18fbcd462e97803c924aa4f741b36d83a733187a5804d27852daeb32fd26 +774c1cb8fb4f69ecfb5c7857d46415568d88f1f9f05a4bf64a1e1ff6d64aec16e1d09292010d1f067c68dddbcde06ea49be2ad3838053f0b9c0c2383edc451ef0188565118e7b3c66a4fa372b96633dc8a753106283b02d0322df273d58cc9bd061ec219f1e1a9c8ca1400e5e39c1b2c254273377dc98a1a2c44e5c2a5b89167 0018adcc22cb9a2db64bad3d60f1608c353e091637b948914115ebd43679904f955c8732 b145a4690bcffeb08d0a03e6de8c8d38f8d1d57829d905e20f6331178ae17e5e0cae53f87a695420300aa0c60fe0f8cf04d84bf2897c998c83e90a3a7f92574c8adb5474503a13b914dc885c2fa12a262195be16fe2c7442b470332ce38288b1 +c406aa4295f85c854b4db2de5a7a2defae53a319866921a3673af5b48c85ef22f6eb4cef892c790d8e64530fc20c729b2821b5f5e515560b1ac764106560c3a6a05657e34cd6deadfe2884bd288cef4ca92e1f25adde7d68a30fb0a1b3678156ced62e466718e68e9d67099ad82613b8d06bdda1a7b867c2455422818ae9eeac 01898276f159c10d92d8d4b6ae214d68c72792a4b5f1f79936ca3c063dc8d9a88be439e2 b6922f8520b718636b1ae8d6ceaf758f4fd53a80e319dcfbe84b2b0cdd24320c48146dd75c32c7ab90a688fced440a830a170999ed9dc2a6e4fc35e0e8eb430a91dfcb3439037b157c35ed5793aad86a8674845216ee9023eca6573aa9ded666 +cb2809152f8258660933472c06ddcdb65f6d5221fa29d5b0efec9c2a7914dbbf9ce0a468ce146fb333d26f510a87a6bb01bf8816756a1b5df81c5f65360957cae84ba038e37e88777580e91c34e2f5aef4fb55af7b81ad28aeba05e0b1c64a15381a6719fd2c16e38a441516e1b394952d984baf9e051b1dc1bda2e12f8ba5b8 012ff37c808c3cc029a9cfbb67a5ed21f3bf362b49270d4ed0f1e38fad25ebd79f112a50 817aa9494bee1b15527c847bd0860f6d79cf916197c01668bac0b2beb427b45ee310e56b2bb4f343316bf3c1c8c06170015bc5b22a6dd675e7fadcd6ea5f93abdb10af12915fc8a9ac12f867ce6d40f30c4b0faaf48c6b5b1889930f15503589 +e060af96d4a7fe512bbf26be9a27bb6a8ff37547d4a7bbbfa710db24cffcfc760dac120f89f642880db2df6307f9ea5441d5932d49762d182b29d8e7fb067a61ab0df622f75cecc917e27d0326085d34581e052c85f50a37713e27518aed7c4434f86970e00a0a4b8503989e72614131b7164c1bdc82d2b6aeac0787f9838476 002b8c1fef9c6def32b5f4127273ce384b6add4aecec957c1662f52334f5ee97f49852d4 9399b3210cf6278d0a4828813f52a2a05395bdade77c124e5ebf64ed1d0441c15092ce0a234945d08a45845d7eb4cebf0259d78ca7ee13795101f30e02bd6ee604e10c80772dd83dd8198699e0acf38d56efdd96d37ca7008b018efa97a3f9ba +d235c31f0a82957a087c7597673970aa39321d4c2640685a03df8388b5eae4825d1fee29926f416d5e62a2e9ca1ea7cefffd31607e750fa9675983608e0f8dc895371b190574d065c5c0c23ffdaf49e65362914363a3fffbc2c1bb487cbd4f69ec22dda5c7dc3bbab805c81faa85787cc176bc0e5703924f395d8c9e7e7701e2 00afb1c45e9a9f02942b8e04da4b815498454dde6643de186625a98b3c1c6993abc8bba4 981de7e6310b94b4319bfe441245e124eca42c69c897c1d2821303dc023549510c7fd252c021c7c87276b16e2fecd2610748ae559a48160c6809cd358f7925fb7b4021658d634c4ae48811fa9ca203d1147a2c4a36d55080263f5338ec74e2b0 +1a2559777a5fd8f269048feda82c4d9fceca95803f84a813789d6ed070422240e443789c5231d63d5268ddebc060dfb99c4eff2ff115d2984d8bbc5c05314562ea6864fd543e7e0a3b8572c017d8ae3563027d79bbe164d40a5bab354720e45094b9b26391ceb55339592fc2f10b97dc9c2649f7227648f5cd2fc46d78d31c0e 00ff537d73a4da0ae3a4894016b71dccef3bc886f3d24a5abb7dd96cf8fdcbdf0fdc5e51 959151a49bf6c47c1c45aff1c937b7d4d87e788b4c43827e608bdd8fd9fc31fc956023471b24e9239afdbfb315b2af70167292fff05e46012508b9ae74f3339297e1d95e00841dc1ba3a9a5918e78fdb8b1b56616c1b580f74cb61cd42360250 +658c0d3f764bbc952fa55a258bac16a5bb5184bfa76cee06baf9ee6b9ac3f116e08bb2406b1dd4be487b057f3b29c2043ebc33019b2017c4deccb86f50ff15fc9248ea5fb64261120b1960525aec3cc18827c23291722c5add8a3761ff8516c61956c62b8cbb13f3d92bf3eb45a70704c01bb3625d21c38ffa83a6db086ee968 016000d2e879906d1040b32eb6ba3caff700e5565871ac75f10c5c15b509964bbe5e14c7 88bd212344e4dbe10b2e8ab76fe10c55df3f9317b0940528cdf84127720be5c16baa96df883240cfb71a2935d73fb0d311bb47d30eaf453674980ac770bc1d78c668e6aa7f5d33013b7472b2bcf0bc7eb17161ec49910a8475cc52aa0a39fd9b +4f10001e3517c2c1f973b555f4827681e096d860c4db08f1f4aef8000c9c24bebe59f8bf3d7d3cac959a1a5477bb0ea43f2e746b5d14ed48a58ef35484b0ac786d2fec669f945e846ad73e6b77a9e47012a951b398941566330d89125eb3c1fbb2f06adb951ff5f047d102fdf28b5cadb4a3e1a10412eb3474d2ed5c3fce78f5 0019528d505bf0584628d0214bc857150a929d3f59619bf8f3acab545fff0977c9bcdc97 877a91c65af78e916713bf9e3a0e613fafbdc8b027aa400b29cf31186255ef3e6728410e1342d4772b89c1533a16c0e20f881010fae7d363002f8aa16aa941c8800bd14d95bd447f88c3ea9de6a50896ffade27227b753ce4dce0f3e6ae67109 +c43ec3c3232cae59bdea7cfaf18a4672035dbd2b8b6b1b44ede376b36cc2d8baeb921e416aa177f5977da8bf1d713509e5251278b6622790056271715cd5feac58bee5baf50b216e8eb886279c5a384cdb696470275b7487fe9ac4c506706f6b0f9809d1ccb102546a4297d2017c2a8df9f02f30d3d1bd9aebf6a92a02e0d202 0067795ce117bc0a389397fc22a01cfd9422cfbfb5aa44131938a8c45e48e1d5a718539c a6a6c71c5cce47e0f7d010cf00bbf76ed481313fb5c946dabe42868aa9995560105dc1351f89554974fafd44dd619d2f0be414a2eb80fe5f531b2587e76f2513860a09a83cdd3d7f90efa139f394fac323bee283a5c83286de99e54c47eea817 +9b7d675a3d2cdeb280ea28289b5fc2a3ef6b535ebee8ad242fb031e2e1f364e8ee806568b2f8627c5a5b4f51f4f65c71acdc1152c08b9211b81907b551e0ff47f5a6aca45dcfa06f09bf195d19d7b165b52111b601fbd97b192f62465f8ba20773b1599c8041e91448eac7a5763ca0628f40768324c5304e1119ca6a1fdb0778 019269dbfe4184249952a651a507584746c5b62c64cb3b17e0158aaf4d086a4afb0330c1 826f40e0664aba8b4e8d43a21acf37b8e47b6842f1ca582a06359d0eb9f3fe5ff29019daedfb9b4a6523cf43e1a5df9e14a9ee5814e2cf34e6e5865877e6f63f22430f8c6aac009438a78d1fd7151b3cdb9142afc3bc723f7a218f6fd8e93be9 +f4a08daf8f66ce57a986f14b918099bcadcc4308bcde7c169ce8536a40d94a928cfc0968180a2c2a242c59df73ff79a03687998c421cf9a0e661630378779a4744ae2a6cd24ff61d7fcd6c11a4c8bcaf358075e96f864df0998ee98ee393b37bb38747b70bb7a208740959b45174a60153ee566e0f62528e9a5e4466186fa650 003835814de0d6441cd80a44e40350cc8bd62ffcc81e939a4410bb9c9259e30463c453b5 a4fbe054aae5a81f3ba511ce6d55689ce1de5af40446e85d1f635300ef00cbfd428b63d6c3ef595a417b88dc10bd780209159068c1f794e45599ecc46b1e466770094cb3db6cea280edb44edc8cfa804e0265735bd985acd04fd163b81a4b899 +864647405c70939fdb4c026bcad53218ba1d438d82c9138f0f0ecac815dbfb242307cca52c84826cf6556c51082a23f14252dfaea43ba229f7493db2bf8ae9cdb0228dab9e25cf385b504b92cca94f813acceaa1f18de851b8936c4dfe9e4e17002f02dded6b4c231ea5e614ab46fcdd637b8c6193e8d0c2df1b3d883b97e1e8 00aee83dbed3b703cb6e60d51e373eb20e298ac005fa6a572d02fa1e6da0345558ad2a46 af04d343acf1eb2079f9554ddeebf7672214bacc0e991355c51eb589e459b1cdfb7a221455e795bf2d8a3d9130eee6aa15eacf79bc75d9b4f6b345ec1bb17264385a2b45cd5cf3866b931b453b021ad070ee6909f971685e828771e3add9ed9d +c87c8f3ad5c28a027b28ae5021dbe8d425f74181d519451f1fead7a1f9dd102fa6785b147b610610cb59bfa91fa363bb79ea602a7d7e1439f874c5dce748e5c320560c2d9676f3a948754c72b6db249478b7e19c9829ab4de2e344535d3e0b7c20c272f82556a280ef491524b255c4fafb9c8ecb87b0149ddd9d7bf6159e3337 017b65c66514019ff935e9d571a4e68e9ee4463b7b9a754b93f4f7741693f4399879fa8a 88a298dff21e3eeb3ebd22fe779cd4042151a0748f02015b2129335b4e083c171511ce5b53d85abe511a75b253c5a10b045ec123751be1f565a50086a9e7de56e85ebe71e57798fff135ee9deac5fa1a592e7b7288a8c66966c065672c7b3b10 +ac7da7611e2ade20aad64b418a16e02e79ab4894d758550210eb10013a9b5533132be701f8843c840807c4167c38d21dff168d3baa65d5bcf285b73dcbb75819f8d7a20a849de335e19bae2aab2ca560b93d340731f291599a5b28afd7737460d291105cbba6d0290e836f6f6c1113d1b2faf90ac5de7c64e25206d79380a4ed 017d2071f39ba35515a8ec977ddd36ca15983e15bcda626f15af61d87d58114f4c80a8be adc214d58eb2740f6550e71cf1ee4cd9f8f674a37bdb718e7d531fc58a714acaf1bf6e00f7804dd9d18dee167490c16202c9b58b7cf58c4cdcbdf5de3a02a37952e6d4672c534a4b647484f35c6fbb380715cc32bdc1d81133b92b45da6d6eef +5757c472fa2f81430dd920f39b61066a28c870b80e6c96f822f8f19b398c3574d159cc22120454dcd7e97be8211916e4bc8db365b2dbb99a6e597d06e6645046a0abdccbd06741e9c0eedf33cb78d78a540c2a390719acc498331e694e6b0118cf4f787b51c7b7237458a6149d6dbd0a08bae8097e919f970fde920485e9a0ac 011504659e12235855fe55220287a101e511d39a627f8a0d414446385d4a88f31507fe74 8fefb9e6466691f347b3ceb70c32ccff3b995acca692caa377042ca6cc88a8a28074dee743293ecd06c60babe478036f085b47295e878f9884428c32a11c4037869d87b090b1bb430ecc694a2b479df84d5cd7c225a24cf731f7ee13d2a34303 +e350383d04af0f4081bf09b95d1d53040e7acc64e56b13b653df31dd119617b800e0cdfeb935dfa5d94f1d7814688d8ce41021810958759cec76560e1e5c0581456acd1a020165849b2203f1c11d318d816697f36a86b59f160faeac7dba71682d3c031d0d547725ef69cbaa28345512e38b75ab011911d8924b2d17a857a96b 016e4cbabb03215767249ba2a608708b78d7387be9e77f5efd2462467fa05e8dcde2c036 824be5314f58cfe4097be19d7d450fbedf065b53c9df4bc54f054b9258c324dda0ebb81adb5ab24586a650ca2d65ce3507b8ff15e3e77b1ab31e4ccee3b356ff750667248a8b19595b9f93eaccbc74de8dcd8383bc49b1da0fc8db08d63f141e diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K409 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K409 new file mode 100644 index 000000000000..b9ff6c100946 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K409 @@ -0,0 +1,60 @@ +f153cc61981a46d8a47d17d29ec157fa93fcf644beb84558db7c99c57fb131dcbc5b65581ced5ff0b29bfdc66ff703ecdd4290f7c353c02a3e6d6867f33f3dccd1a0b6752b8a35fa143f8921a5078af9c85b212564c5b795da9858c7955095938fcd10c21e35e1abe905e84c8b4bc05f2a06091ce876d9519b96951d08c7ac9e 0011c6528939672bed3e8c905b7ba594c3ce95f37fb28044f210cccd01dfdb42c10e8e1a0b5d6fc757834ca7f08e98cbc52b0edd 8a005a30d700695eaaecca753aefc877de2ef23b016f0266cf668b77905e9c4383c08b4807bcc1d6df64e3cd86f6b7251508eddebda657debeaa153a335c5213beeeffaa1a10fe408238837c05b06949b39b74b6f01e7d3f5ddb7aa530b616f7 +258c91524423b5c876432b1930c7b07b56eb5e3945f1e2296a4e5bfb9b9123f800ad195d6104641b1f1970bca553c2032f83d17252e52403a9381c1fc18eaffdf026f7537aa27d84c5e3d6e39e651a92a41139cec5181fe794457f556b390943093be719acd23fa1ddf7ff0aaf0479484a381a309b4f681af74bf97caef08c22 007e3b714496dd118d8f3f597961eec5c43d0265bf85723b0b9b0616977e0acc2cf686cb6afa6cdc19114e27ab000e762dfe467b ac9d887cee9613ec4e6dd88fde6abe952f984cfb1ab963aa3191eea99499eec6121179a0f8261751f698e2cabb3f5c4216a4ef71ea62958c5aa97f1c66b1677fc264a251d07171986dea33396471eefbd681eceaab9a19d9416a87520ccd273c +a16a0d6fd57240fe88c7c36b9f7f9040cfcaa9afc4beeb8300818c5f90cce73b819a12c31d42af33146399cdfa4ed4954d068dbb0f1f342269dd29f1fe357e7224304b67b0f924b794780fe7e6aa9dfa3380252fe7177b43e7b1789718949b9ec1b943c83ed4399491482f0f59d2cb8050ab6f8b5854d76c50651428cd29c40a 00182d1e937b037bf7f84144f7d4c94c935269c9aae7d500aa459a7a0ec113b232dcf282908eee4c84b8106cd38cdc41db3f89e1 a88661833a8f979642c673db07afea473c4a0c2ccdad614eff9743c3cb680fbc6c2a8f2845a6d5818f3a760de9e4068d0c10abe4b2219df921a9146f16a88db35541d3264dba9b6a8d6599ad359b99288dde28d3e67e96cb161d673f4ce13454 +d02ff569828fd1add21f6bd1c50cbdcd09222e458ee79fd5dfdba3cbb84e9d926fcf196cccedece77d5aa17f8c8cbf3a9facf0f02c71d5c1c8aeda9d75f6fd7b6f2c5c70dff992ef6e02c438fb3c66da5a503b3c39acbe2a069da457595b542190d818015d462670b0807c401e36b1bfe05baff3a8ccf8d1f5f8de7840e87993 007ed09428f460724c8a5225a31151e031d9949493fff5703369c401762345d002c4ce424294baab22d9e71edc4f854510cf0e6a b5e0b05211cc6bbc40a0f6be96a2a535b192d6f9b298c48cb1731ab156f132aabfc9c10dc3615858590449b9b9d629ef0fdea5f28c3130fc6b39df67cea1a6ff10445c84c2fc04bbaeb6121a5d0a6715f538c0c1d89e69b985d2e433aab4ac71 +57befce973b225cfce7f996fa5a1a43acd160681b88a87b7de04544eb7b6a719718f1ca7f559b6531bfc18fca3836d2be7f7a6e48387b7579a6845796d30e46f0dda9d82680f8c96c5f0989741adef9762c3db763cae2699cb6c112543635e20ed5cfb4b55ca2ccb32d2d13936085a8ff95ed658a54be73f80c912ccfe5f0ca0 00390f05b9619c27b800e99aeaf61ef7f6249367d5cfaeae3c7b523a8b29153eb8a77132f6c4412545a842d6deb7b7aea7e2bda5 b061ac4fbe151498fc2f7f9dd403634fe13bbee1d78246d99e741548dee880e5377006eb0d50a0492c4aea7e72036cdd06baba1b56f8f6940f420f28fbccc7bb360224288ff156baf99ced37e082b8272bd9726167a920054c87f0c3149eb7a6 +4277ba40cb462860ca722cb4ee71c61836d2ceba18bc91f3fad7dea478972c6da0ebc02815eaaada1d1a5e93d7ab353855ccfdfc94a5742fe18daee2328871e06c1ab0a9a989d1239df2d2d27f96c415e7ef9a941f06c6790675361173cc229aac7045f49eaca207f59c497619ba32e932b5c1c6576812ee5b146e2cc7de5e62 0007d18652732596add3db31f7a0ce6020d03f3df58131b0c7c633faf619b8210cd309d6c0c4083aef1a1b6d2a756adad0bfe344 90911d28408d61bd95a49abe711dc1f4bfa741bd638f16842389a2a26e2e51c621fc0ecec25cb6a8c59056aeae43bcff05bcf58b76914f178fdc223f75618cab67f3e5981e552a20109675a65c840bd3446bbf538c3ef84c9080c869992c99d3 +57ff6792ed4b12220d179bc0ea57ff217f322c85bd3676a681d32d7e4a3e0c8e891fd267df17caba5992f68c35ff670b60b4bbdfff82404f6ed996c30539bc395120f97d4d7a652eaee82bd8f9360bf8bb73748b8bbda9f9480eb54f7eaf2609d4259329e8a5ea020521e7dbd3ec56f23c849932cbdf2875f5d5c774a9d6b0c9 002a91244ea4623b63403dba807d60b914ca3b901a2523244c322f2f11251446d3f15e869d086ebecfa1a39ce304e8b5c8de23e2 ac34a8b85297d6feeeb53b2e5b9c437c8d05af10994726e5fabc52b0652bfb62af4631dd0012d69d88d7c5235fae9cc3031b3219e57770f0980d42efbbe281886fda42334f3a41de22b285beb243bf79a4c78662f0246aac7d03838c07545ecf +f85113eda64478f460b60f8084220134933de049200a5f37884da7901471542e26690a5fabc3cbf9e679ade71b6e54d869bc136c3d34cc4a9efcafb777abf046b5ae5429136112a9a36a475121eb1f33f1f43481286fc1ada98a41064a1fa38c89e99a93065bb2a119348a9e452497fd5a0d2b83a66b09da9f47a0583732adf4 00068c56c6b5d50d1d4e13d3837d8c5e8ba2f825e121b63e97603fdfe78bb6899600ff0dc87b6b3b6868ad0d2f62b7b7a31603ff b06e5466bdc6e487b47629b4ad56d88bf2d553626e7017e9e58d3452f33258b6eed1e31d9fda9b12587b153faf1c9401129a804b668572ad45d36c42eb34f2c860ba2787005c9e738db8fbb3bce78653338dcb0b92cfab12aa51c401ff73eb9e +42811e9ee6dc509572e1cddbe5baf00afeb0c5c13e3755b922eee9e210001676082bc9edc3d78db2b5bebea7a2c0cd2b369226c2b8f83b28f33fb513407ab9d287d14b112d6c3be2493805ace5cf6fd366d03cfb28f4ce3f0f060880db64d6962e997463ba7c05b6fcd1e66babe4b94afc5c2d38c7050c69571d27b66ef0090b 003c88084f8b78446db431bd6e240a0c050813d2a763675b0ea869cbe183df697146cf29c03479af3d34587a95cd257027fbeed8 81440b5f2a8e74a3398a520bf39247ccebd041da4a5a6fcc2fd4aa8628f5a95504a63ce9304a77667a4d61bccc8e6cd60f4628838d6f0da480a33c67579863a4c3c9a2149839d9f592e04fe314146533232c283b61a66d82b9b58dacf349c67a +b38f76ede7441ae0887e689d556f43155b38dab7cde487ce9ef9a46f2957c830d4d28006873fe2368197a6931f6fcaad755102686a457a7edccc8d344e2d2a9162e3d71d41c09a022539ae6d404955a6ad748231aee1f974d4f159940532fb3b1fa0254bfc5805d2fc68696856fadea386c542d3cefd1be3af04ca595e54be25 0051af7b63bf3297ae20517faaa1552f4fde65819dbbff6a52721611e5b7dc1242ed6e69768cdc37ea8cdfd1a5971f06b84b5803 a854848a5b8fc86e7dc1206704dfd32ee51ee5a9253bb7dde2248b92adf36e27ca48daf62e465b89b617b74bc564154c0320f50cbd26a542bcde2e1831894b071610fe7c8e87a58a106e064dc7f7111fa94865c0827fe0e366990fa748171bf8 +356dc86cef7979148e995fc5abe2b14a7d5e4e42c9b3509b4363bb80c581a66f4e7e4aa53a4bfd37f9a7eccf75fdd726f348f6a3f779e6599f61bd1d668517f40453b39bcf35db0852a6a6218198f52b7ceda2ec55fca5abe8e5d93af9a42b9ae4de9530c5870211bacc27c39aa094013db703de2fd3121f08d7e97dbd4e8946 003d65bdec48972d03811b78150a06956eb22d337dbec5416bbd8185a6322cd8c0ff8000210dbd1326422289071cab65175f5d10 98c72462d3dc1755d2288b9c1172871607ac0581a7e3e76ba85e1901b6eb8d4b10da112c8fb989eee730c8a6e7fd10701746bdfc5ee1b3a038e9c4bb65aa78267ceab1f0089e6aee80b7db68e99567d547f634e3ab7ebe0907bd55cd7abf3e69 +06fd39a50bf25e89f1071ff81fec5d1e35b6dd68990414ee403dfdebb792627b6a4ae3d2236c159e4441ff90b61ec87b1592c538515f0486b19e58583394a05e6411e69b4285d6d6589982ac0eeb2c912c4948789cad741183663fc070943389d4e9a1150b8f6088fc50605915e9e24b2d98a1f539024770e4820e14ae42ea8e 001f1a8b5f35dbbf82c102df550c72216a243f986f0325920f6186a16d1da74228cc02be6024c7411160c183c923c743354f9438 a256643ebe4d9e50dafa92be974d90917a441f118aed38f12e5503aa2d55349b767f93a35fd48c951d89125199243c690f97692557b3c86347dfe3bcfc609472451e0cd97478fff5cebc682da3a4ddc3e8c807da3f9a93f689fdac404ac1e2d2 +6daaa41150ea252a3e966a338377307d909b95080e006f13027f2be5059d9208930c5a329994c0b794ef50eb059bc6c215f68cf42260bd410f9bd86d2ad5ab7179c7c92de4a93a5f6aa17de5aefea815e7c0b78a8cc53c21dc4dee037b29c9df4e12343109283ffd5d8a3b81fba1b5e95506c7e01ac056c86dd0ee23bc21af0a 0031dc621200cd174193d95e9092ffb86189c52cdbb9ed937593f2cde7c4a0264b9100e1b8407336c8dfb5520d28a18dc4e39a89 ade227888081bbbad1fd01891ac755a2cb3bbcc9e7349525d5e4761e2b7480d24ca394fa2622bb297f7f844356509a571325266b8f7496272246511b3650e501f4319d25fe58dc8198a32d3504713fa2a4d813e1e8fc2830a26c5e7f9c35311b +6378dd1c12c5197b57d47dc46a67949bdd1e0809004e94d49b0234126a08ad5bf8723ebfd132145813136d8b7dd096f56c34248f09a65c34f60c2f80f9a51b3795f3d2518b11aaeaf6dd45a323794080b78f85d629e5fa719b6ab0b14c78cd908befeaef0dbfaa08cec9318bbcb376d48b11b68735c9554a45293db5e9239ae1 0016e6750245a88340b0f0665b890459f8038e9b1366f2fc1326245a88d4c523ec94429f21869ce3dbf75126e58f77241c99efaa ade098c1fe2cd629ca2ce25f893d9a58e1c29937fa968b72a2ccc60ff16bc5534a21339b70a96a2a5d3d30f6096bd9120cc9c1b75443f2ffdd1e751238a7aef661905368ea317626ac657d968b78fbeca7314371dc07ad1668287ab19333135d +b898d0f9bd80e083fa541f457d14d853bba55b120424a95e1d9511c8833f48444329e0349d68204c4b4581ef1c4dee23ed0a4445727a72e1e6cde422f7c10ae132a3fe681f9d741fda263e73f7cdf10759467c9d76164086abf6780ad474772771eee22d195339bb8f6235e0d992bbe282b13ce4fe01417f507a2c4fa155e108 00788fabdafeebb72f6385301e30024b56639e629a400f9c50d402cfc9b5817844f06a451fbda29c7ece41dc9ffcfc625fe0ff0a a5e37505fed7463408c3b038978bc5f42d00b57c5e33ef42f7cae6c75dba59c7b003cf5b27334350fa5ca4fe47524664184434a14241319c8cc062027cd05d776b9eb6d75480e1c6487643c90f488d4488a1cee0247ca0bfc266b3885a13438d +dbe04561ea8579672a2b3afa94426a3cbc274b55263989d41a778bcb082da797d84d930ca847a481789524940701cd5f1d11b460bdac0bffb0b3a3abe1ab689c519700de85a0a571494ba0cfc3c865450eba7a9e916b7fa9df55e8a1c246c992e6a0b44b78274e008472bed8d8411633e6520e1a906c5d0c8aafd572fe6f1f64 001b8dfd64563dc219d6eeb53f2e3ad1d771140d0960b211dc1f757af5e297dc7548d6133ddb574711d466688f80dbd65a7bbcdc aea1b8f12cb0bb4ed6d868e39a8fab8903ee9f12a86d8a0745ee30aab88f83c7b815de2edc9ed7900ac3cc4c9c44f6cc027b7f55a26d735e2ac9d32883beed46cbe3e4cc9fae3907b2f50a1bf8f7103f7cb9412dbb8551ca8d7b7dc1ca8741f1 +48a8300820fea2ad83c83f7d6b24192715329c3f159d56644e11ed25efcbd3d31600a813b909812987b97d1087e74a63b4494cc031c63492b6615e9d6e5b36f62cb2ef88b9f736595800de465789f43811165a5fc093ee6d776008739de8de2a84e878748641be8bd52e5b891c4145f52bbd46644852a43108e93d86352b2a3c 00422131829608ff730c24ddf7e8b4a2600eaa9681eaf45432daa7d41fe2fb488fd0199d431a1ed823801ce21f4f01a4dd4248ca b5837ea4a3673ea9ce89ced2ce04dc90c720de38d0191b572be67a3c96f212e24b4cabb7fc7e6894c9915f3916a3cf220ac11c19281dc59266733ebf69cbc9e0869ecbb195ed747ec40312512132335803368ebc9576228a06825c69e00dae0d +276e3a986ce33256014aaa3e55cc1f4c75fe831746b342eadb017676b0cba7c353b3a2b554522c12e6aeaf1364cd2eb765a404b3d0aa61258194a30219d76d2bfa98ad20e7e91756cf65e50d7914157f283f2ba3930c0ad3a97532cc747b1cb9c806fff497f0322025a3d02ff407fc7b5808585b91d95523c9d5864efdf7d983 00095ae8e4c7e55eb5da01acc05ecfe72a4dcd8ec152f1c8dc165014f70eb4e4a7861aeb2b96c418b2d4db58659e76184e013a49 a6bf5d45b146330c29b5044fc5ad29ff58fc7078e87f2a726ab4ea4a5411d4a813e5a6bef0a22c4efc798f619874aee80a1bb13f813abb9ba772e83370390abcec98f9e4ef808bf901db5a1758e2c8d181f46d9348474a4dbc4d10219ed035c4 +6a4fc1827c3a7256faa8ec6a0f3d23559d6949f8cc20e7f76111dc4ebd59213951cbf0eadacaeb8862d6baa0cb298645e4314b1c303bd0d5e9893304d4b7fbd36ab05fb6a5edc3fef763e3a4124d61539eb616b359c5cb55b5e2bec50c91dd95fc39ddf521aa854216eb5a707819fa6f067b316a17a3b146e7cc2dd517f7d63f 0006f2075bd730f34df111ebda919167b1d3358ada32cd6747cb3353bcfb814a77ac70cd51b31a0e538539453bf9eaf9d8b384c9 aee8a6400e8eb06e8728d0381e07283becd16d65a3cdd3ca3ce8bb13e36b6909cdcc8bd41867949ed719a22881018c9810351f7a3abeeaa1e0dbaa3748439005b1f036a5d28d5e7d21803c18386e6032e7afad9942c1d1a95996df082b314929 +4b088199bd8c94775d8ee508377d672dbf50f6d2c7370e99821ec8f9387492fb2eebdbea473ea18465565f79e2af418555f10c4a527e05a9e20c9c00b807dc8b350cd4ccc2d87e91f66addf02ce4f43597aa258ac6fbe9365cc2c8e8bbe5c884abc929710e8423cd6722a8f473bb55804159a92a3d8b6661a536b4fb9293bb0a 003887d284e9ad17d38bc6da9d83c192a434c509340a7f233cebb032b09ab7c4c6e8730b4a80844898616c9abcd16b753c6bb4c5 b0343f79091d03c323e8c7738167ef853264474085ae07b7741afba5a963729ec3c838f8b538897ca902f1eed89fdc6a01f457b9bc4e67344ccccd9591d2f9183a06b0199816acaa812f03f9979addf4d6ea410e13efad6656c4e7e10de3a792 +848a13465ddcfb2dc14f7bc0db0756832c22dde1e31e4d8b3ae0dd1aafbdf15e954889e95d3bdfd6e5ebb6171fad62592c23277a89e8ba53978c9b1afedfef7e1c3f6d9f31077530460b47834b30bbd84a4da601be988738aa815d3d7e72043243a5288751ee08b4815a017fb5d9bd55833698a0d526b1ed79da35ef0fac93da 002ea5430610864257c9dc393c3addcd0d8d5bc8aab1067643b08857210464428aa85cf1ae6c743fd2682255d4c8eaa46ca21e73 8e560c8ded94b4aa1e0b9f688ea3b997b3716d7b3b97aac95ef34029978ebc8a8001de0747347e62099110caa0e9e3920d99d032399883b96cdaea9b43daffef93e07fbc832ffedaf5d08155c5631fecb527919d43feb587e8ea5da89121a58e +d1850545c04ea65528849973c220205c35eae98826d169348970d1420b4d872ce233af1daa9e62f6a562544ae3a0633a954a493e9766dd5d87e47486559fdf86229a7c9e1726de21895abdcf2422d438f4ad98d88b45c56742694ad5e11894253270997c049f0f419842482f21c792fbe5613e2defecd485585f1835b6f4c578 0062c757c92eaef41f5d81169ec4968145b5aa2bc1d2a3a5fd000634777748ecb93677b3da12e3be33272a8f0a52300f4a5a37c4 99286ca7cff066d5b74f5163f3f5148526d363d700eeb20fb461de08232eaa352eeb1e9ad1ce53bc57b7f9e8f64d726b09424b0bd85ba5a49660d99b208c528c4fde368419220b25322874bc0f5c2d423dcdcf157a41d42c535ef29a256a2b82 +421c9784d6fd507c82904e1054edf9bdd1efb58a0b211340086069ad38b7b0dd15c2345fa8767ef71254ed1bd5c35f742b1d3f4765ff9007a5477ba9e5d3d5a5cb5fab4efc1cad73701d4776c6c4343f42b5d94a9eb78ae428dfe5fbdd8e6ece09d5b75cf4346cf27db856352225ab04e6ea56661554fbc39916accebecb3935 0048a313c0c11489939fc0cffc6ccb9f179093c4e13141b92dbbaac441b7ae878c9d412066e95615174a24692555cbbe904a14cf b1b7349034d67184e3781f7c8fd60b079b67f7f3f3f1f2645ce52f472fc010815a7854ac102db112a00fceef1300ea260da0062c12dabbb92eb13dc7e1fa6cd3e1156d43b16a0e44607b18545eeafb1a367b5c84000c719e4575a16db870729f +7910bab15b6429947655e33a67f41b76f1d7b71534f8904d6a0472c2faded038565272d0b5f51aa915e0d624e9ff48d50ebfa2f09324864f26c29ab73eb39b436c5c459c7cff4d2b62992e3489cb4ddfc05d7366b161a463aa1b782641d93507de43c8cd0a0a0a9d1c644f4554e3edaf7fd794248110ca9387e73ae5d00d299e 0046e2adfe5d3549e1e6fa1fe69a7cbb4ac9b111c8903d544268f8318b0b47d4b78fe3e56eb5e639ad5382e7cd5bd4b2c3e70ef6 b45cde790b3ff939f17e887a584e8674f091f1856852ab05462fbe1d8c091b713a12afcda443b53def864c6e286facc31907d913098c96f90e5d67a763972f429ff353a7a920e78681cf6c41ec37ccdcdc928e456fe9eb4981697469779cfb6d +e6fc96e060b956c25d50ad25443f3c30a12d199a47451a49ce88307201dfb15ed816982e8888a28daa92eaf3c5584ca6ab2ca9e14577f84396de2e0ac214b24a2279f5e7b344fb7387e9afc8f0a2b77a4d024a20ce6183499b17096947444bbb753d9b39e5c694239d28f9c454bb05468d17ab564ee6cea3741747ccb7f108af 00480103fd6180a431c837643566706e2b9597de0a1346a224d176a5b2c54aa4d064418ed654a5d39f4773fb509f86473ebb373f a5d8dbb9fd4917c0cfda42a88195af325383a95e6a67abb8a45b3fe18cc80872a6306891c2f0eba50e404df403588f9a176b20b49da7f7a395175c2d1899079c15a062f6053641193b13cb993251954e8831e1626a37ecf7bfb43c98fb1a86ed +c8a8a0d41f35537e6fd523ee099eb45e1ad6ab54bed4d3e315e20227db03292e39dc1a91bab439c0d20e36e7fea6ef08983f390a6b5551ac3b4f1895220b2867fab95552cef9bd8702962839bd9b2c72772640e7d3be3c5889d226acbefdcb448432bc503e5a5fe7ae9ae7696c720a799f9882c64ae0385f656074dd8a6821f5 0013c489e8311c6bef02c8f58903b2ba2a98a27cb935d75a30d320af9a14fa3cbc6adcce09235a9eaf333dd05f4b2f1694985dc4 838a5d78a2ad1543b50d7df2f256f5d1353e5aafff12de4fa773d7cc22d80de9dd2b75add9ce5040cf32a83ecd114f2913a3e4b74f8a32677f649f3aa5e669a727d20e387c2e121d1ebeb3225965a9f3bbb47fb8fc096f915455321e5ff19f47 +3407cd6d2845197cd7414a30fc3df7184da204222ffd65c4d16a12cadabf603de8043ea14f5e6ddcc22d3572dc06dec1a23cd924e1847ae285ecf01754e2d1247876431eb98e897e47412a2330bb32990f9714122109e94b38f82cfdbbf2eeb4c6f88f5dbf9f0ccb47939df8be321dcd9bfd9bb99cac9f94885fee7d443fbd87 002419bd2200f8e1d87db848b0379741685e680d9affe693eed49d82931030b6cb05d21a4965f4e1df2045c8513a8f574ca9f2e7 a2681963e4429d377fb8ee5762cec35ab5c27b9607c471bdbb8252b50d2a12e17e2daebb545dc34664103aed56c06d8d151a6707dbca9df299326f2da93e8da11a41f3cd527cb244688dea93e456a9f6169ab0ac695df98a875a51ef2f567cb6 +ad43f8440071285d01fd79244907803601aff4bc5d14c77483a87cd742144d41c68269d76c9a83c09d2178bbcbdf99f927b378497ffdc907a75a3b0ad019e69758dfffa480871eb6e1e17c8539373de611a557fad120d0bd147f8debe5f09a02e56fb607e9c1253ed592071f042e42fee39775b407225a2b86a950d81bb7d7ef 00722951879a65bfcb414e11712ee9431eeb32319e0ff28601112f89276ffc2b96eb65c7fd77d023f09914a53e2aae2c84652bad 874740d2579a019b61bcf5fd072e1b44037812213dd1a0d128756fc2086b95bdd79b6e772e5d690d895f90870a04bb4812fc652d9cc1a947e2ed75775ef385fd9d875dfd647eb4a26bbb4a00fbbe505258b526315e8cec61e7820c75e8eb788a +d61a3765229dcd0b4fa6c57280f851ec2bd54d3ee2436935cd6d94e0120d0844adda163995fbc4cd9d7275da859ad8ebf30af9efbdcfc31c7c9ef42bce9011d37cf9d15fb018e117bbc102f7d05750e5072f73d02c2f45509a55627a78cbd9082cbf36807759d1fe2ecbb92ab30cf28434941712d38bdd100955d611987b5968 003f5b5a772d24bd5454bf26759dbd433fcc7bae4f5c593664c4d75da0cdf9430d7d9162bce3d7f6e13a344259da5a7d6a1635bb 88702934c24b0ec3ea7c45da7a5ff262b007170f9f114abba08b60f4498bf6ab64f25147867499db10bfb3022f9bf02d18e50364ae3fd70915fc375b453a8c92b4861042576fca2361213d48f96714ed5770cf53730beb8914582511d8709630 +1f3c23636414ced48fab6763eed5b22537968e6bf08c178b3d31fb1f6ea773c6979759701d94bc1bee7c354272811edec58eff50c93331b22723d460e56dbee90466b894354777b23b13a37d15a84c762caca70c01518bf34d0c2f072145d274b3b6c932b48bd815fe81161d8507ffbc2f783bd212c29b2887af6d2ffa9d2b4d 0046bb4a141c9099d531dd23ac440eff1f5b10f7cf34920b6b702311d490d25344c665ed5211d401def24986c8094165d10f8934 ac2c7ab8a334c188963d2e73c48eb1576f6a27c7c4f4ce9c63c041eae3dfc785f002bc514a19fdecfc487eeae569af6f161ccdfbf88aab8cbcf089c19252921d053beb3a396792839239be7ca471941eb9da45fceefa375183a1142443243e73 +ec69f2937ec793aaa3486d59d0c960ee50f640a9ce98a3becffc12d6a6c1c6c2f255d37d29f9b4d068373a96beadac98fd5203a9f229bfc70bcd449640165ae5128e3f8d057769e28356e73e35d8e9af7876f608390090892c67391ddfcc1c332aa61efbf72d54bc615998b3be8ab0a9d372784bea48c9fab244482c75cb2de3 006f2c6e9ea8109223d9a349fce14927618fc4fa95e05ecf9aba1546619eaeaca7b5815cc07e97ae8cd1e9973ac603f84d838393 b048ec8a190da578ef7a0ab69801c1717a3bd84da5907f3e444ae5acfa0f6b8499973f7d4fb892d68b631aa9752c1d6c129800ee48a72e803649dc599baf18729dbbbcc1382394f9aebc08c820a29d33c2137b5bb764ac871b5586fa97a783e2 +70e11efc78d7f079ae41ac3c31c96d3220f4abfe23814a2a4a78d9b1a25e838c3408bd416062e4b0a5cdadf0c6e16a11e00f59711b417751f5e4b43ecad99efbdb2a81c91a034e89edc94eb552c3eba62808563cdf64453a1db07daff8742aea4a9fa738e1322da316b26dbca2954b2bc0de6da7518d28e6677dec6ba8af4285 0004212b7fd913d794fc6bb33e0276e349c052c969ecbf6afc89b28f75a599a9242acf74dec9f374361ba296ba42a38407f9b7d6 9870e7ebc479a41e6cd295edc9a40adea457e55222f6de539325ec4744b2f79b33b80a19fdb88e823bc410c355beb5d3181cafe8b47470023bf21cf45e635b24ac256da8bafb510bfe1408411fc19a79c76cf6ed1c2c853cdad879435008142f +d922fa515e3bed60b517a2d37cafe4c041e5ab4b5c8d8d4011bf9fc4013dd8abf7add71fcfde5e71d6abe76bd0f749e960cbed55711c87b5629a2c39cff48ed7d0feaf5cc4765e576a4959521f9a45fcba0dc65ae618826447e02ce6e1cab5ce8d6c96c3211adbb0660de7df7453f3aa726016941d00d8ee536cc106a603d126 006baeebb5ffc89c94c3e8b37b9b0904e7c4b251d204894655bf3b1235710215c29820b9d401c9ca7df1404d2d62d708aafe208a 85be3df648af8bea3bc9844a9361d6a3d10d2f6817683a74e868187bc554aff7abdcbfc6a5fbb147f23ac87ed633156a1471bb746e1b0cf27501a313af5df1f4316ba09bd563b8d31a743a4f16bfcbc9013456937f25a0a1867c036158a1bbfa +4f64d0f6bfc542a0d4347576935bd68ca88524ead03b8d2c494061d0658e6c3e14576b5bcea5f2f992f54cfb52b5c7cf1dfc517205e0454510eef1b7054a8cd06ab53ed2468193f98ff0dd62faf076549ab2a270f259276d5729996c120792c6f466a74ab65035bf38ff2c055b43e2a8b8e2449a2375ddbfc18242157bd905f8 0008e5f66ba53e7caad1feda122a80c32c82d2c32a7237b8ee8ead44ea8f2f01d77c7056b9dd60b92d051f060da8532c1fd0e8f4 a8154e510dff3cbdfb192d886307a2a4672168b39a9c47d5ead9c39c890f6122805f1093069459d356d30d3e6c58479a1255da82ca4944325bbaec8a4a556035ccdf33961846fa2c5503f50ee741716ddea8496af5e5db6ea8ddcb9e6e630593 +7047d478ec5282d55db8c19c97af10951982d908c759ff590f27d57e2664f08d526cbb2bfde39bdbb1aa3dca5a8d3feb50b868be6651f197abccc9d8040b623de367e2ea1d20ecd302afb9e273f4be9f3f64f2c2eb3f92d5e0e375db6549da2a589f0604bc7146562ccefd15995a7c4208f640e7a17afbca69cda4e173380523 004ecb22b44e809f89b16abb10be062c89b41ee34e110403e42a20ce59a99afdc22f6f6dda56e1d9d1b8ce1d057f390db111def3 adb41d3aebec59a2955f2f851af8e70c703543322cddf8ef8eded7481ba8b8f8f05bc22846bf99add3fd466bdda0e08a12ad5cdc96ae7bc36891cdb0bd905e6ab852d149117d6562f1db44fcd16b50a127c81e23037934aaa2ecfd7a61823ae3 +1a8384b4771a410663e56eb36c5d9ede8d161a8fb0e31d3f74bcb017b9e31232bb2e2f4c65a2d85bcd1cedd93ef08d4bb4af0095731574ab3f2762788a1ba3bf0ee46684da8d9dd384432fee99ed3c69213d790a5d81b351063eaf2bda71ca4868ac36be1b571024a8bf09039b347fa996d5d161078314e24b7d073e05cb3d48 0051f9500c15ae73d6d479b9f3d2caccc2039d8d03820befc2aae3bbaf65d59bd9cb3c4e3aa8bed5b3acb70a5566047ffad80729 8113679059f268660e4d89eb33318b0ba13f8242879be35d7f7d1ff0e16a77b4d95b5c7145131f5c37dc6bc4fa9b9b29005cabaf0fcd6797d6e57521932990233e99d1bb34483e160567673b099bed65e48ba6c29dbbba985be7b6474c4f0196 +43513d6dd8bb0af7a6f5a2b35f99957d335a48d54f2c4019ce9518b35441d4935518976ab1df37110b5b53532cd9e2c66d9f87ae7f683d7efdbe1775a6c15eecee84c6f879999d0706f6779dc158c111fe8d7201983883bc8334f51dec60004eb1087347bfdab20f8f2f260556681e05fdbb8a6139857fd3bb2df5bc1f2dc143 000cf01dc4462cca764f4f8cbef48c51980737b9b98d1384b8de9f4c733829db7718a9b5eaa46a8475c2144fe4454cb8eeb0a443 b28ebbd0b57994bbb0e52cf5369df2017a225e7f76e7cc6598fd28d06dc0715ea163356f906e5b849462caabe38bb47100ae560154d60b2d4879d4a9d4476258adfcdfde50e021704daafa8f8f012c9bbc417e7a8d3a3f7324c9410561b98da2 +752300bc5066d0efaf807183a41725e349907b7339d77c79921ead3c685b616b0eb97e708f3880fce0136c510c8cb53b22cb424af6f1c34633600939a0647c02d8f9601f9416f1d24a51657241fb559c25dfba91402cea43bca1a13718b3945b048725f3df560e6717cfc6ebd894e29bff1e0c7763f15b8ea93e67385f059598 0063a9a565497974c6dd459bea0d1196d74f263f333c31b7e8591499960e1cd79e2ef4cc8709f6d54713f873b16e7b0be42f71c8 a51b652557762390cd2dd247317b7ea07b2936e7b7999204db748ed943514f7ad9b7862969f5387f28a78e6ef9ea20eb107eb58fa2d387bcb1d687011f5764357746ecac136e089b6f97204818f9243159cbcdc7e51c655ca31215953db3a602 +f620603489944769c02e2f902c2299dd5f32b5fb463c841b7e1fc0249a85d2c31684bd3daacd97de8291c5d39e84d6e59d3dde1b30c181bfe8d31b8d8e080bd191690a67fa00024ac8c1b10981b40d4f88789ecc58fc69b15417fff34834e23453bb9933a43d08afab74d056f366b40ad167b51ee5f008db151a12b467d3eaa2 0041074dc186193d30aac7cc6d269b938ab40b257d095e54ba79967a377a91b8f73671470cd07f0a3d1db7cf0a31ba9070625e43 8f10293c8555bd3397eccf963021edd12b9435e442fbf009100363d0b51e10ee9bea8f78e13ff932d0f50d86c7a5354e046a8b0fb6c2b1177ff86ca3e54c0737683609c2246e13e86a36fef4edc5c3be8228f04af1ef72935bec3a498e382933 +5575f610762b42ce4e98d7bcf45a7a6a0d66ec7f27d6b8b17f1961249d905bc7e58e2ce0806d467f106b16285dce4544c72666d08b5e2276cd0c4e13187cbda8aecf57b1855afedf8fad39ee4fe009f204e60bdbec79b123456ec2d85631d382b8a2f2c7634af3992e4707f7b4215e2c9d3b0aa8fb08267953883a4213669d33 0010820db54ccf0226161aeaee79cfd2797f87702b4ee91adf8543b3c9e79579d0df8a889e366ec1e0718e039b87a37c24d620e9 ac45b7825ec1419d1a2cae16a46cfbfcb23048a6f01b137660d3b90d1fe9fbb13d5f3c1f5c4c35007b396b0e9ded0f610b6c98f55dd564e0f4f973b310592317c2ea4cd57094c0a694d2ffc045746bbf5dc2cb742744c904e14fcee63ead9c6a +81cf067411dde2d0ab04fe5fa1e28e6975cdcc571588de60a35bd956a535fbbda4affd0803d244f3f7e6902a2c9a7ef2488691b6bef7f8ffb33be09ccae4c5285265e4957f7928ea5cbabd6823297f59a7cfc9939a49f26bde74c4c69e2d38c1efbacbcfdef011213843158072be84ed3c1781f67a0e2d4e9ba76a585c17fc0a 0059d2a06e8bfd5e14a9bc8777958b85be5e97af892d2cdeb0ecbd2d5017952b5042349db5fedba2e26e7b85bbb31ad313d99434 a64c108b2903a1e0bf120e104468d703ea8f2bc25bfb0c61fb3f6255cfd14a37e41523a5dbd35c163f51e6b663abc46d0d458fc6274c54fedea1a3471fb299997b9288eed8a3b6e01f7c17099744a985f076e068e8cf6bbd6b9149bc5188edd4 +8ea18387940035cff2f37278d321b344231075db43c7fa7fee9bd3fdefe5e8f03e7af9deafa1022eb108e19ec11fae34536a4fbac2e8c8139a081a997c080cbe8f3e2d2a72ff26edcc5338b21372fa1498e439e4d9bb12d51cc539f859047957b1b1f1fc30b90231eb06b365a4d404a1fd5a0e5cef171fc95b04d0b557d78ebf 00405590893cbbe18f4ad99df28b5f9d17f8f1882269aff0b7eee9392859d68927a99c942a3075269ddec6d69c0df2d76ab9d801 90b7bd16258dd065ed21919478dd14d644866142a441ffb220b4744ace9da0ad9df1344a9dcf182f4f88535f8ec0236413b3c942a819eef8a04d8f02d3bb11cda59766f39630eac553deaae74c9847727c37493f28de6f5d81d96c019c0ab4b8 +6a253c1aa17b2b1e6624afc8e7456d366ef5b1bd78e740538260f395481148a64da0b6a58cd53d7e06c691beae1a616547cd95c4d259a371e51c2c0e334c8a5311ae31e4c7af325686ff9f7a36f731010ee1a9b8a29169ceac36a060dd23611dc9713c615424888bb574ad5f5755d7311bd169336ae986c977a394bf16487c4e 0062bbb4f565aa0f23b88ab9029d33b995729d10fcfc33ba7c4051e2fbc72f15636a834e3ebfe604b927cdfc89f53c57f36890db 8c3f0dd79d73682a5fdeeed22073b746c438cf4fe6f9556ff872de565fed039417d39bf20120d4c19019e4a1ee0c53290ba5d87d9cba32a689e90c2396504fb6228dad6111993c730b284c8a4b9677bead1af8848c8d13dcb008e3151299579e +0f91d0f0139faf3b90a3d4bebd7e96ff6bb6f90f6c68321fb392637d8ab2a60d649a7b7364ee6e4e274e1a8d342caee36cc11c56c54247fb0a8e8ef81ac4322b454dc9a195dc54567bf47ec8d4fa4cd32e76d78ea2d08bcbce3edbb68fd8597e56d5a9f2df4e47b2701046df89615961db601bd8204584a6a6cfbb627e2a1190 003fad7031cf8810544a3e4bd1382c0a2e22c5a9fe4804ce67b27591fc516ee81dbac841d399327168aa6abd79e2b5ef85df1528 84701648dc9324d1a6467a89b35261268e82803ce544d6eae614a63e7468a9e3c3401eb37cf688262f1628be3f410f7e00c0326e80c4d53bd9825f1050894c45164295691de27ff98406c6a72ab3fda26c057837cd9b0daabad65b2325e2853c +50c17c1fe4dc84648e5c3c3ab8f7c971d4c58d8d56d2b5ddd92e35e6792111ed8dac7644ac8a07ca8bb4e38e071aa47b22ffe495e9083f9bf781ac1b5fba571862c909c7aaa7b8d05ddfb7ef61c99700de734d5658f44ae9fc908c85a2dac8e7f854d6d24be805fcd7f873a91252985c5c73129c60177ba8fd99daa87b25a073 003db41b4f637fe7977c90e4f1a21799baaddd1826c667102414877138436cfae1b9959842b8097b5276f15f2b982ee59df263c8 88d53993b08076b4cc357937a90fd93bbd922f76a478f00309307ab663150146d9faf73124ae54cb74c4204d518d0c6a129a3ad9e28d74c71214c34c5643926c139a3fd7c51a7282132697e2216af93fdf3f058b175282626b8f1f1d4cca6b42 +3583a3226e2dc463a462fefa97024e6e969c1b13bdc1d228e2d7823d9f7c09012390c2535baf086588000e908309090daac6e6d2b06d2ede6fae838ed47f30b5b481185f607a3586f6dea47c8f84e9d3b96d5b0ebae2462fde1e49d84d36658e87dccf5e30c0937feefd8862dcdb1a1ca373f6ae41641502ac54df6633a8cec1 0065b76c6093d9c49591293471286df1a4444e60d9d06cfa114e175afb5f119d2abeb273b0596019a0ec5db5b5869f2cc827b364 a1d61a7d437c7c6a494867c7c597a6cac0ccb359e6fb2ca32830d723f7528b8bc8e9b97e14c45b0a048edb30f82b97df0fb65c89132ab921ece97ab2eeeedf05eac957606092ce933f49167ad5b6ddd8d74a2031db70c634e6b68552ada17f2a +60ca58462d53d074b370127132f4e59f5eb8d15594dc721a94286afd082a8934e52462c9c1c3910f8b50d7aa3671dafa5972958d876d7992467b2fee3795a6f9d8a7bd3003a8582ea8c003aa1e02c08ab6804d85bcfa13a815d75c938671f0af0706c68bc70a6155708ca755cac2fbb68b2952208d63e0e2e3d816f04c61bc03 007e9993f3fc1fdc4c376ef77ecded96006ac1159740bd1b2dc6ae3d97e15a67383f1fc931e460b9af3fe14a54e47919667ed06c a736d479ab0c1e020450e4fa4af63abca32d74fbf863482fa8c5dc62ba0aeec8d3583467953f000ce5fb83453bdb6c53150e23bcc9a9c2de96d3cbfadedb0848d9db3c7494bb7df743d6308c4117eedd4cd7c31c1e5fe9f17818addb59c8708a +c749f9bb92ca9957ca6d0124206ebf65e860ff38a225e241950bf4526cef3f4fa9184ec83f71f813fe852dc08eca6b45b14fc7f2c6a19296529bfda007efe9d0d26492de2a902b45ed39603e22f0a763dfa5deadd97ef6feb859d860baa2cfd1d066c0be0f9f4e0e2fafa69cc51b12e814ad2e33b0acc0bcbe1df8cf018dcd4f 000c11e2979498695c660a2bdfd105b115bc4ff8664ea15cfb40c725406c6fc9a13027bd1d72ffff6258f29e4e19b845243444a7 b20ef2a3ab30e7ba135afba64b8d4ed1c6d2c2946805175b3529d0e533456f170fd57a97dea7a7f3b3c908e683df1430018ac34f4bd64aa66a7f89fd015f2cf932bd18fb098c7815af4a0ac325b78c30f0ed411ffc81c276043e4d75b9ad1da9 +4de8414780ea20f7943b1f1adae5e3962d96e828fee43bdbf2831bd71bd25df2976a3be37a7a667c7fbe1200de578920090d131a750c9bc09bd95b261234ea8cc25423c4ddfff5656d6b32da6e2f6f530e6673a8660aeca31273bb9a3a21bbd7031a2fa71ba37c004d3d1c64b2c0798783e47b2efe1a208959ac16e35d444245 0068dfc23c6635bd1fa1076dcbd456ad6e8df7ce7c1370fe275803befc4ffad007fd062a61cf1d50b93aeb9afe1aab47a65af82a 831931bb38fad90c7e2fe572effe3d6751d25413e7b7ecf82d40b80a27445ae47a97ddcab6113f636e6b72a6e107b0d204b91002bdfae1312a610c338d0981db411a0cb3131ae958c553173ac09d29ed11aba8ec9718005e14e1ddab184826ff +a081d54232f84bb19dbd52ec3812748e2e6486f6cf1b177b27929504ca878036547eb43531bb5b3edc81bfe105370427e92831d2239cca0106d031d9fa8da9cf89c6fb6401377d5936b6329ccad854e5567181b8f16a37c35f333eaa0ffe91d727d183fbab935fdac2d5670dafb3fba59e4fa2df1746c58dd8360fa08af7f4e6 0040807fb888e1d9fd33604546656a493629d94d4a0a9de2608962225ed158167f9e2438abe2d12a11e2adb6c2b66ed78215b0b1 8642fc8a58b0054739cb9d531d8159326819be53b38a193cc022dd9794288f451be9f4bb65665b73382deebc5d696c25085f3df735a923602e9a2c99abc1f510f62f760b5455616b0f794473b4256e8552ea71925f6001075d9cdf97f8fd3318 +ea60266f1538565b3ff42fa4bbfe319be070329059c52c8bc04a7da2824f209c1145a05e551ea59ded8ca8439c328f6907da4e81d658937df614be98c7b8648818ea80ef40e49aaa4431f4a211d62acf2611f5d60c446b2b25745078c643859be1b12b3141a09ab765dd63ea1f2a2df015eca0840087a5db378c4c4cce76cba7 0033bda0a02badae08fe40c239b9d59e5bfe1c4d4b9b7a5acda6790bfd77ad08dde5e93a2da80ec54a7f88146d72218bbb88aa10 b8a5d00395b02a24204d3944ce212681c033c21ae4ed052ee645804fa208ec53f443d4bf0a8c11f3e2f43c319039ff311130be9729f505600de73ffb9789efda63757fb4f0f2dc69de9207b51bc193f339b28a523a47fc1f38b0222a41c1717f +82f38c9405ef0d26bcdd5b3fce4fb0060c3095f61403418e17c337933f0563c03691fabd32ab5e896c593439e7492a9970ae325c67196d9e83fe0f9780409a930326f7e6efae035ef8c321cb9ad12461edd5cde66c04739fe079db65406b3c2d22f2d04b1a4335285513d4ceb901d2ca2ad10c508302266c2cd6079ff14eff4b 004ff431769d26b8837d3e1295f5464fe82be29edefba76323e92078a6483ea0daa96221549102509a1bdcfd46a5a2e5de10c39f b82f3876e33bd827fb90431f351e7d0d7a919f404a86470e4ff159f1f4d42ab65b292ff0644d0cc4f1189d147d2e3bc30d1995331caec0a0657b00f7b7ef8c889e58104264824e50552f2b41c76bf8a6d14c63b9c7dca23821bc235ac86c16f2 +d8506fab4f681ba4ae86066aed447571eba4fe04e6585fe3be6af2ab1000a3da68c5b0c711a85ddf3a40cb7c8944eef81f2094650459e14f5b848e6add7e580b0198070f873eb3ed5d0728eabd92bc1398764b94cbb4cdd7cc2027b9762dd10782658cd9e8a5022ac062fec535d892198c8a387b3d2b6f7c92b1af6ab7dd9e4a 003f85ca1169ca7e9df44cbc6bc7d2868c9d94e8f8b699a42ca492dca0914eb5789a9032218dcef7f95f959c9554a1cd83360439 94d2c294d1ecfe9c82c3193c0d4e40ed0537b7535e4ca4c40cf475c863f2af7b96556399d0957c765a9836392ef8b19b0ee28eca9a62cab99fb91579e8ce36b213491320f930729bd7c7c2e0ea9268589adf363e26bcce4e2dbcbc6f036a8d07 +b3f30d34f252a4c26f396079e773142bf61c0981d912333ade3de4e27cbc72cd8a16b31807f0c46116f87accb854487d83ec8c6a61565e6fca145eab70048245db08616779d7047db63aabd90dd15acbb05eaa510072c151c0518f1b34582b95f43ec7b9484b2993c176de79e84566764467f72392ef31619426d159c91816d4 003a97deb36d68f81f50c8829d412ee5de7f9d775633cb69c09dac558182039e275fc258240517a7c4aa592e364765321f27cb12 94041ada449740b8ef292f225a8f86a68272eedb4713b6b91caf34d37fdc1a79c883d748c15041a158e3b4b3cfaf790608e0b2b8842d1ee5ee744801c1e2d556f777b7a48171a13beb99ada8ca3cf7358cb1b7e3e07da9b8b4f89384b65d293d +0fb13b7c09467ad203852738eda5ddd25b17d330e82c279630b0e1f0c86681f67f6e537fb00da9419114973c8559306de58b0387d86e52d821d982a60769d2f15fd5ac2ee6dc55d8ac04ee247282cb2866b8cb8b4d7b4b6cfb33bfefdff09a73d727193e5fb939ff66ac5fcb644a44f9083a790888cc538c5eb435243c6a34a8 003b1da0ffed24e1a3b5ba22bd684337f6b08053591620541bdad50c761d66201a2cf21a4cc636426456525b598e96baf97d9851 afb2ab03c9bf4cb48b4fd64f184d601ab230ab9201a0b91a671d850b142d8b59670bcfe13c07162b15aa9fcfa6fe503e104c28c4487f787d6fdec1196e0c244abb3aaac109f8d3a9bbf268e8e551cd88ca362195f88543fed1402217badde08c +f9b8124281628cf4e1da0cb4f021c8d19d815644cd80c7c8de4cc62722904ec4cddd26cc4891f30b15098a25ba6923c6abf4774deb6e1883fbb409862f94467e75a725e7154be860fd58347577c83adbf18535c54b102220197afa062cc1c84f6094490ce488af4a08d2c5b808a2572e18a59de96c87162f88413795351cedc1 0040bac7e0d3b54c7753c79d43469e310d876015d948fac4e3a9765444754476af72330e88d79ee6119697aafac8435ab5690754 8b92a01bae16881335dff2bcef2b9c96ac2ba033033b2aa6a7195f296601b4cc4a6616bfb8837d9702e2f08654445e181547b5f910b1154ae25ac26d8db68eb0faa35237e4c4587c6328a3a5670ea6b6690f1b85bab81b24a2b3ca735104bbc1 +4e3cd6100520db050af0daa69fe3cfe6603a223d4f2a6318fc5836db8640d4c7fb80bb781302036d2d6fb8e552b4eaef3133b98ba2d36b9ef0b86243b0391413c73d48ecbf1d19170f1b3b781b35ffd316afb1d55d1dda8e91eed5553780cb2714a93e7ece698b832e853e2589c5ba2b8a997bbbbf625071ded66762af8cad42 0025b7eb3bdefba3c5134438caf968f615b315204f348006f82e8d61057a8a8a853230cf0500f9d0b8c1551a59b9184862dd2ed9 acda32154d287030f3638ed06d924b103dc1388ee5791862ee90c2aa4a6fdde90f164fbf2a488c237c57f00d22dc81a500d3fe1eb22825fa7cc2aa7e13609fbc3791a6af4ddb55775e23d57291b68218eec731de87d54c8fd6af4fa8f898adfa +5411708381a65bef4381c9e13a04cdd5ba0c15829f7f25ccadf695f635384d8e4704cb562741747831b33852567f42fedbd190d2980f1bc921ce01c17d659d4bdd7eb787b3927fcee659dd3b65132496c687f2249272a473d46326e66b3cb78dafbb522390162c168f73bdec88adb145e6afecd561979846ea4c8cee38dc1686 00673b3a2985c95904732632e5d988d8d437a60db13215bb6aa880b348f011c609a1e860461427a8cf0d622abc47f910f5c97ffa 9982d9356ab5335d93d9d5c3ce104f3626a2f513712b7b7d4629dd52f705247098be0c5c87676f597ce2f18943f63f56044ad2fddf5bacce7d5aaac8646c15442fd8c5e003822b4be1a514994de1d9bae4e2ce0179d3657287b82746ff477f50 +23757fa60fcabf543e603d8b31ef0cc99b3ed16b4816a84e01dbfc858872fcb79fd03d2f8a1d4f28c25dc42a39e20c34f81ebccda1682ee9bd22fe323e7f8ea90cf4a2a6ebb634cd1153cdc35f7306f28a2efd822bf23131baa1543d0ed5ab4c8168d3199983fbee117085f90550ec3ffa2b06070d3add1d707fc2593285ff58 000db7dcac414010b816236cad584dabeaec1da76c97182d1b62f87bb7fe2946a64d10430571b2b29ccf2ef72c969a9f045f1f3b 92308d85ad1da2fee98b219b3e7712c356b68984a22fb0ebb7d3cccc0b67e78537950eaf67bd92635089a506d2cac6e60fe04f7229868f2236a26b042600e7a1f49503f50ff2cf5bec289c0f08a8d3b713ca062e66c3921dca0faf404c5543d3 +b976314d2f066f8893307a726f450dcf2cf865c170e90e6908ce9787eec48e1e2119a731b2bec3c12fd4e6282a393774251bcaef91af6ce57c63a8b45bedd72ab862cd169b7c84b8f6a72084ff823a96f2f8eff3483a7ebfabdabf0998377c5a6836d88135cf61c65a0ca7ca57727da68047dc635c17ad13731035fe9a6402af 004717efef16e1ae267e155aa1daabafc68515aa391dfeb73c13d01f3132bd22c984228dddc4dff4c39979e7585acd3f730cfcfa ab74b54ac54a851aab3b3ce9df40e4597b7875bf7de661edce6d620d24906b6b2c778823ed9277626d032d2196fc60010c8195236056c433d18f726fd05fffde3c2435db66f5a84c855a0a46482b1af253801e7c75ee0954150a230d8d8d9668 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K409_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K409_blst new file mode 100644 index 000000000000..2211783040f2 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K409_blst @@ -0,0 +1,60 @@ +f153cc61981a46d8a47d17d29ec157fa93fcf644beb84558db7c99c57fb131dcbc5b65581ced5ff0b29bfdc66ff703ecdd4290f7c353c02a3e6d6867f33f3dccd1a0b6752b8a35fa143f8921a5078af9c85b212564c5b795da9858c7955095938fcd10c21e35e1abe905e84c8b4bc05f2a06091ce876d9519b96951d08c7ac9e 0011c6528939672bed3e8c905b7ba594c3ce95f37fb28044f210cccd01dfdb42c10e8e1a0b5d6fc757834ca7f08e98cbc52b0edd b9dcf4dc9cd46a9169d5a0403a9b1c5ade621e6dcbf2a0850c286d52deca879464b71edc506b5eb80b07e063f30c3562016b78c80dee01a73fb628d17c43b4e20ebb29aca4f82c66f3cab0e8f9ca91f11704ab9a5ba7c32649e4db8bc86bbcfa +258c91524423b5c876432b1930c7b07b56eb5e3945f1e2296a4e5bfb9b9123f800ad195d6104641b1f1970bca553c2032f83d17252e52403a9381c1fc18eaffdf026f7537aa27d84c5e3d6e39e651a92a41139cec5181fe794457f556b390943093be719acd23fa1ddf7ff0aaf0479484a381a309b4f681af74bf97caef08c22 007e3b714496dd118d8f3f597961eec5c43d0265bf85723b0b9b0616977e0acc2cf686cb6afa6cdc19114e27ab000e762dfe467b 963cfa95185dbc81a0946bd3e9236cd39485412dc3f161654bee99de20b0e4dd48d3795832664d225d32bc815f9d9ce611e7ef6479e478ced97291cf1efb99737be2c922918741ca00f91680c1daa0b02b84925df3a2eb713a513218e08fbc28 +a16a0d6fd57240fe88c7c36b9f7f9040cfcaa9afc4beeb8300818c5f90cce73b819a12c31d42af33146399cdfa4ed4954d068dbb0f1f342269dd29f1fe357e7224304b67b0f924b794780fe7e6aa9dfa3380252fe7177b43e7b1789718949b9ec1b943c83ed4399491482f0f59d2cb8050ab6f8b5854d76c50651428cd29c40a 00182d1e937b037bf7f84144f7d4c94c935269c9aae7d500aa459a7a0ec113b232dcf282908eee4c84b8106cd38cdc41db3f89e1 83d5bcf3d4bd49129c90a43a6fb4dac47bc9b26ebba0667e62221c5773e2968c0bd51ce7ee26100b5718634ef88105b0148e0f388e90c10c4452ba31bfbf406f8114ae6758f1977c66eb9333a66336c4c0820bda82f6b705b604f80de71d3a07 +d02ff569828fd1add21f6bd1c50cbdcd09222e458ee79fd5dfdba3cbb84e9d926fcf196cccedece77d5aa17f8c8cbf3a9facf0f02c71d5c1c8aeda9d75f6fd7b6f2c5c70dff992ef6e02c438fb3c66da5a503b3c39acbe2a069da457595b542190d818015d462670b0807c401e36b1bfe05baff3a8ccf8d1f5f8de7840e87993 007ed09428f460724c8a5225a31151e031d9949493fff5703369c401762345d002c4ce424294baab22d9e71edc4f854510cf0e6a ac9f18c1baf4e858474a7f543d609c2e9f4a8958d1fd5b99fc821099d63e781dada774b451044692d705414943005e1c1927ce952d6cdf72d8152fe595e1d21f0b28be47bd2c9f70e5d196f8ac243b1668fe8a24049bf4b53b259cd72b807c2f +57befce973b225cfce7f996fa5a1a43acd160681b88a87b7de04544eb7b6a719718f1ca7f559b6531bfc18fca3836d2be7f7a6e48387b7579a6845796d30e46f0dda9d82680f8c96c5f0989741adef9762c3db763cae2699cb6c112543635e20ed5cfb4b55ca2ccb32d2d13936085a8ff95ed658a54be73f80c912ccfe5f0ca0 00390f05b9619c27b800e99aeaf61ef7f6249367d5cfaeae3c7b523a8b29153eb8a77132f6c4412545a842d6deb7b7aea7e2bda5 a73af23069a9f59272ec71173f428f8767b374e55162f67cc1488112962b4c74238a01d950c1a714fc1941767b37903c0dbf0786233542a6b609d62f8666488ea4a04867c61e125644d8f02356416f81c8eb2f2ebdc6eb624ca9fab145cf0a8f +4277ba40cb462860ca722cb4ee71c61836d2ceba18bc91f3fad7dea478972c6da0ebc02815eaaada1d1a5e93d7ab353855ccfdfc94a5742fe18daee2328871e06c1ab0a9a989d1239df2d2d27f96c415e7ef9a941f06c6790675361173cc229aac7045f49eaca207f59c497619ba32e932b5c1c6576812ee5b146e2cc7de5e62 0007d18652732596add3db31f7a0ce6020d03f3df58131b0c7c633faf619b8210cd309d6c0c4083aef1a1b6d2a756adad0bfe344 a91076b21d1ad181a96b6baec878765352b5670e8a1511a94488fe99985478c09dcba7e6d4987a2c31f9ced7207f8cdb020b2725e59d3177ed095cc09574a014d5df164d30083fa621357560df0489692b42b63f8850bd2c5decf56cd83cc5d8 +57ff6792ed4b12220d179bc0ea57ff217f322c85bd3676a681d32d7e4a3e0c8e891fd267df17caba5992f68c35ff670b60b4bbdfff82404f6ed996c30539bc395120f97d4d7a652eaee82bd8f9360bf8bb73748b8bbda9f9480eb54f7eaf2609d4259329e8a5ea020521e7dbd3ec56f23c849932cbdf2875f5d5c774a9d6b0c9 002a91244ea4623b63403dba807d60b914ca3b901a2523244c322f2f11251446d3f15e869d086ebecfa1a39ce304e8b5c8de23e2 b2bdd0c80a136a220ce4c1391f060d1c4e5cbb25c43b8a1691c3ef609dafa0192ed9b937dad34d1864b8018ba7d7a397171ac705df4286f19a88bf3f0f975529555f439745059ff27ecce3e232f4e47f3485a92f659afb4292da68d0ff93805c +f85113eda64478f460b60f8084220134933de049200a5f37884da7901471542e26690a5fabc3cbf9e679ade71b6e54d869bc136c3d34cc4a9efcafb777abf046b5ae5429136112a9a36a475121eb1f33f1f43481286fc1ada98a41064a1fa38c89e99a93065bb2a119348a9e452497fd5a0d2b83a66b09da9f47a0583732adf4 00068c56c6b5d50d1d4e13d3837d8c5e8ba2f825e121b63e97603fdfe78bb6899600ff0dc87b6b3b6868ad0d2f62b7b7a31603ff b5cd3e9cd84454a5faa9cea7e26940c7a38c68caea6ed5ff789339c07a7e22abef18b74a55fa78dc1d8fbc00d68459161402dad6e1b1c229231fa0412e6c10ad8842bd722107a5517d49ed4008466672905eb9baf2c576ddfa5234085a34ac18 +42811e9ee6dc509572e1cddbe5baf00afeb0c5c13e3755b922eee9e210001676082bc9edc3d78db2b5bebea7a2c0cd2b369226c2b8f83b28f33fb513407ab9d287d14b112d6c3be2493805ace5cf6fd366d03cfb28f4ce3f0f060880db64d6962e997463ba7c05b6fcd1e66babe4b94afc5c2d38c7050c69571d27b66ef0090b 003c88084f8b78446db431bd6e240a0c050813d2a763675b0ea869cbe183df697146cf29c03479af3d34587a95cd257027fbeed8 8849f9b82512429122696494221c6a34e3373dbc20462331561437260cd4c90ee5713395fe2d01f309bdfcd0979cd50500a35df85233a81d08b2f8c06463aae1050e0807209c0038a4dd35e70673e6fdbc7ac46ca99eb722721f342b40c9307f +b38f76ede7441ae0887e689d556f43155b38dab7cde487ce9ef9a46f2957c830d4d28006873fe2368197a6931f6fcaad755102686a457a7edccc8d344e2d2a9162e3d71d41c09a022539ae6d404955a6ad748231aee1f974d4f159940532fb3b1fa0254bfc5805d2fc68696856fadea386c542d3cefd1be3af04ca595e54be25 0051af7b63bf3297ae20517faaa1552f4fde65819dbbff6a52721611e5b7dc1242ed6e69768cdc37ea8cdfd1a5971f06b84b5803 a88e1d254033372779c07f3db67e4cdf2f3f75a2cb11df9076646300f2f5172b04ba3b469fb09e5f686ef5a27a200ebc14dad4b3a602e531e8ae084391b02e6589b96c4aee2ca1c59560fb13649b73ad9f02f1c81fb11241a4bf74eabdf4c88c +356dc86cef7979148e995fc5abe2b14a7d5e4e42c9b3509b4363bb80c581a66f4e7e4aa53a4bfd37f9a7eccf75fdd726f348f6a3f779e6599f61bd1d668517f40453b39bcf35db0852a6a6218198f52b7ceda2ec55fca5abe8e5d93af9a42b9ae4de9530c5870211bacc27c39aa094013db703de2fd3121f08d7e97dbd4e8946 003d65bdec48972d03811b78150a06956eb22d337dbec5416bbd8185a6322cd8c0ff8000210dbd1326422289071cab65175f5d10 8347078ad38b260b50074a90e22cdfb0d1875ce5d3f3da9aa8c71845677627d7112fce6754204b9f15a24840678495a9009d46d584b92e3d7276ce338aea4aacf870a3e37e6029f46d7502fdd173d03f205994f97451d5fdfba7aedad63b1d7d +06fd39a50bf25e89f1071ff81fec5d1e35b6dd68990414ee403dfdebb792627b6a4ae3d2236c159e4441ff90b61ec87b1592c538515f0486b19e58583394a05e6411e69b4285d6d6589982ac0eeb2c912c4948789cad741183663fc070943389d4e9a1150b8f6088fc50605915e9e24b2d98a1f539024770e4820e14ae42ea8e 001f1a8b5f35dbbf82c102df550c72216a243f986f0325920f6186a16d1da74228cc02be6024c7411160c183c923c743354f9438 91c469705d6901befab24242298c8728f9d6c6a066a4a14f65db8e3d3b172e73ad532f87704f063d396fc8b2fddbdd4818c51bf33e8095c6e594af7ae3a83d8d89def1a6cf62faab7228620ea9b2c414276f906ac09b6ef6cc4c449367a7d5c1 +6daaa41150ea252a3e966a338377307d909b95080e006f13027f2be5059d9208930c5a329994c0b794ef50eb059bc6c215f68cf42260bd410f9bd86d2ad5ab7179c7c92de4a93a5f6aa17de5aefea815e7c0b78a8cc53c21dc4dee037b29c9df4e12343109283ffd5d8a3b81fba1b5e95506c7e01ac056c86dd0ee23bc21af0a 0031dc621200cd174193d95e9092ffb86189c52cdbb9ed937593f2cde7c4a0264b9100e1b8407336c8dfb5520d28a18dc4e39a89 84a27d017d67a3c61b9dfa5a7826fa419f6518dbab240db74e68b34bec5727ee1efa28537c2e6fb8d24529a49b12073d16572e7d57090b8465c88dc349409d0b30ba4d7a701ccb0809e23aa58269d7e419cbf27435b4128004b5513be38f17a9 +6378dd1c12c5197b57d47dc46a67949bdd1e0809004e94d49b0234126a08ad5bf8723ebfd132145813136d8b7dd096f56c34248f09a65c34f60c2f80f9a51b3795f3d2518b11aaeaf6dd45a323794080b78f85d629e5fa719b6ab0b14c78cd908befeaef0dbfaa08cec9318bbcb376d48b11b68735c9554a45293db5e9239ae1 0016e6750245a88340b0f0665b890459f8038e9b1366f2fc1326245a88d4c523ec94429f21869ce3dbf75126e58f77241c99efaa 944fa8a6199efde611dbd8dc0020996de257e0357e8c8d24885c8e5c5426e13df952601296edf570d7a5b308c758dc7e1320b7bec6f268426b5e4ca5d35208f9b65b54a446f5367dbcbe852008d62f0dfda7f267dd82299596bbbd71c8d77f26 +b898d0f9bd80e083fa541f457d14d853bba55b120424a95e1d9511c8833f48444329e0349d68204c4b4581ef1c4dee23ed0a4445727a72e1e6cde422f7c10ae132a3fe681f9d741fda263e73f7cdf10759467c9d76164086abf6780ad474772771eee22d195339bb8f6235e0d992bbe282b13ce4fe01417f507a2c4fa155e108 00788fabdafeebb72f6385301e30024b56639e629a400f9c50d402cfc9b5817844f06a451fbda29c7ece41dc9ffcfc625fe0ff0a a44be698165dd7bb4f6569eedd6b32f53f18160100f4d7b77edccc600c3173369797c671729db94d7fc769cb63969a0e14e9f06d9a02fd0a6172c7b177b41b5e905ca389ce6e2f6a517a77b16fe0b093c150ba57af0fbd06e9f8ca4b0e8824e0 +dbe04561ea8579672a2b3afa94426a3cbc274b55263989d41a778bcb082da797d84d930ca847a481789524940701cd5f1d11b460bdac0bffb0b3a3abe1ab689c519700de85a0a571494ba0cfc3c865450eba7a9e916b7fa9df55e8a1c246c992e6a0b44b78274e008472bed8d8411633e6520e1a906c5d0c8aafd572fe6f1f64 001b8dfd64563dc219d6eeb53f2e3ad1d771140d0960b211dc1f757af5e297dc7548d6133ddb574711d466688f80dbd65a7bbcdc a8e0564a85c64b0fda8a9451a3d5db06a5b4ff005ff59ac63e4cb5289b07534d91a858ddb76735c581e5757c7eae5c400340cedf4c24b2664693f58ad926dd39f9d1f009d1f233ae1d20752cfbec5b0577cb73b88ce1ff643f942f6ef9f91e67 +48a8300820fea2ad83c83f7d6b24192715329c3f159d56644e11ed25efcbd3d31600a813b909812987b97d1087e74a63b4494cc031c63492b6615e9d6e5b36f62cb2ef88b9f736595800de465789f43811165a5fc093ee6d776008739de8de2a84e878748641be8bd52e5b891c4145f52bbd46644852a43108e93d86352b2a3c 00422131829608ff730c24ddf7e8b4a2600eaa9681eaf45432daa7d41fe2fb488fd0199d431a1ed823801ce21f4f01a4dd4248ca 85ef2690a241f7fa3467aaace9751ffac2de0c444e7f6314e67c1d383600a874c597f9e68488d22900112caa483520af01830dc207ca9e6c062de0300ce9f93edd552baae2cc24a5078711fe11dff15be14826646d7962afc2d35ef52b9736a0 +276e3a986ce33256014aaa3e55cc1f4c75fe831746b342eadb017676b0cba7c353b3a2b554522c12e6aeaf1364cd2eb765a404b3d0aa61258194a30219d76d2bfa98ad20e7e91756cf65e50d7914157f283f2ba3930c0ad3a97532cc747b1cb9c806fff497f0322025a3d02ff407fc7b5808585b91d95523c9d5864efdf7d983 00095ae8e4c7e55eb5da01acc05ecfe72a4dcd8ec152f1c8dc165014f70eb4e4a7861aeb2b96c418b2d4db58659e76184e013a49 99cd9f2206b75dcdf9b68938a11cf2e4c6a13f4dcaf756a3fc6947a2709df33c1a60bcfedd88eb2307a63762a60b53eb11a95b85ad739ce05b10d52e46f8d5476e95b1482c35700c4eda790df9ab335cfcb9049cb3d265801672710addc2745e +6a4fc1827c3a7256faa8ec6a0f3d23559d6949f8cc20e7f76111dc4ebd59213951cbf0eadacaeb8862d6baa0cb298645e4314b1c303bd0d5e9893304d4b7fbd36ab05fb6a5edc3fef763e3a4124d61539eb616b359c5cb55b5e2bec50c91dd95fc39ddf521aa854216eb5a707819fa6f067b316a17a3b146e7cc2dd517f7d63f 0006f2075bd730f34df111ebda919167b1d3358ada32cd6747cb3353bcfb814a77ac70cd51b31a0e538539453bf9eaf9d8b384c9 a4acc3462d125edb2708403ce2d62af9ab014fb0302afc77a2d4756fac713172dabe0b7fba455b13594713826a5d7f5b01cfd97c6682fd3256808e8fd73a06cfc7650962ee68c16bad21e31a802abe3612e2735fdfd75bba0529a611dac98b50 +4b088199bd8c94775d8ee508377d672dbf50f6d2c7370e99821ec8f9387492fb2eebdbea473ea18465565f79e2af418555f10c4a527e05a9e20c9c00b807dc8b350cd4ccc2d87e91f66addf02ce4f43597aa258ac6fbe9365cc2c8e8bbe5c884abc929710e8423cd6722a8f473bb55804159a92a3d8b6661a536b4fb9293bb0a 003887d284e9ad17d38bc6da9d83c192a434c509340a7f233cebb032b09ab7c4c6e8730b4a80844898616c9abcd16b753c6bb4c5 8b7ab89f728c59232bdd4adbc2818bb7c4d020f12218fe7f7e6f980db8d6ee3819141bf264bf7889bb85d579d44f61e012727e703379631ad1a8e0489720bef81e782afff16b4e65cf2df9c9ff9df20f833607bd8cc7d4498e5e681bc0310663 +848a13465ddcfb2dc14f7bc0db0756832c22dde1e31e4d8b3ae0dd1aafbdf15e954889e95d3bdfd6e5ebb6171fad62592c23277a89e8ba53978c9b1afedfef7e1c3f6d9f31077530460b47834b30bbd84a4da601be988738aa815d3d7e72043243a5288751ee08b4815a017fb5d9bd55833698a0d526b1ed79da35ef0fac93da 002ea5430610864257c9dc393c3addcd0d8d5bc8aab1067643b08857210464428aa85cf1ae6c743fd2682255d4c8eaa46ca21e73 8bf29f2a8cd322398b1b1881642ebf859c61a83e979e000b12e273ef0df4f274d9f64ef0da110133fb47976b92bfee6f0201fed7b3d89e34df423fb0876e52f50cb2dca95e66316bb0b5bb67d74a3c81e6cfdc1990c2a626462e58c3ce3de0bb +d1850545c04ea65528849973c220205c35eae98826d169348970d1420b4d872ce233af1daa9e62f6a562544ae3a0633a954a493e9766dd5d87e47486559fdf86229a7c9e1726de21895abdcf2422d438f4ad98d88b45c56742694ad5e11894253270997c049f0f419842482f21c792fbe5613e2defecd485585f1835b6f4c578 0062c757c92eaef41f5d81169ec4968145b5aa2bc1d2a3a5fd000634777748ecb93677b3da12e3be33272a8f0a52300f4a5a37c4 b2b1dec3ef8d3711d79634a186d87698582882951d5e8dfe0a617e384b3ced5699818c93de9980f8e977c1a0dfc6e8d8157a95c6585514d985d7e3bd75bdb0f0db3e95e33b89a12f58c2b4e785b1108f85054ae9d0cfcde6f978cc3bb78a47bb +421c9784d6fd507c82904e1054edf9bdd1efb58a0b211340086069ad38b7b0dd15c2345fa8767ef71254ed1bd5c35f742b1d3f4765ff9007a5477ba9e5d3d5a5cb5fab4efc1cad73701d4776c6c4343f42b5d94a9eb78ae428dfe5fbdd8e6ece09d5b75cf4346cf27db856352225ab04e6ea56661554fbc39916accebecb3935 0048a313c0c11489939fc0cffc6ccb9f179093c4e13141b92dbbaac441b7ae878c9d412066e95615174a24692555cbbe904a14cf 8fa5ea80dd60be0eb430a598cdcdce564eb1302c6e2d47db1dbca311f4160afd6ca890d95f0adf90eae6cdea17ad8a280119a65c3a93bc122ec03955b8a60b28e7f172a9d7f077fab630b790021635131c0e4aff83ba71ea9d86a867ec4ec7ef +7910bab15b6429947655e33a67f41b76f1d7b71534f8904d6a0472c2faded038565272d0b5f51aa915e0d624e9ff48d50ebfa2f09324864f26c29ab73eb39b436c5c459c7cff4d2b62992e3489cb4ddfc05d7366b161a463aa1b782641d93507de43c8cd0a0a0a9d1c644f4554e3edaf7fd794248110ca9387e73ae5d00d299e 0046e2adfe5d3549e1e6fa1fe69a7cbb4ac9b111c8903d544268f8318b0b47d4b78fe3e56eb5e639ad5382e7cd5bd4b2c3e70ef6 800c5b94a1aa1346453a6d9bce02c790f6ae127bbbad4ea5bc75fffbb8e0962501574b53bbcb80462cd475c6d2fe439716864b3b93ad7c3c026ba90ab53d920b2ec1d416f562c301cef4796067c3047db2140833f800c049004902b793b838ea +e6fc96e060b956c25d50ad25443f3c30a12d199a47451a49ce88307201dfb15ed816982e8888a28daa92eaf3c5584ca6ab2ca9e14577f84396de2e0ac214b24a2279f5e7b344fb7387e9afc8f0a2b77a4d024a20ce6183499b17096947444bbb753d9b39e5c694239d28f9c454bb05468d17ab564ee6cea3741747ccb7f108af 00480103fd6180a431c837643566706e2b9597de0a1346a224d176a5b2c54aa4d064418ed654a5d39f4773fb509f86473ebb373f 93818ea599f8aae4c4f64ffff90a231e806f0ed1f6ccf929deedba57949279fd1644db71c65aaa2c939cf31a9f3502ac1909e8379a7aa32b052658ed8b16b296e450d7e6285b4f653395a2bfa232d3d37b3ad3751794c8f4a6f67529a7dcd3ba +c8a8a0d41f35537e6fd523ee099eb45e1ad6ab54bed4d3e315e20227db03292e39dc1a91bab439c0d20e36e7fea6ef08983f390a6b5551ac3b4f1895220b2867fab95552cef9bd8702962839bd9b2c72772640e7d3be3c5889d226acbefdcb448432bc503e5a5fe7ae9ae7696c720a799f9882c64ae0385f656074dd8a6821f5 0013c489e8311c6bef02c8f58903b2ba2a98a27cb935d75a30d320af9a14fa3cbc6adcce09235a9eaf333dd05f4b2f1694985dc4 9995a233ae40d0c4392fa5bcb00da376505b1acdf9c269d8b72a09b310160f57b7ed6720d83b7cf81f741c1bdac216cb0884b89ba09c14e1ca0da89f49e01beb50fbaf721f04d8345fc67c512f8928a69b37fa64f57f35e8baa5a65968cea7c9 +3407cd6d2845197cd7414a30fc3df7184da204222ffd65c4d16a12cadabf603de8043ea14f5e6ddcc22d3572dc06dec1a23cd924e1847ae285ecf01754e2d1247876431eb98e897e47412a2330bb32990f9714122109e94b38f82cfdbbf2eeb4c6f88f5dbf9f0ccb47939df8be321dcd9bfd9bb99cac9f94885fee7d443fbd87 002419bd2200f8e1d87db848b0379741685e680d9affe693eed49d82931030b6cb05d21a4965f4e1df2045c8513a8f574ca9f2e7 8cda7469945eaf5d881d3665c9f8384b54e6469ea374b7831be31293dee9a4298e211dfff7f88200af6408decc3f8f1b0cca9efc58fc278c62598678f742500721dfd6858aa67ae972c771339ade7f722653bbfbddc243364dadf85498079871 +ad43f8440071285d01fd79244907803601aff4bc5d14c77483a87cd742144d41c68269d76c9a83c09d2178bbcbdf99f927b378497ffdc907a75a3b0ad019e69758dfffa480871eb6e1e17c8539373de611a557fad120d0bd147f8debe5f09a02e56fb607e9c1253ed592071f042e42fee39775b407225a2b86a950d81bb7d7ef 00722951879a65bfcb414e11712ee9431eeb32319e0ff28601112f89276ffc2b96eb65c7fd77d023f09914a53e2aae2c84652bad afddc4325c13c39dc68ee37cbab74e73498bc055430c5b08c6b605e19859745b170362b1a849fb29c1a36d4f5cd2f0fa001621ba4c6b037b790665070db3bc0feda317988ebd7531edf65e92d8c82f6c9de5085597735143fba0bbe49966767d +d61a3765229dcd0b4fa6c57280f851ec2bd54d3ee2436935cd6d94e0120d0844adda163995fbc4cd9d7275da859ad8ebf30af9efbdcfc31c7c9ef42bce9011d37cf9d15fb018e117bbc102f7d05750e5072f73d02c2f45509a55627a78cbd9082cbf36807759d1fe2ecbb92ab30cf28434941712d38bdd100955d611987b5968 003f5b5a772d24bd5454bf26759dbd433fcc7bae4f5c593664c4d75da0cdf9430d7d9162bce3d7f6e13a344259da5a7d6a1635bb 90df3cecb8d213b2b847228befc1271c25a946a5d99f5e910ed4864dc105917fda53b889f8994d95a2c4834def0739d318b131ffd83796d55e2daa15acbceb747466493a0fc682d5136f504acb663391adbfbd0c45ee34f444525aa327097847 +1f3c23636414ced48fab6763eed5b22537968e6bf08c178b3d31fb1f6ea773c6979759701d94bc1bee7c354272811edec58eff50c93331b22723d460e56dbee90466b894354777b23b13a37d15a84c762caca70c01518bf34d0c2f072145d274b3b6c932b48bd815fe81161d8507ffbc2f783bd212c29b2887af6d2ffa9d2b4d 0046bb4a141c9099d531dd23ac440eff1f5b10f7cf34920b6b702311d490d25344c665ed5211d401def24986c8094165d10f8934 b93bad5a8ffebe8b403a5d0c905130b34a20f3f81937e4aa82e7e3ebdb12bdb94d583be4bc974094c0124b1d66b5c46e173a6e1b0301c66aca8b2d3c0be3db2a89a514ba8311f096eff5af07df86630027d49243a025dde117631a2d1bccd2e2 +ec69f2937ec793aaa3486d59d0c960ee50f640a9ce98a3becffc12d6a6c1c6c2f255d37d29f9b4d068373a96beadac98fd5203a9f229bfc70bcd449640165ae5128e3f8d057769e28356e73e35d8e9af7876f608390090892c67391ddfcc1c332aa61efbf72d54bc615998b3be8ab0a9d372784bea48c9fab244482c75cb2de3 006f2c6e9ea8109223d9a349fce14927618fc4fa95e05ecf9aba1546619eaeaca7b5815cc07e97ae8cd1e9973ac603f84d838393 ac57b4741abdf71948ac9e662b4cfd671214a18fd1e143c8e3d990e1320acd144af8cd5be5b606ce07aafeda4a14ffd3137882fcf5948722a40aa2fb1411025fe01a7450f4ca66fe5af26f78ce1e02cafceccd0b9131dc7d50c0e8d4d393bc34 +70e11efc78d7f079ae41ac3c31c96d3220f4abfe23814a2a4a78d9b1a25e838c3408bd416062e4b0a5cdadf0c6e16a11e00f59711b417751f5e4b43ecad99efbdb2a81c91a034e89edc94eb552c3eba62808563cdf64453a1db07daff8742aea4a9fa738e1322da316b26dbca2954b2bc0de6da7518d28e6677dec6ba8af4285 0004212b7fd913d794fc6bb33e0276e349c052c969ecbf6afc89b28f75a599a9242acf74dec9f374361ba296ba42a38407f9b7d6 9997adba0aa5ccb198bc472d333e0164f59f3fc1dcbc33445d0cff4624e1a1ecc6b1c956e4072427adbc216fbebc85060b018acd9fb713bfa7abe9dd20b5ec7ee9b742443d8608c1315a4fed773c50526476d46c00c364f88220a73d236450ed +d922fa515e3bed60b517a2d37cafe4c041e5ab4b5c8d8d4011bf9fc4013dd8abf7add71fcfde5e71d6abe76bd0f749e960cbed55711c87b5629a2c39cff48ed7d0feaf5cc4765e576a4959521f9a45fcba0dc65ae618826447e02ce6e1cab5ce8d6c96c3211adbb0660de7df7453f3aa726016941d00d8ee536cc106a603d126 006baeebb5ffc89c94c3e8b37b9b0904e7c4b251d204894655bf3b1235710215c29820b9d401c9ca7df1404d2d62d708aafe208a 856e4652877789f8969138657e06658f8e35ee0388c1178db709fcbac73d4cdbc30b22297ae4ec9c1afdea8ff086aad0186523611951e549c87727d9f6bfbef2f55a2365a86305189a458c202cd785e80f44a16e05f61d3071b3f5bc36939787 +4f64d0f6bfc542a0d4347576935bd68ca88524ead03b8d2c494061d0658e6c3e14576b5bcea5f2f992f54cfb52b5c7cf1dfc517205e0454510eef1b7054a8cd06ab53ed2468193f98ff0dd62faf076549ab2a270f259276d5729996c120792c6f466a74ab65035bf38ff2c055b43e2a8b8e2449a2375ddbfc18242157bd905f8 0008e5f66ba53e7caad1feda122a80c32c82d2c32a7237b8ee8ead44ea8f2f01d77c7056b9dd60b92d051f060da8532c1fd0e8f4 94aebd7bc2805a9b6510872832a6c396f702e41f0745abc1304d7cd99d79a2a5f9c14be946d471c6c17a9eb2ba5ef4d6147146ce2f172f6f6595fe8eb76438d7bc52fe82d7d62a79e7b0fc5089a11bfe01f94072a997753f36aacb1ee624f0d3 +7047d478ec5282d55db8c19c97af10951982d908c759ff590f27d57e2664f08d526cbb2bfde39bdbb1aa3dca5a8d3feb50b868be6651f197abccc9d8040b623de367e2ea1d20ecd302afb9e273f4be9f3f64f2c2eb3f92d5e0e375db6549da2a589f0604bc7146562ccefd15995a7c4208f640e7a17afbca69cda4e173380523 004ecb22b44e809f89b16abb10be062c89b41ee34e110403e42a20ce59a99afdc22f6f6dda56e1d9d1b8ce1d057f390db111def3 956b6453caba67b9b31b0b07849f2aab8800d3195e58436a6435854caa31c750b0a37b674d9e6951744bd0d5532a92a517f8d99e548542f755c82fb56de2a0bdb471c6bdcbe2b7554a1b4dc6d5bf5aca17c8e33797ac1f06a594167f5ae8c5c3 +1a8384b4771a410663e56eb36c5d9ede8d161a8fb0e31d3f74bcb017b9e31232bb2e2f4c65a2d85bcd1cedd93ef08d4bb4af0095731574ab3f2762788a1ba3bf0ee46684da8d9dd384432fee99ed3c69213d790a5d81b351063eaf2bda71ca4868ac36be1b571024a8bf09039b347fa996d5d161078314e24b7d073e05cb3d48 0051f9500c15ae73d6d479b9f3d2caccc2039d8d03820befc2aae3bbaf65d59bd9cb3c4e3aa8bed5b3acb70a5566047ffad80729 a7e40c001272a9b9b62e1e3cef2145fca75b82f59d8d977dd6fc7b73a2766e5de16d91be98531ff5c0e6dcd6dbdbec7109ac036fe55984492f650b18ce7fe56980a18142611895b37bea7aff014eea6abc820d02f4e1a369b8033c0b152f14be +43513d6dd8bb0af7a6f5a2b35f99957d335a48d54f2c4019ce9518b35441d4935518976ab1df37110b5b53532cd9e2c66d9f87ae7f683d7efdbe1775a6c15eecee84c6f879999d0706f6779dc158c111fe8d7201983883bc8334f51dec60004eb1087347bfdab20f8f2f260556681e05fdbb8a6139857fd3bb2df5bc1f2dc143 000cf01dc4462cca764f4f8cbef48c51980737b9b98d1384b8de9f4c733829db7718a9b5eaa46a8475c2144fe4454cb8eeb0a443 b8e1d13382a4ce5d966393f9f02edb3d81ebf9d6260be36d2ee2d87c0d975eb10c737db1e3d0795e2011fd485a53cb1a0d5e02223b56b38c04525d26fcdce0d68abac07cd6c7a3da6245fa09e1e2c373a66aa6b283fd95eeaaadb5e5dc5764f7 +752300bc5066d0efaf807183a41725e349907b7339d77c79921ead3c685b616b0eb97e708f3880fce0136c510c8cb53b22cb424af6f1c34633600939a0647c02d8f9601f9416f1d24a51657241fb559c25dfba91402cea43bca1a13718b3945b048725f3df560e6717cfc6ebd894e29bff1e0c7763f15b8ea93e67385f059598 0063a9a565497974c6dd459bea0d1196d74f263f333c31b7e8591499960e1cd79e2ef4cc8709f6d54713f873b16e7b0be42f71c8 a94043e1d2a8a31132c9f2618dd9b75f485b0083241136679ab2cb38dc100f137bd858696d7cae69f06d87aa57c93acd0c16c3d448026b27127bce341cd7c4aeaddbd0a0e8ee28ac111b6aed1ba51a99f0394bb7e356e52e7c2074ef8f7b01b1 +f620603489944769c02e2f902c2299dd5f32b5fb463c841b7e1fc0249a85d2c31684bd3daacd97de8291c5d39e84d6e59d3dde1b30c181bfe8d31b8d8e080bd191690a67fa00024ac8c1b10981b40d4f88789ecc58fc69b15417fff34834e23453bb9933a43d08afab74d056f366b40ad167b51ee5f008db151a12b467d3eaa2 0041074dc186193d30aac7cc6d269b938ab40b257d095e54ba79967a377a91b8f73671470cd07f0a3d1db7cf0a31ba9070625e43 b0f288e8a6d2a0e5431e2d806fcaecc00657c5a35e1c9cc7d1de6111867a3044db5b9d49a5694f0c9353bf7aec204bc900eea2d9cf79f0f519fcddb2eb9b75ab2a56752d29d778c3b22b8db6639618c5096f9e61b8112dab2d89b94ea504eb48 +5575f610762b42ce4e98d7bcf45a7a6a0d66ec7f27d6b8b17f1961249d905bc7e58e2ce0806d467f106b16285dce4544c72666d08b5e2276cd0c4e13187cbda8aecf57b1855afedf8fad39ee4fe009f204e60bdbec79b123456ec2d85631d382b8a2f2c7634af3992e4707f7b4215e2c9d3b0aa8fb08267953883a4213669d33 0010820db54ccf0226161aeaee79cfd2797f87702b4ee91adf8543b3c9e79579d0df8a889e366ec1e0718e039b87a37c24d620e9 a2520fd0683bd7d074745a6ebaf406684210c2d60e025682c3abc2fcf8edadd4403d6119942019dad430ed62f46d32e906bc39b6bb815aa982fba2c390aff63066d6ee3a81a54bed2dc67cb710c25bab8f794c79363e3abe7f2545232c7c5c2a +81cf067411dde2d0ab04fe5fa1e28e6975cdcc571588de60a35bd956a535fbbda4affd0803d244f3f7e6902a2c9a7ef2488691b6bef7f8ffb33be09ccae4c5285265e4957f7928ea5cbabd6823297f59a7cfc9939a49f26bde74c4c69e2d38c1efbacbcfdef011213843158072be84ed3c1781f67a0e2d4e9ba76a585c17fc0a 0059d2a06e8bfd5e14a9bc8777958b85be5e97af892d2cdeb0ecbd2d5017952b5042349db5fedba2e26e7b85bbb31ad313d99434 a62100f2ed3b89cfe900482c6582e6f5a1eb866a10aa58387db2d071c3a4e681bf1f015ffd491660ea3b90297928a4f713afddccfdc6e8c9d93a03c60fc2ecc71153167c75d4a29a15af515ff58ddcd4547422ada7bd0d1a2a098367613ab14a +8ea18387940035cff2f37278d321b344231075db43c7fa7fee9bd3fdefe5e8f03e7af9deafa1022eb108e19ec11fae34536a4fbac2e8c8139a081a997c080cbe8f3e2d2a72ff26edcc5338b21372fa1498e439e4d9bb12d51cc539f859047957b1b1f1fc30b90231eb06b365a4d404a1fd5a0e5cef171fc95b04d0b557d78ebf 00405590893cbbe18f4ad99df28b5f9d17f8f1882269aff0b7eee9392859d68927a99c942a3075269ddec6d69c0df2d76ab9d801 b535177131d85882c8b78f6bf43a739640fe7e8f1ce0773c8f1ee641b3cd2a4ef80464a2838fedf3ab341e9065229e0006565e1f3d980b20baabdec642a19a86976f9a3289a0d0102951caf24908f6593a08c2c012b7405b27aaffac012fd046 +6a253c1aa17b2b1e6624afc8e7456d366ef5b1bd78e740538260f395481148a64da0b6a58cd53d7e06c691beae1a616547cd95c4d259a371e51c2c0e334c8a5311ae31e4c7af325686ff9f7a36f731010ee1a9b8a29169ceac36a060dd23611dc9713c615424888bb574ad5f5755d7311bd169336ae986c977a394bf16487c4e 0062bbb4f565aa0f23b88ab9029d33b995729d10fcfc33ba7c4051e2fbc72f15636a834e3ebfe604b927cdfc89f53c57f36890db 8ae56ed324dbdd8c6de302e370c84541c4a50351751675fe40043df3496241a8fef7033fe6ec35891a7be4c51af172bc04d0a9490a099451140c01a9e4ac8d54f58b1aa73ec94eaabc5872ec194b222cdb38aeadd48d4ad36ce7ae0c24fd6afc +0f91d0f0139faf3b90a3d4bebd7e96ff6bb6f90f6c68321fb392637d8ab2a60d649a7b7364ee6e4e274e1a8d342caee36cc11c56c54247fb0a8e8ef81ac4322b454dc9a195dc54567bf47ec8d4fa4cd32e76d78ea2d08bcbce3edbb68fd8597e56d5a9f2df4e47b2701046df89615961db601bd8204584a6a6cfbb627e2a1190 003fad7031cf8810544a3e4bd1382c0a2e22c5a9fe4804ce67b27591fc516ee81dbac841d399327168aa6abd79e2b5ef85df1528 ae02c7ecdf9cb20ae6efbacf3f80cdbfbfcbccb352baf9ae6d4051feff7a24862fb9f31e0cf8e111cfdfe629e1640d0d182d9100c879ae1af7437e4f4d338bb99958166f5315c074eb0ea3e84f76ff586a5212fe40244814c2790e1c5cde3d71 +50c17c1fe4dc84648e5c3c3ab8f7c971d4c58d8d56d2b5ddd92e35e6792111ed8dac7644ac8a07ca8bb4e38e071aa47b22ffe495e9083f9bf781ac1b5fba571862c909c7aaa7b8d05ddfb7ef61c99700de734d5658f44ae9fc908c85a2dac8e7f854d6d24be805fcd7f873a91252985c5c73129c60177ba8fd99daa87b25a073 003db41b4f637fe7977c90e4f1a21799baaddd1826c667102414877138436cfae1b9959842b8097b5276f15f2b982ee59df263c8 adcc3e3dc0bd47edf26aef2fde0c32c5800e8e38c7aedfb70f35db076a8cca15dba956a6898d84812634048119794d750fd7bc931901077da8a8b532e3580c1178252cbb099b84dab2d7e21b319c8e11dadd194116fe7fa02d1ccd2b50ee7576 +3583a3226e2dc463a462fefa97024e6e969c1b13bdc1d228e2d7823d9f7c09012390c2535baf086588000e908309090daac6e6d2b06d2ede6fae838ed47f30b5b481185f607a3586f6dea47c8f84e9d3b96d5b0ebae2462fde1e49d84d36658e87dccf5e30c0937feefd8862dcdb1a1ca373f6ae41641502ac54df6633a8cec1 0065b76c6093d9c49591293471286df1a4444e60d9d06cfa114e175afb5f119d2abeb273b0596019a0ec5db5b5869f2cc827b364 836b499fef14ba1f581496857298bfa441e3c691828e1736b87e7eab610f4e227550fee84e9c97c99f35edf4336a38610e193d0cf9ff4ef5c27b3d42b64505c9dd7e8f2c517dffaa9fc1611f9762399bf835239601a2addc57a4fd69921f270a +60ca58462d53d074b370127132f4e59f5eb8d15594dc721a94286afd082a8934e52462c9c1c3910f8b50d7aa3671dafa5972958d876d7992467b2fee3795a6f9d8a7bd3003a8582ea8c003aa1e02c08ab6804d85bcfa13a815d75c938671f0af0706c68bc70a6155708ca755cac2fbb68b2952208d63e0e2e3d816f04c61bc03 007e9993f3fc1fdc4c376ef77ecded96006ac1159740bd1b2dc6ae3d97e15a67383f1fc931e460b9af3fe14a54e47919667ed06c b63e0975d623ca0f369ec6b6154824fe3850c2e2787c4229e36ba095539f639a2722dcad4c381a1f086428f198b3239519be062bc62fbccdb30402e78601e5b9a8e8313f024f5356662b30a51ebb7f9cb428bd9c6b9e3112588d80911af5eb6f +c749f9bb92ca9957ca6d0124206ebf65e860ff38a225e241950bf4526cef3f4fa9184ec83f71f813fe852dc08eca6b45b14fc7f2c6a19296529bfda007efe9d0d26492de2a902b45ed39603e22f0a763dfa5deadd97ef6feb859d860baa2cfd1d066c0be0f9f4e0e2fafa69cc51b12e814ad2e33b0acc0bcbe1df8cf018dcd4f 000c11e2979498695c660a2bdfd105b115bc4ff8664ea15cfb40c725406c6fc9a13027bd1d72ffff6258f29e4e19b845243444a7 a2a90f61068b5fffb2e1aee5f0c73d68edccec8298bb5856ea3e838cf2766a7bf8fd133954f80c0960d1ad7a19cb8b0f156947acada1c975bb4d36fd734b7e66226ef328553536cb5130a830d290fec56470592e618c60b97a5d6d46a9617771 +4de8414780ea20f7943b1f1adae5e3962d96e828fee43bdbf2831bd71bd25df2976a3be37a7a667c7fbe1200de578920090d131a750c9bc09bd95b261234ea8cc25423c4ddfff5656d6b32da6e2f6f530e6673a8660aeca31273bb9a3a21bbd7031a2fa71ba37c004d3d1c64b2c0798783e47b2efe1a208959ac16e35d444245 0068dfc23c6635bd1fa1076dcbd456ad6e8df7ce7c1370fe275803befc4ffad007fd062a61cf1d50b93aeb9afe1aab47a65af82a 8273a668c6a8dec3d4ba7f21e3cbee7d562d4e77c2a46aa79c35b8148676d68f1f6666e2065e27b3b94674cabab02fb30aacd6a814437ee597846a498da622dba971bdee14da9ccab1ad0cb5bfe50e2d7b2c9ff94bb36df477ce7bd9adaebdaf +a081d54232f84bb19dbd52ec3812748e2e6486f6cf1b177b27929504ca878036547eb43531bb5b3edc81bfe105370427e92831d2239cca0106d031d9fa8da9cf89c6fb6401377d5936b6329ccad854e5567181b8f16a37c35f333eaa0ffe91d727d183fbab935fdac2d5670dafb3fba59e4fa2df1746c58dd8360fa08af7f4e6 0040807fb888e1d9fd33604546656a493629d94d4a0a9de2608962225ed158167f9e2438abe2d12a11e2adb6c2b66ed78215b0b1 b57d9d097e9fd362dcaf0183aa290ff7bf1d39c28321b2e72c2216f7e77dfcc4915a00937895b3547a922c86dfed0a6e0874cf0bbc9ea7ac5a59757fe69a9beca6bb26df101e908e4a0d45d08a26edaa1a08d90a356d934e458a35ff208fd3db +ea60266f1538565b3ff42fa4bbfe319be070329059c52c8bc04a7da2824f209c1145a05e551ea59ded8ca8439c328f6907da4e81d658937df614be98c7b8648818ea80ef40e49aaa4431f4a211d62acf2611f5d60c446b2b25745078c643859be1b12b3141a09ab765dd63ea1f2a2df015eca0840087a5db378c4c4cce76cba7 0033bda0a02badae08fe40c239b9d59e5bfe1c4d4b9b7a5acda6790bfd77ad08dde5e93a2da80ec54a7f88146d72218bbb88aa10 aa42d01a80bd5ab32294bb28692a63e9488f027a4c8fa9b423411df6e926ec73faa1576934fc305e3731ed5eacd298380debba83742047dc8677fbf30cab076698527836ee15b41b8e96d793309365b149b34c49b8fe71ca06b451692e8bcf24 +82f38c9405ef0d26bcdd5b3fce4fb0060c3095f61403418e17c337933f0563c03691fabd32ab5e896c593439e7492a9970ae325c67196d9e83fe0f9780409a930326f7e6efae035ef8c321cb9ad12461edd5cde66c04739fe079db65406b3c2d22f2d04b1a4335285513d4ceb901d2ca2ad10c508302266c2cd6079ff14eff4b 004ff431769d26b8837d3e1295f5464fe82be29edefba76323e92078a6483ea0daa96221549102509a1bdcfd46a5a2e5de10c39f b36f646989715c6f93abb359ba61063f5d73ec52e1216e4f99daf09861ade621cbee16d65096155baa3ba60c9a8a290313cd484b269bc5a887206f9f63cccf780ab857b94e533faee35ac2e2579ecb3dfbc9d9e1923f289ac9d9b8c6571d145e +d8506fab4f681ba4ae86066aed447571eba4fe04e6585fe3be6af2ab1000a3da68c5b0c711a85ddf3a40cb7c8944eef81f2094650459e14f5b848e6add7e580b0198070f873eb3ed5d0728eabd92bc1398764b94cbb4cdd7cc2027b9762dd10782658cd9e8a5022ac062fec535d892198c8a387b3d2b6f7c92b1af6ab7dd9e4a 003f85ca1169ca7e9df44cbc6bc7d2868c9d94e8f8b699a42ca492dca0914eb5789a9032218dcef7f95f959c9554a1cd83360439 b995beaaf707ae00e6bb67638c3d9c449a183cb3c75528f2f92c16e4b26b4dac082267e8ab16be3e5edec675d1f14b460ffec7b8add964c2915c9207e8789775d84b15163ac04ef411077d9684ef486bd6706c9aaa7820ce7b2fd36e0e84578f +b3f30d34f252a4c26f396079e773142bf61c0981d912333ade3de4e27cbc72cd8a16b31807f0c46116f87accb854487d83ec8c6a61565e6fca145eab70048245db08616779d7047db63aabd90dd15acbb05eaa510072c151c0518f1b34582b95f43ec7b9484b2993c176de79e84566764467f72392ef31619426d159c91816d4 003a97deb36d68f81f50c8829d412ee5de7f9d775633cb69c09dac558182039e275fc258240517a7c4aa592e364765321f27cb12 b1041961cb4df4a246bcf8d7864704bfb91a35f12ab85579ee18e767ca46869db03fd71e1f95cada91093148c7f73c6506daa24055f1393797dfba1110efe281b725cd65e0ad157bdc93749585a03df7c17166a3b0c34a00d6ba6b553a4856c7 +0fb13b7c09467ad203852738eda5ddd25b17d330e82c279630b0e1f0c86681f67f6e537fb00da9419114973c8559306de58b0387d86e52d821d982a60769d2f15fd5ac2ee6dc55d8ac04ee247282cb2866b8cb8b4d7b4b6cfb33bfefdff09a73d727193e5fb939ff66ac5fcb644a44f9083a790888cc538c5eb435243c6a34a8 003b1da0ffed24e1a3b5ba22bd684337f6b08053591620541bdad50c761d66201a2cf21a4cc636426456525b598e96baf97d9851 aa686ac417a884b0e7d04436a3946aa640c1ddf3a10012a47d270fe3f132a105f241f1ceca96b67149c1c7a3fe9b42e21535ce394d2229b65821634009090095bae1f2af4ce4e317c157b1ba84872ad5b29b17c38cd9379ee5b21a02a7b27b16 +f9b8124281628cf4e1da0cb4f021c8d19d815644cd80c7c8de4cc62722904ec4cddd26cc4891f30b15098a25ba6923c6abf4774deb6e1883fbb409862f94467e75a725e7154be860fd58347577c83adbf18535c54b102220197afa062cc1c84f6094490ce488af4a08d2c5b808a2572e18a59de96c87162f88413795351cedc1 0040bac7e0d3b54c7753c79d43469e310d876015d948fac4e3a9765444754476af72330e88d79ee6119697aafac8435ab5690754 8ff3969aa57d1b0ec1c8a41cdaf8b124fa95d6d7c69e0f5089b1ad6172a3d7a02aec8a91e92ab8d57bcca50e55cd9867138c2df63919386a2c7572a9042fd4b71b406d5b86002f8320ec0408eb675d587447591f871d47a13b9f8a2abfd3bbae +4e3cd6100520db050af0daa69fe3cfe6603a223d4f2a6318fc5836db8640d4c7fb80bb781302036d2d6fb8e552b4eaef3133b98ba2d36b9ef0b86243b0391413c73d48ecbf1d19170f1b3b781b35ffd316afb1d55d1dda8e91eed5553780cb2714a93e7ece698b832e853e2589c5ba2b8a997bbbbf625071ded66762af8cad42 0025b7eb3bdefba3c5134438caf968f615b315204f348006f82e8d61057a8a8a853230cf0500f9d0b8c1551a59b9184862dd2ed9 a8786f67cb74311374efa7e8d656a71a38591600cd6e3272275b5a82c06ef058e0bcbaa346df822bea8891b1ad6006ce0477319f5006bab9abd55cb21f9cc0e1eb280bf1ae57e190e1c9f8f9fc19d9f8621aa9bab22187b307da2addbb6f817b +5411708381a65bef4381c9e13a04cdd5ba0c15829f7f25ccadf695f635384d8e4704cb562741747831b33852567f42fedbd190d2980f1bc921ce01c17d659d4bdd7eb787b3927fcee659dd3b65132496c687f2249272a473d46326e66b3cb78dafbb522390162c168f73bdec88adb145e6afecd561979846ea4c8cee38dc1686 00673b3a2985c95904732632e5d988d8d437a60db13215bb6aa880b348f011c609a1e860461427a8cf0d622abc47f910f5c97ffa b1107ce9e17d6cc28a0777fbff729931f47f30f52ebf09c4d22a0611f274845169c16563ce99ff31caa4aef36a61737909dcb0729f5071ade425f95eeb262366527d276d5523f3a9b55fbfca700292b48a24c4e5b36882c51cdd4042e04b1de8 +23757fa60fcabf543e603d8b31ef0cc99b3ed16b4816a84e01dbfc858872fcb79fd03d2f8a1d4f28c25dc42a39e20c34f81ebccda1682ee9bd22fe323e7f8ea90cf4a2a6ebb634cd1153cdc35f7306f28a2efd822bf23131baa1543d0ed5ab4c8168d3199983fbee117085f90550ec3ffa2b06070d3add1d707fc2593285ff58 000db7dcac414010b816236cad584dabeaec1da76c97182d1b62f87bb7fe2946a64d10430571b2b29ccf2ef72c969a9f045f1f3b 88f85ff079d032f215f4b529a90f9ed68df6ca2653ea61ba2ae79b6097ae221d71576ae8cb2d0ad039db39d46b948478006f9728657b6c4b60470bcb2ce90b19656b979d55d2901b4e8e900523f9edc2e1a281b793fa16292a86853297a89963 +b976314d2f066f8893307a726f450dcf2cf865c170e90e6908ce9787eec48e1e2119a731b2bec3c12fd4e6282a393774251bcaef91af6ce57c63a8b45bedd72ab862cd169b7c84b8f6a72084ff823a96f2f8eff3483a7ebfabdabf0998377c5a6836d88135cf61c65a0ca7ca57727da68047dc635c17ad13731035fe9a6402af 004717efef16e1ae267e155aa1daabafc68515aa391dfeb73c13d01f3132bd22c984228dddc4dff4c39979e7585acd3f730cfcfa b0cc9ac6d2c341a60691e5daa50bf754449d0e209fb63b108226146482dac9a57a4b6be66af2450416761aeae37f19ff1099d8af8db419d608772465f58b86bd738002622166c05c75403a1901acf2147ac42341e9058bdee328797351617363 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K571 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K571 new file mode 100644 index 000000000000..4b958290313d --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K571 @@ -0,0 +1,60 @@ +964ad0b5acc1c4db6674e86035139f179a9d5ec711b5bae57d2988456bb136d3aade7ac9ef10813e651ae4b9602308b071d75a934a6c012eb90c5eb9b2947b50fc97b1d36c5bf9eb13a7b06c94212c3dcdab402a563262298defff62b836ead1f78f9d20713710fb48115cc5045ba15140fbb4bdf516e4150d830d02cf30963d 019cf4f4d06825499949f9e0b442586fe1bfe3459813a2b92cd8de0f775a4735e02655702ead8e60824180761808d9e816d60bdb0238e1e8039ca7bb63c92e1cf8433ef447e64ead b933471547d37e2f01185f0b6b0f45d1f83b2ae16233b92eafaae27bb0ed9610234e2019d1dd4c83d9d868667ea995c2018ba4a6f3a5f15afdf904a0715fbe435c89db83e0b9f4008a08f358512f974c92713ad7395d3520e6b5505a8a4af71e +baddec4794effa668cde267016dda67bc70b847919a9aa595f93ba9dc27354399ef7a607fbead31e57a8ce698beabb10f313d393980425e67cf95be45d512f00e950c0c5409573ddc3d556f23daf056259ee8914e860562a674311452fed780b3e0317a7fe93baa81fb98df3ae4328b28ad0ac8f8ea33efe24faee658ad026f6 0098521a732e72ed945a549afc92318fef7156ed1d1ed9bab93b581478cb2339eb32bcef705c9bf61cf2873ddbadff8ff3806740a2e30ce67d1807a8179dfd5d952e6f8a583baf81 a9b0291ebcc7ba15ef3dc658761a31c50dabcebe813a811432009c8d5790e22bad3184f698494cdda2bd8d3268fb0b3a105741247c1b183d4e7151caa1a4b04525ef715549085ba6b05dad2c474de717ddc11a6dbef089508914ca591e113e53 +7ef7138fc657492d229054f8a50dcafcfcd1dc06f1c16640af3f658907e2969248b54416066eb119adbfa23b8dc578aef18bba79610b9cc109394b900a25e55a779230bb858b2ddd9499a7775d392328db9177aa9571c2f61dd52010b48502154e914a0c55a54edcc04a6713cf7bda8744a893926118b09df877d1a4f3d95e8c 00336fb21549e397a190beac38a1ee10f0551952da15f71e11dfda415e5ee08da2356f114d450c661f52b2b32cfc7b9be61732672691a079f0927989b7e9f4efe6095a242155b641 aae0e2ea4a730062f24b2dfd5fe73ef91d515f5a191787eb5e605dbe75d86611c1c36806494aa93c4a0afbcedc90542b174e388800fc2f35bb7ba551f14e14edb0683fbc6db1bb1f12bff2a2872fa584fc68ac67c145cf16dd963c3c9da1b27d +d58e1ff1d49a471d0567ecf8f29173dab5fe5f6184ab4cdd095c231fa7b82551f99a482994a46c3d8ebc07297fc9e952a5dee7d5f199b119f6f8b250f8fba45701ac252db725e75c4da27ad77d59a4eac448e54a277986740dfee6596811e59afc9755e53d24b826c09e497e29e69a22bbc85be11763064e9ecad7ae66458ca0 00e287ebfd9ba294128cbd484fc5121d271cd33e685bb1804f09b40aaacf64b5a9f2cde9b30a4a02d3a9bda97d92f46bb8787b3c61f280b1e1a0680f1f0679d3bb34d53725d62e52 ad0a639d73c983e19302e8a53df4468d097a59228afc1833110b645b81bb67ee99582a3b91158b227f5c884ea8f74c6f0dd0b9de0e66addeec36990e3cd780de43e7fe7432ccf6ab98bd889a9307e92a06fb429720a47ba898c505d14b072ada +4949ba765c14c31f68ee0ca26bb42ba2edee63537de4a6f5c42bbd862c21288d6ff48145260365193c6fd2b56dfb014da26b8a483776b717c6874f627c9a622154b824565b23e178240f53ee9748c45759ba5c035b584df0f09504e95eb9bce0301653aadb860bb25e6ea6b9606e0ec3bdb8089e6aa0d5763d331757490715f9 0149de496fa8f88b2741864d0c35b3df666b87179b7bd06cd426a45f13bc87ea9f50dea85e1fd02a532630e0e3a231cc3e7fbb7c7ba85b40cff1124e72c677c6a3ea6aa40ffc64b7 b7af840034316987a8a8fb14a4240c2fdbd7395d09a78d2a4d16b5cff6fc3289e7b31881af8e86be987a3cf054e339521721b35b35e56b9329ade332d33d3db4454dbec3b6373c624331fe4aa73f823f9678a7e6ce95d1991219b187132dc458 +5bc63e5c50b1650f0ed4a599960f1e4e11f6c151b2123fd71d9e3c44662312a74b6854290628e20b30eaba81555acb2fb49b640bdab2528619c7fcad0f2a2880c7ea232d427d7c935fba2313370fda8863a7e7e203d63ea15d0cfa083e716ce6068c63fa616ddc225c9e413e694cdf6b355cb1293af5d6cdea51168f5634e878 017605d7c5873d870462375d741b4bc6375f3d47f7f5e9d998917adf2137a81e63b66917b3dda8968930c4b850f2270eb3187fc756e2beeaa67fe0d73053e6cc0ff0004a21250551 a9153a8a7965a726eb4f054a102d6c5b4934bde067e7bf9b3191de671b10b2a7fb7446bae721aa25c5e81cd9f1e6025c0f6421c678f5f11a0da592b23b100a3efc7b0dbfccd89fb095f6b0415b96c2614705a8801860ec166a6d8cfe2fd2e18b +610f6633718e49d232b3798654095e2efa0de11f41258b27aa01956480c870d901efa77e109d5f95f1f5101d3c90fc51312d9b3019d2e42e0067eed7b457dc7fbe5466923b62c83d7347e4dada571b57813bb9c21d5e308519b8eedb7a7706508ad04aa69698e03636eb30fd9fb363ef3a185756494ee01175b16847f5b68076 009214dc2da0967912c31995cb8f5bcf4bfa832c5a2d3610f3a9857e5eee7c77100d599d9ed003b4106013155dffd6c48859b846e45e0ddbc5fe24f4891c9b2df51407e9cddbd974 aa8f7767abf17a0f68d684ac8fb37c0fc654e45fcd73bda68ba1e6d4a6ff62e0374c6d45ad9a8de324e00dfc1202247b01fd23297214abc201f00c418139df61adad094d904906977d08dabcd0ba1de0320ae53639f8b37e791a2ec7b1aff2e3 +c548f0546cee0c0400401cd540a0aa9377f27ac64492e6baaf38e794db4df83e64ca3d83b67bbb46a6c269c04c2725287cce0dee984a0d468c9ce495a7e554a6835d72c7493bfe88dbd5a044a148c89001b8087fb03e57c2b7212d0b175d616333a9affd8a1802dd49ba9be3ab6c6d9f99a5578d26cc4707a5860c6c804d69ce 0042f2682e9ac8b76f3c0880e12c292524601dce9ea6982dcf68bfdb0d3fbfb50dc9229e54149ef09b95bbf624eb04ce1427077f30d8536be9f69970ddb449ca22ab8368d2689ed4 a19e48ffb1b030d72caff69e8a42bd7a258388f7f217e385266f5b277c463a677b4704dc03a74176a6c78b780bea2d620e438e48dd4d88c65b04688d4d9a9e8186d8eb655c24fddbe4154ba5f373b298004250ad96021df71cbb63d06bb7f4d1 +9431c6c5237f6b4b35682a0c32f68752035c8b295a1763c5dbdfd73466cea64a00ecc11356d02d2a9211dc54548f5db1651e4471898402c887fbf45005a3bda271df0158c98319d4d6751b8ca6b07100182957d5fe0d97c4e2294406f83e9afcae4850bb089f2252490417b5afd8f07f4c795fa84c9c7cdcce26bd97273c0072 017ed9a9c75cf66528428e85b0f019e3488af8b893b12023ff1b4ca9c3691b74e594539afa0f4d7c3863d15399b862f15e27bb077392d6bbd546ddfd46728c75177338466eb2f4ff 908078ff989c77ee85e0e1ed10594af16885802b343f2e08524fddc55045cfca5adbc9d6eec70bedab00e64f4d7f093e01a76bd8d9e7cbfa87f4ffb09c275034dd0b4bb50ea017f28e13593fed8b3467eba0d74549d3c2b8344841eec26d2fbc +417cd5f60416f17081d2c70e9a510114e08be83573bf9deae75fbc3095dffc8a7f7325f61f9d6565381710eda871388cb17619e4448836076338ee309a2bba5f737319002e259b4a875cce1bb97996101c9a7abe0278dcac203a712f0809eb3c4b85a9c380550ab0bbc5067a8edfa78abf03c09b5c08f21714e1022ebfcada4a 01bcc09b3f2f1d26ab9955bff7e8c0f85c8a61293511a196b53d7963f4a4503849c96fb4daa68c9852ad9185e01a35f0bf298e34a09ec352cb6da34f89a1f23e8ea27712a8f43aa7 970760987bda46235277da2a0d81e9108571ac06be8d3386ff3f7a378bd13ed5e1a016aabba4bd66feccef1f463e47e705ceea520186891d7e2663f571b7b30dd2d4f9014423ddd17ff0eaeed372bd8c7134460ec0b89ebaab5201d49fa34df9 +eced8c412a153a643ccd69596389f83b6a36880286f8aeede503452bef8305942d95734fb5733f37ffeceb1c2dae7b1396c3323de11089082745c28a1756f784423fa7ad68bbfbf0d93ff8b7ad62220500df6d6895788402c1f5c69c06dd9ef55e2401cf297184e411be87c1bba657f847208c0e750f94a3df92f253b377b4da 00ec52fc3d9c272ca80623e06b15c35f349b13548ef7ee400bbfa04196850b3b8cc7b239238c827f9b0a3160cd97969ce21d66752791f5896e0385b0527d4d77e4b9fc70f04d73b2 ab916155ae120c3124561b5610a0f972c3db7930db3ca48e254e3250e931bd880750a901baafc4cfcd6f96d694cc8748122ef6825bd282e5a83db0a124844daad64a0fcae02687f9c56228facceb9cfd67fae9fa7a1c2600853689b1593a8621 +30e83ea39a92036e22b7bed7639eab5e5be1d00c20b4a9b9afa9a0d1653369cbef363c119cc6f921c8f84663949c8b8dc9b743ac2b1861a480476e9b64c8f333f34b6fa0e1ddf09d49618ee4f3c1f46751b5595f0aea413d4ca46f3c26b974b112cbe99c813a96a4423764c069454946f213c5f066ec38108f947abeeeb02fb8 006403de7627de22d1dcf6b8da5af62f9ec59ec065cc1ca1311bb98aa439a6d5985619b17c17a70f59e17cf180ea6828ef57f5f1f8ef05680a9fc12ab7faad5af61e4e11fb45d341 82ee8ff233f2f22f6f7504cbb335e08aa36c942ae848e5bc9971bc639390aec1be715dd8ad1f91254f3550a83959a600049131fa0d9426977c08bfb47f161d8539c3725dadb3e876d5385c05690087f51c105e0d114cd3620df78fdecc996032 +3ed244dc16a5cb292db4b1433b0ca3226913f07377faa20c6c1402cb4d026de808ca74a6d4ecdd7c4e662105bff6edb9fae0117c50aa053aef677c0750c7a446edbb879110030758912e8fa666489d702d8fceb719963b24a256429bbcc869a1f4ab9de9db89263e3684d4daa1df2ed94bb59dde2abba63793e5f82aa2e4db83 001fb980aef64254aeb9bb613ff2fc6967503db4bc1f337882f1566cbeb57489cf32e34f310549f41cba1b951f487453c29753a184e33330e90d4b973d2e406c99a239a5c3f96233 a6b3e232be09b047ac8f085e54706442f08ed37a83af040e9a503f3901a0c0a9eea437dd8ae23288d996376a4913a50a04564de0c2d4edc78f110c6b82011c2e872dbd227d202e4c220764eb254455405d5912fe2d058713d3595f69851ae09a +40343935d9423ad30f3fb1832bb08a5d20ddb3a55b59057cd275320db4a5835471c96cfb7d67f41ef860cf5879897b8dcf307bd1a52a6226847b768ea38ff1858f59e64cd635b51e6863773cc6c64b363ec47ca39266422406264668415c189e2f92447ac4c63ee5d74e95d1e6af05016917ad237f482ea0b02aecadd370a8bb 01d96dc09dfaf602789c1dffa5c9ba130832badcf180429660daadf4cf1be5cca92fe9713173861670eebfe3a0ba25bcc76aecac60a756f07b69687e05c7e25984a39556469f62b4 aa55185a799fd74a154f41bf77e3387627248b7b534417fe55843de1bda70ad9dd73073126d759f7a14bb0b87f0b21540a2a67a720c5e6f2877698a861b807f9f6bd18e7f2f3349ffeb29c9413563184657f892c57317ca6a04ca177f507e342 +274567f8841183e68c4f6c6b36c5a52fb0e88492e4076b9cd768bf571facf39dad6affeb68941ee326ee461ce1f33c26e4bfb3c9e0cae8241fbcc14cc69c1af68701fd0be3def1e87b7d52b682ebbe1cc225c1bd177b0886e3698a06d0e410a1f92c9bdf7239189f6acde0d0653815a72987671b415d1e8a70e685d6e5b14c33 009d98b32c8eacd135ffb8e13223690ef02c0c1f29ea8b4da193502c8cb3f39f9eed608c02fd457f2fb685ec4595e8fc8f388d26778d225d2b18c9bc8b199d8b65c0d1a6af33854a 8ad7572c3e7b18e4bd08ebe220c00a8020ffa52856f55ba8bbeae7925b4cf60ae2daa75230a9ff6c019da6d5600dd4b70800b55f1098b33bf07acdef31e1323a97ac66df28cfa4eb5f6a2852362ef63d57854229cbf41817991742705a6c14cc +d9c99b8da92d3c2e40dea3c4025dc37770e867c4d2746c4d726b6de24250591a586c166c88acb8ed340e161d4c81b9d14c919a1b06f1feb22c5ce5fca2693bdaf4994ac72c8983c87f331473fd094eccb3d5f3528e69d487562fb5a65c150a8217192f8aabfa7adcfd0b6916d5000248fbbddf1ca2f38e3d9ed2b388998b7cfc 004d873ac744c4f68bb044783ad69e1a733cb8b8f483f2695bbd90c4211282036ad7914a53b25c3e890c6824643cffbdc4138d7ff457e3fbb99387494eb5cf2bdf1ad243a3a1e644 ab3d47d14438d853dff71528f272c27427bd8708a966f8995b8929232239c9dd35c8b4cfb0a04c36dfdd993791ab554008d970494df28b4437e6e819b3187768b7b5ebed0ceb5407b5737b37e80294349c7e73fb8e544e5309d39acd622a12b0 +d2b88a01fa17703c99e5b867c645e98feec0d6d1afaa20a97b5fce9c23f0594460142af4e36a5739b8d26d3ba35a0263caa5429b4abba157f359fce701c43372500fd2ae1bc2ed80bfcaf8cab7016ff93d4a27f565b7e67fe7dde22bf02c48be12114fbff2421517c825019c0ccc72d927bef156140d7f0e9b6ee37af78c3efa 018d2eb947297a054f8a789771dd875b12b26ef057fb91235dff3b062916f85aab3365609bd2a38a861439c8514e33f174c198139354e63766942f605107cb1b9709b782622b295a 994785d777285174ba4e9b021deebdf60aba12deb104cd2ef3c989ccb794608898653412ea7c93b9786337c26f144ae40e0208089dde87c61588acede72840e9b72d930e737f28a447f8402b6b7a41bd166f366802ffbff41dfd40f5bf70c40d +a704a1428cc894f958774368979fe075353b56790555386e3b043dc6a2919b94a11c7f85883f46b4d47b324d349c28c667bf9a000daaca1d7191f2a0fd97a4867aa9f72422134a690625408a9ea4b723704690b69152655f9e9dd5fa3dd94814d97dd4f13e85c3f9bca769491c2461fbd17e28afac00bfa81371d5039013da8c 00594fc0b7a5cc0216d2e78eeeb6394c8225de795f4b73bec48b2f4ede185ba622b59a16dd3eedf8cf2c94f2ccd6dcd205f64c97cf1b7f1e34129e94b5129502909f43940dba0746 a5bd1247192ef791d143755bf3f4c8141cd57c56f4e5f507b8389f73485f3cfdd5f8084155db4080be25dcb9d4944f8b00e2943a384e9bfb07d67ea8caa3d3fb55be097f5e47d7f1828a2d1fab668b0771f02475f9e3cbb84e284c399fb26195 +f8a87c4acadee27a908718461e3b45060ae4ebb009b10a15926460bf219cb7e75dc3a993fb9a741b94e2fd71615c50f6df958568f452b2cc284f0516816bc0d2e2d45f663155660a26326f63f4aa42a6e1cc8462a2ec620a365257ec042f55e4047b62af689592a1a072553ff174dd629a4f51837780ca232cf479a68c1ebdda 00f000631106c5851e8ae0802b01e7a8a8540b427a8a3956a1d36f0600be89318032320cc420931d825cc964e823745c60aad3437ebc1c91d32004472e9677605fb708e5a71a0d83 970e9ca623504ade6892e367cb5194bf50da7fbd5189a6073140f768e74f68a1c12463af857f763c4742f40e30c83d6414236b42ec7063e05ae4a8ecffe6b47fe27e982565d44087b73a51e442c6013e5fc862c0c70091bd1ee8605be2425c62 +10b5438294a77c7e517ecfe8f8cd58d75297b14116aa93e574996ec4acb21837e6297cc0e7e7b5861e862062f192f2206a01b1caf42c6d7181d02c7d62b76c2881f8479449b02d32c6f792714d8f70f0c75e81c7d9abb996be87f5ad9a01fe42b75855558d5f00df392b62ae0d258f3f67dbeaf07208952e679a2c573aca941b 01023997206341c6147c536d034a9c38b4012035dc2c9b7ef0bb9cfe65e7d788296f055d508a1fd957b2dc7f9eb10c27790f15f30d81670945e54a508c57b70b46b4a09f4c769289 b9af5a25710fac337801cbf80227c9bf0e4da2356b89ac0b16e4cea8bcd30469fd431d064d494ece3352a242b1a1ce001557bf27f6d7b2f4e28df9170c62771c1323a51444af132fe7b8c50e6222a569c70b56449253ce5e88469cf71607b4f1 +d83a52d43216fdb16b1b40469863ca8eff4df9fa358deccb5ffd18b3e22a9d654aedc98f3dbdc4f5b4e56b4299e25d8a5a38d01b34eb93de382df1ae4d1c7f966e84b84c393d167aecc6f1192c4b42cae83748b1ee3d9147ce7de74cebd122695b455e8082f86e3e488fb0f51b3b7edcd579940d1cb9d045296e5e38f201b7ef 011ebf320ecf6a908ea5b868afb8e22246ce84e743e1076d6185ec65dd79043380708bf8da4ba802c3b93b8d15509bb7d7de9dc29f1e9fb0f0f2cb97a26698f955b1f7ef668122be a49045dc497d91555b4e56729d0c4895b330060e184a63fc7719c9a097e4286948120165fee481f3feea5fbbf1bb1d75031243306bd587ea2adf074198c3571ac3bc75e9355b52723d7c111fb56ef37a40b4f631ff028ab930f645cf0aa90f5a +eddf5553ed4db6e8ce72cbcb59fb1eb80671c884ebd68e24bd7abe98bb1f40806de646f4d509be50a3fabfa85c5630905ce81abfad8a55f4cd80208afffb9056bc67d9dd7f4660a5f924af2a3745eec2daec39a3fe36131fe9eea444b92d31f6a125f12125159ba095f89968a7028549466f41ad45668a861f671050d2a6f343 00746d5c824d78f42a1fd63d8fcca61f154ba3e75788b7a0b87f53e5420e23a935b02eaf67bace8dd8a8e7c1caee30154c2428e0a437cf12e235f41c416f92fb54528865fd4766d1 90fc3d4e4006287bee5939a3a792518de78d5800b2189ab3f8efa5265e5c54cd79b3346331f04a2b02ae3378033b52d60a3482ed2874074c46fa089d16a29e3400d4b31800a7b32270b7e86ebfafbdac08af696a32761a88a7d9b60c483d2e3f +3db94335f6d1a125309622c0a9d71bde1da09371f0285a93bd0aac255fa8f10a56074e0f6057f1b1aecf2d86a2319590ead96a2ad1336fe844e09339b456be32374ba2e659fbe9d0f2cdd83444d117d2ce3204ce4b4294dd05405634b84747ffb4227160c4e5c2c9da9815b0c6d20f55705f16cdbaa13d107ae666d707ccbe6c 000670e72ac2de50dd2cdd975a6cdab10ac45e37ef7a28c685d77447051496b5e161f8b1b93f6c7f32fce8ea05e94ed35fd7cb28c44bf51ea29cbaf5aaa31d6abca30a89430323dc 85ceff40b94313b48118e61f8cf1a66059890684541729334e9b311d05319ecaaa15b6617c031e46440eadfc1cb8e24b099695aee5e5e23a49b8fd34342fc3dbc7a31b610235b01d260fccf61cdacdc5609de202c7cae92aa4d67f3d7ef7cf1f +69166ba40768d0a3930325405edfd85f3272f7b8e600b0b319f070274c91f9f03d0e6ec4bfc7b4445e91b87cecabfecf5e77c7301ee3c6b0affca2fa02c92216698705eb75443eecc25438db2d2fb4b24f4195d6b9c05c53e0868d3e58477100607ffdc31b18c40b4ad7202bb034e58653daec0f6b33c024d42a3fc84bd8f86b 00369a3bb96f884983c23281bcd04e24a3e5f6359f81e3c8e46f3f6b865eb6bdf98a630e90646275c587e41b546d3ca7688cc207afda15cf9b25cf83bd6ad27908647f3f9de59de7 8e7f0dd31ab90738798fc25c681a215e5d350147696b57b685d7a4853baa96ef5d1d025d2ebc1aa725c2d221ce2676a10fb878b8edf2c654bd7792c64ea4f2f3cb8edf3f96150481dc946790363ddad10e8ec98497f2e72c0f480432f003c3ae +f64cb668b72f1e6dd026a478505c0eb33446ae9a2993bc7648aaed02e172fa9a0e05eeec61e756ba246c1dad7e85d3f01baf734b1905c5bbd1b08d833c2cf1e079eca75b866d705c407eea8618d23ebbaf269c7185984b3bd4117ecfb295ee6b47eecc8d3a78bb96552f6be314656f91caff793838226662c75cd7804b6bef79 0026717b039df834855511815d5665ff9b654facab469390ae257b7f0eb4dfe66ea0dc037242ed0c13bf229b8f7ff26da9b55fe4750d3451c62804aad493c179ae45d08ece5af085 91bfbba4d1affacc9c0864e4a36a07eb55342f657879829a16e150440a32beba619c8011daa4243c8574960f0170e0d5146e79fb55978ac0fdd6e2be5c8cc26d154a186aabcb60503faae5a70c00ba78e17f13f652c0ef67040dd8a49983d5e9 +51ee0b98eb6a3e3c1afcb35a33697c048dbf61374629ac5702a57801fafbea4d6fa5a26c9d1b79d1c58257ac0106387fab2d4a1b7f8c0dadcbe7c830613531b3c209bc17f792bdba1c1fae1b7528aac53dc86c2094b40194577325c05d2258303a2d17c854e7449489c43991b6877a50692a6340a528a6b188440ac0cddd4c4b 01d642f2d393ed4abea37173e4a79534af87adf534ead4a0a1c46fb047619221e3577e6b8bcc776114d01159c736ab78af3e53feac339d7afe58be8e7a8ed290f1dad960f1b5de94 a7d0728504348d27b97debe8b0c9b4c91c3adb5598777f6fdae710c14401ddff71e0655e80acf3e8d852be83c9d56f4b1875f13a315c5c05482c9575a05e240edcddd4031325802460336d73ae3fcbacc76805eaef2c35f6ffbe53c880b0816e +feee50aeacaccb6b1c3d95c6524044edb78322ee836d8159c4a4c2cc6982480567c4c6cc4806a564876622266e1ebd45f2f4be851b79da025bd57d0e6acce1ec1c8c255eb89713a1e4897d4ee0f7a248b9d4bd3ad5dc0e57f60ebfb65691e164bc908956a019083e923cfd33dcf37c735af3462768a1e14a8051d7aee74d5228 008cb70be29e83f697a3e2f67d86f1c1ec9a163b5335cb4a06004b6634948bf60b8ad9df9b27d2bedc4975265ce44a7884e57082d521320ca4372d38fc77b18d3fa05ad8aa5c43d6 8bc5fc2a8b8bb772113e34430d43db891e4a4a03f65a151455d17b3a9ed06cc4b0a0dd0c5476393011e217456d0f08900ea99150609401dd6351e7920f02bb31e7ce81c9756bffe71f695cbe8ef7b4057cfac0bc309c7c11352c03a1355cf736 +b115f7370d6a93a90fd9dfdfb292956be34b61992ce1fa5627c5e928d74bcdeea66d4040c473306a0070fa8363c4303bea32f73ea3639b5c6676fa5a1d68a2cc1f91f00580d7453a23ae70af4cb1f1657aa82c5b305374effe5d67d559e46a6cee6360503d21070506f1af30bb000d2f2f85caa6465810f89968f33abae81cb3 01eef463771f9c6285f3257691dea0844687606d4dd00b6020517f190891cc1be97cfad21d147ed8881b5a6e19b22ceeae30e1132476325f2de0e9af2e14c80b8c780a9d2d6c96de 8f1a3bcb41415273ddfc52286c470db9785763d8e91c559957ec4d2d1bd376be1eec7baabea7c35b698c3d47a186adc9132b5a9e69834a2b7fd4b5d1e899256b6ca190b1c01bd245196fdeec355de2670b38d3c69b3f94393c927d413fb7ba75 +726782eb0d9720daa64e4a77b5d8dd67a1a193f15eb6b5162e3d89c925ba63b7c7e1c4bfc8d6f11915b0e14d16ab53ab015317bd5958b0beb6074199e05181915496575768d026c23e92e06016598de008c3718aaabcda8b68bebca0a73ecfc7327e8d3646106b7d114dabc46cfe56265c326ee56fd2ca87abb5bed8f997c735 013bd452b0880b101df1aa65724fb60d5d85b37ed5419027481661a3617e0fb37bda1151b9b5b41f908ba832011f7850b75a07b678e5b8cb35c5fc8b94a625e4398cd5ada2b04cc9 b545c7df5bb0c7aa9c60b753c519cc1abebe92cb9e550e4e7822927649a61eba51860a8389a244ed0e3b649742dffd24100f05d6213cdc6a2ca05397e18cfc9693a8d576a836b2f9114c69e61d600340d2dbc127fd6fd7b939271cbe759d843c +1c2418243fcd89c6382b7c3b2a8c341f26d08174a9e9296c4a5c98c5793a0fa48dce51e30811a96b515aa22bf9af89a43de06d696be1e531c5dece1f69fa6ecb7f20be063c602a16454ddafb14385ae3f8246c3f989d0566e06e7ed1864502896ea19df8393259c4dab3b3380a4a80b4103cbef4f38cb69198b7cf74ce94883b 01288141ec2244e4bb3f62daf4ee588aed09ce22be55e3d42e9085a947c1f8cd16533635d170bd64ae0b417346fa4670c25d41387acb2a8e14407a1931d9f7c5358a14eca40974bb 805f7fe60758567894b0f9d8098858550e9f8e303fc2836da9a51d59c9936d0aa1afc8d5cbead1eb190635c6f3f3d9130dbec23f858bd24b1dcee1a721ca0504495c9782b0c4c1efac4c39cefb5fa619f2906761144565ab7bb6d5efdf8bcdbd +1de4b642ec7220c64b91561caed7832044d6e811ac909f3b199cceb0d8a7db91bcdc801412044f5c34b355b95a2c6170fe497f6d5259bc20715a38cb0341c88e93029137e94d895bab464bca6568b852340a5c5d6a225475f6eefe2fc71ffa42f857d9bab768ccaf4793c80c4751a5583269ddcfccf8283c46a1b34d84463e61 001fe06b94a27d551d409b0eb9db0b163fadcf0486e2a6074bafe167f9a3b4ce8ac11f42cf72f9a1833a126b9473163d29bca2ad139dd1a5e7fedf54798bf56507326fae73a3e9a2 a60cea40843903fcced0f6ba9ed936ff05208494158d2c655da92a51703ca4648324b22e1b8aa7aaf6d66d426fdd38f50ace67c911b28010998ee1fd4bb82bb5f163d7944ab859e3f7453895640cca8fc788f724630aaa4b07454c24c053e7b4 +70279be7d7ac72a32606642ecd81b5d4d0f95fbc3c0b07d85c16adf2788601e44dedb8e55e0f9e0b4ca3ca35f5be7511b0e69224a05204af67aae11ce154af6d594d47f6e3142ad183969544aa95cae1edf42bc699137f60178c12b10a67698e37ab9f3edbfb3acdf1b3513d62fe3db33b16cbb4e1f9dfe732c107f9d0c953f6 009cdc7e4945c485a41728f83d5188f539e372ff4fe38fffcaacbcb4522428e4f93ef4972556f4398fe17bdd885768f0fb5590df495badc794d4d274e22f2f4a2535555922fa43f9 97df191e45c343e9ef59f0db76423923f42bc8f5505c7c414fe1538f1ec8fa7ed834f59b73c04299b873fb2ee934edfa010a8a79df4881fdb77ca0dc33b3fdf101b60fd1e20c73cfd924bf1d80fea06a16abfb1f40ce49524e2fd2cb55e5a266 +4d7e0ad520445b6a5cb46b7c77fbd367614044ae6004494c2b3a89089287e2836c73b799cd8c90139eac427ebe335804c3788f3728ffb8edd7f49a4bcc76a9e24ce3c2299cea88c04645b82033115380f81b0c1d823e470631008d350cf0c0dba1915519985b8a389ccd8c809dbd5bb5051a79e631916e0d052d9b6cca18e0ef 002bc753d007c4491cfb8ce0a6c96455acd16d37e02c982db216b8cc1afd6d10c6be4e15a3988b8b8b86b2b5b59a5c1939889024849317f27ee08a06bd8e7524d4ad83a1de208564 b86e9b53840cf066d4be45e46e60f61801c9c19750389e5836ede76a34784154e376e8fea75b35d1133a2a005cbe9a7d18dced31af493db26a8a2490ecfdd4eeaafea92a47707d19a75edc2a133aef496e4e19d5cba34edab5401a07a10cbf4f +d49903f38b5c9b17542310425e59377f61f5b4f4740cd97371ee2116083f7758e69e7e2c1b0950ec6b76f96e3c91c721d6f2843afde8c7505a559c8a64bca2e665aa1131b75bdf86fb5b90581c7d3b61c2cff88f3fccf356ddf5ed282e27727be061b6925c51ea7f1a495f471dc8a5ca1a88bbe29e92338d3c9361460398965a 002082c6e61d0d72f040905d8c1c20d47b029f41ec68d6cbf43ce97c3b2a0a770557a33cb803c432cfbd3958fda30ec1bba77a6613c318597a85ad02b26c44bb77ca96d9cc1194ea 83a97c18b986c7a9dfac0491c72e509aea37e1631be1a1f8ae1c1210ee8d69192238a945e136494483c919f61d5a52cf19de3c39320f12a62bcccb8f4e1e1ea321501af9b62ec2a16b77d3a85fdc820c215c41d91aa9d6e9a2253c22360ed5bc +0e3f4afc3e7b25c1bf2d98098a5a87db1224d9bb45adc6e434732b8722a708ab80a1f3f6ef3c5aa70d2e1dad3e4416b12cc59171f05736c4b58bd084602c344f2f0bf3cfdcfe04c64e87597a99de23ded64b33607f7c273ec321f6462518715b11e91361e89ce5415bfc2ef520bfec378244a3bd2a4b9b6b3d68815f2f75baf6 00e298c93351323e2c5304015a4878997ae4e79d1c32f1dc64262e534d4f2c4b3e222356ffce746763373fdfb936fd330d3214a18c07f1205b20c9a941331cd676040ba1fe3dbce7 8e4f18b4c414c6b26fa95b48fb320b18ae113c11d4299862ba96fecb0b1f509c93dd9aeac870617643cccc223bb076fc0ef7fb72801f31b13f1eead0e5b0c0102bfac7365324a4d73d042a46888e9319f226ee3ce727d25dfde0a547072182a7 +8fe32671f6927272fd3cd8dd4e34d44d27fac8c88b41bf9a48039e914990bf06d1633b38b9200ce1c2a275b9c55498e5da2d0707322c3ea0a0fd7aff598fb801628264e13047c8008153e8595a0dc95d54e70b882ac2ac9314d2b78e7b93922da818d7075215e354708994af66958954c92c074d132dbb2488e5a531c755a8e2 0104f4ad56594c5cec2a988c5596d73adaa5a81802b40110dbae698ddb1f0b271fd1479c38abcdb9b234e69cd0da8a0328d2135c287d5b130a09fa0b899058e7800eb2dfcee95c1a afc7263a2923e6760ccf5322aacb4ac607098177e92c75dd8500033b7eaa7cddaee2bbe489d2bdb334f8abbe695c4e2f0a9780d759c248f6f7d81ae869465d7cdb9fe65387dc352c9dfc07a053d48d2bcca82ee1b9a6339f0f8f785d278fc1c8 +a8fa01136a0a78313a5d160c32fe5d1805eeb3730c18ca0c47818e82c48eb4c9e5b2dfe3ee5facef9ec59b68f4e6f3213f77fba9f8ba06dcde546ae348d343233883894f4423331b536f62373a495852977a51cb192cfbec04b5582b4ece69f345979e234de32da7a120138a057a7119735c4cb19099bf48bb202e7ffac04def 00c4989bf33b3136bcb4ba67906eaff2bcbc6567635aa4b057acb7353ee87ba3cb4cb9838f8f679729d5c6ed98e6c4199cf58605f009c6873a1b8321f83cd3c0973b7a3cfd9dbaa5 92f61715cdb1d7c0175c887a31d4ca2bb40da3f8b3e3c6a80c85b1bf4905f12565da6faebc4d2aabeffa2f58cfb643aa145208377eb8874fbf456462a4b5011f8fa416f0000eb6657cd32afe895b8bdc0037661110e38bda65152fec2cbf8a8f +ba2d83b21c783d6ef2f3b7b10e910a418a9b9f49ae0fd37990335b3a3d15627846c9a12a1f31a3d0e062ad1bec5650606ed4dd06c30e50c1e8761a29f4ea1a20f74635d5dac22e5b787ac10f4ee82b338a641484f91771c128c84d31cdab0a6b9616078c898665655ee9dd4ae73d33b94bf091b064928b959623aa71ff73b4db 01a96f2ad56e31397e236cafc108087479c9823589a5fbc3dc7488d0e5d1199cf245d7f21f524cc0e8b47feca14c93fb760e631434a91188b32965053942f3bd39b3714f9d6f1a11 8b67237883b032911c5d2d14e886aa7694332e83e15b59a16301aec8d5bd2951d26f71cf5faa83b045e2d9b1847d2a5e12ece4cdffaafa527d784a65f614212fd91226eb1d3ec8e1c53cdf31bc629eded3d8739ce46a1fcc9b174f5ae1b25e34 +ea2d5f4e9797bfc2f33f0fccaf530db2bdf8abcec00f09a0338eefdba318221ec0e050cad1a85c3f76b784c6e8c18da2b062f333eeff18b7b781e67d6d0a4368b8231a892e0f4103012348e5df53ac745e4d34e2cd1ee9369f97d4801ff485fc144b2007008036bbc07cb1c302a00054b54f3713919191e1d5052978c9c2895e 00c08ed8e0e0f8b0d0714b46a2164b933f8147692f18da97e5a108c44d5a5cf221cb50536e41832b83bff4026c6df156386235cf5e3e9a67b7cf9b2fa7707c5e0ff33a91601b8e34 97895251b0c2581fbdfe40b4d3159fec0c40358fe9cc1978cc6d1f454842b7075a67df7fb6618d4ff26a6a7541b70092124ee5afae0409284f842b443e64fc1cfdfc6fa130617664fe4c5aa1cc4154267ea3c48503a6bc9e330afc4aa864e0fd +b2293b0a09f41decd9d8e637b1b08c2efe612f33c9c0beebb6e05033c6103b958f8aacd125d7c810b4c287349f5f922d2c6ed554be597fb8b3ba0e5a8c385ed8ae70d5ae19685298f20e8d844fb5ad98db12ba7e5f45baed9045c3e86b3cac9bd55b614b82fd075954fc59bfc6124cbd68edae988596575f379d8921b594c75d 0144090a0ee38cfa21fabcc24d35139a99656911ad4f6dbffb77dbe74e7993edfa9fd63d2c4f6bbdbc8ec21ba13c9f4a3576b5d6e3abeab5af5ac81b1f2bb6d4c42dde645d854d9c b778f764dd6708c0a1531d1fe2dafb30fef8c04c13a7f095ab73d544fac084238a8419806373d99f021bbf31f39271f213486d06863f5f64ecad30f818ef30d37057b16e9733bd4b889659e0ad42c1ab2949ddcf95b4b5f1553695afba706624 +acce54270252e7d9e983c08c993cd6b7e3caf482a9149036afe4665bd3d0662a6818047187872862d5718b8ac063477f693caf1a9baa8bdf2f36d411a796f2b46ab56f66bc94924229f8264016d6769c85d9bbb7d6bb042fefdb8fde1be026b86af2017aacfe38c97309b4689b23fff94f1de880064f1d3ad9d74dc804c41f41 01df26b672b2e3617b6b6c631d3c6be0cb49c0a690de49643e0f416215bcdaefc03fa9c708471f1d87476d58c8f147517ec8a14aa945ef001fa01984d5c3d81f7083ea500558fef4 98523ce8cb6080ffaea3fed854c82491318df366f5aba6c6e702a4c73dc49a36f5fe3a19a943fed5bebc0ed6492be4010d9edc1cdaae0f75c2ea63f9b1ee78e576a673be29603ac3b0aedd291cf7b368f4538174f03d9e3384277c4fa5c32ef3 +e25274ded4840df0d71d3369007118f002b83e2d375c78f7e29ade067db15cce21842611f3f015db2efec57da77cb9d16eb1e00a8c1444d48dfda569e29fca1ebf40a22fc646a9fd44460f0e473bde487634bfbdac2c312f66a1c2982c6fe76c54ac72b6c8cc9345e47cb319a974b3cc4bb40634df74b4ad7e18adfa9a71ddd5 0189918b832e9fa30161fdd927bfc267f6405335df3d66d225e17173af52a671138883bcb94c4403ca3e001fcf09ef4c6488934d6775af2b1da30a8f331579af2d0fbb530298d8f9 abeda04fc38a7452e9d850c8f79f81820c77f1f0747b60efa210340aaae3ff18c94a1ee7de4bfe4c036b0f6120f247dd197ba57ed675ed3dd943bcc667c54fbde8afb163c13359dc119bf8f3b663adf3bef32233252c43544da57a9fd7e89d6e +d8a4aed87c316012482819b03a1d91691f2ad11a2f46082497ea8f64880d686891f7da550b2ac17199c657d4eb9d04d5cb8eaa180f743b87d23b1c86103f9e9bb60f4e19f0ff9d160f180aed7735130c03adb62502e69be5c624ed7bda2301f30580ae0921b02e103a638f5623c02c186e3bfe6ff134c762a2bcac1f879a9353 00bdcc175eca3a399b944eb0334ff33c4fd130999c8ac0e7b52ac5b774fbad53ccc3a31024f5262b2eecfeb2104b14bb244307effe3dbe8ed25686dbf46a42c4b6f8e34010ad826a 947e07495266abf47c30e3519805fa9ad0ba85596b90d5ea92e9c8fa09252c75c2d565e79cb0f4499c7f744cb2b9140d00fe77f7c3854604ed63c5db872729882b68287fa01dad618f4ef5b0788c8d494e6b02923a4dc6c8e216e2d699142859 +acbaa5ffc4eee0850075c0e502a70cc7a897a919f5e7bca4e798385601a26f411fdae5466ba9f6b6d8d7f819a749b799fbf4a3bda9105063e74914e8583ed8b31ea4d22164bee6f14bf53afca269b901c80cb3265be32ffd4ca4bc4ddb83e11eff82ead6d75dc4aec8e5c67f35d58a8a156cd1c0351abdccc0c5396c8fbe6920 0007ab5a55a1d8ecb7f5dca2afdf9ef465569a4b0374716f604ad42a6e0271e934b09655e8e2529784b69b2894bb399b02aeeae30e9e7ae70a2a8e56b9e775bd978a04c728e3951e a588443dff484761afa5b42ac80f59160f65bb77c8a2d8c7c2e9138ddc414462eeb11f1d70393e591412d1c548a7271f135a92ae6d6d9f7abab10dc7f9d15cb9ae31c811159e7989dbf0eda2fb4f7efc210a74e762bb557273eb283392db3bfc +9a57b63a4f418404e8f5dcf3052b9bc04a4f6d2c33bde8651506d9cbc5542ffb9023292dea463111fb78913ccdcd182faabbff9164219b8900c7f9fb394f7d9678f77b18f8d58526ec64d7c1328953b983a7c416583e05a069cd76aefe26e5f5687b70abfbf9f58f052dc0863b4fc3bef805cc3bb05bf76a83235af9d6adfe66 01e7d4da72b1d82e17a066fe387f2a0a7fa4c60ab993ee09710531789186077f2f32b42ddda497d5fb57356383e1f96973df043307f0b6519430c3f0d40d62954032872fceb7dce9 98fd0051f791d2b0522e32b0a4e2bdde36b7fb90e8bacd102b7a61035ad1a5230372841d3c0cbd13b30bd6e2cf75a2020344b40bb49bbda265332707de546b85f278ae47533db85b5c0e334f89567f3a9d4a385d1ee9ceb9b91ce32c60df96ea +97b79c76d9c637f51294369e0bb52c4189f2fd3bd0607f91834aa71b3555605a89ff68e84fb5bda603f502f620e14e8b0c7affefafa2f0b303009ee99653ae4550a05315e551dd12a4d8328279b8150d030b03c5650ed4f8d3ba7c3a5361f472f436b200b321e7863c771e20ddd7bdf739c51de3676f953a5501e4477aed1bd8 015b7271d4319db5743119c8103a7d4c6d57e9c62f3eb93762156d2ebd159980aa57cea948e416717d715a2e458851f1b2e9ad4172bbcc53861db29c3ee0ba8e82617a5866170847 ab2fcb08b813664b00c57dd8dde72a1befd8a2c637d690b151fd2df7a0f5e0695a1daa782422ffc602a3516a1fdbd0591250bb34ac2c7c103cefbfc445aa484b175e31919357e69cd1a4a9ca1d075aab1f7bd6ef3e0ffb894827b3fe13c8da8c +564ad0e37c9c37a60872a4780a723d08d1159ddc77bd834d74c1025cdf3cbd5338c3fc07a904fcad9b979b2a2ceb1a0139af35e5112305fd662a57af6312624b9bdd3a64849f95f59a46ca8feb2ed56f87f258518947474c1729275c4d89b7dd286ed65f286cbac76002cc63b92a73ab6bd13c4adef282f32297e441bdd8fd36 007219ea7917d174a5386df985d0dca798ac9f8e215ab2f0003aee929a2dbd91e37fedead0ed95b1e8aabcf516bdf54337b4aff7ace4c6b3179f2e919a49db50a41c9d4d58d4f636 a58ee3f24269cd16fb2227b49539a2b40657b1d9d2110cc4faf8935027e2a0c2ab2ad5e81b6195997f7beb45a551fff80d4682fb77e7893c9d891fe5110115ea7bf4d45009838a58b63214efb83ce07166d05795d829f6b26aa083bfd4dca9b7 +072ed5b14754fddaf54e20da42432df49bef38f4a3b1841b2db457ff86c44880727aca945770adb41269df41fc17f6a687bcaffaa45a3e59070526ed53b8dc3b78cf9a80a85461eaf4b477e44d5ec4c2bab9c05aa747a5a520b35fd09e8b44539d060ba1c3470267e0dda111b15dbb587614a46e1e477127f963a16cf3a43ee5 00bc623152253da24bf8d752bd78aedf7d5f6a2f889453ccdec14e10753335ea8bea83fd181a1f3680ed50f2324fbeaadae160cc85831750e021f3e44121ea1b1efc29a7d0069479 b1f74355a446ac357fe25a1684c37ff540dc28b7cc9e95d529ecfba417fe2911ad071a66d01635414122ce859eaeb06501f4da70072964ec54c68c179e1f5cb00d449b097f38da133e3793caa914b3a987a80723566af932df20a7e1d87dcbc3 +e660dbdf3e61af39b83b95d3f1970f66d616f03273f7dddb98f768452b21cd39604a31cf80590d4a5e4b0d4917519e10fd325dd4ab7a52d70d154506329baefe0d5816f514ae109483122b4fa8fa1ebd7fdf1fc4e21e8d278a50c05d81c8f489596633d949c6c8fea96fe91430c01522a5afbd5042be8aa47da04581b2bd21cc 00645947d981d258f2954558c31022a3b6ba5fa7b675312f794cb61bfff1d9ce87267e4a1dacb7c8fc58624d31c85ebe22f80d26a620fed5df5bf38515e0903f0b69a606048197d8 b3ce0d2ce62bd028e00d7431d19f371d3909fdb8cb0249c40710c9c6efc8ade0c4d19b40dd3124eb282a9fd3cf54b44b14411c81b55f0b58c4fb71a9f470f7f86e49bbdee80499daf7977db7e8ccfd909164724a738b82d4dcd00d2005e39c7f +8c9acbdc431565feae60e08bc7da113e12372ed373f1e1fdd581f98c8a7b0c79ac4aa42c7ffbc963fb4970fe26c5b5dd314b7051fe971c1186ebcb5650f7f7011a924de893f06961b8c75da7bff331847feead4abd2e8b9d6ecbedac18f4eac207b948e6e4215e4d5cb483e5c66ce7ad788cb89604d3a3e051539094079e7bdb 014cf93ca69d94ee8fbea0c8da9d76aea092b73073d8f5385b65c6dd4d567fe86bc2cfb8e8be890c3c6cd9abf7dc3a17eaecee3d7a9455887863e496c48dc3e47821bd3d825b6bed 8e0c68781e9baa19aae0387ac3238117f041e8d41a08b5c9274ec4f9c299848b531ff29716088104604a176026044fab16198757bf3402e8cb310af2128250b5d272d0231cdf051bdcf1418dec582d6da640de9365f9001efc51e6943199015c +53ef87d6ac7b9698f40b3ea9f3442e7b64207b140b7f66f73fb7d5f8f98452d30a4e493b6c0e3268371e88e612b818d4d847f032ed4983817d020411a52d81fd2a17b58ebdec199d817c2a8ba77042bbd747a6fd4bcc7e844ea829fd8461b389aa0b5957d92962b6d4e86385a8fbca90b8fac40944607117e9a4ef6dccb8fc1e 0033feeaaaa28f16bfaf5ea9c7319cf4561ba4fc55327a8477b6cd58ef6ccad3962ee1f3edb243f3a04e7e49c8e23509fa2d63252adb186b8bc7e9255cd61fa9bc45242d42da3a68 9947658e01007808bfe43e5629f3fed76357a7897570685a3d9a778f475a72fd13dfddcee08c4990385521d43e6f01061312cb3c14209175ee0dcb910cdac073deded4bd5029715db8ae3ba102ca9c4592cba320aa17155b0777bf7767f04398 +dca1b7a9a313ead11c2d54739d9017ae27f9d08b3544e418aee862bb57e427636cb6aedda28e10f12aa15d2355f4f8ef112a86fec5dc46e6acef693cb8fc37c3e4885f3be3d3ab31ea4d73a0de904e95c7135a149f77b621d642f9bd8ba192d39cfc58b6f19a797c4f3b4f3a87054298e3ce5eda0ff7f44f8134c9a108285dfa 005613dfb53149bf5fdc4e08ccc1c752b0b66ab43aef2d008ed40f3df40fcbb2938d2c41e3ea2dd4428aeba9059a97efe5593119673866a19d27a2ee37dd357e22b6bc849e7e22cc b0fff4d7bc2e0b24b47ac662b2bfe3dd6775e6b85060c5098178bcebb09cec4568c96b98342c3381d88fc2f31c1fba770a2d6ae5ee9b22bdbfb0090923b0db98b2deb8a1f952923e4b0afde93d4d457dc0b3c52233df70a2db1f7a74a77d28a3 +aff61d62c8f5c31bbb7d0a64a6ac589e918bbf2f13e7ad13abb9ac26405e267249a7c9922139bc28140833e10976b87e91cf28285274b2b48b63d24ac94c85c70fafa78f8ad05955c0ce6c02b841ee196dab12306e3e3d6138371217e2b474f7e67a80bbb78a47e374ffe2c9f86292e471c551da50d46e7b5c8331029f369767 011b92c8b72b86c51903387a65aa206988d443d1988253329ad3a89c902ff1ef8cf73b7f2e4aaa352443bcb833712d94c3e637ec12cbe4c2d4606878576b17fae1512fc77785b737 a7fb157e5f872caabcb764c6b55744761313384e518cbb404f6883e9b57142712fed159ebd58c8d3aa832256a6e6d95c1398df9c98de425a7756edbde6f8b9ace9d460609c603e1d284494beb51fee7c79bb74b6a8709f8cb06270c87e64d6af +721017294f17ef351e41256b57a64a79f3636628c4bcbe676ac9a2d96076b913dc4b246c9945183ec9bd2d251441b5101eac44e2fa1bef59dec03ccd7fa5accf3b7d094d68dcf78c8de4e2f19f56bf0dcb3b66b9421ec3f8b353b9fd74feb2e9affe0bf9aa421b6f03eeba3ffd58fba56b3ebd094880e50de01ee62a108a24cf 00c3c90d5ce4375a08b85575faa78ee6bbd9e5571ce5a90582042617b807339c282cdc3b003d82006264b1c08c20af4ad4549fbde53d262facb98d923d81b8eb6093374b6a1e84cb 81e83d0d7e635a5cd40e3985644f1deafe667feac7bb17eb77d17d05466fcae580f4991042b73bbeebf7e7e549eb7e25176168c6df7e29f582b4db7356c97d23caea67a4e8be5e4b54e4075b0a2c7d1e8957ca6b1d6014f0071b4cb0e327714f +e2d1f33681759adb7954bb5248b0db3c3885fea0d4c1c0c226eb1e6d2d3ef1b9ac281a0f1c2fe5175b67114b6a501e2426d1454bd5790dcbc4c232cf06b017de8a9bb39e6033f1edb5003e8de3b44cc3d6150c3c952afb442952483cc688908337b7c1a8b5c9da70937ccfa98b2b0098c530ff848010b8e8ee0a8d65283481a8 010f184c16228d9034271332178ed485d10b6aa76003efc160d63fea26fbbdf5552205ac7df0d8c852a1210cf0ba512f20b798827b36ad56b12a826fa7dc1db45aed264ca6822659 a3067ff35530937fcbeefbddd60b89f8045e0c90df0e52247c589fb2b1f7c8cab5cace7e0baac9eaf360d73bfb38a6e7113007ce16576ff74ceec4f7f13f50f8e5af7ffd04ebc18ba1470ba5b1a236517c1d0bdd8382311d0b76c325179bf0dc +414fc5d2bd56b30040e105cb891788792da595583b11b8fcc7320f40dbf64d9263532dc57344dd17573c95eedf851668b5d552e8796af205f3a0043af1a829fabc2e93d9af9091fdd9e0fcbcc9d6d9ec960aa60e4e2964c29a2f375400366480e513f63d124db7745847310e69a38c8455e4e602056a6a4a14a8694155e0a9bf 0181baf9d497159f837cba58a11ca435c442e5ca792ea559bff9f6a1f562c05bf6bb5914afbd1bcaea75b35f88bdd832314b249a5298622c89462344d3f28a44ba3d059df432fc71 8e7c1801b9524be8f3edb8ec2e1e30b35ec164fec0155c206be4556e6d468a3a22c3372886ad6e5fa40b838b75069577122719899b4a42185f9b05a4b54ddb771c948aa0bd4583d6bb1421cad64316c120f0fcd741fbe84d29ddfb53854a083e +3b592cc8972a4782870e079b82a50f84b4c2d8ca90bd500d1ce5678982e266c391c556d8162ac3aab967154d072dbc0ba1dab5545cf2651753dee2881eca5abd412fe624bf3f9d17d33692d21ce23ad15ccffdfd250cb1949e73c9e40a64ebebb03852e92692dad1d7baef97fe109f35b7a492b343d4b643a4a7b1723eaecb64 0083fae86ab96bce99a53e50b7eecff38e4e25b21c4b0f6a4986915de245eae24f16b6a00a4db159ebc27f5a6a072da94ab6be5bf75f5eb3f75c4452bf4ea7014392eb1e02706fb4 85548f6ca9866a3b611fac1ddeb36986cc6a06170333a6d4e11bf50722729766ca2a48e0b0592293f33e5092fb8a0f7c08766855b31170a0de3308670bbf77ef4f336b62d42d60dc4257c0c42ba4613b4c46fdc383b63a074341f6063ffcb21b +0079a02cbab3dc02601fcb5c8607d555beef7cd71a66911ab6514a4ae21c5a9c0e166f8cf5fb198ec5a49a96e17cf041f35f00406b79270ebfe56dc6b8417d2529fd625686ffbc8f69685aefa2fd30a937c02f25b48be4679e6fde821de928b33b12470867def874bb8c7c8038ab6594346a2c44b39210d3610994ba60a05e06 01a663efa7bf4d8479bc535fad71e9b5e4f4281aec55967baa008ba17ac2f89cc3398d30573edef29d590fddce8cb157f655e92779f59e7a18d0327d02e7daf4c1216143b3688fed 8190a3d8e95f04da7fbbe84ad9f24148f56c81056239c296575994d8c5a5a6f3257cb19beab9174a5608eb6749c07fd215807bd5cfd454d74f31b3e8cc44100d0804332fda57a182064163ba2e4a25c37bf32a51e89574643bb0edba0bfc3b1f +88573bd94ef50459814806efa868ebf92b066fbc2f7a4be9d2fa06b9dc1a72f72d783a6bcbc107b18a6314511bff217037a2252e7a5cd34cf9d5b2fe9c7846931f0133b2e95876cb800dc4ed7c4a4e4cc4f1195acf99fb0ec224b1f8fa8af71f72d390eca9d6be3879032a318734a63fec336c79035a43f70271def10c4955d3 00088d1a2c0219696a94337cd56516252b74139ea0733b17fdcbf7692c3e5f6c3989e5da2aaed7468e65a5d578571928ca273ec3b6aa72cd196f560f05095cdc8346e5d31c4c2e0c 856749937c70821af7590a507086e186869125786113915529e2cf1852dea9cd723225aa8f85c80a71c0493a480dd8300afeadb9abe06f7909b95d86d3d3b8e3c1a35dd94fd255b3987ba51208296f013142faa68cea5a8f0a93f8d9030a9135 +d0e02045ece6e338cc8ab41d4a064c982ccb1748c48fc2fe0a6f10bdc876094358a6a90a45facec798a83cc95c6795cf0f0d7c66b77e22cb114c1432bfdaa1485ff35b6a58107cac3b7e58cb4f6c87c68db60b751e78f1fdfa54b8923b98caad0a4f31226956d065c083ace5f1e9e91944dcca51879d782e40358d58ca758750 016cc8a0fd59455ed8d4de561fd518df2e008f7dfaa5f7f29ac2489a411e233917b43eb3ebe2596fc824be58871949545e667dbcf240dfb5e0c615ade0179d9ea2a1b1ebb8ab9384 ac6fb4a49130feb80995f08f982ebee6bae49127b2c7b310ff22488ce9547549d8c9620fd3a62c45146b848f7af8b5360efddfeb6ad22c759e02a7d195bd8bcc13dbd6a9b6ad881547faeb1a1bbeecc6a074f730057eff7d35b66f93f5d48ab1 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K571_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K571_blst new file mode 100644 index 000000000000..5a18b0a0f95d --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_K571_blst @@ -0,0 +1,60 @@ +964ad0b5acc1c4db6674e86035139f179a9d5ec711b5bae57d2988456bb136d3aade7ac9ef10813e651ae4b9602308b071d75a934a6c012eb90c5eb9b2947b50fc97b1d36c5bf9eb13a7b06c94212c3dcdab402a563262298defff62b836ead1f78f9d20713710fb48115cc5045ba15140fbb4bdf516e4150d830d02cf30963d 019cf4f4d06825499949f9e0b442586fe1bfe3459813a2b92cd8de0f775a4735e02655702ead8e60824180761808d9e816d60bdb0238e1e8039ca7bb63c92e1cf8433ef447e64ead a87bb7cbf45e6b6e3b58948ec510bb14d7e716dc398c9af46683d0237daec61e2299f3918bfe5d8929feaaf2a5f81d0112bb7eff401f3a52197061e62a35d0e76ab193c680bb51054371a0fb3301cfe77232209d4e4757b1032948a2b60cc043 +baddec4794effa668cde267016dda67bc70b847919a9aa595f93ba9dc27354399ef7a607fbead31e57a8ce698beabb10f313d393980425e67cf95be45d512f00e950c0c5409573ddc3d556f23daf056259ee8914e860562a674311452fed780b3e0317a7fe93baa81fb98df3ae4328b28ad0ac8f8ea33efe24faee658ad026f6 0098521a732e72ed945a549afc92318fef7156ed1d1ed9bab93b581478cb2339eb32bcef705c9bf61cf2873ddbadff8ff3806740a2e30ce67d1807a8179dfd5d952e6f8a583baf81 8d1b8b71d2f3f373ad94a1ff266fd2e6337ac5d65d9c8228a2bc6384fc41b4dffe6c694f84be4837988cfee3207bb3f10109eb5c9e9fd136d012750c56409c22b63c2e01a3f6e8fe5dc5697b1e258e32cd0bf9c5bdf736c3c1f2b5a6da080021 +7ef7138fc657492d229054f8a50dcafcfcd1dc06f1c16640af3f658907e2969248b54416066eb119adbfa23b8dc578aef18bba79610b9cc109394b900a25e55a779230bb858b2ddd9499a7775d392328db9177aa9571c2f61dd52010b48502154e914a0c55a54edcc04a6713cf7bda8744a893926118b09df877d1a4f3d95e8c 00336fb21549e397a190beac38a1ee10f0551952da15f71e11dfda415e5ee08da2356f114d450c661f52b2b32cfc7b9be61732672691a079f0927989b7e9f4efe6095a242155b641 acbeff1d79197c83a43bf79ec4d04024e6f90d0ed9028302a2eff7db4669a243d108d327bc62ef7d68b8a2002313ab0308c191ef8372950ac53ced10019572909a245679ebb372c1df14af67ab76339a1f9831a4a41c4e2e863987b3bef38f5c +d58e1ff1d49a471d0567ecf8f29173dab5fe5f6184ab4cdd095c231fa7b82551f99a482994a46c3d8ebc07297fc9e952a5dee7d5f199b119f6f8b250f8fba45701ac252db725e75c4da27ad77d59a4eac448e54a277986740dfee6596811e59afc9755e53d24b826c09e497e29e69a22bbc85be11763064e9ecad7ae66458ca0 00e287ebfd9ba294128cbd484fc5121d271cd33e685bb1804f09b40aaacf64b5a9f2cde9b30a4a02d3a9bda97d92f46bb8787b3c61f280b1e1a0680f1f0679d3bb34d53725d62e52 b9639c4019d72cd560beffe1aa4aaf7facd439fd0ef0f6055076098b19df5ba3834512ace5a2b1b5a8fe1f6c674f37f415517eb984f14b2ac9c8abe49c18069328b5bfc1fe87cdd734b19fbd7f5fc8e1314f540f610ff700c9341410f6735cee +4949ba765c14c31f68ee0ca26bb42ba2edee63537de4a6f5c42bbd862c21288d6ff48145260365193c6fd2b56dfb014da26b8a483776b717c6874f627c9a622154b824565b23e178240f53ee9748c45759ba5c035b584df0f09504e95eb9bce0301653aadb860bb25e6ea6b9606e0ec3bdb8089e6aa0d5763d331757490715f9 0149de496fa8f88b2741864d0c35b3df666b87179b7bd06cd426a45f13bc87ea9f50dea85e1fd02a532630e0e3a231cc3e7fbb7c7ba85b40cff1124e72c677c6a3ea6aa40ffc64b7 b34a1fc5ca8ad7fb41a7feda853f0789b3f69dbe866ddf03f6b7e1f952be6579cff48e539566068cee4b42d5f87a4ef712d36d3845a4a29ab4800be68dcf20f9f91a6d999bd61352ae72def0b1f420e7eb804862491549e8602a2f378dd5dcf0 +5bc63e5c50b1650f0ed4a599960f1e4e11f6c151b2123fd71d9e3c44662312a74b6854290628e20b30eaba81555acb2fb49b640bdab2528619c7fcad0f2a2880c7ea232d427d7c935fba2313370fda8863a7e7e203d63ea15d0cfa083e716ce6068c63fa616ddc225c9e413e694cdf6b355cb1293af5d6cdea51168f5634e878 017605d7c5873d870462375d741b4bc6375f3d47f7f5e9d998917adf2137a81e63b66917b3dda8968930c4b850f2270eb3187fc756e2beeaa67fe0d73053e6cc0ff0004a21250551 8fcf194742f40f64b4d8efa7a82eb0572c88fc1b325a6ce866915da4c60dba2fedf48c6b3ff50fa04d5ab915d6355e58117b8380968c1fd21a2d2f9781be47f80a0e8a1d52bf1e0f141a4d36dc9dfb78c6c1cf5dc2752806c1bece4621c2714e +610f6633718e49d232b3798654095e2efa0de11f41258b27aa01956480c870d901efa77e109d5f95f1f5101d3c90fc51312d9b3019d2e42e0067eed7b457dc7fbe5466923b62c83d7347e4dada571b57813bb9c21d5e308519b8eedb7a7706508ad04aa69698e03636eb30fd9fb363ef3a185756494ee01175b16847f5b68076 009214dc2da0967912c31995cb8f5bcf4bfa832c5a2d3610f3a9857e5eee7c77100d599d9ed003b4106013155dffd6c48859b846e45e0ddbc5fe24f4891c9b2df51407e9cddbd974 b44d8356da92943205ca78157e6f2740b32c79919e1cce969f5e11583d8a39a24ed33f2d5b9cdabe77bdaf0c7001e3ea02f5a42c43ad53f50c407cc4bcb01242350b4c3343e04a627b7948993e275e22ce17b8a7464d95fd4d5200a83d717ed5 +c548f0546cee0c0400401cd540a0aa9377f27ac64492e6baaf38e794db4df83e64ca3d83b67bbb46a6c269c04c2725287cce0dee984a0d468c9ce495a7e554a6835d72c7493bfe88dbd5a044a148c89001b8087fb03e57c2b7212d0b175d616333a9affd8a1802dd49ba9be3ab6c6d9f99a5578d26cc4707a5860c6c804d69ce 0042f2682e9ac8b76f3c0880e12c292524601dce9ea6982dcf68bfdb0d3fbfb50dc9229e54149ef09b95bbf624eb04ce1427077f30d8536be9f69970ddb449ca22ab8368d2689ed4 acdd22e05b3a817867bb390fa601419340ef27debbc376e5f4a1c34fff9d65152841f5e58549b565c2078fa7e948abe402e0872d451497366b11d82cee876ffa09e8148b170fc688a887310fe8403a0e6efc44da661e7fee9c63ae948283b455 +9431c6c5237f6b4b35682a0c32f68752035c8b295a1763c5dbdfd73466cea64a00ecc11356d02d2a9211dc54548f5db1651e4471898402c887fbf45005a3bda271df0158c98319d4d6751b8ca6b07100182957d5fe0d97c4e2294406f83e9afcae4850bb089f2252490417b5afd8f07f4c795fa84c9c7cdcce26bd97273c0072 017ed9a9c75cf66528428e85b0f019e3488af8b893b12023ff1b4ca9c3691b74e594539afa0f4d7c3863d15399b862f15e27bb077392d6bbd546ddfd46728c75177338466eb2f4ff 95754dc5c2731c4045d9493af5f254111398eb829f189c39ae23e89d213d3343d64191d68c3532db5f9e5842aa8790e206bdcf8cc975b15150fd05eba32603273270add42f25632310a3a52ca1c12322d48c6cd25923a87f5c26e70aa07c0dd9 +417cd5f60416f17081d2c70e9a510114e08be83573bf9deae75fbc3095dffc8a7f7325f61f9d6565381710eda871388cb17619e4448836076338ee309a2bba5f737319002e259b4a875cce1bb97996101c9a7abe0278dcac203a712f0809eb3c4b85a9c380550ab0bbc5067a8edfa78abf03c09b5c08f21714e1022ebfcada4a 01bcc09b3f2f1d26ab9955bff7e8c0f85c8a61293511a196b53d7963f4a4503849c96fb4daa68c9852ad9185e01a35f0bf298e34a09ec352cb6da34f89a1f23e8ea27712a8f43aa7 8e9e16b7d5f75b8528da37dcc069485bb29f70d9e78cb1a4792293b69e5099e12ca4dda3325fa0b79c46719e721d608514b6090f7f065a8ef01accc57fc14a553fb8ab609b65db10e371384a3ac5782fbed7610ed2ce6351e20f7cebd2400b53 +eced8c412a153a643ccd69596389f83b6a36880286f8aeede503452bef8305942d95734fb5733f37ffeceb1c2dae7b1396c3323de11089082745c28a1756f784423fa7ad68bbfbf0d93ff8b7ad62220500df6d6895788402c1f5c69c06dd9ef55e2401cf297184e411be87c1bba657f847208c0e750f94a3df92f253b377b4da 00ec52fc3d9c272ca80623e06b15c35f349b13548ef7ee400bbfa04196850b3b8cc7b239238c827f9b0a3160cd97969ce21d66752791f5896e0385b0527d4d77e4b9fc70f04d73b2 810f9f2b9702619f554d949183e13023d8623ea22871c3e9a929b22b790386eca432d055809add253e517eff03957f6407a94921b60e6dd235a9895d23211e8a587fa2b532cccda559ce58a8ce5335c06d0067d40d3fe1c986fcdd1cfb45b6d5 +30e83ea39a92036e22b7bed7639eab5e5be1d00c20b4a9b9afa9a0d1653369cbef363c119cc6f921c8f84663949c8b8dc9b743ac2b1861a480476e9b64c8f333f34b6fa0e1ddf09d49618ee4f3c1f46751b5595f0aea413d4ca46f3c26b974b112cbe99c813a96a4423764c069454946f213c5f066ec38108f947abeeeb02fb8 006403de7627de22d1dcf6b8da5af62f9ec59ec065cc1ca1311bb98aa439a6d5985619b17c17a70f59e17cf180ea6828ef57f5f1f8ef05680a9fc12ab7faad5af61e4e11fb45d341 8c841f0750e733dcead42312b59a25cafb264d4f977e888ce84df501c2bc373867b8084a917c9af22a87d649856ccebf19ffeef1c8c15571b7808838bc6845726c4ff335fd89ec458a0719652d0a65e3d08cf89df551cf0a3af4eb7ca828e90d +3ed244dc16a5cb292db4b1433b0ca3226913f07377faa20c6c1402cb4d026de808ca74a6d4ecdd7c4e662105bff6edb9fae0117c50aa053aef677c0750c7a446edbb879110030758912e8fa666489d702d8fceb719963b24a256429bbcc869a1f4ab9de9db89263e3684d4daa1df2ed94bb59dde2abba63793e5f82aa2e4db83 001fb980aef64254aeb9bb613ff2fc6967503db4bc1f337882f1566cbeb57489cf32e34f310549f41cba1b951f487453c29753a184e33330e90d4b973d2e406c99a239a5c3f96233 ac99ba8dafd5c43466cbd1d73f261687047b385f4fb4a41b5c4153ec01c375cc3f80f573f8fa9762e16ee6a2b4407be0116f73f113625b3dc79e67c66c0b6dcb687235daac5e17187fba33a5415486855d82d55d97a88c717569554fb3b5dbaa +40343935d9423ad30f3fb1832bb08a5d20ddb3a55b59057cd275320db4a5835471c96cfb7d67f41ef860cf5879897b8dcf307bd1a52a6226847b768ea38ff1858f59e64cd635b51e6863773cc6c64b363ec47ca39266422406264668415c189e2f92447ac4c63ee5d74e95d1e6af05016917ad237f482ea0b02aecadd370a8bb 01d96dc09dfaf602789c1dffa5c9ba130832badcf180429660daadf4cf1be5cca92fe9713173861670eebfe3a0ba25bcc76aecac60a756f07b69687e05c7e25984a39556469f62b4 b763139eb73d2fb56f77a656f92d39c288a33ced902083f5354b3eba26cae8871fc992fd18cd62eff67dbaf262bc641608381b5028ecffdf0b5e0d3466442e935b705fb7a092feafe7994754f5a571e80ce94df8f032320fd7d9d1719ecabe59 +274567f8841183e68c4f6c6b36c5a52fb0e88492e4076b9cd768bf571facf39dad6affeb68941ee326ee461ce1f33c26e4bfb3c9e0cae8241fbcc14cc69c1af68701fd0be3def1e87b7d52b682ebbe1cc225c1bd177b0886e3698a06d0e410a1f92c9bdf7239189f6acde0d0653815a72987671b415d1e8a70e685d6e5b14c33 009d98b32c8eacd135ffb8e13223690ef02c0c1f29ea8b4da193502c8cb3f39f9eed608c02fd457f2fb685ec4595e8fc8f388d26778d225d2b18c9bc8b199d8b65c0d1a6af33854a 8781208fea31e16a9944772bd7577b9d5fa0a8b4816ae661387ce27999ae2b64f86823b25011e9c2734cfcdfec7c1ce00b39b806205f20631e93790d6082fe01a4d170b032ba7d41708319b75adb5ad02e796631e2f3114a28198701b1a4f80f +d9c99b8da92d3c2e40dea3c4025dc37770e867c4d2746c4d726b6de24250591a586c166c88acb8ed340e161d4c81b9d14c919a1b06f1feb22c5ce5fca2693bdaf4994ac72c8983c87f331473fd094eccb3d5f3528e69d487562fb5a65c150a8217192f8aabfa7adcfd0b6916d5000248fbbddf1ca2f38e3d9ed2b388998b7cfc 004d873ac744c4f68bb044783ad69e1a733cb8b8f483f2695bbd90c4211282036ad7914a53b25c3e890c6824643cffbdc4138d7ff457e3fbb99387494eb5cf2bdf1ad243a3a1e644 b6a7225c8043fb15babebe872564aff42b570c5c548073cbf61cff4069c001dd82fc1f9a96286946d3483ea229c91ffe114bb9f27f59a08bbf5bce6464aa838e34bc79ca87fc767be9232f964a9ed4d268d896a875f62fb3e7f6173be7a6f88a +d2b88a01fa17703c99e5b867c645e98feec0d6d1afaa20a97b5fce9c23f0594460142af4e36a5739b8d26d3ba35a0263caa5429b4abba157f359fce701c43372500fd2ae1bc2ed80bfcaf8cab7016ff93d4a27f565b7e67fe7dde22bf02c48be12114fbff2421517c825019c0ccc72d927bef156140d7f0e9b6ee37af78c3efa 018d2eb947297a054f8a789771dd875b12b26ef057fb91235dff3b062916f85aab3365609bd2a38a861439c8514e33f174c198139354e63766942f605107cb1b9709b782622b295a afa07c40f758277f9b45e8839628146cbca104352ac47c2461f3ccdd13e8c2858939ee50c216bf754ed8bc9f9760639c17eabb74c11401e6ae4acb1146d1bb39b819a9bab5eb0d31c3ce19470f588654065408578b9aa1378902f6bd3078d654 +a704a1428cc894f958774368979fe075353b56790555386e3b043dc6a2919b94a11c7f85883f46b4d47b324d349c28c667bf9a000daaca1d7191f2a0fd97a4867aa9f72422134a690625408a9ea4b723704690b69152655f9e9dd5fa3dd94814d97dd4f13e85c3f9bca769491c2461fbd17e28afac00bfa81371d5039013da8c 00594fc0b7a5cc0216d2e78eeeb6394c8225de795f4b73bec48b2f4ede185ba622b59a16dd3eedf8cf2c94f2ccd6dcd205f64c97cf1b7f1e34129e94b5129502909f43940dba0746 8c23270aec43e5cd63a2900e07ccd40b0681ffa3bd1cb1173b2a68f67b28e08408c991b6e1be979f76f3c0d32625ee0505e748ec3749eb98240cf2da12a08d495ec7719a6c9db4e3bced3719b7e9f0df03a2d6fbccfe39d24488ffe06b9ceea2 +f8a87c4acadee27a908718461e3b45060ae4ebb009b10a15926460bf219cb7e75dc3a993fb9a741b94e2fd71615c50f6df958568f452b2cc284f0516816bc0d2e2d45f663155660a26326f63f4aa42a6e1cc8462a2ec620a365257ec042f55e4047b62af689592a1a072553ff174dd629a4f51837780ca232cf479a68c1ebdda 00f000631106c5851e8ae0802b01e7a8a8540b427a8a3956a1d36f0600be89318032320cc420931d825cc964e823745c60aad3437ebc1c91d32004472e9677605fb708e5a71a0d83 92c5a6e8b644403e9c2a8063364f21ca51a68f5289f0bb1c8dd594777dae77295e882296f0ae0a47b8a31b972cdbea4d043dd8bf38102632472426515f5145a0caa8cd4c52daf424ff03ac7ce858a38a843a571eec6a7010af62331fa506bd5f +10b5438294a77c7e517ecfe8f8cd58d75297b14116aa93e574996ec4acb21837e6297cc0e7e7b5861e862062f192f2206a01b1caf42c6d7181d02c7d62b76c2881f8479449b02d32c6f792714d8f70f0c75e81c7d9abb996be87f5ad9a01fe42b75855558d5f00df392b62ae0d258f3f67dbeaf07208952e679a2c573aca941b 01023997206341c6147c536d034a9c38b4012035dc2c9b7ef0bb9cfe65e7d788296f055d508a1fd957b2dc7f9eb10c27790f15f30d81670945e54a508c57b70b46b4a09f4c769289 b011212591d6cb3542bb1946c212589f884c069a04863bb9a60d21e30a8e78428c4d28f56dd376a1099a47dec79dc756057948c97635ccf4390b3f54e3cec1c561d9c6a2f6d4eab44f430a4463ae4677c421f165be836ebfc971e972c2fb7f5d +d83a52d43216fdb16b1b40469863ca8eff4df9fa358deccb5ffd18b3e22a9d654aedc98f3dbdc4f5b4e56b4299e25d8a5a38d01b34eb93de382df1ae4d1c7f966e84b84c393d167aecc6f1192c4b42cae83748b1ee3d9147ce7de74cebd122695b455e8082f86e3e488fb0f51b3b7edcd579940d1cb9d045296e5e38f201b7ef 011ebf320ecf6a908ea5b868afb8e22246ce84e743e1076d6185ec65dd79043380708bf8da4ba802c3b93b8d15509bb7d7de9dc29f1e9fb0f0f2cb97a26698f955b1f7ef668122be b02b3ec18cf66d67aa39a5155d89590a48e55b8bca4e502d38c215d8f6d22632450d41305afa0a4ab6603a1ca3b342871594d92d8e4ca745d2991b3c21bee1f59f6b2da9a85a48ad39564adb886a24efe46ecc6f4242fa64beda6f6e4771dd79 +eddf5553ed4db6e8ce72cbcb59fb1eb80671c884ebd68e24bd7abe98bb1f40806de646f4d509be50a3fabfa85c5630905ce81abfad8a55f4cd80208afffb9056bc67d9dd7f4660a5f924af2a3745eec2daec39a3fe36131fe9eea444b92d31f6a125f12125159ba095f89968a7028549466f41ad45668a861f671050d2a6f343 00746d5c824d78f42a1fd63d8fcca61f154ba3e75788b7a0b87f53e5420e23a935b02eaf67bace8dd8a8e7c1caee30154c2428e0a437cf12e235f41c416f92fb54528865fd4766d1 8c5067e8bf394d9dbfba03b82020949b140c1a8cd76767c1b0c53c3d00dcf14e86db109afe44ff2d6ff7c99ea5dc081a01ca77e97874f32495f250a76a65c69b17cc4a37c0a1e5dcad6bc63c5597ae57094caf8459a02c8dd6b1313122ead101 +3db94335f6d1a125309622c0a9d71bde1da09371f0285a93bd0aac255fa8f10a56074e0f6057f1b1aecf2d86a2319590ead96a2ad1336fe844e09339b456be32374ba2e659fbe9d0f2cdd83444d117d2ce3204ce4b4294dd05405634b84747ffb4227160c4e5c2c9da9815b0c6d20f55705f16cdbaa13d107ae666d707ccbe6c 000670e72ac2de50dd2cdd975a6cdab10ac45e37ef7a28c685d77447051496b5e161f8b1b93f6c7f32fce8ea05e94ed35fd7cb28c44bf51ea29cbaf5aaa31d6abca30a89430323dc a7c81663800dfac122e2d17f033aeaeed89e72ae636617da5a196dd5b7363524856a34707ab54f76376a5068258baf6b14af0737decbda44e08724daa1f3ab9325358182ea8a4c89b43cfd5a98c1079b9fc2b42e708df6d3760ae3d1cf170081 +69166ba40768d0a3930325405edfd85f3272f7b8e600b0b319f070274c91f9f03d0e6ec4bfc7b4445e91b87cecabfecf5e77c7301ee3c6b0affca2fa02c92216698705eb75443eecc25438db2d2fb4b24f4195d6b9c05c53e0868d3e58477100607ffdc31b18c40b4ad7202bb034e58653daec0f6b33c024d42a3fc84bd8f86b 00369a3bb96f884983c23281bcd04e24a3e5f6359f81e3c8e46f3f6b865eb6bdf98a630e90646275c587e41b546d3ca7688cc207afda15cf9b25cf83bd6ad27908647f3f9de59de7 918d458d788a96cdfd6a8aa8fb395b46abbca6c30ea334f45ea8df9065ceb50a0bfe621da99c4a83e42d8eb4e133956512ab23a8f50e4c7acd44050318227ec370f87a813ccb64112b5aed159fc8ecba724f68b31065a3be5053c2cdc380cd47 +f64cb668b72f1e6dd026a478505c0eb33446ae9a2993bc7648aaed02e172fa9a0e05eeec61e756ba246c1dad7e85d3f01baf734b1905c5bbd1b08d833c2cf1e079eca75b866d705c407eea8618d23ebbaf269c7185984b3bd4117ecfb295ee6b47eecc8d3a78bb96552f6be314656f91caff793838226662c75cd7804b6bef79 0026717b039df834855511815d5665ff9b654facab469390ae257b7f0eb4dfe66ea0dc037242ed0c13bf229b8f7ff26da9b55fe4750d3451c62804aad493c179ae45d08ece5af085 a811694ee3b4d5af26d0d7c8022035cbd2c30106dbe9e4709aa5bb5584fef5682e5ebf09a75a234e067f7cdf9c2a526b06d6b48b57799d2c6041b7b15439318e21b8ba2ce273c690f1afaf26f1f839832de18d833980af8779bb7bb060815b1a +51ee0b98eb6a3e3c1afcb35a33697c048dbf61374629ac5702a57801fafbea4d6fa5a26c9d1b79d1c58257ac0106387fab2d4a1b7f8c0dadcbe7c830613531b3c209bc17f792bdba1c1fae1b7528aac53dc86c2094b40194577325c05d2258303a2d17c854e7449489c43991b6877a50692a6340a528a6b188440ac0cddd4c4b 01d642f2d393ed4abea37173e4a79534af87adf534ead4a0a1c46fb047619221e3577e6b8bcc776114d01159c736ab78af3e53feac339d7afe58be8e7a8ed290f1dad960f1b5de94 8bf7c8834fd30f21dbc009ce199b836d493486a7e7435ed24717ff36c3232d95d98cbf8aaacc4a4048685a25f388ebdb15fcdc5ac444129f42c6a8023d56636e4fc8d0095ecdae9ddb78570b9429233bd10ddca0322e8342a5dbf4f7da5ceaac +feee50aeacaccb6b1c3d95c6524044edb78322ee836d8159c4a4c2cc6982480567c4c6cc4806a564876622266e1ebd45f2f4be851b79da025bd57d0e6acce1ec1c8c255eb89713a1e4897d4ee0f7a248b9d4bd3ad5dc0e57f60ebfb65691e164bc908956a019083e923cfd33dcf37c735af3462768a1e14a8051d7aee74d5228 008cb70be29e83f697a3e2f67d86f1c1ec9a163b5335cb4a06004b6634948bf60b8ad9df9b27d2bedc4975265ce44a7884e57082d521320ca4372d38fc77b18d3fa05ad8aa5c43d6 afa385ceeff577eeaeac1f128b1cb1f4e62b7c7328c80eaf24d9601dc25c3b5641e3940dc824222d72e09c1b8a7f6f10104b67d25fa87ddbd7746ddb87d43c6e461d660fd63fbe3bee960a6d9cded1cffc0efd75d65eb2f13556493d26957454 +b115f7370d6a93a90fd9dfdfb292956be34b61992ce1fa5627c5e928d74bcdeea66d4040c473306a0070fa8363c4303bea32f73ea3639b5c6676fa5a1d68a2cc1f91f00580d7453a23ae70af4cb1f1657aa82c5b305374effe5d67d559e46a6cee6360503d21070506f1af30bb000d2f2f85caa6465810f89968f33abae81cb3 01eef463771f9c6285f3257691dea0844687606d4dd00b6020517f190891cc1be97cfad21d147ed8881b5a6e19b22ceeae30e1132476325f2de0e9af2e14c80b8c780a9d2d6c96de 85b29e8ebf1b200420c9537360be8948b0cde511c25e1e3de95402dcc40a1725e21bb8c58c705c047d95b050fe06d14d1144b6fefb333d85be8a3ec365bdd6a0b35b835bf21b80e36e562a5b7ed537758541f965b37ad57012223eba0618dccd +726782eb0d9720daa64e4a77b5d8dd67a1a193f15eb6b5162e3d89c925ba63b7c7e1c4bfc8d6f11915b0e14d16ab53ab015317bd5958b0beb6074199e05181915496575768d026c23e92e06016598de008c3718aaabcda8b68bebca0a73ecfc7327e8d3646106b7d114dabc46cfe56265c326ee56fd2ca87abb5bed8f997c735 013bd452b0880b101df1aa65724fb60d5d85b37ed5419027481661a3617e0fb37bda1151b9b5b41f908ba832011f7850b75a07b678e5b8cb35c5fc8b94a625e4398cd5ada2b04cc9 b256e6e213d23b940238ebee6f4d686923c27a4a532062e54de0f98c58876778edec030e2b3eed88f07585edbe084af10e055cab72926f3701f9f34b10868f4f0de825a9af6f80fa60d02c96e8d002661e4653a5176422f9df8489fe22db7dd4 +1c2418243fcd89c6382b7c3b2a8c341f26d08174a9e9296c4a5c98c5793a0fa48dce51e30811a96b515aa22bf9af89a43de06d696be1e531c5dece1f69fa6ecb7f20be063c602a16454ddafb14385ae3f8246c3f989d0566e06e7ed1864502896ea19df8393259c4dab3b3380a4a80b4103cbef4f38cb69198b7cf74ce94883b 01288141ec2244e4bb3f62daf4ee588aed09ce22be55e3d42e9085a947c1f8cd16533635d170bd64ae0b417346fa4670c25d41387acb2a8e14407a1931d9f7c5358a14eca40974bb 84cd4d69c1ee86397c582ea79675db6318cf45ba4ca50faf6f1f642638e072b8a89467c02a2466ec087e250a4907467114abb9bfbff30380b0ec532333e68d3e4daec2b06ead24df65e5e4f460b832628b8c5f36148547953dbc11692693b851 +1de4b642ec7220c64b91561caed7832044d6e811ac909f3b199cceb0d8a7db91bcdc801412044f5c34b355b95a2c6170fe497f6d5259bc20715a38cb0341c88e93029137e94d895bab464bca6568b852340a5c5d6a225475f6eefe2fc71ffa42f857d9bab768ccaf4793c80c4751a5583269ddcfccf8283c46a1b34d84463e61 001fe06b94a27d551d409b0eb9db0b163fadcf0486e2a6074bafe167f9a3b4ce8ac11f42cf72f9a1833a126b9473163d29bca2ad139dd1a5e7fedf54798bf56507326fae73a3e9a2 b7c22c26f4aac6f9ddc5f89e98872b7e1ffaba93037d4dc3e9c5e141de20774a468a7ec1998da89f9766d4a64d24f8ba1606c15996ce012952e6746c413a45f9b3c84a09462133c032b1af1d3610bbb08440b772986da7ec7514b03276502e4c +70279be7d7ac72a32606642ecd81b5d4d0f95fbc3c0b07d85c16adf2788601e44dedb8e55e0f9e0b4ca3ca35f5be7511b0e69224a05204af67aae11ce154af6d594d47f6e3142ad183969544aa95cae1edf42bc699137f60178c12b10a67698e37ab9f3edbfb3acdf1b3513d62fe3db33b16cbb4e1f9dfe732c107f9d0c953f6 009cdc7e4945c485a41728f83d5188f539e372ff4fe38fffcaacbcb4522428e4f93ef4972556f4398fe17bdd885768f0fb5590df495badc794d4d274e22f2f4a2535555922fa43f9 98a1855018845ca8ec01eae406093f4fe902528635539406860fe664167c96da761d88983cde04687293065258410cd804d5a0be95456cc13bdd673471e0a08369ed32d6f7e8ee38b727f3667e8b91944a2ab34a2efb2242930d7a51b5b92add +4d7e0ad520445b6a5cb46b7c77fbd367614044ae6004494c2b3a89089287e2836c73b799cd8c90139eac427ebe335804c3788f3728ffb8edd7f49a4bcc76a9e24ce3c2299cea88c04645b82033115380f81b0c1d823e470631008d350cf0c0dba1915519985b8a389ccd8c809dbd5bb5051a79e631916e0d052d9b6cca18e0ef 002bc753d007c4491cfb8ce0a6c96455acd16d37e02c982db216b8cc1afd6d10c6be4e15a3988b8b8b86b2b5b59a5c1939889024849317f27ee08a06bd8e7524d4ad83a1de208564 80c59b70eea0c3ffa2d549b38b0d2757e1f36c89c59d918cb28ad92cc6fe327e198c39fbb3e7b94c7c41e7cbad89cb59169e5246cadfc77414373131b19d3ab905149666df19d359438d9dffba85806b917e0d350afaeefd2ca8bd7ea156873c +d49903f38b5c9b17542310425e59377f61f5b4f4740cd97371ee2116083f7758e69e7e2c1b0950ec6b76f96e3c91c721d6f2843afde8c7505a559c8a64bca2e665aa1131b75bdf86fb5b90581c7d3b61c2cff88f3fccf356ddf5ed282e27727be061b6925c51ea7f1a495f471dc8a5ca1a88bbe29e92338d3c9361460398965a 002082c6e61d0d72f040905d8c1c20d47b029f41ec68d6cbf43ce97c3b2a0a770557a33cb803c432cfbd3958fda30ec1bba77a6613c318597a85ad02b26c44bb77ca96d9cc1194ea 957eb9b0422740836b60f2a1e488baa521a3a441ac3553beb865cb6d11d50497ae87f116de67e93929162de624038cdf02dec5652233c6dc12fdd34414e484fea594ab297d74f60dcac3b087a8d1c0bc9ae65c20fd2d8c606806353ca2d59465 +0e3f4afc3e7b25c1bf2d98098a5a87db1224d9bb45adc6e434732b8722a708ab80a1f3f6ef3c5aa70d2e1dad3e4416b12cc59171f05736c4b58bd084602c344f2f0bf3cfdcfe04c64e87597a99de23ded64b33607f7c273ec321f6462518715b11e91361e89ce5415bfc2ef520bfec378244a3bd2a4b9b6b3d68815f2f75baf6 00e298c93351323e2c5304015a4878997ae4e79d1c32f1dc64262e534d4f2c4b3e222356ffce746763373fdfb936fd330d3214a18c07f1205b20c9a941331cd676040ba1fe3dbce7 a784a6690bff41388ae0b30ff9d073d86a375f941758d3a8af4f5f7aab969f72979ee32e56bb19fc9a82a53c0c192a010a305ee85c213324c1b4a50426752edfb14703ada5d3556c1806b3f60868ccac02d771b25522e2ac4f4926b0ae79f5e0 +8fe32671f6927272fd3cd8dd4e34d44d27fac8c88b41bf9a48039e914990bf06d1633b38b9200ce1c2a275b9c55498e5da2d0707322c3ea0a0fd7aff598fb801628264e13047c8008153e8595a0dc95d54e70b882ac2ac9314d2b78e7b93922da818d7075215e354708994af66958954c92c074d132dbb2488e5a531c755a8e2 0104f4ad56594c5cec2a988c5596d73adaa5a81802b40110dbae698ddb1f0b271fd1479c38abcdb9b234e69cd0da8a0328d2135c287d5b130a09fa0b899058e7800eb2dfcee95c1a a475c4ff1489ff0ced4429b4549b07b63ac07170ae69e6222500d5133359d539cfb58c75a26ea83d4281b79c7c0dd92c142a96e314fddf81c6cd48238385b1d0e28b86c842b57cf66c4a3262ed813612c03c255c17f40b45a0fdc8ae5764ba2d +a8fa01136a0a78313a5d160c32fe5d1805eeb3730c18ca0c47818e82c48eb4c9e5b2dfe3ee5facef9ec59b68f4e6f3213f77fba9f8ba06dcde546ae348d343233883894f4423331b536f62373a495852977a51cb192cfbec04b5582b4ece69f345979e234de32da7a120138a057a7119735c4cb19099bf48bb202e7ffac04def 00c4989bf33b3136bcb4ba67906eaff2bcbc6567635aa4b057acb7353ee87ba3cb4cb9838f8f679729d5c6ed98e6c4199cf58605f009c6873a1b8321f83cd3c0973b7a3cfd9dbaa5 a48339ce76c6640af3a27bffbd5dc51db375bbaf30bab5b62ee2b4ddd20d30e4171db7a47f47f1227f4df268708ef80018134415e5675e1a93e1bd29e5977461e359efa56421b68bc3130ec143d6130b53526b7731901ec96fe5510a0c8f60a0 +ba2d83b21c783d6ef2f3b7b10e910a418a9b9f49ae0fd37990335b3a3d15627846c9a12a1f31a3d0e062ad1bec5650606ed4dd06c30e50c1e8761a29f4ea1a20f74635d5dac22e5b787ac10f4ee82b338a641484f91771c128c84d31cdab0a6b9616078c898665655ee9dd4ae73d33b94bf091b064928b959623aa71ff73b4db 01a96f2ad56e31397e236cafc108087479c9823589a5fbc3dc7488d0e5d1199cf245d7f21f524cc0e8b47feca14c93fb760e631434a91188b32965053942f3bd39b3714f9d6f1a11 93c4fd4464c8a6326a5ad6b5c0be5309c85a3d3c89c10513932c52e90431bc8aee94d8dcde8b9c7c6c263cb716a7eed6103c3f8df0bdf8f865ba84039baad08bd65848eeebe7f67ee533a20700661908e7a5ceea789713c099f201b260a4ea2e +ea2d5f4e9797bfc2f33f0fccaf530db2bdf8abcec00f09a0338eefdba318221ec0e050cad1a85c3f76b784c6e8c18da2b062f333eeff18b7b781e67d6d0a4368b8231a892e0f4103012348e5df53ac745e4d34e2cd1ee9369f97d4801ff485fc144b2007008036bbc07cb1c302a00054b54f3713919191e1d5052978c9c2895e 00c08ed8e0e0f8b0d0714b46a2164b933f8147692f18da97e5a108c44d5a5cf221cb50536e41832b83bff4026c6df156386235cf5e3e9a67b7cf9b2fa7707c5e0ff33a91601b8e34 b05997aaad98a308056dc45093edce6efad6ac12c562fa9773d539470315dccbf4a949ba0b9d2bcfd11a7aeb9d2e85500a7e258182acd5f6a406c8b67c529b0f5b9ef6634a59c3a58960f72715a5b108a6e5c9273cb145e6c930932b50044f54 +b2293b0a09f41decd9d8e637b1b08c2efe612f33c9c0beebb6e05033c6103b958f8aacd125d7c810b4c287349f5f922d2c6ed554be597fb8b3ba0e5a8c385ed8ae70d5ae19685298f20e8d844fb5ad98db12ba7e5f45baed9045c3e86b3cac9bd55b614b82fd075954fc59bfc6124cbd68edae988596575f379d8921b594c75d 0144090a0ee38cfa21fabcc24d35139a99656911ad4f6dbffb77dbe74e7993edfa9fd63d2c4f6bbdbc8ec21ba13c9f4a3576b5d6e3abeab5af5ac81b1f2bb6d4c42dde645d854d9c 8c45d408f241d604dc73245140bd72cd9b0be8ba92ee8d478e2324f045a8d2ff13b3e44b45327ba6b4d841456fb3d2eb0cabc819d4eb88c1633f96ed0144c12645d33ebe240362c3de363c65370a3f43a8ee01e07c3daed847561d748f22ab3b +acce54270252e7d9e983c08c993cd6b7e3caf482a9149036afe4665bd3d0662a6818047187872862d5718b8ac063477f693caf1a9baa8bdf2f36d411a796f2b46ab56f66bc94924229f8264016d6769c85d9bbb7d6bb042fefdb8fde1be026b86af2017aacfe38c97309b4689b23fff94f1de880064f1d3ad9d74dc804c41f41 01df26b672b2e3617b6b6c631d3c6be0cb49c0a690de49643e0f416215bcdaefc03fa9c708471f1d87476d58c8f147517ec8a14aa945ef001fa01984d5c3d81f7083ea500558fef4 b926904eebd9a785360cc335965b7028218fa13dd734d607b5719e0d7e57974aed6d2065a83bdf6814fa276fdcbf161408d5dd17bedba47da63d8205ca2ebcfa68f8e7f717120e41dde773704d471ff7101c36581300b3e150854a04a9dd9601 +e25274ded4840df0d71d3369007118f002b83e2d375c78f7e29ade067db15cce21842611f3f015db2efec57da77cb9d16eb1e00a8c1444d48dfda569e29fca1ebf40a22fc646a9fd44460f0e473bde487634bfbdac2c312f66a1c2982c6fe76c54ac72b6c8cc9345e47cb319a974b3cc4bb40634df74b4ad7e18adfa9a71ddd5 0189918b832e9fa30161fdd927bfc267f6405335df3d66d225e17173af52a671138883bcb94c4403ca3e001fcf09ef4c6488934d6775af2b1da30a8f331579af2d0fbb530298d8f9 9922d253e433597b64c2d01f5b459a3d4d4805b5e088855b1b30e0045b162a88e6a1abd317b5ddc928be5b6841d8f29e0195074386c021571c502bdab3025d18277e96f9120c3c1eb1163044ebecdc7fb83ad70d99a2fd543c826a1305de47d2 +d8a4aed87c316012482819b03a1d91691f2ad11a2f46082497ea8f64880d686891f7da550b2ac17199c657d4eb9d04d5cb8eaa180f743b87d23b1c86103f9e9bb60f4e19f0ff9d160f180aed7735130c03adb62502e69be5c624ed7bda2301f30580ae0921b02e103a638f5623c02c186e3bfe6ff134c762a2bcac1f879a9353 00bdcc175eca3a399b944eb0334ff33c4fd130999c8ac0e7b52ac5b774fbad53ccc3a31024f5262b2eecfeb2104b14bb244307effe3dbe8ed25686dbf46a42c4b6f8e34010ad826a 93d30334684bc3983a22adde1e4b64f807ef6ead2d7143d5e0dccca093b76d5fbd2d4e5978de9f5fd15fe3a3c5d57751118f1fbdcb5a5216d07e5d73d8aec0cf282e94aac0319b69eabf2018b2c29f427fee765d919b16c9ab995b7629cec1f2 +acbaa5ffc4eee0850075c0e502a70cc7a897a919f5e7bca4e798385601a26f411fdae5466ba9f6b6d8d7f819a749b799fbf4a3bda9105063e74914e8583ed8b31ea4d22164bee6f14bf53afca269b901c80cb3265be32ffd4ca4bc4ddb83e11eff82ead6d75dc4aec8e5c67f35d58a8a156cd1c0351abdccc0c5396c8fbe6920 0007ab5a55a1d8ecb7f5dca2afdf9ef465569a4b0374716f604ad42a6e0271e934b09655e8e2529784b69b2894bb399b02aeeae30e9e7ae70a2a8e56b9e775bd978a04c728e3951e 855ea25704a67676abccfb85326c36d3069e1757f2036c7b4291a491cffa22a3f8e3fff1cf03a330ea46408d7b3f7efb149cac8677a7dd6f8ae0291b565ca51e72c68ff3305391c9099834caae198bc5e2e98713229a2ad6eb6236dcda598a08 +9a57b63a4f418404e8f5dcf3052b9bc04a4f6d2c33bde8651506d9cbc5542ffb9023292dea463111fb78913ccdcd182faabbff9164219b8900c7f9fb394f7d9678f77b18f8d58526ec64d7c1328953b983a7c416583e05a069cd76aefe26e5f5687b70abfbf9f58f052dc0863b4fc3bef805cc3bb05bf76a83235af9d6adfe66 01e7d4da72b1d82e17a066fe387f2a0a7fa4c60ab993ee09710531789186077f2f32b42ddda497d5fb57356383e1f96973df043307f0b6519430c3f0d40d62954032872fceb7dce9 afebf22336405a29c1fe120d98a021bc410ed0c93e9a24751803a89bc800e6e4a7828834fad9409090f5d7ef71d395e918ebd7c44b19baca1923fc211cde085d53fc76ca9e33589c529fea5b9c29a38223a27c750517b784bfc78b26907b7b08 +97b79c76d9c637f51294369e0bb52c4189f2fd3bd0607f91834aa71b3555605a89ff68e84fb5bda603f502f620e14e8b0c7affefafa2f0b303009ee99653ae4550a05315e551dd12a4d8328279b8150d030b03c5650ed4f8d3ba7c3a5361f472f436b200b321e7863c771e20ddd7bdf739c51de3676f953a5501e4477aed1bd8 015b7271d4319db5743119c8103a7d4c6d57e9c62f3eb93762156d2ebd159980aa57cea948e416717d715a2e458851f1b2e9ad4172bbcc53861db29c3ee0ba8e82617a5866170847 a734c4e96517ffb2abb56318b3c55b2916d7f2e203a58d833a49e0a375a0fe32adede9444315fa4804086cde3ef730490c65c2e072ee60864ed06b898e2d0b1e1d08e828cc1398079e46c3763a3433066ca33a4f48798783a2f3d91d1ebdc4c9 +564ad0e37c9c37a60872a4780a723d08d1159ddc77bd834d74c1025cdf3cbd5338c3fc07a904fcad9b979b2a2ceb1a0139af35e5112305fd662a57af6312624b9bdd3a64849f95f59a46ca8feb2ed56f87f258518947474c1729275c4d89b7dd286ed65f286cbac76002cc63b92a73ab6bd13c4adef282f32297e441bdd8fd36 007219ea7917d174a5386df985d0dca798ac9f8e215ab2f0003aee929a2dbd91e37fedead0ed95b1e8aabcf516bdf54337b4aff7ace4c6b3179f2e919a49db50a41c9d4d58d4f636 aa8ecce1fb3919a0fee942c73ceb34b350689a60e9dff29fc399d5bca6b8e65d931b2088c7a27d8d01f84efb035387560b5f3c52d30e6ceb96695f86346ab4ae06b2cdef101f464c1a8b645a8bfc8606faa6c384fad765c06c4ff44b47990b71 +072ed5b14754fddaf54e20da42432df49bef38f4a3b1841b2db457ff86c44880727aca945770adb41269df41fc17f6a687bcaffaa45a3e59070526ed53b8dc3b78cf9a80a85461eaf4b477e44d5ec4c2bab9c05aa747a5a520b35fd09e8b44539d060ba1c3470267e0dda111b15dbb587614a46e1e477127f963a16cf3a43ee5 00bc623152253da24bf8d752bd78aedf7d5f6a2f889453ccdec14e10753335ea8bea83fd181a1f3680ed50f2324fbeaadae160cc85831750e021f3e44121ea1b1efc29a7d0069479 8d3f45e92ff975555072fe75c16db216c10ef12e5201410d6e930afe66f6f81decf2d578be23ba7b41fbb61ab1d7c65711307201a02e31f748f8bbcdf484dbb3aca0eef0f01de2389d9e7016040c10e6c26bdb1558734efa7aaa25af5b62de51 +e660dbdf3e61af39b83b95d3f1970f66d616f03273f7dddb98f768452b21cd39604a31cf80590d4a5e4b0d4917519e10fd325dd4ab7a52d70d154506329baefe0d5816f514ae109483122b4fa8fa1ebd7fdf1fc4e21e8d278a50c05d81c8f489596633d949c6c8fea96fe91430c01522a5afbd5042be8aa47da04581b2bd21cc 00645947d981d258f2954558c31022a3b6ba5fa7b675312f794cb61bfff1d9ce87267e4a1dacb7c8fc58624d31c85ebe22f80d26a620fed5df5bf38515e0903f0b69a606048197d8 920cedd4c9ad4a058b2af01602db3ec0c30657e8418c7070635b7396fe675ef1c3d5956a189703adb4c37a80413a8350001383f7b4bead06ca23095023c4326ab21341ad096f625a8f49307d686d3652e55dd3b0ec5c343d36643fa3c14c6cc9 +8c9acbdc431565feae60e08bc7da113e12372ed373f1e1fdd581f98c8a7b0c79ac4aa42c7ffbc963fb4970fe26c5b5dd314b7051fe971c1186ebcb5650f7f7011a924de893f06961b8c75da7bff331847feead4abd2e8b9d6ecbedac18f4eac207b948e6e4215e4d5cb483e5c66ce7ad788cb89604d3a3e051539094079e7bdb 014cf93ca69d94ee8fbea0c8da9d76aea092b73073d8f5385b65c6dd4d567fe86bc2cfb8e8be890c3c6cd9abf7dc3a17eaecee3d7a9455887863e496c48dc3e47821bd3d825b6bed 82ca07c15ef6218918c67eb95b4c156146009ba88d771763c4eda447cccc013a792d18df1e9e7333732dddedc7075c671791195d5fa62ce4d5cbdd95a584884fb84cb51fe4b34a6c7986fb6fb8ca03ba549b7376e54349ef1f53f4ac938a7233 +53ef87d6ac7b9698f40b3ea9f3442e7b64207b140b7f66f73fb7d5f8f98452d30a4e493b6c0e3268371e88e612b818d4d847f032ed4983817d020411a52d81fd2a17b58ebdec199d817c2a8ba77042bbd747a6fd4bcc7e844ea829fd8461b389aa0b5957d92962b6d4e86385a8fbca90b8fac40944607117e9a4ef6dccb8fc1e 0033feeaaaa28f16bfaf5ea9c7319cf4561ba4fc55327a8477b6cd58ef6ccad3962ee1f3edb243f3a04e7e49c8e23509fa2d63252adb186b8bc7e9255cd61fa9bc45242d42da3a68 b0565f13cce1f2ca85308759f69014534caa12c238817583bd516a2f150e3b8a022c483fc87cf58508c83016f9d33dbc13d4812e4710e8404e238c8391b0b7decb159d34948902f0b117401ad42317b9314a899cfcccd943df74861c80019fa6 +dca1b7a9a313ead11c2d54739d9017ae27f9d08b3544e418aee862bb57e427636cb6aedda28e10f12aa15d2355f4f8ef112a86fec5dc46e6acef693cb8fc37c3e4885f3be3d3ab31ea4d73a0de904e95c7135a149f77b621d642f9bd8ba192d39cfc58b6f19a797c4f3b4f3a87054298e3ce5eda0ff7f44f8134c9a108285dfa 005613dfb53149bf5fdc4e08ccc1c752b0b66ab43aef2d008ed40f3df40fcbb2938d2c41e3ea2dd4428aeba9059a97efe5593119673866a19d27a2ee37dd357e22b6bc849e7e22cc 8df688dbab9b3bfb6cee733cda207f310705a761efb358447cc729f8f44dd9bb9e670649500b8b41b21ab4e3552936b602c74a85e34f0f427ae23c34f2d6d85d2c22f3a31edc5c11ee93199e577584e27886202fbf4e10d27f39cbe53d26527b +aff61d62c8f5c31bbb7d0a64a6ac589e918bbf2f13e7ad13abb9ac26405e267249a7c9922139bc28140833e10976b87e91cf28285274b2b48b63d24ac94c85c70fafa78f8ad05955c0ce6c02b841ee196dab12306e3e3d6138371217e2b474f7e67a80bbb78a47e374ffe2c9f86292e471c551da50d46e7b5c8331029f369767 011b92c8b72b86c51903387a65aa206988d443d1988253329ad3a89c902ff1ef8cf73b7f2e4aaa352443bcb833712d94c3e637ec12cbe4c2d4606878576b17fae1512fc77785b737 a24569910aedc9e70d9406d0001b8416ff5ae47b58ef2a6e3a154a7c704078e56fffe63784110f3d1628cc1998d9a50507067a3220df8bcba1f750026f9e60a778ff5d57a61c579575540b121c2f0deb42a3cb0aa21b31eddb9f533b0ccb1c85 +721017294f17ef351e41256b57a64a79f3636628c4bcbe676ac9a2d96076b913dc4b246c9945183ec9bd2d251441b5101eac44e2fa1bef59dec03ccd7fa5accf3b7d094d68dcf78c8de4e2f19f56bf0dcb3b66b9421ec3f8b353b9fd74feb2e9affe0bf9aa421b6f03eeba3ffd58fba56b3ebd094880e50de01ee62a108a24cf 00c3c90d5ce4375a08b85575faa78ee6bbd9e5571ce5a90582042617b807339c282cdc3b003d82006264b1c08c20af4ad4549fbde53d262facb98d923d81b8eb6093374b6a1e84cb 84814a9df3c187cdc6b6fceab74f2b073cd9001eb7649be27702a26c3e97e148c350f06fc370a98d51d79edd215175da052314c07fe3d0fca2490c28851dd5352175d5788a1a05dd136e085111c92cdbf1fe36dfc5de4bc212b789472cab05df +e2d1f33681759adb7954bb5248b0db3c3885fea0d4c1c0c226eb1e6d2d3ef1b9ac281a0f1c2fe5175b67114b6a501e2426d1454bd5790dcbc4c232cf06b017de8a9bb39e6033f1edb5003e8de3b44cc3d6150c3c952afb442952483cc688908337b7c1a8b5c9da70937ccfa98b2b0098c530ff848010b8e8ee0a8d65283481a8 010f184c16228d9034271332178ed485d10b6aa76003efc160d63fea26fbbdf5552205ac7df0d8c852a1210cf0ba512f20b798827b36ad56b12a826fa7dc1db45aed264ca6822659 98eb2bcdf496100e73e402e1ff6f9506c56eb4855cb7b8e1182503298ae0a1dc6b02395cb4a22e045ebf5994eee6016d16c2cf6e107e026a180149a9419dfb90af2c0e84185bcae3db01e51a0bc0d0685f9ebb5d5a0d05af9e0bba42b4e7e04a +414fc5d2bd56b30040e105cb891788792da595583b11b8fcc7320f40dbf64d9263532dc57344dd17573c95eedf851668b5d552e8796af205f3a0043af1a829fabc2e93d9af9091fdd9e0fcbcc9d6d9ec960aa60e4e2964c29a2f375400366480e513f63d124db7745847310e69a38c8455e4e602056a6a4a14a8694155e0a9bf 0181baf9d497159f837cba58a11ca435c442e5ca792ea559bff9f6a1f562c05bf6bb5914afbd1bcaea75b35f88bdd832314b249a5298622c89462344d3f28a44ba3d059df432fc71 98e8f10f17edd2bad61826cedd7d46bc3bc0967fe4c7862486f21a0aa23eb493963175fb0f7762bd2137220edb6236a2069a3ac2aebdd62f4fe2d4171067f0fc84ac6cdafb27f19a22320c897630a5e30361f3b4127c41fbc59c7af03d695862 +3b592cc8972a4782870e079b82a50f84b4c2d8ca90bd500d1ce5678982e266c391c556d8162ac3aab967154d072dbc0ba1dab5545cf2651753dee2881eca5abd412fe624bf3f9d17d33692d21ce23ad15ccffdfd250cb1949e73c9e40a64ebebb03852e92692dad1d7baef97fe109f35b7a492b343d4b643a4a7b1723eaecb64 0083fae86ab96bce99a53e50b7eecff38e4e25b21c4b0f6a4986915de245eae24f16b6a00a4db159ebc27f5a6a072da94ab6be5bf75f5eb3f75c4452bf4ea7014392eb1e02706fb4 aa2102f8aa13d5331c1989d0a4841b533a4059423f6649817d5a3b30616b923986901ab0dd450283f5e8b6a4a5bea6f001dfac1c20ea3ff3e8d277316108d58a46a7006f111d43b4e41549deef605fb85ff5e0986aeeafd08133566016ab5d42 +0079a02cbab3dc02601fcb5c8607d555beef7cd71a66911ab6514a4ae21c5a9c0e166f8cf5fb198ec5a49a96e17cf041f35f00406b79270ebfe56dc6b8417d2529fd625686ffbc8f69685aefa2fd30a937c02f25b48be4679e6fde821de928b33b12470867def874bb8c7c8038ab6594346a2c44b39210d3610994ba60a05e06 01a663efa7bf4d8479bc535fad71e9b5e4f4281aec55967baa008ba17ac2f89cc3398d30573edef29d590fddce8cb157f655e92779f59e7a18d0327d02e7daf4c1216143b3688fed 99266e344de01cad40b2767e342ef570b2996783294a48575ac66ed9a15dc4b9b481f66233f7032dbc11380940f5a6c50443fd45a172252f5b6dd2fda248fe26e93a1bb731cc3f371ccbb7dfa87682830278238f279ab8c8b65ccd7e728cf5ff +88573bd94ef50459814806efa868ebf92b066fbc2f7a4be9d2fa06b9dc1a72f72d783a6bcbc107b18a6314511bff217037a2252e7a5cd34cf9d5b2fe9c7846931f0133b2e95876cb800dc4ed7c4a4e4cc4f1195acf99fb0ec224b1f8fa8af71f72d390eca9d6be3879032a318734a63fec336c79035a43f70271def10c4955d3 00088d1a2c0219696a94337cd56516252b74139ea0733b17fdcbf7692c3e5f6c3989e5da2aaed7468e65a5d578571928ca273ec3b6aa72cd196f560f05095cdc8346e5d31c4c2e0c a183cc7ef14e793abaace1938683f2bf8cba5cf0bcf0c457d3f5f5c7a7da721135df64c57019aca4e7a5b656284924e413c56665102f738c6c165d2fb7dd4804e65722008739300e3833595d35a0bec9e6b3ddc12f52e7e1499b04fa36c88fe3 +d0e02045ece6e338cc8ab41d4a064c982ccb1748c48fc2fe0a6f10bdc876094358a6a90a45facec798a83cc95c6795cf0f0d7c66b77e22cb114c1432bfdaa1485ff35b6a58107cac3b7e58cb4f6c87c68db60b751e78f1fdfa54b8923b98caad0a4f31226956d065c083ace5f1e9e91944dcca51879d782e40358d58ca758750 016cc8a0fd59455ed8d4de561fd518df2e008f7dfaa5f7f29ac2489a411e233917b43eb3ebe2596fc824be58871949545e667dbcf240dfb5e0c615ade0179d9ea2a1b1ebb8ab9384 a8ae20ebd1b9a468b76cd0a5d32c5df24bf819d30847274a67e93f236fd98b3a62a4090c7b1096273e29e7e3ec639f7f17b7a19232579f17a4ae6eff4b1b825e9aaafa478f12962e6efa42b24d947105e1f074f4d1938286a030ac33a3ac71c6 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P224 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P224 new file mode 100644 index 000000000000..a7d96c09f1f5 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P224 @@ -0,0 +1,60 @@ +699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615 992cd443e4be26f1c2d6fa1256dc9cfde9e49e1a9f800703a4bc85ccc83ac670f15512405e4c7d8ad452539edb54729815661cf72f543dcc8392d5833a8016d7e8616750fe2f3d81380be8a7dfb41291d39f957baa198f9c4a5581eef50e20b8 +7de42b44db0aa8bfdcdac9add227e8f0cc7ad1d94693beb5e1d325e5f3f85b3bd033fc25e9469a89733a65d1fa641f7e67d668e7c71d736233c4cba20eb83c368c506affe77946b5e2ec693798aecd7ff943cd8fab90affddf5ad5b8d1af332e6c5fe4a2df16837700b2781e08821d4fbdd8373517f5b19f9e63b89cfeeeef6f cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5 ad4518b516a290b514bc1c831c18abef33b12147e8484c67e38124653691ec13665fb7310c9a1158adb19f2cd96b39990f362c3f616339dedcd476f48799e47c4561676a571953db2f777623244f5c8884df06d4e045aa3c8547e41203b79287 +af0da3adab82784909e2b3dadcecba21eced3c60d7572023dea171044d9a10e8ba67d31b04904541b87fff32a10ccc6580869055fec6216a00320a28899859a6b61faba58a0bc10c2ba07ea16f214c3ddcc9fc5622ad1253b63fe7e95227ae3c9caa9962cffc8b1c4e8260036469d25ab0c8e3643a820b8b3a4d8d43e4b728f9 dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73 8ec6cd4495f88f55f7791e512bb98b067098c6d0c28099a85a19549b8364ebeb6d8c6188ea7cceef3a22ed692e5aad4c10625a5c7c21f9390ee91976dc3099ea6e5ee69ca02ab21f2572fd23c528fa3d08d1c4db4b3bd1a758bb45638c6abe6b +cfa56ae89727df6b7266f69d6636bf738f9e4f15f49c42a0123edac4b3743f32ea52389f919ceb90575c4184897773b2f2fc5b3fcb354880f15c93383215d3c2551fcc1b4180a1ac0f69c969bbc306acd115ce3976eff518540f43ad4076dbb5fbad9ce9b3234f1148b8f5e059192ff480fc4bcbd00d25f4d9f5ed4ba5693b6c aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e b4fb0af113f8cfd18c7cc92d36a5db3fe379a4f3f861e0de4ed98ea41c674c9a0250dfb2960424a92a8255394df680b50b83e2860bb6440fde82fab77b7e152cbffe0f07eed90d7b78894201b6b53a8b794dd52cdfa79dd63a82b9947c56092f +c223c8009018321b987a615c3414d2bb15954933569ca989de32d6bf11107bc47a330ab6d88d9b50d106cf5777d1b736b14bc48deda1bc573a9a7dd42cd061860645306dce7a5ba8c60f135a6a21999421ce8c4670fe7287a7e9ea3aa1e0fa82721f33e6e823957fe86e2283c89ef92b13cd0333c4bb70865ae1919bf538ea34 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4 b0209ac0e5cee891c65a0b0d0e3e920b78573a5dc01f0dcf3cdba01ba9537f0895b8c8be7cb8b9c875876123894f74b80499d96c6b1da7903c7072c3c5f2d56b26bf910643c10bda975e0a8f0d745c2885fe78ee08b6b3d2a82751b4a9e4d0d4 +1c27273d95182c74c100d85b5c08f4b26874c2abc87f127f304aedbf52ef6540eba16dd664ae1e9e30ea1e66ff9cc9ab5a80b5bcbd19dde88a29ff10b50a6abd73388e8071306c68d0c9f6caa26b7e68de29312be959b9f4a5481f5a2ad2070a396ed3de21096541cf58c4a13308e08867565bf2df9d649357a83cdcf18d2cd9 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131 a5dc6baf0545a1332f3b79df3b830c5d41a83ed80a5c19ea7b445365b8766ab61c8a4d722151e8e636ebdde61db2242914efea6ca73500147b52d4ae67854c85f15da5ba9af6eabd71a2b1cd5684e82c807deeeb155f4e734ed48fdb4625be4f +069ae374971627f6b8503f3aa63ab52bcf4f3fcae65b98cdbbf917a5b08a10dc760056714db279806a8d43485320e6fee0f1e0562e077ee270ace8d3c478d79bcdff9cf8b92fdea68421d4a276f8e62ae379387ae06b60af9eb3c40bd7a768aeffccdc8a08bc78ca2eca18061058043a0e441209c5c594842838a4d9d778a053 d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974 829b2fa49af46fdb3339f6c4f0ec695b1baa17e5b9ad04a716eaea18b09648d855542b6dd69b7fbe795ed5594c19813916adf6ac4a6b8cfc46bfc5e98b72e7d15e4954c51c64e1c283022d1e1a1f1df31c13ea5aa222e0dd36ac7f29d632fb77 +d0d5ae3e33600aa21c1606caec449eee678c87cb593594be1fbb048cc7cfd076e5cc7132ebe290c4c014e7a517a0d5972759acfa1438d9d2e5d236d19ac92136f6252b7e5bea7588dcba6522b6b18128f003ecab5cb4908832fb5a375cf820f8f0e9ee870653a73dc2282f2d45622a2f0e85cba05c567baf1b9862b79a4b244e 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8 900affd9bdcfe7839533a22905044c0fbaaac9ee666f419571285f71b1a9b38a3f3602bf0fb50ba842997d97f458a8f10a7a307814553623a6bf39edfaad6f1fade51e59bd8c758b4a3bcd8834094d739977070fe16e429bdc21c6a2914021a3 +79b7375ae7a4f2e4adad8765d14c1540cd9979db38076c157c1837c760ca6febbb18fd42152335929b735e1a08041bd38d315cd4c6b7dd2729de8752f531f07fe4ddc4f1899debc0311eef0019170b58e08895b439ddf09fbf0aeb1e2fd35c2ef7ae402308c3637733802601dd218fb14c22f57870835b10818369d57d318405 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2 a76902617c7c9db4bd7053b03801e785c4ed86894bc63519ad67b8010c850ed2c9d0af47790dfafec9f456a0f0ecf70d072d72653c9b8437da0f66a801e1d31a3ff53241db96ef40bab90ff5a500d4a8086e31cc6fdc499ad07017ecad299437 +8c7de96e6880d5b6efc19646b9d3d56490775cb3faab342e64db2e388c4bd9e94c4e69a63ccdb7e007a19711e69c06f106b71c983a6d97c4589045666c6ab5ea7b5b6d096ddf6fd35b819f1506a3c37ddd40929504f9f079c8d83820fc8493f97b2298aebe48fdb4ff472b29018fc2b1163a22bfbb1de413e8645e871291a9f6 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7 8e5f905dc1af5ddd88373d026ad6a7cbcb6c5498c202b268bea1bafefebe733993c21d99eb18af467b0cb7df12147e56134b0ddbf457ef8dfa2d710a3356de4124796aeee3496a1b6482500c0582cbebbc74a50bd1ac755c8714d62f39bbf2c0 +c89766374c5a5ccef5823e7a9b54af835ac56afbbb517bd77bfecf3fea876bd0cc9ea486e3d685cfe3fb05f25d9c67992cd7863c80a55c7a263249eb3996c4698ad7381131bf3700b7b24d7ca281a100cf2b750e7f0f933e662a08d9f9e47d779fb03754bd20931262ff381a2fe7d1dc94f4a0520de73fa72020494d3133ecf7 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b b62439e0e5dcb6ae6fdc8dff976405c44192146fa3b15d2b1ef4316493ddaee708cb4b22aa57e57ca0c64e3595e2861e111c42fcde768ca2406e2815ab6da8c1e359562313766d433d600bd470dd0f5d09616b2115e3b1e440a9cf110db286e5 +30f0e3b502eec5646929d48fd46aa73991d82079c7bd50a38b38ec0bd84167c8cf5ba39bec26999e70208af9b445046cd9d20c82b7629ca1e51bdd00daddbc35f9eb036a15ac57898642d9db09479a38cc80a2e41e380c8a766b2d623de2de798e1eabc02234b89b85d60154460c3bf12764f3fbf17fcccc82df516a2fbe4ecf c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6 8205b3701f95759a0558504a9bac87095524073a16153c972ee76d2e7d4d273e815edf43492b22c29425ca671e836bbf1195bdb20d09e074834e60916cb819bac681e81ed21162511bc7b18e540ff2efe113989bd7d2cd53a8f73de31bcac795 +6bbb4bf987c8e5069e47c1a541b48b8a3e6d14bfd9ac6dfaa7503b64ab5e1a55f63e91cf5c3e703ac27ad88756dd7fb2d73b909fc15302d0592b974d47e72e60ed339a40b34d39a49b69ea4a5d26ce86f3ca00a70f1cd416a6a5722e8f39d1f0e966981803d6f46dac34e4c7640204cd0d9f1e53fc3acf30096cd00fa80b3ae9 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc 90da4d284753eb05bd600abc1a9bb3e725e00caba092811e00237740d01b93561969e0b9ef50c293c9d28efe0870fbda145bbc0967eea10ada735eb9a4c4c132c0647ba03537b198eba7429f1dda9b37e1da27ecf03134178f3c3f57a5fc1202 +05b8f8e56214d4217323f2066f974f638f0b83689fc4ed1201848230efdc1fbca8f70359cecc921050141d3b02c2f17aa306fc2ce5fc06e7d0f4be162fcd985a0b687b4ba09b681cb52ffe890bf5bb4a104cb2e770c04df433013605eb8c72a09902f4246d6c22b8c191ef1b0bece10d5ce2744fc7345307dd1b41b6eff0ca89 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3 acded4343ddea6ce0f3560b2a3709ff6d514bee45f3898b2b19dfd3c483de7feb51f9150d861e6852bdb0adf6249e1b61564a0c924eabeb86cd4f107b72819be6baf43f8269f1cf4b66bcedfd14b153eef2fca2e0e0995a1744a181d79d5b645 +e5c979f0832242b143077bce6ef146a53bb4c53abfc033473c59f3c4095a68b7a504b609f2ab163b5f88f374f0f3bff8762278b1f1c37323b9ed448e3de33e6443796a9ecaa466aa75175375418186c352018a57ce874e44ae72401d5c0f401b5a51804724c10653fded9066e8994d36a137fdeb9364601daeef09fd174dde4a 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912 ad4a25a783381dfc091e491add421cb0a40003560a0ca43994c4ab80c8fa53eff3396e9b729562f974105820ed71dc8004ffd89285b1ec5d1383b9c052c677fcaecf6275c8b635e5855ab943d6cc51cc1b60b5aa82f2a52c1aa22291e8d6ffe2 +2b49de971bb0f705a3fb5914eb7638d72884a6c3550667dbfdf301adf26bde02f387fd426a31be6c9ff8bfe8690c8113c88576427f1466508458349fc86036afcfb66448b947707e791e71f558b2bf4e7e7507773aaf4e9af51eda95cbce0a0f752b216f8a54a045d47801ff410ee411a1b66a516f278327df2462fb5619470e 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa 85b64d397eb02f43b64d8d47b1c030c9d12475651bf20bebc7735333a810a864f6cb7cc30df4fec2c6e1063693f48f060c3698d40170b7e67ab3f64f5b92baf4221dc9dbe266cb6f7bc9f0a28f711282e3c388a46e6d8d2ebca641299fd10e8d +1fa7201d96ad4d190415f2656d1387fa886afc38e5cd18b8c60da367acf32c627d2c9ea19ef3f030e559fc2a21695cdbb65ddf6ba36a70af0d3fa292a32de31da6acc6108ab2be8bd37843338f0c37c2d62648d3d49013edeb9e179dadf78bf885f95e712fcdfcc8a172e47c09ab159f3a00ed7b930f628c3c48257e92fc7407 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972 ad3cf5fc226436455f8c931ee83e17b282da199a347de514bca39dcf31204af35b4351798ddaadd7ce9fe84bad35ee2d0728f256e996254c274991a12ad9ec175364bced74a240f27fc47e8ae93fdd8a12d93f0a9007d3c1768872f6482e8273 +74715fe10748a5b98b138f390f7ca9629c584c5d6ad268fc455c8de2e800b73fa1ea9aaee85de58baa2ce9ce68d822fc31842c6b153baef3a12bf6b4541f74af65430ae931a64c8b4950ad1c76b31aea8c229b3623390e233c112586aa5907bbe419841f54f0a7d6d19c003b91dc84bbb59b14ec477a1e9d194c137e21c75bbb f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170 a03a7a4aac051349ee4a0b41a8e3be4d37a5679dc50601955935abd4c2e95a9a7ab3159ab0cd52d55450b09c223a6b1304a92b930a335c1494175a760b3581e55ad33ff2283aaefe5ac53370e1b2c93a3d5beb658639fcb786a52b6db2a7cf74 +d10131982dd1a1d839aba383cd72855bf41061c0cb04dfa1acad3181f240341d744ca6002b52f25fb3c63f16d050c4a4ef2c0ebf5f16ce987558f4b9d4a5ad3c6b81b617de00e04ba32282d8bf223bfedbb325b741dfdc8f56fa85c65d42f05f6a1330d8cc6664ad32050dd7b9e3993f4d6c91e5e12cbd9e82196e009ad22560 c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85 8822f9372ac0c3b278408ad5a17ea7b6f01dee41e506192445503a0bd93d40919d58251e5378765d502797b467a48c7e0e9766b2887d729f1c0fa6404fc31062d43ca95d44b14614bc12acba5b4e1692a18d7da3fdc1075913518df286df5c21 +ef9dbd90ded96ad627a0a987ab90537a3e7acc1fdfa991088e9d999fd726e3ce1e1bd89a7df08d8c2bf51085254c89dc67bc21e8a1a93f33a38c18c0ce3880e958ac3e3dbe8aec49f981821c4ac6812dd29fab3a9ebe7fbd799fb50f12021b48d1d9abca8842547b3b99befa612cc8b4ca5f9412e0352e72ab1344a0ac2913db 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6 8c3f166f38d014975b62742ae696adfc1707a70380d7c1507760fd4c3989b5b209ee183348273f0f86fed68d693064121700d8de7964b4f1a5a15ef1ea0a7556105893a2cae7852cbaee4af408e866dfd05b90c179338e0061f115862de7c512 +4cc91f744ac858d3577e48813219aa3538dd813b186b42d1e6218376f07cc1cc448ddd6b37240e98bf953f49cf54d65c12878b33c0bf6eb1c60254f0b6fa974f847e53abc56773eef6f29885dfc619e6a48fc15a667ca94001a0c945b6357a53221b0f4b266181456b0d2d25e90708777f1a6f85971c00140c631c1991e0fd06 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39 816fb61f5a25dbcd9d768d129292384131ca20e6bdd1ee7136235ee23993ef920b9faa6bd2b62a122e10dedd3be0bd1702040bffa2c6a165c7c20eebb14563903d78514749ae166b7156a237fe1206c5ef696ebe2dc56d39ce7bfa7a01048e34 +58f43cc1924de4bc5867664adbc9d26b4f096a43aca47c27c52851b006dc2a658919ef9ce5b5ac48372703be15ac51631c2bd84b88f479f113b0569a9a09e230ec1e8e573474c6075284d3e57d973829af35325d9e7dab4a5f9b065155bbcaff3642a82ef4c9b9e127d3575c050721653da3b087d3fa394192897a5519527d19 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6 86958f1f2d580b1d8e9310ae07a8f2071d39071081ef84acd885c6d70ded948ae8dbfc455ee06b1a05254c14bbb1a54f0f17594a5692e638965f8420c0bf9bec26ea4a3a93db4b1ff017357955c4e109ce87328aa0a1bd08c5a3736bd1f57aeb +113a2806b052fde683ee09453098e402204155afb3776fd1cad3a9103421d327eab8f9ec0dd050ffcc83f93b34ea707705fabeccfe43ab1a71c95298fd3ec769d99ead1066950eee677d225816e0faad19cf69e1b35d16771689e2092cafe16d7c0dd7b0db73fffb8d0f3eaed83004dd21e753530ec939c89ba25578fa5f785b 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b aea8e09385f80bc6229f71a87789a6fe4d27e11e1aa509d2a905ce6b0491d3e4085fca2461a55ee06fc286c9b5c1fd95130f8b46400b838789d2aad54079a2998e96cee26642df6efbc820ff347f1571eaa5397a38a6981ced9e56a661c0e688 +64cbfc8f2e2149a31b3e8a80c4a552f6c62aaeb7990b6e0ee55500a9d17be04213406578caf315951086dff5c2af3b5ce17d425d185101ef26f86396ba3a129a4f3f8e2dd595f59efb6c0f5c2dcc394569d7268695e9ac7daa84203f1f1895f1f9e4b514a5c9cd23baa63454710144fe735ad9b8f42d8c43267aa434a26d7e5f 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b a678c1db02b53841fd49f53ae014b028b7d882228475cb2ebf9d17c686f777e025ecf6db1508f60052a61bfbb76724370a386ac4446e6d1986126363749fd29021c4c645051dd87a9acfe293f4ceb9de3cd09ec51095b66eedb1c5459654f2de +a10a11c8e30fff118d371daf824f16c08200b83ea059436466a4611ccac93b2dea2de8c1006f946196aef7fe9b0c251a391b0340f21797798278b412ff2b53842eec6450728e2bca062f8337a2c204b9ea04ff660cd4d4db559f2f11c4d8ef199021339fcc82396f7a93926cf5f247e37d8067fe50692de54f102bd5ab51925c 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8 a304069be46d53afec2051f4b4a49349f08e30d8fa5d8b04d622e5574dee8211de72936034e35bc4facb03ceca4961d3165e65fec9e5bee4577593273728c4e3c48680a06641267443964db6950a9e72fc2d99fb30f3325d37f261aa5367088f +b3f720bf566ffa369259f4361959ae0641d2755ec264a4c4349981df2b02563275b2b9adb5aee47f7a456760a971991ffed6b17809bb9694138d1677fa916123795239353158fc6b22d10f20d26f5d2dcd8c56c44373eea5b93067dba2d7c5318dac2e9e8714873cb1b37f58c011fd14fa1e535554efe05f468bfc8e11cd8b99 e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784 af137a6e3331059d24a6a2cf26d9054a3e21362965c96faad9bdbbdf66603225b15aecbdcc37bb3dab44016eab500e6600f841529eb056f44d79407d9a8689e07c1278cb8fd90235a11f8f00c8e6799779c31337c16b41330f6e3b0bfe75d80e +0a398a46df7ccc48d1e7833f8bbc67100f1ef77a62dc78bbc115b2a662f9591fbaaa91ad3d788e2fdd1b3164e45293d4f5686c151296901768028ac80ded4bf89c647ad35f0c7c4cb318c0c757c1d83c44d850e5fd4677281b3f13b1ee54de79c8c042813f9d3312dcc6111a68299cb7e829557d7f3d96e702f65aefc6499415 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c 8011ef4fc47bce5a6c97565fb4eab07aedc6b3d0a406887e2c8dd8940d2a48b6e757f4504951e93dbcb510f7da09b9250953232ef879d69da19180e16a8876e4d842206a98a06dde56c53c39cb0397e4b3dba0c750a4c5fdc13e607c811692f6 +8c33616821a6038b448d8918668977fcf1ef5aa0cf7c341837b39bbcc9bca875a3757f4b392630e9995b9bbe4eb66978b877586adaa02f99d2344dae082a7603351d8ffcfca081ab403cd0acb90d078dd1d0789c2eb3185c62bff2d9f04cd38e509e3b83c12ed0a5c6808fc42f7ba5b06acdc496c8ad9be648ee6a4505f8560f 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583 b7d4ddfbe3ae54053e1a3ff1b5ac31f379833f8e9cc67ff61bd9ae60e6954c60f62a26487bd2fd1a58ff7831d620b04d00fc3dd82247a91bc33e11f788b21a3a853289c31142837d2ee15f19ead0be392ee2a415f364301649511fd058ef8b0c +94d56535fd4edfe67a0daa6579f9d53bf6b7b8830ae2aeb62892ff59f18756ddf2811b449c7d20d65d54f8507de4e7c50eaa084830637812aa4b250a4d61ab67845be36e4a41cdc0a70f8d6e3a63d4514f0dc197e6486015046a316153d5f3a3a4a0ae1ed7ea5fa55e12e73d333333685c02e0eb636234ea7e6d4b76b4b76b5a 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2 a145f73750b06e226e71cbbb90519356bf331f00c9a68e5819a469ee0a7892074e0d4bcfc63701117cd4190331bceaf010863c7fe9dcd4b961f2ee5c52d12de73cb3da55c1829159cf52fae7f4b3084206358a5d4307a07f7fafe4a94737733f +5d8ebdf9eb28b47bdafaa36bf0b66a9eaf99b6c83959da4f2b1151b4f4ecd28fb115a64c0cb9491093a7e9b9c53ec423e4c72e7765bb9c818da0e8c428667e44474a71db4867130c77c40bfd8544b2d7b9d6464d2b8e6a48482153256a32437c3a747231f51134dd14c703407e31146a6fcde23bededcf16950486e90ca69ac0 f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc a1143c0f9661664ae6c678bc0af85c99348631162b8f3dfb3638af444ed7f22b17a27cd461ddaf97a23cf12b65afb701062c0b4c78cef8af11e890c93d980e42279f03116cc12db887dfd6b62130108aee2c7b31b610e7c7c4f0248493092be4 +25e4416695f77551fdce276355528ccf1ddc2483821c5d22d751d50111ca2fadc6593b52c74f4b5957494f1df25b0b2f86950d0d19229ec6506fee8581d2dd09d48418b146ff16bd84a17ca0dc83b1888eb407376da6c8a88fa1e60b8c2a2471dfde4b3996ef673d5bde3d70c434dc9f2488e9de16ae657d29e5e59ec922a1ec 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd 861b056d40130301b088a00cad18de836ff82bfe14cb5bf4f652fc55d2caaf87541536d7f70f83e5de498f91c4c3f1960422400347164619ebbf5bc536e7a12abb47d4375f161df160273e0ebe1bcb79a21ebd701bd4fa2d71014f3edb1e823b +9164d633a553deccf3cbd2effccf1387fa3177cd28c95d94a7d1a3e159c5e5c027758cc26493301b2f4d141d8d07a5fe5fead987ce5f30abeafcb48c302afc6c2309f0e93d9b6818cbb6972d222cb7b01302dfe202ae83b89f53150ae4a0e2b8fc0fd1091f19b4ab2e6ab213ab322d04f2c5f57113bfad3c5675227237abf773 e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3 90e1c2a9ccdacde76f2b9bc1256eb9e8b51487a0d3d6e2ebafb29458b35702fc10803375f7c3dd98d7201e229e51bb6a1565e03c4283eaf0eed271afe9cb26c1dcc0cf663ddbab4e9e40738615e59dddb1d889277bcd6c27cad2e2e64f4c1e8e +019df05929321ecea7ee1de4f412aba1c8d3c24437db04b194a68a0a59dd871be10bd3a4be6edf551350ea49fc7155a4d887e1221486291abe77a30633a4c4f7868fe2df24311cba0c73804883954460e122387ed414111ff96ff1aebac8b6a6491d8a0d16e48a63bf3d027c0f68ee4a4b234d73b412196706af8ea022b4dcef b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17 80a014381c9252f8a135ee0925d6981aa25cf66ce50333c20b07ab101b31d29de0ac018d29b18e0f6304a72d722cbe7b0430082caa5ac9750e556490fff538ecb0574609014d03b030a1943d61fc235a16ce42bc3a8cd7781675f01a2068ed57 +5d09d2b1d3fa6e12c10d8b26dc9aabc8dc02bd06e63ff33f8bb91ede4b8694592a69e4ed4cdf6820069e2b9c7803658949e877ffe23bf90bcf5ce1409c06c71d86885a94048b05ac0ec9db193e489a5a2bfa367caf6aa8ecdb032be366174343f6875d2fe1785e8d77334f5f469cec64998e08d3303e5c9a1923b34fdc105d65 efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085 93d611d440e10b94c09639bf4873eb91302a97180993298a6acb3acdce2c9a062979fb626249970c752e5ab90b942577195132c4da6dc925efa73a0e3eaa18be4d882e14ac854115fd68ec7e04be70f3053ac10b4ff1eb48cde642bf4d3d74e5 +50f6dfc81c6cf189e0a310f992907fe93356cee9dea9a41c7671a8daf3f4cfe0c459ce6122c1e731dbf7593419d7114cb73b46956158a982c5d52c72f43f0f822046093c69aeff1f7e4cd8af00ba655c5baa2e7b6a400b4be1f6fd51b3e4cfb35a69c80a28c5cafb771b6c2e52e0aeef0e3fd045e8d40745f3f8b74fd969f816 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd 94c8a97159c239115294e99072ae9e244a0d762a5d6fa18ee4c48baaf7e8361221d30efe7a028ce0209edeea6aeb61250ae58dd26aecf08efe298b2b02218f8ee66a1576ef41c5b1e292ecbc2cfb6f4e71c7734ff8580c18d4133ea55426b502 +e90129ac6672c85bb7b6b18e9dc199c96c81fd65034b53c77818364d512366fb9cd1bc7c82404c451e561fc1ed916c0948f6ac561b33a1ccca093f07684b8c2bafa9e966377bd208556018a5bafb9edcecf70498c7140fe9c8cf3ad8b8c3b0aa489df797944465047465415bb0e24333235fcdd59a98829a3941eaaf62033e82 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d 8051d9797cdf7c01180cfe294111f5def0cb0937281cb543c76ce9686cf401fbbac9beef3006f436f9de9b543dd017e11713143eb453d9cf7b8b9b5a71e1026a64dd2a3265af2d8b174ead2802fa79793fd4fd124c9a5e7b290185ebf3b17a19 +3c9a483c9bee33b601549c592a82e95b4319b1e74b777877f0971bcb4273716b268e8f99f876e42f942f4cf08284896bbc1ffbf094ac0956c3cedfc3580cffa8c74fc6db29a371f2da2d05edb9185ece741fe0d3fabfe9d5b4d373755ebed13dc6840cfa3283b9ea46ec8b95c434f253ae86998182e9cc0e95ee64f323fc74b0 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0 972fc610b8e6945c2e2743034f1faaa76e53cffb768003e9d8e9140c85aa2aa94a480b629b1ded4911cbb303785422dc0c87a1aa5b4c8de27486a316a59fb2f6e0e0b987548a75dd874381323825316d266bac4b9ec17965d4d89c27655b3929 +bfc073fdda63c5fccaa0ca8770c293e8154e7aec56128bbac4fdbd541d602216ebf7ca1e02b514d6e396f20683802ba3f334310a9226576926e3bb19ceee27738d13377cbafeb09d091043501702a07aa31d1f29d50ddc55adcf16ffd40578e734a4e6cb6535f26ad48e0c62ad90e79720000e87d419e92dca3e11f943655b03 e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d b82ddd7881c4da689a10f53267cfbd39fd21170fff8334726d5f5fc33fdae299a8aa46b230e3f4924af3f1a57499e24a0bdc18a6015d10c969058aa94b025c16be14a152923b475a8103f0593b19219f4cc09cc9a3168478e36d04ae2401f21a +08079955d1a1f33728128c73673ec9f21a6ce138dcab5adc4dc068e6ab57314b9fbd8b013123b2fdafa9524fbdd0288777a233de8055cccfad83046ada6a19f01c47817496667bba8fc8b9456fc0e044a562d931dab1adcb66af8b66325bdf28d83ded3e2937958ccd19da540d70ef2c189f55a506c9c0d63406394c5bd3823b f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7 947336d25d9b0c24b4d2a5079639f77b670d5311016ec455ab7a240be4735101118b0e8f4576f3a5c01bcacb24105a33164f5596b7900d0c1100148eb7b707a8783452c0aae80b7e0db7959edb2e218357262b5955e3d8755b47e916f81e33d6 +23900b768f6cd42b8a8df0dcbc9cb5daec8de36b9d5c619adcc1ba2b649103d5af123746cdf19c3fd0665a6fb9338156182aa06181e3c6e37ce56979612af2927440424f89cef43fc754854b8a5c43370808cf5f9929cf47712512ce2f8a2a20d2e9f568c2848b27dfbe09142843c83905ffa5da3b15501761b03dbc2c5398b6 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c a58e95d4c3a37a56ecab25efd6e714565c91e49293efd0c87573842af71f110835e0162e5c5a5795ae5e372e84535287109d42738c5f8fc8e453195d38ca6bf9ea8db74d87270232dd9fc4e779599c459852b3f5049525f2f39fa44a26ff8d2f +1eb28c0bcdd18f73e347f957ece15b4cc83a771b0877e1feaac38e24028fb38ccea8b54ee017dc7c3d5a1327bc6f40b294aa65d7dc487f278846cd101ee84202f14b38aa2c275046aa2577f65ebaea41cd383e8def2fd0b4444dcf426fa75c4082cd7fa035cdb1e0d34a3c79d42130f5b0273eae75bc701dda3aebe7358f41b5 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18 a4d891d6b3eb17062b4b16bdf9204f202152fb7e9b7dc51268825b4d7dd27795baab73865385eaa2457412405190eca8156e0f457d3ca9bd6dfd011cc01cf488337149bc7cecbfdee4ffb6d8b4a194f4082d9de628c434b8cee99303ed415f67 +efab51855407438fd5c250670366bca3c026ecec4a59394f00d8a4b51746d0c4564366656d507e3e13e62fe7abeb976b8859895848dbaecf6582f1898ea06f00d4247702ed9721bd375aa83ae4c67c2eaa6e080777ea5ecf2cf787d785389560ac91cf63a52f0373c3185e18a3b8a466e21b61a239f1b77624eb1acacc76c4e1 bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a 913c1a2ffa2fc6bfe9d7f5b5de3467e670a2ef112b9c758aba8c4ae41ac07327fa84e20adc31c89a58e93e382b1c65460b6278303fad434b0c2470cc1c493bd60fce7dcc6f55f9ab82a0d14f66140c9c2f1020c1d8a9e779e1c634f5120c8861 +31c29ca10279a417f0cc9b1382cf54dbfdfc89f2e6ef08c403c11f580cbf8674b141ed1a417563282d99a55fc616d836421cde9424815c95e7fb7668bf3f137b29937f14882d74e034b732d78d91af7721aac4950734f5fa5d4b4d35534974f8cab6d2e6dca75ddb57e99148c8a59df9fc5bcd723e546e8356f671cf2f65640a dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738 98930dd359c1ad101a0155171ab27747b9fdfa192c22be1555678b08e93337c12ba6e92726a3da7cc02e4e55c0a8f1ea083ee06051b8efdbe24fe56ddb16b77caec6401cdc036783c5b1438852ef6733a14285c6e0ad8c1472aa03ddd01beed7 +8db476f92e332519c1a0ece5d8deded6efbd2d8e8784eea0a6b4c3b4296c35f5f8de4317e5c1627b91fb1973fee86c06e4992aa5a20cb7475c8808ff1da354d07a488dffa7838c6ec1e3f99e3acba831f27bee8434eeda3eb36d0c6df3658883cd40068b1bed841310f6eb38d4a3d07d85848770ff7933c054cd8b34662660b1 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01 ad80cbc2fab0a31bc147b226282d5bd67f551c8e2bb346c7de300497acb937ea911b1270076bdcb5fe78d3a97eaf9d0c03e7c56672a9a5271a2defd7e0d1cfbb86d253964deb05cb72c185326a42ac9eaf209ab6c88e6702b1c2f0d331f9f53a +fcb272c828fe8fd3c6f8de9410c7b6e2b36717c1b0e5e359e9109bd7fc378978aa98182a9d99961898ed88999b050d3b64d1457d7a899d6d273b9f4dde2aafa36d76329d62509043c338f265fc4c7d938459b7fa3b230a9f6cb632b61489546bb4181a5ad7f0d7369b8caced48eb374b075b2b325bc86add0f3b680cd9e80acd 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28 a79dbbd57f4ef3d58dc2fdfeef506c77eedf3093a7c205c88b35c2369f8d53d97cd958ca3150e37fb9ab798ec28321000440655737bb2c5ef0358344b16cc03f2f865936ca568f3770dfb235ea566277710796fd9b1abf4dcbfbe3f8af6ca493 +7522492bdb916a597b8121f3e5c273b1d2800ef8c1db4f7dcbae633b60d7da5193ba53a63d7a377b351897c3b24903ae1cd1994211b259be3e6ae2cbc8970e4957fdf782c7d1bc7a91c80c8ef65468d4ef35428f26e2940ae8b0bd9b8074236bf6c00d0ebe83f9ddb2ade0f835138d39f33b59f244e0037c171f1ba7045a96f5 ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6 b41e0cb484ffcc4364ce6534482e7fba1fa1ca21c8c072691d2b56503f5af954e2a592eb79921224e271341e7ac1f47315635b547cfb6ef219f200ba0c7a5b9baaa481a21d50ddf4ac49a906223db13f3d6ecebd88859b9b3504d25030e1843e +61097114ff855c3e34a62d9b853f8982d35f29cfa4a89893badbca7849e5fb437a1a38d6451bf0ca5a0d528e352b8e4b57f2ea359a7fc8841d49dd3e570f9b016f14156b0bbc4be822e260bd147ec081454969e11cb0034b7450ef4deb7ed6edb977e2f4ed60121aa095fb0ab40240dc329ecc917f5c64b4410612af065ee9dd 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc 955a859a0927677899cf867b8dfcd01c1bd6bfda230354cba6003a518299e7894e02999c2fb263b5090a180c59fa4f9e08721da7f5b88c87d3e75cd3cbfc67cd2208a4358475eac16ee193fc17c4a39b32c3a822034a0a3be0aa7077ae69b9e9 +dd09ae6c982bb1440ca175a87766fefeacc49393ff797c446200662744f37a6e30c5d33ba70cbd8f12277fd6cc0704c17478bbab2a3047469e9618e3c340a9c8caaff5ce7c8a4d90ecae6a9b84b813419dec14460298e7521c9b7fdb7a2089328005bd51d57f92a1bcbeecd34aa40482b549e006bbf6c4ce66d34a22dda4e0e0 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b 8752c9bb85f571716c6b283976659602561da5698de1be1d80162283ce53de0f52effdc9938192e3cb83920c7289d74f003d9d284c29c123a575788a7240fbcb5fb1c9d95fa9bd5454699cab2bfe0057e429ca244875af6aa8896859f20c518b +37a73e2774d3b274db426c89b945696daa96035031f72cea01894b24508c7f81961ec254d36ed6a0f448e11cf7950af769dc6cd2c47e52c6caf0ea92c270974f0214b4db436c36a60fb722060a6bb544462a82e1714f5906ec32886f7d59ebf289541c3a00ec1e004892ef2b1286a0194f55d083c6ec92c64b8fd1452e1c68ba afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc 938f1d943b5320c44923b9fda79811dd557fef5377e256d40abdb8748f816cdc7c591244e4db66cd180eec2bff89e6910c00e7414d28f614c5713a50a52489410ba685ffd17447cd79766ddce35635fe50284daff8eba2b96e7a14c2ab5a6165 +9dc2046ffdc6804544db964481abe5d2d276a2a9eeec4c7ad40215b1de23561d402db69bd0f6eec2254711eea4487c64d9a6b62c3ebaf5ffa8db6e7e3a6e17154d126967a47a853a6f8339bdca9be306a13c7f992ded7619b0da59909a49b1e0930360e05b47f18628a36d69b2f87f2bfddd6a5d4a72f84dc76dbdd43f3a6a35 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c a0ea7a4f40ab878487a75131a1396732a419a39c1d047c0086ff909c2dc6b826ae7d2617210832bf75662c19d788352b02f486575342aab84652188414aa75cb7d4a9a6274a7ecaaddcd766b12f82fbf56a95985431e83178b1b50b2c61fd633 +d9c6847fce688c5e7525a1098b545cb6c15dcd21a02761fc82fc664372a667390680135f91c01a2fa5430c634b1a6d1cd6002d8aa021e7bf5956a7901c2f81bc25d502ba5f55a55f30c0323dc68205cbefec0538e68654e7b327ac1743641896c3e740d8f66f400902b304eafaa4e0d8cffae140536f0922444cc3216a675697 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc 93706d079e21fcac56b77ce5f3041d79548a7ef6f08da4aa7524cf17859796868060f64cde3dac113210bd3cf0944667013d4b69cfa90064550b396b69f3d878ea4dc5ce57aaa8d039e398977bd34a64c0a793c67c5651efe463a4ab0cfd98b8 +69df8a01b66f04930efd2012ff2243874f256ca8758145d2a9e4ecc84d0dbdbd0dc494ae06db0ccbe819918137c90957114558580d6623efbafdd342b38dad9f08708084d32f874fba04782ce26aaab78de2102ad171f8a8f2b30b5bd3d55fdac5fa3acd6f7def7e61c2533938572b331ba6d1c02bd74bfdbf7337ade8f4a190 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4 8458737c3e51dbdb2f12bd7d4fa3e8686056b34fbace242d4b1e64138fca557d80280caf1d8cef750b5da80ab76e55be10d68f0c81a7b37a67bf9742248cbbac27762122593fe76c0ceec38137990d7bdb01881605333eca1e67de996f9dc048 +927524982b8d60777c1105c86fac05f634abf58c73f84fb95d81ba0b86e1e43592c4fcad2e395a40fbe7005697d86088e2fb3bb7287eb3f917d4f2dc281f5cbe65d05b4f9623bca849b10a03beca6aa2056a12ebb91cf257ac448c5e9a78f8349a6a29b17c8978bef43a443cbb8a149eb23f794844fc41693f2dbb97181444be a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916 ab0f00c9fbd8afaf765b5b7386df3acd850a07703784c7a855b2436590c518ebb86fc019a8667392f9fe4806939a45c204b48a1bd5e4a418e0d716991c6a50f6b02d2a6923db3afb66deeecfb103587ae88b72fc8974478bf59815b682fa29e2 +5f9042283561e7f19a436d01c7ef5a950a6d77ede5629cd7e43c0a5d58e8c5673c37945a453291d12938253c71dbe12c8b022ba7276eda6be034ef5ec1ec77dbd1e08f0d7b8e7725b7ec671c075e008a20f77f4ab266f97079b0aa6337df59a33b881954084057b21f294dd14bcb0869a4a6f1f597955ec7bf9d19bb3537a66a fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b b31d02adefee479c3abe3a1f91cf05b908dae7ece01fcf3b4dc8193d981e9279e26fa256b3c7f1b25cdce9b4299482540544a34e16b954e96290ba76143ef055ab939461317a0fec33355fd87a133e3a4c2ede25a441d10bfd81041f1733fe92 +c2ae5573d3bf396523bfb703db8502fd0760cd1be528f6ddbfb95aad399e0b19f3bd9e0fabdb05d49e3f893dffec5b627c9c2f7ad5f32e92e4e27a38cb5c28657657377fdfa1b66cd7ac3d15c6d49df92d284db99f69744f37dc7cb4e7d52920fdb200a7942623a7057ba82e467dcccaa5da416b48510d8364446a6a5e2a5aa8 a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea b5ce010a4cc0a0531130a8696806310e293271508e81ffc5ce95175b8f03cb72b463b20f5c5df9407aecffda50e278ae11cb5fd69082e008a4c7b9b938726601e3d2c8b4bfea57ed7ae71f72d85a884cdebe118c4d0ada0aefafcf71fcb68358 +03c1a1cd30a039d0dcb22fee2450a7fa79495a0d0f4f43d2de4d75bce003c0334a8860f5c164dbd94888a9f751235a3e570d31070e3e1293a7be616af7176600585d36ac013600157d2569d491da4b8a3bf3630c26e0b9925412189f50b0ae6f04c86477932e2ecd8c3546106ae1ebc684cc3adb27ed665eddece886adea4ce3 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0 a9b1e7214e54b65e49ef3adecdae3a4ab653fa0d6209ad47037ff6a8168eb01bbce5534f566d5858d75779439ca6d25b1700e0aefb11250b51a3a9b504d243846750c6e3251d4df0021dc6c140e343620f06de6bfc2eac9f52e81c3bd7bbbea6 +888f6d9bc7c86c0079fbfd42d8c08d6958f40f6e570fb0b1f03d2f8f8a63df4fcc87b379a222cf835820a999d34996e08961f13b86b075e7fd1c303cd3baa44de42168561589012f7e5300da4f8bdf470c07119a5d9f7ba7293568cd7c6a1b7fc1e41cda40bed7d46e5a28af67ae2aabfefe67a86a1c601e6f5ee543e09bd7b6 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294 b54d7fccfd6ee52a71862acf216517ebec9351017d568ed49a4d93078ed7c4531aa954720ed75e14f075f958bdda67b1057d71fd85bb13079831e5ec6f87b165ac047a2be283a856af23e53b605c3007a527b963a212d6ff2479d3f9b7450bde +48453340f1317769e6ee6e103153714365731163dc18f84e9f2fa4b120f9c5a9645ee2f9b66c84c26d95912b422b009b64af96aa418b2427a4209f2e7513ba8e43ec8cf20b34e7529b22eb1199545afe9a9f7d9bcb320aec9ee0162f91c0d1dd9674c9c284f25199c5e109f6f84d7ed0d269cc6413edb81bc2c83e37d644d8b9 b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a a7ea2605bdd53939a57412b0b3b9c1e5af36c8a99314c1910f3883929925c4b46ee5e71a8f6ab7a0fa3fcdef47cf43361756bc441d8993a363e7091877f351f2e0ceb4648f14e1cae338c7d9dc82c7ae919399f92f80b5cce13e0ba3a0ee5d00 +4bdfd3b91d83108409ad765b256e0c9b9937ecf647f8e6f9fc807e2e72af8246178b3fe046b4ea10170450d71a4eec790ecb05f03d7077341de26c4db7eeae24d55c9a9093e837dfdb38168fe8230cb9605825a1282fecd741989bfcdb34678fe077477927f66bd26d003e5dda22043341a14dd31841ba483ad5ce2701e0f68e 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4 8fd88f2da1baa57a1fd9aa93151e830b33bdbee7160f09930d7649e8b43aabd93ecee83a1ae8805b6169513ea6efbdd503c27ccd748c7f914bdbc64db1446ef76463b7b19270d44476b4b0eec4a89611d98995fc564d3012dc467b04d62e2469 +e6cdee8558bc1eacc24e82f0624ce8d02cc8d925b4dd3dec3a72f4a4e0fb76076bfa3ef2e2c33bdd7c27b322bdc09bbfee8fe46f75dbd7bbd2af09690b7137943efe21706e0a1b6d3089540fc58d85ddb55ea836616db573e36c521be008893f40a0a7c349602cc178ea43be59d31ec6449e7ff2c5379379f7d7645134df1bc3 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04 a7d43ec72c8869d0fc85fdd1656b976eb9c74c252c099b570cb334926d0544474817612e5709913b1a19e1804cee61e412888058577505decb68dc2c4af3a9a7332428295e092c2a8b03117fc4f686c9ea6defa0bd575aa432e2e50113c2fc55 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P224_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P224_blst new file mode 100644 index 000000000000..a7d96c09f1f5 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P224_blst @@ -0,0 +1,60 @@ +699325d6fc8fbbb4981a6ded3c3a54ad2e4e3db8a5669201912064c64e700c139248cdc19495df081c3fc60245b9f25fc9e301b845b3d703a694986e4641ae3c7e5a19e6d6edbf1d61e535f49a8fad5f4ac26397cfec682f161a5fcd32c5e780668b0181a91955157635536a22367308036e2070f544ad4fff3d5122c76fad5d 16797b5c0c7ed5461e2ff1b88e6eafa03c0f46bf072000dfc830d615 992cd443e4be26f1c2d6fa1256dc9cfde9e49e1a9f800703a4bc85ccc83ac670f15512405e4c7d8ad452539edb54729815661cf72f543dcc8392d5833a8016d7e8616750fe2f3d81380be8a7dfb41291d39f957baa198f9c4a5581eef50e20b8 +7de42b44db0aa8bfdcdac9add227e8f0cc7ad1d94693beb5e1d325e5f3f85b3bd033fc25e9469a89733a65d1fa641f7e67d668e7c71d736233c4cba20eb83c368c506affe77946b5e2ec693798aecd7ff943cd8fab90affddf5ad5b8d1af332e6c5fe4a2df16837700b2781e08821d4fbdd8373517f5b19f9e63b89cfeeeef6f cf020a1ff36c28511191482ed1e5259c60d383606c581948c3fbe2c5 ad4518b516a290b514bc1c831c18abef33b12147e8484c67e38124653691ec13665fb7310c9a1158adb19f2cd96b39990f362c3f616339dedcd476f48799e47c4561676a571953db2f777623244f5c8884df06d4e045aa3c8547e41203b79287 +af0da3adab82784909e2b3dadcecba21eced3c60d7572023dea171044d9a10e8ba67d31b04904541b87fff32a10ccc6580869055fec6216a00320a28899859a6b61faba58a0bc10c2ba07ea16f214c3ddcc9fc5622ad1253b63fe7e95227ae3c9caa9962cffc8b1c4e8260036469d25ab0c8e3643a820b8b3a4d8d43e4b728f9 dde6f173fa9f307d206ce46b4f02851ebce9638a989330249fd30b73 8ec6cd4495f88f55f7791e512bb98b067098c6d0c28099a85a19549b8364ebeb6d8c6188ea7cceef3a22ed692e5aad4c10625a5c7c21f9390ee91976dc3099ea6e5ee69ca02ab21f2572fd23c528fa3d08d1c4db4b3bd1a758bb45638c6abe6b +cfa56ae89727df6b7266f69d6636bf738f9e4f15f49c42a0123edac4b3743f32ea52389f919ceb90575c4184897773b2f2fc5b3fcb354880f15c93383215d3c2551fcc1b4180a1ac0f69c969bbc306acd115ce3976eff518540f43ad4076dbb5fbad9ce9b3234f1148b8f5e059192ff480fc4bcbd00d25f4d9f5ed4ba5693b6c aeee9071248f077590ac647794b678ad371f8e0f1e14e9fbff49671e b4fb0af113f8cfd18c7cc92d36a5db3fe379a4f3f861e0de4ed98ea41c674c9a0250dfb2960424a92a8255394df680b50b83e2860bb6440fde82fab77b7e152cbffe0f07eed90d7b78894201b6b53a8b794dd52cdfa79dd63a82b9947c56092f +c223c8009018321b987a615c3414d2bb15954933569ca989de32d6bf11107bc47a330ab6d88d9b50d106cf5777d1b736b14bc48deda1bc573a9a7dd42cd061860645306dce7a5ba8c60f135a6a21999421ce8c4670fe7287a7e9ea3aa1e0fa82721f33e6e823957fe86e2283c89ef92b13cd0333c4bb70865ae1919bf538ea34 29c204b2954e1406a015020f9d6b3d7c00658298feb2d17440b2c1a4 b0209ac0e5cee891c65a0b0d0e3e920b78573a5dc01f0dcf3cdba01ba9537f0895b8c8be7cb8b9c875876123894f74b80499d96c6b1da7903c7072c3c5f2d56b26bf910643c10bda975e0a8f0d745c2885fe78ee08b6b3d2a82751b4a9e4d0d4 +1c27273d95182c74c100d85b5c08f4b26874c2abc87f127f304aedbf52ef6540eba16dd664ae1e9e30ea1e66ff9cc9ab5a80b5bcbd19dde88a29ff10b50a6abd73388e8071306c68d0c9f6caa26b7e68de29312be959b9f4a5481f5a2ad2070a396ed3de21096541cf58c4a13308e08867565bf2df9d649357a83cdcf18d2cd9 8986a97b24be042a1547642f19678de4e281a68f1e794e343dabb131 a5dc6baf0545a1332f3b79df3b830c5d41a83ed80a5c19ea7b445365b8766ab61c8a4d722151e8e636ebdde61db2242914efea6ca73500147b52d4ae67854c85f15da5ba9af6eabd71a2b1cd5684e82c807deeeb155f4e734ed48fdb4625be4f +069ae374971627f6b8503f3aa63ab52bcf4f3fcae65b98cdbbf917a5b08a10dc760056714db279806a8d43485320e6fee0f1e0562e077ee270ace8d3c478d79bcdff9cf8b92fdea68421d4a276f8e62ae379387ae06b60af9eb3c40bd7a768aeffccdc8a08bc78ca2eca18061058043a0e441209c5c594842838a4d9d778a053 d9aa95e14cb34980cfddadddfa92bde1310acaff249f73ff5b09a974 829b2fa49af46fdb3339f6c4f0ec695b1baa17e5b9ad04a716eaea18b09648d855542b6dd69b7fbe795ed5594c19813916adf6ac4a6b8cfc46bfc5e98b72e7d15e4954c51c64e1c283022d1e1a1f1df31c13ea5aa222e0dd36ac7f29d632fb77 +d0d5ae3e33600aa21c1606caec449eee678c87cb593594be1fbb048cc7cfd076e5cc7132ebe290c4c014e7a517a0d5972759acfa1438d9d2e5d236d19ac92136f6252b7e5bea7588dcba6522b6b18128f003ecab5cb4908832fb5a375cf820f8f0e9ee870653a73dc2282f2d45622a2f0e85cba05c567baf1b9862b79a4b244e 380fb6154ad3d2e755a17df1f047f84712d4ec9e47d34d4054ea29a8 900affd9bdcfe7839533a22905044c0fbaaac9ee666f419571285f71b1a9b38a3f3602bf0fb50ba842997d97f458a8f10a7a307814553623a6bf39edfaad6f1fade51e59bd8c758b4a3bcd8834094d739977070fe16e429bdc21c6a2914021a3 +79b7375ae7a4f2e4adad8765d14c1540cd9979db38076c157c1837c760ca6febbb18fd42152335929b735e1a08041bd38d315cd4c6b7dd2729de8752f531f07fe4ddc4f1899debc0311eef0019170b58e08895b439ddf09fbf0aeb1e2fd35c2ef7ae402308c3637733802601dd218fb14c22f57870835b10818369d57d318405 6b98ec50d6b7f7ebc3a2183ff9388f75e924243827ddded8721186e2 a76902617c7c9db4bd7053b03801e785c4ed86894bc63519ad67b8010c850ed2c9d0af47790dfafec9f456a0f0ecf70d072d72653c9b8437da0f66a801e1d31a3ff53241db96ef40bab90ff5a500d4a8086e31cc6fdc499ad07017ecad299437 +8c7de96e6880d5b6efc19646b9d3d56490775cb3faab342e64db2e388c4bd9e94c4e69a63ccdb7e007a19711e69c06f106b71c983a6d97c4589045666c6ab5ea7b5b6d096ddf6fd35b819f1506a3c37ddd40929504f9f079c8d83820fc8493f97b2298aebe48fdb4ff472b29018fc2b1163a22bfbb1de413e8645e871291a9f6 8dda0ef4170bf73077d685e7709f6f747ced08eb4cde98ef06ab7bd7 8e5f905dc1af5ddd88373d026ad6a7cbcb6c5498c202b268bea1bafefebe733993c21d99eb18af467b0cb7df12147e56134b0ddbf457ef8dfa2d710a3356de4124796aeee3496a1b6482500c0582cbebbc74a50bd1ac755c8714d62f39bbf2c0 +c89766374c5a5ccef5823e7a9b54af835ac56afbbb517bd77bfecf3fea876bd0cc9ea486e3d685cfe3fb05f25d9c67992cd7863c80a55c7a263249eb3996c4698ad7381131bf3700b7b24d7ca281a100cf2b750e7f0f933e662a08d9f9e47d779fb03754bd20931262ff381a2fe7d1dc94f4a0520de73fa72020494d3133ecf7 3dbe18cd88fa49febfcb60f0369a67b2379a466d906ac46a8b8d522b b62439e0e5dcb6ae6fdc8dff976405c44192146fa3b15d2b1ef4316493ddaee708cb4b22aa57e57ca0c64e3595e2861e111c42fcde768ca2406e2815ab6da8c1e359562313766d433d600bd470dd0f5d09616b2115e3b1e440a9cf110db286e5 +30f0e3b502eec5646929d48fd46aa73991d82079c7bd50a38b38ec0bd84167c8cf5ba39bec26999e70208af9b445046cd9d20c82b7629ca1e51bdd00daddbc35f9eb036a15ac57898642d9db09479a38cc80a2e41e380c8a766b2d623de2de798e1eabc02234b89b85d60154460c3bf12764f3fbf17fcccc82df516a2fbe4ecf c906b667f38c5135ea96c95722c713dbd125d61156a546f49ddaadc6 8205b3701f95759a0558504a9bac87095524073a16153c972ee76d2e7d4d273e815edf43492b22c29425ca671e836bbf1195bdb20d09e074834e60916cb819bac681e81ed21162511bc7b18e540ff2efe113989bd7d2cd53a8f73de31bcac795 +6bbb4bf987c8e5069e47c1a541b48b8a3e6d14bfd9ac6dfaa7503b64ab5e1a55f63e91cf5c3e703ac27ad88756dd7fb2d73b909fc15302d0592b974d47e72e60ed339a40b34d39a49b69ea4a5d26ce86f3ca00a70f1cd416a6a5722e8f39d1f0e966981803d6f46dac34e4c7640204cd0d9f1e53fc3acf30096cd00fa80b3ae9 3456745fbd51eac9b8095cd687b112f93d1b58352dbe02c66bb9b0cc 90da4d284753eb05bd600abc1a9bb3e725e00caba092811e00237740d01b93561969e0b9ef50c293c9d28efe0870fbda145bbc0967eea10ada735eb9a4c4c132c0647ba03537b198eba7429f1dda9b37e1da27ecf03134178f3c3f57a5fc1202 +05b8f8e56214d4217323f2066f974f638f0b83689fc4ed1201848230efdc1fbca8f70359cecc921050141d3b02c2f17aa306fc2ce5fc06e7d0f4be162fcd985a0b687b4ba09b681cb52ffe890bf5bb4a104cb2e770c04df433013605eb8c72a09902f4246d6c22b8c191ef1b0bece10d5ce2744fc7345307dd1b41b6eff0ca89 2c522af64baaca7b7a08044312f5e265ec6e09b2272f462cc705e4c3 acded4343ddea6ce0f3560b2a3709ff6d514bee45f3898b2b19dfd3c483de7feb51f9150d861e6852bdb0adf6249e1b61564a0c924eabeb86cd4f107b72819be6baf43f8269f1cf4b66bcedfd14b153eef2fca2e0e0995a1744a181d79d5b645 +e5c979f0832242b143077bce6ef146a53bb4c53abfc033473c59f3c4095a68b7a504b609f2ab163b5f88f374f0f3bff8762278b1f1c37323b9ed448e3de33e6443796a9ecaa466aa75175375418186c352018a57ce874e44ae72401d5c0f401b5a51804724c10653fded9066e8994d36a137fdeb9364601daeef09fd174dde4a 3eff7d07edda14e8beba397accfee060dbe2a41587a703bbe0a0b912 ad4a25a783381dfc091e491add421cb0a40003560a0ca43994c4ab80c8fa53eff3396e9b729562f974105820ed71dc8004ffd89285b1ec5d1383b9c052c677fcaecf6275c8b635e5855ab943d6cc51cc1b60b5aa82f2a52c1aa22291e8d6ffe2 +2b49de971bb0f705a3fb5914eb7638d72884a6c3550667dbfdf301adf26bde02f387fd426a31be6c9ff8bfe8690c8113c88576427f1466508458349fc86036afcfb66448b947707e791e71f558b2bf4e7e7507773aaf4e9af51eda95cbce0a0f752b216f8a54a045d47801ff410ee411a1b66a516f278327df2462fb5619470e 888fc992893bdd8aa02c80768832605d020b81ae0b25474154ec89aa 85b64d397eb02f43b64d8d47b1c030c9d12475651bf20bebc7735333a810a864f6cb7cc30df4fec2c6e1063693f48f060c3698d40170b7e67ab3f64f5b92baf4221dc9dbe266cb6f7bc9f0a28f711282e3c388a46e6d8d2ebca641299fd10e8d +1fa7201d96ad4d190415f2656d1387fa886afc38e5cd18b8c60da367acf32c627d2c9ea19ef3f030e559fc2a21695cdbb65ddf6ba36a70af0d3fa292a32de31da6acc6108ab2be8bd37843338f0c37c2d62648d3d49013edeb9e179dadf78bf885f95e712fcdfcc8a172e47c09ab159f3a00ed7b930f628c3c48257e92fc7407 5b5a3e186e7d5b9b0fbdfc74a05e0a3d85dc4be4c87269190c839972 ad3cf5fc226436455f8c931ee83e17b282da199a347de514bca39dcf31204af35b4351798ddaadd7ce9fe84bad35ee2d0728f256e996254c274991a12ad9ec175364bced74a240f27fc47e8ae93fdd8a12d93f0a9007d3c1768872f6482e8273 +74715fe10748a5b98b138f390f7ca9629c584c5d6ad268fc455c8de2e800b73fa1ea9aaee85de58baa2ce9ce68d822fc31842c6b153baef3a12bf6b4541f74af65430ae931a64c8b4950ad1c76b31aea8c229b3623390e233c112586aa5907bbe419841f54f0a7d6d19c003b91dc84bbb59b14ec477a1e9d194c137e21c75bbb f60b3a4d4e31c7005a3d2d0f91cb096d016a8ddb5ab10ecb2a549170 a03a7a4aac051349ee4a0b41a8e3be4d37a5679dc50601955935abd4c2e95a9a7ab3159ab0cd52d55450b09c223a6b1304a92b930a335c1494175a760b3581e55ad33ff2283aaefe5ac53370e1b2c93a3d5beb658639fcb786a52b6db2a7cf74 +d10131982dd1a1d839aba383cd72855bf41061c0cb04dfa1acad3181f240341d744ca6002b52f25fb3c63f16d050c4a4ef2c0ebf5f16ce987558f4b9d4a5ad3c6b81b617de00e04ba32282d8bf223bfedbb325b741dfdc8f56fa85c65d42f05f6a1330d8cc6664ad32050dd7b9e3993f4d6c91e5e12cbd9e82196e009ad22560 c8fc474d3b1cba5981348de5aef0839e376f9f18e7588f1eed7c8c85 8822f9372ac0c3b278408ad5a17ea7b6f01dee41e506192445503a0bd93d40919d58251e5378765d502797b467a48c7e0e9766b2887d729f1c0fa6404fc31062d43ca95d44b14614bc12acba5b4e1692a18d7da3fdc1075913518df286df5c21 +ef9dbd90ded96ad627a0a987ab90537a3e7acc1fdfa991088e9d999fd726e3ce1e1bd89a7df08d8c2bf51085254c89dc67bc21e8a1a93f33a38c18c0ce3880e958ac3e3dbe8aec49f981821c4ac6812dd29fab3a9ebe7fbd799fb50f12021b48d1d9abca8842547b3b99befa612cc8b4ca5f9412e0352e72ab1344a0ac2913db 04ef5d2a45341e2ace9af8a6ebd25f6cde45453f55b7a724eb6c21f6 8c3f166f38d014975b62742ae696adfc1707a70380d7c1507760fd4c3989b5b209ee183348273f0f86fed68d693064121700d8de7964b4f1a5a15ef1ea0a7556105893a2cae7852cbaee4af408e866dfd05b90c179338e0061f115862de7c512 +4cc91f744ac858d3577e48813219aa3538dd813b186b42d1e6218376f07cc1cc448ddd6b37240e98bf953f49cf54d65c12878b33c0bf6eb1c60254f0b6fa974f847e53abc56773eef6f29885dfc619e6a48fc15a667ca94001a0c945b6357a53221b0f4b266181456b0d2d25e90708777f1a6f85971c00140c631c1991e0fd06 35d4bbe77d149812339e85c79483cb270bdac56bbf30b5ef3d1f4d39 816fb61f5a25dbcd9d768d129292384131ca20e6bdd1ee7136235ee23993ef920b9faa6bd2b62a122e10dedd3be0bd1702040bffa2c6a165c7c20eebb14563903d78514749ae166b7156a237fe1206c5ef696ebe2dc56d39ce7bfa7a01048e34 +58f43cc1924de4bc5867664adbc9d26b4f096a43aca47c27c52851b006dc2a658919ef9ce5b5ac48372703be15ac51631c2bd84b88f479f113b0569a9a09e230ec1e8e573474c6075284d3e57d973829af35325d9e7dab4a5f9b065155bbcaff3642a82ef4c9b9e127d3575c050721653da3b087d3fa394192897a5519527d19 2c291a393281b75264c9b8817af684fa86a1cdc900822f74039dc5d6 86958f1f2d580b1d8e9310ae07a8f2071d39071081ef84acd885c6d70ded948ae8dbfc455ee06b1a05254c14bbb1a54f0f17594a5692e638965f8420c0bf9bec26ea4a3a93db4b1ff017357955c4e109ce87328aa0a1bd08c5a3736bd1f57aeb +113a2806b052fde683ee09453098e402204155afb3776fd1cad3a9103421d327eab8f9ec0dd050ffcc83f93b34ea707705fabeccfe43ab1a71c95298fd3ec769d99ead1066950eee677d225816e0faad19cf69e1b35d16771689e2092cafe16d7c0dd7b0db73fffb8d0f3eaed83004dd21e753530ec939c89ba25578fa5f785b 831ea25dbeda33d272a1382c5def0e83929170ab06a629eed6ee244b aea8e09385f80bc6229f71a87789a6fe4d27e11e1aa509d2a905ce6b0491d3e4085fca2461a55ee06fc286c9b5c1fd95130f8b46400b838789d2aad54079a2998e96cee26642df6efbc820ff347f1571eaa5397a38a6981ced9e56a661c0e688 +64cbfc8f2e2149a31b3e8a80c4a552f6c62aaeb7990b6e0ee55500a9d17be04213406578caf315951086dff5c2af3b5ce17d425d185101ef26f86396ba3a129a4f3f8e2dd595f59efb6c0f5c2dcc394569d7268695e9ac7daa84203f1f1895f1f9e4b514a5c9cd23baa63454710144fe735ad9b8f42d8c43267aa434a26d7e5f 70f74c7324ef137318b610ead8ddc5b964e0eed3750b20612fc2e67b a678c1db02b53841fd49f53ae014b028b7d882228475cb2ebf9d17c686f777e025ecf6db1508f60052a61bfbb76724370a386ac4446e6d1986126363749fd29021c4c645051dd87a9acfe293f4ceb9de3cd09ec51095b66eedb1c5459654f2de +a10a11c8e30fff118d371daf824f16c08200b83ea059436466a4611ccac93b2dea2de8c1006f946196aef7fe9b0c251a391b0340f21797798278b412ff2b53842eec6450728e2bca062f8337a2c204b9ea04ff660cd4d4db559f2f11c4d8ef199021339fcc82396f7a93926cf5f247e37d8067fe50692de54f102bd5ab51925c 026be5789886d25039c11d7d58a11a6e1d52cb1d5657561f2165b8a8 a304069be46d53afec2051f4b4a49349f08e30d8fa5d8b04d622e5574dee8211de72936034e35bc4facb03ceca4961d3165e65fec9e5bee4577593273728c4e3c48680a06641267443964db6950a9e72fc2d99fb30f3325d37f261aa5367088f +b3f720bf566ffa369259f4361959ae0641d2755ec264a4c4349981df2b02563275b2b9adb5aee47f7a456760a971991ffed6b17809bb9694138d1677fa916123795239353158fc6b22d10f20d26f5d2dcd8c56c44373eea5b93067dba2d7c5318dac2e9e8714873cb1b37f58c011fd14fa1e535554efe05f468bfc8e11cd8b99 e79c18d935c2839644762867aa793201f96a3cde080c5968412ce784 af137a6e3331059d24a6a2cf26d9054a3e21362965c96faad9bdbbdf66603225b15aecbdcc37bb3dab44016eab500e6600f841529eb056f44d79407d9a8689e07c1278cb8fd90235a11f8f00c8e6799779c31337c16b41330f6e3b0bfe75d80e +0a398a46df7ccc48d1e7833f8bbc67100f1ef77a62dc78bbc115b2a662f9591fbaaa91ad3d788e2fdd1b3164e45293d4f5686c151296901768028ac80ded4bf89c647ad35f0c7c4cb318c0c757c1d83c44d850e5fd4677281b3f13b1ee54de79c8c042813f9d3312dcc6111a68299cb7e829557d7f3d96e702f65aefc6499415 0d087f9d1f8ae29c9cf791490efc4a5789a9d52038c4b1d22494ad8c 8011ef4fc47bce5a6c97565fb4eab07aedc6b3d0a406887e2c8dd8940d2a48b6e757f4504951e93dbcb510f7da09b9250953232ef879d69da19180e16a8876e4d842206a98a06dde56c53c39cb0397e4b3dba0c750a4c5fdc13e607c811692f6 +8c33616821a6038b448d8918668977fcf1ef5aa0cf7c341837b39bbcc9bca875a3757f4b392630e9995b9bbe4eb66978b877586adaa02f99d2344dae082a7603351d8ffcfca081ab403cd0acb90d078dd1d0789c2eb3185c62bff2d9f04cd38e509e3b83c12ed0a5c6808fc42f7ba5b06acdc496c8ad9be648ee6a4505f8560f 0830aebb6577d3a3be3ba54a4501c987b0e0bb593267b9bbadb66583 b7d4ddfbe3ae54053e1a3ff1b5ac31f379833f8e9cc67ff61bd9ae60e6954c60f62a26487bd2fd1a58ff7831d620b04d00fc3dd82247a91bc33e11f788b21a3a853289c31142837d2ee15f19ead0be392ee2a415f364301649511fd058ef8b0c +94d56535fd4edfe67a0daa6579f9d53bf6b7b8830ae2aeb62892ff59f18756ddf2811b449c7d20d65d54f8507de4e7c50eaa084830637812aa4b250a4d61ab67845be36e4a41cdc0a70f8d6e3a63d4514f0dc197e6486015046a316153d5f3a3a4a0ae1ed7ea5fa55e12e73d333333685c02e0eb636234ea7e6d4b76b4b76b5a 2acc9b97e625263e8e4cd164302c7d1e078bfcdd706111a13ccda5b2 a145f73750b06e226e71cbbb90519356bf331f00c9a68e5819a469ee0a7892074e0d4bcfc63701117cd4190331bceaf010863c7fe9dcd4b961f2ee5c52d12de73cb3da55c1829159cf52fae7f4b3084206358a5d4307a07f7fafe4a94737733f +5d8ebdf9eb28b47bdafaa36bf0b66a9eaf99b6c83959da4f2b1151b4f4ecd28fb115a64c0cb9491093a7e9b9c53ec423e4c72e7765bb9c818da0e8c428667e44474a71db4867130c77c40bfd8544b2d7b9d6464d2b8e6a48482153256a32437c3a747231f51134dd14c703407e31146a6fcde23bededcf16950486e90ca69ac0 f4e873d4fb944fb52323406f933815092b7672221de4d1c45917f3fc a1143c0f9661664ae6c678bc0af85c99348631162b8f3dfb3638af444ed7f22b17a27cd461ddaf97a23cf12b65afb701062c0b4c78cef8af11e890c93d980e42279f03116cc12db887dfd6b62130108aee2c7b31b610e7c7c4f0248493092be4 +25e4416695f77551fdce276355528ccf1ddc2483821c5d22d751d50111ca2fadc6593b52c74f4b5957494f1df25b0b2f86950d0d19229ec6506fee8581d2dd09d48418b146ff16bd84a17ca0dc83b1888eb407376da6c8a88fa1e60b8c2a2471dfde4b3996ef673d5bde3d70c434dc9f2488e9de16ae657d29e5e59ec922a1ec 62c572ee0d6f81b27e591d788bfc2f42b5105d2663078dfb58069ebd 861b056d40130301b088a00cad18de836ff82bfe14cb5bf4f652fc55d2caaf87541536d7f70f83e5de498f91c4c3f1960422400347164619ebbf5bc536e7a12abb47d4375f161df160273e0ebe1bcb79a21ebd701bd4fa2d71014f3edb1e823b +9164d633a553deccf3cbd2effccf1387fa3177cd28c95d94a7d1a3e159c5e5c027758cc26493301b2f4d141d8d07a5fe5fead987ce5f30abeafcb48c302afc6c2309f0e93d9b6818cbb6972d222cb7b01302dfe202ae83b89f53150ae4a0e2b8fc0fd1091f19b4ab2e6ab213ab322d04f2c5f57113bfad3c5675227237abf773 e2f86bf73ba9336fa023343060f038e9ad41e5fe868e9f80574619a3 90e1c2a9ccdacde76f2b9bc1256eb9e8b51487a0d3d6e2ebafb29458b35702fc10803375f7c3dd98d7201e229e51bb6a1565e03c4283eaf0eed271afe9cb26c1dcc0cf663ddbab4e9e40738615e59dddb1d889277bcd6c27cad2e2e64f4c1e8e +019df05929321ecea7ee1de4f412aba1c8d3c24437db04b194a68a0a59dd871be10bd3a4be6edf551350ea49fc7155a4d887e1221486291abe77a30633a4c4f7868fe2df24311cba0c73804883954460e122387ed414111ff96ff1aebac8b6a6491d8a0d16e48a63bf3d027c0f68ee4a4b234d73b412196706af8ea022b4dcef b0a203438e2586d7575bc417a4a798e47abc22aa3955b58fc2789f17 80a014381c9252f8a135ee0925d6981aa25cf66ce50333c20b07ab101b31d29de0ac018d29b18e0f6304a72d722cbe7b0430082caa5ac9750e556490fff538ecb0574609014d03b030a1943d61fc235a16ce42bc3a8cd7781675f01a2068ed57 +5d09d2b1d3fa6e12c10d8b26dc9aabc8dc02bd06e63ff33f8bb91ede4b8694592a69e4ed4cdf6820069e2b9c7803658949e877ffe23bf90bcf5ce1409c06c71d86885a94048b05ac0ec9db193e489a5a2bfa367caf6aa8ecdb032be366174343f6875d2fe1785e8d77334f5f469cec64998e08d3303e5c9a1923b34fdc105d65 efcfa50fad6fb2065f9a55f28c0c42fa24c809ccb19b6fc6d8ffb085 93d611d440e10b94c09639bf4873eb91302a97180993298a6acb3acdce2c9a062979fb626249970c752e5ab90b942577195132c4da6dc925efa73a0e3eaa18be4d882e14ac854115fd68ec7e04be70f3053ac10b4ff1eb48cde642bf4d3d74e5 +50f6dfc81c6cf189e0a310f992907fe93356cee9dea9a41c7671a8daf3f4cfe0c459ce6122c1e731dbf7593419d7114cb73b46956158a982c5d52c72f43f0f822046093c69aeff1f7e4cd8af00ba655c5baa2e7b6a400b4be1f6fd51b3e4cfb35a69c80a28c5cafb771b6c2e52e0aeef0e3fd045e8d40745f3f8b74fd969f816 61a17816937987764cdc064dc7b5b4f5b16db1023acdfe25902957dd 94c8a97159c239115294e99072ae9e244a0d762a5d6fa18ee4c48baaf7e8361221d30efe7a028ce0209edeea6aeb61250ae58dd26aecf08efe298b2b02218f8ee66a1576ef41c5b1e292ecbc2cfb6f4e71c7734ff8580c18d4133ea55426b502 +e90129ac6672c85bb7b6b18e9dc199c96c81fd65034b53c77818364d512366fb9cd1bc7c82404c451e561fc1ed916c0948f6ac561b33a1ccca093f07684b8c2bafa9e966377bd208556018a5bafb9edcecf70498c7140fe9c8cf3ad8b8c3b0aa489df797944465047465415bb0e24333235fcdd59a98829a3941eaaf62033e82 79d5367314ec664aa0f6ca36f95549502a05bf8400bf532d669fab8d 8051d9797cdf7c01180cfe294111f5def0cb0937281cb543c76ce9686cf401fbbac9beef3006f436f9de9b543dd017e11713143eb453d9cf7b8b9b5a71e1026a64dd2a3265af2d8b174ead2802fa79793fd4fd124c9a5e7b290185ebf3b17a19 +3c9a483c9bee33b601549c592a82e95b4319b1e74b777877f0971bcb4273716b268e8f99f876e42f942f4cf08284896bbc1ffbf094ac0956c3cedfc3580cffa8c74fc6db29a371f2da2d05edb9185ece741fe0d3fabfe9d5b4d373755ebed13dc6840cfa3283b9ea46ec8b95c434f253ae86998182e9cc0e95ee64f323fc74b0 1320eedad4745121793a7eaf732b0b4498f7cb456cac8cf45a1f66f0 972fc610b8e6945c2e2743034f1faaa76e53cffb768003e9d8e9140c85aa2aa94a480b629b1ded4911cbb303785422dc0c87a1aa5b4c8de27486a316a59fb2f6e0e0b987548a75dd874381323825316d266bac4b9ec17965d4d89c27655b3929 +bfc073fdda63c5fccaa0ca8770c293e8154e7aec56128bbac4fdbd541d602216ebf7ca1e02b514d6e396f20683802ba3f334310a9226576926e3bb19ceee27738d13377cbafeb09d091043501702a07aa31d1f29d50ddc55adcf16ffd40578e734a4e6cb6535f26ad48e0c62ad90e79720000e87d419e92dca3e11f943655b03 e18821329447d3f65ba7279e96bd4624ffa1b32b90f6e8331b1e876d b82ddd7881c4da689a10f53267cfbd39fd21170fff8334726d5f5fc33fdae299a8aa46b230e3f4924af3f1a57499e24a0bdc18a6015d10c969058aa94b025c16be14a152923b475a8103f0593b19219f4cc09cc9a3168478e36d04ae2401f21a +08079955d1a1f33728128c73673ec9f21a6ce138dcab5adc4dc068e6ab57314b9fbd8b013123b2fdafa9524fbdd0288777a233de8055cccfad83046ada6a19f01c47817496667bba8fc8b9456fc0e044a562d931dab1adcb66af8b66325bdf28d83ded3e2937958ccd19da540d70ef2c189f55a506c9c0d63406394c5bd3823b f73e030d5a696b358986d3efaca121cf71f775f8835a21e6135145d7 947336d25d9b0c24b4d2a5079639f77b670d5311016ec455ab7a240be4735101118b0e8f4576f3a5c01bcacb24105a33164f5596b7900d0c1100148eb7b707a8783452c0aae80b7e0db7959edb2e218357262b5955e3d8755b47e916f81e33d6 +23900b768f6cd42b8a8df0dcbc9cb5daec8de36b9d5c619adcc1ba2b649103d5af123746cdf19c3fd0665a6fb9338156182aa06181e3c6e37ce56979612af2927440424f89cef43fc754854b8a5c43370808cf5f9929cf47712512ce2f8a2a20d2e9f568c2848b27dfbe09142843c83905ffa5da3b15501761b03dbc2c5398b6 7a0789323f8741c157a1753ae165ecaf8e8b03a60561f8b80cee467c a58e95d4c3a37a56ecab25efd6e714565c91e49293efd0c87573842af71f110835e0162e5c5a5795ae5e372e84535287109d42738c5f8fc8e453195d38ca6bf9ea8db74d87270232dd9fc4e779599c459852b3f5049525f2f39fa44a26ff8d2f +1eb28c0bcdd18f73e347f957ece15b4cc83a771b0877e1feaac38e24028fb38ccea8b54ee017dc7c3d5a1327bc6f40b294aa65d7dc487f278846cd101ee84202f14b38aa2c275046aa2577f65ebaea41cd383e8def2fd0b4444dcf426fa75c4082cd7fa035cdb1e0d34a3c79d42130f5b0273eae75bc701dda3aebe7358f41b5 78e795d0edb11fd9e28dc26b21e751aa89bea0d87932ef11c95c0e18 a4d891d6b3eb17062b4b16bdf9204f202152fb7e9b7dc51268825b4d7dd27795baab73865385eaa2457412405190eca8156e0f457d3ca9bd6dfd011cc01cf488337149bc7cecbfdee4ffb6d8b4a194f4082d9de628c434b8cee99303ed415f67 +efab51855407438fd5c250670366bca3c026ecec4a59394f00d8a4b51746d0c4564366656d507e3e13e62fe7abeb976b8859895848dbaecf6582f1898ea06f00d4247702ed9721bd375aa83ae4c67c2eaa6e080777ea5ecf2cf787d785389560ac91cf63a52f0373c3185e18a3b8a466e21b61a239f1b77624eb1acacc76c4e1 bee02d8bc5bffb3fd3b4c9d6f686409f02662d10150d1e58d689966a 913c1a2ffa2fc6bfe9d7f5b5de3467e670a2ef112b9c758aba8c4ae41ac07327fa84e20adc31c89a58e93e382b1c65460b6278303fad434b0c2470cc1c493bd60fce7dcc6f55f9ab82a0d14f66140c9c2f1020c1d8a9e779e1c634f5120c8861 +31c29ca10279a417f0cc9b1382cf54dbfdfc89f2e6ef08c403c11f580cbf8674b141ed1a417563282d99a55fc616d836421cde9424815c95e7fb7668bf3f137b29937f14882d74e034b732d78d91af7721aac4950734f5fa5d4b4d35534974f8cab6d2e6dca75ddb57e99148c8a59df9fc5bcd723e546e8356f671cf2f65640a dc0ddf6e501418bb8eafc5d7ccc143369e2aa441df8fc57d5f94a738 98930dd359c1ad101a0155171ab27747b9fdfa192c22be1555678b08e93337c12ba6e92726a3da7cc02e4e55c0a8f1ea083ee06051b8efdbe24fe56ddb16b77caec6401cdc036783c5b1438852ef6733a14285c6e0ad8c1472aa03ddd01beed7 +8db476f92e332519c1a0ece5d8deded6efbd2d8e8784eea0a6b4c3b4296c35f5f8de4317e5c1627b91fb1973fee86c06e4992aa5a20cb7475c8808ff1da354d07a488dffa7838c6ec1e3f99e3acba831f27bee8434eeda3eb36d0c6df3658883cd40068b1bed841310f6eb38d4a3d07d85848770ff7933c054cd8b34662660b1 229d89b2fcf8441ffc95ebb2ac2ef156e25825782044b2b8bd6a3e01 ad80cbc2fab0a31bc147b226282d5bd67f551c8e2bb346c7de300497acb937ea911b1270076bdcb5fe78d3a97eaf9d0c03e7c56672a9a5271a2defd7e0d1cfbb86d253964deb05cb72c185326a42ac9eaf209ab6c88e6702b1c2f0d331f9f53a +fcb272c828fe8fd3c6f8de9410c7b6e2b36717c1b0e5e359e9109bd7fc378978aa98182a9d99961898ed88999b050d3b64d1457d7a899d6d273b9f4dde2aafa36d76329d62509043c338f265fc4c7d938459b7fa3b230a9f6cb632b61489546bb4181a5ad7f0d7369b8caced48eb374b075b2b325bc86add0f3b680cd9e80acd 97d747068147c0393a0bb5c159e2c9f1bd538f6204823294883abe28 a79dbbd57f4ef3d58dc2fdfeef506c77eedf3093a7c205c88b35c2369f8d53d97cd958ca3150e37fb9ab798ec28321000440655737bb2c5ef0358344b16cc03f2f865936ca568f3770dfb235ea566277710796fd9b1abf4dcbfbe3f8af6ca493 +7522492bdb916a597b8121f3e5c273b1d2800ef8c1db4f7dcbae633b60d7da5193ba53a63d7a377b351897c3b24903ae1cd1994211b259be3e6ae2cbc8970e4957fdf782c7d1bc7a91c80c8ef65468d4ef35428f26e2940ae8b0bd9b8074236bf6c00d0ebe83f9ddb2ade0f835138d39f33b59f244e0037c171f1ba7045a96f5 ba5374541c13597bded6880849184a593d69d3d4f0b1cb4d0919cbd6 b41e0cb484ffcc4364ce6534482e7fba1fa1ca21c8c072691d2b56503f5af954e2a592eb79921224e271341e7ac1f47315635b547cfb6ef219f200ba0c7a5b9baaa481a21d50ddf4ac49a906223db13f3d6ecebd88859b9b3504d25030e1843e +61097114ff855c3e34a62d9b853f8982d35f29cfa4a89893badbca7849e5fb437a1a38d6451bf0ca5a0d528e352b8e4b57f2ea359a7fc8841d49dd3e570f9b016f14156b0bbc4be822e260bd147ec081454969e11cb0034b7450ef4deb7ed6edb977e2f4ed60121aa095fb0ab40240dc329ecc917f5c64b4410612af065ee9dd 1e27187134d0a63542adf4665fba22f00cfc7b0a1e02effe913ceedc 955a859a0927677899cf867b8dfcd01c1bd6bfda230354cba6003a518299e7894e02999c2fb263b5090a180c59fa4f9e08721da7f5b88c87d3e75cd3cbfc67cd2208a4358475eac16ee193fc17c4a39b32c3a822034a0a3be0aa7077ae69b9e9 +dd09ae6c982bb1440ca175a87766fefeacc49393ff797c446200662744f37a6e30c5d33ba70cbd8f12277fd6cc0704c17478bbab2a3047469e9618e3c340a9c8caaff5ce7c8a4d90ecae6a9b84b813419dec14460298e7521c9b7fdb7a2089328005bd51d57f92a1bcbeecd34aa40482b549e006bbf6c4ce66d34a22dda4e0e0 0905b40e6c29bfcbf55e04266f68f10ca8d3905001d68bb61a27749b 8752c9bb85f571716c6b283976659602561da5698de1be1d80162283ce53de0f52effdc9938192e3cb83920c7289d74f003d9d284c29c123a575788a7240fbcb5fb1c9d95fa9bd5454699cab2bfe0057e429ca244875af6aa8896859f20c518b +37a73e2774d3b274db426c89b945696daa96035031f72cea01894b24508c7f81961ec254d36ed6a0f448e11cf7950af769dc6cd2c47e52c6caf0ea92c270974f0214b4db436c36a60fb722060a6bb544462a82e1714f5906ec32886f7d59ebf289541c3a00ec1e004892ef2b1286a0194f55d083c6ec92c64b8fd1452e1c68ba afbaede5d75e4f241dd5b53220f3f5b9c1aa1d5d298e2d43236452dc 938f1d943b5320c44923b9fda79811dd557fef5377e256d40abdb8748f816cdc7c591244e4db66cd180eec2bff89e6910c00e7414d28f614c5713a50a52489410ba685ffd17447cd79766ddce35635fe50284daff8eba2b96e7a14c2ab5a6165 +9dc2046ffdc6804544db964481abe5d2d276a2a9eeec4c7ad40215b1de23561d402db69bd0f6eec2254711eea4487c64d9a6b62c3ebaf5ffa8db6e7e3a6e17154d126967a47a853a6f8339bdca9be306a13c7f992ded7619b0da59909a49b1e0930360e05b47f18628a36d69b2f87f2bfddd6a5d4a72f84dc76dbdd43f3a6a35 950b07b0c2b7539a21b5135bfede214733f2e009647d38d8b21d760c a0ea7a4f40ab878487a75131a1396732a419a39c1d047c0086ff909c2dc6b826ae7d2617210832bf75662c19d788352b02f486575342aab84652188414aa75cb7d4a9a6274a7ecaaddcd766b12f82fbf56a95985431e83178b1b50b2c61fd633 +d9c6847fce688c5e7525a1098b545cb6c15dcd21a02761fc82fc664372a667390680135f91c01a2fa5430c634b1a6d1cd6002d8aa021e7bf5956a7901c2f81bc25d502ba5f55a55f30c0323dc68205cbefec0538e68654e7b327ac1743641896c3e740d8f66f400902b304eafaa4e0d8cffae140536f0922444cc3216a675697 015bd9f5dfef393b431c3c7fced24385d861ccb563542574a5d2a9bc 93706d079e21fcac56b77ce5f3041d79548a7ef6f08da4aa7524cf17859796868060f64cde3dac113210bd3cf0944667013d4b69cfa90064550b396b69f3d878ea4dc5ce57aaa8d039e398977bd34a64c0a793c67c5651efe463a4ab0cfd98b8 +69df8a01b66f04930efd2012ff2243874f256ca8758145d2a9e4ecc84d0dbdbd0dc494ae06db0ccbe819918137c90957114558580d6623efbafdd342b38dad9f08708084d32f874fba04782ce26aaab78de2102ad171f8a8f2b30b5bd3d55fdac5fa3acd6f7def7e61c2533938572b331ba6d1c02bd74bfdbf7337ade8f4a190 0a3c259df933247445acffb6d8265b601d597fb9997dc2a1eb4deef4 8458737c3e51dbdb2f12bd7d4fa3e8686056b34fbace242d4b1e64138fca557d80280caf1d8cef750b5da80ab76e55be10d68f0c81a7b37a67bf9742248cbbac27762122593fe76c0ceec38137990d7bdb01881605333eca1e67de996f9dc048 +927524982b8d60777c1105c86fac05f634abf58c73f84fb95d81ba0b86e1e43592c4fcad2e395a40fbe7005697d86088e2fb3bb7287eb3f917d4f2dc281f5cbe65d05b4f9623bca849b10a03beca6aa2056a12ebb91cf257ac448c5e9a78f8349a6a29b17c8978bef43a443cbb8a149eb23f794844fc41693f2dbb97181444be a1c8ef463f9e7e3dd63e677412f87cf9ea4ac9a6a2dae629da5b9916 ab0f00c9fbd8afaf765b5b7386df3acd850a07703784c7a855b2436590c518ebb86fc019a8667392f9fe4806939a45c204b48a1bd5e4a418e0d716991c6a50f6b02d2a6923db3afb66deeecfb103587ae88b72fc8974478bf59815b682fa29e2 +5f9042283561e7f19a436d01c7ef5a950a6d77ede5629cd7e43c0a5d58e8c5673c37945a453291d12938253c71dbe12c8b022ba7276eda6be034ef5ec1ec77dbd1e08f0d7b8e7725b7ec671c075e008a20f77f4ab266f97079b0aa6337df59a33b881954084057b21f294dd14bcb0869a4a6f1f597955ec7bf9d19bb3537a66a fa511dbf6fef7e5e9c73e4555eb75d435f7884322d9faf5d78cacc0b b31d02adefee479c3abe3a1f91cf05b908dae7ece01fcf3b4dc8193d981e9279e26fa256b3c7f1b25cdce9b4299482540544a34e16b954e96290ba76143ef055ab939461317a0fec33355fd87a133e3a4c2ede25a441d10bfd81041f1733fe92 +c2ae5573d3bf396523bfb703db8502fd0760cd1be528f6ddbfb95aad399e0b19f3bd9e0fabdb05d49e3f893dffec5b627c9c2f7ad5f32e92e4e27a38cb5c28657657377fdfa1b66cd7ac3d15c6d49df92d284db99f69744f37dc7cb4e7d52920fdb200a7942623a7057ba82e467dcccaa5da416b48510d8364446a6a5e2a5aa8 a58bd53646400a646f0e4208320dc679a9664d1c6bfb27fdc8eac7ea b5ce010a4cc0a0531130a8696806310e293271508e81ffc5ce95175b8f03cb72b463b20f5c5df9407aecffda50e278ae11cb5fd69082e008a4c7b9b938726601e3d2c8b4bfea57ed7ae71f72d85a884cdebe118c4d0ada0aefafcf71fcb68358 +03c1a1cd30a039d0dcb22fee2450a7fa79495a0d0f4f43d2de4d75bce003c0334a8860f5c164dbd94888a9f751235a3e570d31070e3e1293a7be616af7176600585d36ac013600157d2569d491da4b8a3bf3630c26e0b9925412189f50b0ae6f04c86477932e2ecd8c3546106ae1ebc684cc3adb27ed665eddece886adea4ce3 64bd4452b572cc95510ac2e572f41136299ff17f6e8448f4ffb571d0 a9b1e7214e54b65e49ef3adecdae3a4ab653fa0d6209ad47037ff6a8168eb01bbce5534f566d5858d75779439ca6d25b1700e0aefb11250b51a3a9b504d243846750c6e3251d4df0021dc6c140e343620f06de6bfc2eac9f52e81c3bd7bbbea6 +888f6d9bc7c86c0079fbfd42d8c08d6958f40f6e570fb0b1f03d2f8f8a63df4fcc87b379a222cf835820a999d34996e08961f13b86b075e7fd1c303cd3baa44de42168561589012f7e5300da4f8bdf470c07119a5d9f7ba7293568cd7c6a1b7fc1e41cda40bed7d46e5a28af67ae2aabfefe67a86a1c601e6f5ee543e09bd7b6 7f3edb710df9d982f486233d0c176aa88f5a0ee81efa9b8145020294 b54d7fccfd6ee52a71862acf216517ebec9351017d568ed49a4d93078ed7c4531aa954720ed75e14f075f958bdda67b1057d71fd85bb13079831e5ec6f87b165ac047a2be283a856af23e53b605c3007a527b963a212d6ff2479d3f9b7450bde +48453340f1317769e6ee6e103153714365731163dc18f84e9f2fa4b120f9c5a9645ee2f9b66c84c26d95912b422b009b64af96aa418b2427a4209f2e7513ba8e43ec8cf20b34e7529b22eb1199545afe9a9f7d9bcb320aec9ee0162f91c0d1dd9674c9c284f25199c5e109f6f84d7ed0d269cc6413edb81bc2c83e37d644d8b9 b569f8296ff1d9cc01fffd9919016e5730c1858bdb7b99527153751a a7ea2605bdd53939a57412b0b3b9c1e5af36c8a99314c1910f3883929925c4b46ee5e71a8f6ab7a0fa3fcdef47cf43361756bc441d8993a363e7091877f351f2e0ceb4648f14e1cae338c7d9dc82c7ae919399f92f80b5cce13e0ba3a0ee5d00 +4bdfd3b91d83108409ad765b256e0c9b9937ecf647f8e6f9fc807e2e72af8246178b3fe046b4ea10170450d71a4eec790ecb05f03d7077341de26c4db7eeae24d55c9a9093e837dfdb38168fe8230cb9605825a1282fecd741989bfcdb34678fe077477927f66bd26d003e5dda22043341a14dd31841ba483ad5ce2701e0f68e 41a4dd8eee39232b728516e2f21e66011e7426a6b25986c3ffa237e4 8fd88f2da1baa57a1fd9aa93151e830b33bdbee7160f09930d7649e8b43aabd93ecee83a1ae8805b6169513ea6efbdd503c27ccd748c7f914bdbc64db1446ef76463b7b19270d44476b4b0eec4a89611d98995fc564d3012dc467b04d62e2469 +e6cdee8558bc1eacc24e82f0624ce8d02cc8d925b4dd3dec3a72f4a4e0fb76076bfa3ef2e2c33bdd7c27b322bdc09bbfee8fe46f75dbd7bbd2af09690b7137943efe21706e0a1b6d3089540fc58d85ddb55ea836616db573e36c521be008893f40a0a7c349602cc178ea43be59d31ec6449e7ff2c5379379f7d7645134df1bc3 67fa50569257c8cc89ac0325db4902003a62f30b917f53e4035a7e04 a7d43ec72c8869d0fc85fdd1656b976eb9c74c252c099b570cb334926d0544474817612e5709913b1a19e1804cee61e412888058577505decb68dc2c4af3a9a7332428295e092c2a8b03117fc4f686c9ea6defa0bd575aa432e2e50113c2fc55 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P256 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P256 new file mode 100644 index 000000000000..bafd9e2278b9 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P256 @@ -0,0 +1,60 @@ +ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590 a670af25edd3b4bc0ec7604779082eeadd7eefc84f52e830034626584636219660434c70359d664ff682799c45962ba50395815dd223e2b25ea4286f16d86590622815ecfd5c6cc4845de200ecc4aba189715abe0fe5c365572de1ce415042c0 +9155e91fd9155eeed15afd83487ea1a3af04c5998b77c0fe8c43dcc479440a8a9a89efe883d9385cb9edfde10b43bce61fb63669935ad39419cf29ef3a936931733bfc2378e253e73b7ae9a3ec7a6a7932ab10f1e5b94d05160c053988f3bdc9167155d069337d42c9a7056619efc031fa5ec7310d29bd28980b1e3559757578 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98 b6300daa5cf00adb5fce357d8d6504667989b98226e0f648583c951aeacc700a82e3f8d1005e5cfe4ca0440c60ec437a175734d0c95752e3c6044dff87140c740632b824186c1733cf98d05a2e7553420ddb0e5f2747a8dd79235c1b8317f1bf +b242a7586a1383368a33c88264889adfa3be45422fbef4a2df4e3c5325a9c7757017e0d5cf4bbf4de7f99d189f81f1fd2f0dd645574d1eb0d547eead9375677819297c1abe62526ae29fc54cdd11bfe17714f2fbd2d0d0e8d297ff98535980482dd5c1ebdc5a7274aabf1382c9f2315ca61391e3943856e4c5e616c2f1f7be0d a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870 89150d05f794a88695bc173e8e794822ffd0a29959dceb35ffc39a80b7b04f37050a0822f752550f147d081c088cc59312c33dc611e02c28c0eb861460637bdc927a76cdda573a5d9c67a2351e3fdc96dfee44d8631855772955f40af15ed02e +b64005da76b24715880af94dba379acc25a047b06066c9bedc8f17b8c74e74f4fc720d9f4ef0e2a659e0756931c080587ebdcd0f85e819aea6dacb327a9d96496da53ea21aef3b2e793a9c0def5196acec99891f46ead78a85bc7ab644765781d3543da9fbf9fec916dca975ef3b4271e50ecc68bf79b2d8935e2b25fc063358 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f aeb52348b1e95d30265ec740424752cc1231c2e6b4e566e9bb8ba48bd84aaa14f123a2a5364e8bd5ddb8213f807851290f7db28ec7260ad41b7f40ed45fd6a408e9ffc1c0f8ca5661e0955ced950b390546182a1046aca04281ffe20cd9a3a67 +fe6e1ea477640655eaa1f6e3352d4bce53eb3d95424df7f238e93d8531da8f36bc35fa6be4bf5a6a382e06e855139eb617a9cc9376b4dafacbd80876343b12628619d7cbe1bff6757e3706111ed53898c0219823adbc044eaf8c6ad449df8f6aab9d444dadb5c3380eec0d91694df5fc4b30280d4b87d27e67ae58a1df828963 daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d 8715558e462af86f3083e7355ac185b0b8f8d207a8ac427edf829c687bceca21d01b966f8c80d4a94c03c51bc3f802060d31810ce44949e07ca7a95d9f5e4b8141d82cc59996f833baa5cb908d9c03c35d0cd5cef46741c10d0c126be38c43c9 +907c0c00dc080a688548957b5b8b1f33ba378de1368023dcad43242411f554eb7d392d3e5c1668fad3944ff9634105343d83b8c85d2a988da5f5dc60ee0518327caed6dd5cf4e9bc6222deb46d00abde745f9b71d6e7aee6c7fdfc9ed053f2c0b611d4c6863088bd012ea9810ee94f8e58905970ebd07353f1f409a371ed03e3 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5 91f42489661838691b42f97d8bc803d22ab816921b29e0c2ad9e36b15299a9d9c4413e32aa106bd7029c4a7419ca17b613676530c093f88017b400deaa85a5a6bbf7b9e24d207715e1213b03c619fda90b621bd0606f11f3bf75c8bc5b17876b +771c4d7bce05610a3e71b272096b57f0d1efcce33a1cb4f714d6ebc0865b2773ec5eedc25fae81dee1d256474dbd9676623614c150916e6ed92ce4430b26037d28fa5252ef6b10c09dc2f7ee5a36a1ea7897b69f389d9f5075e271d92f4eb97b148f3abcb1e5be0b4feb8278613d18abf6da60bfe448238aa04d7f11b71f44c5 f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96 8a116486bf3965a1f778459bdb857d30da21563c904aa1c166579c273fec3bd1b3898ccb2a96e8f1b8af9ddc4031f644157e7036c6eade5e5894cf8831a59fb2572d10c0468db9cc31c05e4e9d109b8608771dc1f04bf0f66458b892fd4dd1d7 +a3b2825235718fc679b942e8ac38fb4f54415a213c65875b5453d18ca012320ddfbbc58b991eaebadfc2d1a28d4f0cd82652b12e4d5bfda89eda3be12ac52188e38e8cce32a264a300c0e463631f525ae501348594f980392c76b4a12ddc88e5ca086cb8685d03895919a8627725a3e00c4728e2b7c6f6a14fc342b2937fc3dd 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d 845e49b08d24d1445276ab74a7f560492fb2eac7bd39c4d14066b9214d67b3c7c4c5054ab7e9a87012ceb725fb6ba01404828f7b5905762aac65b3a2cd2f4da80d0e63f31d0e8ce894ccc1d642fe9cb5088bc59ecdbd2b22babd16d89bb05b6f +3e6e2a9bffd729ee5d4807849cd4250021d8184cda723df6ab0e5c939d39237c8e58af9d869fe62d3c97b3298a99e891e5e11aa68b11a087573a40a3e83c7965e7910d72f81cad0f42accc5c25a4fd3cdd8cee63757bbbfbdae98be2bc867d3bcb1333c4632cb0a55dffeb77d8b119c466cd889ec468454fabe6fbee7102deaf 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9 a81dd88c51c4fd716d2af2bce2199177bbacb35c2bb2ea03ce03d9d67b5e8084ddd9eb954f7704cc1d8a94fa296a365207a750d16dc1d2be472d9c3b6ac05ebc2716936ccaa6842b41f6e2437e62af7ca90296d4397c168e411740c6e89b57a8 +52e5c308e70329a17c71eaedb66bbee303c8ec48a6f1a2efb235d308563cd58553d434e12f353227a9ea28608ec9c820ed83c95124e7a886f7e832a2de1032e78dc059208f9ec354170b2b1cab992b52ac01e6c0e4e1b0112686962edc53ab226dafcc9fc7baed2cd9307160e8572edb125935db49289b178f35a8ad23f4f801 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634 86d2a5aef51d706bbd068f338c2dc20b7581eb01b106c108763907c1dddc17ff2dbdcf8a52ad6c22b54df60a0a812b500d610d038d4c369229b2c63e6ea7ff86dd4f9897ed87ab59e12386eafabcd0f9fcce32e7057fb049fefed95a70424982 +d3e9e82051d4c84d699453c9ff44c7c09f6523bb92232bcf30bf3c380224249de2964e871d56a364d6955c81ef91d06482a6c7c61bc70f66ef22fad128d15416e7174312619134f968f1009f92cbf99248932efb533ff113fb6d949e21d6b80dfbbe69010c8d1ccb0f3808ea309bb0bac1a222168c95b088847e613749b19d04 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27 8f58501641fc029c93615d193c64781d62ba46fa395521582aa4a9e2c356828369c88ca27ff3d4384752c05df387042501d48a6b12981047ea0dc4b31c9e531b8f412e70e961b6cc4abf6cbc452eb8c33410c2306a7b80e8197eb75f7525887d +968951c2c1918436fe19fa2fe2152656a08f9a6b8aa6201920f1b424da98cee71928897ff087620cc5c551320b1e75a1e98d7d98a5bd5361c9393759614a6087cc0f7fb01fcb173783eb4c4c23961a8231ac4a07d72e683b0c1bd4c51ef1b031df875e7b8d5a6e0628949f5b8f157f43dccaea3b2a4fc11181e6b451e06ceb37 cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d 99313369e88bdc6da18d19adc33db7be28b08d0d83afb452fef829ec17e3deedf30db3773c23469841ab100caa180edd095205faed72d6f711738c097a7474d24676cd781d101e3f71fb96963d4685c27dfc1e9bc5d5c92ae27135a3a420a67d +78048628932e1c1cdd1e70932bd7b76f704ba08d7e7d825d3de763bf1a062315f4af16eccefe0b6ebadccaf403d013f50833ce2c54e24eea8345e25f93b69bb048988d102240225ceacf5003e2abdcc90299f4bf2c101585d36ecdd7a155953c674789d070480d1ef47cc7858e97a6d87c41c6922a00ea12539f251826e141b4 b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c 8402f63e0d9977e91e7e5e0d31613545fbcdea535df2907ee1bbc513078c9282181b687aea33fd9e78b79beeef96656c0f2412465d81f525ca66c666de70c51f6354aebc87b5bcbbb5ba06edc67e26392b8e8c9429f9ea5f42b388d3f9e2a99b +9b0800c443e693067591737fdbcf0966fdfa50872d41d0c189d87cbc34c2771ee5e1255fd604f09fcf167fda16437c245d299147299c69046895d22482db29aba37ff57f756716cd3d6223077f747c4caffbecc0a7c9dfaaafd9a9817470ded8777e6355838ac54d11b2f0fc3f43668ff949cc31de0c2d15af5ef17884e4d66a 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48 ac0653ef2634c60925a950c3d8489d511a74ca1e17d2f6545b888edf76113479349cbee56f6475dc049a519cec95d9740728607c882f8aad02e492186e48a87a6284c284fedc0b5ddd486fb649066e11bf543a5ad86249f570babd4dbf43b679 +fc3b8291c172dae635a6859f525beaf01cf683765d7c86f1a4d768df7cae055f639eccc08d7a0272394d949f82d5e12d69c08e2483e11a1d28a4c61f18193106e12e5de4a9d0b4bf341e2acd6b715dc83ae5ff63328f8346f35521ca378b311299947f63ec593a5e32e6bd11ec4edb0e75302a9f54d21226d23314729e061016 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f 96b241d26e735926c2896dbf28b73d878f82b4e7a59114824f23d057faaba5b44596a73210e8503a80bd8e66cb3a11421849d05911290409909ee35240dadf3d3435b215a4b33024450a97de0b99d6c90997a1f3c4d4c81a93a74e463cdd2601 +5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 a0219030499bfbe55cb33e809b5fd14ad08c8a18e04e3adbedf078403873d6f2a056dff0c0656773487ee43b4113f1af1001411ca65ac7b2c86df1188185dbaf139bfa2d6b8468e418556164c4214646d658943cd55181243b8f135efa718fdf +c35e2f092553c55772926bdbe87c9796827d17024dbb9233a545366e2e5987dd344deb72df987144b8c6c43bc41b654b94cc856e16b96d7a821c8ec039b503e3d86728c494a967d83011a0e090b5d54cd47f4e366c0912bc808fbb2ea96efac88fb3ebec9342738e225f7c7c2b011ce375b56621a20642b4d36e060db4524af1 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 a42bea190e5834624c2cea30643cc92f214b73b59f6806448a2cb6cf89968e5da34bb7f9b5c78580ecc3e33a65af9f090769e0e553420426aafa87bdbb627d1e032d0d053bb1bf0f54ea7bdb1ed58a82bc3358c332d2d4adb8477b56fef54423 +3c054e333a94259c36af09ab5b4ff9beb3492f8d5b4282d16801daccb29f70fe61a0b37ffef5c04cd1b70e85b1f549a1c4dc672985e50f43ea037efa9964f096b5f62f7ffdf8d6bfb2cc859558f5a393cb949dbd48f269343b5263dcdb9c556eca074f2e98e6d94c2c29a677afaf806edf79b15a3fcd46e7067b7669f83188ee e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef 9519069c806f2a51348df6c0af02de3973b5e80cc3929995934a04a219f1ae5f79e7f9b0fb3656ffd032f48cfde00d9418fcbd8b814125405400ba8eaee95c9ec6871c281e0db25fd0eed5aa258d2f0d5e86d857ab9d04ec3b71cc9fa1a090ef +0989122410d522af64ceb07da2c865219046b4c3d9d99b01278c07ff63eaf1039cb787ae9e2dd46436cc0415f280c562bebb83a23e639e476a02ec8cff7ea06cd12c86dcc3adefbf1a9e9a9b6646c7599ec631b0da9a60debeb9b3e19324977f3b4f36892c8a38671c8e1cc8e50fcd50f9e51deaf98272f9266fc702e4e57c30 a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 a127e214f88c7e56efbf1d756a4b972db232967d9a09cd28ebf0541f644809f897fe9a4dc41c1327346420ab1f9b72150d4cb46b8917f9e527312311bb854bb5d7dcbcb7dea25a0167187305a73e23a6764dee14c0ce7ed04ef07bad988ced0a +dc66e39f9bbfd9865318531ffe9207f934fa615a5b285708a5e9c46b7775150e818d7f24d2a123df3672fff2094e3fd3df6fbe259e3989dd5edfcccbe7d45e26a775a5c4329a084f057c42c13f3248e3fd6f0c76678f890f513c32292dd306eaa84a59abe34b16cb5e38d0e885525d10336ca443e1682aa04a7af832b0eee4e7 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d a6751474cac6ebb666bc94e3b3ff7fdd5c47ea32829afe82cbe64b94557f7e3ab71e715f8e19ae9cb9f2c415c2d1632c06bf7e2e001ea8159cf9ab50cada99d9f01250d2a8968de480a932f014938d62adb0bed6dea21a101d60090e09bd1656 +600974e7d8c5508e2c1aab0783ad0d7c4494ab2b4da265c2fe496421c4df238b0be25f25659157c8a225fb03953607f7df996acfd402f147e37aee2f1693e3bf1c35eab3ae360a2bd91d04622ea47f83d863d2dfecb618e8b8bdc39e17d15d672eee03bb4ce2cc5cf6b217e5faf3f336fdd87d972d3a8b8a593ba85955cc9d71 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d 87fa82a9993c4f729f2b69675dd46ce96488b9e1ef3ac6596cc2b26531364884ca33d80ed638cb83b34b65d90ad18bcd0734cb88a09188fd664b3b006b7caf6b3419993726e059a9221d8737e2d0bd017f4fc1ef89af77a2317a8cd253a21c05 +dfa6cb9b39adda6c74cc8b2a8b53a12c499ab9dee01b4123642b4f11af336a91a5c9ce0520eb2395a6190ecbf6169c4cba81941de8e76c9c908eb843b98ce95e0da29c5d4388040264e05e07030a577cc5d176387154eabae2af52a83e85c61c7c61da930c9b19e45d7e34c8516dc3c238fddd6e450a77455d534c48a152010b 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab 83cfd26d2bd54ca5890e62c4d9a82a4130022e342d3dabe9be784eda9aba3184f621ced00b3536b2940777702da35e0d0e6766858fa7913b3fbcb1476e58406af3e4b3f2a1ce294e3dee667c20c26ec6aee8bcd59847c9999924950278a28945 +51d2547cbff92431174aa7fc7302139519d98071c755ff1c92e4694b58587ea560f72f32fc6dd4dee7d22bb7387381d0256e2862d0644cdf2c277c5d740fa089830eb52bf79d1e75b8596ecf0ea58a0b9df61e0c9754bfcd62efab6ea1bd216bf181c5593da79f10135a9bc6e164f1854bc8859734341aad237ba29a81a3fc8b 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a 8026bb404cea7ae6742bbb39229eb613e87a21984a20b1cc97a22c5621078b752bb428cb929c2a62693578c4c095558805bfff69f5915c7ed989b1df703adbc57f2dfb2646aca1398bc57fe93e2c3b8249a6e20e5f45951e40ce7e692a2eb4ad +558c2ac13026402bad4a0a83ebc9468e50f7ffab06d6f981e5db1d082098065bcff6f21a7a74558b1e8612914b8b5a0aa28ed5b574c36ac4ea5868432a62bb8ef0695d27c1e3ceaf75c7b251c65ddb268696f07c16d2767973d85beb443f211e6445e7fe5d46f0dce70d58a4cd9fe70688c035688ea8c6baec65a5fc7e2c93e8 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 acf75c714756247b5de117103d72e3081b5d9357848f07f05aa5ab90cc455d7fe69aadcf051335d39021c04d3a05dd050e60d422dc860877f04f4ac0d48de7e67026b6d7d1c689e255ea6144298a2ff742799630584948db32089dced889e56c +4d55c99ef6bd54621662c3d110c3cb627c03d6311393b264ab97b90a4b15214a5593ba2510a53d63fb34be251facb697c973e11b665cb7920f1684b0031b4dd370cb927ca7168b0bf8ad285e05e9e31e34bc24024739fdc10b78586f29eff94412034e3b606ed850ec2c1900e8e68151fc4aee5adebb066eb6da4eaa5681378e f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 84d6776c83d7283780f13b56ea6504746ad734a812bf9e4ed588ea1a1b664c483b9b9bfa08207a069575e883e0075c8912494e50b311ee470ff59ec9a07c9f85f07f4558014cad04a1205da7a587f84f19c8c8981547c2c5e2df52db44e9d42b +f8248ad47d97c18c984f1f5c10950dc1404713c56b6ea397e01e6dd925e903b4fadfe2c9e877169e71ce3c7fe5ce70ee4255d9cdc26f6943bf48687874de64f6cf30a012512e787b88059bbf561162bdcc23a3742c835ac144cc14167b1bd6727e940540a9c99f3cbb41fb1dcb00d76dda04995847c657f4c19d303eb09eb48a b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 a16f75554da42ab535c8daca419a2929d64ab3f710f5f9e14cd734c3c12ec127262f06edfa7f40db0c57e64c0ab206b80e0a8e83fa6cd3bd4563e92466aa2340d97b95cf06797b93af50c04cbe29785def15584a4d3cce9bd129cf03f6913c2f +3b6ee2425940b3d240d35b97b6dcd61ed3423d8e71a0ada35d47b322d17b35ea0472f35edd1d252f87b8b65ef4b716669fc9ac28b00d34a9d66ad118c9d94e7f46d0b4f6c2b2d339fd6bcd351241a387cc82609057048c12c4ec3d85c661975c45b300cb96930d89370a327c98b67defaa89497aa8ef994c77f1130f752f94a4 d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 b7d16791bfcf8021ab24bfe6c44822500afa66902389d47a71afa7afa801ead48040dfc443a901a3ebeb59aa0f3de945120d64b1fdacc0195dd7baf5d23847dd5f88d456799cf66a21c814cde02e3df5f8297967330c1d5e8741bd769fd6512f +c5204b81ec0a4df5b7e9fda3dc245f98082ae7f4efe81998dcaa286bd4507ca840a53d21b01e904f55e38f78c3757d5a5a4a44b1d5d4e480be3afb5b394a5d2840af42b1b4083d40afbfe22d702f370d32dbfd392e128ea4724d66a3701da41ae2f03bb4d91bb946c7969404cb544f71eb7a49eb4c4ec55799bda1eb545143a7 b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c b4be8e948732f31e8153bb15578be8ea0ac6db10b29a9e53bda4c6487bcf336a001247eff3f403c78f271fccf1b5824009f906b70c754029863db96ea55d1ee3cd8ba72f155658d89b9a6706193f606e2c10a6129c893c170532a308ebab6525 +72e81fe221fb402148d8b7ab03549f1180bcc03d41ca59d7653801f0ba853add1f6d29edd7f9abc621b2d548f8dbf8979bd16608d2d8fc3260b4ebc0dd42482481d548c7075711b5759649c41f439fad69954956c9326841ea6492956829f9e0dc789f73633b40f6ac77bcae6dfc7930cfe89e526d1684365c5b0be2437fdb01 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 8e404a80fc9f0aa942ed5f61576918e9bb61736215abeb887d5f3a0b7180eea314274fddb4914b358b4838c87c83d0ea00826a9b3fdce40543075e19114ebdd33e6a9797a98540b1347d0fa5c078b585f92d465cbd26ad687206f4099cbf6447 +21188c3edd5de088dacc1076b9e1bcecd79de1003c2414c3866173054dc82dde85169baa77993adb20c269f60a5226111828578bcc7c29e6e8d2dae81806152c8ba0c6ada1986a1983ebeec1473a73a04795b6319d48662d40881c1723a706f516fe75300f92408aa1dc6ae4288d2046f23c1aa2e54b7fb6448a0da922bd7f34 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 9809142d31e18522c2a0dedbd9a1d2a47bbdbc28a7f2285111125feb52da7bd0eaecef7b1cae72d0bc162efb883f9d000d3a4644bc680fac7b94d8497af4fb10b8464a88d9698de322adf27fd6b8621c92d9576e887c67b0193193d8bc9912f1 +e0b8596b375f3306bbc6e77a0b42f7469d7e83635990e74aa6d713594a3a24498feff5006790742d9c2e9b47d714bee932435db747c6e733e3d8de41f2f91311f2e9fd8e025651631ffd84f66732d3473fbd1627e63dc7194048ebec93c95c159b5039ab5e79e42c80b484a943f125de3da1e04e5bf9c16671ad55a1117d3306 b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced a16b65f77ec4edeb598bfeeeee8f0629e88626854eec9e319d996f8b57bee37d36a29cde7a03769d775cd28da9e32ff6066e34bdb3e7c21a98c434f203334a34cdb3e1620b18df3c30708f56885a704be3cdd7cda3fdbefc525367ec90550149 +099a0131179fff4c6928e49886d2fdb3a9f239b7dd5fa828a52cbbe3fcfabecfbba3e192159b887b5d13aa1e14e6a07ccbb21f6ad8b7e88fee6bea9b86dea40ffb962f38554056fb7c5bb486418915f7e7e9b9033fe3baaf9a069db98bc02fa8af3d3d1859a11375d6f98aa2ce632606d0800dff7f55b40f971a8586ed6b39e9 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181 987e3d84df11d5f291ed77a994dafddda41d9a6ae8f3e21849f6926d38954325f14b86f0a5e10cb753c31f55366161b41556ddc3750babdc5770c9a5b2b33a454312ed0b9396d37ea0bd16a5e323beab271f62707c5421985d53a53351955bc6 +0fbc07ea947c946bea26afa10c51511039b94ddbc4e2e4184ca3559260da24a14522d1497ca5e77a5d1a8e86583aeea1f5d4ff9b04a6aa0de79cd88fdb85e01f171143535f2f7c23b050289d7e05cebccdd131888572534bae0061bdcc3015206b9270b0d5af9f1da2f9de91772d178a632c3261a1e7b3fb255608b3801962f9 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431 b00c16e2ed6dae77cc0e03f165670dd27c86bca98275847b58d3cdae2a2fd8aeee421f9515b4c3e411f49e72403a70660119e09fa7c94fe8e05b161fab41d5c2d5de8ea9227b10717654909e1d2845bd83f7a9ced1909764ea53151cc6d4158a +1e38d750d936d8522e9db1873fb4996bef97f8da3c6674a1223d29263f1234a90b751785316444e9ba698bc8ab6cd010638d182c9adad4e334b2bd7529f0ae8e9a52ad60f59804b2d780ed52bdd33b0bf5400147c28b4304e5e3434505ae7ce30d4b239e7e6f0ecf058badd5b388eddbad64d24d2430dd04b4ddee98f972988f 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd 8e8ee9057158eeef4b64c3b1a0458cba3a5fa2f9263b008ffae6793a905f88d782d8161889687505e0acc243a68328841901823d2df18d2e86aee3a00ced2ff0b869733aab6cd4dfdcba968838b1286288293058b585b277cc7cdd97b782a440 +abcf0e0f046b2e0672d1cc6c0a114905627cbbdefdf9752f0c31660aa95f2d0ede72d17919a9e9b1add3213164e0c9b5ae3c76f1a2f79d3eeb444e6741521019d8bd5ca391b28c1063347f07afcfbb705be4b52261c19ebaf1d6f054a74d86fb5d091fa7f229450996b76f0ada5f977b09b58488eebfb5f5e9539a8fd89662ab 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de 908566d1f1be150fcb32922e03036b4c26344d11dc54640989fa5959dd5cb26277df05859c1319f5a76a51649248d18b0c4469f96479b0e5fd6df9e4916ee18248ec6b463ec9c216a97be673a9e2d2f4bcf53610668dd604ba081c1fc588aa7a +dc3d4884c741a4a687593c79fb4e35c5c13c781dca16db561d7e393577f7b62ca41a6e259fc1fb8d0c4e1e062517a0fdf95558b7799f20c211796167953e6372c11829beec64869d67bf3ee1f1455dd87acfbdbcc597056e7fb347a17688ad32fda7ccc3572da7677d7255c261738f07763cd45973c728c6e9adbeecadc3d961 ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566 a1de6a07951b2f3ef906f61f82a9aa9f7dcbf4890e5dcf744d09c6d17b31429bbc9108ef599ed0b9bbf9650c4c78c9f512f916ef124ac0ab77c8a8503fc032fb73696ae86c2fe52a57724e9989b1757dad5af8b2ea357c6e3c726c29fc6764be +719bf1911ae5b5e08f1d97b92a5089c0ab9d6f1c175ac7199086aeeaa416a17e6d6f8486c711d386f284f096296689a54d330c8efb0f5fa1c5ba128d3234a3da856c2a94667ef7103616a64c913135f4e1dc50e38daa60610f732ad1bedfcc396f87169392520314a6b6b9af6793dbabad4599525228cc7c9c32c4d8e097ddf6 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee b0ca4050d55cddcc6ad552a2cdfc098687a9c01e44c39e4225651d7d668136a09f6242398632cdf19d433d58a0518b7218084c055d5db045ca9039db0dcfd0f8675cbee6f4a3a1032ea40061b4b1a92f97b1faa2452d88ec58ba328f93225c74 +7cf19f4c851e97c5bca11a39f0074c3b7bd3274e7dd75d0447b7b84995dfc9f716bf08c25347f56fcc5e5149cb3f9cfb39d408ace5a5c47e75f7a827fa0bb9921bb5b23a6053dbe1fa2bba341ac874d9b1333fc4dc224854949f5c8d8a5fedd02fb26fdfcd3be351aec0fcbef18972956c6ec0effaf057eb4420b6d28e0c008c 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd b77eaca6966c00b36468b14de400b9b86c2cb15c1f28a7ebc3dd2737e32396988439e778f2b53da1f451ce927f68399a0a203c7121c65e1d49e4c13c6164116ae4b4677f88f0cfde2b08d95c6441341b87b76315ecf74dc2920e213e8947e35d +b892ffabb809e98a99b0a79895445fc734fa1b6159f9cddb6d21e510708bdab6076633ac30aaef43db566c0d21f4381db46711fe3812c5ce0fb4a40e3d5d8ab24e4e82d3560c6dc7c37794ee17d4a144065ef99c8d1c88bc22ad8c4c27d85ad518fa5747ae35276fc104829d3f5c72fc2a9ea55a1c3a87007cd133263f79e405 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666 a4f8933d3404274f711730582532beb0d9a55607f522202b640dbc653652676b2541a00e13e3113d9289e1d6a5fd754f13494157cb063ca93755558d0842ac96704fcbbc23999d6a512102ac78e2d3a92e35fb2123fe7e9ea50e7db2a283e2af +8144e37014c95e13231cbd6fa64772771f93b44e37f7b02f592099cc146343edd4f4ec9fa1bc68d7f2e9ee78fc370443aa2803ff4ca52ee49a2f4daf2c8181ea7b8475b3a0f608fc3279d09e2d057fbe3f2ffbe5133796124781299c6da60cfe7ecea3abc30706ded2cdf18f9d788e59f2c31662df3abe01a9b12304fb8d5c8c bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67 add64a121b455090dcef47a41f460ba9cb4c459570a1d997310410234e9622c97eaa268588d18f2ce904af89b0123a920aae66877013f472f42cb76748c3e92d6e246369c7ddff0d094fb3796b4058e7ab8a53db8814e17d393b471e66ce850a +a3683d120807f0a030feed679785326698c3702f1983eaba1b70ddfa7f0b3188060b845e2b67ed57ee68087746710450f7427cb34655d719c0acbc09ac696adb4b22aba1b9322b7111076e67053a55f62b501a4bca0ad9d50a868f51aeeb4ef27823236f5267e8da83e143047422ce140d66e05e44dc84fb3a4506b2a5d7caa8 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9 a4c36e53d86550373597ed9615b32a3f9040dc3b43d3915fcfe631ba0fa547af8ff5048e1b2d8b1922d934b607d4dbc5123c2713d496d4a12f63b244e058d6f455d9258af56b177f7d507001211e2fbdd19c1825d56cbeb72dc763f252477cb9 +b1df8051b213fc5f636537e37e212eb20b2423e6467a9c7081336a870e6373fc835899d59e546c0ac668cc81ce4921e88f42e6da2a109a03b4f4e819a17c955b8d099ec6b282fb495258dca13ec779c459da909475519a3477223c06b99afbd77f9922e7cbef844b93f3ce5f50db816b2e0d8b1575d2e17a6b8db9111d6da578 f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce a5a94446aaad2a29238a1627d947ba639d13499f4b2be272d6e64b8661e42f76f2457c42968ac2407d2ef0368904494411b68d0a46fb8cec3b810fa8a77c6c56678d45578a0ba7b3efc7212fd6011400013c9fb40e6ddac46af4798dbdee2342 +0b918ede985b5c491797d0a81446b2933be312f419b212e3aae9ba5914c00af431747a9d287a7c7761e9bcbc8a12aaf9d4a76d13dad59fc742f8f218ef66eb67035220a07acc1a357c5b562ecb6b895cf725c4230412fefac72097f2c2b829ed58742d7c327cad0f1058df1bddd4ae9c6d2aba25480424308684cecd6517cdd8 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f 96b6a9be384df59ed2215ada1a91e3840bceec902fae9a3049a0a452b872b9ab737f8027d409ea8a5a83b4fdaead77980b5707ed273d4b075d00e8b8c413d81bbcd4e450cc95a6e50d60da9ef30595f22371ad4c89b36fea190fbcf4cc89b1b7 +0fab26fde1a4467ca930dbe513ccc3452b70313cccde2994eead2fde85c8da1db84d7d06a024c9e88629d5344224a4eae01b21a2665d5f7f36d5524bf5367d7f8b6a71ea05d413d4afde33777f0a3be49c9e6aa29ea447746a9e77ce27232a550b31dd4e7c9bc8913485f2dc83a56298051c92461fd46b14cc895c300a4fb874 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b aedba2f0ecc6e2fe77c077a0afac2d3d8cb4549c878bdd62d5325fd21a9733de6d100358a458ebea5b004446d0ce43740f653bc09c2afdaced306453911541bffbdc6d03d65ed0b6024f466f46252fd6816b3886a15e72eaf5aacb15edc9bd06 +7843f157ef8566722a7d69da67de7599ee65cb3975508f70c612b3289190e364141781e0b832f2d9627122742f4b5871ceeafcd09ba5ec90cae6bcc01ae32b50f13f63918dfb5177df9797c6273b92d103c3f7a3fc2050d2b196cc872c57b77f9bdb1782d4195445fcc6236dd8bd14c8bcbc8223a6739f6a17c9a861e8c821a6 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388 b7a458d98619d0c27397572c86f751c1070f2f00bb4d390b7e83613c12ae85106adddac1adb1dedd2147f172e25849580d16584b7fb00c46e8920600283bc6940ba156abc069ca5bef475ac4794ac1d1f7a7af03745839a6e01da6ca4cbe693a +6c8572b6a3a4a9e8e03dbeed99334d41661b8a8417074f335ab1845f6cc852adb8c01d9820fcf8e10699cc827a8fbdca2cbd46cc66e4e6b7ba41ec3efa733587e4a30ec552cd8ddab8163e148e50f4d090782897f3ddac84a41e1fcfe8c56b6152c0097b0d634b41011471ffd004f43eb4aafc038197ec6bae2b4470e869bded 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499 80accca69a4a760fcff80ef67b042ce98bde7ca36b7d81143eda32c6d3f561e70690c5533ec50a1687d8bcbafa191414126e4fc03b27bc0ad87c05b52aa1d1e830c534422a38cf25e4696cf7e5030b944d07b8534301096a2ef128014806d490 +7e3c8fe162d48cc8c5b11b5e5ebc05ebc45c439bdbc0b0902145921b8383037cb0812222031598cd1a56fa71694fbd304cc62938233465ec39c6e49f57dfe823983b6923c4e865633949183e6b90e9e06d8275f3907d97967d47b6239fe2847b7d49cf16ba69d2862083cf1bccf7afe34fdc90e21998964107b64abe6b89d126 f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6 a1c62b2963d9f41c43710e7ff06c79bbfda34a0fe611632e262d972cd4a839844ce4428377f3267f95198296675c65580fcfaa0752912d37fd35e592cc4ae4c6c8f426a5787ac3be53af56acda72b07973b1d1afe1a2ee3040da8da303002c0a +d5aa8ac9218ca661cd177756af6fbb5a40a3fecfd4eea6d5872fbb9a2884784aa9b5f0c023a6e0da5cf6364754ee6465b4ee2d0ddc745b02994c98427a213c849537da5a4477b3abfe02648be67f26e80b56a33150490d062aaac137aa47f11cfeddba855bab9e4e028532a563326d927f9e6e3292b1fb248ee90b6f429798db 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead 986b9a13036abd44a1ea541039bb22be01362466aedb085890cfaf0d3eb31ce1b602adfc0d1e647b3ea8a025c04ef17e028f8344f475632ea61a8235ac0bce7153ebde3d2f79d62f7ad8511e8ef9d130dd5d1821fc7f6791a24940f9e7baf046 +790b06054afc9c3fc4dfe72df19dd5d68d108cfcfca6212804f6d534fd2fbe489bd8f64bf205ce04bcb50124a12ce5238fc3fe7dd76e6fa640206af52549f133d593a1bfd423ab737f3326fa79433cde293236f90d4238f0dd38ed69492ddbd9c3eae583b6325a95dec3166fe52b21658293d8c137830ef45297d67813b7a508 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd 88ddce821fbf7852c0bfd62dad48c7a1afb003fa4fa023f4c28d1df18bab411131642def306d65a16e019e5a8d173b940ae64d2c5e106b7891ab8c165dd3c54df36ffd0cfda21b1e69afeb3d879236527e20d4d97d6b507f35718c464785cd0e +6d549aa87afdb8bfa60d22a68e2783b27e8db46041e4df04be0c261c4734b608a96f198d1cdb8d082ae48579ec9defcf21fbc72803764a58c31e5323d5452b9fb57c8991d31749140da7ef067b18bf0d7dfbae6eefd0d8064f334bf7e9ec1e028daed4e86e17635ec2e409a3ed1238048a45882c5c57501b314e636b9bc81cbe 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117 91f55c637b2a69d67544baa98ddce8c861e61af06ad2f9a2f93bedde6e00856b9000a4c968f14f8826fa7506713382990450ef6d9ff0fd93ab9dafdf430c10b98a5c660a92200bca684fce2b48b248612c1c4d78a272e04891eae39195e4690f +1906e48b7f889ee3ff7ab0807a7aa88f53f4018808870bfed6372a77330c737647961324c2b4d46f6ee8b01190474951a701b048ae86579ff8e3fc889fecf926b17f98958ac7534e6e781ca2db2baa380dec766cfb2a3eca2a9d5818967d64dfab84f768d24ec122eebacaab0a4dc3a75f37331bb1c43dd8966cc09ec4945bbd 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61 80c6948e5f04c030563a865048a6fb933796d4d89ec07813d098853ba02eeadc9ab59e61092b4da70e9535ce9845ae850d245e2f66e8bf129ba3c47282eb77b1a840083b9f873c099c492291cde6c29a182c5f2ed0f63aa2204918274f87f30c +7b59fef13daf01afec35dea3276541be681c4916767f34d4e874464d20979863ee77ad0fd1635bcdf93e9f62ed69ae52ec90aab5bbf87f8951213747ccec9f38c775c1df1e9d7f735c2ce39b42edb3b0c5086247556cfea539995c5d9689765288ec600848ecf085c01ca738bbef11f5d12d4457db988b4add90be00781024ad 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2 a683bb41ea0a7aeab69709e634cab416b0cf60f27fa90a8f579870d56d6e173a5f22b14c00267f7fc4cd50b651b94f19153fd9e3c3a7f1588b6692bd57f07ce25b97cbb2a2f1ef8720acb5a09f1c11393b9f82707877869ad588d79183b295c0 +041a6767a935dc3d8985eb4e608b0cbfebe7f93789d4200bcfe595277ac2b0f402889b580b72def5da778a680fd380c955421f626d52dd9a83ea180187b850e1b72a4ec6dd63235e598fd15a9b19f8ce9aec1d23f0bd6ea4d92360d50f951152bc9a01354732ba0cf90aaed33c307c1de8fa3d14f9489151b8377b57c7215f0b 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7 92b085736490fd4611977b57aa186585aa8bc84f5a0bfc531843cb2af5c715a5c89b71acdf1008c17d69dd175e378af7050eddef4bd3c9f1f09d34ec15a33611deb2cd01f1a516224ef685a581f968c107c34cf940149c84adb3e0406630245b +7905a9036e022c78b2c9efd40b77b0a194fbc1d45462779b0b76ad30dc52c564e48a493d8249a061e62f26f453ba566538a4d43c64fb9fdbd1f36409316433c6f074e1b47b544a847de25fc67d81ac801ed9f7371a43da39001c90766f943e629d74d0436ba1240c3d7fab990d586a6d6ef1771786722df56448815f2feda48f 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870 b9166b924c445137ffb5993c5e3e935683b7c73f3e069f406722741594156e3d4fe67a5e6da99f0cbf13a989570a6f6d0cdb77b547ced4f074c52706063c01e4cbf350e157a96abaa28688babc432095535b322a60044bf1783b4b1faa2aa9e4 +cf25e4642d4f39d15afb7aec79469d82fc9aedb8f89964e79b749a852d931d37436502804e39555f5a3c75dd958fd5291ada647c1a5e38fe7b1048f16f2b711fdd5d39acc0812ca65bd50d7f8119f2fd195ab16633503a78ee9102c1f9c4c22568e0b54bd4fa3f5ff7b49160bf23e7e2231b1ebebbdaf0e4a7d4484158a87e07 e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf ae4bfbe87686001d4cc99c82203a9a1734a773978a56ef6b8b15d5274cfc82b6cfd22fc472347d7c79e99479fde6b95202f7dda1782f92f4a7e9ee01ec2bf981aabd8f77f4b4c62462486276c1aebe1118404fa1b472ebc703c9c6daac2233f9 +7562c445b35883cc937be6349b4cefc3556a80255d70f09e28c3f393daac19442a7eecedcdfbe8f7628e30cd8939537ec56d5c9645d43340eb4e78fc5dd4322de8a07966b262770d7ff13a071ff3dce560718e60ed3086b7e0003a6abafe91af90af86733ce8689440bf73d2aa0acfe9776036e877599acbabfcb03bb3b50faa 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c b02722412d488255f7010ec023e75f0cad9e19741830052c601d5909c42568bb127c890924788791d847545c0c99ea79074250ac453cd4df2adcb96f804786f6d4ed392fd31ec90e3da2797c04a7e61336a6fcbe40dcc6d2ae5255363fd68371 +051c2db8e71e44653ea1cb0afc9e0abdf12658e9e761bfb767c20c7ab4adfcb18ed9b5c372a3ac11d8a43c55f7f99b33355437891686d42362abd71db8b6d84dd694d6982f0612178a937aa934b9ac3c0794c39027bdd767841c4370666c80dbc0f8132ca27474f553d266deefd7c9dbad6d734f9006bb557567701bb7e6a7c9 f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9 9192d78ae0ec66e039dbc8cb8703b0f4b8a3f1a7c9f5262ac562f240e3bd24a83e98e9aebb6ad5c83c8cd8a8871cf98b057c3a9a54858d2adb2ca3e3f15bcdca6db7c9bb8765df0c4c4c3bda0b0da9992418aa0a79c45da7569601f2f142a464 +4dcb7b62ba31b866fce7c1feedf0be1f67bf611dbc2e2e86f004422f67b3bc1839c6958eb1dc3ead137c3d7f88aa97244577a775c8021b1642a8647bba82871e3c15d0749ed343ea6cad38f123835d8ef66b0719273105e924e8685b65fd5dc430efbc35b05a6097f17ebc5943cdcd9abcba752b7f8f37027409bd6e11cd158f f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5 ac4fe349a17dc0d2d1b73e17b86107454ffa7882912ef43a548473fa022abee34ac6dfe566a054be519e64bc2beae9f80162734a810262325e47df2a608d677f531221e07c48f1aaa6f921d1077be4a300d21fc09c82fb197a049946afe50deb +efe55737771070d5ac79236b04e3fbaf4f2e9bed187d1930680fcf1aba769674bf426310f21245006f528779347d28b8aeacd2b1d5e3456dcbf188b2be8c07f19219e4067c1e7c9714784285d8bac79a76b56f2e2676ea93994f11eb573af1d03fc8ed1118eafc7f07a82f3263c33eb85e497e18f435d4076a774f42d276c323 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628 b7a09e03641f402384238e2b4d13dc6aedf6c86f45af7c0f89a1f2160000151284636243758b457f3b9ee7f3de54f6e216bd7de47268f69476d066d22f902899e4e1833a7b57a5a61d2b81119007b51c90f726b4540f99981cfacdd719e57148 +ea95859cc13cccb37198d919803be89c2ee10befdcaf5d5afa09dcc529d333ae1e4ffd3bd8ba8642203badd7a80a3f77eeee9402eed365d53f05c1a995c536f8236ba6b6ff8897393506660cc8ea82b2163aa6a1855251c87d935e23857fe35b889427b449de7274d7754bdeace960b4303c5dd5f745a5cfd580293d6548c832 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49 b9715977ad32b8910dc6d62553b1aeea0bb000a784d9323b3755ff598b3cc085ec0f514b4613e9ff88a52642c079af7613dee8cefbbdbcd39cdac700326decc6f20191a5f5934341bfb6c3418a3ed15d30c01164a631c96b3ac98f33ee3486a4 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P256_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P256_blst new file mode 100644 index 000000000000..f95dbeaeb9be --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P256_blst @@ -0,0 +1,60 @@ +ff624d0ba02c7b6370c1622eec3fa2186ea681d1659e0a845448e777b75a8e77a77bb26e5733179d58ef9bc8a4e8b6971aef2539f77ab0963a3415bbd6258339bd1bf55de65db520c63f5b8eab3d55debd05e9494212170f5d65b3286b8b668705b1e2b2b5568610617abb51d2dd0cb450ef59df4b907da90cfa7b268de8c4c2 708309a7449e156b0db70e5b52e606c7e094ed676ce8953bf6c14757c826f590 97eebfdb3d2a11482afe03ea5866bcb54414647952a4b7f83988aea37ae6c3388283367960288c2540693343f16055650b21e2a3623e8407e524f65956db4eb775dbc007695dc24e9f5742a3942ec646c58523584df5348728a7c1a524897128 +9155e91fd9155eeed15afd83487ea1a3af04c5998b77c0fe8c43dcc479440a8a9a89efe883d9385cb9edfde10b43bce61fb63669935ad39419cf29ef3a936931733bfc2378e253e73b7ae9a3ec7a6a7932ab10f1e5b94d05160c053988f3bdc9167155d069337d42c9a7056619efc031fa5ec7310d29bd28980b1e3559757578 90c5386100b137a75b0bb495002b28697a451add2f1f22cb65f735e8aaeace98 98723571a720361feb99e91a423ad3a4ff3670f441c2526adad3efc38f315201df015f6a9792c3c49d6ed4ce8d9817c50aa00e0fb5c769536efa60bbd4d9381417c9d71c626b79cde3fa15f14b3db07785444b12353b2d8687a6ddb0e8a6e50d +b242a7586a1383368a33c88264889adfa3be45422fbef4a2df4e3c5325a9c7757017e0d5cf4bbf4de7f99d189f81f1fd2f0dd645574d1eb0d547eead9375677819297c1abe62526ae29fc54cdd11bfe17714f2fbd2d0d0e8d297ff98535980482dd5c1ebdc5a7274aabf1382c9f2315ca61391e3943856e4c5e616c2f1f7be0d a3a43cece9c1abeff81099fb344d01f7d8df66447b95a667ee368f924bccf870 aab28c22786174eda224d1cb46597a5bf870ac930d0815026776a42c272e7339835ce3b5cb9e498680d5380571e2265302a26c10c1cb945a55919d1fde3c1b4032ebacb52dd2698382aab07dd1ab8279fb5bb58727b640b37b94700cdfad3768 +b64005da76b24715880af94dba379acc25a047b06066c9bedc8f17b8c74e74f4fc720d9f4ef0e2a659e0756931c080587ebdcd0f85e819aea6dacb327a9d96496da53ea21aef3b2e793a9c0def5196acec99891f46ead78a85bc7ab644765781d3543da9fbf9fec916dca975ef3b4271e50ecc68bf79b2d8935e2b25fc063358 7bbc8ff13f6f921f21e949b224c16b7176c5984d312b671cf6c2e4841135fc7f ac605c3f8300442f34d1b2600bf7d8aa8c7fb1e800a545142a6e89c6511b188f269576d58ad182196d260283930d08781990a16726c29a0067edb3b0cba7d1d827d77939bae3ea6c28d27d4b2c63fc2d58cc75aa8723dd25f65c096a3aa768e5 +fe6e1ea477640655eaa1f6e3352d4bce53eb3d95424df7f238e93d8531da8f36bc35fa6be4bf5a6a382e06e855139eb617a9cc9376b4dafacbd80876343b12628619d7cbe1bff6757e3706111ed53898c0219823adbc044eaf8c6ad449df8f6aab9d444dadb5c3380eec0d91694df5fc4b30280d4b87d27e67ae58a1df828963 daf5ec7a4eebc20d9485796c355b4a65ad254fe19b998d0507e91ea24135f45d 92dd94aea46c30154bbda54cd0c013f83fcb0743677bbb39c4990af82c90ed241593f45ea25bc050e5d988adf6ee50f90f59c95ec75b0e7afbf56c8f6a317f0c87c73db43c1e02c0dc9cd9bb3c78e2031590b2ac3bd695391110622e7a19b696 +907c0c00dc080a688548957b5b8b1f33ba378de1368023dcad43242411f554eb7d392d3e5c1668fad3944ff9634105343d83b8c85d2a988da5f5dc60ee0518327caed6dd5cf4e9bc6222deb46d00abde745f9b71d6e7aee6c7fdfc9ed053f2c0b611d4c6863088bd012ea9810ee94f8e58905970ebd07353f1f409a371ed03e3 8729a8396f262dabd991aa404cc1753581cea405f0d19222a0b3f210de8ee3c5 b03de1c9ee5caa727752b586d9e7ee27ea9d959cbde05f119cce33b71016955ed5b1507cda437096015a9dfc8b7a12b008772e9edeb96c42b6b8a8a579d4fd2114c1bb160bc3fc8004bf9be4eb2b1ad518bf1b49b89e225dd7d8920b22094bef +771c4d7bce05610a3e71b272096b57f0d1efcce33a1cb4f714d6ebc0865b2773ec5eedc25fae81dee1d256474dbd9676623614c150916e6ed92ce4430b26037d28fa5252ef6b10c09dc2f7ee5a36a1ea7897b69f389d9f5075e271d92f4eb97b148f3abcb1e5be0b4feb8278613d18abf6da60bfe448238aa04d7f11b71f44c5 f1b62413935fc589ad2280f6892599ad994dae8ca3655ed4f7318cc89b61aa96 8d67c2904a88737cb9e4eff0aa1474bc65e16f8833092e53958a092fec64d19d7f1e24598ebe4b8022066546169743ec082c4cf4193a275f15e0632edccbd7e8ecb963afe464df7aebcf26bafd9b4535c4285acf50680b88f337708c51c1ad02 +a3b2825235718fc679b942e8ac38fb4f54415a213c65875b5453d18ca012320ddfbbc58b991eaebadfc2d1a28d4f0cd82652b12e4d5bfda89eda3be12ac52188e38e8cce32a264a300c0e463631f525ae501348594f980392c76b4a12ddc88e5ca086cb8685d03895919a8627725a3e00c4728e2b7c6f6a14fc342b2937fc3dd 4caaa26f93f009682bbba6db6b265aec17b7ec1542bda458e8550b9e68eed18d b5dcddbc6a5ea99712dc226e0a45bc4eab95c0e850c222bb403a0121572a69ab126c64fda45a0777d3f0355da9ec998605d64130a568f0a3ac0d9894b404c60287c2b9dfa95f936092adde7116414d445a4096398e1c9b07c90d79bc01aa5fd2 +3e6e2a9bffd729ee5d4807849cd4250021d8184cda723df6ab0e5c939d39237c8e58af9d869fe62d3c97b3298a99e891e5e11aa68b11a087573a40a3e83c7965e7910d72f81cad0f42accc5c25a4fd3cdd8cee63757bbbfbdae98be2bc867d3bcb1333c4632cb0a55dffeb77d8b119c466cd889ec468454fabe6fbee7102deaf 7af4b150bb7167cb68037f280d0823ce5320c01a92b1b56ee1b88547481b1de9 a58ad611730594e6e793abfa392a3633cc768a28dbc2e41919d00eb5e8a4a389a64f67159fde57106a39bc5a4e27a8d2143f26897eb88e78a516510f9229e5a31cab5461e12cedbed4b4f8d4a3b593454ff8d5f9910ce7f0abe169ef1cac8bb5 +52e5c308e70329a17c71eaedb66bbee303c8ec48a6f1a2efb235d308563cd58553d434e12f353227a9ea28608ec9c820ed83c95124e7a886f7e832a2de1032e78dc059208f9ec354170b2b1cab992b52ac01e6c0e4e1b0112686962edc53ab226dafcc9fc7baed2cd9307160e8572edb125935db49289b178f35a8ad23f4f801 52ad53e849e30bec0e6345c3e9d98ebc808b19496c1ef16d72ab4a00bbb8c634 a24ab3f1f8473a685cc602123242fa8d96d63d4ae3dcc2e763a6dd271991945196edc209e31b6794776d7e78c9f50577100171d14be22862ee920fb20f91b0e96a83fe840b6ff67880b7265dd390aae112b601cc6dd4525979c1b9f6c6e66c5d +d3e9e82051d4c84d699453c9ff44c7c09f6523bb92232bcf30bf3c380224249de2964e871d56a364d6955c81ef91d06482a6c7c61bc70f66ef22fad128d15416e7174312619134f968f1009f92cbf99248932efb533ff113fb6d949e21d6b80dfbbe69010c8d1ccb0f3808ea309bb0bac1a222168c95b088847e613749b19d04 80754962a864be1803bc441fa331e126005bfc6d8b09ed38b7e69d9a030a5d27 9362651162e5792ca67acc16b9ae796459fb023b60568bd11c0492527a0f7b8570cc80dc98ffad1d83171f304f7088280857f2e75468df6e23579886f200b5262d925eb9dcfb306fccf821e9d12a13eff5f1408ee3d5811c39b73091c3d07b54 +968951c2c1918436fe19fa2fe2152656a08f9a6b8aa6201920f1b424da98cee71928897ff087620cc5c551320b1e75a1e98d7d98a5bd5361c9393759614a6087cc0f7fb01fcb173783eb4c4c23961a8231ac4a07d72e683b0c1bd4c51ef1b031df875e7b8d5a6e0628949f5b8f157f43dccaea3b2a4fc11181e6b451e06ceb37 cfa8c8bd810eb0d73585f36280ecdd296ee098511be8ad5eac68984eca8eb19d adebfa18478b54a3962e153c3942bc29868e33e38852fca7ee293859f77596fd3729227ea6e6bf5d6adb88d60d0b85860dcac7f58f17bfea7cf58c6892c69b132c8b0b1327d46c0c6a55500b82f44a5b2a4767c056e0d2401cebf19852cf1f2f +78048628932e1c1cdd1e70932bd7b76f704ba08d7e7d825d3de763bf1a062315f4af16eccefe0b6ebadccaf403d013f50833ce2c54e24eea8345e25f93b69bb048988d102240225ceacf5003e2abdcc90299f4bf2c101585d36ecdd7a155953c674789d070480d1ef47cc7858e97a6d87c41c6922a00ea12539f251826e141b4 b2021e2665ce543b7feadd0cd5a4bd57ffcc5b32deb860b4d736d9880855da3c b9bf0de2153ecc8553a30324eb3c6b6692d668b0c9a6e3fd2f76d6fd41fa6ac533165b76f387a00a229a378c1b67645204dca1955385b1e2db02995b79b53c88dce1d648ba346afecf1411be576452c046ad21b5de30b4c854eafea8bf5e77e5 +9b0800c443e693067591737fdbcf0966fdfa50872d41d0c189d87cbc34c2771ee5e1255fd604f09fcf167fda16437c245d299147299c69046895d22482db29aba37ff57f756716cd3d6223077f747c4caffbecc0a7c9dfaaafd9a9817470ded8777e6355838ac54d11b2f0fc3f43668ff949cc31de0c2d15af5ef17884e4d66a 0c9bce6a568ca239395fc3552755575cbcdddb1d89f6f5ab354517a057b17b48 afc759c8359645e2314a1417d74fc2d52652207a46a9b43bf71496dafad1ca2011a3e1627f2c89fe3f0abd38583363d80dba20d83bf3078288faa5e5b9eb54681c49e9d32e903ef3248a1467a80bd97c2410ed827cd483f25a5b6911d3007b85 +fc3b8291c172dae635a6859f525beaf01cf683765d7c86f1a4d768df7cae055f639eccc08d7a0272394d949f82d5e12d69c08e2483e11a1d28a4c61f18193106e12e5de4a9d0b4bf341e2acd6b715dc83ae5ff63328f8346f35521ca378b311299947f63ec593a5e32e6bd11ec4edb0e75302a9f54d21226d23314729e061016 1daa385ec7c7f8a09adfcaea42801a4de4c889fb5c6eb4e92bc611d596d68e3f a60c3699082dd5d279202b2da13876fa9b7263e06018629e3dd937892f2a1daa15cd51eb0606e2e16b97a2b49da98a830d3617db26b14969b21ba340e1a0dec603298223386e36d2aaf4507546a22ed8ba7e94f5e0873c749b6c8e5b6ad9dd12 +5905238877c77421f73e43ee3da6f2d9e2ccad5fc942dcec0cbd25482935faaf416983fe165b1a045ee2bcd2e6dca3bdf46c4310a7461f9a37960ca672d3feb5473e253605fb1ddfd28065b53cb5858a8ad28175bf9bd386a5e471ea7a65c17cc934a9d791e91491eb3754d03799790fe2d308d16146d5c9b0d0debd97d79ce8 519b423d715f8b581f4fa8ee59f4771a5b44c8130b4e3eacca54a56dda72b464 9140c000223563b103eb086c8c6c696353856666c19a7223f25517a3c716843d9b933f0c58899d29fa001d08407e2f08157f0297fc46044ee6032a37f2f11853147189a0638d4c73ca99733d78e0c420cfe76cdcdf77230291c7f231c35f5818 +c35e2f092553c55772926bdbe87c9796827d17024dbb9233a545366e2e5987dd344deb72df987144b8c6c43bc41b654b94cc856e16b96d7a821c8ec039b503e3d86728c494a967d83011a0e090b5d54cd47f4e366c0912bc808fbb2ea96efac88fb3ebec9342738e225f7c7c2b011ce375b56621a20642b4d36e060db4524af1 0f56db78ca460b055c500064824bed999a25aaf48ebb519ac201537b85479813 821f1f59a21e478f6c58294e3238f574291ce9d3e019c9f97ce1e6602670a629d85daf6814abd8458e329a0bb073112c1618044b0f1fbfe5927f7a30a2ea78366c89f8f7c94aac497b6f376b3081f1b3ac04db2fc259efb9a575aa6349b4fd8e +3c054e333a94259c36af09ab5b4ff9beb3492f8d5b4282d16801daccb29f70fe61a0b37ffef5c04cd1b70e85b1f549a1c4dc672985e50f43ea037efa9964f096b5f62f7ffdf8d6bfb2cc859558f5a393cb949dbd48f269343b5263dcdb9c556eca074f2e98e6d94c2c29a677afaf806edf79b15a3fcd46e7067b7669f83188ee e283871239837e13b95f789e6e1af63bf61c918c992e62bca040d64cad1fc2ef 8528dff973ffb838d642e6e5b93e1086286cdd65b36ab538041e1fd374265d5c152eb07fcab51f0fb0bb67c65b92a8a1182f8e5f5ee3da836720f6cf359bd0f2a7f2d0813c5d2b0fca274c31b97aef54ce4cfb87dffd1374677d68154dc56cbe +0989122410d522af64ceb07da2c865219046b4c3d9d99b01278c07ff63eaf1039cb787ae9e2dd46436cc0415f280c562bebb83a23e639e476a02ec8cff7ea06cd12c86dcc3adefbf1a9e9a9b6646c7599ec631b0da9a60debeb9b3e19324977f3b4f36892c8a38671c8e1cc8e50fcd50f9e51deaf98272f9266fc702e4e57c30 a3d2d3b7596f6592ce98b4bfe10d41837f10027a90d7bb75349490018cf72d07 8893816b005e9db1e772d4099bd87798673fa8fbec6ed27006746ffa28c5a4d3b588473c4d26b0bd63b4f382ce9be0121951cd438ae149c84c0e4bf99361456f232b70919809f808fe3adf52cf5ef9aef6e07a301cd8b02de8fe9234878a46bc +dc66e39f9bbfd9865318531ffe9207f934fa615a5b285708a5e9c46b7775150e818d7f24d2a123df3672fff2094e3fd3df6fbe259e3989dd5edfcccbe7d45e26a775a5c4329a084f057c42c13f3248e3fd6f0c76678f890f513c32292dd306eaa84a59abe34b16cb5e38d0e885525d10336ca443e1682aa04a7af832b0eee4e7 53a0e8a8fe93db01e7ae94e1a9882a102ebd079b3a535827d583626c272d280d 99ab1f771ba3bb79122ce09d47d0e03bb566932d257ce2aa3ad46f23a20f1deb89973d626672d1597dc25e5f039278b50e2654024854973a50892a66223298bb9e7fefb5a8f6987ca74db40a95c2a132d92cc8c31fcc534624c038cf89afc124 +600974e7d8c5508e2c1aab0783ad0d7c4494ab2b4da265c2fe496421c4df238b0be25f25659157c8a225fb03953607f7df996acfd402f147e37aee2f1693e3bf1c35eab3ae360a2bd91d04622ea47f83d863d2dfecb618e8b8bdc39e17d15d672eee03bb4ce2cc5cf6b217e5faf3f336fdd87d972d3a8b8a593ba85955cc9d71 4af107e8e2194c830ffb712a65511bc9186a133007855b49ab4b3833aefc4a1d 83b2392f3f497118a4b806974971a39d75f99bb759ac0b3cf453e29eadbeb077216d6909d548152eac88ebf1940cf51b14f1a5e8cb52b3f2ea523e689b9cf38ac7c5fa45278ae37f23c1a870bdae13677d488812914d3e4745a3f5b6c4d8c408 +dfa6cb9b39adda6c74cc8b2a8b53a12c499ab9dee01b4123642b4f11af336a91a5c9ce0520eb2395a6190ecbf6169c4cba81941de8e76c9c908eb843b98ce95e0da29c5d4388040264e05e07030a577cc5d176387154eabae2af52a83e85c61c7c61da930c9b19e45d7e34c8516dc3c238fddd6e450a77455d534c48a152010b 78dfaa09f1076850b3e206e477494cddcfb822aaa0128475053592c48ebaf4ab 98626a5808aee694dac875cc715d0ff98a3bd81aa87bbc19a059f73db2185f4ad5e691c520dfccc4e66f232029f8b6c9141d7965e3500462b085366afda0cbbac8d571d26968c78d7e7792d91e3be2892d22549d1b22c3461480f3c513e4532e +51d2547cbff92431174aa7fc7302139519d98071c755ff1c92e4694b58587ea560f72f32fc6dd4dee7d22bb7387381d0256e2862d0644cdf2c277c5d740fa089830eb52bf79d1e75b8596ecf0ea58a0b9df61e0c9754bfcd62efab6ea1bd216bf181c5593da79f10135a9bc6e164f1854bc8859734341aad237ba29a81a3fc8b 80e692e3eb9fcd8c7d44e7de9f7a5952686407f90025a1d87e52c7096a62618a b54816ec9837e1dc2b7fce28966f463456f012c592d372ca83815d1cd0c323e17db0528b0b8904028b850ca61cd639d00e8e3a4675e04663db61668cc3f8c53f9995b62f692f7524abc32c15acf2dfc25d42c5d33c55a6c16b8e7b1e5fc97f72 +558c2ac13026402bad4a0a83ebc9468e50f7ffab06d6f981e5db1d082098065bcff6f21a7a74558b1e8612914b8b5a0aa28ed5b574c36ac4ea5868432a62bb8ef0695d27c1e3ceaf75c7b251c65ddb268696f07c16d2767973d85beb443f211e6445e7fe5d46f0dce70d58a4cd9fe70688c035688ea8c6baec65a5fc7e2c93e8 5e666c0db0214c3b627a8e48541cc84a8b6fd15f300da4dff5d18aec6c55b881 b8abff23505134a2d3bfa61340fc51c7ee14156ffa33c24260cab41857a4084660d267d2d5d253cfd1ad3d11947f6a5c0b72d12bdb698142c267577ce45a222e61a7648d09217cc940fb217eec88320fa2e494078f81a9be55742b0186778280 +4d55c99ef6bd54621662c3d110c3cb627c03d6311393b264ab97b90a4b15214a5593ba2510a53d63fb34be251facb697c973e11b665cb7920f1684b0031b4dd370cb927ca7168b0bf8ad285e05e9e31e34bc24024739fdc10b78586f29eff94412034e3b606ed850ec2c1900e8e68151fc4aee5adebb066eb6da4eaa5681378e f73f455271c877c4d5334627e37c278f68d143014b0a05aa62f308b2101c5308 b698cb7d775f3f0f7eb0ea2e2136b7801eed8ac7c1eee4c42dd91c6f19b34edea0720b7dac3e7b1f7526b22490cb656d19592284655f18c672cbf0bb116dcc68ef16ad1f0627e0d3c15b5c8b8ff884ba6f86469e45dc1556f5d834335df3defc +f8248ad47d97c18c984f1f5c10950dc1404713c56b6ea397e01e6dd925e903b4fadfe2c9e877169e71ce3c7fe5ce70ee4255d9cdc26f6943bf48687874de64f6cf30a012512e787b88059bbf561162bdcc23a3742c835ac144cc14167b1bd6727e940540a9c99f3cbb41fb1dcb00d76dda04995847c657f4c19d303eb09eb48a b20d705d9bd7c2b8dc60393a5357f632990e599a0975573ac67fd89b49187906 922dea63f6c1c1a4f2e30a5a67446067ede8b6bc0fed2ba66822b96b86ec9c83ef2377169fdd8daf965277f73ccaa2750f948b4a6a892d09990949e2f842b499af4b173f5e4f22206d9fdf8693664df0e688cef4de4308cd904862a01fa92188 +3b6ee2425940b3d240d35b97b6dcd61ed3423d8e71a0ada35d47b322d17b35ea0472f35edd1d252f87b8b65ef4b716669fc9ac28b00d34a9d66ad118c9d94e7f46d0b4f6c2b2d339fd6bcd351241a387cc82609057048c12c4ec3d85c661975c45b300cb96930d89370a327c98b67defaa89497aa8ef994c77f1130f752f94a4 d4234bebfbc821050341a37e1240efe5e33763cbbb2ef76a1c79e24724e5a5e7 a442cd5c3a96be6b3c16866e6370eee6f6d9550b056e6d344341fb5758fd6f90b08742f4b73039b9e77bd5125ac1cd9d1024e026bc6d857942800f0cac7ab168f7d595ed630b23b5dda67b604bd66ad19364050b7d06cd0fb0f19197bb00e546 +c5204b81ec0a4df5b7e9fda3dc245f98082ae7f4efe81998dcaa286bd4507ca840a53d21b01e904f55e38f78c3757d5a5a4a44b1d5d4e480be3afb5b394a5d2840af42b1b4083d40afbfe22d702f370d32dbfd392e128ea4724d66a3701da41ae2f03bb4d91bb946c7969404cb544f71eb7a49eb4c4ec55799bda1eb545143a7 b58f5211dff440626bb56d0ad483193d606cf21f36d9830543327292f4d25d8c a9b366688dc13848bf4c425a7ee832f91a92518ea05a3c5ac840c7a727418d7cef3a62409a0bd0cef212482ecc365a0a10862de5c6d5236ea4948493bb3636e57bf1a0aacf0a58891d96840731a262edba9d060c2f32a3b0643e4c0e20ec4664 +72e81fe221fb402148d8b7ab03549f1180bcc03d41ca59d7653801f0ba853add1f6d29edd7f9abc621b2d548f8dbf8979bd16608d2d8fc3260b4ebc0dd42482481d548c7075711b5759649c41f439fad69954956c9326841ea6492956829f9e0dc789f73633b40f6ac77bcae6dfc7930cfe89e526d1684365c5b0be2437fdb01 54c066711cdb061eda07e5275f7e95a9962c6764b84f6f1f3ab5a588e0a2afb1 ac187a371e0439aa551c7d212917ee3a9539477f4f690f3fd09d0e9cd90bd716d3fdcd0fc2704adca7ff53ac195849720207eb7aa7ba5dacfc0d55da9177beb8d5842d9ea2ace20b3e82631bf6145f6cbbe18eba4ee68603449104d7cb3b4003 +21188c3edd5de088dacc1076b9e1bcecd79de1003c2414c3866173054dc82dde85169baa77993adb20c269f60a5226111828578bcc7c29e6e8d2dae81806152c8ba0c6ada1986a1983ebeec1473a73a04795b6319d48662d40881c1723a706f516fe75300f92408aa1dc6ae4288d2046f23c1aa2e54b7fb6448a0da922bd7f34 34fa4682bf6cb5b16783adcd18f0e6879b92185f76d7c920409f904f522db4b1 a824819e3d702ea4995881e1ad9fcb81461ffc69c33fe53eac04109d70cf4ab4af3f0f11140fb23fa03b8d68fd17111b079e1aeb5492c7bcae4d15cc9fe4a6f2aedeed5d2dd233c5f86f7e2198205d8cd9abae665bbf8796f12d297a4e3e5db8 +e0b8596b375f3306bbc6e77a0b42f7469d7e83635990e74aa6d713594a3a24498feff5006790742d9c2e9b47d714bee932435db747c6e733e3d8de41f2f91311f2e9fd8e025651631ffd84f66732d3473fbd1627e63dc7194048ebec93c95c159b5039ab5e79e42c80b484a943f125de3da1e04e5bf9c16671ad55a1117d3306 b6faf2c8922235c589c27368a3b3e6e2f42eb6073bf9507f19eed0746c79dced ac2a6ebb1de312971e415cba1074a1f8a4688328cb63cd18e0c74f8b7e97c5e9b32a1774fe7f00bcc4aed19c1719435f04bac99babe8e7df31a87a870c5bf81c4f7f494e25be8802f7c3f2c4442129f365ebd107d5d25306b7ebffe4f137f45c +099a0131179fff4c6928e49886d2fdb3a9f239b7dd5fa828a52cbbe3fcfabecfbba3e192159b887b5d13aa1e14e6a07ccbb21f6ad8b7e88fee6bea9b86dea40ffb962f38554056fb7c5bb486418915f7e7e9b9033fe3baaf9a069db98bc02fa8af3d3d1859a11375d6f98aa2ce632606d0800dff7f55b40f971a8586ed6b39e9 118958fd0ff0f0b0ed11d3cf8fa664bc17cdb5fed1f4a8fc52d0b1ae30412181 9229af6967bfb60dba690e19df76ef992df0be10d67fa01c2c5a38e7d19bda1b8fefc49cfa0e5b5e5cdb7adbb266f2b0170b6a392fb229e8364805a99f1e3e92d12035edafc5a8fdf93644358cdd8b830f3ffe562fd535d919dab6a5eacacfde +0fbc07ea947c946bea26afa10c51511039b94ddbc4e2e4184ca3559260da24a14522d1497ca5e77a5d1a8e86583aeea1f5d4ff9b04a6aa0de79cd88fdb85e01f171143535f2f7c23b050289d7e05cebccdd131888572534bae0061bdcc3015206b9270b0d5af9f1da2f9de91772d178a632c3261a1e7b3fb255608b3801962f9 3e647357cd5b754fad0fdb876eaf9b1abd7b60536f383c81ce5745ec80826431 8e005bd496c3434f9b6b1e5368f39ccdd92103abd39233fed860315c173bbfe66ee03405e7df05f452ca96bafbde6216117ba6578bbf4c552fd08992f03d64cd1afe3d6d6f4486a8c46e7d20746de7b84361d7b8ddde2dee3996286bb8dd0919 +1e38d750d936d8522e9db1873fb4996bef97f8da3c6674a1223d29263f1234a90b751785316444e9ba698bc8ab6cd010638d182c9adad4e334b2bd7529f0ae8e9a52ad60f59804b2d780ed52bdd33b0bf5400147c28b4304e5e3434505ae7ce30d4b239e7e6f0ecf058badd5b388eddbad64d24d2430dd04b4ddee98f972988f 76c17c2efc99891f3697ba4d71850e5816a1b65562cc39a13da4b6da9051b0fd 80125f89e4b41bc24bd52ac0f15d2734e4a44cbc98850eebb8a966f3d49835f133fcdf8ddbc60bbb83aaf56e1e351c73169c639c42779ed966b54e449de52089cae2826d12898b3844e8114c72988c40b8026cc48e6e81aad89bbdcbc4cdf468 +abcf0e0f046b2e0672d1cc6c0a114905627cbbdefdf9752f0c31660aa95f2d0ede72d17919a9e9b1add3213164e0c9b5ae3c76f1a2f79d3eeb444e6741521019d8bd5ca391b28c1063347f07afcfbb705be4b52261c19ebaf1d6f054a74d86fb5d091fa7f229450996b76f0ada5f977b09b58488eebfb5f5e9539a8fd89662ab 67b9dea6a575b5103999efffce29cca688c781782a41129fdecbce76608174de a629d985e6241464d9cf338a186e7229e3a7e9320a621589498bc236f6ac27daf36afc755b599c613b7e5592cedf351b145cf2d9ca2dee4f24f1c891209c77804797f5e73b7f5c4549199e151374a9a59c80d951aeb3b26c8d8b2478787233d1 +dc3d4884c741a4a687593c79fb4e35c5c13c781dca16db561d7e393577f7b62ca41a6e259fc1fb8d0c4e1e062517a0fdf95558b7799f20c211796167953e6372c11829beec64869d67bf3ee1f1455dd87acfbdbcc597056e7fb347a17688ad32fda7ccc3572da7677d7255c261738f07763cd45973c728c6e9adbeecadc3d961 ecf644ea9b6c3a04fdfe2de4fdcb55fdcdfcf738c0b3176575fa91515194b566 aa4e839eef2e85b253425d1f8471fcafd22469bbe0d97346c976a5057214568530750904183cddd2b269a9ec09a88a33187c7ef0544412429ddca4f6a6a3a4444f185fa2c15882947dd3b3bc37f10d642d2a6c6fa25e25574917968332250b4d +719bf1911ae5b5e08f1d97b92a5089c0ab9d6f1c175ac7199086aeeaa416a17e6d6f8486c711d386f284f096296689a54d330c8efb0f5fa1c5ba128d3234a3da856c2a94667ef7103616a64c913135f4e1dc50e38daa60610f732ad1bedfcc396f87169392520314a6b6b9af6793dbabad4599525228cc7c9c32c4d8e097ddf6 4961485cbc978f8456ec5ac7cfc9f7d9298f99415ecae69c8491b258c029bfee b46112e44eec6c9dc7743adb40b798d64f7415016a5158d8b3f484f3c3bfa0a4963794aad5893f94628e2e91834d04a4164ce703015738a79a4c7659d94826f704838a1d2699007c4287c394042f20c188d06e99241c6cd3c734bca5bc57d23f +7cf19f4c851e97c5bca11a39f0074c3b7bd3274e7dd75d0447b7b84995dfc9f716bf08c25347f56fcc5e5149cb3f9cfb39d408ace5a5c47e75f7a827fa0bb9921bb5b23a6053dbe1fa2bba341ac874d9b1333fc4dc224854949f5c8d8a5fedd02fb26fdfcd3be351aec0fcbef18972956c6ec0effaf057eb4420b6d28e0c008c 587907e7f215cf0d2cb2c9e6963d45b6e535ed426c828a6ea2fb637cca4c5cbd aea7c46c86f12d9e45f54af48aa6420c3b8b424fd8cadc2628c10b183a6edbd66d9a8370e800288e6ea987f7091cdc5c102324f7989ec362d8d33a10b203d179e025e8adf50695dbfc741afd8ceb3069a6bef989aed2fabe4e18945eae88d001 +b892ffabb809e98a99b0a79895445fc734fa1b6159f9cddb6d21e510708bdab6076633ac30aaef43db566c0d21f4381db46711fe3812c5ce0fb4a40e3d5d8ab24e4e82d3560c6dc7c37794ee17d4a144065ef99c8d1c88bc22ad8c4c27d85ad518fa5747ae35276fc104829d3f5c72fc2a9ea55a1c3a87007cd133263f79e405 24b1e5676d1a9d6b645a984141a157c124531feeb92d915110aef474b1e27666 96d69311ee4ab8fc66a0b2cc767639e6e1c7aa3f504a2ec9091fbe9ab15e00eced1b326b24db65cb0dc8b80e50e4bece0352635e79cb8561930bd7ee0abb3aa79729ca3750e7b71f890e6b5a0d09d47e38d7827ed3958ecc5ae239a03c8fe7bb +8144e37014c95e13231cbd6fa64772771f93b44e37f7b02f592099cc146343edd4f4ec9fa1bc68d7f2e9ee78fc370443aa2803ff4ca52ee49a2f4daf2c8181ea7b8475b3a0f608fc3279d09e2d057fbe3f2ffbe5133796124781299c6da60cfe7ecea3abc30706ded2cdf18f9d788e59f2c31662df3abe01a9b12304fb8d5c8c bce49c7b03dcdc72393b0a67cf5aa5df870f5aaa6137ada1edc7862e0981ec67 8e479eb3979adc183a470421a8f8b8dcc5e5592cdfd586b3fbf9af3477942a7486dc94800055b9238547d59d145188ed01985ffa98e15dd1db91d8bc1b450ed2613368fc89f116c4aa8a7dfa3ef33f4765b6ab2f637ca10ff19f892f2111401d +a3683d120807f0a030feed679785326698c3702f1983eaba1b70ddfa7f0b3188060b845e2b67ed57ee68087746710450f7427cb34655d719c0acbc09ac696adb4b22aba1b9322b7111076e67053a55f62b501a4bca0ad9d50a868f51aeeb4ef27823236f5267e8da83e143047422ce140d66e05e44dc84fb3a4506b2a5d7caa8 73188a923bc0b289e81c3db48d826917910f1b957700f8925425c1fb27cabab9 a104c4fbd4c2ad169bfb1a0edbe53b0e8f853d51fdef7175b37caffb6d804670ce7925e4aeefc4ce4a9e5b0aa2ea07370ef98ec86138026ee8a17b460f5a41f221cb356665b03c17c6cd10fa64e4582081b6618de29627d45bca35968d98a630 +b1df8051b213fc5f636537e37e212eb20b2423e6467a9c7081336a870e6373fc835899d59e546c0ac668cc81ce4921e88f42e6da2a109a03b4f4e819a17c955b8d099ec6b282fb495258dca13ec779c459da909475519a3477223c06b99afbd77f9922e7cbef844b93f3ce5f50db816b2e0d8b1575d2e17a6b8db9111d6da578 f637d55763fe819541588e0c603f288a693cc66823c6bb7b8e003bd38580ebce 8dc82fd32db7c538873b72dcee8f32a4c8dbc8596a93acdb9dd19e12ca1e8a4fb2d2dcd6e43a6a293d4c5cfc26e97628088ee4e597a04a2c4d5dbc82c6fca932cf84ba1f090baa2be3e2ad1b724ab5ce8e6b41f7cf6011890bc5b68aad5f8b67 +0b918ede985b5c491797d0a81446b2933be312f419b212e3aae9ba5914c00af431747a9d287a7c7761e9bcbc8a12aaf9d4a76d13dad59fc742f8f218ef66eb67035220a07acc1a357c5b562ecb6b895cf725c4230412fefac72097f2c2b829ed58742d7c327cad0f1058df1bddd4ae9c6d2aba25480424308684cecd6517cdd8 2e357d51517ff93b821f895932fddded8347f32596b812308e6f1baf7dd8a47f 8ef35c34df36ae73d7449720abbdab1b21f3b402b8b94d7a825dd6c289eded1128213af814ab0b3f21588aa1da64c50b1983cbb0d4b31fb663dfbb938e9d74cfce930e2c69840b1e6379e27297a9ed202751998b2483bd63c4f5469d7c884fb1 +0fab26fde1a4467ca930dbe513ccc3452b70313cccde2994eead2fde85c8da1db84d7d06a024c9e88629d5344224a4eae01b21a2665d5f7f36d5524bf5367d7f8b6a71ea05d413d4afde33777f0a3be49c9e6aa29ea447746a9e77ce27232a550b31dd4e7c9bc8913485f2dc83a56298051c92461fd46b14cc895c300a4fb874 77d60cacbbac86ab89009403c97289b5900466856887d3e6112af427f7f0f50b a75d45a99e5824567fb020ca1bfa9882cf220a0f4df5030fd2f8a1f415b2561e783339aaa355a3d98070299060e2835f14b773ed8a15cd998ff727bb7d7848a4905b3e4b8c90d1d05107e1a27ffb0870294d256453e9451c553e912c6c2888b7 +7843f157ef8566722a7d69da67de7599ee65cb3975508f70c612b3289190e364141781e0b832f2d9627122742f4b5871ceeafcd09ba5ec90cae6bcc01ae32b50f13f63918dfb5177df9797c6273b92d103c3f7a3fc2050d2b196cc872c57b77f9bdb1782d4195445fcc6236dd8bd14c8bcbc8223a6739f6a17c9a861e8c821a6 486854e77962117f49e09378de6c9e3b3522fa752b10b2c810bf48db584d7388 b82a57441ce9b07f9d79a4ffe523adaa4c80c02097f3fe8bc343189dd03169d01830ab3b2b0bc6f169d0bccab7fd3c800addf98748c983847e23464a9b5400505b8c9ef5ffd9ad2fddc26cb7fe819aa5d9de233902a16296bef94279a7dfe642 +6c8572b6a3a4a9e8e03dbeed99334d41661b8a8417074f335ab1845f6cc852adb8c01d9820fcf8e10699cc827a8fbdca2cbd46cc66e4e6b7ba41ec3efa733587e4a30ec552cd8ddab8163e148e50f4d090782897f3ddac84a41e1fcfe8c56b6152c0097b0d634b41011471ffd004f43eb4aafc038197ec6bae2b4470e869bded 9dd0d3a3d514c2a8adb162b81e3adfba3299309f7d2018f607bdb15b1a25f499 916d5831e40b06e0b1efe9b6ad5eab65b8b33c164f303d9c78ca74772aeb08378d400efa3b252676c789e07244283aee0af4f604f0e9c9587caa68d078e55637c4777bf4711edf4ea9620a0d9535018f98dc01827019fc85b273f4e448514d3f +7e3c8fe162d48cc8c5b11b5e5ebc05ebc45c439bdbc0b0902145921b8383037cb0812222031598cd1a56fa71694fbd304cc62938233465ec39c6e49f57dfe823983b6923c4e865633949183e6b90e9e06d8275f3907d97967d47b6239fe2847b7d49cf16ba69d2862083cf1bccf7afe34fdc90e21998964107b64abe6b89d126 f9bf909b7973bf0e3dad0e43dcb2d7fa8bda49dbe6e5357f8f0e2bd119be30e6 a35e8f28ebf0294cb7e3bba0667e7b645715057692ba4c904840e9a2495c3edb630f8dc2dc23f15b3b3fd1168b5161c102ad37d27550481c44311c9b4473d96409afe0d4ec399780e26a5699e624f91ff1f0e97c01030ae64b2dc225fab610bd +d5aa8ac9218ca661cd177756af6fbb5a40a3fecfd4eea6d5872fbb9a2884784aa9b5f0c023a6e0da5cf6364754ee6465b4ee2d0ddc745b02994c98427a213c849537da5a4477b3abfe02648be67f26e80b56a33150490d062aaac137aa47f11cfeddba855bab9e4e028532a563326d927f9e6e3292b1fb248ee90b6f429798db 724567d21ef682dfc6dc4d46853880cfa86fe6fea0efd51fac456f03c3d36ead a08f6ec93db22e5ef5db8f96e8b9f263a0f49188ae9292ee391f6daf24fd61a348eee1eb746e15cae6112a39a023ae5f157aec92851787329dbd56bfa9507f7e42b18ae816f204b7dc7cb14413d51d344dde789a0fc2b937df34693ce11899b9 +790b06054afc9c3fc4dfe72df19dd5d68d108cfcfca6212804f6d534fd2fbe489bd8f64bf205ce04bcb50124a12ce5238fc3fe7dd76e6fa640206af52549f133d593a1bfd423ab737f3326fa79433cde293236f90d4238f0dd38ed69492ddbd9c3eae583b6325a95dec3166fe52b21658293d8c137830ef45297d67813b7a508 29c5d54d7d1f099d50f949bfce8d6073dae059c5a19cc70834722f18a7199edd a4b53b53166fbfb4ff78db7e8e385ea55c1f69916af8fea018e363c2d20ba58242606b178cd23ef4aa1895f9bfe4d86c053f139f67a737f41b6cde632840672eb32da5496ed880fb56595b89b8c4a8aa5d052e4468262fcf78dfb15baadc5414 +6d549aa87afdb8bfa60d22a68e2783b27e8db46041e4df04be0c261c4734b608a96f198d1cdb8d082ae48579ec9defcf21fbc72803764a58c31e5323d5452b9fb57c8991d31749140da7ef067b18bf0d7dfbae6eefd0d8064f334bf7e9ec1e028daed4e86e17635ec2e409a3ed1238048a45882c5c57501b314e636b9bc81cbe 0d8095da1abba06b0d349c226511f642dabbf1043ad41baa4e14297afe8a3117 8f2956616c1671d8382b9c872c24ae8a8868e9e9dacfbc4552b7fe0107ecdb2f4ea701c2da37d5b15ced8c87179b823f0d948be544a1ef9f9bee002e0cdbae2b9083b2a794f59da31a304a0d2a139ee6d504850b109bee24a6ffb9ed596c31ba +1906e48b7f889ee3ff7ab0807a7aa88f53f4018808870bfed6372a77330c737647961324c2b4d46f6ee8b01190474951a701b048ae86579ff8e3fc889fecf926b17f98958ac7534e6e781ca2db2baa380dec766cfb2a3eca2a9d5818967d64dfab84f768d24ec122eebacaab0a4dc3a75f37331bb1c43dd8966cc09ec4945bbd 52fe57da3427b1a75cb816f61c4e8e0e0551b94c01382b1a80837940ed579e61 81eaf611d7f851d2637bfb272a2125b22fba0cbd0f3f56912e0b5de0c5f0f42432a13e06a8cf420141a2e5c3f003cfcd14361eebfb31128c7d23fa1a0a1f595edd8ee505ea346f94b4c8f0abc9ecd2319fdf34aa7c4741a6a0fd6da896cf56ec +7b59fef13daf01afec35dea3276541be681c4916767f34d4e874464d20979863ee77ad0fd1635bcdf93e9f62ed69ae52ec90aab5bbf87f8951213747ccec9f38c775c1df1e9d7f735c2ce39b42edb3b0c5086247556cfea539995c5d9689765288ec600848ecf085c01ca738bbef11f5d12d4457db988b4add90be00781024ad 003d91611445919f59bfe3ca71fe0bfdeb0e39a7195e83ac03a37c7eceef0df2 8a21246f5e1d3bfb384d89fb0657691328278782d776f10c4095703363db0379bd308bfcb1ba0a3743b044c6529a6c8c0ef95ad3dac5f8aa28bf49f387ddda9caf2e898a15492f16599882c1783ce02d5cf055b60144b46c72d905a7e940af13 +041a6767a935dc3d8985eb4e608b0cbfebe7f93789d4200bcfe595277ac2b0f402889b580b72def5da778a680fd380c955421f626d52dd9a83ea180187b850e1b72a4ec6dd63235e598fd15a9b19f8ce9aec1d23f0bd6ea4d92360d50f951152bc9a01354732ba0cf90aaed33c307c1de8fa3d14f9489151b8377b57c7215f0b 48f13d393899cd835c4193670ec62f28e4c4903e0bbe5817bf0996831a720bb7 a64866ac2c0d5f9b349332878b109b2fef28056441979acddd5a0e85e70103247a5fe3d471b785f8fd857c8361931cd400d4d25b4a3c39a9bf97ea4ae1720085d19d7395efae45c54e4f267bdbd77fe12f56cd35412eebe6b404951ec362dc40 +7905a9036e022c78b2c9efd40b77b0a194fbc1d45462779b0b76ad30dc52c564e48a493d8249a061e62f26f453ba566538a4d43c64fb9fdbd1f36409316433c6f074e1b47b544a847de25fc67d81ac801ed9f7371a43da39001c90766f943e629d74d0436ba1240c3d7fab990d586a6d6ef1771786722df56448815f2feda48f 95c99cf9ec26480275f23de419e41bb779590f0eab5cf9095d37dd70cb75e870 b52e560b6c7ce6618c6ea18695052ab591807aad3c10a3a4b6f00e045800f3c661a68b94e9cabc3c0d958d6f3fa2cde70a892906ee168974f327cf214402efc31a0fa1bcc67979ee5bd4842bdd3e2533ccb8772113d9ca977ce1203e5561f9aa +cf25e4642d4f39d15afb7aec79469d82fc9aedb8f89964e79b749a852d931d37436502804e39555f5a3c75dd958fd5291ada647c1a5e38fe7b1048f16f2b711fdd5d39acc0812ca65bd50d7f8119f2fd195ab16633503a78ee9102c1f9c4c22568e0b54bd4fa3f5ff7b49160bf23e7e2231b1ebebbdaf0e4a7d4484158a87e07 e15e835d0e2217bc7c6f05a498f20af1cd56f2f165c23d225eb3360aa2c5cbcf b334d8364a81935f10805fdb9fc11c16de0b004b9142916a7cabfc0e3e5e358caf99929d308225c57867ef2e21e6a2e404b064d2d908ff130cba6dda4f6eccaeea25c65fb47485fa0ccce99f7841ea4fb334a36e021480ad6d9f2536fcbc9434 +7562c445b35883cc937be6349b4cefc3556a80255d70f09e28c3f393daac19442a7eecedcdfbe8f7628e30cd8939537ec56d5c9645d43340eb4e78fc5dd4322de8a07966b262770d7ff13a071ff3dce560718e60ed3086b7e0003a6abafe91af90af86733ce8689440bf73d2aa0acfe9776036e877599acbabfcb03bb3b50faa 808c08c0d77423a6feaaffc8f98a2948f17726e67c15eeae4e672edbe388f98c 8db8563d6ec3ca19c1ba993ff9b759318dde9b3ba9cfd5edef308ffb5e4d8409ef73c05537a935ef532df35d275fd54a0b27541baf296d21d9da33eda927181359b785ce41a8cc53a10b2246a6734d5c42bf1fc5073277eb1419a2da1bc1d758 +051c2db8e71e44653ea1cb0afc9e0abdf12658e9e761bfb767c20c7ab4adfcb18ed9b5c372a3ac11d8a43c55f7f99b33355437891686d42362abd71db8b6d84dd694d6982f0612178a937aa934b9ac3c0794c39027bdd767841c4370666c80dbc0f8132ca27474f553d266deefd7c9dbad6d734f9006bb557567701bb7e6a7c9 f7c6315f0081acd8f09c7a2c3ec1b7ece20180b0a6365a27dcd8f71b729558f9 8c1071f4236c3c539ca77552e4c946598322c64c88b47852f5c75522c382861cbe0540cb9f2e765bd91e8d282a9576e618b948795da49f3c4ad4a709a38cf108097ec3d5c86a31ff5cbe819a58c044f49a3274c4a4aa8b4f18a2d83bc251c89c +4dcb7b62ba31b866fce7c1feedf0be1f67bf611dbc2e2e86f004422f67b3bc1839c6958eb1dc3ead137c3d7f88aa97244577a775c8021b1642a8647bba82871e3c15d0749ed343ea6cad38f123835d8ef66b0719273105e924e8685b65fd5dc430efbc35b05a6097f17ebc5943cdcd9abcba752b7f8f37027409bd6e11cd158f f547735a9409386dbff719ce2dae03c50cb437d6b30cc7fa3ea20d9aec17e5a5 b23a7ae2874d1242dfd4d07909ddbd1a74146c40ceb8b30853a295e252bc894663dd3c4d336399714c8777636011e9ec086906a2767bd1fb6787d5591555b439c9c83432a63d19372c40b7fa7038956b1955196c3d2a2db3b21c84b9dbf5737a +efe55737771070d5ac79236b04e3fbaf4f2e9bed187d1930680fcf1aba769674bf426310f21245006f528779347d28b8aeacd2b1d5e3456dcbf188b2be8c07f19219e4067c1e7c9714784285d8bac79a76b56f2e2676ea93994f11eb573af1d03fc8ed1118eafc7f07a82f3263c33eb85e497e18f435d4076a774f42d276c323 26a1aa4b927a516b661986895aff58f40b78cc5d0c767eda7eaa3dbb835b5628 8d3a8098e58166046255cc92e6b28971064a1c473c71fdc57513c0cf58ec40878828adcd7eac866ceaf69c46a095e50f08d6974ad5fe693963406901b76161c97bf31cbc7012f3a78cd622c0a78ac7def0bab66ee0bcc72d4b601710b65f5fc6 +ea95859cc13cccb37198d919803be89c2ee10befdcaf5d5afa09dcc529d333ae1e4ffd3bd8ba8642203badd7a80a3f77eeee9402eed365d53f05c1a995c536f8236ba6b6ff8897393506660cc8ea82b2163aa6a1855251c87d935e23857fe35b889427b449de7274d7754bdeace960b4303c5dd5f745a5cfd580293d6548c832 6a5ca39aae2d45aa331f18a8598a3f2db32781f7c92efd4f64ee3bbe0c4c4e49 99c95de04efce73296d8bb26d068def9ea5d7c90026b4eebe7c43942facc50ab65e51bdc31c061f003c6ab8f9109d63100398d49c0ddfd6f5cf313285e720016f5af91475f29aa5e15eaf9e23aa3f69f361be26a972e5e4c7f70e5fcec5822cf diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P384 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P384 new file mode 100644 index 000000000000..34464b51e33f --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P384 @@ -0,0 +1,60 @@ +39f0b25d4c15b09a0692b22fbacbb5f8aee184cb75887e2ebe0cd3be5d3815d29f9b587e10b3168c939054a89df11068e5c3fac21af742bf4c3e9512f5569674e7ad8b39042bcd73e4b7ce3e64fbea1c434ed01ad4ad8b5b569f6a0b9a1144f94097925672e59ba97bc4d33be2fa21b46c3dadbfb3a1f89afa199d4b44189938 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727 8a01330e1782bcebbd4a2b2df85a6fa38a842d214ae23626aaef0a7e64aea2556d8de00561e6a4fcbcd5bec9273ef30e0689631139c5edac5e2dfe4cb6a3acfb38aba522e7f2f710f3f6f3681e38b3e421c980cfda018dde00f1e134166dcd57 +5a3c80e608ed3ac75a6e45f6e94d374271a6d42b67a481860d5d309cc8b37c79cb61f1716dc8aa84cb309ef9d68eb7fc6cf4b42333f316a5c30e74198c8b340926e340c5de47674a707293c4aa2a1a2274a602f01c26b156e895499c60b38ef53fc2032e7485c168d73700d6fa14232596a0e4997854a0b05d02e351b9d3de96 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246 84943e9a45047fd3891132edb93d3a390f0030d3bfd18108f3b5306012382a8a85c50145a91e919e9d227543ed89eb1506cf25af08613de62b039431c220e0770336147c9b76d257c71a4aa1fc08ea7398a39e602ba6ac6545b63e80e0f72729 +e7d974c5dbd3bfb8a2fb92fdd782f997d04be79e9713944ce13c5eb6f75dfdec811b7ee4b3859114b07f263846ae13f795eec8f3cb5b7565baff68e0fdd5e09ba8b176d5a71cb03fbc5546e6937fba560acb4db24bd42de1851432b96e8ca4078313cb849bce29c9d805258601d67cd0259e255f3048682e8fdbdda3398c3e31 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83 88e8da93d1a48c5fc42be0b10103fa6e71feb1b35ba6d96246ab9328aa6e12f6f3fba78d0ac4e7df49a16bc98e97011b0e8a70cd028be69883c58a625671dddeeace2d2c75ab97cf1d9013ffce9fc76ad1f0bd678f2fe077dcf46277b0f03667 +a670fda4d1d56c70de1d8680328043b2b7029633caf0ee59ffe1421c914bb937133d5a0f9214846b2e0b350455a74c4ab434c56de65a17139bb8212bf1c76071a37536fa29348f871dbb26baa92eb93d97e923a6d2ffd9be25cbc33075e494e6db657bd8dc053fe4e17148d8cf6e2058164f2b5766750eb01bbe7b361cdb848c dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659 805dd6a8cf879f2abe00221575c34946403d827da2a4dfeb8d5aa038bb81f7df40cb50e6f89ab8688cdeeb6c73e463b811057e7653459e770c5c1963cf08217ad3db4c30877b315ee4f3729ea3c5766b2adc22f2f320a888f4a82977dbde1fb6 +7843f918fe2588bcfe756e1f05b491d913523255aa006818be20b676c957f4edb8df863c6f5f8c15b3b80c7a2aa277b70d53f210bdfb856337980c406ea140e439dd321471407f374f69877b2d82367eed51e3c82c13948616dcb301d0c31f8f0352f2846abd9e72071f446a2f1bd3339a09ae41b84e150fd18f4ba5d3c6bfa0 df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718 80cbe60d2fe05e2d16366ca49bb03a9dd4d7934cd16f65fb8bb90068daf7301fd3771ef98ed59e4a16ef5b25709711fa0188d39c2576c9c49f1b294429add0313c397f60513e2c9295eebbb334ef7de90685cb2a26d8f7608740ade207861c6a +caa83d5ab07febbd2e0fe2d63738b9b7b8752594bea7aaf50345b3d2f316653a8c9222f2b7877b64679e9573e81461a426029e45b8873a575094a1d572e0d32a9f0a9c6bcb9a2868543b7d8bbe4a69a09e7321f05f8366cced1b72df526f895b60aed2c39c249653c7839538770d4e5f47d3926ec0d168ab6a1af15bf1dca1f7 ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f 92b126e7b2ddedc28221d1aea3516281b1f148763be4958c244552a6feb817627cc159a8f3b00560cca6f7ddb418ac43145fc33c7d39ce0cd4370479a85a8649e2e1349bd3430f1401902d9ef826e37f94cd3a467bca1f477b675f331063d6bd +594603458d6534974aeeafba919c4d0f4cb6843a3af41204bbb88aeb2fca2772d305163dba863da050aabedbaf89db521955d1715de95bbcef979ecdc0c976181ece00355385f8a8f8cce127c9eac15ce3e958a3ed686184674ec9a50eb63271606ee7fdcb1323da3c3db8e89cad1fb42139a32d08abcfbf0d4ccfca18c89a86 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829 962d0372386c3ac70f8ba9e533e38b6f855ff93f9cbbae5b693e95b28bdeee175e479f79c26045c262ac8ef0308da76b02c13311ce49aee79e7f7ae8c521e9573666f4d2939d6b4136bf8fa38298c2982613ab9a473e6b7118d83ca144770880 +733252d2bd35547838be22656cc7aa67eff0af0b13b428f77267a513c6824c3dbae533068b6817e82665f009560affcfe4b2ddb5b667a644fc1a42d24f24e0947e0dc50fb62c919bc1fe4e7ded5e28f2e6d80fcf66a081fb2763526f8def5a81a4ddd38be0b59ee839da1643eeeaee7b1927cec12cf3da67c02bc5465151e346 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1 a35c9adb2fdf2922fde827094e2538e5e9e3c96cf0a37672eed2df5b4ebf9fbe282faf6451932e6422e1de39171eb19a197c5832f57e2af9b75ebba733833fb091578530f86dce9920eb7746d608f9ec727e8f249a19335869da4fb91e03c81e +5a182bd174feb038dfae3346267156bf663167f713dea1ce936b0edb815cd9b8c8e4d411c786ba2494a81442617255db7158b142e720d86c9b56680fb9efd4298cdd69079a28153494c42a24251c7ad42ecf7e97eabc1b3997529b2a297cbad2474269b87a0b1e385f2d7f8b6eb8d1cd75eaf7e91d1acbecd45d7b2bfbbe3216 e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d b24daf858ffeed952eb2f470277abc3944f2ede6177784033c0936d6544066fe87822a25acf0a154c86a841eda3447c5046c1d0a1dba9a5bed579e4d85f47e942ca90f0e9a478b18e00938262ac1784b79e392ea7b19607a9aba508aafa2e3f3 +aaa99fb1c71340d785a18f6f668e898c25cf7a0ac31d13c5b388b7233408493a5a109af6d07065376b96f4903df7aba2b2af671a18772bb0472490d1240cde28967680727dd4acd47e0308920a75da857a6eeedee5b6586d45dff3d8a680599665aa895c89dd7770b824b7dee477ac5e7602d409d3cc553090c970b50811dbab 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead a487fea7b4b8d83eeabf1c026cc3de63e0969ad91b9e01eb46f27fe3337c711c8e2d028e5b082bd353128516e36199e70ecc5b125977d13a7c4da2c58901a06fa0d2348ba36cb228b861c1acf751d6f978ca69a993e67a890f953408db0676b3 +1fadfa8254d3a0b82d137cfdd82043d5dc1fef195d5297b09cc5cfb061f59c933451c0dc2a11b4037f34f88dacb803251f8880c4b72585c3c196e6fb23484ca43a191f8e41b9b9a37e2e6fcaab6738c3c62d1c98e1c620bb788b7b51a04f998a510efdba0d3418622fe8ce203b3fcd553b9b4206365a39031797ad11e49745ec 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0 8ac1f2b5a86a415871c8017c11d890c9d674d3aafd23c9a118133127debe91bea75e23fee0cb499a5dd57bfcdbe8cbae143dd621140d0c3c07d6fd198c0db45d74b559dcd21db3ed3f46d48e2c388c9490df53b5294907b6917e52781a8d26ed +9ecb6f5ed3ba666a8536a81ef65012c2cb8b433508798d84708abb06dfb75503886f78384fb8c7a4d2d49ef539d9b8a0b60938c7f07471dda91f258b0d99691b38a8403a2bb3f956bdfd09baba16d9b6877097a9b6213481b47a06e139d23ec7abad5668d21f912fdb70d31bb9adf9b3ce80e308252fa81a51674f88d02db72b f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1 95b2ada507e13cee7cab41ec89344522970f49b2384998fa109821524e67760cabbef8a6319513395504b4b91ac4d910176171b7f522a6c767506c461581953bda0d143a7e6296c08b61d864712e6e62822fdf2f469d368b488c894f28d35ce5 +e55bfca78d98e68d1b63688db12485578f36c489766f4d0bfaa0088433ff12133aaca455805095f2e655940860958b3ead111d9070778ee3bbf3e47e43d9eba8b8d9b1fdf72f793fcde2bcaa334f3e35fa2cca531ea7cf27fe9ccba741e38ac26129b2d612bf54a34e0ae6c166c0fef07fcd2b9ac253d7e041a500f7be7b8369 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb 86f580c8b7aa6b23349f4b9ac4315d7e981136a65141af72e6e26a3f4647f61a47092bcbed950a4dd5ff82ecf7e0263b1122d53f8df01c4803407ac6df7eb2c3f100e4aeb16b821f88905ce329f3d7d9ab64737636bf8189fafc58f243a0ccac +02c6b3c83bd34b288d96409162aa4ff114e9d134bf948046eb5ebcc0c7fe9dfceadda83ed69da2fac00c8840f6c702a3fc5e6959d70f7e8af923e99e4937232ae3b841ffefd2e62fab3671a7c94a0281b8ea5bc176add57c5c9b6893fe7f5d48ce7256b96510810c4e046168a3c5be9843b84d5268a50349b3444341aa5490dd 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6 84d750948a6a4feafa4f23a03ec1e4de67d48a4d79f9609989da2c8fe36910ed0f834f6eced6ff5d70addd5ab9d32c56001b586b3982c399f79320526d764f286c8f7087c9f512f78828fd67a7707fdd0b4aab0c89ecabd7c16bb34d4abe5eb4 +94f8bfbb9dd6c9b6193e84c2023a27dea00fd48356909faec2161972439686c146184f80686bc09e1a698af7df9dea3d24d9e9fd6d7348a146339c839282cf8984345dc6a51096d74ad238c35233012ad729f262481ec7cd6488f13a6ebac3f3d23438c7ccb5a66e2bf820e92b71c730bb12fd64ea1770d1f892e5b1e14a9e5c cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd af49496792f98628c577254741e106782eb93ae9d0e41170ff5d19e78d1e287703d5baf9da73961122503ca45de931d414f04a1a0d3280d734088429d8274ab655be25107507cc1e5cd3c9f54056059f94c4567ccb86d2d4a582c40b6a6fb3d3 +663b12ebf44b7ed3872b385477381f4b11adeb0aec9e0e2478776313d536376dc8fd5f3c715bb6ddf32c01ee1d6f8b731785732c0d8441df636d8145577e7b3138e43c32a61bc1242e0e73d62d624cdc924856076bdbbf1ec04ad4420732ef0c53d42479a08235fcfc4db4d869c4eb2828c73928cdc3e3758362d1b770809997 c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b a36876f57c65929c6f88e783fa2d0170c0c432db57f95201dbcd9139229302d207ed7ab3c0e1712f5457a6feff3dc0dc120c1fc41a7bbf5f5111e15508a8be119f6460f9d65ce91c5c720cd3c189696f27c2b3377076954fefa4fee8c7969564 +784d7f4686c01bea32cb6cab8c089fb25c341080d9832e04feac6ea63a341079cbd562a75365c63cf7e63e7e1dddc9e99db75ccee59c5295340c2bba36f457690a8f05c62ab001e3d6b333780117d1456a9c8b27d6c2504db9c1428dad8ba797a4419914fcc636f0f14ede3fba49b023b12a77a2176b0b8ff55a895dcaf8dbce 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9 8cfcee1015f1ff723c76a3a10468e428ef49dbd66f39218dd48f8eb6453c92a23437ebbcd1942816e8a506367c43629708bcaf7b264e313e8ddfe21dfdf1c70196e6ca69de8f5ab868fa8c9d6c8151d0cbdbefa3cf057062169d81f11ef79176 +45e47fccc5bd6801f237cdbeac8f66ebc75f8b71a6da556d2e002352bd85bf269b6bc7c928d7bb1b0422601e4dd80b29d5906f8fcac212fe0eaaf52eda552303259cbcbe532e60abd3d38d786a45e39a2875bce675800a3eaeb9e42983d9fd9031180abd9adccc9ba30c6c198b4202c4dd70f241e969a3c412724b9b595bc28a d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f 884b5223737ad87187c9e34825d17062c7318c0e0477684ac00e819432199c4e92b501f6441f08df055912fd18e9dffb126c85575bec682789738405957f9311b29ada540c4bf2bd2edd308efa7c816a328ee5b4f2b572fdccf6b71ac4f3339f +c33ff63b4e6891e00b2349b3f2907c417ca355560544a91e24a7a0ee260d6850aeded29fc0176b6039ca6187e8333391047cceaf14b1077df8f147dad84d36b2dac5666dc2f69dc9b58b88cc73956efdb3b47f91831d5875051c76b0c4e9fc087012a1f03eeee85d6745b46aa50bd9cb0110c2c94508765cec162ee1aa841d73 d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3 86b7f6b8721c676c7f57089c1b6fdb505f2b297857a8bb222e220ab03c5bd8a9ccf38e6cd71a7cc1e5e24ebc560055f616885fdbd7e015836d457a33a4a2b15ba18838f7d2aa61bba34b33d5bfe5d16c88e133526d24f37ae5c9c82c56933ebb +f562f2b9d84b0e96a52532c3b43c39c8018c738bd8dc3797a7de7353971b2729d522d6961b1f2e4df3f6a4bd3653e6d72b74fc0dba92ab939c4b542e994e5db6dd8ed4f56f651e699052e791237ae1f552f990ad156226ae8f7bf17fcbfa564f749604f97e9df0879d50985747d981422a23040fe52f5ec74caf1d4aaad8a710 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93 a8c0689133e35245abd229a3bd13fe1254e0958b496ec4d9993c1fb7d93366b6a4af86ae7c157728edf73245d2a1e75410290e1951aef611c367d1c68b4845182f1d233095b79a8772ed5b4620d2d595793f8312c556c128a211c9cf11605b3c +ace953ae851f571d71779aa120915f27450b236da23e9106f8d0756abdd25861937941228d225d5fb1aa1b1ebf759b1e326aeb3b6cd0cd87edd2ab9f6a7ad67b63d2c501d6a550edb2e7c9d216cc8af78dd33546af64d00abed4d0d2cfc5c9a7b5a055dbe8f7547902d185cf46937314832bc5c602419a82ab83dbd9d3bd5aff e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1 b051ff751ca3a5183daf2700a502ab0196ba6e0aece15226e02747d73e651ecaffbcf7e233aade47252dfa885d68cf6e09e054f2413b7c10480dec3f730a4ea91ea9e580c94494900d47cc806cecb1c6b435f9767b617b17f7a35a2a4d25b58c +9635ab832240be95301bedb94c5aec169eedc198cbbdfedcf41e9b586143d829b4597a6b2a81902828332825fd84a785f187a3894e21bd99d22c4f94dcf34453fc052f15ec64d1447c932cb38fcdd30b7be851963409c11881438cbaad7e96f9efbde317f2235d66af804477a5dfe9f0c51448383830050ecf228889f83631e1 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960 b8b80d2147ab322be5149427ece8f8f65b3f76bf1b1eac4821ced3dd8f09c8939c2f1b0407669c82ba9161fa729a62f50e84cfa6e0666850b5b1678ef369c0bcea6992de63c203f060cd1ee3f294fe0e6b7e5b3d93916254cf3e3d83baf7eadd +d98b9a7d4fe9d0fd95de5056af164a8b7882cd34ab5bde83a2abb32dc361eb56a479a3a6119db3b91dcad26a42d2206749567f0d97c34a981a91fc734921821a429f6a53401743a5c406ba9d560f956203abc9d1f32f1a13e7d7b290f75c95fdbf857ea597021461c06a3aacfa554ede3d69e4ff03bbbee5b7463ec77de2b3b2 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57 b936bdb32458de408e51d098990c8b064d7c7b4b9b18cac788c598c94bde09202bc4f93dd372c2c1f15fcf798c282a4e013ecf1bf98790756a86dc22569ce2197336d2578f27486d7f9ffcede866501e8eb3422011309727af0f85ab06fc319c +1b4c754ac1c28dc415a71eac816bde68de7e8db66409af835838c5bb2c605111108a3bf13606ed5d8ade5ed72e50503e0de664416393d178ea4eec834d8d6f15039847b410080fd5529b426e5aadd8451c20ebd92d787921f33e147bcbeb327b104d4aab1157fc1df33e4d768404b5ccb7110055c2508c600f429fd0c21b5784 a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1 842887916c3d7975196009a5bb8b7e71d2cf8f2614b06b1d7717e922c578cf36d62eb417679959efe0b99c32dc2a2b1d0df0b17c5a5b567686ea4593fc9f2a93f795f46e991ea24581839288de736428109c8fcd3eae2c4ef3b8466e2d864f6f +3cd8c053741dd9f974c6c5dbf8a1e5728e9b5eafb1cbcfc3452f5fbbda32a8c7564dee157e8d902c52514361da6d972934a56b3276e2a9379e328e24282e0db697c5bc29090fc489ec46b7b188325dd4e96494c250de0f4a89fe2ccf919eaefcfb50c288113e6df92714feb7f46e0822478c796d0f4ff3447a32997e892693ce 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3 a3ca591818d475f14013f443351386d61d25c92e20b56328a0d2665f873363067d1143f7187094b44f88426263bb4330177fd0e4e592a3ef2c24f56f2ca83bd8b07afedd1017a7ccc4b3cc056e21c30298b2ea5dc89bc464a7d7f860a79104ae +ed955dda6d9650124804d3deb6aeef900e520faf98b1ef6f14efcada7ca2433f09329b70897305e59c89024d76e466b28fe02cb2a9b12e2478c66470259d7c282137a19e5a04ffadea55245c0f34a681593fedc42931d8b3321b3d82e9cc102cd00540ad311ec7bd8c9d06db21bea4ca3dc74d98931ae0d40494aefc2345132c 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907 920a299d41b93a64f00ae5255fe4fa65a968d222868c3f1c4dcbbdaffdb6e3edba59bce27ec59087373cc0226b6b554f01592c14650dce9ece8af1d89ba7863bb0b30919279015e538b4e4ac426f176307b4bd8f2109b79cf082db98dc1a8594 +ce395b001da2a58e49691605d44af4206306f62f561bf2394060d2a5591a350277166bed043819035f1e60b5b3fb5ae113ddd0473f8ef6b2b050c472c2a264e1d8b3ca82a4f158c40f2d78d9ce5e5ea6de243f2e1f13f47f6c6f403b270912c81c636be35b396ca58468b3fb60aa83911d61441a0528d973bc31f965d4059080 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245 919a2559032e56bdb1278dcb47ebf4de71be0a0507e23151d49005b6c7bc6e4f89c7381ae9343becab03b884aeb3e0ad083b0556266a3c32e61de1793e206dbd35d4d0863ee62b52e9041ac8c9dcd3a42b2ee08ce66eb3ac00acaecfab62c987 +ffefe316455ae4ffdb890bb804bf7d31424ea060ecacff419d0f7134ff76ad434063c0ec0f8bb7059584d3a03f3625bb9e9f66ace1a47ac4b8f3e76fc7c420c55edb1427d1fa15b387ad73d02b0595c4e74321be8822752230a0dcfb85d60bfa186da7623a8ec3eb1633f0a294b23ae87216b14ccee9ef56418dcfab9427371e 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7 874425d6ab893e9c7e1b50597982f07a8b6dab188068be01bb3f3e5f2205110ac7e150abd9553d3be8ad32055e7e78e600a8cacb0a7696afe15405ec34f01986dfc96c39a49ee111d36a84cb38ff4ee53f1d0205582ffc4fadcc99e650e9481c +304bccb718b3a9e12669913490cc5bcc1979287b56c628fad706c354241e88d10e81445a2853e3fc32ece094ba1abc3fdcab61da27f9a0fca739371049fed462ee6b08fa31cde12720f8144a6f00ce9b1a7a6eadd231f126717074b4efb5c72ce673ca5859000a436f67a338d698759f12c461247c45a361fb6cb661fdbe6714 d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5 b6d6c8d635919ea5c24b94f77b891bb5b9d2604b44ea9af4e677b4b31e5c8948bb8316adc0dc1224570a99e5d6639934150469aee1bd4c4acb7ebb09cf3c5b31edfc0d019bf87d611136911d46fb6a7ea6338c142d30af483b8f36655fb3a8b8 +64f9f05c2805acf59c047b5f5d2e20c39277b6d6380f70f87b72327a76170b872bfe4b25c451602acfb6a631bb885e2655aee8abe44f69c90fb21ffde03cef2a452c468c6369867dfd8aa26ac24e16aa53b292375a8d8fbf988e302bf00088e4c061aa12c421d8fe3cbd7273b0e8993701df1c59431f436a08b8e15bd123d133 b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224 b715a62f1e5b17217cb9d7efa9dc8433f042cc4bbb7a4c89a07f20c83d429c8941b212d7ad1a275b22ad2212f2eb3fc2164e18dfe10a30d7a6b255a088eb95a26bf706d6a3348a538bd5abeb853dbf92370af727eba82e3fb6271c81a58b9279 +6b45d88037392e1371d9fd1cd174e9c1838d11c3d6133dc17e65fa0c485dcca9f52d41b60161246039e42ec784d49400bffdb51459f5de654091301a09378f93464d52118b48d44b30d781eb1dbed09da11fb4c818dbd442d161aba4b9edc79f05e4b7e401651395b53bd8b5bd3f2aaa6a00877fa9b45cadb8e648550b4c6cbe 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 8c3cc32fdccc39275e686eef2f70b888271f0b0b13b9eb7cdff07ad25f532a95abf5114f2b2407800e90157d5f1ee2d10c592df0038ade718c6c7568b1a63ccbe16b312ca06449e9b4962b47f6de877ae8e98c57e1a36d792c98bfcba3cd5f84 +d768f41e6e8ec2125d6cf5786d1ba96668ac6566c5cdbbe407f7f2051f3ad6b1acdbfe13edf0d0a86fa110f405406b69085219b5a234ebdb93153241f785d45811b3540d1c37424cc7194424787a51b79679266484c787fb1ded6d1a26b9567d5ea68f04be416caf3be9bd2cafa208fe2a9e234d3ae557c65d3fe6da4cb48da4 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 8aae3375d692bf6acd3715a1a03fb99f9333812e26448940576cd7ed8e085253dace2131ea4e49ade45955b5951d0f5e10ebb7c09331e18959e3fedd511373fe91201942fd89237ed8999e942db03cc83b609b7c9b66d8348ac10781d1d71e77 +6af6652e92a17b7898e40b6776fabaf0d74cf88d8f0ebfa6088309cbe09fac472eeac2aa8ea96b8c12e993d14c93f8ef4e8b547afe7ae5e4f3973170b35deb3239898918c70c1056332c3f894cd643d2d9b93c2561aac069577bbab45803250a31cd62226cab94d8cba7261dce9fe88c210c212b54329d76a273522c8ba91ddf b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 81f9fff83b3aa71d4a2f7088ea1d346f9cdc7022f09198aedb90568fa128d548d2c1dbf7b23a833a8ad920c9bfd80ed713bff9c023f70fe8da5eb14d667c07cf91364368a0537be2e7fcb2b702499d25fc69883fcba696a7b766a21640ea73de +b96d74b2265dd895d94e25092fb9262dc4f2f7a328a3c0c3da134b2d0a4e2058ca994e3445c5ff4f812738e1b0c0f7a126486942a12e674a21f22d0886d68df2375f41685d694d487a718024933a7c4306f33f1a4267d469c530b0fed4e7dea520a19dd68bf0203cc87cad652260ed43b7b23f6ed140d3085875190191a0381a de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 a1916c8351fd78f01601982d54f2b29637e97fd6d5f092940e5de933ad9d4793a7b6f3e7f33d17e3971865ef704b71d415dfd2b5f359c57aa51ce1d84536e946e1d6a8b4a4e8e880d2c37b19caca024839826d0bd6542c3e75f3074fb5cba918 +7cec7480a037ff40c232c1d2d6e8cd4c080bbeecdaf3886fccc9f129bb6d202c316eca76c8ad4e76079afe622f833a16f4907e817260c1fa68b10c7a151a37eb8c036b057ed4652c353db4b4a34b37c9a2b300fb5f5fcfb8aa8adae13db359160f70a9241546140e550af0073468683377e6771b6508327408c245d78911c2cc 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc 8d385c8d494eb020c2a700e41f84507e6a5344dcc5df3852244519d7b18a9cf13b30869a4133f8895aa6a8463d3ca0d715bd398b443868cf2b3d56d585acc32fd3966f9dd4424c864d8b97b03b9d4a2ef8d4510b4f41fa3476ec1c34973ee34a +00ce978603229710345c9ad7c1c2dba3596b196528eea25bd822d43ca8f76a024e29217703dd0652c8a615284fc3edcc1c5ad1c8d5a8521c8e104c016a24e50c2e25066dcb56596f913b872767e3627aa3e55ec812e9fdac7c2f1beade83aef093e24c9c953982adf431a776880ae4583be158e11cdab1cbca3ad3a66900213d 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 b4bec04cf386b93f0a2d886df5daea5d1b3c2559c24176584b09688cce5967c995c63c744cec2d9521838e6bab07be5f0d0619be8896002ef8fd14688864e041f39ff97b855bcd2fc87b3214bb5e4a8282f64e32be121ff066f68fb16644fb1e +54a255c18692c6162a46add176a0ae8361dcb8948f092d8d7bac83e160431794d3b9812849bf1994bcdcfba56e8540c8a9ee5b93414548f2a653191b6bb28bda8dc70d45cc1b92a489f58a2d54f85766cb3c90de7dd88e690d8ebc9a79987eee1989df35af5e35522f83d85c48dda89863171c8b0bf4853ae28c2ac45c764416 ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 84b011f6a8b69b81c71b8cfa673906203bc69abd41feb0e37a5d6214fe7aaef514461fa2d6639cc25c68c1b6a50ddb86113a71c51cc478a26b9c54bcb178c2088f0171bd4c922b950939fadc2c5dd6b070cb681a8b9799b5da74950f1cd564c7 +692a78f90d4f9d5aee5da536314a78d68c1feabbfe5d1ccea7f6059a66c4b310f8051c411c409ccf6e19a0cbd8b8e100c48317fe8c6d4f8a638b9551ce7ee178020f04f7da3001a0e6855225fb3c9b375e4ed964588a1a41a095f3f476c42d52ffd23ce1702c93b56d4425d3befcf75d0951b6fd5c05b05455bdaf205fe70ca2 adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 97d3627ed93cbef58e44587a25052e36ec32618312a6771f2aedf3e95c57ee3def89a0a32d05fb2c033e5936c483799b0979acf2af04563bdb0aac74bd76bb8013deaeba814e112b0fa9b6d2e38fbb73dcf5714aa78d0a73db750fa8a5bf9494 +3b309bb912ab2a51681451ed18ad79e95d968abc35423a67036a02af92f575a0c89f1b668afe22c7037ad1199e757a8f06b281c33e9a40bab69c9874e0bb680b905d909b9dc24a9fe89bb3d7f7d47082b25093c59754f8c19d1f81f30334a8cdd50a3cb72f96d4b3c305e60a439a7e93aeb640dd3c8de37d63c60fb469c2d3ed 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d 8d4f327a2ece669b7c6f9849c09b7e21ebe11827908e454326e348c4a1babe54942066c350aa5dee76a648659ee703ff117f8b95adba972b40cb5741c0c0aafb514a71efb6fb35f76d760471bada66030f317fec935005b770026ae787585109 +f072b72b8783289463da118613c43824d11441dba364c289de03ff5fab3a6f60e85957d8ff211f1cb62fa90216fb727106f692e5ae0844b11b710e5a12c69df3ed895b94e8769ecd15ff433762d6e8e94d8e6a72645b213b0231344e2c968056766c5dd6b5a5df41971858b85e99afbf859400f839b42cd129068efabeea4a26 e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 b10969a46c1168a1a539d9f773bcba541f913209ced21482738c932f977f69498ae78d00b8758dbac105005c64cf5b2708a2b9a53f15b2fdd8126392478851928dd595f0a59278a877e2bdb9a3761d9c942008d99a4f0c3722ef9d55e677a6fd +cf4945350be8133b575c4ad6c9585e0b83ff1ed17989b6cd6c71b41b5264e828b4e115995b1ae77528e7e9002ac1b5669064442645929f9d7dd70927cb93f95edeb73e8624f4bc897ec4c2c7581cb626916f29b2d6e6c2fba8c59a71e30754b459d81b912a12798182bcff4019c7bdfe929cc769bcc2414befe7d2906add4271 d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca aac95b4e44f4d872fb3a2cdb4624fd374dc8319d111161adeb094aa6d5b15f2537608433ef873c1b25deb3f36ad6f8070ce1ce6d22320a237956b721c2f6e7c7a0a8f5f06909ba6177e0523f40ca8bb7872a912fac9660f64f02aefdc904c572 +d9b5cf0b50416573ff3c63133275a18394dd4326be2041e8d97e6e4e3855a4a177e9d26dfd223fe8aa74564edb49bd72de19916fb6f001f44530d5c18e2c332bce1b7415df5927ece5f3824f34d174b963136b53aef1fb78fb0c06a201a40b2db38e4d8216fc1e392a798c8ab4b3a314496b7f1087804ebfa89bf96e9cdb80c0 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d a8aeb4b4602318bcc54778933e093d78fadc4b66b4e8b6e31595c5405589a942ebc4645e3cab72aa7efaaceff8a6e7660cf75597c88ddb6f9b622018ac351a244ee8b1e0dc0eee7bbae6ad2d397f4ad6674eb3978c6815c7c63772ff8b879b9e +9e4042d8438a405475b7dab1cd783eb6ce1d1bffa46ac9dfda622b23ac31057b922eced8e2ed7b3241efeafd7c9ab372bf16230f7134647f2956fb793989d3c885a5ae064e85ed971b64f5f561e7ddb79d49aa6ebe727c671c67879b794554c04de0e05d68264855745ef3c9567bd646d5c5f8728b797c181b6b6a876e167663 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 98b18fc17172fa5b243800068256b1660c47f1c51df87a343ccb5494756d94ca147eeb9cc5d6f750101437b3057bef2a10d3d2dd5f065a8180a2805bf9353fd9b97a0154e5f8206e8942cebef3e84b88e5b7e06d6b95fbb3dde29b911594b3b3 +0b14a7484a40b68a3ce1273b8a48b8fdb65ba900d98541c4bbd07b97e31bcc4c85545a03e9deab3c563f47a036ff60d0361684ba241b5aa68bb46f440da22181ee328a011de98eff34ba235ec10612b07bdfa6b3dc4ccc5e82d3a8d057e1862fef3def5a1804696f84699fda2ec4175a54a4d08bcb4f0406fdac4eddadf5e29b ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 8a778bc7dd9ab2dd341dcb2544a68695be370d808c594e63262a1e0d1b51651b2580c123127db49a1b52c0bfe6e31dd1087c6f4b06f80c417617f495cbc58bacb4a34653b97606014726d0fa9f754021139497c8042d2ed22aa88a02f5d217cd +0e646c6c3cc0f9fdedef934b7195fe3837836a9f6f263968af95ef84cd035750f3cdb649de745c874a6ef66b3dd83b66068b4335bc0a97184182e3965c722b3b1aee488c3620adb835a8140e199f4fc83a88b02881816b366a09316e25685217f9221157fc05b2d8d2bc855372183da7af3f0a14148a09def37a332f8eb40dc9 e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb 85a2067afbce2e2d6460aea9c74d31f2bb0103eecee2dcee81435918a0f2c166479c0c26de6dc8fbeadb14161630a97216989ba6d5d70be08f611e3990bb6482dd412722abe8227b0a4bab250a265dab3aae4ca2457bef9c9bd09ce212b34fae +67d9eb88f289454d61def4764d1573db49b875cfb11e139d7eacc4b7a79d3db3bf7208191b2b2078cbbcc974ec0da1ed5e0c10ec37f6181bf81c0f32972a125df64e3b3e1d838ec7da8dfe0b7fcc911e43159a79c73df5fa252b98790be511d8a732fcbf011aacc7d45d8027d50a347703d613ceda09f650c6104c9459537c8f 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c 960c9b6f7641a4c0dfd404b4a19c204859e6d30478b83663b24154ff9ad2552f0e0555d68da89f4965287ac7661b6cfc182419b15f3e83084936b6c5710e3d49da3dcb6ac9fda9ab2282b3c7df65f514ad036b0a54344e5b600e2b6497c0b97d +45db86829c363c80160659e3c5c7d7971abb1f6f0d495709bba908d7aa99c9df64b3408a51bd69aba8870e2aaff488ef138f3123cf94391d081f357e21906a4e2f311defe527c55e0231579957c51def507f835cceb466eb2593a509dcbee2f09e0dde6693b2bfe17697c9e86dd672f5797339cbe9ea8a7c6309b061eca7aef5 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f 86a9672240e4faee58d949c04f476df3fe0d2e0405ec18da1f99dfbd286d95e9b396027edd2b9f4b95359132829e206108a5a527962676294c8a72dc21f6ad630b6466aee984ecf291453d13b0f39342390eac5a9b20d0fcb20d200e68fe54dd +4672fce0721d37c5be166bffa4b30d753bcf104b9b414db994b3ed33f36af4935ea59a0bb92db66448b3f57dad4fc67cef10ce141bf82c536be604b89a0bc0e8bca605b867880049d97142d30538fc543bd9d4fab7fdbe2f703815cdb6361beb66acff764bc275f910d1662445b07b92830db69a5994857f53657ed5ca282648 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7 86eca49c9c3ddfebe2f3cae06ac103e804e5a3315d98bb92a88cf44891319d33d1f7d53ff6e94c060fd81ae654f2e66a0af1b72cf186d378cb761886b666f6b76d8a35681a88c70ed1c8d3b99735f37ec534d306d5a8c3e07fe670df9b6b0dc5 +9ae48fdd9bfc5cb0f4d4761e28b2073bda05a3e3fe82c212e66701dc4573cc67a829b0f82d7520b1bf11db0c6d1743822bbe41bb0adbd7222aa5fae70fbd1a31f2d4453a01c81e064d775388468be96f6063f8673b7b8d4455fe1bd4c801ad5e625a015eaa4a1a18da490d2af8642201eaba3c611cbd65f861d8e19ca82a1ee6 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf a1a5ea74311df0dff1788d3bc948022561bae6698a8aa05069e33a099a17dff61a4aaa4e868025f361301cb66ca4a97c00b99698cc1bd69b8d67d47e15336d32d260d07bd56b36168a0bd6137e5166ad6350eb6f095cc8b3f47a9f05f1f425a0 +817d6a110a8fd0ca7b4d565558f68b59a156744d4c5aac5c6610c95451793de2a756f774558c61d21818d3ebeeeb71d132da1c23a02f4b305eccc5cd46bd21dfc173a8a91098354f10ffbb21bf63d9f4c3feb231c736504549a78fd76d39f3ad35c36178f5c233742d2917d5611d2073124845f1e3615b2ef25199a7a547e882 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b aef4ced855cd4385def730b698f79f6604ddd0c5ba7299c6c972966cd815e4f6f242edaed11a733aea0d46cc47e609f20b51d18c8b56a1d077a099bbf3dc479a970e869c441e38b27e6d49156cb7b36699db630c3977b195ca9d5f067db3c4bd +464f10ec6fb229a51db5fd0e122f2cb8a9a022117e2987f4007bf5565b2c16aba0714e2e3cdd0c100d55ac3017e36fc7501ad8309ab9572aa65424c9eb2e580a119c55777676ec498df53ef6ae78fd8a988130ee0e6082bf1ef71cd4c946021018a8ca7154d13b174c638912613b0bdb9001c302bf7e443ad2124ab2c1cce212 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69 b7cb66b990db43d71bf280d7cfbf316f1762854214a361dcfa5ad9c0bb53766fcd0f4688afc029ec1d8e22c569e601b31390078a043211a8c3ad9c93948d075c4ac0e31e130cfea1ca7f9a2f6281ede045e4c2d0a6c513af3471fa17437a6ea4 +4e3e0fb96320ddccde8b463c273654c4f7164920b1d63430921d2e808dee403e6420eedda0a557b911d00736a4f8798dd4ef26673efd6d190988ad4929ec64f8685cfb76070a36cd6a3a4bf2f54fb08a349d44642b6f614043fef9b2813b63457c76537d23da7b37310334f7ba76edf1999dad86f72aa3446445a65952ac4e50 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db a69b18c18b891a02af666c764fde0e2d04cd8de7ab6ba359b9a486b6a9cf14c1ce2680968cd0c61737c05c1887bbbcfb0fbc447830f1d6868339d86139fb01f918a619b1758da940979ca119f7bfd52a382e5696850ba84998b91b1f697baff6 +c466b6b6baf7e6ffa876ec06105e2d43534e0517c07b1c4c9fb67ba81ce09525a7721ec3c290f2b1f65b6463d41598e7a25b2238501629953a5ca955b644354fb6856733a2e5bb8f5bc21a0c803493f5539f9fb83aab3dba2c982989c2270c61ab244b68bfe1b948d00c2ed975e09c29b5f8a7effcad8652a148cc880d503217 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d 9754a60bd5f635d0ade45037b93a83d0538925132ae2d84f3bfc9a80331d36e865a2cb7f6acf8752467c390396a47c0006265708c11fb3ddedacaff18d0244f910fd37ad95c13b9fd77d5a492e78f3f55c61c2ea82bddcf34debc0d132ec2824 +feac892b7720af80b3c9eede51e923f18d3d0c5de4c31f4aa75e36df7c7c2fd8f41778851a24b69e67dccb65e159dd5c383243bad7cfedcc5e85c8a01c34b0b94ba8e07e4c024c09d279b3731e8b62f9562d3c4f5042567efe42a9d0eaaabab28bc6f11232fc8ceaaf4518d9f3b2bebf020294496b7f6b879e69503f75fecd3d 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476 b22aee7d7a32bc7001b9c0b002077e49ea3b42c8a3c58a53fb5c736447c5486206d168435c6bd7c78eed8fd4484c5d26020472c0b7f0bec2a6909a5e1f41adb5dc2bc3a1ad42f1581c7b4e3266ea85f869a1e6cda1a89a293aa3b460b23ec6b8 +cf2982e3bf174ce547741b969403cd11e9553067e6af8177d89511a0eb040db924530bdba65d8b1ff714228db0737c1756f509e1506014a10736e65be2f91980a73891496e90ff2714a3601c7565cdcef5a395e2e0e1652f138d90d61eaa9cba993b823245647f6e07cec9b8b4449cd68a29741cd1579c66e548ca0d0acf33aa ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa 864b34d11b67e46b73a1a1854d4b55da05d79386f1831c91849bebae9b6b44becf086a814d1fc4b738d4222e0c5aede80711bd42e3dd4608853c47db3c77a3c71d93a83492735e71aa6ea430d22ce8f6a75f80f840e97d03371f2fdaa69e5025 +bf9fdd4107ef5a6070108771ac9eee4f0c8043bf0d04db772a47294f4137e2439d94b337114b074e57e0cb78d0ccf352a2833e9788ee2a1a9ffeacd34f38fcefb86653d70c7dadd4cf6548d608e70acdef6c7530974b92c813798add659752a8c72b05e1ad9c65c21834ce6fbe49d8a1426b5a54270794436d284364fac6ec1a 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f a8b58d0fcbbf877f64dc0c4d96d5c90ba86cf79a3f1632bf8270e83cb7ad2052912d429d0d1b7af88e54f21c6e42406600c44dd3c7255db45845dfae31a6a447aecb5cca81017c952025879227e613799fca9d70dacc9293001a0e138546d529 +5d634fb39a2239256107dc68db19751540b4badac9ecf2fce644724401d6d632b3ae3b2e6d05746b77ddc0c899878032248c263eda08d3d004d35952ad7a9cfe19343d14b37f9f632245e7b7b5fae3cb31c5231f82b9f1884f2de7578fbf156c430257031ba97bc6579843bc7f59fcb9a6449a4cd942dffa6adb929cf219f0ad e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1 814aadb7389b398dc23b7790e9aae6ce71cb7c8e1439ad18367a9adaa2863041a8f7c1594efeac3a027add94225a219e10b746e24e73bc8eda3160109572b16404559c082fdbf35b77c7b9df14088042891d4787931ae3d8a294e66294f2f8f6 +c9b4ff721b3e886f0dc05856ffff0aabb64a8504b1746a47fdd73e6b7ebc068f06ac7ffa44c757e4de207fc3cbfaf0469d3ac6795d40630bcafe8c658627e4bc6b86fd6a2135afbc18ccc8e6d0e1e86016930ca92edc5aa3fbe2c57de136d0ea5f41642b6a5d0ddeb380f2454d76a16639d663687f2a2e29fb9304243900d26d 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c 993b3876943e07bed12cc7daab38a5d8d5d92c1e64969b5e178107f479050f3215f344bd7be4927b73d991dbfc137fcb14a2966b2037c2e6be9fb4ba673ab8d749e6ac3881e28bcc6ba262a60e9e5843e18ae4971a4304c0816f265f2ff4c941 +db2ad659cf21bc9c1f7e6469c5f262b73261d49f7b1755fc137636e8ce0202f929dca4466c422284c10be8f351f36333ebc04b1888cba217c0fec872b2dfc3aa0d544e5e06a9518a8cfe3df5b20fbcb14a9bf218e3bf6a8e024530a17bab50906be34d9f9bba69af0b11d8ed426b9ec75c3bd1f2e5b8756e4a72ff846bc9e498 e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c 904a9126ae420d156a6daf2de4e85efda75f11d5fa86963a997d0e400f9c704e607c9b9c374664401d48629d3052bfa3042382dc4730f9e9e399ac395b729612c48185cc274c98be6ae4c961b37a25124073fb42bc3f35de2ae0d01fb8b8f6c0 +dbd8ddc02771a5ff7359d5216536b2e524a2d0b6ff180fa29a41a8847b6f45f1b1d52344d32aea62a23ea3d8584deaaea38ee92d1314fdb4fbbecdad27ac810f02de0452332939f644aa9fe526d313cea81b9c3f6a8dbbeafc899d0cdaeb1dca05160a8a039662c4c845a3dbb07be2bc8c9150e344103e404411668c48aa7792 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855 a4fccc2a526e7fdd3f64fded760ed05b7c7fc6f3d298a7d71d21612fffe6c1a5e4219f63e68d8fa0374c5239880fda9d018ba8757d344910ae1451c30a78bdfc05a6ad3b08a804583044c0d7e5383dbb19cd2b81b12ef68c38221e5b48d32736 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P384_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P384_blst new file mode 100644 index 000000000000..93bf47321c83 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P384_blst @@ -0,0 +1,60 @@ +39f0b25d4c15b09a0692b22fbacbb5f8aee184cb75887e2ebe0cd3be5d3815d29f9b587e10b3168c939054a89df11068e5c3fac21af742bf4c3e9512f5569674e7ad8b39042bcd73e4b7ce3e64fbea1c434ed01ad4ad8b5b569f6a0b9a1144f94097925672e59ba97bc4d33be2fa21b46c3dadbfb3a1f89afa199d4b44189938 0af857beff08046f23b03c4299eda86490393bde88e4f74348886b200555276b93b37d4f6fdec17c0ea581a30c59c727 921bc156dcc7f94ffadfdf74b5e66d93f29c974a7c59832c034e3d47457aeb6766288e44408ea25f6da1b1f9d96cb66614c047bdeec69d65939d74c9def8b4632e169d60987a3b965b2e4c0790d803474a3fa74aad0e67f0a435304fd9e8f521 +5a3c80e608ed3ac75a6e45f6e94d374271a6d42b67a481860d5d309cc8b37c79cb61f1716dc8aa84cb309ef9d68eb7fc6cf4b42333f316a5c30e74198c8b340926e340c5de47674a707293c4aa2a1a2274a602f01c26b156e895499c60b38ef53fc2032e7485c168d73700d6fa14232596a0e4997854a0b05d02e351b9d3de96 047dd5baab23f439ec23b58b7e6ff4cc37813cccb4ea73bb2308e6b82b3170edfe0e131eca50841bf1b686e651c57246 add65f6729d4445c132048849d2c22b4faa490057749e2dd1d9e90373f17ac02fa359a1ed807f1b7977d863855a463d0040478cc426e9d752bd5241699be382fe45c385faa2cbb90bf1268a357f3fc1691876d231ccf8e13f706cb6ebfcdbab2 +e7d974c5dbd3bfb8a2fb92fdd782f997d04be79e9713944ce13c5eb6f75dfdec811b7ee4b3859114b07f263846ae13f795eec8f3cb5b7565baff68e0fdd5e09ba8b176d5a71cb03fbc5546e6937fba560acb4db24bd42de1851432b96e8ca4078313cb849bce29c9d805258601d67cd0259e255f3048682e8fdbdda3398c3e31 54ba9c740535574cebc41ca5dc950629674ee94730353ac521aafd1c342d3f8ac52046ed804264e1440d7fe409c45c83 828c78f7da8f1b3635b8e25bd9fa1eed4cdacc91bfe7e9b3fa3775e61ca53286f91e90b14b25062944547432dea457710ee80485ab81d92a7d2790ed210b2b5e7105ab9d59dc83412d4949bd55b9bb3eee7b3d4143d896f891a6f3cdeb154f87 +a670fda4d1d56c70de1d8680328043b2b7029633caf0ee59ffe1421c914bb937133d5a0f9214846b2e0b350455a74c4ab434c56de65a17139bb8212bf1c76071a37536fa29348f871dbb26baa92eb93d97e923a6d2ffd9be25cbc33075e494e6db657bd8dc053fe4e17148d8cf6e2058164f2b5766750eb01bbe7b361cdb848c dabe87bbe95499bac23bc83c8b7307fe04be198f00059e2bf67c9611feaffb2c8f274f6aa50eb99c3074186d8067d659 85d271e1ee1a14c323ae581c453c225da002f1ce4fbe628d18a470cbcaf3a468f884e0ed22663b0507e79a25e318e5ad09782b34e38bcfa4cec7c44ee0ce671270111108a7123e471e8c2bda2481832b480f3d3398c0ef7a9ff320a4d2851759 +7843f918fe2588bcfe756e1f05b491d913523255aa006818be20b676c957f4edb8df863c6f5f8c15b3b80c7a2aa277b70d53f210bdfb856337980c406ea140e439dd321471407f374f69877b2d82367eed51e3c82c13948616dcb301d0c31f8f0352f2846abd9e72071f446a2f1bd3339a09ae41b84e150fd18f4ba5d3c6bfa0 df43107a1deb24d02e31d479087bd669e2bc3e50f1f44b7db9484a7143cdca6a3391bddfea72dc940dbce8ec5efbd718 b731cc8c7763010edb6296ff605df8b4afeb0700aa2f2d7a0defbddff3cd75e5e85cbabccdc5abef01884884ed372baa185dae3b5c8d46aed8096139348c9519ac6d4a29c683943506b3f42bb48b581ac066e68d2c571108e1370ec14030dccc +caa83d5ab07febbd2e0fe2d63738b9b7b8752594bea7aaf50345b3d2f316653a8c9222f2b7877b64679e9573e81461a426029e45b8873a575094a1d572e0d32a9f0a9c6bcb9a2868543b7d8bbe4a69a09e7321f05f8366cced1b72df526f895b60aed2c39c249653c7839538770d4e5f47d3926ec0d168ab6a1af15bf1dca1f7 ea7a563ba2a7f5ab69973dca1f1a0d1572f0c59817cd3b62ad356c2099e2cdca1c553323563f9dfbb333b126d84abc7f b4db1af7a67630a09a6da927c1089f66076ba88a56b40f4a340de68e439950b8083abcb88655c84514ed353c4d7f5743066fd72ef17b91cca1a9e3cdade0da2a52f4cea9032c7810147e22149f489802db0051e55ad9e5a49477202e33d8b99f +594603458d6534974aeeafba919c4d0f4cb6843a3af41204bbb88aeb2fca2772d305163dba863da050aabedbaf89db521955d1715de95bbcef979ecdc0c976181ece00355385f8a8f8cce127c9eac15ce3e958a3ed686184674ec9a50eb63271606ee7fdcb1323da3c3db8e89cad1fb42139a32d08abcfbf0d4ccfca18c89a86 4cc70cb35b3ddeb0df53a6bd7bd05f8ff4392a2db7344f2d443761484b3a468a4ee3d1a8b27113d57283fd18b05f7829 afcdb50cfb16bdf24b9447d3cb946762646dced91079c03b1f4f1d56a8eede8b96a913b70f1f62ac070f6ceae633564514d36abc30b722bca05cea2baa42f1b2c44ddc1efbfe549d5aa3b2f20f61f79cc14924672e6236666be89f53397fd80c +733252d2bd35547838be22656cc7aa67eff0af0b13b428f77267a513c6824c3dbae533068b6817e82665f009560affcfe4b2ddb5b667a644fc1a42d24f24e0947e0dc50fb62c919bc1fe4e7ded5e28f2e6d80fcf66a081fb2763526f8def5a81a4ddd38be0b59ee839da1643eeeaee7b1927cec12cf3da67c02bc5465151e346 366d15e4cd7605c71560a418bd0f382fd7cd7ad3090ff1b2dfbed74336166a905e1b760cf0bccee7a0e66c5ebfb831f1 b0f25c588a9759d6fd9143ad762bf5c3a13119b7edf8ef25adcc38752801b5ee50b3971de8ddd3952bae3e087defec0d09cf078a234b1cb67c870a7a3a429f59d8de6d5b989f2e6d1637582967a5d65aea6471eea9cc873457bbe2d23ccad4e8 +5a182bd174feb038dfae3346267156bf663167f713dea1ce936b0edb815cd9b8c8e4d411c786ba2494a81442617255db7158b142e720d86c9b56680fb9efd4298cdd69079a28153494c42a24251c7ad42ecf7e97eabc1b3997529b2a297cbad2474269b87a0b1e385f2d7f8b6eb8d1cd75eaf7e91d1acbecd45d7b2bfbbe3216 e357d869857a52a06e1ece5593d16407022354780eb9a7cb8575cef327f877d22322c006b3c8c11e3d7d296a708bdb6d 8063a72ca6a36503f2ab46457425640f64520b31410fbfc638d279e82a42f9a1a41641bd4d18d236d5c0acf1f824645b108f35fb8a3c493da81b124ab48a9aae255a18f6dbad143bf5d6338c55c8d94336260de24a33d4486c45e158db0e933a +aaa99fb1c71340d785a18f6f668e898c25cf7a0ac31d13c5b388b7233408493a5a109af6d07065376b96f4903df7aba2b2af671a18772bb0472490d1240cde28967680727dd4acd47e0308920a75da857a6eeedee5b6586d45dff3d8a680599665aa895c89dd7770b824b7dee477ac5e7602d409d3cc553090c970b50811dbab 745a18db47324a3710b993d115b2834339315e84e7006eafd889fb49bd3cc5a8b50c90526e65e6c53bddd2916d14bead 8a0be4ddb0f2107369bfaf90a6073f7f31eac40880294cc570ac4e328db8effbd3ee5cc3a69e290a8f3ceea52d72b01f09cf0044569b6d775e490f1f1fa60a110d0b835f1ff7666fc17ff7814ed680d004be27621c785aa9177d880597196882 +1fadfa8254d3a0b82d137cfdd82043d5dc1fef195d5297b09cc5cfb061f59c933451c0dc2a11b4037f34f88dacb803251f8880c4b72585c3c196e6fb23484ca43a191f8e41b9b9a37e2e6fcaab6738c3c62d1c98e1c620bb788b7b51a04f998a510efdba0d3418622fe8ce203b3fcd553b9b4206365a39031797ad11e49745ec 93f20963ea5011ff4f26481e359309e634195f6289134087bd2e83eee008c962780a679784ee7ac6acda03d663ed27e0 91d1dcccf54121ac6fac5648b2634b3dfedfc229de8a419e53c0dc3d4c4041b8c39043e3e9135c7cb0f6f9be600d4c22092e379b04335abdd0da2044a5e80479f5f5678c1303d77b659ec5b4ed34ae827af782e2087002d26dcc102af69df6f7 +9ecb6f5ed3ba666a8536a81ef65012c2cb8b433508798d84708abb06dfb75503886f78384fb8c7a4d2d49ef539d9b8a0b60938c7f07471dda91f258b0d99691b38a8403a2bb3f956bdfd09baba16d9b6877097a9b6213481b47a06e139d23ec7abad5668d21f912fdb70d31bb9adf9b3ce80e308252fa81a51674f88d02db72b f175e6ac42fd48ec9d652c10707c039c67c4cc61d8c45a373dcda6e4ca6c53e947e49c24e01b48e7cdf92edfe6d316a1 af341d1df7ee0c96fa908ae5db6cdf8f12a28adb69c185589b7eff43190754790bd4149c07949094c4db18a2bd9f5172007e40ccd273f3cc4eb1dd2ee9309d245797f5266858f5a0d235846e3d9a46e89852692ebd90f554c347ad3c95a31cae +e55bfca78d98e68d1b63688db12485578f36c489766f4d0bfaa0088433ff12133aaca455805095f2e655940860958b3ead111d9070778ee3bbf3e47e43d9eba8b8d9b1fdf72f793fcde2bcaa334f3e35fa2cca531ea7cf27fe9ccba741e38ac26129b2d612bf54a34e0ae6c166c0fef07fcd2b9ac253d7e041a500f7be7b8369 46c4f0b228b28aaa0ec8cfdf1d0ed3408b7ae049312fb9eaf5f3892720e68684cc8ad29844a3dc9d110edf6916dfb8bb 8fc184782e794c4f18fb947e6dce73a9fb091603d3eb959ec2daac244b98108ef72a81d29adf05ae8f197f0679b5703804ec75ac3ec7912c26e2553136be031d12349e1c3e721ff6810d5e7112d96c117f1beba34ed6b5dd93a81840a91b133b +02c6b3c83bd34b288d96409162aa4ff114e9d134bf948046eb5ebcc0c7fe9dfceadda83ed69da2fac00c8840f6c702a3fc5e6959d70f7e8af923e99e4937232ae3b841ffefd2e62fab3671a7c94a0281b8ea5bc176add57c5c9b6893fe7f5d48ce7256b96510810c4e046168a3c5be9843b84d5268a50349b3444341aa5490dd 1d7b71ef01d0d33a8513a3aed3cabb83829589c8021087a740ca65b570777089be721a61172b874a22a1f81aef3f8bb6 a0adf9859a1d260f41d3d0db4261108e36ec805647802224a8950fc2c185fa59db2dfb4a8476c05dcae220301eb7540c04652959fb0ecf1e3ee6b1538f565bd3bc0861fef167df6f8f6faad0715fb4b2ccfde1ecf2c45ba226118b4c0e3038c9 +94f8bfbb9dd6c9b6193e84c2023a27dea00fd48356909faec2161972439686c146184f80686bc09e1a698af7df9dea3d24d9e9fd6d7348a146339c839282cf8984345dc6a51096d74ad238c35233012ad729f262481ec7cd6488f13a6ebac3f3d23438c7ccb5a66e2bf820e92b71c730bb12fd64ea1770d1f892e5b1e14a9e5c cf53bdd4c91fe5aa4d82f116bd68153c907963fa3c9d478c9462bb03c79039493a8eaeb855773f2df37e4e551d509dcd a3d839048ca71d8c38b78f7e022835cdfbd6f83c876a29fda738f44bfe6464c123cecca1ab2cab8e22baf72a9e1241881150ecd9b33f673bee440c29ade0ba171df024583a71e1ccf77a2f425434aaff1521a6039b470216929f06e48e27576e +663b12ebf44b7ed3872b385477381f4b11adeb0aec9e0e2478776313d536376dc8fd5f3c715bb6ddf32c01ee1d6f8b731785732c0d8441df636d8145577e7b3138e43c32a61bc1242e0e73d62d624cdc924856076bdbbf1ec04ad4420732ef0c53d42479a08235fcfc4db4d869c4eb2828c73928cdc3e3758362d1b770809997 c602bc74a34592c311a6569661e0832c84f7207274676cc42a89f058162630184b52f0d99b855a7783c987476d7f9e6b 99bedbf13af083a7dd87966f9311d4193465f6be4b0e796215f90bfe417e390f3f70c9040e76264259c4fc895ceea4a005f127a85053c244a5b27eac1c9c26108211a421e7bd75d81d5bf03c961970d97048ff4a51fd36183ac79a4b3bc338f4 +784d7f4686c01bea32cb6cab8c089fb25c341080d9832e04feac6ea63a341079cbd562a75365c63cf7e63e7e1dddc9e99db75ccee59c5295340c2bba36f457690a8f05c62ab001e3d6b333780117d1456a9c8b27d6c2504db9c1428dad8ba797a4419914fcc636f0f14ede3fba49b023b12a77a2176b0b8ff55a895dcaf8dbce 0287f62a5aa8432ff5e95618ec8f9ccaa870dde99c30b51b7673378efe4ccac598f4bbebbfd8993f9abb747b6ad638b9 95e244e1a6a938ae6b63a54fac81d897e8a4ea2165b15992d0c76f25581a8eed0d88031cf4f211037319d1f9dbea4741161d246e82904f41dc262ff6ccfaf3055f2a9f44e856e80a7f94dcc21df8413786f0826ace832a5703c962367d8d58eb +45e47fccc5bd6801f237cdbeac8f66ebc75f8b71a6da556d2e002352bd85bf269b6bc7c928d7bb1b0422601e4dd80b29d5906f8fcac212fe0eaaf52eda552303259cbcbe532e60abd3d38d786a45e39a2875bce675800a3eaeb9e42983d9fd9031180abd9adccc9ba30c6c198b4202c4dd70f241e969a3c412724b9b595bc28a d44d3108873977036c9b97e03f914cba2f5775b68c425d550995574081191da764acc50196f6d2508082a150af5cd41f 8162e105b0d6528f511ccb5819d8bbcf333990250568b93bff70fceb06ed84404871a9bd6767d5700d0edf2027a4f748032e99ca34b347d9917fdc8fdbd127ae3f5cae5673dde429229bc8007bb7670df1dacad1a883e7638c11a69a876df51d +c33ff63b4e6891e00b2349b3f2907c417ca355560544a91e24a7a0ee260d6850aeded29fc0176b6039ca6187e8333391047cceaf14b1077df8f147dad84d36b2dac5666dc2f69dc9b58b88cc73956efdb3b47f91831d5875051c76b0c4e9fc087012a1f03eeee85d6745b46aa50bd9cb0110c2c94508765cec162ee1aa841d73 d5b72cbb6ec68aca46b9c27ad992afd8ffa02cb3067b234fcfa6e272e3b31be760695ff7df988b57663057ab19dd65e3 b2ec906375cd2c48dfe812bde49ff4623a1c41665e6a9403654fa9cf41ce6698c5325c4bf89d630671b896757df4e2d30da0778c36cd89002d5814c198fe9fdee0661d4fef2faf386ffa58322bcc02c5deab335d72eb6d99867b79ba816941fc +f562f2b9d84b0e96a52532c3b43c39c8018c738bd8dc3797a7de7353971b2729d522d6961b1f2e4df3f6a4bd3653e6d72b74fc0dba92ab939c4b542e994e5db6dd8ed4f56f651e699052e791237ae1f552f990ad156226ae8f7bf17fcbfa564f749604f97e9df0879d50985747d981422a23040fe52f5ec74caf1d4aaad8a710 218ee54a71ef2ccf012aca231fee28a2c665fc395ff5cd20bde9b8df598c282664abf9159c5b3923132983f945056d93 99b508fc63617ceaffe710c139331f7f70a47ee3898f68c55ffc536400f05105b22f58de366a11c711367cb660b603c109fceae8e81dda865f0b2ecc0b14d074f52e39aabc98ebdd25553001df752374fcd6052e7d70cb199aa48d8644a8c453 +ace953ae851f571d71779aa120915f27450b236da23e9106f8d0756abdd25861937941228d225d5fb1aa1b1ebf759b1e326aeb3b6cd0cd87edd2ab9f6a7ad67b63d2c501d6a550edb2e7c9d216cc8af78dd33546af64d00abed4d0d2cfc5c9a7b5a055dbe8f7547902d185cf46937314832bc5c602419a82ab83dbd9d3bd5aff e6ab171f6937c000e144950801ad91023ae8e8476856c2592d9f7d5bb7180fd729211803d39a412ead6c0be761cfa5d1 b7eae01ab9e4dbd7367789343da2d76d2d5520e3503885b516ef155eb8edeab992f4388b67effd4547defa6393bac3d7106c0d792747deca23fce1e81950d9c3a33688e79cc4e9b4a856ad47d44f5247f64a2795f10e1ab8a21f251b7d1f18ec +9635ab832240be95301bedb94c5aec169eedc198cbbdfedcf41e9b586143d829b4597a6b2a81902828332825fd84a785f187a3894e21bd99d22c4f94dcf34453fc052f15ec64d1447c932cb38fcdd30b7be851963409c11881438cbaad7e96f9efbde317f2235d66af804477a5dfe9f0c51448383830050ecf228889f83631e1 14acd516c7198798fd42ab0684d18df1cd1c99e304312752b3035bed6535a8975dff8acfc2ba1675787c817b5bff6960 a03cfd80335115336157d3c473bb6a87e0b0c701ad81f1c2becb8d68a917c28499f2d738d3e53bf6bfb40019b101f9c20a701bd7af9d6b3d097252bb0b85c3c57142220ba5c3e2bb1ed9c2ec280ff9188bf1046cc6abd1b00ff39f0c9a3e880b +d98b9a7d4fe9d0fd95de5056af164a8b7882cd34ab5bde83a2abb32dc361eb56a479a3a6119db3b91dcad26a42d2206749567f0d97c34a981a91fc734921821a429f6a53401743a5c406ba9d560f956203abc9d1f32f1a13e7d7b290f75c95fdbf857ea597021461c06a3aacfa554ede3d69e4ff03bbbee5b7463ec77de2b3b2 2e780550984f3a00cb1e412429b33493c6eb6cd86d12f9d80588c247dcf567bd04296d2d4b24b889d9c54954b7f38f57 a0f898d6173b634c03c4fe25765a091eedf890e8a27aeaf4dfb6c0bd4561906d14322018f1283e7ffc76040b8f5655b5105adfda0bde7b9777739d08b52956139a0c06c9a2c3fd61f3527723fd6d519b0ebf1cef68a5a29bb720a72dc3e775e2 +1b4c754ac1c28dc415a71eac816bde68de7e8db66409af835838c5bb2c605111108a3bf13606ed5d8ade5ed72e50503e0de664416393d178ea4eec834d8d6f15039847b410080fd5529b426e5aadd8451c20ebd92d787921f33e147bcbeb327b104d4aab1157fc1df33e4d768404b5ccb7110055c2508c600f429fd0c21b5784 a24d0fe90808aecc5d90626d7e6da7c9be5dfd4e1233c7f0f71f1b7c1c6fd318fafe18559c94718f044cf02ed5107cb1 a32de597647489e65145ad53651e10b0d0e075d60ebe657c0e41a29156f046f0cafb849d4b0a3e603ef845b6bac415741431587a744f4201dd50a9807f89f786f6261f4f626b8b602af6821911380e7a727d3dbbb6c48fb540d963f1dfde133b +3cd8c053741dd9f974c6c5dbf8a1e5728e9b5eafb1cbcfc3452f5fbbda32a8c7564dee157e8d902c52514361da6d972934a56b3276e2a9379e328e24282e0db697c5bc29090fc489ec46b7b188325dd4e96494c250de0f4a89fe2ccf919eaefcfb50c288113e6df92714feb7f46e0822478c796d0f4ff3447a32997e892693ce 1c172e25732555afee7ded67a496f3f11babc0875898619f4519c29321e201e8ba1149f2c20b48e5efba235d58fea7c3 86010762d1b0954d68ffbf10983bbe20a1241622547eeae7bdaa915c75a4310ffcb848cc067364f6b8074961f227c770151925bebf383d8b90a3de5dd25f7a1725881b4db4be5655ae0c3557e23b0918a896480487a5a9d96ddc56db69e0a69b +ed955dda6d9650124804d3deb6aeef900e520faf98b1ef6f14efcada7ca2433f09329b70897305e59c89024d76e466b28fe02cb2a9b12e2478c66470259d7c282137a19e5a04ffadea55245c0f34a681593fedc42931d8b3321b3d82e9cc102cd00540ad311ec7bd8c9d06db21bea4ca3dc74d98931ae0d40494aefc2345132c 5b96555dbd602e71d4d5d3aee19fd1ea084ee23d4f55c10937056762bc2015cbded2e898a487f5482ab7e1e971245907 a200d7b2891b502ad74be51553a2bcad246e81b388ea11022c30cb72b51d188d84237c6369a0dfb7cc7633d1f328bc491617287f4fad5ce1750562394f73ea1c2d4885271e804d19f77a7ffe5fb2e0b766372de61da49513a10d80e00bfa03f6 +ce395b001da2a58e49691605d44af4206306f62f561bf2394060d2a5591a350277166bed043819035f1e60b5b3fb5ae113ddd0473f8ef6b2b050c472c2a264e1d8b3ca82a4f158c40f2d78d9ce5e5ea6de243f2e1f13f47f6c6f403b270912c81c636be35b396ca58468b3fb60aa83911d61441a0528d973bc31f965d4059080 8df9c3c710a25192f3dea970910bb3784e3509874cccf4334823eb9f7a8d05b067f2d812d61e878e24b093089a0b8245 85205592edf1ccdb2f9e4723bcf3e31ce7b02e2e1e0718f72293be9b256b521759d558047bd365bba2900401a179a3d019addb4b4d3f898213656a97ce65f9b1d9ac6f6a448382770d96955331f8a5c605fbe4498f5c219c37f7932492f57393 +ffefe316455ae4ffdb890bb804bf7d31424ea060ecacff419d0f7134ff76ad434063c0ec0f8bb7059584d3a03f3625bb9e9f66ace1a47ac4b8f3e76fc7c420c55edb1427d1fa15b387ad73d02b0595c4e74321be8822752230a0dcfb85d60bfa186da7623a8ec3eb1633f0a294b23ae87216b14ccee9ef56418dcfab9427371e 6002cb01ad2ce6e7101665d47729c863b6435c3875de57a93f99da834f73e3e6e2b3880e06de3e6bd1d51ea1807ab0d7 b80106cea6c6a8f9622acdc49eb9f80db395872deacb2b6c48a8fa1c5ef7203c7581423b71a21d2966c543281c9a74e30c74f7b694f2035d3c42de66e8551698bdfc02c6cacb8b058875ee591945dc21787fdb91e2baabac984db969d068b5f2 +304bccb718b3a9e12669913490cc5bcc1979287b56c628fad706c354241e88d10e81445a2853e3fc32ece094ba1abc3fdcab61da27f9a0fca739371049fed462ee6b08fa31cde12720f8144a6f00ce9b1a7a6eadd231f126717074b4efb5c72ce673ca5859000a436f67a338d698759f12c461247c45a361fb6cb661fdbe6714 d8559c3543afc6f7b3dc037a687bad2630283757ba7862fd23ed14e2151a4cf5fed3d249268f780e0b96b6b46274a2d5 a86883e0999f07e6368bd121ce6d1892632094ec6f82122f2b49f77a4f2f75889546a8280e716a144a4216abd53390ea0599ccc05ef92619350d13c85bcd01a9b93b6a228d92103487658c0f0b219e295a5ca6b71e4d9371f1db0245255f3d65 +64f9f05c2805acf59c047b5f5d2e20c39277b6d6380f70f87b72327a76170b872bfe4b25c451602acfb6a631bb885e2655aee8abe44f69c90fb21ffde03cef2a452c468c6369867dfd8aa26ac24e16aa53b292375a8d8fbf988e302bf00088e4c061aa12c421d8fe3cbd7273b0e8993701df1c59431f436a08b8e15bd123d133 b9208cbfd186ddfa3efd5b71342ae1efb01a13ebc4c2a992a2cbee7254b7846a4252ece1104b89d13d835911f8511224 87e020c67ec96ecafe202c3ee610c5043bb6a290a5544f67ea365306af8e1f25aeab529320859dde388aa12c8fe80d95188040eb735c972722e452fe7526cc8adc3faed25946ac7afce620dc247dfb94e26b70c81ce5c451fc0c46e272c68f12 +6b45d88037392e1371d9fd1cd174e9c1838d11c3d6133dc17e65fa0c485dcca9f52d41b60161246039e42ec784d49400bffdb51459f5de654091301a09378f93464d52118b48d44b30d781eb1dbed09da11fb4c818dbd442d161aba4b9edc79f05e4b7e401651395b53bd8b5bd3f2aaa6a00877fa9b45cadb8e648550b4c6cbe 201b432d8df14324182d6261db3e4b3f46a8284482d52e370da41e6cbdf45ec2952f5db7ccbce3bc29449f4fb080ac97 adcc68559234052024f0310948871f15986b0776b0b04c4511e44b62dfcf8e755c8f69389c95bf94633e9678e5e084d4098bace0dd56376a722f52eec72040e986bc68321865fae3829f3d653d00ec0359dd3b6d90faa2787830ba66d5db8cd8 +d768f41e6e8ec2125d6cf5786d1ba96668ac6566c5cdbbe407f7f2051f3ad6b1acdbfe13edf0d0a86fa110f405406b69085219b5a234ebdb93153241f785d45811b3540d1c37424cc7194424787a51b79679266484c787fb1ded6d1a26b9567d5ea68f04be416caf3be9bd2cafa208fe2a9e234d3ae557c65d3fe6da4cb48da4 23d9f4ea6d87b7d6163d64256e3449255db14786401a51daa7847161bf56d494325ad2ac8ba928394e01061d882c3528 8af3017e353424e3ac139579b80979011f3672c295bd05031adac865b0af71b49519928614888f22a71a921f16d95c5014586705cc2c89b4de432c83fe5d79fdcd2cc494befc79bc25ae045c36e1801a8e43bb1d609a3d71f2013d1f1b477e21 +6af6652e92a17b7898e40b6776fabaf0d74cf88d8f0ebfa6088309cbe09fac472eeac2aa8ea96b8c12e993d14c93f8ef4e8b547afe7ae5e4f3973170b35deb3239898918c70c1056332c3f894cd643d2d9b93c2561aac069577bbab45803250a31cd62226cab94d8cba7261dce9fe88c210c212b54329d76a273522c8ba91ddf b5f670e98d8befc46f6f51fb2997069550c2a52ebfb4e5e25dd905352d9ef89eed5c2ecd16521853aadb1b52b8c42ae6 806ba4657a327de19317d9e3a212a67d6ec694c1bbb0bf606bc24dff67597074f22c319db5cc12d6e8247adf144c09980c54cbf546c767e88dabc9b1b23e439ede75f54308fddcaaad13df114f03bd5c05fe328555cd60c618476ce9e430d736 +b96d74b2265dd895d94e25092fb9262dc4f2f7a328a3c0c3da134b2d0a4e2058ca994e3445c5ff4f812738e1b0c0f7a126486942a12e674a21f22d0886d68df2375f41685d694d487a718024933a7c4306f33f1a4267d469c530b0fed4e7dea520a19dd68bf0203cc87cad652260ed43b7b23f6ed140d3085875190191a0381a de5975d8932533f092e76295ed6b23f10fc5fba48bfb82c6cc714826baf0126813247f8bd51d5738503654ab22459976 8be83b5752278707315a30d7af4cfcc4c5604abf7c9fb55d46cf350aed2a9468728c427051eb6ed7c1429fd6776d5a7206d3ea75326dd7095682b064c76f6ba8235839ae84e3ffc975c8015c6339f6925cc4505bcd18c4336b535895b7e008d8 +7cec7480a037ff40c232c1d2d6e8cd4c080bbeecdaf3886fccc9f129bb6d202c316eca76c8ad4e76079afe622f833a16f4907e817260c1fa68b10c7a151a37eb8c036b057ed4652c353db4b4a34b37c9a2b300fb5f5fcfb8aa8adae13db359160f70a9241546140e550af0073468683377e6771b6508327408c245d78911c2cc 11e0d470dc31fab0f5722f87b74a6c8d7414115e58ceb38bfcdced367beac3adbf1fe9ba5a04f72e978b1eb54597eabc b1bfed9845436710575777c246423859b195010ea1f1094749a9c857e57824e6c7930428155e2d12e8d94bdfbc10926415c180e7d9aad0c50d862650df98ec289cc438c91a181a19a2626ab5a9b9b859dbe1b9d3bc431931cedae269f19512b0 +00ce978603229710345c9ad7c1c2dba3596b196528eea25bd822d43ca8f76a024e29217703dd0652c8a615284fc3edcc1c5ad1c8d5a8521c8e104c016a24e50c2e25066dcb56596f913b872767e3627aa3e55ec812e9fdac7c2f1beade83aef093e24c9c953982adf431a776880ae4583be158e11cdab1cbca3ad3a66900213d 5c6bbf9fbcbb7b97c9535f57b431ed1ccae1945b7e8a4f1b032016b07810bd24a9e20055c0e9306650df59ef7e2cd8c2 af4cadd9a5a8a01418407282bcc56f1c8b8bbf263443b31dcdb682ef0a52e848acfaf30bfce399b2ed71f4e666d7287c0767bb5a769765674ef352ddc18bcc6f58bb3274a1e60c0498c711d4e48ba0cb1efe1745689cab7192ca9892685e4d77 +54a255c18692c6162a46add176a0ae8361dcb8948f092d8d7bac83e160431794d3b9812849bf1994bcdcfba56e8540c8a9ee5b93414548f2a653191b6bb28bda8dc70d45cc1b92a489f58a2d54f85766cb3c90de7dd88e690d8ebc9a79987eee1989df35af5e35522f83d85c48dda89863171c8b0bf4853ae28c2ac45c764416 ffc7dedeff8343721f72046bc3c126626c177b0e48e247f44fd61f8469d4d5f0a74147fabaa334495cc1f986ebc5f0b1 8d9d9a7788cebd10f6ae1bda95d3eca59d2e10e4b5e71787af6359e689850d00cd4fa2f833bc96eacfc494e51c35b068186ea8980622b8e081ac7b1c81f99acad7e49cc30d143b69bc82b9bc7c00fb7a2d3728fda89b973674211e2a623de4bb +692a78f90d4f9d5aee5da536314a78d68c1feabbfe5d1ccea7f6059a66c4b310f8051c411c409ccf6e19a0cbd8b8e100c48317fe8c6d4f8a638b9551ce7ee178020f04f7da3001a0e6855225fb3c9b375e4ed964588a1a41a095f3f476c42d52ffd23ce1702c93b56d4425d3befcf75d0951b6fd5c05b05455bdaf205fe70ca2 adca364ef144a21df64b163615e8349cf74ee9dbf728104215c532073a7f74e2f67385779f7f74ab344cc3c7da061cf6 a9339c2b8181703e26699072efd9e5ceb946b7fd84641a9932160280f9b96cd9f0ac7dd5f19f53de74f123c44ce114491608f82f9129f316e6d750fa3fc2dd9f2ade57120ab3ba6c2c6dc85c89e0968a6d8f120208ab20b7fde2796323270e2f +3b309bb912ab2a51681451ed18ad79e95d968abc35423a67036a02af92f575a0c89f1b668afe22c7037ad1199e757a8f06b281c33e9a40bab69c9874e0bb680b905d909b9dc24a9fe89bb3d7f7d47082b25093c59754f8c19d1f81f30334a8cdd50a3cb72f96d4b3c305e60a439a7e93aeb640dd3c8de37d63c60fb469c2d3ed 39bea008ec8a217866dcbdb1b93da34d1d3e851d011df9ef44b7828b3453a54aa70f1df9932170804eacd207e4f7e91d af8ae2f2a7e340ce4ccb6b17deb50372a7c5d8971b019e871228d46e6d93cfff1bf8799df4fbfe9fc6b2d7cf083b809715ca8ed889428c00220829baa06101e66d0e4e727ac12372698624d3bf4a6567ccdfa68e7cefa11dade1c0a3de38dbd2 +f072b72b8783289463da118613c43824d11441dba364c289de03ff5fab3a6f60e85957d8ff211f1cb62fa90216fb727106f692e5ae0844b11b710e5a12c69df3ed895b94e8769ecd15ff433762d6e8e94d8e6a72645b213b0231344e2c968056766c5dd6b5a5df41971858b85e99afbf859400f839b42cd129068efabeea4a26 e849cf948b241362e3e20c458b52df044f2a72deb0f41c1bb0673e7c04cdd70811215059032b5ca3cc69c345dcce4cf7 8b59c77b0970900db34e3e0827a9a613a560c87167f9422aab9bfc4675a56eb9c0e767de55fb8ea614b1a29c48580da01847e4cdbca226a6e2d15726bd54d75990fc496ba89c7a93e69c2ec8391b20503da4de0b19f0fb9d8f8aa30db7189534 +cf4945350be8133b575c4ad6c9585e0b83ff1ed17989b6cd6c71b41b5264e828b4e115995b1ae77528e7e9002ac1b5669064442645929f9d7dd70927cb93f95edeb73e8624f4bc897ec4c2c7581cb626916f29b2d6e6c2fba8c59a71e30754b459d81b912a12798182bcff4019c7bdfe929cc769bcc2414befe7d2906add4271 d89607475d509ef23dc9f476eae4280c986de741b63560670fa2bd605f5049f1972792c0413a5b3b4b34e7a38b70b7ca 813eb11d0c8a1c48fbb7df7452bc6fc88f0d2458821dd4ccc804855b8e1ddd29db492163cd0ffd188196740ac5f6754c02bf622675b28193a8959f8ce8b87fc23fbe4de85107d1f1f3aef9446fd84b80b62265ee1cf1586f2fdb01881eee56a1 +d9b5cf0b50416573ff3c63133275a18394dd4326be2041e8d97e6e4e3855a4a177e9d26dfd223fe8aa74564edb49bd72de19916fb6f001f44530d5c18e2c332bce1b7415df5927ece5f3824f34d174b963136b53aef1fb78fb0c06a201a40b2db38e4d8216fc1e392a798c8ab4b3a314496b7f1087804ebfa89bf96e9cdb80c0 083e7152734adf342520ae377087a223688de2899b10cfcb34a0b36bca500a4dfa530e2343e6a39da7ae1eb0862b4a0d 848f2bc9d84e7fd2dc039e34d642cbe2581540bed9851eb24d7c1ccc87370055dc2948dee7b1c998d82b14a1fcceea5d096fae2dbdcfd8516ccb29f014cfa60f0445d92482c1c3d35a3872bb9bbf0d4c7adff0e8fadad3274e90e7660dba2922 +9e4042d8438a405475b7dab1cd783eb6ce1d1bffa46ac9dfda622b23ac31057b922eced8e2ed7b3241efeafd7c9ab372bf16230f7134647f2956fb793989d3c885a5ae064e85ed971b64f5f561e7ddb79d49aa6ebe727c671c67879b794554c04de0e05d68264855745ef3c9567bd646d5c5f8728b797c181b6b6a876e167663 63578d416215aff2cc78f9b926d4c7740a77c142944e104aa7422b19a616898262d46a8a942d5e8d5db135ee8b09a368 a4a73c7a09fd4c59c60eeb3ac5a3cab85bf7246f334e0f18ba080a46f5352d34dacac914056ec97d6e2be5425daa49a10da2a3bef8b41ffe6a4f9decb78f841db7daea52b2626d62085a36b248cb632135453161d0524176aed9e386267cb121 +0b14a7484a40b68a3ce1273b8a48b8fdb65ba900d98541c4bbd07b97e31bcc4c85545a03e9deab3c563f47a036ff60d0361684ba241b5aa68bb46f440da22181ee328a011de98eff34ba235ec10612b07bdfa6b3dc4ccc5e82d3a8d057e1862fef3def5a1804696f84699fda2ec4175a54a4d08bcb4f0406fdac4eddadf5e29b ed4df19971658b74868800b3b81bc877807743b25c65740f1d6377542afe2c6427612c840ada31a8eb794718f37c7283 ac6997ffa26e0631c75ec3a1ed54dabd96146a9e0944ad6b774d41ec507fc4489444421e6c3e993f9b9c75892c52e5db1461147e8d02e873d83d5008dd3bd26bb9e8a663ca3fea8ceac4b04bc331a1a96bf6ea5d5b6a5cc8b4097bb7b34d336f +0e646c6c3cc0f9fdedef934b7195fe3837836a9f6f263968af95ef84cd035750f3cdb649de745c874a6ef66b3dd83b66068b4335bc0a97184182e3965c722b3b1aee488c3620adb835a8140e199f4fc83a88b02881816b366a09316e25685217f9221157fc05b2d8d2bc855372183da7af3f0a14148a09def37a332f8eb40dc9 e9c7e9a79618d6ff3274da1abd0ff3ed0ec1ae3b54c3a4fd8d68d98fb04326b7633fc637e0b195228d0edba6bb1468fb a0819e4e8bbd289b9762690fca76de4df53a5062acf06724e27f8cc433ba388892c706bd1d0b3962bd542194650c83520fa9506cc5f03551a2a8de5fe0b622651b512103d192cde1db80d25ed5bd89f17fcdecb769e384db87aa04775f582f50 +67d9eb88f289454d61def4764d1573db49b875cfb11e139d7eacc4b7a79d3db3bf7208191b2b2078cbbcc974ec0da1ed5e0c10ec37f6181bf81c0f32972a125df64e3b3e1d838ec7da8dfe0b7fcc911e43159a79c73df5fa252b98790be511d8a732fcbf011aacc7d45d8027d50a347703d613ceda09f650c6104c9459537c8f 217afba406d8ab32ee07b0f27eef789fc201d121ffab76c8fbe3c2d352c594909abe591c6f86233992362c9d631baf7c 8d7ff07f7a3cdb46c5cd8f29825021ff7972c003903d4c9f1bb2e526b1bf603a5f86ac09247a64cec4489d9d1c154f4b0af8eb8c371b8902b9165099488530535c2c2fb1fd1d357d99843b86b60d27f639afebf17242a08ddb02aee545c5824a +45db86829c363c80160659e3c5c7d7971abb1f6f0d495709bba908d7aa99c9df64b3408a51bd69aba8870e2aaff488ef138f3123cf94391d081f357e21906a4e2f311defe527c55e0231579957c51def507f835cceb466eb2593a509dcbee2f09e0dde6693b2bfe17697c9e86dd672f5797339cbe9ea8a7c6309b061eca7aef5 0a3f45a28a355381a919372f60320d6610cfb69c3e318eb1607db3cadfc42b728b77a6a9e9e333de9183c58933daf60f aebf6090fb1d4705f29e2129a77589df1be038e61579034619956418529f83bec7d8b4f844f92709331c1a441532b7b514bd0c87a6d50728aff1b3e649629226e619bcdd007c02dca3636c042b20899e72478f7e1506ba85402233c4955be62d +4672fce0721d37c5be166bffa4b30d753bcf104b9b414db994b3ed33f36af4935ea59a0bb92db66448b3f57dad4fc67cef10ce141bf82c536be604b89a0bc0e8bca605b867880049d97142d30538fc543bd9d4fab7fdbe2f703815cdb6361beb66acff764bc275f910d1662445b07b92830db69a5994857f53657ed5ca282648 2e408c57921939f0e0fe2e80ce74a4fa4a1b4fa7ab070206298fe894d655be50e2583af9e45544b5d69c73dce8a2c8e7 94ae3e5203c4b94ff110200030b2fc0c3f07954d5784506c6fa6f4ca070fdb6ff230aa835c619cd51bad0fb0b9eb3a5908025c14cab9e93936b0d3db12e93a9b77702e85872f1fe321dd69cc31248c1650de0302553a13244fd87c3d6461882b +9ae48fdd9bfc5cb0f4d4761e28b2073bda05a3e3fe82c212e66701dc4573cc67a829b0f82d7520b1bf11db0c6d1743822bbe41bb0adbd7222aa5fae70fbd1a31f2d4453a01c81e064d775388468be96f6063f8673b7b8d4455fe1bd4c801ad5e625a015eaa4a1a18da490d2af8642201eaba3c611cbd65f861d8e19ca82a1ee6 1c285da72a8eb1c3c38faab8d3bb4e68dc95c797082b9a3991a21c1de54759071ecf2265fb1eff504ab24174bc6710cf 83c6030b7fa2a4ed62eb66939cf50a6f00351895d0fa8c36893bcf200a50022460dceeec2e6d6db1a7807ac23ad9c2660b715cfb008c2050ceb021f741c36c7e38e5961203f874ea1aed61d3944dcb24fdc0b3ab53fc4d1e80c9bae30304e782 +817d6a110a8fd0ca7b4d565558f68b59a156744d4c5aac5c6610c95451793de2a756f774558c61d21818d3ebeeeb71d132da1c23a02f4b305eccc5cd46bd21dfc173a8a91098354f10ffbb21bf63d9f4c3feb231c736504549a78fd76d39f3ad35c36178f5c233742d2917d5611d2073124845f1e3615b2ef25199a7a547e882 9da37e104938019fbdcf247e3df879a282c45f8fb57e6655e36b47723af42bec3b820f660436deb3de123a21de0ca37b a8331349d18d001b5c7c4b1e173bd7ef6d0486d233c09c10fbb1d7c0b434b41d2da5099745564cd761a27031e537bba008719931edc09351117b4736f2c432b0bd6c88d1d3c812aaee93dd748e8b82d099c3cecd3030de144e1c80346146c105 +464f10ec6fb229a51db5fd0e122f2cb8a9a022117e2987f4007bf5565b2c16aba0714e2e3cdd0c100d55ac3017e36fc7501ad8309ab9572aa65424c9eb2e580a119c55777676ec498df53ef6ae78fd8a988130ee0e6082bf1ef71cd4c946021018a8ca7154d13b174c638912613b0bdb9001c302bf7e443ad2124ab2c1cce212 0661ab3bf9f7bef51bec7dff758de289154557beb9ce18cc4b8cc09a871e8322af259cf188b593dc62f03a19e75f7f69 962266e7cb0d5e9bc8d17e26f87d2aa2f5c9c75e5f5c65986b45384fdcde5e837f240ba5b19c8c06c6bfdd98b17798280b9299d7892de5b532ecaba3c4a46411eb1accf55322764d1383f86e3dce03907613e927bfed4861c34e00dbea0ddb4d +4e3e0fb96320ddccde8b463c273654c4f7164920b1d63430921d2e808dee403e6420eedda0a557b911d00736a4f8798dd4ef26673efd6d190988ad4929ec64f8685cfb76070a36cd6a3a4bf2f54fb08a349d44642b6f614043fef9b2813b63457c76537d23da7b37310334f7ba76edf1999dad86f72aa3446445a65952ac4e50 66e7cfdeb7f264cf786e35210f458c32223c3a12a3bc4b63d53a5776bc9b069928452484f6241caa3781fd1a4109d4db b83fa045204927ed4fc788af927a9701be74e925d07077f4c399d239f46ab40f3208de3abcbf7c479fd65a5af7b78bcd1855df6764da3e83cf32725adbc1993e61be17f9f98efb03a1b4ff7335a75425011b94644f0c783c05d1e4bb2ca486e1 +c466b6b6baf7e6ffa876ec06105e2d43534e0517c07b1c4c9fb67ba81ce09525a7721ec3c290f2b1f65b6463d41598e7a25b2238501629953a5ca955b644354fb6856733a2e5bb8f5bc21a0c803493f5539f9fb83aab3dba2c982989c2270c61ab244b68bfe1b948d00c2ed975e09c29b5f8a7effcad8652a148cc880d503217 92c2f7ee64af86d003ab484e12b82fcf245fc330761057fec5b7af8f7e0a2d85b468c21d171460fcb829cae7b986316d a7ab6e791e48bed3cc76d24c510df46e0064c584fb38c2991e01eda7cedb5615dbff1dc1653cfe9df5b4bc4f0514c996157e404ff3020554a0b24ef19116757127933fcb8af5592b6ec3a9adba28fc93a76f513a5c16ee4a98585dbb43e8de52 +feac892b7720af80b3c9eede51e923f18d3d0c5de4c31f4aa75e36df7c7c2fd8f41778851a24b69e67dccb65e159dd5c383243bad7cfedcc5e85c8a01c34b0b94ba8e07e4c024c09d279b3731e8b62f9562d3c4f5042567efe42a9d0eaaabab28bc6f11232fc8ceaaf4518d9f3b2bebf020294496b7f6b879e69503f75fecd3d 15347caaad1067f1848a676bd0a8c52021ae604b79d02775a0459226e0391a3acd26653c916fcfe86149fb0ee0904476 9102583a582140456aa9ca586577494f37f73622292de518e5ae27ae14a0a28662f42272069885cdea250a587cf5ad77005b85072f02e62a3958edfa76c6263495d0458dcc9a774d72efc66c33bafa808022dd32273e774cd5ff21b42c65c6a1 +cf2982e3bf174ce547741b969403cd11e9553067e6af8177d89511a0eb040db924530bdba65d8b1ff714228db0737c1756f509e1506014a10736e65be2f91980a73891496e90ff2714a3601c7565cdcef5a395e2e0e1652f138d90d61eaa9cba993b823245647f6e07cec9b8b4449cd68a29741cd1579c66e548ca0d0acf33aa ac1cb5e59bda2eff3413a3bab80308f9fb32c595283c795de4c17fdae8d4647b5f108fd0801aee22adb7db129283b5aa ae48a44f35e7b57656e2a6e8e42ef2a95953fefc65fafca529e9cbaf2c9f083eca12c01f1e21d21949d0ecbd2b038dcd06376713fe41f5e28a9fc0f05f03ea950fbfe2e01ea64ad46c499d08798b76013f68f23288bc6018299f35f4a17044ad +bf9fdd4107ef5a6070108771ac9eee4f0c8043bf0d04db772a47294f4137e2439d94b337114b074e57e0cb78d0ccf352a2833e9788ee2a1a9ffeacd34f38fcefb86653d70c7dadd4cf6548d608e70acdef6c7530974b92c813798add659752a8c72b05e1ad9c65c21834ce6fbe49d8a1426b5a54270794436d284364fac6ec1a 205f1eb3dfacff2bdd8590e43e613b92512d6a415c5951bda7a6c37db3aae39b9b7ec6edd256609e75373419087fa71f 97464a24c4e48968448e0379065038e342520ca2bbb975022d272da3a05875d9e98d458fcb583f74c10c51172e3921020c86cb29c7918a997b9c909e503a54ee98c0bbc379eb84dd54b15d2c50b0fce769ccc48a3d2fe16e65fb5d513ca12e1f +5d634fb39a2239256107dc68db19751540b4badac9ecf2fce644724401d6d632b3ae3b2e6d05746b77ddc0c899878032248c263eda08d3d004d35952ad7a9cfe19343d14b37f9f632245e7b7b5fae3cb31c5231f82b9f1884f2de7578fbf156c430257031ba97bc6579843bc7f59fcb9a6449a4cd942dffa6adb929cf219f0ad e21e3a739e7ded418df5d3e7bc2c4ae8da76266a1fc4c89e5b09923db80a72217f1e96158031be42914cf3ee725748c1 b84e00766c9da085dd37e0f0cd336ddfef81e575a6a67b0fe948826d4749b07e65a5fd0bae0669cfb2b258c76614633f16345d8b52c7501bfa233896a03551c27336bc671343c3fa410673113aaaf88841af830b495ca3815f388f70482252f6 +c9b4ff721b3e886f0dc05856ffff0aabb64a8504b1746a47fdd73e6b7ebc068f06ac7ffa44c757e4de207fc3cbfaf0469d3ac6795d40630bcafe8c658627e4bc6b86fd6a2135afbc18ccc8e6d0e1e86016930ca92edc5aa3fbe2c57de136d0ea5f41642b6a5d0ddeb380f2454d76a16639d663687f2a2e29fb9304243900d26d 93434d3c03ec1da8510b74902c3b3e0cb9e8d7dccad37594d28b93e065b468d9af4892a03763a63eae060c769119c23c 899c09596ac38d8ae66ff28a0c02823564a83941c8017ee6abf4eebff384b13f660e66852f359e5078edfc382c0b4e5e167d78a9a36d5fc8bd5e40d03a557d1c20798cd2f7829c370817e4e0fd7dd0d1abf42a1a6a6b0c9fadf38e558c8acdf8 +db2ad659cf21bc9c1f7e6469c5f262b73261d49f7b1755fc137636e8ce0202f929dca4466c422284c10be8f351f36333ebc04b1888cba217c0fec872b2dfc3aa0d544e5e06a9518a8cfe3df5b20fbcb14a9bf218e3bf6a8e024530a17bab50906be34d9f9bba69af0b11d8ed426b9ec75c3bd1f2e5b8756e4a72ff846bc9e498 e36339ddbe8787062a9bc4e1540690915dd2a2f11b3fe9ee946e281a0a2cbed426df405ed9cb0eca42f85443efd09e0c 8ec3b41fce08db4972ced73fb3635ab3c39bfdbb0a6204f569f0877a70886160e039a0faad178f697bc9753ab8629636026a062b6e5e342b48b5988d6700958f574c60dc61d811fc1ae84c24a0ba2eb0c5dc19f2063e2dd0448100404d64d5cb +dbd8ddc02771a5ff7359d5216536b2e524a2d0b6ff180fa29a41a8847b6f45f1b1d52344d32aea62a23ea3d8584deaaea38ee92d1314fdb4fbbecdad27ac810f02de0452332939f644aa9fe526d313cea81b9c3f6a8dbbeafc899d0cdaeb1dca05160a8a039662c4c845a3dbb07be2bc8c9150e344103e404411668c48aa7792 5da87be7af63fdaf40662bd2ba87597f54d7d52fae4b298308956cddbe5664f1e3c48cc6fd3c99291b0ce7a62a99a855 aa2667b18ddfebd0b445ed09926a64ec02afc91cb7069ea7a92f1fe3b2cca2c38be7d5346bebc879495d84386d579d1704642f46bb2eea315263f3ba9740f5eb9bc3d34143a78ec658e11167ba1ad2fa64518e90e6c0db076a4622b4c3efbe80 diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P521 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P521 new file mode 100644 index 000000000000..00b019afe11c --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P521 @@ -0,0 +1,60 @@ +58ec2b2ceb80207ff51b17688bd5850f9388ce0b4a4f7316f5af6f52cfc4dde4192b6dbd97b56f93d1e4073517ac6c6140429b5484e266d07127e28b8e613ddf65888cbd5242b2f0eee4d5754eb11f25dfa5c3f87c790de371856c882731a157083a00d8eae29a57884dbbfcd98922c12cf5d73066daabe3bf3f42cfbdb9d853 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46 a9f30414fb1d90efc46810becc0feba590c89e66b00a0fa8ee851c133ec13d85cfe28535fc7dbffaa7c46eb6f628fe4217f32e2783574d28c9fdfbc08581d7f4d1a71e411ed7c67320622032cab42d0635f59a6685b06f5d1406f36446dd2601 +2449a53e0581f1b56d1e463b1c1686d33b3491efe1f3cc0443ba05d65694597cc7a2595bda9cae939166eb03cec624a788c9bbab69a39fb6554649131a56b26295683d8ac1aea969040413df405325425146c1e3a138d2f4f772ae2ed917cc36465acd66150058622440d7e77b3ad621e1c43a3f277da88d850d608079d9b911 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73 88fdd0c739df2c66320bed9049966bae29ff9ab5a07ba50d974fa02fc6feda6e425e0cdddbd0693922d019f667cd377f02da5fb8e1a1f8c6a12ef4392e4e984831dad2f39c2347b6b5e12e6e2bda8c84a3f2ac8c8f3d345aed26e94700446983 +7ba05797b5b67e1adfafb7fae20c0c0abe1543c94cee92d5021e1abc57720a6107999c70eacf3d4a79702cd4e6885fa1b7155398ac729d1ed6b45e51fe114c46caf444b20b406ad9cde6b9b2687aa645b46b51ab790b67047219e7290df1a797f35949aaf912a0a8556bb21018e7f70427c0fc018e461755378b981d0d9df3a9 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace 8a14ca15f0fc94d5abf044ed2e6edbf06bec56e1a96523c6fedecc977b412dc45e4b92f2dace503b61b898137d658aaa0f9c9d597a6ff8b4a50fdf823343a5cd6de52ad000feb96800d2a8b594505c775f09f9bbe0b6be7eb89abcacb954cd09 +716dabdb22a1c854ec60420249905a1d7ca68dd573efaff7542e76f0eae54a1828db69a39a1206cd05e10e681f24881b131e042ed9e19f5995c253840e937b809dfb8027fed71d541860f318691c13a2eb514daa5889410f256305f3b5b47cc16f7a7dad6359589b5f4568de4c4aae2357a8ea5e0ebaa5b89063eb3aa44eb952 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc b00f0eb9fd8582f71a44ccaa0c77bef134fed90bf0d6087267be742c722e89f5abf3efd72d007727607521c73b592a8b1326c3b3b82264a5469f5d8ccaa9f4673759b93b707d1f53b755e6c61a6359e8ec2708e14e4ddcab24bbcc04a2456738 +9cc9c2f131fe3ac7ea91ae6d832c7788cbbf34f68e839269c336ceef7bef6f20c0a62ea8cc340a333a3002145d07eba4cf4026a0c4b26b0217a0046701de92d573d7c87a386a1ea68dc80525b7dcc9be41b451ad9f3d16819e2a0a0b5a0c56736da3709e64761f97cae2399de2a4022dc4c3d73c7a1735c36dbde86c4bc5b6f7 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549 a0efd4c8e03369501349cd1b489567c80acf73ac18c3ed0b7c83ab811febbd54de5fe685294d8e52ff1cbe59c0ce373818114a7fc4e73dc2e36cf3c2f7918fc838ec1162aaede52e9a889bcc3be8d9c4645d0604140d0235f15554b86b40367f +14c69f8d660f7a6b37b13a6d9788eff16311b67598ab8368039ea1d9146e54f55a83b3d13d7ac9652135933c68fafd993a582253be0deea282d86046c2fb6fd3a7b2c80874ced28d8bed791bd4134c796bb7baf195bdd0dc6fa03fdb7f98755ca063fb1349e56fd0375cf94774df4203b34495404ebb86f1c7875b85174c574c 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4 b4555293e0c725b68fad38a42d88b77a1406106240d2734c2171e17225be85ef40c4de2929f3282624e7b98371616026086818661bb7ed29268f79fb655a3122b9d2abfce904125a405b9e177c92f1558b7371ab662cb8425bcce707ed769461 +8d8e75df200c177dbfe61be61567b82177ea5ec58e2781168d2277d2fd42668f01248ca3eb29ffa2689b12ae40f9c429532b6d2e1f15891322b825a0a072a1c68fa09e78cfdef3e95ed6fdf7233a43cb68236560d49a3278f0b3f47cb08f475bd9ab2f60755ea4a1767de9313b71a1b9ea87ef33f34682efbda263b0f8cc2f52 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16 8028034d9ad9ba07400ddc34dd1120b6b36a26ffe1a78677c03c055f7bf8598b4857b56e033a762110ac3045765d365b14e0f78977628803dbc7f647af36fdd44a8940b0e0e17a5491e83911f7d05984aab059d9e81b53f9b71fd603ad44abb2 +10631c3d438870f311c905e569a58e56d20a2a560e857f0f9bac2bb7233ec40c79de145294da0937e6b5e5c34fff4e6270823e5c8553c07d4adf25f614845b2eac731c5773ebbd716ab45698d156d043859945de57473389954d223522fbafecf560b07ef9ba861bcc1df9a7a89cdd6debf4cd9bf2cf28c193393569ccbd0398 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37 99e837a2b7ced7d12ce9ae466f775a344be3ae7e02c565cb147fa0e383af9223c3d9874b975698859594c6808c6e361e18327035a85cb7383d15c408e496cd54557237305362ab39c66939689e419690fdf1d38b8681e76788288ca33c8f9089 +80aad6d696cbe654faa0d0a24d2f50d46e4f00a1b488ea1a98ed06c44d1d0c568beb4ab3674fc2b1d2d3da1053f28940e89ba1244899e8515cabdd66e99a77df31e90d93e37a8a240e803a998209988fc829e239150da058a300489e33bf3dcdaf7d06069e74569fee77f4e3875d0a713ccd2b7e9d7be62b34b6e375e84209ef 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256 8faebb987e2ee3b3e47b4e62664de9a4af0d41e58e864773bb525d949e041d24e1501bedcc0a73a90f03f3e60b08b78918e657cc2e3d05ce5ab3898012b32f038e0d1fa30e6e9bdda8b037edd438a4ae98c361b26ac6502d406d13072615222d +8a7792a2870d2dd341cd9c4a2a9ec2da753dcb0f692b70b64cef2e22071389c70b3b188dea5f409fb435cbd09082f59de6bc2ff9e65f91b7acc51e6e7f8e513148cb3c7c4664f227d5c704626b0fda447aa87b9d47cd99789b88628eb642ed250312de5ba6b25f3d5342a3cbb7ebd69b0044ee2b4c9ba5e3f5195afb6bea823d 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7 91bdbe7fa038b14af8583eebf8ac9f9594433a596d705aa6aa96341af149acafd338c568befeccfcb8551ed97aead6a70ee46d07379dce4c93e6bcbc7fcb9010ac9319b7c43ae310c9ccc10108d78eeafb382030a1740ee4d3d9e54d2e1eb96a +f971bcd396efb8392207b5ca72ac62649b47732fba8feaa8e84f7fb36b3edb5d7b5333fbfa39a4f882cb42fe57cd1ace43d06aaad33d0603741a18bc261caa14f29ead389f7c20536d406e9d39c34079812ba26b39baedf5feb1ef1f79990496dd019c87e38c38c486ec1c251da2a8a9a57854b80fcd513285e8dee8c43a9890 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73 832831907cf4ec12c9a9143792f377ba513dc7a4ffe565751c7ac7b5504402c14ee64b061f5a7828529d610ebdf218f110252c4665d3485c582e5852861b2da5f12a7a8bf4c60111606f35f0310ba24578b8c6ffa850d048dda0421945c3edb1 +ec0d468447222506b4ead04ea1a17e2aa96eeb3e5f066367975dbaea426104f2111c45e206752896e5fa7594d74ed184493598783cb8079e0e915b638d5c317fa978d9011b44a76b28d752462adf305bde321431f7f34b017c9a35bae8786755a62e746480fa3524d398a6ff5fdc6cec54c07221cce61e46fd0a1af932fa8a33 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c a1771793fdf2c361ed189e5b1d059aaae8ba39e0603dc811742d2910eb1d4021aa5b5ab6c7784a7f18d91618602697191141efed3752539f22e4d8af0f7d0ac1098fb48df3985930635e93ede322d1ecd265d18bdaf5a0e110cdda4fd107a88b +d891da97d2b612fa6483ee7870e0f10fc12a89f9e33d636f587f72e0049f5888782ccde3ea737e2abca41492bac291e20de5b84157a43c5ea900aef761006a4471072ab6ae6d515ffe227695d3ff2341355b8398f72a723ae947f9618237c4b6642a36974860b452c0c6202688bc0814710cbbff4b8e0d1395e8671ae67ada01 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace 835495197e5038ba1d15c3c5ea66bff1b7548d3911cd11dc3991948eeff5d5404d7543d07b3f83740dbb6ab97f49d58f179c25d4a173fa75f8f1445633a1b9bc93537ae631fa5f1fc03a558e22b4a6c2bb9bd4d5f9f1dc084fb5a5a19ce9fe1e +924e4afc979d1fd1ec8ab17e02b69964a1f025882611d9ba57c772175926944e42c68422d15f9326285538a348f9301e593e02c35a9817b160c05e21003d202473db69df695191be22db05615561951867f8425f88c29ba8997a41a2f96b5cee791307369671543373ea91d5ed9d6a34794d33305db8975b061864e6b0fe775f 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8 93d2513fdb970700cc3a0482309ea49dfe45c668e7983ea04b50b2e4fd05bebce66ba627013354a7d015dae95ca5bab7197c3b653cac2c9d4294780f6b87961f705a67a44462e13439bf12cffe9d123a2aa375ca00b35ccb0f7525f58de85330 +c64319c8aa1c1ae676630045ae488aedebca19d753704182c4bf3b306b75db98e9be438234233c2f14e3b97c2f55236950629885ac1e0bd015db0f912913ffb6f1361c4cc25c3cd434583b0f7a5a9e1a549aa523614268037973b65eb59c0c16a19a49bfaa13d507b29d5c7a146cd8da2917665100ac9de2d75fa48cb708ac79 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad a7008756fa32bddb9a2be5768cb1f2c2655709c1cddb0930b0af8893febedf28da5aac079ab1ff8464426c2030dcf3710d0663663ed580e26b01215824b1ec412e82bd1c965ea78939b150310a55901ceed6efff835868874fbc0c388ca9323f +8ab8176b16278db54f84328ae0b75ef8f0cd18afdf40c04ad0927ed0f6d9e47470396c8e87cde7a9be2ffbfe6c9658c88b7de4d582111119c433b2e4a504493f0a1166e3a3ea0d7b93358f4a297d63f65a5e752f94e2ee7f49ebcc742fa3eb03a617d00c574245b77a20033854d82964b2949e2247637239ab00baf4d170d97c 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a a1e06b7229b1159f1b99b1e83a1311eb975a19c7599ad1327ec8c9c912314d0deccbb840ced3b54ee18dbd8b8dde5fa60808f2ed68d11d0807fd760d65cb5677c757e25f9134d803fe10208115b8772f69c80bd444ebd91364e641a07b3bcb13 +c4bc2cec829036469e55acdd277745034e4e3cc4fcd2f50ec8bd89055c19795a1e051ccf9aa178e12f9beab6a016a7257e391faa536eaa5c969396d4e1ade36795a82ebc709d9422de8497e5b68e7292538d4ccdc6dd66d27a3ece6a2844962b77db073df9489c9710585ba03d53fa430dbc6626dc03b61d53fc180b9af5dea6 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c a3ef4697372b597f81a78aa1cbda429b515f683375902ef4c3fcd727ddce15a164c18fa97f49fec99da86636bf9c7a1014799499fd3e319c38749906f03fcf7de78bcc9ef761f27969131e07279f14ea44afa767a4be0e2581e5ffd27d9ed9b5 +1c1b641d0511a0625a4b33e7639d7a057e27f3a7f818e67f593286c8a4c827bb1f3e4f399027e57f18a45403a310c785b50e5a03517c72b45ef8c242a57b162debf2e80c1cf6c7b90237aede5f4ab1fcaf8187be3beb524c223cc0ceff24429eb181a5eea364a748c713214880d976c2cd497fd65ab3854ad0d6c2c1913d3a06 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d 8b46cf5af1bdc6a3efc8c7ed84b7ff9248cf5cc6cfcb42680e117f44d08825a29dedbe4d6a941ed3d1991355659897d317283bd69d43118cbd357fb26f80ae123bd8948a230f36d085824f0aa436121f6527d61b2a5096e8daeaab3e97511e02 +adb5f069b2b501a3ebb83d4f1808eb07710ac4a7b12532996855a20bcc54b2f76812915f632163c3654ff13d187d007152617cf859200194b59c5e81fc6cc9eb1ceb75d654050f260caa79c265254089270ccd02607fdcf3246119738c496dc3a4bd5d3be15789fc3d29a08d6d921febe2f40aef286d5d4330b07198c7f4588e 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c aa66f224d066e6283587617c4b778e77ff018b95dc451626a6f2572342892f93e14a9da7f993068d4b4ea0a06b5ff58d0318349727ee411ed3c4bc3705a7a2b123da8b6bb6e82c450b42e94f5ef2446021ba4e1c837239cbd776694de8e19367 +f253484d121d1ce8a88def6a3e9e78c47f4025ead6f73285bf90647102645b0c32d4d86742a50b8b7a42d5f6156a6faf588212b7dc72c3ffd13973bdba732b554d8bffc57d04f8167aef21ee941ee6ffb6cce0f49445bd707da8deb35dca650aaf761c3aa66a5ebccddd15aee21293f63061a7f4bfc3787c2cd62c806a1a9985 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25 97f23a96ec3337ba2baffbcec9a3781cf280feaf23a60ad14869b1d70820f09f46771e5b97dd3bf7222f466edb2d9cd7053ca820c4f2709b6bb4ffb14d536f9ece193cd0f427fb064e105bdeba01ec3ebcfc1f522641984087b39913354f3c20 +33bab1c369c495db1610965bc0b0546a216e8dd00cd0e602a605d40bc8812bbf1ffa67143f896c436b8f7cf0bed308054f1e1ff77f4d0a13c1e831efbd0e2fcfb3eadab9f755f070ba9aeaceb0a5110f2f8b0c1f7b1aa96a7f2d038a1b72e26400819b1f73d925ea4e34d6acaf59d0a461a34ce5d65c9c937a80e844e323a16d 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf 96b076a8b78c55bc4745403569e9f896ae86e21224d3a31ab869ecc3d0eef71465568b5a2bb9fa91d2f0ee31489bf3f619c17cd0d684edb8e5ed03c607971f6b00ccd79b7d8934c2ef2259aa07db5b7874c4b009b42737c3503213d94bdea67c +08c8b7faaac8e1154042d162dca1df0f66e0001b3c5ecf49b6a4334ce4e8a754a1a8e4daf8ec09cf1e521c96547aed5172ef852e82c03cddd851a9f992183ac5199594f288dbcc53a9bb6128561ff3236a7b4b0dce8eaf7d45e64e782955ee1b690ce6a73ece47dc4409b690de6b7928cbe60c42fc6a5ddf1d729faf1cc3885e 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570 940c75ae2edf0b875807d39262a19badf8d8a04aec6c924ceb6f555880364d24824d7c4d59649ebaec16886ea8dba554105c2afd996336fea27699815a0c843d5961c3891116b556b9c7cb674a3a41de9623983cd95afb6bcb3bf897447a7ded +ba74eed74282811631bd2069e862381e4e2a1e4e9a357b1c159a9ce69786f864b60fe90eeb32d8b72b099986fc594965a33285f7185b415df58fead7b8b50fc60d073680881d7435609ad1d22fd21e789b6730e232b0d2e888889fb82d6ad0337ab909308676164d4f47df44b21190eca8ba0f94995e60ad9bb02938461eee61 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6 b3cc91ea4cb55983fec0fb3e870c02ed124369decbb8a7217741addcb38ba1e329c5d89c5b8a72c17c728a0854190871121dff01718f4e04fdbee7daf0041987e0ed789f7eaf6e8e0f27a03f3c78a901ad11dae3810c751a79b949d0be964da4 +dc71f171a28bdc30968c39f08f999b88dc04c550e261ecf1124d67f05edeae7e87fe9b8135a96fe2bc3996a4f47213d9d191184a76bd6310e1ee5cb67ea7fc3ef6f641a0ba165198040fa668192b75a4754fc02c224bd4a74aade5a8c814adf151c2bfeda65165a04ef359e39847c84e312afb66d4cd1db50d41ef3fe5f31296 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7 94d62f628f9064c24b0664356673683cac7449358fa995b7ce7f58162df9358f4fdad2d451131fec5758c0bca163a6160cca25f53e426039ff1b82314a0b0dea1dc223162ec332584fbb2f578bf84704740feaf19f902a2c605a8b8e305c0335 +b895788d7828aaeace4f6b61a072ffa344d8ea324962ba6dab5efda93f65bf64a0f2ac6d5721d03ee70e2aef21cdba69fd29040199160e3a293b772ffb961ed694a8dc82800dab79367a4809a864e4aff6bc837aaa868e952b771b76591c0bb82249034e3208e593d85973d3fea753a95b16e221b2561644535c0131fe834ae7 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e a12aee8ef42229da4a4d7797045699951f1dd30b7c8143da4bf8fe1d9669251b112a80c1d15439e23dfcc5122d3e86df10a33618d7434585bc756d55e66501c05979047e5921305c6c3c29f4713215dcd7f649c384c1ba5eb075cc32386d885c +2c5bd848c476e34b427cfe5676692e588e1957957db7b5704492bd02104a38216535607f5d092dc40020130c04a3aaf0f1c52409834926d69a05d3f3188187a71d402a10ba34eac8629b4c6359b1095f30f710219298bf06b9f19bfc299981d7e251ca232a0a85338a7e02464731d1b25d4a1f68baf97064516590644820c998 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938 910d18428819b1a26977a5a6e00baff3e7ed230f9086997c27777d71d03d0538bb1cc2edb3128dd08f6a7b7b78e9432607571a0d8d7e1e5647bb3073486f16fae740ce048d388c6902597f86b1425b253e6237b0a2a76f3d3e9ce7516d1ca3f8 +65a0b97048067a0c9040acbb5d7f6e2e6ac462e1e0064a8ce5b5bbf8e57059e25a3ef8c80fc9037ae08f63e63f5bdb9378c322ad9b2daf839fad7a75b1027abb6f70f110247da7e971c7c52914e5a4f7761854432fa16b2a521e7bcaee2c735a87cad20c535bf6d04a87340c229bf9af8647eedca9e2dc0b5aa90f7fea3cdc0a 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662 8dc708664753bfad7c25b8be5379c7183c825c9d92452edb3e812fa04c7c26edf6367b5df5790051f980d1d5e0efbbc80b3f295b21c34afbdba10f9208ae95b17e2cc13cdd4529ab6ed095399c045817f1c4a4e056b3ae161629e936584e9287 +d6e366a87808eea5d39fe77cac4b8c754e865a796062e2ec89f72165cd41fe04c48148068c570e0d29afe9011e7e7a2461f4d9897d8c1fa14b4ff88cab40059d17ab724f4039244e97fcecb07f9ffeec2fb9d6b1896700fe374104a8c44af01a10e93b268d25367bf2bef488b8abcc1ef0e14c3e6e1621b2d58753f21e28b86f 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721 8b56f1926935801c9fe179bb2586c96959386e7aa6f9441d3072e2a0860112f99f80c055a9eac42d2f0802b6e1aeb9fc0784db830583b554d28b70ddc47adee015f0e64bdf806a9fc0e5d27b20177c5492801f700b4aa57ecbfa07f4e5669d4a +f99e1d272d0f5fb9c4f986e873d070ec638422bc04b47c715595e2cf1a701cdf88bc6c4b20085b357bad12ccba67cac8a5ca07f31ba432f9154ff1fadefd487a83a9c37e49fb70a2f170e58889cab0552e0a3806ccfa2a60d96e346851d84b7de6d1a4b8cf37567dc161a84f13421e3412457d4bc27f6213453c8519a2d7daa2 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e 93064bda0e957b9d8eb341d2aace930ddfc81d6d2490f8f83cb85c8dffbc5fa19a0d6ea0c3bfbe4447cf1b3daea145fa0e9ddb9fef974007bd765ae7577c9ced616cfdcb77a4f3791e68b2f10343fd693b744b0fe2fa9a1626b0f25d25cbdb7f +91f1ca8ce6681f4e1f117b918ae787a888798a9df3afc9d0e922f51cdd6e7f7e55da996f7e3615f1d41e4292479859a44fa18a5a006662610f1aaa2884f843c2e73d441753e0ead51dffc366250616c706f07128940dd6312ff3eda6f0e2b4e441b3d74c592b97d9cd910f979d7f39767b379e7f36a7519f2a4a251ef5e8aae1 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418 b35948b65b2529f275a65f251284a6f8c6a1af2c4a90db7060ebd7cc977ef7f6e67c6acb0005354079785e646b8ff8bb04ee636138ffa074830bbf67b6a97bd68e184a9f5432437e1e83c0590f667d97aea681e2bc74ec8d3a1eb2d0763c8f5b +dbc094402c5b559d53168c6f0c550d827499c6fb2186ae2db15b89b4e6f46220386d6f01bebde91b6ceb3ec7b4696e2cbfd14894dd0b7d656d23396ce920044f9ca514bf115cf98ecaa55b950a9e49365c2f3a05be5020e93db92c37437513044973e792af814d0ffad2c8ecc89ae4b35ccb19318f0b988a7d33ec5a4fe85dfe 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950 8aef7df4c9ed79ec2a50b25265e12377b00680999689cab9bb8956399e6b98ef58dbac1d527eed79369b8e6a1e139423005836c3c28bf3510d2a5f42df7c376c5798dd4ddf75ee0784d72672cb5f97b6ea1b2db572ac01cbcf59d74ba8c6cdf5 +114187efd1f6d6c46473fed0c1922987c79be2144439c6f61183caf2045bfb419f8cddc82267d14540624975f27232117729ccfeacccc7ecd5b71473c69d128152931865a60e6a104b67afe5ed443bdbcdc45372f1a85012bbc4614d4c0c534aacd9ab78664dda9b1f1e255878e8ac59e23c56a686f567e4b15c66f0e7c0931e 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b b8bd0527d79eb8c3e3ec39baf3a9a4c5f5919a5d71ac22b300e85114c44d3309c221bd1755fc3f0222f47479ce7b4c470f1cdbe91a87eccc10aff8eb29b58a5e439d930357adee1d0e3c240988db859e34eaa0e32f6d1bc933664f343afea5a6 +6744b69fc2420fe00f2352399bd58719e4ecdd6d602e2c80f194d607e58b27a0854745bfd6d504de2eb30b04cee0f44af710dd77e2f816ac3ac5692fad2d1d417893bb0edba2707a4c146a486f8728ca696d35cc52e9c7187c82d4bdb92eb954794e5ad15133f6bfea1f025da32ada710a3014cf11095b3ff69a94d087f17753 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f b959882c8600368bc25bcf8640242bb1c109d25302de0519c1e586bdb9116ca6f38768338939bf8367026332df7a5ecd14ca778c2283e0a90a6c587841223e68bf0b7221e4fba0f1f05642f36c9bf8ae344675ae7230622aaa9591d92b23d885 +16001f4dcf9e76aa134b12b867f252735144e523e40fba9b4811b07448a24ef4ccf3e81fe9d7f8097ae1d216a51b6eefc83880885e5b14a5eeee025c4232319c4b8bce26807d1b386ad6a964deb3bdca30ee196cfdd717facfad5c77d9b1d05fdd96875e9675e85029ecbf4f94c524624746b7c42870c14a9a1454acf3354474 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66 a909bb09ffda617f6e1da8dbff6cd709ddc55d4f96cbc875c0066b6e27e376e330e2772629e3e377a89ac6187d5160c8055ae821d2a920084e347d68bfc76a0697112391d6f825ddcbc6b3ba0aa0d0f2c1e4a887690da91e0bbef21257d9fa07 +a9824a7b810aa16690083a00d422842971baf400c3563baa789c5653fc13416111c0236c67c68e95a13cec0df50324dcc9ae780ce4232607cb57dd9b2c61b382f0fa51fd4e283e2c55ffe272597651659fbd88cd03bfa9652cd54b01a7034c83a602709879e1325c77969bebfd93932ce09a23eae607374602201614ff84b141 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c b1811b6eadc0423daa82ef751de9e43f998f0aee7e75c2a325559ab363ee942bb1603f853f30dea71b5c19c13d51c5c814b7244703c37558dafdf42da1774e9f8006044f09b57af00f1cc29da6a469a5a08c2986151e374e8455bcade1a0bb1e +90d8bbf714fd2120d2144022bf29520842d9fbd2dc8bb734b3e892ba0285c6a342d6e1e37cc11a62083566e45b039cc65506d20a7d8b51d763d25f0d9eaf3d38601af612c5798a8a2c712d968592b6ed689b88bbab95259ad34da26af9dda80f2f8a02960370bdb7e7595c0a4fffb465d7ad0c4665b5ec0e7d50c6a8238c7f53 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0 867868b2b4375c4afb9536d37c39c6ad45198bdc692f5072715f6c3d8cae558e34ad03fc89e107b9b6ba4ece76d427b50e1d552e5802c8029160ee41209f16ce30b599a1d823a5935718943e85748b0f0a6e9308ab1b9e0f74c65832bd5f6f94 +09952b1e09995e95bf0022e911c6ab1a463b0a1fdd0eec69117b34af1103c720b57600217de7cd178fef92de5391e550af72a8dcf7badf25b06dd039417f9a7d0f5be88fcd4e9655931d5b605452a667c9d1bae91d3476e7d51cff4108f116a49966fb3a7cff8df1c09734ce5620faf2dccb3dc5d94e7e9ac812da31f6d07a38 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9 a3db9c50cb24a95e3f57c820a1429c0a72da11decdcf526399d2a9a3d29682b8eba9d09b4fa115819ff895cfd64f454c04a03ea6edf970a1c3aca5ea6453da79d42b216941db38055e037f4423ce199bafcb0b908a6bb6ca8112f472eb4dffce +0bb0f80cff309c65ff7729c59c517d50fc0ed5be405ef70cb910c3f62c328c90853d4473530b654dda6156e149bc2222a8a7f9be665240e2fbe9d03f78a2356af0bacd1edb84c4801adc8293a8a0bd6123d1cf6ba216aca807a7eb4dca76b493eb6e3dbb69d36f0f00f856222f24d9b93ec34c3b261be2fca0451c00571928e5 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d a7aab3da06db3317f0c781efbf6e25e2f3aa60217df903f69d37c0de99b0031b26e0db072c7dd09ba5cd17e52aa1e108009b7f353410ecc551da829ceace0f69ad330ba39c032bbf5f488fe46c396741f71693a15eba937da7c90fb1ece90144 +7efacf213382ce30804e78b7256854d759147dba9729c51b2759465715bf2c421034c23dc651c13d6cce95f71fe6a84dfbee5768163ac5789ac0474c5ddf4115684683c5f7c204b33b8bcc0c03ac58f66cef2f53b721fe2fac91ad841126101a88f512a7c2ded38549d9f050d4b7961dda48a1489f026c5d111701762418cfe3 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490 ad4fc1b1d843ec3237b548be13675ced09db4769c0dc43619f9a4902c69c2418b3008a7746202ea59298834fe9fe298d09f80ad9ace77a6df5f45700848636f1ce78c3c2f11c71f3c068b212023a662ac9de8b0e6da3744d374df31901f251e3 +28edff8b9d85f5f58499cc11f492abdfab25e8945975bbaeee910afa2b8fc1295ec61406309ce4e09f4ab4f462959fc2a2786802466eb26d3b01be6919893ae75d0fdc2dc8a82e662550f9fce9627dd364188aaba5c6faa1b2d8a2235adfa5ad0dc140f88a2b2f103f5690e877d07fe8fd30d02d2b2729bd3d8eb5b23a21f54c 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1 b7c3dc213652a8552bb95959a44d1778dd5c4e1a5baa20726595935339bb9d476c7193d4be2579eb5335473a6f751842090785b098e907a611cb91c330d0d0abcd0655332afeac90137b39b4923b582fbe72d9b54b8c536e2761a89e1035eda3 +bae2a8897c742fd99fbf813351cd009d3f2e18d825ca22e115276484bce8f82f8c7c0c21dd2af208404d8ef45bb5a6c41693912b630897d5246801bf0775aa9bbac8be98cb861d172c3563dc59e78a58ed13c66dea496471b3ad0eeae8995293e4ab97373edc1837ffc95ff1cc0c1e90e64ea8680b2ca5f1e09bf86b99b343b6 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745 8718b372f8c82e21e0c4277bf3b4c198f94b2952e6a80ebeb658f8721b21eb2936effa00e9f7adc950c28f3e42f78a6213cbb9bb558740bcd54048f0bf085bc63f2a79d15eb8003800a0e40a6fee0d3c9f256d7ebd94a8f950f1e805df3f8fab +d57a26a9593e72bfc87322524639bcaae5f2252d18b99cdaa03b14445b0b8a4dd53928f66a2e4f202fb25b19cad0eb2f1bfda2ab9b0eb668cdcd0fe72f5d9ef2e45e0218590f7ab9d2c9342202610c698bc786cce108a7d4a6730a13e9ea1b470e781f1237d3f84f44abde808516975546bd89075ef9a9732bfd7ee33b6f4399 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f 847db1b384d0e6b5c1c4d00404625fb6c23bce8ecd1260d0eed5dcb9da3bd588b723cf6d334de2c19997f3eef2ff318f138acc0b63800ef3241c4cba1c894213278970c3829343e13c943656637c69dbccc69f75bbe06042f1b95c84bb42d41e +8fdcf5084b12cfc043dd3416b46274e021bbed95d341d3c500c102a5609d3a34de29f8fa9f0adb611a1f47a97ad981f8129d718fc0d6c709eab1a3490db8d550f34eb905b9e00663543afc5bc155e368e0bc919a8b8c9fa42093603537a5614927efa6be819ed42ececbf1a80a61e6e0a7f9b5bc43b9238e62d5df0571fea152 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e 9486e50bd9f643b6de11cb1a22ef08c1d640bdb725d024b2dd1707c35cb9b2b07479311c07238a88f3c810128cd5a5530246bf04553ea2d71b6936172a704fc05fb2db2564cbf6a5a849bf06958538940e4b698342e160332f541aaeb91dbe00 +00669f433934992257bed55861df679804107d7fa491672574a7624949c60049b0533383c88d6896c8de860704c3e6a6aefce83efa57c4d57e9ab253da5d15e1f53ab6dce218b592772ab0bc01fee8e63368e85c0639301456fe2d44cd5396a7f2b22761cd03b80eba7883eede8249a2f5db2183bf00550c5c002f45a5e4fb31 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89 93fa86469e7373a8d43f6da52057fede6bbf0c86669c2dd8602745890eebd58784ac82f70db18793089036bb56a0a195146c7f21135a101159ac92cce2fb23b75b87fc0ec937da66bf23413099dae6832866038b59db97868aa58e079ead2514 +4be81dcfab39a64d6f00c0d7fff94dabdf3473dc49f0e12900df328d6584b854fbaebaf3194c433e9e21743342e2dd056b445c8aa7d30a38504b366a8fa889dc8ecec35b3130070787e7bf0f22fab5bea54a07d3a75368605397ba74dbf2923ef20c37a0d9c64caebcc93157456b57b98d4becb13fecb7cc7f3740a6057af287 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a b3e56c5908108841b164c0fc4040f92ea1536bca353d30da8b3ae58046f80cd6486086273cc0da70c8c9e661637a83df13bc2e444b4c3048cfb0e20b175e908972659c8ed9b6f8d26f58bb9a1aefe60b8bfac413b6cf7a6b788d2fd4c8f0fa8e +9ecd500c60e701404922e58ab20cc002651fdee7cbc9336adda33e4c1088fab1964ecb7904dc6856865d6c8e15041ccf2d5ac302e99d346ff2f686531d25521678d4fd3f76bbf2c893d246cb4d7693792fe18172108146853103a51f824acc621cb7311d2463c3361ea707254f2b052bc22cb8012873dcbb95bf1a5cc53ab89f 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926 a165ed424240ac7810ca20792812cefa1062b9e7b88ea685e423058fc8c1b9f815150a31fd6565d893adb21bfcdac6dc12cc761046e5b97335b22d1b3c6dfba667d6d2f04b33efec5383a49e2cdce9fe3f3e530d7326b6e5b6589f1fd9ac5805 +b3c63e5f5a21c4bfe3dbc644354d9a949186d6a9e1dd873828782aa6a0f1df2f64114a430b1c13fe8a2e09099e1ed05ef70de698161039ded73bcb50b312673bb073f8a792ac140a78a8b7f3586dffb1fc8be4f54516d57418ccc9945025ce3acf1eb84f69ceee5e9bd10c18c251dbc481562cd3aae54b54ab618cb1eeda33cf 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6 af05cd9b70241ad6cb4248d3834b91b677c79362f0cf5943fb03e9a754c2ef66561e511b0ea952c6045f2ca7e56e364f13703799907d9408c161fa499e7043bef00d9e288d0a35654308ce9b46ae3cefe4950854e4e3b7b4ec582fa8b4b59709 +6e0f96d56505ffd2d005d5677dbf926345f0ff0a5da456bbcbcfdc2d33c8d878b0bc8511401c73168d161c23a88b04d7a9629a7a6fbcff241071b0d212248fcc2c94fa5c086909adb8f4b9772b4293b4acf5215ea2fc72f8cec57b5a13792d7859b6d40348fc3ba3f5e7062a19075a9edb713ddcd391aefc90f46bbd81e2557b 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f 8c8343b21d73d9777af2ec4ccc626e8d8ef606f61a5eb46c8c2b76294b0cf93ba0b62d5bd7b2e8d486102ff93e715e75074241a778b2428eee3a8f6769305771431e83e7a52886e68da47bc0e89bc5f055ee5be077b4b7a9354ab649988543b7 +3f12ab17af3c3680aad22196337cedb0a9dba22387a7c555b46e84176a6f8418004552386ada4deec59fdabb0d25e1c6668a96f100b352f8dabd24b2262bd2a3d0f825602d54150bdc4bcbd5b8e0ca52bc8d2c70ff2af9b03e20730d6bd9ec1d091a3e5c877259bcff4fd2c17a12bfc4b08117ec39fe4762be128d0883a37e9d 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742 80268b857c9108c7a10f1fa1980d149c81a22d8836fc83a6b2513e597a30b584fe2522b1815d040a50226e712a9a47980c81320c52f27885ccce07455a7eb8039f21fe6d76faea6084609e79ebc66cd622fb610d182ab1d62d00df16dd70bd93 +a1eed24b3b7c33296c2491d6ee092ec6124f85cf566bb5bc35bffb5c734e34547242e57593e962fb76aee9e800eed2d702cc301499060b76406b347f3d1c86456978950737703c8159001e6778f69c734a56e5ce5938bd0e0de0877d55adeee48b0d8dfa4ac65fd2d3ce3e12878bac5c7014f9284d161b2a3e7d5c88569a45f6 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697 90a022d751e43bbc746ee753b6d311e95400ef89cb5aaebad3c5df071cad0341f4ecbce34d4d8ffe3c86b4f42fbff9e70c848615fe6c954fd162636aed1cf409343c2941a3422ee2c19b70e42374aba716f39fb957bd87c4b2ef62ecd43e12d5 +9aace26837695e6596007a54e4bccdd5ffb16dc6844140e2eeeb584b15acb2bbffd203c74440b6ee8db676fd200b4186a8c3e957c19e74d4d865ada83f80655323dfa3570907ed3ce853b6e8cc375ed2d758a2f5ad265dd3b47650517a49b3d02df9e0c60c21576378c2b3a08481eec129b2a75608e13e6420127a3a63c8a3f1 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04 a3b1e2e8c069ca59d086eb5656b176103e9361d0af4aab204074bf4efc427a404771c4474e7d073645118ff8a36f8ac917c146b804be74a26d59a5b1c6f15521a4a1b05891dda9bb1dfca433e4f38a04110fc2cae375d96fc25e8702f1aef2c8 +ac2175940545d4fbab6e2e651c6830aba562e0c11c919e797c43eff9f187a68a9e5a128e3e2a330b955a3f4577d3f826529ad1b03d7b60f7ad678f005053b41dc0f8d267f3685c6abe1a0e9a733c44b2f3ca48b90806f935141c842e3a6c06a58f5343d75e3585971a734f4ae1074ce5b54f74bd9342f4bbca738d260393f43e 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6 ab02937a1e718581f6aa8501846c67ef4f7cfc6d7d63bfbe267f9dba6c452d9cec1b1fc8d896d8f06f453acebbe48b520355bb5c1b6700d5629be8614b68de4f78d6f990a2817c46b3677c43b1cc3381246ae21e2da8932598f4e47512464c5b +6266f09710e2434cb3da3b15396556765db2ddcd221dce257eab7399c7c490135925112932716af1434053b8b9fe340563e57a0b9776f9ac92cbb5fba18b05c0a2fafbed7240b3f93cd1780c980ff5fe92610e36c0177cabe82367c84cee9020cf26c1d74ae3eb9b9b512cb8b3cb3d81b17cf20dc76591b2b394ef1c62ac12ee 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e a663f388b16a774368a7e9434bfd46700caff7b438d85b16003db663aae0efaa4b923fabf9e149d443e5dd1800690902030292165ed9194da4581eb5b721d7e51be541b693951490dca9b9992c5c23458090998717fde0dccfd915a48ddde790 +3de9e617a6868dca1a1432d503f923535da3f9b34426b2a4822174399c73b1c1ee67311410a58c17202ac767844b2024d8aa21a205707d93865693ac25a24fc87034fa3a7a7e27c3344cb03b87602c15180a5fe6a9dd90cd11af4a0f150207bf2d83f55b12c088adae99aa8cfa659311b3a25beb99056643760d6a282126b9b2 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5 989767975ccbfb9475392959fe1ce20c9ad5c4d1b962e267b9556fe373e3473eb8b3aa69902de606dfdc45b8a3853388185901e6abb55e4477983d5d519e68ef70cfa566240a907b809188c542024d8dd1b10f5a74dc78a25a7f51e97d05830b +aa48851af7ef17abe233163b7185130f4646203c205e22bcc2a5a3697bcab998c73a9ffe1d3ea0b7978ce7df937a72586eb5ca60b0d939a7d1c115c820171c89c8116b7e2c7b98cf0f14e4c4df3cb2f319ad3ab0ea25ff14526ddc037469f000bf82100acd4cdf94feb4eba4ea1726f0569336604a473aee67d71afebb569209 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a a48a48e05a9724b817dc246c9884a79b0a84b0bf5bf9fadb7fe6dfe042ad8230211b83ce4dfa14002af7c1f4b220f6db169466fa5fae6aaf968e3d6a885899e20a10e20976be1c7a060ea1cefe51c8c24a16b8b6bab505f064b2b8dfce655286 +b0d5d52259af364eb2d1a5027e5f7d0afe4b999cc5dd2268cfe76f51d2f17b541bdd7867e23a1bb897705153d9432a24012108979c6a2c9e2567c9531d012f9e4be764419491a52eae2e127430b0ab58cb8e216515a821b3db206447c235bf44ee304201b483b2a88844abaa18bca0147dfff7e502397dd62e15524f67eb2df2 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb 98259eca98df63cef8b808ee63159b095ae7e29de38ceab90087f6cf161e2a6397c91dfeb892b610d94726810406c7b910b60eb9293194024edd7bd0faa6922f84fe2b764c51639d4c1bf84b420dc0e631d25afb25bbaca1d07e96c069b6e5d6 +9599788344976779383a7a0812a096943a1f771ee484d586af1a06207478e4c0be9c200d42460fe837e24b266c8852d80d3c53cc52ffb1913fc3261145fc6da575611efd16c026059a2e64f802517ffd1b6b34de10ad2909c65c2155e8d939b8115400c1d793d23955b15f5d1c13c962ff92b4a815cee0e10f8e14e1f6e6cd38 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77 ad378ea96afb1b4b6fe1e0650ee6e2ac2988308f775661b565e9b4818f747903e92d51791ba1e60d45718327c7ecd6b002a8b416bc3a1b4583abd0f0701a58983fea3cb35238cb4a172906c5daedf3062ce8326f9973e67529f0afde6f8f3df1 +fdde51acfd04eb0ad892ce9d6c0f90eb91ce765cbe3ce9d3f2defe8f691324d26b968b8b90e77706b068585f2a3ee7bf3e910528f7403c5af745a6f9d7ba6c53abd885c3b1be583415b128f4d3f224daf8563476bd9aa61e9c8518c144335f8f879c03696bddbe3ac37a8fbede29861611feaa87e325e2f60278b4893ed57fb0 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c 96610dc24a4da9622aa2c1b86b750f33e6400e6b1ce0e277e1e927d805f00ac8c86290e04bc16e4e261d3b3798fc5bba1117ed1ed044569bd6856bf45d53becf021c907aaf5a3f8a2494d6eb37d9b69c255226726eaf6862cb73241c1b2a2352 +beb34c997f905c77451ac392f7957a0ab8b23325bd5c63ca31c109ac8f655a1e3094240cb8a99284f8091de2ab9a7db2504d16251980b86be89ec3a3f41162698bab51848880633e0b71a38f8896335853d8e836a2454ecab2acdcc052c8f659be1d703b13ae1b090334ac50ab0137ddb5e8b924c0e3d2e5789daaef2fdd4a1e 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63 a37ee3402f9919e9d9706b7363945845480578213f44a7dadea94eb60f90df71366301049313592d34da2ca717d954e4093732963f76a2f0b64b7898fa7d80129266e2e17b80bb002924f8f40d7f3c6a3ccfd101373ddbae8f0a53555b2440ef +543c374af90c34f50ee195006d5f9d8dd986d09ad182fcbefa085567275eee1e742bfe0af3d058675adeb5b9f87f248b00a9fbd2aa779129123a5b983f2f26fc3caf2ea34277550c22fe8c814c739b46972d50232993cddd63a3c99e20f5c5067d9b57e2d5db94317a5a16b5c12b5c4cafbc79cbc2f9940f074bbc7d0dc71e90 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da 8e2d390d79fd0f82fad1a95922770461bed36c5eac63f0016638c09678ab6a5fe33d171e0c10b5fdf428744a9a3f0e7208e981ca37dedb3875b9c8b5c379b499122bde4abc4356ed5b7e397ca42b0455e3fa6eea90adeb5544839ad373631bfd diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P521_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P521_blst new file mode 100644 index 000000000000..26625d0d6edb --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_fips_186_3_P521_blst @@ -0,0 +1,60 @@ +58ec2b2ceb80207ff51b17688bd5850f9388ce0b4a4f7316f5af6f52cfc4dde4192b6dbd97b56f93d1e4073517ac6c6140429b5484e266d07127e28b8e613ddf65888cbd5242b2f0eee4d5754eb11f25dfa5c3f87c790de371856c882731a157083a00d8eae29a57884dbbfcd98922c12cf5d73066daabe3bf3f42cfbdb9d853 01d7bb864c5b5ecae019296cf9b5c63a166f5f1113942819b1933d889a96d12245777a99428f93de4fc9a18d709bf91889d7f8dddd522b4c364aeae13c983e9fae46 853d6ec55d3f75e928ff3031b8676a14b04a696ada8136547217c922e06aca4f9c77876dc6f4c912fb2bc1385ad0bd760e2b280b8697bc0ae72fcb6d7435141ff0fe8313f2849b404ee98157b1013b1434fe6fdd0a3f373569038371aae6b6a1 +2449a53e0581f1b56d1e463b1c1686d33b3491efe1f3cc0443ba05d65694597cc7a2595bda9cae939166eb03cec624a788c9bbab69a39fb6554649131a56b26295683d8ac1aea969040413df405325425146c1e3a138d2f4f772ae2ed917cc36465acd66150058622440d7e77b3ad621e1c43a3f277da88d850d608079d9b911 017e49b8ea8f9d1b7c0378e378a7a42e68e12cf78779ed41dcd29a090ae7e0f883b0d0f2cbc8f0473c0ad6732bea40d371a7f363bc6537d075bd1a4c23e558b0bc73 985e58379c325af437ce40f1416190d6b02e6652a5b5141674e004a7ed8b888ac6055676ded9769cd65fab73c6a548a9089296a78541a4bddfac422e5ee3d36cf3f7da090d7d071196ee95add8a103f8ce42fb879fbbd8b76da6ee6e7db5f540 +7ba05797b5b67e1adfafb7fae20c0c0abe1543c94cee92d5021e1abc57720a6107999c70eacf3d4a79702cd4e6885fa1b7155398ac729d1ed6b45e51fe114c46caf444b20b406ad9cde6b9b2687aa645b46b51ab790b67047219e7290df1a797f35949aaf912a0a8556bb21018e7f70427c0fc018e461755378b981d0d9df3a9 0135ea346852f837d10c1b2dfb8012ae8215801a7e85d4446dadd993c68d1e9206e1d8651b7ed763b95f707a52410eeef4f21ae9429828289eaea1fd9caadf826ace 8220fe6980900bca9154b127c1a81dc25fd199f88c3c3d4a26628c2381af3456c36edbf028dcd9c940204d4e61eced2a06c504d5191f3d76c64fca0e4c3b8ebe210ac353cc4f4aa68aa9f57206b434894fabae8f7cf505e8d9bd12bcec0b8641 +716dabdb22a1c854ec60420249905a1d7ca68dd573efaff7542e76f0eae54a1828db69a39a1206cd05e10e681f24881b131e042ed9e19f5995c253840e937b809dfb8027fed71d541860f318691c13a2eb514daa5889410f256305f3b5b47cc16f7a7dad6359589b5f4568de4c4aae2357a8ea5e0ebaa5b89063eb3aa44eb952 01393cb1ee9bfd7f7b9c057ecc66b43e807e12515f66ed7e9c9210ba1514693965988e567fbad7c3f17231aacee0e9b9a4b1940504b1cd4fd5edfaa62ba4e3e476fc 85b064ee1ab3ea10b3b7d437b49ee606944d1f739b0b8e1f8cf8da593225ce607ed5502469ac997c2f9e3c612fedbe9b0e4d54f3b6586ebb1b6de66211b5cc7b82513018bb7d73105e85c08fc7857fa04e4893a201ae801dfd72f038216f86e6 +9cc9c2f131fe3ac7ea91ae6d832c7788cbbf34f68e839269c336ceef7bef6f20c0a62ea8cc340a333a3002145d07eba4cf4026a0c4b26b0217a0046701de92d573d7c87a386a1ea68dc80525b7dcc9be41b451ad9f3d16819e2a0a0b5a0c56736da3709e64761f97cae2399de2a4022dc4c3d73c7a1735c36dbde86c4bc5b6f7 0179fa164e051c5851e8a37d82c181e809a05fea9a3f083299b22684f59aa27e40dc5a33b3f7949338764d46bfe1f355134750518b856d98d9167ef07aac3092c549 82379a47345a1690738d76d7ede8e91f4a75a66d97c36c25f49faf1745b38c0afb68fb148896d8cf7a4ba453a0910d7d0146298b91a0e393a7a76be3555f2b9bcde1982ab1c2ef8d357c0afc827212a33e0b197278f89bcb2073bcaac7f8ed01 +14c69f8d660f7a6b37b13a6d9788eff16311b67598ab8368039ea1d9146e54f55a83b3d13d7ac9652135933c68fafd993a582253be0deea282d86046c2fb6fd3a7b2c80874ced28d8bed791bd4134c796bb7baf195bdd0dc6fa03fdb7f98755ca063fb1349e56fd0375cf94774df4203b34495404ebb86f1c7875b85174c574c 013dabca37130ba278eae2b3d106b5407711b0d3b437fbf1c952f0773571570764d2c7cb8896a8815f3f1975b21adc6697898e5c0a4242092fc1b80db819a4702df4 9939708540558f47b783b7935bae91ba1e6a7cac9b5f23e0e789b2e56fb4e489d77d33c02db2d50c9ea78738143d31900966512324253899114de11ade7eb45fcdd121a966dd4ed396919e2cff478cb51bc901f1dac9646a553c986b56390045 +8d8e75df200c177dbfe61be61567b82177ea5ec58e2781168d2277d2fd42668f01248ca3eb29ffa2689b12ae40f9c429532b6d2e1f15891322b825a0a072a1c68fa09e78cfdef3e95ed6fdf7233a43cb68236560d49a3278f0b3f47cb08f475bd9ab2f60755ea4a1767de9313b71a1b9ea87ef33f34682efbda263b0f8cc2f52 0198681adbde7840d7ccd9cf1fb82056433fb4dd26bddf909af7b3b99da1ca2c05c8d4560ecd80ba68f376f8b487897e374e99a9288ed7e3645cc0d00a478aae8d16 a44dde1724a86a264d7eb02f1c52fc3bda20bd3707ed4d05b969c7694feb5a41cfcd04b6524bd2d2a8cef5a06bdeb62b17dafea6524357936d882ecb5478725811032b9d5ce6a009f2ff2311ae236fb1d3647170536db06462ddb6d921cacead +10631c3d438870f311c905e569a58e56d20a2a560e857f0f9bac2bb7233ec40c79de145294da0937e6b5e5c34fff4e6270823e5c8553c07d4adf25f614845b2eac731c5773ebbd716ab45698d156d043859945de57473389954d223522fbafecf560b07ef9ba861bcc1df9a7a89cdd6debf4cd9bf2cf28c193393569ccbd0398 008c4c0fd9696d86e99a6c1c32349a89a0b0c8384f2829d1281730d4e9af1df1ad5a0bcfccc6a03a703b210defd5d49a6fb82536f88b885776f0f7861c6fc010ef37 88dde0cf193c5aa0ac2af05a88d4be54fb3559412d5a32c7c386488df1975c67f038da5c034b0e66765124bb3352639010eee4cc93432a80cfc51ce2985b033b99ff57c8be3485e556d78d391b4b3b316f0dd452615e449c20ad3bcab6a175fa +80aad6d696cbe654faa0d0a24d2f50d46e4f00a1b488ea1a98ed06c44d1d0c568beb4ab3674fc2b1d2d3da1053f28940e89ba1244899e8515cabdd66e99a77df31e90d93e37a8a240e803a998209988fc829e239150da058a300489e33bf3dcdaf7d06069e74569fee77f4e3875d0a713ccd2b7e9d7be62b34b6e375e84209ef 01466d14f8fbe25544b209c5e6a000b771ef107867e28ed489a42015119d1aa64bff51d6b7a0ac88673bbc3618c917561cff4a41cdb7c2833dab5ebb9d0ddf2ca256 942a630a76dc0b9240a71cb0f96c9e5e1201a1d9caa9a0b25a1da07476d3aa2ddc49c8a0c73dbea681e740bb1cd7c8d205df8359be719a1fd154cae40cb0b74f827c5f35e0ca88fb7623a788f6558c730da540150477e306f6e2483bc28b9b4f +8a7792a2870d2dd341cd9c4a2a9ec2da753dcb0f692b70b64cef2e22071389c70b3b188dea5f409fb435cbd09082f59de6bc2ff9e65f91b7acc51e6e7f8e513148cb3c7c4664f227d5c704626b0fda447aa87b9d47cd99789b88628eb642ed250312de5ba6b25f3d5342a3cbb7ebd69b0044ee2b4c9ba5e3f5195afb6bea823d 001a99fcf54c9b85010f20dc4e48199266c70767e18b2c618044542cd0e23733817776a1a45dbd74a8e8244a313d96c779f723013cd88886cb7a08ef7ee8fdd862e7 a9a636ae7fe466cc0a314ecfde939366dd70c23555494f94237bd9d32b2cbb1a67697c3c13fb6531aa1645ad0be56472128fbaa51b6d51bcfed3b9a794f93fe8af9ec8f578e3963b2025ed038cdd09cc1b1a4eb77fe66f63b1173f5165d8cdf2 +f971bcd396efb8392207b5ca72ac62649b47732fba8feaa8e84f7fb36b3edb5d7b5333fbfa39a4f882cb42fe57cd1ace43d06aaad33d0603741a18bc261caa14f29ead389f7c20536d406e9d39c34079812ba26b39baedf5feb1ef1f79990496dd019c87e38c38c486ec1c251da2a8a9a57854b80fcd513285e8dee8c43a9890 01b6015d898611fbaf0b66a344fa18d1d488564352bf1c2da40f52cd997952f8ccb436b693851f9ccb69c519d8a033cf27035c27233324f10e9969a3b384e1c1dc73 8aa684c9c06a63714aa1f9e55a682d019a79c58f98f20d44838d9e96bda862d8a20244917aa96e5b051fbd042cab45e70365ab317241a9dc0ce4a37b62eb48417e19880f2fe64ab9edb692e9764ff6cca2d83c14e81c74da5c1b2ccdf46f38ab +ec0d468447222506b4ead04ea1a17e2aa96eeb3e5f066367975dbaea426104f2111c45e206752896e5fa7594d74ed184493598783cb8079e0e915b638d5c317fa978d9011b44a76b28d752462adf305bde321431f7f34b017c9a35bae8786755a62e746480fa3524d398a6ff5fdc6cec54c07221cce61e46fd0a1af932fa8a33 005e0d47bf37f83bcc9cd834245c42420b68751ac552f8a4aae8c24b6064ae3d33508ecd2c17ec391558ec79c8440117ad80e5e22770dac7f2017b755255000c853c b0271587c6de280e5cd42e5acc0dd6eb1e574b674da55a51c619eee37a183bb2bc84fe949114484d99c1c0037f30f10a17be84093428524ecb51c43f5acf8a75f77450946df9d028bb5f8e84872020274448dff74373461e4560da8ffd9b3617 +d891da97d2b612fa6483ee7870e0f10fc12a89f9e33d636f587f72e0049f5888782ccde3ea737e2abca41492bac291e20de5b84157a43c5ea900aef761006a4471072ab6ae6d515ffe227695d3ff2341355b8398f72a723ae947f9618237c4b6642a36974860b452c0c6202688bc0814710cbbff4b8e0d1395e8671ae67ada01 01804ab8f90ff518b58019a0b30c9ed8e00326d42671b71b067e6f815ac6752fa35016bd33455ab51ad4550424034419db8314a91362c28e29a80fbd193670f56ace 987aebca1ef8850cabe3996b1178e1961a4c2769070fab22aa9cdf685d82ba9244a0411baa05f9de2ce3791cd085305c04c4fa1f3af64557418548cf053e97e52a31721b95b919bd9f591d7cb3897255160cc5f07000e880d2d66c1532b676cc +924e4afc979d1fd1ec8ab17e02b69964a1f025882611d9ba57c772175926944e42c68422d15f9326285538a348f9301e593e02c35a9817b160c05e21003d202473db69df695191be22db05615561951867f8425f88c29ba8997a41a2f96b5cee791307369671543373ea91d5ed9d6a34794d33305db8975b061864e6b0fe775f 00159bff3a4e42b133e20148950452d99681de6649a56b904ee3358d6dd01fb6c76ea05345cb9ea216e5f5db9ecec201880bdff0ed02ac28a6891c164036c538b8a8 868e1f1bb434e2d3defc4bf25570dac25b8b1a3fcc649840601134cc3e533b1c3fc35bde3363aa7ab8164ade4177a2cf10ae2bc3376b7565fd63655fb0045c14bf734631b831bc3c8013dac5127299f8eb4afe0bb3dcd924ed586337ba0c7953 +c64319c8aa1c1ae676630045ae488aedebca19d753704182c4bf3b306b75db98e9be438234233c2f14e3b97c2f55236950629885ac1e0bd015db0f912913ffb6f1361c4cc25c3cd434583b0f7a5a9e1a549aa523614268037973b65eb59c0c16a19a49bfaa13d507b29d5c7a146cd8da2917665100ac9de2d75fa48cb708ac79 017418dfc0fc3d38f02aa06b7df6afa9e0d08540fc40da2b459c727cff052eb0827bdb3d53f61eb3033eb083c224086e48e3eea7e85e31428ffe517328e253f166ad 8d798cb85098742f96d0920be73b713a0d92b5c4db88ff260180f458080970cd3fc9b2100b261b56c06448324a77a8bc03ac1ce07d6db778281ce021edd519ad23c38b41698e2a92445d5642c6aeef43f99af25a91489fef94f8eb51c1f86dc1 +8ab8176b16278db54f84328ae0b75ef8f0cd18afdf40c04ad0927ed0f6d9e47470396c8e87cde7a9be2ffbfe6c9658c88b7de4d582111119c433b2e4a504493f0a1166e3a3ea0d7b93358f4a297d63f65a5e752f94e2ee7f49ebcc742fa3eb03a617d00c574245b77a20033854d82964b2949e2247637239ab00baf4d170d97c 01e8c05996b85e6f3f875712a09c1b40672b5e7a78d5852de01585c5fb990bf3812c3245534a714389ae9014d677a449efd658254e610da8e6cad33414b9d33e0d7a a98e1bcf145579ad5a43057b65a5ba8ad19c5cf1c06d473924ea47a026c5af604d67b361a5083d2cbd514ada375966270d195c44891fa82ffc2c80d2ebe638937ce2d86116cfde0566db199ba6ed484e338ba614c071daeb01b51611ea0b5b7f +c4bc2cec829036469e55acdd277745034e4e3cc4fcd2f50ec8bd89055c19795a1e051ccf9aa178e12f9beab6a016a7257e391faa536eaa5c969396d4e1ade36795a82ebc709d9422de8497e5b68e7292538d4ccdc6dd66d27a3ece6a2844962b77db073df9489c9710585ba03d53fa430dbc6626dc03b61d53fc180b9af5dea6 00b65bf33b2f27d52cbfabcadce741e691bf4762089afd37964de1a0deda98331bf8c74020a14b52d44d26e2f6fa7bcddbe83be7db17a0c8a1b376469cf92c6da27c a35bf7c6c14d2d6013e346281f202141a98c2afd4e70f54049d7ef790df1fe85f937bbfc004050b624fcab1d455f6db102148c4215eb1bb0089ef8dde83e4998a3a184dc54170df80d1f7c99197852170ad591cc955a5680b670f24e38015b88 +1c1b641d0511a0625a4b33e7639d7a057e27f3a7f818e67f593286c8a4c827bb1f3e4f399027e57f18a45403a310c785b50e5a03517c72b45ef8c242a57b162debf2e80c1cf6c7b90237aede5f4ab1fcaf8187be3beb524c223cc0ceff24429eb181a5eea364a748c713214880d976c2cd497fd65ab3854ad0d6c2c1913d3a06 002c4e660609e99becd61c14d043e8b419a663010cc1d8f9469897d7d0a4f076a619a7214a2a9d07957b028f7d8539ba7430d0b9a7de08beeeae8452d7bb0eac669d b3f5e883afcbef721dc65c36334bbdbbb54305a6ce1885bef5280dc202bef17c7471d9ca86aac066bec0d2b439ace0f90088b08e9f0c91fbdefaa8d440a0bf33a1ab4a2695d6f7355b47b187b55ebdb657469b006e80456ac213ba05b8a1c488 +adb5f069b2b501a3ebb83d4f1808eb07710ac4a7b12532996855a20bcc54b2f76812915f632163c3654ff13d187d007152617cf859200194b59c5e81fc6cc9eb1ceb75d654050f260caa79c265254089270ccd02607fdcf3246119738c496dc3a4bd5d3be15789fc3d29a08d6d921febe2f40aef286d5d4330b07198c7f4588e 017c3522007a90357ff0bda7d3a36e66df88ca9721fb80e8f63f50255d47ee819068d018f14c6dd7c6ad176f69a4500e6f63caf5cf780531004f85009c69b9c1230c 84a010eaff8d6deec0a41149ac174c5402da5190ca42d7d2ae4c36dd4936e6c08d553477404dfb6aed6d0316dd7f12490911bc1d007a2e9c31d51d1f57a02dd6bd29d23f62e144d1fed59bb0cebb9fe95f73db08c32b0d012d53e9ad841618d8 +f253484d121d1ce8a88def6a3e9e78c47f4025ead6f73285bf90647102645b0c32d4d86742a50b8b7a42d5f6156a6faf588212b7dc72c3ffd13973bdba732b554d8bffc57d04f8167aef21ee941ee6ffb6cce0f49445bd707da8deb35dca650aaf761c3aa66a5ebccddd15aee21293f63061a7f4bfc3787c2cd62c806a1a9985 00c4dad55871d3bd65b016d143ddd7a195cc868b3048c8bbcb1435622036bdb5e0dec7178ca0138c610238e0365968f6ddd191bbfacc91948088044d9966f652ff25 a582cb062290aa2972b59c94e7fbe0faa212abf3629d52c1feac0fc5086780730547e8114a213776c937c8f538678b7506c69ecc1b9f8c8b1cd780df9e2c5575cbf50df4f507a6e1d7ccc69adf478866f4583041e8350ebf630db6332ab9e5ad +33bab1c369c495db1610965bc0b0546a216e8dd00cd0e602a605d40bc8812bbf1ffa67143f896c436b8f7cf0bed308054f1e1ff77f4d0a13c1e831efbd0e2fcfb3eadab9f755f070ba9aeaceb0a5110f2f8b0c1f7b1aa96a7f2d038a1b72e26400819b1f73d925ea4e34d6acaf59d0a461a34ce5d65c9c937a80e844e323a16d 003d4749fadcc2008f098de70545a669133c548ce0e32eec1276ff531bcff53533144555728ad8906d17f091cc0514571691107350b6561858e90dbe19633aaf31bf 98250514ec1f096de4b1a67cf7a02cb3aa729ec7380b58288b051ea1ed76114d91e383a5423b0cea6fb87ab185cbfd940b8ca79e787eac4f513c1d68ccb4c4badfa0739a32869ae54f456d11f0b99953c3f267992b51707432591f99bdc13f18 +08c8b7faaac8e1154042d162dca1df0f66e0001b3c5ecf49b6a4334ce4e8a754a1a8e4daf8ec09cf1e521c96547aed5172ef852e82c03cddd851a9f992183ac5199594f288dbcc53a9bb6128561ff3236a7b4b0dce8eaf7d45e64e782955ee1b690ce6a73ece47dc4409b690de6b7928cbe60c42fc6a5ddf1d729faf1cc3885e 0096a77b591bba65023ba92f8a51029725b555caf6eff129879d28f6400e760439d6e69ce662f6f1aecf3869f7b6057b530a3c6ff8ed9e86d5944f583ee0b3fbb570 964019d525fe5993ba9edc3134a110ecc4d7347d7e077ff6d33d75201a7f73aadd04f5238ddcd9101ff4c494c8cac86301bb809662c8e8d12b41fa621ecb7e2c6fac58ebc077d47fea2a009272bf497925eb46343780736f33bf7851644d22d9 +ba74eed74282811631bd2069e862381e4e2a1e4e9a357b1c159a9ce69786f864b60fe90eeb32d8b72b099986fc594965a33285f7185b415df58fead7b8b50fc60d073680881d7435609ad1d22fd21e789b6730e232b0d2e888889fb82d6ad0337ab909308676164d4f47df44b21190eca8ba0f94995e60ad9bb02938461eee61 0015152382bfd4f7932a8668026e705e9e73daa8bade21e80ea62cf91bd2448ebc4487b508ca2bdaaf072e3706ba87252d64761c6885a65dcafa64c5573c224ae9e6 898333067cdd2a682c7debc779a69c10991653723466fa3ecc680fd9480aed23c3fc5489ed35fcc21adf1e0ec3513bfa14f0bb8cb9019f73960b3e97525c1d436f1e2e137f1fca49749ded8a76e32f30669471c185ca29637edaafa6307d4463 +dc71f171a28bdc30968c39f08f999b88dc04c550e261ecf1124d67f05edeae7e87fe9b8135a96fe2bc3996a4f47213d9d191184a76bd6310e1ee5cb67ea7fc3ef6f641a0ba165198040fa668192b75a4754fc02c224bd4a74aade5a8c814adf151c2bfeda65165a04ef359e39847c84e312afb66d4cd1db50d41ef3fe5f31296 01750ff0ca0c166560b2034bc5760fe0b3915340bc43216e9de0c1d4a76550e8b2036e8b874230f8d29354aed43e183610f24fd4abd4b0be2f111dae942bd7a121f7 a0199959b64c628a4fb432a777973af471068f333071c938a08bcc164672dd720d68f800ff5b2e2b3e7ab3950d447afc159010474b60c0de775978367ddb7b6d3f2d3aecb23d0ec1a3c3f17e1bef95cc5767c856a3e4cc7287b045feddc72e32 +b895788d7828aaeace4f6b61a072ffa344d8ea324962ba6dab5efda93f65bf64a0f2ac6d5721d03ee70e2aef21cdba69fd29040199160e3a293b772ffb961ed694a8dc82800dab79367a4809a864e4aff6bc837aaa868e952b771b76591c0bb82249034e3208e593d85973d3fea753a95b16e221b2561644535c0131fe834ae7 0023048bc16e00e58c4a4c7cc62ee80ea57f745bda35715510ed0fc29f62359ff60b0cf85b673383b87a6e1a792d93ab8549281515850fa24d6a2d93a20a2fff3d6e b64b3b745d1f9a67247345d132b8c09850973c86feb46cb2dec1573508b9474b2c16530d5ef5d2d94db9561849a20bb20ad0ecbe453db5a954f4dd6bab401efb3a5b201ec1c7aab75d23c051b82babf878f5cc5e6372b99a0d7e1cc5ccabcb19 +2c5bd848c476e34b427cfe5676692e588e1957957db7b5704492bd02104a38216535607f5d092dc40020130c04a3aaf0f1c52409834926d69a05d3f3188187a71d402a10ba34eac8629b4c6359b1095f30f710219298bf06b9f19bfc299981d7e251ca232a0a85338a7e02464731d1b25d4a1f68baf97064516590644820c998 002b8b866ce4503bb40ffc2c3c990465c72473f901d6ebe6a119ca49fcec8221b3b4fa7ec4e8e9a10dbd90c739065ad6a3a0dd98d1d6f6dcb0720f25a99357a40938 a50568ab56104d361c200abe457eff20a221cb5a37e2212707aabac3a0e9429952e5482695d0092347e2178e6bf062d90326603001149e0a0ce7f4e750bafc53095f6dced66c073c8002c3f743741480a7530525a1fe7a17b6d2309e8453f6ef +65a0b97048067a0c9040acbb5d7f6e2e6ac462e1e0064a8ce5b5bbf8e57059e25a3ef8c80fc9037ae08f63e63f5bdb9378c322ad9b2daf839fad7a75b1027abb6f70f110247da7e971c7c52914e5a4f7761854432fa16b2a521e7bcaee2c735a87cad20c535bf6d04a87340c229bf9af8647eedca9e2dc0b5aa90f7fea3cdc0a 00a43b32ad7327ec92c0a67279f417c8ada6f40d6282fe79d6dc23b8702147a31162e646291e8df460d39d7cdbdd7b2e7c6c89509b7ed3071b68d4a518ba48e63662 b8ef4cb9c3c612293c8f422da12578ed62d8cde1be0eb516bc770b48b99c74ba3b41c8523efe85b25f89043c5ee6e9b314f9cab39d9f2edb3fa5eeabf8e86b29b5e6fa1662afc7028c9074851c6163f00b2dcf6d9ded6c3787ac3341e74267f7 +d6e366a87808eea5d39fe77cac4b8c754e865a796062e2ec89f72165cd41fe04c48148068c570e0d29afe9011e7e7a2461f4d9897d8c1fa14b4ff88cab40059d17ab724f4039244e97fcecb07f9ffeec2fb9d6b1896700fe374104a8c44af01a10e93b268d25367bf2bef488b8abcc1ef0e14c3e6e1621b2d58753f21e28b86f 003c08fdccb089faee91dac3f56f556654a153cebb32f238488d925afd4c7027707118a372f2a2db132516e12ec25f1664953f123ac2ac8f12e0dcbbb61ff40fb721 85e466df8b071b472c314ec621f2fdc56116ea47768f97cc41d780e8574b6b720587a813665f18e7c9e10afba203709d04c4298c99b06c8fd3786a0cd0b82d92fc6de6604bab6196af03190629dc935cb306549d3fae25e8125260675e7b3fd7 +f99e1d272d0f5fb9c4f986e873d070ec638422bc04b47c715595e2cf1a701cdf88bc6c4b20085b357bad12ccba67cac8a5ca07f31ba432f9154ff1fadefd487a83a9c37e49fb70a2f170e58889cab0552e0a3806ccfa2a60d96e346851d84b7de6d1a4b8cf37567dc161a84f13421e3412457d4bc27f6213453c8519a2d7daa2 00969b515f356f8bb605ee131e80e8831e340902f3c6257270f7dedb2ba9d876a2ae55b4a17f5d9acd46c1b26366c7e4e4e90a0ee5cff69ed9b278e5b1156a435f7e b53e106ea04bd4ca6ae226afbac035823d06de758d803029700a18ad386b6ad2a986306cf6021dd6a3bbd90b55b322220debfb7ce10f5b9f5de4df149d7c0642168977b80f194db4a8eda093d0d791535265d5d7dd328195e3b209916cbd3dca +91f1ca8ce6681f4e1f117b918ae787a888798a9df3afc9d0e922f51cdd6e7f7e55da996f7e3615f1d41e4292479859a44fa18a5a006662610f1aaa2884f843c2e73d441753e0ead51dffc366250616c706f07128940dd6312ff3eda6f0e2b4e441b3d74c592b97d9cd910f979d7f39767b379e7f36a7519f2a4a251ef5e8aae1 0013be0bf0cb060dbba02e90e43c6ba6022f201de35160192d33574a67f3f79df969d3ae87850071aac346b5f386fc645ed1977bea2e8446e0c5890784e369124418 a6876f12ff30f2581f2b4d32387f701a9c1c9064ee4a096c065cb00265b87a14a58b649471e9d41521a5c3e0b36ba273057a91d7d893fdbe02f947f1feede2714091c55bc5f5588addc675a2d508a8382bdcc8e16eeb291b5335d1212d7ea469 +dbc094402c5b559d53168c6f0c550d827499c6fb2186ae2db15b89b4e6f46220386d6f01bebde91b6ceb3ec7b4696e2cbfd14894dd0b7d656d23396ce920044f9ca514bf115cf98ecaa55b950a9e49365c2f3a05be5020e93db92c37437513044973e792af814d0ffad2c8ecc89ae4b35ccb19318f0b988a7d33ec5a4fe85dfe 0095976d387d814e68aeb09abecdbf4228db7232cd3229569ade537f33e07ed0da0abdee84ab057c9a00049f45250e2719d1ecaccf91c0e6fcdd4016b75bdd98a950 a00b2a9d805cc824a014c3626847b4e5c6d51542f13147c5a9365171a5bdc77b609959fbab81f8735933bf73f3bc58ab0d2a4f7404056fedca13cd70b5a24cf605b7c2f8d18e425566091d96cdcf93fe9b5921d774dfb7f06231a03dc70cc970 +114187efd1f6d6c46473fed0c1922987c79be2144439c6f61183caf2045bfb419f8cddc82267d14540624975f27232117729ccfeacccc7ecd5b71473c69d128152931865a60e6a104b67afe5ed443bdbcdc45372f1a85012bbc4614d4c0c534aacd9ab78664dda9b1f1e255878e8ac59e23c56a686f567e4b15c66f0e7c0931e 004ceb9896da32f2df630580de979515d698fbf1dd96bea889b98fc0efd0751ed35e6bcf75bc5d99172b0960ffd3d8b683fbffd4174b379fbdecd7b138bb9025574b 83f1505c48cae0d9fdce70562d6463341dff50d0ad1f68fdc7880523ed6d6b55a0e45329ce87d5a85b4033f1823c7df205200298321f5444025cb88f055b46dc7153dc7880fb582b455fcea693c192580cb45b756aada772376dfaded4bb6338 +6744b69fc2420fe00f2352399bd58719e4ecdd6d602e2c80f194d607e58b27a0854745bfd6d504de2eb30b04cee0f44af710dd77e2f816ac3ac5692fad2d1d417893bb0edba2707a4c146a486f8728ca696d35cc52e9c7187c82d4bdb92eb954794e5ad15133f6bfea1f025da32ada710a3014cf11095b3ff69a94d087f17753 000a8db566bd771a9689ea5188c63d586b9c8b576dbe74c06d618576f61365e90b843d00347fdd084fec4ba229fe671ccdd5d9a3afee821a84af9560cd455ed72e8f aa33d50858a59fb7661232b037e5cd5513efe7c306966af8c7b39e44ab7c95ca40cf328a7d69135687ddc9ec26c3a2d41757b7b0817b9034dcd03ca35b61a0b3e8ba497eb91faf97cadb0d750ef177a7b493ce6473c22794f16f5afc356e9de2 +16001f4dcf9e76aa134b12b867f252735144e523e40fba9b4811b07448a24ef4ccf3e81fe9d7f8097ae1d216a51b6eefc83880885e5b14a5eeee025c4232319c4b8bce26807d1b386ad6a964deb3bdca30ee196cfdd717facfad5c77d9b1d05fdd96875e9675e85029ecbf4f94c524624746b7c42870c14a9a1454acf3354474 01a300b8bf028449344d0e736145d9dd7c4075a783cb749e1ec7988d60440a07021a25a3de74ea5e3d7bd4ab774d8ad6163adae31877ef0b2bd50e26e9e4be8a7b66 b2b51360851cd21e808ef45876728e6ba7a384c4f3bda1ccc69613428e2428b9f5f362a319cf10818fc178af23b1789416cf0a4de42826b29f303392ca4fea8a934213b5d7ab3a7463fea40f8170f856d83653f5131a02478938d02d14a79466 +a9824a7b810aa16690083a00d422842971baf400c3563baa789c5653fc13416111c0236c67c68e95a13cec0df50324dcc9ae780ce4232607cb57dd9b2c61b382f0fa51fd4e283e2c55ffe272597651659fbd88cd03bfa9652cd54b01a7034c83a602709879e1325c77969bebfd93932ce09a23eae607374602201614ff84b141 006a253acd79912a74270fc0703ed6507ab20a970f2bc2277f782062092cf0e60ae1ca1bb44dec003169bc25ef6e7123dd04692f77b181a6d7e692e66b09d35a540c acae53b6b3ba5bad232c39c30d7880b28d172c184d8b45e06f0e21139f05beacbd7e46dd68e4987871f46a3d07f253c904d6d9c2dd828206978fd2f888b3c652ec742ed4f749eea1ec8fe9e005d124252f5248f848abd55d6b84cb5b3400c2de +90d8bbf714fd2120d2144022bf29520842d9fbd2dc8bb734b3e892ba0285c6a342d6e1e37cc11a62083566e45b039cc65506d20a7d8b51d763d25f0d9eaf3d38601af612c5798a8a2c712d968592b6ed689b88bbab95259ad34da26af9dda80f2f8a02960370bdb7e7595c0a4fffb465d7ad0c4665b5ec0e7d50c6a8238c7f53 00d5a5d3ddfd2170f9d2653b91967efc8a5157f8720d740dd974e272aab000cc1a4e6c630348754ab923cafb5056fc584b3706628051c557fce67744ee58ba7a56d0 8cd476950f228ef25c65dc567e10052ff67956cc498df617e2b77ab94025b9b6afa2a7c2f2aa9e8434e69b910b13561a04032f9a7bb1b55b48ee80ca19b79be49e53bbee0a1906d9a9d3195da064acd8ece503c860d4aa2314bb92f781629de4 +09952b1e09995e95bf0022e911c6ab1a463b0a1fdd0eec69117b34af1103c720b57600217de7cd178fef92de5391e550af72a8dcf7badf25b06dd039417f9a7d0f5be88fcd4e9655931d5b605452a667c9d1bae91d3476e7d51cff4108f116a49966fb3a7cff8df1c09734ce5620faf2dccb3dc5d94e7e9ac812da31f6d07a38 01bcedf920fa148361671b43c64e3186e1937eb1bd4b28cbd84c421472394552889bc05509aa732ef69d732b21b750523fdfd811f36467690fe94e01e64c9d5cbbe9 b092de519c293ace2e662cffb67be47f27936f62bd18dccc5e44068af190e9d9ab7e7b0b646395a413ad8e2f7b0fcb091630287beebca1df807c550ea3ca0685907f5ba55832d4d8afb7dd1ea94b8e409de4d62415318df51491cb3d24e5f158 +0bb0f80cff309c65ff7729c59c517d50fc0ed5be405ef70cb910c3f62c328c90853d4473530b654dda6156e149bc2222a8a7f9be665240e2fbe9d03f78a2356af0bacd1edb84c4801adc8293a8a0bd6123d1cf6ba216aca807a7eb4dca76b493eb6e3dbb69d36f0f00f856222f24d9b93ec34c3b261be2fca0451c00571928e5 003789e04b3a2a0254ade3380172c150d2fad033885e02ea8bea5b92db3f4adbab190ae423080a1154dfedec694c25eab46ce638be3db4e4cba67bc39f62d6e7db2d 955e57303ff63aed010599b1e0e852c39b130a2fa9fef2e9816f954fb2a64444b6f636ed14324fb0405b2777869841aa0903da4763f6641e8455b3adbdbcbd7adf13f6fbbe7f120fc789f238c11967ddceef394d4e7ee44ccc0de82081d7013c +7efacf213382ce30804e78b7256854d759147dba9729c51b2759465715bf2c421034c23dc651c13d6cce95f71fe6a84dfbee5768163ac5789ac0474c5ddf4115684683c5f7c204b33b8bcc0c03ac58f66cef2f53b721fe2fac91ad841126101a88f512a7c2ded38549d9f050d4b7961dda48a1489f026c5d111701762418cfe3 0124700aa9186353e298edefc57bec0c7d0201cca10c1d80dd408d5d71040592b0ac59facdadfa8712445f5977ef8d4854022720c3f02d60e0732dbb2f171fcf1490 b9ef529d42468700da93339b6ca8b90fb78d4c843083cf4f213a2f8b09fe9e25bd8695ed7b168ba508578ecf96b3924910f614d2753601bfb480f195aaf2db4f36493975c663aaf3b6b9fd80088996d24c2d86c9fe9f127dae3f79df8ab39c38 +28edff8b9d85f5f58499cc11f492abdfab25e8945975bbaeee910afa2b8fc1295ec61406309ce4e09f4ab4f462959fc2a2786802466eb26d3b01be6919893ae75d0fdc2dc8a82e662550f9fce9627dd364188aaba5c6faa1b2d8a2235adfa5ad0dc140f88a2b2f103f5690e877d07fe8fd30d02d2b2729bd3d8eb5b23a21f54c 01f532d01af885cb4ad5c329ca5d421c5c021883bd5404c798d617679bb8b094cbb7e15c832fb436325c5302313ce5e496f9513455e7021ffad75777a19b226acfa1 87a2b45b1ddc3f10fe7cbd6f0c45a9531c2ab3908e073bc038f436b12a2c45729563066998b3dd9129e20adb6a29333f09d8c2f14222cfd6d6bd2d2f67ecdc4cbc82f41a0d52e362d3ec2ac707cb1314e7b46fe3b8aa5117f5919d1875fe5161 +bae2a8897c742fd99fbf813351cd009d3f2e18d825ca22e115276484bce8f82f8c7c0c21dd2af208404d8ef45bb5a6c41693912b630897d5246801bf0775aa9bbac8be98cb861d172c3563dc59e78a58ed13c66dea496471b3ad0eeae8995293e4ab97373edc1837ffc95ff1cc0c1e90e64ea8680b2ca5f1e09bf86b99b343b6 011abf508bca68a85a54bc0659e77efad3c86112c9db04db2883e76144aa446918bb4bb0784b0b6a0e9aa47399fe3de5aaecfd8894a0d130bb0c366c40d9d5050745 82821d5f44c381e2f3a3e5b3a6834fe3fa578120ada15965d304619bdbaa364b2c1a48fe63da8905f1fb8341c96e23220fcffde3136313470bd2383a9f9513e1c42ca1d01f0c42fc4a27b398d0fc229fd2c548d0986e4220f430bd65451464ff +d57a26a9593e72bfc87322524639bcaae5f2252d18b99cdaa03b14445b0b8a4dd53928f66a2e4f202fb25b19cad0eb2f1bfda2ab9b0eb668cdcd0fe72f5d9ef2e45e0218590f7ab9d2c9342202610c698bc786cce108a7d4a6730a13e9ea1b470e781f1237d3f84f44abde808516975546bd89075ef9a9732bfd7ee33b6f4399 018dbf520d58177e4b7a0627674d220137983f486dd2fd3639f19751804e80df0655db6afd829cdf75238de525e1a7a9f048049b593dd64b4b96cc013f970c05ea1f 961beae5a686f55c007ea8933f838f853e7598e810e8c8ffb81fa37790a150d0dc21e049d084534d8120d7962485e1ed11b7f84d9f923cc86f06a047729de7171ae9e171d1672b5475b55df868281ef70f837a1e131bff2cfddfe3f959ed7745 +8fdcf5084b12cfc043dd3416b46274e021bbed95d341d3c500c102a5609d3a34de29f8fa9f0adb611a1f47a97ad981f8129d718fc0d6c709eab1a3490db8d550f34eb905b9e00663543afc5bc155e368e0bc919a8b8c9fa42093603537a5614927efa6be819ed42ececbf1a80a61e6e0a7f9b5bc43b9238e62d5df0571fea152 0002764f5696aa813cd55d30948585f86288ae05aeb264ca157cd09e1d09a10515a849b0791b755ccc656a34707be9e52f5762d290a7d2bcd6de52c600ff862eaf4e a8aa6d23ab4d72c6ea81f8881d292241af6c4bd383e05b51876eb4c5a84caf7721f840450af7d653bc99548c3685927b12d2ffe4c7876441cc42f103b04eb6b783df4b739ceebc866c3c47339c0dc8f7c9819e5f9118d87847ed8915e10a75dd +00669f433934992257bed55861df679804107d7fa491672574a7624949c60049b0533383c88d6896c8de860704c3e6a6aefce83efa57c4d57e9ab253da5d15e1f53ab6dce218b592772ab0bc01fee8e63368e85c0639301456fe2d44cd5396a7f2b22761cd03b80eba7883eede8249a2f5db2183bf00550c5c002f45a5e4fb31 01b0c9acd3eeb618b4b0de4db402206f0f29adc69d7ad324b6db6601b351f723ac8fe949eeacd34228649bf0126276e5aceb0137d00c30dd858aef2d6b6449de2e89 ade230e9df98a07e9cd234fa2bd4e42404183ade1b18bc475a86f6bb8a4c945f975746e11cca4056f528ffba7ecb7b9b1651e0a31b54141e07d14607b296238aa78bb46133c305f177f93e1ef40e52042283656d247752c5ce7a610cd438a8f0 +4be81dcfab39a64d6f00c0d7fff94dabdf3473dc49f0e12900df328d6584b854fbaebaf3194c433e9e21743342e2dd056b445c8aa7d30a38504b366a8fa889dc8ecec35b3130070787e7bf0f22fab5bea54a07d3a75368605397ba74dbf2923ef20c37a0d9c64caebcc93157456b57b98d4becb13fecb7cc7f3740a6057af287 0181e1037bbec7ca2f271343e5f6e9125162c8a8a46ae8baa7ca7296602ae9d56c994b3b94d359f2b3b3a01deb7a123f07d9e0c2e729d37cc5abdec0f5281931308a 81eae26ef5c1ef15d02ba11441644d3adfb4758aed6b0f68d1843203391cdd9283b204491e55b17acbec43a5717aaa3f006d8a4be1bee55f804f9397adf3467b90ca0e417d4423e139d097b87bd7e064bece03092ad52e91ce03b2416140e9d0 +9ecd500c60e701404922e58ab20cc002651fdee7cbc9336adda33e4c1088fab1964ecb7904dc6856865d6c8e15041ccf2d5ac302e99d346ff2f686531d25521678d4fd3f76bbf2c893d246cb4d7693792fe18172108146853103a51f824acc621cb7311d2463c3361ea707254f2b052bc22cb8012873dcbb95bf1a5cc53ab89f 00f749d32704bc533ca82cef0acf103d8f4fba67f08d2678e515ed7db886267ffaf02fab0080dca2359b72f574ccc29a0f218c8655c0cccf9fee6c5e567aa14cb926 a8c24e1f57ea88f1ef458744537da0965d78b6143b355f8ca7ed12ad678a64d1e792aa35f093b1bb44e3910314c65b4c146644b0ab0ee288f070bb61cc30b8b6ff57cb7ecc6ba0b5f2d57ac8fd95be056c660b2dddc01d74ccff08b234605afc +b3c63e5f5a21c4bfe3dbc644354d9a949186d6a9e1dd873828782aa6a0f1df2f64114a430b1c13fe8a2e09099e1ed05ef70de698161039ded73bcb50b312673bb073f8a792ac140a78a8b7f3586dffb1fc8be4f54516d57418ccc9945025ce3acf1eb84f69ceee5e9bd10c18c251dbc481562cd3aae54b54ab618cb1eeda33cf 01a4d2623a7d59c55f408331ba8d1523b94d6bf8ac83375ceb57a2b395a5bcf977cfc16234d4a97d6f6ee25a99aa5bff15ff535891bcb7ae849a583e01ac49e0e9b6 aa2274664609124185bb4b21535f80eeb82ef1e477565b7e8043f4e9025546fcd4cbe6c63f2053a5d3a62febc31da1af0687d7ccbf667ccaf477f0462e8986fd888ffc2adf8a7dd74a93c97df3a298f52521d2adf260dde2876a4b2c318ac4f6 +6e0f96d56505ffd2d005d5677dbf926345f0ff0a5da456bbcbcfdc2d33c8d878b0bc8511401c73168d161c23a88b04d7a9629a7a6fbcff241071b0d212248fcc2c94fa5c086909adb8f4b9772b4293b4acf5215ea2fc72f8cec57b5a13792d7859b6d40348fc3ba3f5e7062a19075a9edb713ddcd391aefc90f46bbd81e2557b 014787f95fb1057a2f3867b8407e54abb91740c097dac5024be92d5d65666bb16e4879f3d3904d6eab269cf5e7b632ab3c5f342108d1d4230c30165fba3a1bf1c66f 895c59c0706d43a8f0d10c9d78ddb51d8a7f86b4676af137fd47ef81a58d2d077bb299c3a9f699514ad4f8262d4e3d290c6cd8f1cf27783fc11980b8c310909b02694e6bed9b5037313d5bb35957d46ff6d7d4d2c46df0e0e42b29a3e083631d +3f12ab17af3c3680aad22196337cedb0a9dba22387a7c555b46e84176a6f8418004552386ada4deec59fdabb0d25e1c6668a96f100b352f8dabd24b2262bd2a3d0f825602d54150bdc4bcbd5b8e0ca52bc8d2c70ff2af9b03e20730d6bd9ec1d091a3e5c877259bcff4fd2c17a12bfc4b08117ec39fe4762be128d0883a37e9d 015807c101099c8d1d3f24b212af2c0ce525432d7779262eed0709275de9a1d8a8eeeadf2f909cf08b4720815bc1205a23ad1f825618cb78bde747acad8049ca9742 b40b01cb829131a72f4c455afb7b0d1a492c9cadc08bb99c1fb11dce9b069e1be7929de44bb32b42e8cdc91c75b78f5915c85bea535477c12f736c642befdc20bab88cb2d078313bd78cb2d52555b76a1fc6d72baf762ee81396980764e772ad +a1eed24b3b7c33296c2491d6ee092ec6124f85cf566bb5bc35bffb5c734e34547242e57593e962fb76aee9e800eed2d702cc301499060b76406b347f3d1c86456978950737703c8159001e6778f69c734a56e5ce5938bd0e0de0877d55adeee48b0d8dfa4ac65fd2d3ce3e12878bac5c7014f9284d161b2a3e7d5c88569a45f6 018692def0b516edcdd362f42669999cf27a65482f9358fcab312c6869e22ac469b82ca9036fe123935b8b9ed064acb347227a6e377fb156ec833dab9f170c2ac697 99c4e203d64fa4c70ea94a4c28d2b9fc91de9531308e9f1bc4dbd9139fe1605e10359efc2e9b1d53c23372a9f9de7f2f0feacfd41969c2be6630ec7b674eddd6b84cbb357e844f802d81c583fed2b659e9149cd89e79c8446cc2f980e4fa5dee +9aace26837695e6596007a54e4bccdd5ffb16dc6844140e2eeeb584b15acb2bbffd203c74440b6ee8db676fd200b4186a8c3e957c19e74d4d865ada83f80655323dfa3570907ed3ce853b6e8cc375ed2d758a2f5ad265dd3b47650517a49b3d02df9e0c60c21576378c2b3a08481eec129b2a75608e13e6420127a3a63c8a3f1 00a63f9cdefbccdd0d5c9630b309027fa139c31e39ca26686d76c22d4093a2a5e5ec4e2308ce43eb8e563187b5bd811cc6b626eace4063047ac0420c3fdcff5bdc04 a908c8c9779cfe489f567fe602de0ed62e44c235b6003a565de3988caf55233c240d01beeeb65e08ee251fb908624e1e0f85a88a4a38afdc3df891d75b7cd4c2829744dc6be0096c63fcf2768f8fce6fe93825290061713372dd67cbd3c557ce +ac2175940545d4fbab6e2e651c6830aba562e0c11c919e797c43eff9f187a68a9e5a128e3e2a330b955a3f4577d3f826529ad1b03d7b60f7ad678f005053b41dc0f8d267f3685c6abe1a0e9a733c44b2f3ca48b90806f935141c842e3a6c06a58f5343d75e3585971a734f4ae1074ce5b54f74bd9342f4bbca738d260393f43e 0024f7d67dfc0d43a26cc7c19cb511d30a097a1e27e5efe29e9e76e43849af170fd9ad57d5b22b1c8840b59ebf562371871e12d2c1baefc1abaedc872ed5d2666ad6 acf391b4a4d10f882c32349113ef87c57972169e68f944189797be7ce2ea3c904f7a0100bceb4dc278b9c2021c5164760b8e9ecd82ee3c384b8adf300e987bac4a0e81d7bf4fc0d17f646461c5b51b4c865bf4ae7c79d285f8556e19a4a551a7 +6266f09710e2434cb3da3b15396556765db2ddcd221dce257eab7399c7c490135925112932716af1434053b8b9fe340563e57a0b9776f9ac92cbb5fba18b05c0a2fafbed7240b3f93cd1780c980ff5fe92610e36c0177cabe82367c84cee9020cf26c1d74ae3eb9b9b512cb8b3cb3d81b17cf20dc76591b2b394ef1c62ac12ee 00349471460c205d836aa37dcd6c7322809e4e8ef81501e5da87284b267d843897746b33016f50a7b702964910361ed51d0afd9d8559a47f0b7c25b2bc952ce8ed9e 893e1be6dfdee9456e7b77afb02ae50f441fa218b5676ccacf5a3f0a46645f92ff05a8b10433b2e58b261503100ff6c700efb648c2d22daf220e8389ee8f12310115cf20387c94cb3bff67f1beccfb5fe0a87b8eebd1b1435f703de146d82175 +3de9e617a6868dca1a1432d503f923535da3f9b34426b2a4822174399c73b1c1ee67311410a58c17202ac767844b2024d8aa21a205707d93865693ac25a24fc87034fa3a7a7e27c3344cb03b87602c15180a5fe6a9dd90cd11af4a0f150207bf2d83f55b12c088adae99aa8cfa659311b3a25beb99056643760d6a282126b9b2 007788d34758b20efc330c67483be3999d1d1a16fd0da81ed28895ebb35ee21093d37ea1ac808946c275c44454a216195eb3eb3aea1b53a329eca4eb82dd48c784f5 9286d2a640b11e449a5f0d90224c28760c48a7e98c6156d5faa06e789018f25a9db7d6174ef0240286e6ff9989e77eac0e0adc601f40e0fbb0b0e1379a6e91626399285e4a2819db606882244f91c43bc44856d55c3380506fff6d258a06c07f +aa48851af7ef17abe233163b7185130f4646203c205e22bcc2a5a3697bcab998c73a9ffe1d3ea0b7978ce7df937a72586eb5ca60b0d939a7d1c115c820171c89c8116b7e2c7b98cf0f14e4c4df3cb2f319ad3ab0ea25ff14526ddc037469f000bf82100acd4cdf94feb4eba4ea1726f0569336604a473aee67d71afebb569209 01f98696772221e6cccd5569ed8aed3c435ee86a04689c7a64d20c30f6fe1c59cc10c6d2910261d30c3b96117a669e19cfe5b696b68feeacf61f6a3dea55e6e5837a 80281c12c524433795cefd6eec670cc43d298dc55774a505aa959fcbba62387aff50962000f1a942344aebe1a4216d7517b5fc9940c6ac113c56e7acd2889ae3d102ecc346499feb58ef61beac2a4e5e3e38fc38fd1a5ae1412708325deb6dbf +b0d5d52259af364eb2d1a5027e5f7d0afe4b999cc5dd2268cfe76f51d2f17b541bdd7867e23a1bb897705153d9432a24012108979c6a2c9e2567c9531d012f9e4be764419491a52eae2e127430b0ab58cb8e216515a821b3db206447c235bf44ee304201b483b2a88844abaa18bca0147dfff7e502397dd62e15524f67eb2df2 013c3852a6bc8825b45fd7da1754078913d77f4e586216a6eb08b6f03adce7464f5dbc2bea0eb7b12d103870ef045f53d67e3600d7eba07aac5db03f71b64db1cceb 8f9b3e2a65e081ca1a428b78431a2a0fac8daa80b6ea5f9386cb0a92ef4438ad4f70db0c26159ecad91bbb74849c57af10a3492b0631c012bb36eeb598978ac956b178cb895a95c767a934051edf95951b69de8dea49419a17fc53786cf03ac4 +9599788344976779383a7a0812a096943a1f771ee484d586af1a06207478e4c0be9c200d42460fe837e24b266c8852d80d3c53cc52ffb1913fc3261145fc6da575611efd16c026059a2e64f802517ffd1b6b34de10ad2909c65c2155e8d939b8115400c1d793d23955b15f5d1c13c962ff92b4a815cee0e10f8e14e1f6e6cd38 01654eaa1f6eec7159ee2d36fb24d15d6d33a128f36c52e2437f7d1b5a44ea4fa965c0a26d0066f92c8b82bd136491e929686c8bde61b7c704daab54ed1e1bdf6b77 9470a91b9449cc018784079229ba45d27bba40780e09a3b71cfeb99ef64e1904216838f5a6bd69394c990f88f2cadb0c0ea438ea175583f1ac18c56419342fc630acfae6e759267a0551c16a088fa9fc5e821ee8e88d5674022054a7159cb963 +fdde51acfd04eb0ad892ce9d6c0f90eb91ce765cbe3ce9d3f2defe8f691324d26b968b8b90e77706b068585f2a3ee7bf3e910528f7403c5af745a6f9d7ba6c53abd885c3b1be583415b128f4d3f224daf8563476bd9aa61e9c8518c144335f8f879c03696bddbe3ac37a8fbede29861611feaa87e325e2f60278b4893ed57fb0 01cba5d561bf18656991eba9a1dde8bde547885ea1f0abe7f2837e569ca52f53df5e64e4a547c4f26458b5d9626ed6d702e5ab1dd585cf36a0c84f768fac946cfd4c 9813512a69fe5fbaaa5129114825d582500f3606073eef3d3f15c2a46392e72e34e1f8034d5017679fedc8e86fda0a95145ee3552421cd6496f0fe5fe3c8cd100097df82fdfb6f67b27fb672365af1a62e10653fb0440d0638ae2b1bf8fc3aba +beb34c997f905c77451ac392f7957a0ab8b23325bd5c63ca31c109ac8f655a1e3094240cb8a99284f8091de2ab9a7db2504d16251980b86be89ec3a3f41162698bab51848880633e0b71a38f8896335853d8e836a2454ecab2acdcc052c8f659be1d703b13ae1b090334ac50ab0137ddb5e8b924c0e3d2e5789daaef2fdd4a1e 00972e7ff25adf8a032535e5b19463cfe306b90803bf27fabc6046ae0807d2312fbab85d1da61b80b2d5d48f4e5886f27fca050b84563aee1926ae6b2564cd756d63 991275dfbb4c12b21ee2f9b7db0b3798185b5443dc38d1ee954041ad50794b45688da7eea6ef01ec858e166091b2f6e809ef4d8f211d68445e6821ee652a511e3c54a5c20c5c73eb57c3ea3335b1c4892e78f7e7e90d277b234a745610989940 +543c374af90c34f50ee195006d5f9d8dd986d09ad182fcbefa085567275eee1e742bfe0af3d058675adeb5b9f87f248b00a9fbd2aa779129123a5b983f2f26fc3caf2ea34277550c22fe8c814c739b46972d50232993cddd63a3c99e20f5c5067d9b57e2d5db94317a5a16b5c12b5c4cafbc79cbc2f9940f074bbc7d0dc71e90 01f0ec8da29295394f2f072672db014861be33bfd9f91349dad5566ff396bea055e53b1d61c8c4e5c9f6e129ed75a49f91cce1d5530ad4e78c2b793a63195eb9f0da a775fc615150f91376ac34bc2797f923352514ea0a8fb828b4d64186aff6650237e81668b8658e192f43ee6f3d50e0d613107755d84cfbb1ff4537e42965e6ef0bd5e1d76e7aa3c0a40a5c6a4f09c5cd593ede109330a55b6e3a9bac1ec3bc7a diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_rfc6979 b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_rfc6979 new file mode 100644 index 000000000000..3d6a1a522c5b --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_rfc6979 @@ -0,0 +1,34 @@ +73616d706c65 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 b5da61b889f44433ae2eca36ee357782b0158a6376ba62307597ea13097b27411f73aa6b468db7096e3de2e913f168bd10033899de6783ffbce7daba22c1cfdaa0139e5ee89229895ce83273825b14a24eb6bb2ebd8130a8c979d56430eafb0d +74657374 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 88d3170bf64b22984d01bcf91e8c8b45b746b8e2f2736f16b00f0d603ef812de0a113c1e04cff00336e9bee2346854fd09b610f8fe545bf30399dceeaafc8966ae85bed8ce947d2ec97afd03755ace69f763211c8cde68759f9e62bea0e0f7c9 +73616d706c65 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc b42881dc7aa8748d95aac40037307f2866db80bdacd3d77e3da4c67414d28bf983022634521af4b00e31dbb6a36fc8ef07649847b181a770d397d6ec76489d8d16af8f315ce5ac98ce369746ae4e4bad49bb56567dbdc6e465e5fcb9427405ec +74657374 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc a38898883e57fec86e5db5be5994cba7169c759d1e832be5c0c35bc9944d7ab10866e072671b58d5eff30eb8a9dc2f1e02bea61ceea648adbdb5896a3fafc78f4b1b653f6df0ba8b18a7f738101f8651ac4a239d38df062224eb01b2a4657209 +73616d706c65 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 b082e7adc2b96c28c8404fd71b33108c69de124aac453c18603a185b82064e9452ebbb26ef393b2d0a4215bcd56a55560cb8a5ca11b28abaa315192fd15fd1c38739b1cacb5b47aa05f877820d634ff7f75d76f2f19508e6f0ff53bcd65da7a6 +74657374 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 adc4135ef08f87da13bbd32fe730164851c62beaf297b07397fd40bdf3c0fe20bc6800bf7904367a1f98551b556a5352158ab646937af34dfb3548966d0ceb9ee1aa4eb133f8ff2d8df5eef8fb7b178aadfba371a19fb1557f00913c97c1c52a +73616d706c65 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 8ab8941a2de042ee8a14625dd78cbc5695186fb9f8fb71accb2d406cdcdc10b0feef6825b5160e41e5b5959f960cc790065b65419cfcacd6808aada1f2d13b433be33e53683379fbdf6f08f77416c2d826850523ac9d3b2bde6754808bbdb5aa +74657374 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 b448f6a0e53157b6c7d0c8afb3d7d422c38e80dcfae089e18e42fcdfa9fa700755c6648cd409f69fbb7b844d58c0058904cda30731083848bb1e0b452d7006607f40b482cec04d9eed734c37d9e9b5af1e22e7a30e23fa5b11dad5b3f83a0d04 +73616d706c65 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 b7ccd4eccb05b8117c60c507ff51ccee216599a27c47358d921c97346055e9bd6a52851ba0a836f09b14617dfb1c44d817182cf10abc91c37175d56c5a2c7fef4710cc6ec51e5d96b2aefb8584f2d1e5d90c4a2973c6bef2ec54ba09808fc9e7 +74657374 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 a133c2c7dbb8b97cb1f6abe8522eb5d622329b6a4013a6851e7843865167439b27167b34e5abb373010d20432d8cdc4b0b7606f9896fa76f7053eb95288a92d5fdd96ba375bcd04995ba9f5cb7240d9aa86804de7041ae02339fb398495621e3 +73616d706c65 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 805ee8885d17884ae47b3f6e982139451ff2f3ec94522e4fa95fe7da9dae4f2c72733174adf2a6c46d858cfbc865cc1904703ce0c8eaf5242c41f23b4dc51646bb055d1c064cab19d8001f334240ca1ed6fb2cb9d14fa90fa647ab154db659b4 +74657374 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 a93b11b0341e371ae8234042d8704ec08abff62e82d6e0aca38fd6691b6f028397a30d9db693df41132421cae997e9cd14df691f1eeb21051c6235ea8ae6991d9c9e190808698aa633c8d25ebf476328781e3eed350c3e6f03217a3d68026b56 +73616d706c65 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 893c0c744f321d719234396812c4607dbae719830f9c6388849e75ee7537808e7bf5a21b9cc833bf5263737c4ac32aa30522c77934e28d8982ab6fa8da4b05a255565d2b3a17faff38773ba55241f5dd5b822188130be2ff617d38fe71083982 +74657374 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 922e8b6b7bd9178e10242030afa920cab1877af7ce2a68ffb6a2294c94815b5e170fb72ad6d22844393c3f8929a5ac5109a74d691f9fd2890754ea928db203bed991124fdf38a624669f0865257640f423642717319e7a9d446088b6b29795b7 +73616d706c65 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 84040b76ee1d9b9a7dcd71132964e07ce2209cbb60937de7e9126524f6c761b8ec7e67c3625fa69d86f71b327022a0f611247b0e737babb16184a4e4affe976c6efb15320b8bf1784320a2bdde782465f392599b6bb863e7beadf861865e06c2 +74657374 9a4d6792295a7f730fc3f2b49cbc0f62e862272f af24ea6a0724142c3d550f06c18a3e2b9187eb28b646f4b3be61f389e2202ce75224d888bfac93c97eaaec255a2a289d136cf1ad8d04c114b64d8a5ade221376ce31e492461d626f22967e52137dc3ad485a47aee2e6e530abf6599c9c5503ac +73616d706c65 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 995cd965b7eaa06a18f7bb8b2d72b738e6c3783b633c0ef85f5c1e8da684c492ece41a458bcf51a9badf635dc9f5d3420504cd362ab5014d6a2371f3488524eafa915d853e4ff41995de5af7cf5887cb6fe07ddd4e7376b7e0e1f35904933c06 +74657374 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 8e9667de176480aae6caf07ea34ae863bca0b8b684a7e1676f80c258f2901e9df0145ff545be07e2febb2b943919bc601194b269e2e28979c8e1048a395097df528c49bbe8131623a54a4fe1713b7b79c4f67f5b761744c1701bceab1077f656 +73616d706c65 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a 86998b3814cac2803b10cb1243fb85cb102a7e017321b16f6665be8ea931ccca686632eeac3ac55f1a2109b695e6ab060112cb23554a9bc44b11ce0344a26e7021b413d62caf834e565182bcfcc28f4e162a1c246d260dcec17565197135cb73 +74657374 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a a244d178fe08228d95a394ec87f127c88a04d46c6da8f7d125e6de19f6884b28deb710d25a47826022c802f04c95502b126de122cfc5a7126bca59e24d2e384de1a6d0606113d3ea32e9bdd2a462cdf2f60ea8519719ae64f21abdf96f2b087d +73616d706c65 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 8b3d3f98e94ea98ee8132b7e3b2bcb983634e9aec786f8c4eb837af39a600c54a736b6811656ee663ee5b4e594b2e6ed0e3d2e4fbd83175c6672cf25fdf16fc45b5de1707856685005c2a1b1a43749fce891a22763e23fbb0f4ceb1412acd93d +74657374 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 a2f4e05adf10f1bdd711d04eb4d0790e2a9e027b7cf446d2353030c2a244055634f2ba738620ec13d238042714e5dc7c158c6c820bcaa5edc0f64b048bc88f8514eac1843b60583a1b481ed9acc96b3b07cfd2de3efb26dfe2908efd63efb133 +73616d706c65 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 91bd29b6327c80d97f1ec7bba1c16b16d9b81f139aa7fbfcf61eb003b8ca5b3fa54edc7a95bb95acb75c621cc76b117c0426063150a3c6e363d39756bfdeba96e3caffbae20736bb497f88fc8895671937d75d6c7b23e433559f338be9b2a018 +74657374 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 82f652938bde28678e1fa59f7bf9df8f5dd5204c52c8ccb5578470af5492a5b67a838b9afa58707ee1853b724674fe4f1287551bf72ac37bec7b543ed946b44b01c975950e7b446698013b912098c5134fc667f229895338ec877d668aa29759 +73616d706c65 035318fc447d48d7e6bc93b48617dddedf26aa658f 9973a5c6a6a725e92e1ccf48acff4ff1a695147121d103cb788bf347d4041e9b75761d876b472faa00397f74fdceef250642b19a8626cc1717d388d2435e00b85c5e10953d5cabf81345c344355f7f2001b0a502cc124e2fac8fe92ce1b51164 +74657374 035318fc447d48d7e6bc93b48617dddedf26aa658f b1592fac4eb4d1ae2e5019d1ffaf28096e86333061bae1f087a0595f6a114feeb8a844b5a8eb5d9b9461705eec547ddd198758bf6a1b8cbb17521fc2a61c7ae2fcf0e6fb2f54ead8c71112014a795c97f780739a83c724f19472e6692f54ad70 +73616d706c65 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 b650f50f825da83782c8737d0ac0a706eb39e54477d410e7546ba78a2b2bd930c91bac49949848657983a26744f9a93304522658ca75dfa19cf560b60cb11c2523d59ad4da916e7829a647e4c1d4fa79c71c386dd0ee4346b1787b8251e387e6 +74657374 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 a455879aad5625d17aeafae6d180aaa8d85a30811b3408c60e5f1b88398ee802c4cebff17364a950f78fb55e0bc5b4d90e148604fca71ee664f2d7d5d1f78e1a437ae44c06367ec12955a43a2882aab510c90bb73e62508de6d020e0bd6767d3 +73616d706c65 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e b72bab2d5104c9a1c7d702a69463af91daa21f2e135318ee61f2828c4e1622d10c4b1d2fd5bef86f885ca3c67eee882907a00fc57f292da7e900b20823491cae117f1e886a419ef8f3725cf570bcdc3f462da0ed4f4ff634608f13e636a5d917 +74657374 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e a2699a269e0a641fafe5b05f8b7971cc1ba459f2b4d304dd58ccaf48db5652a937afcb761cabdd6b439f4908a05ddb6600fb96b3d24c168f007fd4776a26b2c112fea4d5749ae5f8cc017c7c87776475305d18f907e98ed780ea69a773b6b226 +73616d706c65 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 93150a5c466d820f516e53ce8df135ccdb78c9de77f8aaa64f45d78befa396d57dd23f52707df76eebb1acf3cebbf7f70247e735fffea139f0e4e4da867738f7c3be5b1f3fa2bf43fb443405ee434d766c6105790f68290a57a321f7939ed3f3 +74657374 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 a1f6994a251f72c2fb6f6a6dd86e1e2b410476cb58f41a2f47a70050bed5592f60889f06b45253e2200722e3bd3f0bbe0e3d88cc2da2f84ccb2a4620ede1fad7864b5fac9513c0f07fad79c36353663537b2b362fdd1f23a03e4cdf6a522496f +73616d706c65 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 86b7bd886d81d1d5890081cadec6bc9c182a20118e67a1526d8f0ae9483bb63a5df09f62f4d011b3fce92ac36f9eb5a40d4625d328f9d24a42fabdd19007287f9928af22799b388499e8133abddea027ba1f4006b9c6cfccbe5a141b25ad207b +74657374 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 b6f45623a7139ef0d46d556978893b9cae2c9b5361472679ab3ae33c2eb38c9716e7008a7d620ee7db15cfd9521d04290edd88de1a448d7c764c3100d04e0b783fb7166d066cf62d0d66b48573bf156f9a961868864d96da74ce0be94c5e775e diff --git a/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_rfc6979_blst b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_rfc6979_blst new file mode 100644 index 000000000000..a8564aa48279 --- /dev/null +++ b/src/lib_bls12_381_signature/test/test_vectors/sig_g2_pop/sig_g2_pop_rfc6979_blst @@ -0,0 +1,34 @@ +73616d706c65 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 b5da61b889f44433ae2eca36ee357782b0158a6376ba62307597ea13097b27411f73aa6b468db7096e3de2e913f168bd10033899de6783ffbce7daba22c1cfdaa0139e5ee89229895ce83273825b14a24eb6bb2ebd8130a8c979d56430eafb0d +74657374 411602cb19a6ccc34494d79d98ef1e7ed5af25f7 88d3170bf64b22984d01bcf91e8c8b45b746b8e2f2736f16b00f0d603ef812de0a113c1e04cff00336e9bee2346854fd09b610f8fe545bf30399dceeaafc8966ae85bed8ce947d2ec97afd03755ace69f763211c8cde68759f9e62bea0e0f7c9 +73616d706c65 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc b7b5dc6d3922180c9a1d5b4d255d30aafaeab18a89b89b495d24a343b28d641492f98cf4e8907a0fb5e4f44fd54083e812f0a42240d1f92299b70914a506ceed22277c66293c2e599f6ee67fa73cba0e9e2a3e258da6a8d45729449c3a90d664 +74657374 69c7548c21d0dfea6b9a51c9ead4e27c33d3b3f180316e5bcab92c933f0e4dbc af70892d425ed03685ceb9bc6c6fb6c72cdae8d40ab9179605f7c58d8c07398dba45a57d233db927b86f5698610e97c615d6561b92346d983bbb1323262411823cd77edcdc6ee05d2124c93dc7c55b1d5425de4a7cb92c2d0a0bfb6381b1f792 +73616d706c65 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 b082e7adc2b96c28c8404fd71b33108c69de124aac453c18603a185b82064e9452ebbb26ef393b2d0a4215bcd56a55560cb8a5ca11b28abaa315192fd15fd1c38739b1cacb5b47aa05f877820d634ff7f75d76f2f19508e6f0ff53bcd65da7a6 +74657374 6fab034934e4c0fc9ae67f5b5659a9d7d1fefd187ee09fd4 adc4135ef08f87da13bbd32fe730164851c62beaf297b07397fd40bdf3c0fe20bc6800bf7904367a1f98551b556a5352158ab646937af34dfb3548966d0ceb9ee1aa4eb133f8ff2d8df5eef8fb7b178aadfba371a19fb1557f00913c97c1c52a +73616d706c65 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 8ab8941a2de042ee8a14625dd78cbc5695186fb9f8fb71accb2d406cdcdc10b0feef6825b5160e41e5b5959f960cc790065b65419cfcacd6808aada1f2d13b433be33e53683379fbdf6f08f77416c2d826850523ac9d3b2bde6754808bbdb5aa +74657374 f220266e1105bfe3083e03ec7a3a654651f45e37167e88600bf257c1 b448f6a0e53157b6c7d0c8afb3d7d422c38e80dcfae089e18e42fcdfa9fa700755c6648cd409f69fbb7b844d58c0058904cda30731083848bb1e0b452d7006607f40b482cec04d9eed734c37d9e9b5af1e22e7a30e23fa5b11dad5b3f83a0d04 +73616d706c65 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 b2481324a567c5027ac9640d700b9886f38ced4a330b66834d65e008a754fddf3172948c02bed859f9e5904987cf42ce088e69e1418fa9f4b64abfad041918d549d2924182f024848f4101e59b56e61673132773f634f185f532382a641d4a36 +74657374 c9afa9d845ba75166b5c215767b1d6934e50c3db36e89b127b8a622b120f6721 80b57ed4e1f23874ac3637dd7f4e338f7d5ae8010e1094738ba2d01732755ae3f7795ff535e8c2d4a93fbca84d5fa8ee028e06b352a1a5a6ff871b337b6d73149fd1cfbedd9a205d0e74ac3e419bd6e4e4d30fd6e75f802e1294b30f542608d8 +73616d706c65 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 a67c7ab285aee085497f6478cd8ec24b0b1b0de1cdaf951517712a96c0f1f831182a806b0eb1a16de15bdebcfd415643129821022e55237314ccca22902eb5af6214ea0ac3704d273fca056d5db8a82053f8c8510a0229726be1310a0b22202e +74657374 6b9d3dad2e1b8c1c05b19875b6659f4de23c3b667bf297ba9aa47740787137d8 b88d740b748231df776786d0464acf2cac91f1b1b946c688550e44179d798047873f5a0d9e2093aee21952d55fa079f903f30822ab513042aea07cece597f7eb596cf7686fb7c0f5159512a756b015c6a995529751cd5b4dcf3aecd963869237 +73616d706c65 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 93b9a99309fb9d94a856041f9eb2eeaaaa41027e972e1a569a327659a069789760f40446e15d6ba1228d89918a25d0971302f26721908bdbf189cb242c1d91844e2860892dbc3b88b82edd49ab89e6cbfe5427e711763573aa269fa2652c88b2 +74657374 0fad06daa62ba3b25d2fb40133da757205de67f5bb0018fee8c86e1b68c7e75c 97de60ee2781a42757fa438b9bf274a0db2eb724476d65973c5fe725d5a7a4feb8c13f968656a1c2286c0dd1b0cedb5a04b6f48a8531babf07cfa937469cabfb85528ab863d3f5c2885c6c152ff31f2f1a25bc84514f188a149b3b9c26b0def7 +73616d706c65 9a4d6792295a7f730fc3f2b49cbc0f62e862272f 84040b76ee1d9b9a7dcd71132964e07ce2209cbb60937de7e9126524f6c761b8ec7e67c3625fa69d86f71b327022a0f611247b0e737babb16184a4e4affe976c6efb15320b8bf1784320a2bdde782465f392599b6bb863e7beadf861865e06c2 +74657374 9a4d6792295a7f730fc3f2b49cbc0f62e862272f af24ea6a0724142c3d550f06c18a3e2b9187eb28b646f4b3be61f389e2202ce75224d888bfac93c97eaaec255a2a289d136cf1ad8d04c114b64d8a5ade221376ce31e492461d626f22967e52137dc3ad485a47aee2e6e530abf6599c9c5503ac +73616d706c65 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 995cd965b7eaa06a18f7bb8b2d72b738e6c3783b633c0ef85f5c1e8da684c492ece41a458bcf51a9badf635dc9f5d3420504cd362ab5014d6a2371f3488524eafa915d853e4ff41995de5af7cf5887cb6fe07ddd4e7376b7e0e1f35904933c06 +74657374 103b2142bdc2a3c3b55080d09df1808f79336da2399f5ca7171d1be9b0 8e9667de176480aae6caf07ea34ae863bca0b8b684a7e1676f80c258f2901e9df0145ff545be07e2febb2b943919bc601194b269e2e28979c8e1048a395097df528c49bbe8131623a54a4fe1713b7b79c4f67f5b761744c1701bceab1077f656 +73616d706c65 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a aba854e6f042ef1bba34ed387a73608a754632262939071de42c5e7bd49feb4529b5000cf27d0c74dd6a665e7290a9e8091ec97d9348c9a359994c6c048a70a9589eff583e5b2a35919e55b1c400572980f61ee82737aacb380406c17463c1c2 +74657374 06a0777356e87b89ba1ed3a3d845357be332173c8f7a65bdc7db4fab3c4cc79a ade2800a104af9d0c39cae0b8b8a12221f8b8382e2f8be013cb8558b34bf72eb1a90549881ec47c5f4ffe5e5aaf4979619b6f5ffa33c9c9d972bc04791348e464ad45f60e658bf10197204133adeac39deefec8c02167ba56e7bc476d4ed38d8 +73616d706c65 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 b168b42327c934ef86b5019c883b76e820cc06b351a558dd5637cfd19949a5d2bc509d5a2aa2804129fef1bdc2a17ca918ae9d81db90861831de3618e0a2d2cec43d1322433a7537b31d5f01093e8846a76e238fe0c2faf9e6841252c58d8330 +74657374 29c16768f01d1b8a89fda85e2efd73a09558b92a178a2931f359e4d70ad853e5 b9315d339315ca06d55589c454c9e982140f31e4fe539572968f344e42f06eaf0d7eefcd8900c0903b696dca20e0a09a0099b9e1e15ec6903b82cb6405321529328be722f9c0d63a265109c4ca3a90ac205a0ef356f5e8b548d94c52302a07d0 +73616d706c65 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c b8ca18ecddd51ffe714d407051d0f9d4e081c2e951f1e1fbf66e30b36013d4b46450f6a2d567cd145e9edaa1a2d68d4818e4430afe6e5820940db571c6ec6d41d4e65087095b37d12b39f9b53087f2108e389a5d59df279308ab8df278525adf +74657374 0c16f58550d824ed7b95569d4445375d3a490bc7e0194c41a39deb732c29396c 8727796fd911039b0d130e5d1b949834e631be59fad3a45ec5cdb880c85ab132ee73b8cc9977606b5a87c7ac7c372a5d0ddbf8da2887c7753c759db780f27b06b8838402f3e1f9db866a4458122e81fbc3e87b79fd355b5c7adb540328441287 +73616d706c65 035318fc447d48d7e6bc93b48617dddedf26aa658f 9973a5c6a6a725e92e1ccf48acff4ff1a695147121d103cb788bf347d4041e9b75761d876b472faa00397f74fdceef250642b19a8626cc1717d388d2435e00b85c5e10953d5cabf81345c344355f7f2001b0a502cc124e2fac8fe92ce1b51164 +74657374 035318fc447d48d7e6bc93b48617dddedf26aa658f b1592fac4eb4d1ae2e5019d1ffaf28096e86333061bae1f087a0595f6a114feeb8a844b5a8eb5d9b9461705eec547ddd198758bf6a1b8cbb17521fc2a61c7ae2fcf0e6fb2f54ead8c71112014a795c97f780739a83c724f19472e6692f54ad70 +73616d706c65 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 b650f50f825da83782c8737d0ac0a706eb39e54477d410e7546ba78a2b2bd930c91bac49949848657983a26744f9a93304522658ca75dfa19cf560b60cb11c2523d59ad4da916e7829a647e4c1d4fa79c71c386dd0ee4346b1787b8251e387e6 +74657374 7adc13dd5bf34d1ddeeb50b2ce23b5f5e6d18067306d60c5f6ff11e5d3 a455879aad5625d17aeafae6d180aaa8d85a30811b3408c60e5f1b88398ee802c4cebff17364a950f78fb55e0bc5b4d90e148604fca71ee664f2d7d5d1f78e1a437ae44c06367ec12955a43a2882aab510c90bb73e62508de6d020e0bd6767d3 +73616d706c65 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e 9885cb73973d73c1af01c9d3ff7c6307e21eaf65eb415f3a46ed665b948025fed65b937c725e8be8e7b9caed3322beeb02e384d0a6683272947d05d5f33595dfc25fbd9e924ec4376bdb13e430417cea5404de4baa95061ce541e88fb612c5a8 +74657374 14510d4bc44f2d26f4553942c98073c1bd35545ceabb5cc138853c5158d2729e 958ab4fe9f50f60434df1929cc5d66848d9422d1b45580df13d5892d4078d32c261c57d38fc8445ea3fdf3e3f288bde5051563b1254865ec766939c2c8203a00ae81b147a42dcfc6d961249b75ad26ff4e19b1f54ebad384f7a0399c0931a6e8 +73616d706c65 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 b9efaec7348969bd73a08c9800f29e5742cefa048073d5a71879716b608df35bb0748933d50e04bc13ad2c2eba22e9831006d1cf502cd26614407f80d5763af68fa82f0918c85a9929a1b768ce47d9c661f0b06619a902f3e911392ada364890 +74657374 0494994cc325b08e7b4ce038bd9436f90b5e59a2c13c3140cd3ae07c04a01fc4 a7bb6c32c72e4c1b4b352bc6c905c533184ce6aa341cfa5c2e3418366c926aa89b9e7208050bc0ff9d79b271acc7b7c30bd8af13e51475ca13435957495056165e174c2f45fc7b34e293fa0543d5eacdf3e8fd4fc08f552286803e7791275754 +73616d706c65 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 abd97f5a61438ac9fea3a0c379416b382edf524ee34357a082c50eb2766eff3af01e22cc9bacf8805dd27ca3126be55507a0bb2c6f8f217396d1cd5eb29b74a74f2b748e1ad04f55653b108a2f10c8beee94aebe59d898ef76d8129715b87728 +74657374 028a04857f24c1c082df0d909c0e72f453f2e2340ccb071f0e389bca2575da19 adcda374c92560d76751819969c697f160cfbf800511fe2045cf652332c9d546b3a277ee54cf6863b60c388ab6a63b270afaeacd642e44f7c5ec1bb6168cabcef1ed0e51047e5c516b211efc76061a7cfdc6c5f32063144d0d248e3851ea867f diff --git a/src/lib_bls12_381_signature/test/test_vectors/test_vector_g1_2 b/src/lib_bls12_381_signature/test/test_vectors/test_vector_g1_2 new file mode 100644 index 0000000000000000000000000000000000000000..4500c0ac445409e0ea20c43a0a0c268edf6a8b3d GIT binary patch literal 384 zcmWfa(bL^+ed|X@>){`wR%Rx%SDe~?M$YxqQa?Li6PNNu=a&3h%23U}*k(oe=cvsW zx&=L*A6=52q7yDIx?1Sgt3UgGo-k*bcSx+-HuRX<8U3wUjus8Sg-ZT}u65XUHv6fR zSh4IRO?ij2`~7}jIyZSr&+AIpRW2WduYCJ=VMgZc5)p5yTk+Zn_L0`+%6~-_m-cY| z)~MMg?6%@bak}pe*UvBXJ9j>s9>P$t)+g$mNvG9TA44-=oioQD)wgzsgu8?_3Wc#; z+WIEh!}5D1%Q5SWYi~(R*>xrNt6R!ro_!}xV$c0m`g=6NUh}1mN45I1(Df}Z4~Q?{c;>Bg zdd%xvxstcsjV3&1dA@drYu6^zxCEWG+-fO{_!jK^@b2B8m;46NI(d7!IMS|f(Ei?i wJ#|U&gvW38Th;A-bZ^lM1q00$CeI#6%=^Z~TzEe>&0h2e*4E(-izmATqgJH zNTzy~8^-z33eSu7E8Yp*Soqi{@WJ){@B75}_a!ihu&fZ@?#Pnlb#v7Sz&Jy#BOGS8OZ~4tzTsPxI_I9^x{Ed~N z0%wHFn^stqXmqFvTvM8uCUNZ-A4~H^=7S|7d?8zJD)4`Om^*oIdflFyKxby3J5QR@ zzx~oWzUTHGPnV4P4UZOYnc^auagc4Dl9uz+=-?zy+xaGyn)8DGIqAAgVLjp|e|Tfy zoE^O{L|FOm%;vM)x<%YYI`DzYWSg~?*>OU@pH1%5eyn()ZG9u-hq>29Z>-6vb@5$x zZSjtktM}#@uMP9dB3c%WFDmO$)3v z^aQ6k23(n5F=y}9C!3eC*qBXS)HUa=K(})Nw4G7A`KoJ%(G5iJ$8 zDX{eB(GIKG+uz?zn0IrZ@dTN>M_OH(uDG8oWSBN(TU@bJ1OLvAwM}vUl1n%@9W0vP zelj3S>{*)W^Q#4w^FQiMzL{Y5_c&iz(-oyf9hOR$i}y1Ktp4~r`<`$1n$+$qj_udo zY{Cv-UmL1@xarObi7xRu`VB&bAuAmE^_R@~ + let full = Filename.concat path name in + if Sys.is_directory full then loop full else Hashtbl.add t name full) + (Array.to_list (Sys.readdir path)) + in + let test_vectors = ["test_vectors"; "test/test_vectors"] in + List.iter (fun f -> if Sys.file_exists f then loop f) test_vectors ; + t + +let open_file filename = + let name = + if Sys.file_exists filename then filename + else + try Hashtbl.find file_mapping filename + with _ -> + failwith + (Printf.sprintf + "Cannot open %S, the file doesn't exists in test_vectors" + filename) + in + let ic = open_in_bin name in + ic + +let read_file filename = + let lines = ref [] in + let chan = open_file filename in + try + while true do + lines := input_line chan :: !lines + done ; + !lines + with End_of_file -> + close_in chan ; + List.rev !lines + +let generate_random_byte () = char_of_int (Random.int 256) + +let generate_random_bytes size = + Bytes.init size (fun _ -> generate_random_byte ()) + +let rec repeat n f () = + if n > 0 then ( + f () ; + repeat (n - 1) f ()) diff --git a/src/lib_crypto/dune b/src/lib_crypto/dune index 5b0609a8c741..e6679a905b37 100644 --- a/src/lib_crypto/dune +++ b/src/lib_crypto/dune @@ -20,7 +20,7 @@ zarith zarith_stubs_js bls12-381 - bls12-381-signature) + octez-bls12-381-signature) (js_of_ocaml) (flags (:standard) -- GitLab From 7be6b449b7f646354a4ed729409b25dcfe04ff70 Mon Sep 17 00:00:00 2001 From: Victor Dumitrescu Date: Mon, 13 Mar 2023 10:31:20 +0100 Subject: [PATCH 08/34] Lib_bls12_381_polynomial: drop `internal` from names and bindings --- .gitlab/ci/jobs/packaging/opam_package.yml | 14 +-- dune-project | 2 +- manifest/main.ml | 24 ++--- ...l.opam => octez-bls12-381-polynomial.opam} | 0 opam/tezos-crypto-dal.opam | 2 +- ...ernal_fft.c => bls12_381_polynomial_fft.c} | 102 +++++++++--------- ...ernal_fft.h => bls12_381_polynomial_fft.h} | 16 +-- ...al.c => bls12_381_polynomial_polynomial.c} | 56 +++++----- ...al.h => bls12_381_polynomial_polynomial.h} | 36 +++---- ...aml_bls12_381_polynomial_ec_array_stubs.c} | 8 +- ... => caml_bls12_381_polynomial_fft_stubs.c} | 34 +++--- ...l_bls12_381_polynomial_polynomial_stubs.c} | 72 ++++++------- ... => caml_bls12_381_polynomial_srs_stubs.c} | 4 +- src/lib_bls12_381_polynomial/carray.ml | 6 +- src/lib_bls12_381_polynomial/domain.ml | 4 +- src/lib_bls12_381_polynomial/dune | 16 +-- src/lib_bls12_381_polynomial/ec_carray.ml | 16 +-- src/lib_bls12_381_polynomial/evaluations.ml | 15 ++- src/lib_bls12_381_polynomial/polynomial.ml | 24 ++--- src/lib_bls12_381_polynomial/srs.ml | 2 +- src/lib_bls12_381_polynomial/test/dune | 4 +- .../test/test_coefficients.ml | 8 +- .../test/test_domains.ml | 5 +- .../test/test_evaluations.ml | 8 +- src/lib_bls12_381_polynomial/test/test_pbt.ml | 2 +- .../test/test_polynomial.ml | 85 +++++++-------- src/lib_bls12_381_polynomial/test/test_srs.ml | 7 +- src/lib_crypto_dal/cryptobox.ml | 13 ++- src/lib_crypto_dal/dune | 2 +- src/lib_crypto_dal/test/dune | 2 +- 30 files changed, 285 insertions(+), 304 deletions(-) rename opam/{tezos-bls12-381-polynomial-internal.opam => octez-bls12-381-polynomial.opam} (100%) rename src/lib_bls12_381_polynomial/{bls12_381_polynomial_internal_fft.c => bls12_381_polynomial_fft.c} (79%) rename src/lib_bls12_381_polynomial/{bls12_381_polynomial_internal_fft.h => bls12_381_polynomial_fft.h} (82%) rename src/lib_bls12_381_polynomial/{bls12_381_polynomial_internal_polynomial.c => bls12_381_polynomial_polynomial.c} (88%) rename src/lib_bls12_381_polynomial/{bls12_381_polynomial_internal_polynomial.h => bls12_381_polynomial_polynomial.h} (75%) rename src/lib_bls12_381_polynomial/{caml_bls12_381_polynomial_internal_ec_array_stubs.c => caml_bls12_381_polynomial_ec_array_stubs.c} (92%) rename src/lib_bls12_381_polynomial/{caml_bls12_381_polynomial_internal_fft_stubs.c => caml_bls12_381_polynomial_fft_stubs.c} (81%) rename src/lib_bls12_381_polynomial/{caml_bls12_381_polynomial_internal_polynomial_stubs.c => caml_bls12_381_polynomial_polynomial_stubs.c} (80%) rename src/lib_bls12_381_polynomial/{caml_bls12_381_polynomial_internal_srs_stubs.c => caml_bls12_381_polynomial_srs_stubs.c} (94%) diff --git a/.gitlab/ci/jobs/packaging/opam_package.yml b/.gitlab/ci/jobs/packaging/opam_package.yml index b87b45bb1acb..916d17174441 100644 --- a/.gitlab/ci/jobs/packaging/opam_package.yml +++ b/.gitlab/ci/jobs/packaging/opam_package.yml @@ -240,6 +240,13 @@ opam:octez-baker-PtMumbai: # Ignoring unreleased package octez-bls12-381-hash. +opam:octez-bls12-381-polynomial: + extends: + - .opam_template + - .rules_template__trigger_opam_batch_7 + variables: + package: octez-bls12-381-polynomial + opam:octez-bls12-381-signature: extends: - .opam_template @@ -458,13 +465,6 @@ opam:tezos-base-test-helpers: # Ignoring unreleased package tezos-benchmarks-proto-alpha. -opam:tezos-bls12-381-polynomial-internal: - extends: - - .opam_template - - .rules_template__trigger_opam_batch_7 - variables: - package: tezos-bls12-381-polynomial-internal - opam:tezos-clic: extends: - .opam_template diff --git a/dune-project b/dune-project index 3a3eaff03a50..cd019d72738f 100644 --- a/dune-project +++ b/dune-project @@ -11,6 +11,7 @@ (package (name octez-baker-PtMumbai)) (package (name octez-baker-alpha)) (package (name octez-bls12-381-hash)) +(package (name octez-bls12-381-polynomial)) (package (name octez-bls12-381-signature)) (package (name octez-client)) (package (name octez-codec)) @@ -60,7 +61,6 @@ (package (name tezos-benchmarks-proto-015-PtLimaPt)) (package (name tezos-benchmarks-proto-016-PtMumbai)) (package (name tezos-benchmarks-proto-alpha)) -(package (name tezos-bls12-381-polynomial-internal)) (package (name tezos-clic)) (package (name tezos-client-000-Ps9mPmXa)) (package (name tezos-client-001-PtCJ7pwo)) diff --git a/manifest/main.ml b/manifest/main.ml index 8f63f492663a..05caf81a1996 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1086,9 +1086,9 @@ let _octez_polynomial_tests = ~opam:"octez-polynomial" ~deps:[bls12_381; octez_mec; alcotest; octez_polynomial] -let octez_bls12_381_polynomial_internal = +let octez_bls12_381_polynomial = public_lib - "tezos-bls12-381-polynomial-internal" + "octez-bls12-381-polynomial" ~path:"src/lib_bls12_381_polynomial" ~synopsis: "Polynomials over BLS12-381 finite field - Temporary vendored version of \ @@ -1103,12 +1103,12 @@ let octez_bls12_381_polynomial_internal = flags = []; names = [ - "caml_bls12_381_polynomial_internal_polynomial_stubs"; - "caml_bls12_381_polynomial_internal_srs_stubs"; - "caml_bls12_381_polynomial_internal_ec_array_stubs"; - "caml_bls12_381_polynomial_internal_fft_stubs"; - "bls12_381_polynomial_internal_polynomial"; - "bls12_381_polynomial_internal_fft"; + "caml_bls12_381_polynomial_polynomial_stubs"; + "caml_bls12_381_polynomial_srs_stubs"; + "caml_bls12_381_polynomial_ec_array_stubs"; + "caml_bls12_381_polynomial_fft_stubs"; + "bls12_381_polynomial_polynomial"; + "bls12_381_polynomial_fft"; ]; } @@ -1125,7 +1125,7 @@ let _octez_bls12_381_polynomial_tests = "test_srs"; ] ~path:"src/lib_bls12_381_polynomial/test" - ~opam:"tezos-bls12-381-polynomial-internal" + ~opam:"octez-bls12-381-polynomial" ~deps: [ alcotezt; @@ -1133,7 +1133,7 @@ let _octez_bls12_381_polynomial_tests = octez_polynomial; bisect_ppx; bls12_381; - octez_bls12_381_polynomial_internal; + octez_bls12_381_polynomial; ] ~dep_files:["srs_zcash_g1_5"] @@ -1149,7 +1149,7 @@ let octez_crypto_dal = octez_error_monad |> open_; data_encoding |> open_; octez_crypto; - octez_bls12_381_polynomial_internal; + octez_bls12_381_polynomial; lwt_unix; ] @@ -1167,7 +1167,7 @@ let _octez_crypto_dal_tests = data_encoding |> open_; alcotezt; qcheck_alcotest; - octez_bls12_381_polynomial_internal; + octez_bls12_381_polynomial; octez_test_helpers; ] diff --git a/opam/tezos-bls12-381-polynomial-internal.opam b/opam/octez-bls12-381-polynomial.opam similarity index 100% rename from opam/tezos-bls12-381-polynomial-internal.opam rename to opam/octez-bls12-381-polynomial.opam diff --git a/opam/tezos-crypto-dal.opam b/opam/tezos-crypto-dal.opam index 6a85d095782c..cb03dc47c1f4 100644 --- a/opam/tezos-crypto-dal.opam +++ b/opam/tezos-crypto-dal.opam @@ -14,7 +14,7 @@ depends: [ "tezos-error-monad" "data-encoding" { >= "0.7.1" & < "1.0.0" } "tezos-crypto" - "tezos-bls12-381-polynomial-internal" + "octez-bls12-381-polynomial" "lwt" { >= "5.6.0" } "tezt" { with-test & >= "3.0.0" } "octez-alcotezt" {with-test} diff --git a/src/lib_bls12_381_polynomial/bls12_381_polynomial_internal_fft.c b/src/lib_bls12_381_polynomial/bls12_381_polynomial_fft.c similarity index 79% rename from src/lib_bls12_381_polynomial/bls12_381_polynomial_internal_fft.c rename to src/lib_bls12_381_polynomial/bls12_381_polynomial_fft.c index 48b272a3dfb8..a7331a20fa0e 100644 --- a/src/lib_bls12_381_polynomial/bls12_381_polynomial_internal_fft.c +++ b/src/lib_bls12_381_polynomial/bls12_381_polynomial_fft.c @@ -20,13 +20,13 @@ * SOFTWARE. */ -#include "bls12_381_polynomial_internal_fft.h" +#include "bls12_381_polynomial_fft.h" #include "caml_bls12_381_stubs.h" #include #include // IMPROVEME: can be improve it with lookups? -int bls12_381_polynomial_internal_bitreverse(int n, int l) { +int bls12_381_polynomial_bitreverse(int n, int l) { int r = 0; while (l-- > 0) { r = (r << 1) | (n & 1); @@ -35,11 +35,11 @@ int bls12_381_polynomial_internal_bitreverse(int n, int l) { return r; } -void bls12_381_polynomial_internal_reorg_fr_array_coefficients( +void bls12_381_polynomial_reorg_fr_array_coefficients( blst_fr *coefficients, int n, int logn) { blst_fr tmp; for (int i = 0; i < n; i++) { - int reverse_i = bls12_381_polynomial_internal_bitreverse(i, logn); + int reverse_i = bls12_381_polynomial_bitreverse(i, logn); if (i < reverse_i) { memcpy(&tmp, coefficients + i, sizeof(blst_fr)); memcpy(coefficients + i, coefficients + reverse_i, sizeof(blst_fr)); @@ -49,7 +49,7 @@ void bls12_381_polynomial_internal_reorg_fr_array_coefficients( } // Fr -void bls12_381_polynomial_internal_fft_inplace_aux(blst_fr *coefficients, +void bls12_381_polynomial_fft_inplace_aux(blst_fr *coefficients, blst_fr *domain, int log_domain_size, int log_diff, @@ -79,7 +79,7 @@ void bls12_381_polynomial_internal_fft_inplace_aux(blst_fr *coefficients, } } -void bls12_381_polynomial_internal_fft_inplace(blst_fr *coefficients, +void bls12_381_polynomial_fft_inplace(blst_fr *coefficients, blst_fr *domain, int log_domain_size, int log_degree) { @@ -89,7 +89,7 @@ void bls12_381_polynomial_internal_fft_inplace(blst_fr *coefficients, int log_diff = log_domain_size - log_degree; if (log_diff > 0) { - bls12_381_polynomial_internal_reorg_fr_array_coefficients( + bls12_381_polynomial_reorg_fr_array_coefficients( coefficients, degree_next_pow_of_2, log_degree); int ratio = 1 << log_diff; for (int i = degree_next_pow_of_2 - 1; i >= 0; i--) { @@ -99,23 +99,23 @@ void bls12_381_polynomial_internal_fft_inplace(blst_fr *coefficients, } } } else { - bls12_381_polynomial_internal_reorg_fr_array_coefficients( + bls12_381_polynomial_reorg_fr_array_coefficients( coefficients, domain_size, log_domain_size); } - bls12_381_polynomial_internal_fft_inplace_aux(coefficients, domain, + bls12_381_polynomial_fft_inplace_aux(coefficients, domain, log_domain_size, log_diff, 0); } -void bls12_381_polynomial_internal_ifft_inplace(blst_fr *coefficients, +void bls12_381_polynomial_ifft_inplace(blst_fr *coefficients, blst_fr *domain, int log_domain_size) { int domain_size = 1 << log_domain_size; uint64_t n[4] = {domain_size, 0, 0, 0}; blst_fr inverse_n; - bls12_381_polynomial_internal_reorg_fr_array_coefficients( + bls12_381_polynomial_reorg_fr_array_coefficients( coefficients, domain_size, log_domain_size); - bls12_381_polynomial_internal_fft_inplace_aux(coefficients, domain, + bls12_381_polynomial_fft_inplace_aux(coefficients, domain, log_domain_size, 0, 1); blst_fr_from_uint64(&inverse_n, n); @@ -125,7 +125,7 @@ void bls12_381_polynomial_internal_ifft_inplace(blst_fr *coefficients, } } -void bls12_381_polynomial_internal_dft_inplace(blst_fr *coefficients, +void bls12_381_polynomial_dft_inplace(blst_fr *coefficients, blst_fr *domain, blst_fr *buffer, int length, int inverse) { // We copy the coefficients to the buffer to modify the coefficients @@ -153,11 +153,11 @@ void bls12_381_polynomial_internal_dft_inplace(blst_fr *coefficients, } } -int bls12_381_polynomial_internal_is_power_of_two(int n) { +int bls12_381_polynomial_is_power_of_two(int n) { return (n & (n - 1)) == 0; } -int bls12_381_polynomial_internal_log2(int n) { +int bls12_381_polynomial_log2(int n) { int l = 0; while (n >>= 1) { ++l; @@ -165,7 +165,7 @@ int bls12_381_polynomial_internal_log2(int n) { return l; } -void bls12_381_polynomial_internal_transpose(blst_fr *rows, blst_fr *columns, +void bls12_381_polynomial_transpose(blst_fr *rows, blst_fr *columns, int n1, int n2) { for (int i = 0; i < n1; i++) { for (int j = 0; j < n2; j++) { @@ -174,41 +174,41 @@ void bls12_381_polynomial_internal_transpose(blst_fr *rows, blst_fr *columns, } } -int bls12_381_polynomial_internal_max(int a, int b) { return a >= b ? a : b; } +int bls12_381_polynomial_max(int a, int b) { return a >= b ? a : b; } -void bls12_381_polynomial_internal_fft_round(blst_fr *buffer, blst_fr *domain2, +void bls12_381_polynomial_fft_round(blst_fr *buffer, blst_fr *domain2, int length1, int length2, blst_fr *buffer_dft, int inverse) { - if (bls12_381_polynomial_internal_is_power_of_two(length2)) { - int length2_log = bls12_381_polynomial_internal_log2(length2); + if (bls12_381_polynomial_is_power_of_two(length2)) { + int length2_log = bls12_381_polynomial_log2(length2); if (inverse) { for (int i = 0; i < length1; i++) { - bls12_381_polynomial_internal_ifft_inplace(buffer + (i * length2), + bls12_381_polynomial_ifft_inplace(buffer + (i * length2), domain2, length2_log); } } else { for (int i = 0; i < length1; i++) { - bls12_381_polynomial_internal_fft_inplace( + bls12_381_polynomial_fft_inplace( buffer + (i * length2), domain2, length2_log, length2_log); } } } else { for (int i = 0; i < length1; i++) { - bls12_381_polynomial_internal_dft_inplace(buffer + (i * length2), domain2, + bls12_381_polynomial_dft_inplace(buffer + (i * length2), domain2, buffer_dft, length2, inverse); } } } // The buffer must have size at least 2 * |domain1| * |domain2| -void bls12_381_polynomial_internal_prime_factor_algorithm_fft( +void bls12_381_polynomial_prime_factor_algorithm_fft( blst_fr *coefficients, blst_fr *domain1, blst_fr *domain2, int length1, int length2, int inverse) { int dft_length = - (!bls12_381_polynomial_internal_is_power_of_two(length1) && - !bls12_381_polynomial_internal_is_power_of_two(length2)) - ? bls12_381_polynomial_internal_max(length1, length2) - : (bls12_381_polynomial_internal_is_power_of_two(length1) ? length2 + (!bls12_381_polynomial_is_power_of_two(length1) && + !bls12_381_polynomial_is_power_of_two(length2)) + ? bls12_381_polynomial_max(length1, length2) + : (bls12_381_polynomial_is_power_of_two(length1) ? length2 : length1); // We allocate buffer_dft on the stack because dft_length is <= 2^10 at most // in our use case @@ -224,14 +224,14 @@ void bls12_381_polynomial_internal_prime_factor_algorithm_fft( buffer[(i % length1) * length2 + (i % length2)] = coefficients[i]; } - bls12_381_polynomial_internal_fft_round(buffer, domain2, length1, length2, + bls12_381_polynomial_fft_round(buffer, domain2, length1, length2, buffer_dft, inverse); blst_fr *new_buffer = buffer + length; - bls12_381_polynomial_internal_transpose(new_buffer, buffer, length1, length2); + bls12_381_polynomial_transpose(new_buffer, buffer, length1, length2); - bls12_381_polynomial_internal_fft_round(new_buffer, domain1, length2, length1, + bls12_381_polynomial_fft_round(new_buffer, domain1, length2, length1, buffer_dft, inverse); for (int i = 0; i < length1; i++) { @@ -245,11 +245,11 @@ void bls12_381_polynomial_internal_prime_factor_algorithm_fft( } // G1 -void bls12_381_polynomial_internal_reorg_g1_array_coefficients( +void bls12_381_polynomial_reorg_g1_array_coefficients( int n, int logn, blst_p1 *coefficients) { blst_p1 buffer; for (int i = 0; i < n; i++) { - int reverse_i = bls12_381_polynomial_internal_bitreverse(i, logn); + int reverse_i = bls12_381_polynomial_bitreverse(i, logn); if (i < reverse_i) { memcpy(&buffer, coefficients + i, sizeof(blst_p1)); memcpy(coefficients + i, coefficients + reverse_i, sizeof(blst_p1)); @@ -258,7 +258,7 @@ void bls12_381_polynomial_internal_reorg_g1_array_coefficients( } } -void bls12_381_polynomial_internal_fft_g1_inplace_aux(blst_p1 *coefficients, +void bls12_381_polynomial_fft_g1_inplace_aux(blst_p1 *coefficients, blst_fr *domain, int log_domain_size, int log_diff, @@ -300,7 +300,7 @@ void bls12_381_polynomial_internal_fft_g1_inplace_aux(blst_p1 *coefficients, } } -void bls12_381_polynomial_internal_fft_g1_inplace(blst_p1 *coefficients, +void bls12_381_polynomial_fft_g1_inplace(blst_p1 *coefficients, blst_fr *domain, int log_domain_size, int log_degree) { @@ -310,7 +310,7 @@ void bls12_381_polynomial_internal_fft_g1_inplace(blst_p1 *coefficients, int log_diff = log_domain_size - log_degree; if (log_diff > 0) { - bls12_381_polynomial_internal_reorg_g1_array_coefficients( + bls12_381_polynomial_reorg_g1_array_coefficients( degree_next_pow_of_2, log_degree, coefficients); int ratio = 1 << log_diff; for (int i = degree_next_pow_of_2 - 1; i >= 0; i--) { @@ -320,22 +320,22 @@ void bls12_381_polynomial_internal_fft_g1_inplace(blst_p1 *coefficients, } } } else { - bls12_381_polynomial_internal_reorg_g1_array_coefficients( + bls12_381_polynomial_reorg_g1_array_coefficients( domain_size, log_domain_size, coefficients); } - bls12_381_polynomial_internal_fft_g1_inplace_aux( + bls12_381_polynomial_fft_g1_inplace_aux( coefficients, domain, log_domain_size, log_diff, 0); } -void bls12_381_polynomial_internal_ifft_g1_inplace(blst_p1 *coefficients, +void bls12_381_polynomial_ifft_g1_inplace(blst_p1 *coefficients, blst_fr *domain, int log_domain_size) { int domain_size = 1 << log_domain_size; - bls12_381_polynomial_internal_reorg_g1_array_coefficients( + bls12_381_polynomial_reorg_g1_array_coefficients( domain_size, log_domain_size, coefficients); - bls12_381_polynomial_internal_fft_g1_inplace_aux(coefficients, domain, + bls12_381_polynomial_fft_g1_inplace_aux(coefficients, domain, log_domain_size, 0, 1); uint64_t n[4] = {domain_size, 0, 0, 0}; @@ -355,11 +355,11 @@ void bls12_381_polynomial_internal_ifft_g1_inplace(blst_p1 *coefficients, } // G2 -void bls12_381_polynomial_internal_reorg_g2_array_coefficients( +void bls12_381_polynomial_reorg_g2_array_coefficients( int n, int logn, blst_p2 *coefficients) { blst_p2 buffer; for (int i = 0; i < n; i++) { - int reverse_i = bls12_381_polynomial_internal_bitreverse(i, logn); + int reverse_i = bls12_381_polynomial_bitreverse(i, logn); if (i < reverse_i) { memcpy(&buffer, coefficients + i, sizeof(blst_p2)); memcpy(coefficients + i, coefficients + reverse_i, sizeof(blst_p2)); @@ -368,7 +368,7 @@ void bls12_381_polynomial_internal_reorg_g2_array_coefficients( } } -void bls12_381_polynomial_internal_fft_g2_inplace_aux(blst_p2 *coefficients, +void bls12_381_polynomial_fft_g2_inplace_aux(blst_p2 *coefficients, blst_fr *domain, int log_domain_size, int log_diff, @@ -410,7 +410,7 @@ void bls12_381_polynomial_internal_fft_g2_inplace_aux(blst_p2 *coefficients, } } -void bls12_381_polynomial_internal_fft_g2_inplace(blst_p2 *coefficients, +void bls12_381_polynomial_fft_g2_inplace(blst_p2 *coefficients, blst_fr *domain, int log_domain_size, int log_degree) { @@ -420,7 +420,7 @@ void bls12_381_polynomial_internal_fft_g2_inplace(blst_p2 *coefficients, int log_diff = log_domain_size - log_degree; if (log_diff > 0) { - bls12_381_polynomial_internal_reorg_g2_array_coefficients( + bls12_381_polynomial_reorg_g2_array_coefficients( degree_next_pow_of_2, log_degree, coefficients); int ratio = 1 << log_diff; for (int i = degree_next_pow_of_2 - 1; i >= 0; i--) { @@ -430,21 +430,21 @@ void bls12_381_polynomial_internal_fft_g2_inplace(blst_p2 *coefficients, } } } else { - bls12_381_polynomial_internal_reorg_g2_array_coefficients( + bls12_381_polynomial_reorg_g2_array_coefficients( domain_size, log_domain_size, coefficients); } - bls12_381_polynomial_internal_fft_g2_inplace_aux( + bls12_381_polynomial_fft_g2_inplace_aux( coefficients, domain, log_domain_size, log_diff, 0); } -void bls12_381_polynomial_internal_ifft_g2_inplace(blst_p2 *coefficients, +void bls12_381_polynomial_ifft_g2_inplace(blst_p2 *coefficients, blst_fr *domain, int log_domain_size) { int domain_size = 1 << log_domain_size; - bls12_381_polynomial_internal_reorg_g2_array_coefficients( + bls12_381_polynomial_reorg_g2_array_coefficients( domain_size, log_domain_size, coefficients); - bls12_381_polynomial_internal_fft_g2_inplace_aux(coefficients, domain, + bls12_381_polynomial_fft_g2_inplace_aux(coefficients, domain, log_domain_size, 0, 1); uint64_t n[4] = {domain_size, 0, 0, 0}; diff --git a/src/lib_bls12_381_polynomial/bls12_381_polynomial_internal_fft.h b/src/lib_bls12_381_polynomial/bls12_381_polynomial_fft.h similarity index 82% rename from src/lib_bls12_381_polynomial/bls12_381_polynomial_internal_fft.h rename to src/lib_bls12_381_polynomial/bls12_381_polynomial_fft.h index 431d8764b9a5..bcdfe21ab8fa 100644 --- a/src/lib_bls12_381_polynomial/bls12_381_polynomial_internal_fft.h +++ b/src/lib_bls12_381_polynomial/bls12_381_polynomial_fft.h @@ -28,38 +28,38 @@ // H: domain_size = polynomial degree // Implementation with side effect. The FFT will be inplace, i.e. the array is // going to be modified. -void bls12_381_polynomial_internal_fft_inplace(blst_fr *coefficients, +void bls12_381_polynomial_fft_inplace(blst_fr *coefficients, blst_fr *domain, int log_domain_size, int log_degree); -void bls12_381_polynomial_internal_ifft_inplace(blst_fr *coefficients, +void bls12_381_polynomial_ifft_inplace(blst_fr *coefficients, blst_fr *domain, int log_domain_size); -void bls12_381_polynomial_internal_dft_inplace(blst_fr *coefficients, +void bls12_381_polynomial_dft_inplace(blst_fr *coefficients, blst_fr *domain, blst_fr *buffer, int length, int inverse); -void bls12_381_polynomial_internal_prime_factor_algorithm_fft( +void bls12_381_polynomial_prime_factor_algorithm_fft( blst_fr *coefficients, blst_fr *domain1, blst_fr *domain2, int length1, int length2, int inverse); -void bls12_381_polynomial_internal_fft_g1_inplace(blst_p1 *coefficients, +void bls12_381_polynomial_fft_g1_inplace(blst_p1 *coefficients, blst_fr *domain, int log_domain_size, int log_degree); -void bls12_381_polynomial_internal_ifft_g1_inplace(blst_p1 *coefficients, +void bls12_381_polynomial_ifft_g1_inplace(blst_p1 *coefficients, blst_fr *domain, int log_domain_size); -void bls12_381_polynomial_internal_fft_g2_inplace(blst_p2 *coefficients, +void bls12_381_polynomial_fft_g2_inplace(blst_p2 *coefficients, blst_fr *domain, int log_domain_size, int log_degree); -void bls12_381_polynomial_internal_ifft_g2_inplace(blst_p2 *coefficients, +void bls12_381_polynomial_ifft_g2_inplace(blst_p2 *coefficients, blst_fr *domain, int log_domain_size); #endif diff --git a/src/lib_bls12_381_polynomial/bls12_381_polynomial_internal_polynomial.c b/src/lib_bls12_381_polynomial/bls12_381_polynomial_polynomial.c similarity index 88% rename from src/lib_bls12_381_polynomial/bls12_381_polynomial_internal_polynomial.c rename to src/lib_bls12_381_polynomial/bls12_381_polynomial_polynomial.c index dbca5a456d78..17314ef51c9f 100644 --- a/src/lib_bls12_381_polynomial/bls12_381_polynomial_internal_polynomial.c +++ b/src/lib_bls12_381_polynomial/bls12_381_polynomial_polynomial.c @@ -20,10 +20,10 @@ * SOFTWARE. */ -#include "bls12_381_polynomial_internal_polynomial.h" +#include "bls12_381_polynomial_polynomial.h" #include -void bls12_381_polynomial_internal_polynomial_add(blst_fr *res, blst_fr *poly_1, +void bls12_381_polynomial_polynomial_add(blst_fr *res, blst_fr *poly_1, blst_fr *poly_2, const int size_1, const int size_2) { @@ -44,7 +44,7 @@ void bls12_381_polynomial_internal_polynomial_add(blst_fr *res, blst_fr *poly_1, } } -void bls12_381_polynomial_internal_polynomial_sub(blst_fr *res, blst_fr *poly_1, +void bls12_381_polynomial_polynomial_sub(blst_fr *res, blst_fr *poly_1, blst_fr *poly_2, const int size_1, const int size_2) { @@ -65,7 +65,7 @@ void bls12_381_polynomial_internal_polynomial_sub(blst_fr *res, blst_fr *poly_1, } } -void bls12_381_polynomial_internal_polynomial_mul(blst_fr *res, +void bls12_381_polynomial_polynomial_mul(blst_fr *res, const blst_fr *poly_1, const blst_fr *poly_2, const int size_1, @@ -79,7 +79,7 @@ void bls12_381_polynomial_internal_polynomial_mul(blst_fr *res, } } -void bls12_381_polynomial_internal_polynomial_mul_by_scalar(blst_fr *res, +void bls12_381_polynomial_polynomial_mul_by_scalar(blst_fr *res, blst_fr *scalar, blst_fr *arg, int size) { @@ -89,7 +89,7 @@ void bls12_381_polynomial_internal_polynomial_mul_by_scalar(blst_fr *res, } // res is initialized with blst-fr zeros -void bls12_381_polynomial_internal_polynomial_linear(blst_fr *res, +void bls12_381_polynomial_polynomial_linear(blst_fr *res, blst_fr **polynomials, int *polynomials_len, blst_fr *linear_coeffs, @@ -114,7 +114,7 @@ void bls12_381_polynomial_internal_polynomial_linear(blst_fr *res, // res is initialized with blst-fr zeros // p_0 + s * p_1 + s^2 * p_2 + ... + s^n * p_n = // (..((p_n * s) + p_{n-1}) * s + .. + p_1) * s + p_0 -void bls12_381_polynomial_internal_polynomial_linear_with_powers_horner( +void bls12_381_polynomial_polynomial_linear_with_powers_horner( blst_fr *res, blst_fr **polynomials, int *polynomials_len, blst_fr *linear_coeff, int nb_polys) { int poly_len_j; @@ -140,7 +140,7 @@ void bls12_381_polynomial_internal_polynomial_linear_with_powers_horner( // res is initialized with blst-fr zeros // p_0 + s * p_1 + s^2 * p_2 + ... + s^n * p_n -void bls12_381_polynomial_internal_polynomial_linear_with_powers_naive( +void bls12_381_polynomial_polynomial_linear_with_powers_naive( blst_fr *res, blst_fr **polynomials, int *polynomials_len, blst_fr *linear_coeff, int nb_polys) { int poly_len_j; @@ -163,7 +163,7 @@ void bls12_381_polynomial_internal_polynomial_linear_with_powers_naive( } } -void bls12_381_polynomial_internal_polynomial_linear_with_powers( +void bls12_381_polynomial_polynomial_linear_with_powers( blst_fr *res, blst_fr **polynomials, int *polynomials_len, blst_fr *linear_coeff, int nb_polys) { @@ -178,22 +178,22 @@ void bls12_381_polynomial_internal_polynomial_linear_with_powers( } if (max_len != min_len) { - bls12_381_polynomial_internal_polynomial_linear_with_powers_naive( + bls12_381_polynomial_polynomial_linear_with_powers_naive( res, polynomials, polynomials_len, linear_coeff, nb_polys); } else { - bls12_381_polynomial_internal_polynomial_linear_with_powers_horner( + bls12_381_polynomial_polynomial_linear_with_powers_horner( res, polynomials, polynomials_len, linear_coeff, nb_polys); } } -void bls12_381_polynomial_internal_polynomial_negate(blst_fr *res, blst_fr *arg, +void bls12_381_polynomial_polynomial_negate(blst_fr *res, blst_fr *arg, int size) { for (int i = 0; i < size; i++) { blst_fr_cneg(res + i, arg + i, 1); }; } -void bls12_381_polynomial_internal_polynomial_evaluate(blst_fr *res, +void bls12_381_polynomial_polynomial_evaluate(blst_fr *res, const blst_fr *arg, const int size, const blst_fr *scalar) { @@ -205,7 +205,7 @@ void bls12_381_polynomial_internal_polynomial_evaluate(blst_fr *res, } // poly / (X^n + 1), size > n -void bls12_381_polynomial_internal_polynomial_division_xn_one( +void bls12_381_polynomial_polynomial_division_xn_one( blst_fr *res_q, blst_fr *res_r, const blst_fr *poly, const int size, const int n) { @@ -239,7 +239,7 @@ void bls12_381_polynomial_internal_polynomial_division_xn_one( } // poly / (X^n - 1), size > n -void bls12_381_polynomial_internal_polynomial_division_xn_minus_one( +void bls12_381_polynomial_polynomial_division_xn_minus_one( blst_fr *res_q, blst_fr *res_r, const blst_fr *poly, const int size, const int n) { @@ -273,7 +273,7 @@ void bls12_381_polynomial_internal_polynomial_division_xn_minus_one( } // poly / (X^n + scalar), size > n -void bls12_381_polynomial_internal_polynomial_division_xn( +void bls12_381_polynomial_polynomial_division_xn( blst_fr *res_q, blst_fr *res_r, const blst_fr *poly, const int size, const int n, const blst_fr *scalar) { @@ -282,13 +282,13 @@ void bls12_381_polynomial_internal_polynomial_division_xn( blst_fr_cneg(&minus_one, &minus_one, 1); if (blst_fr_is_equal(scalar, &minus_one)) { - bls12_381_polynomial_internal_polynomial_division_xn_minus_one( + bls12_381_polynomial_polynomial_division_xn_minus_one( res_q, res_r, poly, size, n); return; }; if (blst_fr_is_one(scalar)) { - bls12_381_polynomial_internal_polynomial_division_xn_one(res_q, res_r, poly, + bls12_381_polynomial_polynomial_division_xn_one(res_q, res_r, poly, size, n); return; }; @@ -328,7 +328,7 @@ void bls12_381_polynomial_internal_polynomial_division_xn( // poly * (X^n + 1) // res is initialized with blst-fr zeros -void bls12_381_polynomial_internal_polynomial_mul_xn_one(blst_fr *res, +void bls12_381_polynomial_polynomial_mul_xn_one(blst_fr *res, const blst_fr *poly, const int size, const int n) { @@ -358,7 +358,7 @@ void bls12_381_polynomial_internal_polynomial_mul_xn_one(blst_fr *res, // poly * (X^n - 1) // res is initialized with blst-fr zeros -void bls12_381_polynomial_internal_polynomial_mul_xn_minus_one( +void bls12_381_polynomial_polynomial_mul_xn_minus_one( blst_fr *res, const blst_fr *poly, const int size, const int n) { if (size >= n) { @@ -386,7 +386,7 @@ void bls12_381_polynomial_internal_polynomial_mul_xn_minus_one( // poly * (X^n + scalar) // res is initialized with blst-fr zeros -void bls12_381_polynomial_internal_polynomial_mul_xn(blst_fr *res, +void bls12_381_polynomial_polynomial_mul_xn(blst_fr *res, const blst_fr *poly, const int size, const int n, @@ -397,13 +397,13 @@ void bls12_381_polynomial_internal_polynomial_mul_xn(blst_fr *res, blst_fr_cneg(&minus_one, &minus_one, 1); if (blst_fr_is_equal(scalar, &minus_one)) { - bls12_381_polynomial_internal_polynomial_mul_xn_minus_one(res, poly, size, + bls12_381_polynomial_polynomial_mul_xn_minus_one(res, poly, size, n); return; }; if (blst_fr_is_one(scalar)) { - bls12_381_polynomial_internal_polynomial_mul_xn_one(res, poly, size, n); + bls12_381_polynomial_polynomial_mul_xn_one(res, poly, size, n); return; }; @@ -432,7 +432,7 @@ void bls12_381_polynomial_internal_polynomial_mul_xn(blst_fr *res, } } -void bls12_381_polynomial_internal_polynomial_evaluations_add( +void bls12_381_polynomial_polynomial_evaluations_add( blst_fr *res, blst_fr *eval_1, blst_fr *eval_2, int size_1, int size_2) { int size_res = size_2 >= size_1 ? size_1 : size_2; int step1 = size_1 / size_res; @@ -443,7 +443,7 @@ void bls12_381_polynomial_internal_polynomial_evaluations_add( }; } -void bls12_381_polynomial_internal_polynomial_evaluations_rescale( +void bls12_381_polynomial_polynomial_evaluations_rescale( blst_fr *res, blst_fr *eval, int size_res, int size_eval) { int step = size_eval / size_res; @@ -452,7 +452,7 @@ void bls12_381_polynomial_internal_polynomial_evaluations_rescale( }; } -void bls12_381_polynomial_internal_polynomial_evaluations_mul_arrays( +void bls12_381_polynomial_polynomial_evaluations_mul_arrays( blst_fr *res, blst_fr **evaluations, int *evaluations_len, int *composition_gx, byte **powers, int *powers_numbits, int size_res, int nb_evals) { @@ -487,7 +487,7 @@ void bls12_381_polynomial_internal_polynomial_evaluations_mul_arrays( } } -void bls12_381_polynomial_internal_polynomial_evaluations_linear_arrays( +void bls12_381_polynomial_polynomial_evaluations_linear_arrays( blst_fr *res, blst_fr **evaluations, int *evaluations_len, blst_fr *linear_coeffs, int *composition_gx, blst_fr *add_constant, int size_res, int nb_evals) { @@ -533,7 +533,7 @@ void bls12_381_polynomial_internal_polynomial_evaluations_linear_arrays( } } -void bls12_381_polynomial_internal_polynomial_derivative(blst_fr *res, +void bls12_381_polynomial_polynomial_derivative(blst_fr *res, blst_fr *poly, const int size) { blst_fr scalar; diff --git a/src/lib_bls12_381_polynomial/bls12_381_polynomial_internal_polynomial.h b/src/lib_bls12_381_polynomial/bls12_381_polynomial_polynomial.h similarity index 75% rename from src/lib_bls12_381_polynomial/bls12_381_polynomial_internal_polynomial.h rename to src/lib_bls12_381_polynomial/bls12_381_polynomial_polynomial.h index 196299cf1cd6..d367180bd3f3 100644 --- a/src/lib_bls12_381_polynomial/bls12_381_polynomial_internal_polynomial.h +++ b/src/lib_bls12_381_polynomial/bls12_381_polynomial_polynomial.h @@ -30,78 +30,78 @@ #include #include -int bls12_381_polynomial_internal_polynomial_degree(blst_fr *arg, const int n); +int bls12_381_polynomial_polynomial_degree(blst_fr *arg, const int n); -bool bls12_381_polynomial_internal_polynomial_eq(blst_fr *poly_1, +bool bls12_381_polynomial_polynomial_eq(blst_fr *poly_1, blst_fr *poly_2, int size_1, int size_2); -void bls12_381_polynomial_internal_polynomial_add(blst_fr *res, blst_fr *arg_1, +void bls12_381_polynomial_polynomial_add(blst_fr *res, blst_fr *arg_1, blst_fr *arg_2, int size_1, int size_2); -void bls12_381_polynomial_internal_polynomial_sub(blst_fr *res, blst_fr *arg_1, +void bls12_381_polynomial_polynomial_sub(blst_fr *res, blst_fr *arg_1, blst_fr *arg_2, int size_1, int size_2); -void bls12_381_polynomial_internal_polynomial_mul(blst_fr *res, +void bls12_381_polynomial_polynomial_mul(blst_fr *res, const blst_fr *arg_1, const blst_fr *arg_2, const int size_1, const int size_2); -void bls12_381_polynomial_internal_polynomial_mul_by_scalar(blst_fr *res, +void bls12_381_polynomial_polynomial_mul_by_scalar(blst_fr *res, blst_fr *scalar, blst_fr *arg, int size); -void bls12_381_polynomial_internal_polynomial_linear(blst_fr *res, +void bls12_381_polynomial_polynomial_linear(blst_fr *res, blst_fr **polynomials, int *polynomials_len, blst_fr *linear_coeffs, int nb_polys); -void bls12_381_polynomial_internal_polynomial_linear_with_powers( +void bls12_381_polynomial_polynomial_linear_with_powers( blst_fr *res, blst_fr **polynomials, int *polynomials_len, blst_fr *linear_coeff, int nb_polys); -void bls12_381_polynomial_internal_polynomial_negate(blst_fr *res, blst_fr *arg, +void bls12_381_polynomial_polynomial_negate(blst_fr *res, blst_fr *arg, int size); -bool bls12_381_polynomial_internal_polynomial_is_zero(blst_fr *poly, int size); +bool bls12_381_polynomial_polynomial_is_zero(blst_fr *poly, int size); -void bls12_381_polynomial_internal_polynomial_evaluate(blst_fr *res, +void bls12_381_polynomial_polynomial_evaluate(blst_fr *res, const blst_fr *arg, const int size, const blst_fr *scalar); -void bls12_381_polynomial_internal_polynomial_division_xn( +void bls12_381_polynomial_polynomial_division_xn( blst_fr *res_q, blst_fr *res_r, const blst_fr *poly, int size, int n, const blst_fr *scalar); -void bls12_381_polynomial_internal_polynomial_mul_xn(blst_fr *res, +void bls12_381_polynomial_polynomial_mul_xn(blst_fr *res, const blst_fr *poly, const int size, const int n, const blst_fr *scalar); -void bls12_381_polynomial_internal_polynomial_evaluations_add( +void bls12_381_polynomial_polynomial_evaluations_add( blst_fr *res, blst_fr *eval_1, blst_fr *eval_2, int size_1, int size_2); -void bls12_381_polynomial_internal_polynomial_evaluations_rescale( +void bls12_381_polynomial_polynomial_evaluations_rescale( blst_fr *res, blst_fr *eval, int size_res, int size_eval); -void bls12_381_polynomial_internal_polynomial_evaluations_mul_arrays( +void bls12_381_polynomial_polynomial_evaluations_mul_arrays( blst_fr *res, blst_fr **evaluations, int *evaluations_len, int *composition_gx, byte **powers, int *powers_numbits, int size_res, int nb_evals); -void bls12_381_polynomial_internal_polynomial_evaluations_linear_arrays( +void bls12_381_polynomial_polynomial_evaluations_linear_arrays( blst_fr *res, blst_fr **evaluations, int *evaluations_len, blst_fr *linear_coeffs, int *composition_gx, blst_fr *add_constant, int size_res, int nb_evals); -void bls12_381_polynomial_internal_polynomial_derivative(blst_fr *res, +void bls12_381_polynomial_polynomial_derivative(blst_fr *res, blst_fr *poly, const int size); #endif diff --git a/src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_internal_ec_array_stubs.c b/src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_ec_array_stubs.c similarity index 92% rename from src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_internal_ec_array_stubs.c rename to src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_ec_array_stubs.c index 517d99ec68b6..51024580aea1 100644 --- a/src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_internal_ec_array_stubs.c +++ b/src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_ec_array_stubs.c @@ -26,7 +26,7 @@ #include #include -CAMLprim value caml_bls12_381_polynomial_internal_carray_g1_add_inplace_stubs( +CAMLprim value caml_bls12_381_polynomial_carray_g1_add_inplace_stubs( value carray_g1_1, value carray_g1_2, value size) { CAMLparam3(carray_g1_1, carray_g1_2, size); blst_p1 *carray_g1_1_c = Caml_ba_data_val(carray_g1_1); @@ -40,7 +40,7 @@ CAMLprim value caml_bls12_381_polynomial_internal_carray_g1_add_inplace_stubs( CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_carray_g2_add_inplace_stubs( +CAMLprim value caml_bls12_381_polynomial_carray_g2_add_inplace_stubs( value carray_g2_1, value carray_g2_2, value size) { CAMLparam3(carray_g2_1, carray_g2_2, size); blst_p2 *carray_g2_1_c = Caml_ba_data_val(carray_g2_1); @@ -55,7 +55,7 @@ CAMLprim value caml_bls12_381_polynomial_internal_carray_g2_add_inplace_stubs( } CAMLprim value -caml_bls12_381_polynomial_internal_evaluations_mul_arrays_g1_stubs( +caml_bls12_381_polynomial_evaluations_mul_arrays_g1_stubs( value res, value evaluations, value g1_arrays, value array_dimensions) { CAMLparam4(res, evaluations, array_dimensions, g1_arrays); int size_arrays_c = Int_val(Field(array_dimensions, 0)); @@ -79,7 +79,7 @@ caml_bls12_381_polynomial_internal_evaluations_mul_arrays_g1_stubs( } CAMLprim value -caml_bls12_381_polynomial_internal_evaluations_mul_arrays_g2_stubs( +caml_bls12_381_polynomial_evaluations_mul_arrays_g2_stubs( value res, value evaluations, value g2_arrays, value array_dimensions) { CAMLparam4(res, evaluations, array_dimensions, g2_arrays); int size_arrays_c = Int_val(Field(array_dimensions, 0)); diff --git a/src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_internal_fft_stubs.c b/src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_fft_stubs.c similarity index 81% rename from src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_internal_fft_stubs.c rename to src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_fft_stubs.c index 60993c31dfea..2ae3114eae0e 100644 --- a/src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_internal_fft_stubs.c +++ b/src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_fft_stubs.c @@ -20,7 +20,7 @@ * SOFTWARE. */ -#include "bls12_381_polynomial_internal_fft.h" +#include "bls12_381_polynomial_fft.h" #include "caml_bls12_381_stubs.h" #include #include @@ -31,7 +31,7 @@ #define Blst_g1_array_val(v) ((blst_p1 *)Caml_ba_data_val(v)) #define Blst_g2_array_val(v) ((blst_p2 *)Caml_ba_data_val(v)) -CAMLprim value caml_bls12_381_polynomial_internal_fft_inplace_on_stubs( +CAMLprim value caml_bls12_381_polynomial_fft_inplace_on_stubs( value coefficients, value domain, value log_domain_size, value log_degree) { CAMLparam4(coefficients, domain, log_domain_size, log_degree); @@ -39,25 +39,25 @@ CAMLprim value caml_bls12_381_polynomial_internal_fft_inplace_on_stubs( int log_degree_c = Int_val(log_degree); blst_fr *domain_c = Blst_fr_array_val(domain); blst_fr *coefficients_c = Blst_fr_array_val(coefficients); - bls12_381_polynomial_internal_fft_inplace(coefficients_c, domain_c, + bls12_381_polynomial_fft_inplace(coefficients_c, domain_c, log_domain_size_c, log_degree_c); CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_ifft_inplace_on_stubs( +CAMLprim value caml_bls12_381_polynomial_ifft_inplace_on_stubs( value coefficients, value domain, value log_domain_size) { CAMLparam3(coefficients, domain, log_domain_size); int log_domain_size_c = Int_val(log_domain_size); blst_fr *domain_c = Blst_fr_array_val(domain); blst_fr *coefficients_c = Blst_fr_array_val(coefficients); - bls12_381_polynomial_internal_ifft_inplace(coefficients_c, domain_c, + bls12_381_polynomial_ifft_inplace(coefficients_c, domain_c, log_domain_size_c); CAMLreturn(Val_unit); } CAMLprim value -caml_bls12_381_polynomial_internal_prime_factor_algorithm_fft_stubs( +caml_bls12_381_polynomial_prime_factor_algorithm_fft_stubs( value coefficients, value domain1_length1, value domain2_length2, value inverse) { CAMLparam4(inverse, domain1_length1, domain2_length2, coefficients); @@ -68,12 +68,12 @@ caml_bls12_381_polynomial_internal_prime_factor_algorithm_fft_stubs( bool inverse_c = Bool_val(inverse); blst_fr *coefficients_c = Blst_fr_array_val(coefficients); - bls12_381_polynomial_internal_prime_factor_algorithm_fft( + bls12_381_polynomial_prime_factor_algorithm_fft( coefficients_c, domain1_c, domain2_c, length1_c, length2_c, inverse_c); CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_dft_stubs(value coefficients, +CAMLprim value caml_bls12_381_polynomial_dft_stubs(value coefficients, value domain, value inverse, value length) { @@ -81,12 +81,12 @@ CAMLprim value caml_bls12_381_polynomial_internal_dft_stubs(value coefficients, blst_fr *coefficients_c = Blst_fr_array_val(coefficients); blst_fr *domain_c = Blst_fr_array_val(domain); blst_fr buffer_dft[length]; - bls12_381_polynomial_internal_dft_inplace( + bls12_381_polynomial_dft_inplace( coefficients_c, domain_c, buffer_dft, Int_val(length), Bool_val(inverse)); CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_fft_g1_inplace_on_stubs( +CAMLprim value caml_bls12_381_polynomial_fft_g1_inplace_on_stubs( value coefficients, value domain, value log_domain_size, value log_degree) { CAMLparam4(coefficients, domain, log_domain_size, log_degree); @@ -94,24 +94,24 @@ CAMLprim value caml_bls12_381_polynomial_internal_fft_g1_inplace_on_stubs( int log_degree_c = Int_val(log_degree); blst_fr *domain_c = Blst_fr_array_val(domain); blst_p1 *coefficients_c = Blst_g1_array_val(coefficients); - bls12_381_polynomial_internal_fft_g1_inplace(coefficients_c, domain_c, + bls12_381_polynomial_fft_g1_inplace(coefficients_c, domain_c, log_domain_size_c, log_degree_c); CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_ifft_g1_inplace_on_stubs( +CAMLprim value caml_bls12_381_polynomial_ifft_g1_inplace_on_stubs( value coefficients, value domain, value log_domain_size) { CAMLparam3(coefficients, domain, log_domain_size); int log_domain_size_c = Int_val(log_domain_size); blst_fr *domain_c = Blst_fr_array_val(domain); blst_p1 *coefficients_c = Blst_g1_array_val(coefficients); - bls12_381_polynomial_internal_ifft_g1_inplace(coefficients_c, domain_c, + bls12_381_polynomial_ifft_g1_inplace(coefficients_c, domain_c, log_domain_size_c); CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_fft_g2_inplace_on_stubs( +CAMLprim value caml_bls12_381_polynomial_fft_g2_inplace_on_stubs( value coefficients, value domain, value log_domain_size, value log_degree) { CAMLparam4(coefficients, domain, log_domain_size, log_degree); @@ -119,19 +119,19 @@ CAMLprim value caml_bls12_381_polynomial_internal_fft_g2_inplace_on_stubs( int log_degree_c = Int_val(log_degree); blst_fr *domain_c = Blst_fr_array_val(domain); blst_p2 *coefficients_c = Blst_g2_array_val(coefficients); - bls12_381_polynomial_internal_fft_g2_inplace(coefficients_c, domain_c, + bls12_381_polynomial_fft_g2_inplace(coefficients_c, domain_c, log_domain_size_c, log_degree_c); CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_ifft_g2_inplace_on_stubs( +CAMLprim value caml_bls12_381_polynomial_ifft_g2_inplace_on_stubs( value coefficients, value domain, value log_domain_size) { CAMLparam3(coefficients, domain, log_domain_size); int log_domain_size_c = Int_val(log_domain_size); blst_fr *domain_c = Blst_fr_array_val(domain); blst_p2 *coefficients_c = Blst_g2_array_val(coefficients); - bls12_381_polynomial_internal_ifft_g2_inplace(coefficients_c, domain_c, + bls12_381_polynomial_ifft_g2_inplace(coefficients_c, domain_c, log_domain_size_c); CAMLreturn(Val_unit); } diff --git a/src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_internal_polynomial_stubs.c b/src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_polynomial_stubs.c similarity index 80% rename from src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_internal_polynomial_stubs.c rename to src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_polynomial_stubs.c index 2288894d33cd..b9119ddca253 100644 --- a/src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_internal_polynomial_stubs.c +++ b/src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_polynomial_stubs.c @@ -20,7 +20,7 @@ * SOFTWARE. */ -#include "bls12_381_polynomial_internal_polynomial.h" +#include "bls12_381_polynomial_polynomial.h" #include "caml_bls12_381_stubs.h" #include "ocaml_integers.h" #include @@ -31,7 +31,7 @@ #define Blst_fr_array_val(v) ((blst_fr *)Caml_ba_data_val(v)) -CAMLprim value caml_bls12_381_polynomial_internal_polynomial_carray_get_stubs( +CAMLprim value caml_bls12_381_polynomial_polynomial_carray_get_stubs( value elt, value carray, value idx, value size) { CAMLparam4(elt, carray, idx, size); void *elt_c = Data_custom_val(elt); @@ -44,7 +44,7 @@ CAMLprim value caml_bls12_381_polynomial_internal_polynomial_carray_get_stubs( CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_polynomial_carray_set_stubs( +CAMLprim value caml_bls12_381_polynomial_polynomial_carray_set_stubs( value carray, value elt, value idx, value size) { CAMLparam4(elt, carray, idx, size); void *elt_c = Data_custom_val(elt); @@ -57,7 +57,7 @@ CAMLprim value caml_bls12_381_polynomial_internal_polynomial_carray_set_stubs( CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_polynomial_memset_zero_stubs( +CAMLprim value caml_bls12_381_polynomial_polynomial_memset_zero_stubs( value carray, value n) { CAMLparam2(carray, n); int n_c = Int_val(n); @@ -67,7 +67,7 @@ CAMLprim value caml_bls12_381_polynomial_internal_polynomial_memset_zero_stubs( } CAMLprim value -caml_bls12_381_polynomial_internal_polynomial_compute_domain_stubs( +caml_bls12_381_polynomial_polynomial_compute_domain_stubs( value buffer, value n, value root_of_unity) { CAMLparam3(buffer, n, root_of_unity); blst_fr *root_of_unity_c = Blst_fr_val(root_of_unity); @@ -89,7 +89,7 @@ caml_bls12_381_polynomial_internal_polynomial_compute_domain_stubs( CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_polynomial_of_sparse_stubs( +CAMLprim value caml_bls12_381_polynomial_polynomial_of_sparse_stubs( value polynomial, value coefficients, value nb_coefficients) { CAMLparam3(polynomial, coefficients, nb_coefficients); @@ -108,7 +108,7 @@ CAMLprim value caml_bls12_381_polynomial_internal_polynomial_of_sparse_stubs( CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_polynomial_add_stubs( +CAMLprim value caml_bls12_381_polynomial_polynomial_add_stubs( value res, value arg_1, value arg_2, value size_1, value size_2) { CAMLparam5(res, arg_1, arg_2, size_1, size_2); blst_fr *arg_1_c = Blst_fr_array_val(arg_1); @@ -117,12 +117,12 @@ CAMLprim value caml_bls12_381_polynomial_internal_polynomial_add_stubs( int size_1_c = Int_val(size_1); int size_2_c = Int_val(size_2); - bls12_381_polynomial_internal_polynomial_add(res_c, arg_1_c, arg_2_c, + bls12_381_polynomial_polynomial_add(res_c, arg_1_c, arg_2_c, size_1_c, size_2_c); CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_polynomial_sub_stubs( +CAMLprim value caml_bls12_381_polynomial_polynomial_sub_stubs( value res, value arg_1, value arg_2, value size_1, value size_2) { CAMLparam5(res, arg_1, arg_2, size_1, size_2); blst_fr *arg_1_c = Blst_fr_array_val(arg_1); @@ -131,12 +131,12 @@ CAMLprim value caml_bls12_381_polynomial_internal_polynomial_sub_stubs( int size_1_c = Int_val(size_1); int size_2_c = Int_val(size_2); - bls12_381_polynomial_internal_polynomial_sub(res_c, arg_1_c, arg_2_c, + bls12_381_polynomial_polynomial_sub(res_c, arg_1_c, arg_2_c, size_1_c, size_2_c); CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_polynomial_mul_stubs( +CAMLprim value caml_bls12_381_polynomial_polynomial_mul_stubs( value res, value arg_1, value arg_2, value size_1, value size_2) { CAMLparam5(res, arg_1, arg_2, size_1, size_2); blst_fr *arg_1_c = Blst_fr_array_val(arg_1); @@ -145,13 +145,13 @@ CAMLprim value caml_bls12_381_polynomial_internal_polynomial_mul_stubs( int size_1_c = Int_val(size_1); int size_2_c = Int_val(size_2); - bls12_381_polynomial_internal_polynomial_mul(res_c, arg_1_c, arg_2_c, + bls12_381_polynomial_polynomial_mul(res_c, arg_1_c, arg_2_c, size_1_c, size_2_c); CAMLreturn(Val_unit); } CAMLprim value -caml_bls12_381_polynomial_internal_polynomial_mul_by_scalar_stubs(value res, +caml_bls12_381_polynomial_polynomial_mul_by_scalar_stubs(value res, value scalar, value arg, value size) { @@ -161,12 +161,12 @@ caml_bls12_381_polynomial_internal_polynomial_mul_by_scalar_stubs(value res, blst_fr *arg_c = Blst_fr_array_val(arg); int size_c = Int_val(size); - bls12_381_polynomial_internal_polynomial_mul_by_scalar(res_c, scalar_c, arg_c, + bls12_381_polynomial_polynomial_mul_by_scalar(res_c, scalar_c, arg_c, size_c); CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_polynomial_linear_stubs( +CAMLprim value caml_bls12_381_polynomial_polynomial_linear_stubs( value res, value poly_polylen_coeff, value nb_polys) { CAMLparam3(res, poly_polylen_coeff, nb_polys); blst_fr *res_c = Blst_fr_array_val(res); @@ -186,13 +186,13 @@ CAMLprim value caml_bls12_381_polynomial_internal_polynomial_linear_stubs( memcpy(linear_coeffs_c + i, c, sizeof(blst_fr)); } - bls12_381_polynomial_internal_polynomial_linear(res_c, polys_c, polys_len_c, + bls12_381_polynomial_polynomial_linear(res_c, polys_c, polys_len_c, linear_coeffs_c, nb_polys_c); CAMLreturn(Val_unit); } CAMLprim value -caml_bls12_381_polynomial_internal_polynomial_linear_with_powers_stubs( +caml_bls12_381_polynomial_polynomial_linear_with_powers_stubs( value res, value coeff, value poly_polylen, value nb_polys) { CAMLparam4(res, coeff, poly_polylen, nb_polys); blst_fr *res_c = Blst_fr_array_val(res); @@ -209,23 +209,23 @@ caml_bls12_381_polynomial_internal_polynomial_linear_with_powers_stubs( polys_len_c[i] = Int_val(Field(idx_i, 1)); } - bls12_381_polynomial_internal_polynomial_linear_with_powers( + bls12_381_polynomial_polynomial_linear_with_powers( res_c, polys_c, polys_len_c, coeff_c, nb_polys_c); CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_polynomial_negate_stubs( +CAMLprim value caml_bls12_381_polynomial_polynomial_negate_stubs( value res, value arg, value size) { CAMLparam3(res, arg, size); blst_fr *res_c = Blst_fr_array_val(res); blst_fr *arg_c = Blst_fr_array_val(arg); int size_c = Int_val(size); - bls12_381_polynomial_internal_polynomial_negate(res_c, arg_c, size_c); + bls12_381_polynomial_polynomial_negate(res_c, arg_c, size_c); CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_polynomial_evaluate_stubs( +CAMLprim value caml_bls12_381_polynomial_polynomial_evaluate_stubs( value res, value arg, value size, value scalar) { CAMLparam4(res, arg, size, scalar); blst_fr *res_c = Blst_fr_val(res); @@ -233,12 +233,12 @@ CAMLprim value caml_bls12_381_polynomial_internal_polynomial_evaluate_stubs( int size_c = Int_val(size); blst_fr *scalar_c = Blst_fr_val(scalar); - bls12_381_polynomial_internal_polynomial_evaluate(res_c, arg_c, size_c, + bls12_381_polynomial_polynomial_evaluate(res_c, arg_c, size_c, scalar_c); CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_polynomial_division_xn_stubs( +CAMLprim value caml_bls12_381_polynomial_polynomial_division_xn_stubs( value res_q, value res_r, value poly, value size, value n_and_scalar) { CAMLparam5(res_q, res_r, poly, size, n_and_scalar); blst_fr *poly_c = Blst_fr_array_val(poly); @@ -247,12 +247,12 @@ CAMLprim value caml_bls12_381_polynomial_internal_polynomial_division_xn_stubs( int size_c = Int_val(size); int n_c = Int_val(Field(n_and_scalar, 0)); blst_fr *scalar_c = Blst_fr_val(Field(n_and_scalar, 1)); - bls12_381_polynomial_internal_polynomial_division_xn(res_q_c, res_r_c, poly_c, + bls12_381_polynomial_polynomial_division_xn(res_q_c, res_r_c, poly_c, size_c, n_c, scalar_c); CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_polynomial_mul_xn_stubs( +CAMLprim value caml_bls12_381_polynomial_polynomial_mul_xn_stubs( value res, value poly, value size, value n, value scalar) { CAMLparam4(res, poly, size, n); blst_fr *poly_c = Blst_fr_array_val(poly); @@ -260,7 +260,7 @@ CAMLprim value caml_bls12_381_polynomial_internal_polynomial_mul_xn_stubs( int size_c = Int_val(size); int n_c = Int_val(n); blst_fr *scalar_c = Blst_fr_val(scalar); - bls12_381_polynomial_internal_polynomial_mul_xn(res_c, poly_c, size_c, n_c, + bls12_381_polynomial_polynomial_mul_xn(res_c, poly_c, size_c, n_c, scalar_c); CAMLreturn(Val_unit); } @@ -268,7 +268,7 @@ CAMLprim value caml_bls12_381_polynomial_internal_polynomial_mul_xn_stubs( // Bindings for evaluations.ml CAMLprim value -caml_bls12_381_polynomial_internal_polynomial_evaluations_add_stubs( +caml_bls12_381_polynomial_polynomial_evaluations_add_stubs( value res, value eval_1, value eval_2, value size_1, value size_2) { CAMLparam5(res, eval_1, eval_2, size_1, size_2); blst_fr *res_c = Blst_fr_array_val(res); @@ -277,13 +277,13 @@ caml_bls12_381_polynomial_internal_polynomial_evaluations_add_stubs( int size_1_c = Int_val(size_1); int size_2_c = Int_val(size_2); - bls12_381_polynomial_internal_polynomial_evaluations_add( + bls12_381_polynomial_polynomial_evaluations_add( res_c, eval_1_c, eval_2_c, size_1_c, size_2_c); CAMLreturn(Val_unit); } CAMLprim value -caml_bls12_381_polynomial_internal_polynomial_evaluations_rescale_stubs( +caml_bls12_381_polynomial_polynomial_evaluations_rescale_stubs( value res, value eval, value size_res, value size_eval) { CAMLparam4(res, eval, size_res, size_eval); blst_fr *res_c = Blst_fr_array_val(res); @@ -291,13 +291,13 @@ caml_bls12_381_polynomial_internal_polynomial_evaluations_rescale_stubs( int size_res_c = Int_val(size_res); int size_eval_c = Int_val(size_eval); - bls12_381_polynomial_internal_polynomial_evaluations_rescale( + bls12_381_polynomial_polynomial_evaluations_rescale( res_c, eval_c, size_res_c, size_eval_c); CAMLreturn(Val_unit); } CAMLprim value -caml_bls12_381_polynomial_internal_polynomial_evaluations_mul_arrays_stubs( +caml_bls12_381_polynomial_polynomial_evaluations_mul_arrays_stubs( value res, value eval_evallen_comp_power_powlen, value size_res, value nb_evals) { CAMLparam4(res, eval_evallen_comp_power_powlen, size_res, nb_evals); @@ -321,14 +321,14 @@ caml_bls12_381_polynomial_internal_polynomial_evaluations_mul_arrays_stubs( powers_len_c[i] = Int_val(Field(idx_i, 4)); } - bls12_381_polynomial_internal_polynomial_evaluations_mul_arrays( + bls12_381_polynomial_polynomial_evaluations_mul_arrays( res_c, evaluations_c, evaluations_len_c, composition_gx_c, powers_c, powers_len_c, size_res_c, nb_evals_c); CAMLreturn(Val_unit); } CAMLprim value -caml_bls12_381_polynomial_internal_polynomial_evaluations_linear_arrays_stubs( +caml_bls12_381_polynomial_polynomial_evaluations_linear_arrays_stubs( value res, value eval_evallen_coeff_comp, value add_constant, value size_res, value nb_evals) { CAMLparam5(res, eval_evallen_coeff_comp, add_constant, size_res, nb_evals); @@ -353,18 +353,18 @@ caml_bls12_381_polynomial_internal_polynomial_evaluations_linear_arrays_stubs( composition_gx_c[i] = Int_val(Field(idx_i, 3)); } - bls12_381_polynomial_internal_polynomial_evaluations_linear_arrays( + bls12_381_polynomial_polynomial_evaluations_linear_arrays( res_c, evaluations_c, evaluations_len_c, linear_coeffs_c, composition_gx_c, add_constant_c, size_res_c, nb_evals_c); CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_polynomial_derivative_stubs( +CAMLprim value caml_bls12_381_polynomial_polynomial_derivative_stubs( value res, value poly, value size) { CAMLparam3(res, poly, size); blst_fr *poly_c = Blst_fr_array_val(poly); blst_fr *res_c = Blst_fr_array_val(res); int size_c = Int_val(size); - bls12_381_polynomial_internal_polynomial_derivative(res_c, poly_c, size_c); + bls12_381_polynomial_polynomial_derivative(res_c, poly_c, size_c); CAMLreturn(Val_unit); } diff --git a/src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_internal_srs_stubs.c b/src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_srs_stubs.c similarity index 94% rename from src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_internal_srs_stubs.c rename to src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_srs_stubs.c index 4dd78d8cdb86..a2e2b24c3027 100644 --- a/src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_internal_srs_stubs.c +++ b/src/lib_bls12_381_polynomial/caml_bls12_381_polynomial_srs_stubs.c @@ -13,7 +13,7 @@ #define Srs_val_g2(v) ((blst_p2_affine *)Caml_ba_data_val(v)) -CAMLprim value caml_bls12_381_polynomial_internal_srs_g1_pippenger_stubs( +CAMLprim value caml_bls12_381_polynomial_srs_g1_pippenger_stubs( value res, value srs, value poly, value start, value len) { CAMLparam5(res, srs, poly, start, len); int start_c = Int_val(start); @@ -51,7 +51,7 @@ CAMLprim value caml_bls12_381_polynomial_internal_srs_g1_pippenger_stubs( CAMLreturn(Val_unit); } -CAMLprim value caml_bls12_381_polynomial_internal_srs_g2_pippenger_stubs( +CAMLprim value caml_bls12_381_polynomial_srs_g2_pippenger_stubs( value res, value srs, value poly, value start, value len) { CAMLparam5(res, srs, poly, start, len); int start_c = Int_val(start); diff --git a/src/lib_bls12_381_polynomial/carray.ml b/src/lib_bls12_381_polynomial/carray.ml index 9c0df936a158..ceb86c4fdf9b 100644 --- a/src/lib_bls12_381_polynomial/carray.ml +++ b/src/lib_bls12_381_polynomial/carray.ml @@ -104,7 +104,7 @@ module Make (Elt : Elt_sig) : Carray_sig with type elt = Elt.t = struct - requires: [0 <= i < size p] - ensures: [elt = p[i]] *) external get : elt -> t -> int -> int -> unit - = "caml_bls12_381_polynomial_internal_polynomial_carray_get_stubs" + = "caml_bls12_381_polynomial_polynomial_carray_get_stubs" [@@noalloc] (** [set p elt i size] copies [elt] in the [i]-th element of [p], @@ -112,13 +112,13 @@ module Make (Elt : Elt_sig) : Carray_sig with type elt = Elt.t = struct - requires: [0 <= i < size p] - ensures: [elt = p[i]] *) external set : t -> elt -> int -> int -> unit - = "caml_bls12_381_polynomial_internal_polynomial_carray_set_stubs" + = "caml_bls12_381_polynomial_polynomial_carray_set_stubs" [@@noalloc] (** [memset_zero p n] writes [n] bytes of zeros in [p] - requires: [n <= size p] *) external memset_zero : t -> int -> unit - = "caml_bls12_381_polynomial_internal_polynomial_memset_zero_stubs" + = "caml_bls12_381_polynomial_polynomial_memset_zero_stubs" [@@noalloc] end diff --git a/src/lib_bls12_381_polynomial/domain.ml b/src/lib_bls12_381_polynomial/domain.ml index b2eb1ab8c53f..b96c3d2514cb 100644 --- a/src/lib_bls12_381_polynomial/domain.ml +++ b/src/lib_bls12_381_polynomial/domain.ml @@ -39,7 +39,7 @@ module Stubs = struct ensures: - [res[i] = g^i] for [i = 0..(n-1)] *) external compute_domain : fr_array -> int -> fr -> unit - = "caml_bls12_381_polynomial_internal_polynomial_compute_domain_stubs" + = "caml_bls12_381_polynomial_polynomial_compute_domain_stubs" [@@noalloc] (** [rescale res a size_res size_a] writes the result of rescaling the evaluation @@ -53,7 +53,7 @@ module Stubs = struct - [res] and [a] are disjoint - [size_res mod size_a = 0] *) external rescale : fr_array -> fr_array -> int -> int -> unit - = "caml_bls12_381_polynomial_internal_polynomial_evaluations_rescale_stubs" + = "caml_bls12_381_polynomial_polynomial_evaluations_rescale_stubs" [@@noalloc] end diff --git a/src/lib_bls12_381_polynomial/dune b/src/lib_bls12_381_polynomial/dune index 9b3a81358b0e..a5127f194009 100644 --- a/src/lib_bls12_381_polynomial/dune +++ b/src/lib_bls12_381_polynomial/dune @@ -2,8 +2,8 @@ ; Edit file manifest/main.ml instead. (library - (name tezos_bls12_381_polynomial_internal) - (public_name tezos-bls12-381-polynomial-internal) + (name octez_bls12_381_polynomial) + (public_name octez-bls12-381-polynomial) (instrumentation (backend bisect_ppx)) (libraries bls12-381 @@ -13,10 +13,10 @@ (foreign_stubs (language c) (names - caml_bls12_381_polynomial_internal_polynomial_stubs - caml_bls12_381_polynomial_internal_srs_stubs - caml_bls12_381_polynomial_internal_ec_array_stubs - caml_bls12_381_polynomial_internal_fft_stubs - bls12_381_polynomial_internal_polynomial - bls12_381_polynomial_internal_fft)) + caml_bls12_381_polynomial_polynomial_stubs + caml_bls12_381_polynomial_srs_stubs + caml_bls12_381_polynomial_ec_array_stubs + caml_bls12_381_polynomial_fft_stubs + bls12_381_polynomial_polynomial + bls12_381_polynomial_fft)) (c_library_flags (-Wall -Wextra :standard))) diff --git a/src/lib_bls12_381_polynomial/ec_carray.ml b/src/lib_bls12_381_polynomial/ec_carray.ml index 64fc9a7101dd..c0966783b51c 100644 --- a/src/lib_bls12_381_polynomial/ec_carray.ml +++ b/src/lib_bls12_381_polynomial/ec_carray.ml @@ -229,18 +229,18 @@ module Stubs_g1 = struct external evaluation_ecfft_inplace : ec_array -> domain:fr_array -> log:int -> log_degree:int -> unit - = "caml_bls12_381_polynomial_internal_fft_g1_inplace_on_stubs" + = "caml_bls12_381_polynomial_fft_g1_inplace_on_stubs" external interpolation_ecfft_inplace : ec_array -> domain:fr_array -> log:int -> unit - = "caml_bls12_381_polynomial_internal_ifft_g1_inplace_on_stubs" + = "caml_bls12_381_polynomial_ifft_g1_inplace_on_stubs" external add_arrays_inplace : ec_array -> ec_array -> int -> unit - = "caml_bls12_381_polynomial_internal_carray_g1_add_inplace_stubs" + = "caml_bls12_381_polynomial_carray_g1_add_inplace_stubs" external mul_arrays : ec_array array -> fr_array array -> ec_array array -> int * int -> unit - = "caml_bls12_381_polynomial_internal_evaluations_mul_arrays_g1_stubs" + = "caml_bls12_381_polynomial_evaluations_mul_arrays_g1_stubs" end module Stubs_g2 = struct @@ -250,18 +250,18 @@ module Stubs_g2 = struct external evaluation_ecfft_inplace : ec_array -> domain:fr_array -> log:int -> log_degree:int -> unit - = "caml_bls12_381_polynomial_internal_fft_g2_inplace_on_stubs" + = "caml_bls12_381_polynomial_fft_g2_inplace_on_stubs" external interpolation_ecfft_inplace : ec_array -> domain:fr_array -> log:int -> unit - = "caml_bls12_381_polynomial_internal_ifft_g2_inplace_on_stubs" + = "caml_bls12_381_polynomial_ifft_g2_inplace_on_stubs" external add_arrays_inplace : ec_array -> ec_array -> int -> unit - = "caml_bls12_381_polynomial_internal_carray_g2_add_inplace_stubs" + = "caml_bls12_381_polynomial_carray_g2_add_inplace_stubs" external mul_arrays : ec_array array -> fr_array array -> ec_array array -> int * int -> unit - = "caml_bls12_381_polynomial_internal_evaluations_mul_arrays_g2_stubs" + = "caml_bls12_381_polynomial_evaluations_mul_arrays_g2_stubs" end module G1_carray : diff --git a/src/lib_bls12_381_polynomial/evaluations.ml b/src/lib_bls12_381_polynomial/evaluations.ml index bad8c40d9a22..eed9eeff6fc4 100644 --- a/src/lib_bls12_381_polynomial/evaluations.ml +++ b/src/lib_bls12_381_polynomial/evaluations.ml @@ -42,7 +42,7 @@ module Stubs = struct - [res], [a] and [b] are either pairwise disjoint or equal - [size_b mod size_a = 0] *) external add : fr_array -> fr_array -> fr_array -> int -> int -> unit - = "caml_bls12_381_polynomial_internal_polynomial_evaluations_add_stubs" + = "caml_bls12_381_polynomial_polynomial_evaluations_add_stubs" [@@noalloc] (** [mul_arrays res eval_evallen_comp_power_powlen size_res nb_evals] writes @@ -68,8 +68,7 @@ module Stubs = struct (fr_array * int * int * Bytes.t * int) array -> int -> int -> - unit - = "caml_bls12_381_polynomial_internal_polynomial_evaluations_mul_arrays_stubs" + unit = "caml_bls12_381_polynomial_polynomial_evaluations_mul_arrays_stubs" [@@noalloc] (** [linear_arrays res eval_evallen_coeff_comp add_constant size_res nb_evals] @@ -91,7 +90,7 @@ module Stubs = struct - [res] and [p_i] are disjoint *) external linear_arrays : fr_array -> (fr_array * int * fr * int) array -> fr -> int -> int -> unit - = "caml_bls12_381_polynomial_internal_polynomial_evaluations_linear_arrays_stubs" + = "caml_bls12_381_polynomial_polynomial_evaluations_linear_arrays_stubs" [@@noalloc] (** [fft_inplace p domain log log_degree] computes Fast Fourier Transform. @@ -105,7 +104,7 @@ module Stubs = struct [n]-th root of unity and [n = 2^log] (as done by {!Domain.Stubs.compute_domain}) *) external fft_inplace : fr_array -> domain:fr_array -> log:int -> log_degree:int -> unit - = "caml_bls12_381_polynomial_internal_fft_inplace_on_stubs" + = "caml_bls12_381_polynomial_fft_inplace_on_stubs" (** [ifft_inplace p domain log] computes Inverse Fast Fourier Transform. It converts the evaluation representation of a polynomial [p] to @@ -117,7 +116,7 @@ module Stubs = struct - [domain = [one; g; ..; g^{n-1}]] where [g] is a primitive [n]-th root of unity and [n = 2^log] (as done by {!Domain.Stubs.compute_domain}) *) external ifft_inplace : fr_array -> domain:fr_array -> log:int -> unit - = "caml_bls12_381_polynomial_internal_ifft_inplace_on_stubs" + = "caml_bls12_381_polynomial_ifft_inplace_on_stubs" [@@noalloc] (** [dft_inplace coefficients domain inverse length] computes the Fourier Transform. @@ -130,7 +129,7 @@ module Stubs = struct - [domain = [one; g; ..; g^{n-1}]] where [g] is a primitive [n]-th root of unity (as done by {!Domain.Stubs.compute_domain}) *) external dft_inplace : fr_array -> fr_array -> bool -> int -> unit - = "caml_bls12_381_polynomial_internal_dft_stubs" + = "caml_bls12_381_polynomial_dft_stubs" [@@noalloc] (** [fft_prime_factor_algorithm_inplace coefficient (domain1, domain1_length) (domain2, domain2_length) inverse] @@ -149,7 +148,7 @@ module Stubs = struct [n]-th root of unity (as done by {!Domain.Stubs.compute_domain}) *) external fft_prime_factor_algorithm_inplace : fr_array -> fr_array * int -> fr_array * int -> bool -> unit - = "caml_bls12_381_polynomial_internal_prime_factor_algorithm_fft_stubs" + = "caml_bls12_381_polynomial_prime_factor_algorithm_fft_stubs" [@@noalloc] end diff --git a/src/lib_bls12_381_polynomial/polynomial.ml b/src/lib_bls12_381_polynomial/polynomial.ml index b30c0c8bc7d1..0ee867c250b5 100644 --- a/src/lib_bls12_381_polynomial/polynomial.ml +++ b/src/lib_bls12_381_polynomial/polynomial.ml @@ -40,7 +40,7 @@ module Stubs = struct - [size res = degree p + 1] - [size p = n] *) external of_sparse : fr_array -> (fr * int) array -> int -> unit - = "caml_bls12_381_polynomial_internal_polynomial_of_sparse_stubs" + = "caml_bls12_381_polynomial_polynomial_of_sparse_stubs" [@@noalloc] (** [add res a b size_a size_b] writes the result of polynomial addition of [a] and [b] @@ -52,7 +52,7 @@ module Stubs = struct - [size res = max (size_a, size_b)] - [res], [a] and [b] are either pairwise disjoint or equal *) external add : fr_array -> fr_array -> fr_array -> int -> int -> unit - = "caml_bls12_381_polynomial_internal_polynomial_add_stubs" + = "caml_bls12_381_polynomial_polynomial_add_stubs" [@@noalloc] (** [sub res a b size_a size_b] writes the result of polynomial subtraction of [b] from [a] @@ -64,7 +64,7 @@ module Stubs = struct - [size res = max (size_a, size_b)] - [res], [a] and [b] are either pairwise disjoint or equal *) external sub : fr_array -> fr_array -> fr_array -> int -> int -> unit - = "caml_bls12_381_polynomial_internal_polynomial_sub_stubs" + = "caml_bls12_381_polynomial_polynomial_sub_stubs" [@@noalloc] (** [mul res a b size_a size_b] writes the result of polynomial multiplication of [a] by [b] @@ -76,7 +76,7 @@ module Stubs = struct - [size b = size_b] - [size res = size_a + size_b - 1] *) external mul : fr_array -> fr_array -> fr_array -> int -> int -> unit - = "caml_bls12_381_polynomial_internal_polynomial_mul_stubs" + = "caml_bls12_381_polynomial_polynomial_mul_stubs" [@@noalloc] (** [mul_by_scalar res b a size_a] writes the result of multiplying a polynomial [a] @@ -87,7 +87,7 @@ module Stubs = struct - [size res = size_a] - [res] and [a] either disjoint or equal *) external mul_by_scalar : fr_array -> fr -> fr_array -> int -> unit - = "caml_bls12_381_polynomial_internal_polynomial_mul_by_scalar_stubs" + = "caml_bls12_381_polynomial_polynomial_mul_by_scalar_stubs" [@@noalloc] (** [linear res poly_polylen_coeff nb_polys] writes the result of @@ -101,7 +101,7 @@ module Stubs = struct - [size poly_polylen_coeff = nb_polys] - [size p_i = size_p_i] *) external linear : fr_array -> (fr_array * int * fr) array -> int -> unit - = "caml_bls12_381_polynomial_internal_polynomial_linear_stubs" + = "caml_bls12_381_polynomial_polynomial_linear_stubs" [@@noalloc] (** [linear_with_powers res c poly_polylen nb_polys] writes the result of @@ -116,7 +116,7 @@ module Stubs = struct - [size p_i = size_p_i] *) external linear_with_powers : fr_array -> fr -> (fr_array * int) array -> int -> unit - = "caml_bls12_381_polynomial_internal_polynomial_linear_with_powers_stubs" + = "caml_bls12_381_polynomial_polynomial_linear_with_powers_stubs" [@@noalloc] (** [negate res p n] writes the result of negating a polynomial [p] in [res] @@ -126,7 +126,7 @@ module Stubs = struct - [size res = n] - [res] and [p] either disjoint or equal *) external negate : fr_array -> fr_array -> int -> unit - = "caml_bls12_381_polynomial_internal_polynomial_negate_stubs" + = "caml_bls12_381_polynomial_polynomial_negate_stubs" [@@noalloc] (** [evaluate res p n x] writes the result of evaluating a polynomial [p] at [x] @@ -134,7 +134,7 @@ module Stubs = struct - requires: [size p = n] and [n > 0] *) external evaluate : fr -> fr_array -> int -> fr -> unit - = "caml_bls12_381_polynomial_internal_polynomial_evaluate_stubs" + = "caml_bls12_381_polynomial_polynomial_evaluate_stubs" [@@noalloc] (** [division_xn res_q res_r p size_p (n, c)] writes the quotient and remainder of @@ -146,7 +146,7 @@ module Stubs = struct - [size res_r = n] *) external division_xn : fr_array -> fr_array -> fr_array -> int -> int * fr -> unit - = "caml_bls12_381_polynomial_internal_polynomial_division_xn_stubs" + = "caml_bls12_381_polynomial_polynomial_division_xn_stubs" [@@noalloc] (** [mul_xn res p size_p n c] writes the result of multiplying a polynomial [p] @@ -157,11 +157,11 @@ module Stubs = struct - [size p = size_p] - [size res = size_p + n] *) external mul_xn : fr_array -> fr_array -> int -> int -> fr -> unit - = "caml_bls12_381_polynomial_internal_polynomial_mul_xn_stubs" + = "caml_bls12_381_polynomial_polynomial_mul_xn_stubs" [@@noalloc] external derivative : fr_array -> fr_array -> int -> unit - = "caml_bls12_381_polynomial_internal_polynomial_derivative_stubs" + = "caml_bls12_381_polynomial_polynomial_derivative_stubs" [@@noalloc] end diff --git a/src/lib_bls12_381_polynomial/srs.ml b/src/lib_bls12_381_polynomial/srs.ml index 8d489b19ddea..b2ef6984a785 100644 --- a/src/lib_bls12_381_polynomial/srs.ml +++ b/src/lib_bls12_381_polynomial/srs.ml @@ -208,7 +208,7 @@ module Elt_g1 = struct [@@noalloc] external pippenger : G.t -> Bigstringaf.t -> Polynomial.t -> int -> int -> int - = "caml_bls12_381_polynomial_internal_srs_g1_pippenger_stubs" + = "caml_bls12_381_polynomial_srs_g1_pippenger_stubs" [@@noalloc] end diff --git a/src/lib_bls12_381_polynomial/test/dune b/src/lib_bls12_381_polynomial/test/dune index fdbb0a6c8704..3e87d31f6337 100644 --- a/src/lib_bls12_381_polynomial/test/dune +++ b/src/lib_bls12_381_polynomial/test/dune @@ -10,7 +10,7 @@ qcheck-alcotest octez-polynomial bls12-381 - tezos-bls12-381-polynomial-internal) + octez-bls12-381-polynomial) (library_flags (:standard -linkall)) (flags (:standard) @@ -37,7 +37,7 @@ (rule (alias runtezt) - (package tezos-bls12-381-polynomial-internal) + (package octez-bls12-381-polynomial) (deps srs_zcash_g1_5) (action (run %{dep:./main.exe}))) diff --git a/src/lib_bls12_381_polynomial/test/test_coefficients.ml b/src/lib_bls12_381_polynomial/test/test_coefficients.ml index ddf8aee9538a..56518ac77772 100644 --- a/src/lib_bls12_381_polynomial/test/test_coefficients.ml +++ b/src/lib_bls12_381_polynomial/test/test_coefficients.ml @@ -37,11 +37,9 @@ let rec repeat n f = repeat (n - 1) f) module Scalar = Bls12_381.Fr - -module Domain = Tezos_bls12_381_polynomial_internal.Domain.Domain_unsafe - -module Poly = Tezos_bls12_381_polynomial_internal.Polynomial -module Evaluations = Tezos_bls12_381_polynomial_internal.Evaluations +module Domain = Octez_bls12_381_polynomial.Domain.Domain_unsafe +module Poly = Octez_bls12_381_polynomial.Polynomial +module Evaluations = Octez_bls12_381_polynomial.Evaluations let raises_invalid_arg f = try diff --git a/src/lib_bls12_381_polynomial/test/test_domains.ml b/src/lib_bls12_381_polynomial/test/test_domains.ml index b513bd2a8f9b..8bc28d641a5e 100644 --- a/src/lib_bls12_381_polynomial/test/test_domains.ml +++ b/src/lib_bls12_381_polynomial/test/test_domains.ml @@ -24,9 +24,8 @@ (*****************************************************************************) module Fr = Bls12_381.Fr -module Fr_generation = Tezos_bls12_381_polynomial_internal.Fr_carray - -module Domain = Tezos_bls12_381_polynomial_internal.Domain.Domain_unsafe +module Fr_generation = Octez_bls12_381_polynomial.Fr_carray +module Domain = Octez_bls12_381_polynomial.Domain.Domain_unsafe let factors_naive n = let rec factors_aux n factor result = diff --git a/src/lib_bls12_381_polynomial/test/test_evaluations.ml b/src/lib_bls12_381_polynomial/test/test_evaluations.ml index 07aed285412a..d92cbd69cbff 100644 --- a/src/lib_bls12_381_polynomial/test/test_evaluations.ml +++ b/src/lib_bls12_381_polynomial/test/test_evaluations.ml @@ -24,11 +24,11 @@ (*****************************************************************************) module Fr = Bls12_381.Fr -module Domain = Tezos_bls12_381_polynomial_internal.Domain -module Poly_c = Tezos_bls12_381_polynomial_internal.Polynomial -module Eval = Tezos_bls12_381_polynomial_internal.Evaluations +module Domain = Octez_bls12_381_polynomial.Domain +module Poly_c = Octez_bls12_381_polynomial.Polynomial +module Eval = Octez_bls12_381_polynomial.Evaluations -let powers = Tezos_bls12_381_polynomial_internal.Fr_carray.powers +let powers = Octez_bls12_381_polynomial.Fr_carray.powers (* computes p(g·x) *) let make_composition_gx g p_c = diff --git a/src/lib_bls12_381_polynomial/test/test_pbt.ml b/src/lib_bls12_381_polynomial/test/test_pbt.ml index c5c36141409f..d5f70626d788 100644 --- a/src/lib_bls12_381_polynomial/test/test_pbt.ml +++ b/src/lib_bls12_381_polynomial/test/test_pbt.ml @@ -23,7 +23,7 @@ (* *) (*****************************************************************************) -module P = Tezos_bls12_381_polynomial_internal.Polynomial +module P = Octez_bls12_381_polynomial.Polynomial let polynomial_gen = QCheck.Gen.(sized (fun n -> return @@ P.generate_biased_random_polynomial n)) diff --git a/src/lib_bls12_381_polynomial/test/test_polynomial.ml b/src/lib_bls12_381_polynomial/test/test_polynomial.ml index 3f62fab8d0fd..c66287c9d769 100644 --- a/src/lib_bls12_381_polynomial/test/test_polynomial.ml +++ b/src/lib_bls12_381_polynomial/test/test_polynomial.ml @@ -25,12 +25,10 @@ module Fr = Bls12_381.Fr module G1 = Bls12_381.G1 -module Fr_generation = Tezos_bls12_381_polynomial_internal.Fr_carray +module Fr_generation = Octez_bls12_381_polynomial.Fr_carray module Poly = Polynomial.MakeUnivariate (Fr) - -module Domain = Tezos_bls12_381_polynomial_internal.Domain.Domain_unsafe - -module Poly_c = Tezos_bls12_381_polynomial_internal.Polynomial.Polynomial_impl +module Domain = Octez_bls12_381_polynomial.Domain.Domain_unsafe +module Poly_c = Octez_bls12_381_polynomial.Polynomial.Polynomial_impl let p_of_c : Poly_c.t -> Poly.t = fun poly -> Poly_c.to_sparse_coefficients poly |> Poly.of_coefficients @@ -57,10 +55,8 @@ let test_get_one () = Helpers.must_fail (fun () -> ignore @@ Poly_c.get p 1) let test_get_random () = - let module Poly_c = - Tezos_bls12_381_polynomial_internal.Polynomial.Polynomial_impl - in - let module C_array = Tezos_bls12_381_polynomial_internal.Fr_carray in + let module Poly_c = Octez_bls12_381_polynomial.Polynomial.Polynomial_impl in + let module C_array = Octez_bls12_381_polynomial.Fr_carray in let degree = 1 + Random.int 100 in let p = Poly_c.of_coefficients [(Fr.one, degree)] in assert (Poly_c.length p = degree + 1) ; @@ -434,30 +430,25 @@ let test_vectors_fft_aux = in let expected_fft_results = Array.map Fr.of_string expected_fft_results in let polynomial = - Tezos_bls12_381_polynomial_internal.Polynomial.Polynomial_unsafe - .of_coefficients + Octez_bls12_381_polynomial.Polynomial.Polynomial_unsafe.of_coefficients points in let domain = Domain.build_power_of_two ~primitive_root log in let evaluation = - Tezos_bls12_381_polynomial_internal.Evaluations.evaluation_fft - domain - polynomial + Octez_bls12_381_polynomial.Evaluations.evaluation_fft domain polynomial in assert ( Array.for_all2 Fr.eq expected_fft_results - (Tezos_bls12_381_polynomial_internal.Evaluations.to_array evaluation)) ; - let ifft_results : Tezos_bls12_381_polynomial_internal.Polynomial.t = - Tezos_bls12_381_polynomial_internal.Evaluations.interpolation_fft + (Octez_bls12_381_polynomial.Evaluations.to_array evaluation)) ; + let ifft_results : Octez_bls12_381_polynomial.Polynomial.t = + Octez_bls12_381_polynomial.Evaluations.interpolation_fft domain evaluation in assert ( - Tezos_bls12_381_polynomial_internal.Polynomial.equal - polynomial - ifft_results)) + Octez_bls12_381_polynomial.Polynomial.equal polynomial ifft_results)) let test_vectors_fft () = (* Generated using {{: https://github.com/dannywillems/ocaml-polynomial} https://github.com/dannywillems/ocaml-polynomial}, @@ -685,8 +676,8 @@ let test_big_vectors_fft () = |> test_vectors_fft_aux let test_fft_evaluate_common length inner = - let module Domain = Tezos_bls12_381_polynomial_internal.Domain in - let module Poly = Tezos_bls12_381_polynomial_internal.Polynomial in + let module Domain = Octez_bls12_381_polynomial.Domain in + let module Poly = Octez_bls12_381_polynomial.Polynomial in let polynomial = Poly.generate_biased_random_polynomial length in let primitive_root = Fr_generation.primitive_root_of_unity length in let domain = Domain.build ~primitive_root length in @@ -697,15 +688,15 @@ let test_fft_evaluate_common length inner = assert (Array.for_all2 Fr.eq result expected_result) let test_fft_evaluate () = - let module Evaluations = Tezos_bls12_381_polynomial_internal.Evaluations in + let module Evaluations = Octez_bls12_381_polynomial.Evaluations in test_fft_evaluate_common 16 (fun ~length:_ ~primitive_root:_ ~domain ~polynomial -> Evaluations.(evaluation_fft domain polynomial |> to_array)) let test_fft_pfa_evaluate () = - let module Evaluations = Tezos_bls12_381_polynomial_internal.Evaluations in - let module Domain = Tezos_bls12_381_polynomial_internal.Domain in + let module Evaluations = Octez_bls12_381_polynomial.Evaluations in + let module Domain = Octez_bls12_381_polynomial.Domain in test_fft_evaluate_common (128 * 11) (fun ~length:_ ~primitive_root ~domain:_ ~polynomial -> @@ -718,18 +709,18 @@ let test_fft_pfa_evaluate () = |> to_array)) let test_dft_evaluate () = - let module Evaluations = Tezos_bls12_381_polynomial_internal.Evaluations in - let module Domain = Tezos_bls12_381_polynomial_internal.Domain in - let module Poly = Tezos_bls12_381_polynomial_internal.Polynomial in + let module Evaluations = Octez_bls12_381_polynomial.Evaluations in + let module Domain = Octez_bls12_381_polynomial.Domain in + let module Poly = Octez_bls12_381_polynomial.Polynomial in test_fft_evaluate_common (3 * 11 * 19) (fun ~length:_ ~primitive_root:_ ~domain ~polynomial -> Evaluations.(dft domain polynomial |> to_array)) let test_fft_interpolate () = - let module Domain = Tezos_bls12_381_polynomial_internal.Domain in - let module Poly_c = Tezos_bls12_381_polynomial_internal.Polynomial in - let module Evaluations = Tezos_bls12_381_polynomial_internal.Evaluations in + let module Domain = Octez_bls12_381_polynomial.Domain in + let module Poly_c = Octez_bls12_381_polynomial.Polynomial in + let module Evaluations = Octez_bls12_381_polynomial.Evaluations in let n = 16 in let log = Z.(log2up @@ of_int n) in let domain = Domain.build_power_of_two log in @@ -741,23 +732,23 @@ let test_fft_interpolate () = scalars let test_fft_interpolate_common length inner = - let module Poly = Tezos_bls12_381_polynomial_internal.Polynomial in + let module Poly = Octez_bls12_381_polynomial.Polynomial in let primitive_root = Fr_generation.primitive_root_of_unity length in let polynomial = Poly.generate_biased_random_polynomial length in let result = inner ~length ~primitive_root ~polynomial in assert (Poly.equal polynomial result) let test_ifft_random () = - let module Domain = Tezos_bls12_381_polynomial_internal.Domain in - let module Poly_c = Tezos_bls12_381_polynomial_internal.Polynomial in - let module Evaluations = Tezos_bls12_381_polynomial_internal.Evaluations in + let module Domain = Octez_bls12_381_polynomial.Domain in + let module Poly_c = Octez_bls12_381_polynomial.Polynomial in + let module Evaluations = Octez_bls12_381_polynomial.Evaluations in test_fft_interpolate_common 16 (fun ~length ~primitive_root ~polynomial -> let domain = Domain.build_power_of_two ~primitive_root length in Evaluations.(evaluation_fft domain polynomial |> interpolation_fft domain)) let test_fft_pfa_interpolate () = - let module Evaluations = Tezos_bls12_381_polynomial_internal.Evaluations in - let module Domain = Tezos_bls12_381_polynomial_internal.Domain in + let module Evaluations = Octez_bls12_381_polynomial.Evaluations in + let module Domain = Octez_bls12_381_polynomial.Domain in test_fft_interpolate_common (4 * 3) (fun ~length:_ ~primitive_root ~polynomial -> @@ -770,9 +761,9 @@ let test_fft_pfa_interpolate () = |> interpolation_fft_prime_factor_algorithm ~domain1 ~domain2)) let test_dft_interpolate () = - let module Evaluations = Tezos_bls12_381_polynomial_internal.Evaluations in - let module Domain = Tezos_bls12_381_polynomial_internal.Domain in - let module Poly = Tezos_bls12_381_polynomial_internal.Polynomial in + let module Evaluations = Octez_bls12_381_polynomial.Evaluations in + let module Domain = Octez_bls12_381_polynomial.Domain in + let module Poly = Octez_bls12_381_polynomial.Polynomial in test_fft_interpolate_common (11 * 19) (fun ~length ~primitive_root ~polynomial -> @@ -787,23 +778,19 @@ let test_of_dense () = let test_of_carray_does_not_allocate_a_full_new_carray () = let n = 1 + Random.int 1_000 in let array = Array.init n (fun _ -> Fr.random ()) in - let carray = Tezos_bls12_381_polynomial_internal.Fr_carray.of_array array in + let carray = Octez_bls12_381_polynomial.Fr_carray.of_array array in let polynomial = - Tezos_bls12_381_polynomial_internal.Polynomial.Polynomial_unsafe.of_carray - carray + Octez_bls12_381_polynomial.Polynomial.Polynomial_unsafe.of_carray carray in let two = Fr.of_string "2" in - Tezos_bls12_381_polynomial_internal.Polynomial.mul_by_scalar_inplace + Octez_bls12_381_polynomial.Polynomial.mul_by_scalar_inplace polynomial two polynomial ; let poly_values = - Tezos_bls12_381_polynomial_internal.Polynomial.to_dense_coefficients - polynomial - in - let carray_values = - Tezos_bls12_381_polynomial_internal.Fr_carray.to_array carray + Octez_bls12_381_polynomial.Polynomial.to_dense_coefficients polynomial in + let carray_values = Octez_bls12_381_polynomial.Fr_carray.to_array carray in assert (Array.for_all2 Fr.eq poly_values carray_values) let tests = diff --git a/src/lib_bls12_381_polynomial/test/test_srs.ml b/src/lib_bls12_381_polynomial/test/test_srs.ml index 3ae1b0e3430a..0d34499234e1 100644 --- a/src/lib_bls12_381_polynomial/test/test_srs.ml +++ b/src/lib_bls12_381_polynomial/test/test_srs.ml @@ -25,14 +25,13 @@ module Fr = Bls12_381.Fr module G1 = Bls12_381.G1 -module Poly = Tezos_bls12_381_polynomial_internal.Polynomial +module Poly = Octez_bls12_381_polynomial.Polynomial module Srs : - Tezos_bls12_381_polynomial_internal.Srs.S_unsafe + Octez_bls12_381_polynomial.Srs.S_unsafe with type elt = Bls12_381.G1.t and type polynomial = Poly.t = - Tezos_bls12_381_polynomial_internal.Srs.Make - (Tezos_bls12_381_polynomial_internal.Srs.Elt_g1) + Octez_bls12_381_polynomial.Srs.Make (Octez_bls12_381_polynomial.Srs.Elt_g1) let test_get () = let srs = Srs.generate_insecure 1 Fr.one in diff --git a/src/lib_crypto_dal/cryptobox.ml b/src/lib_crypto_dal/cryptobox.ml index dffaa52489b2..fb588db15afa 100644 --- a/src/lib_crypto_dal/cryptobox.ml +++ b/src/lib_crypto_dal/cryptobox.ml @@ -26,8 +26,8 @@ open Error_monad include Cryptobox_intf module Base58 = Tezos_crypto.Base58 -module Srs_g1 = Tezos_bls12_381_polynomial_internal.Srs.Srs_g1 -module Srs_g2 = Tezos_bls12_381_polynomial_internal.Srs.Srs_g2 +module Srs_g1 = Octez_bls12_381_polynomial.Srs.Srs_g1 +module Srs_g2 = Octez_bls12_381_polynomial.Srs.Srs_g2 type error += Failed_to_load_trusted_setup of string @@ -135,15 +135,14 @@ type srs = { module Inner = struct (* Scalars are elements of the prime field Fr from BLS. *) module Scalar = Bls12_381.Fr - module Polynomials = Tezos_bls12_381_polynomial_internal.Polynomial - - module G1_array = Tezos_bls12_381_polynomial_internal.Ec_carray.G1_carray + module Polynomials = Octez_bls12_381_polynomial.Polynomial + module G1_array = Octez_bls12_381_polynomial.Ec_carray.G1_carray (* Operations on vector of scalars *) - module Evaluations = Tezos_bls12_381_polynomial_internal.Evaluations + module Evaluations = Octez_bls12_381_polynomial.Evaluations (* Domains for the Fast Fourier Transform (FTT). *) - module Domains = Tezos_bls12_381_polynomial_internal.Domain + module Domains = Octez_bls12_381_polynomial.Domain type slot = bytes diff --git a/src/lib_crypto_dal/dune b/src/lib_crypto_dal/dune index 22ba842279de..ca02086f8cd2 100644 --- a/src/lib_crypto_dal/dune +++ b/src/lib_crypto_dal/dune @@ -10,7 +10,7 @@ tezos-error-monad data-encoding tezos-crypto - tezos-bls12-381-polynomial-internal + octez-bls12-381-polynomial lwt.unix) (flags (:standard) diff --git a/src/lib_crypto_dal/test/dune b/src/lib_crypto_dal/test/dune index a7a15b7757b2..63b7f9f58f2a 100644 --- a/src/lib_crypto_dal/test/dune +++ b/src/lib_crypto_dal/test/dune @@ -12,7 +12,7 @@ data-encoding octez-alcotezt qcheck-alcotest - tezos-bls12-381-polynomial-internal + octez-bls12-381-polynomial tezos-test-helpers) (library_flags (:standard -linkall)) (flags -- GitLab From e38de3335d91b641278466d139977311ae25dd79 Mon Sep 17 00:00:00 2001 From: Victor Dumitrescu Date: Mon, 13 Mar 2023 11:46:01 +0100 Subject: [PATCH 09/34] Lib_srs_extraction: import from aplonk/srs-extraction --- .gitlab/ci/jobs/packaging/opam_package.yml | 2 + dune-project | 1 + manifest/main.ml | 84 +++++++- opam/octez-srs-extraction.opam | 25 +++ src/lib_srs_extraction/README.md | 4 + src/lib_srs_extraction/dune | 27 +++ src/lib_srs_extraction/libsrs.ml | 188 ++++++++++++++++++ src/lib_srs_extraction/srs_extraction_main.ml | 111 +++++++++++ src/lib_srs_extraction/test/dune | 62 ++++++ src/lib_srs_extraction/test/main.ml | 13 ++ src/lib_srs_extraction/test/phase1radix2m5 | Bin 0 -> 18720 bytes src/lib_srs_extraction/test/srs_filecoin_g1_6 | Bin 0 -> 3072 bytes src/lib_srs_extraction/test/srs_filecoin_g2_6 | Bin 0 -> 6144 bytes src/lib_srs_extraction/test/srs_zcash_g1_5 | Bin 0 -> 1536 bytes src/lib_srs_extraction/test/srs_zcash_g2_5 | Bin 0 -> 3072 bytes 15 files changed, 516 insertions(+), 1 deletion(-) create mode 100644 opam/octez-srs-extraction.opam create mode 100644 src/lib_srs_extraction/README.md create mode 100644 src/lib_srs_extraction/dune create mode 100644 src/lib_srs_extraction/libsrs.ml create mode 100644 src/lib_srs_extraction/srs_extraction_main.ml create mode 100644 src/lib_srs_extraction/test/dune create mode 100644 src/lib_srs_extraction/test/main.ml create mode 100644 src/lib_srs_extraction/test/phase1radix2m5 create mode 100644 src/lib_srs_extraction/test/srs_filecoin_g1_6 create mode 100644 src/lib_srs_extraction/test/srs_filecoin_g2_6 create mode 100644 src/lib_srs_extraction/test/srs_zcash_g1_5 create mode 100644 src/lib_srs_extraction/test/srs_zcash_g2_5 diff --git a/.gitlab/ci/jobs/packaging/opam_package.yml b/.gitlab/ci/jobs/packaging/opam_package.yml index 916d17174441..a3f309b26817 100644 --- a/.gitlab/ci/jobs/packaging/opam_package.yml +++ b/.gitlab/ci/jobs/packaging/opam_package.yml @@ -363,6 +363,8 @@ opam:octez-smart-rollup-wasm-debugger: # Ignoring unreleased package octez-snoop. +# Ignoring unreleased package octez-srs-extraction. + # Ignoring unreleased package octez-testnet-scenarios. opam:octez-tx-rollup-client-PtLimaPt: diff --git a/dune-project b/dune-project index cd019d72738f..866f6902b62d 100644 --- a/dune-project +++ b/dune-project @@ -35,6 +35,7 @@ (package (name octez-smart-rollup-wasm-benchmark-lib)(allow_empty)) (package (name octez-smart-rollup-wasm-debugger)) (package (name octez-snoop)) +(package (name octez-srs-extraction)) (package (name octez-testnet-scenarios)) (package (name octez-tx-rollup-client-PtLimaPt)) (package (name octez-tx-rollup-node-PtLimaPt)) diff --git a/manifest/main.ml b/manifest/main.ml index 05caf81a1996..52bf23298f2f 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -851,7 +851,6 @@ let octez_bls12_381_signature = } ~c_library_flags:["-Wall"; "-Wextra"; ":standard"; "-lpthread"] ~js_of_ocaml:[[S "javascript_files"; S "blst_bindings_stubs.js"]] - ~linkall:true ~dune: Dune. @@ -1137,6 +1136,89 @@ let _octez_bls12_381_polynomial_tests = ] ~dep_files:["srs_zcash_g1_5"] +let octez_srs_extraction = + public_lib + "octez-srs-extraction" + ~path:"src/lib_srs_extraction" + ~synopsis: + "Extracts SRS for G1 and G2 from powers-of-tau generated by the ZCash and\n\ + Filecoin MPC ceremonies" + ~modules:["libsrs"] + ~bisect_ppx:No + ~deps:[bls12_381; octez_bls12_381_polynomial |> open_] + +let _octez_srs_extraction_main = + private_exe + "srs_extraction_main" + ~path:"src/lib_srs_extraction" + ~opam:"octez-srs-extraction" + ~modules:["srs_extraction_main"] + ~bisect_ppx:No + ~deps: + [ + octez_srs_extraction |> open_; + cmdliner; + unix; + bls12_381; + octez_bls12_381_polynomial |> open_; + ] + +let _octez_srs_extraction_tests = + tests + ["main"] + ~path:"src/lib_srs_extraction/test" + ~opam:"octez-srs-extraction" + ~deps:[octez_srs_extraction |> open_; alcotest] + ~dep_files:["phase1radix2m5"] + ~dune: + Dune.( + let extract curve srs_file = + let generated_srs_file = srs_file ^ ".generated" in + [ + S "rule"; + [S "alias"; S "runtest"]; + [S "package"; S "octez-srs-extraction"]; + [S "deps"; S srs_file; S "phase1radix2m5"]; + [ + S "action"; + [ + S "progn"; + [ + S "run"; + S "%{exe:../srs_extraction_main.exe}"; + S "extract"; + S "zcash"; + S curve; + S "phase1radix2m5"; + S "-o"; + S generated_srs_file; + ]; + [S "diff"; S generated_srs_file; S srs_file]; + ]; + ]; + ] + in + [ + extract "g1" "srs_zcash_g1_5"; + extract "g2" "srs_zcash_g2_5"; + alias_rule + "runtest" + ~package:"octez-srs-extraction" + ~deps:["srs_zcash_g1_5"; "srs_zcash_g2_5"] + ~action: + (run + "../srs_extraction_main.exe" + ["check"; "srs_zcash_g1_5"; "srs_zcash_g2_5"]); + alias_rule + "runtest" + ~package:"octez-srs-extraction" + ~deps:["srs_filecoin_g1_6"; "srs_filecoin_g2_6"] + ~action: + (run + "../srs_extraction_main.exe" + ["check"; "srs_filecoin_g1_6"; "srs_filecoin_g2_6"]); + ]) + let octez_crypto_dal = public_lib "tezos-crypto-dal" diff --git a/opam/octez-srs-extraction.opam b/opam/octez-srs-extraction.opam new file mode 100644 index 000000000000..87a3fb9443ef --- /dev/null +++ b/opam/octez-srs-extraction.opam @@ -0,0 +1,25 @@ +# This file was automatically generated, do not edit. +# Edit file manifest/main.ml instead. +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: ["Tezos devteam"] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "3.0" } + "ocaml" { >= "4.14" } + "bls12-381" { >= "6.1.0" & < "6.2.0" } + "octez-bls12-381-polynomial" + "cmdliner" { >= "1.1.0" } + "base-unix" + "alcotest" { with-test & >= "1.5.0" } +] +build: [ + ["rm" "-r" "vendors"] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Extracts SRS for G1 and G2 from powers-of-tau generated by the ZCash and +Filecoin MPC ceremonies" diff --git a/src/lib_srs_extraction/README.md b/src/lib_srs_extraction/README.md new file mode 100644 index 000000000000..b093e8691c91 --- /dev/null +++ b/src/lib_srs_extraction/README.md @@ -0,0 +1,4 @@ +Extracts SRS for G1 and G2 from powers-of-tau generated by the ZCash and +Filecoin MPC ceremonies: +- https://download.z.cash/downloads/powersoftau (max 2^21) +- https://trusted-setup.filecoin.io/phase1 (max 2^27) diff --git a/src/lib_srs_extraction/dune b/src/lib_srs_extraction/dune new file mode 100644 index 000000000000..feedbbbbc0f1 --- /dev/null +++ b/src/lib_srs_extraction/dune @@ -0,0 +1,27 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name octez_srs_extraction) + (public_name octez-srs-extraction) + (libraries + bls12-381 + octez-bls12-381-polynomial) + (flags + (:standard) + -open Octez_bls12_381_polynomial) + (modules libsrs)) + +(executable + (name srs_extraction_main) + (libraries + octez-srs-extraction + cmdliner + unix + bls12-381 + octez-bls12-381-polynomial) + (flags + (:standard) + -open Octez_srs_extraction + -open Octez_bls12_381_polynomial) + (modules srs_extraction_main)) diff --git a/src/lib_srs_extraction/libsrs.ml b/src/lib_srs_extraction/libsrs.ml new file mode 100644 index 000000000000..36e1e15e7631 --- /dev/null +++ b/src/lib_srs_extraction/libsrs.ml @@ -0,0 +1,188 @@ +open Bls12_381 +module G1 = G1 +module G2 = G2 +module G1_carray = Bls12_381_polynomial.G1_carray +module G2_carray = Bls12_381_polynomial.G2_carray + +module Checks = struct + let equality (g1_elements : Bls12_381_polynomial.G1_carray.t) + (g2_elements : Bls12_381_polynomial.G2_carray.t) = + let g1 = G1_carray.get g1_elements 0 in + let g2 = G2_carray.get g2_elements 0 in + Bls12_381_polynomial.G1_carray.iteri_copy_elt + (fun i g1i -> + let g2i = G2_carray.get g2_elements i in + let gt_element1 = Pairing.pairing g1i g2 in + let gt_element2 = Pairing.pairing g1 g2i in + assert (GT.eq gt_element1 gt_element2)) + g1_elements + + let incrementation_g1 g1_elements g2_elements = + let g2 = G2_carray.get g2_elements 0 in + let g2x = G2_carray.get g2_elements 1 in + for i = 0 to G1_carray.length g1_elements - 2 do + let g1i = G1_carray.get g1_elements i in + let g1iplus = G1_carray.get g1_elements (i + 1) in + let gt_element1 = Pairing.pairing g1i g2x in + let gt_element2 = Pairing.pairing g1iplus g2 in + assert (GT.eq gt_element1 gt_element2) + done + + let incrementation_g2 g1_elements g2_elements = + let g1 = G1_carray.get g1_elements 0 in + let g1x = G1_carray.get g1_elements 1 in + for i = 0 to G2_carray.length g2_elements - 2 do + let g2i = G2_carray.get g2_elements i in + let g2iplus = G2_carray.get g2_elements (i + 1) in + let gt_element1 = Pairing.pairing g1x g2i in + let gt_element2 = Pairing.pairing g1 g2iplus in + assert (GT.eq gt_element1 gt_element2) + done + + let pairings g1_elements g2_elements = + equality g1_elements g2_elements ; + incrementation_g1 g1_elements g2_elements ; + incrementation_g2 g1_elements g2_elements +end + +let exact_log2 p = + if p <= 0 then raise @@ Invalid_argument (string_of_int p) ; + let rec aux res p = + if p = 1 then res + else + let p' = p lsr 1 in + if p' = 1 then + if p mod 2 <> 0 then raise @@ Invalid_argument "not a power of 2" + else res + 1 + else aux (res + 1) p' + in + aux 0 p + +(** The binary format of our Srs is a sequence of G1 or G2 elements. *) +module Srs = struct + let to_file gs file to_compressed_bytes iter = + let oc = open_out_bin file in + try + iter (fun g1 -> output_bytes oc (to_compressed_bytes g1)) gs ; + close_out oc + with e -> + close_out oc ; + raise e + + let gs1_to_file gs output_file = + to_file + gs + output_file + G1.to_compressed_bytes + Bls12_381_polynomial.G1_carray.iter_copy_elt + + let gs2_to_file gs output_file = + to_file + gs + output_file + G2.to_compressed_bytes + Bls12_381_polynomial.G2_carray.iter_copy_elt +end + +(** This module handles the file format of the result of powers-of-tau ceremony. + + The layout of the file can be found at the bottom of this file + https://github.com/ebfull/powersoftau/blob/master/src/bin/verify.rs + to be + let tau_powers_length = 1 lsl power in + G1.size_in_bytes (* alpha in g1 *) + + G1.size_in_bytes (* beta in g1 *) + + G2.size_in_bytes (* beta in g2 *) + + (tau_powers_length * G1.size_in_bytes) (* g1_coeffs *) + + (tau_powers_length * G2.size_in_bytes) (* g2_coeffs *) + + (tau_powers_length * G1.size_in_bytes) (* g1_alpha_coeffs *) + + (tau_powers_length * G1.size_in_bytes) (* g1_beta_coeffs *) + + ((tau_powers_length - 1) * G1.size_in_bytes) (* h *) +*) +module Powers_of_tau = struct + let generate_domain power = + let size = 1 lsl power in + let rec get_omega limit = + if limit < 32 then Fr.square (get_omega (limit + 1)) + else + Fr.of_string + "0x16a2a19edfe81f20d09b681922c813b4b63683508c2280b93829971f439f0d2b" + in + let omega = get_omega power in + let rec encoded_pow_x acc xi i = + if i = 0 then List.rev acc + else encoded_pow_x (xi :: acc) (Fr.mul xi omega) (i - 1) + in + Array.of_list @@ encoded_pow_x [] Fr.one size + + (* Derives the power that generated the file from the total size of the + file using this formula: + let tau_powers_length = (total - g1 - g2) / (4g1+g2) + let power = log2 tau_powers_length + *) + let power_of_radixfile radixfile = + let ic = open_in_bin radixfile in + try + let g1 = G1.size_in_bytes in + let g2 = G2.size_in_bytes in + let filesize = in_channel_length ic in + close_in ic ; + let nb_elements = (filesize - g1 - g2) / ((4 * g1) + g2) in + exact_log2 nb_elements + with e -> + close_in ic ; + raise e + + let to_gs radixfile skip size_in_bytes of_bytes_exn evaluation_ecfft of_array + = + let power = power_of_radixfile radixfile in + let buf = Bytes.create size_in_bytes in + let read ic = + Stdlib.really_input ic buf 0 size_in_bytes ; + of_bytes_exn buf + in + let ic = open_in_bin radixfile in + try + Stdlib.seek_in ic skip ; + let size = 1 lsl power in + let points = Array.init size (fun _i -> read ic) |> of_array in + close_in ic ; + let domain = Bls12_381_polynomial.Domain.build_power_of_two power in + let points = evaluation_ecfft ~domain ~points in + points + with e -> + close_in ic ; + raise e + + let to_g1s radixfile = + let skip_header = + (* Skip alpha_g1, beta_g1 and beta_g2 *) + (2 * G1.size_in_bytes) + G2.size_in_bytes + in + to_gs + radixfile + skip_header + G1.size_in_bytes + G1.of_bytes_exn + Bls12_381_polynomial.G1_carray.evaluation_ecfft + Bls12_381_polynomial.G1_carray.of_array + + let to_g2s radixfile = + let power = power_of_radixfile radixfile in + let size = 1 lsl power in + let skip_header = + (* Skip alpha_g1, beta_g1 and beta_g2 *) + (2 * G1.size_in_bytes) + G2.size_in_bytes + in + let skip_g2s = + let skip_g1s = size * G1.size_in_bytes in + skip_header + skip_g1s + in + to_gs + radixfile + skip_g2s + G2.size_in_bytes + G2.of_bytes_exn + Bls12_381_polynomial.G2_carray.evaluation_ecfft + Bls12_381_polynomial.G2_carray.of_array +end diff --git a/src/lib_srs_extraction/srs_extraction_main.ml b/src/lib_srs_extraction/srs_extraction_main.ml new file mode 100644 index 000000000000..b4a3484b7c00 --- /dev/null +++ b/src/lib_srs_extraction/srs_extraction_main.ml @@ -0,0 +1,111 @@ +open Libsrs + +type curve = G1 | G2 + +let extract curve source input_file output_file = + match curve with + | G1 -> + let g1_elements = Powers_of_tau.to_g1s input_file in + let output_file = + Option.value + ~default: + (Format.sprintf + "srs_%s_g1_%i" + source + (Libsrs.exact_log2 + (Bls12_381_polynomial.G1_carray.length g1_elements))) + output_file + in + Srs.gs1_to_file g1_elements output_file + | G2 -> + let g2_elements = Powers_of_tau.to_g2s input_file in + let output_file = + Option.value + ~default: + (Format.sprintf + "srs_%s_g2_%i" + source + (Libsrs.exact_log2 + (Bls12_381_polynomial.G2_carray.length g2_elements))) + output_file + in + Srs.gs2_to_file g2_elements output_file + +let check g1s_input_file g2s_input_file = + let bigstring_of_file filename = + let fd = Unix.openfile filename [Unix.O_RDONLY] 0o440 in + Bigarray.array1_of_genarray + @@ Unix.map_file + fd + Bigarray.char + Bigarray.c_layout + false + [|(* [-1] means read the whole file *) -1|] + in + let open Bls12_381_polynomial in + let g1s = + Srs.Srs_g1.of_bigstring (bigstring_of_file g1s_input_file) |> Result.get_ok + in + let g2s = + Srs.Srs_g2.of_bigstring (bigstring_of_file g2s_input_file) |> Result.get_ok + in + Srs.check (g1s, g2s) + +let extract_cmd = + let open Cmdliner in + let source = + let doc = "Source of the powers of tau file: filecoin or zcash." in + Arg.( + required + & pos 0 (some (enum [("zcash", "zcash"); ("filecoin", "filecoin")])) None + & info [] ~docv:"source" ~doc) + in + let curve = + let doc = "Which curve points to output: G1 or G2" in + Arg.( + required + & pos + 1 + (some (enum [("g1", G1); ("G1", G1); ("g2", G2); ("G2", G2)])) + None + & info [] ~docv:"curve" ~doc) + in + let input_file = + let doc = "Powers of tau file e.g. phase1radix2m5." in + Arg.(required & pos 2 (some file) None & info [] ~docv:"input" ~doc) + in + let output_file = + let doc = "Output file." in + Arg.( + value & opt (some string) None & info ["o"; "outdir"] ~docv:"output" ~doc) + in + let term = Term.(const extract $ curve $ source $ input_file $ output_file) in + Cmd.(v (info "extract") term) + +let check_cmd = + let open Cmdliner in + let g1s_input_file = + let doc = "Srs file of G1." in + Arg.(required & pos 0 (some file) None & info [] ~docv:"input" ~doc) + in + let g2s_input_file = + let doc = "Srs file of G2." in + Arg.(required & pos 1 (some file) None & info [] ~docv:"input" ~doc) + in + let term = Term.(const check $ g1s_input_file $ g2s_input_file) in + Cmd.(v (info "check") term) + +let _ = + let open Cmdliner in + let doc = + "Extracts SRS for G1 and G2 from powers-of-tau generated by the ZCash and\n\ + Filecoin MPC ceremonies:\n\ + - https://download.z.cash/downloads/powersoftau (max 2^21)\n\ + - https://trusted-setup.filecoin.io/phase1 (max 2^27)\n\n\ + To truncate the result use:\n\ + head -c $(( 48 * nb_elements )) g1_input > g1_output\n\ + head -c $(( 96 * nb_elements )) g2_input > g2_output" + in + let info = Cmd.info "extract-srs" ~doc in + let default = Term.(ret (const (`Help (`Pager, None)))) in + exit @@ Cmd.eval @@ Cmd.group info ~default [extract_cmd; check_cmd] diff --git a/src/lib_srs_extraction/test/dune b/src/lib_srs_extraction/test/dune new file mode 100644 index 000000000000..1f33f9abaa40 --- /dev/null +++ b/src/lib_srs_extraction/test/dune @@ -0,0 +1,62 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(executable + (name main) + (libraries + octez-srs-extraction + alcotest) + (flags + (:standard) + -open Octez_srs_extraction)) + +(rule + (alias runtest) + (package octez-srs-extraction) + (deps phase1radix2m5) + (action (run %{dep:./main.exe}))) + +(rule + (alias runtest) + (package octez-srs-extraction) + (deps srs_zcash_g1_5 phase1radix2m5) + (action + (progn + (run + %{exe:../srs_extraction_main.exe} + extract + zcash + g1 + phase1radix2m5 + -o + srs_zcash_g1_5.generated) + (diff srs_zcash_g1_5.generated srs_zcash_g1_5)))) + +(rule + (alias runtest) + (package octez-srs-extraction) + (deps srs_zcash_g2_5 phase1radix2m5) + (action + (progn + (run + %{exe:../srs_extraction_main.exe} + extract + zcash + g2 + phase1radix2m5 + -o + srs_zcash_g2_5.generated) + (diff srs_zcash_g2_5.generated srs_zcash_g2_5)))) + +(rule + (alias runtest) + (package octez-srs-extraction) + (deps srs_zcash_g1_5 srs_zcash_g2_5) + (action (run ../srs_extraction_main.exe check srs_zcash_g1_5 srs_zcash_g2_5))) + +(rule + (alias runtest) + (package octez-srs-extraction) + (deps srs_filecoin_g1_6 srs_filecoin_g2_6) + (action + (run ../srs_extraction_main.exe check srs_filecoin_g1_6 srs_filecoin_g2_6))) diff --git a/src/lib_srs_extraction/test/main.ml b/src/lib_srs_extraction/test/main.ml new file mode 100644 index 000000000000..12341fc7aa60 --- /dev/null +++ b/src/lib_srs_extraction/test/main.ml @@ -0,0 +1,13 @@ +open Libsrs + +let test_lagrange () = + let input_file = "phase1radix2m5" in + let g1_elements = Powers_of_tau.to_g1s input_file in + let g2_elements = Powers_of_tau.to_g2s input_file in + Checks.equality g1_elements g2_elements + +let tests = [("lagrange zcash_srs", test_lagrange)] + +let () = + let wrap = List.map (fun (name, f) -> Alcotest.test_case name `Quick f) in + Alcotest.run ~verbose:true "SRS" [("Srs", wrap tests)] diff --git a/src/lib_srs_extraction/test/phase1radix2m5 b/src/lib_srs_extraction/test/phase1radix2m5 new file mode 100644 index 0000000000000000000000000000000000000000..22ebb556ee1c2f8d61242cf9f8148c9f8e5d601e GIT binary patch literal 18720 zcmd_S!y7*sj(uezcJC>eb%E4Bk_4maeRpYp=Z(8SQNNh^v z){|WA61%2|d*i1KXN}FiFI;m>`{U-ticLu=ck0|GH9oRdY@Tv;M#kI)e!>|Q|7TT9 zXY{IAaj~#ragEQ4-^%i8UOQ%A^hhqRKluM8u5A?>NWkLzAnh z;=Cg%2K7OQjjO*)kX^rmipcA<{z*Oa4OOGFxyla;MqT^7faiEKYeUbhv7ne$%z*cl~ZOw^Rr?m#u6l zD$CKFIyvIy*=I{;gh_mhTNM7{Q^$0FuebMtp58k2yXxs>zST81G!~uM7%#dpUwFQb z@q6QI*6*LNJezj1p!{Op5`F)lH}sB#t@>gqviL$}hM<&{Nxx`a$^rE*#-c3~O@bF} zv75hH#Y$JDdV$Cb9lq0(CG7v1Mw$z9J1jl4e$E14Rbyq9+K`?pXKff$xjC+0(PMvq z`Qc6Rgj;K5&u`n5E9bq)LpVYre5POK-tO~-5z4Y%Om-g}ZCx7oF?K(>@ue~?XyfMk zrGKCKul3Cqn){u<=+d>9Kic$eo^LZSo#Zv^K}S^mHO1W5$`X7MSErnPRcBJUd&_I4 zHR~ST3qR4zP^P=W_51V-2iQLGY<-^@@u_c>_L&RaESrwT3*KN~e|1~r!2l_n)$_mZ zdAI$nYAT<9$-NGbQyI~JpZ?ocl5|4RMX}+k+T%YPp2XUxhl+fPvtYBBDxx;)fUMA6 z?w8KztnUZ1Pd$4yX~p`h3}=#SI-hw=UHbBG#a88gEy~Mpuw<{2pQy7r@41ZgZS6ak zzdYkQyddCF;ojGGd-NqYOt)oK6E5G#de|gVtnR{+rZ@vR0T~-`4Mxz1YhSm!|m4J-GFk$q)Tty^!th z1wU-HK7>gMHs0~y;@Q`9=za85t_8nU_rJT=eRB61=6jba9Jc*Xp zJ^d)--|5a(`jzhY(=1n=b^GOW|E;09eyMJik%U6ZjfS*^P1m?STr**K{&S9gQA*;k z!U8SjtG9oIY@Drm@AXxwc;#nnL_&Y<{=YCuK)B=AC4KG!t4md1Z+b-i$y>X|?}LC! z#iba&o}dR-|J-Kw1l?VJ;eTk9;{Fp#Pu58oPX6R2{4c{S?%=Ll#mSFurc3Hf-6Zh; z_?*=xp-F!h|4(35{C!eDV#4luXHRTm>K6!dHEt<&eYm@WVe6%nIT}F$*BRr#*jmh7 zv*KvAcIoX+>KhiuTWm9qjK8w+W6%DD;%{;p8BV-d^#6IVCfgd(n<`(*+ZI%OcWDmX zU2%W+B>(6K1)8awo4+M$aW`!Yc%IL>{MUThtDkeD?zf?8FU60v+pol$kqG5#rm(bB)C)Y1nE+i52cgBU|%*|<9`7B~v zwO3W_d^79KUpIq8e|grl8#(P-E#!RtqX~0k+y8av{6;XK0;;D%mPZr6&y5comOa9qzIhQ-~pI5AFlIUjN^YHoI z?sq0Dp78E6Z%cQWe(HT)qjNO#yzXcJ>LWgA`Q3|`IkoEBSIaXpEFV1=1PiAvi4)4) z(C9F$c+O7OBY~46GBuwU+Xzf)4hXqeJJ)KXZttwMhO%$$+)~qS3Mpq@$(q`*K!q?kSTH=aUHGm@zB-aPKike(%Gl)<)cTJXOt4kTJ-cpQ)Giku;lSs->3K8h2q7u4p>o0fQXPWZ6$&=)bQ0@l+H60O?9G8xYNw3+R>^L>l**XE-Z+UlQJpWf8id?{e@ z@!bcEGo#*qZN2f?hdud=xro6%({+|hX4vcH`(!ogFS~O8W#oHTQ?A9L5Hs6T_RxVXc9(ZmC%;{-ysg}|z_j$S&XVf2b_y58pR|ZM zWM{dkJ1Nde-ORsy>m+gGhnr+kLwK7QI*_^8WSrB8$0x zQm=AagpXz!PgQHkIO?l-lUwC8qiS};tMy_b3%1E9$;P|AvwoGjo29??ZtJ%>%k~_< z{aBFy&ExJ@vR}g`^;)9DIq|CDr(WIDiGI@sxHL*K8f5bdY7bT(S5sLP9zT(b zm+xs&R~*}gT8D)GBCV%W-|5Eo@(X(KT{lq=Wnb-BD%W4AV^^UW{4s#HCUm8vldGVO zr~IC?x?%o51+;7V!fK!UW%B&&{vj|L)(B5~(jnk0skCtCZDDF1WFjM`P}{zK=RQmzK%Q zS-&q;?wgmRcOa_wByDnH;vQSk@FJC0SMz|3qx-glD_u zUoP0cBX76ep;;|llfK2=7C*B!ZIj2Pnm0drthgri_lmuVV1IMZ=g`*+kGVKH7*^9@m&T+?r;0vur>#{ zCf~RmBs6Qvh61a7HykJaQ#uoW!rXS_%Fsmr{7Hr9+Mj0__V9<5tk}b88+d%P+p+86 zA@@X-145QI-@1D2@uDk1@7QKM;)`h0H%!i#-tP3EUvS z{?2NlL+P)y4czVjj?Yi}p;?&H;?|;Nw8Zda23Nk|?5BZyHuZnxQtpp>rYf4Q7%1fU z{E*t4`BTEbD?XcDbv-=JIPI>}wD>m(Z;XB_B{X}m^w{RdvGU$uDazfw`bmM?-sdsw z_0u+Qsx1mqDoPX0lAiwQ@42chQ7gG!zthwz-%71r(z9KkscO3ZHR<=(+Y_eTiaQ>( zepcA;q&$Tqa?Lj0^H}>Gi>Dvnq486sfmPsWOTsfXeSNNHInPw{oA%EU>8M?|fvGIx zQCjWw$Dc2VC#`GC?eX1lC$%u>EpIrO)-L^Dj!ScvV`9@;@{>_XuZw&C(qo(6Xx{ndpU3;G zE7{I=(q2n>^;6T#oiFcrE|B+KWux%IfT;}b!WYcXvX&`D1Pc{%nJ!Hd`5gS_+2j0& z`4V@XXMQw0`<+3sdI$5($rrhAFiqI`;pb`lnx8T%r)^j7V@}@3df|nTmW=<(8yT)P z$K1}WN}I5Dmgf0mf+pe0J3}_J{nzG^|B?E6L8sb_M_J*!*8bjmPx#^Fy5{<4yCoLg zo+Es{fpMAhbIp~;ya~7JvmLlk91>2_tTkp!m3);lfpu@vzk-jK-I#U!W+gKPe%7c@ zf4y94;h(Rr{(8?9Hi%{(VcN2C{>BT-=DEC?^sIf}Yh~dlf-{m^E%;PKclgf@-PCG) zB<|i5ff>a|zqzen*Zy-6_n$p1t_*Q-7Pq!v;?L&1KcRLZu58Ja z&Bx3)ue!~mB&8KUW91!*$93Bu%>7nhS8nNL!nR%AmD4DwLRZw>#Z{m4gm&QbRb^MN zN-#4`%zMU{#>9F%lxg7~u36VNWdBq@ZKv&?FyBi`%hYyO>Z%S|4=*N-uW#FLe-@p} za{lfQ2Dho_ogPW@Y0Yw(Akx&kCZE~9z;)3{+t09xlE^AHu zvG3%47JbXJEEY4Y91Uhf^f5LHKRmSAI&|G;pQJTUCcanrqoH9UrhP?!)&?KYr zRU3rY&RHS4dC7s}0mm+EVXMyGz~%NIw?n7FOiysdR}4VlKiCgr8TIrUwd z30zm^R}0jt=~Qz}wwjtO)b&p3^3pidE_gMPt z!iR_PB5BQ&773p%59j}V%~A4;^vjp~%{{pn%Si4iPyEoS`t9BR$2q4ZQ_jCzU*N-) z*Avchm3>xoV@}-K_hQj*c1w%C?c8?5-@|98Vyg1q`=`BJaxbqt_1>p3qqgtNl!Mlx zMJQ2C`~Gw9ItAa859ieETCnKK=hS~Q3`~?bX4|*xP0PQ^eW^vunaOL_ z!G%)3-oBnXGjH;V=f=fLbxrDPj1?_>uYEsn){MG+@3x%yd*R;a&xVWc<;p%`(JbXZ zEci2&xBF-PK{>rWZ~9B3i+C9dKBU^!*~l)xX=--fXzOFOr8D1zCNw-}QRVac9h&L* zmCtd-=Q!n#-PaHJTA793*MFw{a zmGwGeB)Hm6v+k2&zA4$=>2D|3Co8pT^`oQ5bGCKJDrda7v%)C(P987+lIE+gwlT!0 z#HFlWt#f`hN5z$t^?_=ymdTv?HNWZ0TGmguce-Ugu6JAhck1ubNkZSevqazByLuwd zzE56j`L}<*pSPTJGFl(w^Cw0!a>M(UT-D$E7k8hDcw5>(``GGapCyykqU_1Da zNiEigtzFzc;`Es>&XQc}*Gv9ydNp-n){%_|o<885Wu@Sfy1kb%Rz@|`K$&N8kGHpI zW`E|N`AaAMco^;Bv2bO1%K6+A@iJ-(E-|lWhV2eb$hh|86N`sp0HdL9<#V&E2D~cg z82`Le-x{muCVBn;f$YeZeZjMhBUHXgyss1belonK_HH6))aKjw>>7RSE#l5ERQa#c zzic|&8gZAohYCxIpPi2k|29wd<35gs|I$t`KU}`BYZKq!y$=p@OxSn*h3|(?k*_|l zJ$|LPDXl&mnm3Llvnpfo6lZXE( zS08-fQ@Q9#bH!4%ltapQLKa?0zQ8Nzx&N`o*|J3p>=8#Y<(at_haKeDX7)+^U*pdO z^S(8#V>X_7z4<~LUrNPN!3JlM#;p>9_5X5yI-h4)vv^Cr`m$*aANO|DGX06Uo-Z(A zN{FcJ!KJYWC!RVp#Ye5Vx?AodU$Rqtp4_#q_DuCf+fo^BvhHEwom_W4^7!%3`^|0^ z$E?|IHEm;L)Pno7F8fZZn7p?~xmH8ggJF6z&+hUoS1)bjm4E+Nen#QN)t_nw^~0Uz zcsRm$-;jMCux0bFwdOk(Z;3q~{O;)CojZy5S4L>|7JTyNoaum0V#H^~Oax8;Ai zo;HCmBe`SeUe+gnCNkW=!T)YE+mx0rpUu2#vn=H}Crql8FgzWTAo{?-dP(F7XQ#6t zH|$+MG3HXhq}z?}m*^B-&(byWtX{v=mLc4bKmB4|&t&&S|Jm04P}7*2H=+4?wvOL^ zamU76X46U+dvxkHHLopPt#-nM)$cX;e5f^Dq9JREcd}2~y`O4R}e)apP-QgJ@|M2k5nDnwO z@=@`$+uQcu4Pu)ewS=43{Ihs^-kJ20gKwwIEDR9e^xG)Vw|AP^cC~9~p6$3fyKBq( zMK6y@=adCI6tKpgW@lQQX%c0dAH||m?`mK0BGGO~Vzl9WuLM7t93i{k&dV5jS zW_0YAe{)8CXB6`+ok>%UTy=N(JALLX|G?Kv7IMYNN%`M*jaYnf)-g%rYOTlhJN~g| z+-A{E`m-rw4ny>sZuigk*X(-3l{g{Mf6uwYNe^aPK717Kr|8ZZ;czC~G2+|Djun5i zVoj~i6iY~QZD!f^d*5vpIq$R@hpvT|pHDg5JL{`)xluso$8?5`JM@@W1Th-goP8p{ zG;MBVmYU>dwSUKtoN5-;v-}w|-FDJh^K~^V&8}uyG90VC8Q0^S+0~!?bN}R!c?&BS z20rRLEOI?aY4aT4W2+55mgUK>?2h(hWya{+0apP)~0#uYTW~JBKCl(y|xL6)&bmAJSHN=Ot?U zF_a^?X5-_EZL@OgcjT^+QMz~kP?bDFh{`h;wMRoSq4GY$;p0)Cm|MNfJ z{F#$Vi@wY}BeSLa?Z-s1$39PgeKL{B+pv-6&54tX)7|;JnD6Gu#vFX~@7|Tw|F5>p z7HDPkeBxdFVd2%RhfiibdgXX!_j|EzkzLVy(J^o1*#kL00)P1k@~yZe z7OA$lQr-VzzTc1V{~0`fqF-~lcP=#JF}Zd1$UL<*ci18nxAiB4UtOMl(6nOzjs{8p zH7?tKukYUI{?lz?l0ufC$j&c&HXgtIMyzc1#u7m$r)6LJ6!;cYM;u(^p~V@tQrJ7Y zlRsKAbZg|Hf3~qAruSX{?_|68_=aqRoc@&en|7FoFHv85gW2ZnBwP1t3-cyPy|yx6 ztEki?rElj%Stu7L#~0n;3}-ua@2mgu%Pg@{8U7M;rwToo{~>Iu(BwIZQzcgi@G!Yd zcz)bWWZxmBd&$@T9n);!H(2?x>A8%}3-85-g&Zjsd*3YIIQ{IAi#43nSlSM(^|W8= zxBKYA>#zFd_C6K!iENEbz5K7rLw8N#_f_+*sssoA;(u@zn zJ%_6%IG&N=c*nrAlGjZ%;#u=C)6>yfOzmHf@UMHes$ECYWq*BE1N)_!3=)f_uaxez zKE7DYRY~?fzpvCTUDJjB3^h`b8B4f+Z}3|7ML{CZch!BiTzjOTsh-2Hh$NSmHwWx@$CP(fA|l+T=?&GL+9t)s+><$jF1uQoyZUO*(nX>oZ@kO@?zudRGp^3h z(B^^lu_L~vlmE&s^eSCp9JGB7!_vx$_mr17-#B?{f*PM3_k_9qYkD-h^wqCsoGtxa z{Pj7TNX(qc=Yv~bUfyN4sIA;TR&S?=@rUyHoA*0D5=qKDE}t)DQEPiXOR+AxXIlOD zq$Az$RG%o6oR%qZb8P-|Ix6P=Y@Z8CXV|xS-TlvV-oA1@@2pHmcPp;r_b1--)1ZY3x>%x%{=qwgqz4OhdX-Gwmgy9e6h`E zjpOHTxteMuxMt_fo!_};oa%Dj_GHl;bH9sxn_oIjRA>G_W1kB1uV2d(K4(pi$qr$@zDaWLx9P90Hl1=3vz>QTB}YGX<@Atm z2CoY?YfM$pTyp5HQ0|!|mP>~xYcjLVkmXDNXmM(pf$P++(9evz->Db!zMESkNc=9!s= z>eTZ2N&>5ScbMPIgOiaXVlm&#{MfSsvo}4wDSY?cIlovhyB$JzgO>jeWc|Fv zH9utS(Zl<4H_e`^V0qQ9|Fux;Y0f1d9&KuRe@UN--Ox4e%Df=w%?2eEbDaAQg>t0J zeC%3(-shH6-}Ka5CL(9eHd?WXMT*5XolE$}#jtT=W0&W9#y#s--+#X++g3E{D_hqD zX3aF7gGteQe$TPtx~MPWmT{LcTg`;Crq6=ABMSc>+%WxI#?4)p#%`apE{Md(%$jnlRwHG3 zqUJJt|EcNPiTiFYUi?&iN;KTqTSm+^PaLCtC+NZ@o&YLjsu-j zLf;&GzAKgQ>Z~$WpNSH2ep!Fll%Mf!l4kQ>I7{)yqx>uTCz`K#zOq5Q`Ngy>Jx+sr zv0hE`l2IWWYduRfI8N?gVlVQx@cv)B33?kI{hZ~sao@Tkzf(;`B{>}3E`j^Ep5U9J zw2SS6>szyFD|mdx?6z>Ioha)(ucmfP;M}zTDK^YA-)z}C#V;@7mrZR@R5#1d<40sp zo(p>uRb9TMT9f^yN!Fcz+t2#sJ=YKMxL+L^=3+77_JU{gly8}ITz_$7j&iG@+*Na5 zq1V~#gyv5^%``RiVyv~RX2uSWCy}pJ%61&KHH=tk|7(iJ1l0@C0gUIail6Mcli@Lw z+3&PaQd%ANMZF0(){7Z)=Bn<%_c%)zWC#JNKJKwqBLR?H)nXwpY&5i=9qQ>fUguHZA4w*NzC@qQLi0FK2!2 z?u{!EGQFOwBe=^s)#!=9$HV)dPl{2=$UYg!_Ufe0HP(B}jhqiYTgF~ty7S)s18QB| z&gTWMzie6GpmoXk`s_)9PUmEnuwME6Wy?mPtlsbM&#m_Q^4w?niyp6ii2?t%H}R~K z+A3PmE&rZzNr1_ZOF;$+nfK@VyLIr{&Y3YKs9aiFYJ*+>)AIr%HWsPr)3R4sZ#DnP zI3rms+xV5B>B6)or{Lr>+ZJ!TEP3B}%Hp;2B(`?w|1L_`dcMcLK$~DpSxZ4f#r`O5z?Gbt| z zUuWR<`g4bQv)QdzhBpb@i7%hmO7ylGbZ`G{^ZW9qZ`S#PV$zwqsqjB z$+qkDX2efu&i=LF<$Q&|_oe3i*rqU-k5O^wo$nUf`wBNqXxCli9pbuLDEp~cihOWi zm4?m(9<|lovwbEX&YWGrK2JH+sxqj8Eyek~__n}}0oqDO+!M0PZN%GVC_8PqBNS!1 z;_QLTKkWl-r#`%Ye*c=nz_uOJO&FrI9ak@6&MJ-!&JyE!z4S{VQ}(4PRTGrePbV;? zmc?k!xl&VoKzAW~W=nEwgW4UoO4o@;t^f4yHC!<-sG95LTrsx2QN0>Qx4qJumYORC zUS=)tUHkDSQ+;Ay;H=wIH+arZz3y%5`mTFjVxzm>jW2PpIFr29emxO2fBNTVwwUj7 z`4<%uZxdMl+tkjP@kFxVzxOBZMO%2kH9bDOJTU6{cd7> z{E(SS!QHitb55S~R{0#JcJkLGrat>hHkl%JnI-1;_A+0IxwCDaWs65P|NQ0Jd0W3t zn$LNr`+;egLtp5rCxxe(_At4~ZE!u!J|}(3y;L&+=3<9eSCiyUi|-EDR?zZd?eWul zc?0|$b{IwdTDpa=w$Cy7`}wMmoR_}6d=S1=@hHDg*Cfl3J0?6FcX`BE-aoza$mrI; zBhig7ugL6_xpi@S{?*B%?5FZPey)Fgh{<^IwLc;(-<-pI@75SCVl3ccN<)oO! zYi#-011A4?ze(Yl#7))Yl(Ndn^Ik{sr7hjg&1809-^;Ijw|HN!P0;S&{5d*heaHUm z|7?!+w?1p_Z}@({Pfssc=}hJ;&I3LF>)vEaI=*ZDdd;r)g29GU@d^qey8V0By3EV| zeW>Sf-S;!vQ|i^`P3UfUdrSI{>WWD*-h6`0oLeqFydqUIOm z99AkPcbJ89?`50thplJP1y3fY46E?z9Foh}bXIwVTv_Y#Rs1l|pVja}nftJyCgu?saM1<$QV4Y0eIDW$OD24`zpHJ8K>L zxqjkiB~7giZND17IMJD`@AsVbg%a$kVp> zR;-E@ierwvAHWmY|E(~Bk9)DK$^)CjvAUmoQVc80{kGN==bk&W=gdRJpI+%(X5#jfkTO{m)~KhNvtvFv2)^npXW^clKT76{C#t7y{Yqd>Fn6K_|(?Bad#wttPPqZ zC2KEtqSx|NDz`{w>2J{;*%M?Rwq)K{kXpEUPLln>Lpe`=yg55#XR4{-{%5Z@PrJUY zsW|GMih-er_YA|i|5=1ZP0noE(ongh;C#%Q1xYtzFZkcK>PlaAaMJPG=Cq(Uk2bxU z)!no7LeNp=+}itm5`ovn*X?KjRC};hb!ozM4sM3%n`eB2RZ*^qK* zXW41j&aNe9+zh*?^*GPkl4r1zsXOM6q|Wp-nLO?$&fsfYD)*|KF4fCjy{O*ST2l0` z^JeLiv=49jc7C|E_C%q|ajVypCY`YKW3%6R>;7%Q@BSA%qc=teJKsJk&yX>RL395V zrFlDJ3+@WZpXIPJTRm-mD0k}WccGtSvX9?3V~_umy|qto!t+zo3_H@xZ@S0L^|qMd zd+LDlB!)ogIM;2Hc5Pbe!;l#NkxAOgSNG<<^-`L9Y&-2js_xmhL>JGfcGwUZxXi2K z3zHq+gO>dV`0ujq=$H~(TDJdN;reZfFMsto$H)jgEj8|8Qv6q={O?xz`e)(N`;Vo^ zwuu@XTP)+NvX9rUeBtMdHSwV>f?3wxQVNUob?XycF9Klkt&=ZQhNW- zeVOZhOXpmA>v!g1a-q;i@$%$53m#spS?jjV>y~l(b&iSmch|IJ{FT|WwR$3#TI5-s z12t22b$E!z{4H+G;NQnR@z<)2>yubcH-z|A)Rtv!@`$*g;(Js%w(Uo>lJL?Z`L(zF zdAF@x|Ni?e)`%|NWoG}M?^ifbzu{`DV{L}yTD|4s9kT9E_?m6`4l7>~UuHYu8Mk5F zPc^ow6-zYNt*FW9)5=y$cl-LU=Dbqek4tYE%{qd-vZjRpYK(0ShOjOSQIH2I$P$(-Ei7dDY_7zlfIyGfw>$I#yN}8fj(AzG+2X zSN^#+rAAf8-61a@I6Zjq)9HCcRq!se@219i&*p~*a7*+>9+YTfoS3uSNNSnM=Cczx z_Jw%xbFp=-=`od;>}_pY9-BJTlYK)|sNhB~CEquUE$`N_?9y7MJ<;8Jnqlg;jng$h zt1kSx`BbRA_0=m^tyg+~Ey<0Wnf20ae}~JZ{rkF0W4;Mi>bU4^D|)K=h*|t(p3Q;j zVXHT7dE}OwduZ$5#ahiqwFU=DHa$(cCdwVKbsg-T5{nPpv#zx0lru^)7`Ju!9J@v?fsEjt_mAiha`B|B%TN*E4 zz|uV}Q|aoQ8R|@nCdo=!s-Nsqcz5GM+Ju=3T@0+nMzK5NB$q3w&oAA6a1xW)sk!l+ zS6QxBxowhCEu$f!RQT$=?47VpI}|tb&fn)RpxUzQx)5jUk4r_n{Qu5d6@tE2@j#b_VZ%34#VtvVF|1#ESbM2HDvu4T6Xg2*hb<@Gy>OAMg zO7;|{Cx837C`Z92?TY-um8%zT)tOa$_<(T4?4Z3TJ~s)5c(uNX+sE`(EbEep;@zU! zO=;(+PXFh0@7Fs~haBFV2z2O)~>h%-<XAxD(ITWwU{M)OOMwC3%wf`J+fav_iOC=-*0;iQu1f7>I_)U?G`3@B_PXj*SO5P1SlKsY z%~6qO=1XFw-+Fq;&t-0V@SE3wMbKKDJ>jGK>= zRM(!1zE+&^e(qVH2NKOZ)53lyw2IjNImp9j;9GH4d3yW}+l>yrS(8uqNwhDF`tRJL zCAs(g^_pn;h9%RZ`~*z|J0yj~COfQStg-*rt0$ECt-Z}s$sYAi>5o60y`080dHswz%Nskt1WlbFpeZ>)X1Y`^g2r}^PmHRB|E zl!dQ4CMPaD8Qx*i{A#0T-F<^1U40ut$-b@rQT_h6phxcBWe5>0`$y$jr2_tv@ zPc3a`@y)GbRcaNFzjI7~vF5MKc{!zk6%QjFPWGqY_H{i~csgLyxp|KzPCY4{RLVcm zOZp`I|m1!>3px4)dZ zYfZtV)pMP@TAv%}PGsw=y!V+kXPLi=U0p5C$2ezR>BQ3ow>_%A zeaM)7FkVQa&wb5qm5lADEY91Q30KE!GVQ*ke#eaMw8r!4uN-BBU-LeX*{z;idT!bm z!&8+@6`sACeaOsNPNIcnUZaV{<2&99cm7%FwdW3lwnN_=wi-rNDF**{%cORF*v+gd z;G?}b%Br+z=Ax7Dn`HJhYA5wfKj#y)=I-`8eS6y%e{FBw&NuydsMmCzdvo&rV*4w- zn!>jK;$Tiw%2^u0ezS*v@smeo??n<_AKoZW4E?tGwf_#T*|wo}hib}m8T@75p7|Rm z^6bknQ-CkozO-Y4GI|J>4d<)M{x1UEMEr>~rwAIY2Z=dQlzK?51ZD_Z|w%)R!E zuYdgpgWcyOv_u;1(?1oqWqp5N%bePvxah}&cZ|wrqG6v!)^>0GV0k-Ske`vKZ-#Pp zZ(93IV~x^36Q&gvXgK{iZMCD-u)w0L*1v>xrXE+mNus?zhta$YiKX&;Bdw;sel47p z$XCEodB>nm@8GEH}TsF*0Vb% zcw{A=(rOeuSx~|Ech|A!lKZnPyt5n}WX_8FonLI&c;35gV(B}k%?cM;pK{GJlRsn^ z;8gLUm2u5X#y#;a+*Um^PIW)gV-M}yCwXrFo7a-Y_22ZgzD;_g+I+?DVy%|MjJl9% z76+`J2ubfgacLz}x75kI?Z=LB{0@=j7hTD{@l3KZ)0c@`Har zWcmO8rKf6rdA}B?hDG4DhkOhxl3sdxb{sxv&HPTyA_UCcB%@b#Fa{PSO`qNQx@{_`?8{)--I{qJ2j{K~=NMZIgj`Q^kH+)Fj zfBlE;*x9F4k}D^J?*)=!>FlHS)b7uLS3X*Yt_9W~{%v{l$GWnrnN?MFd&K6HJ~q_%FlS$?s-XAAROgO)Xx!pAP{Ao+xNnMgB-i0Te z-7CiLEq-R>Tvc|1V8N!D9~)#ui|;YM-s~TFzmeU7t@3%~{{Cgo{VW+rcA9!jC^9$T z(F;DiyF&ey#~v#dC5a0q|4LpRIH2Nxd42M%9oLoXo|pN&sH#W{D^ZJgDOwn>^hYq# zsN<{Qe^cG5F;;A~cIB!u<*}DuPt-D6RuYq3{8>s@M5xj0`o1%X*^j4PS;5i6d{l3l z!=vTk{yN?{)yx+IfUTb_5{%?(#r-qn&_p>Vs=N~YyUM#~gJ7`+s zCHV`wHvO~rD9CJev|Yu1g46cV-@Q@s7vE-`4tnx8D$MW8|DgZp@)YKLILiO0YJbGF z1Iaa=$7eP?ZarG2?s#MRCl&o|MZW{yy!c?9GryRj`pBb?x1CPA_bO_pGv=~0RGrFQ z++=W+ueRazssKS zUfe!4?T#dO?fA*mHM@Ly&GFIli`l%ig0)@gb9r5EocXizWoVwHMP&zf z&`H)cjZ#-vex9=Z$CJInmhD?3TvytZ7tTNbb$8<9L*);w*!GAS?N$86`7Wx)Y~eL? zd&$V@_Z8c`Jy$xv5OAN6`_FSC-}dF~i|=h&@v8P_^O+c-yW*W8cig`^dcAp&?Kqi3 z>ZSDE-G3Ovk`30r zIDR@%;HmU+qpyzA+nD!z-#owP0e83}>+(Nsyp}m%ugSQk{`eMqbp3y>EfprAyArK7 zzcXGqQT?u)biUQGXEW9~Tz;Cq`q$3dtQYoNGff;07&^8z8T1*}H=K@;+xT_iB2&KF z<*85iSBENy1blKhbxkIX`}vv=K6|PJjrc`VOl-K5#f8t_JH6t=%_>C}>nTm~Vm&N& zSwB7eWAqbOnJVQ(O)=fTZ0w(T%={S7mn#pye5(0dUibWO#-b*VLIdXZg^6nf4I_8_ zoU%SinMJ8<(l6QF)0ccU-@onH*SB2zk1r_kiT*VC{I=Uk<}aV`K6|SvsL?li#!)*d zk$siFUS29#@$|(-4(ElR=ih$%F;nc(x7u39M3&HbJ+W1Kq3Jd^+*g+-F=?l!2lpwb z_=I2WnrnPlb^fW#vrVsxPh5UiH0qg(sfArx?z@~Ox5ujtJoTQv*pvBT*5r$;qo#lU zsl`;p6WnWD@?W{2{nEzJiru_nYekrvD{E$l|2%8H+`IC4%Ay_W9&5N2RDuK#yjyZv z@R^v{CDU8xZi-6r9y;@%4cZ z6?C}yHTA}QpK1%v%5AJHVL^)Xv#sB&HR&$;@P5_mlM*UhyCYpU{S1D&htrwwq}TOp zd+tt>kAGT!a)SK_{|Ouu1i6g&-3b;y9C_Tl%Wi`v^DWnXpUr>R)LaT(|L+rkt#3qUiHv!(W;=|%Q8JK8}%IE z{r6?*IhQXBL|i2q+~j1UEPv;()h(NpF1w2JgT|tFW-|KQ&hj-bnmhmb*0neGH?j8J zh~-%L`02#Ci?^~%{|&den`4;DcHb{T>0qu`hvT)LlnaIJQI~2%bq)316}Pdw{`hw= zraE|HYUh1r=DA1IE3SE**kYWK)%GHAQT3`hhqJBLOXt}=y1uMcB)N$D$l2Qw+aq7x z`2QeU;?f}j$4d{D9e@43Z#*Y7Jh%L0A6xQDza*yB#bUE8eP<+0ReXB6Vw*}YTM%c) zc8{QlhujA9>>66~P7829J{xbbKu<(2_mV<>YNkmSSK8cGDgV;Q4|~>s$e57O^x%cM=A5+M9JD|BGXF)h&)QF=rnx`OzdiGDcA1qp*FQ%I zgHq9R=OjGslQ;~yJ-6M=+4%hJrPGpf;j>gKo2Dl|Xko~Af01T$d5wtXlyU(%9?qx* zytj8hmAZD+N|aIJ{^`B;yPW60mM&=bZJ4X@a>JWP+Cg5D=0y)oyKbC&`G(P(r1c&`I6&%dN~?Cd|4~E zw!8l6y`G;r+3M!iZ=X2C?9Y^aIy3at^jBAR-+V44`FPIXt3iv*INz^d&r)o>L$@hv zkJzuSu!>8TjP+gO_8E*zThF-NzTo-)!}sFfQU%kRl@1m+YcQ1UD39PROmu2*mpO9r zrR0o{*%{48j!zW4CBr|voV(X`q95Nk6`o(Rw`vyro7E^bOZ0tA1^=QYtt(|1u4L-v z-elanP3uRG=*gamHU4|oCW!`}t?7PtT=3GowTZr`%>Fen&->XUCKcsUVqaOaV_k#D z?E7o;ROfb7iwHZFF|VI|v}mpSh288cu3cF&qdohMI)|yfQ89<2Wzaqi+o}K^{rPb% z&!r2zMC`vxyxKUsP%V9vgR0Am(hX}?Xol8Lni0IfZCm<&ruV|thu6H}2)e%X%po`X z1C!?Do_n}6diELny;7^UXD~_1|GBR_vr|v4cK2(}$MgAkllFgktvBbK=pL6JaYsDf zF3#5v^ZnDhGjSX1@iPi}0YCI29i;v|=C)aY-Qs) zFLI{q?LX<2htKW#9?LG=qio{m^{BppagV8bF7K-Kte<7s+FQT85Qq}jOuG22A<(6{ zQ0?`nHFrKPbN!dhbmhPK;o?iK1tx*djYY(x6dSoreUCj~$h|52@s$tG_E|OC&jlv? zX|1p`Tz9@=XR!WNrrW3O7Bx*>^V8?)hP!Td=NLbi&HcQ#Jk751#_t7zJ7PpM%^K#v zw`D8+_CiwYNZ2`+>coaqEGwm~t9czXdf)2_{kD?VZPAbEbjS<3-YvOwQLUm^q3aF# z`-hGDH@xQ8*qOK>L`KB;O+;ICU(gm6H;&R88R^%JEt6J!`R~{I`4``D?G@c|JEK=l zT5ML!>d^Z0WMH6|<^M|Q^vka|MILVuliYUI$m`j+j+!evibof-X{oD5FVve@F-0=y z;PxDoZ>_={=UqN!i2sv)yhEMk$zf63my7@88~>fQMdh>Ql!sgbNA0C|MJT3U(%oeA zX^q6;-3MMf9lGRk=$z30mvh<6v-rPC9B5xKf$KEa0>j#q!g(kE<-7^mz53VQ+x2Fr z-(2@@cz8VZXUAH<)bgnv)fZc&UQ?1uRksMzITuD>DIu;yZ`RY|7CQ1TJQP?53GdVtvF?Ht;bp8 z@3X)2cWzy3m)f^RJ^zD#hyqum_xRk52c`E`Bxc%H@+_~@=-{DX04^{~qI-cOVQR?vc z+so}6wG27_+FxCGU7)5aPVyD|Bmdo134#I~Z=EJQx%KB@KnHscSMt^xRvC@W(hsU< zb&6HaYEsy|j#qp_&gDs>f(?sS)l6smrWMMf>)Cl_i7&U`k%;s2@|K-q_~?7$Q9b7$ zPSvHyVk_*v&wTT9@ka5bqOx3T6h9ns7pdD`;#Mj?V{SO3qi~eYsn6Hm`Gho`W(jlq zd9-7mgM@Q~kk)}Ue9O!~Z}Vs}n95x0HT7dy(4>II^XF>Hozt^xyW?J*3VQHGI+*p) zSLMU%^F!~*v{wk3Fnrc3xuo|)GJglR;j7ojKL^ZGev+S_*PU&tnAk2R9dyf=-K9TYe#ksTgdp`G9P|4(-n{~Y2>zB{2fN2*OY}B!Lo7%u$ zw&wdP-j7Td`^rAEsvn>AoyDqCb?4pHrGD#k%_d0)I_|x(gE3&Gkxi-J_WV7iQ;wcY z`CTL!I4}LGipHwRN7uaCopmR7Nv2I|h~AY1_OnlZf3N0!v#xd3Um?j!+CJ``N1T0S z$|RY+6hCzT-+x)=F5mh^$<0&Po(C*5Sh>&q(7W)}OHZ7?p7?x1-y= z@K|pz@MG%%_R3kcQ&wKMbMDxgfR|}6SI;kFIxbL3Qp3bqJuiq|zev9kHm)Crr zjjv{kzxC?alxcWl{_TtQadwl~%vSBq-w-w5_Tf6#iT3POzn6vYx*Weti)Fpz&L=jC z9E`7uv^M3}$LsWH@=NEJA9&z%xppf1(l2iud$%d4ihld-a@?jBM75UNwyDVEns$^OB0S{r@&RE}XM*`-}RSk&{_1k8l3%(_q)U zrL){UzTOD_NnFGTk@=LdGmT)9tc@Im>D}$v2@xZ=iH#A9il6~1pNDJq_X+)vDL|0 zfjhl4WDD-`<#jr+?eO@zm}_RoE*Km9~4ucn`P?c;*AKfa%nDEsy0 z#NkPc9cukW)=&9-a24mR)s-3E6%%r^F0iin5ZGB~vz3SYp`K#bbopO9nJe4N{Id5< zdU3{kR?cHb9aBN26tP3{M~zm>GKu-Sh|LN7vt4~_tJs-sD#=mlTHiwpqE^TrU8!T` zvHoDcai+V%XaD^9UZ2)p;92bc=iRBO)q(X|`=?FfH`z3S@#@>a7@^4UWMj|DuV)pd zcO7&z-e10VSJsPOtNIlSufATa=YM5E*_rP`p>nK+f7ngu^4f2$I{4Gy@nDqq4c3Ac z;E^+yufJ}Yw<|UD5jTIIa@(zKhSxtV{E+Fs#0K3AuPl&*-F6sK%aym|c$LuPHkyg*LL+iFfzlAJy z9$Rx|B4zRqDE=tjlzIR9OxZ7tTABy{DGPUe&%D_c8zBDR0{7QdWt;9^Eay<&qr2hD z+;39hQ7h!`Sn8@?3br)wF|sb(^3TvnaA)|Q9R1@B^(B4(<{rp9xAk|a^MhjB+{(3w zuG$!8g_QiAUc0%CV^7aCUbCE}tD+LDlP1kR!dmsM{N@{jFx$HaJ(r0zscg_PzheFF zgPBY0%{x<^pND0v43E4~*z~4Pia~oBn}&X8%I9~Cz3B&L_Z7F?d~0*-#_>;o%nyY{PI69@e3^BB)=|@$cVF-6o&IBo)<&+r^C_=6)-K$p=((g}s+deGaf4#tK{p|Ct zZ`VCOt+H|6-NOsTOn=GkX0=+9*8K9+m5>7;;~QeHuVYzt>8G3Up?8i|l8fX2ElWN1 zW&NGlOh(DJ{{gw34$)2i6Hw9m%53YjL|4-vTa>dN}>4fi&A%sjDmQ_sI$j$&t0 z3U#t{lP6ESV?Dj1f$MDL7qf#*RibY;7_`ruBYLwS_pQggkn)|6)XHBSj%Ng#i@~yYOFn)b*Wcx~uFW92j{y!cOSJ(=bm=Wa5t}jMlHkNt(AStBntiqTOh%K9r*zwbQjT{ji7D1@|h8BNO79OVj!6Cf&@JT<#-w zQFg!3;sYCIiDa5q9~FP$AbIwIW76k>)BXk~-D^{3Owf4HZnauhPH5)$ZQ4GUvQw8i z9};)gPj3_i`;uNvSP9`%+gu_FRu(Uea8nN7m<=mao4N)tx8J zuqClrHmoFW%&x1gBB9H z-P@Uh7R@qy|NMUOnbXotkNc~Z&6?zDHqU$+m!|Tw)~6TW%LZ=cFZzEdZB5$j8V>&Z zCM9ooSVis@+%|WbF7JWMUp;@Bu|5;rrrF8d@8O&j?w8X2;iKT@*+1JDZMPY4op@Fd zYHq$VNvJuw_x*Z>Iu-WnnGtg{Gy=A(UOKaSk6Vt~j@lj8dO7L(ad{fy=A!(?J_@Y! zpX_O0)9!F&vR!P&UVoVt+k$q+)d+^JO4LbEm)^N;LZ^LJy607!tFKuZPqBTD%HPLy z`=$1j_wQh?Tq-`XhPwr8Yfg{uQ#G8g{Hl`joDfgq(h~ z$IMR9IHHAp+shYOa~t*?{h#QhV_tmWTL^!9(H!RL)7D8_6~6lZ6~EaTbmi*oPZu&p z3f|5y2(*e>q_z6>MaR!Q@vqizGniuitUs;1ujO7#xu0b1gl&2}Y;HbkdwCzSZ76Q} z=*i8#_CS8F#zTq5lIgwvO*Wd|J3|?x?s+k~&hx#{J)7hGH1<4hZuUoo2W5U}tc&Dq z2*2dQ@I2^QXf9uZzg+s&%cYr`+YcR)d%g2U@A7kN8e#?cepLFtt2(_x=S-RGl{g`- zZdK~H^OO77joa*tstR($moyNVJbGXtz z)}GHfe5Ayn<(AyLJ4s^Jaq`>GE|xV|^JwQY6>Gt=x=^)%;HzO%8D>+V*35{^z5~h+^X$)*J_>wy zb*Ti?pSfyt_D}y`=e+*nHp`nA9BOVDec+h+@bv?;)f0nqOWT!HT2CAAy}OLbLa3De z$$G~9GOtrb*PQ-Z*tBwW`=heax8@(i!i{{zB)`n~4Fd+QehHixm3V44mF+Et)^o*eGh^M$v%S z61x-c|CLnS-+et?i~9rfS5@H?7hbQFU(o7i^w79tpT}06TW?Q%nU)lEMqS$7bFw?* V`za4(_ReS3dfCdknz^*>HUQ4xvsM5A literal 0 HcmV?d00001 diff --git a/src/lib_srs_extraction/test/srs_filecoin_g1_6 b/src/lib_srs_extraction/test/srs_filecoin_g1_6 new file mode 100644 index 0000000000000000000000000000000000000000..f0986d068b6793baa4ecc0518d6065d256e47f32 GIT binary patch literal 3072 zcmbRK@$z!R>DQ;IO-=6cU%7_=a7K^+^pc&d3;nF@#iiFon- zcDJdWkri5GUD3AW!-n_iQ)ibu?zj1^vK4{GK;H*KX2)pbc@t`B`X>tUK-`i zn5;cH%;}xBTG5FDL&xdKGZex!G|21<5E+yLW8tyTKB1Lp1kN;QR=zx_xtW9PGEYpcr9CW-<5VJ z&xV>q3x7I1jKA_)aC)1hm&d{g;i#$d5nE1KH~bVkpyd!fhlSbV$}OwgZ+|tIuk*H7 zoOts7Jn`x3+lr@@Jlx|Op!+Q2%8aNc2j5`vb(L?9+2uDltq$TUc`1vPFrL*W!KL=EI;DqJJ`9L8rH6#yw9qff%$5} zW^9Al_IbzO`^= zk|ygDV+Z~cFMa>U!^<|ydKSMD`en~4@7weUYU{Z|;aU zRAEOVW@OUSLsn-m~@rDQ*gbwVd*o! z6Cb>54)Y7@6Hsn_AX3Pq0*Pm@28Idi6nO1K0D$XBYa6c6`1S+B{RmWZM4Se>gt< zczBKRcUHFySGA-TXOsF$A;nz+1`n?v^O}@-%y_-e7H-LfH#mEbd_JNlvVQ-Kdfp$w zTgy%UyZ_%C+PyT>=klg$KJ-Y%f8RSZ4vwr>? zxzg%*@^|5=dG1y_H^v3G%lbxsez^R@o`cPz#d(cQyM-1^ac$#Zw=4_~T_w)cw)EDf z`I6W3oAna~wfCRQ>K2HbeDL7Lnw`f8Ul7H6t2{C94*Ws2A9tSx!IR|`C@HAiwwn%bPpQFX8fJgmS^$70yh>$w7iTmoLr`~FGYw|-8j2q-Rrk5 zK1E+YcPF1=x^=KFbK~I{L&LCpw*TtPZMt^;z3|r7cuV6Fp)HYVOyY;~WCHW%^I!Cv zR%I?5G_&`XbkWY1+kvwW3pC9QoYV0sHR`y3EQ34u3(0kC3SF%_zqiRAnC@bx&sn=& z_D}xNJsRH=zHCW9m}YXt`pC0si})RGwN2jKtY05B=h*Q#tEO#CtF+rx;F98RbK=d0 zl=E+1ca%r1p2Fg<7isRq#KLmcFJqz9hv1#^F=8=X$M;SxDdd_Xm$zX{4O^X>3TIT` z7tPrV*ZyDZxNp~2{?(rxOS`VHI0^hyUVlMOA?9|-xgTq|1fS{1nSXhpc*ZRKiEz-0 z=u7L>Y#Z&jX)oB{uA#oy^uY($inop_+4DcYx2#jo{ce7{ctwh_;F{9kd91Z(8s{a> zT6eW;an*X(X}+v#Da~w)>MuM^4)K}BxMT50jW?Cv`9UXko&B?YSykKP;Mm^z3(K<` z&UN&A9(Org9I=NzE#GflRc#V4uX?GQe{sLX0W+I9Oi_2YX>sH(=$+O6>&C_C`%&i^ zd;dmV&-ckN{ZO~OAieU<+RYxkZSgm?Os3jTD){}3c}uRa>sNnvEr0$u^S0FFzn1D2 zw6ME&T->`+iBrdN(+8~&3$8|PU#PcqKL4cFziyk0jSntZc!~e)Rr!q-ul@gh*6ZR3 zHW2V+e{$ekV(C>Li=FdBR-`dJe-U-$@cjR$Y8v~Bn)Wltmu)&17F@UFLk0Ws#kZs1 z&D||3Q7`wE?{@YizfbmYj%-d+Qy1GvoQ*szCiUCqZMmgRz|oY=h8kxl&hnow;V9#0 zVz)%)Y=BZ~k~NF4N#KGygJ9=Y{c7KyRi8O_R0+l3mX7%>CnO!@kR5%b_haGS50kH4 zS!U-y#jIzC{Dk&pEiUGK3fjJYjnNx3*jIMi~ybvkWbk6W_Pizj>1UbA{oH zr?Wp5HQC+g-RyqsVJ+7ONy*%!(oatbb-8TJsV-8HvGV;h%~q~2rPbE4-&S`~9!EHr z!o4X^?}*O1vQJd5>%WQIr0*75mZt7PB_B4F*7qhAgr3_Kc>DQ=f6AggVfrccSCe=8 zFp6cZ&$^trK}l-C@^iMAB0I$PsU6MaA=JITF*&)BAGgYntI2LWb2Iefp0YP*7X;tlWAf|Ny-UtXfcV5QJ^7b2cZ8fVe6?_afs>}W=aLTRzX-%AlOKS8cU5N^9 z+Y=Er`)y1L;{$R9pK9^SJ(4bZHLG*eqSmm*+l#bXcs)LtzMcGU`p-WFda;3>u}k=W z<{kHy)vy!r+q~4j>7ionwS=>7H|K4;U^w5R+>VJT9lN z&RLraZ+a}@nJAbr%j?Gcyhjo})|-|^TW(OWGrcjP>9v;nfjhfj7`%^5;&hEF)!DAk zusT|~J;-B)=juAy8}^|Z@!XD6wc@rFtt&C-Q zo*8p^&BnWJJpH+^e@=Rz%em;%rK=pNy|qcc3126tyxo82fZY1U{(Jl1bZchEX^EI_ zS*lSuw`1b`YtEH%-f40ddT(ue&-eFrGh^=26eDgy#qecjcfGIQbWyoGVb2$n(%lsq z^#z+w2s~Y}V(I(KSH1tXCf#1XNcx5PoCQo@KIi{G(eQl8zK#pE?> z*ZyZLChGo98Xg=srWjs0x`jRXJC6WZz=7@c0KlF?7ymDXSuhvgbq7tgNSMHs< zDz3%&Nqm83n={kO?Z2)I_r9t!xxZlj(u*o*=ehK650IJADciWX&Q#!Gk5lcf_DGXW zrdJftUAZokow1-@F2R_)rDx{4-we5xANTfXyDhx@L~>treip}i9o=~uBBx!9SEf(W Mm}F>iu;kii0C%axDgXcg literal 0 HcmV?d00001 diff --git a/src/lib_srs_extraction/test/srs_filecoin_g2_6 b/src/lib_srs_extraction/test/srs_filecoin_g2_6 new file mode 100644 index 0000000000000000000000000000000000000000..1587ec946a6109aa91dfd77871b49b4e7b7a9446 GIT binary patch literal 6144 zcmbRIKszC*aDGDVn#&71)csQ#fAycj^N?jeR}}2~UX)f4ZiYHI_xY zj>&7$rVssG6V*6a)pd^w1Ri@*b>)|XHPe7t6WVFsrR#-TnSbL)eLfihFlV z%vK8c<83hG%-WxCB7(Bsd}hBSr)-}p$QtsF#f`scnb?;L1yiKir`?Nve@jy`&w=qMy2HLUhTbxTX(f=wh@Esnyybl)91W6<+oDc!ukJ~ zFY`EWxF2i&NMf<`{AC@}jaAdHPo5_jv2Nax`nODqF2aX@g_uWcC^Q>KpYJrx;?+Gp zPi*TgsTmsGDJy=6)n1O7V>Ta<1<%eHfAjy8y^veKL~uiy%4F%^L4DFfGH8p2BQrMLU zuQN++MZE7mTz-h_aP`hQ5BA2Xv%N}6GvD_dLc%dode!D<+{hLK~%EvG1E=|^6WK_9cO|nEb{*i;i zg}mu!*GVi^*nNFwwC{zst9D;sPI9}y_Djfjrd3RJVsYykj^6*NwD9|TrvJLr@9PBL z z$QpcoC4Y6OcHVIsQ;J5mw^7{Pj#yhAnVAYdWi*1)Tep+ah9Sx0&hUmJSDZpZ}BZH7T$rCP*0kZ^&L_zWe`G=Q#~Y*Vd|^ z*{%LpYH9iBW0JILtb*RjDtQ+&00B&1cQI8MFT zTI~95NB>ct1B=TSd8poekQ`~wvIUlxu+qL3@n>G8Z zHT&J>&pMze(G%f{e@*p9y?E$+4Q#b?DTQA{Tz@QyI(!YaN6>z9C7SZ zlH(p09RKoYcCWmlZ^6}UbUU%XTHBXx$Xqu0HDxqP2GvAKA{SO`GR&u3PA#QP5HWw|VCd z*53MYBD3Uooyn){YDM2(wi<;Uh5DN!#C7@l8q&8}z6_EIE#EO~itgQ8Ut21cxVrzp zUK!cOaU?Up^Ri&a(`TDr+shbLZ%&W-P_;4VOHSDdm)Gmx%;A|7sb?1Q^hWwE3I3qV zyUc$nxZIoIbMsu!R3_$#iGl?&zbEW&TT*_v-*Vm#^LgyY9tuY}yjZYRu}HdMXx5Gi*do(siKNcwk;C=YI9-d?xb(K zFEd=QQ+Iwar%05;W{Oe7p*sCS)V~mtwID4GW|MvQq4^9;oJ@R$XRW2;ZY>iImHoyh5?+uqyYZTQ#r50#Cz+izyEt8AF7VaYuRUMF zHFu4MdI~plZOg1{uaqbMo8q!fwvyR3Uh1v+r=S9FoyxB1-}|>%U6ywgJXTfr@xNRk zuM5`)hiad0=0X7sHk>ORXJ{LZ;L{Y90m{Fe6r3x%cbR;AUwxm!O;Z58wS z=?S72y4GLG4bPlYcklY5k}pr1B9F8+h*_3-{k8eb8)m+MZGLXS$weuSwQ4H^Hv8*n zh~{bgD;q9e8NfJK;5xth_P9?HPnnlQyu5kaWwy>NL%$hi#iI2=Jt}8nws-MeDM+3h zSGAm7=xc~z*}c0{XHGq4{B)}-_k?X1j$gOBr|Tptv@6@D&8zB)?c)n!wawp{-GX!r zL{6k?Ep(Q@Wo+1euy9?G`SwZm)80MV5PkXPdH=3_o~o?430|CXU9tQO+}n@7n$4Jh zdQM71-Ou80uWv5kIKG|lk~)9Wdh3G`7yk)on`pjFX3M?s_TGt2k{dhJkFx0*Uv$Yh zdy%Q?U+|-S(+@3Jwm;*J$(g`hHnWLWr*GbxBl|*T@_pX8eMPT!tds1Tpmn7APx#Sw zff3jC2e|#@W;-U?zjKH5hmddU?n-`CTt2Der>h0yPqkMk-W4W}GFz ziebx}zbU*;rh0FVtvlSWd-M9i9)1Jcu5$;^Kb3W3Q1Mu^pnclkiAz>r>pwZ?YK}*4 zpkGnf$IY{|E-OA;vHr@&E6Vnr3m+?Rm!H0Q$uCUP?FH9`k{8>VRQ_DoydfYq*?H^3 z{9mn>8ht{tr)^UeI@JCbd~>p_?w>S!dzC)#AL(_6dw;T?eCyqi=o3=E**ILX!a@9z#ZgI(r9PwTqAf4nQ=+{d+anVPgy7RU4njqKqcHdi=0 zESz?BfBbXJ`<}0zg*x}lyLYdmLwtR{uZm2D<;G>*+}esFch>efmOj`i_`<1Y&h1M= zk{1hPj}~oyRPmt2Bg`scQ>@{Uc~|&fe3zWeU>+C$qFc~9yXds;!HCLR+Nv@#lRMZ8 ztRvg3`kR~2DST`Q3S2YMq;tWCC#ETel1qO1Oa2zCSu-W#*KR?f-N~9dGP@o(Zdp5> zTYt(4?s z*F;JDjqdsI%zD$8)L(bi+W+xQi2AZ%&(@{vMj8cskAE|%d;G-rLy?Cdi@?&Sa`zPf zTo*9qj=psGvHaoL>+`o7WNwg~F<(uR<*t~%F30knZj)cE)fVl2!nS{@^@5$;RY&_@ zw9irzc#xOkw?jB)$)WV8eDdpl3EcVetz*XBm+wU~Im0AYExNJY^r69IpRd+@Ts~hW zKb-9`d*j6WzcsHmEx)j_cSj;i53}T<`p|xkRVg<2+rOoi#NPexJMS`mMJC~l z{XKT>ZqA%dVc%o@H~+Gg_LrC%*(3Pyv*Yb=`(FIvn<>ZAGvQm8u~4n|J=L?CyG=`D zET?T^_IOk}!G8wptry|8$(q_tZ&p0WSf-Gg@Y};L_*HR3+OB8&{F%RUXMbI(6}NUy zgV~gQPrue*;#(3c5SX0%`=I*qOo`W8Q9CajJAFD$iz{RMgLBK)w0Y;;n|qDtLbjTL zAD2a;z8bGLuM^)L?*@y>N=b(QA{72Hsp$S<^YG;e4$+JDcGO>(Tx@kW=}lb26kqeG z^>6oFiJdrMT5E+_&-5d^GlOj&AIPbVT=aapLX^Fc`5u){^UTjIPyD&2wb*`MvSZm5 z*CrVY{_`ou(tw&rAPSC;s` zD`HJo=FV+F5!W9taSY$=Qzj#EZ2Hdos-Mr6^#^KP*PNhJJh6ZFyt1A8ce>Bt;Luqi z)hcj_bz|y_ueMtkICbya8++pRjyZD{Zk_c;_u>&jrFn_G5B{v=iaE=EWsS}H3b&L^ z##@}2eB{!6+IM@M{I0X`>}zfLQ*0N0y`Fi3;aqOt!fR_D)?eGRM3U*RCf8e*6F1v7 zaO--^dEC9_!%xsl0RlDx6jotR*_y>yN&%m-{T;wbJv%) z{^Cs+jY&KopLJ=4z#O4@+tyuP_-o#T{;l@UnIm{(cX8B9yho=;8uMIS{pX2s1*nNUdv*IXPkCVqLRyTs#C zr10rIf7JwaFYTN=A^rNwyLJ;zrkaQbD2VCGE&I}O-^kNUbMx+47Ihzih(3oo8ik); z*T&ZiKX2LR#ol4!6B+sKQcF=;&g9v5YoZRytnO<5ezM$OT0_ia*+#{kE8|YQf8)}A z^(pr^u9DV_^12uQEOz9cDL&%(o@d*oRohdTZ>`+!Q z-fNgG=aiSI7W^US`cqG_J5mRPHo0bM*F2JEpXuQun^dygZ^vW*bLr0w!+!70_KUNA zbM@}>>|QVJNftuaOBe&a9?SP6uH){P>zmE-_HEC5Ca#-8vp053U$vCMa(!yFw))3k zU93!#Jk}*W>%I{>zo~t%&7Vbytv^`qh$dP6Ubl{Cirm(g%^ub-e{B}7{P=6>vx%Mx z7kY|dcOYW$*rrdD)za24@%#jd|%`34zq{a4_oJ* zS~F>;NDVJ@ykV58k#(l2j!;3g{L*u4w}dP>!SGG2UzWG+vDca7S*LHFzkSqg$L!>3 zSznKBS>EGUU-!1--NNht+ng_j=WY1+$uxh$)YVx>wjNDc(p0j@sd1y$5@wSt26lHn zRr&On`!b1eJX+wNtF*4l&%dxVT-m>QOOyC(hZMJi`VJG4L|*3KQ`xXm$aI}uNy=sM z_J<_}Gmo$6dXn}@;N2euUK!DVZSplq{k+2HrqJ}F>kScWve&G7F8Doizismb zFP^qz-=`+N5?h$^<(G5kpIQ2BtF84#XMKLECHyvjxu9i<;hpk#Qge6c{;gkC%R0mC z@4ft@uc7l_vq)NMn@9ec=qkc5Rk%`j&ZB34y)X0%{A2Z7|3xk%=&5a=zfol6de14p z*_rQs+v<`s<=WS-`PmIlSGERgaUDPTp;pnun6)wduiHg7CEY#20mr0wWbTWcIpbCH z%9^s?$A@lu%ZTWB_^2hZ8PU#>)Ne$zE@H?l*h4{e5cJvSjmRIEm_hPW{gex*?^gd%;M}Ds;LMnsdPd?I;{w5xuXd%}_kU2g>*u{0 z9Wyx1g+%Togz-s>R`FYA5xN;Wb0w7N*BHKSHiHnr^EMtX1nJXgirl?ddS@P>6WYQ=c?XyJdf^N_i6Et!^Jt4 z633h-?+m@4>9a2VP1noxb6;=jt)F#WIc7oRV`o)!nHG+3*D{0+@4B|k;N!oxZ=&`& z;{X;r?Wg-SK1v!!9_`Rsbo%acguP3}Is?CLC-!?ZZhG=!hI--5Q(Ru(miJ6O{o-%Q*{JVRwCi65UlC4XdvJH^ z)k9hnSR=@p3rX((l>3X)3nd*i--!-DqF&!H;J3Tgbi0kR?->^_Y zwv6pJE31|i%du~#e)Vvzs5+Fk^wy?T`7h0iZ&{jHwI~!XJACJ$&W45Cf*fX-Hyr#v zMZWT$;GVLgUL)D#EX4*&o8yw^Wb@=#ywv${Q*#=pb5Kj)q0UM2BD{A*e+Yf+_@~eE za_X^D5vsX0e>gVYonj`PrRDhbzuwuI&%2da(l&CZ+RWX5{`KnVQ$Cvh-*i%f=i}9b zYY+bt)iD0M*R7B1r=5}c>5YjFH75_W#2dBe*}OE}^6yM#_55#K5f&Q3kymq+S|&Zn zt?s|oVH$c}?%4coy-x)G6^jcnR<|*(vvlR06l7o(s3B8SxUImlBCRxX&Jw@bnKA5s zlS<|reIWFJ&j&s7L1G*wdkH1Kn`bm}Z3u47Y-!8oN;Pq<#w_Xd}JCp%Pc;TJ^ literal 0 HcmV?d00001 diff --git a/src/lib_srs_extraction/test/srs_zcash_g1_5 b/src/lib_srs_extraction/test/srs_zcash_g1_5 new file mode 100644 index 0000000000000000000000000000000000000000..2420c91fe1a1641e9e64af6095852cdc4cf060a4 GIT binary patch literal 1536 zcmbRK@$z!R>DQ;IO-=6cU%7_=a7K^+^pc&d3;nF@#iiFon- zcDJdWkri5GUD3AW!-n_iQ)ibu?zj1^vK4{GK;H*KX2)pbc@t`B`X>tUK-`i zn5;cH%;}xBTG5FDL&xdKGZex!G|21<5E+yLW8tyTKB1Lp1kN;QR=zx_xtW9PGEYpcr9CW-<5VJ z&xV>q3x7I1jKA_)aC)1hm&d{g;i#$d5nE1KH~bVkpyd!fhlSbV$}OwgZ+|tIuk*H7 zoOts7Jn`x3+lr@@Jlx|Op!+Q2%8aNc2j5`vb(L?9+2uDltq$TUc`1vPFrL*W!KL=EI;DqJJ`9L8rH6#yw9qff%$5} zW^9Al_IbzO`^= zk|ygDV+Z~cFMa>U!^<|ydKSMD`en~4@7weUYU{Z|;aU zRAEOVW@OUSLsn-m~@rDQ*gbwVd*o! z6Cb>54)Y7@6Hsn_AX3Pq0*Pm@28Idi6nO1K0D$XBYa6c6`1S+B{RmWZM4Se>gt< zczBKRcUHFySGA-TXOsF$A;nz+1`n?v^O}@-%y_-e7H-LfH#mEbd_JNlvVQ-Kdfp$w zTgy%UyZ_%C+PyT>=klg$KJ-Y%f8RSZ4vwr>? zxzg%*@^|5=dG1y_H^v3G%lbxsez^R@o`cPz#d(cQyM-1^ac$#Zw=4_~T_w)cw)EDf z`I6W3oAna~wfCRQ>K2HbeDL7Lnw`f8Ul7H6t2{C94*Ws2A9tSx!IR|`C@HAiwwn%bPpQFX8fJgmS^$70yh>$w7iTmoLr`~FGYw|-8j2q-Rrk5 zK1E+YcPF1=x^=KFbK~I{L&LCpw*TtPZMt^;z3|r7cuV6Fp)HYVOyY;~WCHW%^I!Cv zR%I?5G_&`XbkWY1+kvwW3pC9QoYV0sHR`y3EQ34u3(0kC3SF%_zqiRAnC@bx&sn=& z_D}xNJsRH=zHCW9m}YXt`pC0si})RGwN2jKtY05B=h*Q#tEO#CtF+rx;F98RbK=d0 zl=E+1ca%r1p2Fg<7isRq#KLmcFJqz9hv1#^F=8=X$M;SxDdd_Xm$zX{4O^X>3TIT` z7tPrV*ZyDZxNp~2{?(rxOS`VHI0^hyUVlMOA?9|-xgTq|1fS{1nSXhpc*ZRKiEz-0 J=u7L>YyouF+=2iA literal 0 HcmV?d00001 diff --git a/src/lib_srs_extraction/test/srs_zcash_g2_5 b/src/lib_srs_extraction/test/srs_zcash_g2_5 new file mode 100644 index 0000000000000000000000000000000000000000..ff5e99a610bc901f0785cb7261abb07083982b90 GIT binary patch literal 3072 zcmbRIKszC*aDGDVn#&71)csQ#fAycj^N?jeR}}2~UX)f4ZiYHI_xY zj>&7$rVssG6V*6a)pd^w1Ri@*b>)|XHPe7t6WVFsrR#-TnSbL)eLfihFlV z%vK8c<83hG%-WxCB7(Bsd}hBSr)-}p$QtsF#f`scnb?;L1yiKir`?Nve@jy`&w=qMy2HLUhTbxTX(f=wh@Esnyybl)91W6<+oDc!ukJ~ zFY`EWxF2i&NMf<`{AC@}jaAdHPo5_jv2Nax`nODqF2aX@g_uWcC^Q>KpYJrx;?+Gp zPi*TgsTmsGDJy=6)n1O7V>Ta<1<%eHfAjy8y^veKL~uiy%4F%^L4DFfGH8p2BQrMLU zuQN++MZE7mTz-h_aP`hQ5BA2Xv%N}6GvD_dLc%dode!D<+{hLK~%EvG1E=|^6WK_9cO|nEb{*i;i zg}mu!*GVi^*nNFwwC{zst9D;sPI9}y_Djfjrd3RJVsYykj^6*NwD9|TrvJLr@9PBL z z$QpcoC4Y6OcHVIsQ;J5mw^7{Pj#yhAnVAYdWi*1)Tep+ah9Sx0&hUmJSDZpZ}BZH7T$rCP*0kZ^&L_zWe`G=Q#~Y*Vd|^ z*{%LpYH9iBW0JILtb*RjDtQ+&00B&1cQI8MFT zTI~95NB>ct1B=TSd8poekQ`~wvIUlxu+qL3@n>G8Z zHT&J>&pMze(G%f{e@*p9y?E$+4Q#b?DTQA{Tz@QyI(!YaN6>z9C7SZ zlH(p09RKoYcCWmlZ^6}UbUU%XTHBXx$Xqu0HDxqP2GvAKA{SO`GR&u3PA#QP5HWw|VCd z*53MYBD3Uooyn){YDM2(wi<;Uh5DN!#C7@l8q&8}z6_EIE#EO~itgQ8Ut21cxVrzp zUK!cOaU?Up^Ri&a(`TDr+shbLZ%&W-P_;4VOHSDdm)Gmx%;A|7sb?1Q^hWwE3I3qV zyUc$nxZIoIbMsu!R3_$#iGl?&zbEW&TT*_v-*Vm#^LgyY9tuY}yjZYRu}HdMXx5Gi*do(siKNcwk;C=YI9-d?xb(K zFEd=QQ+Iwar%05;W{Oe7p*sCS)V~mtwID4GW|MvQq4^9;oJ@R$XRW2;ZY>iImHoyh5?+uqyYZTQ#r50#Cz+izyEt8AF7VaYuRUMF zHFu4MdI~plZOg1{uaqbMo8q!fwvyR3Uh1v+r=S9FoyxB1-}|>%U6ywgJXTfr@xNRk zuM5`)hiad0=0X7sHk>ORXJ{LZ;L{Y90m{Fe6r3x%cbR;AUwxm!O;Z58wS z=?S72y4GLG4bPlYcklY5k}pr1B9F8+h*_3-{k8eb8)m+MZGLXS$weuSwQ4H^Hv8*n zh~{bgD;q9e8NfJK;5xth_P9?HPnnlQyu5kaWwy>NL%$hi#iI2=Jt}8nws-MeDM+3h zSGAm7=xc~z*}c0{XHGq4{B)}-_k?X1j$gOBr|Tptv@6@D&8zB)?c)n!wawp{-GX!r zL{6k?Ep(Q@Wo+1euy9?G`SwZm)80MV5PkXPdH=3_o~o?430|CXU9tQO+}n@7n$4Jh zdQM71-Ou80uWv5kIKG|lk~)9Wdh3G`7yk)on`pjFX3M?s_TGt2k{dhJkFx0*Uv$Yh zdy%Q?U+|-S(+@3Jwm;*J$(g`hHnWLWr*GbxBl|*T@_pX8eMPT!tds1Tpmn7APx#Sw zff3jC2e|#@W;-U?zjKH5hmddU?n-`CTt2Der>h0yPqkMk-W4W}GFz ziebx}zbU*;rh0FVtvlSWd-M9i9)1Jcu5$;^Kb3W3Q1Mu^pnclkiAz>r>pwZ?YK}*4 zpkGnf$IY{|E-OA;vHr@&E6Vnr3m+?Rm!H0Q$uCUP?FH9`k{8>VRQ_DoydfYq*?H^3 z{9mn>8ht{tr)^UeI@JCbd~>p_?w>S!dzC)#AL(_6dw;T?eCyqi=o3=E**ILX!a@9z#ZgI(r9PwTqAf4nQ=+{d+anVPgy7RU4njqKqcHdi=0 zESz?BfBbXJ`<}0zg*x}lyLYdmLwtR{uZm2D<;G>*+}esFch>efmOj`i_`<1Y&h1M= zk{1hPj}~oyRPmt2Bg`scQ>@{Uc~|&fe3zWeU>+C$qFc~9yXds;!HCLR+Nv@#lRMZ8 ztRvg3`kR~2DST`Q3S2YMq;tWCC#ETel1qO1Oa2zCSu-W#*KR?f-N~9dGP@o(Zdp5> zTYt(4?s z*F;JDjqdsI%zD$8)L(bi+W+xQi2AZ%&(@{vMj8cskAE|%d;G-rLy?Cdi@?&Sa`zPf WTo*9qj=psGvHaoL>+`o7WC8#U@$Ym1 literal 0 HcmV?d00001 -- GitLab From afcf2e2d810dbcbc1ca76025274083d2b6fe163d Mon Sep 17 00:00:00 2001 From: Victor Dumitrescu Date: Tue, 14 Mar 2023 10:37:13 +0100 Subject: [PATCH 10/34] Lib_plompiler: import from privacy-team/plompiler --- .gitlab/ci/jobs/packaging/opam_package.yml | 2 + dune-project | 1 + manifest/main.ml | 34 +- opam/octez-plompiler.opam | 27 + opam/tezos-015-PtLimaPt-test-helpers.opam | 2 +- opam/tezos-016-PtMumbai-test-helpers.opam | 2 +- opam/tezos-alpha-test-helpers.opam | 2 +- opam/virtual/octez-deps.opam | 3 +- src/lib_plompiler/README.md | 16 + src/lib_plompiler/ark_128.ml | 223 +++ src/lib_plompiler/ark_252.ml | 990 ++++++++++++ src/lib_plompiler/ark_full.ml | 215 +++ src/lib_plompiler/bounded.ml | 205 +++ src/lib_plompiler/circuit.ml | 1435 +++++++++++++++++ src/lib_plompiler/csir.ml | 469 ++++++ src/lib_plompiler/dune | 20 + src/lib_plompiler/encoding.ml | 206 +++ src/lib_plompiler/gadget_anemoi.ml | 212 +++ src/lib_plompiler/gadget_blake2s.ml | 232 +++ src/lib_plompiler/gadget_edwards.ml | 208 +++ src/lib_plompiler/gadget_merkle.ml | 213 +++ src/lib_plompiler/gadget_merkle_narity.ml | 135 ++ src/lib_plompiler/gadget_poseidon.ml | 423 +++++ src/lib_plompiler/gadget_schnorr.ml | 291 ++++ src/lib_plompiler/gadget_weierstrass.ml | 198 +++ src/lib_plompiler/hash_sig.ml | 47 + src/lib_plompiler/lang_core.ml | 277 ++++ src/lib_plompiler/lang_stdlib.ml | 384 +++++ src/lib_plompiler/linear_algebra.ml | 203 +++ src/lib_plompiler/mds_128.ml | 46 + src/lib_plompiler/mds_252.ml | 65 + src/lib_plompiler/mds_full.ml | 45 + src/lib_plompiler/optimizer.ml | 766 +++++++++ src/lib_plompiler/optimizer_helpers.ml | 124 ++ src/lib_plompiler/plompiler.ml | 84 + src/lib_plompiler/result.ml | 448 +++++ src/lib_plompiler/solver.ml | 449 ++++++ src/lib_plompiler/solver.mli | 191 +++ src/lib_plompiler/utils.ml | 175 ++ src/lib_plompiler/variants.ml | 26 + src/lib_plompiler/z3/assert_nonzero.z3 | 40 + src/lib_plompiler/z3/band.z3 | 53 + src/lib_plompiler/z3/bnot.z3 | 47 + src/lib_plompiler/z3/bor.z3 | 47 + src/lib_plompiler/z3/div.z3 | 40 + src/lib_plompiler/z3/ifthenelse.z3 | 54 + src/lib_plompiler/z3/is_not_zero.z3 | 46 + src/lib_plompiler/z3/is_zero.z3 | 48 + src/lib_plompiler/z3/run_z3_tests.sh | 11 + src/lib_plompiler/z3/upper_bounded.z3 | 58 + src/lib_plompiler/z3/xor.z3 | 54 + .../lib_protocol/test/helpers/dune | 2 +- .../lib_protocol/test/helpers/dune | 2 +- .../lib_protocol/test/helpers/dune | 2 +- 54 files changed, 9587 insertions(+), 11 deletions(-) create mode 100644 opam/octez-plompiler.opam create mode 100644 src/lib_plompiler/README.md create mode 100644 src/lib_plompiler/ark_128.ml create mode 100644 src/lib_plompiler/ark_252.ml create mode 100644 src/lib_plompiler/ark_full.ml create mode 100644 src/lib_plompiler/bounded.ml create mode 100644 src/lib_plompiler/circuit.ml create mode 100644 src/lib_plompiler/csir.ml create mode 100644 src/lib_plompiler/dune create mode 100644 src/lib_plompiler/encoding.ml create mode 100644 src/lib_plompiler/gadget_anemoi.ml create mode 100644 src/lib_plompiler/gadget_blake2s.ml create mode 100644 src/lib_plompiler/gadget_edwards.ml create mode 100644 src/lib_plompiler/gadget_merkle.ml create mode 100644 src/lib_plompiler/gadget_merkle_narity.ml create mode 100644 src/lib_plompiler/gadget_poseidon.ml create mode 100644 src/lib_plompiler/gadget_schnorr.ml create mode 100644 src/lib_plompiler/gadget_weierstrass.ml create mode 100644 src/lib_plompiler/hash_sig.ml create mode 100644 src/lib_plompiler/lang_core.ml create mode 100644 src/lib_plompiler/lang_stdlib.ml create mode 100644 src/lib_plompiler/linear_algebra.ml create mode 100644 src/lib_plompiler/mds_128.ml create mode 100644 src/lib_plompiler/mds_252.ml create mode 100644 src/lib_plompiler/mds_full.ml create mode 100644 src/lib_plompiler/optimizer.ml create mode 100644 src/lib_plompiler/optimizer_helpers.ml create mode 100644 src/lib_plompiler/plompiler.ml create mode 100644 src/lib_plompiler/result.ml create mode 100644 src/lib_plompiler/solver.ml create mode 100644 src/lib_plompiler/solver.mli create mode 100644 src/lib_plompiler/utils.ml create mode 100644 src/lib_plompiler/variants.ml create mode 100644 src/lib_plompiler/z3/assert_nonzero.z3 create mode 100644 src/lib_plompiler/z3/band.z3 create mode 100644 src/lib_plompiler/z3/bnot.z3 create mode 100644 src/lib_plompiler/z3/bor.z3 create mode 100644 src/lib_plompiler/z3/div.z3 create mode 100644 src/lib_plompiler/z3/ifthenelse.z3 create mode 100644 src/lib_plompiler/z3/is_not_zero.z3 create mode 100644 src/lib_plompiler/z3/is_zero.z3 create mode 100755 src/lib_plompiler/z3/run_z3_tests.sh create mode 100644 src/lib_plompiler/z3/upper_bounded.z3 create mode 100644 src/lib_plompiler/z3/xor.z3 diff --git a/.gitlab/ci/jobs/packaging/opam_package.yml b/.gitlab/ci/jobs/packaging/opam_package.yml index a3f309b26817..89c34577bf49 100644 --- a/.gitlab/ci/jobs/packaging/opam_package.yml +++ b/.gitlab/ci/jobs/packaging/opam_package.yml @@ -304,6 +304,8 @@ opam:octez-node-config: variables: package: octez-node-config +# Ignoring unreleased package octez-plompiler. + # Ignoring unreleased package octez-polynomial. opam:octez-protocol-compiler: diff --git a/dune-project b/dune-project index 866f6902b62d..c893c1c7167b 100644 --- a/dune-project +++ b/dune-project @@ -23,6 +23,7 @@ (package (name octez-mec)) (package (name octez-node)) (package (name octez-node-config)) +(package (name octez-plompiler)) (package (name octez-polynomial)) (package (name octez-protocol-compiler)) (package (name octez-proxy-server)) diff --git a/manifest/main.ml b/manifest/main.ml index 52bf23298f2f..458608d4f1ec 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -243,9 +243,6 @@ let ometrics = opam_only "ometrics" V.(at_least "0.2.1") let ppx_expect = inline_tests_backend (external_lib "ppx_expect" V.True) -let plompiler = - external_lib "tezos-plompiler" V.(at_least "1.0.1" && less_than "2.0.0") - let plonk = external_lib "tezos-plonk" V.(at_least "1.0.1" && less_than "2.0.0") let ptime = external_lib ~js_compatible:true "ptime" V.(at_least "1.0.0") @@ -284,6 +281,8 @@ let qcheck_core = external_lib "qcheck-core" V.True let re = external_lib ~js_compatible:true "re" V.(at_least "1.9.0") +let repr = external_lib "repr" V.True + let resto_version = V.(at_least "1.0") let resto = external_lib ~js_compatible:true "resto" resto_version @@ -318,6 +317,8 @@ let secp256k1_internal = let seqes = external_lib ~js_compatible:true "seqes" V.(at_least "0.2") +let stdint = external_lib "stdint" V.True + let str = external_lib ~js_compatible:true "str" ~opam:"" V.True let tar = external_lib "tar" V.True @@ -1163,6 +1164,31 @@ let _octez_srs_extraction_main = octez_bls12_381_polynomial |> open_; ] +let octez_plompiler = + public_lib + "octez-plompiler" + ~internal_name:"plompiler" + ~path:"src/lib_plompiler" + ~synopsis:"Library to write arithmetic circuits for Plonk" + ~deps: + [ + repr; + stdint; + hacl_star; + octez_bls12_381_hash; + octez_polynomial; + octez_mec; + ] + ~preprocess:[staged_pps [ppx_repr; ppx_deriving_show]] + ~dune: + Dune. + [ + alias_rule + "runtest" + ~deps_dune:[S "z3/run_z3_tests.sh"; [S "glob_files"; S "z3/*.z3"]] + ~action:[S "chdir"; S "z3"; [S "run"; S "sh"; S "run_z3_tests.sh"]]; + ] + let _octez_srs_extraction_tests = tests ["main"] @@ -5080,7 +5106,7 @@ module Protocol = Protocol octez_protocol_environment; plugin |> if_some |> open_; octez_shell_services |> open_; - plompiler |> if_ N.(number >= 015); + octez_plompiler |> if_ N.(number >= 015); octez_crypto_dal |> if_ N.(number >= 016) |> open_; ] in diff --git a/opam/octez-plompiler.opam b/opam/octez-plompiler.opam new file mode 100644 index 000000000000..565878ef5810 --- /dev/null +++ b/opam/octez-plompiler.opam @@ -0,0 +1,27 @@ +# This file was automatically generated, do not edit. +# Edit file manifest/main.ml instead. +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: ["Tezos devteam"] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "3.0" } + "ocaml" { >= "4.14" } + "ppx_repr" { >= "0.6.0" } + "ppx_deriving" + "repr" + "stdint" + "hacl-star" { >= "0.6.1" & < "0.7" } + "octez-bls12-381-hash" + "octez-polynomial" + "octez-mec" +] +build: [ + ["rm" "-r" "vendors"] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Library to write arithmetic circuits for Plonk" diff --git a/opam/tezos-015-PtLimaPt-test-helpers.opam b/opam/tezos-015-PtLimaPt-test-helpers.opam index c9770ba9a15b..8cb2483c6402 100644 --- a/opam/tezos-015-PtLimaPt-test-helpers.opam +++ b/opam/tezos-015-PtLimaPt-test-helpers.opam @@ -20,7 +20,7 @@ depends: [ "tezos-protocol-environment" "tezos-protocol-plugin-015-PtLimaPt" "tezos-shell-services" - "tezos-plompiler" { >= "1.0.1" & < "2.0.0" } + "octez-plompiler" ] build: [ ["rm" "-r" "vendors"] diff --git a/opam/tezos-016-PtMumbai-test-helpers.opam b/opam/tezos-016-PtMumbai-test-helpers.opam index 8b75dc573add..c041ee4aae5d 100644 --- a/opam/tezos-016-PtMumbai-test-helpers.opam +++ b/opam/tezos-016-PtMumbai-test-helpers.opam @@ -20,7 +20,7 @@ depends: [ "tezos-protocol-environment" "tezos-protocol-plugin-016-PtMumbai" "tezos-shell-services" - "tezos-plompiler" { >= "1.0.1" & < "2.0.0" } + "octez-plompiler" "tezos-crypto-dal" ] build: [ diff --git a/opam/tezos-alpha-test-helpers.opam b/opam/tezos-alpha-test-helpers.opam index 869b7e341e67..1002ce39d3c9 100644 --- a/opam/tezos-alpha-test-helpers.opam +++ b/opam/tezos-alpha-test-helpers.opam @@ -20,7 +20,7 @@ depends: [ "tezos-protocol-environment" "tezos-protocol-plugin-alpha" "tezos-shell-services" - "tezos-plompiler" { >= "1.0.1" & < "2.0.0" } + "octez-plompiler" "tezos-crypto-dal" ] build: [ diff --git a/opam/virtual/octez-deps.opam b/opam/virtual/octez-deps.opam index a30c8a8906ee..25d4404f77d1 100644 --- a/opam/virtual/octez-deps.opam +++ b/opam/virtual/octez-deps.opam @@ -77,6 +77,7 @@ depends: [ "qcheck-alcotest" { >= "0.20" } "qcheck-core" "re" { >= "1.9.0" } + "repr" "resto" { >= "1.0" } "resto-acl" { >= "1.0" } "resto-cohttp" { >= "1.0" } @@ -87,9 +88,9 @@ depends: [ "ringo" { >= "1.0.0" } "secp256k1-internal" { >= "0.4.0" } "seqes" { >= "0.2" } + "stdint" "tar" "tar-unix" { >= "2.0.1" & < "3.0.0" } - "tezos-plompiler" { >= "1.0.1" & < "2.0.0" } "tezos-plonk" { >= "1.0.1" & < "2.0.0" } "tezos-rust-libs" { = "1.5" } "tezt" { >= "3.0.0" } diff --git a/src/lib_plompiler/README.md b/src/lib_plompiler/README.md new file mode 100644 index 000000000000..7ebf69bb2764 --- /dev/null +++ b/src/lib_plompiler/README.md @@ -0,0 +1,16 @@ +Plompiler is a monadic Domain Specific Language embedded in OCaml that +can be used to build circuits for aPlonK. +Programs written in Plompiler are typed to increase safety and can be +compiled to their circuit representations or interpreted directly in +OCaml for testing. +Together with the circuit, Plompiler also returns an efficient +one-pass solver that given an input finds a valid assignment for the +wires of the circuit. + +Additionally, Plompiler contains a generic optimizer capable of +significantly reducing the size of commonly developed circuits. +Flamegraphs can be generated to inspect the generated circuits +and guide the optimization of each primitives. + +The library also features a highly performant set of primitives for +hashing (Poseidon and Anemoi) and signing. diff --git a/src/lib_plompiler/ark_128.ml b/src/lib_plompiler/ark_128.ml new file mode 100644 index 000000000000..9e22c123d58b --- /dev/null +++ b/src/lib_plompiler/ark_128.ml @@ -0,0 +1,223 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Generated with the command below from commit cd13dd0e984a4eeadd82e0ac4ce792c275bd3b18 + [dune exec ./generate_ark.exe 8 56 3 52435875175126190479447740508185965837690552500527637822603658699938581184513 NomadicLabs] *) + +let v = + [| + "51466596801245350172389236854912648222719187746298709105513845567941180611585"; + "21750751762978437653936573013155607200736969558902465208523342419237410586198"; + "12486517768781903523286807847370218034689963995541894791925792444351839473647"; + "20445718088460789875962943176961386089719184042145123661083866290956184640219"; + "27873160203424299876666416455237485949282512273439804047040763657322096149056"; + "41356063063918478660008355287283031045994439439052675999621074603564345282569"; + "39339901461669097862513996312696398098463519178491001542393778258774347097156"; + "9204042589329629203508256352213922752007565761246017599071231880772962888313"; + "44872792620396140616818721079703154415798612187578057809815607666928058754777"; + "15937726977018206908966109373834056579034465379649731865901151172854062328666"; + "23605712034497375740219228439343452998072299839093594319857450624289690266228"; + "6402638958817972947806346954920050102512724107777426591914400080844084499349"; + "3185239264644999224390913018332891687143438328474986546082170376396564918303"; + "8810128481422180179093610800905689707749830921384041843188605671660723745224"; + "23856254368860098877925830552890800356559853619873956523749705505858453741419"; + "24587049159258135725439557767222187037564112044982562605667614163816312730472"; + "22837536766890438293232796017074642678223630893636795777506185541273623237047"; + "9192015516308615812149895996678356120602200776491327365416854885711899134185"; + "4002652916865493677251257166117182479501804845054999793592382685603350748223"; + "33066348252219459468552045146523238597048287748451612668563453612283148717787"; + "22032405802641325275844419284045173476338377422793990841002770933934147271753"; + "40810499016480900907962993830032852958946905562531549979714594924288595159449"; + "11360048753112901991330610389408512769078774607723790648797196048769123341818"; + "31073120699274505130875191050788584204810084807427992815212547386082177411939"; + "38905424489726634595807315824887707754301482341060164517868666848234609856296"; + "16437589687938886598993201288686198745024640875414943299079721648754955896524"; + "9246415141807177921760679831767807305667023086044867913825908258624135672402"; + "43267134335847210508826260454424281515957785150826503791438907274325277067689"; + "47405994765042204778087426457971662098880376129631959037220571890293893837627"; + "51109501544539159334717344833663305202169784719089645141283241708762847921831"; + "28367352686904931835510258483164340654232741901091990185726515423922311395266"; + "49750106362878302307560487257360445042628424171940583005315598767946030678175"; + "45959469784902653889236043731939532829295000363517367441618551318205534438835"; + "27018375398598043392768159138944903620978890067620474698695220978535490993662"; + "37680060127197925845671480407334293104013784691230898581176604640776871595820"; + "10072365749347322273683640976003223868449058525371389769456254873788829510856"; + "5776958426313577264021166002700070711779258526703552908022966622941040975486"; + "2052552766687385987890760301444512953288614090851121718631539540584797743813"; + "29589973335212398499653074528975769763663217998670026908669929887809390254086"; + "47176517056998440790693968750261830775359488909857950144871025285282622331205"; + "4044841108655017183998683299702141262167457310115051178539772996106040315055"; + "23145769961882962007007503964681965122021931165884937363089732236563915279899"; + "7603705117156652453963281055927587143772971225944827219299824918233735396544"; + "678587461188445034628596985861476825212606316443632929982806452029635142763"; + "43358198653600383869329744766691886425670686115842008451706594321104589073353"; + "29783989749004381558893964246285207519677877370947641650381151227672399441258"; + "46788814117768703246098518443423934593855222525287642802070140820481989754464"; + "47667240567568953271881931068585333300960463653436442752666537199724542862209"; + "36185825409915459203448245743109969343193138020188742950229819419575178293681"; + "10268626031678681962519788038923114866365639923373751230918298280203944789089"; + "22423180878570467317830579782624040309181433514468470079452795926252301501451"; + "27854213599947523969400957712485981554578482677686500615005910306191690675548"; + "32552238758912415934584820719305968737837410579067602670579118065160652867044"; + "27524020150199858721583983985008046355789957344374031640804833804334599991125"; + "11598691035533751109698164453612171297192910953856758972631340412485692367245"; + "19240281692025919244580609351663678384250073443852130798436970816624877123792"; + "19081743524319516787728673230184684387616956386482784328031473187929184929813"; + "13482824733237717061443533817612030042881142888904695925365483772570662398419"; + "24557586779364722370887646696339785224219486745231704250023468368642112077961"; + "49132695885737549819731989839786719093658647324506783818463101428078920152339"; + "47598003338017334595631291432676651103981450315484662200923020856309789617505"; + "29657580775158274893108525946918168971159316368647847989798236676167226124425"; + "2089871173039090298283861039787654594553968107879556266696645874401027551594"; + "17062674176584193145991964541286296980632589397952567044305875706903816798918"; + "39759050960205479940159986279409353005846424612008117451162722701140967479478"; + "22533616828186323521649895181466155821530425549183373709986149684843468562921"; + "11710329771453525931280127059748492796905639784050357470339844149929022650252"; + "28382230089609321965313624834250197889691846195285335974753263997326737343307"; + "17483468269617424580234048407267881623433885539437967900597355348779845904370"; + "15393678108977111939937458813237466536883800502542016725609655847312425800060"; + "35335672469945182745009570081451366206953223954844817103347451918365408472583"; + "18485543557533557196522038987860777539645907448847172084578647917456309932838"; + "35453109551100805378496992884404555281031142908343718145992408005796255932067"; + "26162388899534531304185889785161995414351042512495564813598387581820788701274"; + "30513272868498004256565910019709317337704607470343755267516092336967857454429"; + "7482438077715696595671300257575441576458965352889636767368860652528296466835"; + "4420972756750713378268292139245553512010082345332818480344347760992140415579"; + "45443072118542869094106210430408632401658283491040846320908484790994846489479"; + "4587498519897850005501095589592009810295823998176500983502979737014704428427"; + "20140268669484747984769809200637802968551617462409085249909344252279198873265"; + "29246773006012167464394782413277073922652993569428539217341804135677142314734"; + "2090453766635748262896094182234431405487694916721156619151573559829565285658"; + "28154797511075990999067437210883725325588221412791352016549710458849851400443"; + "7437576051454980648324143413673447321627481635285743115910231258907952681902"; + "47849325109234284589063376275405356989691773872687047237532536232042052359483"; + "12480987611376364480590099596287568108053904335043512585655935306753098846056"; + "35282772152784155873872416038091486728018085424598473101796189937824691931982"; + "44644309599357388823648910637703362148932670809274055496007925095230623381923"; + "40669859985254288073391010054507859022800795198091698303895855303568474914724"; + "49443653278257139506363224578511517450965492260748531903735461532886298470324"; + "28151927370999705099548977210331844092002690574491843105417307465011218883372"; + "1645107825636563552234056692699842524648459238860722695243162269478817742307"; + "20451009040028965353495911802150535366781462589345362185312598771266505204706"; + "27819682514111647266735378995664843430901566567232355462928465778589146617300"; + "9554102125843498587844759244118187314040788045621020914785690475852459244712"; + "19166777550065260996957117606165528594010042113228133002376856047908024628860"; + "26933579719124735456146556120749918059938219375765953757687070745926421730690"; + "43664899352313137143462906778788854871017052765412139294077435721003011363428"; + "36173458814979531375880943417934798141032455281648386700864729797402421147643"; + "11182517313384645430276258135181995604973901045769946685233925860600679925400"; + "18957585496621103259998572202861039692818169581041076732942953590132787413185"; + "990272065387976234207571590743065697998566272630425704533408985373371347703"; + "4566865954002478217870742631824891308061027453183663472158387320791808636718"; + "13275080024861611833879690760787568594881779009163813547717517171800075477326"; + "18280289328587924651942995072338785526297904605272226018248763384856128538194"; + "37393719051038483957290231134622753224758957341736360150179478705995454183736"; + "35471769041551236267108986169916522221022951796087962631717489467967242728989"; + "18313615850921029128115249415256953514199920171298188893865360820700589880640"; + "8649505551495013773478550513798423370916587725243242103915932173300802613836"; + "29426595573001164623970767658482684730540336753851606403197168017465308935012"; + "15800050789941506886367343947552537811144738254935176866599264324633404561668"; + "2388599729796011963372654009792156200311446590133223685676648683498130023426"; + "39710359146943858258478963255479846071237665235335480449874571631729609456656"; + "12539354052138844839668649494440055311612800274194314682724519322900896888667"; + "34775703808689652205221353219074769424059692664878491357308664495453361798542"; + "16602078529355937689782643082006360605957411241022465529030420514355243740084"; + "20279850236027730246187137397861434992518721949131469477063849268012331913542"; + "20700406847766119075096991790226756382972208779794861885683190244345925948772"; + "10767548586122669600841175107605340206307369812479898137983203022752955229420"; + "33780485917217277294437000521052335973598541648381872358473220524753392579944"; + "26053477836690449767759260916263153231466698419416254714069016291032716493795"; + "51075719579296898046678332991810264442802867440545970415662411469944202971572"; + "44425065795172674272025431261784423304992373196100933574446818463450861237636"; + "21673427825228648696679367470878911746787913779734335379612724957949663438503"; + "39500036723407342733895180253912956707996173847799994738506003893694134507820"; + "18814390742264124557923083818518430926773544077233525827507879093955534745943"; + "33285136419882565391925060802949863649369447257963104257237128389534667335431"; + "7242824697084765204242498009056108554791055701454269759053340822841847843590"; + "31173248312673499793759274086904799638353536404479301039538892557122201869326"; + "31186133094427811821728441124091409602329280228993044467507339271468902426067"; + "25737910716320624211587760844165755540380223663083209047341376780006952817951"; + "41007486903540773766178646801963663835738017272207371664092100665995867447476"; + "33733614421653704619906981612465553433605639878071728634533669588152171336923"; + "44508002187727655261274038726582531821774653664912931880913651223618478524203"; + "29308206009053294442851242412693308913204908282227130202504576346803290538114"; + "37195044959073314994498067496758410674853446343706809704471573374824766240756"; + "27750290920151880266415654177442693344449343287594569254432923001134909857161"; + "15765188586172333129026261765507777427830002956246082548695725135386026089531"; + "1723567911352974656239983052419150859691079784042460780666277969900550546629"; + "32624380698163043349452348170080919066187676495607088889037247382764371823304"; + "42332347907545864823851740450059178607636354773434217763190376183475294814740"; + "32851187296571784166842016235453193261263026420621113443940941911613891853263"; + "46515450218610398244495734725817662625773300495752440637456039809680716524335"; + "48802434618714806701215020572358407402163910104929505500552346872970874445024"; + "15041030433764412988626541831537854311766371887970954109236962491586466599144"; + "24914207471851043784197436527940466212674042052967065649457499415892446136159"; + "9071888319763577380151443506898914744736366395870413605185856133895174517345"; + "14324407136483074978482942921602872905704673210914714962854893980450386451889"; + "29042406409942557018444189727617456411092110677398829954434968404039936168367"; + "45298132425441112218235385216467264374863717020516284112024948473015955374084"; + "5848266257013307529285399749765616739303579930676051972945621978827280728485"; + "50258542824814649118248459254788489871100732773736051031417014804244168803608"; + "2211331518382464997157173039326358398024782525487574099479995890254668498248"; + "25495625009683093041292487489064498029388757676050435379647316032736436019034"; + "1673456300079357795623609138015785582077169647352697470259283949067483430156"; + "732875001458000671533092091268384759392197266180901126140125986324726970217"; + "15937486314053418275659636264513684188072392679031027560851186610858143116536"; + "37523979262473761872442642124630377368104280370382009467506872860620420272028"; + "1463301537361190248611634113301833004506917120571380701549297040601288661632"; + "15388046866006485479772795262309796656931214897645470303116977773763549826647"; + "24820458677922696742762859449292673635627885851532245057181102097543570979209"; + "42204379350085294410776773079715228191662735656426212256162333812793552403993"; + "1195814176795714164840835333744966813414161441324551406851397366147530373686"; + "16761973517502055324144398018035682278752429331149035356778515867109688520079"; + "5794935406580257517632452299232288835369749493148532249516641371649010994761"; + "28489054235450115341655557856812811692903805568161190542887091508558194202484"; + "46027667092982098207528356294714952530753544394086856091550981466630371723227"; + "36549545461270844973100848885411892468389487357334958172813302441582453767995"; + "27730798985447029088568033769773024804917434212093202895074054132301610442265"; + "30053494660111523933577748614419372203999341521131288200082766152193752930915"; + "42669519840379176591693261573919152190190830699417113996773900230897690941207"; + "40491463463369636128381274334600090418795787105664137021554873372325496120497"; + "37855317198077808209359933009653152621140711928666934200968394018548493650684"; + "30289339203582770465154470558134566153982220926251521920946038335272057457401"; + "27778690140622310321003540914723670899734999136798303644913768708258653156597"; + "3973394156719142858738591330892034076809261304074876595400530436577715032673"; + "34101414891901169069858357639409485174940075127343413252072373211617833012486"; + "24763874711353584430968413634679742313122411936945926412259875031351381484206"; + "36482519855965638025925823411871352935082631497149119671124638993468289313858"; + "33663960240182462215313666658229034428117630528389633368925326911863733915779"; + "24156616496917756781377614606496469046971000527652456728186486373912788616012"; + "17862377433968409862537980143869608526991820954912158743675488121333401401128"; + "9883166492675772730546061809268489723031153354700278026721716994418744028520"; + "651720966810612228203754272949951577724164458606405611640617175537862475287"; + "45029571820041579599811835408905235857907197206303946042784264756752149312055"; + "15218138019507525985285504884751281493313515412230279354014712290617793064643"; + "7889502179901137713876340968057633612399550484642109442993286207350478652780"; + "51114781021375925510384757787309929484526957562759351412663650152039538436129"; + "49153605396638540179308253872425727518164881509781489770081628829948751933325"; + "39446436805473057234521273352946756590838723177719005850741347955181052035907"; + "32522116151199401996556140465344290516461661003004520182401454275644784968841"; + "35709586671485611381280332540710898003892567989895109778435218770617343891091"; + |] diff --git a/src/lib_plompiler/ark_252.ml b/src/lib_plompiler/ark_252.ml new file mode 100644 index 000000000000..c6766e2b57cd --- /dev/null +++ b/src/lib_plompiler/ark_252.ml @@ -0,0 +1,990 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Come from https://github.com/dusk-network/Hades252/tree/7a7a255f6cc48f892de5cf8935b5264eb8893852/assets *) + +let v = + [| + "49485629590707188350627438543790601843164666730832802354167700559078990180805"; + "5252492454239988725999362667606361246537049278449296815482681202241423199030"; + "14618464101860214640501669418913406667488798576646720991952572594257377039502"; + "49620695691812425396881667059975042814057870860951834243048751692229624331677"; + "52370272705607335752267236318243264940083827067691749458235447563501832651257"; + "14710933242610523976995706443397757945742163741677668728466445608487118981880"; + "40295605676867759583334785789872476122167378326657237878145663333439589007156"; + "17275250730668933226474210235642934004873625116556680337206784052264566986455"; + "45633796471806275582583687299302600425559632837704148321307522586100540673964"; + "33681130375233352141656505268473716952957296224087839911967969212184713588195"; + "712629851673255722293534395801485044243728655856788348424319702704859382351"; + "43317142284252827604873495043870647060512975769565878032083607834275571303426"; + "49340354054830215768241644525595586576960916648952093483202539768057155695733"; + "51072133689923992485577335797823140838583096495379330871465525854048879509188"; + "46949696588385743239566882413656461741807666921366097544593880485391490027378"; + "20573821191096550126141597782760949856255209170402036553268647563825526870436"; + "27160407187556206874731839906107055583040719055315009650316032986707542736994"; + "50189849422262643653706645096664834529407274784147778804216234124791624405728"; + "36711845592560022607016872007330968632549815256229219571331231734465570541772"; + "35499690369690524959345453870997264497352033723668303049826986491601092626610"; + "16316511810555998552036883529281049006950270019860246764897773268401228568605"; + "24273505785788709750944619357321960159456240163658175721572690190239573216897"; + "38957445901173225235458499674711464149245486205504890531219786468849422975246"; + "11823467170230054064490275077272871963881914272709655957174399232209364647447"; + "49592360594196231864432308576338740596601726416914181276008583207908643556097"; + "3309012748654570967607135422003010755248166478871582757366403846071939043322"; + "28008997260349091544245311173997512340365040670749744770222988406313503293844"; + "7882946347332999275161185525751330966422116178677196163170258809540423320804"; + "29731010687109400386993771800155774620735785970162866907509352726525420687486"; + "23931998959081617445949503259792788311676984957946834382760056406764899364397"; + "20391484046421688653112911850234570788797563186823093327188237858525889539247"; + "22656719734855634367860470343411809786356929276974263964151006136177227714579"; + "42018013924524453942303746320960679879055521221983992010530880401352394546138"; + "34997396324562296578241314578708220449054628732531003841806342137992978809863"; + "42567292638455246337550117708556510507190278048736836413208545981863780856831"; + "19529288884212474725617121011420109083719176084042307000138428649194091920639"; + "8327938075667211716886168580211869181679628310891241396086663868161241632320"; + "50546778806178535468498887210218810106123307251791580882247524421100294295341"; + "30574977411404820333239918514944667200338902645085529348563130262864324926217"; + "9892903275194545714737750789991423957405171153621887382923972196579113423179"; + "4920577323034891968079586456848977110594227055454553465331672976737322470181"; + "10785473652133501829555600968223966606682909992869608850754498368109405959958"; + "44259656456536904544779434380762383481009668840670964276817234604369847527532"; + "16013602167551971824719708405514957436426476815028708803379542465790908188145"; + "13198374304416209263916195294139003986416471192907786718634040648208496216781"; + "21804530702651053682928092693590400484720275112701610945338033348613546128300"; + "41258400074102294032881307279891022609951591773444936556013171377165772120999"; + "37500410649974720689109041933579952412448029290473291361854784961766576368877"; + "34335673011929272194773705817147158647851634047942272296257858433783818390462"; + "13886304004325070507319308017925418279796532347344964674118255936953984359681"; + "36212245366398184116212011743173706647869616792063869197638400841024375748712"; + "25759006975740081144269794348054803069434307735185793664670622388493509618893"; + "27454141834179019142193646102488261892878322855049554559653828601521710959492"; + "46231413498972598224538743321743754536555738713900369992799611667660505830198"; + "12831308687888044138550325104853798541540822575395885697883589148652582777980"; + "35086901484248977088412788551567969916605411503392381636519644581735135246639"; + "6475115432881146883349186955429401720007995218321780836251063967786164777830"; + "8814580017771885006531117758255250813668411043820855097899546270767102414310"; + "7807296524174932448970457695754749231363157877776562676221113586348272093145"; + "42150072600290314522584934838938619527057217927054115870685066610015126576749"; + "12014531038737162581705520180807422015561278346762069046014491217217393623145"; + "19933331143038021192464408343147972121326092927465949610356498707738693905912"; + "48162370217774420152062014238018799880581373414572553684036906215372618932347"; + "40819852050845908476800605687008690729086125750975079926804162995170273045987"; + "22226594575860551577968163846926724696603097833150589784765199214152339318359"; + "19545194169971732111027157974516008318207647066892354069067261444231038348510"; + "6049836141434740667284236008114543106249641546035952601692539242914716493120"; + "6791353070942758297826333323115522110180828045205749596445149910757953314373"; + "29909049992012855058485881696486638410170793566701289014595505025597038675406"; + "37049050048958384299197228584051152045340884544932681109205219968133691211039"; + "8271317962040216706363322101654508431702987030110073352137002798152913000015"; + "1670774897775895329767148809679299585171850878621026134776642441972236794266"; + "17422031471600536376610034591163807877753208015405398182227178552347096580633"; + "18756624022690204397552680734127650080255894251074233287591407798661854030530"; + "30668115702052736591929919340014079888097509113980964494205188093038881676393"; + "22070300308208791796677976010650187233479496718840088914015812675958670301234"; + "8719223857171626532277312086417428648729460205529882841381547602107666862130"; + "37958249804564731124361955041894134137282950000798272227069902229038293082676"; + "37189467966805221844845186538807960819299637527099935959247421905494814306365"; + "21466607532037915848310355716841895751321958036985554994122512635502114704749"; + "14179699035342293451307513028958516816541083634684431605407839181393476104825"; + "29154847955666596586127425042717506047631050595585497722311215198569277732248"; + "33188642560979777145374528795549704783805148120231153611600332204665631092317"; + "42564521923637471405699083052532506872185646145525237703447984248100308540906"; + "9688958844450335307002049478744008486071252176234867674338843547336023975670"; + "42848254690746470199841780456337093355003554479162355775109612541732121188865"; + "26571650306498172537015187191960172565543217489415394043243003022941239501277"; + "13259263851666023894687861132930820553832823620306352930622248435429243173163"; + "14935311346095148671867793890923330605843422232075508196436807220447844613370"; + "4344538561671100537571115284147321749241294067305664704606142724262115973132"; + "3661287306275145440306213618539663151346918182078062211644897084121048254313"; + "20823698858703001283317436317010639863721597996546476932310242177301854267509"; + "29589286785528202709772071088244026953664280695981877455063175736821781541694"; + "14714810814119711606060345652389090896596349569507164391329166387481498170325"; + "14212678415151015135383112231592717825106807730018994977285657694049579298318"; + "27294817345129277597625121693563352246269025230758913013178562651622515976209"; + "16308958452953063563921495978976808898979645896736092486449459545961496250858"; + "23801416487202359083498068782586588131855222018242538192997207782091276206860"; + "21788204341490442112154345605131469142633618445779895292676418878377458001839"; + "42939889385890003399975992564558390206777324067014435789391978812483943473084"; + "18744379815502146842706137175625169737619118740225857671323003521379145620839"; + "22969419294986037114832463860692313839911009856023995119192316414140491424064"; + "5158048168028926443440685040647048915854092072898670428607816727103222084992"; + "45436514015774807133067927806141304958513041619855877603424280662728885659666"; + "4148575853437187976059844949320814090464120728486411120676443836675361156433"; + "39274458258755370051287444400457797244045933354561090576339386851101477414906"; + "24226038446737669899105084780102219021070008789681262557528873238824761650295"; + "45554128757216009101367584501852978682053416379828133489710853000149481226345"; + "15468212483347652283360923936198282812982215187267560543021929817615478344667"; + "49120785890340968057046175708683790395194430243216223332975263066275757413807"; + "22165820818885004643510856850784071522542800536416499851315809803527220567485"; + "24255417733013943695455694074510916498983472445769012245738544215443095625555"; + "3578717881416756340877516666877448995809041970558865616428083782655188854064"; + "23826341091172689336238927086223180009822950998486138608038032100061694451939"; + "27712967780178175030774348740828282622058332263075474167028713006452109351081"; + "10692520630891410810882731879436263881937079315958040076096859309741666181887"; + "4139611615212690436843419488530338015260675471298926305839949926237319638064"; + "23893117338530655111858176000813570070168939016669641291797989062978619668263"; + "29493430044283825498112780304231954297919106956762292987523773747600907821123"; + "31224696921534136211793606269507101328026664939270273541391154325809905983477"; + "1161990788645954276916059640768435755816955781531340749166719053457102674329"; + "40032672466651019681467480685414198090289911817277735486101335738870038918838"; + "4663929628087510457582572341889343283250798458980128777564503205493248261588"; + "14576003601768386193074498529707218258345393840871241657474970275429765574440"; + "41907905377583342345509053513634246064531351674075011102250846877938645814680"; + "13820230842080821315141850957892243677733920498405615643268916522170002600281"; + "19848873264729615502674527376791162181860225160995619982736986062940458512804"; + "39528445680729025348431669264547519897612726406686606338168880578253680155174"; + "3118432592224748465457531048962416120738464253058324843908920356643714609755"; + "20291688884043804174664313901962915383913038845115296389312218366129420572704"; + "42557007757415638497613471685612090789101153750789304616028486221591259415030"; + "46792197373741062915032927311079971699067950253133746671662212783669451417489"; + "4446326402184357086836436163159453880944166545117770668456616153083342179625"; + "28708468885765405820890561098801183951304364975777439218943183437220558999123"; + "36301422605515541288198992288053820065278318287890213939282985302088469667626"; + "16513700588570500247891971462860214234891585098734807087134948638523417237942"; + "51303521335085563665906206982117421593801796082688254691383972540879029269486"; + "38349748912024833254388160686883390837675515065069293547130880253459258191513"; + "5863602768144479058589215618670066402672112266393989291900873801213554123005"; + "24816851569224726654303407018916136914696378461182187828394888509457202905452"; + "35668217636187023661106024284393036487257457620610684950679976695467857461614"; + "18049157617317886186455739291622755056587311439504905678793914609021791583485"; + "24311184582337406630675921345578587870745539726250911563471149827579208380375"; + "47049171163587328805804625147855798309518236528924756379359079671413806548741"; + "49217441966653616354960566046394237511933307451264416176581197097030607882249"; + "9741440763223308622766088611912800832840447253106863229069648354711337865316"; + "6711970275005184765958920828167320253630591665126522378985833259053410800609"; + "9977417151377590543160871053129520943830884975635063831123262229069994513327"; + "3082837542990263750321290997953667039889961622919749500136642256407112034669"; + "44429448918101910406096079124013269684487142109369137229916801140750864418243"; + "10204944711013435201457808979370927831932282339697033510029454082329887203672"; + "27567961079029968585701667459244395330846299598586490098261597725737547209132"; + "17092282981739153700626134625162471407726486372216667820609932370888878727413"; + "31485584271040282956654226763326588049877825728467428926223647874479701786506"; + "12955442244748326703021715942574723118787276791607410352602368690534050770417"; + "36233598404262020873794741863731429804608939874302234761885447289322137408181"; + "17365032709923238164430981278878270324454980279560841069445448454199643029113"; + "1599308425815788479548362313813963333016792520742870977461515191009005920540"; + "43669871288596037415496023789232130242903264831017218631867709702917757490026"; + "49117721877014812477333148166335201583815489936606800780714317383158496433108"; + "50780218530638944533890976760629911189324354866670913408371520875375844233903"; + "7689428494847004464240529995304510607351514709716679690600711591096978491670"; + "47955977594669526260247931440322469685056949069904259470080759325035295286461"; + "8365512332847242169003328823195689637827840697541204265356337650289585838123"; + "3840401128719370383692078279691168408796656116885154086592491099204611073383"; + "43069581936608602226405255629351890119646172590162211959289288774795830286246"; + "43974189709355209820476462362097537404927792511028786194043940929898183793414"; + "26332351117299179629573047197679883935341765313312089900660919650133476414458"; + "50351703458402831605416039704608408974892592655299422309480445654414527175979"; + "33468607565896128905680223110626886234307943229683243021379890835118051012325"; + "6614565191349098977235002226407314032868555511403717887772191274612517181410"; + "38103056918801597643212870363828947832437506655680421481428698964117403542602"; + "32908423128582779977704279934611177327699184469671505430337832556835115384573"; + "51834951159973764105688866487621285182469090830458796598668031091107941720686"; + "20906443585217694636590360222926761090515273711034774487436003326403616929638"; + "11543128149317521186944038480148089876167062819998754661365448516694779551074"; + "13337387009791879577397425157695857206822652677921492812658909620421271792366"; + "26158663219738110112661733659009555223590055652836643266081611952515633330808"; + "16620288606563676461349358549564125077202861312536356779066223457462338103688"; + "9370353560216700598486832215289311328374345394195634955453105798486005404415"; + "33633718565315235577394971195804503457415899433434050508477479187227057261067"; + "22882449296374811923033442799913069323577656681081909852574042775892111287921"; + "2940185604989639101256714689859475930684457088567484617894462057139075862941"; + "34483194121915222880375114276064125544128032137924712006849489977876279836276"; + "45372384774901078103486078987247871000423060133375498791638103398927924400835"; + "52387604781514376107006295066270649568927674910028459430830457444029012327788"; + "6167869651297502278429690950623450349205119487045648580978208453778184411341"; + "27462497275790959876141507254409980360566911339456621474224385082554805533038"; + "49147087543811949479056383453491986538702256593160239527509029396813090030404"; + "49587001406488557808406328288652991476747338395266693648839878008858484697835"; + "6313958677173548204879553757285379819254567579081576303778677143280554291690"; + "5591468493874061488706454796222404166033712948542307967483439147905003945470"; + "2437221293824201160919193686511276517772539907794390113067425954677677410182"; + "30357986563693269312610963334150804237408332248581737751589214609304706424480"; + "16637601486751396636529759375224983522742599069263721097214299703128247198523"; + "27879534340144216562112405598077066811919674403148810235445326156746715979842"; + "30788313762153313626674963316612595454484683342245093445515009044754566899486"; + "15725387840690796443588540099094119524389569177620500091843845820844320431289"; + "34132295312326003636265296299999208396694730499866986050666477793086157249908"; + "15362934941085533070255910138373084570641154047840765685532551420580152655609"; + "2755137135618857778067513724833509904536351561976592574187101898503219001617"; + "46622911741851631588024639842856120275465416427660592975008281197121795628830"; + "6964635240711037051215022604794208273817621384886657093402502491567294160845"; + "25783574129877826155110663698218382830525380279909999762879880818546978011140"; + "23465315121256052707655414720713957672069185881022798701424890012062179540328"; + "14395053091536499765531983402867839134341617705786295303106179101403117403050"; + "11316253621114442899553787480078181551163062516697851587687844977545722300558"; + "50064661939091922013762459183760659158315803719176946262123119222324910530256"; + "8783665334345037843914454257570704820761444130918358310108843988258662584186"; + "27618475988876729519248024362417979774716550450998439569984942958903150185062"; + "43015769169394210865366119150018957649114200451714812555830871262755495468016"; + "49732426066558397245060256272342911170810452758926457010543502425937044377044"; + "2952797980452813888623715400169643543685112681184348275283000981057872198778"; + "50872740372354623466916457669382604074806324513038750478426891403283893655073"; + "392818184515825854281773563914353854398754713238832910269587407972143774476"; + "50779005954836595097541637958107285799215893016482426373886980746829520936350"; + "25176357246579974791673072598303068538657314197431647903881566730654004596817"; + "20248152184837592885327768689673131083342577141215627095954882454724068067303"; + "30064303728202536588603791400844418739073552658034934314710159102990759896158"; + "21384606984835160613401783081720653002397794837776744119212545320680659814207"; + "22759565228734648282413300371375307271924944352100268152538666537290900864554"; + "39429333593022349595681621998820719879621843929926124877175561019165223081129"; + "12070092883346592852789463918508042095108508741001381953375286128032289075905"; + "33289517265391819899507145162086978987916991654940411189206013329200864859674"; + "7221597429770981330375263241511499043705983470816845272720562845158859285226"; + "16638272235182748474572289194344411365650205299005022442793882687465898549539"; + "36006214239196604148614442091188440583481038594995316939593040856887035358617"; + "25792600705977450864245882132395859611441619832808864344772519627069798329604"; + "4080552845447537437568804141996338888821838801402604114257764603164350512676"; + "11798208445675100720061102611516112959643834415640440909769995293901688418811"; + "19858693043126873191571109475227847243177160525403793202276277722982907002636"; + "51792167109522919038849306964270342579703542020877440269381030774505714185697"; + "11631710203663443472344988456889389622339025983399538662094459108486378805525"; + "2182473716255059033897861691447270412333028850406831066185078223238986325112"; + "761168299106618959837253184610027302352675981172895412789219362344349418506"; + "36857059855189113781134096792662950699742275482770772595919903687711739320818"; + "18213396754699008102047102089506462494549290414412359468656221893099620902008"; + "12599997312887962866854539884234476951913054226022526078890032319964768070561"; + "31295812056319316979171165714902562241023210946259070539368704588259135657855"; + "36028478227374554353553197903612149760893367375462390976595843472968694902073"; + "19755792677313410149868952739127262822852161041591595345565317109808360990362"; + "7604195354962581173699215459157831606985245892932148667568863588427368471328"; + "37402797671729867091958880703368044330554219817351439709435695854279377052968"; + "15021754554199031983119820117039379649754158617595693761803226478334678245252"; + "47490255684408806072434251664743508051420570808132025501451725974827121258687"; + "17058297088100779754668670576690752359201713072728307725116578742664258035812"; + "33177512279709821535209584501483624708734718786595445144375381063910225855217"; + "22722275695407528091691304246968383686239176745361072723538077075588718852746"; + "22523893181902428650174996691790130832371188536502447987063143120257450653772"; + "23308895356450165080771503655705485959702912748685275383709016805561195393730"; + "31027920485628166856312777655247597928527620141623480299311482321440235423250"; + "45061629190945989233993296798591248101958034421473451931174248051572365665596"; + "12635346734022971744529531315542317156695950592572588825637598149329121435602"; + "20943947811812318510797609944365001415379144029156369080552566308035645494236"; + "25272795848989661284291121337868232983504512905079898072787482710703777539907"; + "30267260031722018334657676019133705236740734579176664833600084021013496843546"; + "31517311768361733509846398942976030662400143969686723910638374750883139079149"; + "23179568872539103374642859400181289258494250830556186918556740813443091863672"; + "43764857307902449625975867969146072336127131357517214347103058354083616467535"; + "50986536293458449273154397197499183679036967678265692625380537258000063532144"; + "17739561056178158081098295809388500809247889131390006315905372775593328303174"; + "29288755790242817717621638923197240104295093218759888966129245521028472275230"; + "34134838804483412147238682009351758572433373367047849860439248437388218182820"; + "5678031864698043849290292270505282805363676850706953191264384683006133884965"; + "26520160397861331597785508913058535821999870140894147231231876363158277734288"; + "29240730915918164705120039064238164059586741149554989326639275573958724232530"; + "8343909311567226700622893556200749476532608824719086807691291972160111871498"; + "35422495044092101446713476071226458201086591087201551382952729636451893974060"; + "28788191175818003347220573268922959045830070401915571862444782695818400239985"; + "4964783835867249774083299211014420218490608209476492267659355881364453511847"; + "10216614694145379678113358015463688529998198929758355282726851046519070445194"; + "27803494825843439402691751649293753560989707643490491294838415993813244078970"; + "30748627242627915480476055895904136928510253392793276393732599431460830214019"; + "7751739221008798527034371607783061382972620557894156823243899329549833690423"; + "33136351771438729026535955096064818190694747127577887810498359791738478202735"; + "15487861031051273320246153480621276816764645205006338931216717383286810036662"; + "49842641210693624237669424014970933360600934128562418971602444161937944689815"; + "38080738277407466133634923380952979679353443729179754588489421357109266527740"; + "49835778803230991359657573667412732792328267908571176221265893225909110634684"; + "48979716276201786775168967369617265563190564537859459940775310207730069238772"; + "48115968293689106220270565101906186091927515718072586052159138752415504690487"; + "44974490348051781688152167728748294073951164996734932874793980137333724713822"; + "32723711714533643804223002624655983381445583052702071992248370814287912622753"; + "35770018441385880747665875909685263825335619219990900501758283083700215049177"; + "24462225877284730742182932602961025133445826599619125054636967365951416719552"; + "23783458847678429109975790282720688654564666590790639711956826681143293787773"; + "22347164999197115677368036880715580840867296071947684897983662897368903035923"; + "44436078084173495334203313236158995421334213775491689085750945085639709823274"; + "25531354606207591001503734717276709131788523985002917593279732600020946775257"; + "25684785975858758309831379800021705800796165309307017255796818608524248856681"; + "15689846944752800355408013445547581183295267110737304356038985876510433629593"; + "2954755130869062203053930362449428183522050551079825685966392986029023636700"; + "27701477658173432393740883974255870340912747006748435341251832401519511471276"; + "49144605237971303130051477474500252441736011779691510816968732821261269570968"; + "41339385840143300905581133617960524027180235012107468786212952859173390468514"; + "39648185702412479261241716678418509894559280563465255646156879733379530382617"; + "2941231259680949143593699011623744100174752512729757643099482873601163245575"; + "42912407210638823710182011018928480520340098630346497369618624020054117846676"; + "48149959907456562949390018405936990163864807774773031806196322989123705667163"; + "22688265260172456453339993837459152038039626634400711129266583542220009592074"; + "12000693219442732741816223290743392039668089531561600727937394342995414579134"; + "11903596729989502145549179132986907891593077014729378748826473464861625192683"; + "2687111115125246444031317339291347908971840740015813305558838776418739833086"; + "23449522976975553535812413915796651435793968713230742677655098865139106223667"; + "9127447737910095400860412314688824392136048676974256371522014899566329800277"; + "18470081002802756098187392375443129770425055057517598292932337151147562979415"; + "44570736387423385650881595596783530585778739624944938740374839306088992916739"; + "41506121518765476611532159577026640847942725069679660287546611181740321613803"; + "17879365806603642296154180079678225700598122219887762781358998608195664544974"; + "5797039731182029290044110349162251456412636832186827899836873551225117057673"; + "16295660997252122627187664110946939903408094437070458659338126254215674463605"; + "34524081549397177387160463682322947783604339299199714872938486944639466740633"; + "46792070054974847313209541773010710216925758583669099409416452772447490195997"; + "26758138270863118025378847876443541196713233312489031593470542282276213542370"; + "25932795773661200059482623714428701540382804071390881515116858419823633841821"; + "13321689192715674395770738630438750136066468135694575335309580617698058033117"; + "9707380803157554078082855616156559824492425930465667797574921265494807066314"; + "7456158743057656267196226193273529706797096313758394320439183942428804984716"; + "45355642533698338070691932069661520741557819242118354206922415757362929214681"; + "11678259483364614216163185940141297609599778858679439537001487250711661685168"; + "3518832067902435230725709346836794333454945124555395496274090845504580131455"; + "32945555853640395249820450907965284295734348780933164440399544563294403789630"; + "39144256186074248653430012132977997931891740120897263028206417805470480396128"; + "513475060263080708913788928053965257750752082706905923893128454713255069681"; + "3683049475437575758554728873338252672236374719853531546923396056498941488282"; + "40512995296870597270088595777901813960760477076488920843379483396300135285919"; + "27566780071222822332525446641593709138022329153495927653774019832657393592701"; + "14553386429473594909470688556596424443792788721346677010176123183887024496060"; + "27859920549341120221544363269894592509610202544403757207234685024595167318501"; + "43630799630596017253244467929174687910181739803861346262759350693495295759987"; + "10566905550291524816328331044922050443675986854353663452037665157735899469921"; + "41883294330455662982758134167170988606274464177099964393473215947428373454548"; + "49807615802944289048873232050825447587887207808798093013193396431089336030610"; + "10322165791099655621755425357073963493688332466706230721287522258992803490137"; + "30646173733388488363150064701278686720564910831836411411651976803737973266145"; + "9402643818207936923863049876511905578631103389374441210902427576559340397042"; + "26796903570709220124665459153306887688701095587820014535393806663646332690802"; + "46485326810825309550921448694342993906840425779587939587426865276020325464945"; + "24356907333535237405651241236585413997915979417848569943590616378149521017774"; + "23511169606994309941348827806149481805650274994320980240977267213388100293357"; + "15731023427833496072707128064453862171578629248859961123054184724775612220021"; + "15476157034920561920585064222922712755398556043478554933175489223519135633295"; + "2588249154193062661573385899432005495347251302263070328643388740869671399217"; + "6009738957936176982507178002696621297792591037813275212151400246297074354799"; + "19233332597631491707508807992208382330520636330001528420218682645685589256221"; + "52257447718383093991766497150127369332489778818971489581567733290721167946805"; + "49137177389699894517809095595548850494591743777874595835879738514452528623678"; + "46568408911734306168397184498986706003337923310668800879260860154439924802578"; + "47934768334329838261157101167633276452145498250520979978623243405647174036268"; + "50548985142375412913344898480017599364756597551569943313108030702053373292351"; + "47313547501137846688862600708885501470839439049482542252265318066588835595877"; + "44379141510324834123427106121179013384083052933887649345549024509665387337907"; + "12745350498713174792397397689765109018413448791457948167478567090039244524261"; + "26500864710621301469407121438090857294270092269498670394353899106577395878729"; + "11347414485694636965135491107674675767460314869225865451044094742585314486685"; + "30546797282015374456420465905729920533639220341847643819193401157056239855445"; + "9764420137258539782443919930298504966223551788317773035826893207520127548815"; + "22299459460462072891198481974919074362126418543881491087838369912934426392572"; + "16855285284125844489209514080904609067369163236122279642071700082910563677928"; + "28470684714066956536547171205246920705847552363405765916824456152219308886458"; + "4732461843529436130239807886795100206469260396399272943452254374852516911378"; + "34562136348353570109700872901928872554702381799420513020116701553340267771150"; + "32365558558736606695100598286177066733690579155204608260555923597643725911454"; + "39093274064908662087943844021095101112203783571135735803933668222858746865243"; + "43197629030144295844773883705380449163834899349448680049499938815732794818313"; + "28135261046436067943449704769784602664670169528558709941327602925531279330283"; + "1506102606338525938978917833686468888009362316628110197189912144850886803765"; + "42336701278628501135217154714167575672783514963702875925876272615990289229528"; + "25024620564425776027644674844378116603084237932862382763192286329954441925762"; + "17870721740021152115020062852028651603316820821405634598215292938053122266052"; + "8726154223262675362011088994808023052872330129832279854214301067840970209836"; + "14874402962592699078349928625650239666631999908036706122344921639840279200415"; + "39756319747099752854658342549564553329846048617905492959798860958027344323191"; + "16691128005183566214615852202071092535806876544863611664073120718156966518635"; + "3656641624593787470623179851898501381429958149290052751094306413295906197198"; + "23058535769798180750363501250801625076459404778101435404523789853891253539536"; + "33558816550895409218380886501604904940103012687961987303678839499951905999903"; + "3535320991257296205944099868175259133046387724680729551263894422361251248758"; + "7317061444673855310460676987104314467363507031733135923911471906709732796227"; + "11500894792409448904640700230690380435021471256333652274764744790985040833762"; + "29946587402762992979637543680372942972051576109298571343103906148223476379391"; + "4083115199018558811067305667801506297182902358286795914571961100973484984414"; + "21780845559336370060316195032869693907916051322860704165373540781960864925849"; + "50108406296877211542712950356627343571290344962477533388788483384843943241826"; + "3604194748440975970709176256380189264567204604496059337216505471586505569550"; + "25367520387024971306924473288179691904393907838798350326959612955828936977623"; + "20832698602125152248033711132843527797288526400731772664791124082045251454142"; + "42631062868366746704081529205540353901856777480389910573915817519106326556653"; + "34498285379235908749982034362054765010463122336180289849202738319552611997489"; + "42569303254780782209383769555863500331363619065952722987173481354130829961783"; + "2968398972388390861514824927379622551058313567208592925335792817590639277711"; + "26932822849411517822460887083515713714294971165226156231324226720523884126957"; + "12289852530007884112177675781197310398488340001613130934099944458324157517609"; + "32571394385633728540470223537905763247514888927223219047927568504736330049592"; + "49323371198951330358894217978741100439230061670861277900398849522199063498403"; + "20916227317093555798135256109920923636673315915840710498394615832626002268064"; + "50437846180582211045193594549699682565194393344569259404783034512017335183667"; + "12720868063213131315535911341883761360678170824615477340625750278643114107287"; + "37197243361742872107474934672270277255457140880848614348969979603547286846838"; + "49972563335848604083615943319581538413921258859517393388640982639930301010342"; + "24578514759429435534489548439103508142292694204518742527201734880498761607088"; + "13544000375663478018521907983648192775225634805964564209488796232080592901057"; + "30244906257123439752743184026932532959005248829599515228075497819748836533053"; + "17158480056121611203761622020240364912867157439578870271481544859959963992982"; + "43213708539956730045950791581115215808814156477860100393372067402068523043784"; + "48148048525328038354477853614732455140796148613572766084643376345096272862233"; + "23955550900926153176119256387738001205670821929278609825909043128410785370923"; + "32084112248131778873683184950328740630941915092866433791792196623349700717247"; + "25228735758855933155378400293367847597725487322422339171350380923514466214585"; + "38708924229373547897104118288852039016237551318118836657141457341427167364654"; + "25573420543845971899026547821922148843484281700825584055000279017238479818969"; + "24727047789721276146751871546128337281102901395874275592320129585145360286605"; + "16376363547325397340914349214206199307694252744603372010394026437013197100776"; + "20208836376333578926014682699975542524501761930394685283441636991924627929267"; + "35206301732048412276841356453505638516993236521927454740085319844070799435331"; + "41261166618096608240361379074330395434896879239200007895635788430952244472582"; + "41432219394078727593377645450491483074448807484512488014556070054882946094209"; + "20834236252121597410527416638607520798042160344062107596356735831487842114761"; + "23532139063413819501017120637575271821539320929878848328154727861013760586039"; + "3946253966634265225936238815600554190068564160724890879995534127285456411579"; + "22846690625697257310904779889019761152674142140749605466121380947233821897617"; + "22087213788241393345997830798811611648992098114012713841486529785834041554496"; + "43158723807235728204358654052498829642083060365187988897913589551158805148577"; + "15465863697980742098871467263990006125886103501516872842535870075250801222781"; + "5680194980291197839690960478626830816555317427024014693910787627450289237742"; + "9094058180026172545686171028787053405103676091999366345519984327286409630688"; + "2332670368762680570021571783692863301454064644206808151563000113996159738789"; + "41147800869911993983577010981800974642409890520338080941707731579519543968663"; + "13279894307388819655466420434801883531790954002783939588058497750423667181893"; + "4870460897717989146446912775477927413376391253591063401746677243573570104602"; + "21434150992290282229101961254012913715487714753851223580286820712178569140123"; + "5884699423472479901902447150142507004213890029567299438503194948937225087869"; + "10751322070759878166895822040094727160998828737858183859125132419531492304288"; + "38992650885322951602413869202579221872340599306440561607592984827348058953230"; + "29170379394369260301915803080156002423232616339189492529725305493825816836491"; + "28207328749747479105410685727161242130439891647417887391083580573114642433586"; + "30853455820741483128256761592665063199571831731867607712950643840486915981512"; + "19674757655311695412098014331868801137574968530161273910500977119681828944720"; + "39760311849140484104401541894168574438723197691222319633908463502228900435385"; + "32907700014271836452044581308399924687442165571312547230568158377188973441089"; + "21419616329214777079035587170514020306037526204702975777693989034339440177318"; + "26618360897653828866229525715043321785206978439662756876063444705770873337597"; + "36839328402947719672481705066838749753765029179922670705966460218560367824702"; + "33819865214094561436972297577491830411674255022072017707118420428518277463984"; + "52239226873754505993400788229529834860768913846928108083029668222253331104089"; + "33663514509883297348657719612646437260376060472686074175777529465535219635914"; + "41003879710590127522478830906318116993393243242504050949617603963042321060476"; + "7812617450066867719201142889276223443655576184992693957516680471935511930279"; + "51121304503531803641767527835120763884818550079574319802192969900240584243331"; + "1274612101252555263549693940665575968018149479789118602662813998362863815476"; + "28111554183672061495966203485846707355259261091518108181556420685499275202196"; + "42136394643178945109983278623800719553667430014244921031314292928454177600075"; + "29400787731444232592537985972506449856480774156983480052734223261628825541468"; + "51495741815899207992089872049098533532158347593725999004967104881825150810836"; + "39333115389438061754746792518056897857082090561687954807372914815130461016655"; + "14294336768755739754763672664822083245398240681090554840744022889714341896060"; + "47674122242123052198728676357951860449892667730335860967923060333702419341834"; + "35684666049106444634028920061342458983421529108234610860428488342278162340897"; + "9217271467341686730075876652325145965408071349745719665965491968116132171401"; + "49102996771041826251600275636051473450230724151940234292281582608241970286503"; + "34854604674557982238222418551502188390821202909341038834798601283398583979700"; + "44103714803951799081408903773636811469217830709674983501189338090554583969027"; + "35216265618185969272100001311669741239205828963710925045672291350518816047261"; + "38403524999556193056272637467205416979772986748102914574085083812998622738913"; + "27146144115803706054383284709975278288993223860198708633471683084389321626754"; + "13717875182956004040277399923680066755828211406717894371621241252873305128902"; + "43893363745908782939920493548985641014151424637808957048781989937501374580035"; + "11726253545109081409164353376819469125399426277505280541880391837677360874072"; + "38928083350744149770676864428063336223211502898736165860838144487338522811447"; + "14125823190822219756837975179681223974137829967998184374453263586157382305654"; + "38513876015199093611082189496524624266110546915344263711135739803957351751310"; + "47685229118417094929745561957819690007671043576786068405288351527235450947053"; + "6959539796323704070461146242134806197237474129123359577767978063953427949977"; + "47545452988897685363050245883092979778729706327058096488694175926251841756750"; + "50819854690063046353662942259579520840136358471545216283227859112171763003225"; + "15309201933918541480912493953275686961353315663926344924717901793290472429632"; + "25814701665737234866376372053628534273087781843875343981916301130840793116256"; + "1916844826075222519090392623030931550354624290318063661929274409207762237329"; + "1046514656280512977708818059092759387987165875435181225389723691639677269582"; + "48632931314601925346131427356122727760212316227166299632747707086089052363684"; + "6605181920334239323337807639920607887166441510148481166461711505022421245712"; + "24648729211610178594528829323421440848291736568213484173668007946234312273906"; + "46859494710268538864658299697721145997690895979735714480735923808224531095520"; + "41175929282429829777281847415308245248403968515148043916452754293744702303400"; + "4936300094396586135539485728167289346454991472436633497057899786781957023646"; + "26497056294320821551797856452767310941293845697666592809944450466405074510159"; + "30179755929855617808122588385117490529340524783380573627382420814158046220265"; + "51404155368749455548900426038075050336878399275390882961314989220012144625413"; + "14816852270047203104312028732909159967998906770274196690632931234420725527426"; + "9617752168355609648284058626664682170830718885414476704978109198619947225853"; + "7427964446763934879077123333856010036056226354148572747809815822346855367365"; + "29674872948739147286091273509870908664455349901359630308300510194622261921733"; + "43495676299055671139434544393413803052382814125675363612358978059313789429586"; + "13094408335698611712427781744265395983524687621162836316320830449519959763188"; + "38569497775632608093794125886753456740306226239072882532108501824492224325593"; + "40308698798346304095630271480781739014165493986458798701620020450887376406428"; + "21695323206500389583562384680685981414856167910480068112985112222651637002862"; + "28462792058602339889033620039075559101583339912637364038250676107653835038248"; + "46541024611362968529348952496518032317778604675804472582130971946588321773057"; + "51356043325501315362210916662661650495252901592454120098836536302110199287188"; + "50506579084327411763038002678064865811256717858083039734318534808177330899455"; + "43768274514650675477817361475016698140148452675749491793321899996800017542942"; + "4365130454011506171008828920058285825290911024175299642700028827967669304334"; + "41317071247365873784712926167181757675491093869449596462352859768807347211544"; + "2666773836237810619617948712753874439458872566874729089643359958440020536859"; + "11268787534831056816083083174895755956352873998182091668492218789389708906242"; + "40695329903519172458025898268523734890965958519055359802905784576698941321234"; + "41627365240233602645027028937623461357745612228956394512781214869371540472342"; + "4164478539096095999131892571705567059771712234999653371776917360777549612104"; + "51248727099288674225044422898397396359619826428997072695850613136023953439945"; + "48153799345590764241473716564225186646412111682334808658902588825212784855559"; + "4038288326645960636183384957834655531514058972517268839850385229326514434196"; + "9349746370858115821223769976893823674367044998087780251985518797575566269054"; + "26635144643229156230109683885266832396020379662024410046384058858172974749048"; + "43223596713057491838453489984430963701106626227127004266936175851674881127669"; + "34365304033357616463976462028585280284797223483341370850659338406635297935595"; + "2134516731680789816358678416060804041161035786347309768102559295564927033298"; + "45222140147028755238863517248876975843048731238253735396150896367564901004686"; + "498606925255879431664844628549393158879953298471933183455573478512612767210"; + "31655578397479065559694701010163356160453434259437394629612488741366238826723"; + "44556920347721604505312194713898769297829148630669474738183867182834534512253"; + "41066252220898939528372277962872199592413634363843816853371068676896371450235"; + "17898654860211486557422421879369818443339885864697693239455405713385693412604"; + "32513783099500141673439294633034010193535529791111957913458937240956644750422"; + "39905409111076411206565494347110894882613346677151423254819846790782130025281"; + "34988407687074005102516587752744593627068947572334289485494224614781612900746"; + "49737579529532507611760379505316974983940800332946027442906862839608822441536"; + "40162178377217761341550347366456178201094415946625032846674573547145969502567"; + "19353664035666185668244147626872757644951716514199713218834744622396379021728"; + "47102456478332690688659328489760691845709562508921577866325372829999411432449"; + "12207115819013703533090639097195525814981520405803331543503208389206865838351"; + "49994145749153772801588770229283450802831018859577109122749028671638201340175"; + "11750496117230153414206471040577887902252831603305505401836225613139968743361"; + "39247158472854700135101098114122648755375036565112534510407184246554146458821"; + "34888420087558994696576075863747777609045400754497672888032242287719438881063"; + "36746602810649853608305671227827297524785410557002588877308144918466075161379"; + "35110190469581159095125917772271263108711630576551389559652466237914252519706"; + "17666646113580405089387681323991445813223732839702375394019098767167481113374"; + "49832915191890911296130390700527381380353409264287349518316829690779511940285"; + "24443498466703215427536198609292882343492137081224136946780263563592401049860"; + "9354050407159006695831135953483212990074661420262042032504530886059244184549"; + "43333009983788285821400695240087914486289602002713044560524409547002696507943"; + "18752273838312523782927643189706439976957320321860728910806488085573896888517"; + "17277900024182511146710507398920674498144288099203282562831710644330579267863"; + "37307678413917534108508235735432663978301009388979394911932194936937228116983"; + "28849789673530572936431250397502939284314408030083300337114716226795362105688"; + "50912816147821018549769876876636191732251692688907664846983470977761901142017"; + "30131058343978916976539560634538314390572592064574889352048802922118040591878"; + "3706738172138818078705220133282568519342502151909947908081476774050163705447"; + "45699814681518246744400453094285582701849408763005827286692443508836010669243"; + "18846003060227712054607266173221112847285282616057372060555371817788046689458"; + "22066640520973054711560800705115163615789502002092761843459719025242646197522"; + "23829247396636262290884964425831569678858143545005515755792807616917823372004"; + "48198239185624674941704629705912623499339853704797750011743362965545369705797"; + "14437343003724224631871818628799571960312140411440628694004790267232875166985"; + "9205739813512268504763814673014453677276549572272076135414717042201476484408"; + "39791411423593512268799994379557077985176861512059575297944927863183698039381"; + "35926621231744856494112841579711773281980064124370668225976659404439672270700"; + "44486629680241930770190601741590174294937444204078046665996776098470715578917"; + "12162293378945031764624085071759188374782023105344514611109545726564556675201"; + "36307225704631546442623734392611975648010152587096752396997755313409683740066"; + "41250750058001775370365399976123622596191578857360075239352807587783963966911"; + "27326083632152278734711454453088575834660104218399840842350769848804017390818"; + "21738472712881664490908162471080764510324227185426320378156680732466086006946"; + "48253221985307003164932400584047916688911336639213284074501437919167577474120"; + "31747278632217258576675538435288102373171173881876663185343643389289388474560"; + "5761801194886985126517131550892405530757591539197426021056539623860947947777"; + "25080051431129686333412677366349247249765542691781361133023295276989895785662"; + "44725507017222585824480973320142248615864064267075237276314928012346637335685"; + "2270142730849677751753329523089749032641108434062308390614061733510185159182"; + "29151537587921846263406040946950786214733637455178025270138954283829217507166"; + "51701993706600967882137291998419813154460359807514636008564722369823738880081"; + "27396983310969582762655735423233600814011645446508465877860524193464148646437"; + "47027464785635786821973369345787882857794216687685310972827981582102274085589"; + "8537697526465704802497642132002864572208835642458535053052653228499861354076"; + "33216310879070852920780500139920461536347985311343304758357092362169634432945"; + "39742197294627214520191321293386324944093718559889580220315772412754596333618"; + "33896963789316206258615821504316306436964228772759528417727957697783861669643"; + "25010660153820592469701812125053548417837781371102734874578902256052345209508"; + "36367261405021942429836445456841404357897358255476611125054531559819745708605"; + "52426140434579970656719582674709112782140126494023197627160774284296958026640"; + "17974065625542652257057290211548736634195575643976320857820652175876530118764"; + "37053031019194686166066970377043979546613341770302232565495885535831842113241"; + "13811446176969112541505871240921570152518757388141946244776461129201049000050"; + "15092093442185484653246077567190483143911375332335503262901381196989675075655"; + "30290712242976568484406185485374545475757630659561739950369976270424078249156"; + "42300599090797035681205333143172106725230562804023721865246977451648659325451"; + "23034899362471909543298700478448553281114092027702550350324373720046757230720"; + "48731736718724459302206059867835027581192820404271125436441919516120222347777"; + "38210977651743308949567656032696478385819661205063514163655683061120398680442"; + "31066571830413162458652431971739961248158700618823531207554971312281336740306"; + "38604214043841500037487247628107100072934980241996056096027128810264297729133"; + "42466391101465852203816440495696613849995732468216567393767726715283921987679"; + "7918626562942975338180644093933988817993856782142079793192213031203713419564"; + "49684155517934574637878829138073579948423899014921699823733824485886261361800"; + "1451275366564565438656353212713435069619539370740288657639758022186872783344"; + "4060684572698408855577084852784974870722088774822168823176048676904575595914"; + "2266042413117404820068618979432448191143223638313669085447265538970047743222"; + "30905627074463551844852560969973865864965309523440254426402110555428247986128"; + "44158908912184255345458082216141321324031565774822466208284543424748103990868"; + "46781765007298128451676105938324040827134620337685516847682075321984346802681"; + "14555474190305191329651931092157102989148485771814319545054338444403258212594"; + "16881117240817753666225190901719116414117517568051590769838881684777210471563"; + "2091384128545629176488696135490230680171339008214937873929334100299232999763"; + "42961581958424980887960069029855144961942029721580484171693959065822644239271"; + "37293380196472166233044745617934489446223933790110588175152241706018245409475"; + "50472789792567303044557428917354654330233740880518444155725173737527015380692"; + "26254591932763759021184569941619883521949754828362687682030335425079808014229"; + "17113230459817249275857268126349806861319046074842290127707156305676386386894"; + "24231753369429127358009700702110183480199277263167907099485750041582214965155"; + "32263789144438090923613388538761009896632203008432412115908330894004664953052"; + "12618230980377962991318338064162350506512133151309212471355044610992713035428"; + "44287411811548063431416128186222883697784161373833563087100707769861270222355"; + "12243970408204409993839495395374510961024300896394362315078558518998085218595"; + "44173339028947996046249077532478888110286784422982124321103998220058630129185"; + "4598274292520003424438601799771684670337297603988895001679632082627567473920"; + "32220511643743595369808381786406376653262724588548158227055695474753444711477"; + "35927311526370278156701529193976259428647110571727767928074012487713280141168"; + "33414541138436871747848548210767170259303594301338319380897399124147207142256"; + "10985815035297592042713783076262430811622978337187158511590030541267680813140"; + "47191419930669230163741552576498932288846324126311314824353674932127709343958"; + "22784828163631611768238083672698851077894334504107657128357294425726824989181"; + "49949907206009595584434917818119046546975686520915136028196584050967515480584"; + "26410109194133218506580932937648982507548919566531870050806115243653049366263"; + "49713902702044838319213158273679308025133803584815262572193546155507722324872"; + "23535559504337049461830629174751216364093038300260308135874588247062574403616"; + "2238775094716444052477495313057898840054408997234199224243609623847342839111"; + "24251437981344168177052800972995593868567104302081741438918736451368941030394"; + "27982993433491253628745454998904820434128996322734239523565021212024510217448"; + "50295838517535590686256014994179135654184756295823594187599260917362939655408"; + "20057613369317870978599836560225006632816653691101308330458367154191918881132"; + "39394614248557203761718739642839828701390805742892989071457854079306409260621"; + "47798093889297880302781161190820961988270610469163421109136182280644356165044"; + "44393568357054115404229042885561023580153267137301539458060374049988839557996"; + "33693283919970625185262931602508844386692612080074318597070832534138700238378"; + "39815716493396968613970558873707844074909540436043586091356171795994263694381"; + "46853573174002303039170539308214250609519855889637324611927935851194802547886"; + "40815147595190732687521587437353012947450179162389073327247952677750833108813"; + "26339521409702735393744068131812259633542864885333572967691724944624282632629"; + "29354121099706613567496209577487729580389509912153101367352651455990974641897"; + "13956682594977060215824578428178631751673652949659210522408548576867791213468"; + "21710651844333023404269198169431081997914625130038397009887765719584062563582"; + "34776931503807259527470945396912938849688359577250098809620069934536239444952"; + "30888022057753192523461569966379378071529579974487499148314453535224010075827"; + "50706911026467569615838130915836644196872403584282694942070640728917921207853"; + "46864858442437162961458912480193558760809343578316469752769914636209220922273"; + "13257506406075894433104506959381001454814282265917832054419709339905914092656"; + "748651022964498225720140702853094466861887182520450179370194887763003477434"; + "9928055927827498106046655953164657438589198384956991765511981535095278477147"; + "17282353886786306350464074480326051762770764361308450866796096466478345879680"; + "1031912496796069267128921308084345914023374178989340573752894044339622888592"; + "25926134979442574649058093555286719859705643564478648509775995356905528815887"; + "15964568489522278652756557360367403556214280414131594187699659173938365588488"; + "38050091280410708232976422594473351403153808832581737053257668228216639900422"; + "12030737699352751292766799393553393267232605717122753898023894800120436351283"; + "28481686315014470274923914799086898836504959567797773710778502159442143532873"; + "34854855773809028752393995264841215192998714650018251274814328745684277843700"; + "23177024339262302793601070921104366455941060951873187433549022636746564985947"; + "32706651237059443616796121926868583069846707958453355769010508784973815882902"; + "46999132467290246174738142479599222392723632370675458675293558263299577721042"; + "51658189751923308132217973966348349720258327530023246552822556444736712390623"; + "6849360125712696557397143449526597653234220520772426233279930720210309738320"; + "37750806736224959930132995620486959583722999721579507748526178865808200136556"; + "20596145017860309309979234965966368019102563566006691095290434157503935075151"; + "41254341165403645465348838011157544897177244154415343520886560798681195976471"; + "39958936321623717554709758924074568269853737880198337327309503417601943446557"; + "19195223398318500029787325435183109593313197618937185661501802900443846527922"; + "10629204629388999052909123660165259102503430047516526387386913093894818621559"; + "22392494050571001911742800275551946666157619565710102369399744439030672915709"; + "45789181983557040436379972210390979168574359994520320974901389101449898971667"; + "31993107635680932518045016097850934312675277860051930648249938294616399737203"; + "41394691516688662849678605584944839500777787870042035604148788674531052718761"; + "4260057227269055804184487378356538538091829237564811490140159259203053493365"; + "22755914276797984949384994213736139778684895539493230631683465009788203482529"; + "40041235704216186530314362855470728008875244931687384625262157538702289816794"; + "6239837510956467015853754603670020841591725704614056805052967999814231026644"; + "29458802836337316653464358527714116167816937061907636047906242601994052671860"; + "10495803222616830164930921154664460461646398358336997556169589368662143070925"; + "22898549214190047583215260016577644830295617833670028301698818524286997579532"; + "24393132143758164018011524734233512995814989110864264594937375305003558662082"; + "35599669100699975483818766527498585288817388816371602239888485323895149359158"; + "38006814568801552692257172170653057840209105926496657875471253681231978835474"; + "37543934971882261953367219974994268988229276972094897853703891601912512732069"; + "15638582370101925565491212811912002274875207706665814348068235624071156999370"; + "31580840665375344887237728746628275665874622958061630557939670052080082572146"; + "12367368728174853025325572761705668347969447581862767534739917589252910852407"; + "6431300041535226336752933722639922185807048849346218384550177388163783622203"; + "25253158156291597068997002534648267078756725939239005896820619368973386400618"; + "32407272173038095334116664653948892086910040424886147129262625126739839822771"; + "13280522211524717536348472783270194511863920959394096229476951226643221055230"; + "16772104472116956787783912564859125725251207740620474891039818280005602295238"; + "9380491773071000549418384879702223304167388163133689178789924347338789859850"; + "6740138750908982892458436295989575152579732709412893038486800886922449522370"; + "48314810935891480393270246846320465418304988645667044400639849377044382785493"; + "49525268202538850726708934355964079225214093569356591960731024652251573337974"; + "10491451908415598562758512398208310743863775903122876297029651957513361141458"; + "19406081409800592976259677521739333450025655891055151006357086244687039619147"; + "13796012858975195466491814297891072959260328291852781745607018638427554265885"; + "6485115628027826708347895792986221021092093804047270852634430130894243301376"; + "7032119811712255634773442378987402663863092963351749353790436863005730387277"; + "49570765767525444909530922468492577696342166915419424004169639950326136617057"; + "1285129643807481578340292178367830355589280266621317949423705788259432932006"; + "3441634142357505544306799203411944242234343920049337423233909232710820734846"; + "46025794658354018692379411175175073186560341494151624685587728046975000562010"; + "12106158677633440534700667787331666286230014762373964286877200484724425265456"; + "23852090676446145451864225599736384585160730887606821819365287956188313561217"; + "4645666973599908624611019322719702479503064932117311025810250241310882715612"; + "27973788552235695206305543261730414876912259984347644517174031345462270738555"; + "43025700336074147238459595423479529842575492457031762291142760348199150113491"; + "11114947607987207788072907159327922005689782074310097245997186074333396056216"; + "49687044256007315302113254820386474091495296180003075377414100433265777233121"; + "10121176151471384524101283711923697637725868232114641816445390512389391879025"; + "51330986445125278830864400207324675203699148153035087480401908084977553474061"; + "47310595279963533769585290517718071207229353045922336729470385238771992063949"; + "45470655810089077363013869164914020509319391456872208545345084082605634862224"; + "40929877503242649981348819772838274267223608227057310481110253536393018059255"; + "17372055570115191467281872597379815744802692968021921450248895690511846645695"; + "47678362609779802562177762420543329986622289631981586798104589503720694371775"; + "26411767877298533345027866329803788909747237313956364077530765489692282596278"; + "24229533690702187779130733022119521753205414714542053126286077188979825374531"; + "18497840321762427856624303545987123524462980182393573916022980133186401139409"; + "926339800459865307621110262317592729066835255833528961455819197753330330312"; + "26987605273411980269258666993213102373601884668454325175338172997856347972333"; + "18391274780315164583236795984691281435086666456604388825240216970397471681364"; + "12097832322841410456967729421116714442525972726222297222010623646121128815790"; + "49675177072983404142217920899359528991366227410655512062504000260893530407911"; + "15707135722931316515055649351245978339654864807851241599499601638769193005324"; + "13383342070542016733720366624023776259361772045149591256080689729754658059980"; + "50987374166360059560703430211826736262378937327825787684985599281463601570367"; + "37692333855557499699736644309219454870696030700215486572270708025082781551549"; + "48478650594548719294793600227459643485482841832424895683273572346673969340753"; + "34197000768287613413510926912918063900967585863143579777915396555872696168197"; + "42341791561950739851197883113950655969381083158985137996020454938455824791661"; + "50432013007639406618408631759754993701106347480289482412566889289659098747090"; + "33561349681426358960433818341708626828528089088226844117603110599540730269202"; + "50705077822458966913066394832821751993904360422435901531249988211620289538605"; + "45812150193659057136265559669604043591894801656607121583303377953470442982671"; + "44899405678979175008096051077001310599468936311348170044304489130853662237683"; + "7059127019337779356629411915385107326268136949565987358909106161315155646816"; + "34328690381291138075517043550284055917545629141111757511239996475405290993321"; + "26939654315244001880568035987806732594072719629182278790540271608004202736265"; + "30814725983945874115800588983627465902316483105630339244815320449875682709724"; + "8398481858488384468602034607148505717684965642826928411240604873022038757210"; + "32368995614504469151394179394757902584570432859893345667551706377300971640771"; + "41155627378215384456908425831665893311330630453454498015644998744726313357371"; + "2153340160120049982298930685564703679245036425190525326118018096283043155652"; + "30352448634031048114241985941470924393535967542582997762031027911599426568195"; + "15261716957885212013251887338156359768948744882202708080437574444095163828003"; + "38989413931358185435843776850185009130324946962753359173722889885807098911567"; + "1704331953122835388982301028858718889034690658545952309945645484614333632807"; + "27403750471903172003031534481941256144265878552723731083968505201259043778402"; + "17562955366799954474182871335569462132288297189443997453618631664362553626261"; + "19086162457604934210305997669117786907689549640695600906760353084525692086019"; + "909236720157425570791649582895043242306821976668909162225950852357093705234"; + "2587678208364293762041139325677564169740285152881638284308667606120057681746"; + "35455340013646018884370176867194236432498101681197729616134222175532845188407"; + "10597974015947868971053495476281648442554475914904865903565006092661125167077"; + "3237760185979457517707698614567204490221992393739789914647016856511321085131"; + "36946097031106423588593893994546210486025823406712493196127193878277998127793"; + "1562072353855994226121886801808336494359509412675230144523806046877228821245"; + "19010448428150791333165899594482872847843192038124839342939985299225110393618"; + "21579288013136572427312994291446922214090964937547933878834394360351661124147"; + "27476725675454012862496969681583556164753553840148186542141037944739225011404"; + "12721482754555216902365268649699780762391451537917039204354173116225938906231"; + "17726161376964586155439029895353641881124547308134311074590598308682629739586"; + "21277449426226092595780141778474905944490289128777491654503164263224221094647"; + "8027270477264632862462234106666097274072824365485884960263030432202348123210"; + "41704607970414222533592973837383672465179394179105424582475027116253727832320"; + "24911397878677534717817496400765259525912587429394942164360589864420581372895"; + "28487683264297785882293411974724574939733908335995066450236207591718649511876"; + "9410945672219127372505114826532796375498170564414051544192375021034240158151"; + "41501277216118808186585885765499182580814856188527129455247808366786573543421"; + "10786842188586265560953543650077602380076591787820349469333358966937440803493"; + "27009619599448135465453464435058428424786314448509662877166278927396974389912"; + "24408090401747031528777292030856366914050775066115322946199273876732066533603"; + "27717428010589203122459895369508850795775086801529508808907903171549714517552"; + "43961339117528688303727933814338246842560025117902212123957164184934798616272"; + "23539099267901977681530985543753979115801969780392578671053292012737090359960"; + "29129130787064690115403858309463936784595038310196943453528132510780666740275"; + "11544217335881527838309935861738104229903387666758470620902798348360616219319"; + "33462911116491023898914175915108269500003786821526355903193319352945031002857"; + "42971396791389197300566908724428992708740412328465643262012289069601063353167"; + "11114100576866102546082991452575837001302257906574345014759165856210897893390"; + "10869503142950375121273168986955759969708630281326506993743041491528703068926"; + "10056285389986129969950435124477608942343465496465667661560622683088232566646"; + "34352912333098020699609122066221942402647202729511926372551684177727356125767"; + "48815653149287031584900334425973245208502245603175731919813468058312231051539"; + "27279886970331272055453009825591093815823325722521311734285899406328214417219"; + "30743518328862506788849929078973418258912120322041236148115187319465176865909"; + "23836593777410321994736212695067663874445976812493472680359497431194677069707"; + "14271245249714372701863366640280358937336173352148459212765723706902523416666"; + "44751389477552162369260519320913279071846090137697398153616721749914975209463"; + "50049310530591903842202745108285775951310636397993830164309261859077944727008"; + "31203592346501430398694586706221740358145194595166035656399113862917383342162"; + "37447642270457825605341454299863838011561200065009939824839354876147406554050"; + "10574164763913009315349684560659607328049286937437594137678635676492164664990"; + "38325320802240945919839117157786458966683186777304529608044491498455717130551"; + "40805013056129827384501225380368635414535634360289381317746546936202290112538"; + "48333388268805149543196989643320441803480506998791523089965182033002284368947"; + "5782032582803275485235374665654094879290446054520008831705805183845211898185"; + "39802516355118908351021607643423040697458583372235828229304343199015399090975"; + "30492929460132725992608458300060364368351457395826268799884859998700261205304"; + "1420460004901060161999428487693270028427827250557258348019289211566581365454"; + "44193635056304562477505124994430538128890073548458826363763791536481254794966"; + "50720689419341593983069569011764146978553260482771698590157644701830829402947"; + "8073796990034033964469665366473997793181957677797087439421280810770488925256"; + "11918471565012754466601744707948105395283969402172028499903545447868170529713"; + "20077023346487118481621638270056399928015669807959870935567399723256898313150"; + "17213961046117186209464109755931248173988132541497089384021158920901269721090"; + "40806924151578521440897441275485084726249888295413627153644179743836373627459"; + "48180670522504204627184158154001766027012194162495506518370446939968021666069"; + "42003056523512230201797933267792902549574504149012715622767056620086275745478"; + "45101413241990392158966509799943874633896537344671548489389563011092925383814"; + "50587462404507583069240045742171989746743467775065297737509970837012535861612"; + "47815286514663372521264717191280262614050727424357000042525142008994950651639"; + "17400463065364361454879212497416099212109445911086039739080338012549330324535"; + "18161390929522210528368217943618859674698687969813941340329551243423634163215"; + "14441574882494975584903294130579023104909680031021053889713767896122879098657"; + "21912867184623729582081200571230217079961934918095841057644441114392793081978"; + "45361556540636295590917957481529238741505687644950500354869312727558668766825"; + "49539592650928368969231099603636984862255298622407911855462789343614490745974"; + "33869060934120743008239749284289212363453006243904282220127716668152965210748"; + "25076370715589585424326332620725315977885925199077963714556765297037513234989"; + "8002444064393390123216308842243771494245898705227632990107898963043446382143"; + "1356017732914259689267113844885694824971954414004791084036465384478863651474"; + "18698831976592497490869840317995921745505006029532075513759064786215310313034"; + "48836462159247124316625665463190819813831892402600021151195654650125270340651"; + "44079217861342722911981257144373371771560838079739791623631524927582118528474"; + "7917860632115468421843323257057624091855319060906343969030682698738062187742"; + "15328920775298393985301712443835521222368870056830753657709551066102881234707"; + "40585149282725386186676237190866920474926692908526104716015727560418525066965"; + "22476618951264551734672333363230193505101669500810396582135708891630628995331"; + "22976271519589645590337728787979950618802152541630285510037871742827357400405"; + "26490418622799095788111021654113322288820745026736077183862125058416171724885"; + "38668434553373591212556681994380448212723195862087041826021901890569924770065"; + "15734290460192933229142204966761293110558662629712541767317274191859409979185"; + "50708043312916419002750805838232616804578377791118982931279441695110104859619"; + "25661993114668520552639676665126758448336667422881593126449325707247794604888"; + "27300404692554829310057036397197575379085146250686335589922839236734268293026"; + "16616950908374247513630471498870667771958507881588444010494951003904728142357"; + "780331858290974370698544345229396895975774808594696606255314479320722478183"; + "15356252408972709076003921799298413990129664042289284426790671672668901277378"; + "22195679839447440563352896996056925121555070971714547978827589453261615780585"; + "50055031037344446643661166893394701232488862253278315780297281928041839024491"; + "39853343710092418340651301215898149540667450843137399936276811087705281337915"; + "41234320088350200826168830307183441504603558317128457459369045773720261208509"; + "41026304730141400072631269150112787967137999190332230376064990660056537630883"; + "46270298741623878847116335581496501056187952274321389849457282429215904661001"; + "24229852243440737653059813128440054999089637857670449169075813133344895934250"; + "8424306277967302875586430461180994699747156058101091594395383080190147483624"; + "49672959835707465722916473003774662744770586652374151972176418791640619586394"; + "50953606432923765425047764715621990710996981237692942916850916691445210588986"; + "44233571495113761415664137120393901177879884654356773130439945796774579578083"; + "11574634161412767461102549430739220546934205978274834090884125505175189074069"; + "8645184998607708462451095150206729904754427459024724873922986748255464652029"; + "37128418642109534373362468648382548670038346064741412903988995594256056481978"; + "33355443735171069266537113956815564199390017657125748952951909212993930853609"; + "18346976095151853612362092673379644124598042905694460090917547301686808797968"; + "32646375704171180130330224041820560945074015817182291941815877259349052407072"; + "43225167886161343156931475989059671126108470737009680929793198947446394575937"; + "8816437937287404337360397847635602367292009763466086832728768883240427981891"; + "38366899091948084905344245020593946957409036781563456341174116328327175180679"; + "800298045483712205484307334575942288725541659796453174814416446066185314381"; + "14508830287813168002435636185480014871079716479693496544419639273961439244196"; + "19123558056196698077756824716735733526899307503111963110801154666985150036515"; + "16303389189674597252380274616649999385814924811197807163354356674102789306574"; + "7453668915100625394664770229394717267390236182731660405097681417166662567678"; + "38798071571359045878565848619638213488585154176099273867945877100609620185282"; + "36631959497302172344707808434460251250381882633514089681745071353294520523286"; + "3295651438846461067006904471387575625423106106098387875100629738076787368486"; + "7639968555171428539513522652621621046079902482011709740085444603640503656201"; + "29579395581332007484259733934571852879364872891046795155379474874395906573519"; + "26653656757216667921153411281655535324426792606630320014981412395252223538329"; + "33945142010095644499737879503783227769340995607126548035094938552106092827502"; + "35659738763390756446419442911986047138385980543377566364330341100094367895238"; + "5380796247086464908504473508326895383205443609034527483380059328805596144573"; + "45555109220928268984543580497682265831199280528890734732631782982445734750732"; + "20535285005178766298291665162439441374276729776225027287990176172368474655430"; + "42276900911794446922826515302740555211179964292337862181106694848183792840849"; + "52163438563491625237964145588646657521828399654529930322643039527692977471445"; + "12381085634185465518625170120342681595340115886064341209590250417404145330796"; + "41332854461896499143467401552257229221502912725720917689641824107995364172760"; + "48130816341111135562667996573877686235140742636682402903593978927062615809300"; + "40708352896435303925197058053634288518207618858900910754332784721266337267119"; + "20414673166470607272747811391805104245858774907937409341200492727939746607797"; + "25627294268923401583055123311122337854601831198810692741217863178401731813982"; + "9471796077791050250358831370212483753463358283515022318409978072807223150958"; + "18314066421198133015325418115287580268791041525896152562360347711250600527843"; + "24017014751842644177743018360725989342257842302110775272063931146838823820708"; + "21581200003538126245980521668237719802680919088433705982480735447972766043363"; + "50184800347056048262055270151626286042367002765576087001102590179487127900402"; + "30495886812798520386657837931015291018488945515192090129642139250370928693580"; + "22576369160305502855935040778001809663355224383879666287087499574629468037932"; + "8892650559142637497217516060667987141940174680954367407928503085925759784531"; + "26585722842364766084323735392097803839711029569348840728693523172589688253154"; + "29233945065322679878626700781011757896403829828629855948960912667621036626304"; + "46495499699253457275171950570731129922763854056949062569251813711011602552765"; + "20175726311806847923316241767174947396593584808993154634747567993383544235788"; + "4439738901982759407797641994447539352385040803130129830312569441261131407125"; + "16457982232415810076025629044220925770877965806117341776311181746417552277025"; + "19907475632940820992995770155453308899317289306448422338160567626015082798255"; + "35223042914091176169939921699730780563001221818541154418947974752159293542388"; + "43001533944345692738449547388403626716967932955110192080457393496732555299619"; + "34125500451758985735535246859157148109918522814391361071782479828094264751521"; + "672210927468386341214054725731176563716514412831001669942787056703691451010"; + "11955392088705171556964578398079500139155403309741307240924960466165999666255"; + "15001212103447594119920182143104283078666143755444714277900928289186853558391"; + "12494141652757315459070169705561134159399433995127302554127714989589492762158"; + "12539864421219420825268500409099786634396457699752281899702857644933872397743"; + "43101784081867314199511257387329290804750329977663948322198895874188929154741"; + "27446223298884346343269149146243911653385549792135607763714158002175305061634"; + "1221810201232089129932400022193871837808173942749956359312713538906718836479"; + "27532908760517365244003806543506083069460105424541918130562804937168539380933"; + "15648693309686663323928562339596607937964297674438414931587554610267850089762"; + "51990644901841817393110558619667069965078896715337659449054804464607693143160"; + "33794620192818979295379085241975052389791263016087838781391920545764975674473"; + "101607244559760430212506597577050204264047733826203142005234996733194535803"; + "40666396311706682608077428065814708907526669028006167240560016976036610792591"; + "12093027072881844562446294223504358738044964433607132404028203137662407596800"; + "47855031407689076102071980457490179464098686349841578053656622219683394194927"; + "22887362617646323246137538576383771868750784401107098034751943222440904306549"; + "14772206578599333281746941359370160645118537874167329823865244020069915126081"; + "3526757700545255914615010391053602312122669226422265428284197630347896730651"; + "33007891082396853981232434558524697472333004416828682481099968575992162687374"; + "31988013417414141593906072198372172527694109442594239825489920432494911766933"; + "11191961053993644897418397896972876540611743197344140729636835194462710841804"; + "21880105207814770273563304401112493784911759454461136323535459121487533758411"; + "41486397989964301339068924325783394852002678141033490060445600519554945226014"; + "16498626461620337833657560298722288376309400783422382991374550718050901966642"; + "24943377286264067314569680564276927094588309007929081549392361988305161867433"; + "37986591875971070389212991388767178111861904302329418052260086662061715255565"; + "32017690217798460109067983234755326443554479110662411364776709358644611216536"; + "11268114558872136972649888237328080074799940976672472351727712756343878033991"; + "8553866868885110753717367996095488037219349823019339928639756785019374917125"; + "32329156174505548357975583161085823726178367498919221564757310317285457845069"; + "27211717469524004207872746964920608620364761642576492559180465819096139390446"; + "17951459528837145129192967424193834007781706018124597879528401736511208623124"; + "5641081412497253735686285180366403504609424502347938813022628844058433088254"; + "44149401842640426661188167090997457203149609985845860407845476505741286527400"; + "1131272348428881671180311242049529569730380344899908988923912651593170365621"; + "29408853361809783058473821719041796914748403385269196060920996759386405450822"; + "46397512824547164970111952967961313462600614947138288894235958387784135997027"; + "47516645729584090306484976699637881381716439437813917167035708795500295063993"; + "33055093158354315225697732538526252497152864807143121380155645175831367997411"; + "2483278713512874912077821925021730472549918913537260777217235941375925483743"; + "48815704230612764031863984553515469905544143230929551627072471933945117691529"; + "4328792740667001536219824544300358343992356873304526946361038441974068375040"; + "8936186593485597641227715388671424329734834396891419524831642301555170823192"; + "17951920387101669293331644306482124096994648510679825947980062912137916768437"; + "19375514622607648705471192919423809092605947096218527444759114794843323604399"; + "29610094038370566321951750688045410763551744002173884016718675203262367949199"; + "26412332356216088802741437584182840836365448342900386978712282658982011423028"; + "6857200692997830027964569096279902529051039382386370537664642602910884711585"; + "23793860449672430773141781094420115804950727589006926766592001526772413630888"; + "48757257789712605511132590475466929307721670979642060291457808809543669563707"; + "41645960082452856575583766422864660930176349173234319988174582522281045680944"; + "33000251418643291466811739862781501771791890505914908533407925955048210111449"; + "15394914111369858819577264515844393687512099293048804309053356275657357176587"; + "8206746691969770388090261805798801614135957851585811798250200766530283892894"; + "8853211220347505554369001872046201218026106125304684911336722654414177119527"; + |] diff --git a/src/lib_plompiler/ark_full.ml b/src/lib_plompiler/ark_full.ml new file mode 100644 index 000000000000..9c672b417b88 --- /dev/null +++ b/src/lib_plompiler/ark_full.ml @@ -0,0 +1,215 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Come from + ``` + dune exec ./generate_ark.exe 60 0 3 "52435875175126190479447740508185965837690552500527637822603658699938581184513" "tezos_poseidon" + ``` + Commit 6a1e59a2cea4392b04b14f6e7ddd03e5d818e623 +*) + +let v = + [| + "12824693747017958656359741899350387676664089448183168620817941350923622240383"; + "2110512952725741187549618038800597171689376420770588630765413738693257923365"; + "47326464895396585099705735602023752272300355108131773128388570963521922081510"; + "563012381688126180539569880290185949096875479968107613527817326352434592856"; + "20435639598009869993321661794628409935886243780150497184529212840833664449656"; + "196568005014908906943408140878629143505019528204274239329256802017215936683"; + "25962654684949630743270090458873017355613280868787190166613423196385364109406"; + "2902949562437765068560667705637724057704859748759440393767306205627156631635"; + "48765024020816932517496715131525675528890199049120440892483976763745835117858"; + "2521254722031505239112642581694420959196804419239024356676547276184406685162"; + "51021598403923227244919665563608069313986657641358042233506839666746223886174"; + "1054116206618757673158081612917129416032354356767130085800942497760890427733"; + "35527058233191932797057544076619925913363578197567288806107068259245425979761"; + "2634280023212643609442836838440917786416264439095063634117944443782024029279"; + "39421919986269102473005636801607717780949112929566701303040428546494236832142"; + "1108697190209272403800986208961553739614858445125481568510484181910492195628"; + "12045800443981429031896147388217433545754425883946502772543316945784413417019"; + "82604952988294859566853552858162148408810580477764040175328077158180638032"; + "50270776669157712293893033630792805271843351375068235098934380606286868420081"; + "4556699357166547420252702363071964093628547740375189594266494741118120185875"; + "28756618406604627864560204181157146784905823733084273636904787891595217041493"; + "3929061368963303543382708474487773927696676445825720846075125669855529226465"; + "18077432337068904300805913007986258320260964944627469934418526215049004418850"; + "555694305263590606473308840289036435744336132072477475386605456741511841112"; + "19540875247789686897819386841067347406140142379787247556508575750097457102800"; + "1448707275568454674766116478738872398268409443096166848018297610768625046726"; + "1365035359887233236958701559549281683572920146548303300137734899617496459320"; + "296272530549376935987465863345169666107896810662168723956830664953961522362"; + "1222008471833248844130489923076230958939009980056422343699249951036863250406"; + "4645825111751650824509927275187472476744269268030571538472557623136712967534"; + "17367408524064290797098982556349219497014777382389461167580403687601422907744"; + "4067034309108034062368247356825838876451720740358475567436606187615273492134"; + "37464072930817278139129480285443023448384449803554018863125599103193054747940"; + "1154923382618727721537690770667336978399240055012120552776957609043905780309"; + "14761222603381544767861781252566790400337820585000529592970728629846169054074"; + "3913916891269533795763393633333348732307055924078927653872560295421023616912"; + "30551679780389794856358102488913579915189391919966614704474658955963931924601"; + "2623945794554933981603577446997424920433800054981268118099374525963300203599"; + "37553485386488789278771814769828299823440779111850352710838985845411101822259"; + "380971882976374898531171928157843618667556427594941784718505414050004483900"; + "10017112572864832043140346277015863860093483928149059067819681230371941944219"; + "3260482321812695850957645581839558488578671815239403289847780027429591624886"; + "24779434793361163444013176816239053406573251563355730673257372706459004109752"; + "3834722693939583529892160907115156917875416106150610312937809427157623722716"; + "34750922361865676680499065756842369674722176279862565574651223917853132870768"; + "3303719823632917286146798280923324860357977348797342300199305695109156084208"; + "26018601582375751114157841612900668552714749858338434790831374188259468891657"; + "3760594088040850818134137825940561088098655326719629222313979094464767486270"; + "13502450637194424997028192825724613739600481337904104764037861753271786962154"; + "3605680875487475312847246627162938193404148815924719449117458482311523099581"; + "1768114684013685999050765210150692485022620153369626171927007242630684789096"; + "4300220668885208831825911397052406422843855438064865963936061488194010074168"; + "18745557299904421052970946495269579008489037727912355291647391635546797208632"; + "4645457313953861508779197981831082874745930614083957226744023638183119182461"; + "42593678790199145995053663684457815472221401417968114050739948072903660677857"; + "5212185812251048319934415989099832693177800787494715126453056611778087850419"; + "46864418721234297280212054571065932300397971297089783351260370088468371917403"; + "2146862295982450015041164285322066583154859608755785000444681979186258495373"; + "8187097041967453124034221635232536216422982441145700214410051992514734925288"; + "4224999113960856492299018528652331073564580004734510854400184247450883619801"; + "30046896000436459201509816995297597671241771046506201400670561663285639550013"; + "3537680698171566937918232502260485817476747029597018017860969285562087473305"; + "29039230731296834920039750344384481514120570535308392319591127087253572446056"; + "1606438979398798927061442150774687036977037804022029261455207241963834106184"; + "13557605550047888935773187080216193242098120252733035588710110279228568211558"; + "4047232145173403805626574199652440367464599106022640127004814141382369658995"; + "13204459193235673971472938035767571814382424793239200188612833165825728682829"; + "402759581944588848536065968240655767930356875210759037966670648336820844993"; + "5838980428774315696686158048972148098130544622501946984994509263591215395426"; + "212043992009831062312891996009060873100128030094171369513299867713516707664"; + "876830352021192217070586013687495740327679213978361548752554043712663949468"; + "1723482914175782687995738495132376039217305247514006613000060283960703558701"; + "44897949014063901955262183967378762018315399981354658326614944928036171768047"; + "1720524035836460098857648729960831988475356761611522787537468077531871738788"; + "43232942027991143475140536337799285287865381320563382715279532867764648867343"; + "3252643389239528156413547074205644285947056504868291498315445124123379223565"; + "10501927276217087031424106573374495637897264496162726694675925473163376758193"; + "4325213853470237890206153973507029163989200227464401797030473409932385586888"; + "15305409251523914230874353354359535059788180981148256493285783828590358196576"; + "1739088134521595648770955683947418709594948489272099893671540048413474833655"; + "32836121401171582866382562943435811841830890811447454667735502397559445574318"; + "2901016800212051377264230669011255203902656783700704539355895622617107865597"; + "18815036596924530952853517621791049640817225487294772991941444704465338992056"; + "685537555661929777955438314288998219757370937229000935628653593362061097997"; + "26092577718767817009266451734151117734467338290919197691355008501655978991425"; + "4216357646309051699951224324469648916897535233092166120987090957075738738289"; + "31651422971070076111196181838264222722181140435327367724766310272862029937859"; + "629273769938900575895441455920675770217393671083647396550016241217499324566"; + "49724468201334828484280244583213965018137667667628337917834235809476876208008"; + "5210665945744217681330157776482926914045721426907722878216669851069550177848"; + "4935444078547826859305672957116002161830310503792073317090488754376244453724"; + "2370975635708536874252971855221791566193989512753728320307480329583888109494"; + "12657496430857347720763402849538700908097732721541800130804971089165651345439"; + "980832203819443439644734094470578305034581183188994771638665578524209909644"; + "27624504294839473686174359070380877344474774819842315451839377969297427239166"; + "5022587565141243376613052649543532876939784755313934472399483321884982186845"; + "32243500134899591779833917317813896966152474894081029615308055451608309817241"; + "100058643858172952146053373048806069099381607603198359470716853088744003679"; + "43109176463952975009536800326405985839082072267836336547187198583087609692365"; + "3590740318354650377127325932768185673866050589216143382199884746038685039193"; + "18785827894321389879001098955985664874180601797364691363126127039762235438445"; + "13890410008915784125744184986842184782250517952645936447684522270657173623882"; + "457536797603734775438134778206691653593049060998477675514667726182894217912"; + "2551079617981818063329006462059001797540515944940219006428117815680076858166"; + "21472457723313943353708874304761694714619626622980133761654506137648304099225"; + "2369717436916504560495435944043536132023039617669790790048479296810831115432"; + "7031013180680842790541369815824254589599329901607532766080140079583861127670"; + "3186817293579606399172870922861931912987218438361533401014989932520483054661"; + "47464742696121028517360413317566460057783566948463915502216100047989262604494"; + "4477286400678903183321675636378207967509823582920376282336875179455466716185"; + "39603832419325005862317577496738452690938824170495474989446912069120567958633"; + "2298800618215111452558013082674860261853363711292796156530795711139925791857"; + "14989846812350944532382882165944724612680358022683579364797569235893833338786"; + "3142685991363476580093079952421569893866001742073784831979945318714331027416"; + "43769651300419944305850468997800960823562418250967725486604486195418246726438"; + "2903010404487914441440543971760165793498717412157398998979659478200111849610"; + "9127217127088119714695972218791177892622662022240237903196570849597530951732"; + "3027763266097571236073965528146797815724807342368263722325647490051351338620"; + "45161221133645017886711261601412531524039384492647873241614048192451822952596"; + "5202754415287792674027662002817505616467813648816826423072323182431484254763"; + "27242140821789243686202266747999653182843137901581640581966605089789849278720"; + "2486352432460205806125626579336554262523134363643243180816080025739061947057"; + "548204231964608561639273529292263414738211059797673641169135393526364027262"; + "4716993594931512860903097324666779737924835078698720901019262576473692405762"; + "9506462229205667401284173411406418258324116909359296336613315546137690056534"; + "1391686368350831625873076044206727120952405196977265549638557303761750998100"; + "46689858246492672703651527423393431292021158320712191462510792543052803111584"; + "1580620578339082387096281340287752692331082813664818782512432430199720845842"; + "8766399310646135463189410004038455360577767145004053413178639873677861998820"; + "2658879060923784327242573848583806968749526761176482702552450732606621976196"; + "50023792217818549536250470523936352020694495495726497073388852837421457132933"; + "4272193681116672267015435255576813070070642689876644167010407346355080628052"; + "47324445308700031888467261626081375992699772780707953194100484365789882431454"; + "745357856006460333137090209500374787442676746021883329936925355341586796125"; + "49684264081550689554750192283845385456679466775345577580166109490155297289216"; + "2362271878323037569608969923690509680390263526712033638784386254822375382291"; + "18892236458444926391262493369877957647095161647121024401756307555714456905508"; + "5172043182544854738478432023277651888486154164999709997889182042094718363590"; + "47112383745286980490237728644604959772374713243485506526636290531977086233783"; + "2468514109210073002795444989278838981077281022625955381003550228078769970142"; + "10760484429579733150748722744770630969539979733239758562622191462913951088333"; + "2172407928705313709242510853013332534382543340814365168104730638847087842171"; + "6739500805755904550287601060022858357500641732900792528669270754636609260080"; + "1785796504238035894463054840331280673310114293716511701617293846491504923269"; + "9632508482164659471598107352396309307790306866273893677886800050425109716792"; + "3314620184087009191069387298030535408664868853185208251237161964919487311583"; + "24563068966148861590901041758592735266698568871660764465875702639116829646304"; + "3172137675500596733636646012235521148230652144749098341049366473486393549037"; + "15684550895396068515471028729350115969732417905333858769590344727369384081603"; + "700248760062686294999986760567278360019832000799190116197996203737634652720"; + "52307485942779459117858479272884228966231265749455272562573874738583619442420"; + "3883657152867570661880089300888026858157645675554719017373884998602380872572"; + "36723879950613977022517261564575507578807019198561897008776817934657868063385"; + "2024835079941342579887433286943199727995352689418525852979628443261099900191"; + "34307840796460362263279500909803958773744979234069495184913872991803774632950"; + "1194435145355209307254189344049195366662231267173012479411964865421960287667"; + "31014650885457826200510401438820002615957776846470325819050879782587513039513"; + "1948547531889945681084691849162487099956320106182019457285868979225032808870"; + "6993260155372174998814252121448583176110548765257321055692123275495549108628"; + "3628614090784348512068372896311673975933525338121052905825942452210572653989"; + "45808574143983102919560752637917514976543075616407947885927216602050326197313"; + "415726167905886898791646220028599685530282471266098241258736873574263892652"; + "38246990752692475328034119997100943294185371168683274197027902045227898059034"; + "1110392451982987995401832490062981110412534192161968804207082758239406833706"; + "27701822355979751474804532392435063061435232116617771073364561464566348695005"; + "4827132391215463563392983490012590712072004147843077585296803565588789328685"; + "7564632283106849394053909408180466805017839429085275010245344373283947508827"; + "2324327327872781533558464380069138496744200643744710345906001952054490919216"; + "13140798650640322980324706670787476707003590015760438979598890984450151901636"; + "3500199380257986467636891750311499575228052306333324812280355945306510138466"; + "28542459574187611357589932976824304434500408729772997945459318680944578211015"; + "3781610762060567361822388324763082672099242323641256901088184397031508534814"; + "14987021714744452231617911764306940261543565067899914241289807445701754462007"; + "1609241716573434851069322332824879589864503452452228361611682688852939169278"; + "34897051546770181831280754566237511483765525227934927588069926033737344741728"; + "1399786866593207439943434122192779159950880088201666748148964449373614133655"; + "32272666727605419884137989690354170945870520375570572628324661236539945300289"; + "3163147813994452717406281941248221080830294034049663043880208950896403668492"; + "23810679194694574195614528371448302918064916463216895875739808511793511307298"; + "3649117216925272192207726573369494771588983064037158465279599876172844009039"; + |] diff --git a/src/lib_plompiler/bounded.ml b/src/lib_plompiler/bounded.ml new file mode 100644 index 000000000000..74afb4cd72de --- /dev/null +++ b/src/lib_plompiler/bounded.ml @@ -0,0 +1,205 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Lang_stdlib +open Lang_core + +module Make (Bound : sig + type 'a t = private Z.t + + val v : 'a t -> Z.t +end) = +struct + module P : sig + type 'a t = private Z.t * Z.t + + val make : ?unsafe:bool -> Z.t -> bound:'a Bound.t -> 'a t + + val v : 'a t -> Z.t + + val add : ?unsafe:bool -> 'a t -> 'b t -> unit t + + val add_left : ?unsafe:bool -> 'a t -> 'b t -> 'a t + + val sub_left : ?unsafe:bool -> 'a t -> 'b t -> 'a t + + val succ : ?unsafe:bool -> 'a t -> 'a t + + val random : ?maxv:Z.t -> 'a Bound.t -> 'a t + + val check : 'a t -> bool + + val f : 'a t -> unit t + end = struct + type 'a t = Z.t * Z.t + + let make ?(unsafe = false) v ~bound = + let bound = (bound : 'a Bound.t :> Z.t) in + assert (bound < Bls12_381.Fr.order) ; + if not unsafe then assert (v < bound) ; + (v, bound) + + let v (x, _) = x + + let add ?(unsafe = false) (a, bnd) (b, bnd') = + let n_bnd = Z.(bnd + bnd') in + if not unsafe then assert (n_bnd < Bls12_381.Fr.order) ; + let r = Z.add a b in + if not unsafe then assert (Z.zero <= r && r < n_bnd) ; + (r, n_bnd) + + let add_left ?(unsafe = false) (a, bnd) (b, bnd') = + if not unsafe then assert (Z.(bnd + bnd' < Bls12_381.Fr.order)) ; + let r = Z.add a b in + if not unsafe then assert (Z.zero <= r && r < bnd) ; + (r, bnd) + + let sub_left ?(unsafe = false) (a, bnd) (b, bnd') = + if not unsafe then assert (Z.(bnd + bnd' < Bls12_381.Fr.order)) ; + let r = Z.sub a b in + if not unsafe then assert (Z.zero <= r && r < bnd) ; + (r, bnd) + + let succ ?(unsafe = false) (a, bnd) = + if not unsafe then assert (Z.(bnd + one < Bls12_381.Fr.order)) ; + let r = Z.succ a in + if not unsafe then assert (Z.zero <= r && r < bnd) ; + (r, bnd) + + let random ?maxv bound = + let random_z bound = Random.int64 (Z.to_int64 bound) |> Z.of_int64 in + let bound = (bound : 'a Bound.t :> Z.t) in + let maxv = + match maxv with + | None -> bound + | Some maxv -> + assert (maxv <= bound) ; + maxv + in + (random_z maxv, bound) + + let check (v, bound) = Z.(v >= zero && v < bound) + + let f x = x + end + + module V (L : LIB) : sig + open L + + type 'a t = private scalar repr * Z.t + + val make : scalar repr -> bound:'a Bound.t -> 'a t L.t + + val make_unsafe : scalar repr -> bound:'a Bound.t -> 'a t + + val succ : ?unsafe:bool -> 'a t -> 'a t L.t + + val add : ?unsafe:bool -> 'a t -> 'b t -> 'c t L.t + + val add_left : ?unsafe:bool -> 'a t -> 'b t -> 'a t L.t + + val sub_left : ?unsafe:bool -> 'a t -> 'b t -> 'a t L.t + + val f : 'a t -> unit t + end = struct + open L + + type 'a t = scalar repr * Z.t + + let make w ~bound = + let bound = (bound : 'a Bound.t :> Z.t) in + assert (bound < Bls12_381.Fr.order) ; + with_bool_check (Num.is_upper_bounded w ~bound) >* ret (w, bound) + + let make_unsafe w ~bound = (w, Bound.v bound) + + let add ?(unsafe = false) (a, bound) (b, bound') = + assert (Z.(bound + bound' < Bls12_381.Fr.order)) ; + let* r = Num.add a b in + if unsafe then ret (r, Z.add bound bound') + else + with_bool_check + (Num.is_upper_bounded_unsafe r ~bound:(Z.add bound bound')) + >* ret (r, Z.add bound bound') + + let add_left ?(unsafe = false) (a, bound) (b, bound') = + assert (Z.(bound + bound' < Bls12_381.Fr.order)) ; + let* r = Num.add a b in + let nb_bits = Z.(numbits (add bound bound')) in + if unsafe then ret (r, bound) + else + with_bool_check (Num.is_upper_bounded_unsafe ~nb_bits ~bound r) + >* ret (r, bound) + + let sub_left ?(unsafe = false) (a, bound) (b, bound') = + assert (Z.(bound + bound' < Bls12_381.Fr.order)) ; + let* r = Num.add ~qr:S.mone a b in + if unsafe then ret (r, bound) + else with_bool_check (Num.geq (a, bound) (b, bound')) >* ret (r, bound) + + let succ ?(unsafe = false) (a, bound) = + assert (Z.(bound + one < Bls12_381.Fr.order)) ; + let* r = Num.add_constant S.one a in + let nb_bits = Z.(numbits (succ bound)) in + if unsafe then ret (r, bound) + else + with_bool_check (Num.is_upper_bounded_unsafe ~nb_bits ~bound r) + >* ret (r, bound) + + let f x = x + end + + module Encoding (L : LIB) = struct + open L + module VL = V (L) + + open Encoding.Encodings (L) + + type bound_check_safety = Safe | Unsafe | NoCheck + + let encoding ~safety (bound : 'a Bound.t) : ('a P.t, 'a VL.t, _) encoding = + let z_bound = Bound.v bound in + let f = + match safety with + | Safe -> with_implicit_bool_check (Num.is_upper_bounded ~bound:z_bound) + | Unsafe -> + with_implicit_bool_check + (Num.is_upper_bounded_unsafe ~bound:z_bound) + | NoCheck -> Fun.id + in + f + @@ conv + (fun (x : 'a VL.t) -> + let w, b = (x : 'a VL.t :> scalar repr * Z.t) in + assert (z_bound = b) ; + w) + (fun w -> VL.make_unsafe w ~bound) + (fun (x : 'a P.t) -> + let v, _ = (x : 'a P.t :> Z.t * Z.t) in + S.of_z v) + (fun v -> P.make ~unsafe:true (S.to_z v) ~bound) + scalar_encoding + end +end diff --git a/src/lib_plompiler/circuit.ml b/src/lib_plompiler/circuit.ml new file mode 100644 index 000000000000..283eaafbf7f3 --- /dev/null +++ b/src/lib_plompiler/circuit.ml @@ -0,0 +1,1435 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +include Lang_core +module Tables = Csir.Tables +open Solver +module CS = Csir.CS + +let tables = Csir.table_registry + +let one = S.one + +let mone = S.(negate one) + +type scalar = X of S.t + +type _ repr = + | Unit : unit repr + | Scalar : int -> scalar repr + | Bool : int -> bool repr + | Pair : 'a repr * 'b repr -> ('a * 'b) repr + | List : 'a repr list -> 'a list repr + +type input_kind = [`InputCom | `Public | `Private] [@@deriving show] + +type trace_kind = [input_kind | `NoInput] [@@deriving show] + +let compare_trace_kind x y = + let to_int = function + | `InputCom -> 0 + | `Public -> 1 + | `Private -> 2 + | `NoInput -> 3 + in + Int.compare (to_int x) (to_int y) + +type state = { + nvars : int; + cs : CS.t; + inputs : S.t array; + input_com_sizes : int list; + pi_size : int; + (* Flag indicating the type of inputs we are expecting. Inputs must + come in order: (i) InputCom; (ii) Public; (iii) Private; + (iv) NoInput (corresponding to intermediary variables). + If we receive an input with earlier precedence than [input_flag], an + error should be raised. *) + input_flag : trace_kind; + (* + Boolean wires to be checked. + If at the end of the circuit ([get_cs]) this is not empty, their + conjunction will be asserted. + *) + check_wires : bool repr list; + (* Delayed computation, used to dump the implicit checks at the end. + This is necessary because some implicit checks on the inputs might + create intermediary variables, which would set to false the [input_flag] + before some inputs are processed. + *) + delayed : state -> state * unit repr; + tables : string list; + solver : Solver.t; + (* label trace *) + labels : string list; +} + +type 'a t = state -> state * 'a + +let ret : 'a -> 'a t = fun x s -> (s, x) + +let ( let* ) : 'a t -> ('a -> 'b t) -> 'b t = + fun m f s -> + let s, o = m s in + f o s + +let ( let*& ) : scalar repr t -> (int -> 'b repr t) -> 'b repr t = + fun m f s -> + let s, Scalar o = m s in + f o s + +let ( >* ) m f = + let* Unit = m in + f + +let rec foldM f e l = + match l with + | [] -> ret e + | x :: xs -> + let* y = f e x in + foldM f y xs + +let rec mapM : ('a -> 'b t) -> 'a list -> 'b list t = + fun f ls -> + match ls with + | [] -> ret @@ [] + | l :: ls -> + let* o = f l in + let* rest = mapM f ls in + ret @@ (o :: rest) + +let map2M f ls rs = mapM (fun (a, b) -> f a b) (List.combine ls rs) + +let rec iterM f l = + match l with + | [] -> ret Unit + | x :: xs -> + let* _ = f x in + iterM f xs + +let iter2M f ls rs = iterM (fun (a, b) -> f a b) (List.combine ls rs) + +let with_bool_check : bool repr t -> unit repr t = + fun c s -> + let s, b = c s in + ({s with check_wires = b :: s.check_wires}, Unit) + +module Input = struct + type 'a implicit_check = 'a repr -> unit repr t + + let default_check : 'a implicit_check = fun _ -> ret Unit + + type 'a t' = + | U : unit t' + | S : scalar -> scalar t' + | B : bool -> bool t' + | P : 'a t' * 'b t' -> ('a * 'b) t' + | L : 'a t' list -> 'a list t' + + and 'a input = 'a t' * 'a implicit_check + + type 'a t = 'a input + + let with_implicit_bool_check bc (i, a) = + let check x s = + ({s with delayed = s.delayed >* with_bool_check (bc x)}, Unit) + in + (i, fun repr -> a repr >* check repr) + + let with_assertion na (i, a) = + let delay_assertion x s = ({s with delayed = s.delayed >* na x}, Unit) in + (i, fun repr -> a repr >* delay_assertion repr) + + let s x = (S (X x), default_check) + + let scalar x = s x + + let to_scalar (S (X x), _) = x + + let bool b = (B b, default_check) + + let to_bool (B b, _) = b + + let unit = (U, default_check) + + let pair : 'a t -> 'b t -> ('a * 'b) t = + fun (a, check_a) (b, check_b) -> + (P (a, b), fun (Pair (ar, br)) -> check_a ar >* check_b br) + + let to_pair (P (a, b), _) = ((a, default_check), (b, default_check)) + + let list : 'a t list -> 'a list t = + fun l -> + ( L (List.map fst l), + fun (List lr) -> + let* _l = + mapM (fun ((_, asssertion), r) -> asssertion r) (List.combine l lr) + in + ret Unit ) + + let to_list (L l, _) = List.map (fun i -> (i, default_check)) l + + let rec make_repr : type a. a t' -> int -> a repr * int = + fun input start -> + match input with + | U -> (Unit, start) + | S _ -> (Scalar start, start + 1) + | B _ -> (Bool start, start + 1) + | P (l, r) -> + let l, m = make_repr l start in + let r, e = make_repr r m in + (Pair (l, r), e) + | L l -> + let l, e = + List.fold_left + (fun (l, i) x -> + let r, i' = make_repr x i in + (r :: l, i')) + ([], start) + l + in + (List (List.rev l), e) +end + +module Dummy = struct + let scalar = Input.(S (X S.zero)) + + let bool = Input.B false + + let list n a = Input.L (List.init n (fun _ -> a)) +end + +let rec encode : type a. a Input.t' -> S.t list = + fun input -> + match input with + | U -> [] + | S (X s) -> [s] + | B b -> if b then [S.one] else [S.zero] + | P (l, r) -> encode l @ encode r + | L l -> List.concat_map encode l + +let serialize i = Array.of_list @@ encode i + +let rec eq : type a. a repr -> a repr -> bool = + fun a b -> + match (a, b) with + | Scalar a, Scalar b | Bool a, Bool b -> a = b + | Pair (al, ar), Pair (bl, br) -> eq al bl && eq ar br + | List l1, List l2 -> List.for_all2 eq l1 l2 + | Unit, Unit -> true + +let pair l r = Pair (l, r) + +let of_pair (Pair (l, r)) = (l, r) + +let to_list l = List l + +let of_list (List l) = l + +let with_label ~label m s = + let s' = {s with labels = label :: s.labels} in + let s'', a = m s' in + ({s'' with labels = s.labels}, a) + +let add_solver : solver:Solver.solver_desc -> unit repr t = + fun ~solver s -> ({s with solver = Solver.append_solver solver s.solver}, Unit) + +let default_solver ?(to_solve = C) g = + let c = g.(0) in + let get_sel = CS.(get_sel c.sels) in + Arith + { + a = c.a; + b = c.b; + c = c.c; + d = c.d; + e = c.e; + qc = get_sel "qc"; + ql = get_sel "ql"; + qr = get_sel "qr"; + qo = get_sel "qo"; + qd = get_sel "qd"; + qe = get_sel "qe"; + qm = get_sel "qm"; + qx5a = get_sel "qx5a"; + qx2b = get_sel "qx2b"; + to_solve; + } + +let append : CS.gate -> ?solver:Solver.solver_desc -> unit repr t = + fun gate ?solver s -> + let solver = + match solver with + | Some s -> s + | None -> if Array.length gate = 1 then default_solver gate else Skip + in + let gate = + Array.map (fun c -> Csir.CS.{c with label = c.label @ s.labels}) gate + in + let cs = gate :: s.cs in + let solver = Solver.append_solver solver s.solver in + ({s with cs; solver}, Unit) + +let append_lookup : + a:int tagged -> + b:int tagged -> + c:int tagged -> + ?d:int tagged -> + ?e:int tagged -> + table:string -> + string -> + unit repr t = + fun ~a ~b ~c ?(d = Input 0) ?(e = Input 0) ~table label s -> + let rec find_index : 'a list -> int -> 'a -> int option = + fun l i y -> + match l with + | [] -> None + | x :: xs -> if x = y then Some i else find_index xs (i + 1) y + in + let use_table s id = + match find_index s.tables 0 id with + | Some i -> (s, i) + | None -> + let i = List.length s.tables in + let tables = s.tables @ [id] in + ({s with tables}, i) + in + let s, index = use_table s table in + let solver = Lookup {a; b; c; d; e; table} in + let a, b, c, d, e = Utils.map5 untag (a, b, c, d, e) in + let cstr = + CS.new_constraint + ~a + ~b + ~c + ~d + ~e + ~q_plookup:S.one + ~q_table:(S.of_z (Z.of_int index)) + ~labels:s.labels + label + in + let cs = [|cstr|] :: s.cs in + ({s with cs; solver = Solver.append_solver solver s.solver}, Unit) + +(* Records inputs, for external use *) +let input : type a. ?kind:input_kind -> a Input.t -> a repr t = + fun ?(kind = `Private) inp -> + let rec aux : type a. kind:input_kind -> a Input.t' -> a repr t = + fun ~kind inp s -> + if compare_trace_kind (kind :> trace_kind) s.input_flag < 0 then + raise + @@ Invalid_argument + (Format.sprintf + "Input order not respected : input_kind : %s, s.input_flag : %s; \ + inputs must be declared in this order : `InputCom, `Public, \ + `Private" + (show_input_kind kind) + (show_trace_kind s.input_flag)) ; + let serialized = serialize inp in + let n = Array.length serialized in + let inputs = Array.append s.inputs serialized in + let input_flag = (kind :> trace_kind) in + let input_com_sizes = + match kind with + | `InputCom -> ( + match s.input_com_sizes with + | hd :: tl -> (hd + n) :: tl + | _ -> + raise + @@ Failure + "initialize inputs commitments with new_input_commitment") + | _ -> s.input_com_sizes + in + let pi_size = s.pi_size + match kind with `Public -> n | _ -> 0 in + match inp with + | Input.U -> assert false + | Input.S _ -> + let r, nvars = Input.make_repr inp s.nvars in + ({s with nvars; inputs; input_com_sizes; pi_size; input_flag}, r) + | Input.B _ -> + let Bool o, nvars = Input.make_repr inp s.nvars in + let s = + { + s with + delayed = + s.delayed + >* append + [|CS.new_constraint ~a:o ~b:o ~c:0 ~ql:mone ~qm:one "bool"|] + ~solver:Skip; + nvars; + inputs; + input_com_sizes; + pi_size; + input_flag; + } + in + (s, Bool o) + | Input.P (l, r) -> + (let* l = aux ~kind l in + let* r = aux ~kind r in + ret @@ Pair (l, r)) + s + | Input.L ls -> + (let* l = mapM (aux ~kind) ls in + ret @@ List l) + s + in + let inp, implicit_check = inp in + let* i = with_label ~label:"Core.input" @@ aux ~kind inp in + implicit_check i >* ret i + +let new_input_com : unit repr t = + fun s -> ({s with input_com_sizes = 0 :: s.input_com_sizes}, Unit) + +type 'b open_input_com = 'b t + +let begin_input_com : 'b -> 'b open_input_com = fun b -> new_input_com >* ret b + +let ( |: ) : + type c d. (c repr -> d) open_input_com -> c Input.t -> d open_input_com = + fun v i s -> + let s, f = v s in + let s, r = (input ~kind:`InputCom i) s in + (s, f r) + +let end_input_com : 'a open_input_com -> 'a t = Fun.id + +(* Doesn't record inputs, for interal use *) +let fresh : type a. a Input.t' -> a repr t = + let rec aux : type a. a Input.t' -> a repr t = + fun input s -> + let s = {s with input_flag = `NoInput} in + match input with + | Input.U | Input.S _ -> + let r, nvars = Input.make_repr input s.nvars in + ({s with nvars}, r) + | Input.B _ -> + let Bool o, nvars = Input.make_repr input s.nvars in + let s, _ = + append + [|CS.new_constraint ~a:o ~b:o ~c:0 ~ql:mone ~qm:one "bool"|] + ~solver:Skip + {s with nvars} + in + (s, Bool o) + | Input.P (l, r) -> + (let* l = aux l in + let* r = aux r in + ret @@ Pair (l, r)) + s + | Input.L ls -> + (let* l = mapM aux ls in + ret @@ List l) + s + in + fun input -> with_label ~label:"Core.fresh" @@ aux input + +let serialize (i, _) = serialize i + +let deserialize : type a. S.t array -> a Input.t -> a Input.t = + let rec aux : type a. S.t array -> a Input.t' -> int -> a Input.t' * int = + fun a w i -> + let open Input in + match w with + | U -> (U, i) + | S _ -> + let s = a.(i) in + (S (X s), i + 1) + | B _ -> + let s = a.(i) in + (B (S.is_one s), i + 1) + | P (wl, wr) -> + let l, i = aux a wl i in + let r, i = aux a wr i in + (P (l, r), i) + | L ws -> + let l, i = + List.fold_left + (fun (acc, i) w -> + let x, i = aux a w i in + (x :: acc, i)) + ([], i) + ws + in + (L (List.rev l), i) + in + fun a (w, check) -> (fst @@ aux a w 0, check) + +let constant_scalar s = + let*& o = fresh Dummy.scalar in + append [|CS.new_constraint ~a:0 ~b:0 ~c:o ~qc:s ~qo:mone "constant_scalar"|] + >* ret (Scalar o) + +let scalar_of_bool (Bool b) = Scalar b + +let unsafe_bool_of_scalar (Scalar b) = Bool b + +let unit = Unit + +module Num = struct + type nonrec scalar = scalar + + type nonrec 'a repr = 'a repr + + type nonrec 'a t = 'a t + + (* l ≠ 0 <=> ∃ r ≠ 0 : l * r - 1 = 0 *) + let assert_nonzero (Scalar l) = + let*& r = fresh Dummy.scalar in + (* 0*l + 0*r + 0*0 + 1*l*r -1 = 0 *) + let gate = + [|CS.new_constraint ~a:l ~b:r ~c:0 ~qc:mone ~qm:one "assert_nonzero"|] + in + let solver = default_solver gate ~to_solve:B in + append gate ~solver + + let is_zero (Scalar l) = + with_label ~label:"Num.is_zero" + @@ let* (Bool bit) = fresh Dummy.bool in + let* (Scalar r) = fresh Dummy.scalar in + let gate = + [| + CS.new_constraint ~a:l ~b:r ~c:bit ~qc:mone ~qo:one ~qm:one "is_zero"; + |] + in + let solver = IsZero {a = l; b = r; c = bit; d = 0; e = 0} in + append gate ~solver >* assert_nonzero (Scalar r) >* ret @@ Bool bit + + let is_not_zero (Scalar l) = + with_label ~label:"Num.is_not_zero" + @@ let* (Bool bit) = fresh Dummy.bool in + let* (Scalar r) = fresh Dummy.scalar in + let gate = + [|CS.new_constraint ~a:l ~b:r ~c:bit ~qo:mone ~qm:one "is_not_zero"|] + in + let solver = IsNotZero {a = l; b = r; c = bit; d = 0; e = 0} in + append gate ~solver >* assert_nonzero (Scalar r) >* ret @@ Bool bit + + let assert_bool (Scalar l) = + with_label ~label:"Num.assert_bool" + @@ + let gate = [|CS.new_constraint ~a:l ~b:0 ~c:0 ~qbool:one "assert_bool"|] in + let solver = Skip in + append gate ~solver + + let custom ?(qc = S.zero) ?(ql = S.zero) ?(qr = S.zero) ?(qo = S.mone) + ?(qm = S.zero) ?qx2b ?qx5a (Scalar l) (Scalar r) = + let*& o = fresh Dummy.scalar in + append + [| + CS.new_constraint + ~a:l + ~b:r + ~c:o + ~qc + ~ql + ~qr + ~qo + ~qm + ?qx2b + ?qx5a + "custom"; + |] + >* ret @@ Scalar o + + let assert_custom ?(qc = S.zero) ?(ql = S.zero) ?(qr = S.zero) ?(qo = S.zero) + ?(qm = S.zero) (Scalar l) (Scalar r) (Scalar o) = + append + [|CS.new_constraint ~a:l ~b:r ~c:o ~qc ~ql ~qr ~qo ~qm "assert_custom"|] + ~solver:Skip + + let add ?(qc = S.zero) ?(ql = S.one) ?(qr = S.one) (Scalar l) (Scalar r) = + let*& o = fresh Dummy.scalar in + append [|CS.new_constraint ~a:l ~b:r ~c:o ~qc ~ql ~qr ~qo:mone "add"|] + >* ret @@ Scalar o + + let add_constant ?(ql = S.one) (k : S.t) (Scalar l) = + let*& o = fresh Dummy.scalar in + append + [|CS.new_constraint ~a:l ~b:0 ~c:o ~qc:k ~ql ~qo:mone "add_constant"|] + >* ret @@ Scalar o + + let sub (Scalar l) (Scalar r) = + let*& o = fresh Dummy.scalar in + append [|CS.new_constraint ~a:l ~b:r ~c:o ~ql:one ~qr:mone ~qo:mone "sub"|] + >* ret @@ Scalar o + + let mul ?(qm = one) (Scalar l) (Scalar r) = + let*& o = fresh Dummy.scalar in + append [|CS.new_constraint ~a:l ~b:r ~c:o ~qm ~qo:mone "mul"|] + >* ret @@ Scalar o + + let div ?(den_coeff = one) (Scalar l) (Scalar r) = + with_label ~label:"Num.div" @@ assert_nonzero (Scalar r) + >* let*& o = fresh Dummy.scalar in + let gate = + [|CS.new_constraint ~a:r ~b:o ~c:l ~qm:den_coeff ~qo:mone "div"|] + in + let solver = default_solver gate ~to_solve:B in + (* r * o - l = 0 <=> o = l / r *) + append gate ~solver >* ret @@ Scalar o + + let pow5 (Scalar l) = + let*& o = fresh Dummy.scalar in + let gate = [|CS.new_constraint ~a:l ~b:0 ~c:o ~qx5a:one ~qo:mone "pow5"|] in + let solver = Pow5 {a = l; c = o} in + append gate ~solver >* ret @@ Scalar o +end + +module Bool = struct + include Num + + let constant_bool : bool -> bool repr t = + fun b -> + let s = if b then S.one else S.zero in + let* (Scalar s) = constant_scalar s in + ret (Bool s) + + let assert_true (Bool bit) = + append + [|CS.new_constraint ~a:bit ~b:0 ~c:0 ~qc:mone ~ql:one "assert_true"|] + ~solver:Skip + + let assert_false (Bool bit) = + append + [|CS.new_constraint ~a:bit ~b:0 ~c:0 ~ql:one "assert_false"|] + ~solver:Skip + + let band : bool repr -> bool repr -> bool repr t = + fun (Bool l) (Bool r) -> + (* NB: Here [o] is declared as a fresh scalar to avoid adding the constraint + asserting it's a bool. It's safe to do so because: + - We can assume that [l] and [r] are booleans + - This operation is closed in {0, 1} + This has additionally been proven using Z3 (see z3 directory). + *) + let*& o = fresh Dummy.scalar in + (* o - l*r = 0 *) + append [|CS.new_constraint ~a:l ~b:r ~c:o ~qm:mone ~qo:one "band"|] + >* ret @@ Bool o + + let bnot (Bool b) = + (* NB: Here [o] is declared as a fresh scalar to avoid adding the constraint + asserting it's a bool. It's safe to do so because: + - We can assume that [b] is a boolen. + - This operation is closed in {0, 1} + This has additionally been proven using Z3 (see z3 directory). + *) + let*& o = fresh Dummy.scalar in + (* o - (1 - i) = 0 *) + append [|CS.new_constraint ~a:b ~b:0 ~c:o ~qc:mone ~ql:one ~qo:one "bnot"|] + >* ret @@ Bool o + + let xor (Bool l) (Bool r) = + (* NB: Here [o] is declared as a fresh scalar to avoid adding the constraint + asserting it's a bool. It's safe to do so because: + - We can assume that [l] and [r] are booleans + - This operation is closed in {0, 1} + This has additionally been proven using Z3 (see z3 directory). + *) + let*& o = fresh Dummy.scalar in + let mtwo = S.of_string "-2" in + append + [| + CS.new_constraint ~a:l ~b:r ~c:o ~ql:one ~qr:one ~qo:mone ~qm:mtwo "xor"; + |] + >* ret @@ Bool o + + let bor (Bool l) (Bool r) = + (* NB: Here [o] is declared as a fresh scalar to avoid adding the constraint + asserting it's a bool. It's safe to do so because: + - We can assume that [l] and [r] are booleans + - This operation is closed in {0, 1} + This has additionally been proven using Z3 (see z3 directory). + *) + let*& o = fresh Dummy.scalar in + append + [| + CS.new_constraint ~a:l ~b:r ~c:o ~ql:one ~qr:one ~qo:mone ~qm:mone "nor"; + |] + >* ret @@ Bool o + + let bor_lookup (Bool l) (Bool r) = + let* (Bool o) = fresh Dummy.bool in + append_lookup + ~a:(Input l) + ~b:(Input r) + ~c:(Output o) + ~table:"or" + "bor lookup" + >* ret @@ Bool o + + let swap : type a. bool repr -> a repr -> a repr -> (a * a) repr t = + let scalar_swap (Bool b) (Scalar x) (Scalar y) = + let*& u = fresh Dummy.scalar in + let*& v = fresh Dummy.scalar in + let solver = Swap {b; x; y; u; v} in + let gate = + [|CS.new_constraint ~a:b ~b:x ~c:y ~d:u ~e:v ~qcond_swap:one "swap"|] + in + append gate ~solver >* ret @@ pair (Scalar u) (Scalar v) + in + let rec aux : type a. bool repr -> a repr -> a repr -> (a * a) repr t = + fun b x y -> + match (x, y) with + | Unit, Unit -> ret (pair Unit Unit) + | Scalar _, Scalar _ -> scalar_swap b x y + | Bool _, Bool _ -> + let* res = scalar_swap b (scalar_of_bool x) (scalar_of_bool y) in + let Scalar u, Scalar v = of_pair res in + ret @@ pair (Bool u) (Bool v) + | Pair (x1, y1), Pair (x2, y2) -> + let* res_x = aux b x1 x2 in + let* res_y = aux b y1 y2 in + let (u1, v1), (u2, v2) = (of_pair res_x, of_pair res_y) in + ret @@ pair (pair u1 u2) (pair v1 v2) + | List ls, List rs -> + let* l = map2M (fun l r -> aux b l r) ls rs in + let l1, l2 = List.(map of_pair l |> split) in + ret @@ pair (List l1) (List l2) + in + fun b x y -> with_label ~label:"Bool.swap" @@ aux b x y + + let ifthenelse : type a. bool repr -> a repr -> a repr -> a repr t = + let aux b l r = + let* swapped = swap b l r in + let _, res = of_pair swapped in + ret res + in + fun b l r -> with_label ~label:"Bool.ifthenelse" @@ aux b l r + + let is_eq_const l s = + with_label ~label:"Bool.is_eq_const" + @@ let* diff = Num.add_constant ~ql:S.mone s l in + is_zero diff + + let band_list l = + with_label ~label:"Bool.band_list" + @@ + match l with + | [] -> constant_bool true + | hd :: tl -> + let* sum = + foldM Num.add (scalar_of_bool hd) (List.map scalar_of_bool tl) + in + is_eq_const sum (S.of_int @@ (List.length tl + 1)) +end + +let hd (List l) = match l with [] -> assert false | x :: _ -> ret x + +let assert_equal : type a. a repr -> a repr -> unit repr t = + let rec aux : type a. a repr -> a repr -> unit repr t = + fun a b -> + match (a, b) with + | Unit, Unit -> ret Unit + | Bool a, Bool b | Scalar a, Scalar b -> + append + [|CS.new_constraint ~a:0 ~b ~c:a ~qr:one ~qo:mone "assert_equal"|] + ~solver:Skip + | Pair (la, ra), Pair (lb, rb) -> aux la lb >* aux ra rb + | List ls, List rs -> iter2M aux ls rs + in + fun a b -> with_label ~label:"Core.assert_equal" @@ aux a b + +let equal : type a. a repr -> a repr -> bool repr t = + let rec aux : type a. a repr -> a repr -> bool repr t = + fun a b -> + let open Bool in + let open Num in + match (a, b) with + | Unit, Unit -> constant_bool true + | Bool a, Bool b -> + let* s = sub (Scalar a) (Scalar b) in + is_zero s + | Scalar _, Scalar _ -> + let* s = sub a b in + is_zero s + | Pair (la, ra), Pair (lb, rb) -> + let* le = aux la lb in + let* re = aux ra rb in + band le re + | List ls, List rs -> + let lrs = List.map2 pair ls rs in + let* acc = constant_bool true in + foldM + (fun acc (Pair (l, r)) -> + let* e = aux l r in + band acc e) + acc + lrs + in + fun a b -> with_label ~label:"Core.equal" @@ aux a b + +(* If [add_alpha], this function returns the binary decomposition of + [l + Utils.alpha], instead of the binary decompostion of [l], where + Utils.alpha is the difference between Scalar.order and its succeeding + power of 2 *) +let bits_of_scalar ?(shift = Z.zero) ~nb_bits (Scalar l) = + with_label ~label:"Core.bits_of_scalar" + @@ let* bits = fresh @@ Dummy.list nb_bits Dummy.bool in + add_solver + ~solver: + (BitsOfS + { + nb_bits; + shift; + l; + bits = List.map (fun (Bool x) -> x) @@ of_list bits; + }) + >* let* sum = + let powers = + List.init nb_bits (fun i -> S.of_z Z.(pow (of_int 2) i)) + in + let sbits = List.map scalar_of_bool (of_list bits) in + foldM + (fun acc (qr, w) -> Num.add ~qr acc w) + (List.hd sbits) + List.(tl @@ combine powers sbits) + in + let* l = + if Z.(not @@ equal shift zero) then + Num.add_constant (S.of_z shift) (Scalar l) + else ret (Scalar l) + in + assert_equal l sum >* ret bits + +module Ecc = struct + let weierstrass_add (Pair (Scalar x1, Scalar y1)) + (Pair (Scalar x2, Scalar y2)) = + with_label ~label:"Ecc.weierstrass_add" + @@ let*& x3 = fresh Dummy.scalar in + let*& y3 = fresh Dummy.scalar in + let gate = + [| + CS.new_constraint + ~a:x1 + ~b:x2 + ~c:x3 + ~qecc_ws_add:one + "weierstrass-add.1"; + CS.new_constraint ~a:y1 ~b:y2 ~c:y3 "weierstrass-add.2"; + |] + in + let solver = Ecc_Ws {x1; x2; x3; y1; y2; y3} in + append gate ~solver >* ret (Pair (Scalar x3, Scalar y3)) + + let edwards_add (Pair (Scalar x1, Scalar y1)) (Pair (Scalar x2, Scalar y2)) = + (* Improve Me: Functorize to pass curve in parameter. *) + with_label ~label:"Ecc.edwards_add" + @@ + let module W = Mec.Curve.Jubjub.AffineEdwards in + let s_of_base s = S.of_z (W.Base.to_z s) in + let a, d = (s_of_base W.a, s_of_base W.d) in + let*& x3 = fresh Dummy.scalar in + let*& y3 = fresh Dummy.scalar in + let gate = + [| + CS.new_constraint ~a:x1 ~b:x2 ~c:x3 ~qecc_ed_add:one "edwards-add.1"; + CS.new_constraint ~a:y1 ~b:y2 ~c:y3 "edwards-add.2"; + |] + in + let solver = Ecc_Ed {x1; x2; x3; y1; y2; y3; a; d} in + append gate ~solver >* ret (Pair (Scalar x3, Scalar y3)) + + let edwards_cond_add (Pair (Scalar x1, Scalar y1)) + (Pair (Scalar x2, Scalar y2)) (Bool bit) = + (* Improve Me: Functorize to pass curve in parameter. *) + with_label ~label:"Ecc.edwards_cond_add" + @@ + let module W = Mec.Curve.Jubjub.AffineEdwards in + let s_of_base s = S.of_z (W.Base.to_z s) in + let a, d = (s_of_base W.a, s_of_base W.d) in + let*& x3 = fresh Dummy.scalar in + let*& y3 = fresh Dummy.scalar in + let gate = + [| + CS.new_constraint + ~a:bit + ~b:x2 + ~c:y2 + ~d:x1 + ~e:y1 + ~qecc_ed_cond_add:one + "edwards-cond-add.1"; + CS.new_constraint ~a:0 ~b:0 ~c:0 ~d:x3 ~e:y3 "edwards-cond-add.2"; + |] + in + let solver = Ecc_Cond_Ed {x1; x2; x3; y1; y2; y3; bit; a; d} in + append gate ~solver >* ret (Pair (Scalar x3, Scalar y3)) +end + +module Poseidon = struct + module VS = Linear_algebra.Make_VectorSpace (S) + module Poly = Polynomial.MakeUnivariate (S) + + module Poly_Module = Linear_algebra.Make_Module (struct + include Poly + + let eq = Poly.equal + + let negate p = Poly.(zero - p) + + let mul = Poly.( * ) + end) + + let poseidon128_full_round ~matrix ~k ~variant + (Scalar x0, Scalar x1, Scalar x2) = + let*& y0 = fresh Dummy.scalar in + let*& y1 = fresh Dummy.scalar in + let*& y2 = fresh Dummy.scalar in + let solver = Poseidon128Full {x0; y0; x1; y1; x2; y2; k; variant} in + let minv = VS.inverse matrix in + let k_vec = VS.(mul minv (transpose [|k|])) in + + (* We enforce the following constraints: + + [x0 y0] with selectors {qc, qx5, qo, qrg, qog} + [x1 y1 y2] with selectors {qc, qx5, qr, qo, qrg} + [x2 y0 y1] with selectors {qc, qx5, qr, qo, qrg} + [ y2 ] with no selectors + + where the selector constants are given by the inverse of the MDS + matrix. In particular: + + y = M * x^5 + k iff M^{-1} * y - x^5 - M^{-1} * k = 0 + + (This allows us to have 1 power of 5 (instead of all 3) per constraint, + since vector x^5 is not multiplied by M in the second representation.) *) + append + [| + CS.new_constraint + ~a:x0 + ~b:0 + ~c:y0 + ~qx5a:mone + ~qc:(S.negate k_vec.(0).(0)) + ~qo:minv.(0).(0) + ~qrg:minv.(0).(1) + ~qog:minv.(0).(2) + "pos128_full.1"; + CS.new_constraint + ~a:x1 + ~b:y1 + ~c:y2 + ~qx5a:mone + ~qc:(S.negate k_vec.(1).(0)) + ~qr:minv.(1).(1) + ~qo:minv.(1).(2) + ~qrg:minv.(1).(0) + "pos128_full.2"; + CS.new_constraint + ~a:x2 + ~b:y0 + ~c:y1 + ~qx5a:mone + ~qc:(S.negate k_vec.(2).(0)) + ~qr:minv.(2).(0) + ~qo:minv.(2).(1) + ~qrg:minv.(2).(2) + "pos128_full.3"; + CS.new_constraint ~a:0 ~b:y2 ~c:0 "pos128_full.4"; + |] + ~solver + >* ret @@ to_list [Scalar y0; Scalar y1; Scalar y2] + + let poseidon128_four_partial_rounds ~matrix ~ks ~variant + (Scalar x0, Scalar x1, Scalar x2) = + let*& a = fresh Dummy.scalar in + let*& a_5 = fresh Dummy.scalar in + let*& b = fresh Dummy.scalar in + let*& b_5 = fresh Dummy.scalar in + let*& c = fresh Dummy.scalar in + let*& c_5 = fresh Dummy.scalar in + let*& y0 = fresh Dummy.scalar in + let*& y1 = fresh Dummy.scalar in + let*& y2 = fresh Dummy.scalar in + let k_cols = Array.init 4 (fun i -> VS.filter_cols (Int.equal i) ks) in + let solver = + Poseidon128Partial + {a; b; c; a_5; b_5; c_5; x0; y0; x1; y1; x2; y2; k_cols; variant} + in + + (* We represent variables x0, x1, x2_5, a, a_5, b, b_5, c, c_5, y0, y1, y2 + with monomials x, x^2, x^3, ..., x^12 respectively. *) + let module SMap = Map.Make (String) in + let vars = + ["x0"; "x1"; "x2_5"; "a"; "a_5"; "b"; "b_5"; "c"; "c_5"; "y0"; "y1"; "y2"] + in + let varsMap = + SMap.of_seq @@ List.(to_seq @@ mapi (fun i s -> (s, i + 1)) vars) + in + + let var s = SMap.find s varsMap in + let pvar s = Poly.of_coefficients [(S.one, var s)] in + let state = [|[|pvar "x0"|]; [|pvar "x1"|]; [|pvar "x2_5"|]|] in + + let to_poly = Array.(map (map (fun c -> Poly.of_coefficients [(c, 0)]))) in + let matrix = to_poly matrix in + + (* Apply partial round 0 *) + let state = Poly_Module.(add (mul matrix state) @@ to_poly k_cols.(0)) in + let eq1 = Poly.(state.(2).(0) - pvar "a") in + state.(2) <- [|pvar "a_5"|] ; + + (* Apply partial round 1 *) + let state = Poly_Module.(add (mul matrix state) @@ to_poly k_cols.(1)) in + let eq2 = Poly.(state.(2).(0) - pvar "b") in + state.(2) <- [|pvar "b_5"|] ; + + (* Apply partial round 2 *) + let state = Poly_Module.(add (mul matrix state) @@ to_poly k_cols.(2)) in + let eq3 = Poly.(state.(2).(0) - pvar "c") in + state.(2) <- [|pvar "c_5"|] ; + + (* Apply partial round 3 *) + let state = Poly_Module.(add (mul matrix state) @@ to_poly k_cols.(3)) in + let eq4 = Poly.(state.(0).(0) - pvar "y0") in + let eq5 = Poly.(state.(1).(0) - pvar "y1") in + let eq6 = Poly.(state.(2).(0) - pvar "y2") in + + let eqs = + let row_of_eq eq = + (* This function gives coefficients in decending order of degree *) + let coeffs = Poly.get_dense_polynomial_coefficients eq in + List.(rev coeffs @ init (13 - List.length coeffs) (fun _ -> S.zero)) + |> Array.of_list + in + Array.map row_of_eq [|eq1; eq2; eq3; eq4; eq5; eq6|] + in + + let cancel i j x = + let x = var x in + VS.row_add ~coeff:S.(negate @@ (eqs.(i).(x) / eqs.(j).(x))) i j eqs + in + + (* Cancel x2_5 *) + cancel 1 0 "x2_5" ; + cancel 2 0 "x2_5" ; + cancel 3 0 "x2_5" ; + cancel 4 0 "x2_5" ; + cancel 5 0 "x2_5" ; + + (* Cancel a_5 *) + cancel 2 1 "a_5" ; + cancel 3 1 "a_5" ; + cancel 4 1 "a_5" ; + cancel 5 1 "a_5" ; + + (* Cancel b_5 *) + cancel 3 2 "b_5" ; + cancel 4 2 "b_5" ; + cancel 5 2 "b_5" ; + + (* Cancel c_5 *) + cancel 4 3 "c_5" ; + + (* Cancel x0 in equation 5 (b_5 comes back) *) + cancel 4 2 "x0" ; + + VS.row_swap 2 4 eqs ; + + (* We enforce the following constraints: + + [x2 ] with selectors {qc, qx5, qlg, qrg, qog} + [a x0 x1] with selectors {qc, qx5, ql, qr, qo, qlg} + [b y1 x1] with selectors {qc, qx5, ql, qr, qo, qlg, qrg, qog} + [c y0 a] with selectors {qc, qx5, ql, qr, qo, qlg, qrg, qog} + [b x0 x1] with selectors {qc, qx5, ql, qr, qo, qlg, qrg} + [c a b] with selectors {qc, qx5, ql, qr, qo, qlg, qrg, qog} + [y2 x0 x1] with no selectors. *) + append + [| + CS.new_constraint + ~a:x2 + ~b:0 + ~c:0 + ~qc:eqs.(0).(0) + ~qx5a:eqs.(0).(var "x2_5") + ~qlg:eqs.(0).(var "a") + ~qrg:eqs.(0).(var "x0") + ~qog:eqs.(0).(var "x1") + "pos128_4partial.1"; + CS.new_constraint + ~a + ~b:x0 + ~c:x1 + ~qc:eqs.(1).(0) + ~qx5a:eqs.(1).(var "a_5") + ~ql:eqs.(1).(var "a") + ~qr:eqs.(1).(var "x0") + ~qo:eqs.(1).(var "x1") + ~qlg:eqs.(1).(var "b") + "pos128_4partial.2"; + CS.new_constraint + ~a:b + ~b:y1 + ~c:x1 + ~qc:eqs.(2).(0) + ~qx5a:eqs.(2).(var "b_5") + ~ql:eqs.(2).(var "b") + ~qr:eqs.(2).(var "y1") + ~qo:eqs.(2).(var "x1") + ~qlg:eqs.(2).(var "c") + ~qrg:eqs.(2).(var "y0") + ~qog:eqs.(2).(var "a") + "pos128_4partial.3"; + CS.new_constraint + ~a:c + ~b:y0 + ~c:a + ~qc:eqs.(3).(0) + ~qx5a:eqs.(3).(var "c_5") + ~ql:eqs.(3).(var "c") + ~qr:eqs.(3).(var "y0") + ~qo:eqs.(3).(var "a") + ~qlg:eqs.(3).(var "b") + ~qrg:eqs.(3).(var "x0") + ~qog:eqs.(3).(var "x1") + "pos128_4partial.4"; + CS.new_constraint + ~a:b + ~b:x0 + ~c:x1 + ~qc:eqs.(4).(0) + ~qx5a:eqs.(4).(var "b_5") + ~ql:eqs.(4).(var "b") + ~qr:eqs.(4).(var "x0") + ~qo:eqs.(4).(var "x1") + ~qlg:eqs.(4).(var "c") + ~qrg:eqs.(4).(var "a") + "pos128_4partial.5"; + CS.new_constraint + ~a:c + ~b:a + ~c:b + ~qc:eqs.(5).(0) + ~qx5a:eqs.(5).(var "c_5") + ~ql:eqs.(5).(var "c") + ~qr:eqs.(5).(var "a") + ~qo:eqs.(5).(var "b") + ~qlg:eqs.(5).(var "y2") + ~qrg:eqs.(5).(var "x0") + ~qog:eqs.(5).(var "x1") + "pos128_4partial.6"; + CS.new_constraint ~a:y2 ~b:x0 ~c:x1 "pos128_4partial.7"; + |] + ~solver + >* ret @@ to_list [Scalar y0; Scalar y1; Scalar y2] +end + +module Anemoi = struct + module AnemoiPerm = Bls12_381_hash.Permutation.Anemoi + + let beta = AnemoiPerm.Parameters.beta + + let gamma = AnemoiPerm.Parameters.gamma + + let g = AnemoiPerm.Parameters.g + + let delta = AnemoiPerm.Parameters.delta + + (* Hash function described in https://eprint.iacr.org/2022/840.pdf *) + + let anemoi_round ~kx ~ky (Scalar x0, Scalar y0) = + let*& w = fresh Dummy.scalar in + let*& v = fresh Dummy.scalar in + let*& x1 = fresh Dummy.scalar in + let*& y1 = fresh Dummy.scalar in + let solver = AnemoiRound {x0; y0; w; v; x1; y1; kx; ky} in + + (* + The equations of a Anemoi round are as follows, + a. x1 - u - g*v - (kx + g*ky) = 0 + Corresponds to Linear layer equation (after adding the round constant to x_i ), eq.4 page 24 + b. y1 - g u - (g^2+1)*v - (g*kx + (g^2+1)*ky) = 0 + Corresponds to Linear layer equation (after adding the round constant to y_i ), eq.5 page 24 + c. w^5 + beta y0^2 + gamma - x0 = 0 + Corresponds to the first equation of S-box, eq.2 page 24 + d. y0 - v - w = 0 + Corresponds to the second equation of S-box layer, eq.1 page 24 + e. w^5 + beta v^2 + delta - u = 0 + Corresponds to the third equation of S-box, eq.3 page 24 + + We inlined $u$ from a. in e. and re-ordered the equations so that the variables fit in the wires. + The result is as follows, + 1. w^5 + beta y0^2 + gamma - x0 = 0 <- c + 2. y0 - v - w = 0 <- d + 3. w^5 + beta v^2 + g*v - x1 + (delta + kx + g*ky) = 0 <- e - a + 4. y1 - g x1 - v - ky = 0 <- b - g * a + *) + append + [| + CS.new_constraint + ~a:y0 + ~b:y0 + ~c:w + ~qc:gamma + ~qm:beta + ~qx5c:one + ~qlg:mone + "anemoi.1"; + CS.new_constraint ~a:x0 ~b:y0 ~c:w ~qr:one ~qlg:mone ~qo:mone "anemoi.2"; + CS.new_constraint + ~a:v + ~b:v + ~c:w + ~qc:S.(kx + delta + (g * ky)) + ~qm:beta + ~qx5c:one + ~ql:g + ~qlg:mone + "anemoi.3"; + CS.new_constraint + ~a:x1 + ~b:y1 + ~c:v + ~qc:S.(negate ky) + ~ql:S.(negate g) + ~qr:one + ~qo:mone + "anemoi.4"; + |] + ~solver + >* ret @@ pair (Scalar x1) (Scalar y1) + + let anemoi_double_round ~kx1 ~ky1 ~kx2 ~ky2 (Scalar x0, Scalar y0) = + let*& w0 = fresh Dummy.scalar in + let*& w1 = fresh Dummy.scalar in + let*& y1 = fresh Dummy.scalar in + let*& x2 = fresh Dummy.scalar in + let*& y2 = fresh Dummy.scalar in + let solver = + AnemoiDoubleRound {x0; y0; w0; w1; y1; x2; y2; kx1; kx2; ky1; ky2} + in + + let two = S.(add one one) in + let g2 = S.(g * g) in + let g2_p_1 = S.(g2 + one) in + let g_beta = S.(g * beta) in + + (* + Equations | Wires | Selectors + ------------------------------------------------------------------------------------------------------------- + a <- 2. -(beta*g)*w0^2 + (2*beta*g)*w0*y0 + (g^2+1)*w0 - g*x0 - (g^2+1)*y0 + y1 + (g*gamma - delta*g - g*kx1 - (g^2+1)*ky1) + | a: y0, b: w0, c: x0 + | qr2=-(beta*g) qm:(2*beta*g) qr:(g^2+1) qo:-g ql:-(g^2+1) qlg:1 qc =(g*gamma - delta*g - g*kx1 - (g^2+1)*ky1) + + b <- 4. -(g * beta)*w1^2 + (2 * g * beta)*w1*y1 - w0 + g^2*w1 + g*x2 + y0 - (g^2+1)*y1 + (g*gamma + ky1 - delta*g - g*kx2 - g^2*ky2) + | a: y1, b: w1, c: w0 + | qr2=-(g*beta) qm:(2*g*beta) qo:-1 qr:g^2 qrg:g qlg:1 ql:-(g^2+1) qc:(g*gamma + ky1 - delta*g -g*kx2 - g^2*ky2) + + c <- 5. w1 - g*x2 - y1 + y2 - ky2 + | a: y0, b: x2, c: y2 + | qlg:1 qr:-g qrg:-1 qo:1 qc:-ky2 + + d <- 3. g*w1^5 + (g * beta)*y1^2 - w0 + y0 - y1 + (ky1 + g*gamma) + | a: w1, b: y1, c: __ + | ql5=g qr2=(g*beta) qlg:-1 qrg:1 qr:-1 qc:(ky1 + g*gamma) + + e <- 1. w0^5 + beta*y0^2 - x0 + gamma + | a: w0, b: y0, c: x0 + | ql5=1 qr2=beta qo:-1 qc:gamma + *) + let qca = S.(sub (gamma * g) ((g * (kx1 + delta)) + (g2_p_1 * ky1))) in + let qcb = S.(sub ((gamma * g) + ky1) ((g * (kx2 + delta)) + (g2 * ky2))) in + let qcd = S.(ky1 + (g * gamma)) in + append + [| + CS.new_constraint + ~a:y0 + ~b:w0 + ~c:x0 + ~qx2b:S.(negate g_beta) + ~qm:S.(two * g_beta) + ~qr:g2_p_1 + ~qo:S.(negate g) + ~ql:S.(negate g2_p_1) + ~qlg:S.one + ~qc:qca + "anemoi_double.a"; + CS.new_constraint + ~a:y1 + ~b:w1 + ~c:w0 + ~qx2b:S.(negate g_beta) + ~qm:S.(two * g_beta) + ~qo:mone + ~qr:g2 + ~qrg:g + ~qlg:one + ~ql:S.(negate g2_p_1) + ~qc:qcb + "anemoi_double.b"; + CS.new_constraint + ~a:y0 + ~b:x2 + ~c:y2 + ~qlg:one + ~qr:S.(negate g) + ~qrg:mone + ~qo:one + ~qc:S.(negate ky2) + "anemoi_double.c"; + CS.new_constraint + ~a:w1 + ~b:y1 + ~c:y1 + ~qx5a:g + ~qx2b:g_beta + ~qlg:mone + ~qrg:one + ~qr:mone + ~qc:qcd + "anemoi_double.d"; + CS.new_constraint + ~a:w0 + ~b:y0 + ~c:x0 + ~qx5a:one + ~qx2b:beta + ~qo:mone + ~qc:gamma + "anemoi_double.e"; + |] + ~solver + >* ret @@ pair (Scalar x2) (Scalar y2) + + let anemoi_custom ~kx1 ~ky1 ~kx2 ~ky2 (Scalar x0, Scalar y0) = + with_label ~label:"custom_anemoi" + @@ let*& x1 = fresh Dummy.scalar in + let*& y1 = fresh Dummy.scalar in + let*& x2 = fresh Dummy.scalar in + let*& y2 = fresh Dummy.scalar in + let precomputed_advice = + [("qadv0", kx1); ("qadv1", ky1); ("qadv2", kx2); ("qadv3", ky2)] + in + let gate = + [| + CS.new_constraint + ~a:0 + ~b:x1 + ~c:y1 + ~d:x0 + ~e:y0 + ~q_anemoi:one + ~precomputed_advice + "custom_anemoi.1"; + CS.new_constraint ~a:0 ~b:0 ~c:0 ~d:x2 ~e:y2 "custom_anemoi.2"; + |] + in + let solver = AnemoiCustom {x0; y0; x1; y1; x2; y2; kx1; kx2; ky1; ky2} in + append gate ~solver >* ret @@ pair (Scalar x2) (Scalar y2) +end + +let get_checks_wire s = + let s, Unit = s.delayed s in + let s, w = Bool.band_list s.check_wires s in + ({s with check_wires = []; delayed = ret Unit}, w) + +let get f = + let s, res = + f + { + nvars = 0; + cs = []; + inputs = Array.init 0 (fun _ -> S.zero); + input_com_sizes = []; + pi_size = 0; + input_flag = `InputCom; + tables = []; + solver = Solver.empty_solver; + delayed = ret Unit; + check_wires = []; + labels = []; + } + in + let s, Unit = s.delayed s in + let s, res = + match s.check_wires with + | [] -> (s, res) + | ws -> + let s, w = Bool.band_list ws s in + let s, Unit = Bool.assert_true w s in + (s, res) + in + let solver = + {s.solver with final_size = s.nvars; initial_size = Array.length s.inputs} + in + let s = {s with solver} in + (s, res) + +let get_inputs f = + let s, _ = get f in + (s.inputs, s.pi_size) + +type cs_result = { + nvars : int; + free_wires : int list; + cs : Csir.CS.t; + input_com_sizes : int list; + tables : Csir.Table.t list; + solver : Solver.t; +} +[@@deriving repr] + +let cs_ti_t = Repr.pair Csir.CS.t Optimizer.trace_info_t + +let get_cs ?(optimize = false) f : cs_result = + let s, _ = get f in + let ts = List.map (fun t_id -> Tables.find t_id tables) s.tables in + let cs, solver, free_wires, nvars = + if optimize then + let circuit_id = Utils.get_circuit_id s.cs in + let path = Utils.circuit_path circuit_id in + let cs, ti = + if Sys.file_exists path then ( + (* If defined, load it up *) + let inc = open_in path in + let size = in_channel_length inc in + let buffer = Bytes.create size in + really_input inc buffer 0 (in_channel_length inc) ; + close_in inc ; + Utils.of_bytes cs_ti_t buffer) + else + let nb_inputs = Array.length s.inputs in + let o = Optimizer.optimize ~nb_inputs s.cs in + let serialized = Utils.to_bytes cs_ti_t o in + let outc = open_out_bin path in + output_bytes outc serialized ; + close_out outc ; + o + in + (cs, Solver.append_solver (Updater ti) s.solver, ti.free_wires, s.nvars) + else (s.cs, s.solver, [], s.nvars) + in + { + nvars; + free_wires; + cs; + tables = ts; + input_com_sizes = List.rev s.input_com_sizes; + solver; + } diff --git a/src/lib_plompiler/csir.ml b/src/lib_plompiler/csir.ml new file mode 100644 index 000000000000..a4d408481e63 --- /dev/null +++ b/src/lib_plompiler/csir.ml @@ -0,0 +1,469 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let nb_wires_arch = 5 + +module Scalar = struct + include Bls12_381.Fr + + type scalar = t + + let mone = negate one + + let string_of_scalar x = + if eq x (of_string "-1") then "-1" + else if eq x (of_string "-2") then "-2" + else + let s = to_string x in + if String.length s > 3 then "h" ^ string_of_int (Z.hash (to_z x)) else s + + let equal a b = Bytes.equal (to_bytes a) (to_bytes b) + + (* TODO https://gitlab.com/nomadic-labs/privacy-team/-/issues/183 + Duplicated in plonk/bls.ml *) + let t : t Repr.t = + Repr.(map (bytes_of (`Fixed size_in_bytes)) of_bytes_exn to_bytes) +end + +(* If multiple tables are used, they all need to have the same number of wires, + so any smaller one will be padded. *) +module Table : sig + type t [@@deriving repr] + + val empty : t + + val size : t -> int + + type entry = { + a : Scalar.t; + b : Scalar.t; + c : Scalar.t; + d : Scalar.t; + e : Scalar.t; + } + + type partial_entry = { + a : Scalar.t option; + b : Scalar.t option; + c : Scalar.t option; + d : Scalar.t option; + e : Scalar.t option; + } + + val mem : entry -> t -> bool + + val find : partial_entry -> t -> entry option + + val to_list : t -> Scalar.t array list + + val of_list : Scalar.t array list -> t +end = struct + (* Rows are variables, columns are entries in the table. + If the table is full it would be |domain|^#variables e.g. 2^5=32 + Example OR gate: + [ + [|0; 0; 1; 1|] ; + [|0; 1; 0; 1|] ; + [|0; 1; 1; 1|] ; + [|0; 0; 0; 0|] ; + [|0; 0; 0; 0|] ; + ] + *) + type entry = { + a : Scalar.t; + b : Scalar.t; + c : Scalar.t; + d : Scalar.t; + e : Scalar.t; + } + + type partial_entry = { + a : Scalar.t option; + b : Scalar.t option; + c : Scalar.t option; + d : Scalar.t option; + e : Scalar.t option; + } + + type t = Scalar.t array array [@@deriving repr] + + let empty = [||] + + let size table = Array.length table.(0) + + (* Function returning the first table corresponding to the input partial entry. + A partial entry is found on the table at row i if it coincides + with the table values in all specified (i.e., not None) columns *) + let find_entry_i : partial_entry -> t -> int -> entry option = + fun pe table i -> + let match_partial_entry o s = + Option.(value ~default:true @@ map (Scalar.eq s) o) + in + if + match_partial_entry pe.a table.(0).(i) + && match_partial_entry pe.b table.(1).(i) + && match_partial_entry pe.c table.(2).(i) + then + Some + { + a = table.(0).(i); + b = table.(1).(i); + c = table.(2).(i); + d = table.(3).(i); + e = table.(4).(i); + } + else None + + let find pe table = + (* TODO make it a binary search *) + let sz = size table in + let rec aux i = + match i with + | 0 -> find_entry_i pe table 0 + | _ -> + let o = find_entry_i pe table i in + if Option.is_some o then o else aux (i - 1) + in + aux (sz - 1) + + let mem : entry -> t -> bool = + fun entry table -> + match + find + { + a = Some entry.a; + b = Some entry.b; + c = Some entry.c; + d = Some entry.d; + e = Some entry.e; + } + table + with + | Some _ -> true + | None -> false + + let to_list table = + Format.printf "\n%i %i\n" (Array.length table) (Array.length table.(0)) ; + Array.to_list table + + let of_list table = Array.of_list table +end + +let table_or = + Table.of_list + Scalar. + [ + [|zero; zero; one; one|]; + [|zero; one; zero; one|]; + [|zero; one; one; one|]; + [|zero; zero; zero; zero|]; + [|zero; zero; zero; zero|]; + ] + +module Tables = Map.Make (String) + +let table_registry = Tables.add "or" table_or Tables.empty + +module CS = struct + let q_list ?q_table ~qc ~ql ~qr ~qo ~qd ~qe ~qlg ~qrg ~qog ~qdg ~qeg ~qm ~qx2b + ~qx5a ~qx5c ~qecc_ws_add ~qecc_ed_add ~qecc_ed_cond_add ~qbool ~qcond_swap + ~q_anemoi ~q_plookup () = + let base = + [ + ("qc", qc); + ("ql", ql); + ("qr", qr); + ("qo", qo); + ("qd", qd); + ("qe", qe); + ("qlg", qlg); + ("qrg", qrg); + ("qog", qog); + ("qdg", qdg); + ("qeg", qeg); + ("qm", qm); + ("qx2b", qx2b); + ("qx5a", qx5a); + ("qx5c", qx5c); + ("qecc_ws_add", qecc_ws_add); + ("qecc_ed_add", qecc_ed_add); + ("qecc_ed_cond_add", qecc_ed_cond_add); + ("qbool", qbool); + ("qcond_swap", qcond_swap); + ("q_anemoi", q_anemoi); + ("q_plookup", q_plookup); + ] + in + Option.(map (fun q -> ("q_table", q)) q_table |> to_list) @ base + + type selector_tag = + | Linear + | Arithmetic + | ThisConstr + | NextConstr + | WireA + | WireB + | WireC + | WireD + | WireE + [@@deriving repr] + + let all_selectors = + q_list + ~qc:[ThisConstr; Arithmetic] + ~ql:[ThisConstr; Linear; Arithmetic; WireA] + ~qr:[ThisConstr; Linear; Arithmetic; WireB] + ~qo:[ThisConstr; Linear; Arithmetic; WireC] + ~qd:[ThisConstr; Linear; Arithmetic; WireD] + ~qe:[ThisConstr; Linear; Arithmetic; WireE] + ~qlg:[NextConstr; Linear; Arithmetic; WireA] + ~qrg:[NextConstr; Linear; Arithmetic; WireB] + ~qog:[NextConstr; Linear; Arithmetic; WireC] + ~qdg:[NextConstr; Linear; Arithmetic; WireD] + ~qeg:[NextConstr; Linear; Arithmetic; WireE] + ~qm:[ThisConstr; Arithmetic; WireA; WireB] + ~qx2b:[ThisConstr; Arithmetic; WireB] + ~qx5a:[ThisConstr; Arithmetic; WireA] + ~qx5c:[ThisConstr; Arithmetic; WireC] + ~qecc_ws_add:[ThisConstr; NextConstr; WireA; WireB; WireC] + ~qecc_ed_add:[ThisConstr; NextConstr; WireA; WireB; WireC] + ~qecc_ed_cond_add: + [ThisConstr; NextConstr; WireA; WireB; WireC; WireD; WireE] + ~qbool:[ThisConstr; WireA] + ~qcond_swap:[ThisConstr; WireA; WireB; WireC; WireD; WireE] + ~q_anemoi:[ThisConstr; NextConstr; WireB; WireC; WireD; WireE] + ~q_plookup:[ThisConstr; WireA; WireB; WireC; WireD; WireE] + ~q_table:[ThisConstr; WireA; WireB; WireC; WireD; WireE] + () + + let selectors_with_tags tags = + List.filter + (fun (_, sel_tags) -> List.for_all (fun t -> List.mem t sel_tags) tags) + all_selectors + |> List.map fst + + let this_constr_selectors = selectors_with_tags [ThisConstr] + + let next_constr_selectors = selectors_with_tags [NextConstr] + + let this_constr_linear_selectors = selectors_with_tags [ThisConstr; Linear] + + let next_constr_linear_selectors = selectors_with_tags [NextConstr; Linear] + + let arithmetic_selectors = selectors_with_tags [Arithmetic] + + type raw_constraint = { + a : int; + b : int; + c : int; + d : int; + e : int; + sels : (string * Scalar.t) list; + precomputed_advice : (string * Scalar.t) list; + label : string list; + } + [@@deriving repr] + + type gate = raw_constraint array [@@deriving repr] + + type t = gate list [@@deriving repr] + + let new_constraint ~a ~b ~c ?(d = 0) ?(e = 0) ?qc ?ql ?qr ?qo ?qd ?qe ?qlg + ?qrg ?qog ?qdg ?qeg ?qm ?qx2b ?qx5a ?qx5c ?qecc_ws_add ?qecc_ed_add + ?qecc_ed_cond_add ?qbool ?qcond_swap ?q_anemoi ?q_plookup ?q_table + ?(precomputed_advice = []) ?(labels = []) label = + let sels = + List.filter_map + (fun (l, x) -> Option.bind x (fun c -> Some (l, c))) + (q_list + ~qc + ~ql + ~qr + ~qo + ~qd + ~qe + ~qlg + ~qrg + ~qog + ~qdg + ~qeg + ~qm + ~qx2b + ~qx5a + ~qx5c + ~qecc_ws_add + ~qecc_ed_add + ~qecc_ed_cond_add + ~qbool + ~qcond_swap + ~q_anemoi + ~q_plookup + ~q_table + ()) + in + {a; b; c; d; e; sels; precomputed_advice; label = label :: labels} + + let get_sel sels s = + match List.find_opt (fun (x, _) -> s = x) sels with + | None -> Scalar.zero + | Some (_, c) -> c + + let to_string_raw_constraint {a; b; c; d; e; sels; precomputed_advice; label} + : string = + let pp_sel (s, c) = s ^ ":" ^ Scalar.string_of_scalar c in + let selectors = String.concat " " (List.map pp_sel sels) in + let precomputed_advice = + String.concat " " (List.map pp_sel precomputed_advice) + in + Format.sprintf + "a:%i b:%i c:%i d:%i e:%i %s | %s [%s]" + a + b + c + d + e + selectors + precomputed_advice + (String.concat " ; " label) + + let to_string_gate g = + String.concat "\n" @@ Array.to_list @@ Array.map to_string_raw_constraint g + + let to_string cs = + List.fold_left (fun acc con -> acc ^ to_string_gate con ^ "\n\n") "" cs + + let is_linear_raw_constr constr = + let linear_selectors = + ("qc" :: this_constr_linear_selectors) @ next_constr_linear_selectors + in + let is_linear_sel (s, _q) = List.mem s linear_selectors in + List.for_all is_linear_sel constr.sels + + let rename_wires_constr ~rename constr = + { + constr with + a = rename constr.a; + b = rename constr.b; + c = rename constr.c; + d = rename constr.d; + e = rename constr.e; + } + + let rename_wires ~rename gate = Array.map (rename_wires_constr ~rename) gate + + let is_arithmetic_raw_constr constr = + let is_arithmetic_sel (s, _q) = List.mem s arithmetic_selectors in + List.for_all is_arithmetic_sel constr.sels + + let boolean_raw_constr constr = + if + constr.sels = [("ql", Scalar.mone); ("qm", Scalar.one)] + && constr.a = constr.b + then Some constr.a + else None + + let used_selectors gate i = + let this_sels = gate.(i).sels in + let prev_sels = if i = 0 then [] else gate.(i - 1).sels in + List.filter (fun (s, _) -> List.mem s this_constr_selectors) this_sels + @ List.filter (fun (s, _) -> List.mem s next_constr_selectors) prev_sels + + let wires_of_constr_i gate i = + let a_selectors = selectors_with_tags [WireA] in + let b_selectors = selectors_with_tags [WireB] in + let c_selectors = selectors_with_tags [WireC] in + let d_selectors = selectors_with_tags [WireD] in + let e_selectors = selectors_with_tags [WireE] in + let intersect names = List.exists (fun (s, _q) -> List.mem s names) in + let sels = used_selectors gate i in + (* We treat qecc_ed_cond_add exceptionally until we have a better interface + on unused wires *) + let relax = + List.map fst sels = ["qecc_ed_cond_add"] && gate.(i).sels = [] + in + let a_selectors = if relax then [] else a_selectors in + let b_selectors = if relax then [] else b_selectors in + let c_selectors = if relax then [] else c_selectors in + (* We treat q_anemoi exceptionally until we have a better interface + on unused wires *) + let relax = List.map fst sels = ["q_anemoi"] && gate.(i).sels = [] in + let a_selectors = if relax then [] else a_selectors in + let b_selectors = if relax then [] else b_selectors in + let c_selectors = if relax then [] else c_selectors in + List.map2 + (fun wsels w -> if intersect wsels sels then w else -1) + [a_selectors; b_selectors; c_selectors; d_selectors; e_selectors] + [gate.(i).a; gate.(i).b; gate.(i).c; gate.(i).d; gate.(i).e] + + let gate_wires gate = + List.init (Array.length gate) (wires_of_constr_i gate) + |> List.concat |> List.sort_uniq Int.compare + |> List.filter (fun x -> x >= 0) + + (* the relationship of this function wrt is_linear_raw_constr is a bit weird *) + let linear_terms constr = + if not @@ is_linear_raw_constr constr then + raise @@ Invalid_argument "constraint is non-linear" + else + List.map + (fun (sel_name, coeff) -> + match sel_name with + | "qc" -> (coeff, -1) + | "ql" -> (coeff, constr.a) + | "qr" -> (coeff, constr.b) + | "qo" -> (coeff, constr.c) + | "qd" -> (coeff, constr.d) + | "qe" -> (coeff, constr.e) + | _ -> assert false) + constr.sels + |> List.filter (fun (q, _) -> not @@ Scalar.is_zero q) + + let mk_linear_constr (wires, sels) = + match wires with + | [a; b; c; d; e] -> + {a; b; c; d; e; sels; precomputed_advice = []; label = ["linear"]} + | _ -> assert false + + let mk_bool_constr wire = + { + a = wire; + b = 0; + c = 0; + d = 0; + e = 0; + sels = [("qbool", Scalar.one)]; + precomputed_advice = []; + label = ["bool"]; + } + + let raw_constraint_equal c1 c2 = + c1.a = c2.a && c1.b = c2.b && c1.c = c2.c && c1.d = c2.d && c1.e = c2.e + && c1.label = c2.label + && List.for_all2 + (fun (name, coeff) (name', coeff') -> + name = name' && Scalar.eq coeff coeff') + c1.sels + c2.sels +end diff --git a/src/lib_plompiler/dune b/src/lib_plompiler/dune new file mode 100644 index 000000000000..646dbcf14d6c --- /dev/null +++ b/src/lib_plompiler/dune @@ -0,0 +1,20 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name plompiler) + (public_name octez-plompiler) + (instrumentation (backend bisect_ppx)) + (libraries + repr + stdint + hacl-star + octez-bls12-381-hash + octez-polynomial + octez-mec) + (preprocess (staged_pps ppx_repr ppx_deriving.show))) + +(rule + (alias runtest) + (deps z3/run_z3_tests.sh (glob_files z3/*.z3)) + (action (chdir z3 (run sh run_z3_tests.sh)))) diff --git a/src/lib_plompiler/encoding.ml b/src/lib_plompiler/encoding.ml new file mode 100644 index 000000000000..70efabd4c10b --- /dev/null +++ b/src/lib_plompiler/encoding.ml @@ -0,0 +1,206 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Lang_stdlib + +module Encodings (L : LIB) = struct + open L + + (** + Encoding type for encapsulating encoding/decoding/input functions. + This type enables us to use more structured types for data + in circuits. + For that, encoding is parameterized by 3 types: + - 'oh is the type of the high-level OCaml representation + - 'u is the unpacked type, i.e. a collection of atomic reprs. + - `p is the packed type, i.e the inner type of Plompiler's repr. + + For example, for the representation of a point (pair of scalars), + one might have: + ( {x:int; y:int}, + scalar repr * scalar repr, + scalar * scalar + ) encoding + + The first type, the record [{x:int; y:int}], represents an OCaml point, + which becomes the argument taken by the [input] function. + + The second type, [scalar repr * scalar repr], is an unpacking of the + encoding. This is used for the result of [decode]. We can use any type + isomorphic to [scalar repr * scalar repr] here. + + The last type must be [scalar * scalar], as an encoding of a point will be + of the type [(scalar * scalar) repr]. + *) + + type ('oh, 'u, 'p) encoding = { + encode : 'u -> 'p repr; + decode : 'p repr -> 'u; + input : 'oh -> 'p Input.t; + of_input : 'p Input.t -> 'oh; + } + + (** + The function [conv] defines conversions for [encoding]s, by changing + the higher-level ['u] and and ['oh] types. + *) + let conv : + ('u1 -> 'u0) -> + ('u0 -> 'u1) -> + ('o1 -> 'o0) -> + ('o0 -> 'o1) -> + ('o0, 'u0, 'p) encoding -> + ('o1, 'u1, 'p) encoding = + fun f g fi gi e -> + let encode a = e.encode @@ f a in + let decode b = g @@ e.decode b in + let input x = e.input @@ fi x in + let of_input x = gi @@ e.of_input x in + {encode; decode; input; of_input} + + let with_implicit_bool_check : + ('p repr -> bool repr t) -> ('o, 'u, 'p) encoding -> ('o, 'u, 'p) encoding + = + fun bc e -> + {e with input = (fun x -> Input.with_implicit_bool_check bc @@ e.input x)} + + let with_assertion : + ('p repr -> unit repr t) -> ('o, 'u, 'p) encoding -> ('o, 'u, 'p) encoding + = + fun assertion e -> + {e with input = (fun x -> Input.with_assertion assertion @@ e.input x)} + + (** Encoding combinators *) + let scalar_encoding = + let encode x = x in + let decode x = x in + let input = Input.scalar in + let of_input = Input.to_scalar in + {encode; decode; input; of_input} + + let bool_encoding = + let encode x = x in + let decode x = x in + let input = Input.bool in + let of_input = Input.to_bool in + {encode; decode; input; of_input} + + let list_encoding (e : _ encoding) = + let encode a = to_list @@ List.map e.encode a in + let decode x = List.map e.decode (of_list x) in + let input a = Input.list @@ List.map e.input a in + let of_input x = List.map e.of_input (Input.to_list x) in + {encode; decode; input; of_input} + + (* Encoding for lists, where we keep the repr of the list itself, not a list + of repr *) + let atomic_list_encoding : + ('a, 'b repr, 'c) encoding -> ('a list, 'b list repr, 'c list) encoding = + fun e -> + let encode a = to_list @@ List.map e.encode (of_list a) in + let decode x = to_list @@ List.map e.decode (of_list x) in + let input a = Input.list @@ List.map e.input a in + let of_input x = List.map e.of_input (Input.to_list x) in + {encode; decode; input; of_input} + + let obj2_encoding (el : _ encoding) (er : _ encoding) = + let encode (a, b) = pair (el.encode a) (er.encode b) in + let decode p = + let a, b = of_pair p in + (el.decode a, er.decode b) + in + let input (a, f) = Input.pair (el.input a) (er.input f) in + let of_input p = + let a, b = Input.to_pair p in + (el.of_input a, er.of_input b) + in + {encode; decode; input; of_input} + + let atomic_obj2_encoding : + ('a, 'b repr, 'c) encoding -> + ('d, 'e repr, 'f) encoding -> + ('a * 'd, ('b * 'e) repr, 'c * 'f) encoding = + fun el er -> + let encode p = + let a, b = of_pair p in + pair (el.encode a) (er.encode b) + in + let decode p = + let a, b = of_pair p in + pair (el.decode a) (er.decode b) + in + let input (a, f) = Input.pair (el.input a) (er.input f) in + let of_input p = + let a, b = Input.to_pair p in + (el.of_input a, er.of_input b) + in + {encode; decode; input; of_input} + + let obj3_encoding e0 e1 e2 = obj2_encoding e0 (obj2_encoding e1 e2) + + let atomic_obj3_encoding e0 e1 e2 = + atomic_obj2_encoding e0 (atomic_obj2_encoding e1 e2) + + let obj4_encoding e0 e1 e2 e3 = obj2_encoding e0 (obj3_encoding e1 e2 e3) + + let atomic_obj4_encoding e0 e1 e2 e3 = + atomic_obj2_encoding e0 (atomic_obj3_encoding e1 e2 e3) + + let obj5_encoding e0 e1 e2 e3 e4 = + obj2_encoding e0 (obj4_encoding e1 e2 e3 e4) + + let atomic_obj5_encoding e0 e1 e2 e3 e4 = + atomic_obj2_encoding e0 (atomic_obj4_encoding e1 e2 e3 e4) + + let obj6_encoding e0 e1 e2 e3 e4 e5 = + obj2_encoding e0 (obj5_encoding e1 e2 e3 e4 e5) + + let atomic_obj6_encoding e0 e1 e2 e3 e4 e5 = + atomic_obj2_encoding e0 (atomic_obj5_encoding e1 e2 e3 e4 e5) + + let obj7_encoding e0 e1 e2 e3 e4 e5 e6 = + obj2_encoding e0 (obj6_encoding e1 e2 e3 e4 e5 e6) + + let atomic_obj7_encoding e0 e1 e2 e3 e4 e5 e6 = + atomic_obj2_encoding e0 (atomic_obj6_encoding e1 e2 e3 e4 e5 e6) + + let obj8_encoding e0 e1 e2 e3 e4 e5 e6 e7 = + obj2_encoding e0 (obj7_encoding e1 e2 e3 e4 e5 e6 e7) + + let atomic_obj8_encoding e0 e1 e2 e3 e4 e5 e6 e7 = + atomic_obj2_encoding e0 (atomic_obj7_encoding e1 e2 e3 e4 e5 e6 e7) + + let obj9_encoding e0 e1 e2 e3 e4 e5 e6 e7 e8 = + obj2_encoding e0 (obj8_encoding e1 e2 e3 e4 e5 e6 e7 e8) + + let atomic_obj9_encoding e0 e1 e2 e3 e4 e5 e6 e7 e8 = + atomic_obj2_encoding e0 (atomic_obj8_encoding e1 e2 e3 e4 e5 e6 e7 e8) + + let obj10_encoding e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 = + obj2_encoding e0 (obj9_encoding e1 e2 e3 e4 e5 e6 e7 e8 e9) + + let atomic_obj10_encoding e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 = + atomic_obj2_encoding e0 (atomic_obj9_encoding e1 e2 e3 e4 e5 e6 e7 e8 e9) +end diff --git a/src/lib_plompiler/gadget_anemoi.ml b/src/lib_plompiler/gadget_anemoi.ml new file mode 100644 index 000000000000..fbbccf082f0a --- /dev/null +++ b/src/lib_plompiler/gadget_anemoi.ml @@ -0,0 +1,212 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Lang_core +open Lang_stdlib +module AnemoiPerm = Bls12_381_hash.Permutation.Anemoi + +module Make (L : LIB) = struct + open L + + (* FIXME: should be removed when + https://gitlab.com/nomadic-labs/cryptography/privacy-team/-/merge_requests/387 + is merged *) + let parameters = AnemoiPerm.Parameters.security_128_state_size_2 + + let nb_rounds = AnemoiPerm.Parameters.get_number_of_rounds parameters + + let matrix = AnemoiPerm.Parameters.get_matrix parameters + + let rc = AnemoiPerm.Parameters.get_round_constants parameters + + let rc = + Array.init + (Array.length rc + 2) + (fun i -> + (* We pad with two zeroes *) + if i / 2 = nb_rounds then Bls12_381.Fr.zero + else if i mod 2 = 0 then rc.(i / 2) + else rc.(nb_rounds + (i / 2))) + + let rec repeat : n:int -> ('a -> 'a t) -> 'a -> 'a t = + fun ~n f e -> + if n <= 0 then ret e + else + let* x = f e in + repeat ~n:(n - 1) f x + + let round : + scalar repr * scalar repr * int -> (scalar repr * scalar repr * int) t = + fun (xi, yi, i) -> + let kx, ky = (rc.(i), rc.(i + 1)) in + with_label ~label:"Anemoi.round" + @@ let* res = Anemoi.anemoi_round ~kx ~ky (xi, yi) in + let xj, yj = of_pair res in + ret @@ (xj, yj, i + 2) + + let init_state_for_rounds x0 y0 = + let* x00 = + Num.add + ~ql:matrix.(0).(0) + ~qr:matrix.(0).(1) + ~qc:S.((matrix.(0).(0) * rc.(0)) + (matrix.(0).(1) * rc.(1))) + x0 + y0 + in + let* y00 = + Num.add + ~ql:matrix.(1).(0) + ~qr:matrix.(1).(1) + ~qc:S.((matrix.(1).(0) * rc.(0)) + (matrix.(1).(1) * rc.(1))) + x0 + y0 + in + ret (x00, y00) + + let compress : scalar repr -> scalar repr -> scalar repr t = + fun x0 y0 -> + with_label ~label:"Anemoi.compress" + @@ let* x00, y00 = init_state_for_rounds x0 y0 in + let* xn, yn, _i = repeat ~n:nb_rounds round (x00, y00, 2) in + Num.add_list (to_list [x0; y0; xn; yn]) + + let double_round : + scalar repr * scalar repr * int -> (scalar repr * scalar repr * int) t = + fun (xi, yi, i) -> + let kx1, ky1 = (rc.(i), rc.(i + 1)) in + let kx2, ky2 = (rc.(i + 2), rc.(i + 3)) in + with_label ~label:"Anemoi.double_round" + @@ let* res = Anemoi.anemoi_double_round ~kx1 ~ky1 ~kx2 ~ky2 (xi, yi) in + let xj, yj = of_pair res in + ret @@ (xj, yj, i + 4) + + let compress_two : scalar repr -> scalar repr -> scalar repr t = + fun x0 y0 -> + with_label ~label:"Anemoi.compress_two" + @@ let* x00, y00 = init_state_for_rounds x0 y0 in + let* xn, yn, n = repeat ~n:(nb_rounds / 2) double_round (x00, y00, 2) in + let* xn, yn, _ = + if nb_rounds mod 2 = 0 then ret (xn, yn, 0) else round (xn, yn, n) + in + Num.add_list (to_list [x0; y0; xn; yn]) + + let custom_round : + scalar repr * scalar repr * int -> (scalar repr * scalar repr * int) t = + fun (xi, yi, i) -> + let kx1, ky1 = (rc.(i), rc.(i + 1)) in + let kx2, ky2 = (rc.(i + 2), rc.(i + 3)) in + with_label ~label:"Anemoi.custom_round" + @@ let* res = Anemoi.anemoi_custom ~kx1 ~ky1 ~kx2 ~ky2 (xi, yi) in + let xj, yj = of_pair res in + ret @@ (xj, yj, i + 4) + + let compress_custom : scalar repr -> scalar repr -> scalar repr t = + fun x0 y0 -> + with_label ~label:"Anemoi.compress_custom" + @@ let* x00, y00 = init_state_for_rounds x0 y0 in + let* xn, yn, n = repeat ~n:(nb_rounds / 2) custom_round (x00, y00, 2) in + let* xn, yn, _ = + if nb_rounds mod 2 = 0 then ret (xn, yn, 0) else round (xn, yn, n) + in + Num.add_list (to_list [x0; y0; xn; yn]) + + let compress_19_5 : scalar repr -> scalar repr -> scalar repr t = + fun x0 y0 -> + (* Anemoi of 20 rounds without the first linear layer *) + (* let* x1, y1 = init_state_for_rounds x0 y0 in *) + with_label ~label:"Anemoi.19.5" + @@ let* xn, yn, _ = repeat ~n:10 custom_round (x0, y0, 0) in + Num.add_list (to_list [x0; y0; xn; yn]) + + let digest : ?input_length:int -> scalar list repr -> scalar repr t = + fun ?input_length:_ inputs -> + match of_list inputs with + | [] -> constant_scalar (AnemoiPerm.jive128_1 S.zero S.zero) + | [x] -> + let* zero = constant_scalar S.zero in + compress_19_5 zero x + | x :: rest -> foldM compress_19_5 x rest +end + +module Anemoi128 = struct + module P : Hash_sig.P_HASH = struct + type scalar = S.t + + let anemoi_instance = + (* 19 rounds *) + AnemoiPerm.(allocate_ctxt Parameters.security_128_state_size_2) + + let jive x y = + let state = + AnemoiPerm.set_state anemoi_instance [|x; y|] ; + AnemoiPerm.apply_flystel anemoi_instance ; + AnemoiPerm.apply_permutation anemoi_instance ; + AnemoiPerm.get_state anemoi_instance + in + S.(state.(0) + state.(1) + x + y) + + let direct ?input_length:_ inputs = + match Array.to_list inputs with + | [] -> jive S.zero S.zero + | [x] -> jive S.zero x + | x :: rest -> List.fold_left jive x rest + + type ctxt = S.t + + let init ?input_length:_ () = S.zero + + let digest ctxt inputs = + ignore ctxt ; + direct inputs + + let get ctxt = ctxt + end + + (* compute one round and return intermediate values *) + let compute_one_round x0 y0 kx ky = + let beta = AnemoiPerm.Parameters.beta in + let gamma = AnemoiPerm.Parameters.gamma in + let delta = AnemoiPerm.Parameters.delta in + let g = AnemoiPerm.Parameters.g in + let alpha_inv = AnemoiPerm.Parameters.alpha_inv in + let g2_p_1 = S.((g * g) + one) in + (* -> Sbox *) + (* w^5 = x0 - (beta y0^2 + gamma) *) + let w_5 = S.(sub x0 ((beta * y0 * y0) + gamma)) in + (* Computing w *) + let w = S.(pow w_5 (to_z alpha_inv)) in + (* v = y0 - w *) + let v = S.sub y0 w in + (* u = w^5 + beta * v^2 + delta *) + let u = S.(w_5 + ((beta * v * v) + delta)) in + (* -> Linear layer + rc *) + (* x1 = (u + kx) + g * (v + ky) *) + let x1 = S.(u + kx + (g * (v + ky))) in + (* y1 = (g * (u + kx) + (g^2 + 1) * (v + ky) *) + let y1 = S.((g * (u + kx)) + (g2_p_1 * (v + ky))) in + (w_5, w, v, u, x1, y1) + + module V : Hash_sig.HASH = Make +end diff --git a/src/lib_plompiler/gadget_blake2s.ml b/src/lib_plompiler/gadget_blake2s.ml new file mode 100644 index 000000000000..6a36b760ba52 --- /dev/null +++ b/src/lib_plompiler/gadget_blake2s.ml @@ -0,0 +1,232 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Lang_stdlib + +module type BLAKE2S = functor (L : LIB) -> sig + open L + + val mixing_g : + Bytes.bl repr Array.t -> + int -> + int -> + int -> + int -> + Bytes.bl repr -> + Bytes.bl repr -> + Bytes.bl repr Array.t t + + val compression : + Bytes.bl repr Array.t -> + Bytes.bl repr Array.t -> + Stdint.Uint64.t -> + bool -> + Bytes.bl repr Array.t t + + val blake2s : Bytes.bl repr -> bytes -> Bytes.bl repr t +end + +module Blake2s : BLAKE2S = +functor + (L : LIB) + -> + struct + open L + + let mixing_g v a b c d x y = + with_label ~label:"Blake2s.mixing_g" + @@ + let r1 = 16 in + let r2 = 12 in + let r3 = 8 in + let r4 = 7 in + let* tmp = Bytes.add ~ignore_carry:true v.(a) v.(b) in + let* tmp = Bytes.add ~ignore_carry:true tmp x in + v.(a) <- tmp ; + let* tmp = Bytes.xor v.(d) v.(a) in + let tmp = Bytes.rotate tmp r1 in + v.(d) <- tmp ; + let* tmp = Bytes.add ~ignore_carry:true v.(c) v.(d) in + v.(c) <- tmp ; + let* tmp = Bytes.xor v.(b) v.(c) in + let tmp = Bytes.rotate tmp r2 in + v.(b) <- tmp ; + let* tmp = Bytes.add ~ignore_carry:true v.(a) v.(b) in + let* tmp = Bytes.add ~ignore_carry:true tmp y in + v.(a) <- tmp ; + let* tmp = Bytes.xor v.(d) v.(a) in + let tmp = Bytes.rotate tmp r3 in + v.(d) <- tmp ; + let* tmp = Bytes.add ~ignore_carry:true v.(c) v.(d) in + v.(c) <- tmp ; + let* tmp = Bytes.xor v.(b) v.(c) in + let tmp = Bytes.rotate tmp r4 in + v.(b) <- tmp ; + ret v + + let sigma = + [| + [|0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10; 11; 12; 13; 14; 15|]; + [|14; 10; 4; 8; 9; 15; 13; 6; 1; 12; 0; 2; 11; 7; 5; 3|]; + [|11; 8; 12; 0; 5; 2; 15; 13; 10; 14; 3; 6; 7; 1; 9; 4|]; + [|7; 9; 3; 1; 13; 12; 11; 14; 2; 6; 5; 10; 4; 0; 15; 8|]; + [|9; 0; 5; 7; 2; 4; 10; 15; 14; 1; 11; 12; 6; 8; 3; 13|]; + [|2; 12; 6; 10; 0; 11; 8; 3; 4; 13; 7; 5; 15; 14; 1; 9|]; + [|12; 5; 1; 15; 14; 13; 4; 10; 0; 7; 6; 3; 9; 2; 8; 11|]; + [|13; 11; 7; 14; 12; 1; 3; 9; 5; 0; 15; 4; 8; 6; 2; 10|]; + [|6; 15; 14; 9; 11; 3; 0; 8; 12; 2; 13; 7; 1; 4; 10; 5|]; + [|10; 2; 8; 4; 7; 6; 1; 5; 15; 11; 9; 14; 3; 12; 13; 0|]; + |] + + let compression h m t f = + assert (Array.length h = 8) ; + assert (Array.length m = 16) ; + with_label ~label:"Blake2s.compression" + @@ let* constants = + mapM + (fun c -> constant_bytes (Utils.bytes_of_hex c)) + [ + "6A09E667"; + "BB67AE85"; + "3C6EF372"; + "A54FF53A"; + "510E527F"; + "9B05688C"; + "1F83D9AB"; + "5BE0CD19"; + ] + in + let constants = Array.of_list constants in + let v = Array.append h constants in + let* tmp = constant_uint32 Stdint.Uint64.(to_uint32 t) in + let* tmp = Bytes.xor v.(12) tmp in + v.(12) <- tmp ; + let* tmp = + constant_uint32 Stdint.Uint64.(to_uint32 (shift_right t 32)) + in + let* tmp = Bytes.xor v.(13) tmp in + v.(13) <- tmp ; + (* TODO here we assign many times the same constant *) + let* tmp = constant_uint32 Stdint.Uint32.max_int in + let* tmp = if f then Bytes.xor v.(14) tmp else ret v.(14) in + v.(14) <- tmp ; + let* v = + foldiM + (fun v i -> + let s = sigma.(i mod 10) in + let* v = mixing_g v 0 4 8 12 m.(s.(0)) m.(s.(1)) in + let* v = mixing_g v 1 5 9 13 m.(s.(2)) m.(s.(3)) in + let* v = mixing_g v 2 6 10 14 m.(s.(4)) m.(s.(5)) in + let* v = mixing_g v 3 7 11 15 m.(s.(6)) m.(s.(7)) in + let* v = mixing_g v 0 5 10 15 m.(s.(8)) m.(s.(9)) in + let* v = mixing_g v 1 6 11 12 m.(s.(10)) m.(s.(11)) in + let* v = mixing_g v 2 7 8 13 m.(s.(12)) m.(s.(13)) in + mixing_g v 3 4 9 14 m.(s.(14)) m.(s.(15))) + v + 10 + in + foldiM + (fun h i -> + let* tmp = Bytes.xor h.(i) v.(i) in + h.(i) <- tmp ; + let* tmp = Bytes.xor h.(i) v.(i + 8) in + h.(i) <- tmp ; + ret h) + h + 8 + + let blake2s input personalization = + assert (Stdlib.Bytes.length personalization = 8) ; + assert (List.length (of_list input) mod 8 = 0) ; + with_label ~label:"Blake2s.blake2s" + @@ + let fist_iv = + Stdint.Uint32.( + let c = of_bytes_big_endian (Utils.bytes_of_hex "6A09E667") 0 in + let mask = of_bytes_big_endian (Utils.bytes_of_hex "01010000") 0 in + let c = logxor (logxor c mask) (of_int 32) in + let b = Stdlib.Bytes.create 4 in + to_bytes_big_endian c b 0 ; + let (`Hex s) = Hex.of_bytes b in + s) + in + let* h = + foldM + (fun acc c -> + let* w = constant_bytes (Utils.bytes_of_hex c) in + ret (w :: acc)) + [] + [ + fist_iv; + "BB67AE85"; + "3C6EF372"; + "A54FF53A"; + "510E527F"; + "9B05688C"; + (* TODO these last two should also contain personalization *) + "1F83D9AB"; + "5BE0CD19"; + ] + in + let h = Array.of_list (List.rev h) in + let* z = constant_bool false in + + let rec loop (blocks, acc_block, acc_u32) (nblock, nu32) rest = + let blocks, acc_block, acc_u32, nblock, nu32 = + if nu32 = 32 then + (blocks, List.rev acc_u32 :: acc_block, [], nblock + 1, 0) + else (blocks, acc_block, acc_u32, nblock, nu32) + in + let blocks, acc_block, acc_u32, nblock, nu32 = + if nblock = 16 then ( + assert (nu32 = 0) ; + (Array.of_list (List.rev acc_block) :: blocks, [], [], 0, 0)) + else (blocks, acc_block, acc_u32, nblock, nu32) + in + match rest with + | [] -> + if nblock = 0 && nu32 = 0 then blocks + else loop (blocks, acc_block, z :: acc_u32) (nblock, nu32 + 1) [] + | bit :: rest -> + loop (blocks, acc_block, bit :: acc_u32) (nblock, nu32 + 1) rest + in + let blocks = loop ([], [], []) (0, 0) (of_list input) in + match blocks with + | [] -> assert false + | last :: rest_inverted -> + let* _ = + foldM + (fun i b -> + let t = Stdint.Uint64.(succ (of_int i) * of_int 64) in + let* _ = compression h b t false in + ret (i + 1)) + 0 + (List.rev @@ List.map (Array.map to_list) rest_inverted) + in + let t = Stdint.Uint64.of_int (List.length (of_list input) / 8) in + let* h = compression h (Array.map to_list last) t true in + let res = List.(map of_list (Array.to_list h) |> flatten) in + ret @@ to_list res + end diff --git a/src/lib_plompiler/gadget_edwards.ml b/src/lib_plompiler/gadget_edwards.ml new file mode 100644 index 000000000000..3248f7cc2f81 --- /dev/null +++ b/src/lib_plompiler/gadget_edwards.ml @@ -0,0 +1,208 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Lang_core +open Lang_stdlib + +module type CURVE_PARAMETERS = sig + val a : S.t + + val d : S.t + + val scalar_order : Z.t + + val base_order : Z.t +end + +let zero = S.zero + +let one = S.one + +let two = S.add one one + +let mone = S.negate one + +module type AFFINE = functor (L : LIB) -> sig + open L + + type point = scalar * scalar + + val input_point : ?kind:input_kind -> S.t * S.t -> point repr t + + val is_on_curve : point repr -> bool repr t + + (** Also checks that the point is on the curve (but not necessarily in the + subgroup). *) + val from_coordinates : scalar repr -> scalar repr -> point repr t + + val unsafe_from_coordinates : scalar repr -> scalar repr -> point repr t + + val get_u_coordinate : point repr -> scalar repr + + val get_v_coordinate : point repr -> scalar repr + + (** The identity element of the curve (0, 1). *) + val id : S.t * S.t + + val add : point repr -> point repr -> point repr t + + val cond_add : point repr -> point repr -> bool repr -> point repr t + + val double : point repr -> point repr t + + val scalar_mul : bool list repr -> point repr -> point repr t + + val scalar_order : Z.t + + val base_order : Z.t + + val multi_scalar_mul : bool list list repr -> point list repr -> point repr t +end + +module MakeAffine (Params : CURVE_PARAMETERS) : AFFINE = +functor + (L : LIB) + -> + struct + include Params + open L + + type point = scalar * scalar + + let input_point ?(kind = `Private) (u, v) = + Input.(pair (scalar u) (scalar v)) |> input ~kind + + let get_u_coordinate p = of_pair p |> fst + + let get_v_coordinate p = of_pair p |> snd + + let id = (S.zero, S.one) + + (* 1 constraint *) + let is_on_curve p = + with_label ~label:"Edwards.is_on_curve" + @@ + let u, v = of_pair p in + let* u2 = Num.square u in + let* v2 = Num.square v in + (* x_l = u^2 *) + (* x_r = v^2 *) + (* -1 * u^2 + 1 * v^2 - d * u^2 v^2 - 1 = 0 *) + (* | | | | | *) + (* ql qr qm qc qo *) + let qm = S.(negate Params.d) in + (* The last wire is multiplied by 0 so we can put any value, we chose u here. *) + let* o = Num.custom ~qc:mone ~ql:mone ~qr:one ~qm u2 v2 in + Num.is_zero o + + let from_coordinates u v = + with_label ~label:"Edwards.from_coordinates" + @@ + let p = pair u v in + with_bool_check (is_on_curve p) >* ret p + + let unsafe_from_coordinates u v = + with_label ~label:"Edwards.unsafe_from_coordinates" (pair u v |> ret) + + (* P1:(u1, v1) + P2:(u2, v2) = P3:(u3, v3) + 2 constraints + *) + let add p1 p2 = Ecc.edwards_add p1 p2 + + let cond_add p1 p2 b = Ecc.edwards_cond_add p1 p2 b + + (* 2 * P1:(u1, v1) = P1:(u1, v1) + P1:(u1, v1) = P3:(u3, v3) as the addition is complete + 12 constraints + *) + + let double p = add p p + + let point_or_zero point b = + with_label ~label:"Edwards.point_or_zero" + @@ + let p_u = get_u_coordinate point in + let p_v = get_v_coordinate point in + (* if b = 1, return (p_u, p_v); otherwise the zero point (0, 1) *) + let b = scalar_of_bool b in + let* u = Num.mul b p_u in + let* v = Num.custom ~qr:mone ~qc:one ~qm:one p_v b in + ret @@ pair u v + + let scalar_mul s p = + let* one = Bool.constant_bool true in + with_label ~label:"Edwards.scalar_mul" + @@ + let rev_s = List.rev (of_list s) in + let* init = point_or_zero p (List.hd rev_s) in + foldM + (fun acc b -> + let* acc = cond_add acc acc one in + cond_add acc p b) + init + (List.tl rev_s) + + (* Computes \prod_i p_i^s_i with inputs: + - ls: [[s_11; ...; s_1m]; ...; [s_n1; ...; s_nm]] + - lp: [p1; ...; pn] *) + let multi_scalar_mul ls lp = + let* one = Bool.constant_bool true in + with_label ~label:"Edwards.multi_scalar_mul" + @@ + (* Check we apply Shamir's trick on at least 2 points *) + let () = assert (List.(length (of_list ls) > 1)) in + (* Converting ls to ls' = [[s_11; ...; s_n1]; ...; [s_1m; ...; s_nm]] *) + let ls = List.map of_list (of_list ls) |> Utils.transpose |> List.rev in + let points = of_list lp in + (* Check we perform scalar multiplications on lists of at least 1 bit *) + assert (List.(length ls > 0)) ; + (* Initializing the accumulator with the first round of Shamir's trick *) + let heads = List.hd ls in + let* init = point_or_zero (List.hd points) (List.hd heads) in + let* init = fold2M cond_add init (List.tl points) (List.tl heads) in + + (* Applying Shamir's trick on the rest of the rounds *) + foldM + (fun acc lb -> + let* acc = cond_add acc acc one in + fold2M cond_add acc points (of_list lb)) + init + List.(map to_list (tl ls)) + end + +module Jubjub = MakeAffine (struct + let a = mone + + let d = + S.of_string + "19257038036680949359750312669786877991949435402254120286184196891950884077233" + + let scalar_order = + Z.of_string + "6554484396890773809930967563523245729705921265872317281365359162392183254199" + + let base_order = + Z.of_string + "52435875175126190479447740508185965837690552500527637822603658699938581184513" +end) diff --git a/src/lib_plompiler/gadget_merkle.ml b/src/lib_plompiler/gadget_merkle.ml new file mode 100644 index 000000000000..21fbf3eb732c --- /dev/null +++ b/src/lib_plompiler/gadget_merkle.ml @@ -0,0 +1,213 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Make (H : sig + module P : Hash_sig.P_HASH + + module V : Hash_sig.HASH +end) = +struct + open Lang_stdlib + open Lang_core + + let left = true + + let right = false + + module P = struct + type tree = Leaf of S.t | Node of S.t * tree * tree + + let root = function Leaf h -> h | Node (h, _, _) -> h + + let generate_tree ?(leaves = [||]) depth = + let size = Z.(to_int (pow (of_int 2) depth)) in + if not (leaves = [||]) then assert (Array.length leaves = size) ; + let leaves = + if leaves = [||] then Array.init size (fun _ -> S.random ()) else leaves + in + let rec build_tree depth index = + if depth = 0 then Leaf leaves.(index) + else + let index = 2 * index in + let tree1 = build_tree (depth - 1) index in + let tree2 = build_tree (depth - 1) (index + 1) in + let root = H.P.direct ~input_length:2 [|root tree1; root tree2|] in + Node (root, tree1, tree2) + in + build_tree depth 0 + + let get_depth tree = + let rec aux acc tree = + match tree with Leaf _ -> acc | Node (_, t, _) -> aux (acc + 1) t + in + aux 0 tree + + let get_leaves tree = + let depth = get_depth tree in + let size = Z.(to_int (pow (of_int 2) depth)) in + let leaves = Array.init size (fun _i -> S.zero) in + let rec aux tree index = + match tree with + | Node (_, t1, t2) -> + let index = 2 * index in + aux t1 index ; + aux t2 (index + 1) + | Leaf leaf -> Array.set leaves index leaf + in + aux tree 0 ; + leaves + + let print_tree tree = + let rec aux tree layer index = + match tree with + | Leaf h -> + Printf.printf + "\n leaf layer %d - index %d: %s" + layer + index + (S.to_string h) + | Node (h, t1, t2) -> + Printf.printf + "\n node layer %d - index %d: %s" + layer + index + (S.to_string h) ; + aux t1 (layer + 1) (2 * index) ; + aux t2 (layer + 1) ((2 * index) + 1) + in + aux tree 0 0 + + type leaf = H.P.scalar + + type path = (H.P.scalar * bool) list + + (* pos is an integer which represents leaves increasingly from right to left *) + let proof_path pos tree : leaf * path = + let rec to_bin acc x index = + if index = 0 then acc + else + match x mod 2 with + | 0 -> to_bin (0 :: acc) (x / 2) (index - 1) + | 1 -> to_bin (1 :: acc) ((x - 1) / 2) (index - 1) + | _ -> assert false + in + let size = get_depth tree in + let binary = to_bin [] pos size in + let rec aux path bin = function + | Leaf leaf -> (leaf, path) + | Node (_, t1, t2) -> + if List.hd bin = 0 then + aux ((root t2, left) :: path) (List.tl bin) t1 + else aux ((root t1, right) :: path) (List.tl bin) t2 + in + aux [] binary tree + + let update_tree ?input_length tree pos leaf = + let depth = get_depth tree in + let size = Z.(to_int (pow (of_int 2) depth)) in + assert (pos < size) ; + let _, path = proof_path pos tree in + let _, updated_path = + List.fold_left + (fun (index, acc_list) (x, b) -> + if index = -1 then (1, [leaf]) + else + let acc = List.hd acc_list in + let left, right = if b then (acc, x) else (x, acc) in + let node = H.P.direct ?input_length [|left; right|] in + (index + 1, node :: acc_list)) + (-1, []) + ((leaf, false) :: path) + in + let rec update_tree_with_path tree path updated_path = + match tree with + | Leaf _h -> Leaf leaf + | Node (_h, t1, t2) -> + let node = List.hd path in + let updated_node = List.hd updated_path in + + let t, t_bar = if snd node = left then (t1, t2) else (t2, t1) in + let updated_branch = + update_tree_with_path t (List.tl path) (List.tl updated_path) + in + let t1, t2 = + if snd node = left then (updated_branch, t_bar) + else (t_bar, updated_branch) + in + Node (updated_node, t1, t2) + in + update_tree_with_path tree (List.rev path) updated_path + end + + module type MERKLE = functor (L : LIB) -> sig + open L + open Encoding.Encodings(L) + + type path + + type leaf = scalar + + type root = scalar + + val path_encoding : (P.path, path, (scalar * bool) list) encoding + + val merkle_proof : path -> leaf repr -> root repr -> bool repr t + end + + module V : MERKLE = + functor + (L : LIB) + -> + struct + open L + module Hash = H.V (L) + + type path = (scalar * bool) list repr + + type leaf = scalar + + type root = scalar + + let path_encoding = + let open Encoding.Encodings (L) in + atomic_list_encoding + (atomic_obj2_encoding scalar_encoding bool_encoding) + + let merkle_proof : path -> leaf repr -> root repr -> bool repr t = + fun path leaf expected_root -> + with_label ~label:"Merkle.merkle_proof" + @@ let* root = + foldM + (fun computed_h step -> + let w, direction = of_pair step in + let* leftright = Bool.swap direction w computed_h in + let l, r = of_pair leftright in + Hash.digest ~input_length:2 (to_list [l; r])) + leaf + (of_list path) + in + equal root expected_root + end +end diff --git a/src/lib_plompiler/gadget_merkle_narity.ml b/src/lib_plompiler/gadget_merkle_narity.ml new file mode 100644 index 000000000000..50bd3b805fcc --- /dev/null +++ b/src/lib_plompiler/gadget_merkle_narity.ml @@ -0,0 +1,135 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Lang_stdlib +open Lang_core + +module type HASH = Hash_sig.HASH + +module type MERKLE_NARITY = functor (H : HASH) (L : LIB) -> sig + open L + + type direction = scalar + + type proof = (scalar * (scalar list * direction) list) repr + + type root = scalar repr + + val merkle_proof : int -> proof -> root -> bool repr t +end + +module P (Mec : Hash_sig.P_HASH) = struct + type tree = Leaf of S.t | Branch of S.t * tree list + + let root = function Leaf h -> h | Branch (h, _) -> h + + let rec generate_tree n depth = + if depth = 0 then Leaf (S.random ()) + else + let children = List.init n (fun _ -> generate_tree n (depth - 1)) in + let root = Mec.direct (Array.of_list (List.map root children)) in + Branch (root, children) + + (* This function assumes that the length of pos and the depth of tree coincide. + Furthermore, that pos is a list of integers between 0 and n-1, where n is + the arity of the tree (which is consistent in arity). + *) + let proof_path_narity pos tree = + let rec aux path pos = function + | Leaf h -> (path, h) + | Branch (_, children) -> + let direction = List.hd pos in + let t = List.nth children direction in + let level_witnesses = + List.filteri (fun j _ -> direction <> j) children |> List.map root + in + aux + ((level_witnesses, S.of_z (Z.of_int direction)) :: path) + (List.tl pos) + t + in + aux [] pos tree +end + +module V : MERKLE_NARITY = +functor + (H : HASH) + (L : LIB) + -> + struct + open L + + open H (L) + + type direction = scalar + + (* leaf, path *) + type proof = (scalar * (scalar list * direction) list) repr + + type root = scalar repr + + let merkle_proof : int -> proof -> root -> bool repr t = + fun n witness expected_root -> + with_label ~label:"MerkleNArity.merkle_proof" + @@ + let module E = Enum (struct + let n = n + end) in + let leaf, path = of_pair witness in + let* root = + foldM + (fun computed_h step -> + let level_witnesses, direction = of_pair step in + let level_witnesses = of_list level_witnesses in + let* hash_inputs = + foldiM + (fun hash_inputs i -> + let hash_inputs = of_list hash_inputs in + let cand_i = + if i > 0 then List.nth level_witnesses (i - 1) + else computed_h + in + let cand_i' = + if i < n - 1 then List.nth level_witnesses i else computed_h + in + let candidates = + to_list + @@ List.init n (fun j -> + if j < i then cand_i + else if j = i then computed_h + else cand_i') + in + let* input_i = E.switch_case direction candidates in + let hash_inputs = to_list (input_i :: hash_inputs) in + ret hash_inputs) + (to_list []) + n + in + digest (to_list @@ List.rev (of_list hash_inputs))) + leaf + (of_list path) + in + equal root expected_root + end diff --git a/src/lib_plompiler/gadget_poseidon.ml b/src/lib_plompiler/gadget_poseidon.ml new file mode 100644 index 000000000000..abbd9ea2cd2d --- /dev/null +++ b/src/lib_plompiler/gadget_poseidon.ml @@ -0,0 +1,423 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Lang_core +open Lang_stdlib + +module type PARAMETERS = sig + val variant : Variants.t + + val width : int + + val nb_full_rounds : int + + val nb_partial_rounds : int + + val nb_skips : int + + val mds_matrix : string array array + + val round_constants : string array + + val partial_round_idx_to_permute : int +end + +module Make (PP : PARAMETERS) (L : LIB) = struct + open PP + open L + module Poly = Polynomial.MakeUnivariate (S) + + type poly = Poly.t + + (* Map between scalar variables and an identifier used as degree in their + polynomial representation. Identifiers are guarateed to be unique. *) + module Map : sig + val init : unit -> unit + + val degree_of_wire : scalar repr -> int + + val wire_of_degree : int -> scalar repr + end = struct + let assoc : ((scalar repr * int) list * int) ref = ref ([], 1) + + let init () = assoc := ([], 1) + + let degree_of_wire w = + List.find_opt (fun (w', _d) -> eq w w') (fst !assoc) |> function + | Some (_, d) -> d + | None -> + let l, d = !assoc in + let l = (w, d) :: l in + assoc := (l, d + 1) ; + d + + let wire_of_degree d = + List.find_opt (fun (_w, d') -> d = d') (fst !assoc) |> function + | Some (w, _) -> w + | None -> assert false + end + + type polys = poly array + + let initial_state = Array.init width (fun _ -> Poly.zero) + + let print_state state = + Array.iter (fun p -> Format.printf "%s\n" (Poly.to_string p)) state ; + Format.printf "\n" + + let mds_matrix = mds_matrix |> Array.map (Array.map S.of_string) + + let round_constants = round_constants |> Array.map S.of_string + + (* Linear composition trick: + + - Core idea: The composition of two linear functions is a linear function. + + - Application to Poseidon: + Partial rounds are linear functions for (width-1) elements of the state. + We can compose two or more partial rounds (configured with [nb_skips]) + before calculating (creating wires for) the actual value of the + elements that are linearly afected. + + - Execution: + We store pending linear computations as polynomials, whose monomials + represent the wires that need to be linearly combined. + + The i-th wire is represented by monomial x^{i+1}. + The independent term x^{0} is reserved for the constant ~qc if any. *) + + (* A polynomial represents a linear combination of wires (and a constant). + The i-th wire is associated to monomial x^{i+1} so that wire 0 is not in + conflict with the constant (which is stored in the independent term) *) + let poly_of_wire w = Poly.of_coefficients [(S.one, Map.degree_of_wire w)] + + let wire_of_poly p = + with_label ~label:"Poseidon.wire_of_poly" + @@ + let coeffs = Poly.get_list_coefficients p |> List.rev in + let qc, ws = + match coeffs with (qc, 0) :: l -> (qc, l) | l -> (S.zero, l) + in + let combined_lists = + List.map (fun (q, d) -> (q, Map.wire_of_degree d)) ws + in + let coeffs, xs = List.split combined_lists in + Num.add_list ~qc ~coeffs (to_list xs) + + let s_box p : poly t = + with_label ~label:"Poseidon.s_box" + @@ + if Poly.is_constant p then ret Poly.(p * p * p * p * p) + else + let open Num in + let* x = wire_of_poly p in + let* x5 = pow5 x in + ret @@ poly_of_wire x5 + + let rec repeat : n:int -> ('a -> 'a t) -> 'a -> 'a t = + fun ~n f e -> + if n <= 0 then ret e + else + let* x = f e in + repeat ~n:(n - 1) f x + + let state_map : polys -> (poly -> poly t) -> polys t = + fun state f -> + with_label ~label:"Poseidon.state_map" + @@ + let rec aux : polys -> int -> polys t = + fun state j -> + if j = width then ret state + else + let* p = f state.(j) in + state.(j) <- p ; + aux state (j + 1) + in + aux state 0 + + (* Simplify the state into single-monomial polynomials by evaluating + pending the linear combination that they store *) + let checkpoint : polys -> polys t = + fun state -> + with_label ~label:"Poseidon.checkpoint" + @@ + let f p = + if Poly.is_constant p then ret p + else + let* w = wire_of_poly p in + ret @@ poly_of_wire w + in + state_map state f + + let apply_matrix state = + let x = Array.copy state in + for j = 0 to width - 1 do + state.(j) <- Poly.zero ; + for i = 0 to width - 1 do + state.(j) <- Poly.(state.(j) + mult_by_scalar mds_matrix.(j).(i) x.(i)) + done + done ; + state + + let apply_round_key (state, i_round_key) = + for i = 0 to width - 1 do + state.(i) <- + Poly.add state.(i) (Poly.constants @@ round_constants.(i_round_key + i)) + done ; + (state, i_round_key + width) + + let full_round : ?skip_ark:bool -> polys * int -> (polys * int) t = + fun ?(skip_ark = false) (state, i_round_key) -> + with_label ~label:"Poseidon.full_round" + @@ let* state = state_map state s_box in + let state = apply_matrix state in + if skip_ark then ret (state, i_round_key) + else ret @@ apply_round_key (state, i_round_key) + + let full_round128 : ?skip_ark:bool -> polys * int -> (polys * int) t = + fun ?(skip_ark = false) (state, i_round_key) -> + assert (width = 3) ; + with_label ~label:"Poseidon.full_round128" + @@ let* state = checkpoint state in + let* x0 = wire_of_poly state.(0) in + let* x1 = wire_of_poly state.(1) in + let* x2 = wire_of_poly state.(2) in + let k = [|S.zero; S.zero; S.zero|] in + if not skip_ark then + for i = 0 to width - 1 do + k.(i) <- round_constants.(i_round_key + i) + done ; + let* output = + Poseidon.poseidon128_full_round + ~matrix:mds_matrix + ~k + ~variant + (x0, x1, x2) + in + (match of_list output with + | [y0; y1; y2] -> + state.(0) <- poly_of_wire y0 ; + state.(1) <- poly_of_wire y1 ; + state.(2) <- poly_of_wire y2 + | _ -> assert false) ; + ret @@ (state, i_round_key + width) + + let partial_round : batch:int -> polys * int -> (polys * int) t = + fun ~batch (state, i_round_key) -> + with_label ~label:"Poseidon.partial_round" + @@ + let f (state, i_round_key) = + let* p = s_box state.(partial_round_idx_to_permute) in + state.(partial_round_idx_to_permute) <- p ; + let state = apply_matrix state in + ret @@ apply_round_key (state, i_round_key) + in + let* state, i_round_key = repeat ~n:batch f (state, i_round_key) in + let* state = checkpoint state in + ret (state, i_round_key) + + let partial_round128 : batch:int -> polys * int -> (polys * int) t = + fun ~batch (state, i_round_key) -> + assert (width = 3) ; + assert (batch = 4) ; + with_label ~label:"Poseidon.partial_round128" + @@ let* state = checkpoint state in + let* x0 = wire_of_poly state.(0) in + let* x1 = wire_of_poly state.(1) in + let* x2 = wire_of_poly state.(2) in + let ks = Array.make_matrix width batch S.zero in + for j = 0 to batch - 1 do + for i = 0 to width - 1 do + ks.(i).(j) <- round_constants.(i_round_key + (width * j) + i) + done + done ; + let* output = + Poseidon.poseidon128_four_partial_rounds + ~matrix:mds_matrix + ~ks + ~variant + (x0, x1, x2) + in + (match of_list output with + | [y0; y1; y2] -> + state.(0) <- poly_of_wire y0 ; + state.(1) <- poly_of_wire y1 ; + state.(2) <- poly_of_wire y2 + | _ -> assert false) ; + ret @@ (state, i_round_key + (batch * width)) + + let apply_permutation (state, _) = + with_label ~label:"Poseidon.apply_permutation" + @@ + let batch = nb_skips + 1 in + + let full = if width = 3 then full_round128 else full_round in + let partial = + if width = 3 && batch = 4 then partial_round128 else partial_round + in + + let state, i_round_key = apply_round_key (state, 0) in + let* state = repeat ~n:(nb_full_rounds / 2) full (state, i_round_key) in + let* state = repeat ~n:(nb_partial_rounds / batch) (partial ~batch) state in + let* state = partial_round ~batch:(nb_partial_rounds mod batch) state in + let* state = repeat ~n:((nb_full_rounds / 2) - 1) full state in + full ~skip_ark:true state + + let prepare_block with_padding (state, blocks_read) r nb_chunks inputs = + let block_size = + if blocks_read < nb_chunks - 1 then width - 1 + else if with_padding then r + else Array.length inputs - (blocks_read * (width - 1)) + in + let offset = blocks_read * (width - 1) in + + for j = 0 to block_size - 1 do + let p = Poly.add state.(j + 1) @@ poly_of_wire inputs.(offset + j) in + state.(j + 1) <- p + done ; + if blocks_read = nb_chunks - 1 && with_padding then + state.(r + 1) <- Poly.add state.(r + 1) Poly.one ; + (state, blocks_read + 1) + + let digest : ?input_length:int -> scalar list repr -> scalar repr t = + fun ?input_length inputs -> + Map.init () ; + let inputs = Array.of_list @@ of_list inputs in + let l = Array.length inputs in + let assert_length expected = + let error_msg = + Format.sprintf "digest expects data of length %d, %d given" expected l + in + if l <> expected then raise @@ Invalid_argument error_msg + in + Option.iter assert_length input_length ; + let with_padding = Option.is_none input_length in + + let polys = Array.init width (fun _ -> Poly.zero) in + + let nb_blocks = ((l - if with_padding then 0 else 1) / (width - 1)) + 1 in + let r = l mod (width - 1) in + with_label ~label:"Poseidon.digest" + @@ + let block_iteration (state, blocks_read, i_round_key) = + let state, blocks_read = + prepare_block with_padding (state, blocks_read) r nb_blocks inputs + in + let* state, i_round_key = apply_permutation (state, i_round_key) in + ret (state, blocks_read, i_round_key) + in + let* state, _, _ = repeat ~n:nb_blocks block_iteration (polys, 0, 0) in + wire_of_poly state.(1) +end + +module Poseidon128 = struct + module P : Hash_sig.P_HASH = struct + module H = Mec.Hash.Poseidon128.Make (S) + include H.Hash + + let direct ?input_length inputs = + let ctx = init ?input_length () in + let ctx = digest ctx inputs in + get ctx + end + + module V : Hash_sig.HASH = Make (struct + let variant = Variants.P128 + + let width = 3 + + let nb_full_rounds = 8 + + let nb_partial_rounds = 56 + + let nb_skips = 3 + + let mds_matrix = Mds_128.v + + let round_constants = Ark_128.v + + let partial_round_idx_to_permute = 2 + end) +end + +module Poseidon252 = struct + module P : Hash_sig.P_HASH = struct + module H = Mec.Hash.Poseidon252.Make (S) + include H.Hash + + let direct ?input_length inputs = + let ctx = init ?input_length () in + let ctx = digest ctx inputs in + get ctx + end + + module V : Hash_sig.HASH = Make (struct + let variant = Variants.P252 + + let width = 5 + + let nb_full_rounds = 8 + + let nb_partial_rounds = 59 + + let nb_skips = 4 + + let mds_matrix = Mds_252.v + + let round_constants = Ark_252.v + + let partial_round_idx_to_permute = 4 + end) +end + +module PoseidonFull = struct + module P : Hash_sig.P_HASH = struct + module H = Mec.Hash.Neptunus.Make (S) + include H.Hash + + let direct ?input_length inputs = + let ctx = init ?input_length () in + let ctx = digest ctx inputs in + get ctx + end + + module V : Hash_sig.HASH = Make (struct + let variant = Variants.PFull128 + + let width = 3 + + let nb_full_rounds = 60 + + let nb_partial_rounds = 0 + + let nb_skips = 0 + + let mds_matrix = Mds_full.v + + let round_constants = Ark_full.v + + let partial_round_idx_to_permute = 0 + end) +end diff --git a/src/lib_plompiler/gadget_schnorr.ml b/src/lib_plompiler/gadget_schnorr.ml new file mode 100644 index 000000000000..52f0e6aa75bc --- /dev/null +++ b/src/lib_plompiler/gadget_schnorr.ml @@ -0,0 +1,291 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Curve = Mec.Curve.Jubjub.AffineEdwards + +module Make (H : sig + module P : Hash_sig.P_HASH + + module V : Hash_sig.HASH +end) = +struct + open Lang_core + + (* vanilla implementation of Schnorr signature using ec-jubjub + * general idea based on + * https://github.com/dusk-network/schnorr/blob/main/src/key_variants/single_key.rs *) + module P : sig + val g : Curve.t + + type pk = Curve.t + + type signature = { + sig_u_bytes : bool list; + sig_r : Curve.t; + c_bytes : bool list; + } + + type sk = Curve.Scalar.t + + val neuterize : sk -> pk + + val sign : ?compressed:bool -> sk -> S.t -> Curve.Scalar.t -> signature + + val verify : + ?compressed:bool -> + msg:S.t -> + pk:pk -> + signature:signature -> + unit -> + bool + end = struct + module H = H.P + + (* S.t and Curve.t are the same but Curve.t is abstract *) + let of_bls_scalar s = S.of_z (Curve.Base.to_z s) + + let g = + Curve.from_coordinates_exn + ~u: + (Curve.Base.of_string + "0x3fd2814c43ac65a6f1fbf02d0fd6cce62e3ebb21fd6c54ed4df7b7ffec7beaca") + ~v:(Curve.Base.of_string "0x12") + + type sk = Curve.Scalar.t + + type pk = Curve.t + + type signature = { + sig_u_bytes : bool list; + sig_r : Curve.t; + c_bytes : bool list; + } + + let neuterize sk = Curve.mul g sk + + let bls_scalar_to_curve_scalar s = Curve.Scalar.of_z (S.to_z s) + + let hash_full a = + let ctx = H.init () in + let ctx = H.digest ctx a in + H.get ctx + + let sign ?(compressed = false) sk msg rand = + let r = Curve.mul g rand in + let r_u = Curve.get_u_coordinate r |> of_bls_scalar in + let r_v = Curve.get_v_coordinate r |> of_bls_scalar in + let c = + if compressed then H.direct ~input_length:2 [|r_u; msg|] + else hash_full [|r_u; r_v; msg|] + in + + let u = + Curve.Scalar.sub + rand + (Curve.Scalar.mul (bls_scalar_to_curve_scalar c) sk) + in + let nb_bits_base = Z.numbits S.order in + let sig_u_bytes = + Utils.bool_list_of_z ~nb_bits:nb_bits_base (Curve.Scalar.to_z u) + in + let c_bytes = Utils.bool_list_of_z ~nb_bits:nb_bits_base (S.to_z c) in + {sig_u_bytes; sig_r = r; c_bytes} + + let verify ?(compressed = false) ~msg ~pk ~signature () = + let sig_u = + Curve.Scalar.of_z @@ Utils.bool_list_to_z signature.sig_u_bytes + in + let sig_c = Utils.bool_list_to_scalar signature.c_bytes in + let sig_r_u = Curve.get_u_coordinate signature.sig_r |> of_bls_scalar in + let sig_r_v = Curve.get_v_coordinate signature.sig_r |> of_bls_scalar in + let c = + if compressed then H.direct ~input_length:2 [|sig_r_u; msg|] + else hash_full [|sig_r_u; sig_r_v; msg|] + in + let c_check = S.eq c sig_c in + let challenge_r = + Curve.add + (Curve.mul g sig_u) + (Curve.mul + pk + (Curve.Scalar.of_z @@ Utils.bool_list_to_z signature.c_bytes)) + in + c_check && signature.sig_r = challenge_r + end + + open Lang_stdlib + open Gadget_edwards + + module V : functor (L : LIB) -> sig + open L + open Jubjub(L) + open Encoding.Encodings(L) + + (* TODO make abstract once compression is done with encodings *) + type pk = point + + val pk_encoding : (P.pk, pk repr, pk) encoding + + type signature = { + sig_u_bytes : bool list repr; + sig_r : point repr; + c_bytes : bool list repr; + } + + val signature_encoding : + (P.signature, signature, bool list * (pk * bool list)) encoding + + val g : Curve.t + + val verify : + ?compressed:bool -> + g:point repr -> + msg:scalar repr -> + pk:pk repr -> + signature:signature -> + unit -> + bool repr t + end = + functor + (L : LIB) + -> + struct + open L + + open Jubjub (L) + + open H.V (L) + + type pk = point + + open Encoding.Encodings (L) + + let point_encoding : (Curve.t, pk repr, pk) encoding = + let curve_base_to_s c = Lang_core.S.of_z @@ Curve.Base.to_z c in + let curve_base_of_s c = Curve.Base.of_z @@ Lang_core.S.to_z c in + with_implicit_bool_check is_on_curve + @@ conv + (fun r -> of_pair r) + (fun (u, v) -> pair u v) + (fun c -> + ( curve_base_to_s @@ Curve.get_u_coordinate c, + curve_base_to_s @@ Curve.get_v_coordinate c )) + (fun (u, v) -> + Curve.from_coordinates_exn + ~u:(curve_base_of_s u) + ~v:(curve_base_of_s v)) + (obj2_encoding scalar_encoding scalar_encoding) + + let pk_encoding = point_encoding + + type signature = { + sig_u_bytes : bool list repr; + sig_r : point repr; + c_bytes : bool list repr; + } + + let signature_encoding = + conv + (fun {sig_u_bytes; sig_r; c_bytes} -> (sig_u_bytes, (sig_r, c_bytes))) + (fun (sig_u_bytes, (sig_r, c_bytes)) -> {sig_u_bytes; sig_r; c_bytes}) + (fun ({sig_u_bytes; sig_r; c_bytes} : P.signature) -> + (sig_u_bytes, (sig_r, c_bytes))) + (fun (sig_u_bytes, (sig_r, c_bytes)) -> {sig_u_bytes; sig_r; c_bytes}) + (obj3_encoding + (atomic_list_encoding bool_encoding) + point_encoding + (atomic_list_encoding bool_encoding)) + + let g = P.g + + (* In the compressed variant, we drop sig_r_v of the challenge input as it + can be represented with a single bit: its parity (because of Edwards curves + are symmetric). We do so as we want to use a hash function with a fixed + input length of 2 to minimize the number of constraints. We can still prove + the security of this scheme using the Forking lemma and forking thrice. + + If we really want to include sig_r_v in the challenge input, we could use + its parity bit instead of the whole scalar and compress it with the message + if it is either small or the output of a hash. This however is expensive as + we have to check the decomposition of sig_r_v with the parity bit. + + Netherless, if the msg input actually is the output of the hash, + (msg = H(msg')) of a single scalar, we could fit sig_r_v in this inner hash + while keeping the full security: + c = H( g**r; msg) = H(g**r; H(msg')) + = H( r_u, r_v, H(msg')) + ~ H( r_u, H(msg', r_v)) (equivalent in term of security) + Doing this would not lead to an additional compression round in the hash, + and as such the resulting overhead would be minimal (one constraint for + Poseidon128). + + Assuming that max_account = max_counter = 2**32 (< 10**10) in the Transfer + circuit (privacy-team/plompiler/test/benchmark.ml), and max_amount = + max_fee = 2**64 (< 10**20), the signature message can be compressed in one + scalar: + msg = H(msg') = H(src || dst || fee || amount || counter) + len(msg') = 192 < BLS12-381.Fr order ~ 2**255 + As such, we could use the above scheme to compute the challenge: + c = H(r_u, H(src || dst || fee || amount || counter, r_v)) *) + + let hash ~compressed sig_r msg = + with_label ~label:"Schnorr.hash" + @@ + let sig_r_u = get_u_coordinate sig_r in + if compressed then digest ~input_length:2 @@ to_list [sig_r_u; msg] + else + let sig_r_v = get_v_coordinate sig_r in + digest @@ to_list [sig_r_u; sig_r_v; msg] + + (* Requires : [c_bytes] is computed correctly by the prover. + Otherwise an assert is triggered. *) + (* TODO: now msg is just one scalar, it will probably be a list of scalars *) + let verify ?(compressed = false) ~g ~msg ~pk ~signature () = + with_label ~label:"Schnorr.verify" + @@ + (* assert bytes' length *) + let {sig_u_bytes; sig_r; c_bytes} = signature in + assert ( + List.compare_length_with (of_list sig_u_bytes) (Z.numbits base_order) + = 0) ; + assert ( + List.compare_length_with (of_list c_bytes) (Z.numbits base_order) = 0) ; + + (* generating challenge *) + let* c = hash ~compressed sig_r msg in + (* check challenge binary decomposition : of_bytes c_bytes = c *) + let* c' = Num.scalar_of_bytes c_bytes in + let* e = equal c' c in + (* re-computing randomness challenge_r = u * G_E + c * pk *) + let* challenge_r = + let scalars = to_list [sig_u_bytes; c_bytes] in + let points = to_list [g; pk] in + multi_scalar_mul scalars points + in + (* check signature randomness sig_r equals challenge_r *) + let* b = equal sig_r challenge_r in + Bool.band e b + end +end diff --git a/src/lib_plompiler/gadget_weierstrass.ml b/src/lib_plompiler/gadget_weierstrass.ml new file mode 100644 index 000000000000..67f9844af238 --- /dev/null +++ b/src/lib_plompiler/gadget_weierstrass.ml @@ -0,0 +1,198 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Lang_core +open Lang_stdlib + +module type CURVE_PARAMETERS = sig + val a : S.t + + val b : S.t + + val scalar_order : Z.t + + val base_order : Z.t +end + +let zero = S.zero + +let one = S.one + +let two = S.add one one + +let three = S.add two one + +let mone = S.negate one + +let mtwo = S.negate two + +module type AFFINE = functor (L : LIB) -> sig + open L + + type point = scalar * scalar + + val input_point : ?kind:input_kind -> S.t * S.t -> point repr t + + val assert_is_on_curve : point repr -> unit repr t + + val from_coordinates : scalar repr -> scalar repr -> point repr t + + (** [unsafe_from_coordinates x y] is similar to !{from_coordinates} but + does not verify the point is on the curve. It can be used to build a + variable of type *point* without adding any constraint. + *) + val unsafe_from_coordinates : scalar repr -> scalar repr -> point repr t + + val get_x_coordinate : point repr -> scalar repr + + val get_y_coordinate : point repr -> scalar repr + + val add : point repr -> point repr -> point repr t + + val double : point repr -> point repr t + + val scalar_mul : bool list repr -> point repr -> bool repr -> point repr t + + val scalar_order : Z.t + + val base_order : Z.t +end + +module MakeAffine (Params : CURVE_PARAMETERS) : AFFINE = +functor + (L : LIB) + -> + struct + include Params + open L + + type point = scalar * scalar + + let input_point ?(kind = `Private) (x, y) = + Input.(pair (scalar x) (scalar y)) |> input ~kind + + let get_x_coordinate p = of_pair p |> fst + + let get_y_coordinate p = of_pair p |> snd + + (* 2 constraints *) + let assert_is_on_curve p = + with_label ~label:"Weierstrass.assert_is_on_curve" + @@ + let x, y = of_pair p in + let* x2 = Num.square x in + let* y2 = Num.square y in + + (* - y^2 + x^3 + a * x + b = 0 + <=> | 1 * x * x^2 + a * x + b - 1 * tmp = 0 + | | | | | + | qm ql qc qo + | -1 * y^2 + 1 * tmp = 0 + | | + ql qr + *) + let ql = Params.a in + let qc = Params.b in + let* tmp = Num.custom ~qm:one ~ql ~qc x x2 in + Num.assert_custom ~ql:mone ~qr:one y2 tmp tmp + + let from_coordinates x y = + with_label ~label:"Weierstrass.from_coordinates" + @@ + let p = pair x y in + assert_is_on_curve p >* ret p + + let unsafe_from_coordinates x y = + with_label ~label:"Weierstrass.unsafe_from_coordinates" (pair x y |> ret) + + (* 2 constraints *) + let add p1 p2 = Ecc.weierstrass_add p1 p2 + + (* 2 * P1:(x1, y1) = P3:(x2, y2) (!= P1:(x1, y1) + P1:(x1, y1) which fails as the addition is not complete) + x2 = [(3 * x1^2 + a) / (2 * y1)]^2 - 2 * x1 + y2 = [(3 * x1^2 + a) / (2 * y1)] * (x1 - x2) - y1 + 9 constraints + *) + let double p = + with_label ~label:"Weierstrass.double" + @@ + let x, y = of_pair p in + (* lambda = (3 * x^2 + a) / (2 * y) *) + let* num_lambda = Num.custom ~qm:three x x ~qc:Params.a in + let* lambda = Num.div ~den_coeff:two num_lambda y in + (* x_r = lambda^2 - 2 * x *) + let* lambda_square = Num.square lambda in + let* x_r = Num.add lambda_square ~qr:mtwo x in + (* y_r = lambda * (x - x_r) - y *) + let* x_minus_xr = Num.add ~qr:mone x x_r in + let* left = Num.mul lambda x_minus_xr in + let* y_r = Num.add ~qr:mone left y in + pair x_r y_r |> ret + + (* We need to check that the variable "flag" is set to false, to do so we can: + - make the variable "flag" public + - assert that the variable "flag" is false. + This needs to be done once for all scalar multiplications. + List.length(of_list s) * (9 + 2 + 7 + 7 + 1) constraints + *) + let scalar_mul s p flag = + with_label ~label:"Weierstrass.scalar_mul" + @@ + let init = pair p flag in + let* res = + foldM + (fun acc b -> + let acc_res, acc_flag = of_pair acc in + let* acc_res = double acc_res in + let* sum = add acc_res p in + let* ite = Bool.ifthenelse acc_flag sum p in + let* acc_res = Bool.ifthenelse b ite acc_res in + let* acc_flag = Bool.bor acc_flag b in + let acc = pair acc_res acc_flag in + ret acc) + init + (List.rev (of_list s)) + in + let result, _ = of_pair res in + ret result + end + +module Jubjub = MakeAffine (struct + let a = + S.of_string + "52296097456646850916096512823759002727550416093741407922227928430486925478210" + + let b = + S.of_string + "48351165704696163914533707656614864561753505123260775585269522553028192119009" + + let scalar_order = + Z.of_string + "6554484396890773809930967563523245729705921265872317281365359162392183254199" + + let base_order = + Z.of_string + "52435875175126190479447740508185965837690552500527637822603658699938581184513" +end) diff --git a/src/lib_plompiler/hash_sig.ml b/src/lib_plompiler/hash_sig.ml new file mode 100644 index 000000000000..9fabfdd28c4d --- /dev/null +++ b/src/lib_plompiler/hash_sig.ml @@ -0,0 +1,47 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Lang_core +open Lang_stdlib + +module type P_HASH = sig + type scalar = S.t + + type ctxt + + val init : ?input_length:int -> unit -> ctxt + + val digest : ctxt -> scalar array -> ctxt + + val get : ctxt -> scalar + + val direct : ?input_length:int -> scalar array -> scalar +end + +module type HASH = functor (L : LIB) -> sig + open L + + val digest : ?input_length:int -> scalar list repr -> scalar repr t +end diff --git a/src/lib_plompiler/lang_core.ml b/src/lib_plompiler/lang_core.ml new file mode 100644 index 000000000000..5ea5798ece30 --- /dev/null +++ b/src/lib_plompiler/lang_core.ml @@ -0,0 +1,277 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module S = Csir.Scalar + +module type NUM = sig + type scalar + + type 'a repr + + type 'a t + + val custom : + ?qc:S.t -> + ?ql:S.t -> + ?qr:S.t -> + ?qo:S.t -> + ?qm:S.t -> + ?qx2b:S.t -> + ?qx5a:S.t -> + scalar repr -> + scalar repr -> + scalar repr t + + val assert_custom : + ?qc:S.t -> + ?ql:S.t -> + ?qr:S.t -> + ?qo:S.t -> + ?qm:S.t -> + scalar repr -> + scalar repr -> + scalar repr -> + unit repr t + + val add : + ?qc:S.t -> ?ql:S.t -> ?qr:S.t -> scalar repr -> scalar repr -> scalar repr t + + val add_constant : ?ql:S.t -> S.t -> scalar repr -> scalar repr t + + val mul : ?qm:S.t -> scalar repr -> scalar repr -> scalar repr t + + val div : ?den_coeff:S.t -> scalar repr -> scalar repr -> scalar repr t + + val pow5 : scalar repr -> scalar repr t + + val is_zero : scalar repr -> bool repr t + + val is_not_zero : scalar repr -> bool repr t + + val assert_nonzero : scalar repr -> unit repr t + + val assert_bool : scalar repr -> unit repr t +end + +module type BOOL = sig + type scalar + + type 'a repr + + type 'a t + + val band : bool repr -> bool repr -> bool repr t + + val xor : bool repr -> bool repr -> bool repr t + + val bor : bool repr -> bool repr -> bool repr t + + val bor_lookup : bool repr -> bool repr -> bool repr t + + val bnot : bool repr -> bool repr t + + val ifthenelse : bool repr -> 'a repr -> 'a repr -> 'a repr t + + val swap : bool repr -> 'a repr -> 'a repr -> ('a * 'a) repr t + + val assert_true : bool repr -> unit repr t + + val assert_false : bool repr -> unit repr t + + val constant_bool : bool -> bool repr t + + val band_list : bool repr list -> bool repr t +end + +module type COMMON = sig + type scalar + + type input_kind = [`InputCom | `Public | `Private] + + type trace_kind = [input_kind | `NoInput] + + type 'a repr + + type 'a t + + val ret : 'a -> 'a t + + val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t + + val ( >* ) : unit repr t -> 'a t -> 'a t + + (* Add a boolean check *) + val with_bool_check : bool repr t -> unit repr t + + (* Retrieve the boolean representing the conjunction of all previous implicit + checks. + WARNING: This will "reset" the implicit check accumulator. + *) + val get_checks_wire : bool repr t + + module Input : sig + type 'a input + + val scalar : S.t -> scalar input + + val to_scalar : scalar input -> S.t + + val bool : bool -> bool input + + val to_bool : bool input -> bool + + val unit : unit input + + val pair : 'a input -> 'b input -> ('a * 'b) input + + val to_pair : ('a * 'b) input -> 'a input * 'b input + + val list : 'a input list -> 'a list input + + val to_list : 'a list input -> 'a input list + + val with_implicit_bool_check : + ('a repr -> bool repr t) -> 'a input -> 'a input + + val with_assertion : ('a repr -> unit repr t) -> 'a input -> 'a input + + type 'a t = 'a input + end + + type 'b open_input_com + + val serialize : 'a Input.t -> S.t array + + val input : ?kind:input_kind -> 'a Input.t -> 'a repr t + + val new_input_com : unit repr t + + val begin_input_com : 'b -> 'b open_input_com + + val ( |: ) : ('c repr -> 'd) open_input_com -> 'c Input.t -> 'd open_input_com + + val end_input_com : 'a open_input_com -> 'a t + + val eq : 'a repr -> 'a repr -> bool + + val foldM : ('a -> 'b -> 'a t) -> 'a -> 'b list -> 'a t + + val pair : 'a repr -> 'b repr -> ('a * 'b) repr + + val of_pair : ('a * 'b) repr -> 'a repr * 'b repr + + val to_list : 'a repr list -> 'a list repr + + val of_list : 'a list repr -> 'a repr list + + val unit : unit repr + + val scalar_of_bool : bool repr -> scalar repr + + val unsafe_bool_of_scalar : scalar repr -> bool repr + + val assert_equal : 'a repr -> 'a repr -> unit repr t + + val equal : 'a repr -> 'a repr -> bool repr t + + val constant_scalar : S.t -> scalar repr t + + (** Returns a list of Boolean variables representing the little endian + bit decomposition of the given scalar (with the least significant bit + on the head). *) + val bits_of_scalar : + ?shift:Z.t -> nb_bits:int -> scalar repr -> bool list repr t + + val with_label : label:string -> 'a t -> 'a t + + module Num : + NUM + with type scalar = scalar + and type 'a repr = 'a repr + and type 'a t = 'a t + + module Bool : + BOOL + with type scalar = scalar + and type 'a repr = 'a repr + and type 'a t = 'a t + + module Ecc : sig + val weierstrass_add : + (scalar * scalar) repr -> + (scalar * scalar) repr -> + (scalar * scalar) repr t + + val edwards_add : + (scalar * scalar) repr -> + (scalar * scalar) repr -> + (scalar * scalar) repr t + + val edwards_cond_add : + (scalar * scalar) repr -> + (scalar * scalar) repr -> + bool repr -> + (scalar * scalar) repr t + end + + module Poseidon : sig + val poseidon128_full_round : + matrix:S.t array array -> + k:S.t array -> + variant:Variants.t -> + scalar repr * scalar repr * scalar repr -> + scalar list repr t + + val poseidon128_four_partial_rounds : + matrix:S.t array array -> + ks:S.t array array -> + variant:Variants.t -> + scalar repr * scalar repr * scalar repr -> + scalar list repr t + end + + module Anemoi : sig + val anemoi_round : + kx:S.t -> ky:S.t -> scalar repr * scalar repr -> (scalar * scalar) repr t + + val anemoi_double_round : + kx1:S.t -> + ky1:S.t -> + kx2:S.t -> + ky2:S.t -> + scalar repr * scalar repr -> + (scalar * scalar) repr t + + val anemoi_custom : + kx1:S.t -> + ky1:S.t -> + kx2:S.t -> + ky2:S.t -> + scalar repr * scalar repr -> + (scalar * scalar) repr t + end + + val hd : 'a list repr -> 'a repr t +end diff --git a/src/lib_plompiler/lang_stdlib.ml b/src/lib_plompiler/lang_stdlib.ml new file mode 100644 index 000000000000..c608691a0f52 --- /dev/null +++ b/src/lib_plompiler/lang_stdlib.ml @@ -0,0 +1,384 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Lang_core + +module type LIB = sig + include COMMON + + val foldiM : ('a -> int -> 'a t) -> 'a -> int -> 'a t + + val fold2M : ('a -> 'b -> 'c -> 'a t) -> 'a -> 'b list -> 'c list -> 'a t + + val mapM : ('a -> 'b t) -> 'a list -> 'b list t + + val map2M : ('a -> 'b -> 'c t) -> 'a list -> 'b list -> 'c list t + + val iterM : ('a -> unit repr t) -> 'a list -> unit repr t + + val iter2M : ('a -> 'b -> unit repr t) -> 'a list -> 'b list -> unit repr t + + module Bool : sig + include BOOL + + (** Returns the pair (s, c_out), as per + https://en.wikipedia.org/wiki/Adder_(electronics)#Full_adder *) + val full_adder : bool repr -> bool repr -> bool repr -> (bool * bool) repr t + end + with type scalar = scalar + and type 'a repr = 'a repr + and type 'a t = 'a t + + module Num : sig + include NUM + + val square : scalar repr -> scalar repr t + + val pow : scalar repr -> bool repr list -> scalar repr t + + val add_list : + ?qc:S.t -> ?coeffs:S.t list -> scalar list repr -> scalar repr t + + val mul_list : scalar list repr -> scalar repr t + + val mul_by_constant : S.t -> scalar repr -> scalar repr t + + val scalar_of_bytes : bool list repr -> scalar repr t + + val is_eq_const : scalar repr -> S.t -> bool repr t + + val assert_eq_const : scalar repr -> S.t -> unit repr t + + (** [is_upper_bounded ~bound x] returns whether the scalar [x] is + strictly lower than [bound] when [x] is interpreted as an integer + from [0] to [p-1] (being [p] the scalar field order). + This circuit is total (and more expensive than our version below). *) + val is_upper_bounded : bound:Z.t -> scalar repr -> bool repr t + + (** Same as [is_upper_bounded] but cheaper and partial. + [is_upper_bounded_unsafe ~bound l] is unsatisfiable if l cannot be + represented in binary with [Z.numbits bound] bits. *) + val is_upper_bounded_unsafe : + ?nb_bits:int -> bound:Z.t -> scalar repr -> bool repr t + + (** [geq (a, bound_a) (b, bound_b)] returns the boolean wire representing + a >= b. + Pre-condition: a ∈ [0, bound_a) ∧ b ∈ [0, bound_b) *) + val geq : scalar repr * Z.t -> scalar repr * Z.t -> bool repr t + end + with type scalar = scalar + and type 'a repr = 'a repr + and type 'a t = 'a t + + module Enum (N : sig + val n : int + end) : sig + (* [switch_case k l] returns the k-th element of the list [l] if k ∈ [0,n) + or the first element of [l] otherwise. *) + val switch_case : scalar repr -> 'a list repr -> 'a repr t + end + + module Bytes : sig + type bl = bool list + + val add : ?ignore_carry:bool -> bl repr -> bl repr -> bl repr t + + val xor : bl repr -> bl repr -> bl repr t + + val rotate : bl repr -> int -> bl repr + end + + val add2 : + (scalar * scalar) repr -> (scalar * scalar) repr -> (scalar * scalar) repr t + + val constant_bool : bool -> bool repr t + + val constant_bytes : ?le:bool -> bytes -> Bytes.bl repr t + + val constant_uint32 : ?le:bool -> Stdint.uint32 -> Bytes.bl repr t +end + +module Lib (C : COMMON) = struct + include C + + let foldiM : ('a -> int -> 'a t) -> 'a -> int -> 'a t = + fun f e n -> foldM f e (List.init n (fun i -> i)) + + let fold2M f acc ls rs = + foldM (fun acc (l, r) -> f acc l r) acc (List.combine ls rs) + + let mapM f l = + let* l = + foldM + (fun acc e -> + let* e = f e in + ret @@ (e :: acc)) + [] + l + in + ret @@ List.rev l + + let map2M f ls rs = mapM (fun (l, r) -> f l r) (List.combine ls rs) + + let iterM f l = foldM (fun _ a -> f a) unit l + + let iter2M f l r = iterM (fun (l, r) -> f l r) (List.combine l r) + + module Bool = struct + include Bool + + let full_adder a b c_in = + let* a_xor_b = xor a b in + let* a_xor_b_xor_c = xor a_xor_b c_in in + let* a_xor_b_and_c = band a_xor_b c_in in + let* a_and_b = band a b in + let* c = bor a_xor_b_and_c a_and_b in + ret (pair a_xor_b_xor_c c) + end + + module Num = struct + include Num + + let square l = mul l l + + let pow x n_list = + let* init = + let* left = constant_scalar S.one in + ret (left, x) + in + let* res, _acc = + foldM + (fun (res, acc) bool -> + let* res_true = mul res acc in + let* res = Bool.ifthenelse bool res_true res in + let* acc = mul acc acc in + ret (res, acc)) + init + n_list + in + ret res + + let add_list ?(qc = S.zero) ?(coeffs = []) l = + let l = of_list l in + let q = + if coeffs != [] then coeffs + else List.init (List.length l) (fun _ -> S.one) + in + assert (List.compare_lengths q l = 0) ; + match (l, q) with + | x1 :: x2 :: xs, ql :: qr :: qs -> + let* res = Num.add ~qc ~ql ~qr x1 x2 in + fold2M (fun acc x ql -> Num.add ~ql x acc) res xs qs + | [x], [ql] -> Num.add_constant ~ql qc x + | [], [] -> constant_scalar qc + | _, _ -> assert false + + let mul_list l = + match of_list l with [] -> assert false | x :: xs -> foldM Num.mul x xs + + let mul_by_constant s x = Num.add_constant ~ql:s S.zero x + + (* Evaluates P(X) = \sum_i bᵢ Xⁱ at 2 with Horner's method: + P(2) = b₀ + 2 (b₁+ 2 (b₂ + 2(…))). *) + let scalar_of_bytes b = + let* zero = constant_scalar S.zero in + foldM + (fun acc b -> add acc (scalar_of_bool b) ~ql:S.(one + one) ~qr:S.one) + zero + (List.rev (of_list b)) + + let assert_eq_const l s = Num.assert_custom ~ql:S.mone ~qc:s l l l + + let is_eq_const l s = + let* diff = add_constant ~ql:S.mone s l in + is_zero diff + + (* Function used by [is_upper_bounded(_unsafe)] *) + let ignore_leading_zeros ~nb_bits ~bound xbits = + (* We can ignore all leading zeros in the bound's little-endian binary + decomposition. The assertion cannot be satisfied if they are all zeros. *) + let rec shave_zeros = function + | [] -> + raise + (Invalid_argument + "is_upper_bounded cannot be satisfied on bound = 0") + | (x, true) :: tl -> (x, tl) + | (_, false) :: tl -> shave_zeros tl + in + List.combine (of_list xbits) (Utils.bool_list_of_z ~nb_bits bound) + |> shave_zeros + + (* Let [(bn,...,b0)] and [(xn,...,x0)] be binary representations + of [bound] and [x] respectively where the least significant bit is + indexed by [0]. Let [op_i = if b_i = 1 then band else bor] for all [i]. + Predicate [x] < [bound] can be expressed as the negation of predicate: + [ xn op_n (... (x1 op_1 (x0 op_0 true))) ]. + Intuitively we need to carry through a flag that indicates if up to + step i, x is greater than b. In order for x[0,i] to be greater than + b[0,i]: + - if b_i = one then x_i will need to match it and the flag must be true. + - if b_i = zero then x needs to be one if the flag is false or it can + have any value if the flag is already true. *) + let is_upper_bounded_unsafe ?nb_bits ~bound x = + assert (Z.zero <= bound && bound < S.order) ; + let nb_bits = + Option.value + ~default:(if Z.(equal bound zero) then 1 else Z.numbits bound) + nb_bits + in + let* xbits = bits_of_scalar ~nb_bits x in + let init, xibi = ignore_leading_zeros ~nb_bits ~bound xbits in + let* geq = + foldM + (fun acc (xi, bi) -> + let op = if bi then Bool.band else Bool.bor in + op xi acc) + init + xibi + in + Bool.bnot geq + + let is_upper_bounded ~bound x = + assert (Z.zero <= bound && bound < S.order) ; + let nb_bits = Z.numbits S.order in + let bound_plus_alpha = Z.(bound + Utils.alpha) in + let* xbits = bits_of_scalar ~shift:Utils.alpha ~nb_bits x in + let init, xibi = + ignore_leading_zeros ~nb_bits ~bound:bound_plus_alpha xbits + in + let* geq = + foldM + (fun acc (xi, bi) -> + let op = if bi then Bool.band else Bool.bor in + op xi acc) + init + xibi + in + Bool.bnot geq + + let geq (a, bound_a) (b, bound_b) = + (* (a - b) + bound_b - 1 ∈ [0, bound_a + bound_b - 1) *) + let* shifted_diff = + Num.add ~qr:S.mone ~qc:(S.of_z Z.(pred bound_b)) a b + in + let nb_bits = Z.(numbits @@ pred (add bound_a bound_b)) in + let* bits = bits_of_scalar ~nb_bits shifted_diff in + let init, xibi = + ignore_leading_zeros ~nb_bits ~bound:Z.(pred bound_b) bits + in + foldM + (fun acc (xi, bi) -> + let op = if bi then Bool.band else Bool.bor in + op xi acc) + init + xibi + end + + module Enum (N : sig + val n : int + end) = + struct + let switch_case k cases = + let cases = of_list cases in + assert (List.compare_length_with cases N.n = 0) ; + let indexed = List.mapi (fun i x -> (i, x)) cases in + foldM + (fun c (i, ci) -> + let* f = Num.is_eq_const k (S.of_z (Z.of_int i)) in + Bool.ifthenelse f ci c) + (snd @@ List.hd indexed) + (List.tl indexed) + end + + module Bytes = struct + type bl = bool list + + let add ?(ignore_carry = false) a b = + let ha, ta = (List.hd (of_list a), List.tl (of_list a)) in + let hb, tb = (List.hd (of_list b), List.tl (of_list b)) in + let* a_xor_b = Bool.xor ha hb in + let* a_and_b = Bool.band ha hb in + let* res, carry = + fold2M + (fun (res, c) a b -> + let* p = Bool.full_adder a b c in + let s, c = of_pair p in + ret (s :: res, c)) + ([a_xor_b], a_and_b) + ta + tb + in + ret @@ to_list @@ List.rev (if ignore_carry then res else carry :: res) + + let xor a b = + let* l = map2M Bool.xor (of_list a) (of_list b) in + ret @@ to_list l + + let rotate a i = + let split_n n l = + let rec aux acc k l = + if k = n then (List.rev acc, l) + else + match l with + | h :: t -> aux (h :: acc) (k + 1) t + | [] -> + raise + (Invalid_argument + (Printf.sprintf "split_n: n=%d >= List.length l=%d" n k)) + in + aux [] 0 l + in + let head, tail = split_n i (of_list a) in + to_list @@ tail @ head + end + + let add2 p1 p2 = + let x1, y1 = of_pair p1 in + let x2, y2 = of_pair p2 in + let* x3 = Num.add x1 x2 in + let* y3 = Num.add y1 y2 in + ret (pair x3 y3) + + let constant_bool b = + let* bit = constant_scalar (if b then S.one else S.zero) in + ret @@ unsafe_bool_of_scalar bit + + let constant_bytes ?(le = false) b = + let bl = Utils.bitlist ~le b in + let* ws = + foldM + (fun ws bit -> + let* w = constant_bool bit in + ret (w :: ws)) + [] + bl + in + ret @@ to_list @@ List.rev ws + + let constant_uint32 ?(le = false) u32 = + let b = Stdlib.Bytes.create 4 in + Stdint.Uint32.to_bytes_big_endian u32 b 0 ; + constant_bytes ~le b +end diff --git a/src/lib_plompiler/linear_algebra.ml b/src/lib_plompiler/linear_algebra.ml new file mode 100644 index 000000000000..e112eebff0bb --- /dev/null +++ b/src/lib_plompiler/linear_algebra.ml @@ -0,0 +1,203 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module type Ring_sig = sig + type t + + val add : t -> t -> t + + val mul : t -> t -> t + + val negate : t -> t + + val zero : t + + val one : t + + val eq : t -> t -> bool +end + +module type Field_sig = sig + include Ring_sig + + val inverse_exn : t -> t +end + +(** This refers to the mathematical generalization of vector space called + "module", where the field of scalars is replaced by a ring *) +module type Module_sig = sig + type t + + type matrix = t array array + + (** [zeros r c] is a matrix with [r] rows and [c] columns filled with zeros *) + val zeros : int -> int -> matrix + + (** [identity n] is the identity matrix of dimension [n] *) + val identity : int -> matrix + + (** matrix equality *) + val equal : matrix -> matrix -> bool + + (** matrix addition *) + val add : matrix -> matrix -> matrix + + (** matrix multiplication *) + val mul : matrix -> matrix -> matrix + + (** matrix transposition *) + val transpose : matrix -> matrix + + (** [row_add ~coeff i j m] adds to the i-th row, the j-th row times coeff in m *) + val row_add : ?coeff:t -> int -> int -> matrix -> unit + + (** [row_swap i j m] swaps the i-th and j-th rows of m *) + val row_swap : int -> int -> matrix -> unit + + (** [row_mul coeff i m] multiplies the i-th row by coeff in m *) + val row_mul : t -> int -> matrix -> unit + + (** [filter_cols f m] removes the columns of [m] whose index does not satisfy [f] *) + val filter_cols : (int -> bool) -> matrix -> matrix + + (** splits matrix [m] into the first n columns and the rest, producing two matrices *) + val split_n : int -> matrix -> matrix * matrix +end + +module type VectorSpace_sig = sig + include Module_sig + + (** reduced row Echelon form of m *) + val reduced_row_echelon_form : matrix -> matrix + + (** [inverse m] is the inverse matrix of m + + @raise [Invalid_argument] if [m] is not invertible *) + val inverse : matrix -> matrix +end + +module Make_Module (Ring : Ring_sig) : Module_sig with type t = Ring.t = struct + type t = Ring.t + + type matrix = t array array + + let zeros r c = Array.make_matrix r c Ring.zero + + let identity n = + Array.(init n (fun i -> init n Ring.(fun j -> if i = j then one else zero))) + + let equal = Array.(for_all2 (for_all2 Ring.eq)) + + let add = Array.(map2 (map2 Ring.add)) + + let mul m1 m2 = + let nb_rows = Array.length m1 in + let nb_cols = Array.length m2.(0) in + let n = Array.length m1.(0) in + assert (Array.length m2 = n) ; + let p = zeros nb_rows nb_cols in + for i = 0 to nb_rows - 1 do + for j = 0 to nb_cols - 1 do + for k = 0 to n - 1 do + p.(i).(j) <- Ring.(add p.(i).(j) @@ mul m1.(i).(k) m2.(k).(j)) + done + done + done ; + p + + let transpose m = + let nb_rows = Array.length m in + let nb_cols = Array.length m.(0) in + Array.(init nb_cols (fun i -> init nb_rows (fun j -> m.(j).(i)))) + + let row_add ?(coeff = Ring.one) i j m = + m.(i) <- Array.map2 Ring.(fun a b -> add a (mul coeff b)) m.(i) m.(j) + + let row_swap i j m = + let aux = m.(i) in + m.(i) <- m.(j) ; + m.(j) <- aux + + let row_mul coeff i m = m.(i) <- Array.map (Ring.mul coeff) m.(i) + + let filter_cols f = + Array.map (fun row -> + List.filteri (fun i _ -> f i) (Array.to_list row) |> Array.of_list) + + let split_n n m = + (filter_cols (fun i -> i < n) m, filter_cols (fun i -> i >= n) m) +end + +module Make_VectorSpace (Field : Field_sig) : + VectorSpace_sig with type t = Field.t = struct + include Make_Module (Field) + + let reduced_row_echelon_form m = + let n = Array.length m in + (* returns the first non-zero index in the row *) + let find_pivot row = + let rec aux cnt = function + | [] -> None + | x :: xs -> if Field.(eq zero x) then aux (cnt + 1) xs else Some cnt + in + aux 0 (Array.to_list row) + in + let move_zeros_to_bottom m = + let is_non_zero_row = Array.exists (fun a -> not Field.(eq zero a)) in + let rec aux nonzeros zeros = function + | [] -> Array.of_list (List.rev nonzeros @ zeros) + | r :: rs -> + if is_non_zero_row r then aux (r :: nonzeros) zeros rs + else aux nonzeros (r :: zeros) rs + in + aux [] [] (Array.to_list m) + in + let rec aux k = + if k >= Array.length m then m + else + match find_pivot m.(k) with + | Some j when j < n -> + row_mul (Field.inverse_exn m.(k).(j)) k m ; + Array.iteri + (fun i _ -> + if i <> k then row_add ~coeff:Field.(negate @@ m.(i).(j)) i k m) + m ; + row_swap k j m ; + aux (k + 1) + | _ -> aux (k + 1) + in + aux 0 |> move_zeros_to_bottom + + let inverse m = + let n = Array.length m in + let id_n = identity n in + let augmented = Array.(map2 append m id_n) in + let reduced = reduced_row_echelon_form augmented in + let residue, inv = split_n n reduced in + let is_zero_row = Array.for_all Field.(eq zero) in + if Array.exists is_zero_row residue then + raise @@ Invalid_argument "matrix [m] is not invertible" + else inv +end diff --git a/src/lib_plompiler/mds_128.ml b/src/lib_plompiler/mds_128.ml new file mode 100644 index 000000000000..08a3bafc2ced --- /dev/null +++ b/src/lib_plompiler/mds_128.ml @@ -0,0 +1,46 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Generated with the command below from commit cd13dd0e984a4eeadd82e0ac4ce792c275bd3b18 + [sage generate_mds.sage 3 NomadicLabs 52435875175126190479447740508185965837690552500527637822603658699938581184513] *) + +let v = + [| + [| + "48527463322097587091854420767453816291840635874249958396342138881138912067190"; + "11996084473350366483175782359948025962778681837397784970341328014763133439499"; + "5762620760470856886668821516275719951899130793312002468640314451189655462163"; + |]; + [| + "43372445583202124108992832749257195116898314930070456682841601188523728879167"; + "22957843818027924237635625446720638788994914691706001027915412076310000455035"; + "45912682675908730967574769352367944608550602185952960151299062991058447525440"; + |]; + [| + "31497265986585083362120862432803344331731948296021705208949638957481968624918"; + "51685553404028716702307457799190688643603961331524463449216360083627404197200"; + "46564571507606908377998846740442910952080430324196357605862207064906809134438"; + |]; + |] diff --git a/src/lib_plompiler/mds_252.ml b/src/lib_plompiler/mds_252.ml new file mode 100644 index 000000000000..f4a7f5142f32 --- /dev/null +++ b/src/lib_plompiler/mds_252.ml @@ -0,0 +1,65 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Come from https://github.com/dusk-network/Hades252/tree/7a7a255f6cc48f892de5cf8935b5264eb8893852/assets *) + +let v = + [| + [| + "2184067777412762892935100798463195235577775932917057678850053321607193454182"; + "36777306597928096063744411004176639921441848277782639947444150234631715334827"; + "46505084276831565334480278148775967314861742095393016475696031258238207768284"; + "14474011154664524427946373126085988481658748083205070504932198000989141204992"; + "41996829456994127535645520838846415226858083018697639239163986389734003951389"; + |]; + [| + "36777306597928096063744411004176639921441848277782639947444150234631715334827"; + "46505084276831565334480278148775967314861742095393016475696031258238207768284"; + "14474011154664524427946373126085988481658748083205070504932198000989141204992"; + "41996829456994127535645520838846415226858083018697639239163986389734003951389"; + "1092033888706381446467550399231597617788887966458528839425026660803596727091"; + |]; + [| + "46505084276831565334480278148775967314861742095393016475696031258238207768284"; + "14474011154664524427946373126085988481658748083205070504932198000989141204992"; + "41996829456994127535645520838846415226858083018697639239163986389734003951389"; + "1092033888706381446467550399231597617788887966458528839425026660803596727091"; + "20060349053415325125678769638641803593513735424245076334969536491617299273542"; + |]; + [| + "14474011154664524427946373126085988481658748083205070504932198000989141204992"; + "41996829456994127535645520838846415226858083018697639239163986389734003951389"; + "1092033888706381446467550399231597617788887966458528839425026660803596727091"; + "20060349053415325125678769638641803593513735424245076334969536491617299273542"; + "44606590886527143271596075756181302879566200389155138885023904467285148259670"; + |]; + [| + "41996829456994127535645520838846415226858083018697639239163986389734003951389"; + "1092033888706381446467550399231597617788887966458528839425026660803596727091"; + "20060349053415325125678769638641803593513735424245076334969536491617299273542"; + "44606590886527143271596075756181302879566200389155138885023904467285148259670"; + "37141785804861502213823474505076128362854142474564156061360245762114092148579"; + |]; + |] diff --git a/src/lib_plompiler/mds_full.ml b/src/lib_plompiler/mds_full.ml new file mode 100644 index 000000000000..4c04fbdc6021 --- /dev/null +++ b/src/lib_plompiler/mds_full.ml @@ -0,0 +1,45 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Come from https://github.com/zcash-hackworks/zcash-test-vectors/blob/master/orchard_poseidon.py *) + +let v = + [| + [| + "20318286217486369426965035069836800746749435906016448674636714520170817018807"; + "22192852525643738215947851702151544501993043677579072964990735260534263737314"; + "8542598184567193950383006010698963992683774969143163395442055984920670969658"; + |]; + [| + "7392954993144188510255764707695079827771707557363197189129035318593453738368"; + "27549511735195789329533968803664746807330189702821962130064027535490056177413"; + "13129156644346446682975824711515160071389200876395558249729931114712818796177"; + |]; + [| + "21010686366472749505451494418483718181134873748085457288199401256016616439986"; + "28561190888145054647914513058959252600378056095166705432358200159539002856405"; + "21356544248278733708505686717446976476730796312725621196632235950424803603792"; + |]; + |] diff --git a/src/lib_plompiler/optimizer.ml b/src/lib_plompiler/optimizer.ml new file mode 100644 index 000000000000..df102947a5b7 --- /dev/null +++ b/src/lib_plompiler/optimizer.ml @@ -0,0 +1,766 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Csir +open Optimizer_helpers + +(** The optimizer simplifies a constraint system, producing an equivalent one + with fewer constraints in essentially three ways: + + - 1. {!next_gate_selectors} [qlg], [qrg] and/or [qog], which + lead to a more compact representation of sums (linear combinations). + + - 2. {!shared_wires} among different constraints. + + - 3. {!compacting_blocks} which operate on independent wires. + + {1 Optimization Rules} + + {2:next_gate_selectors Introducing next-gate selectors} + + In a system with 3-wires architecture, adding (in a linear combination) [n] + elements requires [n-1] constraints. For example, computing + [out = 1 + 2 x1 + 4 x2 + 8 x3 + 16 x4 + 32 x5] can be implemented in 4 + constraints as follows: + {[ + { a = x1; b = x2; c = aux1; identity = [ql 2; qr 4; qo -1; qc 1] }; + { a = x3; b = x4; c = aux2; identity = [ql 8; qr 16; qo -1] }; + { a = x5; b = aux1; c = aux3; identity = [ql 32; qr 1; qo -1] }; + { a = aux2; b = aux3; c = out; identity = [ql 1; qr 1; qo -1] }; + ]} + Instead, by using next-gate selectors, a linear combination of [n] terms + can be implemented in [(n-1)/2] constraints. In this case, just two: + {[ + { a = x1; b = x2; c = out; identity = [ql 2; qr 4; qlg 8; qrg 16; qog 32; qo -1; qc 1] }; + { a = x3; b = x4; c = x5; identity = [] }; + ]} + + {2:shared_wires Reusing shared-wires} + + Remarkably, two linear combinations that involve some common wires can be + implemented more efficiently if they are handled together. + For example, [out1 = 5 x + 3 y + 9 z] and [out2 = 2 x - 3 y + 7 t] can be + implemented with 3 constraints (instead of 4) as follows: + {[ + { a = z; c = out1; identity = [ql 9; qlg 5; qrg 3; qog -1] }; + { a = x; b = y; c = out2; identity = [ql 2; qr -3; qrg 7; qog -1] }; + { b = t; ; identity = [] }; + ]} + Furthermore, observe how, conveniently, some wires in the above constraints + are unbound, which can lead to our next optimization. + + {2:compacting_blocks Compacting blocks} + + Consider a gate which only takes one wire as input, e.g. for computing + [out3 = 3 w + 1], implemented with constraint: + {[{ a = w; c = out3; identity = [ql 3; qo -1; qc 1] }]} + This constraint can be merged with our previous block, which only uses + wire b in its last constraint and has unbound selectors for it: + {[ + { a = z; c = out1; identity = [ql 9; qlg 5; qrg 3; qog -1] }; + { a = x; b = y; c = out2; identity = [ql 2; qr -3; qrg 7; qog -1] }; + { a = w; b = t; c = out3; identity = [ql 3; qo -1; qc 1] }; + ]} + + {1 Algorithm} + + The optimization proceeds in several steps: + + 1. Collect information about all linear constraints/gates (see {!is_linear}), + including the number of occurrences of their output wire among the circuit. + + 2. Inline any {!type:linear_computation} whose output is used only once + among the circuit, in the computation where it is used (only if the latter + is also linear). + + 3. Transform any non-inlined linear computation into a {!type:pseudo_block} + and join pseudo blocks that share at least a wire (preferably two wires). + + 4. Transform pseudo blocks to actual blocks (also considering the non-linear + computations that were left aside) and join blocks that operate on + independent wires together. *) + +let nb_wires_arch = Csir.nb_wires_arch + +type constr = Csir.CS.raw_constraint + +type scalar = Csir.Scalar.t [@@deriving repr] + +(* The goal of blocks and pseudo-blocks is to keep together constraints that + depend on each other, e.g. those using next selectors. *) +type block = constr array + +(* coeff * wire *) +type term = scalar * int [@@deriving repr] + +(** Type to store the trace_updater information. + [free_wires] represents a list of indices of wires that have been + removed from the system and have not been used again for auxiliary + computations. If a free wire [w] is used to store an auxiliary linear + computation on some [terms], it is removed from [free_wires] and the pair + [(v, terms)] is added to the list of [assignments]. *) +type trace_info = {free_wires : int list; assignments : (int * term list) list} +[@@deriving repr] + +(** A pseudo constraint represents an equation between an arbitrary number of + terms. In particular, adding all terms from its head, body, tail and its + constant term should produce 0. + The length of pc_head and pc_tail should never exceed [nb_wires_arch]. *) +type pseudo_constr = { + pc_head : term list; + pc_body : term list; + pc_tail : term list; + pc_const : Scalar.t; +} + +(** A pseudo block is a list of pseudo constraints that have been groupped + in order to apply the {!shared_wires} heuristic.Alcotest + The constraints in a pseudo block satisfy (by construction) the invariant + the pc_head of a constraint starts with the pc_tail of the previous one + (when considering the term variables, coefficients may be different). + Note that the pc_head may contain extra terms that do not appear in the + previous pc_tail. + This invariant is important for [block_of_pseudo_block] to be correct *) +type pseudo_block = pseudo_constr list + +(** [join_list ~join scope x xs] joins [x] with another element among the first + [scope] elements of the list of candidates [xs], or returns [None] if no + union was possible. This function may not preserve the order in [xs] *) +let join_list : + join:('a -> 'a -> 'a option) -> int -> 'a -> 'a list -> 'a list option = + fun ~join scope x xs -> + let rec aux cnt seen_xs = function + | [] -> None + | x' :: xs -> ( + if cnt >= scope then None + else + match join x x' with + | Some union -> Some (List.rev_append seen_xs (union :: xs)) + | None -> ( + match join x' x with + | Some union -> Some (List.rev_append seen_xs (union :: xs)) + | None -> aux (cnt + 1) (x' :: seen_xs) xs)) + in + aux 0 [] xs + +(** [combine_quadratic ~join xs] takes a list of elements [xs] and returns + a (potentially) shorter list [xs'] where some of the elements have been + combined according to [join]. [join x x'] is [None] if [x] and [x'] cannot + be combined and it is [Some union] otherwise. + This algorithm tries to combine every element of [xs] with any other element + by greedily trying all possible [n choose 2] different pairings of elements, + where [n] is the length of [xs]. *) +let combine_quadratic : + scope:int -> join:('a -> 'a -> 'a option) -> 'a list -> 'a list = + fun ~scope ~join groups -> + let rec aux seen_xs = function + | [] -> seen_xs + | x :: xs -> ( + match join_list scope ~join x xs with + | None -> aux (x :: seen_xs) xs + | Some xs -> aux seen_xs xs) + in + aux [] groups + +(** Similar to [combine_quadratic], but more efficient. + Takes a list of [top_candidates] that will each be tried to be combined + with [rest]. This function may not preserve the order in [rest] *) +let combine_quadratic_efficient ~scope ~join top_candidates rest = + let rec aux seen top rest = + match top with + | [] -> List.rev_append (combine_quadratic ~scope ~join seen) rest + | x :: xs -> ( + match join_list scope ~join x rest with + | None -> aux (x :: seen) xs rest + | Some rest -> aux seen xs rest) + in + aux [] top_candidates rest + +(** Concatenates two lists of terms, merging terms with the same wire identifier + (by adding their coefficients) *) +let add_terms : term list -> term list -> term list = + fun terms1 terms2 -> + (* [aux] requires that the terms be first sorted wrt the wire identifier *) + let rec aux terms (q, w) = function + | [] -> (q, w) :: terms + | (q', w') :: rest -> + if w = w' then aux terms (Scalar.add q q', w) rest + else aux ((q, w) :: terms) (q', w') rest + in + let compare (_, w1) (_, w2) = Int.compare w2 w1 in + let sorted = List.sort compare (List.rev_append terms1 terms2) in + match sorted with [] -> [] | _ -> aux [] (List.hd sorted) (List.tl sorted) + +(** [inline w ~from ~into linear] takes an array of linear constraints + (a linear constraint is represented by list of terms), solves for wire + [w] in constraint [linear.(from)] and substitutes wire [w] by the result + in constraint [linear.(into)]. [linear.(from)] is left empty. + This routine should only be called if [w] does not appear in any other + constraint. In that case, constraint [linear.(from)] can then be removed + and wire [w] is said to be "free". *) +let inline w ~from ~into linear : unit = + let equals_w t = w = snd t in + let (q1, _), ts1 = find_and_remove equals_w linear.(from) in + let (q2, _), ts2 = find_and_remove equals_w linear.(into) in + let f (q, w) = (Scalar.(negate q * q2 / q1), w) in + linear.(from) <- [] ; + linear.(into) <- add_terms (List.map f ts1) ts2 + +(** The keys are wire indices and the values lists of constraints indices, such + that the wire appears in each of the constraints. *) +module IMap = Map.Make (Int) +(* TODO: sometimes for clarity I like to make the type of the values monomorphic + This module can also be called Wire_occurrences *) + +module ISet = Set.Make (Int) + +(** Auxiliary function used in [inline_linear]. + + [increase_occurrences map i terms] updates [map] by adding [i] to the + list of occurrences of wire [w] for every [(_, w)] in [terms]. *) +let increase_occurrences map i terms = + List.fold_left + (fun map (_, w) -> + IMap.update w (fun o -> Some (i :: Option.value ~default:[] o)) map) + map + terms + +(** Creates a pseudo block with all terms in the body except for the wire -1 + which is set as constant. *) +let pseudo_block_of_terms terms = + (* The list of terms contains no duplicates with respect to the wire + identifier [w], thanks to function [add_terms]. *) + let qcs, terms = List.partition (fun (_, w) -> w < 0) terms in + let qc = + match qcs with + | [] -> Scalar.zero + | [(q, -1)] -> q + | _ -> + (* Two different terms should not have the same second component *) + assert false + in + [{pc_head = []; pc_body = terms; pc_tail = []; pc_const = qc}] + +(** Returns a list of linear gates that have possibly been inlined, the list of + wires that were inlined (and thus freed) and the list of unchanged non-linear + gates. The wires selected for inlining must: + - appear in exactly two linear gates of size one + - not be inputs + The inlined linear gates are returned as pseudo blocks because they may need + to be split again to fit 3 wires. *) +let inline_linear ~nb_inputs gates = + let linear, non_linear = + List.partition_map + (fun gate -> + if Array.length gate = 1 && CS.is_linear_raw_constr gate.(0) then + Left gate.(0) + else Right gate) + gates + in + let linear = Array.(map CS.linear_terms @@ of_list linear) in + + let non_linear_wires = + List.concat_map CS.gate_wires non_linear |> ISet.of_list + in + + (* Associate each wire to the indices (of array [linear]) of the constraints + where the wire appears. The only wires considered must not: + - be a circuit input + - appear in a non-linear gate. *) + let wire_occurrences = + Array.fold_left + (fun (map, i) gate -> (increase_occurrences map i gate, succ i)) + (IMap.empty, 0) + linear + |> fst + |> IMap.filter (fun w _ -> + w > nb_inputs && (not @@ ISet.mem w non_linear_wires)) + in + + (* During the process of inlining, some wire occurrences will point to + constraints that have been removed (inlined). + In [pointers] we carry the information of where they were inlined into. *) + let pointers = ref IMap.empty in + let rec updated_pointer occ = + match IMap.find_opt occ !pointers with + | Some p -> + let p' = updated_pointer p in + (* Create a direct connection between [occ] and [p'] *) + pointers := IMap.add occ p' !pointers ; + p' + | None -> occ + in + + (* If a wire occurs only on two constraints, we remove one + of them, "inlining" it in the other, the wire disappears *) + let free_wires, removable_constrs = + IMap.fold + (fun w occs (free_wires, removable_constrs) -> + match occs with + | [occ] -> + (* We could raise an exception saying that wire [w] is unnecessary *) + let occ = updated_pointer occ in + (w :: free_wires, occ :: removable_constrs) + | [occ1; occ2] -> + let from = updated_pointer occ1 in + let into = updated_pointer occ2 in + inline w ~from ~into linear ; + (* References to [from] should refer to [into] instead *) + pointers := IMap.add from into !pointers ; + (w :: free_wires, removable_constrs) + | _ -> (free_wires, removable_constrs)) + wire_occurrences + ([], []) + in + + (* Drop removable constraints (only now that the inlining has finished) *) + List.iter (fun c -> linear.(c) <- []) removable_constrs ; + let linear = List.filter (fun ts -> ts <> []) (Array.to_list linear) in + + (* Sort free_vars to reach allocation order. Is this really needed? *) + let free_wires = List.sort Int.compare free_wires in + + let pseudo_blocks = List.map pseudo_block_of_terms linear in + + (pseudo_blocks, non_linear, free_wires) + +(** [place_over_pseudo_block ~perfectly b1 b2] tries to join pseudo block [b1] + on top of [b2], i.e., link the last pseudo constraint of [b1] with the + first pseudo constraint of [b2]. It returns an optional argument containing + the combined pseudo block if the combination was successful. + [perfectly] is a Boolean argument that specifies whether only "perfect" + matches should be accepted. In this context, "perfect" means that the two + constraints to be combined share exactly [nb_wires_arch] wires. *) +let place_over_pseudo_block ~perfectly b1 b2 = + let b1_rest, b1_k = split_last b1 in + let b2_0, b2_rest = split_first b2 in + + if b1_k.pc_tail <> [] || b2_0.pc_head <> [] then None + else + let b1_body = List.map snd b1_k.pc_body in + let b2_body = List.map snd b2_0.pc_body in + let common_body = list_intersection ~equal:( = ) b1_body b2_body in + + (* Given that the head of [b2_0] is empty, we can place [nb_wires_arch] + terms on it. The total room depends on how occupied its tail is *) + let b2_free_room = (2 * nb_wires_arch) - List.length b2_0.pc_tail in + + (* We will pick [n] common terms between the bodies of [b1_k] and [b2_0]. + If the body of [b2_0] fits completely into its head, we do not need + to leave an extra space for an auxiliary variable *) + let n = + if + List.compare_length_with b2_body b2_free_room <= 0 + && List.compare_length_with b2_body nb_wires_arch = 0 + then nb_wires_arch + else nb_wires_arch - 1 + in + let common = rev_first_n ~n common_body |> ISet.of_list in + + let tight = ISet.cardinal common = nb_wires_arch in + if perfectly && not tight then None + else if nb_wires_arch - ISet.cardinal common > 1 then None + else + let split_body = List.partition (fun (_, w) -> ISet.mem w common) in + let qcommon1, body1 = split_body b1_k.pc_body in + let qcommon2, body2 = split_body b2_0.pc_body in + + (* We sort them so that they have the same order *) + let compare_terms (_, w1) (_, w2) = Int.compare w1 w2 in + let qcommon1 = List.sort compare_terms qcommon1 in + let qcommon2 = List.sort compare_terms qcommon2 in + let pc1 = {b1_k with pc_tail = qcommon1; pc_body = body1} in + let pc2 = {b2_0 with pc_head = qcommon2; pc_body = body2} in + Some (b1_rest @ (pc1 :: pc2 :: b2_rest)) + +let combine_pseudo_blocks ~scope ~perfectly pseudo_blocks = + let try_both_ways b1 b2 = + match place_over_pseudo_block ~perfectly b1 b2 with + | None -> place_over_pseudo_block ~perfectly b2 b1 + | Some union -> Some union + in + combine_quadratic ~scope ~join:try_both_ways pseudo_blocks + +let linear_combination ~this ~next qc = + let pad = List.init (nb_wires_arch - List.length this) (fun _ -> 0) in + let wires = List.map snd this @ pad in + + let combine l1 l2 = List.combine (list_sub (List.length l2) l1) l2 in + let this_sels = combine CS.this_constr_linear_selectors (List.map fst this) in + let next_sels = combine CS.next_constr_linear_selectors (List.map fst next) in + CS.mk_linear_constr (wires, (("qc", qc) :: this_sels) @ next_sels) + +let dummy_linear_combination terms = + let pad = List.init (nb_wires_arch - List.length terms) (fun _ -> 0) in + CS.mk_linear_constr (List.map snd terms @ pad, []) + +(** Given a pseudo block, i.e., a list of pseudo constraints, transform it into + a block. Thanks to the invariant that the pc_head of a pseudo constraint + starts with the pc_tail of the previous one, it is enough to add a constraint + for each pc_head (and encode each pc_tail with next-gate selectors). + Note that pc_bodies may need to be freed through auxiliary variables. *) +let block_of_pseudo_block trace_info pseudo_block = + let pseudo_block = Array.of_list pseudo_block in + Array.fold_left + (fun (trace_info, block, residue_pseudo_blocks, i) b -> + (* We need to move all terms from b.pc_body to its head or tail. + If there are more terms that those that can be moved, we will + need an auxiliary variable, to be put in the head *) + + (* TODO: select heuristically what to place and where, e.g., leave + for the residue the terms that are more frequent among the circuit *) + let is_last = i = Array.length pseudo_block - 1 in + let free_room = nb_wires_arch - List.length b.pc_head in + let free_room = + free_room + if is_last then nb_wires_arch - List.length b.pc_tail else 0 + in + let aux_var_needed = List.compare_length_with b.pc_body free_room > 0 in + let n = if aux_var_needed then nb_wires_arch - 1 else nb_wires_arch in + let head, pending = complete ~n b.pc_head b.pc_body in + let tail, pending = + if is_last then complete ~n:nb_wires_arch b.pc_tail pending + else (b.pc_tail, pending) + in + let trace_info, head, residues = + if not aux_var_needed then ( + assert (pending = []) ; + (trace_info, head, [])) + else + let v, free_wires = split_first trace_info.free_wires in + let assignments = (v, pending) :: trace_info.assignments in + assert (List.compare_length_with head nb_wires_arch < 0) ; + let head = head @ [(Scalar.one, v)] in + let trace_info = {free_wires; assignments} in + let residues = + [pseudo_block_of_terms @@ ((Scalar.(negate one), v) :: pending)] + in + (trace_info, head, residues) + in + (* The next constraint will have a head that starts with this tail *) + let constr1 = linear_combination ~this:head ~next:tail b.pc_const in + let constrs = + if is_last && tail <> [] then [constr1; dummy_linear_combination tail] + else [constr1] + in + (trace_info, block @ constrs, residues @ residue_pseudo_blocks, succ i)) + (trace_info, [], [], 0) + pseudo_block + |> fun (trace_info, block, residue_pseudo_blocks, _) -> + (trace_info, Array.of_list block, residue_pseudo_blocks) + +(** This function takes a list of pseudo blocks, combines them if possible and + converts them into blocks. This conversion may lead to residue pseudo blocks + (if auxiliary variables were involved to free a pc_body). + It then applies the same process on the residue pseudo blocks. + Observe that it is relatively rare that a residue pseudo block is produced + after the convertion. Consequently the second iteration of this function + will be among many fewer pseudo blocks and it quickly reaches termination *) +let blocks_of_pseudo_blocks ~scope free_wires pseudo_blocks = + let rec iteration (trace_info, blocks, pseudo_blocks) = + match pseudo_blocks with + | [] -> (trace_info, blocks) + | _ -> + let joined = + pseudo_blocks + |> combine_pseudo_blocks ~scope ~perfectly:true + |> combine_pseudo_blocks ~scope ~perfectly:false + in + List.fold_left + (fun (trace_info, blocks, new_pseudoblks) pb -> + let trace_info, block, new_pseudo = + block_of_pseudo_block trace_info pb + in + ( trace_info, + block :: blocks, + List.rev_append new_pseudo new_pseudoblks )) + (trace_info, blocks, []) + joined + |> iteration + in + let trace_info = {free_wires; assignments = []} in + iteration (trace_info, [], pseudo_blocks) + +(** [place_over_block ~perfectly pb pb'] tries to join block [b1] on top + of [b2]. It works only if the last constraint of [b1] has no selectors. + [perfectly] returns only matches that have no empty selectors (no holes). + It is relevant for a heuristic where we first want to find perfect matches + and then any match. + + The joining is done by + - finding a permutation that makes the wires of b1.last and b2.first match + (being relaxed about unset wires) + - checking if the permutation if perfect and failing if required + - renaming the selectors of b1.last + - renaming the next selectors of b1.second_last + + Example: + [ (1 1 1) [ql:a qlg:b] + (3 2 -1) [] ] + [ (2 3 4) [ql:a] + (1 1 1) [ql:a] ] + becomes + [ (1 1 1) [ql:a qrg:b] + (2 3 4) [ql:a] + (1 1 1) [ql:a] ] +*) +let place_over_block : perfectly:bool -> block -> block -> block option = + fun ~perfectly b1 b2 -> + let b1_k = b1.(Array.length b1 - 1) in + + if b1_k.sels <> [] then None + else + let wires1 = CS.wires_of_constr_i b1 (Array.length b1 - 1) in + let wires2 = CS.wires_of_constr_i b2 0 in + + match adapt wires1 wires2 with + | None -> None + | Some perm -> + let wires1 = permute_list perm wires1 in + let combined = + List.map2 (fun x y -> if x >= 0 then x else y) wires1 wires2 + in + let is_perfect = List.for_all (fun x -> x >= 0) combined in + let b1_k_1 = b1.(Array.length b1 - 2) in + if perfectly && not is_perfect then None + else if + (* if the second last of b1 is not arithmetic, we cannot permute it *) + not (is_identity_perm perm || CS.is_arithmetic_raw_constr b1_k_1) + then None + else + let rename n = + let selectors_assoc = + List.combine + (permute_list perm CS.next_constr_linear_selectors) + CS.next_constr_linear_selectors + in + assert (List.compare_length_with selectors_assoc nb_wires_arch = 0) ; + match List.find_opt (fun (s, _) -> s = n) selectors_assoc with + | Some (_, s') -> s' + | None -> n + in + let sels_prev = List.map (fun (n, q) -> (rename n, q)) b1_k_1.sels in + let a, b, c, d, e = + (* TODO: Revisit [type raw_constraint] and how to represent unused + wires. Should the conversion from -1 to 0 be done here? *) + match List.map (max 0) combined with + | [a; b; c; d; e] -> (a, b, c, d, e) + | _ -> assert false + in + let b2_0 = b2.(0) in + let b2_rest = Array.sub b2 1 (Array.length b2 - 1) in + assert (b1_k.precomputed_advice = []) ; + b1.(Array.length b1 - 1) <- + { + a; + b; + c; + d; + e; + sels = b2_0.sels; + precomputed_advice = b2_0.precomputed_advice; + label = "hyb" :: b2_0.label; + } ; + b1.(Array.length b1 - 2) <- {b1_k_1 with sels = sels_prev} ; + Some (Array.append b1 b2_rest) + +let combine_blocks ~perfectly blocks = + let blocks_with_empty_selectors, rest = + let open CS in + List.partition (fun b -> b.(Array.length b - 1).sels = []) blocks + in + combine_quadratic_efficient + ~join:(place_over_block ~perfectly) + blocks_with_empty_selectors + rest + +(** Takes {!type:trace_info} and returns a function that updates a given + trace to make it compatible with the optimized constraints. *) +let trace_updater : trace_info -> scalar array -> scalar array = + fun trace_info trace -> + let sum ~trace = + List.fold_left + (fun s (coeff, i) -> Scalar.(add s @@ mul coeff trace.(i))) + Scalar.zero + in + List.iter + (fun (i, terms) -> trace.(i) <- sum ~trace terms) + (* Iterate over the assignments reversed to ensure that variables + are assigned in the correct order, in case they depend on each other. *) + (List.rev trace_info.assignments) ; + trace + +let remove_boolean_gates gates = + let gates, boolean_vars = + List.fold_left + (fun (non_boolean_gates, boolean_vars) gate -> + if Array.length gate = 1 then + match CS.boolean_raw_constr gate.(0) with + | Some b -> (non_boolean_gates, b :: boolean_vars) + | None -> (gate :: non_boolean_gates, boolean_vars) + else (gate :: non_boolean_gates, boolean_vars)) + ([], []) + gates + in + (List.rev gates, boolean_vars) + +let add_boolean_checks ~boolean_vars gates = + let bool_vars_map = ref @@ ISet.of_list boolean_vars in + let shared_a constr = + let a_wire = CS.(constr.a) in + if ISet.mem a_wire !bool_vars_map then ( + bool_vars_map := ISet.remove a_wire !bool_vars_map ; + CS.{constr with sels = ("qbool", Scalar.one) :: constr.sels}) + else constr + in + let unused_a ~gate i constr = + let wires = CS.wires_of_constr_i gate i in + if List.hd wires < 0 && ISet.cardinal !bool_vars_map > 0 then ( + let a = ISet.choose !bool_vars_map in + bool_vars_map := ISet.remove a !bool_vars_map ; + CS.{constr with a; sels = ("qbool", Scalar.one) :: constr.sels}) + else constr + in + (* First try to add them on existing constraints, through the qbool selector *) + let gates = List.map (fun gate -> Array.map shared_a gate) gates in + (* Then, try to use constraints that do not use the a wire *) + let gates = List.map (fun gate -> Array.mapi (unused_a ~gate) gate) gates in + (* Finally, add manual constraints for the remaining boolean variables *) + let new_bool_gates = + List.map CS.mk_bool_constr (ISet.to_seq !bool_vars_map |> List.of_seq) + |> Array.of_list + in + List.rev (new_bool_gates :: gates) + +(* This function takes care of renaming variables that are bound to be + the same by an arithmetic constraint. + For example, if there is a constraint of the form [x - y = 0], we will + replace [x -> y] everywhere and remove the constraint. + Alternatively, we could replace [y -> x]. + This is not possible if both [x] and [y] are inputs to the circuit. *) +let inline_renamings ~nb_inputs gates = + let renaming_pairs = + List.filter_map + (fun gate -> + if Array.length gate = 1 && CS.is_linear_raw_constr gate.(0) then + match CS.linear_terms gate.(0) with + | [(q1, w1); (q2, w2)] + when w1 >= 0 && w2 >= 0 && Scalar.(is_zero @@ add q1 q2) -> + Some (w1, w2) + | _ -> None + else None) + gates + in + (* Create a map from wires to all the wires they are bound to be equal to *) + let renaming_partitions = + List.fold_left + (fun partitions (i, j) -> + let rec find_all_equal ~seen i = + let i_set = + Option.value ~default:ISet.empty @@ IMap.find_opt i partitions + in + ISet.fold + (fun j (acc, seen) -> + if ISet.mem j seen then (acc, seen) + else + let j_set = find_all_equal ~seen j in + (ISet.union acc j_set, ISet.add j seen)) + i_set + (i_set, ISet.add i seen) + |> fst + in + let ij_partition = + let ij = ISet.add i @@ ISet.singleton j in + let i_set = find_all_equal ~seen:ij i in + let j_set = find_all_equal ~seen:ij j in + ISet.union i_set j_set |> ISet.union ij + in + ISet.fold + (fun k partitions -> IMap.add k ij_partition partitions) + ij_partition + partitions) + IMap.empty + renaming_pairs + in + (* Each wire will be renamed (if it is not an input wire) to the + minimal wire of their partition. This makes sure that all the wire + in the same partition get renamed to the same wire (when renamed) *) + let renaming = + IMap.mapi + (fun i i_set -> if i <= nb_inputs then i else ISet.min_elt i_set) + renaming_partitions + in + let free_wires = + IMap.filter ( <> ) renaming |> IMap.bindings |> List.map fst + in + let rename i = Option.value ~default:i @@ IMap.find_opt i renaming in + (List.map (CS.rename_wires ~rename) gates, free_wires) + +(* We remove all constraints of the form [a * x - a * x = 0], which may + be the result of having renamed some variables *) +let remove_trivial gates = + List.filter + (fun gate -> + if Array.length gate = 1 && CS.is_linear_raw_constr gate.(0) then + match CS.linear_terms gate.(0) with + | [(q1, w1); (q2, w2)] + when w1 >= 0 && w2 >= 0 && Scalar.(is_zero @@ add q1 q2) -> + w1 <> w2 + | _ -> true + else true) + gates + +(** Takes a list of raw_constraints and returns an equivalent constraint system + with potentially fewer constraints. + As a second output, it returns the necessary information to build a function + that updates the trace to make it compatible with the new constraints *) +let optimize : nb_inputs:int -> CS.gate list -> CS.gate list * trace_info = + fun ~nb_inputs gates -> + let gates, free_wires_inlining = inline_renamings ~nb_inputs gates in + let gates = remove_trivial gates in + let linear_pseudo_blocks, non_linear, free_wires = + inline_linear ~nb_inputs gates + in + let free_wires = List.sort Int.compare @@ free_wires_inlining @ free_wires in + let non_linear, boolean_vars = remove_boolean_gates non_linear in + let scope = + if List.compare_length_with non_linear 10_000 > 0 then 10 else 100 + in + let trace_info, linear_blocks = + blocks_of_pseudo_blocks ~scope free_wires linear_pseudo_blocks + in + let cs = + List.rev_append non_linear linear_blocks + |> combine_blocks ~scope ~perfectly:true + |> combine_blocks ~scope ~perfectly:false + (* we shuffle the blocks to mix linear with non-linear ones and this + way allow for more likely combinations; we use an arbitrary fixed seed + for determinism *) + |> shuffle_list ~seed:1031 + |> combine_blocks ~scope ~perfectly:false + |> shuffle_list ~seed:42 + |> combine_blocks ~scope ~perfectly:false + in + let cs = add_boolean_checks ~boolean_vars cs in + (cs, trace_info) diff --git a/src/lib_plompiler/optimizer_helpers.ml b/src/lib_plompiler/optimizer_helpers.ml new file mode 100644 index 000000000000..89ce35355cb0 --- /dev/null +++ b/src/lib_plompiler/optimizer_helpers.ml @@ -0,0 +1,124 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let find_and_remove_opt f list = + let rec aux acc = function + | [] -> None + | x :: xs -> if f x then Some (x, List.rev acc @ xs) else aux (x :: acc) xs + in + aux [] list + +let find_and_remove f list = + match find_and_remove_opt f list with None -> raise Not_found | Some x -> x + +let find2_and_remove f1 f2 list = + match find_and_remove_opt f1 list with + | None -> find_and_remove f2 list + | Some x -> x + +let rec split_last = function + | [] -> assert false + | [x] -> ([], x) + | x :: xs -> + let xs, last = split_last xs in + (x :: xs, last) + +let split_first = function [] -> assert false | x :: xs -> (x, xs) + +(* TODO: implement this function in O(n) complexity *) +let list_intersection ~equal l1 l2 = + List.fold_left + (fun acc x -> if List.exists (equal x) l1 then x :: acc else acc) + [] + l2 + +(* [complete ~n acc l] moves elements from [l] to [acc] until + [acc] contains exactly [n] elements, it returns two lists + corresponding to the updated [acc] and [l] respectively. *) +let rec complete ~n acc = function + | [] -> (acc, []) + | h :: t -> + let r = List.compare_length_with acc n in + if r > 0 then assert false + else if r = 0 then (acc, h :: t) + else complete ~n (acc @ [h]) t + +let rev_first_n ~n l = + let rec aux (acc, k) = function + | [] -> acc + | h :: t -> if k = n then acc else aux (h :: acc, succ k) t + in + aux ([], 0) l + +let permute_list permutation l = + let l = Array.of_list l in + List.map (fun j -> l.(j)) permutation + +let rec is_identity_perm ?(cnt = 0) permutation = + match permutation with + | [] -> true + | x :: xs -> x = cnt && is_identity_perm ~cnt:(cnt + 1) xs + +(* Given two lists [l1] and [l2], it returns a permutation [p] of [l1] such that + for all i: l2.(i) = l1.(p i) OR l2.(i) < 0 OR l1.(p i) < 0. + (Where a permutation is modeled as a list of integers). *) +let adapt l1 l2 = + (* return the identity if they are already compatible *) + if List.for_all2 (fun x1 x2 -> x1 = x2 || x1 < 0 || x2 < 0) l1 l2 then + Some (List.init (List.length l1) Fun.id) + else + let common = list_intersection ~equal:( = ) l1 l2 in + try + let perm, _ = + List.fold_left + (fun (perm, pending) y -> + let equals_y (_, x) = x = y in + let is_free (_, x) = x < 0 in + let is_unrelated (_, x) = x >= 0 && (not @@ List.mem x common) in + let x, pending = + if y >= 0 then + if List.mem y (List.map snd pending) then + find_and_remove equals_y pending + else find_and_remove is_free pending + else find2_and_remove is_unrelated is_free pending + in + (perm @ [fst x], pending)) + ([], List.mapi (fun i x -> (i, x)) l1) + l2 + in + Some perm + with Not_found -> None + +let list_sub n l = + let rec aux k acc l = + if k = n then List.rev acc else aux (k + 1) (List.hd l :: acc) (List.tl l) + in + aux 0 [] l + +let shuffle_list ?seed l = + (match seed with None -> () | Some i -> Random.init i) ; + List.rev_map (fun x -> (Random.bits (), x)) l + |> List.sort (fun (i, _) (j, _) -> Int.compare i j) + |> List.rev_map snd diff --git a/src/lib_plompiler/plompiler.ml b/src/lib_plompiler/plompiler.ml new file mode 100644 index 000000000000..585d348c5bf7 --- /dev/null +++ b/src/lib_plompiler/plompiler.ml @@ -0,0 +1,84 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +include Lang_core +include Lang_stdlib + +module LibResult : sig + include LIB + + val get_result : 'a repr t -> 'a Input.t +end = struct + include Result + include Lib (Result) +end + +module LibCircuit : sig + include LIB + + val deserialize : S.t array -> 'a Input.t -> 'a Input.t + + val get_inputs : 'a repr t -> S.t array * int + + type cs_result = { + nvars : int; + free_wires : int list; + cs : Csir.CS.t; + input_com_sizes : int list; + tables : Csir.Table.t list; + solver : Solver.t; + } + [@@deriving repr] + + val get_cs : ?optimize:bool -> 'a repr t -> cs_result +end = struct + include Circuit + include Lib (Circuit) +end + +module Gadget = struct + module type HASH = Hash_sig.HASH + + module Anemoi128 = Gadget_anemoi.Anemoi128 + module AnemoiJive_128_1 = Gadget_anemoi.Make + module Poseidon128 = Gadget_poseidon.Poseidon128 + module Poseidon252 = Gadget_poseidon.Poseidon252 + module PoseidonFull = Gadget_poseidon.PoseidonFull + module Merkle = Gadget_merkle.Make + module Merkle_narity = Gadget_merkle_narity + module JubjubEdwards = Gadget_edwards.Jubjub + module JubjubWeierstrass = Gadget_weierstrass.Jubjub + module Schnorr = Gadget_schnorr.Make + module Blake2s = Gadget_blake2s.Blake2s +end + +include Gadget +module Utils = Utils +module Linear_algebra = Linear_algebra +module Optimizer = Optimizer +module Solver = Solver +module Encodings = Encoding.Encodings +module Bounded = Bounded +module Csir = Csir diff --git a/src/lib_plompiler/result.ml b/src/lib_plompiler/result.ml new file mode 100644 index 000000000000..bde8bdaa0906 --- /dev/null +++ b/src/lib_plompiler/result.ml @@ -0,0 +1,448 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +include Lang_core + +type scalar = X of S.t + +type input_kind = [`InputCom | `Public | `Private] + +type trace_kind = [input_kind | `NoInput] + +type 'a repr = + | U : unit repr + | S : scalar -> scalar repr + | B : bool -> bool repr + | P : 'a repr * 'b repr -> ('a * 'b) repr + | L : 'a repr list -> 'a list repr + +type state = bool repr list + +type 'a t = state -> state * 'a + +let ret x s = (s, x) + +let ( let* ) m f s = + let s, o = m s in + f o s + +let ( >* ) m f = + let* U = m in + f + +let rec mapM f ls = + match ls with + | [] -> ret @@ [] + | l :: ls -> + let* o = f l in + let* rest = mapM f ls in + ret @@ (o :: rest) + +let with_bool_check : bool repr t -> unit repr t = + fun check s -> + let s, b = check s in + (b :: s, U) + +module Input = struct + type 'a implicit_check = 'a repr -> unit repr t + + type 'a t' = 'a repr + + type 'a input = 'a t' * 'a implicit_check + + type 'a t = 'a input + + let default_check _ = ret U + + let s x : scalar t' = S (X x) + + let scalar x = (s x, default_check) + + let to_scalar (S (X x), _) = x + + let bool b = (B b, default_check) + + let to_bool (B b, _) = b + + let unit = (U, default_check) + + let pair : 'a t -> 'b t -> ('a * 'b) t = + fun (a, check_a) (b, check_b) -> + (P (a, b), fun (P (ar, br)) -> check_a ar >* check_b br) + + let to_pair (P (a, b), _) = ((a, default_check), (b, default_check)) + + let list : 'a t list -> 'a list t = + fun l -> + ( L (List.map fst l), + fun (L lr) -> + let* _l = + mapM (fun ((_, asssertion), r) -> asssertion r) (List.combine l lr) + in + ret U ) + + let to_list (L l, _) = List.map (fun i -> (i, default_check)) l + + let with_implicit_bool_check bc (i, a) = + (i, fun repr -> a repr >* with_bool_check (bc repr)) + + let with_assertion na (i, a) = (i, fun repr -> a repr >* na repr) +end + +let rec encode : type a. a Input.t' -> S.t list = + fun input -> + match input with + | U -> [] + | S (X s) -> [s] + | B b -> if b then [S.one] else [S.zero] + | P (l, r) -> encode l @ encode r + | L l -> List.concat_map encode l + +let serialize i = Array.of_list @@ encode (fst i) + +let rec eq : type a. a repr -> a repr -> bool = + fun a b -> + match (a, b) with + | S (X a), S (X b) -> S.eq a b + | B a, B b -> a = b + | P (al, ar), P (bl, br) -> eq al bl && eq ar br + | L l1, L l2 -> List.for_all2 eq l1 l2 + | U, U -> true + +let input : type a. ?kind:input_kind -> a Input.t -> a repr t = + fun ?(kind = `Private) (input, check) -> + ignore kind ; + check input >* ret input + +let new_input_com : unit repr t = fun s -> (s, U) + +type 'b open_input_com = 'b t + +let begin_input_com : 'b -> 'b open_input_com = fun b -> new_input_com >* ret b + +let ( |: ) : + type c d. (c repr -> d) open_input_com -> c Input.t -> d open_input_com = + fun v i s -> + let s, f = v s in + let s, r = (input ~kind:`InputCom i) s in + (s, f r) + +let end_input_com : 'a open_input_com -> 'a t = Fun.id + +let to_list l = L l + +let of_list (L l) = l + +let of_pair (P (l, r)) = (l, r) + +let pair l r = P (l, r) + +let unit = U + +let of_s (S (X s)) = s + +let map2 f x y = X (f x y) + +let rec foldM f e l = + match l with + | [] -> ret e + | x :: xs -> + let* y = f e x in + foldM f y xs + +let scalar_of_bool (B b) = if b then S (X S.one) else S (X S.zero) + +let constant_scalar x = ret @@ Input.s x + +let unsafe_bool_of_scalar (S (X s)) = if S.(eq s one) then B true else B false + +module Num = struct + type nonrec scalar = scalar + + type nonrec 'a repr = 'a repr + + type nonrec 'a t = 'a t + + let assert_nonzero sx = + let x = of_s sx in + assert (not S.(x = zero)) ; + ret U + + let is_zero (S (X x)) = ret @@ B S.(x = zero) + + let is_not_zero (S (X x)) = ret @@ B (not S.(x = zero)) + + let custom ?(qc = S.zero) ?(ql = S.zero) ?(qr = S.zero) ?(qo = S.mone) + ?(qm = S.zero) ?(qx2b = S.zero) ?(qx5a = S.zero) sl sr = + let l, r = (of_s sl, of_s sr) in + let o = + S.( + ((ql * l) + (qr * r) + + (qm * l * r) + + qc + + (qx2b * r * r) + + (qx5a * l * l * l * l * l)) + / negate qo) + in + ret @@ S (X o) + + let assert_custom ?(qc = S.zero) ?(ql = S.zero) ?(qr = S.zero) ?(qo = S.zero) + ?(qm = S.zero) sl sr so = + let l, r, o = (of_s sl, of_s sr, of_s so) in + let o = S.((ql * l) + (qr * r) + (qo * o) + (qm * l * r) + qc) in + assert (S.(o = zero)) ; + ret U + + let assert_bool (S (X l)) = + assert (S.(l = zero || l = one)) ; + ret U + + let add ?(qc = S.zero) ?(ql = S.one) ?(qr = S.one) sl sr = + let l, r = (of_s sl, of_s sr) in + let o = S.((ql * l) + (qr * r) + qc) in + ret @@ S (X o) + + let sub sl sr = + let l, r = (of_s sl, of_s sr) in + ret @@ S (map2 S.sub l r) + + let mul ?(qm = S.one) sl sr = + let l, r = (of_s sl, of_s sr) in + let lr = S.mul l r in + ret @@ S (map2 S.mul qm lr) + + let add_constant ?(ql = S.one) k sl = + let l = of_s sl in + let o = S.(k + (ql * l)) in + ret @@ S (X o) + + let div ?(den_coeff = S.one) sl sr = + let l, r = (of_s sl, of_s sr) in + assert (not S.(is_zero r)) ; + assert (not S.(is_zero den_coeff)) ; + let qmr = S.mul den_coeff r in + ret @@ S (map2 S.div_exn l qmr) + + let pow5 sl = + let l = of_s sl in + ret @@ S (X S.(pow l (Z.of_int 5))) +end + +module Bool = struct + include Num + + let s_of_b b = if b then X S.one else X S.zero + + let assert_true (B b) = + assert b ; + ret U + + let assert_false (B b) = + assert (not b) ; + ret U + + let constant_bool : bool -> bool repr t = fun b -> ret (B b) + + let band (B l) (B r) = ret @@ B (l && r) + + let xor (B l) (B r) = + let o = + match (l, r) with + | true, true -> false + | false, true -> true + | true, false -> true + | false, false -> false + in + ret @@ B o + + let bor (B l) (B r) = ret @@ B (l || r) + + let bor_lookup (B l) (B r) = bor (B l) (B r) + + let bnot (B b) = ret @@ B (not b) + + let ifthenelse (B b) l r = if b then ret l else ret r + + let swap (B b) l r = if b then ret @@ pair r l else ret @@ pair l r + + let band_list l : bool repr t = + ret @@ List.fold_left (fun (B a) (B b) -> B (a && b)) (B true) l +end + +let point x y = P (S (X x), S (X y)) + +let of_point (P (S (X x), S (X y))) = (x, y) + +module Ecc = struct + let weierstrass_add p1 p2 = + let module W = Mec.Curve.Jubjub.AffineWeierstrass in + let x1, y1 = of_point p1 in + let x2, y2 = of_point p2 in + let s_to_base s = W.Base.of_z (S.to_z s) in + let s_of_base s = S.of_z (W.Base.to_z s) in + let p1 = W.from_coordinates_exn ~x:(s_to_base x1) ~y:(s_to_base y1) in + let p2 = W.from_coordinates_exn ~x:(s_to_base x2) ~y:(s_to_base y2) in + let p3 = W.add p1 p2 in + ret + @@ point + (s_of_base @@ W.get_x_coordinate p3) + (s_of_base @@ W.get_y_coordinate p3) + + let edwards_add p1 p2 = + let module W = Mec.Curve.Jubjub.AffineEdwards in + let x1, y1 = of_point p1 in + let x2, y2 = of_point p2 in + let s_to_base s = W.Base.of_z (S.to_z s) in + let s_of_base s = S.of_z (W.Base.to_z s) in + let p1 = W.from_coordinates_exn ~u:(s_to_base x1) ~v:(s_to_base y1) in + let p2 = W.from_coordinates_exn ~u:(s_to_base x2) ~v:(s_to_base y2) in + let p3 = W.add p1 p2 in + ret + @@ point + (s_of_base @@ W.get_u_coordinate p3) + (s_of_base @@ W.get_v_coordinate p3) + + let edwards_cond_add p1 p2 (B b) = + let module W = Mec.Curve.Jubjub.AffineEdwards in + let x1, y1 = of_point p1 in + let x2, y2 = of_point p2 in + let s_to_base s = W.Base.of_z (S.to_z s) in + let s_of_base s = S.of_z (W.Base.to_z s) in + let p1 = W.from_coordinates_exn ~u:(s_to_base x1) ~v:(s_to_base y1) in + let p2 = W.from_coordinates_exn ~u:(s_to_base x2) ~v:(s_to_base y2) in + let p3 = W.add p1 p2 in + let out = if b then p3 else p1 in + ret + @@ point + (s_of_base @@ W.get_u_coordinate out) + (s_of_base @@ W.get_v_coordinate out) +end + +module Poseidon = struct + module VS = Linear_algebra.Make_VectorSpace (S) + + let poseidon128_full_round ~matrix ~k ~variant:_ (x0, x1, x2) = + let pow5 x = S.pow (of_s x) (Z.of_int 5) in + let x_vec = [|Array.map pow5 [|x0; x1; x2|]|] |> VS.transpose in + let y_vec = VS.mul matrix x_vec in + let y0 = S.add k.(0) @@ y_vec.(0).(0) in + let y1 = S.add k.(1) @@ y_vec.(1).(0) in + let y2 = S.add k.(2) @@ y_vec.(2).(0) in + ret @@ to_list [S (X y0); S (X y1); S (X y2)] + + let poseidon128_four_partial_rounds ~matrix ~ks ~variant:_ (x0, x1, x2) = + let k0 = VS.filter_cols (Int.equal 0) ks in + let k1 = VS.filter_cols (Int.equal 1) ks in + let k2 = VS.filter_cols (Int.equal 2) ks in + let k3 = VS.filter_cols (Int.equal 3) ks in + let ppow5 v = [|v.(0); v.(1); [|S.pow v.(2).(0) (Z.of_int 5)|]|] in + let x_vec = [|[|of_s x0; of_s x1; of_s x2|]|] |> VS.transpose in + let a_vec = VS.(add (mul matrix @@ ppow5 x_vec) k0) in + let b_vec = VS.(add (mul matrix @@ ppow5 a_vec) k1) in + let c_vec = VS.(add (mul matrix @@ ppow5 b_vec) k2) in + let y_vec = VS.(add (mul matrix @@ ppow5 c_vec) k3) in + ret + @@ to_list [S (X y_vec.(0).(0)); S (X y_vec.(1).(0)); S (X y_vec.(2).(0))] +end + +module Anemoi = struct + module AnemoiPerm = Bls12_381_hash.Permutation.Anemoi + + let beta = S.of_string (Bls12_381.Fr.to_string AnemoiPerm.Parameters.beta) + + let gamma = S.of_string (Bls12_381.Fr.to_string AnemoiPerm.Parameters.gamma) + + let g = S.of_string (Bls12_381.Fr.to_string AnemoiPerm.Parameters.g) + + let delta = S.of_string (Bls12_381.Fr.to_string AnemoiPerm.Parameters.delta) + + let alpha_inv = + S.of_string (Bls12_381.Fr.to_string AnemoiPerm.Parameters.alpha_inv) + + let anemoi_round ~kx ~ky (x0, y0) = + let x0 = of_s x0 in + let y0 = of_s y0 in + let g2_p_1 = S.((g * g) + one) in + let w_5 = S.(sub x0 ((beta * y0 * y0) + gamma)) in + (* (1/5) *) + let w = S.(pow w_5 (to_z alpha_inv)) in + let v = S.sub y0 w in + let u = S.(w_5 + ((beta * v * v) + delta)) in + let x1 = S.(u + kx + (g * (v + ky))) in + let y1 = S.((g * (u + kx)) + (g2_p_1 * (v + ky))) in + ret @@ pair (S (X x1)) (S (X y1)) + + let anemoi_double_round ~kx1 ~ky1 ~kx2 ~ky2 (x0, y0) = + let* res1 = anemoi_round ~kx:kx1 ~ky:ky1 (x0, y0) in + let x1, y1 = of_pair res1 in + let* res2 = anemoi_round ~kx:kx2 ~ky:ky2 (x1, y1) in + let x2, y2 = of_pair res2 in + ret @@ pair x2 y2 + + let anemoi_custom = anemoi_double_round +end + +let hd (L l) = match l with [] -> assert false | x :: _ -> ret x + +let assert_equal l r = + assert (eq l r) ; + ret U + +let equal : type a. a repr -> a repr -> bool repr t = + fun l r -> ret @@ B (eq l r) + +let bits_of_scalar ?(shift = Z.zero) ~nb_bits sx = + let x = of_s sx |> S.to_z in + let x = Z.add shift x in + let sx = S (X (S.of_z x)) in + let binary_decomposition = Utils.bool_list_of_z ~nb_bits x in + let bits = L (List.map (fun x -> B x) binary_decomposition) in + let powers = List.init nb_bits (fun i -> S.of_z Z.(pow (of_int 2) i)) in + let sbits = List.map scalar_of_bool (of_list bits) in + let* sum = + foldM + (fun acc (qr, w) -> Num.add ~qr acc w) + (List.hd sbits) + List.(tl @@ combine powers sbits) + in + with_bool_check (equal sx sum) >* ret bits + +let of_b (B x) = x + +let get_checks_wire : bool repr t = + fun s -> ([], B (List.for_all (fun (B x) -> x) s)) + +let init_state = [] + +let with_label ~label t = + ignore label ; + t + +let get_result : 'a repr t -> 'a Input.t = + fun m -> + let s, r = m init_state in + let c = List.fold_left (fun a b -> a && b) true (List.map of_b s) in + assert c ; + (r, Input.default_check) diff --git a/src/lib_plompiler/solver.ml b/src/lib_plompiler/solver.ml new file mode 100644 index 000000000000..2fb12fcdf98f --- /dev/null +++ b/src/lib_plompiler/solver.ml @@ -0,0 +1,449 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +include Lang_core +module CS = Csir.CS +module VS = Linear_algebra.Make_VectorSpace (S) +module Tables = Csir.Tables + +type wire = A | B | C | D | E [@@deriving repr] + +type 'a tagged = Input of 'a | Output of 'a [@@deriving repr] + +type arith_desc = { + a : int; + b : int; + c : int; + d : int; + e : int; + ql : S.t; + qr : S.t; + qo : S.t; + qd : S.t; + qe : S.t; + qm : S.t; + qc : S.t; + qx5a : S.t; + qx2b : S.t; + to_solve : wire; +} +[@@deriving repr] + +type pow5_desc = {a : int; c : int} [@@deriving repr] + +type wires_desc = {a : int; b : int; c : int; d : int; e : int} +[@@deriving repr] + +type lookup_desc = { + a : int tagged; + b : int tagged; + c : int tagged; + d : int tagged; + e : int tagged; + table : string; +} +[@@deriving repr] + +type ws_desc = {x1 : int; y1 : int; x2 : int; y2 : int; x3 : int; y3 : int} +[@@deriving repr] + +type ed_desc = { + a : S.t; + d : S.t; + x1 : int; + y1 : int; + x2 : int; + y2 : int; + x3 : int; + y3 : int; +} +[@@deriving repr] + +type ed_cond_desc = { + a : S.t; + d : S.t; + x1 : int; + y1 : int; + x2 : int; + y2 : int; + bit : int; + x3 : int; + y3 : int; +} +[@@deriving repr] + +type bits_desc = {nb_bits : int; shift : Utils.Z.t; l : int; bits : int list} +[@@deriving repr] + +type pos128full_desc = { + x0 : int; + y0 : int; + x1 : int; + y1 : int; + x2 : int; + y2 : int; + k : VS.t array; + variant : Variants.t; +} + +type swap_desc = {b : int; x : int; y : int; u : int; v : int} [@@deriving repr] + +(* we define this by hand to avoid doing all linear algebra, VS.t is actually + S.t but for some reason Repr does not see this equality. *) +let pos128full_desc_t = + let open Repr in + record "pos128full_desc" (fun x0 y0 x1 y1 x2 y2 k variant -> + {x0; y0; x1; y1; x2; y2; k; variant}) + |+ field "x0" int (fun t -> t.x0) + |+ field "y0" int (fun t -> t.y0) + |+ field "x1" int (fun t -> t.x1) + |+ field "y1" int (fun t -> t.y1) + |+ field "x2" int (fun t -> t.x2) + |+ field "y2" int (fun t -> t.y2) + |+ field "k" (array S.t) (fun t -> t.k) + |+ field "variant" Variants.t (fun t -> t.variant) + |> sealr + +type pos128partial_desc = { + a : int; + b : int; + c : int; + a_5 : int; + b_5 : int; + c_5 : int; + x0 : int; + y0 : int; + x1 : int; + y1 : int; + x2 : int; + y2 : int; + (* Can we share these? *) + k_cols : VS.matrix array; + variant : Variants.t; +} + +let pos128partial_desc_t = + let open Repr in + record + "pos128partial_desc" + (fun a b c a_5 b_5 c_5 x0 y0 x1 y1 x2 y2 k_cols variant -> + {a; b; c; a_5; b_5; c_5; x0; y0; x1; y1; x2; y2; k_cols; variant}) + |+ field "a" int (fun t -> t.a) + |+ field "b" int (fun t -> t.b) + |+ field "c" int (fun t -> t.c) + |+ field "a_5" int (fun t -> t.a_5) + |+ field "b_5" int (fun t -> t.b_5) + |+ field "c_5" int (fun t -> t.c_5) + |+ field "x0" int (fun t -> t.x0) + |+ field "y0" int (fun t -> t.y0) + |+ field "x1" int (fun t -> t.x1) + |+ field "y1" int (fun t -> t.y1) + |+ field "x2" int (fun t -> t.x2) + |+ field "y2" int (fun t -> t.y2) + |+ field "k_cols" (array (array (array S.t))) (fun t -> t.k_cols) + |+ field "variant" Variants.t (fun t -> t.variant) + |> sealr + +type anemoi_desc = { + x0 : int; + y0 : int; + w : int; + v : int; + x1 : int; + y1 : int; + kx : S.t; + ky : S.t; +} + +let anemoi_desc_t = + let open Repr in + record "anemoi_desc" (fun x0 y0 w v x1 y1 kx ky -> + {x0; y0; w; v; x1; y1; kx; ky}) + |+ field "x0" int (fun t -> t.x0) + |+ field "y0" int (fun t -> t.y0) + |+ field "w" int (fun t -> t.w) + |+ field "v" int (fun t -> t.v) + |+ field "x1" int (fun t -> t.x1) + |+ field "y1" int (fun t -> t.y1) + |+ field "kx" S.t (fun t -> t.kx) + |+ field "ky" S.t (fun t -> t.ky) + |> sealr + +type anemoi_double_desc = { + x0 : int; + y0 : int; + w0 : int; + w1 : int; + y1 : int; + x2 : int; + y2 : int; + kx1 : S.t; + ky1 : S.t; + kx2 : S.t; + ky2 : S.t; +} +[@@deriving repr] + +type anemoi_custom_desc = { + x0 : int; + y0 : int; + x1 : int; + y1 : int; + x2 : int; + y2 : int; + kx1 : S.t; + ky1 : S.t; + kx2 : S.t; + ky2 : S.t; +} +[@@deriving repr] + +type solver_desc = + | Arith of arith_desc + | Pow5 of pow5_desc + | IsZero of wires_desc + | IsNotZero of wires_desc + | Lookup of lookup_desc + | Ecc_Ws of ws_desc + | Ecc_Ed of ed_desc + | Ecc_Cond_Ed of ed_cond_desc + | Swap of swap_desc + | Skip + | BitsOfS of bits_desc + | Poseidon128Full of pos128full_desc + | Poseidon128Partial of pos128partial_desc + | AnemoiRound of anemoi_desc + | AnemoiDoubleRound of anemoi_double_desc + | AnemoiCustom of anemoi_custom_desc + | Updater of Optimizer.trace_info +[@@deriving repr] + +type solvers = solver_desc list [@@deriving repr] + +type t = {solvers : solvers; initial_size : int; final_size : int} +[@@deriving repr] + +let empty_solver = {solvers = []; initial_size = 0; final_size = 0} + +let append_solver sd t = {t with solvers = sd :: t.solvers} + +let untag = function Input a -> a | Output a -> a + +let from_tagged = function Input i -> Some i | Output _ -> None + +let solve_one trace solver = + (match solver with + | Skip -> () + | Arith {a; b; c; d; e; ql; qr; qo; qd; qe; qm; qc; qx5a; qx2b; to_solve; _} + -> ( + (* A gate with degree strictly greater than 1 must be used on an input wire. + This is to avoid having several solutions for the same equation. + *) + match to_solve with + | C -> + let av = trace.(a) in + let bv = trace.(b) in + let dv = trace.(d) in + let ev = trace.(e) in + trace.(c) <- + S.( + ((ql * av) + (qr * bv) + (qd * dv) + (qe * ev) + + (qm * av * bv) + + (qx5a * pow av (Z.of_int 5)) + + (qx2b * (bv * bv)) + + qc) + / negate qo) + | A -> + assert (S.is_zero qx5a) ; + assert (S.is_zero qx2b) ; + let cv = trace.(c) in + let bv = trace.(b) in + let dv = trace.(d) in + let ev = trace.(e) in + trace.(a) <- + S.( + negate ((qr * bv) + (qo * cv) + (qd * dv) + (qe * ev) + qc) + / (ql + (bv * qm))) + | B -> + assert (S.is_zero qx5a) ; + assert (S.is_zero qx2b) ; + let cv = trace.(c) in + let av = trace.(a) in + let dv = trace.(d) in + let ev = trace.(e) in + trace.(b) <- + S.( + negate ((ql * av) + (qo * cv) + (qd * dv) + (qe * ev) + qc) + / (qr + (av * qm))) + | D | E -> raise @@ Failure "Solving for wires D or E is not allowed") + | Pow5 {a; c} -> trace.(c) <- S.pow trace.(a) (Z.of_int 5) + | Lookup {a; b; c; d; e; table} -> + let tbl = Tables.find table Csir.table_registry in + let wa, wb, wc, wd, we = Utils.map5 untag (a, b, c, d, e) in + let a, b, c, d, e = Utils.map5 from_tagged (a, b, c, d, e) in + let a, b, c, d, e = + Utils.map5 (Option.map (fun i -> trace.(i))) (a, b, c, d, e) + in + let entry = Option.get Csir.Table.(find {a; b; c; d; e} tbl) in + trace.(wa) <- entry.a ; + trace.(wb) <- entry.b ; + trace.(wc) <- entry.c ; + trace.(wd) <- entry.d ; + trace.(we) <- entry.e + | IsZero {a; b; c; _} -> + let av = trace.(a) in + trace.(c) <- S.(if av = zero then one else zero) ; + trace.(b) <- S.(if av = zero then one else S.div_exn one av) + | IsNotZero {a; b; c; _} -> + let av = trace.(a) in + trace.(c) <- S.(if av = zero then zero else one) ; + trace.(b) <- S.(if av = zero then one else S.div_exn one av) + | Ecc_Ws {x1; y1; x2; y2; x3; y3} -> + let x1, y1 = (trace.(x1), trace.(y1)) in + let x2, y2 = (trace.(x2), trace.(y2)) in + let lambda = S.(sub y2 y1 / sub x2 x1) in + let x3_v = S.(sub (lambda * lambda) (x1 + x2)) in + trace.(x3) <- x3_v ; + trace.(y3) <- S.(sub (lambda * sub x1 x3_v) y1) + | Ecc_Ed {a; d; x1; y1; x2; y2; x3; y3} -> + let x1, y1 = (trace.(x1), trace.(y1)) in + let x2, y2 = (trace.(x2), trace.(y2)) in + let x1x2 = S.(mul x1 x2) in + let y1y2 = S.(mul y1 y2) in + let denom = S.(d * x1x2 * y1y2) in + let x_res = S.(add (x1 * y2) (x2 * y1) / add one denom) in + let y_res = S.(sub y1y2 (a * x1x2) / sub one denom) in + trace.(x3) <- x_res ; + trace.(y3) <- y_res + | Ecc_Cond_Ed {a; d; x1; y1; x2; y2; bit; x3; y3} -> + let x1, y1 = (trace.(x1), trace.(y1)) in + let x2, y2 = (trace.(x2), trace.(y2)) in + let b = trace.(bit) in + let x2' = S.(mul b x2) in + let y2' = S.(add (mul b y2) (sub one b)) in + let x1x2' = S.(mul x1 x2') in + let y1y2' = S.(mul y1 y2') in + let denom = S.(d * x1x2' * y1y2') in + let x_res = S.(add (x1 * y2') (x2' * y1) / add one denom) in + let y_res = S.(sub y1y2' (a * x1x2') / sub one denom) in + trace.(x3) <- x_res ; + trace.(y3) <- y_res + | BitsOfS {nb_bits; shift; l; bits} -> + let x = trace.(l) |> S.to_z in + let x = Z.(x + shift) in + let binary_decomposition = Utils.bool_list_of_z ~nb_bits x in + List.iter2 + (fun b value -> trace.(b) <- (if value then S.one else S.zero)) + bits + binary_decomposition + | Updater ti -> ignore @@ Optimizer.trace_updater ti trace + | Swap {b; x; y; u; v} -> + let b, x, y = (trace.(b), trace.(x), trace.(y)) in + let x_res, y_res = if S.is_zero b then (x, y) else (y, x) in + trace.(u) <- x_res ; + trace.(v) <- y_res + | Poseidon128Full {x0; y0; x1; y1; x2; y2; k; variant} -> + let matrix = + Array.map (Array.map S.of_string) + @@ if variant = PFull128 then Mds_full.v else Mds_128.v + in + let pow5 x = S.pow trace.(x) (Z.of_int 5) in + let x_vec = [|Array.map pow5 [|x0; x1; x2|]|] |> VS.transpose in + let y_vec = VS.mul matrix x_vec in + List.iteri + (fun i yi -> trace.(yi) <- S.add k.(i) @@ y_vec.(i).(0)) + [y0; y1; y2] + | Poseidon128Partial + {a; b; c; a_5; b_5; c_5; x0; y0; x1; y1; x2; y2; k_cols; variant} -> + let matrix = + Array.map (Array.map S.of_string) + @@ if variant = PFull128 then Mds_full.v else Mds_128.v + in + let pow5 x = S.pow x (Z.of_int 5) in + let ppow5 v = [|v.(0); v.(1); [|pow5 v.(2).(0)|]|] in + let x_vec = [|[|trace.(x0)|]; [|trace.(x1)|]; [|trace.(x2)|]|] in + let a_vec = VS.(add (mul matrix @@ ppow5 x_vec) k_cols.(0)) in + let b_vec = VS.(add (mul matrix @@ ppow5 a_vec) k_cols.(1)) in + let c_vec = VS.(add (mul matrix @@ ppow5 b_vec) k_cols.(2)) in + let y_vec = VS.(add (mul matrix @@ ppow5 c_vec) k_cols.(3)) in + trace.(a) <- a_vec.(2).(0) ; + trace.(b) <- b_vec.(2).(0) ; + trace.(c) <- c_vec.(2).(0) ; + trace.(a_5) <- pow5 trace.(a) ; + trace.(b_5) <- pow5 trace.(b) ; + trace.(c_5) <- pow5 trace.(c) ; + trace.(y0) <- y_vec.(0).(0) ; + trace.(y1) <- y_vec.(1).(0) ; + trace.(y2) <- y_vec.(2).(0) + | AnemoiRound {x0; y0; w; v; x1; y1; kx; ky} -> + let _w_5', w', v', _u', x1', y1' = + Gadget_anemoi.Anemoi128.compute_one_round trace.(x0) trace.(y0) kx ky + in + trace.(w) <- w' ; + trace.(v) <- v' ; + trace.(x1) <- x1' ; + trace.(y1) <- y1' + | AnemoiDoubleRound {x0; y0; w0; w1; y1; x2; y2; kx1; ky1; kx2; ky2} -> + (* First round *) + let _w_5', w', _v', _u', x1', y1' = + Gadget_anemoi.Anemoi128.compute_one_round trace.(x0) trace.(y0) kx1 ky1 + in + (* Computing w *) + trace.(w0) <- w' ; + trace.(y1) <- y1' ; + (* Second round *) + let _w_5', w', _v', _u', x2', y2' = + Gadget_anemoi.Anemoi128.compute_one_round x1' y1' kx2 ky2 + in + trace.(w1) <- w' ; + trace.(x2) <- x2' ; + trace.(y2) <- y2' + | AnemoiCustom {x0; y0; x1; y1; x2; y2; kx1; ky1; kx2; ky2} -> + (* First round *) + let _w_5', _w', _v', _u', x1', y1' = + Gadget_anemoi.Anemoi128.compute_one_round trace.(x0) trace.(y0) kx1 ky1 + in + trace.(x1) <- x1' ; + trace.(y1) <- y1' ; + (* Second round *) + let _w_5', _w', _v', _u', x2', y2' = + Gadget_anemoi.Anemoi128.compute_one_round x1' y1' kx2 ky2 + in + trace.(x2) <- x2' ; + trace.(y2) <- y2') ; + trace + +let solve : t -> S.t array -> S.t array = + fun {solvers; initial_size; final_size} inputs -> + if Array.length inputs <> initial_size then + failwith + (Printf.sprintf + "input size (= %d) != initial_size (= %d)" + (Array.length inputs) + initial_size) ; + let dummy = + Array.(append inputs (init (final_size - length inputs) (fun _ -> S.zero))) + in + List.fold_left solve_one dummy (List.rev solvers) diff --git a/src/lib_plompiler/solver.mli b/src/lib_plompiler/solver.mli new file mode 100644 index 000000000000..915f6e0db675 --- /dev/null +++ b/src/lib_plompiler/solver.mli @@ -0,0 +1,191 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Lang_core +module CS = Csir.CS +open Linear_algebra.Make_VectorSpace(S) +module Tables = Csir.Tables + +type wire = A | B | C | D | E + +type 'a tagged = Input of 'a | Output of 'a + +val untag : 'a tagged -> 'a + +type arith_desc = { + a : int; + b : int; + c : int; + d : int; + e : int; + ql : S.t; + qr : S.t; + qo : S.t; + qd : S.t; + qe : S.t; + qm : S.t; + qc : S.t; + qx5a : S.t; + qx2b : S.t; + to_solve : wire; +} + +type pow5_desc = {a : int; c : int} + +type wires_desc = {a : int; b : int; c : int; d : int; e : int} + +type lookup_desc = { + a : int tagged; + b : int tagged; + c : int tagged; + d : int tagged; + e : int tagged; + table : string; +} + +type swap_desc = {b : int; x : int; y : int; u : int; v : int} + +type ws_desc = {x1 : int; y1 : int; x2 : int; y2 : int; x3 : int; y3 : int} + +type ed_desc = { + a : S.t; + d : S.t; + x1 : int; + y1 : int; + x2 : int; + y2 : int; + x3 : int; + y3 : int; +} + +type ed_cond_desc = { + a : S.t; + d : S.t; + x1 : int; + y1 : int; + x2 : int; + y2 : int; + bit : int; + x3 : int; + y3 : int; +} + +type bits_desc = {nb_bits : int; shift : Z.t; l : int; bits : int list} + +type pos128full_desc = { + x0 : int; + y0 : int; + x1 : int; + y1 : int; + x2 : int; + y2 : int; + k : S.t array; + variant : Variants.t; +} + +type pos128partial_desc = { + a : int; + b : int; + c : int; + a_5 : int; + b_5 : int; + c_5 : int; + x0 : int; + y0 : int; + x1 : int; + y1 : int; + x2 : int; + y2 : int; + k_cols : matrix array; + variant : Variants.t; +} + +type anemoi_desc = { + x0 : int; + y0 : int; + w : int; + v : int; + x1 : int; + y1 : int; + kx : S.t; + ky : S.t; +} + +type anemoi_double_desc = { + x0 : int; + y0 : int; + w0 : int; + w1 : int; + y1 : int; + x2 : int; + y2 : int; + kx1 : S.t; + ky1 : S.t; + kx2 : S.t; + ky2 : S.t; +} + +type anemoi_custom_desc = { + x0 : int; + y0 : int; + x1 : int; + y1 : int; + x2 : int; + y2 : int; + kx1 : S.t; + ky1 : S.t; + kx2 : S.t; + ky2 : S.t; +} + +type solver_desc = + | Arith of arith_desc + | Pow5 of pow5_desc + | IsZero of wires_desc + | IsNotZero of wires_desc + | Lookup of lookup_desc + | Ecc_Ws of ws_desc + | Ecc_Ed of ed_desc + | Ecc_Cond_Ed of ed_cond_desc + | Swap of swap_desc + | Skip + | BitsOfS of bits_desc + | Poseidon128Full of pos128full_desc + | Poseidon128Partial of pos128partial_desc + | AnemoiRound of anemoi_desc + | AnemoiDoubleRound of anemoi_double_desc + | AnemoiCustom of anemoi_custom_desc + | Updater of Optimizer.trace_info + +type solvers + +type t = {solvers : solvers; initial_size : int; final_size : int} +[@@deriving repr] + +val empty_solver : t + +val append_solver : solver_desc -> t -> t + +val solve : t -> S.t array -> S.t array diff --git a/src/lib_plompiler/utils.ml b/src/lib_plompiler/utils.ml new file mode 100644 index 000000000000..3740ab7574cc --- /dev/null +++ b/src/lib_plompiler/utils.ml @@ -0,0 +1,175 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module S = Csir.Scalar + +let map5 f (a, b, c, d, e) = (f a, f b, f c, f d, f e) + +(* Difference between the scalar order and the succeeding power of 2 *) +let alpha = Z.(shift_left one (Z.numbits S.order) - S.order) + +let bitlist : ?le:bool -> bytes -> bool list = + fun ?(le = false) b -> + let l = Bytes.length b in + let start = if le then 0 else l - 1 in + let stop = if le then l else -1 in + let next a = if le then a + 1 else a - 1 in + let rec loop_byte acc n = + if n = stop then acc + else + let byte = Bytes.get_uint8 b n in + let rec loop_bit acc m = + if m = 8 then acc + else + let mask = 1 lsl m in + let bit = byte land mask in + let bit = if bit = 0 then false else true in + loop_bit (bit :: acc) (m + 1) + in + let acc = loop_bit acc 0 in + loop_byte acc (next n) + in + List.rev @@ loop_byte [] start + +let bytes_of_hex hs = + let h = `Hex hs in + Hex.to_bytes h + +let bool_list_to_scalar : bool list -> S.t = + fun b_list -> + let res, _ = + List.fold_left + (fun (acc_res, acc_p) b -> + let acc_res = if b then S.(acc_res + acc_p) else acc_res in + let acc_p = S.double acc_p in + (acc_res, acc_p)) + (S.zero, S.one) + b_list + in + res + +(* We use little endian notation (the lsb is on the head) *) +let bool_list_to_z : bool list -> Z.t = + fun b_list -> + let res, _ = + List.fold_left + (fun (acc_res, acc_p) b -> + let acc_res = if b then Z.(acc_res + acc_p) else acc_res in + let acc_p = Z.(acc_p + acc_p) in + (acc_res, acc_p)) + (Z.zero, Z.one) + b_list + in + res + +(* We use little endian notation (the lsb is on the head) *) +let bool_list_of_z : ?nb_bits:int -> Z.t -> bool list = + fun ?nb_bits z -> + let two = Z.of_int 2 in + let rec aux bits z = function + | 0 -> List.rev bits + | n -> + let b = Z.(equal (z mod two) one) in + aux (b :: bits) (Z.div z two) (n - 1) + in + aux [] z @@ Option.value ~default:(Z.numbits z) nb_bits + +module Z = struct + include Z + + let t : t Repr.t = + Repr.( + map + bytes + (fun bs -> Z.of_bits (Bytes.unsafe_to_string bs)) + (fun s -> Z.to_bits s |> Bytes.of_string)) +end + +let rec transpose = function + | [] | [] :: _ -> [] + | rows -> List.(map hd rows :: (transpose @@ map tl rows)) + +let of_bytes repr bs = + Stdlib.Result.get_ok + @@ Repr.(unstage @@ of_bin_string repr) (Bytes.unsafe_to_string bs) + +let to_bytes repr e = + Bytes.unsafe_of_string @@ Repr.(unstage @@ to_bin_string repr) e + +let tables_cs_encoding_t : (string list * Csir.CS.t) Repr.t = + let open Repr in + pair (list string) Csir.CS.t + +let save_cs_to_file path tables cs = + (* let outc = open_out path in *) + (* let encoder = Jsonm.encoder (`Channel outc) in *) + (* Repr.encode_json tables_cs_encoding_t encoder (tables, cs); *) + (* close_out outc *) + let s = Repr.to_json_string tables_cs_encoding_t (tables, cs) in + let outc = open_out path in + output_string outc s ; + close_out outc + +let load_cs_from_file path = + if not (Sys.file_exists path) then + raise + @@ Invalid_argument + (Printf.sprintf "load_cs_from_file: %s does not exist." path) ; + (* let inc = open_in path in *) + (* let decoder = Jsonm.decoder (`Channel inc) in *) + (* let res = *) + (* Repr.decode_json tables_cs_encoding_t decoder |> Stdlib.Result.get_ok *) + (* in *) + (* close_in inc; *) + (* res *) + let inc = open_in path in + let content = really_input_string inc (in_channel_length inc) in + let res = + Repr.of_json_string tables_cs_encoding_t content |> Stdlib.Result.get_ok + in + close_in inc ; + res + +let get_circuit_id cs = + let serialized_bytes = to_bytes Csir.CS.t cs in + Hacl_star.Hacl.Blake2b_32.hash serialized_bytes 32 |> Hex.of_bytes |> Hex.show + +let circuit_dir = + match Sys.getenv_opt "TMPDIR" with + | None -> "/tmp/plompiler" + | Some dir -> dir ^ "/plompiler" + +let circuit_path s = + if not @@ Sys.file_exists circuit_dir then Sys.mkdir circuit_dir 0o755 ; + circuit_dir ^ "/" ^ s + +let dump_label_traces path (cs : Csir.CS.t) = + let outc = open_out path in + List.iter + Csir.CS.( + Array.iter (fun c -> + Printf.fprintf outc "%s 1\n" @@ String.concat "; " (List.rev c.label))) + cs ; + close_out outc diff --git a/src/lib_plompiler/variants.ml b/src/lib_plompiler/variants.ml new file mode 100644 index 000000000000..86db06a66ba0 --- /dev/null +++ b/src/lib_plompiler/variants.ml @@ -0,0 +1,26 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +type t = P128 | P252 | PFull128 [@@deriving repr] diff --git a/src/lib_plompiler/z3/assert_nonzero.z3 b/src/lib_plompiler/z3/assert_nonzero.z3 new file mode 100644 index 000000000000..b2e217657535 --- /dev/null +++ b/src/lib_plompiler/z3/assert_nonzero.z3 @@ -0,0 +1,40 @@ +;; MIT License +;; Copyright (c) 2022 Nomadic Labs +;; +;; Permission is hereby granted, free of charge, to any person obtaining a copy +;; of this software and associated documentation files (the Software), to deal +;; in the Software without restriction, including without limitation the rights +;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;; copies of the Software, and to permit persons to whom the Software is +;; furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in all +;; copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED AS'$'IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. + +;; [assert_nonzero x] is implemented as: +;; x * r = 1 +;; for some new variable r + +(declare-const x Real) +(declare-const r Real) + +;; Specification +(define-fun specification () Bool (not (= 0 x))) + +;; Constraints +(define-fun constraints () Bool (= 1 (* x r))) + +;; Check soundness +(assert (not (=> constraints specification))) + +(check-sat) +;; unsat +;; (get-model) diff --git a/src/lib_plompiler/z3/band.z3 b/src/lib_plompiler/z3/band.z3 new file mode 100644 index 000000000000..82e083983884 --- /dev/null +++ b/src/lib_plompiler/z3/band.z3 @@ -0,0 +1,53 @@ +;; MIT License +;; Copyright (c) 2022 Nomadic Labs +;; +;; Permission is hereby granted, free of charge, to any person obtaining a copy +;; of this software and associated documentation files (the Software), to deal +;; in the Software without restriction, including without limitation the rights +;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;; copies of the Software, and to permit persons to whom the Software is +;; furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in all +;; copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED AS'$'IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. + +;; band x y = 1 iff x = 1 && y = 1 + +(declare-const x Real) +(declare-const y Real) +(declare-const b Real) + +;; Specification +(define-fun pre-condition () Bool (and (or (= x 0) (= x 1)) + (or (= y 0) (= y 1)) + )) + +(define-fun specification () Bool + (and (=> (= 0 x) (= 0 b)) + (=> (= 0 y) (= 0 b)) + (=> (and (= 1 x) (= 1 y)) (= 1 b)) + ) +) + +(define-fun post-condition () Bool (or (= b 0) (= b 1))) + +;; Constraints +(define-fun constraints () Bool (= b (* x y))) + +;; Check soundness +(assert (not (=> constraints specification))) + +;; Check correctness +(assert (not (=> (and pre-condition specification) post-condition))) + +(check-sat) +;; unsat +;; (get-model) diff --git a/src/lib_plompiler/z3/bnot.z3 b/src/lib_plompiler/z3/bnot.z3 new file mode 100644 index 000000000000..fc237fca579a --- /dev/null +++ b/src/lib_plompiler/z3/bnot.z3 @@ -0,0 +1,47 @@ +;; MIT License +;; Copyright (c) 2022 Nomadic Labs +;; +;; Permission is hereby granted, free of charge, to any person obtaining a copy +;; of this software and associated documentation files (the Software), to deal +;; in the Software without restriction, including without limitation the rights +;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;; copies of the Software, and to permit persons to whom the Software is +;; furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in all +;; copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED AS'$'IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. + +;; bnot x = if x = 0 then 1 else 0 + +(declare-const x Real) +(declare-const b Real) + +;; Specification +(define-fun pre-condition () Bool (or (= x 0) (= x 1))) + +(define-fun specification () Bool (and (=> (= 0 x) (= 1 b)) + (=> (= 1 x) (= 0 b)) + )) + +(define-fun post-condition () Bool (or (= b 0) (= b 1))) + +;; Constraints +(define-fun constraints () Bool (= b (- 1 x))) + +;; Check soundness +(assert (not (=> constraints specification))) + +;; Check correctness +(assert (not (=> (and pre-condition specification) post-condition))) + +(check-sat) +;; unsat +;; (get-model) diff --git a/src/lib_plompiler/z3/bor.z3 b/src/lib_plompiler/z3/bor.z3 new file mode 100644 index 000000000000..15edb68425c5 --- /dev/null +++ b/src/lib_plompiler/z3/bor.z3 @@ -0,0 +1,47 @@ +;; MIT License +;; Copyright (c) 2022 Nomadic Labs +;; +;; Permission is hereby granted, free of charge, to any person obtaining a copy +;; of this software and associated documentation files (the Software), to deal +;; in the Software without restriction, including without limitation the rights +;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;; copies of the Software, and to permit persons to whom the Software is +;; furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in all +;; copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED AS'$'IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. + +;; bor x y = 0 iff x = 0 && y = 0 + +(declare-const x Real) +(declare-const y Real) +(declare-const b Real) + +;; Specification +(define-fun pre-condition () Bool (and (or (= x 0) (= x 1)) + (or (= y 0) (= y 1)) + )) + +(define-fun specification () Bool (and (=> (= 1 x) (= 1 b)) + (=> (= 1 y) (= 1 b)) + (=> (and (= 0 x) (= 0 y)) (= 0 b)) + )) + +;; Constraints +(declare-const constraints Bool) +(assert (= constraints (= b (+ x y (- (* x y)))))) + +;; Check soundness +(assert (not (=> constraints specification))) + +(check-sat) +;; unsat +;; (get-model) diff --git a/src/lib_plompiler/z3/div.z3 b/src/lib_plompiler/z3/div.z3 new file mode 100644 index 000000000000..549c1ab43627 --- /dev/null +++ b/src/lib_plompiler/z3/div.z3 @@ -0,0 +1,40 @@ +;; MIT License +;; Copyright (c) 2022 Nomadic Labs +;; +;; Permission is hereby granted, free of charge, to any person obtaining a copy +;; of this software and associated documentation files (the Software), to deal +;; in the Software without restriction, including without limitation the rights +;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;; copies of the Software, and to permit persons to whom the Software is +;; furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in all +;; copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED AS'$'IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. + +;; Division gate x / y = z + +(declare-const x Real) +(declare-const y Real) +(declare-const z Real) + +;; Specification +(define-fun specification () Bool (= z (/ x y))) + +;; Constraints +(define-fun constraints () Bool (and (= x (* y z)) + (not (= 0 y)) + )) +;; Check soundness +(assert (not (=> constraints specification))) + +(check-sat) +;; unsat +;; (get-model) diff --git a/src/lib_plompiler/z3/ifthenelse.z3 b/src/lib_plompiler/z3/ifthenelse.z3 new file mode 100644 index 000000000000..969fdb3f4793 --- /dev/null +++ b/src/lib_plompiler/z3/ifthenelse.z3 @@ -0,0 +1,54 @@ +;; MIT License +;; Copyright (c) 2022 Nomadic Labs +;; +;; Permission is hereby granted, free of charge, to any person obtaining a copy +;; of this software and associated documentation files (the Software), to deal +;; in the Software without restriction, including without limitation the rights +;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;; copies of the Software, and to permit persons to whom the Software is +;; furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in all +;; copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED AS'$'IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. + +;; ifthenelse b x y = +;; if b = 1 then x +;; else y +;; +;; (Our implementation works under the precondition that b is a bool.) + +(declare-const b Real) +(declare-const x Real) +(declare-const y Real) +(declare-const z Real) + +;; Specification + +(define-fun pre-condition () Bool (or (= x 0) (= x 1))) + +(define-fun specification () Bool (and (=> (= 1 b) (= z x)) + (=> (not (= 1 b)) (= z y)) + )) + +(define-fun post-condition () Bool (or (= x z) (= y z))) + +;; Constraints +(define-fun constraints () Bool (= z (+ (* x b) (* y (- 1 b))))) + +;; Check soundness +(assert (not (=> constraints specification))) + +;; Check correctness +(assert (not (=> (and pre-condition specification) post-condition))) + +(check-sat) +;; unsat +;; (get-model) diff --git a/src/lib_plompiler/z3/is_not_zero.z3 b/src/lib_plompiler/z3/is_not_zero.z3 new file mode 100644 index 000000000000..da5c027fad75 --- /dev/null +++ b/src/lib_plompiler/z3/is_not_zero.z3 @@ -0,0 +1,46 @@ +;; MIT License +;; Copyright (c) 2022 Nomadic Labs +;; +;; Permission is hereby granted, free of charge, to any person obtaining a copy +;; of this software and associated documentation files (the Software), to deal +;; in the Software without restriction, including without limitation the rights +;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;; copies of the Software, and to permit persons to whom the Software is +;; furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in all +;; copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED AS'$'IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. + +;; is_not_zero x = if x <> 0 then 1 else 0 +;; +;; is_not_zero x is defined as b such that: +;; b * (1 - b) = 0 +;; - b + x * r = 0 for some non-zero r + +(declare-const x Real) +(declare-const b Real) +(declare-const r Real) + +;; Specification +(define-fun specification () Bool (ite (= x 0) (= b 0) (= b 1))) + +;; Constraints +(define-fun constraints () Bool (and (= 0 (* b (- 1 b))) + (= 0 (- (* x r) b)) + (not (= 0 r)) + )) + +;; Check soundness +(assert (not (=> constraints specification))) + +(check-sat) +;; unsat +;; (get-model) diff --git a/src/lib_plompiler/z3/is_zero.z3 b/src/lib_plompiler/z3/is_zero.z3 new file mode 100644 index 000000000000..1148b0a0013d --- /dev/null +++ b/src/lib_plompiler/z3/is_zero.z3 @@ -0,0 +1,48 @@ +;; MIT License +;; Copyright (c) 2022 Nomadic Labs +;; +;; Permission is hereby granted, free of charge, to any person obtaining a copy +;; of this software and associated documentation files (the Software), to deal +;; in the Software without restriction, including without limitation the rights +;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;; copies of the Software, and to permit persons to whom the Software is +;; furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in all +;; copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED AS'$'IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. + +;; is_zero x = if x = 0 then 1 else 0 +;; +;; is_zero x is defined as b such that: +;; b * (1 - b) = 0 +;; b + x * r = 1 for some non-zero r + +(declare-const x Real) +(declare-const b Real) +(declare-const r Real) + +;; Specification +(define-fun specification () Bool (and (=> (= x 0) (= b 1)) + (=> (not (= x 0)) (= b 0)) + )) + +;; Constraints +(define-fun constraints () Bool (and (= 0 (* b (- 1 b))) + (= 1 (+ b (* x r))) + (not (= 0 r)) + )) + +;; Check soundness +(assert (not (=> constraints specification))) + +(check-sat) +;; unsat +;; (get-model) diff --git a/src/lib_plompiler/z3/run_z3_tests.sh b/src/lib_plompiler/z3/run_z3_tests.sh new file mode 100755 index 000000000000..afe6e8edf845 --- /dev/null +++ b/src/lib_plompiler/z3/run_z3_tests.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +for f in *.z3 +do + if z3 "$f" | grep -Fxq sat + then + echo "Z3 tests error: test $f is satisfiable" + exit 1 + fi +done +echo "Z3 tests passed!" diff --git a/src/lib_plompiler/z3/upper_bounded.z3 b/src/lib_plompiler/z3/upper_bounded.z3 new file mode 100644 index 000000000000..a4916a755d12 --- /dev/null +++ b/src/lib_plompiler/z3/upper_bounded.z3 @@ -0,0 +1,58 @@ +;; MIT License +;; Copyright (c) 2022 Nomadic Labs +;; +;; Permission is hereby granted, free of charge, to any person obtaining a copy +;; of this software and associated documentation files (the Software), to deal +;; in the Software without restriction, including without limitation the rights +;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;; copies of the Software, and to permit persons to whom the Software is +;; furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in all +;; copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED AS'$'IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. + +;; [assert_upper_bounded x] is satisfiable only if 0 <= x < 13 +;; +;; 13 is 1101 in binary +;; Implemented as: +;; b0 * (1 - b0) = 0 +;; b1 * (1 - b1) = 0 +;; b2 * (1 - b2) = 0 +;; b3 * (1 - b3) = 0 +;; x = b0 + 2 * b1 + 4 * b2 + 8 * b3 +;; not (b3 and (b2 and (b1 or (b0 and true)))) +;; 1 1 0 1 + +(declare-const x Real) +(declare-const b0 Real) +(declare-const b1 Real) +(declare-const b2 Real) +(declare-const b3 Real) + +;; Specification +(define-fun specification () Bool (and (<= 0 x) (< x 13))) + +;; Constraints +(define-fun constraints () Bool + (and (= 0 (* b0 (- 1 b0))) + (and (= 0 (* b1 (- 1 b1))) + (and (= 0 (* b2 (- 1 b2))) + (and (= 0 (* b3 (- 1 b3))) + (and (= x (+ b0 (+ (* 2 b1) (+ (* 4 b2) (* 8 b3))))) + (not (and (= 1 b3) (and (= 1 b2) (or (= 1 b1) (= 1 b0))))) + )))))) + +;; Check soundness +(assert (not (=> constraints specification))) + +(check-sat) +;; unsat +;; (get-model) diff --git a/src/lib_plompiler/z3/xor.z3 b/src/lib_plompiler/z3/xor.z3 new file mode 100644 index 000000000000..63c4acd3f76d --- /dev/null +++ b/src/lib_plompiler/z3/xor.z3 @@ -0,0 +1,54 @@ +;; MIT License +;; Copyright (c) 2022 Nomadic Labs +;; +;; Permission is hereby granted, free of charge, to any person obtaining a copy +;; of this software and associated documentation files (the Software), to deal +;; in the Software without restriction, including without limitation the rights +;; to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +;; copies of the Software, and to permit persons to whom the Software is +;; furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in all +;; copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED AS'$'IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +;; AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +;; LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +;; OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. + +;; xor x y = if x <> y then 1 else 0 + +(declare-const x Real) +(declare-const y Real) +(declare-const b Real) + +;; Specification +(define-fun pre-condition () Bool (and (or (= x 0) (= x 1)) + (or (= y 0) (= y 1)) + )) + +(define-fun specification () Bool (and (=> (and (= 0 x) (= 0 y)) (= 0 b)) + (=> (and (= 0 x) (= 1 y)) (= 1 b)) + (=> (and (= 1 x) (= 0 y)) (= 1 b)) + (=> (and (= 1 x) (= 1 y)) (= 0 b)) + )) + +(define-fun post-condition () Bool (or (= b 0) (= b 1))) + + +;; Constraints +(define-fun constraints () Bool (= b (+ x y (- (* 2 x y))))) + +;; Check soundness +(assert (not (=> constraints specification))) + +;; Check correctness +(assert (not (=> (and pre-condition specification) post-condition))) + + +(check-sat) +;; unsat +;; (get-model) diff --git a/src/proto_015_PtLimaPt/lib_protocol/test/helpers/dune b/src/proto_015_PtLimaPt/lib_protocol/test/helpers/dune index 13bea27a49c9..fc3a05a6f578 100644 --- a/src/proto_015_PtLimaPt/lib_protocol/test/helpers/dune +++ b/src/proto_015_PtLimaPt/lib_protocol/test/helpers/dune @@ -17,7 +17,7 @@ tezos-protocol-environment tezos-protocol-plugin-015-PtLimaPt tezos-shell-services - tezos-plompiler) + octez-plompiler) (flags (:standard) -open Tezos_test_helpers diff --git a/src/proto_016_PtMumbai/lib_protocol/test/helpers/dune b/src/proto_016_PtMumbai/lib_protocol/test/helpers/dune index 9d1ea997fc9e..7640e9ad4875 100644 --- a/src/proto_016_PtMumbai/lib_protocol/test/helpers/dune +++ b/src/proto_016_PtMumbai/lib_protocol/test/helpers/dune @@ -17,7 +17,7 @@ tezos-protocol-environment tezos-protocol-plugin-016-PtMumbai tezos-shell-services - tezos-plompiler + octez-plompiler tezos-crypto-dal) (flags (:standard) diff --git a/src/proto_alpha/lib_protocol/test/helpers/dune b/src/proto_alpha/lib_protocol/test/helpers/dune index e4336ec7c6fd..3baab9c7b3b0 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/dune +++ b/src/proto_alpha/lib_protocol/test/helpers/dune @@ -17,7 +17,7 @@ tezos-protocol-environment tezos-protocol-plugin-alpha tezos-shell-services - tezos-plompiler + octez-plompiler tezos-crypto-dal) (flags (:standard) -- GitLab From 82641c42ab1f9d4c4c4425b59da423efccf0f8a6 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Tue, 14 Mar 2023 13:43:20 +0100 Subject: [PATCH 11/34] Lib_plonk: import from privacy-team/cryptography --- .gitlab/ci/jobs/packaging/opam_package.yml | 77 +- dune-project | 1 + manifest/main.ml | 34 +- opam/octez-plonk.opam | 25 + opam/tezos-protocol-environment.opam | 2 +- opam/virtual/octez-deps.opam | 1 - src/lib_plonk/README.md | 10 + src/lib_plonk/arithmetic_gates.ml | 724 ++++++++++ src/lib_plonk/bls.ml | 46 + src/lib_plonk/boolean_gates.ml | 217 +++ src/lib_plonk/circuit.ml | 506 +++++++ src/lib_plonk/custom_gates.ml | 467 +++++++ src/lib_plonk/dune | 18 + src/lib_plonk/ecc_gates.ml | 720 ++++++++++ src/lib_plonk/evaluations_map.ml | 151 +++ src/lib_plonk/gates_common.ml | 210 +++ src/lib_plonk/hash_gates.ml | 291 ++++ src/lib_plonk/identities.ml | 89 ++ src/lib_plonk/input_commitment.ml | 57 + src/lib_plonk/list.ml | 159 +++ src/lib_plonk/main_protocol.ml | 1391 ++++++++++++++++++++ src/lib_plonk/main_protocol_intf.ml | 169 +++ src/lib_plonk/permutation_gate.ml | 614 +++++++++ src/lib_plonk/plookup_gate.ml | 641 +++++++++ src/lib_plonk/polynomial_commitment.ml | 399 ++++++ src/lib_plonk/polynomial_protocol.ml | 288 ++++ src/lib_plonk/range_check_gate.ml | 415 ++++++ src/lib_plonk/sMap.ml | 286 ++++ src/lib_plonk/utils.ml | 210 +++ src/lib_protocol_environment/dune | 2 +- src/lib_protocol_environment/structs/dune | 2 +- 31 files changed, 8189 insertions(+), 33 deletions(-) create mode 100644 opam/octez-plonk.opam create mode 100644 src/lib_plonk/README.md create mode 100644 src/lib_plonk/arithmetic_gates.ml create mode 100644 src/lib_plonk/bls.ml create mode 100644 src/lib_plonk/boolean_gates.ml create mode 100644 src/lib_plonk/circuit.ml create mode 100644 src/lib_plonk/custom_gates.ml create mode 100644 src/lib_plonk/dune create mode 100644 src/lib_plonk/ecc_gates.ml create mode 100644 src/lib_plonk/evaluations_map.ml create mode 100644 src/lib_plonk/gates_common.ml create mode 100644 src/lib_plonk/hash_gates.ml create mode 100644 src/lib_plonk/identities.ml create mode 100644 src/lib_plonk/input_commitment.ml create mode 100644 src/lib_plonk/list.ml create mode 100644 src/lib_plonk/main_protocol.ml create mode 100644 src/lib_plonk/main_protocol_intf.ml create mode 100644 src/lib_plonk/permutation_gate.ml create mode 100644 src/lib_plonk/plookup_gate.ml create mode 100644 src/lib_plonk/polynomial_commitment.ml create mode 100644 src/lib_plonk/polynomial_protocol.ml create mode 100644 src/lib_plonk/range_check_gate.ml create mode 100644 src/lib_plonk/sMap.ml create mode 100644 src/lib_plonk/utils.ml diff --git a/.gitlab/ci/jobs/packaging/opam_package.yml b/.gitlab/ci/jobs/packaging/opam_package.yml index 89c34577bf49..7601aed1f59e 100644 --- a/.gitlab/ci/jobs/packaging/opam_package.yml +++ b/.gitlab/ci/jobs/packaging/opam_package.yml @@ -238,7 +238,12 @@ opam:octez-baker-PtMumbai: # Ignoring unreleased package octez-baker-alpha. -# Ignoring unreleased package octez-bls12-381-hash. +opam:octez-bls12-381-hash: + extends: + - .opam_template + - .rules_template__trigger_opam_batch_7 + variables: + package: octez-bls12-381-hash opam:octez-bls12-381-polynomial: extends: @@ -288,7 +293,12 @@ opam:octez-injector: variables: package: octez-injector -# Ignoring unreleased package octez-mec. +opam:octez-mec: + extends: + - .opam_template + - .rules_template__trigger_opam_batch_7 + variables: + package: octez-mec opam:octez-node: extends: @@ -304,14 +314,31 @@ opam:octez-node-config: variables: package: octez-node-config -# Ignoring unreleased package octez-plompiler. +opam:octez-plompiler: + extends: + - .opam_template + - .rules_template__trigger_opam_batch_7 + variables: + package: octez-plompiler + +opam:octez-plonk: + extends: + - .opam_template + - .rules_template__trigger_opam_batch_7 + variables: + package: octez-plonk -# Ignoring unreleased package octez-polynomial. +opam:octez-polynomial: + extends: + - .opam_template + - .rules_template__trigger_opam_batch_7 + variables: + package: octez-polynomial opam:octez-protocol-compiler: extends: - .opam_template - - .rules_template__trigger_opam_batch_5 + - .rules_template__trigger_opam_batch_4 variables: package: octez-protocol-compiler @@ -434,7 +461,7 @@ opam:tezos-baking-alpha-commands: opam:tezos-base: extends: - .opam_template - - .rules_template__trigger_opam_batch_7 + - .rules_template__trigger_opam_batch_6 variables: package: tezos-base @@ -535,7 +562,7 @@ opam:tezos-client-007-PsDELPH1: opam:tezos-client-008-PtEdo2Zk: extends: - .opam_template - - .rules_template__trigger_opam_batch_3 + - .rules_template__trigger_opam_batch_2 variables: package: tezos-client-008-PtEdo2Zk @@ -619,7 +646,7 @@ opam:tezos-client-base-unix: opam:tezos-client-commands: extends: - .opam_template - - .rules_template__trigger_opam_batch_6 + - .rules_template__trigger_opam_batch_5 variables: package: tezos-client-commands @@ -633,7 +660,7 @@ opam:tezos-client-demo-counter: opam:tezos-client-genesis: extends: - .opam_template - - .rules_template__trigger_opam_batch_3 + - .rules_template__trigger_opam_batch_2 variables: package: tezos-client-genesis @@ -953,14 +980,14 @@ opam:tezos-mockup-commands: opam:tezos-mockup-proxy: extends: - .opam_template - - .rules_template__trigger_opam_batch_5 + - .rules_template__trigger_opam_batch_4 variables: package: tezos-mockup-proxy opam:tezos-mockup-registration: extends: - .opam_template - - .rules_template__trigger_opam_batch_5 + - .rules_template__trigger_opam_batch_4 variables: package: tezos-mockup-registration @@ -1143,14 +1170,14 @@ opam:tezos-protocol-demo-noops: opam:tezos-protocol-environment: extends: - .opam_template - - .rules_template__trigger_opam_batch_6 + - .rules_template__trigger_opam_batch_5 variables: package: tezos-protocol-environment opam:tezos-protocol-genesis: extends: - .opam_template - - .rules_template__trigger_opam_batch_6 + - .rules_template__trigger_opam_batch_5 variables: package: tezos-protocol-genesis @@ -1178,7 +1205,7 @@ opam:tezos-protocol-plugin-008-PtEdo2Zk: opam:tezos-protocol-plugin-008-PtEdo2Zk-registerer: extends: - .opam_template - - .rules_template__trigger_opam_batch_2 + - .rules_template__trigger_opam_batch_1 variables: package: tezos-protocol-plugin-008-PtEdo2Zk-registerer @@ -1285,7 +1312,7 @@ opam:tezos-protocol-plugin-015-PtLimaPt-registerer: opam:tezos-protocol-plugin-016-PtMumbai: extends: - .opam_template - - .rules_template__trigger_opam_batch_4 + - .rules_template__trigger_opam_batch_3 variables: package: tezos-protocol-plugin-016-PtMumbai @@ -1301,7 +1328,7 @@ opam:tezos-protocol-plugin-016-PtMumbai-registerer: opam:tezos-protocol-plugin-alpha: extends: - .opam_template - - .rules_template__trigger_opam_batch_4 + - .rules_template__trigger_opam_batch_3 variables: package: tezos-protocol-plugin-alpha @@ -1352,7 +1379,7 @@ opam:tezos-rpc: opam:tezos-rpc-http: extends: - .opam_template - - .rules_template__trigger_opam_batch_7 + - .rules_template__trigger_opam_batch_6 variables: package: tezos-rpc-http @@ -1407,7 +1434,7 @@ opam:tezos-scoru-wasm-fast: opam:tezos-scoru-wasm-helpers: extends: - .opam_template - - .rules_template__trigger_opam_batch_6 + - .rules_template__trigger_opam_batch_5 variables: package: tezos-scoru-wasm-helpers @@ -1427,7 +1454,7 @@ opam:tezos-shell: opam:tezos-shell-context: extends: - .opam_template - - .rules_template__trigger_opam_batch_6 + - .rules_template__trigger_opam_batch_5 variables: package: tezos-shell-context @@ -1464,7 +1491,7 @@ opam:tezos-smart-rollup-016-PtMumbai: opam:tezos-smart-rollup-alpha: extends: - .opam_template - - .rules_template__trigger_opam_batch_5 + - .rules_template__trigger_opam_batch_4 variables: package: tezos-smart-rollup-alpha @@ -1508,7 +1535,7 @@ opam:tezos-test-helpers: opam:tezos-test-helpers-extra: extends: - .opam_template - - .rules_template__trigger_opam_batch_7 + - .rules_template__trigger_opam_batch_6 variables: package: tezos-test-helpers-extra @@ -1535,14 +1562,14 @@ opam:tezos-tx-rollup-015-PtLimaPt: opam:tezos-validation: extends: - .opam_template - - .rules_template__trigger_opam_batch_4 + - .rules_template__trigger_opam_batch_3 variables: package: tezos-validation opam:tezos-version: extends: - .opam_template - - .rules_template__trigger_opam_batch_7 + - .rules_template__trigger_opam_batch_6 variables: package: tezos-version @@ -1570,7 +1597,7 @@ opam:tezos-webassembly-interpreter-extra: opam:tezos-workers: extends: - .opam_template - - .rules_template__trigger_opam_batch_7 + - .rules_template__trigger_opam_batch_6 variables: package: tezos-workers @@ -1586,6 +1613,6 @@ opam:tezt-performance-regression: opam:tezt-tezos: extends: - .opam_template - - .rules_template__trigger_opam_batch_7 + - .rules_template__trigger_opam_batch_6 variables: package: tezt-tezos diff --git a/dune-project b/dune-project index c893c1c7167b..e1d475aeeadb 100644 --- a/dune-project +++ b/dune-project @@ -24,6 +24,7 @@ (package (name octez-node)) (package (name octez-node-config)) (package (name octez-plompiler)) +(package (name octez-plonk)) (package (name octez-polynomial)) (package (name octez-protocol-compiler)) (package (name octez-proxy-server)) diff --git a/manifest/main.ml b/manifest/main.ml index 458608d4f1ec..b49d5269abc9 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -243,8 +243,6 @@ let ometrics = opam_only "ometrics" V.(at_least "0.2.1") let ppx_expect = inline_tests_backend (external_lib "ppx_expect" V.True) -let plonk = external_lib "tezos-plonk" V.(at_least "1.0.1" && less_than "2.0.0") - let ptime = external_lib ~js_compatible:true "ptime" V.(at_least "1.0.0") let ppx_import = external_lib "ppx_import" V.True @@ -1189,6 +1187,34 @@ let octez_plompiler = ~action:[S "chdir"; S "z3"; [S "run"; S "sh"; S "run_z3_tests.sh"]]; ] +let octez_plonk = + public_lib + "octez-plonk" + ~internal_name:"plonk" + ~path:"src/lib_plonk" + ~synopsis:"Plonk zero-knowledge proving system" + ~deps: + [ + repr; + hacl_star; + data_encoding; + octez_bls12_381_polynomial |> open_; + octez_plompiler |> open_; + ] + ~preprocess:[pps ppx_repr] + +(* let _octez_plonk_tests = *) +(* private_lib *) +(* "octez-plonk.plonk-test" *) +(* ~path:"src/lib_plonk/test" *) +(* ~synopsis:"Test framework for Plonk zero-knowledge proving system test" *) +(* ~deps: *) +(* [ *) +(* octez_plonk; *) +(* ] *) +(* ~modules:["helpers"; "cases"] *) + + let _octez_srs_extraction_tests = tests ["main"] @@ -2425,7 +2451,7 @@ let octez_protocol_environment_structs = octez_scoru_wasm; data_encoding; bls12_381; - plonk; + octez_plonk; ] let octez_protocol_environment = @@ -2454,7 +2480,7 @@ protocols.|} zarith; zarith_stubs_js; bls12_381; - plonk; + octez_plonk; octez_crypto_dal; vdf; aches; diff --git a/opam/octez-plonk.opam b/opam/octez-plonk.opam new file mode 100644 index 000000000000..39110858ecda --- /dev/null +++ b/opam/octez-plonk.opam @@ -0,0 +1,25 @@ +# This file was automatically generated, do not edit. +# Edit file manifest/main.ml instead. +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: ["Tezos devteam"] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "3.0" } + "ocaml" { >= "4.14" } + "ppx_repr" { >= "0.6.0" } + "repr" + "hacl-star" { >= "0.6.1" & < "0.7" } + "data-encoding" { >= "0.7.1" & < "1.0.0" } + "octez-bls12-381-polynomial" + "octez-plompiler" +] +build: [ + ["rm" "-r" "vendors"] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Plonk zero-knowledge proving system" diff --git a/opam/tezos-protocol-environment.opam b/opam/tezos-protocol-environment.opam index 4fa17ffc4aa0..3118275a9c56 100644 --- a/opam/tezos-protocol-environment.opam +++ b/opam/tezos-protocol-environment.opam @@ -16,7 +16,7 @@ depends: [ "tezos-scoru-wasm" "data-encoding" { >= "0.7.1" & < "1.0.0" } "bls12-381" { >= "6.1.0" & < "6.2.0" } - "tezos-plonk" { >= "1.0.1" & < "2.0.0" } + "octez-plonk" "zarith" { >= "1.12" & < "1.13" } "zarith_stubs_js" "tezos-crypto-dal" diff --git a/opam/virtual/octez-deps.opam b/opam/virtual/octez-deps.opam index 25d4404f77d1..ddb9b18d7042 100644 --- a/opam/virtual/octez-deps.opam +++ b/opam/virtual/octez-deps.opam @@ -91,7 +91,6 @@ depends: [ "stdint" "tar" "tar-unix" { >= "2.0.1" & < "3.0.0" } - "tezos-plonk" { >= "1.0.1" & < "2.0.0" } "tezos-rust-libs" { = "1.5" } "tezt" { >= "3.0.0" } "tls-lwt" { >= "0.16.0" } diff --git a/src/lib_plonk/README.md b/src/lib_plonk/README.md new file mode 100644 index 000000000000..76192e09f43c --- /dev/null +++ b/src/lib_plonk/README.md @@ -0,0 +1,10 @@ +make sure to remove and unpin polynomial, polynomial-sig and plonk, then opam should install all the necessary dependencies. +``` +opam install . +``` + +Otherwise you can manually pin: +``` +opam pin add polynomial-sig.dev git+https://gitlab.com/dannywillems/ocaml-polynomial.git#61639af77c2737c117c837bd77d3a54f20627bd6 +opam pin add polynomial.dev git+https://gitlab.com/dannywillems/ocaml-polynomial.git#61639af77c2737c117c837bd77d3a54f20627bd6 +``` diff --git a/src/lib_plonk/arithmetic_gates.ml b/src/lib_plonk/arithmetic_gates.ml new file mode 100644 index 000000000000..2b05f53b2a29 --- /dev/null +++ b/src/lib_plonk/arithmetic_gates.ml @@ -0,0 +1,724 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Bls +open Identities +module L = Plompiler.LibCircuit +open Gates_common + +module type Params = sig + val wire : string + + val selector : string + + val is_next : bool + + val cs : + q:L.scalar L.repr -> + a:L.scalar L.repr -> + b:L.scalar L.repr -> + c:L.scalar L.repr -> + d:L.scalar L.repr -> + e:L.scalar L.repr -> + ag:L.scalar L.repr -> + bg:L.scalar L.repr -> + cg:L.scalar L.repr -> + dg:L.scalar L.repr -> + eg:L.scalar L.repr -> + ?precomputed_advice:L.scalar L.repr SMap.t -> + unit -> + L.scalar L.repr list L.t +end + +(* General functor to create Artih monomial gate that add wire *) +module AddWire (Params : Params) : Base_sig = struct + let q_label = Params.selector + + let identity = (arith, 1) + + let index_com = None + + let nb_advs = 0 + + let nb_buffers = 1 + + let gx_composition = Params.is_next + + let equations ~q ~a ~b ~c ~d ~e ~ag ~bg ~cg ~dg ~eg ?precomputed_advice:_ () = + let var = + match Params.wire with + | s when s = left -> if Params.is_next then ag else a + | s when s = right -> if Params.is_next then bg else b + | s when s = output -> if Params.is_next then cg else c + | s when s = top -> if Params.is_next then dg else d + | s when s = bottom -> if Params.is_next then eg else e + | _ -> assert false + in + Scalar.[q * var] + + let blinds = + let array = if Params.is_next then [|0; 1|] else [|1; 0|] in + SMap.singleton Params.wire array + + let prover_identities ~prefix_common ~prefix ~public:_ ~domain : + prover_identities = + fun evaluations -> + let tmps, _ = get_buffers ~nb_buffers ~nb_ids:0 in + let poly_names = [prefix_common q_label; prefix Params.wire] in + let composition_gx = + if Params.is_next then ([0; 1], Domain.length domain) else ([0; 0], 1) + in + + let res = + Evaluations.mul ~res:tmps.(0) ~evaluations ~poly_names ~composition_gx () + in + SMap.singleton (prefix @@ arith ^ ".0") res + + let verifier_identities ~prefix_common ~prefix ~public:_ ~generator:_ + ~size_domain:_ : verifier_identities = + fun _ answers -> + let q = get_answer answers X @@ prefix_common q_label in + let w = + let p = if Params.is_next then GX else X in + get_answer answers p @@ prefix Params.wire + in + let res = Scalar.mul q w in + SMap.singleton (prefix @@ arith ^ ".0") res + + let polynomials_degree = SMap.of_list [(Params.wire, 2); (q_label, 2)] + + let cs = Params.cs +end + +(* Add next output gate + Arith monomial + degree : 2n + advice selectors : None + equations : + q·c +*) +module AddOutput = AddWire (struct + let wire = output + + let selector = "qo" + + let is_next = false + + let cs ~q:qo ~a:_ ~b:_ ~c ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + map_singleton (L.Num.mul qo c) +end) + +(* Add next left gate + Arith monomial + degree : 2n + advice selectors : None + equations : + q·a +*) +module AddLeft = AddWire (struct + let wire = left + + let selector = "ql" + + let is_next = false + + let cs ~q:ql ~a ~b:_ ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + map_singleton (L.Num.mul ql a) +end) + +(* Add next right gate + Arith monomial + degree : 2n + advice selectors : None + equations : + q·b +*) +module AddRight = AddWire (struct + let wire = right + + let selector = "qr" + + let is_next = false + + let cs ~q:qr ~a:_ ~b ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + map_singleton (L.Num.mul qr b) +end) + +(* Add top gate + Arith monomial + degree : 2n + advice selectors : None + equations : + q·d +*) +module AddTop = AddWire (struct + let wire = top + + let selector = "qd" + + let is_next = false + + let cs ~q:qd ~a:_ ~b:_ ~c:_ ~d ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + map_singleton (L.Num.mul qd d) +end) + +(* Add bottom gate + Arith monomial + degree : 2n + advice selectors : None + equations : + q·e +*) +module AddBottom = AddWire (struct + let wire = bottom + + let selector = "qe" + + let is_next = false + + let cs ~q:qe ~a:_ ~b:_ ~c:_ ~d:_ ~e ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + map_singleton (L.Num.mul qe e) +end) + +(* Add next output gate + Arith monomial + degree : 2n + advice selectors : None + equations : + q·cg +*) +module AddNextOutput = AddWire (struct + let wire = output + + let selector = "qog" + + let is_next = true + + let cs ~q:qog ~a:_ ~b:_ ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + map_singleton (L.Num.mul qog cg) +end) + +(* Add next left gate + Arith monomial + degree : 2n + advice selectors : None + equations : + q·ag +*) +module AddNextLeft = AddWire (struct + let wire = left + + let selector = "qlg" + + let is_next = true + + let cs ~q:qlg ~a:_ ~b:_ ~c:_ ~d:_ ~e:_ ~ag ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + map_singleton (L.Num.mul qlg ag) +end) + +(* Add next right gate + Arith monomial + degree : 2n + advice selectors : None + equations : + q·bg +*) +module AddNextRight = AddWire (struct + let wire = right + + let selector = "qrg" + + let is_next = true + + let cs ~q:qrg ~a:_ ~b:_ ~c:_ ~d:_ ~e:_ ~ag:_ ~bg ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + map_singleton (L.Num.mul qrg bg) +end) + +(* Add next top gate + Arith monomial + degree : 2n + advice selectors : None + equations : + q·dg +*) +module AddNextTop = AddWire (struct + let wire = top + + let selector = "qdg" + + let is_next = true + + let cs ~q:qdg ~a:_ ~b:_ ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg ~eg:_ + ?precomputed_advice:_ () = + map_singleton (L.Num.mul qdg dg) +end) + +(* Add next bottom gate + Arith monomial + degree : 2n + advice selectors : None + equations : + q·eg +*) +module AddNextBottom = AddWire (struct + let wire = bottom + + let selector = "qeg" + + let is_next = true + + let cs ~q:qeg ~a:_ ~b:_ ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg + ?precomputed_advice:_ () = + map_singleton (L.Num.mul qeg eg) +end) + +(* Add constant + Arith monomial + degree : n + advice selectors : None + equations : + q +*) +module Constant : Base_sig = struct + let q_label = "qc" + + let identity = (arith, 1) + + let index_com = None + + let nb_advs = 0 + + let nb_buffers = 1 + + let gx_composition = false + + let equations ~q ~a:_ ~b:_ ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + [q] + + let blinds = SMap.empty + + let prover_identities ~prefix_common ~prefix ~public:_ ~domain:_ : + prover_identities = + fun evaluations -> + let tmps, _ = get_buffers ~nb_buffers ~nb_ids:0 in + + (* This is copied because in sum_prover_queries it could + be overwritten by the inplace addition. *) + let res = + Evaluations.copy + ~res:tmps.(0) + (SMap.find (prefix_common q_label) evaluations) + in + SMap.singleton (prefix @@ arith ^ ".0") res + + let verifier_identities ~prefix_common ~prefix ~public:_ ~generator:_ + ~size_domain:_ : verifier_identities = + fun _ answers -> + let res = get_answer answers X @@ prefix_common q_label in + SMap.singleton (prefix @@ arith ^ ".0") res + + let polynomials_degree = SMap.empty + + let cs ~q:qc ~a:_ ~b:_ ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + L.ret [qc] +end + +(* Add multiplication + Arith monomial + degree : 3n + advice selectors : None + equations : + q·a·b +*) +module Multiplication : Base_sig = struct + let q_label = "qm" + + let identity = (arith, 1) + + let index_com = None + + let nb_advs = 0 + + let nb_buffers = 1 + + let gx_composition = false + + let equations ~q ~a ~b ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + Scalar.[q * a * b] + + let blinds = SMap.of_list [(right, [|1; 0|]); (left, [|1; 0|])] + + let prover_identities ~prefix_common ~prefix ~public:_ ~domain:_ : + prover_identities = + fun evaluations -> + let tmps, _ = get_buffers ~nb_buffers ~nb_ids:0 in + let ({q; a; b; _} : witness) = + get_evaluations ~q_label ~blinds ~prefix ~prefix_common evaluations + in + + let res = Evaluations.mul_c ~res:tmps.(0) ~evaluations:[q; a; b] () in + SMap.singleton (prefix @@ arith ^ ".0") res + + let verifier_identities ~prefix_common ~prefix ~public:_ ~generator:_ + ~size_domain:_ : verifier_identities = + fun _ answers -> + let ({q; a; b; _} : answers) = + get_answers ~q_label ~blinds ~prefix ~prefix_common answers + in + let res = Scalar.(q * a * b) in + SMap.singleton (prefix @@ arith ^ ".0") res + + let polynomials_degree = SMap.of_list [(left, 3); (right, 3); (q_label, 3)] + + let cs ~q:qm ~a ~b ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + let open L in + map_singleton + (let* tmp = Num.mul qm a in + Num.mul tmp b) +end + +(* Add right² + Arith monomial + degree : 6n + advice selectors : None + equations : + q·b² +*) +module X2B : Base_sig = struct + let q_label = "qx2b" + + let identity = (arith, 1) + + let index_com = None + + let nb_advs = 0 + + let nb_buffers = 1 + + let gx_composition = false + + let equations ~q ~a:_ ~b ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + Scalar.[q * square b] + + let blinds = SMap.singleton right [|1; 0|] + + let prover_identities ~prefix_common ~prefix ~public:_ ~domain:_ : + prover_identities = + fun evaluations -> + let tmps, _ = get_buffers ~nb_buffers ~nb_ids:0 in + let ({q; b; _} : witness) = + get_evaluations ~q_label ~blinds ~prefix ~prefix_common evaluations + in + + let res = + Evaluations.mul_c ~res:tmps.(0) ~evaluations:[q; b] ~powers:[1; 2] () + in + SMap.singleton (prefix @@ arith ^ ".0") res + + let verifier_identities ~prefix_common ~prefix ~public:_ ~generator:_ + ~size_domain:_ : verifier_identities = + fun _ answers -> + let ({q; b; _} : answers) = + get_answers ~q_label ~blinds ~prefix ~prefix_common answers + in + let res = Scalar.(q * square b) in + SMap.singleton (prefix @@ arith ^ ".0") res + + let polynomials_degree = SMap.of_list [(right, 3); (q_label, 3)] + + let cs ~q:qx2b ~a:_ ~b ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + let open L in + map_singleton + (let* b2 = Num.square b in + Num.mul qx2b b2) +end + +(* Add left⁵ + Arith monomial + degree : 6n + advice selectors : None + equations : + q·a⁵ +*) +module X5A : Base_sig = struct + let q_label = "qx5a" + + let identity = (arith, 1) + + let index_com = None + + let nb_advs = 0 + + let nb_buffers = 1 + + let gx_composition = false + + let equations ~q ~a ~b:_ ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + Scalar.[q * pow a (Z.of_int 5)] + + let blinds = SMap.singleton left [|1; 0|] + + let prover_identities ~prefix_common ~prefix ~public:_ ~domain:_ : + prover_identities = + fun evaluations -> + let tmps, _ = get_buffers ~nb_buffers ~nb_ids:0 in + let ({q; a; _} : witness) = + get_evaluations ~q_label ~blinds ~prefix ~prefix_common evaluations + in + + let res = + Evaluations.mul_c ~res:tmps.(0) ~evaluations:[q; a] ~powers:[1; 5] () + in + SMap.singleton (prefix @@ arith ^ ".0") res + + let verifier_identities ~prefix_common ~prefix ~public:_ ~generator:_ + ~size_domain:_ : verifier_identities = + fun _ answers -> + let ({q; a; _} : answers) = + get_answers ~q_label ~blinds ~prefix ~prefix_common answers + in + let a2 = Scalar.mul a a in + let a4 = Scalar.mul a2 a2 in + let a5 = Scalar.mul a4 a in + let res = Scalar.mul q a5 in + SMap.singleton (prefix @@ arith ^ ".0") res + + let polynomials_degree = SMap.of_list [(left, 6); (q_label, 6)] + + let cs ~q:qx5 ~a ~b:_ ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + let open L in + map_singleton + (let* a5 = Num.pow5 a in + Num.mul qx5 a5) +end + +(* Add output⁵ + Arith monomial + degree : 6n + advice selectors : None + equations : + q·c⁵ +*) +module X5C : Base_sig = struct + let q_label = "qx5c" + + let identity = (arith, 1) + + let index_com = None + + let nb_advs = 0 + + let nb_buffers = 1 + + let gx_composition = false + + let equations ~q ~a:_ ~b:_ ~c ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + Scalar.[q * pow c (Z.of_int 5)] + + let blinds = SMap.singleton output [|1; 0|] + + let prover_identities ~prefix_common ~prefix ~public:_ ~domain:_ : + prover_identities = + fun evaluations -> + let tmps, _ = get_buffers ~nb_buffers ~nb_ids:0 in + let ({q; c; _} : witness) = + get_evaluations ~q_label ~blinds ~prefix ~prefix_common evaluations + in + + let res = + Evaluations.mul_c ~res:tmps.(0) ~evaluations:[q; c] ~powers:[1; 5] () + in + SMap.singleton (prefix @@ arith ^ ".0") res + + let verifier_identities ~prefix_common ~prefix ~public:_ ~generator:_ + ~size_domain:_ : verifier_identities = + fun _ answers -> + let ({q; c; _} : answers) = + get_answers ~q_label ~blinds ~prefix ~prefix_common answers + in + let c2 = Scalar.mul c c in + let c4 = Scalar.mul c2 c2 in + let c5 = Scalar.mul c4 c in + let res = Scalar.mul q c5 in + SMap.singleton (prefix @@ arith ^ ".0") res + + let polynomials_degree = SMap.of_list [(output, 6); (q_label, 6)] + + let cs ~q:qx5c ~a:_ ~b:_ ~c ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + let open L in + map_singleton + (let* c5 = Num.pow5 c in + Num.mul qx5c c5) +end + +(* Add public input polynomial + Arith monomial + degree : n + advice selectors : None + equations : + q·a·b +*) +module Public : Base_sig = struct + let q_label = "qpub" + + let blinds = SMap.empty + + let identity = (arith, 1) + + let index_com = None + + let nb_advs = 0 + + let nb_buffers = 0 + + let gx_composition = false + + let equations ~q:_ ~a:_ ~b:_ ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + Scalar.[zero] + + let compute_PI ~start public_inputs domain evaluations = + let size_domain = Domain.length domain in + if size_domain = 0 then Evaluations.zero + else + let l = Array.length public_inputs in + let scalars = + Array.( + concat + [ + init start (fun _ -> Scalar.zero); + public_inputs; + init (size_domain - l - start) (fun _ -> Scalar.zero); + ]) + in + let pi = + Poly.(opposite (Evaluations.interpolation_fft2 domain scalars)) + in + let domain = Evaluations.get_domain evaluations in + Evaluations.evaluation_fft domain pi + + let prover_identities ~prefix_common:_ ~prefix ~public ~domain : + prover_identities = + fun evaluations -> + let res = + compute_PI + ~start:public.input_coms_size + public.public_inputs + domain + evaluations + in + SMap.singleton (prefix @@ arith ^ ".0") res + + let verifier_identities ~prefix_common:_ ~prefix ~public ~generator + ~size_domain : verifier_identities = + fun x _ -> + let res = + if size_domain = 0 then Scalar.zero + else + let g = Scalar.inverse_exn generator in + let f (acc, gix) wi = + let den = Scalar.(sub gix one) in + Scalar.(acc + (wi / den), g * gix) + in + let res, _ = + let shift = public.input_coms_size in + let gx_init = Scalar.(pow generator Z.(neg (of_int shift)) * x) in + Array.fold_left f Scalar.(zero, gx_init) public.public_inputs + in + let n = size_domain in + let xn = Scalar.pow x (Z.of_int n) in + let xn_min_one_div_n = Scalar.(sub xn one / of_int n) in + Scalar.(negate (xn_min_one_div_n * res)) + in + SMap.singleton (prefix @@ arith ^ ".0") res + + let polynomials_degree = SMap.empty + + (* this function will not be used *) + let cs ~q:_ ~a:_ ~b:_ ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + let open L in + ret [] +end + +(* Add idx-th input com polynomial + Arith monomial + degree : 2n + advice selectors : None + equations : + q·com_idx +*) +module InputCom (Com : sig + val idx : int +end) : Base_sig = struct + let q_label = "qcom" ^ string_of_int Com.idx + + let com_label = com_label ^ string_of_int Com.idx + + let blinds = SMap.empty + + let identity = (arith, 1) + + let index_com = Some Com.idx + + let nb_advs = 0 + + let nb_buffers = 0 + + let gx_composition = false + + let equations ~q:_ ~a:_ ~b:_ ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + Scalar.[zero] + + let prover_identities ~prefix_common ~prefix ~public:_ ~domain:_ : + prover_identities = + fun evaluations -> + let _tmps, ids = get_buffers ~nb_buffers ~nb_ids:(snd identity) in + let {q; _} = + get_evaluations ~q_label ~blinds ~prefix ~prefix_common evaluations + in + let com = Evaluations.find_evaluation evaluations (prefix com_label) in + + let res = Evaluations.mul_c ~res:ids.(0) ~evaluations:[q; com] () in + SMap.singleton (prefix @@ arith ^ ".0") res + + let verifier_identities ~prefix_common ~prefix ~public:_ ~generator:_ + ~size_domain:_ : verifier_identities = + fun _ answers -> + let ({q; _} : answers) = + get_answers ~q_label ~blinds ~prefix ~prefix_common answers + in + let com = get_answer answers X @@ prefix com_label in + let res = Scalar.(q * com) in + SMap.singleton (prefix @@ arith ^ ".0") res + + let polynomials_degree = SMap.of_list [(com_label, 2); (q_label, 2)] + + (* TODO: implement *) + let cs ~q:_ ~a:_ ~b:_ ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ = + failwith "input commitments in aPlonK proofs are not supported yet" +end diff --git a/src/lib_plonk/bls.ml b/src/lib_plonk/bls.ml new file mode 100644 index 000000000000..3804c4481ee5 --- /dev/null +++ b/src/lib_plonk/bls.ml @@ -0,0 +1,46 @@ +module Scalar = struct + include Bls12_381.Fr + + let t : t Repr.t = + Repr.(map (bytes_of (`Fixed size_in_bytes)) of_bytes_exn to_bytes) +end + +module Scalar_map = Map.Make (Scalar) +module Poly = Bls12_381_polynomial.Polynomial +module Domain = Bls12_381_polynomial.Domain + +(* Module to operate with polynomials in FFT evaluations form. *) +module Evaluations = Evaluations_map.Make (Bls12_381_polynomial.Evaluations) + +module G1 = struct + include Bls12_381.G1 + + let t : t Repr.t = + Repr.( + map + (bytes_of (`Fixed (size_in_bytes / 2))) + of_compressed_bytes_exn + to_compressed_bytes) +end + +module G2 = struct + include Bls12_381.G2 + + let t : t Repr.t = + Repr.( + map + (bytes_of (`Fixed (size_in_bytes / 2))) + of_compressed_bytes_exn + to_compressed_bytes) +end + +module GT = struct + include Bls12_381.GT + + let t : t Repr.t = + Repr.(map (bytes_of (`Fixed size_in_bytes)) of_bytes_exn to_bytes) +end + +module Pairing = Bls12_381.Pairing +module Srs_g1 = Bls12_381_polynomial.Srs.Srs_g1 +module Srs_g2 = Bls12_381_polynomial.Srs.Srs_g2 diff --git a/src/lib_plonk/boolean_gates.ml b/src/lib_plonk/boolean_gates.ml new file mode 100644 index 000000000000..6a0b55256bb8 --- /dev/null +++ b/src/lib_plonk/boolean_gates.ml @@ -0,0 +1,217 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Bls +open Identities +module L = Plompiler.LibCircuit +open Gates_common + +(* Boolean check : checks that the first wire is boolean + Non Arith + degree : 3n + nb identities : 1 + advice selectors : None + equations : q·a·(1 - a) +*) +module BoolCheck : Base_sig = struct + let q_label = "qbool" + + let identity = (q_label, 1) + + let index_com = None + + let nb_advs = 0 + + let nb_buffers = 1 + + let gx_composition = false + + let equations ~q ~a ~b:_ ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + Scalar.[q * sub one a * a] + + let blinds = SMap.of_list [(left, [|1; 0|])] + + let prover_identities ~prefix_common ~prefix ~public:_ ~domain:_ evaluations = + let tmps, ids = get_buffers ~nb_buffers ~nb_ids:(snd identity) in + let ({q; a; _} : witness) = + get_evaluations ~q_label ~blinds ~prefix ~prefix_common evaluations + in + + let one_minus_a = + Evaluations.linear_c + ~res:tmps.(0) + ~evaluations:[a] + ~add_constant:one + ~linear_coeffs:[mone] + () + in + let id = + Evaluations.mul_c ~res:ids.(0) ~evaluations:[q; a; one_minus_a] () + in + SMap.singleton (prefix @@ q_label ^ ".0") id + + let verifier_identities ~prefix_common ~prefix ~public:_ ~generator:_ + ~size_domain:_ _ answers = + let q = get_answer answers X @@ prefix_common q_label in + let a = get_answer answers X @@ prefix left in + let res = Scalar.(q * a * sub one a) in + SMap.singleton (prefix @@ q_label ^ ".0") res + + let polynomials_degree = SMap.of_list [(left, 3); (q_label, 3)] + + let cs ~q ~a ~b:_ ~c:_ ~d:_ ~e:_ ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + let open L in + map_singleton + (let* tmp = Num.mul q a in + let* tmp' = Num.add_constant Scalar.(one) a ~ql:mone in + Num.mul tmp tmp') +end + +(* Conditional swap : Depending on wire a, swap wires (b,c) in (d,e) + Non Arith + degree : 3n + nb identities : 2 + advice selectors : None + equations : + q · [(1-a)·b + a·c - d] + q · [a·b + (1-a)·c - e] + /!\ We assume that wire a is a bit, this needs to be asserted independently +*) +module CondSwap : Base_sig = struct + let q_label = "qcond_swap" + + let identity = (q_label, 2) + + let index_com = None + + let nb_advs = 0 + + let nb_buffers = 4 + + let gx_composition = false + + let equations ~q ~a:bit ~b ~c ~d ~e ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + let bbit = Scalar.(sub one bit) in + Scalar. + [q * ((bbit * b) + sub (bit * c) d); q * ((bit * b) + sub (bbit * c) e)] + + let blinds = + SMap.of_list + [ + (left, [|1; 0|]); + (right, [|1; 0|]); + (output, [|1; 0|]); + (top, [|1; 0|]); + (bottom, [|1; 0|]); + ] + + let prover_identities ~prefix_common ~prefix ~public:_ ~domain:_ evaluations = + let tmps, ids = get_buffers ~nb_buffers ~nb_ids:(snd identity) in + let ({q; a; b; c; d; e} : witness) = + get_evaluations ~q_label ~blinds ~prefix ~prefix_common evaluations + in + let b, x, y, u, v = (a, b, c, d, e) in + + let bb = + Evaluations.linear_c + ~res:tmps.(0) + ~evaluations:[b] + ~add_constant:one + ~linear_coeffs:[mone] + () + in + (* 0 = q · [(1 - bit) · x + bit · y - u] *) + let t0 = Evaluations.mul_c ~res:tmps.(1) ~evaluations:[q; bb; x] () in + let t1 = Evaluations.mul_c ~res:tmps.(2) ~evaluations:[q; b; y] () in + let t2 = Evaluations.mul_c ~res:tmps.(3) ~evaluations:[q; u] () in + let id1 = + Evaluations.linear_c + ~res:ids.(0) + ~evaluations:[t0; t1; t2] + ~linear_coeffs:[one; one; mone] + () + in + (* 0 = q · [bit · x + (1 - bit) · y - v] *) + let t0 = Evaluations.mul_c ~res:tmps.(1) ~evaluations:[q; bb; y] () in + let t1 = Evaluations.mul_c ~res:tmps.(2) ~evaluations:[q; b; x] () in + let t2 = Evaluations.mul_c ~res:tmps.(3) ~evaluations:[q; v] () in + let id2 = + Evaluations.linear_c + ~res:ids.(1) + ~evaluations:[t0; t1; t2] + ~linear_coeffs:[one; one; mone] + () + in + SMap.of_list + [(prefix @@ q_label ^ ".0", id1); (prefix @@ q_label ^ ".1", id2)] + + let verifier_identities ~prefix_common ~prefix ~public:_ ~generator:_ + ~size_domain:_ : verifier_identities = + fun _ answers -> + let ({q; a; b; c; d; e; _} : answers) = + get_answers ~q_label ~blinds ~prefix ~prefix_common answers + in + let bit, x, y, u, v = (a, b, c, d, e) in + let bbit = Scalar.(sub one bit) in + (* 0 = q · [(1 - bit) · x + bit · y - u] *) + let id1 = Scalar.(q * ((bbit * x) + sub (bit * y) u)) in + (* 0 = q · [bit · x + (1 - bit) · y - v] *) + let id2 = Scalar.(q * ((bit * x) + sub (bbit * y) v)) in + SMap.of_list + [(prefix @@ q_label ^ ".0", id1); (prefix @@ q_label ^ ".1", id2)] + + let polynomials_degree = + SMap.of_list + [(q_label, 3); (left, 3); (right, 3); (output, 3); (top, 3); (bottom, 3)] + + let cs ~q:qbool ~a:bit ~b:x ~c:y ~d:u ~e:v ~ag:_ ~bg:_ ~cg:_ ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + let open L in + let open Num in + let* bit_times_x = mul bit x in + let* bit_times_y = mul bit y in + (* id1 = qbool · [(1 - b) · x + b · y - u] *) + let* id1 = + let* all = + add_list + ~coeffs:[one; mone; one; mone] + (to_list [x; bit_times_x; bit_times_y; u]) + in + mul qbool all + in + (* id1 = qbool · [b · x + (1 - b) · y - v] *) + let* id2 = + let* all = + add_list + ~coeffs:[one; one; mone; mone] + (to_list [bit_times_x; y; bit_times_y; v]) + in + mul qbool all + in + ret [id1; id2] +end diff --git a/src/lib_plonk/circuit.ml b/src/lib_plonk/circuit.ml new file mode 100644 index 000000000000..8ec323590a70 --- /dev/null +++ b/src/lib_plonk/circuit.ml @@ -0,0 +1,506 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler.Csir + +(* We assert here that all modules/selectors have been used. + The "+2" is to take into account lookup selectors which are not defined in + plonk/gates/custom_gates.ml + The "-1" is to remove the Public_gate, which is not used *) +let () = + assert ( + List.compare_length_with + CS.all_selectors + Custom_gates.(nb_custom_gates - 1 - nb_input_com + 2) + = 0) + +let gates_to_string m = + SMap.fold + (fun k v s -> + s ^ k ^ " " ^ String.concat "," (List.map Scalar.to_string v) ^ "\n") + m + "" + +module Circuit : sig + type t = private { + wires : int array SMap.t; + gates : Scalar.t array SMap.t; + tables : Scalar.t array list list; + public_input_size : int; + input_com_sizes : int list; + circuit_size : int; + nb_wires : int; + table_size : int; + nb_lookups : int; + ultra : bool; + range_checks : int list * int; + } + + val make_wires : + a:int list -> + b:int list -> + c:int list -> + d:int list -> + e:int list -> + ?f:int list -> + ?g:int list -> + ?h:int list -> + unit -> + int list SMap.t + + val make_gates : + ?qc:Scalar.t list -> + ?ql:Scalar.t list -> + ?qr:Scalar.t list -> + ?qo:Scalar.t list -> + ?qd:Scalar.t list -> + ?qe:Scalar.t list -> + ?qlg:Scalar.t list -> + ?qrg:Scalar.t list -> + ?qog:Scalar.t list -> + ?qdg:Scalar.t list -> + ?qeg:Scalar.t list -> + ?qm:Scalar.t list -> + ?qx2b:Scalar.t list -> + ?qx5a:Scalar.t list -> + ?qx5c:Scalar.t list -> + ?qecc_ws_add:Scalar.t list -> + ?qecc_ed_add:Scalar.t list -> + ?qecc_ed_cond_add:Scalar.t list -> + ?qbool:Scalar.t list -> + ?qcond_swap:Scalar.t list -> + ?q_anemoi:Scalar.t list -> + ?q_plookup:Scalar.t list -> + ?q_table:Scalar.t list -> + ?precomputed_advice:Scalar.t list SMap.t -> + unit -> + Scalar.t list SMap.t + + val make : + wires:int list SMap.t -> + gates:Scalar.t list SMap.t -> + ?tables:Scalar.t array list list -> + public_input_size:int -> + ?input_com_sizes:int list -> + ?range_checks:int list * int -> + unit -> + t + + val get_nb_of_constraints : t -> int + + (* /////////////////////////////////////////////////////////////////////// *) + + val get_selectors : t -> string list + + val sat : CS.t -> Table.t list -> Scalar.t array -> bool + + val to_plonk : + public_input_size:int -> + ?input_com_sizes:int list -> + ?tables:Table.t list -> + ?range_checks:int list * int -> + CS.t -> + t +end = struct + type t = { + wires : int array SMap.t; + gates : Scalar.t array SMap.t; + tables : Scalar.t array list list; + public_input_size : int; + input_com_sizes : int list; + circuit_size : int; + nb_wires : int; + table_size : int; + nb_lookups : int; + ultra : bool; + range_checks : int list * int; + } + + let get_selectors circuit = SMap.keys circuit.gates + + let make_wires ~a ~b ~c ~d ~e ?(f = []) ?(g = []) ?(h = []) () = + (* Filtering and mapping selectors with labels. *) + let wire_map = + SMap.of_list [("a", a); ("b", b); ("c", c); ("d", d); ("e", e)] + in + let add_map map (label, l) = if l = [] then map else SMap.add label l map in + List.fold_left add_map wire_map [("f", f); ("g", g); ("h", h)] + + let make_gates ?(qc = []) ?(ql = []) ?(qr = []) ?(qo = []) ?(qd = []) + ?(qe = []) ?(qlg = []) ?(qrg = []) ?(qog = []) ?(qdg = []) ?(qeg = []) + ?(qm = []) ?(qx2b = []) ?(qx5a = []) ?(qx5c = []) ?(qecc_ws_add = []) + ?(qecc_ed_add = []) ?(qecc_ed_cond_add = []) ?(qbool = []) + ?(qcond_swap = []) ?(q_anemoi = []) ?(q_plookup = []) ?(q_table = []) + ?(precomputed_advice = SMap.empty) () = + if q_anemoi <> [] && SMap.(is_empty precomputed_advice) then + failwith "Make_gates : q_anemoi must come with advice selectors." ; + (* Filtering and mapping selectors with labels. *) + let gate_list = + CS.q_list + ~qc + ~ql + ~qr + ~qo + ~qd + ~qe + ~qlg + ~qrg + ~qog + ~qdg + ~qeg + ~qm + ~qx2b + ~qx5a + ~qx5c + ~qecc_ws_add + ~qecc_ed_add + ~qecc_ed_cond_add + ~qbool + ~qcond_swap + ~q_anemoi + ~q_plookup + () + in + let add_map map (label, q) = + match q with + | [] -> map + | l -> if List.for_all Scalar.is_zero l then map else SMap.add label q map + in + let base = + if q_table = [] then SMap.empty else SMap.singleton "q_table" q_table + in + List.fold_left add_map base (gate_list @ SMap.bindings precomputed_advice) + + let verify_name name i = + assert (i < 26) ; + let alphabet = "abcdefghijklmnopqrstuvwxyz" in + let letter_i = alphabet.[i] in + let msg = + Printf.sprintf + "%d-th wire must be named '%c' (current name is '%s')." + i + letter_i + name + in + if String.length name <> 1 then raise (Invalid_argument msg) + else if Char.equal name.[0] letter_i then () + else raise (Invalid_argument msg) + + (* If public_input_size is greater than 0, selector ql will be added if not + already present. + Wires and gates cannot be empty and must all have the same length. + *) + let make ~wires ~gates ?(tables = []) ~public_input_size + ?(input_com_sizes = []) ?(range_checks = ([], -1)) () = + if SMap.is_empty wires then + raise @@ Invalid_argument "Make Circuit: empty wires." ; + if SMap.is_empty gates then + raise @@ Invalid_argument "Make Circuit: empty gates." ; + let circuit_size = List.length (snd (SMap.choose wires)) in + if Int.equal circuit_size 0 then + raise (Invalid_argument "Make Circuit: empty circuit.") ; + let wires = SMap.map Array.of_list wires in + + (* Check that all wires have same size, and each wire i is named + as the i-th alphabet’s letter. *) + let nb_wires = SMap.cardinal wires in + let () = + List.iteri + (fun i (name, l) -> + verify_name name i ; + if Array.length l = circuit_size then () + else raise (Invalid_argument "Make Circuit: different length wires.")) + (SMap.bindings wires) + in + (* Filter out null gates *) + let gates = + SMap.filter_map + (fun label -> function + | [] -> None + | q -> + if label = "q_table" then Some (Array.of_list q) + else if List.exists (fun s -> not (Scalar.is_zero s)) q then + Some (Array.of_list q) + else None) + gates + in + (* Check that all selectors have the same size, and that they are available. *) + let () = + SMap.iter + (fun label q -> + if Array.length q = circuit_size then () + else raise (Invalid_argument "Make Circuit: different length gates.") ; + if + List.mem label (List.map fst CS.all_selectors) + || String.starts_with ~prefix:Custom_gates.qadv_label label + then () + else raise (Invalid_argument "Make Circuit: unknown gates.")) + gates + in + (* Check all tables' columns have the same size. *) + let () = + List.iter + (fun l -> + let sub_table_size = Array.length (List.hd l) in + if List.compare_length_with l nb_wires > 0 then + raise + (Invalid_argument "Make Circuit: table(s) with too many columns.") ; + List.iter + (fun t -> + if Array.length t != sub_table_size then + raise + (Invalid_argument + "Make Circuit: table(s) with columns of different length.") + else ()) + l) + tables + in + (* Check all range indexes are contained in the array *) + let () = + List.iter + (fun i -> + if + List.exists + (fun l -> i >= circuit_size + l + public_input_size) + input_com_sizes + then + raise + (Invalid_argument + "Make Circuit: inconsistent range checks indices.")) + (fst range_checks) + in + let table_size = + if tables = [] then 0 + else List.fold_left (fun acc t -> acc + Array.length (List.hd t)) 0 tables + in + (* Determining if UltraPlonk or TurboPlonk needs to be used. *) + let ultra = SMap.mem "q_plookup" gates in + let nb_lookups = + if not ultra then 0 + else + let q_plookup = SMap.find "q_plookup" gates in + Array.fold_left + (fun acc qi -> if Scalar.is_zero qi then acc else acc + 1) + 0 + q_plookup + in + if ultra && not (SMap.mem "q_table" gates) then + raise (Invalid_argument "Make Circuit: expected table selector.") ; + if ultra && tables = [] then + raise (Invalid_argument "Make Circuit: tables empty.") ; + if (not ultra) && (tables != [] || SMap.mem "q_table" gates) then + raise (Invalid_argument "Make Circuit: table(s) given with no lookups.") ; + let gates = + (* Define ql if undefined as it is the gate taking the public input in. *) + if + List.fold_left ( + ) public_input_size input_com_sizes > 0 + && (not @@ SMap.mem "ql" gates) + then SMap.add "ql" (Array.init circuit_size (fun _ -> Scalar.zero)) gates + else gates + in + { + circuit_size; + wires; + gates; + tables; + public_input_size; + input_com_sizes; + nb_wires; + table_size; + nb_lookups; + ultra; + range_checks; + } + + let get_nb_of_constraints cs = Array.length (snd (SMap.choose cs.wires)) + (* ////////////////////////////////////////////////////////// *) + + let sat_gate identities gate trace tables = + let open CS in + let nb_cs = Array.length gate in + let identities = + (* For each constraint *) + List.init nb_cs (fun i -> + (* Retrieving its values as well as the next constraint's values *) + let j = (i + 1) mod nb_cs in + let ci, cj = (gate.(i), gate.(j)) in + let a, b, c, d, e = + ( trace.(ci.a), + trace.(ci.b), + trace.(ci.c), + trace.(ci.d), + trace.(ci.e) ) + in + let ag, bg, cg, dg, eg = + ( trace.(cj.a), + trace.(cj.b), + trace.(cj.c), + trace.(cj.d), + trace.(cj.e) ) + in + (* Folding on selectors *) + List.fold_left + (fun id_map (s_name, q) -> + match s_name with + | "q_plookup" -> id_map + | "q_table" -> + (* We assume there can be only one lookup per gate *) + let entry : Table.entry = Table.{a; b; c; d; e} in + let sub_table = List.nth tables (Scalar.to_z q |> Z.to_int) in + let b = Table.mem entry sub_table in + let id = [|(if b then Scalar.zero else Scalar.one)|] in + SMap.add "q_table" id id_map + | _ -> + (* Retrieving the selector's identity name and equations *) + let s_id_name, _ = Custom_gates.get_ids s_name in + let s_ids = SMap.find s_id_name id_map in + let precomputed_advice = SMap.of_list ci.precomputed_advice in + (* Updating the identities with the equations' output *) + List.iteri + (fun i s -> s_ids.(i) <- Scalar.(s_ids.(i) + s)) + ((Custom_gates.get_eqs s_name) + ~precomputed_advice + ~q + ~a + ~b + ~c + ~d + ~e + ~ag + ~bg + ~cg + ~dg + ~eg + ()) ; + SMap.add s_id_name s_ids id_map) + identities + ci.sels) + in + (* Checking all identities are verified, i.e. the map contains only 0s *) + List.for_all + (SMap.for_all (fun _id_name id -> + let b = Array.for_all Scalar.is_zero id in + (* if Bool.not b then Printf.printf "\nIdentity '%s' not satisfied" id_name + else () ; *) + b)) + identities + + let sat cs tables trace = + (* We initialise a map with all ids used in the circuit *) + let identities = + List.fold_left + (fun map m -> + let id, nb_ids = Custom_gates.get_ids m in + if SMap.mem id map then map + else SMap.add id (Array.init nb_ids (fun _ -> Scalar.zero)) map) + (SMap.singleton "q_table" [|Scalar.zero|]) + Custom_gates.gates_list + in + let exception Constraint_not_satisfied of string in + try + (* We check in each gate, constraint by constraint, that all ids are satisfied *) + List.iteri + (fun i gate -> + (* Printf.printf "\n\nGate %i: %s" i + (Plompiler.Csir.CS.to_string_gate gate); *) + let b = sat_gate identities gate trace tables in + if b then () + else + (* just to exit the iter *) + raise + (Constraint_not_satisfied + (Printf.sprintf "\nGate #%i not satisfied." i))) + cs ; + true + with Constraint_not_satisfied _ -> false + + let to_plonk ~public_input_size ?(input_com_sizes = []) ?(tables = []) + ?(range_checks = ([], -1)) cs = + let open CS in + let cs = List.rev Array.(to_list @@ concat cs) in + assert (cs <> []) ; + let add_wires a b c d e wires = + let add_wire key w wires = + SMap.update key (fun l -> Some (w :: Option.get l)) wires + in + wires |> add_wire "a" a |> add_wire "b" b |> add_wire "c" c + |> add_wire "d" d |> add_wire "e" e + in + let add_selectors sels map pad = + (* Add to the map all new selectors with the coresponding padding + (array of [pad] zeroes). *) + let map = + List.fold_left + (fun map (k, _) -> + if SMap.mem k map then map + else + let zeros = List.init pad (fun _ -> Scalar.zero) in + SMap.add k zeros map) + map + sels + in + + (* Extend every binding in the map by either add the coefficient + or pad with a zero. *) + SMap.fold + (fun label qq map -> + let q = + match List.find_opt (fun (s, _) -> s = label) sels with + | None -> Scalar.zero + | Some (_, coeff) -> coeff + in + SMap.add label (q :: qq) map) + map + map + in + + let wires_map = + SMap.of_list [("a", []); ("b", []); ("c", []); ("d", []); ("e", [])] + in + + List.fold_left + (fun (wires_map, selectors_map, advice_map, pad) + {a; b; c; d; e; sels; precomputed_advice; label} -> + ignore label ; + let wires_map = add_wires a b c d e wires_map in + let selectors_map = add_selectors sels selectors_map pad in + let advice_map = add_selectors precomputed_advice advice_map pad in + (wires_map, selectors_map, advice_map, pad + 1)) + SMap.(wires_map, empty, empty, 0) + cs + |> fun (wires, selectors, advice, _) -> + let gates = SMap.union_disjoint selectors advice in + let tables = List.map Table.to_list tables in + make + ~wires + ~gates + ~range_checks + ~public_input_size + ~input_com_sizes + ~tables + () +end + +include Circuit diff --git a/src/lib_plonk/custom_gates.ml b/src/lib_plonk/custom_gates.ml new file mode 100644 index 000000000000..9aed3497afe5 --- /dev/null +++ b/src/lib_plonk/custom_gates.ml @@ -0,0 +1,467 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Bls +open Identities +module L = Plompiler.LibCircuit + +module type S = sig + val arith_label : string + + val qadv_label : string + + val com_label : string + + val gates_list : string list + + val nb_custom_gates : int + + val nb_input_com : int + + val get_eqs : + string -> + q:Scalar.t -> + a:Scalar.t -> + b:Scalar.t -> + c:Scalar.t -> + d:Scalar.t -> + e:Scalar.t -> + ag:Scalar.t -> + bg:Scalar.t -> + cg:Scalar.t -> + dg:Scalar.t -> + eg:Scalar.t -> + ?precomputed_advice:Scalar.t SMap.t -> + unit -> + Scalar.t list + + val get_ids : string -> string * int + + val get_cs : + string -> + q:L.scalar L.repr -> + a:L.scalar L.repr -> + b:L.scalar L.repr -> + c:L.scalar L.repr -> + d:L.scalar L.repr -> + e:L.scalar L.repr -> + ag:L.scalar L.repr -> + bg:L.scalar L.repr -> + cg:L.scalar L.repr -> + dg:L.scalar L.repr -> + eg:L.scalar L.repr -> + ?precomputed_advice:L.scalar L.repr SMap.t -> + unit -> + L.scalar L.repr list L.t + + val aggregate_blinds : gates:'a SMap.t -> int SMap.t + + val aggregate_prover_identities : + ?circuit_name:string -> + input_coms_size:int -> + proof_idx:int -> + nb_proofs:int -> + gates:'a SMap.t -> + public_inputs:Scalar.t array -> + domain:Domain.t -> + unit -> + prover_identities + + val aggregate_verifier_identities : + ?circuit_name:string -> + input_com_sizes:int list -> + proof_idx:int -> + nb_proofs:int -> + gates:'a SMap.t -> + public_inputs:Scalar.t array -> + generator:Scalar.t -> + size_domain:int -> + unit -> + verifier_identities + + val aggregate_polynomials_degree : gates:'a SMap.t -> int + + val exists_gx_composition : gates:'a SMap.t -> bool + + val cs_pi : + generator:Scalar.t -> + n:Scalar.t -> + x:L.scalar L.repr -> + zs:L.scalar L.repr -> + L.scalar L.repr list -> + L.scalar L.repr L.t +end + +module Aggregator = struct + open Gates_common + + let arith_label = arith + + let com_label = com_label + + let qadv_label = qadv_label + + (* Maximum number of input commitments that can be used in a proof *) + let nb_input_com = 3 + + let gates_map = + let open Arithmetic_gates in + let open Boolean_gates in + let open Hash_gates in + let open Ecc_gates in + SMap.of_list + ([ + (Public.q_label, (module Public : Base_sig)); + (Constant.q_label, (module Constant)); + (AddLeft.q_label, (module AddLeft)); + (AddRight.q_label, (module AddRight)); + (AddOutput.q_label, (module AddOutput)); + (AddTop.q_label, (module AddTop)); + (AddBottom.q_label, (module AddBottom)); + (AddNextLeft.q_label, (module AddNextLeft)); + (AddNextRight.q_label, (module AddNextRight)); + (AddNextOutput.q_label, (module AddNextOutput)); + (AddNextTop.q_label, (module AddNextTop)); + (AddNextBottom.q_label, (module AddNextBottom)); + (Multiplication.q_label, (module Multiplication)); + (X5A.q_label, (module X5A)); + (X5C.q_label, (module X5C)); + (X2B.q_label, (module X2B)); + (AddWeierstrass.q_label, (module AddWeierstrass)); + (AddEdwards.q_label, (module AddEdwards)); + (ConditionalAddEdwards.q_label, (module ConditionalAddEdwards)); + (BoolCheck.q_label, (module BoolCheck)); + (CondSwap.q_label, (module CondSwap)); + (AnemoiDouble.q_label, (module AnemoiDouble)); + ] + @ List.init nb_input_com (fun i -> + ( "qcom" ^ string_of_int i, + (module InputCom (struct + let idx = i + end) : Base_sig) ))) + + let gates_list = SMap.keys gates_map + + let nb_custom_gates = SMap.cardinal gates_map + + (* Removes non-custom-gates from gates (for example q_plookup) *) + let filter_gates gates = SMap.(filter (fun q _ -> mem q gates_map) gates) + + let find_gate q = + match SMap.find_opt q gates_map with + | Some gate -> gate + | None -> + failwith + (Printf.sprintf "\nCustom_gates.find_gate : unknown selector %s." q) + + let get_blinds q = + let module M = (val find_gate q : Base_sig) in + M.blinds + + let get_prover_identities q = + let module M = (val find_gate q : Base_sig) in + M.prover_identities + + let get_coms q = + let module M = (val find_gate q : Base_sig) in + M.index_com + + let get_nb_advs q = + let module M = (val find_gate q : Base_sig) in + M.nb_advs + + let get_nb_buffers q = + let module M = (val find_gate q : Base_sig) in + M.nb_buffers + + let get_verifier_identities q = + let module M = (val find_gate q : Base_sig) in + M.verifier_identities + + let get_polynomials_degree q = + let module M = (val find_gate q : Base_sig) in + M.polynomials_degree + + let get_eqs q = + let module M = (val find_gate q : Base_sig) in + M.equations + + let get_ids q = + let module M = (val find_gate q : Base_sig) in + M.identity + + let get_cs q = + let module M = (val find_gate q : Base_sig) in + M.cs + + let get_gx_composition q = + let module M = (val find_gate q : Base_sig) in + M.gx_composition + + let aggregate_blinds ~gates = + let f_union _key a1 a2 = + if Array.length a1 <> Array.length a2 then + raise (Invalid_argument "All blinds arrays must have the same size.") + else Some Array.(init (length a1) (fun i -> max a1.(i) a2.(i))) + in + let blinds_array = + SMap.( + fold + (fun gate _ acc_blinds -> union f_union acc_blinds (get_blinds gate)) + (filter_gates gates) + empty) + in + let sum_array a = Array.fold_left ( + ) 0 a in + SMap.map sum_array blinds_array + + let filter_evaluations ~evaluations ~prefix ~prefix_common gates = + let get_eval = Evaluations.find_evaluation evaluations in + let base = + List.fold_left + (fun acc x -> + if SMap.exists (fun y _ -> String.equal x y) evaluations then + SMap.add x (get_eval x) acc + else acc) + SMap.empty + ["X"; "GX"] + in + List.fold_left + (fun acc gate -> + (* Adding wires *) + let acc = + SMap.fold + (fun wire blinds acc2 -> + let wire = prefix wire in + if SMap.exists (fun w _ -> String.equal w wire) acc then acc2 + else + let used = blinds.(0) = 1 || blinds.(1) = 1 in + if used then SMap.add wire (get_eval wire) acc2 else acc2) + (get_blinds gate) + acc + in + (* Adding commitments *) + let acc = + match get_coms gate with + | None -> acc + | Some idx -> + let com_i = prefix com_label ^ string_of_int idx in + SMap.add com_i (get_eval com_i) acc + in + (* Adding advice *) + let acc = + List.init (get_nb_advs gate) (fun i -> + prefix_common qadv_label ^ string_of_int i) + |> List.fold_left + (fun acc2 adv_i -> SMap.add adv_i (get_eval adv_i) acc2) + acc + in + (* Adding selector *) + let gate = prefix_common gate in + if String.starts_with ~prefix:(prefix_common "qpub") gate then acc + else SMap.add gate (get_eval gate) acc) + base + gates + + let filter_answers ~answers ~prefix ~prefix_common gates = + let x, gx = (string_of_eval_point X, string_of_eval_point GX) in + let get_x, get_gx = (get_answer answers X, get_answer answers GX) in + let add_mapmap k' k v mm = + SMap.(update k' (fun m -> Option.bind m (fun m -> Some (add k v m)))) mm + in + let add_x, add_gx = (add_mapmap x, add_mapmap gx) in + let exists_mapmap k' k mm = SMap.exists k (SMap.find k' mm) in + let exists_x, exists_gx = (exists_mapmap x, exists_mapmap gx) in + let base = SMap.of_list [(x, SMap.empty); (gx, SMap.empty)] in + List.fold_left + (fun acc gate -> + (* Adding wires *) + let acc = + SMap.fold + (fun wire blinds acc2 -> + let wire = prefix wire in + let acc3 = + if exists_x (fun w _ -> String.equal w wire) acc then acc2 + else if blinds.(0) = 1 then add_x wire (get_x wire) acc2 + else acc2 + in + if exists_gx (fun w _ -> String.equal w wire) acc then acc3 + else if blinds.(1) = 1 then add_gx wire (get_gx wire) acc3 + else acc3) + (get_blinds gate) + acc + in + (* Adding commitments *) + let acc = + match get_coms gate with + | None -> acc + | Some idx -> + let com_i = prefix com_label ^ string_of_int idx in + add_x com_i (get_x com_i) acc + in + (* Adding advice *) + let acc = + List.init (get_nb_advs gate) (fun i -> + prefix_common qadv_label ^ string_of_int i) + |> List.fold_left + (fun acc2 adv_i -> add_x adv_i (get_x adv_i) acc2) + acc + in + (* Adding selector *) + let gate = prefix_common gate in + if String.starts_with ~prefix:(prefix_common "qpub") gate then acc + else add_x gate (get_x gate) acc) + base + gates + + let aggregate_prover_identities ?(circuit_name = "") ~input_coms_size + ~proof_idx ~nb_proofs ~gates ~public_inputs ~domain () : prover_identities + = + let prefix_common = SMap.Aggregation.add_prefix circuit_name in + let prefix = + SMap.Aggregation.add_prefix ~n:nb_proofs ~i:proof_idx circuit_name + in + fun evaluations -> + let size_eval = Evaluations.size_evaluations evaluations in + (* Sort and filter gates according to nb of tmp buffers *) + let gates = + List.sort + (fun gate1 gate2 -> + Int.compare (get_nb_buffers gate1) (get_nb_buffers gate2)) + (filter_gates gates |> SMap.keys) + in + (* Creating tmp buffers for prover identities *) + let nb_min_buffers = + if List.compare_length_with gates 0 = 0 then 0 + else max 1 (get_nb_buffers (List.hd gates)) + in + tmp_buffers := + Array.init nb_min_buffers (fun _ -> Evaluations.create size_eval) ; + (* Filter evaluations *) + let evaluations = + filter_evaluations ~evaluations ~prefix ~prefix_common gates + in + (* Except for the arithmetic gates, + all gates correspond to distinct identities. *) + let init_ids = + let arith_acc_evaluation = Evaluations.create size_eval in + SMap.singleton (prefix @@ arith ^ ".0") arith_acc_evaluation + in + let union key e1 e2 = + assert (key = prefix @@ arith ^ ".0") ; + Some (Evaluations.add ~res:e1 e1 e2) + in + let public = {public_inputs; input_coms_size} in + List.fold_left + (fun accumulated_ids gate -> + SMap.union + union + accumulated_ids + (get_prover_identities + gate + ~prefix_common + ~prefix + ~public + ~domain + evaluations)) + init_ids + gates + + let aggregate_verifier_identities ?(circuit_name = "") ~input_com_sizes + ~proof_idx ~nb_proofs ~gates ~public_inputs ~generator ~size_domain () : + verifier_identities = + let prefix_common = SMap.Aggregation.add_prefix circuit_name in + let prefix = + SMap.Aggregation.add_prefix ~n:nb_proofs ~i:proof_idx circuit_name + in + fun x answers -> + let gates = filter_gates gates |> SMap.keys in + let answers = filter_answers ~answers ~prefix ~prefix_common gates in + let arith_id = SMap.singleton (prefix @@ arith ^ ".0") Scalar.zero in + let union key s1 s2 = + assert (key = prefix @@ arith ^ ".0") ; + Some (Scalar.add s1 s2) + in + let public = + { + public_inputs; + input_coms_size = List.fold_left ( + ) 0 input_com_sizes; + } + in + List.fold_left + (fun accumulated_ids gate -> + let gate_ids = + get_verifier_identities + gate + ~prefix_common + ~prefix + ~public + ~generator + ~size_domain + in + SMap.union union accumulated_ids (gate_ids x answers)) + arith_id + gates + + let aggregate_polynomials_degree ~gates = + SMap.fold + (fun gate _ degree -> + let map = get_polynomials_degree gate in + SMap.fold (fun _ d acc -> max d acc) map degree) + (filter_gates gates) + 0 + + let exists_gx_composition ~gates = + SMap.exists (fun q _ -> get_gx_composition q) (filter_gates gates) + + (* - (x^n -1)/n·(w0/(x -1) + w1/(x/g - 1) + … + wn/(x/g^n - 1)) *) + let cs_pi ~generator ~n ~x ~zs pi_list = + let open L in + let open Num in + let mone = Scalar.(negate one) in + let n_inv = Scalar.(inverse_exn (negate n)) in + let g_inv = Scalar.inverse_exn generator in + match pi_list with + | [] -> constant_scalar Scalar.zero + | hd :: tl_pi -> + (* negate because we want -PI(x) *) + let* left_term = mul_by_constant n_inv zs in + let* init_value = + let* x_minus_one = add_constant mone x in + div hd x_minus_one + in + let* sum, _g_inv_k = + foldM + (fun (res, g_inv_k) w_k -> + let* x_g_inv_k_minus_one = add_constant ~ql:g_inv_k mone x in + let* to_add = div w_k x_g_inv_k_minus_one in + let* res = add res to_add in + ret (res, Scalar.mul g_inv_k g_inv)) + (init_value, g_inv) + tl_pi + in + mul left_term sum +end + +include (Aggregator : S) diff --git a/src/lib_plonk/dune b/src/lib_plonk/dune new file mode 100644 index 000000000000..2ec999d8b7c7 --- /dev/null +++ b/src/lib_plonk/dune @@ -0,0 +1,18 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name plonk) + (public_name octez-plonk) + (instrumentation (backend bisect_ppx)) + (libraries + repr + hacl-star + data-encoding + octez-bls12-381-polynomial + octez-plompiler) + (preprocess (pps ppx_repr)) + (flags + (:standard) + -open Octez_bls12_381_polynomial + -open Plompiler)) diff --git a/src/lib_plonk/ecc_gates.ml b/src/lib_plonk/ecc_gates.ml new file mode 100644 index 000000000000..a9a3ff339466 --- /dev/null +++ b/src/lib_plonk/ecc_gates.ml @@ -0,0 +1,720 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Bls +open Identities +module L = Plompiler.LibCircuit +open Gates_common + +(* Weierstrass elliptic curve addition : checks that (a, ag) + (b, bg) = (c, cg) + Non Arith + degree : 4n + nb identities : 2 + advice selectors : None + equations : with λ = (bg - ag) / (b - a), + 1) q·[ (a + b + c)·(b - a)² - (bg - ag)² ] = 0 + 2) q·[ (ag + cg)·(b - a) - (a - c)·(bg - ag) ] = 0 + /!\ q must be 0 or 1 +*) +module AddWeierstrass : Base_sig = struct + let q_label = "qecc_ws_add" + + let identity = (q_label, 2) + + let index_com = None + + let nb_advs = 0 + + let nb_buffers = 3 + + let gx_composition = true + + let equations ~q ~a ~b ~c ~d:_ ~e:_ ~ag ~bg ~cg ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + if Scalar.is_zero q then Scalar.[zero; zero] + else if not (Scalar.(is_one) q) then + failwith "AddWeierstrass.equations : qecc_ws_add must be zero or one." + else + let lambda = Scalar.(div_exn (sub bg ag) (sub b a)) in + let x = Scalar.(sub (lambda * lambda) (a + b)) in + let y = Scalar.(sub (lambda * sub a x) ag) in + Scalar.[sub x c; sub y cg] + + let blinds = + SMap.of_list [(right, [|1; 1|]); (left, [|1; 1|]); (output, [|1; 1|])] + + let prover_identities ~prefix_common ~prefix ~public:_ ~domain : + prover_identities = + fun evaluations -> + (* lambda: + numerator = (bg - ag) ; + denominator = (b - a) *) + (* identity on new point's x coordinate: + (c + b + a)·(b - a)^2 - (bg - ag)^2 = 0 *) + let domain_size = Domain.length domain in + let tmps, ids = get_buffers ~nb_buffers ~nb_ids:(snd identity) in + let ({q; a; b; c; _} : witness) = + get_evaluations ~q_label ~blinds ~prefix ~prefix_common evaluations + in + + (* tmps.(2) <- (b - a) *) + let b_minus_a = + Evaluations.linear_c + ~res:tmps.(2) + ~evaluations:[b; a] + ~linear_coeffs:[one; mone] + () + in + (* tmps.(1) <- (b - a)^2 *) + let b_minus_a_sqr = + Evaluations.mul_c ~res:tmps.(1) ~evaluations:[b_minus_a] ~powers:[2] () + in + (* ids.(1) <- (a + b + c) *) + let a_plus_b_plus_c = + Evaluations.linear_c ~res:ids.(1) ~evaluations:[a; b; c] () + in + (* tmps.(0) <- (a + b + c)·(b - a)^2 *) + let left_term = + Evaluations.mul_c + ~res:tmps.(0) + ~evaluations:[a_plus_b_plus_c; b_minus_a_sqr] + () + in + (* ids.(1) <- (a + b + c)·(b - a)^2 - (bg - ag)^2 *) + let first_identity = + Evaluations.linear_c + ~res:ids.(1) + ~evaluations:[left_term; b_minus_a_sqr] + ~composition_gx:([0; 1], domain_size) + ~linear_coeffs:[one; mone] + () + in + let first_identity = + Evaluations.mul_c ~res:ids.(0) ~evaluations:[q; first_identity] () + in + (* identity on new point's y coordinate: + (cg + ag)·(b - a) - (bg - ag)·(a - c) = 0 *) + (* ids.(1) <- (cg + ag) *) + let cg_plus_ag = + Evaluations.linear_c + ~res:ids.(1) + ~evaluations:[c; a] + ~composition_gx:([1; 1], domain_size) + () + in + (* tmps.(0) <- (cg + ag)·(b - a) *) + let left_term_2 = + Evaluations.mul_c ~res:tmps.(0) ~evaluations:[cg_plus_ag; b_minus_a] () + in + (* ids.(1) <- (a - c) *) + let a_minus_c = + Evaluations.linear_c + ~res:ids.(1) + ~evaluations:[a; c] + ~linear_coeffs:[one; mone] + () + in + (* tmps.(1) <- (bg - ag)·(a - c) *) + let right_term_2 = + Evaluations.mul_c + ~res:tmps.(1) + ~evaluations:[b_minus_a; a_minus_c] + ~composition_gx:([1; 0], domain_size) + () + in + (* tmps.(2) <- (cg + ag)·(b - a) - (bg - ag)·(a - c) *) + let second_identity = + Evaluations.linear_c + ~res:tmps.(2) + ~evaluations:[left_term_2; right_term_2] + ~linear_coeffs:[one; mone] + () + in + let second_identity = + Evaluations.mul_c ~res:ids.(1) ~evaluations:[q; second_identity] () + in + SMap.of_list + [ + (prefix @@ q_label ^ ".0", first_identity); + (prefix @@ q_label ^ ".1", second_identity); + ] + + let verifier_identities ~prefix_common ~prefix ~public:_ ~generator:_ + ~size_domain:_ : verifier_identities = + fun _ answers -> + let {q; a; b; c; ag; bg; cg; _} = + get_answers ~q_label ~blinds ~prefix ~prefix_common answers + in + let num_lambda = Scalar.(sub bg ag) in + let den_lambda = Scalar.(sub b a) in + (* identity on new point's x coordinate: + (c + b + a)·(b - a)^2 - (bg - ag)^2 = 0 *) + let first_identity = + let num_lambda2 = Scalar.mul num_lambda num_lambda in + let den_lambda2 = Scalar.mul den_lambda den_lambda in + let id = Scalar.(sub ((c + b + a) * den_lambda2) num_lambda2) in + Scalar.mul q id + in + (* identity on new point's y coordinate: + (cg + ag)·(b - a) - (bg - ag)·(a - c) = 0 *) + let second_identity = + let id = Scalar.(sub ((cg + ag) * den_lambda) (num_lambda * sub a c)) in + Scalar.mul q id + in + SMap.of_list + [ + (prefix @@ q_label ^ ".0", first_identity); + (prefix @@ q_label ^ ".1", second_identity); + ] + + let polynomials_degree = + SMap.of_list [(left, 4); (right, 4); (output, 4); (q_label, 4)] + + let cs ~q:qec ~a ~b ~c ~d:_ ~e:_ ~ag ~bg ~cg ~dg:_ ~eg:_ ?precomputed_advice:_ + () = + let open L in + let open Num in + let sub = add ~qr:mone in + let* lambda_num = sub bg ag in + let* lambda_denom = sub b a in + let* lambda_num2 = mul lambda_num lambda_num in + let* cba = add_list (to_list [c; b; a]) in + let* fst_term = mul_list (to_list [cba; lambda_denom; lambda_denom]) in + let* fst = sub fst_term lambda_num2 in + let* fst = mul qec fst in + let* cgag = add cg ag in + let* ac = sub a c in + let* fst_term = mul cgag lambda_denom in + let* snd_term = mul lambda_num ac in + let* snd = sub fst_term snd_term in + let* snd = mul qec snd in + ret [fst; snd] +end + +(* Edwards elliptic curve addition : checks that P + Q = R + Non Arith + degree : 6n + nb identities : 2 + advice selectors : None + equations : + 1) q · [ r ·(1 + param_d · px · qx · py · qy) - (px · bg + qx · py) ] = 0 + 2) q · [ ry ·(1 - param_d · px · qx · py · qy) - (qy · py - param_a · qx · px) ] = 0 + /!\ q must be 0 or 1 +*) +module AddEdwards : Base_sig = struct + let q_label = "qecc_ed_add" + + let identity = (q_label, 2) + + let index_com = None + + let nb_advs = 0 + + let nb_buffers = 2 + + let gx_composition = true + + (* JubJub curve parameters *) + let param_a = mone + + let param_d = + Scalar.of_string + "19257038036680949359750312669786877991949435402254120286184196891950884077233" + + let equations ~q ~a:px ~b:qx ~c:rx ~d:_ ~e:_ ~ag:py ~bg:qy ~cg:ry ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + if Scalar.is_zero q then Scalar.[zero; zero] + else if not (Scalar.is_one q) then + failwith "AddEdwards.equations : qecc_ed_add must be zero or one." + else + let pxqy = Scalar.(px * qy) in + let qxpy = Scalar.(qx * py) in + let pyqy = Scalar.(py * qy) in + let pxqx = Scalar.(px * qx) in + let rx' = Scalar.((pxqy + qxpy) / (one + (param_d * pxqy * qxpy))) in + let ry' = + Scalar.( + (pyqy + (negate param_a * pxqx)) + / (one + (negate param_d * pxqy * qxpy))) + in + Scalar.[rx' + negate rx; ry' + negate ry] + + let blinds = + SMap.of_list [(right, [|1; 1|]); (left, [|1; 1|]); (output, [|1; 1|])] + + let prover_identities ~prefix_common ~prefix ~public:_ ~domain : + prover_identities = + fun evaluations -> + let domain_size = Domain.length domain in + let tmps, ids = get_buffers ~nb_buffers ~nb_ids:(snd identity) in + let ({q; a; b; c; _} : witness) = + get_evaluations ~q_label ~blinds ~prefix ~prefix_common evaluations + in + let s, p, q, r = (q, a, b, c) in + + (* identity on new point's x coordinate: + q · [r_x · (1 + Params_d · p_x · q_x · p_y · q_y) - (q_x · q_y + p_y · q_x)] = 0 *) + (* tmps.(0) <- p_x · q_y *) + let px_mul_qy = + Evaluations.mul_c + ~res:tmps.(0) + ~evaluations:[p; q] + ~composition_gx:([0; 1], domain_size) + () + in + (* tmps.(1) <- p_y · q_x *) + let py_mul_qx = + Evaluations.mul_c + ~res:tmps.(1) + ~evaluations:[p; q] + ~composition_gx:([1; 0], domain_size) + () + in + (* ids.(0) <- px · py · qx · qy *) + let px_mul_py_mul_qx_mul_qy = + Evaluations.mul_c ~res:ids.(0) ~evaluations:[px_mul_qy; py_mul_qx] () + in + (* ids.(1) <- 1 + Params_d · px · py · qx · qy *) + let one_plus_d_mul_px_mul_py_mul_qx_mul_qy = + Evaluations.linear_c + ~res:ids.(1) + ~evaluations:[px_mul_py_mul_qx_mul_qy] + ~linear_coeffs:[param_d] + ~add_constant:one + () + in + (* ids.(0) <- px · qy + py · qx *) + let px_mul_qy_plus_py_mul_qx = + Evaluations.linear_c ~res:ids.(0) ~evaluations:[px_mul_qy; py_mul_qx] () + in + (* tmps.(0) <- rx · (1 + Params_d · px · py · qx · qy) *) + let rx_mul_one_plus_d_mul_px_mul_py_mul_qx_mul_qy = + Evaluations.mul_c + ~res:tmps.(0) + ~evaluations:[one_plus_d_mul_px_mul_py_mul_qx_mul_qy; r] + () + in + (* tmps.(1) <- rx · (1 + Params_d · px · py · qx · qy) - (px · qy + py · qx) *) + let first_identity = + Evaluations.linear_c + ~res:tmps.(1) + ~evaluations: + [ + rx_mul_one_plus_d_mul_px_mul_py_mul_qx_mul_qy; + px_mul_qy_plus_py_mul_qx; + ] + ~linear_coeffs:[one; mone] + () + in + let first_identity = + Evaluations.mul_c ~res:ids.(0) ~evaluations:[s; first_identity] () + in + (* identity on new point's y coordinate: + q * [ry * (1 - Params_d * p_x * q_x * p_y * q_y) - (p_y * q_y - Params_a * p_x * q_x)] = 0 *) + (* tmps.(1) <- (1 - Params_d · px · py · qx · qy) *) + let one_minus_d_mul_px_mul_py_mul_qx_mul_qy = + Evaluations.linear_c + ~res:tmps.(1) + ~evaluations:[one_plus_d_mul_px_mul_py_mul_qx_mul_qy] + ~linear_coeffs:[mone] + ~add_constant:two + () + in + (* tmps.(0) <- ry · (1 - Params_d · px · py · qx · qy) *) + let ry_mul_one_minus_d_mul_px_mul_py_mul_qx_mul_qy = + Evaluations.mul_c + ~res:tmps.(0) + ~evaluations:[one_minus_d_mul_px_mul_py_mul_qx_mul_qy; r] + ~composition_gx:([0; 1], domain_size) + () + in + (* ids.(1) <- px · qx *) + let px_mul_qx = Evaluations.mul_c ~res:ids.(1) ~evaluations:[p; q] () in + (* tmps.(1) <- ry · (1 - Params_d · px · py · qx · qy) - py · qy + Params_a · px · qx *) + let second_identity = + Evaluations.linear_c + ~res:tmps.(1) + ~evaluations: + [ry_mul_one_minus_d_mul_px_mul_py_mul_qx_mul_qy; px_mul_qx; px_mul_qx] + ~composition_gx:([0; 1; 0], domain_size) + ~linear_coeffs:[one; mone; param_a] + () + in + let second_identity = + Evaluations.mul_c ~res:ids.(1) ~evaluations:[s; second_identity] () + in + SMap.of_list + [ + (prefix @@ q_label ^ ".0", first_identity); + (prefix @@ q_label ^ ".1", second_identity); + ] + + let verifier_identities ~prefix_common ~prefix ~public:_ ~generator:_ + ~size_domain:_ : verifier_identities = + fun _ answers -> + let {q; a; b; c; ag; bg; cg; _} = + get_answers ~q_label ~blinds ~prefix ~prefix_common answers + in + let px, py, qx, qy, rx, ry = (a, ag, b, bg, c, cg) in + let pxqx = Scalar.mul px qx in + let pyqy = Scalar.mul py qy in + let den_common = Scalar.(param_d * pxqx * pyqy) in + (* q·[x3·(1 + d·x1·x2·y1·y2) - (x1·y2 + y1·x2)] = 0 *) + let first_identity = + let num = Scalar.((px * qy) + (py * qx)) in + let den = Scalar.(one + den_common) in + let id = Scalar.(sub (rx * den) num) in + Scalar.mul q id + in + (* q · [ry · (1 - d · px · qx · py · qy) - (py · qy - a · px · qx)] = 0 *) + let second_identity = + let num = Scalar.(sub pyqy (param_a * pxqx)) in + let den = Scalar.(sub one den_common) in + let id = Scalar.(sub (ry * den) num) in + Scalar.mul q id + in + SMap.of_list + [ + (prefix @@ q_label ^ ".0", first_identity); + (prefix @@ q_label ^ ".1", second_identity); + ] + + let polynomials_degree = + SMap.of_list [(left, 6); (right, 6); (output, 6); (q_label, 6)] + + let cs ~q:qec ~a:px ~b:qx ~c:rx ~d:_ ~e:_ ~ag:py ~bg:qy ~cg:ry ~dg:_ ~eg:_ + ?precomputed_advice:_ () = + let open L in + let open Num in + let sub = add ~qr:mone in + let* pxqy = mul px qy in + let* qxpy = mul qx py in + (* 1 + d · p_x · q_x · p_y · q_y *) + let* den = custom ~qc:Scalar.one ~qm:param_d pxqy qxpy in + let* fst_term = mul rx den in + let* snd_term = add pxqy qxpy in + let* fst_id = sub fst_term snd_term in + let* fst_id = mul qec fst_id in + (* 1 - d · p_x · q_x · p_y · q_y *) + let* den' = add_constant two ~ql:mone den in + (* r_y · (1 - d · p_x · q_x · p_y · q_y) *) + let* fst_term = mul ry den' in + (* p_y · q_y - a · p_x · q_x *) + let* snd_term = + let* pyqy = mul py qy in + let* apxqx = mul ~qm:param_a px qx in + sub pyqy apxqx + in + let* snd_id = sub fst_term snd_term in + let* snd_id = mul qec snd_id in + ret [fst_id; snd_id] +end + +(* Edwards elliptic curve conditional addition : checks that P(d, e) + a · Q = R + Non Arith + degree : 7n + nb identities : 2 + advice selectors : None + equations : + · q · [ rx · (1 + param_d · bit · qx · qy · px · py) - (px + bit · (px · qy + qx · py - px)) ] = 0 + · q · [ ry · (1 - param_d · bit · qx · qy · px · py) - (py + bit · (py · qy - param_a · qx · px - py)) ] = 0 +*) +module ConditionalAddEdwards : Base_sig = struct + let q_label = "qecc_ed_cond_add" + + let identity = (q_label, 2) + + let index_com = None + + let nb_advs = 0 + + let nb_buffers = 3 + + let gx_composition = true + + (* JubJub curve parameters *) + let param_a = mone + + let param_d = + Scalar.of_string + "19257038036680949359750312669786877991949435402254120286184196891950884077233" + + (* Let P = (p_x; p_y), Q = (q_x; q_y), R = (r_x; r_y), b in {0,1}. + This gate asserts that R = P + b * Q. + b * Q = Q if b = 1 and (0, 1) if b = 0, so b * Q can be written as: (b * q_x; b * q_y + 1 - b) + Let a et d the Edwards curve parameters. + We thus have the following identities: + r_x = (p_x * (b * q_y + 1 - b) + b * q_x * p_y) / (1 + d * p_x * b * q_x * p_y * (b * q_y + 1 - b)) + r_y = (p_y * (b * q_y + 1 - b) - a * p_x * b * q_x) / (1 - d * p_x * b * q_x * p_y * (b * q_y + 1 - b)) + We put in the wires a, b and c the point coordinates in this order: + a b c d e + wire #i: bit q_x q_y p_x p_y + wire #i+1: r_x r_y + + Simplifying the equations, we get: + r_x = (p_x * (b * q_y + 1 - b) + b * q_x * p_y) / (1 + b * d * p_x * q_x * p_y * q_y) + r_y = (p_y * (b * q_y + 1 - b) - b * a * p_x * q_x) / (1 - b * d * p_x * q_x * p_y * q_y) + *) + let equations ~q ~a:bit ~b:qx ~c:qy ~d:px ~e:py ~ag:_ ~bg:_ ~cg:_ ~dg:rx + ~eg:ry ?precomputed_advice:_ () = + if Scalar.is_zero q then Scalar.[zero; zero] + else + let qx' = Scalar.(bit * qx) in + let qy' = Scalar.((bit * qy) + sub one bit) in + let pxqy' = Scalar.(px * qy') in + let qx'py = Scalar.(qx' * py) in + let pyqy' = Scalar.(py * qy') in + let pxqx' = Scalar.(px * qx') in + let rx' = Scalar.((pxqy' + qx'py) / (one + (param_d * pxqy' * qx'py))) in + let ry' = + Scalar.( + (pyqy' + (negate param_a * pxqx')) + / (one + (negate param_d * pxqy' * qx'py))) + in + Scalar.[rx' + negate rx; ry' + negate ry] + + let blinds = + SMap.of_list + [ + (left, [|1; 0|]); + (right, [|1; 0|]); + (output, [|1; 0|]); + (top, [|1; 1|]); + (bottom, [|1; 1|]); + ] + + let prover_identities ~prefix_common ~prefix ~public:_ ~domain evaluations = + let domain_size = Domain.length domain in + let tmps, ids = get_buffers ~nb_buffers ~nb_ids:(snd identity) in + let ({q; a; b; c; d; e} : witness) = + get_evaluations ~q_label ~blinds ~prefix ~prefix_common evaluations + in + let b, qx, qy, px, py, rx, ry = (a, b, c, d, e, d, e) in + + (* identity on new point's x coordinate: + q · [r_x · (1 + d · b · p_x · q_x · p_y · q_y) + - (b · p_x · q_y + p_x - b · p_x + b · q_x · p_y) = 0] *) + (* tmps.(0) <- b · px · qy *) + let b_mul_px_mul_qy = + Evaluations.mul_c ~res:tmps.(0) ~evaluations:[b; px; qy] () + in + (* tmps.(1) <- py · qx *) + let py_mul_qx = Evaluations.mul_c ~res:tmps.(1) ~evaluations:[py; qx] () in + (* tmps.(2) <- b · px *) + let b_mul_px = Evaluations.mul_c ~res:tmps.(2) ~evaluations:[b; px] () in + (* ids.(0) <- b · px · py · qx · qy *) + let b_mul_px_mul_py_mul_qx_mul_qy = + Evaluations.mul_c + ~res:ids.(0) + ~evaluations:[b_mul_px_mul_qy; py_mul_qx] + () + in + (* ids.(1) <- 1 + Params_d · b · px · py · qx · qy *) + let den1 = + Evaluations.linear_c + ~res:ids.(1) + ~evaluations:[b_mul_px_mul_py_mul_qx_mul_qy] + ~linear_coeffs:[param_d] + ~add_constant:one + () + in + (* tmps.(1) <- b · py · qx *) + let b_mul_py_mul_qx = + Evaluations.mul_c ~res:tmps.(1) ~evaluations:[b; py; qx] () + in + (* ids.(0) <- px - b · px + b · px · qy + b · py · qx *) + let rhs = + Evaluations.linear_c + ~res:ids.(0) + ~evaluations:[px; b_mul_px; b_mul_px_mul_qy; b_mul_py_mul_qx] + ~linear_coeffs:[one; mone; one; one] + () + in + (* tmps.(0) <- rx · (1 + Params_d · b · px · py · qx · qy) *) + let lhs = + Evaluations.mul_c + ~res:tmps.(0) + ~evaluations:[den1; rx] + ~composition_gx:([0; 1], domain_size) + () + in + (* tmps.(1) <- + rx · (1 + Params_d · b · px · py · qx · qy) + - (px - b · px + b · px · qy + b · py · qx) *) + let first_identity = + Evaluations.linear_c + ~res:tmps.(1) + ~evaluations:[lhs; rhs] + ~linear_coeffs:[one; mone] + () + in + let first_identity = + Evaluations.mul_c ~res:ids.(0) ~evaluations:[q; first_identity] () + in + (* identity on new point's y coordinate: + q · [r_y · (1 - d · b · p_x · q_x · p_y · q_y) + - (b · p_y · q_y + p_y - p_y · b - a · p_x · b · q_x)] = 0 *) + (* tmps.(1) <- (1 - Params_d · b · px · py · qx · qy) *) + let den2 = + Evaluations.linear_c + ~res:tmps.(1) + ~evaluations:[den1] + ~linear_coeffs:[mone] + ~add_constant:two + () + in + (* tmps.(0) <- ry · (1 - Params_d · px · py · qx · qy) *) + let lhs = + Evaluations.mul_c + ~res:tmps.(0) + ~evaluations:[den2; ry] + ~composition_gx:([0; 1], domain_size) + () + in + (* ids.(1) <- px · qx *) + let px_mul_qx = Evaluations.mul_c ~res:ids.(1) ~evaluations:[px; qx] () in + (* tmps.(1) <- py · qy *) + let py_mul_qy = Evaluations.mul_c ~res:tmps.(1) ~evaluations:[py; qy] () in + let minus_a_mul_px_mul_qx_plus_py_mul_qy_minus_py = + Evaluations.linear_c + ~res:tmps.(2) + ~evaluations:[px_mul_qx; py_mul_qy; py] + ~linear_coeffs:[Scalar.negate param_a; one; mone] + () + in + let minus_b_times_a_mul_px_mul_qx_plus_py_mul_qy_minus_py = + Evaluations.mul_c + ~res:ids.(1) + ~evaluations:[b; minus_a_mul_px_mul_qx_plus_py_mul_qy_minus_py] + () + in + let rhs = + Evaluations.linear_c + ~res:tmps.(2) + ~evaluations:[minus_b_times_a_mul_px_mul_qx_plus_py_mul_qy_minus_py; py] + () + in + (* tmps.(1) <- + ry · (1 - Params_d · px · py · qx · qy) + - (b · py · qy + py - py · b - Params_a · px · b · qx) *) + let second_identity = + Evaluations.linear_c + ~res:tmps.(1) + ~evaluations:[lhs; rhs] + ~linear_coeffs:[one; mone] + () + in + let second_identity = + Evaluations.mul_c ~res:ids.(1) ~evaluations:[q; second_identity] () + in + SMap.of_list + [ + (prefix @@ q_label ^ ".0", first_identity); + (prefix @@ q_label ^ ".1", second_identity); + ] + + let verifier_identities ~prefix_common ~prefix ~public:_ ~generator:_ + ~size_domain:_ _ answers = + let {q; a; b; c; d; e; dg; eg; _} = + get_answers ~q_label ~blinds ~prefix ~prefix_common answers + in + let b, qx, qy, px, py, rx, ry = (a, b, c, d, e, dg, eg) in + let bpxqy = Scalar.(b * px * qy) in + let pyqx = Scalar.(py * qx) in + let den_common = Scalar.(param_d * bpxqy * pyqx) in + (* q · [rx · (1 + d · b · px · qx · py · qy) + - (b · px · qy + px - b · px + b · qx · py) = 0] *) + let first_identity = + let num = Scalar.(sub px (b * px) + bpxqy + (b * pyqx)) in + let den = Scalar.(one + den_common) in + let id = Scalar.(sub (rx * den) num) in + Scalar.mul q id + in + (* q · [ry · (1 - d · b · px · qx · py · qy) + - (b · py · qy + py - py · b - a · px · b · qx)] = 0 *) + let second_identity = + let num = + Scalar.(sub (b * py * qy) (param_a * px * b * qx) + sub py (py * b)) + in + let den = Scalar.(sub one den_common) in + let id = Scalar.(sub (ry * den) num) in + Scalar.mul q id + in + SMap.of_list + [ + (prefix @@ q_label ^ ".0", first_identity); + (prefix @@ q_label ^ ".1", second_identity); + ] + + let polynomials_degree = + SMap.of_list + [(left, 7); (right, 7); (output, 7); (top, 7); (bottom, 7); (q_label, 7)] + + let cs ~q:qec ~a:bit ~b:qx ~c:qy ~d:px ~e:py ~ag:_ ~bg:_ ~cg:_ ~dg:rx ~eg:ry + ?precomputed_advice:_ () = + let open L in + let open Num in + let sub x y = add ~qr:mone x y in + let* px_qy = mul px qy in + let* py_qx = mul py qx in + let* pqs = mul px_qy py_qx in + let* denom_first = custom ~qm:param_d bit pqs ~qc:one in + (* q · [rx · (1 + d · b · px · qx · py · qy) + - (b · px · qy + b · py · qx - b · px + px)] = 0 *) + let* first_identity = + (* left = rx · (1 + d · b · px · qx · py · qy) *) + let* left = mul denom_first rx in + (* right = b · (px · qy + py · qx - px) + px *) + let* px_qy_plus_py_qx = add px_qy py_qx in + let* px_qy_plus_py_qx_minux_px = sub px_qy_plus_py_qx px in + let* right_b = mul bit px_qy_plus_py_qx_minux_px in + let* right = add px right_b in + (* all = left - right + = rx · (1 + d · b · px · qx · py · qy) + - (b · px · qy + b · py · qx - b · px + px) *) + let* all = sub left right in + mul qec all + in + (* q · [ry · (1 - d · b · px · qx · py · qy) + - (b · py · qy - a · b · px · qx - b · py + py )] = 0 *) + let* second_identity = + (* left = ry · (1 - d · b · px · qx · py · qy) *) + let* denom_second = add_constant ~ql:mone two denom_first in + let* left = mul ry denom_second in + (* right = b · (py · qy - a · px · qx - py) + py *) + let* py_qy = mul py qy in + let* a_px_qx = mul ~qm:param_a px qx in + let* py_qy_plus_a_px_qx = sub py_qy a_px_qx in + let* py_qy_plus_a_px_qx_minus_py = sub py_qy_plus_a_px_qx py in + let* right_b = mul bit py_qy_plus_a_px_qx_minus_py in + let* right = add right_b py in + (* all = left - right + = y · (1 - d · b · px · qx · py · qy) + - (b · py · qy - a · b · px · qx - b · py + py ) *) + let* all = sub left right in + mul qec all + in + ret [first_identity; second_identity] +end diff --git a/src/lib_plonk/evaluations_map.ml b/src/lib_plonk/evaluations_map.ml new file mode 100644 index 000000000000..073d908789e6 --- /dev/null +++ b/src/lib_plonk/evaluations_map.ml @@ -0,0 +1,151 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* Alternative representation of polynomials containing + the evaluations of a polynomial on a certain set and its + degree *) + +module type Evaluations_sig = sig + include Octez_bls12_381_polynomial.Evaluations.Evaluations_sig + + (** [size_evaluations] returns the maximum size of elements in evaluations *) + val size_evaluations : t SMap.t -> int + + (** [find_evaluation m name] returns the evaluation for a given name [name] *) + val find_evaluation : t SMap.t -> string -> t + + (** [print_evaluations_name] prints [(name, degree, length)] for each evaluation *) + val print_evaluations_name : t SMap.t -> unit + + (** [get_domain] returns the evaluation for ["X"] *) + val get_domain : t SMap.t -> domain + + (** [compute_evaluations] converts the coefficient representation of each + polynomial [pᵢ] to the evaluation representation. + + Note: + - size of domain must be a power of two + - size of a polynomial [pᵢ] must be less than or equal to size of domain *) + val compute_evaluations : domain:domain -> polynomial SMap.t -> t SMap.t + + (** [compute_evaluations_update_map] writes the result of {!compute_evaluations} in + [evaluations]. If [domain] is not provided, {!get_domain} is called *) + val compute_evaluations_update_map : + ?domain:domain -> evaluations:t SMap.t -> polynomial SMap.t -> t SMap.t + + (** [mul] invokes {!mul_c} with the evaluations for given names [poly_names] *) + val mul : + ?res:t -> + evaluations:t SMap.t -> + poly_names:string list -> + ?composition_gx:int list * int -> + ?powers:int list -> + unit -> + t + + (** [linear] invokes {!linear_c} with the evaluations for given names [poly_names] *) + val linear : + ?res:t -> + evaluations:t SMap.t -> + poly_names:SMap.key list -> + ?linear_coeffs:scalar list -> + ?composition_gx:int list * int -> + ?add_constant:scalar -> + unit -> + t +end + +module Make (E : Octez_bls12_381_polynomial.Evaluations.Evaluations_sig) : + Evaluations_sig + with type scalar = E.scalar + and type domain = E.domain + and type polynomial = E.polynomial + and type t = E.t = struct + include E + + let print_evaluations_name map = + let s_eval = + "{" + ^ SMap.fold + (fun k eval acc -> + acc + ^ Printf.sprintf "\n %s -> (%d, %d)" k (degree eval) (length eval)) + map + "" + ^ "\n}" + in + Printf.printf "\nevaluations : %s" s_eval + + (* Returns the maximum size of elements in evaluations ; + raise failure if max_size equals zero *) + let size_evaluations evaluations = + let evals = SMap.values evaluations in + let size_max = List.fold_left max 0 @@ List.map length evals in + if size_max = 0 then + failwith "size_evaluations: a maximum size of evaluations can't be zero!" + else size_max + + let not_found x = + raise + (Invalid_argument + (Printf.sprintf "Evaluations : %s not found in evaluations map." x)) + + let find_evaluation evaluations name = + match SMap.find_opt name evaluations with + | None -> not_found name + | Some x -> x + + (* Returns the evals of "X" as a domain + @raise Invalid_argument if "X" is not in evaluations + *) + let get_domain evaluations = to_domain (find_evaluation evaluations "X") + + let compute_evaluations ~domain poly_map = + SMap.map (evaluation_fft domain) poly_map + + (* Adds evaluation of poly_map’s polynomials on the domain given by the evaluation of "X" + @raise Invalid_argument if "X" is not in evaluations + *) + let compute_evaluations_update_map ?domain ~evaluations poly_map = + let domain = + match domain with Some domain -> domain | None -> get_domain evaluations + in + SMap.union_disjoint evaluations (compute_evaluations ~domain poly_map) + + let mul ?res ~evaluations ~poly_names ?composition_gx ?powers () = + let list_eval = List.map (find_evaluation evaluations) poly_names in + mul_c ?res ~evaluations:list_eval ?composition_gx ?powers () + + let linear ?res ~evaluations ~poly_names ?linear_coeffs ?composition_gx + ?add_constant () = + let list_eval = List.map (find_evaluation evaluations) poly_names in + linear_c + ?res + ~evaluations:list_eval + ?linear_coeffs + ?composition_gx + ?add_constant + () +end diff --git a/src/lib_plonk/gates_common.ml b/src/lib_plonk/gates_common.ml new file mode 100644 index 000000000000..df7a079b2ba8 --- /dev/null +++ b/src/lib_plonk/gates_common.ml @@ -0,0 +1,210 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Bls +open Identities +module L = Plompiler.LibCircuit + +type public = {public_inputs : Scalar.t array; input_coms_size : int} + +let one = Scalar.one + +let mone = Scalar.negate one + +let two = Scalar.add one one + +let left = "a" + +let right = "b" + +let output = "c" + +let top = "d" + +let bottom = "e" + +let com_label = "com" + +let tmp_buffers = ref [||] + +type answers = { + q : Poly.scalar; + a : Poly.scalar; + b : Poly.scalar; + c : Poly.scalar; + d : Poly.scalar; + e : Poly.scalar; + ag : Poly.scalar; + bg : Poly.scalar; + cg : Poly.scalar; + dg : Poly.scalar; + eg : Poly.scalar; +} + +type witness = { + q : Evaluations.t; + a : Evaluations.t; + b : Evaluations.t; + c : Evaluations.t; + d : Evaluations.t; + e : Evaluations.t; +} + +let get_buffers ~nb_buffers ~nb_ids = + let precomputed = !tmp_buffers in + let nb_precomputed = Array.length precomputed in + let size_eval = Evaluations.length precomputed.(0) in + let buffers = + Array.init (max nb_buffers nb_precomputed) (fun i -> + if i < nb_precomputed then precomputed.(i) + else Evaluations.create size_eval) + in + tmp_buffers := buffers ; + (buffers, Array.init nb_ids (fun _ -> Evaluations.create size_eval)) + +let get_answers ~q_label ~blinds ~prefix ~prefix_common answers : answers = + let dummy = Scalar.zero in + let answer = get_answer answers in + let answer_wire w = + match SMap.find_opt w blinds with + | Some array -> + assert (Array.length array = 2) ; + let w' = prefix w in + let x = if array.(0) = 0 then dummy else answer X w' in + let gx = if array.(1) = 0 then dummy else answer GX w' in + (x, gx) + | None -> (dummy, dummy) + in + let q = prefix_common q_label |> answer X in + let a, ag = answer_wire left in + let b, bg = answer_wire right in + let c, cg = answer_wire output in + let d, dg = answer_wire top in + let e, eg = answer_wire bottom in + {q; a; b; c; d; e; ag; bg; cg; dg; eg} + +let get_evaluations ~q_label ~blinds ~prefix ~prefix_common evaluations = + let dummy = Evaluations.zero in + let find_wire w = + match SMap.find_opt w blinds with + | Some array -> + assert (Array.length array = 2) ; + if array.(0) = 0 && array.(1) = 0 then dummy + else Evaluations.find_evaluation evaluations (prefix w) + | None -> dummy + in + { + q = Evaluations.find_evaluation evaluations (prefix_common q_label); + a = find_wire left; + b = find_wire right; + c = find_wire output; + d = find_wire top; + e = find_wire bottom; + } + +(* Block names to merge identities within, if identities are independent, use q_label instead. + For instance, we want to have want AddLeft and Addright identities to be merged inside the Arithmetic block, + we thus use "arith" as Map key for these gates identities. + We also want to use the ECC point addition identity independently, as such we put ECCAdd gate's q_label as key. *) +let arith = "Arith" + +let qadv_label = "qadv" + +let map_singleton m = + let map f t = + let open L in + let* x = t in + ret (f x) + in + map (fun x -> [x]) m + +module type Base_sig = sig + val q_label : string + + (* array.(i) = 1 <=> f is evaluated at (g^i)X *) + val blinds : int array SMap.t + + val identity : string * int + + val index_com : int option + + val nb_advs : int + + val nb_buffers : int + + val gx_composition : bool + + val equations : + q:Scalar.t -> + a:Scalar.t -> + b:Scalar.t -> + c:Scalar.t -> + d:Scalar.t -> + e:Scalar.t -> + ag:Scalar.t -> + bg:Scalar.t -> + cg:Scalar.t -> + dg:Scalar.t -> + eg:Scalar.t -> + ?precomputed_advice:Scalar.t SMap.t -> + unit -> + Scalar.t list + + val prover_identities : + prefix_common:(string -> string) -> + prefix:(string -> string) -> + public:public -> + domain:Domain.t -> + prover_identities + + val verifier_identities : + prefix_common:(string -> string) -> + prefix:(string -> string) -> + public:public -> + generator:Scalar.t -> + size_domain:int -> + verifier_identities + + (* Give the size of the domain on which the identities + of the gate need to have the evaluation of each of his polynomial + divided by the size of the citcuit. *) + val polynomials_degree : int SMap.t + + val cs : + q:L.scalar L.repr -> + a:L.scalar L.repr -> + b:L.scalar L.repr -> + c:L.scalar L.repr -> + d:L.scalar L.repr -> + e:L.scalar L.repr -> + ag:L.scalar L.repr -> + bg:L.scalar L.repr -> + cg:L.scalar L.repr -> + dg:L.scalar L.repr -> + eg:L.scalar L.repr -> + ?precomputed_advice:L.scalar L.repr SMap.t -> + unit -> + L.scalar L.repr list L.t +end diff --git a/src/lib_plonk/hash_gates.ml b/src/lib_plonk/hash_gates.ml new file mode 100644 index 000000000000..14782dc3a715 --- /dev/null +++ b/src/lib_plonk/hash_gates.ml @@ -0,0 +1,291 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Bls +open Identities +module L = Plompiler.LibCircuit +open Gates_common + +(* Anemoi 2 rounds + Arith monomial + degree : 6n + advice selectors : kx1, kx2, ky1, ky2 (round constants) + equations : x2, y2 = round(x1,y1) = round(round(x0, y0)) + 1) q · [g · x1 + ky1 - y1)^2 · beta - beta · y0^2 - (g^2 + 1) · x1 + g · y1 + delta - gamma + kx1 + x0] + 2) q · [g · x1 + ky1 + y0 - y1)^5 + beta · y0^2 + gamma - x0] + 3) q · [g · x2 + ky2 - y2)^2 · beta - beta · y1^2 - (g^2 + 1) · x2 + g · y2 + delta - gamma + kx2 + x1] + 4) q · [g · x2 + ky2 + y1 - y2)^5 + beta · y1^2 + gamma - x1] +*) +module AnemoiDouble : Base_sig = struct + module AnemoiPerm = Bls12_381_hash.Permutation.Anemoi + + let q_label = "q_anemoi" + + let identity = (q_label, 4) + + let index_com = None + + let nb_advs = 4 + + let nb_buffers = 3 + + let gx_composition = true + + let g = AnemoiPerm.Parameters.g + + let beta = AnemoiPerm.Parameters.beta + + let gamma = AnemoiPerm.Parameters.gamma + + let delta = AnemoiPerm.Parameters.delta + + let kx1_label = qadv_label ^ "0" + + let ky1_label = qadv_label ^ "1" + + let kx2_label = qadv_label ^ "2" + + let ky2_label = qadv_label ^ "3" + + let ( -@ ) a b = Scalar.sub a b + + let g2_p_1 = Scalar.((g * g) + one) + + (* Identities: + (g · x1 + ky1 - y1)^2 · beta - beta · y0^2 - (g^2 + 1) · x1 + g · y1 + delta - gamma + kx1 + x0 + (g · x1 + ky1 + y0 - y1)^5 + beta · y0^2 + gamma - x0 + (g · x2 + ky2 - y2)^2 · beta - beta · y1^2 - (g^2 + 1) · x2 + g · y2 + delta - gamma + kx2 + x1 + (g · x2 + ky2 + y1 - y2)^5 + beta · y1^2 + gamma - x1 + + a b c d e + wire #i: x1 y1 x0 y0 + wire #i+1: x2 y2 *) + let round_identities ~kx ~ky (x, y) (x', y') = + let mv = Scalar.((g * x') + ky -@ y') in + let w = Scalar.(mv + y) in + let c = Scalar.((g * y') + delta + kx + x -@ ((g2_p_1 * x') + gamma)) in + let beta_y2 = Scalar.(beta * y * y) in + let id1 = Scalar.((beta * mv * mv) -@ beta_y2 + c) in + let id2 = Scalar.(pow w (Z.of_int 5) + beta_y2 + gamma -@ x) in + [id1; id2] + + let cs_round_identities ~kx ~ky (x, y) (x', y') = + let open L in + let open Num in + let mg2_p_1 = Scalar.negate g2_p_1 in + let* mv = add_list ~coeffs:[g; one; mone] (to_list [x'; ky; y']) in + let* w = add mv y in + let* c = + add_list + ~qc:(delta -@ gamma) + ~coeffs:[g; one; one; mg2_p_1] + (to_list [y'; kx; x; x']) + in + let* beta_y2 = mul ~qm:beta y y in + let* beta_mv2_c = custom ~qx2b:beta ~ql:one c mv in + let* id1 = add ~qr:mone beta_mv2_c beta_y2 in + let* w5_x = custom ~qx5a:one ~qr:mone w x in + let* id2 = add ~qc:gamma w5_x beta_y2 in + ret [id1; id2] + + let evals_round_identities ~domain_size ~buffers ~selector ~id1_buffer + ~id2_buffer ~kx ~ky ?(compose' = 0) (x, y) (x', y') = + (* buffers.(0) <- g · x' - y' + ky *) + let gx'_y'_ky = + Evaluations.linear_c + ~res:buffers.(0) + ~evaluations:[x'; y'; ky] + ~linear_coeffs:[g; mone; one] + ~composition_gx:([compose'; compose'; 0], domain_size) + () + in + (* id1_buffer <- (g · x' + ky - y')^2 *) + let id1_partial = + Evaluations.mul_c ~res:id1_buffer ~evaluations:[gx'_y'_ky] ~powers:[2] () + in + (* buffers.(1) <- (g · x' + ky - y') + y *) + let w = + Evaluations.linear_c ~res:buffers.(1) ~evaluations:[gx'_y'_ky; y] () + in + (* id2_buffer <- (g · x' + ky + y - y')^5 *) + let id2_partial = + Evaluations.mul_c ~res:id2_buffer ~evaluations:[w] ~powers:[5] () + in + (* buffers.(2) <- y^2 *) + let y2 = + Evaluations.mul_c ~res:buffers.(2) ~evaluations:[y] ~powers:[2] () + in + (* buffer1 <- (g · x' + ky - y')^2 + y^2 + x' + y' + x + kx *) + let id1 = + Evaluations.linear_c + ~res:buffers.(0) + ~evaluations:[id1_partial; y2; x'; y'; x; kx] + ~linear_coeffs:Scalar.[beta; negate beta; negate g2_p_1; g; one; one] + ~composition_gx:([0; 0; compose'; compose'; 0; 0], domain_size) + ~add_constant:(delta -@ gamma) + () + in + (* buffer2 <- (g · x' + ky + y - y')^5 + y^2 + x *) + let id2 = + Evaluations.linear_c + ~res:buffers.(1) + ~evaluations:[id2_partial; y2; x] + ~linear_coeffs:[Scalar.one; beta; mone] + ~add_constant:gamma + () + in + (* id1_buffer <- q · (g · x' + ky - y')^2 + y^2 + x' + y' + x + kx *) + let qid1 = + Evaluations.mul_c ~res:id1_buffer ~evaluations:[selector; id1] () + in + (* id2_buffer <- q · (g · x' + ky + y - y')^5 + y^2 + x *) + let qid2 = + Evaluations.mul_c ~res:id2_buffer ~evaluations:[selector; id2] () + in + (qid1, qid2) + + let equations ~q ~a:_ ~b:x1 ~c:y1 ~d:x0 ~e:y0 ~ag:_ ~bg:_ ~cg:_ ~dg:x2 ~eg:y2 + ?(precomputed_advice = SMap.empty) () = + if Scalar.is_zero q then Scalar.[zero; zero; zero; zero] + else + let kx1 = SMap.find kx1_label precomputed_advice in + let ky1 = SMap.find ky1_label precomputed_advice in + let kx2 = SMap.find kx2_label precomputed_advice in + let ky2 = SMap.find ky2_label precomputed_advice in + let ids12 = round_identities ~kx:kx1 ~ky:ky1 (x0, y0) (x1, y1) in + let ids34 = round_identities ~kx:kx2 ~ky:ky2 (x1, y1) (x2, y2) in + ids12 @ ids34 + + let blinds = + SMap.of_list + [ + (left, [|0; 0|]); + (right, [|1; 0|]); + (output, [|1; 0|]); + (top, [|1; 1|]); + (bottom, [|1; 1|]); + ] + + let prover_identities ~prefix_common ~prefix ~public:_ ~domain : + prover_identities = + fun evaluations -> + let domain_size = Domain.length domain in + let buffers, ids = get_buffers ~nb_buffers ~nb_ids:(snd identity) in + let ({q; b; c; d; e; _} : witness) = + get_evaluations ~q_label ~blinds ~prefix ~prefix_common evaluations + in + let selector, x1, y1, x0, y0, x2, y2 = (q, b, c, d, e, d, e) in + + let kx1, ky1, kx2, ky2 = + ( Evaluations.find_evaluation evaluations (prefix_common kx1_label), + Evaluations.find_evaluation evaluations (prefix_common ky1_label), + Evaluations.find_evaluation evaluations (prefix_common kx2_label), + Evaluations.find_evaluation evaluations (prefix_common ky2_label) ) + in + let id1, id2 = + evals_round_identities + ~domain_size + ~buffers + ~selector + ~id1_buffer:ids.(0) + ~id2_buffer:ids.(1) + ~kx:kx1 + ~ky:ky1 + (x0, y0) + (x1, y1) + in + let id3, id4 = + evals_round_identities + ~domain_size + ~buffers + ~selector + ~id1_buffer:ids.(2) + ~id2_buffer:ids.(3) + ~kx:kx2 + ~ky:ky2 + ~compose':1 + (x1, y1) + (x2, y2) + in + SMap.of_list + [ + (prefix @@ q_label ^ ".0", id1); + (prefix @@ q_label ^ ".1", id2); + (prefix @@ q_label ^ ".2", id3); + (prefix @@ q_label ^ ".3", id4); + ] + + let verifier_identities ~prefix_common ~prefix ~public:_ ~generator:_ + ~size_domain:_ : verifier_identities = + fun _ answers -> + let {q; b; c; d; e; dg; eg; _} = + get_answers ~q_label ~blinds ~prefix ~prefix_common answers + in + let x0, y0, x1, y1, x2, y2 = (d, e, b, c, dg, eg) in + + let kx1 = get_answer answers X @@ prefix_common kx1_label in + let ky1 = get_answer answers X @@ prefix_common ky1_label in + let kx2 = get_answer answers X @@ prefix_common kx2_label in + let ky2 = get_answer answers X @@ prefix_common ky2_label in + let precomputed_advice = + SMap.of_list + [(kx1_label, kx1); (ky1_label, ky1); (kx2_label, kx2); (ky2_label, ky2)] + in + let identities = + equations + ~q + ~a:0 + ~b:x1 + ~c:y1 + ~d:x0 + ~e:y0 + ~ag:0 + ~bg:0 + ~cg:0 + ~dg:x2 + ~eg:y2 + ~precomputed_advice + () + |> List.map (Scalar.mul q) + in + SMap.of_list + @@ List.mapi + (fun i id -> (prefix @@ q_label ^ "." ^ string_of_int i, id)) + identities + + let polynomials_degree = + SMap.of_list [(right, 6); (output, 6); (top, 6); (bottom, 6); (q_label, 6)] + + let cs ~q ~a:_ ~b:x1 ~c:y1 ~d:x0 ~e:y0 ~ag:_ ~bg:_ ~cg:_ ~dg:x2 ~eg:y2 + ?(precomputed_advice = SMap.empty) () = + let open L in + let kx1 = SMap.find kx1_label precomputed_advice in + let ky1 = SMap.find ky1_label precomputed_advice in + let kx2 = SMap.find kx2_label precomputed_advice in + let ky2 = SMap.find ky2_label precomputed_advice in + let* ids12 = cs_round_identities ~kx:kx1 ~ky:ky1 (x0, y0) (x1, y1) in + let* ids34 = cs_round_identities ~kx:kx2 ~ky:ky2 (x1, y1) (x2, y2) in + mapM (fun id -> Num.mul q id) (ids12 @ ids34) +end diff --git a/src/lib_plonk/identities.ml b/src/lib_plonk/identities.ml new file mode 100644 index 000000000000..ee438cc0188e --- /dev/null +++ b/src/lib_plonk/identities.ml @@ -0,0 +1,89 @@ +open Bls + +module Identities : sig + (** The type for prover identities: functions from a (string) map of + polynomials in FFT evaluations form to a (string) map of evaluated + identities (also polynomials in FFT evaluations form). *) + type prover_identities = Evaluations.t SMap.t -> Evaluations.t SMap.t + + (** The type for verifier identities: functions which map an evaluation point + ξ an a [PC.answer] into a (string) map of evaluated identities. *) + type verifier_identities = + Scalar.t -> Scalar.t SMap.t SMap.t -> Scalar.t SMap.t + + (** The type for evaluation points. Either [X], [GX], or a custom point, + which must be specified by an evaluation point name paired with a + scalar that will multiply ξ. For example: + - [X] could be implemented as [Custom ("x", Scalar.one)] + - [GX] could be implemented as + [Custom ("gx", generator)]. *) + type eval_point = X | GX | Custom of string * Scalar.t [@@deriving repr] + + val string_of_eval_point : eval_point -> string + + (** [convert_eval_points gen x points] maps the polynomial protocol + [points : eval_point list] into scalars, by evaluating the underlying + "composition" polynomial at [x]. + The generator [gen] is used in case the [eval_point] equals [GX], in + which case the resulting scalar is [x * gen]. *) + val convert_eval_points : + generator:Scalar.t -> x:Scalar.t -> eval_point list -> Scalar.t SMap.t + + (** [get_answer answers p name] extracts the evaluation of polynomial [name] + at point [p] from the given [answers]. *) + val get_answer : Scalar.t SMap.t SMap.t -> eval_point -> string -> Scalar.t + + (** A function to merge a list of prover identities into one. *) + val merge_prover_identities : prover_identities list -> prover_identities + + (** A function to merge a list of verifier identities into one. *) + val merge_verifier_identities : + verifier_identities list -> verifier_identities +end = struct + type prover_identities = Evaluations.t SMap.t -> Evaluations.t SMap.t + + type verifier_identities = + Scalar.t -> Scalar.t SMap.t SMap.t -> Scalar.t SMap.t + + type eval_point = X | GX | Custom of string * Scalar.t [@@deriving repr] + + let string_of_eval_point = function + | X -> "x" + | GX -> "gx" + | Custom (s, _) -> s + + let convert_eval_points ~generator ~x l = + let eval = function + | X -> x + | GX -> Scalar.mul generator x + | Custom (_, f) -> Scalar.mul f x + in + SMap.of_list @@ List.map (fun p -> (string_of_eval_point p, eval p)) l + + let get_answer answers x n = + let x_map = SMap.find (string_of_eval_point x) answers in + match SMap.find_opt n x_map with + | Some x -> x + | None -> + raise + (Invalid_argument + (Printf.sprintf + "Identities.get_answers : name '%s' not found in answers." + n)) + + let merge_prover_identities identities_list : prover_identities = + fun evaluations -> + List.fold_left + (fun acc_map ids -> SMap.union_disjoint acc_map (ids evaluations)) + SMap.empty + identities_list + + let merge_verifier_identities identities_list : verifier_identities = + fun x answers -> + List.fold_left + (fun acc_map ids -> SMap.union_disjoint acc_map (ids x answers)) + SMap.empty + identities_list +end + +include Identities diff --git a/src/lib_plonk/input_commitment.ml b/src/lib_plonk/input_commitment.ml new file mode 100644 index 000000000000..3651edc73b9f --- /dev/null +++ b/src/lib_plonk/input_commitment.ml @@ -0,0 +1,57 @@ +open Bls + +module type S = sig + module Commitment : + Polynomial_commitment.Commitment_sig with type secret = Poly.t SMap.t + + type public_parameters = Commitment.prover_public_parameters + + type prover_aux = {poly : Poly.t; pc_prover_aux : Commitment.prover_aux} + [@@deriving repr] + + type public = Commitment.t [@@deriving repr] + + type t = {public : public; prover_aux : prover_aux} [@@deriving repr] + + (* size is the expected length of the commitment ; it must be at least bigger + than the length of the secret if it’s given, the secret is padded with zero + to reach this length *) + val commit : + ?size:int -> ?shift:int -> public_parameters -> int -> Scalar.t array -> t +end + +module Make_impl (Commitment : Polynomial_commitment.Commitment_sig) = struct + module Commitment = Commitment + + type public_parameters = Commitment.prover_public_parameters + + type prover_aux = {poly : Poly.t; pc_prover_aux : Commitment.prover_aux} + [@@deriving repr] + + type public = Commitment.t [@@deriving repr] + + type t = {public : public; prover_aux : prover_aux} [@@deriving repr] + + let commit ?size ?(shift = 0) pp n secret = + let domain = Domain.build n in + let l = Array.length secret in + let size = Option.value ~default:l size in + let secret = + Array.(append secret (init (size - l) (Fun.const Scalar.zero))) + in + (* we add some randomness to hide the secret *) + let secret = + let random _ = Scalar.random () in + let head = Array.init shift random in + let tail = Array.init (n - size - shift) random in + Array.concat [head; secret; tail] + in + let poly = Evaluations.interpolation_fft2 domain secret in + let poly_map = SMap.singleton "com" poly in + let public, pc_prover_aux = Commitment.commit pp poly_map in + {public; prover_aux = {poly; pc_prover_aux}} +end + +module Make : functor (Commitment : Polynomial_commitment.Commitment_sig) -> + S with module Commitment = Commitment = + Make_impl diff --git a/src/lib_plonk/list.ml b/src/lib_plonk/list.ml new file mode 100644 index 000000000000..14c6c9fa0e46 --- /dev/null +++ b/src/lib_plonk/list.ml @@ -0,0 +1,159 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +include Stdlib.List +module List = Stdlib.List + +(* Separate the heads and the tails of a list of list. + raises if one of the lists is empty *) +let get_heads_and_tails ll = + let rec aux heads tails = function + | [] -> (rev heads, rev tails) + | (h :: t) :: ll -> aux (h :: heads) (t :: tails) ll + | _ -> raise (Invalid_argument "get_firsts_and_tails: one list is empty") + in + aux [] [] ll + +(* map for n lists of the same size grouped in ln *) +(* the use of get_firsts_and_tails ensures all lists in ln have the same size *) +let mapn f = function + | [] -> [] + | ln -> + let rec aux ln = + match hd ln with + | [] -> [] + | _ -> + let heads, tails = get_heads_and_tails ln in + f heads :: aux tails + in + aux ln + +(* List.fold_left2 which stops when end of one of the lists is reached *) +let rec fold_left2_opt f acc l1 l2 = + match (l1, l2) with + | [], _ -> acc + | _, [] -> acc + | a1 :: l1, a2 :: l2 -> fold_left2_opt f (f acc a1 a2) l1 l2 + +(* List.fold_left for 3 lists of same size *) +let rec fold_left3 f acc l1 l2 l3 = + match (l1, l2, l3) with + | [], [], [] -> acc + | a1 :: l1, a2 :: l2, a3 :: l3 -> fold_left3 f (f acc a1 a2 a3) l1 l2 l3 + | _ -> raise (Invalid_argument "fold_left3 : lists don’t have the same size.") + +(* List.fold_left for 4 lists of same size *) +let rec fold_left4 f acc l1 l2 l3 l4 = + match (l1, l2, l3, l4) with + | [], [], [], [] -> acc + | a1 :: l1, a2 :: l2, a3 :: l3, a4 :: l4 -> + fold_left4 f (f acc a1 a2 a3 a4) l1 l2 l3 l4 + | _ -> raise (Invalid_argument "fold_left4 : lists don’t have the same size.") + +(* List.fold_left for 5 lists of same size *) +let rec fold_left5 f acc l1 l2 l3 l4 l5 = + match (l1, l2, l3, l4, l5) with + | [], [], [], [], [] -> acc + | a1 :: l1, a2 :: l2, a3 :: l3, a4 :: l4, a5 :: l5 -> + fold_left5 f (f acc a1 a2 a3 a4 a5) l1 l2 l3 l4 l5 + | _ -> raise (Invalid_argument "fold_left5 : lists don’t have the same size.") + +(* List.fold_left for 6 lists of same size *) +let rec fold_left6 f acc l1 l2 l3 l4 l5 l6 = + match (l1, l2, l3, l4, l5, l6) with + | [], [], [], [], [], [] -> acc + | a1 :: l1, a2 :: l2, a3 :: l3, a4 :: l4, a5 :: l5, a6 :: l6 -> + fold_left6 f (f acc a1 a2 a3 a4 a5 a6) l1 l2 l3 l4 l5 l6 + | _ -> raise (Invalid_argument "fold_left6 : lists don’t have the same size.") + +let split_n n l = + let rec aux acc k l = + if k = n then (List.rev acc, l) + else + match l with + | h :: t -> aux (h :: acc) (k + 1) t + | [] -> + raise + (Invalid_argument + (Printf.sprintf "split_n: n=%d >= List.length l=%d" n k)) + in + aux [] 0 l + +let split_in_half l = + let len = List.length l in + match len mod 2 with + | 0 -> split_n (len / 2) l + | _ -> + raise + (Invalid_argument + (Printf.sprintf "split_in_half: length %d not even." len)) + +let map f l = rev (rev_map f l) + +let map2 f l1 l2 = rev (rev_map2 f l1 l2) + +let rev_mapi f l = + let rec rmap_f i accu = function + | [] -> accu + | a :: l -> rmap_f (i + 1) (f i a :: accu) l + in + rmap_f 0 [] l + +let mapi f l = rev (rev_mapi f l) + +(* not tail-recursive *) +let rec map2_opt merge l1 l2 = + match (l1, l2) with + | [], _ -> l2 + | _, [] -> l1 + | h1 :: t1, h2 :: t2 -> merge h1 h2 :: map2_opt merge t1 t2 + +(* same as List.combine but allows lists of different sizes *) +let safe_combine l1 l2 = + let rec aux acc l1 l2 = + match (l1, l2) with + | [], _ -> List.rev acc + | _, [] -> List.rev acc + | h1 :: t1, h2 :: t2 -> aux ((h1, h2) :: acc) t1 t2 + in + aux [] l1 l2 + +exception Internal + +(* equivalent to List.rev (List.flatten l) but tail recursive*) +let rev_flatten l = + let rec aux res l = + match l with [] -> res | h :: t -> aux (List.rev_append h res) t + in + aux [] l + +let flatten l = List.rev @@ rev_flatten l + +(* applies a random permutation to the elements of the given list *) +let shuffle ?seed l = + (match seed with None -> () | Some i -> Random.init i) ; + List.rev_map (fun x -> (Random.bits (), x)) l + |> List.sort (fun (i, _) (j, _) -> Int.compare i j) + |> List.rev_map snd diff --git a/src/lib_plonk/main_protocol.ml b/src/lib_plonk/main_protocol.ml new file mode 100644 index 000000000000..4108eb76096f --- /dev/null +++ b/src/lib_plonk/main_protocol.ml @@ -0,0 +1,1391 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** + aPlonK is a {e PlonK}-based proving system. + As such, it provides a way to create {e succinct cryptographic proofs} + about a given predicate, which can be then verified with a low + computational cost. + + In this system, a predicate is represented by an {e arithmetic circuit}, + i.e. a collection of arithmetic {e gates} operating over a {e prime field}, + connected through {e wires} holding {e scalars} from this field. + For example, the following diagram illustrates a simple circuit checking that + the addition of two scalars ([w1] and [w2]) is equal to [w0]. Here, + the [add] gate can be seen as taking two inputs and producing an output, + while the [eq] gate just takes two inputs and asserts they're equal. + +{[ + (w0)│ w1│ w2│ + │ └───┐ ┌───┘ + │ ┌─┴───┴─┐ + │ │ add │ + │ └───┬───┘ + └──────┐ ┌───┘w3 + ┌─┴───┴─┐ + │ eq │ + └───────┘ +]} + + The wires of a circuit are called {e prover inputs}, since the prover needs + an assignment of all wires to produce a proof. + The predicate also declares a subset of the wires called {e verifier inputs}. + In our example, wire [w0] is the only verifier input, which is + indicated by the parenthesis. + A proof for a given [w0] would prove the following statement: + [∃ w1, w2, w3: w3 = w1 + w2 ∧ w0 = w3] + This means that the verifier only needs a (typically small) subset of the + inputs alongside the (succinct) proof to check the validity of the statement. + + A more interesting example would be to replace the [add] gate + by a more complicated hash circuit. This would prove the knowledge of the + pre-image of a hash. + + A simplified view of aPlonk's API consists of the following three functions: +{[ + val setup : circuit -> srs -> + (prover_public_parameters, verifier_public_parameters) + + val prove : prover_public_parameters -> prover_inputs -> + private_inputs -> proof + + val verify : verifier_public_parameters -> verifier_inputs -> + proof -> bool +]} + + In addition to the prove and verify, the interface provides a function + to setup the system. The setup function requires a {e Structured Reference String}. + Two large SRSs were generated by the ZCash and Filecoin + projects and are both used in aPlonK. + Notice also that the circuit is used during setup only and, independently + from its size, the resulting {e verifier_public_parameters} will be a + succinct piece of data that will be posted on-chain to allow + verification and they are bound to the specific circuit that generated + them. + The {e prover_public_parameters}'s size is linear in the size of the circuit. + *) + +open Bls +open Utils +open Identities +include Main_protocol_intf + +module Make_impl (PP : Polynomial_protocol.S) = struct + module RangeCheck = Range_check_gate.Range_check_gate (PP) + module Perm = Permutation_gate.Permutation_gate (PP) + module Plook = Plookup_gate.Plookup_gate (PP) + module Gates = Custom_gates + module Commitment = PP.PC.Commitment + module Input_commitment = Input_commitment.Make (PP.PC.Commitment) + module PP = PP + + exception Entry_not_in_table = Plook.Entry_not_in_table + + exception Rest_not_null = Poly.Rest_not_null + + type scalar = Scalar.t [@@deriving repr] + + type circuit_map = (Circuit.t * int) SMap.t + + type proof = { + perm_and_plook : Commitment.t; + wires_cm : Commitment.t; + pp_proof : PP.proof; + } + [@@deriving repr] + + type circuit_prover_input = { + witness : scalar array; + input_commitments : Input_commitment.t list; + } + [@@deriving repr] + + type prover_inputs = circuit_prover_input list SMap.t [@@deriving repr] + + type public_inputs = scalar array list [@@deriving repr] + + type verifier_inputs = + (public_inputs * Input_commitment.public list list) SMap.t + [@@deriving repr] + + let check_circuit_name map = + SMap.iter + (fun name _ -> + if name = "" then () + else if Char.compare name.[0] '9' <= 0 then + failwith + (Printf.sprintf "check_circuit_name : circuit name (= '%s')" name + ^ " must not begin with '\\', '#', '$', '%', '&', ''', '(', ')', \ + '*', '+', ',', '-', '.', '/' or a digit.") + else if String.contains name SMap.Aggregation.sep.[0] then + failwith + (Printf.sprintf + "check_circuit_name : circuit name (= '%s') mustn't contain '%s'" + name + SMap.Aggregation.sep)) + map + + let check_circuits circuits_map inputs = + check_circuit_name inputs ; + SMap.( + iter (fun k _ -> + if not (mem k circuits_map) then + failwith + (Printf.sprintf + "check_circuits : circuit %s not found in public parameters." + k))) + inputs + + (* Returns wires names as a list of strings ; the i-th wire is named after + the i-th letter of the alphabet + *) + let get_wires_names nb_wires = + let alphabet = "abcdefghijklmnopqrstuvwxyz" in + List.init nb_wires (fun i -> Char.escaped alphabet.[i]) + + let hash_verifier_inputs verifier_inputs = + let open Utils.Hash in + let bytes_of_com c = Plompiler.Utils.to_bytes Input_commitment.public_t c in + let st = init () in + SMap.iter + (fun key (public_inputs_list, input_commitments_list) -> + update st (Bytes.of_string key) ; + List.iter + (fun pi -> Array.iter (fun s -> update st (Scalar.to_bytes s)) pi) + public_inputs_list ; + List.iter + (List.iter (fun c -> update st (bytes_of_com c))) + input_commitments_list) + verifier_inputs ; + finish st + + type gate_randomness = { + beta_perm : scalar; + gamma_perm : scalar; + beta_plook : scalar; + gamma_plook : scalar; + beta_rc : scalar; + gamma_rc : scalar; + delta : scalar; + } + + let build_gates_randomness transcript = + let betas_gammas, transcript = Fr_generation.random_fr_list transcript 7 in + let beta_perm = List.hd betas_gammas in + let gamma_perm = List.nth betas_gammas 1 in + let beta_plook = List.nth betas_gammas 2 in + let gamma_plook = List.nth betas_gammas 3 in + let beta_rc = List.nth betas_gammas 4 in + let gamma_rc = List.nth betas_gammas 5 in + let delta = List.nth betas_gammas 6 in + ( {beta_perm; gamma_perm; beta_plook; gamma_plook; beta_rc; gamma_rc; delta}, + transcript ) + + module Prover = struct + (* - n : upper-bound on the number of constraints in a circuit + - domain : n powers of an n-th root of unity + - pp_public_parameters : polynomial protocol prover parameters + - g_map : preprocessed polynomials for each circuit, prefixed with the + circuit name ; note that this is circuit specific, but we need + them together in order to commit to the whole g_map once. + - g_prover_aux : auxiliary information returned when commiting to g_map. + Note that the rest of the commitment is not needed by + the prover. + - evaluations : FFT evaluations of commonly used polynomials for all + circuits, e.g. L1, Si1, Si2, Si3, X (Lnp1 for plookup). + Each evaluation is on a domain that may be bigger than + [domain] the size is [4n] for most polynomials and [8n] + for some of them. For that, there must exist a [8n]-th + root of unity in the scalar field. These evaluations + does not contain g_map’s. + - zk : true if we want to hide witness polynomial by adding multiple of + (X^n - 1). This increases polynomials degree & may increase the + the size of the evaluations domain & FFTs. + - nb_of_t_chunks : number of T polynomials returned by PP + - eval_points : used for the PC query ; note that the input commitments + are not here, their eval_points have to be added at + proof/verification time + *) + type common_prover_pp = { + n : int; + domain : Domain.t; + pp_public_parameters : PP.prover_public_parameters; + g_map : Poly.t SMap.t; + g_prover_aux : Commitment.prover_aux; + evaluations : Evaluations.t SMap.t; + zk : bool; + nb_of_t_chunks : int; + eval_points : eval_point list list; + } + [@@deriving repr] + + (* - circuit_size : number of constraints in the circuit + - input_com_sizes : the size of each input_commitment + - public_input_size : the size of the public inputs + - gates : map from selector names to an array of selector coefficients + (one selector coefficient per constraint). + The length of such array is the domain size (also n). If there + are fewer constraints than n, the array is padded with 0's, + except qpub, that should be [||] if there are public inputs. + - tables : [tables] is a list of scalar arrays, one per wire, so the list + length is nb_wires, typically 5. + Each array is the concatenation of one of the columns of all + Plookup tables. (One column per wire, tables which use fewer + columns are completed with dummy ones). + Each scalar array is a concatenation of tables + - wires : map from wire names to an array of indices (one index per + constraint representing the variable that such wire takes at + that constraint). + Again, the length of such array is the domain size (i.e. n). + If there are fewer constraints than n, the array is padded with + the last array element. + - permutation: indices corresponding to a permutation that preserves + [wires]. Its length is [n * nb_wires], typically [5n] and + should be maximal in the sense that it splits in as many cycles + as there are variables in the circuit. + - evaluations : similar as the common_pp evaluations, but for the + circuit-specific polynomials (selectors, Ss_i, plookup polys), + that are contained in common_pp.g_map. + - alpha : scalar used by plookup. + - ultra : flag to specify whether plookup is being used. + *) + type circuit_prover_pp = { + circuit_size : int; + input_com_sizes : int list; + public_input_size : int; + gates : Scalar.t array SMap.t; + tables : Scalar.t array list; + wires : int array SMap.t; + permutation : int array; + rc_permutation : int array; + evaluations : Evaluations.t SMap.t; + alpha : Scalar.t option; + ultra : bool; + range_checks : int list * int; + } + [@@deriving repr] + + type public_parameters = { + common_pp : common_prover_pp; + circuits_map : circuit_prover_pp SMap.t; + transcript : PP.transcript; + } + [@@deriving repr] + + let enforce_wire_values wire_indices wire_values = + try + SMap.map + (fun l -> + let w_array = Array.map (fun index -> wire_values.(index)) l in + Evaluations.of_array (Array.length w_array - 1, w_array)) + wire_indices + with Invalid_argument _ -> + failwith + "Compute_wire_polynomial : x's length does not match with circuit. \ + Either your witness is too short, or some indexes in a, b or c are \ + greater than the witness size." + + let compute_wire_polynomials ~zero_knowledge ~gates n domain wires = + let unblinded_res = + SMap.map (fun w -> Evaluations.interpolation_fft domain w) wires + in + if zero_knowledge then + let nb_blinds_map = Gates.aggregate_blinds ~gates in + let polys_and_blinds = + SMap.mapi + (fun name f -> + (* 1 more blind is added for the commitment evaluation *) + let nb_blinds = + 1 + Option.value ~default:0 (SMap.find_opt name nb_blinds_map) + in + Poly.blind ~nb_blinds n f) + unblinded_res + in + (SMap.map fst polys_and_blinds, Some (SMap.map snd polys_and_blinds)) + else (unblinded_res, None) + + (* returns informations about wires, including commitment, blinds & + different useful representations of wires *) + let commit_to_wires ?all_keys ?shifts_map pp + (inputs_map : circuit_prover_input list SMap.t) = + (* wires values map list map *) + let wires_list_map = + SMap.mapi + (fun name input -> + let circuit_pp = SMap.find name pp.circuits_map in + List.map + (fun w -> enforce_wire_values circuit_pp.wires w.witness) + input) + inputs_map + in + (* wires polynomials map list map & there blinds *) + let f_wires, f_blinds = + SMap.mapi + (fun name w_list -> + let circuit_pp = SMap.find name pp.circuits_map in + List.map + (compute_wire_polynomials + ~zero_knowledge:pp.common_pp.zk + ~gates:circuit_pp.gates + pp.common_pp.n + pp.common_pp.domain) + w_list + |> List.split) + wires_list_map + |> SMap.two_maps_of_pair_map + in + (* all wires polynomials gather in a map *) + let all_f_wires = SMap.Aggregation.gather_maps ?shifts_map f_wires in + let cm_wires, cm_aux_wires = + Commitment.commit + ?all_keys + pp.common_pp.pp_public_parameters + all_f_wires + in + (wires_list_map, f_wires, f_blinds, all_f_wires, cm_wires, cm_aux_wires) + + (* The shared permutation argument consists of leveraging the fact that + all proofs of the same circuit type share the same permutation + for ensuring the copy-satisfiability. + This allows us to run a single permutation argument on a linear + combination of the wire polynomials of all same-circuit proofs. + Namely, let a_i(X), b_i(X), c_i(X) be the wire polynomials of the + i-th proof. Let delta be some scalar sampled after (and based on) + a commitment to all a_i, b_i, c_i and consider batched polynomials: + A(X) := \sum_i delta^{i-1} a_i(X) + B(X) := \sum_i delta^{i-1} b_i(X) + C(X) := \sum_i delta^{i-1} c_i(X) + We will perform a single permutation argument for A, B and C. *) + let build_batched_wires_values {delta; _} wires_list_map = + let nb_wires = SMap.(cardinal (List.hd (choose wires_list_map |> snd))) in + let agg_map = + SMap.of_list ((List.map (fun i -> (i, []))) (get_wires_names nb_wires)) + in + SMap.map + (fun l -> + List.fold_left + (fun acc wires -> + (SMap.mapi (fun k v -> SMap.find k wires :: v)) acc) + agg_map + (List.rev l) + |> SMap.map (fun ws_list -> + Evaluations.linear_with_powers ws_list delta)) + wires_list_map + |> SMap.(map (update_keys String.capitalize_ascii)) + + (* For each circuit, interpolates the batched wires A, B, C from the + batched witness *) + let batched_wires_poly_of_batched_wires {common_pp; _} batched_wires + (delta, f_blinds) = + let batched_polys = + SMap.map + (fun w -> Evaluations.interpolation_fft common_pp.domain w) + batched_wires + in + if not common_pp.zk then batched_polys + else + (* delta is only used to batched the blinds, the polys are computed + from a witness batched with delta already *) + let batched_blinds = + let f_blinds = List.map (fun b -> Option.get b) f_blinds in + SMap.map_list_to_list_map f_blinds + |> SMap.map (fun p -> Poly.linear_with_powers p delta) + in + SMap.mapi + (fun name f -> + let b = SMap.find name batched_blinds in + Poly.(f + mul_xn b common_pp.n Scalar.(negate one))) + batched_polys + + (* compute the batched polynomials A, B, C for the shared-permutation + argument; polynomial A (analogously B and C) can be computed by + batching polynomials a_i with powers of delta; or alternatively, by + applying an IFFT interpolation on the batched witness; we expect + the latter to be more efficient if the number of batched proofs + is over the threshold of [log2(n)] proofs, where [n] is the domain + size: this is because polynomial batching would require about + [n * nb_proofs] scalar operations (per polynomial) whereas the IFFT + would need [n * log2(n)]; such theoretical threshold has also been + empirically sustained with benchmarks *) + let build_batched_witness_polys pp {delta; _} f_blinds batched_wires f_wires + = + let logn = Z.log2 @@ Z.of_int pp.common_pp.n in + let batched_witness_polys = + SMap.mapi + (fun name wires_list -> + let batched_wires = SMap.find name batched_wires in + let f_blinds = SMap.find name f_blinds in + if List.compare_length_with wires_list logn > 0 then + (* we apply an IFFT on the batched witness *) + batched_wires_poly_of_batched_wires + pp + batched_wires + (delta, f_blinds) + else + (* Use capital for the batched wires *) + let wires_list = + List.map (SMap.update_keys String.capitalize_ascii) wires_list + in + (* we batched the a_i polynomials (analogously for b_i and c_i) *) + SMap.map (fun p -> Poly.linear_with_powers p delta) + @@ SMap.map_list_to_list_map wires_list) + f_wires + in + batched_witness_polys |> SMap.Aggregation.smap_of_smap_smap + + (* For each circuits, compute the shared Z polynomial *) + let build_f_map_perm pp {beta_perm = beta; gamma_perm = gamma; _} + batched_wires = + SMap.mapi + (fun name values -> + let circuit_pp = SMap.find name pp.circuits_map in + let zs = + Perm.f_map_contribution + ~permutation:circuit_pp.permutation + ~values + ~beta + ~gamma + ~domain:pp.common_pp.domain + in + if pp.common_pp.zk then + SMap.map + (fun f -> fst (Poly.blind ~nb_blinds:3 pp.common_pp.n f)) + zs + else zs) + batched_wires + |> SMap.Aggregation.smap_of_smap_smap + + (* For each circuit, computes Plookup-specific polynomials *) + let build_f_map_plook ?shifts_map pp + {beta_plook = beta; gamma_plook = gamma; _} wires_list_map = + SMap.mapi + (fun name w_list -> + let circuit_pp = SMap.find name pp.circuits_map in + if not circuit_pp.ultra then [] + else + List.map + (fun wires -> + let plook_map = + Plook.f_map_contribution + ~wires + ~gates:circuit_pp.gates + ~tables:circuit_pp.tables + ~alpha:circuit_pp.alpha + ~beta + ~gamma + ~domain:pp.common_pp.domain + ~circuit_size:circuit_pp.circuit_size + in + if pp.common_pp.zk then + SMap.map + (fun f -> fst (Poly.blind ~nb_blinds:3 pp.common_pp.n f)) + plook_map + else plook_map) + w_list) + wires_list_map + |> SMap.Aggregation.gather_maps ?shifts_map + + let build_f_map_range_checks ?shifts_map pp + {beta_rc = beta; gamma_rc = gamma; _} wires_list_map = + SMap.mapi + (fun name w_list -> + let circuit_pp = SMap.find name pp.circuits_map in + if fst circuit_pp.range_checks = [] then [] + else + List.map + (fun wires -> + let rc_map = + RangeCheck.f_map_contribution + ~permutation:circuit_pp.rc_permutation + ~beta + ~gamma + ~domain:pp.common_pp.domain + ~range_checks:circuit_pp.range_checks + ~values:wires + in + if pp.common_pp.zk then + SMap.map + (fun f -> fst (Poly.blind ~nb_blinds:3 pp.common_pp.n f)) + rc_map + else rc_map) + w_list) + wires_list_map + |> SMap.Aggregation.gather_maps ?shifts_map + + let format_input_com (inputs_map : circuit_prover_input list SMap.t) = + SMap.mapi + (fun name l -> + let n = List.length l in + List.mapi + (fun i w -> + (* For each proof, transforms the list of inputs commitments into + a map of the form {com_label0 -> ic0 ; com_label1 -> ic1 ; …} *) + (List.mapi (fun j ic -> + let name = + SMap.Aggregation.add_prefix + ~n + ~i + name + (Gates.com_label ^ string_of_int j) + in + ( Input_commitment.(SMap.singleton name ic.prover_aux.poly), + ic.prover_aux.pc_prover_aux ))) + w.input_commitments) + l + |> List.concat) + inputs_map + |> SMap.values |> List.concat + + let build_evaluations pp f_map = + (* rebuild g_maps’ evaluations *) + let evaluations = + SMap.fold + (fun _ pp evals -> SMap.union_disjoint pp.evaluations evals) + pp.circuits_map + pp.common_pp.evaluations + in + Evaluations.compute_evaluations_update_map ~evaluations f_map + + let build_perm_identities pp rd = + SMap.mapi + (fun circuit_name circuit_pp -> + let wires_names = SMap.keys circuit_pp.wires in + let perm_identities = + (* Using the batched wires *) + let wires_names = List.map String.capitalize_ascii wires_names in + Perm.prover_identities + ~circuit_name + ~wires_names + ~beta:rd.beta_perm + ~gamma:rd.gamma_perm + ~n:pp.common_pp.n + () + in + perm_identities) + pp.circuits_map + |> SMap.values |> merge_prover_identities + + let build_gates_plook_rc_identities ?shifts_map pp + {beta_plook; gamma_plook; beta_rc; gamma_rc; _} inputs_map = + let identities_map = + SMap.mapi + (fun circuit_name inputs_list -> + let circuit_pp = SMap.find circuit_name pp.circuits_map in + let wires_names = SMap.keys circuit_pp.wires in + (* Identities that must be computed for each proof *) + let shift, nb_proofs = + match shifts_map with + | None -> (0, List.length inputs_list) + | Some shifts_map -> SMap.find circuit_name shifts_map + in + let gates_identities = + List.mapi + (fun i inputs -> + let input_coms_size = + List.fold_left ( + ) 0 circuit_pp.input_com_sizes + in + let public_inputs = + Array.sub + inputs.witness + input_coms_size + circuit_pp.public_input_size + in + Gates.aggregate_prover_identities + ~circuit_name + ~nb_proofs + ~input_coms_size + ~proof_idx:(i + shift) + ~gates:circuit_pp.gates + ~public_inputs + ~domain:pp.common_pp.domain + ()) + inputs_list + in + let plookup_identities = + if not circuit_pp.ultra then [] + else + List.init nb_proofs (fun proof_idx -> + Plook.prover_identities + ~circuit_name + ~nb_proofs + ~proof_idx + ~wires_names + ~alpha:circuit_pp.alpha + ~beta:beta_plook + ~gamma:gamma_plook + ~n:pp.common_pp.n + ()) + in + let rc_identities = + if fst circuit_pp.range_checks = [] then [] + else + List.init nb_proofs (fun proof_idx -> + RangeCheck.prover_identities + ~circuit_name + ~nb_proofs + ~proof_idx + ~beta:beta_rc + ~gamma:gamma_rc + ~domain_size:pp.common_pp.n + ()) + in + merge_prover_identities + (plookup_identities @ gates_identities @ rc_identities)) + inputs_map + in + merge_prover_identities (SMap.values identities_map) + + let prove_parameters ~pp_prove pp ~inputs_map = + let wires_list_map, f_wires, f_blinds, all_f_wires, cm_wires, cm_aux_wires + = + commit_to_wires pp inputs_map + in + (* compute beta & gamma (common for all proofs) *) + let transcript = Transcript.expand Commitment.t cm_wires pp.transcript in + let rd, transcript = build_gates_randomness transcript in + + let batched_wires = build_batched_wires_values rd wires_list_map in + + let f_map_contributions = + let f_map_perm = build_f_map_perm pp rd batched_wires in + let f_map_plook = build_f_map_plook pp rd wires_list_map in + let f_map_rc = build_f_map_range_checks pp rd wires_list_map in + SMap.union_disjoint_list [f_map_perm; f_map_plook; f_map_rc] + in + + let input_com_secrets = format_input_com inputs_map in + + let identities = + let perm_ids = build_perm_identities pp rd in + let gates_plook_rc_ids = + build_gates_plook_rc_identities pp rd inputs_map + in + merge_prover_identities [perm_ids; gates_plook_rc_ids] + in + + let eval_points = + pp.common_pp.eval_points @ List.map (Fun.const [X]) input_com_secrets + in + + let batched_wires_polys = + build_batched_witness_polys pp rd f_blinds batched_wires f_wires + in + + let evaluations = + build_evaluations + pp + (SMap.union_disjoint_list + (all_f_wires :: f_map_contributions :: batched_wires_polys + :: List.map fst input_com_secrets)) + in + + let cm_perm_plook_rc, perm_plook_rc_prv_aux = + Commitment.commit pp.common_pp.pp_public_parameters f_map_contributions + in + let transcript = + Transcript.expand Commitment.t cm_perm_plook_rc transcript + in + + let secrets = + [ + (pp.common_pp.g_map, pp.common_pp.g_prover_aux); + (f_map_contributions, perm_plook_rc_prv_aux); + (all_f_wires, cm_aux_wires); + ] + @ input_com_secrets + in + + let generator = Domain.get pp.common_pp.domain 1 in + let pp_proof, _transcript = + pp_prove + pp.common_pp.pp_public_parameters + transcript + ~n:pp.common_pp.n + ~generator + ~secrets + ~eval_points + ~evaluations + ~identities + ~nb_of_t_chunks:pp.common_pp.nb_of_t_chunks + in + + (pp_proof, (cm_perm_plook_rc, cm_wires, rd)) + end + + module Verifier = struct + (* - n : upper-bound on the number of constraints in a circuit + - generator : primitive n-th root of unity + - pp_public_parameters : polynomial protocol verifier parameters + - cm_g : commitment to the preprocessed polynomials + - eval_points : used for the PC query ; note that the input commitments + are not here, their eval_points have to be added at + proof/verification time + *) + type common_verifier_pp = { + n : int; + generator : Scalar.t; + pp_public_parameters : PP.verifier_public_parameters; + cm_g : Commitment.t; + eval_points : eval_point list list; + } + [@@deriving repr] + + (* - gates : map of selector names ; they are binded to unit because we + just need their name for the verification + - nb_wires : wire architecture (number of wires per gate, typically 3) + - alpha : scalar used by plookup. + - ultra : flag to specify whether plookup is being used. + - input_com_sizes : the size of each input_commitment + *) + type circuit_verifier_pp = { + gates : unit SMap.t; + nb_wires : int; + alpha : Scalar.t option; + ultra : bool; + input_com_sizes : int list; + range_checks : bool; + } + [@@deriving repr] + + let circuit_verifier_pp_of_circuit_prover_pp + (prover_pp : Prover.circuit_prover_pp) = + { + gates = SMap.map (Fun.const ()) prover_pp.gates; + (* TODO: remove obsolete nb_wires field from circuit_verifier_pp *) + nb_wires = Plompiler.Csir.nb_wires_arch; + alpha = prover_pp.alpha; + ultra = prover_pp.ultra; + input_com_sizes = prover_pp.input_com_sizes; + range_checks = fst prover_pp.range_checks <> []; + } + + let build_identities circuits_map (n, generator) rd public_inputs_map = + let identities_map = + SMap.mapi + (fun circuit_name pi_list -> + let circuit_pp = SMap.find circuit_name circuits_map in + let nb_proofs = List.length pi_list in + let wires_names = get_wires_names circuit_pp.nb_wires in + let perm_identities = + Perm.verifier_identities + ~circuit_name + ~wires_names + ~nb_proofs + ~generator + ~n + ~beta:rd.beta_perm + ~gamma:rd.gamma_perm + ~delta:rd.delta + () + in + let gates_identities = + List.mapi + (fun proof_idx public_inputs -> + Gates.aggregate_verifier_identities + ~circuit_name + ~input_com_sizes:circuit_pp.input_com_sizes + ~nb_proofs + ~proof_idx + ~gates:circuit_pp.gates + ~public_inputs + ~generator + ~size_domain:n + ()) + pi_list + in + let plookup_identities = + if not circuit_pp.ultra then [] + else + List.init nb_proofs (fun proof_idx -> + Plook.verifier_identities + ~circuit_name + ~nb_proofs + ~proof_idx + ~wires_names + ~generator + ~n + ~alpha:circuit_pp.alpha + ~beta:rd.beta_plook + ~gamma:rd.gamma_plook + ()) + in + let rc_identities = + if not circuit_pp.range_checks then [] + else + List.init nb_proofs (fun proof_idx -> + RangeCheck.verifier_identities + ~circuit_name + ~proof_idx + ~nb_proofs + ~beta:rd.beta_rc + ~gamma:rd.gamma_rc + ~domain_size:n + ~generator + ()) + in + merge_verifier_identities + (perm_identities + :: (plookup_identities @ gates_identities @ rc_identities))) + public_inputs_map + in + merge_verifier_identities (SMap.values identities_map) + + let format_input_com (inputs_map : verifier_inputs) = + SMap.mapi + (fun name (_, l) -> + let n = List.length l in + List.mapi + (fun i ic -> + let rename j s = + SMap.Aggregation.add_prefix ~n ~i name s ^ string_of_int j + in + List.mapi (fun j -> Commitment.rename (rename j)) ic) + l + |> List.concat) + inputs_map + |> SMap.values |> List.concat + + (* Assumes the same circuit, i.e. the public parameters are fixed *) + let verify_parameters ((common_pp, circuits_map), transcript) inputs_map + proof = + (* The transcript is the same as the provers's transcript since the proof + is already aggregated *) + let transcript = + Transcript.expand Commitment.t proof.wires_cm transcript + in + (* Get the same randomness for all proofs *) + (* Step 1a : compute beta & gamma *) + let rd, transcript = build_gates_randomness transcript in + (* Step 3 : compute verifier’s identities *) + let identities = + build_identities + circuits_map + (common_pp.n, common_pp.generator) + rd + (SMap.map fst inputs_map) + in + let input_commitments = format_input_com inputs_map in + let commitments = + [common_pp.cm_g; proof.perm_and_plook; proof.wires_cm] + @ input_commitments + in + let eval_points = + common_pp.eval_points @ List.map (Fun.const [X]) input_commitments + in + let transcript = + Transcript.expand Commitment.t proof.perm_and_plook transcript + in + (transcript, identities, rd, commitments, eval_points) + end + + type prover_public_parameters = Prover.public_parameters = { + common_pp : Prover.common_prover_pp; + circuits_map : Prover.circuit_prover_pp SMap.t; + transcript : PP.transcript; + } + [@@deriving repr] + + type verifier_public_parameters = { + common_pp : Verifier.common_verifier_pp; + circuits_map : Verifier.circuit_verifier_pp SMap.t; + transcript : PP.transcript; + } + [@@deriving repr] + + module Preprocess = struct + let eval_points (circuits_map : Prover.circuit_prover_pp SMap.t) = + let open Prover in + let used_ultra = SMap.exists (fun _ c -> c.ultra) circuits_map in + let used_gx_gate = + SMap.exists + (fun _ c -> Gates.exists_gx_composition ~gates:c.gates) + circuits_map + in + let g_points = if used_ultra then [X; GX] else [X] in + let f_points = if used_gx_gate then [X; GX] else [X] in + [g_points; [X; GX]; f_points] + + let degree_evaluations ~nb_wires ~gates ~ultra = + let min_deg = + (* minimum size needed for permutation gate ; if we are in the gate case, nb_wires = 0 => min_perm = 1 which is the minimum degree anyway *) + let min_perm = Perm.polynomials_degree ~nb_wires in + if ultra then max (Plook.polynomials_degree ()) min_perm else min_perm + in + max min_deg (Gates.aggregate_polynomials_degree ~gates) + + let domain_evaluations ~zero_knowledge ~n len_evals = + let zk_factor = if zero_knowledge then if n <= 2 then 4 else 2 else 1 in + let len_evals = zk_factor * len_evals * n in + Domain.build_power_of_two Z.(log2up (of_int len_evals)) + + (* Function preprocessing the circuit wires and selector polynomials; + Inputs: + - n: the number of constraints in the circuits + the number of public inputs + - domain: the interpolation domain for polynomials of size n + - s elector_polys: the selector polynomials, + e.g. [ql, qr, qo, qm, qc] for an arithmetic circuit. + We assume ql is the first polynomial in the list. + - wire_indices: the list corresponding to the wires indices, + e.g. [a, b, c] for an arithmetic circuit + - l, the number of public inputs + the number of elements committed in input_commitments + Outputs: + - interpolated_polys: selector polynomials, prepended with 0/1s for the public inputs, + interpolated on the domain + - extended_wires: circuits wires prepended with wires corresponding to the public inputs + *) + let preprocessing n domain (c : Circuit.t) = + let l = List.fold_left ( + ) c.public_input_size c.input_com_sizes in + (* Updating selectors for public inputs. *) + let gates = + (* Define ql if undefined as it is the gate taking the public input in. *) + if l > 0 && (not @@ SMap.mem "ql" c.gates) then + SMap.add + "ql" + (Array.init c.circuit_size (fun _ -> Scalar.zero)) + c.gates + else c.gates + in + (* other preprocessed things in article are computed in prove of permutations *) + let extended_gates = + (* Adding 0s/1s for public inputs & input_commitments *) + SMap.mapi + (fun label poly -> + let length_poly = Array.length poly in + Array.init n (fun i -> + if i < l && label = "ql" then Scalar.one + else if l <= i && i < l + length_poly then poly.(i - l) + else Scalar.zero)) + gates + in + let extended_gates, _, _ = + List.fold_left + (fun (acc, i, k) size -> + let acc = + SMap.add + ("qcom" ^ string_of_int i) + (Array.init n (fun j -> + if j >= k && j < k + size then Scalar.(negate one) + else Scalar.zero)) + acc + in + (acc, i + 1, k + size)) + (extended_gates, 0, 0) + c.input_com_sizes + in + let interpolated_gates = + SMap.map (Evaluations.interpolation_fft2 domain) extended_gates + in + let extended_gates = + if c.public_input_size = 0 then extended_gates + else SMap.add "qpub" [||] extended_gates + in + let extended_wires = + let li_array = Array.init l (fun i -> i) in + (* Adding public inputs and resizing *) + SMap.map (fun w -> Array.pad (Array.append li_array w) n) c.wires + in + let adapted_range_checks = + (List.map (Int.add l) (fst c.range_checks), snd c.range_checks) + in + let extended_tables = + if not c.ultra then [] + else + Plook.format_tables + ~tables:c.tables + ~nb_columns:c.nb_wires + ~length_not_padded:c.table_size + ~length_padded:n + in + ( interpolated_gates, + extended_gates, + extended_wires, + extended_tables, + adapted_range_checks ) + + let preprocess_map domain domain_evals n circuits_map = + (* Preprocessing wires, gates and tables *) + SMap.fold + (fun circuit_name (circuit, _) (prv, vrf, all_g_maps) -> + (* Generating alpha for Plookup *) + let alpha = + if Circuit.(circuit.ultra) then Some (Scalar.random ()) else None + in + let gates_poly, gates, wires, tables, range_checks = + preprocessing n domain circuit + in + (* Generating permutation *) + let permutation = Perm.build_permutation wires in + + let rc_permutation = + RangeCheck.build_permutation ~range_checks ~size_domain:n + in + let g_map_perm = + Perm.preprocessing + ~domain + ~nb_wires:circuit.nb_wires + ~permutation + () + in + let g_map_plook = + if circuit.ultra then Plook.preprocessing ~domain ~tables ~alpha () + else SMap.empty + in + let g_map_range_check = + RangeCheck.preprocessing + ~permutation:rc_permutation + ~range_checks:circuit.range_checks + ~domain + in + let circuit_g_map = + SMap.union_disjoint_list + [g_map_plook; g_map_perm; gates_poly; g_map_range_check] + |> SMap.Aggregation.prefix_map circuit_name + in + let evaluations = + Evaluations.compute_evaluations ~domain:domain_evals circuit_g_map + in + let prover_pp = + Prover. + { + circuit_size = circuit.circuit_size; + input_com_sizes = circuit.input_com_sizes; + public_input_size = circuit.public_input_size; + gates; + tables; + wires; + evaluations; + permutation; + rc_permutation; + alpha; + ultra = circuit.ultra; + range_checks; + } + in + let verifier_pp = + let gates = SMap.map (fun _ -> ()) gates in + Verifier. + { + gates; + nb_wires = circuit.nb_wires; + alpha; + ultra = circuit.ultra; + input_com_sizes = circuit.input_com_sizes; + range_checks = fst range_checks <> []; + } + in + ( SMap.add_unique circuit_name prover_pp prv, + SMap.add_unique circuit_name verifier_pp vrf, + SMap.union_disjoint all_g_maps circuit_g_map )) + circuits_map + SMap.(empty, empty, empty) + + let compute_sizes + Circuit. + { + public_input_size; + input_com_sizes; + circuit_size; + nb_wires; + table_size; + nb_lookups; + ultra; + gates; + _; + } nb_proofs = + (* Computing domain *) + (* For TurboPlonk, we want a domain of size a power of two + higher than or equal to the number of constraints plus public inputs. + As for UltraPlonk, a domain of size stricly higher than the number of constraints + (to be sure we pad the last lookup). *) + let nb_cs_pi = + circuit_size + + List.fold_left ( + ) public_input_size input_com_sizes + + if ultra then 1 else 0 + in + (* For UltraPlonk, we want a domain of size a power of two + higher than the number of records and strictly higher than the number of lookups *) + let nb_rec_look = if ultra then max (nb_lookups + 1) table_size else 0 in + let max_nb = max nb_cs_pi nb_rec_look in + let log = Z.(log2up (of_int max_nb)) in + let n = Int.shift_left 1 log in + let pack_size = + (* L1, Ssi, selectors, ultra stuff *) + let nb_g_map_polys = + let ultra_polys = if ultra then 2 else 0 in + 1 + nb_wires + SMap.cardinal gates + ultra_polys + in + let nb_extra_polys = if ultra then 5 else 1 in + let online = max nb_wires nb_extra_polys * nb_proofs in + (* 5 stands for the max number of T polynomials, if we split T *) + let offline = max nb_g_map_polys 5 in + (* Multiply by 2 to have more than needed, just in case *) + 2 * max online offline + in + (log, n, pack_size) + + let get_sizes ~zero_knowledge circuits_map = + let log, n, total_pack, some_ultra = + SMap.fold + (fun _ (c, nb_proofs) (acc_log, acc_n, acc_pack_size, acc_ultra) -> + let log, n, pack_size = compute_sizes c nb_proofs in + ( max acc_log log, + max acc_n n, + acc_pack_size + pack_size, + acc_ultra || c.ultra )) + circuits_map + (0, 0, 0, false) + in + let degree_evals = + SMap.fold + (fun _ ((c : Circuit.t), _) acc_deg_eval -> + let deg_eval = + degree_evaluations + ~nb_wires:c.nb_wires + ~gates:c.gates + ~ultra:c.ultra + in + max acc_deg_eval deg_eval) + circuits_map + 0 + in + let domain_evals = domain_evaluations ~zero_knowledge ~n degree_evals in + let domain = Domain.build_power_of_two log in + let total_pack = 1 lsl Z.(log2up (of_int total_pack)) in + (* Each t chunk should be of degree [n]. + We remove 1 because t is divided by (X^n - 1) *) + let nb_of_t_chunks = + degree_evals + (if zero_knowledge then 1 else 0) - 1 + in + (domain, n, total_pack, domain_evals, some_ultra, nb_of_t_chunks) + + let setup_circuits ~zero_knowledge circuits_map ~srs = + let domain, n, pack_size, domain_evals, some_ultra, nb_of_t_chunks = + get_sizes ~zero_knowledge circuits_map + in + let evaluations = + let nb_wires = + SMap.fold + (fun _ ((c : Circuit.t), _) m -> max m c.nb_wires) + circuits_map + 0 + in + (* Add X evaluations, which is the domain needed for other evaluations *) + let evaluations = + SMap.singleton "X" (Evaluations.of_domain domain_evals) + in + (* Add L₁, Sid₁, Sid₂, Sid₃, Sid₄, Sid₅ *) + let evaluations = + Perm.common_preprocessing ~nb_wires ~domain ~evaluations + in + + (* if ultra add L_n_plus_1 *) + if some_ultra then Plook.common_preprocessing ~n ~domain ~evaluations + else evaluations + in + let pp_prv, pp_vrf, g_map = + preprocess_map domain domain_evals n circuits_map + in + (* Generating public parameters *) + let pp_prover, pp_verifier = PP.setup ~setup_params:pack_size ~srs in + let cm_g, g_prover_aux = Commitment.commit pp_prover g_map in + (* Generating transcript *) + let transcript = + let tmp = PP.PC.Public_parameters.to_bytes n pp_prover in + Transcript.expand Commitment.t cm_g tmp + in + let eval_points = eval_points pp_prv in + let common_prv = + Prover. + { + n; + domain; + pp_public_parameters = pp_prover; + evaluations; + g_map; + g_prover_aux; + zk = zero_knowledge; + nb_of_t_chunks; + eval_points; + } + in + let common_vrf = + Verifier. + { + n; + generator = Domain.get domain 1; + pp_public_parameters = pp_verifier; + cm_g; + eval_points; + } + in + ( ({common_pp = common_prv; circuits_map = pp_prv; transcript} + : prover_public_parameters), + {common_pp = common_vrf; circuits_map = pp_vrf; transcript} ) + end + + let to_verifier_inputs (pp : prover_public_parameters) = + let extract name (secrets : circuit_prover_input list) : + public_inputs * Input_commitment.public list list = + let c = SMap.find name pp.circuits_map in + let ic_size = List.fold_left ( + ) 0 c.input_com_sizes in + let public_inputs = + List.map + (fun s -> Array.sub s.witness ic_size c.public_input_size) + secrets + in + let input_commitments = + List.map + (fun s -> + List.map + (fun (c : Input_commitment.t) -> c.public) + s.input_commitments) + secrets + in + (public_inputs, input_commitments) + in + SMap.mapi extract + + let expand_transcript_with_verifier_inputs transcript verifier_inputs = + Transcript.expand + Repr.bytes + (hash_verifier_inputs verifier_inputs) + transcript + + let input_commit ?size ?shift (pp : prover_public_parameters) secret = + Input_commitment.commit + ?size + ?shift + pp.common_pp.pp_public_parameters + pp.common_pp.n + secret + + let update_prover_public_parameters x (pp : prover_public_parameters) = + {pp with transcript = Transcript.expand Repr.bytes x pp.transcript} + + let update_verifier_public_parameters x (pp : verifier_public_parameters) = + {pp with transcript = Transcript.expand Repr.bytes x pp.transcript} + + (* [filter_pp_circuits pp inputs_map] returns [pp] + without the circuits that don’t appear in [inputs_map]’s keys + *) + let filter_prv_pp_circuits (pp : prover_public_parameters) inputs_map = + check_circuits pp.circuits_map inputs_map ; + {pp with circuits_map = SMap.sub_map inputs_map pp.circuits_map} + + let filter_vrf_pp_circuits pp inputs_map = + check_circuits pp.circuits_map inputs_map ; + {pp with circuits_map = SMap.sub_map inputs_map pp.circuits_map} + + let setup ~zero_knowledge circuits_map ~srs = + check_circuit_name circuits_map ; + Preprocess.setup_circuits ~zero_knowledge circuits_map ~srs + + (* inputs is a map between circuit names to list of public inputs *) + let prove (pp : prover_public_parameters) ~inputs = + check_circuit_name pp.circuits_map ; + (* add the verifier inputs to the transcript *) + let pp = + { + pp with + transcript = + expand_transcript_with_verifier_inputs + pp.transcript + (to_verifier_inputs pp inputs); + } + in + let pp_proof, (perm_and_plook, wires_cm, _) = + Prover.prove_parameters + ~pp_prove:PP.prove + (filter_prv_pp_circuits pp inputs) + ~inputs_map:inputs + in + {perm_and_plook; wires_cm; pp_proof} + + let verify pp ~inputs proof = + check_circuit_name pp.circuits_map ; + let circuits_map = SMap.sub_map inputs pp.circuits_map in + (* add the verifier inputs to the transcript *) + let transcript = + expand_transcript_with_verifier_inputs pp.transcript inputs + in + let transcript, identities, _, commitments, eval_points = + Verifier.verify_parameters + ((pp.common_pp, circuits_map), transcript) + inputs + proof + in + PP.verify + pp.common_pp.pp_public_parameters + transcript + ~n:pp.common_pp.n + ~generator:pp.common_pp.generator + ~commitments + ~identities + ~eval_points + proof.pp_proof + |> fst + + let scalar_encoding = + Data_encoding.( + conv + Scalar.to_bytes + Scalar.of_bytes_exn + (Fixed.bytes Scalar.size_in_bytes)) + + let data_encoding_of_repr repr = + Data_encoding.conv + (Plompiler.Utils.to_bytes repr) + (Plompiler.Utils.of_bytes repr) + Data_encoding.bytes + + let proof_encoding = data_encoding_of_repr proof_t + + let verifier_public_parameters_encoding = + data_encoding_of_repr verifier_public_parameters_t + + module Internal_for_tests = struct + let mutate_vi verifier_inputs = + (* TODO we could do a more randomized search *) + let key, (public_inputs_list, input_commitments_list) = + SMap.choose verifier_inputs + in + match public_inputs_list with + | head :: tail -> + if head = [||] then None (* empty public inputs *) + else + let new_head = Array.copy head in + new_head.(0) <- Scalar.(add one new_head.(0)) ; + let public_inputs_list = new_head :: tail in + let inputs = (public_inputs_list, input_commitments_list) in + Some (SMap.add key inputs verifier_inputs) + | [] -> failwith "mutate_vi : all circuits should have verifier inputs." + end +end + +module Make : functor (PP : Polynomial_protocol.S) -> + S with type public_inputs = Scalar.t array list = + Make_impl + +include Make (Polynomial_protocol) diff --git a/src/lib_plonk/main_protocol_intf.ml b/src/lib_plonk/main_protocol_intf.ml new file mode 100644 index 000000000000..12da090fc4c8 --- /dev/null +++ b/src/lib_plonk/main_protocol_intf.ml @@ -0,0 +1,169 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) +open Bls + +module type S = sig + (** Raised by the prover when the provided inputs are not a satisfying + assignment of the circuit. *) + exception Rest_not_null of string + + (** Raised by the prover when the provided inputs are not a satisfying + assignment of the circuit when using Plookup. *) + exception Entry_not_in_table of string + + module Input_commitment : Input_commitment.S + + type scalar = Scalar.t [@@deriving repr] + + (** *) + val scalar_encoding : scalar Data_encoding.t + + (** Before proving and verifying, circuits go through a pre-processing + step called [setup]. + The [setup] takes as input a [circuit_map], which associates + an identifier to a circuit and the number of statements that can be + proved with that circuit. + This produces a set of [public_parameters] which are bound to the + circuits and can be reused. + *) + type circuit_map = (Circuit.t * int) SMap.t + + (** Set of [public_parameters] needed by the prover. + Its size is linear in the size of the circuits. + *) + type prover_public_parameters [@@deriving repr] + + (** Set of [public_parameters] needed by the verifier. + Its size is constant w.r.t. the size of the circuits. + *) + type verifier_public_parameters [@@deriving repr] + + val verifier_public_parameters_encoding : + verifier_public_parameters Data_encoding.t + + (** Succinct proof for a collection of statements. *) + type proof [@@deriving repr] + + val proof_encoding : proof Data_encoding.t + + (** Witness is the whole trace for the circuit, including + input_commitment values first, followed by public input + values and followed by the rest of the trace. + This is the prover input for a single proof. *) + type circuit_prover_input = { + witness : scalar array; + input_commitments : Input_commitment.t list; + } + [@@deriving repr] + + (** Map where each circuit identifier is bound to + a list of [circuit_prover_input] for a list of statements. *) + type prover_inputs = circuit_prover_input list SMap.t [@@deriving repr] + + (** The public inputs for one circuit & several statements *) + type public_inputs [@@deriving repr] + + (** The verifier inputs, represented as a map where each circuit is binded to + the verifier inputs for this circuit. *) + type verifier_inputs = + (public_inputs * Input_commitment.public list list) SMap.t + [@@deriving repr] + + (** Conversion from [prover_inputs] to [verifier_inputs]. *) + val to_verifier_inputs : + prover_public_parameters -> prover_inputs -> verifier_inputs + + (** [input_commit ~shift pp secret] produces a commitment to the [secret] + array and additional prover information. This commitment is designed to be + easily involved in a PlonK proof. In particular, the values of [secret] + will be added to the arithmetic identity in such a way that [secret.(i)] + participates in constraint number [shift + i], where equality will be + asserted with respect to a PlonK variable in the same constraint. + This allows us to "load" the value of [secret.(i)] into the variable, which + may be reused across the circuit. + The optional argument [shift] has a default value of 0. + The commitment is relative to a certain domain size [n], included in [pp], + the secret will remain information-theoretically hidden as long as the + commitment is involved in at most [n - |secret|] different proofs. + If the optionnal argument [size] is given, the secret will be padded with + zeros to have the length [size] (note that an error will be risen if size + is smaller than the secret length). + *) + val input_commit : + ?size:int -> + ?shift:int -> + prover_public_parameters -> + scalar array -> + Input_commitment.t + + (** [setup ~zero_knowledge circuit_map ~srs] pre-processes the [circuit_map] + producing the public parameters. + The SRSs of ZCash and Filecoin can be loaded from file using the + {!Bls12_381_polynomial} library. + Activating [zero_knowledge] adds an overhead in proving time. + *) + val setup : + zero_knowledge:bool -> + circuit_map -> + srs:Bls12_381_polynomial.Srs.t * Bls12_381_polynomial.Srs.t -> + prover_public_parameters * verifier_public_parameters + + (** Enrich the [prover_public_parameters] with extra application data to + prevent replay attacks. + The same data must be used for updating the prover and verifier + public parameters. + *) + val update_prover_public_parameters : + Bytes.t -> prover_public_parameters -> prover_public_parameters + + (** Enrich the [verifier_public_parameters] with extra application data to + prevent replay attacks. + The same data must be used for updating the prover and verifier + public parameters. + *) + val update_verifier_public_parameters : + Bytes.t -> verifier_public_parameters -> verifier_public_parameters + + (** [prove public_parameters ~inputs] produces a proof for the collection + of statements implied by [inputs] and the circuits used for generating + [public_parameters]. + + @raises Rest_not_null + @raises Entry_not_in_table + *) + val prove : prover_public_parameters -> inputs:prover_inputs -> proof + + (** [verify public_parameters ~inputs proof] checks the validity of the + [proof] with regards to [public_parameters] and [inputs]. + *) + val verify : + verifier_public_parameters -> inputs:verifier_inputs -> proof -> bool + + module Internal_for_tests : sig + (** [mutate_vi vi] returns None if vi is empty and Some vi' else. + vi' is slightly different from vi *) + val mutate_vi : verifier_inputs -> verifier_inputs option + end +end diff --git a/src/lib_plonk/permutation_gate.ml b/src/lib_plonk/permutation_gate.ml new file mode 100644 index 000000000000..d23ac198cab4 --- /dev/null +++ b/src/lib_plonk/permutation_gate.ml @@ -0,0 +1,614 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Bls +open Utils +open Identities +module L = Plompiler.LibCircuit + +module Permutation_gate_impl (PP : Polynomial_protocol.S) = struct + module PP = PP + module Commitment = PP.PC.Commitment + + let z_name = "Z" + + let zg_name z_name = z_name ^ "g" + + let l1 = "L1" + + let ids_label = "Perm" + + (* element preprocessed and known by both prover and verifier *) + type public_parameters = { + g_map_perm_PP : Poly.t SMap.t; + cm_g_map_perm_PP : Commitment.t SMap.t; + s_poly_map : Poly.t SMap.t; + cm_s_poly_map : Commitment.t SMap.t; + permutation : int array; + } + + let srs_size ~zero_knowledge ~n = if zero_knowledge then n + 9 else n + + let one = Scalar.one + + let zero = Scalar.zero + + let mone = Scalar.negate one + + let quadratic_non_residues = Fr_generation.build_quadratic_non_residues 8 + + let get_k k = + if k < 8 then quadratic_non_residues.(k) + else raise (Invalid_argument "Permutation.get_k : k must be lower than 8.") + + module Partition = struct + module IntSet = Set.Make (Int) + module IntMap = Map.Make (Int) + + type t = IntSet.t IntMap.t + + (* receives [wire_indices], a map from wire names (e.g. "a", "b", "c") to + [int list], flattens its data into a concatenated list of indices [idxs] + and outputs a map keyed by indices, pointing to the set of (integer) + positions where the index appears in [idxs] *) + let build_partition wire_indices = + (* [add_IntMap i e map] adds [e] to the set bound to [i] in [map], + if [i] is not bound, it binds [i] to the singleton set {e} *) + let add_IntMap i e map = + let set = Option.value (IntMap.find_opt i map) ~default:IntSet.empty in + IntMap.add i (IntSet.add e set) map + in + let idxs = SMap.values wire_indices in + let map, _i = + List.fold_left + (fun (int_map, i) wire_indices_i -> + let new_map, j = + Array.fold_left + (fun (map, j) h -> + let new_map = add_IntMap h (i + j) map in + (new_map, j + 1)) + (int_map, 0) + wire_indices_i + in + (new_map, i + j)) + (IntMap.empty, 0) + idxs + in + map + + (* returns a permutation in the form of [int array] which splits in cycles + that involve the indices of each group in the given [partition], e.g. + on input partition := { 0 -> { 0; 3; 4 } ; 1 -> { 1; 2 } } + outputs permutation [| 3 2 1 4 0 |] *) + let partition_to_permutation partition = + let kn = + IntMap.fold (fun _ set sum -> sum + IntSet.cardinal set) partition 0 + in + (* array initialisation *) + let permutation = Array.make kn (-1) in + let set_cycle_in_permutation _idx cycle = + match IntSet.cardinal cycle with + | 0 -> failwith "cycles_to_permutation_map_set : empty cycle" + | 1 -> + (* σ(e) = e *) + let e = IntSet.choose cycle in + permutation.(e) <- e + | n -> + let first = IntSet.min_elt cycle in + let aux e (i, prec) = + if i = 0 then (i + 1, e) + else if i < n - 1 then ( + permutation.(prec) <- e ; + (i + 1, e)) + else ( + permutation.(prec) <- e ; + permutation.(e) <- first ; + (i + 1, e)) + in + ignore @@ IntSet.fold aux cycle (0, -1) + in + IntMap.iter set_cycle_in_permutation partition ; + (* If cycles is a legit partition of [kn], no -1 should be left *) + if Array.mem (-1) permutation then + failwith "cycles is not a 'partition' of kn" + else permutation + end + + module Preprocessing = struct + (* Returns the minimal (monic) polynomial L1 that satisfies + L1(generator) = 1 and L1(h) = 0 for all h != generator in domain, + where generator is the first non-trivial element in domain. *) + let compute_l1 domain = + let size_domain = Domain.length domain in + let scalar_list = + Array.append + [|zero; one|] + Array.(init (size_domain - 2) (fun _ -> zero)) + in + Evaluations.interpolation_fft2 domain scalar_list + + (* returns [sid_0, …, sid_k] *) + let sid_list_non_quadratic_residues size = + if size > 8 then + raise (Failure "sid_list_non_quadratic_residues: sid list too long") + else List.init size (fun i -> Poly.of_coefficients [(get_k i, 1)]) + + let sid_map_non_quadratic_residues_prover size = + if size > 8 then + raise (Failure "sid_map_non_quadratic_residues: sid map too long") + else + SMap.of_list + (List.init size (fun i -> + let k = get_k i in + ("Si" ^ string_of_int (i + 1), Poly.of_coefficients [(k, 1)]))) + + let evaluations_sid nb_sid evaluations = + let domain_evals = Evaluations.find_evaluation evaluations "X" in + SMap.of_list + (List.init nb_sid (fun i -> + let k = get_k i in + ( "Si" ^ string_of_int (i + 1), + Evaluations.mul_by_scalar k domain_evals ))) + + let ssigma_map_non_quadratic_residues permutation domain size = + let n = Domain.length domain in + let ssigma_map = + SMap.of_list + (List.init size (fun i -> + let offset = i * n in + let coeff_list = + Array.init n (fun j -> + let s_ij = permutation.(offset + j) in + let coeff = get_k (s_ij / n) in + let index = s_ij mod n in + Scalar.mul coeff (Domain.get domain index)) + in + ( "Ss" ^ string_of_int (i + 1), + Evaluations.interpolation_fft2 domain coeff_list ))) + in + ssigma_map + end + + module Permutation_poly = struct + (* compute f' & g' = (f + β×Sid + γ) & (g + β×Sσ + γ) products with Z *) + (* compute_prime computes the following + z_name * (w_1 + beta * s_1 + gamma) * ... * (w_n + beta * s_n + gamma) + - z_name could be either "Z" or "Zg" + - evaluations contains "Z" but not "Zg" + - if z_name = "Zg", we compute "Zg" as composition_gx of "Z" with 1 *) + let compute_prime ~prefix res_evaluation tmp_evaluation tmp2_evaluation beta + gamma evaluations wires_names s_names (z_name, this_z_name) n = + let zg_name = zg_name z_name in + let z_evaluation = + Evaluations.find_evaluation evaluations (prefix z_name) + in + + let _i, res_evaluation = + let f_fold (i, acc_evaluation) wire_name s_name = + let comp = if i = 0 && this_z_name = zg_name then 1 else 0 in + let res_evaluation = + (* tmp_evaluation <- wire_name + beta * s_name + gamma *) + let evaluation_linear_i = + Evaluations.linear + ~res:tmp_evaluation + ~evaluations + ~poly_names:[wire_name; s_name] + ~linear_coeffs:[one; beta] + ~add_constant:gamma + () + in + (* tmp2_evaluation <- acc_evaluation * evaluation_linear_i *) + let acc_evaluation_new = + Evaluations.mul_c + ~res:tmp2_evaluation + ~evaluations:[evaluation_linear_i; acc_evaluation] + ~composition_gx:([0; comp], n) + () + in + Evaluations.copy ~res:res_evaluation acc_evaluation_new + in + (i + 1, res_evaluation) + in + List.fold_left2 f_fold (0, z_evaluation) wires_names s_names + in + res_evaluation + + (* evaluations must contain z’s evaluation *) + let prover_identities ~additionnal_prefix:a_pref ~prefix wires_names beta + gamma n evaluations = + let z_name = a_pref z_name in + let raw_z_name = z_name in + let zg_name = zg_name z_name in + let z_evaluation = + Evaluations.find_evaluation evaluations (prefix z_name) + in + let z_evaluation_len = Evaluations.length z_evaluation in + let tmp_evaluation = Evaluations.create z_evaluation_len in + let tmp2_evaluation = Evaluations.create z_evaluation_len in + let id1_evaluation = Evaluations.create z_evaluation_len in + let id2_evaluation = Evaluations.create z_evaluation_len in + + let wires_names = List.map prefix wires_names in + + let identity_zfg = + let nb_wires = List.length wires_names in + + (* changes f (resp g) array to f'(resp g') array, and multiply them together + and with z (resp zg) *) + let f_evaluation = + let sid_names = + List.init nb_wires (fun i -> "Si" ^ string_of_int (i + 1)) + in + compute_prime + ~prefix + tmp_evaluation + id2_evaluation + tmp2_evaluation + beta + gamma + evaluations + wires_names + sid_names + (raw_z_name, z_name) + n + in + let g_evaluation = + let ss_names = + List.init nb_wires (fun i -> + prefix @@ a_pref "Ss" ^ string_of_int (i + 1)) + in + compute_prime + ~prefix + id2_evaluation + id1_evaluation + tmp2_evaluation + beta + gamma + evaluations + wires_names + ss_names + (raw_z_name, zg_name) + n + in + Evaluations.linear_c + ~res:id1_evaluation + ~evaluations:[f_evaluation; g_evaluation] + ~linear_coeffs:[one; mone] + () + in + let identity_l1_z = + let l1_evaluation = Evaluations.find_evaluation evaluations l1 in + let z_mone_evaluation = + Evaluations.linear_c + ~res:tmp_evaluation + ~evaluations:[z_evaluation] + ~add_constant:mone + () + in + + Evaluations.mul_c + ~res:id2_evaluation + ~evaluations:[l1_evaluation; z_mone_evaluation] + () + in + SMap.of_list + [ + (prefix (a_pref "Perm.a"), identity_l1_z); + (prefix (a_pref "Perm.b"), identity_zfg); + ] + + (* compute_Z performs the following steps in the two loops. + ---------------------- + | f_11 f_21 ... f_k1 | -> f_prod_1 (no need to compute as Z(g) is always one) + | f_12 f_22 ... f_k2 | -> f_prod_2 = f_12 * f_22 * ... * f_k2 + | ........... | -> ... + | f_1n f_2n ... f_kn | -> f_prod_n = f_1n * f_2n * ... * f_kn + -------------------- + 1. compute f_res = [ f_prod_1; f_prod_2; ...; f_prod_n ] + 2. compute g_res = [ g_prod_1; g_prod_2; ...; g_prod_n ] + 3. compute f_over_g = [ f_prod_1 / g_prod_1; ...; f_prod_n / g_prod_n ] + 4. apply fold_mul_array to f_over_g: + [f_over_g_1; f_over_g_1 * f_over_g_2; ..; f_over_g_1 * f_over_g_2 * .. * f_over_n ] + 5. as step 4 computes [Z(g); Z(g^2); ..; Z(g^n)], we need to do a rotate right by 1 + (i.e., composition_gx with n - 1): [Z(g^n); Z(g); Z(g^2); ..; Z(g^{n-1})] *) + let compute_Z s domain beta gamma values = + let size_domain = Domain.length domain in + let scalar_array_Z = + let values_array = Array.of_list (SMap.values values) in + let size_res = Evaluations.length values_array.(0) in + assert (size_res = size_domain) ; + let g_res = Array.init size_res (fun _ -> Scalar.zero) in + let f_prev = ref Scalar.one in + let f_res = ref Scalar.one in + let tmp = Scalar.(copy one) in + (* the first element of scalar_array_Z is always one *) + for i = 1 to size_res - 1 do + for j = 0 to Array.length values_array - 1 do + let value_j_i = Evaluations.get values_array.(j) i in + let v_gamma = Scalar.add gamma value_j_i in + let f_coeff = + let gi = Domain.get domain i in + Scalar.( + mul_inplace tmp gi (get_k j) ; + mul_inplace gi tmp beta ; + add_inplace gi gi v_gamma ; + gi) + in + let g_coeff = + let sj = s.((j * size_domain) + i) in + let gj = Domain.get domain (sj mod size_domain) in + Scalar.( + mul_inplace tmp gj (get_k (Int.div sj size_domain)) ; + mul_inplace gj tmp beta ; + add_inplace gj gj v_gamma ; + gj) + in + if j = 0 then ( + f_res := f_coeff ; + g_res.(i) <- g_coeff) + else + Scalar.( + mul_inplace !f_res !f_res f_coeff ; + mul_inplace g_res.(i) g_res.(i) g_coeff) + done ; + let f_over_g = Scalar.div_exn !f_res g_res.(i) in + Scalar.( + mul_inplace f_over_g f_over_g !f_prev ; + g_res.(i) <- !f_prev ; + f_prev := f_over_g) + done ; + + g_res.(0) <- !f_prev ; + g_res + in + Evaluations.interpolation_fft2 domain scalar_array_Z + end + + (* max degree needed is the degree of Perm.b, which is sum of wire’s degree plus z degree *) + let polynomials_degree ~nb_wires = nb_wires + 1 + + let build_permutation wires = + let partition = Partition.build_partition wires in + Partition.partition_to_permutation partition + + (* d = polynomials’ max degree + n = generator’s order + Returns SRS of decent size, preprocessed polynomials for permutation and + their commitments (g_map_perm, cm_g_map_perm (="L1" -> L₁, preprocessed + polynomial for verify perm’s identity), s_poly_map, cm_s_poly_map) & those + for PP (g_map_PP, cm_g_map_PP) + permutation for ssigma_list computation is deducted of cycles + Details for SRS size : + max size needed is deg(T)+1 + v polynomials all have degree 1 + according to identities_list_perm[0], t has max degree of Z×fL×fR×fO ; + interpolation makes polynomials of degree n-1, so Z has degree of X²×Zh = + X²×(X^n - 1) which is n+2, and each f has degree of X×Zh so n+1 + As a consequence, deg(T)-deg(Zs) = (n+2)+3(n+1) - n = 3n+5 + (for gates’ identity verification, max degree is degree of qM×fL×fR which + is (n-1)+(n+1)+(n+1) < 3n+5) *) + let preprocessing ~domain ~permutation ~nb_wires () = + Preprocessing.ssigma_map_non_quadratic_residues permutation domain nb_wires + + let common_preprocessing ~nb_wires ~domain ~evaluations = + let sid_evals = Preprocessing.evaluations_sid nb_wires evaluations in + let evaluations = SMap.union_disjoint evaluations sid_evals in + let l1_map = SMap.singleton l1 @@ Preprocessing.compute_l1 domain in + Evaluations.compute_evaluations_update_map ~evaluations l1_map + + let prover_identities ?(prefix = "") ?(circuit_name = "") ~wires_names ~beta + ~gamma ~n () = + let additionnal_prefix s = + if s = z_name && prefix <> "" then prefix ^ "Perm_" ^ s else prefix ^ s + in + let prefix = SMap.Aggregation.add_prefix circuit_name in + fun evaluations -> + Permutation_poly.prover_identities + ~additionnal_prefix + ~prefix + wires_names + beta + gamma + n + evaluations + + let verifier_identities ?(prefix = "") ?(circuit_name = "") ~nb_proofs + ~generator ~n ~wires_names ~beta ~gamma ~delta () = + let a_pref s = + if s = z_name && prefix <> "" then prefix ^ "Perm_" ^ s else prefix ^ s + in + let prefix = SMap.Aggregation.add_prefix circuit_name in + let prefix_j j = + SMap.Aggregation.add_prefix ~n:nb_proofs ~i:j circuit_name + in + let z_name = a_pref z_name in + let ss_names = + List.init (List.length wires_names) (fun i -> + a_pref "Ss" ^ string_of_int (i + 1)) + in + fun x answers -> + let get_ss i = get_answer answers X (prefix @@ List.nth ss_names i) in + (* compute the delta-aggregated wire evaluations at x for each wire name *) + let batched = + let wire_j w j = get_answer answers X @@ prefix_j j w in + List.map + (fun w -> Fr_generation.batch delta (List.init nb_proofs (wire_j w))) + wires_names + in + let z = get_answer answers X (prefix z_name) in + let zg = get_answer answers GX (prefix z_name) in + (* compute the first identity: (Z(x) - 1) * L1(x) *) + let res1 = + Scalar.( + sub z one * Fr_generation.evaluate_l1 ~domain_size:n ~generator x) + in + (* compute the second identity *) + let res2 = + let z_factors = + List.mapi Scalar.(fun i w -> w + (beta * get_k i * x) + gamma) batched + in + let zg_factors = + List.mapi Scalar.(fun i w -> w + (beta * get_ss i) + gamma) batched + in + let multiply l = List.fold_left Scalar.mul (List.hd l) (List.tl l) in + Scalar.sub + (multiply @@ (z :: z_factors)) + (multiply @@ (zg :: zg_factors)) + in + SMap.of_list + [(prefix (a_pref "Perm.a"), res1); (prefix (a_pref "Perm.b"), res2)] + + let f_map_contribution ~permutation ~values ~beta ~gamma ~domain = + SMap.singleton + z_name + (Permutation_poly.compute_Z permutation domain beta gamma values) + + let cs ~sum_alpha_i ~l1 ~ss1 ~ss2 ~ss3 ~ss4 ~ss5 ~beta ~gamma ~delta ~x ~z ~zg + ~wires = + let open L in + let a_list, b_list, c_list, d_list, e_list = + let rec aux (acc_a, acc_b, acc_c, acc_d, acc_e) = function + | [] -> List.(rev acc_a, rev acc_b, rev acc_c, rev acc_d, rev acc_e) + | [a; b; c; d; e] :: tl -> + aux (a :: acc_a, b :: acc_b, c :: acc_c, d :: acc_d, e :: acc_e) tl + | _ -> failwith "Unexpected wires format" + in + aux ([], [], [], [], []) wires + in + let* cs_perm_a = Num.custom ~qr:Scalar.(negate one) ~qm:Scalar.(one) z l1 in + + let* a = sum_alpha_i a_list delta in + let* b = sum_alpha_i b_list delta in + let* c = sum_alpha_i c_list delta in + let* d = sum_alpha_i d_list delta in + let* e = sum_alpha_i e_list delta in + let* betaid1 = Num.mul ~qm:(get_k 0) beta x in + let* betaid2 = Num.mul ~qm:(get_k 1) beta x in + let* betaid3 = Num.mul ~qm:(get_k 2) beta x in + let* betaid4 = Num.mul ~qm:(get_k 3) beta x in + let* betaid5 = Num.mul ~qm:(get_k 4) beta x in + let* betasigma1 = Num.mul beta ss1 in + let* betasigma2 = Num.mul beta ss2 in + let* betasigma3 = Num.mul beta ss3 in + let* betasigma4 = Num.mul beta ss4 in + let* betasigma5 = Num.mul beta ss5 in + + let* aid = Num.add_list (to_list [a; betaid1; gamma]) in + let* bid = Num.add_list (to_list [b; betaid2; gamma]) in + let* cid = Num.add_list (to_list [c; betaid3; gamma]) in + let* did = Num.add_list (to_list [d; betaid4; gamma]) in + let* eid = Num.add_list (to_list [e; betaid5; gamma]) in + let* asigma = Num.add_list (to_list [a; betasigma1; gamma]) in + let* bsigma = Num.add_list (to_list [b; betasigma2; gamma]) in + let* csigma = Num.add_list (to_list [c; betasigma3; gamma]) in + let* dsigma = Num.add_list (to_list [d; betasigma4; gamma]) in + let* esigma = Num.add_list (to_list [e; betasigma5; gamma]) in + + let* left_term = Num.mul_list (to_list [aid; bid; cid; did; eid; z]) in + + let* right_term = + Num.mul_list (to_list [asigma; bsigma; csigma; dsigma; esigma; zg]) + in + let* cs_perm_b = Num.add ~qr:Scalar.(negate one) left_term right_term in + ret (cs_perm_a, cs_perm_b) +end + +module type S = sig + module PP : Polynomial_protocol.S + + val srs_size : zero_knowledge:bool -> n:int -> int + + val polynomials_degree : nb_wires:int -> int + + val build_permutation : int array SMap.t -> int array + + val preprocessing : + domain:Domain.t -> + permutation:int array -> + nb_wires:int -> + unit -> + Poly.t SMap.t + + val common_preprocessing : + nb_wires:int -> + domain:Domain.t -> + evaluations:Evaluations.t SMap.t -> + Evaluations.t SMap.t + + (* prefix is an additionnal prefix for Ss, Z and identities names ; it is + used by Range check gate *) + val prover_identities : + ?prefix:string -> + ?circuit_name:string -> + wires_names:string list -> + beta:Scalar.t -> + gamma:Scalar.t -> + n:int -> + unit -> + prover_identities + + (* prefix is an additionnal prefix for Ss, Z and identities names ; it is + used by Range check gate *) + val verifier_identities : + ?prefix:string -> + ?circuit_name:string -> + nb_proofs:int -> + generator:Scalar.t -> + n:int -> + wires_names:string list -> + beta:Scalar.t -> + gamma:Scalar.t -> + delta:Scalar.t -> + unit -> + verifier_identities + + val f_map_contribution : + permutation:int array -> + values:Evaluations.t SMap.t -> + beta:Poly.scalar -> + gamma:Poly.scalar -> + domain:Domain.t -> + Poly.t SMap.t + + val cs : + sum_alpha_i:(L.scalar L.repr list -> L.scalar L.repr -> L.scalar L.repr L.t) -> + l1:L.scalar L.repr -> + ss1:L.scalar L.repr -> + ss2:L.scalar L.repr -> + ss3:L.scalar L.repr -> + ss4:L.scalar L.repr -> + ss5:L.scalar L.repr -> + beta:L.scalar L.repr -> + gamma:L.scalar L.repr -> + delta:L.scalar L.repr -> + x:L.scalar L.repr -> + z:L.scalar L.repr -> + zg:L.scalar L.repr -> + wires:L.scalar L.repr list list -> + (L.scalar L.repr * L.scalar L.repr) L.t +end + +module Permutation_gate (PP : Polynomial_protocol.S) : S with module PP = PP = + Permutation_gate_impl (PP) diff --git a/src/lib_plonk/plookup_gate.ml b/src/lib_plonk/plookup_gate.ml new file mode 100644 index 000000000000..50c148e716ab --- /dev/null +++ b/src/lib_plonk/plookup_gate.ml @@ -0,0 +1,641 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Bls +open Utils +open Identities + +module Plookup_gate_impl (PP : Polynomial_protocol.S) = struct + module PP = PP + + exception Entry_not_in_table of string + + let q_label = "q_plookup" + + let q_table = "q_table" + + let f = "f_plookup" + + let fg = "fg_plookup" + + let z = "z_plookup" + + let t = "table" + + let h1 = "h1" + + let h2 = "h2" + + let zg = "zg_plookup" + + let tg = "tg_plookup" + + let h1g = "h1g" + + let h2g = "h2g" + + let l1 = "L1" + + let ln_p_1 = "L_n_plus_1" + + let x_m_1 = "x_minus_1" + + let x = "X" + + type public_parameters = + (PP.prover_public_parameters * PP.verifier_public_parameters) + * Scalar.t array list + * Poly.t SMap.t + + let zero = Scalar.zero + + let one = Scalar.one + + let mone = Scalar.negate one + + (* alpha is a randomness used for Plookup *) + let get_alpha = function + | Some alpha -> alpha + | None -> failwith "Plookup alpha is undefined" + + let gate_identity ~prefix_common ~prefix ~n ~generator ~wires_names ~alpha + ~beta ~gamma : verifier_identities = + fun x answers -> + let q_label_name = prefix_common q_label in + let q_table_name = prefix_common q_table in + let t_name = prefix_common t in + let z_name = prefix z in + let f_name = prefix f in + let h1_name = prefix h1 in + let h2_name = prefix h2 in + let wires_names = List.map (fun x -> prefix x) wires_names in + let ( @- ) a b = Scalar.sub a b in + let one_p_b = Scalar.(one + beta) in + let g_one_p_b = Scalar.(gamma * one_p_b) in + let g_one_p_b_2 = Scalar.square g_one_p_b in + + let q = get_answer answers X q_label_name in + let z = get_answer answers X z_name in + let f = get_answer answers X f_name in + let t_val = get_answer answers X t_name in + let h1 = get_answer answers X h1_name in + let h2 = get_answer answers X h2_name in + let zg = get_answer answers GX z_name in + let fg = get_answer answers GX f_name in + let tg = get_answer answers GX t_name in + let h1g = get_answer answers GX h1_name in + let h2g = get_answer answers GX h2_name in + + let l1 = Fr_generation.evaluate_l1 ~domain_size:n ~generator x in + let ln_p_1 = Fr_generation.evaluate_l0 ~domain_size:n x in + + let z_m_1 = Scalar.(z @- one) in + let x_m_1 = Scalar.(x @- one) in + (* Identity: L1(x)·[Z(x) - 1] = 0 *) + let id_a = Scalar.(l1 * z_m_1) in + (* Identity: Ln+1(x)·[h1(x) - h2(gx)] = 0 *) + let id_c = Scalar.(ln_p_1 * sub h1 h2g) in + (* Identity: Ln+1(x)·[Z(x) - 1] = 0 *) + let id_d = Scalar.(ln_p_1 * z_m_1) in + (* Identity: + (x - g^{n+1})·Z(x)·(1 + β)·[γ + f(x)]·[γ(1 + β) + t(x) + β·t(gx)] + = (x - g^{n+1})·Z(g·x)·[γ(1 + β) + h1(x) + β·h1(gx)]·[γ(1 + β) + h2(x) + β·h2(gx)] + *) + (* Note that g^{n+1} equals 1 *) + (* Developping the left part of the equality *) + let l_g_a = Scalar.(g_one_p_b_2 * x_m_1 * z) in + let l_g_b = Scalar.(g_one_p_b * x_m_1 * t_val * z) in + let l_g_c = Scalar.(beta * g_one_p_b * x_m_1 * z * tg) in + let l_f_a = Scalar.(g_one_p_b * one_p_b * x_m_1 * z * f) in + let l_f_b = Scalar.(one_p_b * x_m_1 * t_val * z * f) in + let l_f_c = Scalar.(beta * one_p_b * x_m_1 * z * f * tg) in + (* Developping the right part of the equality *) + let ra_a_a = Scalar.(g_one_p_b_2 * x_m_1 * zg) in + let ra_a_b = Scalar.(g_one_p_b * x_m_1 * h2 * zg) in + let ra_a_c = Scalar.(g_one_p_b * beta * x_m_1 * zg * h2g) in + let ra_b_a = Scalar.(g_one_p_b * x_m_1 * h1 * zg) in + let ra_b_b = Scalar.(x_m_1 * h1 * h2 * zg) in + let ra_b_c = Scalar.(beta * x_m_1 * h1 * zg * h2g) in + let ra_c_a = Scalar.(g_one_p_b * beta * x_m_1 * h1g * zg) in + let ra_c_b = Scalar.(beta * x_m_1 * h1g * h2 * zg) in + let ra_c_c = Scalar.(square beta * x_m_1 * h1g * zg * h2g) in + let id_b = + Scalar.( + (l_g_a + l_g_b + l_g_c + l_f_a + l_f_b + l_f_c) + @- ra_a_a + ra_a_b + ra_a_c + ra_b_a + ra_b_b + ra_b_c + ra_c_a + ra_c_b + + ra_c_c) + in + let identities = + SMap.of_list + @@ List.map + (fun (key, id) -> (key, Scalar.mul q id)) + [ + (prefix "Plookup.a", id_a); + (prefix "Plookup.b", id_b); + (prefix "Plookup.c", id_c); + (prefix "Plookup.d", id_d); + ] + in + let id_ultra = + let q_table = get_answer answers X q_table_name in + let wire_values = + List.map (fun w -> get_answer answers X w) wires_names + in + let prod = Fr_generation.batch alpha (q_table :: wire_values) in + Scalar.(q * (prod @- fg)) + in + SMap.add (prefix "Plookup.ultra") id_ultra identities + + let prover_identities ~prefix_common ~prefix ~wires_names ~alpha ~beta ~gamma + n : prover_identities = + fun evaluations -> + let q = prefix_common q_label in + let q_table = prefix_common q_table in + let t = prefix_common t in + let z = prefix z in + let h1 = prefix h1 in + let h2 = prefix h2 in + let f = prefix f in + let wires_names = List.map (fun n -> prefix n) wires_names in + let fs = q_table :: wires_names in + let z = Evaluations.find_evaluation evaluations z in + let q = Evaluations.find_evaluation evaluations q in + let l1 = Evaluations.find_evaluation evaluations l1 in + let ln_p_1 = Evaluations.find_evaluation evaluations ln_p_1 in + + let eval_length = Evaluations.length q in + let id1_evaluation = Evaluations.create eval_length in + let id2_evaluation = Evaluations.create eval_length in + let id3_evaluation = Evaluations.create eval_length in + let id4_evaluation = Evaluations.create eval_length in + let tmp_evaluation = Evaluations.create eval_length in + + let idb = + let one_p_b = Scalar.(one + beta) in + let g_one_p_b = Scalar.(gamma * one_p_b) in + + (* res <- γ·(1 + β) + e(x) + β·e(gx) *) + let g_one_p_b_plus_e_plus_beta_p_eg res e = + Evaluations.linear + ~res + ~evaluations + ~poly_names:[e; e] + ~add_constant:g_one_p_b + ~composition_gx:([0; 1], n) + ~linear_coeffs:[one; beta] + () + in + + (* id1_evaluation <- (x - 1) *) + let x_mone = + Evaluations.linear + ~res:id1_evaluation + ~evaluations + ~poly_names:[x] + ~add_constant:mone + () + in + (* id2_evaluation <- (1 + β)·f(x) + γ·(1 + β) *) + let f_expr = + Evaluations.linear + ~res:id2_evaluation + ~evaluations + ~poly_names:[f] + ~linear_coeffs:[one_p_b] + ~add_constant:g_one_p_b + () + in + (* id3_evaluation <- γ·(1 + β) + t(x) + β·t(gx) *) + let t_expr = g_one_p_b_plus_e_plus_beta_p_eg id3_evaluation t in + (* id4_evaluation <- + z(x)·(x - 1)·((1 + β)·f(x) + γ·(1 + β))·(γ·(1 + β) + t(x) + β·t(gx)) *) + let left_term = + Evaluations.mul_c + ~res:id4_evaluation + ~evaluations:[z; x_mone; f_expr; t_expr] + () + in + + (* id2_evaluation <- γ·(1 + β) + h1(x) + β·h1(gx) *) + let h1_expr = g_one_p_b_plus_e_plus_beta_p_eg id2_evaluation h1 in + (* id3_evaluation <- γ·(1 + β) + h2(x) + β·h2(gx) *) + let h2_expr = g_one_p_b_plus_e_plus_beta_p_eg id3_evaluation h2 in + (* tmp_evaluation <- + z(gx)·(x - 1)·(γ·(1 + β) + h1(x) + β·h1(gx))·(γ·(1 + β) + h2(x) + β·h2(gx)) *) + let right_term = + Evaluations.mul_c + ~res:tmp_evaluation + ~evaluations:[z; x_mone; h1_expr; h2_expr] + ~composition_gx:([1; 0; 0; 0], n) + () + in + let id_b = + Evaluations.linear_c + ~res:id1_evaluation + ~evaluations:[left_term; right_term] + ~linear_coeffs:[one; mone] + () + in + Evaluations.mul_c ~res:id2_evaluation ~evaluations:[q; id_b] () + in + + (* tmp_evaluation <- (z - 1) *) + let z_mone = + Evaluations.linear_c + ~res:tmp_evaluation + ~evaluations:[z] + ~add_constant:mone + () + in + + let ida = + Evaluations.mul_c ~res:id1_evaluation ~evaluations:[q; l1; z_mone] () + in + let idd = + Evaluations.mul_c ~res:id4_evaluation ~evaluations:[q; ln_p_1; z_mone] () + in + + let idc = + (* tmp_evaluation <- (h1(x) - h2(gx)) *) + let h1_minus_h2g = + Evaluations.linear + ~res:tmp_evaluation + ~evaluations + ~poly_names:[h1; h2] + ~linear_coeffs:[one; mone] + ~composition_gx:([0; 1], n) + () + in + + Evaluations.mul_c + ~res:id3_evaluation + ~evaluations:[q; ln_p_1; h1_minus_h2g] + () + in + + let base = [ida; idb; idc; idd] in + let ids = + let id_agg = + let id5_evaluation = Evaluations.create eval_length in + (* id5_evaluation <- fs1 + alpha * fs2 + alpha^2 * fs3 + .. *) + let s = + let alpha_array = Fr_generation.powers (List.length fs) alpha in + Evaluations.linear + ~res:id5_evaluation + ~evaluations + ~poly_names:fs + ~linear_coeffs:(Array.to_list alpha_array) + () + in + + (* tmp_evaluation <- (s - f) *) + let s_minus_f = + let f = Evaluations.find_evaluation evaluations f in + Evaluations.linear_c + ~res:tmp_evaluation + ~evaluations:[s; f] + ~linear_coeffs:[one; mone] + ~composition_gx:([0; 1], n) + () + in + Evaluations.mul_c ~res:id5_evaluation ~evaluations:[q; s_minus_f] () + in + id_agg :: base + in + let id_names = + let base = ["Plookup.a"; "Plookup.b"; "Plookup.c"; "Plookup.d"] in + let base = "Plookup.ultra" :: base in + List.map (fun id_name -> prefix id_name) base + in + SMap.of_list (List.combine id_names ids) + + module Plookup_poly = struct + let ln_p_1 n domain = + let scalar_list = Array.(append [|one|] (init (n - 1) (fun _ -> zero))) in + Evaluations.interpolation_fft2 domain scalar_list + + (* computes an array where the i-th element is sum_j alpha_j*x_i,j + where x_i,j is the i-th elementof the j_th array of the list*) + let compute_aggregation array_list alpha = + let n = Array.length (List.hd array_list) in + let nb_wires = List.length array_list in + let alpha_array = Fr_generation.powers nb_wires alpha in + Array.init n (fun i -> + let fis = List.map (fun array -> array.(i)) array_list in + List.fold_left2 + (fun acc alpha_j fij -> Scalar.(acc + (alpha_j * fij))) + Scalar.zero + (Array.to_list alpha_array) + fis) + + let compute_f_aggregation gates wires alpha n = + let q = SMap.find q_label gates in + let nb_wires = SMap.cardinal wires in + let alpha_array = Fr_generation.powers nb_wires alpha in + let array_list = SMap.values wires in + let compute_aggregate qi fis = + List.fold_left2 + (fun acc alpha_j fij -> Scalar.(acc + (alpha_j * qi * fij))) + Scalar.zero + (Array.to_list alpha_array) + fis + in + (* Store previous lookup to pad with *) + let previous_lookup = + let index = + List.find + (fun i -> not (Scalar.is_zero q.(i))) + (List.init n (fun i -> i)) + in + let q0 = q.(index) in + let f0s = List.map (fun array -> array.(index)) array_list in + ref (compute_aggregate q0 f0s) + in + Array.init n (fun i -> + let qi = q.(i) in + if Scalar.is_zero qi then !previous_lookup + else + let fis = List.map (fun array -> array.(i)) array_list in + let lookup = compute_aggregate qi fis in + if not (Scalar.eq !previous_lookup lookup) then + previous_lookup := lookup ; + lookup) + + let sort_by f t = + let indexes_t, _ = + Array.fold_left + (fun (map, i) z -> (Scalar_map.add z i map, i + 1)) + (Scalar_map.empty, 0) + t + in + let my_compare a b = + let a_index_opt = Scalar_map.find_opt a indexes_t in + let b_index_opt = Scalar_map.find_opt b indexes_t in + match (a_index_opt, b_index_opt) with + | Some a_index, Some b_index -> a_index - b_index + | _ -> raise (Entry_not_in_table "Array f is not included in array t") + in + Array.sort my_compare f ; + f + + let switch t = + let k = Array.length t in + Array.init k (fun i -> if i = 0 then t.(k - 1) else t.(i - 1)) + + let t_poly_from_tables tables alpha domain = + let t = compute_aggregation tables alpha in + Evaluations.interpolation_fft2 domain (switch t) + + let compute_s f t = sort_by (Array.concat [f; t]) t + + let compute_h s domain n = + let compute_hi ~domain ~start s n = + Evaluations.interpolation_fft2 domain (switch (Array.sub s start n)) + in + let h1 = compute_hi ~domain ~start:0 s n in + let h2 = compute_hi ~domain ~start:(n - 1) s n in + (h1, h2) + + let compute_z beta gamma f t s n domain = + let one_p_beta = Scalar.(one + beta) in + let gamma_one_p_beta = Scalar.(gamma * one_p_beta) in + let tmp = Scalar.(copy one) in + + let to_acc array i = + let beta_a = Scalar.mul beta array.(Int.succ i) in + Scalar.( + add_inplace tmp beta_a array.(i) ; + add_inplace beta_a tmp gamma_one_p_beta ; + beta_a) + in + + (* the first two elements of z_array are always one *) + let z_array = Array.init n (fun _ -> Scalar.zero) in + + z_array.(0) <- one ; + z_array.(1) <- one ; + for i = 0 to n - 3 do + let f_coeff = Scalar.(f.(i) + gamma) in + let t_coeff = to_acc t i in + Scalar.( + mul_inplace tmp f_coeff one_p_beta ; + mul_inplace f_coeff tmp t_coeff) ; + + let acc_i = to_acc s i in + let acc_n_i = to_acc s (n - 1 + i) in + Scalar.mul_inplace acc_i acc_i acc_n_i ; + let z_coeff = Scalar.(f_coeff / acc_i) in + z_array.(i + 2) <- Scalar.mul z_array.(i + 1) z_coeff + done ; + + Evaluations.interpolation_fft2 domain z_array + end + + let srs_size ~length_table = + let log = Z.(log2up (of_int length_table)) in + let length_padded = Int.shift_left 1 log in + length_padded + + (* max degree of Plookup identities is idb’s degree, which is ~4n *) + let polynomials_degree () = 4 + + let common_preprocessing ~n:nb_records ~domain ~evaluations = + let lnp1_map = + SMap.singleton ln_p_1 (Plookup_poly.ln_p_1 nb_records domain) + in + Evaluations.compute_evaluations_update_map ~evaluations lnp1_map + + let preprocessing ~domain ~tables ~alpha () = + let alpha = get_alpha alpha in + SMap.singleton t (Plookup_poly.t_poly_from_tables tables alpha domain) + + let format_tables ~tables ~nb_columns ~length_not_padded ~length_padded = + let concatenated_table = + (* We make sure that all tables have the same number of columns as the number of wires by filling with columns of 0s. + We also index tables. *) + let corrected_tables = + List.mapi + (fun i t -> + let nb_subtable_columns = List.length t in + let sub_table_size = Array.length (List.hd t) in + (* Pad table to have constant number of columns. *) + let padding_columns = + List.init (nb_columns - nb_subtable_columns) (fun _ -> + Array.make sub_table_size zero) + in + let full_table = t @ padding_columns in + (* Indexing table. *) + Array.make sub_table_size (Scalar.of_z (Z.of_int i)) :: full_table) + tables + in + (* Concatenating tables. *) + let acc_n = List.init (nb_columns + 1) (fun _ -> [||]) in + List.fold_left + (fun aa ll -> List.map2 (fun a l -> Array.append a l) aa ll) + acc_n + corrected_tables + in + (* Padding table. *) + List.map + (fun t -> + let last = t.(length_not_padded - 1) in + let padding = Array.make (length_padded - length_not_padded) last in + Array.append t padding) + concatenated_table + + let prover_identities ?(circuit_name = "") ~proof_idx ~nb_proofs ~wires_names + ~alpha ~beta ~gamma ~n () : prover_identities = + let alpha = get_alpha alpha in + let prefix_common = SMap.Aggregation.add_prefix circuit_name in + let prefix = + SMap.Aggregation.add_prefix ~n:nb_proofs ~i:proof_idx circuit_name + in + prover_identities ~prefix_common ~prefix ~wires_names ~alpha ~beta ~gamma n + + let verifier_identities ?(circuit_name = "") ~proof_idx ~nb_proofs ~n + ~generator ~wires_names ~alpha ~beta ~gamma () : verifier_identities = + let alpha = get_alpha alpha in + let prefix_common = SMap.Aggregation.add_prefix circuit_name in + let prefix = + SMap.Aggregation.add_prefix ~n:nb_proofs ~i:proof_idx circuit_name + in + gate_identity + ~prefix_common + ~prefix + ~n + ~generator + ~wires_names + ~alpha + ~beta + ~gamma + + (* wires must be correctly padded *) + (*TODO : do this in evaluation*) + (*TODO : use mul z_s*) + let f_map_contribution ~wires ~gates ~tables ~alpha ~beta ~gamma ~domain + ~circuit_size:_ = + (* TODO : remove this conversion *) + let wires = SMap.map Evaluations.to_array wires in + let size_domain = Domain.length domain in + let alpha = get_alpha alpha in + let t_agg = Plookup_poly.compute_aggregation tables alpha in + (* We add the table selector to be aggregated alongside the wires. *) + let wires_to_agg = + let table_selector = SMap.find q_table gates in + (* We add the prefix _ to the selector's label to make sure the selector is first in the map. *) + SMap.add ("_" ^ q_table) table_selector wires + in + let final_size = size_domain - 1 in + (* /!\ We remove here the last value of each wire, this is ok as it always corresponds to padding. *) + let padded_f_list = + SMap.map (fun w -> Array.resize w final_size) wires_to_agg + in + let f_agg = + Plookup_poly.compute_f_aggregation gates padded_f_list alpha final_size + in + let f_poly = + Evaluations.interpolation_fft2 domain Array.(append [|zero|] f_agg) + in + let s = Plookup_poly.compute_s f_agg t_agg in + let h1_poly, h2_poly = Plookup_poly.compute_h s domain size_domain in + let z_poly = + Plookup_poly.compute_z beta gamma f_agg t_agg s size_domain domain + in + SMap.of_list [(h1, h1_poly); (h2, h2_poly); (z, z_poly); (f, f_poly)] +end + +module type S = sig + module PP : Polynomial_protocol.S + + exception Entry_not_in_table of string + + type public_parameters = + (PP.prover_public_parameters * PP.verifier_public_parameters) + * Scalar.t array list + * Poly.t SMap.t + + val srs_size : length_table:int -> int + + val polynomials_degree : unit -> int + + val format_tables : + tables:Scalar.t array list list -> + nb_columns:int -> + length_not_padded:int -> + length_padded:int -> + Scalar.t array list + + val common_preprocessing : + n:int -> + domain:Domain.t -> + evaluations:Evaluations.t SMap.t -> + Evaluations.t SMap.t + + val preprocessing : + domain:Domain.t -> + tables:Scalar.t array list -> + alpha:Scalar.t option -> + unit -> + Poly.t SMap.t + + val prover_identities : + ?circuit_name:string -> + proof_idx:int -> + nb_proofs:int -> + wires_names:string list -> + alpha:Scalar.t option -> + beta:Scalar.t -> + gamma:Scalar.t -> + n:int -> + unit -> + prover_identities + + val verifier_identities : + ?circuit_name:string -> + proof_idx:int -> + nb_proofs:int -> + n:int -> + generator:Scalar.t -> + wires_names:string list -> + alpha:Scalar.t option -> + beta:Scalar.t -> + gamma:Scalar.t -> + unit -> + verifier_identities + + val f_map_contribution : + wires:Evaluations.t SMap.t -> + gates:Scalar.t array SMap.t -> + tables:Scalar.t array list -> + alpha:Scalar.t option -> + beta:Scalar.t -> + gamma:Scalar.t -> + domain:Domain.t -> + circuit_size:int -> + PP.PC.secret +end + +module Plookup_gate (PP : Polynomial_protocol.S) : S with module PP = PP = + Plookup_gate_impl (PP) diff --git a/src/lib_plonk/polynomial_commitment.ml b/src/lib_plonk/polynomial_commitment.ml new file mode 100644 index 000000000000..7e08052a12f0 --- /dev/null +++ b/src/lib_plonk/polynomial_commitment.ml @@ -0,0 +1,399 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Bls +open Utils + +(* Implements a batched version of the KZG10 scheme, described in Section 3 of + the PlonK paper: https://eprint.iacr.org/2019/953.pdf *) + +module type Commitment_sig = sig + type t [@@deriving repr] + + type prover_aux [@@deriving repr] + + type prover_public_parameters + + type secret = Poly.t SMap.t + + (* [all_keys] is an optional argument that should only be used for + partial commitments. It contains all the polynomial names that + make up the full commitment. + For instance, if the full commitment contains polynomials "a", "b", "c" & + "d", then all keys will contain ["a", "b", "c", "d"] + Note that [secret] may only contain a subset of [all_keys] (for instance, + {"a", "b"}). + *) + val commit : + ?all_keys:string list -> + prover_public_parameters -> + secret -> + t * prover_aux + + val cardinal : t -> int + + val rename : (string -> string) -> t -> t +end + +module type Public_parameters_sig = sig + type prover [@@deriving repr] + + type verifier [@@deriving repr] + + type setup_params = int + + val setup : + setup_params -> + Bls12_381_polynomial.Srs.t * Bls12_381_polynomial.Srs.t -> + prover * verifier + + val to_bytes : int -> prover -> Bytes.t +end + +module type S = sig + (* polynomials to be committed *) + type secret = Poly.t SMap.t + + (* maps evaluation point names to evaluation point values *) + type query = Scalar.t SMap.t [@@deriving repr] + + (* maps evaluation point names to (map from polynomial names to evaluations) *) + type answer = Scalar.t SMap.t SMap.t [@@deriving repr] + + type proof [@@deriving repr] + + type transcript = Bytes.t + + module Commitment : Commitment_sig + + module Public_parameters : + Public_parameters_sig with type prover = Commitment.prover_public_parameters + + val evaluate : secret -> query -> answer + + val prove : + Public_parameters.prover -> + transcript -> + secret list -> + Commitment.prover_aux list -> + query list -> + answer list -> + proof * transcript + + val verify : + Public_parameters.verifier -> + transcript -> + Commitment.t list -> + query list -> + answer list -> + proof -> + bool * transcript +end + +module Kzg_impl = struct + module Public_parameters = struct + (* Structured Reference String + - srs1 : [[1]₁, [x¹]₁, …, [x^(d-1)]₁] ; + - encoding_1 : [1]₂; + - encoding_x : [x]₂ *) + type prover = {srs1 : Srs_g1.t; encoding_1 : G2.t; encoding_x : G2.t} + [@@deriving repr] + + let to_bytes len srs = + let open Utils.Hash in + let st = init () in + update st (G2.to_bytes srs.encoding_1) ; + update st (G2.to_bytes srs.encoding_x) ; + let srs1 = Srs_g1.to_array ~len srs.srs1 in + Array.iter (fun key -> update st (G1.to_bytes key)) srs1 ; + finish st + + type verifier = {encoding_1 : G2.t; encoding_x : G2.t} [@@deriving repr] + + type setup_params = int + + let setup_verifier srs_g2 = + let encoding_1 = Srs_g2.get srs_g2 0 in + let encoding_x = Srs_g2.get srs_g2 1 in + {encoding_1; encoding_x} + + let setup_prover (srs_g1, srs_g2) = + let {encoding_1; encoding_x} = setup_verifier srs_g2 in + {srs1 = srs_g1; encoding_1; encoding_x} + + let setup _ (srs, _) = + let prv = setup_prover srs in + let vrf = setup_verifier (snd srs) in + (prv, vrf) + end + + module Commitment = struct + type prover_public_parameters = Public_parameters.prover + + type secret = Poly.t SMap.t + + type t = G1.t SMap.t [@@deriving repr] + + type prover_aux = unit [@@deriving repr] + + let commit_single srs p = + let srs = Public_parameters.(srs.srs1) in + let poly_size = Poly.degree p + 1 in + let srs_size = Srs_g1.size srs in + if poly_size = 0 then G1.zero + else if poly_size > srs_size then + raise + (Failure + (Printf.sprintf + "Kzg.commit : Polynomial degree, %i, exceeds srs length, %i." + poly_size + srs_size)) + else Srs_g1.pippenger srs p + + let commit ?all_keys:_ srs f_map = + let cmt = SMap.map (commit_single srs) f_map in + let prover_aux = () in + (cmt, prover_aux) + + let cardinal cmt = SMap.cardinal cmt + + let rename f cmt = + SMap.fold (fun key x acc -> SMap.add (f key) x acc) cmt SMap.empty + end + + (* polynomials to be committed *) + type secret = Commitment.secret + + (* maps evaluation point names to evaluation point values *) + type query = Scalar.t SMap.t [@@deriving repr] + + (* maps evaluation point names to (map from polynomial names to evaluations) *) + type answer = Scalar.t SMap.t SMap.t [@@deriving repr] + + type transcript = Bytes.t + + let pippenger ?(start = 0) ?len ps ss = + try G1.pippenger ~start ?len ps ss + with Invalid_argument s -> + raise (Invalid_argument (Printf.sprintf "KZG.pippenger : %s" s)) + + type proof = G1.t SMap.t [@@deriving repr] + + (* compute W := (f(x) - s) / (x - z), where x is the srs secret exponent, + for every evaluation point [zname], key of the [query] map, where + z := SMap.find zname query + s := SMap.find zname batched_answer + f := SMap.find zname batched_polys + the computation is performed by first calculating polynomial + (f(X) - s) / (X - z) and then committing to it using the srs. + Here, f (respecitvely s) is a batched polynomial (respecively batched + evaluation) of all polynomials (and their respective evaluations) that + are evaluated at a common point z. They have been batched with the + uniformly sampled randomness from [y_map], see {!sample_ymap} *) + let compute_Ws srs batched_polys batched_answer query = + SMap.mapi + (fun x z -> + let f = SMap.find x batched_polys in + let s = SMap.find x batched_answer in + (* WARNING: This modifies [batched_polys], but we won't use it again: *) + Poly.sub_inplace f f @@ Poly.constant s ; + let h = fst @@ Poly.division_xn f 1 (Scalar.negate z) in + Commitment.commit_single srs h) + query + + (* verify the KZG equation: e(F - [s]₁ + z W, [1]₂) = e(W, [x]₂) + for every evaluation point [zname], key of the [query] map, where + z := SMap.find zname query + s := SMap.find zname s_map + W := SMap.find zname w_map + and F is computed as a linear combination (determined by [coeffs]) + of the commitments in [SMap.find zname cmt_map]. + All verification equations are checked at once by batching them + with fresh randomness sampled in [r_map]. + The combination of [cmt_map] and other G1.mul is delayed as much + as possible, in order to combine all of them with a single pippenger *) + let verifier_check srs cmt_map coeffs query s_map w_map = + let r_map = SMap.map (fun _ -> Scalar.random ()) w_map in + let cmts = SMap.values cmt_map in + let exponents = + SMap.fold + (fun x r exponents -> + let x_coeffs = SMap.find x coeffs in + SMap.mapi + (fun name exp -> + match SMap.find_opt name x_coeffs with + | None -> exp + | Some c -> Scalar.(exp + (r * c))) + exponents) + r_map + (SMap.map (fun _ -> Scalar.zero) cmt_map) + |> SMap.values + in + let s = + SMap.fold + (fun x r s -> Scalar.(sub s (r * SMap.find x s_map))) + r_map + Scalar.zero + in + let w_left_exps = + List.map (fun (x, r) -> Scalar.mul r @@ SMap.find x query) + @@ SMap.bindings r_map + in + let w_right_exps = + (* We negate them before the pairing_check, which is done on the lhs *) + SMap.values r_map |> List.map Scalar.negate + in + + let ws = SMap.values w_map in + let left = + pippenger + (Array.of_list @@ (G1.one :: ws) @ cmts) + (Array.of_list @@ (s :: w_left_exps) @ exponents) + in + let right = pippenger (Array.of_list ws) (Array.of_list w_right_exps) in + Public_parameters.[(left, srs.encoding_1); (right, srs.encoding_x)] + |> Pairing.pairing_check + + (* return a map between evaluation point names (from [query]) and uniformly + sampled scalars, used for batching; also return an updated transcript *) + let sample_ys transcript query = + let n = SMap.cardinal query in + let ys, transcript = Fr_generation.random_fr_list transcript n in + let y_map = + SMap.of_list (List.map2 (fun y name -> (name, y)) ys @@ SMap.keys query) + in + (y_map, transcript) + + (* On input a scalar map [y_map] and [answer], e.g., + y_map := { 'x0' -> y₀; 'x1' -> y₁ } + answer := { 'x0' -> { 'a' -> a(x₀); 'b' -> b(x₀); 'c' -> c(x₀); ... }; + 'x1' -> { 'a' -> a(x₁); 'c' -> c(x₁); 'd' -> d(x₁); ... }; } + outputs a map of batched evaluations: + { 'x0' -> a(x₀) + y₀b(x0) + y₀²c(x₀) + ...); + 'x1' -> a(x₁) + y₁c(x1) + y₁²d(x₁) + ...); } + and a map of batching coefficients: + { 'x0' -> { 'a' -> 1; 'b' -> y₀; 'c' -> y₀²; ... }; + 'x1' -> { 'a' -> 1; 'c' -> y₁; 'd' -> y₁²; ... }; } *) + let batch_answer y_map answer = + let couples = + SMap.mapi + (fun x s_map -> + let y = SMap.find x y_map in + let s, coeffs, _yk = + SMap.fold + (fun name s (acc_s, coeffs, yk) -> + let acc_s = Scalar.(add acc_s @@ mul yk s) in + let coeffs = SMap.add name yk coeffs in + let yk = Scalar.mul yk y in + (acc_s, coeffs, yk)) + s_map + (Scalar.zero, SMap.empty, Scalar.one) + in + (s, coeffs)) + answer + in + (SMap.map fst couples, SMap.map snd couples) + + (* On input batching coefficients [coeffs] and a map of polys [f_map], e.g., + coeffs := { 'x0' -> { 'a' -> 1; 'b' -> y₀; 'c' -> y₀²; ... }; + 'x1' -> { 'a' -> 1; 'c' -> y₁; 'd' -> y₁²; ... }; } + f_map := { 'a' -> a(X); 'b' -> b(X); 'c' -> c(X); ... }, + outputs a map of batched polynomials: + { 'x0' -> a(X) + y₀b(X) + y₀²c(X) + ...); + 'x1' -> a(X) + y₁c(X) + y₁²d(X) + ...); } *) + let batch_polys coeffs f_map = + let polys = SMap.bindings f_map in + SMap.map + (fun f_coeffs -> + let coeffs, polys = + List.filter_map + (fun (name, p) -> + Option.map (fun c -> (c, p)) @@ SMap.find_opt name f_coeffs) + polys + |> List.split + in + Poly.linear polys coeffs) + coeffs + + let prove_single srs transcript f_map query answer = + let y_map, transcript = sample_ys transcript query in + let batched_answer, coeffs = batch_answer y_map answer in + let batched_polys = batch_polys coeffs f_map in + let proof = compute_Ws srs batched_polys batched_answer query in + (proof, Transcript.expand proof_t proof transcript) + + let verify_single srs transcript cmt_map query answer proof = + let y_map, transcript = sample_ys transcript query in + let batched_answer, coeffs = batch_answer y_map answer in + let b = verifier_check srs cmt_map coeffs query batched_answer proof in + (b, Transcript.expand proof_t proof transcript) + + (* group functions allow [prove] and [verify] rely on [prove_single] and + [verify_single] respectively *) + + let group_secrets : secret list -> secret = SMap.union_disjoint_list + + let group_cmts : Commitment.t list -> Commitment.t = SMap.union_disjoint_list + + let group_queries : query list -> query = + fun query_list -> + let union = + SMap.union (fun _ z z' -> + if Scalar.eq z z' then Some z + else + failwith "group_query: equal query names must map to equal values") + in + List.fold_left union (List.hd query_list) (List.tl query_list) + + let group_answers : answer list -> answer = + fun answer_list -> + List.fold_left + (SMap.union (fun _ m1 m2 -> Some (SMap.union_disjoint m1 m2))) + (List.hd answer_list) + (List.tl answer_list) + + (* evaluate every polynomial in [f_map] at all evaluation points in [query] *) + let evaluate : Poly.t SMap.t -> query -> answer = + fun f_map query -> + SMap.map (fun z -> SMap.map (fun f -> Poly.evaluate f z) f_map) query + + let prove srs transcript f_map_list _prover_aux_list query_list answer_list = + let transcript = Transcript.list_expand query_t query_list transcript in + let transcript = Transcript.list_expand answer_t answer_list transcript in + let f_map = group_secrets f_map_list in + let query = group_queries query_list in + let answer = group_answers answer_list in + prove_single srs transcript f_map query answer + + let verify srs transcript cmt_map_list query_list answer_list proof = + let transcript = Transcript.list_expand query_t query_list transcript in + let transcript = Transcript.list_expand answer_t answer_list transcript in + let cmt_map = group_cmts cmt_map_list in + let query = group_queries query_list in + let answer = group_answers answer_list in + verify_single srs transcript cmt_map query answer proof +end + +include (Kzg_impl : S) diff --git a/src/lib_plonk/polynomial_protocol.ml b/src/lib_plonk/polynomial_protocol.ml new file mode 100644 index 000000000000..84229bfd4803 --- /dev/null +++ b/src/lib_plonk/polynomial_protocol.ml @@ -0,0 +1,288 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Bls +open Utils +open Identities + +(** A polynomial protocol allows a prover to convince a verifier of the fact + that certain algebraic identites between polynomials (polynomials that have + been previously committed) hold when evaluated over a set of points. + (In our implementation such set of points must be a subgroup of roots of + unity.) + + For example, let K be a field and let H be a subset of K. + Let f1(X), f2(X) and f3(X) be univariate polynomials over K and let + C1, C2 and C3 be polynomial commitments to f1, f2 and f3, respectively. + A polynomial protocol allows a prover to argue knowledge of: + {[ + PoK{ (f1, f2, f3) : Ci = Com(fi) ∀ i /\ f1(x) * f2(x) = f3(x) ∀ x ∈ H } + ]} + This can be accomplished by evaluating polynomial commitments at a single + point ξ (uniformly sampled from K). For that, note that the above + polynomial identity holds for every x ∈ H iff polynomial (f1 * f2 - f3) is + divisible by Zh, the minimal (monic) polynomial that vanishes over set H. + Thus, the prover can commit to polynomial T := (f1 * f2 - f3) / Zh and + evaluate polynomial commitments C1, C2, C3, T at ξ (chosen after T). Let + c1, c2, c3, t be such evaluations. + The verifier can then check that t * Zh(ξ) = c1 * c2 - c3. + + A general polynomial protocol should allow for multiple identities involving + addition, multiplication and composition of polynomials. + + See {{: https://eprint.iacr.org/2019/953.pdf }2019/953 Section 4.1} for + more details. *) + +(** Functor building an implementation of a polynomial protocol given a + polynomial commitment scheme [PC]. *) +module Make_impl (PC : Polynomial_commitment.S) = struct + module PC = PC + + type prover_public_parameters = PC.Public_parameters.prover [@@deriving repr] + + type verifier_public_parameters = PC.Public_parameters.verifier + [@@deriving repr] + + type transcript = Bytes.t [@@deriving repr] + + type proof = { + cm_t : PC.Commitment.t; + pc_proof : PC.proof; + pc_answers : PC.answer list; + } + [@@deriving repr] + + (** [split_t n t nb_of_t_chunks] splits [t] polynomial in [nb_of_t_chunks] + polynomials of at most [n] coefficients (and at most degree [n]-1), + except the last one that may have more coeffictients depending on [t]’s + degree + *) + let split_t n t nb_of_t_chunks = + List.mapi + (fun i t_i -> ("T_" ^ string_of_int i, t_i)) + (Poly.split ~nb_chunks:nb_of_t_chunks n t) + |> SMap.of_list + + (* [compute_t ~n ~alpha evaluations] returns a polynomial T splitted in chunks, + where [T(X) = (sum_i alpha^i evaluations[i]) / (X^n - 1)] and the returned + chunks [{ 'T_0' -> T0; 'T_1' -> T1; 'T_2' -> T2 }] are such that + [T = T0 + X^n T1 + X^{2n} T2]. *) + let compute_t ~n ~alpha ~nb_of_t_chunks evaluated_identities = + let nb_ids = SMap.cardinal evaluated_identities in + let evaluations = SMap.values evaluated_identities in + let alphas = Fr_generation.powers nb_ids alpha |> Array.to_list in + let s_eval = Evaluations.linear_c ~evaluations ~linear_coeffs:alphas () in + let s_deg = Evaluations.degree s_eval in + let domain = Domain.build_power_of_two (Z.log2up (Z.of_int (s_deg + 1))) in + let s = Evaluations.interpolation_fft domain s_eval in + let t, rem = Poly.division_xn s n Scalar.(negate one) in + if Poly.is_zero rem then ( + let splits = split_t n t nb_of_t_chunks in + assert (SMap.for_all (fun _k v -> Poly.degree v < n) splits) ; + splits) + else raise @@ Poly.Rest_not_null "T is not divisible by Zh" + + let eval_and_batch_ids (alpha, x) pc_answers identities = + let answers = + let f _key m1 m2 = Some (SMap.union_disjoint m1 m2) in + List.fold_left (SMap.union f) SMap.empty pc_answers + in + identities x answers |> SMap.values |> Fr_generation.batch alpha + + let verify_t n x ids_batch t_evals = + let t_eval = Fr_generation.batch (Scalar.pow x (Z.of_int n)) t_evals in + let zh = Scalar.(sub (pow x (Z.of_int n)) one) in + Scalar.(eq ids_batch (t_eval * zh)) + + let setup ~setup_params ~srs = PC.Public_parameters.setup setup_params srs + + (* This function is the common code between prove & Aggregation.PP.prove *) + let prove_aux pc_public_parameters transcript n generator secrets eval_points + evaluations identities nb_of_t_chunks = + let alpha, transcript = Fr_generation.random_fr transcript in + let evaluated_ids = identities evaluations in + let t = compute_t ~n ~alpha ~nb_of_t_chunks evaluated_ids in + let cm_t, t_prover_aux = PC.Commitment.commit pc_public_parameters t in + let transcript = Transcript.expand PC.Commitment.t cm_t transcript in + let x, transcript = Fr_generation.random_fr transcript in + let prover_aux_list = t_prover_aux :: List.map snd secrets in + let polys_list = t :: List.map fst secrets in + let eval_points = [X] :: eval_points in + let query_list = List.map (convert_eval_points ~generator ~x) eval_points in + let answer_list = List.map2 PC.evaluate polys_list query_list in + ( (alpha, x, answer_list, cm_t), + polys_list, + prover_aux_list, + query_list, + transcript ) + + let prove pc_public_parameters transcript ~n ~generator ~secrets ~eval_points + ~evaluations ~identities ~nb_of_t_chunks = + let ( (_, _, answer_list, cm_t), + polys_list, + prover_aux_list, + query_list, + transcript ) = + prove_aux + pc_public_parameters + transcript + n + generator + secrets + eval_points + evaluations + identities + nb_of_t_chunks + in + let pc_proof, transcript = + PC.prove + pc_public_parameters + transcript + polys_list + prover_aux_list + query_list + answer_list + in + ({cm_t; pc_proof; pc_answers = answer_list}, transcript) + + type pp_commit_to_t_r = Evaluations.t SMap.t [@@deriving repr] + + (* This function is the common code between verify & Aggregation.PP.verify *) + let verify_aux transcript generator commitments eval_points proof = + let alpha, transcript = Fr_generation.random_fr transcript in + let transcript = Transcript.expand PC.Commitment.t proof.cm_t transcript in + let x, transcript = Fr_generation.random_fr transcript in + let cm_list = proof.cm_t :: commitments in + let eval_points = [X] :: eval_points in + let query_list = List.map (convert_eval_points ~generator ~x) eval_points in + (alpha, x, transcript, cm_list, query_list) + + let verify pc_public_parameters transcript ~n ~generator ~commitments + ~eval_points ~identities proof = + let alpha, x, transcript, cmts, query_list = + verify_aux transcript generator commitments eval_points proof + in + let pc_verif, transcript = + PC.verify + pc_public_parameters + transcript + cmts + query_list + proof.pc_answers + proof.pc_proof + in + let ids_batch = eval_and_batch_ids (alpha, x) proof.pc_answers identities in + let t_verif = + let t_evals = + List.hd proof.pc_answers + |> SMap.find (string_of_eval_point X) + |> SMap.values + in + verify_t n x ids_batch t_evals + in + (pc_verif && t_verif, transcript) +end + +(** Output signature of the functor [Polynomial_protocol.Make]. *) +module type S = sig + (** Underlying polynomial commitment scheme on which the polynomial protocol + is based. Input of the functor [Polynomial_protocol.Make]. *) + module PC : Polynomial_commitment.S + + (** The type of prover public parameters. *) + type prover_public_parameters = PC.Public_parameters.prover [@@deriving repr] + + (** The type of verifier public parameters. *) + type verifier_public_parameters = PC.Public_parameters.verifier + [@@deriving repr] + + (** The type for transcripts, used for applying the Fiat-Shamir heuristic *) + type transcript = PC.transcript [@@deriving repr] + + (** The type for proofs, containing a commitment to the polynomial T that + asserts the satisfiability of the identities over the subset of interest, + as well as a [PC] proof and a list of [PC] answers. *) + type proof = { + cm_t : PC.Commitment.t; + pc_proof : PC.proof; + pc_answers : PC.answer list; + } + [@@deriving repr] + + (** The polynomial commitment setup function, requires a labeled + argument of setup parameters for the underlying [PC] and a labeled + argument containing the path location of a set of SRS files. *) + val setup : + setup_params:PC.Public_parameters.setup_params -> + srs:Bls12_381_polynomial.Srs.t * Bls12_381_polynomial.Srs.t -> + prover_public_parameters * verifier_public_parameters + + (** The prover function. Takes as input the [prover_public_parameters], + an initial [transcript] (possibly including a context if this [prove] is + used as a building block of a bigger protocol), the size [n] of subgroup H, + the canonical [generator] of subgroup H, a list of [secrets] including + polynomials that have supposedly been committed (and a verifier received + such commitments) as well as prover auxiliary information generated + during the committing process, a list of evaluation point lists specifying + the evaluation points where each secret needs to be evaluated at, + a map of the above-mentioned polynomials this time in FFT [evaluations] form, + for efficient polynomial multiplication, and some [prover_identities] that + are supposedly satisfied by the secret polynomials. + Outputs a proof and an updated transcript. *) + val prove : + prover_public_parameters -> + transcript -> + n:int -> + generator:Scalar.t -> + secrets:(Poly.t SMap.t * PC.Commitment.prover_aux) list -> + eval_points:eval_point list list -> + evaluations:Evaluations.t SMap.t -> + identities:prover_identities -> + nb_of_t_chunks:int -> + proof * transcript + + (** The verifier function. Takes as input the [verifier_public_parameters], + an initial [transcript] (that should coincide with the initial transcript + used by [prove]), the size [n] of subgroup H, the canonical [generator] of + subgroup H, a list of [commitments] to the secret polynomials by the prover, + a list of evaluation points as in [prove], some [verifier_identities], and + a [proof]. + Outputs a [bool] value representing acceptance or rejection. *) + val verify : + verifier_public_parameters -> + transcript -> + n:int -> + generator:Scalar.t -> + commitments:PC.Commitment.t list -> + eval_points:eval_point list list -> + identities:verifier_identities -> + proof -> + bool * transcript +end + +module Make : functor (PC : Polynomial_commitment.S) -> S with module PC = PC = + Make_impl + +include Make (Polynomial_commitment) diff --git a/src/lib_plonk/range_check_gate.ml b/src/lib_plonk/range_check_gate.ml new file mode 100644 index 000000000000..e1c1ea9c33d6 --- /dev/null +++ b/src/lib_plonk/range_check_gate.ml @@ -0,0 +1,415 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* This gate is used to do range checks on values of a wire + We noticed an overhead of 20% in prover time when using this protocol ; + considering N is the number of constraints, if there are κ constraints per + range checks, denoting x the percentage of the Z polynomial used, solving + the equation N × 1.2 = N + κ × N × x gives x = (0.2/κ). + With κ = 3, we need the Z polynomial filled by 7%. + + Note that we don’t handle several proofs for now. + + TODO to integrate the protocol completely : + - handle several proofs + - integration to plompiler + - more tests, especially for zk + - integration to aPlonK +*) + +open Bls +open Utils +open Identities + +module type S = sig + module PP : Polynomial_protocol.S + + val build_permutation : + range_checks:int list * int -> size_domain:int -> int array + + val common_preprocessing : unit -> 'a SMap.t + + val preprocessing : + permutation:int array -> + range_checks:'a list * int -> + domain:Domain.t -> + Poly.t SMap.t + + val f_map_contribution : + permutation:int array -> + beta:Scalar.t -> + gamma:Scalar.t -> + domain:Domain.t -> + range_checks:int list * int -> + values:Evaluations.t SMap.t -> + Poly.t SMap.t + + val prover_identities : + ?circuit_name:string -> + nb_proofs:int -> + proof_idx:int -> + beta:Scalar.t -> + gamma:Scalar.t -> + domain_size:int -> + unit -> + prover_identities + + val verifier_identities : + ?circuit_name:string -> + nb_proofs:int -> + proof_idx:int -> + beta:Scalar.t -> + gamma:Scalar.t -> + domain_size:int -> + generator:Scalar.t -> + unit -> + verifier_identities +end + +module Range_check_gate_impl (PP : Polynomial_protocol.S) = struct + module PP = PP + + exception Too_many_checks of string + + let lnin1 = "Lni_plus_n_minus_1" + + let pnin1 = "Pni_plus_n_minus_1" + + let z_name = "RC_Z" + + let z_perm_name = "RC_Perm_Z" + + let ids_label = "RC_Perm" + + let wire = "a" + + type public_parameters = Poly.t SMap.t + + let zero, one, two = Scalar.(zero, one, one + one) + + let mone, mtwo = Scalar.(negate one, negate two) + + (* This function returns the index of the first occurence of [x] in [l]. + If [l] does not contain [x], -1 is returned. *) + let find l x = + let rec aux i = function + | [] -> -1 + | h :: t -> if x = h then i else aux (i + 1) t + in + aux 0 l + + (* Build the permutation such that nj <-> N + i_j for n = [up_bound], + j < len([rc]), N = [size_domain], i_j = index of the j-th range check in + [rc] *) + let build_permutation ~range_checks:(rc, up_bound) ~size_domain = + let get_safe l i = + try size_domain + List.nth l (i / up_bound) with _ -> i + in + if rc = [] then [||] + else + let fst = + Array.init size_domain (fun i -> + (* if we are at a range check index i then the permutation goes on + the corresponding index in the range check list ; if there is no + more index in the range check list, or if we are not at a range + check index, i is a fix point of the permutation + *) + if i mod up_bound = 0 then get_safe rc i else i) + in + let snd = + Array.init size_domain (fun i -> + (* if i is not a index of the range check list then it’s a fix point, + else it goes on on index of the corresponding range check ; + this piece is the mirror of the preceeding one *) + match find rc i with -1 -> size_domain + i | j -> j * up_bound) + in + Array.append fst snd + + (* TODO we should be able to aggregate permutation for different range checks + proofs as we do for wires ; for now & simplicity, we don’t handle several + proofs in one circuit *) + module Permutation = struct + module Perm = Permutation_gate.Permutation_gate_impl (PP) + + let preprocessing ~permutation ~domain = + let ss_map = + Perm.Preprocessing.ssigma_map_non_quadratic_residues + permutation + domain + 2 + in + SMap.update_keys (String.cat "RC_") ss_map + + let f_map_contribution ~permutation ~beta ~gamma ~domain ~values = + SMap.singleton + z_perm_name + (Perm.Permutation_poly.compute_Z permutation domain beta gamma values) + + let prover_identities ~prefix_common ~prefix ~beta ~gamma domain_size = + Perm.prover_identities + ~prefix:"RC_" + ~circuit_name:prefix_common + ~wires_names:[prefix z_name; prefix wire] + ~beta + ~gamma + ~n:domain_size + () + + let verifier_identities ~prefix_common ~prefix ~beta ~gamma domain_size + generator = + Perm.verifier_identities + ~prefix:"RC_" + ~circuit_name:prefix_common + ~nb_proofs:1 + ~generator + ~n:domain_size + ~wires_names:[prefix z_name; prefix wire] + ~beta + ~gamma + ~delta:one + () + end + + module RangeChecks = struct + let assert_not_too_many_checks k nb = + if k < nb then + raise + (Too_many_checks + (Printf.sprintf "%d checks asked, %d checks expected" nb k)) + + let compute_pnin1 upper_bound domain domain_size = + let x_w i = + Poly.of_coefficients + [(one, 1); (Scalar.negate (Domain.get domain i), 0)] + in + let k = domain_size / upper_bound in + (* Computes product of (X-ω^(ni + n - 1)) from i = 1 to k *) + let rec aux res = function + | 0 -> res + | i -> aux (Poly.mul res (x_w ((upper_bound * i) - 1))) (i - 1) + in + aux Poly.one k + + let preprocessing ~range_checks:(idx, upper_bound) ~domain = + if Z.(log2up (of_int upper_bound)) <> Z.(log2 (of_int upper_bound)) then + failwith "upper_bound must be a power of two." ; + if idx = [] then SMap.empty + else + let domain_size = Domain.length domain in + let lnin1_poly = + Array.init domain_size (fun i -> + if i mod upper_bound = upper_bound - 1 then one else zero) + |> Evaluations.interpolation_fft2 domain + in + let pnin1_poly = compute_pnin1 upper_bound domain domain_size in + SMap.of_list [(lnin1, lnin1_poly); (pnin1, pnin1_poly)] + + let get_checks_from_wire k check_indices wire = + let checks = List.map (Evaluations.get wire) check_indices in + checks @ List.(init (k - length checks) (Fun.const Scalar.zero)) + + (* compute the evaluations of the Z polynomial for a scalar [x] with the bound [up] *) + let partial_z up x = + let x = Scalar.to_z x in + let rec aux gwi = function + | 1 -> gwi + | i -> + let q = Z.(div (List.hd gwi) (one + one)) in + aux (q :: gwi) (i - 1) + in + let res = aux [x] up in + res |> List.rev_map Scalar.of_z + + let build_z_evals domain up k check_indices values = + let checks = get_checks_from_wire k check_indices values in + let all_evals = List.concat_map (partial_z up) checks |> Array.of_list in + let evals = + Array.( + append + all_evals + (init + (Domain.length domain - length all_evals) + (Fun.const Scalar.zero))) + in + Evaluations.of_array (Array.length evals - 1, evals) + + let compute_Z domain up k check_indices values = + let evals = build_z_evals domain up k check_indices values in + (evals, Evaluations.interpolation_fft domain evals) + + let f_map_contribution ~range_checks:(check_indices, upper_bound) ~domain + ~values = + let wire = SMap.find wire values in + let nb_range_checks = List.length check_indices in + let k = Domain.length domain / upper_bound in + assert_not_too_many_checks k nb_range_checks ; + let evals, z = compute_Z domain upper_bound k check_indices wire in + (evals, SMap.of_list [(z_name, z)]) + + let prover_identities ~prefix_common ~prefix n = + let prefix_common = SMap.Aggregation.add_prefix prefix_common in + fun evaluations -> + let z_evaluation = + Evaluations.find_evaluation evaluations (prefix z_name) + in + let z_evaluation_len = Evaluations.length z_evaluation in + let tmp_evaluation = Evaluations.create z_evaluation_len in + let tmp2_evaluation = Evaluations.create z_evaluation_len in + let idrca_evaluation = Evaluations.create z_evaluation_len in + let idrcb_evaluation = Evaluations.create z_evaluation_len in + + (* Z × (1-Z) × Lnin1 *) + let identity_rca = + let lnin1_evaluation = + Evaluations.find_evaluation evaluations (prefix_common lnin1) + in + let one_m_z_evaluation = + Evaluations.linear_c + ~res:tmp_evaluation + ~linear_coeffs:[mone] + ~evaluations:[z_evaluation] + ~add_constant:one + () + in + Evaluations.mul_c + ~res:idrca_evaluation + ~evaluations:[z_evaluation; one_m_z_evaluation; lnin1_evaluation] + () + in + (* (Z - 2Zg) × (1 - Z + 2Zg) × Pnin1 *) + let identity_rcb = + let pnin1_evaluation = + Evaluations.find_evaluation evaluations (prefix_common pnin1) + in + let z_min_2Zg_evaluation = + Evaluations.linear_c + ~res:tmp_evaluation + ~linear_coeffs:[one; mtwo] + ~composition_gx:([0; 1], n) + ~evaluations:[z_evaluation; z_evaluation] + () + in + let one_m_Z_p_2Zg_evaluation = + Evaluations.linear_c + ~res:tmp2_evaluation + ~linear_coeffs:[mone] + ~evaluations:[z_min_2Zg_evaluation] + ~add_constant:one + () + in + Evaluations.mul_c + ~res:idrcb_evaluation + ~evaluations: + [z_min_2Zg_evaluation; one_m_Z_p_2Zg_evaluation; pnin1_evaluation] + () + in + SMap.of_list + [(prefix "RC.a", identity_rca); (prefix "RC.b", identity_rcb)] + + let verifier_identities ~prefix_common ~prefix = + let prefix_common = SMap.Aggregation.add_prefix prefix_common in + fun _x answers -> + let z = get_answer answers X (prefix z_name) in + let zg = get_answer answers GX (prefix z_name) in + let lnin1 = get_answer answers X (prefix_common lnin1) in + let pnin1 = get_answer answers X (prefix_common pnin1) in + let identity_rca = Scalar.(z * (one + negate z) * lnin1) in + let identity_rcb = + Scalar.((z + (mtwo * zg)) * (one + negate z + (two * zg)) * pnin1) + in + SMap.of_list + [(prefix "RC.a", identity_rca); (prefix "RC.b", identity_rcb)] + end + + let preprocessing ~permutation ~range_checks ~domain = + if fst range_checks = [] then SMap.empty + else + let rc = RangeChecks.preprocessing ~range_checks ~domain in + let perm = Permutation.preprocessing ~permutation ~domain in + SMap.union_disjoint rc perm + + let common_preprocessing () = SMap.empty + + let f_map_contribution ~permutation ~beta ~gamma ~domain ~range_checks + ~(values : Evaluations.t SMap.t) = + let values = SMap.singleton wire (SMap.find wire values) in + let z_evals, f_rc = + RangeChecks.f_map_contribution ~range_checks ~domain ~values + in + let f_perm = + Permutation.f_map_contribution + ~permutation + ~beta + ~gamma + ~domain + ~values:(SMap.add_unique z_name z_evals values) + in + SMap.union_disjoint f_rc f_perm + + let prover_identities ?(circuit_name = "") ~nb_proofs ~proof_idx ~beta ~gamma + ~domain_size () = + let proof_prefix = + SMap.Aggregation.add_prefix ~n:nb_proofs ~i:proof_idx "" + in + let prefix s = SMap.Aggregation.add_prefix circuit_name (proof_prefix s) in + let rc_ids = + RangeChecks.prover_identities + ~prefix_common:circuit_name + ~prefix + domain_size + in + let perm_ids = + Permutation.prover_identities + ~prefix_common:circuit_name + ~prefix:proof_prefix + ~beta + ~gamma + domain_size + in + Identities.merge_prover_identities [rc_ids; perm_ids] + + let verifier_identities ?(circuit_name = "") ~nb_proofs ~proof_idx ~beta + ~gamma ~domain_size ~generator () = + let proof_prefix = + SMap.Aggregation.add_prefix ~n:nb_proofs ~i:proof_idx "" + in + let prefix s = SMap.Aggregation.add_prefix circuit_name (proof_prefix s) in + let rc_ids = + RangeChecks.verifier_identities ~prefix_common:circuit_name ~prefix + in + let perm_ids = + Permutation.verifier_identities + ~prefix_common:circuit_name + ~prefix:proof_prefix + ~beta + ~gamma + domain_size + generator + in + Identities.merge_verifier_identities [rc_ids; perm_ids] +end + +module Range_check_gate (PP : Polynomial_protocol.S) : S with module PP = PP = + Range_check_gate_impl (PP) diff --git a/src/lib_plonk/sMap.ml b/src/lib_plonk/sMap.ml new file mode 100644 index 000000000000..439e41235be8 --- /dev/null +++ b/src/lib_plonk/sMap.ml @@ -0,0 +1,286 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module StringMap = struct + module M = Map.Make (String) + include M + + let of_list l = of_seq (List.to_seq l) + + let t (inner : 'a Repr.t) : 'a t Repr.t = + let module M = Repr.Of_map (struct + include M + + let key_t = Repr.string + end) in + M.t inner + + let keys t = bindings t |> List.map fst + + let values t = bindings t |> List.map snd + + let to_bytes printer map = + fold + (fun key elt state -> + Bytes.cat (Bytes.of_string key) (Bytes.cat (printer elt) state)) + map + Bytes.empty + + let show (show_inner : 'a -> string) : 'a t -> string = + fun m -> + "{\n" + ^ String.concat + "\n" + (List.map (fun (k, v) -> k ^ ": " ^ show_inner v) (bindings m)) + ^ "\n}" + + let add_unique k v m = + if mem k m then + raise + (Invalid_argument (Printf.sprintf "key %s already present in map." k)) + else add k v m + + (* Return the union of two maps. The keys of the maps have to be disjoint unless + specifically stated in common_keys. In this case both key's values + are asserted to be equal, with a given equality function. + If no equal function is given the polymorphic euqality is used.*) + let union_disjoint ?(common_keys_equal_elt = ([], ( = ))) x y = + let common_keys, equal_elt = common_keys_equal_elt in + union + (fun key elt_1 elt_2 -> + if not (List.mem key common_keys) then + raise + (Invalid_argument + (Printf.sprintf + "the key %s appears in both union arguments and does not \ + belong\n\ + \ to common_keys." + key)) + else if not (equal_elt elt_1 elt_2) then + raise + (Invalid_argument + (Printf.sprintf + "the key %s appears in both union argument with different \ + values" + key)) + else Some elt_1) + x + y + + (* applies union_disjoint on a list of map*) + let union_disjoint_list ?(common_keys_equal_elt = ([], ( = ))) map_list = + List.fold_left (union_disjoint ~common_keys_equal_elt) empty map_list + + (* given a list of maps outputs a single map with the union of all keys and + containing lists which consist of the concatenation of the data elements + under the same key (order is preserved) *) + let map_list_to_list_map map_list = + let join _key x y = Some (x @ y) in + List.fold_left + (fun list_map m -> union join list_map (map (fun x -> [x]) m)) + empty + map_list + + let sub_map sub_map map = + let res = filter (fun name _ -> mem name sub_map) map in + if cardinal res <> cardinal sub_map then + failwith "sub_map : first argument is not contained in the second." ; + res + + let two_maps_of_pair_map m = + fold + (fun k (v1, v2) (acc1, acc2) -> (add k v1 acc1, add k v2 acc2)) + m + (empty, empty) + + let update_keys f map = fold (fun k v acc -> add (f k) v acc) map empty + + module Aggregation = struct + (* separator between prefixes & name ; must be only one character *) + let sep = "~" + + let padded ~n i = + let str = string_of_int i in + let len = String.length (string_of_int (n - 1)) in + String.(make (len - length str) '0') ^ str + + let add_prefix ?(n = 1) ?(i = 0) ?(shift = 0) prefix str = + let prefix = if prefix = "" then "" else prefix ^ sep in + if n = 1 then prefix ^ str else prefix ^ padded ~n (i + shift) ^ sep ^ str + + let prefix_map ?n ?i ?shift prefix str_map = + fold (fun k -> add (add_prefix ?n ?i ?shift prefix k)) str_map empty + + (* This function will merge the maps of the list, by prefixing each key with it’s index in the list, optionnally with a shift, with the index prefix prefixed with zero to we able to handle [n] elements with the same prefix size ; if a [prefix] is given, it will be put before the index. + *) + let map_of_list_map ?(prefix = "") ?shift ?n list_map = + let n = match n with None -> List.length list_map | Some n -> n in + let shift = match shift with None -> 0 | Some shift -> shift in + List.mapi (fun i m -> prefix_map ~n ~i ~shift prefix m) list_map + |> union_disjoint_list + + let smap_of_smap_smap mapmap = + fold (fun prefix map res -> prefix_map prefix map :: res) mapmap [] + |> union_disjoint_list + + let gather_maps ?(shifts_map = empty) map_list_map = + mapi + (fun name list_map -> + let shift, n = + match find_opt name shifts_map with + | None -> (None, None) + | Some (shift, n) -> (Some shift, Some n) + in + map_of_list_map ?shift ?n list_map) + map_list_map + |> smap_of_smap_smap + + let filter_by_circuit_name circuit_name = + let sep_char = + assert (String.length sep = 1) ; + String.get sep 0 + in + filter (fun key _ -> + let name_parts = String.split_on_char sep_char key in + circuit_name = "" + || List.exists + (String.equal circuit_name) + (* we exclude the last element in [name_parts] *) + (List.rev name_parts |> List.tl)) + + let select_answers_by_circuit circuit_name = + map (filter_by_circuit_name circuit_name) + end +end + +module type S = sig + include Map.S with type key = string and type 'a t = 'a StringMap.t + + val t : 'a Repr.ty -> 'a t Repr.ty + + val of_list : (string * 'a) list -> 'a t + + val keys : 'a t -> string list + + val values : 'a t -> 'a list + + (* [add_unique k v map] adds [k -> v] to [map] & throw an error if [k] is + already in [map] + *) + val add_unique : key -> 'a -> 'a t -> 'a t + + val union_disjoint : + ?common_keys_equal_elt:string list * ('a -> 'a -> bool) -> + 'a t -> + 'a t -> + 'a t + + val union_disjoint_list : + ?common_keys_equal_elt:string list * ('a -> 'a -> bool) -> 'a t list -> 'a t + + val map_list_to_list_map : 'a t list -> 'a list t + + (* [sub_map m1 m2] returns m2 without the keys that do not appear in m1. + Raises failure if some key of m1 is not in m2 + *) + val sub_map : 'a t -> 'b t -> 'b t + + (* Splits a map of couple into a couple of maps *) + val two_maps_of_pair_map : ('a * 'b) t -> 'a t * 'b t + + (* USE WITH CAUTION : be sure your update function won’t create duplications *) + val update_keys : (key -> key) -> 'a t -> 'a t + + module Aggregation : sig + (* Separator for prefixing *) + val sep : string + + (* [add_prefix ~n ~i ~shift prefix str] return idx^prefix^sep^str + idx = [i] + [shift] as a string, eventually padded with '0' before to + allow a numbering until [n] with the same number of caracters + for instance, [prefix ~n:11 ~i:5 ~shift:1 "hello" "world"] will return + "06~hello~world" + *) + val add_prefix : + ?n:int -> ?i:int -> ?shift:int -> string -> string -> string + + (* adds prefix to each key of str_map ; [i] will be added as a string + before the prefix + For instance [prefix_map ~n:3000 ~i:5 ~shift:1 "hello" map] will prefix + all the keys of [map] with "0006~hello~" + *) + val prefix_map : ?n:int -> ?i:int -> ?shift:int -> string -> 'a t -> 'a t + + val map_of_list_map : + ?prefix:key -> ?shift:int -> ?n:int -> 'a t list -> 'a t + + (* "c1" -> {"a" ; "b"} ; "c2" -> {"a" ; "c"} becomes + {"c1~a" ; "c1~b" ; "c2~a" ; "c2~c"} with the same values *) + val smap_of_smap_smap : 'a t t -> 'a t + + (* Converts a map of list of map in a map, by merging each list of map in + one map, prefixing all keys with their proof index, and then merging all + the new maps into one prefixing the keys with the outside map’s keys. + shifts_maps map outside key to pairs of integers. + 'key1' -> (7, 20) means that 20 proofs will be produced for key1 in + total and we should start from the 8th one, assuming 7 of them were done + independently. (Note that we may not even finish the whole 20, this + depends on the map_list length). + For example, on input: + { 'circuit_foo' -> [ {'a' -> fa0; 'b' -> fb0; 'c' -> fc0}; + {'a' -> fa1; 'b' -> fb1; 'c' -> fc1} ]; + 'circuit_bar' -> [ {'a' -> ga0; 'b' -> gb0; 'c' -> gc0} ]; } + outputs + { 'circuit_foo~0~a' -> fa0; + 'circuit_foo~0~b' -> fb0 + 'circuit_foo~0~c' -> fc0 + 'circuit_foo~1~a' -> fa1 + 'circuit_foo~1~b' -> fb1 + 'circuit_foo~1~c' -> fc1 + 'circuit_bar~0~a' -> ga0 + 'circuit_bar~0~b' -> gb0 + 'circuit_bar~0~c' -> gc0 + } + *) + val gather_maps : ?shifts_map:(int * int) t -> 'a t list t -> 'a t + + (* Filter a map keeping the elements whose key corresponds to the given + circuit name *) + val filter_by_circuit_name : string -> 'a t -> 'a t + + (* [select_answers_by_circuit circuit_name s_map_map] takes a [circuit_name] + and a map with the structure: + { 'x' -> { 'circuit_foo~0~a' -> [scalar] ; + 'circuit_foo~0~b' -> [scalar] ; + ... + } + } + and filters the keys of the inner map, keeping the elements whose key + corresponds to the given circuit name. *) + val select_answers_by_circuit : string -> 'a t t -> 'a t t + end +end + +include (StringMap : S) diff --git a/src/lib_plonk/utils.ml b/src/lib_plonk/utils.ml new file mode 100644 index 000000000000..b7da05ae8e81 --- /dev/null +++ b/src/lib_plonk/utils.ml @@ -0,0 +1,210 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Hash : sig + type state + + val init : unit -> state + + val update : state -> bytes -> unit + + val finish : state -> bytes + + val hash_bytes : bytes list -> bytes + + val bytes_to_seed : bytes -> int array * bytes +end = struct + type state = Hacl_star.EverCrypt.Hash.t + + let init () = + Hacl_star.EverCrypt.Hash.init ~alg:Hacl_star.SharedDefs.HashDefs.BLAKE2b + + let update st msg = Hacl_star.EverCrypt.Hash.update ~st ~msg + + let finish st = Hacl_star.EverCrypt.Hash.finish ~st + + let hash_bytes bytes = + (* select the appropriate BLAKE2b function depending on platform and + * always produce a 32 byte digest *) + let blake2b msg = + let digest_size = 32 in + let open Hacl_star in + if AutoConfig2.(has_feature VEC256) then + Hacl.Blake2b_256.hash msg digest_size + else Hacl.Blake2b_32.hash msg digest_size + in + blake2b (Bytes.concat Bytes.empty bytes) + + (* generate a seed for Random.full_init from hash of b bytes + Also returns the hash of the bytes*) + let bytes_to_seed b = + let hashed_b = hash_bytes [b] in + assert (Bytes.length hashed_b = 32) ; + let sys_int_size = Sys.int_size - 1 in + let modulo = Z.pow (Z.of_int 2) sys_int_size in + (* seed generation based on four int, computed from hashed_b sub_byte ; + each ni is Bytes.sub hashed_b i 8 modulo 2**sys.int_size, in order to avoid + Z.Overflow when ni is converted to int *) + let n0_raw = Z.of_bits (Bytes.sub_string hashed_b 0 8) in + let n0 = Z.to_int (Z.erem n0_raw modulo) in + let n1_raw = Z.of_bits (Bytes.sub_string hashed_b 8 8) in + let n1 = Z.to_int (Z.erem n1_raw modulo) in + let n2_raw = Z.of_bits (Bytes.sub_string hashed_b 16 8) in + let n2 = Z.to_int (Z.erem n2_raw modulo) in + let n3_raw = Z.of_bits (Bytes.sub_string hashed_b 24 8) in + let n3 = Z.to_int (Z.erem n3_raw modulo) in + ([|n0; n1; n2; n3|], hashed_b) +end + +module Transcript = struct + (* expand a transcript with the elements of a list *) + let list_expand repr list transcript = + let open Hash in + let st = init () in + update st transcript ; + List.iter (fun a -> update st (Plompiler.Utils.to_bytes repr a)) list ; + finish st + + let expand : 'a Repr.t -> 'a -> bytes -> bytes = + fun repr x transcript -> list_expand repr [x] transcript +end + +module Array = struct + include Array + + (* Pad array to given size with the last element of the array *) + let pad array final_size = + let size = Array.length array in + Array.init final_size (fun i -> + if i < size then array.(i) else array.(size - 1)) + + (* Resize array: return the array, subarray or pad it with its last element *) + let resize array final_size = + let size = Array.length array in + if size = final_size then array + else if size > final_size then Array.sub array 0 final_size + else pad array final_size + + let build init next len = + let xi = ref init in + Array.init len (fun _ -> + let i = !xi in + xi := next !xi ; + i) +end + +module Fr_generation : sig + (* computes [| 1; x; x²; x³; ...; xᵈ⁻¹ |] *) + val powers : int -> Bls.Scalar.t -> Bls.Scalar.t array + + (* [batch x l] adds the elements of l scaled by ascending powers of x *) + val batch : Bls.Scalar.t -> Bls.Scalar.t list -> Bls.Scalar.t + + (* quadratic non-residues for Sid *) + val build_quadratic_non_residues : int -> Bls.Scalar.t array + + (* generate several scalars based on seed transcript *) + val random_fr_list : Bytes.t -> int -> Bls.Scalar.t list * Bytes.t + + (* generate a single scalars based on seed transcript *) + val random_fr : Bytes.t -> Bls.Scalar.t * Bytes.t + + (* Evaluates L1 on x, where L1 is the minimal (monic) polynomial that + satisfies L1(generator) = 1 and L1(generator^i) = 0 + for all i = 2, ..., domain_size. *) + val evaluate_l1 : + domain_size:int -> generator:Bls.Scalar.t -> Bls.Scalar.t -> Bls.Scalar.t + + (* Evaluates Ln_p_1 on x, where Ln_p_1 is the minimal (monic) polynomial that + satisfies Ln_p_1(1) = 1 and Ln_p_1(generator^i) = 0 + for all i = 1, ..., domain_size. *) + val evaluate_l0 : domain_size:int -> Bls.Scalar.t -> Bls.Scalar.t +end = struct + open Bls + + let powers d x = Array.build Scalar.one Scalar.(mul x) d + + let batch x l = + List.fold_left + (fun acc y -> Scalar.((x * acc) + y)) + Scalar.zero + (List.rev l) + + let build_quadratic_non_residues len = + let is_nonresidue n = Z.(equal (Scalar.legendre_symbol n) Z.(-one)) in + let rec next n = + Scalar.(n + one) |> fun n -> if is_nonresidue n then n else next n + in + Array.build Scalar.one next len + + (* a is the element to hash + * to_bytes_func, add, one is the function of conversion to_bytes, the function of addition, the one compatible with a type + * returns x ∈ F built from the hash of a + * if hash a not in F, returns hash (a+1) until its value belongs to F + *) + let rec hash_to_Fr a = + let b = Z.to_bits a |> Bytes.of_string in + let hashed_b = Hash.hash_bytes [b] in + assert (Bytes.length hashed_b = 32) ; + let x_fr = Scalar.of_bytes_opt hashed_b in + match x_fr with + | Some a -> a (* x_fr can be converted *) + | None -> hash_to_Fr (Z.succ a) + + let generate_random_fr ?state () = + (match state with None -> () | Some s -> Random.set_state s) ; + let n0 = Z.of_int64 @@ Random.int64 Int64.max_int in + let n1 = Z.of_int64 @@ Random.int64 Int64.max_int in + let n2 = Z.of_int64 @@ Random.int64 Int64.max_int in + let n3 = Z.of_int64 @@ Random.int64 Int64.max_int in + let n1_64 = Z.(n1 lsl 64) in + let n2_128 = Z.(n2 lsl 128) in + let n3_192 = Z.(n3 lsl 192) in + let gamma_z = Z.(n0 + n1_64 + n2_128 + n3_192) in + let gamma_fr = hash_to_Fr gamma_z in + gamma_fr + + (* generate nb_values scalar of Fr based on seed transcript *) + let random_fr_list transcript nb_values = + let transcript_array, hashed_transcript = Hash.bytes_to_seed transcript in + Random.full_init transcript_array ; + (List.init nb_values (fun _ -> generate_random_fr ()), hashed_transcript) + + let random_fr transcript = + let l, hashed_transcript = random_fr_list transcript 1 in + (List.hd l, hashed_transcript) + + let evaluate_l1 ~domain_size ~generator x = + let n = Z.of_int domain_size in + let l1_num = Scalar.(generator * sub (pow x n) one) in + let l1_den = Scalar.(of_z n * sub x generator) in + Scalar.div_exn l1_num l1_den + + let evaluate_l0 ~domain_size x = + let n = Z.of_int domain_size in + let l0_num = Scalar.(sub (pow x n) one) in + let l0_den = Scalar.(of_z n * sub x one) in + Scalar.div_exn l0_num l0_den +end diff --git a/src/lib_protocol_environment/dune b/src/lib_protocol_environment/dune index be936933add7..1ca6ff51f9f8 100644 --- a/src/lib_protocol_environment/dune +++ b/src/lib_protocol_environment/dune @@ -9,7 +9,7 @@ zarith zarith_stubs_js bls12-381 - tezos-plonk + octez-plonk tezos-crypto-dal class_group_vdf aches diff --git a/src/lib_protocol_environment/structs/dune b/src/lib_protocol_environment/structs/dune index 3613a738a540..8893e4b9cf64 100644 --- a/src/lib_protocol_environment/structs/dune +++ b/src/lib_protocol_environment/structs/dune @@ -12,4 +12,4 @@ tezos-scoru-wasm data-encoding bls12-381 - tezos-plonk)) + octez-plonk)) -- GitLab From 49ece782dbe138de2612f775f053196c0f3ca0da Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Fri, 17 Mar 2023 12:00:30 +0100 Subject: [PATCH 12/34] octez-plonk.aggregation: import from privacy-team/cryptography --- manifest/main.ml | 7 + src/lib_aplonk/plonk-aggregation/dune | 14 + .../plonk-aggregation/main_protocol.ml | 287 ++++++++++ src/lib_aplonk/plonk-aggregation/pack.ml | 490 ++++++++++++++++++ .../polynomial_commitment.ml | 285 ++++++++++ .../plonk-aggregation/polynomial_protocol.ml | 241 +++++++++ 6 files changed, 1324 insertions(+) create mode 100644 src/lib_aplonk/plonk-aggregation/dune create mode 100644 src/lib_aplonk/plonk-aggregation/main_protocol.ml create mode 100644 src/lib_aplonk/plonk-aggregation/pack.ml create mode 100644 src/lib_aplonk/plonk-aggregation/polynomial_commitment.ml create mode 100644 src/lib_aplonk/plonk-aggregation/polynomial_protocol.ml diff --git a/manifest/main.ml b/manifest/main.ml index b49d5269abc9..262532697eee 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1214,6 +1214,13 @@ let octez_plonk = (* ] *) (* ~modules:["helpers"; "cases"] *) +let octez_plonk_aggregation = + public_lib + "octez-plonk.aggregation" + ~path:"src/lib_aplonk/plonk-aggregation" + ~internal_name:"aggregation" + ~preprocess:[pps ppx_repr] + ~deps:[octez_plonk; octez_bls12_381_polynomial |> open_] let _octez_srs_extraction_tests = tests diff --git a/src/lib_aplonk/plonk-aggregation/dune b/src/lib_aplonk/plonk-aggregation/dune new file mode 100644 index 000000000000..76af7db5f4c8 --- /dev/null +++ b/src/lib_aplonk/plonk-aggregation/dune @@ -0,0 +1,14 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name aggregation) + (public_name octez-plonk.aggregation) + (instrumentation (backend bisect_ppx)) + (libraries + octez-plonk + octez-bls12-381-polynomial) + (preprocess (pps ppx_repr)) + (flags + (:standard) + -open Octez_bls12_381_polynomial)) diff --git a/src/lib_aplonk/plonk-aggregation/main_protocol.ml b/src/lib_aplonk/plonk-aggregation/main_protocol.ml new file mode 100644 index 000000000000..7cb17b7a6fd5 --- /dev/null +++ b/src/lib_aplonk/plonk-aggregation/main_protocol.ml @@ -0,0 +1,287 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk.Bls +open Plonk.Utils +module SMap = Plonk.SMap + +module type S = sig + module PP : Polynomial_protocol.S + + include Plonk.Main_protocol.S + + module Gates : Plonk.Custom_gates.S + + module Perm : Plonk.Permutation_gate.S with module PP := PP + + (** Returns (g, n), where n is the size of the circuit padded to the next + power of two & g is a primitive n-th root of unity + *) + val get_gen_n_prover : prover_public_parameters -> scalar * int + + (** Returns (g, n), where n is the size of the circuit padded to the next + power of two & g is a primitive n-th root of unity + *) + val get_gen_n_verifier : verifier_public_parameters -> scalar * int + + val filter_prv_pp_circuits : + prover_public_parameters -> 'a SMap.t -> prover_public_parameters + + val filter_vrf_pp_circuits : + verifier_public_parameters -> 'a SMap.t -> verifier_public_parameters + + (** Auxiliary information needed by the prover for the meta-verification in + aPlonK *) + type prover_aux = { + answers : scalar SMap.t SMap.t list; + batch : scalar SMap.t list; + alpha : scalar; + beta : scalar; + gamma : scalar; + delta : scalar; + x : scalar; + r : scalar; + cms_answers : PP.Answers_commitment.t SMap.t; + cms_pi : PP.Answers_commitment.t SMap.t; + ids_batch : (scalar * int) SMap.t; + t_answers : scalar list; + } + + (** Auxiliary information needed by the verifier for the meta-verification in + aPlonK *) + type verifier_aux = { + alpha : scalar; + beta : scalar; + gamma : scalar; + delta : scalar; + x : scalar; + r : scalar; + } + + type input_commit_info = { + nb_max_answers : int; + nb_max_pi : int; + func : ?size:int -> ?shift:int -> scalar array -> PP.Answers_commitment.t; + } + + val prove_list : + prover_public_parameters -> + input_commit_infos:input_commit_info SMap.t -> + inputs:prover_inputs -> + proof * prover_aux + + val verify_list : + verifier_public_parameters -> + proof + * scalar SMap.t list + * PP.Answers_commitment.public SMap.t + * PP.Answers_commitment.public SMap.t + * scalar list + * (scalar * int) SMap.t -> + bool * verifier_aux +end + +module Make_impl (Super_PP : Polynomial_protocol.S) = struct + include Plonk.Main_protocol.Make_impl (Super_PP) + module Input_commitment = Input_commitment + module PP = Super_PP + + type prover_aux = { + answers : scalar SMap.t SMap.t list; + batch : scalar SMap.t list; + alpha : scalar; + beta : scalar; + gamma : scalar; + delta : scalar; + x : scalar; + r : scalar; + cms_answers : PP.Answers_commitment.t SMap.t; + cms_pi : PP.Answers_commitment.t SMap.t; + ids_batch : (scalar * int) SMap.t; + t_answers : scalar list; + } + + type verifier_aux = { + alpha : scalar; + beta : scalar; + gamma : scalar; + delta : scalar; + x : scalar; + r : scalar; + } + + type input_commit_info = { + nb_max_answers : int; + nb_max_pi : int; + func : + ?size:int -> ?shift:int -> scalar array -> Super_PP.Answers_commitment.t; + } + + let hash_pi (pp : prover_public_parameters) ic_infos inputs = + (* TODO: can we commit only to the hidden pi?*) + let pi_infos = + SMap.mapi + (fun circuit_name inputs_list -> + let ic_info = SMap.find circuit_name ic_infos in + let c = SMap.find circuit_name pp.circuits_map in + let ic_size = List.fold_left ( + ) 0 c.input_com_sizes in + let pi = + List.map + (fun s -> Array.sub s.witness ic_size c.public_input_size) + inputs_list + in + (pi, ic_info.func ~size:ic_info.nb_max_pi @@ Array.concat pi)) + inputs + in + (SMap.map fst pi_infos, SMap.map snd pi_infos) + + let compute_ids_batch (pp : prover_public_parameters) rd alpha x + public_inputs_map answers cms_answers = + let n_gen = (pp.common_pp.n, Domain.get pp.common_pp.domain 1) in + let identities = + Verifier.build_identities + (SMap.map + Verifier.circuit_verifier_pp_of_circuit_prover_pp + pp.circuits_map) + n_gen + rd + public_inputs_map + in + let merged_answers = + let f _key m1 m2 = Some (SMap.union_disjoint m1 m2) in + List.fold_left (SMap.union f) SMap.empty answers + in + let evaluated_ids = identities x merged_answers in + SMap.mapi + (fun circuit_name _ -> + let ids = + SMap.Aggregation.filter_by_circuit_name circuit_name evaluated_ids + in + (Fr_generation.batch alpha (SMap.values ids), SMap.cardinal ids)) + (* we use cms_answers cause it contains the circuit_names *) + cms_answers + + let update_transcript_with_pi transcript cms_pi = + SMap.fold + (fun _ cm_pi transcript -> + PP.Answers_commitment.(Transcript.expand public_t cm_pi) transcript) + cms_pi + transcript + + let update_prv_pp_transcript_with_pi (pp : prover_public_parameters) cms_pi = + { + pp with + transcript = + update_transcript_with_pi + pp.transcript + (SMap.map PP.Answers_commitment.(fun a -> a.public) cms_pi); + } + + let commit_to_answers_map = + SMap.map (fun ic_info -> + ic_info.func ~shift:ic_info.nb_max_pi ~size:ic_info.nb_max_answers) + + let prove_list (pp : prover_public_parameters) ~input_commit_infos ~inputs = + let public_inputs_map, cms_pi = hash_pi pp input_commit_infos inputs in + (* add the PI in the transcript *) + let pp = update_prv_pp_transcript_with_pi pp cms_pi in + let commit_to_answers_map = commit_to_answers_map input_commit_infos in + let ( ( pp_proof, + Super_PP.{answers; batch; alpha; x; r; cms_answers; t_answers} ), + (perm_and_plook, wires_cm, rd) ) = + Prover.prove_parameters + ~pp_prove:(Super_PP.prove_super_aggregation ~commit_to_answers_map) + pp + ~inputs_map:inputs + in + let ids_batch = + compute_ids_batch pp rd alpha x public_inputs_map answers cms_answers + in + ( {perm_and_plook; wires_cm; pp_proof}, + { + answers; + batch; + alpha; + beta = rd.beta_perm; + gamma = rd.gamma_perm; + delta = rd.delta; + x; + r; + cms_answers; + cms_pi; + ids_batch; + t_answers; + } ) + + let verify_list pp (proof, s_list, cms_answers, cms_pi, t_answers, ids_batch) + = + (* add the PI in the transcript *) + let transcript = update_transcript_with_pi pp.transcript cms_pi in + let transcript, _, rd, commitments, eval_points = + (* Note that we don’t care about inputs here, because verify_parameters + only cares about input_coms & identities that we don’t have here *) + Verifier.verify_parameters + ((pp.common_pp, pp.circuits_map), transcript) + SMap.empty + proof + in + let (kzg_verif, Super_PP.{alpha; x; r}), _transcript = + Super_PP.verify_super_aggregation + pp.common_pp.pp_public_parameters + transcript + ~n:pp.common_pp.n + ~generator:pp.common_pp.generator + ~commitments + ~eval_points + ~s_list + ~cms_answers + ~t_answers + ~ids_batch + proof.pp_proof + in + ( kzg_verif, + { + alpha; + beta = rd.beta_perm; + gamma = rd.gamma_perm; + delta = rd.delta; + x; + r; + } ) + + let get_gen_n_prover (prover_public_params : prover_public_parameters) = + ( Domain.get prover_public_params.common_pp.domain 1, + prover_public_params.common_pp.n ) + + let get_gen_n_verifier (verifier_public_params : verifier_public_parameters) = + ( verifier_public_params.common_pp.generator, + verifier_public_params.common_pp.n ) +end + +module Make : functor (PP : Polynomial_protocol.S) -> + S with module PP = PP and type public_inputs = Scalar.t array list = + Make_impl + +include Make (Polynomial_protocol) diff --git a/src/lib_aplonk/plonk-aggregation/pack.ml b/src/lib_aplonk/plonk-aggregation/pack.ml new file mode 100644 index 000000000000..190138557743 --- /dev/null +++ b/src/lib_aplonk/plonk-aggregation/pack.ml @@ -0,0 +1,490 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk +open Utils + +(* Our version of SnarkPack for PLONK *) + +module type Aggregator = sig + (* Public parameters *) + type prover_public_parameters [@@deriving repr] + + type verifier_public_parameters [@@deriving repr] + + (* Data to be aggregated *) + type data = Bls.G1.t + + (* Commitment to the data *) + type commitment = {cmt_t : Bls.GT.t; cmt_len : int} [@@deriving repr] + + (* Randomness used to pack the data, usually derived from a commitment to it *) + type randomness = Bls.Scalar.t + + (* Packed/aggregated data *) + type packed = Bls.G1.t [@@deriving repr] + + (* Proof that the data was correctly aggregated *) + type proof [@@deriving repr] + + type transcript = Bytes.t + + type setup_params + + val setup : + int -> + Bls12_381_polynomial.Srs.t -> + prover_public_parameters * verifier_public_parameters + + val get_setup_params : prover_public_parameters -> setup_params + + val public_parameters_to_bytes : prover_public_parameters -> Bytes.t + + val commit : prover_public_parameters -> data array -> commitment + + val commitment_cardinal : commitment -> int + + val partial_commit : + relevant_positions:int list -> + prover_public_parameters -> + data array -> + commitment + + val empty_commitment : commitment + + val combine : commitment -> commitment -> commitment + + val prove_single : + prover_public_parameters -> + transcript -> + randomness -> + data array -> + (packed * proof) * transcript + + val prove : + prover_public_parameters -> + transcript -> + randomness -> + data array list -> + (packed list * proof) * transcript + + val verify_single : + verifier_public_parameters -> + transcript -> + commitment -> + randomness -> + packed * proof -> + bool * transcript + + val verify : + verifier_public_parameters -> + transcript -> + commitment list -> + randomness -> + packed list * proof -> + bool * transcript +end + +module Pack_impl = struct + open Bls + + type scalar = Scalar.t + + type g1 = G1.t + + type g2 = G2.t + + type gt = GT.t + + type prover_public_parameters = { + length : int; + srs2_t : G2.t array; + g1_t : G1.t; + } + [@@deriving repr] + + type verifier_public_parameters = G1.t [@@deriving repr] + + type data = G1.t + + type commitment = {cmt_t : GT.t; cmt_len : int} [@@deriving repr] + + type randomness = Scalar.t + + type packed = G1.t [@@deriving repr] + + type ipa_proof = { + t_Ls : GT.t array; + t_Rs : GT.t array; + r_Ls : G1.t array; + r_Rs : G1.t array; + a0 : G1.t; + t0 : G2.t; + } + [@@deriving repr] + + let empty_ipa_proof len = + { + t_Ls = Array.init len (fun _i -> GT.zero); + t_Rs = Array.init len (fun _i -> GT.zero); + r_Ls = Array.init len (fun _i -> G1.zero); + r_Rs = Array.init len (fun _i -> G1.zero); + a0 = G1.zero; + t0 = G2.zero; + } + + type kzg_proof = G2.t [@@deriving repr] + + type proof = ipa_proof * kzg_proof [@@deriving repr] + + type transcript = Bytes.t + + type setup_params = int + + let hash ~transcript ~random ?(g1s = [[||]]) ?(g2s = [[||]]) ?(gts = [[||]]) + ?(scalars = [[||]]) () = + let transcript = + let open Utils.Hash in + let st = init () in + update st transcript ; + List.iter (Array.iter (fun key -> update st (G1.to_bytes key))) g1s ; + List.iter (Array.iter (fun key -> update st (G2.to_bytes key))) g2s ; + List.iter (Array.iter (fun key -> update st (GT.to_bytes key))) gts ; + List.iter + (Array.iter (fun key -> update st (Scalar.to_bytes key))) + scalars ; + finish st + in + let seed, _ = Utils.Hash.bytes_to_seed transcript in + let state = Some (Random.State.make seed) in + (random ?state (), transcript) + + let ip_pairing array1 array2 = + if Array.length array1 = 0 then GT.zero + else + let min_length = min (Array.length array1) (Array.length array2) in + let list_combined = + List.init min_length (fun i -> (array1.(i), array2.(i))) + in + Pairing.(miller_loop list_combined |> final_exponentiation_exn) + + let setup_verifier srs_g1_t = Srs_g1.get srs_g1_t 1 + + let setup_prover d (srs_g1_t, srs_g2_t) = + let srs2_t = Srs_g2.to_array ~len:d srs_g2_t in + let g1_t = setup_verifier srs_g1_t in + {length = d; srs2_t; g1_t} + + let setup d srs_t = + let prv = setup_prover d srs_t in + let vrf = setup_verifier (fst srs_t) in + (prv, vrf) + + let get_setup_params public_parameters = public_parameters.length + + let public_parameters_to_bytes {srs2_t; g1_t; _} = + hash + ~transcript:Bytes.empty + ~random:Scalar.random + ~g1s:[[|g1_t|]] + ~g2s:[srs2_t] + () + |> fst |> Scalar.to_bytes + + let commit pp data = + {cmt_t = ip_pairing data pp.srs2_t; cmt_len = Array.length data} + + let commitment_cardinal cmt = cmt.cmt_len + + let partial_commit ~relevant_positions pp data = + let filter_srs : G2.t array -> G2.t array = + let module ISet = Set.Make (Int) in + let pos_set = ISet.of_list relevant_positions in + fun srs -> + List.filteri (fun i _proof -> ISet.mem i pos_set) (Array.to_list srs) + |> Array.of_list + in + { + cmt_t = ip_pairing data (filter_srs pp.srs2_t); + cmt_len = Array.length data; + } + + let bytes_of_commitment cmt = + Bytes.cat + (Bytes.of_string (string_of_int cmt.cmt_len)) + (GT.to_bytes cmt.cmt_t) + + let empty_commitment = {cmt_t = GT.zero; cmt_len = 0} + + let combine c0 c1 = + let cmt_t = GT.add c0.cmt_t c1.cmt_t in + let cmt_len = Int.add c0.cmt_len c1.cmt_len in + {cmt_t; cmt_len} + + let pack rs data = + if Array.length data = 0 then G1.zero + else + (* rs can be longer than needed *) + let rs = Array.sub rs 0 (Array.length data) in + let packed = G1.pippenger data rs in + packed + + let array_split_in_half a = + let len = Array.length a in + let len2 = len / 2 in + match len mod 2 with + | 0 -> (Array.sub a 0 len2, Array.sub a len2 len2) + | _ -> + raise + (Invalid_argument + (Printf.sprintf "split_in_half: length %d not even." len)) + + let array_padded_with_zero src dst_len zero = + let src_len = Array.length src in + assert (src_len <= dst_len) ; + if src_len = dst_len then src + else + let dst = Array.init dst_len (fun _i -> zero) in + Array.blit src 0 dst 0 src_len ; + dst + + let prove_but_not_pack pp transcript r data packed = + (* Assert that the data length is a power of 2 *) + let data_length = Array.length data in + if data_length = 0 then + raise @@ Invalid_argument "[Array.length data] cannot be 0" ; + let nb_iter = Z.(log2up @@ of_int data_length) in + let next_2power = Int.shift_left 1 nb_iter in + let diff_from_2power = next_2power - data_length in + let data = + if diff_from_2power = 0 then data + else ( + Format.printf + "\nWARNING: [Array.length data] is %d, not a power of 2, we pad it\n" + data_length ; + array_padded_with_zero data next_2power G1.zero) + in + let data_length = next_2power in + let rs = Fr_generation.powers data_length r in + let transcript = Bytes.cat transcript @@ G1.to_bytes packed in + + let rec loop transcript g_poly ipa_proof a b t i = + if i = nb_iter then + match (a, b, t) with + | [|a0|], [|_|], [|t0|] -> (g_poly, {ipa_proof with a0; t0}, transcript) + | _ -> raise @@ Invalid_argument "Aggregation: IPA loop" + else + let a_left, a_right = array_split_in_half a in + let b_left, b_right = array_split_in_half b in + let t_left, t_right = array_split_in_half t in + + let t_L = ip_pairing a_left t_right in + let t_R = ip_pairing a_right t_left in + + let r_L = G1.pippenger a_left b_right in + let r_R = G1.pippenger a_right b_left in + + let u, transcript = + let g1s = [[|r_L; r_R|]] in + let gts = [[|t_L; t_R|]] in + Scalar.(hash ~transcript ~random ~g1s ~gts ()) + in + let u_inv = Scalar.inverse_exn u in + + let merge ~add ~mul x y = add (mul x u) (mul y u_inv) in + let a' = Array.map2 G1.(merge ~add ~mul) a_left a_right in + let b' = Array.map2 Scalar.(merge ~add ~mul) b_right b_left in + let t' = Array.map2 G2.(merge ~add ~mul) t_right t_left in + + ipa_proof.t_Ls.(i) <- t_L ; + ipa_proof.t_Rs.(i) <- t_R ; + ipa_proof.r_Ls.(i) <- r_L ; + ipa_proof.r_Rs.(i) <- r_R ; + + let xn = Int.shift_left 1 (nb_iter - 1 - i) in + let g'_poly = Poly.(g_poly * of_coefficients [(u_inv, 0); (u, xn)]) in + + loop transcript g'_poly ipa_proof a' b' t' (i + 1) + in + + let srs2_t = Array.sub pp.srs2_t 0 data_length in + let g, ipa_proof, transcript = + loop transcript Poly.one (empty_ipa_proof nb_iter) data rs srs2_t 0 + in + + let gts = [ipa_proof.t_Ls; ipa_proof.t_Rs] in + let g1s = [[|ipa_proof.a0|]; ipa_proof.r_Ls; ipa_proof.r_Rs] in + let g2s = [[|ipa_proof.t0|]] in + let rho, transcript = Scalar.(hash ~transcript ~random ~g1s ~g2s ~gts ()) in + let h = + fst + @@ Poly.( + division_xn (g - (constant @@ evaluate g rho)) 1 (Scalar.negate rho)) + in + let h_coeffs = Poly.to_dense_coefficients h in + let kzg_proof_t = G2.pippenger srs2_t h_coeffs in + + let proof = (ipa_proof, kzg_proof_t) in + (proof, transcript) + + let prove_single pp transcript r data = + let rs = Fr_generation.powers (Array.length data) r in + let packed = pack rs data in + let proof, transcript = prove_but_not_pack pp transcript r data packed in + ((packed, proof), transcript) + + let prove pp transcript r data_list = + let n = List.length data_list in + if n = 0 then raise @@ Failure "data_list cannot be empty" ; + + let max_length_datas = + List.fold_left max 0 @@ List.map Array.length data_list + in + + (* Pad with zeros at the tail so that all datas have the same length *) + let padded_datas = + List.map + (fun l -> array_padded_with_zero l max_length_datas G1.zero) + data_list + in + let delta, transcript = Scalar.(hash ~transcript ~random ()) in + let deltas = Fr_generation.powers n delta |> Array.to_list in + let data = + (* data = delta^0·padded_datas.(0) +...+ delta^(n-1)·padded_datas.(n-1) *) + let safe_tl = function _ :: tl -> tl | _ -> [] in + List.fold_left2 + (fun acc padded_data d -> + Array.map2 (fun a b -> G1.(add a (mul b d))) acc padded_data) + (List.hd padded_datas) + (safe_tl padded_datas) + (safe_tl deltas) + in + let rs = Fr_generation.powers max_length_datas r in + let packed = pack rs data in + let packed_list = List.map (pack rs) data_list in + let proof, transcript = prove_but_not_pack pp transcript r data packed in + ((packed_list, proof), transcript) + + let verify_single pp transcript cmt r (packed, (ipa_proof, kzg_proof)) = + let transcript = Bytes.cat transcript @@ G1.to_bytes packed in + (* FIXME: assert that the length of these six arrays (or at least one of them) + equals the log2 of cmt.cmt_len *) + let us, transcript = + let len = Array.length ipa_proof.t_Ls in + let us = Array.init len (fun _i -> Scalar.zero) in + let transcript_i = ref transcript in + for i = 0 to len - 1 do + let u, transcript = + let g1s = [[|ipa_proof.r_Ls.(i); ipa_proof.r_Rs.(i)|]] in + let gts = [[|ipa_proof.t_Ls.(i); ipa_proof.t_Rs.(i)|]] in + Scalar.(hash ~transcript:!transcript_i ~random ~g1s ~gts ()) + in + us.(i) <- u ; + transcript_i := transcript + done ; + (us, !transcript_i) + in + + (* g(X) := (u₁⁻¹ + u₁ X^{2ᵏ⁻¹}) · (u₂⁻¹ + u₂ X^{2ᵏ⁻²}) ··· (uₖ⁻¹ + uₖ X) *) + let eval_g x = + let len = Array.length us in + let acc = ref Scalar.one in + let x_power = ref x in + for i = 0 to len - 1 do + let u = us.(len - 1 - i) in + let term = Scalar.(inverse_exn u + (u * !x_power)) in + acc := Scalar.mul !acc term ; + x_power := Scalar.square !x_power + done ; + !acc + in + + (* Verify the IPA proof *) + let r0 = eval_g r in + + (* Computes [init + sum_j (u_j^2 L_j + u_j^{-2} R_j)] *) + let rhs ~init ~add ~mul us gLs gRs = + let len = Array.length us in + let acc = ref init in + for i = 0 to len - 1 do + let u2 = Scalar.square us.(i) in + let u2_inv = Scalar.inverse_exn u2 in + acc := add !acc @@ add (mul gLs.(i) u2) (mul gRs.(i) u2_inv) + done ; + !acc + in + + let lhs_t = Pairing.pairing ipa_proof.a0 ipa_proof.t0 in + let rhs_t = + GT.(rhs ~init:cmt.cmt_t ~add ~mul us ipa_proof.t_Ls ipa_proof.t_Rs) + in + + let lhs_r = G1.mul ipa_proof.a0 r0 in + let rhs_r = + G1.(rhs ~init:packed ~add ~mul us ipa_proof.r_Ls ipa_proof.r_Rs) + in + + let ipa_ok = GT.eq lhs_t rhs_t && G1.eq lhs_r rhs_r in + + (* Verify the KZG proof *) + let gts = [ipa_proof.t_Ls; ipa_proof.t_Rs] in + let g1s = [[|ipa_proof.a0|]; ipa_proof.r_Ls; ipa_proof.r_Rs] in + let g2s = [[|ipa_proof.t0|]] in + let rho, transcript = Scalar.(hash ~transcript ~random ~g1s ~g2s ~gts ()) in + let m_v = eval_g rho |> Scalar.negate |> G2.(mul one) in + let st0 = ipa_proof.t0 in + let rho_g1 = G1.mul G1.one @@ Scalar.negate rho in + + let rhs = + ip_pairing G1.[|negate one; add pp rho_g1|] G2.[|add st0 m_v; kzg_proof|] + in + let kzg_ok = GT.is_zero rhs in + + (ipa_ok && kzg_ok, transcript) + + let verify pp transcript cmt_list r (packed_list, proof) = + let delta, transcript = Scalar.(hash ~transcript ~random ()) in + + let combine_cmt d c1 c2 = + { + cmt_t = GT.add c1.cmt_t (GT.mul c2.cmt_t d); + cmt_len = max c1.cmt_len c2.cmt_len; + } + in + + let combine_packed d p1 p2 = G1.add p1 (G1.mul p2 d) in + + let cmt, packed, _ = + List.fold_left2 + (fun (cmt, packed, d) c p -> + (combine_cmt d cmt c, combine_packed d packed p, Scalar.mul d delta)) + ({cmt_t = GT.zero; cmt_len = 0}, G1.zero, Scalar.one) + cmt_list + packed_list + in + verify_single pp transcript cmt r (packed, proof) +end + +include (Pack_impl : Aggregator) diff --git a/src/lib_aplonk/plonk-aggregation/polynomial_commitment.ml b/src/lib_aplonk/plonk-aggregation/polynomial_commitment.ml new file mode 100644 index 000000000000..7d1c8e90c257 --- /dev/null +++ b/src/lib_aplonk/plonk-aggregation/polynomial_commitment.ml @@ -0,0 +1,285 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk +open Bls +open Utils + +module type S = sig + include Polynomial_commitment.S + + (** Auxiliary information needed by the prover for the meta-verification in + aPlonK *) + type prover_aux = {r : Scalar.t; s_list : Scalar.t SMap.t list} + + val prove_super_aggregation : + Public_parameters.prover -> + transcript -> + Poly.t SMap.t list -> + Commitment.prover_aux list -> + query list -> + Scalar.t SMap.t SMap.t list -> + (proof * prover_aux) * transcript + + val verify_super_aggregation : + Public_parameters.verifier -> + transcript -> + Commitment.t list -> + query list -> + Scalar.t SMap.t list -> + proof -> + bool * Scalar.t * transcript +end + +module Make_impl + (PC : Polynomial_commitment.S with type Commitment.t = Bls.G1.t SMap.t) = +struct + type secret = PC.secret + + type query = PC.query [@@deriving repr] + + type answer = PC.answer [@@deriving repr] + + type transcript = PC.transcript + + module Public_parameters = struct + type prover = { + pp_pc_prover : PC.Public_parameters.prover; + pp_pack_prover : Pack.prover_public_parameters; + } + [@@deriving repr] + + type verifier = { + pp_pc_verifier : PC.Public_parameters.verifier; + pp_pack_verifier : Pack.verifier_public_parameters; + } + [@@deriving repr] + + type setup_params = int + + let setup setup_params srs = + let pp_pc_prover, pp_pc_verifier = + PC.Public_parameters.setup setup_params srs + in + let pp_pack_prover, pp_pack_verifier = + Pack.setup setup_params (snd srs) + in + let pp_prover = {pp_pc_prover; pp_pack_prover} in + let pp_verifier = {pp_pc_verifier; pp_pack_verifier} in + (pp_prover, pp_verifier) + + let to_bytes d ({pp_pc_prover; pp_pack_prover} : prover) = + Utils.Hash.hash_bytes + [ + PC.Public_parameters.to_bytes d pp_pc_prover; + Pack.public_parameters_to_bytes pp_pack_prover; + ] + end + + module Commitment = struct + type prover_public_parameters = Public_parameters.prover + + type secret = Poly.t SMap.t + + type t = Pack.commitment [@@deriving repr] + + (* [PC.Commitment.t] is required to be [Bls12_381.G1.t SMap.t], + containing all the commitments that were packed *) + type prover_aux = PC.Commitment.t * PC.Commitment.prover_aux + [@@deriving repr] + + let commit ?all_keys (pp : Public_parameters.prover) f_map = + (* Relevant_positions is the list of the indexes of f_map’s elements in the all_keys list. *) + let relevant_positions = + match all_keys with + | None -> List.init (SMap.cardinal f_map) Fun.id + | Some ks -> + List.mapi (fun i x -> (i, x)) ks + |> List.filter_map (fun (i, x) -> + Option.map (Fun.const i) (SMap.find_opt x f_map)) + in + let prover_aux = PC.Commitment.commit pp.pp_pc_prover f_map in + let cm_list = SMap.values (fst prover_aux) in + let pack_cmt = + Pack.partial_commit + ~relevant_positions + pp.pp_pack_prover + (Array.of_list cm_list) + in + (pack_cmt, prover_aux) + + let cardinal = Pack.commitment_cardinal + + let rename _f cmt = cmt + end + + type proof = { + pc_proof : PC.proof; + packed_values : Pack.packed list; + pack_proof : Pack.proof; + } + [@@deriving repr] + + type prover_aux = {r : Scalar.t; s_list : Scalar.t SMap.t list} + + let batch_polys r map = + let polys = SMap.values map in + Poly.linear_with_powers polys r + + let batch_answers r = + SMap.map (fun m -> Fr_generation.batch r @@ SMap.values m) + + let evaluate = PC.evaluate + + (* compute P := cmt₀ + r cmt₁ + r² cmt₂ + ... for every group of commitments + in the list [prover_aux_list], and common randomness r (freshly sampled); + such P values are returned as [packed_values], together with a proof + [packed_proof] of their correctness; + also, on input a list of evaluations [answer_list], at the requested points + in [query_list], produce a proof of their validity: such proof is a PC + proof (for every group) on the aggregatted commitment P with respect to the + corresponding aggregated evaluations (we thus batch [answer_list] with [r] + similarly) *) + let prove_pack (pp : Public_parameters.prover) transcript f_map_list + (prover_aux_list : Commitment.prover_aux list) query_list answer_list = + let r, transcript = Fr_generation.random_fr transcript in + let f_list = List.map (batch_polys r) f_map_list in + let s_list = List.map (batch_answers r) answer_list in + (* [cmts_list] is a list of G1.t SMap.t, containing the PC commitments to + every polynomial (note that PC.Commitment.t = Bls12_381.G1.t SMap.t) *) + let cmts_list = + List.map + (fun (cmts, _prover_aux) -> SMap.values cmts |> Array.of_list) + prover_aux_list + in + (* [packed_values] has type [G1.t list] and it is the result of batching + each map in [cmt_list] with powers of [r]. + [pack_proof] asserts that [packed_values] was correctly computed. *) + let (packed_values, pack_proof), transcript = + Pack.prove pp.pp_pack_prover transcript r cmts_list + in + (* prepare [f_list] and [s_list], the batched version of [f_map_list] + polys and [answer_list] (using randomness [r]) by selecting a dummy + name for them [string_of_int i] in order to call the underlying PC *) + let f_map_list = + List.mapi (fun i l -> SMap.singleton (string_of_int i) l) f_list + in + let s_map_list = + List.mapi + (fun i m -> SMap.map (fun s -> SMap.singleton (string_of_int i) s) m) + s_list + in + let prover_aux_list = List.map snd prover_aux_list in + (* call the underlying PC prover on the batched polynomials/evaluations + the verifier will verify such proof using [packed_values] as the + commitments *) + let pc_proof, transcript = + PC.prove + pp.pp_pc_prover + transcript + f_map_list + prover_aux_list + query_list + s_map_list + in + let proof = {pc_proof; packed_values; pack_proof} in + let transcript = Transcript.expand proof_t proof transcript in + ((proof, {r; s_list}), transcript) + + let prove (pp : Public_parameters.prover) transcript f_map_list + (prover_aux_list : Commitment.prover_aux list) query_list answer_list = + let transcript = Transcript.list_expand query_t query_list transcript in + let transcript = Transcript.list_expand answer_t answer_list transcript in + let (proof, _), transcript = + prove_pack pp transcript f_map_list prover_aux_list query_list answer_list + in + (proof, transcript) + + let prove_super_aggregation (pp : Public_parameters.prover) transcript + f_map_list (prover_aux_list : Commitment.prover_aux list) query_list + answer_list = + let transcript = Transcript.list_expand query_t query_list transcript in + prove_pack pp transcript f_map_list prover_aux_list query_list answer_list + + let verify_pack (pp : Public_parameters.verifier) r transcript cmt_list + query_list s_list proof = + (* verify that the [packed_values] are correct, they will be used as + the commitments for the PC proof of (batched) evaluations *) + let pack_ok, transcript = + Pack.verify + pp.pp_pack_verifier + transcript + cmt_list + r + (proof.packed_values, proof.pack_proof) + in + (* batch the evaluations using [r] and prepare the query to the PC verifier + by selecting the default dummy names [string_of_int i] names *) + let s_map_list = + List.mapi + (fun i m -> SMap.map (fun s -> SMap.singleton (string_of_int i) s) m) + s_list + in + let cmt_map_list = + List.mapi + (fun i l -> SMap.singleton (string_of_int i) l) + proof.packed_values + in + (* verify that the batched evaluations are correct *) + let pc_ok, transcript = + PC.verify + pp.pp_pc_verifier + transcript + cmt_map_list + query_list + s_map_list + proof.pc_proof + in + (pack_ok && pc_ok, Transcript.expand proof_t proof transcript) + + let verify (pp : Public_parameters.verifier) transcript cmt_list query_list + s_map_list proof = + let transcript = Transcript.list_expand query_t query_list transcript in + let transcript = Transcript.list_expand answer_t s_map_list transcript in + let r, transcript = Fr_generation.random_fr transcript in + let s_list = List.map (batch_answers r) s_map_list in + verify_pack pp r transcript cmt_list query_list s_list proof + + let verify_super_aggregation (pp : Public_parameters.verifier) transcript + cmt_list query_list s_list proof = + let transcript = Transcript.list_expand query_t query_list transcript in + let r, transcript = Fr_generation.random_fr transcript in + let ok, transcript = + verify_pack pp r transcript cmt_list query_list s_list proof + in + (ok, r, transcript) +end + +module Make : functor + (PC : Polynomial_commitment.S with type Commitment.t = Bls.G1.t SMap.t) + -> S = + Make_impl + +include Make (Polynomial_commitment.Kzg_impl) diff --git a/src/lib_aplonk/plonk-aggregation/polynomial_protocol.ml b/src/lib_aplonk/plonk-aggregation/polynomial_protocol.ml new file mode 100644 index 000000000000..e30459668bbc --- /dev/null +++ b/src/lib_aplonk/plonk-aggregation/polynomial_protocol.ml @@ -0,0 +1,241 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk.Bls +open Plonk.Utils +open Plonk.Identities +module SMap = Plonk.SMap + +module type S = sig + module PC : Polynomial_commitment.S + + module Answers_commitment : Plonk.Input_commitment.S + + include Plonk.Polynomial_protocol.S with module PC := PC + + (** Auxiliary information needed by the prover for the meta-verification in + aPlonK *) + type prover_aux = { + answers : Scalar.t SMap.t SMap.t list; + batch : Scalar.t SMap.t list; + alpha : Scalar.t; + x : Scalar.t; + r : Scalar.t; + cms_answers : Answers_commitment.t SMap.t; + t_answers : Scalar.t list; + } + + (** Auxiliary information needed by the verifier for the meta-verification in + aPlonK *) + type verifier_aux = {alpha : Scalar.t; x : Scalar.t; r : Scalar.t} + + val update_transcript_with_formatted_answers : + transcript -> + (Poly.scalar array -> Answers_commitment.t) SMap.t -> + Poly.scalar SMap.t SMap.t list -> + Poly.scalar list * Answers_commitment.t SMap.t * transcript + + val prove_super_aggregation : + prover_public_parameters -> + transcript -> + commit_to_answers_map:(Scalar.t array -> Answers_commitment.t) SMap.t -> + n:int -> + generator:Scalar.t -> + secrets:(Poly.t SMap.t * PC.Commitment.prover_aux) list -> + eval_points:eval_point list list -> + evaluations:Evaluations.t SMap.t -> + identities:prover_identities -> + nb_of_t_chunks:int -> + (proof * prover_aux) * transcript + + val verify_super_aggregation : + verifier_public_parameters -> + transcript -> + n:int -> + generator:Scalar.t -> + commitments:PC.Commitment.t list -> + eval_points:eval_point list list -> + s_list:Scalar.t SMap.t list -> + cms_answers:Answers_commitment.public SMap.t -> + t_answers:Scalar.t list -> + ids_batch:(Scalar.t * int) SMap.t -> + proof -> + (bool * verifier_aux) * PC.transcript +end + +module Make_impl + (Super_PC : Polynomial_commitment.S) + (Answers_commitment : Plonk.Input_commitment.S) = +struct + include Plonk.Polynomial_protocol.Make_impl (Super_PC) + module PC = Super_PC + module Answers_commitment = Answers_commitment + + type prover_aux = { + answers : Scalar.t SMap.t SMap.t list; + batch : Scalar.t SMap.t list; + alpha : Scalar.t; + x : Scalar.t; + r : Scalar.t; + cms_answers : Answers_commitment.t SMap.t; + t_answers : Scalar.t list; + } + + type verifier_aux = {alpha : Scalar.t; x : Scalar.t; r : Scalar.t} + + (* Expand the transcript with all answers. Circuit answers are involved + in commiment form, whereas t_answers are included in the clear, given + that they are exposed in the proof *) + let update_transcript_with_answers transcript cms_answers t_answers = + SMap.fold + (fun circuit_name cm_answers transcript -> + transcript + |> Transcript.expand Repr.string circuit_name + |> Transcript.expand Answers_commitment.public_t cm_answers) + cms_answers + transcript + |> Transcript.expand (Repr.list Scalar.t) t_answers + + let verify_t ~n ~x ~alpha ~t_answers ~ids_batch = + let sum_ids, _ = + SMap.fold + (fun _ (id_batch, size) (acc, acc_alpha) -> + Scalar. + (acc + (id_batch * acc_alpha), acc_alpha * pow alpha (Z.of_int size))) + ids_batch + (Scalar.zero, Scalar.one) + in + verify_t n x sum_ids t_answers + + let update_transcript_with_formatted_answers transcript cm_to_answers_map + answer_list = + let t_answers, circuit_answers = + (List.hd answer_list, List.tl answer_list) + in + let t_answers = t_answers |> SMap.values |> List.concat_map SMap.values in + let cms_answers = + let flatten_circuit_answers circuit_answers = + circuit_answers + |> List.concat_map SMap.values + |> List.concat_map SMap.values + |> Array.of_list + in + SMap.mapi + (fun circuit_name commit -> + List.map + (SMap.Aggregation.select_answers_by_circuit circuit_name) + circuit_answers + |> flatten_circuit_answers |> commit) + cm_to_answers_map + in + (* We treat t answers as Public inputs instead of through the + input_commitment because they are not circuit-specific *) + let transcript = + update_transcript_with_answers + transcript + (SMap.map Answers_commitment.(fun a -> a.public) cms_answers) + t_answers + in + (t_answers, cms_answers, transcript) + + let prove_super_aggregation pc_public_parameters transcript + ~commit_to_answers_map ~n ~generator ~secrets ~eval_points ~evaluations + ~identities ~nb_of_t_chunks = + let ( (alpha, x, answer_list, cm_t), + polys_list, + prover_aux_list, + query_list, + transcript ) = + prove_aux + pc_public_parameters + transcript + n + generator + secrets + eval_points + evaluations + identities + nb_of_t_chunks + in + let t_answers, cms_answers, transcript = + update_transcript_with_formatted_answers + transcript + commit_to_answers_map + answer_list + in + let (pc_proof, Super_PC.{r; s_list}), transcript = + Super_PC.prove_super_aggregation + pc_public_parameters + transcript + polys_list + prover_aux_list + query_list + answer_list + in + ( ( {cm_t; pc_proof; pc_answers = []}, + { + answers = answer_list; + cms_answers; + batch = s_list; + alpha; + x; + r; + t_answers; + } ), + transcript ) + + let verify_super_aggregation pc_public_parameters transcript ~n ~generator + ~commitments ~eval_points ~s_list ~cms_answers ~t_answers ~ids_batch proof + = + let alpha, x, transcript, cmts, query_list = + verify_aux transcript generator commitments eval_points proof + in + let transcript = + update_transcript_with_answers transcript cms_answers t_answers + in + (* Step 2a: KZG.verify proofs for witness combinations *) + let pc_verif, r, transcript = + Super_PC.verify_super_aggregation + pc_public_parameters + transcript + cmts + query_list + s_list + proof.pc_proof + in + let pp_verif = verify_t ~n ~x ~alpha ~t_answers ~ids_batch in + ((pc_verif && pp_verif, {alpha; x; r}), transcript) +end + +module Make_aggregation : functor + (PC : Polynomial_commitment.S) + (Answers_commitment : Plonk.Input_commitment.S) + -> + S with module Answers_commitment = Answers_commitment with module PC = PC = + Make_impl + +module KZG_Answers_commitment = + Plonk.Input_commitment.Make (Plonk.Polynomial_commitment.Commitment) +include Make_aggregation (Polynomial_commitment) (KZG_Answers_commitment) -- GitLab From 6df6da0f2ef8d5b33109de71b379497bd124e9a3 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Tue, 14 Mar 2023 13:43:30 +0100 Subject: [PATCH 13/34] octez-aplonk: import from privacy-team/cryptography --- .gitlab/ci/jobs/packaging/opam_package.yml | 2 + dune-project | 1 + manifest/main.ml | 11 + opam/octez-aplonk.opam | 21 + src/lib_aplonk/README.md | 7 + src/lib_aplonk/circuit.ml | 713 +++++++++++++++++++++ src/lib_aplonk/dune | 10 + src/lib_aplonk/main_protocol.ml | 514 +++++++++++++++ src/lib_aplonk/pi_parameters.ml | 103 +++ 9 files changed, 1382 insertions(+) create mode 100644 opam/octez-aplonk.opam create mode 100644 src/lib_aplonk/README.md create mode 100644 src/lib_aplonk/circuit.ml create mode 100644 src/lib_aplonk/dune create mode 100644 src/lib_aplonk/main_protocol.ml create mode 100644 src/lib_aplonk/pi_parameters.ml diff --git a/.gitlab/ci/jobs/packaging/opam_package.yml b/.gitlab/ci/jobs/packaging/opam_package.yml index 7601aed1f59e..86fcd74a9508 100644 --- a/.gitlab/ci/jobs/packaging/opam_package.yml +++ b/.gitlab/ci/jobs/packaging/opam_package.yml @@ -222,6 +222,8 @@ opam:octez-alcotezt: variables: package: octez-alcotezt +# Ignoring unreleased package octez-aplonk. + opam:octez-baker-PtLimaPt: extends: - .opam_template diff --git a/dune-project b/dune-project index e1d475aeeadb..2f180eeb41e6 100644 --- a/dune-project +++ b/dune-project @@ -7,6 +7,7 @@ (package (name octez-accuser-PtMumbai)) (package (name octez-accuser-alpha)) (package (name octez-alcotezt)) +(package (name octez-aplonk)) (package (name octez-baker-PtLimaPt)) (package (name octez-baker-PtMumbai)) (package (name octez-baker-alpha)) diff --git a/manifest/main.ml b/manifest/main.ml index 262532697eee..741e4616c113 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1222,6 +1222,17 @@ let octez_plonk_aggregation = ~preprocess:[pps ppx_repr] ~deps:[octez_plonk; octez_bls12_381_polynomial |> open_] +let _octez_aplonk = + public_lib + "octez-aplonk" + ~internal_name:"aplonk" + ~path:"src/lib_aplonk" + ~synopsis: + "Zero-knowledge proving system based on PlonK optimized for proofs \ + aggregation" + ~preprocess:[pps ppx_repr] + ~deps:[octez_plonk_aggregation] + let _octez_srs_extraction_tests = tests ["main"] diff --git a/opam/octez-aplonk.opam b/opam/octez-aplonk.opam new file mode 100644 index 000000000000..42747a6722aa --- /dev/null +++ b/opam/octez-aplonk.opam @@ -0,0 +1,21 @@ +# This file was automatically generated, do not edit. +# Edit file manifest/main.ml instead. +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: ["Tezos devteam"] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "3.0" } + "ocaml" { >= "4.14" } + "ppx_repr" { >= "0.6.0" } + "octez-plonk" +] +build: [ + ["rm" "-r" "vendors"] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Zero-knowledge proving system based on PlonK optimized for proofs aggregation" diff --git a/src/lib_aplonk/README.md b/src/lib_aplonk/README.md new file mode 100644 index 000000000000..377e425b666c --- /dev/null +++ b/src/lib_aplonk/README.md @@ -0,0 +1,7 @@ +aPlonK is a PlonK-inspired proving system which focuses +on proof-aggregation and distributed proof generation. +It is an OCaml implementation from scratch of the PlonK proving +system based on the bls12-381 curve, which eases the integration +of new custom gates and lookup tables. +Instead of the classic KZG commitment scheme, our custom aggregation +protocol can verify multiple proofs in logarithmic time. \ No newline at end of file diff --git a/src/lib_aplonk/circuit.ml b/src/lib_aplonk/circuit.ml new file mode 100644 index 000000000000..cd12a0964774 --- /dev/null +++ b/src/lib_aplonk/circuit.ml @@ -0,0 +1,713 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* This files contains all tools that can be used to create the verification circuit of aPlonK. *) + +module SMap = Plonk.SMap +open Plonk.Bls + +let nb_wires = Plompiler.Csir.nb_wires_arch + +(* Applies the function [f] to the last element of the list [l] *) +let map_end f l = + let n = List.length l in + List.mapi (fun i x -> if i = n - 1 then f x else x) l + +module V (Main : Aggregation.Main_protocol.S) = struct + module Gates = Main.Gates + module Perm = Main.Perm + module S = Plompiler.S + open Plompiler.LibCircuit + + type scalar_input = scalar Input.input + + (* This type gathers all inputs of the verification circuit + alpha, beta, gamma, delta, x, r are challenges generated from Fiat-Shamir + ss1, ss2, ss3, ss4, ss5 are preprocessed permutation polynomials evaluations at x + selectors are the list of the selectors evaluations at x with their names + ids_batch is the batch (with alpha) of the evaluated identities at x + wires_g is the lists of all wires evaluations at gx for each proof + wires is the lists of all wires evaluations at x for each proof + zg is the permutation polynomial evaluation at gx + z is the permutation polynomial evaluation at x + batch are the expected batched values with r of + · ss1, ss2, ss3, ss4, ss5 selectors + · ids_batch + · wires_g + · wires + · zg_list + · z_list + outer_pi is the list of public inputs that are public to aPlonK’s verifier + inner_pi is the list of hidden public inputs that are not known from aPlonK’s verifier + *) + type circuit_inputs = { + switches : bool Input.input list; + compressed_switches : scalar_input; + alpha : scalar_input; + beta : scalar_input; + gamma : scalar_input; + delta : scalar_input; + x : scalar_input; + r : scalar_input; + ss1 : scalar_input; + ss2 : scalar_input; + ss3 : scalar_input; + ss4 : scalar_input; + ss5 : scalar_input; + selectors : (string * scalar_input) list; + ids_batch : scalar_input; + wires_g : scalar_input list list; + wires : scalar_input list list; + zg : scalar_input; + z : scalar_input; + batch : scalar_input list; + inner_pi : scalar_input list list; + outer_pi : scalar_input list; + } + + let nb_batch gates = if Gates.exists_gx_composition ~gates then 5 else 4 + + (* This inputs is given to the verification circuit when it’s created. The value of the dummy inputs is irrelevant, only their structures & sizes matter *) + let dummy_input gates nb_proofs nb_inner_pi nb_outer_pi = + let switches = List.init nb_proofs (fun _ -> Input.bool true) in + let dummy_input = Input.scalar S.one in + let wires = + List.init nb_proofs (fun _ -> List.init nb_wires (fun _ -> dummy_input)) + in + let inner_pi = + List.init nb_proofs (fun _ -> + List.init nb_inner_pi (fun _ -> dummy_input)) + in + let outer_pi = List.init nb_outer_pi (fun _ -> dummy_input) in + let selectors = List.map (fun q -> (q, dummy_input)) gates in + let gates = SMap.of_list (List.map (fun g -> (g, ())) gates) in + let batch = List.init (nb_batch gates) (fun _ -> dummy_input) in + let wires_g = if nb_batch gates = nb_batch SMap.empty then [] else wires in + { + switches; + compressed_switches = dummy_input; + alpha = dummy_input; + beta = dummy_input; + gamma = dummy_input; + delta = dummy_input; + x = dummy_input; + r = dummy_input; + ss1 = dummy_input; + ss2 = dummy_input; + ss3 = dummy_input; + ss4 = dummy_input; + ss5 = dummy_input; + selectors; + ids_batch = dummy_input; + wires_g; + wires; + zg = dummy_input; + z = dummy_input; + batch; + inner_pi; + outer_pi; + } + + module Constraints = struct + (* replace by [zero] all elements of the second list that correspond to false in the first one *) + let switch_list = map2M (fun s l -> mapM (Num.mul s) l) + + (* Replace with zeros all the wires values when the correponding switch is false *) + let switch switches ~wires ~wires_g ~inner_pi = + let switches = List.map scalar_of_bool switches in + let* wires = switch_list switches wires in + let* wires_g = + match wires_g with + | [] -> ret [] + | wires_g -> switch_list switches wires_g + in + let* inner_pi = switch_list switches inner_pi in + ret (wires, wires_g, inner_pi) + + (* Because we can’t deal as we want with the monad in the output of Gates functions & for gates uniformity, Arith monomials are expected to be given as scalar repr t list t. *) + let format_arith_cs : scalar repr list t -> scalar repr t = + fun scalar_repr_list_t -> + let* scalar_repr_list = scalar_repr_list_t in + match scalar_repr_list with + | [cs] -> ret cs + | _ -> raise (Invalid_argument "Invalid format for Arith constraint.") + + (* Makes fetching wires from wires lists easy *) + let format_wires = function + | [a; b; c; d; e], [ag; bg; cg; dg; eg] -> + (a, b, c, d, e, ag, bg, cg, dg, eg) + | _ -> raise (Invalid_argument "Unexpected wire list format.") + + (* For a selector name and value q, given the wires values wires & wires_g, returns the evaluation of arithmetic monomial associated with the selector. *) + let cs_of_arith_sel name q wires wires_g = + let a, b, c, d, e, ag, bg, cg, dg, eg = format_wires (wires, wires_g) in + format_arith_cs + (Gates.get_cs name ~q ~a ~b ~c ~d ~e ~ag ~bg ~cg ~dg ~eg ()) + + (* For a selector name and value q, given the wires values wires & wires_g, returns the evaluation of identity given by the selector. *) + let cs_of_custom_sel ?precomputed_advice name q wires wires_g = + let a, b, c, d, e, ag, bg, cg, dg, eg = format_wires (wires, wires_g) in + Gates.get_cs + name + ~q + ~a + ~b + ~c + ~d + ~e + ~ag + ~bg + ~cg + ~dg + ~eg + ?precomputed_advice + () + + (* Circuit that computes x^n for n given as a scalar *) + let compute_xn x n = + with_label ~label:"x^n" + @@ + let nb_bits = S.size_in_bytes in + let* n_repr = constant_scalar n in + let* n_bytes = bits_of_scalar ~nb_bits n_repr in + Num.pow x (of_list n_bytes) + + (* Circuit that computes x^n - 1 *) + let compute_zs xn = Num.add_constant S.(negate one) xn + + (* Circuit that computes L1(x) := (g / n) * (x^n - 1) / (x - g) *) + let compute_l1 x xn_minus_one n generator = + let* den = Num.add_constant S.(negate generator) x in + Num.div ~den_coeff:(S.div_exn n generator) xn_minus_one den + + (* Circuit that computes (x₀ + αx₁ + α²x₂ + …) for list_circuit = [x₀, x₁, x₂, …] *) + let sum_alpha_i list_circuit alpha = + let list_circuit = List.rev list_circuit in + match list_circuit with + | [] -> constant_scalar S.zero + | init :: list_circuit -> + foldM + (fun acc circuit -> + let* tmp = Num.mul acc alpha in + Num.add tmp circuit) + init + list_circuit + + (* Circuit that computes (x₀ + αx₁ + α²x₂ + …) for list_circuit = [x₀, x₁, x₂, …] and ignores the coefficients when corresponding switch is false ; for instance, if switch₁ = 0 and all other switches are 1, it will compute (x₀ + αx₂ + α²x₃ + …) *) + let sum_alpha_i_switched switches list_circuit alpha = + let* zero = constant_scalar S.zero in + let* alpha_min_one = Num.add ~qc:S.(negate one) alpha zero in + let nb_proofs = List.length switches in + let list_circuit = List.rev list_circuit in + let switches = List.rev switches in + match list_circuit with + | [] -> constant_scalar S.zero + | list_circuit -> + let* res, _ = + fold2M + (fun (acc, i) coeff switch -> + let switch = scalar_of_bool switch in + let* coeff = Num.mul switch coeff in + (* α = [switch × (α - 1)] + 1 *) + let* alpha = + Num.custom ~qm:S.one ~qc:S.one switch alpha_min_one + in + let* tmp = Num.add acc coeff in + let* res = + if i = nb_proofs then ret tmp else Num.mul tmp alpha + in + ret (res, i + 1)) + (zero, 1) + list_circuit + switches + in + ret res + + (* Circuit that recomputes T polynomial from the t_list of its parts & x^n *) + let compute_t xn t_list = sum_alpha_i t_list xn + + let add_circuits circuit_list = + let* circuit_list = mapM Fun.id circuit_list in + Num.add_list (to_list circuit_list) + + (* Checks that compressed_switches is the sum of all switches and that switches has the structure [1…10…0] *) + let check_switches compressed_switches switches = + let switches = List.map scalar_of_bool switches in + let* sum = Num.add_list (to_list switches) in + let switches_pairs, _ = + List.fold_left + (fun (pairs, s_prev) s -> ((s_prev, s) :: pairs, s)) + ([], List.hd switches) + (List.tl switches) + in + iterM + (fun (s_prev, s) -> + Num.assert_custom ~qm:S.one ~qr:S.(negate one) s_prev s s) + switches_pairs + >* equal compressed_switches sum + + (* Recomputes batches & compare them to claimed batches *) + let check_batch r (g_list, wires, wiresg, z, zg) batch = + let wires = List.flatten wires in + let wiresg = List.flatten wiresg in + let* batch_g = sum_alpha_i g_list r in + let* batch_wires = sum_alpha_i wires r in + let g_exp = List.nth batch 0 in + let zg_exp = List.nth batch 1 in + let z_exp = List.nth batch 2 in + let* g = equal batch_g g_exp in + let* z = equal z z_exp in + let* zg = equal zg zg_exp in + match wiresg with + | [] -> + let wires_exp = List.nth batch 3 in + let* wires = equal batch_wires wires_exp in + Bool.band_list [g; wires; zg; z] + | wg -> + let* batch_wires_g = sum_alpha_i wg r in + let wiresg_exp = List.nth batch 3 in + let wires_exp = List.nth batch 4 in + let* wiresg = equal batch_wires_g wiresg_exp in + let* wires = equal batch_wires wires_exp in + Bool.band_list [g; wiresg; wires; zg; z] + + (* custom_ids is a nested list with 3 levels: + - the outter one corresponds to different proofs + - the middle level corresponds to different identities + - the inner level corresponds to different equations of the same identity *) + let format_custom_ids custom_ids = + let suffix_ids l = + List.map + (fun (s, l) -> + List.mapi (fun i x -> (s ^ "." ^ string_of_int i, x)) l) + l + |> List.flatten + in + let index_proofs l = + let n = List.length l in + List.mapi + (fun i inner_l -> + List.map + (fun (s, x) -> (SMap.Aggregation.add_prefix ~n ~i "" s, x)) + inner_l) + l + in + index_proofs (List.map suffix_ids custom_ids) |> List.flatten + + let format_arith_ids arith_ids = + let arith = Plonk.Custom_gates.arith_label in + let n = List.length arith_ids in + List.mapi + (fun i x -> (SMap.Aggregation.add_prefix ~n ~i "" arith, x)) + arith_ids + + (* Verifies that the linear combination of identities with alpha is equal to T×Zs + The identities are computed from evaluations, with the functions cs of Custom_gates & Permutation_gate + *) + let check_identities ~switches (n, generator) x ids_batch + (q_names, selectors) (alpha, beta, gamma, delta) (wires_g, wires, zg, z) + (ss1, ss2, ss3, ss4, ss5) pi_list_list = + (* We don’t care about wires_g value if it’s empty so we just take wires *) + let wires_g = match wires_g with [] -> wires | w -> w in + (* precompute some constant *) + let* t = Bool.constant_bool true in + let* xn = compute_xn x n in + let* zs = compute_zs xn in + let* l1 = compute_l1 x zs n generator in + (* split the arith selectors & other selectors in two lists *) + let is_advice_sel s = String.starts_with ~prefix:Gates.qadv_label s in + let arith_selectors, custom_selectors = + List.combine q_names selectors + |> List.partition (fun (q_name, _) -> + if is_advice_sel q_name then false + else + let id_name, nb_id = Gates.get_ids q_name in + if id_name = Gates.arith_label then + if nb_id <> 1 then + failwith "partition_selector : invalid Arith identity." + else true + else false) + in + let advice_selectors, custom_selectors = + List.partition (fun (s, _) -> is_advice_sel s) custom_selectors + in + let precomputed_advice = SMap.of_list advice_selectors in + (* Custom identities are usually composed with several identities + Custom_ids has format + [[[q₁.ida₁ ; q₁.idb₁] ; [q₂.ida₁ ; q₂.idb₁]] ; + [[q₁.ida₂ ; q₁.idb₂] ; [q₂.ida₂ ; q₂.idb₂]] ; + [[q₁.ida₃ ; q₁.idb₃] ; [q₂.ida₃ ; q₂.idb₃]]] + for 2 selectors q₁ & q₂ with 2 identities each (ida & idb) & 3 proofs + *) + let* custom_ids = + map2M + (fun wires wires_g -> + mapM + (fun (name, q) -> + let* id_values = + cs_of_custom_sel ~precomputed_advice name q wires wires_g + in + ret (name, id_values)) + custom_selectors) + wires + wires_g + in + let* arith_list = + let monomials = + List.map + (fun (name, q) -> List.map2 (cs_of_arith_sel name q) wires wires_g) + arith_selectors + in + let pi_list = + List.map (Gates.cs_pi ~generator ~n ~x ~zs) pi_list_list + in + Plonk.List.mapn add_circuits (pi_list :: monomials) |> mapM Fun.id + in + (* Using switched wires is enough for adapting the perm identity to the lower number of proof *) + let* perm_a, perm_b = + (Perm.cs + ~sum_alpha_i + ~l1 + ~ss1 + ~ss2 + ~ss3 + ~ss4 + ~ss5 + ~beta + ~gamma + ~delta + ~x + ~z + ~zg) + ~wires + in + let perm_ids = [("Perm.a", perm_a); ("Perm.b", perm_b)] in + let identities = + format_arith_ids arith_list @ format_custom_ids custom_ids @ perm_ids + |> List.sort (fun (s, _) (s', _) -> String.compare s s') + |> List.map snd + in + (* Adapt the switches to match the identities *) + let id_switches = + let nb_ids_per_proof = + let nb_custom_ids = + List.( + hd custom_ids |> fold_left (fun acc l -> acc + length (snd l)) 0) + in + (* +1 for the arithmetic identity *) + nb_custom_ids + 1 + in + (* [true ; true] is added for the permutation identities *) + (List.map (fun b -> List.init nb_ids_per_proof (Fun.const b)) switches + |> List.flatten) + @ [t; t] + in + let* sum_id = sum_alpha_i_switched id_switches identities alpha in + equal sum_id ids_batch + end + + (* number of public inputs in the verification circuit added by meta; circuit + public inputs will be considered later (when their amount is known) *) + let meta_public_input_size gates = 8 + nb_batch gates + + let nb_answers nb_proofs gates = + (* Sσ₁ + Sσ₂ + Sσ₃ + Sσ₄ + Sσ₅ + selectors *) + let nb_g = nb_wires + SMap.cardinal gates in + let nb_w = nb_proofs * nb_wires in + let nb_wg = if Gates.exists_gx_composition ~gates then nb_w else 0 in + let nb_z = 1 in + let nb_zg = 1 in + nb_g + nb_w + nb_wg + nb_z + nb_zg + + let verify_batch r batch batches t_answers = + let init_sum = + List.map (SMap.map @@ Fun.const Scalar.zero) (List.tl batch) + in + let init_sizes = List.map (SMap.map @@ Fun.const 0) (List.tl batch) in + let sum_batches, _ = + SMap.fold + (fun _circuit_name this_batch (acc_sum, acc_sizes) -> + let values = List.map (SMap.map fst) this_batch in + let sizes_list = List.map (SMap.map snd) this_batch in + let acc_sum = + List.map2 + (fun map_sum (map_this_batch, map_sizes) -> + SMap.mapi + (fun key acc_value -> + let size = SMap.find key map_sizes |> Z.of_int in + let this_value = SMap.find key map_this_batch in + Scalar.(acc_value + (this_value * pow r size))) + map_sum) + acc_sum + (List.combine values acc_sizes) + in + let acc_sizes = + List.map2 + (fun map_acc_sizes map_sizes -> + SMap.mapi + (fun key size -> size + SMap.find key map_sizes) + map_acc_sizes) + acc_sizes + sizes_list + in + (acc_sum, acc_sizes)) + batches + (init_sum, init_sizes) + in + let t_batch = + List.fold_left + (fun (acc, rk) x -> Scalar.(acc + (rk * x), r * rk)) + (Scalar.zero, Scalar.one) + t_answers + |> fst + in + (* Complete the first element of [sum_batches] with [t_batch] *) + let sum_batches = + let hd = List.hd batch in + assert (SMap.cardinal hd = 1) ; + let t_key, _t_value = SMap.choose hd in + SMap.singleton t_key t_batch :: sum_batches + in + let given = List.concat_map SMap.values batch in + let computed = List.concat_map SMap.values sum_batches in + List.for_all2 Scalar.( = ) given computed + + (* Format verification circuit public inputs *) + let aggreg_public_inputs pi_size (alpha, beta, gamma, delta, x, r) batch + ids_batch compressed_switches outer_pi = + let batch = List.concat_map SMap.values batch |> List.map fst in + let public_input = + Array.of_list + ([alpha; beta; gamma; delta; x; r] + @ batch + @ [ids_batch; compressed_switches] + @ outer_pi) + in + let l = Array.length public_input in + if l <> pi_size then + failwith + (Printf.sprintf + "Public input has not expected size (expected: %d; actual: %d)." + pi_size + l) ; + public_input + + let compute_switches max_nb_proofs nb_proofs = + let switches = + Array.init max_nb_proofs S.(fun i -> if i < nb_proofs then one else zero) + in + (switches, S.of_int nb_proofs) + + let pad_inputs nb_max_proofs inner_pi answers = + let to_pad = nb_max_proofs - List.length inner_pi in + let padded_inner_pi = + let nb_inner_pi = List.(length (hd inner_pi)) in + List.flatten inner_pi + @ List.(init (to_pad * nb_inner_pi) (Fun.const S.zero)) + in + let padded_answers = + let answers = + answers |> List.map (fun a -> SMap.values a |> List.map SMap.values) + in + let pad_wires wires_list = + List.map + (fun w_list -> + w_list @ List.init (to_pad * nb_wires) (Fun.const S.zero)) + wires_list + in + map_end pad_wires answers |> List.flatten |> List.flatten + in + (padded_inner_pi, padded_answers) + + (* Returns witness of verification circuit *) + let get_witness max_nb_proofs (p : Main.prover_aux) circuit_name pi_size + solver (inner_pi, outer_pi) switches compressed_switches batch = + let ids_batch = SMap.find circuit_name p.ids_batch |> fst in + let public = + aggreg_public_inputs + pi_size + (p.alpha, p.beta, p.gamma, p.delta, p.x, p.r) + batch + ids_batch + compressed_switches + outer_pi + in + let circuit_answers = + List.map + (SMap.Aggregation.select_answers_by_circuit circuit_name) + (* ignore the first element in p.answers corresponding to T evaluations, + which are handled outside of the meta-verification circuit *) + (List.tl p.answers) + in + let inputs = + let inner_pi, answers = + pad_inputs max_nb_proofs inner_pi circuit_answers + in + Array.(concat [of_list (inner_pi @ answers); public; switches]) + in + try Plompiler.Solver.solve solver inputs + with e -> + print_string "\nSolver failure\n" ; + raise e + + let get_batches inputs answers r = + let batch_map r map = Plonk.Utils.Fr_generation.batch r (SMap.values map) in + (* we map over [inputs] just because it contains the circuit_names *) + SMap.mapi + (fun circuit_name _ -> + let answers = + List.map + (SMap.Aggregation.select_answers_by_circuit circuit_name) + (List.tl answers) + in + List.map SMap.(map (fun m -> (batch_map r m, cardinal m))) answers) + inputs + + (* generator & n are the subgroup generator & size of the subgroup of identities verification + check_pi is a function related to PI, given here as argument in order to allow several PI handling forms + *) + let verification_circuit (generator, n) check_pi + { + switches; + compressed_switches; + alpha; + beta; + gamma; + delta; + x; + r; + ss1; + ss2; + ss3; + ss4; + ss5; + selectors; + ids_batch; + wires_g; + wires; + zg; + z; + batch; + outer_pi; + inner_pi; + } = + let n = S.of_int n in + (* input selectors in the same order they are given *) + let q_names, selectors = List.split selectors in + + let* inner_pi = + begin_input_com (fun inner_pi -> List.map of_list (of_list inner_pi)) + |: Input.list (List.map Input.list inner_pi) + |> end_input_com + in + let* ss1, ss2, ss3, ss4, ss5, selectors, zg, z, wires_g, wires = + begin_input_com (fun ss1 ss2 ss3 ss4 ss5 selectors zg z wires_g wires -> + ( ss1, + ss2, + ss3, + ss4, + ss5, + of_list selectors, + zg, + z, + List.map of_list (of_list wires_g), + List.map of_list (of_list wires) )) + |: ss1 |: ss2 |: ss3 |: ss4 |: ss5 |: Input.list selectors |: zg |: z + |: Input.list (List.map Input.list wires_g) + |: Input.list (List.map Input.list wires) + |> end_input_com + in + let* alpha = input ~kind:`Public alpha in + let* beta = input ~kind:`Public beta in + let* gamma = input ~kind:`Public gamma in + let* delta = input ~kind:`Public delta in + let* x = input ~kind:`Public x in + let* r = input ~kind:`Public r in + + let* batch = mapM (input ~kind:`Public) batch in + + let* ids_batch = input ~kind:`Public ids_batch in + + let* compressed_switches = input ~kind:`Public compressed_switches in + + (* Input PI *) + let* outer_pi = mapM (input ~kind:`Public) outer_pi in + + let* switches = mapM input switches in + + (* We use the switch to only take the n first wires evaluations (where n is the number of proofs actually performed), the rest is set to zero ; this nullifies batches and the permutation argument where proofs were not computed *) + let* switched_wires, switched_wires_g, switched_inner_pi = + Constraints.switch switches ~wires ~wires_g ~inner_pi + in + + let* check_switches = + with_label ~label:"check_switches" + @@ Constraints.check_switches compressed_switches switches + in + + let* check_pi = + with_label ~label:"check_pi" + @@ check_pi ~switches ~outer:outer_pi ~inner:inner_pi + in + + let* check_identities = + with_label ~label:"check_identities" + @@ Constraints.check_identities + ~switches + (n, generator) + x + ids_batch + (q_names, selectors) + (alpha, beta, gamma, delta) + (switched_wires_g, switched_wires, zg, z) + (ss1, ss2, ss3, ss4, ss5) + switched_inner_pi + in + let* check_batch = + with_label ~label:"check_batch" + @@ + let g_list = [ss1; ss2; ss3; ss4; ss5] @ selectors in + Constraints.check_batch + r + (g_list, switched_wires, switched_wires_g, z, zg) + batch + in + + let* res = + with_label ~label:"check_aplonk_res" + @@ Bool.band_list + [check_switches; check_batch; check_identities; check_pi] + in + Bool.assert_true res + + (* Function that creates the verification circuit as cs *) + let get_cs_verification pp circuit nb_proofs (nb_outer_pi, nb_inner_pi) + check_pi = + let gen, n = Main.get_gen_n_prover pp in + let gates = Plonk.Circuit.get_selectors circuit in + let dummy_input = dummy_input gates nb_proofs nb_inner_pi nb_outer_pi in + Plompiler.LibCircuit.get_cs + (verification_circuit (gen, n) check_pi dummy_input) +end diff --git a/src/lib_aplonk/dune b/src/lib_aplonk/dune new file mode 100644 index 000000000000..6454f85f1b72 --- /dev/null +++ b/src/lib_aplonk/dune @@ -0,0 +1,10 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name aplonk) + (public_name octez-aplonk) + (instrumentation (backend bisect_ppx)) + (libraries + octez-plonk.aggregation) + (preprocess (pps ppx_repr))) diff --git a/src/lib_aplonk/main_protocol.ml b/src/lib_aplonk/main_protocol.ml new file mode 100644 index 000000000000..8f357b808d01 --- /dev/null +++ b/src/lib_aplonk/main_protocol.ml @@ -0,0 +1,514 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(* This file implements the aPlonK protocol, designed to produce multiple PlonK + proofs at the same time, which can be verified in logarithmic time. + In addition to using a multi-polynomial commitment scheme, aPlonK delegates + part of verification checks on scalar values to the prover, who will produce + a PlonK proof that the checks pass correctly. *) + +open Plonk.Bls +module SMap = Plonk.SMap + +module Make_impl + (Main_KZG : Plonk.Main_protocol.S + with type public_inputs = Scalar.t array list) + (Main_Pack : Aggregation.Main_protocol.S + with type public_inputs = Scalar.t array list + with module PP.Answers_commitment = Main_KZG.Input_commitment) + (PIs : Pi_parameters.S) = +struct + module Aggreg_circuit = Circuit.V (Main_Pack) + module L = Plompiler.LibCircuit + + exception Entry_not_in_table of string + + exception Rest_not_null of string + + module Input_commitment = Main_Pack.Input_commitment + + type scalar = Scalar.t [@@deriving repr] + + type circuit_map = Main_Pack.circuit_map + + let public_input_size circuit_name gates = + let module PI = (val PIs.get_pi_module circuit_name) in + Aggreg_circuit.meta_public_input_size gates + PI.nb_outer + + (* Type of prover public params for meta-verification of a base circuit: + - meta_pp : meta-verification prover PP of this base circuit + - meta_solver : Plompiler solver for this meta-verification circuit + - public_input_size : number of public inputs in this base circuit + - input_com_sizes : number of input commitment sizes expected by this + base circuit + - nb_proofs : maximum number of proofs that will be created on + this base circuit *) + type prover_meta_pp = { + meta_pp : Main_KZG.prover_public_parameters; + meta_solver : Plompiler.Solver.t; + public_input_size : int; + input_com_sizes : int list; + nb_proofs : int; + } + [@@deriving repr] + + (* Type of verifier public params for meta-verification of a base circuit: + - meta_pp : meta-verification verifier PP of this base circuit + - public_input_size : number of public inputs in this base circuit *) + type verifier_meta_pp = { + meta_pp : Main_KZG.verifier_public_parameters; + public_input_size : int; + nb_proofs : int; + } + [@@deriving repr] + + (* Type of prover public parameters of aPlonK: + - main_pp : main_protocol (prover) public parameters of the aPlonK + aggregated statement + - meta_pps : [prover_meta_pp] for meta-verification of all the supported + base circuits, encoded as a string map keyed by the base + circuit names *) + type prover_public_parameters = { + main_pp : Main_Pack.prover_public_parameters; + meta_pps : prover_meta_pp SMap.t; + } + [@@deriving repr] + + (* Type of verifier public parameters of aPlonK: + - main_pp : main_protocol (verifier) public parameters of the aPlonK + aggregated statement + - meta_pps : [verifier_meta_pp] for meta-verification of all the supported + base circuits, encoded as a string map keyed by the base + circuit names *) + type verifier_public_parameters = { + main_pp : Main_Pack.verifier_public_parameters; + meta_pps : verifier_meta_pp SMap.t; + } + [@@deriving repr] + + (* Type of an aggregated aPlonK proof: + - main_proof : proof of the aggregated aPlonK statement + - meta_proofs : meta-verification proofs for each base circuit, + encoded as a string map keyed by the base circuit names + - batch : COULD BE REMOVED AND RECOMPUTED FROM [batches] + - batches : aggregated evaluation values for each of the base circuits + in the catalog; its structure is as follows: + * we have one "batch" (of type [(scalar * int) SMap.t list]) per base + circuit, stored in a string map keyed by the base circuit names + * each "batch" is a list of [(scalar * int) SMap.t], corresponding to + the groups of polynomials committed during the PlonK protocol; + currently this list includes four groups of polynomials: + - setup-polynomials, + - perm-and-plook polynomials + - wire-polynomials + in that order (although aPlonK is order-agnostic, as long as the + order is consistent with [cms_answers]). + IMPORTANT: t-polynomials are handeled separately, explicitly in + the multi-aPlonK protocol + * each [(scalar * int) SMap.t] is a map containing the batched + evaluation of all the polynomials in the group at the point + represented by the map key (typically "X" and "GX"); the [int] + indicates the number of polynomials that were batch + - cms_answers : commitments to the PlonK polynomial evaluations + (a.k.a. "answers"), one commitment per base circuit, + presented in a string map keyed by the base circuit names; + each commitment includes the evaluations that were + "batched" in [batches] + - cms_pi : commitments to the public inputs of each base circuit, + presented in a string map keyed by the base circuit names + - ids_batch : a map from circuit names to pairs [scalar * int], the + [scalar] is the value corresponding to the batched + identities of that circuit, whereas the [int] indicates + how many identities were batched. + - t_answers : evaluations of polynomial [T] at [x]; this type is a list + of scalars given that [T] may be split into several parts. + *) + type proof = { + main_proof : Main_Pack.proof; + meta_proofs : Main_KZG.proof SMap.t; + batch : Main_KZG.scalar SMap.t list; + batches : (Main_KZG.scalar * int) SMap.t list SMap.t; + cms_answers : Main_Pack.PP.Answers_commitment.public SMap.t; + cms_pi : Main_Pack.PP.Answers_commitment.public SMap.t; + ids_batch : (Main_KZG.scalar * int) SMap.t; + t_answers : Main_KZG.scalar list; + } + [@@deriving repr] + + type circuit_prover_input = Main_Pack.circuit_prover_input = { + witness : scalar array; + input_commitments : Main_Pack.Input_commitment.t list; + } + [@@deriving repr] + + type prover_inputs = circuit_prover_input list SMap.t [@@deriving repr] + + type public_inputs = scalar list [@@deriving repr] + + type verifier_inputs = + (public_inputs * Input_commitment.public list list) SMap.t + [@@deriving repr] + + let to_verifier_inputs (pp : prover_public_parameters) inputs = + let vi = Main_Pack.to_verifier_inputs pp.main_pp inputs in + SMap.mapi + (fun circuit_name (pi, ic) -> + let module PI = (val PIs.get_pi_module circuit_name) in + let pi = PI.outer_of_inner (List.map Array.to_list pi) in + assert (List.for_all (fun i -> i = []) ic) ; + (pi, ic)) + vi + + (* We only need to modify the main circuit PP, since it rules them all + (meta-circuits get their state updated after the main circuit proof) *) + let update_prover_public_parameters bytes (pp : prover_public_parameters) = + { + pp with + main_pp = Main_Pack.update_prover_public_parameters bytes pp.main_pp; + } + + (* We only need to modify the main circuit PP, since it rules them all + (meta-circuits get their state updated after the main circuit proof) *) + let update_verifier_public_parameters bytes (pp : verifier_public_parameters) + = + { + pp with + main_pp = Main_Pack.update_verifier_public_parameters bytes pp.main_pp; + } + + let filter_prv_pp_circuits (pp : prover_public_parameters) inputs = + {pp with main_pp = Main_Pack.filter_prv_pp_circuits pp.main_pp inputs} + + let filter_vrf_pp_circuits pp inputs = + {pp with main_pp = Main_Pack.filter_vrf_pp_circuits pp.main_pp inputs} + + (* used for debug with sat *) + let cs_global = ref SMap.empty + + (* ////////////////////////////////////////////////////// *) + + let input_commit_infos (pp : prover_public_parameters) = + SMap.map + (fun prover_meta_pp -> + Main_Pack. + { + (* meta-verification circuits have exactly 2 input commitments: + one for the PI and one for the answers (in that order) *) + nb_max_pi = List.hd prover_meta_pp.input_com_sizes; + nb_max_answers = List.nth prover_meta_pp.input_com_sizes 1; + func = + (fun ?size ?shift s -> + Main_KZG.input_commit ?size ?shift prover_meta_pp.meta_pp s); + }) + pp.meta_pps + + (* ////////////////////////////////////////////////////// *) + + let input_commit ?size ?shift (pp : prover_public_parameters) secret = + ignore (size, shift, pp, secret) ; + failwith "[input_commit] in aPlonK is not supported yet" + + let meta_setup ~zero_knowledge ~srs ~main_prover_pp circuit_name + (circuit, nb_proofs) = + let module PI = (val PIs.get_pi_module circuit_name) in + let cs = + Aggreg_circuit.get_cs_verification + main_prover_pp + circuit + nb_proofs + PI.(nb_outer, nb_inner) + PI.check + in + (* cs_global is used for sat *) + cs_global := SMap.add circuit_name cs.cs !cs_global ; + (* Plompiler.Utils.dump_label_traces + ("../../../../flamegraph/flamegraph" ^ "_" ^ Int.to_string nb_proofs) + cs.cs; *) + let public_input_size = public_input_size circuit_name circuit.gates in + let input_com_sizes = cs.input_com_sizes in + let circuit_aggreg = + Plonk.Circuit.to_plonk ~public_input_size ~input_com_sizes cs.cs + in + let agg_circuit_map = + SMap.singleton ("meta_" ^ circuit_name) (circuit_aggreg, 1) + in + let prover_meta_pp, verifier_meta_pp = + Main_KZG.setup ~zero_knowledge agg_circuit_map ~srs + in + let prover_meta_pp = + { + meta_pp = prover_meta_pp; + meta_solver = cs.solver; + public_input_size; + input_com_sizes; + nb_proofs; + } + in + let verifier_meta_pp = + {meta_pp = verifier_meta_pp; public_input_size; nb_proofs} + in + (prover_meta_pp, verifier_meta_pp) + + let setup ~zero_knowledge circuits_map ~srs = + let prover_pp, verifier_pp = + Main_Pack.setup ~zero_knowledge circuits_map ~srs + in + let meta_pps = + SMap.mapi + (meta_setup ~zero_knowledge ~srs ~main_prover_pp:prover_pp) + circuits_map + in + let prover_meta_pps = SMap.map fst meta_pps in + let verifier_meta_pps = SMap.map snd meta_pps in + ( ({main_pp = prover_pp; meta_pps = prover_meta_pps} + : prover_public_parameters), + {main_pp = verifier_pp; meta_pps = verifier_meta_pps} ) + + let meta_prove ~(main_prover_aux : Main_Pack.prover_aux) ~meta_pps + ~inner_pi_map ~transcript batches circuit_name circuit_inputs = + let module PI = (val PIs.get_pi_module circuit_name) in + let prover_meta_pp : prover_meta_pp = SMap.find circuit_name meta_pps in + let batch = SMap.find circuit_name batches in + let cm_pi = SMap.find circuit_name main_prover_aux.cms_pi in + let cm_answers = SMap.find circuit_name main_prover_aux.cms_answers in + let switches, compressed_switches = + let nb_proofs = List.length circuit_inputs in + Aggreg_circuit.compute_switches prover_meta_pp.nb_proofs nb_proofs + in + let inner_pi = + SMap.find circuit_name inner_pi_map |> fst |> List.map Array.to_list + in + let trace = + let outer_pi = PI.outer_of_inner inner_pi in + Aggreg_circuit.get_witness + prover_meta_pp.nb_proofs + main_prover_aux + circuit_name + prover_meta_pp.public_input_size + prover_meta_pp.meta_solver + (inner_pi, outer_pi) + switches + compressed_switches + batch + in + let secret = + Main_KZG.{witness = trace; input_commitments = [cm_pi; cm_answers]} + in + let cs = SMap.find circuit_name !cs_global in + assert (Plonk.Circuit.sat cs [] trace) ; + let inputs = SMap.singleton ("meta_" ^ circuit_name) [secret] in + let pp_aggreg_circuit = + Main_KZG.update_prover_public_parameters transcript prover_meta_pp.meta_pp + in + try Main_KZG.prove pp_aggreg_circuit ~inputs + with Main_KZG.Rest_not_null _ -> + raise + (Rest_not_null + "Main_Kzg.prove could not create a proof for the verification \ + circuit.") + + let meta_proof (pp : prover_public_parameters) inputs (main_proof, prover_aux) + = + let open Main_Pack in + let transcript = + Data_encoding.Binary.to_bytes_exn proof_encoding main_proof + in + let inner_pi_map = to_verifier_inputs pp.main_pp inputs in + let batches = + Aggreg_circuit.get_batches inputs prover_aux.answers prover_aux.r + in + let meta_proofs = + SMap.mapi + (fun circuit_name circuit_inputs -> + meta_prove + ~main_prover_aux:prover_aux + ~meta_pps:pp.meta_pps + ~inner_pi_map + ~transcript + batches + circuit_name + circuit_inputs) + inputs + in + let cms_answers = + SMap.map + Main_Pack.PP.Answers_commitment.(fun cm_answers -> cm_answers.public) + prover_aux.cms_answers + in + let cms_pi = + SMap.map + Main_Pack.PP.Answers_commitment.(fun cm_pi -> cm_pi.public) + prover_aux.cms_pi + in + { + main_proof; + meta_proofs; + batch = prover_aux.batch; + batches; + cms_answers; + cms_pi; + t_answers = prover_aux.t_answers; + ids_batch = prover_aux.ids_batch; + } + + let prove (pp : prover_public_parameters) ~(inputs : prover_inputs) = + let pp = filter_prv_pp_circuits pp inputs in + let input_commit_infos = input_commit_infos pp in + let proof_base_circuits = + try Main_Pack.prove_list pp.main_pp ~input_commit_infos ~inputs + with Main_Pack.Rest_not_null _ -> + raise + (Rest_not_null + "Main_Pack.prove could not create a proof for the base circuit.") + in + meta_proof pp inputs proof_base_circuits + + let meta_verify ~transcript ~inputs ~proof alpha_et_al circuit_name pp = + let cm_answers = SMap.find circuit_name proof.cms_answers in + let cm_pi = SMap.find circuit_name proof.cms_pi in + let meta_proof = SMap.find circuit_name proof.meta_proofs in + let batch = SMap.find circuit_name proof.batches in + let ids_batch = SMap.find circuit_name proof.ids_batch |> fst in + let pi, input_commitments_list = SMap.find circuit_name inputs in + let nb_proofs = List.length input_commitments_list in + if List.exists (fun l -> l <> []) input_commitments_list then + raise + @@ Invalid_argument + "input commitments in the base circuit of\n\ + \ aPlonK are not yet supported" ; + let public_inputs = + Aggreg_circuit.aggreg_public_inputs + pp.public_input_size + alpha_et_al + batch + ids_batch + (Scalar.of_int nb_proofs) + pi + in + let pp_aggreg_circuit = + Main_KZG.update_verifier_public_parameters transcript pp.meta_pp + in + let inputs = + SMap.singleton + ("meta_" ^ circuit_name) + ([public_inputs], [[cm_pi; cm_answers]]) + in + Main_KZG.verify pp_aggreg_circuit ~inputs meta_proof + + let verify pp ~(inputs : verifier_inputs) proof = + let pp = filter_vrf_pp_circuits pp inputs in + let main_verif, main_verifier_aux = + Main_Pack.verify_list + pp.main_pp + ( proof.main_proof, + proof.batch, + proof.cms_answers, + proof.cms_pi, + proof.t_answers, + proof.ids_batch ) + in + let transcript = + Data_encoding.Binary.to_bytes_exn + Main_Pack.proof_encoding + proof.main_proof + in + let batch_ok = + Aggreg_circuit.verify_batch + main_verifier_aux.r + proof.batch + proof.batches + proof.t_answers + in + let meta_proofs_ok = + let v = main_verifier_aux in + SMap.for_all + (meta_verify + ~transcript + ~inputs + ~proof + (v.alpha, v.beta, v.gamma, v.delta, v.x, v.r)) + pp.meta_pps + in + main_verif && batch_ok && meta_proofs_ok + + (* Encodings *) + + let scalar_encoding = Main_Pack.scalar_encoding + + let data_encoding_of_repr repr = + Data_encoding.conv + (Plompiler.Utils.to_bytes repr) + (Plompiler.Utils.of_bytes repr) + Data_encoding.bytes + + let proof_encoding = data_encoding_of_repr proof_t + + let verifier_public_parameters_encoding = + data_encoding_of_repr verifier_public_parameters_t + + module Internal_for_tests = struct + let mutate_vi verifier_inputs = + let key, (public_inputs, input_commitments_list) = + SMap.choose verifier_inputs + in + match public_inputs with + | [] -> None + | input -> + let input = Array.of_list input in + let i = Random.int (Array.length input) in + input.(i) <- Scalar.random () ; + Some + (SMap.add + key + (Array.to_list input, input_commitments_list) + verifier_inputs) + end +end + +(* Main_KZG is used on the meta-verification circuit *) +module Main_KZG = Plonk.Main_protocol +module Super_PP = + Aggregation.Polynomial_protocol.Make_aggregation + (Aggregation.Polynomial_commitment) + (Main_KZG.Input_commitment) + +(* Main_Pack is used for the base circuits that we are proving; + it is built with the super aggregation *) +module Main_Pack = Aggregation.Main_protocol.Make (Super_PP) + +module Make_raw + (Main_KZG : Plonk.Main_protocol.S + with type public_inputs = Scalar.t array list) + (Main_Pack : Aggregation.Main_protocol.S + with type public_inputs = Scalar.t array list + with module PP.Answers_commitment = Main_KZG.Input_commitment) + (PIs : Pi_parameters.S) : + Plonk.Main_protocol.S + with module Input_commitment = Main_Pack.Input_commitment + with type circuit_prover_input = Main_Pack.circuit_prover_input + with type public_inputs = Scalar.t list = + Make_impl (Main_KZG) (Main_Pack) (PIs) + +module Make (PIs : Pi_parameters.S) = Make_raw (Main_KZG) (Main_Pack) (PIs) diff --git a/src/lib_aplonk/pi_parameters.ml b/src/lib_aplonk/pi_parameters.ml new file mode 100644 index 000000000000..9d35320dd92c --- /dev/null +++ b/src/lib_aplonk/pi_parameters.ml @@ -0,0 +1,103 @@ +module Main_Pack = Aggregation.Main_protocol +module L = Plompiler.LibCircuit + +(** Tells the meta-verification proof what to do with the public inputs + of the inner proofs *) +module type CircuitPI = sig + (** number of public inputs in an individual inner proof *) + val nb_inner : int + + (** total number of public inputs that are public for aPlonK *) + val nb_outer : int + + (** predicate (in circuit form) on all of PI of the inner proofs and outer PI. + giving the argument [[x_1;x_2];[y_1;y_2]] means that x_1 ; x_2 are resp. + the fst and second PI of the first inner proof and y_1;y_2 the fst and snd + PI of the snd inner proof *) + val check : + switches:bool L.repr list -> + outer:L.scalar L.repr list -> + inner:L.scalar L.repr list list -> + bool L.repr L.t + + (** create outer from inner PI; note that the existence of this function + restricts the outer PI to be computable from the inner PI. *) + val outer_of_inner : Main_Pack.scalar list list -> Main_Pack.scalar list +end + +module type S = sig + val get_pi_module : string -> (module CircuitPI) +end + +module No_public_input : CircuitPI = struct + let nb_inner = 0 + + let nb_outer = 0 + + let check ~switches:_ ~outer:_ ~inner:_ = L.Bool.constant_bool true + + let outer_of_inner _ = [] +end + +module One_public_input : CircuitPI = struct + let nb_inner = 1 + + let nb_outer = 0 + + let check ~switches:_ ~outer:_ ~inner:_ = L.Bool.constant_bool true + + let outer_of_inner _ = [] +end + +(* PI_parameters module designed for a rollup. There are 2 public inputs + per proof, for the initial and final state respectively; + everything is hidden expect the initial state of the very first proof & + the final state of the very last proof. *) +module Rollup_example : CircuitPI = struct + let nb_inner = 2 + + let nb_outer = 2 + + (* /!\ Note that this function assumes that the first proof is not turned + off by the switches (ie the first switch is true); + If the first proof is turned off, this function will NOT return the + expected result. *) + let check ~switches ~outer ~inner = + let open L in + (* we unroll the first iteration of the fold to start with a prec_out *) + let* last_out, rel_inner_pi = + fold2M + (fun (prec_out, res) inner_pi switch -> + match inner_pi with + | [current_in; current_out] -> + (* if switch is true then we compare the roots and replace the + old root by the new one; else we fill [ok] with true and keep + the old root for next comparison. *) + let* ok = + let* n_switch = Bool.bnot switch in + let* compare = equal prec_out current_in in + Bool.bor n_switch compare + in + let* out = Bool.ifthenelse switch current_out prec_out in + let res = ok :: res in + ret (out, res) + | _ -> failwith "Check_pi : invalid format for inner_pi.") + (List.nth (List.hd inner) 1, []) + (List.tl inner) + (List.tl switches) + in + match outer with + | [first_root; last_root] -> + let* first_root = equal first_root List.(hd (hd inner)) in + let* last_root = equal last_root last_out in + Bool.band_list ([first_root; last_root] @ rel_inner_pi) + | _ -> failwith "Check_pi : invalid format for outer_pi." + + let outer_of_inner inner_pi = + let rec get_last = function + | [[_; x]] -> x + | _ :: l -> get_last l + | _ -> failwith "outer_of_inner : wrong inner_pi format" + in + [List.(hd (hd inner_pi)); get_last inner_pi] +end -- GitLab From 6a27bcdbf2173aa10f3bee7c5a80a6269601390b Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Tue, 14 Mar 2023 15:18:45 +0100 Subject: [PATCH 14/34] Protocol environment: open plonk --- manifest/main.ml | 4 ++-- src/lib_protocol_environment/dune | 1 + src/lib_protocol_environment/structs/dune | 5 ++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/manifest/main.ml b/manifest/main.ml index 741e4616c113..ed3960895657 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -2469,7 +2469,7 @@ let octez_protocol_environment_structs = octez_scoru_wasm; data_encoding; bls12_381; - octez_plonk; + octez_plonk |> open_; ] let octez_protocol_environment = @@ -2498,7 +2498,7 @@ protocols.|} zarith; zarith_stubs_js; bls12_381; - octez_plonk; + octez_plonk |> open_; octez_crypto_dal; vdf; aches; diff --git a/src/lib_protocol_environment/dune b/src/lib_protocol_environment/dune index 1ca6ff51f9f8..8c95e6215a89 100644 --- a/src/lib_protocol_environment/dune +++ b/src/lib_protocol_environment/dune @@ -24,5 +24,6 @@ tezos-event-logging) (flags (:standard) + -open Plonk -open Tezos_base.TzPervasives -open Tezos_micheline)) diff --git a/src/lib_protocol_environment/structs/dune b/src/lib_protocol_environment/structs/dune index 8893e4b9cf64..9bf776a36493 100644 --- a/src/lib_protocol_environment/structs/dune +++ b/src/lib_protocol_environment/structs/dune @@ -12,4 +12,7 @@ tezos-scoru-wasm data-encoding bls12-381 - octez-plonk)) + octez-plonk) + (flags + (:standard) + -open Plonk)) -- GitLab From 5a85f0125fe8f1aed59c35386ae04bef93a07f97 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Tue, 14 Mar 2023 15:19:03 +0100 Subject: [PATCH 15/34] Protocol environment: change to use new interface of Plonk --- src/lib_protocol_environment/structs/v8_plonk.ml | 1 + 1 file changed, 1 insertion(+) diff --git a/src/lib_protocol_environment/structs/v8_plonk.ml b/src/lib_protocol_environment/structs/v8_plonk.ml index 303a3d8c1447..fe6f9fb9153f 100644 --- a/src/lib_protocol_environment/structs/v8_plonk.ml +++ b/src/lib_protocol_environment/structs/v8_plonk.ml @@ -35,6 +35,7 @@ let public_parameters_encoding = let scalar_array_encoding = Data_encoding.array scalar_encoding let verify pp inputs proof = + let inputs = List.map (fun (k, v) -> (k, (v, []))) inputs in Result.value ~default:false @@ Tezos_lwt_result_stdlib.Lwtreslib.Bare.Result.catch (fun () -> verify pp ~inputs:(Plonk.SMap.of_list inputs) proof) -- GitLab From a616b9a8b1f02980020dd1c6384f3cdbdac50997 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Fri, 17 Mar 2023 11:47:16 +0100 Subject: [PATCH 16/34] Proto alpha: change to use new interface of Plonk --- .../test/helpers/dummy_zk_rollup.ml | 41 +++++++++---------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/src/proto_alpha/lib_protocol/test/helpers/dummy_zk_rollup.ml b/src/proto_alpha/lib_protocol/test/helpers/dummy_zk_rollup.ml index 68d89f2c7ea9..d8288139f9f9 100644 --- a/src/proto_alpha/lib_protocol/test/helpers/dummy_zk_rollup.ml +++ b/src/proto_alpha/lib_protocol/test/helpers/dummy_zk_rollup.ml @@ -278,35 +278,35 @@ module V (L : LIB) = struct >* ret expected_new_state (** Circuit definition for one public operation *) - let predicate_op ?(public = true) ~old_state ~new_state ~fee ~exit_validity + let predicate_op ?(kind = `Public) ~old_state ~new_state ~fee ~exit_validity ~rollup_id op = - let* old_state = input ~public:true @@ Input.bool old_state in - let* new_state = input ~public:true @@ Input.bool new_state in + let* old_state = input ~kind:`Public @@ Input.bool old_state in + let* new_state = input ~kind:`Public @@ Input.bool new_state in let* (_fee : scalar repr) = - input ~public:true + input ~kind:`Public @@ E.((fee_encoding ~safety:Bounded_e.Unsafe).input) fee in let* (_exit_validity : bool repr) = - input ~public:true @@ Input.bool exit_validity + input ~kind:`Public @@ Input.bool exit_validity in let* rollup_id = - input ~public:true @@ E.(tezos_pkh_encoding.input) rollup_id + input ~kind:`Public @@ E.(tezos_pkh_encoding.input) rollup_id in - let* op = input ~public @@ E.op_encoding.input op in + let* op = input ~kind @@ E.op_encoding.input op in let op = E.op_encoding.decode op in let* expected_new_state = logic_op ~old_state ~rollup_id op in assert_equal expected_new_state new_state (** Circuit definition for a batch of private operations *) let predicate_batch ~old_state ~new_state ~fees ~rollup_id ops = - let* old_state = input ~public:true @@ Input.bool old_state in - let* new_state = input ~public:true @@ Input.bool new_state in + let* old_state = input ~kind:`Public @@ Input.bool old_state in + let* new_state = input ~kind:`Public @@ Input.bool new_state in let* (_fees : scalar repr) = - input ~public:true + input ~kind:`Public @@ E.((amount_encoding ~safety:Bounded_e.Unsafe).input) fees in let* rollup_id = - input ~public:true @@ E.(tezos_pkh_encoding.input) rollup_id + input ~kind:`Public @@ E.(tezos_pkh_encoding.input) rollup_id in let* ops = input @@ (Encodings.list_encoding E.op_encoding).input ops in let ops = (Encodings.list_encoding E.op_encoding).decode ops in @@ -320,10 +320,10 @@ module V (L : LIB) = struct (** Fee circuit *) let predicate_fees ~old_state ~new_state ~fees = - let* old_state = input ~public:true @@ Input.bool old_state in - let* new_state = input ~public:true @@ Input.bool new_state in + let* old_state = input ~kind:`Public @@ Input.bool old_state in + let* new_state = input ~kind:`Public @@ Input.bool new_state in let* (_fees : scalar repr) = - input ~public:true + input ~kind:`Public @@ E.((amount_encoding ~safety:Bounded_e.Unsafe).input) fees in assert_equal old_state new_state @@ -379,7 +379,7 @@ end = struct let lazy_srs = lazy - (let open Bls12_381_polynomial in + (let open Octez_bls12_381_polynomial.Bls12_381_polynomial in (Srs.generate_insecure 9 1, Srs.generate_insecure 1 1)) let dummy_l1_dst = @@ -504,7 +504,7 @@ end = struct insert "op" Plonk.Main_protocol. - {public = public_inputs; witness = private_inputs} + {witness = private_inputs; input_commitments = []} rev_inputs, ("op", pi_to_send) :: rev_pending_pis )) (s, rev_inputs, []) @@ -551,7 +551,7 @@ end = struct insert batch_name Plonk.Main_protocol. - {public = public_inputs; witness = private_inputs} + {witness = private_inputs; input_commitments = []} rev_inputs, (batch_name, pi_to_send) :: rev_private_pis )) (s, rev_inputs, []) @@ -570,17 +570,14 @@ end = struct let private_inputs = Solver.solve fee_solver public_inputs in ( insert "fee" - Plonk.Main_protocol.{public = public_inputs; witness = private_inputs} + Plonk.Main_protocol.{witness = private_inputs; input_commitments = []} rev_inputs, fee_pi ) in let inputs = SMap.map List.rev rev_inputs in - let proof = Plonk.Main_protocol.prove prover_pp ~inputs in let verifier_inputs = - Plonk.SMap.map - (List.map (fun Plonk.Main_protocol.{public; witness = _} -> public)) - inputs + Plonk.Main_protocol.to_verifier_inputs prover_pp inputs in assert ( Plonk.Main_protocol.verify public_parameters ~inputs:verifier_inputs proof) ; -- GitLab From e057fd8719a90ad16a9cba2d62f26aac3b4f1463 Mon Sep 17 00:00:00 2001 From: Victor Dumitrescu Date: Tue, 14 Mar 2023 16:42:08 +0100 Subject: [PATCH 17/34] Lib_plonk_distribution: import from privacy-team/distributed_plonk --- manifest/main.ml | 8 + .../plonk-distribution/dune | 11 + .../plonk-distribution/kzg.ml | 157 +++++++ .../plonk-distribution/kzg_pack.ml | 195 ++++++++ .../plonk-distribution/main_protocol.ml | 431 ++++++++++++++++++ .../plonk-distribution/polynomial_protocol.ml | 86 ++++ .../plonk-distribution/test/main.ml | 34 ++ .../test/test_polynomial_commitment.ml | 193 ++++++++ 8 files changed, 1115 insertions(+) create mode 100644 src/lib_distributed_plonk/plonk-distribution/dune create mode 100644 src/lib_distributed_plonk/plonk-distribution/kzg.ml create mode 100644 src/lib_distributed_plonk/plonk-distribution/kzg_pack.ml create mode 100644 src/lib_distributed_plonk/plonk-distribution/main_protocol.ml create mode 100644 src/lib_distributed_plonk/plonk-distribution/polynomial_protocol.ml create mode 100644 src/lib_distributed_plonk/plonk-distribution/test/main.ml create mode 100644 src/lib_distributed_plonk/plonk-distribution/test/test_polynomial_commitment.ml diff --git a/manifest/main.ml b/manifest/main.ml index ed3960895657..e5de33f1bde9 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1233,6 +1233,14 @@ let _octez_aplonk = ~preprocess:[pps ppx_repr] ~deps:[octez_plonk_aggregation] +let octez_plonk_distribution = + public_lib + "octez-plonk.distribution" + ~internal_name:"plonk_for_distribution" + ~path:"src/lib_distributed_plonk/plonk-distribution" + ~deps:[octez_plonk; octez_plonk_aggregation] + ~preprocess:[pps ppx_repr] + let _octez_srs_extraction_tests = tests ["main"] diff --git a/src/lib_distributed_plonk/plonk-distribution/dune b/src/lib_distributed_plonk/plonk-distribution/dune new file mode 100644 index 000000000000..db8eedde27da --- /dev/null +++ b/src/lib_distributed_plonk/plonk-distribution/dune @@ -0,0 +1,11 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name plonk_for_distribution) + (public_name octez-plonk.distribution) + (instrumentation (backend bisect_ppx)) + (libraries + octez-plonk + octez-plonk.aggregation) + (preprocess (pps ppx_repr))) diff --git a/src/lib_distributed_plonk/plonk-distribution/kzg.ml b/src/lib_distributed_plonk/plonk-distribution/kzg.ml new file mode 100644 index 000000000000..2cbe530f3c28 --- /dev/null +++ b/src/lib_distributed_plonk/plonk-distribution/kzg.ml @@ -0,0 +1,157 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk.Bls +open Plonk.Utils +module SMap = Plonk.SMap + +(** Extension of the PC signature with additional types and functions used + in by Distributed_prover *) + +module type Commitment_sig = sig + include Plonk.Polynomial_commitment.Commitment_sig + + val recombine : t list -> t + + val recombine_prover_aux : prover_aux list -> prover_aux + + val empty : t + + val empty_prover_aux : prover_aux +end + +module type PC_for_distribution_sig = sig + module BasePC : Plonk.Polynomial_commitment.S + + module Commitment : + Commitment_sig + with type secret = BasePC.secret + and type prover_public_parameters = BasePC.Public_parameters.prover + + include module type of BasePC with module Commitment := Commitment + + val merge_answers : answer list -> answer + + type worker_msg [@@deriving repr] + + type main_prover_state + + type main_prover_msg [@@deriving repr] + + type partial_prover_aux + + val distributed_expand_transcript : + transcript -> query list -> answer list -> transcript + + val distributed_prove_main1 : + Public_parameters.prover -> + transcript -> + query list -> + answer list -> + secret list -> + Commitment.prover_aux list -> + (* we assume the same message is sent to all workers *) + worker_msg * main_prover_state + + val distributed_prove_worker : + secret list -> Commitment.prover_aux list -> worker_msg -> main_prover_msg + + val distributed_prove_main2 : + main_prover_state -> + main_prover_msg list -> + proof * transcript * partial_prover_aux +end + +(** Extension of the KZG implementation with additional types and functions + used in by Distributed_prover *) +module Kzg_impl = struct + module BasePC = Plonk.Polynomial_commitment.Kzg_impl + include BasePC + + type worker_msg = Scalar.t SMap.t SMap.t [@@deriving repr] + + (* batched polynomials, keyed by evaluation points *) + type main_prover_msg = Poly.t SMap.t [@@deriving repr] + + type main_prover_state = { + srs : Public_parameters.prover; + transcript : transcript; + query : query; + batched_answer : Scalar.t SMap.t; + main_msg : main_prover_msg; + } + + type partial_prover_aux = unit + + let merge_answers : answer list -> answer = + let open SMap in + List.fold_left (union (fun _k m1 m2 -> Some (union_disjoint m1 m2))) empty + + module Commitment = struct + include Commitment + + let recombine cmt_list = + List.fold_left + (SMap.union (fun _k x _ -> Some x)) + (List.hd cmt_list) + (List.tl cmt_list) + + let recombine_prover_aux _ = () + + let empty = SMap.empty + + let empty_prover_aux = () + end + + let distributed_prove_worker f_map_list _prover_aux_list coeffs = + let f_map = group_secrets f_map_list in + batch_polys coeffs f_map + + let distributed_expand_transcript transcript query_list answer_list = + let transcript = Transcript.list_expand query_t query_list transcript in + Transcript.list_expand answer_t answer_list transcript + + let distributed_prove_main1 srs transcript query_list answer_list secret_list + prover_aux_list = + let query = group_queries query_list in + let answer = group_answers answer_list in + let y_map, transcript = sample_ys transcript query in + let batched_answer, coeffs = batch_answer y_map answer in + let main_msg = + distributed_prove_worker secret_list prover_aux_list coeffs + in + let state = {srs; transcript; query; batched_answer; main_msg} in + (coeffs, state) + + let distributed_prove_main2 {srs; transcript; query; batched_answer; main_msg} + batched_polys_list = + let batched_polys_list = main_msg :: batched_polys_list in + let batched_polys = + SMap.map_list_to_list_map batched_polys_list + |> SMap.map (List.fold_left Poly.add Poly.zero) + in + let proof = compute_Ws srs batched_polys batched_answer query in + (proof, Transcript.expand proof_t proof transcript, ()) +end diff --git a/src/lib_distributed_plonk/plonk-distribution/kzg_pack.ml b/src/lib_distributed_plonk/plonk-distribution/kzg_pack.ml new file mode 100644 index 000000000000..c8c10be5d2fc --- /dev/null +++ b/src/lib_distributed_plonk/plonk-distribution/kzg_pack.ml @@ -0,0 +1,195 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk.Bls +open Plonk.Utils +module SMap = Plonk.SMap + +module type Super_PC_sig = sig + include Kzg.PC_for_distribution_sig + + type prover_aux = {r : Scalar.t; s_list : Scalar.t SMap.t list} + + val prove_super_aggregation : + Public_parameters.prover -> + transcript -> + Poly.t SMap.t list -> + Commitment.prover_aux list -> + query list -> + Scalar.t SMap.t SMap.t list -> + (proof * prover_aux) * transcript + + val verify_super_aggregation : + Public_parameters.verifier -> + transcript -> + Commitment.t list -> + query list -> + Scalar.t SMap.t list -> + proof -> + bool * Scalar.t * transcript +end + +(** Extension of the KZG_pack implementation with additional + types and functions used in by Distributed_prover *) +module Kzg_pack_impl = struct + module Pack = Aggregation.Pack + module PC = Kzg.Kzg_impl + module BasePC = Aggregation.Polynomial_commitment.Make_impl (PC) + + module Commitment = struct + include BasePC.Commitment + + let recombine l = List.fold_left Pack.combine (List.hd l) (List.tl l) + + let recombine_prover_aux l = + let cm = PC.Commitment.recombine (List.map fst l) in + let p_a = PC.Commitment.recombine_prover_aux (List.map snd l) in + (cm, p_a) + + let empty = Pack.empty_commitment + + let empty_prover_aux = (PC.Commitment.empty, PC.Commitment.empty_prover_aux) + end + + include (BasePC : module type of BasePC with module Commitment := Commitment) + + type worker_msg = Scalar.t * string list list [@@deriving repr] + + type main_prover_msg = Poly.t list * Commitment.prover_aux list + [@@deriving repr] + + type main_prover_state = + Public_parameters.prover + * transcript + * Scalar.t + * query list + * Scalar.t SMap.t list + * main_prover_msg + + type partial_prover_aux = {r : Scalar.t; s_list : Scalar.t SMap.t list} + + let merge_answers : answer list -> answer = + let open SMap in + List.fold_left (union (fun _k m1 m2 -> Some (union_disjoint m1 m2))) empty + + let distributed_prove_worker f_map_list prover_aux_list (r, poly_keys_list) = + let gen_powers r l = + List.mapi (fun i x -> (x, Scalar.pow r @@ Z.of_int i)) l |> SMap.of_list + in + let r_powers_list = List.map (gen_powers r) poly_keys_list in + let f_list = + List.map2 + (fun f_map r_map -> + let polys = SMap.bindings f_map in + let coeffs = List.map (fun (name, _) -> SMap.find name r_map) polys in + Poly.linear (List.map snd polys) coeffs) + f_map_list + r_powers_list + in + (f_list, prover_aux_list) + + let distributed_expand_transcript transcript query_list answer_list = + let transcript = Transcript.list_expand query_t query_list transcript in + Transcript.list_expand answer_t answer_list transcript + + let distributed_prove_main1 (pp : Public_parameters.prover) transcript + query_list answer_list secret_list prover_aux_list : + worker_msg * main_prover_state = + let r, transcript = Fr_generation.random_fr transcript in + let s_list = List.map (batch_answers r) answer_list in + + let get_keys map_map = + SMap.fold + (fun _ m acc -> SMap.union (fun _ _ x -> Some x) m acc) + map_map + SMap.empty + |> SMap.bindings |> List.map fst + in + let poly_keys_list = List.map get_keys answer_list in + let worker_message = (r, poly_keys_list) in + (* The main thread simulates a worker, since it is the only one who knows + the information about t_map, g_map, plook_map. We need to pad a dummy + secret and a dummy prover_aux at the end, corresponding to f_map, which + the main thread does not have information about. *) + let main_msg = + distributed_prove_worker secret_list prover_aux_list worker_message + in + let state = (pp, transcript, r, query_list, s_list, main_msg) in + (worker_message, state) + + let distributed_prove_main2 + ((pp, transcript, r, query_list, s_list, main_msg) : main_prover_state) + worker_msg_list = + let worker_msg_list = main_msg :: worker_msg_list in + let f_list_list = List.map fst worker_msg_list in + let f_list = + Plonk.List.mapn (List.fold_left Poly.add Poly.zero) f_list_list + in + let prover_aux_list_list = List.map snd worker_msg_list in + let prover_aux_list = + Plonk.List.mapn Commitment.recombine_prover_aux prover_aux_list_list + in + (* [cmts_list] is a list of G1.t SMap.t, containing the PC commitments to + every polynomial (note that PC.Commitment.t = Bls12_381.G1.t SMap.t) *) + let cmts_list = + List.map + (fun (cmts, _prover_aux) -> + List.map snd @@ SMap.bindings cmts |> Array.of_list) + prover_aux_list + in + (* [packed_values] has type [G1.t list] and it is the result of batching + each map in [cmt_list] with powers of [r]. + [pack_proof] asserts that [packed_values] was correctly computed. *) + let (packed_values, pack_proof), transcript = + Pack.prove pp.pp_pack_prover transcript r cmts_list + in + (* prepare [f_list] and [s_list], the batched version of [f_map_list] + polys and [answer_list] (using randomness [r]) by selecting a dummy + name for them [string_of_int i] in order to call the underlying PC *) + let f_map_list = + List.mapi (fun i l -> SMap.singleton (string_of_int i) l) f_list + in + let s_map_list = + List.mapi + (fun i m -> SMap.map (fun s -> SMap.singleton (string_of_int i) s) m) + s_list + in + let prover_aux_list = List.map snd prover_aux_list in + (* call the underlying PC prover on the batched polynomials/evaluations + the verifier will verify such proof using [packed_values] as the + commitments *) + let pc_proof, transcript = + PC.prove + pp.pp_pc_prover + transcript + f_map_list + prover_aux_list + query_list + s_map_list + in + let proof = {pc_proof; packed_values; pack_proof} in + let transcript = Transcript.expand proof_t proof transcript in + (proof, transcript, {s_list; r}) +end diff --git a/src/lib_distributed_plonk/plonk-distribution/main_protocol.ml b/src/lib_distributed_plonk/plonk-distribution/main_protocol.ml new file mode 100644 index 000000000000..56b3f6a02ed9 --- /dev/null +++ b/src/lib_distributed_plonk/plonk-distribution/main_protocol.ml @@ -0,0 +1,431 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk.Bls +open Plonk.Utils +open Plonk.Identities +module SMap = Plonk.SMap + +let nb_wires = Plompiler.Csir.nb_wires_arch + +module type S = sig + module PP : Polynomial_protocol.S + + type proof = { + perm_and_plook : PP.PC.Commitment.t; + wires_cm : PP.PC.Commitment.t; + pp_proof : PP.proof; + } + + include Plonk.Main_protocol_intf.S with type proof := proof + + type gate_randomness = { + beta_perm : Scalar.t; + gamma_perm : Scalar.t; + beta_plook : Scalar.t; + gamma_plook : Scalar.t; + beta_rc : Scalar.t; + gamma_rc : Scalar.t; + delta : Scalar.t; + } + + val build_gates_randomness : bytes -> gate_randomness * bytes + + val filter_prv_pp_circuits : + prover_public_parameters -> 'a SMap.t -> prover_public_parameters + + val hash_verifier_inputs : verifier_inputs -> bytes + + module Prover : sig + val commit_to_wires : + ?all_keys:string list -> + ?shifts_map:(int * int) SMap.t -> + prover_public_parameters -> + circuit_prover_input list SMap.t -> + Evaluations.t SMap.t list SMap.t + * Poly.t SMap.t list SMap.t + * Poly.t SMap.t option list SMap.t + * Poly.t SMap.t + * Input_commitment.public + * PP.PC.Commitment.prover_aux + + val build_evaluations : + prover_public_parameters -> + Evaluations.polynomial SMap.t -> + Evaluations.t SMap.t + + val build_f_map_plook : + ?shifts_map:(int * int) SMap.t -> + prover_public_parameters -> + gate_randomness -> + Evaluations.t SMap.t list SMap.t -> + Poly.t SMap.t + + val batched_wires_poly_of_batched_wires : + prover_public_parameters -> + Evaluations.t SMap.t -> + Scalar.t * Poly.t SMap.t option list -> + Poly.t SMap.t + + val build_batched_wires_values : + gate_randomness -> + Evaluations.t SMap.t list SMap.t -> + Evaluations.t SMap.t SMap.t + + val build_f_map_perm : + prover_public_parameters -> + gate_randomness -> + Evaluations.t SMap.t SMap.t -> + Poly.t SMap.t + + val build_perm_identities : + prover_public_parameters -> gate_randomness -> prover_identities + + val build_gates_plook_rc_identities : + ?shifts_map:(int * int) SMap.t -> + prover_public_parameters -> + gate_randomness -> + circuit_prover_input list SMap.t -> + prover_identities + end + + type worker_inputs [@@deriving repr] + + val split_inputs_map : + nb_workers:int -> + circuit_prover_input list SMap.t -> + worker_inputs SMap.t list + + type commit_to_wires_reply = PP.PC.Commitment.t [@@deriving repr] + + (* shifts_maps binds circuits names to pairs of integers. + 'c1' -> (7, 20) means that 20 proofs are expected for circuit 'c1' and + there must be a shift of 7 in indexing considering the worker is starting + at proof No. 7 *) + type commit_to_wires_remember = { + all_f_wires : Poly.t SMap.t; + wires_list_map : Evaluations.t SMap.t list SMap.t; + inputs_map : circuit_prover_input list SMap.t; + shifts_map : (int * int) SMap.t; + f_wires : Poly.t SMap.t list SMap.t; + cm_aux_wires : PP.PC.Commitment.prover_aux; + } + + val worker_commit_to_wires : + prover_public_parameters -> + worker_inputs SMap.t -> + commit_to_wires_reply * commit_to_wires_remember + + type commit_to_plook_rc_reply = { + batched_wires_map : Evaluations.t SMap.t SMap.t; + cmt : PP.PC.Commitment.t; + f_map : Poly.t SMap.t; + prover_aux : PP.PC.Commitment.prover_aux; + } + [@@deriving repr] + + type commit_to_plook_rc_remember = { + beta_plook : scalar; + gamma_plook : scalar; + beta_rc : scalar; + gamma_rc : scalar; + } + + val commit_to_plook_rc : + prover_public_parameters -> + (int * int) SMap.t -> + bytes -> + Evaluations.t SMap.t list SMap.t -> + commit_to_plook_rc_reply * commit_to_plook_rc_remember + + val batch_evaluated_ids : + alpha:scalar -> Evaluations.t SMap.t -> string list -> Evaluations.t + + val kzg_eval_at_x : + prover_public_parameters -> + PP.transcript -> + (PP.PC.secret * PP.PC.Commitment.prover_aux) list -> + scalar -> + PP.PC.answer list + + val shared_perm_argument : + prover_public_parameters -> + int -> + gate_randomness -> + 'a list SMap.t -> + commit_to_plook_rc_reply list -> + Poly.t SMap.t + * Evaluations.t SMap.t + * (commit_to_wires_reply * PP.PC.Commitment.prover_aux) + + val make_secret : + prover_public_parameters -> + Poly.t SMap.t * PP.PC.Commitment.prover_aux -> + (Poly.t SMap.t * PP.PC.Commitment.prover_aux) list + + val make_eval_points : + prover_public_parameters -> eval_point list list * eval_point list list + + val get_srs : prover_public_parameters -> PP.prover_public_parameters + + (** Returns (g, n, nb_t), where n is the size of the circuit padded to the + next power of two, g is a primitive n-th root of unity, & nb_t is the + number of T polynomials in the answers + *) + val get_gen_n_nbt : prover_public_parameters -> scalar * int * int + + val get_transcript : prover_public_parameters -> bytes + + val check_no_zk : prover_public_parameters -> unit +end + +(* [build_all_keys strs shifts_map] returns a list of prefixed [strs], + deduced from the [shifts_map] (that contains circuits names binded with, + among others, the number of proofs) that corresponds to all the + names of the [strs] polynomials that will be committed for the proof +*) +let build_all_keys names shifts_map = + let build_all_names prefix n name = + List.init n (fun i -> SMap.Aggregation.add_prefix ~n ~i prefix name) + in + SMap.mapi + (fun prefix (_i, n) -> + List.concat_map (build_all_names prefix n) names + |> List.sort String.compare) + shifts_map + |> SMap.values |> List.concat + +module Common (PP : Polynomial_protocol.S) = struct + open Plonk.Main_protocol.Make_impl (PP) + + open Prover + module Commitment = PP.PC.Commitment + + type commit_to_wires_reply = Commitment.t [@@deriving repr] + + type worker_inputs = {inputs : circuit_prover_input list; shift : int * int} + [@@deriving repr] + + let split_inputs_map ~nb_workers inputs_map = + let list_range i1 i2 = List.filteri (fun i _ -> i1 <= i && i < i2) in + List.map + (fun i -> + SMap.map + (fun l -> + let n = List.length l in + let chunk_size = + Z.(cdiv (of_int n) (of_int nb_workers) |> to_int) + in + let inputs = list_range (chunk_size * i) (chunk_size * (i + 1)) l in + let shift = (chunk_size * i, n) in + {inputs; shift}) + inputs_map) + (List.init nb_workers Fun.id) + + type commit_to_plook_rc_reply = { + batched_wires_map : Evaluations.t SMap.t SMap.t; + cmt : Commitment.t; + f_map : Poly.t SMap.t; + prover_aux : Commitment.prover_aux; + } + [@@deriving repr] + + type commit_to_plook_rc_remember = { + beta_plook : scalar; + gamma_plook : scalar; + beta_rc : scalar; + gamma_rc : scalar; + } + + type commit_to_wires_remember = { + all_f_wires : Poly.t SMap.t; + wires_list_map : Evaluations.t SMap.t list SMap.t; + inputs_map : circuit_prover_input list SMap.t; + shifts_map : (int * int) SMap.t; + f_wires : Poly.t SMap.t list SMap.t; + cm_aux_wires : Commitment.prover_aux; + } + + let worker_commit_to_wires pp worker_inputs_map = + let inputs_map = SMap.map (fun wi -> wi.inputs) worker_inputs_map in + let shifts_map = SMap.map (fun wi -> wi.shift) worker_inputs_map in + let all_keys = build_all_keys (get_wires_names nb_wires) shifts_map in + let wires_list_map, f_wires, _, all_f_wires, cm_wires, cm_aux_wires = + commit_to_wires ~all_keys ~shifts_map pp inputs_map + in + ( cm_wires, + { + all_f_wires; + wires_list_map; + inputs_map; + shifts_map; + f_wires; + cm_aux_wires; + } ) + + let commit_to_plook_rc pp shifts_map transcript f_wires_list_map = + let rd, _transcript = build_gates_randomness transcript in + let batched_wires_map = build_batched_wires_values rd f_wires_list_map in + (* ******************************************* *) + let f_map_plook = build_f_map_plook ~shifts_map pp rd f_wires_list_map in + let f_map_rc = + Prover.build_f_map_range_checks ~shifts_map pp rd f_wires_list_map + in + let f_map = SMap.union_disjoint f_map_plook f_map_rc in + (* commit to the plookup polynomials *) + let cmt, prover_aux = + (* FIXME: implement Plookup *) + let all_keys = build_all_keys ["plook"; "RC"] shifts_map in + PP.PC.Commitment.commit ~all_keys pp.common_pp.pp_public_parameters f_map + in + ( {batched_wires_map; cmt; f_map; prover_aux}, + { + beta_plook = rd.beta_plook; + gamma_plook = rd.gamma_plook; + beta_rc = rd.beta_rc; + gamma_rc = rd.gamma_rc; + } ) + + let batch_evaluated_ids ~alpha evaluated_ids all_ids_keys = + let powers_map = + SMap.of_list @@ List.mapi (fun i s -> (s, i)) all_ids_keys + in + let ids_keys, evaluations = List.split @@ SMap.bindings evaluated_ids in + let powers = + List.map (fun s -> SMap.find s powers_map) ids_keys + |> List.map (fun i -> Scalar.pow alpha @@ Z.of_int i) + in + Evaluations.linear_c ~evaluations ~linear_coeffs:powers () + + let kzg_eval_at_x pp transcript secrets_worker generator = + let eval_points_worker = + [List.hd @@ List.rev @@ pp.common_pp.eval_points] + in + let x, _transcript = Fr_generation.random_fr transcript in + let polys_list_worker = List.map fst secrets_worker in + let query_list_worker = + List.map (convert_eval_points ~generator ~x) eval_points_worker + in + List.map2 PP.PC.evaluate polys_list_worker query_list_worker + + (* Same as Plonk.Main_protocol.build_batched_witness_poly, but the IFFT + version every times. + Because I don’t know how to use f_wires in distributed_prover + *) + let build_batched_witness_polys_bis pp batched_witnesses = + let batched_witness_polys = + SMap.map + (fun batched_witness -> + (* we apply an IFFT on the batched witness *) + batched_wires_poly_of_batched_wires + pp + batched_witness + (Scalar.zero, [])) + batched_witnesses + in + batched_witness_polys |> SMap.Aggregation.smap_of_smap_smap + + let shared_perm_argument pp nb_workers randomness inputs_map replies = + let recombine_batched_wires pieces = + (* we want the last worker to be first to apply Horner's method *) + let pieces = List.rev pieces in + List.fold_left + (fun acc m -> + SMap.union + (fun circuit_name witness_acc witness_m -> + let n = List.length (SMap.find circuit_name inputs_map) in + let chunk_size = Z.(cdiv (of_int n) (of_int nb_workers)) in + let delta_factor = Scalar.pow randomness.delta chunk_size in + let sum = + SMap.mapi + (fun i w_acc -> + let w = SMap.find i witness_m in + Evaluations.(add w (mul_by_scalar delta_factor w_acc))) + witness_acc + in + Some sum) + acc + m) + (List.hd pieces) + (List.tl pieces) + in + let batched_wires_map = + recombine_batched_wires (List.map (fun r -> r.batched_wires_map) replies) + in + let open Prover in + let f_map_perm = build_f_map_perm pp randomness batched_wires_map in + + let evaluated_perm_ids = + let evaluations = + let batched_wires_polys = + build_batched_witness_polys_bis pp batched_wires_map + in + build_evaluations + pp + (SMap.union_disjoint f_map_perm batched_wires_polys) + in + (build_perm_identities pp randomness) evaluations + in + let cmt = Commitment.commit pp.common_pp.pp_public_parameters f_map_perm in + + (f_map_perm, evaluated_perm_ids, cmt) + + let make_secret pp (f_map, f_prv_aux) = + [(pp.common_pp.g_map, pp.common_pp.g_prover_aux); (f_map, f_prv_aux)] + + let make_eval_points pp = Plonk.List.split_n 2 pp.common_pp.eval_points + + let get_generator pp = Domain.get pp.common_pp.domain 1 + + let get_srs pp = pp.common_pp.pp_public_parameters + + let get_gen_n_nbt pp = + ( Domain.get pp.common_pp.domain 1, + pp.common_pp.n, + pp.common_pp.nb_of_t_chunks ) + + let get_transcript pp = pp.transcript + + let check_no_zk pp = + if pp.common_pp.zk then failwith "Distribution with ZK is not supported" +end + +module Make (PP : Polynomial_protocol.S) = struct + module PP = PP + module MP = Plonk.Main_protocol.Make_impl (PP) + + include (MP : module type of MP with module PP := PP) + + include Common (PP) +end + +module MakeSuper (PP : Polynomial_protocol.Super) = struct + module PP = PP + module MP = Aggregation.Main_protocol.Make_impl (PP) + + include (MP : module type of MP with module PP := PP) + + include Common (PP) +end diff --git a/src/lib_distributed_plonk/plonk-distribution/polynomial_protocol.ml b/src/lib_distributed_plonk/plonk-distribution/polynomial_protocol.ml new file mode 100644 index 000000000000..4ea419ef1df8 --- /dev/null +++ b/src/lib_distributed_plonk/plonk-distribution/polynomial_protocol.ml @@ -0,0 +1,86 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk.Bls + +module type S = sig + module PC : Kzg.PC_for_distribution_sig + + include Plonk.Polynomial_protocol.S with module PC := PC + + (** [compute_t ~n ~alpha evaluations] returns a polynomial T splitted in chunks, + where [T(X) = (sum_i alpha^i evaluations[i]) / (X^n - 1)] and the returned + chunks [{ 'T_0' -> T0; 'T_1' -> T1; 'T_2' -> T2 }] are such that + [T = T0 + X^n T1 + X^{2n} T2]. *) + val compute_t : + n:int -> + alpha:Scalar.t -> + nb_of_t_chunks:int -> + Evaluations.t Plonk.SMap.t -> + Evaluations.polynomial Plonk.SMap.t +end + +module type Super = sig + module PC : Kzg_pack.Super_PC_sig + + include Aggregation.Polynomial_protocol.S with module PC := PC + + (** [compute_t ~n ~alpha evaluations] returns a polynomial T splitted in chunks, + where [T(X) = (sum_i alpha^i evaluations[i]) / (X^n - 1)] and the returned + chunks [{ 'T_0' -> T0; 'T_1' -> T1; 'T_2' -> T2 }] are such that + [T = T0 + X^n T1 + X^{2n} T2]. *) + val compute_t : + n:int -> + alpha:Scalar.t -> + nb_of_t_chunks:int -> + Evaluations.t Plonk.SMap.t -> + Evaluations.polynomial Plonk.SMap.t +end + +module Make (PC : Kzg.PC_for_distribution_sig) : S with module PC = PC = struct + module PP = Plonk.Polynomial_protocol.Make_impl (PC) + module PC = PC + + let compute_t = PP.compute_t + + include (PP : Plonk.Polynomial_protocol.S with module PC := PC) +end + +module MakeSuper + (PC : Kzg_pack.Super_PC_sig) + (Answers_commitment : Plonk.Input_commitment.S) : + Super with module PC = PC with module Answers_commitment = Answers_commitment = +struct + module PP = + Aggregation.Polynomial_protocol.Make_impl (PC) (Answers_commitment) + module PC = PC + module Answers_commitment = Answers_commitment + + include ( + PP : + module type of PP + with module PC := PC + with module Answers_commitment := Answers_commitment) +end diff --git a/src/lib_distributed_plonk/plonk-distribution/test/main.ml b/src/lib_distributed_plonk/plonk-distribution/test/main.ml new file mode 100644 index 000000000000..8d7db892e6fc --- /dev/null +++ b/src/lib_distributed_plonk/plonk-distribution/test/main.ml @@ -0,0 +1,34 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk_test + +let () = + Helpers.with_seed (fun () -> + Helpers.with_output_to_file (fun () -> + Alcotest.run + ~verbose:false + "PlonK" + [("Polynomial_commitment", Test_polynomial_commitment.tests)])) diff --git a/src/lib_distributed_plonk/plonk-distribution/test/test_polynomial_commitment.ml b/src/lib_distributed_plonk/plonk-distribution/test/test_polynomial_commitment.ml new file mode 100644 index 000000000000..4c9ba075ddf3 --- /dev/null +++ b/src/lib_distributed_plonk/plonk-distribution/test/test_polynomial_commitment.ml @@ -0,0 +1,193 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk.Bls +open Plonk.Utils + +module External (PC : Plonk_for_distribution.Kzg.PC_for_distribution_sig) = +struct + module SMap = Plonk.SMap + + let generate_random_poly degree = + Poly.of_coefficients (List.init degree (fun i -> (Scalar.random (), i))) + + let generate_f_map ~prefix degree n = + let generate_f i = + (prefix ^ "|" ^ string_of_int i, generate_random_poly degree) + in + SMap.of_list (List.init n generate_f) + + type instance = { + pp_prover : PC.Public_parameters.prover; + pp_verifier : PC.Public_parameters.verifier; + f_map_list : Poly.t SMap.t list; + cmt_list : PC.Commitment.t list; + prover_aux_list : PC.Commitment.prover_aux list; + transcript : Bytes.t; + query_list : Scalar.t SMap.t list; + answer_list : PC.answer list; + } + + let generate_instance ~nb_batches ~nb_polys_per_batch = + let max_degree = 20 in + let pp_prover, pp_verifier = + PC.Public_parameters.setup (2 * nb_polys_per_batch) Plonk_test.Helpers.srs + in + let f_map_list = + List.init nb_batches (fun i -> + generate_f_map ~prefix:(string_of_int i) max_degree nb_polys_per_batch) + in + let cmt_list, prover_aux_list = + List.map (PC.Commitment.commit pp_prover) f_map_list |> List.split + in + let transcript = + Transcript.list_expand PC.Commitment.t cmt_list Bytes.empty + in + let x1 = Scalar.random () in + let x2 = Scalar.random () in + let just_x1 = SMap.singleton "x1" x1 in + let both_points = SMap.of_list [("x1", x1); ("x2", x2)] in + let query_list = + just_x1 :: List.init (nb_batches - 1) (fun _ -> both_points) + in + let answer_list = List.map2 PC.evaluate f_map_list query_list in + { + pp_prover; + pp_verifier; + f_map_list; + cmt_list; + prover_aux_list; + transcript; + query_list; + answer_list; + } + + let prove_distributed instance = + let main_secrets, worker_secrets = + List.map + (let b = Random.bool () in + SMap.partition (fun _ _ -> b)) + instance.f_map_list + |> List.split + in + let secrets1, secrets2 = + List.map (SMap.partition (fun _ _ -> Random.bool ())) worker_secrets + |> List.split + in + let transcript = + PC.distributed_expand_transcript + instance.transcript + instance.query_list + instance.answer_list + in + let worker_msg, state = + PC.distributed_prove_main1 + instance.pp_prover + transcript + instance.query_list + instance.answer_list + main_secrets + instance.prover_aux_list + in + let main_prover_msg1 = + PC.distributed_prove_worker secrets1 instance.prover_aux_list worker_msg + in + let main_prover_msg2 = + PC.distributed_prove_worker secrets2 instance.prover_aux_list worker_msg + in + PC.distributed_prove_main2 state [main_prover_msg1; main_prover_msg2] + + let prove_and_verify_instance ?(wrong_transcript = false) + ?(distributed = false) instance = + let proof, prover_final_transcript = + if distributed then + let proof, transcript, _aux = prove_distributed instance in + (proof, transcript) + else + PC.prove + instance.pp_prover + instance.transcript + instance.f_map_list + instance.prover_aux_list + instance.query_list + instance.answer_list + in + + let b, verifier_final_transcript = + PC.verify + instance.pp_verifier + (if wrong_transcript then Bytes.empty else instance.transcript) + instance.cmt_list + instance.query_list + instance.answer_list + proof + in + + (* This should hold as long as they input the same query list, + the same answer list and start from the same transcript (where + we should typically have included the cmt list *) + if not wrong_transcript then + assert (Bytes.equal prover_final_transcript verifier_final_transcript) ; + b + + let test_correctness () = + let instance = generate_instance ~nb_batches:4 ~nb_polys_per_batch:16 in + assert (prove_and_verify_instance instance) + + let test_correctness_distribution () = + let instance = generate_instance ~nb_batches:4 ~nb_polys_per_batch:16 in + assert (prove_and_verify_instance ~distributed:true instance) + + let test_wrong_answer () = + let instance = generate_instance ~nb_batches:4 ~nb_polys_per_batch:8 in + let first_answer = List.hd instance.answer_list in + let key, outputs = SMap.choose first_answer in + let first_answer' = + SMap.add key (SMap.map (fun _ -> Scalar.random ()) outputs) first_answer + in + let instance' = + { + instance with + answer_list = first_answer' :: List.tl instance.answer_list; + } + in + assert (not @@ prove_and_verify_instance instance') + + let test_wrong_transcript () = + let instance = generate_instance ~nb_batches:4 ~nb_polys_per_batch:8 in + assert (not @@ prove_and_verify_instance ~wrong_transcript:true instance) +end + +module KZG_Tests = External (Plonk_for_distribution.Kzg.Kzg_impl) +module KZG_Pack_Tests = External (Plonk_for_distribution.Kzg_pack.Kzg_pack_impl) + +let tests = + List.map + (fun (name, f) -> Alcotest.test_case name `Quick f) + [ + ("distr. correctness (KZG)", KZG_Tests.test_correctness_distribution); + ( "distr. correctness (KZG_Pack)", + KZG_Pack_Tests.test_correctness_distribution ); + ] -- GitLab From 5266bbcaa78a7c09f28b822b5338497d540a80e3 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Tue, 14 Mar 2023 19:50:44 +0100 Subject: [PATCH 18/34] octez-plonk.plonk-test: import from nomadic-labs/cryptography --- manifest/main.ml | 9 + opam/octez-plonk.opam | 1 + src/lib_plonk/test/cases.ml | 764 ++++++++++++++++++++++++++++++++++ src/lib_plonk/test/dune | 13 + src/lib_plonk/test/helpers.ml | 541 ++++++++++++++++++++++++ 5 files changed, 1328 insertions(+) create mode 100644 src/lib_plonk/test/cases.ml create mode 100644 src/lib_plonk/test/dune create mode 100644 src/lib_plonk/test/helpers.ml diff --git a/manifest/main.ml b/manifest/main.ml index e5de33f1bde9..46b78e11ebd0 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1241,6 +1241,15 @@ let octez_plonk_distribution = ~deps:[octez_plonk; octez_plonk_aggregation] ~preprocess:[pps ppx_repr] +let _octez_plonk_test_helpers = + public_lib + "octez-plonk.plonk-test" + ~path:"src/lib_plonk/test" + ~internal_name:"plonk_test" + ~deps:[octez_plonk; octez_plonk_aggregation; octez_plonk_distribution] + ~modules:["helpers"; "cases"] + ~preprocess:[pps ppx_repr] + let _octez_srs_extraction_tests = tests ["main"] diff --git a/opam/octez-plonk.opam b/opam/octez-plonk.opam index 39110858ecda..0e9a9ac61612 100644 --- a/opam/octez-plonk.opam +++ b/opam/octez-plonk.opam @@ -16,6 +16,7 @@ depends: [ "data-encoding" { >= "0.7.1" & < "1.0.0" } "octez-bls12-381-polynomial" "octez-plompiler" + "qcheck-alcotest" { >= "0.20" } ] build: [ ["rm" "-r" "vendors"] diff --git a/src/lib_plonk/test/cases.ml b/src/lib_plonk/test/cases.ml new file mode 100644 index 000000000000..2494ed91fafd --- /dev/null +++ b/src/lib_plonk/test/cases.ml @@ -0,0 +1,764 @@ +open Plonk +module Scalar = Bls.Scalar + +let ( ! ) = List.map Scalar.of_int + +let ( !! ) l = List.map Scalar.of_int l |> Array.of_list + +type outcome = Valid | Proof_error | Lookup_error + +type case = { + name : string; + circuit : Circuit.t; + witness : Scalar.t array; + outcome : outcome; +} + +(* This function aggregates cases ; if several cases concern the same circuit, + it becomes a circuit with several statements *) +let aggregate_cases ?(prefix = "") cases = + let outcome = (List.hd cases).outcome in + let name, circuits_map, inputs_map, outcome = + List.fold_left + (fun (name, circuits_map, inputs_map, outcome) case -> + assert (outcome = case.outcome) ; + let circuit = case.circuit in + let other_inputs = + Option.value ~default:[] @@ SMap.find_opt case.name inputs_map + in + let inputs = case.witness :: other_inputs in + SMap. + ( (if name = "" then case.name else name ^ "+" ^ case.name), + add case.name (circuit, List.length inputs) circuits_map, + add case.name inputs inputs_map, + outcome )) + SMap.(prefix, empty, empty, outcome) + cases + in + let inputs_map = SMap.map List.rev inputs_map in + (name, circuits_map, inputs_map, outcome) + +module Unit_tests_for_each_selector = struct + (* ---- Unit tests for each selector. ---- + We make circuits with 2 constraints, + as circuits with 1 constraint are not supported. *) + + let qc = + let name = "qc" in + let witness = !![0; 1] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 0] ~b:[0; 0] ~c:[0; 1] ~d:[0; 0] ~e:[0; 0] () + in + let gates = Circuit.make_gates ~qo:![0; -1] ~qc:![0; 1] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let ql = + let name = "ql" in + let witness = !![0; 1] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 1] ~b:[0; 0] ~c:[0; 1] ~d:[0; 0] ~e:[0; 0] () + in + let gates = Circuit.make_gates ~ql:![1; 1] ~qo:![0; -1] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qr = + let name = "qr" in + let witness = !![0; 1] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 0] ~b:[0; 1] ~c:[0; 1] ~d:[0; 0] ~e:[0; 0] () + in + let gates = Circuit.make_gates ~qr:![1; 1] ~qo:![0; -1] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qd = + let name = "qd" in + let witness = !![0; 1] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 0] ~b:[0; 0] ~c:[0; 1] ~d:[0; 1] ~e:[0; 0] () + in + let gates = Circuit.make_gates ~qd:![1; 1] ~qo:![0; -1] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qe = + let name = "qe" in + let witness = !![0; 1] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 0] ~b:[0; 0] ~c:[0; 1] ~d:[0; 0] ~e:[0; 1] () + in + let gates = Circuit.make_gates ~qe:![1; 1] ~qo:![0; -1] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qlg = + let name = "qlg" in + let witness = !![0; 1] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 1] ~b:[0; 0] ~c:[1; 0] ~d:[0; 0] ~e:[0; 0] () + in + let gates = Circuit.make_gates ~qlg:![1; 0] ~qo:![-1; 0] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qrg = + let name = "qrg" in + let witness = !![0; 1] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 0] ~b:[0; 1] ~c:[1; 0] ~d:[0; 0] ~e:[0; 0] () + in + let gates = Circuit.make_gates ~qrg:![1; 0] ~qo:![-1; 0] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qog = + let name = "qog" in + let witness = !![0; 1] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 0] ~b:[0; 0] ~c:[1; 1] ~d:[0; 0] ~e:[0; 0] () + in + let gates = Circuit.make_gates ~qog:![1; 0] ~qo:![-1; 0] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qdg = + let name = "qdg" in + let witness = !![0; 1] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 0] ~b:[0; 0] ~c:[1; 0] ~d:[0; 1] ~e:[0; 0] () + in + let gates = Circuit.make_gates ~qdg:![1; 0] ~qo:![-1; 0] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qeg = + let name = "qeg" in + let witness = !![0; 1] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 0] ~b:[0; 0] ~c:[1; 0] ~d:[0; 0] ~e:[0; 1] () + in + let gates = Circuit.make_gates ~qeg:![1; 0] ~qo:![-1; 0] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qm = + let name = "qm" in + let witness = !![0; 1] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 1] ~b:[1; 1] ~c:[0; 1] ~d:[0; 0] ~e:[0; 0] () + in + let gates = Circuit.make_gates ~qm:![1; 1] ~qo:![0; -1] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qx2b = + let name = "qx2b" in + let witness = !![0; -3; 3; 9] in + let circuit = + let wires = + Circuit.make_wires + ~a:[0; 0; 0] + ~b:[0; 1; 2] + ~c:[0; 3; 3] + ~d:[0; 0; 0] + ~e:[0; 0; 0] + () + in + let gates = Circuit.make_gates ~qx2b:![1; 1; 1] ~qo:![0; -1; -1] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qx5a = + let name = "qx5a" in + let witness = !![0; 2; 32] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 1] ~b:[0; 0] ~c:[0; 2] ~d:[0; 0] ~e:[0; 0] () + in + let gates = Circuit.make_gates ~qx5a:![1; 1] ~qo:![0; -1] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qx5c = + let name = "qx5c" in + let witness = !![0; 243; 3] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 1] ~b:[0; 0] ~c:[0; 2] ~d:[0; 0] ~e:[0; 0] () + in + let gates = Circuit.make_gates ~qx5c:![1; 1] ~ql:![0; -1] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qecc_ws_add = + let name = "qecc_ws_add" in + (* We check that: (3,1) + (4,4) = (2,2). + These are dummy points, they do not belong to a specific curve. *) + let witness = !![1; 2; 3; 4] in + let circuit = + let wires = + Circuit.make_wires ~a:[2; 0] ~b:[3; 3] ~c:[1; 1] ~d:[0; 0] ~e:[0; 0] () + in + let gates = Circuit.make_gates ~qecc_ws_add:![1; 0] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qecc_ed_add = + let name = "qecc_ed_add" in + let witness = !![0; 1] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 1] ~b:[0; 1] ~c:[0; 1] ~d:[0; 0] ~e:[0; 0] () + in + let gates = Circuit.make_gates ~qecc_ed_add:![1; 0] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qecc_ed_cond_add = + let name = "qecc_cond_ed_add" in + (* In the first 2 constraints we are doing A(0;1) + 0B(2;3) = C(1;2); + in the other 2, A(0;1) + 1B(0;1) = C(0;1) *) + let witness = !![0; 1; 2; 3] in + let circuit = + let wires = + Circuit.make_wires + ~a:[0; 0; 1; 0] + ~b:[2; 0; 0; 0] + ~c:[3; 0; 1; 0] + ~d:[1; 1; 0; 0] + ~e:[2; 2; 1; 1] + () + in + let gates = Circuit.make_gates ~qecc_ed_cond_add:![1; 0; 1; 0] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qbool = + let name = "qbool" in + let witness = !![0; 1] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 1] ~b:[0; 0] ~c:[0; 0] ~d:[0; 0] ~e:[0; 0] () + in + let gates = Circuit.make_gates ~qbool:![1; 1] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let qcond_swap = + let name = "qcond_swap" in + let witness = !![0; 1; 2] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 1] ~b:[1; 1] ~c:[2; 2] ~d:[1; 2] ~e:[2; 1] () + in + let gates = Circuit.make_gates ~qcond_swap:![1; 1] () in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let q_anemoi = + let name = "q_anemoi" in + let x0 = "1" in + let y0 = "1" in + let x1 = + "39027417478195954763090966714903261667484379123570980405377627458504913299628" + in + let y1 = + "12807118572207854608879870979725669075358379219019309928321803168748017551407" + in + let x2 = + "16347289160862248212893857406118677211322091184422502665988411845410114556281" + in + + let y2 = + "7279269625797671375403766084307099687590046281141194129086784189878517048332" + in + + let kx1 = Scalar.of_string "39" in + let ky1 = + Scalar.of_string + "14981678621464625851270783002338847382197300714436467949315331057125308909900" + in + let kx2 = + Scalar.of_string + "41362478282768062297187132445775312675360473883834860695283235286481594490621" + in + let ky2 = + Scalar.of_string + "28253420209785428420233456008091632509255652343634529984400816700490470131093" + in + let witness = Array.map Scalar.of_string [|"0"; x0; y0; x1; y1; x2; y2|] in + let circuit = + let wires = + Circuit.make_wires + ~a:[0; 0; 0; 0] + ~b:[0; 0; 3; 0] + ~c:[0; 0; 4; 0] + ~d:[0; 0; 1; 5] + ~e:[0; 0; 2; 6] + () + in + let precomputed_advice = + SMap.of_list + [ + ("qadv0", Scalar.[zero; zero; kx1; zero]); + ("qadv1", Scalar.[zero; zero; ky1; zero]); + ("qadv2", Scalar.[zero; zero; kx2; zero]); + ("qadv3", Scalar.[zero; zero; ky2; zero]); + ] + in + let gates = + Circuit.make_gates + ~q_anemoi:Scalar.[zero; zero; one; zero] + ~ql:Scalar.[one; one; zero; zero] + ~qr:Scalar.[one; zero; zero; zero] + ~precomputed_advice + () + in + Circuit.make ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + let list = + [ + qc; + ql; + qr; + qd; + qe; + qlg; + qrg; + qog; + qdg; + qeg; + qm; + qx2b; + qx5a; + qx5c; + qecc_ws_add; + qecc_ed_add; + qecc_ed_cond_add; + qbool; + qcond_swap; + q_anemoi; + ] +end + +module General_circuits = struct + let bnot = + let name = "bnot" in + let witness = !![0; 1] in + let circuit = + let wires = + Circuit.make_wires ~a:[0; 0] ~b:[0; 0] ~c:[1; 0] ~d:[0; 0] ~e:[0; 0] () + in + let gates = Circuit.make_gates ~qo:![-1; -1] ~qc:![1; 0] () in + Circuit.make ~wires ~gates ~public_input_size:1 () + in + {name; circuit; witness; outcome = Valid} + + let list = [bnot] +end + +module General = struct + (* General tests *) + + (* Proving the relations + x10 = x0 + x1 * (x2 + x3 * (x4 + x5)) + & P(x2, x0) + Q(x3, x3) = R(x1, x1) + + Using intermediary variables: + x10 = x0 + x1 * (x2 + x3 * x6) + x10 = x0 + x1 * (x2 + x7) + x10 = x0 + x1 * x8 + x10 = x0 + x9 + <=> + Constraints: + 1*x0 + 1*x9 - 1*x10 + 0*x0*x9 + 0 = 0 + 0*x1 + 0*x8 - 1*x9 + 1*x1*x8 + 0 = 0 + 1*x2 + 1*x7 - 1*x8 + 0*x2*x7 + 0 = 0 + 0*x3 + 0*x6 - 1*x7 + 1*x3*x6 + 0 = 0 + 1*x4 + 1*x5 - 1*x6 + 0*x4*x5 + 0 = 0 + F_add_weirestrass(x2, x3, x1, x0, x3, x1) = 0 + *) + + (* Base circuit proves that: + 95 = 1 + 2 * (3 + 4 * (5 + 6)) + with 1 public input + *) + + let wires = + Circuit.make_wires + ~a:[0; 1; 2; 3; 4; 2; 0] + ~b:[9; 8; 7; 6; 5; 3; 3] + ~c:[10; 9; 8; 7; 6; 1; 1] + ~d:[0; 0; 0; 0; 0; 0; 0] + ~e:[0; 0; 0; 0; 0; 0; 0] + () + + let gates = + Circuit.make_gates + ~ql:![1; 0; 1; 0; 1; 0; 0] + ~qr:![1; 0; 1; 0; 1; 0; 0] + ~qo:![-1; -1; -1; -1; -1; 0; 0] + ~qm:![0; 1; 0; 1; 0; 0; 0] + ~qecc_ws_add:![0; 0; 0; 0; 0; 1; 0] + () + + let circuit = Circuit.make ~wires ~gates ~public_input_size:1 () + + let witness = !![1; 2; 3; 4; 5; 6; 11; 44; 47; 94; 95] + + let zero_values = + let name = "zero_values" in + let witness = Array.make 11 (Scalar.of_int 0) in + {name; circuit; witness; outcome = Valid} + + let non_zero_values = + let name = "non_zero_values" in + {name; circuit; witness; outcome = Valid} + + (* Same test with no public inputs *) + let no_public_inputs = + let name = "no_public_inputs" in + let circuit = Circuit.make ~wires ~gates ~public_input_size:0 () in + {name; circuit; witness; outcome = Valid} + + let wrong_values = + let name = "wrong_values" in + let witness = + !![1; 2; 3; 4; 5; 6; 11; 44; 47; 94; 94] + (* """mistake""" here *) + in + {name; circuit; witness; outcome = Proof_error} + + let input_com = + let name = "input_commitment" in + let circuit = + Circuit.make ~wires ~gates ~public_input_size:0 ~input_com_sizes:[3; 1] () + in + {name; circuit; witness; outcome = Valid} + + let list = + [zero_values; non_zero_values; no_public_inputs; wrong_values; input_com] + + let list_one_public_input = [zero_values; non_zero_values; wrong_values] +end + +module Big_circuit = struct + (* generates circuit with 2^k - 1 constraints that adds 2^(k + 1) inputs 4 by 4, + then adds 2^(k-1) inputs 2 by 2, then multiplies 2^(k-2) inputs 2 by 2, and + repeat the two last steps until there is 1 output left. + At each gate of the circuit, a random scalar is also added. There + is a total of k-1 layers of gates, i-th layer contains 2^i gates (starting + from the "output layer", numbering from 0 to i-1) + IMPORTANT : with aPlonK, this case is intended to fit PI_rollup_example + module, which means 2 public inputs and the first element of each witness + equal to the second element of the previous witness. + *) + let make ~nb_proofs ~public_input_size ~k = + let name = Format.sprintf "big_circuit.%i.%i" public_input_size k in + let len_fst_layer = 1 lsl (k - 1) in + (* for wires d & e : [[d₁ ; e₁] ; [d₂ ; e₂] ; …]. They are handled + separately because they are only in the first gate & we don’t want to + involve them in the loop *) + let e_d = + Array.init len_fst_layer (fun _ -> Scalar.[|random (); random ()|]) + in + let witness nb_proofs k qc = + let rec build_w (acc_w_left, acc_w_right) = + let l = List.hd acc_w_left in + let r = List.hd acc_w_right in + let len_l = Array.length l in + assert (Array.(len_l = length r)) ; + let op = + if List.length acc_w_left mod 2 = 0 then Scalar.mul else Scalar.add + in + let add_qc i = + let i_constraint = + let lens = + List.(fold_left (fun i l -> i + Array.length l)) + 0 + (acc_w_left @ acc_w_right) + in + lens - (1 lsl k) + i + in + Scalar.(add qc.(i_constraint)) + in + if len_l = 1 then + (* We are at the last layer, there is only 1 gate left *) + let last = add_qc 0 (op l.(0) r.(0)) in + Array.( + concat + List.(rev acc_w_left @ rev acc_w_right @ [[|last|]] @ to_list e_d)) + else if len_l = len_fst_layer then + let wl = + Array.init (len_l / 2) (fun i -> + let j = 2 * i in + add_qc j Scalar.(l.(j) + r.(j) + e_d.(j).(0) + e_d.(j).(1))) + in + let wr = + Array.init (len_l / 2) (fun i -> + let j = (2 * i) + 1 in + add_qc j Scalar.(l.(j) + r.(j) + e_d.(j).(0) + e_d.(j).(1))) + in + build_w (wl :: acc_w_left, wr :: acc_w_right) + else + let wl = + Array.init (len_l / 2) (fun i -> + add_qc (2 * i) (op l.(2 * i) r.(2 * i))) + in + let wr = + Array.init (len_l / 2) (fun i -> + add_qc ((2 * i) + 1) (op l.((2 * i) + 1) r.((2 * i) + 1))) + in + build_w (wl :: acc_w_left, wr :: acc_w_right) + in + let open Stdlib (* to recover the ! deref operator *) in + let w0 = ref (Scalar.random ()) in + List.init nb_proofs (fun _ -> + let w = + let w_left = + Array.init len_fst_layer (fun i -> + if i = 0 then !w0 else Scalar.random ()) + in + let w_right = + Array.init len_fst_layer (fun _ -> Scalar.random ()) + in + + build_w ([w_left], [w_right]) + in + w0 := w.(1) ; + w) + in + let n = (1 lsl k) - 1 in + let qc = List.init n (fun _ -> Scalar.random ()) in + let circuit = + let wires = + let last_c = 2 * n in + let a = List.init n Fun.id in + let b = List.init n (fun i -> n + i) in + let c = + List.init (n / 2) (fun i -> + let i = (1 lsl (k - 1)) + i in + [i; n + i]) + @ [[last_c]] + |> List.concat + in + let d = + List.init n (fun i -> + if i < len_fst_layer then last_c + ((2 * i) + 1) else 0) + in + let e = + List.mapi (fun i x -> if i < len_fst_layer then x + 1 else 0) d + in + Circuit.Circuit.make_wires ~a ~b ~c ~d ~e () + in + let gates = + let is_add k n i = + let dist = k - Z.(log2 (of_int (Int.sub n i))) in + if dist mod 2 = 0 then false else true + in + let qm = List.init n (fun i -> if is_add k n i then 0 else 1) in + let ql = List.init n (fun i -> if is_add k n i then 1 else 0) in + let qr = ql in + let qo = List.init n (fun _ -> -1) in + let qd = List.init n (fun i -> if i < 1 lsl (k - 1) then 1 else 0) in + let qe = qd in + Circuit.Circuit.make_gates + ~qm:!qm + ~ql:!ql + ~qr:!qr + ~qo:!qo + ~qd:!qd + ~qe:!qe + ~qc + () + in + Circuit.make ~wires ~gates ~public_input_size () + in + let witnesses = witness nb_proofs k (Array.of_list qc) in + List.map + (fun witness -> {name; circuit; witness; outcome = Valid}) + witnesses + + let list = make ~nb_proofs:2 ~public_input_size:2 ~k:5 + + let list_slow = make ~nb_proofs:2 ~public_input_size:2 ~k:16 +end + +let list = + Unit_tests_for_each_selector.list @ General_circuits.list @ General.list + @ Big_circuit.list + +let list_slow = Big_circuit.list_slow + +module Lookup = struct + (* Tables corresponding to addition of digits mod m to perform tests on. *) + let table_add_mod_m m = + let m2 = m * m in + let t_1 = List.init m2 (fun i -> i / m) in + let t_2 = List.init m2 (fun i -> i mod m) in + let t_3 = List.init m2 (fun i -> ((i / m) + i) mod m) in + [!!t_1; !!t_2; !!t_3] + + let table_add_mod_5 = table_add_mod_m 5 + + let table_add_mod_10 = table_add_mod_m 10 + + (* ---- Unit tests for each selector. ---- *) + let qplookup = + let name = "qplookup" in + let witness = !![0; 1; 2] in + let circuit = + let wires = Circuit.make_wires ~a:[1] ~b:[1] ~c:[2] ~d:[0] ~e:[0] () in + let gates = Circuit.make_gates ~q_plookup:![1] ~q_table:![0] () in + let tables = [table_add_mod_5] in + Circuit.make ~tables ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + (* ---- Test with 2 tables. ---- *) + let qplookup_two_tables = + let name = "qplookup_two_tables" in + let witness = !![0; 1; 3; 9] in + let circuit = + let wires = + Circuit.make_wires ~a:[2; 3] ~b:[2; 1] ~c:[1; 0] ~d:[0; 0] ~e:[0; 0] () + in + let gates = Circuit.make_gates ~q_plookup:![1; 1] ~q_table:![0; 1] () in + let tables = [table_add_mod_5; table_add_mod_10] in + Circuit.make ~tables ~wires ~gates ~public_input_size:0 () + in + {name; circuit; witness; outcome = Valid} + + (* ---- General test with correct and incorrect witness. ---- *) + + let wires = + Circuit.make_wires + ~a:[1; 1; 4; 2; 4; 3; 1] + ~b:[2; 1; 2; 2; 3; 4; 4] + ~c:[3; 1; 1; 4; 2; 2; 2] + ~d:[0; 0; 0; 0; 0; 0; 0] + ~e:[0; 0; 0; 0; 0; 0; 0] + () + + let gates = + Circuit.make_gates + ~qo:![0; -1; 0; -1; 0; 0; 0] + ~qm:![0; 1; 0; 1; 0; 0; 0] + ~qecc_ws_add:![0; 0; 0; 0; 0; 1; 0] + ~q_plookup:![1; 0; 1; 0; 1; 0; 0] + ~q_table:![0; 0; 0; 0; 0; 0; 0] + () + + let tables = [table_add_mod_5] + + let circuit = + (* Proving the relations with addition mod 5 using lookups + x8 = x7 + x1 * (x3 + x4 * (x5 + x6)) + R(x2, x2) = P(x3, x1) + Q(x4, x4) <- these are dummy points + with 1 public input + <=> + Constraints: + lookup: x1 (+) x7 = x8 + 1*x1*x7 - 1*x7 = 0 + lookup: x3 (+) x4 = x7 + 1*x4*x1 - x4 = 0 + lookup: x5 (+) x6 = x1 + F_add_weirestrass(x3, x4, x2, x1, x4, x2) = 0 + *) + Circuit.make ~tables ~wires ~gates ~public_input_size:1 () + + (* Base witness proves that: + 3 = 2 + 1 * (2 + 2 * (3 + 4)) addition modulo 5 + R(2,2) = P(3,1) + Q(4,4) weierstrass point addition + *) + let witness = !![0; 1; 2; 3; 4] + + let lookup_zero_values = + let name = "lookup_zero_values" in + let witness = !!(List.init 5 (fun _i -> 0)) in + {name; circuit; witness; outcome = Valid} + + let lookup_non_zero_values = + let name = "lookup_non_zero_values" in + {name; circuit; witness; outcome = Valid} + + let lookup_no_public_inputs = + let name = "lookup_no_public_inputs" in + let circuit = Circuit.make ~tables ~wires ~gates ~public_input_size:0 () in + {name; circuit; witness; outcome = Valid} + + let lookup_wrong_arith_values = + let name = "lookup_wrong_arith_values" in + let wires = + Circuit.make_wires + ~a:[1; 1; 4; 2; 4; 3; 1] + ~b:[2; 1; 2; 2; 3; 4; 4] + ~c:[3; 1; 1; 3; 2; 2; 2] + ~d:[0; 0; 0; 0; 0; 0; 0] + ~e:[0; 0; 0; 0; 0; 0; 0] + () + (* """mistake""" here in arith. constraint *) + in + let circuit = Circuit.make ~tables ~wires ~gates ~public_input_size:1 () in + {name; circuit; witness; outcome = Proof_error} + + let wrong_plookup_values = + let name = "wrong_plookup_values" in + let wires = + Circuit.make_wires + ~a:[0; 1; 4; 2; 4; 3; 1] + ~b:[2; 1; 2; 2; 3; 4; 4] + ~c:[3; 1; 1; 4; 2; 2; 2] + ~d:[0; 0; 0; 0; 0; 0; 0] + ~e:[0; 0; 0; 0; 0; 0; 0] + () + (* """mistake""" here in lookup constraint *) + in + let circuit = Circuit.make ~tables ~wires ~gates ~public_input_size:1 () in + {name; circuit; witness; outcome = Lookup_error} + + let list = + [ + qplookup; + qplookup_two_tables; + lookup_zero_values; + lookup_non_zero_values; + lookup_no_public_inputs; + lookup_wrong_arith_values; + wrong_plookup_values; + ] +end diff --git a/src/lib_plonk/test/dune b/src/lib_plonk/test/dune new file mode 100644 index 000000000000..20ab19f58053 --- /dev/null +++ b/src/lib_plonk/test/dune @@ -0,0 +1,13 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name plonk_test) + (public_name octez-plonk.plonk-test) + (instrumentation (backend bisect_ppx)) + (libraries + octez-plonk + octez-plonk.aggregation + octez-plonk.distribution) + (preprocess (pps ppx_repr)) + (modules helpers cases)) diff --git a/src/lib_plonk/test/helpers.ml b/src/lib_plonk/test/helpers.ml new file mode 100644 index 000000000000..08650affcd29 --- /dev/null +++ b/src/lib_plonk/test/helpers.ml @@ -0,0 +1,541 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let with_seed (f : unit -> unit) = + (* Seed for deterministic pseudo-randomness: + If the environment variable RANDOM_SEED is set, then its value is used as + as seed. Otherwise, a random seed is used. + WARNING: using [Random.self_init] elsewhere in the tests breaks thedeterminism. + *) + let seed = + match Sys.getenv_opt "RANDOM_SEED" with + | None -> + Random.self_init () ; + Random.int 1073741823 + | Some v -> ( + try int_of_string v + with _ -> + failwith + (Format.sprintf + "Invalid random seed '%s'. Maybe you need to run '$ unset \ + RANDOM_SEED' in your terminal?" + v)) + in + Printf.printf "Random seed: %d\n" seed ; + Random.init seed ; + f () + +let output_buffer = ref stdout + +let with_output_to_file (f : unit -> unit) = + output_buffer := open_out "test.output" ; + f () ; + close_out !output_buffer + +let set_seed s = Random.init s + +let bigstring_of_file filename ~hash = + let bs = + let fd = Unix.openfile filename [Unix.O_RDONLY] 0o440 in + Bigarray.array1_of_genarray + @@ Unix.map_file + fd + Bigarray.char + Bigarray.c_layout + false + [|(* [-1] means read the whole file *) -1|] + in + let computed_hash = + let st = + Hacl_star.EverCrypt.Hash.init ~alg:Hacl_star.SharedDefs.HashDefs.BLAKE2b + in + let len = 48 (* works for both g1 and g2 *) in + let msg = Bytes.create len in + for i = 0 to (Bigstringaf.length bs / len) - 1 do + Bigstringaf.blit_to_bytes bs ~src_off:(i * len) msg ~dst_off:0 ~len ; + Hacl_star.EverCrypt.Hash.update ~st ~msg + done ; + Hacl_star.EverCrypt.Hash.finish ~st + in + let hash = Hex.to_bytes (`Hex hash) in + if computed_hash <> hash then failwith ("Invalid hash: " ^ filename) ; + bs + +let load_real_srs prefix = + let open Octez_bls12_381_polynomial.Bls12_381_polynomial.Srs in + let ( // ) s1 s2 = s1 ^ "/" ^ s2 in + ( ( Srs_g1.of_bigstring + (bigstring_of_file + (prefix // "srs_filecoin_g1_21") + ~hash: + "25281025229b67eed4bcf4451dca0e5ac3fc6c5bf5934f54449105a7feba8049cf0e9f390f23528d5f860387c07a6b374f2ef6dad6fd73b051e4cc4699974738") + ~len:(1 lsl 21) + |> Result.get_ok, + Srs_g2.of_bigstring + (bigstring_of_file + (prefix // "srs_filecoin_g2_1") + ~hash: + "ee034f5e6d3d9dc2097861ffb278438573f0a9c84afd6806a5b53b158b0e6e6847dc8a84e1b01c3c161ed4593816d59bf4817c797ffad6fffbea143987e340a4") + ~len:2 + |> Result.get_ok ), + ( Srs_g1.of_bigstring + (bigstring_of_file + (prefix // "srs_zcash_g1_1") + ~hash: + "435fd5b85e1e3271c8e241b25da799df3e312e67d06c9e009fb967a8d597ed37897047aa48659526ce10db857ee02c64e6f577ef80485d34d7506fff40a901b4") + ~len:2 + |> Result.get_ok, + Srs_g2.of_bigstring + (bigstring_of_file + (prefix // "srs_zcash_g2_10") + ~hash: + "39ebc126d18caade1bee9294124292a089746441cee6b80efb37f0a1e6a37e8acabfa3c0a3b0c6ce15ea3a46a5f5373be222bb1a54b332d43e25f489c66dec49") + ~len:(1 lsl 10) + |> Result.get_ok ) ) + +let make_fake_srs () = + let open Octez_bls12_381_polynomial.Bls12_381_polynomial in + (Srs.generate_insecure 14 1, Srs.generate_insecure 1 14) + +let srs = + match Sys.getenv_opt "SRS_DIR" with + | None -> make_fake_srs () + | Some prefix -> load_real_srs prefix + +let rec repeat n f = + if n <= 0 then () + else ( + f () ; + repeat (n - 1) f) + +let must_fail f = + let exception Local in + try + (try f () with _ -> raise Local) ; + assert false + with + | Local -> () + | _ -> assert false + +let string_of_bytes bytes = + if bytes <= 1024. then Printf.sprintf "%3.2f B " bytes + else + let kilobytes = bytes /. 1024. in + if kilobytes <= 1024. then Printf.sprintf "%3.2f KB" kilobytes + else + let megabytes = kilobytes /. 1024. in + if megabytes <= 1024. then Printf.sprintf "%3.2f MB" megabytes + else + let gigabytes = megabytes /. 1024. in + Printf.sprintf "%.2f GB" gigabytes + +let hash_of_repr t v = + let serialized_bytes = + Bytes.of_string @@ Repr.(unstage @@ to_bin_string t) v + in + Hacl_star.Hacl.Blake2b_32.hash serialized_bytes 32 |> Hex.of_bytes |> Hex.show + +let get_input_com_secrets private_inputs input_com_sizes = + let secrets, _ = + List.fold_left + (fun (secrets, l) size -> + (Array.sub private_inputs l size :: secrets, l + size)) + ([], 0) + input_com_sizes + in + List.rev secrets + +module Time = struct + type data = {n : int; sum : float; sum_squares : float; last : float} + + let str_time = ref "" + + let zero_data = {n = 0; sum = 0.; sum_squares = 0.; last = 0.} + + let setup = ref zero_data + + let prove = ref zero_data + + let verify = ref zero_data + + let reset () = + setup := zero_data ; + prove := zero_data ; + verify := zero_data + + let update data time = + let sum = time +. !data.sum in + let sum_squares = (time *. time) +. !data.sum_squares in + data := {n = !data.n + 1; sum; sum_squares; last = time} + + let mean data = !data.sum /. float_of_int !data.n + + let var data = + let m = mean data in + (!data.sum_squares /. float_of_int !data.n) -. (m *. m) + + let std data = sqrt (var data) + + let string_of_time t = + if t > 60. then Printf.sprintf "%3.2f m " (t /. 60.) + else if t > 1. then Printf.sprintf "%3.2f s " t + else if t > 0.001 then Printf.sprintf "%3.2f ms" (t *. 1_000.) + else Printf.sprintf "%3.0f µs" (t *. 1_000_000.) + + let time description f = + Gc.full_major () ; + let st1 = Gc.stat () in + let start = Unix.gettimeofday () in + let res = f () in + let stop = Unix.gettimeofday () in + let d = stop -. start in + let () = + match description with + | "setup" -> update setup d + | "prove" -> update prove d + | "verify" -> update verify d + | _ -> () + in + let t_str = string_of_time d in + let st2 = Gc.stat () in + let allocations = + (st2.minor_words +. st2.major_words -. st2.promoted_words + -. (st1.minor_words +. st1.major_words -. st1.promoted_words)) + *. 8. + |> string_of_bytes + in + let top_heap_words = + if st2.top_heap_words > st1.top_heap_words then + st2.top_heap_words |> float_of_int |> Float.mul 8. |> string_of_float + else "?" + in + Printf.printf + "%-8s: Time: %8s Allocations %6s MaxHeap: %s\n%!" + description + t_str + allocations + top_heap_words ; + res + + let reset_str () = str_time := "" + + let update_str ?header () = + let header = + match header with None -> "" | Some header -> header ^ "\n" + in + str_time := + !str_time + ^ Printf.sprintf + "%s%f\n%f\n%f\n" + header + !setup.last + !prove.last + !verify.last + + let print_time_in_file file = + let oc = open_out file in + Printf.fprintf oc "%s" !str_time ; + close_out oc + + let bench_test_circuit ~nb_rep func () = + reset () ; + repeat nb_rep func ; + assert (nb_rep = !setup.n && nb_rep = !prove.n && nb_rep = !verify.n) ; + Printf.printf + "\nTimes over %d repetitions (95%% confidence interval):\n\n" + nb_rep ; + let pp = string_of_time in + let z = 1.96 in + Printf.printf " Setup : %s ± %s\n" (pp (mean setup)) (pp (z *. std setup)) ; + Printf.printf " Prove : %s ± %s\n" (pp (mean prove)) (pp (z *. std prove)) ; + Printf.printf + " Verify: %s ± %s\n" + (pp (mean verify)) + (pp (z *. std verify)) ; + Printf.printf "\n" + + let time_if_verbose verbose description f = + if verbose then time description f else f () +end + +module Make (Main : Plonk.Main_protocol.S) = struct + open Plonk.Circuit + + module Singleton = struct + include Main + + let setup ~zero_knowledge circuit ~srs = + let circuits_map = Plonk.SMap.singleton "" (circuit, 1) in + Main.setup ~zero_knowledge circuits_map ~srs + + let prove pp ~(inputs : circuit_prover_input list) = + let inputs = Plonk.SMap.singleton "" inputs in + Main.prove pp ~inputs + + let verify pp ~inputs proof = + let inputs = Plonk.SMap.singleton "" inputs in + Main.verify pp ~inputs proof + end + + let multi_input_commit pp input_commitment_secrets = + List.fold_left + (fun (cmts, shift) secret -> + (Main.input_commit ~shift pp secret :: cmts, shift + Array.length secret)) + ([], 0) + input_commitment_secrets + |> fst |> List.rev + + let print_info name zero_knowledge proof pp_prover pp_verifier = + let proof_size = + Data_encoding.Binary.length Main.proof_encoding proof |> Float.of_int + in + let proof_hash = hash_of_repr Main.proof_t proof in + let prover_pp_hash = + hash_of_repr Main.prover_public_parameters_t pp_prover + in + let verifier_pp_hash = + hash_of_repr Main.verifier_public_parameters_t pp_verifier + in + Printf.fprintf + !output_buffer + "%s:\n\ + Proof size: %s\n\ + Proof hash: %s\n\ + Prover_pp hash: %s\n\ + Verifier_pp hash: %s\n\n" + (if zero_knowledge then "zk-" ^ name else name) + (string_of_bytes proof_size) + proof_hash + prover_pp_hash + verifier_pp_hash + + let make_secret pp_prover input_com_sizes witness = + let open Main in + let input_com_secrets = get_input_com_secrets witness input_com_sizes in + let input_commitments = multi_input_commit pp_prover input_com_secrets in + {witness; input_commitments} + + let test_circuits ~name ?(zero_knowledge = false) ?(outcome = Cases.Valid) + ?(verbose = false) circuit_map private_inputs = + let time_if_verbose verbose description f = + if verbose then Time.time description f else f () + in + if verbose then + Plonk.SMap.iter + (fun cname (circuit, _n) -> + Format.printf + "circuit '%s' has %d constraints\n" + cname + circuit.circuit_size) + circuit_map ; + let pp_prover, pp_verifier = + time_if_verbose verbose "setup" (fun () -> + Main.setup ~zero_knowledge circuit_map ~srs) + in + let prover_inputs = + Plonk.SMap.mapi + (fun c_name -> + let c = fst (Plonk.SMap.find c_name circuit_map) in + List.map (make_secret pp_prover c.input_com_sizes)) + private_inputs + in + let verifier_inputs = Main.to_verifier_inputs pp_prover prover_inputs in + match outcome with + | Valid -> ( + let proof = + time_if_verbose verbose "prove" (fun () -> + Main.prove pp_prover ~inputs:prover_inputs) + in + Gc.full_major () ; + let v = + time_if_verbose verbose "verify" (fun () -> + Main.verify pp_verifier ~inputs:verifier_inputs proof) + in + assert v ; + print_info name zero_knowledge proof pp_prover pp_verifier ; + (* Test that verification fails if we mutate public inputs *) + match Main.Internal_for_tests.mutate_vi verifier_inputs with + | None -> () (* No public inputs *) + | Some verifier_inputs -> + let v = Main.verify pp_verifier ~inputs:verifier_inputs proof in + assert (not v)) + | _ -> ( + try + let proof = Main.prove pp_prover ~inputs:prover_inputs in + assert (not (Main.verify pp_verifier ~inputs:verifier_inputs proof)) + with + | Main.Rest_not_null _ -> + if outcome = Proof_error then () + else raise (Invalid_argument "Proving error: incorrect witness") + | Main.Entry_not_in_table _ -> + if outcome = Lookup_error then () + else raise (Invalid_argument "Proving error: incorrect lookup") + | e -> raise e) + + (* generator must be n-th root of unity + n must be in the form 2^i + for k number of gates + a_c, b_c, c_c, ql, qr, qo, qm, qc must be lists of length k + x is an array of length m = 3+2(k-1) + l between 0 and m-1, l first parameters will be taken as public inputs + n = k+l + valid_proof is true if the proof is expected valid, false if it must fail + if verbose print run times when valid_proof is true + *) + let test_circuit ~name ?zero_knowledge ?outcome ?verbose circuit + private_inputs = + let circuit_map = Plonk.SMap.singleton name (circuit, 1) in + let inputs = Plonk.SMap.singleton name [private_inputs] in + test_circuits ~name ?zero_knowledge ?outcome ?verbose circuit_map inputs + + let run_test_case ~zero_knowledge ?verbose + Cases.{name; circuit; witness; outcome} () = + test_circuit ~name ~zero_knowledge ~outcome ?verbose circuit witness + + let test_aggregated_cases ?(prefix = "") cases = + let name, circuits_map, inputs_map, outcome = + Cases.aggregate_cases ~prefix cases + in + ( name, + fun ~zero_knowledge () -> + test_circuits ~name ~zero_knowledge circuits_map inputs_map ~outcome ) +end + +module Plompiler_Helpers = struct + open Plompiler + module CS = Plonk.Circuit + + type test_info = {valid : bool; name : string; flamegraph : bool} + + module type Test = functor (L : LIB) -> sig + open L + + val tests : ((unit -> unit repr t) * test_info) list + end + + let to_test ?plonk ?(optimize = true) test () = + let module Test = (val test : Test) in + let circuits = + let module E1 = Test (LibCircuit) in + E1.tests + in + let results = + let module E2 = Test (LibResult) in + E2.tests + in + let run_one_test (circuit, info) (result, _) = + let LibCircuit.{cs; tables; solver; _} = + LibCircuit.(get_cs (circuit ())) + in + let initial, public_input_size = LibCircuit.(get_inputs (circuit ())) in + if info.flamegraph then + Plompiler.Utils.dump_label_traces (info.name ^ "_flamegraph") cs ; + let pi = + try Solver.solve solver initial |> fun x -> Some x with _ -> None + in + match pi with + | None -> assert (not info.valid) + | Some private_inputs -> + (* Printf.printf + "Trace:\n%s\n%s\n" + (String.concat + "," + (List.init (Array.length private_inputs) string_of_int)) + (String.concat + "," + (List.map S.string_of_scalar (Array.to_list private_inputs))) ; + Printf.printf "CS:\n%s\n" (CS.to_string cs) ; *) + if not info.valid then assert (not @@ CS.sat cs tables private_inputs) + else ( + Printf.fprintf + !output_buffer + "%s:\nConstraints: %d\n\n" + info.name + Array.(concat cs |> length) ; + + assert (CS.sat cs tables private_inputs) ; + let cs, private_inputs = + if optimize then ( + let LibCircuit.{cs; solver; _} = + LibCircuit.(get_cs ~optimize (circuit ())) + in + Printf.fprintf + !output_buffer + "%s_optimized:\nConstraints: %d\n\n" + info.name + Array.(concat cs |> length) ; + let private_inputs = Solver.solve solver initial in + assert (CS.sat cs tables private_inputs) ; + + (cs, private_inputs)) + else (cs, private_inputs) + in + if info.flamegraph then + Plompiler.Utils.dump_label_traces + (info.name ^ "_opt_flamegraph") + cs ; + let res = LibResult.get_result (result ()) in + let serialized_res = LibResult.serialize res in + let out_size = Array.length serialized_res in + let trace_out = + Array.sub + private_inputs + (Array.length private_inputs - out_size) + out_size + in + (* Compare values obtained from Result and Circuit interpreters *) + assert (Array.for_all2 S.( = ) serialized_res trace_out) ; + match plonk with + | None -> () + | Some plonk -> + let module Main = (val plonk : Plonk.Main_protocol.S) in + let open Make (Main) in + let circuit = CS.to_plonk ~public_input_size ~tables cs in + test_circuit + ~name:info.name + ~zero_knowledge:false + ~outcome:Valid + circuit + private_inputs) + in + List.iter2 run_one_test circuits results + + module Utils (L : LIB) = struct + open L + + (* We test equality for Num, Bool, lists, tuples *) + let test_equal x z () = + let* x = input ~kind:`Public x in + let* z = input z in + assert_equal x z + + let si x = Input.scalar @@ S.of_string @@ string_of_int x + + let test ~valid ?(name = "test") ?(flamegraph = false) x = + (x, {valid; name; flamegraph}) + end +end + +include Plompiler_Helpers -- GitLab From c66986f0d13ca2c6a98ab8b05f08fc2636bb0381 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Tue, 14 Mar 2023 20:03:19 +0100 Subject: [PATCH 19/34] octez-plonk test main: import from nomadic-labs/cryptography --- manifest/main.ml | 67 ++- src/lib_plonk/test/dune | 41 ++ src/lib_plonk/test/main.ml | 43 ++ src/lib_plonk/test/test-quick.expected | 486 ++++++++++++++++ src/lib_plonk/test/test-slow.expected | 534 ++++++++++++++++++ src/lib_plonk/test/test_circuit.ml | 235 ++++++++ src/lib_plonk/test/test_evaluations.ml | 92 +++ src/lib_plonk/test/test_main_protocol.ml | 161 ++++++ src/lib_plonk/test/test_pack.ml | 109 ++++ src/lib_plonk/test/test_permutations.ml | 160 ++++++ src/lib_plonk/test/test_plookup.ml | 126 +++++ .../test/test_polynomial_commitment.ml | 164 ++++++ .../test/test_polynomial_protocol.ml | 199 +++++++ src/lib_plonk/test/test_range_checks.ml | 118 ++++ src/lib_plonk/test/test_utils.ml | 127 +++++ 15 files changed, 2661 insertions(+), 1 deletion(-) create mode 100644 src/lib_plonk/test/main.ml create mode 100644 src/lib_plonk/test/test-quick.expected create mode 100644 src/lib_plonk/test/test-slow.expected create mode 100644 src/lib_plonk/test/test_circuit.ml create mode 100644 src/lib_plonk/test/test_evaluations.ml create mode 100644 src/lib_plonk/test/test_main_protocol.ml create mode 100644 src/lib_plonk/test/test_pack.ml create mode 100644 src/lib_plonk/test/test_permutations.ml create mode 100644 src/lib_plonk/test/test_plookup.ml create mode 100644 src/lib_plonk/test/test_polynomial_commitment.ml create mode 100644 src/lib_plonk/test/test_polynomial_protocol.ml create mode 100644 src/lib_plonk/test/test_range_checks.ml create mode 100644 src/lib_plonk/test/test_utils.ml diff --git a/manifest/main.ml b/manifest/main.ml index 46b78e11ebd0..aaab69c81479 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1241,7 +1241,7 @@ let octez_plonk_distribution = ~deps:[octez_plonk; octez_plonk_aggregation] ~preprocess:[pps ppx_repr] -let _octez_plonk_test_helpers = +let octez_plonk_test_helpers = public_lib "octez-plonk.plonk-test" ~path:"src/lib_plonk/test" @@ -1249,6 +1249,71 @@ let _octez_plonk_test_helpers = ~deps:[octez_plonk; octez_plonk_aggregation; octez_plonk_distribution] ~modules:["helpers"; "cases"] ~preprocess:[pps ppx_repr] + ~dune: + Dune. + [ + alias_rule + "runtest" + ~package:"octez-plonk" + ~action: + (G + [ + setenv + "RANDOM_SEED" + "42" + (progn + [ + run_exe "main" ["-q"]; + [S "diff?"; S "test-quick.expected"; S "test.output"]; + ]); + ]); + alias_rule + "runtest_slow" + ~package:"octez-plonk" + ~action:(run_exe "main" []); + alias_rule + "runtest_slow_with_regression" + ~package:"octez-plonk" + ~action: + (G + [ + setenv + "RANDOM_SEED" + "42" + (progn + [ + run_exe "main" []; + [S "diff?"; S "test-slow.expected"; S "test.output"]; + ]); + ]); + ] + +let _octez_plonk_test_helpers_main = + private_exe + "main" + ~path:"src/lib_plonk/test" + ~opam:"octez-plonk" + ~modules: + [ + "main"; + "test_circuit"; + "test_evaluations"; + "test_main_protocol"; + "test_pack"; + "test_permutations"; + "test_plookup"; + "test_polynomial_commitment"; + "test_polynomial_protocol"; + "test_range_checks"; + "test_utils"; + ] + ~bisect_ppx:No + ~deps: + [ + octez_plonk_test_helpers; + qcheck_alcotest; + octez_bls12_381_polynomial |> open_; + ] let _octez_srs_extraction_tests = tests diff --git a/src/lib_plonk/test/dune b/src/lib_plonk/test/dune index 20ab19f58053..867f5e75a97f 100644 --- a/src/lib_plonk/test/dune +++ b/src/lib_plonk/test/dune @@ -11,3 +11,44 @@ octez-plonk.distribution) (preprocess (pps ppx_repr)) (modules helpers cases)) + +(rule + (alias runtest) + (package octez-plonk) + (action + (setenv RANDOM_SEED 42 + (progn (run %{exe:main.exe} -q) (diff? test-quick.expected test.output))))) + +(rule + (alias runtest_slow) + (package octez-plonk) + (action (run %{exe:main.exe}))) + +(rule + (alias runtest_slow_with_regression) + (package octez-plonk) + (action + (setenv RANDOM_SEED 42 + (progn (run %{exe:main.exe}) (diff? test-slow.expected test.output))))) + +(executable + (name main) + (libraries + octez-plonk.plonk-test + qcheck-alcotest + octez-bls12-381-polynomial) + (flags + (:standard) + -open Octez_bls12_381_polynomial) + (modules + main + test_circuit + test_evaluations + test_main_protocol + test_pack + test_permutations + test_plookup + test_polynomial_commitment + test_polynomial_protocol + test_range_checks + test_utils)) diff --git a/src/lib_plonk/test/main.ml b/src/lib_plonk/test/main.ml new file mode 100644 index 000000000000..f7ff72558200 --- /dev/null +++ b/src/lib_plonk/test/main.ml @@ -0,0 +1,43 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk_test + +let () = + Helpers.with_seed (fun () -> + Helpers.with_output_to_file (fun () -> + Alcotest.run ~verbose:false "PlonK" + [ + ("Utils", Test_utils.tests); + ("Evaluations", Test_evaluations.tests); + ("Plonk_Pack", Test_pack.tests); + ("Polynomial Commitment", Test_polynomial_commitment.tests); + ("Polynomial_protocol", Test_polynomial_protocol.tests); + ("Permutations", Test_permutations.tests); + ("Plookup", Test_plookup.tests); + ("Range_Checks", Test_range_checks.tests); + ("Main_Protocol", Test_main_protocol.tests); + ("Circuit", Test_circuit.tests); + ])) diff --git a/src/lib_plonk/test/test-quick.expected b/src/lib_plonk/test/test-quick.expected new file mode 100644 index 000000000000..aa52ce41498b --- /dev/null +++ b/src/lib_plonk/test/test-quick.expected @@ -0,0 +1,486 @@ +Range_Checks_single: +Proof size: 2.79 KB +Proof hash: 621749a22bf2f8fb0201b2dee3b09287c17b6231e700ba327f5dc922dc1bdaa8 +Prover_pp hash: 59842dfe85e5f4b05739153c65e03bf8a156de6e729cf6f06203672e3c5a2f7c +Verifier_pp hash: 911abc9711a95a8e6d39eccfef1766f75afe007653839e2ab44053eea2620970 + +Range_Checks_single: +Proof size: 2.79 KB +Proof hash: 621749a22bf2f8fb0201b2dee3b09287c17b6231e700ba327f5dc922dc1bdaa8 +Prover_pp hash: 59842dfe85e5f4b05739153c65e03bf8a156de6e729cf6f06203672e3c5a2f7c +Verifier_pp hash: 911abc9711a95a8e6d39eccfef1766f75afe007653839e2ab44053eea2620970 + +KZG.qc: +Proof size: 1.46 KB +Proof hash: e5d21dccc44875304ca58e6b1f73a76ad292c4080386990142a7b3026a5ec1af +Prover_pp hash: fa2b7f9c04cee1f51e8149395eedf6ec65f927eeffb0e98a4837b6f60235b7fc +Verifier_pp hash: 459338d51a3188abeffda0887f239216c0a4b1f7c7e929b4e4c2be674c8347fa + +KZG.ql: +Proof size: 1.46 KB +Proof hash: 5d38b6c381987557bb8be8d682c46b25b99475e536db8947d1f8cc847ab5521e +Prover_pp hash: 09176f149942271fab2b4b82c0263ef19e3e2e431b224853c26c0518154ac38d +Verifier_pp hash: b0dcf0fee7cbf0e2434d3f2a73f08bb98f4461d7b859acba875ec08b6590f40a + +KZG.qr: +Proof size: 1.46 KB +Proof hash: 625892d734c40c31a77120d8bd9e3809171d64ad1576887f44c40d56c83ac69f +Prover_pp hash: 66ae4cfea01bf3e5cea95a42081c6075d88e1491ca2cbeee58c751868e7b1295 +Verifier_pp hash: b9e2a0c0dcda8b1622e3704398a8cdba1f2873beef9b1025fe191ebd97715a9e + +KZG.qd: +Proof size: 1.46 KB +Proof hash: 490531d3394658ac3d67b3200b155945eede11adf811beec74fefcb9ee40ff2a +Prover_pp hash: 115c3fd0136e50b281d45bd5e1ba6194741e5dca4886d0830c8b223d034332c8 +Verifier_pp hash: 3a941afed8780e14ba0d34c0ca7a90b94ad6f245f8c9f361649a3d68c7d9b5c0 + +KZG.qe: +Proof size: 1.46 KB +Proof hash: 2bd399884ffc85329d2d31d5ed39e2ef92a6a13d4e268862b6d058a1d75b9b60 +Prover_pp hash: 7c9b1c6a724cf683d1ff751a992ca8e7354708445dd5f24412df01e4a73ca110 +Verifier_pp hash: 6545c547f9b2367d7350b1828e075b99856b9931496a6dcbefb103712bce0b75 + +KZG.qlg: +Proof size: 1.69 KB +Proof hash: 6297c973233645ce0758ad1999797c04b811b608b3a3e8ef6b79716953a81916 +Prover_pp hash: 4a0ff927977b6878f28edba4b01ac5d6e00b7e527156fcf4b37aa49047c361d8 +Verifier_pp hash: 964225d4eb20b9ea290f7af03a0594ca659e482555858147f886f8c7a157eb49 + +KZG.qrg: +Proof size: 1.69 KB +Proof hash: 8002ffb54382992f40c9be14460c8a03d7225e1f4837c56989c60a30b02d5dce +Prover_pp hash: 76a16e62e978d86e2351e01398e43e47b67cd92d23a336d7c2e66c97175f9308 +Verifier_pp hash: 2b3c57ae53fb4435de31820d9e5ee660bb88a7c469c8b1faefc3b71693e8c454 + +KZG.qog: +Proof size: 1.69 KB +Proof hash: 99c36cfb2dc6107de40de80ea6a73ff2f6e7428cb8487a9cba9cc61689119937 +Prover_pp hash: b88645338942471c6c22ae5dd3634552d8016351c26422f23570c817e1e50c59 +Verifier_pp hash: 7ea4a01041a9fd34a1a0860ad2c6a29a3185e98cbb7ff24b676bbf3848632ab0 + +KZG.qdg: +Proof size: 1.69 KB +Proof hash: f6302a5cea552f8b9714de171d31b70fef605d56662c5a2184b3cfd69bd603ae +Prover_pp hash: 738e3098ed41fab2cf2394b84889e042fccdb868b253d88057cd388c20006132 +Verifier_pp hash: 7ef1d7d7248af6b46757ac993cd403564372b54c34af7e79e35d3826275d263f + +KZG.qeg: +Proof size: 1.69 KB +Proof hash: 0d3ed4622e20593a98f7b1d9f4f52cff02c625f21fbfbdf7921d0d6bc9ea3b19 +Prover_pp hash: 3db96b3f412bafa88dea0b984688b0f61bac1789630e3d4f25154c7c27bb8ea5 +Verifier_pp hash: 11dbb306d7ee240a552a449310f044d64fbf49a6339b44adec0c6be2b348602b + +KZG.qm: +Proof size: 1.46 KB +Proof hash: 0a05632e8b973771d020d63f024c6e50112b6c9700ab3813c41dc2d65b81be60 +Prover_pp hash: 2ee6f56291edd671e2c7d4ea03877e73ff46ba437bcf41453a065724e59bf3f9 +Verifier_pp hash: bc1393c2f286c6f2f0d2f712aaed728b994f7964fb01a858b784440527ef4cfc + +KZG.qx2b: +Proof size: 1.50 KB +Proof hash: 0f3bbd889320dd2f97131e54963ff6a9dbd892a1cce64ca10ba158bfe2764f2f +Prover_pp hash: f61b45fe1d0f29c6ee823b8857ef63a59b477615a822cd8b9352a4ce7b6d60d0 +Verifier_pp hash: 73218e8fe9f7715677aabead204111bfcf5bba8e295542dfdc706f0440f2bcc9 + +KZG.qx5a: +Proof size: 1.50 KB +Proof hash: 0161c5cb9e4d49131965e3f04ff363ffe4439c932313dabce25ef28e52acdb58 +Prover_pp hash: 7e78c992a5c698bde2621675e89e58b8de2727197c9d9098fb1f6427071b35b9 +Verifier_pp hash: 478bf9fc0a8f3897395ab3ffe8dac44c8b7cb68d49b637488ddd7e1784c6b36c + +KZG.qx5c: +Proof size: 1.50 KB +Proof hash: ac455c0ef323ba04d6b3b189349a730466f67156d4d271acb550e3c7f96c26f6 +Prover_pp hash: 0081e1709cadf48bc9ef1f6f008b1957154845b2a31ea5a1dc39e2e5daea53d6 +Verifier_pp hash: c6cdb65f67e3dd91875e7750b0b8cca04cc6a9bb0db95169a3b974b1bb0a206c + +KZG.qecc_ws_add: +Proof size: 1.85 KB +Proof hash: ef06e421cf841608f89569beb72cc2aeb2a3767c88599efe35385f09c122e2e4 +Prover_pp hash: b0485e2a5df41cf2474fd257c458b3f85e703450b2277e2f9f4e39b8986f4396 +Verifier_pp hash: d9eead3723b88098c17b95508dceffc01570c85a27c6d561d09a90044c834317 + +KZG.qecc_ed_add: +Proof size: 1.85 KB +Proof hash: 7a603bcd200ceab141f1a580b6fe2e9081a20121019ad1d6e35d35450c989bfe +Prover_pp hash: ac45ba5531a06df936df65d86ff303aee16cb15e2b2b916ecf89b837801afd17 +Verifier_pp hash: 94e11e1b0842f11fe5db38e08a6f09c643a7809e1b84b204eaf28c80edbc8acd + +KZG.qecc_cond_ed_add: +Proof size: 2.05 KB +Proof hash: 5db81fd3b64e265e3222dd69e6918065877fc4d358de45c1815c9a1f4911cacb +Prover_pp hash: e20d46e7db64973bb77e840d991a3b36cd88f7e19cb7d70eb00707e48c8db393 +Verifier_pp hash: 480d9e04c94cd3951734ca70ebc53c439b1af1973b8feb8b0fd734497986b60c + +KZG.qbool: +Proof size: 1.48 KB +Proof hash: 0d103d5d23bf6ee93570ecdd58be21edaa05d39b7a0ca02423759c4c18338400 +Prover_pp hash: 9eba92c56ad424bcc1091f1d393eb291ea2da83a9523b06c389a48241f364364 +Verifier_pp hash: ae1d071a7e8ef1830020a3f908acdb378f9e0881dd848336e22e6225cc60ef6a + +KZG.qcond_swap: +Proof size: 1.58 KB +Proof hash: 27a025809f2e2284b0d191433258cfcb671d89411d8328a2bfd291fb41f2b9d9 +Prover_pp hash: 8bdb6f4d4208501c8896105f59ca9f5cd6f82326b0ceb8a03760c217b0f6bef7 +Verifier_pp hash: 05fe06ade03cef2de1f54b49fabfd98a8e4fe49c669abd73ee5fc1a6eeaa4e7b + +KZG.q_anemoi: +Proof size: 2.07 KB +Proof hash: 463cf0b715ecb77534acc49d321eb7797dab6f80de479d3288149629c12c3359 +Prover_pp hash: 310cbba17f71c77d7d8999c0396211e9881c4e2d665333b00dc1f2eae1374955 +Verifier_pp hash: 4f07f5a91ef9374b8eab9d1583fd7bf5f64c8a7d56bd9e05b26c4619e830032b + +KZG.bnot: +Proof size: 1.54 KB +Proof hash: c0beebbfbe92d56ce6ac0edf6548a8b9bf885c8d60afcf97927535a0f85fc42c +Prover_pp hash: cf4f545b5307c6ebc61860e0819ee9190fbde32577e43ec1ac8bea68f93720c4 +Verifier_pp hash: c7b03b3e8a9959bdd220be6392cfbd5d373831eb4aaee373989209b2263fdd26 + +KZG.zero_values: +Proof size: 2.04 KB +Proof hash: bde519470bdfa70a37b853a31354b4799e8276be30b4126539208756e3ef3fdf +Prover_pp hash: 442ad0a89fdbbed8c38fec3249d289e02f65d9676d24cba867158c67e6ed8f2b +Verifier_pp hash: ba2d0385d5789a1a6d162e42a6567e19df6d9bb5ed069a8be8abcadc86e776eb + +KZG.non_zero_values: +Proof size: 2.15 KB +Proof hash: 5807a54038e98b4125909698d644fa655d71373c60b44f78d8d5c28b87ea9999 +Prover_pp hash: 24e0f5af2106f1c4f69409da99e00171135d9b952d492500b9d1753b52294321 +Verifier_pp hash: c96c56aa1923262bea4a9ce8f937ce62dca3fa9cabfe68ac8cbc2a1507e061cd + +KZG.no_public_inputs: +Proof size: 2.18 KB +Proof hash: adc83367e4234a6458579c9d806d2905643113e50b01cbde226867dfa96eb5f9 +Prover_pp hash: 58aff55881b6073e353100a085b7aef833ba107ff2953d7063eabaacbd731272 +Verifier_pp hash: 1940e7a6df80a13a025328a90149c2606ed2a1eee386b560c1105259b0cc64a4 + +KZG.input_commitment: +Proof size: 2.42 KB +Proof hash: a323d9be26d8fc772b7ac2ee7039df48f6c930177728fcd631d0f2b6c416907c +Prover_pp hash: 53067521843b7574c22c73ecf17400f38677c9aaa9e1f7fdc9ef38f529a96d93 +Verifier_pp hash: 5341ebf040752c9de5fbfe668d6cd7a753f3ba62574f4591c5e7ec37cb61565c + +KZG.big_circuit.2.5: +Proof size: 1.99 KB +Proof hash: 68a7de1146dbf68a00f31bd196c3f9a63a2816ad2bb99f1e4e962e3e53e3a64f +Prover_pp hash: 6c669e82d14eb59816dfa90c7d37606f5a70c04e4623de16879fc7c0df08d646 +Verifier_pp hash: 4705d450db18055dc1f9137242f787c4284d4dd39a05f3f3271b4912a8f289f9 + +KZG.big_circuit.2.5: +Proof size: 1.99 KB +Proof hash: 3d276e11e9a16078efa45f1182ea71169ec7d15f0252c11bb3d74a19315ef0e7 +Prover_pp hash: 6c669e82d14eb59816dfa90c7d37606f5a70c04e4623de16879fc7c0df08d646 +Verifier_pp hash: 4705d450db18055dc1f9137242f787c4284d4dd39a05f3f3271b4912a8f289f9 + +KZG.qplookup: +Proof size: 2.71 KB +Proof hash: bb39a9cf6a520abd44c44000ee0ba27dbf14172690fd59bb842de420a2eb197c +Prover_pp hash: 55dad9de0b8d3cae0d273c87ac859cf0287517a34b8a078203a3c50866270c5f +Verifier_pp hash: e98da2c9624f58e42794f89a1c16d23c68d697db3c756586f382f814521197d1 + +KZG.qplookup_two_tables: +Proof size: 3.15 KB +Proof hash: 240f8c5850633280b395105ccb659f6322a576e8207d09e26dfa1805f3b59965 +Prover_pp hash: 011f2b901ec03a4c811c0a70c7c3cacaed80b053f8e99adb2b054869626b2d22 +Verifier_pp hash: 88ed6db7ef9f36c7e1441ec7e11a7a6eba9f868aaf6a40b707362dde7ee20aa7 + +KZG.lookup_zero_values: +Proof size: 3.86 KB +Proof hash: 4eb7cff7ed4ebb7c648fa1455f0afe91c12d7f52e26ad797298d9fcb29236ea9 +Prover_pp hash: 038ac0b4d8c5fbbff10ea14451ece9f4758826b34625bfad25397505b26f05b2 +Verifier_pp hash: 8560333e54704948e6602b830ebf868279c9904563f5d2bb9d49b007fb356b42 + +KZG.lookup_non_zero_values: +Proof size: 4.07 KB +Proof hash: c87544aec07fa09732eb3c5857bbaf24994702d9274e7408befdeb0a6f69014d +Prover_pp hash: 67117de4b8b75bb70a86bb0a5306cb69c29d35d5eb89466fd77493d725f89adc +Verifier_pp hash: 45b49b220cd8774e93f5b1fa9a8c022dd4ec6d239285f6e743b3cc5350b64cc4 + +KZG.lookup_no_public_inputs: +Proof size: 4.00 KB +Proof hash: 6ab3524c83f62e9abda5366517d2f743785cf5911d7216f760edd8bbe17aa419 +Prover_pp hash: 10dea49f2de9efa100fffacfce7c67be4439fb9bb154f11aa64f11fb40797acd +Verifier_pp hash: c33a99420ca02b4deae7b8d180c5d770050d793bb7788582a2d02e86259362ad + +KZG+zero_values+non_zero_values: +Proof size: 3.42 KB +Proof hash: a47e285f9b8444d9a11334067b9f33edfa81ece2eac52cc37c7a556eb44434b7 +Prover_pp hash: 75d9cd1c97acc2a2bbfe3e4099b81b8a2d4a3c32e3e16b76f9b2b01592d60fd2 +Verifier_pp hash: 522f5a0ed7e75bc757697cd2974f776b8bf50098b0450d124501543931ab5d7b + +KZG+zero_values+zero_values: +Proof size: 2.75 KB +Proof hash: 7c0493e4f2c218e04c49e370322bef66dfdff217f1a14934800138ec72113de6 +Prover_pp hash: 4ed0ed079c87a2d1482c0733d34d75afccaf80c9d17b066cf907089436002b36 +Verifier_pp hash: edbb6aed1be4ce4df9308235dfe0f2e8e7ab1461f56d2198a795ae0bf826c9a3 + +KZG+ql+qr+qlg+qrg+qog+qm: +Proof size: 6.69 KB +Proof hash: 38a2af810e63f9f6c33e716873520df15f3299ac9c8255dc4af5a5cacd81351b +Prover_pp hash: f6a2e5d15804c19584ce3452dcdee75521ef6391a513f9e2d484565559eca368 +Verifier_pp hash: b01bb6e433deee0580a68ae5f44b799679ac554e9d975e2c66006afb4fe1aa2d + +KZG+qplookup+lookup_zero_values: +Proof size: 5.84 KB +Proof hash: e025259fa2c970b379b2b5410d9099aa343c23c31baa6a0997f8bdcb20216737 +Prover_pp hash: 11c75c7918f44864b60504f9af364c56b506892786513c7359ecb59bc1b80865 +Verifier_pp hash: 25d4b7284878fc455b4ff714cb952beb5ad01bef1790e22f61a54b5db935bc69 + +KZG+lookup_non_zero_values+lookup_no_public_inputs: +Proof size: 7.09 KB +Proof hash: f7527ef78f84bb16f6f2a2953128f6caef431028dc19e1ac391a11ac93426dc7 +Prover_pp hash: 5b3c14095b5fa9b05451285fcaa33cad30f6be770d63b518f2bf66ca27162421 +Verifier_pp hash: a0502a91919003a8d593bc27f9c3a29e6a33e5255474b45368803f00b6e8dee7 + +KZG+qplookup_two_tables+qplookup_two_tables: +Proof size: 4.43 KB +Proof hash: a7c766534ed172cbb5e778c433db094f774d89e05a06b98edc03cf5c2996a692 +Prover_pp hash: 4ede302154681600d8b2a260b7b87f51889eeaab21c053351d5dc6df4ebf3ee2 +Verifier_pp hash: 6eba17b9048af415f143c7c34921157fa0f1490dade42e59316b0ecfcae991a2 + +KZG_Pack.qc: +Proof size: 6.71 KB +Proof hash: eb2d81074f6af099a76c0df92f17d7463d477b8a0f5674b280457da1c45f2536 +Prover_pp hash: 5151b594aa418c3ccc8cf9b396542342fbfb7fa985e54442401b646bd48b3e07 +Verifier_pp hash: 4b00da5fe7f792b2c1b9b3de90fc949c9ff5ee1e05bd7c7127d2021094392c66 + +KZG_Pack.ql: +Proof size: 6.71 KB +Proof hash: bc16084a9b50e2c3e2fb87c7d50b7516b64a3a399ecc7b253afb1d1611528ac2 +Prover_pp hash: 2505fcc4ac61c1fed5d7c00d3f5a1c91c04d8b7391805c1b2ebf3e0874f22198 +Verifier_pp hash: 9a8d116e17690a38f09799682f5fb4f62b1c5d1527b4fffb9c109a4291304b59 + +KZG_Pack.qr: +Proof size: 6.71 KB +Proof hash: f948075eea10794d390154b10f1d78ee86e8bcab3aee5907f43a8e6c974dafc4 +Prover_pp hash: 03c96bf36a3dcc25df80bb6e7be27bbb1f6c9996f444929093668d1c10494b41 +Verifier_pp hash: 85ace7b6ba35947ad50cff206af5eeac41536c9bc632bc2d04d9ceb8c0ad1ca7 + +KZG_Pack.qd: +Proof size: 6.71 KB +Proof hash: adf69738b1fb6c75c43fb8db90fa629e43d8146605c406f63d604006e979f623 +Prover_pp hash: bd389ce58dfce31cc8184257c3480937d9b080e1ffab58d010f888abdeeeb00e +Verifier_pp hash: 69a898e0d99195da9d8e2aa5286c86203d4bbc41b1bee5fed121012d0ecb54fd + +KZG_Pack.qe: +Proof size: 6.71 KB +Proof hash: fb27ed82dbb8c30dca55d508eaeaf0aaa157ac890d2bf24431a43d4150240248 +Prover_pp hash: ea9cd7fe619e01fb6374c0b5b1582da60b1f2733a70e7a3923c171e568dc329b +Verifier_pp hash: 2829b72ace62ddea3ec1d1004a9235fc1812ccd5feb5df489c88903d54c6007b + +KZG_Pack.qlg: +Proof size: 6.96 KB +Proof hash: ca4980f4da48c0df98fa9235296038e4f35ff2cb7e18054ae83faeb8ea13774d +Prover_pp hash: f488925b0754f0c0ff3dd2640bb68b9b3b8820e410e69703a289e2bea4f50c9b +Verifier_pp hash: 3e974370822e19c51c37dcfce5c46858f8e6d810b4ea1cb98c25489cb9439232 + +KZG_Pack.qrg: +Proof size: 6.96 KB +Proof hash: 8eee45bef7d6cb38252ce8a5a30d3e6ef808fe62956aa7f9ed810b041080ad69 +Prover_pp hash: cf2fde5d7a7447cdafc2a1eb24fbd425dbdf8f72b2f205259eed5134fbe73f33 +Verifier_pp hash: 8138852825717285c8c93caf4b36052b5600a87cc7340e648bed7e4bfcb68183 + +KZG_Pack.qog: +Proof size: 6.96 KB +Proof hash: 71592e30912246e4af8a4f7826c3c297b38d022007478b731f573d80a1f90543 +Prover_pp hash: f77b5637cb691cf95c08118501a77894f6e141f2544708c7de80a447bb2aa804 +Verifier_pp hash: 25906d181c03216aa5cf0bd198f0712895335a5165776fd70576245a2750556d + +KZG_Pack.qdg: +Proof size: 6.96 KB +Proof hash: e7dd464179236c5d2443f3c2d47e1ad3a7a032bd3075e669c9751daa2f42ba89 +Prover_pp hash: 1c25fea62a8032d2621143b9118f2881b251ce78417a58329de6ddfbcab4e064 +Verifier_pp hash: a6e7dd5508eddc9314b622e9c8648e40db234cccf884ed6cc6f84024249d4642 + +KZG_Pack.qeg: +Proof size: 6.96 KB +Proof hash: 762ada940dcdb97173f58f9875087c7612d29252e69002b23b54ad2daa219c8a +Prover_pp hash: 3af382c67d8dcb361aa943208c15ffb26705cdff33c8d78a1ab607cd8b140e03 +Verifier_pp hash: 162ff4588173a6543aae4bbba72730ebb0cb9d44c758ffbee64e28e2a7e1fe9b + +KZG_Pack.qm: +Proof size: 6.71 KB +Proof hash: 8c9065f0caa79578e336820ce96808bae16c90b02a957afb6f91d274e9fdadfa +Prover_pp hash: e446380b0134075c12c39fd0b29a45a278f6d68fdeae8d069c2d91a79c7cbc1a +Verifier_pp hash: f954a26d1f033e9f320611c3bac5e9f9d46a1c3cb03167d922c5680161917853 + +KZG_Pack.qx2b: +Proof size: 6.74 KB +Proof hash: de4578ec7caba05259e647a205ec6192f8fc9e1f451ceeadf6e376c796cff011 +Prover_pp hash: 8d98b727ef6a914f4145823757025638ea71a1ff3178fee2ef977c3003e93605 +Verifier_pp hash: 3db034fffcb81fbbfa36ea1c5008f2ddb50ff05ff3efd0b6ac93ae18225c3029 + +KZG_Pack.qx5a: +Proof size: 6.74 KB +Proof hash: 9dd246a5672e3c3a01669ec376c12567c66917d9227dd11ec5fd63cfb255b4cb +Prover_pp hash: f24d54983dbea887d02c4276c69d366605944633c34975b8f3ae968de81e08b3 +Verifier_pp hash: 92bc09e2a078a8ca0c7d60f8cf2b4bbb991a52c5f2c1cf6d0633b4638d8976ee + +KZG_Pack.qx5c: +Proof size: 6.74 KB +Proof hash: b80bf7b5bcc7f6ea0ef544e56c1b095e9d64800731fea6951fc32d7b69114a8d +Prover_pp hash: 22419b4c5a3b13eaea6a02f19bed41d8054f3e9d7b86270fcffe20c097096c7a +Verifier_pp hash: ba03c097b96d1d12043335e63a3c2b9b9e77141e0eff37e96f7106339689d4f3 + +KZG_Pack.qecc_ws_add: +Proof size: 7.06 KB +Proof hash: 2f8d6e9374a9285e8e3ca7a51e1e8a7d5b7c348a6c16074879f2ab797f920f29 +Prover_pp hash: 4eab1708b787fd5824604793a55a58b85cabcc0bb6214626254f736fbada8494 +Verifier_pp hash: e5c67dfb7c88f3f770fd152fb0f3cddefb9361384f691f03607cef942330801d + +KZG_Pack.qecc_ed_add: +Proof size: 7.06 KB +Proof hash: 3746ddba358ce3e871ededc280612a92f639d9c00c05e8882cbe462e0101906b +Prover_pp hash: 7d22443f2be447bc8791b465af0cbd9b7b620322f30912d66b117390f7059976 +Verifier_pp hash: daadf165fffbda6e61faa90df92ee50372b4516ef1e831438d55af418a92791d + +KZG_Pack.qecc_cond_ed_add: +Proof size: 7.19 KB +Proof hash: c12dbfbed51ff147e7b81fbd9c6108799777762571b2b9b9bd463cf899c41500 +Prover_pp hash: ee0bd68724f840202f3a8802ee919bc787094203d8d458d2cb6c38e4ac35870b +Verifier_pp hash: b33a8214f6ade48285d1882ebc3afa96043d21e874c9c72f35373c1800980c0e + +KZG_Pack.qbool: +Proof size: 6.71 KB +Proof hash: e28123f691069dea4d744a260d14902496af861109d86852d498915165698494 +Prover_pp hash: 9ab001b470f2c4892cbf3d67b0c5ca448760d5159561c8272a9d1e531376f3b8 +Verifier_pp hash: b289726172165f2e18cf6b00af4edf931e6e295215a7aa1512be0a152799c756 + +KZG_Pack.qcond_swap: +Proof size: 6.78 KB +Proof hash: 40aa06895549843ab31c2f748450fc7cb53bcf6cea35ce2d0a88e8cdcc16d0c0 +Prover_pp hash: 87367d6b8a6d479ce63126bac751e2adb5b67900f0ec5b1738eea1cff0115a20 +Verifier_pp hash: ed0b0cec2da61ef2b0fcd7c7ccd81ada574796b3d4232190d0eea4c7a208c4fe + +KZG_Pack.q_anemoi: +Proof size: 8.55 KB +Proof hash: 31bbc4f459367e1d5e974d23312f5599fdfbd57919f495b2ae7a1de239e8b0a5 +Prover_pp hash: 4f940e4e3b2dca2422172c37f13e3c225837af3211c7318687eca865eda9cd79 +Verifier_pp hash: 0e1798f7653c62087f76d1da16f04f2560b7656c81c85c8a003eba6cfbb427e4 + +KZG_Pack.bnot: +Proof size: 6.79 KB +Proof hash: 71591537dffdb3772ecccac3083e827cf87b28822dc5d7c4136d081e7238d8b0 +Prover_pp hash: d378b04c8f4ec84a9bdbdf2fa231f889c739f9f1b0299fda63b89522cb1be7e4 +Verifier_pp hash: 248242363ba621fc13abb736ce9f112be76a314ae27fd0d969076d7501a0996f + +KZG_Pack.zero_values: +Proof size: 8.50 KB +Proof hash: 14d358626e8f13890f120d376e4c9a4e06190f132ed8e01e7ef452b6863afe68 +Prover_pp hash: 74a1a9375443c6632c029e6cf20efda9aa5d96b8263cd3edaf43b5387a7b9082 +Verifier_pp hash: 6fac24b55a2dac88e8c29269f443ecf3d3f18893847acd40fd8f6eac51dfc87d + +KZG_Pack.non_zero_values: +Proof size: 8.59 KB +Proof hash: e447b5a3d36794e81b999b732774ea8cbf03238a2c549e2b24055ac6d8c83503 +Prover_pp hash: a3cdd5c5e0b0e6a5a275bc46527ca148d6a4fa2e7bae7a35aab485b6ae910abb +Verifier_pp hash: 3fdd175a3c4f6a31de93134e646834a5b682192275e10fb0662bdd1449853aec + +KZG_Pack.no_public_inputs: +Proof size: 8.61 KB +Proof hash: 0c47ff38c9cb24e89d1aa906f6e367180f2f46c246138411314ff5b94d84d031 +Prover_pp hash: ec41854995ad2d228c034ff6cea60238f9cd44f5ed8033ac38ca99fd3ee9040e +Verifier_pp hash: add925556fdf7e213c61e07fa33989574d37925a741ddc49baabfd8bc8c18d24 + +KZG_Pack.input_commitment: +Proof size: 8.96 KB +Proof hash: 5fb84f904eaba9bae7d48a628973a30a6d7f843b497da29eadf228b3f82ee893 +Prover_pp hash: 51e1595b8f00c746901ed7a5b33ab873dd00c680727e1531ae9c411467958e7e +Verifier_pp hash: 0a332649005b7663f21b5ed05e6130efddb5786d063fa0ebd7725c6f2595b18f + +KZG_Pack.big_circuit.2.5: +Proof size: 8.40 KB +Proof hash: 9215215b90eeb695042aa14f3a814bd21325ded2936baf4e4bf6edcbff0f524a +Prover_pp hash: a32c894fbcc710f861c73698ee850d38c112aeae6b13f76363c24da289730077 +Verifier_pp hash: 6e77906b1b08650520d0f70a9bb828473736548145a4ec72ca967396d1de32b6 + +KZG_Pack.big_circuit.2.5: +Proof size: 8.40 KB +Proof hash: 2198a6cdff8a01f3bb755d882058de1573365592e601c28afff5572296ff40f3 +Prover_pp hash: a32c894fbcc710f861c73698ee850d38c112aeae6b13f76363c24da289730077 +Verifier_pp hash: 6e77906b1b08650520d0f70a9bb828473736548145a4ec72ca967396d1de32b6 + +KZG_Pack.qplookup: +Proof size: 7.74 KB +Proof hash: 5235dc42a91f60aafec831013c0c06ecef062f074fd65fe2c34f787dc9664b2f +Prover_pp hash: 34b43d5e9642744c8040cc803ec04b61b5c2b1da296a91d82fcb9f8d74b0d0b5 +Verifier_pp hash: 56c8af017ebaeb2d774f5d14493c8e3bf4e2ef75bcfb97530c1ed5f00af83bd4 + +KZG_Pack.qplookup_two_tables: +Proof size: 8.07 KB +Proof hash: d961a7b0c25b3da059dbbcec6a7f533c39bb258ba83f594b3c26378b55b183dc +Prover_pp hash: 45433c16333f177eb198ce2b53a66ca886ca59281c167826d54e732cf850b998 +Verifier_pp hash: e6929e6f07bfec256fa3de3da95168ddfcaa0939f5da63f7d0f5145b5a362437 + +KZG_Pack.lookup_zero_values: +Proof size: 10.08 KB +Proof hash: 44c520bc9729f14775dde88dc3e81cb786d63f655fd6ba47697d1c3b4f335d25 +Prover_pp hash: 1dfbca49a3df354ab0611fe8643859a44afcd5ec8c581872f2ec7130c4c0a8ee +Verifier_pp hash: 2b5af21d607f264746c9c2cec68ebafe5b5246d457742fcd5126393c6419704a + +KZG_Pack.lookup_non_zero_values: +Proof size: 10.25 KB +Proof hash: de139246879a8a1e2bedaba70dfe798637b5a0df64bb95c15b4aa4f9e1cab497 +Prover_pp hash: 4dd570692ff4752950b0f01c3d61a0effe1a82db276485cadc3b2db9f262482b +Verifier_pp hash: 3350a89a8476982bfb38d6e7e6012791de927aebb23f43a7a80965780b5424bd + +KZG_Pack.lookup_no_public_inputs: +Proof size: 10.16 KB +Proof hash: 7337697eb9ad4fc377189720e3860a6a404e02a9822e8832f53dd1981cde5980 +Prover_pp hash: 169ef32386b604c954bb33b2a5d3de929ad5ef914a2c32122673c4f85531c4df +Verifier_pp hash: 28f5fdd6065f6842edd8ff272dcc49237c0ad1df23dca28bf3687b463cd86876 + +KZG_Pack+zero_values+non_zero_values: +Proof size: 10.62 KB +Proof hash: c2548a6c62752795f419e69ac3b43af52a8b56038227366bff871bba88113d33 +Prover_pp hash: 14a3c8f1c57cea867a4dea445ac913d56744dd19900b8a9b14f34f7729c7fb28 +Verifier_pp hash: bc814695c9f44beb27aecac42429c2710cb88310137142a87839813c0d5bdc86 + +KZG_Pack+zero_values+zero_values: +Proof size: 8.80 KB +Proof hash: 120e22ca526dc138d027b3608b01e3af366ec707c9cfe6a8f716fa977f873508 +Prover_pp hash: c9860224ab550723e0ee3f3efdf73a6ddb5d6ca5f87baa055c5ee3561c36668c +Verifier_pp hash: dc8e1b1babda79085d53142d3792293367dc54a4c37b87ab17eda653a0469138 + +KZG_Pack+ql+qr+qlg+qrg+qog+qm: +Proof size: 13.98 KB +Proof hash: 65933111561c820f5fa1bdefebfb04a548b8c1b91dc4279a352e03a0a3eec69e +Prover_pp hash: c1f5f1b5247d690d72e2cae3673c09996670e157a693ca42afd2f044443d8f7b +Verifier_pp hash: 3b95a1881dee5789993f11128474fd41f813b6f23d6a66ba9cebed118dcabc48 + +KZG_Pack+qplookup+lookup_zero_values: +Proof size: 12.51 KB +Proof hash: 9bf6373a176789862f64d4e05051e5a5c77fbeeccc71711c3e0581f0433fb0fb +Prover_pp hash: 697a563c9e48fc56dfa0decfa1047081c374ba2bc73462eb98fa272dd5fcedee +Verifier_pp hash: 169b9afae6fa59ddfe692bc8c56cfb7da1547f781e1cfe044220aae650d990c5 + +KZG_Pack+lookup_non_zero_values+lookup_no_public_inputs: +Proof size: 13.58 KB +Proof hash: 8f9300f1886bd61e20ec36c9a3687bf1e4d319bdcbf5f80082302138569c29bb +Prover_pp hash: 4b0fafe99ff25eb42ac0f762b31e44dec7308927ccbcb03a11541c92b03301d7 +Verifier_pp hash: 6922a918184fae3b55f93a921a3a9e285e52a6638a135e969c66b92d066a89fc + +KZG_Pack+qplookup_two_tables+qplookup_two_tables: +Proof size: 9.79 KB +Proof hash: e1b00fc9652bcccb279ed7296d7f62526495a4a6b6886056ef0b32918e3bb186 +Prover_pp hash: 5cb0685c917293268d3def8e565963d7b7853c6ec500b60492f2b1173c8050ce +Verifier_pp hash: 7439ec7c76f7bc5d6b8fcec52113751cc61fef5b17822a91f72d28dff326c045 + +several_circuits_one_input: +Proof size: 1.65 KB +Proof hash: a266423c771624306f212a0a36903854007145072cb7c9abfce7ae92106a6cad +Prover_pp hash: 97a52c45971d2519aaae693eee7aae642e293f2c4cd2bbd810f58e6808790744 +Verifier_pp hash: c49be90792a4e85de1e4f8b0f21e48baed1c93a343e297144f1abcb007b1d904 + +several_circuits_one_input: +Proof size: 8.07 KB +Proof hash: 957411c7e968111f33ae6554eea074fe35456f091a0ee7f6b9b6d47c26e9d2a1 +Prover_pp hash: cab759aa493dff2ef4dda01712a76290ff41b6cc10e521c6c5e8bb28dc9b2acb +Verifier_pp hash: ce465aaf9c325f8babe1f8fe5f23d8ed2a0cb1c8ae77e840af9ec72eb55bcdca + +test_disjoint: +Proof size: 1.36 KB +Proof hash: 1b9e7d3cec65b7a0c0581f08cbe3be91e9a9102f1d6ff3a04fa62d32b49719ae +Prover_pp hash: 729029eb4eabadc8a6a9d3c5bec803092f53df526a909845367ca9d1c93f7245 +Verifier_pp hash: 8b664ba6835ff66ccb16c2df49b55279fc03bcd9b79835f7d9ddf72008cce59f + diff --git a/src/lib_plonk/test/test-slow.expected b/src/lib_plonk/test/test-slow.expected new file mode 100644 index 000000000000..54e7c54407f7 --- /dev/null +++ b/src/lib_plonk/test/test-slow.expected @@ -0,0 +1,534 @@ +Range_Checks_single: +Proof size: 2.79 KB +Proof hash: 8aae21a89c3481da1d3bf00c9fda124be6d5721a0142f68ebd9dccede4fe4b27 +Prover_pp hash: 13e71d9eda1d5fe3d66fd788d178ee6f16931562735f74baa7d5f2bc5d831f24 +Verifier_pp hash: 92471f7e472d711067eab5df2f94865f57e5a9a1ec3914f6a84529b3ea1c05d0 + +Range_Checks_single: +Proof size: 2.79 KB +Proof hash: 8aae21a89c3481da1d3bf00c9fda124be6d5721a0142f68ebd9dccede4fe4b27 +Prover_pp hash: 13e71d9eda1d5fe3d66fd788d178ee6f16931562735f74baa7d5f2bc5d831f24 +Verifier_pp hash: 92471f7e472d711067eab5df2f94865f57e5a9a1ec3914f6a84529b3ea1c05d0 + +KZG.qc: +Proof size: 1.46 KB +Proof hash: ed8ba1a23579e07d2edb3be25bdf8f0efd6c5957c744de856695b40d7147347c +Prover_pp hash: d9604a7324825a9524164ee606d88cac404e7ae48ff3f0455efbb497d8c5276c +Verifier_pp hash: 26eb2fbd6fb864dccf14da21ffeec39cb8339c40aed86dee54bdf4b32f541691 + +KZG.ql: +Proof size: 1.46 KB +Proof hash: 1c178ec365c9cf49d8070030d01422131e9464347330684e8902a9c57ea115ad +Prover_pp hash: f6a73417301c45aeeae7de67147178c8e9983eaf54c970517a0584c37f160b4d +Verifier_pp hash: 5a6f7c693839beefcc548476fd10bb7ef680f8dcf53354d1de7aed72f4a54873 + +KZG.qr: +Proof size: 1.46 KB +Proof hash: 09bcfd8cf9f4c8f6045c6fe21d924a8f4687599b9e690a4174e5130e1fe2913d +Prover_pp hash: ed0afdc072e3c02274d7699be620aff504fcdba1ff7c7a6ff9e5a90e27586d7d +Verifier_pp hash: fe6df32f1013212e3e235a34f28c599ba3ceab3f01e227522789bbcbdc0a6cf9 + +KZG.qd: +Proof size: 1.46 KB +Proof hash: 8707754b92c4aff08e4baf2eb3f097759b1aae114381c5b7e774ad1160880453 +Prover_pp hash: d0aaf56cbd4e96c6eb75a99ae5e7c7e6824772daf467c7d58f57abbf920efa57 +Verifier_pp hash: 3b73a353870c1e3b0ce8c1d03fcacd83107fd915416a345702bd60d9df392aab + +KZG.qe: +Proof size: 1.46 KB +Proof hash: fdcbe7af1ce4fc510a0d2fae0fd28ca0edf03e2d6d46fe8daf94a032863a1369 +Prover_pp hash: 46ab4332b3db8135832ffee86cbf9eacd4e771af5321e59af33c3a59170b537a +Verifier_pp hash: 91de9dda4644eda0fe433954e5ac3f56ed75310185cc24ccd4f4f40244f71c62 + +KZG.qlg: +Proof size: 1.69 KB +Proof hash: 242a8f0d27fdac6d9b0119c9786eb565cf404b88351685ddfbbafc5fb52c85b9 +Prover_pp hash: 040914f2f2c8459cde397d7b196a1d05752ed479b6dbd28ff4df9c00dc687e11 +Verifier_pp hash: f840887fb3144a0dc838e432cd13bf1820df0a50c379db47126f53b112bcc394 + +KZG.qrg: +Proof size: 1.69 KB +Proof hash: b624cd8d7c95cafcdb1172f083bd8adf492ea841305ded057b132eef1b2a5e0d +Prover_pp hash: 2a6b47efd94917f21fc97963decf382b8f0b313ac67e49724380cdacd140c68e +Verifier_pp hash: 7a57d8976af28452cc7e267a8839509e3ed57abdd87ba6975a28838832956c72 + +KZG.qog: +Proof size: 1.69 KB +Proof hash: 756628e758995e8b1a99934db74cf30d728c83a6eb50c90f6d12cddc2d47cdc7 +Prover_pp hash: fe7a9122b5f7d6abfc8823c2e23ceeea243f3b73ad22a6e3ad79466907c501e4 +Verifier_pp hash: f7d9c815e4a4d27f89cf94e08a220b85821d3429b6129f77a8018202e59785ca + +KZG.qdg: +Proof size: 1.69 KB +Proof hash: 13174ce6f9fae92ed9e46dfe3e89463dfeb7564115edf921f4c07da61c94cce2 +Prover_pp hash: 4d05cae813f2cc752b1dfb83f6d8b28c6fecb405de221273afd7b361284a3635 +Verifier_pp hash: 68e52cd06e5b738b4c36fb7fcb59f2484abbf1f52039f0248c5f35a289a07219 + +KZG.qeg: +Proof size: 1.69 KB +Proof hash: 676a3d5397f15e424452d35d29637eb7453726e4a43cc956bfd41f4b6f4bae5f +Prover_pp hash: a810d9bb2299afe2bd5641b83fb325741e08ef016c361929ac9be42977ca1f61 +Verifier_pp hash: 7bccdc25952260075dc501e235016310a029a5f07a91a198d9751603fdb90dbe + +KZG.qm: +Proof size: 1.46 KB +Proof hash: 476013fde332ef2d2923ba08ca13958c7c6389050fbddbede21eb9df01e10f28 +Prover_pp hash: 0cf9763522fce218cdd9ce8158dc1ab20bf212fc092fea40a8add8be8ecc6f6f +Verifier_pp hash: 7ff5822b60d384045de1cc84c99a39804ca89ca6d8202790478c2cf199881a79 + +KZG.qx2b: +Proof size: 1.50 KB +Proof hash: 721e75efd803fb9a2f021f07fedf41a9a841104272179dd7e304144f10dd1195 +Prover_pp hash: 0d0387d5bc64e2522695226e7fab3e6941bef9f1585e1223ce547543a2e493ec +Verifier_pp hash: 35772887372c7d40298729f0e4a75f36701f0527b338abdb8a8bc3e5acb8bf8a + +KZG.qx5a: +Proof size: 1.50 KB +Proof hash: eb73d47b5cf37b05c71880293cd2dbcd727e6f0967804df90d323acf02449ebe +Prover_pp hash: 32caa2f235fdbdb39c690c568852c4d0bbbeaf8c5ff2bd151d59a619c9e39ec6 +Verifier_pp hash: 3c5f064209168da9119d172cbdd9d7c7d7ac152d5eebda62c07cc15c287144e2 + +KZG.qx5c: +Proof size: 1.50 KB +Proof hash: 0ed6a292ba5877129bba6b206e3d3e561a5124953cc2eead0a02cc76004109e5 +Prover_pp hash: 4b91b6f0bbbc69a52bf2490ecfcddaf55aa6d7bb46dcc52f66bf5edcccbc9d7c +Verifier_pp hash: 8d619d1465efd787c703127854e3cdd703fd9ac01eeecff443baa1092905a6f9 + +KZG.qecc_ws_add: +Proof size: 1.85 KB +Proof hash: 152e7e1023f3322a864ef93fa8b95885de71f14749fbf2f74f33ac276c9a8872 +Prover_pp hash: 325955fda54a661f1c59d3c0ae0f9283a455e91ef7b0ba52962c465c83f9ea20 +Verifier_pp hash: 3e4a5896d199a36c59738c9691a919b51a1e7523d320f45f2bf96f2325b3b74c + +KZG.qecc_ed_add: +Proof size: 1.85 KB +Proof hash: 9fbd1122d20ab742f9365a6338347728497f2049272e127141ab6dcace071167 +Prover_pp hash: 2f036feef975cf82dace8ddc3a74f7f6784c74bdd75e3d9665041f5ab051c687 +Verifier_pp hash: a94fef8ab7b5229d095703db067a14873fb8dd70922388a50f98a7d88f242049 + +KZG.qecc_cond_ed_add: +Proof size: 2.05 KB +Proof hash: f0e86052c82fe7745bf58d2ba029d1887a734a99ec559668579d290f2e1af6b5 +Prover_pp hash: 6fbc3c8aaff3956177a65f9d9642751a23c4730599dfbff4b5d0c177af09542c +Verifier_pp hash: 2f5a95b6f094ecf95861f59af367d2bfa4431ba801a290c42800efd4d72ce1e0 + +KZG.qbool: +Proof size: 1.48 KB +Proof hash: 6f240d81cb68f114256c1a26986db6073281d948d5608eb4cb98c20c10d079a4 +Prover_pp hash: e807e1194dbfe4accf461a91f74678eb45e9ae3c7de37999a16c912329835b4a +Verifier_pp hash: a76436b6d833084b46c18717710e58a91406e546af5e3183570e190f64dda7a2 + +KZG.qcond_swap: +Proof size: 1.58 KB +Proof hash: 55d70ea169f55324d37f831251278d6f3f53d7859cc873978bf7e2c1b4ec50d7 +Prover_pp hash: f4c150b59be667e035681a0422574151414f7d06af323a479a7af9fd717805a8 +Verifier_pp hash: c9ccee34c07500eae2ee8b3b4bbd2accdbd23ab4142e3cc08fdc526d56e85237 + +KZG.q_anemoi: +Proof size: 2.07 KB +Proof hash: 34a498d94372e0a75e3468eb36b9911cc8e8e78b44e30213d2a6043d23975649 +Prover_pp hash: 65093f62dc26a2f5c5340cb5a520917134c03aac05b4a909e0fb330aec44191b +Verifier_pp hash: 966c75a36c9a59fa8014ce82a525531714a96e014f98778952ddad95fd3fa821 + +KZG.bnot: +Proof size: 1.54 KB +Proof hash: 2a09dd60c4e1c393d8983fbb2b4ca4a9a9b92a476f95ed566d13115b350108f2 +Prover_pp hash: 9aeca9c446af0dae102ecde4f5625dc7f610ad6fff247459d89911aeef086843 +Verifier_pp hash: e170093c6ed66eb7b897e1561321df66b2612d92bd50313958ded86054b04ef8 + +KZG.zero_values: +Proof size: 2.04 KB +Proof hash: 94aee4067637522644d922699dbdebe56308e6aba9e63c0c80422f5484379ce7 +Prover_pp hash: d556286d3a8bf77f3bf20df380125f22c2a25ad13acc75ff755053158463ba06 +Verifier_pp hash: 3b19dbf36c7421e55d1a9203098e93436ccaafc52b70cd64f67666c9d34d65bc + +KZG.non_zero_values: +Proof size: 2.15 KB +Proof hash: ecd4d3f179fd49a2332a10af38405c1a397fc5eb5458a42ca08eafb4f10d0565 +Prover_pp hash: d97dcf033e78840a6a655b66ae2021d5deab2145864dc7c88e5b110a1e8f64fb +Verifier_pp hash: e513e8ec8c446cc8463b135d42a5053ed08367a5d73c2e803e9baaa3c95e9dfa + +KZG.no_public_inputs: +Proof size: 2.18 KB +Proof hash: 20b383270814d0ed0045d0b8e3c8d2eb0d644a7b35ee78f3311f10bb68443b7a +Prover_pp hash: e2dfed8e51f7745be337c94a09d3bb27c9cd479a75093e603d350fa41cd800df +Verifier_pp hash: 07c7f6c0f08ef4ef793a04fc2c1ad25644803ba61b7fce03768b90719e9e9399 + +KZG.input_commitment: +Proof size: 2.42 KB +Proof hash: 0ba02eca2298a2a40168e0f60877d2b114d5e6b733fd9711de60cd77f28490c2 +Prover_pp hash: 8fd63626e0c51b19ac7ed52394384f65be3c712982b9d34047421e8b5b1f56b7 +Verifier_pp hash: f7dab3788f8034f633c24381512a4b18254eee7a6b7d7ae077ac451fba35ae33 + +KZG.big_circuit.2.5: +Proof size: 1.99 KB +Proof hash: cf08fd3ed9c7c14bcc4771c1bedfd861e516d70ac3cbc4aa817268261f8fb5fc +Prover_pp hash: 592ec290062860351758bbab4c1008966c372315d7ce6c1b95dcbc2fed3e6d38 +Verifier_pp hash: ba7d2b30fc1eb0349e7d385a82ed0af82f23deff965aa85d01a76e1167ecd35c + +KZG.big_circuit.2.5: +Proof size: 1.99 KB +Proof hash: 2d71253fb30f8db18a76e246e06887b6224e2cb41c162da386cab41721ea25e6 +Prover_pp hash: 592ec290062860351758bbab4c1008966c372315d7ce6c1b95dcbc2fed3e6d38 +Verifier_pp hash: ba7d2b30fc1eb0349e7d385a82ed0af82f23deff965aa85d01a76e1167ecd35c + +KZG.qplookup: +Proof size: 2.71 KB +Proof hash: d4b4107dddca2c7e20be6028282f7c005c81c123c5b5976eeb28a0554dd2f8c6 +Prover_pp hash: 1a34b79bf635be5792118459d2369b466a229f1b88513e179c0d4a3a6fcb7891 +Verifier_pp hash: fae1bbc752308b9456f7c627a5d5bf54138f184fe2e16a0157b3329066c118db + +KZG.qplookup_two_tables: +Proof size: 3.15 KB +Proof hash: 51b75657ec66cc9dadee1261a1545f05d6743fb285ac1105f6d853e8959e7f67 +Prover_pp hash: d2bd014c4577f5f16759fde3f023e11290a5ab54968ba179a1bb99622220c522 +Verifier_pp hash: 97009c497f96f2779dbd929b9d71b59408f158e453858bace44501b456837c37 + +KZG.lookup_zero_values: +Proof size: 3.86 KB +Proof hash: 6d7509f0469bae4a1a18093d559b5183ba4363848de3cf47705455b462b2b2b8 +Prover_pp hash: dd233083394cdf7794348f7c0425e01d10dac08861a68069701954339fa992f6 +Verifier_pp hash: cb644009c23d60ff7df4ae5a35d37504dc8d587817975afb1020e9e2a7d41fe3 + +KZG.lookup_non_zero_values: +Proof size: 4.07 KB +Proof hash: 9dce07a3f4d34e52568a2cbf23433fe76db8e10a8aa8b4324618c49f01ad6c04 +Prover_pp hash: b02dc32979cec66536653fff48727346af6cc50000f8c9a8c85c78e88f2a5d0c +Verifier_pp hash: eb9849980af045288c0498a1305d1b48a040caaff64737b8e8ca0095eded6080 + +KZG.lookup_no_public_inputs: +Proof size: 4.00 KB +Proof hash: 3da2cb08704260aa671c9624540b9223fccfdd27f458bae42ee0d11d64a59f76 +Prover_pp hash: 9da12562bdb6529e9cfd131dcc42b1aa1f9f0f8eccf839f8312432e9b46cbac6 +Verifier_pp hash: 1d81b906feaaa844b7861bf40805ea6595392172bbeb14b52e17e4e355ce8344 + +KZG+zero_values+non_zero_values: +Proof size: 3.42 KB +Proof hash: aabe651d2a5ad8d5e816cc2d7a593250e768e570d345fb23a4e089f5d62da1cd +Prover_pp hash: b4d334a91b8a7eea5463936ba9d86c3ad6ea572fe729de4857f82842cb7253a6 +Verifier_pp hash: 3c05937c745ee3b6308cf42507edf048a1d310f6a1bea6f0eb1c40c17895c4fc + +KZG+zero_values+zero_values: +Proof size: 2.75 KB +Proof hash: 4f98b9d6c15a997bd6d0d50a49dbbbe02e574e1d39ad0266d3bdb5e2106f6656 +Prover_pp hash: fb7082558341156691e966b532a589fc98bc7d202c80e786a0c6154710265108 +Verifier_pp hash: 8edce321406c38c48012fa00145c5752f2bb2eefab35c90e59f3fe497b4a40b9 + +KZG+ql+qr+qlg+qrg+qog+qm: +Proof size: 6.69 KB +Proof hash: f53a73e047c3fc130a8e682a2d256d0e38334d7637f688501b192797eb7e21a8 +Prover_pp hash: 4d91878ebd6c460392a247062762fb5539b0062a21d31505095eddf53b545652 +Verifier_pp hash: e9d8bc2cb68d29f4af12f5a13cd60966d2dd886115479f106424a1bc83d40b4c + +KZG+qplookup+lookup_zero_values: +Proof size: 5.84 KB +Proof hash: b622408c88a141e2371cc0fb631f701cd89013331469c4ba9a900ccd1e1f59ba +Prover_pp hash: af1de7f7bb141351467aa282e10f22b2e0258f5c0e6b2e83e1e933d2a874cff7 +Verifier_pp hash: 667202844d0a48e2ef9b580ca5b2776060e78eb7ce917db6aefaca61794997ce + +KZG+lookup_non_zero_values+lookup_no_public_inputs: +Proof size: 7.09 KB +Proof hash: 2d6be3d383cc874b2622dc9ed38b71d8572ed47dfe520fa718fcac995f5abb6c +Prover_pp hash: b193e1dd939476431462544ba12061e41728de887d965c6aefe6581eb337e200 +Verifier_pp hash: 6cf93155e986aab117c20b675ab8659201bc5083a70052adecc8072195c390a3 + +KZG+qplookup_two_tables+qplookup_two_tables: +Proof size: 4.43 KB +Proof hash: d2121cb0dec27135cb79603e90a51aeab5bb4f89813796eaceb548e35265d024 +Prover_pp hash: be222706e0a29ecda7105ebbf86e780a1306ca843225f64588a2697af63262c8 +Verifier_pp hash: 341ead935b4a34d161b04a3d0d8f4a043f9b581bd6543266daacb3ac06d68bb3 + +KZG_Pack.qc: +Proof size: 6.71 KB +Proof hash: 5778af7ec0f9bedc5b067bfedbcb9e1db47e15a929772af5e301f47bdf9b497d +Prover_pp hash: bfef559aeecc8dd9c52184a5ce64ad18f8a7095be7fdc770128ec63b07327ed7 +Verifier_pp hash: 063d60866600b31c77f1e2b645510c858ad1bf42914602703edb613eb15c78be + +KZG_Pack.ql: +Proof size: 6.71 KB +Proof hash: 135de834a72a7ed9b2d4c950f03b4d35eaef1e58c8390c140bd2873e91257b8f +Prover_pp hash: 253addd4229f917fbd5abb46f9796c274ac8dab70e9f7b326c870725f9c309ef +Verifier_pp hash: 79c258c4b5165af4d7bf8c697bf048e0f24cce23d20d28de56f1455d1e38414b + +KZG_Pack.qr: +Proof size: 6.71 KB +Proof hash: 7569392ad2c563dafb31610b2859a31fd3107a7f731ffd22b0c1541a29a95b32 +Prover_pp hash: 238047922182bed58e9ff0034e9c1e255509a3414170469166ddc9cd280efce3 +Verifier_pp hash: ff994915215d4336668b63692ff163bdb70dc22589e35d30ebbbc3d827903cca + +KZG_Pack.qd: +Proof size: 6.71 KB +Proof hash: 1d1616b653fb8bf168af76ee87ff2873126768e835c45f37f08fb05e871ae308 +Prover_pp hash: dd0131312b1618c6a56167177cbcd02b45705c07e2199eca74dc61bad396aba5 +Verifier_pp hash: d61ea0a9af097fdb22c1871091a1d4d536930668368bc2794a459ea5efdc5a37 + +KZG_Pack.qe: +Proof size: 6.71 KB +Proof hash: ca2ff96a7ebe117ddfd88df77606024d6ca93dc420759fe7c30879f7171460d4 +Prover_pp hash: 416b8c424963bab6611da33c16465260de983c0584fbeef59c11aca15921082c +Verifier_pp hash: 09b23dcc3e10bb767c09e583bfd6375f2eecd637765a3638437c9c72bfeb25c2 + +KZG_Pack.qlg: +Proof size: 6.96 KB +Proof hash: 10d22bb35eb61df2d496d7e25e493f4efc9739714169a8b53768a3423b673f9e +Prover_pp hash: dec468342601c2e4caff07cdc3cfb5587d985b135514922e8fbfd94eb1bf8e91 +Verifier_pp hash: d4958faa3a6959f3729b5aa7680513c2a880c8b6e7006fb9f9dc09b6732d0d40 + +KZG_Pack.qrg: +Proof size: 6.96 KB +Proof hash: f01d75a0162b5d757d5ff39b2ba00bb094f4d0119bc53eff96bd9a7238955903 +Prover_pp hash: 740fa42826d4f468ec6864473528c308a637781aac64a90785866475fc26a90c +Verifier_pp hash: 34401ad6ac74b03dbf7ac413181ed7b1edc08b186941733dac19da5b13790946 + +KZG_Pack.qog: +Proof size: 6.96 KB +Proof hash: fd3e23f68298c1288fe3736e63e7258a5ee4b2f020727454c5f39dabd0d10e72 +Prover_pp hash: e628eb1215936e436aa3d2fa27c84bbff39ec47f33d337602d04db440ff03c9f +Verifier_pp hash: 5a148ea5513a9235980c5305c8be60fb008b7cd211f498941575afad384b1369 + +KZG_Pack.qdg: +Proof size: 6.96 KB +Proof hash: 16eb4083ed6e9961f761fd7462f26aedda00be9be158a31c613c4a8102671d26 +Prover_pp hash: a5369a9c59b8000445e0bf7a3c0a722dd4bc327b276cecbf608cb298a9e9b993 +Verifier_pp hash: e566f816aef92e9ea1d93d4214f1a883679a150ef4aab96c13e964edc918b5e4 + +KZG_Pack.qeg: +Proof size: 6.96 KB +Proof hash: c10648fcbed11e7eb1dec6974c281f1819bb1e9a110541596669dd4e274b4b3a +Prover_pp hash: b5984ad626122b3d16ba831625f6d9d9c2d24c71db1a1a86ab8be96402454d47 +Verifier_pp hash: 817cf7fe4d8e419f4dfcacff99e21a18d5639b42efe82dc953e292bba2f7173d + +KZG_Pack.qm: +Proof size: 6.71 KB +Proof hash: e6d0ec74e33c27c75d8719f4e095f70ab61e97a6a6f5ffcdfb8cde36036cbd92 +Prover_pp hash: 4bb8864d911bc3c4f6cb636f93bfba6bdfb21b0aca47a501219c18f8525c520c +Verifier_pp hash: 84f68443292533101f451fa0cc447ed37004ecb6b6d65a88da296ab1d1b9fad5 + +KZG_Pack.qx2b: +Proof size: 6.74 KB +Proof hash: f0751181b6385934dc323b37e78f4bbb312025508f0a901a87d10e75c6dddf77 +Prover_pp hash: 3e2708280bbec82e6234dc93662958519706bc97ae36b87bba5a4bf8bf9402e2 +Verifier_pp hash: 1bd3cc26d391b63694e3c08b3225ad16c61bf4871ea78866455671fad155f691 + +KZG_Pack.qx5a: +Proof size: 6.74 KB +Proof hash: eeedb4c62ebf5080c8147a6a2a90a5552a6f25fe36a5ab10c826282f3f44fbc0 +Prover_pp hash: 7c3abd0c213f4f49280d6de135639d45ba285ec2c2f3844cc2701a6b27f716ce +Verifier_pp hash: 4cb934f08197900f74f7db352a8f51f4ed43c325c8440c403d7d88932788294d + +KZG_Pack.qx5c: +Proof size: 6.74 KB +Proof hash: 5231b8f945c8c29d45b9ecd44cd92ffe403579cec14f20a71152af41351e077c +Prover_pp hash: bf838ef6aa25b0c71701e5cf962dc9d8de507de3dbd0d03e63b1a0373cbc81af +Verifier_pp hash: 8f280e67081a60b6616e2ad222aa235243a176601bdd6fcb210eb884359966cc + +KZG_Pack.qecc_ws_add: +Proof size: 7.06 KB +Proof hash: 4014bbce63e1e10ba229f9ac3fc30dd063e570f88db88d47ad8fde92c2be191f +Prover_pp hash: cfb1a4456db2751f9dbef65d23d3410f2c1f5c8875dcfb5a5146ce3dd5d77224 +Verifier_pp hash: cfe9b0c0fc7e94837e369a6d5d008de97d14372dee20627ed4a979e369aad0ff + +KZG_Pack.qecc_ed_add: +Proof size: 7.06 KB +Proof hash: c6dd169c48ec3e5c8b3d62b785e72b09c08f0b95ca3ae19fa94eecf6bbf74b4b +Prover_pp hash: ea72166e4b4936b0253064d9a32d9ce2c750cc01aae40c85f3b63b8b2bec96cf +Verifier_pp hash: f274fcad8ca40868a082eb89f8faa470ef9e87d746a774f5ebd813ac0f688f13 + +KZG_Pack.qecc_cond_ed_add: +Proof size: 7.19 KB +Proof hash: 76399bd5abcd6faa8d52c5cfe4c2b1c0bdd8703e2b3ea56ec2ea83e5c31d04f1 +Prover_pp hash: 17780a9d895e9e5cc039897cd932d887aed15b936f912c5c3ac9fe7abd991e69 +Verifier_pp hash: 2ece190a3d439ae870ae85fdafe63c11c61239200fb81f6c733def34875e34f6 + +KZG_Pack.qbool: +Proof size: 6.71 KB +Proof hash: 3f5860e345b8555a6fcce6ac8c81dfc3229afbf8ab83246590f90e4123576869 +Prover_pp hash: 79c1dfab86c1342d58eda39cc28a34bf730741f2e69eb82b377cd00fefd477fa +Verifier_pp hash: 900bb6f55e5650f418a7ed9bac30702688b026b6e2683c072d041066a0f7d39e + +KZG_Pack.qcond_swap: +Proof size: 6.78 KB +Proof hash: 16f75c7d837778c7e6d796d9c721f805f8223c36b8c5adfa5365b6bc63d4e38b +Prover_pp hash: 41a73ce7840125a10a91a31b827aafa8aba0f4a2ab154b067ae60cc3c37ca868 +Verifier_pp hash: 3b6b9903a0e91c55dcf38d4f7a1f6843d5c3e72dfd73e8cf8f61e4db36d0b238 + +KZG_Pack.q_anemoi: +Proof size: 8.55 KB +Proof hash: 26d5498ddb4ef9df8fc3d37d46f0a4d18757566c65fc9ff18b7a6f173a086a65 +Prover_pp hash: a2c30b77deaead72341a9db6d1137b006a20f64aaf471e671b68b2d2927e3eb2 +Verifier_pp hash: 363b15b999755dc08eeae64f93585ccfc9ae4f7f1532fa98e6fd8ca7f5cdd616 + +KZG_Pack.bnot: +Proof size: 6.79 KB +Proof hash: 643d50efb8e5202c302bb47c6c70576d0e976989c8174d2409a1d5b7d9b98ea5 +Prover_pp hash: d23019947f497822a9f542a90035f3a6353ce1112da1fdde62bc47d3f398a678 +Verifier_pp hash: 4497b60c020dce4881663b3fa65f4228271197168f57a7e5e5676653bd189f12 + +KZG_Pack.zero_values: +Proof size: 8.50 KB +Proof hash: c7921f018b7fc584f5608e16035c3a532e9bc28cb81c5b352720b04c1381c51b +Prover_pp hash: 422dbc7cef2dcaf06f37034b306f3597cbeb8a0a0e679b31d9865ddb0c59eb90 +Verifier_pp hash: 28a145ac5bbdce7ccae09b568e02c7da34b6205701e240f9d549a1d1666846a9 + +KZG_Pack.non_zero_values: +Proof size: 8.59 KB +Proof hash: db0acf0f9abac7201dc37b802f51c44c201dc757f1887f800f6c9204c7e1aea6 +Prover_pp hash: 69d69426ec677cfcaa281185d2735723244c25e189eae97acdefb34342674b40 +Verifier_pp hash: 31d60a7121d9a09c82a9ce4b97dc40ca6f73aed2bcd83fe25d099486c002b030 + +KZG_Pack.no_public_inputs: +Proof size: 8.61 KB +Proof hash: 6cb5b1600ccabc8c554a4efd909c216af0f67d8a0f1c0b8200baef9eab39be4d +Prover_pp hash: e3e5d57d9b701a7b82dddf696b8419a97371b6960d309efdbce8bb2c7405d303 +Verifier_pp hash: 2507dffa84f622b8dfe8157e02105204692234f6e47b7da2f1a3bf7ebd49ce8e + +KZG_Pack.input_commitment: +Proof size: 8.96 KB +Proof hash: 009d80193fde3d5b9d1ab3882a55206267d05f092a69382a55fbec7aef5bee0f +Prover_pp hash: 5d750e370ca8e43e3c1441747f81844617c632e6e99c436186ce9d1ede6d3b34 +Verifier_pp hash: 0912f48dfb284f39dbde9649e2671c32c96087557ac27c5ef05b2b0df16075d6 + +KZG_Pack.big_circuit.2.5: +Proof size: 8.40 KB +Proof hash: a6dd0994786cbe26b64ef6d69ba8d82981fe2ba1eaa888cd2466f11f4fa424fb +Prover_pp hash: ee1a8eb431655d052e511310c2eb26e97efa065bb21514acc9608d4f76e25bcb +Verifier_pp hash: 52e3bbff3b4f2009e68c5b78f475dfd22d8be11904957dab2f9ce10f4ae210e8 + +KZG_Pack.big_circuit.2.5: +Proof size: 8.40 KB +Proof hash: 258e6f1f675680ad52b8bbf254e2d366521cce62dcf83a1062d7ccfcf3b0e78b +Prover_pp hash: ee1a8eb431655d052e511310c2eb26e97efa065bb21514acc9608d4f76e25bcb +Verifier_pp hash: 52e3bbff3b4f2009e68c5b78f475dfd22d8be11904957dab2f9ce10f4ae210e8 + +KZG_Pack.qplookup: +Proof size: 7.74 KB +Proof hash: 9b769c119ac90a22189f36685b78040ae758c4abfdb729445d2acbfc85319b47 +Prover_pp hash: d9beb3365a16db0d2e3fcd119b858269d7cf4920c489e061ddd3f1a1c43c6afe +Verifier_pp hash: ee1e8bfbf1b076a4f1c6a3862c68449455a38ffc3a5f702a2d435e964ea97937 + +KZG_Pack.qplookup_two_tables: +Proof size: 8.07 KB +Proof hash: 505251f9bcc344cfcf39364aec137dc440d3646eec261d4b00abb0ddebd9a5bf +Prover_pp hash: 3c41a5ec6cb0788197c353e9deaa7d199f4841007ab447194264dc37e7eec8c5 +Verifier_pp hash: 9f52c2ccc8d5e7b1af5233b944145a53d732ac3c7b709ce0a507ede745c4e0e4 + +KZG_Pack.lookup_zero_values: +Proof size: 10.08 KB +Proof hash: 5c2180213ec4e236a6f98554253c88a8af3116d3224b2bfebe9a92d572bd0322 +Prover_pp hash: 78d458c9360d4a0256d5c6f3dfee7839b1174ebcda0cf68cf93b9b3970fd30da +Verifier_pp hash: 2f4bb4b2a4f91ae4f9c024682a7702d40f6975e72e7d98274b94a53b021fb0b9 + +KZG_Pack.lookup_non_zero_values: +Proof size: 10.25 KB +Proof hash: 7dfb97f6601de310403c2d8d70efffb72ee5ce62fcb584b0141e56ae59c592c8 +Prover_pp hash: 7d4162b4d14079d208e58cfbb896f15e0e069093939b9068627a9e2bcbe977da +Verifier_pp hash: 5b6c6eb8da7a7fe9d44f2c519c761aa4f95710cc1465043377ededb563cf0bcc + +KZG_Pack.lookup_no_public_inputs: +Proof size: 10.16 KB +Proof hash: e9394a52cb5ccf6db19d39cdf42a27b0231b0d88d587b7c17f64572c7e8e2f41 +Prover_pp hash: ba9999118e00914c44608a3bf31cefcdc0476ec484c2da8884c35c06a5865cd3 +Verifier_pp hash: 750c681c3c3d05af1b128d12cca0ccd7d67e4adf59c7c3282959c0050faead20 + +KZG_Pack+zero_values+non_zero_values: +Proof size: 10.62 KB +Proof hash: 7d7d8282a011bcbaff41dfdd2f37d01b41c1bd24c0a6adef038e308cc6c315b7 +Prover_pp hash: fd59d5bb43ba7ea94e63a4b54a26ebecf3a4328243077416bcbd02638d16b921 +Verifier_pp hash: 3dce0b25178e6eb8052afa94633c71025e1df97b54e5a4c1b16e15e0b1f96608 + +KZG_Pack+zero_values+zero_values: +Proof size: 8.80 KB +Proof hash: 3dbf0bf66e9164789ea352737427bd8ee3680af87b8eb429aa1ad8f8b331213e +Prover_pp hash: 8dc79ed13dfb80abe0f78e358093735f0c1ef72327d6d2e1a2c782be0d0b314e +Verifier_pp hash: 9b43bd04449d30002f36dc8f6e682749562938a122e8b7a5b04645e99839d41b + +KZG_Pack+ql+qr+qlg+qrg+qog+qm: +Proof size: 13.98 KB +Proof hash: a20c5dcee623acb95db57e3df224932418f3973c8e06a9ac384069e1a7398d83 +Prover_pp hash: cacb4e6ce9cb5e785e63cbfa29ffcc2f579d075a909eb43eba76827890cfd6cb +Verifier_pp hash: ad71d72e6290a8907907955ea0c0db9d9dcf7416bd88f7aaf6dbdfe54926aaf7 + +KZG_Pack+qplookup+lookup_zero_values: +Proof size: 12.51 KB +Proof hash: a2293e9a0365294d71a6b00fd3cfc57709c0cc5a284432fe60d491c364abf180 +Prover_pp hash: 873bfcd75b782727bd5233ff2f6c2b66c5e03dbe760514d31a94f557244a2034 +Verifier_pp hash: 2f3358e49a9be4d5fa1078edc774e4299fac4198963990bd403da903f47ca75d + +KZG_Pack+lookup_non_zero_values+lookup_no_public_inputs: +Proof size: 13.58 KB +Proof hash: e3d641052c08c9fc1e12d085043b0ecad74fccaacf33162a816c908d38544b75 +Prover_pp hash: 64d1d1d4b775895c84043e2df57ea47a60618eab715d8b34bfcae9981063787c +Verifier_pp hash: d8eb0c842f3209656b598fbaba18f5dc874d082c08ed7f94adcb36e7ccf4328f + +KZG_Pack+qplookup_two_tables+qplookup_two_tables: +Proof size: 9.79 KB +Proof hash: 18d54de7976c605eab8c8ba502248beeba6db4d6a886ef767efd7ce70d36c56f +Prover_pp hash: 7736b1fb4bceca964be9c28c2108879bc498f622ef0145223e1942bdb10fd8df +Verifier_pp hash: 69d82160f259bb17d8bae98e9a56b3ab144d84113ce4b6d137c490c1a4aa8ced + +several_circuits_one_input: +Proof size: 1.65 KB +Proof hash: 4e727afb1d8f6a98b4a98519b448e159067b0f2db93376c37f3eb81cadcb902e +Prover_pp hash: defc2813d39b11158c273824bf6733cc96a2fccc1bdac0a9b0bcd9128d0fee96 +Verifier_pp hash: a00683d5c64cd7684bd2cf2b4ff3bad0703959061a10de3c180b438ff9ba44d6 + +several_circuits_one_input: +Proof size: 8.07 KB +Proof hash: ae9a3f8f822543b32bb1aa34adca6f5e01adb54db1912aaa99cd883642a456d7 +Prover_pp hash: ea9c68c4fbf8cfd8832e22fb1c548ad364335daea48fdf1408e8fc6ba7789de3 +Verifier_pp hash: d499a5e259a4e10552b1e81026bd2dd42806af5de6846a44c85c8fb0070d331b + +KZG.big_circuit.2.16: +Proof size: 2.01 KB +Proof hash: 40c4eb8a1628f22b53cb3abb8c44e767c324fc3b198ac024602386ffa948c63a +Prover_pp hash: eae33e1077d813773b9578ebed27b8b0995785aa330836d8eba4f20704369565 +Verifier_pp hash: f101f2091ab2809d47c04945c6207816c198c6015cbd5c9e13cab750e1b004fa + +zk-KZG.big_circuit.2.16: +Proof size: 2.10 KB +Proof hash: d8de354eb4cbef7e8e4d72a63b5bee30a7b0df72a074ad597e96521d85eb35f3 +Prover_pp hash: 69521c437b1a19612f726dcfc7cca46ad216535ce97efb583ed483001851069d +Verifier_pp hash: f101f2091ab2809d47c04945c6207816c198c6015cbd5c9e13cab750e1b004fa + +KZG.big_circuit.2.16: +Proof size: 2.01 KB +Proof hash: f17533c72fc81bacb42645922dc5d2c8eb5ba3ef0ea446d33ada8a12586ebdce +Prover_pp hash: eae33e1077d813773b9578ebed27b8b0995785aa330836d8eba4f20704369565 +Verifier_pp hash: f101f2091ab2809d47c04945c6207816c198c6015cbd5c9e13cab750e1b004fa + +zk-KZG.big_circuit.2.16: +Proof size: 2.10 KB +Proof hash: 1ac4c2823e878461afc3227bc57ada3df9f161bee5a10e00465c77c4148e631f +Prover_pp hash: 69521c437b1a19612f726dcfc7cca46ad216535ce97efb583ed483001851069d +Verifier_pp hash: f101f2091ab2809d47c04945c6207816c198c6015cbd5c9e13cab750e1b004fa + +KZG_Pack.big_circuit.2.16: +Proof size: 8.42 KB +Proof hash: c3da34b6def272cec727d361c7841ae61560b3b0931432fffbdc30a56d49959d +Prover_pp hash: 6b5cd5f8235dcfb699fbb559fff3b093991de1fef06250a2f0999516e0d6c72b +Verifier_pp hash: ed6e9ff7817aaf6174e8eb795b8656f00f37eaa34b812f4c10f0e51cf85a7c82 + +zk-KZG_Pack.big_circuit.2.16: +Proof size: 8.46 KB +Proof hash: ebe9d078f4009f9eac8a42c40b7db3f214ca7cc3b8c61a7447def2a31ee9220f +Prover_pp hash: 50ecdb144fa428cc1c247fbc24f0e1f2c857954150c655c2a0956e35492c0ae8 +Verifier_pp hash: ed6e9ff7817aaf6174e8eb795b8656f00f37eaa34b812f4c10f0e51cf85a7c82 + +KZG_Pack.big_circuit.2.16: +Proof size: 8.42 KB +Proof hash: a9a72d54d9c185bc0cf98fae3cd398076698c321dc7de69038ff6a873765a79a +Prover_pp hash: 6b5cd5f8235dcfb699fbb559fff3b093991de1fef06250a2f0999516e0d6c72b +Verifier_pp hash: ed6e9ff7817aaf6174e8eb795b8656f00f37eaa34b812f4c10f0e51cf85a7c82 + +zk-KZG_Pack.big_circuit.2.16: +Proof size: 8.46 KB +Proof hash: 9ccd25f4af3a5db571d8d322d137020e8d3a16389d1990642bcb48ccf430ca5c +Prover_pp hash: 50ecdb144fa428cc1c247fbc24f0e1f2c857954150c655c2a0956e35492c0ae8 +Verifier_pp hash: ed6e9ff7817aaf6174e8eb795b8656f00f37eaa34b812f4c10f0e51cf85a7c82 + +test_disjoint: +Proof size: 1.36 KB +Proof hash: c2947d4f5f76675ef2b9d44a8793677057c20a016534cb4cd9695534fea19a83 +Prover_pp hash: 6a9440354abbd2f3e8fe177190f84bd73a18a20519100b5c796d2189fe5b911c +Verifier_pp hash: 9cc2a722b2569e302cf3348ddefad8f3eab747678bf8e526f89838293fabe385 + diff --git a/src/lib_plonk/test/test_circuit.ml b/src/lib_plonk/test/test_circuit.ml new file mode 100644 index 000000000000..6e3005b29b73 --- /dev/null +++ b/src/lib_plonk/test/test_circuit.ml @@ -0,0 +1,235 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module SMap = Plonk.SMap +open Plompiler.Csir + +let gates_equal = SMap.equal (Array.for_all2 Scalar.equal) + +module Make = struct + module Main = Plonk.Main_protocol + module Helpers = Plonk_test.Helpers + module Helpers_main = Helpers.Make (Main) + + let test_make_one_sel sel () = + let open Plonk.Circuit in + let wires = SMap.of_list [("a", [1]); ("b", [1]); ("c", [1])] in + let gates = SMap.add sel [Scalar.one] SMap.empty in + let gates, tables = + match sel with + | "q_plookup" -> (SMap.add "q_table" [Scalar.one] gates, [[[||]]]) + | "q_table" -> (SMap.add "q_plookup" [Scalar.one] gates, [[[||]]]) + | _ -> (gates, []) + in + let c = make ~tables ~wires ~gates ~public_input_size:0 () in + let wires = Tables.map Array.of_list wires in + let gates = Tables.map Array.of_list gates in + assert (c.wires = wires) ; + assert (gates_equal c.gates gates) + + let tests_one_sel = + List.map + (fun (s, _) -> + Alcotest.test_case ("make " ^ s) `Quick (test_make_one_sel s)) + CS.all_selectors + + let test_empty () = + let open Plonk.Circuit in + let wires = SMap.of_list [("a", [1]); ("b", [1]); ("c", [1])] in + let gates = SMap.add "qc" [Scalar.one] SMap.empty in + Helpers.must_fail (fun () -> + ignore @@ make ~wires:SMap.empty ~gates ~public_input_size:0 ()) ; + Helpers.must_fail (fun () -> + ignore @@ make ~wires ~gates:SMap.empty ~public_input_size:0 ()) + + let test_different_size () = + let open Plonk.Circuit in + (* wires have different size wrt to gates *) + let wires = SMap.of_list [("a", [1]); ("b", [1]); ("c", [1])] in + let gates = SMap.add "qc" Scalar.[one; one] SMap.empty in + Helpers.must_fail (fun () -> + ignore @@ make ~wires ~gates ~public_input_size:0 ()) ; + (* wires have different sizes *) + let wires = SMap.of_list [("a", [1; 1]); ("b", [1]); ("c", [1])] in + let gates = SMap.add "qc" Scalar.[one] SMap.empty in + Helpers.must_fail (fun () -> + ignore @@ make ~wires ~gates ~public_input_size:0 ()) ; + (* gates have different sizes *) + let wires = SMap.of_list [("a", [1]); ("b", [1]); ("c", [1])] in + let gates = SMap.of_list Scalar.[("qc", [one]); ("ql", [one; one])] in + Helpers.must_fail (fun () -> + ignore @@ make ~wires ~gates ~public_input_size:0 ()) + + (* Test that Plonk supports using qecc_ws_add and a q*g in the same circuit. *) + let test_disjoint () = + let open Plonk.Circuit in + let x = Scalar.[|one; add one one; of_string "3"; of_string "4"|] in + let wires = + SMap.of_list [("a", [0; 2; 0]); ("b", [0; 3; 3]); ("c", [0; 1; 1])] + in + let gates = + SMap.of_list + Scalar. + [ + ("ql", [one; zero; zero]); + ("qecc_ws_add", [zero; one; zero]); + ("qlg", [one; zero; zero]); + ("qc", [Scalar.(negate (of_string "4")); zero; zero]); + ] + in + let c = make ~wires ~gates ~public_input_size:0 () in + Helpers_main.test_circuit ~name:"test_disjoint" c x + + let test_wrong_selectors () = + let open Plonk.Circuit in + let wires = + SMap.of_list [("a", [0; 2; 0]); ("b", [0; 3; 3]); ("c", [0; 1; 1])] + in + let gates = + SMap.of_list + Scalar. + [ + ("ql", [one; zero; zero]); + ("dummy", [zero; one; zero]); + ("qlg", [one; zero; zero]); + ("qc", [Scalar.(negate (of_string "4")); zero; zero]); + ] + in + try + let _ = make ~wires ~gates ~public_input_size:0 () in + () + with + | Invalid_argument s when s = "Make Circuit: unknown gates." -> () + | _ -> + failwith + "Test_wrong_selector : Invalid_argument \"Make Circuit: unknown \ + gates.\" expected." + + let test_vector () = + let open Plonk.Circuit in + let wires = SMap.of_list [("a", [1; 1]); ("b", [1; 1]); ("c", [1; 1])] in + let gates = + SMap.of_list Scalar.[("qc", [zero; one]); ("qr", [zero; zero])] + in + let gates_expected = + SMap.of_list Scalar.[("qc", [|zero; one|]); ("ql", [|zero; zero|])] + in + let c = make ~wires ~gates ~public_input_size:1 () in + let wires = Tables.map Array.of_list wires in + assert (c.wires = wires) ; + assert (gates_equal c.gates gates_expected) + + (* TODO add more tests about lookup *) + + let test_table () = + let zero, one = Scalar.(zero, one) in + let table_or = + Table.of_list + [ + [|zero; zero; one; one|]; + [|zero; one; zero; one|]; + [|zero; one; one; one|]; + [|zero; zero; zero; zero|]; + [|zero; zero; zero; zero|]; + ] + in + let entry = + ({a = zero; b = zero; c = zero; d = zero; e = zero} : Table.entry) + in + let input = + Table.{a = Some zero; b = Some zero; c = None; d = None; e = None} + in + assert (Table.size table_or = 4) ; + assert (Table.mem entry table_or) ; + Table.find input table_or |> Option.get |> fun res -> + assert (Scalar.(eq entry.a res.a && eq entry.b res.b && eq entry.c res.c)) ; + () +end + +module To_plonk = struct + let test_vector () = + let open Plonk.Circuit in + let open CS in + let zero, one, two = Scalar.(zero, one, one + one) in + let precomputed_advice = [] in + let g1 = + [| + { + a = 0; + b = 1; + c = 0; + d = 0; + e = 0; + sels = [("qr", one)]; + precomputed_advice; + label = []; + }; + |] + in + let g2 = + [| + { + a = 1; + b = 2; + c = 1; + d = 0; + e = 0; + sels = [("qm", two)]; + precomputed_advice; + label = []; + }; + |] + in + let c = to_plonk ~public_input_size:0 [g1; g2] in + let expected_wires = + SMap.of_list + [ + ("a", [|0; 1|]); + ("b", [|1; 2|]); + ("c", [|0; 1|]); + ("d", [|0; 0|]); + ("e", [|0; 0|]); + ] + in + let expected_gates = + SMap.of_list [("qr", [|one; zero|]); ("qm", [|zero; two|])] + in + assert (c.wires = expected_wires) ; + assert (gates_equal c.gates expected_gates) +end + +let tests = + Make.tests_one_sel + @ List.map + (fun (n, f) -> Alcotest.test_case n `Quick f) + [ + ("make empty", Make.test_empty); + ("make different_size", Make.test_different_size); + ("make vectors", Make.test_vector); + ("make table", Make.test_table); + ("make disjoint", Make.test_disjoint); + ("to_plonk vectors", To_plonk.test_vector); + ("to_plonk wrong selectors", Make.test_wrong_selectors); + ] diff --git a/src/lib_plonk/test/test_evaluations.ml b/src/lib_plonk/test/test_evaluations.ml new file mode 100644 index 000000000000..b2ad9f09afab --- /dev/null +++ b/src/lib_plonk/test/test_evaluations.ml @@ -0,0 +1,92 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Fr = Bls12_381.Fr +module SMap = Plonk.SMap +module Domain = Bls12_381_polynomial.Domain +module P = Bls12_381_polynomial.Polynomial +module Eval = Plonk.Evaluations_map.Make (Bls12_381_polynomial.Evaluations) + +let powers = Octez_bls12_381_polynomial.Fr_carray.powers + +open Eval + +let test_linear () = + let p_1 = P.generate_biased_random_polynomial 10 in + let p_2 = P.generate_biased_random_polynomial 10 in + let domain = Domain.build_power_of_two 6 in + let eval1 = evaluation_fft domain p_1 in + let eval2 = evaluation_fft domain p_2 in + let cst, linear_coeff_1, linear_coeff_2 = + (Fr.random (), Fr.random (), Fr.random ()) + in + let p_1_comp = + let caml = P.to_dense_coefficients p_1 in + let pow_g = powers (Array.length caml) (Domain.get domain 1) in + Array.map2 Fr.mul caml pow_g |> P.of_dense + in + let expected_res = + P.( + mul_by_scalar linear_coeff_1 p_1_comp + + mul_by_scalar linear_coeff_2 p_2 + + mul_by_scalar cst P.one) + in + let evaluations = SMap.of_list [("1", eval1); ("2", eval2)] in + let res_eval = + linear + ~evaluations + ~poly_names:["1"; "2"] + ~add_constant:cst + ~linear_coeffs:[linear_coeff_1; linear_coeff_2] + ~composition_gx:([1; 0], 64) + () + in + let res = interpolation_fft domain res_eval in + assert (P.equal res expected_res) + +let test_mul () = + let p_1 = P.generate_biased_random_polynomial 10 in + let p_2 = P.generate_biased_random_polynomial 10 in + let domain = Domain.build_power_of_two 6 in + let eval1 = evaluation_fft domain p_1 in + let eval2 = evaluation_fft domain p_2 in + let p_2_comp = + let caml = P.to_dense_coefficients p_2 in + let pow_g = powers (Array.length caml) (Domain.get domain 1) in + Array.map2 Fr.mul caml pow_g |> P.of_dense + in + let evaluations = SMap.of_list [("1", eval1); ("2", eval2)] in + let res_eval = + mul ~evaluations ~poly_names:["1"; "2"] ~composition_gx:([0; 1], 64) () + in + let expected_res = P.mul p_1 p_2_comp in + let res = interpolation_fft domain res_eval in + assert (P.equal res expected_res) + +let tests = + [ + Alcotest.test_case "test_linear" `Quick test_linear; + Alcotest.test_case "test_mul" `Quick test_mul; + ] diff --git a/src/lib_plonk/test/test_main_protocol.ml b/src/lib_plonk/test/test_main_protocol.ml new file mode 100644 index 000000000000..0ac7edfaf567 --- /dev/null +++ b/src/lib_plonk/test/test_main_protocol.ml @@ -0,0 +1,161 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module External + (MP : Plonk.Main_protocol.S + with type public_inputs = Plompiler.S.t array list) = +struct + module H = Plonk_test.Helpers.Make (MP) + + let test_encodings ~zero_knowledge () = + let open Plonk.Circuit in + let open Plonk_test.Cases in + let module Main = H.Singleton in + let {circuit; witness; _} = General.non_zero_values in + let pp_prover, pp_verifier = + Main.setup ~zero_knowledge circuit ~srs:Plonk_test.Helpers.srs + in + let inputs = [H.make_secret pp_prover circuit.input_com_sizes witness] in + let verifier_inputs = + Main.to_verifier_inputs pp_prover (Plonk.SMap.singleton "" inputs) + |> Plonk.SMap.choose |> snd + in + let b_pp_verifier = + Data_encoding.Binary.to_bytes_exn + Main.verifier_public_parameters_encoding + pp_verifier + in + let pp_verifier' = + Data_encoding.Binary.of_bytes_exn + Main.verifier_public_parameters_encoding + b_pp_verifier + in + let proof = Main.prove pp_prover ~inputs in + let b_proof = Data_encoding.Binary.to_bytes_exn Main.proof_encoding proof in + let proof' = + Data_encoding.Binary.of_bytes_exn Main.proof_encoding b_proof + in + assert (Main.verify pp_verifier' ~inputs:verifier_inputs proof') ; + (* Json *) + let b_pp_verifier = + Data_encoding.Json.construct + Main.verifier_public_parameters_encoding + pp_verifier + in + let _pp_verifier' = + Data_encoding.Json.destruct + Main.verifier_public_parameters_encoding + b_pp_verifier + in + let proof = Main.prove pp_prover ~inputs in + let b_proof = Data_encoding.Json.construct Main.proof_encoding proof in + let proof' = Data_encoding.Json.destruct Main.proof_encoding b_proof in + assert (Main.verify pp_verifier ~inputs:verifier_inputs proof') + + let tests_quick pc_name = + let open Plonk_test in + let aggregated_cases = + let open Cases.General in + let open Cases.Unit_tests_for_each_selector in + [ + [zero_values; non_zero_values]; + [zero_values; zero_values]; + [ql; qr; qlg; qrg; qog; qm]; + ] + @ Cases.Lookup. + [ + [qplookup; lookup_zero_values]; + [lookup_non_zero_values; lookup_no_public_inputs]; + [lookup_wrong_arith_values; lookup_wrong_arith_values]; + [qplookup_two_tables; qplookup_two_tables]; + ] + in + List.map + (fun case -> + Cases. + ( case.name, + H.run_test_case {case with name = pc_name ^ "." ^ case.name} )) + (Cases.list @ Cases.Lookup.list) + @ List.map (H.test_aggregated_cases ~prefix:pc_name) aggregated_cases + @ [("test_encodings", test_encodings)] + + let tests_slow pc_name = + let open Plonk_test in + List.map + (fun case -> + let case = Cases.{case with name = pc_name ^ "." ^ case.name} in + (Cases.(case.name), H.run_test_case case)) + Cases.list_slow + + let several_circuits_one_input ~zero_knowledge () = + let open Plonk_test.Cases in + let qc = Unit_tests_for_each_selector.qc in + let ql = Unit_tests_for_each_selector.ql in + let circuits = + Plonk.SMap.of_list + [(qc.name, (qc.circuit, 1)); (ql.name, (ql.circuit, 1))] + in + let inputs = Plonk.SMap.singleton qc.name [qc.witness] in + H.test_circuits + ~name:"several_circuits_one_input" + ~zero_knowledge + circuits + inputs +end + +module External_Kzg = External (Plonk.Main_protocol) +module PP_Pack = + Aggregation.Polynomial_protocol.Make_aggregation + (Aggregation.Polynomial_commitment) + (Plonk.Main_protocol.Input_commitment) +module External_Kzg_pack = External (Plonk.Main_protocol.Make (PP_Pack)) + +let tests = + let quick = + let tests_kzg = External_Kzg.tests_quick "KZG" in + let tests_kzg_pack = External_Kzg_pack.tests_quick "KZG_Pack" in + List.map + (fun (n, f) -> Alcotest.test_case n `Quick (f ~zero_knowledge:false)) + (tests_kzg @ tests_kzg_pack + @ [ + ("Subset of proofs (KZG)", External_Kzg.several_circuits_one_input); + ( "Subset of proofs (Pack)", + External_Kzg_pack.several_circuits_one_input ); + ]) + in + let slow = + let tests_kzg = External_Kzg.tests_slow "KZG" in + let tests_kzg_pack = External_Kzg_pack.tests_slow "KZG_Pack" in + List.map + (fun (n, f) -> + Alcotest. + [ + test_case n `Slow (f ~zero_knowledge:false); + test_case (n ^ " zk") `Slow (f ~zero_knowledge:true); + ]) + (tests_kzg @ tests_kzg_pack) + |> List.flatten + in + quick @ slow diff --git a/src/lib_plonk/test/test_pack.ml b/src/lib_plonk/test/test_pack.ml new file mode 100644 index 000000000000..244a00b024ea --- /dev/null +++ b/src/lib_plonk/test/test_pack.ml @@ -0,0 +1,109 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Internal = struct + open Aggregation.Pack.Pack_impl + + let test_verifier_srs () = + let n = 2 in + let pp_prv, pp_vrf = setup n (snd Plonk_test.Helpers.srs) in + assert (Plonk.Bls.G1.eq pp_prv.g1_t pp_vrf) +end + +module External = struct + open Aggregation.Pack + open Plonk.Bls + open Plonk.Utils + + let with_time f = + let start_time = Sys.time () in + let res = f () in + let end_time = Sys.time () in + (res, end_time -. start_time) + + let srs = + let open Octez_bls12_381_polynomial.Bls12_381_polynomial.Srs in + let x = Bls12_381.Fr.random () in + (Srs_g1.generate_insecure 2 x, Srs_g2.generate_insecure 256 x) + + let test_prove_and_verify_single () = + Random.init 31415 ; + let n = 256 in + let pp_prv, pp_vrf = setup n srs in + let data = Array.init n (fun _i -> G1.random ()) in + let cmt, t1 = with_time @@ fun () -> commit pp_prv data in + let transcript = Transcript.expand commitment_t cmt Bytes.empty in + let r, transcript = Fr_generation.random_fr transcript in + let ((packed, proof), prover_transcript), t2 = + with_time @@ fun () -> prove_single pp_prv transcript r data + in + let (b, verifier_transcript), t3 = + with_time @@ fun () -> + verify_single pp_vrf transcript cmt r (packed, proof) + in + assert (Bytes.equal prover_transcript verifier_transcript) ; + assert b ; + Format.printf "\nTime commit (single): %f s\n" t1 ; + Format.printf "Time aggregate and prove (single): %f s\n" t2 ; + Format.printf "Time verify (single): %f s\n" t3 + + let test_prove_and_verify () = + Random.init 31415 ; + let max_n = 256 in + let nb_instances = 10 in + let pp_prv, pp_vrf = setup max_n srs in + let generate_instance () = + let data = Array.init (1 + Random.int max_n) (fun _i -> G1.random ()) in + let cmt = commit pp_prv data in + (data, cmt) + in + let instances = List.init nb_instances (fun _ -> generate_instance ()) in + let datas, cmts = List.split instances in + + let transcript = Transcript.list_expand commitment_t cmts Bytes.empty in + let r, transcript = Fr_generation.random_fr transcript in + + let ((packed_map, proof), prover_transcript), t1 = + with_time @@ fun () -> prove pp_prv transcript r datas + in + let (b, verifier_transcript), t2 = + with_time @@ fun () -> verify pp_vrf transcript cmts r (packed_map, proof) + in + Format.printf "Time aggregate and prove: %f s\n" t1 ; + Format.printf "Time verify: %f s\n" t2 ; + assert (Bytes.equal prover_transcript verifier_transcript) ; + assert b +end + +let tests = + Alcotest. + [ + test_case "SRS" `Quick Internal.test_verifier_srs; + test_case + "correctness (single)" + `Quick + External.test_prove_and_verify_single; + test_case "correctness" `Quick External.test_prove_and_verify; + ] diff --git a/src/lib_plonk/test/test_permutations.ml b/src/lib_plonk/test/test_permutations.ml new file mode 100644 index 000000000000..079c48cbde2f --- /dev/null +++ b/src/lib_plonk/test/test_permutations.ml @@ -0,0 +1,160 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk +open Bls + +let create_random_permutation n = + (* This function does not sample permutations uniformly at random, + it seems to be biased towards permutations similar to the identity *) + let l = List.init n (fun i -> (i, Random.int n)) in + let compare (_, k1) (_, k2) = compare k1 k2 in + let permutation_list = List.map (fun (i, _) -> i) (List.sort compare l) in + Array.of_list permutation_list + +let expand_permutation ~n permutation = + let m = Array.length permutation in + List.init m (fun i -> Array.init n (fun j -> (permutation.(i) * n) + j)) + |> Array.concat + +let arbitrary_perm = + let print_perm perm = + String.concat " " (List.map string_of_int (Array.to_list perm)) + in + + let perm_gen = + QCheck.Gen.( + sized @@ fun d _st -> + let d = if d > 10 then 10 else if d < 2 then 2 else d in + let n = Z.(pow (of_int 2) d |> to_int) in + let perm = create_random_permutation n in + perm) + in + QCheck.make perm_gen ~print:print_perm + +module Internal = struct + open Permutation_gate.Permutation_gate_impl (Polynomial_protocol) + + let generate_random_polynomial n = + Poly.of_coefficients (List.init n (fun i -> (Scalar.random (), i))) + + let build_gi_list generator n = + let rec aux acc i = + if i = n then List.rev acc + else + let g_i_min_1 = List.hd acc in + aux (Scalar.mul g_i_min_1 generator :: acc) (i + 1) + in + aux [generator] 2 + + let test_cycles_to_permutation () = + let cycles_list_to_cycles_map cycles_list = + let open Partition in + let cycles_set = List.map IntSet.of_list cycles_list in + let aux (i, map) s = (i + 1, IntMap.add i s map) in + let _, cycles = List.fold_left aux (0, IntMap.empty) cycles_set in + cycles + in + let partition = + [[0; 1; 2; 3]; [4; 5; 6]; [7; 8; 9]] |> cycles_list_to_cycles_map + in + let permutation = Partition.partition_to_permutation partition in + let res = [|1; 2; 3; 0; 5; 6; 4; 8; 9; 7|] in + assert (permutation = res) ; + let t = 300 in + let kn = 1000 in + (* i-th cycle is the equivalence class modulo t for integers under kn ; cycles is a partition of [0, kn-1] *) + let cycles_list = + let cycles_array = Array.init t (fun _ -> []) in + let rec aux i = + if i = -1 then Array.to_list cycles_array + else + let p = i mod t in + cycles_array.(p) <- i :: cycles_array.(p) ; + aux (i - 1) + in + aux (kn - 1) + in + let partition = cycles_list_to_cycles_map cycles_list in + let permutation = Partition.partition_to_permutation partition in + let verify_cycle_in_permutation cycle = + let a0 = List.hd cycle in + let rec aux prec l = + match l with + | [] -> permutation.(prec) = a0 + | e :: r -> permutation.(prec) = e && aux e r + in + (aux a0 (List.tl cycle), List.length cycle) + in + let aux (v_acc, k_acc) cycle = + let v, k = verify_cycle_in_permutation cycle in + (v && v_acc, k + k_acc) + in + let cycles_in_perm, sum_card_cycles = + List.fold_left aux (true, 0) cycles_list + in + (* (cycles ⊆ permutation) & (card(cycles) = card(permutation)) => cycles = permutation *) + assert cycles_in_perm ; + assert (sum_card_cycles = Array.length permutation) +end + +module External = struct + module PP = Polynomial_protocol + module Perm = Permutation_gate.Permutation_gate_impl (PP) + + let nb_wires = 3 + + let test_prop_perm_check (perm : int array) = + let n = Array.length perm in + let log = Z.(log2up (of_int n)) in + let domain = Domain.build_power_of_two log in + let l1 = Perm.Preprocessing.compute_l1 domain in + + (* Check that L1(g^1) = 1 and L(g^i) = 0 for all i <> 1 *) + let _lconsistency (i, g) = + let v = Poly.evaluate l1 g in + if i = 1 then Scalar.is_one v else Scalar.is_zero v + in + (* Array.for_all *) + (* lconsistency *) + (* (Array.mapi (fun i g -> (i, g)) (Domain.to_array domain)) *) + (* && *) + Perm.srs_size ~zero_knowledge:true ~n = n + 9 + && Perm.srs_size ~zero_knowledge:false ~n = n +end + +let tests = + [ + Alcotest.test_case + "test_cycles_to_permutation" + `Quick + Internal.test_cycles_to_permutation; + QCheck_alcotest.to_alcotest + (QCheck.Test.make + ~count:30 + ~name:"permutation_properties" + arbitrary_perm + External.test_prop_perm_check); + ] diff --git a/src/lib_plonk/test/test_plookup.ml b/src/lib_plonk/test/test_plookup.ml new file mode 100644 index 000000000000..31f95c5e3b34 --- /dev/null +++ b/src/lib_plonk/test/test_plookup.ml @@ -0,0 +1,126 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk.Bls + +module Internal = struct + open Plonk.Plookup_gate.Plookup_gate_impl (Plonk.Polynomial_protocol) + + module Fr_gen = Octez_bls12_381_polynomial.Fr_carray + + let test_aggregation () = + let alpha = Scalar.random () in + let length_list = 5 in + let length_t = 30 in + let length_f = 25 in + let tables = + List.init length_list (fun _ -> + Array.init length_t (fun _ -> Scalar.random ())) + in + let k_array = Array.init length_f (fun _ -> Random.int length_t) in + let f_list = + List.init length_list (fun i -> + Array.init length_f (fun j -> + let t_i = List.nth tables i in + t_i.(k_array.(j)))) + in + let f_list_sorted = + List.map2 (fun f t -> Plookup_poly.sort_by f t) f_list tables + in + let t = Plookup_poly.compute_aggregation tables alpha in + let f = Plookup_poly.compute_aggregation f_list_sorted alpha in + for i = 0 to length_f - 1 do + assert (Array.exists (fun x -> Scalar.eq x f.(i)) t) + done ; + () + + let test_z () = + let n = 32 in + let log = 5 in + let generator = Fr_gen.primitive_root_of_unity_power_of_two ~log in + let domain = Domain.build_power_of_two log in + let t = Array.init n (fun _ -> Scalar.random ()) in + let f = + Array.init (n - 1) (fun i -> + let k = if i = 0 || i = 1 || i = n - 1 then 5 else i in + t.(k)) + in + let beta = Scalar.random () in + let gamma = Scalar.random () in + let one_plus_beta = Scalar.(one + beta) in + let gamma_one_plus_beta = Scalar.(gamma * one_plus_beta) in + let s = Plookup_poly.compute_s f t in + let z = Plookup_poly.compute_z beta gamma f t s n domain in + let t_poly = + Evaluations.interpolation_fft2 domain (Plookup_poly.switch t) + in + let f_poly = + Evaluations.interpolation_fft2 domain Array.(append [|zero|] f) + in + let h1, h2 = Plookup_poly.compute_h s domain n in + let eval_left x = + let x_minus_one = Scalar.(x + negate one) in + let f_term = Scalar.(Poly.evaluate f_poly x + gamma) in + let t_term = + Scalar.( + gamma_one_plus_beta + Poly.evaluate t_poly x + + (beta * Poly.evaluate t_poly (generator * x))) + in + Scalar.(x_minus_one * Poly.evaluate z x * one_plus_beta * f_term * t_term) + in + let eval_right x = + let x_minus_one = Scalar.(x + negate one) in + let h_term h = + Scalar.( + gamma_one_plus_beta + Poly.evaluate h x + + (beta * Poly.evaluate h (generator * x))) + in + Scalar.( + x_minus_one * Poly.evaluate z (generator * x) * h_term h1 * h_term h2) + in + for i = 0 to 31 do + let eval_point = Scalar.pow generator (Z.of_int i) in + assert (Scalar.eq (eval_left eval_point) (eval_right eval_point)) + done ; + () + + let test_sort () = + let a = Array.init 10 (fun i -> Scalar.of_z (Z.of_int i)) in + let b = Array.init 12 (fun i -> Scalar.of_z (Z.of_int (11 - i))) in + let sorted_a = Plookup_poly.sort_by a b in + Array.iteri + (fun i a_i -> assert (Scalar.eq a_i (Scalar.of_z (Z.of_int (9 - i))))) + sorted_a ; + () +end + +let tests = + List.map + (fun (name, f) -> Alcotest.test_case name `Quick f) + [ + ("Internal.test_z", Internal.test_z); + ("Internal.test_sort", Internal.test_sort); + ("Internal.test_aggregation", Internal.test_aggregation); + ] diff --git a/src/lib_plonk/test/test_polynomial_commitment.ml b/src/lib_plonk/test/test_polynomial_commitment.ml new file mode 100644 index 000000000000..82ef60fa9cea --- /dev/null +++ b/src/lib_plonk/test/test_polynomial_commitment.ml @@ -0,0 +1,164 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk.Bls +open Plonk.Utils + +module Internal = struct + open Plonk.Polynomial_commitment.Kzg_impl + + let test_verifier_srs () = + let n = 2 in + let pp_prv, pp_vrf = + Public_parameters.setup (n, 0) Plonk_test.Helpers.srs + in + assert (G2.eq pp_prv.encoding_1 pp_vrf.encoding_1) ; + assert (G2.eq pp_prv.encoding_x pp_vrf.encoding_x) +end + +module External (PC : Plonk.Polynomial_commitment.S) = struct + module SMap = Plonk.SMap + + let generate_random_poly degree = + Poly.of_coefficients (List.init degree (fun i -> (Scalar.random (), i))) + + let generate_f_map ~prefix degree n = + let generate_f i = + (prefix ^ "|" ^ string_of_int i, generate_random_poly degree) + in + SMap.of_list (List.init n generate_f) + + type instance = { + pp_prover : PC.Public_parameters.prover; + pp_verifier : PC.Public_parameters.verifier; + f_map_list : Poly.t SMap.t list; + cmt_list : PC.Commitment.t list; + prover_aux_list : PC.Commitment.prover_aux list; + transcript : Bytes.t; + query_list : Scalar.t SMap.t list; + answer_list : PC.answer list; + } + + let generate_instance ~nb_batches ~nb_polys_per_batch = + let max_degree = 20 in + let pp_prover, pp_verifier = + PC.Public_parameters.setup (2 * nb_polys_per_batch) Plonk_test.Helpers.srs + in + let f_map_list = + List.init nb_batches (fun i -> + generate_f_map ~prefix:(string_of_int i) max_degree nb_polys_per_batch) + in + let cmt_list, prover_aux_list = + List.map (PC.Commitment.commit pp_prover) f_map_list |> List.split + in + let transcript = + Transcript.list_expand PC.Commitment.t cmt_list Bytes.empty + in + let x1 = Scalar.random () in + let x2 = Scalar.random () in + let just_x1 = SMap.singleton "x1" x1 in + let both_points = SMap.of_list [("x1", x1); ("x2", x2)] in + let query_list = + just_x1 :: List.init (nb_batches - 1) (fun _ -> both_points) + in + let answer_list = List.map2 PC.evaluate f_map_list query_list in + { + pp_prover; + pp_verifier; + f_map_list; + cmt_list; + prover_aux_list; + transcript; + query_list; + answer_list; + } + + let prove_and_verify_instance ?(wrong_transcript = false) instance = + let proof, prover_final_transcript = + PC.prove + instance.pp_prover + instance.transcript + instance.f_map_list + instance.prover_aux_list + instance.query_list + instance.answer_list + in + + let b, verifier_final_transcript = + PC.verify + instance.pp_verifier + (if wrong_transcript then Bytes.empty else instance.transcript) + instance.cmt_list + instance.query_list + instance.answer_list + proof + in + + (* This should hold as long as they input the same query list, + the same answer list and start from the same transcript (where + we should typically have included the cmt list *) + if not wrong_transcript then + assert (Bytes.equal prover_final_transcript verifier_final_transcript) ; + b + + let test_correctness () = + let instance = generate_instance ~nb_batches:4 ~nb_polys_per_batch:16 in + assert (prove_and_verify_instance instance) + + let test_wrong_answer () = + let instance = generate_instance ~nb_batches:4 ~nb_polys_per_batch:8 in + let first_answer = List.hd instance.answer_list in + let key, outputs = SMap.choose first_answer in + let first_answer' = + SMap.add key (SMap.map (fun _ -> Scalar.random ()) outputs) first_answer + in + let instance' = + { + instance with + answer_list = first_answer' :: List.tl instance.answer_list; + } + in + assert (not @@ prove_and_verify_instance instance') + + let test_wrong_transcript () = + let instance = generate_instance ~nb_batches:4 ~nb_polys_per_batch:8 in + assert (not @@ prove_and_verify_instance ~wrong_transcript:true instance) +end + +module KZG_Tests = External (Plonk.Polynomial_commitment) +module KZG_Pack_Tests = External (Aggregation.Polynomial_commitment) + +let tests = + [Alcotest.test_case "test_verifier_srs" `Quick Internal.test_verifier_srs] + @ List.map + (fun (name, f) -> Alcotest.test_case name `Quick f) + [ + ("correctness (KZG)", KZG_Tests.test_correctness); + ("wrong answer (KZG)", KZG_Tests.test_wrong_answer); + ("wrong transcript (KZG)", KZG_Tests.test_wrong_transcript); + ("correctness (KZG_Pack)", KZG_Pack_Tests.test_correctness); + ("wrong answer (KZG_Pack)", KZG_Pack_Tests.test_wrong_answer); + ("wrong transcript (KZG_Pack)", KZG_Pack_Tests.test_wrong_transcript); + ] diff --git a/src/lib_plonk/test/test_polynomial_protocol.ml b/src/lib_plonk/test/test_polynomial_protocol.ml new file mode 100644 index 000000000000..260561ae4140 --- /dev/null +++ b/src/lib_plonk/test/test_polynomial_protocol.ml @@ -0,0 +1,199 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk.Bls +open Plonk.Identities + +module External (PP : Plonk.Polynomial_protocol.S) = struct + module SMap = Plonk.SMap + + let pow5_mod_zh ~n p = + let domain = Domain.build_power_of_two (Z.log2 @@ Z.of_int (8 * n)) in + let p_e = Evaluations.evaluation_fft domain p in + let p2_e = Evaluations.mul_c ~evaluations:[p_e; p_e] () in + let p5_e = Evaluations.mul_c ~evaluations:[p2_e; p2_e; p_e] () in + let p5 = Evaluations.interpolation_fft domain p5_e in + snd @@ Poly.division_xn p5 n Scalar.(negate one) + + let sample_polys_and_identities n = + let pA = Poly.random n in + let pB = Poly.random n in + let _, pC = Poly.(division_xn (mul pA pB) n Scalar.(negate one)) in + let zh = Poly.of_coefficients Scalar.[(one, n); (negate one, 0)] in + let pD = Poly.(sub pA @@ mul zh (Poly.random 2)) in + let eD = + let domain = Domain.build_power_of_two (Z.log2 @@ Z.of_int (8 * n)) in + Evaluations.evaluation_fft domain pD + in + let pA5 = pow5_mod_zh ~n pA in + let poly_map = + SMap.of_list + [ + ("A", pA); + ("B", pB); + ("C", pC); + ("A5", pA5); + ("D", pD); + ("0", Poly.zero); + ] + in + (* define prover identities *) + let prover_id1 evaluations = + let eA = SMap.find "A" evaluations in + let eB = SMap.find "B" evaluations in + let eC = SMap.find "C" evaluations in + let eAB = Evaluations.mul_c ~evaluations:[eA; eB] () in + Evaluations.linear_c + ~evaluations:[eAB; eC] + ~linear_coeffs:Scalar.[one; negate one] + () + in + + let prover_id2 evaluations = + let eA = SMap.find "A" evaluations in + Evaluations.linear_c + ~evaluations:[eA; eD] + ~linear_coeffs:Scalar.[one; negate one] + () + in + let prover_id3 evaluations = + Evaluations.create (Evaluations.length @@ snd (SMap.choose evaluations)) + in + let prover_id4 evaluations = + let eA = SMap.find "A" evaluations in + let eA5 = SMap.find "A5" evaluations in + let eA_5 = Evaluations.mul_c ~evaluations:[eA] ~powers:[5] () in + Evaluations.linear_c + ~evaluations:[eA_5; eA5] + ~linear_coeffs:Scalar.[one; negate one] + () + in + let prover_identities : prover_identities = + fun evaluations -> + SMap.of_list + [ + ("id1", prover_id1 evaluations); + ("id2", prover_id2 evaluations); + ("id3", prover_id3 evaluations); + ("id4", prover_id4 evaluations); + ] + in + (* define verifier identities *) + let verifier_id1 answers = + let x_evals = SMap.find "x" answers in + let a = SMap.find "A" x_evals in + let b = SMap.find "B" x_evals in + let c = SMap.find "C" x_evals in + Scalar.(sub (a * b) c) + in + let verifier_id2 answers = + let x_evals = SMap.find "x" answers in + let a = SMap.find "A" x_evals in + let d = SMap.find "D" x_evals in + Scalar.(sub a d) + in + let verifier_id3 answers = + let x_evals = SMap.find "x" answers in + SMap.find "0" x_evals + in + let verifier_id4 answers = + let x_evals = SMap.find "x" answers in + let a = SMap.find "A" x_evals in + let a5 = SMap.find "A5" x_evals in + Scalar.(sub (a * a * a * a * a) a5) + in + let verifier_identities : verifier_identities = + fun _x answers -> + SMap.of_list + [ + ("id1", verifier_id1 answers); + ("id2", verifier_id2 answers); + ("id3", verifier_id3 answers); + ("id4", verifier_id4 answers); + ] + in + (poly_map, prover_identities, verifier_identities) + + let test_protocol () = + let n = 1 lsl 5 in + let nb_of_t_chunks = 5 in + (* sample test *) + let poly_map, prover_identities, verifier_identities = + sample_polys_and_identities n + in + (* setup *) + let prover_pp, verifier_pp = + let next_pow2 k = Z.(pow (of_int 2) @@ log2up (of_int k) |> to_int) in + PP.setup + ~setup_params:(next_pow2 @@ max nb_of_t_chunks (SMap.cardinal poly_map)) + ~srs:Plonk_test.Helpers.srs + in + (* prover *) + let cm, prover_aux = PP.PC.Commitment.commit prover_pp poly_map in + let secrets = [(poly_map, prover_aux)] in + let eval_points = [[X]] in + (* The generator is not needed since we evaluate only at X *) + let generator = Scalar.zero in + let domain = Domain.build_power_of_two (Z.log2 @@ Z.of_int (8 * n)) in + let evaluations = SMap.map (Evaluations.evaluation_fft domain) poly_map in + let proof, transcript = + PP.prove + prover_pp + Bytes.empty + ~n + ~generator + ~secrets + ~eval_points + ~evaluations + ~identities:prover_identities + ~nb_of_t_chunks + in + (* verifier *) + let ok, transcript' = + PP.verify + verifier_pp + Bytes.empty + ~n + ~generator + ~commitments:[cm] + ~eval_points + ~identities:verifier_identities + proof + in + assert (Bytes.equal transcript transcript') ; + assert ok +end + +module External_Kzg = External (Plonk.Polynomial_protocol) +module External_Kzg_Pack = + External (Plonk.Polynomial_protocol.Make (Aggregation.Polynomial_commitment)) + +let tests = + List.map + (fun (name, f) -> Alcotest.test_case name `Quick f) + [ + ("Polynomial Protocol (Kzg)", External_Kzg.test_protocol); + ("Polynomial Protocol (Kzg_Pack)", External_Kzg_Pack.test_protocol); + ] diff --git a/src/lib_plonk/test/test_range_checks.ml b/src/lib_plonk/test/test_range_checks.ml new file mode 100644 index 000000000000..719dfff04504 --- /dev/null +++ b/src/lib_plonk/test/test_range_checks.ml @@ -0,0 +1,118 @@ +open Plonk +open Bls + +let one = Scalar.one + +let two = Scalar.(one + one) + +module Internal = struct + open Range_check_gate.Range_check_gate_impl (Polynomial_protocol) + + let test_min_z () = + let upper_bound = 4 in + let x = Random.int (1 lsl upper_bound) |> Scalar.of_int in + let evals = RangeChecks.partial_z upper_bound x in + assert (Scalar.eq (List.nth evals 0) x) ; + let last = List.nth evals (upper_bound - 1) in + assert (Scalar.(eq last one || eq last zero)) +end + +module External (PC : Polynomial_commitment.S) = struct + module PP = Polynomial_protocol.Make (PC) + module H = Plonk_test.Helpers.Make (Main_protocol) + open Plonk_test.Cases + + let test_range_checks_single ~zero_knowledge () = + let wires = SMap.map Array.to_list General.circuit.wires in + let gates = SMap.map Array.to_list General.circuit.gates in + let circuit = + Plonk.Circuit.make + ~wires + ~gates + ~public_input_size:General.circuit.public_input_size + ~range_checks:([4; 6], 4) + () + in + let inputs = General.witness in + H.test_circuit ~name:"Range_Checks_single" ~zero_knowledge circuit inputs ; + let circuit = + Plonk.Circuit.make + ~wires + ~gates + ~public_input_size:General.circuit.public_input_size + ~range_checks:([1; 3; 4; 6], 2) + () + in + try + H.test_circuit + ~name:"Range_Checks_single_wrong" + ~zero_knowledge + circuit + inputs + with Plonk.Main_protocol.Rest_not_null _ -> () + + (* This test does not work since several proofs are not supported yet *) + let test_range_checks_multi ~zero_knowledge () = + let wires = SMap.map Array.to_list General.circuit.wires in + let gates = SMap.map Array.to_list General.circuit.gates in + let circuit1 = + Plonk.Circuit.make + ~wires + ~gates + ~public_input_size:General.circuit.public_input_size + ~range_checks:([4; 6], 4) + () + in + let witness = General.witness in + let circuit2 = + Plonk.Circuit.make + ~wires + ~gates + ~public_input_size:General.circuit.public_input_size + ~range_checks:([1; 2], 2) + () + in + let circuits = + SMap.of_list [("circuit1", (circuit1, 2)); ("circuit2", (circuit2, 1))] + in + let inputs = + SMap.of_list [("circuit1", [witness; witness]); ("circuit2", [witness])] + in + + H.test_circuits ~name:"Range_Checks_multi" ~zero_knowledge circuits inputs ; + + let circuit3 = + Plonk.Circuit.make + ~wires + ~gates + ~public_input_size:General.circuit.public_input_size + ~range_checks:([1; 3; 4; 6], 2) + () + in + let circuits = SMap.add_unique "circuit3" (circuit3, 1) circuits in + let inputs = SMap.add_unique "circuit3" [witness] inputs in + try + H.test_circuits + ~name:"Range_Checks_multi_wrong" + ~zero_knowledge + circuits + inputs + with Plonk.Main_protocol.Rest_not_null _ -> () + + let tests_quick pc_name = + [ + (pc_name ^ ".Range_Checks_single", test_range_checks_single) + (* (pc_name ^ ".Range_Checks_multi", test_range_checks_multi); *); + ] +end + +module External_Kzg = External (Polynomial_commitment) +module External_Kzg_pack = External (Aggregation.Polynomial_commitment) + +(* TODO zk tests *) +let tests = + let tests_kzg = External_Kzg.tests_quick "KZG" in + let tests_kzg_pack = External_Kzg_pack.tests_quick "KZG_Pack" in + List.map + (fun (n, f) -> Alcotest.test_case n `Quick (f ~zero_knowledge:false)) + (tests_kzg @ tests_kzg_pack) diff --git a/src/lib_plonk/test/test_utils.ml b/src/lib_plonk/test/test_utils.ml new file mode 100644 index 000000000000..4c3a0c8ff1db --- /dev/null +++ b/src/lib_plonk/test/test_utils.ml @@ -0,0 +1,127 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk.List +module Helpers = Plonk_test.Helpers + +let rng6 = [1; 2; 3; 4; 5; 6] + +let list_tests () = + let left, right = split_n 2 rng6 in + assert (List.equal ( = ) [1; 2] left) ; + assert (List.equal ( = ) [3; 4; 5; 6] right) ; + + let left, right = split_in_half rng6 in + assert (List.equal ( = ) [1; 2; 3] left) ; + assert (List.equal ( = ) [4; 5; 6] right) ; + + assert ( + 21 * 21 = fold_left3 (fun acc a b c -> acc + (a * b * c)) 0 rng6 rng6 rng6) + +module Fr_generation = struct + module Scalar = Plonk.Bls.Scalar + module Fr_generation = Plonk.Utils.Fr_generation + module Scalar_set = Set.Make (Scalar) + + let test_powers () = + let n = 256 in + let x = Scalar.random () in + let ps = Fr_generation.powers n x in + assert (Array.length ps = n) ; + assert (Scalar.eq Scalar.one ps.(0)) ; + for i = 1 to n - 1 do + assert (ps.(i) = Scalar.mul ps.(i - 1) x) + done + + let test_random_fr () = + let transcript = Random.int 1000 |> string_of_int |> Bytes.of_string in + (* check that the transcript changes after sampling *) + let x, new_transcript = Fr_generation.random_fr transcript in + assert (not @@ Bytes.equal transcript new_transcript) ; + (* check that different transcripts lead to different elements (w.h.p.) *) + let y, _ = Fr_generation.random_fr new_transcript in + assert (not @@ Scalar.eq x y) ; + (* check that random_fr and random_fr_list are consistent when only + one element is sampled *) + let l, new_transcript' = Fr_generation.random_fr_list transcript 1 in + assert (Bytes.equal new_transcript new_transcript') ; + (match l with [x'] -> assert (Scalar.eq x x') | _ -> assert false) ; + (* check that all outputs of random_fr_list are different (w.h.p.) *) + let n = 100 in + let l, _ = Fr_generation.random_fr_list transcript n in + let dedup_l = List.sort_uniq Scalar.compare l in + assert (List.length dedup_l = n) + + (* generates the subgroup generated by the default 2^n-th root of unity + sampled in bls12-381-polynomial fr_generation *) + let subgroup_H n = + let module BLS_Fr_gen = Octez_bls12_381_polynomial.Fr_carray in + let w = BLS_Fr_gen.primitive_root_of_unity_power_of_two ~log:n in + Fr_generation.powers (1 lsl n) w |> Array.to_list |> Scalar_set.of_list + + (* check that the subgroup generated by the default 2^n-th root of unity + leads to disjoint sets when shifted by any of the first k default + quadratic non-residues *) + let test_disjoint_shifted_subgroups k n = + let non_residues = Fr_generation.build_quadratic_non_residues k in + let sH = subgroup_H n in + let subgroups = + Array.map (fun nr -> Scalar_set.map (Scalar.mul nr) sH) non_residues + in + for i = 0 to k - 1 do + for j = i + 1 to k - 1 do + assert (Scalar_set.disjoint subgroups.(i) subgroups.(j)) + done + done + + let test_quadratic_non_residues () = + (* we set k = 3 because we use PLONK we an architecture of 3 wires *) + let k = 3 in + for n = 0 to 16 do + test_disjoint_shifted_subgroups k n + done + + let test_quadratic_non_residues_slow () = + (* we set k = 3 because we use PLONK we an architecture of 3 wires *) + let k = 3 in + for n = 17 to 21 do + test_disjoint_shifted_subgroups k n + done + + let tests = + Alcotest. + [ + test_case "powers" `Quick test_powers; + test_case "random_fr" `Quick test_random_fr; + test_case "quadratic_non_residues" `Quick test_quadratic_non_residues; + test_case + "quadratic_non_residues_slow" + `Slow + test_quadratic_non_residues_slow; + ] +end + +let tests = + Alcotest.(test_case "List.ml" `Quick list_tests) :: Fr_generation.tests -- GitLab From 3d543c5ad676e8ab7b4823e2360ab70750cb14a1 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Fri, 17 Mar 2023 12:06:07 +0100 Subject: [PATCH 20/34] octez_plonk_test_helpers_bench: import from privacy-team/cryptography --- manifest/main.ml | 9 +++ src/lib_plonk/test/bench.ml | 129 ++++++++++++++++++++++++++++++++++++ src/lib_plonk/test/dune | 6 ++ 3 files changed, 144 insertions(+) create mode 100644 src/lib_plonk/test/bench.ml diff --git a/manifest/main.ml b/manifest/main.ml index aaab69c81479..58abf3458cc6 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1315,6 +1315,15 @@ let _octez_plonk_test_helpers_main = octez_bls12_381_polynomial |> open_; ] +let _octez_plonk_test_helpers_bench = + private_exe + "bench" + ~path:"src/lib_plonk/test" + ~opam:"octez-plonk" + ~modules:["bench"] + ~bisect_ppx:No + ~deps:[octez_plonk_test_helpers] + let _octez_srs_extraction_tests = tests ["main"] diff --git a/src/lib_plonk/test/bench.ml b/src/lib_plonk/test/bench.ml new file mode 100644 index 000000000000..44a4e23446c9 --- /dev/null +++ b/src/lib_plonk/test/bench.ml @@ -0,0 +1,129 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Main = Plonk.Main_protocol +module H = Plonk_test.Helpers.Make (Main) +module S = Plompiler.S + +(* let () = + let k = 16 in + let public_input_size = 10 in + let start_build_circuit = Unix.gettimeofday () in + let case = + Plonk_test.Cases.Big_circuit.make ~nb_proofs:1 ~public_input_size ~k + |> List.hd + in + let end_build_circuit = Unix.gettimeofday () in + Printf.printf "\n\nNumber of gates : %d\nNumber of public inputs : %d\n" + ((1 lsl k) - 1) + public_input_size; + Printf.printf "Dummy circuit built in %f ms.\n" + ((end_build_circuit -. start_build_circuit) *. 1000.); + H.run_test_case ~verbose:true ~zero_knowledge:false case () *) + +let rc_circuit n nb_range_checks nb_bits = + let open Plompiler.LibCircuit in + let inputs = + List.init nb_range_checks (fun i -> + Input.scalar (Plompiler.S.of_z (Z.of_int (i + 1)))) + in + Printf.printf "\nnb_bits : %d" nb_bits ; + Printf.printf "\nbound : %d\n" (1 lsl nb_bits) ; + let range_checks r_list = + let* b = + mapM + (Num.is_upper_bounded_unsafe + ~nb_bits + ~bound:Z.((one lsl nb_bits) - one)) + r_list + in + Bool.band_list b + in + (* This circuit has 2^n dummy constraints, takes [inputs] as inputs, and if + [rc] is true, it adds a range check on every input *) + let circuit rc inputs = + let* inputs = mapM input inputs in + let* i1 = constant_scalar S.zero in + let l = List.init (1 lsl n) (Fun.const i1) in + let i = ref 0 in + let* foo = + foldM + (fun acc a -> + i := !i + 1 ; + let i = S.of_z (Z.of_int !i) in + Num.custom ~qc:i ~ql:i acc a) + i1 + l + in + let* rc = if rc then range_checks inputs else equal foo foo in + Bool.assert_true rc + in + (circuit true inputs, circuit false inputs) + +let () = + let open Plonk_test.Cases in + let nb_constraints = 13 in + let nb_range_checks = 1 lsl 6 in + let nb_bits = 16 in + let start_build_circuit = Unix.gettimeofday () in + let with_rc, no_rc = rc_circuit nb_constraints nb_range_checks nb_bits in + let range_checks = List.init nb_range_checks (fun i -> i + 1) in + let base_witness = !!range_checks in + Printf.printf "\n\n------------------\n" ; + let cs_with_rc = Plompiler.LibCircuit.get_cs with_rc in + let witness_with_rc = Plompiler.Solver.solve cs_with_rc.solver base_witness in + let circuit_with_rc = + Plonk.Circuit.to_plonk ~public_input_size:0 cs_with_rc.cs + in + Printf.printf "\n\n------------------\n" ; + (* Note that range checks are not the same as the ones in the previous + circuit ; it is just indexes I took to make it work *) + let range_checks = + List.( + rev (init nb_range_checks (fun i -> (1 lsl (nb_constraints + 1)) - i - 1))) + in + let cs_no_rc = Plompiler.LibCircuit.get_cs no_rc in + let witness_no_rc = Plompiler.Solver.solve cs_no_rc.solver base_witness in + let circuit_no_rc = + Plonk.Circuit.to_plonk + ~range_checks:(range_checks, nb_bits) + ~public_input_size:0 + cs_no_rc.cs + in + let end_build_circuit = Unix.gettimeofday () in + Printf.printf + "Dummy circuit built in %f ms.\n" + ((end_build_circuit -. start_build_circuit) *. 1000.) ; + Printf.printf "\n\n------------------\n" ; + Plonk_test.Helpers.( + Time.bench_test_circuit ~nb_rep:1 (fun () -> + H.test_circuit ~name:"" ~verbose:true circuit_with_rc witness_with_rc)) + () ; + Gc.full_major () ; + Printf.printf "\n\n------------------\n" ; + Plonk_test.Helpers.( + Time.bench_test_circuit ~nb_rep:1 (fun () -> + H.test_circuit ~name:"" ~verbose:true circuit_no_rc witness_no_rc)) + () diff --git a/src/lib_plonk/test/dune b/src/lib_plonk/test/dune index 867f5e75a97f..64b2dc9f5b32 100644 --- a/src/lib_plonk/test/dune +++ b/src/lib_plonk/test/dune @@ -52,3 +52,9 @@ test_polynomial_protocol test_range_checks test_utils)) + +(executable + (name bench) + (libraries + octez-plonk.plonk-test) + (modules bench)) -- GitLab From eed4c13dc7a04883f9d96c82ef4f7adacd6abdfc Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 15 Mar 2023 13:13:39 +0100 Subject: [PATCH 21/34] lib_plonk test_plompiler: add afl --- manifest/main.ml | 9 ++++ opam/octez-plonk.opam | 1 + src/lib_plonk/test/main.ml | 4 +- src/lib_plonk/test_plompiler/afl.ml | 82 +++++++++++++++++++++++++++++ src/lib_plonk/test_plompiler/dune | 10 ++++ 5 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 src/lib_plonk/test_plompiler/afl.ml create mode 100644 src/lib_plonk/test_plompiler/dune diff --git a/manifest/main.ml b/manifest/main.ml index 58abf3458cc6..65e919ebf7aa 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1324,6 +1324,15 @@ let _octez_plonk_test_helpers_bench = ~bisect_ppx:No ~deps:[octez_plonk_test_helpers] +let _octez_plonk_test_plompiler_afl = + private_exe + "afl" + ~path:"src/lib_plonk/test_plompiler" + ~opam:"octez-plonk" + ~modules:["afl"] + ~bisect_ppx:No + ~deps:[octez_plompiler; octez_plonk; bls12_381] + let _octez_srs_extraction_tests = tests ["main"] diff --git a/opam/octez-plonk.opam b/opam/octez-plonk.opam index 0e9a9ac61612..2bb7cfb14fbb 100644 --- a/opam/octez-plonk.opam +++ b/opam/octez-plonk.opam @@ -17,6 +17,7 @@ depends: [ "octez-bls12-381-polynomial" "octez-plompiler" "qcheck-alcotest" { >= "0.20" } + "bls12-381" { >= "6.1.0" & < "6.2.0" } ] build: [ ["rm" "-r" "vendors"] diff --git a/src/lib_plonk/test/main.ml b/src/lib_plonk/test/main.ml index f7ff72558200..60a069073713 100644 --- a/src/lib_plonk/test/main.ml +++ b/src/lib_plonk/test/main.ml @@ -28,7 +28,9 @@ open Plonk_test let () = Helpers.with_seed (fun () -> Helpers.with_output_to_file (fun () -> - Alcotest.run ~verbose:false "PlonK" + Alcotest.run + ~verbose:false + "PlonK" [ ("Utils", Test_utils.tests); ("Evaluations", Test_evaluations.tests); diff --git a/src/lib_plonk/test_plompiler/afl.ml b/src/lib_plonk/test_plompiler/afl.ml new file mode 100644 index 000000000000..4b6373342f18 --- /dev/null +++ b/src/lib_plonk/test_plompiler/afl.ml @@ -0,0 +1,82 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +module CS = Plonk.Circuit + +module Gen = struct + let read_int () = + try input_binary_int stdin + with End_of_file -> + Printf.printf "insufficient input" ; + exit 0 + + let scalar () = + (* Fr.random () *) + S.of_z @@ Z.of_int @@ read_int () +end + +let test_afl () = + let module P (L : LIB) = struct + open L + open L.Num + + let[@warning "-8"] t (x, y) = + let* x = input x in + let* y = input y in + let* o = add x y in + let* o = mul o y in + div o y + + let ins = Input.(scalar S.zero, scalar S.one) + end in + let circuit, ins = + let module E1 = P (LibCircuit) in + (E1.t, E1.ins) + in + + let LibCircuit.{cs; tables; solver; _} = LibCircuit.(get_cs (circuit ins)) in + (* safety: sat => trace *) + let private_inputs = Array.init solver.final_size (fun _ -> Gen.scalar ()) in + if CS.sat cs tables private_inputs then ( + print_endline "satisfied" ; + let initial, _ = LibCircuit.(get_inputs (circuit ins)) in + let solved_pi = Solver.solve solver initial in + assert (Array.for_all2 S.( = ) solved_pi private_inputs)) + else () ; + (* soundness: trace => sat *) + let trace = + let x = LibCircuit.Input.scalar @@ Gen.scalar () in + let y = LibCircuit.Input.scalar @@ Gen.scalar () in + let initial, _ = LibCircuit.(get_inputs (circuit (x, y))) in + try Solver.solve solver initial |> fun x -> Some x with _ -> None + in + match trace with + | None -> () + | Some trace -> + print_endline "found trace" ; + assert (CS.sat cs tables trace) + +let () = test_afl () diff --git a/src/lib_plonk/test_plompiler/dune b/src/lib_plonk/test_plompiler/dune new file mode 100644 index 000000000000..b0d154178620 --- /dev/null +++ b/src/lib_plonk/test_plompiler/dune @@ -0,0 +1,10 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(executable + (name afl) + (libraries + octez-plompiler + octez-plonk + bls12-381) + (modules afl)) -- GitLab From c1ea0fe4014a772503445b250f3cb480c0f2b60b Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 15 Mar 2023 13:22:19 +0100 Subject: [PATCH 22/34] lib_plonk test_plompiler: add main.exe --- manifest/main.ml | 68 + .../test_plompiler/bench_poseidon.ml | 104 + src/lib_plonk/test_plompiler/benchmark.ml | 629 ++ src/lib_plonk/test_plompiler/dune | 44 + src/lib_plonk/test_plompiler/main.ml | 52 + .../test_plompiler/test-quick.expected | 2022 +++++++ .../test_plompiler/test-slow.expected | 5108 +++++++++++++++++ src/lib_plonk/test_plompiler/test_anemoi.ml | 271 + src/lib_plonk/test_plompiler/test_blake.ml | 201 + src/lib_plonk/test_plompiler/test_core.ml | 1044 ++++ src/lib_plonk/test_plompiler/test_edwards.ml | 325 ++ src/lib_plonk/test_plompiler/test_encoding.ml | 203 + src/lib_plonk/test_plompiler/test_enum.ml | 75 + .../test_plompiler/test_input_com.ml | 88 + .../test_plompiler/test_linear_algebra.ml | 75 + src/lib_plonk/test_plompiler/test_lookup.ml | 74 + src/lib_plonk/test_plompiler/test_merkle.ml | 159 + .../test_plompiler/test_merkle_narity.ml | 100 + .../test_plompiler/test_optimizer.ml | 120 + src/lib_plonk/test_plompiler/test_poseidon.ml | 120 + src/lib_plonk/test_plompiler/test_schnorr.ml | 111 + .../test_plompiler/test_serialization.ml | 52 + .../test_plompiler/test_weierstrass.ml | 188 + 23 files changed, 11233 insertions(+) create mode 100644 src/lib_plonk/test_plompiler/bench_poseidon.ml create mode 100644 src/lib_plonk/test_plompiler/benchmark.ml create mode 100644 src/lib_plonk/test_plompiler/main.ml create mode 100644 src/lib_plonk/test_plompiler/test-quick.expected create mode 100644 src/lib_plonk/test_plompiler/test-slow.expected create mode 100644 src/lib_plonk/test_plompiler/test_anemoi.ml create mode 100644 src/lib_plonk/test_plompiler/test_blake.ml create mode 100644 src/lib_plonk/test_plompiler/test_core.ml create mode 100644 src/lib_plonk/test_plompiler/test_edwards.ml create mode 100644 src/lib_plonk/test_plompiler/test_encoding.ml create mode 100644 src/lib_plonk/test_plompiler/test_enum.ml create mode 100644 src/lib_plonk/test_plompiler/test_input_com.ml create mode 100644 src/lib_plonk/test_plompiler/test_linear_algebra.ml create mode 100644 src/lib_plonk/test_plompiler/test_lookup.ml create mode 100644 src/lib_plonk/test_plompiler/test_merkle.ml create mode 100644 src/lib_plonk/test_plompiler/test_merkle_narity.ml create mode 100644 src/lib_plonk/test_plompiler/test_optimizer.ml create mode 100644 src/lib_plonk/test_plompiler/test_poseidon.ml create mode 100644 src/lib_plonk/test_plompiler/test_schnorr.ml create mode 100644 src/lib_plonk/test_plompiler/test_serialization.ml create mode 100644 src/lib_plonk/test_plompiler/test_weierstrass.ml diff --git a/manifest/main.ml b/manifest/main.ml index 65e919ebf7aa..fe3deb529402 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1333,6 +1333,74 @@ let _octez_plonk_test_plompiler_afl = ~bisect_ppx:No ~deps:[octez_plompiler; octez_plonk; bls12_381] +let _octez_plonk_test_plompiler_main = + private_exe + "main" + ~path:"src/lib_plonk/test_plompiler" + ~opam:"octez-plonk" + ~modules: + [ + "bench_poseidon"; + "benchmark"; + "main"; + "test_anemoi"; + "test_blake"; + "test_core"; + "test_edwards"; + "test_encoding"; + "test_enum"; + "test_input_com"; + "test_linear_algebra"; + "test_lookup"; + "test_merkle"; + "test_merkle_narity"; + "test_optimizer"; + "test_poseidon"; + "test_schnorr"; + "test_serialization"; + "test_weierstrass"; + ] + ~bisect_ppx:No + ~deps:[octez_plonk_test_helpers] + ~dune: + Dune. + [ + alias_rule + "runtest" + ~package:"octez-plonk" + ~action: + (G + [ + setenv + "RANDOM_SEED" + "42" + (progn + [ + run_exe "main" ["-q"]; + [S "diff?"; S "test-quick.expected"; S "test.output"]; + ]); + ]); + alias_rule + "runtest_slow" + ~package:"octez-plonk" + ~action:(run_exe "main" []); + alias_rule + "runtest_slow_with_regression" + ~package:"octez-plonk" + ~action: + (G + [ + setenv + "RANDOM_SEED" + "42" + (progn + [ + run_exe "main" []; + [S "diff?"; S "test-slow.expected"; S "test.output"]; + ]); + ]); + ] + let _octez_srs_extraction_tests = tests ["main"] diff --git a/src/lib_plonk/test_plompiler/bench_poseidon.ml b/src/lib_plonk/test_plompiler/bench_poseidon.ml new file mode 100644 index 000000000000..3bccc362a493 --- /dev/null +++ b/src/lib_plonk/test_plompiler/bench_poseidon.ml @@ -0,0 +1,104 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk_test +open LibCircuit +module CS = Plonk.Circuit +module Hash = Poseidon128.V (LibCircuit) +module Main = Plonk.Main_protocol + +open Helpers.Utils (LibCircuit) + +let hash x = + let ctx = Poseidon128.P.init ~input_length:1 () in + let ctx = Poseidon128.P.digest ctx [|x|] in + Poseidon128.P.get ctx + +let rec repeated_hash n x = if n <= 0 then x else repeated_hash (n - 1) (hash x) + +let build_poseidon_circuit ~nb_hashes_per_circuit x y () = + let* start = input ~kind:`Public @@ Input.scalar x in + let* expected = input @@ Input.scalar y in + let* out = + foldM + (fun acc _ -> + let* acc = Hash.digest ~input_length:1 (to_list [acc]) in + ret acc) + start + (List.init nb_hashes_per_circuit Fun.id) + in + with_bool_check (equal out expected) + +let benchmark () = + let nb_hashes_per_circuit = 100 in + let nb_proofs = 2 in + + let x = S.random () in + let y = repeated_hash nb_hashes_per_circuit x in + let circuit = build_poseidon_circuit ~nb_hashes_per_circuit x y () in + + let {cs; solver; _} = get_cs ~optimize:true circuit in + let initial, public_input_size = get_inputs circuit in + let private_inputs = Solver.solve solver initial in + + assert (CS.sat cs [] private_inputs) ; + + let inputs = Main.{witness = private_inputs; input_commitments = []} in + let plonk_circuit = Plonk.Circuit.to_plonk ~public_input_size cs in + let cname = "" in + let replicate x = List.init nb_proofs (Fun.const x) in + let circuits_map = Plonk.SMap.singleton cname (plonk_circuit, nb_proofs) in + let inputs_map = Plonk.SMap.singleton cname (replicate inputs) in + + let zero_knowledge = false in + Printf.printf + "\nIterated Poseidon circuit of %d hashes\n" + nb_hashes_per_circuit ; + Printf.printf "Constraints per circuit: %d\n" Array.(concat cs |> length) ; + Printf.printf "Number of proofs: %d\n" nb_proofs ; + Printf.printf + "Total number of Poseidon hashes involved: %d\n" + (nb_hashes_per_circuit * nb_proofs) ; + Format.print_flush () ; + + let pp_prv, pp_vrf = + Helpers.Time.time "Setup" @@ fun () -> + Main.setup ~zero_knowledge circuits_map ~srs:Helpers.srs + in + + let proof = + Helpers.Time.time "Prove" @@ fun () -> Main.prove pp_prv ~inputs:inputs_map + in + + let verifier_inputs = Main.to_verifier_inputs pp_prv inputs_map in + + let verif_ok = + Helpers.Time.time "Verify" @@ fun () -> + Main.verify pp_vrf ~inputs:verifier_inputs proof + in + assert verif_ok + +let bench = [Alcotest.test_case "Poseidon benchmark" `Slow benchmark] diff --git a/src/lib_plonk/test_plompiler/benchmark.ml b/src/lib_plonk/test_plompiler/benchmark.ml new file mode 100644 index 000000000000..ab61ed96a0d7 --- /dev/null +++ b/src/lib_plonk/test_plompiler/benchmark.ml @@ -0,0 +1,629 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk_test +module HashPV = Poseidon128 +module MerklePV = Gadget.Merkle (HashPV) +module SchnorrPV = Plompiler.Schnorr (HashPV) +module Hash = HashPV.P +module Merkle = MerklePV.P +module Schnorr = SchnorrPV.P +module Curve = Mec.Curve.Jubjub.AffineEdwards + +let two = Z.of_int 2 + +let depth_tree = 10 + +let max_nb_accounts = Z.(shift_left one depth_tree) + +let max_balance = Z.(shift_left one 20) + +let max_amount = Z.(shift_left one 20) + +let max_fee = Z.(shift_left one 10) + +let max_counter = Z.(shift_left one 20) + +(* Checks to ensure that we do not have overflows when updating the balance. *) +let () = assert (Z.(two * max_balance < Bls12_381.Fr.order)) + +let () = assert (Z.(two * (max_amount + max_fee) < Bls12_381.Fr.order)) + +(* If size of an account balance and counter < BLS12-381 Fr order, we can + compress the Merkle leaf to 2 scalars (pk_x, compress(balance, counter)). *) +let () = + assert ( + Z.numbits max_balance + Z.numbits max_counter + < Z.(numbits Bls12_381.Fr.order)) + +(* If the accumulated size of the two accounts, tx amount, tx fee and + cnt_src < BLS12-381 Fr order, we can compress the Schnorr message to 1 scalar. *) +let () = + assert ( + (2 * depth_tree) + Z.numbits max_amount + Z.numbits max_fee + + Z.numbits max_counter + < Z.(numbits Bls12_381.Fr.order)) + +let nb_bits_base = Z.numbits S.order + +module TxHelpers = struct + let of_int x = Z.of_int x |> S.of_z + + let to_bls_scalar s = Curve.Base.of_z (S.to_z s) + + let of_bls_scalar s = S.of_z (Curve.Base.to_z s) + + let point_to_affine (u, v) = + Curve.unsafe_from_coordinates ~u:(to_bls_scalar u) ~v:(to_bls_scalar v) + + let affine_to_point p = + let u = Curve.get_u_coordinate p in + let v = Curve.get_v_coordinate p in + (of_bls_scalar u, of_bls_scalar v) +end + +include TxHelpers + +let random_int = Stdlib.Random.int + +let random_z bound = Random.int64 (Z.to_int64 bound) |> Z.of_int64 + +(* These functions aimed to format integers more efficiently by compressing + them in a scalar. *) + +(* This function computes the maximal bound of a list of bounded variables + written as [(value, bound)_1, ..., (value, bound)_n] *) +let compression_bound values = List.fold_left Z.mul Z.one (List.map snd values) + +(* This function attempts to compress a list of integers into one scalar. *) +let compress values = + assert (compression_bound values < S.order) ; + List.fold_left + (fun acc (v, v_bound) -> Z.(v + (acc * v_bound))) + (fst @@ List.hd values) + (List.tl values) + +type state = { + sks : Schnorr.sk array; + balances : Z.t array; + counters : Z.t array; + tree : Merkle.tree; +} + +type account = {pk : Schnorr.pk; balance : Z.t; cnt : Z.t} + +type proof = {init_path : Merkle.path; root : S.t; new_path : Merkle.path} + +type tx = { + src_pos : int; + dst_pos : int; + amount : Z.t; + fee : Z.t; + msg : S.t; + src : account; + dst : account; + src_proof : proof; + dst_proof : proof; + signature : Schnorr.signature; +} + +let make_leaf pk bal counter = + (* We can use just the u coordinate of pk as Edwards curves are symmetric and as such there are only two possible v coordinates and the same sk is used to generate both. + We could set a convention to only use pk with v coordination of a given parity, for instance v odd. *) + (* TODO move this in schnorr and make the pk directly a single coordinate *) + let u = Curve.get_u_coordinate pk |> of_bls_scalar in + let compressed = compress [(bal, max_balance); (counter, max_counter)] in + Hash.direct ~input_length:2 [|u; S.of_z compressed|] + +let init_state () = + let size = Z.to_int max_nb_accounts in + let sks = Array.init size (fun _ -> Curve.Scalar.random ()) in + let balances = Array.init size (fun _ -> random_z Z.(max_balance / two)) in + let counters = Array.init size (fun _ -> random_z max_counter) in + let leaves = + Array.init size (fun i -> + make_leaf (Schnorr.neuterize sks.(i)) balances.(i) counters.(i)) + in + let tree = Merkle.generate_tree ~leaves depth_tree in + {sks; balances; counters; tree} + +let generate_transaction : state -> tx * state = + fun ({sks; balances; counters; tree} as state) -> + let size = Z.to_int max_nb_accounts in + let src_pos = random_int size in + let dst_pos = random_int size in + let sk_src = sks.(src_pos) in + let bl_src = balances.(src_pos) in + let bl_dst = balances.(dst_pos) in + let cnt_src = counters.(src_pos) in + let pk_src = Schnorr.neuterize sk_src in + let fee = random_z Z.(min bl_src max_fee) in + let max_src_amount = Z.(min (bl_src - fee) max_amount) in + let max_dst_amount = Z.(max_balance - bl_dst) in + let amount = random_z Z.(min max_src_amount max_dst_amount) in + let msg = + let compressed_msg = + compress + [ + (Z.of_int src_pos, max_nb_accounts); + (Z.of_int dst_pos, max_nb_accounts); + (fee, max_fee); + (amount, max_amount); + (cnt_src, max_counter); + ] + in + Hash.direct ~input_length:1 [|S.of_z compressed_msg|] + in + let signature = + let random = Curve.Scalar.random () in + Schnorr.sign ~compressed:true sk_src msg random + in + let src_proof, tree = + let _, init_path = Merkle.proof_path src_pos tree in + let new_bl_src = Z.(bl_src - amount - fee) in + let new_cnt_src = Z.succ cnt_src in + let new_leaf_src = make_leaf pk_src new_bl_src new_cnt_src in + balances.(src_pos) <- Z.(bl_src - amount - fee) ; + counters.(src_pos) <- new_cnt_src ; + let tree = Merkle.update_tree ~input_length:2 tree src_pos new_leaf_src in + let root = Merkle.root tree in + + let _, new_path = Merkle.proof_path src_pos tree in + ({init_path; root; new_path}, tree) + in + (* We retrieve bl_dst after updating the src_leaf as dst may be equal to src *) + let sk_dst = sks.(dst_pos) in + let bl_dst = balances.(dst_pos) in + let cnt_dst = counters.(dst_pos) in + let pk_dst = Schnorr.neuterize sk_dst in + let dst_proof, tree = + let _, init_path = Merkle.proof_path dst_pos tree in + let new_leaf = make_leaf pk_dst Z.(bl_dst + amount) cnt_dst in + balances.(dst_pos) <- Z.(bl_dst + amount) ; + let tree = Merkle.update_tree ~input_length:2 tree dst_pos new_leaf in + let root = Merkle.root tree in + let _, new_path = Merkle.proof_path dst_pos tree in + ({init_path; root; new_path}, tree) + in + ( { + src_pos; + dst_pos; + amount; + fee; + msg; + src = {pk = pk_src; balance = bl_src; cnt = Z.(succ cnt_src)}; + dst = {pk = pk_dst; balance = bl_dst; cnt = cnt_dst}; + src_proof; + dst_proof; + signature; + }, + {state with tree; balances; counters} ) + +(* TODO this should make a block *) +let generate_transactions n state = + let rec aux n state acc_tx = + if n <= 0 then (List.rev acc_tx, state) + else + let tx, state = generate_transaction state in + aux (n - 1) state (tx :: acc_tx) + in + aux n state [] + +module Benchmark (L : LIB) = struct + module Hash = HashPV.V (L) + module Plompiler_Curve = JubjubEdwards (L) + module Schnorr = SchnorrPV.V (L) + module Merkle = MerklePV.V (L) + + open Helpers.Utils (L) + + open L + + let monadic_compress values = + assert (compression_bound values < S.order) ; + foldM + (fun acc (v, v_bound) -> Num.add ~ql:(S.of_z v_bound) acc v) + (fst @@ List.hd values) + (List.tl values) + + open Encodings (L) + + type curve_t_u = (scalar * scalar) repr + + let curve_base_to_s c = S.of_z @@ Curve.Base.to_z c + + let curve_base_of_s c = Curve.Base.of_z @@ S.to_z c + + let curve_scalar_to_s c = S.of_z @@ Curve.Scalar.to_z c + + let curve_scalar_of_s c = Curve.Scalar.of_z @@ S.to_z c + + let s_of_int x = S.of_z (Z.of_int x) + + let s_to_int s = Z.to_int (S.to_z s) + + type curve_base_t_u = scalar repr + + type curve_scalar_t_u = scalar repr + + let curve_scalar_t_encoding : (Curve.Scalar.t, curve_scalar_t_u, _) encoding = + conv + (fun r -> r) + (fun r -> r) + curve_scalar_to_s + curve_scalar_of_s + scalar_encoding + + let curve_t_encoding : (Curve.t, curve_t_u, _) encoding = + with_implicit_bool_check Plompiler_Curve.is_on_curve + @@ conv + (fun r -> of_pair r) + (fun (u, v) -> pair u v) + (fun c -> + ( curve_base_to_s @@ Curve.get_u_coordinate c, + curve_base_to_s @@ Curve.get_v_coordinate c )) + (fun (u, v) -> + Curve.from_coordinates_exn + ~u:(curve_base_of_s u) + ~v:(curve_base_of_s v)) + (obj2_encoding scalar_encoding scalar_encoding) + + type account_u = { + pk : Schnorr.pk repr; + balance : scalar repr; + cnt : scalar repr; + } + + let account_encoding : (account, account_u, _) encoding = + conv + (fun {pk; balance; cnt} -> (pk, (balance, cnt))) + (fun (pk, (balance, cnt)) -> {pk; balance; cnt}) + (fun (acc : account) -> (acc.pk, (S.of_z acc.balance, S.of_z acc.cnt))) + (fun (pk, (balance, cnt)) -> + {pk; balance = S.to_z balance; cnt = S.to_z cnt}) + (obj3_encoding Schnorr.pk_encoding scalar_encoding scalar_encoding) + + type proof_u = { + init_path : Merkle.path; + root : scalar repr; + new_path : Merkle.path; + } + + let proof_encoding : (proof, proof_u, _) encoding = + conv + (fun {init_path; root; new_path} -> (init_path, (root, new_path))) + (fun (init_path, (root, new_path)) -> {init_path; root; new_path}) + (fun ({init_path; root; new_path} : proof) -> + (init_path, (root, new_path))) + (fun (init_path, (root, new_path)) -> {init_path; root; new_path}) + (obj3_encoding Merkle.path_encoding scalar_encoding Merkle.path_encoding) + + type tx_u = { + src_pos : scalar repr; + dst_pos : scalar repr; + amount : scalar repr; + fee : scalar repr; + msg : curve_base_t_u; + src : account_u; + dst : account_u; + src_proof : proof_u; + dst_proof : proof_u; + signature : Schnorr.signature; + } + + let tx_encoding : (tx, tx_u, _) encoding = + conv + (fun tx -> + ( tx.src_pos, + ( tx.dst_pos, + ( tx.amount, + ( tx.fee, + ( tx.msg, + ( tx.src, + (tx.dst, (tx.src_proof, (tx.dst_proof, tx.signature))) ) ) + ) ) ) )) + (fun ( src_pos, + ( dst_pos, + ( amount, + (fee, (msg, (src, (dst, (src_proof, (dst_proof, signature)))))) + ) ) ) -> + { + src_pos; + dst_pos; + amount; + fee; + msg; + src; + dst; + src_proof; + dst_proof; + signature; + }) + (fun (tx : tx) -> + ( s_of_int tx.src_pos, + ( s_of_int tx.dst_pos, + ( S.of_z tx.amount, + ( S.of_z tx.fee, + ( tx.msg, + ( tx.src, + (tx.dst, (tx.src_proof, (tx.dst_proof, tx.signature))) ) ) + ) ) ) )) + (fun ( src_pos, + ( dst_pos, + ( amount, + (fee, (msg, (src, (dst, (src_proof, (dst_proof, signature)))))) + ) ) ) -> + { + src_pos = s_to_int src_pos; + dst_pos = s_to_int dst_pos; + amount = S.to_z amount; + fee = S.to_z fee; + msg; + src; + dst; + src_proof; + dst_proof; + signature; + }) + (obj10_encoding + scalar_encoding + scalar_encoding + scalar_encoding + scalar_encoding + scalar_encoding + account_encoding + account_encoding + proof_encoding + proof_encoding + Schnorr.signature_encoding) + + let check_merkle_proof pk bl cnt path root = + let pk_x, _pk_y = of_pair pk in + let* compressed = + monadic_compress [(bl, max_balance); (cnt, max_counter)] + in + (* Building leaf *) + let* leaf = Hash.digest ~input_length:2 (to_list [pk_x; compressed]) in + (* Building merkle proof *) + Merkle.merkle_proof path leaf root + + let make_rollup init_tree tx_list () = + let* generator = + Plompiler_Curve.(input_point @@ affine_to_point Schnorr.g) + in + let* init_root = Input.scalar init_tree |> input in + let* inputs_rollup = + mapM + (fun (tx : tx) -> + let i = tx_encoding.input tx in + input i) + tx_list + in + let* _root = + foldM + (fun fold_root ptx -> + let tx = tx_encoding.decode ptx in + (* ---------- Check the init src leaf is in the init tree ---------- *) + let* init_cnt_src = Num.add_constant S.mone tx.src.cnt in + let* b_init_src_leaf = + check_merkle_proof + tx.src.pk + tx.src.balance + init_cnt_src + tx.src_proof.init_path + fold_root + in + (* ---------- Check the new src leaf is in the tmp tree ---------- *) + (* Building new src leaf *) + let* new_bl_src = + Num.add_list + ~coeffs:S.[one; mone; mone] + (to_list [tx.src.balance; tx.amount; tx.fee]) + in + let* b_new_src_leaf = + check_merkle_proof + tx.src.pk + new_bl_src + tx.src.cnt + tx.src_proof.new_path + tx.src_proof.root + in + (* ---------- Check the init dst leaf is in the init tree ---------- *) + let* b_init_dst_leaf = + check_merkle_proof + tx.dst.pk + tx.dst.balance + tx.dst.cnt + tx.dst_proof.init_path + tx.src_proof.root + in + (* ---------- Check the new dst leaf is in the new tree ---------- *) + (* Building new dst leaf *) + let* new_bl_dst = Num.add tx.dst.balance tx.amount in + let* b_new_dst_leaf = + check_merkle_proof + tx.dst.pk + new_bl_dst + tx.dst.cnt + tx.dst_proof.new_path + tx.dst_proof.root + in + + Bool.assert_true b_init_src_leaf + >* (* ---------- Batching merkle proof checks ---------- *) + Num.assert_custom + ~qm:S.one + ~qc:S.mone + (scalar_of_bool b_init_src_leaf) + (scalar_of_bool b_new_src_leaf) + (scalar_of_bool b_new_src_leaf) + >* Num.assert_custom + ~qm:S.one + ~qc:S.mone + (scalar_of_bool b_init_dst_leaf) + (scalar_of_bool b_new_dst_leaf) + (scalar_of_bool b_new_dst_leaf) + (* ---------------------- Check balances ---------------------- *) + (* These checks require that (max_amount + max_fee) and max_balance + be strictly smaller than BLS.order/2 in order to avoid overflows. + That way, if fee is in [0, max_fee), amount is in [0, max_amount) + and we have the precondition that bl_src is in [0, max_balance), + then new_bl_src = bl_src - (fee + amount) cannot fall back + into [0, max_balance) unless we really have bl_src >= (fee + amount). + The last check on new_bl_dst is only necessary to preserve the + invariant that balances are in [0, max_balance), but it is not + necessary in terms of "conservation of money". *) + >* with_bool_check (Num.is_upper_bounded_unsafe ~bound:max_fee tx.fee) + >* with_bool_check + (Num.is_upper_bounded_unsafe ~bound:max_amount tx.amount) + >* with_bool_check + (Num.is_upper_bounded_unsafe ~bound:max_counter tx.src.cnt) + >* with_bool_check + (Num.is_upper_bounded_unsafe ~bound:max_balance new_bl_src) + >* with_bool_check + (Num.is_upper_bounded_unsafe ~bound:max_balance new_bl_dst) + >* + (* Check pk_dst <> gen (used as dummy pk to note closed accounts) *) + (* Checking that the x coordinates of pk_dst and generator are + different is enough as we do not want both points with the + generator x coordinate to be used as public key. *) + let x_pk = of_pair tx.dst.pk |> fst in + let x_g = of_pair generator |> fst in + let* diff = Num.add x_pk ~qr:S.mone x_g in + Num.assert_nonzero diff + >* (* Building signature message *) + let* compressed = + monadic_compress + [ + (tx.src_pos, max_nb_accounts); + (tx.dst_pos, max_nb_accounts); + (tx.fee, max_fee); + (tx.amount, max_amount); + (init_cnt_src, max_counter); + ] + in + let* msg = Hash.digest ~input_length:1 (to_list [compressed]) in + (* Building signature proof *) + let* b_schnorr = + Schnorr.verify + ~compressed:true + ~g:generator + ~msg + ~pk:tx.src.pk + ~signature:tx.signature + () + in + Bool.assert_true b_schnorr >* ret tx.dst_proof.root) + init_root + inputs_rollup + in + ret unit +end + +let benchmark () = + let module Main = Plonk.Main_protocol in + let open Helpers in + let circuit_info = ref None in + let init_state = init_state () in + (* nb_txs is the number of transactions in one circuit *) + let nb_txs = 1 in + (* nb_proofs is the number of proofs to aggregate *) + let nb_proofs = 1 in + let tx_state_lists = + let rec_state = ref init_state in + print_endline "" ; + Time.time + (Printf.sprintf + "Generate %d proofs comprising %d transactions each." + nb_proofs + nb_txs) + @@ fun () -> + List.init nb_proofs (fun _ -> + let start_state = !rec_state in + let txs, end_state = generate_transactions nb_txs start_state in + rec_state := end_state ; + (txs, start_state)) + in + let witness_list, cs_opt, public_input_size = + Time.time "Build witness" @@ fun () -> + List.fold_left + (fun (acc_inputs, _cs, _public_input_size) (txs, state) -> + let cs, circuit, solver = + match !circuit_info with + | None -> + let module E1 = Benchmark (LibCircuit) in + let circuit = E1.make_rollup (Merkle.root state.tree) txs in + let LibCircuit.{cs; solver; _} = + LibCircuit.(get_cs ~optimize:true (circuit ())) + in + circuit_info := Some (cs, circuit, solver) ; + (cs, circuit, solver) + | Some info -> info + in + let witness, public_input_size = + let initial, public_input_size = + LibCircuit.(get_inputs (circuit ())) + in + let private_inputs = Solver.solve solver initial in + (private_inputs, public_input_size) + in + (* We check satisfiability of CS with the witness in case of a wrong erronerous transaction *) + assert (CS.sat cs [] witness) ; + let inputs = Main.{witness; input_commitments = []} in + (inputs :: acc_inputs, Some cs, public_input_size)) + ([], None, 0) + tx_state_lists + in + let cs = Option.get cs_opt in + let msg = + Printf.sprintf + "Transfer circuit for %d transactions on a tree of depth %d.\n\ + Constraints: %i\n" + nb_txs + depth_tree + Array.(concat cs |> length) + in + Printf.fprintf !Helpers.output_buffer "%s" msg ; + print_endline msg ; + let circuit = + Time.time "PlonK convertion" @@ fun () -> + Plonk.Circuit.to_plonk ~public_input_size cs + in + let circuit_map = Plonk.SMap.singleton "" (circuit, nb_proofs) in + let inputs = Plonk.SMap.singleton "" witness_list in + let pp_prv, pp_vrf = + Time.time "Setup" @@ fun () -> + Main.setup ~zero_knowledge:false circuit_map ~srs:Helpers.srs + in + let proof = Time.time "Prove" @@ fun () -> Main.prove pp_prv ~inputs in + let v = + let verifier_inputs = Main.to_verifier_inputs pp_prv inputs in + Time.time "Verify" @@ fun () -> + Main.verify pp_vrf ~inputs:verifier_inputs proof + in + assert v + +let bench = [Alcotest.test_case "Tx benchmark" `Slow benchmark] diff --git a/src/lib_plonk/test_plompiler/dune b/src/lib_plonk/test_plompiler/dune index b0d154178620..d57e0ad7d473 100644 --- a/src/lib_plonk/test_plompiler/dune +++ b/src/lib_plonk/test_plompiler/dune @@ -8,3 +8,47 @@ octez-plonk bls12-381) (modules afl)) + +(executable + (name main) + (libraries + octez-plonk.plonk-test) + (modules + bench_poseidon + benchmark + main + test_anemoi + test_blake + test_core + test_edwards + test_encoding + test_enum + test_input_com + test_linear_algebra + test_lookup + test_merkle + test_merkle_narity + test_optimizer + test_poseidon + test_schnorr + test_serialization + test_weierstrass)) + +(rule + (alias runtest) + (package octez-plonk) + (action + (setenv RANDOM_SEED 42 + (progn (run %{exe:main.exe} -q) (diff? test-quick.expected test.output))))) + +(rule + (alias runtest_slow) + (package octez-plonk) + (action (run %{exe:main.exe}))) + +(rule + (alias runtest_slow_with_regression) + (package octez-plonk) + (action + (setenv RANDOM_SEED 42 + (progn (run %{exe:main.exe}) (diff? test-slow.expected test.output))))) diff --git a/src/lib_plonk/test_plompiler/main.ml b/src/lib_plonk/test_plompiler/main.ml new file mode 100644 index 000000000000..1c0d261438b5 --- /dev/null +++ b/src/lib_plonk/test_plompiler/main.ml @@ -0,0 +1,52 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk_test + +let () = + Helpers.with_seed (fun () -> + Helpers.with_output_to_file (fun () -> + Alcotest.run + "Plompiler" + [ + ("Core", Test_core.tests); + ("Blake", Test_blake.tests); + ("Poseidon", Test_poseidon.tests); + ("Anemoi", Test_anemoi.tests); + ("Enum", Test_enum.tests); + ("Schnorr", Test_schnorr.tests); + ("Merkle", Test_merkle.tests); + ("Merkle N-arity: Plonk integration", Test_merkle_narity.tests); + ("Edwards", Test_edwards.tests); + ("Weierstrass", Test_weierstrass.tests); + ("Serialization", Test_serialization.tests); + ("Lookups", Test_lookup.tests); + ("InputCom", Test_input_com.tests); + ("Linear algebra", Test_linear_algebra.tests); + ("Bench", Benchmark.bench); + ("Bench Poseidon", Bench_poseidon.bench); + ("Optimizer", Test_optimizer.tests); + ("Encoding", Test_encoding.tests); + ])) diff --git a/src/lib_plonk/test_plompiler/test-quick.expected b/src/lib_plonk/test_plompiler/test-quick.expected new file mode 100644 index 000000000000..d36e9a37a24c --- /dev/null +++ b/src/lib_plonk/test_plompiler/test-quick.expected @@ -0,0 +1,2022 @@ +Num.test_add: +Constraints: 2 + +Num.test_add_optimized: +Constraints: 2 + +Num.test_add: +Proof size: 1.63 KB +Proof hash: 85e16c0ed64a9fe63613f111e01ace016b45bdf4e50f5cb00321d03a2b7de0c5 +Prover_pp hash: afe9715188f6e63ed67edc24ea47a64fb6be5383183f71a96189248af03c0acf +Verifier_pp hash: f8517817d47ee0b0e62e79dfb250333421e7f3ac4cabbce8bd7bf9ff20553cae + +Num.test_add: +Constraints: 2 + +Num.test_add_optimized: +Constraints: 2 + +Num.test_add: +Proof size: 1.63 KB +Proof hash: ce0a27ae5e0378251dc173581487d5bdc27f7fc047c87bd02e4b330199755af7 +Prover_pp hash: afe9715188f6e63ed67edc24ea47a64fb6be5383183f71a96189248af03c0acf +Verifier_pp hash: f8517817d47ee0b0e62e79dfb250333421e7f3ac4cabbce8bd7bf9ff20553cae + +Num.test_add_constant: +Constraints: 2 + +Num.test_add_constant_optimized: +Constraints: 2 + +Num.test_add_constant: +Proof size: 1.81 KB +Proof hash: ec868d91d8e3fa177464cf6b8cea42dbe7aee29c6605931001d9706ff2ccc330 +Prover_pp hash: f6057c00c9ec1a6d142a3327bc1dda783920a291dbaeb97e1ced0d6b7cfc20b0 +Verifier_pp hash: 1534cd157f632796472596f3aa9e32f8ba78d5959bd689f4236add5eeda2e0fa + +Num.test_add_constant: +Constraints: 2 + +Num.test_add_constant_optimized: +Constraints: 2 + +Num.test_add_constant: +Proof size: 1.76 KB +Proof hash: a498db19775f6c0de8be271747add3b67917087bc7e1ac17837f4b31391a4d2a +Prover_pp hash: 8c8718675aa8d6ed8485aed37649c4374475078cdd51e4f59c7b2518d8d28161 +Verifier_pp hash: 08e72ab8888a03e5056b2d06b0f9642dd68c7682e5cedd74a8fdcc1e43e501ea + +Num.test_sub: +Constraints: 2 + +Num.test_sub_optimized: +Constraints: 2 + +Num.test_sub: +Proof size: 1.63 KB +Proof hash: c5cedfe84da41f72110b4225397811f49cdc126ae68c80fa1fdbcce0185d272b +Prover_pp hash: 1a653171195cf30b7a7fd68c6cc78153af28405e53dd140e863fe88f0d0536f2 +Verifier_pp hash: a6c48586e1b42d8e04c71b60e2c7fda1a1a62c3a8357655e274c524a0b7078d8 + +Num.test_sub: +Constraints: 2 + +Num.test_sub_optimized: +Constraints: 2 + +Num.test_sub: +Proof size: 1.63 KB +Proof hash: 6f5fc69fe49871f57290d48512d0e2b62e14d45ef215582c4c4c60ef1e341d03 +Prover_pp hash: 1a653171195cf30b7a7fd68c6cc78153af28405e53dd140e863fe88f0d0536f2 +Verifier_pp hash: a6c48586e1b42d8e04c71b60e2c7fda1a1a62c3a8357655e274c524a0b7078d8 + +Num.test_mul: +Constraints: 2 + +Num.test_mul_optimized: +Constraints: 2 + +Num.test_mul: +Proof size: 1.67 KB +Proof hash: f18c7bb6862d4681aea12132c7c1f6cd9e4f77a6efb4261611678d1579e4a84c +Prover_pp hash: 94a7d8e8e8d1b7fc89e4fa6fc80ae2c8a266e1d9e75892a9f90a8d3fd326df01 +Verifier_pp hash: b95acc448a4e379e6cefb0004946facd093d36aec84cdd9492b285e2fbc99c17 + +Num.test_mul: +Constraints: 2 + +Num.test_mul_optimized: +Constraints: 2 + +Num.test_mul: +Proof size: 1.67 KB +Proof hash: d2174fd539bd7108f614149ba4d85895f532c3ad517482a6d23737902f2c492e +Prover_pp hash: 94a7d8e8e8d1b7fc89e4fa6fc80ae2c8a266e1d9e75892a9f90a8d3fd326df01 +Verifier_pp hash: b95acc448a4e379e6cefb0004946facd093d36aec84cdd9492b285e2fbc99c17 + +Num.test_mul: +Constraints: 2 + +Num.test_mul_optimized: +Constraints: 2 + +Num.test_mul: +Proof size: 1.67 KB +Proof hash: 4c4ce11afa65a8ddaaaf7a5ddb5be17c11425a58ca0f8817eee1b16edfff84e8 +Prover_pp hash: 94a7d8e8e8d1b7fc89e4fa6fc80ae2c8a266e1d9e75892a9f90a8d3fd326df01 +Verifier_pp hash: b95acc448a4e379e6cefb0004946facd093d36aec84cdd9492b285e2fbc99c17 + +Num.test_num: +Constraints: 6 + +Num.test_num_optimized: +Constraints: 5 + +Num.test_num: +Proof size: 1.72 KB +Proof hash: 68640a9fc65938eeb50bd9f8007bb17a2b0169f78972698931ff09fac3a6fee1 +Prover_pp hash: e98c39f2e0332f9694981e0b822dd08053a6695e78562e07159d456e884cfd45 +Verifier_pp hash: 0f25184e6cfeb7c04c90d774e094c885c02f1a620a7a31f82f427222845468e5 + +Num.test_div: +Constraints: 3 + +Num.test_div_optimized: +Constraints: 2 + +Num.test_div: +Proof size: 1.67 KB +Proof hash: f5933f9b10164a9d2735f7c2b8e98e8c5dc283c82ea86b0b00f0d9070246030d +Prover_pp hash: 8a932f11ab16b1e93ae0bd3361be8a766913de00cd0a0e803fda4839399f05cd +Verifier_pp hash: 8f2ce6e871ed5fa40416505443cbb18498976aeec35a35e72c3a03fc4cc479f7 + +pow5: +Constraints: 2 + +pow5_optimized: +Constraints: 2 + +pow5: +Proof size: 1.50 KB +Proof hash: c3289ce7ab7bfe57a1e248cea97b612838a6e6354494059dfeeb19fd49e3595d +Prover_pp hash: f8a76297dec2315d71110cbd2b1d0ac5e184c59ba3a10ec58b4f6d27a9106860 +Verifier_pp hash: 5ce84da57f613e4f8a9dcd0f98bf91693d9f70310c7698a47ff275007147b9d5 + +test: +Constraints: 2 + +test_optimized: +Constraints: 2 + +test: +Proof size: 1.50 KB +Proof hash: d88b3c663c11a2477a84a92544d29dc72eed33e9d3f2552534979fa83e07b45c +Prover_pp hash: e43c7bf0d23c4806451cdc65ff14d525fd8e7dffea445590d22493044fe1f7f2 +Verifier_pp hash: 833b1544014b4f91cfce28c0ca5c0c0d639181fa8cd20e5b003eeb8eeca5e141 + +test: +Constraints: 2 + +test_optimized: +Constraints: 2 + +test: +Proof size: 1.50 KB +Proof hash: e911139cffc5c61f3b54ab875ffa5cf7f5b0d9155c75bb7b7bfe645c22011540 +Prover_pp hash: e43c7bf0d23c4806451cdc65ff14d525fd8e7dffea445590d22493044fe1f7f2 +Verifier_pp hash: 833b1544014b4f91cfce28c0ca5c0c0d639181fa8cd20e5b003eeb8eeca5e141 + +test: +Constraints: 2 + +test_optimized: +Constraints: 2 + +test: +Proof size: 1.50 KB +Proof hash: 36d321c07f4f7d24e00728308d66d1b74600a73f274f2afc68d6707c504dc2ee +Prover_pp hash: e43c7bf0d23c4806451cdc65ff14d525fd8e7dffea445590d22493044fe1f7f2 +Verifier_pp hash: 833b1544014b4f91cfce28c0ca5c0c0d639181fa8cd20e5b003eeb8eeca5e141 + +pow: +Constraints: 6 + +pow_optimized: +Constraints: 4 + +pow: +Proof size: 1.57 KB +Proof hash: 69587cf09d51a8dd05888a5c6bba5cfc7aefbe195db9e6783374efdad07c992e +Prover_pp hash: 9abf08eb2008a730f19bf6e7a531bf21cd014cf8c97e933fa53cdcc0c893be58 +Verifier_pp hash: 02b7dfd055019176a84b03ec4d82a274dd14b9b571f89937af039bfd175d193f + +pow: +Constraints: 6 + +pow_optimized: +Constraints: 4 + +pow: +Proof size: 1.57 KB +Proof hash: db8311e57b9783cb6f70a525465ab43d2edc49312d4c97eaa44d9bbf31f487a3 +Prover_pp hash: 9abf08eb2008a730f19bf6e7a531bf21cd014cf8c97e933fa53cdcc0c893be58 +Verifier_pp hash: 02b7dfd055019176a84b03ec4d82a274dd14b9b571f89937af039bfd175d193f + +pow: +Constraints: 10 + +pow_optimized: +Constraints: 7 + +pow: +Proof size: 1.57 KB +Proof hash: bf47f0b65fe6f644e0fe1494a02436bda18f1ea36ea6f5c789b02583e130cafe +Prover_pp hash: df21f172b9fc4e58bec21dcf8483a0f5feffc832520ab4bfdd07eca2b4b8f033 +Verifier_pp hash: 28773d9d023c131bf6eaf1f40eb3a85d22aff56b27eefa68296550d478003c39 + +pow: +Constraints: 10 + +pow_optimized: +Constraints: 7 + +pow: +Proof size: 1.57 KB +Proof hash: 40d7440fb584b82d67852f36d4b18f68ec095b18f74a418d07e0bb16d27b0e68 +Prover_pp hash: df21f172b9fc4e58bec21dcf8483a0f5feffc832520ab4bfdd07eca2b4b8f033 +Verifier_pp hash: 28773d9d023c131bf6eaf1f40eb3a85d22aff56b27eefa68296550d478003c39 + +pow: +Constraints: 18 + +pow_optimized: +Constraints: 13 + +pow: +Proof size: 1.57 KB +Proof hash: 510b66a1d61e748f043e9a28917c11d27b200a835ba20fc4b0dc3a0e2418c76c +Prover_pp hash: 980825832ea7639088e37b04c8fd4cdf7bbdc389b5e1b201084ce27c6c4816f0 +Verifier_pp hash: 5a6ec5d2fea585ba27eae6755d4a25843d1924b81f4f016115778a5ae9bdc96d + +pow: +Constraints: 26 + +pow_optimized: +Constraints: 19 + +pow: +Proof size: 1.57 KB +Proof hash: 56d360b300cac396f4ecee3b8038610179c0ef85e8ba69a724911e64bfa04019 +Prover_pp hash: 66e87989961c4ed3d4608a328928f923318b0418c998b72b7d1d34443d236b6e +Verifier_pp hash: fe373d1967d1eb397ca22922c6bd98fe92d3097e9e7d74d695c361d6d995bfb3 + +pow: +Constraints: 14 + +pow_optimized: +Constraints: 10 + +pow: +Proof size: 1.57 KB +Proof hash: 1849cdddeb2ac1d5d46c9859b50bd10f25936fa405c11362e482c5568f032864 +Prover_pp hash: 873c5c51118bc6e9db3a8db218cfaeb83b06a2301daf8588a3a3907e4cb33eb9 +Verifier_pp hash: e9d71a7fa9dae5910c1cca6b3de08eab782b1b9115f560f451bfcfe826bc6007 + +Num.test_equal: +Constraints: 1 + +Num.test_equal_optimized: +Constraints: 1 + +Num.test_equal: +Proof size: 1.62 KB +Proof hash: b1a397112aba6b974e922acf00cebe528a5fd7c564d40efd978248eb1a16ee2e +Prover_pp hash: 1eb0d7651ec0d512c8557829903e60a7cc3b0730fc35d4a172e8c6ed0003a430 +Verifier_pp hash: 565093938a315a50c170ff52a90af08c2eeda13189f122390673efadf3103fe2 + +Num.bits_of_scalar: +Constraints: 15 + +Num.bits_of_scalar_optimized: +Constraints: 6 + +Num.bits_of_scalar: +Proof size: 2.28 KB +Proof hash: 88053d72718cd6232a3fc13a232adad225360d328d9c8458c06772c85ecaf5d3 +Prover_pp hash: 60e3293a6382268863af02a004d3615544895fa012f922903ccdfae025a3b95a +Verifier_pp hash: 8f6207020a798cfceb0a16dd6ce94bac3d69f7112755b8ac73bc782a0635397f + +Num.bits_of_scalar: +Constraints: 15 + +Num.bits_of_scalar_optimized: +Constraints: 6 + +Num.bits_of_scalar: +Proof size: 2.28 KB +Proof hash: 0426f8765426ff7cb75885546fc9fdd2464594cb6f919988f89e437c901e99a4 +Prover_pp hash: c7c9a63e46ac62379007198b94e91f73df451247ea655dddd852ee6e8844bc8e +Verifier_pp hash: 6f5df870d295ea1481821e04178a358c07fbb3268d1d77a81e329726b3ef7c56 + +Num.is_upper_bounded: +Constraints: 8 + +Num.is_upper_bounded_optimized: +Constraints: 5 + +Num.is_upper_bounded: +Proof size: 1.96 KB +Proof hash: be481d22fd515ce6b30ed0f8301d0786b296573fa32c3293273991cb10692b22 +Prover_pp hash: 6d39ca9e157e5d4b6c555ba50fe358ffa0ee8a7d476ee37430f4abf9f3c3d8b4 +Verifier_pp hash: ba37fd84456c67d7537f93663c6b22645e1b81e3128330049c21c2911e3beec9 + +Num.is_upper_bounded: +Constraints: 14 + +Num.is_upper_bounded_optimized: +Constraints: 8 + +Num.is_upper_bounded: +Proof size: 2.01 KB +Proof hash: 16da0bdc4a70877739f97d16ce7e42e0987d3922cd6bc760b86010ccf3a28f98 +Prover_pp hash: a130bd3468df011564041cff448b5027dbed9643a339c789ca4b76309326ba29 +Verifier_pp hash: e6089004da03cb7bbd4003eee4947b1428706de4e8292698f5fe3fe13ebd7fdb + +Num.is_upper_bounded: +Constraints: 26 + +Num.is_upper_bounded_optimized: +Constraints: 12 + +Num.is_upper_bounded: +Proof size: 2.51 KB +Proof hash: 838e3ddbb1ceb90868da26ef81148c182ddf23960d24c96710d610d80896dc05 +Prover_pp hash: a7312bd9501fbec613cf911ee4efb552abe425aa58122370d6603ef6de3838cf +Verifier_pp hash: e19cc5c6464cd1230aee8be9a1bf996148a29320d2da9eeb1a425f65595f20ad + +Num.is_upper_bounded: +Constraints: 738 + +Num.is_upper_bounded_optimized: +Constraints: 318 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: 90fac996883a297f73bf486bcc96a81beabce68b8779da8b67417365c347df05 +Prover_pp hash: 51c0698dba103c63adcd7ffa05d42512ab5470b819d3c063847488980099fbbd +Verifier_pp hash: 811db672733a18fe20cd61c10384ecf5119208f55334ee29d3d8046b9db273ba + +Num.is_upper_bounded: +Constraints: 8 + +Num.is_upper_bounded_optimized: +Constraints: 5 + +Num.is_upper_bounded: +Proof size: 1.96 KB +Proof hash: be481d22fd515ce6b30ed0f8301d0786b296573fa32c3293273991cb10692b22 +Prover_pp hash: 6d39ca9e157e5d4b6c555ba50fe358ffa0ee8a7d476ee37430f4abf9f3c3d8b4 +Verifier_pp hash: ba37fd84456c67d7537f93663c6b22645e1b81e3128330049c21c2911e3beec9 + +Num.is_upper_bounded: +Constraints: 735 + +Num.is_upper_bounded_optimized: +Constraints: 315 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: ee10a5c1aa5ff107f7ae5515baf268d2eec17d2510c3c6fb75db600e55d5ea60 +Prover_pp hash: 0fd0be85a86673ec30a5235c5851f1d9d5273d46bbd691f59284b52704ecf6a0 +Verifier_pp hash: cd33f2b2e1f676d6f3f0ff79be4d4d8c40a7bfdb814d4423813c443daccbcf71 + +Num.is_upper_bounded: +Constraints: 765 + +Num.is_upper_bounded_optimized: +Constraints: 319 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: 1ce19d1dc4b2ebe5a0a0322b96c19f87c96c0514d7d3ffcf660a308ae870bd54 +Prover_pp hash: 76e7ea755b8926ce2feaa3b8b2486e6feaa177df545a466d45f24694d1058d02 +Verifier_pp hash: f8521807392d2444baf7528a59799ac13de030099ee1b1e880584d4f06324494 + +Num.is_upper_bounded: +Constraints: 765 + +Num.is_upper_bounded_optimized: +Constraints: 319 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: 9a6df0e245241b36935c6c3bebafd1936f6d12f0b68ee8552046541f3cf36e26 +Prover_pp hash: 5f8710ed59dbc2e7ac3637bfbdd494698f5667153418a249a7f0a0a0e11b320e +Verifier_pp hash: 76390f7ed449bf73d3a0159f6c5b4f2d0c4c2773b84231b2c4b693a2a0e72881 + +Num.is_upper_bounded: +Constraints: 767 + +Num.is_upper_bounded_optimized: +Constraints: 319 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: 8c8d2986d9c3146986fa950fe8baecfceee7a069ffe93ec99b2cd5970453a3d1 +Prover_pp hash: c7c4a30caae6d0e60cff0de2916a5c4239f0f038385d96527160de27db5cf025 +Verifier_pp hash: 85ba29546ce1cec963aff514560ca995fe9f3d357de003319c565313891586e0 + +Num.is_upper_bounded: +Constraints: 735 + +Num.is_upper_bounded_optimized: +Constraints: 315 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: ee10a5c1aa5ff107f7ae5515baf268d2eec17d2510c3c6fb75db600e55d5ea60 +Prover_pp hash: 0fd0be85a86673ec30a5235c5851f1d9d5273d46bbd691f59284b52704ecf6a0 +Verifier_pp hash: cd33f2b2e1f676d6f3f0ff79be4d4d8c40a7bfdb814d4423813c443daccbcf71 + +Num.is_upper_bounded_totality: +Constraints: 764 + +Num.is_upper_bounded_totality_optimized: +Constraints: 318 + +Num.is_upper_bounded_totality: +Proof size: 2.93 KB +Proof hash: 66119d5cbc950d83506ffcc5f5b5e800c97f8dce1bdedb1cf14a1b94054e065b +Prover_pp hash: 7b3520fead146b322d3cdfb9b9d04661e2c1db8210fdc3e44f37428ebe2d992f +Verifier_pp hash: 484c9409f3aa70a055ca69ec365bf637b81da41bba34a8d1f1beeb43c601d3c9 + +Num.is_upper_bounded_totality: +Constraints: 734 + +Num.is_upper_bounded_totality_optimized: +Constraints: 314 + +Num.is_upper_bounded_totality: +Proof size: 2.93 KB +Proof hash: eb8022d740cf0adcb4146bbd364bbddc0b59929006cf065336f3c27d1794cf8e +Prover_pp hash: e6b3598760ed140aebf7a092348a5126c38a88b9d139c5800c02dd0869ea3be5 +Verifier_pp hash: 857a076a1ed88dd0b4690a436e64310fcd358876aec0390a880a4f4333046915 + +Num.is_upper_bounded_totality: +Constraints: 766 + +Num.is_upper_bounded_totality_optimized: +Constraints: 318 + +Num.is_upper_bounded_totality: +Proof size: 2.93 KB +Proof hash: ee6fe50cb3ec3ad7b7a8bac4ad8e46023aecb6c7756330943f460d628937512e +Prover_pp hash: a14fb739056e1d383bf9ef274b4a730d72da7600f8abe7fdfa912cf6ae4546c4 +Verifier_pp hash: 50964f40089fa6b1335ae0389d7ab3df1855f59c38f0572cef5c26cb2b7d4cdf + +Num.geq: +Constraints: 25 + +Num.geq_optimized: +Constraints: 11 + +Num.geq: +Proof size: 2.12 KB +Proof hash: 5b8aab4e83ca35b9ccf00974033fe5da48ffe7a2714883fab718ce07690cc9ac +Prover_pp hash: d8fb40d7281e3d1c0aac862ebd180ed57dee2d6d668711128c67a781a87dc389 +Verifier_pp hash: 882c9e2a3214f746600528d4ea54e5e2ac9232478c691f277bd9e855c45b8383 + +Num.geq: +Constraints: 22 + +Num.geq_optimized: +Constraints: 10 + +Num.geq: +Proof size: 2.08 KB +Proof hash: d996e387080f62f96b50bc1c198e6ed3c5f7c2f39b339eb415743639d9d1f661 +Prover_pp hash: e52fd5334e230c262ea4dc950e7940705ca2bd22c3977078da84f8987a146fb5 +Verifier_pp hash: 18e90a9cee80b110b1f6789f8630730392aa5039c2c43004ec163bd650427ccc + +Num.test_add: +Constraints: 2 + +Num.test_add_optimized: +Constraints: 2 + +Num.test_add: +Constraints: 2 + +Num.test_add_optimized: +Constraints: 2 + +Num.test_add_constant: +Constraints: 2 + +Num.test_add_constant_optimized: +Constraints: 2 + +Num.test_add_constant: +Constraints: 2 + +Num.test_add_constant_optimized: +Constraints: 2 + +Num.test_sub: +Constraints: 2 + +Num.test_sub_optimized: +Constraints: 2 + +Num.test_sub: +Constraints: 2 + +Num.test_sub_optimized: +Constraints: 2 + +Num.test_mul: +Constraints: 2 + +Num.test_mul_optimized: +Constraints: 2 + +Num.test_mul: +Constraints: 2 + +Num.test_mul_optimized: +Constraints: 2 + +Num.test_mul: +Constraints: 2 + +Num.test_mul_optimized: +Constraints: 2 + +Num.test_num: +Constraints: 6 + +Num.test_num_optimized: +Constraints: 5 + +Num.test_div: +Constraints: 3 + +Num.test_div_optimized: +Constraints: 2 + +pow5: +Constraints: 2 + +pow5_optimized: +Constraints: 2 + +test: +Constraints: 2 + +test_optimized: +Constraints: 2 + +test: +Constraints: 2 + +test_optimized: +Constraints: 2 + +test: +Constraints: 2 + +test_optimized: +Constraints: 2 + +pow: +Constraints: 6 + +pow_optimized: +Constraints: 4 + +pow: +Constraints: 6 + +pow_optimized: +Constraints: 4 + +pow: +Constraints: 10 + +pow_optimized: +Constraints: 7 + +pow: +Constraints: 10 + +pow_optimized: +Constraints: 7 + +pow: +Constraints: 18 + +pow_optimized: +Constraints: 13 + +pow: +Constraints: 26 + +pow_optimized: +Constraints: 19 + +pow: +Constraints: 14 + +pow_optimized: +Constraints: 10 + +Num.test_equal: +Constraints: 1 + +Num.test_equal_optimized: +Constraints: 1 + +Num.bits_of_scalar: +Constraints: 15 + +Num.bits_of_scalar_optimized: +Constraints: 6 + +Num.bits_of_scalar: +Constraints: 15 + +Num.bits_of_scalar_optimized: +Constraints: 6 + +Num.is_upper_bounded: +Constraints: 8 + +Num.is_upper_bounded_optimized: +Constraints: 5 + +Num.is_upper_bounded: +Constraints: 14 + +Num.is_upper_bounded_optimized: +Constraints: 8 + +Num.is_upper_bounded: +Constraints: 26 + +Num.is_upper_bounded_optimized: +Constraints: 12 + +Num.is_upper_bounded: +Constraints: 738 + +Num.is_upper_bounded_optimized: +Constraints: 318 + +Num.is_upper_bounded: +Constraints: 8 + +Num.is_upper_bounded_optimized: +Constraints: 5 + +Num.is_upper_bounded: +Constraints: 735 + +Num.is_upper_bounded_optimized: +Constraints: 315 + +Num.is_upper_bounded: +Constraints: 765 + +Num.is_upper_bounded_optimized: +Constraints: 319 + +Num.is_upper_bounded: +Constraints: 765 + +Num.is_upper_bounded_optimized: +Constraints: 319 + +Num.is_upper_bounded: +Constraints: 767 + +Num.is_upper_bounded_optimized: +Constraints: 319 + +Num.is_upper_bounded: +Constraints: 735 + +Num.is_upper_bounded_optimized: +Constraints: 315 + +Num.is_upper_bounded_totality: +Constraints: 764 + +Num.is_upper_bounded_totality_optimized: +Constraints: 318 + +Num.is_upper_bounded_totality: +Constraints: 734 + +Num.is_upper_bounded_totality_optimized: +Constraints: 314 + +Num.is_upper_bounded_totality: +Constraints: 766 + +Num.is_upper_bounded_totality_optimized: +Constraints: 318 + +Num.geq: +Constraints: 25 + +Num.geq_optimized: +Constraints: 11 + +Num.geq: +Constraints: 22 + +Num.geq_optimized: +Constraints: 10 + +Bool.test_assert_true_and_false: +Constraints: 2 + +Bool.test_assert_true_and_false_optimized: +Constraints: 1 + +Bool.test_assert_true_and_false: +Constraints: 2 + +Bool.test_assert_true_and_false_optimized: +Constraints: 1 + +Bool.test_equal: +Constraints: 3 + +Bool.test_equal_optimized: +Constraints: 2 + +Bool.test_is_zero: +Constraints: 4 + +Bool.test_is_zero_optimized: +Constraints: 3 + +Bool.test_is_not_zero: +Constraints: 4 + +Bool.test_is_not_zero_optimized: +Constraints: 3 + +Bool.test_assert_bool: +Constraints: 1 + +Bool.test_assert_bool_optimized: +Constraints: 1 + +Bool.test_assert_bool: +Constraints: 1 + +Bool.test_assert_bool_optimized: +Constraints: 1 + +Bool.test_band: +Constraints: 5 + +Bool.test_band_optimized: +Constraints: 4 + +Bool.test_band: +Constraints: 5 + +Bool.test_band_optimized: +Constraints: 4 + +Bool.test_band: +Constraints: 5 + +Bool.test_band_optimized: +Constraints: 4 + +Bool.test_band: +Constraints: 5 + +Bool.test_band_optimized: +Constraints: 4 + +Bool.test_xor: +Constraints: 5 + +Bool.test_xor_optimized: +Constraints: 4 + +Bool.test_xor: +Constraints: 5 + +Bool.test_xor_optimized: +Constraints: 4 + +Bool.test_xor: +Constraints: 5 + +Bool.test_xor_optimized: +Constraints: 4 + +Bool.test_xor: +Constraints: 5 + +Bool.test_xor_optimized: +Constraints: 4 + +Bool.test_bor: +Constraints: 5 + +Bool.test_bor_optimized: +Constraints: 4 + +Bool.test_bor: +Constraints: 5 + +Bool.test_bor_optimized: +Constraints: 4 + +Bool.test_bor: +Constraints: 5 + +Bool.test_bor_optimized: +Constraints: 4 + +Bool.test_bor: +Constraints: 5 + +Bool.test_bor_optimized: +Constraints: 4 + +Bool.test_bnot: +Constraints: 4 + +Bool.test_bnot_optimized: +Constraints: 3 + +Bool.test_bnot: +Constraints: 4 + +Bool.test_bnot_optimized: +Constraints: 3 + +Bool.test_ifthenelse: +Constraints: 3 + +Bool.test_ifthenelse_optimized: +Constraints: 1 + +Bool.test_ifthenelse: +Constraints: 3 + +Bool.test_ifthenelse_optimized: +Constraints: 1 + +Bool.test_ifthenelse: +Constraints: 6 + +Bool.test_ifthenelse_optimized: +Constraints: 4 + +Bool.test_ifthenelse: +Constraints: 6 + +Bool.test_ifthenelse_optimized: +Constraints: 4 + +Bool.test_ifthenelse: +Constraints: 5 + +Bool.test_ifthenelse_optimized: +Constraints: 2 + +Bool.test_ifthenelse: +Constraints: 5 + +Bool.test_ifthenelse_optimized: +Constraints: 2 + +Bool.test_ifthenelse: +Constraints: 5 + +Bool.test_ifthenelse_optimized: +Constraints: 2 + +Bool.test_ifthenelse: +Constraints: 5 + +Bool.test_ifthenelse_optimized: +Constraints: 2 + +Bool.test_swap: +Constraints: 4 + +Bool.test_swap_optimized: +Constraints: 2 + +Bool.test_swap: +Constraints: 4 + +Bool.test_swap_optimized: +Constraints: 2 + +Bool.test_swap: +Constraints: 8 + +Bool.test_swap_optimized: +Constraints: 5 + +Bool.test_swap: +Constraints: 8 + +Bool.test_swap_optimized: +Constraints: 5 + +Bool.test_swap: +Constraints: 7 + +Bool.test_swap_optimized: +Constraints: 3 + +Bool.test_swap: +Constraints: 7 + +Bool.test_swap_optimized: +Constraints: 3 + +Bool.test_swap: +Constraints: 7 + +Bool.test_swap_optimized: +Constraints: 3 + +Bool.test_swap: +Constraints: 7 + +Bool.test_swap_optimized: +Constraints: 3 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +List.test_add_list: +Constraints: 5 + +List.test_add_list_optimized: +Constraints: 2 + +List.test_add_list: +Constraints: 6 + +List.test_add_list_optimized: +Constraints: 2 + +List.test_equal: +Constraints: 2 + +List.test_equal_optimized: +Constraints: 2 + +List.test_hd: +Constraints: 1 + +List.test_hd_optimized: +Constraints: 1 + +List.test_mul_list: +Constraints: 4 + +List.test_mul_list_optimized: +Constraints: 3 + +List.test_mul_list: +Constraints: 5 + +List.test_mul_list_optimized: +Constraints: 4 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_scalar_of_bytes: +Constraints: 82 + +Rest.test_scalar_of_bytes_optimized: +Constraints: 45 + +Tuple.test_equal: +Constraints: 2 + +Tuple.test_equal_optimized: +Constraints: 2 + +Tuple.test_point: +Constraints: 4 + +Tuple.test_point_optimized: +Constraints: 3 + +ECC.test_weierstrass_add: +Constraints: 12 + +ECC.test_weierstrass_add_optimized: +Constraints: 11 + +ECC.test_edwards_add: +Constraints: 12 + +ECC.test_edwards_add_optimized: +Constraints: 11 + +Bytes.test_add: +Constraints: 69 + +Bytes.test_add_optimized: +Constraints: 54 + +Bytes.test_xor: +Constraints: 40 + +Bytes.test_xor_optimized: +Constraints: 25 + +Bytes.blake: +Constraints: 160 + +Bytes.blake_optimized: +Constraints: 97 + +Bytes.test_ifthenelse: +Constraints: 41 + +Bytes.test_ifthenelse_optimized: +Constraints: 32 + +Bytes.test_ifthenelse: +Constraints: 41 + +Bytes.test_ifthenelse_optimized: +Constraints: 32 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Blake.test_mixing: +Constraints: 2638 + +Blake.test_mixing_optimized: +Constraints: 1998 + +Blake.test_compression: +Constraints: 87808 + +Blake.test_compression_optimized: +Constraints: 87264 + +Blake.test_blake2s: +Constraints: 174377 + +Blake.test_blake2s_optimized: +Constraints: 174089 + +Poseidon.test_poseidon: +Constraints: 273 + +Poseidon.test_poseidon_optimized: +Constraints: 118 + +Poseidon.test_poseidon: +Constraints: 804 + +Poseidon.test_poseidon_optimized: +Constraints: 340 + +Poseidon.test_poseidon.fixed_length: +Constraints: 273 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 118 + +Poseidon.test_poseidon.fixed_length: +Constraints: 539 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 229 + +Poseidon.test_poseidon: +Constraints: 975 + +Poseidon.test_poseidon_optimized: +Constraints: 298 + +Poseidon.test_poseidon: +Constraints: 1991 + +Poseidon.test_poseidon_optimized: +Constraints: 603 + +Poseidon.test_poseidon.fixed_length: +Constraints: 975 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 298 + +Poseidon.test_poseidon.fixed_length: +Constraints: 991 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 304 + +Poseidon.test_poseidon: +Constraints: 611 + +Poseidon.test_poseidon_optimized: +Constraints: 190 + +Poseidon.test_poseidon: +Constraints: 1818 + +Poseidon.test_poseidon_optimized: +Constraints: 556 + +Poseidon.test_poseidon.fixed_length: +Constraints: 611 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 190 + +Poseidon.test_poseidon.fixed_length: +Constraints: 1215 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 373 + +Anemoi.test_round.valid: +Constraints: 20 + +Anemoi.test_round.valid_optimized: +Constraints: 18 + +Anemoi.test_round.valid: +Constraints: 20 + +Anemoi.test_round.valid_optimized: +Constraints: 18 + +Anemoi.test_compress.valid: +Constraints: 90 + +Anemoi.test_compress.valid_optimized: +Constraints: 85 + +Anemoi.test_compress.valid: +Constraints: 90 + +Anemoi.test_compress.valid_optimized: +Constraints: 85 + +Anemoi.test_double_round.valid: +Constraints: 21 + +Anemoi.test_double_round.valid_optimized: +Constraints: 19 + +Anemoi.test_double_round.valid: +Constraints: 21 + +Anemoi.test_double_round.valid_optimized: +Constraints: 19 + +Anemoi.test_compress_two.valid: +Constraints: 63 + +Anemoi.test_compress_two.valid_optimized: +Constraints: 58 + +Anemoi.test_compress_two.valid: +Constraints: 63 + +Anemoi.test_compress_two.valid_optimized: +Constraints: 58 + +Anemoi.test_compress.valid: +Constraints: 32 + +Anemoi.test_compress.valid_optimized: +Constraints: 17 + +Anemoi.test_compress.valid: +Constraints: 78 + +Anemoi.test_compress.valid_optimized: +Constraints: 39 + +Enum.test_switch: +Constraints: 16 + +Enum.test_switch_optimized: +Constraints: 12 + +Enum.test_switch: +Constraints: 16 + +Enum.test_switch_optimized: +Constraints: 12 + +Enum.test_switch: +Constraints: 16 + +Enum.test_switch_optimized: +Constraints: 12 + +Enum.test_switch: +Constraints: 16 + +Enum.test_switch_optimized: +Constraints: 12 + +Enum.test_switch: +Constraints: 16 + +Enum.test_switch_optimized: +Constraints: 12 + +Schnorr.test_circuit_verify: +Constraints: 2381 + +Schnorr.test_circuit_verify_optimized: +Constraints: 881 + +Merkle.test_merkle_pos: +Constraints: 1945 + +Merkle.test_merkle_pos_optimized: +Constraints: 593 + +Merkle.test_merkle_pos: +Constraints: 1945 + +Merkle.test_merkle_pos_optimized: +Constraints: 593 + +Merkle.test_merkle_pos: +Constraints: 1945 + +Merkle.test_merkle_pos_optimized: +Constraints: 593 + +Merkle.test_merkle_pos: +Constraints: 1945 + +Merkle.test_merkle_pos_optimized: +Constraints: 593 + +MerkleNarity.test_merkle_pos: +Constraints: 5030 + +MerkleNarity.test_merkle_pos_optimized: +Constraints: 1604 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_scalar_mul: +Constraints: 6 + +Edwards.test_scalar_mul_optimized: +Constraints: 3 + +Edwards.test_scalar_mul: +Constraints: 6 + +Edwards.test_scalar_mul_optimized: +Constraints: 3 + +Edwards.test_scalar_mul: +Constraints: 11 + +Edwards.test_scalar_mul_optimized: +Constraints: 5 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_multi_scalar_mul: +Constraints: 2033 + +Edwards.test_multi_scalar_mul_optimized: +Constraints: 763 + +Edwards.test_multi_scalar_mul: +Constraints: 2795 + +Edwards.test_multi_scalar_mul_optimized: +Constraints: 1017 + +Edwards.test_multi_scalar_mul: +Constraints: 3557 + +Edwards.test_multi_scalar_mul_optimized: +Constraints: 1271 + +Edwards.test_multi_scalar_mul: +Constraints: 4319 + +Edwards.test_multi_scalar_mul_optimized: +Constraints: 1525 + +Edwards.test_multi_scalar_mul: +Constraints: 5081 + +Edwards.test_multi_scalar_mul_optimized: +Constraints: 1779 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_scalar_mul: +Constraints: 4067 + +Weierstrass.test_scalar_mul_optimized: +Constraints: 3810 + +Weierstrass.test_scalar_mul: +Constraints: 4067 + +Weierstrass.test_scalar_mul_optimized: +Constraints: 3810 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Bool.test_bor_lookup: +Constraints: 7 + +Bool.test_bor_lookup_optimized: +Constraints: 5 + +Bool.test_bor_lookup: +Constraints: 7 + +Bool.test_bor_lookup_optimized: +Constraints: 5 + +Bool.test_bor_lookup: +Constraints: 7 + +Bool.test_bor_lookup_optimized: +Constraints: 5 + +Bool.test_bor_lookup: +Constraints: 7 + +Bool.test_bor_lookup_optimized: +Constraints: 5 + +Optimizer.test_long_sum: +Constraints: 100 + +Optimizer.test_long_sum_optimized: +Constraints: 26 + +Optimizer.test_long_sum: +Constraints: 500 + +Optimizer.test_long_sum_optimized: +Constraints: 126 + +Optimizer.test_poseidon_rounds: +Constraints: 11 + +Optimizer.test_poseidon_rounds_optimized: +Constraints: 5 + +Optimizer.test_ecc_ed_cond_add: +Constraints: 12 + +Optimizer.test_ecc_ed_cond_add_optimized: +Constraints: 5 + +Encoding.test_foo: +Constraints: 8 + +Encoding.test_foo_optimized: +Constraints: 7 + +Encoding.test_assertion: +Constraints: 4 + +Encoding.test_assertion_optimized: +Constraints: 3 + diff --git a/src/lib_plonk/test_plompiler/test-slow.expected b/src/lib_plonk/test_plompiler/test-slow.expected new file mode 100644 index 000000000000..832f2146e39f --- /dev/null +++ b/src/lib_plonk/test_plompiler/test-slow.expected @@ -0,0 +1,5108 @@ +Num.test_add: +Constraints: 2 + +Num.test_add_optimized: +Constraints: 2 + +Num.test_add: +Proof size: 1.63 KB +Proof hash: 78840d590a6187e45c5b044304e283bec8f5630fd3eda019d0252f46159036a0 +Prover_pp hash: 463e7afef6be60d32ccff71713fc3e446f2964ebb0dfe4b588aed3f8d1f51f7c +Verifier_pp hash: f8358ef6b978d333ebce3dc2365dfc938759181ef24af82c3654f0759f1b6331 + +Num.test_add: +Constraints: 2 + +Num.test_add_optimized: +Constraints: 2 + +Num.test_add: +Proof size: 1.63 KB +Proof hash: 4389305841b0af0bd4e2a50511c8ca29bfe03f2137db0ffaf19572f157621547 +Prover_pp hash: 463e7afef6be60d32ccff71713fc3e446f2964ebb0dfe4b588aed3f8d1f51f7c +Verifier_pp hash: f8358ef6b978d333ebce3dc2365dfc938759181ef24af82c3654f0759f1b6331 + +Num.test_add_constant: +Constraints: 2 + +Num.test_add_constant_optimized: +Constraints: 2 + +Num.test_add_constant: +Proof size: 1.81 KB +Proof hash: 0d0c2b9afbaa710f9c8ec6839e60a3a11d942547b337da3dfe5d862658b334c2 +Prover_pp hash: 54a693cba6ce49da6608037bddaa96ed3173d4d5e7f99d311d7cbbd8934671b2 +Verifier_pp hash: f7820a43ae1dca9115fddfff3a678e429c1475406c43b86bd9f7b5a6e801e032 + +Num.test_add_constant: +Constraints: 2 + +Num.test_add_constant_optimized: +Constraints: 2 + +Num.test_add_constant: +Proof size: 1.76 KB +Proof hash: d7ddac082965bf1cb53bf335144326aa61c635720fd4d1d6de9042def30f2467 +Prover_pp hash: 14a6e487d286d4cab37eada4ed51d80bb76dfdbe803220fa4776895a9daa13ea +Verifier_pp hash: 49a2d752c77dd14db87121b347682e8f2e31deec516b09a6226c33ce436408df + +Num.test_sub: +Constraints: 2 + +Num.test_sub_optimized: +Constraints: 2 + +Num.test_sub: +Proof size: 1.63 KB +Proof hash: c4f64fa01de7d5c5f39ed4f8513bccaaf4cc1ceb5de117cc7121173af9bf0c3f +Prover_pp hash: 0ad03f1ccf62a9d7ba869aa656d8936f4272d6fac5eddbb7ca2a06379da7629e +Verifier_pp hash: 156200960d82a40fe7208c606039d005babb500681930710f1060a83c079ac90 + +Num.test_sub: +Constraints: 2 + +Num.test_sub_optimized: +Constraints: 2 + +Num.test_sub: +Proof size: 1.63 KB +Proof hash: 3c256589ee6d222168e6a6fcc211508fb38565015982dd2583e03c8841c0ebc3 +Prover_pp hash: 0ad03f1ccf62a9d7ba869aa656d8936f4272d6fac5eddbb7ca2a06379da7629e +Verifier_pp hash: 156200960d82a40fe7208c606039d005babb500681930710f1060a83c079ac90 + +Num.test_mul: +Constraints: 2 + +Num.test_mul_optimized: +Constraints: 2 + +Num.test_mul: +Proof size: 1.67 KB +Proof hash: 69cb25724c2ebdc605756d795ca3a2e2beea68d2fdc5b97c90e4a366ec341f1a +Prover_pp hash: 385ee46c9cd44f5a0d52114b685139bce0f381157f36dcf3bfc084d46f265911 +Verifier_pp hash: 4a79c5e8623fa5b1c6443d2c426847ee4f9812a6a1b3f4735b6742b67ba17f11 + +Num.test_mul: +Constraints: 2 + +Num.test_mul_optimized: +Constraints: 2 + +Num.test_mul: +Proof size: 1.67 KB +Proof hash: de63cf579e2cfb4b545b3026c069728fb802826acdf1c7f2df22e9d758e15903 +Prover_pp hash: 385ee46c9cd44f5a0d52114b685139bce0f381157f36dcf3bfc084d46f265911 +Verifier_pp hash: 4a79c5e8623fa5b1c6443d2c426847ee4f9812a6a1b3f4735b6742b67ba17f11 + +Num.test_mul: +Constraints: 2 + +Num.test_mul_optimized: +Constraints: 2 + +Num.test_mul: +Proof size: 1.67 KB +Proof hash: 7e8da5fb65812339b9a664be09ce4e07f82ff1c440d1f0e2ff401a9f169f7fea +Prover_pp hash: 385ee46c9cd44f5a0d52114b685139bce0f381157f36dcf3bfc084d46f265911 +Verifier_pp hash: 4a79c5e8623fa5b1c6443d2c426847ee4f9812a6a1b3f4735b6742b67ba17f11 + +Num.test_num: +Constraints: 6 + +Num.test_num_optimized: +Constraints: 5 + +Num.test_num: +Proof size: 1.72 KB +Proof hash: 31b21088e0d99bf3f1d0318111c415ec4f0134c038cd2ab5745e2d66c4dc582d +Prover_pp hash: 663f062553a164eb89ead19d0ce9d8b43de20736b98d532f20aeb6d967c176a6 +Verifier_pp hash: 3854844f2cefbbb02fb0a4443e79b49bf1380a5743a7e5899c4d3da2ff8a0ec1 + +Num.test_div: +Constraints: 3 + +Num.test_div_optimized: +Constraints: 2 + +Num.test_div: +Proof size: 1.67 KB +Proof hash: d1d09520bb85e0902edd175ac8a6d2baa7af311f798760f76dd9e215a71037f5 +Prover_pp hash: 430d829e0f9c19a794cd13a7ae2d077e024c85ce6cbf072bf3bdb6336872b1f7 +Verifier_pp hash: fd5d39f4419746db33d04b2472c4ff1f6ba71135121b6f42d027f4a3ece61bcd + +pow5: +Constraints: 2 + +pow5_optimized: +Constraints: 2 + +pow5: +Proof size: 1.50 KB +Proof hash: 5b8b017253ee5edab8365103cf41e1dfcd92e926338cc7169838deb801bfc9b0 +Prover_pp hash: d2d1ce9fbc11db3093c23010c574a5d1c48fd44e22038dc081affeb1fabb827e +Verifier_pp hash: cb89c752b04fdd8e9d7efb3bd398a576d4165145b1f48fdeee4d91c88894a818 + +test: +Constraints: 2 + +test_optimized: +Constraints: 2 + +test: +Proof size: 1.50 KB +Proof hash: 46004f9536371196c8b383fb02760de049567f30a2285c4dee6d6e23b45291fc +Prover_pp hash: 90d77f832efc14232ed8c13dabb2f9a0a07b7cd6f6b0964ffdd1109f006436b9 +Verifier_pp hash: a81c6d0f2aabfa667b669fc5d27017d6c750e8d9b3b50c0e6ff904c68cdf2c68 + +test: +Constraints: 2 + +test_optimized: +Constraints: 2 + +test: +Proof size: 1.50 KB +Proof hash: 3e4ca0c15707fd0cafa9c56407eeaf51786e5a6cb377721eb002041c0b748658 +Prover_pp hash: 90d77f832efc14232ed8c13dabb2f9a0a07b7cd6f6b0964ffdd1109f006436b9 +Verifier_pp hash: a81c6d0f2aabfa667b669fc5d27017d6c750e8d9b3b50c0e6ff904c68cdf2c68 + +test: +Constraints: 2 + +test_optimized: +Constraints: 2 + +test: +Proof size: 1.50 KB +Proof hash: 07c878b0f5f987076aea21b50d9313b38791da337d75c88df4ab773edb8dfa54 +Prover_pp hash: 90d77f832efc14232ed8c13dabb2f9a0a07b7cd6f6b0964ffdd1109f006436b9 +Verifier_pp hash: a81c6d0f2aabfa667b669fc5d27017d6c750e8d9b3b50c0e6ff904c68cdf2c68 + +pow: +Constraints: 6 + +pow_optimized: +Constraints: 4 + +pow: +Proof size: 1.57 KB +Proof hash: 8e1aa06d30e5846152af8d95d26e89e3fc584028915097e3c524d5672095e698 +Prover_pp hash: ec395a60169c2396e7af472b383994e7a3af02393d62f7c9498de054d13e7f62 +Verifier_pp hash: d1e4a51252d1ef10f3d53b43e6689e17b8569db4364ebf81f5505357740e21ed + +pow: +Constraints: 6 + +pow_optimized: +Constraints: 4 + +pow: +Proof size: 1.57 KB +Proof hash: c2d03e6d59c48d914f596483dac68b0191f01266bd5a4a930827aa820ac1ad9b +Prover_pp hash: ec395a60169c2396e7af472b383994e7a3af02393d62f7c9498de054d13e7f62 +Verifier_pp hash: d1e4a51252d1ef10f3d53b43e6689e17b8569db4364ebf81f5505357740e21ed + +pow: +Constraints: 10 + +pow_optimized: +Constraints: 7 + +pow: +Proof size: 1.57 KB +Proof hash: 7ad5ae7534c9c3b02037755bfa43fd94fbab51fcd168c41584ca2168dba82be8 +Prover_pp hash: 492750d6fae26e7830631d31eae42b8140f1129a6d3d124e000a89addf513f06 +Verifier_pp hash: dbeb0903627b947f202091b0a0a0b13c3e829881c5b5fa922bc20cb36e896080 + +pow: +Constraints: 10 + +pow_optimized: +Constraints: 7 + +pow: +Proof size: 1.57 KB +Proof hash: 6936209db0cdeb01c9e934fd5eaf572d7177bcb5f8f9dbacf9378ef09d55dd13 +Prover_pp hash: 492750d6fae26e7830631d31eae42b8140f1129a6d3d124e000a89addf513f06 +Verifier_pp hash: dbeb0903627b947f202091b0a0a0b13c3e829881c5b5fa922bc20cb36e896080 + +pow: +Constraints: 18 + +pow_optimized: +Constraints: 13 + +pow: +Proof size: 1.57 KB +Proof hash: 05052c816a6a7ea8d9cc7c2d3c38c6c0810084d5c62e6ffe5e20cbf02bafb986 +Prover_pp hash: fb6918241ab44f484a42b392bf20149d75f96d354ff3354eb8031f676545490f +Verifier_pp hash: 1f73a5cb718a289dd4de50e6e80238e0067a81d4e30c2f3c66cb65861afa26a9 + +pow: +Constraints: 26 + +pow_optimized: +Constraints: 19 + +pow: +Proof size: 1.57 KB +Proof hash: 7249c137ffecf569d29a408eee0a2ee81e1399a0d78044ef79f5242689a2711c +Prover_pp hash: 3c988cc32f24799505f88dde9ac6ebda93b8a578739cafb965219a78f0a03886 +Verifier_pp hash: e380fcc587e2736cdf9e725a084f9f1a37074dcffee7bb5222bedae8d5231cd1 + +pow: +Constraints: 14 + +pow_optimized: +Constraints: 10 + +pow: +Proof size: 1.57 KB +Proof hash: 1fa22228627d8aba599c94546f6bf6e6ea5a5ec5737f305a72fab818631e1d1c +Prover_pp hash: 05b4cfb7d9ff3f9ef0162a0e174f3068b483aa8c56e22356fa1dc0605f20f9be +Verifier_pp hash: 9b88d99f1e2b6d328f11cd296cdc81a05cc0e64d67b43027f1e3343017dbe6d0 + +Num.test_equal: +Constraints: 1 + +Num.test_equal_optimized: +Constraints: 1 + +Num.test_equal: +Proof size: 1.62 KB +Proof hash: b62cd824a5e930a60c6f65b085efe6222f415155b6a0f966a9bf00c1a92e8660 +Prover_pp hash: 3cf111b04edfe56f5f0b8ce66c4a19ac0007f04fd0cc28178976a47c277cdda3 +Verifier_pp hash: 481e6b21e305d2a03f6c7792d9afd6a5b40a881b9e5d9c6a4434a1a05affeb6c + +Num.bits_of_scalar: +Constraints: 15 + +Num.bits_of_scalar_optimized: +Constraints: 6 + +Num.bits_of_scalar: +Proof size: 2.28 KB +Proof hash: 09981dc210479d6e7a6dfef00d2fe96c99bb12dbc55b90876a002dfa278527e3 +Prover_pp hash: f0ccc6bc84c0c5ab1a8fccb6b0778a672f8c1f0a668e7bfeadd1e2f4de10805b +Verifier_pp hash: 3dcf4f4b3dc2daf37152cc2ec0514b2b4adb69bc21fb929de5202565f3c19b98 + +Num.bits_of_scalar: +Constraints: 15 + +Num.bits_of_scalar_optimized: +Constraints: 6 + +Num.bits_of_scalar: +Proof size: 2.28 KB +Proof hash: d117fcd8c9319154103791efb07673e6c8cf8aedeba60118fcd41d66c0faa843 +Prover_pp hash: bdfb408ffad04d2def55e2c1d1620aeca80e7bb69441f00f59813afe9beab53a +Verifier_pp hash: 72388bdbe01b792c0b359fef40373056cd07cec863d7e48b4a8546809f953290 + +Num.is_upper_bounded: +Constraints: 8 + +Num.is_upper_bounded_optimized: +Constraints: 5 + +Num.is_upper_bounded: +Proof size: 1.96 KB +Proof hash: e37beefe3d5e414d040133c0f0f3e2d2d9232dd98eb9c231d805cdca97306977 +Prover_pp hash: 8cd15656662aedb7379c0549fae51fb189323b59c2a3bee559f957da5e63d45f +Verifier_pp hash: 54c700cb844f53973b924c700d371298f375735ec347b1b4ac8d74fefcb8cf35 + +Num.is_upper_bounded: +Constraints: 14 + +Num.is_upper_bounded_optimized: +Constraints: 8 + +Num.is_upper_bounded: +Proof size: 2.01 KB +Proof hash: b17849b6aafac9a5c45ea180dac046867413191b1e9a71a336fde84ad43c58ab +Prover_pp hash: 1e3d84f90de5958a589f8cef22c002bb5b76ba353c2e41ea87e53e8b3a90be0e +Verifier_pp hash: bfb2403c79895d9fd129f0f7b46b2212a42818e998d48849cc4aaaf9c8f2547b + +Num.is_upper_bounded: +Constraints: 26 + +Num.is_upper_bounded_optimized: +Constraints: 12 + +Num.is_upper_bounded: +Proof size: 2.51 KB +Proof hash: 3704c2958f92c80e727cfe3c672a046832b9065101b0a11b41d8d06946ddcbc8 +Prover_pp hash: 7f195be5672e8ede003ea945607ec946177f7c9271a23d7386711a04d2645798 +Verifier_pp hash: 7fb724eab9a8e06ad003216b229f591ed0e7d1bb283662d1b7e29bbc12ddf3bb + +Num.is_upper_bounded: +Constraints: 738 + +Num.is_upper_bounded_optimized: +Constraints: 318 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: 59ee74d493b93c2abe4175c49af4a25dae0aa6fe063f779d50cb14748ace0c0d +Prover_pp hash: 13d7b24b2d15ef34626fc8afe001211588653cbb20607c2c9f0b2d05f79e62ab +Verifier_pp hash: 9767122fcd34a26ba6151520267638bfc6f2934e2dceba1eb379726163496234 + +Num.is_upper_bounded: +Constraints: 8 + +Num.is_upper_bounded_optimized: +Constraints: 5 + +Num.is_upper_bounded: +Proof size: 1.96 KB +Proof hash: e37beefe3d5e414d040133c0f0f3e2d2d9232dd98eb9c231d805cdca97306977 +Prover_pp hash: 8cd15656662aedb7379c0549fae51fb189323b59c2a3bee559f957da5e63d45f +Verifier_pp hash: 54c700cb844f53973b924c700d371298f375735ec347b1b4ac8d74fefcb8cf35 + +Num.is_upper_bounded: +Constraints: 735 + +Num.is_upper_bounded_optimized: +Constraints: 315 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: c470a1527b02c41aad9834fbb47e75601464b0b25b53a8cffab739ebede7bb29 +Prover_pp hash: 7da0870177cc36565502138a6a3b7d382e32c008c8cbf74ed281c49f451cf540 +Verifier_pp hash: 54ac7559c6601fb4a6c087e3cf4a998aead89ddf066cdefdde860613573ea9ad + +Num.is_upper_bounded: +Constraints: 765 + +Num.is_upper_bounded_optimized: +Constraints: 319 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: 270cb6a9e964b7fd90df555b475baf1f77d958379733cb7076b0a8dfd24ffc34 +Prover_pp hash: aa2491fad0c9e9370678e387eaec321cbe4815426c5d8439c804adedd7ea6ed9 +Verifier_pp hash: 9ec587eea6199e21e0832bcc0c9f96368445e27022a35c79aec208039dc4633e + +Num.is_upper_bounded: +Constraints: 765 + +Num.is_upper_bounded_optimized: +Constraints: 319 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: 10887a206c80c9713b38407af90d62e8dedfc2c829337e38ed6d5bc9e8526cd8 +Prover_pp hash: 82452e784ddd393d8ec468b925f3328563cb0f467d635e4a34cf40509b178a58 +Verifier_pp hash: 2effa9f1d6f2ff450171d5b2d8a6b8f9aa4fff282fecbb11d9f2418d1aca2143 + +Num.is_upper_bounded: +Constraints: 767 + +Num.is_upper_bounded_optimized: +Constraints: 319 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: a809fafdd4700de3748e2270fb882c2a683545fe2b4c610c3f00d89d75d63fc4 +Prover_pp hash: e0a263e18961c159808f93725d642fce4ceea4b7814f226433eec360028f1ae4 +Verifier_pp hash: 5f0b34025674e79cb38e26e22f80607c9d6f244a6e9fd8b995f0833d19701a9a + +Num.is_upper_bounded: +Constraints: 735 + +Num.is_upper_bounded_optimized: +Constraints: 315 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: c470a1527b02c41aad9834fbb47e75601464b0b25b53a8cffab739ebede7bb29 +Prover_pp hash: 7da0870177cc36565502138a6a3b7d382e32c008c8cbf74ed281c49f451cf540 +Verifier_pp hash: 54ac7559c6601fb4a6c087e3cf4a998aead89ddf066cdefdde860613573ea9ad + +Num.is_upper_bounded_totality: +Constraints: 764 + +Num.is_upper_bounded_totality_optimized: +Constraints: 318 + +Num.is_upper_bounded_totality: +Proof size: 2.93 KB +Proof hash: bd1490573d9b689ed263c41316c9e442d5fd184a30b3e77b59d1dabd38dac350 +Prover_pp hash: 8bc6f262eb161424b9da9f4e312c1ce214d564e3fd8f480a5e53e611af98f231 +Verifier_pp hash: 56f8bec45d05e0da8d702de460bf4fcbfff724000b4e42ec3c6474b8c41c791d + +Num.is_upper_bounded_totality: +Constraints: 734 + +Num.is_upper_bounded_totality_optimized: +Constraints: 314 + +Num.is_upper_bounded_totality: +Proof size: 2.93 KB +Proof hash: a9eef15e6f8606e35a6272ce328788a3c36d1fe669acc124deb26d1ca94409f0 +Prover_pp hash: 242e25c0faa2aef74d963de6c9a50030d731a3d0a8829eba76bd938859e30740 +Verifier_pp hash: bd3ecd3199a2a14445568feacc2e3c61683e5152d22f47073029d36a4619a945 + +Num.is_upper_bounded_totality: +Constraints: 766 + +Num.is_upper_bounded_totality_optimized: +Constraints: 318 + +Num.is_upper_bounded_totality: +Proof size: 2.93 KB +Proof hash: d9d4b14a914fa061d3188dbcdd7bef35f0d69c6ee2143326220c3246378d800f +Prover_pp hash: e1668b58b05e20d6c06fdd0cd467277d669e5c18d1f7c63bff80f5e3a591fb27 +Verifier_pp hash: b6b92f7682ded2d6243f4496fc4fd6456573d22dd4daf1a084441acd24151a84 + +Num.geq: +Constraints: 25 + +Num.geq_optimized: +Constraints: 11 + +Num.geq: +Proof size: 2.12 KB +Proof hash: 25741a6123ce1dea70b41df67f2b6cb949201b7951f58c97ee1d55f21bee121e +Prover_pp hash: 20d4da0bc772811baa5be2e837cd6b8868b11b948c2d7f899d85c910c38ee46e +Verifier_pp hash: 815e415c551a94e1fa234702c96f126706ef70de7232718fbac768c17a58e813 + +Num.geq: +Constraints: 22 + +Num.geq_optimized: +Constraints: 10 + +Num.geq: +Proof size: 2.08 KB +Proof hash: 1f7bb47e87b8cfb474d60d257066e3f9b8ee6256edf21ff7a99d2a71910f3c35 +Prover_pp hash: 1915b81ba6d52e9e5b86f3462e25ef8310f3b0fb460c223edccf064e06a6c441 +Verifier_pp hash: d201ce00e41e0af77c46fefcdbaca15432d5ac6931fbc94c0334bc228bbfe499 + +Num.test_add: +Constraints: 2 + +Num.test_add_optimized: +Constraints: 2 + +Num.test_add: +Constraints: 2 + +Num.test_add_optimized: +Constraints: 2 + +Num.test_add_constant: +Constraints: 2 + +Num.test_add_constant_optimized: +Constraints: 2 + +Num.test_add_constant: +Constraints: 2 + +Num.test_add_constant_optimized: +Constraints: 2 + +Num.test_sub: +Constraints: 2 + +Num.test_sub_optimized: +Constraints: 2 + +Num.test_sub: +Constraints: 2 + +Num.test_sub_optimized: +Constraints: 2 + +Num.test_mul: +Constraints: 2 + +Num.test_mul_optimized: +Constraints: 2 + +Num.test_mul: +Constraints: 2 + +Num.test_mul_optimized: +Constraints: 2 + +Num.test_mul: +Constraints: 2 + +Num.test_mul_optimized: +Constraints: 2 + +Num.test_num: +Constraints: 6 + +Num.test_num_optimized: +Constraints: 5 + +Num.test_div: +Constraints: 3 + +Num.test_div_optimized: +Constraints: 2 + +pow5: +Constraints: 2 + +pow5_optimized: +Constraints: 2 + +test: +Constraints: 2 + +test_optimized: +Constraints: 2 + +test: +Constraints: 2 + +test_optimized: +Constraints: 2 + +test: +Constraints: 2 + +test_optimized: +Constraints: 2 + +pow: +Constraints: 6 + +pow_optimized: +Constraints: 4 + +pow: +Constraints: 6 + +pow_optimized: +Constraints: 4 + +pow: +Constraints: 10 + +pow_optimized: +Constraints: 7 + +pow: +Constraints: 10 + +pow_optimized: +Constraints: 7 + +pow: +Constraints: 18 + +pow_optimized: +Constraints: 13 + +pow: +Constraints: 26 + +pow_optimized: +Constraints: 19 + +pow: +Constraints: 14 + +pow_optimized: +Constraints: 10 + +Num.test_equal: +Constraints: 1 + +Num.test_equal_optimized: +Constraints: 1 + +Num.bits_of_scalar: +Constraints: 15 + +Num.bits_of_scalar_optimized: +Constraints: 6 + +Num.bits_of_scalar: +Constraints: 15 + +Num.bits_of_scalar_optimized: +Constraints: 6 + +Num.is_upper_bounded: +Constraints: 8 + +Num.is_upper_bounded_optimized: +Constraints: 5 + +Num.is_upper_bounded: +Constraints: 14 + +Num.is_upper_bounded_optimized: +Constraints: 8 + +Num.is_upper_bounded: +Constraints: 26 + +Num.is_upper_bounded_optimized: +Constraints: 12 + +Num.is_upper_bounded: +Constraints: 738 + +Num.is_upper_bounded_optimized: +Constraints: 318 + +Num.is_upper_bounded: +Constraints: 8 + +Num.is_upper_bounded_optimized: +Constraints: 5 + +Num.is_upper_bounded: +Constraints: 735 + +Num.is_upper_bounded_optimized: +Constraints: 315 + +Num.is_upper_bounded: +Constraints: 765 + +Num.is_upper_bounded_optimized: +Constraints: 319 + +Num.is_upper_bounded: +Constraints: 765 + +Num.is_upper_bounded_optimized: +Constraints: 319 + +Num.is_upper_bounded: +Constraints: 767 + +Num.is_upper_bounded_optimized: +Constraints: 319 + +Num.is_upper_bounded: +Constraints: 735 + +Num.is_upper_bounded_optimized: +Constraints: 315 + +Num.is_upper_bounded_totality: +Constraints: 764 + +Num.is_upper_bounded_totality_optimized: +Constraints: 318 + +Num.is_upper_bounded_totality: +Constraints: 734 + +Num.is_upper_bounded_totality_optimized: +Constraints: 314 + +Num.is_upper_bounded_totality: +Constraints: 766 + +Num.is_upper_bounded_totality_optimized: +Constraints: 318 + +Num.geq: +Constraints: 25 + +Num.geq_optimized: +Constraints: 11 + +Num.geq: +Constraints: 22 + +Num.geq_optimized: +Constraints: 10 + +Bool.test_assert_true_and_false: +Constraints: 2 + +Bool.test_assert_true_and_false_optimized: +Constraints: 1 + +Bool.test_assert_true_and_false: +Constraints: 2 + +Bool.test_assert_true_and_false_optimized: +Constraints: 1 + +Bool.test_equal: +Constraints: 3 + +Bool.test_equal_optimized: +Constraints: 2 + +Bool.test_is_zero: +Constraints: 4 + +Bool.test_is_zero_optimized: +Constraints: 3 + +Bool.test_is_not_zero: +Constraints: 4 + +Bool.test_is_not_zero_optimized: +Constraints: 3 + +Bool.test_assert_bool: +Constraints: 1 + +Bool.test_assert_bool_optimized: +Constraints: 1 + +Bool.test_assert_bool: +Constraints: 1 + +Bool.test_assert_bool_optimized: +Constraints: 1 + +Bool.test_band: +Constraints: 5 + +Bool.test_band_optimized: +Constraints: 4 + +Bool.test_band: +Constraints: 5 + +Bool.test_band_optimized: +Constraints: 4 + +Bool.test_band: +Constraints: 5 + +Bool.test_band_optimized: +Constraints: 4 + +Bool.test_band: +Constraints: 5 + +Bool.test_band_optimized: +Constraints: 4 + +Bool.test_xor: +Constraints: 5 + +Bool.test_xor_optimized: +Constraints: 4 + +Bool.test_xor: +Constraints: 5 + +Bool.test_xor_optimized: +Constraints: 4 + +Bool.test_xor: +Constraints: 5 + +Bool.test_xor_optimized: +Constraints: 4 + +Bool.test_xor: +Constraints: 5 + +Bool.test_xor_optimized: +Constraints: 4 + +Bool.test_bor: +Constraints: 5 + +Bool.test_bor_optimized: +Constraints: 4 + +Bool.test_bor: +Constraints: 5 + +Bool.test_bor_optimized: +Constraints: 4 + +Bool.test_bor: +Constraints: 5 + +Bool.test_bor_optimized: +Constraints: 4 + +Bool.test_bor: +Constraints: 5 + +Bool.test_bor_optimized: +Constraints: 4 + +Bool.test_bnot: +Constraints: 4 + +Bool.test_bnot_optimized: +Constraints: 3 + +Bool.test_bnot: +Constraints: 4 + +Bool.test_bnot_optimized: +Constraints: 3 + +Bool.test_ifthenelse: +Constraints: 3 + +Bool.test_ifthenelse_optimized: +Constraints: 1 + +Bool.test_ifthenelse: +Constraints: 3 + +Bool.test_ifthenelse_optimized: +Constraints: 1 + +Bool.test_ifthenelse: +Constraints: 6 + +Bool.test_ifthenelse_optimized: +Constraints: 4 + +Bool.test_ifthenelse: +Constraints: 6 + +Bool.test_ifthenelse_optimized: +Constraints: 4 + +Bool.test_ifthenelse: +Constraints: 5 + +Bool.test_ifthenelse_optimized: +Constraints: 2 + +Bool.test_ifthenelse: +Constraints: 5 + +Bool.test_ifthenelse_optimized: +Constraints: 2 + +Bool.test_ifthenelse: +Constraints: 5 + +Bool.test_ifthenelse_optimized: +Constraints: 2 + +Bool.test_ifthenelse: +Constraints: 5 + +Bool.test_ifthenelse_optimized: +Constraints: 2 + +Bool.test_swap: +Constraints: 4 + +Bool.test_swap_optimized: +Constraints: 2 + +Bool.test_swap: +Constraints: 4 + +Bool.test_swap_optimized: +Constraints: 2 + +Bool.test_swap: +Constraints: 8 + +Bool.test_swap_optimized: +Constraints: 5 + +Bool.test_swap: +Constraints: 8 + +Bool.test_swap_optimized: +Constraints: 5 + +Bool.test_swap: +Constraints: 7 + +Bool.test_swap_optimized: +Constraints: 3 + +Bool.test_swap: +Constraints: 7 + +Bool.test_swap_optimized: +Constraints: 3 + +Bool.test_swap: +Constraints: 7 + +Bool.test_swap_optimized: +Constraints: 3 + +Bool.test_swap: +Constraints: 7 + +Bool.test_swap_optimized: +Constraints: 3 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +List.test_add_list: +Constraints: 5 + +List.test_add_list_optimized: +Constraints: 2 + +List.test_add_list: +Constraints: 6 + +List.test_add_list_optimized: +Constraints: 2 + +List.test_equal: +Constraints: 2 + +List.test_equal_optimized: +Constraints: 2 + +List.test_hd: +Constraints: 1 + +List.test_hd_optimized: +Constraints: 1 + +List.test_mul_list: +Constraints: 4 + +List.test_mul_list_optimized: +Constraints: 3 + +List.test_mul_list: +Constraints: 5 + +List.test_mul_list_optimized: +Constraints: 4 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_scalar_of_bytes: +Constraints: 82 + +Rest.test_scalar_of_bytes_optimized: +Constraints: 45 + +Tuple.test_equal: +Constraints: 2 + +Tuple.test_equal_optimized: +Constraints: 2 + +Tuple.test_point: +Constraints: 4 + +Tuple.test_point_optimized: +Constraints: 3 + +ECC.test_weierstrass_add: +Constraints: 12 + +ECC.test_weierstrass_add_optimized: +Constraints: 11 + +ECC.test_edwards_add: +Constraints: 12 + +ECC.test_edwards_add_optimized: +Constraints: 11 + +Bytes.test_add: +Constraints: 69 + +Bytes.test_add_optimized: +Constraints: 54 + +Bytes.test_xor: +Constraints: 40 + +Bytes.test_xor_optimized: +Constraints: 25 + +Bytes.blake: +Constraints: 160 + +Bytes.blake_optimized: +Constraints: 97 + +Bytes.test_ifthenelse: +Constraints: 41 + +Bytes.test_ifthenelse_optimized: +Constraints: 32 + +Bytes.test_ifthenelse: +Constraints: 41 + +Bytes.test_ifthenelse_optimized: +Constraints: 32 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Num.test_add: +Constraints: 2 + +Num.test_add_optimized: +Constraints: 2 + +Num.test_add: +Proof size: 1.63 KB +Proof hash: 78840d590a6187e45c5b044304e283bec8f5630fd3eda019d0252f46159036a0 +Prover_pp hash: 463e7afef6be60d32ccff71713fc3e446f2964ebb0dfe4b588aed3f8d1f51f7c +Verifier_pp hash: f8358ef6b978d333ebce3dc2365dfc938759181ef24af82c3654f0759f1b6331 + +Num.test_add: +Constraints: 2 + +Num.test_add_optimized: +Constraints: 2 + +Num.test_add: +Proof size: 1.63 KB +Proof hash: 4389305841b0af0bd4e2a50511c8ca29bfe03f2137db0ffaf19572f157621547 +Prover_pp hash: 463e7afef6be60d32ccff71713fc3e446f2964ebb0dfe4b588aed3f8d1f51f7c +Verifier_pp hash: f8358ef6b978d333ebce3dc2365dfc938759181ef24af82c3654f0759f1b6331 + +Num.test_add_constant: +Constraints: 2 + +Num.test_add_constant_optimized: +Constraints: 2 + +Num.test_add_constant: +Proof size: 1.81 KB +Proof hash: 0d0c2b9afbaa710f9c8ec6839e60a3a11d942547b337da3dfe5d862658b334c2 +Prover_pp hash: 54a693cba6ce49da6608037bddaa96ed3173d4d5e7f99d311d7cbbd8934671b2 +Verifier_pp hash: f7820a43ae1dca9115fddfff3a678e429c1475406c43b86bd9f7b5a6e801e032 + +Num.test_add_constant: +Constraints: 2 + +Num.test_add_constant_optimized: +Constraints: 2 + +Num.test_add_constant: +Proof size: 1.76 KB +Proof hash: d7ddac082965bf1cb53bf335144326aa61c635720fd4d1d6de9042def30f2467 +Prover_pp hash: 14a6e487d286d4cab37eada4ed51d80bb76dfdbe803220fa4776895a9daa13ea +Verifier_pp hash: 49a2d752c77dd14db87121b347682e8f2e31deec516b09a6226c33ce436408df + +Num.test_sub: +Constraints: 2 + +Num.test_sub_optimized: +Constraints: 2 + +Num.test_sub: +Proof size: 1.63 KB +Proof hash: c4f64fa01de7d5c5f39ed4f8513bccaaf4cc1ceb5de117cc7121173af9bf0c3f +Prover_pp hash: 0ad03f1ccf62a9d7ba869aa656d8936f4272d6fac5eddbb7ca2a06379da7629e +Verifier_pp hash: 156200960d82a40fe7208c606039d005babb500681930710f1060a83c079ac90 + +Num.test_sub: +Constraints: 2 + +Num.test_sub_optimized: +Constraints: 2 + +Num.test_sub: +Proof size: 1.63 KB +Proof hash: 3c256589ee6d222168e6a6fcc211508fb38565015982dd2583e03c8841c0ebc3 +Prover_pp hash: 0ad03f1ccf62a9d7ba869aa656d8936f4272d6fac5eddbb7ca2a06379da7629e +Verifier_pp hash: 156200960d82a40fe7208c606039d005babb500681930710f1060a83c079ac90 + +Num.test_mul: +Constraints: 2 + +Num.test_mul_optimized: +Constraints: 2 + +Num.test_mul: +Proof size: 1.67 KB +Proof hash: 69cb25724c2ebdc605756d795ca3a2e2beea68d2fdc5b97c90e4a366ec341f1a +Prover_pp hash: 385ee46c9cd44f5a0d52114b685139bce0f381157f36dcf3bfc084d46f265911 +Verifier_pp hash: 4a79c5e8623fa5b1c6443d2c426847ee4f9812a6a1b3f4735b6742b67ba17f11 + +Num.test_mul: +Constraints: 2 + +Num.test_mul_optimized: +Constraints: 2 + +Num.test_mul: +Proof size: 1.67 KB +Proof hash: de63cf579e2cfb4b545b3026c069728fb802826acdf1c7f2df22e9d758e15903 +Prover_pp hash: 385ee46c9cd44f5a0d52114b685139bce0f381157f36dcf3bfc084d46f265911 +Verifier_pp hash: 4a79c5e8623fa5b1c6443d2c426847ee4f9812a6a1b3f4735b6742b67ba17f11 + +Num.test_mul: +Constraints: 2 + +Num.test_mul_optimized: +Constraints: 2 + +Num.test_mul: +Proof size: 1.67 KB +Proof hash: 7e8da5fb65812339b9a664be09ce4e07f82ff1c440d1f0e2ff401a9f169f7fea +Prover_pp hash: 385ee46c9cd44f5a0d52114b685139bce0f381157f36dcf3bfc084d46f265911 +Verifier_pp hash: 4a79c5e8623fa5b1c6443d2c426847ee4f9812a6a1b3f4735b6742b67ba17f11 + +Num.test_num: +Constraints: 6 + +Num.test_num_optimized: +Constraints: 5 + +Num.test_num: +Proof size: 1.72 KB +Proof hash: 31b21088e0d99bf3f1d0318111c415ec4f0134c038cd2ab5745e2d66c4dc582d +Prover_pp hash: 663f062553a164eb89ead19d0ce9d8b43de20736b98d532f20aeb6d967c176a6 +Verifier_pp hash: 3854844f2cefbbb02fb0a4443e79b49bf1380a5743a7e5899c4d3da2ff8a0ec1 + +Num.test_div: +Constraints: 3 + +Num.test_div_optimized: +Constraints: 2 + +Num.test_div: +Proof size: 1.67 KB +Proof hash: d1d09520bb85e0902edd175ac8a6d2baa7af311f798760f76dd9e215a71037f5 +Prover_pp hash: 430d829e0f9c19a794cd13a7ae2d077e024c85ce6cbf072bf3bdb6336872b1f7 +Verifier_pp hash: fd5d39f4419746db33d04b2472c4ff1f6ba71135121b6f42d027f4a3ece61bcd + +pow5: +Constraints: 2 + +pow5_optimized: +Constraints: 2 + +pow5: +Proof size: 1.50 KB +Proof hash: 5b8b017253ee5edab8365103cf41e1dfcd92e926338cc7169838deb801bfc9b0 +Prover_pp hash: d2d1ce9fbc11db3093c23010c574a5d1c48fd44e22038dc081affeb1fabb827e +Verifier_pp hash: cb89c752b04fdd8e9d7efb3bd398a576d4165145b1f48fdeee4d91c88894a818 + +test: +Constraints: 2 + +test_optimized: +Constraints: 2 + +test: +Proof size: 1.50 KB +Proof hash: 46004f9536371196c8b383fb02760de049567f30a2285c4dee6d6e23b45291fc +Prover_pp hash: 90d77f832efc14232ed8c13dabb2f9a0a07b7cd6f6b0964ffdd1109f006436b9 +Verifier_pp hash: a81c6d0f2aabfa667b669fc5d27017d6c750e8d9b3b50c0e6ff904c68cdf2c68 + +test: +Constraints: 2 + +test_optimized: +Constraints: 2 + +test: +Proof size: 1.50 KB +Proof hash: 3e4ca0c15707fd0cafa9c56407eeaf51786e5a6cb377721eb002041c0b748658 +Prover_pp hash: 90d77f832efc14232ed8c13dabb2f9a0a07b7cd6f6b0964ffdd1109f006436b9 +Verifier_pp hash: a81c6d0f2aabfa667b669fc5d27017d6c750e8d9b3b50c0e6ff904c68cdf2c68 + +test: +Constraints: 2 + +test_optimized: +Constraints: 2 + +test: +Proof size: 1.50 KB +Proof hash: 07c878b0f5f987076aea21b50d9313b38791da337d75c88df4ab773edb8dfa54 +Prover_pp hash: 90d77f832efc14232ed8c13dabb2f9a0a07b7cd6f6b0964ffdd1109f006436b9 +Verifier_pp hash: a81c6d0f2aabfa667b669fc5d27017d6c750e8d9b3b50c0e6ff904c68cdf2c68 + +pow: +Constraints: 6 + +pow_optimized: +Constraints: 4 + +pow: +Proof size: 1.57 KB +Proof hash: 8e1aa06d30e5846152af8d95d26e89e3fc584028915097e3c524d5672095e698 +Prover_pp hash: ec395a60169c2396e7af472b383994e7a3af02393d62f7c9498de054d13e7f62 +Verifier_pp hash: d1e4a51252d1ef10f3d53b43e6689e17b8569db4364ebf81f5505357740e21ed + +pow: +Constraints: 6 + +pow_optimized: +Constraints: 4 + +pow: +Proof size: 1.57 KB +Proof hash: c2d03e6d59c48d914f596483dac68b0191f01266bd5a4a930827aa820ac1ad9b +Prover_pp hash: ec395a60169c2396e7af472b383994e7a3af02393d62f7c9498de054d13e7f62 +Verifier_pp hash: d1e4a51252d1ef10f3d53b43e6689e17b8569db4364ebf81f5505357740e21ed + +pow: +Constraints: 10 + +pow_optimized: +Constraints: 7 + +pow: +Proof size: 1.57 KB +Proof hash: 7ad5ae7534c9c3b02037755bfa43fd94fbab51fcd168c41584ca2168dba82be8 +Prover_pp hash: 492750d6fae26e7830631d31eae42b8140f1129a6d3d124e000a89addf513f06 +Verifier_pp hash: dbeb0903627b947f202091b0a0a0b13c3e829881c5b5fa922bc20cb36e896080 + +pow: +Constraints: 10 + +pow_optimized: +Constraints: 7 + +pow: +Proof size: 1.57 KB +Proof hash: 6936209db0cdeb01c9e934fd5eaf572d7177bcb5f8f9dbacf9378ef09d55dd13 +Prover_pp hash: 492750d6fae26e7830631d31eae42b8140f1129a6d3d124e000a89addf513f06 +Verifier_pp hash: dbeb0903627b947f202091b0a0a0b13c3e829881c5b5fa922bc20cb36e896080 + +pow: +Constraints: 18 + +pow_optimized: +Constraints: 13 + +pow: +Proof size: 1.57 KB +Proof hash: 05052c816a6a7ea8d9cc7c2d3c38c6c0810084d5c62e6ffe5e20cbf02bafb986 +Prover_pp hash: fb6918241ab44f484a42b392bf20149d75f96d354ff3354eb8031f676545490f +Verifier_pp hash: 1f73a5cb718a289dd4de50e6e80238e0067a81d4e30c2f3c66cb65861afa26a9 + +pow: +Constraints: 26 + +pow_optimized: +Constraints: 19 + +pow: +Proof size: 1.57 KB +Proof hash: 7249c137ffecf569d29a408eee0a2ee81e1399a0d78044ef79f5242689a2711c +Prover_pp hash: 3c988cc32f24799505f88dde9ac6ebda93b8a578739cafb965219a78f0a03886 +Verifier_pp hash: e380fcc587e2736cdf9e725a084f9f1a37074dcffee7bb5222bedae8d5231cd1 + +pow: +Constraints: 14 + +pow_optimized: +Constraints: 10 + +pow: +Proof size: 1.57 KB +Proof hash: 1fa22228627d8aba599c94546f6bf6e6ea5a5ec5737f305a72fab818631e1d1c +Prover_pp hash: 05b4cfb7d9ff3f9ef0162a0e174f3068b483aa8c56e22356fa1dc0605f20f9be +Verifier_pp hash: 9b88d99f1e2b6d328f11cd296cdc81a05cc0e64d67b43027f1e3343017dbe6d0 + +Num.test_equal: +Constraints: 1 + +Num.test_equal_optimized: +Constraints: 1 + +Num.test_equal: +Proof size: 1.62 KB +Proof hash: b62cd824a5e930a60c6f65b085efe6222f415155b6a0f966a9bf00c1a92e8660 +Prover_pp hash: 3cf111b04edfe56f5f0b8ce66c4a19ac0007f04fd0cc28178976a47c277cdda3 +Verifier_pp hash: 481e6b21e305d2a03f6c7792d9afd6a5b40a881b9e5d9c6a4434a1a05affeb6c + +Num.bits_of_scalar: +Constraints: 15 + +Num.bits_of_scalar_optimized: +Constraints: 6 + +Num.bits_of_scalar: +Proof size: 2.28 KB +Proof hash: 09981dc210479d6e7a6dfef00d2fe96c99bb12dbc55b90876a002dfa278527e3 +Prover_pp hash: f0ccc6bc84c0c5ab1a8fccb6b0778a672f8c1f0a668e7bfeadd1e2f4de10805b +Verifier_pp hash: 3dcf4f4b3dc2daf37152cc2ec0514b2b4adb69bc21fb929de5202565f3c19b98 + +Num.bits_of_scalar: +Constraints: 15 + +Num.bits_of_scalar_optimized: +Constraints: 6 + +Num.bits_of_scalar: +Proof size: 2.28 KB +Proof hash: d117fcd8c9319154103791efb07673e6c8cf8aedeba60118fcd41d66c0faa843 +Prover_pp hash: bdfb408ffad04d2def55e2c1d1620aeca80e7bb69441f00f59813afe9beab53a +Verifier_pp hash: 72388bdbe01b792c0b359fef40373056cd07cec863d7e48b4a8546809f953290 + +Num.is_upper_bounded: +Constraints: 8 + +Num.is_upper_bounded_optimized: +Constraints: 5 + +Num.is_upper_bounded: +Proof size: 1.96 KB +Proof hash: e37beefe3d5e414d040133c0f0f3e2d2d9232dd98eb9c231d805cdca97306977 +Prover_pp hash: 8cd15656662aedb7379c0549fae51fb189323b59c2a3bee559f957da5e63d45f +Verifier_pp hash: 54c700cb844f53973b924c700d371298f375735ec347b1b4ac8d74fefcb8cf35 + +Num.is_upper_bounded: +Constraints: 14 + +Num.is_upper_bounded_optimized: +Constraints: 8 + +Num.is_upper_bounded: +Proof size: 2.01 KB +Proof hash: b17849b6aafac9a5c45ea180dac046867413191b1e9a71a336fde84ad43c58ab +Prover_pp hash: 1e3d84f90de5958a589f8cef22c002bb5b76ba353c2e41ea87e53e8b3a90be0e +Verifier_pp hash: bfb2403c79895d9fd129f0f7b46b2212a42818e998d48849cc4aaaf9c8f2547b + +Num.is_upper_bounded: +Constraints: 26 + +Num.is_upper_bounded_optimized: +Constraints: 12 + +Num.is_upper_bounded: +Proof size: 2.51 KB +Proof hash: 3704c2958f92c80e727cfe3c672a046832b9065101b0a11b41d8d06946ddcbc8 +Prover_pp hash: 7f195be5672e8ede003ea945607ec946177f7c9271a23d7386711a04d2645798 +Verifier_pp hash: 7fb724eab9a8e06ad003216b229f591ed0e7d1bb283662d1b7e29bbc12ddf3bb + +Num.is_upper_bounded: +Constraints: 738 + +Num.is_upper_bounded_optimized: +Constraints: 318 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: 59ee74d493b93c2abe4175c49af4a25dae0aa6fe063f779d50cb14748ace0c0d +Prover_pp hash: 13d7b24b2d15ef34626fc8afe001211588653cbb20607c2c9f0b2d05f79e62ab +Verifier_pp hash: 9767122fcd34a26ba6151520267638bfc6f2934e2dceba1eb379726163496234 + +Num.is_upper_bounded: +Constraints: 8 + +Num.is_upper_bounded_optimized: +Constraints: 5 + +Num.is_upper_bounded: +Proof size: 1.96 KB +Proof hash: e37beefe3d5e414d040133c0f0f3e2d2d9232dd98eb9c231d805cdca97306977 +Prover_pp hash: 8cd15656662aedb7379c0549fae51fb189323b59c2a3bee559f957da5e63d45f +Verifier_pp hash: 54c700cb844f53973b924c700d371298f375735ec347b1b4ac8d74fefcb8cf35 + +Num.is_upper_bounded: +Constraints: 735 + +Num.is_upper_bounded_optimized: +Constraints: 315 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: c470a1527b02c41aad9834fbb47e75601464b0b25b53a8cffab739ebede7bb29 +Prover_pp hash: 7da0870177cc36565502138a6a3b7d382e32c008c8cbf74ed281c49f451cf540 +Verifier_pp hash: 54ac7559c6601fb4a6c087e3cf4a998aead89ddf066cdefdde860613573ea9ad + +Num.is_upper_bounded: +Constraints: 765 + +Num.is_upper_bounded_optimized: +Constraints: 319 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: 270cb6a9e964b7fd90df555b475baf1f77d958379733cb7076b0a8dfd24ffc34 +Prover_pp hash: aa2491fad0c9e9370678e387eaec321cbe4815426c5d8439c804adedd7ea6ed9 +Verifier_pp hash: 9ec587eea6199e21e0832bcc0c9f96368445e27022a35c79aec208039dc4633e + +Num.is_upper_bounded: +Constraints: 765 + +Num.is_upper_bounded_optimized: +Constraints: 319 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: 10887a206c80c9713b38407af90d62e8dedfc2c829337e38ed6d5bc9e8526cd8 +Prover_pp hash: 82452e784ddd393d8ec468b925f3328563cb0f467d635e4a34cf40509b178a58 +Verifier_pp hash: 2effa9f1d6f2ff450171d5b2d8a6b8f9aa4fff282fecbb11d9f2418d1aca2143 + +Num.is_upper_bounded: +Constraints: 767 + +Num.is_upper_bounded_optimized: +Constraints: 319 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: a809fafdd4700de3748e2270fb882c2a683545fe2b4c610c3f00d89d75d63fc4 +Prover_pp hash: e0a263e18961c159808f93725d642fce4ceea4b7814f226433eec360028f1ae4 +Verifier_pp hash: 5f0b34025674e79cb38e26e22f80607c9d6f244a6e9fd8b995f0833d19701a9a + +Num.is_upper_bounded: +Constraints: 735 + +Num.is_upper_bounded_optimized: +Constraints: 315 + +Num.is_upper_bounded: +Proof size: 2.62 KB +Proof hash: c470a1527b02c41aad9834fbb47e75601464b0b25b53a8cffab739ebede7bb29 +Prover_pp hash: 7da0870177cc36565502138a6a3b7d382e32c008c8cbf74ed281c49f451cf540 +Verifier_pp hash: 54ac7559c6601fb4a6c087e3cf4a998aead89ddf066cdefdde860613573ea9ad + +Num.is_upper_bounded_totality: +Constraints: 764 + +Num.is_upper_bounded_totality_optimized: +Constraints: 318 + +Num.is_upper_bounded_totality: +Proof size: 2.93 KB +Proof hash: bd1490573d9b689ed263c41316c9e442d5fd184a30b3e77b59d1dabd38dac350 +Prover_pp hash: 8bc6f262eb161424b9da9f4e312c1ce214d564e3fd8f480a5e53e611af98f231 +Verifier_pp hash: 56f8bec45d05e0da8d702de460bf4fcbfff724000b4e42ec3c6474b8c41c791d + +Num.is_upper_bounded_totality: +Constraints: 734 + +Num.is_upper_bounded_totality_optimized: +Constraints: 314 + +Num.is_upper_bounded_totality: +Proof size: 2.93 KB +Proof hash: a9eef15e6f8606e35a6272ce328788a3c36d1fe669acc124deb26d1ca94409f0 +Prover_pp hash: 242e25c0faa2aef74d963de6c9a50030d731a3d0a8829eba76bd938859e30740 +Verifier_pp hash: bd3ecd3199a2a14445568feacc2e3c61683e5152d22f47073029d36a4619a945 + +Num.is_upper_bounded_totality: +Constraints: 766 + +Num.is_upper_bounded_totality_optimized: +Constraints: 318 + +Num.is_upper_bounded_totality: +Proof size: 2.93 KB +Proof hash: d9d4b14a914fa061d3188dbcdd7bef35f0d69c6ee2143326220c3246378d800f +Prover_pp hash: e1668b58b05e20d6c06fdd0cd467277d669e5c18d1f7c63bff80f5e3a591fb27 +Verifier_pp hash: b6b92f7682ded2d6243f4496fc4fd6456573d22dd4daf1a084441acd24151a84 + +Num.geq: +Constraints: 25 + +Num.geq_optimized: +Constraints: 11 + +Num.geq: +Proof size: 2.12 KB +Proof hash: 25741a6123ce1dea70b41df67f2b6cb949201b7951f58c97ee1d55f21bee121e +Prover_pp hash: 20d4da0bc772811baa5be2e837cd6b8868b11b948c2d7f899d85c910c38ee46e +Verifier_pp hash: 815e415c551a94e1fa234702c96f126706ef70de7232718fbac768c17a58e813 + +Num.geq: +Constraints: 22 + +Num.geq_optimized: +Constraints: 10 + +Num.geq: +Proof size: 2.08 KB +Proof hash: 1f7bb47e87b8cfb474d60d257066e3f9b8ee6256edf21ff7a99d2a71910f3c35 +Prover_pp hash: 1915b81ba6d52e9e5b86f3462e25ef8310f3b0fb460c223edccf064e06a6c441 +Verifier_pp hash: d201ce00e41e0af77c46fefcdbaca15432d5ac6931fbc94c0334bc228bbfe499 + +Bool.test_assert_true_and_false: +Constraints: 2 + +Bool.test_assert_true_and_false_optimized: +Constraints: 1 + +Bool.test_assert_true_and_false: +Proof size: 2.02 KB +Proof hash: 86acf6333f47a06452107313884fd1cf0edb3b7923522701c5f89947d9010c9f +Prover_pp hash: 03c6e046b97cb5ab87998cfc8c8fc369b0a5f0ff9f51483ed14f1f99b554a48f +Verifier_pp hash: 9f94e42030ae97bd7412b5dd67d2ffb4df03748e7193c520e6a4842607ceec59 + +Bool.test_assert_true_and_false: +Constraints: 2 + +Bool.test_assert_true_and_false_optimized: +Constraints: 1 + +Bool.test_assert_true_and_false: +Proof size: 1.95 KB +Proof hash: 5bfaf43c5d27c54cdf7effa9b714a68ad23d519dc696b98c35fc8c1272ea124f +Prover_pp hash: 7117ed05a8faf71bdcae228c2a507be3f5f9b84dee2739a2dd24aea15ae7f050 +Verifier_pp hash: 3e395a514c0e3fa55641c793c81cede7bd8ff55860cda9882ed1f879f239abfa + +Bool.test_equal: +Constraints: 3 + +Bool.test_equal_optimized: +Constraints: 2 + +Bool.test_equal: +Proof size: 1.69 KB +Proof hash: 451cfbaee1e225041516906fcdb76876f8ee6d42fa753e674c73fecec4c53503 +Prover_pp hash: e2dc9da74b3048b20823c7ac7780a68fc693b0988797a72c6159da436826be59 +Verifier_pp hash: 89b3bd1ff8e9a58e2292f7ffa35f4ec47a78d893f996ea9abb6c8e164cc90b97 + +Bool.test_is_zero: +Constraints: 4 + +Bool.test_is_zero_optimized: +Constraints: 3 + +Bool.test_is_zero: +Proof size: 1.84 KB +Proof hash: 454d05ef2b62e7903d61e9e43282524bf8dd51e6481488befb78ec53188cf596 +Prover_pp hash: 1857923b1bee92caa2239e1942ba8998ebb098be380c6723ed71d8bf330055c6 +Verifier_pp hash: 49e1051a1d3aa138a3bfb1b7643a15a282426e9298ec439018e51bad8efc4022 + +Bool.test_is_not_zero: +Constraints: 4 + +Bool.test_is_not_zero_optimized: +Constraints: 3 + +Bool.test_is_not_zero: +Proof size: 1.93 KB +Proof hash: 0c12ea5b19915e20ee363aa7a4f97094f0076def8a0d4c57268e39fba843dd3e +Prover_pp hash: 707e7a5ec2c314d8fe46a14b2705e7d43df7dad9249dc0e8dd9c826f1797404e +Verifier_pp hash: fb0d43e327770d736ded8446d1016f8fec1518f8779fe7683a687c3647e25161 + +Bool.test_assert_bool: +Constraints: 1 + +Bool.test_assert_bool_optimized: +Constraints: 1 + +Bool.test_assert_bool: +Proof size: 1.76 KB +Proof hash: 81fc45c03cea11cbf2e9c75a7f174225a87f5cb842451483fafc9df19fcc881a +Prover_pp hash: 7b8bf1a65051d573c6ead2050793c48135064caa314a5fc81ae0001d3125e798 +Verifier_pp hash: ea6106d03a25b55b8e89c40f460b8cffe9017092325308baa20943bb6127ab60 + +Bool.test_assert_bool: +Constraints: 1 + +Bool.test_assert_bool_optimized: +Constraints: 1 + +Bool.test_assert_bool: +Proof size: 1.76 KB +Proof hash: 9bd65baa8e0dedb12ff2d99b1e52e746f2c23464ee2bde2246f2df67398e0eb4 +Prover_pp hash: 7b8bf1a65051d573c6ead2050793c48135064caa314a5fc81ae0001d3125e798 +Verifier_pp hash: ea6106d03a25b55b8e89c40f460b8cffe9017092325308baa20943bb6127ab60 + +Bool.test_band: +Constraints: 5 + +Bool.test_band_optimized: +Constraints: 4 + +Bool.test_band: +Proof size: 1.77 KB +Proof hash: 6f5a197b5d3380179f7a264e2ae81db2affb932401fc3337bda60bbc0328e4cf +Prover_pp hash: 1fe7c11531f69115541504a4c53a0b186277ea809b9b78f9c30b1135896c1100 +Verifier_pp hash: b53049d2b8a8f3b7ce83b901eda6ab5b4a5d661b63cdf954f04bf88d0189265e + +Bool.test_band: +Constraints: 5 + +Bool.test_band_optimized: +Constraints: 4 + +Bool.test_band: +Proof size: 1.77 KB +Proof hash: aa449bcabd6b0fe23cf2ba16be79d8b4451eaad7aa765e2c66eab4503a15fd07 +Prover_pp hash: 1fe7c11531f69115541504a4c53a0b186277ea809b9b78f9c30b1135896c1100 +Verifier_pp hash: b53049d2b8a8f3b7ce83b901eda6ab5b4a5d661b63cdf954f04bf88d0189265e + +Bool.test_band: +Constraints: 5 + +Bool.test_band_optimized: +Constraints: 4 + +Bool.test_band: +Proof size: 1.77 KB +Proof hash: acac1f3d06a0a3164c2eef3cdaab00ce8ca35cfdd24d48376192bb545c31f696 +Prover_pp hash: 1fe7c11531f69115541504a4c53a0b186277ea809b9b78f9c30b1135896c1100 +Verifier_pp hash: b53049d2b8a8f3b7ce83b901eda6ab5b4a5d661b63cdf954f04bf88d0189265e + +Bool.test_band: +Constraints: 5 + +Bool.test_band_optimized: +Constraints: 4 + +Bool.test_band: +Proof size: 1.77 KB +Proof hash: da2142af10d5793cf7df592fdced183617821a70c6be809a1719c588f81f0d94 +Prover_pp hash: 1fe7c11531f69115541504a4c53a0b186277ea809b9b78f9c30b1135896c1100 +Verifier_pp hash: b53049d2b8a8f3b7ce83b901eda6ab5b4a5d661b63cdf954f04bf88d0189265e + +Bool.test_xor: +Constraints: 5 + +Bool.test_xor_optimized: +Constraints: 4 + +Bool.test_xor: +Proof size: 1.75 KB +Proof hash: d0fbdb67f295e9cbe358839ff8c0d0b7d38784be3d8797c2ca6084296a921f6b +Prover_pp hash: 07484206af4a6a68a4861a18c0713805466fd5116eeae33b34a43985ee71e524 +Verifier_pp hash: ad970d76c8fbd079f31811336e0952c300467034dfb220e2c9a752b95c6d31b8 + +Bool.test_xor: +Constraints: 5 + +Bool.test_xor_optimized: +Constraints: 4 + +Bool.test_xor: +Proof size: 1.75 KB +Proof hash: 9638c3e9368374f79ec247f0934b41bee5364f2cbe986f72cadb850cb0377949 +Prover_pp hash: 07484206af4a6a68a4861a18c0713805466fd5116eeae33b34a43985ee71e524 +Verifier_pp hash: ad970d76c8fbd079f31811336e0952c300467034dfb220e2c9a752b95c6d31b8 + +Bool.test_xor: +Constraints: 5 + +Bool.test_xor_optimized: +Constraints: 4 + +Bool.test_xor: +Proof size: 1.75 KB +Proof hash: 8794a97786b8f46e466a8c3e90f7cb0c47d294726376ebfe33730f1ac4e53dab +Prover_pp hash: 07484206af4a6a68a4861a18c0713805466fd5116eeae33b34a43985ee71e524 +Verifier_pp hash: ad970d76c8fbd079f31811336e0952c300467034dfb220e2c9a752b95c6d31b8 + +Bool.test_xor: +Constraints: 5 + +Bool.test_xor_optimized: +Constraints: 4 + +Bool.test_xor: +Proof size: 1.75 KB +Proof hash: c2551a21a6399636db08098b65dc454d41736b4030a9298b98d75ee6efdabb5d +Prover_pp hash: 07484206af4a6a68a4861a18c0713805466fd5116eeae33b34a43985ee71e524 +Verifier_pp hash: ad970d76c8fbd079f31811336e0952c300467034dfb220e2c9a752b95c6d31b8 + +Bool.test_bor: +Constraints: 5 + +Bool.test_bor_optimized: +Constraints: 4 + +Bool.test_bor: +Proof size: 1.75 KB +Proof hash: b46387ea37ec902a054fbbca5a2c876ca4f5238b72cf19937d89a5347f04bb30 +Prover_pp hash: a7dee5d2765e406a56dbdede06de1ff6497ddb22401be151105821b8a2753abb +Verifier_pp hash: a8d67d2def56dbc13d7f389de0a4b5b90c065fb02920aa408c967ac97a612a20 + +Bool.test_bor: +Constraints: 5 + +Bool.test_bor_optimized: +Constraints: 4 + +Bool.test_bor: +Proof size: 1.75 KB +Proof hash: c48cb6f18626133100a5d2275f510852fbd6b9b62536d9b7d72943f179f3a758 +Prover_pp hash: a7dee5d2765e406a56dbdede06de1ff6497ddb22401be151105821b8a2753abb +Verifier_pp hash: a8d67d2def56dbc13d7f389de0a4b5b90c065fb02920aa408c967ac97a612a20 + +Bool.test_bor: +Constraints: 5 + +Bool.test_bor_optimized: +Constraints: 4 + +Bool.test_bor: +Proof size: 1.75 KB +Proof hash: 7b7b8aa521d10761fc191169377802d3cf0097f34c49ca718303d378c39ba19e +Prover_pp hash: a7dee5d2765e406a56dbdede06de1ff6497ddb22401be151105821b8a2753abb +Verifier_pp hash: a8d67d2def56dbc13d7f389de0a4b5b90c065fb02920aa408c967ac97a612a20 + +Bool.test_bor: +Constraints: 5 + +Bool.test_bor_optimized: +Constraints: 4 + +Bool.test_bor: +Proof size: 1.75 KB +Proof hash: 4c1a194407758f6a5b21616fe0e5d7b507185b3fd3d502ec3d91d79f0502a2a4 +Prover_pp hash: a7dee5d2765e406a56dbdede06de1ff6497ddb22401be151105821b8a2753abb +Verifier_pp hash: a8d67d2def56dbc13d7f389de0a4b5b90c065fb02920aa408c967ac97a612a20 + +Bool.test_bnot: +Constraints: 4 + +Bool.test_bnot_optimized: +Constraints: 3 + +Bool.test_bnot: +Proof size: 1.72 KB +Proof hash: 5e941b017e0ac340654a8924f7732e2b832681e38a767d219e473bb276afeb16 +Prover_pp hash: bba2c47730bb6215c5745c092c7b801b37d4e6a90c723bde8cf2c5e00a2d7cff +Verifier_pp hash: 4f35936539b9084ca58481e79631a972443ecaf3ddb496294d8f2f5bc66a2c53 + +Bool.test_bnot: +Constraints: 4 + +Bool.test_bnot_optimized: +Constraints: 3 + +Bool.test_bnot: +Proof size: 1.72 KB +Proof hash: 251863a3189b79633dbd745554b4219aad737dde101dec308084f77403efed06 +Prover_pp hash: bba2c47730bb6215c5745c092c7b801b37d4e6a90c723bde8cf2c5e00a2d7cff +Verifier_pp hash: 4f35936539b9084ca58481e79631a972443ecaf3ddb496294d8f2f5bc66a2c53 + +Bool.test_ifthenelse: +Constraints: 3 + +Bool.test_ifthenelse_optimized: +Constraints: 1 + +Bool.test_ifthenelse: +Proof size: 1.80 KB +Proof hash: 806be715bb7eeafd588214b3fd6b36bf139111e971166234618d5520bd17071f +Prover_pp hash: 762476a162ea08c5210f8188b148d385db5d84b67d49544c049ece52b216b442 +Verifier_pp hash: d24017fb443060b495bc97c9226b0fc32322bf419e66920d6da2f67ac3bd80d4 + +Bool.test_ifthenelse: +Constraints: 3 + +Bool.test_ifthenelse_optimized: +Constraints: 1 + +Bool.test_ifthenelse: +Proof size: 1.80 KB +Proof hash: 8e9495fe48d3fbfc56d8c2c9966a36ed76c98306868c68b4622e733ba03228ae +Prover_pp hash: 762476a162ea08c5210f8188b148d385db5d84b67d49544c049ece52b216b442 +Verifier_pp hash: d24017fb443060b495bc97c9226b0fc32322bf419e66920d6da2f67ac3bd80d4 + +Bool.test_ifthenelse: +Constraints: 6 + +Bool.test_ifthenelse_optimized: +Constraints: 4 + +Bool.test_ifthenelse: +Proof size: 1.80 KB +Proof hash: 2b7077ac3b81e58e396820edaad57253227fc66b69f31a65a349eae8627dd786 +Prover_pp hash: aaa17833995055ddd7b4a937d171c6a5d9963445c1f1ec3e6a70d7f5bcfcbbc4 +Verifier_pp hash: ac962b046cd9dbf04a83551a82503701b3fdbb252ddb3aae87afb8da01fe612b + +Bool.test_ifthenelse: +Constraints: 6 + +Bool.test_ifthenelse_optimized: +Constraints: 4 + +Bool.test_ifthenelse: +Proof size: 1.80 KB +Proof hash: 9db22003c4f321b9a09d276c569e555ee06c1e4a5456c6157a0eed0083826c5e +Prover_pp hash: aaa17833995055ddd7b4a937d171c6a5d9963445c1f1ec3e6a70d7f5bcfcbbc4 +Verifier_pp hash: ac962b046cd9dbf04a83551a82503701b3fdbb252ddb3aae87afb8da01fe612b + +Bool.test_ifthenelse: +Constraints: 5 + +Bool.test_ifthenelse_optimized: +Constraints: 2 + +Bool.test_ifthenelse: +Proof size: 1.80 KB +Proof hash: fde9db2368177b3843559b13554a04624e773a36af6da1af8d9627373a7bd686 +Prover_pp hash: c391dee89542ef2153b06315a139e32643d34b428dcb43f06165a7bda9085074 +Verifier_pp hash: 1de44a122d948936cc12586ceb7646740e40624caa44c5174dcd8c399232207d + +Bool.test_ifthenelse: +Constraints: 5 + +Bool.test_ifthenelse_optimized: +Constraints: 2 + +Bool.test_ifthenelse: +Proof size: 1.80 KB +Proof hash: be1c0b593db1bc763d71780fb3b106f8514d567525dc34e32e49afdc3ea62b88 +Prover_pp hash: c391dee89542ef2153b06315a139e32643d34b428dcb43f06165a7bda9085074 +Verifier_pp hash: 1de44a122d948936cc12586ceb7646740e40624caa44c5174dcd8c399232207d + +Bool.test_ifthenelse: +Constraints: 5 + +Bool.test_ifthenelse_optimized: +Constraints: 2 + +Bool.test_ifthenelse: +Proof size: 1.80 KB +Proof hash: fde9db2368177b3843559b13554a04624e773a36af6da1af8d9627373a7bd686 +Prover_pp hash: c391dee89542ef2153b06315a139e32643d34b428dcb43f06165a7bda9085074 +Verifier_pp hash: 1de44a122d948936cc12586ceb7646740e40624caa44c5174dcd8c399232207d + +Bool.test_ifthenelse: +Constraints: 5 + +Bool.test_ifthenelse_optimized: +Constraints: 2 + +Bool.test_ifthenelse: +Proof size: 1.80 KB +Proof hash: be1c0b593db1bc763d71780fb3b106f8514d567525dc34e32e49afdc3ea62b88 +Prover_pp hash: c391dee89542ef2153b06315a139e32643d34b428dcb43f06165a7bda9085074 +Verifier_pp hash: 1de44a122d948936cc12586ceb7646740e40624caa44c5174dcd8c399232207d + +Bool.test_swap: +Constraints: 4 + +Bool.test_swap_optimized: +Constraints: 2 + +Bool.test_swap: +Proof size: 1.73 KB +Proof hash: fdb5e275ec5fcea18b74e3540990246eda6f3d62212195793f3dddaa9e3d6efc +Prover_pp hash: 7dbebb345203a35dcd3a3c5a3135d203ca82c644cf35ddc1384ac17bb07f357b +Verifier_pp hash: ada8b1155d260dcd1868e33270c01fc777310da607acb4006b89493267f06a50 + +Bool.test_swap: +Constraints: 4 + +Bool.test_swap_optimized: +Constraints: 2 + +Bool.test_swap: +Proof size: 1.73 KB +Proof hash: 8fce6d614d26c45f0a011a8df30cd89e055a25ec8038d4ab92d6c48a4516e3e2 +Prover_pp hash: 7dbebb345203a35dcd3a3c5a3135d203ca82c644cf35ddc1384ac17bb07f357b +Verifier_pp hash: ada8b1155d260dcd1868e33270c01fc777310da607acb4006b89493267f06a50 + +Bool.test_swap: +Constraints: 8 + +Bool.test_swap_optimized: +Constraints: 5 + +Bool.test_swap: +Proof size: 1.73 KB +Proof hash: 96f520557ca88ec0cffedf8b1f440127e5261ae2bf9ae81daef8ecf2e5b508bb +Prover_pp hash: 432693b847d37dc41050120be3d45bed2b5f8e7586b032064c35a31b27de0ecd +Verifier_pp hash: 4eeb8d0c9e5354f5d21c19669cb0027cd180db0fa05eed69a597bfc84986de91 + +Bool.test_swap: +Constraints: 8 + +Bool.test_swap_optimized: +Constraints: 5 + +Bool.test_swap: +Proof size: 1.73 KB +Proof hash: 4d29491d789e1c5903ec219fe669cbedf0c623eec67e4bd983dc81c69bc7a50a +Prover_pp hash: 432693b847d37dc41050120be3d45bed2b5f8e7586b032064c35a31b27de0ecd +Verifier_pp hash: 4eeb8d0c9e5354f5d21c19669cb0027cd180db0fa05eed69a597bfc84986de91 + +Bool.test_swap: +Constraints: 7 + +Bool.test_swap_optimized: +Constraints: 3 + +Bool.test_swap: +Proof size: 1.73 KB +Proof hash: 2cec47261a02c2c0f2cdbc20398c79919afef3d12e0584d250f3345681ddde32 +Prover_pp hash: 6ebe4886e34f9f689b3417e5d257114b0454cb6aa0c1454b6b712097e1911d2f +Verifier_pp hash: ae891d0ab4bd5aab39d1d3ecc1b0d4d744c491618644039d465eced59df7d780 + +Bool.test_swap: +Constraints: 7 + +Bool.test_swap_optimized: +Constraints: 3 + +Bool.test_swap: +Proof size: 1.73 KB +Proof hash: b457c7814494d7f98ad9a43df9b47f1ff05bdf69b2134af8616d52416b6e3bd3 +Prover_pp hash: 6ebe4886e34f9f689b3417e5d257114b0454cb6aa0c1454b6b712097e1911d2f +Verifier_pp hash: ae891d0ab4bd5aab39d1d3ecc1b0d4d744c491618644039d465eced59df7d780 + +Bool.test_swap: +Constraints: 7 + +Bool.test_swap_optimized: +Constraints: 3 + +Bool.test_swap: +Proof size: 1.73 KB +Proof hash: 2cec47261a02c2c0f2cdbc20398c79919afef3d12e0584d250f3345681ddde32 +Prover_pp hash: 6ebe4886e34f9f689b3417e5d257114b0454cb6aa0c1454b6b712097e1911d2f +Verifier_pp hash: ae891d0ab4bd5aab39d1d3ecc1b0d4d744c491618644039d465eced59df7d780 + +Bool.test_swap: +Constraints: 7 + +Bool.test_swap_optimized: +Constraints: 3 + +Bool.test_swap: +Proof size: 1.73 KB +Proof hash: b457c7814494d7f98ad9a43df9b47f1ff05bdf69b2134af8616d52416b6e3bd3 +Prover_pp hash: 6ebe4886e34f9f689b3417e5d257114b0454cb6aa0c1454b6b712097e1911d2f +Verifier_pp hash: ae891d0ab4bd5aab39d1d3ecc1b0d4d744c491618644039d465eced59df7d780 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Proof size: 1.90 KB +Proof hash: d39b9c9f4df9b2d5d3fef34bb0be0b3be828f30e45814d7413d66f5dc6187030 +Prover_pp hash: bd36694e4e5d9c7bd0247bcd0b27249e9f17ecb9b371f80823093a3224cf2356 +Verifier_pp hash: d35467fbd7edaaa7c238115ff80f457d008db3878e07e8ef0cbde711f988cda7 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Proof size: 1.90 KB +Proof hash: 6a0ccf889bc6dc675f19d146294bca9c45c837687dcf21cbbf1048c6b2bad434 +Prover_pp hash: bd36694e4e5d9c7bd0247bcd0b27249e9f17ecb9b371f80823093a3224cf2356 +Verifier_pp hash: d35467fbd7edaaa7c238115ff80f457d008db3878e07e8ef0cbde711f988cda7 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Proof size: 1.90 KB +Proof hash: c151ccd9c3e7b6d8441ad601c6c4c9239379fa204801c1f4389e69305ddbcce9 +Prover_pp hash: bd36694e4e5d9c7bd0247bcd0b27249e9f17ecb9b371f80823093a3224cf2356 +Verifier_pp hash: d35467fbd7edaaa7c238115ff80f457d008db3878e07e8ef0cbde711f988cda7 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Proof size: 1.90 KB +Proof hash: 32b9ab8a0fe6ce49ab6dcfdada4b668f75bd5a2ce093c8b2660bcd5dc9c958a0 +Prover_pp hash: bd36694e4e5d9c7bd0247bcd0b27249e9f17ecb9b371f80823093a3224cf2356 +Verifier_pp hash: d35467fbd7edaaa7c238115ff80f457d008db3878e07e8ef0cbde711f988cda7 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Proof size: 1.90 KB +Proof hash: 70d0bd8a485992da7d8cc8b1130c850f80be0a88cce729bcb846924f5e5332d9 +Prover_pp hash: bd36694e4e5d9c7bd0247bcd0b27249e9f17ecb9b371f80823093a3224cf2356 +Verifier_pp hash: d35467fbd7edaaa7c238115ff80f457d008db3878e07e8ef0cbde711f988cda7 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Proof size: 1.90 KB +Proof hash: c14cb09af4f4f0a612444e31a896f0b17bb12e81cb41cc1bac89fab9f6c45752 +Prover_pp hash: bd36694e4e5d9c7bd0247bcd0b27249e9f17ecb9b371f80823093a3224cf2356 +Verifier_pp hash: d35467fbd7edaaa7c238115ff80f457d008db3878e07e8ef0cbde711f988cda7 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Proof size: 1.90 KB +Proof hash: c47907432f0c04382f16ed243abe4940d3b7baa822be56628df262d66f6b7359 +Prover_pp hash: bd36694e4e5d9c7bd0247bcd0b27249e9f17ecb9b371f80823093a3224cf2356 +Verifier_pp hash: d35467fbd7edaaa7c238115ff80f457d008db3878e07e8ef0cbde711f988cda7 + +Bool.test_full_adder: +Constraints: 12 + +Bool.test_full_adder_optimized: +Constraints: 9 + +Bool.test_full_adder: +Proof size: 1.90 KB +Proof hash: dddec349546c3bbd86399c5255a9c732ff30d73942a5334c03d908bf9f79e2a4 +Prover_pp hash: bd36694e4e5d9c7bd0247bcd0b27249e9f17ecb9b371f80823093a3224cf2356 +Verifier_pp hash: d35467fbd7edaaa7c238115ff80f457d008db3878e07e8ef0cbde711f988cda7 + +List.test_add_list: +Constraints: 5 + +List.test_add_list_optimized: +Constraints: 2 + +List.test_add_list: +Proof size: 1.80 KB +Proof hash: b00d6be535b3dd8e3ec416cdebe66cda4372af36e6466aaec40b28727797bf0e +Prover_pp hash: 32a48a3b34a116c0e21ce73fd3d8e33048b6ac33fc4a7fa72cdacf2211adcef5 +Verifier_pp hash: 64b3714a1b0daf0b0f5ba34084ae51ad360c4a2b89b7dd1a22cb26b7dad3a6a8 + +List.test_add_list: +Constraints: 6 + +List.test_add_list_optimized: +Constraints: 2 + +List.test_add_list: +Proof size: 1.86 KB +Proof hash: 9894b559cefbb5720551235170798024ab3bccbb396db58d9ed99a1d57d20543 +Prover_pp hash: 6f8d9011a82b56c38b4bb8f1eecaf522866b3ff03c22a3ef483d069d7e014485 +Verifier_pp hash: 782002b4304d23d61d7dd03681e90ab151a3655d77afedfc06fba2fd80016631 + +List.test_equal: +Constraints: 2 + +List.test_equal_optimized: +Constraints: 2 + +List.test_equal: +Proof size: 1.64 KB +Proof hash: 4e3cd57e7212704cb7130740759d84f001b3b00b1ae0b008aeecd292881c022c +Prover_pp hash: 7b32510f3bfb5e97a775ad9c53059424e552ac03a0946804b9d08b0ef023f376 +Verifier_pp hash: 1ee36b166fe2e2cd04d3a227b0ce77a7561d85b148d86f3830012fd76a669367 + +List.test_hd: +Constraints: 1 + +List.test_hd_optimized: +Constraints: 1 + +List.test_hd: +Proof size: 1.58 KB +Proof hash: 212a5be827aa3bbe83eb57e49b313d9e7fd0e42d332c9cac1d4e47b608cd9508 +Prover_pp hash: d9f7c372e2c99398f994305f9b53436002c853018d110ecb3f845f30a53a0503 +Verifier_pp hash: dfadae21d03bfd109d442a396a4618b5d919b35a12187de17c79b1e928e9b416 + +List.test_mul_list: +Constraints: 4 + +List.test_mul_list_optimized: +Constraints: 3 + +List.test_mul_list: +Proof size: 1.75 KB +Proof hash: 69f917358aeb0306077ccb0a5a550c4c5a2d0b7112c6222b205f224453720b13 +Prover_pp hash: 7e1c569084ad35f9513aafd9db70d0e3ccda649bf9edc7c225d5f0470f5ebc38 +Verifier_pp hash: 256b506797ef7bde13c72852f921556d414845e7b52ebae77b1259d257b48c11 + +List.test_mul_list: +Constraints: 5 + +List.test_mul_list_optimized: +Constraints: 4 + +List.test_mul_list: +Proof size: 1.75 KB +Proof hash: 5bda467f86f1774eea07b563baf175a8d153bb6ff8398d514c007f0dce3b5ae2 +Prover_pp hash: 03b38bd96159ab4560e74f8cf5c174226095c53f548c65dc59ff390d0e124f9f +Verifier_pp hash: 6fab9fa8761d02bc2375c47d371abbd3e509a214875e2c5dd2f2a3cf3d56b5ac + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Proof size: 1.90 KB +Proof hash: 174b13fb7d3485ba89dc8bf9253183ca0509117d7640579c0d6b5aa2fc849612 +Prover_pp hash: 5ae9ed8e7bed66a1c657872e2863c9672f14113feae81f55ff1c361f85c92909 +Verifier_pp hash: 6026022f3d915155e3706b61b92fdd85a792262828f9c37b00b7f523c79a3319 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Proof size: 1.90 KB +Proof hash: 2ae3a134527742aad33aeab4cddb9eb7f05d7baab5d7103d124e7d1e0038111d +Prover_pp hash: 5ae9ed8e7bed66a1c657872e2863c9672f14113feae81f55ff1c361f85c92909 +Verifier_pp hash: 6026022f3d915155e3706b61b92fdd85a792262828f9c37b00b7f523c79a3319 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Proof size: 1.90 KB +Proof hash: af5168d5eb2fa7f3698bb3128ca89155bc966ae9f272354bd45a3fea2503c1f8 +Prover_pp hash: 5ae9ed8e7bed66a1c657872e2863c9672f14113feae81f55ff1c361f85c92909 +Verifier_pp hash: 6026022f3d915155e3706b61b92fdd85a792262828f9c37b00b7f523c79a3319 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Proof size: 1.90 KB +Proof hash: 6e4c7697487d630f94094d4e072a5e16148ccfe1ce764160cc71b25fd0b957bf +Prover_pp hash: 5ae9ed8e7bed66a1c657872e2863c9672f14113feae81f55ff1c361f85c92909 +Verifier_pp hash: 6026022f3d915155e3706b61b92fdd85a792262828f9c37b00b7f523c79a3319 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Proof size: 1.90 KB +Proof hash: 9dbfba9c24b4ecabbc8de5ea3f1e1cbeb46c250c76b158627757a1c93b684f4d +Prover_pp hash: 5ae9ed8e7bed66a1c657872e2863c9672f14113feae81f55ff1c361f85c92909 +Verifier_pp hash: 6026022f3d915155e3706b61b92fdd85a792262828f9c37b00b7f523c79a3319 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Proof size: 1.90 KB +Proof hash: 8e6749166de2ef9d12d86a64b28825af858c1e8f6c168c6918e01e22a651b401 +Prover_pp hash: 5ae9ed8e7bed66a1c657872e2863c9672f14113feae81f55ff1c361f85c92909 +Verifier_pp hash: 6026022f3d915155e3706b61b92fdd85a792262828f9c37b00b7f523c79a3319 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Proof size: 1.90 KB +Proof hash: 36ad01b8d90c6c76a7edd42b76bb2d99ac5da7f17e5562069036f2e3a151796f +Prover_pp hash: 5ae9ed8e7bed66a1c657872e2863c9672f14113feae81f55ff1c361f85c92909 +Verifier_pp hash: 6026022f3d915155e3706b61b92fdd85a792262828f9c37b00b7f523c79a3319 + +Rest.test_full_adder: +Constraints: 12 + +Rest.test_full_adder_optimized: +Constraints: 9 + +Rest.test_full_adder: +Proof size: 1.90 KB +Proof hash: f50a507eb5f21bd00eea9557509b584ddc0cf43ec8b9314e0b1eb27f1076bdf0 +Prover_pp hash: 5ae9ed8e7bed66a1c657872e2863c9672f14113feae81f55ff1c361f85c92909 +Verifier_pp hash: 6026022f3d915155e3706b61b92fdd85a792262828f9c37b00b7f523c79a3319 + +Rest.test_scalar_of_bytes: +Constraints: 82 + +Rest.test_scalar_of_bytes_optimized: +Constraints: 45 + +Rest.test_scalar_of_bytes: +Proof size: 2.67 KB +Proof hash: 80c4b477b87a65182fbb4450177518b4ac5022c965781b6786b4e9e7c7e2d7ca +Prover_pp hash: 7c167a864fe2872f80420991ed963005a4e7fb356ae4e5cccac2f6b65a68cbb7 +Verifier_pp hash: 8adbd185277d3ade929c103571b5a0c551a1b56122de06f1a886eb46ae956483 + +Tuple.test_equal: +Constraints: 2 + +Tuple.test_equal_optimized: +Constraints: 2 + +Tuple.test_equal: +Proof size: 1.66 KB +Proof hash: 69c10f7452f49d1937cfa30742f592a19b72eb2dfb4cf07c7259ab1e114a1882 +Prover_pp hash: 99c7a8bf21ffd8b3490bdd49ae0ada3f2e221f357a9c6b2180465b9f741941ca +Verifier_pp hash: 00ed435e54620174b1e21b5bc79b3ee7ef2f9e7eef63d713ef4ad9334d9ebdc4 + +Tuple.test_point: +Constraints: 4 + +Tuple.test_point_optimized: +Constraints: 3 + +Tuple.test_point: +Proof size: 1.71 KB +Proof hash: 957c0ae9e1608aedfa2396613b48215c0bf5cac3df4e4e9236f6c2ba92412406 +Prover_pp hash: 2728c358e9b9280d9f2dcdae9844db64c5514424f6e17c872f31251fe645fc81 +Verifier_pp hash: abd5125a371deab8977f9caf35d63d5dfa7e97af12eb387b9f0bfc84edd84746 + +ECC.test_weierstrass_add: +Constraints: 12 + +ECC.test_weierstrass_add_optimized: +Constraints: 11 + +ECC.test_weierstrass_add: +Proof size: 2.41 KB +Proof hash: 840e8fdc8b90afbbfe5b9ffbe4b38d00c1b25c26d26872786d18464e57e06676 +Prover_pp hash: 295850e43286f4ee43266dc083a7353eb6f600313f2fc611c3b3f0757a5355d2 +Verifier_pp hash: b4e53f58b52535bf83be18fb0e248705d77164575dbad2eb7b951ba1078f9ae3 + +ECC.test_edwards_add: +Constraints: 12 + +ECC.test_edwards_add_optimized: +Constraints: 11 + +ECC.test_edwards_add: +Proof size: 2.29 KB +Proof hash: 8c25321e8a5e7cab18e851e3424daef08555fab79c1ff2a47f2aae3a58cac4b0 +Prover_pp hash: 1b8ba9322c28e4b75840e0f16d7a9f84766b44d114978b5b935e637087e9923b +Verifier_pp hash: f59d836f83e8bb32d2008d26522774f383869b2052f349e0484ecf98cb8d1aa4 + +Bytes.test_add: +Constraints: 69 + +Bytes.test_add_optimized: +Constraints: 54 + +Bytes.test_add: +Proof size: 1.77 KB +Proof hash: 4f9b6393c803e422626869f499ec218d0488507c59620a73c8239a77aa82e333 +Prover_pp hash: 853da2641506993d8aeee0296b42e4d7b12c858482812790a1c5a4c139505127 +Verifier_pp hash: 33b6f4b8544a8dc4468086b5f957ce701a159b7e7875e926ec23f07a6c6b14e2 + +Bytes.test_xor: +Constraints: 40 + +Bytes.test_xor_optimized: +Constraints: 25 + +Bytes.test_xor: +Proof size: 1.77 KB +Proof hash: 9bf77f78259926bcd66ae8b228e6b737fbf44a2b646fb905f8956560876cee35 +Prover_pp hash: a7c33e4630a51f59a88b9f4277aa0898bea905775021a6e478f7e5cda8a81288 +Verifier_pp hash: f22b43eda8c61d860265bc46c95c38239c9b3242cdbd75dea1ce9175e850d642 + +Bytes.blake: +Constraints: 160 + +Bytes.blake_optimized: +Constraints: 97 + +Bytes.blake: +Proof size: 1.70 KB +Proof hash: 5560e71c39b2831ff036207b5f3c4cc8aee40326ead67bc47c85149042d442cb +Prover_pp hash: c139ffb3fcc3af45f86de0b95789b49344a70106e78463ee350eacdda3d05167 +Verifier_pp hash: 96ef0313a674b356b5b721650d7a35348fd20dfdfc4c57501a62072b3dd01120 + +Bytes.test_ifthenelse: +Constraints: 41 + +Bytes.test_ifthenelse_optimized: +Constraints: 32 + +Bytes.test_ifthenelse: +Proof size: 1.82 KB +Proof hash: ff8ac90ee06ccd4f305a44becbb1788960bfec19686a93d88e30105b2d0b4661 +Prover_pp hash: c63a5e1d63589bab249dec681877ff666aadd36d1f1999f9b9a9abce9d959b2a +Verifier_pp hash: 72725dfa0e2f0cad318f63a326aa68d5f53c4fa51f56db8163a6ab95bd4f43d9 + +Bytes.test_ifthenelse: +Constraints: 41 + +Bytes.test_ifthenelse_optimized: +Constraints: 32 + +Bytes.test_ifthenelse: +Proof size: 1.82 KB +Proof hash: ca7e83cfb656c8d8739a52b12bb2ceab668b4b2c78f87b82818471c92ec09e90 +Prover_pp hash: c63a5e1d63589bab249dec681877ff666aadd36d1f1999f9b9a9abce9d959b2a +Verifier_pp hash: 72725dfa0e2f0cad318f63a326aa68d5f53c4fa51f56db8163a6ab95bd4f43d9 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: 9a5adc8f0da60570e6df16b613dc60a3750e01a53914359ba63b7152e7550d69 +Prover_pp hash: abf5d4e850764938dcfa4c518c810728021d44c8bd78209ae8a80ad220664f90 +Verifier_pp hash: db9b8c521517087acb52e0a83e1df6fd6723d82f0789977d0e3e7914293a8e29 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: 6db097a1b01f283e3608a9cfb525fbe6841bebc772fa81b3cea12e9c277ea37f +Prover_pp hash: f5eeb024e36351064e9ef4f8472362e4b08e960ec67f22acc348a39910683608 +Verifier_pp hash: 0dde21e74a20b45be729c7c11c90b38c7cd938bb91e4694d401e63d71ffc108f + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: 6656845aa61f22c100af09160648565e6bcbda26c7af83028f44baed5d69a6d6 +Prover_pp hash: 85c355d34cf4e5f8203404d2886b2fe81116b174655f5a214d5e2c35e1ad4fc0 +Verifier_pp hash: 1231cbbf4078b9515d3c433dec192587e972fe6ee1fd7bc4f83c81001fe55a99 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: 620053126f7dc6ee7a02b5c22b6c426c9b4776b8bc2707c91c35c8134e7e78e9 +Prover_pp hash: 283e8baf63fa7fb1f46daf1c9b4cc7c02986094d5b6df3724a47083470cdccc4 +Verifier_pp hash: 694cac401e9fe83103653d3f546ec8021007a482529bf6144967a13268f58601 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: d155d4033170e0097a9344a6f1eb00cbd572534af38d02936e8affedd005ea7a +Prover_pp hash: cf70bab73da228369bb291a11accd305d18458a77e780451a9461ecf0a13460f +Verifier_pp hash: 8dab8d2f380dc80d8a2966eaa07ad670fa4c5a36c4385efef0c7db2570220f9c + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: 15342a9dc47a52a701ed4c76ef2c8f464c64dcd7c424c20b13503c38a03d8119 +Prover_pp hash: c9ee71c6fa80942becf5e13a50f0060b3cce85e1542ea99c0d8110e86b59f837 +Verifier_pp hash: e75cf6d0dc1d7a6fc1315aa801d94e3241ce648ccb686b12fab5717534b9cd88 + +Bytes.test_rotate: +Constraints: 24 + +Bytes.test_rotate_optimized: +Constraints: 16 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: 99c0e7a53bab84f34ab23041fd55f9bd2f9749fcac2e6f0869acef123e0e108b +Prover_pp hash: 9285e40a91663cff5839cf197279039a9bc0388abe17a171e515ebaca0cec30a +Verifier_pp hash: 7d4af2735626a4bce260b258f7298402978eaa368c9525b8dd396b6401665b84 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: 29a9704017f6d649d3efc53ffe5465ab1d5abdda88598f9eaedd16ff0c9686fe +Prover_pp hash: c5349d9ce550d3b251cf90bd351c99de01ef09abf5daffa2a7f9118ba9fa2778 +Verifier_pp hash: 2e1a3df859ae63ffb1820026c471f9eec56eb8fa07b09a34e61a3b37c535f543 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: cd666f213a3423f148b915007437691d22745c5efd132241b8d2c5a375ac83e3 +Prover_pp hash: 2b81203ec153dcc94b8d3f6413fc4dda027a1f350d0e1e25206d4c4057de4a08 +Verifier_pp hash: 830d9a160c0a6c51e96ecd719b98482b79df5a9dab80ba33e8b8426859b4d5b3 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: 1057883d7c63f330049cf815e28f1bed01583bb9ce378516fa4152afb55b1064 +Prover_pp hash: 21bed1b2d78be951fed9c4d21ef815d6dcbed31dd28a0ce387440363e6c1c752 +Verifier_pp hash: 84c7c0849ca6a130c9bc6af97d6ebbd5b6406899ae1c7fc2dde2713c13cec948 + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: 68cd88437a6b749016c49a47bbbda21767f96672d10c28bc2984627bd2d72aef +Prover_pp hash: 05c2d1b0c46a5023babfdff7ab1639c836060455edc77b1dc9f8c2c086370b4e +Verifier_pp hash: 4be2c4a9d8b4712bb4094bc89d26647560b003e92ddd10ba4c4a10eddd027d8c + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: f57f4ab105ce98e09c3059cd861b5cba2f652cb1ff0ee38b8c7e3305e8887359 +Prover_pp hash: 5245044c63e0798f668196f1c90141c946d23bf2ea1c5c449d069a2135ddbc49 +Verifier_pp hash: cbd0108ee528559ce865efa4b430bd8dd6b6fc81fe302fd42f3ac02a77c892df + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: 3279c30fb6df37c424adbb77f16c2137293f13cb08aa6cb44c831ab889468321 +Prover_pp hash: 806ca3907a7a7db4eab10df6896f8a9c794180474d13ef28bc87c125fe44e666 +Verifier_pp hash: 5df1827cac6c8264c294fc37c83212c0b77b9e1b754e82f91b0bfd113722e9bd + +Bytes.test_rotate: +Constraints: 48 + +Bytes.test_rotate_optimized: +Constraints: 32 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: b394c6e374488e6266583b4772603c86453f4b3375067a6983c3cb8d1f791721 +Prover_pp hash: 6cf22ea672a0c38340f9240008dcc071cdad06f86589623b68433acb9c7c0383 +Verifier_pp hash: 3d055df104907367b10e4239e8bf25009e8501c6c7a695a33ca4e3c7655ec99b + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: fc8c5aa3b2985a5962be54a05ff3cc84b2fa84c6f2542bfc2516e4da6d4664fa +Prover_pp hash: 3f9751002b3bc22790ab86fc4bfeb9128aaac35ca2ff56fbc92f98c33a021dfc +Verifier_pp hash: 779c9a6c43df6bb6c44a827f613621632bb2cce7b39a659b43a2d8c6cbbc85c8 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: 3164f9d8d02ff8b65a59868647027cdee85b8bc27d31b43f9192752f296e9018 +Prover_pp hash: 5feb166784ed04ca5cb54140cca03bdd6ee67ceba87a26c6ef99f2fbd4145057 +Verifier_pp hash: 252a89b723bfbfa4009babf64327ecf412508826ab5a6b9e92db5511cc4077bc + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: e064ecec79a544123d6fe41cec633f945d9f8dbe897064d81b76048748bde6d1 +Prover_pp hash: 348be9ba260fb6270eeb8a645cb0e30c6c685ba6fe234e8d4c58002c94e5299c +Verifier_pp hash: 7c71915654b8cf7bd0be349919ca6b23ee0f5d477558739cc0804a47fb4ef49f + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: 8bec6de3d0e6950ef73ee9917a58e0675cf2d1a3edbbd4eed31008b62ad84406 +Prover_pp hash: b784a13bcf3901120bccd7e09ede4672de386dcf11b00383f5a535d57dd55919 +Verifier_pp hash: da43230142b82c795e0c9951d66a29e94c00591e7145a4bd62a00671e484fbcc + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: 86ced16e373bf55158b2ba05ece5740df9db75727059aa5d58411833d9e94204 +Prover_pp hash: ec1e18a9290998fbeb8865226327245824f62135a44aed915a5840f5e6b7cb19 +Verifier_pp hash: 8618fd8439874cb59687acd82c4d30420b896c26cc219e30a58e8ff7f56a9eb1 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: e7f31efa17d2db9228756c69beb5dcb6b562ebb7454a9ffc67fbca0634a95c47 +Prover_pp hash: a4dbaaec73fe935106f55cab9678b5ecd4b70a87c722fbde7b98d4ba3b0897a3 +Verifier_pp hash: 13aa6018e9ff6bf07ac9692746721da337325926191583a533662ae68425f4c2 + +Bytes.test_rotate: +Constraints: 72 + +Bytes.test_rotate_optimized: +Constraints: 48 + +Bytes.test_rotate: +Proof size: 1.73 KB +Proof hash: c6e2e44fe7a2c66aa7ea9c204ee1ffab994dc21051fa6564cf9f290d73bb2536 +Prover_pp hash: cf7cc9671f11836a06f4907b5afce74ece715680ebb49163ac68e0b3a6090d76 +Verifier_pp hash: a6cb3f3ff4226b803643dc71bb932fa02d0d9fcc356d8c6b789f9e29d91522cc + +Blake.test_mixing: +Constraints: 2638 + +Blake.test_mixing_optimized: +Constraints: 1998 + +Blake.test_compression: +Constraints: 87808 + +Blake.test_compression_optimized: +Constraints: 87264 + +Blake.test_blake2s: +Constraints: 174377 + +Blake.test_blake2s_optimized: +Constraints: 174089 + +Blake.test_mixing: +Constraints: 2638 + +Blake.test_mixing_optimized: +Constraints: 1998 + +Blake.test_mixing: +Proof size: 1.84 KB +Proof hash: aa06a83366de786aeef5f9e19661226b3798026bada6931cd8a1f673a18cc1d2 +Prover_pp hash: 7ecc53a057a1d375457dcc717ddf2a31332358f8565440874f791a582ec2a82f +Verifier_pp hash: 84cba29d1fb0d7a9c922b455e951e2eee2b95329c8d140abbcad85bdf4134cb3 + +Blake.test_compression: +Constraints: 87808 + +Blake.test_compression_optimized: +Constraints: 87264 + +Blake.test_compression: +Proof size: 2.00 KB +Proof hash: c4ac9322d3b379e20e84ccb25f2b8d56fb8513ba9f8a00b50949c9f39ef85c4f +Prover_pp hash: f0e1305f522fcca241a28628ced30c90ef4d8d7dbf05df7209ad41dca58df1e0 +Verifier_pp hash: d513d4fbe2386f687bbb924dbf6cdf08fcdde59d6b9527469fc036ead5f11c4f + +Blake.test_blake2s: +Constraints: 174377 + +Blake.test_blake2s_optimized: +Constraints: 174089 + +Blake.test_blake2s: +Proof size: 1.91 KB +Proof hash: 76588830be856b7991ad7e2f5ae69e661603597517f5b6484dedc70420fc161a +Prover_pp hash: 08cebe70812ea314218c5d886f3e196815048c60cb76fe92ae3eb637a1d16428 +Verifier_pp hash: 962822cf330eeeea89be302b8bb7e0529591d33de04c54da4937cf7d0f51671e + +Poseidon.test_poseidon: +Constraints: 273 + +Poseidon.test_poseidon_optimized: +Constraints: 118 + +Poseidon.test_poseidon: +Constraints: 804 + +Poseidon.test_poseidon_optimized: +Constraints: 340 + +Poseidon.test_poseidon.fixed_length: +Constraints: 273 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 118 + +Poseidon.test_poseidon.fixed_length: +Constraints: 539 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 229 + +Poseidon.test_poseidon: +Constraints: 975 + +Poseidon.test_poseidon_optimized: +Constraints: 298 + +Poseidon.test_poseidon: +Constraints: 1991 + +Poseidon.test_poseidon_optimized: +Constraints: 603 + +Poseidon.test_poseidon.fixed_length: +Constraints: 975 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 298 + +Poseidon.test_poseidon.fixed_length: +Constraints: 991 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 304 + +Poseidon.test_poseidon: +Constraints: 611 + +Poseidon.test_poseidon_optimized: +Constraints: 190 + +Poseidon.test_poseidon: +Constraints: 1818 + +Poseidon.test_poseidon_optimized: +Constraints: 556 + +Poseidon.test_poseidon.fixed_length: +Constraints: 611 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 190 + +Poseidon.test_poseidon.fixed_length: +Constraints: 1215 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 373 + +Poseidon.test_poseidon: +Constraints: 273 + +Poseidon.test_poseidon_optimized: +Constraints: 118 + +Poseidon.test_poseidon: +Proof size: 2.63 KB +Proof hash: 1876030e98b77e6e7c71635aa3b9c8fe3ba643ba9f320e0f048662fca966f6de +Prover_pp hash: d2121ad63584138f22972250adb45aa8e8578b3f6a66c7655ae6b51c26f0b486 +Verifier_pp hash: 79a6f2d5cd304d1bf518b95606babdc912a6ed44cd2c98a6c668c309d145d3b9 + +Poseidon.test_poseidon: +Constraints: 804 + +Poseidon.test_poseidon_optimized: +Constraints: 340 + +Poseidon.test_poseidon: +Proof size: 2.63 KB +Proof hash: eec26f0b4b5e24d02d1a535c9249e464ba21aa7b4e5fb90b6e73b78fe6916add +Prover_pp hash: ec2047cf4561b3c5f08f668016db9513e53e5049e960f0451a9842c5281f125e +Verifier_pp hash: 192b220503a6b1015cb1133aaac4f7993b8da7360ab66c700a4a242d366e26d9 + +Poseidon.test_poseidon.fixed_length: +Constraints: 273 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 118 + +Poseidon.test_poseidon.fixed_length: +Proof size: 3.08 KB +Proof hash: e085c93e960e7f252fbe910ec1280271ad4456c92549500b084e0ea5b483dbc2 +Prover_pp hash: 234e13c2e9b8186b11fdbca59c2e0f793942c57fcb3c5148748b142916158e22 +Verifier_pp hash: c0b196e6ed78ad169c97b899b4756f141653071372da9ec0bca6f5f92fb81d66 + +Poseidon.test_poseidon.fixed_length: +Constraints: 539 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 229 + +Poseidon.test_poseidon.fixed_length: +Proof size: 3.08 KB +Proof hash: fd2c11c4bab3a7001e89e96c1a67112e60351d458f10921cbe4a5fa8c402dbf2 +Prover_pp hash: 5e22c76c424e5f4b17c784746bd0fbaf8ab6baf6e5b0720a033d606f296dc3c0 +Verifier_pp hash: f48f831763e4723c92053e63695bd069133436f9b5c774532c97e5ce87324876 + +Poseidon.test_poseidon: +Constraints: 975 + +Poseidon.test_poseidon_optimized: +Constraints: 298 + +Poseidon.test_poseidon: +Proof size: 2.75 KB +Proof hash: 08068b8c527558704762cef9d559bafa7774c3d98731f636918664d169cb4ad6 +Prover_pp hash: d2dd28eb4f0188ccabfdc8e21be958795f8ca4769b7da3bc4e25ffa5bfa1f2b1 +Verifier_pp hash: 7aa93acd50497227c13bf8adfdb337ba9068898f7531471a3bdf208873be5502 + +Poseidon.test_poseidon: +Constraints: 1991 + +Poseidon.test_poseidon_optimized: +Constraints: 603 + +Poseidon.test_poseidon: +Proof size: 2.75 KB +Proof hash: 884d91efaa2dd445b621fdf52cc4d8650ce0a7106589aca1132e31ab2509f5dc +Prover_pp hash: b47d33d67eebdbb1985858622a15386f00f06ce3cc700396e1fda5128cbcf7c2 +Verifier_pp hash: 69e9937d63fe7ac694f030da168df082e2d974baaa037be313f8d733648125c8 + +Poseidon.test_poseidon.fixed_length: +Constraints: 975 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 298 + +Poseidon.test_poseidon.fixed_length: +Proof size: 3.22 KB +Proof hash: 5fb170660b98ba29a6ecbe480b36d35246400a1af3dc53e590cac768821880b7 +Prover_pp hash: 28720fd90b0d1ad5685dd375d911f76235843f7d4476bc812290c59b1a3bc203 +Verifier_pp hash: 992872b041bc2d17418aba8f57c168241378c14247b24c3bd51d3490b3a79dfe + +Poseidon.test_poseidon.fixed_length: +Constraints: 991 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 304 + +Poseidon.test_poseidon.fixed_length: +Proof size: 3.22 KB +Proof hash: 7bec10149a1f9efc6d147055422b4690220981db5b74c9a1881cf3866b1c4be2 +Prover_pp hash: 89eb07ae5019d4d589375eae13349dafdcf4d66c113b788ad900df4b17fbb1e3 +Verifier_pp hash: fa8cf71c35f60ab52b9515bde3510f9c4bb0bc9c6302f9fc78664ba26aa1797e + +Poseidon.test_poseidon: +Constraints: 611 + +Poseidon.test_poseidon_optimized: +Constraints: 190 + +Poseidon.test_poseidon: +Proof size: 2.52 KB +Proof hash: acb88122f0d63c3d4c28c4e17d86bb81ed90156b24e933fa9bd30f89af3de336 +Prover_pp hash: 51fdbb287dc63c51d1269e54bf165738a0cd3b422bf02ff3bdea5bf1888125f9 +Verifier_pp hash: f8ba090b27757a20e7652eea18904f45fb8c91e1f22b7930e23467bc88e852b0 + +Poseidon.test_poseidon: +Constraints: 1818 + +Poseidon.test_poseidon_optimized: +Constraints: 556 + +Poseidon.test_poseidon: +Proof size: 2.52 KB +Proof hash: 218b17076be03a74a069d0bfec5fb09e333e3a8334cf606eccebd35c7acb79fd +Prover_pp hash: bac89179af0ecaf73704e20f8b8fbdd1081c28f2ec669cb435b5d628459ff728 +Verifier_pp hash: 26e83a71c7d3dc412d9f2ceac360177ab0707432a36d2c7ea9611fc5b2d6d6ba + +Poseidon.test_poseidon.fixed_length: +Constraints: 611 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 190 + +Poseidon.test_poseidon.fixed_length: +Proof size: 2.94 KB +Proof hash: 3edf0bcb08926e1959f8e7f52526ea6dc4530359f9366675199d2c9ce2616ca2 +Prover_pp hash: e208ebf1c0f5606277c0cfd7b4259471a2c4888104a130faa19c8fbece72dc78 +Verifier_pp hash: b368816312caa6edf8d40397a7a4afb4c475aebee127292e495c5b3157a371d5 + +Poseidon.test_poseidon.fixed_length: +Constraints: 1215 + +Poseidon.test_poseidon.fixed_length_optimized: +Constraints: 373 + +Poseidon.test_poseidon.fixed_length: +Proof size: 2.94 KB +Proof hash: 32ef9683c984882d8d3958c27ae2808ee9e0da5ee63baf3581788060323d92a0 +Prover_pp hash: 6520df771576874050913e67102f442964ff7c6a6fd03182d289405c948f1f7c +Verifier_pp hash: bcbfe74ce0f417530de0a480f5f77723e35d66f6470f53d5ad693dae165ea2c5 + +Anemoi.test_round.valid: +Constraints: 20 + +Anemoi.test_round.valid_optimized: +Constraints: 18 + +Anemoi.test_round.valid: +Constraints: 20 + +Anemoi.test_round.valid_optimized: +Constraints: 18 + +Anemoi.test_compress.valid: +Constraints: 90 + +Anemoi.test_compress.valid_optimized: +Constraints: 85 + +Anemoi.test_compress.valid: +Constraints: 90 + +Anemoi.test_compress.valid_optimized: +Constraints: 85 + +Anemoi.test_double_round.valid: +Constraints: 21 + +Anemoi.test_double_round.valid_optimized: +Constraints: 19 + +Anemoi.test_double_round.valid: +Constraints: 21 + +Anemoi.test_double_round.valid_optimized: +Constraints: 19 + +Anemoi.test_compress_two.valid: +Constraints: 63 + +Anemoi.test_compress_two.valid_optimized: +Constraints: 58 + +Anemoi.test_compress_two.valid: +Constraints: 63 + +Anemoi.test_compress_two.valid_optimized: +Constraints: 58 + +Anemoi.test_compress.valid: +Constraints: 32 + +Anemoi.test_compress.valid_optimized: +Constraints: 17 + +Anemoi.test_compress.valid: +Constraints: 78 + +Anemoi.test_compress.valid_optimized: +Constraints: 39 + +Anemoi.test_round.valid: +Constraints: 20 + +Anemoi.test_round.valid_optimized: +Constraints: 18 + +Anemoi.test_round.valid: +Proof size: 2.43 KB +Proof hash: 7ea9e14b43677572a41f61a1d1560d780299a97ebd49a6128eca0f8c602d6b02 +Prover_pp hash: c28543fc000fc14e80ae33e73b208fd6dcc42049595e09858034b81ce793bb0b +Verifier_pp hash: 97286a3568e81ab861677be154b350fd51df97ea784d07ea539d7e85a3b06cf1 + +Anemoi.test_round.valid: +Constraints: 20 + +Anemoi.test_round.valid_optimized: +Constraints: 18 + +Anemoi.test_round.valid: +Proof size: 2.43 KB +Proof hash: d4286f8e82869eb73a2cfde279b3474c86467dace423bb01bad85fac2806b4ef +Prover_pp hash: c28543fc000fc14e80ae33e73b208fd6dcc42049595e09858034b81ce793bb0b +Verifier_pp hash: 97286a3568e81ab861677be154b350fd51df97ea784d07ea539d7e85a3b06cf1 + +Anemoi.test_compress.valid: +Constraints: 90 + +Anemoi.test_compress.valid_optimized: +Constraints: 85 + +Anemoi.test_compress.valid: +Proof size: 2.71 KB +Proof hash: ac2e257b8169b1f7631ad769662a2e8bb9eb73b055b918c9d7be30582b5b6a5b +Prover_pp hash: 6186811375351a60ee00358a144cb4fb43770d87593c0d9d6ac32111b3d5bf7f +Verifier_pp hash: a09fec9495601d3862bc5e685fddb04728c1c00a2410170091c7a609e497e693 + +Anemoi.test_compress.valid: +Constraints: 90 + +Anemoi.test_compress.valid_optimized: +Constraints: 85 + +Anemoi.test_compress.valid: +Proof size: 2.71 KB +Proof hash: b5bcb910b09dbee192fff0571dd6f72f5fa91d53fdced578dd0bb3494b23a3fd +Prover_pp hash: 6186811375351a60ee00358a144cb4fb43770d87593c0d9d6ac32111b3d5bf7f +Verifier_pp hash: a09fec9495601d3862bc5e685fddb04728c1c00a2410170091c7a609e497e693 + +Anemoi.test_double_round.valid: +Constraints: 21 + +Anemoi.test_double_round.valid_optimized: +Constraints: 19 + +Anemoi.test_double_round.valid: +Proof size: 2.78 KB +Proof hash: 68960830b67250e960b8143d3f8ac48c424b124bbb68c391876d45c97e8e0b0f +Prover_pp hash: 6bf5ff7bb37034fda40d8765205f3626f1745bf190392b1707169e53079ecb09 +Verifier_pp hash: 1d4cfb56faf9dffbdb0dc788ef5391128ead9a55b5b58eb2b7ab1298f7c88b46 + +Anemoi.test_double_round.valid: +Constraints: 21 + +Anemoi.test_double_round.valid_optimized: +Constraints: 19 + +Anemoi.test_double_round.valid: +Proof size: 2.78 KB +Proof hash: 12b76e1d4c03989b02d84cc7531e126f9f3f3b5260342bd2cd7ee68bbd2e9bd8 +Prover_pp hash: 6bf5ff7bb37034fda40d8765205f3626f1745bf190392b1707169e53079ecb09 +Verifier_pp hash: 1d4cfb56faf9dffbdb0dc788ef5391128ead9a55b5b58eb2b7ab1298f7c88b46 + +Anemoi.test_compress_two.valid: +Constraints: 63 + +Anemoi.test_compress_two.valid_optimized: +Constraints: 58 + +Anemoi.test_compress_two.valid: +Proof size: 3.04 KB +Proof hash: 508573549dbda784bc80ff114d7d725cc60dfb67927bc593e640ce0c26f33158 +Prover_pp hash: 442a09c4978b7747d50f52ab9f7837f9d16b4b65b130637ce94639b4283607bb +Verifier_pp hash: 105ed6461c897c498383ec2d946eb620466576ee4d3e4adc6742f131de28ee8e + +Anemoi.test_compress_two.valid: +Constraints: 63 + +Anemoi.test_compress_two.valid_optimized: +Constraints: 58 + +Anemoi.test_compress_two.valid: +Proof size: 3.04 KB +Proof hash: 4bec55ee8203bc600a75064bc86c18ca544d77f5a51faba757b6cc452422ef3b +Prover_pp hash: 442a09c4978b7747d50f52ab9f7837f9d16b4b65b130637ce94639b4283607bb +Verifier_pp hash: 105ed6461c897c498383ec2d946eb620466576ee4d3e4adc6742f131de28ee8e + +Anemoi.test_compress.valid: +Constraints: 32 + +Anemoi.test_compress.valid_optimized: +Constraints: 17 + +Anemoi.test_compress.valid: +Proof size: 2.90 KB +Proof hash: 885f44cf0f42b1d8882f5c7f2d887dde27498981d36ba7e17735d33cc4fc543d +Prover_pp hash: e7a4a0183765bd7de648add5d9ffccd4c70d0e7f76043461ef1a69dfd08d3a06 +Verifier_pp hash: 5297ac27c009e2195a5226f4fd7870f2af40ec143179ebc9c603cc83eb844dc9 + +Anemoi.test_compress.valid: +Constraints: 78 + +Anemoi.test_compress.valid_optimized: +Constraints: 39 + +Anemoi.test_compress.valid: +Proof size: 2.90 KB +Proof hash: b3d45f6fb13c9de28d0e256dff7cde45b61c1059d7ce5f5149e4a18cdcff9cb7 +Prover_pp hash: 25a3d52e4a6b118c0264a3d6ed325e47fbe8fa8fa54071d1159182de0f79bb48 +Verifier_pp hash: e67fb3e46c7d2f71373fa1367a823d4b259c3fda47a8f6d9eb6e674351df4c9f + +Enum.test_switch: +Constraints: 16 + +Enum.test_switch_optimized: +Constraints: 12 + +Enum.test_switch: +Constraints: 16 + +Enum.test_switch_optimized: +Constraints: 12 + +Enum.test_switch: +Constraints: 16 + +Enum.test_switch_optimized: +Constraints: 12 + +Enum.test_switch: +Constraints: 16 + +Enum.test_switch_optimized: +Constraints: 12 + +Enum.test_switch: +Constraints: 16 + +Enum.test_switch_optimized: +Constraints: 12 + +Enum.test_switch: +Constraints: 16 + +Enum.test_switch_optimized: +Constraints: 12 + +Enum.test_switch: +Proof size: 1.92 KB +Proof hash: 2523b4827573f2d2e9f760ccb2ec17c53488ca2f09636fc5a132944c09f811a3 +Prover_pp hash: 5a3b240c7e2ad6cc6102325f754d10759463da1322adfd0510c34ba6c2b0e01b +Verifier_pp hash: 00f744470cd62587344f7ccaf14b3bb7c88ad700f200c4e291f484033cc928f8 + +Enum.test_switch: +Constraints: 16 + +Enum.test_switch_optimized: +Constraints: 12 + +Enum.test_switch: +Proof size: 1.92 KB +Proof hash: 1c95bc1501ea4e121fd40ff017216cd87a6c4478148753df37071995f6805697 +Prover_pp hash: 5a3b240c7e2ad6cc6102325f754d10759463da1322adfd0510c34ba6c2b0e01b +Verifier_pp hash: 00f744470cd62587344f7ccaf14b3bb7c88ad700f200c4e291f484033cc928f8 + +Enum.test_switch: +Constraints: 16 + +Enum.test_switch_optimized: +Constraints: 12 + +Enum.test_switch: +Proof size: 1.92 KB +Proof hash: d4def6cfa69d29a274fc5f6f51aacd3d56bde902e33b10fef084a3a6ded73dc4 +Prover_pp hash: 5a3b240c7e2ad6cc6102325f754d10759463da1322adfd0510c34ba6c2b0e01b +Verifier_pp hash: 00f744470cd62587344f7ccaf14b3bb7c88ad700f200c4e291f484033cc928f8 + +Enum.test_switch: +Constraints: 16 + +Enum.test_switch_optimized: +Constraints: 12 + +Enum.test_switch: +Proof size: 1.92 KB +Proof hash: 31a8bdcd48b70571d5bf049f0bbce57a3ecce55821030b51090d98e2cd4a1637 +Prover_pp hash: 5a3b240c7e2ad6cc6102325f754d10759463da1322adfd0510c34ba6c2b0e01b +Verifier_pp hash: 00f744470cd62587344f7ccaf14b3bb7c88ad700f200c4e291f484033cc928f8 + +Enum.test_switch: +Constraints: 16 + +Enum.test_switch_optimized: +Constraints: 12 + +Enum.test_switch: +Proof size: 1.92 KB +Proof hash: d6822cc729fd957d3366d379a4f2184e2f079933a3f8701f4d15b86ca20df9da +Prover_pp hash: 5a3b240c7e2ad6cc6102325f754d10759463da1322adfd0510c34ba6c2b0e01b +Verifier_pp hash: 00f744470cd62587344f7ccaf14b3bb7c88ad700f200c4e291f484033cc928f8 + +Schnorr.test_circuit_verify: +Constraints: 2381 + +Schnorr.test_circuit_verify_optimized: +Constraints: 881 + +Schnorr.test_circuit_verify: +Constraints: 2381 + +Schnorr.test_circuit_verify_optimized: +Constraints: 881 + +Schnorr.test_circuit_verify: +Proof size: 3.35 KB +Proof hash: 6ff6b0c6f5987b646acc3992c4e2b2d3d099d52a25d5356a1daf5530cb06e454 +Prover_pp hash: 39d5b3529bf820f5388dded850f205ab5b893d4f6aa9f9b48e2660960de20b90 +Verifier_pp hash: a7caf589d02054b934bbf623f7508d3e3daf46f00f752b261b513222de0ebca0 + +Merkle.test_merkle_pos: +Constraints: 1945 + +Merkle.test_merkle_pos_optimized: +Constraints: 593 + +Merkle.test_merkle_pos: +Constraints: 1945 + +Merkle.test_merkle_pos_optimized: +Constraints: 593 + +Merkle.test_merkle_pos: +Constraints: 1945 + +Merkle.test_merkle_pos_optimized: +Constraints: 593 + +Merkle.test_merkle_pos: +Constraints: 1945 + +Merkle.test_merkle_pos_optimized: +Constraints: 593 + +Merkle.test_merkle_pos: +Constraints: 1945 + +Merkle.test_merkle_pos_optimized: +Constraints: 593 + +Merkle.test_merkle_pos: +Proof size: 2.81 KB +Proof hash: aeb73a3837cf0a52708c62fff61840a7a530df1386948857a46e467ce7eb114b +Prover_pp hash: 7fb2e7fe5b3a35a7d21da4e0e10b4fe789efee381c37c28850c9f6e45f7cfdaf +Verifier_pp hash: c8ae1cf09fca2170d1e17ac33d590d0ab7231479bb3ab2bf78a0f0fb22192734 + +Merkle.test_merkle_pos: +Constraints: 1945 + +Merkle.test_merkle_pos_optimized: +Constraints: 593 + +Merkle.test_merkle_pos: +Proof size: 2.81 KB +Proof hash: 57804b86d659e5247e3d9c710e2541e6a2d316100ed0e215aff4bacb7e6b6fee +Prover_pp hash: 7fb2e7fe5b3a35a7d21da4e0e10b4fe789efee381c37c28850c9f6e45f7cfdaf +Verifier_pp hash: c8ae1cf09fca2170d1e17ac33d590d0ab7231479bb3ab2bf78a0f0fb22192734 + +Merkle.test_merkle_pos: +Constraints: 1945 + +Merkle.test_merkle_pos_optimized: +Constraints: 593 + +Merkle.test_merkle_pos: +Proof size: 2.81 KB +Proof hash: de6050577b72e38d3635ddf22b290f74bbdfcb7cde8e3f44321c48a24c489f94 +Prover_pp hash: 7fb2e7fe5b3a35a7d21da4e0e10b4fe789efee381c37c28850c9f6e45f7cfdaf +Verifier_pp hash: c8ae1cf09fca2170d1e17ac33d590d0ab7231479bb3ab2bf78a0f0fb22192734 + +Merkle.test_merkle_pos: +Constraints: 1945 + +Merkle.test_merkle_pos_optimized: +Constraints: 593 + +Merkle.test_merkle_pos: +Proof size: 2.81 KB +Proof hash: 63a8e260e1189da2db0090aae8780ad61994ab8e0eebcdb74d6af8339fb7d057 +Prover_pp hash: 7fb2e7fe5b3a35a7d21da4e0e10b4fe789efee381c37c28850c9f6e45f7cfdaf +Verifier_pp hash: c8ae1cf09fca2170d1e17ac33d590d0ab7231479bb3ab2bf78a0f0fb22192734 + +MerkleNarity.test_merkle_pos: +Constraints: 5030 + +MerkleNarity.test_merkle_pos_optimized: +Constraints: 1604 + +MerkleNarity.test_merkle_pos: +Constraints: 5030 + +MerkleNarity.test_merkle_pos_optimized: +Constraints: 1604 + +MerkleNarity.test_merkle_pos: +Proof size: 3.03 KB +Proof hash: 6d604e1be0b81121c92f4c187a1b249579684d8f075ccad189882bcc083cd7e3 +Prover_pp hash: 4fc82105467707c3047d114d167af916a89a5adf85cdf7a285b47102488ff7a2 +Verifier_pp hash: 1d636cc492f8d1f44944014531354eee207b6d6355555c3ee36362378bb915e5 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_scalar_mul: +Constraints: 6 + +Edwards.test_scalar_mul_optimized: +Constraints: 3 + +Edwards.test_scalar_mul: +Constraints: 6 + +Edwards.test_scalar_mul_optimized: +Constraints: 3 + +Edwards.test_scalar_mul: +Constraints: 11 + +Edwards.test_scalar_mul_optimized: +Constraints: 5 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_multi_scalar_mul: +Constraints: 2033 + +Edwards.test_multi_scalar_mul_optimized: +Constraints: 763 + +Edwards.test_multi_scalar_mul: +Constraints: 2795 + +Edwards.test_multi_scalar_mul_optimized: +Constraints: 1017 + +Edwards.test_multi_scalar_mul: +Constraints: 3557 + +Edwards.test_multi_scalar_mul_optimized: +Constraints: 1271 + +Edwards.test_multi_scalar_mul: +Constraints: 4319 + +Edwards.test_multi_scalar_mul_optimized: +Constraints: 1525 + +Edwards.test_multi_scalar_mul: +Constraints: 5081 + +Edwards.test_multi_scalar_mul_optimized: +Constraints: 1779 + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Proof size: 1.97 KB +Proof hash: 751429fec181a6a915acaf8e8e415798c74546f0f9ff6f810d31e74fe3ad1cd8 +Prover_pp hash: 3e557f14f170632c1a9108ea2a14cf3e17867b39c4200748be39b8365cd4d6a7 +Verifier_pp hash: e80f39b8ad26ff071afc2092527b81bbec517f16a05b38e3e9788667cce09a0d + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Proof size: 1.97 KB +Proof hash: 18bec626d1e671e4851004ca1fd7eba2fe3dc93467787b3d62ae3ac64585afc1 +Prover_pp hash: 3e557f14f170632c1a9108ea2a14cf3e17867b39c4200748be39b8365cd4d6a7 +Verifier_pp hash: e80f39b8ad26ff071afc2092527b81bbec517f16a05b38e3e9788667cce09a0d + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Proof size: 1.97 KB +Proof hash: 06be664b0a1d5c76d37d8acc17fdb21c7b75fc20f27d567b9087445b0cc56202 +Prover_pp hash: 3e557f14f170632c1a9108ea2a14cf3e17867b39c4200748be39b8365cd4d6a7 +Verifier_pp hash: e80f39b8ad26ff071afc2092527b81bbec517f16a05b38e3e9788667cce09a0d + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Proof size: 1.97 KB +Proof hash: d912be8a050955e7b860bc057a373c482a12265d58314706ec002ab15f1c5a1a +Prover_pp hash: 3e557f14f170632c1a9108ea2a14cf3e17867b39c4200748be39b8365cd4d6a7 +Verifier_pp hash: e80f39b8ad26ff071afc2092527b81bbec517f16a05b38e3e9788667cce09a0d + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Proof size: 1.97 KB +Proof hash: 7974fd9b7b53f0fb57d39fe29ef42a66e093691c810ef4748ad7adcdd5f10d6b +Prover_pp hash: 3e557f14f170632c1a9108ea2a14cf3e17867b39c4200748be39b8365cd4d6a7 +Verifier_pp hash: e80f39b8ad26ff071afc2092527b81bbec517f16a05b38e3e9788667cce09a0d + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Proof size: 1.97 KB +Proof hash: 891bc3fedd1f7c43c332048fbf38ddf4279ecc0d17a8c76ec1ead99d74b28f15 +Prover_pp hash: 3e557f14f170632c1a9108ea2a14cf3e17867b39c4200748be39b8365cd4d6a7 +Verifier_pp hash: e80f39b8ad26ff071afc2092527b81bbec517f16a05b38e3e9788667cce09a0d + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Proof size: 1.97 KB +Proof hash: 476f675a520eb558d47c11a5314dc124af7542238808d24626084867a773cd33 +Prover_pp hash: 3e557f14f170632c1a9108ea2a14cf3e17867b39c4200748be39b8365cd4d6a7 +Verifier_pp hash: e80f39b8ad26ff071afc2092527b81bbec517f16a05b38e3e9788667cce09a0d + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Proof size: 1.97 KB +Proof hash: c0b1ca395bdd0a93a2ee4846c51a59cb1b473fbf79f48ce7dc16d1537539d11e +Prover_pp hash: 3e557f14f170632c1a9108ea2a14cf3e17867b39c4200748be39b8365cd4d6a7 +Verifier_pp hash: e80f39b8ad26ff071afc2092527b81bbec517f16a05b38e3e9788667cce09a0d + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Proof size: 1.97 KB +Proof hash: 8b4f738e17a275289e44a4a65ef3dd1e70dbca00eb263e15a59adc889559f8d4 +Prover_pp hash: 3e557f14f170632c1a9108ea2a14cf3e17867b39c4200748be39b8365cd4d6a7 +Verifier_pp hash: e80f39b8ad26ff071afc2092527b81bbec517f16a05b38e3e9788667cce09a0d + +Edwards.test_add: +Constraints: 4 + +Edwards.test_add_optimized: +Constraints: 3 + +Edwards.test_add: +Proof size: 1.97 KB +Proof hash: ce3f11876d92735c98cc857a6ad16b1613958b6c411f5ba24a6fbfcbafc05045 +Prover_pp hash: 3e557f14f170632c1a9108ea2a14cf3e17867b39c4200748be39b8365cd4d6a7 +Verifier_pp hash: e80f39b8ad26ff071afc2092527b81bbec517f16a05b38e3e9788667cce09a0d + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Proof size: 2.25 KB +Proof hash: 3cfa041c2faad44f3c69b49d5e119eab6f9c7dbc3ee4cf8fbda5489166c4f068 +Prover_pp hash: 011b548556889f96891f835e608c7f9b76daa213e0587a0c74b16fa2d21fd63b +Verifier_pp hash: c27c87564c87dd95681de40f3e8ab7ba505abec68b31a846c856c834d0fb369f + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Proof size: 2.25 KB +Proof hash: 9ebdf3211c67855f7d0ca0adfdbc034319b1956679b5219edc94e258140fad24 +Prover_pp hash: 011b548556889f96891f835e608c7f9b76daa213e0587a0c74b16fa2d21fd63b +Verifier_pp hash: c27c87564c87dd95681de40f3e8ab7ba505abec68b31a846c856c834d0fb369f + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Proof size: 2.25 KB +Proof hash: 33116c7b79426817d0b134d1b1012c47686182c231fce598fd7949955384aa4e +Prover_pp hash: 011b548556889f96891f835e608c7f9b76daa213e0587a0c74b16fa2d21fd63b +Verifier_pp hash: c27c87564c87dd95681de40f3e8ab7ba505abec68b31a846c856c834d0fb369f + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Proof size: 2.25 KB +Proof hash: 390f16b08d0aa71347afe03762f6bdd31e43f6f083efce9ed0f5d70e19252d78 +Prover_pp hash: 011b548556889f96891f835e608c7f9b76daa213e0587a0c74b16fa2d21fd63b +Verifier_pp hash: c27c87564c87dd95681de40f3e8ab7ba505abec68b31a846c856c834d0fb369f + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Proof size: 2.25 KB +Proof hash: db3e0b29d0b4889b4094d3f753143f2c9aad52ef19e55e0287c8f08a8f443ab1 +Prover_pp hash: 011b548556889f96891f835e608c7f9b76daa213e0587a0c74b16fa2d21fd63b +Verifier_pp hash: c27c87564c87dd95681de40f3e8ab7ba505abec68b31a846c856c834d0fb369f + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Proof size: 2.25 KB +Proof hash: 91b43667692d5f6ebd871cf79da829553f69aca1650cfbfba5e0a0b19d7899e7 +Prover_pp hash: 011b548556889f96891f835e608c7f9b76daa213e0587a0c74b16fa2d21fd63b +Verifier_pp hash: c27c87564c87dd95681de40f3e8ab7ba505abec68b31a846c856c834d0fb369f + +Edwards.test_cond_add: +Constraints: 5 + +Edwards.test_cond_add_optimized: +Constraints: 2 + +Edwards.test_cond_add: +Proof size: 2.25 KB +Proof hash: c8960bad980c48c28b91cc6b5feb3ba6dcc8a3b11328e853e1723f555f3b5f17 +Prover_pp hash: 011b548556889f96891f835e608c7f9b76daa213e0587a0c74b16fa2d21fd63b +Verifier_pp hash: c27c87564c87dd95681de40f3e8ab7ba505abec68b31a846c856c834d0fb369f + +Edwards.test_scalar_mul: +Constraints: 6 + +Edwards.test_scalar_mul_optimized: +Constraints: 3 + +Edwards.test_scalar_mul: +Proof size: 2.03 KB +Proof hash: 8405ec4051196c6fe27cdb076521cab30a8bd15681dddecd7a9edc667e4c6a83 +Prover_pp hash: f79f45a70fccb3e8924a943f85171a8a054174df1b963564b89ba89667d1afc8 +Verifier_pp hash: 278cd5b854277283723c92851dc9807d0518e51ebea3a35a6c543eca99912fd4 + +Edwards.test_scalar_mul: +Constraints: 6 + +Edwards.test_scalar_mul_optimized: +Constraints: 3 + +Edwards.test_scalar_mul: +Proof size: 2.03 KB +Proof hash: 2ef3c1eed11638ceed0e0799c398cca261488b22b23882da4d5507cdc2761c41 +Prover_pp hash: f79f45a70fccb3e8924a943f85171a8a054174df1b963564b89ba89667d1afc8 +Verifier_pp hash: 278cd5b854277283723c92851dc9807d0518e51ebea3a35a6c543eca99912fd4 + +Edwards.test_scalar_mul: +Constraints: 11 + +Edwards.test_scalar_mul_optimized: +Constraints: 5 + +Edwards.test_scalar_mul: +Proof size: 2.47 KB +Proof hash: 35019e6eba278a5be2c50ddf3cc50a79b2fbdfefb01c68a98f6a585510ad08c6 +Prover_pp hash: c7580ca7555565f097688743782a651c6d5a7046a16df5b6e5c1883328bcd808 +Verifier_pp hash: 64017de399a455ca766dc6b8c1f0baab1237b38a268f3f9cbc60cfd8bfdfca53 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Proof size: 2.47 KB +Proof hash: 67669d8de2ac91b5655fb97e368b5ec056e11d4b4c1d783a2c78fc3997e515e3 +Prover_pp hash: 314eabadef36d1afae1b5a4e3bd17b05b8d5bbe4c58c97e367c2dc6db6c907f4 +Verifier_pp hash: 8331c2fd116dae77e599496e3eb84d065837c762f8157d0bdbed6c4140b67a71 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Proof size: 2.47 KB +Proof hash: 9aff40dabbee66fcdb2f054224db59fb3cc9dd47b4e4723c0729eb26a274ca42 +Prover_pp hash: 314eabadef36d1afae1b5a4e3bd17b05b8d5bbe4c58c97e367c2dc6db6c907f4 +Verifier_pp hash: 8331c2fd116dae77e599496e3eb84d065837c762f8157d0bdbed6c4140b67a71 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Proof size: 2.47 KB +Proof hash: 4bb845ce316d0acc861edb371e5f1e04435ead383d1114adf3cbf22040e28e58 +Prover_pp hash: 314eabadef36d1afae1b5a4e3bd17b05b8d5bbe4c58c97e367c2dc6db6c907f4 +Verifier_pp hash: 8331c2fd116dae77e599496e3eb84d065837c762f8157d0bdbed6c4140b67a71 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Proof size: 2.47 KB +Proof hash: 2993ece0af52dbd786251e8871135617d6e15c66044ae5958b2a7d00dbba46e4 +Prover_pp hash: 314eabadef36d1afae1b5a4e3bd17b05b8d5bbe4c58c97e367c2dc6db6c907f4 +Verifier_pp hash: 8331c2fd116dae77e599496e3eb84d065837c762f8157d0bdbed6c4140b67a71 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Proof size: 2.47 KB +Proof hash: 59094685d4278bd58132ece1281b8520609dcd496c6b0ef93685ef9996e6741c +Prover_pp hash: 314eabadef36d1afae1b5a4e3bd17b05b8d5bbe4c58c97e367c2dc6db6c907f4 +Verifier_pp hash: 8331c2fd116dae77e599496e3eb84d065837c762f8157d0bdbed6c4140b67a71 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Proof size: 2.47 KB +Proof hash: bc557c3d45e011836b02dcd7b435b785e897047f1b5b59e30a708ff499b867c9 +Prover_pp hash: 314eabadef36d1afae1b5a4e3bd17b05b8d5bbe4c58c97e367c2dc6db6c907f4 +Verifier_pp hash: 8331c2fd116dae77e599496e3eb84d065837c762f8157d0bdbed6c4140b67a71 + +Edwards.test_scalar_mul: +Constraints: 1271 + +Edwards.test_scalar_mul_optimized: +Constraints: 509 + +Edwards.test_scalar_mul: +Proof size: 2.47 KB +Proof hash: ca35361dc4a40c2e87be832c415b665f504dd478aec0f5eda7967e485ab6e1eb +Prover_pp hash: 314eabadef36d1afae1b5a4e3bd17b05b8d5bbe4c58c97e367c2dc6db6c907f4 +Verifier_pp hash: 8331c2fd116dae77e599496e3eb84d065837c762f8157d0bdbed6c4140b67a71 + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: ae77889ba4a66ca3032367eb8060b606fe99a9c8d245f0c160e42e7653b77870 +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: 17a1222d6decfe641874cf364ea42c0c3592d8093b1c13706cd2ce4c0e7b3f50 +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: 812390eca2006d8f81d0d9fa6ba42b4c1f20beb01e463f5892f179a479abe803 +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: efaa26668587e243a229244828b56d70c7c6ad2e713d77643d32b96c94cebc6e +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: d83b50bbdafc62af277fc0536e701a3acd21c6c2b9ba7e5f7586de78d784aa53 +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: 4f992c1790ec0c0865d11abfe23f65b2dfacd03906471c2f37038ce719f41be3 +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: cea61797f1e6b00d07da4e04e0fbaac279bd45c5d6bee33e874b10c044bfbd99 +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: 10272db81d96c02f424f873acb7b4d70e9f86c078953e9e21c8d04c21b6576bd +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: 95a6d0818e2fa2622b65d7caf47c194f179ca93a36cd7242f5f35d3f54ab0d45 +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: 6e4909aeefab47dd2a62d61d2d60e8b5cdbdd65f69e7cb022f7544cd0648e8e6 +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: 1542eae21e7b9e45966cff415a1ccdda3637e2bf1fcf8b160e3d90de6ab91932 +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: 6ce7db52b055028f8fe3d92af368bfd76699b8f08b3b6a1f9f70628dc853345e +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: 33314b547c4ba8e3db4a2c742f943ac7809353bee02d1bf0fcee581ce00a87e2 +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: ea23260836b1c0d0b92a4ca56b5b6dccc808be3e575eb5fe246f5e6a1b8dd1ce +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: 660cf1a9f6336717a2254a1ad70d15d9053ddddccb0ff9522f7b5d507923f059 +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: 08795d7aba78ee926cf4824985cd3086456f5ebab6751c8e3b1f00f6ef64ec93 +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_is_on_curve: +Constraints: 7 + +Edwards.test_is_on_curve_optimized: +Constraints: 6 + +Edwards.test_is_on_curve: +Proof size: 2.05 KB +Proof hash: fc008cbe85f16aaf2113db8376962086bf68414cae619999c4f3c4f27153e1ef +Prover_pp hash: 40e022c1c2e539e403e40b385bfd28f26bba4301be0fceb5e10cb21449997383 +Verifier_pp hash: 71490648648c3e8705df353c761bcb53c67910f89af7bac0778c5d4b2081e6ed + +Edwards.test_multi_scalar_mul: +Constraints: 2033 + +Edwards.test_multi_scalar_mul_optimized: +Constraints: 763 + +Edwards.test_multi_scalar_mul: +Proof size: 2.65 KB +Proof hash: ab38db898ad936b1e8cfce97746d3930e512cdfa67d215b8d2e482d867c89545 +Prover_pp hash: 67598168df081d3ad8b9aaf0e194f3c5ad1308b50817d511a936b851a598911a +Verifier_pp hash: f9c168e3be4239b2d79e9dcfa7459d393759f0d9658cca6d703322bf3bd51b07 + +Edwards.test_multi_scalar_mul: +Constraints: 2795 + +Edwards.test_multi_scalar_mul_optimized: +Constraints: 1017 + +Edwards.test_multi_scalar_mul: +Proof size: 2.65 KB +Proof hash: a9bdeb6cd72b4ae4d9bc5ec432b5c8945d691db1c7dc9cf28088c7603e943963 +Prover_pp hash: c30eb9a9f2ae00b7bd0e6513f576f94b68d479bb631b5bfcb9329ca7ab3ffb7d +Verifier_pp hash: c4babbce138a646cda871b80471a438fd99b569fcfb30dcc53148ae8e45fa9a3 + +Edwards.test_multi_scalar_mul: +Constraints: 3557 + +Edwards.test_multi_scalar_mul_optimized: +Constraints: 1271 + +Edwards.test_multi_scalar_mul: +Proof size: 2.65 KB +Proof hash: 7db0c98e335823211e2674da3e50cd8e9a694a40b6642ed7f1109fbdb1bb2d6e +Prover_pp hash: 2c1a97194f92b5bf2e3e3e1619318c48bd7f6841f25553deee3a9bab2eab21ce +Verifier_pp hash: ab677ac9cbfcf287441104d56d4f78409c04400f16d1ff8e84ef9b1ea2b1c2b5 + +Edwards.test_multi_scalar_mul: +Constraints: 4319 + +Edwards.test_multi_scalar_mul_optimized: +Constraints: 1525 + +Edwards.test_multi_scalar_mul: +Proof size: 2.65 KB +Proof hash: b05f808d05e87cb2d8cfe0a021a24cbcde5ac566a3857197d87fa057515f59c0 +Prover_pp hash: 996d6191811a59c4fb61828c66a8ecf8a2c5458b8a757ebbd36db98a65d5be30 +Verifier_pp hash: 6579fb0307a30c2798d4e309a2a28cbb07c3d284b3d3383e19f05993b57295e4 + +Edwards.test_multi_scalar_mul: +Constraints: 5081 + +Edwards.test_multi_scalar_mul_optimized: +Constraints: 1779 + +Edwards.test_multi_scalar_mul: +Proof size: 2.65 KB +Proof hash: d82d21fbb73ffc794f0b01c74a945b3d390b30c0ef50a86c1ac6675004643523 +Prover_pp hash: e884bd5492a9ee5f09cf3bb716cfe8f2e4f939306a1e2da13efcdf934a541e47 +Verifier_pp hash: daebff3368da3b22c9eabd1b8e4fd1ce6ef632079b3c56d1204d9a0e7a1f17d0 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_scalar_mul: +Constraints: 4067 + +Weierstrass.test_scalar_mul_optimized: +Constraints: 3810 + +Weierstrass.test_scalar_mul: +Constraints: 4067 + +Weierstrass.test_scalar_mul_optimized: +Constraints: 3810 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Proof size: 2.07 KB +Proof hash: 20e8229f9ab1b58171e29bd94fd90f01fef2d9422ea2095392ab2d75c9761b4e +Prover_pp hash: 4e473906d7c085d1ce5a8ac4b38fe9a7112205d54b180bf7dee51324ee54e289 +Verifier_pp hash: 5f5d9d42203703da45e4a2ce6dd77d1935b0b1ca280a263186c1fa979977ab19 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Proof size: 2.07 KB +Proof hash: 4a1df707ea352b59a1daedffdb47d4fc5dfd200860a7465bbc0f699efec1d7e3 +Prover_pp hash: 4e473906d7c085d1ce5a8ac4b38fe9a7112205d54b180bf7dee51324ee54e289 +Verifier_pp hash: 5f5d9d42203703da45e4a2ce6dd77d1935b0b1ca280a263186c1fa979977ab19 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Proof size: 2.07 KB +Proof hash: a55400d331f063b185c09290b6825b00f42f2a320a3e96c16dc10d0a8402b01a +Prover_pp hash: 4e473906d7c085d1ce5a8ac4b38fe9a7112205d54b180bf7dee51324ee54e289 +Verifier_pp hash: 5f5d9d42203703da45e4a2ce6dd77d1935b0b1ca280a263186c1fa979977ab19 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Proof size: 2.07 KB +Proof hash: 1a7408ebdc9db230b918f01f23fc74b9096ccfe61ff3dbcc35b65a5a0fe90b11 +Prover_pp hash: 4e473906d7c085d1ce5a8ac4b38fe9a7112205d54b180bf7dee51324ee54e289 +Verifier_pp hash: 5f5d9d42203703da45e4a2ce6dd77d1935b0b1ca280a263186c1fa979977ab19 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Proof size: 2.07 KB +Proof hash: 2d89b85b6e3043eeda7635999c33f473ea8d4c3362fd6642ea44a399beea1824 +Prover_pp hash: 4e473906d7c085d1ce5a8ac4b38fe9a7112205d54b180bf7dee51324ee54e289 +Verifier_pp hash: 5f5d9d42203703da45e4a2ce6dd77d1935b0b1ca280a263186c1fa979977ab19 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Proof size: 2.07 KB +Proof hash: 9cfb29650b66e82042741273001ad6fc62986882d53c28854c1c3c4b2aa54e65 +Prover_pp hash: 4e473906d7c085d1ce5a8ac4b38fe9a7112205d54b180bf7dee51324ee54e289 +Verifier_pp hash: 5f5d9d42203703da45e4a2ce6dd77d1935b0b1ca280a263186c1fa979977ab19 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Proof size: 2.07 KB +Proof hash: 50ea5a77d1f21042847586fbf8bd01afda893f3fc992de4f4656516488813adc +Prover_pp hash: 4e473906d7c085d1ce5a8ac4b38fe9a7112205d54b180bf7dee51324ee54e289 +Verifier_pp hash: 5f5d9d42203703da45e4a2ce6dd77d1935b0b1ca280a263186c1fa979977ab19 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Proof size: 2.07 KB +Proof hash: 6c06dbcb337892989e116f992afc614f8e2cae0a184a995a7a1d02a5ed8ba526 +Prover_pp hash: 4e473906d7c085d1ce5a8ac4b38fe9a7112205d54b180bf7dee51324ee54e289 +Verifier_pp hash: 5f5d9d42203703da45e4a2ce6dd77d1935b0b1ca280a263186c1fa979977ab19 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Proof size: 2.07 KB +Proof hash: 7f27b8ae6d8690d2a592f9e8dbe55cb73a3e28649e49812260d6a96f89d88dd6 +Prover_pp hash: 4e473906d7c085d1ce5a8ac4b38fe9a7112205d54b180bf7dee51324ee54e289 +Verifier_pp hash: 5f5d9d42203703da45e4a2ce6dd77d1935b0b1ca280a263186c1fa979977ab19 + +Weierstrass.test_add: +Constraints: 4 + +Weierstrass.test_add_optimized: +Constraints: 3 + +Weierstrass.test_add: +Proof size: 2.07 KB +Proof hash: 676773e048ba6b29c4600c92a174ba943fd0d9faf640a1156f0d93042cc669b0 +Prover_pp hash: 4e473906d7c085d1ce5a8ac4b38fe9a7112205d54b180bf7dee51324ee54e289 +Verifier_pp hash: 5f5d9d42203703da45e4a2ce6dd77d1935b0b1ca280a263186c1fa979977ab19 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Proof size: 1.97 KB +Proof hash: 31275047458f786b6af1675b2708f4f6df767185d9f0a42ceb3c660e4f4ecd83 +Prover_pp hash: 996190c17ffa7c63a337445453ff32776c78288aa94ed859a5b022c3309da83e +Verifier_pp hash: 7bb0573430accbabf5fcea59eb596ea486ad185490e825d154a6771ad15ef234 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Proof size: 1.97 KB +Proof hash: 217338604d3037214bf9674ffa577a44c3164e4221494ac57c86768d9fdaa067 +Prover_pp hash: 996190c17ffa7c63a337445453ff32776c78288aa94ed859a5b022c3309da83e +Verifier_pp hash: 7bb0573430accbabf5fcea59eb596ea486ad185490e825d154a6771ad15ef234 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Proof size: 1.97 KB +Proof hash: 0595b653a856db5e8f820849f5c4655c16e66e3b88c1e22e18392e87583f929a +Prover_pp hash: 996190c17ffa7c63a337445453ff32776c78288aa94ed859a5b022c3309da83e +Verifier_pp hash: 7bb0573430accbabf5fcea59eb596ea486ad185490e825d154a6771ad15ef234 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Proof size: 1.97 KB +Proof hash: 456f181e1fff46e36e57d6a111551a87b38337c0417877512c72f9dc9fe6c9ac +Prover_pp hash: 996190c17ffa7c63a337445453ff32776c78288aa94ed859a5b022c3309da83e +Verifier_pp hash: 7bb0573430accbabf5fcea59eb596ea486ad185490e825d154a6771ad15ef234 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Proof size: 1.97 KB +Proof hash: 88d2c009eb96597deffbca8c85fc2f0f39e4788ca45130a9c460ef8ba8b05c0e +Prover_pp hash: 996190c17ffa7c63a337445453ff32776c78288aa94ed859a5b022c3309da83e +Verifier_pp hash: 7bb0573430accbabf5fcea59eb596ea486ad185490e825d154a6771ad15ef234 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Proof size: 1.97 KB +Proof hash: e1c50dd81af36835df9fa51b5e47b5cc9d58ac2bfde68752becc428c0e9e605f +Prover_pp hash: 996190c17ffa7c63a337445453ff32776c78288aa94ed859a5b022c3309da83e +Verifier_pp hash: 7bb0573430accbabf5fcea59eb596ea486ad185490e825d154a6771ad15ef234 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Proof size: 1.97 KB +Proof hash: f74362b972c1c18f65c3a106392c41cbb1c04735b111c3b94a6127ba5671a231 +Prover_pp hash: 996190c17ffa7c63a337445453ff32776c78288aa94ed859a5b022c3309da83e +Verifier_pp hash: 7bb0573430accbabf5fcea59eb596ea486ad185490e825d154a6771ad15ef234 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Proof size: 1.97 KB +Proof hash: ca601eb42e6c98c09be6d754d6a40f88a44641bdabe5a14d30189e2974aff709 +Prover_pp hash: 996190c17ffa7c63a337445453ff32776c78288aa94ed859a5b022c3309da83e +Verifier_pp hash: 7bb0573430accbabf5fcea59eb596ea486ad185490e825d154a6771ad15ef234 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Proof size: 1.97 KB +Proof hash: 0ef8dd6fd272b19b55d24135a9b81a15f80ac89f4dd890d110479f705ef68d53 +Prover_pp hash: 996190c17ffa7c63a337445453ff32776c78288aa94ed859a5b022c3309da83e +Verifier_pp hash: 7bb0573430accbabf5fcea59eb596ea486ad185490e825d154a6771ad15ef234 + +Weierstrass.test_double: +Constraints: 10 + +Weierstrass.test_double_optimized: +Constraints: 8 + +Weierstrass.test_double: +Proof size: 1.97 KB +Proof hash: 1cd2240b2d82d97400a89b801d07d5393539724ac288c0cf094cca6a6c5aedbd +Prover_pp hash: 996190c17ffa7c63a337445453ff32776c78288aa94ed859a5b022c3309da83e +Verifier_pp hash: 7bb0573430accbabf5fcea59eb596ea486ad185490e825d154a6771ad15ef234 + +Weierstrass.test_scalar_mul: +Constraints: 4067 + +Weierstrass.test_scalar_mul_optimized: +Constraints: 3810 + +Weierstrass.test_scalar_mul: +Proof size: 2.57 KB +Proof hash: ee55eda333da5b128723df88074453b4e9f0d74d2b7303d76e6920beabcdf0aa +Prover_pp hash: 4ff633dde2262ce1efe42354fc7a8d12425e81b96a76eaefbec70c191b209f4b +Verifier_pp hash: e91d57e2f01610ddb2e3364fd9a373c8166c0770d4f6fd866eba1ab575abdd47 + +Weierstrass.test_scalar_mul: +Constraints: 4067 + +Weierstrass.test_scalar_mul_optimized: +Constraints: 3810 + +Weierstrass.test_scalar_mul: +Proof size: 2.57 KB +Proof hash: 2c4ac07dac8f7a09b29c5491b32639cc3f0e99ce1b1349a91fba842c1d634cd3 +Prover_pp hash: 4ff633dde2262ce1efe42354fc7a8d12425e81b96a76eaefbec70c191b209f4b +Verifier_pp hash: e91d57e2f01610ddb2e3364fd9a373c8166c0770d4f6fd866eba1ab575abdd47 + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Proof size: 2.15 KB +Proof hash: 1b17e4702aeda8878554b8cb840ce0a486859ccbcc9f9a0a8a294cfb76154656 +Prover_pp hash: 843f7c940b224424aecd441b70b96bf040098640df62d54bf3091806da673026 +Verifier_pp hash: d8717ebe29c1e196e45ace8ab3bfac9da190e19959e44e5234c92c1969d7631b + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Proof size: 2.15 KB +Proof hash: cedc5fe1164ca3653aefbeb6f05306bff5dac309c97bb1480c90cd0cb8519fd0 +Prover_pp hash: 843f7c940b224424aecd441b70b96bf040098640df62d54bf3091806da673026 +Verifier_pp hash: d8717ebe29c1e196e45ace8ab3bfac9da190e19959e44e5234c92c1969d7631b + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Proof size: 2.15 KB +Proof hash: 9b28ae25c85a1d045a7fd0ad86bd38fc0c983303ccb979bc6563ff8e10eecb1a +Prover_pp hash: 843f7c940b224424aecd441b70b96bf040098640df62d54bf3091806da673026 +Verifier_pp hash: d8717ebe29c1e196e45ace8ab3bfac9da190e19959e44e5234c92c1969d7631b + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Proof size: 2.15 KB +Proof hash: 73bc22215d62ab60e74ac984b63fc28fcc7bc5fb71efbcfa453c16e999c69a54 +Prover_pp hash: 843f7c940b224424aecd441b70b96bf040098640df62d54bf3091806da673026 +Verifier_pp hash: d8717ebe29c1e196e45ace8ab3bfac9da190e19959e44e5234c92c1969d7631b + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Proof size: 2.15 KB +Proof hash: 674f6cb56c59702407f8e0112f38a15d22a9dee15df3492a1198fc8f5ac79b78 +Prover_pp hash: 843f7c940b224424aecd441b70b96bf040098640df62d54bf3091806da673026 +Verifier_pp hash: d8717ebe29c1e196e45ace8ab3bfac9da190e19959e44e5234c92c1969d7631b + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Proof size: 2.15 KB +Proof hash: 4e7c525f92c57f722fcbe12dbdafe6654cfcc6b96909de47cd36da92ec7e4bb0 +Prover_pp hash: 843f7c940b224424aecd441b70b96bf040098640df62d54bf3091806da673026 +Verifier_pp hash: d8717ebe29c1e196e45ace8ab3bfac9da190e19959e44e5234c92c1969d7631b + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Proof size: 2.15 KB +Proof hash: 9d505547656cc1adb6d726c4fb7fd1784501d5f082378220ce068e76c3567a09 +Prover_pp hash: 843f7c940b224424aecd441b70b96bf040098640df62d54bf3091806da673026 +Verifier_pp hash: d8717ebe29c1e196e45ace8ab3bfac9da190e19959e44e5234c92c1969d7631b + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Proof size: 2.15 KB +Proof hash: 95104a49372144331b54c3f8ef5969366f90a6ee7ab85c5fc68a1e61f1c1b6ff +Prover_pp hash: 843f7c940b224424aecd441b70b96bf040098640df62d54bf3091806da673026 +Verifier_pp hash: d8717ebe29c1e196e45ace8ab3bfac9da190e19959e44e5234c92c1969d7631b + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Proof size: 2.15 KB +Proof hash: 846519e815b8c23c05b72ce37fb6c96063ba471d1879bba456935dc662e09401 +Prover_pp hash: 843f7c940b224424aecd441b70b96bf040098640df62d54bf3091806da673026 +Verifier_pp hash: d8717ebe29c1e196e45ace8ab3bfac9da190e19959e44e5234c92c1969d7631b + +Weierstrass.is_on_curve_circuit: +Constraints: 4 + +Weierstrass.is_on_curve_circuit_optimized: +Constraints: 4 + +Weierstrass.is_on_curve_circuit: +Proof size: 2.15 KB +Proof hash: cf58e5911027d73a9c286a2094b43ca5baee2561fb9daeb78934712ff86f9bbd +Prover_pp hash: 843f7c940b224424aecd441b70b96bf040098640df62d54bf3091806da673026 +Verifier_pp hash: d8717ebe29c1e196e45ace8ab3bfac9da190e19959e44e5234c92c1969d7631b + +Bool.test_bor_lookup: +Constraints: 7 + +Bool.test_bor_lookup_optimized: +Constraints: 5 + +Bool.test_bor_lookup: +Constraints: 7 + +Bool.test_bor_lookup_optimized: +Constraints: 5 + +Bool.test_bor_lookup: +Constraints: 7 + +Bool.test_bor_lookup_optimized: +Constraints: 5 + +Bool.test_bor_lookup: +Constraints: 7 + +Bool.test_bor_lookup_optimized: +Constraints: 5 + +Bool.test_bor_lookup: +Constraints: 7 + +Bool.test_bor_lookup_optimized: +Constraints: 5 + +Bool.test_bor_lookup: +Proof size: 3.36 KB +Proof hash: 939d9debe63c4ace8d3469b57d9b8a6e5d129ae5a0841144d6185ee76002274f +Prover_pp hash: 44bb071dcee20f2d9dce20bfec2a689b932ee7db0f13226a70d3f0b41bc051c6 +Verifier_pp hash: 360f0118adab15eb61e93d24f653ca77637e377c7618278cf17b4dea2e57a529 + +Bool.test_bor_lookup: +Constraints: 7 + +Bool.test_bor_lookup_optimized: +Constraints: 5 + +Bool.test_bor_lookup: +Proof size: 3.36 KB +Proof hash: 896735088c9c16a081c698bac2521951425acaccd5cf4b74f89e9f1ae525b2b2 +Prover_pp hash: bfbd992c48aab5d307284bd1c6ee4816a7184e777ed94dd688f73ee16d0840d4 +Verifier_pp hash: b12addb4967f75b7654108988bb2da780c084d3e4ee39508277ebb2d662487a9 + +Bool.test_bor_lookup: +Constraints: 7 + +Bool.test_bor_lookup_optimized: +Constraints: 5 + +Bool.test_bor_lookup: +Proof size: 3.36 KB +Proof hash: 136290f3e95808bcd3db1dd4d5e397726d157d1839046d705934c997499422b1 +Prover_pp hash: ea787ab19e8c770672ad00a903935e8d9bc7405a3070457e2e43bfa6428c7165 +Verifier_pp hash: 2f28d39d8e42e2cb9f4ca731fc281a01a5251b909319d2a2ada55d2f3a6a7fae + +Bool.test_bor_lookup: +Constraints: 7 + +Bool.test_bor_lookup_optimized: +Constraints: 5 + +Bool.test_bor_lookup: +Proof size: 3.36 KB +Proof hash: 4b740c7cacd5fdb197d7b186dfdb832a7aa32d6f2d318aac3d252f19b1aa024c +Prover_pp hash: 4bbcb4dc73a35edd9227b3421c3452f61d04bf0220c70b6b3116c5490cef6952 +Verifier_pp hash: 7fc80c820209467ec9924fb918580eda2372fe039595a7cd7f255aeadd320d51 + +Transfer circuit for 1 transactions on a tree of depth 10. +Constraints: 6139 +Optimizer.test_long_sum: +Constraints: 100 + +Optimizer.test_long_sum_optimized: +Constraints: 26 + +Optimizer.test_long_sum: +Constraints: 500 + +Optimizer.test_long_sum_optimized: +Constraints: 126 + +Optimizer.test_poseidon_rounds: +Constraints: 11 + +Optimizer.test_poseidon_rounds_optimized: +Constraints: 5 + +Optimizer.test_ecc_ed_cond_add: +Constraints: 12 + +Optimizer.test_ecc_ed_cond_add_optimized: +Constraints: 5 + +Optimizer.test_long_sum: +Constraints: 100 + +Optimizer.test_long_sum_optimized: +Constraints: 26 + +Optimizer.test_long_sum: +Proof size: 2.55 KB +Proof hash: e7ba77355db1477df93e0c8fdeda554b1ddc87997d10fa14b444b7ea4a15407b +Prover_pp hash: 47521235d8f2641a893851206f6eb94910801142371b101a2ee06381980cc33a +Verifier_pp hash: 5fb67afd1d1f1ca51e4417dff7190123e0180357a4c665e51a62c862c38773b3 + +Optimizer.test_long_sum: +Constraints: 500 + +Optimizer.test_long_sum_optimized: +Constraints: 126 + +Optimizer.test_long_sum: +Proof size: 2.55 KB +Proof hash: 3d5aa3b51b29260c2d64d33b14eabf6d09458de927c234b46e9ea866f16042ff +Prover_pp hash: 7c223bf777a767e66549dbdd2892040b45ca13f1459564de4f5075373c5a1a9f +Verifier_pp hash: 8cb356f4769ac11d93e3a14ae43b8f51cb10ebef101c4f5e2fbc31335f40dba5 + +Optimizer.test_poseidon_rounds: +Constraints: 11 + +Optimizer.test_poseidon_rounds_optimized: +Constraints: 5 + +Optimizer.test_poseidon_rounds: +Proof size: 2.64 KB +Proof hash: 77efefdaaf0aa3b02995fa1d477e610b860d5f8d801a41b9c4ce894168c186f4 +Prover_pp hash: 28dcaa590b37e7cf9c46912408d304a5a8ab90754473fe101b5aa2e9a982a095 +Verifier_pp hash: 001c3436f56f117e2eedad568609eb5ceabd6fb77cbff9362f3ba8f0e4e53ae6 + +Optimizer.test_ecc_ed_cond_add: +Constraints: 12 + +Optimizer.test_ecc_ed_cond_add_optimized: +Constraints: 5 + +Optimizer.test_ecc_ed_cond_add: +Proof size: 2.42 KB +Proof hash: 358c5aa86f2fc01c229131e1aa28dbc1a4073d7786ddd166651c2944a408937a +Prover_pp hash: 943b12b189ffcf12825cae1adb2fddb7ca54349d4418d2d1074678bcef54d130 +Verifier_pp hash: b32a010e75fc4d7b5fa424b3c926a361deb51d8ee1a26c59ef4a36b6c62e8313 + +Encoding.test_foo: +Constraints: 8 + +Encoding.test_foo_optimized: +Constraints: 7 + +Encoding.test_assertion: +Constraints: 4 + +Encoding.test_assertion_optimized: +Constraints: 3 + +Encoding.test_foo: +Constraints: 8 + +Encoding.test_foo_optimized: +Constraints: 7 + +Encoding.test_foo: +Proof size: 1.73 KB +Proof hash: 9dfd98a40a3a8179477430cdc40d7b28f08233492abc99e65574dd3c682e13a8 +Prover_pp hash: 990c6d75568c47cfefdfe01abebcc387146ec5170564fa760fdcbdfc61cea078 +Verifier_pp hash: aa91937fe02c8dde040acf4403b16f4c78316ce1d061bb7ea400bfd167d8ae12 + +Encoding.test_assertion: +Constraints: 4 + +Encoding.test_assertion_optimized: +Constraints: 3 + +Encoding.test_assertion: +Proof size: 1.79 KB +Proof hash: 3e7cd4b2b6f0fb543b1a3d0ab8a72bceda4cbdb75de7f832d437cc34ccca9744 +Prover_pp hash: 218973f8bbdf29eca00603f2621744df3e5af4e855043534b5933aa7f8ea0b34 +Verifier_pp hash: 2678966962bd2130be106099af9d3ae206422fc9984ff9bb58324e46a00e67dc + diff --git a/src/lib_plonk/test_plompiler/test_anemoi.ml b/src/lib_plonk/test_plompiler/test_anemoi.ml new file mode 100644 index 000000000000..b316a36731e3 --- /dev/null +++ b/src/lib_plonk/test_plompiler/test_anemoi.ml @@ -0,0 +1,271 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk_test +module CS = Plonk.Circuit +open Helpers + +module Anemoi_test (L : LIB) = struct + open L + + open Utils (L) + + module Hash1 = AnemoiJive_128_1 (L) + module Hash2 = Anemoi128.V (L) + + let test_vectors = [(S.one, S.one); (S.one, S.(one + one))] + + let inputs : (scalar Input.t * scalar Input.t) list = + List.map (fun (x, y) -> (Input.scalar x, Input.scalar y)) test_vectors + + module AnemoiPerm = Bls12_381_hash.Permutation.Anemoi + + let parameters = AnemoiPerm.Parameters.security_128_state_size_2 + + let anemoi_instance = AnemoiPerm.allocate_ctxt parameters + + let matrix = AnemoiPerm.Parameters.get_matrix parameters + + (* Test naive implementation of Anemoi *) + let test_round x y expected_x expected_y () = + let* x = input ~kind:`Public x in + let* y = input ~kind:`Public y in + let* expected_x = input expected_x in + let* expected_y = input expected_y in + (* use round constants #0, #1 *) + let* x, y = Hash1.init_state_for_rounds x y in + (* use round constants #2, #3 *) + let* xx, yy, _ = Hash1.round (x, y, 2) in + let* bx = equal xx expected_x in + let* by = equal yy expected_y in + let b = Bool.band bx by in + with_bool_check b + + let tests_round = + let expected () = + List.map + (fun v -> + let x, y = v in + let res = + AnemoiPerm.set_state anemoi_instance [|x; y|] ; + AnemoiPerm.apply_one_round anemoi_instance 0 ; + AnemoiPerm.apply_constants_addition anemoi_instance 1 ; + AnemoiPerm.apply_linear_layer anemoi_instance ; + AnemoiPerm.get_state anemoi_instance + in + (Input.scalar res.(0), Input.scalar res.(1))) + test_vectors + in + let wrong = + List.map + (fun _ -> (Input.scalar @@ S.random (), Input.scalar @@ S.random ())) + (expected ()) + in + List.map2 + (fun (x, y) (ex, ey) -> + test ~valid:true ~name:"Anemoi.test_round.valid" @@ test_round x y ex ey) + inputs + (expected ()) + @ List.map2 + (fun (x, y) (wx, wy) -> + test ~valid:false ~name:"Anemoi.test_round.invalid" + @@ test_round x y wx wy) + inputs + wrong + + let test_anemoi_compress x y expected () = + let* x = input ~kind:`Public x in + let* y = input ~kind:`Public y in + let* expected = input expected in + let* o = Hash1.compress x y in + with_bool_check (equal o expected) + + let tests_compress = + let expected () = + let direct (x, y) = + let state = + AnemoiPerm.set_state anemoi_instance [|x; y|] ; + AnemoiPerm.apply_permutation anemoi_instance ; + AnemoiPerm.get_state anemoi_instance + in + S.(state.(0) + state.(1) + x + y) + in + List.map (fun v -> Input.scalar @@ direct v) test_vectors + in + let wrong = List.map (fun _ -> Input.scalar @@ S.random ()) (expected ()) in + List.map2 + (fun (x, y) e -> + test ~valid:true ~name:"Anemoi.test_compress.valid" + @@ test_anemoi_compress x y e) + inputs + (expected ()) + @ List.map2 + (fun (x, y) w -> + test ~valid:false ~name:"Anemoi.test_compress.invalid" + @@ test_anemoi_compress x y w) + inputs + wrong + + (* Test implementation with two rounds in 5 constraints *) + let test_double_round x y expected_x expected_y () = + let* x = input ~kind:`Public x in + let* y = input ~kind:`Public y in + let* expected_x = input expected_x in + let* expected_y = input expected_y in + (* use round constants #0, #1 *) + let* x, y = Hash1.init_state_for_rounds x y in + (* use round constants #2, #3, #4, #5 *) + let* xx, yy, _ = Hash1.double_round (x, y, 2) in + let* bx = equal xx expected_x in + let* by = equal yy expected_y in + let b = Bool.band bx by in + with_bool_check b + + let tests_double_round = + let expected () = + List.map + (fun v -> + let x, y = v in + let res = + AnemoiPerm.set_state anemoi_instance [|x; y|] ; + AnemoiPerm.apply_one_round anemoi_instance 0 ; + AnemoiPerm.apply_one_round anemoi_instance 1 ; + AnemoiPerm.apply_constants_addition anemoi_instance 2 ; + AnemoiPerm.apply_linear_layer anemoi_instance ; + AnemoiPerm.get_state anemoi_instance + in + (Input.scalar res.(0), Input.scalar res.(1))) + test_vectors + in + let wrong = + List.map + (fun _ -> (Input.scalar @@ S.random (), Input.scalar @@ S.random ())) + (expected ()) + in + List.map2 + (fun (x, y) (ex, ey) -> + test ~valid:true ~name:"Anemoi.test_double_round.valid" + @@ test_double_round x y ex ey) + inputs + (expected ()) + @ List.map2 + (fun (x, y) (wx, wy) -> + test ~valid:false ~name:"Anemoi.test_double_round.invalid" + @@ test_double_round x y wx wy) + inputs + wrong + + let test_anemoi_compress_two x y expected () = + let* x = input ~kind:`Public x in + let* y = input ~kind:`Public y in + let* expected = input expected in + let* o = Hash1.compress_two x y in + with_bool_check (equal o expected) + + let tests_compress_two = + let expected () = + let direct (x, y) = + let state = + AnemoiPerm.set_state anemoi_instance [|x; y|] ; + AnemoiPerm.apply_permutation anemoi_instance ; + AnemoiPerm.get_state anemoi_instance + in + S.(state.(0) + state.(1) + x + y) + in + List.map (fun v -> Input.scalar @@ direct v) test_vectors + in + let wrong = List.map (fun _ -> Input.scalar @@ S.random ()) (expected ()) in + List.map2 + (fun (x, y) e -> + test ~valid:true ~name:"Anemoi.test_compress_two.valid" + @@ test_anemoi_compress_two x y e) + inputs + (expected ()) + @ List.map2 + (fun (x, y) w -> + test ~valid:false ~name:"Anemoi.test_compress_two.invalid" + @@ test_anemoi_compress_two x y w) + inputs + wrong + + (* Test with custom gates for 2 rounds in 4 constraints *) + let test_anemoi_hash inputs expected () = + let* expected = input ~kind:`Public expected in + let* inputs = input inputs in + let* o = Hash2.digest inputs in + with_bool_check (equal o expected) + + let tests_hash = + let test_vectors = [[S.one; S.one]; [S.one; S.one; S.one; S.one]] in + + let inputs : scalar list Input.input list = + List.map + (fun l -> List.map (fun x -> Input.scalar x) l |> Input.list) + test_vectors + in + let expected () = + let direct l = Anemoi128.P.direct (Array.of_list l) in + let direct2 l = + let anemoi_instance = Anemoi128.P.init () in + let anemoi_instance = Anemoi128.P.digest anemoi_instance l in + Anemoi128.P.get anemoi_instance + in + List.map + (fun v -> + let exp = direct v in + assert (S.(eq exp (direct2 (Array.of_list v)))) ; + Input.scalar @@ exp) + test_vectors + in + let wrong = List.map (fun _ -> Input.scalar @@ S.random ()) (expected ()) in + List.map2 + (fun l e -> + test ~valid:true ~name:"Anemoi.test_compress.valid" + @@ test_anemoi_hash l e) + inputs + (expected ()) + @ List.map2 + (fun l w -> + test ~valid:false ~name:"Anemoi.test_compress.invalid" + @@ test_anemoi_hash l w) + inputs + wrong + + let tests = + tests_round @ tests_compress @ tests_double_round @ tests_compress_two + @ tests_hash +end + +let tests = + let both = [("Anemoi", (module Anemoi_test : Test))] in + List.map (fun (name, m) -> Alcotest.test_case name `Quick (to_test m)) both + @ List.map + (fun (name, m) -> + Alcotest.test_case + (name ^ " plonk") + `Slow + (to_test ~plonk:(module Plonk.Main_protocol) m)) + both diff --git a/src/lib_plonk/test_plompiler/test_blake.ml b/src/lib_plonk/test_plompiler/test_blake.ml new file mode 100644 index 000000000000..8820916a6833 --- /dev/null +++ b/src/lib_plonk/test_plompiler/test_blake.ml @@ -0,0 +1,201 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk_test +module CS = Plonk.Circuit +open Helpers + +module Blake (L : LIB) = struct + open L + + open Utils (L) + + module B = Plompiler.Blake2s (L) + + let test_mixing (constants : Bytes.bl Input.t Array.t) z exp () = + let* constants = + foldM + (fun acc c -> + let* w = input ~kind:`Public c in + ret @@ (w :: acc)) + [] + (Array.to_list constants) + in + let constants = Array.of_list (List.rev constants) in + let* z = input z in + let* exp = + foldM + (fun acc c -> + let* w = input c in + ret @@ (w :: acc)) + [] + (Array.to_list exp) + in + let exp = Array.of_list (List.rev exp) in + let* constants = B.mixing_g constants 0 4 8 12 z z in + fold2M + (fun _ a b -> assert_equal a b) + unit + (Array.to_list constants) + (Array.to_list exp) + + let input_bitlist l = Input.list (List.map Input.bool l) + + let tests_mixing = + let constants = + Array.of_list + @@ List.map + (fun s -> input_bitlist Plompiler.Utils.(bitlist @@ bytes_of_hex s)) + (List.init 16 (fun _ -> "00000001")) + in + let z = + input_bitlist Plompiler.Utils.(bitlist @@ bytes_of_hex "00000001") + in + let exp = + Array.of_list + @@ List.map + (fun s -> input_bitlist Plompiler.Utils.(bitlist @@ bytes_of_hex s)) + [ + "00000024"; + "00000001"; + "00000001"; + "00000001"; + "42480404"; + "00000001"; + "00000001"; + "00000001"; + "24020201"; + "00000001"; + "00000001"; + "00000001"; + "24000200"; + "00000001"; + "00000001"; + "00000001"; + ] + in + [test ~valid:true ~name:"Blake.test_mixing" @@ test_mixing constants z exp] + + let test_compression h m exp () = + let* h = + foldM + (fun acc c -> + let* w = input ~kind:`Public c in + ret @@ (w :: acc)) + [] + (Array.to_list h) + in + let h = Array.of_list (List.rev h) in + let* m = + foldM + (fun acc c -> + let* w = input c in + ret @@ (w :: acc)) + [] + (Array.to_list m) + in + let m = Array.of_list (List.rev m) in + let* exp = + foldM + (fun acc c -> + let* w = input c in + ret @@ (w :: acc)) + [] + (Array.to_list exp) + in + let exp = Array.of_list (List.rev exp) in + let* h = B.compression h m (Stdint.Uint64.of_int 65) false in + (* assert_equal (to_list @@ List.rev @@ of_list @@ h.(0)) exp.(0) *) + fold2M + (fun _ a b -> assert_equal a b) + unit + (Array.to_list h) + (Array.to_list exp) + + let tests_compression = + let h = + Array.of_list + @@ List.map + (fun s -> input_bitlist Plompiler.Utils.(bitlist @@ bytes_of_hex s)) + (List.init 8 (fun _ -> "00000001")) + in + let m = + Array.of_list + @@ List.map + (fun s -> input_bitlist Plompiler.Utils.(bitlist @@ bytes_of_hex s)) + (List.init 16 (fun _ -> "00000001")) + in + let exp = + Array.of_list + @@ List.map + (fun s -> input_bitlist Plompiler.Utils.(bitlist @@ bytes_of_hex s)) + [ + "6f226bc1"; + "40e44908"; + "d271fbed"; + "0f593d3a"; + "4ea6db39"; + "32c6318c"; + "a8e058a1"; + "16c949ad"; + ] + in + + [ + test ~valid:true ~name:"Blake.test_compression" @@ test_compression h m exp; + ] + + let test_blake2s i exp () = + let* i = input ~kind:`Public i in + let* exp = input exp in + let personalization = Plompiler.Utils.bytes_of_hex "0000000000000000" in + let* o = B.blake2s i personalization in + assert_equal exp o + + let tests_blake2s = + let i = + input_bitlist Plompiler.Utils.(bitlist (Stdlib.Bytes.make 65 '\xff')) + in + let exp = + input_bitlist + Plompiler.Utils.( + bitlist + @@ bytes_of_hex + "d63a602a01d5982f054e07431bb0f93139c135f296f7fc4c131a3d2a8f28dc2c") + in + [test ~valid:true ~name:"Blake.test_blake2s" @@ test_blake2s i exp] + + let tests = tests_mixing @ tests_compression @ tests_blake2s +end + +let tests = + [ + Alcotest.test_case "Blake2s" `Quick (to_test (module Blake : Test)); + Alcotest.test_case + "Blake2s plonk" + `Slow + (to_test ~plonk:(module Plonk.Main_protocol) (module Blake : Test)); + ] diff --git a/src/lib_plonk/test_plompiler/test_core.ml b/src/lib_plonk/test_plompiler/test_core.ml new file mode 100644 index 000000000000..ec219a91f8c0 --- /dev/null +++ b/src/lib_plonk/test_plompiler/test_core.ml @@ -0,0 +1,1044 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk_test +module CS = Plonk.Circuit +open Helpers + +module Num : Test = +functor + (L : LIB) + -> + struct + open L + open L.Num + + open Utils (L) + + let test_bop f x y z () = + let* x = input ~kind:`Public x in + let* y = input y in + let* z = input z in + let* o = f x y in + assert_equal o z + + let test_op f x z () = + let* x = input ~kind:`Public x in + let* z = input z in + let* o = f x in + assert_equal o z + + let tests_add = + let x1, y1, z1 = (si 6, si 2, si 8) in + let x2, y2, z2 = (si 6, si 0, si 6) in + [ + test ~valid:true ~name:"Num.test_add" @@ test_bop add x1 y1 z1; + test ~valid:true ~name:"Num.test_add" @@ test_bop add x2 y2 z2; + test ~valid:false @@ test_bop add x1 y1 (si 4); + test ~valid:false @@ test_bop add x2 y2 y2; + ] + + let tests_add_constant = + let x1, z1 = (si 6, si 7) in + [ + test ~valid:true ~name:"Num.test_add_constant" + @@ test_op (add_constant S.one) x1 z1; + test ~valid:true ~name:"Num.test_add_constant" + @@ test_op (add_constant S.zero) x1 x1; + test ~valid:false @@ test_op (add_constant S.one) x1 x1; + test ~valid:false @@ test_op (add_constant S.zero) x1 z1; + ] + + let tests_sub = + let sub = add ~qr:S.mone in + let x1, y1, z1 = (si 6, si 2, si 4) in + let x2, y2, z2 = (si 6, si 0, si 6) in + [ + test ~valid:true ~name:"Num.test_sub" @@ test_bop sub x1 y1 z1; + test ~valid:true ~name:"Num.test_sub" @@ test_bop sub x2 y2 z2; + test ~valid:false @@ test_bop sub x1 y1 (si 8); + test ~valid:false @@ test_bop sub x2 y2 y2; + ] + + let tests_mul = + let x1, y1, z1 = (si 6, si 2, si 12) in + let x2, y2, z2 = (si 6, si 0, si 0) in + let x3, y3, z3 = (si 6, si 1, si 6) in + + [ + test ~valid:true ~name:"Num.test_mul" @@ test_bop mul x1 y1 z1; + test ~valid:true ~name:"Num.test_mul" @@ test_bop mul x2 y2 z2; + test ~valid:true ~name:"Num.test_mul" @@ test_bop mul x3 y3 z3; + test ~valid:false @@ test_bop mul x1 y1 (si 1); + test ~valid:false @@ test_bop mul x2 y2 x2; + ] + + let tests_div = + let x1, y1, z1 = (si 6, si 2, si 3) in + [ + test ~valid:true ~name:"Num.test_div" @@ test_bop div x1 y1 z1; + test ~valid:false @@ test_bop div x1 y1 (si 4); + test ~valid:false @@ test_bop div (si 0) (si 0) (si 4); + ] + + let test_num x y z () = + let* x = input ~kind:`Public x in + let* y = input y in + let* z = input z in + let* o = add x y in + let* o = mul o y in + let* o = add_constant S.one o in + let* o = div o y in + assert_equal o z + + let tests_num = + let i = si 1 in + let o = si 3 in + let bad_o = si 4 in + [ + test ~valid:true ~name:"Num.test_num" @@ test_num i i o; + test ~valid:false @@ test_num i i bad_o; + ] + + let test_pow5 x z () = + let* x = input ~kind:`Public x in + let* z = input z in + let* z' = pow5 x in + assert_equal z z' + + let tests_pow5 = + [ + test ~valid:true ~name:"pow5" @@ test_pow5 (si 0) (si 0); + test ~valid:true @@ test_pow5 (si 1) (si 1); + test ~valid:true @@ test_pow5 (si 2) (si 32); + test ~valid:true @@ test_pow5 (si (-1)) (si (-1)); + test ~valid:false @@ test_pow5 (si 0) (si 1); + ] + + let test_pow x n_list expected_res () = + let* x = input ~kind:`Public x in + let* expected_res = input ~kind:`Public expected_res in + let* n_list = mapM input n_list in + let* o = pow x n_list in + assert_equal o expected_res + + let tests_pow = + let open Input in + [ + test ~valid:true ~name:"pow" @@ test_pow (si 0) [bool true] (si 0); + test ~valid:true ~name:"pow" @@ test_pow (si 0) [bool false] (si 1); + test ~valid:true ~name:"pow" + @@ test_pow (si 1) [bool true; bool true] (si 1); + test ~valid:true ~name:"pow" + @@ test_pow (si 3) [bool true; bool true] (si 27); + test ~valid:true ~name:"pow" + @@ test_pow + (si 2) + [bool false; bool true; bool true; bool false] + (si 64); + test ~valid:true ~name:"pow" + @@ test_pow + (si 2) + [ + bool true; + bool false; + bool false; + bool true; + bool true; + bool false; + ] + (si 33554432); + test ~valid:true ~name:"pow" + @@ test_pow (si (-1)) [bool false; bool true; bool true] (si 1); + test ~valid:false @@ test_pow (si 2) [bool true] (si 1); + ] + + let tests_equal = + [ + test ~valid:true ~name:"Num.test_equal" @@ test_equal (si 0) (si 0); + test ~valid:false @@ test_equal (si 10) (si 0); + ] + + let test_bits_of_scalar sx expected () = + let nb_bits = List.length expected in + let* x = input sx in + let* xbits = bits_of_scalar ~nb_bits x in + iterM + (fun (xbit, e) -> + if e = 0 then Bool.assert_false xbit else Bool.assert_true xbit) + (List.combine (of_list xbits) expected) + + let tests_bits_of_scalar = + let test = test ~name:"Num.bits_of_scalar" in + [ + test ~valid:true @@ test_bits_of_scalar (si 9) [1; 0; 0; 1; 0]; + test ~valid:true @@ test_bits_of_scalar (si 30) [0; 1; 1; 1; 1]; + test ~valid:false @@ test_bits_of_scalar (si 3) [1; 1; 1; 0; 0]; + ] + + let test_upper_bound_unsafe ~bound sx () = + let* x = input sx in + with_bool_check @@ is_upper_bounded_unsafe ~bound x + + let test_upper_bound ~bound sx () = + let* x = input sx in + let* b = is_upper_bounded ~bound x in + Bool.assert_true b + + let tests_upper_bound ~safe = + let test = test ~name:"Num.is_upper_bounded" in + let test_upper_bound = + if safe then test_upper_bound else test_upper_bound_unsafe + in + [ + test ~valid:true @@ test_upper_bound ~bound:Z.one (si 0); + test ~valid:true @@ test_upper_bound ~bound:(Z.of_int 5) (si 4); + test ~valid:true @@ test_upper_bound ~bound:(Z.of_int 101) (si 100); + test ~valid:true @@ test_upper_bound ~bound:Z.(S.order - one) (si (-2)); + test ~valid:true + @@ test_upper_bound ~bound:Z.one (Input.scalar @@ S.(of_z order)); + test ~valid:false @@ test_upper_bound ~bound:Z.one (si 1); + test ~valid:false @@ test_upper_bound ~bound:(Z.of_int 5) (si 5); + test ~valid:false @@ test_upper_bound ~bound:(Z.of_int 5) (si 100); + test ~valid:false @@ test_upper_bound ~bound:Z.one (si (-1)); + test ~valid:false @@ test_upper_bound ~bound:Z.(S.order - one) (si (-1)); + ] + + let test_upper_bound_totality is_upper_bounded ~bound sx () = + let* x = input sx in + let* _ = is_upper_bounded ~bound x in + ret unit + + let tests_upper_bound_totality ~safe = + let test = test ~name:"Num.is_upper_bounded_totality" in + let test_upper_bound = + test_upper_bound_totality (fun ~bound x -> + if safe then is_upper_bounded ~bound x + else is_upper_bounded_unsafe ~bound x) + in + [ + test ~valid:safe @@ test_upper_bound ~bound:(Z.of_int 5) (si 100); + test ~valid:safe @@ test_upper_bound ~bound:Z.one (si (-1)); + test ~valid:safe + @@ test_upper_bound ~bound:Z.(div S.order (of_int 2)) (si (-1)); + ] + + let test_geq (a, bound_a) (b, bound_b) () = + let* a = input a in + let* b = input b in + let* r = Num.geq (a, bound_a) (b, bound_b) in + Bool.assert_true r + + let tests_geq = + let test = test ~name:"Num.geq" in + [ + test ~valid:true @@ test_geq (si 0, Z.of_int 100) (si 0, Z.of_int 100); + test ~valid:true @@ test_geq (si 5, Z.of_int 6) (si 3, Z.of_int 100); + test ~valid:false @@ test_geq (si 5, Z.of_int 6) (si 6, Z.of_int 7); + ] + + let tests = + tests_add @ tests_add_constant @ tests_sub @ tests_mul @ tests_num + @ tests_div @ tests_pow5 @ tests_pow @ tests_equal @ tests_bits_of_scalar + @ tests_upper_bound ~safe:false + @ tests_upper_bound ~safe:true + @ tests_upper_bound_totality ~safe:false + @ tests_upper_bound_totality ~safe:true + @ tests_geq + end + +module Bool : Test = +functor + (L : LIB) + -> + struct + open L + open L.Bool + + open Utils (L) + + let test_assert_true b () = + let* b = input ~kind:`Public b in + assert_true b + + let test_assert_false b () = + let* b = input ~kind:`Public b in + assert_false b + + let tests_assert_true_and_false = + [ + test ~valid:true ~name:"Bool.test_assert_true_and_false" + @@ test_assert_true (Input.bool true); + test ~valid:false @@ test_assert_true (Input.bool false); + test ~valid:true ~name:"Bool.test_assert_true_and_false" + @@ test_assert_false (Input.bool false); + test ~valid:false @@ test_assert_false (Input.bool true); + ] + + let tests_equal = + [ + test ~valid:true ~name:"Bool.test_equal" + @@ test_equal (Input.bool true) (Input.bool true); + test ~valid:false @@ test_equal (Input.bool false) (Input.bool true); + ] + + let test_is_zero x () = + let* x = input ~kind:`Public x in + let* b = Num.is_zero x in + assert_true b + + let tests_is_zero = + [ + test ~valid:true ~name:"Bool.test_is_zero" @@ test_is_zero (si 0); + test ~valid:false @@ test_is_zero (si 1); + ] + + let test_is_not_zero x () = + let* x = input ~kind:`Public x in + let* b = Num.is_not_zero x in + assert_true b + + let tests_is_not_zero = + [ + test ~valid:true ~name:"Bool.test_is_not_zero" @@ test_is_not_zero (si 5); + test ~valid:false @@ test_is_not_zero (si 0); + ] + + let test_assert_bool x () = + let* x = input ~kind:`Public x in + Num.assert_bool x + + let tests_assert_bool = + [ + test ~valid:true ~name:"Bool.test_assert_bool" @@ test_assert_bool (si 0); + test ~valid:true ~name:"Bool.test_assert_bool" + @@ test_assert_bool (si 1); + test ~valid:false @@ test_assert_bool (si (2 + Random.int 1000)); + ] + + let test_band x y z () = + let* x = input ~kind:`Public x in + let* y = input y in + let* z = input z in + let* z' = band x y in + assert_equal z z' + + let tests_band = + List.map + (test ~valid:true ~name:"Bool.test_band") + Input. + [ + test_band (bool false) (bool false) (bool false); + test_band (bool false) (bool true) (bool false); + test_band (bool true) (bool false) (bool false); + test_band (bool true) (bool true) (bool true); + ] + + let test_xor x y z () = + let* x = input ~kind:`Public x in + let* y = input y in + let* z = input z in + let* z' = xor x y in + assert_equal z z' + + let tests_xor = + List.map + (test ~valid:true ~name:"Bool.test_xor") + Input. + [ + test_xor (bool false) (bool false) (bool false); + test_xor (bool false) (bool true) (bool true); + test_xor (bool true) (bool false) (bool true); + test_xor (bool true) (bool true) (bool false); + ] + + let test_bor x y z () = + let* x = input ~kind:`Public x in + let* y = input y in + let* z = input z in + let* z' = bor x y in + assert_equal z z' + + let tests_bor = + List.map + (test ~valid:true ~name:"Bool.test_bor") + Input. + [ + test_bor (bool false) (bool false) (bool false); + test_bor (bool false) (bool true) (bool true); + test_bor (bool true) (bool false) (bool true); + test_bor (bool true) (bool true) (bool true); + ] + + let test_bnot x z () = + let* x = input ~kind:`Public x in + let* z = input z in + let* z' = bnot x in + assert_equal z z' + + let tests_bnot = + List.map + (test ~valid:true ~name:"Bool.test_bnot") + Input. + [ + test_bnot (bool false) (bool true); + test_bnot (bool true) (bool false); + ] + + let test_ifthenelse b x y z () = + let* b = input ~kind:`Public b in + let* x = input ~kind:`Public x in + let* y = input ~kind:`Public y in + let* z = input z in + let* z' = ifthenelse b x y in + assert_equal z z' + + let tests_ifthenelse = + List.map + (test ~valid:true ~name:"Bool.test_ifthenelse") + Input. + [ + test_ifthenelse (bool true) (si 0) (si 1) (si 0); + test_ifthenelse (bool false) (si 0) (si 1) (si 1); + test_ifthenelse (bool true) (bool true) (bool false) (bool true); + test_ifthenelse (bool false) (bool true) (bool false) (bool false); + test_ifthenelse + (bool true) + (pair (si 0) (si 1)) + (pair (si 2) (si 3)) + (pair (si 0) (si 1)); + test_ifthenelse + (bool false) + (pair (si 0) (si 1)) + (pair (si 2) (si 3)) + (pair (si 2) (si 3)); + test_ifthenelse + (bool true) + (list [si 0; si 1]) + (list [si 2; si 3]) + (list [si 0; si 1]); + test_ifthenelse + (bool false) + (list [si 0; si 1]) + (list [si 2; si 3]) + (list [si 2; si 3]); + ] + @ List.map + (test ~valid:false) + Input. + [ + test_ifthenelse (bool true) (si 0) (si 1) (si 1); + test_ifthenelse (bool false) (si 0) (si 1) (si 0); + ] + + let test_swap b x y u v () = + let* b = input ~kind:`Public b in + let* x = input ~kind:`Public x in + let* y = input ~kind:`Public y in + let* u = input u in + let* v = input v in + let* res = swap b x y in + let res_u, res_v = of_pair res in + let* _ = assert_equal res_u u in + assert_equal res_v v + + let tests_swap = + List.map + (test ~valid:true ~name:"Bool.test_swap") + Input. + [ + test_swap (bool true) (si 0) (si 1) (si 1) (si 0); + test_swap (bool false) (si 0) (si 1) (si 0) (si 1); + test_swap + (bool true) + (bool true) + (bool false) + (bool false) + (bool true); + test_swap + (bool false) + (bool true) + (bool false) + (bool true) + (bool false); + test_swap + (bool true) + (pair (si 0) (si 1)) + (pair (si 2) (si 3)) + (pair (si 2) (si 3)) + (pair (si 0) (si 1)); + test_swap + (bool false) + (pair (si 0) (si 1)) + (pair (si 2) (si 3)) + (pair (si 0) (si 1)) + (pair (si 2) (si 3)); + test_swap + (bool true) + (list [si 0; si 1]) + (list [si 2; si 3]) + (list [si 2; si 3]) + (list [si 0; si 1]); + test_swap + (bool false) + (list [si 0; si 1]) + (list [si 2; si 3]) + (list [si 0; si 1]) + (list [si 2; si 3]); + ] + @ List.map + (test ~valid:false) + Input. + [ + test_swap (bool true) (si 0) (si 1) (si 0) (si 1); + test_swap (bool false) (si 0) (si 1) (si 1) (si 0); + ] + + let test_full_adder l r c_in c_out s_out () = + let* l = input ~kind:`Public l in + let* r = input ~kind:`Public r in + let* c_in = input c_in in + let* s_out = input s_out in + let* c_out = input c_out in + let* p = Bool.full_adder l r c_in in + let s, c = of_pair p in + assert_equal s s_out >* assert_equal c c_out + + let tests_full_adder = + (* table from from https://en.wikipedia.org/wiki/Adder_(electronics)#Full_adder *) + List.map + (test ~valid:true ~name:"Bool.test_full_adder") + Input. + [ + test_full_adder + (bool false) + (bool false) + (bool false) + (bool false) + (bool false); + test_full_adder + (bool false) + (bool false) + (bool true) + (bool false) + (bool true); + test_full_adder + (bool false) + (bool true) + (bool false) + (bool false) + (bool true); + test_full_adder + (bool false) + (bool true) + (bool true) + (bool true) + (bool false); + test_full_adder + (bool true) + (bool false) + (bool false) + (bool false) + (bool true); + test_full_adder + (bool true) + (bool false) + (bool true) + (bool true) + (bool false); + test_full_adder + (bool true) + (bool true) + (bool false) + (bool true) + (bool false); + test_full_adder + (bool true) + (bool true) + (bool true) + (bool true) + (bool true); + ] + @ List.map + (test ~valid:false) + Input. + [ + test_full_adder + (bool true) + (bool true) + (bool true) + (bool true) + (bool false); + test_full_adder + (bool false) + (bool false) + (bool false) + (bool true) + (bool false); + ] + + let tests = + tests_assert_true_and_false @ tests_equal @ tests_is_zero + @ tests_is_not_zero @ tests_assert_bool @ tests_band @ tests_xor + @ tests_bor @ tests_bnot @ tests_ifthenelse @ tests_swap + @ tests_full_adder + end + +module List_ : Test = +functor + (L : LIB) + -> + struct + open L + + open Utils (L) + + let test_add_list x z () = + let* x = input ~kind:`Public x in + let* z = input z in + let* y = Num.add_list x in + let y = to_list [y] in + let* z' = Num.add_list y in + assert_equal z z' + + let i = Input.(list @@ List.init 4 (fun _ -> scalar S.one)) + + let o = si 4 + + let i2 = Input.(list @@ List.init 5 (fun _ -> scalar S.one)) + + let o2 = si 5 + + let tests_add_list = + [ + test ~valid:true ~name:"List.test_add_list" @@ test_add_list i o; + test ~valid:true ~name:"List.test_add_list" @@ test_add_list i2 o2; + test ~valid:false @@ test_add_list i o2; + ] + + let test_mul_list x z () = + let* x = input ~kind:`Public x in + let* z = input z in + let* y = Num.mul_list x in + let y = to_list [y] in + let* z' = Num.mul_list y in + assert_equal z z' + + let i = Input.(list @@ List.init 4 (fun _ -> scalar S.(one + one))) + + let o = si 16 + + let i2 = Input.(list @@ List.init 5 (fun _ -> scalar S.mone)) + + let o2 = si (-1) + + let tests_mul_list = + [ + test ~valid:true ~name:"List.test_mul_list" @@ test_mul_list i o; + test ~valid:true ~name:"List.test_mul_list" @@ test_mul_list i2 o2; + test ~valid:false @@ test_mul_list i o2; + ] + + let tests_equal = + let i = Input.(list [si 10; si 2]) in + let j = Input.(list [si 2; si 10]) in + [ + test ~valid:true ~name:"List.test_equal" @@ test_equal i i; + test ~valid:false @@ test_equal i j; + ] + + let test_hd l z () = + let* l = input ~kind:`Public l in + let* z = input z in + let* x = hd l in + assert_equal x z + + let tests_hd = + let i = Input.(list [si 2; si 20]) in + let o = si 2 in + [test ~valid:true ~name:"List.test_hd" @@ test_hd i o] + + let tests = tests_add_list @ tests_equal @ tests_hd @ tests_mul_list + end + +module Tuple : Test = +functor + (L : LIB) + -> + struct + open L + + open Utils (L) + + let tests_equal = + let i = Input.(pair (si 0) (si 1)) in + let j = Input.(pair (si 1) (si 0)) in + [ + test ~valid:true ~name:"Tuple.test_equal" @@ test_equal i i; + test ~valid:false @@ test_equal i j; + ] + + let test_point x y z () = + let* x = input ~kind:`Public x in + let* y = input y in + let* z = input z in + let* z' = add2 x y in + assert_equal z z' + + let i = Input.(pair (si 1) (si 0)) + + let o = Input.(pair (si 2) (si 0)) + + let tests_point = + [ + test ~valid:true ~name:"Tuple.test_point" @@ test_point i i o; + test ~valid:false @@ test_point i i i; + ] + + let tests = tests_equal @ tests_point + end + +module Bytes : Test = +functor + (L : LIB) + -> + struct + open L + open L.Bytes + + open Utils (L) + + let input_bitlist l = Input.list (List.map Input.bool l) + + let test_add a b z () = + let* a = input ~kind:`Public a in + let* b = input b in + let* z = input z in + let* z' = add ~ignore_carry:true a b in + assert_equal z z' + + let tests_add = + let ex = Plompiler.Utils.(bitlist @@ bytes_of_hex "08") in + let input_bitlist l = Input.list (List.map Input.bool l) in + let i = input_bitlist ex in + let o = input_bitlist Plompiler.Utils.(bitlist @@ bytes_of_hex "10") in + [ + test ~valid:true ~name:"Bytes.test_add" @@ test_add i i o; + test ~valid:false ~name:"Bytes.test_add" @@ test_add o o i; + ] + + let test_xor a b z () = + let* a = input ~kind:`Public a in + let* b = input b in + let* z = input z in + let* z' = xor a b in + assert_equal z z' + + let tests_xor = + let ex = Plompiler.Utils.(bitlist @@ bytes_of_hex "08") in + let i = input_bitlist ex in + let o = input_bitlist Plompiler.Utils.(bitlist @@ bytes_of_hex "00") in + let i1 = + input_bitlist Plompiler.Utils.(bitlist @@ bytes_of_hex "510e527f") + in + let i2 = + input_bitlist Plompiler.Utils.(bitlist @@ bytes_of_hex "00000041") + in + let o1 = + input_bitlist Plompiler.Utils.(bitlist @@ bytes_of_hex "510e523e") + in + [ + test ~valid:true ~name:"Bytes.test_xor" @@ test_xor i i o; + test ~valid:true ~name:"Bytes.blake" @@ test_xor i1 i2 o1; + test ~valid:false ~name:"Bytes.test_xor" @@ test_xor o o i; + ] + + let test_ifthenelse_bytes b l r z () = + let* b = input ~kind:`Public b in + let* l = input ~kind:`Public l in + let* r = input ~kind:`Public r in + let* z = input z in + let* o = Bool.ifthenelse b l r in + assert_equal z o + + let tests_ifthenelse_bytes = + let l = input_bitlist Plompiler.Utils.(bitlist @@ bytes_of_hex "01") in + let r = input_bitlist Plompiler.Utils.(bitlist @@ bytes_of_hex "00") in + [ + test ~valid:true ~name:"Bytes.test_ifthenelse" + @@ test_ifthenelse_bytes (Input.bool true) l r l; + test ~valid:true ~name:"Bytes.test_ifthenelse" + @@ test_ifthenelse_bytes (Input.bool false) l r r; + test ~valid:false ~name:"Bytes.test_ifthenelse" + @@ test_ifthenelse_bytes (Input.bool false) l r l; + ] + + let test_rotate l i z () = + let* l = input ~kind:`Public l in + let* z = input z in + let o = rotate l i in + assert_equal o z + + let tests_rotate = + List.map + (fun (i, a, b) -> + let a = + input_bitlist Plompiler.Utils.(bitlist @@ Stdlib.Bytes.of_string a) + in + let b = + input_bitlist Plompiler.Utils.(bitlist @@ Stdlib.Bytes.of_string b) + in + test ~valid:true ~name:"Bytes.test_rotate" @@ test_rotate a i b) + [ + (1, "\001", "\128"); + (2, "\001", "\064"); + (3, "\001", "\032"); + (4, "\001", "\016"); + (5, "\001", "\008"); + (6, "\001", "\004"); + (7, "\001", "\002"); + (1, "\000\001", "\128\000"); + (2, "\000\001", "\064\000"); + (3, "\000\001", "\032\000"); + (4, "\000\001", "\016\000"); + (5, "\000\001", "\008\000"); + (6, "\000\001", "\004\000"); + (7, "\000\001", "\002\000"); + (1, "\000\000\001", "\128\000\000"); + (2, "\000\000\001", "\064\000\000"); + (3, "\000\000\001", "\032\000\000"); + (4, "\000\000\001", "\016\000\000"); + (5, "\000\000\001", "\008\000\000"); + (6, "\000\000\001", "\004\000\000"); + (7, "\000\000\001", "\002\000\000"); + ] + + let tests = tests_add @ tests_xor @ tests_ifthenelse_bytes @ tests_rotate + end + +module ECC : Test = +functor + (L : LIB) + -> + struct + open L + open L.Bool + open L.Ecc + + open Utils (L) + + module W = Mec.Curve.Jubjub.AffineWeierstrass + module E = Mec.Curve.Jubjub.AffineEdwards + + let test_weierstrass_add x y z () = + let* x = input ~kind:`Public x in + let* y = input y in + let* z = input z in + let* z' = weierstrass_add x y in + let* b = equal z z' in + assert_true b + + let tests_weierstrass_add = + let s_of_base s = S.of_z (W.Base.to_z s) in + let p1 = W.random () in + let p2 = W.random () in + let p1_i = + Input.( + pair + (scalar @@ s_of_base @@ W.get_x_coordinate p1) + (scalar @@ s_of_base @@ W.get_y_coordinate p1)) + in + let p2_i = + Input.( + pair + (scalar @@ s_of_base @@ W.get_x_coordinate p2) + (scalar @@ s_of_base @@ W.get_y_coordinate p2)) + in + let o = + let p = W.add p1 p2 in + Input.( + pair + (scalar @@ s_of_base @@ W.get_x_coordinate p) + (scalar @@ s_of_base @@ W.get_y_coordinate p)) + in + [ + test ~valid:true ~name:"ECC.test_weierstrass_add" + @@ test_weierstrass_add p1_i p2_i o; + test ~valid:false ~name:"ECC.test_weierstrass_add" + @@ test_weierstrass_add p1_i p2_i p1_i; + ] + + let test_edwards_add x y z () = + let* x = input ~kind:`Public x in + let* y = input y in + let* z = input z in + let* z' = edwards_add x y in + let* b = equal z z' in + assert_true b + + let tests_edwards_add = + let s_of_base s = S.of_z (E.Base.to_z s) in + let p1 = E.random () in + let p2 = E.random () in + let p1_i = + Input.( + pair + (scalar @@ s_of_base @@ E.get_u_coordinate p1) + (scalar @@ s_of_base @@ E.get_v_coordinate p1)) + in + let p2_i = + Input.( + pair + (scalar @@ s_of_base @@ E.get_u_coordinate p2) + (scalar @@ s_of_base @@ E.get_v_coordinate p2)) + in + let o = + let p = E.add p1 p2 in + Input.( + pair + (scalar @@ s_of_base @@ E.get_u_coordinate p) + (scalar @@ s_of_base @@ E.get_v_coordinate p)) + in + [ + test ~valid:true ~name:"ECC.test_edwards_add" + @@ test_edwards_add p1_i p2_i o; + test ~valid:false @@ test_edwards_add p1_i p2_i p1_i; + ] + + let tests = tests_weierstrass_add @ tests_edwards_add + end + +module Rest : Test = +functor + (L : LIB) + -> + struct + open L + open L.Bool + open L.Num + + open Utils (L) + + let test_full_adder l r c_in o () = + let* l = input ~kind:`Public l in + let* r = input r in + let* o = input o in + let* c_in = input c_in in + let* o' = full_adder l r c_in in + assert_equal o o' + + let tests_full_adder = + (* table from from https://en.wikipedia.org/wiki/Adder_(electronics)#Full_adder *) + List.map + (test ~valid:true ~name:"Rest.test_full_adder") + Input. + [ + test_full_adder + (bool false) + (bool false) + (bool false) + (pair (bool false) (bool false)); + test_full_adder + (bool false) + (bool false) + (bool true) + (pair (bool true) (bool false)); + test_full_adder + (bool false) + (bool true) + (bool false) + (pair (bool true) (bool false)); + test_full_adder + (bool false) + (bool true) + (bool true) + (pair (bool false) (bool true)); + test_full_adder + (bool true) + (bool false) + (bool false) + (pair (bool true) (bool false)); + test_full_adder + (bool true) + (bool false) + (bool true) + (pair (bool false) (bool true)); + test_full_adder + (bool true) + (bool true) + (bool false) + (pair (bool false) (bool true)); + test_full_adder + (bool true) + (bool true) + (bool true) + (pair (bool true) (bool true)); + ] + + let test_scalar_of_bytes b s () = + let* b = input ~kind:`Public b in + let* s = input s in + let* s' = scalar_of_bytes b in + assert_equal s s' + + let t s () = + let b = Stdlib.Bytes.of_string s in + let bs = Plompiler.Utils.bitlist ~le:true b in + let bs = Input.list (List.map Input.bool bs) in + test_scalar_of_bytes bs (Input.scalar (S.of_bytes_exn b)) () + + let tests_scalar_of_bytes = + [test ~valid:true ~name:"Rest.test_scalar_of_bytes" @@ t "\x010101"] + + let tests = tests_full_adder @ tests_scalar_of_bytes + end + +let tests = + let both = + [ + ("Num", (module Num : Test)); + ("Bool", (module Bool : Test)); + ("List", (module List_ : Test)); + ("Rest", (module Rest : Test)); + ("Tuple", (module Tuple : Test)); + ("ECC", (module ECC : Test)); + ("Bytes", (module Bytes : Test)); + ] + in + (* This test uses plonk and it is marked quick so that it + is always run by the CI *) + Alcotest.test_case + ("Num" ^ " plonk") + `Quick + (to_test ~plonk:(module Plonk.Main_protocol) (module Num : Test)) + :: List.map (fun (name, m) -> Alcotest.test_case name `Quick (to_test m)) both + @ List.map + (fun (name, m) -> + Alcotest.test_case + (name ^ " plonk") + `Slow + (to_test ~plonk:(module Plonk.Main_protocol) m)) + both diff --git a/src/lib_plonk/test_plompiler/test_edwards.ml b/src/lib_plonk/test_plompiler/test_edwards.ml new file mode 100644 index 000000000000..040bb83684f3 --- /dev/null +++ b/src/lib_plonk/test_plompiler/test_edwards.ml @@ -0,0 +1,325 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk_test + +module Vectors = struct + let g = + ( S.of_string + "0x187d2619ff114316d237e86684fb6e3c6b15e9b924fa4e322764d3177508297a", + S.of_string + "0x6230c613f1b460e026221be21cf4eabd5a8ea552db565cb18d3cabc39761eb9b" ) + + let g2 = + ( S.of_string + "0x35d84b4bbb504c30df6005260b550f1b00db242e7c2dee016712bd2b0f13281b", + S.of_string + "0x412ef797a253102e1bd0d6a40e717a0abfa0b7c56d0ef92a81cb8292fdc6f6d5" ) + + (* https://github.com/zcash/librustzcash/blob/1b4aab0b76d465e4fe548f230b7c3ebdc398a1a5/zcash_primitives/src/constants.rs *) + let valid_points = + [ + (S.zero, S.one); + ( S.of_string + "0x73c016a42ded9578b5ea25de7ec0e3782f0c718f6f0fbadd194e42926f661b51", + S.of_string + "0x289e87a2d3521b5779c9166b837edc5ef9472e8bc04e463277bfabd432243cca" + ); + ( S.of_string + "0x15a36d1f0f390d8852a35a8c1908dd87a361ee3fd48fdf77b9819dc82d90607e", + S.of_string + "0x015d8c7f5b43fe33f7891142c001d9251f3abeeb98fad3e87b0dc53c4ebf1891" + ); + ( S.of_string + "0x664321a58246e2f6eb69ae39f5c84210bae8e5c46641ae5c76d6f7c2b67fc475", + S.of_string + "0x362e1500d24eee9ee000a46c8e8ce8538bb22a7f1784b49880ed502c9793d457" + ); + ( S.of_string + "0x323a6548ce9d9876edc5f4a9cff29fd57d02d50e654b87f24c767804c1c4a2cc", + S.of_string + "0x2f7ee40c4b56cad891070acbd8d947b75103afa1a11f6a8584714beca33570e9" + ); + ( S.of_string + "0x3bd2666000b5479689b64b4e03362796efd5931305f2f0bf46809430657f82d1", + S.of_string + "0x494bc52103ab9d0a397832381406c9e5b3b9d8095859d14c99968299c3658aef" + ); + ( S.of_string + "0x63447b2ba31bb28ada049746d76d3ee51d9e5ca21135ff6fcb3c023258d32079", + S.of_string + "0x64ec4689e8bfb6e564cdb1070a136a28a80200d2c66b13a7436082119f8d629a" + ); + ] +end + +module JubjubEdwards (L : LIB) = struct + module MecJubJub = Mec.Curve.Jubjub.AffineEdwards + open L + + let point_of_mec p = + let u = MecJubJub.get_u_coordinate p in + let v = MecJubJub.get_v_coordinate p in + ( S.of_bytes_exn (MecJubJub.Base.to_bytes u), + S.of_bytes_exn (MecJubJub.Base.to_bytes v) ) + + open Helpers.Utils (L) + + open Plompiler.JubjubEdwards (L) + + let add_circuit p q expected () = + let* p = input_point ~kind:`Public p in + let* q = input_point ~kind:`Public q in + let* r = input_point expected in + let* o = add p q in + assert_equal o r + + let test_vectors = + List.init 7 (fun _ -> (MecJubJub.random (), MecJubJub.random ())) + + let inputs = + let open Vectors in + (* 0 + 0 = 0 *) + (id, id) :: (* 0 + g = g *) + (id, g) :: (* g + g = g2 *) + (g, g) + :: (* p + q = r *) + List.map (fun (p, q) -> (point_of_mec p, point_of_mec q)) test_vectors + + let expected = + let open Vectors in + (* 0 + 0 = 0 *) + id :: (* 0 + g = g *) + g :: (* g + g = g2 *) + g2 + :: (* p + q = r *) + List.map + (fun (input1, input2) -> + let res = MecJubJub.add input1 input2 in + point_of_mec res) + test_vectors + + let wrong = List.map (fun _ -> (S.random (), S.random ())) expected + + let test_add = + List.map2 + (fun (p1, p2) e -> + test ~valid:true ~name:"Edwards.test_add" @@ add_circuit p1 p2 e) + inputs + expected + @ List.map2 + (fun (p1, p2) w -> test ~valid:false @@ add_circuit p1 p2 w) + inputs + wrong + + let cond_add_circuit p q b expected () = + let* p = input_point ~kind:`Public p in + let* q = input_point ~kind:`Public q in + let* b = input ~kind:`Public (Input.bool b) in + let* r = input_point expected in + let* o = cond_add p q b in + assert_equal o r + + let inputs = + List.map + (fun (p, q) -> (point_of_mec p, point_of_mec q, Random.bool ())) + test_vectors + + let expected = + List.map2 + (fun (input1, input2) (_, _, b) -> + let res = if b then MecJubJub.add input1 input2 else input1 in + point_of_mec res) + test_vectors + inputs + + let wrong = List.map (fun _ -> (S.random (), S.random ())) expected + + let test_cond_add = + List.map2 + (fun (p1, p2, b) e -> + test ~valid:true ~name:"Edwards.test_cond_add" + @@ cond_add_circuit p1 p2 b e) + inputs + expected + @ List.map2 + (fun (p1, p2, b) w -> test ~valid:false @@ cond_add_circuit p1 p2 b w) + inputs + wrong + + let input_bytes bytes = input Input.(list (List.map bool bytes)) + + let scalar_mul_circuit p input_b expected () = + let* p = input_point ~kind:`Public p in + let* b = input_bytes input_b in + let* r = input_point expected in + let* o = scalar_mul b p in + assert_equal o r + + let test_vectors = + let size = Z.log2 S.order in + List.init 7 (fun _ -> + (MecJubJub.random (), List.init size (fun _ -> Stdlib.Random.bool ()))) + + let inputs = + let open Vectors in + (* g^0 = 0 *) + (g, [false]) :: (* g^1 = g *) + (g, [true]) + :: (* g^2 = g2 *) + (g, [false; true]) + :: (* p + q = r *) + List.map + (fun (input_p, input_b) -> (point_of_mec input_p, input_b)) + test_vectors + + let expected = + let open Vectors in + (* g^0 = 0 *) + id :: (* g^1 = g *) + g :: (* g^2 = g2 *) + g2 + :: (* p + q = r *) + List.map + (fun (input_p, input_b) -> + let exponent = Plompiler.Utils.bool_list_to_scalar input_b in + let exponent = MecJubJub.Scalar.of_bytes_exn (S.to_bytes exponent) in + let res = MecJubJub.mul input_p exponent in + point_of_mec res) + test_vectors + + let wrong = List.map (fun _ -> (S.random (), S.random ())) expected + + let test_scalar_mul = + List.map2 + (fun (p, b) e -> + test ~valid:true ~name:"Edwards.test_scalar_mul" + @@ scalar_mul_circuit p b e) + inputs + expected + @ List.map2 + (fun (p, b) w -> test ~valid:false @@ scalar_mul_circuit p b w) + inputs + wrong + + let multi_scalar_mul_circuit ps bs expected () = + let* p = mapM (fun p -> input_point ~kind:`Public p) ps in + let* b = mapM (fun b -> input_bytes b) bs in + let* r = input_point expected in + let* o = multi_scalar_mul (to_list b) (to_list p) in + assert_equal o r + + let test_vectors = + let size = Z.log2 S.order in + List.init 5 (fun i -> + ( List.init (2 + i) (fun _ -> MecJubJub.random ()), + List.init (2 + i) (fun _ -> + List.init size (fun _ -> Stdlib.Random.bool ())) )) + + let inputs = + (* Pi p_i^s_i = r *) + List.map + (fun (points, exponents) -> + let points = List.map point_of_mec points in + (points, exponents)) + test_vectors + + let expected = + List.map + (fun (points, exponents) -> + let multiplied = + List.map2 + (fun input_p input_b -> + let exponent = Plompiler.Utils.bool_list_to_scalar input_b in + let exponent = + MecJubJub.Scalar.of_bytes_exn (S.to_bytes exponent) + in + MecJubJub.mul input_p exponent) + points + exponents + in + let summed = + List.fold_left + (fun acc p -> MecJubJub.add acc p) + MecJubJub.zero + multiplied + in + point_of_mec summed) + test_vectors + + let wrong = List.map (fun _ -> (S.random (), S.random ())) expected + + let test_multi_scalar_mul = + List.map2 + (fun (p, b) e -> + test ~valid:true ~name:"Edwards.test_multi_scalar_mul" + @@ multi_scalar_mul_circuit p b e) + inputs + expected + @ List.map2 + (fun (p, b) w -> + test ~valid:false ~name:"Edwards.test_multi_scalar_mul" + @@ multi_scalar_mul_circuit p b w) + inputs + wrong + + let is_on_curve_circuit p () = + let* p = input_point ~kind:`Public p in + let* b = is_on_curve p in + Bool.assert_true b + + let test_vectors = List.init 10 (fun _ -> MecJubJub.random ()) + + let inputs = + let open Vectors in + valid_points @ List.map point_of_mec test_vectors + + let wrong = List.map (fun _ -> (S.random (), S.random ())) inputs + + let test_is_on_curve = + List.map + (fun i -> + test ~valid:true ~name:"Edwards.test_is_on_curve" + @@ is_on_curve_circuit i) + inputs + @ List.map (fun w -> test ~valid:false @@ is_on_curve_circuit w) wrong + + let tests = + test_add @ test_cond_add @ test_scalar_mul @ test_is_on_curve + @ test_multi_scalar_mul +end + +let tests = + let open Helpers in + let both = [("JubJubEdward", (module JubjubEdwards : Test))] in + List.map (fun (name, m) -> Alcotest.test_case name `Quick (to_test m)) both + @ List.map + (fun (name, m) -> + Alcotest.test_case + (name ^ " plonk") + `Slow + (to_test ~plonk:(module Plonk.Main_protocol) m)) + both diff --git a/src/lib_plonk/test_plompiler/test_encoding.ml b/src/lib_plonk/test_plompiler/test_encoding.ml new file mode 100644 index 000000000000..6df692e3553e --- /dev/null +++ b/src/lib_plonk/test_plompiler/test_encoding.ml @@ -0,0 +1,203 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk_test +module CS = Plonk.Circuit +open Helpers + +(** + Example of the usage of encodings. +*) + +module Encoding : Test = +functor + (L : LIB) + -> + struct + open L + + open Utils (L) + + (** + [foo] is a circuit that takes a list of lines (pairs of 3D points) + and simply increments by 1 the second coordinate of every point. + This example shows how this simple task requires a great deal of packing + and unpacking. + *) + + let _foo : + ((scalar * (scalar * scalar)) * (scalar * (scalar * scalar))) list repr -> + ((scalar * (scalar * scalar)) * (scalar * (scalar * scalar))) list repr + t = + fun a -> + let a = of_list a in + foldM + (fun acc l -> + let p0, p1 = of_pair l in + let p0_x, aux = of_pair p0 in + let p0_y, p0_z = of_pair aux in + let p1_x, aux = of_pair p1 in + let p1_y, p1_z = of_pair aux in + + let* p0_y = Num.add_constant S.one p0_y in + let* p1_y = Num.add_constant S.one p1_y in + + let aux = pair p0_y p0_z in + let p0 = pair p0_x aux in + let aux = pair p1_y p1_z in + let p1 = pair p1_x aux in + let l = pair p0 p1 in + ret @@ to_list (l :: of_list acc)) + (to_list []) + a + + (** + Now we'll define the same circuit using Encodings. + We'll start by defining encodings for points and lines. + *) + + open Encodings (L) + + (** [point] is type of the high-level OCaml representation *) + type point = {x : int; y : int; z : int} + + (** [point_u] is an unpacked Plompiler representaion of [point]. + In general, for a record type [t], [t_u] will be a record type + with the same field names as [t], but holding Plompiler reprs. + It can be seen as an unpacking of the low-leve Plompiler + representation, which in this case will be + [(scalar * (scalar * scalar)) repr]. + *) + type point_u = {x : scalar repr; y : scalar repr; z : scalar repr} + + let s_of_int x = S.of_z (Z.of_int x) + + let s_to_int s = Z.to_int (S.to_z s) + + (** [point_encoding] provides us three functions: + - [encode : point_u -> (scalar * (scalar * scalar)) repr] + - [decode : (scalar * (scalar * scalar)) repr -> point_u] + - [input : point -> (scalar * (scalar * scalar)) Input.t ] + + The first two are used for packing/unpacking the date type in a circuit, + while the third one is helpful for processing its inputs. + *) + let point_encoding : (point, point_u, _) encoding = + conv + (fun {x; y; z} -> (x, (y, z))) + (fun (x, (y, z)) -> {x; y; z}) + (fun ({x; y; z} : point) -> (s_of_int x, (s_of_int y, s_of_int z))) + (fun (x, (y, z)) -> {x = s_to_int x; y = s_to_int y; z = s_to_int z}) + (obj3_encoding scalar_encoding scalar_encoding scalar_encoding) + + type line = {p0l : point; p1l : point} + + type line_u = {p0 : point_u; p1 : point_u} + + let line_encoding : (line, line_u, _) encoding = + conv + (fun {p0; p1} -> (p0, p1)) + (fun (p0, p1) -> {p0; p1}) + (fun {p0l; p1l} -> (p0l, p1l)) + (fun (p0l, p1l) -> {p0l; p1l}) + (obj2_encoding point_encoding point_encoding) + + (* Now we provide an equivalent definition for [foo], using the encodings. *) + let _foo' a = + let a = of_list a in + foldM + (fun acc l -> + let l = line_encoding.decode l in + + let* p0_y = Num.add_constant S.one l.p0.y in + let* p1_y = Num.add_constant S.one l.p1.y in + + let l = + line_encoding.encode + @@ {p0 = {l.p0 with y = p0_y}; p1 = {l.p1 with y = p1_y}} + in + ret @@ to_list (l :: of_list acc)) + (to_list []) + a + + let test_foo a expected () = + let* a = input ~kind:`Public a in + let* expected = input expected in + let* o = _foo' a in + assert_equal o expected + + let pz : point = {x = 0; y = 0; z = 0} + + let po : point = {x = 0; y = 1; z = 0} + + let lz = {p0l = pz; p1l = pz} + + let lo = {p0l = po; p1l = po} + + let inpt = Input.list @@ [line_encoding.input lz] + + let expected = Input.list @@ [line_encoding.input lo] + + let tests_foo = + [test ~name:"Encoding.test_foo" ~valid:true @@ test_foo inpt expected] + + let first_is_zero p = + let p = point_encoding.decode p in + (* We want the intermediate variable here, to test the + behaviour of input_flag *) + let* z = constant_scalar S.zero in + assert_equal p.x z + + let test_assertion a b () = + let* _a = input ~kind:`Public a in + let* _b = input b in + ret unit + + let enc' = with_assertion first_is_zero point_encoding + + let p1 : point = {x = 1; y = 1; z = 0} + + let tests_assertion = + [ + test ~name:"Encoding.test_assertion" ~valid:true + @@ test_assertion (enc'.input pz) (enc'.input po); + test ~name:"Encoding.test_assertion" ~valid:false + @@ test_assertion (enc'.input p1) (enc'.input po); + ] + + let tests = tests_foo @ tests_assertion + end + +let tests = + let both = [("Encoding", (module Encoding : Test))] in + List.map (fun (name, m) -> Alcotest.test_case name `Quick (to_test m)) both + @ List.map + (fun (name, m) -> + Alcotest.test_case + (name ^ " plonk") + `Slow + (to_test ~plonk:(module Plonk.Main_protocol) m)) + both diff --git a/src/lib_plonk/test_plompiler/test_enum.ml b/src/lib_plonk/test_plompiler/test_enum.ml new file mode 100644 index 000000000000..ad1ea24334d2 --- /dev/null +++ b/src/lib_plonk/test_plompiler/test_enum.ml @@ -0,0 +1,75 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk_test +module CS = Plonk.Circuit +open Helpers + +module Enum : Test = +functor + (L : LIB) + -> + struct + open L + + open Utils (L) + + module E = Enum (struct + let n = 4 + end) + + let test_switch k l expected () = + let* k = input ~kind:`Public k in + let* l = input l ~kind:`Public in + let* expected = input expected in + let* o = E.switch_case k l in + assert_equal o expected + + let l = Input.list [si 0; si 2; si 4; si 6] + + let tests_switch = + List.init 4 (fun i -> + test ~valid:true ~name:"Enum.test_switch" + @@ test_switch (si i) l (si @@ (2 * i))) + @ [ + test ~valid:true ~name:"Enum.test_switch" + @@ test_switch (si 5) l (si 0); + ] + @ [test ~valid:false @@ test_switch (si 1) l (si 0)] + + let tests = tests_switch + end + +let tests = + let both = [("Enum", (module Enum : Test))] in + List.map (fun (name, m) -> Alcotest.test_case name `Quick (to_test m)) both + @ List.map + (fun (name, m) -> + Alcotest.test_case + (name ^ " plonk") + `Slow + (to_test ~plonk:(module Plonk.Main_protocol) m)) + both diff --git a/src/lib_plonk/test_plompiler/test_input_com.ml b/src/lib_plonk/test_plompiler/test_input_com.ml new file mode 100644 index 000000000000..31c483ef6aa4 --- /dev/null +++ b/src/lib_plonk/test_plompiler/test_input_com.ml @@ -0,0 +1,88 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open LibCircuit +module CS = Plonk.Circuit +module Hash = Poseidon128.V (LibCircuit) +module Main = Plonk.Main_protocol +module Helpers = Plonk_test.Helpers + +open Plonk_test.Helpers.Utils (LibCircuit) + +let hash array = + let ctx = Poseidon128.P.init ~input_length:(Array.length array) () in + let ctx = Poseidon128.P.digest ctx array in + Poseidon128.P.get ctx + +let build_circuit x1 x2 x3 x4 y () = + let* expected = begin_input_com Fun.id |: Input.scalar y |> end_input_com in + let* x1, x2 = + begin_input_com (fun a b -> (a, b)) + |: Input.scalar x1 |: Input.scalar x2 |> end_input_com + in + let* x3 = input ~kind:`Public (Input.scalar x3) in + let* x4 = input (Input.scalar x4) in + let* out = Hash.digest ~input_length:4 (to_list [x1; x2; x3; x4]) in + with_bool_check (equal out expected) + +let test_input_com () = + let w = S.zero in + let circuit = build_circuit w w w w w () in + + let {cs; solver; input_com_sizes; _} = get_cs ~optimize:true circuit in + let _, public_input_size = get_inputs circuit in + assert (input_com_sizes = [1; 2]) ; + assert (public_input_size = 1) ; + let plonk_circuit = + Plonk.Circuit.to_plonk ~public_input_size ~input_com_sizes cs + in + let cname = "" in + let circuits_map = Plonk.SMap.singleton cname (plonk_circuit, 1) in + let zero_knowledge = false in + let pp_prv, pp_vrf = + Main.setup ~zero_knowledge circuits_map ~srs:Helpers.srs + in + let x1, x2, x3, x4 = (S.random (), S.random (), S.random (), S.random ()) in + let y = hash [|x1; x2; x3; x4|] in + let private_inputs = Solver.solve solver [|y; x1; x2; x3; x4|] in + assert (CS.sat cs [] private_inputs) ; + let input_com_y = Main.input_commit pp_prv [|y|] in + let input_com_x1x2 = Main.input_commit ~shift:1 pp_prv [|x1; x2|] in + let public = [|x3|] in + let input_commitments = [input_com_y; input_com_x1x2] in + let verifier_input_commitments = + [input_com_y.public; input_com_x1x2.public] + in + let inputs = Main.{input_commitments; witness = private_inputs} in + let inputs_map = Plonk.SMap.singleton cname [inputs] in + let verifier_inputs = + Plonk.SMap.singleton cname ([public], [verifier_input_commitments]) + in + let proof = Main.prove pp_prv ~inputs:inputs_map in + let verif_ok = Main.verify pp_vrf ~inputs:verifier_inputs proof in + assert verif_ok + +let tests = [Alcotest.test_case "Input commitment" `Quick test_input_com] diff --git a/src/lib_plonk/test_plompiler/test_linear_algebra.ml b/src/lib_plonk/test_plompiler/test_linear_algebra.ml new file mode 100644 index 000000000000..ed3f62fec433 --- /dev/null +++ b/src/lib_plonk/test_plompiler/test_linear_algebra.ml @@ -0,0 +1,75 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module S = Plompiler.Csir.Scalar +module VS = Plompiler.Linear_algebra.Make_VectorSpace (S) + +let random r c = Array.init r (fun _ -> Array.init c (fun _ -> S.random ())) + +let sizes = List.init 10 (fun i -> i + 1) + +let mk_tests f () = List.iter f sizes + +let test_distributive n = + let a = random (n + 1) n in + let b = random n (n + 2) in + let c = random n (n + 2) in + let m1 = VS.(mul a (add b c)) in + let m2 = VS.(add (mul a b) (mul a c)) in + assert (VS.equal m1 m2) + +let test_identity n = + let id_n = VS.identity n in + let inv = VS.inverse id_n in + assert (VS.equal id_n inv) ; + + let m = random n n in + assert (VS.(equal m (mul id_n m))) ; + assert (VS.(equal m (mul m id_n))) + +let test_transpose n = + let m = random (n + 1) n in + assert (VS.(equal m @@ transpose (transpose m))) + +let test_inverse n = + let open VS in + let id_n = identity n in + let m = random n n in + let inv = inverse m in + assert (equal id_n @@ mul m inv) ; + assert (equal id_n @@ mul inv m) ; + + try + let _ = inverse @@ zeros n n in + assert false + with Invalid_argument _ -> () + +let tests = + [ + Alcotest.test_case "Distributive" `Quick (mk_tests test_distributive); + Alcotest.test_case "Identity" `Quick (mk_tests test_identity); + Alcotest.test_case "Transpose" `Quick (mk_tests test_transpose); + Alcotest.test_case "Inverse" `Quick (mk_tests test_inverse); + ] diff --git a/src/lib_plonk/test_plompiler/test_lookup.ml b/src/lib_plonk/test_plompiler/test_lookup.ml new file mode 100644 index 000000000000..3f17826cbc60 --- /dev/null +++ b/src/lib_plonk/test_plompiler/test_lookup.ml @@ -0,0 +1,74 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk_test +module CS = Plonk.Circuit +open Helpers + +module Bool : Test = +functor + (L : LIB) + -> + struct + open L + open L.Bool + + open Utils (L) + + let test_bor x y z () = + (* A dummy input with the value of zero needs to be added if the number of + rows in the table is smaller than the number of wires architecture *) + let* _ = input ~kind:`Public (Input.bool false) in + let* x = input ~kind:`Public x in + let* y = input y in + let* z = input z in + let* z' = bor_lookup x y in + assert_equal z z' + + let tests_bor = + List.map + (test ~valid:true ~name:"Bool.test_bor_lookup") + Input. + [ + test_bor (bool false) (bool false) (bool false); + test_bor (bool false) (bool true) (bool true); + test_bor (bool true) (bool false) (bool true); + test_bor (bool true) (bool true) (bool true); + ] + + let tests = tests_bor + end + +let tests = + let both = [("Bool", (module Bool : Test))] in + List.map (fun (name, m) -> Alcotest.test_case name `Quick (to_test m)) both + @ List.map + (fun (name, m) -> + Alcotest.test_case + (name ^ " plonk") + `Slow + (to_test ~plonk:(module Plonk.Main_protocol) m)) + both diff --git a/src/lib_plonk/test_plompiler/test_merkle.ml b/src/lib_plonk/test_plompiler/test_merkle.ml new file mode 100644 index 000000000000..a9123762f576 --- /dev/null +++ b/src/lib_plonk/test_plompiler/test_merkle.ml @@ -0,0 +1,159 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk_test +module CS = Plonk.Circuit +open Helpers +module Hash = Poseidon252.P +module Merkle = Merkle (Poseidon252) +module Helper = Merkle.P + +module MerklePath (L : LIB) = struct + open Utils (L) + + open Merkle.V (L) + + let left = Merkle.left + + let right = Merkle.right + + let tree = Helper.generate_tree 2 + + let root = Helper.root tree + + let test_path_correctness () = + let open Helper in + let hash a = Hash.direct a in + let r = + S.of_string + "40895470603270371738190901050353228005886571814752512228619736449827845164505" + in + let wl = + S.of_string + "3424181894117710793412228511600041687987227889466046940028281425652819848308" + in + let wr = + S.of_string + "7957136680924550432598373971480555041766263219276812040814026910179063320538" + in + + let wll = S.of_string "0" in + + let wlr = S.of_string "1" in + + assert (S.(hash [|wll; wlr|] = wl)) ; + + let wrl = S.of_string "2" in + + let wrr = S.of_string "3" in + + assert (S.(hash [|wrl; wrr|] = wr)) ; + + assert (S.(hash [|wl; wr|] = r)) ; + + let tree = + Node (r, Node (wl, Leaf wll, Leaf wlr), Node (wr, Leaf wrl, Leaf wrr)) + in + let w0, path0 = proof_path 0 tree in + let exp_path0 = [(wlr, left); (wr, left)] in + assert (S.eq w0 wll) ; + + let w1, path1 = proof_path 1 tree in + let exp_path1 = [(wll, right); (wr, left)] in + assert (S.eq w1 wlr) ; + + let w2, path2 = proof_path 2 tree in + let exp_path2 = [(wrr, left); (wl, right)] in + assert (S.eq w2 wrl) ; + + let w3, path3 = proof_path 3 tree in + let exp_path3 = [(wrl, right); (wl, right)] in + assert (S.eq w3 wrr) ; + + List.iter2 + (fun path exp_path -> + List.iter2 + (fun (h, d) (h', d') -> assert (S.eq h h' && d = d')) + path + exp_path) + [path0; path1; path2; path3] + [exp_path0; exp_path1; exp_path2; exp_path3] + + let test = test_path_correctness +end + +(* Doesn't really depend on evaluator, this is a pure test *) +module MPath = MerklePath (LibCircuit) + +module MerklePos (L : LIB) = struct + open L + + open Utils (L) + + open Merkle.V (L) + + let test_merkle path leaf root = + let* path = input ~kind:`Public path in + let path = path_encoding.decode path in + let* leaf = input ~kind:`Public leaf in + let* root = input root in + let* o = merkle_proof path leaf root in + Bool.assert_true o + + let tree = Helper.generate_tree 2 + + let root = Helper.root tree + + let test_merkle_pos pos () = + let leaf, path = Helper.proof_path pos tree in + let leaf = Input.scalar leaf in + let path = path_encoding.input path in + let root = Input.scalar root in + test_merkle path leaf root + + let tests_merkle_pos = + List.init 4 (fun i -> + test ~valid:true ~name:"Merkle.test_merkle_pos" @@ test_merkle_pos i) + + let test_merkle_wrong_leaf () = + let _, path = Helper.proof_path 2 tree in + let leaf = Input.scalar root in + let path = path_encoding.input path in + let root = Input.scalar root in + test_merkle path leaf root + + let tests = tests_merkle_pos @ [test ~valid:false test_merkle_wrong_leaf] +end + +let tests = + [ + Alcotest.test_case "Merkle path" `Quick MPath.test; + Alcotest.test_case "Merkle pos" `Quick (to_test (module MerklePos : Test)); + Alcotest.test_case + "Merkle pos plonk" + `Slow + (to_test ~plonk:(module Plonk.Main_protocol) (module MerklePos : Test)); + ] diff --git a/src/lib_plonk/test_plompiler/test_merkle_narity.ml b/src/lib_plonk/test_plompiler/test_merkle_narity.ml new file mode 100644 index 000000000000..ee7bb5c8c5cf --- /dev/null +++ b/src/lib_plonk/test_plompiler/test_merkle_narity.ml @@ -0,0 +1,100 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk_test +module CS = Plonk.Circuit +open Helpers +module Hash = Poseidon252.P + +let n = 3 + +module MerklePos (L : LIB) = struct + open L + + open Utils (L) + + open Merkle_narity.V (Poseidon252.V) (L) + + module Helper = Merkle_narity.P (Hash) + + let test_merkle witness root = + let* witness = input ~kind:`Public witness in + let* root = input root in + let* o = merkle_proof n witness root in + Bool.assert_true o + + let height = 5 + + let tree = Helper.generate_tree n height + + let root = Helper.root tree + + let test_merkle_pos pos () = + let path, leaf = Helper.proof_path_narity pos tree in + let witness = + Input.( + pair + (scalar leaf) + (list + (List.map + (fun (sl, dir) -> + pair (list @@ List.map scalar sl) (scalar dir)) + path))) + in + let root = Input.scalar root in + test_merkle witness root + + let tests_merkle_pos = + let pos = [0; 1; 2; 1; 2] in + test ~valid:true ~name:"MerkleNarity.test_merkle_pos" @@ test_merkle_pos pos + + let test_merkle_wrong_leaf () = + let pos = [0; 1; 2; 1; 2] in + let path, _ = Helper.proof_path_narity pos tree in + let witness = + Input.( + pair + (scalar root) + (list + (List.map + (fun (sl, dir) -> + pair (list @@ List.map scalar sl) (scalar dir)) + path))) + in + let root = Input.scalar root in + test_merkle witness root + + let tests = [tests_merkle_pos] @ [test ~valid:false test_merkle_wrong_leaf] +end + +let tests = + [ + Alcotest.test_case "Merkle pos" `Quick (to_test (module MerklePos : Test)); + Alcotest.test_case + "Merkle pos plonk" + `Slow + (to_test ~plonk:(module Plonk.Main_protocol) (module MerklePos : Test)); + ] diff --git a/src/lib_plonk/test_plompiler/test_optimizer.ml b/src/lib_plonk/test_plompiler/test_optimizer.ml new file mode 100644 index 000000000000..70d692d9a752 --- /dev/null +++ b/src/lib_plonk/test_plompiler/test_optimizer.ml @@ -0,0 +1,120 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk_test +module CS = Plonk.Circuit +open Helpers + +module Optimizer : Test = +functor + (L : LIB) + -> + struct + open L + + open Utils (L) + + let test_long_sum inputs expected () = + let* inputs = input ~kind:`Public inputs in + let* expected = input expected in + let* o = + foldM Num.add (List.hd (of_list inputs)) (List.tl (of_list inputs)) + in + assert_equal o expected + + let test_vectors = + List.map (fun n -> List.init n (fun _ -> S.random ())) [100; 500] + + let inputs : scalar list Input.t list = + List.map (fun vs -> Input.(list @@ List.map scalar vs)) test_vectors + + let expected = + List.map + (fun vs -> Input.scalar @@ List.fold_left S.add S.zero vs) + test_vectors + + let tests_long_sum = + List.map2 + (fun i e -> + test ~valid:true ~name:"Optimizer.test_long_sum" @@ test_long_sum i e) + inputs + expected + + let test_poseidon_rounds (a1, b1, c1) expected () = + let s i = S.of_z (Z.of_int i) in + let* a1 = input a1 in + let* b1 = input b1 in + let* c1 = input c1 in + let abc = to_list [a1; b1; c1] in + let* expected = input expected in + let* a2 = Num.add_list ~qc:(s 0) ~coeffs:[s 1; s 5; s 25] abc in + let* b2 = Num.add_list ~qc:(s 0) ~coeffs:[s 6; s 7; s 49] abc in + let* c2 = Num.add_list ~qc:(s 0) ~coeffs:[s 9; s 9; s 9] abc in + let a3 = a2 in + let b3 = b2 in + let* c3 = Num.pow5 c2 in + let abc' = to_list [a3; b3; c3] in + let* c4 = Num.add_list ~qc:(s 1) ~coeffs:[s 9; s 9; s 9] abc' in + let* c5 = Num.pow5 c4 in + assert_equal c5 expected + + let tests_poseidon_rounds = + [ + test ~valid:true ~name:"Optimizer.test_poseidon_rounds" + @@ test_poseidon_rounds (si 0, si 0, si 0) (si 1); + ] + + let test_ecc_ed_cond_add p q () = + let module ECC = JubjubEdwards (L) in + let* zero = input ~kind:`Public (Input.bool false) in + let* one = input ~kind:`Public (Input.bool true) in + let* p = ECC.input_point ~kind:`Public p in + let* q = ECC.input_point ~kind:`Public q in + let* r = ECC.cond_add p q one in + let* t = ECC.cond_add r p zero in + let* z = ECC.cond_add t t one in + let* _ = ECC.cond_add z z one in + assert_equal r t + + let tests_ecc_ed_cond_add = + [ + test ~valid:true ~name:"Optimizer.test_ecc_ed_cond_add" + @@ test_ecc_ed_cond_add (S.zero, S.one) (S.zero, S.one); + ] + + let tests = tests_long_sum @ tests_poseidon_rounds @ tests_ecc_ed_cond_add + end + +let tests = + let both = [("Optimizer", (module Optimizer : Test))] in + List.map (fun (name, m) -> Alcotest.test_case name `Quick (to_test m)) both + @ List.map + (fun (name, m) -> + Alcotest.test_case + (name ^ " plonk") + `Slow + (to_test ~plonk:(module Plonk.Main_protocol) m)) + both diff --git a/src/lib_plonk/test_plompiler/test_poseidon.ml b/src/lib_plonk/test_plompiler/test_poseidon.ml new file mode 100644 index 000000000000..a49491a67e7c --- /dev/null +++ b/src/lib_plonk/test_plompiler/test_poseidon.ml @@ -0,0 +1,120 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk_test +module CS = Plonk.Circuit +open Helpers + +module Poseidon_test + (Mec : Plompiler__Hash_sig.P_HASH) (P : functor (L : LIB) -> sig + val digest : + ?input_length:int -> L.scalar list L.repr -> L.scalar L.repr L.t + end) + (L : LIB) = +struct + open L + + open Utils (L) + + module P = P (L) + + let test_poseidon ?(fixed_length = false) inputs expected () = + let* inputs = input ~kind:`Public inputs in + let* expected = input expected in + let input_length = + if fixed_length then Some (List.length @@ of_list inputs) else None + in + let* o = P.digest ?input_length inputs in + with_bool_check (equal o expected) + + let test_vectors = + [[|S.one|]; Array.init 4 (fun i -> S.of_string @@ string_of_int (i + 1))] + + let inputs : scalar list Input.t list = + List.map + (fun v -> Input.(list @@ List.map scalar (Array.to_list v))) + test_vectors + + let expected ?(fixed_length = false) () = + let direct inputs = + let input_length = + if fixed_length then Some (Array.length inputs) else None + in + let ctx = Mec.init ?input_length () in + let ctx = Mec.digest ctx inputs in + Mec.get ctx + in + List.map (fun v -> Input.scalar @@ direct v) test_vectors + + let wrong = List.map (fun _ -> Input.scalar @@ S.random ()) (expected ()) + + let tests_variable_length = + List.map2 + (fun i e -> + test ~valid:true ~name:"Poseidon.test_poseidon" @@ test_poseidon i e) + inputs + (expected ()) + @ List.map2 + (fun i w -> + test ~name:"Poseidon.test_poseidon" ~valid:false @@ test_poseidon i w) + inputs + wrong + + let tests_fixed_length = + List.map2 + (fun i e -> + test ~valid:true ~name:"Poseidon.test_poseidon.fixed_length" + @@ test_poseidon ~fixed_length:true i e) + inputs + (expected ~fixed_length:true ()) + @ List.map2 + (fun i w -> + test ~valid:false ~name:"Poseidon.test_poseidon" + @@ test_poseidon ~fixed_length:true i w) + inputs + wrong + + let tests = tests_variable_length @ tests_fixed_length +end + +let tests = + let open Gadget in + let both = + [ + ( "Poseidon128", + (module Poseidon_test (Poseidon128.P) (Poseidon128.V) : Test) ); + ("Poseidon252", (module Poseidon_test (Poseidon252.P) (Poseidon252.V))); + ("PoseidonFull", (module Poseidon_test (PoseidonFull.P) (PoseidonFull.V))); + ] + in + List.map (fun (name, m) -> Alcotest.test_case name `Quick (to_test m)) both + @ List.map + (fun (name, m) -> + Alcotest.test_case + (name ^ " plonk") + `Slow + (to_test ~plonk:(module Plonk.Main_protocol) m)) + both diff --git a/src/lib_plonk/test_plompiler/test_schnorr.ml b/src/lib_plonk/test_plompiler/test_schnorr.ml new file mode 100644 index 000000000000..b7d7c946c019 --- /dev/null +++ b/src/lib_plonk/test_plompiler/test_schnorr.ml @@ -0,0 +1,111 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk_test +module CS = Plonk.Circuit +open Helpers + +module P = struct + (* https://github.com/dusk-network/jubjub/blob/052ac22bc69403171ad1e32c3332b7510891419a/src/lib.rs#L121 *) + + module A = Mec.Curve.Jubjub.AffineEdwards + module Schnorr = Plompiler.Schnorr (Plompiler.Anemoi128) + module P = Schnorr.P + + let test_vanilla_schnorr () = + let sk = A.Scalar.random () in + let msg = S.random () in + let rand = A.Scalar.random () in + let pk = P.neuterize sk in + let signature = P.sign sk msg rand in + assert (P.verify ~msg ~pk ~signature ()) ; + let msg = S.random () in + assert (not @@ P.verify ~msg ~pk ~signature ()) + + let test = test_vanilla_schnorr +end + +module Schnorr (L : LIB) = struct + open L + + open Utils (L) + + module Schnorr = Plompiler.Schnorr (Plompiler.Anemoi128) + module Sc = Schnorr.V (L) + module A = Mec.Curve.Jubjub.AffineEdwards + + let test_circuit_verify g pk msg signature () = + let* g = input ~kind:`Public g in + let* pk = input ~kind:`Public @@ Sc.pk_encoding.input pk in + let* msg = input msg in + let* signature = input @@ Sc.signature_encoding.input signature in + let signature = Sc.signature_encoding.decode signature in + with_bool_check (Sc.verify ~g ~msg ~pk ~signature ()) + + let sk = A.Scalar.random () + + let pk = Schnorr.P.neuterize sk + + let msg = S.random () + + let rand = A.Scalar.random () + + let signature = Schnorr.P.sign sk msg rand + + let nb_bits = Z.numbits A.Base.order + + let wrong_u_bytes = + Plompiler.Utils.bool_list_of_z ~nb_bits + @@ A.Scalar.to_z @@ A.Scalar.random () + + let tests = + let g = Sc.pk_encoding.input Sc.g in + let msg = Input.scalar msg in + [ + test + ~valid:true + ~name:"Schnorr.test_circuit_verify" + (test_circuit_verify g pk msg signature); + test + ~valid:false + ~name:"Schnorr.test_circuit_verify" + (test_circuit_verify + g + pk + msg + {signature with sig_u_bytes = wrong_u_bytes}); + ] +end + +let tests = + [ + Alcotest.test_case "P" `Quick P.test; + Alcotest.test_case "Schnorr" `Quick (to_test (module Schnorr : Test)); + Alcotest.test_case + "Schnorr plonk" + `Slow + (to_test ~plonk:(module Plonk.Main_protocol) (module Schnorr : Test)); + ] diff --git a/src/lib_plonk/test_plompiler/test_serialization.ml b/src/lib_plonk/test_plompiler/test_serialization.ml new file mode 100644 index 000000000000..20fe236056cd --- /dev/null +++ b/src/lib_plonk/test_plompiler/test_serialization.ml @@ -0,0 +1,52 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk_test +open Helpers +open LibCircuit + +open Utils (LibCircuit) + +let test_serialization () = + let module Hash = Gadget.Poseidon128.V (LibCircuit) in + let poseidon x = + let* x = input ~kind:`Public x in + Hash.digest (LibCircuit.to_list [x]) + in + let LibCircuit.{cs; _} = LibCircuit.get_cs (poseidon @@ si 1) in + let path = "test_serialization.json" in + Plompiler.Utils.save_cs_to_file path [] cs ; + let _, cs' = Plompiler.Utils.load_cs_from_file path in + assert ( + List.for_all2 + (fun g g' -> Array.for_all2 Csir.CS.raw_constraint_equal g g') + cs + cs') + +let tests = + List.map + (fun (name, test) -> Alcotest.test_case name `Quick test) + [("Poseidon128", test_serialization)] diff --git a/src/lib_plonk/test_plompiler/test_weierstrass.ml b/src/lib_plonk/test_plompiler/test_weierstrass.ml new file mode 100644 index 000000000000..61a05134552c --- /dev/null +++ b/src/lib_plonk/test_plompiler/test_weierstrass.ml @@ -0,0 +1,188 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk_test + +module JubjubWeierstrass (L : LIB) = struct + module MecJubJub = Mec.Curve.Jubjub.AffineWeierstrass + open L + + open Helpers.Utils (L) + + open Plompiler.JubjubWeierstrass (L) + + let point_of_mec p = + let x = MecJubJub.get_x_coordinate p in + let y = MecJubJub.get_y_coordinate p in + ( S.of_bytes_exn (MecJubJub.Base.to_bytes x), + S.of_bytes_exn (MecJubJub.Base.to_bytes y) ) + + let add_circuit p q expected () = + let* p = input_point ~kind:`Public p in + let* q = input_point ~kind:`Public q in + let* r = input_point expected in + let* o = add p q in + assert_equal o r + + let test_vectors = + List.init 10 (fun _ -> (MecJubJub.random (), MecJubJub.random ())) + + let inputs = + (* p + q = r *) + List.map (fun (p1, p2) -> (point_of_mec p1, point_of_mec p2)) test_vectors + + let expected = + (* p + q = r *) + List.map + (fun (input1, input2) -> + let res = MecJubJub.add input1 input2 in + point_of_mec res) + test_vectors + + let wrong = List.map (fun _ -> (S.random (), S.random ())) expected + + let test_add = + List.map2 + (fun (p1, p2) e -> + test ~valid:true ~name:"Weierstrass.test_add" @@ add_circuit p1 p2 e) + inputs + expected + @ List.map2 + (fun i w -> test ~valid:false @@ add_circuit (fst i) (snd i) w) + inputs + wrong + + let double_circuit p expected () = + let* p = input_point ~kind:`Public p in + let* r = input_point expected in + let* o = double p in + assert_equal o r + + let test_vectors = List.init 10 (fun _ -> MecJubJub.random ()) + + let inputs = + (* p + p = r *) + List.map point_of_mec test_vectors + + let expected = + (* p + p = r *) + List.map + (fun input -> + let res = MecJubJub.double input in + point_of_mec res) + test_vectors + + let wrong = List.map (fun _ -> (S.random (), S.random ())) expected + + let test_double = + List.map2 + (fun i e -> + test ~valid:true ~name:"Weierstrass.test_double" @@ double_circuit i e) + inputs + expected + @ List.map2 + (fun i w -> test ~valid:false @@ double_circuit i w) + inputs + wrong + + let input_bytes bytes = input Input.(list (List.map (fun b -> bool b) bytes)) + + let scalar_mul_circuit p input_b expected () = + let* flag = input ~kind:`Public (Input.bool false) in + let* p = input_point p in + let* b = input_bytes input_b in + let* r = input_point expected in + let* o = scalar_mul b p flag in + assert_equal r o + + let test_vectors = + let size = Z.log2 S.order in + List.init 2 (fun _ -> + let bool_list = List.init size (fun _ -> Stdlib.Random.bool ()) in + (MecJubJub.random (), bool_list)) + + let inputs = + (* p^k = r *) + List.map + (fun (input_p, input_b) -> (point_of_mec input_p, input_b)) + test_vectors + + let expected = + (* p^k = r *) + List.map + (fun (input_p, input_b) -> + let exponent = Plompiler.Utils.bool_list_to_scalar input_b in + let exponent = MecJubJub.Scalar.of_bytes_exn (S.to_bytes exponent) in + let res = MecJubJub.mul input_p exponent in + point_of_mec res) + test_vectors + + let wrong = List.map (fun _ -> (S.random (), S.random ())) expected + + let test_scalar_mul = + List.map2 + (fun (p, b) e -> + test ~valid:true ~name:"Weierstrass.test_scalar_mul" + @@ scalar_mul_circuit p b e) + inputs + expected + @ List.map2 + (fun (p, b) w -> test ~valid:false @@ scalar_mul_circuit p b w) + inputs + wrong + + let is_on_curve_circuit p () = + let* p = input_point ~kind:`Public p in + assert_is_on_curve p + + let test_vectors = List.init 10 (fun _ -> MecJubJub.random ()) + + let inputs = List.map point_of_mec test_vectors + + let wrong = List.map (fun _ -> (S.random (), S.random ())) expected + + let test_is_on_curve = + List.map + (fun i -> + test ~valid:true ~name:"Weierstrass.is_on_curve_circuit" + @@ is_on_curve_circuit i) + inputs + @ List.map (fun w -> test ~valid:false @@ is_on_curve_circuit w) wrong + + let tests = test_add @ test_double @ test_scalar_mul @ test_is_on_curve +end + +let tests = + let open Helpers in + let both = [("JubJubWeierstrass", (module JubjubWeierstrass : Test))] in + List.map (fun (name, m) -> Alcotest.test_case name `Quick (to_test m)) both + @ List.map + (fun (name, m) -> + Alcotest.test_case + (name ^ " plonk") + `Slow + (to_test ~plonk:(module Plonk.Main_protocol) m)) + both -- GitLab From 46c1fb711184cd9d1046fdfe9a1b85fbefb2d214 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 15 Mar 2023 13:34:58 +0100 Subject: [PATCH 23/34] lib_aplonk test main/bench: import from privacy-team --- manifest/main.ml | 57 ++++- src/lib_aplonk/test/bench.ml | 93 +++++++ src/lib_aplonk/test/dune | 36 +++ src/lib_aplonk/test/main.ml | 38 +++ src/lib_aplonk/test/test-quick.expected | 204 +++++++++++++++ src/lib_aplonk/test/test-slow.expected | 216 ++++++++++++++++ src/lib_aplonk/test/test_aplonk.ml | 292 ++++++++++++++++++++++ src/lib_aplonk/test/test_main_protocol.ml | 157 ++++++++++++ 8 files changed, 1092 insertions(+), 1 deletion(-) create mode 100644 src/lib_aplonk/test/bench.ml create mode 100644 src/lib_aplonk/test/dune create mode 100644 src/lib_aplonk/test/main.ml create mode 100644 src/lib_aplonk/test/test-quick.expected create mode 100644 src/lib_aplonk/test/test-slow.expected create mode 100644 src/lib_aplonk/test/test_aplonk.ml create mode 100644 src/lib_aplonk/test/test_main_protocol.ml diff --git a/manifest/main.ml b/manifest/main.ml index fe3deb529402..25d80b120a9d 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1222,7 +1222,7 @@ let octez_plonk_aggregation = ~preprocess:[pps ppx_repr] ~deps:[octez_plonk; octez_bls12_381_polynomial |> open_] -let _octez_aplonk = +let octez_aplonk = public_lib "octez-aplonk" ~internal_name:"aplonk" @@ -1401,6 +1401,61 @@ let _octez_plonk_test_plompiler_main = ]); ] +let _octez_aplonk_test_main = + private_exe + "main" + ~path:"src/lib_aplonk/test" + ~opam:"octez-aplonk" + ~deps:[octez_plonk_test_helpers; octez_aplonk] + ~modules:["main"; "test_aplonk"; "test_main_protocol"] + ~dune: + Dune. + [ + alias_rule + "runtest" + ~package:"octez-aplonk" + ~action: + (G + [ + setenv + "RANDOM_SEED" + "42" + (progn + [ + run_exe "main" ["-q"]; + [S "diff?"; S "test-quick.expected"; S "test.output"]; + ]); + ]); + alias_rule + "runtest_slow" + ~package:"octez-aplonk" + ~action:(run_exe "main" []); + alias_rule + "runtest_slow_with_regression" + ~package:"octez-aplonk" + ~action: + (G + [ + setenv + "RANDOM_SEED" + "42" + (progn + [ + run_exe "main" []; + [S "diff?"; S "test-slow.expected"; S "test.output"]; + ]); + ]); + ] + +let _octez_aplonk_test_helpers_bench = + private_exe + "bench" + ~path:"src/lib_aplonk/test" + ~opam:"octez-aplonk" + ~modules:["bench"] + ~bisect_ppx:No + ~deps:[octez_plonk_test_helpers; octez_aplonk] + let _octez_srs_extraction_tests = tests ["main"] diff --git a/src/lib_aplonk/test/bench.ml b/src/lib_aplonk/test/bench.ml new file mode 100644 index 000000000000..725c15a28726 --- /dev/null +++ b/src/lib_aplonk/test/bench.ml @@ -0,0 +1,93 @@ +module PI = Aplonk.Pi_parameters.Rollup_example + +module PIs = struct + let get_pi_module _ = (module PI : Aplonk.Pi_parameters.CircuitPI) +end + +module Plonk_Helpers = Plonk_test.Helpers.Make (Plonk.Main_protocol) +module APlonk_Helpers = Plonk_test.Helpers.Make (Aplonk.Main_protocol.Make (PIs)) +module Cases = Plonk_test.Cases + +let file = "./benchmarks" + +let bench_big_circuit nb_constraints_l nb_proofs_l () = + Gc.full_major () ; + let nb_proofs = 1 lsl nb_proofs_l in + Printf.printf + "\n\n\ + Number of gates : %d (= 2^%d - 1)\n\ + Number of public inputs : %d\n\ + Number of proofs : %d (= 2^%d)\n" + ((1 lsl nb_constraints_l) - 1) + nb_constraints_l + PI.nb_inner + nb_proofs + nb_proofs_l ; + let time = Unix.gettimeofday () in + let case_list = + Cases.Big_circuit.make + ~nb_proofs + ~public_input_size:PI.nb_inner + ~k:nb_constraints_l + in + let name = "Big Circuit" in + let _, circuits_map, inputs_map, outcome = Cases.aggregate_cases case_list in + Printf.printf + "\ntime build circuit & witness : %f s." + (Unix.gettimeofday () -. time) ; + + Gc.full_major () ; + + print_endline "\n\n\nPLONK" ; + Plonk_Helpers.test_circuits + ~name + ~outcome + ~verbose:true + circuits_map + inputs_map ; + Plonk_test.Helpers.Time.update_str ~header:(string_of_int nb_proofs_l) () ; + + Gc.full_major () ; + + print_endline "\naPLONK" ; + APlonk_Helpers.test_circuits + ~name + ~outcome + ~verbose:true + circuits_map + inputs_map ; + Plonk_test.Helpers.Time.update_str () + +(* Run benches of Plonk(KZG) & aPlonK (nb_proofs_end - nb_proofs_start + 1) + times, with a nb_proofs from nb_proofs_start until nb_proofs_end (included). + Prints the execution time in benchmark file, as : + nb_proofs + time setup PlonK + time prove PlonK + time verify PlonK + time setup aPlonK + time prove aPlonK + time verify aPlonK +*) +let benches_big_circuit nb_constraints nb_proofs_start nb_proofs_end () = + Plonk_test.Helpers.Time.reset_str () ; + if nb_proofs_start > nb_proofs_end then + failwith + "Zero benchmarks are launched as the second argument is bigger that the \ + third." ; + try + for i = nb_proofs_start to nb_proofs_end do + print_endline "\n\n-------------------------------------" ; + let () = bench_big_circuit nb_constraints i () in + () + done ; + Plonk_test.Helpers.Time.print_time_in_file file + with e -> + Plonk_test.Helpers.Time.print_time_in_file file ; + raise e + +let () = + let nb_constraints_l = int_of_string Sys.argv.(1) in + let nb_proofs_start = int_of_string Sys.argv.(2) in + let nb_proofs_end = int_of_string Sys.argv.(3) in + benches_big_circuit nb_constraints_l nb_proofs_start nb_proofs_end () diff --git a/src/lib_aplonk/test/dune b/src/lib_aplonk/test/dune new file mode 100644 index 000000000000..da588658657f --- /dev/null +++ b/src/lib_aplonk/test/dune @@ -0,0 +1,36 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(executable + (name main) + (instrumentation (backend bisect_ppx)) + (libraries + octez-plonk.plonk-test + octez-aplonk) + (modules main test_aplonk test_main_protocol)) + +(rule + (alias runtest) + (package octez-aplonk) + (action + (setenv RANDOM_SEED 42 + (progn (run %{exe:main.exe} -q) (diff? test-quick.expected test.output))))) + +(rule + (alias runtest_slow) + (package octez-aplonk) + (action (run %{exe:main.exe}))) + +(rule + (alias runtest_slow_with_regression) + (package octez-aplonk) + (action + (setenv RANDOM_SEED 42 + (progn (run %{exe:main.exe}) (diff? test-slow.expected test.output))))) + +(executable + (name bench) + (libraries + octez-plonk.plonk-test + octez-aplonk) + (modules bench)) diff --git a/src/lib_aplonk/test/main.ml b/src/lib_aplonk/test/main.ml new file mode 100644 index 000000000000..72c0acdac774 --- /dev/null +++ b/src/lib_aplonk/test/main.ml @@ -0,0 +1,38 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk_test + +let () = + Helpers.with_seed (fun () -> + Helpers.with_output_to_file (fun () -> + Alcotest.run + ~verbose:false + "aPlonk" + [ + ("aPlonk Internal", Test_aplonk.Internal.tests); + ("aPlonk External", Test_aplonk.External.tests); + ("Main Proto (aPlonk)", Test_main_protocol.tests); + ])) diff --git a/src/lib_aplonk/test/test-quick.expected b/src/lib_aplonk/test/test-quick.expected new file mode 100644 index 000000000000..07759583245d --- /dev/null +++ b/src/lib_aplonk/test/test-quick.expected @@ -0,0 +1,204 @@ +test_sum_alpha: +Proof size: 1.72 KB +Proof hash: 3189d74f9b60cb10f96b66007e80b66b7fccb0880ce12eec5894dc3794046cd7 +Prover_pp hash: 01deea3a6faf7ec3b9de6f85ad026a7306667ea4891ef9f9752b5f32ca162cd1 +Verifier_pp hash: 6682e418852a383b0638413a3fa588c5f3409e98118f0b4e2b8bc500a327943b + +test_pi: +Proof size: 1.66 KB +Proof hash: ea247d0f094d42df808fb7335d4368db82c629de1174c820ebd9d3d80252e751 +Prover_pp hash: 3b60652b78ff1d468977413df3ba52e94a4a7f68493fc39375a90738061ee6a8 +Verifier_pp hash: b19bf90ec1e2b1b18541b98ea4eb46339dac62a3b1c47337582cf64e72165662 + +test_pi: +Proof size: 1.66 KB +Proof hash: 56c1f3cc7f17007a8e1859e4a46a7d6ba53763c9eb825980a9abbcab6b494146 +Prover_pp hash: 3b60652b78ff1d468977413df3ba52e94a4a7f68493fc39375a90738061ee6a8 +Verifier_pp hash: b19bf90ec1e2b1b18541b98ea4eb46339dac62a3b1c47337582cf64e72165662 + +first_test_proto_rollup: +Proof size: 9.57 KB +Proof hash: 8811677c2b79dd3cc89b852097bf6d89b4bc07e1e63b75e434a36322e9011de5 +Prover_pp hash: 0b58f9f4fc4a82117d8260145e3084c6d50e2352052552c244d318da317bc3e6 +Verifier_pp hash: 7a15447037f0aadd721a6864afb41fc64b6d55792b62a142d0dcabf0398ba554 + +qc: +Proof size: 8.34 KB +Proof hash: 453588d5192e69267273ff4917010987033cfd0eab10e789d4b939db35307750 +Prover_pp hash: da2aa6fa61bde99bb894ffdf4669292c052b77a8fd0d69f2594f9381c801c154 +Verifier_pp hash: 61bffafd2e34b79f787b3fa5d44af89f8bda03a146c47c3eb8309e722a558c6b + +ql: +Proof size: 8.34 KB +Proof hash: 5fe7b1dd3e9514fa32687a2d8560fe7a2d5744511fc0480d6a744271d8965a18 +Prover_pp hash: 3aa9f2490b331e6b2dcfa54fb346ec0ba289980c0ec4575b894bf9e56be5aa20 +Verifier_pp hash: 94bb89f3359cd6cd55ac94fc7a99fa94b0b0b11dbf80213c63cb32e86b500a56 + +qr: +Proof size: 8.34 KB +Proof hash: 9ec049d3801fd4d7eed69e7ed4b50d3d9a636691c8b2261b721f59de836d5f87 +Prover_pp hash: d5ebe8ce4de7d2a5134895797b39b2449dd2ccccffd4ead739c669da8fb5809e +Verifier_pp hash: c686e05fd65049f49961f8355bad364c89b452477d64737e16a2761098cc8e00 + +qd: +Proof size: 8.34 KB +Proof hash: 6c73d04a8a2a71d03255111e2bf183a11832e1670350160ad4987ef4e7aa6d6c +Prover_pp hash: 295417439cac83148b7e1d29fb2fc480927789a44aca5b4c0c910083cbd6d264 +Verifier_pp hash: a39e6dbb270552bf6463d36cbe0a47b5cf478af21a935b0ce1c7f34d2ca903e9 + +qe: +Proof size: 8.34 KB +Proof hash: f4669f41fcd14d0d5182a98f4189db1fd4141344225935945f8b509924d37741 +Prover_pp hash: f9cc19f7fb2a3bb20b003340a8ccb2ff517007dbd42fec05ee1e2a2a71d4a38a +Verifier_pp hash: cc1406ffc401b95287566e8bfea610a1cf6661ff3344dc1db7986360e362822e + +qlg: +Proof size: 8.45 KB +Proof hash: 0af8237fa6336a5ba5489dbea968f67dd3037749602d7b60de76a8f245d4e2cb +Prover_pp hash: 64fbba1c1649d0767461e47117fa55e67605c8f40024837e6cfa0036c3097b45 +Verifier_pp hash: 5a05e61f84f16575138ff72b75c1d2447613a514c496fa5e998edeeb211d1c4f + +qrg: +Proof size: 8.45 KB +Proof hash: 36fa9a82e0c06e8ee8f69746121d4bde76557a5080ca3d214995f1234402e25f +Prover_pp hash: b96ededdb9a721b4414cc7e4ea18aca163f503eac12371d48bec5cb82f739db0 +Verifier_pp hash: 07e52b039f91075675781b1ac030751998270999cd20d63e6b39dd8dbdac4b37 + +qog: +Proof size: 8.45 KB +Proof hash: 27afbb34f8bb1605ee4d293c3a0dfdbbf3d354efd4fe66867e425d803f3a7961 +Prover_pp hash: 31bcfb06fcb0a1a3c9ae99c5249fc721e6c099abdb73fd1d8971ad417ffc3686 +Verifier_pp hash: 6ea32faae52e8f43a9567f023d8a99f4fcd5ac4028163e5642a468094d21ee3e + +qdg: +Proof size: 8.45 KB +Proof hash: cae668118b6ed336241e67174f8b8bf901aee14290c3e5d789ebdc165b6290f4 +Prover_pp hash: 7981314ce61af52bf25fe1362788f22cfdef30f50d017c384708ac65a43d3fa6 +Verifier_pp hash: 8bd53ac1a555cb2a234c6e87de59d848929a1fb5596e3eff9b88092ff09d5587 + +qeg: +Proof size: 8.45 KB +Proof hash: af513a1463a383e7b15f8a924856a0f6ba54a44314acbc37e19347af1a461f2f +Prover_pp hash: 633eacc95f254ebfdb5721f4d9adc4eea51d65ac5f87d6ae963b7ee5dff12746 +Verifier_pp hash: c9deb3121122cbedd4b7d503aeefb7912f46ddb1870f26ea3ee0d74c5034cf4e + +qm: +Proof size: 8.34 KB +Proof hash: adc8e53a93a8150326bdf395c1fe6a304d7e03efe74a2a5a126f54770c0a35f6 +Prover_pp hash: 1d451caf68566852378ab387e464576875138f7da7ccf340af2fa0df75164b3b +Verifier_pp hash: e114616a146fc9d4a372e3a4986d5a561e949e6876e5c261a93ffc31ca702956 + +qx2b: +Proof size: 8.41 KB +Proof hash: d5c8145eea60811fad77a16cb7aaa95622c33a046311f149458ecf36cbde536c +Prover_pp hash: dcd4bb023a1532787d8b07e76b92cbb083b2d81cd0212365d790231dca21a477 +Verifier_pp hash: 575a3f35f9d53bff37eb4dddde1e5dcd0e2e838d2878640722b8e1a789186e4a + +qx5a: +Proof size: 8.45 KB +Proof hash: b6f7ff5da42befc951a9b99bdc0e87569bc9e8a9e29b89199566e51746bb2729 +Prover_pp hash: 1b9c06ee80ab36c5b80936fcace2d9d89eeba70ce357f84fe1ab6de1777e2c89 +Verifier_pp hash: 5cf346e41a64da5fd1f3f3bb6c83b662454d77b4d7206806ffc9c99bc2084ecc + +qx5c: +Proof size: 8.45 KB +Proof hash: ef700db9a13f67fd335facafabfc6bbf7e7051689b283004e3594e0668c9c177 +Prover_pp hash: 76c50d95b29a82fb6074f1b0ab970477eaf3261a24c5f7fb57750e7fba018a9d +Verifier_pp hash: 0d7210968d19f2770800ea7987f6622a580f8d83d59c04d1bc2112a6a17cffcd + +qecc_ws_add: +Proof size: 8.70 KB +Proof hash: f1050e41e5df139a42b1e31a337d4b4c9d53550a002a0e7abd713a628f755f7f +Prover_pp hash: 173d49f4ccd71a3741e24a221305a42a184f3e5bf965cd5c435a97350c2ff2c5 +Verifier_pp hash: 3ec8c242f5477760330b4ca873d2e500d9d2196b3b517aa34e3f2e43a528885f + +qecc_ed_add: +Proof size: 8.70 KB +Proof hash: eaede12099b73231c28f9a2b6836b7cf1906927cee449152fdbfb261c36adbb3 +Prover_pp hash: b99bcac8781b5f5f6f1d85a3240e455f53228e3e0dabdedabef35be79b2f974e +Verifier_pp hash: bdf2d525ca47ea3038962df179ee68e23f9319a653bb8b1fbd413c502769c50d + +qecc_cond_ed_add: +Proof size: 8.90 KB +Proof hash: 6bd8676d5c27da429ff342d2d9dce0da7abcdb0759bd15d0658c0dd46e259739 +Prover_pp hash: f8695a0e31b7f3a30e2bbb04e9b7f4d2d6b2f47c8b6d16ea4cb7b3e596a01a1b +Verifier_pp hash: 054a67b45bd02d716a217d7046474668ccb9023d3699d9091c03759e4fef87e0 + +qbool: +Proof size: 8.44 KB +Proof hash: a1eb5cdaa05be7df3e9d320d258d3a9ad991ee6f3a21e8431177408d3fb43032 +Prover_pp hash: 88d00f1444d9e3d48bc9e5c80be285c3802d8f72423f735d747e2b004be32209 +Verifier_pp hash: 6776566f691081d9d6795c95ac5f8689b4288b1c5299bd389c265609cca3b318 + +qcond_swap: +Proof size: 8.60 KB +Proof hash: 9128854174345eb0f497b2f6a097eedfdedb285d4de780d3ddc312fbe15a36da +Prover_pp hash: ad2e21b4384636ce66bd250960ff182c879388b46e46303eebbc5c6c5221f050 +Verifier_pp hash: 79c4d2cab1af81288b454ca2013f8d2a20e94add59c253cb647b8a1ccb707265 + +q_anemoi: +Proof size: 9.92 KB +Proof hash: 354c3c37de21c7e554d5ca8178d08f511375b83c07ea95f5780deb983b2ca313 +Prover_pp hash: d9d892cdf0cfbe37dd25539b381ceb291c1e26f0b70b4c55d792d065a960c250 +Verifier_pp hash: 891557710de8558e884a7e37e9e9d57ce40057b5b6df4a18df190a2fa1dfccab + +no_public_inputs: +Proof size: 10.08 KB +Proof hash: 1bd5b18c93cad80845f1c39187c7db4a5d25ade2f006b8c7fa2cec305be2644b +Prover_pp hash: 118df135cf0e144a2fbf84fd892fbb72506ecefc3a447ff6c7cb5d66cac6a8b8 +Verifier_pp hash: 67a5a82358f8c1e6e62f67201d00526feb41de5a07d0bbbc1d3281504d8ebbb4 + +bnot: +Proof size: 8.41 KB +Proof hash: 77a86b32156f5395fc2baa189b4bf0a86198eadf837cdd81927aa63aad37f875 +Prover_pp hash: fb64860468e743956691681370b8a375a598e2004b6954dfcea93d912bfe95a4 +Verifier_pp hash: c39a3aac19a3f67566651c2934b1573c3b732289e655c4c799e36cf12da66191 + +zero_values: +Proof size: 9.92 KB +Proof hash: 6576ea3775f4db81d22f58563391ed38f038ceb1212716283f1ac6fa9ee8098e +Prover_pp hash: 7242ecaff696da2cd3ec75a73f13abb972c1b3ce16ebeac3d87204192d237329 +Verifier_pp hash: 05834b986d6029b859ec71be817630867edd4278b66f85010b618802b3c4f3ec + +non_zero_values: +Proof size: 10.05 KB +Proof hash: d9dd7bb0e817145411456e2f68505eff5ea7b7faedb6cc2185171a09135153b9 +Prover_pp hash: 9c3acfbdbc76c3ed17fe3e6fc3cb1792ecd8c72385395e020f6b9bb8d5d0b8ba +Verifier_pp hash: 829a241f8d7148caf14c4890596d6e25e2abc51e155221ea9fc58a7de7c0fea2 + +big_circuit.2.5+big_circuit.2.5: +Proof size: 9.98 KB +Proof hash: 57fef6b7483b0d8eed6a2aae990c86c94ea07d69f141d4c76d7c278aeb55e7b4 +Prover_pp hash: 1a68c0c2007122ae3cb0a454a4e48769dfcfee1982806240fe60f61526171a13 +Verifier_pp hash: ef6ba611f07830c189b550f33647c26f9e40f9f32d99af215c9f52114fcff923 + +upper_bound_no_pi: +Proof size: 8.34 KB +Proof hash: 9808fc5f20f3e62dbf58f95032918cc2802cfa3fc71e127413507eb66a6307e2 +Prover_pp hash: 1430d1f820f8166297f9fccd5f741401245609156c0979f3a924374577e41bb9 +Verifier_pp hash: 89fb4413f0e735b9129c47b85f085f60233f35f791f9d0c3a7c3a3ce0b6276dc + +upper_bound_pi: +Proof size: 9.98 KB +Proof hash: bbf0966f8053977e33f067a20ee9fbccde4e4a453a616021cb16d7aa2421fdc9 +Prover_pp hash: a15f6afdcea6171536e2537661539121eda5cec05e2d0b311e92fc370ba01c97 +Verifier_pp hash: 6af0ec7fb35032269ce82608a61f4c3a1d36c77ee60a1193b940a6b58f9753ba + +qc+ql+qr+qd+qe: +Proof size: 20.53 KB +Proof hash: cff49a86f536e318e34cbd202a10d11ac2370a7b6e9e98b95c9d71f4a6b87308 +Prover_pp hash: 595450f7572902a776907dc3bdd409c5c8380909b04e76142d3a0be52db70324 +Verifier_pp hash: 006308a95d1e666fecab22a9efc1ab0c123e3e0c3ea3202b94832303d2d4a644 + +non_zero_values+non_zero_values+zero_values: +Proof size: 13.73 KB +Proof hash: ccd36692837e5ff26304a1b5897eb3e0f3f3ddf22fcf1d04eb9903673d4392a6 +Prover_pp hash: aee0cea7a12d3b36dad111f2ed50c7d5ae03b15a3efea23970113ba579c5ba2f +Verifier_pp hash: 98514b6569aa552502257e8b8229274d37a1866af54adfd6a959847fb4f93119 + +qlg+qrg+non_zero_values+zero_values: +Proof size: 19.34 KB +Proof hash: 4de3da12d7e197689b3cf4a4ee48036dd37174554dd22cb2d88e6bf945600ecc +Prover_pp hash: fe8922ad95a7e2b5d863edb1e49c34a551d1b9b561fb2a180a320c97a395a46e +Verifier_pp hash: b36afe3e68e18b389119c991f8162102ccf89c0acc3bc21a869fcf4828105883 + diff --git a/src/lib_aplonk/test/test-slow.expected b/src/lib_aplonk/test/test-slow.expected new file mode 100644 index 000000000000..f77510ed041f --- /dev/null +++ b/src/lib_aplonk/test/test-slow.expected @@ -0,0 +1,216 @@ +test_sum_alpha: +Proof size: 1.72 KB +Proof hash: ba8572922258ba94e49c79fe1b37e0ec53c63a8c88e0208e503b2fcbda779a0a +Prover_pp hash: 330df6bad68d1e5729c4904ad0b4d097ca8bdc8aef751c396f309040a8364ee0 +Verifier_pp hash: bbc5813f6b8a4d3f03a9b4b01935177f75ab0fbda26d1f750fc4377109466da5 + +test_pi: +Proof size: 1.66 KB +Proof hash: 618c8cb44f066a8d1a62a79809a0e498399569ac45609cc96e018600524c6d0a +Prover_pp hash: 7feb3d436be44ad79c178474b931786033c46e18e7572c15aa13894dc6f8acd9 +Verifier_pp hash: 49bed71014ab3148d49ba1fbc1439723e544ef8bcce49f302e42abbe43ea11b8 + +test_pi: +Proof size: 1.66 KB +Proof hash: 00b336573ad95181ed7e40ec5a8a5659aa935d85bb97737c50415588f6afffee +Prover_pp hash: 7feb3d436be44ad79c178474b931786033c46e18e7572c15aa13894dc6f8acd9 +Verifier_pp hash: 49bed71014ab3148d49ba1fbc1439723e544ef8bcce49f302e42abbe43ea11b8 + +first_test_proto_rollup: +Proof size: 9.57 KB +Proof hash: deba8db45ae96b6a42ea77b225f8657010bdc5e0dbb572f42088fbc3a0521eb3 +Prover_pp hash: 8ab1265fc7cb6261ff734677bbc1797a07fc0fe15013e136821eb2047ec0cf8b +Verifier_pp hash: 2026dbab097778c678af2ddd54e973f2bd9ab68b2759030ae13f0a37b08a85f1 + +compare_protos : aplonk: +Proof size: 9.61 KB +Proof hash: 3ca8005da666c2f57976221f07d53e91c8c45b146414de1e039d5d14fb52ede2 +Prover_pp hash: cd1dda3187a017c96f1ac473d011d8c491fa9ec520eff6bc13bffe195c50d5aa +Verifier_pp hash: 45f02d0c4906520ae4ae71b9a41ed7ffc9a0b18c26116e53d538a2aa47cd86fc + +compare_protos : Pack: +Proof size: 2.99 KB +Proof hash: dcf5cbf1d24a0fafabf892796ae6f3578cd9fc8224f439f6250d6e1804887267 +Prover_pp hash: 1262dba0d82ed5a5720d21edeecba60a964ce0811568f8f9a3638abd366ea77b +Verifier_pp hash: cafa36f6a59751b370e83f5f47cad023ded5bff72d69bc0fb46d6a5be0dcab3c + +qc: +Proof size: 8.34 KB +Proof hash: e24eef61714a63bcaafaf763d94d42b5f3bcfc84e1480f51969d21a4ef49a8c5 +Prover_pp hash: 48cd8c5e507aabf4402da08cb4081d2006cb9a213e00817bd2cec9f05d0ff9f6 +Verifier_pp hash: a769a98000205bab087a2d526d6db279313f7495209a908077e8d8310d8acfca + +ql: +Proof size: 8.34 KB +Proof hash: 05ee2908fbf7997ebb1a46b46b952731b93b3234ed135d515cdc111f642ab44b +Prover_pp hash: 994a771c7bc00d4f205b3c9aba1f180f39b154f98513a32ad33fd0b35a51ea0c +Verifier_pp hash: 33a3ec7af7ad67a110bf94dc3e8ed1d4594e9de16fe3acdc39db00025bc90949 + +qr: +Proof size: 8.34 KB +Proof hash: 0011284af631747d4b25e394ee45657346de97c235cbe57a58a5e83c5d44e403 +Prover_pp hash: a5569335be61f5415852c7ae73aa773ab20eab378eaa80fce0fcf1cc3c333ca3 +Verifier_pp hash: 8373dbe8ceb9bf29a4049737d8f2ca9d335697eb8105d37ef3d037783e6632fc + +qd: +Proof size: 8.34 KB +Proof hash: 5c4b983121f47439518d544e37c3db6b9d21069935d187a93cf3cd14ea0beb3f +Prover_pp hash: c26481deef5e2ac21c864097715d13fef2e47185bf6dc87f7f3ee3074cef099a +Verifier_pp hash: fd831a01a3ac00e66d3db64225ab4a1223f10e2aa39df7699b9a49c5ee6e0716 + +qe: +Proof size: 8.34 KB +Proof hash: 20906b3811a36566ffdda4ac170dfc1f9382fe765d3d09df7868df80c3e3b965 +Prover_pp hash: 3b327b7df32531bcbc4d65e3e18164e99d775e8b306beccdcd778f6ea83ffbcc +Verifier_pp hash: 6a64920ff72568fbf096f8fcdf00be158fb6a66d6d84b58ebac4102c7062de3c + +qlg: +Proof size: 8.45 KB +Proof hash: 36ab356aa461d7c7ca1f9655a5ab891bfabd4568454af3833e6667ad0a9f5894 +Prover_pp hash: d0b917130f97f3c0a82fbaafdf6c3bff02e35cd7bc5f3a045f0d2479c1d7156c +Verifier_pp hash: c9730859a640503e3cd55620730383d1040379d17401a63a265d3343eac56b7a + +qrg: +Proof size: 8.45 KB +Proof hash: 1feecfdd6a57bce821ad6ee8198d3beed04f4b4c62097d516ae2136c86b1aba1 +Prover_pp hash: 24c39e58d3907a6597eb6ca16b515add501cdcdb0b3751f578a33a2f7182ad24 +Verifier_pp hash: 3c4bd62b11e467cd01678b9c6972005413735c2d8a3556514e35ff61802d3bcb + +qog: +Proof size: 8.45 KB +Proof hash: a5007184cc20475150ed5dab7d7e6c243b811d84bde81f3a4f458e4ed01f48f5 +Prover_pp hash: 29bb16b538821c55ed5437ac9ebf065abf7b018f88df8c76f5b85154da7de3da +Verifier_pp hash: 7c81d886954fab2b02826ead7df012a4754afe5df694128a46d184c37263f4c4 + +qdg: +Proof size: 8.45 KB +Proof hash: 0466950c8a48dc8e6d8404c614fb30d54ae132cfb1eec94053e24cc20797f367 +Prover_pp hash: 25901865656289d5bcacdd17bc86af40d418d1c6360eb8f374d88eb4887e91c8 +Verifier_pp hash: 9500d5c037eb7dc047c631579068c9ddb66ef78e7319236e87d8c76d5222c7ab + +qeg: +Proof size: 8.45 KB +Proof hash: 16a7612875d68e02dd9ff634d915d759f40e6ac8311c4d344dede8672b45e87c +Prover_pp hash: d437001858842ea6bed71a7d3cf59f4f1b5766dd57fbbb11b16cb2a4e5027d18 +Verifier_pp hash: eb85b73df8ab85a9ad04b7e8f489cb9fdf7f85e71bd55957b4c149dba60cbe9c + +qm: +Proof size: 8.34 KB +Proof hash: 029efa60f8a46cbbc22ef905902ccbb2c089147da07832d73db8899b4ba45e42 +Prover_pp hash: 71e6e83d9e14b9c8c3f1b319a8a00fdade770cd93cf2296101c0c9965a9398e3 +Verifier_pp hash: 36b67e1877801c6bf268fa0beabb14d690d5a2dcc93a76dcad23f11e8d540d4f + +qx2b: +Proof size: 8.41 KB +Proof hash: 4e4cde4ae2ae61b270107e82563dd8d2453cb312e4e73a82dd4bdc8379602454 +Prover_pp hash: 15103b865fe9c49d886473de9a33537575c2c37b74453e85c86f8212af172b15 +Verifier_pp hash: b45820195b1c6794662a91ed7af8515f7132f8a4b10d48f52979fb6f274915fa + +qx5a: +Proof size: 8.45 KB +Proof hash: af7a5b3494b21957bca7e4ea2fba38450028b25f96bacf2e5ac7f2312ab26e87 +Prover_pp hash: 325e3f0c5c1ae2b20737e226e71e56a9cad091df164cf1f58bd8b5a7647e4da0 +Verifier_pp hash: a599a88eb2f06ec615c5945cc4b0266086b0900b48e0477a04bcb7cb24f4ab8e + +qx5c: +Proof size: 8.45 KB +Proof hash: 9f0929d6288819a7a0042dd678b8296547111af57ac45ec2d689ac5be76bdb67 +Prover_pp hash: 039471f51fc81479e1821dffabe30f9d24dbf717e39f543fedd39729fbc52a00 +Verifier_pp hash: 4236e560d442e4ff882d82fc55b3da0f5fddd8ad64bb3c8dbd270fee5ae20cbc + +qecc_ws_add: +Proof size: 8.70 KB +Proof hash: 774ebbeafa13ccd3982b4e59c5fc07f8f35c674ad7bba506e8aca196f31c25ec +Prover_pp hash: 32f5f8443744eb30999730a46c1ba8516b97e3fc406e15f6b9f4ca4c49a6eafe +Verifier_pp hash: dec285a756eabf021088ca666abe760fe1dcc55774fce195cb69404f53c40c32 + +qecc_ed_add: +Proof size: 8.70 KB +Proof hash: dc623b0f9be06fbd4a452e2ef1b5ef63aa0008cd22bc26d206f2cdadd52686a7 +Prover_pp hash: 6d3cf4d4f12cdf8ec7c4a39ede89f896fcb341db04c1ad1cac7598193f6a3285 +Verifier_pp hash: 8525e221ebb25287ea9b373ef891f1b692db3a2bf6275afd84ead90e0031f6aa + +qecc_cond_ed_add: +Proof size: 8.90 KB +Proof hash: c6a704c46b155c10bf5381c5a1afdb2c3d608a59d07b1dfa5c469dd89e87ecb2 +Prover_pp hash: 08dd59858848f7f3ddfa4bdc6a3e70a2922748202f5d205250ce9f97c39071a1 +Verifier_pp hash: 399a4ece2192cb97f5ee9ae9b5f126955a5c841494a33cf8f0da10b31e474340 + +qbool: +Proof size: 8.44 KB +Proof hash: 2f704d7472292872937c4ca18ff3972601d96d9c4be6c83712f9ae6d94064abe +Prover_pp hash: eee1d99ae046545594f26c66a232b3b294456509e5f30c957bd49ecba64cccf9 +Verifier_pp hash: 816df57213896d4378202c71e98b82d5444fb5338088ff20433a53eea340fa17 + +qcond_swap: +Proof size: 8.60 KB +Proof hash: b2ffb96d27fc8ec06b40e485c29de108f28117b75a89a8e786b349cff02b6c67 +Prover_pp hash: eaa268b9efb4b24fe38084468637ce9adb299a8bca6483ac0485a6739be11367 +Verifier_pp hash: a0c509a9dccc8b99cba98456e5ecfd2ca0bb0ae8a16c69f20459e3a819f06298 + +q_anemoi: +Proof size: 9.92 KB +Proof hash: bc69f5034c01db96d7f35dea4a93472fa0f5fc171e092d8951f3431f5d45bb7d +Prover_pp hash: cf44e35fd9b6c166a02c358c8764cb9a49da546135938fbc345e08fe2e7788e4 +Verifier_pp hash: 0eb6617cdebe86a54bfc8bdde1c42430a0297feae96ca72b5082d1271a334721 + +no_public_inputs: +Proof size: 10.08 KB +Proof hash: 4b1f3a2f5099833143c182175de14b1374453c8b8444b1bee1c548be21005057 +Prover_pp hash: b56bff358c4bccdad28ba6c2fe39bca79c532cbb82bbc43e0d4249721dbb7c6f +Verifier_pp hash: 51c5dd60034dada7b51a8de17a504ded54b2c33746ec6af3f7911b5eac73d845 + +bnot: +Proof size: 8.41 KB +Proof hash: ad3fd8083809355dd55da16a3bdf7d85e7fe009d0174dd483ee234a2b8ac4103 +Prover_pp hash: 5eabcd479aa31c16b0f32b8f799aa07dfbbda5a256592f39e7d012c4f99be656 +Verifier_pp hash: 3f3ce646cb77c243aa64b34ebecd5829f8d001c2b403a5dd529b4ec3548d41ef + +zero_values: +Proof size: 9.92 KB +Proof hash: 3e5572e259cd74457f8b8bb1ef6d5971410591a220b757a1d4ea2521c8fdc53b +Prover_pp hash: 5bd9f5b09195c2245efd2bc1e3cf644743c5a1f6efc308226791011c2dfcb37a +Verifier_pp hash: 42290a3c4ccd9ddbc98570d96b767760d611516c9268d6643f7fcfc766dc7892 + +non_zero_values: +Proof size: 10.05 KB +Proof hash: 46d108e150a4db79fd268790854f1ab2883a001021f17636fc64eb2021b8094e +Prover_pp hash: 20ae1e910e83ccba27779ade52acd6c7b305d74c2dfe8268560121ac710a87bd +Verifier_pp hash: cd707c645f37557500c4620462fee3687f3748a92df2fb26c6e7fbe50980fdae + +big_circuit.2.5+big_circuit.2.5: +Proof size: 9.98 KB +Proof hash: f1d3ea8438f8cdcc26b9a99f260b3f44fb1deccd6d80fbc9ea6fb4d286760f4c +Prover_pp hash: 1499bd0c15610c6e283b9cabf202fb43b4040d079ae59b3d6045865e7674d459 +Verifier_pp hash: d00710465432e50b5aa06d1d98ebdaefd3e0d1818f38d002fbbf1776f1a520c9 + +upper_bound_no_pi: +Proof size: 8.34 KB +Proof hash: d280ac6c9c9018210cabaea160151b8172750c241e675fac295598e4d837f09c +Prover_pp hash: a04da74248938c0c52bdf28ba0230da5ed2ec7ecc7c07324ac237f326e326447 +Verifier_pp hash: cfdb1151daa3b67922cdf991d6bea04a13ff7174b353f59662efa0b3ec98bfca + +upper_bound_pi: +Proof size: 9.98 KB +Proof hash: 99d4aebf719011269822df03ee67a4b31070f25d786d33169d0b7f7b2346474e +Prover_pp hash: a8349391c118ccb88bccded92dd11978996e21615df51bb682cf633cee595aa7 +Verifier_pp hash: 029d7dc38ec62854e07830b7c66348710e2b201c1bd08d55f227e4d39716fd91 + +qc+ql+qr+qd+qe: +Proof size: 20.53 KB +Proof hash: f3666c72a12a0057310ea55f0f8587b7023ec4eaab9731ddd9ca4ce91057d033 +Prover_pp hash: 199dd9fa025e0f7ff5ed5c34a4e0bf9403d8bc684510d86b825413c6e7d53efb +Verifier_pp hash: f75d7bb30310b66ec5fcbd184bf298928bf1f67b5aa383afb2388fdf3cc68416 + +non_zero_values+non_zero_values+zero_values: +Proof size: 13.73 KB +Proof hash: a524735036136d2a2b766b5a97194dbca084d7c682eaf89f954438e2c53fb7a8 +Prover_pp hash: 72ba04473917b07f16b05e1ffe82a9166aa0c98d061f81362f294533ee0841da +Verifier_pp hash: 9e12bb3fc96c467ea8d1ff5f587889c8183cab8e4906a692310918e7a39d6215 + +qlg+qrg+non_zero_values+zero_values: +Proof size: 19.34 KB +Proof hash: 7c667e5fa1506d09c43ecd10df2ba3a22ff431e080a39212efcc28a1d5e8aebf +Prover_pp hash: 1cd75a6f6f334e3cd16d7097cf59521ec4dbe6baa8adb60b99328a9d2db03134 +Verifier_pp hash: aa44e336856b8d8bd767824f21c7728abaca16b28820e2b4abe80e88bbc53d90 + diff --git a/src/lib_aplonk/test/test_aplonk.ml b/src/lib_aplonk/test/test_aplonk.ml new file mode 100644 index 000000000000..53b2731190a0 --- /dev/null +++ b/src/lib_aplonk/test/test_aplonk.ml @@ -0,0 +1,292 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +open Plonk.Bls +module L = LibCircuit +module PP = Plonk.Polynomial_protocol.Make (Aggregation.Polynomial_commitment) +module Main = Plonk.Main_protocol.Make (PP) +module Circuits = Aplonk.Circuit.V (Aplonk.Main_protocol.Main_Pack) + +module Rollup_PIs = struct + open Aplonk.Pi_parameters + + let get_pi_module _ = (module Rollup_example : CircuitPI) +end + +let cs_of_repr public_input_size circuit = + let cs = L.get_cs circuit in + let plonk_circuit = Plonk.Circuit.to_plonk ~public_input_size cs.cs in + (plonk_circuit, cs.solver) + +(* Tests on Circuit functions *) +module Internal = struct + module Main = Plonk.Main_protocol + module H = Plonk_test.Helpers.Make (Main) + module Aplonk_main = Aplonk.Main_protocol.Make (Rollup_PIs) + + open Plonk_test.Helpers.Utils (L) + + (* Calls Plonk.(setup, prove & verify) on a plompiler circuit with the given inputs *) + let test_plompiler_circuit ~name circuit inputs = + let circuit, solver = cs_of_repr 0 circuit in + let witness = + try Plompiler.Solver.solve solver inputs + with e -> + print_string "\nSolver failure\n" ; + raise e + in + H.test_circuit ~name ~zero_knowledge:false circuit witness + + let test_pi () = + let log = 4 in + let n = 1 lsl log in + let domain = Domain.build_power_of_two log in + let p1 = S.random () in + let p2 = S.random () in + let x = S.random () in + let expected_PIx = + let pi_array = + Array.of_list (p1 :: p2 :: List.init (n - 2) (fun _ -> S.zero)) + in + let pi_poly = Evaluations.interpolation_fft2 domain pi_array in + Poly.(evaluate (opposite pi_poly) x) + in + let generator = Domain.get domain 1 in + let circuit = + let open L in + let n = S.of_int n in + let* p1 = input (Input.scalar p1) in + let* p2 = input (Input.scalar p2) in + let* x = input (Input.scalar x) in + let* exp = input (Input.scalar expected_PIx) in + let* xn = Circuits.Constraints.compute_xn x n in + let* zs = Circuits.Constraints.compute_zs xn in + let* res = Circuits.Gates.cs_pi ~generator ~n ~x ~zs [p1; p2] in + assert_equal exp res + in + let inputs = [|p1; p2; x; expected_PIx|] in + test_plompiler_circuit ~name:"test_pi" circuit inputs + + let test_t () = + let d = 10 in + let nb_t = 3 in + let n = 20 in + let t_list = + List.init nb_t (fun _ -> + Poly.of_coefficients (List.init d (fun i -> (S.random (), i)))) + in + let x = S.random () in + let xn = S.pow x (Z.of_int n) in + let x_ni = Array.init nb_t (fun i -> S.pow xn (Z.of_int i)) in + let t_list = List.map (fun t -> Poly.evaluate t x) t_list in + let _, t_exp = + List.fold_left + (fun (i, acc) t_val -> (i + 1, S.(acc + (x_ni.(i) * t_val)))) + (0, S.zero) + t_list + in + let circuit = + let open L in + let* xn = input (Input.scalar xn) in + let* t_list = mapM (fun x -> input (Input.scalar x)) t_list in + let* t_exp = input (Input.scalar t_exp) in + let* t_res = Circuits.Constraints.compute_t xn t_list in + assert_equal t_exp t_res + in + let inputs = Array.of_list ((xn :: t_list) @ [t_exp]) in + test_plompiler_circuit ~name:"test_t" circuit inputs + + let test_sum_alpha () = + let n = 20 in + let alpha = S.random () in + let list_val = List.init n (fun _ -> S.random ()) in + let exp = + List.fold_left + (fun acc x -> S.((alpha * acc) + x)) + S.zero + (List.rev list_val) + in + let circuit = + let open L in + let* list_val = mapM (fun x -> input (Input.scalar x)) list_val in + let* alpha = input (Input.scalar alpha) in + let* exp = input (Input.scalar exp) in + let* res = Circuits.Constraints.sum_alpha_i list_val alpha in + assert_equal exp res + in + let inputs = Array.of_list (list_val @ [alpha; exp]) in + test_plompiler_circuit ~name:"test_sum_alpha" circuit inputs + + let tests = + [ + Alcotest.test_case "Sum_alpha_i" `Quick test_sum_alpha; + Alcotest.test_case "PI" `Quick test_pi; + Alcotest.test_case "T" `Quick test_pi; + ] +end + +(* Tests on Main *) +module External = struct + module Main = Aplonk.Main_protocol.Make (Rollup_PIs) + + (* Builds n witness + witness is a function that takes a scalar pi_start & a solver and returns a witness that starts with pi_starts and its second element + *) + let get_witness (solver, witness) n = + Printf.printf "\n\nnb_proofs = %d" n ; + let pi_start = ref (S.random ()) in + let inputs = + List.init n (fun _ -> + let x, pi_end = witness ~pi_start:!pi_start solver in + pi_start := pi_end ; + x) + in + inputs + + (* Run Pack & aPlonk proto on the given circuit *) + let compare_protos + ?(pi = + (module Aplonk.Pi_parameters.Rollup_example + : Aplonk.Pi_parameters.CircuitPI)) (circuit, witness) nb_proofs () = + let module PI = (val pi) in + let module PIs = struct + let get_pi_module _ = (module PI : Aplonk.Pi_parameters.CircuitPI) + end in + let l = PI.nb_inner in + let circuit, solver = cs_of_repr l circuit in + let witness = get_witness (solver, witness) nb_proofs in + let circuit_map = Plonk.SMap.singleton "" (circuit, nb_proofs) in + let inputs = Plonk.SMap.singleton "" witness in + Printf.printf "\n\n*** SUPER ***" ; + let module Helpers = Plonk_test.Helpers.Make (Aplonk.Main_protocol.Make (PIs)) in + Helpers.test_circuits ~name:"compare_protos : aplonk" circuit_map inputs ; + Printf.printf "\n\n*** PLONK ***" ; + let module Helpers = Plonk_test.Helpers.Make (Plonk.Main_protocol) in + Helpers.test_circuits ~name:"compare_protos : Pack" circuit_map inputs + + let first_test_proto_rollup nb_proofs () = + let module PI = Aplonk.Pi_parameters.Rollup_example in + let module Helpers = + Plonk_test.Helpers.Make (Aplonk.Main_protocol.Make (Rollup_PIs)) in + let l = PI.nb_inner in + let circuit = + let wires = + Plonk.Circuit.make_wires + ~a:[0; 1; 2; 7; 8] + ~b:[3; 4; 5; 9; 10] + ~c:[2; 5; 6; 11; 12] + ~d:[0; 0; 0; 0; 0] + ~e:[0; 0; 0; 0; 0] + () + in + let gates = + Plonk.Circuit.make_gates + ~ql:S.[one; one; zero; zero; zero] + ~qr:S.[one; zero; zero; zero; zero] + ~qm:S.[zero; zero; one; zero; zero] + ~qo:S.[mone; mone; mone; zero; zero] + ~qc:S.[zero; one; zero; zero; zero] + ~qrg:S.[one; zero; zero; zero; zero] + ~qecc_ed_add:S.[zero; zero; zero; one; zero] + () + in + Plonk.Circuit.make ~wires ~gates ~public_input_size:l () + in + let witness ~pi_start _witness_aux = + let x0 = pi_start in + let x1 = S.random () in + let x3 = S.random () in + let x4 = S.random () in + let x2 = S.(x0 + x3 + x4) in + let x5 = S.(x1 + one) in + let x6 = S.(x2 * x5) in + let x7 = S.zero in + let x8 = S.one in + let x9 = S.zero in + let x10 = S.one in + let x11 = S.zero in + let x12 = S.one in + ([|x0; x1; x2; x3; x4; x5; x6; x7; x8; x9; x10; x11; x12|], x1) + in + let witness = get_witness (None, witness) nb_proofs in + let circuit_map = Plonk.SMap.singleton "" (circuit, nb_proofs) in + let inputs = Plonk.SMap.singleton "" witness in + Helpers.test_circuits ~name:"first_test_proto_rollup" circuit_map inputs + + let compare_protos_dummy_circuit = + let poseidon l = + let module Poseidon = Plompiler.Poseidon128.V (Plompiler.LibCircuit) in + Poseidon.digest l + in + let p1 = + S. + ( of_string + "0x73c016a42ded9578b5ea25de7ec0e3782f0c718f6f0fbadd194e42926f661b51", + of_string + "0x289e87a2d3521b5779c9166b837edc5ef9472e8bc04e463277bfabd432243cca" + ) + in + let p2 = + S. + ( of_string + "0x664321a58246e2f6eb69ae39f5c84210bae8e5c46641ae5c76d6f7c2b67fc475", + of_string + "0x362e1500d24eee9ee000a46c8e8ce8538bb22a7f1784b49880ed502c9793d457" + ) + in + let circuit = + let module Edwards = Plompiler.JubjubEdwards (L) in + let open L in + let* x0 = input ~kind:`Public (Input.scalar S.one) in + let* x1 = input ~kind:`Public (Input.scalar S.one) in + let* p1 = Edwards.input_point p1 in + let* p2 = Edwards.input_point p2 in + let* sum = Edwards.add p1 p2 in + let u = Edwards.get_u_coordinate sum in + let v = Edwards.get_v_coordinate sum in + let* res = poseidon (to_list [x0; x1; u; v]) in + assert_equal res res + in + let witness ~pi_start solver = + let x1 = S.random () in + let u1, v1 = p1 in + let u2, v2 = p2 in + let witness = + try Plompiler.Solver.solve solver [|pi_start; x1; u1; v1; u2; v2|] + with e -> + print_string "\nSolver failure\n" ; + raise e + in + (witness, x1) + in + compare_protos (circuit, witness) + + let tests = + [ + Alcotest.test_case "test proto" `Quick (first_test_proto_rollup 3); + Alcotest.test_case "compare protos" `Slow (compare_protos_dummy_circuit 3); + ] +end diff --git a/src/lib_aplonk/test/test_main_protocol.ml b/src/lib_aplonk/test/test_main_protocol.ml new file mode 100644 index 000000000000..ebe18c447b8f --- /dev/null +++ b/src/lib_aplonk/test/test_main_protocol.ml @@ -0,0 +1,157 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module External = struct + module Cases = Plonk_test.Cases + module SMap = Plonk.SMap + open Aplonk.Pi_parameters + + let no_pi_cases = + Cases.Unit_tests_for_each_selector.list @ [Cases.General.no_public_inputs] + + let one_pi_cases = + Cases.General_circuits.list @ Cases.General.list_one_public_input + + let pi_rollup_cases = Cases.(aggregate_cases Big_circuit.list) + + module No_input_PIs = struct + let get_pi_module _ = (module No_public_input : CircuitPI) + end + + module One_input_PIs = struct + let get_pi_module _ = (module One_public_input : CircuitPI) + end + + module Rollup_PIs = struct + let get_pi_module _ = (module Rollup_example : CircuitPI) + end + + let upper_bound_no_pi ~zero_knowledge () = + let module Main = Aplonk.Main_protocol.Make (No_input_PIs) in + let module H = Plonk_test.Helpers.Make (Main) in + let open Plonk_test.Cases in + let qc = Unit_tests_for_each_selector.qc in + + let circuits = SMap.of_list [(qc.name, (qc.circuit, 4))] in + let inputs = SMap.singleton qc.name [qc.witness] in + H.test_circuits ~name:"upper_bound_no_pi" ~zero_knowledge circuits inputs + + let upper_bound_pi_rollup ~zero_knowledge () = + let module Main = Aplonk.Main_protocol.Make (Rollup_PIs) in + let module H = Plonk_test.Helpers.Make (Main) in + let open Plonk_test.Cases in + let nb_proofs = 3 in + let nb_proofs_added = 1 in + let _name, circuits_map, inputs, _outcome = + Big_circuit.make ~nb_proofs ~public_input_size:2 ~k:3 |> aggregate_cases + in + let circuits = + SMap.map (fun (c, n) -> (c, n + nb_proofs_added)) circuits_map + in + H.test_circuits ~name:"upper_bound_pi" ~zero_knowledge circuits inputs + + let tests_quick pc_name = + let prefix s (n, f) = (s ^ "." ^ n, f) in + let no_pi_tests = + let module Main = Aplonk.Main_protocol.Make (No_input_PIs) in + let module H = Plonk_test.Helpers.Make (Main) in + List.map + (fun case -> (Cases.(case.name), H.run_test_case case ~verbose:false)) + no_pi_cases + in + let one_pi_tests = + let module Main = Aplonk.Main_protocol.Make (One_input_PIs) in + let module H = Plonk_test.Helpers.Make (Main) in + List.map + (fun case -> (Cases.(case.name), H.run_test_case case ~verbose:false)) + one_pi_cases + in + let pi_rollup_case = + let module Main = Aplonk.Main_protocol.Make (Rollup_PIs) in + let module H = Plonk_test.Helpers.Make (Main) in + let name, circuits_map, inputs_map, outcome = + Cases.(aggregate_cases Big_circuit.list) + in + ( name, + fun ~zero_knowledge () -> + H.test_circuits ~name ~zero_knowledge circuits_map inputs_map ~outcome + ) + in + let multi_tests = + let open Cases.Unit_tests_for_each_selector in + let open Cases.General in + let module PIs = struct + let pi_map = + SMap.of_list + [ + (qc.name, (module No_public_input : CircuitPI)); + (ql.name, (module No_public_input : CircuitPI)); + (qr.name, (module No_public_input : CircuitPI)); + (qd.name, (module No_public_input : CircuitPI)); + (qe.name, (module No_public_input : CircuitPI)); + (qlg.name, (module No_public_input : CircuitPI)); + (qrg.name, (module No_public_input : CircuitPI)); + (zero_values.name, (module One_public_input : CircuitPI)); + (non_zero_values.name, (module One_public_input : CircuitPI)); + ] + + let get_pi_module circuit_name = SMap.find circuit_name pi_map + end in + let module Main = Aplonk.Main_protocol.Make (PIs) in + let module H = Plonk_test.Helpers.Make (Main) in + List.concat_map + (fun cases -> + let name, circuits_map, inputs_map, outcome = + Cases.(aggregate_cases cases) + in + [ + ( name, + fun ~zero_knowledge () -> + H.test_circuits + ~name + ~zero_knowledge + ~outcome + circuits_map + inputs_map ); + ]) + [ + [qc; ql; qr; qd; qe]; + [non_zero_values; non_zero_values; zero_values]; + [qlg; qrg; non_zero_values; zero_values]; + ] + in + no_pi_tests @ one_pi_tests @ [pi_rollup_case] + @ [ + ("nb_proofs no pi", upper_bound_no_pi); + ("nb_proofs pi_rollup", upper_bound_pi_rollup); + ] + @ multi_tests + |> List.map (prefix pc_name) +end + +let tests = + List.map + (fun (n, f) -> Alcotest.test_case n `Quick (f ~zero_knowledge:false)) + (External.tests_quick "aplonk") -- GitLab From 2a0b2895d20a47473cda0047e1296af039327f58 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 15 Mar 2023 15:04:41 +0100 Subject: [PATCH 24/34] lib_distributed_internal: import from privacy-team/cryptography fork --- .gitlab/ci/jobs/packaging/opam_package.yml | 4 + dune-project | 2 + manifest/main.ml | 19 + opam/octez-distributed-internal.opam | 20 + opam/octez-distributed-lwt-internal.opam | 23 + src/lib_distributed_internal/README.md | 27 + .../lwt/distributed_lwt.ml | 78 + .../lwt/distributed_lwt.mli | 19 + src/lib_distributed_internal/lwt/dune | 13 + .../src/distributed.ml | 2116 +++++++++++++++++ .../src/distributed.mli | 354 +++ src/lib_distributed_internal/src/dune | 9 + 12 files changed, 2684 insertions(+) create mode 100644 opam/octez-distributed-internal.opam create mode 100644 opam/octez-distributed-lwt-internal.opam create mode 100644 src/lib_distributed_internal/README.md create mode 100644 src/lib_distributed_internal/lwt/distributed_lwt.ml create mode 100644 src/lib_distributed_internal/lwt/distributed_lwt.mli create mode 100644 src/lib_distributed_internal/lwt/dune create mode 100644 src/lib_distributed_internal/src/distributed.ml create mode 100644 src/lib_distributed_internal/src/distributed.mli create mode 100644 src/lib_distributed_internal/src/dune diff --git a/.gitlab/ci/jobs/packaging/opam_package.yml b/.gitlab/ci/jobs/packaging/opam_package.yml index 86fcd74a9508..942e6a33fe28 100644 --- a/.gitlab/ci/jobs/packaging/opam_package.yml +++ b/.gitlab/ci/jobs/packaging/opam_package.yml @@ -286,6 +286,10 @@ opam:octez-crawler: # Ignoring unreleased package octez-dal-node. +# Ignoring unreleased package octez-distributed-internal. + +# Ignoring unreleased package octez-distributed-lwt-internal. + # Ignoring unreleased package octez-evm-proxy. opam:octez-injector: diff --git a/dune-project b/dune-project index 2f180eeb41e6..b3c21c99059a 100644 --- a/dune-project +++ b/dune-project @@ -19,6 +19,8 @@ (package (name octez-crawler)) (package (name octez-dac-node)) (package (name octez-dal-node)) +(package (name octez-distributed-internal)) +(package (name octez-distributed-lwt-internal)) (package (name octez-evm-proxy)) (package (name octez-injector)) (package (name octez-mec)) diff --git a/manifest/main.ml b/manifest/main.ml index 25d80b120a9d..0237979b3191 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -365,6 +365,25 @@ let () = (* INTERNAL LIBS *) +(* Fork of https://github.com/essdotteedot/distributed, used for plonk. + uwt has been removed. The directories examples and tests have been dropped. +*) +let distributed_internal = + public_lib + "octez-distributed-internal" + ~internal_name:"distributed" + ~path:"src/lib_distributed_internal/src" + ~synopsis:"Fork of distributed. Use for Octez only" + ~deps:[unix] + +let _distributed_internal_lwt = + public_lib + "octez-distributed-lwt-internal" + ~internal_name:"distributed_lwt" + ~path:"src/lib_distributed_internal/lwt" + ~synopsis:"Fork of distributed-lwt. Use for Octez only" + ~deps:[unix; distributed_internal; lwt; lwt_unix; logs_lwt] + let tezt_lib = external_lib ~js_compatible:false diff --git a/opam/octez-distributed-internal.opam b/opam/octez-distributed-internal.opam new file mode 100644 index 000000000000..4097153e5d1d --- /dev/null +++ b/opam/octez-distributed-internal.opam @@ -0,0 +1,20 @@ +# This file was automatically generated, do not edit. +# Edit file manifest/main.ml instead. +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: ["Tezos devteam"] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "3.0" } + "ocaml" { >= "4.14" } + "base-unix" +] +build: [ + ["rm" "-r" "vendors"] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Fork of distributed. Use for Octez only" diff --git a/opam/octez-distributed-lwt-internal.opam b/opam/octez-distributed-lwt-internal.opam new file mode 100644 index 000000000000..eecebd2b4d2e --- /dev/null +++ b/opam/octez-distributed-lwt-internal.opam @@ -0,0 +1,23 @@ +# This file was automatically generated, do not edit. +# Edit file manifest/main.ml instead. +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: ["Tezos devteam"] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "3.0" } + "ocaml" { >= "4.14" } + "base-unix" + "octez-distributed-internal" + "lwt" { >= "5.6.0" } + "logs" +] +build: [ + ["rm" "-r" "vendors"] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Fork of distributed-lwt. Use for Octez only" diff --git a/src/lib_distributed_internal/README.md b/src/lib_distributed_internal/README.md new file mode 100644 index 000000000000..ce78b30cb0d2 --- /dev/null +++ b/src/lib_distributed_internal/README.md @@ -0,0 +1,27 @@ +# distributed [![Build Status](https://travis-ci.org/essdotteedot/distributed.svg?branch=master)](https://travis-ci.org/essdotteedot/distributed) [![Coverage Status](https://coveralls.io/repos/github/essdotteedot/distributed/badge.svg?branch=master)](https://coveralls.io/github/essdotteedot/distributed?branch=master) [![Docs Online](https://img.shields.io/badge/Docs-Online-brightgreen.svg)](https://essdotteedot.github.io/distributed/) [![Appveyor Status](https://ci.appveyor.com/api/projects/status/github/essdotteedot/distributed?branch=master&svg=true)](https://ci.appveyor.com/project/essdotteedot/distributed) +Library to provide Erlang style distributed computations. This library is inspired by Cloud Haskell. + +Primitives for spawning processes (in the Erlang sense) either remotely or locally, monitoring/unmonitoring spawned processes, sending, +receiving, broadcasting messages to those processes. Unlike Erlang, the messages that are sent between processes are typed. + +Installation +------------ + +The core library, lwt implementation, and uwt implementation are available via [OPAM](https://opam.ocaml.org): + + $ opam install distributed + + $ opam install distributed-lwt + + $ opam install distributed-uwt + +Documentation +------------- + +The API documentation is available [here](https://essdotteedot.github.io/distributed/). +Example programs can be found in the [examples](examples) directory. + +License +------- + +[MIT License](LICENSE.md) diff --git a/src/lib_distributed_internal/lwt/distributed_lwt.ml b/src/lib_distributed_internal/lwt/distributed_lwt.ml new file mode 100644 index 000000000000..993079831638 --- /dev/null +++ b/src/lib_distributed_internal/lwt/distributed_lwt.ml @@ -0,0 +1,78 @@ +module type CustomerLogger = sig + val msg : Logs.level -> 'a Logs_lwt.log +end + +module IO_LWT (L : CustomerLogger) = struct + type 'a t = 'a Lwt.t + + type 'a stream = 'a Lwt_stream.t + + type input_channel = Lwt_io.input_channel + + type output_channel = Lwt_io.output_channel + + type server = Lwt_io.server + + type level = Debug | Info | Warning | Error + + exception Timeout = Lwt_unix.Timeout + + let lib_name = "Distributed_lwt" + + let lib_version = "0.2.0" + + let lib_description = "A Lwt based implementation." + + let return = Lwt.return + + let ( >>= ) = Lwt.( >>= ) + + let fail = Lwt.fail + + let catch = Lwt.catch + + let async = Lwt.async + + let create_stream = Lwt_stream.create + + let get = Lwt_stream.get + + let stream_append = Lwt_stream.append + + let close_input = Lwt_io.close + + let close_output = Lwt_io.close + + let read_value = Lwt_io.read_value + + let write_value = Lwt_io.write_value + + let open_connection sock_addr = Lwt_io.open_connection sock_addr + + let establish_server ?backlog sock_addr server_fn = + Lwt_io.establish_server_with_client_address ?backlog sock_addr server_fn + + let of_logs_lwt_level = function + | Debug -> Logs.Debug + | Info -> Logs.Info + | Warning -> Logs.Warning + | Error -> Logs.Error + + let log (level : level) (msg_fmtter : unit -> string) = + L.msg (of_logs_lwt_level level) (fun m -> m "%s" @@ msg_fmtter ()) + >>= fun _ -> return () + + let shutdown_server = Lwt_io.shutdown_server + + let sleep = Lwt_unix.sleep + + let timeout = Lwt_unix.timeout + + let pick = Lwt.pick + + let at_exit = Lwt_main.at_exit +end + +module Make (M : Distributed.Message_type) (L : CustomerLogger) : + Distributed.Process with type 'a io = 'a Lwt.t and type message_type = M.t = + Distributed.Make (IO_LWT (L)) (M) diff --git a/src/lib_distributed_internal/lwt/distributed_lwt.mli b/src/lib_distributed_internal/lwt/distributed_lwt.mli new file mode 100644 index 000000000000..bb4a1699fa86 --- /dev/null +++ b/src/lib_distributed_internal/lwt/distributed_lwt.mli @@ -0,0 +1,19 @@ +(** A lwt based implementation of {!module:Distributed}. Note, that this lwt based implmentation depends on the [Logs_lwt] library. + In keeping with the usage conventions of the [Logs] library, this implementation does not define a source, it does not set the + log level, and it does not define a reporter. The application is expected to define a source, set the log level, and define + a reporter (see the examples). + + @author essdotteedot + @version 0.2.0 + *) + +(** This module provides a Log_lwt based logger to use. *) +module type CustomerLogger = sig + (** [msg level logger] returns a logger that can be use to log levels at the provided level. The returned thread only proceeds once the log operation is over. *) + val msg : Logs.level -> 'a Logs_lwt.log +end + +(** Functor to create a module of type {!module:Distributed.Process} given a message module [M] of type {!module:Distributed.Message_type} + and a custom logger module [L] of type {!module:CustomerLogger}. *) +module Make (M : Distributed.Message_type) (L : CustomerLogger) : + Distributed.Process with type 'a io = 'a Lwt.t and type message_type = M.t diff --git a/src/lib_distributed_internal/lwt/dune b/src/lib_distributed_internal/lwt/dune new file mode 100644 index 000000000000..ed38a0a6320a --- /dev/null +++ b/src/lib_distributed_internal/lwt/dune @@ -0,0 +1,13 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name distributed_lwt) + (public_name octez-distributed-lwt-internal) + (instrumentation (backend bisect_ppx)) + (libraries + unix + octez-distributed-internal + lwt + lwt.unix + logs.lwt)) diff --git a/src/lib_distributed_internal/src/distributed.ml b/src/lib_distributed_internal/src/distributed.ml new file mode 100644 index 000000000000..4b34e3160c66 --- /dev/null +++ b/src/lib_distributed_internal/src/distributed.ml @@ -0,0 +1,2116 @@ +module Potpourri = struct + let get_option (v : 'a option) : 'a = + match v with None -> assert false (*BISECT-IGNORE*) | Some v' -> v' + + let map_default_option (f : 'a -> 'b) (default_value : 'b) (opt : 'a option) : + 'b = + match opt with Some v -> f v | None -> default_value + + let post_incr (v : int ref) : int = + let res = !v in + v := !v + 1 ; + res + + let of_option (f : unit -> 'a) : 'a option = try Some (f ()) with _ -> None + + let pp_list ?first ?last ?sep (items : 'a list) + (string_of_item : 'a -> string) formatter : unit = + if first <> None then Format.fprintf formatter (get_option first) else () ; + List.iter + (fun i -> + let s = string_of_item i in + Format.fprintf formatter "%s" s ; + if sep <> None then Format.fprintf formatter (get_option sep) else ()) + items ; + if last <> None then Format.fprintf formatter (get_option last) else () +end + +module Node_id = struct + type t = {ip : Unix.inet_addr option; port : int option; name : string} + + let make_local_node name = {ip = None; port = None; name} + + let make_remote_node ipStr port name = + {ip = Some (Unix.inet_addr_of_string ipStr); port = Some port; name} + + let is_local node local_node = + node.ip = local_node.ip && node.port = local_node.port + + let get_name {name; _} = name + + let print_string_of_node node formatter = + let string_of_ip = + if node.ip = None then "None" + else Unix.string_of_inet_addr @@ Potpourri.get_option node.ip + in + let string_of_port = + if node.port = None then "None" + else string_of_int @@ Potpourri.get_option node.port + in + Format.fprintf + formatter + "{ip : %s ; port : %s ; name : %s}" + string_of_ip + string_of_port + node.name + + let get_ip {ip; _} = ip + + let get_port {port; _} = port +end + +module Node_id_seeded_hash_type = struct + type t = Node_id.t + + let equal (n1 : t) (n2 : t) : bool = + (Node_id.get_ip n1, Node_id.get_port n1) + = (Node_id.get_ip n2, Node_id.get_port n2) + + let hash (seed : int) (n : t) : int = + Hashtbl.seeded_hash seed (Node_id.get_ip n, Node_id.get_port n) +end + +module Node_id_hashtbl = Hashtbl.MakeSeeded (Node_id_seeded_hash_type) + +module Process_id = struct + type t = {node : Node_id.t; proc_id : int} + + let make nid pid = {node = nid; proc_id = pid} + + let make_local name next_process_id = + { + node = Node_id.make_local_node name; + proc_id = Potpourri.post_incr next_process_id; + } + + let make_remote ipStr port name next_process_id = + { + node = Node_id.make_remote_node ipStr port name; + proc_id = Potpourri.post_incr next_process_id; + } + + let is_local {node; _} local_node = Node_id.is_local node local_node + + let get_node {node; _} = node + + let get_id {proc_id; _} = proc_id + + let print_string_of_pid p formatter = + Format.fprintf formatter "{node : " ; + Node_id.print_string_of_node p.node formatter ; + Format.fprintf formatter " ; id : %d}" p.proc_id +end + +module Process_id_seeed_hash_type = struct + type t = Process_id.t + + let equal (p1 : t) (p2 : t) : bool = + let p1_ip = Node_id.get_ip @@ Process_id.get_node p1 in + let p1_port = Node_id.get_port @@ Process_id.get_node p1 in + let p1_id = Process_id.get_id p1 in + + let p2_ip = Node_id.get_ip @@ Process_id.get_node p2 in + let p2_port = Node_id.get_port @@ Process_id.get_node p2 in + let p2_id = Process_id.get_id p2 in + + (p1_ip, p1_port, p1_id) = (p2_ip, p2_port, p2_id) + + let hash (seed : int) (p : t) : int = + let p_ip = Node_id.get_ip @@ Process_id.get_node p in + let p_port = Node_id.get_port @@ Process_id.get_node p in + let p_id = Process_id.get_id p in + Hashtbl.seeded_hash seed (p_ip, p_port, p_id) +end + +module Process_id_hashtbl = Hashtbl.MakeSeeded (Process_id_seeed_hash_type) + +module type Nonblock_io = sig + type 'a t + + type 'a stream + + type input_channel + + type output_channel + + type server + + type level = Debug | Info | Warning | Error + + exception Timeout + + val lib_name : string + + val lib_version : string + + val lib_description : string + + val return : 'a -> 'a t + + val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t + + val fail : exn -> 'a t + + val catch : (unit -> 'a t) -> (exn -> 'a t) -> 'a t + + val async : (unit -> unit t) -> unit + + val create_stream : unit -> 'a stream * ('a option -> unit) + + val get : 'a stream -> 'a option t + + val stream_append : 'a stream -> 'a stream -> 'a stream + + val close_input : input_channel -> unit t + + val close_output : output_channel -> unit t + + val read_value : input_channel -> 'a t + + val write_value : + output_channel -> ?flags:Marshal.extern_flags list -> 'a -> unit t + + val open_connection : Unix.sockaddr -> (input_channel * output_channel) t + + val establish_server : + ?backlog:int -> + Unix.sockaddr -> + (Unix.sockaddr -> input_channel * output_channel -> unit t) -> + server t + + val shutdown_server : server -> unit t + + val log : level -> (unit -> string) -> unit t + + val sleep : float -> unit t + + val timeout : float -> 'a t + + val pick : 'a t list -> 'a t + + val at_exit : (unit -> unit t) -> unit +end + +module type Message_type = sig + type t + + val string_of_message : t -> string +end + +module type Process = sig + exception Init_more_than_once + + exception InvalidNode of Node_id.t + + exception Local_only_mode + + type 'a io + + type 'a t + + type message_type + + type 'a matcher_list + + type monitor_ref + + type monitor_reason = + | Normal of Process_id.t + | Exception of Process_id.t * exn + | UnkownNodeId of Process_id.t * Node_id.t + | NoProcess of Process_id.t + + module Remote_config : sig + type t = { + remote_nodes : (string * int * string) list; + local_port : int; + connection_backlog : int; + node_name : string; + node_ip : string; + } + end + + module Local_config : sig + type t = {node_name : string} + end + + type node_config = Local of Local_config.t | Remote of Remote_config.t + + val return : 'a -> 'a t + + val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t + + type proc_rep = Fun of (unit -> unit t) | Registered of string + + val register : string -> (Process_id.t -> unit -> unit t) -> unit t + + val fail : exn -> 'a t + + val catch : (unit -> 'a t) -> (exn -> 'a t) -> 'a t + + val spawn : + ?monitor:bool -> + Node_id.t -> + proc_rep -> + Process_id.t -> + (Process_id.t * monitor_ref option) t + + val case : (message_type -> (unit -> 'a t) option) -> 'a matcher_list + + val termination_case : (monitor_reason -> 'a t) -> 'a matcher_list + + val ( |. ) : 'a matcher_list -> 'a matcher_list -> 'a matcher_list + + val receive : ?timeout_duration:float -> 'a matcher_list -> 'a option t + + val receive_loop : ?timeout_duration:float -> bool matcher_list -> unit t + + val send : Process_id.t -> message_type -> unit t + + val ( >! ) : Process_id.t -> message_type -> unit t + + val broadcast : Node_id.t -> message_type -> unit t + + val monitor : Process_id.t -> monitor_ref t + + val unmonitor : monitor_ref -> unit t + + val get_self_pid : Process_id.t t + + val get_self_node : Node_id.t t + + val get_remote_node : string -> Node_id.t option t + + val get_remote_nodes : Node_id.t list t + + val add_remote_node : string -> int -> string -> Node_id.t t + + val remove_remote_node : Node_id.t -> unit t + + val lift_io : 'a io -> 'a t + + val run_node : ?process:(unit -> unit t) -> node_config -> unit io +end + +module Make (I : Nonblock_io) (M : Message_type) : + Process with type message_type = M.t and type 'a io = 'a I.t = struct + exception Init_more_than_once + + exception InvalidNode of Node_id.t + + exception Local_only_mode + + type 'a io = 'a I.t + + type message_type = M.t + + type monitor_ref = Monitor_Ref of int * Process_id.t * Process_id.t + (* unique id, the process doing the monitoring and the process being monitored *) + + type monitor_reason = + | Normal of Process_id.t + | Exception of Process_id.t * exn + | UnkownNodeId of Process_id.t * Node_id.t + | NoProcess of Process_id.t + + module Remote_config = struct + type t = { + remote_nodes : (string * int * string) list; + local_port : int; + connection_backlog : int; + node_name : string; + node_ip : string; + } + end + + module Local_config = struct + type t = {node_name : string} + end + + type node_config = Local of Local_config.t | Remote of Remote_config.t + + module Monitor_ref_order_type = struct + type t = monitor_ref + + let compare (Monitor_Ref (id1, _, _) : t) (Monitor_Ref (id2, _, _) : t) : + int = + id1 - id2 + end + + module Monitor_ref_set = Set.Make (Monitor_ref_order_type) + + type message = + | Data of Process_id.t * Process_id.t * message_type + (* sending process id, receiving process id and the message *) + | Broadcast of + Process_id.t + * Node_id.t + * message_type (* sending process id, receiving node and the message *) + | Proc of proc_rep * Process_id.t * Process_id.t + (* the process to be spawned elsewhere and the process that requested the spawning *) + | Spawn_monitor of proc_rep * Process_id.t * Process_id.t * Process_id.t + (* the process to be spawned elsewhere, the monitoring process and the process that requested the spawning.*) + | Node of Node_id.t + (* initial message sent to remote node to identify ourselves *) + | Exit of Process_id.t * monitor_reason + (* process that was being monitored and the reason for termination *) + | Monitor of Process_id.t * Process_id.t * Process_id.t + (* the process doing the monitoring and the id of the process to be monitored and the process that requested the monitoring *) + | Unmonitor of monitor_ref * Process_id.t + (* process to unmonitor and the process that requested the unmonitor *) + | Proc_result of Process_id.t * Process_id.t + (* result of spawning a process and the receiver process id *) + | Spawn_monitor_result of message option * monitor_ref * Process_id.t + (* result of spawning and monitoring a process and the receiver process id *) + | Monitor_result of + message option + * monitor_ref + * Process_id.t (* result of monitor and the receiving process *) + | Unmonitor_result of monitor_ref * Process_id.t + (* monitor ref that was requested to be unmonitored and the receiving process *) + + and node_state = { + mailboxes : (int, message I.stream * (message option -> unit)) Hashtbl.t; + remote_nodes : I.output_channel Node_id_hashtbl.t; + monitor_table : Monitor_ref_set.t Process_id_hashtbl.t; + local_node : Node_id.t; + monitor_ref_id : int ref; + config : Remote_config.t option ref; + log_buffer : Buffer.t; + log_formatter : Format.formatter; + est_in_ch : I.input_channel option ref; + (* input channel from calling I.establish_server, store here so we can close when server exits*) + est_out_ch : I.output_channel option ref; + (* output_channel channel from calling I.establish_server, store here so we can close when server exits*) + node_server : I.server option ref; + (* the server from calling I.establish_server, store here so we can close listening socket when server exits *) + next_process_id : int ref; + registered_funs : (string, Process_id.t -> unit -> unit t) Hashtbl.t; + } + + and 'a t = node_state * Process_id.t -> (node_state * Process_id.t * 'a) io + + and proc_rep = Fun of (unit -> unit t) | Registered of string + + type 'a matcher = message -> (unit -> 'a t) option + + type 'a matcher_list = + | Matcher of 'a matcher + | Matchers of 'a matcher * 'a matcher_list + + let initalised = ref false + + let dist_lib_version = "0.6.0" + + let print_string_of_termination_reason (reason : monitor_reason) + (formatter : Format.formatter) : unit = + match reason with + | Normal pid -> + Format.fprintf formatter "{termination reason : normal ; pid : " ; + Process_id.print_string_of_pid pid formatter ; + Format.fprintf formatter "}" + | Exception (pid, e) -> + Format.fprintf + formatter + "{termination reason : exception %s ; pid : " + (Printexc.to_string e) ; + Process_id.print_string_of_pid pid formatter ; + Format.fprintf formatter "}" + | UnkownNodeId (pid, n) -> + Format.fprintf formatter "{termination reason : unknown node id " ; + Node_id.print_string_of_node n formatter ; + Format.fprintf formatter " ; pid : " ; + Process_id.print_string_of_pid pid formatter ; + Format.fprintf formatter "}" + | NoProcess p -> + Format.fprintf formatter "{termination reason : unknown process" ; + Process_id.print_string_of_pid p formatter ; + Format.fprintf formatter "}" + + let print_string_of_monitor_ref (Monitor_Ref (id, pid, monitee_pid)) + (formatter : Format.formatter) : unit = + Format.fprintf formatter "{id : %d ; monitor process : " id ; + Process_id.print_string_of_pid pid formatter ; + Format.fprintf formatter " ; monitee process : " ; + Process_id.print_string_of_pid monitee_pid formatter ; + Format.fprintf formatter "}" + + let print_string_of_monitor_notification (Monitor_Ref (id, pid, monitee_pid)) + (reason : monitor_reason) (formatter : Format.formatter) : unit = + Format.fprintf formatter "{id : %d ; monitor process : " id ; + Process_id.print_string_of_pid pid formatter ; + Format.fprintf formatter " ; monitee process" ; + Process_id.print_string_of_pid monitee_pid formatter ; + Format.fprintf formatter " ; reason : " ; + print_string_of_termination_reason reason formatter ; + Format.fprintf formatter "}" + + let rec print_string_of_message (m : message) (formatter : Format.formatter) : + unit = + match m with + | Data (sender, recver, msg) -> + Format.fprintf formatter "Data : {sender pid : " ; + Process_id.print_string_of_pid sender formatter ; + Format.fprintf formatter " ; receiver pid : " ; + Process_id.print_string_of_pid recver formatter ; + Format.fprintf formatter " ; message : %s}" (M.string_of_message msg) + | Broadcast (sender, recv_node, msg) -> + Format.fprintf formatter "Broadcast : {sender pid : " ; + Process_id.print_string_of_pid sender formatter ; + Format.fprintf formatter " ; receiver node : " ; + Node_id.print_string_of_node recv_node formatter ; + Format.fprintf formatter " ; message : %s}" (M.string_of_message msg) + | Proc (_, sender_pid, _) -> + Format.fprintf formatter "Proc { ; sender pid : " ; + Process_id.print_string_of_pid sender_pid formatter + | Spawn_monitor (_, pid, sender, _) -> + Format.fprintf formatter "Spawn and monitor { ; monitor pid : " ; + Process_id.print_string_of_pid pid formatter ; + Format.fprintf formatter " ; sender pid " ; + Process_id.print_string_of_pid sender formatter ; + Format.fprintf formatter "}" + | Node nid -> + Format.fprintf formatter "Node " ; + Node_id.print_string_of_node nid formatter + | Exit (pid, mreason) -> + Format.fprintf formatter "Exit : {exit pid : " ; + Process_id.print_string_of_pid pid formatter ; + Format.fprintf formatter " ; reason : " ; + print_string_of_termination_reason mreason formatter ; + Format.fprintf formatter "}" + | Monitor (monitor_pid, monitee_pid, sender) -> + Format.fprintf formatter "Monitor : {monitor pid : " ; + Process_id.print_string_of_pid monitor_pid formatter ; + Format.fprintf formatter " ; monitee pid : " ; + Process_id.print_string_of_pid monitee_pid formatter ; + Format.fprintf formatter " ; sender pid : " ; + Process_id.print_string_of_pid sender formatter ; + Format.fprintf formatter "}" + | Unmonitor (mref, sender) -> + Format.fprintf + formatter + "Unmonitor : {monitor reference to unmonitor : " ; + print_string_of_monitor_ref mref formatter ; + Format.fprintf formatter " ; sender pid : " ; + Process_id.print_string_of_pid sender formatter ; + Format.fprintf formatter "}" + | Proc_result (pid, recv_pid) -> + Format.fprintf formatter "Proc result {spawned pid : " ; + Process_id.print_string_of_pid pid formatter ; + Format.fprintf formatter " ; receiver pid : " ; + Process_id.print_string_of_pid recv_pid formatter ; + Format.fprintf formatter "}" + | Spawn_monitor_result (monitor_msg, monitor_res, receiver) -> + Format.fprintf formatter "Spawn and monitor result {monitor message : " ; + Potpourri.map_default_option + (fun m -> print_string_of_message m formatter) + () + monitor_msg ; + Format.fprintf formatter " ; monitor result : " ; + print_string_of_monitor_ref monitor_res formatter ; + Format.fprintf formatter " : receiver pid : " ; + Process_id.print_string_of_pid receiver formatter ; + Format.fprintf formatter "}" + | Monitor_result (monitor_msg, monitor_res, receiver) -> + Format.fprintf formatter "Monitor result {monitor message : " ; + Potpourri.map_default_option + (fun m -> print_string_of_message m formatter) + () + monitor_msg ; + Format.fprintf formatter " ; monitor result : " ; + print_string_of_monitor_ref monitor_res formatter ; + Format.fprintf formatter " ; receiver pid : " ; + Process_id.print_string_of_pid receiver formatter ; + Format.fprintf formatter "}" + | Unmonitor_result (mref, pid) -> + Format.fprintf + formatter + "Unmonitor result : {monittor reference to unmonitor: " ; + print_string_of_monitor_ref mref formatter ; + Format.fprintf formatter " ; receiver pid : " ; + Process_id.print_string_of_pid pid formatter ; + Format.fprintf formatter "}" + + let print_string_of_config (c : node_config) (formatter : Format.formatter) : + unit = + match c with + | Local l -> + Format.fprintf + formatter + "{node type : local ; node name : %s}" + l.Local_config.node_name + | Remote r -> + let print_remote_nodes () = + Potpourri.pp_list + ~first:"[" + ~last:"]" + ~sep:";" + r.Remote_config.remote_nodes + (fun (ip, port, name) -> + Format.sprintf "%s:%d, name : %s" ip port name) + formatter + in + Format.fprintf formatter "{node type : remote ; remote nodes : " ; + print_remote_nodes () ; + Format.fprintf + formatter + " ; local port : %d ; connection backlog : %d ; node name : %s ; \ + node ip : %s}" + r.Remote_config.local_port + r.Remote_config.connection_backlog + r.Remote_config.node_name + r.Remote_config.node_ip + + let log_msg (ns : node_state) (level : I.level) ?exn (action : string) ?pid + (details : unit -> unit) : unit I.t = + let time_str () = + let time_float = Unix.gettimeofday () in + let time_record = Unix.gmtime time_float in + Format.fprintf + ns.log_formatter + "[%d-%02d-%02d-%02d:%02d:%02d:%03.0f]" + (1900 + time_record.Unix.tm_year) + (1 + time_record.Unix.tm_mon) + time_record.Unix.tm_mday + time_record.Unix.tm_hour + time_record.Unix.tm_min + time_record.Unix.tm_sec + (mod_float (time_float *. 1000.) 1000.) + in + let backtrace_str () = + if Printexc.backtrace_status () then Printexc.get_backtrace () else "" + in + let str_of_log_bugger () = + let str_contents = Buffer.contents ns.log_buffer in + Buffer.reset ns.log_buffer ; + str_contents + in + let print_log_msg () = + time_str () ; + Format.fprintf ns.log_formatter "[Node : " ; + Node_id.print_string_of_node ns.local_node ns.log_formatter ; + (match pid with + | None -> () + | Some pid' -> Format.fprintf ns.log_formatter "|Process : %d" pid') ; + Format.fprintf ns.log_formatter "] [Action : %s] [Details : " action ; + details () ; + Format.fprintf ns.log_formatter "]" ; + match exn with + | None -> () + | Some exn' -> + Format.fprintf + ns.log_formatter + " [Exception : %s] [Backtrace : %s]" + (Printexc.to_string exn') + (backtrace_str ()) + in + I.log level (fun () -> + print_log_msg () ; + str_of_log_bugger ()) + + let safe_close_channel (ns : node_state) + (ch : [`Out of I.output_channel | `In of I.input_channel]) + (action : string) (details : unit -> unit) : unit I.t = + let open I in + catch + (fun () -> + match ch with + | `Out out_ch -> close_output out_ch + | `In in_ch -> close_input in_ch) + (fun e -> log_msg ns Warning ~exn:e action details) + + let at_exit_handler ns () = + let open I in + log_msg ns Info "at exit handler" (fun () -> + Format.fprintf ns.log_formatter "at exit handler started") + >>= fun () -> + (match !(ns.node_server) with + | Some serv -> + catch + (fun () -> shutdown_server serv) + (fun exn -> + log_msg ns Warning ~exn "node shutting down" (fun () -> + Format.fprintf + ns.log_formatter + "error while shutting down server")) + | None -> return ()) + >>= fun () -> + (match (!(ns.est_in_ch), !(ns.est_out_ch)) with + | Some est_in, None -> + safe_close_channel ns (`In est_in) "node shutting down" (fun () -> + Format.fprintf + ns.log_formatter + "error while closing remote connection") + | None, Some est_out -> + safe_close_channel ns (`Out est_out) "node shutting down" (fun () -> + Format.fprintf + ns.log_formatter + "error while closing remote connection") + | Some est_in, Some est_out -> + safe_close_channel ns (`In est_in) "node shutting down" (fun () -> + Format.fprintf + ns.log_formatter + "error while closing remote connection") + >>= fun _ -> + safe_close_channel ns (`Out est_out) "node shutting down" (fun () -> + Format.fprintf + ns.log_formatter + "error while closing remote connection") + | _ -> return ()) + >>= fun () -> + Node_id_hashtbl.fold + (fun _ out_ch _ -> + safe_close_channel ns (`Out out_ch) "node shutting down" (fun () -> + Format.fprintf + ns.log_formatter + "error while closing remote connection")) + ns.remote_nodes + (return ()) + >>= fun () -> + log_msg ns Info "at exit handler" (fun () -> + Format.fprintf ns.log_formatter "at exit handler finished") + + let return (v : 'a) : 'a t = fun (ns, pid) -> I.return (ns, pid, v) + + let ( >>= ) (p : 'a t) (f : 'a -> 'b t) : 'b t = + fun (ns, pid) -> I.(p (ns, pid) >>= fun (ns', pid', v) -> (f v) (ns', pid')) + + let fail (e : exn) : 'a t = fun _ -> I.fail e + + let catch (p : unit -> 'a t) (handler : exn -> 'a t) : 'a t = + fun (ns, pid) -> + I.catch (fun () -> (p ()) (ns, pid)) (fun e -> (handler e) (ns, pid)) + + let register (name : string) (f : Process_id.t -> unit -> unit t) : unit t = + fun (ns, pid) -> + Hashtbl.add ns.registered_funs name f ; + I.return (ns, pid, ()) + + let lift_io (io_comp : 'a io) : 'a t = + fun (ns, pid) -> I.(io_comp >>= fun res -> return (ns, pid, res)) + + let send_monitor_response (ns : node_state) + (monitors : Monitor_ref_set.t option) + (termination_reason : monitor_reason) : unit io = + let open I in + let send_monitor_response_local (Monitor_Ref (_, pid, _)) = + match + Potpourri.of_option @@ fun () -> + Hashtbl.find ns.mailboxes (Process_id.get_id pid) + with + | None -> return () + | Some (_, push_fn) -> + return @@ push_fn @@ Some (Exit (pid, termination_reason)) + in + + let send_monitor_response_remote + (Monitor_Ref (_, monitoring_process, monitored_process) as mref) = + catch + (fun () -> + match + Potpourri.of_option @@ fun () -> + Node_id_hashtbl.find + ns.remote_nodes + (Process_id.get_node monitoring_process) + with + | None -> + log_msg ns Info "sending remote monitor notification" (fun () -> + Format.fprintf ns.log_formatter "monitor reference " ; + print_string_of_monitor_ref mref ns.log_formatter ; + Format.fprintf ns.log_formatter " remote node " ; + Node_id.print_string_of_node + (Process_id.get_node monitoring_process) + ns.log_formatter ; + Format.fprintf + ns.log_formatter + " is down, skipping sending monitor message") + | Some out_ch -> + write_value out_ch (Exit (monitored_process, termination_reason)) + >>= fun () -> + log_msg ns Info "sending remote monitor notification" (fun () -> + Format.fprintf + ns.log_formatter + "sent monitor notification for monitor ref " ; + print_string_of_monitor_ref mref ns.log_formatter ; + Format.fprintf ns.log_formatter " to remote node " ; + Node_id.print_string_of_node + (Process_id.get_node monitoring_process) + ns.log_formatter)) + (fun e -> + log_msg + ns + ~exn:e + Error + "sending remote monitor notification" + (fun () -> + Format.fprintf ns.log_formatter "monitor reference " ; + print_string_of_monitor_ref mref ns.log_formatter ; + Format.fprintf + ns.log_formatter + ", error sending monitor message to remote node " ; + Node_id.print_string_of_node + (Process_id.get_node monitoring_process) + ns.log_formatter ; + Format.fprintf ns.log_formatter ", removing node") + >>= fun () -> + return + @@ Node_id_hashtbl.remove + ns.remote_nodes + (Process_id.get_node monitoring_process)) + in + + let iter_fn (Monitor_Ref (_, pid, _) as mref) _ = + if Process_id.is_local pid ns.local_node then + send_monitor_response_local mref >>= fun () -> + log_msg ns Debug "sent local monitor notification" (fun () -> + print_string_of_monitor_notification + mref + termination_reason + ns.log_formatter) + else + log_msg ns Debug "start sending remote monitor notification" (fun () -> + Format.fprintf ns.log_formatter "monitor reference : " ; + print_string_of_monitor_notification + mref + termination_reason + ns.log_formatter) + >>= fun () -> + send_monitor_response_remote mref >>= fun () -> + log_msg + ns + Debug + "finished sending remote monitor notification" + (fun () -> + Format.fprintf ns.log_formatter "monitor reference : " ; + print_string_of_monitor_notification + mref + termination_reason + ns.log_formatter) + in + + match monitors with + | None -> return () + | Some monitors' -> Monitor_ref_set.fold iter_fn monitors' (return ()) + + let run_process' (ns : node_state) (pid : Process_id.t) (p : unit t) : unit io + = + let open I in + catch + (fun () -> + log_msg ns Debug "starting process" (fun () -> + Process_id.print_string_of_pid pid ns.log_formatter) + >>= fun () -> + p (ns, pid) >>= fun _ -> + log_msg ns Debug "process terminated successfully" (fun () -> + Process_id.print_string_of_pid pid ns.log_formatter) + >>= fun () -> + send_monitor_response + ns + ( Potpourri.of_option @@ fun () -> + Process_id_hashtbl.find ns.monitor_table pid ) + (Normal pid) + >>= fun () -> + Process_id_hashtbl.remove ns.monitor_table pid ; + return @@ Hashtbl.remove ns.mailboxes (Process_id.get_id pid)) + (fun e -> + log_msg ns ~exn:e Error "process failed with error" (fun () -> + Process_id.print_string_of_pid pid ns.log_formatter) + >>= fun () -> + Hashtbl.remove ns.mailboxes (Process_id.get_id pid) ; + (match e with + | InvalidNode n -> + send_monitor_response + ns + ( Potpourri.of_option @@ fun () -> + Process_id_hashtbl.find ns.monitor_table pid ) + (UnkownNodeId (pid, n)) + | _ -> + send_monitor_response + ns + ( Potpourri.of_option @@ fun () -> + Process_id_hashtbl.find ns.monitor_table pid ) + (Exception (pid, e))) + >>= fun () -> return @@ Process_id_hashtbl.remove ns.monitor_table pid) + + let sync_send pid ns ?flags out_ch msg_create_fn response_fn = + let open I in + let remote_config = Potpourri.get_option !(ns.config) in + let new_pid = + Process_id.make_remote + remote_config.Remote_config.node_ip + remote_config.Remote_config.local_port + remote_config.Remote_config.node_name + ns.next_process_id + in + let new_mailbox, push_fn = I.create_stream () in + Hashtbl.replace + ns.mailboxes + (Process_id.get_id new_pid) + (new_mailbox, push_fn) ; + let msg_to_send = msg_create_fn new_pid in + log_msg ns ~pid Debug "sync send start" (fun () -> + Format.fprintf ns.log_formatter "created new process " ; + Process_id.print_string_of_pid new_pid ns.log_formatter ; + Format.fprintf ns.log_formatter " for sync send of " ; + print_string_of_message msg_to_send ns.log_formatter) + >>= fun () -> + write_value out_ch ?flags msg_to_send >>= fun () -> + get new_mailbox >>= fun result_pid -> + Hashtbl.remove ns.mailboxes (Process_id.get_id new_pid) ; + log_msg ns ~pid Debug "sync send end" (fun () -> + Format.fprintf ns.log_formatter "process " ; + Process_id.print_string_of_pid new_pid ns.log_formatter ; + Format.fprintf ns.log_formatter " finished for sync send of " ; + print_string_of_message msg_to_send ns.log_formatter) + >>= fun () -> response_fn (Potpourri.get_option result_pid) + (* we do not send None on mailboxes *) + + let monitor_helper (ns : node_state) (monitor_pid : Process_id.t) + (monitee_pid : Process_id.t) : message option * monitor_ref = + let new_monitor_ref = + Monitor_Ref + (Potpourri.post_incr ns.monitor_ref_id, monitor_pid, monitee_pid) + in + match + Potpourri.of_option @@ fun () -> + Hashtbl.find ns.mailboxes (Process_id.get_id monitee_pid) + with + | None -> (Some (Exit (monitee_pid, NoProcess monitee_pid)), new_monitor_ref) + | Some _ -> + (match + Potpourri.of_option @@ fun () -> + Process_id_hashtbl.find ns.monitor_table monitee_pid + with + | None -> + Process_id_hashtbl.add + ns.monitor_table + monitee_pid + (Monitor_ref_set.of_list [new_monitor_ref]) + | Some curr_monitor_set -> + Process_id_hashtbl.replace + ns.monitor_table + monitee_pid + (Monitor_ref_set.add new_monitor_ref curr_monitor_set)) ; + (None, new_monitor_ref) + + let monitor_response_handler (ns : node_state) + (res : message option * monitor_ref) : monitor_ref = + match res with + | Some msg, (Monitor_Ref (_, monitor_pid, _) as mref) -> + let _, push_fn = + Hashtbl.find ns.mailboxes (Process_id.get_id monitor_pid) + in + (* process is currently running so mailbox must be present *) + push_fn @@ Some msg ; + mref + | None, (Monitor_Ref (_, _, monitee_pid) as mref) -> + (match + Potpourri.of_option @@ fun () -> + Process_id_hashtbl.find ns.monitor_table monitee_pid + with + | None -> + Process_id_hashtbl.add + ns.monitor_table + monitee_pid + (Monitor_ref_set.of_list [mref]) + | Some curr_monitor_set -> + Process_id_hashtbl.replace + ns.monitor_table + monitee_pid + (Monitor_ref_set.add mref curr_monitor_set)) ; + mref + + let monitor_local (ns : node_state) (monitor_pid : Process_id.t) + (monitee_pid : Process_id.t) : monitor_ref = + monitor_response_handler ns @@ monitor_helper ns monitor_pid monitee_pid + + let make_new_pid (node_to_spwan_on : Node_id.t) (ns : node_state) : + Process_id.t = + if !(ns.config) = None then + Process_id.make_local + (Node_id.get_name node_to_spwan_on) + ns.next_process_id + else + let remote_config = Potpourri.get_option !(ns.config) in + Process_id.make_remote + remote_config.Remote_config.node_ip + remote_config.Remote_config.local_port + remote_config.Remote_config.node_name + ns.next_process_id + + let spawn ?(monitor = false) (node_id : Node_id.t) (p : proc_rep) + (pid_to_send : Process_id.t) : (Process_id.t * monitor_ref option) t = + let open I in + fun (ns, pid) -> + let proc = p in + let p = + match p with + | Fun p -> fun _ -> p + | Registered n -> Hashtbl.find ns.registered_funs n + in + if Node_id.is_local node_id ns.local_node then ( + let new_pid = make_new_pid node_id ns in + Hashtbl.replace + ns.mailboxes + (Process_id.get_id new_pid) + (I.create_stream ()) ; + if monitor then ( + let monitor_res = monitor_local ns pid new_pid in + async (fun () -> run_process' ns new_pid (p pid ())) ; + log_msg + ~pid:(Process_id.get_id pid) + ns + Debug + "spawned and monitored local process" + (fun () -> + Format.fprintf ns.log_formatter "result pid " ; + Process_id.print_string_of_pid new_pid ns.log_formatter ; + Format.fprintf ns.log_formatter ", result monitor reference : " ; + print_string_of_monitor_ref monitor_res ns.log_formatter) + >>= fun () -> return (ns, pid, (new_pid, Some monitor_res))) + else ( + async (fun () -> run_process' ns new_pid (p pid ())) ; + log_msg + ~pid:(Process_id.get_id pid) + ns + Debug + "spawned local process" + (fun () -> + Format.fprintf ns.log_formatter "result pid " ; + Process_id.print_string_of_pid new_pid ns.log_formatter) + >>= fun () -> return (ns, pid, (new_pid, None)))) + else + match + Potpourri.of_option @@ fun () -> + Node_id_hashtbl.find ns.remote_nodes node_id + with + | Some out_ch -> + if monitor then + log_msg + ~pid:(Process_id.get_id pid) + ns + Debug + "spawning and monitoring remote process" + (fun () -> + Format.fprintf ns.log_formatter "on remote node " ; + Node_id.print_string_of_node node_id ns.log_formatter ; + Format.fprintf ns.log_formatter ", local process " ; + Process_id.print_string_of_pid pid ns.log_formatter) + >>= fun () -> + sync_send + (Process_id.get_id pid) + ns + ~flags:[Marshal.Closures] + out_ch + (fun receiver_pid -> + Spawn_monitor (proc, pid, receiver_pid, pid_to_send)) + (fun res -> + let (Monitor_Ref (_, _, monitored_proc) as mref) = + match res with + | Spawn_monitor_result (_, mr, _) -> mr + | _ -> assert false + in + (*BISECT-IGNORE*) + log_msg + ~pid:(Process_id.get_id pid) + ns + Debug + "spawned and monitored remote process" + (fun () -> + Format.fprintf ns.log_formatter "spawned on remote node " ; + Node_id.print_string_of_node node_id ns.log_formatter ; + Format.fprintf ns.log_formatter " : result pid " ; + Process_id.print_string_of_pid + monitored_proc + ns.log_formatter ; + Format.fprintf + ns.log_formatter + ", result monitor reference : " ; + print_string_of_monitor_ref mref ns.log_formatter) + >>= fun () -> return (ns, pid, (monitored_proc, Some mref))) + else + log_msg + ~pid:(Process_id.get_id pid) + ns + Debug + "spawning remote process" + (fun () -> + Format.fprintf ns.log_formatter "on remote node " ; + Node_id.print_string_of_node node_id ns.log_formatter ; + Format.fprintf ns.log_formatter ", local process " ; + Process_id.print_string_of_pid pid ns.log_formatter) + >>= fun () -> + sync_send + (Process_id.get_id pid) + ns + ~flags:[Marshal.Closures] + out_ch + (fun receiver_pid -> Proc (proc, receiver_pid, pid_to_send)) + (fun res -> + let remote_proc_pid = + match res with Proc_result (r, _) -> r | _ -> assert false + in + (*BISECT-IGNORE*) + log_msg + ~pid:(Process_id.get_id pid) + ns + Debug + "spawned remote process" + (fun () -> + Format.fprintf ns.log_formatter "on remote node " ; + Node_id.print_string_of_node node_id ns.log_formatter ; + Format.fprintf ns.log_formatter " : result pid " ; + Process_id.print_string_of_pid + remote_proc_pid + ns.log_formatter) + >>= fun () -> return (ns, pid, (remote_proc_pid, None))) + | None -> + log_msg + ~pid:(Process_id.get_id pid) + ns + Error + "failed to spawn process on remote node" + (fun () -> + Format.fprintf ns.log_formatter "remote node " ; + Node_id.print_string_of_node node_id ns.log_formatter ; + Format.fprintf ns.log_formatter ", is unknown, local process " ; + Process_id.print_string_of_pid pid ns.log_formatter) + >>= fun () -> fail @@ InvalidNode node_id + + let case (match_fn : message_type -> (unit -> 'a t) option) : 'a matcher_list + = + let matcher = function Data (_, _, msg) -> match_fn msg | _ -> None in + Matcher matcher + + let termination_case (handler_fn : monitor_reason -> 'a t) : 'a matcher_list = + let matcher = function + | Exit (_, reason) -> Some (fun () -> handler_fn reason) + | _ -> None + in + Matcher matcher + + let rec ( |. ) (first_matchers : 'a matcher_list) + (second_matchers : 'a matcher_list) : 'a matcher_list = + match (first_matchers, second_matchers) with + | Matcher matcher, Matcher matcher' -> Matchers (matcher, Matcher matcher') + | Matcher matcher, Matchers (matcher', matchers) -> + Matchers (matcher, Matchers (matcher', matchers)) + | Matchers (matcher, matchers), matchers' -> + Matchers (matcher, matchers |. matchers') + + let receive ?timeout_duration (matchers : 'a matcher_list) : 'a option t = + let open I in + let temp_stream, temp_push_fn = create_stream () in + let result = ref None in + let mailbox_cleaned_up = ref false in + + let restore_mailbox ns pid = + mailbox_cleaned_up := true ; + let mailbox', old_push_fn = + Hashtbl.find ns.mailboxes (Process_id.get_id pid) + in + temp_push_fn None ; + (* close new stream so we can append new and old *) + Hashtbl.replace + ns.mailboxes + (Process_id.get_id pid) + (stream_append temp_stream mailbox', old_push_fn) + in + + let test_match ns pid matcher candidate_msg no_match_fn = + match matcher candidate_msg with + | None -> no_match_fn () + | Some fn -> + restore_mailbox ns pid ; + result := Some (fn ()) ; + true + in + + let rec iter_fn ns pid match_fns candidate_msg = + match match_fns with + | Matcher matcher -> + test_match ns pid matcher candidate_msg (fun () -> + temp_push_fn (Some candidate_msg) ; + false) + | Matchers (matcher, xs) -> + test_match ns pid matcher candidate_msg (fun () -> + iter_fn ns pid xs candidate_msg) + in + + let rec iter_stream iter_fn stream = + get stream >>= fun v -> + if iter_fn (Potpourri.get_option v) then return () + else iter_stream iter_fn stream + in + + (* a None is never sent, see send function below. *) + let do_receive_blocking (ns, pid) = + let mailbox, _ = Hashtbl.find ns.mailboxes (Process_id.get_id pid) in + iter_stream (iter_fn ns pid matchers) mailbox >>= fun () -> + (Potpourri.get_option !result) (ns, pid) >>= fun (ns', pid', result') -> + return (ns', pid', Some result') + in + + fun (ns, pid) -> + match timeout_duration with + | None -> + catch + (fun () -> + log_msg + ~pid:(Process_id.get_id pid) + ns + Debug + "receiving with no time out" + (fun () -> + Format.fprintf ns.log_formatter "receiver process " ; + Process_id.print_string_of_pid pid ns.log_formatter) + >>= fun () -> + do_receive_blocking (ns, pid) >>= fun (ns', pid', res) -> + log_msg + ~pid:(Process_id.get_id pid) + ns + Debug + "successfully received and processed message with no time out" + (fun () -> + Format.fprintf ns.log_formatter "receiver process " ; + Process_id.print_string_of_pid pid ns.log_formatter) + >>= fun () -> return (ns', pid', res)) + (fun e -> + if not !mailbox_cleaned_up then restore_mailbox ns pid else () ; + log_msg + ~pid:(Process_id.get_id pid) + ns + ~exn:e + Error + "receiving with no time out failed" + (fun () -> + Format.fprintf ns.log_formatter "receiver process " ; + Process_id.print_string_of_pid pid ns.log_formatter ; + Format.fprintf ns.log_formatter ", encountred exception") + >>= fun () -> fail e) + | Some timeout_duration' -> + log_msg + ~pid:(Process_id.get_id pid) + ns + Debug + "receiving with time out" + (fun () -> + Format.fprintf ns.log_formatter "receiver process " ; + Process_id.print_string_of_pid pid ns.log_formatter ; + Format.fprintf ns.log_formatter ", time out %f" timeout_duration') + >>= fun () -> + catch + (fun () -> + pick [do_receive_blocking (ns, pid); timeout timeout_duration'] + >>= fun (ns', pid', res) -> + log_msg + ns + ~pid:(Process_id.get_id pid) + Debug + "successfully received and processed a message with time out" + (fun () -> + Format.fprintf ns.log_formatter "receiver process " ; + Process_id.print_string_of_pid pid ns.log_formatter ; + Format.fprintf + ns.log_formatter + ", time out %f" + timeout_duration') + >>= fun () -> return (ns', pid', res)) + (fun e -> + if not !mailbox_cleaned_up then restore_mailbox ns pid else () ; + match e with + | Timeout -> + log_msg + ~pid:(Process_id.get_id pid) + ns + Debug + "receive timed out" + (fun () -> + Format.fprintf ns.log_formatter "receiver process " ; + Process_id.print_string_of_pid pid ns.log_formatter ; + Format.fprintf + ns.log_formatter + ", time out %f" + timeout_duration') + >>= fun () -> return (ns, pid, None) + | e -> + log_msg + ~pid:(Process_id.get_id pid) + ns + ~exn:e + Error + "receiving with time out failed" + (fun () -> + Format.fprintf ns.log_formatter "receiver process " ; + Process_id.print_string_of_pid pid ns.log_formatter ; + Format.fprintf + ns.log_formatter + ", time out %f" + timeout_duration') + >>= fun () -> fail e) + + let rec receive_loop ?timeout_duration (matchers : bool matcher_list) : unit t + = + let open I in + fun (ns, pid) -> + (receive ?timeout_duration matchers) (ns, pid) >>= fun (ns', pid', res) -> + match res with + | None | Some false -> return (ns', pid', ()) + | Some true -> (receive_loop ?timeout_duration matchers) (ns', pid') + + let send_to_remote_node_helper (pid : int) (ns : node_state) + (node : Node_id.t) (sending_log_action : string) + (print_sending_log_msg : unit -> unit) + (print_unknown_node_msg : unit -> unit) (msg : message) : unit I.t = + let open I in + match + Potpourri.of_option @@ fun () -> Node_id_hashtbl.find ns.remote_nodes node + with + | Some remote_output -> + log_msg ns ~pid Debug sending_log_action (fun () -> + print_sending_log_msg ()) + >>= fun () -> + write_value + ~flags:[Marshal.Closures] + remote_output + msg (* marshal because the message could be a function *) + | None -> + log_msg ns ~pid Error sending_log_action (fun () -> + print_unknown_node_msg ()) + >>= fun () -> fail @@ InvalidNode node + + let send (remote_pid : Process_id.t) (msg : message_type) : unit t = + let open I in + fun (ns, pid) -> + if Process_id.is_local remote_pid ns.local_node then + match + Potpourri.of_option @@ fun () -> + Hashtbl.find ns.mailboxes (Process_id.get_id remote_pid) + with + | None -> + log_msg + ns + ~pid:(Process_id.get_id pid) + I.Warning + "unable to send message to local process" + (fun () -> + Format.fprintf + ns.log_formatter + "message : %s, to unknown local process: " + (M.string_of_message msg) ; + Process_id.print_string_of_pid remote_pid ns.log_formatter ; + Format.fprintf ns.log_formatter ", from local process: " ; + Process_id.print_string_of_pid pid ns.log_formatter) + >>= fun () -> return (ns, pid, ()) + | Some (_, push_fn) -> + log_msg + ns + ~pid:(Process_id.get_id pid) + I.Debug + "successfully sent message to local process" + (fun () -> + Format.fprintf + ns.log_formatter + "message : %s, to local process: " + (M.string_of_message msg) ; + Process_id.print_string_of_pid remote_pid ns.log_formatter ; + Format.fprintf ns.log_formatter ", from local process: " ; + Process_id.print_string_of_pid pid ns.log_formatter) + >>= fun () -> + return @@ (ns, pid, push_fn @@ Some (Data (pid, remote_pid, msg))) + else + let sending_msg () = + Format.fprintf + ns.log_formatter + "message : %s, to remote process: " + (M.string_of_message msg) ; + Process_id.print_string_of_pid remote_pid ns.log_formatter ; + Format.fprintf ns.log_formatter ", from local process: " ; + Process_id.print_string_of_pid pid ns.log_formatter + in + let unknown_node_msg () = + Format.fprintf + ns.log_formatter + "message : %s, to unknown remote process: " + (M.string_of_message msg) ; + Process_id.print_string_of_pid remote_pid ns.log_formatter ; + Format.fprintf ns.log_formatter ", from local process: " ; + Process_id.print_string_of_pid pid ns.log_formatter + in + send_to_remote_node_helper + (Process_id.get_id pid) + ns + (Process_id.get_node remote_pid) + "sending message to remote process" + sending_msg + unknown_node_msg + (Data (pid, remote_pid, msg)) + >>= fun () -> + log_msg + ns + ~pid:(Process_id.get_id pid) + I.Debug + "successfully sent message to remote process" + (fun () -> + Format.fprintf + ns.log_formatter + "message : %s, to remote process: " + (M.string_of_message msg) ; + Process_id.print_string_of_pid remote_pid ns.log_formatter ; + Format.fprintf ns.log_formatter ", from local process: " ; + Process_id.print_string_of_pid pid ns.log_formatter) + >>= fun () -> return (ns, pid, ()) + + let ( >! ) (pid : Process_id.t) (msg : message_type) : unit t = send pid msg + + let broadcast_local ?pid (ns : node_state) (sending_pid : Process_id.t) + (m : message_type) : unit io = + let open I in + Hashtbl.fold + (fun recev_pid (_, push_fn) _ -> + let recev_pid' = Process_id.make ns.local_node recev_pid in + if recev_pid' = sending_pid then return () + else + log_msg ?pid ns I.Debug "broadcast" (fun () -> + Format.fprintf + ns.log_formatter + "sending message %s to local process " + (M.string_of_message m) ; + Process_id.print_string_of_pid recev_pid' ns.log_formatter ; + Format.fprintf ns.log_formatter " from process " ; + Process_id.print_string_of_pid sending_pid ns.log_formatter ; + Format.fprintf ns.log_formatter " as result of broadcast request") + >>= fun () -> + return @@ push_fn @@ Some (Data (sending_pid, recev_pid', m))) + ns.mailboxes + (return ()) + + let broadcast (node : Node_id.t) (m : message_type) : unit t = + let open I in + fun (ns, pid) -> + if Node_id.is_local node ns.local_node then + log_msg ~pid:(Process_id.get_id pid) ns I.Debug "broadcast" (fun () -> + Format.fprintf + ns.log_formatter + "sending broadcast message %s to local processes running on \ + local node " + (M.string_of_message m) ; + Node_id.print_string_of_node node ns.log_formatter ; + Format.fprintf ns.log_formatter " from local process " ; + Process_id.print_string_of_pid pid ns.log_formatter) + >>= fun () -> + broadcast_local ns pid m >>= fun () -> return (ns, pid, ()) + else + let sending_msg () = + Format.fprintf ns.log_formatter "Process " ; + Process_id.print_string_of_pid pid ns.log_formatter ; + Format.fprintf + ns.log_formatter + " is sending broadcast message %s to remote node " + (M.string_of_message m) ; + Node_id.print_string_of_node node ns.log_formatter + in + let unknwon_node_msg () = + Format.fprintf ns.log_formatter "Process " ; + Process_id.print_string_of_pid pid ns.log_formatter ; + Format.fprintf + ns.log_formatter + " failed to send broadcast message %s to remote node " + (M.string_of_message m) ; + Node_id.print_string_of_node node ns.log_formatter ; + Format.fprintf ns.log_formatter ", remote node is unknown" + in + send_to_remote_node_helper + (Process_id.get_id pid) + ns + node + "broadcasting to remote node" + sending_msg + unknwon_node_msg + (Broadcast (pid, node, m)) + >>= fun () -> + log_msg + ns + ~pid:(Process_id.get_id pid) + I.Debug + "successfully sent broadcast message to remote node" + (fun () -> + Format.fprintf + ns.log_formatter + "message : %s, to remote node: " + (M.string_of_message m) ; + Node_id.print_string_of_node node ns.log_formatter) + >>= fun () -> return (ns, pid, ()) + + let lookup_node_and_send (pid : int) (ns : node_state) + (receiver_process : Process_id.t) (action : string) + (unknown_node_msg : unit -> unit) + (node_found_fn : I.output_channel -> 'a I.t) : 'a I.t = + let open I in + match + Potpourri.of_option @@ fun () -> + Node_id_hashtbl.find + ns.remote_nodes + (Process_id.get_node @@ receiver_process) + with + | None -> + log_msg ~pid ns Error action (fun () -> unknown_node_msg ()) + >>= fun () -> fail @@ InvalidNode (Process_id.get_node receiver_process) + | Some out_ch -> node_found_fn out_ch + + let monitor (pid_to_monitor : Process_id.t) : monitor_ref t = + fun (ns, pid) -> + let open I in + if Process_id.is_local pid_to_monitor ns.local_node then + log_msg ~pid:(Process_id.get_id pid) ns Debug "monitored" (fun () -> + Format.fprintf ns.log_formatter "Creating monitor for local process " ; + Process_id.print_string_of_pid pid_to_monitor ns.log_formatter ; + Format.fprintf ns.log_formatter " to be monitored by local process " ; + Process_id.print_string_of_pid pid ns.log_formatter) + >>= fun () -> return (ns, pid, monitor_local ns pid pid_to_monitor) + else + log_msg ~pid:(Process_id.get_id pid) ns Debug "monitoring" (fun () -> + Format.fprintf ns.log_formatter "Creating monitor for remote process " ; + Process_id.print_string_of_pid pid_to_monitor ns.log_formatter ; + Format.fprintf ns.log_formatter " to be monitored by local process " ; + Process_id.print_string_of_pid pid ns.log_formatter) + >>= fun () -> + let unknown_mode_msg () = + Format.fprintf ns.log_formatter "Process " ; + Process_id.print_string_of_pid pid ns.log_formatter ; + Format.fprintf ns.log_formatter " failed to monitor remote process " ; + Process_id.print_string_of_pid pid_to_monitor ns.log_formatter ; + Format.fprintf ns.log_formatter " on remote node " ; + Node_id.print_string_of_node + (Process_id.get_node pid_to_monitor) + ns.log_formatter ; + Format.fprintf ns.log_formatter ", remote node is unknown" + in + let node_found_fn out_ch = + sync_send + (Process_id.get_id pid) + ns + out_ch + (fun receiver_pid -> Monitor (pid, pid_to_monitor, receiver_pid)) + (fun res -> + let res' = + match res with + | Monitor_result (mon_msg, mon_res, _) -> (mon_msg, mon_res) + | _ -> assert false + in + (*BISECT-IGNORE*) + log_msg + ~pid:(Process_id.get_id pid) + ns + I.Debug + "successfully monitored remote process" + (fun () -> + Format.fprintf ns.log_formatter "result: " ; + print_string_of_message res ns.log_formatter) + >>= fun () -> return (ns, pid, monitor_response_handler ns res')) + in + lookup_node_and_send + (Process_id.get_id pid) + ns + pid_to_monitor + "monitoring" + unknown_mode_msg + node_found_fn + + let unmonitor_local (ns : node_state) + (Monitor_Ref (_, _, process_to_unmonitor) as mref) : unit = + match + Potpourri.of_option @@ fun () -> + Process_id_hashtbl.find ns.monitor_table process_to_unmonitor + with + | None -> () + | Some curr_set -> + let curr_set' = Monitor_ref_set.remove mref curr_set in + if Monitor_ref_set.is_empty curr_set' then + Process_id_hashtbl.remove ns.monitor_table process_to_unmonitor + else + Process_id_hashtbl.replace + ns.monitor_table + process_to_unmonitor + curr_set' + + let unmonitor (Monitor_Ref (_, _, process_to_unmonitor) as mref) : unit t = + let open I in + fun (ns, pid) -> + if Process_id.is_local process_to_unmonitor ns.local_node then + log_msg ns ~pid:(Process_id.get_id pid) Debug "unmonitored" (fun () -> + Format.fprintf ns.log_formatter "Unmonitor local : " ; + print_string_of_monitor_ref mref ns.log_formatter) + >>= fun () -> return (ns, pid, unmonitor_local ns mref) + else + log_msg ns ~pid:(Process_id.get_id pid) Debug "unmonitoring" (fun () -> + Format.fprintf ns.log_formatter "Unmonitor remote : " ; + print_string_of_monitor_ref mref ns.log_formatter) + >>= fun () -> + let unknown_node_msg () = + Format.fprintf ns.log_formatter "Process " ; + Process_id.print_string_of_pid pid ns.log_formatter ; + Format.fprintf ns.log_formatter " failed to monitor remote process " ; + Process_id.print_string_of_pid process_to_unmonitor ns.log_formatter ; + Format.fprintf ns.log_formatter " on remote node " ; + Node_id.print_string_of_node + (Process_id.get_node process_to_unmonitor) + ns.log_formatter ; + Format.fprintf ns.log_formatter ", remote node is unknown" + in + let node_found_fn out_ch = + sync_send + (Process_id.get_id pid) + ns + out_ch + (fun recv_pid -> Unmonitor (mref, recv_pid)) + (fun _ -> + log_msg + ~pid:(Process_id.get_id pid) + ns + Debug + "successfully unmonitored" + (fun () -> + Format.fprintf ns.log_formatter "monitor ref : " ; + print_string_of_monitor_ref mref ns.log_formatter) + >>= fun () -> return (ns, pid, ())) + in + lookup_node_and_send + (Process_id.get_id pid) + ns + process_to_unmonitor + "unmonitoring" + unknown_node_msg + node_found_fn + + let get_self_pid : Process_id.t t = + fun (ns, proc_id) -> I.return (ns, proc_id, proc_id) + + let get_self_node : Node_id.t t = + fun (ns, pid) -> I.return (ns, pid, Process_id.get_node pid) + + let get_remote_node node_name (ns, pid) = + let res : Node_id.t option ref = ref None in + let iter_fn node _ = + if Node_id.get_name node = node_name && !res = None then res := Some node + else () + in + Node_id_hashtbl.iter iter_fn ns.remote_nodes ; + I.return (ns, pid, !res) + + let get_remote_nodes : Node_id.t list t = + fun (ns, pid) -> + let res : Node_id.t list = + Node_id_hashtbl.fold (fun n _ acc -> n :: acc) ns.remote_nodes [] + in + I.return (ns, pid, res) + + let clean_up_node_connection ns node in_ch out_ch = + let open I in + let out_details () = + if node <> None then ( + Format.fprintf + ns.log_formatter + "encountered error while closing output channel for remote node " ; + Node_id.print_string_of_node + (Potpourri.get_option node) + ns.log_formatter) + else + Format.fprintf + ns.log_formatter + "encountered error while closing output channel" + in + let in_details () = + if node <> None then ( + Format.fprintf + ns.log_formatter + "encountered error while closing input channel for remote node " ; + Node_id.print_string_of_node + (Potpourri.get_option node) + ns.log_formatter) + else + Format.fprintf + ns.log_formatter + "encountered error while closing input channel" + in + safe_close_channel ns (`In in_ch) "node connection clean up" out_details + >>= fun () -> + safe_close_channel ns (`Out out_ch) "node connection clean up" in_details + >>= fun () -> + if node = None then return () + else + return + @@ Node_id_hashtbl.remove ns.remote_nodes (Potpourri.get_option node) + + let rec wait_for_node_msg ns in_ch out_ch client_addr node_ref = + let open I in + let print_string_of_client_addr () = + match client_addr with + | Unix.ADDR_UNIX s -> Format.fprintf ns.log_formatter "%s" s + | Unix.ADDR_INET (ip, port) -> + Format.fprintf + ns.log_formatter + "%s:%d" + (Unix.string_of_inet_addr ip) + port + in + + read_value in_ch >>= fun (msg : message) -> + log_msg ns Debug "node process message" (fun () -> + Format.fprintf ns.log_formatter "received message " ; + print_string_of_message msg ns.log_formatter ; + Format.fprintf ns.log_formatter " from " ; + print_string_of_client_addr ()) + >>= fun () -> + match msg with + | Node node -> + node_ref := Some node ; + Node_id_hashtbl.replace ns.remote_nodes node out_ch ; + return node + | _ -> + log_msg ns Debug "node process message" (fun () -> + Format.fprintf ns.log_formatter "ignore message " ; + print_string_of_message msg ns.log_formatter ; + Format.fprintf ns.log_formatter ", waiting for handshake") + >>= fun () -> wait_for_node_msg ns in_ch out_ch client_addr node_ref + + let server_handler (ns : node_state) + ((in_ch, out_ch) : I.input_channel * I.output_channel) (node : Node_id.t) + : unit I.t = + let open I in + let remote_config = Potpourri.get_option !(ns.config) in + + let spawn_preamble () = + let new_pid = + Process_id.make_remote + remote_config.Remote_config.node_ip + remote_config.Remote_config.local_port + remote_config.Remote_config.node_name + ns.next_process_id + in + Hashtbl.replace + ns.mailboxes + (Process_id.get_id new_pid) + (I.create_stream ()) ; + new_pid + in + + let put_in_mailbox receiver_pid msg = + match + Potpourri.of_option @@ fun () -> + Hashtbl.find ns.mailboxes (Process_id.get_id receiver_pid) + with + | None -> + let receiver_not_found_err_msg () = + Format.fprintf ns.log_formatter "remote node " ; + Node_id.print_string_of_node node ns.log_formatter ; + Format.fprintf ns.log_formatter ", processed message " ; + print_string_of_message msg ns.log_formatter ; + Format.fprintf ns.log_formatter ", recipient unknown local process " ; + Process_id.print_string_of_pid receiver_pid ns.log_formatter + in + log_msg ns I.Warning "node process message" receiver_not_found_err_msg + | Some (_, push_fn) -> return @@ push_fn (Some msg) + in + + let rec handler () = + let log_handler_stop msg = + let node_str () = Node_id.print_string_of_node node ns.log_formatter in + log_msg ns Error "node process message" (fun () -> + Format.fprintf ns.log_formatter "remote node " ; + node_str () ; + Format.fprintf + ns.log_formatter + " %s, stopping handler for remote node " + msg ; + node_str ()) + in + if + ( Potpourri.of_option @@ fun () -> + Node_id_hashtbl.find ns.remote_nodes node ) + = None + then log_handler_stop "has been previously removed" + else + read_value in_ch >>= fun (msg : message) -> + log_msg ns Debug "node process message" (fun () -> + Format.fprintf ns.log_formatter "remote node " ; + Node_id.print_string_of_node node ns.log_formatter ; + Format.fprintf ns.log_formatter ", message " ; + print_string_of_message msg ns.log_formatter) + >>= fun () -> + match msg with + | Node _ -> handler () + | Proc (p, sender_pid, pid_to_send) -> + let result_pid = spawn_preamble () in + write_value out_ch (Proc_result (result_pid, sender_pid)) + >>= fun () -> + let p = + match p with + | Fun p -> fun _ -> p + | Registered n -> Hashtbl.find ns.registered_funs n + in + async (fun () -> run_process' ns result_pid (p pid_to_send ())) ; + handler () + | Spawn_monitor (p, monitor_pid, sender, pid_to_send) -> + let new_pid = spawn_preamble () in + let monitor_msg, monitor_res = + monitor_helper ns monitor_pid new_pid + in + write_value + out_ch + (Spawn_monitor_result (monitor_msg, monitor_res, sender)) + >>= fun () -> + let p = + match p with + | Fun p -> fun _ -> p + | Registered n -> Hashtbl.find ns.registered_funs n + in + async (fun () -> run_process' ns new_pid (p pid_to_send ())) ; + handler () + | Monitor (monitor_pid, to_be_monitored, sender) -> + let mon_msg, mon_res = + monitor_helper ns monitor_pid to_be_monitored + in + write_value out_ch (Monitor_result (mon_msg, mon_res, sender)) + >>= fun () -> handler () + | Unmonitor (mref, sender) -> + unmonitor_local ns mref ; + write_value out_ch (Unmonitor_result (mref, sender)) >>= fun () -> + handler () + | Broadcast (sender_pid, _, msg) -> + broadcast_local ns sender_pid msg >>= fun () -> handler () + | Data (_, r, _) as data -> + put_in_mailbox r data >>= fun () -> handler () + | Exit (s, m) -> ( + match + Potpourri.of_option @@ fun () -> + Process_id_hashtbl.find ns.monitor_table s + with + | None -> + log_msg ns Error "node process message" (fun () -> + Format.fprintf ns.log_formatter "no entry for " ; + Process_id.print_string_of_pid s ns.log_formatter ; + Format.fprintf + ns.log_formatter + " in monitor table when processing " ; + print_string_of_message msg ns.log_formatter) + >>= fun () -> handler () + | Some pids -> + Monitor_ref_set.fold + (fun (Monitor_Ref (_, pid, _)) _ -> + put_in_mailbox pid (Exit (s, m))) + pids + (return ()) + >>= fun () -> handler ()) + | Proc_result (_, receiver_pid) as pres -> + put_in_mailbox receiver_pid pres >>= fun () -> handler () + | Spawn_monitor_result (monitor_msg, mref, receiver) as sres -> + ignore (monitor_response_handler ns (monitor_msg, mref)) ; + put_in_mailbox receiver sres >>= fun () -> handler () + | Monitor_result (mon_msg, mref, receiver) as mres -> + ignore (monitor_response_handler ns (mon_msg, mref)) ; + put_in_mailbox receiver mres >>= fun () -> handler () + | Unmonitor_result (mref, receiver_pid) as unmonres -> + unmonitor_local ns mref ; + put_in_mailbox receiver_pid unmonres >>= fun () -> handler () + in + handler () + + let node_server_fn (ns : node_state) (client_addr : Unix.sockaddr) + ((in_ch, out_ch) : I.input_channel * I.output_channel) : unit I.t = + let open I in + let node_ref = ref None in + catch + (fun () -> + ns.est_in_ch := Some in_ch ; + ns.est_out_ch := Some out_ch ; + wait_for_node_msg ns in_ch out_ch client_addr node_ref >>= fun node -> + write_value out_ch @@ Node ns.local_node >>= fun () -> + log_msg ns Debug "node server loop" (fun () -> + Format.fprintf ns.log_formatter "starting server handler") + >>= fun _ -> server_handler ns (in_ch, out_ch) node) + (fun e -> + log_msg ns ~exn:e Error "node process message" (fun () -> + Format.fprintf ns.log_formatter "unexpected exception") + >>= fun () -> clean_up_node_connection ns !node_ref in_ch out_ch) + + let connect_to_remote_node ?pid (ns : node_state) (remote_node : Node_id.t) + (ip : string) (port : int) (name : string) + (remote_sock_addr : Unix.sockaddr) : unit I.t = + let open I in + let node_ref = ref None in + let server_handler_safe server_fn (in_ch, out_ch) = + catch + (fun () -> server_fn ns (in_ch, out_ch) remote_node) + (fun e -> + clean_up_node_connection ns (Some remote_node) in_ch out_ch + >>= fun () -> + log_msg ns ~exn:e Error "node client loop" @@ fun () -> + Format.fprintf + ns.log_formatter + "unexpected exception while processing messages for remote node " ; + Node_id.print_string_of_node remote_node ns.log_formatter) + in + log_msg ns ?pid Debug "connecting to remote node" (fun () -> + Format.fprintf + ns.log_formatter + "remote node %s:%d, name %s" + ip + port + name) + >>= fun () -> + open_connection remote_sock_addr >>= fun (in_ch, out_ch) -> + write_value out_ch @@ Node ns.local_node >>= fun () -> + log_msg ns ?pid Debug "connecting to remote node" (fun () -> + Format.fprintf ns.log_formatter "sent message " ; + print_string_of_message (Node ns.local_node) ns.log_formatter ; + Format.fprintf + ns.log_formatter + " remote node %s:%d, name %s" + ip + port + name) + >>= fun () -> + wait_for_node_msg ns in_ch out_ch remote_sock_addr node_ref >>= fun _ -> + log_msg ns Debug "connected to remote node" (fun () -> + Format.fprintf + ns.log_formatter + "remote node %s:%d, name %s" + ip + port + name) + >>= fun () -> + return + @@ async (fun () -> server_handler_safe server_handler (in_ch, out_ch)) + + let add_remote_node (ip : string) (port : int) (name : string) : Node_id.t t = + let open I in + fun (ns, pid) -> + if !(ns.config) = None then + log_msg + ~pid:(Process_id.get_id pid) + ns + Error + "add remote node" + (fun () -> + Format.fprintf + ns.log_formatter + "called add remote node when node is running with local only \ + configuration") + >>= fun () -> fail Local_only_mode + else + log_msg + ~pid:(Process_id.get_id pid) + ns + Debug + "adding remote node" + (fun () -> + Format.fprintf ns.log_formatter "%s:%d, name %s" ip port name) + >>= fun () -> + let remote_sock_addr = + Unix.ADDR_INET (Unix.inet_addr_of_string ip, port) + in + let remote_node = Node_id.make_remote_node ip port name in + if Node_id_hashtbl.mem ns.remote_nodes remote_node then + log_msg + ~pid:(Process_id.get_id pid) + ns + Warning + "remote node already exists" + (fun () -> + Format.fprintf ns.log_formatter "%s:%d, name %s" ip port name) + >>= fun () -> return (ns, pid, remote_node) + else + connect_to_remote_node ns remote_node ip port name remote_sock_addr + >>= fun () -> return (ns, pid, remote_node) + + let remove_remote_node (node : Node_id.t) : unit t = + let open I in + fun (ns, pid) -> + if !(ns.config) = None then + log_msg + ~pid:(Process_id.get_id pid) + ns + Error + "remote remote node" + (fun () -> + Format.fprintf + ns.log_formatter + "called remove remote node when node is running with local only \ + configuration") + >>= fun () -> fail Local_only_mode + else + log_msg + ~pid:(Process_id.get_id pid) + ns + Debug + "removing remote node" + (fun () -> + Format.fprintf ns.log_formatter "remote node : " ; + Node_id.print_string_of_node node ns.log_formatter) + >>= fun () -> + Node_id_hashtbl.remove ns.remote_nodes node ; + return (ns, pid, ()) + + let rec connect_to_remote_nodes (ns : node_state) + (nodes : (string * int * string) list) : unit io = + let open I in + match nodes with + | [] -> return () + | (ip, port, name) :: rest -> + let remote_sock_addr = + Unix.ADDR_INET (Unix.inet_addr_of_string ip, port) + in + let remote_node = Node_id.make_remote_node ip port name in + connect_to_remote_node ns remote_node ip port name remote_sock_addr + >>= fun () -> connect_to_remote_nodes ns rest + + let run_node ?process (node_config : node_config) : unit io = + let open I in + if !initalised then fail Init_more_than_once + else ( + initalised := true ; + let buff = Buffer.create 1024 in + match node_config with + | Local local_config -> + let ns = + { + mailboxes = Hashtbl.create 1000; + remote_nodes = Node_id_hashtbl.create ~random:true 10; + monitor_table = Process_id_hashtbl.create ~random:true 1000; + local_node = + Node_id.make_local_node local_config.Local_config.node_name; + monitor_ref_id = ref 0; + config = ref None; + log_buffer = buff; + log_formatter = Format.formatter_of_buffer buff; + est_in_ch = ref None; + est_out_ch = ref None; + node_server = ref None; + next_process_id = ref 0; + registered_funs = Hashtbl.create 10; + } + in + log_msg ns Info "node start up" (fun () -> + Format.fprintf + ns.log_formatter + "{Distributed library version : %s ; Threading implementation \ + : [name : %s ; version : %s ; description : %s]}" + dist_lib_version + lib_name + lib_version + lib_description) + >>= fun () -> + log_msg ns Info "node start up" (fun () -> + Format.fprintf + ns.log_formatter + "local only mode with configuration of " ; + print_string_of_config node_config ns.log_formatter) + >>= fun () -> + if process = None then return () + else + let new_pid = + Process_id.make_local + local_config.Local_config.node_name + ns.next_process_id + in + Hashtbl.replace + ns.mailboxes + (Process_id.get_id new_pid) + (I.create_stream ()) ; + run_process' ns new_pid ((Potpourri.get_option process) ()) + | Remote remote_config -> + let ns = + { + mailboxes = Hashtbl.create 1000; + remote_nodes = Node_id_hashtbl.create ~random:true 10; + monitor_table = Process_id_hashtbl.create ~random:true 1000; + local_node = + Node_id.make_remote_node + remote_config.Remote_config.node_ip + remote_config.Remote_config.local_port + remote_config.Remote_config.node_name; + monitor_ref_id = ref 0; + config = ref (Some remote_config); + log_buffer = buff; + log_formatter = Format.formatter_of_buffer buff; + est_in_ch = ref None; + est_out_ch = ref None; + node_server = ref None; + (* fill in below *) + next_process_id = ref 0; + registered_funs = Hashtbl.create 10; + } + in + log_msg ns Info "node start up" (fun () -> + Format.fprintf + ns.log_formatter + "{Distributed library version : %s ; Threading implementation \ + : [name : %s ; version : %s ; description : %s]}" + dist_lib_version + lib_name + lib_version + lib_description) + >>= fun () -> + log_msg ns Info "node start up" (fun () -> + Format.fprintf + ns.log_formatter + "remote mode with configuration of " ; + print_string_of_config node_config ns.log_formatter) + >>= fun () -> + I.catch + (fun () -> + connect_to_remote_nodes + ns + remote_config.Remote_config.remote_nodes + >>= fun () -> + let local_sock_addr = + Unix.ADDR_INET + (Unix.inet_addr_any, remote_config.Remote_config.local_port) + in + I.establish_server + ~backlog:remote_config.Remote_config.connection_backlog + local_sock_addr + (node_server_fn ns) + >>= fun command_process_server -> + ns.node_server := Some command_process_server ; + at_exit (fun () -> + log_msg ns Info "node shutting down" (fun () -> + Format.fprintf + ns.log_formatter + "start clean up actions for remote mode with \ + configuration of " ; + print_string_of_config node_config ns.log_formatter) + >>= fun () -> + at_exit_handler ns () >>= fun () -> + log_msg ns Info "node shutting down" (fun () -> + Format.fprintf + ns.log_formatter + "finished clean up actions for remote mode with \ + configuration of " ; + print_string_of_config node_config ns.log_formatter)) ; + if process = None then return () + else + let new_pid = + Process_id.make_remote + remote_config.Remote_config.node_ip + remote_config.Remote_config.local_port + remote_config.Remote_config.node_name + ns.next_process_id + in + Hashtbl.replace + ns.mailboxes + (Process_id.get_id new_pid) + (I.create_stream ()) ; + run_process' ns new_pid ((Potpourri.get_option process) ())) + (fun e -> + log_msg ns Error ~exn:e "node start up" (fun () -> + Format.fprintf + ns.log_formatter + "encountered exception during node startup, shutting down \ + server") + >>= fun () -> + at_exit_handler ns () >>= fun () -> + (* reraise exception so os level process stops*) + fail e)) +end diff --git a/src/lib_distributed_internal/src/distributed.mli b/src/lib_distributed_internal/src/distributed.mli new file mode 100644 index 000000000000..14357f0f03b5 --- /dev/null +++ b/src/lib_distributed_internal/src/distributed.mli @@ -0,0 +1,354 @@ +(** This module provides modules to create distribtued computations. + Distributed comutations are described using the {!module-type:Process}. + {!module-type:Process} provides a monadic interface to describe distributed computations. + + @author essdotteedot + @version 0.6.0 +*) + +(** Some nomenclature : + - Node : A node corresponds to a operating system process. There can be many nodes on a + single machine. + + - Process : A process corresponds to a light weight thread (i.e., user space cooperative threads). + There can be many processes on a single Node. + +*) + +(** This module provides a type representing a node id. *) +module Node_id : sig + (** The abstract type representing a node id. *) + type t + + (** [get_name node] returns the name of the node. *) + val get_name : t -> string +end + +(** This module provides a type representing a process id. *) +module Process_id : sig + (** The abstract type representing a process id. *) + type t +end + +(** Abstract type which can perform monadic concurrent IO. *) +module type Nonblock_io = sig + (** The monadic light weight thread type returning value ['a]. *) + type 'a t + + (** An unbounded stream holding values of ['a]. *) + type 'a stream + + (** A type to represent a non-blocking input channel *) + type input_channel + + (** A type to represent a non-blocking output channel *) + type output_channel + + (** A type to represent a server *) + type server + + (** Exception raised by {!val:timeout} operation *) + exception Timeout + + type level = + | Debug + | Info + | Warning + | Error (** Type to represent levels of a log message. *) + + (** The name of the implementation, for logging purposes. *) + val lib_name : string + + (** The version implementation, for logging purposes. *) + val lib_version : string + + (** A description of the implementation (e.g., the url of the code repository ), for logging purposes. *) + val lib_description : string + + (** [return v] creates a light weight thread returning [v]. *) + val return : 'a -> 'a t + + (** [bind t f] is a thread which first waits for the thread [t] to terminate and then, if the thread succeeds, + behaves as the application of function [f] to the return value of [t]. If the thread [t] fails, [bind t f] also fails, + with the same exception. + *) + val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t + + (** [fail e] is a thread that fails with the exception [e]. *) + val fail : exn -> 'a t + + (** [catch t f] is a thread that behaves as the thread [t ()] if this thread succeeds. + If the thread [t ()] fails with some exception, [catch t f] behaves as the application of [f] to this exception. + *) + val catch : (unit -> 'a t) -> (exn -> 'a t) -> 'a t + + (** [async f starts] a thread without waiting for the result. *) + val async : (unit -> unit t) -> unit + + (** [create ()] returns a new stream and a push function. *) + val create_stream : unit -> 'a stream * ('a option -> unit) + + (** [get st] removes and returns the first element of the stream, if any. Will block if the stream is empty. *) + val get : 'a stream -> 'a option t + + (** [stream_append s1 s2] returns a [stream] which returns all elements of [s1], then all elements of [s2]. *) + val stream_append : 'a stream -> 'a stream -> 'a stream + + (** [close ch] closes the given channel immediately. *) + val close_input : input_channel -> unit t + + (** [close ch] closes the given channel. It performs all pending actions, flushes it and closes it. *) + val close_output : output_channel -> unit t + + (** [read_value ic] reads a marshalled value from [ic]. *) + val read_value : input_channel -> 'a t + + (** [write_value oc ?flags x] marshals the value [x] to [oc]. *) + val write_value : + output_channel -> ?flags:Marshal.extern_flags list -> 'a -> unit t + + (** [open_connection addr] opens a connection to the given address and returns two channels for using it. *) + val open_connection : Unix.sockaddr -> (input_channel * output_channel) t + + (** [establish_server ?backlog sockaddr f] creates a server which will listen for incoming connections. + New connections are passed to [f]. Note that [f] must not raise any exception. Backlog is the argument passed to Lwt_unix.listen. + *) + val establish_server : + ?backlog:int -> + Unix.sockaddr -> + (Unix.sockaddr -> input_channel * output_channel -> unit t) -> + server t + + (** [shutdown_server server] will shutdown [server]. *) + val shutdown_server : server -> unit t + + (** [log level message_formatter] logs a message at the specified level using the formatter provided. *) + val log : level -> (unit -> string) -> unit t + + (** [sleep d] is a thread that remains suspended for [d] seconds and then terminates. *) + val sleep : float -> unit t + + (** [timeout d] is a thread that remains suspended for [d] seconds and then fails with ​{!exception:Distributed.Nonblock_io.Timeout}. *) + val timeout : float -> 'a t + + (** [pick l] behaves as the first thread in l to terminate. If several threads are already terminated, one is chosen at random. Cancels all sleeping threads when one terminates. *) + val pick : 'a t list -> 'a t + + (** [at_exit fn] will call fn on program exit. *) + val at_exit : (unit -> unit t) -> unit +end + +(** The abstract type representing the messages that will be sent between processes. *) +module type Message_type = sig + (** Abstract type representing the messages that will be sent between processes. *) + type t + + (** [string_of_message msg] returns the [string] representation of [msg]. *) + val string_of_message : t -> string +end + +(** A unit of computation which can be executed on a local or remote host, is monadic. *) +module type Process = sig + (** Exception that is raised if {!val:run_node} is called more than once. *) + exception Init_more_than_once + + (** Exception that is raised when {!val:spawn}, {!val:broadcast}, {!val:monitor} are called with an invalid node or if {!val:send} + is called with a process which resides on an unknown node. + *) + exception InvalidNode of Node_id.t + + (** Exception that is raised when {!val:add_remote_node} or {!val:remove_remote_node} is called on a node that is operating in local only mode. *) + exception Local_only_mode + + (** The abstract monadic type representing a computation returning ['a]. *) + type 'a t + + (** Abstract type for monadic concurrent IO returning ['a]. *) + type 'a io + + (** The abstract type representing the messages that will be sent between processes. *) + type message_type + + (** The abstract type representing a non-empty list of matchers to be used with {!val:receive} function. *) + type 'a matcher_list + + (** The abstract type representing a monitor_ref that is returned when a processes is monitored and can be used to unmonitor it. *) + type monitor_ref + + (** Reason for process termination. *) + type monitor_reason = + | Normal of Process_id.t (** Process terminated normally. *) + | Exception of Process_id.t * exn (** Process terminated with exception. *) + | UnkownNodeId of Process_id.t * Node_id.t + (** An operation failed because the remote node id is unknown. *) + | NoProcess of Process_id.t + (** Attempted to monitor a process that does not exist. *) + + (** The configuration of a node to be run as a remote node i.e., one that can both send an receive messages with other nodes. *) + module Remote_config : sig + type t = { + remote_nodes : (string * int * string) list; + (** The initial list of remote nodes which this node can send messages to. A list of external ip address/port/node name triplets.*) + local_port : int; (** The port that this node should run on. *) + connection_backlog : int; + (** The the argument used when listening on a socket. *) + node_name : string; (** The name of this node. *) + node_ip : string; (** The external ip address of this node. *) + } + end + + (** The configuration of a node to be run as a local node i.e., one that can not send or receive messages with other nodes. *) + module Local_config : sig + type t = {node_name : string (** The name of this node. *)} + end + + (** The configuration of a node. Can be one of {!node_config.Local} or {!node_config.Remote}. *) + type node_config = Local of Local_config.t | Remote of Remote_config.t + + (** [return v] creates a computation returning [v]. *) + val return : 'a -> 'a t + + (** [c >>= f] is a computation which first waits for the computation [c] to terminate and then, if the computation succeeds, + behaves as the application of function [f] to the return value of [c]. If the computation [c] fails, [c >>= f] also fails, + with the same exception. + *) + val ( >>= ) : 'a t -> ('a -> 'b t) -> 'b t + + type proc_rep = Fun of (unit -> unit t) | Registered of string + + val register : string -> (Process_id.t -> unit -> unit t) -> unit t + + (** [fail e] is a process that fails with the exception [e]. *) + val fail : exn -> 'a t + + (** [catch p f] is a process that behaves as the process [p ()] if this process succeeds. + If the process [p ()] fails with some exception, [catch p f] behaves as the application of [f] to this exception. + *) + val catch : (unit -> 'a t) -> (exn -> 'a t) -> 'a t + + (** [spawn monitor name node_id process] will spawn [process] on [node_id] returning the {!type:Process_id.t} associated with the newly spawned process. + If [monitor] is true (default value is false) then the spawned process will also be monitored and the associated {!type:monitor_ref} will be + returned. + + If [node_id] is an unknown node then {!exception:InvalidNode} exception is raised. + *) + val spawn : + ?monitor:bool -> + Node_id.t -> + proc_rep -> + Process_id.t -> + (Process_id.t * monitor_ref option) t + + (** [case match_fn] will create a {!type:matcher_list} which will use [match_fn] to match on potential messages. + [match_fn] should return [None] to indicate no match or [Some handler] where [handler] is the function + that should be called to handle the matching message. + *) + val case : (message_type -> (unit -> 'a t) option) -> 'a matcher_list + + (** [termination_case handler] will create a {!type:matcher_list} which can use used to match against [termination_reason] for a + process that is being monitored. If this process is monitoring another process then providing this matcher in the list + of matchers to {!val:receive} will allow this process to act on the termination of the monitored process. + + NOTE : when a remote process (i.e., one running on another node) raises an exception you will not be able + to pattern match on the exception . This is a limitation of the Marshal OCaml module : + " Values of extensible variant types, for example exceptions (of extensible type exn), returned by the unmarshaller + should not be pattern-matched over through [match ... with] or [try ... with], because unmarshalling does not preserve the + information required for matching their constructors. Structural equalities with other extensible variant values does not work either. + Most other uses such as Printexc.to_string, will still work as expected. " + + See http://caml.inria.fr/pub/docs/manual-ocaml/libref/Marshal.html. + *) + val termination_case : (monitor_reason -> 'a t) -> 'a matcher_list + + (** [a_matcher |. b_matcher] is a {!type:matcher_list} consiting of the matchers in [a_matcher] followed by the matchers + in [b_matcher]. + *) + val ( |. ) : 'a matcher_list -> 'a matcher_list -> 'a matcher_list + + (** [receive timeout matchers] will wait for a message to be sent to this process which matches one of matchers provided in + [matchers]. The first matching matcher in [matchers] will used process the matching message returning [Some result] where + [result] is result of the matcher processing the matched message. All the other non-matching messages are left in the same + order they came in. + + If a time out is provided and no matching messages has arrived in the time out period then None will be returned. + + If the [matchers] is empty then an {!exception:Empty_matchers} exception is raised. + *) + val receive : ?timeout_duration:float -> 'a matcher_list -> 'a option t + + (** [receive_loop timeout matchers] is a convenience function which will loop until a matcher in [matchers] returns false. *) + val receive_loop : ?timeout_duration:float -> bool matcher_list -> unit t + + (** [send process_id msg] will send, asynchronously, message [msg] to the process with id [process_id] (possibly running on a remote node). + + If [process_id] is resides on an unknown node then {!exception:InvalidNode} exception is raised. + + If [process_id] is an unknown process but the node on which it resides is known then send will still succeed (i.e., will not raise any exceptions). + *) + val send : Process_id.t -> message_type -> unit t + + (** [pid >! msg] is equivalent to [send pid msg]. [>!] is an infix alias for [send]. *) + val ( >! ) : Process_id.t -> message_type -> unit t + + (** [broadcast node_id msg] will send, asynchronously, message [msg] to all the processes on [node_id]. + + If [node_id] is an unknown node then {!exception:InvalidNode} exception is raised. + *) + val broadcast : Node_id.t -> message_type -> unit t + + (** [monitor pid] will allows the calling process to monitor [pid]. When [pid] terminates (normally or abnormally) this monitoring + process will receive a [termination_reason] message, which can be matched in [receive] using [termination_matcher]. A single + process can be monitored my multiple processes. + + If [process_id] is resides on an unknown node then {!exception:InvalidNode} exception is raised. + *) + val monitor : Process_id.t -> monitor_ref t + + (** [unmonitor mref] will cause this process to stop monitoring the process which is referenced by [mref]. + If the current process is not monitoring the process referenced by [mref] then [unmonitor] is a no-op. + + If process being unmonitored as indicated by [monitor_ref] is resides on an unknown node then {!exception:InvalidNode} exception is raised. + *) + val unmonitor : monitor_ref -> unit t + + (** [get_self_pid process] will return the process id associated with [process]. *) + val get_self_pid : Process_id.t t + + (** [get_self_node process] will return the node id associated with [process]. *) + val get_self_node : Node_id.t t + + (** [get_remote_node node_name] will return the node id associated with [name], if there is no record of a node with [name] at + this time then [None] is returned. + *) + val get_remote_node : string -> Node_id.t option t + + (** The list of all nodes currently active and inactive. *) + val get_remote_nodes : Node_id.t list t + + (** [add_remote_node ip port name] will connect to the remote node at [ip]:[port] with name [name] and add it to the current nodes list of connected remote nodes. + The newly added node id is returned as the result. Adding a remote node that already exists is a no-op. + + If the node is operating in local only mode then {!exception:Local_only_mode} is raised. + *) + val add_remote_node : string -> int -> string -> Node_id.t t + + (** [remove_remote_node node_id] will remove [node_id] from the list of connected remote nodes. + + If the node is operating in local only mode then {!exception:Local_only_mode} is raised. + *) + val remove_remote_node : Node_id.t -> unit t + + (** [lift_io io] lifts the [io] computation into the process. *) + val lift_io : 'a io -> 'a t + + (** [run_node process node_monitor_fn node_config] performs the necessary bootstrapping to start this + node according to [node_config]. If provided, runs the initial [process] returning the resulting [io]. + + If it's called more than once then an exception of {!exception:Init_more_than_once} is raised. + *) + val run_node : ?process:(unit -> unit t) -> node_config -> unit io +end + +(** Functor to create a module of type {!module-type:Process} given a message module [M] of type {!module-type:Message_type}. *) +module Make (I : Nonblock_io) (M : Message_type) : + Process with type message_type = M.t and type 'a io = 'a I.t diff --git a/src/lib_distributed_internal/src/dune b/src/lib_distributed_internal/src/dune new file mode 100644 index 000000000000..3a4272c15cce --- /dev/null +++ b/src/lib_distributed_internal/src/dune @@ -0,0 +1,9 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name distributed) + (public_name octez-distributed-internal) + (instrumentation (backend bisect_ppx)) + (libraries + unix)) -- GitLab From 3a528c48b563155423e5d09d80660bbd9418d43d Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 15 Mar 2023 15:27:39 +0100 Subject: [PATCH 25/34] lib_plonk_communication: import from privacy-team/aplonk --- .gitlab/ci/jobs/packaging/opam_package.yml | 14 +- manifest/main.ml | 10 +- opam/octez-plonk.opam | 2 + .../communication/distributed_wrapper.ml | 229 +++++++++++ src/lib_distributed_plonk/communication/dune | 15 + .../communication/message.ml | 354 ++++++++++++++++++ .../communication/message.mli | 99 +++++ 7 files changed, 720 insertions(+), 3 deletions(-) create mode 100644 src/lib_distributed_plonk/communication/distributed_wrapper.ml create mode 100644 src/lib_distributed_plonk/communication/dune create mode 100644 src/lib_distributed_plonk/communication/message.ml create mode 100644 src/lib_distributed_plonk/communication/message.mli diff --git a/.gitlab/ci/jobs/packaging/opam_package.yml b/.gitlab/ci/jobs/packaging/opam_package.yml index 942e6a33fe28..cdc53b39cbc1 100644 --- a/.gitlab/ci/jobs/packaging/opam_package.yml +++ b/.gitlab/ci/jobs/packaging/opam_package.yml @@ -286,9 +286,19 @@ opam:octez-crawler: # Ignoring unreleased package octez-dal-node. -# Ignoring unreleased package octez-distributed-internal. +opam:octez-distributed-internal: + extends: + - .opam_template + - .rules_template__trigger_opam_batch_7 + variables: + package: octez-distributed-internal -# Ignoring unreleased package octez-distributed-lwt-internal. +opam:octez-distributed-lwt-internal: + extends: + - .opam_template + - .rules_template__trigger_opam_batch_7 + variables: + package: octez-distributed-lwt-internal # Ignoring unreleased package octez-evm-proxy. diff --git a/manifest/main.ml b/manifest/main.ml index 0237979b3191..7a2729c4b2c8 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -376,7 +376,7 @@ let distributed_internal = ~synopsis:"Fork of distributed. Use for Octez only" ~deps:[unix] -let _distributed_internal_lwt = +let distributed_internal_lwt = public_lib "octez-distributed-lwt-internal" ~internal_name:"distributed_lwt" @@ -1260,6 +1260,14 @@ let octez_plonk_distribution = ~deps:[octez_plonk; octez_plonk_aggregation] ~preprocess:[pps ppx_repr] +let _octez_plonk_communication = + public_lib + "octez-plonk.communication" + ~internal_name:"communication" + ~path:"src/lib_distributed_plonk/communication" + ~deps:[logs; distributed_internal_lwt; octez_plonk_distribution |> open_] + ~preprocess:[pps ppx_repr] + let octez_plonk_test_helpers = public_lib "octez-plonk.plonk-test" diff --git a/opam/octez-plonk.opam b/opam/octez-plonk.opam index 2bb7cfb14fbb..a341407e9fd3 100644 --- a/opam/octez-plonk.opam +++ b/opam/octez-plonk.opam @@ -16,6 +16,8 @@ depends: [ "data-encoding" { >= "0.7.1" & < "1.0.0" } "octez-bls12-381-polynomial" "octez-plompiler" + "logs" + "octez-distributed-lwt-internal" "qcheck-alcotest" { >= "0.20" } "bls12-381" { >= "6.1.0" & < "6.2.0" } ] diff --git a/src/lib_distributed_plonk/communication/distributed_wrapper.ml b/src/lib_distributed_plonk/communication/distributed_wrapper.ml new file mode 100644 index 000000000000..f14c7cea919c --- /dev/null +++ b/src/lib_distributed_plonk/communication/distributed_wrapper.ml @@ -0,0 +1,229 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +(** Wrapper for the Distributed library. + The new API is designed for the distribution of protocols based on a + 1 master N workers architecture, in which at each step of the protocol: + {ul + {li + The master asks all the workers to compute the same function over + different inputs. We call these messages {e requests}. Each protocol + step will define a [request] (see {Message} module), whose payload + will change for every worker.} + {li + Each worker computes the {e reply} to the received request, and sends + it back to the master. Each protocol step will define a [reply] + (see {Message} module). + } + {li + The master waits to receive all the replies from the workers. + } + } + + Instead of directly using the [send] and [receive], the new API provides + two abstractions, `dmap` and `handle_request`, to implement this + interaction from the master and worker respectively. These abstractions + will enforce via the type-system that the [request] and [reply] used + correspond to the same protocol step. +*) + +module Logger = struct + let log_src = + Logs.Src.create + "distributed" + ~doc:"logs events related to the distributed library" + + module Log = (val Logs_lwt.src_log log_src : Logs_lwt.LOG) + + let msg = Log.msg + + (* slightly modified version of reporter defined in Logs_lwt manual : http://erratique.ch/software/logs/doc/Logs_lwt.html#report_ex*) + let lwt_reporter () = + let buf_fmt () = + let b = Buffer.create 512 in + ( Format.formatter_of_buffer b, + fun () -> + let m = Buffer.contents b in + Buffer.reset b ; + m ) + in + let app, app_flush = buf_fmt () in + let reporter = Logs.format_reporter ~app ~dst:app () in + let report src level ~over k msgf = + let k' () = + let write () = Lwt_io.write Lwt_io.stdout (app_flush ()) in + let unblock () = + over () ; + Lwt.return_unit + in + Lwt.finalize write unblock |> ignore ; + k () + in + reporter.Logs.report src level ~over:(fun () -> ()) k' msgf + in + {Logs.report} +end + +(** + Messages are refined into either a [request] or a [reply]. + Both these types are parameterized by their protocol [step]. + The ground type of messages ([t]) is enforced to be [bytes], + to avoid relying on the Marshalling performed by the Distributed library. +*) +module type Enriched_message_type = sig + include Distributed.Message_type with type t = bytes + + type 'a step + + type 'step request + + type 'step reply + + val request_step : 'step request -> 'step step + + val of_request : 'a request -> t + + val of_reply : 'a reply -> t + + val to_request : 'step step -> t -> 'step request option + + val to_reply : 'step step -> t -> 'step reply option + + val index : t -> int +end + +module type Enriched_process = sig + include Distributed.Process + + module M : Enriched_message_type + + (** Additional monadic interface *) + + val ( let* ) : 'a t -> ('a -> 'b t) -> 'b t + + val ( let+ ) : 'a t -> ('a -> 'b) -> 'b t + + val mapM : ('a -> 'b t) -> 'a list -> 'b list t + + (** [dmap ~pids ~request ~reply l] sends requests built by applying + [request] to the elements of [l] to the workers [pids] and waits + to receive a valid [reply] from each worker. + *) + val dmap : + pids:Distributed.Process_id.t list -> + request:('a -> index:int -> 'step M.request) -> + reply:('step M.reply -> (unit -> 'b t) option) -> + 'a list -> + 'b list t + + (** [handle_request master_pid ~setp ~handler l] waits to receive a request + for a given [step], process it through [handler] and sends the reply to + [master_pid]. + The [handler] might also return some additional data ('b) that isn't + meant to be sent back to the master, but rather kept by the worker for + future computation. + *) + val handle_request : + Distributed.Process_id.t -> + step:'step M.step -> + handler:('step M.request -> (unit -> ('step M.reply * 'b) t) option) -> + 'b t +end + +module Make (A : Enriched_message_type) : + Enriched_process + with type message_type = A.t + and type M.t = A.t + and type 'a M.step = 'a A.step + and type 'a M.request = 'a A.request + and type 'a M.reply = 'a A.reply + and type 'a io = 'a Lwt.t = struct + include Distributed_lwt.Make (A) (Logger) + module M = A + + let ( let* ) = ( >>= ) + + let ( let+ ) : 'a t -> ('a -> 'b) -> 'b t = + fun m f -> m >>= fun x -> return (f x) + + let mapM : ('a -> 'b t) -> 'a list -> 'b list t = + fun f -> + let rec go acc = function + | [] -> return (List.rev acc) + | x :: xs -> + let* y = f x in + go (y :: acc) xs + in + go [] + + let dmap ~pids ~request ~reply l = + let module IMap = Map.Make (Int) in + let expected = List.length pids in + let replies = ref IMap.empty in + mapM + (fun ((index, pid), x) -> + let* () = send pid (M.of_request @@ request x ~index) in + return (M.request_step @@ request x ~index)) + List.(combine (combine (init (length pids) Fun.id) pids) l) + >>= fun steps -> + let step = List.hd steps in + receive_loop + (case (function m -> + Option.bind (M.to_reply step m) @@ fun r -> + Option.map + (fun f () -> + lift_io + @@ Lwt_io.printlf "got message %s from remote node\n" + @@ M.string_of_message m + >>= fun () -> + let* () = lift_io @@ Lwt_io.flush_all () in + f () >>= fun y -> + replies := IMap.add (M.index m) y !replies ; + return (IMap.cardinal !replies < expected)) + (reply r))) + >>= fun _ -> return (List.map snd @@ IMap.bindings !replies) + + let handle_request : + Distributed.Process_id.t -> + step:'step M.step -> + handler:('step M.request -> (unit -> ('step M.reply * 'b) t) option) -> + 'b t = + fun pid ~step ~handler -> + let* x = + receive + (case (fun m -> + Option.map (fun f () -> + let* () = + lift_io + @@ Lwt_io.printlf "got message %s from remote node\n" + @@ M.string_of_message m + in + f ()) + @@ Option.bind (M.to_request step m) handler)) + in + let repl, v = Option.get x in + let* () = send pid (M.of_reply repl) in + return v +end diff --git a/src/lib_distributed_plonk/communication/dune b/src/lib_distributed_plonk/communication/dune new file mode 100644 index 000000000000..f36c32380ce6 --- /dev/null +++ b/src/lib_distributed_plonk/communication/dune @@ -0,0 +1,15 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name communication) + (public_name octez-plonk.communication) + (instrumentation (backend bisect_ppx)) + (libraries + logs + octez-distributed-lwt-internal + octez-plonk.distribution) + (preprocess (pps ppx_repr)) + (flags + (:standard) + -open Plonk_for_distribution)) diff --git a/src/lib_distributed_plonk/communication/message.ml b/src/lib_distributed_plonk/communication/message.ml new file mode 100644 index 000000000000..c583954fc8f2 --- /dev/null +++ b/src/lib_distributed_plonk/communication/message.ml @@ -0,0 +1,354 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module type S = sig + (** Plonk Main Protocol *) + module MP : Plonk_for_distribution.Main_protocol.S + + (** Type witness for a protocol step. *) + type 'a step = + | S_ctw : [`Commit_to_wires] step + | S_ctp : [`Commit_to_plook] step + | S_pppi : [`PP_prepare_ids] step + | S_ppctt : [`PP_commit_to_t] step + | S_ppkeax : [`PP_kzg_eval_at_x] step + | S_pcd : [`PC_distribution] step + + (* All message payloads need to have an index, so that + they can be sorted back by the master. *) + type ctw_payload = {index : int; content : MP.worker_inputs Plonk.SMap.t} + + type ctpap_payload = {index : int; content : MP.PP.transcript} + + type pppi_payload = {index : int; content : MP.PP.transcript} + + type ppctt_payload = {index : int; content : string list * Plonk.Bls.Scalar.t} + + type ppkeax_payload = {index : int; content : MP.PP.transcript} + + type pcd_payload = {index : int; content : MP.PP.PC.worker_msg} + + type 'step request = + | Commit_to_wires : ctw_payload -> [`Commit_to_wires] request + | Commit_to_plook : ctpap_payload -> [`Commit_to_plook] request + | PP_prepare_ids : pppi_payload -> [`PP_prepare_ids] request + | PP_commit_to_t : ppctt_payload -> [`PP_commit_to_t] request + | PP_KZG_eval_at_x : ppkeax_payload -> [`PP_kzg_eval_at_x] request + | PC_Distribution : pcd_payload -> [`PC_distribution] request + + type ctw_res_payload = {index : int; content : MP.commit_to_wires_reply} + + type ctpap_res_payload = {index : int; content : MP.commit_to_plook_rc_reply} + + type pppi_res_payload = {index : int; content : string list} + + type ppctt_res_payload = {index : int; content : Plonk.Bls.Evaluations.t} + + type ppkeax_res_payload = {index : int; content : MP.PP.PC.answer list} + + type pcd_res_payload = {index : int; content : MP.PP.PC.main_prover_msg} + + type 'step reply = + | Commit_to_wires_res : ctw_res_payload -> [`Commit_to_wires] reply + | Commit_to_plook_res : ctpap_res_payload -> [`Commit_to_plook] reply + | PP_prepare_ids_res : pppi_res_payload -> [`PP_prepare_ids] reply + | PP_commit_to_t_res : ppctt_res_payload -> [`PP_commit_to_t] reply + | PP_KZG_eval_at_x_res : ppkeax_res_payload -> [`PP_kzg_eval_at_x] reply + | PC_Distribution_res : pcd_res_payload -> [`PC_distribution] reply + + type t = bytes + + val request_step : 'step request -> 'step step + + val of_request : 'a request -> t + + val of_reply : 'a reply -> t + + val to_request : 'step step -> t -> 'step request option + + val to_reply : 'step step -> t -> 'step reply option + + val index : t -> int + + val string_of_message : t -> string +end + +module Make = +functor + (MP : Plonk_for_distribution.Main_protocol.S) + -> + struct + module MP = MP + + (** Type witness for a protocol step. *) + type 'a step = + | S_ctw : [`Commit_to_wires] step + | S_ctp : [`Commit_to_plook] step + | S_pppi : [`PP_prepare_ids] step + | S_ppctt : [`PP_commit_to_t] step + | S_ppkeax : [`PP_kzg_eval_at_x] step + | S_pcd : [`PC_distribution] step + + (* All message payloads need to have an index, so that + they can be sorted back by the master. *) + type ctw_payload = {index : int; content : MP.worker_inputs Plonk.SMap.t} + [@@deriving repr] + + type ctpap_payload = {index : int; content : MP.PP.transcript} + [@@deriving repr] + + type pppi_payload = {index : int; content : MP.PP.transcript} + [@@deriving repr] + + type ppctt_payload = { + index : int; + content : string list * Plonk.Bls.Scalar.t; + } + [@@deriving repr] + + type ppkeax_payload = {index : int; content : MP.PP.transcript} + [@@deriving repr] + + type pcd_payload = {index : int; content : MP.PP.PC.worker_msg} + [@@deriving repr] + + type 'step request = + | Commit_to_wires : ctw_payload -> [`Commit_to_wires] request + | Commit_to_plook : ctpap_payload -> [`Commit_to_plook] request + | PP_prepare_ids : pppi_payload -> [`PP_prepare_ids] request + | PP_commit_to_t : ppctt_payload -> [`PP_commit_to_t] request + | PP_KZG_eval_at_x : ppkeax_payload -> [`PP_kzg_eval_at_x] request + | PC_Distribution : pcd_payload -> [`PC_distribution] request + + type ctw_res_payload = {index : int; content : MP.commit_to_wires_reply} + [@@deriving repr] + + type ctpap_res_payload = { + index : int; + content : MP.commit_to_plook_rc_reply; + } + [@@deriving repr] + + type pppi_res_payload = {index : int; content : string list} + [@@deriving repr] + + type ppctt_res_payload = {index : int; content : Plonk.Bls.Evaluations.t} + [@@deriving repr] + + type ppkeax_res_payload = {index : int; content : MP.PP.PC.answer list} + [@@deriving repr] + + type pcd_res_payload = {index : int; content : MP.PP.PC.main_prover_msg} + [@@deriving repr] + + type 'step reply = + | Commit_to_wires_res : ctw_res_payload -> [`Commit_to_wires] reply + | Commit_to_plook_res : ctpap_res_payload -> [`Commit_to_plook] reply + | PP_prepare_ids_res : pppi_res_payload -> [`PP_prepare_ids] reply + | PP_commit_to_t_res : ppctt_res_payload -> [`PP_commit_to_t] reply + | PP_KZG_eval_at_x_res : ppkeax_res_payload -> [`PP_kzg_eval_at_x] reply + | PC_Distribution_res : pcd_res_payload -> [`PC_distribution] reply + + (* Non-GADT versions of [request] and [reply], used to derive a [Repr.t] *) + type f_request = + | FCommit_to_wires : ctw_payload -> f_request + | FCommit_to_plook : ctpap_payload -> f_request + | FPP_prepare_ids : pppi_payload -> f_request + | FPP_commit_to_t : ppctt_payload -> f_request + | FPP_KZG_eval_at_x : ppkeax_payload -> f_request + | FPC_Distribution : pcd_payload -> f_request + [@@deriving repr] + + let forget_request : type a. a request -> f_request = function + | Commit_to_wires p -> FCommit_to_wires p + | Commit_to_plook p -> FCommit_to_plook p + | PP_prepare_ids p -> FPP_prepare_ids p + | PP_commit_to_t p -> FPP_commit_to_t p + | PP_KZG_eval_at_x p -> FPP_KZG_eval_at_x p + | PC_Distribution p -> FPC_Distribution p + + type f_reply = + | FCommit_to_wires_res : ctw_res_payload -> f_reply + | FCommit_to_plook_res : ctpap_res_payload -> f_reply + | FPP_prepare_ids_res : pppi_res_payload -> f_reply + | FPP_commit_to_t_res : ppctt_res_payload -> f_reply + | FPP_KZG_eval_at_x_res : ppkeax_res_payload -> f_reply + | FPC_Distribution_res : pcd_res_payload -> f_reply + [@@deriving repr] + + let forget_reply : type a. a reply -> f_reply = function + | Commit_to_wires_res p -> FCommit_to_wires_res p + | Commit_to_plook_res p -> FCommit_to_plook_res p + | PP_prepare_ids_res p -> FPP_prepare_ids_res p + | PP_commit_to_t_res p -> FPP_commit_to_t_res p + | PP_KZG_eval_at_x_res p -> FPP_KZG_eval_at_x_res p + | PC_Distribution_res p -> FPC_Distribution_res p + + type msg = Request : f_request -> msg | Reply : f_reply -> msg + [@@deriving repr] + + type t = bytes + + let of_bytes_exn r b = + Result.get_ok + @@ Repr.(unstage @@ Repr.of_bin_string r) (Bytes.to_string b) + + let to_bytes r v = Bytes.of_string Repr.((unstage @@ to_bin_string r) v) + + let request_step : type s. s request -> s step = function + | Commit_to_wires _p -> S_ctw + | Commit_to_plook _p -> S_ctp + | PP_prepare_ids _p -> S_pppi + | PP_commit_to_t _p -> S_ppctt + | PP_KZG_eval_at_x _p -> S_ppkeax + | PC_Distribution _p -> S_pcd + + let of_request : 'a request -> t = + fun r -> to_bytes msg_t @@ Request (forget_request r) + + let of_reply : 'a reply -> t = + fun r -> to_bytes msg_t @@ Reply (forget_reply r) + + let to_reply : type s. s step -> t -> s reply option = + fun step t -> + let m = of_bytes_exn msg_t t in + match (step, m) with + | S_ctw, Reply (FCommit_to_wires_res p) -> Some (Commit_to_wires_res p) + | S_ctp, Reply (FCommit_to_plook_res p) -> Some (Commit_to_plook_res p) + | S_pppi, Reply (FPP_prepare_ids_res p) -> Some (PP_prepare_ids_res p) + | S_ppctt, Reply (FPP_commit_to_t_res p) -> Some (PP_commit_to_t_res p) + | S_ppkeax, Reply (FPP_KZG_eval_at_x_res p) -> + Some (PP_KZG_eval_at_x_res p) + | S_pcd, Reply (FPC_Distribution_res p) -> Some (PC_Distribution_res p) + | _ -> None + + let to_request : type s. s step -> t -> s request option = + fun step t -> + let m = of_bytes_exn msg_t t in + match (step, m) with + | S_ctw, Request (FCommit_to_wires p) -> Some (Commit_to_wires p) + | S_ctp, Request (FCommit_to_plook p) -> Some (Commit_to_plook p) + | S_pppi, Request (FPP_prepare_ids p) -> Some (PP_prepare_ids p) + | S_ppctt, Request (FPP_commit_to_t p) -> Some (PP_commit_to_t p) + | S_ppkeax, Request (FPP_KZG_eval_at_x p) -> Some (PP_KZG_eval_at_x p) + | S_pcd, Request (FPC_Distribution p) -> Some (PC_Distribution p) + | _ -> None + + let index : t -> int = + fun t -> + let m = of_bytes_exn msg_t t in + match m with + | Request (FCommit_to_wires {index; _}) + | Reply (FCommit_to_wires_res {index; _}) + | Request (FCommit_to_plook {index; _}) + | Reply (FCommit_to_plook_res {index; _}) + | Request (FPP_prepare_ids {index; _}) + | Reply (FPP_prepare_ids_res {index; _}) + | Request (FPP_commit_to_t {index; _}) + | Reply (FPP_commit_to_t_res {index; _}) + | Request (FPP_KZG_eval_at_x {index; _}) + | Reply (FPP_KZG_eval_at_x_res {index; _}) + | Request (FPC_Distribution {index; _}) + | Reply (FPC_Distribution_res {index; _}) -> + index + + let string_of_bytes bytes = + let bytes = float_of_int bytes in + if bytes <= 1024. then Printf.sprintf "%3.2f B " bytes + else + let kilobytes = bytes /. 1024. in + if kilobytes <= 1024. then Printf.sprintf "%3.2f KB" kilobytes + else + let megabytes = kilobytes /. 1024. in + if megabytes <= 1024. then Printf.sprintf "%3.2f MB" megabytes + else + let gigabytes = megabytes /. 1024. in + Printf.sprintf "%.2f GB" gigabytes + + let string_of_message : t -> string = + fun t -> + let m = of_bytes_exn msg_t t in + match m with + | Request (FCommit_to_wires {index; content = _}) -> + Format.sprintf + "Commit_to_wires: %d (%s)" + index + (string_of_bytes @@ Bytes.length t) + | Reply (FCommit_to_wires_res {index; content = _}) -> + Format.sprintf + "Commit_to_wires_res: %d (%s)" + index + (string_of_bytes @@ Bytes.length t) + | Request (FCommit_to_plook {index; content = _}) -> + Format.sprintf + "Commit_to_plook: %d (%s)" + index + (string_of_bytes @@ Bytes.length t) + | Reply (FCommit_to_plook_res {index; content = _}) -> + Format.sprintf + "Commit_to_plook_res: %d (%s)" + index + (string_of_bytes @@ Bytes.length t) + | Request (FPP_prepare_ids {index; content = _}) -> + Format.sprintf + "PP_prepare_ids: %d (%s)" + index + (string_of_bytes @@ Bytes.length t) + | Reply (FPP_prepare_ids_res {index; content = _}) -> + Format.sprintf + "PP_prepare_ids_res: %d (%s)" + index + (string_of_bytes @@ Bytes.length t) + | Request (FPP_commit_to_t {index; content = _}) -> + Format.sprintf + "PP_commit_to_t: %d (%s)" + index + (string_of_bytes @@ Bytes.length t) + | Reply (FPP_commit_to_t_res {index; content = _}) -> + Format.sprintf + "PP_commit_to_t_res: %d (%s)" + index + (string_of_bytes @@ Bytes.length t) + | Request (FPP_KZG_eval_at_x {index; content = _}) -> + Format.sprintf + "PP_KZG_eval_at_x: %d (%s)" + index + (string_of_bytes @@ Bytes.length t) + | Reply (FPP_KZG_eval_at_x_res {index; content = _}) -> + Format.sprintf + "PP_KZG_eval_at_x_res: %d (%s)" + index + (string_of_bytes @@ Bytes.length t) + | Request (FPC_Distribution {index; content = _}) -> + Format.sprintf + "PC_Distribution: %d (%s)" + index + (string_of_bytes @@ Bytes.length t) + | Reply (FPC_Distribution_res {index; content = _}) -> + Format.sprintf + "PC_Distribution_res: %d (%s)" + index + (string_of_bytes @@ Bytes.length t) + end diff --git a/src/lib_distributed_plonk/communication/message.mli b/src/lib_distributed_plonk/communication/message.mli new file mode 100644 index 000000000000..56795ce87927 --- /dev/null +++ b/src/lib_distributed_plonk/communication/message.mli @@ -0,0 +1,99 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module type S = sig + (** Plonk Main Protocol *) + module MP : Plonk_for_distribution.Main_protocol.S + + (** Type witness for a protocol step. *) + type 'a step = + | S_ctw : [`Commit_to_wires] step + | S_ctp : [`Commit_to_plook] step + | S_pppi : [`PP_prepare_ids] step + | S_ppctt : [`PP_commit_to_t] step + | S_ppkeax : [`PP_kzg_eval_at_x] step + | S_pcd : [`PC_distribution] step + + (* All message payloads need to have an index, so that + they can be sorted back by the master. *) + type ctw_payload = {index : int; content : MP.worker_inputs Plonk.SMap.t} + + type ctpap_payload = {index : int; content : MP.PP.transcript} + + type pppi_payload = {index : int; content : MP.PP.transcript} + + type ppctt_payload = {index : int; content : string list * Plonk.Bls.Scalar.t} + + type ppkeax_payload = {index : int; content : MP.PP.transcript} + + type pcd_payload = {index : int; content : MP.PP.PC.worker_msg} + + type 'step request = + | Commit_to_wires : ctw_payload -> [`Commit_to_wires] request + | Commit_to_plook : ctpap_payload -> [`Commit_to_plook] request + | PP_prepare_ids : pppi_payload -> [`PP_prepare_ids] request + | PP_commit_to_t : ppctt_payload -> [`PP_commit_to_t] request + | PP_KZG_eval_at_x : ppkeax_payload -> [`PP_kzg_eval_at_x] request + | PC_Distribution : pcd_payload -> [`PC_distribution] request + + type ctw_res_payload = {index : int; content : MP.commit_to_wires_reply} + + type ctpap_res_payload = {index : int; content : MP.commit_to_plook_rc_reply} + + type pppi_res_payload = {index : int; content : string list} + + type ppctt_res_payload = {index : int; content : Plonk.Bls.Evaluations.t} + + type ppkeax_res_payload = {index : int; content : MP.PP.PC.answer list} + + type pcd_res_payload = {index : int; content : MP.PP.PC.main_prover_msg} + + type 'step reply = + | Commit_to_wires_res : ctw_res_payload -> [`Commit_to_wires] reply + | Commit_to_plook_res : ctpap_res_payload -> [`Commit_to_plook] reply + | PP_prepare_ids_res : pppi_res_payload -> [`PP_prepare_ids] reply + | PP_commit_to_t_res : ppctt_res_payload -> [`PP_commit_to_t] reply + | PP_KZG_eval_at_x_res : ppkeax_res_payload -> [`PP_kzg_eval_at_x] reply + | PC_Distribution_res : pcd_res_payload -> [`PC_distribution] reply + + type t = bytes + + val request_step : 'step request -> 'step step + + val of_request : 'a request -> t + + val of_reply : 'a reply -> t + + val to_request : 'step step -> t -> 'step request option + + val to_reply : 'step step -> t -> 'step reply option + + val index : t -> int + + val string_of_message : t -> string +end + +module Make : functor (MP : Plonk_for_distribution.Main_protocol.S) -> + S with module MP = MP -- GitLab From 4bcc4341f06057bc363300672e0158aa6dcacbed Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 15 Mar 2023 15:56:06 +0100 Subject: [PATCH 26/34] lib_distributed_plonk: import from privacy-team/cryptography --- .gitlab/ci/jobs/packaging/opam_package.yml | 2 + dune-project | 1 + manifest/main.ml | 13 +- opam/octez-distributed-plonk.opam | 22 + .../distributed_prover.ml | 472 ++++++++++++++++++ src/lib_distributed_plonk/dune | 16 + src/lib_distributed_plonk/filenames.ml | 5 + src/lib_distributed_plonk/master_runner.ml | 83 +++ src/lib_distributed_plonk/worker.ml | 176 +++++++ 9 files changed, 789 insertions(+), 1 deletion(-) create mode 100644 opam/octez-distributed-plonk.opam create mode 100644 src/lib_distributed_plonk/distributed_prover.ml create mode 100644 src/lib_distributed_plonk/dune create mode 100644 src/lib_distributed_plonk/filenames.ml create mode 100644 src/lib_distributed_plonk/master_runner.ml create mode 100644 src/lib_distributed_plonk/worker.ml diff --git a/.gitlab/ci/jobs/packaging/opam_package.yml b/.gitlab/ci/jobs/packaging/opam_package.yml index cdc53b39cbc1..a6574b4a622d 100644 --- a/.gitlab/ci/jobs/packaging/opam_package.yml +++ b/.gitlab/ci/jobs/packaging/opam_package.yml @@ -300,6 +300,8 @@ opam:octez-distributed-lwt-internal: variables: package: octez-distributed-lwt-internal +# Ignoring unreleased package octez-distributed-plonk. + # Ignoring unreleased package octez-evm-proxy. opam:octez-injector: diff --git a/dune-project b/dune-project index b3c21c99059a..ed419c8eacbd 100644 --- a/dune-project +++ b/dune-project @@ -21,6 +21,7 @@ (package (name octez-dal-node)) (package (name octez-distributed-internal)) (package (name octez-distributed-lwt-internal)) +(package (name octez-distributed-plonk)) (package (name octez-evm-proxy)) (package (name octez-injector)) (package (name octez-mec)) diff --git a/manifest/main.ml b/manifest/main.ml index 7a2729c4b2c8..1068b33f3afd 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1260,7 +1260,7 @@ let octez_plonk_distribution = ~deps:[octez_plonk; octez_plonk_aggregation] ~preprocess:[pps ppx_repr] -let _octez_plonk_communication = +let octez_plonk_communication = public_lib "octez-plonk.communication" ~internal_name:"communication" @@ -1268,6 +1268,17 @@ let _octez_plonk_communication = ~deps:[logs; distributed_internal_lwt; octez_plonk_distribution |> open_] ~preprocess:[pps ppx_repr] +let _octez_distributed_plonk = + public_lib + "octez-distributed-plonk" + ~internal_name:"distributed_plonk" + ~path:"src/lib_distributed_plonk" + ~synopsis:"Distributed version of the proving system" + ~deps:[octez_aplonk; octez_plonk_communication; octez_plonk |> open_] + ~modules:["distributed_prover"; "filenames"; "master_runner"; "worker"] + ~preprocess:[pps ppx_repr] + ~bisect_ppx:Yes + let octez_plonk_test_helpers = public_lib "octez-plonk.plonk-test" diff --git a/opam/octez-distributed-plonk.opam b/opam/octez-distributed-plonk.opam new file mode 100644 index 000000000000..412ccff51791 --- /dev/null +++ b/opam/octez-distributed-plonk.opam @@ -0,0 +1,22 @@ +# This file was automatically generated, do not edit. +# Edit file manifest/main.ml instead. +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: ["Tezos devteam"] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "3.0" } + "ocaml" { >= "4.14" } + "ppx_repr" { >= "0.6.0" } + "octez-aplonk" + "octez-plonk" +] +build: [ + ["rm" "-r" "vendors"] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Distributed version of the proving system" diff --git a/src/lib_distributed_plonk/distributed_prover.ml b/src/lib_distributed_plonk/distributed_prover.ml new file mode 100644 index 000000000000..539402385045 --- /dev/null +++ b/src/lib_distributed_plonk/distributed_prover.ml @@ -0,0 +1,472 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Bls +open Utils +open Identities +open Communication +module SMap = Plonk.SMap + +module type S = sig + module MP : Plonk.Main_protocol.S + + module Msg : Message.S + + module D : + Distributed_wrapper.Enriched_process + with type 'a M.step = 'a Msg.step + and type 'a M.request = 'a Msg.request + and type 'a M.reply = 'a Msg.reply + and type 'a io = 'a Lwt.t + + val distributed_prover_main : + workers:Distributed.Process_id.t list -> + inputs:MP.prover_inputs -> + MP.prover_public_parameters -> + MP.proof D.t +end + +module Make_common (MP : Plonk_for_distribution.Main_protocol.S) = struct + module MP = MP + module Msg = Message.Make (MP) + module D = Distributed_wrapper.Make (Msg) + + let pc_distributed_prove_main ~workers pp transcript query_list answers_list + secret_list prover_aux_list = + let open MP.PP in + let transcript = + PC.distributed_expand_transcript transcript query_list answers_list + in + let worker_message, state = + PC.distributed_prove_main1 + pp + transcript + query_list + answers_list + (secret_list @ [SMap.empty]) + (prover_aux_list @ [PC.Commitment.empty_prover_aux]) + in + let open D in + let request content ~index = Msg.PC_Distribution {index; content} in + let reply (Msg.PC_Distribution_res {content; _}) = + Some (fun () -> return content) + in + let* prover_messages = + dmap + ~pids:workers + ~request + ~reply + (List.init (List.length workers) (fun _ -> worker_message)) + in + return (PC.distributed_prove_main2 state prover_messages) + + let pp_distributed_prove_aux ~workers pc_public_parameters transcript ~n + ~generator ~secrets_main ~eval_points_main ~eval_points_worker + ~evaluated_perm_ids ~nb_of_t_chunks = + let open MP.PP in + let open D in + let module M = Msg in + let alpha, transcript = Fr_generation.random_fr transcript in + let* ids_keys = + dmap + ~pids:workers + ~request:(fun content ~index -> M.PP_prepare_ids {index; content}) + ~reply:(function + | M.PP_prepare_ids_res {content; _} -> Some (fun () -> return content)) + (List.map (Fun.const transcript) workers) + in + let perm_ids_keys, perm_ids = + List.split @@ SMap.bindings evaluated_perm_ids + in + let all_ids_keys = + List.concat (perm_ids_keys :: ids_keys) |> List.sort String.compare + in + let* batched_evaluated_ids_list = + dmap + ~pids:workers + ~request:(fun content ~index -> M.PP_commit_to_t {index; content}) + ~reply:(function + | M.PP_commit_to_t_res {content; _} -> Some (fun () -> return content)) + (List.map (Fun.const (all_ids_keys, alpha)) workers) + in + let batched_perm = + let powers_map = + SMap.of_list @@ List.mapi (fun i s -> (s, i)) all_ids_keys + in + let powers = + List.map (fun s -> SMap.find s powers_map) perm_ids_keys + |> List.map (fun i -> Scalar.pow alpha @@ Z.of_int i) + in + Evaluations.linear_c ~evaluations:perm_ids ~linear_coeffs:powers () + in + let batched_ids = + Evaluations.linear_c + ~evaluations:(batched_perm :: batched_evaluated_ids_list) + () + in + (* batched_ids contains just one element, so [alpha] will not be used in + the call to compute_t; this is intended *) + let t = + compute_t ~n ~alpha ~nb_of_t_chunks (SMap.singleton "batched" batched_ids) + in + let cm_t, t_prover_aux = PC.Commitment.commit pc_public_parameters t in + let transcript = Transcript.expand PC.Commitment.t cm_t transcript in + let* pc_answers_worker = + dmap + ~pids:workers + ~request:(fun content ~index -> M.PP_KZG_eval_at_x {index; content}) + ~reply:(function + | M.PP_KZG_eval_at_x_res {content; _} -> + Some (fun () -> return content)) + (List.init (List.length workers) (Fun.const transcript)) + in + let x, transcript = Fr_generation.random_fr transcript in + let prover_aux_list_main = t_prover_aux :: List.map snd secrets_main in + let polys_list_main = t :: List.map fst secrets_main in + let eval_points_main = [X] :: eval_points_main in + let query_list_main = + List.map (convert_eval_points ~generator ~x) eval_points_main + in + let query_list_worker = + List.map (convert_eval_points ~generator ~x) eval_points_worker + in + let pc_answers_main = + List.map2 PC.evaluate polys_list_main query_list_main + in + let answer_list = + pc_answers_main @ Plonk.List.mapn PC.merge_answers pc_answers_worker + in + return + ( (alpha, x, answer_list, cm_t), + polys_list_main, + prover_aux_list_main, + query_list_main @ query_list_worker, + transcript ) + + let pp_distributed_prove_main ~workers pc_public_parameters transcript + (generator, n, nb_of_t_chunks) ~secrets_main ~eval_points_main + ~eval_points_worker ~evaluated_perm_ids = + let open D in + let module M = Msg in + let* ( (_, _, answer_list, cm_t), + polys_list, + prover_aux_list, + query_list, + transcript ) = + pp_distributed_prove_aux + ~workers + pc_public_parameters + transcript + ~n + ~generator + ~secrets_main + ~eval_points_main + ~eval_points_worker + ~evaluated_perm_ids + ~nb_of_t_chunks + in + let* pc_proof, transcript, _aux = + pc_distributed_prove_main + ~workers + pc_public_parameters + transcript + query_list + answer_list + polys_list + prover_aux_list + in + return (MP.PP.{cm_t; pc_proof; pc_answers = answer_list}, transcript) + + let distributed_prover ~(workers : Distributed.Process_id.t list) ~pp_prove pp + ~inputs = + let open D in + let open MP in + let module M = Msg in + let nb_workers = List.length workers in + (* send the public inputs to the workers *) + let workers_inputs_map = split_inputs_map ~nb_workers inputs in + + let* replies0 = + dmap + ~pids:workers + ~request:(fun content ~index -> M.Commit_to_wires {index; content}) + ~reply:(fun (M.Commit_to_wires_res {content; _}) -> + Some (fun () -> return content)) + workers_inputs_map + in + let commitment_wires = PP.PC.Commitment.recombine replies0 in + + (* update the transcript with the commitment to wires *) + let transcript = + Transcript.expand PP.PC.Commitment.t commitment_wires (get_transcript pp) + in + let* replies = + dmap + ~pids:workers + ~request:(fun content ~index -> M.Commit_to_plook {index; content}) + ~reply:(fun (M.Commit_to_plook_res {content; _}) -> + Some (fun () -> return content)) + (List.init nb_workers (Fun.const transcript)) + in + let* _ = lift_io @@ Lwt_io.flush_all () in + + let randomness, transcript = build_gates_randomness transcript in + + let f_map_perm, evaluated_perm_ids, (cmt_perm, perm_prover_aux) = + shared_perm_argument pp nb_workers randomness inputs replies + in + + let cmt_plook = + PP.PC.Commitment.recombine (List.map (fun r -> r.cmt) replies) + in + let cmt_perm_and_plook = PP.PC.Commitment.recombine [cmt_plook; cmt_perm] in + (* update the transcript with the commitment to perm and plook *) + let transcript = + Transcript.expand PP.PC.Commitment.t cmt_perm_and_plook transcript + in + let f_map_plook = + SMap.union_disjoint_list (List.map (fun r -> r.f_map) replies) + in + let f_perm_and_plook_map = SMap.union_disjoint f_map_perm f_map_plook in + let perm_and_plook_prover_aux = + PP.PC.Commitment.recombine_prover_aux + (perm_prover_aux :: List.map (fun r -> r.prover_aux) replies) + in + let secrets_main = + make_secret pp (f_perm_and_plook_map, perm_and_plook_prover_aux) + in + let eval_points_main, eval_points_worker = make_eval_points pp in + + let params = get_gen_n_nbt pp in + let* pp_proof, transcript = + pp_prove + ~workers + (get_srs pp) + transcript + params + ~secrets_main + ~eval_points_main + ~eval_points_worker + ~evaluated_perm_ids + in + let* () = lift_io @@ Lwt_io.(flush stdout) in + return + ( pp_proof, + transcript, + ( cmt_perm_and_plook, + commitment_wires, + randomness.beta_perm, + randomness.gamma_perm, + randomness.delta ) ) + + let distributed_prover_main ~workers ~inputs + (pp : MP.prover_public_parameters) = + let open D in + let open MP in + check_no_zk pp ; + let pp = filter_prv_pp_circuits pp inputs in + let pp = + update_prover_public_parameters + (hash_verifier_inputs (to_verifier_inputs pp inputs)) + pp + in + let* pp_proof, _transcript, (perm_and_plook, wires_cm, _, _, _) = + distributed_prover ~workers ~pp_prove:pp_distributed_prove_main pp ~inputs + in + return {perm_and_plook; wires_cm; pp_proof} +end + +module PC_Kzg = Plonk_for_distribution.Kzg_pack.Kzg_pack_impl +module PP_Kzg = Plonk_for_distribution.Polynomial_protocol.Make (PC_Kzg) +module Main_Kzg = Plonk_for_distribution.Main_protocol.Make (PP_Kzg) +module PC_Pack = Plonk_for_distribution.Kzg_pack.Kzg_pack_impl +module PP_Pack = + Plonk_for_distribution.Polynomial_protocol.MakeSuper + (PC_Pack) + (Main_Kzg.Input_commitment) +module Main_Pack = Plonk_for_distribution.Main_protocol.MakeSuper (PP_Pack) +module Make_aPlonk = Aplonk.Main_protocol.Make_impl (Main_Kzg) (Main_Pack) + +module Super_impl (PI : Aplonk.Pi_parameters.S) = struct + module MP = Make_aPlonk (PI) + module Common = Make_common (Main_Pack) + module D = Common.D + module Msg = Common.Msg + open PC_Pack + + let pc_distributed_prove_super_aggregation_main ~workers + (pp : Public_parameters.prover) transcript query_list answers_list + secret_list (prover_aux_list : Commitment.prover_aux list) = + let open Common in + let transcript = Transcript.list_expand query_t query_list transcript in + let worker_message, state = + distributed_prove_main1 + pp + transcript + query_list + answers_list + (secret_list @ [SMap.empty]) + (prover_aux_list @ [Commitment.empty_prover_aux]) + in + let open D in + let request content ~index = Msg.PC_Distribution {index; content} in + let reply (Msg.PC_Distribution_res {content; _}) = + Some (fun () -> return content) + in + let* prover_messages = + dmap + ~pids:workers + ~request + ~reply + (List.init (List.length workers) (fun _ -> worker_message)) + in + let proof, transcript, {s_list; r} = + distributed_prove_main2 state prover_messages + in + return (proof, s_list, r, transcript) + + let pp_distributed_prove_super_aggregation_main ~workers pc_public_parameters + transcript (generator, n, nb_of_t_chunks) ~commit_to_answers_map + ~secrets_main ~eval_points_main ~eval_points_worker ~evaluated_perm_ids = + let open Common in + let open D in + let open PP_Pack in + let module M = Msg in + let* ( (alpha, x, answer_list, cm_t), + polys_list, + prover_aux_list, + query_list, + transcript ) = + pp_distributed_prove_aux + ~workers + pc_public_parameters + transcript + ~n + ~generator + ~secrets_main + ~eval_points_main + ~eval_points_worker + ~evaluated_perm_ids + ~nb_of_t_chunks + in + let t_answers, cms_answers, transcript = + update_transcript_with_formatted_answers + transcript + commit_to_answers_map + answer_list + in + let* pc_proof, s_list, r, transcript = + pc_distributed_prove_super_aggregation_main + ~workers + pc_public_parameters + transcript + query_list + answer_list + polys_list + prover_aux_list + in + return + ( PP_Pack. + ( {cm_t; pc_proof; pc_answers = []}, + { + answers = answer_list; + batch = s_list; + alpha; + x; + r; + cms_answers; + t_answers; + } ), + transcript ) + + let distributed_prove_super_aggregation ~workers + (pp : Main_Pack.prover_public_parameters) ~input_commit_infos ~inputs = + let open Common in + let open Main_Pack in + let open D in + (* TODO: can we commit only to the hidden pi?*) + let public_inputs_map, cms_pi = hash_pi pp input_commit_infos inputs in + (* add the PI in the transcript *) + let pp = update_prv_pp_transcript_with_pi pp cms_pi in + let commit_to_answers_map = commit_to_answers_map input_commit_infos in + let* ( (pp_proof, PP.{answers; batch; alpha; x; r; cms_answers; t_answers}), + _transcript, + (perm_and_plook, wires_cm, beta, gamma, delta) ) = + distributed_prover + ~workers + ~pp_prove: + (pp_distributed_prove_super_aggregation_main ~commit_to_answers_map) + pp + ~inputs + in + let ids_batch = + (* FIXME: generalize to plookup & RC *) + let rd = + { + beta_perm = beta; + gamma_perm = gamma; + beta_plook = Scalar.one; + gamma_plook = Scalar.one; + beta_rc = Scalar.one; + gamma_rc = Scalar.one; + delta; + } + in + compute_ids_batch pp rd alpha x public_inputs_map answers cms_answers + in + return + ( {perm_and_plook; wires_cm; pp_proof}, + { + answers; + batch; + alpha; + beta; + gamma; + delta; + x; + r; + cms_answers; + cms_pi; + ids_batch; + t_answers; + } ) + + let distributed_prover_main ~workers ~(inputs : MP.prover_inputs) + (pp : MP.prover_public_parameters) = + let open MP in + let open D in + let* distributed_proof = + distributed_prove_super_aggregation + ~workers + pp.main_pp + ~input_commit_infos:(input_commit_infos pp) + ~inputs + in + return (meta_proof pp inputs distributed_proof) +end + +module Make (MP : Plonk_for_distribution.Main_protocol.S) : S = Make_common (MP) + +module Super (PI : Aplonk.Pi_parameters.S) : S = Super_impl (PI) diff --git a/src/lib_distributed_plonk/dune b/src/lib_distributed_plonk/dune new file mode 100644 index 000000000000..b1b1962d8b21 --- /dev/null +++ b/src/lib_distributed_plonk/dune @@ -0,0 +1,16 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name distributed_plonk) + (public_name octez-distributed-plonk) + (instrumentation (backend bisect_ppx)) + (libraries + octez-aplonk + octez-plonk.communication + octez-plonk) + (preprocess (pps ppx_repr)) + (flags + (:standard) + -open Plonk) + (modules distributed_prover filenames master_runner worker)) diff --git a/src/lib_distributed_plonk/filenames.ml b/src/lib_distributed_plonk/filenames.ml new file mode 100644 index 000000000000..270271e25961 --- /dev/null +++ b/src/lib_distributed_plonk/filenames.ml @@ -0,0 +1,5 @@ +(* names for the public parameters files used for tests *) + +let plonk_pp_file = "pp" + +let meta_pp_file = "pp_meta" diff --git a/src/lib_distributed_plonk/master_runner.ml b/src/lib_distributed_plonk/master_runner.ml new file mode 100644 index 000000000000..097047bb2797 --- /dev/null +++ b/src/lib_distributed_plonk/master_runner.ml @@ -0,0 +1,83 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) +open Communication.Distributed_wrapper + +module Make (D : Enriched_process with type 'a io = 'a Lwt.t) : sig + type node = {name : string; ip : string; port : int} + + type 'a master_task := workers:Distributed.Process_id.t list -> 'a D.t + + val run : self_node:node -> nodes:node list -> 'a master_task -> 'a +end = struct + type node = {name : string; ip : string; port : int} + + let master_config ~ip ~port ~nodes = + D.Remote + { + D.Remote_config.node_name = "master"; + D.Remote_config.local_port = port; + D.Remote_config.connection_backlog = 10; + D.Remote_config.node_ip = ip; + D.Remote_config.remote_nodes = nodes; + } + + let master_proc m ~ret () = + let open D in + let* nodes = get_remote_nodes in + let* pid_to_send_to = get_self_pid in + (* Dummy worker process in the master *) + (* FIXME: why do we need this? *) + let* () = register "worker" (fun _pid () -> D.return ()) in + (* spawn and monitor a process on the remote node atomically *) + let* remote_pids = + mapM + (fun n -> + let+ pid, _ref = + spawn ~monitor:true n (Registered "worker") pid_to_send_to + in + pid) + nodes + in + let+ r = m ~workers:remote_pids in + ret := Some r ; + () + + let run ~self_node ~nodes m = + let logs_level = + Option.bind (Sys.getenv_opt "DP_LOGS") (fun s -> + Result.get_ok @@ Logs.level_of_string s) + in + Logs.Src.set_level Logger.log_src logs_level ; + Logs.set_reporter @@ Logger.lwt_reporter () ; + let ret = ref None in + Lwt_main.run + (D.run_node + ~process:(master_proc m ~ret) + (master_config + ~ip:self_node.ip + ~port:self_node.port + ~nodes:(List.map (fun n -> (n.ip, n.port, n.name)) nodes))) ; + Option.get !ret +end diff --git a/src/lib_distributed_plonk/worker.ml b/src/lib_distributed_plonk/worker.ml new file mode 100644 index 000000000000..ebddabf4b8fc --- /dev/null +++ b/src/lib_distributed_plonk/worker.ml @@ -0,0 +1,176 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Communication + +module type S = sig + module Msg : Message.S + + module D : + Distributed_wrapper.Enriched_process + with type 'a M.step = 'a Msg.step + and type 'a M.request = 'a Msg.request + and type 'a M.reply = 'a Msg.reply + and type 'a io = 'a Lwt.t + + val worker_proc : string -> Distributed.Process_id.t -> unit -> 'a D.t +end + +module Make (Main : Plonk_for_distribution.Main_protocol.S) : S = struct + module Msg = Message.Make (Main) + module D = Distributed_wrapper.Make (Msg) + open Main + + (** + Worker loop. + Implements the worker side of the proving protocol. + *) + let worker_proc pp_file main_pid () = + let open D in + let* () = lift_io @@ Lwt_io.printlf "Spawn" in + let* fd = lift_io Lwt_io.(open_file ~mode:Input pp_file) in + let* () = lift_io @@ Lwt_io.printlf "Open PP file" in + let* s = lift_io @@ Lwt_io.read fd in + let* () = lift_io @@ Lwt_io.printlf "Read PP file" in + let pp = + Plompiler.Utils.of_bytes prover_public_parameters_t (Bytes.of_string s) + in + let* () = lift_io @@ Lwt_io.close fd in + let* () = lift_io @@ Lwt_io.printlf "Loaded PP\n" in + let rec loop () = + let* { + all_f_wires; + wires_list_map; + inputs_map; + shifts_map; + cm_aux_wires; + _; + } = + handle_request + main_pid + ~step:Msg.S_ctw + ~handler:(fun (Msg.Commit_to_wires {index; content}) -> + Some + (fun () -> + let content, rem = worker_commit_to_wires pp content in + return (Msg.Commit_to_wires_res {index; content}, rem))) + in + let* {f_map; _}, {beta_plook; gamma_plook; beta_rc; gamma_rc} = + handle_request + main_pid + ~step:Msg.S_ctp + ~handler:(fun (Msg.Commit_to_plook {index; content}) -> + Some + (fun () -> + let reply, rem = + commit_to_plook_rc pp shifts_map content wires_list_map + in + return + ( Msg.Commit_to_plook_res {index; content = reply}, + (reply, rem) ))) + in + let evaluations = + Prover.build_evaluations pp (SMap.union_disjoint all_f_wires f_map) + in + let identities = + Prover.build_gates_plook_rc_identities + ~shifts_map + pp + { + beta_plook; + gamma_plook; + beta_rc; + gamma_rc; + beta_perm = Bls.Scalar.zero; + gamma_perm = Bls.Scalar.zero; + delta = Bls.Scalar.zero; + } + inputs_map + in + let evaluated_ids = identities evaluations in + let ids_keys = SMap.bindings evaluated_ids |> List.map fst in + let* _transcript = + handle_request + main_pid + ~step:Msg.S_pppi + ~handler:(fun (Msg.PP_prepare_ids {index; content = transcript}) -> + Some + (fun () -> + return + ( Msg.PP_prepare_ids_res {index; content = ids_keys}, + transcript ))) + in + let* () = + handle_request + main_pid + ~step:Msg.S_ppctt + ~handler:(fun + (Msg.PP_commit_to_t {index; content = all_ids_keys, alpha}) + -> + Some + (fun () -> + let batched_ids = + batch_evaluated_ids ~alpha evaluated_ids all_ids_keys + in + return + (Msg.PP_commit_to_t_res {index; content = batched_ids}, ()))) + in + let generator, _, _ = get_gen_n_nbt pp in + let* () = + handle_request + main_pid + ~step:Msg.S_ppkeax + ~handler:(fun (Msg.PP_KZG_eval_at_x {index; content = transcript}) -> + Some + (fun () -> + let secrets_worker = [(all_f_wires, cm_aux_wires)] in + let r = kzg_eval_at_x pp transcript secrets_worker generator in + return (Msg.PP_KZG_eval_at_x_res {index; content = r}, ()))) + in + let* () = + (* The next two functions are used to pad the query to + [distributed_prover_worker] with dummy values in the positions that + the worker does not have information about, namely, those of: + t_map, g_map, plook_map, which are ATM handled by the main thread *) + let pad_secrets l = (List.init 3 @@ Fun.const SMap.empty) @ l in + let pad_prover_aux l = + (List.init 3 @@ Fun.const PP.PC.Commitment.empty_prover_aux) @ l + in + handle_request main_pid ~step:Msg.S_pcd ~handler:(function + | Msg.PC_Distribution {index; content = worker_msg} -> + Some + (fun () -> + let secrets = pad_secrets [all_f_wires] in + let prover_aux = pad_prover_aux [cm_aux_wires] in + let prvr_main_msg = + PP.PC.distributed_prove_worker secrets prover_aux worker_msg + in + return + (Msg.PC_Distribution_res {index; content = prvr_main_msg}, ()))) + in + loop () + in + loop () +end -- GitLab From 979ca34d5c118c6f0b4c1886e1cc6b3abbac84ff Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 15 Mar 2023 16:26:46 +0100 Subject: [PATCH 27/34] lib_distributed_plonk test: import from privacy-team/cryptography --- manifest/main.ml | 51 +++++- opam/octez-distributed-plonk.opam | 1 + src/lib_distributed_plonk/dune | 7 + .../test/distribution_helpers.ml | 155 ++++++++++++++++++ src/lib_distributed_plonk/test/dune | 25 +++ 5 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 src/lib_distributed_plonk/test/distribution_helpers.ml create mode 100644 src/lib_distributed_plonk/test/dune diff --git a/manifest/main.ml b/manifest/main.ml index 1068b33f3afd..547a239ebd0b 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1268,7 +1268,7 @@ let octez_plonk_communication = ~deps:[logs; distributed_internal_lwt; octez_plonk_distribution |> open_] ~preprocess:[pps ppx_repr] -let _octez_distributed_plonk = +let octez_distributed_plonk = public_lib "octez-distributed-plonk" ~internal_name:"distributed_plonk" @@ -1439,6 +1439,55 @@ let _octez_plonk_test_plompiler_main = ]); ] +let octez_distributed_plonk_test = + private_lib + "distributed_plonk_test" + ~opam:"octez-distributed-plonk" + ~path:"src/lib_distributed_plonk/test" + ~deps: + [ + octez_distributed_plonk; + octez_plonk; + octez_plonk_aggregation; + octez_plonk_distribution; + octez_plonk_test_helpers; + octez_aplonk; + ] + ~modules:["distribution_helpers"] + ~bisect_ppx:No + +let _octez_distributed_plonk_test_main = + private_exe + "main" + ~path:"src/lib_distributed_plonk/test" + ~opam:"octez-distributed-plonk" + ~bisect_ppx:No + ~deps: + [ + octez_distributed_plonk_test; + octez_distributed_plonk; + octez_plonk_test_helpers; + qcheck_alcotest; + ] + ~modules:["main"; "test_distribution"] + ~dune: + Dune. + [ + alias_rule + "runtest" + ~package:"octez-plonk" + ~action:[S "run"; S "%{exe:main.exe}"]; + ] + +let _octez_distributed_plonk_worker_runner = + private_exe + "worker_runner" + ~path:"src/lib_distributed_plonk" + ~opam:"octez-distributed-plonk" + ~bisect_ppx:No + ~deps:[octez_distributed_plonk; octez_plonk_distribution] + ~modules:["worker_runner"] + let _octez_aplonk_test_main = private_exe "main" diff --git a/opam/octez-distributed-plonk.opam b/opam/octez-distributed-plonk.opam index 412ccff51791..527059c38af3 100644 --- a/opam/octez-distributed-plonk.opam +++ b/opam/octez-distributed-plonk.opam @@ -13,6 +13,7 @@ depends: [ "ppx_repr" { >= "0.6.0" } "octez-aplonk" "octez-plonk" + "qcheck-alcotest" { >= "0.20" } ] build: [ ["rm" "-r" "vendors"] diff --git a/src/lib_distributed_plonk/dune b/src/lib_distributed_plonk/dune index b1b1962d8b21..5c299a0048fa 100644 --- a/src/lib_distributed_plonk/dune +++ b/src/lib_distributed_plonk/dune @@ -14,3 +14,10 @@ (:standard) -open Plonk) (modules distributed_prover filenames master_runner worker)) + +(executable + (name worker_runner) + (libraries + octez-distributed-plonk + octez-plonk.distribution) + (modules worker_runner)) diff --git a/src/lib_distributed_plonk/test/distribution_helpers.ml b/src/lib_distributed_plonk/test/distribution_helpers.ml new file mode 100644 index 000000000000..57ad0fec2f6d --- /dev/null +++ b/src/lib_distributed_plonk/test/distribution_helpers.ml @@ -0,0 +1,155 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk_test +open Helpers +open Distributed_plonk + +let nb_proofs = 12 + +let circuit_size = 4 + +module Scalar = Plonk.Bls.Scalar +(* open Helpers *) + +module Port : sig + val make : unit -> int +end = struct + let port = ref 50000 + + let make () = + let p = !port in + port := p + 1 ; + p +end + +module type DP_for_tests = sig + include Distributed_prover.S + + module Worker_Main : Plonk_for_distribution.Main_protocol.S + + val pp_file : string + + val get_distributed_pp : MP.prover_public_parameters -> bytes +end + +module DP_PlonK (Main : Plonk_for_distribution.Main_protocol.S) = struct + include Distributed_prover.Make (Main) + module Worker_Main = Main + + let pp_file = Distributed_plonk.Filenames.plonk_pp_file + + let get_distributed_pp pp_prover = + Plompiler.Utils.to_bytes MP.prover_public_parameters_t pp_prover +end + +module DP_aPlonk (PI : Aplonk.Pi_parameters.S) = struct + include Distributed_prover.Super_impl (PI) + module Worker_Main = Distributed_prover.Main_Pack + + let pp_file = Distributed_plonk.Filenames.meta_pp_file + + let get_distributed_pp pp_prover = + let ({main_pp; _} : MP.prover_public_parameters) = pp_prover in + Plompiler.Utils.to_bytes + Distributed_prover.Main_Pack.prover_public_parameters_t + main_pp +end + +module No_public_input_PIs = struct + let get_pi_module _ = + (module Aplonk.Pi_parameters.No_public_input + : Aplonk.Pi_parameters.CircuitPI) +end + +module DP_Kzg = DP_PlonK (Distributed_prover.Main_Kzg) +module DP_Pack = DP_PlonK (Distributed_prover.Main_Pack) +module DP_Meta = DP_aPlonk (No_public_input_PIs) + +let srs = srs + +let circuits_inputs nb_proofs k = + let open Cases in + let _, circuit_map, witness, _ = + Big_circuit.make ~nb_proofs ~public_input_size:2 ~k |> aggregate_cases + in + (* FIXME Multicircuit with Meta-PlonK doesn’t work *) + (* let circuit_map = + Plonk.SMap.(union_disjoint circuit_map (update_keys (fun i -> i ^ "2") circuit_map)) + in *) + (circuit_map, witness) + +module Helpers (DP : DP_for_tests) = struct + module MP = DP.MP + module Runner = Master_runner.Make (DP.D) + + let parse_nodes s = + (* Expected as ip:port;ip:port... *) + let node_strings = String.split_on_char ',' s in + List.mapi + (fun i ns -> + let n = String.split_on_char ':' ns in + Runner. + { + ip = List.hd n; + port = int_of_string @@ List.nth n 1; + name = "worker" ^ string_of_int i; + }) + node_strings + + let run_master ?nb_proofs ?(k = circuit_size) ~self_node ~nodes () = + let nb_proofs = + match nb_proofs with None -> List.length nodes | Some n -> n + in + let circuit_map, x_map = circuits_inputs nb_proofs k in + let pp_prover, pp_verifier = + MP.setup ~zero_knowledge:false circuit_map ~srs + in + let oc = open_out DP.pp_file in + let b = DP.get_distributed_pp pp_prover in + output_bytes oc b ; + close_out oc ; + let inputs = + Plonk.SMap.map + (List.map (fun witness -> MP.{witness; input_commitments = []})) + x_map + in + let verifier_inputs = MP.to_verifier_inputs pp_prover inputs in + + let t1 = Unix.gettimeofday () in + + let proof = + Runner.run + ~self_node + ~nodes + DP.(distributed_prover_main ~inputs pp_prover) + in + let t2 = Unix.gettimeofday () in + Printf.printf "Prover time: %4.2f\n" (t2 -. t1) ; + let b = + try MP.verify pp_verifier ~inputs:verifier_inputs proof with _e -> false + in + Printf.printf "Verified: %b\n" b +end diff --git a/src/lib_distributed_plonk/test/dune b/src/lib_distributed_plonk/test/dune new file mode 100644 index 000000000000..bc2d2050cd27 --- /dev/null +++ b/src/lib_distributed_plonk/test/dune @@ -0,0 +1,25 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name distributed_plonk_test) + (package octez-distributed-plonk) + (libraries + octez-distributed-plonk + octez-plonk + octez-plonk.aggregation + octez-plonk.distribution + octez-plonk.plonk-test + octez-aplonk) + (modules distribution_helpers)) + +(executable + (name main) + (libraries + distributed_plonk_test + octez-distributed-plonk + octez-plonk.plonk-test + qcheck-alcotest) + (modules main test_distribution)) + +(rule (alias runtest) (package octez-plonk) (action (run %{exe:main.exe}))) -- GitLab From 9bab8e1d07e2ea59b165feb384604562a6f9f5c7 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 15 Mar 2023 16:33:32 +0100 Subject: [PATCH 28/34] lib_distributed_plonk test main: import from privacy-team/cryptography --- manifest/main.ml | 2 +- src/lib_distributed_plonk/test/dune | 5 +- src/lib_distributed_plonk/test/main.ml | 34 +++++ .../test/test_distribution.ml | 144 ++++++++++++++++++ 4 files changed, 183 insertions(+), 2 deletions(-) create mode 100644 src/lib_distributed_plonk/test/main.ml create mode 100644 src/lib_distributed_plonk/test/test_distribution.ml diff --git a/manifest/main.ml b/manifest/main.ml index 547a239ebd0b..2a8bc8bcaf77 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1475,7 +1475,7 @@ let _octez_distributed_plonk_test_main = [ alias_rule "runtest" - ~package:"octez-plonk" + ~package:"octez-distributed-plonk" ~action:[S "run"; S "%{exe:main.exe}"]; ] diff --git a/src/lib_distributed_plonk/test/dune b/src/lib_distributed_plonk/test/dune index bc2d2050cd27..c80de7f6b60b 100644 --- a/src/lib_distributed_plonk/test/dune +++ b/src/lib_distributed_plonk/test/dune @@ -22,4 +22,7 @@ qcheck-alcotest) (modules main test_distribution)) -(rule (alias runtest) (package octez-plonk) (action (run %{exe:main.exe}))) +(rule + (alias runtest) + (package octez-distributed-plonk) + (action (run %{exe:main.exe}))) diff --git a/src/lib_distributed_plonk/test/main.ml b/src/lib_distributed_plonk/test/main.ml new file mode 100644 index 000000000000..f93374e18ee7 --- /dev/null +++ b/src/lib_distributed_plonk/test/main.ml @@ -0,0 +1,34 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk_test + +let () = + Helpers.with_seed (fun () -> + Helpers.with_output_to_file (fun () -> + Alcotest.run + ~verbose:false + "Distributed PlonK" + [("Distribution", Test_distribution.tests)])) diff --git a/src/lib_distributed_plonk/test/test_distribution.ml b/src/lib_distributed_plonk/test/test_distribution.ml new file mode 100644 index 000000000000..70d1739a460c --- /dev/null +++ b/src/lib_distributed_plonk/test/test_distribution.ml @@ -0,0 +1,144 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Distributed_plonk_test.Distribution_helpers +open Distributed_plonk + +let test_distribution dp () = + let module DP = (val dp : DP_for_tests) in + let module Worker0 = Worker.Make (DP.Worker_Main) in + let module Worker1 = Worker.Make (DP.Worker_Main) in + let module Master = DP.D in + let loopback = "127.0.0.1" in + let master_port = Port.make () in + let worker0_port = Port.make () in + let worker1_port = Port.make () in + let worker0_config = + let open Worker0.D in + Remote + { + Remote_config.node_name = "worker0"; + Remote_config.local_port = worker0_port; + Remote_config.connection_backlog = 10; + Remote_config.node_ip = loopback; + Remote_config.remote_nodes = []; + } + in + let worker1_config = + let open Worker1.D in + Remote + { + Remote_config.node_name = "worker1"; + Remote_config.local_port = worker1_port; + Remote_config.connection_backlog = 10; + Remote_config.node_ip = loopback; + Remote_config.remote_nodes = []; + } + in + let master_config = + let open Master in + Remote + { + Remote_config.node_name = "master"; + Remote_config.local_port = master_port; + Remote_config.connection_backlog = 10; + Remote_config.node_ip = loopback; + Remote_config.remote_nodes = + [ + (loopback, worker0_port, "worker0"); + (loopback, worker1_port, "worker1"); + ]; + } + in + let circuit_map, x_map = circuits_inputs nb_proofs circuit_size in + let pp_prover, pp_verifier = + DP.MP.setup ~zero_knowledge:false circuit_map ~srs + in + let b = DP.get_distributed_pp pp_prover in + let oc = open_out DP.pp_file in + output_bytes oc b ; + close_out oc ; + let inputs = + Plonk.SMap.map + (List.map (fun witness -> DP.MP.{witness; input_commitments = []})) + x_map + in + let master_proc m ~ret () = + let open Master in + let* nodes = get_remote_nodes in + let* pid_to_send_to = get_self_pid in + (* Dummy worker process in the master *) + let* () = register "worker" (fun _pid () -> return ()) in + (* spawn and monitor a process on the remote node atomically *) + let* remote_pids = + mapM + (fun n -> + let+ pid, _ref = + spawn ~monitor:true n (Registered "worker") pid_to_send_to + in + pid) + nodes + in + let+ r = m ~workers:remote_pids in + ret := Some r ; + () + in + let ret = ref None in + Lwt.async (fun () -> + Worker0.D.run_node + ~process:(fun () -> + Worker0.D.register "worker" Worker0.(worker_proc DP.pp_file)) + worker0_config) ; + Lwt.async (fun () -> + Worker1.D.run_node + ~process:(fun () -> + Worker1.D.register "worker" Worker1.(worker_proc DP.pp_file)) + worker1_config) ; + Lwt_main.run + (let open Master_runner.Make (Master) in + Master.run_node + ~process:(master_proc DP.(distributed_prover_main ~inputs pp_prover) ~ret) + master_config) ; + let proof = Option.get !ret in + let verifier_inputs = DP.MP.to_verifier_inputs pp_prover inputs in + assert (DP.MP.verify pp_verifier ~inputs:verifier_inputs proof) + +module Rollup_example_PIs = struct + let get_pi_module _ = + (module Aplonk.Pi_parameters.Rollup_example : Aplonk.Pi_parameters.CircuitPI) +end + +module DP_Kzg = DP_PlonK (Distributed_prover.Main_Kzg) +module DP_Pack = DP_PlonK (Distributed_prover.Main_Pack) +module DP_Meta = DP_aPlonk (Rollup_example_PIs) + +let tests = + List.map + (fun (name, f) -> Alcotest.test_case name `Quick f) + [ + ("test_distribution_kzg", test_distribution (module DP_Kzg)); + ("test_distribution_kzg_pack", test_distribution (module DP_Pack)); + ("test_distribution_meta", test_distribution (module DP_Meta)); + ] -- GitLab From 353a504de761ce46fa6be1c52c50b3176980e413 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Wed, 15 Mar 2023 18:07:36 +0100 Subject: [PATCH 29/34] lib_distributed_plonk worker_runner: import from privacy-team/cryptography --- src/lib_distributed_plonk/worker_runner.ml | 70 ++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 src/lib_distributed_plonk/worker_runner.ml diff --git a/src/lib_distributed_plonk/worker_runner.ml b/src/lib_distributed_plonk/worker_runner.ml new file mode 100644 index 000000000000..a91bcfb6df71 --- /dev/null +++ b/src/lib_distributed_plonk/worker_runner.ml @@ -0,0 +1,70 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Distributed_plonk +open Communication +module Plonk_Worker = Worker.Make (Distributed_prover.Main_Kzg) +module APlonk_Worker = Worker.Make (Distributed_prover.Main_Pack) + +(** Executable for running a worker. *) + +let () = + let logs_level = + Option.bind (Sys.getenv_opt "DP_LOGS") (fun s -> + Result.get_ok @@ Logs.level_of_string s) + in + let args = Sys.argv in + (* set the log level and the reporter*) + Logs.Src.set_level Distributed_wrapper.Logger.log_src logs_level ; + Logs.set_reporter @@ Distributed_wrapper.Logger.lwt_reporter () ; + let ip = args.(1) in + let port = int_of_string args.(2) in + let name = args.(3) in + let plonk_or_aplonk = args.(4) in + let (module Worker : Worker.S), pp_file = + match plonk_or_aplonk with + | "plonk" -> + ((module Plonk_Worker), Distributed_plonk.Filenames.plonk_pp_file) + | "aplonk" -> + ((module APlonk_Worker), Distributed_plonk.Filenames.meta_pp_file) + | _ -> failwith "prover_worker : args.(4) must be 'plonk' or 'aplonk'" + in + let module D = Worker.D in + let worker_config ~ip ~port ~name = + D.Remote + { + D.Remote_config.node_name = name; + D.Remote_config.local_port = port; + D.Remote_config.connection_backlog = 10; + D.Remote_config.node_ip = ip; + D.Remote_config.remote_nodes = []; + } + in + Lwt.( + Lwt_main.run + ( D.run_node + ~process:(fun () -> D.register "worker" (Worker.worker_proc pp_file)) + (worker_config ~ip ~port ~name) + >>= fun () -> fst @@ wait () )) -- GitLab From ca383f009a5a9aa4172b66572eb3ad77ff23469f Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Fri, 17 Mar 2023 11:31:42 +0100 Subject: [PATCH 30/34] lib_epoxy_tx: import from privacy-team/cryptography --- .gitlab/ci/jobs/packaging/opam_package.yml | 2 + dune-project | 1 + manifest/main.ml | 53 + opam/octez-epoxy-tx.opam | 25 + src/lib_epoxy_tx/constants.ml | 88 + src/lib_epoxy_tx/dune | 13 + src/lib_epoxy_tx/test/benchmark.ml | 131 ++ src/lib_epoxy_tx/test/censorship.ml | 264 +++ src/lib_epoxy_tx/test/dune | 29 + src/lib_epoxy_tx/test/helpers.ml | 81 + src/lib_epoxy_tx/test/invalidTx.ml | 307 +++ src/lib_epoxy_tx/test/main.ml | 39 + src/lib_epoxy_tx/test/randomTx.ml | 67 + src/lib_epoxy_tx/test/test-quick.expected | 60 + src/lib_epoxy_tx/test/test-slow.expected | 204 ++ src/lib_epoxy_tx/tx_rollup.ml | 2114 ++++++++++++++++++++ src/lib_epoxy_tx/types.ml | 687 +++++++ src/lib_epoxy_tx/utils.ml | 63 + 18 files changed, 4228 insertions(+) create mode 100644 opam/octez-epoxy-tx.opam create mode 100644 src/lib_epoxy_tx/constants.ml create mode 100644 src/lib_epoxy_tx/dune create mode 100644 src/lib_epoxy_tx/test/benchmark.ml create mode 100644 src/lib_epoxy_tx/test/censorship.ml create mode 100644 src/lib_epoxy_tx/test/dune create mode 100644 src/lib_epoxy_tx/test/helpers.ml create mode 100644 src/lib_epoxy_tx/test/invalidTx.ml create mode 100644 src/lib_epoxy_tx/test/main.ml create mode 100644 src/lib_epoxy_tx/test/randomTx.ml create mode 100644 src/lib_epoxy_tx/test/test-quick.expected create mode 100644 src/lib_epoxy_tx/test/test-slow.expected create mode 100644 src/lib_epoxy_tx/tx_rollup.ml create mode 100644 src/lib_epoxy_tx/types.ml create mode 100644 src/lib_epoxy_tx/utils.ml diff --git a/.gitlab/ci/jobs/packaging/opam_package.yml b/.gitlab/ci/jobs/packaging/opam_package.yml index a6574b4a622d..761308813be4 100644 --- a/.gitlab/ci/jobs/packaging/opam_package.yml +++ b/.gitlab/ci/jobs/packaging/opam_package.yml @@ -302,6 +302,8 @@ opam:octez-distributed-lwt-internal: # Ignoring unreleased package octez-distributed-plonk. +# Ignoring unreleased package octez-epoxy-tx. + # Ignoring unreleased package octez-evm-proxy. opam:octez-injector: diff --git a/dune-project b/dune-project index ed419c8eacbd..697e27c2f4a9 100644 --- a/dune-project +++ b/dune-project @@ -22,6 +22,7 @@ (package (name octez-distributed-internal)) (package (name octez-distributed-lwt-internal)) (package (name octez-distributed-plonk)) +(package (name octez-epoxy-tx)) (package (name octez-evm-proxy)) (package (name octez-injector)) (package (name octez-mec)) diff --git a/manifest/main.ml b/manifest/main.ml index 2a8bc8bcaf77..30f8dde1d750 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1543,6 +1543,59 @@ let _octez_aplonk_test_helpers_bench = ~bisect_ppx:No ~deps:[octez_plonk_test_helpers; octez_aplonk] +let octez_epoxy_tx = + public_lib + "octez-epoxy-tx" + ~path:"src/lib_epoxy_tx" + ~synopsis:"Circuits for transaction Epoxy rollup" + ~internal_name:"epoxy_tx" + ~deps:[octez_plompiler; hex; stdint; octez_plonk; octez_mec] + +let _octez_epoxy_tx_tests = + private_exe + "main" + ~path:"src/lib_epoxy_tx/test" + ~opam:"octez-epoxy-tx" + ~deps:[octez_epoxy_tx; octez_plonk_test_helpers; octez_aplonk] + ~dune: + Dune. + [ + alias_rule + "runtest" + ~package:"octez-epoxy-tx" + ~action: + (G + [ + setenv + "RANDOM_SEED" + "42" + (progn + [ + run_exe "main" ["-q"]; + [S "diff?"; S "test-quick.expected"; S "test.output"]; + ]); + ]); + alias_rule + "runtest_slow" + ~package:"octez-epoxy-tx" + ~action:(run_exe "main" []); + alias_rule + "runtest_slow_with_regression" + ~package:"octez-epoxy-tx" + ~action: + (G + [ + setenv + "RANDOM_SEED" + "42" + (progn + [ + run_exe "main" []; + [S "diff?"; S "test-slow.expected"; S "test.output"]; + ]); + ]); + ] + let _octez_srs_extraction_tests = tests ["main"] diff --git a/opam/octez-epoxy-tx.opam b/opam/octez-epoxy-tx.opam new file mode 100644 index 000000000000..d34b78e2fef8 --- /dev/null +++ b/opam/octez-epoxy-tx.opam @@ -0,0 +1,25 @@ +# This file was automatically generated, do not edit. +# Edit file manifest/main.ml instead. +opam-version: "2.0" +maintainer: "contact@tezos.com" +authors: ["Tezos devteam"] +homepage: "https://www.tezos.com/" +bug-reports: "https://gitlab.com/tezos/tezos/issues" +dev-repo: "git+https://gitlab.com/tezos/tezos.git" +license: "MIT" +depends: [ + "dune" { >= "3.0" } + "ocaml" { >= "4.14" } + "octez-plompiler" + "hex" { >= "1.3.0" } + "stdint" + "octez-plonk" + "octez-mec" + "octez-aplonk" +] +build: [ + ["rm" "-r" "vendors"] + ["dune" "build" "-p" name "-j" jobs] + ["dune" "runtest" "-p" name "-j" jobs] {with-test} +] +synopsis: "Circuits for transaction Epoxy rollup" diff --git a/src/lib_epoxy_tx/constants.ml b/src/lib_epoxy_tx/constants.ml new file mode 100644 index 000000000000..55d83b7a7157 --- /dev/null +++ b/src/lib_epoxy_tx/constants.ml @@ -0,0 +1,88 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +let two = Z.of_int 2 + +let accounts_depth = 2 + +let tickets_depth = 2 + +let max_nb_accounts = Int.shift_left 1 accounts_depth + +let max_nb_tickets = Int.shift_left 1 tickets_depth + +let tez_id = Bls12_381.Fr.zero + +type position + +type balance + +type amount + +type fee + +type counter + +type op_code + +module Bound : sig + type 'a t = private Z.t + + val max_nb_leaves : position t + + val max_balance : balance t + + val max_amount : amount t + + val max_fee : fee t + + val max_counter : counter t + + val max_op_code : op_code t + + val v : 'a t -> Z.t +end = struct + type 'a t = Z.t + + let max_nb_leaves = Z.(shift_left one) (accounts_depth + tickets_depth) + + let max_balance = Z.(shift_left one 20) + + let max_amount = Z.(shift_left one 20) + + let max_fee = Z.(shift_left one 10) + + let max_counter = Z.(shift_left one 20) + + let max_op_code = Z.(shift_left one 2) + + let v x = x +end + +(* Fee for creating a new L2 account. This needs to be fixed, + as the create always goes through L1 and thus the L2 operator + is forced to include it. +*) +let create_fee = Z.of_int 5 diff --git a/src/lib_epoxy_tx/dune b/src/lib_epoxy_tx/dune new file mode 100644 index 000000000000..3a35e4aa0bb0 --- /dev/null +++ b/src/lib_epoxy_tx/dune @@ -0,0 +1,13 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(library + (name epoxy_tx) + (public_name octez-epoxy-tx) + (instrumentation (backend bisect_ppx)) + (libraries + octez-plompiler + hex + stdint + octez-plonk + octez-mec)) diff --git a/src/lib_epoxy_tx/test/benchmark.ml b/src/lib_epoxy_tx/test/benchmark.ml new file mode 100644 index 000000000000..46db46c5bac4 --- /dev/null +++ b/src/lib_epoxy_tx/test/benchmark.ml @@ -0,0 +1,131 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Epoxy_tx.Tx_rollup +open Plompiler +module H = Helpers.V (LibCircuit) +module HashPV = Plompiler.Anemoi128 +module SchnorrPV = Plompiler.Schnorr (HashPV) +module Schnorr = SchnorrPV.P + +let sks : Schnorr.sk array = + Array.init Constants.max_nb_accounts (fun _ -> + Mec.Curve.Jubjub.AffineEdwards.Scalar.random ()) + +let pks = Array.map Schnorr.neuterize sks + +let circuit_inputs ~nb_batches ~batch_size = + Plonk_test.Helpers.Time.time "prepare" (fun () -> + let init_state = + P.make_state + [ + (pks.(0), Z.of_int 1_000_000, [||]); + (pks.(0), Z.of_int 1_000_000, [||]); + ] + in + (* Batches and intermediate states *) + let rs = + P.generate_transactions + ~nb_batches + ~batch_size + ~src_pos:Z.zero + ~dst_pos:(Z.of_int Constants.max_nb_tickets) + ~amount: + { + id = Constants.tez_id; + amount = + Types.P.Bounded.make ~bound:Constants.Bound.max_amount Z.one; + } + ~fee:(Z.of_int 2) + ~sks + init_state + in + let batch, s = List.hd rs in + let c = H.inner_batch batch init_state s in + let initial, public_input_size = LibCircuit.get_inputs c in + let r = LibCircuit.get_cs ~optimize:true c in + let private_inputs = Solver.solve r.solver initial in + let circ = Plonk.Circuit.to_plonk ~public_input_size r.cs in + let solver = Solver.solve r.solver in + let hd = private_inputs in + let cs, _ = + List.fold_left + (fun (acc, acc_s) (batch, s) -> + let c = H.inner_batch batch acc_s s in + let initial, _ = LibCircuit.get_inputs c in + let private_inputs = solver initial in + (private_inputs :: acc, s)) + ([], s) + (List.tl rs) + in + (circ, hd :: List.rev cs)) + +let benchmark ~nb_batches ~batch_size () = + Format.printf "nb_batches %i batch_size %i\n%!" nb_batches batch_size ; + let circ_map, private_inputs = + let circ, private_inputs = circuit_inputs ~nb_batches ~batch_size in + let circ_map = Plonk.SMap.(add "batch" (circ, nb_batches) empty) in + let private_inputs = Plonk.SMap.(add "batch" private_inputs empty) in + (circ_map, private_inputs) + in + Gc.full_major () ; + let module H = Plonk_test.Helpers.Make (Plonk.Main_protocol) in + H.test_circuits ~name:"benchmark" ~verbose:true circ_map private_inputs + +let benchmark_meta ~nb_batches ~batch_size () = + let module PIs = struct + let get_pi_module _ = + (module Epoxy_tx.Tx_rollup.PI_parameters_predicate_private_batch + : Aplonk.Pi_parameters.CircuitPI) + end in + let module H = Plonk_test.Helpers.Make (Aplonk.Main_protocol.Make (PIs)) in + let circuit, witness = circuit_inputs ~nb_batches ~batch_size in + let circuit_map = Plonk.SMap.singleton "" (circuit, nb_batches) in + let inputs = Plonk.SMap.singleton "" witness in + Gc.full_major () ; + H.test_circuits ~name:"benchmark_meta" ~verbose:true circuit_map inputs + +let tests = + let nb_rep = 2 in + [ + Alcotest.test_case "Private batch benchmark" `Slow (fun () -> + ignore + @@ List.map + (fun (nb_batches, batch_size) -> + Plonk_test.Helpers.Time.bench_test_circuit + ~nb_rep + (benchmark ~nb_batches ~batch_size) + ()) + [(4, 1)]); + Alcotest.test_case "Private batch benchmark aPlonK" `Slow (fun () -> + ignore + @@ List.map + (fun (nb_batches, batch_size) -> + Plonk_test.Helpers.Time.bench_test_circuit + ~nb_rep + (benchmark_meta ~nb_batches ~batch_size) + ()) + [(4, 1)]); + ] diff --git a/src/lib_epoxy_tx/test/censorship.ml b/src/lib_epoxy_tx/test/censorship.ml new file mode 100644 index 000000000000..92a1944a3f57 --- /dev/null +++ b/src/lib_epoxy_tx/test/censorship.ml @@ -0,0 +1,264 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Epoxy_tx.Tx_rollup +open Plompiler +open Plonk_test.Helpers +open Helpers +open P +module TP = Types.P +module HashPV = Plompiler.Anemoi128 +module SchnorrPV = Plompiler.Schnorr (HashPV) +module Schnorr = SchnorrPV.P + +let sks : Schnorr.sk array = + Array.init Constants.max_nb_accounts (fun _ -> + Mec.Curve.Jubjub.AffineEdwards.Scalar.random ()) + +let pks = Array.map Schnorr.neuterize sks + +module Censorship (L : LIB) = struct + open Utils (L) + + open Helpers.V (L) + + open V (L) + + let tez i = + TP. + { + id = Epoxy_tx.Constants.tez_id; + amount = Bounded.make ~bound:Constants.Bound.max_amount (Z.of_int i); + } + + (* Invalid Merkle proofs: + A malicious validator tries to use an incorrect Merkle proof + to invalidate a valid transaction. + *) + let tests_incorrect_proof = + let state = + P.make_state Z.[(pks.(0), of_int 100, [||]); (pks.(1), of_int 10, [||])] + in + let r, state' = + P.generate_transaction + ~src_pos:Z.zero + ~dst_pos:Z.(of_int @@ Constants.max_nb_tickets) + ~amount:(tez 50) + ~fee:Z.zero + ~valid:false + ~unsafe:true + ~sks + state + in + let tx_s = match r.tx_s with Transfer tx -> tx | _ -> assert false in + let bad_src_proof = + {tx_s.src.account.proof with path = List.rev tx_s.src.account.proof.path} + in + let bad_dst_path = + {tx_s.dst.leaf with path = List.rev tx_s.dst.leaf.path} + in + let tx_s1 = + { + tx_s with + src = + { + tx_s.src with + account = {tx_s.src.account with proof = bad_src_proof}; + }; + } + in + let tx_s2 = {tx_s with dst = {tx_s.dst with leaf = bad_dst_path}} in + let tx_s3 = + { + tx_s with + src = + { + tx_s.src with + account = + { + tx_s.src.account with + proof = tx_s.dst.account.proof; + before = tx_s.dst.account.before; + }; + }; + } + in + [ + test + ~valid:false + ~name:"incorrect src proof" + (circuit_op {r with tx_s = Transfer tx_s1} state state'); + test + ~valid:false + ~name:"incorrect dst proof" + (circuit_op {r with tx_s = Transfer tx_s2} state state'); + test + ~valid:false + ~name:"incorrect src proof" + (circuit_op {r with tx_s = Transfer tx_s3} state state'); + ] + + (* Prover tries to censor a valid Tx by using another leaf from the same pk + *) + (* let tests_bad_pos = + (* State in which pk0 has two leaves: 0 and 2, with balaces 100 and 10 + and pk1 has a balance of 100 at pos 1. + *) + let open Constants.Bound in + let open Types.P in + let s = + let max_size = Z.to_int (v max_nb_accounts) in + let acc0 = + { + balance = Bounded.make ~bound:max_balance (Z.of_int 100); + pk = Schnorr.neuterize P.sks.(0); + cnt = Bounded.make ~bound:max_counter Z.zero; + pos = Bounded.make ~bound:max_nb_accounts Z.zero; + } + in + let acc1 = + { + balance = Bounded.make ~bound:max_balance (Z.of_int 100); + pk = Schnorr.neuterize P.sks.(1); + cnt = Bounded.make ~bound:max_counter Z.zero; + pos = Bounded.make ~bound:max_nb_accounts Z.one; + } + in + let acc2 = + { + acc0 with + balance = Bounded.make ~bound:max_balance (Z.of_int 10); + pos = Bounded.make ~bound:max_nb_accounts Z.(of_int 2); + } + in + let accs_list = [(0, acc0); (1, acc1); (2, acc2)] in + let accounts = IMap.of_seq (List.to_seq accs_list) in + let leaves = + Array.append + (Array.of_list (List.map (fun (_, acc) -> P.make_leaf acc) accs_list)) + (Array.init (max_size - 3) (fun i -> + P.make_leaf (P.default_account (3 + i)))) + in + let tree = Merkle.generate_tree ~leaves Constants.depth_tree in + {accounts; tree; next_position = List.length accs_list} + in + (* There is a Tx from pk0 (pos 0) to pk1 of 50 tokens, which should be + valid. However, we craft it using pos 2 for pk0, and change it + afterwards. The circuit should be able to catch this. + *) + let (r, s') = + let unsafe = true in + let actual_src_pos = Bounded.make ~bound:max_nb_accounts Z.zero in + let src_pos_i = 2 in + let dst_pos_i = 1 in + let dst_pos = Bounded.make ~bound:max_nb_accounts (Z.of_int dst_pos_i) in + let sk_src = P.sks.(0) in + let acc_src = P.get_account src_pos_i s.accounts in + let acc_dst = P.get_account dst_pos_i s.accounts in + let cnt = Bounded.make ~bound:max_counter Z.one in + let fee = Bounded.make ~bound:max_fee Z.zero in + let amount = Bounded.make ~bound:max_amount (Z.of_int 50) in + let msg = + let compressed_msg = + P.compress + Bounded.[f actual_src_pos; f dst_pos; f fee; f amount; f cnt] + in + HashPV.P.direct ~input_length:1 [|S.of_z compressed_msg|] + in + let signature = + let random = Curve.Scalar.random () in + Schnorr.sign ~compressed:true sk_src msg random + in + let (src_proof, s) = + let (_, path) = Merkle.proof_path src_pos_i s.tree in + let new_bl_src = + Bounded.(sub_left ~unsafe acc_src.balance (add ~unsafe amount fee)) + in + let new_cnt_src = Bounded.succ ~unsafe acc_src.cnt in + let new_acc_src = + {acc_src with balance = new_bl_src; cnt = new_cnt_src} + in + let new_leaf_src = P.make_leaf new_acc_src in + let accounts = IMap.add src_pos_i new_acc_src s.accounts in + let tree = + Merkle.update_tree ~input_length:2 s.tree src_pos_i new_leaf_src + in + let root = Merkle.root tree in + ({path; root}, {s with tree; accounts}) + in + let (dst_proof, s) = + let (_, path) = Merkle.proof_path dst_pos_i s.tree in + let new_bl_dst = Bounded.(add_left ~unsafe acc_dst.balance amount) in + let new_acc_dst = {acc_dst with balance = new_bl_dst} in + let new_leaf = P.make_leaf new_acc_dst in + let accounts = IMap.add dst_pos_i new_acc_dst s.accounts in + let tree = + Merkle.update_tree ~input_length:2 s.tree dst_pos_i new_leaf + in + let root = Merkle.root tree in + ({path; root}, {s with tree; accounts}) + in + let acc_after_src = P.get_account src_pos_i s.accounts in + let acc_after_dst = P.get_account dst_pos_i s.accounts in + (* TODO: fix this! *) + let payload : transfer_payload = + { + msg = {cnt; src = actual_src_pos; dst = dst_pos; amount; fee}; + signature; + } + in + let header = Dummy.header in + let op : transfer = {header; payload} in + let src = + { + account_before = acc_src; + account_after = acc_after_src; + proof = src_proof; + } + in + let dst = + { + account_before = acc_dst; + account_after = acc_after_dst; + proof = dst_proof; + } + in + let tx_s : tx_storage = Transfer {src; dst; valid = true} in + ({tx = Transfer op; tx_s; fee; hash = msg; exit_validity = false}, s) + in + [test ~valid:false ~name:"incorrect src proof" (circuit_op r s s')] *) + + let tests = tests_incorrect_proof + (* @ tests_bad_pos *) +end + +let tests = + [ + Alcotest.test_case "Censorship" `Quick (to_test (module Censorship : Test)); + Alcotest.test_case + "Censorship plonk" + `Slow + (to_test ~plonk:(module Plonk.Main_protocol) (module Censorship : Test)); + ] diff --git a/src/lib_epoxy_tx/test/dune b/src/lib_epoxy_tx/test/dune new file mode 100644 index 000000000000..667e41edec21 --- /dev/null +++ b/src/lib_epoxy_tx/test/dune @@ -0,0 +1,29 @@ +; This file was automatically generated, do not edit. +; Edit file manifest/main.ml instead. + +(executable + (name main) + (instrumentation (backend bisect_ppx)) + (libraries + octez-epoxy-tx + octez-plonk.plonk-test + octez-aplonk)) + +(rule + (alias runtest) + (package octez-epoxy-tx) + (action + (setenv RANDOM_SEED 42 + (progn (run %{exe:main.exe} -q) (diff? test-quick.expected test.output))))) + +(rule + (alias runtest_slow) + (package octez-epoxy-tx) + (action (run %{exe:main.exe}))) + +(rule + (alias runtest_slow_with_regression) + (package octez-epoxy-tx) + (action + (setenv RANDOM_SEED 42 + (progn (run %{exe:main.exe}) (diff? test-slow.expected test.output))))) diff --git a/src/lib_epoxy_tx/test/helpers.ml b/src/lib_epoxy_tx/test/helpers.ml new file mode 100644 index 000000000000..1acfac98c7c7 --- /dev/null +++ b/src/lib_epoxy_tx/test/helpers.ml @@ -0,0 +1,81 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Epoxy_tx.Tx_rollup +open Plompiler +open Types.P +open Constants.Bound + +module V (L : LIB) = struct + open V (L) + + let make_pos i = Bounded.make ~bound:max_nb_leaves (Z.of_int i) + + let get_rollup_id (r : P.generate_op_result) = + match r.tx with + | Transfer t -> t.header.rollup_id + | Create t -> t.header.rollup_id + | Credit t -> t.header.rollup_id + | Debit t -> t.header.rollup_id + + let circuit_op (r : P.generate_op_result) init_state state () = + predicate_op + ~old_root:(MerklePV.P.root init_state.accounts_tree) + ~old_next_pos:(make_pos init_state.next_position) + ~new_root:(MerklePV.P.root state.accounts_tree) + ~new_next_pos:(make_pos state.next_position) + ~fee:r.fee + ~exit_validity:r.exit_validity + ~rollup_id:(get_rollup_id r) + r.tx + r.tx_s + + let pos_of_index ?(offset = 0) index = + Z.of_int @@ ((Epoxy_tx.Constants.max_nb_tickets * index) + offset) + + let inner_batch (rs : P.generate_op_result list) init_state state = + let get_op : tx -> transfer = function + | Transfer op -> op + | _ -> assert false + in + let get_op_s : tx_storage -> transfer_storage = function + | Transfer op -> op + | _ -> assert false + in + predicate_private_batch + ~old_root:(MerklePV.P.root init_state.accounts_tree) + ~old_next_pos:(make_pos init_state.next_position) + ~new_root:(MerklePV.P.root state.accounts_tree) + ~new_next_pos:(make_pos state.next_position) + ~fees: + (List.fold_left + (fun acc (r : P.generate_op_result) -> + Bounded.add_left ~unsafe:true acc r.fee) + (Bounded.make ~bound:max_amount Z.zero) + rs) + ~rollup_id:(get_rollup_id (List.hd rs)) + (List.map (fun (r : P.generate_op_result) -> get_op r.tx) rs) + (List.map (fun (r : P.generate_op_result) -> get_op_s r.tx_s) rs) +end diff --git a/src/lib_epoxy_tx/test/invalidTx.ml b/src/lib_epoxy_tx/test/invalidTx.ml new file mode 100644 index 000000000000..d4fb272f96e5 --- /dev/null +++ b/src/lib_epoxy_tx/test/invalidTx.ml @@ -0,0 +1,307 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Epoxy_tx.Tx_rollup +open Plompiler +open Plonk_test.Helpers +open P +module TP = Types.P +module HashPV = Plompiler.Anemoi128 +module SchnorrPV = Plompiler.Schnorr (HashPV) +module Schnorr = SchnorrPV.P + +let sks : Schnorr.sk array = + Array.init Constants.max_nb_accounts (fun _ -> + Mec.Curve.Jubjub.AffineEdwards.Scalar.random ()) + +let pks = Array.map Schnorr.neuterize sks + +module InvalidTx (L : LIB) = struct + open Utils (L) + + open Helpers.V (L) + + open V (L) + + let tez i = + TP. + { + id = Epoxy_tx.Constants.tez_id; + amount = Bounded.make ~bound:Constants.Bound.max_amount (Z.of_int i); + } + + let get_transfer (r, state) = + let tx = match r.tx with Transfer tx -> tx | _ -> assert false in + (tx, state) + + (* Insufficient balance: + User 0 attempts to send 100 to user 1, but only has a balance of 99 + *) + let tests_insufficient_balace = + let state = + P.make_state Z.[(pks.(0), of_int 99, [||]); (pks.(1), of_int 100, [||])] + in + let r1, state1 = + P.generate_transaction + ~valid:false + ~unsafe:true + ~src_pos:Z.zero + ~dst_pos:Z.(of_int Constants.max_nb_tickets) + ~amount:(tez 100) + ~fee:Z.zero + ~sks + state + in + let r2, state2 = + P.generate_transaction + ~src_pos:Z.zero + ~dst_pos:Z.(of_int Constants.max_nb_tickets) + ~amount:(tez 80) + ~fee:Z.(of_int 20) + ~valid:false + ~unsafe:true + ~sks + state + in + [ + test + ~valid:true + ~name:"insufficient balance: amount > bal" + (circuit_op r1 state state1); + test + ~valid:true + ~name:"insufficient balance: amount + fee > bal" + (circuit_op r2 state state2); + ] + + (* Dst doesn't exist *) + let tests_invalid_dst = + let state = P.make_state [(pks.(0), Z.of_int 100, [||])] in + let r, state' = + P.generate_transaction + ~src_pos:Z.zero + ~dst_pos:Z.(of_int Constants.max_nb_tickets) + ~amount:(tez 10) + ~fee:Z.zero + ~valid:false + ~unsafe:true + ~sks + state + in + [test ~valid:true ~name:"invalid dst" (circuit_op r state state')] + + (* Src doesn't exist *) + + let tests_invalid_src = + let state = P.make_state [(pks.(0), Z.of_int 100, [||])] in + let r, state' = + P.generate_transaction + ~src_pos:Z.(of_int Constants.max_nb_tickets) + ~dst_pos:Z.zero + ~amount:(tez 10) + ~fee:Z.zero + ~valid:false + ~unsafe:true + ~sks + state + in + [test ~valid:true ~name:"invalid src" (circuit_op r state state')] + + (* Replay *) + let tests_replay = + let state = + P.make_state Z.[(pks.(0), of_int 100, [||]); (pks.(1), of_int 100, [||])] + in + let _r, state1 = + P.generate_transaction + ~src_pos:Z.zero + ~dst_pos:Z.(of_int Constants.max_nb_tickets) + ~amount:(tez 10) + ~fee:Z.zero + ~cnt:Z.zero + ~valid:true + ~unsafe:true + ~sks + state + in + let r, state' = + P.generate_transaction + ~src_pos:Z.zero + ~dst_pos:Z.(of_int Constants.max_nb_tickets) + ~amount:(tez 10) + ~fee:Z.zero + ~cnt:Z.zero + ~valid:false + ~unsafe:true + ~sks + state1 + in + [test ~valid:true ~name:"replay" (circuit_op r state1 state')] + + (* New balance out of bounds *) + let tests_out_of_bounds = + let state = + P.make_state + Z. + [ + (pks.(0), of_int 100, [||]); + (pks.(1), Constants.Bound.(v max_balance) - of_int 50, [||]); + ] + in + let r, state' = + P.generate_transaction + ~src_pos:Z.zero + ~dst_pos:Z.(of_int Constants.max_nb_tickets) + ~amount:(tez 60) + ~fee:Z.zero + ~valid:false + ~unsafe:true + ~sks + state + in + [ + test + ~valid:true + ~name:"balance out of bounds 1" + (circuit_op r state state'); + ] + + (* Invalid signature *) + let tests_invalid_signature = + let state = P.make_state Z.[(pks.(0), of_int 100, [||])] in + let r, state' = + P.generate_transaction + ~src_pos:Z.zero + ~dst_pos:Z.(of_int Constants.max_nb_tickets) + ~amount:(tez 50) + ~fee:Z.zero + ~valid:false + ~unsafe:true + ~sks + state + in + let tx, state' = get_transfer (r, state') in + let bad_msg = + let compressed_msg = + P.compress + TP.Bounded. + [ + f tx.header.op_code; + f tx.header.price.amount; + f tx.payload.msg.dst; + (* change order*) + f tx.payload.msg.src; + f tx.payload.msg.fee; + f tx.payload.msg.amount.amount; + f tx.payload.msg.cnt; + ] + in + HashPV.P.direct + ~input_length:4 + [| + Epoxy_tx.Utils.scalar_of_bytes tx.header.l1_dst; + S.of_z compressed_msg; + tx.header.price.id; + tx.payload.msg.amount.id; + |] + in + let rand = Mec.Curve.Jubjub.AffineEdwards.Scalar.random () in + let bad_msg_signature = + SchnorrPV.P.sign ~compressed:true sks.(0) bad_msg rand + in + let tx_bad_msg = + {tx with payload = {tx.payload with signature = bad_msg_signature}} + in + (* TODO: fix this *) + let msg = + let compressed_msg = + P.compress + TP.Bounded. + [ + f tx.header.op_code; + f tx.header.price.amount; + f tx.payload.msg.src; + f tx.payload.msg.dst; + f tx.payload.msg.fee; + f tx.payload.msg.amount.amount; + f tx.payload.msg.cnt; + ] + in + HashPV.P.direct + ~input_length:4 + [| + Epoxy_tx.Utils.scalar_of_bytes tx.header.l1_dst; + S.of_z compressed_msg; + tx.header.price.id; + tx.payload.msg.amount.id; + |] + in + let bad_sk_signature = SchnorrPV.P.sign ~compressed:true sks.(1) msg rand in + let tx_bad_sk = + {tx with payload = {tx.payload with signature = bad_sk_signature}} + in + let tx_not_on_curve = + let bad_r = + Mec.Curve.Jubjub.AffineEdwards.( + unsafe_from_coordinates ~u:(Base.of_z Z.one) ~v:(Base.of_z Z.one)) + in + { + tx with + payload = + { + tx.payload with + signature = {tx.payload.signature with sig_r = bad_r}; + }; + } + in + + [ + test + ~valid:true + ~name:"invalid signature: bad msg" + (circuit_op {r with tx = Transfer tx_bad_msg} state state'); + test + ~valid:true + ~name:"invalid signature: bad sk" + (circuit_op {r with tx = Transfer tx_bad_sk} state state'); + test + ~valid:true + ~name:"invalid signature: not on curve" + (circuit_op {r with tx = Transfer tx_not_on_curve} state state'); + ] + + let tests = + tests_insufficient_balace @ tests_invalid_dst @ tests_invalid_src + @ tests_replay @ tests_out_of_bounds @ tests_invalid_signature +end + +let tests = + [ + Alcotest.test_case "InvalidTx" `Quick (to_test (module InvalidTx : Test)); + Alcotest.test_case + "InvalidTx plonk" + `Slow + (to_test ~plonk:(module Plonk.Main_protocol) (module InvalidTx : Test)); + ] diff --git a/src/lib_epoxy_tx/test/main.ml b/src/lib_epoxy_tx/test/main.ml new file mode 100644 index 000000000000..e216276dd1df --- /dev/null +++ b/src/lib_epoxy_tx/test/main.ml @@ -0,0 +1,39 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plonk_test + +let () = + Helpers.with_seed (fun () -> + Helpers.with_output_to_file (fun () -> + Alcotest.run + ~verbose:true + "Tx Rollup" + [ + ("RandomTx", RandomTx.tests); + ("InvalidTx", InvalidTx.tests); + ("Censorship", Censorship.tests); + ("Benchmark", Benchmark.tests); + ])) diff --git a/src/lib_epoxy_tx/test/randomTx.ml b/src/lib_epoxy_tx/test/randomTx.ml new file mode 100644 index 000000000000..86036373e118 --- /dev/null +++ b/src/lib_epoxy_tx/test/randomTx.ml @@ -0,0 +1,67 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Epoxy_tx.Tx_rollup +open Plompiler +open Plonk_test.Helpers + +module RandomTx (L : LIB) = struct + open Plonk_test.Helpers.Utils (L) + + open Helpers.V (L) + + open V (L) + + module HashPV = Plompiler.Anemoi128 + module SchnorrPV = Plompiler.Schnorr (HashPV) + module Schnorr = SchnorrPV.P + + let sks : Schnorr.sk array = + Array.init Constants.max_nb_accounts (fun _ -> + Mec.Curve.Jubjub.AffineEdwards.Scalar.random ()) + + let pks = Array.map Schnorr.neuterize sks + + let init_state = P.random_state sks () + + let r, state = P.generate_transaction ~sks init_state + + let tests = + [ + test + ~valid:true + ~name:"RandomTx.make_rollup" + (circuit_op r init_state state); + ] +end + +let tests = + [ + Alcotest.test_case "RandomTx" `Quick (to_test (module RandomTx : Test)); + Alcotest.test_case + "RandomTx plonk" + `Slow + (to_test ~plonk:(module Plonk.Main_protocol) (module RandomTx : Test)); + ] diff --git a/src/lib_epoxy_tx/test/test-quick.expected b/src/lib_epoxy_tx/test/test-quick.expected new file mode 100644 index 000000000000..a04c3de3b5c9 --- /dev/null +++ b/src/lib_epoxy_tx/test/test-quick.expected @@ -0,0 +1,60 @@ +RandomTx.make_rollup: +Constraints: 3760 + +RandomTx.make_rollup_optimized: +Constraints: 1423 + +insufficient balance: amount > bal: +Constraints: 3760 + +insufficient balance: amount > bal_optimized: +Constraints: 1423 + +insufficient balance: amount + fee > bal: +Constraints: 3760 + +insufficient balance: amount + fee > bal_optimized: +Constraints: 1423 + +invalid dst: +Constraints: 3760 + +invalid dst_optimized: +Constraints: 1423 + +invalid src: +Constraints: 3760 + +invalid src_optimized: +Constraints: 1423 + +replay: +Constraints: 3760 + +replay_optimized: +Constraints: 1423 + +balance out of bounds 1: +Constraints: 3760 + +balance out of bounds 1_optimized: +Constraints: 1423 + +invalid signature: bad msg: +Constraints: 3760 + +invalid signature: bad msg_optimized: +Constraints: 1423 + +invalid signature: bad sk: +Constraints: 3760 + +invalid signature: bad sk_optimized: +Constraints: 1423 + +invalid signature: not on curve: +Constraints: 3760 + +invalid signature: not on curve_optimized: +Constraints: 1423 + diff --git a/src/lib_epoxy_tx/test/test-slow.expected b/src/lib_epoxy_tx/test/test-slow.expected new file mode 100644 index 000000000000..60d5b28d3529 --- /dev/null +++ b/src/lib_epoxy_tx/test/test-slow.expected @@ -0,0 +1,204 @@ +RandomTx.make_rollup: +Constraints: 3760 + +RandomTx.make_rollup_optimized: +Constraints: 1423 + +RandomTx.make_rollup: +Constraints: 3760 + +RandomTx.make_rollup_optimized: +Constraints: 1423 + +RandomTx.make_rollup: +Proof size: 3.13 KB +Proof hash: ca463881d200d11f6bc5b9b4f15294e574cbe4c90ec87bb5aeae7980076d28ba +Prover_pp hash: 254882a724a1a5dfabb52c42375d960391f8be276d075c5369af5b1e2ee8cfa5 +Verifier_pp hash: 130756b55cb16714615228a08a2c6c494d4b15228a6023f1a4cb75f56619980c + +insufficient balance: amount > bal: +Constraints: 3760 + +insufficient balance: amount > bal_optimized: +Constraints: 1423 + +insufficient balance: amount + fee > bal: +Constraints: 3760 + +insufficient balance: amount + fee > bal_optimized: +Constraints: 1423 + +invalid dst: +Constraints: 3760 + +invalid dst_optimized: +Constraints: 1423 + +invalid src: +Constraints: 3760 + +invalid src_optimized: +Constraints: 1423 + +replay: +Constraints: 3760 + +replay_optimized: +Constraints: 1423 + +balance out of bounds 1: +Constraints: 3760 + +balance out of bounds 1_optimized: +Constraints: 1423 + +invalid signature: bad msg: +Constraints: 3760 + +invalid signature: bad msg_optimized: +Constraints: 1423 + +invalid signature: bad sk: +Constraints: 3760 + +invalid signature: bad sk_optimized: +Constraints: 1423 + +invalid signature: not on curve: +Constraints: 3760 + +invalid signature: not on curve_optimized: +Constraints: 1423 + +insufficient balance: amount > bal: +Constraints: 3760 + +insufficient balance: amount > bal_optimized: +Constraints: 1423 + +insufficient balance: amount > bal: +Proof size: 3.71 KB +Proof hash: 707fa203fab59a164b9011ae059c19e5e6d4e94d71f393a5583b87d223aeb832 +Prover_pp hash: 53db01b2215ff322a1f2d51a9ef7745d796463b3598cdc2a6fc665ab174dcffa +Verifier_pp hash: dea786762d596e0a7e2329644647c755744b905c9a862850dd9f8eb4a0a314ca + +insufficient balance: amount + fee > bal: +Constraints: 3760 + +insufficient balance: amount + fee > bal_optimized: +Constraints: 1423 + +insufficient balance: amount + fee > bal: +Proof size: 3.97 KB +Proof hash: 71870b8bbd5cdf6a7aebcd2f86a8fddfaee48da64c849b355f320911efa22522 +Prover_pp hash: 26bba0518bc2429805f3cf1b3d1b00b262c760112265fd8b6b0c6129e60ca560 +Verifier_pp hash: 72f1c27fcd97b6823804ac43e99a2a2e53804c497d13c4f0a0afb06804490706 + +invalid dst: +Constraints: 3760 + +invalid dst_optimized: +Constraints: 1423 + +invalid dst: +Proof size: 2.75 KB +Proof hash: 2a19a16f61f938c4e2a544f4643c8baf6e6b4c3d3060fc4a1f2dce27f781f6f6 +Prover_pp hash: 601c76b2c454878fb567ada1f4ec0055302b3b0dafb973bf176cfa58402e1d8e +Verifier_pp hash: 16b49d55945280cd35610575348f10f63ee5f1f922730c64639cd7bd2c615df6 + +invalid src: +Constraints: 3760 + +invalid src_optimized: +Constraints: 1423 + +invalid src: +Proof size: 2.75 KB +Proof hash: b605890a6ce49e09e90c9298359414be586f9a41af0c790d05ce1f5a94e47d87 +Prover_pp hash: bd81591ae287ba09e9090c37cd7875830466589890a40f5cdcf0602380b8df42 +Verifier_pp hash: 9d498379c6e73920534d339793cc3f718c62b312bec31725d54d0fbe37a56a7e + +replay: +Constraints: 3760 + +replay_optimized: +Constraints: 1423 + +replay: +Proof size: 2.54 KB +Proof hash: a2e68d2417c26fc59c6ad5abd3329b6fc808f5ed791a2c2a75e865e70573d214 +Prover_pp hash: 314e08f2887c6d8d5aa82b4d9e05eb55b246e72a1630841816f6c1121dbd0b03 +Verifier_pp hash: ac6cdc4825081c331f341cae9fe980db06b936cc4b698de15e04a70e4ca2e232 + +balance out of bounds 1: +Constraints: 3760 + +balance out of bounds 1_optimized: +Constraints: 1423 + +balance out of bounds 1: +Proof size: 3.25 KB +Proof hash: 18b2ec09204fe13aa26fa3f76e6c22682d8b72074fd739c0b032bdd4fccf465c +Prover_pp hash: a238ce464a901050f8e7cc137375421229374ff903b5502c465fced1a7a2ccf4 +Verifier_pp hash: b75aa485eb7e48f5258c70e581246cad2bb7ab106e2e9431074725a870cba9c0 + +invalid signature: bad msg: +Constraints: 3760 + +invalid signature: bad msg_optimized: +Constraints: 1423 + +invalid signature: bad msg: +Proof size: 3.38 KB +Proof hash: 32b526dcbf1f74ece4f397d84d02945f13e9226f8d7d6270bf8f72345c6b3b39 +Prover_pp hash: aeeac370e721a83c126ec661fcc837bcaa71fa918dea481e7d94511877ebc7df +Verifier_pp hash: c14aac1821b9ca4c0c6c1bbde1f6a7f1e34b5bcd7ca8fa23485584551511e814 + +invalid signature: bad sk: +Constraints: 3760 + +invalid signature: bad sk_optimized: +Constraints: 1423 + +invalid signature: bad sk: +Proof size: 3.34 KB +Proof hash: 9c2fa7ee974b3f29bf93457a9608db62146d894f9681225dbf307088ac00b7f2 +Prover_pp hash: 86b9c49eff7b9a12c87928141b1677a78f4655a6ca5b40fedbb16ae377707cc3 +Verifier_pp hash: 2b780182467b766302b5bd12225487d44e2774471ead6847e8b88614c0bbea7c + +invalid signature: not on curve: +Constraints: 3760 + +invalid signature: not on curve_optimized: +Constraints: 1423 + +invalid signature: not on curve: +Proof size: 3.59 KB +Proof hash: 19d9aeb1b1404eb6f60b75dfe34154deeea9721197f34daa23efe6ea12eb81f1 +Prover_pp hash: b285cf5a2af3148680a51e5b8acdc82266065e9c27078a9fd48334711ef24daa +Verifier_pp hash: 444896fb75ac99f3d0f70fa53601924ce66eee447163214a12770ff3b151a853 + +benchmark: +Proof size: 4.61 KB +Proof hash: e121544533111c7b44140b5019dd62860e8663745fadf04d13184be865f90140 +Prover_pp hash: 5efee91cb2e45cdb17e3be39785c24082fec9fcfa30f6b13fb2bbd22f3d86a70 +Verifier_pp hash: 7ed32e56ee49e190ec37c21056be1b3c287814d08fa543a8c456e701270e7a18 + +benchmark: +Proof size: 4.61 KB +Proof hash: da68541b5692398eb22f057e0dc6186d8225ae4cc5c90031cee9981602d3991c +Prover_pp hash: 5efee91cb2e45cdb17e3be39785c24082fec9fcfa30f6b13fb2bbd22f3d86a70 +Verifier_pp hash: 7ed32e56ee49e190ec37c21056be1b3c287814d08fa543a8c456e701270e7a18 + +benchmark_meta: +Proof size: 10.90 KB +Proof hash: 8cb05e77aea1941d06d78d17cc4b10f09f4c498f7b1a51c20d6209e808774561 +Prover_pp hash: c6a93a7cfca723d18b703412998f40d1d36b6f8d0ed695ff7c776532533138cf +Verifier_pp hash: 38c3360669a1be23e32e4de333ca325c74ab720108cd504fe5fd5969953c643f + +benchmark_meta: +Proof size: 10.90 KB +Proof hash: 207064f62f1e46182f21cb2fa4718f4d83ce7c4a9487b5f7de7c2c616f9bb106 +Prover_pp hash: c6a93a7cfca723d18b703412998f40d1d36b6f8d0ed695ff7c776532533138cf +Verifier_pp hash: 38c3360669a1be23e32e4de333ca325c74ab720108cd504fe5fd5969953c643f + diff --git a/src/lib_epoxy_tx/tx_rollup.ml b/src/lib_epoxy_tx/tx_rollup.ml new file mode 100644 index 000000000000..3a4c7acfba0e --- /dev/null +++ b/src/lib_epoxy_tx/tx_rollup.ml @@ -0,0 +1,2114 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module Constants = Constants +module Types = Types +module Utils = Utils +open Utils +open Plompiler +module HashPV = Anemoi128 +module MerklePV = Gadget.Merkle (HashPV) +module SchnorrPV = Plompiler.Schnorr (HashPV) +module Hash = HashPV.P +module Merkle = MerklePV.P +module Schnorr = SchnorrPV.P +module Curve = Mec.Curve.Jubjub.AffineEdwards + +module P = struct + open Types.P + open Constants + (* These functions aimed to format integers more efficiently by compressing + them in a scalar. *) + + (* This function computes the maximal bound of a list of bounded variables + written as [(value, bound)_1, ..., (value, bound)_n] *) + let compression_bound (values : unit Bounded.t list) = + let values = (values :> (Z.t * Z.t) list) in + List.fold_left Z.mul Z.one (List.map snd values) + + (* This function attempts to compress a list of integers into one scalar. *) + let compress (values : unit Bounded.t list) = + assert (compression_bound values < S.order) ; + let values = (values :> (Z.t * Z.t) list) in + List.fold_left + (fun acc (v, v_bound) -> Z.(v + (acc * v_bound))) + (fst @@ List.hd values) + (List.tl values) + + let scalar_of_account (acc : account) = + (* We can use just the u coordinate of pk as Edwards curves are symmetric and as such there are only two possible v coordinates and the same sk is used to generate both. + We could set a convention to only use pk with v coordination of a given parity, for instance v odd. *) + (* TODO move this in schnorr and make the pk directly a single coordinate *) + let u = Curve.get_u_coordinate acc.pk |> of_bls_scalar in + let compressed = compress Bounded.[f acc.tez_balance; f acc.cnt] in + let h = Hash.direct ~input_length:2 [|u; S.of_z compressed|] in + (* we leverage the Correlation-Intractablity (with respecto to +) of the + hash function and add [h] to the ticket's root (which is also the output + of a hash); alternatively (and to avoid relying on CI) we could define + [scalar_of_account] as the hash of all 3 inputs [u, compressed, + acc.tickets_root ], but that would require one extra iteration of the + hash function *) + S.add h acc.tickets_root + + let scalar_of_leaf (l : leaf) = + let compressed = compress Bounded.[f l.pos; f l.ticket.amount] in + Hash.direct ~input_length:2 [|l.ticket.id; S.of_z compressed|] + + let default_leaf pos = + { + pos = Bounded.make ~bound:Bound.max_nb_leaves (Z.of_int pos); + ticket = Dummy.ticket_balance; + } + + let empty_ticket_tree start_pos = + let size = max_nb_tickets in + let leaves = Array.init size (fun i -> default_leaf (i + start_pos)) in + ( leaves, + Merkle.generate_tree + ~leaves:(Array.map scalar_of_leaf leaves) + tickets_depth ) + + let default_account acc_index = + let start_pos = max_nb_tickets * acc_index in + let leaves, ticket_tree = empty_ticket_tree start_pos in + let tickets_root = Merkle.root ticket_tree in + ( { + pk = Schnorr.g; + tez_balance = Bounded.make ~bound:Bound.max_balance Z.zero; + cnt = Bounded.make ~bound:Bound.max_counter Z.zero; + tickets_root; + }, + leaves, + ticket_tree ) + + let get_account : + int -> + (account * leaf array * Merkle.tree) IMap.t -> + account * leaf array * Merkle.tree = + fun i accs -> + IMap.find_opt i accs |> Option.value ~default:(default_account i) + + let random_leaf pos = + let id = S.random () in + let amount = Bounded.random Bound.max_balance in + {pos; ticket = {id; amount}} + + let random_ticket_tree start_pos = + let size = max_nb_tickets in + let leaves = + Array.init size (fun i -> + random_leaf + (Bounded.make ~bound:Bound.max_nb_leaves + @@ Z.of_int @@ (i + start_pos))) + in + ( Merkle.generate_tree + ~leaves:(Array.map scalar_of_leaf leaves) + tickets_depth, + leaves ) + + let random_account sks i = + let open Bound in + let tez_balance = Bounded.make Z.(v max_balance / two) ~bound:max_balance in + let pk = Schnorr.neuterize sks.(i) in + let cnt = Bounded.random max_counter in + let start_pos = max_nb_tickets * i in + let ticket_tree, leaves = random_ticket_tree start_pos in + let tickets_root = Merkle.root ticket_tree in + ({tez_balance; pk; cnt; tickets_root}, leaves, ticket_tree) + + let random_state sks () = + (* We don't generate empty states *) + let size = 1 + random_int (max_nb_accounts - 1) in + let next_index = random_int max_nb_accounts in + let next_position = max_nb_tickets * next_index in + let indices = List.init size (fun _ -> random_int max_nb_accounts) in + let indices = List.filter (fun i -> next_index <> i) indices in + let accs_list = List.map (random_account sks) indices in + let indexed_accounts = List.combine indices accs_list in + let accounts = IMap.of_seq (List.to_seq indexed_accounts) in + let account_scalars = + Array.init max_nb_accounts (fun i -> + scalar_of_account + (let x, _, _ = default_account i in + x)) + in + let () = + List.iter + (fun (i, (acc, _, _)) -> account_scalars.(i) <- scalar_of_account acc) + indexed_accounts + in + let accounts_tree = + Merkle.generate_tree ~leaves:account_scalars accounts_depth + in + {accounts; accounts_tree; next_position} + + let empty_state () = + let accounts = Array.init max_nb_accounts (fun i -> default_account i) in + let accounts_tree = + Merkle.generate_tree + ~leaves:(Array.map (fun (a, _, _) -> scalar_of_account a) accounts) + accounts_depth + in + let accounts = Array.mapi (fun i x -> (i, x)) accounts in + let accounts = IMap.of_seq @@ Array.to_seq accounts in + {accounts; accounts_tree; next_position = 0} + + let make_state (bals : (Schnorr.pk * Z.t * balance ticket array) list) = + let open Bound in + let s = empty_state () in + let _, accounts, accounts_tree = + List.fold_left + (fun (i, accounts, accounts_tree) (pk, tez_bal, tickets) -> + let acc, leaves, _tree = get_account i accounts in + let leaves = + Array.mapi + (fun i {pos; ticket} -> + let ticket = + try tickets.(i) with Invalid_argument _ -> ticket + in + {pos; ticket}) + leaves + in + let tree = + Merkle.generate_tree + ~leaves:(Array.map scalar_of_leaf leaves) + tickets_depth + in + let acc = + { + acc with + tez_balance = Bounded.make ~bound:max_balance tez_bal; + pk; + tickets_root = Merkle.root tree; + } + in + let accounts = IMap.add i (acc, leaves, tree) accounts in + let accounts_tree = + Merkle.update_tree + ~input_length:2 + accounts_tree + i + (scalar_of_account acc) + in + (i + 1, accounts, accounts_tree)) + (0, s.accounts, s.accounts_tree) + bals + in + {accounts; accounts_tree; next_position = List.length bals * max_nb_tickets} + + let coerce (type a) (x : a Bounded.t) = fst (x : a Bounded.t :> Z.t * Z.t) + + let hash_op (t : unsigned_tx) = + let module Curve = Mec.Curve.Jubjub.AffineEdwards in + let module S = Bls12_381.Fr in + match t with + (* Do not use wildcard patterns, make sure we never forget to sign a field *) + | Transfer {header; payload = {src; dst; fee; amount; cnt}} -> + let compressed_msg = + compress + Bounded. + [ + f header.op_code; + f header.price.amount; + f src; + f dst; + f fee; + f amount.amount; + f cnt; + ] + in + Hash.direct + ~input_length:4 + [| + scalar_of_bytes header.l1_dst; + S.of_z compressed_msg; + header.price.id; + amount.id; + |] + | Create {header; payload = {pk; fee}} -> + let compressed_msg = + compress Bounded.[f header.op_code; f header.price.amount; f fee] + in + let pk_x, pk_y = affine_to_point pk in + Hash.direct + ~input_length:5 + [| + scalar_of_bytes header.l1_dst; + S.of_z compressed_msg; + pk_x; + pk_y; + header.price.id; + |] + | Credit {header; payload = {dst; amount; cnt}} -> + let compressed_msg = + compress + Bounded. + [ + f header.op_code; + f header.price.amount; + f dst; + f amount.amount; + f cnt; + ] + in + Hash.direct + ~input_length:4 + [| + scalar_of_bytes header.l1_dst; + S.of_z compressed_msg; + header.price.id; + amount.id; + |] + | Debit {header; payload = {src; amount; cnt}} -> + let compressed_msg = + compress + Bounded. + [ + f header.op_code; + f header.price.amount; + f src; + f amount.amount; + f cnt; + ] + in + Hash.direct + ~input_length:4 + [| + scalar_of_bytes header.l1_dst; + S.of_z compressed_msg; + header.price.id; + amount.id; + |] + + let sign_op sk (t : unsigned_tx) : tx = + let module Curve = Mec.Curve.Jubjub.AffineEdwards in + let module S = Bls12_381.Fr in + let msg = hash_op t in + match t with + (* Do not use wildcard patterns, make sure we never forget to sign a field *) + | Transfer {header; payload = {src; dst; fee; amount; cnt}} -> + let signature = + let random = Curve.Scalar.random () in + Schnorr.sign ~compressed:true sk msg random + in + Transfer + {header; payload = {msg = {src; dst; fee; amount; cnt}; signature}} + | Create {header; payload = {pk; fee}} -> + let signature = + let random = Curve.Scalar.random () in + Schnorr.sign ~compressed:true sk msg random + in + Create {header; payload = {msg = {pk; fee}; signature}} + | Debit {header; payload = {src; amount; cnt}} -> + let signature = + let random = Curve.Scalar.random () in + Schnorr.sign ~compressed:true sk msg random + in + Debit {header; payload = {msg = {src; amount; cnt}; signature}} + | Credit t -> Credit t + + (* Check if an operation is valid in a certain state and, if possible, + return the storage needed to make the proof. + The only case where the storage isn't computed is for ill-formed ops, + as the ill-formed circuits do not need any storage. + *) + let preprocess_operation : + state -> tx -> tezos_zkru -> state * tx * tx_storage option = + fun s tx rollup_id -> + match tx with + | Transfer + ({header; payload = {msg = {cnt; src; dst; amount; fee}; signature}} as + op) -> + let msg = + hash_op @@ Transfer {header; payload = {cnt; src; dst; amount; fee}} + in + let well_formed = + Bounded.( + check cnt && check src && check dst && check amount.amount + && check fee) + in + if not well_formed then (s, Transfer op, None) + else + let src_index = Z.to_int (coerce src) / Constants.max_nb_tickets in + let src_offset = Z.to_int (coerce src) mod Constants.max_nb_tickets in + let dst_index = Z.to_int (coerce dst) / Constants.max_nb_tickets in + let dst_offset = Z.to_int (coerce dst) mod Constants.max_nb_tickets in + let src_account, src_leaves, src_tree = + get_account src_index s.accounts + in + let src_leaf = src_leaves.(src_offset) in + + let is_tez = amount.id = Constants.tez_id in + + let ticket_amount = + if is_tez then Bounded.make ~bound:Constants.Bound.max_amount Z.zero + else amount.amount + in + let tez_transfer_amount = + if is_tez then amount.amount + else Bounded.make ~bound:Constants.Bound.max_amount Z.zero + in + let tez_amount = + Bounded.add_left ~unsafe:true tez_transfer_amount fee + in + + let new_tez_amount_src = + Bounded.(sub_left ~unsafe:true src_account.tez_balance tez_amount) + in + let new_ticket_amount_src = + Bounded.(sub_left ~unsafe:true src_leaf.ticket.amount ticket_amount) + in + + let dst_account, dst_leaves, _dst_tree = + (* When src and dst are the same, we need to apply the effects of + the transfer from src to the state before checking the validity + of the dst *) + if dst_index = src_index then ( + let new_ticket_src = + {src_leaf.ticket with amount = new_ticket_amount_src} + in + let new_leaf_src = {src_leaf with ticket = new_ticket_src} in + src_leaves.(src_offset) <- new_leaf_src ; + let src_tree = + Merkle.update_tree + ~input_length:2 + src_tree + src_offset + (scalar_of_leaf new_leaf_src) + in + let new_cnt_src = Bounded.succ ~unsafe:true src_account.cnt in + let new_acc_src = + { + src_account with + tez_balance = new_tez_amount_src; + cnt = new_cnt_src; + tickets_root = Merkle.root src_tree; + } + in + (new_acc_src, src_leaves, src_tree)) + else get_account dst_index s.accounts + in + let dst_leaf = dst_leaves.(dst_offset) in + let new_tez_amount_dst = + Bounded.( + add_left ~unsafe:true dst_account.tez_balance tez_transfer_amount) + in + let new_ticket_amount_dst = + Bounded.(add_left ~unsafe:true dst_leaf.ticket.amount ticket_amount) + in + + let check_counter = src_account.cnt < cnt in + let check_signature = + Schnorr.verify + ~compressed:true + ~msg + ~pk:src_account.pk + ~signature + () + in + let check_balances = + Z.(coerce new_tez_amount_src >= zero) + && Z.(coerce new_ticket_amount_src >= zero) + && Bounded.check new_tez_amount_dst + && Bounded.check new_ticket_amount_dst + in + (* TODO: add check for rollup id *) + let check_rollup_id = rollup_id = header.rollup_id in + let check_ticket_ids = + let check_src = is_tez || amount.id = src_leaf.ticket.id in + let check_dst = + is_tez + || Z.(Bounded.v @@ dst_leaf.ticket.amount = zero) + || amount.id = dst_leaf.ticket.id + in + check_src && check_dst + in + let check_dst_pk = dst_account.pk <> Schnorr.g in + let check_price = Z.(zero = Bounded.v header.price.amount) in + + let valid = + check_counter && check_signature && check_balances && check_dst_pk + && check_ticket_ids && check_price && check_rollup_id + in + + let src_proof, s = + let _, path = Merkle.proof_path src_index s.accounts_tree in + let s = + if valid then ( + let new_ticket_src = + {src_leaf.ticket with amount = new_ticket_amount_src} + in + let new_leaf_src = {src_leaf with ticket = new_ticket_src} in + src_leaves.(src_offset) <- new_leaf_src ; + let src_tree = + Merkle.update_tree + ~input_length:2 + src_tree + src_offset + (scalar_of_leaf new_leaf_src) + in + let new_cnt_src = Bounded.succ ~unsafe:true src_account.cnt in + let new_acc_src = + { + src_account with + tez_balance = new_tez_amount_src; + cnt = new_cnt_src; + tickets_root = Merkle.root src_tree; + } + in + let accounts = + IMap.add + src_index + (new_acc_src, src_leaves, src_tree) + s.accounts + in + let accounts_tree = + Merkle.update_tree + ~input_length:2 + s.accounts_tree + src_index + (scalar_of_account new_acc_src) + in + {s with accounts_tree; accounts}) + else s + in + let root = Merkle.root s.accounts_tree in + ({path; root}, s) + in + let acc_after_src, leaves_after_src, tree_after_src = + get_account src_index s.accounts + in + let leaf_after_src = leaves_after_src.(src_offset) in + let _, src_leaf_path = Merkle.proof_path src_offset tree_after_src in + let src = + { + account = + {before = src_account; after = acc_after_src; proof = src_proof}; + leaf = + { + before = src_leaf; + after = leaf_after_src; + path = src_leaf_path; + }; + } + in + (* We retrieve bl_dst after updating the src_leaf as dst may be equal to src *) + let dst_account, dst_leaves, dst_tree = + get_account dst_index s.accounts + in + let dst_proof, s = + let _, path = Merkle.proof_path dst_index s.accounts_tree in + let s = + if valid then ( + let new_ticket_dst = + { + id = (if is_tez then dst_leaf.ticket.id else amount.id); + amount = new_ticket_amount_dst; + } + in + let new_leaf_dst = {dst_leaf with ticket = new_ticket_dst} in + dst_leaves.(dst_offset) <- new_leaf_dst ; + let dst_tree = + Merkle.update_tree + ~input_length:2 + dst_tree + dst_offset + (scalar_of_leaf new_leaf_dst) + in + let new_acc_dst = + { + dst_account with + tez_balance = new_tez_amount_dst; + tickets_root = Merkle.root dst_tree; + } + in + let accounts = + IMap.add + dst_index + (new_acc_dst, dst_leaves, dst_tree) + s.accounts + in + let accounts_tree = + Merkle.update_tree + ~input_length:2 + s.accounts_tree + dst_index + (scalar_of_account new_acc_dst) + in + {s with accounts_tree; accounts}) + else s + in + let root = Merkle.root s.accounts_tree in + ({path; root}, s) + in + + let acc_after_dst, leaves_after_dst, tree_after_dst = + get_account dst_index s.accounts + in + let leaf_after_dst = leaves_after_dst.(dst_offset) in + let _, dst_leaf_path = Merkle.proof_path dst_offset tree_after_dst in + let dst = + { + account = + {before = dst_account; after = acc_after_dst; proof = dst_proof}; + leaf = + { + before = dst_leaf; + after = leaf_after_dst; + path = dst_leaf_path; + }; + } + in + (s, Transfer op, Some (Transfer {src; dst; valid})) + | Create ({header; payload = {msg = {pk; fee}; signature}} as op) -> + let msg = hash_op @@ Create {header; payload = {pk; fee}} in + let well_formed = Bounded.(check fee) in + if not well_formed then (s, Create op, None) + else + let dst_pos = s.next_position in + let dst_index = dst_pos / Constants.max_nb_tickets in + let dst_offset = dst_pos mod Constants.max_nb_tickets in + assert (dst_offset = 0) ; + let next_empty_pos = dst_pos + Constants.max_nb_tickets in + let next_empty_index = dst_index + 1 in + let next_empty_offset = 0 in + let s = {s with next_position = next_empty_pos} in + let dst_account, dst_leaves, dst_tree = + get_account dst_index s.accounts + in + let next_empty_account, next_empty_leaves, next_empty_tree = + get_account (dst_index + 1) s.accounts + in + let check_next_is_empty = next_empty_account.pk = Schnorr.g in + let check_rollup_id = rollup_id = header.rollup_id in + let check_signature = + Schnorr.verify ~compressed:true ~msg ~pk ~signature () + in + let check_price = + Bounded.v header.price.amount = Bounded.v fee + && header.price.id = Constants.tez_id + in + let valid = + check_signature && check_next_is_empty && check_price + && check_rollup_id + in + + let next_empty_proof, s = + let _, path = Merkle.proof_path next_empty_index s.accounts_tree in + let root = Merkle.root s.accounts_tree in + ({path; root}, s) + in + let dst_proof, s = + let _, path = Merkle.proof_path dst_index s.accounts_tree in + let s = + if valid then + let new_acc_dst = {dst_account with pk} in + let accounts = + IMap.add + dst_index + (new_acc_dst, dst_leaves, dst_tree) + s.accounts + in + let accounts_tree = + Merkle.update_tree + ~input_length:2 + s.accounts_tree + dst_index + (scalar_of_account new_acc_dst) + in + {s with accounts_tree; accounts} + else s + in + let root = Merkle.root s.accounts_tree in + ({path; root}, s) + in + let acc_after_dst, _, _ = get_account dst_index s.accounts in + let dst_leaf = dst_leaves.(dst_offset) in + let _, dst_leaf_path = Merkle.proof_path dst_offset dst_tree in + let dst = + { + account = + {before = dst_account; after = acc_after_dst; proof = dst_proof}; + leaf = {before = dst_leaf; after = dst_leaf; path = dst_leaf_path}; + } + in + let next_empty_leaf = next_empty_leaves.(next_empty_offset) in + let _, ne_leaf_path = + Merkle.proof_path next_empty_offset next_empty_tree + in + let next_empty = + { + account = + { + before = next_empty_account; + after = next_empty_account; + proof = next_empty_proof; + }; + leaf = + { + before = next_empty_leaf; + after = next_empty_leaf; + path = ne_leaf_path; + }; + } + in + (s, Create op, Some (Create {dst; next_empty; valid})) + | Credit ({header; payload = {cnt; dst; amount}} as op) -> + let well_formed = + Bounded.(check cnt && check dst && check amount.amount) + in + if not well_formed then (s, Credit op, None) + else + let dst_index = Z.to_int (coerce dst) / Constants.max_nb_tickets in + let dst_offset = Z.to_int (coerce dst) mod Constants.max_nb_tickets in + + let is_tez = amount.id = Constants.tez_id in + let ticket_amount = + if is_tez then Bounded.make ~bound:Constants.Bound.max_amount Z.zero + else amount.amount + in + let tez_amount = + if is_tez then amount.amount + else Bounded.make ~bound:Constants.Bound.max_amount Z.zero + in + + let dst_account, dst_leaves, dst_tree = + get_account dst_index s.accounts + in + let dst_leaf = dst_leaves.(dst_offset) in + + let new_tez_amount_dst = + Bounded.(add_left ~unsafe:true dst_account.tez_balance tez_amount) + in + let new_ticket_amount_dst = + Bounded.(add_left ~unsafe:true dst_leaf.ticket.amount ticket_amount) + in + + let check_counter = dst_account.cnt < cnt in + let check_balances = + Bounded.check new_tez_amount_dst + && Bounded.check new_ticket_amount_dst + in + let check_rollup_id = rollup_id = header.rollup_id in + let check_ticket_ids = + is_tez + || Z.(Bounded.v @@ dst_leaf.ticket.amount = zero) + || amount.id = dst_leaf.ticket.id + in + let check_price = + Bounded.v header.price.amount = Bounded.v amount.amount + && header.price.id = amount.id + in + let check_dst_pk = dst_account.pk <> Schnorr.g in + + let valid = + check_counter && check_dst_pk && check_balances && check_ticket_ids + && check_price && check_rollup_id + in + + let dst_proof, s = + let _, path = Merkle.proof_path dst_index s.accounts_tree in + let s = + if valid then ( + let new_ticket_dst = + {id = amount.id; amount = new_ticket_amount_dst} + in + let new_leaf_dst = {dst_leaf with ticket = new_ticket_dst} in + dst_leaves.(dst_offset) <- new_leaf_dst ; + let dst_tree = + Merkle.update_tree + ~input_length:2 + dst_tree + dst_offset + (scalar_of_leaf new_leaf_dst) + in + let new_acc_dst = + { + dst_account with + tez_balance = new_tez_amount_dst; + cnt; + tickets_root = Merkle.root dst_tree; + } + in + let accounts = + IMap.add + dst_index + (new_acc_dst, dst_leaves, dst_tree) + s.accounts + in + let accounts_tree = + Merkle.update_tree + ~input_length:2 + s.accounts_tree + dst_index + (scalar_of_account new_acc_dst) + in + {s with accounts_tree; accounts}) + else s + in + let root = Merkle.root s.accounts_tree in + ({path; root}, s) + in + + let acc_after_dst, leaves_after_dst, tree_after_dst = + get_account dst_index s.accounts + in + let leaf_after_dst = leaves_after_dst.(dst_offset) in + let _, dst_leaf_path = Merkle.proof_path dst_offset tree_after_dst in + let dst = + { + account = + {before = dst_account; after = acc_after_dst; proof = dst_proof}; + leaf = + { + before = dst_leaf; + after = leaf_after_dst; + path = dst_leaf_path; + }; + } + in + (s, Credit op, Some (Credit {dst; valid})) + | Debit ({header; payload = {msg = {cnt; src; amount}; signature}} as op) -> + let msg = hash_op @@ Debit {header; payload = {cnt; src; amount}} in + let well_formed = + Bounded.(check cnt && check src && check amount.amount) + in + if not well_formed then (s, Debit op, None) + else + let src_index = Z.to_int (coerce src) / Constants.max_nb_tickets in + let src_offset = Z.to_int (coerce src) mod Constants.max_nb_tickets in + + let src_account, src_leaves, src_tree = + get_account src_index s.accounts + in + let src_leaf = src_leaves.(src_offset) in + + let is_tez = amount.id = Constants.tez_id in + + let ticket_amount = + if is_tez then Bounded.make ~bound:Constants.Bound.max_amount Z.zero + else amount.amount + in + let tez_amount = + if is_tez then amount.amount + else Bounded.make ~bound:Constants.Bound.max_amount Z.zero + in + + let new_tez_amount_src = + Bounded.(sub_left ~unsafe:true src_account.tez_balance tez_amount) + in + let new_ticket_amount_src = + Bounded.(sub_left ~unsafe:true src_leaf.ticket.amount ticket_amount) + in + + let check_counter = src_account.cnt < cnt in + let check_signature = + Schnorr.verify + ~compressed:true + ~msg + ~pk:src_account.pk + ~signature + () + in + let check_balances = + Z.(coerce new_tez_amount_src >= zero) + && Z.(coerce new_ticket_amount_src >= zero) + in + let check_rollup_id = rollup_id = header.rollup_id in + let check_ticket_ids = is_tez || amount.id = src_leaf.ticket.id in + let check_price = + Bounded.v header.price.amount = Bounded.v amount.amount + && header.price.id = amount.id + in + let valid = + check_counter && check_signature && check_balances + && check_ticket_ids && check_price && check_rollup_id + in + + let src_proof, s = + let _, path = Merkle.proof_path src_index s.accounts_tree in + let s = + if valid then ( + let new_ticket_src = + {src_leaf.ticket with amount = new_ticket_amount_src} + in + let new_leaf_src = {src_leaf with ticket = new_ticket_src} in + src_leaves.(src_offset) <- new_leaf_src ; + let src_tree = + Merkle.update_tree + ~input_length:2 + src_tree + src_offset + (scalar_of_leaf new_leaf_src) + in + let new_cnt_src = Bounded.succ ~unsafe:true src_account.cnt in + let new_acc_src = + { + src_account with + tez_balance = new_tez_amount_src; + cnt = new_cnt_src; + tickets_root = Merkle.root src_tree; + } + in + let accounts = + IMap.add + src_index + (new_acc_src, src_leaves, src_tree) + s.accounts + in + let accounts_tree = + Merkle.update_tree + ~input_length:2 + s.accounts_tree + src_index + (scalar_of_account new_acc_src) + in + {s with accounts_tree; accounts}) + else s + in + let root = Merkle.root s.accounts_tree in + ({path; root}, s) + in + let acc_after_src, leaves_after_src, tree_after_src = + get_account src_index s.accounts + in + let leaf_after_src = leaves_after_src.(src_offset) in + let _, src_leaf_path = Merkle.proof_path src_offset tree_after_src in + let src = + { + account = + {before = src_account; after = acc_after_src; proof = src_proof}; + leaf = + { + before = src_leaf; + after = leaf_after_src; + path = src_leaf_path; + }; + } + in + (s, Debit op, Some (Debit {src; valid})) + + (* Get validity from an optional tx storage, as computed by preprocess_op *) + let get_validity tx_s : bool = + match tx_s with + | Some (Transfer t_s) -> t_s.valid + | Some (Create t_s) -> t_s.valid + | Some (Credit t_s) -> t_s.valid + | Some (Debit t_s) -> t_s.valid + | None -> false + + (* Get the actual fee of an op *) + let tx_fee (op : tx) op_s = + let z = Bounded.make ~bound:Constants.Bound.max_fee Z.zero in + match (op, get_validity op_s) with + | Transfer tx, true -> tx.payload.msg.fee + | Create tx, true -> tx.payload.msg.fee + | _ -> z + + let preprocess_private_batch (s : state) ops rollup_id = + let s, ops, ops_s, fees = + List.fold_left + (fun (s, ops, ops_s, acc_fee) op -> + let s, tx, tx_s = preprocess_operation s op rollup_id in + let fee = tx_fee tx tx_s in + let op = match tx with Transfer op -> op | _ -> assert false in + let op_s = + match tx_s with Some (Transfer op_s) -> op_s | _ -> assert false + in + ( s, + op :: ops, + op_s :: ops_s, + Bounded.add_left ~unsafe:true acc_fee fee )) + (s, [], [], Bounded.make ~bound:Constants.Bound.max_amount Z.zero) + ops + in + let ops, ops_s = (List.rev ops, List.rev ops_s) in + (s, ops, ops_s, fees) + + type generate_op_result = { + tx : tx; + tx_s : tx_storage; + fee : fee Bounded.t; + hash : S.t; + exit_validity : bool; + } + + let generate_transaction : + ?src_pos:Z.t -> + ?dst_pos:Z.t -> + ?amount:amount ticket -> + ?fee:Z.t -> + ?cnt:Z.t -> + ?valid:bool -> + ?unsafe:bool -> + sks:Schnorr.sk array -> + state -> + generate_op_result * state = + fun ?src_pos + ?dst_pos + ?amount + ?fee + ?cnt + ?(valid = true) + ?(unsafe = false) + ~sks + s -> + let open Bound in + let unpack_optional ~bound ?opts ?(maxv = Bound.v bound) arg = + match (arg, opts) with + | Some v, _ -> Bounded.make ~unsafe ~bound v + | None, Some opts -> + assert (List.compare_length_with opts 0 > 0) ; + let i = random_int (List.length opts) in + Bounded.make ~unsafe ~bound @@ List.nth opts i + | _ -> Bounded.random ~maxv bound + in + let open_positions = + List.of_seq + (* TODO: use other offsets *) + @@ Seq.map (fun (i, _) -> Z.of_int @@ (max_nb_tickets * i)) + @@ IMap.to_seq s.accounts + in + let src_pos = + unpack_optional ~bound:max_nb_leaves ~opts:open_positions src_pos + in + let src_pos_i = Z.to_int @@ Bounded.v src_pos in + let src_index = src_pos_i / max_nb_tickets in + let src_offset = src_pos_i mod max_nb_tickets in + let dst_pos = + unpack_optional ~bound:max_nb_leaves ~opts:open_positions dst_pos + in + let dst_pos_i = Z.to_int @@ Bounded.v dst_pos in + + let dst_index = dst_pos_i / max_nb_tickets in + let dst_offset = dst_pos_i mod max_nb_tickets in + let sk_src = sks.(src_index) in + let src_acc, src_leaves, _src_tree = get_account src_index s.accounts in + let dst_acc, dst_leaves, _dst_tree = get_account dst_index s.accounts in + + let src_leaf = src_leaves.(src_offset) in + let dst_leaf = dst_leaves.(dst_offset) in + let cnt = + Option.( + value + ~default:src_acc.cnt + (map (Bounded.make ~unsafe ~bound:max_counter) cnt)) + in + let cnt = Bounded.succ cnt in + let fee = + unpack_optional + ~bound:max_fee + ~maxv:Z.(min (Bounded.v src_acc.tez_balance) (Bound.v max_fee)) + fee + in + let amount_id = + Option.(value ~default:tez_id (map (fun {id; _} -> id) amount)) + in + let is_tez = amount_id = tez_id in + let max_src_amount = + if is_tez then + Z.(min Bounded.(v src_acc.tez_balance - v fee) (Bound.v max_amount)) + else Z.(min Bounded.(v src_leaf.ticket.amount) (Bound.v max_amount)) + in + let max_dst_amount = + let bal = + if is_tez then dst_acc.tez_balance else dst_leaf.ticket.amount + in + Z.(Bound.v max_balance - Bounded.v bal) + in + let amount_amount = + unpack_optional + ~bound:max_amount + ~maxv:Z.(min max_src_amount max_dst_amount) + (Option.map (fun {amount; id = _id} -> Bounded.v amount) amount) + in + let amount = {id = amount_id; amount = amount_amount} in + let header = Dummy.header in + let unsigned_payload = {cnt; src = src_pos; dst = dst_pos; amount; fee} in + let op = sign_op sk_src (Transfer {header; payload = unsigned_payload}) in + let msg = hash_op (Transfer {header; payload = unsigned_payload}) in + let s, tx, tx_s = preprocess_operation s op header.rollup_id in + let tx_s = Option.get tx_s in + ( { + tx; + tx_s; + fee = + (if valid then fee else Bounded.make ~unsafe ~bound:max_fee Z.zero); + hash = msg; + exit_validity = false; + }, + s ) + + let generate_transactions : + ?src_pos:Z.t -> + ?dst_pos:Z.t -> + ?amount:amount ticket -> + ?fee:Z.t -> + ?cnt:Z.t -> + ?valid:bool -> + ?unsafe:bool -> + nb_batches:int -> + batch_size:int -> + sks:Schnorr.sk array -> + state -> + (generate_op_result list * state) list = + fun ?src_pos + ?dst_pos + ?amount + ?fee + ?cnt + ?(valid = true) + ?(unsafe = false) + ~nb_batches + ~batch_size + ~sks + state -> + let make_batch state = + let batch, state = + List.fold_left + (fun (txs, state) _ -> + let tx, state = + generate_transaction + ?src_pos + ?dst_pos + ?amount + ?fee + ?cnt + ~valid + ~unsafe + ~sks + state + in + (tx :: txs, state)) + ([], state) + (List.init batch_size Fun.id) + in + (List.rev batch, state) + in + let batches, _ = + List.fold_left + (fun (batches, state) _ -> + let batch, state = make_batch state in + ((batch, state) :: batches, state)) + ([], state) + (List.init nb_batches Fun.id) + in + List.rev batches +end + +module V (L : LIB) = struct + module Hash = HashPV.V (L) + module Plompiler_Curve = JubjubEdwards (L) + module Schnorr = SchnorrPV.V (L) + module Merkle = MerklePV.V (L) + open L + module T = Types.V (L) + open T + module Encodings = Types.Encodings (L) + + let compression_bound (values : unit Bounded_u.t list) = + let values = (values :> (scalar repr * Z.t) list) in + List.fold_left Z.mul Z.one (List.map snd values) + + let monadic_compress (values : unit Bounded_u.t list) = + assert (compression_bound values < S.order) ; + let values = (values :> (scalar repr * Z.t) list) in + foldM + (fun acc (v, v_bound) -> Num.add ~ql:(S.of_z v_bound) acc v) + (fst @@ List.hd values) + (List.tl values) + + let assert_merkle_proof x path root = + let* b = Merkle.merkle_proof path x root in + Bool.assert_true b + + let hash_leaf (l : leaf_u) = + let* compressed = monadic_compress Bounded_u.[f l.pos; f l.ticket.amount] in + Hash.digest ~input_length:2 (to_list [l.ticket.id; compressed]) + + let hash_account (acc : account_u) = + let pk_x, _pk_y = of_pair acc.pk in + let* compressed = + monadic_compress Bounded_u.[f acc.tez_balance; f acc.cnt] + in + let* h = Hash.digest ~input_length:2 (to_list [pk_x; compressed]) in + (* we leverage the Correlation-Intractablity (with respecto to +) of the + hash function and add [h] to the ticket's root (which is also the output + of a hash); alternatively (and to avoid relying on CI) we could define + [scalar_of_account] as the hash of all 3 inputs [pk_x, compressed, + acc.tickets_root ], but that would require one extra iteration of the + hash function *) + Num.add h acc.tickets_root + + let assert_tree_proofs (acc : account_u) (leaf : leaf_u) path_acc path_leaf + root = + let* scalar_acc = hash_account acc in + assert_merkle_proof scalar_acc path_acc root + >* let* scalar_leaf = hash_leaf leaf in + assert_merkle_proof scalar_leaf path_leaf acc.tickets_root + + let coerce (type a) (x : a Bounded_u.t) = + fst (x : a Bounded_u.t :> scalar repr * Z.t) + + let check_eq_account (a : account_u) (b : account_u) = + with_bool_check (equal a.pk b.pk) + >* with_bool_check (equal (coerce a.tez_balance) (coerce b.tez_balance)) + >* with_bool_check (equal (coerce a.cnt) (coerce b.cnt)) + >* with_bool_check (equal a.tickets_root b.tickets_root) + + let check_eq_leaf (a : leaf_u) (b : leaf_u) = + with_bool_check (equal (coerce a.pos) (coerce b.pos)) + >* with_bool_check (equal a.ticket.id b.ticket.id) + >* with_bool_check (equal (coerce a.ticket.amount) (coerce b.ticket.amount)) + + let predicate_fees ~old_root ~old_next_pos ~new_root ~new_next_pos ~fees + operator = + let safety = Encodings.Bounded_e.Unsafe in + + let* old_root = input ~kind:`Public @@ Input.scalar old_root in + let* old_next_pos = + input ~kind:`Public @@ Encodings.(pos_encoding ~safety).input old_next_pos + in + let* new_root = input ~kind:`Public @@ Input.scalar new_root in + let* new_next_pos = + input ~kind:`Public @@ Encodings.(pos_encoding ~safety).input new_next_pos + in + let* fees = + input ~kind:`Public @@ Encodings.((amount_encoding ~safety).input) fees + in + let* operator = + input @@ Encodings.account_tree_el_encoding.input operator + in + let* generator = + Plompiler_Curve.(input_point @@ affine_to_point Schnorr.g) + in + let fees = Encodings.((amount_encoding ~safety).decode) fees in + let operator = Encodings.account_tree_el_encoding.decode operator in + assert_equal old_next_pos new_next_pos + >* let* before_s = hash_account operator.before in + let* after_s = hash_account operator.after in + assert_merkle_proof before_s operator.proof.path old_root + >* assert_merkle_proof after_s operator.proof.path new_root + (* When checking MPs, we need to check that the whole leaves are + consistent, not just the new balance *) + >* let* new_bl_operator = + Bounded_u.add_left operator.before.tez_balance fees + in + let new_acc_operator = + {operator.before with tez_balance = new_bl_operator} + in + check_eq_account new_acc_operator operator.after + >* + let x_pk = of_pair operator.before.pk |> fst in + let x_g = of_pair generator |> fst in + let* diff = Num.add x_pk ~qr:S.mone x_g in + with_bool_check (Num.is_not_zero diff) + + let hash_op = function + | `Transfer (tx : transfer_u) -> + let* compressed = + monadic_compress + Bounded_u. + [ + f tx.header.op_code; + f tx.header.price.amount; + f tx.payload.msg.src; + f tx.payload.msg.dst; + f tx.payload.msg.fee; + f tx.payload.msg.amount.amount; + f tx.payload.msg.cnt; + ] + in + Hash.digest + ~input_length:4 + (to_list + [ + tx.header.l1_dst; + compressed; + tx.header.price.id; + tx.payload.msg.amount.id; + ]) + | `Create (tx : create_u) -> + let* compressed = + monadic_compress + Bounded_u. + [ + f tx.header.op_code; + f tx.header.price.amount; + f tx.payload.msg.fee; + ] + in + let x_pk, y_pk = of_pair tx.payload.msg.pk in + Hash.digest + ~input_length:5 + (to_list + [tx.header.l1_dst; compressed; x_pk; y_pk; tx.header.price.id]) + | `Credit (tx : credit_u) -> + let* compressed = + monadic_compress + Bounded_u. + [ + f tx.header.op_code; + f tx.header.price.amount; + f tx.payload.dst; + f tx.payload.amount.amount; + f tx.payload.cnt; + ] + in + Hash.digest + ~input_length:4 + (to_list + [ + tx.header.l1_dst; + compressed; + tx.header.price.id; + tx.payload.amount.id; + ]) + | `Debit (tx : debit_u) -> + let* compressed = + monadic_compress + Bounded_u. + [ + f tx.header.op_code; + f tx.header.price.amount; + f tx.payload.msg.src; + f tx.payload.msg.amount.amount; + f tx.payload.msg.cnt; + ] + in + Hash.digest + ~input_length:4 + (to_list + [ + tx.header.l1_dst; + compressed; + tx.header.price.id; + tx.payload.msg.amount.id; + ]) + + let expected_op_code : Types.P.tx -> S.t = function + | Types.P.Transfer _ -> S.zero + | Types.P.Create _ -> S.one + | Types.P.Credit _ -> S.of_int 2 + | Types.P.Debit _ -> S.of_int 3 + + let get_op_code : Types.P.tx -> Z.t = + let open Types.P.Bounded in + function + | Types.P.Transfer tx -> v tx.header.op_code + | Types.P.Create tx -> v tx.header.op_code + | Types.P.Credit tx -> v tx.header.op_code + | Types.P.Debit tx -> v tx.header.op_code + + let predicate_ill_formed ~old_root ~old_next_pos ~new_root ~new_next_pos ~fee + ~exit_validity ~rollup_id (t : Types.P.tx) = + let safety = Encodings.Bounded_e.Safe in + let* old_root = input ~kind:`Public @@ Input.scalar old_root in + let* old_next_pos = + input ~kind:`Public @@ Encodings.(pos_encoding ~safety).input old_next_pos + in + let* new_root = input ~kind:`Public @@ Input.scalar new_root in + let* new_next_pos = + input ~kind:`Public @@ Encodings.(pos_encoding ~safety).input new_next_pos + in + let* fee = + input ~kind:`Public @@ Encodings.((fee_encoding ~safety).input) fee + in + let fee = Encodings.((fee_encoding ~safety).decode) fee in + let* exit_validity = input ~kind:`Public @@ Input.bool exit_validity in + let* _rollup_id = + input ~kind:`Public @@ Encodings.(tezos_zkru_encoding.input) rollup_id + in + (* Assert that fee = 0 *) + Bool.assert_false (unsafe_bool_of_scalar @@ coerce fee) + >* assert_equal old_root new_root + >* assert_equal old_next_pos new_next_pos + >* + match t with + | Types.P.Transfer tx -> + let* tx = + input ~kind:`Public + @@ Encodings.((transfer_encoding ~safety).input) tx + in + let tx = Encodings.((transfer_encoding ~safety).decode) tx in + Num.assert_eq_const (coerce tx.header.op_code) (expected_op_code t) + >* let* b_tx = get_checks_wire in + Bool.assert_false b_tx + | Types.P.Create tx -> + let* tx = + input ~kind:`Public @@ Encodings.((create_encoding ~safety).input) tx + in + let tx = Encodings.((create_encoding ~safety).decode) tx in + Num.assert_eq_const (coerce tx.header.op_code) (expected_op_code t) + >* Bool.assert_true exit_validity + >* let* b_tx = get_checks_wire in + Bool.assert_false b_tx + | Types.P.Credit tx -> + let* tx = + input ~kind:`Public @@ Encodings.(credit_encoding ~safety).input tx + in + let tx = Encodings.((credit_encoding ~safety).decode) tx in + Num.assert_eq_const (coerce tx.header.op_code) (expected_op_code t) + >* Bool.assert_true exit_validity + >* let* b_tx = get_checks_wire in + Bool.assert_false b_tx + | Types.P.Debit tx -> + let* tx = + input ~kind:`Public @@ Encodings.(debit_encoding ~safety).input tx + in + let tx = Encodings.((debit_encoding ~safety).decode) tx in + Num.assert_eq_const (coerce tx.header.op_code) (expected_op_code t) + >* Bool.assert_false exit_validity + >* let* b_tx = get_checks_wire in + Bool.assert_false b_tx + + let transfer_circuit ~op_code ~old_root ~old_next_pos ~rollup_id ~generator + (tx : transfer_u) (tx_s : transfer_storage_u) = + (* The validation of a transaction is done through a series of + boolean checks and assertions. + The assertions are important to stop malicious validators + from censoring transactions. Given that the circuit can + only determine the validity of a Tx from the src/dst accounts + provided by the prover, it is important to make sure that + these values are correct (through the Merkle proofs) and + in the right positions. + Thus, the Merkle proofs must always be valid. This has two + consecuences: + 1. The positions present in a Tx must always be in range. + 2. We add more constraints, as we need to check that the + leaves used for the proofs of the new state correspond to + their expected values. + *) + Num.assert_eq_const (coerce tx.header.op_code) op_code + >* (* ---------- Assert the init src leaf is in the init tree ---------- *) + assert_tree_proofs + tx_s.src.account.before + tx_s.src.leaf.before + tx_s.src.account.proof.path + tx_s.src.leaf.path + old_root + >* (* ---------- Assert the init dst leaf is in the tmp tree ---------- *) + assert_tree_proofs + tx_s.dst.account.before + tx_s.dst.leaf.before + tx_s.dst.account.proof.path + tx_s.dst.leaf.path + tx_s.src.account.proof.root + >* (* ---------- Assert the new src leaf is in the tmp tree ---------- *) + assert_tree_proofs + tx_s.src.account.after + tx_s.src.leaf.after + tx_s.src.account.proof.path + tx_s.src.leaf.path + tx_s.src.account.proof.root + >* (* ---------- Assert the new dst leaf is in the new tree ---------- *) + assert_tree_proofs + tx_s.dst.account.after + tx_s.dst.leaf.after + tx_s.dst.account.proof.path + tx_s.dst.leaf.path + tx_s.dst.account.proof.root + >* (* ------------------- Assert positions --------------------- + Leaves contain their position to check that the proof's + path actually corresponds to the correct leaf. *) + assert_equal (coerce tx.payload.msg.src) (coerce tx_s.src.leaf.before.pos) + >* assert_equal + (coerce tx.payload.msg.dst) + (coerce tx_s.dst.leaf.before.pos) + (* ----------------- Check rollup id ----------------------- *) + >* with_bool_check (equal rollup_id tx.header.rollup_id) + >* (* ----------------- Check ticket ids ---------------------- + If the amount is in tez (or the dst balance is 0), then we don't enforce this *) + let* is_tez = Num.is_eq_const tx.payload.msg.amount.id Constants.tez_id in + let* dst_bal_is_0 = + Num.is_zero @@ coerce tx_s.dst.leaf.before.ticket.amount + in + let* equal_src = + equal tx.payload.msg.amount.id tx_s.src.leaf.before.ticket.id + in + with_bool_check (Bool.bor is_tez equal_src) + >* let* is_tez_or_bal_0 = Bool.bor is_tez dst_bal_is_0 in + let* equal_dst = + equal tx.payload.msg.amount.id tx_s.dst.leaf.before.ticket.id + in + with_bool_check (Bool.bor is_tez_or_bal_0 equal_dst) + >* (* ----------------- Check new leaves -----------------------*) + let* z = constant_scalar S.zero in + let* ticket_amount = + Bool.ifthenelse is_tez z (coerce tx.payload.msg.amount.amount) + in + let ticket_amount = + Bounded_u.make_unsafe ~bound:Constants.Bound.max_amount ticket_amount + in + let* new_ticket_amnt_src = + Bounded_u.sub_left tx_s.src.leaf.before.ticket.amount ticket_amount + in + let new_ticket_src = + {id = tx_s.src.leaf.before.ticket.id; amount = new_ticket_amnt_src} + in + let new_leaf_src = {tx_s.src.leaf.before with ticket = new_ticket_src} in + let* new_ticket_amnt_dst = + Bounded_u.add_left tx_s.dst.leaf.before.ticket.amount ticket_amount + in + let* new_ticket_id_dst = + Bool.ifthenelse + is_tez + tx_s.dst.leaf.before.ticket.id + tx.payload.msg.amount.id + in + let new_ticket_dst = + {id = new_ticket_id_dst; amount = new_ticket_amnt_dst} + in + let new_leaf_dst = {tx_s.dst.leaf.before with ticket = new_ticket_dst} in + check_eq_leaf new_leaf_src tx_s.src.leaf.after + >* check_eq_leaf new_leaf_dst tx_s.dst.leaf.after + >* (* ----------------- Check new accounts -----------------------*) + let* tez_transfer_amount = + Bool.ifthenelse is_tez (coerce tx.payload.msg.amount.amount) z + in + let tez_transfer_amount = + Bounded_u.make_unsafe + ~bound:Constants.Bound.max_amount + tez_transfer_amount + in + let* tez_amount = + Bounded_u.add_left tez_transfer_amount tx.payload.msg.fee + in + + let* new_tez_bal_src = + Bounded_u.sub_left tx_s.src.account.before.tez_balance tez_amount + in + let new_acc_src = + { + tx_s.src.account.before with + tez_balance = new_tez_bal_src; + cnt = tx.payload.msg.cnt; + (* This value has already been checked in the Merkle proof, see README *) + tickets_root = tx_s.src.account.after.tickets_root; + } + in + let* new_tez_bal_dst = + Bounded_u.add_left + tx_s.dst.account.before.tez_balance + tez_transfer_amount + in + let new_acc_dst = + { + tx_s.dst.account.before with + tickets_root = tx_s.dst.account.after.tickets_root; + tez_balance = new_tez_bal_dst; + } + in + check_eq_account new_acc_src tx_s.src.account.after + >* check_eq_account new_acc_dst tx_s.dst.account.after + >* (* ---------------------- Check counter ----------------------- *) + let* expected_cnt = Bounded_u.succ tx_s.src.account.before.cnt in + with_bool_check (equal (coerce expected_cnt) (coerce tx.payload.msg.cnt)) + >* (* ---------------------- Check price = 0 ----------------------- *) + with_bool_check (Num.is_zero @@ coerce tx.header.price.amount) + >* + (* Check pk_dst <> gen (used as dummy pk to note closed accounts) + Checking that the x coordinates of pk_dst and generator are + different is enough as we do not want both points with the + generator x coordinate to be used as public key. *) + let x_pk = of_pair tx_s.dst.account.before.pk |> fst in + let x_g = of_pair generator |> fst in + let* diff = Num.add x_pk ~qr:S.mone x_g in + with_bool_check (Num.is_not_zero diff) + >* (* Building signature message + ---------- Verify signature ---------- *) + let* msg = hash_op (`Transfer tx) in + (* Building signature proof *) + with_bool_check + (Schnorr.verify + ~compressed:true + ~g:generator + ~msg + ~pk:tx_s.src.account.before.pk + ~signature:tx.payload.signature + ()) + >* let* b_tx = get_checks_wire in + let* expected_fee = + Bool.ifthenelse b_tx (coerce tx.payload.msg.fee) z + in + let* root_next = + Bool.ifthenelse b_tx tx_s.dst.account.proof.root old_root + in + assert_equal b_tx tx_s.valid + >* ret + ( root_next, + old_next_pos, + Bounded_u.make_unsafe + ~bound:Constants.Bound.max_fee + expected_fee ) + + let predicate_op ?(public = true) ~old_root ~old_next_pos ~new_root + ~new_next_pos ~fee ~exit_validity ~rollup_id (t : Types.P.tx) + (t_storage : Types.P.tx_storage) = + (* bounded encoding safety *) + let safety = Encodings.Bounded_e.Unsafe in + let* old_root = input ~kind:`Public @@ Input.scalar old_root in + let* old_next_pos = + input ~kind:`Public @@ Encodings.(pos_encoding ~safety).input old_next_pos + in + let* new_root = input ~kind:`Public @@ Input.scalar new_root in + let* new_next_pos = + input ~kind:`Public @@ Encodings.(pos_encoding ~safety).input new_next_pos + in + let* fee = + input ~kind:`Public @@ Encodings.((fee_encoding ~safety).input) fee + in + let fee = Encodings.((fee_encoding ~safety).decode) fee in + let* exit_validity = input ~kind:`Public @@ Input.bool exit_validity in + let* rollup_id = + input ~kind:`Public @@ Encodings.(tezos_zkru_encoding.input) rollup_id + in + match (t, t_storage) with + | Transfer tx, Transfer tx_s -> + let kind = if public then `Public else `Private in + let* tx = + input ~kind @@ Encodings.((transfer_encoding ~safety).input) tx + in + let tx = Encodings.((transfer_encoding ~safety).decode) tx in + let* tx_s = input @@ Encodings.(transfer_storage_encoding.input) tx_s in + let tx_s = Encodings.(transfer_storage_encoding.decode) tx_s in + let* generator = + Plompiler_Curve.(input_point @@ affine_to_point Schnorr.g) + in + let* root_next, next_pos_next, computed_fee = + transfer_circuit + ~op_code:(expected_op_code t) + ~old_root + ~old_next_pos + ~rollup_id + ~generator + tx + tx_s + in + assert_equal root_next new_root + >* assert_equal next_pos_next new_next_pos + >* assert_equal (coerce computed_fee) (coerce fee) + | Create tx, Create tx_s -> + assert public ; + let* tx = + input ~kind:`Public @@ Encodings.((create_encoding ~safety).input) tx + in + let tx = Encodings.((create_encoding ~safety).decode) tx in + let* tx_s = input @@ Encodings.(create_storage_encoding.input) tx_s in + let tx_s = Encodings.(create_storage_encoding.decode) tx_s in + let* generator = + Plompiler_Curve.(input_point @@ affine_to_point Schnorr.g) + in + Num.assert_eq_const (coerce tx.header.op_code) (expected_op_code t) + >* let* dst_account_before_s = hash_account tx_s.dst.account.before in + let* dst_account_after_s = hash_account tx_s.dst.account.after in + let* next_empty_account_s = + hash_account tx_s.next_empty.account.before + in + assert_merkle_proof + dst_account_before_s + tx_s.dst.account.proof.path + old_root + >* assert_merkle_proof + dst_account_after_s + tx_s.dst.account.proof.path + tx_s.dst.account.proof.root + >* assert_merkle_proof + next_empty_account_s + tx_s.next_empty.account.proof.path + old_root + (* [tx_s.next_empty.after] is ignored, as that account doesn't change *) + >* (* Assert that the position used is the old_next_pos + This value has already been checked in the Merkle proof, see README *) + assert_equal old_next_pos (coerce tx_s.dst.leaf.after.pos) + >* assert_equal new_next_pos (coerce tx_s.next_empty.leaf.before.pos) + >* + (* Assert new_next_pos is "default" *) + let x_pk = of_pair tx_s.next_empty.account.before.pk |> fst in + let x_g = of_pair generator |> fst in + let* diff = Num.add x_pk ~qr:S.mone x_g in + with_bool_check (Num.is_zero diff) + >* + (* Check initial account is "default" *) + let x_pk = of_pair tx_s.dst.account.before.pk |> fst in + let x_g = of_pair generator |> fst in + let* diff = Num.add x_pk ~qr:S.mone x_g in + with_bool_check (Num.is_zero diff) + (* Compare with expected account *) + >* + let new_acc_dst = + {tx_s.dst.account.before with pk = tx.payload.msg.pk} + in + check_eq_account new_acc_dst tx_s.dst.account.after + (* ----------------- Check rollup id -----------------------*) + >* with_bool_check (equal rollup_id tx.header.rollup_id) + >* (* -- Check price = fee and that fee is the expected value -- *) + with_bool_check (Num.is_eq_const tx.header.price.id Constants.tez_id) + >* with_bool_check + (equal + (coerce tx.header.price.amount) + (coerce tx.payload.msg.fee)) + >* with_bool_check + (Num.is_eq_const + (coerce tx.payload.msg.fee) + (S.of_z Constants.create_fee)) + >* (* ---------- Verify signature ---------- *) + (* Building signature message *) + (* TODO: We could hash it as + Hash(pk_x, pk_y, fee) := Anemoi(pk_x, pk_y + 2 * fee) + *) + let* msg = hash_op (`Create tx) in + (* Building signature proof *) + with_bool_check + (Schnorr.verify + ~compressed:true + ~g:generator + ~msg + ~pk:tx.payload.msg.pk + ~signature:tx.payload.signature + ()) + >* let* b_tx = get_checks_wire in + let* z = constant_scalar S.zero in + let* expected_fee = + Bool.ifthenelse b_tx (coerce tx.payload.msg.fee) z + in + assert_equal (coerce fee) expected_fee + >* let* root_next = + Bool.ifthenelse b_tx tx_s.dst.account.proof.root old_root + in + assert_equal b_tx tx_s.valid + >* let* not_valid = Bool.bnot b_tx in + assert_equal not_valid exit_validity + >* assert_equal root_next new_root + | Credit tx, Credit tx_s -> + assert public ; + let* tx = + input ~kind:`Public @@ Encodings.(credit_encoding ~safety).input tx + in + let tx = Encodings.(credit_encoding ~safety).decode tx in + let* tx_s = input @@ Encodings.(credit_storage_encoding.input) tx_s in + let tx_s = Encodings.(credit_storage_encoding.decode) tx_s in + let* generator = + Plompiler_Curve.(input_point @@ affine_to_point Schnorr.g) + in + + assert_equal old_next_pos new_next_pos + >* Num.assert_eq_const (coerce tx.header.op_code) (expected_op_code t) + >* (* ---------- Assert the init dst leaf is in the init tree ---------- *) + assert_tree_proofs + tx_s.dst.account.before + tx_s.dst.leaf.before + tx_s.dst.account.proof.path + tx_s.dst.leaf.path + old_root + >* (* ---------- Assert the new dst leaf is in the new tree ---------- *) + assert_tree_proofs + tx_s.dst.account.after + tx_s.dst.leaf.after + tx_s.dst.account.proof.path + tx_s.dst.leaf.path + tx_s.dst.account.proof.root + >* + (* Leaves contain their position to check that the proof's + path actually corresponds to the correct leaf. *)(* ------------------- Assert positions --------------------- *) + assert_equal (coerce tx.payload.dst) (coerce tx_s.dst.leaf.before.pos) + (* Assert fee is equal to 0 *) + >* Bool.assert_false (unsafe_bool_of_scalar @@ coerce fee) + (* ----------------- Check rollup id -----------------------*) + >* with_bool_check (equal rollup_id tx.header.rollup_id) + (* ----------------- Check ticket ids ---------------------- *) + (* You can credit to any position with a balance of 0 *) + >* let* is_tez = + Num.is_eq_const tx.payload.amount.id Constants.tez_id + in + let* eq_id = + equal tx.payload.amount.id tx_s.dst.leaf.before.ticket.id + in + let* is_tez_or_eq_id = Bool.bor is_tez eq_id in + let* bal_0 = + Num.is_zero (coerce tx_s.dst.leaf.before.ticket.amount) + in + with_bool_check (Bool.bor is_tez_or_eq_id bal_0) + >* (* ----------------- Check new leaf and acc ---------------------- *) + let* z = constant_scalar S.zero in + let* ticket_amount = + Bool.ifthenelse is_tez z (coerce tx.payload.amount.amount) + in + let ticket_amount = + Bounded_u.make_unsafe + ~bound:Constants.Bound.max_amount + ticket_amount + in + let* new_ticket_amnt_dst = + Bounded_u.add_left tx_s.dst.leaf.before.ticket.amount ticket_amount + in + let* new_ticket_id_dst = + Bool.ifthenelse + is_tez + tx_s.dst.leaf.before.ticket.id + tx.payload.amount.id + in + let new_ticket_dst = + {id = new_ticket_id_dst; amount = new_ticket_amnt_dst} + in + + let new_leaf_dst = + {tx_s.dst.leaf.before with ticket = new_ticket_dst} + in + let* tez_credit_amount = + Bool.ifthenelse is_tez (coerce tx.payload.amount.amount) z + in + let tez_credit_amount = + Bounded_u.make_unsafe + ~bound:Constants.Bound.max_amount + tez_credit_amount + in + let* new_tez_bal_dst = + Bounded_u.add_left + tx_s.dst.account.before.tez_balance + tez_credit_amount + in + let new_acc_dst = + { + tx_s.dst.account.before with + tez_balance = new_tez_bal_dst; + cnt = tx.payload.cnt; + tickets_root = tx_s.dst.account.after.tickets_root; + } + in + check_eq_leaf new_leaf_dst tx_s.dst.leaf.after + >* check_eq_account new_acc_dst tx_s.dst.account.after + >* (* ---------------------- Check counter ----------------------- *) + let* expected_cnt = Bounded_u.succ tx_s.dst.account.before.cnt in + with_bool_check (equal (coerce expected_cnt) (coerce tx.payload.cnt)) + >* + (* Check pk_dst <> gen (used as dummy pk to note closed accounts) *) + (* Checking that the x coordinates of pk_dst and generator are + different is enough as we do not want both points with the + generator x coordinate to be used as public key. *) + let x_pk = of_pair tx_s.dst.account.before.pk |> fst in + let x_g = of_pair generator |> fst in + let* diff = Num.add x_pk ~qr:S.mone x_g in + with_bool_check (Num.is_not_zero diff) + >* (* ---------- Check price = amount ---------- *) + with_bool_check (equal tx.header.price.id tx.payload.amount.id) + >* with_bool_check + (equal + (coerce tx.header.price.amount) + (coerce tx.payload.amount.amount)) + >* let* b_tx = get_checks_wire in + let* root_next = + Bool.ifthenelse b_tx tx_s.dst.account.proof.root old_root + in + assert_equal b_tx tx_s.valid + >* let* not_valid = Bool.bnot b_tx in + assert_equal not_valid exit_validity + >* assert_equal root_next new_root + | Debit tx, Debit tx_s -> + assert public ; + let* tx = + input ~kind:`Public @@ Encodings.(debit_encoding ~safety).input tx + in + let tx = Encodings.(debit_encoding ~safety).decode tx in + let* tx_s = input @@ Encodings.(debit_storage_encoding.input) tx_s in + let tx_s = Encodings.(debit_storage_encoding.decode) tx_s in + let* generator = + Plompiler_Curve.(input_point @@ affine_to_point Schnorr.g) + in + + assert_equal old_next_pos new_next_pos + >* Num.assert_eq_const (coerce tx.header.op_code) (expected_op_code t) + >* (* ---------- Assert the init src leaf is in the init tree ---------- *) + assert_tree_proofs + tx_s.src.account.before + tx_s.src.leaf.before + tx_s.src.account.proof.path + tx_s.src.leaf.path + old_root + >* (* ---------- Assert the new src leaf is in the new tree ---------- *) + assert_tree_proofs + tx_s.src.account.after + tx_s.src.leaf.after + tx_s.src.account.proof.path + tx_s.src.leaf.path + tx_s.src.account.proof.root + >* + (* Leaves contain their position to check that the proof's + path actually corresponds to the correct leaf. *)(* ------------------- Assert positions --------------------- *) + assert_equal + (coerce tx.payload.msg.src) + (coerce tx_s.src.leaf.before.pos) + (* Assert fee is equal to 0 *) + >* Bool.assert_false (unsafe_bool_of_scalar @@ coerce fee) + (* ----------------- Check rollup id -----------------------*) + >* with_bool_check (equal rollup_id tx.header.rollup_id) + (* ----------------- Check ticket ids ---------------------- *) + >* let* is_tez = + Num.is_eq_const tx.payload.msg.amount.id Constants.tez_id + in + let* eq_id = + equal tx.payload.msg.amount.id tx_s.src.leaf.before.ticket.id + in + with_bool_check (Bool.bor is_tez eq_id) + >* (* ----------------- Check new leaves -----------------------*) + let* z = constant_scalar S.zero in + let* ticket_amount = + Bool.ifthenelse is_tez z (coerce tx.payload.msg.amount.amount) + in + let ticket_amount = + Bounded_u.make_unsafe + ~bound:Constants.Bound.max_amount + ticket_amount + in + let* new_ticket_amnt_src = + Bounded_u.sub_left tx_s.src.leaf.before.ticket.amount ticket_amount + in + let new_ticket_src = + {id = tx.payload.msg.amount.id; amount = new_ticket_amnt_src} + in + let new_leaf_src = + {tx_s.src.leaf.before with ticket = new_ticket_src} + in + + let* tez_debit_amount = + Bool.ifthenelse is_tez (coerce tx.payload.msg.amount.amount) z + in + let tez_debit_amount = + Bounded_u.make_unsafe + ~bound:Constants.Bound.max_amount + tez_debit_amount + in + let* new_tez_bal_src = + Bounded_u.sub_left + tx_s.src.account.before.tez_balance + tez_debit_amount + in + let new_acc_src = + { + tx_s.src.account.before with + tez_balance = new_tez_bal_src; + cnt = tx.payload.msg.cnt; + tickets_root = tx_s.src.account.after.tickets_root; + } + in + + check_eq_leaf new_leaf_src tx_s.src.leaf.after + >* check_eq_account new_acc_src tx_s.src.account.after + >* (* ---------------------- Check counter ----------------------- *) + let* expected_cnt = Bounded_u.succ tx_s.src.account.before.cnt in + with_bool_check + (equal (coerce expected_cnt) (coerce tx.payload.msg.cnt)) + >* (* ---------- Check price = amount ---------- *) + with_bool_check (equal tx.header.price.id tx.payload.msg.amount.id) + >* with_bool_check + (equal + (coerce tx.header.price.amount) + (coerce tx.payload.msg.amount.amount)) + >* (* ---------- Verify signature ---------- *) + + (* Building signature message *) + let* msg = hash_op (`Debit tx) in + (* Building signature proof *) + with_bool_check + (Schnorr.verify + ~compressed:true + ~g:generator + ~msg + ~pk:tx_s.src.account.before.pk + ~signature:tx.payload.signature + ()) + >* let* b_tx = get_checks_wire in + let* root_next = + Bool.ifthenelse b_tx tx_s.src.account.proof.root old_root + in + assert_equal b_tx tx_s.valid + >* assert_equal b_tx exit_validity + >* assert_equal root_next new_root + | _ -> assert false + + let predicate_private_batch ~old_root ~old_next_pos ~new_root ~new_next_pos + ~fees ~rollup_id (ops : Types.P.transfer list) + (ops_s : Types.P.transfer_storage list) = + assert (List.compare_lengths ops ops_s = 0) ; + let safety = Encodings.Bounded_e.Unsafe in + let* old_root = input ~kind:`Public @@ Input.scalar old_root in + let* old_next_pos = + input ~kind:`Public @@ Encodings.(pos_encoding ~safety).input old_next_pos + in + let* new_root = input ~kind:`Public @@ Input.scalar new_root in + let* new_next_pos = + input ~kind:`Public @@ Encodings.(pos_encoding ~safety).input new_next_pos + in + let* fees = + input ~kind:`Public @@ Encodings.((amount_encoding ~safety).input) fees + in + let fees = Encodings.((amount_encoding ~safety).decode) fees in + let* rollup_id = + input ~kind:`Public @@ Encodings.(tezos_zkru_encoding.input) rollup_id + in + let* ops = + mapM + (fun tx -> input @@ Encodings.((transfer_encoding ~safety).input tx)) + ops + in + let ops = List.map Encodings.((transfer_encoding ~safety).decode) ops in + let* ops_s = + mapM + (fun tx_s -> input @@ Encodings.(transfer_storage_encoding.input tx_s)) + ops_s + in + let ops_s = List.map Encodings.(transfer_storage_encoding.decode) ops_s in + let* generator = + Plompiler_Curve.(input_point @@ affine_to_point Schnorr.g) + in + let op_code = S.zero in + let* z = constant_scalar S.zero in + let z = Bounded_u.make_unsafe ~bound:Constants.Bound.max_amount z in + let* computed_root, computed_fees = + fold2M + (fun (computed_root, computed_fees) op op_s -> + let* computed_root, _, fee = + transfer_circuit + ~op_code + ~old_root:computed_root + ~old_next_pos + ~rollup_id + ~generator + op + op_s + in + (* TODO: should we bound check every time? Or just at the end *) + let* computed_fees = + Bounded_u.add_left ~unsafe:true computed_fees fee + in + ret (computed_root, computed_fees)) + (old_root, z) + ops + ops_s + in + assert_equal computed_root new_root + >* assert_equal old_next_pos new_next_pos + >* assert_equal (coerce computed_fees) (coerce fees) +end + +(* for each proof, pi = [old_root, old_next_pos, new_root, new_next_pos, fees, rollup_id] + public pi are the first old_root, the last next_root, the last fees, the last rollup_id + - for all proofs, next old_root must be equal to current next_root + - for all proofs, rollup_id must be the same + - for each proof, fees is the sum of its transactions fees + - for all proofs, old_next_pos & new_next_pos must be the same +*) +module PI_parameters_predicate_private_batch = struct + module L = LibCircuit + + (* accumulator type for the fold_left in check_pi *) + type acc = { + root : L.scalar L.repr; + pos : L.scalar L.repr; + total_fees : L.scalar L.repr; + } + + let inner_elt pi_list = + match pi_list with + | [old_root; old_next_pos; new_root; new_next_pos; fees; rollup_id] -> + (old_root, old_next_pos, new_root, new_next_pos, fees, rollup_id) + | _ -> failwith "invalid inner_pi format." + + let outer_elt pi_list = + match pi_list with + | [old_root; new_root; total_fees; rollup_id] -> + (old_root, new_root, total_fees, rollup_id) + | _ -> failwith "invalid outer_pi format." + + let nb_inner = 6 + + let nb_outer = 4 + + (* /!\ Note that this function assumes that the first proof is not turned off by the switches (ie the first switch is true) ; + If the first proof is turned off, this function will NOT return the expected result + *) + let check ~switches ~outer ~inner = + let open L in + let init, first_root, init_rollup_id = + let first_root, _old_next_pos, new_root, new_next_pos, fees, rollup_id = + inner_elt (List.hd inner) + in + ( ({root = new_root; pos = new_next_pos; total_fees = fees}, []), + first_root, + rollup_id ) + in + let old_root, new_root, total_fees, outer_rollup_id = outer_elt outer in + let* acc, inner_checks = + fold2M + (fun (acc, checks) pi_list switch -> + let* n_switch = Bool.bnot switch in + let old_root, old_next_pos, new_root, new_next_pos, fees, rollup_id = + inner_elt pi_list + in + let* check_old_pos = + let* res = equal acc.pos old_next_pos in + Bool.bor n_switch res + in + let* check_roots = + let* res = equal acc.root old_root in + Bool.bor n_switch res + in + let* check_id = + let* res = equal outer_rollup_id rollup_id in + Bool.bor n_switch res + in + let* total_fees = + let* fees = Num.mul (scalar_of_bool switch) fees in + Num.add acc.total_fees fees + in + let checks = [check_old_pos; check_roots; check_id] @ checks in + let* root = Bool.ifthenelse switch new_root acc.root in + let* pos = Bool.ifthenelse switch new_next_pos acc.pos in + ret ({root; pos; total_fees}, checks)) + init + (List.tl inner) + (List.tl switches) + in + let* check_fees = equal total_fees acc.total_fees in + let* check_first_root = equal old_root first_root in + let* check_last_root = equal new_root acc.root in + let* check_fst_rollup_id = equal outer_rollup_id init_rollup_id in + Bool.band_list + ([check_fees; check_first_root; check_last_root; check_fst_rollup_id] + @ inner_checks) + + let outer_of_inner inner = + let old_root, _, _, _, first_fees, rollup_id = inner_elt (List.hd inner) in + let new_root, total_fees = + List.fold_left + (fun (_, acc_fees) pi -> + let _, _, new_root, _, fees, _ = inner_elt pi in + let acc_fees = Plonk.Bls.Scalar.(acc_fees + fees) in + (new_root, acc_fees)) + (old_root, first_fees) + (List.tl inner) + in + [old_root; new_root; total_fees; rollup_id] +end diff --git a/src/lib_epoxy_tx/types.ml b/src/lib_epoxy_tx/types.ml new file mode 100644 index 000000000000..b975ce046596 --- /dev/null +++ b/src/lib_epoxy_tx/types.ml @@ -0,0 +1,687 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +module U = Utils +open Plompiler +module HashPV = Anemoi128 +module MerklePV = Gadget.Merkle (HashPV) +module SchnorrPV = Plompiler.Schnorr (HashPV) +module Curve = Mec.Curve.Jubjub.AffineEdwards +open Constants +module Bounded = Bounded.Make (Bound) + +module P = struct + module Schnorr = SchnorrPV.P + module Merkle = MerklePV.P + module Bounded = Bounded.P + + type 'a ticket = {id : S.t; amount : 'a Bounded.t} + + type tezos_pkh = bytes + + type tezos_zkru = bytes + + type account = { + pk : Schnorr.pk; + tez_balance : balance Bounded.t; + cnt : counter Bounded.t; + tickets_root : S.t; + } + + type leaf = {pos : position Bounded.t; ticket : balance ticket} + + module IMap = Map.Make (Int) + + type state = { + (* account index*) + accounts : (account * leaf array * Merkle.tree) IMap.t; + accounts_tree : Merkle.tree; + (* First leaf of an empty account *) + next_position : int; + } + + type proof = {path : Merkle.path; root : S.t} + + type account_tree_el = {before : account; after : account; proof : proof} + + type leaf_tree_el = {before : leaf; after : leaf; path : Merkle.path} + + type tree_el = {account : account_tree_el; leaf : leaf_tree_el} + + type header = { + op_code : op_code Bounded.t; + price : balance ticket; + l1_dst : tezos_pkh; + rollup_id : tezos_zkru; + } + + type unsigned_transfer_payload = { + cnt : counter Bounded.t; + src : position Bounded.t; + dst : position Bounded.t; + amount : amount ticket; + fee : fee Bounded.t; + } + + type transfer_payload = { + msg : unsigned_transfer_payload; + signature : Schnorr.signature; + } + + type unsigned_transfer = { + header : header; + payload : unsigned_transfer_payload; + } + + type transfer = {header : header; payload : transfer_payload} + + type transfer_storage = {src : tree_el; dst : tree_el; valid : bool} + + type unsigned_create_payload = {pk : Schnorr.pk; fee : fee Bounded.t} + + type create_payload = { + msg : unsigned_create_payload; + signature : Schnorr.signature; + } + + type unsigned_create = {header : header; payload : unsigned_create_payload} + + type create = {header : header; payload : create_payload} + + type create_storage = {dst : tree_el; next_empty : tree_el; valid : bool} + + type credit_payload = { + cnt : counter Bounded.t; + dst : position Bounded.t; + amount : amount ticket; + } + + type credit = {header : header; payload : credit_payload} + + type credit_storage = {dst : tree_el; valid : bool} + + type unsigned_debit_payload = { + cnt : counter Bounded.t; + src : position Bounded.t; + amount : amount ticket; + } + + type debit_payload = { + msg : unsigned_debit_payload; + signature : Schnorr.signature; + } + + type unsigned_debit = {header : header; payload : unsigned_debit_payload} + + type debit = {header : header; payload : debit_payload} + + type debit_storage = {src : tree_el; valid : bool} + + type unsigned_tx = + | Transfer of unsigned_transfer + | Create of unsigned_create + | Credit of credit + | Debit of unsigned_debit + + type tx = + | Transfer of transfer + | Create of create + | Credit of credit + | Debit of debit + + type tx_storage = + | Transfer of transfer_storage + | Create of create_storage + | Credit of credit_storage + | Debit of debit_storage + + module Dummy = struct + let cnt = Bounded.make ~bound:Bound.max_counter Z.zero + + let fee = Bounded.make ~bound:Bound.max_fee Z.zero + + let pos = Bounded.make ~bound:Bound.max_nb_leaves Z.zero + + let amount = Bounded.make ~bound:Bound.max_amount Z.zero + + let balance = Bounded.make ~bound:Bound.max_balance Z.zero + + let ticket_amount = {id = S.zero; amount} + + let ticket_balance = {id = S.zero; amount = balance} + + let op_code = Bounded.make ~bound:Bound.max_op_code Z.zero + + let root = Bls12_381.Fr.random () + + let sk = Curve.Scalar.random () + + let pk = Schnorr.neuterize sk + + let tezos_pkh = Bytes.init 21 (fun i -> char_of_int i) + + let tezos_zkru = Bytes.init 20 (fun _i -> char_of_int 0) + + let signature = + let rand = Curve.Scalar.random () in + Schnorr.sign sk S.zero rand + + let leaf : leaf = {pos; ticket = ticket_balance} + + let account : account = + {pk; tez_balance = balance; cnt; tickets_root = root} + + let proof depth : proof = + {path = List.init depth (fun _ -> (Bls12_381.Fr.random (), true)); root} + + let account_tree_el : account_tree_el = + { + before = account; + after = account; + proof = proof Constants.accounts_depth; + } + + let leaf_tree_el : leaf_tree_el = + {before = leaf; after = leaf; path = (proof Constants.tickets_depth).path} + + let tree_el : tree_el = {account = account_tree_el; leaf = leaf_tree_el} + + let header = + { + op_code; + price = ticket_balance; + l1_dst = tezos_pkh; + rollup_id = tezos_zkru; + } + + let unsigned_transfer_payload = + {cnt; src = pos; dst = pos; amount = ticket_amount; fee} + + let transfer_payload : transfer_payload = + {msg = unsigned_transfer_payload; signature} + + let transfer : transfer = {header; payload = transfer_payload} + + let transfer_storage : transfer_storage = + {src = tree_el; dst = tree_el; valid = true} + + let unsigned_create_payload = {pk; fee} + + let create_payload : create_payload = + {msg = unsigned_create_payload; signature} + + let create : create = {header; payload = create_payload} + + let create_storage : create_storage = + {dst = tree_el; next_empty = tree_el; valid = true} + + let credit_payload = {cnt; dst = pos; amount = ticket_amount} + + let credit : credit = {header; payload = credit_payload} + + let credit_storage : credit_storage = {dst = tree_el; valid = true} + + let unsgined_debit_payload = {cnt; src = pos; amount = ticket_amount} + + let debit_payload : debit_payload = + {msg = unsgined_debit_payload; signature} + + let debit : debit = {header; payload = debit_payload} + + let debit_storage : debit_storage = {src = tree_el; valid = true} + end +end + +module V (L : LIB) = struct + open L + module Schnorr = SchnorrPV.V (L) + module Merkle = MerklePV.V (L) + module Bounded_u = Bounded.V (L) + + type curve_t_u = (scalar * scalar) repr + + type curve_base_t_u = scalar repr + + type curve_scalar_t_u = scalar repr + + type 'a ticket_u = {id : scalar repr; amount : 'a Bounded_u.t} + + type tezos_pkh_u = scalar repr + + type tezos_zkru_u = scalar repr + + type account_u = { + pk : Schnorr.pk repr; + tez_balance : balance Bounded_u.t; + cnt : counter Bounded_u.t; + tickets_root : scalar repr; + } + + type leaf_u = {pos : position Bounded_u.t; ticket : balance ticket_u} + + type proof_u = {path : Merkle.path; root : scalar repr} + + type account_tree_el_u = { + before : account_u; + after : account_u; + proof : proof_u; + } + + type leaf_tree_el_u = {before : leaf_u; after : leaf_u; path : Merkle.path} + + type tree_el_u = {account : account_tree_el_u; leaf : leaf_tree_el_u} + + type header_u = { + op_code : op_code Bounded_u.t; + price : balance ticket_u; + l1_dst : tezos_pkh_u; + rollup_id : tezos_zkru_u; + } + + type unsigned_transfer_payload_u = { + cnt : counter Bounded_u.t; + src : position Bounded_u.t; + dst : position Bounded_u.t; + amount : amount ticket_u; + fee : fee Bounded_u.t; + } + + type transfer_payload_u = { + msg : unsigned_transfer_payload_u; + signature : Schnorr.signature; + } + + type transfer_u = {header : header_u; payload : transfer_payload_u} + + type transfer_storage_u = { + src : tree_el_u; + dst : tree_el_u; + valid : bool repr; + } + + type unsigned_create_payload_u = {pk : Schnorr.pk repr; fee : fee Bounded_u.t} + + type create_payload_u = { + msg : unsigned_create_payload_u; + signature : Schnorr.signature; + } + + type create_u = {header : header_u; payload : create_payload_u} + + type create_storage_u = { + dst : tree_el_u; + next_empty : tree_el_u; + valid : bool repr; + } + + type credit_payload_u = { + cnt : counter Bounded_u.t; + dst : position Bounded_u.t; + amount : amount ticket_u; + } + + type credit_u = {header : header_u; payload : credit_payload_u} + + type credit_storage_u = {dst : tree_el_u; valid : bool repr} + + type unsigned_debit_payload_u = { + cnt : counter Bounded_u.t; + src : position Bounded_u.t; + amount : amount ticket_u; + } + + type debit_payload_u = { + msg : unsigned_debit_payload_u; + signature : Schnorr.signature; + } + + type debit_u = {header : header_u; payload : debit_payload_u} + + type debit_storage_u = {src : tree_el_u; valid : bool repr} +end + +module Encodings (L : LIB) = struct + module Bounded_e = Bounded.Encoding (L) + open P + open L + + open V (L) + + open Encodings (L) + + module Anemoi = Anemoi128.V + module Plompiler_Curve = JubjubEdwards (L) + module Plompiler_Hash = Anemoi (L) + open U + + let s_of_int x = S.of_z (Z.of_int x) + + let curve_base_t_encoding : (Curve.Base.t, curve_base_t_u, _) encoding = + conv + (fun r -> r) + (fun r -> r) + curve_base_to_s + curve_base_of_s + scalar_encoding + + let curve_scalar_t_encoding : (Curve.Scalar.t, curve_scalar_t_u, _) encoding = + conv + (fun r -> r) + (fun r -> r) + curve_scalar_to_s + curve_scalar_of_s + scalar_encoding + + let curve_t_encoding : (Curve.t, curve_t_u, _) encoding = + with_implicit_bool_check Plompiler_Curve.is_on_curve + @@ conv + (fun r -> of_pair r) + (fun (u, v) -> pair u v) + (fun c -> + ( curve_base_to_s @@ Curve.get_u_coordinate c, + curve_base_to_s @@ Curve.get_v_coordinate c )) + (fun (u, v) -> + Curve.from_coordinates_exn + ~u:(curve_base_of_s u) + ~v:(curve_base_of_s v)) + (obj2_encoding scalar_encoding scalar_encoding) + + let balance_encoding ~safety = + Bounded_e.encoding ~safety Constants.Bound.max_balance + + let amount_encoding ~safety = + Bounded_e.encoding ~safety Constants.Bound.max_amount + + let fee_encoding ~safety = Bounded_e.encoding ~safety Constants.Bound.max_fee + + let pos_encoding ~safety = + Bounded_e.encoding ~safety Constants.Bound.max_nb_leaves + + let cnt_encoding ~safety = + Bounded_e.encoding ~safety Constants.Bound.max_counter + + let op_code_encoding ~safety = + Bounded_e.encoding ~safety Constants.Bound.max_op_code + + let tezos_pkh_encoding : (tezos_pkh, tezos_pkh_u, _) encoding = + conv + (fun pkhu -> pkhu) + (fun w -> w) + U.scalar_of_bytes + U.scalar_to_bytes + scalar_encoding + + let tezos_zkru_encoding : (tezos_zkru, tezos_zkru_u, _) encoding = + conv + (fun zkru -> zkru) + (fun w -> w) + U.scalar_of_bytes + U.scalar_to_bytes + scalar_encoding + + let ticket_encoding ~safety (bound : 'a Bound.t) : + ('a ticket, 'a ticket_u, _) encoding = + conv + (fun {id; amount} -> (id, amount)) + (fun (id, amount) -> {id; amount}) + (fun ({id; amount} : 'a ticket) -> (id, amount)) + (fun (id, amount) -> {id; amount}) + (obj2_encoding scalar_encoding (Bounded_e.encoding ~safety bound)) + + let ticket_balance_encoding ~safety = + ticket_encoding ~safety Constants.Bound.max_balance + + let ticket_amount_encoding ~safety = + ticket_encoding ~safety Constants.Bound.max_amount + + let account_encoding : (account, account_u, _) encoding = + conv + (fun {pk; tez_balance; cnt; tickets_root} -> + (pk, (tez_balance, (cnt, tickets_root)))) + (fun (pk, (tez_balance, (cnt, tickets_root))) -> + {pk; tez_balance; cnt; tickets_root}) + (fun (acc : account) -> + (acc.pk, (acc.tez_balance, (acc.cnt, acc.tickets_root)))) + (fun (pk, (tez_balance, (cnt, tickets_root))) -> + {pk; tez_balance; cnt; tickets_root}) + (obj4_encoding + Schnorr.pk_encoding + (balance_encoding ~safety:NoCheck) + (cnt_encoding ~safety:NoCheck) + scalar_encoding) + + let leaf_encoding : (leaf, leaf_u, _) encoding = + conv + (fun {pos; ticket} -> (pos, ticket)) + (fun (pos, ticket) -> {pos; ticket}) + (fun ({pos; ticket} : leaf) -> (pos, ticket)) + (fun (pos, ticket) -> {pos; ticket}) + (obj2_encoding + (pos_encoding ~safety:NoCheck) + (ticket_balance_encoding ~safety:NoCheck)) + + let proof_encoding : (proof, proof_u, _) encoding = + conv + (fun {path; root} -> (path, root)) + (fun (path, root) -> {path; root}) + (fun ({path; root} : proof) -> (path, root)) + (fun (path, root) -> {path; root}) + (obj2_encoding Merkle.path_encoding scalar_encoding) + + let account_tree_el_encoding : + (account_tree_el, account_tree_el_u, _) encoding = + conv + (fun {before; after; proof} -> (before, (after, proof))) + (fun (before, (after, proof)) -> {before; after; proof}) + (fun ({before; after; proof} : account_tree_el) -> + (before, (after, proof))) + (fun (before, (after, proof)) -> {before; after; proof}) + (obj3_encoding account_encoding account_encoding proof_encoding) + + let leaf_tree_el_encoding : (leaf_tree_el, leaf_tree_el_u, _) encoding = + conv + (fun {before; after; path} -> (before, (after, path))) + (fun (before, (after, path)) -> {before; after; path}) + (fun ({before; after; path} : leaf_tree_el) -> (before, (after, path))) + (fun (before, (after, path)) -> {before; after; path}) + (obj3_encoding leaf_encoding leaf_encoding Merkle.path_encoding) + + let tree_el_encoding : (tree_el, tree_el_u, _) encoding = + conv + (fun {account; leaf} -> (account, leaf)) + (fun (account, leaf) -> {account; leaf}) + (fun ({account; leaf} : tree_el) -> (account, leaf)) + (fun (account, leaf) -> {account; leaf}) + (obj2_encoding account_tree_el_encoding leaf_tree_el_encoding) + + let header_encoding ~safety : (header, header_u, _) encoding = + conv + (fun {op_code; price; l1_dst; rollup_id} -> + (op_code, (price, (l1_dst, rollup_id)))) + (fun (op_code, (price, (l1_dst, rollup_id))) -> + {op_code; price; l1_dst; rollup_id}) + (fun ({op_code; price; l1_dst; rollup_id} : header) -> + (op_code, (price, (l1_dst, rollup_id)))) + (fun (op_code, (price, (l1_dst, rollup_id))) -> + {op_code; price; l1_dst; rollup_id}) + (obj4_encoding + (op_code_encoding ~safety) + (ticket_balance_encoding ~safety) + tezos_pkh_encoding + tezos_zkru_encoding) + + let unsigned_transfer_payload_encoding ~safety : + (unsigned_transfer_payload, unsigned_transfer_payload_u, _) encoding = + conv + (fun (tx : unsigned_transfer_payload_u) -> + (tx.cnt, (tx.src, (tx.dst, (tx.amount, tx.fee))))) + (fun (cnt, (src, (dst, (amount, fee)))) -> {cnt; src; dst; amount; fee}) + (fun (tx : unsigned_transfer_payload) -> + (tx.cnt, (tx.src, (tx.dst, (tx.amount, tx.fee))))) + (fun (cnt, (src, (dst, (amount, fee)))) -> {cnt; src; dst; amount; fee}) + (obj5_encoding + (cnt_encoding ~safety) + (pos_encoding ~safety) + (pos_encoding ~safety) + (ticket_amount_encoding ~safety) + (fee_encoding ~safety)) + + let transfer_payload_encoding ~safety : + (transfer_payload, transfer_payload_u, _) encoding = + conv + (fun ({msg; signature} : transfer_payload_u) -> (msg, signature)) + (fun (msg, signature) -> {msg; signature}) + (fun ({msg; signature} : transfer_payload) -> (msg, signature)) + (fun (msg, signature) -> {msg; signature}) + (obj2_encoding + (unsigned_transfer_payload_encoding ~safety) + Schnorr.signature_encoding) + + let transfer_encoding ~safety : (transfer, transfer_u, _) encoding = + conv + (fun (tx : transfer_u) -> (tx.header, tx.payload)) + (fun (header, payload) -> {header; payload}) + (fun (tx : transfer) -> (tx.header, tx.payload)) + (fun (header, payload) -> {header; payload}) + (obj2_encoding + (header_encoding ~safety) + (transfer_payload_encoding ~safety)) + + let transfer_storage_encoding : + (transfer_storage, transfer_storage_u, _) encoding = + conv + (fun (tx : transfer_storage_u) -> (tx.src, (tx.dst, tx.valid))) + (fun (src, (dst, valid)) -> {src; dst; valid}) + (fun (tx : transfer_storage) -> (tx.src, (tx.dst, tx.valid))) + (fun (src, (dst, valid)) -> {src; dst; valid}) + (obj3_encoding tree_el_encoding tree_el_encoding bool_encoding) + + let unsigned_create_payload_encoding ~safety : + (unsigned_create_payload, unsigned_create_payload_u, _) encoding = + conv + (fun (tx : unsigned_create_payload_u) -> (tx.pk, tx.fee)) + (fun (pk, fee) -> {pk; fee}) + (fun (tx : unsigned_create_payload) -> (tx.pk, tx.fee)) + (fun (pk, fee) -> {pk; fee}) + (obj2_encoding Schnorr.pk_encoding (fee_encoding ~safety)) + + let create_payload_encoding ~safety : + (create_payload, create_payload_u, _) encoding = + conv + (fun ({msg; signature} : create_payload_u) -> (msg, signature)) + (fun (msg, signature) -> {msg; signature}) + (fun ({msg; signature} : create_payload) -> (msg, signature)) + (fun (msg, signature) -> {msg; signature}) + (obj2_encoding + (unsigned_create_payload_encoding ~safety) + Schnorr.signature_encoding) + + let create_encoding ~safety : (create, create_u, _) encoding = + conv + (fun (tx : create_u) -> (tx.header, tx.payload)) + (fun (header, payload) -> {header; payload}) + (fun (tx : create) -> (tx.header, tx.payload)) + (fun (header, payload) -> {header; payload}) + (obj2_encoding + (header_encoding ~safety) + (create_payload_encoding ~safety)) + + let create_storage_encoding : (create_storage, create_storage_u, _) encoding = + conv + (fun (tx : create_storage_u) -> (tx.dst, (tx.next_empty, tx.valid))) + (fun (dst, (next_empty, valid)) -> {dst; next_empty; valid}) + (fun (tx : create_storage) -> (tx.dst, (tx.next_empty, tx.valid))) + (fun (dst, (next_empty, valid)) -> {dst; next_empty; valid}) + (obj3_encoding tree_el_encoding tree_el_encoding bool_encoding) + + let credit_payload_encoding ~safety : + (credit_payload, credit_payload_u, _) encoding = + conv + (fun (tx : credit_payload_u) -> (tx.cnt, (tx.dst, tx.amount))) + (fun (cnt, (dst, amount)) -> {cnt; dst; amount}) + (fun (tx : credit_payload) -> (tx.cnt, (tx.dst, tx.amount))) + (fun (cnt, (dst, amount)) -> {cnt; dst; amount}) + (obj3_encoding + (cnt_encoding ~safety) + (pos_encoding ~safety) + (ticket_amount_encoding ~safety)) + + let credit_encoding ~safety : (credit, credit_u, _) encoding = + conv + (fun (tx : credit_u) -> (tx.header, tx.payload)) + (fun (header, payload) -> {header; payload}) + (fun (tx : credit) -> (tx.header, tx.payload)) + (fun (header, payload) -> {header; payload}) + (obj2_encoding + (header_encoding ~safety) + (credit_payload_encoding ~safety)) + + let credit_storage_encoding : (credit_storage, credit_storage_u, _) encoding = + conv + (fun (tx : credit_storage_u) -> (tx.dst, tx.valid)) + (fun (dst, valid) -> {dst; valid}) + (fun (tx : credit_storage) -> (tx.dst, tx.valid)) + (fun (dst, valid) -> {dst; valid}) + (obj2_encoding tree_el_encoding bool_encoding) + + let unsigned_debit_payload_encoding ~safety : + (unsigned_debit_payload, unsigned_debit_payload_u, _) encoding = + conv + (fun (tx : unsigned_debit_payload_u) -> (tx.cnt, (tx.src, tx.amount))) + (fun (cnt, (src, amount)) -> {cnt; src; amount}) + (fun (tx : unsigned_debit_payload) -> (tx.cnt, (tx.src, tx.amount))) + (fun (cnt, (src, amount)) -> {cnt; src; amount}) + (obj3_encoding + (cnt_encoding ~safety) + (pos_encoding ~safety) + (ticket_amount_encoding ~safety)) + + let debit_payload_encoding ~safety : + (debit_payload, debit_payload_u, _) encoding = + conv + (fun ({msg; signature} : debit_payload_u) -> (msg, signature)) + (fun (msg, signature) -> {msg; signature}) + (fun ({msg; signature} : debit_payload) -> (msg, signature)) + (fun (msg, signature) -> {msg; signature}) + (obj2_encoding + (unsigned_debit_payload_encoding ~safety) + Schnorr.signature_encoding) + + let debit_encoding ~safety : (debit, debit_u, _) encoding = + conv + (fun (tx : debit_u) -> (tx.header, tx.payload)) + (fun (header, payload) -> {header; payload}) + (fun (tx : debit) -> (tx.header, tx.payload)) + (fun (header, payload) -> {header; payload}) + (obj2_encoding (header_encoding ~safety) (debit_payload_encoding ~safety)) + + let debit_storage_encoding : (debit_storage, debit_storage_u, _) encoding = + conv + (fun (tx : debit_storage_u) -> (tx.src, tx.valid)) + (fun (src, valid) -> {src; valid}) + (fun (tx : debit_storage) -> (tx.src, tx.valid)) + (fun (src, valid) -> {src; valid}) + (obj2_encoding tree_el_encoding bool_encoding) +end diff --git a/src/lib_epoxy_tx/utils.ml b/src/lib_epoxy_tx/utils.ml new file mode 100644 index 000000000000..089716960deb --- /dev/null +++ b/src/lib_epoxy_tx/utils.ml @@ -0,0 +1,63 @@ +(*****************************************************************************) +(* *) +(* MIT License *) +(* Copyright (c) 2022 Nomadic Labs *) +(* *) +(* Permission is hereby granted, free of charge, to any person obtaining a *) +(* copy of this software and associated documentation files (the "Software"),*) +(* to deal in the Software without restriction, including without limitation *) +(* the rights to use, copy, modify, merge, publish, distribute, sublicense, *) +(* and/or sell copies of the Software, and to permit persons to whom the *) +(* Software is furnished to do so, subject to the following conditions: *) +(* *) +(* The above copyright notice and this permission notice shall be included *) +(* in all copies or substantial portions of the Software. *) +(* *) +(* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR*) +(* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *) +(* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL *) +(* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER*) +(* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *) +(* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *) +(* DEALINGS IN THE SOFTWARE. *) +(* *) +(*****************************************************************************) + +open Plompiler +module Curve = Mec.Curve.Jubjub.AffineEdwards + +let of_int x = Z.of_int x |> S.of_z + +let to_bls_scalar s = Curve.Base.of_z (S.to_z s) + +let of_bls_scalar s = S.of_z (Curve.Base.to_z s) + +let point_to_affine (u, v) = + Curve.unsafe_from_coordinates ~u:(to_bls_scalar u) ~v:(to_bls_scalar v) + +let affine_to_point p = + let u = Curve.get_u_coordinate p in + let v = Curve.get_v_coordinate p in + (of_bls_scalar u, of_bls_scalar v) + +let random_int = Stdlib.Random.int + +let random_z bound = Random.int64 (Z.to_int64 bound) |> Z.of_int64 + +let nb_bits_base = Z.numbits S.order + +let curve_base_to_s c = S.of_z @@ Curve.Base.to_z c + +let curve_base_of_s c = Curve.Base.of_z @@ S.to_z c + +let curve_scalar_to_s c = S.of_z @@ Curve.Scalar.to_z c + +let curve_scalar_of_s c = Curve.Scalar.of_z @@ S.to_z c + +let scalar_of_bytes bs = + assert (Bytes.length bs < S.size_in_bytes) ; + (* The bytes are interpreted as a Z integer *) + let z = Z.of_bits @@ Bytes.to_string bs in + S.of_z z + +let scalar_to_bytes s = S.to_z s |> Z.to_bits |> Bytes.of_string -- GitLab From b2ae75ead43f4ffa9cd9a8ce1ab8b71f97c9b18b Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 16 Mar 2023 10:25:45 +0100 Subject: [PATCH 31/34] Proto L: change to use new interface of Plonk --- .../test/helpers/dummy_zk_rollup.ml | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/proto_015_PtLimaPt/lib_protocol/test/helpers/dummy_zk_rollup.ml b/src/proto_015_PtLimaPt/lib_protocol/test/helpers/dummy_zk_rollup.ml index 4c151881554b..c8ec6240e21d 100644 --- a/src/proto_015_PtLimaPt/lib_protocol/test/helpers/dummy_zk_rollup.ml +++ b/src/proto_015_PtLimaPt/lib_protocol/test/helpers/dummy_zk_rollup.ml @@ -270,33 +270,33 @@ module V (L : LIB) = struct >* ret expected_new_state (** Circuit definition for one public operation *) - let predicate_op ?(public = true) ~old_state ~new_state ~fee ~exit_validity + let predicate_op ?(kind = `Public) ~old_state ~new_state ~fee ~exit_validity ~rollup_id op = - let* old_state = input ~public:true @@ Input.bool old_state in - let* new_state = input ~public:true @@ Input.bool new_state in + let* old_state = input ~kind:`Public @@ Input.bool old_state in + let* new_state = input ~kind:`Public @@ Input.bool new_state in let* _fee = - input ~public:true + input ~kind:`Public @@ E.((fee_encoding ~safety:Bounded_e.Unsafe).input) fee in - let* _exit_validity = input ~public:true @@ Input.bool exit_validity in + let* _exit_validity = input ~kind:`Public @@ Input.bool exit_validity in let* rollup_id = - input ~public:true @@ E.(tezos_pkh_encoding.input) rollup_id + input ~kind:`Public @@ E.(tezos_pkh_encoding.input) rollup_id in - let* op = input ~public @@ E.op_encoding.input op in + let* op = input ~kind @@ E.op_encoding.input op in let op = E.op_encoding.decode op in let* expected_new_state = logic_op ~old_state ~rollup_id op in assert_equal expected_new_state new_state (** Circuit definition for a batch of private operations *) let predicate_batch ~old_state ~new_state ~fees ~rollup_id ops = - let* old_state = input ~public:true @@ Input.bool old_state in - let* new_state = input ~public:true @@ Input.bool new_state in + let* old_state = input ~kind:`Public @@ Input.bool old_state in + let* new_state = input ~kind:`Public @@ Input.bool new_state in let* _fees = - input ~public:true + input ~kind:`Public @@ E.((amount_encoding ~safety:Bounded_e.Unsafe).input) fees in let* rollup_id = - input ~public:true @@ E.(tezos_pkh_encoding.input) rollup_id + input ~kind:`Public @@ E.(tezos_pkh_encoding.input) rollup_id in let* ops = input @@ (Encodings.list_encoding E.op_encoding).input ops in let ops = (Encodings.list_encoding E.op_encoding).decode ops in @@ -310,10 +310,10 @@ module V (L : LIB) = struct (** Fee circuit *) let predicate_fees ~old_state ~new_state ~fees = - let* old_state = input ~public:true @@ Input.bool old_state in - let* new_state = input ~public:true @@ Input.bool new_state in + let* old_state = input ~kind:`Public @@ Input.bool old_state in + let* new_state = input ~kind:`Public @@ Input.bool new_state in let* _fees = - input ~public:true + input ~kind:`Public @@ E.((amount_encoding ~safety:Bounded_e.Unsafe).input) fees in assert_equal old_state new_state @@ -353,7 +353,7 @@ end = struct let lazy_srs = lazy - (let open Bls12_381_polynomial in + (let open Octez_bls12_381_polynomial.Bls12_381_polynomial in (Srs.generate_insecure 8 1, Srs.generate_insecure 1 1)) let dummy_l1_dst = -- GitLab From 6bdc0e16d94e16464b3966e057d8e5e2a7a141e4 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 16 Mar 2023 10:26:15 +0100 Subject: [PATCH 32/34] Proto M: change to use new interface of Plonk --- .../test/helpers/dummy_zk_rollup.ml | 40 +++++++++---------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/proto_016_PtMumbai/lib_protocol/test/helpers/dummy_zk_rollup.ml b/src/proto_016_PtMumbai/lib_protocol/test/helpers/dummy_zk_rollup.ml index 5c81adad3bf1..5176108be37d 100644 --- a/src/proto_016_PtMumbai/lib_protocol/test/helpers/dummy_zk_rollup.ml +++ b/src/proto_016_PtMumbai/lib_protocol/test/helpers/dummy_zk_rollup.ml @@ -278,35 +278,35 @@ module V (L : LIB) = struct >* ret expected_new_state (** Circuit definition for one public operation *) - let predicate_op ?(public = true) ~old_state ~new_state ~fee ~exit_validity + let predicate_op ?(kind = `Public) ~old_state ~new_state ~fee ~exit_validity ~rollup_id op = - let* old_state = input ~public:true @@ Input.bool old_state in - let* new_state = input ~public:true @@ Input.bool new_state in + let* old_state = input ~kind:`Public @@ Input.bool old_state in + let* new_state = input ~kind:`Public @@ Input.bool new_state in let* (_fee : scalar repr) = - input ~public:true + input ~kind:`Public @@ E.((fee_encoding ~safety:Bounded_e.Unsafe).input) fee in let* (_exit_validity : bool repr) = - input ~public:true @@ Input.bool exit_validity + input ~kind:`Public @@ Input.bool exit_validity in let* rollup_id = - input ~public:true @@ E.(tezos_pkh_encoding.input) rollup_id + input ~kind:`Public @@ E.(tezos_pkh_encoding.input) rollup_id in - let* op = input ~public @@ E.op_encoding.input op in + let* op = input ~kind @@ E.op_encoding.input op in let op = E.op_encoding.decode op in let* expected_new_state = logic_op ~old_state ~rollup_id op in assert_equal expected_new_state new_state (** Circuit definition for a batch of private operations *) let predicate_batch ~old_state ~new_state ~fees ~rollup_id ops = - let* old_state = input ~public:true @@ Input.bool old_state in - let* new_state = input ~public:true @@ Input.bool new_state in + let* old_state = input ~kind:`Public @@ Input.bool old_state in + let* new_state = input ~kind:`Public @@ Input.bool new_state in let* (_fees : scalar repr) = - input ~public:true + input ~kind:`Public @@ E.((amount_encoding ~safety:Bounded_e.Unsafe).input) fees in let* rollup_id = - input ~public:true @@ E.(tezos_pkh_encoding.input) rollup_id + input ~kind:`Public @@ E.(tezos_pkh_encoding.input) rollup_id in let* ops = input @@ (Encodings.list_encoding E.op_encoding).input ops in let ops = (Encodings.list_encoding E.op_encoding).decode ops in @@ -320,10 +320,10 @@ module V (L : LIB) = struct (** Fee circuit *) let predicate_fees ~old_state ~new_state ~fees = - let* old_state = input ~public:true @@ Input.bool old_state in - let* new_state = input ~public:true @@ Input.bool new_state in + let* old_state = input ~kind:`Public @@ Input.bool old_state in + let* new_state = input ~kind:`Public @@ Input.bool new_state in let* (_fees : scalar repr) = - input ~public:true + input ~kind:`Public @@ E.((amount_encoding ~safety:Bounded_e.Unsafe).input) fees in assert_equal old_state new_state @@ -379,7 +379,7 @@ end = struct let lazy_srs = lazy - (let open Bls12_381_polynomial in + (let open Octez_bls12_381_polynomial.Bls12_381_polynomial in (Srs.generate_insecure 9 1, Srs.generate_insecure 1 1)) let dummy_l1_dst = @@ -504,7 +504,7 @@ end = struct insert "op" Plonk.Main_protocol. - {public = public_inputs; witness = private_inputs} + {witness = private_inputs; input_commitments = []} rev_inputs, ("op", pi_to_send) :: rev_pending_pis )) (s, rev_inputs, []) @@ -551,7 +551,7 @@ end = struct insert batch_name Plonk.Main_protocol. - {public = public_inputs; witness = private_inputs} + {witness = private_inputs; input_commitments = []} rev_inputs, (batch_name, pi_to_send) :: rev_private_pis )) (s, rev_inputs, []) @@ -570,7 +570,7 @@ end = struct let private_inputs = Solver.solve fee_solver public_inputs in ( insert "fee" - Plonk.Main_protocol.{public = public_inputs; witness = private_inputs} + Plonk.Main_protocol.{witness = private_inputs; input_commitments = []} rev_inputs, fee_pi ) in @@ -578,9 +578,7 @@ end = struct let proof = Plonk.Main_protocol.prove prover_pp ~inputs in let verifier_inputs = - Plonk.SMap.map - (List.map (fun Plonk.Main_protocol.{public; witness = _} -> public)) - inputs + Plonk.Main_protocol.to_verifier_inputs prover_pp inputs in assert ( Plonk.Main_protocol.verify public_parameters ~inputs:verifier_inputs proof) ; -- GitLab From c1fe4f58e3cd4e064a849cb5f0c68daf16661ac3 Mon Sep 17 00:00:00 2001 From: Danny Willems Date: Thu, 16 Mar 2023 14:49:34 +0100 Subject: [PATCH 33/34] Manifest: deactivate z3 tests z3 is not installed in the CI and it is not expected to have it installed --- manifest/main.ml | 17 +++++++++-------- src/lib_plompiler/dune | 5 ----- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/manifest/main.ml b/manifest/main.ml index 30f8dde1d750..68dd77745504 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1197,14 +1197,15 @@ let octez_plompiler = octez_mec; ] ~preprocess:[staged_pps [ppx_repr; ppx_deriving_show]] - ~dune: - Dune. - [ - alias_rule - "runtest" - ~deps_dune:[S "z3/run_z3_tests.sh"; [S "glob_files"; S "z3/*.z3"]] - ~action:[S "chdir"; S "z3"; [S "run"; S "sh"; S "run_z3_tests.sh"]]; - ] +(* Deactivating z3 tests. z3 is not installed in the CI *) +(* ~dune: *) +(* Dune. *) +(* [ *) +(* alias_rule *) +(* "runtest" *) +(* ~deps_dune:[S "z3/run_z3_tests.sh"; [S "glob_files"; S "z3/*.z3"]] *) +(* ~action:[S "chdir"; S "z3"; [S "run"; S "sh"; S "run_z3_tests.sh"]]; *) +(* ] *) let octez_plonk = public_lib diff --git a/src/lib_plompiler/dune b/src/lib_plompiler/dune index 646dbcf14d6c..290b55e21157 100644 --- a/src/lib_plompiler/dune +++ b/src/lib_plompiler/dune @@ -13,8 +13,3 @@ octez-polynomial octez-mec) (preprocess (staged_pps ppx_repr ppx_deriving.show))) - -(rule - (alias runtest) - (deps z3/run_z3_tests.sh (glob_files z3/*.z3)) - (action (chdir z3 (run sh run_z3_tests.sh)))) -- GitLab From e68de62e3cfa4a1e5de2cc231ffab35ead27bae6 Mon Sep 17 00:00:00 2001 From: Victor Dumitrescu Date: Mon, 27 Mar 2023 15:58:33 +0200 Subject: [PATCH 34/34] Alcotezt: port lib_polynomial --- manifest/main.ml | 118 +++++++++++++++++------------------ opam/octez-polynomial.opam | 4 +- src/lib_polynomial/test/dune | 34 +++++++--- tezt/tests/dune | 1 + 4 files changed, 88 insertions(+), 69 deletions(-) diff --git a/manifest/main.ml b/manifest/main.ml index 68dd77745504..0be7701949d7 100644 --- a/manifest/main.ml +++ b/manifest/main.ml @@ -1097,11 +1097,11 @@ let octez_polynomial = ~deps:[bls12_381; bisect_ppx; zarith] let _octez_polynomial_tests = - tests - ["test_with_finite_field"; "test_utils"] + tezt + ["test_with_finite_field"; "test_utils"; "polynomial_pbt"] ~path:"src/lib_polynomial/test" ~opam:"octez-polynomial" - ~deps:[bls12_381; octez_mec; alcotest; octez_polynomial] + ~deps:[bls12_381; octez_mec; alcotezt; octez_polynomial] let octez_bls12_381_polynomial = public_lib @@ -1181,6 +1181,62 @@ let _octez_srs_extraction_main = octez_bls12_381_polynomial |> open_; ] +let _octez_srs_extraction_tests = + tests + ["main"] + ~path:"src/lib_srs_extraction/test" + ~opam:"octez-srs-extraction" + ~deps:[octez_srs_extraction |> open_; alcotest] + ~dep_files:["phase1radix2m5"] + ~dune: + Dune.( + let extract curve srs_file = + let generated_srs_file = srs_file ^ ".generated" in + [ + S "rule"; + [S "alias"; S "runtest"]; + [S "package"; S "octez-srs-extraction"]; + [S "deps"; S srs_file; S "phase1radix2m5"]; + [ + S "action"; + [ + S "progn"; + [ + S "run"; + S "%{exe:../srs_extraction_main.exe}"; + S "extract"; + S "zcash"; + S curve; + S "phase1radix2m5"; + S "-o"; + S generated_srs_file; + ]; + [S "diff"; S generated_srs_file; S srs_file]; + ]; + ]; + ] + in + [ + extract "g1" "srs_zcash_g1_5"; + extract "g2" "srs_zcash_g2_5"; + alias_rule + "runtest" + ~package:"octez-srs-extraction" + ~deps:["srs_zcash_g1_5"; "srs_zcash_g2_5"] + ~action: + (run + "../srs_extraction_main.exe" + ["check"; "srs_zcash_g1_5"; "srs_zcash_g2_5"]); + alias_rule + "runtest" + ~package:"octez-srs-extraction" + ~deps:["srs_filecoin_g1_6"; "srs_filecoin_g2_6"] + ~action: + (run + "../srs_extraction_main.exe" + ["check"; "srs_filecoin_g1_6"; "srs_filecoin_g2_6"]); + ]) + let octez_plompiler = public_lib "octez-plompiler" @@ -1597,62 +1653,6 @@ let _octez_epoxy_tx_tests = ]); ] -let _octez_srs_extraction_tests = - tests - ["main"] - ~path:"src/lib_srs_extraction/test" - ~opam:"octez-srs-extraction" - ~deps:[octez_srs_extraction |> open_; alcotest] - ~dep_files:["phase1radix2m5"] - ~dune: - Dune.( - let extract curve srs_file = - let generated_srs_file = srs_file ^ ".generated" in - [ - S "rule"; - [S "alias"; S "runtest"]; - [S "package"; S "octez-srs-extraction"]; - [S "deps"; S srs_file; S "phase1radix2m5"]; - [ - S "action"; - [ - S "progn"; - [ - S "run"; - S "%{exe:../srs_extraction_main.exe}"; - S "extract"; - S "zcash"; - S curve; - S "phase1radix2m5"; - S "-o"; - S generated_srs_file; - ]; - [S "diff"; S generated_srs_file; S srs_file]; - ]; - ]; - ] - in - [ - extract "g1" "srs_zcash_g1_5"; - extract "g2" "srs_zcash_g2_5"; - alias_rule - "runtest" - ~package:"octez-srs-extraction" - ~deps:["srs_zcash_g1_5"; "srs_zcash_g2_5"] - ~action: - (run - "../srs_extraction_main.exe" - ["check"; "srs_zcash_g1_5"; "srs_zcash_g2_5"]); - alias_rule - "runtest" - ~package:"octez-srs-extraction" - ~deps:["srs_filecoin_g1_6"; "srs_filecoin_g2_6"] - ~action: - (run - "../srs_extraction_main.exe" - ["check"; "srs_filecoin_g1_6"; "srs_filecoin_g2_6"]); - ]) - let octez_crypto_dal = public_lib "tezos-crypto-dal" diff --git a/opam/octez-polynomial.opam b/opam/octez-polynomial.opam index 308caa38d65f..aaa40821f4ee 100644 --- a/opam/octez-polynomial.opam +++ b/opam/octez-polynomial.opam @@ -13,12 +13,14 @@ depends: [ "bls12-381" { >= "6.1.0" & < "6.2.0" } "bisect_ppx" { >= "2.7.0" } "zarith" { >= "1.12" & < "1.13" } + "tezt" { with-test & >= "3.0.0" } "octez-mec" {with-test} - "alcotest" { with-test & >= "1.5.0" } + "octez-alcotezt" {with-test} ] build: [ ["rm" "-r" "vendors"] ["dune" "build" "-p" name "-j" jobs] ["dune" "runtest" "-p" name "-j" jobs] {with-test} + ["dune" "build" "@runtezt" "-p" name "-j" jobs] {with-test} ] synopsis: "Polynomials over finite fields" diff --git a/src/lib_polynomial/test/dune b/src/lib_polynomial/test/dune index 894e92710224..69da6cb80949 100644 --- a/src/lib_polynomial/test/dune +++ b/src/lib_polynomial/test/dune @@ -1,20 +1,36 @@ ; This file was automatically generated, do not edit. ; Edit file manifest/main.ml instead. -(executables - (names test_with_finite_field test_utils) +(library + (name src_lib_polynomial_test_tezt_lib) + (instrumentation (backend bisect_ppx)) (libraries + tezt.core bls12-381 octez-mec - alcotest - octez-polynomial)) + octez-alcotezt + octez-polynomial) + (library_flags (:standard -linkall)) + (flags + (:standard) + -open Tezt_core + -open Tezt_core.Base + -open Octez_alcotezt) + (modules test_with_finite_field test_utils polynomial_pbt)) + +(executable + (name main) + (instrumentation (backend bisect_ppx --bisect-sigterm)) + (libraries + src_lib_polynomial_test_tezt_lib + tezt) + (modules main)) (rule - (alias runtest) + (alias runtezt) (package octez-polynomial) - (action (run %{dep:./test_with_finite_field.exe}))) + (action (run %{dep:./main.exe}))) (rule - (alias runtest) - (package octez-polynomial) - (action (run %{dep:./test_utils.exe}))) + (targets main.ml) + (action (with-stdout-to %{targets} (echo "let () = Tezt.Test.run ()")))) diff --git a/tezt/tests/dune b/tezt/tests/dune index e503505f9839..20e7bc6411d1 100644 --- a/tezt/tests/dune +++ b/tezt/tests/dune @@ -76,6 +76,7 @@ src_lib_proxy_test_tezt_lib src_lib_protocol_environment_test_shell_context_tezt_lib src_lib_protocol_environment_test_tezt_lib + src_lib_polynomial_test_tezt_lib src_lib_p2p_tezt_tezt_lib src_lib_mockup_test_tezt_lib src_lib_lwt_result_stdlib_test_tezt_lib -- GitLab