Sage constants & tests codegen (#101)

* Implement a Sage codegenerator for frobenius constants

* Sage codegen for pairings

* Autogen of endomorphism acceleration constants

* The autogen fixed a copy-paste bug in lattice decomposition. We can use conditional negation now and save an add+dbl in scalar mul

* small fixes

* sage code for square root bls12-377 is not old

* readme updates

* Provide test suggestions for derive_frobenius

* indentation + add equation form to sage

* Sage test vector generator

* Use the json vectors
- includes type system workaround: generic sandwich https://github.com/nim-lang/Nim/issues/11225
- converting NimNode to typedesc: https://github.com/nim-lang/Nim/issues/6785

* Delete old sage code

* Install nim-serialization and nim-json-serialization in CI

* CI nimble install force yes
This commit is contained in:
Mamy Ratsimbazafy 2020-10-10 16:19:23 +02:00 committed by GitHub
parent 71bb4c799a
commit a2f46f77b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
56 changed files with 6077 additions and 5324 deletions

View File

@ -201,7 +201,7 @@ jobs:
shell: bash
run: |
nimble refresh
nimble install -y gmp stew
nimble install -y gmp stew serialization json_serialization
- name: Run Constantine tests (with Assembler & with GMP)
if: (runner.os == 'Linux' || runner.os == 'macOS') && matrix.target.cpu == 'amd64'
shell: bash

View File

@ -123,7 +123,7 @@ before_script:
- export PATH="$PWD/nim-${CHANNEL}/bin${PATH:+:$PATH}"
script:
- nimble refresh
- nimble install gmp stew
- nimble install -y gmp stew serialization json_serialization
# Installing Clang9.0 or later is a pain in Travis
# for inline assembly "flag output constraint"
# Also MacOS build is timing out with 2 series of tests.

View File

@ -1,4 +1,4 @@
# Constantine - Constant Time Pairing-Based & Elliptic Curve Cryptography
# Constantine - Fast, compact, hardened Pairing-Based Cryptography
[![License: Apache](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
@ -7,7 +7,10 @@
[![Build Status: Travis](https://img.shields.io/travis/com/mratsim/constantine/master?label=Travis%20%28Linux%20x86_64%2FARM64%2FPowerPC64,%20MacOS%20x86_64%29)](https://travis-ci.com/mratsim/constantine)\
[![Build Status: Azure](https://img.shields.io/azure-devops/build/numforge/07a2a7a5-995a-45d3-acd5-f5456fe7b04d/4?label=Azure%20%28Linux%2032%2F64-bit%2C%20Windows%2032%2F64-bit%2C%20MacOS%2064-bit%29)](https://dev.azure.com/numforge/Constantine/_build?definitionId=4&branchName=master)
This library provides [constant-time](https://en.wikipedia.org/wiki/Side-channel_attack) implementation of elliptic curve cryptography
> “A cryptographic system should be secure even if everything about the system, except the key, is public knowledge.”\
> — Auguste Kerckhoffs
This library provides [constant-time](https://en.wikipedia.org/wiki/Timing_attack) implementation of elliptic curve cryptography
with a particular focus on pairing-based cryptography.
The implementations are accompanied with SAGE code used as reference implementation and test vectors generators before writing highly optimized routines implemented in the [Nim language](https://nim-lang.org/)
@ -16,10 +19,10 @@ The implementations are accompanied with SAGE code used as reference implementat
## Target audience
The library aims to be a portable, compact and hardened library for elliptic curve cryptography needs, in particular for blockchain protocols and zero-knowledge proofs system.
The library aims to be a fast, compact and hardened library for elliptic curve cryptography needs, in particular for blockchain protocols and zero-knowledge proofs system.
The library focuses on following properties:
- constant-time (not leaking secret data via side-channels)
- constant-time (not leaking secret data via [side-channels](https://en.wikipedia.org/wiki/Side-channel_attack))
- performance
- generated code size, datatype size and stack usage
@ -51,7 +54,7 @@ The Nim language offers the following benefits for cryptography:
- Obscure embedded devices with proprietary C compilers can be targeted.
- WASM can be targeted.
- Performance reachable in C is reachable in Nim, easily.
- Rich type system: generics, dependent types, mutability-tracking and side-effect analysis, borrow-checking, distinct types (Miles != Meters, SecretBool != bool SecretWord != uint64).
- Rich type system: generics, dependent types, mutability-tracking and side-effect analysis, borrow-checking, compiler enforced distinct types (Miles != Meters, SecretBool != bool and SecretWord != uint64).
- Compile-time evaluation, including parsing hex string, converting them to BigInt or Finite Field elements and doing bigint operations.
- Assembly support either inline or ``__attribute__((naked))`` or a simple `{.compile: "myasm.S".}` away
- No GC if no GC-ed types are used (automatic memory management is set at the type level and optimized for latency/soft-realtime by default and can be totally deactivated).

View File

@ -29,7 +29,7 @@ strategy:
VM: 'ubuntu-18.04'
UCPU: amd64
CHANNEL: devel
WEAVE_TEST_LANG: cpp
TEST_LANG: cpp
# Deactivated for now, this is cross-compilation and tricky to get right
# Linux_devel_32bit:
@ -219,7 +219,7 @@ steps:
- bash: |
echo "PATH=${PATH}"
nimble refresh
nimble install gmp stew
nimble install -y gmp stew serialization json_serialization
displayName: 'Installing package and testing dependencies'
- bash: |

View File

@ -175,7 +175,7 @@ proc scalarMulGenericBench*(T: typedesc, window: static int, iters: int) =
let exponent = rng.random_unsafe(BigInt[bits])
bench("EC ScalarMul Generic " & G1_or_G2 & " (window = " & $window & ", scratchsize = " & $(1 shl window) & ')', T, iters):
bench("EC ScalarMul " & $bits & "-bit Generic " & G1_or_G2 & " (window = " & $window & ')', T, iters):
r = P
r.scalarMulGeneric(exponent, window)
@ -188,7 +188,7 @@ proc scalarMulEndo*(T: typedesc, iters: int) =
let exponent = rng.random_unsafe(BigInt[bits])
bench("EC ScalarMul " & G1_or_G2 & " (endomorphism accelerated)", T, iters):
bench("EC ScalarMul " & $bits & "-bit " & G1_or_G2 & " (endomorphism accelerated)", T, iters):
r = P
r.scalarMulEndo(exponent)
@ -201,7 +201,7 @@ proc scalarMulEndoWindow*(T: typedesc, iters: int) =
let exponent = rng.random_unsafe(BigInt[bits])
bench("EC ScalarMul Window-2 " & G1_or_G2 & " (endomorphism accelerated)", T, iters):
bench("EC ScalarMul " & $bits & "-bit " & G1_or_G2 & " (window-2, endomorphism accelerated)", T, iters):
r = P
when T.F is Fp:
r.scalarMulGLV_m2w2(exponent)
@ -217,6 +217,6 @@ proc scalarMulUnsafeDoubleAddBench*(T: typedesc, iters: int) =
let exponent = rng.random_unsafe(BigInt[bits])
bench("EC ScalarMul " & G1_or_G2 & " (unsafe reference DoubleAdd)", T, iters):
bench("EC ScalarMul " & $bits & "-bit " & G1_or_G2 & " (unsafe reference DoubleAdd)", T, iters):
r = P
r.unsafe_ECmul_double_add(exponent)

View File

@ -114,7 +114,7 @@ const testDesc: seq[tuple[path: string, useGMP: bool]] = @[
# Elliptic curve arithmetic vs Sagemath
("tests/t_ec_frobenius.nim", false),
("tests/t_ec_sage_bn254.nim", false),
("tests/t_ec_sage_bn254_snarks.nim", false),
("tests/t_ec_sage_bls12_377.nim", false),
("tests/t_ec_sage_bls12_381.nim", false),
# Edge cases highlighted by past bugs

View File

@ -15,11 +15,11 @@ import
# -----------------------------------------------------------------
# c = (SNR^((p-1)/6)^coef).
# Then for frobenius(2): c * conjugate(c)
# And for frobenius(3): c² * conjugate(c)
# Then for frobenius(2): c * conjugate(c)
# And for frobenius(3): c² * conjugate(c)
const BLS12_377_FrobeniusMapCoefficients* = [
# frobenius(1)
[Fp2[BLS12_377].fromHex( # SNR^((p-1)/6)^0
# frobenius(1) -----------------------
[Fp2[BLS12_377].fromHex( # SNR^((p-1)/6)^0
"0x1",
"0x0"
),
@ -27,93 +27,89 @@ const BLS12_377_FrobeniusMapCoefficients* = [
"0x9a9975399c019633c1e30682567f915c8a45e0f94ebc8ec681bf34a3aa559db57668e558eb0188e938a9d1104f2031",
"0x0"
),
Fp2[BLS12_377].fromHex( # SNR^((p-1)/6)^2 = SNR^((p-1)/3)
Fp2[BLS12_377].fromHex( # SNR^((p-1)/6)^2
"0x9b3af05dd14f6ec619aaf7d34594aabc5ed1347970dec00452217cc900000008508c00000000002",
"0x0"
),
Fp2[BLS12_377].fromHex( # SNR^((p-1)/6)^3 = SNR^((p-1)/2)
Fp2[BLS12_377].fromHex( # SNR^((p-1)/6)^3
"0x1680a40796537cac0c534db1a79beb1400398f50ad1dec1bce649cf436b0f6299588459bff27d8e6e76d5ecf1391c63",
"0x0"
),
Fp2[BLS12_377].fromHex( # SNR^((p-1)/6)^4 = SNR^(2(p-1)/3)
Fp2[BLS12_377].fromHex( # SNR^((p-1)/6)^4
"0x9b3af05dd14f6ec619aaf7d34594aabc5ed1347970dec00452217cc900000008508c00000000001",
"0x0"
),
Fp2[BLS12_377].fromHex( # SNR^((p-1)/6)^5
Fp2[BLS12_377].fromHex( # SNR^((p-1)/6)^5
"0xcd70cb3fc936348d0351d498233f1fe379531411832232f6648a9a9fc0b9c4e3e21b7467077c05853e2c1be0e9fc32",
"0x0"
)],
# frobenius(2)
[Fp2[BLS12_377].fromHex( # norm(SNR)^((p-1)/6)^1
# frobenius(2) -----------------------
[Fp2[BLS12_377].fromHex( # norm(SNR)^((p-1)/6)^0
"0x1",
"0x0"
),
Fp2[BLS12_377].fromHex( # norm(SNR)^((p-1)/6)^2
Fp2[BLS12_377].fromHex( # norm(SNR)^((p-1)/6)^1
"0x9b3af05dd14f6ec619aaf7d34594aabc5ed1347970dec00452217cc900000008508c00000000002",
"0x0"
),
Fp2[BLS12_377].fromHex(
Fp2[BLS12_377].fromHex( # norm(SNR)^((p-1)/6)^2
"0x9b3af05dd14f6ec619aaf7d34594aabc5ed1347970dec00452217cc900000008508c00000000001",
"0x0"
),
Fp2[BLS12_377].fromHex(
Fp2[BLS12_377].fromHex( # norm(SNR)^((p-1)/6)^3
"0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000000",
"0x0"
),
Fp2[BLS12_377].fromHex(
Fp2[BLS12_377].fromHex( # norm(SNR)^((p-1)/6)^4
"0x1ae3a4617c510eabc8756ba8f8c524eb8882a75cc9bc8e359064ee822fb5bffd1e945779fffffffffffffffffffffff",
"0x0"
),
Fp2[BLS12_377].fromHex(
Fp2[BLS12_377].fromHex( # norm(SNR)^((p-1)/6)^5
"0x1ae3a4617c510eabc8756ba8f8c524eb8882a75cc9bc8e359064ee822fb5bffd1e94577a00000000000000000000000",
"0x0"
)],
# frobenius(3)
[Fp2[BLS12_377].fromHex(
# frobenius(3) -----------------------
[Fp2[BLS12_377].fromHex( # (SNR²)^((p-1)/6)^0
"0x1",
"0x0"
),
Fp2[BLS12_377].fromHex(
Fp2[BLS12_377].fromHex( # (SNR²)^((p-1)/6)^1
"0x1680a40796537cac0c534db1a79beb1400398f50ad1dec1bce649cf436b0f6299588459bff27d8e6e76d5ecf1391c63",
"0x0"
),
Fp2[BLS12_377].fromHex(
Fp2[BLS12_377].fromHex( # (SNR²)^((p-1)/6)^2
"0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000000",
"0x0"
),
Fp2[BLS12_377].fromHex(
Fp2[BLS12_377].fromHex( # (SNR²)^((p-1)/6)^3
"0x4630059e5fd9200575d0e552278a89da1f40fdf62334cd620d1860769e389d7db2d8ea700d82721691ea130ec6e39e",
"0x0"
),
Fp2[BLS12_377].fromHex(
Fp2[BLS12_377].fromHex( # (SNR²)^((p-1)/6)^4
"0x1",
"0x0"
),
Fp2[BLS12_377].fromHex(
Fp2[BLS12_377].fromHex( # (SNR²)^((p-1)/6)^5
"0x1680a40796537cac0c534db1a79beb1400398f50ad1dec1bce649cf436b0f6299588459bff27d8e6e76d5ecf1391c63",
"0x0"
)]]
# ψ (Psi) - Untwist-Frobenius-Twist Endomorphisms on twisted curves
# -----------------------------------------------------------------
# BLS12_377 is a D-Twist: psi1_coef1 = SNR^((p-1)/6)
# BLS12_377 is a D-Twist: SNR^((p-1)/6)
const BLS12_377_FrobeniusPsi_psi1_coef1* = Fp2[BLS12_377].fromHex(
"0x9a9975399c019633c1e30682567f915c8a45e0f94ebc8ec681bf34a3aa559db57668e558eb0188e938a9d1104f2031",
"0x0"
)
# SNR^((p-1)/3)
const BLS12_377_FrobeniusPsi_psi1_coef2* = Fp2[BLS12_377].fromHex(
# SNR^((p-1)/3)
const BLS12_377_FrobeniusPsi_psi1_coef2* = Fp2[BLS12_377].fromHex(
"0x9b3af05dd14f6ec619aaf7d34594aabc5ed1347970dec00452217cc900000008508c00000000002",
"0x0"
)
# SNR^((p-1)/2)
const BLS12_377_FrobeniusPsi_psi1_coef3* = Fp2[BLS12_377].fromHex(
# SNR^((p-1)/2)
const BLS12_377_FrobeniusPsi_psi1_coef3* = Fp2[BLS12_377].fromHex(
"0x1680a40796537cac0c534db1a79beb1400398f50ad1dec1bce649cf436b0f6299588459bff27d8e6e76d5ecf1391c63",
"0x0"
)
# norm(SNR)^((p-1)/3)
const BLS12_377_FrobeniusPsi_psi2_coef2* = Fp2[BLS12_377].fromHex(
# norm(SNR)^((p-1)/3)
const BLS12_377_FrobeniusPsi_psi2_coef2* = Fp2[BLS12_377].fromHex(
"0x9b3af05dd14f6ec619aaf7d34594aabc5ed1347970dec00452217cc900000008508c00000000001",
"0x0"
)
)

View File

@ -10,60 +10,54 @@ import
../config/[curves, type_bigint, type_fp],
../io/[io_bigints, io_fields]
# BLS12-377 G1
# ----------------------------------------------------------------------------------------
# BLS12_377 G1
# ------------------------------------------------------------
const BLS12_377_cubicRootofUnity_mod_p* =
Fp[BLS12_377].fromHex"0x9b3af05dd14f6ec619aaf7d34594aabc5ed1347970dec00452217cc900000008508c00000000001"
const BLS12_377_cubicRootOfUnity_mod_p* =
Fp[BLS12_377].fromHex"0x1ae3a4617c510eabc8756ba8f8c524eb8882a75cc9bc8e359064ee822fb5bffd1e945779fffffffffffffffffffffff"
const BLS12_377_Lattice_G1* = (
# (BigInt, isNeg)
((BigInt[127].fromHex"0x452217cc900000010a11800000000000", false), # u² - 1
(BigInt[1].fromHex"0x1", true)), # -1
((BigInt[1].fromHex"0x1", false), # 1
(BigInt[127].fromHex"0x452217cc900000010a11800000000001", false)) # u²
((BigInt[127].fromHex"0x452217cc900000010a11800000000001", false),
(BigInt[1].fromHex"0x1", false)),
((BigInt[1].fromHex"0x1", false),
(BigInt[127].fromHex"0x452217cc900000010a11800000000000", true))
)
const BLS12_377_Babai_G1* = (
# Vector for Babai rounding
# (BigInt, isNeg)
(BigInt[130].fromHex"0x3b3f7aa969fd371607f72ed32af90182c", false),
(BigInt[130].fromHex"0x3b3f7aa969fd371607f72ed32af90181e", false),
(BigInt[4].fromHex"0xd", false)
)
# BLS12-377 G2
# ----------------------------------------------------------------------------------------
# BLS12_377 G2
# ------------------------------------------------------------
const BLS12_377_Lattice_G2* = (
# Curve of order 254 -> mini scalars of size 65
# x = -0xd201000000010000
# Value, isNeg
((BigInt[64].fromHex"0x8508c00000000001", true), # -x
(BigInt[1].fromHex"0x1", false), # 1
(BigInt[1].fromHex"0x0", false), # 0
(BigInt[1].fromHex"0x0", false)), # 0
((BigInt[1].fromHex"0x0", false), # 0
(BigInt[64].fromHex"0x8508c00000000001", true), # -x
(BigInt[1].fromHex"0x1", false), # 1
(BigInt[1].fromHex"0x0", false)), # 0
((BigInt[1].fromHex"0x0", false), # 0
(BigInt[1].fromHex"0x0", false), # 0
(BigInt[64].fromHex"0x8508c00000000001", true), # -x
(BigInt[1].fromHex"0x1", false)), # 1
((BigInt[1].fromHex"0x1", false), # 1
(BigInt[1].fromHex"0x0", false), # 0
(BigInt[1].fromHex"0x1", true), # -1
(BigInt[64].fromHex"0x8508c00000000001", true)) # -x
# (BigInt, isNeg)
((BigInt[64].fromHex"0x8508c00000000001", true),
(BigInt[1].fromHex"0x1", false),
(BigInt[1].fromHex"0x0", false),
(BigInt[1].fromHex"0x0", false)),
((BigInt[1].fromHex"0x0", false),
(BigInt[64].fromHex"0x8508c00000000001", true),
(BigInt[1].fromHex"0x1", false),
(BigInt[1].fromHex"0x0", false)),
((BigInt[1].fromHex"0x0", false),
(BigInt[1].fromHex"0x0", false),
(BigInt[64].fromHex"0x8508c00000000001", true),
(BigInt[1].fromHex"0x1", false)),
((BigInt[1].fromHex"0x1", false),
(BigInt[1].fromHex"0x0", false),
(BigInt[1].fromHex"0x1", true),
(BigInt[64].fromHex"0x8508c00000000001", false))
)
const BLS12_377_Babai_G2* = (
# Vector for Babai rounding
# Value, isNeg
(BigInt[193].fromHex"0x1eca0125755aed064f63abaff9084ce152979759b442f60d1", true),
(BigInt[130].fromHex"0x3b3f7aa969fd371607f72ed32af90181f", true),
(BigInt[67].fromhex"0x72030ba8ee9c06415", true),
(BigInt[1].fromhex"0x0", false)
# (BigInt, isNeg)
(BigInt[193].fromHex"0x1eca0125755aed064f63abaff9084ce152979759b442f60d0", true),
(BigInt[130].fromHex"0x3b3f7aa969fd371607f72ed32af90181e", true),
(BigInt[67].fromHex"0x72030ba8ee9c06422", true),
(BigInt[4].fromHex"0xd", false)
)

View File

@ -8,24 +8,28 @@
import
../config/[curves, type_bigint],
../towers,
../io/io_bigints,
../towers,
../pairing/cyclotomic_fp12
# Slow generic implementation
# ------------------------------------------------------------
# The bit count must be exact for the Miller loop
const BLS12_377_pairing_ate_param* = block:
# BLS Miller loop is parametrized by u
# +1 so that we can take *3 and NAF encode it
BigInt[64+1].fromHex("0x8508c00000000001")
# BLS12 Miller loop is parametrized by u
# +1 to bitlength so that we can mul by 3 for NAF encoding
BigInt[64+1].fromHex"0x8508c00000000001"
const BLS12_377_pairing_ate_param_isNeg* = false
const BLS12_377_pairing_finalexponent* = block:
# (p^12 - 1) / r
# BigInt[4269].fromHex"0x1b2ff68c1abdc48ab4f04ed12cc8f9b2f161b41c7eb8865b9ad3c9bb0571dd94c6bde66548dc13624d9d741024ceb315f46a89cc2482605eb6afc6d8977e5e2ccbec348dd362d59ec2b5bc62a1b467ae44572215548abc98bb4193886ed89cceaedd0221aba84fb33e5584ac29619a87a00c315178155496857c995eab4a8a9af95f4015db27955ae408d6927d0ab37d52f3917c4ddec88f8159f7bcba7eb65f1aae4eeb4e70cb20227159c08a7fdfea9b62bb308918eac3202569dd1bcdd86b431e3646356fc3fb79f89b30775e006993adb629586b6c874b7688f86f11ef7ad94a40eb020da3c532b317232fa56dc564637b331a8e8832eab84269f00b506602c8594b7f7da5a5d8d851fff6ab1d38a354fc8e0b8958e2a9e5ce2d7e50ec36d761d9505fe5e1f317257e2df2952fcd4c93b85278c20488b4ccaee94db3fec1ce8283473e4b493843fa73abe99af8bafce29170b2b863b9513b5a47312991f60c5a4f6872b5d574212bf00d797c0bea3c0f7dfd748e63679fda9b1c50f2df74de38f38e004ae0df997a10db31d209cacbf58ba0678bfe7cd0985bc43258d72d8d5106c21635ae1e527eb01fca3032d50d97756ec9ee756eaba7f21652a808a4e2539e838ef7ec4b178b29e3b976c46bd0ecdd32c1fb75e6e0aef2d8b5661f595a98023f3520381aba8da6cce785dbb0a0bba025478d75ee749619cdb7c42a21098ece86a00c6c2046c1e00000063c69000000000000"
# (p^12 - 1) / r * 3
BigInt[4271].fromHex"0x518fe3a450394da01ed0ec73865aed18d4251c557c299312d07b5d31105598be5439b32fda943a26e8d85c306e6c1941dd3f9d646d87211c240f5489c67b1a8663c49da97a2880dc48213527e51d370acd05663ffda035ca31c4ba994c89d66c0c97066502f8ef19bb008e047c24cf96e02493f4683ffdc39075cc1c01df9fd0ec1dc0419176c010ac1a83b777201a77f8dab474e99c59ae840de7362f7c231d500aecc1eb52616067540d419f7f9fbfd22831919b4ac04960703d9753698941c95aa2d2a04f4bf26de9d191661a013cbb09227c09424595e2639ae94d35ce708bdec2c10628eb4f981945698ef049502d2a71994fab9898c028c73dd021f13208590be27e78f0f18a88f5ffe40157a9e9fef5aa229c0aa7fdb16a887af2c4a486258bf11fb1a5d945707a89d7bf8f67e5bb28f76a460d9a1e660cbbe91bfc456b8789d5bae1dba8cbef5b03bcd0ea30f6a7b45218292b2bf3b20ed5937cb5e2250eee395821805c6383d0286c7423beb42e79f85dab2a36df8fd154f2d89e5e9aaadaaa00e0a29ecc6e329195761d6063e0a2e136a3fb7671c9134c970a8588a7f3144642a10a5af77c105f5e90987f28c6604c5dcb604c02f7d642f7f819eea6fadb8aace7c4e146a17dab2c644d4372c6979845f261b4a20cd88a20325e0c0fc806bd9f60a8502fa8f466b6919311e232e06fd6a861cb5dc24d69274c7e631cac6b93e0254460d445a0000012b53b000000000000"
# Addition chain
# ------------------------------------------------------------
func pow_x*(r: var Fp12[BLS12_377], a: Fp12[BLS12_377], invert = BLS12_377_pairing_ate_param_isNeg) =
## f^x with x the curve parameter
## For BLS12_377 f^-0x8508c00000000001

View File

@ -15,11 +15,11 @@ import
# -----------------------------------------------------------------
# c = (SNR^((p-1)/6)^coef).
# Then for frobenius(2): c * conjugate(c)
# And for frobenius(3): c² * conjugate(c)
# Then for frobenius(2): c * conjugate(c)
# And for frobenius(3): c² * conjugate(c)
const BLS12_381_FrobeniusMapCoefficients* = [
# frobenius(1)
[Fp2[BLS12_381].fromHex( # SNR^((p-1)/6)^0
# frobenius(1) -----------------------
[Fp2[BLS12_381].fromHex( # SNR^((p-1)/6)^0
"0x1",
"0x0"
),
@ -27,93 +27,89 @@ const BLS12_381_FrobeniusMapCoefficients* = [
"0x1904d3bf02bb0667c231beb4202c0d1f0fd603fd3cbd5f4f7b2443d784bab9c4f67ea53d63e7813d8d0775ed92235fb8",
"0xfc3e2b36c4e03288e9e902231f9fb854a14787b6c7b36fec0c8ec971f63c5f282d5ac14d6c7ec22cf78a126ddc4af3"
),
Fp2[BLS12_381].fromHex( # SNR^((p-1)/6)^2 = SNR^((p-1)/3)
Fp2[BLS12_381].fromHex( # SNR^((p-1)/6)^2
"0x0",
"0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac"
),
Fp2[BLS12_381].fromHex( # SNR^((p-1)/6)^3 = SNR^((p-1)/2)
Fp2[BLS12_381].fromHex( # SNR^((p-1)/6)^3
"0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09",
"0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09"
),
Fp2[BLS12_381].fromHex( # SNR^((p-1)/6)^4 = SNR^(2(p-1)/3)
Fp2[BLS12_381].fromHex( # SNR^((p-1)/6)^4
"0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad",
"0x0"
),
Fp2[BLS12_381].fromHex( # SNR^((p-1)/6)^5
Fp2[BLS12_381].fromHex( # SNR^((p-1)/6)^5
"0x5b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116",
"0x144e4211384586c16bd3ad4afa99cc9170df3560e77982d0db45f3536814f0bd5871c1908bd478cd1ee605167ff82995"
)],
# frobenius(2)
[Fp2[BLS12_381].fromHex( # norm(SNR)^((p-1)/6)^1
# frobenius(2) -----------------------
[Fp2[BLS12_381].fromHex( # norm(SNR)^((p-1)/6)^0
"0x1",
"0x0"
),
Fp2[BLS12_381].fromHex( # norm(SNR)^((p-1)/6)^2
Fp2[BLS12_381].fromHex( # norm(SNR)^((p-1)/6)^1
"0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffeffff",
"0x0"
),
Fp2[BLS12_381].fromHex(
Fp2[BLS12_381].fromHex( # norm(SNR)^((p-1)/6)^2
"0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe",
"0x0"
),
Fp2[BLS12_381].fromHex(
Fp2[BLS12_381].fromHex( # norm(SNR)^((p-1)/6)^3
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa",
"0x0"
),
Fp2[BLS12_381].fromHex(
Fp2[BLS12_381].fromHex( # norm(SNR)^((p-1)/6)^4
"0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac",
"0x0"
),
Fp2[BLS12_381].fromHex(
Fp2[BLS12_381].fromHex( # norm(SNR)^((p-1)/6)^5
"0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad",
"0x0"
)],
# frobenius(3)
[Fp2[BLS12_381].fromHex(
# frobenius(3) -----------------------
[Fp2[BLS12_381].fromHex( # (SNR²)^((p-1)/6)^0
"0x1",
"0x0"
),
Fp2[BLS12_381].fromHex(
Fp2[BLS12_381].fromHex( # (SNR²)^((p-1)/6)^1
"0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2",
"0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09"
),
Fp2[BLS12_381].fromHex(
Fp2[BLS12_381].fromHex( # (SNR²)^((p-1)/6)^2
"0x0",
"0x1"
),
Fp2[BLS12_381].fromHex(
Fp2[BLS12_381].fromHex( # (SNR²)^((p-1)/6)^3
"0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2",
"0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2"
),
Fp2[BLS12_381].fromHex(
Fp2[BLS12_381].fromHex( # (SNR²)^((p-1)/6)^4
"0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaaa",
"0x0"
),
Fp2[BLS12_381].fromHex(
Fp2[BLS12_381].fromHex( # (SNR²)^((p-1)/6)^5
"0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09",
"0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2"
)]]
# ψ (Psi) - Untwist-Frobenius-Twist Endomorphisms on twisted curves
# -----------------------------------------------------------------
# BLS12_381 is a M-Twist: psi1_coef1 = (1/SNR)^((p-1)/6)
# BLS12_381 is a M-twist: (1/SNR)^((p-1)/6)
const BLS12_381_FrobeniusPsi_psi1_coef1* = Fp2[BLS12_381].fromHex(
"0x5b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116",
"0x5b2cfd9013a5fd8df47fa6b48b1e045f39816240c0b8fee8beadf4d8e9c0566c63a3e6e257f87329b18fae980078116"
)
# (1/SNR)^((p-1)/3)
const BLS12_381_FrobeniusPsi_psi1_coef2* = Fp2[BLS12_381].fromHex(
# (1/SNR)^((p-1)/3)
const BLS12_381_FrobeniusPsi_psi1_coef2* = Fp2[BLS12_381].fromHex(
"0x0",
"0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaad"
)
# (1/SNR)^((p-1)/2)
const BLS12_381_FrobeniusPsi_psi1_coef3* = Fp2[BLS12_381].fromHex(
# (1/SNR)^((p-1)/2)
const BLS12_381_FrobeniusPsi_psi1_coef3* = Fp2[BLS12_381].fromHex(
"0x135203e60180a68ee2e9c448d77a2cd91c3dedd930b1cf60ef396489f61eb45e304466cf3e67fa0af1ee7b04121bdea2",
"0x6af0e0437ff400b6831e36d6bd17ffe48395dabc2d3435e77f76e17009241c5ee67992f72ec05f4c81084fbede3cc09"
)
# norm(SNR)^((p-1)/3)
const BLS12_381_FrobeniusPsi_psi2_coef2* = Fp2[BLS12_381].fromHex(
# norm((1/SNR))^((p-1)/3)
const BLS12_381_FrobeniusPsi_psi2_coef2* = Fp2[BLS12_381].fromHex(
"0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac",
"0x0"
)
)

View File

@ -10,60 +10,54 @@ import
../config/[curves, type_bigint, type_fp],
../io/[io_bigints, io_fields]
# BLS12-381 G1
# ----------------------------------------------------------------------------------------
# BLS12_381 G1
# ------------------------------------------------------------
const BLS12_381_cubicRootOfUnity_mod_p* =
Fp[BLS12_381].fromHex"0x1a0111ea397fe699ec02408663d4de85aa0d857d89759ad4897d29650fb85f9b409427eb4f49fffd8bfd00000000aaac"
Fp[BLS12_381].fromHex"0x5f19672fdf76ce51ba69c6076a0f77eaddb3a93be6f89688de17d813620a00022e01fffffffefffe"
const BLS12_381_Lattice_G1* = (
# (BigInt, isNeg)
((BigInt[128].fromHex"0xac45a4010001a40200000000ffffffff", false), # u² - 1
(BigInt[1].fromHex"0x1", true)), # -1
((BigInt[1].fromHex"0x1", false), # 1
(BigInt[128].fromHex"0xac45a4010001a4020000000100000000", false)) # u²
((BigInt[128].fromHex"0xac45a4010001a4020000000100000000", false),
(BigInt[1].fromHex"0x1", false)),
((BigInt[1].fromHex"0x1", false),
(BigInt[128].fromHex"0xac45a4010001a40200000000ffffffff", true))
)
const BLS12_381_Babai_G1* = (
# Vector for Babai rounding
# (BigInt, isNeg)
(BigInt[129].fromHex"0x17c6becf1e01faadd63f6e522f6cfee30", false),
(BigInt[129].fromHex"0x17c6becf1e01faadd63f6e522f6cfee2e", false),
(BigInt[2].fromHex"0x2", false)
)
# BLS12-381 G2
# ----------------------------------------------------------------------------------------
# BLS12_381 G2
# ------------------------------------------------------------
const BLS12_381_Lattice_G2* = (
# Curve of order 254 -> mini scalars of size 65
# x = -0xd201000000010000
# Value, isNeg
((BigInt[64].fromHex"0xd201000000010000", false), # -x
(BigInt[1].fromHex"0x1", false), # 1
(BigInt[1].fromHex"0x0", false), # 0
(BigInt[1].fromHex"0x0", false)), # 0
((BigInt[1].fromHex"0x0", false), # 0
(BigInt[64].fromHex"0xd201000000010000", false), # -x
(BigInt[1].fromHex"0x1", false), # 1
(BigInt[1].fromHex"0x0", false)), # 0
((BigInt[1].fromHex"0x0", false), # 0
(BigInt[1].fromHex"0x0", false), # 0
(BigInt[64].fromHex"0xd201000000010000", false), # -x
(BigInt[1].fromHex"0x1", false)), # 1
((BigInt[1].fromHex"0x1", false), # 1
(BigInt[1].fromHex"0x0", false), # 0
(BigInt[1].fromHex"0x1", true), # -1
(BigInt[64].fromHex"0xd201000000010000", false)) # -x
# (BigInt, isNeg)
((BigInt[64].fromHex"0xd201000000010000", false),
(BigInt[1].fromHex"0x1", false),
(BigInt[1].fromHex"0x0", false),
(BigInt[1].fromHex"0x0", false)),
((BigInt[1].fromHex"0x0", false),
(BigInt[64].fromHex"0xd201000000010000", false),
(BigInt[1].fromHex"0x1", false),
(BigInt[1].fromHex"0x0", false)),
((BigInt[1].fromHex"0x0", false),
(BigInt[1].fromHex"0x0", false),
(BigInt[64].fromHex"0xd201000000010000", false),
(BigInt[1].fromHex"0x1", false)),
((BigInt[1].fromHex"0x1", false),
(BigInt[1].fromHex"0x0", false),
(BigInt[1].fromHex"0x1", true),
(BigInt[64].fromHex"0xd201000000010000", true))
)
const BLS12_381_Babai_G2* = (
# Vector for Babai rounding
# Value, isNeg
# (BigInt, isNeg)
(BigInt[193].fromHex"0x1381204ca56cd56b533cfcc0d3e76ec2892078a5e8573b29c", false),
(BigInt[129].fromHex"0x17c6becf1e01faadd63f6e522f6cfee2f", true),
(BigInt[65].fromhex"0x1cfbe4f7bd0027db0", false),
(BigInt[1].fromhex"0x0", false)
(BigInt[129].fromHex"0x17c6becf1e01faadd63f6e522f6cfee2e", true),
(BigInt[65].fromHex"0x1cfbe4f7bd0027db2", false),
(BigInt[2].fromHex"0x2", false)
)

View File

@ -8,23 +8,28 @@
import
../config/[curves, type_bigint],
../towers,
../io/io_bigints,
../towers,
../pairing/cyclotomic_fp12
# Slow generic implementation
# ------------------------------------------------------------
# The bit count must be exact for the Miller loop
const BLS12_381_pairing_ate_param* = block:
# BLS Miller loop is parametrized by u
BigInt[64+2].fromHex("0xd201000000010000") # +2 so that we can take *3 and NAF encode it
# BLS12 Miller loop is parametrized by u
# +2 to bitlength so that we can mul by 3 for NAF encoding
BigInt[64+2].fromHex"0xd201000000010000"
const BLS12_381_pairing_ate_param_isNeg* = true
const BLS12_381_pairing_finalexponent* = block:
# (p^12 - 1) / r
# BigInt[4314].fromHex"0x2ee1db5dcc825b7e1bda9c0496a1c0a89ee0193d4977b3f7d4507d07363baa13f8d14a917848517badc3a43d1073776ab353f2c30698e8cc7deada9c0aadff5e9cfee9a074e43b9a660835cc872ee83ff3a0f0f1c0ad0d6106feaf4e347aa68ad49466fa927e7bb9375331807a0dce2630d9aa4b113f414386b0e8819328148978e2b0dd39099b86e1ab656d2670d93e4d7acdd350da5359bc73ab61a0c5bf24c374693c49f570bcd2b01f3077ffb10bf24dde41064837f27611212596bc293c8d4c01f25118790f4684d0b9c40a68eb74bb22a40ee7169cdc1041296532fef459f12438dfc8e2886ef965e61a474c5c85b0129127a1b5ad0463434724538411d1676a53b5a62eb34c05739334f46c02c3f0bd0c55d3109cd15948d0a1fad20044ce6ad4c6bec3ec03ef19592004cedd556952c6d8823b19dadd7c2498345c6e5308f1c511291097db60b1749bf9b71a9f9e0100418a3ef0bc627751bbd81367066bca6a4c1b6dcfc5cceb73fc56947a403577dfa9e13c24ea820b09c1d9f7c31759c3635de3f7a3639991708e88adce88177456c49637fd7961be1a4c7e79fb02faa732e2f3ec2bea83d196283313492caa9d4aff1c910e9622d2a73f62537f2701aaef6539314043f7bbce5b78c7869aeb2181a67e49eeed2161daf3f881bd88592d767f67c4717489119226c2f011d4cab803e9d71650a6f80698e2f8491d12191a04406fbc8fbd5f48925f98630e68bfb24c0bcb9b55df57510"
# (p^12 - 1) / r * 3
BigInt[4316].fromHex"0x8ca592196587127a538fd40dc3e541f9dca04bb7dc671be77cf17715a2b2fe3bea73dfb468d8f473094aecb7315a664019fbd84913caba6579c08fd42009fe1bd6fcbce15eacb2cf3218a165958cb8bfdae2d2d54207282314fc0dea9d6ff3a07dbd34efb77b732ba5f994816e296a72928cfee133bdc3ca9412b984b9783d9c6aa81297ab1cd294a502304773528bbae8706979f28efa0d355b0224e2513d6e4a5d3bb4dde0523678105d9167ff1323d6e99ac312d8a7d762336370c4347bb5a7e405d6f3496b2dd38e722d4c1f3ac25e3167ec2cb543d69430c37c2f98fcdd0dd36caa9f5aa7994cec31b24ed5e515911037b376e521070d29c9d56cfa8c3574363efb20f28c19e4105ab99edd44084bd23725017931d6740bda71e5f07600ce6b407e543c4bc40bcd4c0b600e6c98003bf8548986b14d9098746dc89d154af91ad54f337b31c79222145dd3ed254fdeda0300c49ebcd2352765f533883a3513435f3ee452496f5166c25bf503bd6ec0a0679efda3b46ebf86211d458de749460d4a2a19abe6ea2accb451ab9a096b98465d044dc2a7f86c253a4ee57b6df108eff598a8dbc483bf8b74c2789939db85ffd7e0fd55b32bc26877f5be26fa7d750500ce2fab93c0cbe7336b126a5693d0c16484f37addccc7642590dbe98538990b88637e374d545d9b34b67448d0357e60280bbd8542f1f4e813caa8e8db57364b4e0cc14f35af381dd9b71ec9292b3a3f16e42362d2019e05f30"
# Addition chain
# ------------------------------------------------------------
func pow_xdiv2*(r: var Fp12[BLS12_381], a: Fp12[BLS12_381], invert = BLS12_381_pairing_ate_param_isNeg) =
## f^(x/2) with x the curve parameter
## For BLS12_381 f^-0xd201000000010000

View File

@ -15,11 +15,11 @@ import
# -----------------------------------------------------------------
# c = (SNR^((p-1)/6)^coef).
# Then for frobenius(2): c * conjugate(c)
# And for frobenius(3): c² * conjugate(c)
# Then for frobenius(2): c * conjugate(c)
# And for frobenius(3): c² * conjugate(c)
const BN254_Nogami_FrobeniusMapCoefficients* = [
# frobenius(1)
[Fp2[BN254_Nogami].fromHex( # SNR^((p-1)/6)^0
# frobenius(1) -----------------------
[Fp2[BN254_Nogami].fromHex( # SNR^((p-1)/6)^0
"0x1",
"0x0"
),
@ -27,93 +27,89 @@ const BN254_Nogami_FrobeniusMapCoefficients* = [
"0x1b377619212e7c8cb6499b50a846953f850974924d3f77c2e17de6c06f2a6de9",
"0x9ebee691ed1837503eab22f57b96ac8dc178b6db2c08850c582193f90d5922a"
),
Fp2[BN254_Nogami].fromHex( # SNR^((p-1)/6)^2 = SNR^((p-1)/3)
Fp2[BN254_Nogami].fromHex( # SNR^((p-1)/6)^2
"0x0",
"0x25236482400000017080eb4000000006181800000000000cd98000000000000b"
),
Fp2[BN254_Nogami].fromHex( # SNR^((p-1)/6)^3 = SNR^((p-1)/2)
Fp2[BN254_Nogami].fromHex( # SNR^((p-1)/6)^3
"0x23dfc9d1a39f4db8c69b87a8848aa075a7333a0e62d78cbf4b1b8eeae58b81c5",
"0x23dfc9d1a39f4db8c69b87a8848aa075a7333a0e62d78cbf4b1b8eeae58b81c5"
),
Fp2[BN254_Nogami].fromHex( # SNR^((p-1)/6)^4 = SNR^(2(p-1)/3)
Fp2[BN254_Nogami].fromHex( # SNR^((p-1)/6)^4
"0x25236482400000017080eb4000000006181800000000000cd98000000000000c",
"0x0"
),
Fp2[BN254_Nogami].fromHex( # SNR^((p-1)/6)^5
Fp2[BN254_Nogami].fromHex( # SNR^((p-1)/6)^5
"0x19f3db6884cdca43c2b0d5792cd135accb1baea0b017046e859975ab54b5ef9b",
"0xb2f8919bb3235bdf7837806d32eca5b9605515f4fe8fba521668a54ab4a1078"
)],
# frobenius(2)
[Fp2[BN254_Nogami].fromHex( # norm(SNR)^((p-1)/6)^1
# frobenius(2) -----------------------
[Fp2[BN254_Nogami].fromHex( # norm(SNR)^((p-1)/6)^0
"0x1",
"0x0"
),
Fp2[BN254_Nogami].fromHex( # norm(SNR)^((p-1)/6)^2
Fp2[BN254_Nogami].fromHex( # norm(SNR)^((p-1)/6)^1
"0x49b36240000000024909000000000006cd80000000000008",
"0x0"
),
Fp2[BN254_Nogami].fromHex(
Fp2[BN254_Nogami].fromHex( # norm(SNR)^((p-1)/6)^2
"0x49b36240000000024909000000000006cd80000000000007",
"0x0"
),
Fp2[BN254_Nogami].fromHex(
Fp2[BN254_Nogami].fromHex( # norm(SNR)^((p-1)/6)^3
"0x2523648240000001ba344d80000000086121000000000013a700000000000012",
"0x0"
),
Fp2[BN254_Nogami].fromHex(
Fp2[BN254_Nogami].fromHex( # norm(SNR)^((p-1)/6)^4
"0x25236482400000017080eb4000000006181800000000000cd98000000000000b",
"0x0"
),
Fp2[BN254_Nogami].fromHex(
Fp2[BN254_Nogami].fromHex( # norm(SNR)^((p-1)/6)^5
"0x25236482400000017080eb4000000006181800000000000cd98000000000000c",
"0x0"
)],
# frobenius(3)
[Fp2[BN254_Nogami].fromHex(
# frobenius(3) -----------------------
[Fp2[BN254_Nogami].fromHex( # (SNR²)^((p-1)/6)^0
"0x1",
"0x0"
),
Fp2[BN254_Nogami].fromHex(
Fp2[BN254_Nogami].fromHex( # (SNR²)^((p-1)/6)^1
"0x1439ab09c60b248f398c5d77b755f92b9edc5f19d2873545be471151a747e4e",
"0x23dfc9d1a39f4db8c69b87a8848aa075a7333a0e62d78cbf4b1b8eeae58b81c5"
),
Fp2[BN254_Nogami].fromHex(
Fp2[BN254_Nogami].fromHex( # (SNR²)^((p-1)/6)^2
"0x0",
"0x1"
),
Fp2[BN254_Nogami].fromHex(
Fp2[BN254_Nogami].fromHex( # (SNR²)^((p-1)/6)^3
"0x1439ab09c60b248f398c5d77b755f92b9edc5f19d2873545be471151a747e4e",
"0x1439ab09c60b248f398c5d77b755f92b9edc5f19d2873545be471151a747e4e"
),
Fp2[BN254_Nogami].fromHex(
Fp2[BN254_Nogami].fromHex( # (SNR²)^((p-1)/6)^4
"0x2523648240000001ba344d80000000086121000000000013a700000000000012",
"0x0"
),
Fp2[BN254_Nogami].fromHex(
Fp2[BN254_Nogami].fromHex( # (SNR²)^((p-1)/6)^5
"0x23dfc9d1a39f4db8c69b87a8848aa075a7333a0e62d78cbf4b1b8eeae58b81c5",
"0x1439ab09c60b248f398c5d77b755f92b9edc5f19d2873545be471151a747e4e"
)]]
# ψ (Psi) - Untwist-Frobenius-Twist Endomorphisms on twisted curves
# -----------------------------------------------------------------
# BN254_Nogami is a D-Twist: psi1_coef1 = SNR^((p-1)/6)
# BN254_Snarks is a D-Twist: SNR^((p-1)/6)
const BN254_Nogami_FrobeniusPsi_psi1_coef1* = Fp2[BN254_Nogami].fromHex(
"0x1b377619212e7c8cb6499b50a846953f850974924d3f77c2e17de6c06f2a6de9",
"0x9ebee691ed1837503eab22f57b96ac8dc178b6db2c08850c582193f90d5922a"
)
# SNR^((p-1)/3)
const BN254_Nogami_FrobeniusPsi_psi1_coef2* = Fp2[BN254_Nogami].fromHex(
# SNR^((p-1)/3)
const BN254_Nogami_FrobeniusPsi_psi1_coef2* = Fp2[BN254_Nogami].fromHex(
"0x0",
"0x25236482400000017080eb4000000006181800000000000cd98000000000000b"
)
# SNR^((p-1)/2)
const BN254_Nogami_FrobeniusPsi_psi1_coef3* = Fp2[BN254_Nogami].fromHex(
# SNR^((p-1)/2)
const BN254_Nogami_FrobeniusPsi_psi1_coef3* = Fp2[BN254_Nogami].fromHex(
"0x23dfc9d1a39f4db8c69b87a8848aa075a7333a0e62d78cbf4b1b8eeae58b81c5",
"0x23dfc9d1a39f4db8c69b87a8848aa075a7333a0e62d78cbf4b1b8eeae58b81c5"
)
# norm(SNR)^((p-1)/3)
const BN254_Nogami_FrobeniusPsi_psi2_coef2* = Fp2[BN254_Nogami].fromHex(
# norm(SNR)^((p-1)/3)
const BN254_Nogami_FrobeniusPsi_psi2_coef2* = Fp2[BN254_Nogami].fromHex(
"0x49b36240000000024909000000000006cd80000000000007",
"0x0"
)
)

View File

@ -8,14 +8,17 @@
import
../config/[curves, type_bigint],
../towers,
../io/io_bigints,
../towers,
../pairing/cyclotomic_fp12
# Slow generic implementation
# ------------------------------------------------------------
# The bit count must be exact for the Miller loop
const BN254_Nogami_pairing_ate_param* = block:
# BN Miller loop is parametrized by 6u+2
# 65+2 bit for NAF x3 encoding
# +2 to bitlength so that we can mul by 3 for NAF encoding
BigInt[65+2].fromHex"0x18300000000000004"
const BN254_Nogami_pairing_ate_param_isNeg* = true
@ -24,6 +27,9 @@ const BN254_Nogami_pairing_finalexponent* = block:
# (p^12 - 1) / r
BigInt[2786].fromHex"0x2928fbb36b391596ee3fe4cbe857330da83e46fedf04d235a4a8daf5ff9f6eabcb4e3f20aa06f0a0d96b24f9af0cbbce750d61627dcbf5fec9139b8f1c46c86b49b4f8a202af26e4504f2c0f56570e9bd5b94c403f385d1908556486e24b396ddc2cdf13d06542f84fe8e82ccbad7b7423fc1ef4e8cc73d605e3e867c0a75f45ea7f6356d9846ce35d5a34f30396938818ad41914b97b99c289a7259b5d2e09477a77bd3c409b19f19e893f8ade90b0aed1b5fc8a07a3cebb41d4e9eee96b21a832ddb1e93e113edfb704fa532848c18593cd0ee90444a1b3499a800177ea38bdec62ec5191f2b6bbee449722f98d2173ad33077545c2ad10347e125a56fb40f086e9a4e62ad336a72c8b202ac3c1473d73b93d93dc0795ca0ca39226e7b4c1bb92f99248ec0806e0ad70744e9f2238736790f5185ea4c70808442a7d530c6ccd56b55a6973867ec6c73599bbd020bbe105da9c6b5c009ad8946cd6f0"
# Addition chain
# ------------------------------------------------------------
func pow_u*(r: var Fp12[BN254_Nogami], a: Fp12[BN254_Nogami], invert = BN254_Nogami_pairing_ate_param_isNeg) =
## f^u with u the curve parameter
## For BN254_Nogami f^-0x4080000000000001

View File

@ -15,11 +15,11 @@ import
# -----------------------------------------------------------------
# c = (SNR^((p-1)/6)^coef).
# Then for frobenius(2): c * conjugate(c)
# And for frobenius(3): c² * conjugate(c)
# Then for frobenius(2): c * conjugate(c)
# And for frobenius(3): c² * conjugate(c)
const BN254_Snarks_FrobeniusMapCoefficients* = [
# frobenius(1)
[Fp2[BN254_Snarks].fromHex( # SNR^((p-1)/6)^0
# frobenius(1) -----------------------
[Fp2[BN254_Snarks].fromHex( # SNR^((p-1)/6)^0
"0x1",
"0x0"
),
@ -27,93 +27,89 @@ const BN254_Snarks_FrobeniusMapCoefficients* = [
"0x1284b71c2865a7dfe8b99fdd76e68b605c521e08292f2176d60b35dadcc9e470",
"0x246996f3b4fae7e6a6327cfe12150b8e747992778eeec7e5ca5cf05f80f362ac"
),
Fp2[BN254_Snarks].fromHex( # SNR^((p-1)/6)^2 = SNR^((p-1)/3)
Fp2[BN254_Snarks].fromHex( # SNR^((p-1)/6)^2
"0x2fb347984f7911f74c0bec3cf559b143b78cc310c2c3330c99e39557176f553d",
"0x16c9e55061ebae204ba4cc8bd75a079432ae2a1d0b7c9dce1665d51c640fcba2"
),
Fp2[BN254_Snarks].fromHex( # SNR^((p-1)/6)^3 = SNR^((p-1)/2)
Fp2[BN254_Snarks].fromHex( # SNR^((p-1)/6)^3
"0x63cf305489af5dcdc5ec698b6e2f9b9dbaae0eda9c95998dc54014671a0135a",
"0x7c03cbcac41049a0704b5a7ec796f2b21807dc98fa25bd282d37f632623b0e3"
),
Fp2[BN254_Snarks].fromHex( # SNR^((p-1)/6)^4 = SNR^(2(p-1)/3)
Fp2[BN254_Snarks].fromHex( # SNR^((p-1)/6)^4
"0x5b54f5e64eea80180f3c0b75a181e84d33365f7be94ec72848a1f55921ea762",
"0x2c145edbe7fd8aee9f3a80b03b0b1c923685d2ea1bdec763c13b4711cd2b8126"
),
Fp2[BN254_Snarks].fromHex( # SNR^((p-1)/6)^5
Fp2[BN254_Snarks].fromHex( # SNR^((p-1)/6)^5
"0x183c1e74f798649e93a3661a4353ff4425c459b55aa1bd32ea2c810eab7692f",
"0x12acf2ca76fd0675a27fb246c7729f7db080cb99678e2ac024c6b8ee6e0c2c4b"
)],
# frobenius(2)
[Fp2[BN254_Snarks].fromHex( # norm(SNR)^((p-1)/6)^1
# frobenius(2) -----------------------
[Fp2[BN254_Snarks].fromHex( # norm(SNR)^((p-1)/6)^0
"0x1",
"0x0"
),
Fp2[BN254_Snarks].fromHex( # norm(SNR)^((p-1)/6)^2
Fp2[BN254_Snarks].fromHex( # norm(SNR)^((p-1)/6)^1
"0x30644e72e131a0295e6dd9e7e0acccb0c28f069fbb966e3de4bd44e5607cfd49",
"0x0"
),
Fp2[BN254_Snarks].fromHex(
Fp2[BN254_Snarks].fromHex( # norm(SNR)^((p-1)/6)^2
"0x30644e72e131a0295e6dd9e7e0acccb0c28f069fbb966e3de4bd44e5607cfd48",
"0x0"
),
Fp2[BN254_Snarks].fromHex(
Fp2[BN254_Snarks].fromHex( # norm(SNR)^((p-1)/6)^3
"0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46",
"0x0"
),
Fp2[BN254_Snarks].fromHex(
Fp2[BN254_Snarks].fromHex( # norm(SNR)^((p-1)/6)^4
"0x59e26bcea0d48bacd4f263f1acdb5c4f5763473177fffffe",
"0x0"
),
Fp2[BN254_Snarks].fromHex(
Fp2[BN254_Snarks].fromHex( # norm(SNR)^((p-1)/6)^5
"0x59e26bcea0d48bacd4f263f1acdb5c4f5763473177ffffff",
"0x0"
)],
# frobenius(3)
[Fp2[BN254_Snarks].fromHex(
# frobenius(3) -----------------------
[Fp2[BN254_Snarks].fromHex( # (SNR²)^((p-1)/6)^0
"0x1",
"0x0"
),
Fp2[BN254_Snarks].fromHex(
Fp2[BN254_Snarks].fromHex( # (SNR²)^((p-1)/6)^1
"0x19dc81cfcc82e4bbefe9608cd0acaa90894cb38dbe55d24ae86f7d391ed4a67f",
"0xabf8b60be77d7306cbeee33576139d7f03a5e397d439ec7694aa2bf4c0c101"
),
Fp2[BN254_Snarks].fromHex(
Fp2[BN254_Snarks].fromHex( # (SNR²)^((p-1)/6)^2
"0x856e078b755ef0abaff1c77959f25ac805ffd3d5d6942d37b746ee87bdcfb6d",
"0x4f1de41b3d1766fa9f30e6dec26094f0fdf31bf98ff2631380cab2baaa586de"
),
Fp2[BN254_Snarks].fromHex(
Fp2[BN254_Snarks].fromHex( # (SNR²)^((p-1)/6)^3
"0x2a275b6d9896aa4cdbf17f1dca9e5ea3bbd689a3bea870f45fcc8ad066dce9ed",
"0x28a411b634f09b8fb14b900e9507e9327600ecc7d8cf6ebab94d0cb3b2594c64"
),
Fp2[BN254_Snarks].fromHex(
Fp2[BN254_Snarks].fromHex( # (SNR²)^((p-1)/6)^4
"0xbc58c6611c08dab19bee0f7b5b2444ee633094575b06bcb0e1a92bc3ccbf066",
"0x23d5e999e1910a12feb0f6ef0cd21d04a44a9e08737f96e55fe3ed9d730c239f"
),
Fp2[BN254_Snarks].fromHex(
Fp2[BN254_Snarks].fromHex( # (SNR²)^((p-1)/6)^5
"0x13c49044952c0905711699fa3b4d3f692ed68098967c84a5ebde847076261b43",
"0x16db366a59b1dd0b9fb1b2282a48633d3e2ddaea200280211f25041384282499"
)]]
# ψ (Psi) - Untwist-Frobenius-Twist Endomorphisms on twisted curves
# -----------------------------------------------------------------
# BN254_Snarks is a D-Twist: psi1_coef1 = SNR^((p-1)/6)
# BN254_Snarks is a D-Twist: SNR^((p-1)/6)
const BN254_Snarks_FrobeniusPsi_psi1_coef1* = Fp2[BN254_Snarks].fromHex(
"0x1284b71c2865a7dfe8b99fdd76e68b605c521e08292f2176d60b35dadcc9e470",
"0x246996f3b4fae7e6a6327cfe12150b8e747992778eeec7e5ca5cf05f80f362ac"
)
# SNR^((p-1)/3)
const BN254_Snarks_FrobeniusPsi_psi1_coef2* = Fp2[BN254_Snarks].fromHex(
# SNR^((p-1)/3)
const BN254_Snarks_FrobeniusPsi_psi1_coef2* = Fp2[BN254_Snarks].fromHex(
"0x2fb347984f7911f74c0bec3cf559b143b78cc310c2c3330c99e39557176f553d",
"0x16c9e55061ebae204ba4cc8bd75a079432ae2a1d0b7c9dce1665d51c640fcba2"
)
# SNR^((p-1)/2)
const BN254_Snarks_FrobeniusPsi_psi1_coef3* = Fp2[BN254_Snarks].fromHex(
# SNR^((p-1)/2)
const BN254_Snarks_FrobeniusPsi_psi1_coef3* = Fp2[BN254_Snarks].fromHex(
"0x63cf305489af5dcdc5ec698b6e2f9b9dbaae0eda9c95998dc54014671a0135a",
"0x7c03cbcac41049a0704b5a7ec796f2b21807dc98fa25bd282d37f632623b0e3"
)
# norm(SNR)^((p-1)/3)
const BN254_Snarks_FrobeniusPsi_psi2_coef2* = Fp2[BN254_Snarks].fromHex(
# norm(SNR)^((p-1)/3)
const BN254_Snarks_FrobeniusPsi_psi2_coef2* = Fp2[BN254_Snarks].fromHex(
"0x30644e72e131a0295e6dd9e7e0acccb0c28f069fbb966e3de4bd44e5607cfd48",
"0x0"
)
)

View File

@ -10,63 +10,54 @@ import
../config/[curves, type_bigint, type_fp],
../io/[io_bigints, io_fields]
# BN254 Snarks G1
# ----------------------------------------------------------------------------------------
# BN254_Snarks G1
# ------------------------------------------------------------
const BN254_Snarks_cubicRootofUnity_mod_p* =
const BN254_Snarks_cubicRootOfUnity_mod_p* =
Fp[BN254_Snarks].fromHex"0x30644e72e131a0295e6dd9e7e0acccb0c28f069fbb966e3de4bd44e5607cfd48"
# Chapter 6.3.1 - Guide to Pairing-based Cryptography
const BN254_Snarks_Lattice_G1* = (
# Curve of order 254 -> mini scalars of size 127
# u = 0x44E992B44A6909F1
# (BigInt, isNeg)
((BigInt[64].fromHex"0x89d3256894d213e3", false), # 2u + 1
(BigInt[127].fromHex"0x6f4d8248eeb859fd0be4e1541221250b", false)), # 6u² + 4u + 1
((BigInt[127].fromHex"0x6f4d8248eeb859fc8211bbeb7d4f1128", false), # 6u² + 2u
(BigInt[64].fromHex"0x89d3256894d213e3", true)) # -2u - 1
((BigInt[127].fromHex"0x6f4d8248eeb859fc8211bbeb7d4f1128", false),
(BigInt[64].fromHex"0x89d3256894d213e3", true)),
((BigInt[64].fromHex"0x89d3256894d213e3", true),
(BigInt[127].fromHex"0x6f4d8248eeb859fd0be4e1541221250b", true))
)
const BN254_Snarks_Babai_G1* = (
# Vector for Babai rounding
# (BigInt, isNeg)
(BigInt[66].fromHex"0x2d91d232ec7e0b3d7", false), # (2u + 1) << 2^256 // r
(BigInt[130].fromHex"0x24ccef014a773d2d25398fd0300ff6565", false) # (6u² + 4u + 1) << 2^256 // r
(BigInt[130].fromHex"0x24ccef014a773d2d25398fd0300ff6565", false),
(BigInt[66].fromHex"0x2d91d232ec7e0b3d7", true)
)
# BN254 Snarks G2
# ----------------------------------------------------------------------------------------
# BN254_Snarks G2
# ------------------------------------------------------------
const BN254_Snarks_Lattice_G2* = (
# Curve of order 254 -> mini scalars of size 65
# x = 0x44E992B44A6909F1
# Value, isNeg
((BigInt[63].fromHex"0x44e992b44a6909f2", false), # x+1
(BigInt[63].fromHex"0x44e992b44a6909f1", false), # x
(BigInt[63].fromHex"0x44e992b44a6909f1", false), # x
(BigInt[64].fromHex"0x89d3256894d213e2", true)), # -2x
((BigInt[64].fromHex"0x89d3256894d213e3", false), # 2x+1
(BigInt[63].fromHex"0x44e992b44a6909f1", true), # -x
(BigInt[63].fromHex"0x44e992b44a6909f2", true), # -x-1
(BigInt[63].fromHex"0x44e992b44a6909f1", true)), # -x
((BigInt[64].fromHex"0x89d3256894d213e2", false), # 2x
(BigInt[64].fromHex"0x89d3256894d213e3", false), # 2x+1
(BigInt[64].fromHex"0x89d3256894d213e3", false), # 2x+1
(BigInt[64].fromHex"0x89d3256894d213e3", false)), # 2x+1
((BigInt[63].fromHex"0x44e992b44a6909f0", false), # x-1
(BigInt[65].fromHex"0x113a64ad129a427c6", false), # 4x+2
(BigInt[64].fromHex"0x89d3256894d213e1", true), # -2x+1
(BigInt[63].fromHex"0x44e992b44a6909f0", false)), # x-1
)
# (BigInt, isNeg)
((BigInt[64].fromHex"0x89d3256894d213e2", false),
(BigInt[63].fromHex"0x44e992b44a6909f2", false),
(BigInt[63].fromHex"0x44e992b44a6909f1", true),
(BigInt[63].fromHex"0x44e992b44a6909f1", false)),
((BigInt[63].fromHex"0x44e992b44a6909f1", true),
(BigInt[63].fromHex"0x44e992b44a6909f1", false),
(BigInt[63].fromHex"0x44e992b44a6909f1", true),
(BigInt[64].fromHex"0x89d3256894d213e3", true)),
((BigInt[63].fromHex"0x44e992b44a6909f2", false),
(BigInt[63].fromHex"0x44e992b44a6909f1", false),
(BigInt[63].fromHex"0x44e992b44a6909f1", false),
(BigInt[64].fromHex"0x89d3256894d213e2", true)),
((BigInt[64].fromHex"0x89d3256894d213e3", false),
(BigInt[63].fromHex"0x44e992b44a6909f1", true),
(BigInt[63].fromHex"0x44e992b44a6909f2", true),
(BigInt[63].fromHex"0x44e992b44a6909f1", true))
)
const BN254_Snarks_Babai_G2* = (
# Vector for Babai rounding
# Value, isNeg
(BigInt[128].fromHex"0xc444fab18d269b9dd0cb46fd51906254", false), # 2x²+3x+1 << 2^256 // r
(BigInt[193].fromHex"0x13d00631561b2572922df9f942d7d77c7001378f5ee78976d", false), # 3x³+8x²+x << 2^256 // r
(BigInt[192].fromhex"0x9e80318ab0d92b94916fcfca16bebbe436510546a93478ab", false), # 6x³+4x²+x << 2^256 // r
(BigInt[128].fromhex"0xc444fab18d269b9af7ae23ce89afae7d", true) # -2x²-x << 2^256 // r
# (BigInt, isNeg)
(BigInt[192].fromHex"0x9e80318ab0d92b9308e5da66fc7184ae46f4bda995d51bb1", false),
(BigInt[192].fromHex"0x9e80318ab0d92b9555b4ca7ba3e5577f2dff291532e42728", true),
(BigInt[192].fromHex"0x9e80318ab0d92b9555b4ca7ba3e55782071c4c43fac4daff", false),
(BigInt[192].fromHex"0x9e80318ab0d92b9555b4ca7ba3e5577dc170977dcef3cd3f", false)
)

View File

@ -8,13 +8,17 @@
import
../config/[curves, type_bigint],
../towers,
../io/io_bigints,
../towers,
../pairing/cyclotomic_fp12
# Slow generic implementation
# ------------------------------------------------------------
# The bit count must be exact for the Miller loop
const BN254_Snarks_pairing_ate_param* = block:
# BN Miller loop is parametrized by 6u+2
# +2 to bitlength so that we can mul by 3 for NAF encoding
BigInt[65+2].fromHex"0x19d797039be763ba8"
const BN254_Snarks_pairing_ate_param_isNeg* = false
@ -23,6 +27,9 @@ const BN254_Snarks_pairing_finalexponent* = block:
# (p^12 - 1) / r
BigInt[2790].fromHex"0x2f4b6dc97020fddadf107d20bc842d43bf6369b1ff6a1c71015f3f7be2e1e30a73bb94fec0daf15466b2383a5d3ec3d15ad524d8f70c54efee1bd8c3b21377e563a09a1b705887e72eceaddea3790364a61f676baaf977870e88d5c6c8fef0781361e443ae77f5b63a2a2264487f2940a8b1ddb3d15062cd0fb2015dfc6668449aed3cc48a82d0d602d268c7daab6a41294c0cc4ebe5664568dfc50e1648a45a4a1e3a5195846a3ed011a337a02088ec80e0ebae8755cfe107acf3aafb40494e406f804216bb10cf430b0f37856b42db8dc5514724ee93dfb10826f0dd4a0364b9580291d2cd65664814fde37ca80bb4ea44eacc5e641bbadf423f9a2cbf813b8d145da90029baee7ddadda71c7f3811c4105262945bba1668c3be69a3c230974d83561841d766f9c9d570bb7fbe04c7e8a6c3c760c0de81def35692da361102b6b9b2b918837fa97896e84abb40a4efb7e54523a486964b64ca86f120"
# Addition chain
# ------------------------------------------------------------
func pow_u*(r: var Fp12[BN254_Snarks], a: Fp12[BN254_Snarks], invert = BN254_Snarks_pairing_ate_param_isNeg) =
## f^u with u the curve parameter
## For BN254_Snarks f^0x44e992b44a6909f1

View File

@ -39,6 +39,7 @@ type
func decomposeEndo*[M, scalBits, L: static int](
miniScalars: var MultiScalar[M, L],
negatePoints: var array[M, SecretBool],
scalar: BigInt[scalBits],
F: typedesc[Fp or Fp2]
) =
@ -109,6 +110,9 @@ func decomposeEndo*[M, scalBits, L: static int](
else:
k[miniScalarIdx] -= alphaB
let isNeg = k[miniScalarIdx].isMsbSet()
negatePoints[miniScalarIdx] = isNeg
k[miniScalarIdx].cneg(isNeg)
miniScalars[miniScalarIdx].copyTruncatedFrom(k[miniScalarIdx])
# Secret scalar + dynamic point
@ -304,9 +308,10 @@ func scalarMulEndo*[scalBits; EC](
{.error: "Unconfigured".}
# 2. Decompose scalar into mini-scalars
const L = (scalBits + M - 1) div M + 1 + 1 # A "+1" to handle negative
const L = (scalBits + M - 1) div M + 1 # Alternatively, negative can be handled with an extra "+1"
var miniScalars {.noInit.}: array[M, BigInt[L]]
miniScalars.decomposeEndo(scalar, P.F)
var negatePoints {.noInit.}: array[M, SecretBool]
miniScalars.decomposeEndo(negatePoints, scalar, P.F)
# 3. Handle negative mini-scalars
# A scalar decomposition might lead to negative miniscalar.
@ -319,17 +324,10 @@ func scalarMulEndo*[scalBits; EC](
# - Conditional negate is about 10 cycles per Fp, on G2 projective we have 3 (coords) * 2 (Fp2) * 10 (cycles) ~= 60 cycles
# We need to test the mini scalar, which is 65 bits so 2 Fp so about 2 cycles
# and negate it as well.
#
# However solution 1 seems to cause issues (TODO)
# with some of the BLS12-381 G2 test cases (6 and 9) as one of the miniscalars is 65 bits
# instead of the expected maximum of 64.
# - 0x5668a2332db27199dcfb7cbdfca6317c2ff128db26d7df68483e0a095ec8e88f
# - 0x644dc62869683f0c93f38eaef2ba6912569dc91ec2806e46b4a3dd6a4421dad1
#
# Furthermore solution 2 isn't enough on BLS12-377 G2 as test fails when miniScalars[0] is negative
let isNeg0 = miniscalars[0].isMsbSet()
miniscalars[0].cneg(isNeg0)
P.cneg(isNeg0)
block:
P.cneg(negatePoints[0])
staticFor i, 1, M:
endomorphisms[i-1].cneg(negatePoints[i])
# 4. Precompute lookup table
var lut {.noInit.}: array[1 shl (M-1), typeof(P)]
@ -458,8 +456,8 @@ func w2TableIndex(glv: GLV_SAC, bit2: int, isNeg: var SecretBool): SecretWord {.
func computeRecodedLength(bitWidth, window: int): int =
# Strangely in the paper this doesn't depend
# "m", the GLV decomposition dimension.
# lw = ⌈log2 r/w⌉+1+1 (a "+1" to handle negative mini scalars)
let lw = (bitWidth + window - 1) div window + 1 + 1
# lw = ⌈log2 r/w⌉+1 (optionally a second "+1" to handle negative mini scalars)
let lw = (bitWidth + window - 1) div window + 1
result = (lw mod window) + lw
func scalarMulGLV_m2w2*[scalBits; EC](
@ -488,12 +486,16 @@ func scalarMulGLV_m2w2*[scalBits; EC](
# 2. Decompose scalar into mini-scalars
const L = computeRecodedLength(C.getCurveOrderBitwidth(), 2)
var miniScalars {.noInit.}: array[2, BigInt[L]]
miniScalars.decomposeEndo(scalar, P0.F)
var negatePoints {.noInit.}: array[2, SecretBool]
miniScalars.decomposeEndo(negatePoints, scalar, P0.F)
# 3. TODO: handle negative mini-scalars
# 3. Handle negative mini-scalars
# Either negate the associated base and the scalar (in the `endomorphisms` array)
# Or use Algorithm 3 from Faz et al which can encode the sign
# in the GLV representation at the low low price of 1 bit
block:
P0.cneg(negatePoints[0])
P1.cneg(negatePoints[1])
# 4. Precompute lookup table
var lut {.noInit.}: array[8, EC]

View File

@ -383,7 +383,7 @@ func affineFromJacobian*[F; Tw](
aff.y.prod(jac.y, invZ)
aff.y.prod(jac.y, invZ2)
func projectiveFromJacobian*[F; Tw](
func jacobianFromAffine*[F; Tw](
jac: var ECP_ShortW_Jac[F, Tw],
aff: ECP_ShortW_Aff[F, Tw]) {.inline.} =
jac.x = aff.x

View File

@ -407,7 +407,7 @@ func nativeEndianToHex(bytes: openarray[byte], order: static[Endianness]): strin
#
# ############################################################
func fromHex*(T: type BigInt, s: string): T {.noInit.} =
func fromHex*(a: var BigInt, s: string) =
## Convert a hex string to BigInt that can hold
## the specified number of bits
##
@ -421,12 +421,26 @@ func fromHex*(T: type BigInt, s: string): T {.noInit.} =
## Can work at compile-time to declare curve moduli from their hex strings
# 1. Convert to canonical uint
const canonLen = (T.bits + 8 - 1) div 8
const canonLen = (BigInt.bits + 8 - 1) div 8
var bytes: array[canonLen, byte]
hexToPaddedByteArray(s, bytes, bigEndian)
# 2. Convert canonical uint to Big Int
result.fromRawUint(bytes, bigEndian)
a.fromRawUint(bytes, bigEndian)
func fromHex*(T: type BigInt, s: string): T {.noInit.} =
## Convert a hex string to BigInt that can hold
## the specified number of bits
##
## For example `fromHex(BigInt[256], "0x123456")`
##
## Hex string is assumed big-endian
##
## This API is intended for configuration and debugging purposes
## Do not pass secret or private data to it.
##
## Can work at compile-time to declare curve moduli from their hex strings
result.fromHex(s)
func appendHex*(dst: var string, big: BigInt, order: static Endianness = bigEndian) =
## Append the BigInt hex into an accumulator

View File

@ -8,7 +8,6 @@
import
./io_bigints, ./io_fields, ./io_towers,
../config/curves,
../arithmetic,
../towers,
../elliptic/[

View File

@ -1,7 +1,10 @@
# Sage scripts
This folder holds sage scripts:
- either for automating curve configuration
for example for computing the prime and order of BN or BLS curve families,
for irreducible polynomials for extension fields.
- for automating curve configuration
- Cofactor determination
- Frobenius precomputations
- Scalar docomposition for endomorphism acceleration
- Pairing parameters for naive implementation (ate and final exponent)
- Square-root parameters for naive implementation.
- for test vectors against a reference implementation.

View File

@ -1,106 +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.
# ############################################################
#
# BLS12 Curves parameters
# (Barreto-Lynn-Scott with embedding degree of 12)
#
# ############################################################
#
# This module derives a BLS12 curve parameters from
# its base parameter x
def compute_curve_characteristic(x_str):
x = sage_eval(x_str)
p = (x - 1)^2 * (x^4 - x^2 + 1)//3 + x
r = x^4 - x^2 + 1
t = x + 1
print(f'BLS12 family - {p.nbits()} bits')
print(' Prime modulus p: 0x' + p.hex())
print(' Curve order r: 0x' + r.hex())
print(' trace t: 0x' + t.hex())
print(' Parameter x: ' + x_str)
if x < 0:
print(' Parameter x (hex): -0x' + (-x).hex())
else:
print(' Parameter x (hex): 0x' + x.hex())
print()
print(f' p mod 3: ' + str(p % 3))
print(f' p mod 4: ' + str(p % 4))
print(f' p mod 8: ' + str(p % 8))
print(f' p mod 12: ' + str(p % 12))
print(f' p mod 16: ' + str(p % 16))
print()
print(f' p^2 mod 3: ' + str(p^2 % 3))
print(f' p^2 mod 4: ' + str(p^2 % 4))
print(f' p^2 mod 8: ' + str(p^2 % 8))
print(f' p^2 mod 12: ' + str(p^2 % 12))
print(f' p^2 mod 16: ' + str(p^2 % 16))
print()
print(f' Endomorphism-based acceleration when p mod 3 == 1')
print(f' Endomorphism can be field multiplication by one of the non-trivial cube root of unity 𝜑')
print(f' Rationale:')
print(f' curve equation is y² = x³ + b, and y² = (x𝜑)³ + b <=> y² = x³ + b (with 𝜑³ == 1) so we are still on the curve')
print(f' this means that multiplying by 𝜑 the x-coordinate is equivalent to a scalar multiplication by some λᵩ')
print(f' with λᵩ² + λᵩ + 1 ≡ 0 (mod CurveOrder), see below. Hence we have a 2 dimensional decomposition of the scalar multiplication')
print(f' i.e. For any [s]P, we can find a corresponding [k1]P + [k2][λᵩ]P with [λᵩ]P being a simple field multiplication by 𝜑')
print(f' Finding cube roots:')
print(f'1=0 <=> (x1)(x²+x+1) = 0, if x != 1, x solves (x²+x+1) = 0 <=> x = (-1±√3)/2')
print(f' cube roots of unity: ' + str(['0x' + Integer(root).hex() for root in GF(p)(1).nth_root(3, all=True)]))
print(f' GLV-2 decomposition of s into (k1, k2) on G1')
print(f' (k1, k2) = (s, 0) - 𝛼1 b1 - 𝛼2 b2')
print(f' 𝛼i = 𝛼\u0302i * s / r')
print(f' Lattice b1: ' + str(['0x' + b.hex() for b in [x^2-1, -1]]))
print(f' Lattice b2: ' + str(['0x' + b.hex() for b in [1, x^2]]))
# Babai rounding
ahat1 = x^2
ahat2 = 1
# We want a1 = ahat1 * s/r with m = 2 (for a 2-dim decomposition) and r the curve order
# To handle rounding errors we instead multiply by
# 𝜈 = (2^WordBitWidth)^w (i.e. the same as the R magic constant for Montgomery arithmetic)
# with 𝜈 > r and w minimal so that 𝜈 > r
# a1 = ahat1*𝜈/r * s/𝜈
v = int(r).bit_length()
print(f' r.bit_length(): {v}')
v = int(((v + 64 - 1) // 64) * 64) # round to next multiple of 64
print(f' 𝜈 > r, 𝜈: 2^{v}')
print(f' Babai roundings')
print(f' 𝛼\u03021: ' + '0x' + ahat1.hex())
print(f' 𝛼\u03022: ' + '0x' + ahat2.hex())
print(f' Handle rounding errors')
print(f' 𝛼\u03051 = 𝛼\u03021 * s / r with 𝛼1 = (𝛼\u03021 * 𝜈/r) * s/𝜈')
print(f' 𝛼\u03052 = 𝛼\u03022 * s / r with 𝛼2 = (𝛼\u03022 * 𝜈/r) * s/𝜈')
print(f' -----------------------------------------------------')
l1 = Integer(ahat1 << v) // r
l2 = Integer(ahat2 << v) // r
print(f' 𝛼1 = (0x{l1.hex()} * s) >> {v}')
print(f' 𝛼2 = (0x{l2.hex()} * s) >> {v}')
if __name__ == "__main__":
# Usage
# BLS12-381
# sage sage/curve_family_bls12.sage '-(2^63 + 2^62 + 2^60 + 2^57 + 2^48 + 2^16)'
# BLS12-377
# sage sage/curve_family_bls12.sage '3 * 2^46 * (7 * 13 * 499) + 1'
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("curve_param",nargs="+")
args = parser.parse_args()
compute_curve_characteristic(args.curve_param[0])

View File

@ -1,104 +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.
# ############################################################
#
# BN Curves parameters
# (Barreto-Naehrig curves)
#
# ############################################################
#
# This module derives a BN curve parameters from
# its base parameterx
def compute_curve_characteristic(x_str):
x = sage_eval(x_str)
p = 36*x^4 + 36*x^3 + 24*x^2 + 6*x + 1
r = 36*x^4 + 36*x^3 + 18*x^2 + 6*x + 1
t = 6*x^2 + 1
print(f'BN family - {p.nbits()} bits')
print(' Prime modulus p: 0x' + p.hex())
print(' Curve order r: 0x' + r.hex())
print(' trace t: 0x' + t.hex())
print(' Parameterx: ' + x_str)
if x < 0:
print(' Parameterx (hex): -0x' + (-x).hex())
else:
print(' Parameterx (hex): 0x' +x.hex())
print(f' p mod 3: ' + str(p % 3))
print(f' p mod 4: ' + str(p % 4))
print(f' p mod 8: ' + str(p % 8))
print(f' p mod 12: ' + str(p % 12))
print(f' p mod 16: ' + str(p % 16))
print()
print(f' p^2 mod 3: ' + str(p^2 % 3))
print(f' p^2 mod 4: ' + str(p^2 % 4))
print(f' p^2 mod 8: ' + str(p^2 % 8))
print(f' p^2 mod 12: ' + str(p^2 % 12))
print(f' p^2 mod 16: ' + str(p^2 % 16))
print()
print(f' Endomorphism-based acceleration when p mod 3 == 1')
print(f' Endomorphism can be field multiplication by one of the non-trivial cube root of unity 𝜑')
print(f' Rationale:')
print(f' curve equation is y² = x³ + b, and y² = (x𝜑)³ + b <=> y² = x³ + b (with 𝜑³ == 1) so we are still on the curve')
print(f' this means that multiplying by 𝜑 the x-coordinate is equivalent to a scalar multiplication by some λᵩ')
print(f' with λᵩ² + λᵩ + 1 ≡ 0 (mod r) and 𝜑² + 𝜑 + 1 ≡ 0 (mod p), see below.')
print(f' Hence we have a 2 dimensional decomposition of the scalar multiplication')
print(f' i.e. For any [s]P, we can find a corresponding [k1]P + [k2][λᵩ]P with [λᵩ]P being a simple field multiplication by 𝜑')
print(f' Finding cube roots:')
print(f'1=0 <=> (x1)(x²+x+1) = 0, if x != 1, x solves (x²+x+1) = 0 <=> x = (-1±√3)/2')
print(f' cube roots of unity 𝜑 (mod p): ' + str(['0x' + Integer(root).hex() for root in GF(p)(1).nth_root(3, all=True)]))
print(f' cube roots of unity λᵩ (mod r): ' + str(['0x' + Integer(root).hex() for root in GF(r)(1).nth_root(3, all=True)]))
print(f' GLV-2 decomposition of s into (k1, k2) on G1')
print(f' (k1, k2) = (s, 0) - 𝛼1 b1 - 𝛼2 b2')
print(f' 𝛼i = 𝛼\u0302i * s / r')
print(f' Lattice b1: ' + str(['0x' + b.hex() for b in [2*x+1, 6*x^2+4*x+1]]))
print(f' Lattice b2: ' + str(['0x' + b.hex() for b in [6*x^2+2*x, -2*x-1]]))
# Babai rounding
ahat1 = 2*x+1
ahat2 = 6*x^2+4*x+1
# We want a1 = ahat1 * s/r with m = 2 (for a 2-dim decomposition) and r the curve order
# To handle rounding errors we instead multiply by
# 𝜈 = (2^WordBitWidth)^w (i.e. the same as the R magic constant for Montgomery arithmetic)
# with 𝜈 > r and w minimal so that 𝜈 > r
# a1 = ahat1*𝜈/r * s/𝜈
v = int(r).bit_length()
print(f' r.bit_length(): {v}')
v = int(((v + 64 - 1) // 64) * 64) # round to next multiple of 64
print(f' 𝜈 > r, 𝜈: 2^{v}')
print(f' Babai roundings')
print(f' 𝛼\u03021: ' + '0x' + ahat1.hex())
print(f' 𝛼\u03022: ' + '0x' + ahat2.hex())
print(f' Handle rounding errors')
print(f' 𝛼1 = 𝛼\u03021 * s / r with 𝛼1 = (𝛼\u03021 * 𝜈/r) * s/𝜈')
print(f' 𝛼2 = 𝛼\u03022 * s / r with 𝛼2 = (𝛼\u03022 * 𝜈/r) * s/𝜈')
print(f' -----------------------------------------------------')
l1 = Integer(ahat1 << v) // r
l2 = Integer(ahat2 << v) // r
print(f' 𝛼1 = (0x{l1.hex()} * s) >> {v}')
print(f' 𝛼2 = (0x{l2.hex()} * s) >> {v}')
if __name__ == "__main__":
# Usage
# sage sage/curve_family_bn.sage '-(2^62 + 2^55 + 1)'
# sage sage/curve_family_bn.sage 4965661367192848881
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("curve_param",nargs="+")
args = parser.parse_args()
compute_curve_characteristic(args.curve_param[0])

117
sage/curves.sage Normal file
View File

@ -0,0 +1,117 @@
#!/usr/bin/sage
# vim: syntax=python
# vim: set ts=2 sw=2 et:
# 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.
# ############################################################
#
# Curves configuration
#
# ############################################################
import inspect
# Accelerate arithmetic by accepting probabilistic proofs
from sage.structure.proof.all import arithmetic
arithmetic(False)
def derive_BN_field(x):
params = {
'param': x,
'modulus': 36*x^4 + 36*x^3 + 24*x^2 + 6*x + 1,
'order': 36*x^4 + 36*x^3 + 18*x^2 + 6*x + 1,
'trace': 6*x^2 + 1,
'family': 'BN'
}
return params
def derive_BLS12_field(x):
params = {
'param': x,
'modulus': (x - 1)^2 * (x^4 - x^2 + 1)//3 + x,
'order': x^4 - x^2 + 1,
'trace': x + 1,
'family': 'BLS12'
}
return params
def copyright():
return inspect.cleandoc("""
# 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.
""")
Curves = {
'BN254_Nogami': {
'field': derive_BN_field(-(2^62 + 2^55 + 1)),
'curve': {
'form': 'short_weierstrass',
'a': 0,
'b': 2
},
'tower': {
'embedding_degree': 12,
'twist_degree': 6,
'QNR_Fp': -1,
'SNR_Fp2': [1, 1],
'twist': 'D_Twist'
}
},
'BN254_Snarks': {
'field': derive_BN_field(Integer('0x44e992b44a6909f1')),
'curve': {
'form': 'short_weierstrass',
'a': 0,
'b': 3
},
'tower': {
'embedding_degree': 12,
'twist_degree': 6,
'QNR_Fp': -1,
'SNR_Fp2': [9, 1],
'twist': 'D_Twist'
}
},
'BLS12_377': {
'field': derive_BLS12_field(3 * 2^46 * (7 * 13 * 499) + 1),
'curve': {
'form': 'short_weierstrass',
'a': 0,
'b': 1
},
'tower': {
'embedding_degree': 12,
'twist_degree': 6,
'QNR_Fp': -5,
'SNR_Fp2': [0, 1],
'twist': 'D_Twist'
}
},
'BLS12_381': {
'field': derive_BLS12_field(-(2^63 + 2^62 + 2^60 + 2^57 + 2^48 + 2^16)),
'curve': {
'form': 'short_weierstrass',
'a': 0,
'b': 4
},
'tower': {
'embedding_degree': 12,
'twist_degree': 6,
'QNR_Fp': -1,
'SNR_Fp2': [1, 1],
'twist': 'M_Twist'
}
}
}

View File

@ -0,0 +1,289 @@
#!/usr/bin/sage
# vim: syntax=python
# vim: set ts=2 sw=2 et:
# 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.
# ############################################################
#
# Endomorphism acceleration constants
#
# ############################################################
# Imports
# ---------------------------------------------------------
import os
import inspect, textwrap
# Working directory
# ---------------------------------------------------------
os.chdir(os.path.dirname(__file__))
# Sage imports
# ---------------------------------------------------------
# Accelerate arithmetic by accepting probabilistic proofs
from sage.structure.proof.all import arithmetic
arithmetic(False)
load('curves.sage')
# Utilities
# ---------------------------------------------------------
def fp2_to_hex(a):
v = vector(a)
return '0x' + Integer(v[0]).hex() + ' + β * ' + '0x' + Integer(v[1]).hex()
def pretty_print_lattice(Lat):
print('Lattice:')
latHex = [['0x' + x.hex() if x >= 0 else '-0x' + (-x).hex() for x in vec] for vec in Lat]
maxlen = max([len(cell) for row in latHex for cell in row])
for row in latHex:
row = ' '.join(cell.rjust(maxlen + 2) for cell in row)
print(row)
def pretty_print_babai(Basis):
print('Babai:')
for i, v in enumerate(Basis):
if v < 0:
print(f' 𝛼\u0305{i}: -0x{Integer(int(-v)).hex()}')
else:
print(f' 𝛼\u0305{i}: 0x{Integer(int(v)).hex()}')
def derive_lattice(r, lambdaR, m):
lat = Matrix(matrix.identity(m))
lat[0, 0] = r
for i in range(1, m):
lat[i, 0] = -lambdaR^i
return lat.LLL()
def derive_babai(r, lattice, m):
basis = m * [0]
basis[0] = r
ahat = vector(basis) * lattice.inverse()
v = int(r).bit_length()
v = int(((v + 64 - 1) // 64) * 64)
return [(a << v) // r for a in ahat]
# TODO: maximum infinity norm
# G1 Endomorphism
# ---------------------------------------------------------
def check_cubic_root_endo(G1, Fp, r, cofactor, lambdaR, phiP):
## Check the Endomorphism for p mod 3 == 1
## Endomorphism can be field multiplication by one of the non-trivial cube root of unity 𝜑
## Rationale:
## curve equation is y² = x³ + b, and y² = (x𝜑)³ + b <=> y² = x³ + b (with 𝜑³ == 1) so we are still on the curve
## this means that multiplying by 𝜑 the x-coordinate is equivalent to a scalar multiplication by some λᵩ
## with λᵩ² + λᵩ + 1 ≡ 0 (mod r) and 𝜑² + 𝜑 + 1 ≡ 0 (mod p), see below.
## Hence we have a 2 dimensional decomposition of the scalar multiplication
## i.e. For any [s]P, we can find a corresponding [k1]P + [k2][λᵩ]P with [λᵩ]P being a simple field multiplication by 𝜑
## Finding cube roots:
## x³1=0 <=> (x1)(x²+x+1) = 0, if x != 1, x solves (x²+x+1) = 0 <=> x = (-1±√3)/2
assert phiP^3 == Fp(1)
assert lambdaR^3 % r == 1
Prand = G1.random_point()
P = Prand * cofactor
assert P != G1([0, 1, 0])
(Px, Py, Pz) = P
Qendo = G1([Px*phiP, Py, Pz])
Qlambda = lambdaR * P
assert P != Qendo
assert P != Qlambda
assert Qendo == Qlambda
print('Endomorphism OK')
def genCubicRootEndo(curve_name, curve_config):
p = curve_config[curve_name]['field']['modulus']
r = curve_config[curve_name]['field']['order']
b = curve_config[curve_name]['curve']['b']
Fp = GF(p)
G1 = EllipticCurve(Fp, [0, b])
cofactor = G1.order() // r
(phi1, phi2) = (Fp(root) for root in Fp(1).nth_root(3, all=True) if root != 1)
(lambda1, lambda2) = (GF(r)(root) for root in GF(r)(1).nth_root(3, all=True) if root != 1)
print('𝜑1 (mod p): 0x' + Integer(phi1).hex())
print('λᵩ1 (mod r): 0x' + Integer(lambda1).hex())
print('𝜑2 (mod p): 0x' + Integer(phi2).hex())
print('λᵩ2 (mod r): 0x' + Integer(lambda2).hex())
# TODO: is there a better way than spray-and-pray?
# TODO: Should we maximize or minimize lambda
# to maximize/minimize the scalar norm?
# TODO: Or is there a way to ensure
# that the Babai basis is mostly positive?
if lambda1 < lambda2:
lambda1, lambda2 = lambda2, lambda1
try:
check_cubic_root_endo(G1, Fp, r, cofactor, int(lambda1), phi1)
except:
print('Failure with:')
print(' 𝜑 (mod p): 0x' + Integer(phi1).hex())
print(' λᵩ (mod r): 0x' + Integer(lambda1).hex())
phi1, phi2 = phi2, phi1
check_cubic_root_endo(G1, Fp, r, cofactor, int(lambda1), phi1)
finally:
print('Success with:')
print(' 𝜑 (mod p): 0x' + Integer(phi1).hex())
print(' λᵩ (mod r): 0x' + Integer(lambda1).hex())
lattice = derive_lattice(r, lambda1, 2)
pretty_print_lattice(lattice)
babai = derive_babai(r, lattice, 2)
pretty_print_babai(babai)
return phi1, lattice, babai
# G2 Endomorphism
# ---------------------------------------------------------
def genPsiEndo(curve_name, curve_config):
t = curve_config[curve_name]['field']['trace']
r = curve_config[curve_name]['field']['order']
k = curve_config[curve_name]['tower']['embedding_degree']
# Decomposition factor depends on the embedding degree
m = CyclotomicField(k).degree()
# λψ is the trace of Frobenius - 1
lambda_psi = t - 1
lattice = derive_lattice(r, lambda_psi, m)
pretty_print_lattice(lattice)
babai = derive_babai(r, lattice, m)
pretty_print_babai(babai)
return lattice, babai
# Dump
# ---------------------------------------------------------
def dumpLattice(lattice):
result = ' # (BigInt, isNeg)\n'
lastRow = lattice.nrows() - 1
lastCol = lattice.ncols() - 1
for rowID, row in enumerate(lattice):
for colID, val in enumerate(row):
result += ' '
result += '(' if colID == 0 else ' '
result += f'(BigInt[{max(1, int(abs(val)).bit_length())}].fromHex"0x{Integer(int(abs(val))).hex()}", '
result += ('false' if val >= 0 else 'true') + ')'
result += ')' if colID == lastCol else ''
result += ',\n' if (rowID != lastRow or colID != lastCol) else '\n'
return result
def dumpBabai(vec):
result = ' # (BigInt, isNeg)\n'
lastRow = len(vec) - 1
for rowID, val in enumerate(vec):
result += ' '
result += f'(BigInt[{max(1, int(abs(val)).bit_length())}].fromHex"0x{Integer(int(abs(val))).hex()}", '
result += ('false' if val >= 0 else 'true') + ')'
result += ',\n' if rowID != lastRow else '\n'
return result
def dumpConst(name, inner):
result = f'const {name}* = (\n'
result += inner
result += ')\n'
return result
# CLI
# ---------------------------------------------------------
if __name__ == "__main__":
# Usage
# BLS12-381
# sage sage/derive_pairing.sage BLS12_381
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("curve",nargs="+")
args = parser.parse_args()
curve = args.curve[0]
if curve not in Curves:
raise ValueError(
curve +
' is not one of the available curves: ' +
str(Curves.keys())
)
else:
print('\nPrecomputing G1 - 𝜑 (phi) cubic root endomorphism')
print('----------------------------------------------------\n')
cubeRootModP, g1lat, g1babai = genCubicRootEndo(curve, Curves)
print('\n\nPrecomputing G2 - ψ (Psi) - untwist-Frobenius-twist endomorphism')
print('----------------------------------------------------\n')
g2lat, g2babai = genPsiEndo(curve, Curves)
with open(f'{curve.lower()}_glv.nim', 'w') as f:
f.write(copyright())
f.write('\n\n')
f.write(inspect.cleandoc(f"""
import
../config/[curves, type_bigint, type_fp],
../io/[io_bigints, io_fields]
# {curve} G1
# ------------------------------------------------------------
"""))
f.write('\n\n')
f.write(inspect.cleandoc(f"""
const {curve}_cubicRootOfUnity_mod_p* =
Fp[{curve}].fromHex"0x{Integer(cubeRootModP).hex()}"
"""))
f.write('\n\n')
f.write(dumpConst(
f'{curve}_Lattice_G1',
dumpLattice(g1lat)
))
f.write('\n')
f.write(dumpConst(
f'{curve}_Babai_G1',
dumpBabai(g1babai)
))
f.write('\n\n')
f.write(inspect.cleandoc(f"""
# {curve} G2
# ------------------------------------------------------------
"""))
f.write('\n\n')
f.write(dumpConst(
f'{curve}_Lattice_G2',
dumpLattice(g2lat)
))
f.write('\n')
f.write(dumpConst(
f'{curve}_Babai_G2',
dumpBabai(g2babai)
))

276
sage/derive_frobenius.sage Normal file
View File

@ -0,0 +1,276 @@
#!/usr/bin/sage
# vim: syntax=python
# vim: set ts=2 sw=2 et:
# 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.
# ############################################################
#
# Frobenius constants
#
# ############################################################
# Imports
# ---------------------------------------------------------
import os
import inspect, textwrap
# Working directory
# ---------------------------------------------------------
os.chdir(os.path.dirname(__file__))
# Sage imports
# ---------------------------------------------------------
# Accelerate arithmetic by accepting probabilistic proofs
from sage.structure.proof.all import arithmetic
arithmetic(False)
load('curves.sage')
# Utilities
# ---------------------------------------------------------
def fp2_to_hex(a):
v = vector(a)
return '0x' + Integer(v[0]).hex() + ' + β * ' + '0x' + Integer(v[1]).hex()
def field_to_nim(value, field, curve, prefix = "", comment_above = "", comment_right = ""):
if field == 'Fp2':
v = vector(value)
result = '# ' + comment_above + '\n' if comment_above else ''
comment_right = ' # ' + comment_right if comment_right else ''
result += inspect.cleandoc(f"""
{prefix}Fp2[{curve}].fromHex( {comment_right}
"0x{Integer(v[0]).hex()}",
"0x{Integer(v[1]).hex()}"
)""")
return result
else:
raise newException(NotImplementedError)
# Code generators
# ---------------------------------------------------------
def genFrobeniusMapConstants(curve_name, curve_config):
embdeg = curve_config[curve_name]['tower']['embedding_degree']
twdeg = curve_config[curve_name]['tower']['twist_degree']
g2field = f'Fp{embdeg//twdeg}' if (embdeg//twdeg) > 1 else 'Fp'
p = curve_config[curve_name]['field']['modulus']
Fp = GF(p)
K.<u> = PolynomialRing(Fp)
if g2field == 'Fp2':
QNR_Fp = curve_config[curve_name]['tower']['QNR_Fp']
Fp2.<beta> = Fp.extension(u^2 - QNR_Fp)
SNR = curve_config[curve_name]['tower']['SNR_Fp2']
if g2field == 'Fp2':
cur = Fp2([1, 0])
SNR = Fp2(SNR)
else:
cur = Fp(1)
SNR = Fp(SNR)
print('\n----> Frobenius extension field constants <----\n')
buf = inspect.cleandoc(f"""
# Frobenius map - on extension fields
# -----------------------------------------------------------------
# c = (SNR^((p-1)/{twdeg})^coef).
# Then for frobenius(2): c * conjugate(c)
# And for frobenius(3): c² * conjugate(c)
const {curve_name}_FrobeniusMapCoefficients* = [
""")
FrobConst_map = SNR^((p-1)/6)
FrobConst_map_list = []
arr = ""
for i in range(twdeg):
if i == 0:
arr += '\n# frobenius(1) -----------------------\n'
arr += '['
arr += field_to_nim(cur, g2field, curve_name, comment_right = f'SNR^((p-1)/{twdeg})^{i}')
FrobConst_map_list.append(cur)
cur *= FrobConst_map
if i == twdeg - 1:
arr += ']'
arr += ',\n'
for i in range(twdeg):
if i == 0:
arr += '# frobenius(2) -----------------------\n'
arr += '['
val = FrobConst_map_list[i]*conjugate(FrobConst_map_list[i])
arr += field_to_nim(val, g2field, curve_name, comment_right = f'norm(SNR)^((p-1)/{twdeg})^{i}')
if i == twdeg - 1:
arr += ']'
arr += ',\n'
for i in range(twdeg):
if i == 0:
arr += '# frobenius(3) -----------------------\n'
arr += '['
val = FrobConst_map_list[i]^2 * conjugate(FrobConst_map_list[i])
arr += field_to_nim(val, g2field, curve_name, comment_right = f'(SNR²)^((p-1)/{twdeg})^{i}')
if i == twdeg - 1:
arr += ']]'
else:
arr += ',\n'
buf += textwrap.indent(arr, ' ')
return buf
def genFrobeniusPsiConstants(curve_name, curve_config):
embdeg = curve_config[curve_name]['tower']['embedding_degree']
twdeg = curve_config[curve_name]['tower']['twist_degree']
twkind = curve_config[curve_name]['tower']['twist']
g2field = f'Fp{embdeg//twdeg}' if (embdeg//twdeg) > 1 else 'Fp'
p = curve_config[curve_name]['field']['modulus']
Fp = GF(p)
K.<u> = PolynomialRing(Fp)
if g2field == 'Fp2':
QNR_Fp = curve_config[curve_name]['tower']['QNR_Fp']
Fp2.<beta> = Fp.extension(u^2 - QNR_Fp)
SNR = curve_config[curve_name]['tower']['SNR_Fp2']
if g2field == 'Fp2':
cur = Fp2([1, 0])
SNR = Fp2(SNR)
else:
cur = Fp(1)
SNR = Fp(SNR)
print('\n----> ψ (Psi) - Untwist-Frobenius-Twist Endomorphism constants <----\n')
buf = inspect.cleandoc(f"""
# ψ (Psi) - Untwist-Frobenius-Twist Endomorphisms on twisted curves
# -----------------------------------------------------------------
""")
buf += '\n'
if twkind == 'D_Twist':
buf += f'# {curve_name} is a D-Twist: psi1_coef1 = SNR^((p-1)/{twdeg})\n\n'
FrobConst_psi = SNR^((p-1)/twdeg)
snrUsed = 'SNR'
else:
buf += f'# {curve_name} is a M-Twist: psi1_coef1 = (1/SNR)^((p-1)/{twdeg})\n\n'
FrobConst_psi = (1/SNR)^((p-1)/twdeg)
snrUsed = '(1/SNR)'
FrobConst_psi1_coef2 = FrobConst_psi^2
FrobConst_psi1_coef3 = FrobConst_psi1_coef2 * FrobConst_psi
buf += field_to_nim(
FrobConst_psi1_coef2, g2field, curve_name,
prefix = f'const {curve_name}_FrobeniusPsi_psi1_coef2* = ',
comment_above = f'{snrUsed}^((p-1)/{twdeg//2})'
) + '\n'
buf += field_to_nim(
FrobConst_psi1_coef3, g2field, curve_name,
prefix = f'const {curve_name}_FrobeniusPsi_psi1_coef3* = ',
comment_above = f'{snrUsed}^((p-1)/{twdeg//3})'
) + '\n'
FrobConst_psi2_coef2 = FrobConst_psi1_coef2 * FrobConst_psi1_coef2**p
buf += field_to_nim(
FrobConst_psi2_coef2, g2field, curve_name,
prefix = f'const {curve_name}_FrobeniusPsi_psi2_coef2* = ',
comment_above = f'norm({snrUsed})^((p-1)/{twdeg//2})'
)
# psi2_coef3 is always -1 (mod p^m) with m = embdeg/twdeg
# Recap, with ξ (xi) the sextic non-residue
# psi_2 = ((1/ξ)^((p-1)/6))^2 = (1/ξ)^((p-1)/3)
# psi_3 = psi_2 * (1/ξ)^((p-1)/6) = (1/ξ)^((p-1)/3) * (1/ξ)^((p-1)/6) = (1/ξ)^((p-1)/2)
#
# Reminder, in 𝔽p2, frobenius(a) = a^p = conj(a)
# psi2_2 = psi_2 * psi_2^p = (1/ξ)^((p-1)/3) * (1/ξ)^((p-1)/3)^p = (1/ξ)^((p-1)/3) * frobenius((1/ξ))^((p-1)/3)
# = norm(1/ξ)^((p-1)/3)
# psi2_3 = psi_3 * psi_3^p = (1/ξ)^((p-1)/2) * (1/ξ)^((p-1)/2)^p = (1/ξ)^((p-1)/2) * frobenius((1/ξ))^((p-1)/2)
# = norm(1/ξ)^((p-1)/2)
#
# In Fp²:
# - quadratic non-residues respect the equation a^((p²-1)/2) ≡ -1 (mod p²) by the Legendre symbol
# - sextic non-residues are also quadratic non-residues so ξ^((p²-1)/2) ≡ -1 (mod p²)
# - QRT(1/a) = QRT(a) with QRT the quadratic residuosity test
#
# We have norm(ξ)^((p-1)/2) = (ξ*frobenius(ξ))^((p-1)/2) = (ξ*(ξ^p))^((p-1)/2) = ξ^(p+1)^(p-1)/2
# = ξ^((p²-1)/2)
# And ξ^((p²-1)/2) ≡ -1 (mod p²)
# So psi2_3 ≡ -1 (mod p²)
return buf
# CLI
# ---------------------------------------------------------
if __name__ == "__main__":
# Usage
# BLS12-381
# sage sage/derive_frobenius.sage BLS12_381
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("curve",nargs="+")
args = parser.parse_args()
curve = args.curve[0]
if curve not in Curves:
raise ValueError(
curve +
' is not one of the available curves: ' +
str(Curves.keys())
)
else:
FrobMap = genFrobeniusMapConstants(curve, Curves)
FrobPsi = genFrobeniusPsiConstants(curve, Curves)
with open(f'{curve.lower()}_frobenius.nim', 'w') as f:
f.write(copyright())
f.write('\n\n')
f.write(inspect.cleandoc("""
import
../config/curves,
../towers,
../io/io_towers
"""))
f.write('\n\n')
f.write(FrobMap)
f.write('\n\n')
f.write(FrobPsi)
print(f'Successfully created {curve}_frobenius.nim')
print(inspect.cleandoc("""\n
For testing you can verify the following invariants:
Galbraith-Lin-Scott, 2008, Theorem 1
Fuentes-Castaneda et al, 2011, Equation (2)
ψ(ψ(P)) - t*ψ(P) + p*P == Infinity
Galbraith-Scott, 2008, Lemma 1
The cyclotomic polynomial with (ψ(P)) == Infinity
Hence for embedding degree k=12
ψ⁴(P) - ψ²(P) + P == Infinity
for embedding degree k=6
ψ²(P) - ψ(P) + P == Infinity
"""))

134
sage/derive_pairing.sage Normal file
View File

@ -0,0 +1,134 @@
#!/usr/bin/sage
# vim: syntax=python
# vim: set ts=2 sw=2 et:
# 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.
# ############################################################
#
# Pairing constants
#
# ############################################################
# Imports
# ---------------------------------------------------------
import os
import inspect, textwrap
# Working directory
# ---------------------------------------------------------
os.chdir(os.path.dirname(__file__))
# Sage imports
# ---------------------------------------------------------
# Accelerate arithmetic by accepting probabilistic proofs
from sage.structure.proof.all import arithmetic
arithmetic(False)
load('curves.sage')
# Utilities
# ---------------------------------------------------------
# Code generators
# ---------------------------------------------------------
def genAteParam(curve_name, curve_config):
u = curve_config[curve_name]['field']['param']
family = curve_config[curve_name]['field']['family']
if family == 'BLS12':
ate_param = u
ate_comment = ' # BLS12 Miller loop is parametrized by u\n'
elif family == 'BN':
ate_param = 6*u+2
ate_comment = ' # BN Miller loop is parametrized by 6u+2\n'
else:
raise ValueError(f'family: {family} is not implemented')
buf = '# The bit count must be exact for the Miller loop\n'
buf += f'const {curve_name}_pairing_ate_param* = block:\n'
buf += ate_comment
ate_bits = int(ate_param).bit_length()
naf_bits = int(3*ate_param).bit_length() - ate_bits
buf += f' # +{naf_bits} to bitlength so that we can mul by 3 for NAF encoding\n'
buf += f' BigInt[{ate_bits}+{naf_bits}].fromHex"0x{Integer(abs(ate_param)).hex()}"\n\n'
buf += f'const {curve_name}_pairing_ate_param_isNeg* = {"true" if ate_param < 0 else "false"}'
return buf
def genFinalExp(curve_name, curve_config):
p = curve_config[curve_name]['field']['modulus']
r = curve_config[curve_name]['field']['order']
k = curve_config[curve_name]['tower']['embedding_degree']
family = curve_config[curve_name]['field']['family']
fexp = (p^k - 1)//r
if family == 'BLS12':
fexp *= 3
buf = f'const {curve_name}_pairing_finalexponent* = block:\n'
buf += f' # (p^{k} - 1) / r' + (' * 3' if family == 'BLS12' else '')
buf += '\n'
buf += f' BigInt[{int(fexp).bit_length()}].fromHex"0x{Integer(fexp).hex()}"'
return buf
# CLI
# ---------------------------------------------------------
if __name__ == "__main__":
# Usage
# BLS12-381
# sage sage/derive_pairing.sage BLS12_381
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("curve",nargs="+")
args = parser.parse_args()
curve = args.curve[0]
if curve not in Curves:
raise ValueError(
curve +
' is not one of the available curves: ' +
str(Curves.keys())
)
else:
ate = genAteParam(curve, Curves)
fexp = genFinalExp(curve, Curves)
with open(f'{curve.lower()}_pairing.nim', 'w') as f:
f.write(copyright())
f.write('\n\n')
f.write(inspect.cleandoc("""
import
../config/[curves, type_bigint],
../io/io_bigints
# Slow generic implementation
# ------------------------------------------------------------
"""))
f.write('\n\n')
f.write(ate)
f.write('\n\n')
f.write(fexp)
f.write('\n\n')
f.write(inspect.cleandoc("""
# Addition chain
# ------------------------------------------------------------
"""))
print(f'Successfully created {curve}_pairing.nim')

View File

@ -1,165 +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.
# ############################################################
#
# BLS12-377
# Frobenius Endomorphism
# Untwist-Frobenius-Twist isogeny
#
# ############################################################
# Parameters
x = 3 * 2^46 * (7 * 13 * 499) + 1
p = (x - 1)^2 * (x^4 - x^2 + 1)//3 + x
r = x^4 - x^2 + 1
t = x + 1
print('p : ' + p.hex())
print('r : ' + r.hex())
print('t : ' + t.hex())
# Finite fields
Fp = GF(p)
K2.<u> = PolynomialRing(Fp)
Fp2.<beta> = Fp.extension(u^2+5) # √-5 quadratic non-residue
# K6.<v> = PolynomialRing(F2)
# Fp6.<eta> = Fp2.extension(v^3-Fp2([0, 1])
# K12.<w> = PolynomialRing(Fp6)
# Fp12.<gamma> = Fp6.extension(w^2-eta)
# Curves
b = 1
SNR = Fp2([0, 1]) # √-5 sextic non-residue
G1 = EllipticCurve(Fp, [0, b])
G2 = EllipticCurve(Fp2, [0, b/SNR])
# Utilities
def fp2_to_hex(a):
v = vector(a)
return '0x' + Integer(v[0]).hex() + ' + β * ' + '0x' + Integer(v[1]).hex()
# Frobenius map constants
print('\nFrobenius extension field constants')
FrobConst_map = SNR^((p-1)/6)
FrobConst_map_list = []
cur = Fp2([1, 0])
for i in range(6):
FrobConst_map_list.append(cur)
print(f'FrobConst_map_{i} : {fp2_to_hex(cur)}')
cur *= FrobConst_map
print('')
for i in range(6):
print(f'FrobConst_map_{i}_pow2 : {fp2_to_hex(FrobConst_map_list[i]*conjugate(FrobConst_map_list[i]))}')
print('')
for i in range(6):
print(f'FrobConst_map_{i}_pow3 : {fp2_to_hex(FrobConst_map_list[i]**2 * conjugate(FrobConst_map_list[i]))}')
# Frobenius psi constants (D type: use SNR, M type use 1/SNR)
print('\nψ (Psi) - Untwist-Frobenius-Twist constants')
FrobConst_psi = SNR^((p-1)/6)
FrobConst_psi_2 = FrobConst_psi * FrobConst_psi
FrobConst_psi_3 = FrobConst_psi_2 * FrobConst_psi
print('FrobConst_psi : ' + fp2_to_hex(FrobConst_psi))
print('FrobConst_psi_2 : ' + fp2_to_hex(FrobConst_psi_2))
print('FrobConst_psi_3 : ' + fp2_to_hex(FrobConst_psi_3))
print('')
FrobConst_psi2_2 = FrobConst_psi_2 * FrobConst_psi_2**p
FrobConst_psi2_3 = FrobConst_psi_3 * FrobConst_psi_3**p
print('FrobConst_psi2_2 : ' + fp2_to_hex(FrobConst_psi2_2))
print('FrobConst_psi2_3 : ' + fp2_to_hex(FrobConst_psi2_3))
print('')
FrobConst_psi3_2 = FrobConst_psi_2 * FrobConst_psi2_2**p
FrobConst_psi3_3 = FrobConst_psi_3 * FrobConst_psi2_3**p
print('FrobConst_psi3_2 : ' + fp2_to_hex(FrobConst_psi3_2))
print('FrobConst_psi3_3 : ' + fp2_to_hex(FrobConst_psi3_3))
# Recap, with ξ (xi) the sextic non-residue
# psi_2 = (ξ^((p-1)/6))^2 = ξ^((p-1)/3)
# psi_3 = psi_2 * ξ^((p-1)/6) = ξ^((p-1)/3) * ξ^((p-1)/6) = ξ^((p-1)/2)
#
# Reminder, in 𝔽p2, frobenius(a) = a^p = conj(a)
# psi2_2 = psi_2 * psi_2^p = ξ^((p-1)/3) * ξ^((p-1)/3)^p = ξ^((p-1)/3) * frobenius(ξ)^((p-1)/3)
# = norm(ξ)^((p-1)/3)
# psi2_3 = psi_3 * psi_3^p = ξ^((p-1)/2) * ξ^((p-1)/2)^p = ξ^((p-1)/2) * frobenius(ξ)^((p-1)/2)
# = norm(ξ)^((p-1)/2)
#
# In Fp²:
# - quadratic non-residues respect the equation a^((p²-1)/2) ≡ -1 (mod p²) by the Legendre symbol
# - sextic non-residues are also quadratic non-residues so ξ^((p²-1)/2) ≡ -1 (mod p²)
#
# We have norm(ξ)^((p-1)/2) = (ξ*frobenius(ξ))^((p-1)/2) = (ξ*(ξ^p))^((p-1)/2) = ξ^(p+1)^(p-1)/2
# = ξ^((p²-1)/2)
# And ξ^((p²-1)/2) ≡ -1 (mod p²)
# So psi2_3 ≡ -1 (mod p²)
#
# TODO: explain why psi3_2 = [0, -1]
# Frobenius Fp2
A = Fp2([5, 7])
Aconj = Fp2([5, -7])
AF = A.frobenius(1) # or pth_power(1)
AF2 = A.frobenius(2)
AF3 = A.frobenius(3)
print('')
print('A : ' + fp2_to_hex(A))
print('A conjugate: ' + fp2_to_hex(Aconj))
print('')
print('AF1 : ' + fp2_to_hex(AF))
print('AF2 : ' + fp2_to_hex(AF2))
print('AF3 : ' + fp2_to_hex(AF3))
def psi(P):
(Px, Py, Pz) = P
return G2([
FrobConst_psi_2 * Px.frobenius(),
FrobConst_psi_3 * Py.frobenius()
# Pz.frobenius() - Always 1 after extract
])
def psi2(P):
(Px, Py, Pz) = P
return G2([
FrobConst_psi2_2 * Px.frobenius(2),
FrobConst_psi2_3 * Py.frobenius(2)
# Pz - Always 1 after extract
])
# Test generator
set_random_seed(1337)
# Vectors
print('\nTest vectors:')
for i in range(4):
P = G2.random_point()
(Px, Py, Pz) = P
vPx = vector(Px)
vPy = vector(Py)
# Pz = vector(Pz)
print(f'\nTest {i}')
print(' Px: ' + Integer(vPx[0]).hex() + ' + β * ' + Integer(vPx[1]).hex())
print(' Py: ' + Integer(vPy[0]).hex() + ' + β * ' + Integer(vPy[1]).hex())
# Galbraith-Lin-Scott, 2008, Theorem 1
# Fuentes-Castaneda et al, 2011, Equation (2)
assert psi(psi(P)) - t*psi(P) + p*P == G2([0, 1, 0])
# Galbraith-Scott, 2008, Lemma 1
# k-th cyclotomic polynomial with k = 12
assert psi2(psi2(P)) - psi2(P) + P == G2([0, 1, 0])
assert psi(psi(P)) == psi2(P)
(Qx, Qy, Qz) = psi(P)
vQx = vector(Qx)
vQy = vector(Qy)
print(' Qx: ' + Integer(vQx[0]).hex() + ' + β * ' + Integer(vQx[1]).hex())
print(' Qy: ' + Integer(vQy[0]).hex() + ' + β * ' + Integer(vQy[1]).hex())

View File

@ -1,180 +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.
# ############################################################
#
# BLS12-381
# Frobenius Endomorphism
# Untwist-Frobenius-Twist isogeny
#
# ############################################################
# Parameters
x = -(2^63 + 2^62 + 2^60 + 2^57 + 2^48 + 2^16)
p = (x - 1)^2 * (x^4 - x^2 + 1)//3 + x
r = x^4 - x^2 + 1
t = x + 1
print('p : ' + p.hex())
print('r : ' + r.hex())
print('t : ' + t.hex())
print('p (mod r) == t-1 (mod r) == 0x' + (p % r).hex())
# Finite fields
Fp = GF(p)
K2.<u> = PolynomialRing(Fp)
Fp2.<beta> = Fp.extension(u^2+1)
# Curves
b = 4
SNR = Fp2([1, 1])
G1 = EllipticCurve(Fp, [0, b])
G2 = EllipticCurve(Fp2, [0, b*SNR])
# https://crypto.stackexchange.com/questions/64064/order-of-twisted-curve-in-pairings
# https://math.stackexchange.com/questions/144194/how-to-find-the-order-of-elliptic-curve-over-finite-field-extension
cofactorG1 = G1.order() // r
cofactorG2 = G2.order() // r
print('')
print('cofactor G1: ' + cofactorG1.hex())
print('cofactor G2: ' + cofactorG2.hex())
print('')
# Utilities
def fp2_to_hex(a):
v = vector(a)
return '0x' + Integer(v[0]).hex() + ' + β * ' + '0x' + Integer(v[1]).hex()
# Frobenius map constants
print('\nFrobenius extension field constants')
FrobConst_map = SNR^((p-1)/6)
FrobConst_map_list = []
cur = Fp2([1, 0])
for i in range(6):
FrobConst_map_list.append(cur)
print(f'FrobConst_map_{i} : {fp2_to_hex(cur)}')
cur *= FrobConst_map
print('')
for i in range(6):
print(f'FrobConst_map_{i}_pow2 : {fp2_to_hex(FrobConst_map_list[i]*conjugate(FrobConst_map_list[i]))}')
print('')
for i in range(6):
print(f'FrobConst_map_{i}_pow3 : {fp2_to_hex(FrobConst_map_list[i]**2 * conjugate(FrobConst_map_list[i]))}')
# Frobenius psi constants (D type: use SNR, M type use 1/SNR)
print('\nψ (Psi) - Untwist-Frobenius-Twist constants')
print('1/sextic_non_residue: ' + fp2_to_hex(1/SNR))
FrobConst_psi = (1/SNR)^((p-1)/6)
FrobConst_psi_2 = FrobConst_psi * FrobConst_psi
FrobConst_psi_3 = FrobConst_psi_2 * FrobConst_psi
print('FrobConst_psi : ' + fp2_to_hex(FrobConst_psi))
print('FrobConst_psi_2 : ' + fp2_to_hex(FrobConst_psi_2))
print('FrobConst_psi_3 : ' + fp2_to_hex(FrobConst_psi_3))
print('')
FrobConst_psi2_2 = FrobConst_psi_2 * FrobConst_psi_2**p
FrobConst_psi2_3 = FrobConst_psi_3 * FrobConst_psi_3**p
print('FrobConst_psi2_2 : ' + fp2_to_hex(FrobConst_psi2_2))
print('FrobConst_psi2_3 : ' + fp2_to_hex(FrobConst_psi2_3))
print('')
FrobConst_psi3_2 = FrobConst_psi_2 * FrobConst_psi2_2**p
FrobConst_psi3_3 = FrobConst_psi_3 * FrobConst_psi2_3**p
print('FrobConst_psi3_2 : ' + fp2_to_hex(FrobConst_psi3_2))
print('FrobConst_psi3_3 : ' + fp2_to_hex(FrobConst_psi3_3))
# Recap, with ξ (xi) the sextic non-residue
# psi_2 = ((1/ξ)^((p-1)/6))^2 = (1/ξ)^((p-1)/3)
# psi_3 = psi_2 * (1/ξ)^((p-1)/6) = (1/ξ)^((p-1)/3) * (1/ξ)^((p-1)/6) = (1/ξ)^((p-1)/2)
#
# Reminder, in 𝔽p2, frobenius(a) = a^p = conj(a)
# psi2_2 = psi_2 * psi_2^p = (1/ξ)^((p-1)/3) * (1/ξ)^((p-1)/3)^p = (1/ξ)^((p-1)/3) * frobenius((1/ξ))^((p-1)/3)
# = norm(1/ξ)^((p-1)/3)
# psi2_3 = psi_3 * psi_3^p = (1/ξ)^((p-1)/2) * (1/ξ)^((p-1)/2)^p = (1/ξ)^((p-1)/2) * frobenius((1/ξ))^((p-1)/2)
# = norm(1/ξ)^((p-1)/2)
#
# In Fp²:
# - quadratic non-residues respect the equation a^((p²-1)/2) ≡ -1 (mod p²) by the Legendre symbol
# - sextic non-residues are also quadratic non-residues so ξ^((p²-1)/2) ≡ -1 (mod p²)
# - QRT(1/a) = QRT(a) with QRT the quadratic residuosity test
#
# We have norm(ξ)^((p-1)/2) = (ξ*frobenius(ξ))^((p-1)/2) = (ξ*(ξ^p))^((p-1)/2) = ξ^(p+1)^(p-1)/2
# = ξ^((p²-1)/2)
# And ξ^((p²-1)/2) ≡ -1 (mod p²)
# So psi2_3 ≡ -1 (mod p²)
#
# TODO: explain why psi3_2 = [0, -1]
# Frobenius Fp2
A = Fp2([5, 7])
Aconj = Fp2([5, -7])
AF = A.frobenius(1) # or pth_power(1)
AF2 = A.frobenius(2)
AF3 = A.frobenius(3)
print('')
print('A : ' + fp2_to_hex(A))
print('A conjugate: ' + fp2_to_hex(Aconj))
print('')
print('AF1 : ' + fp2_to_hex(AF))
print('AF2 : ' + fp2_to_hex(AF2))
print('AF3 : ' + fp2_to_hex(AF3))
def psi(P):
(Px, Py, Pz) = P
return G2([
FrobConst_psi_2 * Px.frobenius(),
FrobConst_psi_3 * Py.frobenius()
# Pz.frobenius() - Always 1 after extract
])
def psi2(P):
(Px, Py, Pz) = P
return G2([
FrobConst_psi2_2 * Px.frobenius(2),
FrobConst_psi2_3 * Py.frobenius(2)
# Pz - Always 1 after extract
])
def clearCofactorG2(P):
return cofactorG2 * P
# Test generator
set_random_seed(1337)
# Vectors
print('\nTest vectors:')
for i in range(4):
P = G2.random_point()
P = clearCofactorG2(P)
(Px, Py, Pz) = P
vPx = vector(Px)
vPy = vector(Py)
# Pz = vector(Pz)
print(f'\nTest {i}')
print(' Px: ' + Integer(vPx[0]).hex() + ' + β * ' + Integer(vPx[1]).hex())
print(' Py: ' + Integer(vPy[0]).hex() + ' + β * ' + Integer(vPy[1]).hex())
# Galbraith-Lin-Scott, 2008, Theorem 1
# Fuentes-Castaneda et al, 2011, Equation (2)
assert psi(psi(P)) - t*psi(P) + p*P == G2([0, 1, 0]), "Always true"
# Galbraith-Scott, 2008, Lemma 1
# k-th cyclotomic polynomial with k = 12
assert psi2(psi2(P)) - psi2(P) + P == G2([0, 1, 0]), "Always true"
assert psi(psi(P)) == psi2(P), "Always true"
(Qx, Qy, Qz) = psi(P)
vQx = vector(Qx)
vQy = vector(Qy)
print(' Qx: ' + Integer(vQx[0]).hex() + ' + β * ' + Integer(vQx[1]).hex())
print(' Qy: ' + Integer(vQy[0]).hex() + ' + β * ' + Integer(vQy[1]).hex())
assert psi(P) == (p % r) * P, "Can be false if the cofactor was not cleared"

View File

@ -1,184 +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.
# ############################################################
#
# BN254-Nogami
# Frobenius Endomorphism
# Untwist-Frobenius-Twist isogeny
#
# ############################################################
# Parameters
x = -(2^62 + 2^55 + 1)
p = 36*x^4 + 36*x^3 + 24*x^2 + 6*x + 1
r = 36*x^4 + 36*x^3 + 18*x^2 + 6*x + 1
t = 6*x^2 + 1
print('p : ' + p.hex())
print('r : ' + r.hex())
print('t : ' + t.hex())
print('p (mod r) == t-1 (mod r) == 0x' + (p % r).hex())
# Finite fields
Fp = GF(p)
K2.<u> = PolynomialRing(Fp)
Fp2.<beta> = Fp.extension(u^2+1)
# Curves
b = 2
SNR = Fp2([1, 1])
G1 = EllipticCurve(Fp, [0, b])
G2 = EllipticCurve(Fp2, [0, b/SNR])
# https://crypto.stackexchange.com/questions/64064/order-of-twisted-curve-in-pairings
# https://math.stackexchange.com/questions/144194/how-to-find-the-order-of-elliptic-curve-over-finite-field-extension
cofactorG1 = G1.order() // r
cofactorG2 = G2.order() // r
print('')
print('cofactor G1: ' + cofactorG1.hex())
print('cofactor G2: ' + cofactorG2.hex())
print('')
# Utilities
def fp2_to_hex(a):
v = vector(a)
return '0x' + Integer(v[0]).hex() + ' + β * ' + '0x' + Integer(v[1]).hex()
# Frobenius map constants
print('\nFrobenius extension field constants')
FrobConst_map = SNR^((p-1)/6)
FrobConst_map_list = []
cur = Fp2([1, 0])
for i in range(6):
FrobConst_map_list.append(cur)
print(f'FrobConst_map_{i} : {fp2_to_hex(cur)}')
cur *= FrobConst_map
print('')
for i in range(6):
print(f'FrobConst_map_{i}_pow2 : {fp2_to_hex(FrobConst_map_list[i]*conjugate(FrobConst_map_list[i]))}')
print('')
for i in range(6):
print(f'FrobConst_map_{i}_pow3 : {fp2_to_hex(FrobConst_map_list[i]**2 * conjugate(FrobConst_map_list[i]))}')
# Frobenius psi constants (D type: use SNR, M type use 1/SNR)
print('\nψ (Psi) - Untwist-Frobenius-Twist constants')
FrobConst_psi = SNR^((p-1)/6)
FrobConst_psi_2 = FrobConst_psi * FrobConst_psi
FrobConst_psi_3 = FrobConst_psi_2 * FrobConst_psi
print('FrobConst_psi : ' + fp2_to_hex(FrobConst_psi))
print('FrobConst_psi_2 : ' + fp2_to_hex(FrobConst_psi_2))
print('FrobConst_psi_3 : ' + fp2_to_hex(FrobConst_psi_3))
print('')
FrobConst_psi2_2 = FrobConst_psi_2 * FrobConst_psi_2^p
FrobConst_psi2_3 = FrobConst_psi_3 * FrobConst_psi_3^p
print('FrobConst_psi2_2 : ' + fp2_to_hex(FrobConst_psi2_2))
print('FrobConst_psi2_3 : ' + fp2_to_hex(FrobConst_psi2_3))
print('')
FrobConst_psi3_2 = FrobConst_psi_2 * FrobConst_psi2_2^p
FrobConst_psi3_3 = FrobConst_psi_3 * FrobConst_psi2_3^p
print('FrobConst_psi3_2 : ' + fp2_to_hex(FrobConst_psi3_2))
print('FrobConst_psi3_3 : ' + fp2_to_hex(FrobConst_psi3_3))
# Recap, with ξ (xi) the sextic non-residue
# psi_2 = (ξ^((p-1)/6))^2 = ξ^((p-1)/3)
# psi_3 = psi_2 * ξ^((p-1)/6) = ξ^((p-1)/3) * ξ^((p-1)/6) = ξ^((p-1)/2)
#
# Reminder, in 𝔽p2, frobenius(a) = a^p = conj(a)
# psi2_2 = psi_2 * psi_2^p = ξ^((p-1)/3) * ξ^((p-1)/3)^p = ξ^((p-1)/3) * frobenius(ξ)^((p-1)/3)
# = norm(ξ)^((p-1)/3)
# psi2_3 = psi_3 * psi_3^p = ξ^((p-1)/2) * ξ^((p-1)/2)^p = ξ^((p-1)/2) * frobenius(ξ)^((p-1)/2)
# = norm(ξ)^((p-1)/2)
#
# In Fp²:
# - quadratic non-residues respect the equation a^((p²-1)/2) ≡ -1 (mod p²) by the Legendre symbol
# - sextic non-residues are also quadratic non-residues so ξ^((p²-1)/2) ≡ -1 (mod p²)
#
# We have norm(ξ)^((p-1)/2) = (ξ*frobenius(ξ))^((p-1)/2) = (ξ*(ξ^p))^((p-1)/2) = ξ^(p+1)^(p-1)/2
# = ξ^((p²-1)/2)
# And ξ^((p²-1)/2) ≡ -1 (mod p²)
# So psi2_3 ≡ -1 (mod p²)
# Frobenius Fp2
A = Fp2([5, 7])
Aconj = Fp2([5, -7])
AF = A.frobenius(1) # or pth_power(1)
AF2 = A.frobenius(2)
AF3 = A.frobenius(3)
print('')
print('A : ' + fp2_to_hex(A))
print('A conjugate: ' + fp2_to_hex(Aconj))
print('')
print('AF1 : ' + fp2_to_hex(AF))
print('AF2 : ' + fp2_to_hex(AF2))
print('AF3 : ' + fp2_to_hex(AF3))
def psi(P):
(Px, Py, Pz) = P
return G2([
FrobConst_psi_2 * Px.frobenius(1),
FrobConst_psi_3 * Py.frobenius(1)
# Pz.frobenius() - Always 1 after extract
])
def psi2(P):
(Px, Py, Pz) = P
return G2([
FrobConst_psi2_2 * Px.frobenius(2),
FrobConst_psi2_3 * Py.frobenius(2)
# Pz - Always 1 after extract
])
def clearCofactorG2(P):
return cofactorG2 * P
# Test generator
set_random_seed(1337)
# Vectors
print('\nTest vectors:')
for i in range(4):
P = G2.random_point()
P = clearCofactorG2(P)
(Px, Py, Pz) = P
vPx = vector(Px)
vPy = vector(Py)
# vPz = vector(Pz)
print(f'\nTest {i}')
print(' Px: ' + Integer(vPx[0]).hex() + ' + β * ' + Integer(vPx[1]).hex())
print(' Py: ' + Integer(vPy[0]).hex() + ' + β * ' + Integer(vPy[1]).hex())
# print(' Pz: ' + Integer(vPz[0]).hex() + ' + β * ' + Integer(vPz[1]).hex())
# Galbraith-Lin-Scott, 2008, Theorem 1
# Fuentes-Castaneda et al, 2011, Equation (2)
assert psi(psi(P)) - t*psi(P) + p*P == G2([0, 1, 0])
# Galbraith-Scott, 2008, Lemma 1
# k-th cyclotomic polynomial with k = 12
assert psi2(psi2(P)) - psi2(P) + P == G2([0, 1, 0])
assert psi(psi(P)) == psi2(P)
(Qx, Qy, Qz) = psi(P)
vQx = vector(Qx)
vQy = vector(Qy)
print(' Qx: ' + Integer(vQx[0]).hex() + ' + β * ' + Integer(vQx[1]).hex())
print(' Qy: ' + Integer(vQy[0]).hex() + ' + β * ' + Integer(vQy[1]).hex())
(Rx, Ry, Rz) = (p % r) * P
vRx = vector(Rx)
vRy = vector(Ry)
print(' Rx: ' + Integer(vRx[0]).hex() + ' + β * ' + Integer(vRx[1]).hex())
print(' Ry: ' + Integer(vRy[0]).hex() + ' + β * ' + Integer(vRy[1]).hex())
assert psi(P) == (p % r) * P, "Can be false if the cofactor was not cleared"

View File

@ -1,178 +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.
# ############################################################
#
# BN254-Snarks
# Frobenius Endomorphism
# Untwist-Frobenius-Twist isogeny
#
# ############################################################
# Parameters
x = Integer('0x44E992B44A6909F1')
p = 36*x^4 + 36*x^3 + 24*x^2 + 6*x + 1
r = 36*x^4 + 36*x^3 + 18*x^2 + 6*x + 1
t = 6*x^2 + 1
cofactor = 1
print('p : ' + p.hex())
print('r : ' + r.hex())
print('t : ' + t.hex())
print('p (mod r) == t-1 (mod r) == 0x' + (p % r).hex())
# Finite fields
Fp = GF(p)
K2.<u> = PolynomialRing(Fp)
Fp2.<beta> = Fp.extension(u^2+1)
# Curves
b = 3
SNR = Fp2([9, 1])
G1 = EllipticCurve(Fp, [0, b])
G2 = EllipticCurve(Fp2, [0, b/SNR])
# https://crypto.stackexchange.com/questions/64064/order-of-twisted-curve-in-pairings
# https://math.stackexchange.com/questions/144194/how-to-find-the-order-of-elliptic-curve-over-finite-field-extension
cofactorG1 = G1.order() // r
cofactorG2 = G2.order() // r
print('')
print('cofactor G1: ' + cofactorG1.hex())
print('cofactor G2: ' + cofactorG2.hex())
print('')
# Utilities
def fp2_to_hex(a):
v = vector(a)
return '0x' + Integer(v[0]).hex() + ' + β * ' + '0x' + Integer(v[1]).hex()
# Frobenius map constants
print('\nFrobenius extension field constants')
FrobConst_map = SNR^((p-1)/6)
FrobConst_map_list = []
cur = Fp2([1, 0])
for i in range(6):
FrobConst_map_list.append(cur)
print(f'FrobConst_map_{i} : {fp2_to_hex(cur)}')
cur *= FrobConst_map
print('')
for i in range(6):
print(f'FrobConst_map_{i}_pow2 : {fp2_to_hex(FrobConst_map_list[i]*conjugate(FrobConst_map_list[i]))}')
print('')
for i in range(6):
print(f'FrobConst_map_{i}_pow3 : {fp2_to_hex(FrobConst_map_list[i]**2 * conjugate(FrobConst_map_list[i]))}')
# Frobenius psi constants (D type: use SNR, M type use 1/SNR)
print('\nψ (Psi) - Untwist-Frobenius-Twist constants')
FrobConst_psi = SNR^((p-1)/6)
FrobConst_psi_2 = FrobConst_psi * FrobConst_psi
FrobConst_psi_3 = FrobConst_psi_2 * FrobConst_psi
print('FrobConst_psi : ' + fp2_to_hex(FrobConst_psi))
print('FrobConst_psi_2 : ' + fp2_to_hex(FrobConst_psi_2))
print('FrobConst_psi_3 : ' + fp2_to_hex(FrobConst_psi_3))
print('')
FrobConst_psi2_2 = FrobConst_psi_2 * FrobConst_psi_2^p
FrobConst_psi2_3 = FrobConst_psi_3 * FrobConst_psi_3^p
print('FrobConst_psi2_2 : ' + fp2_to_hex(FrobConst_psi2_2))
print('FrobConst_psi2_3 : ' + fp2_to_hex(FrobConst_psi2_3))
print('')
FrobConst_psi3_2 = FrobConst_psi_2 * FrobConst_psi2_2^p
FrobConst_psi3_3 = FrobConst_psi_3 * FrobConst_psi2_3^p
print('FrobConst_psi3_2 : ' + fp2_to_hex(FrobConst_psi3_2))
print('FrobConst_psi3_3 : ' + fp2_to_hex(FrobConst_psi3_3))
# Recap, with ξ (xi) the sextic non-residue
# psi_2 = (ξ^((p-1)/6))^2 = ξ^((p-1)/3)
# psi_3 = psi_2 * ξ^((p-1)/6) = ξ^((p-1)/3) * ξ^((p-1)/6) = ξ^((p-1)/2)
#
# Reminder, in 𝔽p2, frobenius(a) = a^p = conj(a)
# psi2_2 = psi_2 * psi_2^p = ξ^((p-1)/3) * ξ^((p-1)/3)^p = ξ^((p-1)/3) * frobenius(ξ)^((p-1)/3)
# = norm(ξ)^((p-1)/3)
# psi2_3 = psi_3 * psi_3^p = ξ^((p-1)/2) * ξ^((p-1)/2)^p = ξ^((p-1)/2) * frobenius(ξ)^((p-1)/2)
# = norm(ξ)^((p-1)/2)
#
# In Fp²:
# - quadratic non-residues respect the equation a^((p²-1)/2) ≡ -1 (mod p²) by the Legendre symbol
# - sextic non-residues are also quadratic non-residues so ξ^((p²-1)/2) ≡ -1 (mod p²)
#
# We have norm(ξ)^((p-1)/2) = (ξ*frobenius(ξ))^((p-1)/2) = (ξ*(ξ^p))^((p-1)/2) = ξ^(p+1)^(p-1)/2
# = ξ^((p²-1)/2)
# And ξ^((p²-1)/2) ≡ -1 (mod p²)
# So psi2_3 ≡ -1 (mod p²)
# Frobenius Fp2
A = Fp2([5, 7])
Aconj = Fp2([5, -7])
AF = A.frobenius(1) # or pth_power(1)
AF2 = A.frobenius(2)
AF3 = A.frobenius(3)
print('')
print('A : ' + fp2_to_hex(A))
print('A conjugate: ' + fp2_to_hex(Aconj))
print('')
print('AF1 : ' + fp2_to_hex(AF))
print('AF2 : ' + fp2_to_hex(AF2))
print('AF3 : ' + fp2_to_hex(AF3))
def psi(P):
(Px, Py, Pz) = P
return G2([
FrobConst_psi_2 * Px.frobenius(1),
FrobConst_psi_3 * Py.frobenius(1)
# Pz.frobenius() - Always 1 after extract
])
def psi2(P):
(Px, Py, Pz) = P
return G2([
FrobConst_psi2_2 * Px.frobenius(2),
FrobConst_psi2_3 * Py.frobenius(2)
# Pz - Always 1 after extract
])
def clearCofactorG2(P):
return cofactorG2 * P
# Test generator
set_random_seed(1337)
# Vectors
print('\nTest vectors:')
for i in range(4):
P = G2.random_point()
P = clearCofactorG2(P)
(Px, Py, Pz) = P
vPx = vector(Px)
vPy = vector(Py)
# vPz = vector(Pz)
print(f'\nTest {i}')
print(' Px: ' + Integer(vPx[0]).hex() + ' + β * ' + Integer(vPx[1]).hex())
print(' Py: ' + Integer(vPy[0]).hex() + ' + β * ' + Integer(vPy[1]).hex())
# print(' Pz: ' + Integer(vPz[0]).hex() + ' + β * ' + Integer(vPz[1]).hex())
# Galbraith-Lin-Scott, 2008, Theorem 1
# Fuentes-Castaneda et al, 2011, Equation (2)
assert psi(psi(P)) - t*psi(P) + p*P == G2([0, 1, 0])
# Galbraith-Scott, 2008, Lemma 1
# k-th cyclotomic polynomial with k = 12
assert psi2(psi2(P)) - psi2(P) + P == G2([0, 1, 0])
assert psi(psi(P)) == psi2(P)
(Qx, Qy, Qz) = psi(P)
vQx = vector(Qx)
vQy = vector(Qy)
print(' Qx: ' + Integer(vQx[0]).hex() + ' + β * ' + Integer(vQx[1]).hex())
print(' Qy: ' + Integer(vQy[0]).hex() + ' + β * ' + Integer(vQy[1]).hex())
assert psi(P) == (p % r) * P, "Can be false if the cofactor was not cleared"

View File

@ -1,223 +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.
# ############################################################
#
# BLS12-381 GLS Endomorphism
# Lattice Decomposition
#
# ############################################################
# Parameters
x = 3 * 2^46 * (7 * 13 * 499) + 1
p = (x - 1)^2 * (x^4 - x^2 + 1)//3 + x
r = x^4 - x^2 + 1
print('p : ' + p.hex())
print('r : ' + r.hex())
# Cube root of unity (mod r) formula for any BLS12 curves
lambda1_r = x^2 - 1
assert lambda1_r^3 % r == 1
print('λᵩ1 : ' + lambda1_r.hex())
print('λᵩ1+r: ' + (lambda1_r+r).hex())
lambda2_r = x^4
assert lambda2_r^3 % r == 1
print('λᵩ2 : ' + lambda2_r.hex())
# Finite fields
F = GF(p)
# Curves
b = 1
G1 = EllipticCurve(F, [0, b])
cofactorG1 = G1.order() // r
print('')
print('cofactor G1: ' + cofactorG1.hex())
print('')
(phi1, phi2) = (root for root in GF(p)(1).nth_root(3, all=True) if root != 1)
print('𝜑1 :' + Integer(phi1).hex())
print('𝜑2 :' + Integer(phi2).hex())
assert phi1^3 % p == 1
assert phi2^3 % p == 1
def clearCofactorG1(P):
return cofactorG1 * P
# Test generator
set_random_seed(1337)
# Check
def checkEndo():
Prand = G1.random_point()
P = clearCofactorG1(Prand)
assert P != G1([0, 1, 0]) # Infinity
(Px, Py, Pz) = P
Qendo1 = G1([Px*phi1 % p, Py, Pz])
Qendo2 = G1([Px*phi2 % p, Py, Pz])
Q1 = lambda1_r * P
Q2 = lambda2_r * P
assert P != Q1
assert P != Q2
assert (F(Px)*F(phi1))^3 == F(Px)^3
assert (F(Px)*F(phi2))^3 == F(Px)^3
assert Q1 == Qendo1
assert Q2 == Qendo1
print('Endomorphism OK with 𝜑1')
checkEndo()
# Decomposition generated by LLL-algorithm and Babai rounding
# to solve the Shortest (Basis) Vector Problem
# Lattice from Guide to Pairing-Based Cryptography
Lat = [
[x^2-1, -1],
[1, x^2]
]
ahat = [x^2, 1]
n = int(r).bit_length()
n = int(((n + 64 - 1) // 64) * 64) # round to next multiple of 64
v = [Integer(a << n) // r for a in ahat]
def pretty_print_lattice(Lat):
latHex = [['0x' + x.hex() if x >= 0 else '-0x' + (-x).hex() for x in vec] for vec in Lat]
maxlen = max([len(cell) for row in latHex for cell in row])
for row in latHex:
row = ' '.join(cell.rjust(maxlen + 2) for cell in row)
print(row)
print('\nLattice')
pretty_print_lattice(Lat)
print('\nbasis:')
print(' 𝛼\u03050: 0x' + v[0].hex())
print(' 𝛼\u03051: 0x' + v[1].hex())
print('')
maxInfNorm = abs(x^2 + 1)
print('\nmax infinity norm:')
print(' ||(a0 , a1)||∞ ≤ 0x' + str(maxInfNorm.hex()))
print(' infinity norm bitlength: ' + str(int(maxInfNorm).bit_length()))
# Contrary to Faz2013 paper, we use the max infinity norm
# to properly dimension our recoding instead of ⌈log2 r/m⌉ + 1
# which fails for some inputs
#
# +1 for signed column
# Optional +1 for handling negative miniscalars
L = int(maxInfNorm).bit_length() + 1
L += 1
def getGLV1_decomp(scalar):
maxLen = (int(r).bit_length() + 1) // 2 + 1
a0 = (v[0] * scalar) >> n
a1 = (v[1] * scalar) >> n
k0 = scalar - a0 * Lat[0][0] - a1 * Lat[1][0]
k1 = 0 - a0 * Lat[0][1] - a1 * Lat[1][1]
assert int(k0).bit_length() <= maxLen
assert int(k1).bit_length() <= maxLen
assert scalar == (k0 + k1 * (lambda1_r % r)) % r
assert scalar == (k0 + k1 * (lambda2_r % r)) % r
return k0, k1
def recodeScalars(k):
m = 2
b = [[0] * L, [0] * L]
b[0][L-1] = 0
for i in range(0, L-1): # l-2 inclusive
b[0][i] = 1 - ((k[0] >> (i+1)) & 1)
for j in range(1, m):
for i in range(0, L):
b[j][i] = k[j] & 1
k[j] = k[j]//2 + (b[j][i] & b[0][i])
return b
def buildLut(P0, P1):
m = 2
lut = [0] * (1 << (m-1))
lut[0] = P0
lut[1] = P0 + P1
return lut
def pointToString(P):
(Px, Py, Pz) = P
return '(x: ' + Integer(Px).hex() + ', y: ' + Integer(Py).hex() + ', z: ' + Integer(Pz).hex() + ')'
def scalarMulEndo(scalar, P0):
m = 2
print('L: ' + str(L))
print('scalar: ' + Integer(scalar).hex())
k0, k1 = getGLV1_decomp(scalar)
print('k0: ' + k0.hex())
print('k1: ' + k1.hex())
P1 = (lambda1_r % r) * P0
(Px, Py, Pz) = P0
P1_endo = G1([Px*phi1 % p, Py, Pz])
assert P1 == P1_endo
expected = scalar * P0
decomp = k0*P0 + k1*P1
assert expected == decomp
print('------ recode scalar -----------')
even = k0 & 1 == 0
if even:
k0 += 1
b = recodeScalars([k0, k1])
print('b0: ' + str(list(reversed(b[0]))))
print('b1: ' + str(list(reversed(b[1]))))
print('------------ lut ---------------')
lut = buildLut(P0, P1)
print('------------ mul ---------------')
# b[0][L-1] is always 0
Q = lut[b[1][L-1]]
for i in range(L-2, -1, -1):
Q *= 2
Q += (1 - 2 * b[0][i]) * lut[b[1][i]]
if even:
Q -= P0
print('final Q: ' + pointToString(Q))
print('expected: ' + pointToString(expected))
assert Q == expected
# Test generator
set_random_seed(1337)
for i in range(1):
print('---------------------------------------')
scalar = randrange(r) # Pick an integer below curve order
P = G1.random_point()
P = clearCofactorG1(P)
scalarMulEndo(scalar, P)

View File

@ -1,375 +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.
# ############################################################
#
# BLS12-381 GLS Endomorphism
# Lattice Decomposition
#
# ############################################################
# Parameters
x = 3 * 2^46 * (7 * 13 * 499) + 1
p = (x - 1)^2 * (x^4 - x^2 + 1)//3 + x
r = x^4 - x^2 + 1
t = x+1
print(' Prime modulus p: 0x' + p.hex())
print(' Curve order r: 0x' + r.hex())
print(' trace t: 0x' + t.hex())
# Finite fields
Fp = GF(p)
K2.<u> = PolynomialRing(Fp)
Fp2.<beta> = Fp.extension(u^2+5)
SNR = Fp2([0, 1]) # Sextic Non-Residue for Sextic Twist
# Curves
b = 1
G1 = EllipticCurve(Fp, [0, b])
G2 = EllipticCurve(Fp2, [0, b/SNR])
# https://crypto.stackexchange.com/questions/64064/order-of-twisted-curve-in-pairings
# https://math.stackexchange.com/questions/144194/how-to-find-the-order-of-elliptic-curve-over-finite-field-extension
cofactorG1 = G1.order() // r
cofactorG2 = G2.order() // r
print('')
print('cofactor G1: ' + cofactorG1.hex())
print('cofactor G2: ' + cofactorG2.hex())
print('')
# Frobenius constants (D type: use SNR, M type use 1/SNR)
FrobConst_psi = SNR^((p-1)/6)
FrobConst_psi_2 = FrobConst_psi * FrobConst_psi
FrobConst_psi_3 = FrobConst_psi_2 * FrobConst_psi
FrobConst_psi2_2 = FrobConst_psi_2 * FrobConst_psi_2^p
FrobConst_psi2_3 = FrobConst_psi_3 * FrobConst_psi_3^p
def psi(P):
(Px, Py, Pz) = P
return G2([
FrobConst_psi_2 * Px.frobenius(1),
FrobConst_psi_3 * Py.frobenius(1)
# Pz.frobenius() - Always 1 after extract
])
def psi2(P):
(Px, Py, Pz) = P
return G2([
FrobConst_psi2_2 * Px.frobenius(2),
FrobConst_psi2_3 * Py.frobenius(2)
# Pz - Always 1 after extract
])
def clearCofactorG2(P):
return cofactorG2 * P
# Test generator
set_random_seed(1337)
# Check
def checkEndo():
P = G2.random_point()
P = clearCofactorG2(P)
(Px, Py, Pz) = P
# Galbraith-Lin-Scott, 2008, Theorem 1
assert psi(psi(P)) - t*psi(P) + p*P == G2([0, 1, 0])
# Galbraith-Scott, 2008, Lemma 1
# k-th cyclotomic polynomial with k = 12
assert psi2(psi2(P)) - psi2(P) + P == G2([0, 1, 0])
assert p % r == (t-1) % r
# assert (p^4 - p^2 + 1) % r == 0
assert ((t-1)^4 - (t-1)^2 + 1) % r == 0
assert (t-1)*P == (p % r)*P
assert (t-1)*P == psi(P)
print('Endomorphism OK')
checkEndo()
def subgroup_check(P):
ppP = psi2(P)
assert x * psi(ppP) - ppP + P == G2([0,1,0])
# Decomposition generated by LLL-algorithm and Babai rounding
# to solve the Shortest (Basis) Vector Problem
#
# TODO: This lattice is generating wrong result
# Lattice from Guide to Pairing-Based Cryptography
# Lat = [
# [ x, 1, 0, 0],
# [ 0, x, 1, 0],
# [ 0, 0, x, 1],
# [ 1, 0,-1, x]
# ]
# ahat = [x*(x^2+1), -(x^2+1), x, -1]
# Lattice from my own LLL+Babai rounding routines
Lat = Matrix([
[-x, 1, 0, 0],
[ 0,-x, 1, 0],
[ 0, 0,-x, 1],
[ 1, 0,-1,-x]
])
# print('Lat: ' + str(Lat))
ahat = vector([r, 0, 0, 0]) * Lat.inverse()
# print('ahat: ' + str(ahat))
n = int(r).bit_length()
n = int(((n + 64 - 1) // 64) * 64) # round to next multiple of 64
v = [Integer(int(a) << n) // r for a in ahat]
def pretty_print_lattice(Lat):
latHex = [['0x' + x.hex() if x >= 0 else '-0x' + (-x).hex() for x in vec] for vec in Lat]
maxlen = max([len(cell) for row in latHex for cell in row])
for row in latHex:
row = ' '.join(cell.rjust(maxlen + 2) for cell in row)
print(row)
print('\nLattice')
pretty_print_lattice(Lat)
print('\nbasis:')
print(' 𝛼\u03050: 0x' + v[0].hex())
print(' 𝛼\u03051: 0x' + v[1].hex())
print(' 𝛼\u03052: 0x' + v[2].hex())
print(' 𝛼\u03053: 0x' + v[3].hex())
print('')
maxInfNorm = abs(x + 2)
print('\nmax infinity norm:')
print(' ||(a0, a1, a2, a3)||∞ ≤ 0x' + str(maxInfNorm.hex()))
print(' infinity norm bitlength: ' + str(int(maxInfNorm).bit_length()))
# Contrary to Faz2013 paper, we use the max infinity norm
# to properly dimension our recoding instead of ⌈log2 r/m⌉ + 1
# which fails for some inputs
# +1 for signed column
# Optional +1 for handling negative miniscalars
L = int(maxInfNorm).bit_length() + 1
L += 1
lambda1 = (t-1) % r
lambda2 = lambda1^2 % r
lambda3 = lambda1^3 % r
def getGLV2_decomp(scalar):
maxLen = (int(r).bit_length() + 3) // 4 + 1
maxLen += 1 # Deal with negative miniscalars
a0 = (v[0] * scalar) >> n
a1 = (v[1] * scalar) >> n
a2 = (v[2] * scalar) >> n
a3 = (v[3] * scalar) >> n
k0 = scalar - a0 * Lat[0][0] - a1 * Lat[1][0] - a2 * Lat[2][0] - a3 * Lat[3][0]
k1 = 0 - a0 * Lat[0][1] - a1 * Lat[1][1] - a2 * Lat[2][1] - a3 * Lat[3][1]
k2 = 0 - a0 * Lat[0][2] - a1 * Lat[1][2] - a2 * Lat[2][2] - a3 * Lat[3][2]
k3 = 0 - a0 * Lat[0][3] - a1 * Lat[1][3] - a2 * Lat[2][3] - a3 * Lat[3][3]
print("k0.bitlength(): " + str(int(k0).bit_length()))
print("k1.bitlength(): " + str(int(k1).bit_length()))
print("k2.bitlength(): " + str(int(k2).bit_length()))
print("k3.bitlength(): " + str(int(k3).bit_length()))
print('k0: ' + k0.hex())
print('k1: ' + k1.hex())
print('k2: ' + k2.hex())
print('k3: ' + k3.hex())
assert scalar == (k0 + k1*lambda1 + k2*lambda2 + k3*lambda3) % r
assert int(k0).bit_length() <= maxLen
assert int(k1).bit_length() <= maxLen
assert int(k2).bit_length() <= maxLen
assert int(k3).bit_length() <= maxLen
return k0, k1, k2, k3
def recodeScalars(k):
m = 4
b = [[0] * L, [0] * L, [0] * L, [0] * L]
b[0][L-1] = 0
for i in range(0, L-1): # l-2 inclusive
b[0][i] = 1 - ((k[0] >> (i+1)) & 1)
for j in range(1, m):
for i in range(0, L):
b[j][i] = k[j] & 1
k[j] = k[j]//2 + (b[j][i] & b[0][i])
return b
def clearBit(v, bit):
return v & ~int(1 << bit)
def buildLut(P0, P_endos):
m = 4
assert len(P_endos) == m-1
lut = [0] * (1 << (m-1))
lut[0] = P0
lutS = [''] * (1 << (m-1))
lutS[0] = 'P0'
endoS = ['P1', 'P2', 'P3']
for u in range(1, 1 << (m-1)):
msb = u.bit_length() - 1
idx = clearBit(u, msb)
lut[u] = lut[clearBit(u, msb)] + P_endos[msb]
lutS[u] = lutS[clearBit(u, msb)] + ' + ' + endoS[msb]
print('LUT: ' + str(lutS))
return lut
def pointToString(P):
(Px, Py, Pz) = P
vPx = vector(Px)
vPy = vector(Py)
result = 'Point(\n'
result += ' Px: ' + Integer(vPx[0]).hex() + ' + β * ' + Integer(vPx[1]).hex() + '\n'
result += ' Py: ' + Integer(vPy[0]).hex() + ' + β * ' + Integer(vPy[1]).hex() + '\n'
result += ')'
return result
def getIndex(glvRecoding, bit):
m = 4
index = 0
for k in range(1, m):
index |= ((glvRecoding[k][bit] & 1) << (k-1))
return index
def updateFactors(factors, recoded, bit):
index = getIndex(recoded, bit)
if recoded[0][bit] == 0: # Positive
factors[0] += 1
factors[1] += (index >> 0) & 1
factors[2] += (index >> 1) & 1
factors[3] += (index >> 2) & 1
else:
factors[0] -= 1
factors[1] -= (index >> 0) & 1
factors[2] -= (index >> 1) & 1
factors[3] -= (index >> 2) & 1
def doubleFactors(factors):
for i in range(len(factors)):
factors[i] *= 2
def printFactors(factors):
print('Multiplication done: ')
for i in range(len(factors)):
print(f' f{i}: {factors[i].hex()}')
def scalarMulEndo(scalar, P0):
m = 4
print('L: ' + str(L))
print('scalar: ' + Integer(scalar).hex())
k0, k1, k2, k3 = getGLV2_decomp(scalar)
P1 = psi(P0)
P2 = psi2(P0)
P3 = psi(P2)
expected = scalar * P0
decomp = k0*P0 + k1*P1 + k2*P2 + k3*P3
print('expected: ' + pointToString(expected))
print('decomp: ' + pointToString(decomp))
assert expected == decomp
# Alternative to adding an extra bit
# to deal with miniscalars
# if k0 < 0: k0 = -k0; P0 = -P0
# if k1 < 0: k1 = -k1; P1 = -P1
# if k2 < 0: k2 = -k2; P2 = -P2
# if k3 < 0: k3 = -k3; P3 = -P3
# assert expected == k0*P0 + k1*P1 + k2*P2 + k3*P3
# Somehow the recoding doesn't cope with first scalar being negative
if k0 < 0:
k0 = -k0
P0 = -P0
print('------ recode scalar -----------')
even = k0 & 1 == 0
print('was even: ' + str(even))
if even:
k0 += 1
b = recodeScalars([k0, k1, k2, k3])
print('b0: ' + str(list(reversed(b[0]))))
print('b1: ' + str(list(reversed(b[1]))))
print('b2: ' + str(list(reversed(b[2]))))
print('b3: ' + str(list(reversed(b[3]))))
print('------------ lut ---------------')
lut = buildLut(P0, [P1, P2, P3])
print('------------ mul ---------------')
# b[0][L-1] is always 0
print(f'L-1: {getIndex(b, L-1)}')
print(f'L-2: {getIndex(b, L-2)}')
print(f'L-3: {getIndex(b, L-3)}')
print(f'L-4: {getIndex(b, L-4)}')
print(f'L-5: {getIndex(b, L-5)}')
print(f'L-6: {getIndex(b, L-6)}')
factors = [0, 0, 0, 0] # Track the decomposed scalar applied (debugging)
updateFactors(factors, b, L-1)
Q = lut[getIndex(b, L-1)]
for bit in range(L-2, -1, -1):
Q *= 2
Q += (1 - 2 * b[0][bit]) * lut[getIndex(b, bit)]
doubleFactors(factors)
updateFactors(factors, b, bit)
if even:
Q -= P0
print('----')
print('final Q: ' + pointToString(Q))
print('expected: ' + pointToString(expected))
print('----')
printFactors(factors)
print('Mul expected:')
print(' k0: ' + k0.hex())
print(' k1: ' + k1.hex())
print(' k2: ' + k2.hex())
print(' k3: ' + k3.hex())
assert Q == expected
# Test generator
set_random_seed(1337)
for i in range(1):
print('---------------------------------------')
scalar = randrange(r) # Pick an integer below curve order
# P = G2.random_point()
# P = clearCofactorG2(P)
scalar = Integer('0x9d432eb58ec68bbc09d10961451d99c7796fb2f795eca603d6feaf3e2a1634b')
P = G2([
Fp2([Integer('0x267401f3ef554fe74ae131d56a10edf14ae40192654901b4618d2bf7af22e77c2a9b79e407348dbd4aad13ca73b33a'),
Integer('0x12dcca838f46a3e0418e5dd8b978362757a16bfd78f0b77f4a1916ace353938389ae3ea228d0eb5020a0aaa58884aec')]),
Fp2([Integer('0x11799118d2e054aabd9f74c0843fecbdc1c0d56f61c61c5854c2507ae2416e48a6b2cd3bc8bf7495a4d3d8270eafe2b'),
Integer('0x823b9f8fb9f8297734a14359fa2c2a0de275e7e638197eaaaa7cff28f9cb3101bdabb570016672455f1ecae625e294')])
])
subgroup_check(P)
scalarMulEndo(scalar, P)

View File

@ -1,227 +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.
# ############################################################
#
# BLS12-381 GLS Endomorphism
# Lattice Decomposition
#
# ############################################################
# Parameters
x = -(2^63 + 2^62 + 2^60 + 2^57 + 2^48 + 2^16)
p = (x - 1)^2 * (x^4 - x^2 + 1)//3 + x
r = x^4 - x^2 + 1
print('p : ' + p.hex())
print('r : ' + r.hex())
# Cube root of unity (mod r) formula for any BLS12 curves
lambda1_r = x^2 - 1
assert lambda1_r^3 % r == 1
print('λᵩ1 : ' + lambda1_r.hex())
print('λᵩ1+r: ' + (lambda1_r+r).hex())
lambda2_r = x^4
assert lambda2_r^3 % r == 1
print('λᵩ2 : ' + lambda2_r.hex())
# Finite fields
F = GF(p)
# Curves
b = 4
G1 = EllipticCurve(F, [0, b])
cofactorG1 = G1.order() // r
print('')
print('cofactor G1: ' + cofactorG1.hex())
print('')
(phi1, phi2) = (root for root in GF(p)(1).nth_root(3, all=True) if root != 1)
print('𝜑1 :' + Integer(phi1).hex())
print('𝜑2 :' + Integer(phi2).hex())
assert phi1^3 % p == 1
assert phi2^3 % p == 1
def clearCofactorG1(P):
return cofactorG1 * P
# Test generator
set_random_seed(1337)
# Check
def checkEndo():
Prand = G1.random_point()
P = clearCofactorG1(Prand)
assert P != G1([0, 1, 0]) # Infinity
(Px, Py, Pz) = P
Qendo1 = G1([Px*phi1 % p, Py, Pz])
Qendo2 = G1([Px*phi2 % p, Py, Pz])
Q1 = lambda1_r * P
Q2 = lambda2_r * P
assert P != Q1
assert P != Q2
assert (F(Px)*F(phi1))^3 == F(Px)^3
assert (F(Px)*F(phi2))^3 == F(Px)^3
assert Q1 == Qendo2
assert Q2 == Qendo2
print('Endomorphism OK with 𝜑2')
checkEndo()
# Decomposition generated by LLL-algorithm and Babai rounding
# to solve the Shortest (Basis) Vector Problem
# Lattice from Guide to Pairing-Based Cryptography
Lat = [
[x^2-1, -1],
[1, x^2]
]
ahat = [x^2, 1]
n = int(r).bit_length()
n = int(((n + 64 - 1) // 64) * 64) # round to next multiple of 64
v = [Integer(a << n) // r for a in ahat]
def pretty_print_lattice(Lat):
latHex = [['0x' + x.hex() if x >= 0 else '-0x' + (-x).hex() for x in vec] for vec in Lat]
maxlen = max([len(cell) for row in latHex for cell in row])
for row in latHex:
row = ' '.join(cell.rjust(maxlen + 2) for cell in row)
print(row)
print('\nLattice')
pretty_print_lattice(Lat)
print('\nbasis:')
print(' 𝛼\u03050: 0x' + v[0].hex())
print(' 𝛼\u03051: 0x' + v[1].hex())
print('')
maxInfNorm = abs(x + 2)
print('\nmax infinity norm:')
print(' ||(a0, a1)||∞ ≤ 0x' + str(maxInfNorm.hex()))
print(' infinity norm bitlength: ' + str(int(maxInfNorm).bit_length()))
# Contrary to Faz2013 paper, we use the max infinity norm
# to properly dimension our recoding instead of ⌈log2 r/m⌉ + 1
# which fails for some inputs
# +1 for signed column
# Optional +1 for handling negative miniscalars
L = int(maxInfNorm).bit_length() + 1
L += 1
def getGLV1_decomp(scalar):
maxLen = (int(r).bit_length() + 1) // 2 + 1
a0 = (v[0] * scalar) >> n
a1 = (v[1] * scalar) >> n
k0 = scalar - a0 * Lat[0][0] - a1 * Lat[1][0]
k1 = 0 - a0 * Lat[0][1] - a1 * Lat[1][1]
assert int(k0).bit_length() <= maxLen
assert int(k1).bit_length() <= maxLen
assert scalar == (k0 + k1 * (lambda1_r % r)) % r
assert scalar == (k0 + k1 * (lambda2_r % r)) % r
return k0, k1
def recodeScalars(k):
m = 2
b = [[0] * L, [0] * L]
b[0][L-1] = 0
for i in range(0, L-1): # l-2 inclusive
b[0][i] = 1 - ((k[0] >> (i+1)) & 1)
for j in range(1, m):
for i in range(0, L):
b[j][i] = k[j] & 1
k[j] = k[j]//2 + (b[j][i] & b[0][i])
return b
def buildLut(P0, P1):
m = 2
lut = [0] * (1 << (m-1))
lut[0] = P0
lut[1] = P0 + P1
return lut
def pointToString(P):
(Px, Py, Pz) = P
return '(x: ' + Integer(Px).hex() + ', y: ' + Integer(Py).hex() + ', z: ' + Integer(Pz).hex() + ')'
def scalarMulEndo(scalar, P0):
m = 2
print('L: ' + str(L))
print('scalar: ' + Integer(scalar).hex())
k0, k1 = getGLV1_decomp(scalar)
print('k0: ' + k0.hex())
print('k1: ' + k1.hex())
P1 = (lambda1_r % r) * P0
(Px, Py, Pz) = P0
P1_endo = G1([Px*phi2 % p, Py, Pz])
assert P1 == P1_endo
expected = scalar * P0
decomp = k0*P0 + k1*P1
assert expected == decomp
print('------ recode scalar -----------')
even = k0 & 1 == 0
if even:
k0 += 1
b = recodeScalars([k0, k1])
print('b0: ' + str(list(reversed(b[0]))))
print('b1: ' + str(list(reversed(b[1]))))
print('------------ lut ---------------')
lut = buildLut(P0, P1)
print('------------ mul ---------------')
# b[0][L-1] is always 0
Q = lut[b[1][L-1]]
for i in range(L-2, -1, -1):
Q *= 2
Q += (1 - 2 * b[0][i]) * lut[b[1][i]]
if even:
Q -= P0
print('final Q: ' + pointToString(Q))
print('expected: ' + pointToString(expected))
assert Q == expected
# Test generator
set_random_seed(1337)
for i in range(1):
print('---------------------------------------')
# scalar = randrange(r) # Pick an integer below curve order
# P = G1.random_point()
# P = clearCofactorG1(P)
scalar = Integer('0xf7e60a832eb77ac47374bc93251360d6c81c21add62767ff816caf11a20d8db')
P = G1([
Integer('0xf9679bb02ee7f352fff6a6467a5e563ec8dd38c86a48abd9e8f7f241f1cdd29d54bc3ddea3a33b62e0d7ce22f3d244a'),
Integer('0x50189b992cf856846b30e52205ff9ef72dc081e9680726586231cbc29a81a162120082585f401e00382d5c86fb1083f'),
Integer(1)
])
scalarMulEndo(scalar, P)

View File

@ -1,415 +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.
# ############################################################
#
# BLS12-381 GLS Endomorphism
# Lattice Decomposition
#
# ############################################################
# Parameters
x = -(2^63 + 2^62 + 2^60 + 2^57 + 2^48 + 2^16)
p = (x - 1)^2 * (x^4 - x^2 + 1)//3 + x
r = x^4 - x^2 + 1
t = x+1
print(' Prime modulus p: 0x' + p.hex())
print(' Curve order r: 0x' + r.hex())
print(' trace t: 0x' + t.hex())
# Finite fields
Fp = GF(p)
K2.<u> = PolynomialRing(Fp)
Fp2.<beta> = Fp.extension(u^2+1)
SNR = Fp2([1, 1]) # Sextic Non-Residue for Sextic Twist
# Curves
b = 4
G1 = EllipticCurve(Fp, [0, b])
G2 = EllipticCurve(Fp2, [0, b*SNR])
# https://crypto.stackexchange.com/questions/64064/order-of-twisted-curve-in-pairings
# https://math.stackexchange.com/questions/144194/how-to-find-the-order-of-elliptic-curve-over-finite-field-extension
cofactorG1 = G1.order() // r
cofactorG2 = G2.order() // r
print('')
print('cofactor G1: ' + cofactorG1.hex())
print('cofactor G2: ' + cofactorG2.hex())
print('')
# Frobenius constants (D type: use SNR, M type use 1/SNR)
FrobConst_psi = (1/SNR)^((p-1)/6)
FrobConst_psi_2 = FrobConst_psi * FrobConst_psi
FrobConst_psi_3 = FrobConst_psi_2 * FrobConst_psi
FrobConst_psi2_2 = FrobConst_psi_2 * FrobConst_psi_2^p
FrobConst_psi2_3 = FrobConst_psi_3 * FrobConst_psi_3^p
def psi(P):
(Px, Py, Pz) = P
return G2([
FrobConst_psi_2 * Px.frobenius(1),
FrobConst_psi_3 * Py.frobenius(1)
# Pz.frobenius() - Always 1 after extract
])
def psi2(P):
(Px, Py, Pz) = P
return G2([
FrobConst_psi2_2 * Px.frobenius(2),
FrobConst_psi2_3 * Py.frobenius(2)
# Pz - Always 1 after extract
])
def clearCofactorG2(P):
return cofactorG2 * P
# Test generator
set_random_seed(1337)
# Check
def checkEndo():
P = G2.random_point()
P = clearCofactorG2(P)
(Px, Py, Pz) = P
# Galbraith-Lin-Scott, 2008, Theorem 1
assert psi(psi(P)) - t*psi(P) + p*P == G2([0, 1, 0])
# Galbraith-Scott, 2008, Lemma 1
# k-th cyclotomic polynomial with k = 12
assert psi2(psi2(P)) - psi2(P) + P == G2([0, 1, 0])
assert p % r == (t-1) % r
# assert (p^4 - p^2 + 1) % r == 0
assert ((t-1)^4 - (t-1)^2 + 1) % r == 0
assert (t-1)*P == (p % r)*P
assert (t-1)*P == psi(P)
print('Endomorphism OK')
checkEndo()
def subgroup_check(P):
ppP = psi2(P)
assert x * psi(ppP) - ppP + P == G2([0,1,0])
# Decomposition generated by LLL-algorithm and Babai rounding
# to solve the Shortest (Basis) Vector Problem
#
# TODO: This lattice is generating wrong result
# Lattice from Guide to Pairing-Based Cryptography
# Lat = [
# [ x, 1, 0, 0],
# [ 0, x, 1, 0],
# [ 0, 0, x, 1],
# [ 1, 0,-1, x]
# ]
# ahat = [x*(x^2+1), -(x^2+1), x, -1]
# Lattice from my own LLL+Babai rounding routines
Lat = Matrix([
[-x, 1, 0, 0],
[ 0,-x, 1, 0],
[ 0, 0,-x, 1],
[ 1, 0,-1,-x]
])
# print('Lat: ' + str(Lat))
ahat = vector([r, 0, 0, 0]) * Lat.inverse()
# print('ahat: ' + str(ahat))
n = int(r).bit_length()
n = int(((n + 64 - 1) // 64) * 64) # round to next multiple of 64
v = [Integer(int(a) << n) // r for a in ahat]
def pretty_print_lattice(Lat):
latHex = [['0x' + x.hex() if x >= 0 else '-0x' + (-x).hex() for x in vec] for vec in Lat]
maxlen = max([len(cell) for row in latHex for cell in row])
for row in latHex:
row = ' '.join(cell.rjust(maxlen + 2) for cell in row)
print(row)
print('\nLattice')
pretty_print_lattice(Lat)
print('\nbasis:')
print(' 𝛼\u03050: 0x' + v[0].hex())
print(' 𝛼\u03051: 0x' + v[1].hex())
print(' 𝛼\u03052: 0x' + v[2].hex())
print(' 𝛼\u03053: 0x' + v[3].hex())
print('')
maxInfNorm = abs(x + 2)
print('\nmax infinity norm:')
print(' ||(a0 , a1 , a2 , a3)||∞ ≤ 0x' + str(maxInfNorm.hex()))
print(' infinity norm bitlength: ' + str(int(maxInfNorm).bit_length()))
# Contrary to Faz2013 paper, we use the max infinity norm
# to properly dimension our recoding instead of ⌈log2 r/m⌉ + 1
# which fails for some inputs
# +1 for signed column
# Optional +1 for handling negative miniscalars
L = int(maxInfNorm).bit_length() + 1
L += 1
lambda1 = (t-1) % r
lambda2 = lambda1^2 % r
lambda3 = lambda1^3 % r
def getGLV2_decomp(scalar):
maxLen = (int(r).bit_length() + 3) // 4 + 1
maxLen += 1 # Deal with negative miniscalars
a0 = (v[0] * scalar) >> n
a1 = (v[1] * scalar) >> n
a2 = (v[2] * scalar) >> n
a3 = (v[3] * scalar) >> n
k0 = scalar - a0 * Lat[0][0] - a1 * Lat[1][0] - a2 * Lat[2][0] - a3 * Lat[3][0]
k1 = 0 - a0 * Lat[0][1] - a1 * Lat[1][1] - a2 * Lat[2][1] - a3 * Lat[3][1]
k2 = 0 - a0 * Lat[0][2] - a1 * Lat[1][2] - a2 * Lat[2][2] - a3 * Lat[3][2]
k3 = 0 - a0 * Lat[0][3] - a1 * Lat[1][3] - a2 * Lat[2][3] - a3 * Lat[3][3]
print("k0.bitlength(): " + str(int(k0).bit_length()))
print("k1.bitlength(): " + str(int(k1).bit_length()))
print("k2.bitlength(): " + str(int(k2).bit_length()))
print("k3.bitlength(): " + str(int(k3).bit_length()))
print('k0: ' + k0.hex())
print('k1: ' + k1.hex())
print('k2: ' + k2.hex())
print('k3: ' + k3.hex())
assert scalar == (k0 + k1*lambda1 + k2*lambda2 + k3*lambda3) % r
assert int(k0).bit_length() <= maxLen
assert int(k1).bit_length() <= maxLen
assert int(k2).bit_length() <= maxLen
assert int(k3).bit_length() <= maxLen
return k0, k1, k2, k3
def recodeScalars(k):
m = 4
b = [[0] * L, [0] * L, [0] * L, [0] * L]
b[0][L-1] = 0
for i in range(0, L-1): # l-2 inclusive
b[0][i] = 1 - ((k[0] >> (i+1)) & 1)
for j in range(1, m):
for i in range(0, L):
b[j][i] = k[j] & 1
k[j] = k[j]//2 + (b[j][i] & b[0][i])
return b
def clearBit(v, bit):
return v & ~int(1 << bit)
def buildLut(P0, P_endos):
m = 4
assert len(P_endos) == m-1
lut = [0] * (1 << (m-1))
lut[0] = P0
lutS = [''] * (1 << (m-1))
lutS[0] = 'P0'
endoS = ['P1', 'P2', 'P3']
for u in range(1, 1 << (m-1)):
msb = u.bit_length() - 1
idx = clearBit(u, msb)
lut[u] = lut[clearBit(u, msb)] + P_endos[msb]
lutS[u] = lutS[clearBit(u, msb)] + ' + ' + endoS[msb]
print('LUT: ' + str(lutS))
return lut
def pointToString(P):
(Px, Py, Pz) = P
vPx = vector(Px)
vPy = vector(Py)
result = 'Point(\n'
result += ' Px: ' + Integer(vPx[0]).hex() + ' + β * ' + Integer(vPx[1]).hex() + '\n'
result += ' Py: ' + Integer(vPy[0]).hex() + ' + β * ' + Integer(vPy[1]).hex() + '\n'
result += ')'
return result
def getIndex(glvRecoding, bit):
m = 4
index = 0
for k in range(1, m):
index |= ((glvRecoding[k][bit] & 1) << (k-1))
return index
def updateFactors(factors, recoded, bit):
index = getIndex(recoded, bit)
if recoded[0][bit] == 0: # Positive
factors[0] += 1
factors[1] += (index >> 0) & 1
factors[2] += (index >> 1) & 1
factors[3] += (index >> 2) & 1
else:
factors[0] -= 1
factors[1] -= (index >> 0) & 1
factors[2] -= (index >> 1) & 1
factors[3] -= (index >> 2) & 1
def doubleFactors(factors):
for i in range(len(factors)):
factors[i] *= 2
def printFactors(factors):
print('Multiplication done: ')
for i in range(len(factors)):
print(f' f{i}: {factors[i].hex()}')
def scalarMulEndo(scalar, P0):
m = 4
print('r bits: ' + str(int(r).bit_length()))
print('L: ' + str(L))
print('scalar: ' + Integer(scalar).hex())
k0, k1, k2, k3 = getGLV2_decomp(scalar)
P1 = psi(P0)
P2 = psi2(P0)
P3 = psi(P2)
expected = scalar * P0
decomp = k0*P0 + k1*P1 + k2*P2 + k3*P3
print('expected: ' + pointToString(expected))
print('decomp: ' + pointToString(decomp))
assert expected == decomp
# Alternative to adding an extra bit
# to deal with miniscalars, unfortunately broken
# for some input
# for example 0x5668a2332db27199dcfb7cbdfca6317c2ff128db26d7df68483e0a095ec8e88f
# which is missing bits for b[2]
# if k0 < 0: k0 = -k0; P0 = -P0
# if k1 < 0: k1 = -k1; P1 = -P1
# if k2 < 0: k2 = -k2; P2 = -P2
# if k3 < 0: k3 = -k3; P3 = -P3
print('------ recode scalar -----------')
even = k0 & 1 == 0
print('was even: ' + str(even))
if even:
k0 += 1
b = recodeScalars([k0, k1, k2, k3])
print('b0: ' + str(list(reversed(b[0]))))
print('b1: ' + str(list(reversed(b[1]))))
print('b2: ' + str(list(reversed(b[2]))))
print('b3: ' + str(list(reversed(b[3]))))
print('------------ lut ---------------')
lut = buildLut(P0, [P1, P2, P3])
print('------------ mul ---------------')
# b[0][L-1] is always 0
print(f'L-1: {getIndex(b, L-1)}')
print(f'L-2: {getIndex(b, L-2)}')
print(f'L-3: {getIndex(b, L-3)}')
print(f'L-4: {getIndex(b, L-4)}')
print(f'L-5: {getIndex(b, L-5)}')
print(f'L-6: {getIndex(b, L-6)}')
factors = [0, 0, 0, 0] # Track the decomposed scalar applied (debugging)
updateFactors(factors, b, L-1)
Q = lut[getIndex(b, L-1)]
for bit in range(L-2, -1, -1):
Q *= 2
Q += (1 - 2 * b[0][bit]) * lut[getIndex(b, bit)]
doubleFactors(factors)
updateFactors(factors, b, bit)
if even:
Q -= P0
print('----')
print('final Q: ' + pointToString(Q))
print('expected: ' + pointToString(expected))
print('----')
printFactors(factors)
print('Mul expected:')
print(' k0: ' + k0.hex())
print(' k1: ' + k1.hex())
print(' k2: ' + k2.hex())
print(' k3: ' + k3.hex())
assert Q == expected
# Test generator
set_random_seed(1337)
for i in range(1):
print('---------------------------------------')
# scalar = randrange(r) # Pick an integer below curve order
# P = G2.random_point()
# P = clearCofactorG2(P)
# scalar = Integer('0x1f7bef2a74f3bf8ac0225a9edfa514bb5666b15e7be3e929059f2ef75f0035a6')
# P = G2([
# Fp2([Integer('0x989f16bcb9da60ef72383e6134ba194f57e30109806304336c0c995e2857ed20bf5b6e03d6fe1424332e9c666cbd10a'),
# Integer('0x16692643cb5e7466e3730d3ea775c7741ac34d670b3be685761a7d6ab722a2673ce374ddab87b7c4d2675ba2199f9121')]),
# Fp2([Integer('0x931e416488bef7cb4a053e4bd86ef44818bc03a5be5b04606b2a4dc1d139a3a452f5f7172f24eeaad84702b73b155bb'),
# Integer('0x192c3e2a6619473216b7bb2447448cdbeb9f7e3c9486b0a05aadf6dcd91d7cb275a5d84c1a362628efffbc8711a62a67')])
# ])
# This integer leads to negative miniscalar for proper handling it requires either:
# 1. Negating it and then negating the corresponding curve point P
# 2. Adding an extra bit to the recoding, which will do the right thing™
#
# For implementation solution 1 is faster:
# - Double + Add is about 5000~8000 cycles on 6 64-bits limbs (BLS12-381)
# - Conditional negate is about 10 cycles per Fp, on G2 projective we have 3 (coords) * 2 (Fp2) * 10 (cycles) ~= 60 cycles
# We need to test the mini scalar, which is 65 bits so 2 Fp so about 2 cycles
# and negate it as well.
# scalar = Integer('0x6448f296d9b1a8d81319a0b789df04c587c6165776ccf39f50a354204aabe0da')
# P = G2([
# Fp2([Integer('0x5adc112fb04bf4ca642d5a7d7343ccd6b93546442d2fff5b9d32c15e456d54884cba49dd7f94ce4ddaad4018e55d0f2'),
# Integer('0x5d1c5bbf5d7a833dc76ba206bfa99c281fc37941be050e18f8c6d267b2376b3634d8ad6eb951e52a6d096315abd17d6')]),
# Fp2([Integer('0x15a959e54981fab9ac3c6f5bfd6fb60a50a916bd43d96a09922a54309b84812736581bfa728670cba864b08b9e391bb9'),
# Integer('0xf5d6d74f1dd3d9c07451340b8f6990fe93a28fe5e176564eb920bf17eb02df8b6f1e626eda5542ff415f89d51943001')])
# ])
# The following input fails in Constantine when negating the base point
# but not when adding an extra bit
# scalar = Integer('0x5668a2332db27199dcfb7cbdfca6317c2ff128db26d7df68483e0a095ec8e88f')
# P = G2([
# Fp2([Integer('0xa8c5649d2df1bae84fd9e8bfcde5113937b3acea22d67ddfedaf1fb8de8c1ef4c70591cf505c24c31e54020c2c510c3'),
# Integer('0xa0553f98229a6a067489c3ee204161c11e96f421b3e9c145dc3865b03e9d4ff6cab14c5b5308ecd31173f954463690c')]),
# Fp2([Integer('0xb29d8dfe18dc41b4826c3a102c1bf8f306cb42433cc36ee38080f47a324c02a678f9daed0a2bc577c18b9865de029f0'),
# Integer('0x558cdabf11e37c5c5e8abd668bbdd71bb3f07f320948ccaac8a207359fffe38424bfd9b1ef1d24b28b2fbb9f76faff1')])
# ])
# The following fails when we have both extra bit and negation of the first
# scalar if it is negative.
# it also uses 65 bits instead of teh expected max of 64
# And triggers an off by 1 when negating
scalar = Integer('0x6448f296d9b1a8d81319a0b789df04c587c6165776ccf39f50a354204aabe0da')
P = G2([
Fp2([Integer('0x5adc112fb04bf4ca642d5a7d7343ccd6b93546442d2fff5b9d32c15e456d54884cba49dd7f94ce4ddaad4018e55d0f2'),
Integer('0x5d1c5bbf5d7a833dc76ba206bfa99c281fc37941be050e18f8c6d267b2376b3634d8ad6eb951e52a6d096315abd17d6')]),
Fp2([Integer('0x15a959e54981fab9ac3c6f5bfd6fb60a50a916bd43d96a09922a54309b84812736581bfa728670cba864b08b9e391bb9'),
Integer('0xf5d6d74f1dd3d9c07451340b8f6990fe93a28fe5e176564eb920bf17eb02df8b6f1e626eda5542ff415f89d51943001')])
])
subgroup_check(P)
scalarMulEndo(scalar, P)

View File

@ -1,219 +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.
# ############################################################
#
# BN254-Snarks GLV Endomorphism
# Lattice Decomposition
#
# ############################################################
# Parameters
x = Integer('0x44E992B44A6909F1')
p = 36*x^4 + 36*x^3 + 24*x^2 + 6*x + 1
r = 36*x^4 + 36*x^3 + 18*x^2 + 6*x + 1
# Cube root of unity (mod r) formula for any BN curves
lambda1_r = (-(36*x^3+18*x^2+6*x+2))
assert lambda1_r^3 % r == 1
print('λᵩ1 : ' + lambda1_r.hex())
print('λᵩ1+r: ' + (lambda1_r+r).hex())
lambda2_r = (36*x^4-1)
assert lambda2_r^3 % r == 1
print('λᵩ2 : ' + lambda2_r.hex())
# Finite fields
F = GF(p)
# Curves
b = 3
G1 = EllipticCurve(F, [0, b])
cofactorG1 = G1.order() // r
assert cofactorG1 == 1, "BN curve have a prime order"
print('')
print('cofactor G1: ' + cofactorG1.hex())
print('')
(phi1, phi2) = (root for root in GF(p)(1).nth_root(3, all=True) if root != 1)
print('𝜑1 :' + Integer(phi1).hex())
print('𝜑2 :' + Integer(phi2).hex())
# Test generator
set_random_seed(1337)
# Check
def checkEndo():
P = G1.random_point()
assert P != G1([0, 1, 0]) # Infinity
(Px, Py, Pz) = P
Qendo1 = G1([Px*phi1 % p, Py, Pz])
Qendo2 = G1([Px*phi2 % p, Py, Pz])
Q1 = lambda1_r * P
Q2 = lambda2_r * P
assert P != Q1
assert P != Q2
assert (F(Px)*F(phi1))^3 == F(Px)^3
assert (F(Px)*F(phi2))^3 == F(Px)^3
assert Q1 == Qendo1
assert Q2 == Qendo1
print('Endomorphism OK with 𝜑1')
checkEndo()
# Decomposition generated by LLL-algorithm and Babai rounding
# to solve the Shortest (Basis) Vector Problem
# Lattice from Guide to Pairing-Based Cryptography
Lat = [
[2*x+1, 6*x^2+4*x+1],
[6*x^2+2*x, -2*x-1]
]
ahat = [2*x+1, 6*x^2+4*x+1]
n = int(r).bit_length()
n = int(((n + 64 - 1) // 64) * 64) # round to next multiple of 64
v = [Integer(a << n) // r for a in ahat]
def pretty_print_lattice(Lat):
latHex = [['0x' + x.hex() if x >= 0 else '-0x' + (-x).hex() for x in vec] for vec in Lat]
maxlen = max([len(cell) for row in latHex for cell in row])
for row in latHex:
row = ' '.join(cell.rjust(maxlen + 2) for cell in row)
print(row)
print('\nLattice')
pretty_print_lattice(Lat)
print('\nbasis:')
print(' 𝛼\u03050: 0x' + v[0].hex())
print(' 𝛼\u03051: 0x' + v[1].hex())
print('')
maxInfNorm = abs(6*x^2+6*x+2)
print('\nmax infinity norm:')
print(' ||(a0, a1)||∞ ≤ 0x' + str(maxInfNorm.hex()))
print(' infinity norm bitlength: ' + str(int(maxInfNorm).bit_length()))
# Contrary to Faz2013 paper, we use the max infinity norm
# to properly dimension our recoding instead of ⌈log2 r/m⌉ + 1
# which fails for some inputs
# +1 for signed column
# Optional +1 for handling negative miniscalars
L = int(maxInfNorm).bit_length() + 1
L += 1
def getGLV2_decomp(scalar):
maxLen = (int(r).bit_length() + 1) // 2 + 1
a0 = (v[0] * scalar) >> n
a1 = (v[1] * scalar) >> n
k0 = scalar - a0 * Lat[0][0] - a1 * Lat[1][0]
k1 = 0 - a0 * Lat[0][1] - a1 * Lat[1][1]
assert int(k0).bit_length() <= maxLen
assert int(k1).bit_length() <= maxLen
assert scalar == (k0 + k1 * (lambda1_r % r)) % r
assert scalar == (k0 + k1 * (lambda2_r % r)) % r
return k0, k1
def recodeScalars(k):
m = 2
b = [[0] * L, [0] * L]
b[0][L-1] = 0
for i in range(0, L-1): # l-2 inclusive
b[0][i] = 1 - ((k[0] >> (i+1)) & 1)
for j in range(1, m):
for i in range(0, L):
b[j][i] = k[j] & 1
k[j] = k[j]//2 + (b[j][i] & b[0][i])
return b
def buildLut(P0, P1):
m = 2
lut = [0] * (1 << (m-1))
lut[0] = P0
lut[1] = P0 + P1
return lut
def pointToString(P):
(Px, Py, Pz) = P
return '(x: ' + Integer(Px).hex() + ', y: ' + Integer(Py).hex() + ', z: ' + Integer(Pz).hex() + ')'
def scalarMulEndo(scalar, P0):
m = 2
print('L: ' + str(L))
print('scalar: ' + Integer(scalar).hex())
k0, k1 = getGLV2_decomp(scalar)
print('k0: ' + k0.hex())
print('k1: ' + k1.hex())
P1 = (lambda1_r % r) * P0
(Px, Py, Pz) = P0
P1_endo = G1([Px*phi1 % p, Py, Pz])
assert P1 == P1_endo
expected = scalar * P0
decomp = k0*P0 + k1*P1
assert expected == decomp
print('------ recode scalar -----------')
even = k0 & 1 == 0
if even:
k0 += 1
b = recodeScalars([k0, k1])
print('b0: ' + str(list(reversed(b[0]))))
print('b1: ' + str(list(reversed(b[1]))))
print('------------ lut ---------------')
lut = buildLut(P0, P1)
print('------------ mul ---------------')
# b[0][L-1] is always 0
Q = lut[b[1][L-1]]
for i in range(L-2, -1, -1):
Q *= 2
Q += (1 - 2 * b[0][i]) * lut[b[1][i]]
if even:
Q -= P0
print('final Q: ' + pointToString(Q))
print('expected: ' + pointToString(expected))
assert Q == expected
# Test generator
set_random_seed(1337)
for i in range(1):
print('---------------------------------------')
# scalar = randrange(r) # Pick an integer below curve order
# P = G1.random_point()
scalar = Integer('0x0e08a292f940cfb361cc82bc24ca564f51453708c9745a9cf8707b11c84bc448')
P = G1([
Integer('0x22d3af0f3ee310df7fc1a2a204369ac13eb4a48d969a27fcd2861506b2dc0cd7'),
Integer('0x1c994169687886ccd28dd587c29c307fb3cab55d796d73a5be0bbf9aab69912e'),
Integer(1)
])
scalarMulEndo(scalar, P)

View File

@ -1,385 +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.
# ############################################################
#
# BN254-Snarks GLS Endomorphism
# Lattice Decomposition
#
# ############################################################
# Parameters
x = Integer('0x44E992B44A6909F1')
p = 36*x^4 + 36*x^3 + 24*x^2 + 6*x + 1
r = 36*x^4 + 36*x^3 + 18*x^2 + 6*x + 1
t = 6*x^2 + 1
print(' Prime modulus p: 0x' + p.hex())
print(' Curve order r: 0x' + r.hex())
print(' trace t: 0x' + t.hex())
# Finite fields
Fp = GF(p)
K2.<u> = PolynomialRing(Fp)
Fp2.<beta> = Fp.extension(u^2+1)
SNR = Fp2([9, 1]) # Sextic Non-Residue for Sextic Twist
# Curves
b = 3
G1 = EllipticCurve(Fp, [0, b])
G2 = EllipticCurve(Fp2, [0, b/SNR])
# https://crypto.stackexchange.com/questions/64064/order-of-twisted-curve-in-pairings
# https://math.stackexchange.com/questions/144194/how-to-find-the-order-of-elliptic-curve-over-finite-field-extension
cofactorG1 = G1.order() // r
cofactorG2 = G2.order() // r
print('')
print('cofactor G1: ' + cofactorG1.hex())
print('cofactor G2: ' + cofactorG2.hex())
print('')
# Frobenius constants (D type: use SNR, M type use 1/SNR)
FrobConst_psi = SNR^((p-1)/6)
FrobConst_psi_2 = FrobConst_psi * FrobConst_psi
FrobConst_psi_3 = FrobConst_psi_2 * FrobConst_psi
FrobConst_psi2_2 = FrobConst_psi_2 * FrobConst_psi_2^p
FrobConst_psi2_3 = FrobConst_psi_3 * FrobConst_psi_3^p
def psi(P):
(Px, Py, Pz) = P
return G2([
FrobConst_psi_2 * Px.frobenius(1),
FrobConst_psi_3 * Py.frobenius(1)
# Pz.frobenius() - Always 1 after extract
])
def psi2(P):
(Px, Py, Pz) = P
return G2([
FrobConst_psi2_2 * Px.frobenius(2),
FrobConst_psi2_3 * Py.frobenius(2)
# Pz - Always 1 after extract
])
def clearCofactorG2(P):
return cofactorG2 * P
# Test generator
set_random_seed(1337)
# Check
def checkEndo():
P = G2.random_point()
P = clearCofactorG2(P)
(Px, Py, Pz) = P
# Galbraith-Lin-Scott, 2008, Theorem 1
assert psi(psi(P)) - t*psi(P) + p*P == G2([0, 1, 0])
# Galbraith-Scott, 2008, Lemma 1
# k-th cyclotomic polynomial with k = 12
assert psi2(psi2(P)) - psi2(P) + P == G2([0, 1, 0])
assert p % r == (t-1) % r
# assert (p^4 - p^2 + 1) % r == 0
assert ((t-1)^4 - (t-1)^2 + 1) % r == 0
assert (t-1)*P == (p % r)*P
assert (t-1)*P == psi(P)
print('Endomorphism OK')
checkEndo()
# Decomposition generated by LLL-algorithm and Babai rounding
# to solve the Shortest (Basis) Vector Problem
# TODO: This Lattice from Guide to Pairing-Based Cryptography
# gives miniscalars bigger than (r/4)+1 = 65 bits
# for unknown reason
# The linear combination is correct though.
# Lattice from Guide to Pairing-Based Cryptography
# Lat = [
# [ - x , 2*x , 2*x+1, - x ],
# [ -2*x-1, x , x+1, x ],
# [ 2*x+1, 0, 2*x , 1],
# [ -1, 2*x+1, 1, 2*x ]
# ]
# ahat = [2*x+1, -(12*x^3+6*x^2+2*x+1), 2*x*(3*x^2+3*x+1), 6*x^2-1]
# Lattice from Galbraith-Scott 2008
Lat = Matrix([
[ x+1, x , x , -2*x ],
[ 2*x+1, -x , -x-1, -x ],
[ 2*x , 2*x+1, 2*x+1, 2*x+1],
[ x-1, 4*x+2, -2*x+1, x-1]
])
ahat = [2*x^2+3*x+1, 12*x^3+8*x^2+x, 6*x^3+4*x^2+x, -2*x^2-x]
n = int(r).bit_length()
n = int(((n + 64 - 1) // 64) * 64) # round to next multiple of 64
v = [Integer(a << n) // r for a in ahat]
def pretty_print_lattice(Lat):
latHex = [['0x' + x.hex() if x >= 0 else '-0x' + (-x).hex() for x in vec] for vec in Lat]
maxlen = max([len(cell) for row in latHex for cell in row])
for row in latHex:
row = ' '.join(cell.rjust(maxlen + 2) for cell in row)
print(row)
print('\nLattice')
pretty_print_lattice(Lat)
print('\nbasis:')
print(' 𝛼\u03050: 0x' + v[0].hex())
print(' 𝛼\u03051: 0x' + v[1].hex())
print(' 𝛼\u03052: 0x' + v[2].hex())
print(' 𝛼\u03053: 0x' + v[3].hex())
print('')
maxInfNorm = abs(5*x + 3)
print('\nmax infinity norm:')
print(' ||(a0 , a1 , a2 , a3)||∞ ≤ 0x' + str(maxInfNorm.hex()))
print(' infinity norm bitlength: ' + str(int(maxInfNorm).bit_length()))
# Contrary to Faz2013 paper, we use the max infinity norm
# to properly dimension our recoding instead of ⌈log2 r/m⌉ + 1
# which fails for some inputs
# +1 for signed column
# Optional +1 for handling negative miniscalars
L = int(maxInfNorm).bit_length() + 1
L += 1
lambda1 = (t-1) % r
lambda2 = lambda1^2 % r
lambda3 = lambda1^3 % r
def getGLV2_decomp(scalar):
maxLen = (int(r).bit_length() + 3) // 4 + 1
a0 = (v[0] * scalar) >> n
a1 = (v[1] * scalar) >> n
a2 = (v[2] * scalar) >> n
a3 = (v[3] * scalar) >> n
print('𝛼0: ' + a0.hex())
print('𝛼1: ' + a1.hex())
print('𝛼2: ' + a2.hex())
print('𝛼3: ' + a3.hex())
print('𝛼3 unred: ' + (v[3] * scalar).hex())
print('')
print('Lat[3][0]: ' + Lat[3][0].hex())
print('a3 * Lat[3][0]: ' + (a3 * Lat[3][0]).hex())
print('')
k0 = scalar - a0 * Lat[0][0] - a1 * Lat[1][0] - a2 * Lat[2][0] - a3 * Lat[3][0]
k1 = 0 - a0 * Lat[0][1] - a1 * Lat[1][1] - a2 * Lat[2][1] - a3 * Lat[3][1]
k2 = 0 - a0 * Lat[0][2] - a1 * Lat[1][2] - a2 * Lat[2][2] - a3 * Lat[3][2]
k3 = 0 - a0 * Lat[0][3] - a1 * Lat[1][3] - a2 * Lat[2][3] - a3 * Lat[3][3]
k = [scalar, 0, 0, 0]
a = [a0, a1, a2, a3]
for i in range(4):
for j in range(4):
elem = a[j] * Lat[j][i]
print(f'a{j} * Lat[{j}][{i}] = {elem.hex()}')
k[i] -= elem
print(f' k{i} = {k[i].hex()}')
print('k: ' + str([ki.hex() for ki in k]))
print("k0.bitlength(): " + str(int(k0).bit_length()))
print("k1.bitlength(): " + str(int(k1).bit_length()))
print("k2.bitlength(): " + str(int(k2).bit_length()))
print("k3.bitlength(): " + str(int(k3).bit_length()))
print('k0: ' + k0.hex())
print('k1: ' + k1.hex())
print('k2: ' + k2.hex())
print('k3: ' + k3.hex())
assert scalar == (k0 + k1*lambda1 + k2*lambda2 + k3*lambda3) % r
assert int(k0).bit_length() <= maxLen
assert int(k1).bit_length() <= maxLen
assert int(k2).bit_length() <= maxLen
assert int(k3).bit_length() <= maxLen
return k0, k1, k2, k3
def recodeScalars(k):
m = 4
b = [[0] * L, [0] * L, [0] * L, [0] * L]
b[0][L-1] = 0
for i in range(0, L-1): # l-2 inclusive
b[0][i] = 1 - ((k[0] >> (i+1)) & 1)
for j in range(1, m):
for i in range(0, L):
b[j][i] = k[j] & 1
k[j] = k[j]//2 + (b[j][i] & b[0][i])
return b
def clearBit(v, bit):
return v & ~int(1 << bit)
def buildLut(P0, P_endos):
m = 4
assert len(P_endos) == m-1
lut = [0] * (1 << (m-1))
lut[0] = P0
lutS = [''] * (1 << (m-1))
lutS[0] = 'P0'
endoS = ['P1', 'P2', 'P3']
for u in range(1, 1 << (m-1)):
msb = u.bit_length() - 1
idx = clearBit(u, msb)
lut[u] = lut[clearBit(u, msb)] + P_endos[msb]
lutS[u] = lutS[clearBit(u, msb)] + ' + ' + endoS[msb]
print('LUT: ' + str(lutS))
return lut
def pointToString(P):
(Px, Py, Pz) = P
vPx = vector(Px)
vPy = vector(Py)
result = 'Point(\n'
result += ' Px: ' + Integer(vPx[0]).hex() + ' + β * ' + Integer(vPx[1]).hex() + '\n'
result += ' Py: ' + Integer(vPy[0]).hex() + ' + β * ' + Integer(vPy[1]).hex() + '\n'
result += ')'
return result
def getIndex(glvRecoding, bit):
m = 4
index = 0
for k in range(1, m):
index |= ((glvRecoding[k][bit] & 1) << (k-1))
return index
def updateFactors(factors, recoded, bit):
index = getIndex(recoded, bit)
if recoded[0][bit] == 0: # Positive
factors[0] += 1
factors[1] += (index >> 0) & 1
factors[2] += (index >> 1) & 1
factors[3] += (index >> 2) & 1
else:
factors[0] -= 1
factors[1] -= (index >> 0) & 1
factors[2] -= (index >> 1) & 1
factors[3] -= (index >> 2) & 1
def doubleFactors(factors):
for i in range(len(factors)):
factors[i] *= 2
def printFactors(factors):
for i in range(len(factors)):
print(f'f{i}: {factors[i].hex()}')
def scalarMulEndo(scalar, P0):
m = 4
print('L: ' + str(L))
print('scalar: ' + Integer(scalar).hex())
k0, k1, k2, k3 = getGLV2_decomp(scalar)
P1 = psi(P0)
P2 = psi2(P0)
P3 = psi(P2)
expected = scalar * P0
decomp = k0*P0 + k1*P1 + k2*P2 + k3*P3
print('expected: ' + pointToString(expected))
print('decomp: ' + pointToString(decomp))
assert expected == decomp
print('------ recode scalar -----------')
even = k0 & 1 == 0
print('was even: ' + str(even))
if even:
k0 += 1
b = recodeScalars([k0, k1, k2, k3])
print('b0: ' + str(list(reversed(b[0]))))
print('b1: ' + str(list(reversed(b[1]))))
print('b2: ' + str(list(reversed(b[2]))))
print('b3: ' + str(list(reversed(b[3]))))
print('------------ lut ---------------')
lut = buildLut(P0, [P1, P2, P3])
print('------------ mul ---------------')
# b[0][L-1] is always 0
print(f'L-1: {getIndex(b, L-1)}')
print(f'L-2: {getIndex(b, L-2)}')
print(f'L-3: {getIndex(b, L-3)}')
print(f'L-4: {getIndex(b, L-4)}')
print(f'L-5: {getIndex(b, L-5)}')
print(f'L-6: {getIndex(b, L-6)}')
factors = [0, 0, 0, 0] # Track the decomposed scalar applied (debugging)
updateFactors(factors, b, L-1)
Q = lut[getIndex(b, L-1)]
for bit in range(L-2, -1, -1):
Q *= 2
Q += (1 - 2 * b[0][bit]) * lut[getIndex(b, bit)]
doubleFactors(factors)
updateFactors(factors, b, bit)
if even:
Q -= P0
print('----')
print('final Q: ' + pointToString(Q))
print('expected: ' + pointToString(expected))
print('----')
printFactors(factors)
print('Mul expected:')
print(' k0: ' + k0.hex())
print(' k1: ' + k1.hex())
print(' k2: ' + k2.hex())
print(' k3: ' + k3.hex())
assert Q == expected
# Test generator
set_random_seed(1337)
for i in range(1):
print('---------------------------------------')
# scalar = randrange(r) # Pick an integer below curve order
# P = G2.random_point()
# P = clearCofactorG2(P)
# scalar = Integer('0x2c02275a71bb41c911faf48cab4f7ac7fc6672a5c15586185c8cff3203181da0')
# P = G2([
# Fp2([Integer('0x2a028c1328bb0abf252edfbf7133b84eef2a5f20163fe61685b4b54229ca585d'),
# Integer('0x8f80ad79e8e7e79bbdc645d9f5b339c52dd99a901b90de2494492656f11a9d5')]),
# Fp2([Integer('0x1f04320578e31ffa2e2b59ad8fcb1aba622b5f307ac540cf2ccdab07dec56503'),
# Integer('0x2973900c0fdf651b64f5b1a990baec7c582e0743d501bdb991374776d6c73b28')])
# ])
scalar = Integer('0x24c5b2ce21615dca82231f5fb0fc8d05aa07c6df4bb5aa7c2381ac7b61a6290c')
P = G2([
Fp2([Integer('0x1132e63c444e1abce6fc4c39bdf5be5caad586837cbf5ca9d3891482bdefe77'),
Integer('0x22b71f598dab789f055fc9669ddf66f0d75f581af0e9e8863d7f95a51ef34862')]),
Fp2([Integer('0x58e39050f64c9948d7238b99ecaee947cb934688a6e9f483c5c36b6e07aa31b'),
Integer('0x2e64b920f498e12992f2a4ae3f9ced43f3f64705c9008169f3b930a760d055fb')])
])
scalarMulEndo(scalar, P)

View File

@ -1,38 +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.
# ############################################################
#
# Lattice decomposition finder
#
# ############################################################
# Example of BLS12-381 with the ψ (Psi) - Untwist-Frobenius-Twist endomorphism
x = -(2^63 + 2^62 + 2^60 + 2^57 + 2^48 + 2^16)
p = (x - 1)^2 * (x^4 - x^2 + 1)//3 + x
r = x^4 - x^2 + 1
t = x + 1 # Trace of Frobenius
lambda_psi = t - 1
Lpsi = Matrix([
[ r, 0, 0, 0],
[-lambda_psi, 1, 0, 0],
[-lambda_psi^2, 0, 1, 0],
[-lambda_psi^3, 0, 0, 1],
])
Lpsi = Lpsi.LLL()
print(Lpsi)
ahat = vector([r, 0, 0, 0]) * Lpsi.inverse()
print('ahat: ' + str(ahat))
v = int(r).bit_length()
v = int(((v + 64 - 1) // 64) * 64)
print([(a << v) // r for a in ahat])

View File

@ -1,173 +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.
# This script checks polynomial irreducibility
#
# Constructing Tower Extensions for the implementation of Pairing-Based Cryptography
# Naomi Benger and Michael Scott, 2009
# https://eprint.iacr.org/2009/556
# Note: Some of the curves here are not pairing friendly and never used in an extension field.
# We still check them to potentially add them as additional test vectors in
# 𝔽p2, 𝔽p6, 𝔽p12, ... since as they are most 0xFF bytes they
# trigger "carry" code-paths that are not triggered by pairing-friendly moduli.
Curves = {
'P224': Integer('0xffffffffffffffffffffffffffffffff000000000000000000000001'),
'BN254_Nogami': Integer('0x2523648240000001ba344d80000000086121000000000013a700000000000013'),
'BN254_Snarks': Integer('0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47'),
'Curve25519': Integer('0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed'),
'P256': Integer('0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff'),
'Secp256k1': Integer('0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F'),
'BLS12_377': Integer('0x01ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001'),
'BLS12_381': Integer('0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab'),
'BN446': Integer('0x2400000000000000002400000002d00000000d800000021c0000001800000000870000000b0400000057c00000015c000000132000000067'),
'FKM12_447': Integer('0x4ce300001338c00001c08180000f20cfffffe5a8bffffd08a000000f228000007e8ffffffaddfffffffdc00000009efffffffca000000007'),
'BLS12_461': Integer('0x15555545554d5a555a55d69414935fbd6f1e32d8bacca47b14848b42a8dffa5c1cc00f26aa91557f00400020000555554aaaaaac0000aaaaaaab'),
'BN462': Integer('0x240480360120023ffffffffff6ff0cf6b7d9bfca0000000000d812908f41c8020ffffffffff6ff66fc6ff687f640000000002401b00840138013')
}
def find_quadratic_non_residues(A, B, Field, modulus):
result = false
for a in A:
for b in B:
residue = Fp(a^2 + b^2).residue_symbol(Fp.ideal(modulus),2)
if residue < 0:
print(f' 𝔽p4 = 𝔽p2[v] / v² - ({a} ± {b}𝑖) is an irreducible polynomial')
result = true
return result
def find_cubic_non_residues_pmod3eq1(A, B, modulus):
assert modulus % 3 == 1
result = false
for a in A:
for b in B:
# The following `residue_symbol` is not satisfactory for cubic root
# It just returns exceptions for all values
#
#
# residue = Fp(a^2 + b^2).residue_symbol(Fp.ideal(modulus),3)
# if residue < 0:
# print(f' 𝔽p2[v] / v³ - ({a} ± {b}𝑖) is an irreducible polynomial')
# for p ≡ 1 (mod 3)
# we have ``a`` a cubic residue iff a^((p-1)/3) ≡ 1 (mod p)
residue = pow(a^2 + b^2, (modulus-1)//3, modulus)
if residue != 1:
print(f' 𝔽p6 = 𝔽p2[v] / v³ - ({a} ± {b}𝑖) is a possible extension')
result = true
return result
for curve, modulus in Curves.items():
print(f'Curve {curve}:')
print(f' Modulus 0x{modulus.hex()}:')
pMod4 = modulus % 4
print(f' p mod 4: {pMod4}')
if pMod4 == 3:
# This is actually the hard case, but given that most pairing friendly curves somehow end up in that case
# this is the one we will focus on.
print(f' ^ suggested irreducible polynomial for 𝔽p2: u² + 1 (𝔽p2 complex)')
else:
print(f' ⚠️ p mod 4 != 3: to be reviewed manually. See Theorem 1 of Scott 2009 Constructing Tower Extensions for the implementation of Pairing-Based Cryptography')
print(f' p mod 8: {modulus % 8}')
print(f' p mod 12: {modulus % 12}')
if pMod4 != 3:
print(f' p mod 4 != 3 => find a square/cubic root and then successively adjoin roots of the roots to build the tower.')
print(f' Skipping to next curve.')
continue
Fp.<p> = NumberField(x - 1)
print('')
print(' Searching for valid irreducible polynomials ...')
# Constructing 𝔽p4
print(' 𝔽p4 = 𝔽p2[v] / v² - (a ± 𝑖 b))')
found = find_quadratic_non_residues([0, 1, 2], [1, 2], Fp, modulus)
if not found:
found = find_quadratic_non_residues(range(5), range(1, 5), Fp, modulus)
assert found
found = false
# Constructing 𝔽p6
print(' 𝔽p6 = 𝔽p2[v] / v³ - (a ± 𝑖 b))')
pMod3 = modulus % 3
print(f' p mod 3: {pMod3}')
if pMod3 != 1:
# A remark on the computation of cube roots in finite fields
# https://eprint.iacr.org/2009/457.pdf
print(f' p mod 3 != 1 => to be reviewed manually')
print(f' Skipping to next curve.')
continue
if not found:
found = find_cubic_non_residues_pmod3eq1([0, 1, 2], [1, 2], modulus)
if not found:
found = find_cubic_non_residues_pmod3eq1(range(5), range(1, 5), modulus)
if not found:
found = find_cubic_non_residues_pmod3eq1(range(17), range(1, 17), modulus)
assert found
# ############################################################
#
# Failed experiments of actually instantiating
# the tower of extension fields
#
# ############################################################
# ############################################################
# 1st try
# # Create the field of x ∈ [0, p-1]
# K.<p> = NumberField(x - 1)
#
# # Tower Fp² with Fp[u] / (u² + 1) <=> u = 𝑖
# L.<im> = K.extension(x^2 + 1)
#
# TODO how to make the following work?
# # Tower Fp^6 with Fp²[v] / (v³ - (u + 1))
# M.<xi> = L.extension(x^3 - (im + 1))
# ############################################################
# 2nd try
# # Create the field of u ∈ [0, p-1]
# p = Integer('0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47')
# Fp = GF(p)
# Elem.<u> = Fp[]
# print("p mod 4 = ", p % 4)
#
# # Tower Fp² with Fp[u] / (u² + 1) <=> u = 𝑖
# Fp2.<im> = Fp.extension(u^2 + 1)
# Elem2.<v> = Fp2[]
#
# # Tower Fp^6 with Fp²[v] / (v³ - (u + 1))
# Fp6.<xi> = Fp.extension(v^3 - (im + 1))
# Elem6.<w> = Fp6[]
# ############################################################
# 3rd try
# K.<xi, im, p> = NumberField([x^3 - I - 1, x^2 + 1, x - 1])
# ############################################################
# 4th try, just trying to verify Fp6
# print('Verifying non-residues')
# modulus = Integer('0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47')
# Fp.<p> = NumberField(x - 1)
# r1 = Fp(-1).residue_symbol(Fp.ideal(modulus),2)
# print('Fp² = Fp[sqrt(-1)]: ' + str(r1))
# Fp2.<im> = Fp.extension(x^2 + 1)
# xi = Fp2(1+im)
# r2 = xi.residue_symbol(Fp2.ideal(modulus),3)
# # ValueError: The residue symbol to that power is not defined for the number field
# # ^ AFAIK that means that Fp2 doesn't contain the 3rd root of unity
# # so we are clear
# print('Fp6 = Fp²[cubicRoot(1+I)]: ' + str(r2))

View File

@ -1,109 +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.
# ############################################################
#
# BN254 test generator
#
# ############################################################
# Parameters
x = 3 * 2^46 * (7 * 13 * 499) + 1
p = (x - 1)^2 * (x^4 - x^2 + 1)//3 + x
r = x^4 - x^2 + 1
# Finite fields
Fp = GF(p)
K2.<u> = PolynomialRing(Fp)
Fp2.<beta> = Fp.extension(u^2+5)
# Curves
b = 1
SNR = Fp2([0, 1])
G1 = EllipticCurve(Fp, [0, b])
G2 = EllipticCurve(Fp2, [0, b/SNR])
# https://crypto.stackexchange.com/questions/64064/order-of-twisted-curve-in-pairings
# https://math.stackexchange.com/questions/144194/how-to-find-the-order-of-elliptic-curve-over-finite-field-extension
cofactorG1 = G1.order() // r
cofactorG2 = G2.order() // r
print('')
print('cofactor G1: ' + cofactorG1.hex())
print('cofactor G2: ' + cofactorG2.hex())
print('')
def clearCofactorG1(P):
return cofactorG1 * P
def clearCofactorG2(P):
return cofactorG2 * P
# Test generator
set_random_seed(1337)
print('=========================================')
print('G1 vectors: ')
for i in range(10):
print(f'--- test {i} ------------------------------')
Prand = G1.random_point()
P = clearCofactorG1(Prand)
(Px, Py, Pz) = P
print('Px: ' + Integer(Px).hex())
print('Py: ' + Integer(Py).hex())
# print('Pz: ' + Integer(Pz).hex())
exponent = randrange(r) # Pick an integer below curve order
print('scalar: ' + Integer(exponent).hex())
Q = exponent * P
(Qx, Qy, Qz) = Q
print('Qx: ' + Integer(Qx).hex())
print('Qy: ' + Integer(Qy).hex())
# print('Qz: ' + Integer(Qz).hex())
print('=========================================')
print('G2 vectors: ')
for i in range(10):
print(f'--- test {i} ------------------------------')
Prand = G2.random_point()
P = clearCofactorG2(Prand)
(Px, Py, Pz) = P
vPx = vector(Px)
vPy = vector(Py)
# Pz = vector(Pz)
print('Px: ' + Integer(vPx[0]).hex() + ' + β * ' + Integer(vPx[1]).hex())
print('Py: ' + Integer(vPy[0]).hex() + ' + β * ' + Integer(vPy[1]).hex())
exponent = randrange(r) # Pick an integer below curve order
print('scalar: ' + Integer(exponent).hex())
Q = exponent * P
(Qx, Qy, Qz) = Q
Qx = vector(Qx)
Qy = vector(Qy)
print('Qx: ' + Integer(Qx[0]).hex() + ' + β * ' + Integer(Qx[1]).hex())
print('Qy: ' + Integer(Qy[0]).hex() + ' + β * ' + Integer(Qy[1]).hex())
print('=========================================')
# CurveOrder sanity check
#
# P = G1.random_point()
# (Px, Py, Pz) = P
# print('Px: ' + Integer(Px).hex())
# print('Py: ' + Integer(Py).hex())
# print('Pz: ' + Integer(Pz).hex())
#
# print('order: ' + Integer(r).hex())
#
# Q = (r * cofactor) * P
# (Qx, Qy, Qz) = Q
# print('Qx: ' + Integer(Qx).hex())
# print('Qy: ' + Integer(Qy).hex())
# print('Qz: ' + Integer(Qz).hex())

View File

@ -1,113 +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.
# ############################################################
#
# BN254 test generator
#
# ############################################################
# Parameters
x = -(2^63 + 2^62 + 2^60 + 2^57 + 2^48 + 2^16)
p = (x - 1)^2 * (x^4 - x^2 + 1)//3 + x
r = x^4 - x^2 + 1
# Finite fields
Fp = GF(p)
K2.<u> = PolynomialRing(Fp)
Fp2.<beta> = Fp.extension(u^2+1)
# K6.<v> = PolynomialRing(Fp2)
# Fp6.<eta> = Fp2.extension(v^3-Fp2([1, 1])
# K12.<w> = PolynomialRing(Fp6)
# K12.<gamma> = F6.extension(w^2-eta)
# Curves
b = 4
SNR = Fp2([1, 1])
G1 = EllipticCurve(Fp, [0, b])
G2 = EllipticCurve(Fp2, [0, b*SNR])
# https://crypto.stackexchange.com/questions/64064/order-of-twisted-curve-in-pairings
# https://math.stackexchange.com/questions/144194/how-to-find-the-order-of-elliptic-curve-over-finite-field-extension
cofactorG1 = G1.order() // r
cofactorG2 = G2.order() // r
print('')
print('cofactor G1: ' + cofactorG1.hex())
print('cofactor G2: ' + cofactorG2.hex())
print('')
def clearCofactorG1(P):
return cofactorG1 * P
def clearCofactorG2(P):
return cofactorG2 * P
# Test generator
set_random_seed(1337)
print('=========================================')
print('G1 vectors: ')
for i in range(10):
print(f'--- test {i} ------------------------------')
Prand = G1.random_point()
P = clearCofactorG1(Prand)
(Px, Py, Pz) = P
print('Px: ' + Integer(Px).hex())
print('Py: ' + Integer(Py).hex())
# print('Pz: ' + Integer(Pz).hex())
exponent = randrange(r) # Pick an integer below curve order
print('scalar: ' + Integer(exponent).hex())
Q = exponent * P
(Qx, Qy, Qz) = Q
print('Qx: ' + Integer(Qx).hex())
print('Qy: ' + Integer(Qy).hex())
# print('Qz: ' + Integer(Qz).hex())
print('=========================================')
print('G2 vectors: ')
for i in range(10):
print(f'--- test {i} ------------------------------')
Prand = G2.random_point()
P = clearCofactorG2(Prand)
(Px, Py, Pz) = P
vPx = vector(Px)
vPy = vector(Py)
# Pz = vector(Pz)
print('Px: ' + Integer(vPx[0]).hex() + ' + β * ' + Integer(vPx[1]).hex())
print('Py: ' + Integer(vPy[0]).hex() + ' + β * ' + Integer(vPy[1]).hex())
exponent = randrange(r) # Pick an integer below curve order
print('scalar: ' + Integer(exponent).hex())
Q = exponent * P
(Qx, Qy, Qz) = Q
Qx = vector(Qx)
Qy = vector(Qy)
print('Qx: ' + Integer(Qx[0]).hex() + ' + β * ' + Integer(Qx[1]).hex())
print('Qy: ' + Integer(Qy[0]).hex() + ' + β * ' + Integer(Qy[1]).hex())
print('=========================================')
# CurveOrder sanity check
#
# P = G1.random_point()
# (Px, Py, Pz) = P
# print('Px: ' + Integer(Px).hex())
# print('Py: ' + Integer(Py).hex())
# print('Pz: ' + Integer(Pz).hex())
#
# print('order: ' + Integer(r).hex())
#
# Q = (r * cofactor) * P
# (Qx, Qy, Qz) = Q
# print('Qx: ' + Integer(Qx).hex())
# print('Qy: ' + Integer(Qy).hex())
# print('Qz: ' + Integer(Qz).hex())

View File

@ -1,114 +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.
# ############################################################
#
# BN254 test generator
#
# ############################################################
# Parameters
x = Integer('0x44E992B44A6909F1')
p = 36*x^4 + 36*x^3 + 24*x^2 + 6*x + 1
r = 36*x^4 + 36*x^3 + 18*x^2 + 6*x + 1
# Finite fields
Fp = GF(p)
K2.<u> = PolynomialRing(Fp)
Fp2.<beta> = Fp.extension(u^2+1)
# K6.<v> = PolynomialRing(Fp2)
# Fp6.<eta> = Fp2.extension(v^3-Fp2([9, 1]))
# K12.<w> = PolynomialRing(F6)
# K12.<gamma> = Fp6.extension(w^2-eta)
# Curves
b = 3
SNR = Fp2([9, 1])
G1 = EllipticCurve(Fp, [0, b])
G2 = EllipticCurve(Fp2, [0, b/SNR])
# https://crypto.stackexchange.com/questions/64064/order-of-twisted-curve-in-pairings
# https://math.stackexchange.com/questions/144194/how-to-find-the-order-of-elliptic-curve-over-finite-field-extension
cofactorG1 = G1.order() // r
cofactorG2 = G2.order() // r
print('')
print('cofactor G1: ' + cofactorG1.hex())
print('cofactor G2: ' + cofactorG2.hex())
print('')
def clearCofactorG1(P):
return cofactorG1 * P
def clearCofactorG2(P):
return cofactorG2 * P
# Test generator
set_random_seed(1337)
print('=========================================')
print('G1 vectors: ')
for i in range(10):
print(f'--- test {i} ------------------------------')
P = G1.random_point()
P = clearCofactorG1(P)
(Px, Py, Pz) = P
print('Px: ' + Integer(Px).hex())
print('Py: ' + Integer(Py).hex())
# print('Pz: ' + Integer(Pz).hex())
exponent = randrange(r) # Pick an integer below curve order
print('scalar: ' + Integer(exponent).hex())
Q = exponent * P
(Qx, Qy, Qz) = Q
print('Qx: ' + Integer(Qx).hex())
print('Qy: ' + Integer(Qy).hex())
# print('Qz: ' + Integer(Qz).hex())
print('---------------------------------------')
print('=========================================')
print('G2 vectors: ')
for i in range(10):
print(f'--- test {i} ------------------------------')
P = G2.random_point()
P = clearCofactorG2(P)
(Px, Py, Pz) = P
vPx = vector(Px)
vPy = vector(Py)
# Pz = vector(Pz)
print('Px: ' + Integer(vPx[0]).hex() + ' + β * ' + Integer(vPx[1]).hex())
print('Py: ' + Integer(vPy[0]).hex() + ' + β * ' + Integer(vPy[1]).hex())
exponent = randrange(r) # Pick an integer below curve order
print('scalar: ' + Integer(exponent).hex())
assert exponent < r
Q = exponent * P
(Qx, Qy, Qz) = Q
Qx = vector(Qx)
Qy = vector(Qy)
print('Qx: ' + Integer(Qx[0]).hex() + ' + β * ' + Integer(Qx[1]).hex())
print('Qy: ' + Integer(Qy[0]).hex() + ' + β * ' + Integer(Qy[1]).hex())
print('---------------------------------------')
print('=========================================')
# CurveOrder sanity check
#
# P = G1.random_point()
# (Px, Py, Pz) = P
# print('Px: ' + Integer(Px).hex())
# print('Py: ' + Integer(Py).hex())
# print('Pz: ' + Integer(Pz).hex())
#
# print('order: ' + Integer(r).hex())
#
# Q = (r * cofactor) * P
# (Qx, Qy, Qz) = Q
# print('Qx: ' + Integer(Qx).hex())
# print('Qy: ' + Integer(Qy).hex())
# print('Qz: ' + Integer(Qz).hex())

View File

@ -0,0 +1,246 @@
#!/usr/bin/sage
# vim: syntax=python
# vim: set ts=2 sw=2 et:
# 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.
# ############################################################
#
# Scalar multiplication test generator
#
# ############################################################
# Imports
# ---------------------------------------------------------
import os, json
import inspect, textwrap
# Working directory
# ---------------------------------------------------------
os.chdir(os.path.dirname(__file__))
# Sage imports
# ---------------------------------------------------------
# Accelerate arithmetic by accepting probabilistic proofs
from sage.structure.proof.all import arithmetic
arithmetic(False)
load('curves.sage')
# Utilities
# ---------------------------------------------------------
def progressbar(it, prefix="", size=60, file=sys.stdout):
count = len(it)
def show(j):
x = int(size*j/count)
file.write("%s[%s%s] %i/%i\r" % (prefix, "#"*x, "."*(size-x), j, count))
file.flush()
show(0)
for i, item in enumerate(it):
yield item
show(i+1)
file.write("\n")
file.flush()
def serialize_bigint(x):
return '0x' + Integer(x).hex()
def serialize_G1(P):
(Px, Py, Pz) = P
coords = {
'x': serialize_bigint(Px),
'y': serialize_bigint(Py)
}
return coords
def serialize_G2(P):
(Px, Py, Pz) = P
Px = vector(Px)
Py = vector(Py)
coords = {
'x': {
'c0': serialize_bigint(Px[0]),
'c1': serialize_bigint(Px[1])
},
'y': {
'c0': serialize_bigint(Py[0]),
'c1': serialize_bigint(Py[1])
}
}
return coords
# Generator
# ---------------------------------------------------------
def genScalarMulG1(curve_name, curve_config, count, seed):
p = curve_config[curve_name]['field']['modulus']
r = curve_config[curve_name]['field']['order']
form = curve_config[curve_name]['curve']['form']
a = curve_config[curve_name]['curve']['a']
b = curve_config[curve_name]['curve']['b']
Fp = GF(p)
G1 = EllipticCurve(Fp, [0, b])
cofactor = G1.order() // r
out = {
'curve': curve_name,
'group': 'G1',
'modulus': serialize_bigint(p),
'order': serialize_bigint(r),
'cofactor': serialize_bigint(cofactor),
'form': form
}
if form == 'short_weierstrass':
out['a'] = serialize_bigint(a)
out['b'] = serialize_bigint(b)
vectors = []
set_random_seed(seed)
for i in progressbar(range(count)):
v = {}
P = G1.random_point()
scalar = randrange(r)
P *= cofactor # clear cofactor
v['id'] = i
v['P'] = serialize_G1(P)
v['scalar'] = serialize_bigint(scalar)
Q = scalar * P
v['Q'] = serialize_G1(Q)
vectors.append(v)
out['vectors'] = vectors
return out
def genScalarMulG2(curve_name, curve_config, count, seed):
p = curve_config[curve_name]['field']['modulus']
r = curve_config[curve_name]['field']['order']
form = curve_config[curve_name]['curve']['form']
a = curve_config[curve_name]['curve']['a']
b = curve_config[curve_name]['curve']['b']
embedding_degree = curve_config[curve_name]['tower']['embedding_degree']
twist_degree = curve_config[curve_name]['tower']['twist_degree']
twist = curve_config[curve_name]['tower']['twist']
G2_field_degree = embedding_degree // twist_degree
G2_field = f'Fp{G2_field_degree}' if G2_field_degree > 1 else 'Fp'
if G2_field_degree == 2:
non_residue_fp = curve_config[curve_name]['tower']['QNR_Fp']
else:
raise NotImplementedError()
Fp = GF(p)
K.<u> = PolynomialRing(Fp)
if G2_field == 'Fp2':
Fp2.<beta> = Fp.extension(u^2 - non_residue_fp)
G2F = Fp2
if twist_degree == 6:
non_residue_twist = curve_config[curve_name]['tower']['SNR_Fp2']
else:
raise NotImplementedError()
else:
G2F = Fp
raise NotImplementedError()
if twist == 'D_Twist':
G2 = EllipticCurve(G2F, [0, b/G2F(non_residue_twist)])
elif twist == 'M_Twist':
G2 = EllipticCurve(G2F, [0, b*G2F(non_residue_twist)])
else:
raise ValueError('G2 must be a D_Twist or M_Twist but found ' + twist)
cofactor = G2.order() // r
out = {
'curve': curve_name,
'group': 'G2',
'modulus': serialize_bigint(p),
'order': serialize_bigint(r),
'cofactor': serialize_bigint(cofactor),
'form': form,
'twist_degree': int(twist_degree),
'twist': twist,
'non_residue_fp': int(non_residue_fp),
'G2_field': G2_field,
'non_residue_twist': [int(coord) for coord in non_residue_twist] if isinstance(non_residue_twist, list) else int(non_residue_twist)
}
if form == 'short_weierstrass':
out['a'] = serialize_bigint(a)
out['b'] = serialize_bigint(b)
vectors = []
set_random_seed(seed)
for i in progressbar(range(count)):
v = {}
P = G2.random_point()
scalar = randrange(r)
P *= cofactor # clear cofactor
v['id'] = i
v['P'] = serialize_G2(P)
v['scalar'] = serialize_bigint(scalar)
Q = scalar * P
v['Q'] = serialize_G2(Q)
vectors.append(v)
out['vectors'] = vectors
return out
# CLI
# ---------------------------------------------------------
if __name__ == "__main__":
# Usage
# BLS12-381
# sage sage/derive_pairing.sage BLS12_381 G1
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument("curve",nargs="+")
args = parser.parse_args()
curve = args.curve[0]
group = args.curve[1]
if curve not in Curves:
raise ValueError(
curve +
' is not one of the available curves: ' +
str(Curves.keys())
)
elif group not in ['G1', 'G2']:
raise ValueError(
group +
' is not a valid group, expected G1 or G2 instead'
)
else:
print(f'\nGenerating test vectors tv_{curve}_scalar_mul_{group}.json')
print('----------------------------------------------------\n')
count = 40
seed = 1337
if group == 'G1':
out = genScalarMulG1(curve, Curves, count, seed)
elif group == 'G2':
out = genScalarMulG2(curve, Curves, count, seed)
with open(f'tv_{curve}_scalar_mul_{group}.json', 'w') as f:
json.dump(out, f, indent=2)

View File

@ -8,7 +8,6 @@
import
# Internals
../../constantine/config/[common, curves],
../../constantine/arithmetic,
../../constantine/io/io_bigints

View File

@ -7,572 +7,30 @@
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import
# Standard library
std/[unittest, times],
# Internals
../constantine/config/[common, curves],
../constantine/arithmetic,
../constantine/config/[type_fp, curves],
../constantine/towers,
../constantine/io/[io_bigints, io_ec],
../constantine/elliptic/[
ec_shortweierstrass_projective,
ec_shortweierstrass_jacobian,
ec_scalar_mul, ec_endomorphism_accel],
../constantine/elliptic/ec_shortweierstrass_jacobian,
../constantine/elliptic/ec_shortweierstrass_projective,
# Test utilities
./support/ec_reference_scalar_mult
./t_ec_sage_template
echo "\n------------------------------------------------------\n"
run_scalar_mul_test_vs_sage(
ECP_ShortW_Proj[Fp[BLS12_377], NotOnTwist],
"t_ec_sage_bls12_377_g1_projective"
)
proc test(
id: int,
EC: typedesc[ECP_ShortW_Proj or ECP_ShortW_Jac],
Px, Py: string,
scalar: string,
Qx, Qy: string
) =
run_scalar_mul_test_vs_sage(
ECP_ShortW_Jac[Fp[BLS12_377], NotOnTwist],
"t_ec_sage_bls12_377_g1_jacobian"
)
test "test " & $id & " - " & $EC:
var P: EC
let pOK = P.fromHex(Px, Py)
doAssert pOK
run_scalar_mul_test_vs_sage(
ECP_ShortW_Proj[Fp2[BLS12_377], OnTwist],
"t_ec_sage_bls12_377_g2_projective"
)
var Q: EC
let qOK = Q.fromHex(Qx, Qy)
let exponent = BigInt[EC.F.C.getCurveOrderBitwidth()].fromHex(scalar)
var
impl = P
reference = P
endo = P
endoW = P
impl.scalarMulGeneric(exponent)
reference.unsafe_ECmul_double_add(exponent)
endo.scalarMulEndo(exponent)
endoW.scalarMulGLV_m2w2(exponent)
doAssert: bool(Q == reference)
doAssert: bool(Q == impl)
doAssert: bool(Q == endo)
doAssert: bool(Q == endoW)
suite "Scalar Multiplication (cofactor cleared): BLS12_377 implementation vs SageMath" & " [" & $WordBitwidth & "-bit mode]":
# Generated via sage sage/testgen_bls12_377.sage
test(
id = 0,
EC = ECP_ShortW_Proj[Fp[BLS12_377], NotOnTwist],
Px = "4e7e6dfa01ed0ceb6e66708b07cb5c6cd30a42eeb13d7b76f8d103a0a4d491450be6f526fc12f15209b792220c041e",
Py = "c782515159b7e7b9371e0e0caa387951317e993b1625d91869d4346621058a0960ef1b8b6eabb33cd5719694908a05",
scalar = "cf815cb4d44d3d691b7c82a40b4b70caa9b0e8fe9586648abf3f1e2e639ca1b",
Qx = "4a1203db4af8f0efc18c7ceb24999eb6e0dbdfc8f44a9edd5ba2f9eced38e81ecae287ab1c184eea8e8753d1178604",
Qy = "f7509cdce5de473e37f36c69d93ff1b2ab04c3ae25a3b5e41f2c138cdcc69ed5eaf4ac95a7a857eef336ebac19bcd3"
)
test(
id = 1,
EC = ECP_ShortW_Proj[Fp[BLS12_377], NotOnTwist],
Px = "13d735b28405253dcc0bc60bcdc13633475ffc187d38a9b97655b0d0fa1d56c4548f11ea0a795391ee85c953aaf9b83",
Py = "1693101123fd13a20f9c0569c52c29507ba1c8b6dd412660bc82e7974022f1a10f9137b4ba59d3f0aab67027cefec19",
scalar = "913aa7b9fa2f940b70b6dcf538cc08da1a369809ab86a8ee49cead0ed6bfef6",
Qx = "10e0e8582ec3456f7569473892c23997d004f2542d914fa75db8f1798ed8ce505836e8b7af5cf1503e14d85fadd65ee",
Qy = "d5151ae60e43100e20aad7eaf8659e690e8034910d7717078031520fcbf6f9a00b22c6a9894aec88c9182f13335639"
)
test(
id = 2,
EC = ECP_ShortW_Proj[Fp[BLS12_377], NotOnTwist],
Px = "6dd2211113cada09d3b96848cbf21ed14f6fc238b581c0afd49aa776980101e4ee279a256ce8f1428d3ed3f70afd85",
Py = "3b406b4433a3f44f8e196012f50c520e876412fbcae2651916f133c1fd3899c79f676e1abba01d84bab7ad100c9295",
scalar = "4cf47669aeb0f30b6c6c5aa02808a87dc787fba22da32875e614a54a50b6a0c",
Qx = "3caf55e1f82d746df2bf47defbee127a3e6f7e79a9575929704b25489ffb801dbce07999acbddfd79352b0633a2708",
Qy = "3fc275c136b07456f0b6ee814508876037add5e95357fae6b4195744ba5ccccaf93581e34feb2babe652a9a704731b"
)
test(
id = 3,
EC = ECP_ShortW_Proj[Fp[BLS12_377], NotOnTwist],
Px = "18648abbe3261f93cbf679777eac66e419035041a967d1e6a0f0afdb92810d7122e0984f1d6efc8fe518500464ee803",
Py = "7b6f518d4d06309aad4d60d29118310b6c8b17c7bf5db2251f4701b13b89a8c0f04bb5d0386785e55ffbbd7ecc445e",
scalar = "69498486a06c18f836a8e9ed507bbb563d6d03545e03e08f628e8fbd2e5d098",
Qx = "6a871d872673879fd23ec8c150f8d63e8130dc60343fc0c2ec9ff1b02e769e20eeec0288102ccec6ff2f6ac6973b4",
Qy = "cd95a31afa4f0bbcc063a1585fec4a6c51812b2baaee42a04525fd55b3a9db3bdb7cbc77f7cd32f42d2e0eb26ddfa2"
)
test(
id = 4,
EC = ECP_ShortW_Proj[Fp[BLS12_377], NotOnTwist],
Px = "745e9944549522486f3446676cc62fb666682e10c661a13b8110b42cb9a37676b6f33a46f9495f4fafb342d5809db5",
Py = "bc595854bc42ccec60dd9ec573608d736aa59996cef1c2e8f6c5d424f525a6f3e3d4beeedfac6b959dbd71ced95b13",
scalar = "6e08d8714102a5aa3e9f46e33c70a759c27253c7b0196c3e46c7cb42671197e",
Qx = "18a967a80785de8ec6ac9d98cffa06a8c633b5fa0f36431a32f7bd955946edc3d55f79bfdf5335db405560a6cbe2415",
Qy = "4552ff2eb6ade0c6b33c3603460d9d62099201d842c9883b33b7ed1147cb17268338a77a9417776ddbd774e91a8d2"
)
test(
id = 5,
EC = ECP_ShortW_Proj[Fp[BLS12_377], NotOnTwist],
Px = "f7b56cf212a8906ed77a758164c0bd05ce1fbd3ee3c4357e7a09b3aedc748a29ace254f1f6df35b8cb74361060337f",
Py = "2640ef641d20fea19b28947833e53faceeafa57a8761b807049f3d707d70c01f1c69a57edd993d301a64517bf47f77",
scalar = "a5c46d7a52938fed7f3093d5867f65361dc8b48c83bd7db490c26736196e20e",
Qx = "434f024c4afd7b9a44375011d663af0ae0fe79442e9caf36518e053bb13d49998ec1d2da4bc1c4a812812119b3221f",
Qy = "32c959e2a678cf93f77e621fdf887454a5f9cb7a67f29065669f48234c25e321ceb5758dfba987431a0c2caec94616"
)
test(
id = 6,
EC = ECP_ShortW_Proj[Fp[BLS12_377], NotOnTwist],
Px = "43b387c12e4cc91fb1a5593b7671356dceb0fe6e6ac666d5bac94f2a44c8db54976b649a678aae038b21144de04e23",
Py = "1a6366a50f1f9ba64eef73d82bec86177bf184be048a9d66326ccb0122203569ddcb8cf74445cadaff7f47a66d1b1a2",
scalar = "bddd07231bc7fe89ee4a859a00ea1f9d236be9e7fd561303d566904c1b0a07c",
Qx = "8ddb7a959483b51a1471de988146b7d5b166f660734b4d55166c5a23d781e923261927b1012dce73b822bb6e56bfd2",
Qy = "dc7178bf5597ef31209a5b0409fc42c64b81260a0046a562ca08c7a9dc67b444c25e94fb97b9a6bb4c137cadd81021"
)
test(
id = 7,
EC = ECP_ShortW_Proj[Fp[BLS12_377], NotOnTwist],
Px = "6984c9385a67081f97b3d33444077466cca1d0442a4da8c083a0957578e0b21011435b126a5ab143da9da1cf5b216f",
Py = "18a87c7f5f6c5a8101773e63956b9addd4becf5177acc560d548e5331638121934842fdc9f654b3f456a7df5a2e471a",
scalar = "b72c41a6ffaff0aacb5d62e3dcb16acfec66b6a9639e19d3128fd43c18e7dbe",
Qx = "19279201c3c7a9d50b546aa99d3e1a6625fe2a7bc64a09625b683534638b9e87b9102d4dba6684956b6be7668a658c6",
Qy = "195f15ad1edc05f8b289c7eee7bd8f78116a2d5ba8b83643d9e7cb2cdc6550bcf8c2145008e900ca9cba4d5040e9f4"
)
test(
id = 8,
EC = ECP_ShortW_Proj[Fp[BLS12_377], NotOnTwist],
Px = "efc34595823e7333616f7768bc82f407268df6f029bf4c94d15f1785dc7ccc08f22e7301dfc48dadc0ea383c8bb3e",
Py = "2459bd9f71977ef122d2102e8bfd07a5737066075058cfa8bcaa9f9690ed065919c844363ceaea6f9bb650906a535f",
scalar = "8f90f6ab0ffa6e4acc601b44c062745f2935b3dc153d0da07977470080d5c18",
Qx = "35d08b33e02579581905941975c8b1cc5be1c9670a7f7ef390daa363b0abd3571a802d8c27f156fba40573094f6c7a",
Qy = "111ba3bdfa4260dc2b636479edb1fcf2fc9478aa722da0118908e1db1551cf7e131c8521b2f3708ef670684dbe8d181"
)
test(
id = 9,
EC = ECP_ShortW_Proj[Fp[BLS12_377], NotOnTwist],
Px = "3eec93c2a9c5fd03f0de5ede2fdac9e361090fbaea38e4a0f1828745f1d14a057d9fd7c46b9168bd95a45a182a3a62",
Py = "e912dc7e95f90d91e3274ec5639edacb88be1b092c47c13d31a29ecd579885cc09f197f8207d23b2260ab10c94d5f5",
scalar = "203300e949aff816d084a388f07c74b9152bb11b523543afd65c805a389980",
Qx = "8c23ae9c51e7c92c6a59f0ed07a59f148b4d79394fc026931c264612041eedd3782e4f249bbfad1799212788c1a00d",
Qy = "191628b702ebef397bb7c52102ee4522f864ff594b24dc385ece081e8066bcde20aa5c7dfd00fb1f3cea221b3ad4ea2"
)
# ----------------------------------------
test(
id = 0,
EC = ECP_ShortW_Jac[Fp[BLS12_377], NotOnTwist],
Px = "4e7e6dfa01ed0ceb6e66708b07cb5c6cd30a42eeb13d7b76f8d103a0a4d491450be6f526fc12f15209b792220c041e",
Py = "c782515159b7e7b9371e0e0caa387951317e993b1625d91869d4346621058a0960ef1b8b6eabb33cd5719694908a05",
scalar = "cf815cb4d44d3d691b7c82a40b4b70caa9b0e8fe9586648abf3f1e2e639ca1b",
Qx = "4a1203db4af8f0efc18c7ceb24999eb6e0dbdfc8f44a9edd5ba2f9eced38e81ecae287ab1c184eea8e8753d1178604",
Qy = "f7509cdce5de473e37f36c69d93ff1b2ab04c3ae25a3b5e41f2c138cdcc69ed5eaf4ac95a7a857eef336ebac19bcd3"
)
test(
id = 1,
EC = ECP_ShortW_Jac[Fp[BLS12_377], NotOnTwist],
Px = "13d735b28405253dcc0bc60bcdc13633475ffc187d38a9b97655b0d0fa1d56c4548f11ea0a795391ee85c953aaf9b83",
Py = "1693101123fd13a20f9c0569c52c29507ba1c8b6dd412660bc82e7974022f1a10f9137b4ba59d3f0aab67027cefec19",
scalar = "913aa7b9fa2f940b70b6dcf538cc08da1a369809ab86a8ee49cead0ed6bfef6",
Qx = "10e0e8582ec3456f7569473892c23997d004f2542d914fa75db8f1798ed8ce505836e8b7af5cf1503e14d85fadd65ee",
Qy = "d5151ae60e43100e20aad7eaf8659e690e8034910d7717078031520fcbf6f9a00b22c6a9894aec88c9182f13335639"
)
test(
id = 2,
EC = ECP_ShortW_Jac[Fp[BLS12_377], NotOnTwist],
Px = "6dd2211113cada09d3b96848cbf21ed14f6fc238b581c0afd49aa776980101e4ee279a256ce8f1428d3ed3f70afd85",
Py = "3b406b4433a3f44f8e196012f50c520e876412fbcae2651916f133c1fd3899c79f676e1abba01d84bab7ad100c9295",
scalar = "4cf47669aeb0f30b6c6c5aa02808a87dc787fba22da32875e614a54a50b6a0c",
Qx = "3caf55e1f82d746df2bf47defbee127a3e6f7e79a9575929704b25489ffb801dbce07999acbddfd79352b0633a2708",
Qy = "3fc275c136b07456f0b6ee814508876037add5e95357fae6b4195744ba5ccccaf93581e34feb2babe652a9a704731b"
)
test(
id = 3,
EC = ECP_ShortW_Jac[Fp[BLS12_377], NotOnTwist],
Px = "18648abbe3261f93cbf679777eac66e419035041a967d1e6a0f0afdb92810d7122e0984f1d6efc8fe518500464ee803",
Py = "7b6f518d4d06309aad4d60d29118310b6c8b17c7bf5db2251f4701b13b89a8c0f04bb5d0386785e55ffbbd7ecc445e",
scalar = "69498486a06c18f836a8e9ed507bbb563d6d03545e03e08f628e8fbd2e5d098",
Qx = "6a871d872673879fd23ec8c150f8d63e8130dc60343fc0c2ec9ff1b02e769e20eeec0288102ccec6ff2f6ac6973b4",
Qy = "cd95a31afa4f0bbcc063a1585fec4a6c51812b2baaee42a04525fd55b3a9db3bdb7cbc77f7cd32f42d2e0eb26ddfa2"
)
test(
id = 4,
EC = ECP_ShortW_Jac[Fp[BLS12_377], NotOnTwist],
Px = "745e9944549522486f3446676cc62fb666682e10c661a13b8110b42cb9a37676b6f33a46f9495f4fafb342d5809db5",
Py = "bc595854bc42ccec60dd9ec573608d736aa59996cef1c2e8f6c5d424f525a6f3e3d4beeedfac6b959dbd71ced95b13",
scalar = "6e08d8714102a5aa3e9f46e33c70a759c27253c7b0196c3e46c7cb42671197e",
Qx = "18a967a80785de8ec6ac9d98cffa06a8c633b5fa0f36431a32f7bd955946edc3d55f79bfdf5335db405560a6cbe2415",
Qy = "4552ff2eb6ade0c6b33c3603460d9d62099201d842c9883b33b7ed1147cb17268338a77a9417776ddbd774e91a8d2"
)
test(
id = 5,
EC = ECP_ShortW_Jac[Fp[BLS12_377], NotOnTwist],
Px = "f7b56cf212a8906ed77a758164c0bd05ce1fbd3ee3c4357e7a09b3aedc748a29ace254f1f6df35b8cb74361060337f",
Py = "2640ef641d20fea19b28947833e53faceeafa57a8761b807049f3d707d70c01f1c69a57edd993d301a64517bf47f77",
scalar = "a5c46d7a52938fed7f3093d5867f65361dc8b48c83bd7db490c26736196e20e",
Qx = "434f024c4afd7b9a44375011d663af0ae0fe79442e9caf36518e053bb13d49998ec1d2da4bc1c4a812812119b3221f",
Qy = "32c959e2a678cf93f77e621fdf887454a5f9cb7a67f29065669f48234c25e321ceb5758dfba987431a0c2caec94616"
)
test(
id = 6,
EC = ECP_ShortW_Jac[Fp[BLS12_377], NotOnTwist],
Px = "43b387c12e4cc91fb1a5593b7671356dceb0fe6e6ac666d5bac94f2a44c8db54976b649a678aae038b21144de04e23",
Py = "1a6366a50f1f9ba64eef73d82bec86177bf184be048a9d66326ccb0122203569ddcb8cf74445cadaff7f47a66d1b1a2",
scalar = "bddd07231bc7fe89ee4a859a00ea1f9d236be9e7fd561303d566904c1b0a07c",
Qx = "8ddb7a959483b51a1471de988146b7d5b166f660734b4d55166c5a23d781e923261927b1012dce73b822bb6e56bfd2",
Qy = "dc7178bf5597ef31209a5b0409fc42c64b81260a0046a562ca08c7a9dc67b444c25e94fb97b9a6bb4c137cadd81021"
)
test(
id = 7,
EC = ECP_ShortW_Jac[Fp[BLS12_377], NotOnTwist],
Px = "6984c9385a67081f97b3d33444077466cca1d0442a4da8c083a0957578e0b21011435b126a5ab143da9da1cf5b216f",
Py = "18a87c7f5f6c5a8101773e63956b9addd4becf5177acc560d548e5331638121934842fdc9f654b3f456a7df5a2e471a",
scalar = "b72c41a6ffaff0aacb5d62e3dcb16acfec66b6a9639e19d3128fd43c18e7dbe",
Qx = "19279201c3c7a9d50b546aa99d3e1a6625fe2a7bc64a09625b683534638b9e87b9102d4dba6684956b6be7668a658c6",
Qy = "195f15ad1edc05f8b289c7eee7bd8f78116a2d5ba8b83643d9e7cb2cdc6550bcf8c2145008e900ca9cba4d5040e9f4"
)
test(
id = 8,
EC = ECP_ShortW_Jac[Fp[BLS12_377], NotOnTwist],
Px = "efc34595823e7333616f7768bc82f407268df6f029bf4c94d15f1785dc7ccc08f22e7301dfc48dadc0ea383c8bb3e",
Py = "2459bd9f71977ef122d2102e8bfd07a5737066075058cfa8bcaa9f9690ed065919c844363ceaea6f9bb650906a535f",
scalar = "8f90f6ab0ffa6e4acc601b44c062745f2935b3dc153d0da07977470080d5c18",
Qx = "35d08b33e02579581905941975c8b1cc5be1c9670a7f7ef390daa363b0abd3571a802d8c27f156fba40573094f6c7a",
Qy = "111ba3bdfa4260dc2b636479edb1fcf2fc9478aa722da0118908e1db1551cf7e131c8521b2f3708ef670684dbe8d181"
)
test(
id = 9,
EC = ECP_ShortW_Jac[Fp[BLS12_377], NotOnTwist],
Px = "3eec93c2a9c5fd03f0de5ede2fdac9e361090fbaea38e4a0f1828745f1d14a057d9fd7c46b9168bd95a45a182a3a62",
Py = "e912dc7e95f90d91e3274ec5639edacb88be1b092c47c13d31a29ecd579885cc09f197f8207d23b2260ab10c94d5f5",
scalar = "203300e949aff816d084a388f07c74b9152bb11b523543afd65c805a389980",
Qx = "8c23ae9c51e7c92c6a59f0ed07a59f148b4d79394fc026931c264612041eedd3782e4f249bbfad1799212788c1a00d",
Qy = "191628b702ebef397bb7c52102ee4522f864ff594b24dc385ece081e8066bcde20aa5c7dfd00fb1f3cea221b3ad4ea2"
)
proc test(
id: int,
EC: typedesc[ECP_ShortW_Proj or ECP_ShortW_Jac],
Px0, Px1, Py0, Py1: string,
scalar: string,
Qx0, Qx1, Qy0, Qy1: string
) =
test "test " & $id & " - " & $EC:
var P: EC
let pOK = P.fromHex(Px0, Px1, Py0, Py1)
doAssert pOK
var Q: EC
let qOK = Q.fromHex(Qx0, Qx1, Qy0, Qy1)
let exponent = BigInt[EC.F.C.getCurveOrderBitwidth()].fromHex(scalar)
var
impl = P
reference = P
endo = P
impl.scalarMulGeneric(exponent)
reference.unsafe_ECmul_double_add(exponent)
endo.scalarMulEndo(exponent)
doAssert: bool(Q == reference)
doAssert: bool(Q == impl)
doAssert: bool(Q == endo)
suite "Scalar Multiplication G2: BLS12-381 implementation vs SageMath" & " [" & $WordBitwidth & "-bit mode]":
# Generated via sage sage/testgen_bls12_377.sage
test(
id = 0,
EC = ECP_ShortW_Proj[Fp2[BLS12_377], OnTwist],
Px0 = "267401f3ef554fe74ae131d56a10edf14ae40192654901b4618d2bf7af22e77c2a9b79e407348dbd4aad13ca73b33a",
Px1 = "12dcca838f46a3e0418e5dd8b978362757a16bfd78f0b77f4a1916ace353938389ae3ea228d0eb5020a0aaa58884aec",
Py0 = "11799118d2e054aabd9f74c0843fecbdc1c0d56f61c61c5854c2507ae2416e48a6b2cd3bc8bf7495a4d3d8270eafe2b",
Py1 = "823b9f8fb9f8297734a14359fa2c2a0de275e7e638197eaaaa7cff28f9cb3101bdabb570016672455f1ecae625e294",
scalar = "9d432eb58ec68bbc09d10961451d99c7796fb2f795eca603d6feaf3e2a1634b",
Qx0 = "12cfcb50345d43271d2a20e8208789c8ca82f2b8732fae4e7cccd87eb0883741d5e77166971c38c54170bf7635ca2f3",
Qx1 = "17467c786368f2f6eabd78f1c24aa668eae9cd00f6045bfd86b1b3c40966f023a71927026ae5a1281b432ac980d2b6b",
Qy0 = "6f5f1068b6e6a8fafd96894d8b0a8548acee24319d8e2d8b6e6982b1ced8970d9fe33155e74b33d6c2a7835196ca9",
Qy1 = "dc3c7c91c712f9a2631d2b5e49497d8cdf2ea4b30859b43edd716e84cd6a8b61e63cf708d263a7845913cdfb9c7f3b"
)
test(
id = 1,
EC = ECP_ShortW_Proj[Fp2[BLS12_377], OnTwist],
Px0 = "3a3055d6a46901c1b2227a0e334ffa9f654e62a6d3608f3a672e5816f9e9b04c0e668c3e9f8c807b269422afdc7de9",
Px1 = "25803bd55f37b254865d5fc7ac9843fb306c2eb09d34ee0c4ecb705b5e10f6911f07fd707a2e28681a421f45b1a4d",
Py0 = "15a0594a3c9dddc535472c4827aa443774a06f77bec2d20837c6574aa5fac35a279bac756531fa75f979a7a97f297d6",
Py1 = "15e8c3e013cbc64110f075295f39a4f85c9591a52b8e4903047b1f4b44bb5216b6339788c82fd90e82b1027756e7987",
scalar = "a0067f5b4294fbacd24730fed25c936a08b5f1a77824149ad6c2ce476518d17",
Qx0 = "6280dbf019f8d94acac4a39213e03f221be732849b45437edef7617460e83f972883c20791a86670a8a4c6c0125629",
Qx1 = "ab3a185addbd6c7db907170d75bd2f1997666e93d8cedbef9e10a103110d4ea09d9a889f505d7026e5c498b0355c1",
Qy0 = "1a6dd15b4c2bd6bd97858e5a75ac4365f8becaa885c4e3267d0ae256655cd057061d61b2b9acbd10bdf678a9c1e7f8c",
Qy1 = "16204b5825eec903cb7798cb62ccadb9004032d72bb815958fcd2f613c77e147656449fdaa210994338978676ad6b0e"
)
test(
id = 2,
EC = ECP_ShortW_Proj[Fp2[BLS12_377], OnTwist],
Px0 = "18ebf549cd24a64badff4ec177205be121757b68589020434aba816756d2e6fa95fdb389c8639d4bf77575122e1c04e",
Px1 = "11cd0f0976658a6f2ec113034428ef1605befdaa5642944f5c4e571b24fc166c368c30473e25ab148209be4c0b4e37",
Py0 = "1190d818317495201732feb2cfc8f507adac6273debff46bb6aea4a3f3e3fe7d28d893c90b21a6f28d2fbc72d9fc528",
Py1 = "df5fcb2daa302a5c64aeef96835e0a6b39f5d7bf0e70cc10401f966745a6b3fa682b7e5b45d9295e744e1dd7855fd4",
scalar = "7a49802ba58c87c30b631b2f90a3b876c7143e09b542c9c14706bddf9bd4117",
Qx0 = "6cdff80576d8695a646f915caba5bc6748eee1707bb0d4ebcabaf8d236b780aef6a953a07f48ef4696f02db4906c71",
Qx1 = "6b64ca5f0d46702e7e9e7beb1993b698c9b3e9991f545241d5fd44a27dc692d5f5a4c2fe6871af0653128f960307d4",
Qy0 = "cfad02b664495d42d1c6b598306229c67bcf76cc923abb13ae038c90e959a7611161a98d607729577d55ec18bf1e74",
Qy1 = "e433d9dd7d47d94e9f61a5bc27a688c63efa05408d6fd40a5c4e2711a37d011dc80f5dbaaafd939a07235c770feead"
)
test(
id = 3,
EC = ECP_ShortW_Proj[Fp2[BLS12_377], OnTwist],
Px0 = "52b54c30c1dcadbcb698d0cb7fd65de1eb8f7590c7afe46e019bdc9e0ef8bc4c060339220d3615e4b1f2b12ffa6d83",
Px1 = "dd53b483c2ab1aaa7ed22ef619b5e979237ae95476436f2c51c8b70da39a4e54a989f10f6d12ee098154911aa052f6",
Py0 = "2a8c96662a7c76cb7d8ca6571a5b99abfd2d7343dd668425e5fa4a8c880b313b70f09a15a825fac63ae7065c0c51d",
Py1 = "7bd93bb9d5bfdd15636a34a13385e9abbc1088ecc02c86cbc733122ccbbb657ec8d75e47102ce46d35a9612c01fc3d",
scalar = "e0c564e69ad68343fd4ec3d4dafdf6a92f44c13fc70a9aad95d10b2c96ee747",
Qx0 = "126f6039b7031b73a7f926bd443ace416f62e56f03864d660bbe1f1a2a994672d408f9936293f367d3fb5d8e275ad40",
Qx1 = "1654a2c26479ace1eb68e279eceac6aa10680549b09f42d288767f6296c98ba4299fa6df37a946b88823a5deebc231c",
Qy0 = "23026839059191f71e2abcf582234aa2ce4b4225c3d503e8fc6c119df1168192e894f33ed48bc571e5527365dd92b5",
Qy1 = "11f8fcce53f5e3211290e6c72736eb1c9d2e159dd243f3e493c430f0411864e109af09a3b9379c4b332815e012caa80"
)
test(
id = 4,
EC = ECP_ShortW_Proj[Fp2[BLS12_377], OnTwist],
Px0 = "fb6dd822e327a60c9e55d760c4f5d26783617a06f868835c2f46e902108eaca5d60fd64c0a0c8a6dc12f9352dfef33",
Px1 = "85e97eef3b4e42a93b8421644e9334f4543a25a36ccd41d448c385146baf3b1efbaeac49c202b04cdbf8b50f3fd962",
Py0 = "8db78b315a524f17ac3d69333604e6bc8aa0b2f138f9adf7edb19f49c847eda6b64df9fe2576b7687e7b55cb5f0bd0",
Py1 = "d4a0c7e5e7aaacab0e0e60c6c49624971a161de4f0daa7968f80998fb7b4761b1196964b26fefa9337fd133784e3d9",
scalar = "1abce9e9c079c686864304d479d68087db33f9edb3f7b2e4655fe0c1da4993f",
Qx0 = "1238814ea497bc1b65ba1c0fbfc394427b10b2d8783bf6a04e01505bc165b577cb2366c19c24c555235ff9b16e7233a",
Qx1 = "b156205cad5d2d97d24c45fe218cd412f47248f26d579fb368af5ba2d80b8c95e2a68f4c84540a8b78b2f0a33a48a4",
Qy0 = "12154ce4a569b39ccfe464a7559b8baf03d3fb6462e67dc0c4ae79a3c33b7756e0c558eff64f9558ebd6500086684f8",
Qy1 = "74571a18fc091f4d77cc7d363bf7a34ab4d0dca86c160b261b383e416f68fa553d7b8b8f6317c8e340ce454daffb5f"
)
test(
id = 5,
EC = ECP_ShortW_Proj[Fp2[BLS12_377], OnTwist],
Px0 = "b56e23f2558c3c124f024952e1858067223541f51a8885d161133beb7bf8d64f22163769e604afbf7fbfb02e1fcb43",
Px1 = "e10c4366d667b40488a9ae32daf3e2a5cc8ddf25ed407afe1a38b855f3ac4f7ea20455924e71369eed07114613b633",
Py0 = "f42d3ab4716d10384bcdfec38cba997c2bafb8d8de32a47225a3e2d2835be1ad02a63323d3dd4145db21e3cbf5cc7a",
Py1 = "15f48a901f3dfd3b812a455f1297e8311c4608869ea02d3d16e9aafdf610d7e72f34b02830de8cc0d0f4e909af5827d",
scalar = "401e70df8ccaa504da72b1d649c067f3b752156dcea5b48dcb601710ab0baa3",
Qx0 = "949099ea1ece1be6fa3f3537e8ba39587b40003fb409a4beb831bb1d9d999b7c621b9a1ced3223f710e0bd05f4a018",
Qx1 = "cdfc0d47788bca3672126e0facc05c19a4fb24a43eee32c8e08a6e5152f6af1d7c2efa48907046f90a721ed28fcf7",
Qy0 = "11d608a01cfe1a40806b9951f85a7bb1b6df6e4c4e2c7c50c17e8fad6ed397a430aff9b4742408367d6536fe503692a",
Qy1 = "19c25d8a782b9d8d9f067d345fd03afe50439c82f99a06abca790f2fae944677d8095d2e276fcb7a75cfb2cbccf89d7"
)
test(
id = 6,
EC = ECP_ShortW_Proj[Fp2[BLS12_377], OnTwist],
Px0 = "137001541ab8a479362ee39f818fc38788231e5288ceea5ebe0c08d0bbca3be9519aa415bde98428df26d361b7311ea",
Px1 = "411b1a4f0abb9fd255a7ae26ac39c1f2c88a48f82c7623b6f225aec9755206e27084b23cbc98f31399405a6599dc54",
Py0 = "833ef097986116cab669c4fddff9b831535d100644f732fb0da0a2dce17d69beaeed67230dd66392e840679afbae1e",
Py1 = "f63e809bd55617c31570d686dbc9b94b3cb96c154f9983181cb913a0671c0c16143332087e44a0283ebf01eea6d73b",
scalar = "10697220c755c800861d377c55b22ae48c25dc144e1fa7a1e5bbdf82993aa33c",
Qx0 = "10fc7772bb2bc946e3ff659c01a0452ebf5dd1472bd1aa71e198597fd05361bf0d173817f91fcb8a1b96b46c35d2675",
Qx1 = "d7b00ddf32f9d8e549c05dd605931ef737d8a4bc62795f73044482957b8093b1cdad0f55c7d4edf6f59594a13f9b67",
Qy0 = "148756a592dec0bf2fda41ac219c4a891ef427665ba1cf47b58bed4996cf8937fb07929c041f10e8a55b2238944fd30",
Qy1 = "e4a240f5c32dab76575ace4d035cbd1e2b87d7585fee7bfde9c88e918a7ad2cd8eb4982acfacfac58c33c8a54ddac7"
)
test(
id = 7,
EC = ECP_ShortW_Proj[Fp2[BLS12_377], OnTwist],
Px0 = "1580ffccc21b057dfe4831f950cbb8f1436f999df657404ecec20225a929a5d56920e8662abc426de23402643087308",
Px1 = "8bf8ff20713a9054aa1cce9635eb3d6ac8371fc052b747a8414595708ff9462d64a0a11ff2c1c5121f4ecc5f22df5e",
Py0 = "e7a5f7df0cec03de25da415fdda485ecc1443b95352e47b23e5506b820c9bc9ea9c2d9e99dd48e1f74e1befe58ce80",
Py1 = "12b5638a0f7e508016fddd2dae2d84736efa59c53f2a5d979b9a29fc7c9c406407bb5f5788bcea3529ac1a763c72e8b",
scalar = "bd936c7066316d3f86b077419a0c0fb9867d4612208241fc004b548f1f54fad",
Qx0 = "69e3411725062858ca7e5fc4d648037baf10e34ba6830ff0090e7188932112b9458c4f4b82f2f0f06c6501fcdaa86c",
Qx1 = "127b75c55c90a872c1d749d05609d2499065ac3c9eb96bd6a9816bd7a2315795ddf40944baef1907676395df306860e",
Qy0 = "13fd0e314159909d3091e382017b35ec21ee2004e9082cd24338817046ed2202ffed52e7714cf436b953f95f49f9856",
Qy1 = "5a8ccdf4a1600fafcc86c646d83199c41cbfebf7a1fa2b1cb9c408352be46a33d0f411b175348f42382d170e17ec2b"
)
test(
id = 8,
EC = ECP_ShortW_Proj[Fp2[BLS12_377], OnTwist],
Px0 = "10898a074b6931cc4ada152b64dd1c6b2bb47912e6502b9e88f638e489c144f8aa9b9f915bb428e082ec84676607f40",
Px1 = "18484823648fe1699468e2d265cd2f2e381a0e67f35f8d192259e2a14573692b4e1fbdeed639e9b6eb0731be820b166",
Py0 = "1840bc6fcb224efe00e32f827fa4f9694cd4186493089c66a936e912b50346b75542b6edbe51ba95c88d3b0fcac34ed",
Py1 = "18cb4201510933776a28ff1c44d356ceab065880f5242d8cc7cdf86874568df679b20f34b6a216d0047d2e1c1a16b85",
scalar = "bdb46c0eece9c8bac8a382def90b522b1d5197f09cf9f7cd98b710845ddb7b4",
Qx0 = "102779766b0068b176e118348e4163e89e3171e6eaad0e47f00cad626f8db025ec3ea990363813882c3dcfcbb642240",
Qx1 = "131eb563d2b0145eee52ee7586acd0254f103f02a20de3bf0202d1cffec2c3628501ec20f9f2ae5f461b59604afc04c",
Qy0 = "1463527db149d2c76f30c082786edb3fe1a9c7f4e04f9496e7adb40aab89340d9792f7d75cf3f5f81b0a28f09625175",
Qy1 = "f3190261db082c207ccd88a3ba762d2c0ba330548444afca03c8535ff11c7c90659a867dda3712a83f02ad184eb24a"
)
test(
id = 9,
EC = ECP_ShortW_Proj[Fp2[BLS12_377], OnTwist],
Px0 = "13c3a392307124afb5f219ba0f8062fa9b75654d3fff12bc924592d284af550f039b6ac58880d2c6fea146b3982f03c",
Px1 = "188169bc937fcc20cc9c289adef30580188f64ecb126faadb5b888f31b813727ff7046d1a19b81abeea6609b8b208c6",
Py0 = "2f9bde8fdd43c5f4de30f335a480dca3bf0858464d8368984406f10ddc1ecabb15fcfd11cebd4fef426e7ca9411221",
Py1 = "25505653e199c354f2da8a13ed9de47f9b51a06ad2fa8826c4b8a9c61c6e75268807d7053e06bfc2899d1a3d6deeb4",
scalar = "91c6249ee16ef94d0b905575982419a7cf31d125775e7ede5c0ab4f86defd33",
Qx0 = "1967547943b197311a7d6723dcc37c3e649f173cec1c88ffca27df86518b3392ae0ee13dbca375c928b94d129226852",
Qx1 = "18b793916195f2d7d2a47c3f8243e5bdc239e78a3eb26971dac01b5f4ce14081a06529ab66cda8e8d5537808223fd00",
Qy0 = "a784902a14ad39adcfdc52bc30d8b8711b93dd869af2375a1f408ba8610b5c558bbebfe9f8f9875954780f4b4262c0",
Qy1 = "fb1c766957c89e4d67747549f650070983e6c19d0208b7e65478e4dd4f72fc54fca450d96329182e3f00d16ae0f3a"
)
# -----------------
test(
id = 0,
EC = ECP_ShortW_Jac[Fp2[BLS12_377], OnTwist],
Px0 = "267401f3ef554fe74ae131d56a10edf14ae40192654901b4618d2bf7af22e77c2a9b79e407348dbd4aad13ca73b33a",
Px1 = "12dcca838f46a3e0418e5dd8b978362757a16bfd78f0b77f4a1916ace353938389ae3ea228d0eb5020a0aaa58884aec",
Py0 = "11799118d2e054aabd9f74c0843fecbdc1c0d56f61c61c5854c2507ae2416e48a6b2cd3bc8bf7495a4d3d8270eafe2b",
Py1 = "823b9f8fb9f8297734a14359fa2c2a0de275e7e638197eaaaa7cff28f9cb3101bdabb570016672455f1ecae625e294",
scalar = "9d432eb58ec68bbc09d10961451d99c7796fb2f795eca603d6feaf3e2a1634b",
Qx0 = "12cfcb50345d43271d2a20e8208789c8ca82f2b8732fae4e7cccd87eb0883741d5e77166971c38c54170bf7635ca2f3",
Qx1 = "17467c786368f2f6eabd78f1c24aa668eae9cd00f6045bfd86b1b3c40966f023a71927026ae5a1281b432ac980d2b6b",
Qy0 = "6f5f1068b6e6a8fafd96894d8b0a8548acee24319d8e2d8b6e6982b1ced8970d9fe33155e74b33d6c2a7835196ca9",
Qy1 = "dc3c7c91c712f9a2631d2b5e49497d8cdf2ea4b30859b43edd716e84cd6a8b61e63cf708d263a7845913cdfb9c7f3b"
)
test(
id = 1,
EC = ECP_ShortW_Jac[Fp2[BLS12_377], OnTwist],
Px0 = "3a3055d6a46901c1b2227a0e334ffa9f654e62a6d3608f3a672e5816f9e9b04c0e668c3e9f8c807b269422afdc7de9",
Px1 = "25803bd55f37b254865d5fc7ac9843fb306c2eb09d34ee0c4ecb705b5e10f6911f07fd707a2e28681a421f45b1a4d",
Py0 = "15a0594a3c9dddc535472c4827aa443774a06f77bec2d20837c6574aa5fac35a279bac756531fa75f979a7a97f297d6",
Py1 = "15e8c3e013cbc64110f075295f39a4f85c9591a52b8e4903047b1f4b44bb5216b6339788c82fd90e82b1027756e7987",
scalar = "a0067f5b4294fbacd24730fed25c936a08b5f1a77824149ad6c2ce476518d17",
Qx0 = "6280dbf019f8d94acac4a39213e03f221be732849b45437edef7617460e83f972883c20791a86670a8a4c6c0125629",
Qx1 = "ab3a185addbd6c7db907170d75bd2f1997666e93d8cedbef9e10a103110d4ea09d9a889f505d7026e5c498b0355c1",
Qy0 = "1a6dd15b4c2bd6bd97858e5a75ac4365f8becaa885c4e3267d0ae256655cd057061d61b2b9acbd10bdf678a9c1e7f8c",
Qy1 = "16204b5825eec903cb7798cb62ccadb9004032d72bb815958fcd2f613c77e147656449fdaa210994338978676ad6b0e"
)
test(
id = 2,
EC = ECP_ShortW_Jac[Fp2[BLS12_377], OnTwist],
Px0 = "18ebf549cd24a64badff4ec177205be121757b68589020434aba816756d2e6fa95fdb389c8639d4bf77575122e1c04e",
Px1 = "11cd0f0976658a6f2ec113034428ef1605befdaa5642944f5c4e571b24fc166c368c30473e25ab148209be4c0b4e37",
Py0 = "1190d818317495201732feb2cfc8f507adac6273debff46bb6aea4a3f3e3fe7d28d893c90b21a6f28d2fbc72d9fc528",
Py1 = "df5fcb2daa302a5c64aeef96835e0a6b39f5d7bf0e70cc10401f966745a6b3fa682b7e5b45d9295e744e1dd7855fd4",
scalar = "7a49802ba58c87c30b631b2f90a3b876c7143e09b542c9c14706bddf9bd4117",
Qx0 = "6cdff80576d8695a646f915caba5bc6748eee1707bb0d4ebcabaf8d236b780aef6a953a07f48ef4696f02db4906c71",
Qx1 = "6b64ca5f0d46702e7e9e7beb1993b698c9b3e9991f545241d5fd44a27dc692d5f5a4c2fe6871af0653128f960307d4",
Qy0 = "cfad02b664495d42d1c6b598306229c67bcf76cc923abb13ae038c90e959a7611161a98d607729577d55ec18bf1e74",
Qy1 = "e433d9dd7d47d94e9f61a5bc27a688c63efa05408d6fd40a5c4e2711a37d011dc80f5dbaaafd939a07235c770feead"
)
test(
id = 3,
EC = ECP_ShortW_Jac[Fp2[BLS12_377], OnTwist],
Px0 = "52b54c30c1dcadbcb698d0cb7fd65de1eb8f7590c7afe46e019bdc9e0ef8bc4c060339220d3615e4b1f2b12ffa6d83",
Px1 = "dd53b483c2ab1aaa7ed22ef619b5e979237ae95476436f2c51c8b70da39a4e54a989f10f6d12ee098154911aa052f6",
Py0 = "2a8c96662a7c76cb7d8ca6571a5b99abfd2d7343dd668425e5fa4a8c880b313b70f09a15a825fac63ae7065c0c51d",
Py1 = "7bd93bb9d5bfdd15636a34a13385e9abbc1088ecc02c86cbc733122ccbbb657ec8d75e47102ce46d35a9612c01fc3d",
scalar = "e0c564e69ad68343fd4ec3d4dafdf6a92f44c13fc70a9aad95d10b2c96ee747",
Qx0 = "126f6039b7031b73a7f926bd443ace416f62e56f03864d660bbe1f1a2a994672d408f9936293f367d3fb5d8e275ad40",
Qx1 = "1654a2c26479ace1eb68e279eceac6aa10680549b09f42d288767f6296c98ba4299fa6df37a946b88823a5deebc231c",
Qy0 = "23026839059191f71e2abcf582234aa2ce4b4225c3d503e8fc6c119df1168192e894f33ed48bc571e5527365dd92b5",
Qy1 = "11f8fcce53f5e3211290e6c72736eb1c9d2e159dd243f3e493c430f0411864e109af09a3b9379c4b332815e012caa80"
)
test(
id = 4,
EC = ECP_ShortW_Jac[Fp2[BLS12_377], OnTwist],
Px0 = "fb6dd822e327a60c9e55d760c4f5d26783617a06f868835c2f46e902108eaca5d60fd64c0a0c8a6dc12f9352dfef33",
Px1 = "85e97eef3b4e42a93b8421644e9334f4543a25a36ccd41d448c385146baf3b1efbaeac49c202b04cdbf8b50f3fd962",
Py0 = "8db78b315a524f17ac3d69333604e6bc8aa0b2f138f9adf7edb19f49c847eda6b64df9fe2576b7687e7b55cb5f0bd0",
Py1 = "d4a0c7e5e7aaacab0e0e60c6c49624971a161de4f0daa7968f80998fb7b4761b1196964b26fefa9337fd133784e3d9",
scalar = "1abce9e9c079c686864304d479d68087db33f9edb3f7b2e4655fe0c1da4993f",
Qx0 = "1238814ea497bc1b65ba1c0fbfc394427b10b2d8783bf6a04e01505bc165b577cb2366c19c24c555235ff9b16e7233a",
Qx1 = "b156205cad5d2d97d24c45fe218cd412f47248f26d579fb368af5ba2d80b8c95e2a68f4c84540a8b78b2f0a33a48a4",
Qy0 = "12154ce4a569b39ccfe464a7559b8baf03d3fb6462e67dc0c4ae79a3c33b7756e0c558eff64f9558ebd6500086684f8",
Qy1 = "74571a18fc091f4d77cc7d363bf7a34ab4d0dca86c160b261b383e416f68fa553d7b8b8f6317c8e340ce454daffb5f"
)
test(
id = 5,
EC = ECP_ShortW_Jac[Fp2[BLS12_377], OnTwist],
Px0 = "b56e23f2558c3c124f024952e1858067223541f51a8885d161133beb7bf8d64f22163769e604afbf7fbfb02e1fcb43",
Px1 = "e10c4366d667b40488a9ae32daf3e2a5cc8ddf25ed407afe1a38b855f3ac4f7ea20455924e71369eed07114613b633",
Py0 = "f42d3ab4716d10384bcdfec38cba997c2bafb8d8de32a47225a3e2d2835be1ad02a63323d3dd4145db21e3cbf5cc7a",
Py1 = "15f48a901f3dfd3b812a455f1297e8311c4608869ea02d3d16e9aafdf610d7e72f34b02830de8cc0d0f4e909af5827d",
scalar = "401e70df8ccaa504da72b1d649c067f3b752156dcea5b48dcb601710ab0baa3",
Qx0 = "949099ea1ece1be6fa3f3537e8ba39587b40003fb409a4beb831bb1d9d999b7c621b9a1ced3223f710e0bd05f4a018",
Qx1 = "cdfc0d47788bca3672126e0facc05c19a4fb24a43eee32c8e08a6e5152f6af1d7c2efa48907046f90a721ed28fcf7",
Qy0 = "11d608a01cfe1a40806b9951f85a7bb1b6df6e4c4e2c7c50c17e8fad6ed397a430aff9b4742408367d6536fe503692a",
Qy1 = "19c25d8a782b9d8d9f067d345fd03afe50439c82f99a06abca790f2fae944677d8095d2e276fcb7a75cfb2cbccf89d7"
)
test(
id = 6,
EC = ECP_ShortW_Jac[Fp2[BLS12_377], OnTwist],
Px0 = "137001541ab8a479362ee39f818fc38788231e5288ceea5ebe0c08d0bbca3be9519aa415bde98428df26d361b7311ea",
Px1 = "411b1a4f0abb9fd255a7ae26ac39c1f2c88a48f82c7623b6f225aec9755206e27084b23cbc98f31399405a6599dc54",
Py0 = "833ef097986116cab669c4fddff9b831535d100644f732fb0da0a2dce17d69beaeed67230dd66392e840679afbae1e",
Py1 = "f63e809bd55617c31570d686dbc9b94b3cb96c154f9983181cb913a0671c0c16143332087e44a0283ebf01eea6d73b",
scalar = "10697220c755c800861d377c55b22ae48c25dc144e1fa7a1e5bbdf82993aa33c",
Qx0 = "10fc7772bb2bc946e3ff659c01a0452ebf5dd1472bd1aa71e198597fd05361bf0d173817f91fcb8a1b96b46c35d2675",
Qx1 = "d7b00ddf32f9d8e549c05dd605931ef737d8a4bc62795f73044482957b8093b1cdad0f55c7d4edf6f59594a13f9b67",
Qy0 = "148756a592dec0bf2fda41ac219c4a891ef427665ba1cf47b58bed4996cf8937fb07929c041f10e8a55b2238944fd30",
Qy1 = "e4a240f5c32dab76575ace4d035cbd1e2b87d7585fee7bfde9c88e918a7ad2cd8eb4982acfacfac58c33c8a54ddac7"
)
test(
id = 7,
EC = ECP_ShortW_Jac[Fp2[BLS12_377], OnTwist],
Px0 = "1580ffccc21b057dfe4831f950cbb8f1436f999df657404ecec20225a929a5d56920e8662abc426de23402643087308",
Px1 = "8bf8ff20713a9054aa1cce9635eb3d6ac8371fc052b747a8414595708ff9462d64a0a11ff2c1c5121f4ecc5f22df5e",
Py0 = "e7a5f7df0cec03de25da415fdda485ecc1443b95352e47b23e5506b820c9bc9ea9c2d9e99dd48e1f74e1befe58ce80",
Py1 = "12b5638a0f7e508016fddd2dae2d84736efa59c53f2a5d979b9a29fc7c9c406407bb5f5788bcea3529ac1a763c72e8b",
scalar = "bd936c7066316d3f86b077419a0c0fb9867d4612208241fc004b548f1f54fad",
Qx0 = "69e3411725062858ca7e5fc4d648037baf10e34ba6830ff0090e7188932112b9458c4f4b82f2f0f06c6501fcdaa86c",
Qx1 = "127b75c55c90a872c1d749d05609d2499065ac3c9eb96bd6a9816bd7a2315795ddf40944baef1907676395df306860e",
Qy0 = "13fd0e314159909d3091e382017b35ec21ee2004e9082cd24338817046ed2202ffed52e7714cf436b953f95f49f9856",
Qy1 = "5a8ccdf4a1600fafcc86c646d83199c41cbfebf7a1fa2b1cb9c408352be46a33d0f411b175348f42382d170e17ec2b"
)
test(
id = 8,
EC = ECP_ShortW_Jac[Fp2[BLS12_377], OnTwist],
Px0 = "10898a074b6931cc4ada152b64dd1c6b2bb47912e6502b9e88f638e489c144f8aa9b9f915bb428e082ec84676607f40",
Px1 = "18484823648fe1699468e2d265cd2f2e381a0e67f35f8d192259e2a14573692b4e1fbdeed639e9b6eb0731be820b166",
Py0 = "1840bc6fcb224efe00e32f827fa4f9694cd4186493089c66a936e912b50346b75542b6edbe51ba95c88d3b0fcac34ed",
Py1 = "18cb4201510933776a28ff1c44d356ceab065880f5242d8cc7cdf86874568df679b20f34b6a216d0047d2e1c1a16b85",
scalar = "bdb46c0eece9c8bac8a382def90b522b1d5197f09cf9f7cd98b710845ddb7b4",
Qx0 = "102779766b0068b176e118348e4163e89e3171e6eaad0e47f00cad626f8db025ec3ea990363813882c3dcfcbb642240",
Qx1 = "131eb563d2b0145eee52ee7586acd0254f103f02a20de3bf0202d1cffec2c3628501ec20f9f2ae5f461b59604afc04c",
Qy0 = "1463527db149d2c76f30c082786edb3fe1a9c7f4e04f9496e7adb40aab89340d9792f7d75cf3f5f81b0a28f09625175",
Qy1 = "f3190261db082c207ccd88a3ba762d2c0ba330548444afca03c8535ff11c7c90659a867dda3712a83f02ad184eb24a"
)
test(
id = 9,
EC = ECP_ShortW_Jac[Fp2[BLS12_377], OnTwist],
Px0 = "13c3a392307124afb5f219ba0f8062fa9b75654d3fff12bc924592d284af550f039b6ac58880d2c6fea146b3982f03c",
Px1 = "188169bc937fcc20cc9c289adef30580188f64ecb126faadb5b888f31b813727ff7046d1a19b81abeea6609b8b208c6",
Py0 = "2f9bde8fdd43c5f4de30f335a480dca3bf0858464d8368984406f10ddc1ecabb15fcfd11cebd4fef426e7ca9411221",
Py1 = "25505653e199c354f2da8a13ed9de47f9b51a06ad2fa8826c4b8a9c61c6e75268807d7053e06bfc2899d1a3d6deeb4",
scalar = "91c6249ee16ef94d0b905575982419a7cf31d125775e7ede5c0ab4f86defd33",
Qx0 = "1967547943b197311a7d6723dcc37c3e649f173cec1c88ffca27df86518b3392ae0ee13dbca375c928b94d129226852",
Qx1 = "18b793916195f2d7d2a47c3f8243e5bdc239e78a3eb26971dac01b5f4ce14081a06529ab66cda8e8d5537808223fd00",
Qy0 = "a784902a14ad39adcfdc52bc30d8b8711b93dd869af2375a1f408ba8610b5c558bbebfe9f8f9875954780f4b4262c0",
Qy1 = "fb1c766957c89e4d67747549f650070983e6c19d0208b7e65478e4dd4f72fc54fca450d96329182e3f00d16ae0f3a"
)
run_scalar_mul_test_vs_sage(
ECP_ShortW_Jac[Fp2[BLS12_377], OnTwist],
"t_ec_sage_bls12_377_g2_jacobian"
)

View File

@ -7,573 +7,30 @@
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import
# Standard library
std/[unittest, times],
# Internals
../constantine/config/[common, curves],
../constantine/arithmetic,
../constantine/config/[type_fp, curves],
../constantine/towers,
../constantine/io/[io_bigints, io_ec],
../constantine/elliptic/[
ec_shortweierstrass_projective,
ec_shortweierstrass_jacobian,
ec_scalar_mul,
ec_endomorphism_accel],
../constantine/elliptic/ec_shortweierstrass_jacobian,
../constantine/elliptic/ec_shortweierstrass_projective,
# Test utilities
./support/ec_reference_scalar_mult
./t_ec_sage_template
echo "\n------------------------------------------------------\n"
run_scalar_mul_test_vs_sage(
ECP_ShortW_Proj[Fp[BLS12_381], NotOnTwist],
"t_ec_sage_bls12_381_g1_projective"
)
proc test(
id: int,
EC: typedesc[ECP_ShortW_Proj or ECP_ShortW_Jac],
Px, Py: string,
scalar: string,
Qx, Qy: string
) =
run_scalar_mul_test_vs_sage(
ECP_ShortW_Jac[Fp[BLS12_381], NotOnTwist],
"t_ec_sage_bls12_381_g1_jacobian"
)
test "test " & $id & " - " & $EC:
var P: EC
let pOK = P.fromHex(Px, Py)
doAssert pOK
run_scalar_mul_test_vs_sage(
ECP_ShortW_Proj[Fp2[BLS12_381], OnTwist],
"t_ec_sage_bls12_381_g2_projective"
)
var Q: EC
let qOK = Q.fromHex(Qx, Qy)
let exponent = BigInt[EC.F.C.getCurveOrderBitwidth()].fromHex(scalar)
var
impl = P
reference = P
endo = P
endoW = P
impl.scalarMulGeneric(exponent)
reference.unsafe_ECmul_double_add(exponent)
endo.scalarMulEndo(exponent)
endoW.scalarMulGLV_m2w2(exponent)
doAssert: bool(Q == reference)
doAssert: bool(Q == impl)
doAssert: bool(Q == endo)
doAssert: bool(Q == endoW)
suite "Scalar Multiplication (cofactor cleared): BLS12_381 implementation vs SageMath" & " [" & $WordBitwidth & "-bit mode]":
# Generated via sage sage/testgen_bls12_381.sage
test(
id = 0,
EC = ECP_ShortW_Proj[Fp[BLS12_381], NotOnTwist],
Px = "f9679bb02ee7f352fff6a6467a5e563ec8dd38c86a48abd9e8f7f241f1cdd29d54bc3ddea3a33b62e0d7ce22f3d244a",
Py = "50189b992cf856846b30e52205ff9ef72dc081e9680726586231cbc29a81a162120082585f401e00382d5c86fb1083f",
scalar = "f7e60a832eb77ac47374bc93251360d6c81c21add62767ff816caf11a20d8db",
Qx = "c344f3bcc86df380186311fa502b7943a436a629380f8ee1960515522eedc58fe67ddd47615487668bcf12842c524d8",
Qy = "189e0c154f2631ad26e24ca73d84fb60a21d385fe205df04cf9f2f6fc0c3aa72afe9fbea71a930fa71d9bbfddb2fa571"
)
test(
id = 1,
EC = ECP_ShortW_Proj[Fp[BLS12_381], NotOnTwist],
Px = "17d71835ff84f150fabf5c77ac90bf7f6249143abd1f5d8a46a76f243d424d82e1e258fc7983ba8af97a2462adebe090",
Py = "d3e108ee1332067cbe4f4193eae10381acb69f493b40e53d9dee59506b49c6564c9056494a7f987982eb4069512c1c6",
scalar = "5f10367bdae7aa872d90b5ac209321ce5a15181ce22848d032a8d452055cbfd0",
Qx = "21073bee733a07b15d83afcd4e6ee11b01e6137fd5ad4589c5045e12d79a9a9490a3ebc59f30633a60fc3635a3c1e51",
Qy = "eb7a97a9d3dfff1667b8fa559bdcdf37c7767e6afb8ca93ad9dd44feb93761e10aa2c4c1a79728a21cd4a6f705398b5"
)
test(
id = 2,
EC = ECP_ShortW_Proj[Fp[BLS12_381], NotOnTwist],
Px = "f92c9572692e8f3d450483a7a9bb4694e3b54c9cd09441a4dd7f579b0a6984e47f8090c31c172b33d87f3de186d6b58",
Py = "286ede4cb2ae19ead4932d5550c5d3ec8ce3a3ada5e1ed6d202e93dd1b16d3513f0f9b62adc6323f18e272a426ee955",
scalar = "4c321d72220c098fc0fd52306de98f8be9446bf854cf1e4d8dbae62375d18faf",
Qx = "4bb385e937582ae32aa7ba89632fcef2eace3f7b57309d979cf35298a430de9ef4d9ac5ba2335c1a4b6e7e5c38d0036",
Qy = "1801154d3a7b0daea772345b7f72a4c88c9677743f267da63490dad4dece2ecc9ec02d4d4d063086ee5d356aa2db914e"
)
test(
id = 3,
EC = ECP_ShortW_Proj[Fp[BLS12_381], NotOnTwist],
Px = "ec23ff3435b8ebd5e8e0a879d432e11eb974161664b1341fd28f1ffc4c228bf6ada2ae4a565f18c9b66f67a7573502d",
Py = "10c4b647be08db0b49b75320ae891f9f9c5d7bb7c798947e800d681d205d1b24b12e4dfa993d1bd16851b00356627cc1",
scalar = "1738857afb76c55f615c2a20b44ca90dcb3267d804ec23fddea431dbee4eb37f",
Qx = "dc7ae7801152918ee3c13590407b4242a80d0b855a0bf585d3dc30719601d2d5d9e01e99ae735003ecb7c20ef48265",
Qy = "142c01a6aa390426a4ce2f36df43f86442732c35d4e05e5b67f3623832944f0ea5a29138624cb939330652a3cfb282b5"
)
test(
id = 4,
EC = ECP_ShortW_Proj[Fp[BLS12_381], NotOnTwist],
Px = "df127083c2a5ef2388b02af913c0e4002a52a82db9e5ecbf23ee4f557d3b61c91ebcfe9d4973070b46bc5ea6897bca1",
Py = "318960aeea262ec23ffdd42ec1ba72ae6fa2186a1e2a0fc2659073fb7b5adfb50d581a4d998a94d1accf78b1b3a0163",
scalar = "19c47811813444020c999a2b263940b5054cf45bb8ad8e086ff126bfcd5507e1",
Qx = "5f93c42fd76a29063efa2ee92607e0b3ae7edc4e419b3914661e5162d6beaeb96a34d2007ff817bc102651f61dca8d1",
Qy = "18dde8666bb1d0a379719d7d1b1512de809b70e49d9553303274ea872e56f7f39da551d6bcb7c57ae88ec7dc1fb354a4"
)
test(
id = 5,
EC = ECP_ShortW_Proj[Fp[BLS12_381], NotOnTwist],
Px = "101123de23c0f240c583c2368c4118dc942db219c55f58cf54acd500c1fcfa06f651ad75319ebf840cbdb6bddea7fde4",
Py = "5268587d4b844b0708e0336d1bbf48da185aaf5b948eccc3b565d00a856dd55882b9bb31c52af0e275b168cb35eb7b0",
scalar = "43ffcda71e45a3e90b7502d92b30a0b06c54c95a91aa21e0438677b1c2714ecb",
Qx = "f9871b682c1c76c7f4f0a7ca57ad876c10dc108b65b76987264873278d9f54db95101c173aed06d07062efc7d47ca0c",
Qy = "20d9628d611e72a4251a1f2357d4f53e68e4915383b6a0d126273d216b1a8c5e2cb7b2688ad702ef1682f4c5228fcd9"
)
test(
id = 6,
EC = ECP_ShortW_Proj[Fp[BLS12_381], NotOnTwist],
Px = "1457ba1bae6eb3afae3261941c65c93e3ae7d784907d15b8d559100da5e13fd29e4a4d6e3103b781a95237b7b2d80a8e",
Py = "6a869a47cb48d01e7d29660932afd7617720262b55de5f430b8aa3d74f9fd2b9d3a07ce192425da58014764fc9532cd",
scalar = "64ad0d6c36dba5368e71f0010aebf860288f54611e5aaf18082bae7a404ebfd8",
Qx = "93e540e26190e161038d985d40f2ab897cbc2346be7d8f2b201a689b59d4020a8740e252606f2f79ba0e121ccc9976d",
Qy = "10568d68f1b993aa1eded3869eda14e509f1cb4d8553bdf97feee175467cea4c0c1316fdb4e5a68440ad04b96b2d3bfc"
)
test(
id = 7,
EC = ECP_ShortW_Proj[Fp[BLS12_381], NotOnTwist],
Px = "2615f843e8fe68d4c337bcf83b2cf13cbae638edd0740f1eac520dc2146afa3b8d36c540878c1d207ef913634b1e593",
Py = "1787d6eeeceb6e7793073f0bbe7bae522529c126b650c43d5d41e732c581a57df1bfb818061b7b4e6c9145da5df2c43e",
scalar = "b0ac3d0e685583075aa46c03a00859dfbec24ccb36e2cae3806d82275adcc03",
Qx = "d95ed29c2e15fd2205d83a71478341d6022deb93af4d49f704437678a72ce141d2f6043aa0e34e26f60d17e16b97053",
Qy = "b37cbded112c84116b74ff311b10d148f3e203cb88d4a011b096c74cd2bfdb27255727de4aa8299ae10b32d661d48a7"
)
test(
id = 8,
EC = ECP_ShortW_Proj[Fp[BLS12_381], NotOnTwist],
Px = "10bc0c4e1ed87246a9d4d7d38546369f275a245f6e1d3b882e8c9a7f05bc6ee8ff97a96a54084c2bef15ed8bfefb1465",
Py = "1782377e5f588576b5ab42fea224e88873dda957202f0c6d72ce8728c2d58dc654be77226fbda385d5f269354e4a176a",
scalar = "23941bb3c3659423d6fdafb7cff52e0e02de0ac91e64c537c6203d64905b63d0",
Qx = "83f1e7e8bd963c1ccd837dae7bc9336531aaf0aee717537a9a7e2712e220f74cdb73a99f331c0eb6b377be3dafc211f",
Qy = "cd87773d072b1305dfc85c2983aecae2ab316e5e8f31306c32d58d6ce2e431b12685d18c58b6a35ad2113c5b689eeb"
)
test(
id = 9,
EC = ECP_ShortW_Proj[Fp[BLS12_381], NotOnTwist],
Px = "be4f9f721d98a761a5562bd80ea06f369e9cbb7d33bbb2f0191d4b77d0fd2a10c4083b54157b525f36c522ca3a6ca09",
Py = "166c315ecdd20acb3c5efcc7e038b17d0b37a06ffbf77873f15fc0cd091a1e4102a8b8bf5507919453759e744391b04d",
scalar = "4203156dcf70582ea8cbd0388104f47fd5a18ae336b2fed8458e1e4e74d7baf5",
Qx = "c72bc7087cd22993b7f6d2e49026abfde678a384073ed373b95df722b1ab658eb5ae42211e5528af606e38b59511bc6",
Qy = "96d80593b42fe44e64793e490b1257af0aa26b36773aac93c3686fdb14975917cf60a1a19e32623218d0722dbb88a85"
)
# -----
test(
id = 0,
EC = ECP_ShortW_Jac[Fp[BLS12_381], NotOnTwist],
Px = "f9679bb02ee7f352fff6a6467a5e563ec8dd38c86a48abd9e8f7f241f1cdd29d54bc3ddea3a33b62e0d7ce22f3d244a",
Py = "50189b992cf856846b30e52205ff9ef72dc081e9680726586231cbc29a81a162120082585f401e00382d5c86fb1083f",
scalar = "f7e60a832eb77ac47374bc93251360d6c81c21add62767ff816caf11a20d8db",
Qx = "c344f3bcc86df380186311fa502b7943a436a629380f8ee1960515522eedc58fe67ddd47615487668bcf12842c524d8",
Qy = "189e0c154f2631ad26e24ca73d84fb60a21d385fe205df04cf9f2f6fc0c3aa72afe9fbea71a930fa71d9bbfddb2fa571"
)
test(
id = 1,
EC = ECP_ShortW_Jac[Fp[BLS12_381], NotOnTwist],
Px = "17d71835ff84f150fabf5c77ac90bf7f6249143abd1f5d8a46a76f243d424d82e1e258fc7983ba8af97a2462adebe090",
Py = "d3e108ee1332067cbe4f4193eae10381acb69f493b40e53d9dee59506b49c6564c9056494a7f987982eb4069512c1c6",
scalar = "5f10367bdae7aa872d90b5ac209321ce5a15181ce22848d032a8d452055cbfd0",
Qx = "21073bee733a07b15d83afcd4e6ee11b01e6137fd5ad4589c5045e12d79a9a9490a3ebc59f30633a60fc3635a3c1e51",
Qy = "eb7a97a9d3dfff1667b8fa559bdcdf37c7767e6afb8ca93ad9dd44feb93761e10aa2c4c1a79728a21cd4a6f705398b5"
)
test(
id = 2,
EC = ECP_ShortW_Jac[Fp[BLS12_381], NotOnTwist],
Px = "f92c9572692e8f3d450483a7a9bb4694e3b54c9cd09441a4dd7f579b0a6984e47f8090c31c172b33d87f3de186d6b58",
Py = "286ede4cb2ae19ead4932d5550c5d3ec8ce3a3ada5e1ed6d202e93dd1b16d3513f0f9b62adc6323f18e272a426ee955",
scalar = "4c321d72220c098fc0fd52306de98f8be9446bf854cf1e4d8dbae62375d18faf",
Qx = "4bb385e937582ae32aa7ba89632fcef2eace3f7b57309d979cf35298a430de9ef4d9ac5ba2335c1a4b6e7e5c38d0036",
Qy = "1801154d3a7b0daea772345b7f72a4c88c9677743f267da63490dad4dece2ecc9ec02d4d4d063086ee5d356aa2db914e"
)
test(
id = 3,
EC = ECP_ShortW_Jac[Fp[BLS12_381], NotOnTwist],
Px = "ec23ff3435b8ebd5e8e0a879d432e11eb974161664b1341fd28f1ffc4c228bf6ada2ae4a565f18c9b66f67a7573502d",
Py = "10c4b647be08db0b49b75320ae891f9f9c5d7bb7c798947e800d681d205d1b24b12e4dfa993d1bd16851b00356627cc1",
scalar = "1738857afb76c55f615c2a20b44ca90dcb3267d804ec23fddea431dbee4eb37f",
Qx = "dc7ae7801152918ee3c13590407b4242a80d0b855a0bf585d3dc30719601d2d5d9e01e99ae735003ecb7c20ef48265",
Qy = "142c01a6aa390426a4ce2f36df43f86442732c35d4e05e5b67f3623832944f0ea5a29138624cb939330652a3cfb282b5"
)
test(
id = 4,
EC = ECP_ShortW_Jac[Fp[BLS12_381], NotOnTwist],
Px = "df127083c2a5ef2388b02af913c0e4002a52a82db9e5ecbf23ee4f557d3b61c91ebcfe9d4973070b46bc5ea6897bca1",
Py = "318960aeea262ec23ffdd42ec1ba72ae6fa2186a1e2a0fc2659073fb7b5adfb50d581a4d998a94d1accf78b1b3a0163",
scalar = "19c47811813444020c999a2b263940b5054cf45bb8ad8e086ff126bfcd5507e1",
Qx = "5f93c42fd76a29063efa2ee92607e0b3ae7edc4e419b3914661e5162d6beaeb96a34d2007ff817bc102651f61dca8d1",
Qy = "18dde8666bb1d0a379719d7d1b1512de809b70e49d9553303274ea872e56f7f39da551d6bcb7c57ae88ec7dc1fb354a4"
)
test(
id = 5,
EC = ECP_ShortW_Jac[Fp[BLS12_381], NotOnTwist],
Px = "101123de23c0f240c583c2368c4118dc942db219c55f58cf54acd500c1fcfa06f651ad75319ebf840cbdb6bddea7fde4",
Py = "5268587d4b844b0708e0336d1bbf48da185aaf5b948eccc3b565d00a856dd55882b9bb31c52af0e275b168cb35eb7b0",
scalar = "43ffcda71e45a3e90b7502d92b30a0b06c54c95a91aa21e0438677b1c2714ecb",
Qx = "f9871b682c1c76c7f4f0a7ca57ad876c10dc108b65b76987264873278d9f54db95101c173aed06d07062efc7d47ca0c",
Qy = "20d9628d611e72a4251a1f2357d4f53e68e4915383b6a0d126273d216b1a8c5e2cb7b2688ad702ef1682f4c5228fcd9"
)
test(
id = 6,
EC = ECP_ShortW_Jac[Fp[BLS12_381], NotOnTwist],
Px = "1457ba1bae6eb3afae3261941c65c93e3ae7d784907d15b8d559100da5e13fd29e4a4d6e3103b781a95237b7b2d80a8e",
Py = "6a869a47cb48d01e7d29660932afd7617720262b55de5f430b8aa3d74f9fd2b9d3a07ce192425da58014764fc9532cd",
scalar = "64ad0d6c36dba5368e71f0010aebf860288f54611e5aaf18082bae7a404ebfd8",
Qx = "93e540e26190e161038d985d40f2ab897cbc2346be7d8f2b201a689b59d4020a8740e252606f2f79ba0e121ccc9976d",
Qy = "10568d68f1b993aa1eded3869eda14e509f1cb4d8553bdf97feee175467cea4c0c1316fdb4e5a68440ad04b96b2d3bfc"
)
test(
id = 7,
EC = ECP_ShortW_Jac[Fp[BLS12_381], NotOnTwist],
Px = "2615f843e8fe68d4c337bcf83b2cf13cbae638edd0740f1eac520dc2146afa3b8d36c540878c1d207ef913634b1e593",
Py = "1787d6eeeceb6e7793073f0bbe7bae522529c126b650c43d5d41e732c581a57df1bfb818061b7b4e6c9145da5df2c43e",
scalar = "b0ac3d0e685583075aa46c03a00859dfbec24ccb36e2cae3806d82275adcc03",
Qx = "d95ed29c2e15fd2205d83a71478341d6022deb93af4d49f704437678a72ce141d2f6043aa0e34e26f60d17e16b97053",
Qy = "b37cbded112c84116b74ff311b10d148f3e203cb88d4a011b096c74cd2bfdb27255727de4aa8299ae10b32d661d48a7"
)
test(
id = 8,
EC = ECP_ShortW_Jac[Fp[BLS12_381], NotOnTwist],
Px = "10bc0c4e1ed87246a9d4d7d38546369f275a245f6e1d3b882e8c9a7f05bc6ee8ff97a96a54084c2bef15ed8bfefb1465",
Py = "1782377e5f588576b5ab42fea224e88873dda957202f0c6d72ce8728c2d58dc654be77226fbda385d5f269354e4a176a",
scalar = "23941bb3c3659423d6fdafb7cff52e0e02de0ac91e64c537c6203d64905b63d0",
Qx = "83f1e7e8bd963c1ccd837dae7bc9336531aaf0aee717537a9a7e2712e220f74cdb73a99f331c0eb6b377be3dafc211f",
Qy = "cd87773d072b1305dfc85c2983aecae2ab316e5e8f31306c32d58d6ce2e431b12685d18c58b6a35ad2113c5b689eeb"
)
test(
id = 9,
EC = ECP_ShortW_Jac[Fp[BLS12_381], NotOnTwist],
Px = "be4f9f721d98a761a5562bd80ea06f369e9cbb7d33bbb2f0191d4b77d0fd2a10c4083b54157b525f36c522ca3a6ca09",
Py = "166c315ecdd20acb3c5efcc7e038b17d0b37a06ffbf77873f15fc0cd091a1e4102a8b8bf5507919453759e744391b04d",
scalar = "4203156dcf70582ea8cbd0388104f47fd5a18ae336b2fed8458e1e4e74d7baf5",
Qx = "c72bc7087cd22993b7f6d2e49026abfde678a384073ed373b95df722b1ab658eb5ae42211e5528af606e38b59511bc6",
Qy = "96d80593b42fe44e64793e490b1257af0aa26b36773aac93c3686fdb14975917cf60a1a19e32623218d0722dbb88a85"
)
proc test(
id: int,
EC: typedesc[ECP_ShortW_Proj or ECP_ShortW_Jac],
Px0, Px1, Py0, Py1: string,
scalar: string,
Qx0, Qx1, Qy0, Qy1: string
) =
test "test " & $id & " - " & $EC:
var P: EC
let pOK = P.fromHex(Px0, Px1, Py0, Py1)
doAssert pOK
var Q: EC
let qOK = Q.fromHex(Qx0, Qx1, Qy0, Qy1)
let exponent = BigInt[EC.F.C.getCurveOrderBitwidth()].fromHex(scalar)
var
impl = P
reference = P
endo = P
impl.scalarMulGeneric(exponent)
reference.unsafe_ECmul_double_add(exponent)
endo.scalarMulEndo(exponent)
doAssert: bool(Q == reference)
doAssert: bool(Q == impl)
doAssert: bool(Q == endo)
suite "Scalar Multiplication G2: BLS12-381 implementation vs SageMath" & " [" & $WordBitwidth & "-bit mode]":
# Generated via sage sage/testgen_bls12_381.sage
test(
id = 0,
EC = ECP_ShortW_Proj[Fp2[BLS12_381], OnTwist],
Px0 = "10fbddd49246ac4b0faa489e3474507ebc96a5da194b2f7a706fad6bf8435021e1598700088abfe0ae7343296c1b7f52",
Px1 = "324102fa5bd71d9048c3c6a6c62d1f35195d7067bf00dc5eaedd14eecc688383446aba4e8fda059d3f619f00be7890",
Py0 = "f3e974aafa7a3fb3a1209f3af4492c9d9c52f1ae738e1e08309dd0f438f131f8ddd8b934eb8ff2cb078b8c524c11fab",
Py1 = "15e75704edffe7b975cf1d3f27f1dceb89d02e5660650195e0288e5d26c5e9087c241d1bd3263c991d10e2695d1611f1",
scalar = "1f7bef2a74f3bf8ac0225a9edfa514bb5666b15e7be3e929059f2ef75f0035a6",
Qx0 = "1328e4ac12458f9e0c22e925d2fc5593eaf0c126154b484de986895030f830262f54493edcc26aa39c5ab8e714b784b3",
Qx1 = "14d375c704f9187984fe2d64d5517ce7c6eb09981cee68cd48370df21d7f4d0b19431347be3b9eae9d46605cb229e293",
Qy0 = "1580cb4fceea4e71e222945825d4352c97a02d3118ffbd0e006e467b1ff6d4207acd2bb58a197894e9870cbd1bfb369c",
Qy1 = "5df16d4223c040dffcd1912359cfae1f3a99e7f519b2aedaaeb6d77115c63acf309f9effc69d4d9a0d7de420dbf9f1a"
)
test(
id = 1,
EC = ECP_ShortW_Proj[Fp2[BLS12_381], OnTwist],
Px0 = "4b472ab5d0995a22c95f0805eb459b147d2033b8c13c1c07c857a97e66952d4df3e3b5f346997cc7bd19886492fae83",
Px1 = "12228345592511c7327176258097c70dffad1ff53b37163cbd4747d0085ed0bcfe90b9150d2f7e49580a42110b1d9c6b",
Py0 = "19220ed4e423d3274a8e9a58624b8762d7831d6f65fcaf6718b933bf77a0c41d3bb713a2224dbc448cfc735101a5bb1e",
Py1 = "1d4c7565e4831130ae0ddd95aaad4033e57daab2518b3f0d934c7abc7db8614adbf39beaef5ebb85d34f5add8a6d341",
scalar = "b500f1fa8ffa8d1c0aa7d65054a9aaa0d9ed2fff83b40516def10b03cc80026",
Qx0 = "aaf3fc4e3c92df5b76863d64d19d26213757173c1a8ef4beddbee7c22f5a6a00418527f83c9ab5b17797cd2212d3d73",
Qx1 = "1643ce8e3a0f0997e949c04cb28aa77b7184033dd0056caee2488311e0a3567a0cd9d051ee531d6a83be8ac516c3f075",
Qy0 = "12923eb157d8ee0a940e100408250beded20e4185cbec484431f705ab605c452122c66d6f08e1b06305677dc872a024f",
Qy1 = "460b65406a6e3935dfd75977b12c02971d2673b9c23b032494e6684e08727f35da0407be6708e98cd309ff0c09be00d"
)
test(
id = 2,
EC = ECP_ShortW_Proj[Fp2[BLS12_381], OnTwist],
Px0 = "11c9f03cd130f7b4d6675b902d9b4dddfa41577b7673c31a508760675ca083abedfe3f6c1c69eb46737d4877adb527c6",
Px1 = "c64be8d22d478378784c4f38e386635a8ab606d2b35101ebecfe97b3bb5132d26e9a7ea9690d07a78a22f458045a8c5",
Py0 = "6253c05b48fde95024644efd87cdf0cf15414c36c35625e383ea7b5ab839eaa783563918cd9e5e391ef1512a6ac28e0",
Py1 = "2d214172d2a0326ed45b60945c424ac30f416fa8c6e11f243034a9de26f4aaa69c0d4cc8405227f26c6ee4085ea5bd4",
scalar = "3638a1f09b542c9c14706bddf9bd411747489f3d398a5c286d28f3a950e33406",
Qx0 = "a6e22837968f191d848297f60b511acf4cc375e53161e7869b8d98455375d8ee69367513b3439b6c4ee66f9232badbb",
Qx1 = "10f95cc0c70943519c30c04a8625bb56c1656da634018b1e6e35786b610785f41978983c61e78d4be003074d7fd76660",
Qy0 = "bae732b1dd39cb84c7e0649ed641f9d275bfc45721e3ac35d6cd35faa356235ce0b69fa0f2882d6d2762ed8846368d6",
Qy1 = "bcab3bee59706e0f8c381d2a15a55ce6b2c38d1639b43852af2a62f1366d1cdb8433240cbb237750f2f3e0435b23141"
)
test(
id = 3,
EC = ECP_ShortW_Proj[Fp2[BLS12_381], OnTwist],
Px0 = "5adc112fb04bf4ca642d5a7d7343ccd6b93546442d2fff5b9d32c15e456d54884cba49dd7f94ce4ddaad4018e55d0f2",
Px1 = "5d1c5bbf5d7a833dc76ba206bfa99c281fc37941be050e18f8c6d267b2376b3634d8ad6eb951e52a6d096315abd17d6",
Py0 = "15a959e54981fab9ac3c6f5bfd6fb60a50a916bd43d96a09922a54309b84812736581bfa728670cba864b08b9e391bb9",
Py1 = "f5d6d74f1dd3d9c07451340b8f6990fe93a28fe5e176564eb920bf17eb02df8b6f1e626eda5542ff415f89d51943001",
scalar = "6448f296d9b1a8d81319a0b789df04c587c6165776ccf39f50a354204aabe0da",
Qx0 = "689e9532c287233d12c3d7196361a06479ecb762a8542f6ba4003a5863d5731f3a0cd3fe4e1405aa3c6f9bd87c08b26",
Qx1 = "b74b46e87a05b7413282d63d63a2b1eeb23e8c482fa8097623888d4be2b90c7cdb49fcb93c74f2b98da15aa9382e285",
Qy0 = "44250df4c1e38bfd7fef6c61649afe7ab5d5252b98589d71f1a64efac5ae8ecf0ccafa173acaafc30a0b2a1616b08e4",
Qy1 = "173b324bb2e0596d0ab560c2a447a1867fea87c5712bd06f2503385b0e145509036c119440973396fc263a02838c8433"
)
test(
id = 4,
EC = ECP_ShortW_Proj[Fp2[BLS12_381], OnTwist],
Px0 = "99f8b62e82892d323847f64ab2b422478d207b780fbb097cdca6a1a89e70ff09213dee8534eaf63dac9f7f7feff2548",
Px1 = "12e7b53d802fa9cd897b5470614d57b1620bfe53f36158466f83e7cc6a6cccb1ac7557a8d5a2208c7c1366835c2cba59",
Py0 = "115d6b7a8bc5628690ec750207b3252d4121c20c2106d0277cd41dee7b1d4ed1ff856883719bccb545054b9a745a53e2",
Py1 = "4b55174d273b358a72687d52956af3e94d97db8d2cc508b2a4ec5b0c0b4073b8fcc52eadaea35e3eae9a441b3f86cbc",
scalar = "150caebc321c53c0658c5cecb45e564620b57bfbad0f5d5a277be71a184937b7",
Qx0 = "3f474d7fa1ff31949c7b61f1ff71a7ccd282201ef88ef12fcd1fd3fef6a3ca18d8bb31fa7e9f4abc713f37e02abef3",
Qx1 = "cb94daed6079cbe5a628ae4c27e8ad31a17f14e68050e8ce1b03d5a3c0e6a6cc5a34b3115034349b2ebe8de6a2c441e",
Qy0 = "15b09aac63ac527ad719ee2bcebda6bb646044d9060c4f72280d41186798912b6e29b2f7782744b8cdce927a9c1b9340",
Qy1 = "5204820d6336aade860fb1cb983bcc66e10cfb352ea645b4cdf74e643e9fdf545609bd7181a67daac891f551a6ce566"
)
test(
id = 5,
EC = ECP_ShortW_Proj[Fp2[BLS12_381], OnTwist],
Px0 = "7f56aa6111f341d6381090f058835b3d60200032b382108194188c40afe4225eb6fecaba734084283771923e004b5ca",
Px1 = "18abca4d9eca6d3ef3c720ca6b27f824fdd12dcac72c167f0212f707fa22752f291c9c20a4b92417d05c64207b8e6da6",
Py0 = "10e08fc323d2ef92c5fd9a0ba38e32e16068ac5a4a0f95b0390c2e8ad6caa446adebe16bbf628a0c2de007bfa1218317",
Py1 = "6394379cc76d50b41865b619007de5a7cda3bb7ae6fc696bf2f83e2de562039dab890a9e2b4d61045bac606f224ba42",
scalar = "138ecc47a9d5b6cf2a052731b8f016734614949862a9f2be703935a5e0cd43bd",
Qx0 = "19ec61da69ffdbf79411f041276d4e9fe02df31caa79406135a7522a12965364bb3549b7310393208082465feca7c9eb",
Qx1 = "457ddcc53f5338d34713a91ca4298896bfa7ede3b939cd1c8b320a4c9ba4c1038ac09740e5b428f5c15bdf18ca6af0b",
Qy0 = "9e334e01a81dc6da2004d2f13eec7c15ba0ab8fb8a9628ce24a0de073b251f955ee758f5b0a298c4fadd641610c7fe0",
Qy1 = "935bf9c37ed2ce17b9e5f8014816d8a1a3d8debfc72e39ea9121018f3a990561cfbc64c25621d16a921f458d7f40344"
)
test(
id = 6,
EC = ECP_ShortW_Proj[Fp2[BLS12_381], OnTwist],
Px0 = "a8c5649d2df1bae84fd9e8bfcde5113937b3acea22d67ddfedaf1fb8de8c1ef4c70591cf505c24c31e54020c2c510c3",
Px1 = "a0553f98229a6a067489c3ee204161c11e96f421b3e9c145dc3865b03e9d4ff6cab14c5b5308ecd31173f954463690c",
Py0 = "b29d8dfe18dc41b4826c3a102c1bf8f306cb42433cc36ee38080f47a324c02a678f9daed0a2bc577c18b9865de029f0",
Py1 = "558cdabf11e37c5c5e8abd668bbdd71bb3f07f320948ccaac8a207359fffe38424bfd9b1ef1d24b28b2fbb9f76faff1",
scalar = "5668a2332db27199dcfb7cbdfca6317c2ff128db26d7df68483e0a095ec8e88f",
Qx0 = "490e99b9a27cb49b9446a7bedb8c22ef802cfdc3609cbecd8de4e227fdb72aeafb27c53d74361008ce9ea806e25dc85",
Qx1 = "1624f7ed9ca1fcfda7651608be2acb1d76cb37ab989c1aecf06a6401ee66afdddf283039496c2320dca4d720e8b8a337",
Qy0 = "c6fef37a864fa1602824a2128d4a62e3221413e1ded862f11347576f43c27d69b1957385ad6ba7a9168c05e6fc2ab85",
Qy1 = "11d4a696f8e366929fe0b7eae94702a89aef43725218f95e0bfe7d7abd726e884604838e4d7d670c9579431f9d8012e0"
)
test(
id = 7,
EC = ECP_ShortW_Proj[Fp2[BLS12_381], OnTwist],
Px0 = "eb79d9e425feb105ec09ce60949721b12dac5e6721c8a6b505aa2d83270d2a3e6c6bcce16a1b510f6822504c5e86416",
Px1 = "9f5d2dc403a2e96c3f59c7bb98a36cc8be68500510fd88b09f55938efd192d9653f4bcfd1451518c535e9d1996a924",
Py0 = "114825899129828ee0b946811ff98a79af1b53c4511bc45a8e41a07a7d9600c824ed7c5cd608781d0a98a13e69b0c002",
Py1 = "57600cfce779277faf31d1b18a39c752c179a76b301cbdc317263c7e8770df0d5896c9dec84958bf558c16b5ec5869c",
scalar = "45b4bca2f783bba42b2d41a8d00f4c5f18a78738a5678fc3707523e7c62dafcb",
Qx0 = "71bee2c58caace914434607aff9c1730af2da8bd78d1a44215d9c7cc422623e9b65ba1fc7207de9d0af96f8211eda2b",
Qx1 = "80ea7a46f9352599f67bbbed1253b142422cb79af32b1a544e77ff02c25057396569182341e5492c4a520a756568a41",
Qy0 = "73470439d1202c87e54d9de94121f5e36371fe527eca699f48caba867111707a250b2b0357e79a8263babb907c9f43a",
Qy1 = "cf2f2cca752462c5fc2827b7871d517e50d7ecd819e0b9419f9b1e357874acca15c8f0a1f611aa243b9d21ce1962d3a"
)
test(
id = 8,
EC = ECP_ShortW_Proj[Fp2[BLS12_381], OnTwist],
Px0 = "17ce8a849a475599245ad6b84cf5284cd15d6346ae52a833954ec50d5cf7f0be1cd8473fdc9dfd500d7f1d80bf6fa6ca",
Px1 = "15d8128bc60c8e83846bf6748982a7188df6393a9379b2959fa7e1cb72f1c1da066fe3a6d927f97ecec3725fac65eb10",
Py0 = "a05421595b36750e134b91500962201e9f57ac068732b9fb34ec50ff22f274d395d34d133e131e6dc7bc42d66149767",
Py1 = "178cb2541ce0c60b8860d59762daa6a5b55a0ca034aa18b1fcc6deb23aaa093fb2a6129db0d58de044c4bbb23f1fa298",
scalar = "6083671fcc66dc084ad73eba100830555fcfcc5eccaa6acb27cda0d3fa8d6f64",
Qx0 = "175a067a5cca1e18c2c60c1ed84a2d0fdad20ad8e2b9b67a13d8a173d6c097bd2bb8fa6d83ff5ab3668d56d39f34cbe0",
Qx1 = "14bdf8d62a088a6a71e5ea236bd3caa07934da726fc1f0b7ae462272c0778615734fac562a0293ae5da759dcfc78480c",
Qy0 = "59ead353a2a4189dd9dc0d93ac86d0f3f8fd60bf3db10fd77e4295b1dfaeccb28aa481b1efce7198093a7f2e8ba3617",
Qy1 = "a4661ce0260e251df9d2b01b5af29262e019b8ea12b3a0a2c4c125c09cadd906dcd8a25b7876e76892acfd74dfab8c5"
)
test(
id = 9,
EC = ECP_ShortW_Proj[Fp2[BLS12_381], OnTwist],
Px0 = "13eb9e9906446be49345c08de406cd104d6bb9901ee12af0b80a8351027152d6f6d158d5a906e4a58c5602e97347cfd5",
Px1 = "1218df3f2a9cd7685325a4a7bb6a3636a458a52ea7f1e1d73c2429acb74a2a9beb838c109541120b095118c90868eb0f",
Py0 = "3ac16edac6898f11ff8ddb48fad6f59f4842cd427d72fa964171801be172b8ecd2fdffb4882d4aa6f1e730f6e53f8c5",
Py1 = "b2d251295859b1be1854b1db06eae2ff8e3879d8ba5d9f86f4bb805c65696b48d0771cf10150983e322bdf9eb659af1",
scalar = "644dc62869683f0c93f38eaef2ba6912569dc91ec2806e46b4a3dd6a4421dad1",
Qx0 = "1888f703e7525e4ac29788eb6e3afde14e4c8b36f74a3058ab7e991630cdb8332fb164766db6d14186ac7fa2e593f513",
Qx1 = "1496076ec35db3760a3cfe22a1759b01ac89b7ae21ccb9c4d7553a7881f4a610ef88a56b2e5a027ab49507fd710dd9ea",
Qy0 = "1357e8db4a105bf81a94e9b9130a892b1ec78d564f77b2717451cce777c16a409cd19f450247c75882f1b84678d7c46d",
Qy1 = "14dd91161426cd5d831914706ee9f427512a789f4953f82538f3fb17553840eae31c992de2ed91a6695d291b5ef4c204"
)
# -----
test(
id = 0,
EC = ECP_ShortW_Jac[Fp2[BLS12_381], OnTwist],
Px0 = "10fbddd49246ac4b0faa489e3474507ebc96a5da194b2f7a706fad6bf8435021e1598700088abfe0ae7343296c1b7f52",
Px1 = "324102fa5bd71d9048c3c6a6c62d1f35195d7067bf00dc5eaedd14eecc688383446aba4e8fda059d3f619f00be7890",
Py0 = "f3e974aafa7a3fb3a1209f3af4492c9d9c52f1ae738e1e08309dd0f438f131f8ddd8b934eb8ff2cb078b8c524c11fab",
Py1 = "15e75704edffe7b975cf1d3f27f1dceb89d02e5660650195e0288e5d26c5e9087c241d1bd3263c991d10e2695d1611f1",
scalar = "1f7bef2a74f3bf8ac0225a9edfa514bb5666b15e7be3e929059f2ef75f0035a6",
Qx0 = "1328e4ac12458f9e0c22e925d2fc5593eaf0c126154b484de986895030f830262f54493edcc26aa39c5ab8e714b784b3",
Qx1 = "14d375c704f9187984fe2d64d5517ce7c6eb09981cee68cd48370df21d7f4d0b19431347be3b9eae9d46605cb229e293",
Qy0 = "1580cb4fceea4e71e222945825d4352c97a02d3118ffbd0e006e467b1ff6d4207acd2bb58a197894e9870cbd1bfb369c",
Qy1 = "5df16d4223c040dffcd1912359cfae1f3a99e7f519b2aedaaeb6d77115c63acf309f9effc69d4d9a0d7de420dbf9f1a"
)
test(
id = 1,
EC = ECP_ShortW_Jac[Fp2[BLS12_381], OnTwist],
Px0 = "4b472ab5d0995a22c95f0805eb459b147d2033b8c13c1c07c857a97e66952d4df3e3b5f346997cc7bd19886492fae83",
Px1 = "12228345592511c7327176258097c70dffad1ff53b37163cbd4747d0085ed0bcfe90b9150d2f7e49580a42110b1d9c6b",
Py0 = "19220ed4e423d3274a8e9a58624b8762d7831d6f65fcaf6718b933bf77a0c41d3bb713a2224dbc448cfc735101a5bb1e",
Py1 = "1d4c7565e4831130ae0ddd95aaad4033e57daab2518b3f0d934c7abc7db8614adbf39beaef5ebb85d34f5add8a6d341",
scalar = "b500f1fa8ffa8d1c0aa7d65054a9aaa0d9ed2fff83b40516def10b03cc80026",
Qx0 = "aaf3fc4e3c92df5b76863d64d19d26213757173c1a8ef4beddbee7c22f5a6a00418527f83c9ab5b17797cd2212d3d73",
Qx1 = "1643ce8e3a0f0997e949c04cb28aa77b7184033dd0056caee2488311e0a3567a0cd9d051ee531d6a83be8ac516c3f075",
Qy0 = "12923eb157d8ee0a940e100408250beded20e4185cbec484431f705ab605c452122c66d6f08e1b06305677dc872a024f",
Qy1 = "460b65406a6e3935dfd75977b12c02971d2673b9c23b032494e6684e08727f35da0407be6708e98cd309ff0c09be00d"
)
test(
id = 2,
EC = ECP_ShortW_Jac[Fp2[BLS12_381], OnTwist],
Px0 = "11c9f03cd130f7b4d6675b902d9b4dddfa41577b7673c31a508760675ca083abedfe3f6c1c69eb46737d4877adb527c6",
Px1 = "c64be8d22d478378784c4f38e386635a8ab606d2b35101ebecfe97b3bb5132d26e9a7ea9690d07a78a22f458045a8c5",
Py0 = "6253c05b48fde95024644efd87cdf0cf15414c36c35625e383ea7b5ab839eaa783563918cd9e5e391ef1512a6ac28e0",
Py1 = "2d214172d2a0326ed45b60945c424ac30f416fa8c6e11f243034a9de26f4aaa69c0d4cc8405227f26c6ee4085ea5bd4",
scalar = "3638a1f09b542c9c14706bddf9bd411747489f3d398a5c286d28f3a950e33406",
Qx0 = "a6e22837968f191d848297f60b511acf4cc375e53161e7869b8d98455375d8ee69367513b3439b6c4ee66f9232badbb",
Qx1 = "10f95cc0c70943519c30c04a8625bb56c1656da634018b1e6e35786b610785f41978983c61e78d4be003074d7fd76660",
Qy0 = "bae732b1dd39cb84c7e0649ed641f9d275bfc45721e3ac35d6cd35faa356235ce0b69fa0f2882d6d2762ed8846368d6",
Qy1 = "bcab3bee59706e0f8c381d2a15a55ce6b2c38d1639b43852af2a62f1366d1cdb8433240cbb237750f2f3e0435b23141"
)
test(
id = 3,
EC = ECP_ShortW_Jac[Fp2[BLS12_381], OnTwist],
Px0 = "5adc112fb04bf4ca642d5a7d7343ccd6b93546442d2fff5b9d32c15e456d54884cba49dd7f94ce4ddaad4018e55d0f2",
Px1 = "5d1c5bbf5d7a833dc76ba206bfa99c281fc37941be050e18f8c6d267b2376b3634d8ad6eb951e52a6d096315abd17d6",
Py0 = "15a959e54981fab9ac3c6f5bfd6fb60a50a916bd43d96a09922a54309b84812736581bfa728670cba864b08b9e391bb9",
Py1 = "f5d6d74f1dd3d9c07451340b8f6990fe93a28fe5e176564eb920bf17eb02df8b6f1e626eda5542ff415f89d51943001",
scalar = "6448f296d9b1a8d81319a0b789df04c587c6165776ccf39f50a354204aabe0da",
Qx0 = "689e9532c287233d12c3d7196361a06479ecb762a8542f6ba4003a5863d5731f3a0cd3fe4e1405aa3c6f9bd87c08b26",
Qx1 = "b74b46e87a05b7413282d63d63a2b1eeb23e8c482fa8097623888d4be2b90c7cdb49fcb93c74f2b98da15aa9382e285",
Qy0 = "44250df4c1e38bfd7fef6c61649afe7ab5d5252b98589d71f1a64efac5ae8ecf0ccafa173acaafc30a0b2a1616b08e4",
Qy1 = "173b324bb2e0596d0ab560c2a447a1867fea87c5712bd06f2503385b0e145509036c119440973396fc263a02838c8433"
)
test(
id = 4,
EC = ECP_ShortW_Jac[Fp2[BLS12_381], OnTwist],
Px0 = "99f8b62e82892d323847f64ab2b422478d207b780fbb097cdca6a1a89e70ff09213dee8534eaf63dac9f7f7feff2548",
Px1 = "12e7b53d802fa9cd897b5470614d57b1620bfe53f36158466f83e7cc6a6cccb1ac7557a8d5a2208c7c1366835c2cba59",
Py0 = "115d6b7a8bc5628690ec750207b3252d4121c20c2106d0277cd41dee7b1d4ed1ff856883719bccb545054b9a745a53e2",
Py1 = "4b55174d273b358a72687d52956af3e94d97db8d2cc508b2a4ec5b0c0b4073b8fcc52eadaea35e3eae9a441b3f86cbc",
scalar = "150caebc321c53c0658c5cecb45e564620b57bfbad0f5d5a277be71a184937b7",
Qx0 = "3f474d7fa1ff31949c7b61f1ff71a7ccd282201ef88ef12fcd1fd3fef6a3ca18d8bb31fa7e9f4abc713f37e02abef3",
Qx1 = "cb94daed6079cbe5a628ae4c27e8ad31a17f14e68050e8ce1b03d5a3c0e6a6cc5a34b3115034349b2ebe8de6a2c441e",
Qy0 = "15b09aac63ac527ad719ee2bcebda6bb646044d9060c4f72280d41186798912b6e29b2f7782744b8cdce927a9c1b9340",
Qy1 = "5204820d6336aade860fb1cb983bcc66e10cfb352ea645b4cdf74e643e9fdf545609bd7181a67daac891f551a6ce566"
)
test(
id = 5,
EC = ECP_ShortW_Jac[Fp2[BLS12_381], OnTwist],
Px0 = "7f56aa6111f341d6381090f058835b3d60200032b382108194188c40afe4225eb6fecaba734084283771923e004b5ca",
Px1 = "18abca4d9eca6d3ef3c720ca6b27f824fdd12dcac72c167f0212f707fa22752f291c9c20a4b92417d05c64207b8e6da6",
Py0 = "10e08fc323d2ef92c5fd9a0ba38e32e16068ac5a4a0f95b0390c2e8ad6caa446adebe16bbf628a0c2de007bfa1218317",
Py1 = "6394379cc76d50b41865b619007de5a7cda3bb7ae6fc696bf2f83e2de562039dab890a9e2b4d61045bac606f224ba42",
scalar = "138ecc47a9d5b6cf2a052731b8f016734614949862a9f2be703935a5e0cd43bd",
Qx0 = "19ec61da69ffdbf79411f041276d4e9fe02df31caa79406135a7522a12965364bb3549b7310393208082465feca7c9eb",
Qx1 = "457ddcc53f5338d34713a91ca4298896bfa7ede3b939cd1c8b320a4c9ba4c1038ac09740e5b428f5c15bdf18ca6af0b",
Qy0 = "9e334e01a81dc6da2004d2f13eec7c15ba0ab8fb8a9628ce24a0de073b251f955ee758f5b0a298c4fadd641610c7fe0",
Qy1 = "935bf9c37ed2ce17b9e5f8014816d8a1a3d8debfc72e39ea9121018f3a990561cfbc64c25621d16a921f458d7f40344"
)
test(
id = 6,
EC = ECP_ShortW_Jac[Fp2[BLS12_381], OnTwist],
Px0 = "a8c5649d2df1bae84fd9e8bfcde5113937b3acea22d67ddfedaf1fb8de8c1ef4c70591cf505c24c31e54020c2c510c3",
Px1 = "a0553f98229a6a067489c3ee204161c11e96f421b3e9c145dc3865b03e9d4ff6cab14c5b5308ecd31173f954463690c",
Py0 = "b29d8dfe18dc41b4826c3a102c1bf8f306cb42433cc36ee38080f47a324c02a678f9daed0a2bc577c18b9865de029f0",
Py1 = "558cdabf11e37c5c5e8abd668bbdd71bb3f07f320948ccaac8a207359fffe38424bfd9b1ef1d24b28b2fbb9f76faff1",
scalar = "5668a2332db27199dcfb7cbdfca6317c2ff128db26d7df68483e0a095ec8e88f",
Qx0 = "490e99b9a27cb49b9446a7bedb8c22ef802cfdc3609cbecd8de4e227fdb72aeafb27c53d74361008ce9ea806e25dc85",
Qx1 = "1624f7ed9ca1fcfda7651608be2acb1d76cb37ab989c1aecf06a6401ee66afdddf283039496c2320dca4d720e8b8a337",
Qy0 = "c6fef37a864fa1602824a2128d4a62e3221413e1ded862f11347576f43c27d69b1957385ad6ba7a9168c05e6fc2ab85",
Qy1 = "11d4a696f8e366929fe0b7eae94702a89aef43725218f95e0bfe7d7abd726e884604838e4d7d670c9579431f9d8012e0"
)
test(
id = 7,
EC = ECP_ShortW_Jac[Fp2[BLS12_381], OnTwist],
Px0 = "eb79d9e425feb105ec09ce60949721b12dac5e6721c8a6b505aa2d83270d2a3e6c6bcce16a1b510f6822504c5e86416",
Px1 = "9f5d2dc403a2e96c3f59c7bb98a36cc8be68500510fd88b09f55938efd192d9653f4bcfd1451518c535e9d1996a924",
Py0 = "114825899129828ee0b946811ff98a79af1b53c4511bc45a8e41a07a7d9600c824ed7c5cd608781d0a98a13e69b0c002",
Py1 = "57600cfce779277faf31d1b18a39c752c179a76b301cbdc317263c7e8770df0d5896c9dec84958bf558c16b5ec5869c",
scalar = "45b4bca2f783bba42b2d41a8d00f4c5f18a78738a5678fc3707523e7c62dafcb",
Qx0 = "71bee2c58caace914434607aff9c1730af2da8bd78d1a44215d9c7cc422623e9b65ba1fc7207de9d0af96f8211eda2b",
Qx1 = "80ea7a46f9352599f67bbbed1253b142422cb79af32b1a544e77ff02c25057396569182341e5492c4a520a756568a41",
Qy0 = "73470439d1202c87e54d9de94121f5e36371fe527eca699f48caba867111707a250b2b0357e79a8263babb907c9f43a",
Qy1 = "cf2f2cca752462c5fc2827b7871d517e50d7ecd819e0b9419f9b1e357874acca15c8f0a1f611aa243b9d21ce1962d3a"
)
test(
id = 8,
EC = ECP_ShortW_Jac[Fp2[BLS12_381], OnTwist],
Px0 = "17ce8a849a475599245ad6b84cf5284cd15d6346ae52a833954ec50d5cf7f0be1cd8473fdc9dfd500d7f1d80bf6fa6ca",
Px1 = "15d8128bc60c8e83846bf6748982a7188df6393a9379b2959fa7e1cb72f1c1da066fe3a6d927f97ecec3725fac65eb10",
Py0 = "a05421595b36750e134b91500962201e9f57ac068732b9fb34ec50ff22f274d395d34d133e131e6dc7bc42d66149767",
Py1 = "178cb2541ce0c60b8860d59762daa6a5b55a0ca034aa18b1fcc6deb23aaa093fb2a6129db0d58de044c4bbb23f1fa298",
scalar = "6083671fcc66dc084ad73eba100830555fcfcc5eccaa6acb27cda0d3fa8d6f64",
Qx0 = "175a067a5cca1e18c2c60c1ed84a2d0fdad20ad8e2b9b67a13d8a173d6c097bd2bb8fa6d83ff5ab3668d56d39f34cbe0",
Qx1 = "14bdf8d62a088a6a71e5ea236bd3caa07934da726fc1f0b7ae462272c0778615734fac562a0293ae5da759dcfc78480c",
Qy0 = "59ead353a2a4189dd9dc0d93ac86d0f3f8fd60bf3db10fd77e4295b1dfaeccb28aa481b1efce7198093a7f2e8ba3617",
Qy1 = "a4661ce0260e251df9d2b01b5af29262e019b8ea12b3a0a2c4c125c09cadd906dcd8a25b7876e76892acfd74dfab8c5"
)
test(
id = 9,
EC = ECP_ShortW_Jac[Fp2[BLS12_381], OnTwist],
Px0 = "13eb9e9906446be49345c08de406cd104d6bb9901ee12af0b80a8351027152d6f6d158d5a906e4a58c5602e97347cfd5",
Px1 = "1218df3f2a9cd7685325a4a7bb6a3636a458a52ea7f1e1d73c2429acb74a2a9beb838c109541120b095118c90868eb0f",
Py0 = "3ac16edac6898f11ff8ddb48fad6f59f4842cd427d72fa964171801be172b8ecd2fdffb4882d4aa6f1e730f6e53f8c5",
Py1 = "b2d251295859b1be1854b1db06eae2ff8e3879d8ba5d9f86f4bb805c65696b48d0771cf10150983e322bdf9eb659af1",
scalar = "644dc62869683f0c93f38eaef2ba6912569dc91ec2806e46b4a3dd6a4421dad1",
Qx0 = "1888f703e7525e4ac29788eb6e3afde14e4c8b36f74a3058ab7e991630cdb8332fb164766db6d14186ac7fa2e593f513",
Qx1 = "1496076ec35db3760a3cfe22a1759b01ac89b7ae21ccb9c4d7553a7881f4a610ef88a56b2e5a027ab49507fd710dd9ea",
Qy0 = "1357e8db4a105bf81a94e9b9130a892b1ec78d564f77b2717451cce777c16a409cd19f450247c75882f1b84678d7c46d",
Qy1 = "14dd91161426cd5d831914706ee9f427512a789f4953f82538f3fb17553840eae31c992de2ed91a6695d291b5ef4c204"
)
run_scalar_mul_test_vs_sage(
ECP_ShortW_Jac[Fp2[BLS12_381], OnTwist],
"t_ec_sage_bls12_381_g2_jacobian"
)

View File

@ -1,579 +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/[unittest, times],
# Internals
../constantine/config/[common, curves],
../constantine/arithmetic,
../constantine/towers,
../constantine/io/[io_bigints, io_ec],
../constantine/elliptic/[
ec_shortweierstrass_projective,
ec_shortweierstrass_jacobian,
ec_scalar_mul,
ec_endomorphism_accel],
# Test utilities
./support/ec_reference_scalar_mult
echo "\n------------------------------------------------------\n"
proc test(
id: int,
EC: typedesc[ECP_ShortW_Proj or ECP_ShortW_Jac],
Px, Py: string,
scalar: string,
Qx, Qy: string
) =
test "test " & $id & " - " & $EC:
var P: EC
let pOK = P.fromHex(Px, Py)
doAssert pOK
var Q: EC
let qOK = Q.fromHex(Qx, Qy)
let exponent = BigInt[EC.F.C.getCurveOrderBitwidth()].fromHex(scalar)
var
impl = P
reference = P
endo = P
endoW = P
impl.scalarMulGeneric(exponent)
reference.unsafe_ECmul_double_add(exponent)
endo.scalarMulEndo(exponent)
endoW.scalarMulGLV_m2w2(exponent)
doAssert: bool(Q == reference)
doAssert: bool(Q == impl)
doAssert: bool(Q == endo)
doAssert: bool(Q == endoW)
suite "Scalar Multiplication G1: BN254 implementation vs SageMath" & " [" & $WordBitwidth & "-bit mode]":
# Generated via sage sage/testgen_bn254_snarks.sage
test(
id = 0,
EC = ECP_ShortW_Proj[Fp[BN254_Snarks], NotOnTwist],
Px = "22d3af0f3ee310df7fc1a2a204369ac13eb4a48d969a27fcd2861506b2dc0cd7",
Py = "1c994169687886ccd28dd587c29c307fb3cab55d796d73a5be0bbf9aab69912e",
scalar = "e08a292f940cfb361cc82bc24ca564f51453708c9745a9cf8707b11c84bc448",
Qx = "267c05cd49d681c5857124876748365313b9c285e783206f48513ce06d3df931",
Qy = "2fa00719ce37465dbe7037f723ed5df08c76b9a27a4dd80d86c0ee5157349b96"
)
test(
id = 1,
EC = ECP_ShortW_Proj[Fp[BN254_Snarks], NotOnTwist],
Px = "2724750abe620fce759b6f18729e40f891a514160d477811a44b222372cc4ea3",
Py = "105cdcbe363921790a56bf2696e73642447c60b814827ca4dba86c814912c98a",
scalar = "2f5c2960850eabadab1e5595ff0bf841206885653e7f2024248b281a86744790",
Qx = "57d2dcbc665fb93fd5119bb982c29700d025423d60a42b5fe17210fd5a868fd",
Qy = "2abad564ff78fbc266dfb77bdd110b22271136b33ce5049fb3ca05107787abc"
)
test(
id = 2,
EC = ECP_ShortW_Proj[Fp[BN254_Snarks], NotOnTwist],
Px = "39bc19c41835082f86ca046b71875b051575072e4d6a4aeedac31eee34b07df",
Py = "1fdbf42fc20421e1e775fd93ed1888d614f7e39067e7443f21b6a4817481c346",
scalar = "29e140c33f706c0111443699b0b8396d8ead339a3d6f3c212b08749cf2a16f6b",
Qx = "83895d1c7a2b15a5dfe9371983196591415182978e8ff0e83262e32d768c712",
Qy = "2ed8b88e1cd08814ce1d1929d0e4bba6fb5897f915b3525cf12349256da95499"
)
test(
id = 3,
EC = ECP_ShortW_Proj[Fp[BN254_Snarks], NotOnTwist],
Px = "157a3e1ff9dabccced9746e19855a9438098be6d734f07d1c069aa1bd05b8d87",
Py = "1c96bf3e48bc1a6635d93d4f1302a0eba39bd907c5d861f2a9d0c714ee60f04d",
scalar = "29b05bd55963e262e0fa458c76297fb5be3ec1421fdb1354789f68fdce81dc2c",
Qx = "196aeca74447934eeaba0f2263177fcb7eb239985814f8ef2d7bf08677108c9",
Qy = "1f5aa4c7df4a9855113c63d8fd55c512c7e919b8ae0352e280bdb1009299c3b2"
)
test(
id = 4,
EC = ECP_ShortW_Proj[Fp[BN254_Snarks], NotOnTwist],
Px = "2f260967d4cd5d15f98c0a0a9d5abaae0c70d3b8d83e1e884586cd6ece395fe7",
Py = "2a102c7aebdfaa999d5a99984148ada142f72f5d4158c10368a2e13dded886f6",
scalar = "1796de74c1edac90d102e7c33f3fad94304eaff4a67a018cae678774d377f6cd",
Qx = "28c73e276807863ecf4ae60b1353790f10f176ca8c55b3db774e33c569ef39d5",
Qy = "c386e24828cead255ec7657698559b23a26fc9bd5db70a1fe20b48ecfbd6db9"
)
test(
id = 5,
EC = ECP_ShortW_Proj[Fp[BN254_Snarks], NotOnTwist],
Px = "1b4ccef57f4411360a02b8228e4251896c9492ff93a69ba3720da0cd46a04e83",
Py = "1fabcb215bd7c06ead2e6b0167497efc2cdd3dbacf69bcb0244142fd63c1e405",
scalar = "116741cd19dac61c5e77877fc6fef40f363b164b501dfbdbc09e17ea51d6beb0",
Qx = "192ca2e120b0f5296baf7cc47bfebbbc74748c8847bbdbe485bcb796de2622aa",
Qy = "8bc6b1aa4532c727be8fd21a8176d55bc721c727af327f601f7a8dff655b0b9"
)
test(
id = 6,
EC = ECP_ShortW_Proj[Fp[BN254_Snarks], NotOnTwist],
Px = "2807c88d6759280d6bd83a54d349a533d1a66dc32f72cab8114ab707f10e829b",
Py = "dbf0d486aeed3d303880f324faa2605aa0219e35661bc88150470c7df1c0b61",
scalar = "2a5976268563870739ced3e6efd8cf53887e8e4426803377095708509dd156ca",
Qx = "2841f67de361436f64e582a134fe36ab7196334c758a07e732e1cf1ccb35a476",
Qy = "21fb9b8311e53832044be5ff024f737aee474bc504c7c158fe760cc999da8612"
)
test(
id = 7,
EC = ECP_ShortW_Proj[Fp[BN254_Snarks], NotOnTwist],
Px = "2754a174a33a55f2a31573767e9bf5381b47dca1cbebc8b68dd4df58b3f1cc2",
Py = "f222f59c8893ad87c581dacb3f8b6e7c20e7a13bc5fb6e24262a3436d663b1",
scalar = "25d596bf6caf4565fbfd22d81f9cef40c8f89b1e5939f20caa1b28056e0e4f58",
Qx = "2b48dd3ace8e403c2905f00cdf13814f0dbecb0c0465e6455fe390cc9730f5a",
Qy = "fe65f0cd4ae0d2e459daa4163f32deed1250b5c384eb5aeb933162a41793d25"
)
test(
id = 8,
EC = ECP_ShortW_Proj[Fp[BN254_Snarks], NotOnTwist],
Px = "273bf6c679d8e880034590d16c007bbabc6c65ed870a263b5d1ce7375c18fd7",
Py = "2904086cb9e33657999229b082558a74c19b2b619a0499afb2e21d804d8598ee",
scalar = "67a499a389129f3902ba6140660c431a56811b53de01d043e924711bd341e53",
Qx = "1d827e4569f17f068457ffc52f1c6ed7e2ec89b8b520efae48eff41827f79128",
Qy = "be8c488bb9587bcb0faba916277974afe12511e54fbd749e27d3d7efd998713"
)
test(
id = 9,
EC = ECP_ShortW_Proj[Fp[BN254_Snarks], NotOnTwist],
Px = "ec892c09a5f1c68c1bfec7780a1ebd279739383f2698eeefbba745b3e717fd5",
Py = "23d273a1b9750fe1d4ebd4b7c25f4a8d7d94f6662c436305cca8ff2cdbd3f736",
scalar = "d2f09ceaa2638b7ac3d7d4aa9eff7a12e93dc85db0f9676e5f19fb86d6273e9",
Qx = "305d7692b141962a4a92038adfacc0d2691e5589ed097a1c661cc48c84e2b64e",
Qy = "bafa230a0f5cc2fa3cf07fa46312cb724fc944b097890fa60f2cf42a1be7963"
)
# --------------------------------------------------------------------------
test(
id = 0,
EC = ECP_ShortW_Jac[Fp[BN254_Snarks], NotOnTwist],
Px = "22d3af0f3ee310df7fc1a2a204369ac13eb4a48d969a27fcd2861506b2dc0cd7",
Py = "1c994169687886ccd28dd587c29c307fb3cab55d796d73a5be0bbf9aab69912e",
scalar = "e08a292f940cfb361cc82bc24ca564f51453708c9745a9cf8707b11c84bc448",
Qx = "267c05cd49d681c5857124876748365313b9c285e783206f48513ce06d3df931",
Qy = "2fa00719ce37465dbe7037f723ed5df08c76b9a27a4dd80d86c0ee5157349b96"
)
test(
id = 1,
EC = ECP_ShortW_Jac[Fp[BN254_Snarks], NotOnTwist],
Px = "2724750abe620fce759b6f18729e40f891a514160d477811a44b222372cc4ea3",
Py = "105cdcbe363921790a56bf2696e73642447c60b814827ca4dba86c814912c98a",
scalar = "2f5c2960850eabadab1e5595ff0bf841206885653e7f2024248b281a86744790",
Qx = "57d2dcbc665fb93fd5119bb982c29700d025423d60a42b5fe17210fd5a868fd",
Qy = "2abad564ff78fbc266dfb77bdd110b22271136b33ce5049fb3ca05107787abc"
)
test(
id = 2,
EC = ECP_ShortW_Jac[Fp[BN254_Snarks], NotOnTwist],
Px = "39bc19c41835082f86ca046b71875b051575072e4d6a4aeedac31eee34b07df",
Py = "1fdbf42fc20421e1e775fd93ed1888d614f7e39067e7443f21b6a4817481c346",
scalar = "29e140c33f706c0111443699b0b8396d8ead339a3d6f3c212b08749cf2a16f6b",
Qx = "83895d1c7a2b15a5dfe9371983196591415182978e8ff0e83262e32d768c712",
Qy = "2ed8b88e1cd08814ce1d1929d0e4bba6fb5897f915b3525cf12349256da95499"
)
test(
id = 3,
EC = ECP_ShortW_Jac[Fp[BN254_Snarks], NotOnTwist],
Px = "157a3e1ff9dabccced9746e19855a9438098be6d734f07d1c069aa1bd05b8d87",
Py = "1c96bf3e48bc1a6635d93d4f1302a0eba39bd907c5d861f2a9d0c714ee60f04d",
scalar = "29b05bd55963e262e0fa458c76297fb5be3ec1421fdb1354789f68fdce81dc2c",
Qx = "196aeca74447934eeaba0f2263177fcb7eb239985814f8ef2d7bf08677108c9",
Qy = "1f5aa4c7df4a9855113c63d8fd55c512c7e919b8ae0352e280bdb1009299c3b2"
)
test(
id = 4,
EC = ECP_ShortW_Jac[Fp[BN254_Snarks], NotOnTwist],
Px = "2f260967d4cd5d15f98c0a0a9d5abaae0c70d3b8d83e1e884586cd6ece395fe7",
Py = "2a102c7aebdfaa999d5a99984148ada142f72f5d4158c10368a2e13dded886f6",
scalar = "1796de74c1edac90d102e7c33f3fad94304eaff4a67a018cae678774d377f6cd",
Qx = "28c73e276807863ecf4ae60b1353790f10f176ca8c55b3db774e33c569ef39d5",
Qy = "c386e24828cead255ec7657698559b23a26fc9bd5db70a1fe20b48ecfbd6db9"
)
test(
id = 5,
EC = ECP_ShortW_Jac[Fp[BN254_Snarks], NotOnTwist],
Px = "1b4ccef57f4411360a02b8228e4251896c9492ff93a69ba3720da0cd46a04e83",
Py = "1fabcb215bd7c06ead2e6b0167497efc2cdd3dbacf69bcb0244142fd63c1e405",
scalar = "116741cd19dac61c5e77877fc6fef40f363b164b501dfbdbc09e17ea51d6beb0",
Qx = "192ca2e120b0f5296baf7cc47bfebbbc74748c8847bbdbe485bcb796de2622aa",
Qy = "8bc6b1aa4532c727be8fd21a8176d55bc721c727af327f601f7a8dff655b0b9"
)
test(
id = 6,
EC = ECP_ShortW_Jac[Fp[BN254_Snarks], NotOnTwist],
Px = "2807c88d6759280d6bd83a54d349a533d1a66dc32f72cab8114ab707f10e829b",
Py = "dbf0d486aeed3d303880f324faa2605aa0219e35661bc88150470c7df1c0b61",
scalar = "2a5976268563870739ced3e6efd8cf53887e8e4426803377095708509dd156ca",
Qx = "2841f67de361436f64e582a134fe36ab7196334c758a07e732e1cf1ccb35a476",
Qy = "21fb9b8311e53832044be5ff024f737aee474bc504c7c158fe760cc999da8612"
)
test(
id = 7,
EC = ECP_ShortW_Jac[Fp[BN254_Snarks], NotOnTwist],
Px = "2754a174a33a55f2a31573767e9bf5381b47dca1cbebc8b68dd4df58b3f1cc2",
Py = "f222f59c8893ad87c581dacb3f8b6e7c20e7a13bc5fb6e24262a3436d663b1",
scalar = "25d596bf6caf4565fbfd22d81f9cef40c8f89b1e5939f20caa1b28056e0e4f58",
Qx = "2b48dd3ace8e403c2905f00cdf13814f0dbecb0c0465e6455fe390cc9730f5a",
Qy = "fe65f0cd4ae0d2e459daa4163f32deed1250b5c384eb5aeb933162a41793d25"
)
test(
id = 8,
EC = ECP_ShortW_Jac[Fp[BN254_Snarks], NotOnTwist],
Px = "273bf6c679d8e880034590d16c007bbabc6c65ed870a263b5d1ce7375c18fd7",
Py = "2904086cb9e33657999229b082558a74c19b2b619a0499afb2e21d804d8598ee",
scalar = "67a499a389129f3902ba6140660c431a56811b53de01d043e924711bd341e53",
Qx = "1d827e4569f17f068457ffc52f1c6ed7e2ec89b8b520efae48eff41827f79128",
Qy = "be8c488bb9587bcb0faba916277974afe12511e54fbd749e27d3d7efd998713"
)
test(
id = 9,
EC = ECP_ShortW_Jac[Fp[BN254_Snarks], NotOnTwist],
Px = "ec892c09a5f1c68c1bfec7780a1ebd279739383f2698eeefbba745b3e717fd5",
Py = "23d273a1b9750fe1d4ebd4b7c25f4a8d7d94f6662c436305cca8ff2cdbd3f736",
scalar = "d2f09ceaa2638b7ac3d7d4aa9eff7a12e93dc85db0f9676e5f19fb86d6273e9",
Qx = "305d7692b141962a4a92038adfacc0d2691e5589ed097a1c661cc48c84e2b64e",
Qy = "bafa230a0f5cc2fa3cf07fa46312cb724fc944b097890fa60f2cf42a1be7963"
)
proc test(
id: int,
EC: typedesc[ECP_ShortW_Proj or ECP_ShortW_Jac],
Px0, Px1, Py0, Py1: string,
scalar: string,
Qx0, Qx1, Qy0, Qy1: string
) =
test "test " & $id & " - " & $EC:
var P: EC
let pOK = P.fromHex(Px0, Px1, Py0, Py1)
doAssert pOK
var Q: EC
let qOK = Q.fromHex(Qx0, Qx1, Qy0, Qy1)
let exponent = BigInt[EC.F.C.getCurveOrderBitwidth()].fromHex(scalar)
var
impl = P
reference = P
endo = P
impl.scalarMulGeneric(exponent)
reference.unsafe_ECmul_double_add(exponent)
endo.scalarMulEndo(exponent)
doAssert: bool(Q == reference)
doAssert: bool(Q == impl)
doAssert: bool(Q == endo)
suite "Scalar Multiplication G2: BN254 implementation vs SageMath" & " [" & $WordBitwidth & "-bit mode]":
# Generated via sage sage/testgen_bn254_snarks.sage
test(
id = 0,
EC = ECP_ShortW_Proj[Fp2[BN254_Snarks], OnTwist],
Px0 = "1dcee2242ae85da43d02d38032b85836660f9a0a8777ab66c84ffbbde3ac3b25",
Px1 = "1e2eb4c305e3b6c36a4081888b7a953eb44804b8b5120306331f8c89a3bb950",
Py0 = "1db75f495edd522cae161ceeb86ca466ca2efd80ef979028d7aa39679de675fd",
Py1 = "b1b6edeb6a7689595098a58a916657dcc09f53f5fc1a1a64b34a2b80447692e",
scalar = "3075e23caee5579e5c96f1ca7b206862c2cf3ce21d79182d58b140074b7bd34",
Qx0 = "8d63bb4368f94f1629f33ef0c970b3a6fcec6979e423f54ce657f0493c08fde",
Qx1 = "29d1af77bb890dcb27e685198f23dffd5ae5733bd6dd55757dcb44ce8c396742",
Qy0 = "13c24efab7e517c2337ba9cbb8cfb2166666a44550fc4d314f4c81a4812fb8a",
Qy1 = "c3ad1f7a175fa21e1d18595f8fc793688e1a33feda902805a52569ea7a787bb"
)
test(
id = 1,
EC = ECP_ShortW_Proj[Fp2[BN254_Snarks], OnTwist],
Px0 = "5ed8c937273562944e0f1ebfb40e6511202188c1cabf588ed38735016d37b32",
Px1 = "23f75e8322c4b540cd5b8fd144a89ab5206a040f498b7b59385770bc841cf012",
Py0 = "2150beef17f5c22a65a4129390f47eece8f0c7d0c516790ea2632e7fd594ed8",
Py1 = "78281fb396e2b923453fae943af96b57e8b283fc40b0be4be3a1750d0daf121",
scalar = "1eac341ad699cba0cb13ae35b8215bfe0f34e931f8e51e33bf90d9849767bb",
Qx0 = "1bb6e8c1be4d9da9ef294ab066c82bb6dd805efa0c73f289e25f5cc6fc4f12e4",
Qx1 = "8ca44ff91e6484ecadc2a866ec64031e71c4a9d7a902f4280bef3db4dbf1bc9",
Qy0 = "39d151a22c49d4c71c8258e9664ead46ddccd49c596056509d9f9e6055def62",
Qy1 = "b37a08b453b96880f435d9fb2555960571a76e72a9d0d0ec622b055b7c97cdb"
)
test(
id = 2,
EC = ECP_ShortW_Proj[Fp2[BN254_Snarks], OnTwist],
Px0 = "2ac4b3d0a70d6686c63d9d63cce1370eafd4dc67f616c13582c6c64f6670513e",
Px1 = "f1daeb6a2581ba6c8027a645ab5c10e303db4aee85c70c8fe11f4c1adcc7029",
Py0 = "25807ff21967759cab64844741d006e2aa0221d9836613b1239da1a167d15131",
Py1 = "148dae725e508dbb43616972e2945f4868b2a193d828ed2efcf9c8a37b6b83f5",
scalar = "b29535765163b5d5f2d01c8fcde010d11f3f0f250a2cc84b8bc13dd9083356c",
Qx0 = "5f4b3a8a5fe74bf3f2ddc0bc2024f18c7958b2846dab1c602b8256a6035361a",
Qx1 = "ba3dad609b1ba8c78cbbfb7fae2d2f9398ef02265e3b4c0f3c8c18d8d0e59d6",
Qy0 = "2c226aee4621895d63df069c4b6951e2201ee1508d5d54e6ee860533b73b534a",
Qy1 = "2aa5384592339bff0a6e4664c931c0ec9f5a3d2fb2fff87a52245c0d95d3d130"
)
test(
id = 3,
EC = ECP_ShortW_Proj[Fp2[BN254_Snarks], OnTwist],
Px0 = "2a028c1328bb0abf252edfbf7133b84eef2a5f20163fe61685b4b54229ca585d",
Px1 = "8f80ad79e8e7e79bbdc645d9f5b339c52dd99a901b90de2494492656f11a9d5",
Py0 = "1f04320578e31ffa2e2b59ad8fcb1aba622b5f307ac540cf2ccdab07dec56503",
Py1 = "2973900c0fdf651b64f5b1a990baec7c582e0743d501bdb991374776d6c73b28",
scalar = "2c02275a71bb41c911faf48cab4f7ac7fc6672a5c15586185c8cff3203181da0",
Qx0 = "2f39a0772a0bd75db3e6ec0745b18824118e534fdefec811d0a4ca2ca3ce7606",
Qx1 = "23e1601a4338502dbc619a8bde251114272ca87662a851a56035c81d46877d81",
Qy0 = "1f0ee85e7c590124f89319f2450f7b8421d9f6d6414fd3b5cc18d781b69b30c9",
Qy1 = "29e4ff75afecaf732419409a5e0d8e94df6acec29fb5b298c7aad5ceef63e5f9"
)
test(
id = 4,
EC = ECP_ShortW_Proj[Fp2[BN254_Snarks], OnTwist],
Px0 = "1132e63c444e1abce6fc4c39bdf5be5caad586837cbf5ca9d3891482bdefe77",
Px1 = "22b71f598dab789f055fc9669ddf66f0d75f581af0e9e8863d7f95a51ef34862",
Py0 = "58e39050f64c9948d7238b99ecaee947cb934688a6e9f483c5c36b6e07aa31b",
Py1 = "2e64b920f498e12992f2a4ae3f9ced43f3f64705c9008169f3b930a760d055fb",
scalar = "24c5b2ce21615dca82231f5fb0fc8d05aa07c6df4bb5aa7c2381ac7b61a6290c",
Qx0 = "25a0637163a40813529e8a22a3e8be6db96f6dc1cdb8e1844729cad6be11668e",
Qx1 = "16de42461c4db7f9f72eb28bb16da850a42fc153dec64baf021f67f5564f36d8",
Qy0 = "27f2d743d3ce0c1f92c51110a6b9ca93a95693161f1d1cd85a0cf5a2492b4901",
Qy1 = "2c5a8df4fe93e31e374595c0605b1a8b93bb429232cf40f45c847739790c191e"
)
test(
id = 5,
EC = ECP_ShortW_Proj[Fp2[BN254_Snarks], OnTwist],
Px0 = "6a20c456e80e2bfe37d8631d41ffed31cba5d1c411e816d64014d0088d16554",
Px1 = "9d1555c77222abd79e17e2806386c53aba9609375276e817f52f03dc3f75676",
Py0 = "127e76f384726e56dfaa46e6fde6dc644f5fd494d056191059e2bebc525ce835",
Py1 = "2d80f2570da62adc61d794ac17c251f9f9f3de2b45f39c8ede5a9e215e60363",
scalar = "263e44e282fe22216cc054a39e40d4e38e71780bdc84563c340bdaaf4562534b",
Qx0 = "6d7e15b98352e445d1bdacb48826e5a7e8cf854fb9bc18839b30a164a2a9c53",
Qx1 = "12aa3294f6a9bb17f91d5875a5a1aa559c29b06134c6d165d83c8e9e02947568",
Qy0 = "271b8b552e52bdd310c46e07327a18861c91a739da178be909f0a4fe53ae0d05",
Qy1 = "1f4f200de96541e826f0bd536b1401e05e2a7c5a96c567b6dff21a21119bbf7"
)
test(
id = 6,
EC = ECP_ShortW_Proj[Fp2[BN254_Snarks], OnTwist],
Px0 = "4c591d080257375d6189340185c6fe4c1fa796722d07e1bec0b17080b6b1154",
Px1 = "241e2f2eb2a58afc2b5410d4ccbf75b53744ca1ac0bb28d7c60449f8d06204a4",
Py0 = "eaddea52f2e884a5e2635965ca4146b12127fe8a8883e07def8e8720f410781",
Py1 = "cc60dec6ad90e38c851924cf39ddd11b70eeb3fac95731eafd984e9aba2cae",
scalar = "1471f378000d557f0c33c1f8c8313edd53422479440cbd0fdc4cc55f1163deec",
Qx0 = "2a86b4867d7f63afdc09048210a3ef6d363c7896ccc1bb248f3aad4174e1f8fa",
Qx1 = "84c200018461c84ef9ce6de2c691b95cc2c41edc87107331f107ac49de76656",
Qy0 = "2ea1b6d71adb183d9a8dd319a21a679cb0b4e06bc96583d3a786f82b88b5e3ba",
Qy1 = "834e2ff738dcb5e8db7e4dae9336dede51524313b476019ea29ebadbb4ba12d"
)
test(
id = 7,
EC = ECP_ShortW_Proj[Fp2[BN254_Snarks], OnTwist],
Px0 = "115e772198e3f0003e31c0a1c48b6ac870d96020a4d634b7f14c15422d001cfe",
Px1 = "1913447ff41836e0b6a3b01be670a2457e6119e02ae35903fb71be4369e269f7",
Py0 = "14cb779c640aad2731b93b07c623c621a5585d0374f0394e5332f20ac28ca49d",
Py1 = "13a4c4b67f5976431158be8137b5017127fdbc312dc49825dae218a9a7878817",
scalar = "411315458c0c0cb27a058faf15dcbf2e467128f9c958d92de37902e1912f81",
Qx0 = "243a8808a891428d01ef28a77d0766488a98272a5dd394b2992599ff522f264",
Qx1 = "1baebf873402812e4345a8b1783fd25272c64d6194bd9f50b32b8e67ee737dc7",
Qy0 = "1f1001ba8b8b27159568f72e80662e352adfc00c9341d8b4fb8ef6f75ff628d2",
Qy1 = "169af215aa2456c6a65e13ac4df1ba1c982ca791058612679ef26dcb8fb0a989"
)
test(
id = 8,
EC = ECP_ShortW_Proj[Fp2[BN254_Snarks], OnTwist],
Px0 = "13faa1f28e6bfe89765c284e67face6ce0a29006ebc1551d4243e754c59f88ad",
Px1 = "640cebb80938dfcb998d84a8e5aafd47ffbcba0aa2f8c9b1c585baf119a8942",
Py0 = "1de793a9ef8f4dea5dad12fb09ddefa07ce197d4d7389a29ad3d8c6484582afe",
Py1 = "fc6e1f8bf75d1b7e48fdb6b2869c2de553663742c151b390cede6712da5a084",
scalar = "111e6f761ce48e22970752bd56cab93d47caa252d52948367b21163591f7b7b1",
Qx0 = "1c25702bf3b6f5fb453c6473b6dc2d67cd3cc21c65b589df1bfde254d50cffdd",
Qx1 = "14d03eb2075d6b5995240cc54a01ebe50b43933863f0316760226fbfa3a0280",
Qy0 = "1a075c9f2f6afa6e07e54b143a33c17e81d0ac8b91e0c8e0fdd5082bd6b9a72d",
Qy1 = "8e5ef57bb0f95fb6538dfaeac677977e3f3d6f49142c09584d8ec5c2ccd9b2d"
)
test(
id = 9,
EC = ECP_ShortW_Proj[Fp2[BN254_Snarks], OnTwist],
Px0 = "2fc3da947b78ac524a57670cef36ca89f1dad71b337bc3c18305c582a59648ad",
Px1 = "2f7cc845d8c1ef0613f919d8c47f3c62f83608a45b1e186748ac5dcccd4c6baf",
Py0 = "18ddc4718a4161f72f8d188fc61a609a3d592e186a65f4158483b719ffb05b8f",
Py1 = "45b9c3629ed709784db63ff090e2e891c5b5c6b2222cb6afc56638d7389d689",
scalar = "6223903d4bc2adea7b0a0db92822b6c2638691e4388df93f567e11edd6f23",
Qx0 = "9ec612ab0cf4a48e1c15d22284bce8e34619bfb9afb688a9a7930afcc1bd0f3",
Qx1 = "d796e5f5ae1a15622d2284ada34166b9e7c717bd2ff9b2cf2c6e48c33db5ff2",
Qy0 = "2a8ecb09a01cd2f89b316e7569331e9da3bfbd8a40114913b3e5477442c0e4ef",
Qy1 = "282b14bc00df2dd1733e3187a9845ef3a123c17ce4f6154e5cad26c3b48d1b98"
)
# --------------------------------------------------------------------------
test(
id = 0,
EC = ECP_ShortW_Jac[Fp2[BN254_Snarks], OnTwist],
Px0 = "1dcee2242ae85da43d02d38032b85836660f9a0a8777ab66c84ffbbde3ac3b25",
Px1 = "1e2eb4c305e3b6c36a4081888b7a953eb44804b8b5120306331f8c89a3bb950",
Py0 = "1db75f495edd522cae161ceeb86ca466ca2efd80ef979028d7aa39679de675fd",
Py1 = "b1b6edeb6a7689595098a58a916657dcc09f53f5fc1a1a64b34a2b80447692e",
scalar = "3075e23caee5579e5c96f1ca7b206862c2cf3ce21d79182d58b140074b7bd34",
Qx0 = "8d63bb4368f94f1629f33ef0c970b3a6fcec6979e423f54ce657f0493c08fde",
Qx1 = "29d1af77bb890dcb27e685198f23dffd5ae5733bd6dd55757dcb44ce8c396742",
Qy0 = "13c24efab7e517c2337ba9cbb8cfb2166666a44550fc4d314f4c81a4812fb8a",
Qy1 = "c3ad1f7a175fa21e1d18595f8fc793688e1a33feda902805a52569ea7a787bb"
)
test(
id = 1,
EC = ECP_ShortW_Jac[Fp2[BN254_Snarks], OnTwist],
Px0 = "5ed8c937273562944e0f1ebfb40e6511202188c1cabf588ed38735016d37b32",
Px1 = "23f75e8322c4b540cd5b8fd144a89ab5206a040f498b7b59385770bc841cf012",
Py0 = "2150beef17f5c22a65a4129390f47eece8f0c7d0c516790ea2632e7fd594ed8",
Py1 = "78281fb396e2b923453fae943af96b57e8b283fc40b0be4be3a1750d0daf121",
scalar = "1eac341ad699cba0cb13ae35b8215bfe0f34e931f8e51e33bf90d9849767bb",
Qx0 = "1bb6e8c1be4d9da9ef294ab066c82bb6dd805efa0c73f289e25f5cc6fc4f12e4",
Qx1 = "8ca44ff91e6484ecadc2a866ec64031e71c4a9d7a902f4280bef3db4dbf1bc9",
Qy0 = "39d151a22c49d4c71c8258e9664ead46ddccd49c596056509d9f9e6055def62",
Qy1 = "b37a08b453b96880f435d9fb2555960571a76e72a9d0d0ec622b055b7c97cdb"
)
test(
id = 2,
EC = ECP_ShortW_Jac[Fp2[BN254_Snarks], OnTwist],
Px0 = "2ac4b3d0a70d6686c63d9d63cce1370eafd4dc67f616c13582c6c64f6670513e",
Px1 = "f1daeb6a2581ba6c8027a645ab5c10e303db4aee85c70c8fe11f4c1adcc7029",
Py0 = "25807ff21967759cab64844741d006e2aa0221d9836613b1239da1a167d15131",
Py1 = "148dae725e508dbb43616972e2945f4868b2a193d828ed2efcf9c8a37b6b83f5",
scalar = "b29535765163b5d5f2d01c8fcde010d11f3f0f250a2cc84b8bc13dd9083356c",
Qx0 = "5f4b3a8a5fe74bf3f2ddc0bc2024f18c7958b2846dab1c602b8256a6035361a",
Qx1 = "ba3dad609b1ba8c78cbbfb7fae2d2f9398ef02265e3b4c0f3c8c18d8d0e59d6",
Qy0 = "2c226aee4621895d63df069c4b6951e2201ee1508d5d54e6ee860533b73b534a",
Qy1 = "2aa5384592339bff0a6e4664c931c0ec9f5a3d2fb2fff87a52245c0d95d3d130"
)
test(
id = 3,
EC = ECP_ShortW_Jac[Fp2[BN254_Snarks], OnTwist],
Px0 = "2a028c1328bb0abf252edfbf7133b84eef2a5f20163fe61685b4b54229ca585d",
Px1 = "8f80ad79e8e7e79bbdc645d9f5b339c52dd99a901b90de2494492656f11a9d5",
Py0 = "1f04320578e31ffa2e2b59ad8fcb1aba622b5f307ac540cf2ccdab07dec56503",
Py1 = "2973900c0fdf651b64f5b1a990baec7c582e0743d501bdb991374776d6c73b28",
scalar = "2c02275a71bb41c911faf48cab4f7ac7fc6672a5c15586185c8cff3203181da0",
Qx0 = "2f39a0772a0bd75db3e6ec0745b18824118e534fdefec811d0a4ca2ca3ce7606",
Qx1 = "23e1601a4338502dbc619a8bde251114272ca87662a851a56035c81d46877d81",
Qy0 = "1f0ee85e7c590124f89319f2450f7b8421d9f6d6414fd3b5cc18d781b69b30c9",
Qy1 = "29e4ff75afecaf732419409a5e0d8e94df6acec29fb5b298c7aad5ceef63e5f9"
)
test(
id = 4,
EC = ECP_ShortW_Jac[Fp2[BN254_Snarks], OnTwist],
Px0 = "1132e63c444e1abce6fc4c39bdf5be5caad586837cbf5ca9d3891482bdefe77",
Px1 = "22b71f598dab789f055fc9669ddf66f0d75f581af0e9e8863d7f95a51ef34862",
Py0 = "58e39050f64c9948d7238b99ecaee947cb934688a6e9f483c5c36b6e07aa31b",
Py1 = "2e64b920f498e12992f2a4ae3f9ced43f3f64705c9008169f3b930a760d055fb",
scalar = "24c5b2ce21615dca82231f5fb0fc8d05aa07c6df4bb5aa7c2381ac7b61a6290c",
Qx0 = "25a0637163a40813529e8a22a3e8be6db96f6dc1cdb8e1844729cad6be11668e",
Qx1 = "16de42461c4db7f9f72eb28bb16da850a42fc153dec64baf021f67f5564f36d8",
Qy0 = "27f2d743d3ce0c1f92c51110a6b9ca93a95693161f1d1cd85a0cf5a2492b4901",
Qy1 = "2c5a8df4fe93e31e374595c0605b1a8b93bb429232cf40f45c847739790c191e"
)
test(
id = 5,
EC = ECP_ShortW_Jac[Fp2[BN254_Snarks], OnTwist],
Px0 = "6a20c456e80e2bfe37d8631d41ffed31cba5d1c411e816d64014d0088d16554",
Px1 = "9d1555c77222abd79e17e2806386c53aba9609375276e817f52f03dc3f75676",
Py0 = "127e76f384726e56dfaa46e6fde6dc644f5fd494d056191059e2bebc525ce835",
Py1 = "2d80f2570da62adc61d794ac17c251f9f9f3de2b45f39c8ede5a9e215e60363",
scalar = "263e44e282fe22216cc054a39e40d4e38e71780bdc84563c340bdaaf4562534b",
Qx0 = "6d7e15b98352e445d1bdacb48826e5a7e8cf854fb9bc18839b30a164a2a9c53",
Qx1 = "12aa3294f6a9bb17f91d5875a5a1aa559c29b06134c6d165d83c8e9e02947568",
Qy0 = "271b8b552e52bdd310c46e07327a18861c91a739da178be909f0a4fe53ae0d05",
Qy1 = "1f4f200de96541e826f0bd536b1401e05e2a7c5a96c567b6dff21a21119bbf7"
)
test(
id = 6,
EC = ECP_ShortW_Jac[Fp2[BN254_Snarks], OnTwist],
Px0 = "4c591d080257375d6189340185c6fe4c1fa796722d07e1bec0b17080b6b1154",
Px1 = "241e2f2eb2a58afc2b5410d4ccbf75b53744ca1ac0bb28d7c60449f8d06204a4",
Py0 = "eaddea52f2e884a5e2635965ca4146b12127fe8a8883e07def8e8720f410781",
Py1 = "cc60dec6ad90e38c851924cf39ddd11b70eeb3fac95731eafd984e9aba2cae",
scalar = "1471f378000d557f0c33c1f8c8313edd53422479440cbd0fdc4cc55f1163deec",
Qx0 = "2a86b4867d7f63afdc09048210a3ef6d363c7896ccc1bb248f3aad4174e1f8fa",
Qx1 = "84c200018461c84ef9ce6de2c691b95cc2c41edc87107331f107ac49de76656",
Qy0 = "2ea1b6d71adb183d9a8dd319a21a679cb0b4e06bc96583d3a786f82b88b5e3ba",
Qy1 = "834e2ff738dcb5e8db7e4dae9336dede51524313b476019ea29ebadbb4ba12d"
)
test(
id = 7,
EC = ECP_ShortW_Jac[Fp2[BN254_Snarks], OnTwist],
Px0 = "115e772198e3f0003e31c0a1c48b6ac870d96020a4d634b7f14c15422d001cfe",
Px1 = "1913447ff41836e0b6a3b01be670a2457e6119e02ae35903fb71be4369e269f7",
Py0 = "14cb779c640aad2731b93b07c623c621a5585d0374f0394e5332f20ac28ca49d",
Py1 = "13a4c4b67f5976431158be8137b5017127fdbc312dc49825dae218a9a7878817",
scalar = "411315458c0c0cb27a058faf15dcbf2e467128f9c958d92de37902e1912f81",
Qx0 = "243a8808a891428d01ef28a77d0766488a98272a5dd394b2992599ff522f264",
Qx1 = "1baebf873402812e4345a8b1783fd25272c64d6194bd9f50b32b8e67ee737dc7",
Qy0 = "1f1001ba8b8b27159568f72e80662e352adfc00c9341d8b4fb8ef6f75ff628d2",
Qy1 = "169af215aa2456c6a65e13ac4df1ba1c982ca791058612679ef26dcb8fb0a989"
)
test(
id = 8,
EC = ECP_ShortW_Jac[Fp2[BN254_Snarks], OnTwist],
Px0 = "13faa1f28e6bfe89765c284e67face6ce0a29006ebc1551d4243e754c59f88ad",
Px1 = "640cebb80938dfcb998d84a8e5aafd47ffbcba0aa2f8c9b1c585baf119a8942",
Py0 = "1de793a9ef8f4dea5dad12fb09ddefa07ce197d4d7389a29ad3d8c6484582afe",
Py1 = "fc6e1f8bf75d1b7e48fdb6b2869c2de553663742c151b390cede6712da5a084",
scalar = "111e6f761ce48e22970752bd56cab93d47caa252d52948367b21163591f7b7b1",
Qx0 = "1c25702bf3b6f5fb453c6473b6dc2d67cd3cc21c65b589df1bfde254d50cffdd",
Qx1 = "14d03eb2075d6b5995240cc54a01ebe50b43933863f0316760226fbfa3a0280",
Qy0 = "1a075c9f2f6afa6e07e54b143a33c17e81d0ac8b91e0c8e0fdd5082bd6b9a72d",
Qy1 = "8e5ef57bb0f95fb6538dfaeac677977e3f3d6f49142c09584d8ec5c2ccd9b2d"
)
test(
id = 9,
EC = ECP_ShortW_Jac[Fp2[BN254_Snarks], OnTwist],
Px0 = "2fc3da947b78ac524a57670cef36ca89f1dad71b337bc3c18305c582a59648ad",
Px1 = "2f7cc845d8c1ef0613f919d8c47f3c62f83608a45b1e186748ac5dcccd4c6baf",
Py0 = "18ddc4718a4161f72f8d188fc61a609a3d592e186a65f4158483b719ffb05b8f",
Py1 = "45b9c3629ed709784db63ff090e2e891c5b5c6b2222cb6afc56638d7389d689",
scalar = "6223903d4bc2adea7b0a0db92822b6c2638691e4388df93f567e11edd6f23",
Qx0 = "9ec612ab0cf4a48e1c15d22284bce8e34619bfb9afb688a9a7930afcc1bd0f3",
Qx1 = "d796e5f5ae1a15622d2284ada34166b9e7c717bd2ff9b2cf2c6e48c33db5ff2",
Qy0 = "2a8ecb09a01cd2f89b316e7569331e9da3bfbd8a40114913b3e5477442c0e4ef",
Qy1 = "282b14bc00df2dd1733e3187a9845ef3a123c17ce4f6154e5cad26c3b48d1b98"
)

View File

@ -0,0 +1,36 @@
# 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/config/[type_fp, curves],
../constantine/towers,
../constantine/elliptic/ec_shortweierstrass_jacobian,
../constantine/elliptic/ec_shortweierstrass_projective,
# Test utilities
./t_ec_sage_template
run_scalar_mul_test_vs_sage(
ECP_ShortW_Proj[Fp[BN254_Snarks], NotOnTwist],
"t_ec_sage_bn254_snarks_g1_projective"
)
run_scalar_mul_test_vs_sage(
ECP_ShortW_Jac[Fp[BN254_Snarks], NotOnTwist],
"t_ec_sage_bn254_snarks_g1_jacobian"
)
run_scalar_mul_test_vs_sage(
ECP_ShortW_Proj[Fp2[BN254_Snarks], OnTwist],
"t_ec_sage_bn254_snarks_g2_projective"
)
run_scalar_mul_test_vs_sage(
ECP_ShortW_Jac[Fp2[BN254_Snarks], OnTwist],
"t_ec_sage_bn254_snarks_g2_jacobian"
)

View File

@ -0,0 +1,206 @@
# 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/[unittest, times, os, strutils, macros],
# 3rd party
serialization, json_serialization,
# Internals
../constantine/config/[common, curves, type_bigint, type_fp],
../constantine/towers,
../constantine/io/[io_bigints, io_ec],
../constantine/elliptic/[
ec_shortweierstrass_affine,
ec_shortweierstrass_projective,
ec_shortweierstrass_jacobian,
ec_scalar_mul,
ec_endomorphism_accel],
# Test utilities
./support/ec_reference_scalar_mult
# Workaround
# --------------------------------------------------------------------------
# Generic sandwich - https://github.com/nim-lang/Nim/issues/11225
export serialization, json_serialization
# When run_scalar_mul_test_vs_sage is not instantiated from this exact file
# "nim-serialization" somehow tries to serialize SecretWord
# json_serialization/reader.nim(522, 12) Error: Failed to convert to JSON an unsupported type: SecretWord
#
# This obscure error actually requires exporting the `readValue` proc
# Serialization
# --------------------------------------------------------------------------
macro matchingScalar*(EC: type ECP_ShortW_Aff): untyped =
## Workaround the annoying type system
## 1. Higher-kinded type
## 2. Computation in type section needs template or macro indirection
## 3. Converting NimNode to typedesc
## https://github.com/nim-lang/Nim/issues/6785
# BigInt[EC.F.C.getCurveOrderBitwidth()]
let ec = EC.getTypeImpl()
# echo ec.treerepr
# BracketExpr
# Sym "typeDesc"
# BracketExpr
# Sym "ECP_ShortW_Aff"
# BracketExpr
# Sym "Fp"
# IntLit 12
# IntLit 0
doAssert ec[0].eqIdent"typedesc"
doAssert ec[1][0].eqIdent"ECP_ShortW_Aff"
ec[1][1].expectkind(nnkBracketExpr)
doAssert ($ec[1][1][0]).startsWith"Fp"
let curve = Curve(ec[1][1][1].intVal)
let bitwidth = getAST(getCurveOrderBitwidth(curve))
result = nnkBracketExpr.newTree(
bindSym"BigInt",
bitwidth
)
type
TestVector*[EC: ECP_ShortW_Aff] = object
id: int
P: EC
scalar: matchingScalar(EC)
Q: EC
EC_G1_hex = object
x: string
y: string
Fp2_hex = object
c0: string
c1: string
EC_G2_hex = object
x: Fp2_hex
y: Fp2_hex
ScalarMulTestG1[EC: ECP_ShortW_Aff] = object
curve: string
group: string
modulus: string
order: string
cofactor: string
form: string
a: string
b: string
# vectors ------------------
vectors: seq[TestVector[EC]]
ScalarMulTestG2[EC: ECP_ShortW_Aff] = object
curve: string
group: string
modulus: string
order: string
cofactor: string
form: string
a: string
b: string
# G2 -----------------------
twist_degree: int
twist: string
non_residue_fp: int
G2_field: string
non_residue_twist: array[2, int]
# vectors ------------------
vectors: seq[TestVector[EC]]
const
TestVectorsDir* =
currentSourcePath.rsplit(DirSep, 1)[0] / "vectors"
proc readValue*(reader: var JsonReader, value: var BigInt) =
value.fromHex(reader.readValue(string))
proc readValue*(reader: var JsonReader, value: var ECP_ShortW_Aff) =
when ECP_ShortW_Aff.F is Fp:
let P = reader.readValue(EC_G1_hex)
let ok = value.fromHex(P.x, P.y)
doAssert ok, "\nDeserialization error on G1 for\n" &
" P.x: " & P.x & "\n" &
" P.y: " & P.x & "\n"
elif ECP_ShortW_Aff.F is Fp2:
let P = reader.readValue(EC_G2_hex)
let ok = value.fromHex(P.x.c0, P.x.c1, P.y.c0, P.y.c1)
doAssert ok, "\nDeserialization error on G2 for\n" &
" P.x0: " & P.x.c0 & "\n" &
" P.x1: " & P.x.c1 & "\n" &
" P.y0: " & P.y.c0 & "\n" &
" P.y1: " & P.y.c1 & "\n"
else:
{.error: "Not Implemented".}
proc loadVectors(TestType: typedesc): TestType =
const group = when TestType.EC.Tw == NotOnTwist: "G1"
else: "G2"
const filename = "tv_" & $TestType.EC.F.C & "_scalar_mul_" & group & ".json"
result = Json.loadFile(TestVectorsDir/filename, TestType)
# Testing
# ------------------------------------------------------------------------
proc run_scalar_mul_test_vs_sage*(
EC: typedesc,
moduleName: string
) =
echo "\n------------------------------------------------------\n"
echo moduleName & '\n'
when EC.Tw == NotOnTwist:
const G1_or_G2 = "G1"
let vec = loadVectors(ScalarMulTestG1[ECP_ShortW_Aff[EC.F, EC.Tw]])
else:
const G1_or_G2 = "G2"
let vec = loadVectors(ScalarMulTestG2[ECP_ShortW_Aff[EC.F, EC.Tw]])
const coord = when EC is ECP_ShortW_Proj: " Projective coordinates "
elif EC is ECP_ShortW_Jac: " Jacobian coordinates "
const testSuiteDesc = "Scalar Multiplication " & $EC.F.C & " " & G1_or_G2 & " vs SageMath"
suite testSuiteDesc & " [" & $WordBitwidth & "-bit mode]":
for i in 0 ..< vec.vectors.len:
test "test " & $vec.vectors[i].id & " - " & $EC:
var
P{.noInit.}: EC
Q {.noInit.}: EC
impl {.noInit.}: EC
reference {.noInit.}: EC
endo {.noInit.}: EC
when EC is ECP_ShortW_Proj:
P.projectiveFromAffine(vec.vectors[i].P)
Q.projectiveFromAffine(vec.vectors[i].Q)
else:
P.jacobianFromAffine(vec.vectors[i].P)
Q.jacobianFromAffine(vec.vectors[i].Q)
impl = P
reference = P
endo = P
impl.scalarMulGeneric(vec.vectors[i].scalar)
reference.unsafe_ECmul_double_add(vec.vectors[i].scalar)
endo.scalarMulEndo(vec.vectors[i].scalar)
doAssert: bool(Q == reference)
doAssert: bool(Q == impl)
doAssert: bool(Q == endo)
when EC.F is Fp: # Test windowed endomorphism acceleration
var endoW = P
endoW.scalarMulGLV_m2w2(vec.vectors[i].scalar)
doAssert: bool(Q == endoW)

View File

@ -0,0 +1,492 @@
{
"curve": "BLS12_377",
"group": "G1",
"modulus": "0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001",
"order": "0x12ab655e9a2ca55660b44d1e5c37b00159aa76fed00000010a11800000000001",
"cofactor": "0x170b5d44300000000000000000000000",
"form": "short_weierstrass",
"a": "0x0",
"b": "0x1",
"vectors": [
{
"id": 0,
"P": {
"x": "0x4e7e6dfa01ed0ceb6e66708b07cb5c6cd30a42eeb13d7b76f8d103a0a4d491450be6f526fc12f15209b792220c041e",
"y": "0xc782515159b7e7b9371e0e0caa387951317e993b1625d91869d4346621058a0960ef1b8b6eabb33cd5719694908a05"
},
"scalar": "0xcf815cb4d44d3d691b7c82a40b4b70caa9b0e8fe9586648abf3f1e2e639ca1b",
"Q": {
"x": "0x4a1203db4af8f0efc18c7ceb24999eb6e0dbdfc8f44a9edd5ba2f9eced38e81ecae287ab1c184eea8e8753d1178604",
"y": "0xf7509cdce5de473e37f36c69d93ff1b2ab04c3ae25a3b5e41f2c138cdcc69ed5eaf4ac95a7a857eef336ebac19bcd3"
}
},
{
"id": 1,
"P": {
"x": "0x13d735b28405253dcc0bc60bcdc13633475ffc187d38a9b97655b0d0fa1d56c4548f11ea0a795391ee85c953aaf9b83",
"y": "0x1693101123fd13a20f9c0569c52c29507ba1c8b6dd412660bc82e7974022f1a10f9137b4ba59d3f0aab67027cefec19"
},
"scalar": "0x913aa7b9fa2f940b70b6dcf538cc08da1a369809ab86a8ee49cead0ed6bfef6",
"Q": {
"x": "0x10e0e8582ec3456f7569473892c23997d004f2542d914fa75db8f1798ed8ce505836e8b7af5cf1503e14d85fadd65ee",
"y": "0xd5151ae60e43100e20aad7eaf8659e690e8034910d7717078031520fcbf6f9a00b22c6a9894aec88c9182f13335639"
}
},
{
"id": 2,
"P": {
"x": "0x6dd2211113cada09d3b96848cbf21ed14f6fc238b581c0afd49aa776980101e4ee279a256ce8f1428d3ed3f70afd85",
"y": "0x3b406b4433a3f44f8e196012f50c520e876412fbcae2651916f133c1fd3899c79f676e1abba01d84bab7ad100c9295"
},
"scalar": "0x4cf47669aeb0f30b6c6c5aa02808a87dc787fba22da32875e614a54a50b6a0c",
"Q": {
"x": "0x3caf55e1f82d746df2bf47defbee127a3e6f7e79a9575929704b25489ffb801dbce07999acbddfd79352b0633a2708",
"y": "0x3fc275c136b07456f0b6ee814508876037add5e95357fae6b4195744ba5ccccaf93581e34feb2babe652a9a704731b"
}
},
{
"id": 3,
"P": {
"x": "0x18648abbe3261f93cbf679777eac66e419035041a967d1e6a0f0afdb92810d7122e0984f1d6efc8fe518500464ee803",
"y": "0x7b6f518d4d06309aad4d60d29118310b6c8b17c7bf5db2251f4701b13b89a8c0f04bb5d0386785e55ffbbd7ecc445e"
},
"scalar": "0x69498486a06c18f836a8e9ed507bbb563d6d03545e03e08f628e8fbd2e5d098",
"Q": {
"x": "0x6a871d872673879fd23ec8c150f8d63e8130dc60343fc0c2ec9ff1b02e769e20eeec0288102ccec6ff2f6ac6973b4",
"y": "0xcd95a31afa4f0bbcc063a1585fec4a6c51812b2baaee42a04525fd55b3a9db3bdb7cbc77f7cd32f42d2e0eb26ddfa2"
}
},
{
"id": 4,
"P": {
"x": "0x745e9944549522486f3446676cc62fb666682e10c661a13b8110b42cb9a37676b6f33a46f9495f4fafb342d5809db5",
"y": "0xbc595854bc42ccec60dd9ec573608d736aa59996cef1c2e8f6c5d424f525a6f3e3d4beeedfac6b959dbd71ced95b13"
},
"scalar": "0x6e08d8714102a5aa3e9f46e33c70a759c27253c7b0196c3e46c7cb42671197e",
"Q": {
"x": "0x18a967a80785de8ec6ac9d98cffa06a8c633b5fa0f36431a32f7bd955946edc3d55f79bfdf5335db405560a6cbe2415",
"y": "0x4552ff2eb6ade0c6b33c3603460d9d62099201d842c9883b33b7ed1147cb17268338a77a9417776ddbd774e91a8d2"
}
},
{
"id": 5,
"P": {
"x": "0xf7b56cf212a8906ed77a758164c0bd05ce1fbd3ee3c4357e7a09b3aedc748a29ace254f1f6df35b8cb74361060337f",
"y": "0x2640ef641d20fea19b28947833e53faceeafa57a8761b807049f3d707d70c01f1c69a57edd993d301a64517bf47f77"
},
"scalar": "0xa5c46d7a52938fed7f3093d5867f65361dc8b48c83bd7db490c26736196e20e",
"Q": {
"x": "0x434f024c4afd7b9a44375011d663af0ae0fe79442e9caf36518e053bb13d49998ec1d2da4bc1c4a812812119b3221f",
"y": "0x32c959e2a678cf93f77e621fdf887454a5f9cb7a67f29065669f48234c25e321ceb5758dfba987431a0c2caec94616"
}
},
{
"id": 6,
"P": {
"x": "0x43b387c12e4cc91fb1a5593b7671356dceb0fe6e6ac666d5bac94f2a44c8db54976b649a678aae038b21144de04e23",
"y": "0x1a6366a50f1f9ba64eef73d82bec86177bf184be048a9d66326ccb0122203569ddcb8cf74445cadaff7f47a66d1b1a2"
},
"scalar": "0xbddd07231bc7fe89ee4a859a00ea1f9d236be9e7fd561303d566904c1b0a07c",
"Q": {
"x": "0x8ddb7a959483b51a1471de988146b7d5b166f660734b4d55166c5a23d781e923261927b1012dce73b822bb6e56bfd2",
"y": "0xdc7178bf5597ef31209a5b0409fc42c64b81260a0046a562ca08c7a9dc67b444c25e94fb97b9a6bb4c137cadd81021"
}
},
{
"id": 7,
"P": {
"x": "0x6984c9385a67081f97b3d33444077466cca1d0442a4da8c083a0957578e0b21011435b126a5ab143da9da1cf5b216f",
"y": "0x18a87c7f5f6c5a8101773e63956b9addd4becf5177acc560d548e5331638121934842fdc9f654b3f456a7df5a2e471a"
},
"scalar": "0xb72c41a6ffaff0aacb5d62e3dcb16acfec66b6a9639e19d3128fd43c18e7dbe",
"Q": {
"x": "0x19279201c3c7a9d50b546aa99d3e1a6625fe2a7bc64a09625b683534638b9e87b9102d4dba6684956b6be7668a658c6",
"y": "0x195f15ad1edc05f8b289c7eee7bd8f78116a2d5ba8b83643d9e7cb2cdc6550bcf8c2145008e900ca9cba4d5040e9f4"
}
},
{
"id": 8,
"P": {
"x": "0xefc34595823e7333616f7768bc82f407268df6f029bf4c94d15f1785dc7ccc08f22e7301dfc48dadc0ea383c8bb3e",
"y": "0x2459bd9f71977ef122d2102e8bfd07a5737066075058cfa8bcaa9f9690ed065919c844363ceaea6f9bb650906a535f"
},
"scalar": "0x8f90f6ab0ffa6e4acc601b44c062745f2935b3dc153d0da07977470080d5c18",
"Q": {
"x": "0x35d08b33e02579581905941975c8b1cc5be1c9670a7f7ef390daa363b0abd3571a802d8c27f156fba40573094f6c7a",
"y": "0x111ba3bdfa4260dc2b636479edb1fcf2fc9478aa722da0118908e1db1551cf7e131c8521b2f3708ef670684dbe8d181"
}
},
{
"id": 9,
"P": {
"x": "0x3eec93c2a9c5fd03f0de5ede2fdac9e361090fbaea38e4a0f1828745f1d14a057d9fd7c46b9168bd95a45a182a3a62",
"y": "0xe912dc7e95f90d91e3274ec5639edacb88be1b092c47c13d31a29ecd579885cc09f197f8207d23b2260ab10c94d5f5"
},
"scalar": "0x203300e949aff816d084a388f07c74b9152bb11b523543afd65c805a389980",
"Q": {
"x": "0x8c23ae9c51e7c92c6a59f0ed07a59f148b4d79394fc026931c264612041eedd3782e4f249bbfad1799212788c1a00d",
"y": "0x191628b702ebef397bb7c52102ee4522f864ff594b24dc385ece081e8066bcde20aa5c7dfd00fb1f3cea221b3ad4ea2"
}
},
{
"id": 10,
"P": {
"x": "0x1059566739d7e809f4e4d1aabad499f7e545d0d3726a22c38cb0e19d83ff2ad8687eb5d7252c600a1daccbaa77e7136",
"y": "0x8b96eb20f3a0004ff700127a45f25063fc28e2f67efcb8441f4e5f62c45c75327a23b80849b88c50221d434687d3b3"
},
"scalar": "0x1b3da5ff83b40516def10b03cc800268b869b91528310a95e69fc0c24d27993",
"Q": {
"x": "0x1337449040d093bbc8bb045efabd39d0bd2c614e9d32a3fced300da578c8c7f8219fa94b4dce84b6f6590cec2a3c49e",
"y": "0x552984425a57d8e80e0ff5b5aa9d80574fd8733a1dca49f972ef42d0b53cfd18f498e8290de91976b2be95270f624a"
}
},
{
"id": 11,
"P": {
"x": "0x137b08ddca0951faa2ba15e4f79d5f9832715730ab8b7a9ea62a957605fa02232de87dcecaf5049714f887e364580f3",
"y": "0x9dddff8f5ea7bccc86af012cda80b58f56586c13c316345a5edf9e7221ea85687f4e7c2d551969e02150078f911b88"
},
"scalar": "0xb74095c9b7c6549479f9f8a1e2664eee2a887e6eaf9e9ed1e910edc66bb14f4",
"Q": {
"x": "0x196cbdc599661615105c79af664881b7b6c27e0998192788a8188a3537559b940e74aced53f0ea558bee9789089dc32",
"y": "0x102e563bc6485853723c8762fc276d5180016775f1cf71ca3022c10bbe8d03ad62290f2d2adb9c6b66ab00211a81345"
}
},
{
"id": 12,
"P": {
"x": "0x30ce29566b3601bef30e5a2396234292d09e149b419c510924a1efb4a1e8d07f8b45b4a40976efd3142ab795bf696b",
"y": "0x19f9726ee1f191037d80b39f26d117b844ff7e1220c3b474d0db7f8b9f4663028f634c2c1bf805f6309b8bd44070bf7"
},
"scalar": "0x1fe7248aafa0171a278fea3359e5ddbfa3c60ce06c019475dc88eb8544ef3d5",
"Q": {
"x": "0x1a11c6e9eeb573ab8e302a9bbe5b0e223bab592ae806a2493a9370886e74ba39bd3c22306799d70430dc4c8e671cd29",
"y": "0x25d7205d6830a4c851863ac97e65952cc28e9f055c8f264c32fc22274be762440bc0c90edbfaef0190f1871fa74c0b"
}
},
{
"id": 13,
"P": {
"x": "0xa29c53534ed37be37af8f29756397abb64765b533550d339f691f04b4bfabcadba1dc8c4a61f60e10745e212bd1f10",
"y": "0x6febfcfd023578c7554a609658c1f5457d2cb4fc469078f08493bb64039c091d88cefa2dfb816fe3be9dfb051c65a9"
},
"scalar": "0x10f8c2ca76ccf39f50a354204aabe0daa56da8fe08f90834486477294136523e",
"Q": {
"x": "0x5d208ce7a22006adf22c8a1ac04098fe4b9a9c2a6354b8b491a368c376c77bf226dcb21e7a49e51b0c66f44568b2a8",
"y": "0x620f6de7d3fa4fbf90007099a2179d8db391971d1ba952b857f62ba22923fb9d0da4b96abd876630975b30918aca79"
}
},
{
"id": 14,
"P": {
"x": "0x10848fe51aff7ab80b81954782eec8facaad3784a213c3e4968f605441426071eb860c6c2d0d01da11be074330a3548",
"y": "0x13126e4d29b91c38a061e9c6248d64599f47e940138225f4adc085b35af68a81bc805bf52260019de5dd9842630c408"
},
"scalar": "0xd77b2fa252dfd15c053a2f557004feb0286877794e3c23f267e1397b6d73b7a",
"Q": {
"x": "0x116b1e65c835d9d8e042c1f7815b0c658fc41ba427e37a79a5c805b13d446eaf4e714fcead0a96b982f1de8359dc086",
"y": "0x12b62cc9d4e12aa9ae3be0e668cfdac43864e2a61e14979769ca5207651000a86ccb76ab37574a433df645170d3fb5a"
}
},
{
"id": 15,
"P": {
"x": "0x14d5afa9a746498411f1719e9f74cb387819458166e8cd553d9f32c31c922697b9fb12abfaac1ad55381010cd87da3a",
"y": "0x2f0427b6590406c1f7fa1c87f09038f0d08369ed0693c39dfcae239a04d433fac6179cc29ca6f484678dace7c24bf6"
},
"scalar": "0x416af7fad0f5d5a277be71a184937b73e97325d7b47dcc7c4ca7b885041f91f",
"Q": {
"x": "0x18788422d3b4ff57f80127bddd8203ac64369ad90a48e6e52368f85b6a199cb16277f4814d8dca60e12d803008c93bb",
"y": "0xf885c05499aebf50f660eeed7b8d4dbf8244c9765a421ff7dc750839687856c4e6cc7b4c551d106b84ff06766af5cb"
}
},
{
"id": 16,
"P": {
"x": "0x1175183ecc5dd314b2b22fed08f26e4306272c809315566fc0fe4a8b616d62d1a67f6a29c3dbf8f90c7d44a1b0cdf53",
"y": "0x1425bb46f998c2b0d4237c2148545d032cba429c1dbdc02a3455f99fa2c8caf2ff5d4422f17c66a9869144c19fad7cb"
},
"scalar": "0x1abce9e9c079c686864304d479d68087db33f9edb3f7b2e4655fe0c1da4993f",
"Q": {
"x": "0x125108089bf35c15169563909d6820273dd2f4f3243f3a04b26a86c8341a189b2869ad1b9f1c99ed2cd8d9f9649da2",
"y": "0xb2c234f4cb5b7b4061fc49e299414135d40e967dc1e7f7177eadaaf17451b8a6d537bec035f8b2638b78b251444d6"
}
},
{
"id": 17,
"P": {
"x": "0xf853b2d6f2c220c9ade11e7130d0c4fbf480c57787497fa0d55bbb77bb91cf608b8a109c0416e4f4f91de2d0c3c7da",
"y": "0x461b751b6a2443e5f6a76861e65bf34d24a792e81fbc4b53a80b92798369e6ebf1602dbf0986cd807de9d4c3699922"
},
"scalar": "0x9d8ee5d0d1286c796cbc9dde632ce87ebc1ede7e148bd453d54c6f69f6f6a43",
"Q": {
"x": "0x16880d061cb3fbd6fd92eda9a9c13f85e015b225ab6b0056142ceb9bda6532a09c51f8c9f95e5929e4c83937370ba3",
"y": "0x136e6dc4c31b67b27ddcf67958ed55956071053842b9dc44098e68172dc3700f4c3b5ba51590be86de73e7e7ff8de44"
}
},
{
"id": 18,
"P": {
"x": "0x19f44738aaa54f5a88211584dfdc7de4bffaf2fff7f978ec18eeca1ff56a9792d4d27aa670b764d2690f97de0fcc088",
"y": "0xb3c03b9c0a8efc24b23821e482bcbabe008834c0c6bf06b6202ad03bb9078cef16c25153a541144bdb35dc1cd196a5"
},
"scalar": "0x5b84be2ad592c1a73f4c23a9968584c200f386ef8ccaa504da72b1d649c067f",
"Q": {
"x": "0x40c1f223b3faea4cce4ea800e4495bbdb5084643aced9ab2df6e813e010d892872b4ccc6eff03c32eee4019178d46a",
"y": "0xeaeaa3123636be20985700f5c40b0aad3dc16096acce2e90b0ab5a436c0f887246ff55b9c78f1d9bad2ab28e4f0a34"
}
},
{
"id": 19,
"P": {
"x": "0x1d7ade04b0b494cf9a18204549a1e43670f61bb597affcdad332235feb05dd7b23f3c19389b3466733495db14bc0b2",
"y": "0x1385cd962326c026e114f51ab5e838e740bc9026021c0a45c3ea8c2a06f85da40a2d786fcfc52aed63b5ba0f5673505"
},
"scalar": "0x4e3b311a9d5b6cf2a052731b8f016734614949862a9f2be703935a5e0cd43bd",
"Q": {
"x": "0xeeceeef376634d1b387e689d22c5cdb4283a7c30fa1db69a85aadeaa9087dca006a32c99cd6185d1547369f74942ab",
"y": "0xfbc0a8bd889652d2bca06f3d74bd5bb13cdc9a0f51d27ae82bcd3e0627bcfe6d69a002d8d0ebad76a1ac571343245c"
}
},
{
"id": 20,
"P": {
"x": "0x190c235c2ded176e51400c6be1101417ce6fffdc54fdf9e18996ecc3b7336d957c2de096dc867ded034be25db356af5",
"y": "0x11b315331297edd1ccdca050b9f350f191c33c33376f797e811eb93b67c19be4bf3c0eb8b00cd7b9c7cbc3a0884d610"
},
"scalar": "0xb101f1aace4f33a418c299971d9f1aea0b147bd30d3c622be93f105de665284",
"Q": {
"x": "0x60ae24af5636a2175345ca0a80ea2c1a0005bf7fef15ec7288ee07e140b6d9a9c0b1329b5a6659adf9a9c0934fcdbe",
"y": "0xec674893e254e6fc23c51582a5afcb7ecb594b6f01893d702efd265466e2bc8026bd54b65148c57fe16abd82b67412"
}
},
{
"id": 21,
"P": {
"x": "0x13e60f4a6ea38f083da305b6d7bb961f104657a0bc7cc3e07bc62d2b2fc3adfe353e5e2b00083b1b1cddc86d77f4a63",
"y": "0x4e86375d04c3712c7986f1e40561e15cdc1d613bdb23b2fedab9865f3f20b14f355aa2f3e26058b3001ff6debf1baf"
},
"scalar": "0x128ba2a07c3eaeaf79e8798a5f5e6c5b68facc4d7a2548787be9df6d017acbfc",
"Q": {
"x": "0xd1fa9799346f831d300da85d02fee8c7b6b338e04c94a82b87646c8ec48eb653a32977c839e5a8fedf33b764041580",
"y": "0xa4998011326524215671e4efdc10e6bf361c2e2c8fd9fd5a623605d76c8cf6477c2e32d2550d20b21c5123b1bffbb0"
}
},
{
"id": 22,
"P": {
"x": "0x1ac8f1a07307d2893612240cdc90d4e6d09cf6213dc4c628eaadd20c45d6468419e773bbc52dcc7f96fd4156ebc4b03",
"y": "0x1ac12cb428a81e6b5723dfb9d2e913ac3867071ed348a1e5b3e201e471575e0ce816ac99653f30c4e954cd9d8b33791"
},
"scalar": "0xbd936c7066316d3f86b077419a0c0fb9867d4612208241fc004b548f1f54fad",
"Q": {
"x": "0x7dc0495d3ba2ac3ec9e042852c5c8a2cb409177412ab8cf7e914efb7a4a79ea74be0d2d05ac0e21cfd94f8360d3dc9",
"y": "0x10aeec70a2ed379232f91b7d7ac36d65b300789ba0c1b8e5831169bc06a0cc7369c9b8b6b75454ddb1bd0ea47043cbb"
}
},
{
"id": 23,
"P": {
"x": "0xd42cc74c705c69cbadb505c6bdd3945cb55643645fcd0dd4f8d03e0f8f6cb555e35878a2083ddf1822289e6984d1d1",
"y": "0x9437ba66de87d02488b924d870a6aac9d559fdcc3dd4a11fb39a587405138c67d8b40ffacbc4c2c569216eace7426e"
},
"scalar": "0x125b0927fae0602054e45cbb2606d068f8caaf94e1c5986186301cec80171075",
"Q": {
"x": "0x566b4cba972d223e5ecf302db3abf9a1b5f635c695796d62db56290913f8b3f5cbf93340153d6782d9db190bc1a38e",
"y": "0x65ead53709d930dabcce53a8f91a5941e4dc398fdab15bf709d09fb73ebeb425ea6c7518a7c75e25089699369fc37f"
}
},
{
"id": 24,
"P": {
"x": "0x1abd2a45d8a9271f700f33eeeab223b68ce7f1c3220c23584b8d19c4ac9eb1bffcfb849ac257787211cf4ebfaa80aed",
"y": "0x1737af483d223a5e039e8715f2b529652e1b65f8a41d4a068f019f8057471ec91ea7a4db4401295de6c86f50b42e2fb"
},
"scalar": "0xbdb46c0eece9c8bac8a382def90b522b1d5197f09cf9f7cd98b710845ddb7b4",
"Q": {
"x": "0xe789cd635126c3375b33dba71787bf586cd3fdcd088d6649e6204499027af4662e96b7c20e50ccda28256cf3e2330e",
"y": "0xedeecca7bb976e49bad7dc80b0966b7e38c4fd0e27da0a15315507b37163703fef2f9432fb4c22a1130f014e6a59c6"
}
},
{
"id": 25,
"P": {
"x": "0xb268217aba354ab4e990cf3ac64df96850490c7d7e4dfca5af149e282310109875348dc46425372e07257c0fd60444",
"y": "0x9c74d5a1e5349ddc4e74514f6c2c23ad38a330c6ea4b9121db2b99dfd433d3394a6055d9968282255490454bf9633d"
},
"scalar": "0xce4e8733f9491e3269ff2de895375cc946ef4aacd3f4b2db5252c67101ade8",
"Q": {
"x": "0x195fc3204d6dea6414a5eff56329e1c1ce3ae7646ba85295d2b4801160a1464c96b370a874ec2e118b1a20f6cb7e0d4",
"y": "0x17dd3e8c51c3375fca7cd55c1940c02065e027cc660f4ce4b7f31585a4d5c98517a430470ce986dcb27a2fe551805e9"
}
},
{
"id": 26,
"P": {
"x": "0xd9b773201b05913f8ae27d7c894dd16542b3495324462e66e26ec3c2866f446b3bd97cad95e1aff0123f60d89286d3",
"y": "0x6a4ca5ef1dc12422d0211814b79a2c09e9113c160164263e165fbbecfb49b80edce9e37ba98a3411cd99180c73dd8e"
},
"scalar": "0xbf62a8efc2c13d8643bf7ae7736547267af110611b331deef2b14bb7a12f17",
"Q": {
"x": "0xe8a6702c87c1465e535502290b1116d122ca62e440768dfd1b40bff78c6da5cd105ff12bda91e7363d9bb6f359db90",
"y": "0x10a2ad9107ed97c511a43ad744494af39a5319c97a99a0d68dd4d72966b42e9536dee2e38cc52d345f982e4c9ad340e"
}
},
{
"id": 27,
"P": {
"x": "0x16d668cfb1cd8f3ccbf8f6fdad31b5bf3b1509aa2e17d2d5731b6fa6618730f4f2d58d692c082ae6ac1730d1667459e",
"y": "0x10fdd5a6c3cf89e8fe4f908a99ec74d83107bdd071f07bb9cf6399eb83a72158e3bf19839e35236605aebbb708873d0"
},
"scalar": "0x56905360f50fadc7b727060812eae0a48e31249ee16ef94d0b905575982419a",
"Q": {
"x": "0x8b3d0eb8490198e3f188fd2958fb11522e26b7f015788b451478d87ad91c81261956897daf5cd0d687d1af01f9a44f",
"y": "0x121497a0e204df5698da46ffc2cdf7e575730305fef9d2ae8e020145a3f4c790c0a512bf73b519fa3da0c1d151cb8ec"
}
},
{
"id": 28,
"P": {
"x": "0x10a63254fe9b79cfcba46497503df4597202293729df02430d48150d541f6f0637c8184f2ac17ecc393acd6a17f5c2",
"y": "0x4f075f85da79d912f281fcc6836a026f8ef0f81b82895e44df9373a66bcb75ca3c9e2033f394d34c1aeaadd3860753"
},
"scalar": "0xf4dd3101ad878e82d0ea59883e07402aa4b31be2ec48738a455a1352c253e52",
"Q": {
"x": "0xd5fe9d3786de4eae06df72da7ace296efc1e64c2bf91f9d5b4aa763b7ddf96d29966c493b485546088c915a01d5e3d",
"y": "0x9bc16aa4450cea3f3cfa3403f6cc15c093471b4a3a237ccf68737154b7d9dc65cafc981e5584f3f0037916daec1fe"
}
},
{
"id": 29,
"P": {
"x": "0xd5b8211ef9e900bffce9f3cd0c8192ed312d0986115c958a5f3fc6165a14b0477ca76e8b9001c122a893a370539ad4",
"y": "0x5caa4a51cfb24184206f7ce8c374a991df2a0929ab43a9645c79dae48c143a59d427c6d4a93dbf5652e407007c4920"
},
"scalar": "0x3882624dd59fdd8428cf3fd28db20d28a94ba94a5e0a8fbc1ea4c3a25a41755",
"Q": {
"x": "0x167afd3babe791a31241bfc7f7b417fa0f2ee0083fc9424707414e7f28de55ff95744d324f57509fa6ff2d9c59068cc",
"y": "0x1436a90529ef244ff769e2dfba0b30cdc49726dd10f56cd4f6845d645cac69da8a590a3391fdaead6af7c4276ac76d7"
}
},
{
"id": 30,
"P": {
"x": "0x6e7e8b036725a99e4dc1ce6d353fa8388d13221803e1d0fd53c60353de4add409f495c7b4e7d750cce796bd839abf4",
"y": "0x17d059368fa0e6b4c1509644d65fcf2f767b30f0b6a0b8d50bcd71ec49999043e25dc81e17f48ed638b8efd9231fde1"
},
"scalar": "0x1a2d363a7d869f9592e8cf63f5df14451894f8d5dd7b41a3cac93a13a157a79",
"Q": {
"x": "0x19238977df4ca8f585af4d1871bfd4689f52df63a89bb3f5938e8512d1c95f620244030013f807128d2b229c89105e5",
"y": "0x1433c735661f48c76c09b653d1af06388f956ac643c50ee81977b7177540d52a0756f1095119be21965460bf2cf4270"
}
},
{
"id": 31,
"P": {
"x": "0xcb49fa5f22e9b25c6ee37c06d7db5bfe71ad40fdb9b8bbd23310854fcaaa36514660e26e3f3d3b40683221506008e2",
"y": "0xad5d0cc67a9bbf6d9de2f40f24a2ea1e82b810bed1ac6e17177b8c0eb5c6101bd11d9f3b1cd7d5144992ac68a03fc"
},
"scalar": "0x828fa4ffc8d5bfb75c7df4fe8b731348c9235020195b0c0277d87f2528d2beb",
"Q": {
"x": "0xdb6bbddbfbeb8adf4ef28dd67f74dd764c7fcabf7d3958103bcd159f6d75a7e57c8fbb356044ea4285e4ab883c8591",
"y": "0x18ff2ef876afbed0c2bccf610219e0160bc5cd21fc27bca718fce466f04dd72dc88f8b5d54f3181c9d85ba31977f582"
}
},
{
"id": 32,
"P": {
"x": "0xeff19b81e8c019b4e66372deb4bbd5eb53e7fd28f50d191202219206ba790b1e7ad80072c07533cd110c6aa23f22fa",
"y": "0x10fedf92b738516b1b69ff28fdd02160fb57db01ed9227ab469375a5f391aa24bdf4300a259b4570bd8bfda01fb709a"
},
"scalar": "0x3f1f2f3cf086cd1246feee0c5a2464cea3dba7e0b89aee64337644111924b1d",
"Q": {
"x": "0x5ac25bf2f486c4490940c4f778730e6901c1cffffe85b16629e24eed4fcd7b07f44edb924ec5bee3d84b006686a092",
"y": "0x79d55bade5281c754113ae592f0544bed2587f6635d52daedc66bf9c0de0659b315d07fcc4be1fbad7552d2fc16e61"
}
},
{
"id": 33,
"P": {
"x": "0x30b8bae257cd9754bfacae78ff6c56c4b5acb83d60a7e556bcda6d6c0fad2405f040b7b365f1b14cccd302285b89f9",
"y": "0xc5e50cb86f60bec122f7c304549431a16f3522b7d7128c40bbdb9f3a525dcc402dce462152e1f19f80ae3430208d9a"
},
"scalar": "0x3c560ba9a44130e7b566b2ad39acc7cf178ccd0272b84dfcf53b10acb8e3be6",
"Q": {
"x": "0xbf61a3ed87dc003ab2f17cb981a33d1810bdefd6f0fb9b245c9647778a1fa6d41b526e2787c379076412dde07ab01e",
"y": "0x37bce1025a01db6dfb37aea5dfb5ca2ad7ef7a9e58c5a968d73cfbd61d3bf7a81b943bd3c87b0ed17bc9ad4b1a7bd"
}
},
{
"id": 34,
"P": {
"x": "0x10271d70d423e4da106933c84df4037af5be96296f905e6088a44eb0b0b0c2078eefaec55bc24078d4483d3e5f0f0c1",
"y": "0x112a6a736544d6cbaf86498b9c24cc07be48818e7e10240a53ca7a3ec7ccae1904960b75ab09ffffa95ff7a6224aecb"
},
"scalar": "0x11e6bd418d7f4688bd95500c2c6bb17b54b1374c0b120613810a740f39319e05",
"Q": {
"x": "0x12ff92ec16179edea66c4cd8e47ee0323952432c8698f8b9cc8ce62ce1b7146f87888eecd77a7ff922dcc89b56fdb9f",
"y": "0x18fc6985ed3205b8e8855bedf29137d43db531231c90e909b0ca934ce86ecdc28e2f438c49d39be713c9e1185cc1505"
}
},
{
"id": 35,
"P": {
"x": "0x1ad73f190dea64c1dbb1cb86989cd169040532af3b6abdca5da63de6472783e60b15cf8afad4590b933a275fa09f82d",
"y": "0xd2adc75756597618fccc80bf152fb2dca16c5b8310824c2affaf622cc97aa223aaf0aed4fc9ea44d75eb6b1b0a3f1b"
},
"scalar": "0x6e48d6bc3ead3859bad81057e1e4f6d15f1f7b01cfc0434f536b7dd7226dc8b",
"Q": {
"x": "0x8519af36ec945f4d624a6bcc62acebbe006d78f664a7fd651b0989f830a80da1c158f4c6ec13572c2918b8c10644a5",
"y": "0xa6408c801ed5c55822daceca164a9b5161e59579ae4281017f9b8bec0cc2b81874f021e5b521234166adced2113127"
}
},
{
"id": 36,
"P": {
"x": "0x8cb6a687ff4052c149a9f8ef6301cb9023a86eefa2eb1c4abc5f852d5a6101098efaa8f2d7d62a5e4c45e95d0d2148",
"y": "0x16379adee9e0b4f24c8a7321b67633b4ca92a646315d19fd7d615d258228fe55788bfb9b43066358d3fd86b30ed5e72"
},
"scalar": "0x24acddcd653958352643dec812c75bee17f729b0cf1936df8c60669711d8ee",
"Q": {
"x": "0x17d03cadb318eccf24680c21609cf42519692c1c458b67f9bc41d892bcb6bf3d3df8d0c64c6960b01dcd1fe7b65e451",
"y": "0xf8a18049dee4397baac0e1421a85a0ba1428692fd44bdb027d9c133eeaa470f1353cff0a7c29cc81002116a7404062"
}
},
{
"id": 37,
"P": {
"x": "0x160f035c984fc14fc4feb1d03f2ddc4393693508e708fc7114dcde0a7b01a60b7ae26a7fa49517895faa9f05e10030e",
"y": "0x30a35286590d25a199f19b6b160d0a35ade83191bcb4232fa709d73fa78a411120f2f3bca39beb8d4eb71633c76ee1"
},
"scalar": "0x48a33710b79c49635709fd11ca9b660302e17361dbc11623db76043fda45f83",
"Q": {
"x": "0xfec169b3323279c55ff2a6fbb2b5c6ad2db80f862ba24623af570ed752cfeb8126f35b62e3dba9a2ec7c95278daea5",
"y": "0x191156fb08cc34a7135964c268f67e2c4867ad60bcbd29acedbcbfa45412fda3a5543a90af8860bdf8f23dd7863af2c"
}
},
{
"id": 38,
"P": {
"x": "0xc05a5beb427c59de69288fffebba18ad52aebe170f9d25eb6d33aee9909c2cef4ab8aff3277d286a34370b0e3a48fd",
"y": "0xa18efa9f07c033c915282c43539cef367ceb33407b945d4e8cdfd507a16ce173817eda4d9fdaee980118ba599bc931"
},
"scalar": "0x2927e0845fe1a0f33ff628afb719e558d4ebf1a928e0c965eb224227e5ba3b9",
"Q": {
"x": "0x195c37ebf48c46aa59cc2e936e2e1809448bf5ad196bba905ef30a7c215453e40720f807d7028f93dd2dc64b3b87e5b",
"y": "0xc06369095876bba0461be5d52175a55855113e6901c141db3cbd34c1e6628d5cbec6662b3ba3e82a50777bf354178d"
}
},
{
"id": 39,
"P": {
"x": "0x16a0ab8e16b4272940093ac7f56613349ceac9f476af5c5e415aef4580b630ce3588b2aa5bd3aa27e90716f7e02a330",
"y": "0x4aa4fc5dc4617aa52d71d07f0d18b246e7380c081f6ad6e406885e4175fcd949b58aaca1ed5f4660790c84ba41b3c8"
},
"scalar": "0x82a86ac4d89d0e0bf2c9fe28e0fc0812d4267663157fe0ccb319053076a2449",
"Q": {
"x": "0x8b1161e6cb9406e0377bb1f7bc54b61d381a711768cf2df9ef010e98f5a6aff4f129b327b7a26506bd2ab5d4a15603",
"y": "0x1a7515b4b12d0a9361027d7c85f07d65cc1c9e3b9845336b69ea96eb44ce30b2c2bd4b7f606c4a8f8aa7469eb0e2656"
}
}
]
}

View File

@ -0,0 +1,980 @@
{
"curve": "BLS12_377",
"group": "G2",
"modulus": "0x1ae3a4617c510eac63b05c06ca1493b1a22d9f300f5138f1ef3622fba094800170b5d44300000008508c00000000001",
"order": "0x12ab655e9a2ca55660b44d1e5c37b00159aa76fed00000010a11800000000001",
"cofactor": "0x26ba558ae9562addd88d99a6f6a829fbb36b00e1dcc40c8c505634fae2e189d693e8c36676bd09a0f3622fba094800452217cc900000000000000000000001",
"form": "short_weierstrass",
"twist_degree": 6,
"twist": "D_Twist",
"non_residue_fp": -5,
"G2_field": "Fp2",
"non_residue_twist": [
0,
1
],
"a": "0x0",
"b": "0x1",
"vectors": [
{
"id": 0,
"P": {
"x": {
"c0": "0xab080b20561040388b5b0e22af3c27f68ad41d5bf57de5b89bc5fd688d41b7949daaaf78dc87ff070f3be842c54232",
"c1": "0x1a80a67d56d1e44ebeaff0b560cc05a21feb39f02bf32910125161a665364ddcd2417183b7970563991556cd7f2f046"
},
"y": {
"c0": "0x16e3a6b142cd3ae7ecc4e8cf253c99354d65ff2b734bc87d6aa4e2a92eef56b20f70eb39fba31f3908526e5e3853a25",
"c1": "0x12eebda917ccac5823163ef8e49b8b67f72dfd1daa7f9a1a3f62918f7e82f29daa9b4efae38487b7faa01d949896369"
}
},
"scalar": "0x774340850f83bb192b29307e9b2d63feb1d23979e3f6321624f33531e78a45",
"Q": {
"x": {
"c0": "0x16f689a3244aecf1574cf2d3b3f64dadbd22b43a8ea61f50d99280d3815b1bbb1ac4a63933d9437d5c1c470fb07f461",
"c1": "0x1631603d58caa47ad3e3f3db3cd27575cf28729547a8b7c762a317d41fe46779a3395b5397c334b541709db5bd3136e"
},
"y": {
"c0": "0xea7c0527bc52243b89c9d3cc09cb5f84f7fe687d652a7cb88c345309f32f1e6705f6bd1a30224206dc990ebf003976",
"c1": "0x8dde747428890f58f6d4eb0a4a8bafa849be885111238ef701b067aef50da41789bfa54cde8e4a7b73769dc3b0480d"
}
}
},
{
"id": 1,
"P": {
"x": {
"c0": "0x359fa9239299018b83196cb5aa6bfd4ffe9307052f037417c3ea258c85be0ae062be364864343b55386f8b7adffe58",
"c1": "0x2737f25f0d837f6c1aa145331fc9d5ff995a0ee2812435064ce44bfb70bbc3c4da02c10aa522802dc74b369a594a18"
},
"y": {
"c0": "0x19e725fb4bb3e1746e7ede80f4d884a43cf7ac2888184079ce54cf3e737eeec20cf9c33da0032de61cc21a57a12adf2",
"c1": "0x17c8960a47ea043b81acecad1c56b287eb09436fe7739b122afca82a4406664172f159f7971c71584a11c07f05a862e"
}
},
"scalar": "0x50b392d2e7200e40515f675415d71a3eb5f02abbccaf42dcb77b2550a69c021",
"Q": {
"x": {
"c0": "0x139e63a12dc3e1bedf9243757820d6b6e6932ee7cba62f65fdf5db1c3be739a812370659d330679e64d87692a0154b",
"c1": "0x1226de321a004cb658d9fc45ab4eafcb3e29c4671c4639e09ed94762e21f5528bcd686ad3bd401290c3dd35a600fc7b"
},
"y": {
"c0": "0x112a6f343955e4ead54ead9847c1a28ece9737e6af055672cec4059b94ed87a2d297e1d650bbfb68a263252dc80c851",
"c1": "0x12d701462b8fe6c0a3c75194fa7ee96c55b5744a729edb1e2bd0844d92a5fa7537ca525301bb48b106449f69857cce9"
}
}
},
{
"id": 2,
"P": {
"x": {
"c0": "0x199e658daa982f2b12bcf3e093b2fa44f5b908c42d10ff14fcb4f3f3fb0ad467cfd0ab1134137e3aecddcbd473708c7",
"c1": "0xc29ca66fde2a48cde9d3694c2fc05e2e817d4fdbddf3812c08500e5ccfae4de267820b6168feb14debd4b05cc02fd8"
},
"y": {
"c0": "0x3032543e146466f9ad67ef77370084b8121a31e52220f06ad6e43eb61877f7bce6a42d9b5599316c4dbdf614d70ab3",
"c1": "0xaabe6c9feb20bcfb68e1d4a4daa7eac856ee818fa54ba9628d82e7ed0e057bc3fdd8709ed6c630a3d9eb4195b448e4"
}
},
"scalar": "0xd06ad767a953eb0ae126b764fcf9583ab50420730311af7d2b1c643a4e5b8f2",
"Q": {
"x": {
"c0": "0x3639cb7ba5e0adc7d83e44d8ded4ced5ae2bf2ba97c26ee12f5b8de190beb5a3f9e6209c24272380f65db70e9db0c4",
"c1": "0xbe25b2df8874d57a2e3f54f0d313a5d862e3ef89b6aa8fe617cebd9fe964c5622dda60eab46ee404b7c30134849cfc"
},
"y": {
"c0": "0x13857ac7c445075b25f1b6ded6670d548ba2fc7953637d124c91b1b46d8f1386d007a75f96bcb4abb62319e0ea9f1a9",
"c1": "0x1d0c5fae0586f434721c891325ff258115534d0ee356c9bcffb4e40f87337060bc971f00c706c69748535066f014f2"
}
}
},
{
"id": 3,
"P": {
"x": {
"c0": "0x17f1cf8a2944780ed7e23c433183e2eb8b4c1db163192e783431538f391bf777812feb1d960ccb4c5d626b205d7d4fc",
"c1": "0x1171c0bf0e1d0baaf229a9009f43143adca3005a7e9698c4bc742834cf3ba02407fb0024d8174052ba71811eb5fe322"
},
"y": {
"c0": "0x114fcd5c7f34b90ca2e08fc39e774ea731b93a673dcabed1495c702147ffce2f3deb2add026a1b25c5bbbceaeb6f285",
"c1": "0x14d84ef523a6734cd26ed1412b6e3c4d23a0c5a9752f4902ab46abc286d265f50a086af9ecdd8f03e9539a1df170c33"
}
},
"scalar": "0x9bde0fcb2da232a8507ac66a7c7422d0112a50bebe904792d43dfec443d86be",
"Q": {
"x": {
"c0": "0x7e32414bec635bdd555c19605fcc49787c476a834b3f68dc4ed607a477d273772b70b51fdb5dd593d97db20dcb4abe",
"c1": "0xb138769b96bbd8626d1eff0342fa3a30cfb4ba16a8b585fd4ab2e894297c684f82ab64cbcd335b306c6bfc4a452fa8"
},
"y": {
"c0": "0xeb1ca93b164d611a31d54cf530589029dd052bc12a41f7edf002ffdaa62fb97c4e8bfb0318770677306765f5fb50c8",
"c1": "0x8e607bb49a9a1284a70ac03a3babf2b6ede1d96a983a9e39d425662c7c1a914c515131a1790ab46c80cff3494d4c69"
}
}
},
{
"id": 4,
"P": {
"x": {
"c0": "0xb321f753541fe24539521c4814c7eb2e2c8886dbb6d23d8ec4129a0c4cfde627eac47a5d1f1655379c492b5b7c1f2e",
"c1": "0x101f060a6bc3ed14996b34f80b7724e9d1ba22107371d403efb577e1161836d2c8ba723f37d93d9d3317f2f834c1573"
},
"y": {
"c0": "0x3c03926763201e78eea6140b2047ddaa9cdfe8a76cadfd3ee10bec3a458afb00f661f0d26ef4a159b35da4084190a8",
"c1": "0x821ea08b0857fea85e0fa61e9c79a56188b2699118390b2acaeb6053e44af65fb091e38f05be46a68f703ac7f61254"
}
},
"scalar": "0xa923bb520914b82ea44b16129671e0d4906bb9774f7627b13d3817fc2de121a",
"Q": {
"x": {
"c0": "0xddecc1b023be5b72b28d30bdf5a55f8b83e47f08b8a807a0b0bedf6bd4f50c5d6092dc2df2d6b9f863dc12c599632b",
"c1": "0x168d115a28fd60e4ff0637ea952a5460c5f912a99cc039832c5018eafa661da92be22cd9f295546807e5fe46dd37440"
},
"y": {
"c0": "0x4a40a0f25e61392fd97225cc1be3b6d5740ff6f8c4fa43ac859a80ca591ec7f2053b620c4968f0f0ee2b456b0843c0",
"c1": "0xf97bd29b85cff2896c555a3660576bf61d04f47b47a5b0a64d159e26818c18fd1cfe0e2c6d39a3a52c3f9b22add20d"
}
}
},
{
"id": 5,
"P": {
"x": {
"c0": "0x8b35f65cdc4e653ec18b127828a2242100b98d838cf19f9daa3299e26dc4f59b360e0909779856d75e1bf092fdd7e",
"c1": "0x4989676fa8d62f962b0141429992d052801e2c1c2039082df7fe4c01c3bf3a592d75d6971f50e9a779969e10079b82"
},
"y": {
"c0": "0x13a9cb8a4febb25942aa53f43e6b00fa15fea23cdb1101198507cb4a61506bf5554389c2d23773def685b09fb3e93a",
"c1": "0x5aefc260542351828c2a7325d8aac3e7e954f070f3e8a5ba8d8bc40604a0a92b88048dff6a41ceb46949285c3c5426"
}
},
"scalar": "0x10f43f368ecb344d0636809104edbc0f61eb3094a0f15a900d26aeead09cd1c3",
"Q": {
"x": {
"c0": "0xe72923d57e8bdd14776d8ea18c02513b08f94846833ce584d73531af71691867f878268e1214549884cf71cdba168a",
"c1": "0x4573974413e2d5ab53176cc7785dfc7ee952c3f3887e1ac4dabdd003a5199b702d81ee1068aac922d4f21a3de1060e"
},
"y": {
"c0": "0x62c0cde1935571d1720c85dcf2dde942a991258c82fe15c7d5d53e32231e080e4ca48cc17b1e2a28f9025ee768ea4a",
"c1": "0x16245442188862d124c10841f260cec7255c7246bd0a803f1cf0edeaf7ba6f66ab326282f03b028b900625cd86c53b0"
}
}
},
{
"id": 6,
"P": {
"x": {
"c0": "0x1709bb2fde58addfec90776f0c6cdf1223f1e5394918b2ef66a214ce85b6faee524112e88d5febd3234aabd08703a8e",
"c1": "0xc1ecffeb91b81339a30627d9a9b84b61f57b8436ce42800f0d149477d85e4d121acb10278ea99f591f769d89790a80"
},
"y": {
"c0": "0x16f62a599b3332cd2b2efb0238683bc0344646a15501240f5dd62b1eeb8e52b07e34c38e4124e5302f26a09f44c5097",
"c1": "0x958d11d762deca6f9d35c7f078d6b737e2a22c66b4115d8477f5d6a70d307034d3fa474a1753d49fcbb6262041b1cc"
}
},
"scalar": "0x11ec1943f2b149e991f1e8035fc86ae1dfb12fa18736ed458a39c77b4093a33e",
"Q": {
"x": {
"c0": "0x39249a2948e72e2d57e581081df3ed5e17743df8c7537b81d2b2131e7e4eaec403f4695b602e86dd2c7e52728fe4a6",
"c1": "0x12c7dfe5d9393d9d6038c79a524a025e7558f4693bb304beb0298b633f41114653b0fa0813095ab4ca8be5734f19b01"
},
"y": {
"c0": "0x10570b80e43d42de115820561519229ba52a874b82951a4a6c6ecab8e1b8e50bd023a18c8dade5c562a1478f22fbf46",
"c1": "0x5d50b99511c87aba4ebcda4c2d1bc2a26b290da47de1abf16437c1d11a2c8e0a58838db4695011e4df16266c138caa"
}
}
},
{
"id": 7,
"P": {
"x": {
"c0": "0xada92586e33dc0713ce175fbe109f77dc6a7d9499e91b321b9e8fa975f922733eeac97b9610ae928d089ea116d8d87",
"c1": "0xeb531d457beec2aea5267204c0637bbf55443f06f416e5853ffca5b1ab83ae2958d1bf50ddc02dc01e1ce3b8f92761"
},
"y": {
"c0": "0x79900606df01fb4f6616107e8dd63879ac5226d4a55fe321e414a3b7f240dd5924f72ccd3136100e3eedb89d70a551",
"c1": "0xcad03ded8e7c42164d8b24ec3cffea23f8177338926b1a3ed7b91243e103c279dcea8b135af40350387db78c2d670e"
}
},
"scalar": "0x17229a30580750c1f2b196c75ae2a5aa5d528dfca4ecafc72acd5b28be21a32",
"Q": {
"x": {
"c0": "0xf10d47f95432fe6558c7ff1835ac3617da1c49aa6c2b2767bb82e8656819578f7600b8efc5ad528b02412b547eb95",
"c1": "0xe47fda35ae2e140738c563e5b75f836bedf18395a9e29314959c484c7aa663a289ad8caef6a3f6bcaa9522daeee04b"
},
"y": {
"c0": "0xe9b82a43338d0aa9f9c7c84f9ed49ef0463e8da5fa46d19cbf8c969023f7410a88c3b96181c4517c9d2154d518192",
"c1": "0xf3f32949aa4e313e85b0232b239a847c572c719d6ba55bfd9779548ba930ba6c70cc8e8e77ebf062c18f13015c85ec"
}
}
},
{
"id": 8,
"P": {
"x": {
"c0": "0x289d0e4cf158757dea5b024dbd998c81fbc0f06a904bde9b18d932652e02be4445d6c78f61c526137b818e0e00646e",
"c1": "0x73f35ca67a60db503364666475e69bd0f4d5982841c639b791ffa71b3e3cddd4f6ead93a889d0155c4ae171509a387"
},
"y": {
"c0": "0x39a0891b143f55b9ada61c437e079036a190c48f9a2a74a483d41398be3fd131453a0ad4e8b88516e17e23e83e45fc",
"c1": "0x99c24cd63c88c151524319ea76336b78cb821840da63d1e4c7408e1d65b2eb24e9300e7c4a92afbfdcdb8a5f9fc9f9"
}
},
"scalar": "0x117efc66135de516e814e8a0cd0bcb57a03778e98811a7774bfd4b558c5b3266",
"Q": {
"x": {
"c0": "0x16b1d804cc39735305040e3f0b73d08ee7350bff914d29efd7ab526f33699a39bd19fa1f72746f8a57eeccb3bc5280d",
"c1": "0x126aff9986e72f04fdb3a19afffb6c6fe48087021eca667ddb1ff1d50c581ff77594a61a0a1508797cea71b6cde76e5"
},
"y": {
"c0": "0x193b8f8cb2dab755711bbb1029f587c0842a258dba162cc54a7f40d958b79f998c711c8c73abd3cf8682fc8d58838a3",
"c1": "0x638966d78d57ca15ba7e14a4727a97bc7ec4dac2057678d2c175f1045172dc143237ee1c3a70e74dcfd3b34f166b9c"
}
}
},
{
"id": 9,
"P": {
"x": {
"c0": "0x1320dff368249219ea382d5a54a8dcb93975785fa35621ef52e61ab47c5023197b83ba046ccd3ca6ccdb68da413527a",
"c1": "0x834357c03209c362c737d5dc17c18ea1af545047fa2e23da39dc0157dc155245318dd669f74083ad372b0a57a7c2d8"
},
"y": {
"c0": "0xbe24f5fb316660218b1e28675af59675d09ffd54eecb6fe877bccf726a2e4fc0580e002a0b2c103223963e2d7aae4a",
"c1": "0x852561e740cbeff4852f3f7d9999ab1f2c5b62f1f5bcbb949b45c45c88806cfc4fab4604a21250302af338aa6035d4"
}
},
"scalar": "0x6ddb84e2bc7914cf4e25ae1c8736ecb2ce4a6a2250ed4d300898044ef9855be",
"Q": {
"x": {
"c0": "0x1130e5125d60ed56c7fa5fb8ce6aad0b462e7a2f7e64ea0ff59e678e101a8ac6d0adb2bb627f58cf009e0f76eeda53c",
"c1": "0xd61707dee74d92539f407b7706cf5d14fbf544e8b0480818195a1208a1bb82cf873379bafa2841648d7e85aefdbf85"
},
"y": {
"c0": "0xfd3a80f699b1023bb24fc51235a5f79dbc44a8e198071da24506bac3a80a41055fac26e597a2b6df5de2546f01dd5b",
"c1": "0x694765aa9c50177980f61c88857d34916028f99fe8609e566aa528faddb42a3f8e1a4a3738cadea893220240bb4f6e"
}
}
},
{
"id": 10,
"P": {
"x": {
"c0": "0x5c925a87641e3d952b90beeaaba87cc51e269ffb9ab9b691d14299757a8681e385c3b7891f77104283828204b486ad",
"c1": "0x6f23c07ef09b6f780ec635b9541961e90d1209fec58af185cdf53c27f0c380414c87fc0ff4244ae64c1888e8665b67"
},
"y": {
"c0": "0x168f033e0a3428d610c03cc56916df5d8d07f1c16256d24194f67ccd571dc82046d030db2bf363428c537648fe28af2",
"c1": "0xff3ee6f352f19a76efed37eac7397af0a51813804087c60c96dbd854986d187a17c006c97950de608c644147dea7e1"
}
},
"scalar": "0x1035e170eabc82625344eecc8044f688a14896a0cdd03130694a81338a510572",
"Q": {
"x": {
"c0": "0x14a6da1e156e24e498954f93a69073c1b9f65841da90a4e1d3537dbc1d9b5e61c079c8b212cf8b038ef9fc472e9eb62",
"c1": "0x5c9e19f5a8cfdb0be7da4123211cf878bcc67ea7f932ea28ec27bdcd6a458b6637194a3c4db0fe33289eb932bc641f"
},
"y": {
"c0": "0x183bfe3a0b2f2afc5c2f104cf37b0ab3a09e1ace1eceef628b61309459032c84855a4040f2a54f0f6429c4756236ed7",
"c1": "0x11aca6bebf614dc4e71d08af011ae40949b9eba8d6109ab2b60f9463282e69ff044e7c29aa5d9f7abe0beb2cc1a1680"
}
}
},
{
"id": 11,
"P": {
"x": {
"c0": "0x1244164a5f8f3defc0a0ad1e9fc03f72077124f768c2de20262eec36ba0628f7efe7974381106a2efcd65c8250a5866",
"c1": "0xdd3402a7e7f3841a7d5051131b702265f73ecaac58b213e7c4cd8d1c1f92362ae0c6637965ccb924d180914e94c0c5"
},
"y": {
"c0": "0x4917cf4f9006b878104dd874b21258d593f480d9263094eecabb9211b713b3b752b1a4508fd5eb04cda3b8e763b21f",
"c1": "0x1442de232535385f9240b06a144b1725ea1f914886b28146a395c8f55450b8b95232bb77b779236b36f5b39e4673daa"
}
},
"scalar": "0xaf4a6e3b968137703bdc46ce87e2b737eeb68ee0dcf75921d80075254ff1649",
"Q": {
"x": {
"c0": "0x17ad23b8d507f27fa0f0be70051b1a39d847cab5de7cd39c8848739baabe99659fabbe7592263cfab82f56ba93e67fe",
"c1": "0x6cc58eb1889530747be902428d294f717a7acc2e18dc1df8e8375e7458dbb1b159f4a8b0c47962609d6c0c75a27f1c"
},
"y": {
"c0": "0x184475146723021f05937113165b23634f13d6b73e687f986a707e1bb373c857fbb99f3ac233bb1cdd8303471956907",
"c1": "0x2a5935370b1dc90edff3fffd8941008bdb6099db6cd31babee780bb099fdc1816096db04e6f5e1f17e2d400cdcde18"
}
}
},
{
"id": 12,
"P": {
"x": {
"c0": "0xcc37be334995fe760f0a1b540765e58c84bf8dcf131ca2d6ada5fc3b49432d236b7480cd0b7307f535614c8aafb0a5",
"c1": "0x17de0b3c177a0b822db70f1a80754af8bb6d7fb768c64357431978456d6c1a7a7dadb441e04c4af64814e4d6f77b7f4"
},
"y": {
"c0": "0x7ecda97a3e06d900e59f1e93ed67cb6bbbab77fdab5fd8ec0d1a10295433302535b120eca2964f05fe22892529ad60",
"c1": "0x4a34c672340864274c42d830b394d114c381c2017cde9749086fa28b8b041cc9c13ab976f5b4f3111532933e6b69f9"
}
},
"scalar": "0xb5363848735700bc821a7a4a2568720b4177ddaee9b4aa27d7ed795a8057d26",
"Q": {
"x": {
"c0": "0xe22e91dac45a49d063401453d8c38359380ac37851e04f2a85b745b7d314f867f575e9cc5c7819697e1f9b31030c5d",
"c1": "0x1832fabc96c8b2e0a64096794f097864b50ff0524450976f62d67979eb83d3e083fd86718f8650c52dc12dc1e28a9ec"
},
"y": {
"c0": "0xec5709b1371d31e3dcd26305dcd48c876b4d4b08ce0333fe384ed1229dee45090bc7993361bb252e7d2801c25148",
"c1": "0xf9f934c35cb568a4faec97593e5624ab539139f05433d66b2d07fad4805dcde66c99e2ea65996bd7976e0586dee3e"
}
}
},
{
"id": 13,
"P": {
"x": {
"c0": "0x10a71421240ac1ced1a41e6eb15d208a5e2fc4ac0d9ac65173f4181ddf286ed1218f44fa0c82d0214d3c22d455fa094",
"c1": "0x7d97fcb89845feddf3328414939570ed33bf6a6b67587f240db01a1b5fafd04503106be54f099207fc6fc59ad8c9be"
},
"y": {
"c0": "0x189a4df6df515e5c6a1be69426ea5dc2122fbc6bebaec7854aeb0b2f242bdbfa18467ed75f0e7f9be02ce603c1f4006",
"c1": "0xa406a43a43e715200daa17fbb721d3408bddad88b6a3a35f00c8bbb36f4203b7eb0348f8e13b83fe2dcc29c27f345e"
}
},
"scalar": "0x1f1e7a7ef63899b369a15639d4acb97ceb17ddf9c95eec36edf5a3ee3c2794c",
"Q": {
"x": {
"c0": "0x906b6ad1994083fe4bff8c41f0f1830228da407fe0a0a21e87b05ccbbdc2f248cd529987b157f7b1658b504468e9ed",
"c1": "0x7e6bc4a23e927405c9769f33633e748bcec420a2b513c2c3067047ce7f4d00f3f50b16430c6dd5ad1fb91a0cc45c15"
},
"y": {
"c0": "0x123e6b15995436e0eca5683afa68e75cb9d0ec13a1db595e126bcd3239f07067994e30cf6b327b5a053d726a65a6049",
"c1": "0x1903d132132b4da635a1f4fb98225ed3714943f819cf2f9f7397e1d2ac0a5a59e9169988eb9222e7fcfecb0b4e3f90d"
}
}
},
{
"id": 14,
"P": {
"x": {
"c0": "0xb2abf49df8d52846503de01e2fd3642d5fa6f44d99cbcfbe836e21277cc76a06fbc01825cc5432657b62f06a21fe59",
"c1": "0x644852eddbc4e3bc608a8d3bd46b7753e5b8dad43f0126e557361cc707a9ce493436cdd8645b7f9db961c870df9d20"
},
"y": {
"c0": "0x4f76bfee6bf5d4ff4dae12dd0c19325b8b19afbb8483e25ed7986895f6fbab95a1e5f11c0447c2376354e106ab5e46",
"c1": "0x19e52b3860d5638b6780e24ef221ac0b2d39599347a4fa6db35d73f9661e433f94e604e911a68edcb9ad03517a1c3b3"
}
},
"scalar": "0x3641ab676f9ec6a285b66cacafd66c6cc21b8fc69f89f57b2202d83248c16cc",
"Q": {
"x": {
"c0": "0x1a02c5deebf03c68b1ceedd94bca11aaba0cb82e35082ffac1234e5e8525d76685cce5bc88db56dfc9bafb9e5aa3555",
"c1": "0x110daaee16f9cca57cb5bba46568ec99e3237784970674e12948aacb6432e34d402afe89b9db0f4d883e5b118d018ed"
},
"y": {
"c0": "0x167504e5dddd4781123c08e6502541ace8110429b2f2b39e582836d454169b279ba46d67efc0a906eedc2d04f964200",
"c1": "0x193e232fa873d27e9a930806d13e490afe0d747ba377c791b3a84e6ec743ee00e4b6a7d72f40338bbc811f79a10eea1"
}
}
},
{
"id": 15,
"P": {
"x": {
"c0": "0xe7bd295545bbef9ece5aa0f2e5eb43062765ce42ad132a859aa1467396c63be2bc86cf22d0e5eed774b875444d35a0",
"c1": "0x4c9ff95578fdead23f6d0896b14318944d930fb196c615a370e7ded37964c04819c18b30429afc2a8f0796718d720d"
},
"y": {
"c0": "0x913724c5548b3c60cf6bc2984ccd2edac60f82f724fd365ce484c6e580dd1896c1e7e54e91b11f9ffed02244c89b1",
"c1": "0x6aefd824386ba94f1e7a9062c4d928484e98db343c79016261019450905cdc711cb9f753d9aa334cee94a13b949528"
}
},
"scalar": "0xccb4caf00a8006d7699836444c0f7fe43a9c147c692af5040ab1092e6846b26",
"Q": {
"x": {
"c0": "0x57cf442d6924452012ae2547ad1f0202ef8f1313fca638bd60253bd72c6e2576d53cdeb9259fcac7b37aee450a8a2e",
"c1": "0xe88155a46cbb77577c5b724104790446afb61dd6c57c8e3e763be7bc77f2d959069de6c410bff19fe15f3da8c2c12c"
},
"y": {
"c0": "0x17639e5274c87dae5c5ad2919eea7cc463f50c0d847773719b7705b4e7435b3018126e11215a329e79ce2646fcaab64",
"c1": "0x13e1fba010e60bbbd4aa917227649009dc590922aeceb40a9bb7bf2fccc1fefbf2f76a5a3afa9220d91f394b8d7105"
}
}
},
{
"id": 16,
"P": {
"x": {
"c0": "0x6f608fa241170ce9617e3c8eaa0fa7e7c8ca8d2c68aa5abf2383ed7400c46363bc0e7e451d7862d5b59aa645fce13a",
"c1": "0x148c43ae9126a6dc20a4ab8e7af4e018e682be7c1f1af3f538e1062b318b055bdd248e5483a28892f4d3c7f007a9cc0"
},
"y": {
"c0": "0x2dff8f0941a7795d6dd59cc802f82ff997d00b06fb71e1878a3e6a233aad83794343ea34ce897707c0a93df58a2b35",
"c1": "0x149d6818eeb5e8cb2a3020ca840e4c207a87c412f1d46fa32805793e87c9e5e063b0755817e9b39dfd5f439cf3c6d81"
}
},
"scalar": "0x10ed1da7d49cb23feb27d74851980098173bc40027996a989025e4a853c0e09a",
"Q": {
"x": {
"c0": "0xc1b50ae415e4a48926b53dd1eb4f34fdf3a6426c44c96435af63eea8f91250b1d6e641c62d9d37d22fa0b8276f20ff",
"c1": "0x5cc26f4283e6db3a1a325c14c780e2959e107378bd20f750295fc76a9127f4b06aab7a69d05ce9183fa627e5cfbfa9"
},
"y": {
"c0": "0xe1f2d318a0dd7655750bb5001adfb3cce713b1abef1d1c4fabfb0927a4ab4aecb64215877cf341f662e998dbbe5d07",
"c1": "0xe35a784ffca836a40547c35433cbd377b37eedd1f7b145ce0cdcf5dbad03c95fa5ea16d143935e81dc11e039867d02"
}
}
},
{
"id": 17,
"P": {
"x": {
"c0": "0xfdfc54b06fde57e8afedcc93177422469cbdc757151088e6ea222d945fd380adcda2bf3e3a45e0a22bb21185e56f28",
"c1": "0x26dabe30add019843135a58713074324bc5558a5328c725ff036970a22f06dd341e6722a2fdf435371cb2f4fc92663"
},
"y": {
"c0": "0x644ad8939ff2aeb3fa06442127c72ff7e9b0790db27cbb09b1eb7a64c1f658184f2ad02000f29a2f81629fc424eaed",
"c1": "0x4a95c629d51786914b92c356e42b02ed6aa464e501c14a330eef7e0315435a3c97e1955accd683a7983cec209c1c01"
}
},
"scalar": "0xbf2c4692995f15a76375f9fec16663181f4bc69a7e7717f7e0cba7903ed35d1",
"Q": {
"x": {
"c0": "0x1a7abaad7db873980f0d163adbd75ddadaa3451da151ce3f0b19683f173f88e56f5941396c735a00d85d0f8fbb0b98b",
"c1": "0x134de4336f8db021374c31a0f87ec13377c1e689e3f045872a76bd5fa7b6f781a92a485657c8ead6ac76330844ae677"
},
"y": {
"c0": "0x931eb8e2778e7f4239cfa66c1d2afdb8f805e887fdbf3702e88f6cfc1094475e2cea10547906b781624e1348c87f06",
"c1": "0x130aec93d33bccbb1a4f59aaed8458d22c32a65a917f7b820f421b3db1f376de23b1a7fd776dc6abe1c6ebec8741606"
}
}
},
{
"id": 18,
"P": {
"x": {
"c0": "0x18f132e12ae26906866ca6503b3a5451a48952c8bf26db09db87b299b8d61a4f2035014f26ecf2fe4e7d1ca2957adef",
"c1": "0xf88ad4acb449d7be127d54e641b8f977877fdbf208e22aaef95c97cea6060c15377b9427f313c783c5b097d2f39f44"
},
"y": {
"c0": "0x149ff9a1383c45501953fcafc24a625a444d16708c89511e3ca7857df7b68039566cf1380378a105bedfebbd1744e2d",
"c1": "0x119696aef90b53f6de3b89478695d7d2f9db89cceb9f6423c47ec728621805f71eb4bc3e0717b2d65dfa0e81515e795"
}
},
"scalar": "0x4999e4d91d15207a38c8481dda0e8e4b26ae60ee93558056535732379831d5a",
"Q": {
"x": {
"c0": "0x5e6d7900f35de1fecf5016582de2eda4e8226d558ed1f6db1fec0adf9af9a41f7df30343e172a3096287fa2eb3112e",
"c1": "0x7f571e4490a27f1f75e26a05989bb3a7bfe218735e5ccee43d62b2e3eb086d071498c7251d9714525efdc18ddf551e"
},
"y": {
"c0": "0x113516643716e41ce2fa57294a582e1266669862f00731bdefdc19232f76a384bcd7c35529098a85e436b2c380b5da1",
"c1": "0x16f5c2b79ed1aba7ac1f87768a909496003b4e7f71dd143705db4f86309f0fd696f5a50be755e0b16364403bfb60905"
}
}
},
{
"id": 19,
"P": {
"x": {
"c0": "0x22704c5733cd79bdc55e01991b9e1d99418f414167ad3af005aa044cf05a26588aadd7294ffbfba8fe239fb451a3f5",
"c1": "0xe97d735001647d3c18eacf3ec9cd4797a1e4bea316441aaf78950e9b0f17483001266a1673b49f0b0bcf54546ab343"
},
"y": {
"c0": "0x174d9f8bf0a6b46531250894120fe49f99c63006205759c66d2d8fa21c8a7d576642dc3eb0a690d59dd4a16eec1e1fd",
"c1": "0x165d4bde299a8484ecfe41654c046264e78c392cf416fbc3dfabe4ff46afc965601e87cd016009aa08d4cec952062e1"
}
},
"scalar": "0x105844111a548723cfb66a5cf2cff88c85dc4a45859806cb444a206505c18cf7",
"Q": {
"x": {
"c0": "0x3e09aca2b56e16806e7e27159364d8ce9ca55e134ea9c5db4ae22071e18b70b5e2f9b0ae4d3cd75ee2bed22a9df440",
"c1": "0x3a9e9b05e96d606059e075b325c3b6e7511167dce00ed957c25f1f9373b29e88d0c064f55687f00771a480291f6e1a"
},
"y": {
"c0": "0x3b8399091c047984b53098f91bdd2cb3db6ddb5a50c593fb6ef8a63f4fa516274c6aec266f3af8ff849ace6601f458",
"c1": "0x3a6c44b93f470e8fb97655c54d42439fcb79837282c3d93b971a177d614761105b4e8c731f0e8741f54c9af8184605"
}
}
},
{
"id": 20,
"P": {
"x": {
"c0": "0x858458eccaf3cc2744baadf9a65cb1076f74e23d6db77748b8135121cbd1b50bd9b0e93b75972bbc02c5eeaab03f0d",
"c1": "0xea70aba9ea3c7095751c519d92af779abc86268339cf6510f05bc2d237108a57075f3d78cfeef91569f1c26e66450a"
},
"y": {
"c0": "0x1369d7d50cef5b2d7d9ffe43a37885f5fde06b01adae590ea24a0143b38fbc98cbeeec4c155605418846a1093f28bea",
"c1": "0x57064bef61ce3774ebaaa41f08ddb4fe5733e5f2d9febd4e10f566ac985af3a1bf527b58dbaa980de17b2eb129d502"
}
},
"scalar": "0xbc1b29b908d58af7778b162f478b8540b1c2c4a50116dcf71c8018da9ee45f",
"Q": {
"x": {
"c0": "0x13c5434587b0c8c6d94b80db3197bfa16a663ac3df0507bccb8d4159b48f94958d177f9c14cff8448c10b102889761b",
"c1": "0x73aaa4a2e9fedfdd8d4520a2d2f05bb21c8148e8f2ee2a655d44b0e8770175384d0c4d36041f459bd0d30a913f1d8d"
},
"y": {
"c0": "0xa0affbb510d377a4217bc26be09a41c64d9e988322aa1ce15a3ef2da887a96d043498c4997b485951d811a373b0cd5",
"c1": "0x4bf3fc89a550ee404edc8e28bc040a29ea9a5bdf7bd69280be40c84d3e56b8632527c3f6b7b697a71e13eb3025ac0a"
}
}
},
{
"id": 21,
"P": {
"x": {
"c0": "0xc49d0c28f46ac15287f429de3b68832d92bf4f376e4b9648f5d6ecb2384cbb27dc5850fd5619698f17249a67dd8163",
"c1": "0xa1ef1253a54107feef0cfb2fe7e80c0b49a986609f7896164d2765908e1d3ee9b5916947fb091fab32b17ae8de6059"
},
"y": {
"c0": "0x137888d28369102b2c60d26501be2d64f695d13e383c579111a9667f165815777da7e6e01143d0e20cb51fe6562923d",
"c1": "0x5b710d6fc7bc4be50b79aed7ce6623e0a2c01a944031e810d3e57f45ca79a981ad095418927d5c9b9ba78c104c3bb1"
}
},
"scalar": "0xc0dac6a14474f135d4380544c19a534cc89b1286ccdab5199646eb19d31572f",
"Q": {
"x": {
"c0": "0xd9a8f830fcdfa1a3815b4e563d87ea640dc2a620fd0582416675dee05a2ef72786d2796a6f10f8fe1c2fc8a8260e9d",
"c1": "0xecb3cc262d237026bc65f58c8c478edd75e001b2cbceb6fa9232982374676281e43d4b158249bda39083a701d3898"
},
"y": {
"c0": "0x19b7e5be0432310c513380958c2e9bff65d97c84f8050174b84c5e6c91c072360d2b57ff7a006a9a35663524e6bab58",
"c1": "0x3812f92449a8aa9e582e2402991e30d87771929854f915ea0e8c2248cf84f7f155a2663c7bb4764341f83d66a087dd"
}
}
},
{
"id": 22,
"P": {
"x": {
"c0": "0x131f20b34e9b7b47a1bf6e0f2c9c7151618de6e1b20a550c81eec0f390b22a6f33cfb37573d0152f513dffe71cc8bd9",
"c1": "0x224d58781e24ce961805f8b8d456e7ccc985546c3ec8e386abf5d194edd0bd435ace80179140f4a0de4bb06bc09148"
},
"y": {
"c0": "0x37d8266a6310bc04999b391889c03411f7c9fbe5c03167af84f55e3257c8a409d5a30aca51eef4b8ce023ba8ba852d",
"c1": "0x2b502b8d45a13b43fe2f4c50076b74df561cc5cff4aa9d1869ccf3680c931ccc62b75c29c9e6cd3f7dbb21ffa1cbd0"
}
},
"scalar": "0x1218eef07685d572f28a59e3cd731fbbaab6ed9a76603bbfdd31c2f6490fbac5",
"Q": {
"x": {
"c0": "0x2a69c6740535b52357a8de04dd3a103897ab34a6b2429d5498a5a6378b1d22b97274b858abdaea30ba7fdc9e8cfc7",
"c1": "0x4fe83c6237c7c9615f4bc08914b17dc9741e4112afb733756a683580119ac8026e952a04283bdd4de3167df9434f56"
},
"y": {
"c0": "0x242babc94952a494c4115ba7d180a0a82e62a7392ba473eacb628d76da72d8ec5b68e81d51f8c188125c3b69f50471",
"c1": "0x186bd028ad6c80a9dd5da881c1540ef20c0918896f280d9659ed28dde73e9b630970d3ac048c7c71a27049230d2bfc3"
}
}
},
{
"id": 23,
"P": {
"x": {
"c0": "0x16195995d3fa6df3444a05cb381e50f1ba3ec1f388861eabc0a2ff962058a6d398b93be701eee4f45c5825a5b67c8f2",
"c1": "0x19f7301bc3d01a8b37787ba323dd656e8fe67faa2d4f31124048036ef5f2ea3c0f7ef08d88221032b41ede3efa830c8"
},
"y": {
"c0": "0x108bad5b2ae54d33c3cae8588c90ce88aa35367d16492565487e21b074c91042e74ea34d19830de314eb89d6f5113fb",
"c1": "0x11d4548c8fc9956a5e567e32b23132407557cab6e67b037455f9ca5b1eb389a9c8d431b3193d05ea89818197bdf47c7"
}
},
"scalar": "0x8fdd885f1c0336e4deba119dc8a81430a00eeccf1028ec5d62aba2a0f81da0",
"Q": {
"x": {
"c0": "0x149ac6589472283f8298bc7d1150958201c19a6bf1afcec8c56d42a0c2638be771fbc7aaaba62766c9589d58fb57702",
"c1": "0x147f4ecae1cddc0afc85cae74c00b70d6dfd0a7bf08bd99b5cfcb14fda1606020cd41230ad70c0acd656fe6550b003b"
},
"y": {
"c0": "0x18c234985931f7c345c0e4d6cad4a2cd8294811d7e2eb44e3e590fef34fa653ca65944e9d2e156f4f4f0646f9f13cab",
"c1": "0x1714381d5e1807285d8c63b08a86c7251386e06adafbee4e99eedaefae850229b1b689faee25961fba0950078a61b8b"
}
}
},
{
"id": 24,
"P": {
"x": {
"c0": "0x45322a5410f20def1c88a5f13cbfafa37d365c1aea9a815d2fcef57d69f73c5b819fbc0bb30850742272e98f10ba4f",
"c1": "0x78e7a75a53ef134ee9daea355aef765f4eb68267a47612b7332935c71b9e1d9dc623a30181e55438af94ebab826eb"
},
"y": {
"c0": "0x12a9b5a1fbb00ba13a6c6ca90b0bdb2aa03ec5fefe86067fa174c8fdb8438742c4dd39c3d999dbacbf214912dfbe707",
"c1": "0x19eab60d45ee9e565336978cf447eef71a9b23ce14813c6db13e46e790eeb8b7154f322914697cc2d2b7bcc78ff3f90"
}
},
"scalar": "0xa55a53a28457b26c0177c97aa827cf439be416b0d453cbb3d2b765870d0d58c",
"Q": {
"x": {
"c0": "0xdf1ca2944dc1775f3436add64fe3a270797e88b0bb9af8e5a3adfa9943f7be4a71c4ec13824b2b7bc775c4413159dc",
"c1": "0x114b9d1713013dcefeeb13cf9bfdf6a744c27bcd26d3958b352a1a10c6d0baa2c41c75a98e2cdf76e292d4f55962d71"
},
"y": {
"c0": "0xa0d8c3cdf944cebbd578222e8e21b4fdb9b30794310bdb2ed1437b1a1123a6dd36d33407bb861744b4f672f3e5448e",
"c1": "0x95c5f29eb848d9c290c8a66a5d2989cdfbc41271a864ec4ee130c72a7c89868a369d75309f7b09bee651b3fef056e1"
}
}
},
{
"id": 25,
"P": {
"x": {
"c0": "0xa5283272ca9c02b0c85050b93f67ce26c59bd2e39c34e03832f849b567a484f2d103f50966317a8ebb04d6e401f449",
"c1": "0x598fe2850421d6d728fefd15fb4101ad9c4cc0a95f4a87b13c6e4dc58c13ac0fd3c10af14b9b9f3577f365394a189"
},
"y": {
"c0": "0xdd79aacf3785da12394b7dc7059cdb9cc45456909d94d03b7b6f5d367b80dfbe4d933149ee1782f35d2fff4448c5f5",
"c1": "0xbb43989a40eba251ff49d01b3643abacb4c8d37803f9445fdc1a416f90525adbdc84b22107b5325672d3020af940e3"
}
},
"scalar": "0xd2e92d55991f61f9161c70b39d76eea16f899c12f4ab9112b88cb24c75efb4f",
"Q": {
"x": {
"c0": "0xd4eab58f163d7946e229a255331cd982159a30916b2f7d7baaeadb9d3e3f1e8237f4523d6511142adab98a367c5ca2",
"c1": "0x8f3cb8266e4ebf5d4bfb2ee6955323c5ae6e9048d03f0933e87431ae363aa25930feee2a0b6a5cda961cc131cdd00d"
},
"y": {
"c0": "0x804e36e6666b675f95e89ac0c62f8c0cc499071fc11edd6ebe2f2c13dcdd670f681349095685e15b9652401835ce86",
"c1": "0x88ed13ad9edc6efef933cd0a1a439018a6bc66308afe3ef1883f7eb3fd67b3ad09a8be6a5f8f710aaffe62e68b2ad9"
}
}
},
{
"id": 26,
"P": {
"x": {
"c0": "0x898a8204658bf436fa0a3a17c7cea54b09e76c0ed378af07ad48360620cab971b6fd7e89d68a97cbfae88d9c87ebb4",
"c1": "0x128a450ff1b8832f739fae1bf7b5237b019e9b0ed8712c37a771abc241a76520353f37b46004f32199452f41753108a"
},
"y": {
"c0": "0xbdb0cc043fddf175ef325077b4f6666f1e42b747df7659ccc02e38e096d1a30600fa0b4d58b997f2aecb7eeac53376",
"c1": "0x6bc602b63a2b6496d70cc213dec1baca237174200da6e9660112781857459f52a878c6948a2cae55db62b9bf4b54d7"
}
},
"scalar": "0xfb5c87cbd2180816ad42acd68041732efc7aab96fcbad8a431854c6862d505",
"Q": {
"x": {
"c0": "0x160553a6b9db8e20d11d72c8ba78fb1c5bc69db52223eb0c0973a8306de7dc80524cbfc4882622dec49d7417011b639",
"c1": "0x12c1fa2d2dbd6fb6933c8cc9132817fe5d7ab991af236d97084ce0400cc7548f807bcbb178fab9232a2a31edff79a1e"
},
"y": {
"c0": "0xf3b17e4e99de5a13c2f3e09d9ebfb83e2e729bcb7f7aa58dfabab4b392a8721653e846a3da01e22d03ad2ada7bbdc3",
"c1": "0xe9c16b279883885ad749141924c01416b4a7f7592aac0126837edf3399f070cdc9c63fa31657acb93c0a2989008a39"
}
}
},
{
"id": 27,
"P": {
"x": {
"c0": "0xc036f8242da3411231fd72c5b43e7aa0360abdf54173b37349713b9270f60992e473406236ea17afb2c45fba7aa920",
"c1": "0xed2d471a476676fc5165ae03c15715d7c060e99280dfd9f8a4e1f633f2d30f4b5ea349aa19edf875442800e6847220"
},
"y": {
"c0": "0x113a53a098a9556de0b6ff3a12804b018fffddcb1d235772582cae6cd78901bf809219d0d2a064f37e2c0b3e732e096",
"c1": "0xaab00d825e3ca629b6da744e514b2c5460f9e7cfc6a679d3e9a80e089aef229a95cdd107397f5e8c8339af158a9491"
}
},
"scalar": "0x720026e328dde137b31fe25a08a00523351abc790f6405dbbdf12ae6e48bd02",
"Q": {
"x": {
"c0": "0x31c46da0ab4f882012c62d82ee908e774401a776428f61a96d1df6f42dd57cc0bbc737d7fdeb16a5d09ed210c06ab5",
"c1": "0x39c0655112a6a6c27b5cc17652953ad9172d2f2efe63d4236a0917d94d30639ccbe8f6693494afd9448ccd043359aa"
},
"y": {
"c0": "0x1c3ea0304681f21096e676e39bc6bfb165c0980d68558582a43a7ac2d410c0abbcc9b0377e391de0db7063f48f09a9",
"c1": "0x24572a92d84136918aa055ae1bdbedb04ac93e87b5e3844a27250155c1efb89e39ba6d39938d22428f734989bbf17b"
}
}
},
{
"id": 28,
"P": {
"x": {
"c0": "0xf4b273fdcb49a862ef354dcbb1ed7726b80c722fc4198dfaa4bfc78b19b0db47e01f6be7280c8ee17593fbd7dce0ec",
"c1": "0x17ffff72cabfd30f965da201fd7c55f6c90fd3a1f281e08b19bc1c4d83f2f8a5b0319463bf004130695ba96e0f51d8f"
},
"y": {
"c0": "0x40a587e455d7dac68b110e9fc4c3277fc448bd1c08a5035bc7b4b033ea6490062b2af81e09a1c5d384afcdbb51ff2d",
"c1": "0xf4a6a31d9d3876a867c6e2bd22d489b678dad51a346ab6b4a2a2ed65d9edb0f1f7cdea976b95ca498957639c25cbc5"
}
},
"scalar": "0xa2beb2ec9c6a0a4a0863a0775440943e72d58436b104e7a016a5fdbfde95a64",
"Q": {
"x": {
"c0": "0x115dea65c51e59da0d6fdf1ff36c00cadd567b83f5892d944282eeea8b09ef1f46d75c23d01de058bd9b3a167389746",
"c1": "0x1bc3b3d7edbb2f9f7f6b88a5b67565758d16b393ed75a9c2c87fe0c95d28e835fc2656b02d8517eb2cf193ab80965d"
},
"y": {
"c0": "0x1731d1c7bf560b1ef27c49598faad508bcc44e971cd94e020b4f31113c38a7ec72df255efa0b5ec87bc0d51d9f1ef5",
"c1": "0x141b469248bd6eb359c8178891d8a9b546aa7b8265cb3b8cfd2cf70ec9ae0161fef218f57c8ffd774db0224aac4d77"
}
}
},
{
"id": 29,
"P": {
"x": {
"c0": "0x93eaa878875e94b2de4500fed40a1076dc79badd0c528fce263f3226c43de4f99f6f90fbafb3f3463b74ad793cf808",
"c1": "0x138fd222739014b9d1e5a8f55391d19d12b19eac981537d6f356cca30becd768a1863ab69497b867981444f855b1cab"
},
"y": {
"c0": "0xbe91fa324d2995eb9f672a1fb845285f0e311c5623c09dcfa32790a71b00a9299b2103143b762a3a84122b84185744",
"c1": "0x93387cc145b8b7a6abb30153efded1578e4d4962d5283cbfe3cfbced42f11813a8788b7edc2db91b3bd0f4c60578f2"
}
},
"scalar": "0x9b50c131e8e2ad4a030798ead36ba13763f032711f3a2afbc3e33ecdaf931e8",
"Q": {
"x": {
"c0": "0x4c99853606ce6de18fa65fe830cb2a030615ed7784e63afce8b4323c10cc925c15da0376f69e66479b6368040073c1",
"c1": "0x3b7160cb5e2648f1b3442391d6d23d8bb13d0f851af6b41cd5b16ad788837b6694287e32687316fdc27722bd01f9d"
},
"y": {
"c0": "0x11ca43dcdfdb881955a24613d3b7880c7f9bfd0a4ac9b6ba3bc4e5e0ab187a1fe54f113aabfea3f842bd75ef4a8cb9d",
"c1": "0xdb1b3b5b85a92cf3e18415e8beafdb204cedcdad7a252488c9db56084e93df4414fa5b646b367583e3fe9e35d065af"
}
}
},
{
"id": 30,
"P": {
"x": {
"c0": "0x94e366d0fc20f0a470ddfde406ae10253e3da38415a968e29f71c5ccff31c0bb1371fca2007f128391da5adc4f5022",
"c1": "0x11d4f79d1cbb677f9264dc50fba1b2719b094f042aa1c7e9febd0a9b6ab605e5cc488c184cde6678db1b8ff3243527d"
},
"y": {
"c0": "0x11787e9a28453e9e09dc1479969c8487d5a49b5e24b98055b1ce07b6308c59597db814c9854673afea19b97e98541ea",
"c1": "0x7a139cbd1c8005779f7256e7805645490292a97ce45ec569b6c2f26b208d0a74cf9774bc2e3baa57b7b42e40bce1f4"
}
},
"scalar": "0x1143005cdf9d1b37bc0bb53fdf5ce0228463be0bddbb6884e25f3c97d66fc7e5",
"Q": {
"x": {
"c0": "0x1470a98d661ebde1bb4905a6958b372a46d81aa27d6b58625f111363a1737ab84c965a91bd889478d30b5e27875fc93",
"c1": "0x8919ad9f313b0e9309ec3d0606a1ba05bc9ba342912055a9519aba6bbc74c4edf07de0a04381953005b5ebbafe3c33"
},
"y": {
"c0": "0x3727290d066a268152e5190619c635307fd24afdb794d8c83c6cbf829b9297cbf5663ba52e5e8b463f3b212814a33e",
"c1": "0xff8f79c1b17a524e9e47677b8e97dd4e975ca679f81384bf2b02797bc1fbbb4bb9f6f565587f70603f6b81316a69fd"
}
}
},
{
"id": 31,
"P": {
"x": {
"c0": "0x1ad2f019f4eb8d90e5391972ae7b74a0a68bf05f0e4bd1455109c425552a6b1b19d190ac8022a52e422c29cea1f9d0a",
"c1": "0x1934b448e48cb8d4d0a231dd6af70f6b2eb1eef2f213949bb1cc24c49686b82995beae6eca4975f1d8f99d2bf884938"
},
"y": {
"c0": "0x144ed2ffccf3129906161b11f16b4fa6fc2f0f2edbaea479b00077b1194b031938f7a8117c109f125579528685b0403",
"c1": "0x1410f0a7cecec2a88a963a73a8a59137994c1217b74e96009ba72c3e317715b140279bc152b30804d0cf94162db21a7"
}
},
"scalar": "0xc42af7872353d25fd1229a2633752e9f978d91333962e72839885e074141b19",
"Q": {
"x": {
"c0": "0x6dd888d3390af853671b812c76f0aaa7270e34ad5a8d23be16845c050145ec7f46881dc4f9cb0f5bddecbc3840197a",
"c1": "0x6b5d2605c186a45ca3fb2cf396d20204f7aba89ad20bcf4e67cff33642a6c2a2e98976acdf326c47c99fa61ea9063a"
},
"y": {
"c0": "0x161b454a017d373456aaa1932f8e99a365f6944872a3dc128965ba0118be3a28607c723efa8f8d3fb4d224bdf92b069",
"c1": "0x1a1e58461f437d9059c4e9bfb8b85dad778fd64304045c185d55ae51f2c83586c25b53e4af579a1a32e65361537ed59"
}
}
},
{
"id": 32,
"P": {
"x": {
"c0": "0x13f05516fd186a5ae2f852338841bbd661b968fc4ac77854beba76634a97def0f82c7660f2ffda499252150d264be1",
"c1": "0xaa9e4b3e552ddffb43a527a702ddd55323a3f92a281346536ed093ae1558366a7ea1369f125ccfd873cb02c4d9b34b"
},
"y": {
"c0": "0x14864e67cb6ef84a5f7d629a7db8edc5e556f452dcb5b111d3435a4c2a99aadd99965140c8dd42d2e862aaa4bdc7549",
"c1": "0xe698e4cdce08821d80b22ec87cfc80ea35f834cf3edcec500349eefadbabd56c15992384845129048aa7786f4cb2ec"
}
},
"scalar": "0xbf056c447086a6ca7506f41e9158d7d9d50cef1ccb1ed9374228d5b61ad2a6",
"Q": {
"x": {
"c0": "0xfc70ee0a7a115c2e88e05815365b6d0a51f4bbe80b20cf2fcafccce048f07722d01921bbc0613f161db6e464c8e1b5",
"c1": "0x10d6ebc8ce772415071d7a1ec1c5437f928fac46e1fd4f748df660ca7677051260d92c4be53cb8bfda85bca1f6e6921"
},
"y": {
"c0": "0x88fa8482ab11fb4c46cc9b2c3767ce744281cb4c6336b9fc2948f70e1016c647898d1ca83e36ef9cbfea4c1a9fbe2b",
"c1": "0xbf75d064eaaaf90e351a65d5473b5e847b29f275d1b10a329c7f3f2ca9bc44f6149d96ed4b58b8b659ba8aec18e99b"
}
}
},
{
"id": 33,
"P": {
"x": {
"c0": "0x16da79bdc8c5d6b71f72b9eb265db24dbf3b89e8d7a9075437635309cb1adfdee02c04e2a163f570e1b6c95bfd207f8",
"c1": "0x480d326cff2f34582ab127df7e1843bdf36c8b6efeb3d2c9bc84b40978a676669d0c430c1bc7b17107814d3d8125aa"
},
"y": {
"c0": "0x17e9eb26ee528dbe4cf228fd355d1336a4215447a6aa71c75685f9e911e33bf6568206f4b0cd8cb827a084a16c3e422",
"c1": "0xdb70f348a48533f0900676f8f2e953abf0e0e5e8d21855acc96b3cf1bd38a4164a293e971110fa8ac8114edf81a305"
}
},
"scalar": "0x621d93d5779b355bd32e3c381cfd371f26ec534825175cf544611a1eeea615e",
"Q": {
"x": {
"c0": "0x9788a6669995b7dadb3dc979b8d3974fcfd371b42072a5aadbcbe2140b8a683fe44c6e730bc9fe1617b579d4d65cf3",
"c1": "0x1ab4e3e46e5da1ffb8a9018979de248b967240b29b368f5c62f3bc3b364af4c381d3d99b1979c6035ea5c983c95afd0"
},
"y": {
"c0": "0x13ca9bed1c1e0fdc74da853f0e3a7b10face1e53e266fd1c71de5f56aeb8769fb7eaf2fb065bef14406b5179a322a83",
"c1": "0x19bf8845b2b5630d5e804a97680913e8de2022cecbe91165444d2e053f8ac4255c24441c77ee2c2cfc98d88c8c8bdce"
}
}
},
{
"id": 34,
"P": {
"x": {
"c0": "0x11c9029fe5c3ae63fb8e07b6262b68bf82f6492db780714a8b8e21157eb76c008afad9ae6508c92adc35d72f01888ae",
"c1": "0x896e9c5ed9e5817cdb6dfa573d78fd0006013a0338dc00d289cc32e0bf675878281bb3bbbf1fa0790db084aa5f1b83"
},
"y": {
"c0": "0xec42ea9bf6b8a350ae808f7e634c2efe06383f1df1d9fcea03fd1da1e23be5f0987f32966cdeef7303146f1e136804",
"c1": "0xf3d3da0994c29577d4e00e86817bc5c7a463e5b0cc5e58d9dc548dc422203ef02f8950a2d262ff997bc6808828a36b"
}
},
"scalar": "0x9064434b3910f87a67ef765d5333e2e307a6776d9c2780d7752b316d4da125a",
"Q": {
"x": {
"c0": "0x6a4e785b3fda539535e586ce3ddb6f62d120fd6b12b6f014498961ccc311487b4f154e47ff3325ed287928254bfe2d",
"c1": "0xa461c5d7b96652b8904596d74faaa4ed6cb16413b7bfd05a728e15997d981cac541ca1aeab12de4319991b7e47286a"
},
"y": {
"c0": "0x1535d22ebf336fab0d259576b1efe9520a794cf9024fb77f8f27aa8fc9323891b0ce083978ac83cbfd7163da8160c2f",
"c1": "0x954744c54f83b68debd27e4a755aa1f9b3fae55baab51a6d6f54c5bc8f95cdfc31acf82d421b24b281228f53dc015e"
}
}
},
{
"id": 35,
"P": {
"x": {
"c0": "0x176267909f058d12649ba4afe56fafaf68f34a3fa5994542ea70709b7738c32b2593d26210637f942adf3ea2e418be3",
"c1": "0x60491bdd436d4c99988d50dd560fd19b1a34b0ea9e147e871f7091fda215474b69fab52d9b056b52214405826c9c82"
},
"y": {
"c0": "0x14d245e8ea7ac2ab6f4d44186d16f67bfc6474a0cd8f51abc3def643bf9e7fc3f1f5d80e8b04cc45b62dc575c28cdd9",
"c1": "0x116a3262a72bf6eb4cb32bd04feb6a0296a6f662f09c7bbf24e58f79ee31581be30f228e81ba57dd51d4ef0c8efadb0"
}
},
"scalar": "0x6280f3ecb9f7f79bf2a6d315c34bb3608f56c1aa01964e972acf12cb35abdd6",
"Q": {
"x": {
"c0": "0x1b8b54dea47242176a5f47b995ba3dc60f909c546ad16f8bd9133d07ad84ec72b8eb374db952911f51b254240e5b63",
"c1": "0xcdcd62d86c37480d68c3047ead4213bba8a188af3779b347a210d74c99275001ee2b076699bfdbdbe144e694b84ed8"
},
"y": {
"c0": "0x1344811f93140816b51469d1b8696e38fadd59e9944c7a2d141b4eb39cef46702a02e75b7881b1ba629e532cc021ffd",
"c1": "0x812eca972f75b78ac16c6a8cbbaa18653e2f3f7668676f551e3d1abef86b61fd6e61087f64b4d779c1ff43a705242e"
}
}
},
{
"id": 36,
"P": {
"x": {
"c0": "0x44f352ea449aa7dcea59cc61b411a85fd1f995054e7cbc7df97c05e05548ee69ff850f32aef0f72952303b2c22dabf",
"c1": "0x196bc6d9b644e966247793ea8354d334324273c0e62fc7942798c2ce166375addb1646a5ed9256eb4bf8b1ca0aa92cb"
},
"y": {
"c0": "0xcca161cb416cf6e9466d7a65b891dc180d721b12945adb6c1fcd662dac9ce482812fef535ef974973df868386a58d8",
"c1": "0x1236f018a642959dfc4f329760f019f4346e8f8dbfaa925618700b7024defb063e15b371dab7059acb63d43bbc2bf85"
}
},
"scalar": "0xf09c5e72bb8913046cad795ac55cfa7b46c4dfc05e470ef894465c5970f9246",
"Q": {
"x": {
"c0": "0x7bf1f0784a13479b936c6359046786aeca7775e296d019cdf49065eddad006ce19cd0d39614dbe139654c973e71ceb",
"c1": "0xa4cf62c6a50e64d02efc9f7a52b1f64f676eb7a1e29cec9ddf83f81f7faddbf94057daf6108c8e46b3fcbc5ba6ac19"
},
"y": {
"c0": "0x158f71f85131dd6f6f5aa91a8a1fdd9799e6c650bc87fbf8243e58e273977603a3b5d3be4600adf8a4345de7565b07e",
"c1": "0xa1c42c21ac8752fd8e3e2bc07470b02da271e1ef2bfb02c36123f7099b808e6171eb2800e06b8603cd4198a60fc46f"
}
}
},
{
"id": 37,
"P": {
"x": {
"c0": "0x14f5bd30bb95bab6b9a752f0f9c9fcafc86b06bf7240add8bbc2354eddb33e28ea0f1ad327e3b2a85fc86631118da6",
"c1": "0xf191c26234256e48ef9174330678e50a6e0ad476575449fa13e098a4c61473e10e9973939f0c3636bc17ca8b5a593c"
},
"y": {
"c0": "0xa8de1bbbefc8591c3316244296648f48572a5ea8b103c8030f66e22e3848f1b824c0e38346c2300fc827855ff190a8",
"c1": "0xb39d2ec295d93aea0a48992ac72cd5c81ba5540f10f6b57eb5c1e59d9a29c2feb5db44b6e61c88a65786699424b222"
}
},
"scalar": "0x9cd0f09b5db13eb48361d970b68d09c44ff7965907a98c1643a1e677bb6ed60",
"Q": {
"x": {
"c0": "0x5d0e82cde933f0212c9a91eaa0ce9f31d74e1958d43e6da75af65e217ab5f38e3fc12d9fdc9eb729fa16fa99edee7f",
"c1": "0x47a3c04c57e65179bb50c6a968eb632ce182d4ad53f186891fcd970e5ce37a690150b9850f58ed24886b87ba94fd28"
},
"y": {
"c0": "0x14fcedd02743ce2c6b202fed786cd9a8b55948381ce2824f58e654b170042becf2b05d9893d12f7104b3e0a46ef39aa",
"c1": "0x12108d9797208e6801643a4b51c7f96f3ec8e203bf3d874a39cdfe176cd317fd502c934b586282b2ac4dd9e498a7af3"
}
}
},
{
"id": 38,
"P": {
"x": {
"c0": "0xfdfa9e9fc0726c4282c44fa06b8a99e66806ecc2ae2720ac1f03281b6509d3d15494ffbd9ad1543f36235e976d1787",
"c1": "0x592dda63e5893af508e9e03575863587a09f8bc5ae0d845cd2a2b0b76f3c8b3b857678409681000e0be4dd7b60feea"
},
"y": {
"c0": "0xfcfd77868055616738bdc11eb6b257ba9eb5fcdf684b05980a794cbd85803ab7104aefa01418dc736361c3a72a4eea",
"c1": "0x571d18711d78e84d144cc3da5fb6bbfb6adb7208b850e191c7b5ed5c042d0a49973d91585af5f6711ca57d19730ce5"
}
},
"scalar": "0xce136dc2be3c35bcd981d687e8fe25b36c9a1ac7d5609d7577a28f3b267462d",
"Q": {
"x": {
"c0": "0x12f271fd41bbf9b507c75f49f70cad08fc1f1dbf2acfb4b640e21db346cd0bab5353c5ca482aa2e88cba7d33860c522",
"c1": "0xca30f865d7e42cb9ff369039e838235d31103e0d3b0a315d75e790c2c71884d6893a513d1e43aeeabe0b016f13f874"
},
"y": {
"c0": "0x584384151e3b28bb8825559723420cd19b0e484d8f298a2b13a0c8bc9cfa7d41e5945d8ca9636e274f26b0a3a655dc",
"c1": "0x17651475ba4d197bdeb944d40410b5241b5fbf66c48ea7e3df968e6b6939729ddea6f0a021826e79690f5b17ab17ce7"
}
}
},
{
"id": 39,
"P": {
"x": {
"c0": "0x9c9e178a59d8c9ff54f63190f414da5ec65de71d2041b42678da93d23dfd48987ac613ca4492bffe06f4198deec327",
"c1": "0x3e8e7595fb51f50b0388cea288cd59e67852698c860ef473476818b397a4bfd7229a0da112313ee8b8873dd017576c"
},
"y": {
"c0": "0x5466fff70c66511c81496c85d8ef41d7a169223efb876234437d2fd2b97821f856d11f698c35c5f3ff7ff6699b0404",
"c1": "0x1adb162f90e8219f4db0a2499282347ff1fa9b7339e22862b2e22ec8bcf7b3e1939619a0c0e5f6f695a673cec675cd7"
}
},
"scalar": "0x1c211ba91d40d2a8e3028962cca5a3c8dee44ce9b9a45735f6cbd825ee1b795",
"Q": {
"x": {
"c0": "0x60fe67936d1e1d500be3cd58d9dc2d6715f25d035923e11a2c5b80928b08c38fe078324c2b4bbbcaa8bcd9d955f59a",
"c1": "0x154ac68e98e02c327133554c035037e3285552a5accb56f1e9f49aba8a39429f22ce5cd8b6972a9ff4f414af5360396"
},
"y": {
"c0": "0x16891031259a458410777529b113f027d4d4ea8d45a328f9d0be289ef84e7951c0eefcbbb64490f23c8df4d83a22a51",
"c1": "0x3a91aba231acf430b004f077296b612d7140a2a2bb9f8100392d6ae254e43be36162851f70fecb6875a26b068e1509"
}
}
}
]
}

View File

@ -0,0 +1,492 @@
{
"curve": "BLS12_381",
"group": "G1",
"modulus": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab",
"order": "0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001",
"cofactor": "0x396c8c005555e1568c00aaab0000aaab",
"form": "short_weierstrass",
"a": "0x0",
"b": "0x4",
"vectors": [
{
"id": 0,
"P": {
"x": "0xf9679bb02ee7f352fff6a6467a5e563ec8dd38c86a48abd9e8f7f241f1cdd29d54bc3ddea3a33b62e0d7ce22f3d244a",
"y": "0x50189b992cf856846b30e52205ff9ef72dc081e9680726586231cbc29a81a162120082585f401e00382d5c86fb1083f"
},
"scalar": "0xf7e60a832eb77ac47374bc93251360d6c81c21add62767ff816caf11a20d8db",
"Q": {
"x": "0xc344f3bcc86df380186311fa502b7943a436a629380f8ee1960515522eedc58fe67ddd47615487668bcf12842c524d8",
"y": "0x189e0c154f2631ad26e24ca73d84fb60a21d385fe205df04cf9f2f6fc0c3aa72afe9fbea71a930fa71d9bbfddb2fa571"
}
},
{
"id": 1,
"P": {
"x": "0x17d71835ff84f150fabf5c77ac90bf7f6249143abd1f5d8a46a76f243d424d82e1e258fc7983ba8af97a2462adebe090",
"y": "0xd3e108ee1332067cbe4f4193eae10381acb69f493b40e53d9dee59506b49c6564c9056494a7f987982eb4069512c1c6"
},
"scalar": "0x5f10367bdae7aa872d90b5ac209321ce5a15181ce22848d032a8d452055cbfd0",
"Q": {
"x": "0x21073bee733a07b15d83afcd4e6ee11b01e6137fd5ad4589c5045e12d79a9a9490a3ebc59f30633a60fc3635a3c1e51",
"y": "0xeb7a97a9d3dfff1667b8fa559bdcdf37c7767e6afb8ca93ad9dd44feb93761e10aa2c4c1a79728a21cd4a6f705398b5"
}
},
{
"id": 2,
"P": {
"x": "0xf92c9572692e8f3d450483a7a9bb4694e3b54c9cd09441a4dd7f579b0a6984e47f8090c31c172b33d87f3de186d6b58",
"y": "0x286ede4cb2ae19ead4932d5550c5d3ec8ce3a3ada5e1ed6d202e93dd1b16d3513f0f9b62adc6323f18e272a426ee955"
},
"scalar": "0x4c321d72220c098fc0fd52306de98f8be9446bf854cf1e4d8dbae62375d18faf",
"Q": {
"x": "0x4bb385e937582ae32aa7ba89632fcef2eace3f7b57309d979cf35298a430de9ef4d9ac5ba2335c1a4b6e7e5c38d0036",
"y": "0x1801154d3a7b0daea772345b7f72a4c88c9677743f267da63490dad4dece2ecc9ec02d4d4d063086ee5d356aa2db914e"
}
},
{
"id": 3,
"P": {
"x": "0xec23ff3435b8ebd5e8e0a879d432e11eb974161664b1341fd28f1ffc4c228bf6ada2ae4a565f18c9b66f67a7573502d",
"y": "0x10c4b647be08db0b49b75320ae891f9f9c5d7bb7c798947e800d681d205d1b24b12e4dfa993d1bd16851b00356627cc1"
},
"scalar": "0x1738857afb76c55f615c2a20b44ca90dcb3267d804ec23fddea431dbee4eb37f",
"Q": {
"x": "0xdc7ae7801152918ee3c13590407b4242a80d0b855a0bf585d3dc30719601d2d5d9e01e99ae735003ecb7c20ef48265",
"y": "0x142c01a6aa390426a4ce2f36df43f86442732c35d4e05e5b67f3623832944f0ea5a29138624cb939330652a3cfb282b5"
}
},
{
"id": 4,
"P": {
"x": "0xdf127083c2a5ef2388b02af913c0e4002a52a82db9e5ecbf23ee4f557d3b61c91ebcfe9d4973070b46bc5ea6897bca1",
"y": "0x318960aeea262ec23ffdd42ec1ba72ae6fa2186a1e2a0fc2659073fb7b5adfb50d581a4d998a94d1accf78b1b3a0163"
},
"scalar": "0x19c47811813444020c999a2b263940b5054cf45bb8ad8e086ff126bfcd5507e1",
"Q": {
"x": "0x5f93c42fd76a29063efa2ee92607e0b3ae7edc4e419b3914661e5162d6beaeb96a34d2007ff817bc102651f61dca8d1",
"y": "0x18dde8666bb1d0a379719d7d1b1512de809b70e49d9553303274ea872e56f7f39da551d6bcb7c57ae88ec7dc1fb354a4"
}
},
{
"id": 5,
"P": {
"x": "0x101123de23c0f240c583c2368c4118dc942db219c55f58cf54acd500c1fcfa06f651ad75319ebf840cbdb6bddea7fde4",
"y": "0x5268587d4b844b0708e0336d1bbf48da185aaf5b948eccc3b565d00a856dd55882b9bb31c52af0e275b168cb35eb7b0"
},
"scalar": "0x43ffcda71e45a3e90b7502d92b30a0b06c54c95a91aa21e0438677b1c2714ecb",
"Q": {
"x": "0xf9871b682c1c76c7f4f0a7ca57ad876c10dc108b65b76987264873278d9f54db95101c173aed06d07062efc7d47ca0c",
"y": "0x20d9628d611e72a4251a1f2357d4f53e68e4915383b6a0d126273d216b1a8c5e2cb7b2688ad702ef1682f4c5228fcd9"
}
},
{
"id": 6,
"P": {
"x": "0x1457ba1bae6eb3afae3261941c65c93e3ae7d784907d15b8d559100da5e13fd29e4a4d6e3103b781a95237b7b2d80a8e",
"y": "0x6a869a47cb48d01e7d29660932afd7617720262b55de5f430b8aa3d74f9fd2b9d3a07ce192425da58014764fc9532cd"
},
"scalar": "0x64ad0d6c36dba5368e71f0010aebf860288f54611e5aaf18082bae7a404ebfd8",
"Q": {
"x": "0x93e540e26190e161038d985d40f2ab897cbc2346be7d8f2b201a689b59d4020a8740e252606f2f79ba0e121ccc9976d",
"y": "0x10568d68f1b993aa1eded3869eda14e509f1cb4d8553bdf97feee175467cea4c0c1316fdb4e5a68440ad04b96b2d3bfc"
}
},
{
"id": 7,
"P": {
"x": "0x2615f843e8fe68d4c337bcf83b2cf13cbae638edd0740f1eac520dc2146afa3b8d36c540878c1d207ef913634b1e593",
"y": "0x1787d6eeeceb6e7793073f0bbe7bae522529c126b650c43d5d41e732c581a57df1bfb818061b7b4e6c9145da5df2c43e"
},
"scalar": "0xb0ac3d0e685583075aa46c03a00859dfbec24ccb36e2cae3806d82275adcc03",
"Q": {
"x": "0xd95ed29c2e15fd2205d83a71478341d6022deb93af4d49f704437678a72ce141d2f6043aa0e34e26f60d17e16b97053",
"y": "0xb37cbded112c84116b74ff311b10d148f3e203cb88d4a011b096c74cd2bfdb27255727de4aa8299ae10b32d661d48a7"
}
},
{
"id": 8,
"P": {
"x": "0x10bc0c4e1ed87246a9d4d7d38546369f275a245f6e1d3b882e8c9a7f05bc6ee8ff97a96a54084c2bef15ed8bfefb1465",
"y": "0x1782377e5f588576b5ab42fea224e88873dda957202f0c6d72ce8728c2d58dc654be77226fbda385d5f269354e4a176a"
},
"scalar": "0x23941bb3c3659423d6fdafb7cff52e0e02de0ac91e64c537c6203d64905b63d0",
"Q": {
"x": "0x83f1e7e8bd963c1ccd837dae7bc9336531aaf0aee717537a9a7e2712e220f74cdb73a99f331c0eb6b377be3dafc211f",
"y": "0xcd87773d072b1305dfc85c2983aecae2ab316e5e8f31306c32d58d6ce2e431b12685d18c58b6a35ad2113c5b689eeb"
}
},
{
"id": 9,
"P": {
"x": "0xbe4f9f721d98a761a5562bd80ea06f369e9cbb7d33bbb2f0191d4b77d0fd2a10c4083b54157b525f36c522ca3a6ca09",
"y": "0x166c315ecdd20acb3c5efcc7e038b17d0b37a06ffbf77873f15fc0cd091a1e4102a8b8bf5507919453759e744391b04d"
},
"scalar": "0x4203156dcf70582ea8cbd0388104f47fd5a18ae336b2fed8458e1e4e74d7baf5",
"Q": {
"x": "0xc72bc7087cd22993b7f6d2e49026abfde678a384073ed373b95df722b1ab658eb5ae42211e5528af606e38b59511bc6",
"y": "0x96d80593b42fe44e64793e490b1257af0aa26b36773aac93c3686fdb14975917cf60a1a19e32623218d0722dbb88a85"
}
},
{
"id": 10,
"P": {
"x": "0x5c0d5fcd2ff364b5a73bacde4abbf7fe98a1dd4e4abed78fa96244f13c1003cc0e28ebd59d2de32d8d7a5c999e1cb82",
"y": "0x62615902a6feb46093cc77f7c9c7c4f75193f5d211e72deda9d827f3cf3334fcbd3093c66ed431fadb45dc21dbd7fee"
},
"scalar": "0x318c79935f61fafa8cce97b2d3b058a35b9620d76ffaff0aacb5d62e3dcb16ac",
"Q": {
"x": "0x3b5d47b85d3663a6698d2ea3fe9ea989fbf10e43dc8aa443455c6dc75581631023f2c7d279d02f334989cd5eb001fe",
"y": "0xf615863774b6d9595b2fbdd2f71b6e4c43225c737055b0e3fefbbfc0be3270f72f706226d34425a54739678f71f66d3"
}
},
{
"id": 11,
"P": {
"x": "0x146ae9eaeae0a00bd71795be6e2526e0cdd235a7a09c8de701aa96b5aa7814317ba7d90250fa407d470e629a91ce77d",
"y": "0x1bdbd86c06bb81076e4027d4cc532ed190db4e19fa4ce86e7859fd979d988a4e983e2d5321ee9d7b61e3f826b39ec48"
},
"scalar": "0x5c8a95d81b523543afd65c805a389980ba5695456f1256c81a51ff49dc6be772",
"Q": {
"x": "0x1f1c7a2d0c4c04a4371dc9d07ee996460b52536892449e7a2e0a798da7f31ee0ae8ce1c4bca4d55777ecf17ceda697a",
"y": "0xf9c3a65806703fa9b8e79884bea2a2b204e415225423d07c6b1a747722b6430a5a023211f7e711b07ca11885cb5cb48"
}
},
{
"id": 12,
"P": {
"x": "0x12d9ac1c4b4342bb601efa9505776936b6a4d8289fa9cc8186e74a59af4b0d9c46a29ebf1dcef8098ec90794a9ea6958",
"y": "0x13b00f64c1193d63f547bd09290178f4b9f6f954855133e8966511d3affbb7e0c7241fa273da690b1a7b95d83e7fc665"
},
"scalar": "0x45c34dc8528310a95e69fc0c24d27993530ad70672db2a4d1faaf0e0b7a418f5",
"Q": {
"x": "0x859b304ef906eb070370941471d0249922f627d465ba4766e38a6dc62bf3ff63710c4736c085daf79dfe8f90025ef8c",
"y": "0x6d12aba0f059e7f0bd336b793364f268e429f42100332101177237d4643e7c1793d685717abb65ab22a2706fa9b9c91"
}
},
{
"id": 13,
"P": {
"x": "0x99372e61aec8df9a76b4258de660f05bd48c8318500c95ce7f4641e629a7d62c079a9a33e63fb2515e3694a24931e9b",
"y": "0xf27fd12ad4f6d025b55c3c4e3125f8ccbdafe19c0d266259aad94acd5b378119915a3910fd8a0c6b16a7c4999e683df"
},
"scalar": "0x60d95fa08b3cae31b7ed148e02dcd60107d9670df5b9f69ecb7fb6066bc96bb8",
"Q": {
"x": "0xf401672d1446064175bcab3db95df157da4a0039510529f7207dc338db548d6015827b811f67f9d9dbbccd6d16d18f1",
"y": "0x12eb5d1089dfe2c2a279db3ffed10ec8ec792c75ddeac5f6f788b18369fc35bd4ced95e3e154b9d4fd153d82137fd9f3"
}
},
{
"id": 14,
"P": {
"x": "0x56d0418931fbce9fb682b6f03cec8397136df53ffdb3c6d3e0501b6c5561179e06c02cd067f335fbe96a51a6e7dbecc",
"y": "0x217ad0d71c2bc2ffb23f52c4a6d7ceca769d60af7bfddff32c19f375b7cb441b6b690ad65f6c33c559719abd7160b17"
},
"scalar": "0x5d7173feea4ebba2fc41fadc5ddcba3a3cee7f6e3ec71fdd7d7f9145b9b70552",
"Q": {
"x": "0xaedbc4bb487e906e83746be51b2aa85840a73cd5ed36d08308ce3e05b77042e777ea2d57ea5a91b17a4d8c6af86095a",
"y": "0xe08e3f9775f1342b5b9eb2000f788b8bf02f03b5107c3ed792444436b03ad802d48852761c23352923bf49d925670ed"
}
},
{
"id": 15,
"P": {
"x": "0x149241d1c702e57cdfd91ae5a8786775a5488be08ff594a66819ff97eb35f7206b6a7431f9baf4f03d28604fa7920728",
"y": "0x80a165919ee7a889f5b54199976e86b62d0e8560802b68f0addee680f4fded5d7af53dadeaa517d4912a87806721936"
},
"scalar": "0x3638a1f09b542c9c14706bddf9bd411747489f3d398a5c286d28f3a950e33406",
"Q": {
"x": "0x16bd4093541e6e1dcb9dc8beb1516d44936777d60a622a19728e5ef8a62aa0a591783af82c3e0acdae2bf2b4191990c9",
"y": "0xba0a2f00b2dd2dca59fa4ec5b2da0f5f419920e94aaf48f683bed5bff1be21feb0c471ffa1cebf6c104ea51398162a"
}
},
{
"id": 16,
"P": {
"x": "0x7b1064b140ba94fec9cc0d39c366e5ed1ad94119b55c5276ad6401964bc3d0b6ddcf3beacdc3c22d6c21f20e44b4235",
"y": "0x5e88ccfe4e4940c9d976516c1718fb5e06e1db70090d9d943b8b7c5e83da8860e827a42101281b7825e8d97f10fa78e"
},
"scalar": "0x43e30b2b76ccf39f50a354204aabe0daa56da8fe08f90834486477294136523e",
"Q": {
"x": "0x65c6c95b5a263ee620be43c100f63ae9958bb011466bd0fa3246c050d369219126146e588ca5cf7b2d0276572ba5d20",
"y": "0x1987e02727efd46be9b3c2894806dbee44e8164becde71ea12abc4ba39171871b7f8ba527f0c4161040467cf12d7a76"
}
},
{
"id": 17,
"P": {
"x": "0x11a781f450bd0a92e10ffa3295ffc6cd21fc0342445ac385955653d1459857256bee38163939d03d546b9ecc99c0f68a",
"y": "0x11ab37cffd53718d515b971d7b758eff175918827f5596f309a9cfff841559ada81736581b592c3d84285d92bfd32dd2"
},
"scalar": "0x566abd28ece240d97585e5bf871bba98e2eb57415b359f129c0c3f54f72900b6",
"Q": {
"x": "0x37e9c94e86733e8f96b803f6250bd568c5443ad8b8fbf16d58a9e0df254a60b5eaaa85f5f493b8cf36ed75b61a0d4f6",
"y": "0xfb84c376d83be11cd1ff66bbe393a24c1b49faf445ac7efc47db99eef78259e87043557e85e3adf0b9d409b40990cb1"
}
},
{
"id": 18,
"P": {
"x": "0x97ede383a40480da68d425b08ab0085d537c3369a63262401968713554cfc66a22026fc16c6f07e546527b7022587f1",
"y": "0x146d0c345100bc217a35af37fe2d5113f951b1ee916b3fae34a17c2a9fb7f6fbc3d48da392b1fe99e7f2fa272cfbcc3a"
},
"scalar": "0x5cbb76c17df070ab2bea372815ac6277062b27569ad68343fd4ec3d4dafdf6a",
"Q": {
"x": "0xab189cd52d8a56804bf89b4cfce5bb883496661b2b1efc815391fe9c7c47542ac5ebf83269afc2be4dfac65f9e42703",
"y": "0x1356ef010c7e56af391223a09e126534c15a6c9dfd9915fe66fd1e70213a5d8544ce81fa2840d4da68fa51f498c185be"
}
},
{
"id": 19,
"P": {
"x": "0x1762cb2e92c80fe3309c51976d0989b530eb45bf6ba345d728f1737bbf3991a3e0d1686ddbd28979c20e6047bfa66fa6",
"y": "0x2108436b0d1409211fe12b2b1921aaf12d1784aa20e1137eefa4a5586e935bbd4e22e4c639e7efa58e7c7d38d47dd2"
},
"scalar": "0x3ed99fcfdb3f7b2e4655fe0c1da4993ff8faadf3b0a6960e052a92551d54e979",
"Q": {
"x": "0x435ec5230b3cf7ea43c4770e836c2287b4e399838efe2f699350b200da3501d332e4850d724f2ed214c10ebd44c701e",
"y": "0x1842e9526cbede65523d51a22f24062a38677296ea96f8267a2858c3792655f9651643361d38610873c347edb22a0e67"
}
},
{
"id": 20,
"P": {
"x": "0x175a91d65b8a73b1202f96489dd7ea2ba3c90c88d3bf1ac32fcb38bbdf57613d755a2a0431ee0344fbf3438e779db973",
"y": "0x17e74f122a4a0aa2a48a4c9f7eaed6b5232eac6a059630ba783caaf9cd0d2bd1b828307f8b85753e24080c5d20c59a49"
},
"scalar": "0x16e12f89ad592c1a73f4c23a9968584c200f386ef8ccaa504da72b1d649c067f",
"Q": {
"x": "0xa1770b84c906b50205d23016233490583837d2d5032ba9dcbbb1f8db41588cd9ddb034111724d6029ef411e627305eb",
"y": "0xd39f07bcb6c33f9c7f607a97e7d8f92b3bc128dccb0b4efe1e9922f386966914ae0b2b2befecad31f81f69a01096dff"
}
},
{
"id": 21,
"P": {
"x": "0x16f8de5ba05c41620d915eed03e7169d2c2e2662db70387cd72ff92a9b59203b81d77bd666d1b16515378c37d2679116",
"y": "0xc84c6fb110e2c9c1aa872103e8f19d9c2ddcfd7ab569d1400ba31f4ee1343426e2a66a9000e64f8959cee4ce866e20c"
},
"scalar": "0x206a80f9bb17e5c1999589b36027cf083b6303189f00a8f966647a29b6c6e158",
"Q": {
"x": "0x10fcedf23fe5691957b148d1d0506b83fafefa001d8cd5261a1cfe1d01db4ddf358160bc8f590698be8262022eb98b06",
"y": "0x14f4575fb460364c6defafd27e09f69f98dc32889148270543065580059152ce62b9817e37beff303cb64670efd23485"
}
},
{
"id": 22,
"P": {
"x": "0x1692476e5e45776beefd3ed27efc0bd4483c604b3ba2341b3f213c3affe238362777ec262645ec1cc10ee70daee2d249",
"y": "0x172e0eed5e2fd3b47a3cdb4a252a4ced49210338e8995c4f7b4e975f3aed8a015f59c98a62201d07fbf77589903cc1c7"
},
"scalar": "0x4fbc38ab04a94842ce30838a5c18f7f9834b9103c755c800861d377c55b22ae4",
"Q": {
"x": "0x1564f4eccad61eeb966acf1897653988ffb2589d51e4df3b9b57443f73b4872efda447133b49591861c69429cd80113d",
"y": "0x19b932289baea59eb6941613c0cebd72eade1bdb68689925ff26c5d6d6140b57e673eb3e13b82bd3e3b0da26397f3273"
}
},
{
"id": 23,
"P": {
"x": "0x12dcdd85a8dbef6329adf4d2697af5549bdd8bd8d8887967736de5eccbff23341d8ef4ef59993893cf10d37a4174b5d0",
"y": "0x1500833024089b79f247a7ed9b27f2d76090535c0236e77fa6e732e68323160a45df7985b5d7f4893faf817e2ee6f83a"
},
"scalar": "0x56da818f793c06ed98941d025d5e17a6d80bbc42b7f49003e4c0dfdf3f0dabb3",
"Q": {
"x": "0x12b06a230a3066c4c0e0559706cdcd6824c36ae0cad5c6d4ee8a8051327caa0a44b9fc63de72ebd98631d10a59024d99",
"y": "0x7be26dfb09324f208c3d52630609c4699685fd0957bc5a69f9b8a15a3e9a97c80fbe16b8b7a1266fde31ec8db99adc8"
}
},
{
"id": 24,
"P": {
"x": "0x8cc360c2e5da78a2b23db62ed8858d888fbc60ee9782ba0ba9b658a4af1715e6916b70884c3fbd6352ea07e843c197",
"y": "0x98cd6c1099c0e6a3ee74aebd5206072fa5723645c17f94cb614e0a3a11cb839b4fd774462f9bfb9e6969c1151f765c5"
},
"scalar": "0x6083671fcc66dc084ad73eba100830555fcfcc5eccaa6acb27cda0d3fa8d6f64",
"Q": {
"x": "0xd5c1d32be6da76e1e7ab4f9e20115da3feba4edc1b7937069046e76a08fbfdb863a6e801d59f4cdccb0f55c23526dd3",
"y": "0x4d3e5554dec9dce799bc3f3ae6868fda40b672881dbedc9062a2965990060d576cc1dcc16fcf8aa94c1975d0929316f"
}
},
{
"id": 25,
"P": {
"x": "0x15c42746387dc681935e941acd95eaf10eeb1aed84a2dfef33443b3d2936cf4936fe788b5306ecc5b317b7aea16cc740",
"y": "0xa2ed64ecbcf9911319a9527b7b1c824404a0d39df3b636be5a383d9a174595c7b6512ea30aba97aa4a9e43b55034f25"
},
"scalar": "0x3facf17aee449fd486412257a8275ad7d711adafaaed588e9734aeb0bbc79bd",
"Q": {
"x": "0x572b9821aa82fdd8df5304170ddbb7e7cf84b992dca76b7271671427771f778c8af895fec84fd7ca0e32ea6128c2d52",
"y": "0x125e7b8b2bba47301bee246f647105e0c1420a3cabc6e879721eb8c02072ed7adcb17903434126111019133aa41d828f"
}
},
{
"id": 26,
"P": {
"x": "0x194d9fb9724d20018b4bb04703314c4d13253e2299571ec4a25b2a186ceb68d2333652517d48239eb9eaefe73fbb76c6",
"y": "0x3e5f1a463c10ef52426f0f405e7f4e01e12014918f4462a8abbc3f755bc0e9cb907f7511282be1aab3fb9e8b5accddd"
},
"scalar": "0x64a377a5acd3f4b2db5252c67101ade845d2cb346eb7fcafc810f0e7a47f6ec1",
"Q": {
"x": "0xed3e051329d494c325c3085a7b9c31ab13f12129ccf654165c93d267866afc7d7ed5702e78af1ed56fd15b564657e3a",
"y": "0xe5b5fb8ae200b813efc35365091db27b5418c08b0cffd872a88f204495f30680b26b5f30711acee6950c0ead4148b3b"
}
},
{
"id": 27,
"P": {
"x": "0x101802892f2045592e97744817c76508cc9403e0cf121e3e933a7fa9924961e9b97427bbcbcc2c8b6c00524b42b23d4f",
"y": "0x136d1c3034e6e8d96cbbea77652194aa81e239f0cc1aa8efa5f05b81dd2135a5ac3a3fd9b8190e1ca752cc67318243ee"
},
"scalar": "0x24718924ee16ef94d0b905575982419a7cf31d125775e7ede5c0ab4f86defd33",
"Q": {
"x": "0x5655300f7c0529e910c03a3998ddd9f143db103348fdcc588d4ab28c82fb57dc1a52755b966bab6f18e9b3341f87b95",
"y": "0x2b8e2f16502c2c367c4509f23aaa853714628cf7068625d39cd57401eb3e1935711c89719a9f21097d178aef5376bfb"
}
},
{
"id": 28,
"P": {
"x": "0xa77a5edd27d0afdd2fd80309306bf6049373bc8dce8abc9781f95136410d99cab0175eb99496c9401371bc309343aed",
"y": "0x132c9bd87f12274ab9bd27d774f725524ac8ff0d86730f83140b8934b475d2bd938643d0b31324710ac0a40d00546739"
},
"scalar": "0x3b19e00f0644b0fa53abe392b3fd7777b8d3ccc2ccc418e8b0b8134c534a4933",
"Q": {
"x": "0x8db80b53344589cb5fd89c1a5bb52228144aed731493ee367219250a76c659776b56785f72d558464ea8bddfa9cde35",
"y": "0x1855239898f5a2746c029c190e66cf0d9934319bdd9f586d41254b75ad6d24929e537eb22330f35f6d75ae35b0bac61d"
}
},
{
"id": 29,
"P": {
"x": "0x437eeb155cff94f5bf1306ac8c2f300094cefbec895af1c2fe1d098269e3a557ec59691fd738f062e23e40fe050c9e8",
"y": "0x2ce40f0e5e793939b896415d1e199f187fc577484be4af6615f16376fac5c09116c037206c39c36d7002612adbb94e5"
},
"scalar": "0x2d89c587f7e36c5728ec2aacfd11d45e1a01a594f4e6000307db63bc09513460",
"Q": {
"x": "0x154048f38964d45cea0f0b5c2c84898287530e7bcf94e8c878d464fdba652c3b539487617abae4cd9a5513f89f67435",
"y": "0x1282e20b43e9fd5428448a8f7c1664308941dee268fc219b869d091e3931baaacb471288e841f0d770812b2c22e23acc"
}
},
{
"id": 30,
"P": {
"x": "0xe36b6e98ccac03518303dd49635beba1a2c9cacc0b6490df11098cdec0b5199a6f954d831da1cb7ae2ca0fbe24ce8cc",
"y": "0x20d8203ca0ed08a783e3639d24b5dcbca7a65e25a88d4c831be21f073aa80a1451ca95dcc61dae0f754280a40d0ef9c"
},
"scalar": "0x128262a47acbadead3c6d90ab1ab94fdd4a69370f816313ff8a20649df5be028",
"Q": {
"x": "0x102fb51fc5ae72abced7dc1250a69d46105a980ba6d573511dbc9f5ca81ea7441afe87690157cb5100f831509d964b54",
"y": "0xb50480d6c446d1b186b44fa18ce4950ecee0be4cb08f02b50fe7a5ff6f2545139be67c597b2f173c25b9b6aa262b96e"
}
},
{
"id": 31,
"P": {
"x": "0x529b559005eae27f192a56e4f934607821556c234ecdcd85e01e9340420aedcbb7de5c98d2086f287fa2e1cbfa9a2c0",
"y": "0x1744e3070a3862c8ff67ad8b53b21e06281146c7ffadbab75959827f35e395c8cc52fead55322c553edeebe9134fac3f"
},
"scalar": "0x418c8f7dceddd870ce5200263c9787401bb0fb339a1bdcc64347d5aa0cf98e4c",
"Q": {
"x": "0x14ac8564f2d61fda2b4ee5c73e66a9beaa4be413f9bdab7d7a2d3a9cde250d419f2ac849d44962f53ca3bfb9f425d7f",
"y": "0x9ef98f577079fff0bdf9c3a1fec08930f1efd326d8f1eb1cc068c2d3826e0118a6dc2c1ebfd6cb09d3e523d813a33f1"
}
},
{
"id": 32,
"P": {
"x": "0xea554e37dc92836928eb689ef6a32026a169e425d6dac13a7cf22eb669389cfddaedcbd6ea6aef9fc39b3e3a403c7ed",
"y": "0x6e63f4df492b91bc043f307701fade6fc525ff3306b4439646d537557e6dcb7ea86b4d02c35ddfa28121ad543eb5e76"
},
"scalar": "0x575635311121c25969a513404d05bea2edb9df6083f45c0c4874e21a0ed10e8c",
"Q": {
"x": "0x1806367828979a1716ac776b85e9d9e815c34a62516070c5f841f0ba95069074900fcc15a51ae087ff059699cb25b4af",
"y": "0x82500fcfa348578353f567dcd131beb29f546cb75a519f8971b904923bdd70b01ab2ee6ab2d5f1afe7530f833a0f080"
}
},
{
"id": 33,
"P": {
"x": "0x5b468d26269e6c8f942e44a6b144202e8f33653993da91e8c50844ce25f6320c68c0690a0764c879cc39d18fe61d777",
"y": "0x6a583e5fe9c277ae52f88dce00c691d167c168dada34aa6f02e2a45299fedfbaae7228ef0d4f5a8b76bbc1942b5a8ed"
},
"scalar": "0x54b423e240f26a02b972c1d322176baccbcaa65ecefbaabcfa13706e40984a1a",
"Q": {
"x": "0xead9341c4ace405f1a5c789fa04ca565e23629348526ddf389b1beb8d931162a36df93e87906df33a0df2af8733d821",
"y": "0x103bcba5fb05a4f180c000496935cf8dd88689d5a47036ef0b7cad5ccb68576d3f24362efea5da90794a1c3d2154361a"
}
},
{
"id": 34,
"P": {
"x": "0x17a352e7334b566b1546347e1c95f987e24236db45adf6f95fd1d2ebaa4ba800ec1366f47d25e388eee73504987cbaf1",
"y": "0x1511973d183cafa684a3ec66eb524fe0123899a26230c79a415434444c730839b00f28cc908ea3a0100c0a5539a43017"
},
"scalar": "0x2a589ba60b120613810a740f39319e0596e52015b5e08eda138167f7f8e547a2",
"Q": {
"x": "0x65aff59bde2bf5883c3b376f7ec390c5f909e214e491f0d7c8af9f49c88e16a7504b4a464b873ed7b8b744e944f4eaa",
"y": "0x3c2e649ef9cb3ee71c673889186fa8712c7e7880f557954a989965344d7d416c5b5890a951024ea4a221179c105d888"
}
},
{
"id": 35,
"P": {
"x": "0xe2480df90e263c686cd8591a3faa258a79b5acc2df7f667b83ac7d7f3d6a8cf0676f785dc9413cd655f0e32b922de69",
"y": "0x1667ad1beb3c0976012ea7e6228b9b8ad158b8802b261030f0f2faae5c197730fbd18c4f5de6e9ef3d0f11a63c05c963"
},
"scalar": "0xaf8fbd81cfc0434f536b7dd7226dc8b9e0dfa5e26ec56be4c68be3b91a7e483",
"Q": {
"x": "0x1d601c7fb050e0c6377ce434dcfad5609901da50593823e28ca9165afc195c2f995e90ca7fe9720e11ec67ea379536a",
"y": "0x71c620e73affccc44bbc86ea1e7dd071b8a86d4bdb7ff0f4af91e0a1da3bbd5b3b6d4527907883e9c99fd910c2997e8"
}
},
{
"id": 36,
"P": {
"x": "0x11206eae189e6f6c425ccd156c44a9bf47dfe7aec2662e80ad6f7b3887ec9557093cfe9d194c650f679bbd27c6b38a0e",
"y": "0xa31c646e1a04d62d85bd9c9e67c23c97154aaa42ac545c93f53a95bb09d71f656824103c1785a17fd99c5bdcabe7b1c"
},
"scalar": "0x92b375cd653958352643dec812c75bee17f729b0cf1936df8c60669711d8ee",
"Q": {
"x": "0xf01101650961413ca5e63867765e30a3ba2f1883083c79f4245043f432737c5d580ec44175474331c624ca73d471ea4",
"y": "0x171ce109b63e64931d08a0eb65b94cf49bcc5a859af1f57332eb709b6ca9457a6d22582c1958e32312676b80e1c0f797"
}
},
{
"id": 37,
"P": {
"x": "0x13043b145f1609d166491f437dc3e6a5bb8f1bd996b1fea2ad45466e8762e32005434c2e07b41e6fc3a7e8c3d3349259",
"y": "0xcb6157d54ef3a35381613d37f0e78aab7b62432e2963d39a5b3b77ff90410bc90ad0130078b52af8a75d544da1ead4f"
},
"scalar": "0x261f80993a9b2b3b7d7140604b529cd424519b8d0b79c49635709fd11ca9b660",
"Q": {
"x": "0x3b114854b55b3eb759b7eebdcf57fc1954563b0f89f78fe6f3e89544a30b1c48eeefb904783e6fca7a4bfe01150c850",
"y": "0x13baa76024343d26341ed43b5e4abfc4a9c6b1aedc64cddc107e5ea0ad4dbc23284e9353d2ba7e6d22a3e36e4853bc79"
}
},
{
"id": 38,
"P": {
"x": "0x176f190ce4ae35c59df395f4b7328290e306b6f89e7e9416fe288b8edcc4559f545e113685dcc34bc0cd97f2d8142858",
"y": "0x101342fb41568dd0e55e0e2818c56e3057f2b819ec0d47aa02b7a92fff7602fee261fcdc8c5aa4a0c7aca6cd7df38fbd"
},
"scalar": "0x3c8dd3f490354c7df1b09099dcd7e5b9373dc6fb1724894f8707335afdb11f58",
"Q": {
"x": "0x17a5fac1d13235f455cc0c9390dfa82c9d8b0acd7059088a6fbffb86c3db2f495889c2b08257f13b999ec3846ddeb4c",
"y": "0x9b15683b1f17c399e22ffd77c60d8eda4a624679c61b14c9f77b89174415fd858402744728dd2925180833f00a939aa"
}
},
{
"id": 39,
"P": {
"x": "0x19d3b65c45e920c23127feaee64a9d6e14cc8c87a676f0ac2661cf5d1aed6091b1f0257ecd217e3974bdea3bcfab41fa",
"y": "0x505126ef8e6c93e51d74775831fa8d21786303e688e6d9bd75a2e1a63daa15f36dcbf2a8c2c6ea023d9e743c9d49064"
},
"scalar": "0x7321fe3d7514d44c3782d62712b677b23620978242df9a8800115372ea9a85ae",
"Q": {
"x": "0x394a9521bdc89e2dfbba7c334174daa9721ad433705000aae9ebf53caf607e263eb4ad0a905ac106184e10ac6caadee",
"y": "0x100a2615b974ce14ca4964a4f853f95ebd0db0d9072fff7818cab3909d2de2e36a5b181ad796cb16fbd212b37185c173"
}
}
]
}

View File

@ -0,0 +1,980 @@
{
"curve": "BLS12_381",
"group": "G2",
"modulus": "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab",
"order": "0x73eda753299d7d483339d80809a1d80553bda402fffe5bfeffffffff00000001",
"cofactor": "0x5d543a95414e7f1091d50792876a202cd91de4547085abaa68a205b2e5a7ddfa628f1cb4d9e82ef21537e293a6691ae1616ec6e786f0c70cf1c38e31c7238e5",
"form": "short_weierstrass",
"twist_degree": 6,
"twist": "M_Twist",
"non_residue_fp": -1,
"G2_field": "Fp2",
"non_residue_twist": [
1,
1
],
"a": "0x0",
"b": "0x4",
"vectors": [
{
"id": 0,
"P": {
"x": {
"c0": "0x9ec4d4d15b8634a7a2b220486ad93735e96420b6d59596f767628f91b32b8a2a10789c0b9a7d2c919741374866166bc",
"c1": "0x12297bf829cabe2ba92e6699328a14c604ab14327748c6943ead5eb163df03578187d26f61a8aa67a9a31a690b3a8f58"
},
"y": {
"c0": "0x1408cc29c231f4378b7221eb2422e8c1ff34b7bfeaa6751453ffef5580326c73bb40b340ac059186ee70e500675533fb",
"c1": "0x12564f85a81cccfdf565f3d55da3edbce5bd7a8aea7c26f1eceb36f656804642d4eb1018da9e3984fdd0c8145824b1b4"
}
},
"scalar": "0x67af10bf777554ae7c1deff5ddb5bcbb581fc9f13728a439bcc260173b46567d",
"Q": {
"x": {
"c0": "0x147c36710aeacee7285054520ea54164587c197449b6af0c770629aac0c4f22766c904fa60b69b632e519175dac07add",
"c1": "0x179c358508d6b5c67ef585a0fe744932774f6ec5f6bac7ac94883c2af9b7579ebff594a96986eb84584e5547a568f3c8"
},
"y": {
"c0": "0x84ee8c1d0502b06c8f3bc6c79fae2cccdbf5659764f4e2f2edfd8d68e3a8b130156e24dabd559951c35fd9f8058a493",
"c1": "0x88781ef6d8379724333eb69f22d7290e401287069426e5da2153c19ddd2af6d4a44c5e7a127abc9f61bc19d8f208f81"
}
}
},
{
"id": 1,
"P": {
"x": {
"c0": "0x38bd6ee09da742880206dc132be4641d7ed91ad8ee6714e7a22ab52ff3cc7dc606c35a06abf62ff5187ae5ca311d941",
"c1": "0x52d6c875865a9aa2b2f0d99d757a9f954cbb4f1ad4d7d3de7068666cd9ea3c5988003827b61c5b0e53589745ac5ebc2"
},
"y": {
"c0": "0xd779cd8eb5f8d3a3b3a3bb61032e1b4cd69f960fcbf196c04e659c6eeea0b78396966418f88f2e37b30931e0e789d8c",
"c1": "0xb9490dfa408a4d93838b330d6fbffdd1852bf50ad8b2898fa230e474a0124126ff4224ae14622090bd47299fd4e381f"
}
},
"scalar": "0x5bd0ae1fa4f8f69aee37bf282d4aac82b7bd1fd47139250b9c708997a7ff8f60",
"Q": {
"x": {
"c0": "0xe4b4271b366ab9bec8b42362814cdbeeff401e98fef15d01d147c9d2ff2ff9e8ab2bcbc429c492102b83bb27372634f",
"c1": "0x772da4a376bf436467ef530fc9b21d424c0248f6b29ef65a4ba8bb0d2702454124622c1d5e847399e6674ff6c64c91b"
},
"y": {
"c0": "0xb8dea81a39ccde8ef2571275d4095bf4d29442f32f9eadaa43fcbcec62e495bfa707c7cd550fc3d62bfaab8facbf2c6",
"c1": "0xa2f6195b784c63e76520aaf0b1493e1ca44bd7f69b2517606bc5fb8ef4a31a035736185bae5d144e4cab40ef166eb7a"
}
}
},
{
"id": 2,
"P": {
"x": {
"c0": "0xacc4063b6e6a4f30793b94559b8f9b05a0c67a357252d2f7998959982e4c0ee52d17fd98693bff7c079d65b909d5d62",
"c1": "0x18f09c87642727f40085bdf953529b7f9cfcff8c3787237cdbbfede67a0d62d0c1f32e019814560d9690100df3e26ca7"
},
"y": {
"c0": "0x13a2d593a5fb7cfc9f8ec4debd039cba1ab675ac8709ef067fa0ea82537c54e753483bfa5580153e0ac4c6e94eeafa28",
"c1": "0x8df3ec34f2f8abc711a9d7a8c7cedd2d4b4c80a51259a075334bb8433cef1c67f53d9bcf02100cacf8d7b3cf8a91048"
}
},
"scalar": "0x8696393aee14d9e140cba05be79b5cb0441816d9e8c837015be0bfe46d979da",
"Q": {
"x": {
"c0": "0x1fc8e0bcf6d65ff5c9651d5717ed0416396b75870d50789d150b1dbe4931d1c75d22ed2a3aed045c17adc7acab4b618",
"c1": "0x17f7441aedaebbe537de1f291f24f657cf470dc3041824d2eb0bdfffc6736c9d51d9aaa3792d55341cc5d718a7f6943e"
},
"y": {
"c0": "0xfcd1bf0b1bd40ce61dfd5632ba1e48bb6a828adb254c90ffffe14a6b351a2ac288b30dbe8adcb67c82f50cc3d0c001b",
"c1": "0x3fc38bd9b64db8e19d14145e318b5a63fe58af882730442c75b99901b9a8a91aa11914016a4160bd7edbc74e055be22"
}
}
},
{
"id": 3,
"P": {
"x": {
"c0": "0xb95829b0c3d45fac57ef4f374a079dda6f3ca6650ea0f4caa32128b5fc4a40f4b34d9fe0b60ca9325be958a27cedac2",
"c1": "0xef8d6fc29bb7e5137666209540c8ea44625c3eb0d01bb3c8ec5f813656e07bdb2a6dc9ddce8cf138f680b78f3e23ba"
},
"y": {
"c0": "0x16675e4e82c97439354847b4a7e5b240273e93a2d1218da7e4a244f7ec0ea9b851cf917fadd240e83ae22de8644a97b",
"c1": "0x3d794b7a32fb59e440c06314a498c74bc4c1f9aa3bd1ce0af5c781b904d84def189f625b9586db24b26a156f6dc4ed5"
}
},
"scalar": "0x67a0dd93e812f226efd6a05d2cf72c5f9b4255d87a93003857b7ec88b162b346",
"Q": {
"x": {
"c0": "0x40b6261449fce1096b5e0dfa6945a80b38eb840c0369f53b76023d547c5c6ce7e1f7c3d7a143dde4dd2b6c939ebd012",
"c1": "0x64c0d74190d9bd5c3ef6eaa5cc3d1935b29e81ce4767d329d82457403b3cedda07a8e71175a129c89878e835f9d7733"
},
"y": {
"c0": "0xf84c130d2a363c10588b0b2ecd399b93d5c80b0ad4f7d1514f9fd5c95f8cd4b874496269de1e02200fd93b6bd7903d4",
"c1": "0x1814bcf895b0d054d11ed73553571124178318df87b52b0f5f406fc31b831a3afcc16fb6aa330bca6c0557ec85084303"
}
}
},
{
"id": 4,
"P": {
"x": {
"c0": "0x11a39133cba3dc32878c32dff1bf057fe56026d526adc4df3de336c82748334e20506e67f44133fb0b6de42dfec4cedc",
"c1": "0x79823c1c197f08674f24b13facc8de9e4e276dfcb415179a0bf823960a1af60169087e07cc69e08d41120e3bbe8ab"
},
"y": {
"c0": "0x706ae86ab988aa6ad85b8c33651612367de7f353dba197209e8d0bb3eb92079dffb10d25fb866eaf57c63984b2f5bfb",
"c1": "0xc6ef16520aed784366513ac11c75eadfae420d2e70ce86df361ac1b24639abeee4db924de14d0f33bc0802f69812559"
}
},
"scalar": "0x6bb8fbfa6f0de8ce868ea90f92f8a220bc96baa1f841b2f0e7e26228f36c95a7",
"Q": {
"x": {
"c0": "0x120cb9055eb5af37dbe7acea2437c53404007508925ca926d1fdf3474593a0491c575fc691c3d0cafb8ad2e053252150",
"c1": "0x105a33ea615b314e039f3f7c2254269db33ef5f30addea2b4e30e1765afc02407e2327a859a594ad68f5ca06f9d82b3f"
},
"y": {
"c0": "0xe125b391e14ab3664dabed9017563804186366a958369381ae99cde577ea68e2cc1fb1b3d4a42ab4d5b1418400185b4",
"c1": "0xa4061b9b8c84ac60d56ef74a87f0d6caefce1dbd8b7eb67a46dfc859924824c6437847c41ea42af3cc49bbc461ebede"
}
}
},
{
"id": 5,
"P": {
"x": {
"c0": "0x3de9608707a6cafa119c0280cd625d3ea70ec54b1206226dd110ade9197beade6f3e7fb635eee8fda560a0453778718",
"c1": "0x112e3bc71f6ba9c8574d18c05e3e1c5a3228f8541cb18dc70162b3d8d2d7051d6df74a0825148fda5ec5b692751d6677"
},
"y": {
"c0": "0x120ddcc9a437e3daa1237b099112c17fad7827cef60b54579e6389f2a0325d03d5812a271a4795386e2f9cb15a48622b",
"c1": "0x7136c511539308f08ea8fcd8e1954e6dce0c27d6df21ddfb095c6d1b116cb3e346b964a08c404687807826ba9729f42"
}
},
"scalar": "0x4d1b14e769e71f6d5191f014663829442d5c73208af481fe8cab65e7ec0cb8f1",
"Q": {
"x": {
"c0": "0x795101fa1276ad3850ecdb367d18484ef844b2ecd95339c3ac8be7dcce30bde950e27d275cc1a8ebbffae81a3985baa",
"c1": "0xb8741b1242a432067e4078a1c7150f77a693d270ea5fa45e8d9b5b80107672fff989afbcac11456a0506f98137e197"
},
"y": {
"c0": "0x14b2c2c2656504adc2742b84d8e38406120f78a4e2442af034c00f328ef7566d2b3cc834ba7b74541dc5b1a582dce501",
"c1": "0x8e50d116038a0b24faab45108b1d3bd02cff9aec148020160a0f7215d139e17520582ecc9c0c9f057f256947ecbd49c"
}
}
},
{
"id": 6,
"P": {
"x": {
"c0": "0x5a75f88c2dfe4101e0845a264d8320c051193cea63bd1bf58a3d9d9f242ab32c92fc295a42a179ec690ccc6b03a48f8",
"c1": "0x16af4e80cc712f658475fd38937c9991f2e396c5bd74da8c9ab6a9272ce73a4cb927ecbc8f8ab8d55b96a1860dcd1991"
},
"y": {
"c0": "0x116d63bc3c93e768a4021257c20c6e960d65f32ecdcef1cdb5e26fbb9759cf6e01056193f45d0c67916aba023888577a",
"c1": "0x49c2cd8134846c3a499a3aa8565f9ade0d87c333c10154a7f19e4269c0df6bf5b4bbe6005f0d7a887675b4217d7a361"
}
},
"scalar": "0x414257650bf812497f4af2ae88e39832ac95f809682ecb0dc7316acc536a4160",
"Q": {
"x": {
"c0": "0xa0e52e121ff2d20366ef8fcb72484186acda66da64de094458c47cc003457593790f6c771f4b7e70f358d9564724a66",
"c1": "0xbcb3b531ab6db5269db9ad63c11d8258bfda3e60977365f119cdd1ea1e5cca9e1a6b7a263e5464b58dba3097c6e57bb"
},
"y": {
"c0": "0x2d862d1bd039ca33f5e1882a73642208bd3bcaf76cc36440e80e08320d1be2c7d462ea3be452aaeba96cc166739970c",
"c1": "0x159b498e06a872aee69eda9867f78d0b72799ca27073ebf2b290cb99c81d453131eaf9cd66ac1ed55d4e5856ef270070"
}
}
},
{
"id": 7,
"P": {
"x": {
"c0": "0x119e9f7b7e32907fd2cc57c576f7bc5898149badd3410495b2f83ac5539acf9ad683144fc9295cab995c355904d700e5",
"c1": "0x1227d6dfe24729ea6665fc021d2109708134743f1bbbaf33cf1602ea35b5ac1ec486f523792640e928bde69ff543920b"
},
"y": {
"c0": "0x624db6f87a5b752498095ce80e52fcf490b388ce590cedb02ab6447c478e2ad6904028ca2d2181861badd0d6a6fabeb",
"c1": "0x69a57a5a752f9687cb143b39cbee5783caa9b6ba7c39920235bd5cf1796108f132765afe4492a647fc11bc23d82bf66"
}
},
"scalar": "0x501bbc748811a7774bfd4b558c5b3266c3f1b4049d2f658c34609654d5b60680",
"Q": {
"x": {
"c0": "0x19e591f883d822fdcc74c43ec72f8ad3c00151160284a0c97edc68ea1c07ef01db5b821633374bbd322e2476a8432ffd",
"c1": "0x12080d2556b3568e46fb0e0b3cf20a216d631120663ad747baf3d5b4e497df787020749a490b02dd329a820926b89ba1"
},
"y": {
"c0": "0x12127db1dd1db4d3ad2c43fd8787be6e9446b46406ffee0053bb775c2c50ca6c68c08174e9096a06a390dd9d62d48db8",
"c1": "0x1167a8ff1db9245e4caf6bd5ce069797587d9467176bc82308229eb7222575fc9e9bcc6341b1a39e910e938517dc3794"
}
}
},
{
"id": 8,
"P": {
"x": {
"c0": "0x15b3c0c5b7cf346c42cd33a0f3d2fa0b783fbb9671e3920884af7da192ed3c12f29626d4c73158e556a01ecd9e024d42",
"c1": "0x11ae718c2d9c5dad5ea273c511f78e5c668b47df6299236aa2b1667fe12a2b93db89469646c64d94199d3804bb45a643"
},
"y": {
"c0": "0xd20337cc4fc891068fc8ca5888ae1da059c290b9bc8c8c4893dd49e5ea866ebedab9f1e832c63d9570e0d822fb10024",
"c1": "0xb85e3d98306130d06006f08e6ac3776d19c6891622998fcdd66b5beca101ca66a90a73982f267f1d1c6e628a403ba39"
}
},
"scalar": "0x542e906bee5237b0a55850e3bf7812ba6627ec8b762b174d91a297cd258f5fc8",
"Q": {
"x": {
"c0": "0x17621f23f9b5fee086deceb3fa85d182f0d2daeba977b2fb6d207e04f86890d99b86e457f15917fc19e4ca6cac1ba8d7",
"c1": "0x14d6dc5ed2757da944237455e4669f4003d6e254b49de198181bbcf69627e169316182ab0f135d2f71e09c1247ac7f07"
},
"y": {
"c0": "0x1699066e7fbbfba67f695530c669511fa4f14fcca5d817b8c52be0d5748230f9f579e3ddbdff85c73fb65a9f625ccc17",
"c1": "0x2db8382b1ff53f17a1f806c27cd839c9dca269ed7e8feba0bfaac68f34ea0d447541e3e17437221d52999f633aa358f"
}
}
},
{
"id": 9,
"P": {
"x": {
"c0": "0x1855ef3f5b131b2c7d1e5531d80b088506848858f2e6d3b152a7425a06b133cb44fe90397c37d5c2a708390186bdc2d8",
"c1": "0x148d95cd78ed474494887968bb8f41e982a6d5c44acfbc3c656aae42af437b58ea069dd01971539e40507deacf18212"
},
"y": {
"c0": "0xe2f02f7d38a40043c9a66f326c3072f6aba5c4101b03aa86ee021ff20747ff20526f68238b69d58164fd6f809b09fe2",
"c1": "0xb5d8f0617c9502a87f449be88b06be34932e1e6e8436a5b0cf1ea66aaf58f173c15aaf197bcbafeb28b1985b713a656"
}
},
"scalar": "0x166bec9ad4389bf7a8c0cea573380eac05f2ec5609c22a9cf5b40e34635a4cdc",
"Q": {
"x": {
"c0": "0x356e68af92e9c967f25666e3177b038a19705de36b960b479931208bd7c18c674b6c0e1fb94ee3164bbf6c94d0bc96f",
"c1": "0x8d7b2cb0a24a566df0b099a2844fc4e37dd3f936a434a1cf0ff17c74c66ccfe4962057af44ba3a8720b04ca1c71cb44"
},
"y": {
"c0": "0xcb6ac28bac038439f9d1dd2dc04faffddba59cfe22541e418c839964ce31bd30235d2600688e8bb74c8411ffb312a78",
"c1": "0x430868ebd5cf73b3daf1f790b1fc3457956b2dccbadfd9a73a409499ec0f8558188a76c4fb29533b1365db30e60ef17"
}
}
},
{
"id": 10,
"P": {
"x": {
"c0": "0x17dd0d5a9682fef47562555f6d7d6742683c853cb0c9c1b78e376a24f31733827739c0113e574c56db87b5a7d21ef205",
"c1": "0x4778705edf695e59a708defccfb16fcfafb5a101340ba4d32f724e3fc38b47a8fd2bf564d17bbe3d0f769f8d0855e76"
},
"y": {
"c0": "0x35a46f6ba26c9f17f9667d6d3a119d27029542e3839d8cb8ba4beb1ca0a30e950f9f683917cc75361f9478f32e994c4",
"c1": "0x1533e2a513f9576d9db62ae308d02f548bc2d4f169da5adefd1701037d7504549e5afa7b52b9e159970e19b3c14ba8e6"
}
},
"scalar": "0x63a85da59b08e2d7bfe84b8781c36ba034e319ec97113b0a83cf20145c57412c",
"Q": {
"x": {
"c0": "0x111489264b56ca99adec07d58b0a5990fd97c34a0c659e0ae1ce183f9126a7f02da156e38728cf10936e811a76ced641",
"c1": "0x636e8b6197461acc438d53feaf14195bf00718583268f741e9a2570fa058e6088ec595bb16973377cd0416557d85923"
},
"y": {
"c0": "0x146a11d7a40d289ffbb3be9848cc98e7c48ebcf345de56b27b1361cc78f6003a1349621727c79ae3243478dbcfee60d8",
"c1": "0xdc3472d0449b138ea2eed815080995156abd60066a6b3e908860b89dc939d4475ceb362c34700f559048891a06525d0"
}
}
},
{
"id": 11,
"P": {
"x": {
"c0": "0x161f0c6a1c3dbb01a077c349d3af53e1e7a45031fe4a2303c7bb9cd812ea79f68cc5cbb619cf4e41532c33aa47c21a30",
"c1": "0xfc5333f13829fe5c3ed0ddb7d8dffca529acfc05dd49fe760a02b1f10b6fc057a64b97ba563d88ac0feeefa0b514b0b"
},
"y": {
"c0": "0x993d923436513ae154170c1a6c60e69c24807c85b6e911e68435cc6e18c58c38e31ee638399cd2510aa82637f14d0fa",
"c1": "0x3cdceda3978b5da23269ff6814276e190242b3c8d3566199fc37d13ad7b34a4f113629d1b38e2ee69661a442d07e8d3"
}
},
"scalar": "0x4590710e4bff754a71a1eb1da8aefb56d2a5f91d547af5d9cf0af76ef5a8a77d",
"Q": {
"x": {
"c0": "0x40f09e94657f00664fa9099c94ab05ea6b3b6c44b0689b514018cb0b4371f72ad0ada3c5ddd972c6966ebf6dd21cfd6",
"c1": "0x246941ec4330ef175a13dd38a09ad9a9a9a5ed3c3fcf38ac81d35c2b7ce203857dd127783af25d1e943980c03a877c1"
},
"y": {
"c0": "0x7fb8f4c191bc10be67f24caf823e0f8aebfa669f02983aa4dc0188c979020ab230add1cc651f1def9312c4465bca647",
"c1": "0x14ec373615a588f6911b31623c9926cffb1ded7d05e90c0e6c12aa3c7f5769da465fd1357d0e6d0b9923d1ecfe51440e"
}
}
},
{
"id": 12,
"P": {
"x": {
"c0": "0x4a320b8181720c764b00d8ac4aa5f4172587e94849843dc01c3dc179da77b2f314732488521f986e13f869aac2bda68",
"c1": "0xe9f36414a4972036f9bf62a2b97a975ced44e318f999a67817c57512485e9a201747600783da9fc9e6884d05aa4be2c"
},
"y": {
"c0": "0x16cb5a8fcc6914e0a25e011301e12a4f2ff04a8763dd152a8733240c80abe36eee068fba4803d6ad673f98ae23bca53a",
"c1": "0x154ebcadb0b24137de122e33bb0954195c8b6574f9b3b7bcc927b8b028f4fd2da4262d193be4885da512c2d615872d6d"
}
},
"scalar": "0x6dd561488c86a665a5a7e1a2ed2daa6217247aa916e9dfc07be411e7456e5995",
"Q": {
"x": {
"c0": "0x98d27e21ce1f4e9d7bf3f5ab761080026a8884571ff60d24a8a4874bfc26483abebf16b2990b09ad23f4399cefd2a35",
"c1": "0x119347faca37e9860e48ccea354bbc6725d6c853d0883b8e21f96ec02af28d10e487fdf836f666b82395274fa90a2c60"
},
"y": {
"c0": "0xee7f2398902aec634c74ca952bad22d49b7d02dbc1664489ec8294aeac8edd66506f3d6c09c91bc8aabcd16dabe3c01",
"c1": "0xd2848d7e98034d838a41eb2d6487d07607e4c233268eed0b113fba17161caab9851191c681ae3fd6e74ad71843a9a48"
}
}
},
{
"id": 13,
"P": {
"x": {
"c0": "0x143c08be1fe69ae6064a7ab14319e2c5a9195666f56a82fee5fe396ce723bc9d0e5296521d257b6ff4651c11b4f00688",
"c1": "0xed5a9582cdb1d6280ae9bce610ac02ddb672811970e2a46a175a6d9ef69ae0b83d7a3c1175b5d9027b7fc3b70631253"
},
"y": {
"c0": "0xf00c45f1c1ba738d13039812e664ddf4a441eed744f1a6c3d065979203461c30fb42dc72977de3665b5c14dceced739",
"c1": "0x342d97d1ed5ca70be038c930846c7f94e5ea62bdd3ef373ae73cdf0ad2488aab60cf240ed48f8c5c523fbac23c67c39"
}
},
"scalar": "0x438b74fa1d6412d820eceed59e954b5eca04791c602f6dfb0e9f390c01f989c8",
"Q": {
"x": {
"c0": "0x12045baab231c46cb6cb7ca54915e384cbf5d321246345daf41d1ed9bf719247b4392cc508c918b44321a8f8f64ff87b",
"c1": "0x14757f042a95e43a2a328df92dc6c4da7d864d3be1bdae14ce8ba3543a826ebab22a3dac889c057d8dde02fa4950fe0e"
},
"y": {
"c0": "0x1601e98c467fd1ab4ec5503640c242b0be9da90460a5df7e8786b34abe829f6e818ca834695b526305fadbefd24d5bfc",
"c1": "0x19ed53b697c39d59f1422f3e9fa02597b52a525f7b6d4517ff1b0863e7c2dc00dad5b4802295a67a3ea55dc17a16a17f"
}
}
},
{
"id": 14,
"P": {
"x": {
"c0": "0x1821b088bd8897c7e665174d6a5f723ca49421ef805e0e7712d48a9bb9166fb59a9aa88fd511f49176deb43c920ed7e2",
"c1": "0x19a6136f0f6314922de288ae417948706d7d92eece54de2e6c836beff12cfca33c18187425515c2e32d50e4337e577a7"
},
"y": {
"c0": "0x4b8208a2847677d131c6aec7a8d9013d8131dcbad5386ca9cd306c056696727bf7f7cafb6283a1bd5d10b352a9414a4",
"c1": "0x149e61458f58c942ef864af6130cee701ee5bff060aa2113e866375f769efd68b13a5088a808def6e15c39e3b3835cfd"
}
},
"scalar": "0x13e03982faee8d020318e2cc8456cfa2d0475c8f6417ec3439976aa1455c604f",
"Q": {
"x": {
"c0": "0x180d579ab5e9cf52b631db60ca65ed2f6bc11a8b4a76d3642253dd38a980038fe0d678b5463014a4eccca6a49800e2d5",
"c1": "0x88a2ddb7b55389ffb6bc8cdc281209625c996090cef6028cffed77f3b934ca75cb5df7d0c60459606161dd7e43a1348"
},
"y": {
"c0": "0x1738a0571750871bb1fbb819144391e67e867150b0f4e896eba9f923961dcd8a014c5c3bcde7774765d02273d7c229",
"c1": "0x18c7a4dfd418fd1f55417e58ac86a65421bfd3da556c12a9acc84f299832a751b8bbe4a6d40b911927ef41d0c301f731"
}
}
},
{
"id": 15,
"P": {
"x": {
"c0": "0x959fb70d94634e92fed75f0014104f821bf47982e8e220ffbccd71f619de40ea5036c46628d2311322312ffb0b06859",
"c1": "0x167ed2818d06b5b32e279d8d46529079949a0a1545ecde3466893b1db8d843e763000223520b89bdf47ea085bd3468b6"
},
"y": {
"c0": "0xece452f8e23ae01157a3ebe784d71b41d06ee8608c1a9bb36b949f65c96f34716f019fcfe740a80a2dde0190c2f5534",
"c1": "0xd82868b9ee2735cdc74d5a7184a1dfad796899a1b3326d7259097692c7cf49e4bd326cf40254b9f7ae50b343ecee02c"
}
},
"scalar": "0x2b61ad5d2a0f7d64e2f0b4870a4ca9244119765821e395273500e7bcf90fea66",
"Q": {
"x": {
"c0": "0x7b86ef8659065d2c5715586f4c3fd46fcc83c5d61f835d3f222c10475ef540b8bc06b89f166fb8b34ddc284a9b3e9b4",
"c1": "0x192312ec620b9e4877590f4c4a723a57dd4cc5145b963adb41ca9189d2977d5386b49c129ad35fa9e97a882d5b5fb46a"
},
"y": {
"c0": "0x14361eb646eeffc8164d2edbe6d2815148350687a2e019a58a26a9c1fe85a9715c1f512de87ccfd4f053123d4e379614",
"c1": "0xd096034e22c6df90df3ad120edcf2da38bba90bb1e4c98b628bc7c67a1d2c93e35ffa3e65ca15ad32b621c7cefed021"
}
}
},
{
"id": 16,
"P": {
"x": {
"c0": "0x1b23d15d3a3cade68e9b6eb2f7cb8a14ff983f1921d71b9ddc6b1c925b2518a50066e0dfccc247a8183e1f2685e73a4",
"c1": "0x41d2b53b32009826796b131092d131b3450aefb7a5ef2f755634f748fb07741110e0147668b301a440e6861d6493ef0"
},
"y": {
"c0": "0x159d8e87bea89f65b1a7b99023e8c3e0b40216e6fec60e1f2008038c215b87f2dfdf50a3b73ad2e0bb7834f2f29d1e71",
"c1": "0x3f2a867e83c53f45953e66f19795522b14fafeb15e3655fb8423800f1f886e6ee151edb5bdad28191d3d14f4b7d4747"
}
},
"scalar": "0xb9de20027996a989025e4a853c0e09a1624c2eb9ceb2a64448a87ff032244c0",
"Q": {
"x": {
"c0": "0x60f271bdca22b275fbed1fe634eacd2263163449a0ba563cad80e74405362c3404e009352cb6c9cb615bff6caeba98c",
"c1": "0x661768c680484ab53cc1ecb17e6fe37f305ea0985eacc0abf8511bdfdb338a2e2930dff37c09fe8207f9f20132eb099"
},
"y": {
"c0": "0x45881b320a5fd621a7a99d413161327141a6c65e9852f9ae5f3e6d71ef42070b5cb20ec873201126eab6b567e6baea5",
"c1": "0x16b030a7318bf609faf996c24bd1aed7d11141fd3c917481a999b1b5098fc0fa04ad33b4e9c0c1fb09210c1aec9eefeb"
}
}
},
{
"id": 17,
"P": {
"x": {
"c0": "0x188e61e33a44be112b40dd4ee0f76962da8f697e8b004e1f8cd22cd0a71ef842118a5ee24580d5d0545b778b4471cbb2",
"c1": "0x19924cc85e41146f8b950c700a71d4f630c7d54d7f79f61f5fdcc3253697d68116b4f0f4c9e60433a7c0bd66862b3894"
},
"y": {
"c0": "0xefea5351a703f5e36b980d4ec214528b124469199fe5920788a46ab13e807e50e70fd9db4863d5e3eec411b48af21b6",
"c1": "0x87b98d2b5c8a9bce1555b8322f9d5677115967778cf2cbd360bda2c7a354512c7045f52d88ca9cfaef6a21cc46773e2"
}
},
"scalar": "0x840d0a5529da4cdec5a5734ee2aec6dfb06918ccffacb78dfcfab172c4b52ce",
"Q": {
"x": {
"c0": "0x721048c0d95ededeaf77afc6c29a92f6441acf6f55f91d225b32b20a535444fe0f842ec873aff228d0ec54e7ee61aaf",
"c1": "0x13adc1b93e9dfb4e9c3a515a442e2c4c1daca1b12ab4a9d2d5b47a35c06ef2e7d1bb9d67131146d978cf3ed744024abc"
},
"y": {
"c0": "0x15010f3e3ba170457982627fdea7697dc237d58effee0e8dab49c7fae1205011c16c4009558601fbda71d950bde204cb",
"c1": "0xa6be0bfa9711e87953d5e3ca782ffda46445367a0a169fb360c17cd6c914d9aee64cb584b313631284e9cc12b27794b"
}
}
},
{
"id": 18,
"P": {
"x": {
"c0": "0x53f8007bc7025f052498aca4848a41599abe7af5cf00cc8238680368a982b85437430403aa59dfc5848f7dc916c51fc",
"c1": "0x149f30d8e94e31cf34a7ab073088449cca90ff506681e8c68ca14f922f782c95a83f891ce0b9d50c762882f2068a8061"
},
"y": {
"c0": "0x6343384b10962e10dd4739090e568608f49cac804ed358588329d4213824d5ea9a3b17bb485cc934e9c3ecff4ed578a",
"c1": "0x3650b70907cb688e5381ca24a5a63e0851d3a911195c74771ea6fcc10ec639aa74d4a74bd043b21bfc7013f0c6a17e"
}
},
"scalar": "0x46191d3caeb4d810ce0ad8072d23e8a24ccf26d91d15207a38c8481dda0e8e4",
"Q": {
"x": {
"c0": "0xe297549cd13a44f3f853097f8f71b85a2dab0c594990a19dfd4353a0dd735f17165f59f79bc63a061e2b1f263ac29c7",
"c1": "0x999e91875f8b2b5be6874fedea380c2eb1724c0d95c9dcd977c42a184eb53bbb6a132cd0218f1bd004f6a2c1a1985b"
},
"y": {
"c0": "0xf0f65994567678b592d9b229d902ac1211680cfc8e027ff0593f70dcbe2c422db2d93c0e76de0872409cdb04934b31f",
"c1": "0xc11d0294b61766dd7da81de06ee0d892dd449d410a5b690f0e24d0895a84b5004ce8e4675daec2d93154168c8a7f436"
}
}
},
{
"id": 19,
"P": {
"x": {
"c0": "0x8cc5f7b1dc2dd58ba56e530465ee28488a3de76cf085ea8615c692b36161825b0ecebd848c0b01d8fec42a04d6c7a0c",
"c1": "0x110adfc7d6e0ccc8875c729a0f4cfa96024a1f510b0c2ca1db32e2a0bfc6b0c6ab0bf2b0a30893ea95b518997daee54b"
},
"y": {
"c0": "0x868c40f869ae5d7ea29f0fb3315c6971c044595c74be3521bece884c5e5e3ee6dcd0c20f025e65698030f3c1b44f4ac",
"c1": "0xdf13f9ce015b48edcbc93848e43807c8eec638cf62fc36b92fcb0896b7663e7aef0b42c3b81a784cc21a9d989557a05"
}
},
"scalar": "0x10a52a09a569a404b84f0ccaa3a6f17899db9614cf35ecbf015dd5fc945bb412",
"Q": {
"x": {
"c0": "0x1107cf1e68dfab7f3b431a9ca507d5f63337ed154295eced835d4f2e4e227cc622109a5e6b809a54bd9c5006d1dfa3b3",
"c1": "0xed33a71aab75c60afc9c42972b3520ebcec3fbc76b9398053fb3530697c2275455884f084d1a3ec62595346e01997e8"
},
"y": {
"c0": "0x18d5f88f662fd8e41b66d0ce11a0bc91a8dda6d1717086fdfca5a83df29b1e6305b93da62967151dcfe027dcf240ba8",
"c1": "0x1520e099273838d14b04495ebfdb86b60bf35444f4a31246161b6862d58c922080d2178f6629a1fbc5c60b9b259356d6"
}
}
},
{
"id": 20,
"P": {
"x": {
"c0": "0x2c2df9daa5a51d0d2bd2e44c343ecd55f81893204accce320d2343c594b60e457efde6cde13787bf4c54cecd7a29307",
"c1": "0x8f3a7e0605980a5b9f63df686f4c54f3a8f97c344f15b663ece183a048e68c4b2f76ca9da3a68c31a246a1915839401"
},
"y": {
"c0": "0xe1b5ecc4fb845faa4c6dbe229c5d70c5968f841692c9c7871aefaed1d1a96dcf861264014238e0f01a661b34eac3006",
"c1": "0x894baa49dfb7896fcb82ee68b96a383250de24e98a583a1aca4a409378f7ab21fe8e004dfc25f2494bec2d37e2c9f84"
}
},
"scalar": "0x251871b54ffcb02128f9b7d41593d72369430f19ad5e5ccb642fb4a6f06c883c",
"Q": {
"x": {
"c0": "0x2985e87c3aafe784bfc39415c066bf33e3311f7d11a9ba462b3972693378276ea798bf88092ba697e7579f12550a897",
"c1": "0x905d2715effd2313536029f2a0e932c489a9420fa366aa2982227054c2c027920a434542390d914c40f41d407d127c5"
},
"y": {
"c0": "0xc99721067fed8b047b141908bcecb7854eeebbdd105c270924cf37543a4ad2c4bb2aefb4447eb052a2de4898111e91f",
"c1": "0x62cb9213f6da031e291cd8b4e3170629e6a140ab415770166a98fdd529cd85cd14987188438c10f5d23d305f6b36ae1"
}
}
},
{
"id": 21,
"P": {
"x": {
"c0": "0x158a898968a4fe84a725266ce5519d65eb190ff2ce8a0419be16f8731ef1a920a8b8981b7eb958b8c6ab5a8f341500af",
"c1": "0x14cdfb2d87a1adcd32fb0952d5070caff1c5a33dce0c2cd0b11198a8d18b646e5bd6059f57c7b7f1172289a8658a9932"
},
"y": {
"c0": "0x112fbfaa9da6f63cb611b3a8519ed02cc4f0601e38edbfec732c6672b3bec4fe8b4189f2ada2062c45af535e9edfe916",
"c1": "0x8a3277ad1d82d542c6f38941b2df7ac0bdc108d928d5952d87f2a69b6e1ed943454ed9f465184c48c2d2c3e70b22bc8"
}
},
"scalar": "0x1f4328992c1e66a1458efeb28de02e0fad149769a36970de6a7991178dc3e75c",
"Q": {
"x": {
"c0": "0x11818c02bda4a8701f32cc502964245f506b5150463e27c4e5c204c781c43b812fe48fc76fc95446d54dfadf8346503e",
"c1": "0x127cf17ebf28ade2ec4b0932945ff4a00a953ea285d3e4aad1392f8ef640729f5d8779a2ef2dc4278281d4f276155379"
},
"y": {
"c0": "0x846802378b83951cac666435213c33ddd0d78bb14dea4cc51897f714a3e5c6e27306998ee6da36494162e992810ded4",
"c1": "0xb86d983fc721897c30a25d15724438425ef7464f613bcc7bf0cf6c52e1806a13b6bcd03e8a4251fed552b093d77b506"
}
}
},
{
"id": 22,
"P": {
"x": {
"c0": "0xe51704b2c1c919eb15096d95bcc903192ea227df3afb70e855c212a4317f30d30b1357068e8931bb592baf99262fa89",
"c1": "0x771591418ee2c684da767ee9e921fee5a57670c13ad442b557a71235f6d878f2ca3cfdd61349571f3779a1442ad6c3"
},
"y": {
"c0": "0xd33261d1786eb5a0eaa423d1caaea9b2193a148ca7d0d7b1afb2a0c11b5910212fb07ed5d10896735a177aad56979a4",
"c1": "0xfdb8739a0e46b91175d2c582c0c317bb4566057978f23f2f56da501d65a8e567653886300d5c7609e12698c96363e62"
}
},
"scalar": "0x57092e5c2513aeceabcc01ebb8d3716ad27d08c210fbef2571765989d2a997e7",
"Q": {
"x": {
"c0": "0xdb95ba5a5b5d0fe51cc9e36ebf99d9b586e4bb96e2143a58b743c17fbd82683e5ebd68646406d5608271454e5368822",
"c1": "0x57d514206cfff16d98f147648e5ba409bf2c7545bf73f2f9bcb167f00f856a0bae97d5f8ae3b3242eea436a976749d8"
},
"y": {
"c0": "0xc57feb3306a84560ce135a8ae90fdde9aa7d7e14c32f355139eba67bc14b290a79445878bb9e24653dd47c384d3d210",
"c1": "0x7b2f1293b41f24e6c77347e86bd2ae61b5e7d131c80c38868c6493432b59e83230f3ab92edba08798cc0dc2c6144fc9"
}
}
},
{
"id": 23,
"P": {
"x": {
"c0": "0x16293c9c76470ce20b7c25dca543bdeebb7ee427cfa0bacd8f461ef6bc5dba6bc7fcd13d7fc035b0e3b04909c7f3217e",
"c1": "0x18a17dc8642420a0285ad076e0576bbc4b54048480dc327672b7b17b46b893ffc341022ab6f869e4c248468db0f3b2b9"
},
"y": {
"c0": "0xf021cf72bf675de37ab3dc07214ec02f01c4ee21438ec04485c32331e71cb50422df61ed65989afda935d6dcfb5decd",
"c1": "0x11d88ae540975d9b1dff881652c37785f877183848aa6a6519f935eb0c80a75ceaec23011061452fffd5f28bd1f885b7"
}
},
"scalar": "0x52a675a265dd392b602f181fb3a96c3293644da85e86dfc0c23d72ac9edd392e",
"Q": {
"x": {
"c0": "0x9184a921c53ee2d5ee4f695e6ca7a000fe47b9aa9b7b06c6cdb6b15b628bdc5160a555930dbb6a3f34644c5babd76ea",
"c1": "0x6c5507e366c444a063e7f82a211e723ff70ae7e5b1db5fd5b958da202387e393ee2f39d7173bf175ae646cffdb6ad4c"
},
"y": {
"c0": "0xbb260a49db5fe8d149665e77bc57247132c7918628cb7117900258a0a83dfe919e78fc2115a58a398f9f884c7fdd5fd",
"c1": "0x8512bf36ce340cd6b5f47d4325d1a8f9f81c8370d7f2a4c6dda62377ea6832d2b73b4bd69d4f68b85c4cc58d78e41ec"
}
}
},
{
"id": 24,
"P": {
"x": {
"c0": "0x8561e4740349e870049e08c809ed497978e69a6f08b9a890e8fa347e7fa263fd979ba11e821cc55e7a0bfd2a7d92bf7",
"c1": "0x114497860bdd773d139f7af8180b15166d110754da04dca638542a1edfb11ecf5ce351607d5c8518ddcad612b3ba1382"
},
"y": {
"c0": "0x1e34f55b110fd2e4c6dc2b4d0d21e599fe35f536b700a1b09e98c55a481389ccac8b6392c4d0f0676f129ac26c93414",
"c1": "0x46b5f0f444f1ebfd054d5c7d286434c23927e9c87f0abd507709626bd63c1bbec67d46cb072980915e3d38c12e23bd3"
}
},
"scalar": "0x2926960fdefa115b286b93869f526a79bd6b041449777dc5813af11a991b3d5c",
"Q": {
"x": {
"c0": "0x161c52df66ba123d09aee45ec96c6f994e708dee29cc00e1b967f0ea27681aba7c5cc59a0e94129958779180bc56b98c",
"c1": "0xd6937f74c3601077af1ece31c06a26997e9d9737bbcf0388b2a2dd5955c5e7772e9f7affd4d5139f307268333011594"
},
"y": {
"c0": "0x14e3f5f191cb1c57d5588ac71aac3ed1010f476e5de57057d51b17514a586db8fce2c2f1d5912967a744a6327e26e1f8",
"c1": "0x17390f8fa91fcfe6696b95b648a25f8198c75b442864c05a40f707ea2bb438ccbe1d268ca2b284067106927ffe2e45c5"
}
}
},
{
"id": 25,
"P": {
"x": {
"c0": "0x4dde1cb9caa33c04d94910ae16d76b77efc97ad2e179eb508275f7bba97a6991b2b0378d7ebe8ef751cbad3a522f6e9",
"c1": "0xad0ddc16e48ca237dc82cc3c0e61bbe97ab1de5cd13b75d1d1d9bcd1ba70f0edb613dddd042f00391afc77d80f10df5"
},
"y": {
"c0": "0x9d71b6a7d85639e4ea6b29e1325ca50a3039594a071b1eb05121f14ea48cf15183959d805f184d217dbccecb9893987",
"c1": "0x1e10d38faf6ce340be3164a025866a6ccee1fa4942694f3720b7a9a02259a77172c3b41e853bdb30961764ccfa6144a"
}
},
"scalar": "0x3634328bec527e7e1f2ce632e3d9da0e05e0d94bb908d58af7778b162f478b85",
"Q": {
"x": {
"c0": "0xc7782615aab71f8b14dd4aa231ca2ac3d3904b35bf4bda3d47d49a79be8e836880fed7f970c606693e10248a2788d90",
"c1": "0x1867dd8de206ca3a4d4ff2ed3382caae562738ffab395715db8f944895cab986e083ba26445387a8cbcb7d447bc9814d"
},
"y": {
"c0": "0x13cfcef2a2886b0e867e902e1e76cd61683b6606d53f52226c28878c9dce25b8cb9dd17794a0cf7687e327527d8539db",
"c1": "0x66788fa01c44578f0aa670c9bd52d61ab6f3f2b16693c41a0efd44420dd0ba3880d6ce2baee5f444466b709de7c25f2"
}
}
},
{
"id": 26,
"P": {
"x": {
"c0": "0x12b9048ad9dc4047e8dc2acf3a08bd1d3846112885c8337953abe40d1e4e1d26dbc67eb486699619916189122fd1afc1",
"c1": "0x850d176fefac5bba1823a56f03e64c8c33b5706eb0e751486463a9710727fd29d8013ffaff30c88a10ac40f80038119"
},
"y": {
"c0": "0x17a216a6be6013dddee1947eb9ba92af01241162a2fc8a47bad239a7f5e5fc33a63ce12edafaca0420efe7b33ef1bee5",
"c1": "0x12908f2a678227284e76027fe86eeba27359a6bb364119a87c4a7b503e8024bf59aaa9266982dc89ce78ac871df1c36f"
}
},
"scalar": "0x4374bf5c5614a8e7b73074a2e2f7999143f87314732a9ee33c1735f8c92e8a35",
"Q": {
"x": {
"c0": "0x41a96bfef1ce470e9df0432ddaa235708bc73e097eb07fa03c87a2897d751be04640bd3fdf1cd16895de4d47c5e4d42",
"c1": "0xe529f98de16fa54413d54fc7b2f04d70c6775a9cb5750418a0378abc3b9df15352b0584b50e8e39ed23a6699e0ece2f"
},
"y": {
"c0": "0x104d91da83869b510ad33d5f649fdf5bbf04dadb3ca4debb8c9606ebcb2700ab68fa080a838f03aef7c2fcc5482ad0de",
"c1": "0x1586b12b9982fc87f734648548d69efe4a47450084b73bb00b422d0c53e13b8752d8be6d3b794e652c1840385e0c6cb0"
}
}
},
{
"id": 27,
"P": {
"x": {
"c0": "0xaf945f8188893c261d07cac5d6aae68b2e64586b7ec0ca02c10255ce92b9c13547136b75357802b5e8283fd56dacbcc",
"c1": "0x75ee9118229c6c5de16a264260ffb5b41b57e50e16353ac97a2b26a2af557fb57a8efcba0741ae47f8fe77c4dbd58bf"
},
"y": {
"c0": "0x1041c147ac8ffd6a2b7647d09561cc47d14ec9a0c5c608167a0e36f89e659cf30c80b3c41d52f02370c030425ae9f1d4",
"c1": "0x10f16a7831a05385c3a2d09b754f5e187edcfcc5af7206aff839f6db09b5a60e8284fd76b9e0b5883f551c9eb820b2af"
}
},
"scalar": "0x3036b1aa14474f135d4380544c19a534cc89b1286ccdab5199646eb19d31572f",
"Q": {
"x": {
"c0": "0x48fd65195a2f0aea58d21142f85e94f8149bd8c83fc48c7e2438ead616674c4910bca945727e35ec9259bfc00fe6fb",
"c1": "0xa2a9aebbf679306131f7838223768eb7814c28e18e307a1b23799ee4514e8f4707d359ed887b11dd3c166cbddd2d5e3"
},
"y": {
"c0": "0xa5b040a0247b07c44409615675ba6af64d2d52ffa8f6ee66b63cdfb4279e75d6d248f1404bfab1699e298b441692035",
"c1": "0xd8171ac6a9c60838402bceeb0f18b1f890da8ad01f86af49b29552f1fa1d8311a4e3ad43495ff006912daf9be951e16"
}
}
},
{
"id": 28,
"P": {
"x": {
"c0": "0x75b382a58e05f43b52a29940b74b1ebbf2f74b5a80671bcd4b5f5ad43f7e90a4ba49d5860d57d22c7a3990160ad5680",
"c1": "0x12bd2fed30cdf6f95e7a7f0d104c8baa7bafcfa3eb9a272cf2c0123ec5a2c968134694440cf400ef8c85359dcd233d52"
},
"y": {
"c0": "0xac4a8673bb9e791644b4518e6b4132b03e7ba596af6b7698f17dfb117093cae6c7e5c0becd32391d9ed98b788489ec4",
"c1": "0x17cfb0b62dca0fd8f4b9bc98cbfe068795aad7aeba636e03ba4ea8bea4c34edd8f59e44c9caa48c5ba0493b8e7824716"
}
},
"scalar": "0x55ad209ef711ea2cca482ae48cd2f59989ffc864e0fd9aea9dec6c6d5340dbc",
"Q": {
"x": {
"c0": "0x138d09ecb1564eeb7401be0913d5ea67870a21ddda088a9e53787e4505cd0741e9b2e982cac6d32c737dd33030625891",
"c1": "0xcfadff67d636c42b8bbe22d92a0f3ba800a7189cd974ef15fd3e922784162c78a1d1cb983d1413a87caf4b76e6f4247"
},
"y": {
"c0": "0xff176e1078f4b4adb71cc6475953b435d5948bedb42329837c1f55291a994957e7742300e9c37be56c2a0b64c3d5abf",
"c1": "0xd15e45b23fed73ffb21591ea16e7a43c3578d34406b15a70aace1761cf40cbd73db977ecce735702b84fe73705e891"
}
}
},
{
"id": 29,
"P": {
"x": {
"c0": "0x1632f03cca35dfe6b1413ae607c9aa99f5dcd1ccc8fb1b9ec0258f6a0a651d97b30cd08eba8f55be60616fbd138cf3e3",
"c1": "0x33a16556214e4160be07c9ff1801163cf96d06db6179e18172d56c011f6896f7fa34787af7263da2f6b1e2174aab254"
},
"y": {
"c0": "0x108109aece72e29fc71d30ef80094accb851fcb8cd698c4a19141be2bb30def7c79b0a1004ac00954d3d5ade98f948dc",
"c1": "0x199c5b798c915d117e1e1eae6db7eb43f08018a90ca0311372b1683cb99c235e01ea2115f52f1f7dca60dcc4c6ddf731"
}
},
"scalar": "0x11e8df6ac4d9ea272c526f87ad3b7459220fe39d5ede05f947a88a739d2c8f9e",
"Q": {
"x": {
"c0": "0xeeb2ee557c7248338e664e5325a0df8eaf89212a18c8a32cafc0b9bd56682e742b739229a37da077ec2e452d12daaa3",
"c1": "0x18e586777147b7cd896a7f97198bb9d61691fbfa2c900e01d6be0cbdbd13e50eaa949665749054336ebbb386cc6d64f"
},
"y": {
"c0": "0x3b431723d2b115ca0f9dbd39a46f07fdcaec17b0a8c89414ce518ae7a44abc924d4b839c7a9d48e540b43a21ed9e600",
"c1": "0xd03a19638abd54bd6e7e09823e733faeedecf6682322e4b489fd84f3cea12ff6687890749cd4582bd5e765c35c8ae90"
}
}
},
{
"id": 30,
"P": {
"x": {
"c0": "0x17773c31d618ce80a75d85725aa484dac4bbad80f032799243c12847b320be0771b4346f3861736d0dce4bb80d9593bf",
"c1": "0x7a4a051d39b5c967db23a45cb613c9b0bd2f649b25ce12f1cdd883985106a27f72b3dfac2bfd73a36f52fac469f994"
},
"y": {
"c0": "0x72c195e3535433475471c511343daadd8220d6bc18438e86c729b5a2ffa0ae7d51919b12ef6d1d0d05068d6eb79e524",
"c1": "0x1126157ca1c9f825b1f3901f01fa1c8851fad24baf4cdb1f80b9d3f2dd5ffea330019ababaf741d46eb2f3cfee8036b2"
}
},
"scalar": "0x44032d121d4963e8c7747c7820eb5782851fa686ea3c1559cb1a61f7f81de172",
"Q": {
"x": {
"c0": "0x163b2fdcfa37b69930921688b0e3a862c20f89fb152d21594f8385429d1b731a470d185f4aaa88fe688d7040f09c7535",
"c1": "0x198fa523c2e63f2cd8623d2abcbcd372974f46869916a13b78f5c5253268204f7f35322ebbc90ac38979476af6f3bb"
},
"y": {
"c0": "0x1227279e4f72437f60345304fe3d412a838a87fe1620d1e554a82b8214660381a5b13373d46dd9fad5bf501471937ec7",
"c1": "0xcd755396034fb15724f8424e1a91a578bdbc1d6af6e28d9c17d68d470abd210804a4a16ea814657c90a41385ecc6d2"
}
}
},
{
"id": 31,
"P": {
"x": {
"c0": "0xf3c473396d9b982719ad73066ff0e32ed737459b6124d5a2fbf5f07566a071264771321940c9fc83d3566d54adba86d",
"c1": "0xe9a808d3c0044ff2ff634c47662730d7eacd0a36d5d8d97e5cccc2ccdf41e011daeb81d147571bad962fab3c38b1a05"
},
"y": {
"c0": "0x19e7fc0defd417c62505fe46380c49e1f91b073fe53da892d167ce020cea438084b712e10fdc06c2337535a9b7a6d091",
"c1": "0x5d043049a6f2c20811537a409fb1f28e093b05b8bc251d6172e2c0da3896af6bdabb80b74c67086dba2003468694b51"
}
},
"scalar": "0x67c550e27bd33dd2eaabbc813811f1e970564b30dcd30e93775c8c711a41fddd",
"Q": {
"x": {
"c0": "0x1420a73d96c43ecf5ce711dd1f15db7db342e5315f78e04002680cb18e09d3bd778424c35ccc34133600b5b044e30e0a",
"c1": "0x13b4963df899b2bc1b6f26e47768b55b3cc92bdc6fda4e1c62f50259401e6a6438f498459e17a1d0815c541f6eba8c8"
},
"y": {
"c0": "0x499230283a98af93af04731493f5a18a6789e8bd84de24a8d308e0a66632782751ebf890146c4da2027bae2e82a6845",
"c1": "0xf8957b2c89ba1568e750ebf2eca41ce70cf1a5a6f3f17cd2a5a4533b98be9c920f9ce7951faae68f3eea5a53911c777"
}
}
},
{
"id": 32,
"P": {
"x": {
"c0": "0xc459580b4ebec9576d062e9b2a5aae14c31989b449cfaba0d86745a04f8b38913e6de98d6b0ad693b47679af531268f",
"c1": "0xa5292fd6cb72d77758dad95d7bc81525e30575150888265c1698a1524476a884069de28789cf373f7d4fac88a30a91c"
},
"y": {
"c0": "0xab924a2980e6f01d3bde95123d00374c22fed57b7182748444a74d293ab18a72769c6c333fbd3d1c376c8e9cd08a56e",
"c1": "0x1157b2f2425f940d2dcac15c3994e1768d8779d24d05cb2e288ad82ac6d5e1d11accea3391d0210e7ac2e438509ae1d4"
}
},
"scalar": "0x1be2c5d3d73a2156fa42ae121251e1705b63075fc8378a577fc348511b8869dc",
"Q": {
"x": {
"c0": "0x18121525ff4753e5820dca75289f5a51cebf92f7738a4ca12d8f6b6751e70df0afa6fa0b6f47c4cc40b72c7717bc57fe",
"c1": "0xcdc9c6b22040ccc519ced565330e4b27c7cfc7b00714b0c2d88f1c08fb1c683bdc8d26f5b5b45b5f8e3856ad9fb1b8f"
},
"y": {
"c0": "0xd52d0db19b2dce08c8261d0b9e475265ca13a8de8e0b11db6ed8ebe6d6f2f3f953f0e6edeee86c64f3c41f11b623d3c",
"c1": "0x6c089e5b998f5960d6bb35d212c10ca75c757141ded6a0e1bd90e88e9b735f0d20acf3cf275adfee76b583234b45e99"
}
}
},
{
"id": 33,
"P": {
"x": {
"c0": "0x603c81fe7368fb7a2bdf2600b1a0a93710ac022a0bc65fb3e8595e8a97096961fcb60be9297d60c5f14153886a1d6de",
"c1": "0xfc2b418e8481ee411e3ba3e6f2b18e3cc842c2879dc085e5e20d51d361ded300d51bd67137d9b0a4d36ebc8f97b89ea"
},
"y": {
"c0": "0x13fa955dfa7e8992dfe5319c10cec018fb409d9bf3c20b248a2b1633927f8f0588bb946a7ee4720311b88f62160ea0a9",
"c1": "0x19de3775d457ad64c7b7256426ee9f79a10db6b7cba56589da8c2cdc84b9df3ab677b710ebc68bc79eeb616829d6e3a4"
}
},
"scalar": "0x5faa8aa3bedad35fad1ea6cba0cc79d0ca66dbd633a17488852b47b2c6354a73",
"Q": {
"x": {
"c0": "0xe958f738218eb02956feabb5a9227007b4356e61ffaa5e69d8d0a444f42d40019764266228d09e89f75c6b2ebfbc8c1",
"c1": "0x94422f1930b6a3ecf2cc66a0c620e92dfd68f8de84bfc2eb92b8499fdace5da8167ce4463b17836d157c6f5c177468"
},
"y": {
"c0": "0xd2d2ebfc53fc7fff460a5918f7f9d62afd87276c7dcbbd976485705b43ab6830cff0c94b10a2585474cf6d1280613c7",
"c1": "0x8ae39229f16428350f3da8d6f2eaf611446418f67a1aa905375127f086b528dd9b02addc595e025d4af85b85d981fe5"
}
}
},
{
"id": 34,
"P": {
"x": {
"c0": "0x100edb01dbb5200e1df2dd76d1a09db39e4fb76637fd534121715a5027b83543de314756ad7c6332b9834f69b8083645",
"c1": "0x3fbca8abb02154f58cb8980f8db101348c2c28324324ea2f0ba6704d6044e12f7210f0b3937875c3720f15fd829fe63"
},
"y": {
"c0": "0x51e52694ab4348b3b513824b4abff76996761bb2c8698d5586f99fc6d419dfc5c74e016ec479076dbee37ef4873c3b4",
"c1": "0xddbcfb07a216199490c72fd4e51792d691be49e138364b51801be74fdffec26487e01c778d733b1fbf6836edd3cb9d3"
}
},
"scalar": "0x4e827db7b4b65fc35b7a8f628df68cfd906e695dc20499dc15301be0164a6bee",
"Q": {
"x": {
"c0": "0xa81a4cb2b1bb54f53f765fc4f5f2993ca904701cf84922baa6b728a39c4dca264492c1dd26a6c64249912a1b3c9ef4f",
"c1": "0x175c192ae7bb9b1fadd1ca9f7fa81d21c2eae8b9247b6519f3ef933e7bf48504022c744fb40682cbfa6617e5694ddc54"
},
"y": {
"c0": "0x16910bdb7b36b04e16f725b35856cc04b1f99e14151e90bcd0927c4e509a22f2542701ec17ac38443c36b4bebf0b9bf8",
"c1": "0x1283c1424af701e0a435a71114494117613e976e5f72a25984284d892fe6813113e894b6407602d1d8b6c343b89fe884"
}
}
},
{
"id": 35,
"P": {
"x": {
"c0": "0x174fd8dc574b5926fffeb7d3e2f90be6ca4debaad42eaaa6c7dda0271109bb5d6fa131eb927571ba85c9d85dfb7e9e2e",
"c1": "0x9c4ba82d481f61a0a45516570486dbcb583f62abe04babcdfc1ddc78235c92c8f658ad141678eaad9cf70b4b8150216"
},
"y": {
"c0": "0xecf46e917aed4ecd9d93f131505ab3ac1449c459182f338ee4d58e0b939f16b023714f3da9cbd68f1296ce60f3e5576",
"c1": "0x3e978c0bae6f4acacfd4c3eccf61eed27e1d38bc16b6caf5ed9cdc504c06a1c1d42e30cc262ada63e16fae7a120347a"
}
},
"scalar": "0x65ebdd0eac05eb248bb175caff0dec1d8d431bbaaf6b81520b21d69ef3e4f5f4",
"Q": {
"x": {
"c0": "0x19d842bd7582c5171629c5bf061cf375386bf549eda2851557afe222839706dfddba7a25bc4b4f139faf34232f81950c",
"c1": "0x127dc960f674a3155e2fbae724916a5020729f866ce58242751c6a37d030cfdb7a6f3b92c4c1f209309ed50aac5fbf58"
},
"y": {
"c0": "0xafc9a3bd17ae235ed72013e45c11bba45e47074319e2de636fc275b31b129a663b6cf7f70a88e39a5c117591853cb2",
"c1": "0x15c7bb28420c6cc486cbebcc15b0fcce3414129c55dd677f395c01f548f61569626065a40f42b87965da98b034478065"
}
}
},
{
"id": 36,
"P": {
"x": {
"c0": "0xc13c3536375eec4fcbbd6553c9c884c385abf1c52e3379ec6d93f3f8cdb02896dbf47aa26362f9708fa5ea938e97ce5",
"c1": "0x938a1bd16b11e3b65e2bd824916d4c7382aeab8e870e9f67f1484c250960ab8889fdf1456a39f0fdb824ee074ac39bd"
},
"y": {
"c0": "0x502600f44a48e22b02ceeef8f2eb1de5ed0b3b02f8f6fd40106388adddfa7439b4d7c647fa1ba6ad6f9c24d36a40633",
"c1": "0xc5c33d4a1200f670b9c1b733a5eb3af700e62d39ce8b800627e2ebc4ff2cdc54eeddd785b0cae979e2c1472a106bed1"
}
},
"scalar": "0x149ebd5c3525019c0d7f46a2a15f137a12534d70e63eeeb27c08092b773beda9",
"Q": {
"x": {
"c0": "0x137a10fd08b1f996feec16a2a08faa47abead0ef881314557105bc5b869a318ee9ece52da126fcedb48eb276dd000cbb",
"c1": "0xf01e99c928455d99326dcee95a1668e935af57e91e7d32a8fa7bea05959ba31cccdd03e9ef0501b2ff864062f6ffc2e"
},
"y": {
"c0": "0x2ca6ccf93503cfd6ba49e4f1c13612dc11551c92e23cf4e1f1274febff180a0194bedda57c3352c61e867567420823c",
"c1": "0x11295f30bc87c4df8f5da978df0db3d7a1ff7a55411d0a01b4471c297e6d3b6eb357e3f62e9cd0f17fb08d1a0a52cb18"
}
}
},
{
"id": 37,
"P": {
"x": {
"c0": "0x199d47b8758a7657d0b58299904ba3f539dd5fca38c04c13559c4a8b27d7843e310e998d09b81c898e1af2f43616bb6e",
"c1": "0x50bea093a29053c33a7effe810b3d1177a3f5d67b31e91499ba04dfb1fe8ec1f0dce23db12d3516b778a5fc8ea8f68"
},
"y": {
"c0": "0x1dbd67a55705f040d763f53eb479411bdc015c9c8ae77bb2c24b45daa83642e3a73f1933b124c039ff92b5ef91dea45",
"c1": "0x12e5a0e78404ad66635307cd399de1c3735c8c7e8055672ddef513245dd1a17de50271632e895ab4a944f5a648189621"
}
},
"scalar": "0x4a104d90c4efe06782116c08946e35e8490a743510f3cc947196b66c9dd67296",
"Q": {
"x": {
"c0": "0xcfcb2e2665affe6d85a0fea5aef503513f911efcf0196794028d5a280e6530c65e887c9c0720e6b456bd20ef12d789d",
"c1": "0x16cc317eb380597f91332fd1b760fabee4a0c868b5fedecc0b8efdec6101ac1b0772a29c2b54dada0fc03700d5ddeb16"
},
"y": {
"c0": "0x1794d312d7a5701f162ddeaba0c6d9a21b69d674976a89c94a82402a3c63e6356c951078ad063ed9702dd14b650c5eab",
"c1": "0x11c967f624d28aa6b6c9cfeba8b5dcb85e1f1134e3e7c30a63cf9c50c5e0b24213c2787deb98e1107d3e16b2ab1e9831"
}
}
},
{
"id": 38,
"P": {
"x": {
"c0": "0xe536453b7c8b64fecd3b40e26fbf34568cccd55206673130af4c3b94620c947f547b27253efae745aadf03e922c081e",
"c1": "0xc1ca7edc32cabe086b4b3a2e1d4ee736f69ecb6b0b1a510f14c0ec451fd42cb688dd38994eda6a6e707ef7771b0b5aa"
},
"y": {
"c0": "0x3e80f8f05faa2ecf911bed86da75008de1942eaba3a8bdc8d6238c251dd6226b584281800fa69d22fc7fadcb4be3026",
"c1": "0x15e082f350227447ca7192a11777d13acecce08252ffa4637bb885b520d3e00abc30069f56ab605d32ce214e594e2e8b"
}
},
"scalar": "0x3384db722be3c35bcd981d687e8fe25b36c9a1ac7d5609d7577a28f3b267462d",
"Q": {
"x": {
"c0": "0x191601d6565477efa8b13ac2be32b5b4389b3d021adb7ffda357032ff5229466ab038ed6e897dc1070b5c0a4cb271393",
"c1": "0x144efa694229e848b2af80bb12c38706b5c9c504ae02dac17a02fcf42d837e86992c14e11fa104abde9a2dd97b1e36f3"
},
"y": {
"c0": "0x17811edfb39110fb10c1a9b481c76fd4ebbd8eb42875e4396facb1a959ec65d7c08b0e592a4d4d0ba70e47b2a06ac753",
"c1": "0x1747ea4350018164423ddf24d88700162045aec57ffd4940bc2ceac69a7e3ae0a4b4b1060dadfc5f58e0163759ca3e7b"
}
}
},
{
"id": 39,
"P": {
"x": {
"c0": "0x1196d67eccf2f07ac2249ef581a1efcbc30e0987056cc4395d3e9585167a7e4ef56745319e03c5012bd7f7faa48ecdbc",
"c1": "0x3e1a4f1fd673ee93ee74a14e7276b919b586b41f3f6eec1f97ad4575618800245432c2ee8bc9856fda3b8b725393bd1"
},
"y": {
"c0": "0x16d2c26b253ba39764505351a0bf68a14dabd8eaaff42cda1939528602a85c1d45d696dcf0dea638672485cde2278dc0",
"c1": "0x5e3615af7a67a32417a673640618e486f312167e6533ddc63e6631e2555f3f20e269c895bb27c84cddfe0dc3fcbfec4"
}
},
"scalar": "0x70846eb91d40d2a8e3028962cca5a3c8dee44ce9b9a45735f6cbd825ee1b795",
"Q": {
"x": {
"c0": "0x2554142a72410c3da85b635481f1f28c17d9bf746ce692e68a46134e2505c586b0ff264026b66222fa7aa756e0b219c",
"c1": "0xd29e1905e92ad0a75c015871763f9160bc6c891e843c53f49c67c233e979edebd910c9137ff821a8b2e6d0ef290f4ac"
},
"y": {
"c0": "0x1617ce981ab7444d5852021d7df9558dfcb2fad9e239ba97a586ba04fec0cbee40fe04d0468eac50506ce88b4932cd7b",
"c1": "0xc7efba6916676f62cbeb10dd81a07983a889376a5d255c48007a5d2f4afaa1959f7bda4c38d16b5094bc790fffcb5f2"
}
}
}
]
}

View File

@ -0,0 +1,492 @@
{
"curve": "BN254_Snarks",
"group": "G1",
"modulus": "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47",
"order": "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001",
"cofactor": "0x1",
"form": "short_weierstrass",
"a": "0x0",
"b": "0x3",
"vectors": [
{
"id": 0,
"P": {
"x": "0x22d3af0f3ee310df7fc1a2a204369ac13eb4a48d969a27fcd2861506b2dc0cd7",
"y": "0x1c994169687886ccd28dd587c29c307fb3cab55d796d73a5be0bbf9aab69912e"
},
"scalar": "0xe08a292f940cfb361cc82bc24ca564f51453708c9745a9cf8707b11c84bc448",
"Q": {
"x": "0x267c05cd49d681c5857124876748365313b9c285e783206f48513ce06d3df931",
"y": "0x2fa00719ce37465dbe7037f723ed5df08c76b9a27a4dd80d86c0ee5157349b96"
}
},
{
"id": 1,
"P": {
"x": "0x2724750abe620fce759b6f18729e40f891a514160d477811a44b222372cc4ea3",
"y": "0x105cdcbe363921790a56bf2696e73642447c60b814827ca4dba86c814912c98a"
},
"scalar": "0x2f5c2960850eabadab1e5595ff0bf841206885653e7f2024248b281a86744790",
"Q": {
"x": "0x57d2dcbc665fb93fd5119bb982c29700d025423d60a42b5fe17210fd5a868fd",
"y": "0x2abad564ff78fbc266dfb77bdd110b22271136b33ce5049fb3ca05107787abc"
}
},
{
"id": 2,
"P": {
"x": "0x39bc19c41835082f86ca046b71875b051575072e4d6a4aeedac31eee34b07df",
"y": "0x1fdbf42fc20421e1e775fd93ed1888d614f7e39067e7443f21b6a4817481c346"
},
"scalar": "0x29e140c33f706c0111443699b0b8396d8ead339a3d6f3c212b08749cf2a16f6b",
"Q": {
"x": "0x83895d1c7a2b15a5dfe9371983196591415182978e8ff0e83262e32d768c712",
"y": "0x2ed8b88e1cd08814ce1d1929d0e4bba6fb5897f915b3525cf12349256da95499"
}
},
{
"id": 3,
"P": {
"x": "0x157a3e1ff9dabccced9746e19855a9438098be6d734f07d1c069aa1bd05b8d87",
"y": "0x1c96bf3e48bc1a6635d93d4f1302a0eba39bd907c5d861f2a9d0c714ee60f04d"
},
"scalar": "0x29b05bd55963e262e0fa458c76297fb5be3ec1421fdb1354789f68fdce81dc2c",
"Q": {
"x": "0x196aeca74447934eeaba0f2263177fcb7eb239985814f8ef2d7bf08677108c9",
"y": "0x1f5aa4c7df4a9855113c63d8fd55c512c7e919b8ae0352e280bdb1009299c3b2"
}
},
{
"id": 4,
"P": {
"x": "0x2f260967d4cd5d15f98c0a0a9d5abaae0c70d3b8d83e1e884586cd6ece395fe7",
"y": "0x2a102c7aebdfaa999d5a99984148ada142f72f5d4158c10368a2e13dded886f6"
},
"scalar": "0x1796de74c1edac90d102e7c33f3fad94304eaff4a67a018cae678774d377f6cd",
"Q": {
"x": "0x28c73e276807863ecf4ae60b1353790f10f176ca8c55b3db774e33c569ef39d5",
"y": "0xc386e24828cead255ec7657698559b23a26fc9bd5db70a1fe20b48ecfbd6db9"
}
},
{
"id": 5,
"P": {
"x": "0x1b4ccef57f4411360a02b8228e4251896c9492ff93a69ba3720da0cd46a04e83",
"y": "0x1fabcb215bd7c06ead2e6b0167497efc2cdd3dbacf69bcb0244142fd63c1e405"
},
"scalar": "0x116741cd19dac61c5e77877fc6fef40f363b164b501dfbdbc09e17ea51d6beb0",
"Q": {
"x": "0x192ca2e120b0f5296baf7cc47bfebbbc74748c8847bbdbe485bcb796de2622aa",
"y": "0x8bc6b1aa4532c727be8fd21a8176d55bc721c727af327f601f7a8dff655b0b9"
}
},
{
"id": 6,
"P": {
"x": "0x2807c88d6759280d6bd83a54d349a533d1a66dc32f72cab8114ab707f10e829b",
"y": "0xdbf0d486aeed3d303880f324faa2605aa0219e35661bc88150470c7df1c0b61"
},
"scalar": "0x2a5976268563870739ced3e6efd8cf53887e8e4426803377095708509dd156ca",
"Q": {
"x": "0x2841f67de361436f64e582a134fe36ab7196334c758a07e732e1cf1ccb35a476",
"y": "0x21fb9b8311e53832044be5ff024f737aee474bc504c7c158fe760cc999da8612"
}
},
{
"id": 7,
"P": {
"x": "0x2754a174a33a55f2a31573767e9bf5381b47dca1cbebc8b68dd4df58b3f1cc2",
"y": "0xf222f59c8893ad87c581dacb3f8b6e7c20e7a13bc5fb6e24262a3436d663b1"
},
"scalar": "0x25d596bf6caf4565fbfd22d81f9cef40c8f89b1e5939f20caa1b28056e0e4f58",
"Q": {
"x": "0x2b48dd3ace8e403c2905f00cdf13814f0dbecb0c0465e6455fe390cc9730f5a",
"y": "0xfe65f0cd4ae0d2e459daa4163f32deed1250b5c384eb5aeb933162a41793d25"
}
},
{
"id": 8,
"P": {
"x": "0x273bf6c679d8e880034590d16c007bbabc6c65ed870a263b5d1ce7375c18fd7",
"y": "0x2904086cb9e33657999229b082558a74c19b2b619a0499afb2e21d804d8598ee"
},
"scalar": "0x67a499a389129f3902ba6140660c431a56811b53de01d043e924711bd341e53",
"Q": {
"x": "0x1d827e4569f17f068457ffc52f1c6ed7e2ec89b8b520efae48eff41827f79128",
"y": "0xbe8c488bb9587bcb0faba916277974afe12511e54fbd749e27d3d7efd998713"
}
},
{
"id": 9,
"P": {
"x": "0xec892c09a5f1c68c1bfec7780a1ebd279739383f2698eeefbba745b3e717fd5",
"y": "0x23d273a1b9750fe1d4ebd4b7c25f4a8d7d94f6662c436305cca8ff2cdbd3f736"
},
"scalar": "0xd2f09ceaa2638b7ac3d7d4aa9eff7a12e93dc85db0f9676e5f19fb86d6273e9",
"Q": {
"x": "0x305d7692b141962a4a92038adfacc0d2691e5589ed097a1c661cc48c84e2b64e",
"y": "0xbafa230a0f5cc2fa3cf07fa46312cb724fc944b097890fa60f2cf42a1be7963"
}
},
{
"id": 10,
"P": {
"x": "0x148523f92df8d037353fd0bdc6d0febc88c9e1bc568d72c80c58438f6295dc59",
"y": "0x251580663ec294fa4afb8f5ea1340ea281e5ba0faa1adb7b2e5a066f440147f6"
},
"scalar": "0x3845ad0148f76bdf14f752268eafb065c7272721784a8c6bd3a5fa736332b94",
"Q": {
"x": "0x120d0df2c066c27aa8332690053f2698c9aaea773a9116edeea2a5e6f5393f0",
"y": "0x6e79ecf7746a4beecc9366aa3558011dd8ef2fe9faa230107e64f232ae950d"
}
},
{
"id": 11,
"P": {
"x": "0x1323cb93cf5f33ebf21d2c0ba56e1c39fd0e75b1623d3ab160fed44a37ee1bda",
"y": "0x118560ff4940f22e7aec1b92707b637520bf7b740cba254fe8eb1643333dce95"
},
"scalar": "0x252f232224ad7d89266c28d1289098f03226fa84e7905b0df4e1f6cc4e2e897",
"Q": {
"x": "0x10438dbb82ca277773e2769588bb8d65bcf8009d40a913604574ee652135542e",
"y": "0x121a0a03c90102ff699a4965e691403b6b4dcc2b64e3496a8e4f3b08700d90a2"
}
},
{
"id": 12,
"P": {
"x": "0x3a7e0e36a933e9ad5732235e93cec84ae8db3104348bf24312ffcdf8e0e78a9",
"y": "0xb16292ebf8631b3a0692017ea8eb2b07bb701d3adc0b5bd96409c2dbdabb52b"
},
"scalar": "0x175ed37fdee061c78e28d668a26add87007ab0d11ad699cba0cb13ae35b8215b",
"Q": {
"x": "0x78f98145bc4295a54b801aedbfce880f16c488216b94457be42a8ec97cbe9f5",
"y": "0x475ab19f29bd7b76fb9ed7ba68b5e1b25fa32bc975b659b645d53f97dc9e737"
}
},
{
"id": 13,
"P": {
"x": "0xfb9835a1f2a882cc4c7915f0eea2218b0089d6a71bb41c911faf48cab4f7ac7",
"y": "0x20557f5377910568bd2455048f2570137ef59cc3f16a8a21d76c4bfd1a0520f1"
},
"scalar": "0x2c09383033bc05ff693ec906cdcd2415acca073eaae81ea2e75fbe3122d91a11",
"Q": {
"x": "0x2d400e116b98c3a2e522c6fdf5d9f298d5284d9be2158ed867b603b3988d443c",
"y": "0x1cc66e8e310d69bb46c943f5ff25bd212b1830d365e60edb235095a4a19ee1f5"
}
},
{
"id": 14,
"P": {
"x": "0x1cfac3eb7f51ef5c90fe33469dd55b0641eaf4597cfde95f01fe8d0c16613599",
"y": "0x2cbba5c72a787b2f881f24cd62319e39f320c54820068fc73f35afd998c184e1"
},
"scalar": "0x24c5b2ce21615dca82231f5fb0fc8d05aa07c6df4bb5aa7c2381ac7b61a6290c",
"Q": {
"x": "0x18c95d7e9f5f9bf66a4133204af08abc539d03fb73d7dc175f055d640f519a95",
"y": "0x2a4350878be8570f2009ac19dfdc770a9a1cbd22299ca86c7262b9eb6341f120"
}
},
{
"id": 15,
"P": {
"x": "0x1c9d4cd1239bc59ae80557dfb0c86a1f86ec92e749c8722a713c953eafd6ca20",
"y": "0x2081b76f82bc636dfb0ba24e364ca68b6343f0c1754d624decceb3b33b4c74c"
},
"scalar": "0x239c5e02dc84563c340bdaaf4562534b33ee935ff339870b12f9f83eb31a791a",
"Q": {
"x": "0xd2683e06c812e71e114a0b482c563c340017220ee2e8374138a95b658375d12",
"y": "0x27dba973e77c66fb2d85b9964c8377e2779666df06913e77a5e1cfd0f61cd63a"
}
},
{
"id": 16,
"P": {
"x": "0x2bcca4d5e3ee027610989b9e2a5c2bc5dac28833bf25fc700690cc51ad518a66",
"y": "0x1963e6d2f802f31268e0427897cebdf235f5fd0032df916f4d5bea79a6802349"
},
"scalar": "0x23b31c35ea0317455f6d5ae6853938a8fd832b055fb8d4d0544dc4733be5873",
"Q": {
"x": "0x27ed8e1819eff1f3f45955d048322d999200db5f370d10f897f2b8d23bfedf11",
"y": "0x39b58bace54a74a54bd6265aeffb6bcf318f624f0f512f73e36fe5ccd69ab2c"
}
},
{
"id": 17,
"P": {
"x": "0x269da0baac87cfda91dcc696c425eee829630f3eab25975484383528e81d5a51",
"y": "0x1174c07ba95ab49d7684088f744fa92e7cc79d9c1728fc1284d6835e815783ad"
},
"scalar": "0x14d0891e440cbd0fdc4cc55f1163deec34684839c549f63e2b67043d5c6a3b7a",
"Q": {
"x": "0xeffa3daca47b712d89bdf196bccf7d5b6f2936f649dc3e1b4e6a6b6f90d5f30",
"y": "0x199e242082340a9b9bf455ad98e9a4a4f47b79a0cf5d977c48c028237508d36e"
}
},
{
"id": 18,
"P": {
"x": "0x2c0dc536b58de4878fb80632a76fd8c951c7cde2000d557f0c33c1f8c8313edd",
"y": "0xb47958947884ef571ed7c551d610ab2a590b174467dc271ba90753ce8565fa0"
},
"scalar": "0x11e6d36aa05a0b253391de46a38bb640c822a7d2deff7cfa7a2bb4ea21bff46e",
"Q": {
"x": "0x288e0963403093d072870aeb72663e0a8018ea3e2a468463b071bfb90b0667e1",
"y": "0x1de4dc8536bc36acebbe357f34b9924a92ce5e37d438eea27fa7b676c8044b23"
}
},
{
"id": 19,
"P": {
"x": "0x2d7d457d64317fb2ca9a73853c11f0d8ea2f9e9e2059c66445be7354018206c9",
"y": "0x5a5553dc4eb6ebb490ce6e71d7bab9cac50758d604177c20dc94e4b5da6ce76"
},
"scalar": "0x3550d13fb01317874bc884137be3ec9d5cc946b3bc90b1a182dd6c8b24d1637",
"Q": {
"x": "0x113a487d26baffd0d194138d1f242ae33fe7837395ea04a96810993c24d391bd",
"y": "0xb6c771fe1737af1ebaa64f11b5c8192f29e1098d337d884a3695235216bd2df"
}
},
{
"id": 20,
"P": {
"x": "0x22a178cc5c0847579ae8bd3c63f5321c4beca1867c0cc48c3dd8ea5346545fff",
"y": "0x82062ba4cad78411aba105d3a7227b06b1e781db1ea009c8ad8b781fcf3a037"
},
"scalar": "0x2d065d1f44795ae8f9d2739dda24ceb561d3aea6a90f003badd6ac9cf4e635b3",
"Q": {
"x": "0x7e0c8ddb85187d3e787f2e227dda2e8c50f8b4029d3efc895857ed4a4967a32",
"y": "0x19700aeffda9b019c7556f63a992a33bddc327b615a415b11f63fcf963cdcec5"
}
},
{
"id": 21,
"P": {
"x": "0xffcd6e5c952cc067aa3ae121a242b478d5ed96da30eb78ac5588964dd0f3405",
"y": "0x10784735e8d8623beda487cc8204a61f8cee32625b8ac8ae99fa81da11e1bf0d"
},
"scalar": "0xee64b54258e687fc9887ca2362b71c50539c881d43097a0578b58c487fd26ca",
"Q": {
"x": "0x1242743fa09c758b96a19de815b590ca3c96e41f050a63708e328d6b8824f6cd",
"y": "0x2c66161e1eebd84d8447c8e2244ca19d89e746cd932725d27ddc2278e737652f"
}
},
{
"id": 22,
"P": {
"x": "0x2db92ffd62bf2675414c5455c50dcf09e50d5e980d29ae653cdff2e9a67de43",
"y": "0xba1cd7057b33897d1cfb0de452f07d497fa2c9b72e2fe75d2d3fd6bd842aaf0"
},
"scalar": "0x189d5317bd61f0885c9bf39e9c6baeeec2ac555d3c6d1802259a4f4c15e0bd3d",
"Q": {
"x": "0x1dcb7795df1069b2321fbd400b8dea0f618e9998ae1add0de4d2803b559e4ea4",
"y": "0x1e42af695a1d61106d4a38edb8dfecbbbf42f3ac2da2eb49f128fd68b4c76e8f"
}
},
{
"id": 23,
"P": {
"x": "0x2c247d741e5bc1e6354390a0f07abf7fc443fdb57746f87fbf7ef6b29b08cc28",
"y": "0x884c985e9e12a61229a2408ef7d719af9a8424a83a188e37a7948c9e5824505"
},
"scalar": "0x10b16eab8cb4ec5f039a2cf378f20b3c3e10bdba4a877e80f4f4c4627163d414",
"Q": {
"x": "0xcab89c6c816208b288d7a0cef95b40b7e38b8ec2db22340f5c2d7856ed2c5cf",
"y": "0xbf958b6572f9f42934315df44c52aefcd817e9e01ed57f58ba355ba36c971a2"
}
},
{
"id": 24,
"P": {
"x": "0x87bbdc12fea71a426b43a8d0894de8263787a26c6a2afda5bd31f967c65383e",
"y": "0x43e60246efa3a16b03f952ece5e4226135b50a23c10617e7dc4df33afbd4753"
},
"scalar": "0xf0af4b63cb602604a06c597bc2a75e078b15d7c2df37ce42bde69ca13599811",
"Q": {
"x": "0x1e1d152c8165fa773e16f41f2e1c7d629a8c7584de6766788e2f99bf9b186530",
"y": "0x1be496a402f046c95d892ed6a5471781b201c350c86e55530e2367118de2b36b"
}
},
{
"id": 25,
"P": {
"x": "0x286a9ea8b5a65fa0d570635ffca925abcc52a476e602b93c43b1c2b6da1bd2e3",
"y": "0x27fe854a6b39abe73c4ffd44cd4547981e20646501196340dabeabe1beadac5b"
},
"scalar": "0x7188b949fc8499db75ae19842f14dc8274af3e92e28716b76d2adc2f4b9b9e7",
"Q": {
"x": "0x2da7c7d0fd546c27b405a89bf419280d6b819f81dd3171582462b6190f3aae8",
"y": "0x1549fe1b9cb7776eb4440ca4636f496d3e17138012488c88bb18a8bdca4cc79c"
}
},
{
"id": 26,
"P": {
"x": "0x2bafb56f37fc8a4e316d092c509b880c30d67d204602f670518c6f2ee3f7cd68",
"y": "0x70bafbb2d34255884839dd1ba74ed3fc436bfabfff0e7cc2d867441d9d675ef"
},
"scalar": "0xa48591f45da5ad607639073a076ee8aeb56262bfd4f6dc6e138425eaee9c9ae",
"Q": {
"x": "0x1161959e5a97457d68f29ca3c9dc7a8f4004103a8029112cc941a7fc4a29b476",
"y": "0x20edb88979342c2e93cf6d35595e55742c0044f018dfd203fb2efead22de535f"
}
},
{
"id": 27,
"P": {
"x": "0x90c37ba887ae51975dd3a8dc177ae15bc2aeea4fcffb633ff6f5db5622690c1",
"y": "0x1b4ae8767b6db3b805a3613b868ba8480c1274c2c73c718ded8ee0864d7dd74c"
},
"scalar": "0x1829df2cce135c94e4a6f8c72128a68b53d8aec09a30e810c08cad0143ca5e18",
"Q": {
"x": "0x2e15a14af81f9806fbb1291b288263909981660d02477da3aa05c82fe8a25497",
"y": "0x258601e8f86b19d7c74a4cb809b279293f23bc9c8f1ac4d8309a70d8c27c24e5"
}
},
{
"id": 28,
"P": {
"x": "0x29afb0bb8449ddac50717e1d25dad62984a701983697a63336e45daf7ea97c9c",
"y": "0x12ad7ecdbe6b656bf44e2112d1a5a87b2bc0f4e3234750b11ed9ae76453dec06"
},
"scalar": "0x1100331edc8dd561f57694f9f4a32f114e56bf756c8a2ba87df8329a10aa4b12",
"Q": {
"x": "0x16a63a16bb7655074c9644fc24aa0f4cab61bc8911d381caf1af56da841abc40",
"y": "0x1dae466d5ce876acbb82fcbbeeb91998bd7850867a946db8057602e284aa8cea"
}
},
{
"id": 29,
"P": {
"x": "0x27d918bf7e8a2c83ab637ccfa423f00591123fbf84ebec990969b99e06169787",
"y": "0x2da54f7e40092f3a81a8ecbf9bfe354619323f27bf24b29424890b97a6a8d4a1"
},
"scalar": "0x1264f8b6760ae783b91cb825b46ad015e45e924b32a562e931783f6c7ec63dca",
"Q": {
"x": "0x29069738e5027fc8e11e33bf945fa0a297c260308aa76d671b73245f9ee20ea8",
"y": "0x22f63c9f6ef28bfaa9b21670ba6a1018f2fb6343e6646d163e15ebbe5281a9a6"
}
},
{
"id": 30,
"P": {
"x": "0xac4f28b816c1535dc5836f0ba51bf862b70ad57b005f9c8a4a7fcfbd451c8d3",
"y": "0x6d671bd0457bc901a8be991245beb1295b88ba7029d28faa75e068b923ca224"
},
"scalar": "0x3417abf204bc2907b42045f9510693a4af18151888ccf75e71c60c663b73662",
"Q": {
"x": "0x209660c6039d04f8126d12e8c2c120b0e0d29b1be28497eb3079b392dfdad047",
"y": "0x15787779e685921f84f48164ad397f8704f95544c967e1b5cadc6ec87803b8e4"
}
},
{
"id": 31,
"P": {
"x": "0x1ef8341f82f694e040910e68a54baac4a378d52cfee4aa7335550e8d68ad1c6e",
"y": "0x7a314c51e78fbe5e82d1745af480d4f34d60423a284de5c85fdab64036c5f29"
},
"scalar": "0x2588e331d2f9358be1ff4f9676d69fbad43de58d1aac365d57f8e3afb56b61de",
"Q": {
"x": "0x2921003fd5ae988eb4e3abe9d2ee2627b91eb9f3ae6fab449726252f1de8b06d",
"y": "0x29b6473f15f5f5708e94da2f58aeda64bc01a2e909080f6c6cb1878111298c70"
}
},
{
"id": 32,
"P": {
"x": "0x250311f0f95137a190994efc75d99f648a43448f5c7238043a71eef42e4bfdcf",
"y": "0xe49093f8626ad7dc79e939ee7304110492fc32e54fc5af21650e4c131299fc8"
},
"scalar": "0xd9a3b943988f2af3457fefd358545c6c936c6ccd08c0a6d6b2fbfe1ad2c5d76",
"Q": {
"x": "0xf3940be3578ee5217a73183bc3423258dd1aecc1319d34dcc289e919182b5c2",
"y": "0x1fd9fe47073c4637862c54acdb7190729b05393b44ac7b09ceebc6f11c80d1a7"
}
},
{
"id": 33,
"P": {
"x": "0xabbe56709797a29e6aa061e256705e8d1cc9656a652590fa0a42550d009adb3",
"y": "0x1e07308d7c31e358c009a351f876e446c649bc1e6205c149ea7f63a9f1b1eaaa"
},
"scalar": "0x146aaf961442cd8e3c214282d56a2b893785cf1a4d174c63c3129362844cc400",
"Q": {
"x": "0x2e4194da91421e3b886094fe90da1731da8c2f12d25b9547416e8ae39f1cdc0c",
"y": "0x5fa2d16ec410cb59e12495b26b3a416413fbb124a3836050a64b838a0865e5d"
}
},
{
"id": 34,
"P": {
"x": "0x2fa7c6743d9decef59938ab82f516ea6726437d94f9527ff653ca51ae542a60a",
"y": "0x27ffcbd0152613190d20d0ccecdac848259e11f8444f2299e1206b54732287ea"
},
"scalar": "0x170c7328a9b02a49c7fa0ef3a8459baa4ff5dac0a6ed9e6bdeb58d6815c3ac23",
"Q": {
"x": "0x19b897c2f3dc81a6e37816501d79948c9589eed59039bc44ed5991170982dfc1",
"y": "0x2dcd36676c98c4d0b213ddcfd80056f677a315a6b90fe86d5aa3aef3414074a1"
}
},
{
"id": 35,
"P": {
"x": "0xc367c0d6b1503eef66d7e53525577620ac8049000ba2771d604034ce96bc261",
"y": "0x11795a4beb65c948647108a8ee08c1a58b8ad3fdf6c6b9b08d606d23a7a36a07"
},
"scalar": "0x20a1d8f998224d7e4a414c5870264c91e94d73ffeefd88aeb7a357a91cc693bb",
"Q": {
"x": "0x1c798d139649f4a497c4ccc7f05804ce44608fa8398cdef2b11110b4d72d24fc",
"y": "0x66c89ffbfa21a48f67f093fa68596eec75326014cf505b766b8081df2b6958e"
}
},
{
"id": 36,
"P": {
"x": "0x15cc528dc3ee524b4be51b806f6ac5c22c2a99e433ab2e80c3e3947e4d79bc71",
"y": "0x172f8322bff2a9f39c4610080f132e63015c5e1c3f64dafced095592ddd9e692"
},
"scalar": "0x2131557de2580fe5626cca0178dea0c95d37c8c75c2f544dc9cd16a12d6c2bb4",
"Q": {
"x": "0x246494ee5f7b1cd5b500551a05f879499bdef0fed91ad9d2d58c1f68744fcf6d",
"y": "0x3fe38e36892e297104cb0633b2f9e77c3feda7f1dc9e5e6fe04814615d906e7"
}
},
{
"id": 37,
"P": {
"x": "0x2eb90ccf155f1cd2a5cd3f8431c9dcef8219d1ffe19dd097cb876861827bca7b",
"y": "0x4bd0a99b1feac1656342e540c78bbd6745daaed022d715b5b932e8394f37b84"
},
"scalar": "0x179971bd22e6b2fa24084c299585c90e4a361342dc8d66f509834e0fecebc207",
"Q": {
"x": "0x4d2df13d44060cda50ab3d8253f505c2883dc4bba4a7b6789ed6cf65704f627",
"y": "0x2762d6f9679571a23b61cfa145ef70f484259140cc1acf8e3f72a9ce509c42a4"
}
},
{
"id": 38,
"P": {
"x": "0x98f659dfffb09983c2df3d4065c145e9a5c55eee35a0e8ba7e6ca10335ebd0a",
"y": "0x26ca3f6a4ef7e153b2aff8eb128b66cc0fd785798dd2fb2ce9e93d3f21d5c2a0"
},
"scalar": "0xd207e98eb1a813026ed20c3aaac9a1547196f5c9075e9c9e66bd668d4a24546",
"Q": {
"x": "0x30ec5502cbd162b474bf5619ea337b6b15b95cb76db073778a43d47536b3832",
"y": "0x6e9b07f044e7006348caec8d291e404871575bfa71a67fd76f45c8baf1cedee"
}
},
{
"id": 39,
"P": {
"x": "0x2dd2bff238458805650bb7cbc4f87bacf2dd44fdc225cd3c7626c32bd5899cf0",
"y": "0x2369f39c1a3b5b5fd20e926596513d991e7ac335dd933ab15acb08dfab1d1c64"
},
"scalar": "0x167a229b0b49c002b74f08059a6a88b004c9a9a71d596073e5d8f1eea9e7b4fa",
"Q": {
"x": "0x772a85b2c9443913c47f445275953bce7abfcb412c57cc94f61f53219108d3b",
"y": "0x1b995df3d365563c885ac7442bf629d40b589b865f6585cf0d5d1ab6e4512dde"
}
}
]
}

View File

@ -0,0 +1,980 @@
{
"curve": "BN254_Snarks",
"group": "G2",
"modulus": "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47",
"order": "0x30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001",
"cofactor": "0x30644e72e131a029b85045b68181585e06ceecda572a2489345f2299c0f9fa8d",
"form": "short_weierstrass",
"twist_degree": 6,
"twist": "D_Twist",
"non_residue_fp": -1,
"G2_field": "Fp2",
"non_residue_twist": [
9,
1
],
"a": "0x0",
"b": "0x3",
"vectors": [
{
"id": 0,
"P": {
"x": {
"c0": "0x1625bf258f7f7be15ee438ab65c97393391fb36133cbb17c44c98efad3b04f06",
"c1": "0x25e9e71cbbb71cc1720d0102a7015f1224469a5e45c80017f4c212f34134294a"
},
"y": {
"c0": "0x7cfda5f906b107ff2477779f0d03d4795049df8125d8131316ab2bbe12acf87",
"c1": "0x11f787a6cfa5113a8071d6e502b0644a8884b353d6a93b843e21b6d6803d42e0"
}
},
"scalar": "0xf4a990ccca0053b6aeec01ed669ae5134323e4a9bce7e9d4e5ecd1baac01965",
"Q": {
"x": {
"c0": "0x22c922cfbb5952b437336aabec6622d687d9504bf4cf5669425b7d6a63876336",
"c1": "0x5af7544eb37275fae5d085495815fe3780c013d894ce6897d29b6da8a619df5"
},
"y": {
"c0": "0x2e47462b6f7f5f047cfe4876646a30d58329a90fcec0a8dbf400e02da8730d0e",
"c1": "0x1c48a7e54d8a93329dbe2530d02408a52e239e76892e39b50201196d429d62e0"
}
}
},
{
"id": 1,
"P": {
"x": {
"c0": "0x2879e40e222aca781b2bb47ad1c27693b2de5b47a33447d656fff119eeb3dd8",
"c1": "0x2f5421a2eec78d1b8d8c287670cc09577aa18bef3d24ae0b83208582e3234ed6"
},
"y": {
"c0": "0x1554127f4db7b8cbc926708ceff2cc5a3f45ac8f5d1f9606e128d112d0f64e95",
"c1": "0x26cefb017e2533b8bd31d5eec61f4b18500ac3a6b0bdae97b7f6c43b1f060e1e"
}
},
"scalar": "0x237a00cd09f8ab026971e5e8458cc54091f091d089fadf8346fd0698c759173a",
"Q": {
"x": {
"c0": "0x1fd7fc9a078ac3aaa9058f70adae0fa1e7e3329099928449607b044beda3e53e",
"c1": "0x1184f64b41778079e13b410a45132ebba8834ec11d80b5b84012814f98d7f842"
},
"y": {
"c0": "0xd80c38032bc4ad41d9f65293f099dd9f51c9482286e911f3b753a492f66a39",
"c1": "0x163a788d60c0028016a7f8a36b5f3aaf540db2a2b1809ed09f9a0a78b2e16569"
}
}
},
{
"id": 2,
"P": {
"x": {
"c0": "0x217f7bcdf4bd2611cc5aedccc5d14bca0e7002b3542a18aebae7a50877d98d6b",
"c1": "0x1789e8769420a2c63f4061d774afebb3dd0edded0fff4a44af9be4ddc0afcd6b"
},
"y": {
"c0": "0x1db3b94f333d245dca5320e98154ea865de81bbf0564d1e31dba3ff4d37ecd1c",
"c1": "0x822b0814347b4b26c14394e74d815cb895f8400a3ce850a08b0cb86dfa6b63e"
}
},
"scalar": "0x6ed213f37703ff64c3d7379de22249ccf0881037948beec3cdef64dd024ffd4",
"Q": {
"x": {
"c0": "0x14f253bc0ef0908c0436372cd91be89630371cbf431d88b59e7107dfd73f00d3",
"c1": "0x3eb7edea7bc0ca9790e0e39f5c9501adb618de554b6c740e10eeb89b42412a9"
},
"y": {
"c0": "0x2392105914e19a0886e7f332675640acba379d68f68670fff8b059a9c7d2a29f",
"c1": "0x28186248bbb018adf820e02125583abf14c3ac2c13a2c7a471bd38fb18d78fca"
}
}
},
{
"id": 3,
"P": {
"x": {
"c0": "0x138e20127a6283933575ff28e92f9ab38f556b3394b013bcc96be77377030de8",
"c1": "0x166dcad5c9ecc01f6a93486e12e664dcb4011a1230bc991790230602008a18e1"
},
"y": {
"c0": "0x190bbd99c0d9a0d0c6ca9287d8b69f3a5284afe4a9fddff4d4e10d9ced271163",
"c1": "0x53a8aabaed6875827f147852922b8ac6c5d2951e190bd46f814450f68c4c14a"
}
},
"scalar": "0x62bd5288cf20a6e36f17d948a80e2158ce1f82403053e46dcc7ad5abc661ade",
"Q": {
"x": {
"c0": "0x2327f8e27eb45900c7c18b3bc2d4693738fd8437dcb956e1683f997a4f141ea9",
"c1": "0x1c4264bffd9416c48cb49bd47db3c3eaa8be281355c3ec4f4484833a7688767b"
},
"y": {
"c0": "0x2a86f85af9d45fa3299b95d13f5de1fd14e039bb6803e3b100354c437ff247f6",
"c1": "0x1f856d131816c68fd05d356fdb7a578b4fb0ec201c14e8bd43ec4f861ca758d5"
}
}
},
{
"id": 4,
"P": {
"x": {
"c0": "0x4b6ad5b6cb0fabc25f5a66a3979858b8fea4eebfd1a4470e4b3a6924b006112",
"c1": "0x27d3e3b73ffda5ec398157a3ff6dd2380ee6b2d02faf28bc2baaf23713e45dc"
},
"y": {
"c0": "0x290902771c94305e47b0ad9305f6502ee38b9687791accfc1b94e8b1f4d74810",
"c1": "0x1128ed5d7a58ee5cb2754d4307d6465832a64a1f70675cf3e0581f3d2e0b9a29"
}
},
"scalar": "0x97f69fbd95814f6029b0b25c25d3cd15ff9d8e3497a4a0b469c800682a838c1",
"Q": {
"x": {
"c0": "0x2be93e870399723371767c8f79a83b32074a9b71ef0f336aa378447ababa702e",
"c1": "0x2bfc6251f2342c16928c90a5991311ad62d5ccfaf8b200cf7d0d6ad788049b6c"
},
"y": {
"c0": "0x4b2d7d2e98996d55ebae20deec2168a437371dd2ae297b0f7ac037832d61567",
"c1": "0x24fb06fe3910993b775361f3ea897bff48babd7185d29fcf12aff7f7bfe68772"
}
}
},
{
"id": 5,
"P": {
"x": {
"c0": "0x23564c0191c7c6abd3194f357ce83ca3a8fd08827877f1f5bb0d406f0ed083d",
"c1": "0x5e39d7bdea1ff7c795238e7efd1822f0ae71bd399e209c6bf52697f8691573d"
},
"y": {
"c0": "0x3a9039a328db0dcc2e83c128c346102c8ae83c566c9abf3ac1eed35a0798c79",
"c1": "0x275e014c9ada99807e67fdc03fc99ac91eaf4bc7d0a9ff849fd92fa967739dec"
}
},
"scalar": "0x294ea5041de649a34abbbe380b335da0bb773accedb844ff6a930891162bb69d",
"Q": {
"x": {
"c0": "0x195cccddcfa00e62b841339c6b5637ecdf5210354cfc25588f30175882b059b0",
"c1": "0x5a63a9161d1d1059673cd19aefa756bfb2c11c9b68be099776d7879d63053e"
},
"y": {
"c0": "0x1c8efcaf1c31a9ad54f4c62813761070f7e79aa351df482980d3bf01483d862d",
"c1": "0x1f515e9e34e542014fd6361cc1c39fb31f7a423d30dabb74a1de562fb4e23cff"
}
}
},
{
"id": 6,
"P": {
"x": {
"c0": "0x21148bf49f36d6a0b688e8e182e23618de5dba4da3a33b46234d335398c0fa26",
"c1": "0x16efcc88d5c35644d24ca75f4d1387e17a2539cdded78c7c04b04ceddf58084c"
},
"y": {
"c0": "0x19356eb4c5f4e4cb73621fe3bc7364670953f4a46d3df8e27c9ace79da15cdef",
"c1": "0x29c2ba4bb71ff8996086533c57d6c68b08f6c20a01ea401382345b49dd28ac4c"
}
},
"scalar": "0x50a411bbe00b5c8dedd665e8c340cf4ebcf069bf923007ee79c152bb3a9f6b9",
"Q": {
"x": {
"c0": "0x25043c3a82ed42f8696774231e5de41698ab505ec566787e36fb39a8c4bd30b2",
"c1": "0x289d436a295bb2153ffd32f4f7c1067bdf2f4ff04d3419dd3597c01ed5dc6d95"
},
"y": {
"c0": "0x472b8526ee3ba91ce30411d13d4f0f5d3149b5357b4915c196e288f7bb6440e",
"c1": "0xa6979710f980163ac60fed61caf1756aa5e7cd5101d25bc84ddd55967ef22a5"
}
}
},
{
"id": 7,
"P": {
"x": {
"c0": "0x1dc9f6fc6333e87e61814f57771db1c9b67a9e0ae09abdf7018548b7b5e9ab00",
"c1": "0xa217cbc3ee71086e819f637056b41dd8df67a8e792588c81212a47b6e63d0ef"
},
"y": {
"c0": "0x957d0624e802cf65edb5a0555618e82627e10c2468d09f8c050f398a22be2cc",
"c1": "0x12b7f3ee937b92194a854d050e6cf3cab7fcaf030810ecba6fa865f58440090c"
}
},
"scalar": "0xa62755eeb96c240521f3962964b172b10aa81ca1bde0568f2ff2233c5951432",
"Q": {
"x": {
"c0": "0x117822fbe06340aeff058c09cd4fe8d8d0704919ed867c3e8db110c7b98d8a5b",
"c1": "0x73019cea0f6317a6afee0d17d32d293bc8d318258fb42b74929a8b11fd814d0"
},
"y": {
"c0": "0x23afb7a93df0644486043d17c8503b5d0775e9b764ef2cbdf631a525c9f6c969",
"c1": "0x122bfb74f993e0f8eba1f2bc1c20364c00e7b8b715d55a0c51969d2eb041fa1b"
}
}
},
{
"id": 8,
"P": {
"x": {
"c0": "0xd9e4df25615df57f4c97d3b17c15bc5544013e9fb9f3afa4da7a6a21e477c32",
"c1": "0x1193a47f2b2e39f9f14b884064beb6c6d12b2d14f2351082c01f272f1ffb2e98"
},
"y": {
"c0": "0x576cf91fb6b1e55f9cc4c2ccbae2248ad543ef6621ba23814240cd805b9099c",
"c1": "0xe784617111a3f0997184f9f267ce0b7c918434a1a69be753ba9487cce2d4dec"
}
},
"scalar": "0x2b7c3ab242b02a049035f52d290668e6e2b9b6c7494a05db7fc4ddfed3c5b698",
"Q": {
"x": {
"c0": "0x509b503e565b8b03b09f223cbdf4e36db24608b4c65f0f2fd20f332babab834",
"c1": "0x124c60059dc34e1ba87375614889461b88467b8f1fd61bf81e372b6ec16ca7ba"
},
"y": {
"c0": "0x2fe3320955e6cd43b4b9ce2ab447fc363cecf281d0c8ca2bbe14947bc846d4a3",
"c1": "0x1e00db47a89a971f9996d09e1f42f488519283d2543f775a66b9164834bb3205"
}
}
},
{
"id": 9,
"P": {
"x": {
"c0": "0x21b01e9778c174437317bebae850a5d8a487364fcc4e8df8b57d69488746fc02",
"c1": "0x16608971f6cc74714894ce7f94a73b056b0b5d10308ad29c91e2b15e965e0eb6"
},
"y": {
"c0": "0x28d909f74ac4627ea269ef580ab6fbb89137bb60485fc5063e55d131468f0870",
"c1": "0x152d036d9b123dfc285fec76dd270a5bba0c808ad07a77fe3379214b1b07d12b"
}
},
"scalar": "0x16e34632d04259cd28729c6aa8f882d2a6b12f6a8ba0783c40d8bb05fd8a10cc",
"Q": {
"x": {
"c0": "0x2ab9533e327cc2dd689d2734347a8ad9f96df7c5f7b25393b35ac9164d3584c8",
"c1": "0x2c28adc9cbd4a25529751ed71c1d09dc031e4400980953f9b6e1c2d1fc588f42"
},
"y": {
"c0": "0x16e042d64372dedf99cf43eec9b42f4672554f6e9e4e96772e6fc36d2b5be51e",
"c1": "0xa21fa3def1893463fc49abdf768af367d8bca7f2ec2653d92d3468f8208309e"
}
}
},
{
"id": 10,
"P": {
"x": {
"c0": "0x2bf7345bc5929ff5c5bb62713a31d4a3f4dd0e860bb6f4cb122c6a353b85cd19",
"c1": "0x1ff9a1bfb398237db64a0bb525c9a9aa7082991e605081b92b4c89db03e3cc03"
},
"y": {
"c0": "0x6fcb9e09b1c66ff84ae29b4fc285b82dbc0381f930e10988fc5af68abfca345",
"c1": "0x13fa9fd4cc0edee469766b634870cde0f58a03d0efe003fc24bc03c426d5f8da"
}
},
"scalar": "0x1a01c730b207403d5762c950573926e60ba1be22d9335c1cf5d1829133028678",
"Q": {
"x": {
"c0": "0x2f1e3744ac84bc068a2e28e353c0af3fce76fbed67ac4a9e82e36535a02d9128",
"c1": "0x692eecc8b72dbf74dff27201a1e5a0e0a5144b15beffd8e206df39cb2a4200e"
},
"y": {
"c0": "0x1f6f8760b0e1764c10fb05907b3edea41e72ce693beee777d6d760e14e21b065",
"c1": "0x1c1224abfca140b87694e4b46224f253774f158c1fb759d61768e6b15ce9a4ba"
}
}
},
{
"id": 11,
"P": {
"x": {
"c0": "0x109c14490ed62687438d8dd7007d6ac7deb77cf3fc3b7bd8e39235f986f1fb92",
"c1": "0x15a0dec27bf7acbd07180ef95c630be20ecb98a5f45910afec7c8a12d61c9b36"
},
"y": {
"c0": "0x12b3c56881d71eb432b14dc9374b9b22ea6197ea62ced1cc2fd05ac39e647421",
"c1": "0x21e23558302df29d7ff50ce65e01bc9bd4be585828aedc335f87f602e36907d1"
}
},
"scalar": "0x7956c3f46bf864013a6094c834e0fa4ef376155f8b82e34fe46e1f69b999566",
"Q": {
"x": {
"c0": "0x1d3001f49e1d6cc80e4a896bfdbb59d5c5561e9a631eb2ba5205183a29d85985",
"c1": "0x22da5a5842443add54617a699e02b3484978f9077eb220fe9e625e4d13909f77"
},
"y": {
"c0": "0x21f77214405cda2133b7a632cfada2f9ff6e675c185fada3c26cf13df49e9267",
"c1": "0x193f4814b6dce57dfdea8efede35a46e1d045d1d82994e058ea02cc28453146a"
}
}
},
{
"id": 12,
"P": {
"x": {
"c0": "0x1908e3869a722ff619a8f7a1ca88c05e8601a6ced375202caeb1bddcbba21474",
"c1": "0x1897b1be2b561d304a535d81baa41f958e74cdb7d5669e497206a7902e15dfe0"
},
"y": {
"c0": "0xecbbc55a8216d5b0cca24dd596043223f30ebd8f327e2bc9c1fa5184eca3202",
"c1": "0x16e77962a9c01c5dec89157a499583748619523d068c05e278cfc8ac7ac2b7d8"
}
},
"scalar": "0x4d9f07fee76f37cebe11d120ec1e3613118c582c1dac76b61bb69d23d72ff7f",
"Q": {
"x": {
"c0": "0x232b877cc05a03ada12cc34057531c71cd53d339f85e4133cf60a1d1b3aa758c",
"c1": "0x11f31ce793db86ef6529a77bd34f4651a807c83ffb3e984bfa7a4a016c371238"
},
"y": {
"c0": "0x23b56c577cc0fc092693148224617401669eebc485bd6a2e79b2e26dee869d78",
"c1": "0xdcb2841256601aef96212c32429eb843d59d62011c96fadac12777967a5cc4c"
}
}
},
{
"id": 13,
"P": {
"x": {
"c0": "0x302432e20af8e20d27b7054c63a1cc540b1464d0cf9c0b9bbc8d0112fd343417",
"c1": "0x1f5c6b889a2c7bf2079e7f34b73ce802e353bf53385d27fb9393641cbf307568"
},
"y": {
"c0": "0x2236105495d21f489543016ba5e66c21790315b81771823702c4f2b9a380348e",
"c1": "0xb95a470ff3f05f70927d9f7765e6990a111a3a94881eea2030ab319b878335"
}
},
"scalar": "0x2466d8b753c5607fc0ed25f3abc2b8e49ba634729d17f9ba15354be968485128",
"Q": {
"x": {
"c0": "0x17dafede288693f75ca925cda9c06b907d31f448299a6aff3670f92c7e5926e7",
"c1": "0x1d89b343eb09f2499c2ad1f4af7b2ab54ad612d19c4887033412fa84e8e65513"
},
"y": {
"c0": "0x3d8790eeae16b8256214d9409ac50b7232e5d8525cd24ca25db8b6798f721df",
"c1": "0x1cf730421d4b12317ad15133e78d6f34454224627268a96b4e85e66a13a9098c"
}
}
},
{
"id": 14,
"P": {
"x": {
"c0": "0x27132f2e2b576e1cc8e2febbbfaf01e5dc08726996a16571b6571f7ae441cdff",
"c1": "0x10e1124333039ea19e949f26ee27798255d861a5e2eed179095f3347158430ea"
},
"y": {
"c0": "0x2c99b1596c926d7ad21b85479d7904d2a6dc4f04fb668f1a410acd631861b033",
"c1": "0xcc02ff98d9fb7f55b86cd87f36230f72aaf2f33dbf6c68c3d39f0650e373543"
}
},
"scalar": "0x1949dd8dd4cbb689f5d7a927d8ebccb408e1e834d71afb8f8eca1a1b71a58fd0",
"Q": {
"x": {
"c0": "0x2b4bdaf8b0696e58f8b5224e78acde1f0d0393c1eca1db41d659b7b297d60b05",
"c1": "0x2a71e1a5d86dd4b8a02c79446f3d856d86c904f98a4f49f9f06018b0afba34f1"
},
"y": {
"c0": "0xfd340f1ab2ec6940b71b1d9b5113bd540e2c44f2efd9f1d1d018eace033473c",
"c1": "0x70652f3b671e7c19216b980d0dff46de60ffae0b6da5fac9abdc68283e6197c"
}
}
},
{
"id": 15,
"P": {
"x": {
"c0": "0x2028c3037f5231fde9f97814139035bbb27388a62133d0c90cdc28515542b15",
"c1": "0x125ed92f49dc022404bdd14d7e363edc8522ee9b6251d2ad11abe819aeabd4de"
},
"y": {
"c0": "0x303baf7faa1e69355bcd0ed6c23a3f0d6f99459ad6392117b5f5d8b208ff51f7",
"c1": "0x18cc98c778e550eca0dc91f7b17286aaa2b644fd1254a0f9f4a5c802d4280167"
}
},
"scalar": "0x27f0f46b6590a026f9cfc665f9e94aeba10fa6ba994e91e4aa0b8aefd44541cb",
"Q": {
"x": {
"c0": "0x420b39ccde74837db91b97987c87ece42df33f7d27d796eb2a4b443542f4b62",
"c1": "0x14325548a7660ee26539f6de03edf8311af51af5d9ea9895b79a7e82bb60bbf0"
},
"y": {
"c0": "0x261368848e83e5faead719dd9170a707d80dbf47d2afe9cd54cc31593fea3c63",
"c1": "0x1b5ab5f305282c727a93c1a36386b8ee7dea181238b0811d34612b7254fddc5b"
}
}
},
{
"id": 16,
"P": {
"x": {
"c0": "0x2d3f04726387c68e15470de17c2dbd151f0fa68b2932f41df54991c9fce9d188",
"c1": "0xc8eab4369edb20710234ef85b76b8ab8877b14746895ef776f4c9222488919b"
},
"y": {
"c0": "0x11bae76f68738d51addcfa80c2c4bb887bca77eccbb1b99dd3d7cebba0ec6363",
"c1": "0xc5a9eb14dd8e417783130df881004eababc90013337bc892e0875db91872c2b"
}
},
"scalar": "0x2dd20fad04b440639afba585fa9fc769bea04e212767b61c85e7f59084ea7c39",
"Q": {
"x": {
"c0": "0x16c02847860121906d64c32d69ef930b1e570bb3588ee30aadab869f2fc933e2",
"c1": "0x24b6e1d61e00665fd118876420d63f7662a7bb207ef08d7c86cc1de6cd5d2c3e"
},
"y": {
"c0": "0x1fc04064197a9c8246d1f8776c2d0b4def63d2921750f1bf9adcf760a9b628b",
"c1": "0x12977ce225494368c151ce50e6ed0a981ce1a6d56864fd278f109c6d0429aa12"
}
}
},
{
"id": 17,
"P": {
"x": {
"c0": "0x18bb780ea6c8645cf075cbaf795f9a8d416753b06d379f24b20d442c79b47de3",
"c1": "0x292185bec02a33685af4964d7a340a5e32b26a65ee14d7a4a0a934c5be680d1e"
},
"y": {
"c0": "0x5effc675b73e313e692318045e2533ebf83e0db6e394ad19a8d6dea35809057",
"c1": "0x128172f6033034541003d3fe5d6f7e7e8d2fe2c8b35ca5225371673c43a78959"
}
},
"scalar": "0x2500d86fee9f6801643bd47690616623d60b41ce7debb349a0a1ffc2995735f5",
"Q": {
"x": {
"c0": "0xecb96f1edba266b95b5d51bafe1d4aed223df726f7923d3e02fc9f181ea5f2f",
"c1": "0x1b073668584a22fee4312828d4e8a59a9c5f12401dcdc051054f9781f02e1a03"
},
"y": {
"c0": "0x5aff779731663c94fb6b8c84bb8c10667add1d1d72b2a58f4c1ac04b5ab16a2",
"c1": "0x88aad66912e2bc5552f477dacd4e155e0ebcfdbc525803f933129c9d21405ae"
}
}
},
{
"id": 18,
"P": {
"x": {
"c0": "0x2b297908bd6bc5e802de7f6d7c8ece5d995bfdf655dcfeed677f281b23e47eaf",
"c1": "0x2f3a261832fa2225c0ef01bdceb949ae57c915b0418c69c978200b22eaeeada8"
},
"y": {
"c0": "0x1322578ec154e61e08de18cab576b8acfbca2b86f59dd1cb05fb86b8fd04cd2a",
"c1": "0x2d74b82585f9021c9ec9b54f3f63c8689017d4cae96ea97d94ffc83b0c02abe3"
}
},
"scalar": "0x2ba6bc9761268479c5bb78f71937ca3d906fd55a9715a2e19880f24da75b2c1f",
"Q": {
"x": {
"c0": "0x1a1e97b5e0936ae9eb51d892f1d699db66fa78f558b521ebea29b5402b22b34d",
"c1": "0x24b204328c4a42caf6d48b33b9fe657d47650ef4475adcc459d9155c139cf054"
},
"y": {
"c0": "0x1dd15f3536e070c3822cca3b2db7a85241fe46a585b6c6aad25c498e122469e",
"c1": "0xc05b851aa525815c3d4e695966beb3940afe41aa2e45678bd055cc3f6da7936"
}
}
},
{
"id": 19,
"P": {
"x": {
"c0": "0x4a5f8846d3d83d9400fe0df8a742f92fc4d855549e80a59494eb6330a901809",
"c1": "0x6734e58547c4847414c9169b24aa4635e36a29e2e276d7f43fdfef719f1e6b1"
},
"y": {
"c0": "0x124abcb2f6e30f1ac934024d6289f39f38c64dffa7e4777bc1d84be4a4b2cbbc",
"c1": "0x142c259c0853ea1883435ce062b69eeb36d353b279c47e550f80ad030d29a299"
}
},
"scalar": "0x179577966033c6378dc25ba322a3ab4eed87ac1c9846356ad27ba6a789409693",
"Q": {
"x": {
"c0": "0x2223d6f800d2c749b45aae0a292641a84fabaf59fdacaf6a284a49abf8d29510",
"c1": "0x2a759798af0d0ee1d151fa6cf4937b780ed52b02f4cc40b268214c14434494d6"
},
"y": {
"c0": "0x2cf8a4beabb7e4788255c6af321fddcb23c0410d39952f01ef715bfc5b5e50ed",
"c1": "0x1695f40286f934f43a36d7a80144e9dd73692c889513bab03d2675edd4c5f351"
}
}
},
{
"id": 20,
"P": {
"x": {
"c0": "0xbf5be6c3fd3d32381ea85323569316e96e5ea246b0f8e965f5a1af753633d89",
"c1": "0x1489a4ef0d17b19bda82416c70c4aa664c8c01ac6d068925147f825b0ae283d5"
},
"y": {
"c0": "0x197a969987ad91be0e9bd2cc0acf469382eeabda4e083f7014de9e32652b9009",
"c1": "0x10a438eab3483a12c88772d57ec1a922f646ae7cde7b5fec07b3c32bfdbde60"
}
},
"scalar": "0x18d9b30b25dad3a84a63bc3497173c7e3a81db93f245eefada200b467e8c5287",
"Q": {
"x": {
"c0": "0x97d5910d627fc68841440c73a8609884b7a84199640fa43dcc1651979d9c2ab",
"c1": "0x23c270484cd4d90f525219e78d7e1f241ce191fb855d7c48e45b95825de46cf5"
},
"y": {
"c0": "0x13cf2d1bc2493a1bc3e4a0ac0bb1eca6bc1883d38547f8a531e2e0c5a8ef8059",
"c1": "0x200228eb0eb0be6dc1f4aabd7be75800fc6c85f533c7f449d3cb705a9dda4448"
}
}
},
{
"id": 21,
"P": {
"x": {
"c0": "0x23bb6760b60ef32b724d4bd1bc86bda3214796506698302b5f892ff94b8ca518",
"c1": "0x1d02236af6fb6684867bf8769755f9a1825bd7c21b5bb0ebf0cdeb953d34f1a3"
},
"y": {
"c0": "0x181e2be90a70e8e9c0dad11e0c537d3305104d9b9d505ca944e1b0ed0ee32395",
"c1": "0x23a886311223de7f4316b59005c48eb431bfff717e135f6cb78c5c12aac8f642"
}
},
"scalar": "0xcb6fd81d09d7f41c6090e93a46c66a8cd8248b97a2a5f3d8f0f0c8aceb4d356",
"Q": {
"x": {
"c0": "0x15d23d618934a1bdaf6778176de447c78a3effc0e47cb3b14f10710207b11ac",
"c1": "0xbdaf3ae6d74d5713b88c13741b65762a2f748026ffcfae62349b93932c2fe97"
},
"y": {
"c0": "0x1dd1905bd866d0e934fe933f24e5867ac2b9ac3ab4129642da3b456d44ded8ae",
"c1": "0x1fc43bd941fbe7c682c0fe6a7cbfe42b244321bcb5212a7e75ce368d812f3b46"
}
}
},
{
"id": 22,
"P": {
"x": {
"c0": "0xed121f410e970ee41fe2927eb1cf3f9a55aa004ae3cd3e630509da4532e49bf",
"c1": "0x3bced2117f94147d162193366f039baceb403394c43ef5cee56c61f1d9dc013"
},
"y": {
"c0": "0x2f7835844306788b2aeea63646fb0eedcc7b5936d2d02ec6e4d745101f3ca8cd",
"c1": "0x2e6be82fd2ed79ced5c181a0b80334030cd3df6104a0715002c748047ac9974d"
}
},
"scalar": "0x3298cf3c55f7d9fe650b7108fd6d5eedcea3b0d5955c0ce1d5283e1514f66b6",
"Q": {
"x": {
"c0": "0x210e32941e9a0bd1369bbd1ca10e4098524bc6e438b6bc998ecee36cf8f2eff6",
"c1": "0x1cce991601cecf3f16e6140d3c33c172a9e4edb36188311f8fc946be7fbea508"
},
"y": {
"c0": "0x161256e207c543f73059e7765973a6e5094049df26b43dfb3127eb4698915c6d",
"c1": "0xea7639368f6c607de59c1019ddf431baca00b630ef6fe3a50dd78b40911b656"
}
}
},
{
"id": 23,
"P": {
"x": {
"c0": "0x1ee70d477156e96adf9dba13b1f353a52f8de7bf1689444033c75ff2c4673e85",
"c1": "0x2c8bf4c4f6c2bee7df280b0b6355977380336b373495ccb30237ca8edede846"
},
"y": {
"c0": "0x1d1d3554d5c296c4bdfab6b17f878fede93f26718f29a74f79a03abdd8f4da09",
"c1": "0x1955c0c257f5ab4d16b3101c72f4d575d614b060e053f5c8be222f0fb450de4c"
}
},
"scalar": "0x1d452534873553997ae4682a447edde2eb8ab54f3e35af07320ee306871ea160",
"Q": {
"x": {
"c0": "0x2e1fa1b0319c69c7cfa8c8e818c8012246f902d2d60c810c9e5453af46b2e737",
"c1": "0xaa1a3718b2963159b5195c42908df3de89225718d7a6731db5301acd61223de"
},
"y": {
"c0": "0x28650054ddbc0a28e44f919fa262219ef42915003b10a3387214efc6d427b6bd",
"c1": "0x2cfb2a1f8b57ebee8c96ae55c7b021e27395a674b4dfe4047399d37ef550fed4"
}
}
},
{
"id": 24,
"P": {
"x": {
"c0": "0xbfe53b46fe2f96f53061d8a1bf826e63fa175da43e0eafc078767c92753483a",
"c1": "0x78926b1571687613ec4e40287c4ce9b8554f96f58576b8f3ee3f53ba5799474"
},
"y": {
"c0": "0xe59a1f874cf818d4f22d5d6eeeb9bddfe5bb89bd00c675be8b15f0e13c80ffc",
"c1": "0xc1fd043b06296fd548a17381e966b5880a98d3a0936d77bbec6e4e9855fa2fb"
}
},
"scalar": "0x16b64c33ed81dc9bb39bbf535fbfd43ced3e7deacf2e3fcd99991a68700c7f67",
"Q": {
"x": {
"c0": "0x126d668137c086a45370635c30ba6bfc90196744e7121d8544af23feea8cf976",
"c1": "0x21e4142a97a18a50a73142f785abbc90f9bf592af551633db442e019d8b9767e"
},
"y": {
"c0": "0x1cc82ab25178278889f45b15db2a8f929fb619c30ae59d978ad9833b21e346fa",
"c1": "0x22aa1d25a70a54020560e7975e7911328ab2b2e77b8561feaf3758dd49c89ee8"
}
}
},
{
"id": 25,
"P": {
"x": {
"c0": "0x25a4285665cc2545de67bccff505431a7f2d9ae699659fce1e6e5b9484d96cb",
"c1": "0x278ba0ce6daf9b5ae6fd63ffeb98709722133f5cae60f08afa784adf13b51b8c"
},
"y": {
"c0": "0x27649f50664434cac5ff32faa57c2afac827a337b17ff2ff54e7a4a8e5ca0c60",
"c1": "0xc01ab56241a8c27fd1ce429104ddf4d4faac77084d091baed8197037f37c74e"
}
},
"scalar": "0x20087e3937f77fa131cf5ef5ee753ace441b4ae4d9bae6987b97a8d506ae88c5",
"Q": {
"x": {
"c0": "0x1bb7ea37b088e9319dabe6f045df5c44575a1185bbb6e764ecccff25a289f014",
"c1": "0x15a3c5eff6c8cb3c522e49acd5895f565999e4885cfeddde70da4d71be2510f5"
},
"y": {
"c0": "0x23e11415d6a9e72fa6a9ceb03af64eff0959d8e83c21446229fa87ca586e6eb9",
"c1": "0x1eac1a232258e157d830b16a17cdc6d0411557562d1edfe779c8b79a0c7a8533"
}
}
},
{
"id": 26,
"P": {
"x": {
"c0": "0x2c5f822df413a1442f0415880241ced5560d7604289a92c79a45d4f5acabfc56",
"c1": "0x24581d6b0f87bce0d93de44ac1e9977105b696e078bf97f9bb384cf1843cf153"
},
"y": {
"c0": "0x273637f9ff691a7d56ff157ca54df037c439c27ec2f0d35171a40807e1132df8",
"c1": "0xc323b87d7b1201bdb44eed3217ff4c68ca0757ae648572ce32616fd03425355"
}
},
"scalar": "0x1ddab66e2fecfcc4ef565745ceb882edb2160a2bd34a4b4ae7a1ce22b2b70810",
"Q": {
"x": {
"c0": "0x181cc276fe9b486b49c0f7a8a056a0c59b47d05c2ac29ecc8cbb54587810e9bf",
"c1": "0x2a353a018b5bfb9be6b2ca9b2ce17f9146d21f7dbe39c9631a768f515b26027d"
},
"y": {
"c0": "0x23fa9fcde2706b5f00c3435321b8c03800e34e913a0f7512db47ee1867086e91",
"c1": "0x12c994c10321dd50745045a40e84ddaf183439593521615af3c4c6926a294fe7"
}
}
},
{
"id": 27,
"P": {
"x": {
"c0": "0x255b4ea5ac26fd05cb63d53ad971d898d26a2040e5759a94e0f1f678ff541535",
"c1": "0x10027fbd49a2f0e821455e81395618ae43bbdc13a6e4803863af8e72c9aebd41"
},
"y": {
"c0": "0x2807e6a0e23d36a83b6294ee7845ce9fe74b51a4e8082f25df1c7f8fa97a5c34",
"c1": "0x821daba762dc909fefdd724a220a4c90ee272408ebbe0ce247b038c0d486632"
}
},
"scalar": "0x17171602bee6f1e6199835e7504c26a538d6e74561759417e5637dba9ad48bf3",
"Q": {
"x": {
"c0": "0x1500f1cd7ede8e308659881877d3f475cb48b26f73bd8aa2faffc94920fc4f62",
"c1": "0x2bd1c25acc1ebb7dfe8c0630a701aa2e74eb75785f55b21ccd959c4e82b8a317"
},
"y": {
"c0": "0x15522576bd72f4a63a47af2d693db3654893dab5e1c131665a7443742f3010ae",
"c1": "0x1609a8565eb5a4b746cbea3d7ae595842cc90c439bebcd113fe86d3add876651"
}
}
},
{
"id": 28,
"P": {
"x": {
"c0": "0x1ca4cc39bbc5d7e3a6bd5121ea6e54ad6e0ac89a3b7e6d46dd3718394fde7e72",
"c1": "0x22b98436e9cfeef43c3054ecf1ccadfbc5ab01d14af008935c4ae76729908c1d"
},
"y": {
"c0": "0xf50affb4f0a65be664e44472945061014356a26d7d89111667ec2b1c0d6cd90",
"c1": "0x188df415536ce3780b7c36adb6b3933ef6650bbc7080c1b86ad1082fbb69f00"
}
},
"scalar": "0x218e3e8e9644b4448bedee674a0b59c757c0a9fac535afea3b033628db390bc2",
"Q": {
"x": {
"c0": "0x29251c96b5d3356888bb91b9e236ebd9aa296dbb43ada3d39450b2c3a2f3948e",
"c1": "0x7fa3e8a79358afd691ae7070919b5d4a09440947bd0f9efd0e686077709c47"
},
"y": {
"c0": "0x303fc51fa8433b17e563fe9947ea9f8f411250b1b8967cf90839ccff23c3f2b5",
"c1": "0x1d44c83c20e3d4b347fb552d0c32bbf84fb3091bd36d4af51ffc3590c4234b5d"
}
}
},
{
"id": 29,
"P": {
"x": {
"c0": "0x2877dec7a312946fb64fc4a2f1ab8a0bca88efe307792fca6562a378ec8aeb64",
"c1": "0x22f93659213a5da096d259fe9d535c5c80b27776799ccd69221454833142416c"
},
"y": {
"c0": "0x2517992d8bfe48c4742c215618e3cf43560755f7e70448d4e2b55031d6c4fc58",
"c1": "0x2a2984650a76475ad042d93b057aebe1a4c1d5a179e9b813286c59e23640f0ba"
}
},
"scalar": "0x2bc419904c811c74a50ac512a3af552b5462f7f76141ab495b9cd9ed055a22a",
"Q": {
"x": {
"c0": "0x2727754ac523d9d3dc83779ad467d0bc354c107b37bbc221de09225c917a2ad7",
"c1": "0x1875b20d1f7467857cc367f06447ec313f8f2689d8f9aa4b9bdb50a7f650a155"
},
"y": {
"c0": "0x1b993f464d464a5fea08f154db4511af39ae9fa82219024fb23b54882ad9f5b6",
"c1": "0xe76091821facf77157d2746cdf6aae676daf21c644bc1ff4d255998793670c5"
}
}
},
{
"id": 30,
"P": {
"x": {
"c0": "0xa761424b49b1ec6e0cb5782fa9112342f02a9fccc36dedb9dbfcb0e09543053",
"c1": "0x2e15ae9937167f082156388d1576d53fc243124f431cf8f2ca7cbf7c0d6b6efa"
},
"y": {
"c0": "0x7f63245e3f6c42bec2ed5336f5ec2a53d4aaffa2f97b8c44b3c74551fc64d02",
"c1": "0xbe474bb6471e2f9a7143c1ac179374bc6928e55675e840ceceef5862406e836"
}
},
"scalar": "0xcfe5029fa05727d4f5c00694a3ff19d244f7514b6eccf418d3d8ce28b974ce0",
"Q": {
"x": {
"c0": "0x57c81b98b027503184ff8d14de25b9b29d410561ae89fa90836cc11dfce1533",
"c1": "0x15885335d7c83d28e2c93ba2c52453a9abf6937434e4ebaddce98797914e667"
},
"y": {
"c0": "0x187190557ac23b00f4d4f5884277c05632f59871ea1d0dea57166a019f01f3",
"c1": "0x106c3432e758d746e6ab99dff06690dfda96e2c938d2ca3f961d0a3e24480575"
}
}
},
{
"id": 31,
"P": {
"x": {
"c0": "0x2f7a8be801d3049a020427a7d91da75171b0a5b25a3d9a1b0a6c77e1bd7c6d21",
"c1": "0xba9e7b75e34c2fdc9eba9979708d03db6a5a71484ba5f0346d03198edffb49a"
},
"y": {
"c0": "0x223746d8f8f8c0ee49f171ebb5c595a3f06d313fa3d8aa1de005ed5f4730b1a8",
"c1": "0x20436ac231e6a2950d4fdbc2027c462c0c145fd0211c25a0c151b59658b5e61b"
}
},
"scalar": "0x16282791727bc8c77fd1b539ebb27c40bcf7d01b0eaa4f2d1049ebb57cc0e254",
"Q": {
"x": {
"c0": "0x14a712ac590dff2fadeaea157ec2ce9f0d765f1b0bc798e5c17228b36d61740e",
"c1": "0x17828387d2919f4448cace5cd3c924b25be6d1554c4ec4fad1d864be8130665c"
},
"y": {
"c0": "0x27331c49b4ce882213211a0996bce732764835d3e9ac6008dfb08785a139801",
"c1": "0x17db53dfaee928753c07b866391789038290034858e9e812e5afa74db57b625a"
}
}
},
{
"id": 32,
"P": {
"x": {
"c0": "0x17fb7d1649d1f0e7010cbd28c32d25d189a665955339e30b56f69352e5e95131",
"c1": "0x4ee8ea8db7b8fef55c763d1f593fef4dad52cda809c28fd3a0856742c42c9fc"
},
"y": {
"c0": "0x2f9cdfe4f8946ddc94cb36361312c7365434365729965b45f68297720bce31ba",
"c1": "0x5a82731ca1ea02c56b90d92b4ab778d048bcc2fbb337a2d7608fc7382fae9b1"
}
},
"scalar": "0x17252dc9538b9c44670e59e3508eb7d83bc1ff6ecc411991bf6b8800935b56e8",
"Q": {
"x": {
"c0": "0x1fb348a96ed82afdb2208b61fe725d5886ed70d6a6274f54412c4f2f3222c540",
"c1": "0x8c2153f807fb8aa9d1af2b9cbee027c95f2d9e1f060527a34a7548a0e03abc1"
},
"y": {
"c0": "0x10a1306044710912d9171a5d3346956362117a5d7257026d187612cf0f76955a",
"c1": "0x1a8fd0ec9507921edd84a56e2d2a43f1fe57c40dadd3429675887105560ee63"
}
}
},
{
"id": 33,
"P": {
"x": {
"c0": "0xaeb19cb6fbb194d70d050608870d0c15a699ee39fb498784348cd196043f4a0",
"c1": "0x27bf963337cc5650c29a198e43a023115827f645d0f0ecd5a43c96c3af4dad07"
},
"y": {
"c0": "0x2b5bf7fafa151a9803f2d4efad7a7a8e34dd0d58659788d65773f71acfd7310b",
"c1": "0x76a09a2a3dbeca23bebb043dac34d2e9089a95ead74bb1018081cd89007daf7"
}
},
"scalar": "0x22265877e84a95bc98ac54f6d7099611d56560b1fda2b0a56daa7954e152184b",
"Q": {
"x": {
"c0": "0x2c8c6fbecb161108f800f5a364207ceadeb394854066ac70e8b0f16ebe05535",
"c1": "0x15595cf3229221c1b247fbae471d4e039152b87f3927fff8c4962c09a194af2c"
},
"y": {
"c0": "0x8ec16a825d84279f16091d0cb214d55ac5a85d400f5cbe19318ea18bbdedaf8",
"c1": "0x19af2645801421e42a3a7d873a5d0cf2b057359fa308cb9bd36405b9332c639d"
}
}
},
{
"id": 34,
"P": {
"x": {
"c0": "0x1c52613ef69c0d91d65e5dcb8d62df9c66fde5718b75e2e48454a28bea235a10",
"c1": "0xa9a6d98875d99fd4537be146ecbe90885ec3d654681713485b9e70278c0d988"
},
"y": {
"c0": "0x5187b8164cda49cc72e06883256314fd1fe9515e22b33b27c3af94b2004cc59",
"c1": "0x2ab7d6dbc9aa1327a06fa5e2cab77657d196e66a116c8a9442a2beadcbb81534"
}
},
"scalar": "0x29ebe627896f3089cfc548c24fd614790f891560f09a2c0b00d9b1c0746dbee9",
"Q": {
"x": {
"c0": "0x26f714e653fd4e1299c12f444bd535c7954ec924e41c14c5a29ec8df6f98c8ed",
"c1": "0x13dc1a018beef9b1a2b5fe21061a9cadceb24de9825551b052c0e7e0f0ec136b"
},
"y": {
"c0": "0x1328989de1290ca86415f7a70fbd320549bf4e49f6bc5e1c2a97a2850f43cc21",
"c1": "0xb53ae45f85f48e6f887c3f5d4816216fc94b3a526799480654aba5f837600b8"
}
}
},
{
"id": 35,
"P": {
"x": {
"c0": "0x146ec5cda703b28905d98bd080bf3422bdaca76cc5375c0d011dee17cd18134b",
"c1": "0x2d6a1b127396e663898d9234a3b2e39e36097b76fa619e4f288bd173ed5a6419"
},
"y": {
"c0": "0x1a46a5b8be34fef4dff75b867dbe090c5c59582824f984e3223981446cd3ea19",
"c1": "0x2bbdaf1b557ce800ac567b9748a7fa18f401f1b2e6ab1dd33cf26b3ebde77379"
}
},
"scalar": "0x420d38e89dea2daa792b23b8daf2af449ac02691bb79623d44543650851848",
"Q": {
"x": {
"c0": "0x21ef349d541c21a8836b8e1c064b83067d11332953f6a9faf8d0c5ad487b53bc",
"c1": "0xe840cf1d7986b44778474033cbe65578c711a5ea05c44a5bf66b34b8880caea"
},
"y": {
"c0": "0xf15cbada0dc3ff21cc8df981b96352b193a9f68f982fd892610dc2f000bb5cb",
"c1": "0x1f4a018afcf945f39850369c12ed875fc0cff378aa88625b6959136855e830ba"
}
}
},
{
"id": 36,
"P": {
"x": {
"c0": "0x18ed416390eed89db0ebeb36317b7c7509141a3f2f06922a491d68fe9f08401b",
"c1": "0x91e6c11db4b845f03205f1142d5f1f5e0caf5fb98fc9697c16d4cf11f651874"
},
"y": {
"c0": "0x1ba88562888c425a1dc52fcb96fc1e7f7d93c319b43541a6126e32c7228a31e",
"c1": "0x6f0d64a6d31249301417b65f71608042f2303157630a4871a6732e46075f4f2"
}
},
"scalar": "0xee0b0c49ed468ac5486b2b4ba509aa62405b579371223c1d900e6fc5369476",
"Q": {
"x": {
"c0": "0x2ebe8dc4b7f908dd32437afbafe58ffdbe721e6610d3c38b731d24cd7e62134e",
"c1": "0xc073a0e5faa5885d2c8621ce6a2133c6470e0fec8e0b29214d293f01b46c1f2"
},
"y": {
"c0": "0x164ca34152dda200e7ee5de448eeb43717c960ee2917232f59871bbcb62da415",
"c1": "0x15b31f24168b5eef2395d9026b89705a4dd9954da1c7ccc13233162171453d55"
}
}
},
{
"id": 37,
"P": {
"x": {
"c0": "0x1947cf6904f3be73ce741d1c9c8a05b330cb244d4711eea555a4156fd5a5a065",
"c1": "0x2f0371ad62f02703fc529d925fa8c7a9db08bc7669a391bbceb7a6cd4acfc03"
},
"y": {
"c0": "0x6de7f21c2437efb523b128b009488ea283e5cad04770f791d670b7f63dbded6",
"c1": "0xb7ed1621f487b8f176b41e73a7e4c9e6dd730c4df4ee63770cb55ec65c77763"
}
},
"scalar": "0x1019c6fd4411a79e4067200d6bc08a6cd31aba0b4bf0122012a7c090debb4911",
"Q": {
"x": {
"c0": "0x1878ef502d104e6a99d88455b7459c6b4f86ce4b3cc52d2b0db1fe5d1afe3c47",
"c1": "0x28b3c6133e5dc370fa7b69084d1e9432c2c4fd0af98051e7e19fe21d000ef8c1"
},
"y": {
"c0": "0x239dff76d6a291439f65ecc45a3073a7fc66901a8d8e2053eaa318852f735fe8",
"c1": "0x2f1959ea8cdfde3deb0434235bb9d5aaa9003773d57b3de7eb5d275f982e8687"
}
}
},
{
"id": 38,
"P": {
"x": {
"c0": "0x2c916f06f8231872b95939a7241e8a0f726e9e971fd75a184dc6620c32995d65",
"c1": "0x2b9050eda5925757e0b1b3c3795b99671dad16b1d046e1d870aabe49fb1a1b71"
},
"y": {
"c0": "0x15bbaf27fa285a14f25d97f3f210375b37bbe81ab423e83152d8a96a4dd4c607",
"c1": "0x2e889b65d20214deee20b2426fa5dbfec1fecf82689f1d79bbee2ba8d37912f1"
}
},
"scalar": "0x5fecf0f77d5893688482fa8f53c6d27959b1d35ad28e40384464d72cff32022",
"Q": {
"x": {
"c0": "0x142aceba262e8fcbf3cc0a10be267cdd7b972cd096d49cd0bcfeb5a5fde9e6d5",
"c1": "0x1cea6dde06c3700680bcb6fb477f8425f700defd392c541086c1fb76db043b86"
},
"y": {
"c0": "0x10c0bc6da5b705f0ee651b2a8931d893fcc8a818ae2d6d96fb39fcfb74655d46",
"c1": "0xb7a28b5fa126c074f6f2141428641b22f44b206e6ee29e14b5788c7cdde0db2"
}
}
},
{
"id": 39,
"P": {
"x": {
"c0": "0x1e62f0b5c22a8a108a2288d74f5590a439cb5c37fdfb7f743df2ed7da34cb07c",
"c1": "0x2e2a1ccdfe837509a2c9fbf18eb04149a7a29157da1257729c65a6f08071047c"
},
"y": {
"c0": "0x4fbc1fa90d965f0031b0b12e23c82bc13915a514387843f9aec77aabec40945",
"c1": "0x26159129fcea1dbaad972a459db9d546ea7163a09139939cb6c91741c79345a8"
}
},
"scalar": "0x286799045208066279c27dd97ed6f300796c72f06c304694759b500b38904c73",
"Q": {
"x": {
"c0": "0x20b6ebcb8640ab3b79167922f1df68df507a94b407956fabe25f3359e7e1c16",
"c1": "0x14eab748fc9a8817bceda8cd798ce8e986c37f3e535ee71eb57e677fff44da01"
},
"y": {
"c0": "0x3fc452439640e70407f4437804a879e88a48c85ab4b7a20edd9d372de81cb62",
"c1": "0x2e87b1536e41403bc8bc511741a9d5eee7b0fdd122bb3e6e5c88ff14be0abfad"
}
}
}
]
}