diff --git a/README.md b/README.md index 4ca36af..2be6e97 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ After [installation](#installation), the available high-level protocols are: - [x] Ethereum EVM precompiles on BN254_Snarks (also called alt_bn128 or bn256 in Ethereum) `import constantine/ethereum_evm_precompiles` -- [ ] BLS signature on BLS12-381 G2 as used in Ethereum 2. +- [x] BLS signature on BLS12-381 G2 as used in Ethereum 2. Cryptographic suite: `BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_` This scheme is also used in the following blockchains: diff --git a/benchmarks/bench_blssig_on_bls12_381_g2.nim b/benchmarks/bench_blssig_on_bls12_381_g2.nim new file mode 100644 index 0000000..f34eea1 --- /dev/null +++ b/benchmarks/bench_blssig_on_bls12_381_g2.nim @@ -0,0 +1,187 @@ +# Constantine +# Copyright (c) 2018-2019 Status Research & Development GmbH +# Copyright (c) 2020-Present Mamy André-Ratsimbazafy +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +import + # Internals + ../constantine/blssig_pop_on_bls12381_g2, + # Helpers + ../helpers/prng_unsafe, + ./bench_blueprint + +proc separator*() = separator(132) + +proc report(op, curve: string, startTime, stopTime: MonoTime, startClk, stopClk: int64, iters: int) = + let ns = inNanoseconds((stopTime-startTime) div iters) + let throughput = 1e9 / float64(ns) + when SupportsGetTicks: + echo &"{op:<40} {curve:<15} {throughput:>15.3f} ops/s {ns:>9} ns/op {(stopClk - startClk) div iters:>9} CPU cycles (approx)" + else: + echo &"{op:<40} {curve:<15} {throughput:>15.3f} ops/s {ns:>9} ns/op" + +template bench(op: string, curve: string, iters: int, body: untyped): untyped = + measure(iters, startTime, stopTime, startClk, stopClk, body) + report(op, curve, startTime, stopTime, startClk, stopClk, iters) + +proc benchDeserPubkey*(iters: int) = + var seckey: array[32, byte] + for i in 1 ..< 32: + seckey[i] = byte 42 + var + sk{.noInit.}: SecretKey + pk{.noInit.}: PublicKey + pk_comp{.noInit.}: array[48, byte] + + let ok = sk.deserialize_secret_key(seckey) + doAssert ok == cttBLS_Success + let ok2 = pk.derive_public_key(sk) + doAssert ok2 == cttBLS_Success + + # Serialize compressed + let ok3 = pk_comp.serialize_public_key_compressed(pk) + doAssert ok3 == cttBLS_Success + + var pk2{.noInit.}: PublicKey + + bench("Pubkey deserialization (full checks)", "BLS12_381 G1", iters): + let status = pk2.deserialize_public_key_compressed(pk_comp) + +proc benchDeserPubkeyUnchecked*(iters: int) = + var seckey: array[32, byte] + for i in 1 ..< 32: + seckey[i] = byte 42 + var + sk{.noInit.}: SecretKey + pk{.noInit.}: PublicKey + pk_comp{.noInit.}: array[48, byte] + + let ok = sk.deserialize_secret_key(seckey) + doAssert ok == cttBLS_Success + let ok2 = pk.derive_public_key(sk) + doAssert ok2 == cttBLS_Success + + # Serialize compressed + let ok3 = pk_comp.serialize_public_key_compressed(pk) + doAssert ok3 == cttBLS_Success + + var pk2{.noInit.}: PublicKey + + bench("Pubkey deserialization (skip checks)", "BLS12_381 G1", iters): + let status = pk2.deserialize_public_key_compressed_unchecked(pk_comp) + +proc benchDeserSig*(iters: int) = + var seckey: array[32, byte] + for i in 1 ..< 32: + seckey[i] = byte 42 + const msg = "abcdef0123456789" + + var + sk{.noInit.}: SecretKey + pk{.noInit.}: PublicKey + sig_comp{.noInit.}: array[96, byte] + sig {.noInit.}: Signature + + let ok = sk.deserialize_secret_key(seckey) + doAssert ok == cttBLS_Success + let ok2 = pk.derive_public_key(sk) + doAssert ok2 == cttBLS_Success + + let status = sig.sign(sk, msg) + doAssert status == cttBLS_Success + + # Serialize compressed + let ok3 = sig_comp.serialize_signature_compressed(sig) + doAssert ok3 == cttBLS_Success + + var sig2{.noInit.}: Signature + + bench("Signature deserialization (full checks)", "BLS12_381 G2", iters): + let status = sig2.deserialize_signature_compressed(sig_comp) + +proc benchDeserSigUnchecked*(iters: int) = + var seckey: array[32, byte] + for i in 1 ..< 32: + seckey[i] = byte 42 + const msg = "abcdef0123456789" + + var + sk{.noInit.}: SecretKey + pk{.noInit.}: PublicKey + sig_comp{.noInit.}: array[96, byte] + sig {.noInit.}: Signature + + let ok = sk.deserialize_secret_key(seckey) + doAssert ok == cttBLS_Success + let ok2 = pk.derive_public_key(sk) + doAssert ok2 == cttBLS_Success + + let status = sig.sign(sk, msg) + doAssert status == cttBLS_Success + + # Serialize compressed + let ok3 = sig_comp.serialize_signature_compressed(sig) + doAssert ok3 == cttBLS_Success + + var sig2{.noInit.}: Signature + + bench("Signature deserialization (skip checks)", "BLS12_381 G2", iters): + let status = sig2.deserialize_signature_compressed_unchecked(sig_comp) + +proc benchSign*(iters: int) = + var seckey: array[32, byte] + for i in 1 ..< 32: + seckey[i] = byte 42 + let msg = "Mr F was here" + + var pk: PublicKey + var sk: SecretKey + var sig: Signature + + let ok = sk.deserialize_secret_key(seckey) + doAssert ok == cttBLS_Success + + bench("BLS signature", "BLS12_381 G2", iters): + let status = sig.sign(sk, msg) + doAssert status == cttBLS_Success + + +proc benchVerify*(iters: int) = + var seckey: array[32, byte] + for i in 1 ..< 32: + seckey[i] = byte 42 + let msg = "Mr F was here" + + var pk: PublicKey + var sk: SecretKey + var sig: Signature + + let ok = sk.deserialize_secret_key(seckey) + doAssert ok == cttBLS_Success + + let ok2 = sig.sign(sk, msg) + + let ok3 = pk.derive_public_key(sk) + doAssert ok3 == cttBLS_Success + + bench("BLS verification", "BLS12_381", iters): + let valid = pk.verify(msg, sig) + +const Iters = 1000 + +proc main() = + separator() + benchDeserPubkey(Iters) + benchDeserPubkeyUnchecked(Iters) + benchDeserSig(Iters) + benchDeserSigUnchecked(Iters) + separator() + benchSign(Iters) + benchVerify(Iters) + separator() + +main() +notes() diff --git a/benchmarks/bench_fields_template.nim b/benchmarks/bench_fields_template.nim index bb9b462..b6ec393 100644 --- a/benchmarks/bench_fields_template.nim +++ b/benchmarks/bench_fields_template.nim @@ -38,7 +38,7 @@ macro fixFieldDisplay(T: typedesc): untyped = # At compile-time, enums are integers and their display is buggy # we get the Curve ID instead of the curve name. let instantiated = T.getTypeInst() - var name = $instantiated[1][0] # Fp + var name = $instantiated[1][0] # 𝔽p name.add "[" & $Curve(instantiated[1][1].intVal) & "]" result = newLit name diff --git a/constantine.nimble b/constantine.nimble index 9bc685f..58e60f9 100644 --- a/constantine.nimble +++ b/constantine.nimble @@ -190,8 +190,8 @@ const testDesc: seq[tuple[path: string, useGMP: bool]] = @[ # Protocols # ---------------------------------------------------------- - ("tests/t_sig_bls_lowlevel.nim", false), ("tests/t_ethereum_evm_precompiles.nim", false), + ("tests/t_blssig_pop_on_bls12381_g2.nim", false), ] # For temporary (hopefully) investigation that can only be reproduced in CI @@ -209,9 +209,7 @@ const skipSanitizers = [ "tests/backend/t_ec_sage_bls12_377.nim", "tests/backend/t_ec_sage_bls12_381.nim", "tests/backend/t_hash_to_field.nim", - "tests/backend/t_hash_to_curve.nim", - "tests/backend/t_sig_bls_lowlevel.nim", - "tests/protocols/t_ethereum_evm_precompiles.nim" + "tests/backend/t_hash_to_curve.nim" ] when defined(windows): @@ -746,3 +744,20 @@ task bench_hash_to_curve_gcc_noasm, "Run Hash-to-Curve benchmarks": task bench_hash_to_curve_clang_noasm, "Run Hash-to-Curve benchmarks": runBench("bench_hash_to_curve", "clang", useAsm = false) + +# BLS signatures +# ------------------------------------------ +task bench_blssig_on_bls12_381_g2, "Run Hash-to-Curve benchmarks": + runBench("bench_blssig_on_bls12_381_g2") + +task bench_blssig_on_bls12_381_g2_gcc, "Run Hash-to-Curve benchmarks": + runBench("bench_blssig_on_bls12_381_g2", "gcc") + +task bench_blssig_on_bls12_381_g2_clang, "Run Hash-to-Curve benchmarks": + runBench("bench_blssig_on_bls12_381_g2", "clang") + +task bench_blssig_on_bls12_381_g2_gcc_noasm, "Run Hash-to-Curve benchmarks": + runBench("bench_blssig_on_bls12_381_g2", "gcc", useAsm = false) + +task bench_blssig_on_bls12_381_g2_clang_noasm, "Run Hash-to-Curve benchmarks": + runBench("bench_blssig_on_bls12_381_g2", "clang", useAsm = false) diff --git a/constantine/backend/config/curves_declaration.nim b/constantine/backend/config/curves_declaration.nim index 8d0ef05..2b5be17 100644 --- a/constantine/backend/config/curves_declaration.nim +++ b/constantine/backend/config/curves_declaration.nim @@ -36,7 +36,7 @@ export CurveFamily, SexticTwist # - type Curve* = enum # - proc Mod*(curve: static Curve): auto # which returns the field modulus of the curve -# - proc Family*(curve: static Curve): CurveFamily +# - proc family*(curve: static Curve): CurveFamily # which returns the curve family declareCurves: diff --git a/constantine/backend/curves/bls12_377_g2_params.nim b/constantine/backend/curves/bls12_377_constants.nim similarity index 100% rename from constantine/backend/curves/bls12_377_g2_params.nim rename to constantine/backend/curves/bls12_377_constants.nim diff --git a/constantine/backend/curves/bls12_381_g2_params.nim b/constantine/backend/curves/bls12_381_constants.nim similarity index 100% rename from constantine/backend/curves/bls12_381_g2_params.nim rename to constantine/backend/curves/bls12_381_constants.nim diff --git a/constantine/backend/curves/bls12_381_generators.nim b/constantine/backend/curves/bls12_381_generators.nim new file mode 100644 index 0000000..d1eb747 --- /dev/null +++ b/constantine/backend/curves/bls12_381_generators.nim @@ -0,0 +1,32 @@ +# Constantine +# Copyright (c) 2018-2019 Status Research & Development GmbH +# Copyright (c) 2020-Present Mamy André-Ratsimbazafy +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +import + ../config/[curves, type_ff], + ../elliptic/ec_shortweierstrass_affine, + ../io/[io_fields, io_towers] + +# Generators +# ----------------------------------------------------------------- +# https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-10#section-4.2.1 + +const BLS12_381_generator_G1* = ECP_ShortW_Aff[Fp[BLS12_381], G1]( + x: Fp[BLS12_381].fromHex"0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb", + y: Fp[BLS12_381].fromHex"0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e1" +) + +const BLS12_381_generator_G2* = ECP_ShortW_Aff[Fp2[BLS12_381], G2]( + x: Fp2[BLS12_381].fromHex( + "0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d1770bac0326a805bbefd48056c8c121bdb8", + "0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049334cf11213945d57e5ac7d055d042b7e" + ), + y: Fp2[BLS12_381].fromHex( + "0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c923ac9cc3baca289e193548608b82801", + "0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab3f370d275cec1da1aaa9075ff05f79be" + ) +) diff --git a/constantine/backend/curves/bls12_381_subgroups.nim b/constantine/backend/curves/bls12_381_subgroups.nim index 3ce2152..7aeaf21 100644 --- a/constantine/backend/curves/bls12_381_subgroups.nim +++ b/constantine/backend/curves/bls12_381_subgroups.nim @@ -82,11 +82,11 @@ const Cofactor_Eff_BLS12_381_G2 = BigInt[636].fromHex"0xbc69f08f2ee75b3584c6a0ea ## P -> (x^2 - x - 1) P + (x - 1) ψ(P) + ψ(ψ(2P)) func clearCofactorReference*(P: var ECP_ShortW_Prj[Fp[BLS12_381], G1]) {.inline.} = - ## Clear the cofactor of BLS12_381 G1 + ## Clear the cofactor of BLS12_381 𝔾1 P.scalarMulGeneric(Cofactor_Eff_BLS12_381_G1) func clearCofactorReference*(P: var ECP_ShortW_Prj[Fp2[BLS12_381], G2]) {.inline.} = - ## Clear the cofactor of BLS12_381 G2 + ## Clear the cofactor of BLS12_381 𝔾2 # Endomorphism acceleration cannot be used if cofactor is not cleared P.scalarMulGeneric(Cofactor_Eff_BLS12_381_G2) @@ -96,11 +96,11 @@ func clearCofactorReference*(P: var ECP_ShortW_Prj[Fp2[BLS12_381], G2]) {.inline # # ############################################################ -# BLS12 G1 +# BLS12 𝔾1 # ------------------------------------------------------------ -func clearCofactorFast*(P: var ECP_ShortW_Prj[Fp[BLS12_381], G1]) = - ## Clear the cofactor of BLS12_381 G1 +func clearCofactorFast*(P: var ECP_ShortW[Fp[BLS12_381], G1]) = + ## Clear the cofactor of BLS12_381 𝔾1 ## ## Wahby et al "Fast and simple constant-time hashing to the BLS12-381 elliptic curve", https://eprint.iacr.org/2019/403 ## Optimized using endomorphisms @@ -109,19 +109,19 @@ func clearCofactorFast*(P: var ECP_ShortW_Prj[Fp[BLS12_381], G1]) = t.pow_bls12_381_minus_x(P) # [-x]P P += t # [1-x]P -# BLS12 G2 +# BLS12 𝔾2 # ------------------------------------------------------------ # From any point on the elliptic curve E2 of a BLS12 curve -# Obtain a point in the G2 prime-order subgroup +# Obtain a point in the 𝔾2 prime-order subgroup # # Described in https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#appendix-G.4 # # Implementations, multiple implementations are possible in increasing order of speed: # # - The default, canonical, implementation is h_eff * P -# - Scott et al, "Fast Hashing to G2 on Pairing-Friendly Curves", https://doi.org/10.1007/978-3-642-03298-1_8 -# - Fuentes-Castaneda et al, "Fast Hashing to G2 on Pairing-Friendly Curves", https://doi.org/10.1007/978-3-642-28496-0_25 -# - Budroni et al, "Hashing to G2 on BLS pairing-friendly curves", https://doi.org/10.1145/3313880.3313884 +# - Scott et al, "Fast Hashing to 𝔾2 on Pairing-Friendly Curves", https://doi.org/10.1007/978-3-642-03298-1_8 +# - Fuentes-Castaneda et al, "Fast Hashing to 𝔾2 on Pairing-Friendly Curves", https://doi.org/10.1007/978-3-642-28496-0_25 +# - Budroni et al, "Hashing to 𝔾2 on BLS pairing-friendly curves", https://doi.org/10.1145/3313880.3313884 # - Wahby et al "Fast and simple constant-time hashing to the BLS12-381 elliptic curve", https://eprint.iacr.org/2019/403 # - IETF "Hashing to Elliptic Curves", https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-hash-to-curve-11#appendix-G.4 # @@ -138,8 +138,8 @@ func clearCofactorFast*(P: var ECP_ShortW_Prj[Fp[BLS12_381], G1]) = # with Psi (ψ) - untwist-Frobenius-Twist function # and x the curve BLS parameter -func clearCofactorFast*(P: var ECP_ShortW_Prj[Fp2[BLS12_381], G2]) = - ## Clear the cofactor of BLS12_381 G2 +func clearCofactorFast*(P: var ECP_ShortW[Fp2[BLS12_381], G2]) = + ## Clear the cofactor of BLS12_381 𝔾2 ## Optimized using endomorphisms ## P -> [x²-x-1]P + [x-1] ψ(P) + ψ²([2]P) @@ -166,18 +166,18 @@ func clearCofactorFast*(P: var ECP_ShortW_Prj[Fp2[BLS12_381], G2]) = # # ############################################################ -func isInSubgroup*(P: ECP_ShortW_Prj[Fp[BLS12_381], G1]): SecretBool = - ## Returns true if P is in G1 subgroup, i.e. P is a point of order r. +func isInSubgroup*(P: ECP_ShortW_Jac[Fp[BLS12_381], G1] or ECP_ShortW_Prj[Fp[BLS12_381], G1]): SecretBool = + ## Returns true if P is in 𝔾1 subgroup, i.e. P is a point of order r. ## A point may be on a curve but not on the prime order r subgroup. ## Not checking subgroup exposes a protocol to small subgroup attacks. ## ## Warning ⚠: Assumes that P is on curve # Implementation: Scott, https://eprint.iacr.org/2021/1130.pdf - # A note on group membership tests for G1, G2 and GT + # A note on group membership tests for 𝔾1, 𝔾2 and 𝔾T # on BLS pairing-friendly curves - # P is in the G1 subgroup iff ϕ(P) == [-u²](P) - var t0{.noInit.}, t1{.noInit.}: ECP_ShortW_Prj[Fp[BLS12_381], G1] - + # P is in the 𝔾1 subgroup iff ϕ(P) == [-u²](P) + var t0{.noInit.}, t1{.noInit.}: typeof(P) + # [-u²]P t0.pow_bls12_381_x(P) t1.pow_bls12_381_minus_x(t0) @@ -189,18 +189,39 @@ func isInSubgroup*(P: ECP_ShortW_Prj[Fp[BLS12_381], G1]): SecretBool = return t0 == t1 -func isInSubgroup*(P: ECP_ShortW_Prj[Fp2[BLS12_381], G2]): SecretBool = - ## Returns true if P is in G2 subgroup, i.e. P is a point of order r. +func isInSubgroup*(P: ECP_ShortW_Jac[Fp2[BLS12_381], G2] or ECP_ShortW_Prj[Fp2[BLS12_381], G2]): SecretBool = + ## Returns true if P is in 𝔾2 subgroup, i.e. P is a point of order r. ## A point may be on a curve but not on the prime order r subgroup. ## Not checking subgroup exposes a protocol to small subgroup attacks. ## ## Warning ⚠: Assumes that P is on curve # Implementation: Scott, https://eprint.iacr.org/2021/1130.pdf - # A note on group membership tests for G1, G2 and GT + # A note on group membership tests for 𝔾1, 𝔾2 and 𝔾T # on BLS pairing-friendly curves - # P is in the G1 subgroup iff ψ(P) == [u](P) - var t0{.noInit.}, t1{.noInit.}: ECP_ShortW_Prj[Fp2[BLS12_381], G2] + # P is in the 𝔾1 subgroup iff ψ(P) == [u](P) + var t0{.noInit.}, t1{.noInit.}: typeof(P) t0.pow_bls12_381_x(P) # [u]P t1.frobenius_psi(P) # ψ(P) - return t0 == t1 \ No newline at end of file + return t0 == t1 + +func isInSubgroup*(P: ECP_ShortW_Aff[Fp[BLS12_381], G1]): SecretBool = + ## Returns true if P is in 𝔾1 subgroup, i.e. P is a point of order r. + ## A point may be on a curve but not on the prime order r subgroup. + ## Not checking subgroup exposes a protocol to small subgroup attacks. + ## + ## Warning ⚠: Assumes that P is on curve + var t{.noInit.}: ECP_ShortW_Prj[Fp[BLS12_381], G1] + t.fromAffine(P) + return t.isInSubgroup() + + +func isInSubgroup*(P: ECP_ShortW_Aff[Fp2[BLS12_381], G2]): SecretBool = + ## Returns true if P is in 𝔾2 subgroup, i.e. P is a point of order r. + ## A point may be on a curve but not on the prime order r subgroup. + ## Not checking subgroup exposes a protocol to small subgroup attacks. + ## + ## Warning ⚠: Assumes that P is on curve + var t{.noInit.}: ECP_ShortW_Jac[Fp2[BLS12_381], G2] + t.fromAffine(P) + return t.isInSubgroup() \ No newline at end of file diff --git a/constantine/backend/curves/bn254_nogami_g2_params.nim b/constantine/backend/curves/bn254_nogami_constants.nim similarity index 100% rename from constantine/backend/curves/bn254_nogami_g2_params.nim rename to constantine/backend/curves/bn254_nogami_constants.nim diff --git a/constantine/backend/curves/bn254_snarks_g2_params.nim b/constantine/backend/curves/bn254_snarks_constants.nim similarity index 100% rename from constantine/backend/curves/bn254_snarks_g2_params.nim rename to constantine/backend/curves/bn254_snarks_constants.nim diff --git a/constantine/backend/curves/bw6_761_g2_params.nim b/constantine/backend/curves/bw6_761_constants.nim similarity index 100% rename from constantine/backend/curves/bw6_761_g2_params.nim rename to constantine/backend/curves/bw6_761_constants.nim diff --git a/constantine/backend/curves/zoo_g2_params.nim b/constantine/backend/curves/zoo_constants.nim similarity index 87% rename from constantine/backend/curves/zoo_g2_params.nim rename to constantine/backend/curves/zoo_constants.nim index 12f639e..a9c3933 100644 --- a/constantine/backend/curves/zoo_g2_params.nim +++ b/constantine/backend/curves/zoo_constants.nim @@ -9,11 +9,11 @@ import std/macros, ../config/curves, - ./bls12_377_g2_params, - ./bls12_381_g2_params, - ./bn254_nogami_g2_params, - ./bn254_snarks_g2_params, - ./bw6_761_g2_params + ./bls12_377_constants, + ./bls12_381_constants, + ./bn254_nogami_constants, + ./bn254_snarks_constants, + ./bw6_761_constants {.experimental: "dynamicBindSym".} diff --git a/constantine/backend/curves/zoo_generators.nim b/constantine/backend/curves/zoo_generators.nim new file mode 100644 index 0000000..8533d3b --- /dev/null +++ b/constantine/backend/curves/zoo_generators.nim @@ -0,0 +1,23 @@ +# Constantine +# Copyright (c) 2018-2019 Status Research & Development GmbH +# Copyright (c) 2020-Present Mamy André-Ratsimbazafy +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +import + std/macros, + ../config/curves, + ./bls12_381_generators + +{.experimental: "dynamicbindsym".} + +macro getGenerator*(C: static Curve, subgroup: static string = ""): untyped = + ## Returns the curve subgroup generator. + ## Pairing-friendly curves expect G1 or G2 + + if subgroup == "": + return bindSym($C & "_generator") + else: + return bindSym($C & "_generator_" & subgroup) \ No newline at end of file diff --git a/constantine/backend/curves/zoo_subgroups.nim b/constantine/backend/curves/zoo_subgroups.nim index 7c1ce68..99e4f47 100644 --- a/constantine/backend/curves/zoo_subgroups.nim +++ b/constantine/backend/curves/zoo_subgroups.nim @@ -25,7 +25,7 @@ export func clearCofactor*[ECP](P: var ECP) {.inline.} = ## Clear the cofactor of a point on the curve ## From a point on the curve, returns a point on the subgroup of order r - when ECP.F.C in {BLS12_381}: + when ECP.F.C in {BN254_Nogami, BN254_SNarks, BLS12_377, BLS12_381}: P.clearCofactorFast() else: P.clearCofactorReference() diff --git a/constantine/backend/elliptic/ec_endomorphism_accel.nim b/constantine/backend/elliptic/ec_endomorphism_accel.nim index 57f5649..fe3523c 100644 --- a/constantine/backend/elliptic/ec_endomorphism_accel.nim +++ b/constantine/backend/elliptic/ec_endomorphism_accel.nim @@ -29,7 +29,6 @@ import # using: # - GLV endomorphism on G1 (Gallant-Lambert-Vanstone) # - GLV and GLS endomorphisms on G2 (Galbraith-Lin-Scott) -# - NAF recoding (windowed Non-Adjacent-Form) # Decomposition into scalars -> miniscalars # ---------------------------------------------------------------------------------------- diff --git a/constantine/backend/elliptic/ec_shortweierstrass_affine.nim b/constantine/backend/elliptic/ec_shortweierstrass_affine.nim index 3916c5e..b968003 100644 --- a/constantine/backend/elliptic/ec_shortweierstrass_affine.nim +++ b/constantine/backend/elliptic/ec_shortweierstrass_affine.nim @@ -12,7 +12,7 @@ import ../arithmetic, ../towers, ../io/[io_fields, io_towers], - ../curves/zoo_g2_params + ../curves/zoo_constants # ############################################################ # @@ -45,6 +45,11 @@ func isInf*(P: ECP_ShortW_Aff): SecretBool = ## and false otherwise result = P.x.isZero() and P.y.isZero() +func setInf*(P: var ECP_ShortW_Aff) = + ## Set P to the infinity point + P.x.setZero() + P.y.setZero() + func ccopy*(P: var ECP_ShortW_Aff, Q: ECP_ShortW_Aff, ctl: SecretBool) {.inline.} = ## Constant-time conditional copy ## If ctl is true: Q is copied into P @@ -71,7 +76,7 @@ func curve_eq_rhs*[F](y2: var F, x: F, G: static Subgroup) = y2.fromUint uint -F.C.getCoefB() y2.diff(t, y2) else: - y2.sum(F.C.getCoefB_G2, t) + y2.sum(F.C.getCoefB_G2(), t) when F.C.getCoefA() != 0: t = x diff --git a/constantine/backend/hash_to_curve/h2c_hash_to_field.nim b/constantine/backend/hash_to_curve/h2c_hash_to_field.nim index 8dd46e0..1cfde96 100644 --- a/constantine/backend/hash_to_curve/h2c_hash_to_field.nim +++ b/constantine/backend/hash_to_curve/h2c_hash_to_field.nim @@ -41,14 +41,14 @@ template strxor(b_i: var array, b0: array): untyped = b_i[i] = b_i[i] xor b0[i] # ---------------------------------------------------------------- -func shortDomainSepTag[DigestSize: static int, B: byte|char]( +func shortDomainSepTag*[DigestSize: static int, B: byte|char]( H: type CryptoHash, output: var array[DigestSize, byte], oversizedDST: openarray[B]) = ## Compute a short Domain Separation Tag - ## from a domain separation tag larger than 255 bits + ## from a domain separation tag larger than 255 bytes ## - ## https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-09#section-5.4.3 + ## https://tools.ietf.org/html/draft-irtf-cfrg-hash-to-curve-14#section-5.4.3 static: doAssert DigestSize == H.type.digestSize var ctx {.noInit.}: H ctx.init() @@ -86,11 +86,10 @@ func expandMessageXMD*[B1, B2, B3: byte|char, len_in_bytes: static int]( ## and `CoreVerify(PK, PK || message, signature)` ## - `message` is the message to hash ## - `domainSepTag` is the protocol domain separation tag (DST). - ## If a domainSepTag larger than 255-bit is required, - ## it is recommended to cache the reduced DST - - # TODO oversized DST support - + ## `domainSepTag` MUST be at most 255 bytes. + ## The function `shortDomainSepTag` MUST be used to compute an adequate DST + ## for an oversized source DST. + ## That DST can be cached. # Steps: # 1. ell = ceil(len_in_bytes / b_in_bytes) # 2. ABORT if ell > 255 @@ -210,7 +209,7 @@ func hashToField*[Field; B1, B2, B3: byte|char, count: static int]( len_in_bytes = count * m * L var uniform_bytes{.noInit.}: array[len_in_bytes, byte] - sha256.expandMessageXMD( + H.expandMessageXMD( uniform_bytes, augmentation = augmentation, message = message, diff --git a/constantine/backend/hash_to_curve/h2c_map_to_isocurve_swu.nim b/constantine/backend/hash_to_curve/h2c_map_to_isocurve_swu.nim index dedb940..9506242 100644 --- a/constantine/backend/hash_to_curve/h2c_map_to_isocurve_swu.nim +++ b/constantine/backend/hash_to_curve/h2c_map_to_isocurve_swu.nim @@ -54,7 +54,7 @@ func sgn0(x: Fp): SecretBool = # Another angle is that if M is odd, # a+M and a have different parity even though they are # the same modulo M. - let canonical = x.toBig() + let canonical {.noInit.} = x.toBig() result = canonical.isOdd() func sgn0(x: Fp2): SecretBool = diff --git a/constantine/backend/hash_to_curve/hash_to_curve.nim b/constantine/backend/hash_to_curve/hash_to_curve.nim index 752c7ba..f11e131 100644 --- a/constantine/backend/hash_to_curve/hash_to_curve.nim +++ b/constantine/backend/hash_to_curve/hash_to_curve.nim @@ -125,7 +125,7 @@ func hashToCurve*[ B1, B2, B3: byte|char]( H: type CryptoHash, k: static int, - output: var ECP_ShortW_Prj[F, G], + output: var ECP_ShortW_Jac[F, G], augmentation: openarray[B1], message: openarray[B2], domainSepTag: openarray[B3] @@ -149,20 +149,52 @@ func hashToCurve*[ ## and `CoreVerify(PK, PK || message, signature)` ## - `message` is the message to hash ## - `domainSepTag` is the protocol domain separation tag (DST). - ## If a domainSepTag larger than 255-bit is required, - ## it is recommended to cache the reduced DST. var u{.noInit.}: array[2, F] - H.hashToField(k, u, augmentation, message, domainSepTag) - - when false: - var P{.noInit.}: array[2, ECP_ShortW_Prj[F, G]] - P[0].mapToCurve(u[0]) - P[1].mapToCurve(u[1]) - output.sum(P[0], P[1]) + if domainSepTag.len <= 255: + H.hashToField(k, u, augmentation, message, domainSepTag) else: - var Pjac{.noInit.}: ECP_ShortW_Jac[F, G] - Pjac.mapToCurve_fusedAdd(u[0], u[1]) - output.projectiveFromJacobian(Pjac) + const N = H.type.digestSize() + var dst {.noInit.}: array[N, byte] + H.shortDomainSepTag(dst, domainSepTag) + H.hashToField(k, u, augmentation, message, dst) + output.mapToCurve_fusedAdd(u[0], u[1]) output.clearCofactor() + +func hashToCurve*[ + F; G: static Subgroup; + B1, B2, B3: byte|char]( + H: type CryptoHash, + k: static int, + output: var (ECP_ShortW_Prj[F, G] or ECP_ShortW_Aff[F, G]), + augmentation: openarray[B1], + message: openarray[B2], + domainSepTag: openarray[B3] + ) = + ## Hash a message to an elliptic curve + ## + ## Arguments: + ## - `Hash` a cryptographic hash function. + ## - `Hash` MAY be a Merkle-Damgaard hash function like SHA-2 + ## - `Hash` MAY be a sponge-based hash function like SHA-3 or BLAKE2 + ## - Otherwise, H MUST be a hash function that has been proved + ## indifferentiable from a random oracle [MRH04] under a reasonable + ## cryptographic assumption. + ## - k the security parameter of the suite in bits (for example 128) + ## - `output`, an elliptic curve point that will be overwritten. + ## - `augmentation`, an optional augmentation to the message. This will be prepended, + ## prior to hashing. + ## This is used for building the "message augmentation" variant of BLS signatures + ## https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-04#section-3.2 + ## which requires `CoreSign(SK, PK || message)` + ## and `CoreVerify(PK, PK || message, signature)` + ## - `message` is the message to hash + ## - `domainSepTag` is the protocol domain separation tag (DST). + + var Pjac{.noInit.}: ECP_ShortW_Jac[F, G] + H.hashToCurve(k, Pjac, augmentation, message, domainSepTag) + when output is ECP_ShortW_Prj: + output.projectiveFromJacobian(Pjac) + else: + output.affine(Pjac) \ No newline at end of file diff --git a/constantine/backend/hashes.nim b/constantine/backend/hashes.nim index f82908d..caca378 100644 --- a/constantine/backend/hashes.nim +++ b/constantine/backend/hashes.nim @@ -25,8 +25,8 @@ type ## - SHA3-512 block size is 72 bits # should we avoid int to avoid exception? But they are compile-time - H.digestSize is int - H.internalBlockSize is int + H.digestSize is static int + H.internalBlockSize is static int # Context # ------------------------------------------- diff --git a/constantine/backend/io/io_bigints.nim b/constantine/backend/io/io_bigints.nim index 6c1e475..d6b59df 100644 --- a/constantine/backend/io/io_bigints.nim +++ b/constantine/backend/io/io_bigints.nim @@ -293,7 +293,8 @@ func exportRawUint*( ## or zero-padded right for little-endian. ## I.e least significant bit is aligned to buffer boundary - assert dst.len >= (BigInt.bits + 7) div 8, "BigInt -> Raw int conversion: destination buffer is too small" + debug: + doAssert dst.len >= (BigInt.bits + 7) div 8, "BigInt -> Raw int conversion: destination buffer is too small" when BigInt.bits == 0: zeroMem(dst, dst.len) diff --git a/constantine/backend/pairing/pairing_bls12.nim b/constantine/backend/pairing/pairing_bls12.nim index 6759641..fc09f18 100644 --- a/constantine/backend/pairing/pairing_bls12.nim +++ b/constantine/backend/pairing/pairing_bls12.nim @@ -15,6 +15,7 @@ import ], ../isogeny/frobenius, ../curves/zoo_pairings, + ../arithmetic, ./cyclotomic_subgroup, ./lines_eval, ./miller_loops @@ -118,7 +119,7 @@ func finalExpHard_BLS12*[C](f: var Fp12[C]) {.meter.} = v2.cyclotomic_square(f) # v2 = f² # (x−1)² - when C.pairing(ate_param).isEven.bool: + when C.pairing(ate_param).isEven().bool: v0.cycl_exp_by_curve_param_div2(v2) # v0 = (f²)^(x/2) = f^x else: v0.cycl_exp_by_curve_param(f) diff --git a/constantine/backend/pairings.nim b/constantine/backend/pairings.nim new file mode 100644 index 0000000..1633d0d --- /dev/null +++ b/constantine/backend/pairings.nim @@ -0,0 +1,20 @@ +# Constantine +# Copyright (c) 2018-2019 Status Research & Development GmbH +# Copyright (c) 2020-Present Mamy André-Ratsimbazafy +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +import + ./config/curves, + ./pairing/[pairing_bn, pairing_bls12], + ./towers + +template pairing*[C](gt: var Fp12[C], P, Q: typed) = + when family(C) == BarretoNaehrig: + pairing_bn(gt, P, Q) + elif family(C) == BarretoLynnScott: + pairing_bls12(gt, P, Q) + else: + {.error: "Pairing not implemented for " & $C.} \ No newline at end of file diff --git a/constantine/backend/signatures/README.md b/constantine/backend/signatures/README.md new file mode 100644 index 0000000..99485fa --- /dev/null +++ b/constantine/backend/signatures/README.md @@ -0,0 +1,6 @@ +# Signatures schemes + +## BLS signatures (Boneh-Lynn-Schacham) + +- https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04 +- https://github.com/cfrg/draft-irtf-cfrg-bls-signature diff --git a/constantine/backend/signatures/bls_signatures.nim b/constantine/backend/signatures/bls_signatures.nim new file mode 100644 index 0000000..87ba27b --- /dev/null +++ b/constantine/backend/signatures/bls_signatures.nim @@ -0,0 +1,126 @@ +# Constantine +# Copyright (c) 2018-2019 Status Research & Development GmbH +# Copyright (c) 2020-Present Mamy André-Ratsimbazafy +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +import + ../ec_shortweierstrass, + ../hash_to_curve/hash_to_curve, + ../hashes, ../pairings, + ../curves/zoo_generators + +# ############################################################ +# +# BLS Signatures +# +# ############################################################ + +# This module implements generic BLS signatures +# https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04 +# https://github.com/cfrg/draft-irtf-cfrg-bls-signature +# +# We use generic shortnames SecKey, PubKey, Sig +# so tat the algorithms fit whether Pubkey and Sig are on G1 or G2 +# Actual protocols should expose publicly the full names SecretKey, PublicKey and Signature + + +{.push inline.} # inline in the main public procs +{.push raises: [].} # No exceptions allowed in core cryptographic operations + + +func derivePubkey*[Pubkey, SecKey](pubkey: var Pubkey, seckey: SecKey): bool = + ## Generates the public key associated with the input secret key. + ## + ## Returns: + ## - false is secret key is invalid (SK == 0 or >= BLS12-381 curve order), + ## true otherwise + ## By construction no public API should ever instantiate + ## an invalid secretkey in the first place. + const Group = Pubkey.G + type Field = Pubkey.F + const EC = Field.C + + if seckey.isZero().bool: + return false + if bool(seckey >= EC.getCurveOrder()): + return false + + var pk {.noInit.}: ECP_ShortW_Jac[Field, Group] + pk.fromAffine(EC.getGenerator($Group)) + pk.scalarMul(seckey) + pubkey.affine(pk) + return true + +func coreSign*[B1, B2, B3: byte|char, Sig, SecKey]( + signature: var Sig, + secretKey: SecKey, + message: openarray[B1], + H: type CryptoHash, + k: static int, + augmentation: openarray[B2], + domainSepTag: openarray[B3]) = + ## Computes a signature for the message from the specified secret key. + ## + ## Output: + ## - `signature` is overwritten with `message` signed with `secretKey` + ## + ## Inputs: + ## - `Hash` a cryptographic hash function. + ## - `Hash` MAY be a Merkle-Damgaard hash function like SHA-2 + ## - `Hash` MAY be a sponge-based hash function like SHA-3 or BLAKE2 + ## - Otherwise, H MUST be a hash function that has been proved + ## indifferentiable from a random oracle [MRH04] under a reasonable + ## cryptographic assumption. + ## - k the security parameter of the suite in bits (for example 128) + ## - `output`, an elliptic curve point that will be overwritten. + ## - `augmentation`, an optional augmentation to the message. This will be prepended, + ## prior to hashing. + ## This is used for building the "message augmentation" variant of BLS signatures + ## https://tools.ietf.org/html/draft-irtf-cfrg-bls-signature-04#section-3.2 + ## which requires `CoreSign(SK, PK || message)` + ## and `CoreVerify(PK, PK || message, signature)` + ## - `message` is the message to hash + ## - `domainSepTag` is the protocol domain separation tag (DST). + + type ECP_Jac = ECP_ShortW_Jac[Sig.F, Sig.G] + + var sig {.noInit.}: ECP_Jac + H.hashToCurve(k, sig, augmentation, message, domainSepTag) + sig.scalarMul(secretKey) + + signature.affine(sig) + +func coreVerify*[B1, B2, B3: byte|char, Pubkey, Sig]( + pubKey: Pubkey, + message: openarray[B1], + signature: Sig, + H: type CryptoHash, + k: static int, + augmentation: openarray[B2], + domainSepTag: openarray[B3]): bool = + ## Check that a signature is valid + ## for a message under the provided public key + ## This assumes that the PublicKey and Signatures + ## have been pre-checked for non-infinity and being in the correct subgroup + ## (likely on deserialization) + var Q {.noInit.}: ECP_ShortW_Aff[Sig.F, Sig.G] + var negG {.noInit.}: ECP_ShortW_Aff[Pubkey.F, Pubkey.G] + + negG.neg(Pubkey.F.C.getGenerator($Pubkey.G)) + H.hashToCurve(k, Q, augmentation, message, domainSepTag) + + when Sig.F.C.getEmbeddingDegree() == 12: + var gt {.noInit.}: Fp12[Sig.F.C] + else: + {.error: "Not implemented: signature on k=" & $Sig.F.C.getEmbeddingDegree() & " for curve " & $$Sig.F.C.} + + # e(PK, H(msg))*e(sig, -G) == 1 + when Sig.G == G2: + pairing(gt, [pubKey, negG], [Q, signature]) + else: + pairing(gt, [Q, signature], [pubKey, negG]) + + return gt.isOne().bool() \ No newline at end of file diff --git a/constantine/blssig_pop_on_bls12381_g2.nim b/constantine/blssig_pop_on_bls12381_g2.nim new file mode 100644 index 0000000..5856b97 --- /dev/null +++ b/constantine/blssig_pop_on_bls12381_g2.nim @@ -0,0 +1,408 @@ +# Constantine +# Copyright (c) 2018-2019 Status Research & Development GmbH +# Copyright (c) 2020-Present Mamy André-Ratsimbazafy +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +import + ./backend/config/[ + common, curves, type_bigint, type_ff + ], + ./backend/[ + ec_shortweierstrass, + hash_to_curve/hash_to_curve, + hashes, + towers, + arithmetic, + signatures/bls_signatures, + curves/zoo_subgroups, + primitives + ], + ./backend/io/[io_bigints, io_fields] + +export + curves, # generic sandwich on matchingBigInt + towers, # generic sandwich on extension field access + hashes, # generic sandwich on sha256 + ec_shortweierstrass # generic sandwich on affine + +## ############################################################ +## +## BLS Signatures on BLS12-381 G2 +## +## ############################################################ +## +## This module implements BLS Signatures (Boneh-Lynn-Schacham) +## on top of the BLS12-381 curve (Barreto-Lynn-Scott). +## +## Ciphersuite: +## +## - Secret keys on Fr (32 bytes) +## - Public keys on G1 (48 bytes compressed, 96 bytes uncompressed) +## - Signatures on G2 (96 bytes compressed, 192 bytes uncompressed) +## +## Hash-to curve: +## - Domain separation tag: "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_" +## - Hash function: SHA256 +## +## Currently Constantine does not provide popProve and popVerify +## which are thin wrapper over sign/verify with +## - the message to sign or verify being the compressed or uncompressed public key +## or another application-specific "hash_pubkey_to_point" scheme +## - domain-separation-tag: "BLS_POP_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_" +## +## Constantine currently assumes that proof-of-possessions are handled at the application-level +## +## In proof-of-stake blockchains, being part of the staker/validator sets +## already serve as proof-of-possession. + +const DST = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_" +const ffi_prefix = "ctt_blssig_pop_on_bls12381_g2_" + +{.push raises: [].} # No exceptions allowed in core cryptographic operations +# {.push cdecl, dynlib, exportc:ffi_prefix & "$1".} # TODO, C API + +type + SecretKey* {.byref.} = object + ## A BLS12_381 secret key + raw: matchingOrderBigInt(BLS12_381) + + PublicKey* {.byref.} = object + ## A BLS12_381 public key for BLS signature schemes with public keys on G1 and signatures on G2 + raw: ECP_ShortW_Aff[Fp[BLS12_381], G1] + + Signature* {.byref.} = object + ## A BLS12_381 signature for BLS signature schemes with public keys on G1 and signatures on G2 + raw: ECP_ShortW_Aff[Fp2[BLS12_381], G2] + + CttBLSStatus* = enum + cttBLS_Success + cttBLS_VerificationFailure + cttBLS_InvalidEncoding + cttBLS_CoordinateGreaterOrEqualThanModulus + cttBLS_PointAtInfinity + cttBLS_PointNotOnCurve + cttBLS_PointNotInSubgroup + cttBLS_ZeroSecretKey + cttBLS_SecretKeyLargerThanCurveOrder + +# Comparisons +# ------------------------------------------------------------------------------------------------ + +func isZero*(elem: PublicKey or Signature): bool = + ## Returns true if input is 0 + bool(elem.raw.isInf()) + +func `==`*(a, b: PublicKey or Signature): bool = + ## Returns true if inputs are equal + bool(a.raw == b.raw) + +# Input validation +# ------------------------------------------------------------------------------------------------ + +func validate_seckey*(secret_key: SecretKey): CttBLSStatus = + ## Validate the secret key. + ## Regarding timing attacks, this will leak timing information only if the key is invalid. + ## Namely, the secret key is 0 or the secret key is too large. + if secret_key.raw.isZero().bool(): + return cttBLS_ZeroSecretKey + if bool(secret_key.raw >= BLS12_381.getCurveOrder()): + return cttBLS_SecretKeyLargerThanCurveOrder + return cttBLS_Success + +func validate_pubkey*(public_key: PublicKey): CttBLSStatus = + ## Validate the public key. + ## This is an expensive operation that can be cached + if public_key.raw.isInf().bool(): + return cttBLS_PointAtInfinity + if not isOnCurve(public_key.raw.x, public_key.raw.y, G1).bool(): + return cttBLS_PointNotOnCurve + if not public_key.raw.isInSubgroup().bool(): + return cttBLS_PointNotInSubgroup + +func validate_sig*(signature: Signature): CttBLSStatus = + ## Validate the signature. + ## This is an expensive operation that can be cached + if signature.raw.isInf().bool(): + return cttBLS_PointAtInfinity + if not isOnCurve(signature.raw.x, signature.raw.y, G2).bool(): + return cttBLS_PointNotOnCurve + if not signature.raw.isInSubgroup().bool(): + return cttBLS_PointNotInSubgroup + +# Codecs +# ------------------------------------------------------------------------------------------------ + +## BLS12-381 serialization +## +## 𝔽p elements are encoded in big-endian form. They occupy 48 bytes in this form. +## 𝔽p2​ elements are encoded in big-endian form, meaning that the 𝔽p2​ element c0+c1u +## is represented by the 𝔽p​ element c1​ followed by the 𝔽p element c0​. +## This means 𝔽p2​ elements occupy 96 bytes in this form. +## The group 𝔾1​ uses 𝔽p elements for coordinates. The group 𝔾2​ uses 𝔽p2​ elements for coordinates. +## 𝔾1​ and 𝔾2​ elements can be encoded in uncompressed form (the x-coordinate followed by the y-coordinate) or in compressed form (just the x-coordinate). +## 𝔾1​ elements occupy 96 bytes in uncompressed form, and 48 bytes in compressed form. +## 𝔾2​ elements occupy 192 bytes in uncompressed form, and 96 bytes in compressed form. +## +## The most-significant three bits of a 𝔾1​ or 𝔾2​ encoding should be masked away before the coordinate(s) are interpreted. These bits are used to unambiguously represent the underlying element: +## +## The most significant bit, when set, indicates that the point is in compressed form. Otherwise, the point is in uncompressed form. +## The second-most significant bit indicates that the point is at infinity. If this bit is set, the remaining bits of the group element’s encoding should be set to zero. +## The third-most significant bit is set if (and only if) this point is in compressed form +## and it is not the point at infinity and its y-coordinate is the lexicographically largest of the two associated with the encoded x-coordinate. +## +## - https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-bls-signature-04#appendix-A +## - https://docs.rs/bls12_381/latest/bls12_381/notes/serialization/index.html +## - https://github.com/zkcrypto/bls12_381/blob/0.6.0/src/notes/serialization.rs + +func serialize_secret_key*(dst: var array[32, byte], secret_key: SecretKey): CttBLSStatus = + ## Serialize a secret key + ## Returns cttBLS_Success if successful + dst.exportRawUint(secret_key.raw, bigEndian) + return cttBLS_Success + +func serialize_public_key_compressed*(dst: var array[48, byte], public_key: PublicKey): CttBLSStatus = + ## Serialize a public key in compressed (Zcash) format + ## + ## Returns cttBLS_Success if successful + if public_key.raw.isInf().bool(): + for i in 0 ..< dst.len: + dst[i] = byte 0 + dst[0] = byte 0b11000000 # Compressed + Infinity + return cttBLS_Success + + dst.exportRawUint(public_key.raw.x, bigEndian) + # The curve equation has 2 solutions for y² = x³ + 4 with y unknown and x known + # The lexicographically largest will have bit 381 set to 1 + # (and bit 383 for the compressed representation) + # The solutions are {y, p-y} hence the lexicographyically largest is greater than p/2 + # so with exact integers, as p is odd, greater or equal (p+1)/2 + let lexicographicallyLargest = byte(public_key.raw.y.toBig() >= Fp[BLS12_381].getPrimePlus1div2()) + dst[0] = dst[0] or (0b10000000 or (lexicographicallyLargest shl 5)) + + return cttBLS_Success + +func serialize_signature_compressed*(dst: var array[96, byte], signature: Signature): CttBLSStatus = + ## Serialize a signature in compressed (Zcash) format + ## + ## Returns cttBLS_Success if successful + if signature.raw.isInf().bool(): + for i in 0 ..< dst.len: + dst[i] = byte 0 + dst[0] = byte 0b11000000 # Compressed + Infinity + return cttBLS_Success + + dst.toOpenArray(0, 48-1).exportRawUint(signature.raw.x.c1, bigEndian) + dst.toOpenArray(48, 96-1).exportRawUint(signature.raw.x.c0, bigEndian) + + let isLexicographicallyLargest = + if signature.raw.y.c1.isZero().bool(): + byte(signature.raw.y.c0.toBig() >= Fp[BLS12_381].getPrimePlus1div2()) + else: + byte(signature.raw.y.c1.toBig() >= Fp[BLS12_381].getPrimePlus1div2()) + dst[0] = dst[0] or (byte 0b10000000 or (isLexicographicallyLargest shl 5)) + + return cttBLS_Success + +func deserialize_secret_key*(dst: var SecretKey, src: array[32, byte]): CttBLSStatus = + ## deserialize a secret key + ## + ## This is protected against side-channel unless your key is invalid. + ## In that case it will like whether it's all zeros or larger than the curve order. + dst.raw.fromRawUint(src, bigEndian) + let status = validate_seckey(dst) + if status != cttBLS_Success: + dst.raw.setZero() + return status + return cttBLS_Success + +func deserialize_public_key_compressed_unchecked*(dst: var PublicKey, src: array[48, byte]): CttBLSStatus = + ## Deserialize a public_key in compressed (Zcash) format. + ## + ## Warning ⚠: + ## This procedure skips the very expensive subgroup checks. + ## Not checking subgroup exposes a protocol to small subgroup attacks. + ## + ## Returns cttBLS_Success if successful + + # src must have the compressed flag + if (src[0] and byte 0b10000000) == byte 0: + return cttBLS_InvalidEncoding + + # if infinity, src must be all zeros + if (src[0] and byte 0b01000000) != 0: + if (src[0] and byte 0b00111111) != 0: # Check all the remaining bytes in MSB + return cttBLS_InvalidEncoding + for i in 1 ..< src.len: + if src[i] != byte 0: + return cttBLS_InvalidEncoding + dst.raw.setInf() + return cttBLS_PointAtInfinity + + # General case + var t{.noInit.}: matchingBigInt(BLS12_381) + t.fromRawUint(src, bigEndian) + t.limbs[^1] = t.limbs[^1] and (MaxWord shr 3) # The first 3 bytes contain metadata to mask out + + if bool(t >= BLS12_381.Mod()): + return cttBLS_CoordinateGreaterOrEqualThanModulus + + var x{.noInit.}: Fp[BLS12_381] + x.fromBig(t) + + let onCurve = dst.raw.trySetFromCoordX(x) + if not(bool onCurve): + return cttBLS_PointNotOnCurve + + let isLexicographicallyLargest = dst.raw.y.toBig() >= Fp[BLS12_381].getPrimePlus1div2() + let srcIsLargest = SecretBool((src[0] shr 5) and byte 1) + dst.raw.y.cneg(isLexicographicallyLargest xor srcIsLargest) + +func deserialize_public_key_compressed*(dst: var PublicKey, src: array[48, byte]): CttBLSStatus = + ## Deserialize a public_key in compressed (Zcash) format + ## + ## Returns cttBLS_Success if successful + + result = deserialize_public_key_compressed_unchecked(dst, src) + if result != cttBLS_Success: + return result + + if not(bool dst.raw.isInSubgroup): + return cttBLS_PointNotInSubgroup + +func deserialize_signature_compressed_unchecked*(dst: var Signature, src: array[96, byte]): CttBLSStatus = + ## Deserialize a signature in compressed (Zcash) format. + ## + ## Warning ⚠: + ## This procedure skips the very expensive subgroup checks. + ## Not checking subgroup exposes a protocol to small subgroup attacks. + ## + ## Returns cttBLS_Success if successful + + # src must have the compressed flag + if (src[0] and byte 0b10000000) == byte 0: + return cttBLS_InvalidEncoding + + # if infinity, src must be all zeros + if (src[0] and byte 0b01000000) != 0: + if (src[0] and byte 0b00111111) != 0: # Check all the remaining bytes in MSB + return cttBLS_InvalidEncoding + for i in 1 ..< src.len: + if src[i] != byte 0: + return cttBLS_InvalidEncoding + dst.raw.setInf() + return cttBLS_PointAtInfinity + + # General case + var t{.noInit.}: matchingBigInt(BLS12_381) + t.fromRawUint(src.toOpenArray(0, 48-1), bigEndian) + t.limbs[^1] = t.limbs[^1] and (MaxWord shr 3) # The first 3 bytes contain metadata to mask out + + if bool(t >= BLS12_381.Mod()): + return cttBLS_CoordinateGreaterOrEqualThanModulus + + var x{.noInit.}: Fp2[BLS12_381] + x.c1.fromBig(t) + + t.fromRawUint(src.toOpenArray(48, 96-1), bigEndian) + if bool(t >= BLS12_381.Mod()): + return cttBLS_CoordinateGreaterOrEqualThanModulus + + x.c0.fromBig(t) + + let onCurve = dst.raw.trySetFromCoordX(x) + if not(bool onCurve): + return cttBLS_PointNotOnCurve + + let isLexicographicallyLargest = + if dst.raw.y.c1.isZero().bool(): + dst.raw.y.c0.toBig() >= Fp[BLS12_381].getPrimePlus1div2() + else: + dst.raw.y.c1.toBig() >= Fp[BLS12_381].getPrimePlus1div2() + + let srcIsLargest = SecretBool((src[0] shr 5) and byte 1) + dst.raw.y.cneg(isLexicographicallyLargest xor srcIsLargest) + +func deserialize_signature_compressed*(dst: var Signature, src: array[96, byte]): CttBLSStatus = + ## Deserialize a public_key in compressed (Zcash) format + ## + ## Returns cttBLS_Success if successful + + result = deserialize_signature_compressed_unchecked(dst, src) + if result != cttBLS_Success: + return result + + if not(bool dst.raw.isInSubgroup): + return cttBLS_PointNotInSubgroup + +# Signatures +# ------------------------------------------------------------------------------------------------ + +func derive_public_key*(public_key: var PublicKey, secret_key: SecretKey): CttBLSStatus = + ## Derive the public key matching with a secret key + ## + ## Secret protection: + ## - A valid secret key will only leak that it is valid. + ## - An invalid secret key will leak whether it's all zero or larger than the curve order. + let status = validate_seckey(secret_key) + if status != cttBLS_Success: + return status + + let ok = public_key.raw.derivePubkey(secret_key.raw) + if not ok: + # This is unreachable since validate_seckey would have caught those + return cttBLS_InvalidEncoding + return cttBLS_Success + +func sign*[T: byte|char](signature: var Signature, secret_key: SecretKey, message: openArray[T]): CttBLSStatus = + ## Produce a signature for the message under the specified secret key + ## Signature is on BLS12-381 G2 (and public key on G1) + ## + ## For message domain separation purpose, the tag is `BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_` + ## + ## Input: + ## - A secret key + ## - A message + ## + ## Output: + ## - `signature` is overwritten with `message` signed with `secretKey` + ## with the scheme + ## - A status code indicating success or if the secret key is invalid. + ## + ## Secret protection: + ## - A valid secret key will only leak that it is valid. + ## - An invalid secret key will leak whether it's all zero or larger than the curve order. + let status = validate_seckey(secret_key) + if status != cttBLS_Success: + signature.raw.setInf() + return status + + coreSign(signature.raw, secretKey.raw, message, sha256, 128, augmentation = "", DST) + return cttBLS_Success + +func verify*[T: byte|char](public_key: PublicKey, message: openarray[T], signature: Signature): CttBLSStatus = + ## Check that a signature is valid for a message + ## under the provided public key. + ## returns `true` if the signature is valid, `false` otherwise. + ## + ## For message domain separation purpose, the tag is `BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_` + ## + ## Input: + ## - A public key initialized by one of the key derivation or deserialization procedure. + ## Or validated via validate_pubkey + ## - A message + ## - A signature initialized by one of the key derivation or deserialization procedure. + ## Or validated via validate_pubkey + ## + ## In particular, the public key and signature are assumed to be on curve subgroup checked. + + # Deal with cases were pubkey or signature were mistakenly zero-init, due to a generic aggregation tentative for example + if bool(public_key.raw.isInf() or signature.raw.isInf()): + return cttBLS_PointAtInfinity + + let verified = coreVerify(public_key.raw, message, signature.raw, sha256, 128, augmentation = "", DST) + if verified: + return cttBLS_Success + return cttBLS_VerificationFailure \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/README.md b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/README.md new file mode 100644 index 0000000..ef9c6aa --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/README.md @@ -0,0 +1,4 @@ +# BLS signature on BLS12-381 G2 tests + +Source: https://github.com/ethereum/bls12-381-tests +version 0.1.1 at https://github.com/ethereum/bls12-381-tests/releases/tag/v0.1.1 \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_0x0000000000000000000000000000000000000000000000000000000000000000.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_0x0000000000000000000000000000000000000000000000000000000000000000.json new file mode 100644 index 0000000..34f0e23 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_0x0000000000000000000000000000000000000000000000000000000000000000.json @@ -0,0 +1 @@ +{"input": ["0xb6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380b55285a55", "0xb23c46be3a001c63ca711f87a005c200cc550b9429d5f4eb38d74322144f1b63926da3388979e5321012fb1a0526bcd100b5ef5fe72628ce4cd5e904aeaa3279527843fae5ca9ca675f4f51ed8f83bbf7155da9ecc9663100a885d5dc6df96d9", "0x948a7cb99f76d616c2c564ce9bf4a519f1bea6b0a624a02276443c245854219fabb8d4ce061d255af5330b078d5380681751aa7053da2c98bae898edc218c75f07e24d8802a17cd1f6833b71e58f5eb5b94208b4d0bb3848cecb075ea21be115"], "output": "0x9683b3e6701f9a4b706709577963110043af78a5b41991b998475a3d3fd62abf35ce03b33908418efc95a058494a8ae504354b9f626231f6b3f3c849dfdeaf5017c4780e2aee1850ceaf4b4d9ce70971a3d2cfcd97b7e5ecf6759f8da5f76d31"} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_0x5656565656565656565656565656565656565656565656565656565656565656.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_0x5656565656565656565656565656565656565656565656565656565656565656.json new file mode 100644 index 0000000..7197038 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_0x5656565656565656565656565656565656565656565656565656565656565656.json @@ -0,0 +1 @@ +{"input": ["0x882730e5d03f6b42c3abc26d3372625034e1d871b65a8a6b900a56dae22da98abbe1b68f85e49fe7652a55ec3d0591c20767677e33e5cbb1207315c41a9ac03be39c2e7668edc043d6cb1d9fd93033caa8a1c5b0e84bedaeb6c64972503a43eb", "0xaf1390c3c47acdb37131a51216da683c509fce0e954328a59f93aebda7e4ff974ba208d9a4a2a2389f892a9d418d618418dd7f7a6bc7aa0da999a9d3a5b815bc085e14fd001f6a1948768a3f4afefc8b8240dda329f984cb345c6363272ba4fe", "0xa4efa926610b8bd1c8330c918b7a5e9bf374e53435ef8b7ec186abf62e1b1f65aeaaeb365677ac1d1172a1f5b44b4e6d022c252c58486c0a759fbdc7de15a756acc4d343064035667a594b4c2a6f0b0b421975977f297dba63ee2f63ffe47bb6"], "output": "0xad38fc73846583b08d110d16ab1d026c6ea77ac2071e8ae832f56ac0cbcdeb9f5678ba5ce42bd8dce334cc47b5abcba40a58f7f1f80ab304193eb98836cc14d8183ec14cc77de0f80c4ffd49e168927a968b5cdaa4cf46b9805be84ad7efa77b"} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_0xabababababababababababababababababababababababababababababababab.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_0xabababababababababababababababababababababababababababababababab.json new file mode 100644 index 0000000..8b47fc8 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_0xabababababababababababababababababababababababababababababababab.json @@ -0,0 +1 @@ +{"input": ["0x91347bccf740d859038fcdcaf233eeceb2a436bcaaee9b2aa3bfb70efe29dfb2677562ccbea1c8e061fb9971b0753c240622fab78489ce96768259fc01360346da5b9f579e5da0d941e4c6ba18a0e64906082375394f337fa1af2b7127b0d121", "0x9674e2228034527f4c083206032b020310face156d4a4685e2fcaec2f6f3665aa635d90347b6ce124eb879266b1e801d185de36a0a289b85e9039662634f2eea1e02e670bc7ab849d006a70b2f93b84597558a05b879c8d445f387a5d5b653df", "0xae82747ddeefe4fd64cf9cedb9b04ae3e8a43420cd255e3c7cd06a8d88b7c7f8638543719981c5d16fa3527c468c25f0026704a6951bde891360c7e8d12ddee0559004ccdbe6046b55bae1b257ee97f7cdb955773d7cf29adf3ccbb9975e4eb9"], "output": "0x9712c3edd73a209c742b8250759db12549b3eaf43b5ca61376d9f30e2747dbcf842d8b2ac0901d2a093713e20284a7670fcf6954e9ab93de991bb9b313e664785a075fc285806fa5224c82bde146561b446ccfc706a64b8579513cfc4ff1d930"} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_infinity_signature.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_infinity_signature.json new file mode 100644 index 0000000..487ed63 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_infinity_signature.json @@ -0,0 +1 @@ +{"input": ["0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"], "output": "0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_na_signatures.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_na_signatures.json new file mode 100644 index 0000000..6dd2c24 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_na_signatures.json @@ -0,0 +1 @@ +{"input": [], "output": null} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_single_signature.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_single_signature.json new file mode 100644 index 0000000..d2b4f9c --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate/aggregate_single_signature.json @@ -0,0 +1 @@ +{"input": ["0xb6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380b55285a55"], "output": "0xb6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380b55285a55"} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate_verify/aggregate_verify_infinity_pubkey.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate_verify/aggregate_verify_infinity_pubkey.json new file mode 100644 index 0000000..89ff735 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate_verify/aggregate_verify_infinity_pubkey.json @@ -0,0 +1 @@ +{"input": {"pubkeys": ["0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f", "0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"], "messages": ["0x0000000000000000000000000000000000000000000000000000000000000000", "0x5656565656565656565656565656565656565656565656565656565656565656", "0xabababababababababababababababababababababababababababababababab", "0x1212121212121212121212121212121212121212121212121212121212121212"], "signature": "0x9104e74b9dfd3ad502f25d6a5ef57db0ed7d9a0e00f3500586d8ce44231212542fcfaf87840539b398bf07626705cf1105d246ca1062c6c2e1a53029a0f790ed5e3cb1f52f8234dc5144c45fc847c0cd37a92d68e7c5ba7c648a8a339f171244"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate_verify/aggregate_verify_na_pubkeys_and_infinity_signature.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate_verify/aggregate_verify_na_pubkeys_and_infinity_signature.json new file mode 100644 index 0000000..33d1e32 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate_verify/aggregate_verify_na_pubkeys_and_infinity_signature.json @@ -0,0 +1 @@ +{"input": {"pubkeys": [], "messages": [], "signature": "0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate_verify/aggregate_verify_na_pubkeys_and_na_signature.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate_verify/aggregate_verify_na_pubkeys_and_na_signature.json new file mode 100644 index 0000000..aa3db50 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate_verify/aggregate_verify_na_pubkeys_and_na_signature.json @@ -0,0 +1 @@ +{"input": {"pubkeys": [], "messages": [], "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate_verify/aggregate_verify_tampered_signature.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate_verify/aggregate_verify_tampered_signature.json new file mode 100644 index 0000000..274088a --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate_verify/aggregate_verify_tampered_signature.json @@ -0,0 +1 @@ +{"input": {"pubkeys": ["0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f"], "messages": ["0x0000000000000000000000000000000000000000000000000000000000000000", "0x5656565656565656565656565656565656565656565656565656565656565656", "0xabababababababababababababababababababababababababababababababab"], "signature": "0x9104e74bffffffff"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate_verify/aggregate_verify_valid.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate_verify/aggregate_verify_valid.json new file mode 100644 index 0000000..1592941 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/aggregate_verify/aggregate_verify_valid.json @@ -0,0 +1 @@ +{"input": {"pubkeys": ["0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f"], "messages": ["0x0000000000000000000000000000000000000000000000000000000000000000", "0x5656565656565656565656565656565656565656565656565656565656565656", "0xabababababababababababababababababababababababababababababababab"], "signature": "0x9104e74b9dfd3ad502f25d6a5ef57db0ed7d9a0e00f3500586d8ce44231212542fcfaf87840539b398bf07626705cf1105d246ca1062c6c2e1a53029a0f790ed5e3cb1f52f8234dc5144c45fc847c0cd37a92d68e7c5ba7c648a8a339f171244"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/batch_verify/batch_verify_invalid_forged_signature_set.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/batch_verify/batch_verify_invalid_forged_signature_set.json new file mode 100644 index 0000000..567a4ac --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/batch_verify/batch_verify_invalid_forged_signature_set.json @@ -0,0 +1 @@ +{"input": {"pubkeys": ["0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81"], "messages": ["0x0000000000000000000000000000000000000000000000000000000000000000", "0x5656565656565656565656565656565656565656565656565656565656565656"], "signatures": ["0xa70f1f1b4bd97d182ebb55d08be3f90b1dc232bb50b44e259381a642ef0bad3629ad3542f3e8ff6a84e451fc0b595e090fc4f0e860cfc5584715ef1b6cd717b9994378f7a51b815bbf5a0d95bc3402583ad2e95a229731e539906249a5e4355c", "0xb758eb7e15c101f53be2214d2a6b65e8fe7053146dbe3c73c9fe9b5efecdf63ca06a4d5d938dbf18fe6600529c0011a7013f45ae012b02904d5c7c33316e935a0e084abead4f43f84383c52cd3b3f14024437e251a2a7c0d5147954022873a58"]}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/batch_verify/batch_verify_valid_simple_signature_set.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/batch_verify/batch_verify_valid_simple_signature_set.json new file mode 100644 index 0000000..e963845 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/batch_verify/batch_verify_valid_simple_signature_set.json @@ -0,0 +1 @@ +{"input": {"pubkeys": ["0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f"], "messages": ["0x0000000000000000000000000000000000000000000000000000000000000000", "0x5656565656565656565656565656565656565656565656565656565656565656", "0xabababababababababababababababababababababababababababababababab"], "signatures": ["0xb6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380b55285a55", "0xaf1390c3c47acdb37131a51216da683c509fce0e954328a59f93aebda7e4ff974ba208d9a4a2a2389f892a9d418d618418dd7f7a6bc7aa0da999a9d3a5b815bc085e14fd001f6a1948768a3f4afefc8b8240dda329f984cb345c6363272ba4fe", "0xae82747ddeefe4fd64cf9cedb9b04ae3e8a43420cd255e3c7cd06a8d88b7c7f8638543719981c5d16fa3527c468c25f0026704a6951bde891360c7e8d12ddee0559004ccdbe6046b55bae1b257ee97f7cdb955773d7cf29adf3ccbb9975e4eb9"]}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_infinity_with_false_b_flag.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_infinity_with_false_b_flag.json new file mode 100644 index 0000000..e20b8a0 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_infinity_with_false_b_flag.json @@ -0,0 +1 @@ +{"input": {"pubkey": "800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_infinity_with_true_b_flag.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_infinity_with_true_b_flag.json new file mode 100644 index 0000000..6785356 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_infinity_with_true_b_flag.json @@ -0,0 +1 @@ +{"input": {"pubkey": "c01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_not_in_G1.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_not_in_G1.json new file mode 100644 index 0000000..3e427f7 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_not_in_G1.json @@ -0,0 +1 @@ +{"input": {"pubkey": "8123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_not_in_curve.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_not_in_curve.json new file mode 100644 index 0000000..519f1b0 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_not_in_curve.json @@ -0,0 +1 @@ +{"input": {"pubkey": "8123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde0"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_too_few_bytes.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_too_few_bytes.json new file mode 100644 index 0000000..6bc3df8 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_too_few_bytes.json @@ -0,0 +1 @@ +{"input": {"pubkey": "9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaa"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_too_many_bytes.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_too_many_bytes.json new file mode 100644 index 0000000..bef7441 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_too_many_bytes.json @@ -0,0 +1 @@ +{"input": {"pubkey": "9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaa900"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_with_b_flag_and_a_flag_true.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_with_b_flag_and_a_flag_true.json new file mode 100644 index 0000000..4a10d0f --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_with_b_flag_and_a_flag_true.json @@ -0,0 +1 @@ +{"input": {"pubkey": "e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_with_b_flag_and_x_nonzero.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_with_b_flag_and_x_nonzero.json new file mode 100644 index 0000000..f7679c6 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_with_b_flag_and_x_nonzero.json @@ -0,0 +1 @@ +{"input": {"pubkey": "c123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_with_wrong_c_flag.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_with_wrong_c_flag.json new file mode 100644 index 0000000..54b6ef9 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_with_wrong_c_flag.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_x_equal_to_modulus.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_x_equal_to_modulus.json new file mode 100644 index 0000000..6129f60 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_x_equal_to_modulus.json @@ -0,0 +1 @@ +{"input": {"pubkey": "9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_x_greater_than_modulus.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_x_greater_than_modulus.json new file mode 100644 index 0000000..d6e83b6 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_fails_x_greater_than_modulus.json @@ -0,0 +1 @@ +{"input": {"pubkey": "9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_succeeds_correct_point.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_succeeds_correct_point.json new file mode 100644 index 0000000..f71aa2e --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_succeeds_correct_point.json @@ -0,0 +1 @@ +{"input": {"pubkey": "a491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_succeeds_infinity_with_true_b_flag.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_succeeds_infinity_with_true_b_flag.json new file mode 100644 index 0000000..d3f5043 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G1/deserialization_succeeds_infinity_with_true_b_flag.json @@ -0,0 +1 @@ +{"input": {"pubkey": "c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_infinity_with_false_b_flag.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_infinity_with_false_b_flag.json new file mode 100644 index 0000000..1e35bbd --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_infinity_with_false_b_flag.json @@ -0,0 +1 @@ +{"input": {"signature": "800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_infinity_with_true_b_flag.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_infinity_with_true_b_flag.json new file mode 100644 index 0000000..9e721a1 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_infinity_with_true_b_flag.json @@ -0,0 +1 @@ +{"input": {"signature": "c01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_not_in_G2.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_not_in_G2.json new file mode 100644 index 0000000..025e3bf --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_not_in_G2.json @@ -0,0 +1 @@ +{"input": {"signature": "8123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_not_in_curve.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_not_in_curve.json new file mode 100644 index 0000000..964bae6 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_not_in_curve.json @@ -0,0 +1 @@ +{"input": {"signature": "8123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcde0"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_too_few_bytes.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_too_few_bytes.json new file mode 100644 index 0000000..f7e753c --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_too_few_bytes.json @@ -0,0 +1 @@ +{"input": {"signature": "8123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_too_many_bytes.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_too_many_bytes.json new file mode 100644 index 0000000..03b981f --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_too_many_bytes.json @@ -0,0 +1 @@ +{"input": {"signature": "8123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdefff"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_with_b_flag_and_a_flag_true.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_with_b_flag_and_a_flag_true.json new file mode 100644 index 0000000..7b6b2ab --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_with_b_flag_and_a_flag_true.json @@ -0,0 +1 @@ +{"input": {"signature": "e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_with_b_flag_and_x_nonzero.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_with_b_flag_and_x_nonzero.json new file mode 100644 index 0000000..471f048 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_with_b_flag_and_x_nonzero.json @@ -0,0 +1 @@ +{"input": {"signature": "c123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_with_wrong_c_flag.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_with_wrong_c_flag.json new file mode 100644 index 0000000..789952f --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_with_wrong_c_flag.json @@ -0,0 +1 @@ +{"input": {"signature": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_xim_equal_to_modulus.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_xim_equal_to_modulus.json new file mode 100644 index 0000000..567ce63 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_xim_equal_to_modulus.json @@ -0,0 +1 @@ +{"input": {"signature": "9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_xim_greater_than_modulus.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_xim_greater_than_modulus.json new file mode 100644 index 0000000..af28ceb --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_xim_greater_than_modulus.json @@ -0,0 +1 @@ +{"input": {"signature": "9a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_xre_equal_to_modulus.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_xre_equal_to_modulus.json new file mode 100644 index 0000000..3d9b2f7 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_xre_equal_to_modulus.json @@ -0,0 +1 @@ +{"input": {"signature": "8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_xre_greater_than_modulus.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_xre_greater_than_modulus.json new file mode 100644 index 0000000..4cd7f00 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_fails_xre_greater_than_modulus.json @@ -0,0 +1 @@ +{"input": {"signature": "8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaac"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_succeeds_correct_point.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_succeeds_correct_point.json new file mode 100644 index 0000000..dd2d1f6 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_succeeds_correct_point.json @@ -0,0 +1 @@ +{"input": {"signature": "b2cc74bc9f089ed9764bbceac5edba416bef5e73701288977b9cac1ccb6964269d4ebf78b4e8aa7792ba09d3e49c8e6a1351bdf582971f796bbaf6320e81251c9d28f674d720cca07ed14596b96697cf18238e0e03ebd7fc1353d885a39407e0"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_succeeds_infinity_with_true_b_flag.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_succeeds_infinity_with_true_b_flag.json new file mode 100644 index 0000000..4cc2051 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/deserialization_G2/deserialization_succeeds_infinity_with_true_b_flag.json @@ -0,0 +1 @@ +{"input": {"signature": "c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_extra_pubkey_4f079f946446fabf.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_extra_pubkey_4f079f946446fabf.json new file mode 100644 index 0000000..d0753eb --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_extra_pubkey_4f079f946446fabf.json @@ -0,0 +1 @@ +{"input": {"pubkeys": ["0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f"], "message": "0x5656565656565656565656565656565656565656565656565656565656565656", "signature": "0x912c3615f69575407db9392eb21fee18fff797eeb2fbe1816366ca2a08ae574d8824dbfafb4c9eaa1cf61b63c6f9b69911f269b664c42947dd1b53ef1081926c1e82bb2a465f927124b08391a5249036146d6f3f1e17ff5f162f779746d830d1"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_extra_pubkey_5a38e6b4017fe4dd.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_extra_pubkey_5a38e6b4017fe4dd.json new file mode 100644 index 0000000..0e9b4d5 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_extra_pubkey_5a38e6b4017fe4dd.json @@ -0,0 +1 @@ +{"input": {"pubkeys": ["0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f", "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f"], "message": "0xabababababababababababababababababababababababababababababababab", "signature": "0x9712c3edd73a209c742b8250759db12549b3eaf43b5ca61376d9f30e2747dbcf842d8b2ac0901d2a093713e20284a7670fcf6954e9ab93de991bb9b313e664785a075fc285806fa5224c82bde146561b446ccfc706a64b8579513cfc4ff1d930"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_extra_pubkey_a698ea45b109f303.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_extra_pubkey_a698ea45b109f303.json new file mode 100644 index 0000000..ede4023 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_extra_pubkey_a698ea45b109f303.json @@ -0,0 +1 @@ +{"input": {"pubkeys": ["0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f"], "message": "0x0000000000000000000000000000000000000000000000000000000000000000", "signature": "0xb6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380b55285a55"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_infinity_pubkey.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_infinity_pubkey.json new file mode 100644 index 0000000..59b9cab --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_infinity_pubkey.json @@ -0,0 +1 @@ +{"input": {"pubkeys": ["0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f", "0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"], "message": "0x1212121212121212121212121212121212121212121212121212121212121212", "signature": "0xafcb4d980f079265caa61aee3e26bf48bebc5dc3e7f2d7346834d76cbc812f636c937b6b44a9323d8bc4b1cdf71d6811035ddc2634017faab2845308f568f2b9a0356140727356eae9eded8b87fd8cb8024b440c57aee06076128bb32921f584"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_na_pubkeys_and_infinity_signature.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_na_pubkeys_and_infinity_signature.json new file mode 100644 index 0000000..44a68dd --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_na_pubkeys_and_infinity_signature.json @@ -0,0 +1 @@ +{"input": {"pubkeys": [], "message": "0xabababababababababababababababababababababababababababababababab", "signature": "0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_na_pubkeys_and_na_signature.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_na_pubkeys_and_na_signature.json new file mode 100644 index 0000000..39af907 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_na_pubkeys_and_na_signature.json @@ -0,0 +1 @@ +{"input": {"pubkeys": [], "message": "0xabababababababababababababababababababababababababababababababab", "signature": "0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_tampered_signature_3d7576f3c0e3570a.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_tampered_signature_3d7576f3c0e3570a.json new file mode 100644 index 0000000..18a5fe1 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_tampered_signature_3d7576f3c0e3570a.json @@ -0,0 +1 @@ +{"input": {"pubkeys": ["0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f"], "message": "0xabababababababababababababababababababababababababababababababab", "signature": "0x9712c3edd73a209c742b8250759db12549b3eaf43b5ca61376d9f30e2747dbcf842d8b2ac0901d2a093713e20284a7670fcf6954e9ab93de991bb9b313e664785a075fc285806fa5224c82bde146561b446ccfc706a64b8579513cfcffffffff"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_tampered_signature_5e745ad0c6199a6c.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_tampered_signature_5e745ad0c6199a6c.json new file mode 100644 index 0000000..02594cf --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_tampered_signature_5e745ad0c6199a6c.json @@ -0,0 +1 @@ +{"input": {"pubkeys": ["0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a"], "message": "0x0000000000000000000000000000000000000000000000000000000000000000", "signature": "0xb6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380bffffffff"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_tampered_signature_652ce62f09290811.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_tampered_signature_652ce62f09290811.json new file mode 100644 index 0000000..d4b26bc --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_tampered_signature_652ce62f09290811.json @@ -0,0 +1 @@ +{"input": {"pubkeys": ["0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81"], "message": "0x5656565656565656565656565656565656565656565656565656565656565656", "signature": "0x912c3615f69575407db9392eb21fee18fff797eeb2fbe1816366ca2a08ae574d8824dbfafb4c9eaa1cf61b63c6f9b69911f269b664c42947dd1b53ef1081926c1e82bb2a465f927124b08391a5249036146d6f3f1e17ff5f162f7797ffffffff"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_valid_3d7576f3c0e3570a.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_valid_3d7576f3c0e3570a.json new file mode 100644 index 0000000..2470cb2 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_valid_3d7576f3c0e3570a.json @@ -0,0 +1 @@ +{"input": {"pubkeys": ["0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f"], "message": "0xabababababababababababababababababababababababababababababababab", "signature": "0x9712c3edd73a209c742b8250759db12549b3eaf43b5ca61376d9f30e2747dbcf842d8b2ac0901d2a093713e20284a7670fcf6954e9ab93de991bb9b313e664785a075fc285806fa5224c82bde146561b446ccfc706a64b8579513cfc4ff1d930"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_valid_5e745ad0c6199a6c.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_valid_5e745ad0c6199a6c.json new file mode 100644 index 0000000..8ba6535 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_valid_5e745ad0c6199a6c.json @@ -0,0 +1 @@ +{"input": {"pubkeys": ["0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a"], "message": "0x0000000000000000000000000000000000000000000000000000000000000000", "signature": "0xb6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380b55285a55"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_valid_652ce62f09290811.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_valid_652ce62f09290811.json new file mode 100644 index 0000000..25b0fdf --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/fast_aggregate_verify/fast_aggregate_verify_valid_652ce62f09290811.json @@ -0,0 +1 @@ +{"input": {"pubkeys": ["0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81"], "message": "0x5656565656565656565656565656565656565656565656565656565656565656", "signature": "0x912c3615f69575407db9392eb21fee18fff797eeb2fbe1816366ca2a08ae574d8824dbfafb4c9eaa1cf61b63c6f9b69911f269b664c42947dd1b53ef1081926c1e82bb2a465f927124b08391a5249036146d6f3f1e17ff5f162f779746d830d1"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/hash_to_G2/hash_to_G2__2782afaa8406d038.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/hash_to_G2/hash_to_G2__2782afaa8406d038.json new file mode 100644 index 0000000..9b17202 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/hash_to_G2/hash_to_G2__2782afaa8406d038.json @@ -0,0 +1 @@ +{"input": {"msg": "a512_aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"}, "output": {"x": "0x01a6ba2f9a11fa5598b2d8ace0fbe0a0eacb65deceb476fbbcb64fd24557c2f4b18ecfc5663e54ae16a84f5ab7f62534,0x11fca2ff525572795a801eed17eb12785887c7b63fb77a42be46ce4a34131d71f7a73e95fee3f812aea3de78b4d01569", "y": "0x0b6798718c8aed24bc19cb27f866f1c9effcdbf92397ad6448b5c9db90d2b9da6cbabf48adc1adf59a1a28344e79d57e,0x03a47f8e6d1763ba0cad63d6114c0accbef65707825a511b251a660a9b3994249ae4e63fac38b23da0c398689ee2ab52"}} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/hash_to_G2/hash_to_G2__7590bd067999bbfb.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/hash_to_G2/hash_to_G2__7590bd067999bbfb.json new file mode 100644 index 0000000..dffb205 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/hash_to_G2/hash_to_G2__7590bd067999bbfb.json @@ -0,0 +1 @@ +{"input": {"msg": "abc"}, "output": {"x": "0x02c2d18e033b960562aae3cab37a27ce00d80ccd5ba4b7fe0e7a210245129dbec7780ccc7954725f4168aff2787776e6,0x139cddbccdc5e91b9623efd38c49f81a6f83f175e80b06fc374de9eb4b41dfe4ca3a230ed250fbe3a2acf73a41177fd8", "y": "0x1787327b68159716a37440985269cf584bcb1e621d3a7202be6ea05c4cfe244aeb197642555a0645fb87bf7466b2ba48,0x00aa65dae3c8d732d10ecd2c50f8a1baf3001578f71c694e03866e9f3d49ac1e1ce70dd94a733534f106d4cec0eddd16"}} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/hash_to_G2/hash_to_G2__a54942c8e365f378.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/hash_to_G2/hash_to_G2__a54942c8e365f378.json new file mode 100644 index 0000000..a471f86 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/hash_to_G2/hash_to_G2__a54942c8e365f378.json @@ -0,0 +1 @@ +{"input": {"msg": ""}, "output": {"x": "0x0141ebfbdca40eb85b87142e130ab689c673cf60f1a3e98d69335266f30d9b8d4ac44c1038e9dcdd5393faf5c41fb78a,0x05cb8437535e20ecffaef7752baddf98034139c38452458baeefab379ba13dff5bf5dd71b72418717047f5b0f37da03d", "y": "0x0503921d7f6a12805e72940b963c0cf3471c7b2a524950ca195d11062ee75ec076daf2d4bc358c4b190c0c98064fdd92,0x12424ac32561493f3fe3c260708a12b7c620e7be00099a974e259ddc7d1f6395c3c811cdd19f1e8dbf3e9ecfdcbab8d6"}} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/hash_to_G2/hash_to_G2__c938b486cf69e8f7.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/hash_to_G2/hash_to_G2__c938b486cf69e8f7.json new file mode 100644 index 0000000..ebe84eb --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/hash_to_G2/hash_to_G2__c938b486cf69e8f7.json @@ -0,0 +1 @@ +{"input": {"msg": "abcdef0123456789"}, "output": {"x": "0x121982811d2491fde9ba7ed31ef9ca474f0e1501297f68c298e9f4c0028add35aea8bb83d53c08cfc007c1e005723cd0,0x190d119345b94fbd15497bcba94ecf7db2cbfd1e1fe7da034d26cbba169fb3968288b3fafb265f9ebd380512a71c3f2c", "y": "0x05571a0f8d3c08d094576981f4a3b8eda0a8e771fcdcc8ecceaf1356a6acf17574518acb506e435b639353c2e14827c8,0x0bb5e7572275c567462d91807de765611490205a941a5a6af3b1691bfe596c31225d3aabdf15faff860cb4ef17c7c3be"}} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_11b8c7cad5238946.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_11b8c7cad5238946.json new file mode 100644 index 0000000..00b558b --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_11b8c7cad5238946.json @@ -0,0 +1 @@ +{"input": {"privkey": "0x47b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff665138", "message": "0x0000000000000000000000000000000000000000000000000000000000000000"}, "output": "0xb23c46be3a001c63ca711f87a005c200cc550b9429d5f4eb38d74322144f1b63926da3388979e5321012fb1a0526bcd100b5ef5fe72628ce4cd5e904aeaa3279527843fae5ca9ca675f4f51ed8f83bbf7155da9ecc9663100a885d5dc6df96d9"} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_142f678a8d05fcd1.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_142f678a8d05fcd1.json new file mode 100644 index 0000000..29b1c46 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_142f678a8d05fcd1.json @@ -0,0 +1 @@ +{"input": {"privkey": "0x47b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff665138", "message": "0x5656565656565656565656565656565656565656565656565656565656565656"}, "output": "0xaf1390c3c47acdb37131a51216da683c509fce0e954328a59f93aebda7e4ff974ba208d9a4a2a2389f892a9d418d618418dd7f7a6bc7aa0da999a9d3a5b815bc085e14fd001f6a1948768a3f4afefc8b8240dda329f984cb345c6363272ba4fe"} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_37286e1a6d1f6eb3.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_37286e1a6d1f6eb3.json new file mode 100644 index 0000000..a62d5cf --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_37286e1a6d1f6eb3.json @@ -0,0 +1 @@ +{"input": {"privkey": "0x47b8192d77bf871b62e87859d653922725724a5c031afeabc60bcef5ff665138", "message": "0xabababababababababababababababababababababababababababababababab"}, "output": "0x9674e2228034527f4c083206032b020310face156d4a4685e2fcaec2f6f3665aa635d90347b6ce124eb879266b1e801d185de36a0a289b85e9039662634f2eea1e02e670bc7ab849d006a70b2f93b84597558a05b879c8d445f387a5d5b653df"} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_7055381f640f2c1d.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_7055381f640f2c1d.json new file mode 100644 index 0000000..62d42df --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_7055381f640f2c1d.json @@ -0,0 +1 @@ +{"input": {"privkey": "0x328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d216", "message": "0x0000000000000000000000000000000000000000000000000000000000000000"}, "output": "0x948a7cb99f76d616c2c564ce9bf4a519f1bea6b0a624a02276443c245854219fabb8d4ce061d255af5330b078d5380681751aa7053da2c98bae898edc218c75f07e24d8802a17cd1f6833b71e58f5eb5b94208b4d0bb3848cecb075ea21be115"} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_84d45c9c7cca6b92.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_84d45c9c7cca6b92.json new file mode 100644 index 0000000..3254f7f --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_84d45c9c7cca6b92.json @@ -0,0 +1 @@ +{"input": {"privkey": "0x328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d216", "message": "0xabababababababababababababababababababababababababababababababab"}, "output": "0xae82747ddeefe4fd64cf9cedb9b04ae3e8a43420cd255e3c7cd06a8d88b7c7f8638543719981c5d16fa3527c468c25f0026704a6951bde891360c7e8d12ddee0559004ccdbe6046b55bae1b257ee97f7cdb955773d7cf29adf3ccbb9975e4eb9"} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_8cd3d4d0d9a5b265.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_8cd3d4d0d9a5b265.json new file mode 100644 index 0000000..7ba74f0 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_8cd3d4d0d9a5b265.json @@ -0,0 +1 @@ +{"input": {"privkey": "0x328388aff0d4a5b7dc9205abd374e7e98f3cd9f3418edb4eafda5fb16473d216", "message": "0x5656565656565656565656565656565656565656565656565656565656565656"}, "output": "0xa4efa926610b8bd1c8330c918b7a5e9bf374e53435ef8b7ec186abf62e1b1f65aeaaeb365677ac1d1172a1f5b44b4e6d022c252c58486c0a759fbdc7de15a756acc4d343064035667a594b4c2a6f0b0b421975977f297dba63ee2f63ffe47bb6"} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_c82df61aa3ee60fb.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_c82df61aa3ee60fb.json new file mode 100644 index 0000000..bc95a91 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_c82df61aa3ee60fb.json @@ -0,0 +1 @@ +{"input": {"privkey": "0x263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e3", "message": "0x0000000000000000000000000000000000000000000000000000000000000000"}, "output": "0xb6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380b55285a55"} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_d0e28d7e76eb6e9c.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_d0e28d7e76eb6e9c.json new file mode 100644 index 0000000..d6d5683 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_d0e28d7e76eb6e9c.json @@ -0,0 +1 @@ +{"input": {"privkey": "0x263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e3", "message": "0x5656565656565656565656565656565656565656565656565656565656565656"}, "output": "0x882730e5d03f6b42c3abc26d3372625034e1d871b65a8a6b900a56dae22da98abbe1b68f85e49fe7652a55ec3d0591c20767677e33e5cbb1207315c41a9ac03be39c2e7668edc043d6cb1d9fd93033caa8a1c5b0e84bedaeb6c64972503a43eb"} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_f2ae1097e7d0e18b.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_f2ae1097e7d0e18b.json new file mode 100644 index 0000000..7def669 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_f2ae1097e7d0e18b.json @@ -0,0 +1 @@ +{"input": {"privkey": "0x263dbd792f5b1be47ed85f8938c0f29586af0d3ac7b977f21c278fe1462040e3", "message": "0xabababababababababababababababababababababababababababababababab"}, "output": "0x91347bccf740d859038fcdcaf233eeceb2a436bcaaee9b2aa3bfb70efe29dfb2677562ccbea1c8e061fb9971b0753c240622fab78489ce96768259fc01360346da5b9f579e5da0d941e4c6ba18a0e64906082375394f337fa1af2b7127b0d121"} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_zero_privkey.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_zero_privkey.json new file mode 100644 index 0000000..755ed44 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/sign/sign_case_zero_privkey.json @@ -0,0 +1 @@ +{"input": {"privkey": "0x0000000000000000000000000000000000000000000000000000000000000000", "message": "0xabababababababababababababababababababababababababababababababab"}, "output": null} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_infinity_pubkey_and_infinity_signature.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_infinity_pubkey_and_infinity_signature.json new file mode 100644 index 0000000..32d43b5 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_infinity_pubkey_and_infinity_signature.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "message": "0x1212121212121212121212121212121212121212121212121212121212121212", "signature": "0xc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_195246ee3bd3b6ec.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_195246ee3bd3b6ec.json new file mode 100644 index 0000000..139d7bf --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_195246ee3bd3b6ec.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f", "message": "0xabababababababababababababababababababababababababababababababab", "signature": "0xae82747ddeefe4fd64cf9cedb9b04ae3e8a43420cd255e3c7cd06a8d88b7c7f8638543719981c5d16fa3527c468c25f0026704a6951bde891360c7e8d12ddee0559004ccdbe6046b55bae1b257ee97f7cdb955773d7cf29adf3ccbb9ffffffff"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_2ea479adf8c40300.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_2ea479adf8c40300.json new file mode 100644 index 0000000..8962d38 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_2ea479adf8c40300.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "message": "0x5656565656565656565656565656565656565656565656565656565656565656", "signature": "0x882730e5d03f6b42c3abc26d3372625034e1d871b65a8a6b900a56dae22da98abbe1b68f85e49fe7652a55ec3d0591c20767677e33e5cbb1207315c41a9ac03be39c2e7668edc043d6cb1d9fd93033caa8a1c5b0e84bedaeb6c64972ffffffff"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_2f09d443ab8a3ac2.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_2f09d443ab8a3ac2.json new file mode 100644 index 0000000..2e5ede0 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_2f09d443ab8a3ac2.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "message": "0x0000000000000000000000000000000000000000000000000000000000000000", "signature": "0xb23c46be3a001c63ca711f87a005c200cc550b9429d5f4eb38d74322144f1b63926da3388979e5321012fb1a0526bcd100b5ef5fe72628ce4cd5e904aeaa3279527843fae5ca9ca675f4f51ed8f83bbf7155da9ecc9663100a885d5dffffffff"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_3208262581c8fc09.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_3208262581c8fc09.json new file mode 100644 index 0000000..e482d88 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_3208262581c8fc09.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "message": "0x5656565656565656565656565656565656565656565656565656565656565656", "signature": "0xaf1390c3c47acdb37131a51216da683c509fce0e954328a59f93aebda7e4ff974ba208d9a4a2a2389f892a9d418d618418dd7f7a6bc7aa0da999a9d3a5b815bc085e14fd001f6a1948768a3f4afefc8b8240dda329f984cb345c6363ffffffff"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_6b3b17f6962a490c.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_6b3b17f6962a490c.json new file mode 100644 index 0000000..a95f074 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_6b3b17f6962a490c.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f", "message": "0x5656565656565656565656565656565656565656565656565656565656565656", "signature": "0xa4efa926610b8bd1c8330c918b7a5e9bf374e53435ef8b7ec186abf62e1b1f65aeaaeb365677ac1d1172a1f5b44b4e6d022c252c58486c0a759fbdc7de15a756acc4d343064035667a594b4c2a6f0b0b421975977f297dba63ee2f63ffffffff"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_6eeb7c52dfd9baf0.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_6eeb7c52dfd9baf0.json new file mode 100644 index 0000000..f3c232a --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_6eeb7c52dfd9baf0.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "message": "0xabababababababababababababababababababababababababababababababab", "signature": "0x9674e2228034527f4c083206032b020310face156d4a4685e2fcaec2f6f3665aa635d90347b6ce124eb879266b1e801d185de36a0a289b85e9039662634f2eea1e02e670bc7ab849d006a70b2f93b84597558a05b879c8d445f387a5ffffffff"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_8761a0b7e920c323.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_8761a0b7e920c323.json new file mode 100644 index 0000000..207b6d4 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_8761a0b7e920c323.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "message": "0xabababababababababababababababababababababababababababababababab", "signature": "0x91347bccf740d859038fcdcaf233eeceb2a436bcaaee9b2aa3bfb70efe29dfb2677562ccbea1c8e061fb9971b0753c240622fab78489ce96768259fc01360346da5b9f579e5da0d941e4c6ba18a0e64906082375394f337fa1af2b71ffffffff"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_d34885d766d5f705.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_d34885d766d5f705.json new file mode 100644 index 0000000..8ae27bd --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_d34885d766d5f705.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f", "message": "0x0000000000000000000000000000000000000000000000000000000000000000", "signature": "0x948a7cb99f76d616c2c564ce9bf4a519f1bea6b0a624a02276443c245854219fabb8d4ce061d255af5330b078d5380681751aa7053da2c98bae898edc218c75f07e24d8802a17cd1f6833b71e58f5eb5b94208b4d0bb3848cecb075effffffff"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_e8a50c445c855360.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_e8a50c445c855360.json new file mode 100644 index 0000000..eb326ef --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_tampered_signature_case_e8a50c445c855360.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "message": "0x0000000000000000000000000000000000000000000000000000000000000000", "signature": "0xb6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380bffffffff"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_195246ee3bd3b6ec.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_195246ee3bd3b6ec.json new file mode 100644 index 0000000..36515d8 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_195246ee3bd3b6ec.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f", "message": "0xabababababababababababababababababababababababababababababababab", "signature": "0xae82747ddeefe4fd64cf9cedb9b04ae3e8a43420cd255e3c7cd06a8d88b7c7f8638543719981c5d16fa3527c468c25f0026704a6951bde891360c7e8d12ddee0559004ccdbe6046b55bae1b257ee97f7cdb955773d7cf29adf3ccbb9975e4eb9"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_2ea479adf8c40300.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_2ea479adf8c40300.json new file mode 100644 index 0000000..a1a009f --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_2ea479adf8c40300.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "message": "0x5656565656565656565656565656565656565656565656565656565656565656", "signature": "0x882730e5d03f6b42c3abc26d3372625034e1d871b65a8a6b900a56dae22da98abbe1b68f85e49fe7652a55ec3d0591c20767677e33e5cbb1207315c41a9ac03be39c2e7668edc043d6cb1d9fd93033caa8a1c5b0e84bedaeb6c64972503a43eb"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_2f09d443ab8a3ac2.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_2f09d443ab8a3ac2.json new file mode 100644 index 0000000..e48e5cd --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_2f09d443ab8a3ac2.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "message": "0x0000000000000000000000000000000000000000000000000000000000000000", "signature": "0xb23c46be3a001c63ca711f87a005c200cc550b9429d5f4eb38d74322144f1b63926da3388979e5321012fb1a0526bcd100b5ef5fe72628ce4cd5e904aeaa3279527843fae5ca9ca675f4f51ed8f83bbf7155da9ecc9663100a885d5dc6df96d9"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_3208262581c8fc09.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_3208262581c8fc09.json new file mode 100644 index 0000000..202923a --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_3208262581c8fc09.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "message": "0x5656565656565656565656565656565656565656565656565656565656565656", "signature": "0xaf1390c3c47acdb37131a51216da683c509fce0e954328a59f93aebda7e4ff974ba208d9a4a2a2389f892a9d418d618418dd7f7a6bc7aa0da999a9d3a5b815bc085e14fd001f6a1948768a3f4afefc8b8240dda329f984cb345c6363272ba4fe"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_6b3b17f6962a490c.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_6b3b17f6962a490c.json new file mode 100644 index 0000000..f904137 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_6b3b17f6962a490c.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f", "message": "0x5656565656565656565656565656565656565656565656565656565656565656", "signature": "0xa4efa926610b8bd1c8330c918b7a5e9bf374e53435ef8b7ec186abf62e1b1f65aeaaeb365677ac1d1172a1f5b44b4e6d022c252c58486c0a759fbdc7de15a756acc4d343064035667a594b4c2a6f0b0b421975977f297dba63ee2f63ffe47bb6"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_6eeb7c52dfd9baf0.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_6eeb7c52dfd9baf0.json new file mode 100644 index 0000000..b94b289 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_6eeb7c52dfd9baf0.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "message": "0xabababababababababababababababababababababababababababababababab", "signature": "0x9674e2228034527f4c083206032b020310face156d4a4685e2fcaec2f6f3665aa635d90347b6ce124eb879266b1e801d185de36a0a289b85e9039662634f2eea1e02e670bc7ab849d006a70b2f93b84597558a05b879c8d445f387a5d5b653df"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_8761a0b7e920c323.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_8761a0b7e920c323.json new file mode 100644 index 0000000..66cdc7f --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_8761a0b7e920c323.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "message": "0xabababababababababababababababababababababababababababababababab", "signature": "0x91347bccf740d859038fcdcaf233eeceb2a436bcaaee9b2aa3bfb70efe29dfb2677562ccbea1c8e061fb9971b0753c240622fab78489ce96768259fc01360346da5b9f579e5da0d941e4c6ba18a0e64906082375394f337fa1af2b7127b0d121"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_d34885d766d5f705.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_d34885d766d5f705.json new file mode 100644 index 0000000..1ef2ea4 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_d34885d766d5f705.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f", "message": "0x0000000000000000000000000000000000000000000000000000000000000000", "signature": "0x948a7cb99f76d616c2c564ce9bf4a519f1bea6b0a624a02276443c245854219fabb8d4ce061d255af5330b078d5380681751aa7053da2c98bae898edc218c75f07e24d8802a17cd1f6833b71e58f5eb5b94208b4d0bb3848cecb075ea21be115"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_e8a50c445c855360.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_e8a50c445c855360.json new file mode 100644 index 0000000..d94718d --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_valid_case_e8a50c445c855360.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "message": "0x0000000000000000000000000000000000000000000000000000000000000000", "signature": "0xb6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380b55285a55"}, "output": true} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_195246ee3bd3b6ec.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_195246ee3bd3b6ec.json new file mode 100644 index 0000000..37c53ea --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_195246ee3bd3b6ec.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f", "message": "0xabababababababababababababababababababababababababababababababab", "signature": "0x9674e2228034527f4c083206032b020310face156d4a4685e2fcaec2f6f3665aa635d90347b6ce124eb879266b1e801d185de36a0a289b85e9039662634f2eea1e02e670bc7ab849d006a70b2f93b84597558a05b879c8d445f387a5d5b653df"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_2ea479adf8c40300.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_2ea479adf8c40300.json new file mode 100644 index 0000000..a8da83a --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_2ea479adf8c40300.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "message": "0x5656565656565656565656565656565656565656565656565656565656565656", "signature": "0xa4efa926610b8bd1c8330c918b7a5e9bf374e53435ef8b7ec186abf62e1b1f65aeaaeb365677ac1d1172a1f5b44b4e6d022c252c58486c0a759fbdc7de15a756acc4d343064035667a594b4c2a6f0b0b421975977f297dba63ee2f63ffe47bb6"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_2f09d443ab8a3ac2.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_2f09d443ab8a3ac2.json new file mode 100644 index 0000000..11e7e89 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_2f09d443ab8a3ac2.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "message": "0x0000000000000000000000000000000000000000000000000000000000000000", "signature": "0xb6ed936746e01f8ecf281f020953fbf1f01debd5657c4a383940b020b26507f6076334f91e2366c96e9ab279fb5158090352ea1c5b0c9274504f4f0e7053af24802e51e4568d164fe986834f41e55c8e850ce1f98458c0cfc9ab380b55285a55"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_3208262581c8fc09.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_3208262581c8fc09.json new file mode 100644 index 0000000..c730774 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_3208262581c8fc09.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "message": "0x5656565656565656565656565656565656565656565656565656565656565656", "signature": "0x882730e5d03f6b42c3abc26d3372625034e1d871b65a8a6b900a56dae22da98abbe1b68f85e49fe7652a55ec3d0591c20767677e33e5cbb1207315c41a9ac03be39c2e7668edc043d6cb1d9fd93033caa8a1c5b0e84bedaeb6c64972503a43eb"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_6b3b17f6962a490c.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_6b3b17f6962a490c.json new file mode 100644 index 0000000..205a89f --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_6b3b17f6962a490c.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f", "message": "0x5656565656565656565656565656565656565656565656565656565656565656", "signature": "0xaf1390c3c47acdb37131a51216da683c509fce0e954328a59f93aebda7e4ff974ba208d9a4a2a2389f892a9d418d618418dd7f7a6bc7aa0da999a9d3a5b815bc085e14fd001f6a1948768a3f4afefc8b8240dda329f984cb345c6363272ba4fe"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_6eeb7c52dfd9baf0.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_6eeb7c52dfd9baf0.json new file mode 100644 index 0000000..a6b207c --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_6eeb7c52dfd9baf0.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb301803f8b5ac4a1133581fc676dfedc60d891dd5fa99028805e5ea5b08d3491af75d0707adab3b70c6a6a580217bf81", "message": "0xabababababababababababababababababababababababababababababababab", "signature": "0x91347bccf740d859038fcdcaf233eeceb2a436bcaaee9b2aa3bfb70efe29dfb2677562ccbea1c8e061fb9971b0753c240622fab78489ce96768259fc01360346da5b9f579e5da0d941e4c6ba18a0e64906082375394f337fa1af2b7127b0d121"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_8761a0b7e920c323.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_8761a0b7e920c323.json new file mode 100644 index 0000000..7ed9778 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_8761a0b7e920c323.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "message": "0xabababababababababababababababababababababababababababababababab", "signature": "0xae82747ddeefe4fd64cf9cedb9b04ae3e8a43420cd255e3c7cd06a8d88b7c7f8638543719981c5d16fa3527c468c25f0026704a6951bde891360c7e8d12ddee0559004ccdbe6046b55bae1b257ee97f7cdb955773d7cf29adf3ccbb9975e4eb9"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_d34885d766d5f705.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_d34885d766d5f705.json new file mode 100644 index 0000000..a9c10e0 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_d34885d766d5f705.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xb53d21a4cfd562c469cc81514d4ce5a6b577d8403d32a394dc265dd190b47fa9f829fdd7963afdf972e5e77854051f6f", "message": "0x0000000000000000000000000000000000000000000000000000000000000000", "signature": "0xb23c46be3a001c63ca711f87a005c200cc550b9429d5f4eb38d74322144f1b63926da3388979e5321012fb1a0526bcd100b5ef5fe72628ce4cd5e904aeaa3279527843fae5ca9ca675f4f51ed8f83bbf7155da9ecc9663100a885d5dc6df96d9"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_e8a50c445c855360.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_e8a50c445c855360.json new file mode 100644 index 0000000..bf24f57 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verify_wrong_pubkey_case_e8a50c445c855360.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0xa491d1b0ecd9bb917989f0e74f0dea0422eac4a873e5e2644f368dffb9a6e20fd6e10c1b77654d067c0618f6e5a7f79a", "message": "0x0000000000000000000000000000000000000000000000000000000000000000", "signature": "0x948a7cb99f76d616c2c564ce9bf4a519f1bea6b0a624a02276443c245854219fabb8d4ce061d255af5330b078d5380681751aa7053da2c98bae898edc218c75f07e24d8802a17cd1f6833b71e58f5eb5b94208b4d0bb3848cecb075ea21be115"}, "output": false} \ No newline at end of file diff --git a/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verifycase_one_privkey_47117849458281be.json b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verifycase_one_privkey_47117849458281be.json new file mode 100644 index 0000000..11c9373 --- /dev/null +++ b/tests/blssig_pop_on_bls12381_g2_test_vectors_v0.1.1/verify/verifycase_one_privkey_47117849458281be.json @@ -0,0 +1 @@ +{"input": {"pubkey": "0x97f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb", "message": "0x1212121212121212121212121212121212121212121212121212121212121212", "signature": "0xa42ae16f1c2a5fa69c04cb5998d2add790764ce8dd45bf25b29b4700829232052b52352dcff1cf255b3a7810ad7269601810f03b2bc8b68cf289cf295b206770605a190b6842583e47c3d1c0f73c54907bfb2a602157d46a4353a20283018763"}, "output": true} \ No newline at end of file diff --git a/tests/t_blssig_pop_on_bls12381_g2.nim b/tests/t_blssig_pop_on_bls12381_g2.nim new file mode 100644 index 0000000..4bd9d8f --- /dev/null +++ b/tests/t_blssig_pop_on_bls12381_g2.nim @@ -0,0 +1,213 @@ +# Constantine +# Copyright (c) 2018-2019 Status Research & Development GmbH +# Copyright (c) 2020-Present Mamy André-Ratsimbazafy +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + +import + std/[json, os, unittest, strutils], + pkg/[jsony, stew/byteutils], + ../constantine/blssig_pop_on_bls12381_g2, + ../constantine/backend/io/io_bigints + +type + PubkeyField = object + pubkey: array[48, byte] + SignatureField =object + signature: array[96, byte] + DeserG1_test = object + input: PubkeyField + output: bool + DeserG2_test = object + input: SignatureField + output: bool + + InputSign = object + privkey: array[32, byte] + message: array[32, byte] + + Sign_test = object + input: InputSign + output: array[96, byte] + + InputVerify = object + pubkey: array[48, byte] + message: array[32, byte] + signature: array[96, byte] + + Verify_test = object + input: InputVerify + output: bool + +proc parseHook*[N: static int](src: string, pos: var int, value: var array[N, byte]) = + var str: string + parseHook(src, pos, str) + str.hexToPaddedByteArray(value, bigEndian) + +const SkippedTests = [ + # By construction, input MUST be 48 bytes, which is enforced at the type-system level. + "deserialization_fails_too_many_bytes.json" +] + +const TestDir = currentSourcePath.rsplit(DirSep, 1)[0] / "blssig_pop_on_bls12381_g2_test_vectors_v0.1.1" + +iterator walkTests*(category: string, skipped: var int): (string, string) = + let testDir = TestDir/category + + for file in walkDirRec(testDir, relative = true): + if file in SkippedTests: + echo "[WARNING] Skipping - ", file + inc skipped + continue + + yield (testDir, file) + +template testGen*(name, testData, TestType, body: untyped): untyped = + ## Generates a test proc + ## with identifier "test_name" + ## The test vector data is available as JsonNode under the + ## the variable passed as `testData` + proc `test _ name`() = + var count = 0 # Need to fail if walkDir doesn't return anything + var skipped = 0 + for dir, file in walkTests(astToStr(name), skipped): + stdout.write(" " & astToStr(name) & " test: " & alignLeft(file, 60)) + let testFile = readFile(dir/file) + let testData = testFile.fromJson(TestType) + + body + + stdout.write "[" & $status & "]\n" + inc count + + doAssert count > 0, "Empty or inexisting test folder: " & astToStr(name) + if skipped > 0: + echo "[Warning]: ", skipped, " tests skipped." + +testGen(deserialization_G1, testVector, DeserG1_test): + var pubkey{.noInit.}: PublicKey + + let status = pubkey.deserialize_public_key_compressed(testVector.input.pubkey) + let success = status == cttBLS_Success or status == cttBLS_PointAtInfinity + + doAssert success == testVector.output, block: + "\nDeserialization differs from expected \n" & + " deserializable? " & $success & " (" & $status & ")\n" & + " expected: " & $testVector.output + + if success: # Roundtrip + var s{.noInit.}: array[48, byte] + + let status2 = s.serialize_public_key_compressed(pubkey) + doAssert status2 == cttBLS_Success + doAssert s == testVector.input.pubkey, block: + "\nSerialization roundtrip differs from expected \n" & + " serialized: 0x" & $s.toHex() & " (" & $status2 & ")\n" & + " expected: 0x" & $testVector.input.pubkey.toHex() + +testGen(deserialization_G2, testVector, DeserG2_test): + var sig{.noInit.}: Signature + + let status = sig.deserialize_signature_compressed(testVector.input.signature) + let success = status == cttBLS_Success or status == cttBLS_PointAtInfinity + + doAssert success == testVector.output, block: + "\nDeserialization differs from expected \n" & + " deserializable? " & $success & " (" & $status & ")\n" & + " expected: " & $testVector.output + + if success: # Roundtrip + var s{.noInit.}: array[96, byte] + + let status2 = s.serialize_signature_compressed(sig) + doAssert status2 == cttBLS_Success + doAssert s == testVector.input.signature, block: + "\nSerialization roundtrip differs from expected \n" & + " serialized: 0x" & $s.toHex() & " (" & $status2 & ")\n" & + " expected: 0x" & $testVector.input.signature.toHex() + +testGen(sign, testVector, Sign_test): + var seckey{.noInit.}: SecretKey + var sig{.noInit.}: Signature + + let status = seckey.deserialize_secret_key(testVector.input.privkey) + if status != cttBLS_Success: + doAssert testVector.output == default(array[96, byte]) + let status2 = sig.sign(seckey, testVector.input.message) + doAssert status2 != cttBLS_Success + else: + let status2 = sig.sign(seckey, testVector.input.message) + doAssert status2 == cttBLS_Success + + block: # deserialize the output for extra codec testing + var output{.noInit.}: Signature + let status3 = output.deserialize_signature_compressed(testVector.output) + doAssert status3 == cttBLS_Success + doAssert sig == output, block: + var sig_bytes{.noInit.}: array[96, byte] + var roundtrip{.noInit.}: array[96, byte] + let sb_status = sig_bytes.serialize_signature_compressed(sig) + let rt_status = roundtrip.serialize_signature_compressed(output) + + "\nResult signature differs from expected \n" & + " computed: 0x" & $sig_bytes.toHex() & " (" & $sb_status & ")\n" & + " roundtrip: 0x" & $roundtrip.toHex() & " (" & $rt_status & ")\n" & + " expected: 0x" & $testVector.output.toHex() + + block: # serialize the result for extra codec testing + var sig_bytes{.noInit.}: array[96, byte] + let status3 = sig_bytes.serialize_signature_compressed(sig) + doAssert status3 == cttBLS_Success + doAssert sig_bytes == testVector.output, block: + "\nResult signature differs from expected \n" & + " computed: 0x" & $sig_bytes.toHex() & " (" & $status3 & ")\n" & + " expected: 0x" & $testVector.output.toHex() + +testGen(verify, testVector, Verify_test): + var + pubkey{.noInit.}: PublicKey + signature{.noInit.}: Signature + status = cttBLS_Success + + block testChecks: + status = pubkey.deserialize_public_key_compressed(testVector.input.pubkey) + if status notin {cttBLS_Success, cttBLS_PointAtInfinity}: + # For point at infinity, we want to make sure that "verify" itself handles them. + break testChecks + status = signature.deserialize_signature_compressed(testVector.input.signature) + if status notin {cttBLS_Success, cttBLS_PointAtInfinity}: + # For point at infinity, we want to make sure that "verify" itself handles them. + break testChecks + + + status = pubkey.verify(testVector.input.message, signature) + let success = status == cttBLS_Success + doAssert success == testVector.output, block: + "\Verification differs from expected \n" & + " valid sig? " & $success & " (" & $status & ")\n" & + " expected: " & $testVector.output + + if success: # Extra codec testing + block: + var output{.noInit.}: array[48, byte] + let s = output.serialize_public_key_compressed(pubkey) + doAssert s == cttBLS_Success + doAssert output == testVector.input.pubkey + + block: + var output{.noInit.}: array[96, byte] + let s = output.serialize_signature_compressed(signature) + doAssert s == cttBLS_Success + doAssert output == testVector.input.signature + +suite "BLS signature on BLS12381G3 - ETH 2.0 test vectors": + test "Deserialization_G1(PublicKey) -> bool": + test_deserialization_G1() + test "Deserialization_G2(Signature) -> bool": + test_deserialization_G2() + test "sign(SecretKey, message) -> Signature": + test_sign() + test "verify(PublicKey, message, Signature) -> bool": + test_verify() \ No newline at end of file diff --git a/tests/t_sig_bls_lowlevel.nim b/tests/t_sig_bls_lowlevel.nim deleted file mode 100644 index 64546b0..0000000 --- a/tests/t_sig_bls_lowlevel.nim +++ /dev/null @@ -1,190 +0,0 @@ -# Constantine -# Copyright (c) 2018-2019 Status Research & Development GmbH -# Copyright (c) 2020-Present Mamy André-Ratsimbazafy -# Licensed and distributed under either of -# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT). -# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). -# at your option. This file may not be copied, modified, or distributed except according to those terms. - -import - # Standard library - std/[os, times], - # Internals - ../constantine/backend/config/common, - ../constantine/backend/[ - arithmetic, primitives, - towers, ec_shortweierstrass, - hashes - ], - ../constantine/backend/elliptic/ec_scalar_mul, - ../constantine/backend/io/[io_fields, io_towers, io_ec], - ../constantine/backend/config/curves, - ../constantine/backend/curves/zoo_subgroups, - ../constantine/backend/hash_to_curve/hash_to_curve, - ../constantine/backend/pairing/pairing_bls12, - # Test utilities - ../helpers/prng_unsafe - -# Testing implementation of BLS signature scheme -# with low-level primitives -# ---------------------------------------------- - -var rng: RngState -let timeseed = uint32(toUnix(getTime()) and (1'i64 shl 32 - 1)) # unixTime mod 2^32 -seed(rng, timeseed) -echo "\n------------------------------------------------------\n" -echo "test_sig_bls xoshiro512** seed: ", timeseed - -# Generators -# ------------------------------------------------------------- -# https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-pairing-friendly-curves-10#section-4.2.1 -# -const BLS12_381_G1_generator_x = Fp[BLS12_381].fromHex( - "0x17f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac58" & - "6c55e83ff97a1aeffb3af00adb22c6bb" -) - -const BLS12_381_G1_generator_y = Fp[BLS12_381].fromHex( - "0x08b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3ed" & - "d03cc744a2888ae40caa232946c5e7e1" -) - -const BLS12_381_G2_generator_x = Fp2[BLS12_381].fromHex( - "0x024aa2b2f08f0a91260805272dc51051c6e47ad4fa403b02b4510b647ae3d177" & - "0bac0326a805bbefd48056c8c121bdb8", - "0x13e02b6052719f607dacd3a088274f65596bd0d09920b61ab5da61bbdc7f5049" & - "334cf11213945d57e5ac7d055d042b7e" -) - -const BLS12_381_G2_generator_y = Fp2[BLS12_381].fromHex( - "0x0ce5d527727d6e118cc9cdc6da2e351aadfd9baa8cbdd3a76d429a695160d12c" & - "923ac9cc3baca289e193548608b82801", - "0x0606c4a02ea734cc32acd2b02bc28b99cb3e287e85a763af267492ab572e99ab" & - "3f370d275cec1da1aaa9075ff05f79be" -) - -const BLS12_381_G1_generator = ECP_ShortW_Aff[Fp[BLS12_381], G1]( - x: BLS12_381_G1_generator_x, y: BLS12_381_G1_generator_y -) -const BLS12_381_G2_generator = ECP_ShortW_Aff[Fp2[BLS12_381], G2]( - x: BLS12_381_G2_generator_x, y: BLS12_381_G2_generator_y -) - -# We test using the pubkey on G1, signature on G2 scheme. -# with SHA256 hash and proof-of-possession. (Ethereum 2 config). -const DomainSepTag = "BLS_SIG_BLS12381G2_XMD:SHA-256_SSWU_RO_POP_" - -func genSecretKey(rng: var RngState, seckey: var Fr[BLS12_381]) = - # Don't do this at home! - seckey = rng.random_unsafe(Fr[BLS12_381]) - while seckey.isZero().bool: - seckey = rng.random_unsafe(Fr[BLS12_381]) - -func publicKeyG1( - pubkey: var ECP_ShortW_Aff[Fp[BLS12_381], G1], - seckey: Fr[BLS12_381] - ) = - var t: ECP_ShortW_Prj[Fp[BLS12_381], G1] - t.fromAffine(BLS12_381_G1_generator) - t.scalarMul(seckey.toBig()) - pubkey.affine(t) - doAssert not bool pubkey.isInf() - -func signG2[T: byte|char]( - signature: var ECP_ShortW_Aff[Fp2[BLS12_381], G2], - message: openarray[T], - secretKey: Fr[BLS12_381] - ) = - doAssert not bool secretKey.isZero() - var t: ECP_ShortW_Prj[Fp2[BLS12_381], G2] - hashToCurve( - H = sha256, k = 128, - output = t, - augmentation = "", - message = message, - domainSepTag = DomainSepTag - ) - t.scalarMul(secretKey.toBig()) - signature.affine(t) - doAssert not bool signature.isInf() - -func verifyG2[T: byte|char]( - pubkey: ECP_ShortW_Aff[Fp[BLS12_381], G1], - message: openarray[T], - signature: ECP_ShortW_Aff[Fp2[BLS12_381], G2] - ): SecretBool = - doAssert not pubkey.isInf.bool - doAssert not signature.isInf.bool - - var Q {.noinit.}: typeof(signature) - var Qprj {.noInit.}: ECP_ShortW_Prj[Fp2[BLS12_381], G2] - hashToCurve( - H = sha256, k = 128, - output = Qprj, - augmentation = "", - message = message, - domainSepTag = DomainSepTag - ) - Q.affine(Qprj) - - var e0{.noInit.}, e1{.noInit.}: Fp12[BLS12_381] - e0.pairing_bls12(pubkey, Q) - e1.pairing_bls12(BLS12_381_G1_generator, signature) - - return e0 == e1 - -func verifyG2_multi[T: byte|char]( - pubkey: ECP_ShortW_Aff[Fp[BLS12_381], G1], - message: openarray[T], - signature: ECP_ShortW_Aff[Fp2[BLS12_381], G2] - ): SecretBool = - doAssert not pubkey.isInf.bool - doAssert not signature.isInf.bool - - var Qprj {.noInit.}: ECP_ShortW_Prj[Fp2[BLS12_381], G2] - hashToCurve( - H = sha256, k = 128, - output = Qprj, - augmentation = "", - message = message, - domainSepTag = DomainSepTag - ) - - var G2s: array[2, ECP_ShortW_Aff[Fp2[BLS12_381], G2]] - var G1s: array[2, ECP_ShortW_Aff[Fp[BLS12_381], G1]] - - G1s[0] = pubkey - G2s[0].affine(Qprj) - - G1s[1].neg(BLS12_381_G1_generator) - G2s[1] = signature - - var e: Fp12[BLS12_381] - e.pairing_bls12(G1s, G2s) - - return e.isOne() - -proc bls_signature_test(rng: var RngState, i: int) = - var - seckey: Fr[BLS12_381] - pubkey: ECP_ShortW_Aff[Fp[BLS12_381], G1] - message = rng.random_byte_seq(length = i) - signature: ECP_ShortW_Aff[Fp2[BLS12_381], G2] - - rng.genSecretKey(seckey) - pubkey.publicKeyG1(seckey) - signature.signG2(message, seckey) - - let okSingle = pubkey.verifyG2(message, signature) - doAssert bool okSingle - - let okMulti = pubkey.verifyG2_multi(message, signature) - doAssert bool okMulti - -for i in 0 ..< 500: - rng.bls_signature_test(i) - stdout.write('.') - stdout.flushFile() -stdout.write('\n') - -echo "SUCCESS - BLS Signature scheme on BLS12_381, pubkey on G1, signatures on G2"