Eth1 evm precompiles (#166)
* Prepare support for Eth1 EVM * Implement EIP 196 (Ethereum BN254 add/mul) * Implement ETH1 pairing precompile * Accelerate isOnCurve for G2 with precomputation
This commit is contained in:
parent
f5c0b6245d
commit
1195e5e980
|
@ -166,6 +166,7 @@ const testDesc: seq[tuple[path: string, useGMP: bool]] = @[
|
|||
# Protocols
|
||||
# ----------------------------------------------------------
|
||||
("tests/t_sig_bls_lowlevel.nim", false),
|
||||
("tests/protocols/t_ethereum_evm_precompiles.nim", false),
|
||||
]
|
||||
|
||||
# For temporary (hopefully) investigation that can only be reproduced in CI
|
||||
|
@ -184,7 +185,8 @@ const skipSanitizers = [
|
|||
"tests/t_ec_sage_bls12_381.nim",
|
||||
"tests/t_hash_to_field.nim",
|
||||
"tests/t_hash_to_curve.nim",
|
||||
"tests/t_sig_bls_lowlevel.nim"
|
||||
"tests/t_sig_bls_lowlevel.nim",
|
||||
"tests/protocols/t_ethereum_evm_precompiles.nim"
|
||||
]
|
||||
|
||||
when defined(windows):
|
||||
|
|
|
@ -91,7 +91,7 @@ macro getMontyOne*(ff: type FF): untyped =
|
|||
result = bindConstant(ff, "MontyOne")
|
||||
|
||||
macro getMontyPrimeMinus1*(ff: type FF): untyped =
|
||||
## Get (P+1) / 2 for an odd prime
|
||||
## Get (P-1)
|
||||
result = bindConstant(ff, "MontyPrimeMinus1")
|
||||
|
||||
macro getInvModExponent*(ff: type FF): untyped =
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# Constantine
|
||||
# Copyright (c) 2018-2019 Status Research & Development GmbH
|
||||
# Copyright (c) 2020-Present Mamy André-Ratsimbazafy
|
||||
# Licensed and distributed under either of
|
||||
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
|
||||
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
../config/curves,
|
||||
../io/io_towers
|
||||
|
||||
# Curve precomputed parameters
|
||||
# -----------------------------------------------------------------
|
||||
const BLS12_377_coefB_G2* = Fp2[BLS12_377].fromHex(
|
||||
"0x0",
|
||||
"0x10222f6db0fd6f343bd03737460c589dc7b4f91cd5fd889129207b63c6bf8000dd39e5c1ccccccd1c9ed9999999999a"
|
||||
)
|
|
@ -0,0 +1,18 @@
|
|||
# Constantine
|
||||
# Copyright (c) 2018-2019 Status Research & Development GmbH
|
||||
# Copyright (c) 2020-Present Mamy André-Ratsimbazafy
|
||||
# Licensed and distributed under either of
|
||||
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
|
||||
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
../config/curves,
|
||||
../io/io_towers
|
||||
|
||||
# Curve precomputed parameters
|
||||
# -----------------------------------------------------------------
|
||||
const BLS12_381_coefB_G2* = Fp2[BLS12_381].fromHex(
|
||||
"0x4",
|
||||
"0x4"
|
||||
)
|
|
@ -0,0 +1,18 @@
|
|||
# Constantine
|
||||
# Copyright (c) 2018-2019 Status Research & Development GmbH
|
||||
# Copyright (c) 2020-Present Mamy André-Ratsimbazafy
|
||||
# Licensed and distributed under either of
|
||||
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
|
||||
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
../config/curves,
|
||||
../io/io_towers
|
||||
|
||||
# Curve precomputed parameters
|
||||
# -----------------------------------------------------------------
|
||||
const BN254_Nogami_coefB_G2* = Fp2[BN254_Nogami].fromHex(
|
||||
"0x1",
|
||||
"0x2523648240000001ba344d80000000086121000000000013a700000000000012"
|
||||
)
|
|
@ -0,0 +1,18 @@
|
|||
# Constantine
|
||||
# Copyright (c) 2018-2019 Status Research & Development GmbH
|
||||
# Copyright (c) 2020-Present Mamy André-Ratsimbazafy
|
||||
# Licensed and distributed under either of
|
||||
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
|
||||
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
../config/curves,
|
||||
../io/io_towers
|
||||
|
||||
# Curve precomputed parameters
|
||||
# -----------------------------------------------------------------
|
||||
const BN254_Snarks_coefB_G2* = Fp2[BN254_Snarks].fromHex(
|
||||
"0x2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e5",
|
||||
"0x9713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d2"
|
||||
)
|
|
@ -0,0 +1,16 @@
|
|||
# Constantine
|
||||
# Copyright (c) 2018-2019 Status Research & Development GmbH
|
||||
# Copyright (c) 2020-Present Mamy André-Ratsimbazafy
|
||||
# Licensed and distributed under either of
|
||||
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
|
||||
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
../config/curves,
|
||||
../io/io_fields
|
||||
|
||||
# Curve precomputed parameters
|
||||
# -----------------------------------------------------------------
|
||||
const BW6_761_coefB_G2* = Fp[BW6_761].fromHex(
|
||||
"0x4")
|
|
@ -0,0 +1,27 @@
|
|||
# Constantine
|
||||
# Copyright (c) 2018-2019 Status Research & Development GmbH
|
||||
# Copyright (c) 2020-Present Mamy André-Ratsimbazafy
|
||||
# Licensed and distributed under either of
|
||||
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
|
||||
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
std/macros,
|
||||
../config/curves,
|
||||
./bls12_377_precomputed_params,
|
||||
./bls12_381_precomputed_params,
|
||||
./bn254_nogami_precomputed_params,
|
||||
./bn254_snarks_precomputed_params,
|
||||
./bw6_761_precomputed_params
|
||||
|
||||
{.experimental: "dynamicBindSym".}
|
||||
|
||||
macro getCoefB_G2*(C: static Curve): untyped =
|
||||
## A pairing curve has the following equation on G1
|
||||
## y² = x³ + b
|
||||
## and on G2
|
||||
## y² = x³ + b/µ (D-Twist)
|
||||
## y² = x³ + b*µ (M-Twist)
|
||||
## with µ the non-residue (sextic non-residue with a sextic twist)
|
||||
return bindSym($C & "_coefB_G2")
|
|
@ -16,10 +16,11 @@ import
|
|||
elliptic/[
|
||||
ec_shortweierstrass_affine,
|
||||
ec_shortweierstrass_jacobian,
|
||||
ec_shortweierstrass_projective
|
||||
ec_shortweierstrass_projective,
|
||||
ec_scalar_mul
|
||||
]
|
||||
|
||||
export ec_shortweierstrass_affine, ec_shortweierstrass_jacobian, ec_shortweierstrass_projective
|
||||
export ec_shortweierstrass_affine, ec_shortweierstrass_jacobian, ec_shortweierstrass_projective, ec_scalar_mul
|
||||
|
||||
func projectiveFromJacobian*[F; Tw](
|
||||
prj: var ECP_ShortW_Prj[F, Tw],
|
||||
|
|
|
@ -11,7 +11,8 @@ import
|
|||
../config/[common, curves],
|
||||
../arithmetic,
|
||||
../towers,
|
||||
../io/[io_fields, io_towers]
|
||||
../io/[io_fields, io_towers],
|
||||
../curves/zoo_precomputed_params
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
|
@ -42,11 +43,6 @@ func `==`*(P, Q: ECP_ShortW_Aff): SecretBool =
|
|||
func isInf*(P: ECP_ShortW_Aff): SecretBool =
|
||||
## Returns true if P is an infinity point
|
||||
## and false otherwise
|
||||
##
|
||||
## Note: the jacobian coordinates equation is
|
||||
## Y² = X³ + aXZ⁴ + bZ⁶
|
||||
## A "zero" point is any point with coordinates X and Z = 0
|
||||
## Y can be anything
|
||||
result = P.x.isZero() and P.y.isZero()
|
||||
|
||||
func curve_eq_rhs*[F](y2: var F, x: F, Tw: static Twisted) =
|
||||
|
@ -59,45 +55,15 @@ func curve_eq_rhs*[F](y2: var F, x: F, Tw: static Twisted) =
|
|||
t.square(x)
|
||||
t *= x
|
||||
|
||||
# This procedure is not use in perf critical situation like signing/verification
|
||||
# but for testing to quickly create points on a curve.
|
||||
# That said D-Twists require an inversion
|
||||
# and we could avoid doing `b/µ` or `µ*b` at runtime on 𝔽p²
|
||||
# which would accelerate random point generation
|
||||
#
|
||||
# This is preferred to generating random point
|
||||
# via random scalar multiplication of the curve generator
|
||||
# as the latter assumes:
|
||||
# - point addition, doubling work
|
||||
# - scalar multiplication works
|
||||
# - a generator point is defined
|
||||
# i.e. you can't test unless everything is already working
|
||||
#
|
||||
# TODO: precomputation needed when deserializing points
|
||||
# to check if a point is on-curve and prevent denial-of-service
|
||||
# using slow inversion.
|
||||
when F.C.getCoefB() >= 0:
|
||||
y2.fromInt F.C.getCoefB()
|
||||
when Tw == OnTwist:
|
||||
when F.C.getSexticTwist() == D_Twist:
|
||||
y2 /= SexticNonResidue
|
||||
elif F.C.getSexticTwist() == M_Twist:
|
||||
y2 *= SexticNonResidue
|
||||
else:
|
||||
{.error: "Only twisted curves are supported on extension field 𝔽p²".}
|
||||
|
||||
y2 += t
|
||||
when Tw == NotOnTwist:
|
||||
when F.C.getCoefB() >= 0:
|
||||
y2.fromInt F.C.getCoefB()
|
||||
y2 += t
|
||||
else:
|
||||
y2.fromInt -F.C.getCoefB()
|
||||
y2.diff(t, y2)
|
||||
else:
|
||||
y2.fromInt -F.C.getCoefB()
|
||||
when Tw == OnTwist:
|
||||
when F.C.getSexticTwist() == D_Twist:
|
||||
y2 /= SexticNonResidue
|
||||
elif F.C.getSexticTwist() == M_Twist:
|
||||
y2 *= SexticNonResidue
|
||||
else:
|
||||
{.error: "Only twisted curves are supported on extension field 𝔽p²".}
|
||||
|
||||
y2.diff(t, y2)
|
||||
y2.sum(F.C.getCoefB_G2, t)
|
||||
|
||||
when F.C.getCoefA() != 0:
|
||||
t = x
|
||||
|
@ -127,6 +93,15 @@ func trySetFromCoordX*[F, Tw](
|
|||
##
|
||||
## Note: Dedicated robust procedures for hashing-to-curve
|
||||
## will be provided, this is intended for testing purposes.
|
||||
##
|
||||
## For **test case generation only**,
|
||||
## this is preferred to generating random point
|
||||
## via random scalar multiplication of the curve generator
|
||||
## as the latter assumes:
|
||||
## - point addition, doubling work
|
||||
## - scalar multiplication works
|
||||
## - a generator point is defined
|
||||
## i.e. you can't test unless everything is already working
|
||||
P.y.curve_eq_rhs(x, Tw)
|
||||
result = sqrt_if_square(P.y)
|
||||
P.x = x
|
||||
|
|
|
@ -91,6 +91,15 @@ func trySetFromCoordsXandZ*[F; Tw](
|
|||
##
|
||||
## Note: Dedicated robust procedures for hashing-to-curve
|
||||
## will be provided, this is intended for testing purposes.
|
||||
##
|
||||
## For **test case generation only**,
|
||||
## this is preferred to generating random point
|
||||
## via random scalar multiplication of the curve generator
|
||||
## as the latter assumes:
|
||||
## - point addition, doubling work
|
||||
## - scalar multiplication works
|
||||
## - a generator point is defined
|
||||
## i.e. you can't test unless everything is already working
|
||||
P.y.curve_eq_rhs(x, Tw)
|
||||
result = sqrt_if_square(P.y)
|
||||
|
||||
|
@ -114,6 +123,15 @@ func trySetFromCoordX*[F; Tw](
|
|||
##
|
||||
## Note: Dedicated robust procedures for hashing-to-curve
|
||||
## will be provided, this is intended for testing purposes.
|
||||
##
|
||||
## For **test case generation only**,
|
||||
## this is preferred to generating random point
|
||||
## via random scalar multiplication of the curve generator
|
||||
## as the latter assumes:
|
||||
## - point addition, doubling work
|
||||
## - scalar multiplication works
|
||||
## - a generator point is defined
|
||||
## i.e. you can't test unless everything is already working
|
||||
P.y.curve_eq_rhs(x, Tw)
|
||||
result = sqrt_if_square(P.y)
|
||||
P.x = x
|
||||
|
|
|
@ -85,6 +85,15 @@ func trySetFromCoordsXandZ*[F; Tw](
|
|||
##
|
||||
## Note: Dedicated robust procedures for hashing-to-curve
|
||||
## will be provided, this is intended for testing purposes.
|
||||
##
|
||||
## For **test case generation only**,
|
||||
## this is preferred to generating random point
|
||||
## via random scalar multiplication of the curve generator
|
||||
## as the latter assumes:
|
||||
## - point addition, doubling work
|
||||
## - scalar multiplication works
|
||||
## - a generator point is defined
|
||||
## i.e. you can't test unless everything is already working
|
||||
P.y.curve_eq_rhs(x, Tw)
|
||||
result = sqrt_if_square(P.y)
|
||||
|
||||
|
@ -105,6 +114,15 @@ func trySetFromCoordX*[F; Tw](
|
|||
##
|
||||
## Note: Dedicated robust procedures for hashing-to-curve
|
||||
## will be provided, this is intended for testing purposes.
|
||||
##
|
||||
## For **test case generation only**,
|
||||
## this is preferred to generating random point
|
||||
## via random scalar multiplication of the curve generator
|
||||
## as the latter assumes:
|
||||
## - point addition, doubling work
|
||||
## - scalar multiplication works
|
||||
## - a generator point is defined
|
||||
## i.e. you can't test unless everything is already working
|
||||
P.y.curve_eq_rhs(x, Tw)
|
||||
result = sqrt_if_square(P.y)
|
||||
P.x = x
|
||||
|
|
|
@ -31,7 +31,7 @@ import
|
|||
|
||||
# TODO: the in-place API should return a bool
|
||||
# to indicate success.
|
||||
# the out-of place API are for for configuration,
|
||||
# the out-of place API are for configuration,
|
||||
# prototyping, research and debugging purposes,
|
||||
# and can use exceptions.
|
||||
|
||||
|
@ -359,7 +359,7 @@ func countNonBlanks(hexStr: string, startPos: int): int =
|
|||
if c in blanks:
|
||||
result += 1
|
||||
|
||||
func hexToPaddedByteArray(hexStr: string, output: var openArray[byte], order: static[Endianness]) =
|
||||
func hexToPaddedByteArray*(hexStr: string, output: var openArray[byte], order: static[Endianness]) =
|
||||
## Read a hex string and store it in a byte array `output`.
|
||||
## The string may be shorter than the byte array.
|
||||
##
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
import
|
||||
./io_bigints,
|
||||
../config/common,
|
||||
../config/[common, curves],
|
||||
../arithmetic/finite_fields,
|
||||
../primitives
|
||||
|
||||
|
@ -84,12 +84,16 @@ func toHex*(f: FF, order: static Endianness = bigEndian): string =
|
|||
|
||||
func fromHex*(dst: var FF, hexString: string) {.raises: [ValueError].}=
|
||||
## Convert a hex string to a element of Fp or Fr
|
||||
## Warning: protocols might want a specific function that checks
|
||||
## that the input is in [0, modulus) range
|
||||
# TODO: review API, should return bool
|
||||
let raw {.noinit.} = fromHex(dst.mres.typeof, hexString)
|
||||
dst.fromBig(raw)
|
||||
|
||||
func fromHex*(T: type FF, hexString: string): T {.noInit, raises: [ValueError].}=
|
||||
## Convert a hex string to a element of Fp
|
||||
## Warning: protocols might want a specific function that checks
|
||||
## that the input is in [0, modulus) range
|
||||
result.fromHex(hexString)
|
||||
|
||||
func toDecimal*(f: FF): string =
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
# Constantine-backed protocols
|
||||
|
||||
## Ethereum Virtual Machine
|
||||
|
||||
For Zero-Knowledge Proofs as described in
|
||||
|
||||
- Succinct Non-Interactive Zero Knowledge
|
||||
for a von Neumann Architecture\
|
||||
Eli Ben-Sasson, Alessandro Chiesa, Eran Tromer, Madars Virza\
|
||||
https://eprint.iacr.org/2013/879.pdf
|
||||
|
||||
Constantine-backed precompiles for
|
||||
|
||||
- ECADD on BN254_Snarks (called `alt_bn128` in Ethereum), address 0x6, spec [EIP-196](https://eips.ethereum.org/EIPS/eip-196) and pricing [EIP-1108](https://eips.ethereum.org/EIPS/eip-1108)
|
||||
- ECMUL on BN254_Snarks (called `alt_bn128` in Ethereum), address 0x7, spec [EIP-196](https://eips.ethereum.org/EIPS/eip-196) and pricing [EIP-1108](https://eips.ethereum.org/EIPS/eip-1108)
|
||||
- ECPAIRING on BN254_Snarks (called `alt_bn128` in Ethereum), address 0x8, spec [EIP-197](https://eips.ethereum.org/EIPS/eip-197) and pricing [EIP-1108](https://eips.ethereum.org/EIPS/eip-1108)
|
|
@ -0,0 +1,380 @@
|
|||
# Constantine
|
||||
# Copyright (c) 2018-2019 Status Research & Development GmbH
|
||||
# Copyright (c) 2020-Present Mamy André-Ratsimbazafy
|
||||
# Licensed and distributed under either of
|
||||
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
|
||||
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
../config/[common, curves],
|
||||
../arithmetic, ../towers,
|
||||
../arithmetic/limbs_montgomery,
|
||||
../ec_shortweierstrass,
|
||||
../pairing/[pairing_bn, miller_loops, cyclotomic_fp12],
|
||||
../io/[io_bigints, io_fields]
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# Ethereum EVM precompiles
|
||||
#
|
||||
# ############################################################
|
||||
|
||||
# No exceptions for the EVM API
|
||||
{.push raises: [].}
|
||||
|
||||
type
|
||||
CttEVMStatus* = enum
|
||||
cttEVM_Success
|
||||
cttEVM_IntLargerThanModulus
|
||||
cttEVM_PointNotOnCurve
|
||||
cttEVM_PointNotInSubgroup
|
||||
cttEVM_InvalidInputLength
|
||||
|
||||
func parseRawUint(
|
||||
dst: var Fp[BN254_Snarks],
|
||||
src: openarray[byte]): CttEVMStatus =
|
||||
## Parse an unsigned integer from its canonical
|
||||
## big-endian or little-endian unsigned representation
|
||||
## And store it into a field element.
|
||||
##
|
||||
## Return false if the integer is larger than the field modulus.
|
||||
## Returns true on success.
|
||||
var big {.noInit.}: BigInt[254]
|
||||
big.fromRawUint(src, bigEndian)
|
||||
|
||||
if not bool(big < Mod(BN254_Snarks)):
|
||||
return cttEVM_IntLargerThanModulus
|
||||
|
||||
dst.fromBig(big)
|
||||
return cttEVM_Success
|
||||
|
||||
func fromRawCoords(
|
||||
dst: var ECP_ShortW_Prj[Fp[BN254_Snarks], NotOnTwist],
|
||||
x, y: openarray[byte]): CttEVMStatus =
|
||||
|
||||
# Deserialization
|
||||
# ----------------------
|
||||
# Encoding spec https://eips.ethereum.org/EIPS/eip-196
|
||||
|
||||
let status_x = dst.x.parseRawUint(x)
|
||||
if status_x != cttEVM_Success:
|
||||
return status_x
|
||||
let status_y = dst.y.parseRawUint(y)
|
||||
if status_y != cttEVM_Success:
|
||||
return status_y
|
||||
|
||||
# Handle point at infinity
|
||||
if dst.x.isZero().bool and dst.y.isZero().bool:
|
||||
dst.setInf()
|
||||
return cttEVM_Success
|
||||
|
||||
# Otherwise regular point
|
||||
dst.z.setOne()
|
||||
|
||||
# Deserialization checks
|
||||
# ----------------------
|
||||
|
||||
# Point on curve
|
||||
if not bool(isOnCurve(dst.x, dst.y, NotOnTwist)):
|
||||
return cttEVM_PointNotOnCurve
|
||||
|
||||
# BN254_Snarks is a curve with cofactor 1,
|
||||
# so no subgroup checks are necessary
|
||||
|
||||
return cttEVM_Success
|
||||
|
||||
func eth_evm_ecadd*(
|
||||
r: var array[64, byte], inputs: openarray[byte]): CttEVMStatus =
|
||||
## Elliptic Curve addition on BN254_Snarks
|
||||
## (also called alt_bn128 in Ethereum specs
|
||||
## and bn256 in Ethereum tests)
|
||||
##
|
||||
## Name: ECADD
|
||||
##
|
||||
## Inputs:
|
||||
## - A G1 point P with coordinates (Px, Py)
|
||||
## - A G1 point Q with coordinates (Qx, Qy)
|
||||
##
|
||||
## Each coordinate is a 32-bit bigEndian integer
|
||||
## They are serialized concatenated in a byte array [Px, Py, Qx, Qy]
|
||||
## If the length is less than 128 bytes, input is virtually padded with zeros.
|
||||
## If the length is greater than 128 bytes, input is truncated to 128 bytes.
|
||||
##
|
||||
## Output
|
||||
## - A G1 point R with coordinates (Px + Qx, Py + Qy)
|
||||
## - Status code:
|
||||
## cttEVM_Success
|
||||
## cttEVM_IntLargerThanModulus
|
||||
## cttEVM_PointNotOnCurve
|
||||
##
|
||||
## Spec https://eips.ethereum.org/EIPS/eip-196
|
||||
|
||||
# Auto-pad with zero
|
||||
var padded: array[128, byte]
|
||||
let lastIdx = min(inputs.len, 128) - 1
|
||||
padded[0 .. lastIdx] = inputs.toOpenArray(0, lastIdx)
|
||||
|
||||
var P{.noInit.}, Q{.noInit.}, R{.noInit.}: ECP_ShortW_Prj[Fp[BN254_Snarks], NotOnTwist]
|
||||
|
||||
let statusP = P.fromRawCoords(
|
||||
x = padded.toOpenArray(0, 31),
|
||||
y = padded.toOpenArray(32, 63)
|
||||
)
|
||||
if statusP != cttEVM_Success:
|
||||
return statusP
|
||||
let statusQ = Q.fromRawCoords(
|
||||
x = padded.toOpenArray(64, 95),
|
||||
y = padded.toOpenArray(96, 127)
|
||||
)
|
||||
if statusQ != cttEVM_Success:
|
||||
return statusQ
|
||||
|
||||
R.sum(P, Q)
|
||||
var aff{.noInit.}: ECP_ShortW_Aff[Fp[BN254_Snarks], NotOnTwist]
|
||||
aff.affineFromProjective(R)
|
||||
|
||||
r.toOpenArray(0, 31).exportRawUint(
|
||||
aff.x, bigEndian
|
||||
)
|
||||
r.toOpenArray(32, 63).exportRawUint(
|
||||
aff.y, bigEndian
|
||||
)
|
||||
|
||||
func eth_evm_ecmul*(
|
||||
r: var array[64, byte], inputs: openarray[byte]): CttEVMStatus =
|
||||
## Elliptic Curve multiplication on BN254_Snarks
|
||||
## (also called alt_bn128 in Ethereum specs
|
||||
## and bn256 in Ethereum tests)
|
||||
##
|
||||
## Name: ECMUL
|
||||
##
|
||||
## Inputs:
|
||||
## - A G1 point P with coordinates (Px, Py)
|
||||
## - A scalar s in 0 ..< 2²⁵⁶
|
||||
##
|
||||
## Each coordinate is a 32-bit bigEndian integer
|
||||
## They are serialized concatenated in a byte array [Px, Py, r]
|
||||
## If the length is less than 96 bytes, input is virtually padded with zeros.
|
||||
## If the length is greater than 96 bytes, input is truncated to 96 bytes.
|
||||
##
|
||||
## Output
|
||||
## - A G1 point R = [s]P
|
||||
## - Status code:
|
||||
## cttEVM_Success
|
||||
## cttEVM_IntLargerThanModulus
|
||||
## cttEVM_PointNotOnCurve
|
||||
##
|
||||
## Spec https://eips.ethereum.org/EIPS/eip-196
|
||||
|
||||
# Auto-pad with zero
|
||||
var padded: array[128, byte]
|
||||
let lastIdx = min(inputs.len, 128) - 1
|
||||
padded[0 .. lastIdx] = inputs.toOpenArray(0, lastIdx)
|
||||
|
||||
var P{.noInit.}: ECP_ShortW_Prj[Fp[BN254_Snarks], NotOnTwist]
|
||||
|
||||
let statusP = P.fromRawCoords(
|
||||
x = padded.toOpenArray(0, 31),
|
||||
y = padded.toOpenArray(32, 63)
|
||||
)
|
||||
if statusP != cttEVM_Success:
|
||||
return statusP
|
||||
|
||||
var smod{.noInit.}: Fr[BN254_Snarks]
|
||||
var s{.noInit.}: BigInt[256]
|
||||
s.fromRawUint(padded.toOpenArray(64,95), bigEndian)
|
||||
|
||||
when true:
|
||||
# The spec allows s to be bigger than the curve order r and the field modulus p.
|
||||
# As, elliptic curve are a cyclic group mod r, we can reduce modulo r and get the same result.
|
||||
# This allows to use windowed endomorphism acceleration
|
||||
# which is 31.5% faster than plain windowed scalar multiplication
|
||||
# at the low cost of a modular reduction.
|
||||
|
||||
var sprime{.noInit.}: typeof(smod.mres)
|
||||
# Due to mismatch between the BigInt[256] input and the rest being BigInt[254]
|
||||
# we use the low-level montyResidue instead of 'fromBig'
|
||||
montyResidue(smod.mres.limbs, s.limbs,
|
||||
Fr[BN254_Snarks].fieldMod().limbs,
|
||||
Fr[BN254_Snarks].getR2modP().limbs,
|
||||
Fr[BN254_Snarks].getNegInvModWord(),
|
||||
Fr[BN254_Snarks].getSpareBits())
|
||||
sprime = smod.toBig()
|
||||
P.scalarMul(sprime)
|
||||
else:
|
||||
P.scalarMul(s)
|
||||
|
||||
var aff{.noInit.}: ECP_ShortW_Aff[Fp[BN254_Snarks], NotOnTwist]
|
||||
aff.affineFromProjective(P)
|
||||
|
||||
r.toOpenArray(0, 31).exportRawUint(
|
||||
aff.x, bigEndian
|
||||
)
|
||||
r.toOpenArray(32, 63).exportRawUint(
|
||||
aff.y, bigEndian
|
||||
)
|
||||
|
||||
func subgroupCheck(P: ECP_ShortW_Aff[Fp2[BN254_Snarks], OnTwist]): bool =
|
||||
## A point may be on a curve but in case the curve has a cofactor != 1
|
||||
## that point may not be in the correct cyclic subgroup.
|
||||
## If we are on the subgroup of order r then [r]P = 0
|
||||
|
||||
# TODO: Generic for any curve
|
||||
|
||||
var Q{.noInit.}: ECP_ShortW_Prj[Fp2[BN254_Snarks], OnTwist]
|
||||
|
||||
# TODO: precompute up to the endomorphism decomposition
|
||||
# or implement fixed base scalar mul
|
||||
# as subgroup checks are a deserialization bottleneck
|
||||
var rm1 = Fr[BN254_Snarks].fieldMod()
|
||||
rm1 -= One
|
||||
|
||||
# We can't use endomorphism acceleration when multiplying
|
||||
# by the curve order r to check [r]P == 0
|
||||
# as it requires the scalar to be < r.
|
||||
# But we can use it to multiply by [r-1].
|
||||
Q.projectiveFromAffine(P)
|
||||
let Q0 = Q
|
||||
Q.scalarMul(rm1)
|
||||
Q += Q0
|
||||
|
||||
return bool(Q.isInf())
|
||||
|
||||
func fromRawCoords(
|
||||
dst: var ECP_ShortW_Aff[Fp[BN254_Snarks], NotOnTwist],
|
||||
x, y: openarray[byte]): CttEVMStatus =
|
||||
|
||||
# Deserialization
|
||||
# ----------------------
|
||||
# Encoding spec https://eips.ethereum.org/EIPS/eip-196
|
||||
|
||||
let status_x = dst.x.parseRawUint(x)
|
||||
if status_x != cttEVM_Success:
|
||||
return status_x
|
||||
let status_y = dst.y.parseRawUint(y)
|
||||
if status_y != cttEVM_Success:
|
||||
return status_y
|
||||
|
||||
# Handle point at infinity
|
||||
if dst.x.isZero().bool and dst.y.isZero().bool:
|
||||
return cttEVM_Success
|
||||
|
||||
# Deserialization checks
|
||||
# ----------------------
|
||||
|
||||
# Point on curve
|
||||
if not bool(isOnCurve(dst.x, dst.y, NotOnTwist)):
|
||||
return cttEVM_PointNotOnCurve
|
||||
|
||||
# BN254_Snarks is a curve with cofactor 1,
|
||||
# so no subgroup checks are necessary
|
||||
|
||||
return cttEVM_Success
|
||||
|
||||
func fromRawCoords(
|
||||
dst: var ECP_ShortW_Aff[Fp2[BN254_Snarks], OnTwist],
|
||||
x0, x1, y0, y1: openarray[byte]): CttEVMStatus =
|
||||
|
||||
# Deserialization
|
||||
# ----------------------
|
||||
# Encoding spec https://eips.ethereum.org/EIPS/eip-196
|
||||
|
||||
let status_x0 = dst.x.c0.parseRawUint(x0)
|
||||
if status_x0 != cttEVM_Success:
|
||||
return status_x0
|
||||
let status_x1 = dst.x.c1.parseRawUint(x1)
|
||||
if status_x1 != cttEVM_Success:
|
||||
return status_x1
|
||||
|
||||
let status_y0 = dst.y.c0.parseRawUint(y0)
|
||||
if status_y0 != cttEVM_Success:
|
||||
return status_y0
|
||||
let status_y1 = dst.y.c1.parseRawUint(y1)
|
||||
if status_y1 != cttEVM_Success:
|
||||
return status_y1
|
||||
|
||||
# Handle point at infinity
|
||||
if dst.x.isZero().bool and dst.y.isZero().bool:
|
||||
return cttEVM_Success
|
||||
|
||||
# Deserialization checks
|
||||
# ----------------------
|
||||
|
||||
# Point on curve
|
||||
if not bool(isOnCurve(dst.x, dst.y, OnTwist)):
|
||||
return cttEVM_PointNotOnCurve
|
||||
|
||||
if not subgroupCheck(dst):
|
||||
return cttEVM_PointNotInSubgroup
|
||||
|
||||
return cttEVM_Success
|
||||
|
||||
func eth_evm_ecpairing*(
|
||||
r: var array[32, byte], inputs: openarray[byte]): CttEVMStatus =
|
||||
## Elliptic Curve pairing on BN254_Snarks
|
||||
## (also called alt_bn128 in Ethereum specs
|
||||
## and bn256 in Ethereum tests)
|
||||
##
|
||||
## Name: ECPAIRING
|
||||
##
|
||||
## Inputs:
|
||||
## - An array of [(P0, Q0), (P1, Q1), ... (Pk, Qk)] points in (G1, G2)
|
||||
##
|
||||
## Output
|
||||
## - 0 or 1 in uint256 BigEndian representation
|
||||
## - Status code:
|
||||
## cttEVM_Success
|
||||
## cttEVM_IntLargerThanModulus
|
||||
## cttEVM_PointNotOnCurve
|
||||
## cttEVM_InvalidInputLength
|
||||
##
|
||||
## Spec https://eips.ethereum.org/EIPS/eip-197
|
||||
|
||||
let N = inputs.len div 192
|
||||
if inputs.len mod 192 != 0:
|
||||
return cttEVM_InvalidInputLength
|
||||
|
||||
if N == 0:
|
||||
# Spec: "Empty input is valid and results in returning one."
|
||||
zeroMem(r.addr, r.sizeof())
|
||||
r[^1] = byte 1
|
||||
return
|
||||
|
||||
var gt0{.noInit.}, gt1{.noInit.}: Fp12[BN254_Snarks]
|
||||
var P{.noInit.}: ECP_ShortW_Aff[Fp[BN254_Snarks], NotOnTwist]
|
||||
var Q{.noInit.}: ECP_ShortW_Aff[Fp2[BN254_Snarks], OnTwist]
|
||||
|
||||
for i in 0 ..< N:
|
||||
let pos = i*192
|
||||
|
||||
let statusP = P.fromRawCoords(
|
||||
x = inputs.toOpenArray(pos, pos+31),
|
||||
y = inputs.toOpenArray(pos+32, pos+63)
|
||||
)
|
||||
if statusP != cttEVM_Success:
|
||||
return statusP
|
||||
|
||||
# Warning EIP197 encoding order:
|
||||
# Fp2 (a, b) <=> a*𝑖 + b instead of regular a+𝑖b
|
||||
let statusQ = Q.fromRawCoords(
|
||||
x1 = inputs.toOpenArray(pos+64, pos+95),
|
||||
x0 = inputs.toOpenArray(pos+96, pos+127),
|
||||
y1 = inputs.toOpenArray(pos+128, pos+159),
|
||||
y0 = inputs.toOpenArray(pos+160, pos+191)
|
||||
)
|
||||
if statusQ != cttEVM_Success:
|
||||
return statusQ
|
||||
|
||||
gt1.millerLoopGenericBN(P, Q)
|
||||
if i == 0:
|
||||
gt0 = gt1
|
||||
else:
|
||||
gt0 *= gt1
|
||||
|
||||
gt0.finalExpEasy()
|
||||
gt0.finalExpHard_BN()
|
||||
|
||||
zeroMem(r.addr, r.sizeof())
|
||||
if gt0.isOne().bool:
|
||||
r[^1] = byte 1
|
|
@ -564,8 +564,7 @@ func `/=`*[C: static Curve](a: var Fp2[C], _: type NonResidue) =
|
|||
var a0 = a.c0
|
||||
let a1 = a.c1
|
||||
const u2v2 = u*u - Beta*v*v # (u² - βv²)
|
||||
# TODO can be precomputed (or precompute b/µ the twist coefficient)
|
||||
# and use faster non-constant-time inversion in the VM
|
||||
# TODO can be precomputed to avoid costly inversion.
|
||||
var u2v2inv {.noInit.}: a.c0.typeof
|
||||
u2v2inv.fromUint(u2v2)
|
||||
u2v2inv.inv()
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
#!/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 = ""):
|
||||
result = '# ' + comment_above + '\n' if comment_above else ''
|
||||
comment_right = ' # ' + comment_right if comment_right else ''
|
||||
|
||||
if field == 'Fp2':
|
||||
v = vector(value)
|
||||
|
||||
result += inspect.cleandoc(f"""
|
||||
{prefix}Fp2[{curve}].fromHex( {comment_right}
|
||||
"0x{Integer(v[0]).hex()}",
|
||||
"0x{Integer(v[1]).hex()}"
|
||||
)""")
|
||||
elif field == 'Fp':
|
||||
result += inspect.cleandoc(f"""
|
||||
{prefix}Fp[{curve}].fromHex( {comment_right}
|
||||
"0x{Integer(value).hex()}")
|
||||
""")
|
||||
else:
|
||||
raise NotImplementedError()
|
||||
|
||||
return result
|
||||
|
||||
# Code generators
|
||||
# ---------------------------------------------------------
|
||||
|
||||
def gen_coef_b_on_G2(curve_name, curve_config):
|
||||
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']
|
||||
elif G2_field_degree == 1:
|
||||
if twist_degree == 6:
|
||||
# Only for complete serialization
|
||||
non_residue_fp = curve_config[curve_name]['tower']['SNR_Fp']
|
||||
else:
|
||||
raise NotImplementedError()
|
||||
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()
|
||||
elif G2_field == 'Fp':
|
||||
G2F = Fp
|
||||
if twist_degree == 6:
|
||||
non_residue_twist = curve_config[curve_name]['tower']['SNR_Fp']
|
||||
else:
|
||||
raise NotImplementedError()
|
||||
else:
|
||||
raise NotImplementedError()
|
||||
|
||||
if twist == 'D_Twist':
|
||||
G2B = b/G2F(non_residue_twist)
|
||||
G2 = EllipticCurve(G2F, [0, G2B])
|
||||
elif twist == 'M_Twist':
|
||||
G2B = b*G2F(non_residue_twist)
|
||||
G2 = EllipticCurve(G2F, [0, G2B])
|
||||
else:
|
||||
raise ValueError('G2 must be a D_Twist or M_Twist but found ' + twist)
|
||||
|
||||
buf = inspect.cleandoc(f"""
|
||||
# Curve precomputed parameters
|
||||
# -----------------------------------------------------------------
|
||||
""")
|
||||
buf += '\n'
|
||||
|
||||
buf += f'const {curve_name}_coefB_G2* = '
|
||||
buf += field_to_nim(G2B, G2_field, curve_name)
|
||||
buf += '\n'
|
||||
|
||||
return buf
|
||||
|
||||
# CLI
|
||||
# ---------------------------------------------------------
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Usage
|
||||
# BLS12-381
|
||||
# sage sage/precompute_params.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:
|
||||
G2B = gen_coef_b_on_G2(curve, Curves)
|
||||
|
||||
with open(f'{curve.lower()}_precomputed_params.nim', 'w') as f:
|
||||
f.write(copyright())
|
||||
f.write('\n\n')
|
||||
|
||||
f.write(inspect.cleandoc("""
|
||||
import
|
||||
../config/curves,
|
||||
../io/io_towers
|
||||
"""))
|
||||
|
||||
f.write('\n\n')
|
||||
f.write(G2B)
|
||||
|
||||
print(f'Successfully created {curve.lower()}_precomputed_params.nim')
|
|
@ -0,0 +1,119 @@
|
|||
{
|
||||
"func": "bn256add",
|
||||
"fork": "Istanbul",
|
||||
"data":
|
||||
[
|
||||
{
|
||||
"Input": "18b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc9063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f3726607c2b7f58a84bd6145f00c9c2bc0bb1a187f20ff2c92963a88019e7c6a014eed06614e20c147e940f2d70da3f74c9a17df361706a4485c742bd6788478fa17d7",
|
||||
"Expected": "2243525c5efd4b9c3d3c45ac0ca3fe4dd85e830a4ce6b65fa1eeaee202839703301d1d33be6da8e509df21cc35964723180eed7532537db9ae5e7d48f195c915",
|
||||
"Name": "chfast1",
|
||||
"Gas": 150,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "2243525c5efd4b9c3d3c45ac0ca3fe4dd85e830a4ce6b65fa1eeaee202839703301d1d33be6da8e509df21cc35964723180eed7532537db9ae5e7d48f195c91518b18acfb4c2c30276db5411368e7185b311dd124691610c5d3b74034e093dc9063c909c4720840cb5134cb9f59fa749755796819658d32efc0d288198f37266",
|
||||
"Expected": "2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb721611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb204",
|
||||
"Name": "chfast2",
|
||||
"Gas": 150,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Name": "cdetrio1",
|
||||
"Gas": 150,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Name": "cdetrio2",
|
||||
"Gas": 150,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Name": "cdetrio3",
|
||||
"Gas": 150,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "",
|
||||
"Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Name": "cdetrio4",
|
||||
"Gas": 150,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Name": "cdetrio5",
|
||||
"Gas": 150,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
|
||||
"Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
|
||||
"Name": "cdetrio6",
|
||||
"Gas": 150,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
|
||||
"Name": "cdetrio7",
|
||||
"Gas": 150,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
|
||||
"Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
|
||||
"Name": "cdetrio8",
|
||||
"Gas": 150,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
|
||||
"Gas": 150,
|
||||
"Name": "cdetrio9",
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Expected": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
|
||||
"Gas": 150,
|
||||
"Name": "cdetrio10",
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "0000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002",
|
||||
"Expected": "030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd315ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4",
|
||||
"Name": "cdetrio11",
|
||||
"Gas": 150,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Expected": "030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd315ed738c0e0a7c92e7845f96b2ae9c0a68a6a449e3538fc7ff3ebf7a5a18a2c4",
|
||||
"Name": "cdetrio12",
|
||||
"Gas": 150,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98",
|
||||
"Expected": "15bf2bb17880144b5d1cd2b1f46eff9d617bffd1ca57c37fb5a49bd84e53cf66049c797f9ce0d17083deb32b5e36f2ea2a212ee036598dd7624c168993d1355f",
|
||||
"Name": "cdetrio13",
|
||||
"Gas": 150,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa92e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Expected": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Name": "cdetrio14",
|
||||
"Gas": 150,
|
||||
"NoBenchmark": false
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
{
|
||||
"func": "bn256mul",
|
||||
"fork": "Byzantium",
|
||||
"data":
|
||||
[
|
||||
{
|
||||
"Input": "2bd3e6d0f3b142924f5ca7b49ce5b9d54c4703d7ae5648e61d02268b1a0a9fb721611ce0a6af85915e2f1d70300909ce2e49dfad4a4619c8390cae66cefdb20400000000000000000000000000000000000000000000000011138ce750fa15c2",
|
||||
"Expected": "070a8d6a982153cae4be29d434e8faef8a47b274a053f5a4ee2a6c9c13c31e5c031b8ce914eba3a9ffb989f9cdd5b0f01943074bf4f0f315690ec3cec6981afc",
|
||||
"Name": "chfast1",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "070a8d6a982153cae4be29d434e8faef8a47b274a053f5a4ee2a6c9c13c31e5c031b8ce914eba3a9ffb989f9cdd5b0f01943074bf4f0f315690ec3cec6981afc30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd46",
|
||||
"Expected": "025a6f4181d2b4ea8b724290ffb40156eb0adb514c688556eb79cdea0752c2bb2eff3f31dea215f1eb86023a133a996eb6300b44da664d64251d05381bb8a02e",
|
||||
"Name": "chfast2",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "025a6f4181d2b4ea8b724290ffb40156eb0adb514c688556eb79cdea0752c2bb2eff3f31dea215f1eb86023a133a996eb6300b44da664d64251d05381bb8a02e183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7ea3",
|
||||
"Expected": "14789d0d4a730b354403b5fac948113739e276c23e0258d8596ee72f9cd9d3230af18a63153e0ec25ff9f2951dd3fa90ed0197bfef6e2a1a62b5095b9d2b4a27",
|
||||
"Name": "chfast3",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"Expected": "2cde5879ba6f13c0b5aa4ef627f159a3347df9722efce88a9afbb20b763b4c411aa7e43076f6aee272755a7f9b84832e71559ba0d2e0b17d5f9f01755e5b0d11",
|
||||
"Name": "cdetrio1",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f630644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000",
|
||||
"Expected": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe3163511ddc1c3f25d396745388200081287b3fd1472d8339d5fecb2eae0830451",
|
||||
"Name": "cdetrio2",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": true
|
||||
},
|
||||
{
|
||||
"Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000100000000000000000000000000000000",
|
||||
"Expected": "1051acb0700ec6d42a88215852d582efbaef31529b6fcbc3277b5c1b300f5cf0135b2394bb45ab04b8bd7611bd2dfe1de6a4e6e2ccea1ea1955f577cd66af85b",
|
||||
"Name": "cdetrio3",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": true
|
||||
},
|
||||
{
|
||||
"Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000009",
|
||||
"Expected": "1dbad7d39dbc56379f78fac1bca147dc8e66de1b9d183c7b167351bfe0aeab742cd757d51289cd8dbd0acf9e673ad67d0f0a89f912af47ed1be53664f5692575",
|
||||
"Name": "cdetrio4",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": true
|
||||
},
|
||||
{
|
||||
"Input": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f60000000000000000000000000000000000000000000000000000000000000001",
|
||||
"Expected": "1a87b0584ce92f4593d161480614f2989035225609f08058ccfa3d0f940febe31a2f3c951f6dadcc7ee9007dff81504b0fcd6d7cf59996efdc33d92bf7f9f8f6",
|
||||
"Name": "cdetrio5",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": true
|
||||
},
|
||||
{
|
||||
"Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"Expected": "29e587aadd7c06722aabba753017c093f70ba7eb1f1c0104ec0564e7e3e21f6022b1143f6a41008e7755c71c3d00b6b915d386de21783ef590486d8afa8453b1",
|
||||
"Name": "cdetrio6",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000",
|
||||
"Expected": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa92e83f8d734803fc370eba25ed1f6b8768bd6d83887b87165fc2434fe11a830cb",
|
||||
"Name": "cdetrio7",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": true
|
||||
},
|
||||
{
|
||||
"Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000100000000000000000000000000000000",
|
||||
"Expected": "221a3577763877920d0d14a91cd59b9479f83b87a653bb41f82a3f6f120cea7c2752c7f64cdd7f0e494bff7b60419f242210f2026ed2ec70f89f78a4c56a1f15",
|
||||
"Name": "cdetrio8",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": true
|
||||
},
|
||||
{
|
||||
"Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000000000000000000000000000000000009",
|
||||
"Expected": "228e687a379ba154554040f8821f4e41ee2be287c201aa9c3bc02c9dd12f1e691e0fd6ee672d04cfd924ed8fdc7ba5f2d06c53c1edc30f65f2af5a5b97f0a76a",
|
||||
"Name": "cdetrio9",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": true
|
||||
},
|
||||
{
|
||||
"Input": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"Expected": "17c139df0efee0f766bc0204762b774362e4ded88953a39ce849a8a7fa163fa901e0559bacb160664764a357af8a9fe70baa9258e0b959273ffc5718c6d4cc7c",
|
||||
"Name": "cdetrio10",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": true
|
||||
},
|
||||
{
|
||||
"Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff",
|
||||
"Expected": "00a1a234d08efaa2616607e31eca1980128b00b415c845ff25bba3afcb81dc00242077290ed33906aeb8e42fd98c41bcb9057ba03421af3f2d08cfc441186024",
|
||||
"Name": "cdetrio11",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d9830644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000000",
|
||||
"Expected": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b8692929ee761a352600f54921df9bf472e66217e7bb0cee9032e00acc86b3c8bfaf",
|
||||
"Name": "cdetrio12",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": true
|
||||
},
|
||||
{
|
||||
"Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000100000000000000000000000000000000",
|
||||
"Expected": "1071b63011e8c222c5a771dfa03c2e11aac9666dd097f2c620852c3951a4376a2f46fe2f73e1cf310a168d56baa5575a8319389d7bfa6b29ee2d908305791434",
|
||||
"Name": "cdetrio13",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": true
|
||||
},
|
||||
{
|
||||
"Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000009",
|
||||
"Expected": "19f75b9dd68c080a688774a6213f131e3052bd353a304a189d7a2ee367e3c2582612f545fb9fc89fde80fd81c68fc7dcb27fea5fc124eeda69433cf5c46d2d7f",
|
||||
"Name": "cdetrio14",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": true
|
||||
},
|
||||
{
|
||||
"Input": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d980000000000000000000000000000000000000000000000000000000000000001",
|
||||
"Expected": "039730ea8dff1254c0fee9c0ea777d29a9c710b7e616683f194f18c43b43b869073a5ffcc6fc7a28c30723d6e58ce577356982d65b833a5a5c15bf9024b43d98",
|
||||
"Name": "cdetrio15",
|
||||
"Gas": 40000,
|
||||
"NoBenchmark": true
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
{
|
||||
"func": "ecpairing",
|
||||
"fork": "byzantium",
|
||||
"data":
|
||||
[
|
||||
{
|
||||
"Input": "1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f593034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf704bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a416782bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c2032c61a830e3c17286de9462bf242fca2883585b93870a73853face6a6bf411198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa",
|
||||
"Expected": "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"Name": "jeff1",
|
||||
"Gas": 260000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "2eca0c7238bf16e83e7a1e6c5d49540685ff51380f309842a98561558019fc0203d3260361bb8451de5ff5ecd17f010ff22f5c31cdf184e9020b06fa5997db841213d2149b006137fcfb23036606f848d638d576a120ca981b5b1a5f9300b3ee2276cf730cf493cd95d64677bbb75fc42db72513a4c1e387b476d056f80aa75f21ee6226d31426322afcda621464d0611d226783262e21bb3bc86b537e986237096df1f82dff337dd5972e32a8ad43e28a78a96a823ef1cd4debe12b6552ea5f06967a1237ebfeca9aaae0d6d0bab8e28c198c5a339ef8a2407e31cdac516db922160fa257a5fd5b280642ff47b65eca77e626cb685c84fa6d3b6882a283ddd1198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa",
|
||||
"Expected": "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"Name": "jeff2",
|
||||
"Gas": 260000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "0f25929bcb43d5a57391564615c9e70a992b10eafa4db109709649cf48c50dd216da2f5cb6be7a0aa72c440c53c9bbdfec6c36c7d515536431b3a865468acbba2e89718ad33c8bed92e210e81d1853435399a271913a6520736a4729cf0d51eb01a9e2ffa2e92599b68e44de5bcf354fa2642bd4f26b259daa6f7ce3ed57aeb314a9a87b789a58af499b314e13c3d65bede56c07ea2d418d6874857b70763713178fb49a2d6cd347dc58973ff49613a20757d0fcc22079f9abd10c3baee245901b9e027bd5cfc2cb5db82d4dc9677ac795ec500ecd47deee3b5da006d6d049b811d7511c78158de484232fc68daf8a45cf217d1c2fae693ff5871e8752d73b21198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa",
|
||||
"Expected": "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"Name": "jeff3",
|
||||
"Gas": 260000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "2f2ea0b3da1e8ef11914acf8b2e1b32d99df51f5f4f206fc6b947eae860eddb6068134ddb33dc888ef446b648d72338684d678d2eb2371c61a50734d78da4b7225f83c8b6ab9de74e7da488ef02645c5a16a6652c3c71a15dc37fe3a5dcb7cb122acdedd6308e3bb230d226d16a105295f523a8a02bfc5e8bd2da135ac4c245d065bbad92e7c4e31bf3757f1fe7362a63fbfee50e7dc68da116e67d600d9bf6806d302580dc0661002994e7cd3a7f224e7ddc27802777486bf80f40e4ca3cfdb186bac5188a98c45e6016873d107f5cd131f3a3e339d0375e58bd6219347b008122ae2b09e539e152ec5364e7e2204b03d11d3caa038bfc7cd499f8176aacbee1f39e4e4afc4bc74790a4a028aff2c3d2538731fb755edefd8cb48d6ea589b5e283f150794b6736f670d6a1033f9b46c6f5204f50813eb85c8dc4b59db1c5d39140d97ee4d2b36d99bc49974d18ecca3e7ad51011956051b464d9e27d46cc25e0764bb98575bd466d32db7b15f582b2d5c452b36aa394b789366e5e3ca5aabd415794ab061441e51d01e94640b7e3084a07e02c78cf3103c542bc5b298669f211b88da1679b0b64a63b7e0e7bfe52aae524f73a55be7fe70c7e9bfc94b4cf0da1213d2149b006137fcfb23036606f848d638d576a120ca981b5b1a5f9300b3ee2276cf730cf493cd95d64677bbb75fc42db72513a4c1e387b476d056f80aa75f21ee6226d31426322afcda621464d0611d226783262e21bb3bc86b537e986237096df1f82dff337dd5972e32a8ad43e28a78a96a823ef1cd4debe12b6552ea5f",
|
||||
"Expected": "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"Name": "jeff4",
|
||||
"Gas": 340000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "20a754d2071d4d53903e3b31a7e98ad6882d58aec240ef981fdf0a9d22c5926a29c853fcea789887315916bbeb89ca37edb355b4f980c9a12a94f30deeed30211213d2149b006137fcfb23036606f848d638d576a120ca981b5b1a5f9300b3ee2276cf730cf493cd95d64677bbb75fc42db72513a4c1e387b476d056f80aa75f21ee6226d31426322afcda621464d0611d226783262e21bb3bc86b537e986237096df1f82dff337dd5972e32a8ad43e28a78a96a823ef1cd4debe12b6552ea5f1abb4a25eb9379ae96c84fff9f0540abcfc0a0d11aeda02d4f37e4baf74cb0c11073b3ff2cdbb38755f8691ea59e9606696b3ff278acfc098fa8226470d03869217cee0a9ad79a4493b5253e2e4e3a39fc2df38419f230d341f60cb064a0ac290a3d76f140db8418ba512272381446eb73958670f00cf46f1d9e64cba057b53c26f64a8ec70387a13e41430ed3ee4a7db2059cc5fc13c067194bcc0cb49a98552fd72bd9edb657346127da132e5b82ab908f5816c826acb499e22f2412d1a2d70f25929bcb43d5a57391564615c9e70a992b10eafa4db109709649cf48c50dd2198a1f162a73261f112401aa2db79c7dab1533c9935c77290a6ce3b191f2318d198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa",
|
||||
"Expected": "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"Name": "jeff5",
|
||||
"Gas": 340000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "1c76476f4def4bb94541d57ebba1193381ffa7aa76ada664dd31c16024c43f593034dd2920f673e204fee2811c678745fc819b55d3e9d294e45c9b03a76aef41209dd15ebff5d46c4bd888e51a93cf99a7329636c63514396b4a452003a35bf704bf11ca01483bfa8b34b43561848d28905960114c8ac04049af4b6315a416782bb8324af6cfc93537a2ad1a445cfd0ca2a71acd7ac41fadbf933c2a51be344d120a2a4cf30c1bf9845f20c6fe39e07ea2cce61f0c9bb048165fe5e4de877550111e129f1cf1097710d41c4ac70fcdfa5ba2023c6ff1cbeac322de49d1b6df7c103188585e2364128fe25c70558f1560f4f9350baf3959e603cc91486e110936198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa",
|
||||
"Expected": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Name": "jeff6",
|
||||
"Gas": 260000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "",
|
||||
"Expected": "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"Name": "empty_data",
|
||||
"Gas": 100000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa",
|
||||
"Expected": "0000000000000000000000000000000000000000000000000000000000000000",
|
||||
"Name": "one_point",
|
||||
"Gas": 180000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d",
|
||||
"Expected": "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"Name": "two_point_match_2",
|
||||
"Gas": 260000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa",
|
||||
"Expected": "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"Name": "two_point_match_3",
|
||||
"Gas": 260000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "105456a333e6d636854f987ea7bb713dfd0ae8371a72aea313ae0c32c0bf10160cf031d41b41557f3e7e3ba0c51bebe5da8e6ecd855ec50fc87efcdeac168bcc0476be093a6d2b4bbf907172049874af11e1b6267606e00804d3ff0037ec57fd3010c68cb50161b7d1d96bb71edfec9880171954e56871abf3d93cc94d745fa114c059d74e5b6c4ec14ae5864ebe23a71781d86c29fb8fb6cce94f70d3de7a2101b33461f39d9e887dbb100f170a2345dde3c07e256d1dfa2b657ba5cd030427000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000021a2c3013d2ea92e13c800cde68ef56a294b883f6ac35d25f587c09b1b3c635f7290158a80cd3d66530f74dc94c94adb88f5cdb481acca997b6e60071f08a115f2f997f3dbd66a7afe07fe7862ce239edba9e05c5afff7f8a1259c9733b2dfbb929d1691530ca701b4a106054688728c9972c8512e9789e9567aae23e302ccd75",
|
||||
"Expected": "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"Name": "two_point_match_4",
|
||||
"Gas": 260000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed275dc4a288d1afb3cbb1ac09187524c7db36395df7be3b99e673b13a075a65ec1d9befcd05a5323e6da4d435f3b617cdb3af83285c2df711ef39c01571827f9d",
|
||||
"Expected": "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"Name": "ten_point_match_1",
|
||||
"Gas": 900000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002203e205db4f19b37b60121b83a7333706db86431c6d835849957ed8c3928ad7927dc7234fd11d3e8c36c59277c3e6f149d5cd3cfa9a62aee49f8130962b4b3b9195e8aa5b7827463722b8c153931579d3505566b4edf48d498e185f0509de15204bb53b8977e5f92a0bc372742c4830944a59b4fe6b1c0466e2a6dad122b5d2e030644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd31a76dae6d3272396d0cbe61fced2bc532edac647851e3ac53ce1cc9c7e645a83198e9393920d483a7260bfb731fb5d25f1aa493335a9e71297e485b7aef312c21800deef121f1e76426a00665e5c4479674322d4f75edadd46debd5cd992f6ed090689d0585ff075ec9e99ad690c3395bc4b313370b38ef355acdadcd122975b12c85ea5db8c6deb4aab71808dcb408fe3d1e7690c43d37b4ce6cc0166fa7daa",
|
||||
"Expected": "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"Name": "ten_point_match_2",
|
||||
"Gas": 900000,
|
||||
"NoBenchmark": false
|
||||
},
|
||||
{
|
||||
"Input": "105456a333e6d636854f987ea7bb713dfd0ae8371a72aea313ae0c32c0bf10160cf031d41b41557f3e7e3ba0c51bebe5da8e6ecd855ec50fc87efcdeac168bcc0476be093a6d2b4bbf907172049874af11e1b6267606e00804d3ff0037ec57fd3010c68cb50161b7d1d96bb71edfec9880171954e56871abf3d93cc94d745fa114c059d74e5b6c4ec14ae5864ebe23a71781d86c29fb8fb6cce94f70d3de7a2101b33461f39d9e887dbb100f170a2345dde3c07e256d1dfa2b657ba5cd030427000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000021a2c3013d2ea92e13c800cde68ef56a294b883f6ac35d25f587c09b1b3c635f7290158a80cd3d66530f74dc94c94adb88f5cdb481acca997b6e60071f08a115f2f997f3dbd66a7afe07fe7862ce239edba9e05c5afff7f8a1259c9733b2dfbb929d1691530ca701b4a106054688728c9972c8512e9789e9567aae23e302ccd75",
|
||||
"Expected": "0000000000000000000000000000000000000000000000000000000000000001",
|
||||
"Name": "ten_point_match_3",
|
||||
"Gas": 260000,
|
||||
"NoBenchmark": false
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
# 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],
|
||||
# Status
|
||||
stew/byteutils,
|
||||
# 3rd party
|
||||
jsony,
|
||||
# Internals
|
||||
../../constantine/io/io_bigints,
|
||||
../../constantine/protocols/ethereum_evm_precompiles
|
||||
|
||||
type
|
||||
BN256Tests = object
|
||||
`func`: string
|
||||
fork: string
|
||||
data: seq[BN256Test]
|
||||
|
||||
HexString = string
|
||||
|
||||
BN256Test = object
|
||||
Input: HexString
|
||||
Expected: HexString
|
||||
Name: string
|
||||
Gas: int
|
||||
NoBenchmark: bool
|
||||
|
||||
const
|
||||
TestVectorsDir* =
|
||||
currentSourcePath.rsplit(DirSep, 1)[0] / "ethereum_evm_precompiles"
|
||||
|
||||
proc loadVectors(TestType: typedesc, filename: string): TestType =
|
||||
let content = readFile(TestVectorsDir/filename)
|
||||
result = content.fromJson(TestType)
|
||||
|
||||
template runBN256Tests(filename: string, funcname: untyped, osize: static int) =
|
||||
proc `bn256testrunner _ funcname`() =
|
||||
let vec = loadVectors(BN256Tests, filename)
|
||||
echo "Running ", filename
|
||||
|
||||
for test in vec.data:
|
||||
stdout.write " Testing " & test.Name & " ... "
|
||||
|
||||
# Length: 2 hex characters -> 1 byte
|
||||
var inputbytes = newSeq[byte](test.Input.len div 2)
|
||||
test.Input.hexToPaddedByteArray(inputbytes, bigEndian)
|
||||
|
||||
var r: array[osize, byte]
|
||||
var expected: array[osize, byte]
|
||||
|
||||
let status = funcname(r, inputbytes)
|
||||
if status != cttEVM_Success:
|
||||
reset(r)
|
||||
|
||||
test.Expected.hexToPaddedByteArray(expected, bigEndian)
|
||||
|
||||
doAssert r == expected, "[Test Failure]\n" &
|
||||
" " & funcname.astToStr & " status: " & $status & "\n" &
|
||||
" " & "result: " & r.toHex() & "\n" &
|
||||
" " & "expected: " & expected.toHex() & '\n'
|
||||
|
||||
stdout.write "Success\n"
|
||||
|
||||
`bn256testrunner _ funcname`()
|
||||
|
||||
runBN256Tests("bn256Add.json", eth_evm_ecadd, 64)
|
||||
runBN256Tests("bn256mul.json", eth_evm_ecmul, 64)
|
||||
runBN256Tests("pairing.json", eth_evm_ecpairing, 32)
|
Loading…
Reference in New Issue