mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-02-18 04:43:32 +00:00
Optimize ecrecover ASM (#840)
* windowed mul * Working * Window of 4 bits * Fix * Comments * Unroll loop * Unroll loop * remove global * Minor * Minor * Implement `CALLVALUE, CALLDATALOAD, CALLDATASIZE, CALLDATACOPY` in interpreter * Minor * Doesn't work * Minor * Minor * wnaf msm * Working hardcoded values: 28657 opcodes * Working wnaf * Small wnaf optim * Precompute works * Working together * Bump to 129 bits * Working glv decomposition * Working MSM with GLV * Almost working * Working * ECC test folder * Working with real sig data * Fix tests + Clippy * Minor * Cleaning * Comments * Cleaning * Smaller glv test file * Print opcode count at the end of interpreter run * More constants * Add z3 proof that the GLV scalars are 129-bit or less * Minor change to z3 proof * Minor * Hamish's suggestion * Working * Cleaning * Clippy * PR feedback * Minor PR feedback
This commit is contained in:
parent
9990632f48
commit
ca002aeafa
@ -28,12 +28,13 @@ pub(crate) fn combined_kernel() -> Kernel {
|
||||
include_str!("asm/curve/bn254/curve_mul.asm"),
|
||||
include_str!("asm/curve/bn254/moddiv.asm"),
|
||||
include_str!("asm/curve/common.asm"),
|
||||
include_str!("asm/curve/secp256k1/curve_mul.asm"),
|
||||
include_str!("asm/curve/secp256k1/curve_add.asm"),
|
||||
include_str!("asm/curve/secp256k1/ecrecover.asm"),
|
||||
include_str!("asm/curve/secp256k1/inverse_scalar.asm"),
|
||||
include_str!("asm/curve/secp256k1/lift_x.asm"),
|
||||
include_str!("asm/curve/secp256k1/moddiv.asm"),
|
||||
include_str!("asm/curve/secp256k1/glv.asm"),
|
||||
include_str!("asm/curve/secp256k1/precomputation.asm"),
|
||||
include_str!("asm/exp.asm"),
|
||||
include_str!("asm/fields/fp6_macros.asm"),
|
||||
include_str!("asm/fields/fp6_mul.asm"),
|
||||
|
||||
@ -15,7 +15,7 @@ global ec_add_valid_points_secp:
|
||||
%jumpi(ec_add_first_zero)
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Check if the first point is the identity.
|
||||
// Check if the second point is the identity.
|
||||
DUP4
|
||||
// stack: y1, x0, y0, x1, y1, retdest
|
||||
DUP4
|
||||
@ -33,9 +33,9 @@ global ec_add_valid_points_secp:
|
||||
EQ
|
||||
// stack: x0 == x1, x0, y0, x1, y1, retdest
|
||||
%jumpi(ec_add_equal_first_coord)
|
||||
// Standard affine addition formula.
|
||||
global ec_add_valid_points_no_edge_case_secp:
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Otherwise, we can use the standard formula.
|
||||
// Compute lambda = (y0 - y1)/(x0 - x1)
|
||||
DUP4
|
||||
// stack: y1, x0, y0, x1, y1, retdest
|
||||
@ -174,66 +174,49 @@ ec_add_equal_first_coord:
|
||||
// Assumption: x0 == x1 and y0 == y1
|
||||
// Standard doubling formula.
|
||||
ec_add_equal_points:
|
||||
// stack: x0, y0, x1, y1, retdest
|
||||
|
||||
// Compute lambda = 3/2 * x0^2 / y0
|
||||
%secp_base
|
||||
// stack: N, x0, y0, x1, y1, retdest
|
||||
%secp_base
|
||||
// stack: N, N, x0, y0, x1, y1, retdest
|
||||
DUP3
|
||||
// stack: x0, N, N, x0, y0, x1, y1, retdest
|
||||
DUP1
|
||||
// stack: x0, x0, N, N, x0, y0, x1, y1, retdest
|
||||
%stack (x0, y0, x1, y1, retdest) -> (x0, x0, @SECP_BASE, @SECP_BASE, x0, y0, x1, y1, retdest)
|
||||
MULMOD
|
||||
// stack: x0^2, N, x0, y0, x1, y1, retdest with
|
||||
PUSH 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffe19 // 3/2 in the base field
|
||||
// stack: 3/2, x0^2, N, x0, y0, x1, y1, retdest
|
||||
MULMOD
|
||||
// stack: 3/2 * x0^2, x0, y0, x1, y1, retdest
|
||||
DUP3
|
||||
// stack: y0, 3/2 * x0^2, x0, y0, x1, y1, retdest
|
||||
%moddiv_secp_base
|
||||
// stack: lambda, x0, y0, x1, y1, retdest
|
||||
%jump(ec_add_valid_points_with_lambda)
|
||||
|
||||
// Secp256k1 elliptic curve doubling.
|
||||
// Assumption: (x0,y0) is a valid point.
|
||||
// Assumption: (x,y) is a valid point.
|
||||
// Standard doubling formula.
|
||||
global ec_double_secp:
|
||||
// stack: x0, y0, retdest
|
||||
DUP2
|
||||
// stack: y0, x0, y0, retdest
|
||||
DUP2
|
||||
// stack: x0, y0, x0, y0, retdest
|
||||
%jump(ec_add_equal_points)
|
||||
// stack: x, y, retdest
|
||||
DUP2 DUP2 %ec_isidentity
|
||||
// stack: (x,y)==(0,0), x, y, retdest
|
||||
%jumpi(retself)
|
||||
|
||||
// Compute lambda = 3/2 * x0^2 / y0
|
||||
%stack (x, y, retdest) -> (x, x, @SECP_BASE, @SECP_BASE, x, y, retdest)
|
||||
MULMOD
|
||||
PUSH 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffff7ffffe19 // 3/2 in the base field
|
||||
MULMOD
|
||||
DUP3
|
||||
%moddiv_secp_base
|
||||
%stack (lambda, x, y, retdest) -> (lambda, x, y, x, y, retdest)
|
||||
%jump(ec_add_valid_points_with_lambda)
|
||||
|
||||
retself:
|
||||
%stack (x, y, retdest) -> (retdest, x, y)
|
||||
JUMP
|
||||
|
||||
// Push the order of the Secp256k1 scalar field.
|
||||
%macro secp_base
|
||||
PUSH 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f
|
||||
PUSH @SECP_BASE
|
||||
%endmacro
|
||||
|
||||
// Modular subtraction. Subtraction x-y underflows iff x<x-y, so can be computed as N*(x<x-y) + x-y.
|
||||
// Modular subtraction.
|
||||
// TODO: Use SUBMOD when it's ready
|
||||
%macro submod_secp_base
|
||||
// stack: x, y
|
||||
SWAP1
|
||||
// stack: y, x
|
||||
DUP2
|
||||
// stack: x, y, x
|
||||
SUB
|
||||
// stack: x - y, x
|
||||
DUP1
|
||||
// stack: x - y, x - y, x
|
||||
SWAP2
|
||||
// stack: x, x - y, x - y
|
||||
LT
|
||||
// stack: x < x - y, x - y
|
||||
%secp_base
|
||||
// stack: N, x < x - y, x - y
|
||||
MUL
|
||||
// stack: N * (x < x - y), x - y
|
||||
ADD
|
||||
// (x-y) % N
|
||||
%stack (x, y) -> (@SECP_BASE, y, x, @SECP_BASE)
|
||||
SUB ADDMOD
|
||||
%endmacro
|
||||
|
||||
// Check if (x,y) is a valid curve point.
|
||||
|
||||
@ -1,71 +0,0 @@
|
||||
// Same algorithm as in `exp.asm`
|
||||
global ec_mul_valid_point_secp:
|
||||
// stack: x, y, s, retdest
|
||||
%stack (x,y) -> (x,y,x,y)
|
||||
%ec_isidentity
|
||||
// stack: (x,y)==(0,0), x, y, s, retdest
|
||||
%jumpi(ret_zero_ec_mul)
|
||||
DUP3
|
||||
// stack: s, x, y, s, retdest
|
||||
%jumpi(step_case)
|
||||
// stack: x, y, s, retdest
|
||||
%jump(ret_zero_ec_mul)
|
||||
|
||||
step_case:
|
||||
// stack: x, y, s, retdest
|
||||
PUSH recursion_return
|
||||
// stack: recursion_return, x, y, s, retdest
|
||||
PUSH 2
|
||||
// stack: 2, recursion_return, x, y, s, retdest
|
||||
DUP5
|
||||
// stack: s, 2, recursion_return, x, y, s, retdest
|
||||
DIV
|
||||
// stack: s / 2, recursion_return, x, y, s, retdest
|
||||
PUSH step_case_contd
|
||||
// stack: step_case_contd, s / 2, recursion_return, x, y, s, retdest
|
||||
DUP5
|
||||
// stack: y, step_case_contd, s / 2, recursion_return, x, y, s, retdest
|
||||
DUP5
|
||||
// stack: x, y, step_case_contd, s / 2, recursion_return, x, y, s, retdest
|
||||
%jump(ec_double_secp)
|
||||
|
||||
// Assumption: 2(x,y) = (x',y')
|
||||
step_case_contd:
|
||||
// stack: x', y', s / 2, recursion_return, x, y, s, retdest
|
||||
%jump(ec_mul_valid_point_secp)
|
||||
|
||||
recursion_return:
|
||||
// stack: x', y', x, y, s, retdest
|
||||
SWAP4
|
||||
// stack: s, y', x, y, x', retdest
|
||||
PUSH 1
|
||||
// stack: 1, s, y', x, y, x', retdest
|
||||
AND
|
||||
// stack: s & 1, y', x, y, x', retdest
|
||||
SWAP1
|
||||
// stack: y', s & 1, x, y, x', retdest
|
||||
SWAP2
|
||||
// stack: x, s & 1, y', y, x', retdest
|
||||
SWAP3
|
||||
// stack: y, s & 1, y', x, x', retdest
|
||||
SWAP4
|
||||
// stack: x', s & 1, y', x, y, retdest
|
||||
SWAP1
|
||||
// stack: s & 1, x', y', x, y, retdest
|
||||
%jumpi(odd_scalar)
|
||||
// stack: x', y', x, y, retdest
|
||||
SWAP3
|
||||
// stack: y, y', x, x', retdest
|
||||
POP
|
||||
// stack: y', x, x', retdest
|
||||
SWAP1
|
||||
// stack: x, y', x', retdest
|
||||
POP
|
||||
// stack: y', x', retdest
|
||||
SWAP2
|
||||
// stack: retdest, x', y'
|
||||
JUMP
|
||||
|
||||
odd_scalar:
|
||||
// stack: x', y', x, y, retdest
|
||||
%jump(ec_add_valid_points_secp)
|
||||
@ -6,19 +6,7 @@ global ecrecover:
|
||||
%ecrecover_input_check
|
||||
// stack: isValid(v,r,s), hash, v, r, s, retdest
|
||||
|
||||
// Lift r to an elliptic curve point if possible.
|
||||
SWAP2
|
||||
// stack: v, hash, isValid(v,r,s), r, s, retdest
|
||||
DUP4
|
||||
// stack: r, v, hash, isValid(v,r,s), r, s, retdest
|
||||
|
||||
// Compute v-27 which gives the parity of the y-coordinate of the lifted point.
|
||||
SWAP1
|
||||
// stack: v, r, hash, isValid(v,r,s), r, s, retdest
|
||||
PUSH 27
|
||||
// stack: 27, v, r, hash, isValid(v,r,s), r, s, retdest
|
||||
SWAP1
|
||||
// stack: v, 27, r, hash, isValid(v,r,s), r, s, retdest
|
||||
%stack (valid, hash, v, r, s, retdest) -> (v, 27, r, hash, valid, r, s, retdest)
|
||||
SUB
|
||||
// stack: v - 27, r, hash, isValid(v,r,s), r, s, retdest
|
||||
SWAP1
|
||||
@ -62,70 +50,58 @@ ecrecover_valid_input:
|
||||
%mulmodn_secp_scalar
|
||||
// stack: u1, y, hash, x, r^(-1), retdest
|
||||
|
||||
|
||||
// Compute (X,Y) = u1 * (x,y)
|
||||
PUSH ecrecover_with_first_point
|
||||
// stack: ecrecover_with_first_point, u1, y, hash, x, r^(-1), retdest
|
||||
SWAP1
|
||||
// stack: u1, ecrecover_with_first_point, y, hash, x, r^(-1), retdest
|
||||
SWAP2
|
||||
// stack: y, ecrecover_with_first_point, u1, hash, x, r^(-1), retdest
|
||||
SWAP1
|
||||
// stack: ecrecover_with_first_point, y, u1, hash, x, r^(-1), retdest
|
||||
SWAP3
|
||||
// stack: hash, y, u1, ecrecover_with_first_point, x, r^(-1), retdest
|
||||
SWAP4
|
||||
// stack: x, y, u1, ecrecover_with_first_point, hash, r^(-1), retdest
|
||||
%jump(ec_mul_valid_point_secp)
|
||||
|
||||
// ecrecover precompile.
|
||||
// Assumption: (X,Y) = u1 * P. Result is (X,Y) + u2*GENERATOR
|
||||
ecrecover_with_first_point:
|
||||
// stack: X, Y, hash, r^(-1), retdest
|
||||
%secp_scalar
|
||||
// stack: p, X, Y, hash, r^(-1), retdest
|
||||
SWAP1
|
||||
// stack: X, p, Y, hash, r^(-1), retdest
|
||||
SWAP4
|
||||
// stack: r^(-1), p, Y, hash, X, retdest
|
||||
SWAP2
|
||||
// stack: Y, p, r^(-1), hash, X, retdest
|
||||
SWAP3
|
||||
// stack: hash, p, r^(-1), Y, X, retdest
|
||||
|
||||
// Compute u2 = -hash * r^(-1)
|
||||
MOD
|
||||
// stack: hash%p, r^(-1), Y, X, retdest
|
||||
%secp_scalar
|
||||
// stack: p, hash%p, r^(-1), Y, X, retdest
|
||||
SUB
|
||||
// stack: -hash, r^(-1), Y, X, retdest
|
||||
%mulmodn_secp_scalar
|
||||
// stack: u2, Y, X, retdest
|
||||
%stack (u1, y, hash, x, rinv, retdest) -> (hash, @SECP_SCALAR, @SECP_SCALAR, rinv, @SECP_SCALAR, u1, x, y, pubkey_to_addr, retdest)
|
||||
MOD SWAP1 SUB MULMOD
|
||||
// stack: u2, u1, x, y, pubkey_to_addr, retdest
|
||||
%jump(ecdsa_msm_with_glv)
|
||||
|
||||
// Compute u2 * GENERATOR and chain the call to `ec_mul` with a call to `ec_add` to compute PUBKEY = (X,Y) + u2 * GENERATOR,
|
||||
// and a call to `pubkey_to_addr` to get the final result `KECCAK256(PUBKEY)[-20:]`.
|
||||
PUSH pubkey_to_addr
|
||||
// stack: pubkey_to_addr, u2, Y, X, retdest
|
||||
SWAP3
|
||||
// stack: X, u2, Y, pubkey_to_addr, retdest
|
||||
PUSH ec_add_valid_points_secp
|
||||
// stack: ec_add_valid_points_secp, X, u2, Y, pubkey_to_addr, retdest
|
||||
SWAP1
|
||||
// stack: X, ec_add_valid_points_secp, u2, Y, pubkey_to_addr, retdest
|
||||
PUSH 0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798 // x-coordinate of generator
|
||||
// stack: Gx, X, ec_add_valid_points_secp, u2, Y, pubkey_to_addr, retdest
|
||||
SWAP1
|
||||
// stack: X, Gx, ec_add_valid_points_secp, u2, Y, pubkey_to_addr, retdest
|
||||
PUSH 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8 // y-coordinate of generator
|
||||
// stack: Gy, X, Gx, ec_add_valid_points_secp, u2, Y, pubkey_to_addr, retdest
|
||||
SWAP1
|
||||
// stack: X, Gy, Gx, ec_add_valid_points_secp, u2, Y, pubkey_to_addr, retdest
|
||||
SWAP4
|
||||
// stack: u2, Gy, Gx, ec_add_valid_points_secp, X, Y, pubkey_to_addr, retdest
|
||||
SWAP2
|
||||
// stack: Gx, Gy, u2, ec_add_valid_points_secp, X, Y, pubkey_to_addr, retdest
|
||||
%jump(ec_mul_valid_point_secp)
|
||||
// Computes `a * G + b * Q` using GLV+precomputation, where `G` is the Secp256k1 generator and `Q` is a point on the curve.
|
||||
// Pseudo-code:
|
||||
// precompute_table(G) -- precomputation table for the combinations of `G, phi(G), Q, phi(Q)`.
|
||||
// let a0, a1 = glv_decompose(a)
|
||||
// let b0, b1 = glv_decompose(b)
|
||||
// return msm_with_precomputation([a0, a1, b0, b1], [G, phi(G), Q, phi(Q)]) -- phi is the Secp endomorphism.
|
||||
ecdsa_msm_with_glv:
|
||||
%stack (a, b, Qx, Qy, retdest) -> (a, ecdsa_after_glv_a, b, Qx, Qy, retdest)
|
||||
%jump(glv_decompose)
|
||||
ecdsa_after_glv_a:
|
||||
%stack (a1neg, a0, a1, b, Qx, Qy, retdest) -> (b, ecdsa_after_glv_b, a1neg, a0, a1, Qx, Qy, retdest)
|
||||
%jump(glv_decompose)
|
||||
ecdsa_after_glv_b:
|
||||
%stack (b1neg, b0, b1, a1neg, a0, a1, Qx, Qy, retdest) -> (a1neg, b1neg, Qx, Qy, ecdsa_after_precompute, a0, a1, b0, b1, retdest)
|
||||
%jump(precompute_table)
|
||||
ecdsa_after_precompute:
|
||||
// stack: a0, a1, b0, b1, retdest
|
||||
PUSH 0 PUSH 0 PUSH 129 // 129 is the bit length of the GLV exponents
|
||||
// stack: i, accx, accy, a0, a1, b0, b1, retdest
|
||||
ecdsa_after_precompute_loop:
|
||||
%stack (i, accx, accy, a0, a1, b0, b1, retdest) -> (i, b1, i, accx, accy, a0, a1, b0, b1, retdest)
|
||||
SHR %and_const(1)
|
||||
%stack (bit_b1, i, accx, accy, a0, a1, b0, b1, retdest) -> (i, b0, bit_b1, i, accx, accy, a0, a1, b0, b1, retdest)
|
||||
SHR %and_const(1)
|
||||
%stack (bit_b0, bit_b1, i, accx, accy, a0, a1, b0, b1, retdest) -> (i, a1, bit_b0, bit_b1, i, accx, accy, a0, a1, b0, b1, retdest)
|
||||
SHR %and_const(1)
|
||||
%stack (bit_a1, bit_b0, bit_b1, i, accx, accy, a0, a1, b0, b1, retdest) -> (i, a0, bit_a1, bit_b0, bit_b1, i, accx, accy, a0, a1, b0, b1, retdest)
|
||||
SHR %and_const(1)
|
||||
%mul_const(2) ADD %mul_const(2) ADD %mul_const(2) ADD
|
||||
%stack (index, i, accx, accy, a0, a1, b0, b1, retdest) -> (index, index, i, accx, accy, a0, a1, b0, b1, retdest)
|
||||
%mul_const(2) %add_const(1)
|
||||
%mload_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
SWAP1 %mul_const(2)
|
||||
%mload_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
%stack (Px, Py, i, accx, accy, a0, a1, b0, b1, retdest) -> (Px, Py, accx, accy, ecdsa_after_precompute_loop_contd, i, a0, a1, b0, b1, retdest)
|
||||
%jump(ec_add_valid_points_secp)
|
||||
ecdsa_after_precompute_loop_contd:
|
||||
%stack (accx, accy, i, a0, a1, b0, b1, retdest) -> (i, accx, accy, ecdsa_after_precompute_loop_contd2, i, a0, a1, b0, b1, retdest)
|
||||
ISZERO %jumpi(ecdsa_after_precompute_loop_end)
|
||||
%jump(ec_double_secp)
|
||||
ecdsa_after_precompute_loop_contd2:
|
||||
%stack (accx, accy, i, a0, a1, b0, b1, retdest) -> (i, accx, accy, a0, a1, b0, b1, retdest)
|
||||
%decrement %jump(ecdsa_after_precompute_loop)
|
||||
ecdsa_after_precompute_loop_end:
|
||||
%stack (accx, accy, ecdsa_after_precompute_loop_contd2, i, a0, a1, b0, b1, retdest) -> (retdest, accx, accy)
|
||||
JUMP
|
||||
|
||||
// Take a public key (PKx, PKy) and return the associated address KECCAK256(PKx || PKy)[-20:].
|
||||
pubkey_to_addr:
|
||||
@ -207,13 +183,13 @@ pubkey_to_addr:
|
||||
%endmacro
|
||||
|
||||
%macro secp_scalar
|
||||
PUSH 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141
|
||||
PUSH @SECP_SCALAR
|
||||
%endmacro
|
||||
|
||||
// Return u256::MAX which is used to indicate the input was invalid.
|
||||
%macro ecrecover_invalid_input
|
||||
// stack: retdest
|
||||
PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
|
||||
PUSH @U256_MAX
|
||||
// stack: u256::MAX, retdest
|
||||
SWAP1
|
||||
// stack: retdest, u256::MAX
|
||||
|
||||
104
evm/src/cpu/kernel/asm/curve/secp256k1/glv.asm
Normal file
104
evm/src/cpu/kernel/asm/curve/secp256k1/glv.asm
Normal file
@ -0,0 +1,104 @@
|
||||
// Inspired by https://github.com/AztecProtocol/weierstrudel/blob/master/huff_modules/endomorphism.huff
|
||||
// See also Sage code in evm/src/cpu/kernel/tests/ecc/glv_test_data
|
||||
// Given scalar `k ∈ Secp256k1::ScalarField`, return `u, k1, k2` with `k1,k2 < 2^129` and such that
|
||||
// `k = k1 - s*k2` if `u==0` otherwise `k = k1 + s*k2`, where `s` is the scalar value representing the endomorphism.
|
||||
// In the comments below, N means @SECP_SCALAR
|
||||
//
|
||||
// Z3 proof that the resulting `k1, k2` satisfy `k1>0`, `k1 < 2^129` and `|k2| < 2^129`.
|
||||
// ```python
|
||||
// from z3 import Solver, Int, Or, unsat
|
||||
// q = 115792089237316195423570985008687907852837564279074904382605163141518161494337
|
||||
// glv_s = 37718080363155996902926221483475020450927657555482586988616620542887997980018
|
||||
// g1 = 303414439467246543595250775667605759172
|
||||
// g2 = 64502973549206556628585045361533709077
|
||||
// b2 = 64502973549206556628585045361533709077
|
||||
// b1 = -303414439467246543595250775667605759171
|
||||
// k = Int("k")
|
||||
// c1 = Int("c1")
|
||||
// c2 = Int("c2")
|
||||
// s = Solver()
|
||||
//
|
||||
// c2p = -c2
|
||||
// s.add(k < q)
|
||||
// s.add(0 < k)
|
||||
// s.add(c1 * (2**256) <= g2 * k)
|
||||
// s.add((c1 + 1) * (2**256) > g2 * k)
|
||||
// s.add(c2p * (2**256) <= g1 * k)
|
||||
// s.add((c2p + 1) * (2**256) > g1 * k)
|
||||
//
|
||||
// q1 = c1 * b1
|
||||
// q2 = c2 * b2
|
||||
//
|
||||
// k2 = q2 - q1
|
||||
// k2L = (glv_s * k2) % q
|
||||
// k1 = k - k2L
|
||||
//
|
||||
// s.add(Or((k2 >= 2**129), (-k2 >= 2**129), (k1 >= 2**129), (k1 < 0)))
|
||||
// assert s.check() == unsat
|
||||
// ```
|
||||
global glv_decompose:
|
||||
// stack: k, retdest
|
||||
PUSH @SECP_SCALAR DUP1 DUP1
|
||||
// Compute c2 which is the top 256 bits of k*g1. Use asm from https://medium.com/wicketh/mathemagic-full-multiply-27650fec525d.
|
||||
PUSH @U256_MAX
|
||||
// stack: -1, N, N, N, k, retdest
|
||||
PUSH @SECP_GLV_MINUS_G1 DUP6
|
||||
// stack: k, g1, -1, N, N, N, k, retdest
|
||||
MULMOD
|
||||
// stack: (k * g1 % -1), N, N, N, k, retdest
|
||||
PUSH @SECP_GLV_MINUS_G1 DUP6
|
||||
// stack: k, g1, (k * g1 % -1), N, N, N, k, retdest
|
||||
MUL
|
||||
// stack: bottom = (k * g1), (k * g1 % -1), N, N, N, k, retdest
|
||||
DUP1 DUP3
|
||||
// stack: (k * g1 % -1), bottom, bottom, (k * g1 % -1), N, N, N, k, retdest
|
||||
LT SWAP2 SUB SUB
|
||||
// stack: c2, N, N, N, k, retdest
|
||||
PUSH @SECP_GLV_B2 MULMOD
|
||||
// stack: q2=c2*b2, N, N, k, retdest
|
||||
|
||||
// Use the same trick to compute c1 = top 256 bits of g2*k.
|
||||
PUSH @SECP_SCALAR PUSH @U256_MAX
|
||||
PUSH @SECP_GLV_G2 DUP7 MULMOD
|
||||
PUSH @SECP_GLV_G2 DUP7 MUL
|
||||
DUP1 DUP3 LT
|
||||
SWAP2 SUB SUB
|
||||
// stack: c1, N, q2, N, N, k, retdest
|
||||
PUSH @SECP_GLV_B1 MULMOD
|
||||
// stack: q1, q2, N, N, k, retdest
|
||||
|
||||
// We compute k2 = q1 + q2 - N, but we check for underflow and return N-q1-q2 instead if there is one,
|
||||
// along with a flag `underflow` set to 1 if there is an underflow, 0 otherwise.
|
||||
ADD %sub_check_underflow
|
||||
// stack: k2, underflow, N, k, retdest
|
||||
SWAP3 PUSH @SECP_SCALAR DUP5 PUSH @SECP_GLV_S
|
||||
// stack: s, k2, N, k, underflow, N, k2, retdest
|
||||
MULMOD
|
||||
// stack: s*k2, k, underflow, N, k2, retdest
|
||||
// Need to return `k + s*k2` if no underflow occur, otherwise return `k - s*k2` which is done in the `underflowed` fn.
|
||||
SWAP2 DUP1 %jumpi(underflowed)
|
||||
%stack (underflow, k, x, N, k2) -> (k, x, N, k2, underflow)
|
||||
ADDMOD
|
||||
%stack (k1, k2, underflow, retdest) -> (retdest, underflow, k1, k2)
|
||||
JUMP
|
||||
|
||||
underflowed:
|
||||
// stack: underflow, k, s*k2, N, k2
|
||||
// Compute (k-s*k2)%N. TODO: Use SUBMOD here when ready
|
||||
%stack (u, k, x, N, k2) -> (N, x, k, N, k2, u)
|
||||
SUB ADDMOD
|
||||
%stack (k1, k2, underflow, retdest) -> (retdest, underflow, k1, k2)
|
||||
JUMP
|
||||
|
||||
%macro sub_check_underflow
|
||||
// stack: x, y
|
||||
DUP2 DUP2 LT
|
||||
// stack: x<y, x, y
|
||||
DUP1 ISZERO DUP2 DUP4 DUP6 SUB MUL
|
||||
// stack: (y-x)*(x<y), x>=y, x<y, x, y
|
||||
%stack (a, b, c, x, y) -> (x, y, b, a, c)
|
||||
SUB MUL ADD
|
||||
%stack (res, bool) -> (res, @SECP_SCALAR, bool)
|
||||
MOD
|
||||
%endmacro
|
||||
|
||||
74
evm/src/cpu/kernel/asm/curve/secp256k1/precomputation.asm
Normal file
74
evm/src/cpu/kernel/asm/curve/secp256k1/precomputation.asm
Normal file
@ -0,0 +1,74 @@
|
||||
// Initial stack: Gneg, Qneg, Qx, Qy, retdest
|
||||
// Compute a*G ± b*phi(G) + c*Q ± d*phi(Q) for a,b,c,d in {0,1}^4 and store its x-coordinate at location `2*(8a+4b+2c+d)` and its y-coordinate at location `2*(8a+4b+2c+d)+1` in the SEGMENT_KERNEL_ECDSA_TABLE segment.
|
||||
global precompute_table:
|
||||
// First store G, ± phi(G), G ± phi(G)
|
||||
// Use Gneg for the ±, e.g., ±phi(G) is computed as `Gneg * (-phi(G)) + (1-Gneg)*phi(G)` (note only the y-coordinate needs to be filtered).
|
||||
// stack: Gneg, Qneg, Qx, Qy, retdest
|
||||
PUSH 32670510020758816978083085130507043184471273380659243275938904335757337482424 PUSH 17 PUSH 55066263022277343669578718895168534326250603453777594175500187360389116729240 PUSH 16
|
||||
%mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE) %mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
|
||||
DUP1 DUP1 %mul_const(32670510020758816978083085130507043184471273380659243275938904335757337482424) SWAP1 PUSH 1 SUB %mul_const(83121579216557378445487899878180864668798711284981320763518679672151497189239) ADD
|
||||
PUSH 9 PUSH 85340279321737800624759429340272274763154997815782306132637707972559913914315 PUSH 8
|
||||
%mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE) %mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
|
||||
DUP1 DUP1 %mul_const(83121579216557378445487899878180864668798711284981320763518679672151497189239) SWAP1 PUSH 1 SUB %mul_const(100652675408719987021357910538015346127426077519185866739835120963490438734674) ADD
|
||||
PUSH 25
|
||||
%mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
|
||||
DUP1 %mul_const(91177636130617246552803821781935006617134368061721227770777272682868638699771) SWAP1 PUSH 1 SUB %mul_const(66837770201594535779099350687042404727408598709762866365333192677982385899440) ADD
|
||||
PUSH 24
|
||||
%mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
|
||||
// Then store Q, ±phi(Q), Q ± phi(Q)
|
||||
%stack (Qneg, Qx, Qy, retdest) -> (4, Qx, 5, Qy, Qx, @SECP_BASE, Qneg, Qx, Qy, retdest)
|
||||
%mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE) %mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
// stack: Qx, @SECP_BASE, Qx, Qy, retdest
|
||||
PUSH @SECP_GLV_BETA MULMOD
|
||||
%stack (betaQx, Qneg, Qx, Qy, retdest) -> (Qneg, Qy, Qneg, betaQx, Qx, Qy, retdest)
|
||||
MUL SWAP1 PUSH 1 SUB
|
||||
// stack: 1-Qneg, Qneg*Qy, betaQx, Qx, Qy, retdest
|
||||
DUP5 PUSH @SECP_BASE SUB MUL ADD
|
||||
%stack (selectQy, betaQx, Qx, Qy, retdest) -> (2, betaQx, 3, selectQy, betaQx, selectQy, Qx, Qy, precompute_table_contd, retdest)
|
||||
%mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE) %mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
%jump(ec_add_valid_points_no_edge_case_secp)
|
||||
precompute_table_contd:
|
||||
%stack (x, y, retdest) -> (6, x, 7, y, retdest)
|
||||
%mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE) %mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
PUSH 2
|
||||
// Use a loop to store a*G ± b*phi(G) + c*Q ± d*phi(Q) for a,b,c,d in {0,1}^4.
|
||||
precompute_table_loop:
|
||||
// stack: i, retdest
|
||||
DUP1 %increment %mload_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
%stack (y, i, retdest) -> (i, y, i, retdest)
|
||||
%mload_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
PUSH precompute_table_loop_contd
|
||||
DUP3 DUP3
|
||||
PUSH 9 %mload_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
PUSH 8 %mload_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
// stack: Gx, Gy, x, y, precompute_table_loop_contd, x, y, i, retdest
|
||||
%jump(ec_add_valid_points_secp)
|
||||
precompute_table_loop_contd:
|
||||
%stack (Rx, Ry, x, y, i, retdest) -> (i, 8, Rx, i, 9, Ry, x, y, i, retdest)
|
||||
ADD %mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE) ADD %mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
DUP2 DUP2
|
||||
PUSH 17 %mload_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
PUSH 16 %mload_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
%stack (Gx, Gy, x, y, x, y, i, retdest) -> (Gx, Gy, x, y, precompute_table_loop_contd2, x, y, i, retdest)
|
||||
%jump(ec_add_valid_points_secp)
|
||||
precompute_table_loop_contd2:
|
||||
%stack (Rx, Ry, x, y, i, retdest) -> (i, 16, Rx, i, 17, Ry, x, y, i, retdest)
|
||||
ADD %mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE) ADD %mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
PUSH 25 %mload_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
PUSH 24 %mload_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
%stack (Gx, Gy, x, y, i, retdest) -> (Gx, Gy, x, y, precompute_table_loop_contd3, i, retdest)
|
||||
%jump(ec_add_valid_points_secp)
|
||||
precompute_table_loop_contd3:
|
||||
%stack (Rx, Ry, i, retdest) -> (i, 24, Rx, i, 25, Ry, i, retdest)
|
||||
ADD %mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE) ADD %mstore_kernel(@SEGMENT_KERNEL_ECDSA_TABLE)
|
||||
%add_const(2)
|
||||
DUP1 %eq_const(8) %jumpi(precompute_table_end)
|
||||
%jump(precompute_table_loop)
|
||||
|
||||
precompute_table_end:
|
||||
// stack: i, retdest
|
||||
POP JUMP
|
||||
@ -133,7 +133,7 @@
|
||||
PUSH $c
|
||||
// stack: c, input, ...
|
||||
GT // Check it backwards: (input < c) == (c > input)
|
||||
// stack: input <= c, ...
|
||||
// stack: input < c, ...
|
||||
%endmacro
|
||||
|
||||
%macro le_const(c)
|
||||
|
||||
@ -63,7 +63,11 @@ const HASH_CONSTANTS: [(&str, [u8; 32]); 2] = [
|
||||
),
|
||||
];
|
||||
|
||||
const EC_CONSTANTS: [(&str, [u8; 32]); 3] = [
|
||||
const EC_CONSTANTS: [(&str, [u8; 32]); 10] = [
|
||||
(
|
||||
"U256_MAX",
|
||||
hex!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"),
|
||||
),
|
||||
(
|
||||
"BN_BASE",
|
||||
hex!("30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"),
|
||||
@ -76,6 +80,30 @@ const EC_CONSTANTS: [(&str, [u8; 32]); 3] = [
|
||||
"SECP_SCALAR",
|
||||
hex!("fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"),
|
||||
),
|
||||
(
|
||||
"SECP_GLV_BETA",
|
||||
hex!("7ae96a2b657c07106e64479eac3434e99cf0497512f58995c1396c28719501ee"),
|
||||
),
|
||||
(
|
||||
"SECP_GLV_S",
|
||||
hex!("5363ad4cc05c30e0a5261c028812645a122e22ea20816678df02967c1b23bd72"),
|
||||
),
|
||||
(
|
||||
"SECP_GLV_MINUS_G1",
|
||||
hex!("00000000000000000000000000000000e4437ed6010e88286f547fa90abfe4c4"),
|
||||
),
|
||||
(
|
||||
"SECP_GLV_G2",
|
||||
hex!("000000000000000000000000000000003086d221a7d46bcde86c90e49284eb15"),
|
||||
),
|
||||
(
|
||||
"SECP_GLV_B1",
|
||||
hex!("fffffffffffffffffffffffffffffffdd66b5e10ae3a1813507ddee3c5765c7e"),
|
||||
),
|
||||
(
|
||||
"SECP_GLV_B2",
|
||||
hex!("000000000000000000000000000000003086d221a7d46bcde86c90e49284eb15"),
|
||||
),
|
||||
];
|
||||
|
||||
const GAS_CONSTANTS: [(&str, u16); 36] = [
|
||||
|
||||
@ -32,7 +32,7 @@ const BN_BASE: U256 = U256([
|
||||
]);
|
||||
|
||||
impl MemoryState {
|
||||
fn mload_general(&self, context: usize, segment: Segment, offset: usize) -> U256 {
|
||||
pub(crate) fn mload_general(&self, context: usize, segment: Segment, offset: usize) -> U256 {
|
||||
self.get(MemoryAddress::new(context, segment, offset))
|
||||
}
|
||||
|
||||
@ -120,6 +120,7 @@ impl<'a> Interpreter<'a> {
|
||||
println!("{}: {}", get_mnemonic(i as u8), self.opcode_count[i])
|
||||
}
|
||||
}
|
||||
println!("Total: {}", self.opcode_count.into_iter().sum::<usize>());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@ -134,10 +134,12 @@ mod bn {
|
||||
|
||||
#[cfg(test)]
|
||||
mod secp {
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::cpu::kernel::aggregator::combined_kernel;
|
||||
use crate::cpu::kernel::interpreter::{run, run_interpreter};
|
||||
use anyhow::Result;
|
||||
use ethereum_types::U256;
|
||||
|
||||
use crate::cpu::kernel::aggregator::{combined_kernel, KERNEL};
|
||||
use crate::cpu::kernel::interpreter::{run, run_interpreter, Interpreter};
|
||||
use crate::cpu::kernel::tests::u256ify;
|
||||
|
||||
#[test]
|
||||
@ -146,7 +148,6 @@ mod secp {
|
||||
let kernel = combined_kernel();
|
||||
let ec_add = kernel.global_labels["ec_add_valid_points_secp"];
|
||||
let ec_double = kernel.global_labels["ec_double_secp"];
|
||||
let ec_mul = kernel.global_labels["ec_mul_valid_point_secp"];
|
||||
let identity = ("0x0", "0x0");
|
||||
let point0 = (
|
||||
"0xc82ccceebd739e646631b7270ed8c33e96c4940b19db91eaf67da6ec92d109b",
|
||||
@ -166,12 +167,6 @@ mod secp {
|
||||
"0x7872498939b02197c2b6f0a0f5767f36551e43f910de472fbbff0538b21f5f45",
|
||||
"0x294e15025d935438023a0e4056892abd6405fade13cf2b3131d8755be7cebad",
|
||||
);
|
||||
let s = "0xa72ad7d8ce24135b5138f853d7a9896381c40523b5d1cf03072151f2af10e35e";
|
||||
// point4 = s * point0
|
||||
let point4 = (
|
||||
"0xd8bec38864f0fe56d429540e6de624afb8ddc7fba1f738337913922a30b96c14",
|
||||
"0x5b086b2720ac39d173777bc36a49629c80c3a3e55e1c50527e60016d9be71318",
|
||||
);
|
||||
|
||||
// Standard addition #1
|
||||
let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0, point1.1, point1.0])?;
|
||||
@ -192,10 +187,6 @@ mod secp {
|
||||
let initial_stack = u256ify(["0xdeadbeef", point0.1, point0.0])?;
|
||||
let stack = run_interpreter(ec_double, initial_stack)?.stack().to_vec();
|
||||
assert_eq!(stack, u256ify([point3.1, point3.0])?);
|
||||
// Standard doubling #3
|
||||
let initial_stack = u256ify(["0xdeadbeef", "0x2", point0.1, point0.0])?;
|
||||
let stack = run_interpreter(ec_mul, initial_stack)?.stack().to_vec();
|
||||
assert_eq!(stack, u256ify([point3.1, point3.0])?);
|
||||
|
||||
// Addition with identity #1
|
||||
let initial_stack = u256ify(["0xdeadbeef", identity.1, identity.0, point1.1, point1.0])?;
|
||||
@ -211,36 +202,29 @@ mod secp {
|
||||
let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec();
|
||||
assert_eq!(stack, u256ify([identity.1, identity.0])?);
|
||||
|
||||
// Scalar multiplication #1
|
||||
let initial_stack = u256ify(["0xdeadbeef", s, point0.1, point0.0])?;
|
||||
let stack = run_interpreter(ec_mul, initial_stack)?.stack().to_vec();
|
||||
assert_eq!(stack, u256ify([point4.1, point4.0])?);
|
||||
// Scalar multiplication #2
|
||||
let initial_stack = u256ify(["0xdeadbeef", "0x0", point0.1, point0.0])?;
|
||||
let stack = run_interpreter(ec_mul, initial_stack)?.stack().to_vec();
|
||||
assert_eq!(stack, u256ify([identity.1, identity.0])?);
|
||||
// Scalar multiplication #3
|
||||
let initial_stack = u256ify(["0xdeadbeef", "0x1", point0.1, point0.0])?;
|
||||
let stack = run_interpreter(ec_mul, initial_stack)?.stack().to_vec();
|
||||
assert_eq!(stack, u256ify([point0.1, point0.0])?);
|
||||
// Scalar multiplication #4
|
||||
let initial_stack = u256ify(["0xdeadbeef", s, identity.1, identity.0])?;
|
||||
let stack = run_interpreter(ec_mul, initial_stack)?.stack().to_vec();
|
||||
assert_eq!(stack, u256ify([identity.1, identity.0])?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Multiple calls
|
||||
let ec_mul_hex = format!("0x{ec_mul:x}");
|
||||
let initial_stack = u256ify([
|
||||
"0xdeadbeef",
|
||||
s,
|
||||
&ec_mul_hex,
|
||||
identity.1,
|
||||
identity.0,
|
||||
point0.1,
|
||||
point0.0,
|
||||
])?;
|
||||
let stack = run_interpreter(ec_add, initial_stack)?.stack().to_vec();
|
||||
assert_eq!(stack, u256ify([point4.1, point4.0])?);
|
||||
#[test]
|
||||
fn test_glv_verify_data() -> Result<()> {
|
||||
let glv = KERNEL.global_labels["glv_decompose"];
|
||||
|
||||
let f = include_str!("glv_test_data");
|
||||
for line in f.lines().filter(|s| !s.starts_with("//")) {
|
||||
let mut line = line
|
||||
.split_whitespace()
|
||||
.map(|s| U256::from_str_radix(s, 10).unwrap())
|
||||
.collect::<Vec<_>>();
|
||||
let k = line.remove(0);
|
||||
line.reverse();
|
||||
|
||||
let mut initial_stack = u256ify(["0xdeadbeef"])?;
|
||||
initial_stack.push(k);
|
||||
let mut int = Interpreter::new(&KERNEL.code, glv, initial_stack, &KERNEL.prover_inputs);
|
||||
int.run()?;
|
||||
|
||||
assert_eq!(line, int.stack());
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -25,6 +25,24 @@ fn test_invalid_ecrecover(hash: &str, v: &str, r: &str, s: &str) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecrecover_real_block() -> Result<()> {
|
||||
let f = include_str!("ecrecover_test_data");
|
||||
let convert_v = |v| match v {
|
||||
// TODO: do this properly.
|
||||
"0" => "0x1b",
|
||||
"1" => "0x1c",
|
||||
"37" => "0x1b",
|
||||
"38" => "0x1c",
|
||||
_ => panic!("Invalid v."),
|
||||
};
|
||||
for line in f.lines().filter(|s| !s.starts_with("//")) {
|
||||
let line = line.split_whitespace().collect::<Vec<_>>();
|
||||
test_valid_ecrecover(line[4], convert_v(line[0]), line[1], line[2], line[3])?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecrecover() -> Result<()> {
|
||||
test_valid_ecrecover(
|
||||
184
evm/src/cpu/kernel/tests/ecc/ecrecover_test_data
Normal file
184
evm/src/cpu/kernel/tests/ecc/ecrecover_test_data
Normal file
@ -0,0 +1,184 @@
|
||||
// // `ethers.rs` code to get ECDSA data for every transaction in block 16141392.
|
||||
// #[tokio::main]
|
||||
// async fn main() -> Result<()> {
|
||||
// let provider =
|
||||
// Provider::<Http>::try_from("https://mainnet.infura.io/v3/c60b0bb42f8a4c6481ecd229eddaca27")
|
||||
// .expect("could not instantiate HTTP Provider");
|
||||
// let mut ans = String::new();
|
||||
// let block = provider.get_block(16141392).await?.unwrap();
|
||||
// for tx in block.transactions {
|
||||
// let tx = provider.get_transaction(tx).await?.unwrap();
|
||||
// let typed_tx: TypedTransaction = (&tx).into();
|
||||
// ans.push_str(&format!(
|
||||
// "{} 0x{:x} 0x{:x} {:?} {:?}\n",
|
||||
// tx.v,
|
||||
// tx.r,
|
||||
// tx.s,
|
||||
// tx.from,
|
||||
// typed_tx.sighash()
|
||||
// ));
|
||||
// }
|
||||
// let mut f = File::create("ecrecover_test_data").expect("Unable to create");
|
||||
// f.write_all(ans.as_bytes()).expect("Unable to write");
|
||||
// Ok(())
|
||||
// }
|
||||
37 0x71e206f9a89076270d57e93486946ce5803dbcb76279780aa41bf258763fad23 0x5f7e34e4a781f7572f8192b845de80fe24d77f13552dfefb67e03c94388934c 0x7a7f78a2af5aef01a889e8713083ab77dcc9fc9b 0xf457bef979aae3c1cbbb294a8f015a8e149a60ec0146383a4bec6fb097098d24
|
||||
1 0x57d71702dde291f2d7c6ea8b9d8172523b72e93db5a7426c5b898bb74d555a3b 0x47303ce56b157b8c237bc0206a610975ef690bd71912315a35fd01ea428b7520 0x1113efd5c8896ccf251ea360bb9d91f113707f80 0x65a5c566f3dea5f436bb33e8803be619c1c6d3857b0199335630e643a1e3774c
|
||||
38 0x6cb3fd5d878b8b234906bc447c9b6abac34fec019d82d1e1419874bff40f08e1 0x4de3f2f5babfa400a014739e705f64219824ed75ab16058835452366e00b7498 0xea320901e51d9268a7f5789d305b1330657fc52b 0x3c922df979a5c1922d2baedca63215577d603b13b72862b57fbf240ca501bb20
|
||||
0 0xa34136f1b02ba36d0644d6aa695bca911c9a7ce5e19272f97b82056b03f481cc 0x26eb167cf65e0ce1f8f0c3809863e3c8542f706b8ef07ad849793fe208bcc7e6 0x4e80744fa23cec76e1621ce0dfaceb4b1d532e12 0xf4e022d9b83d279611395823e4b436d1b795054e59d0ddc663c42c41075026c4
|
||||
37 0xf4fa7bd652968977947eb8a9bbb216735ded98405e95555cafdf48615c1d4866 0x77545ac93bf7065641161ec455c23a8fe2b0e6f1f9d8ab8efefa39e6ae3ae0 0x9acbb72cf67103a30333a32cd203459c6a9c3311 0x2727dd81db2f9141fe2828b150dff11b073a825b88e514b1d33f3bec117e3c5a
|
||||
38 0xca14396f151b4c21129bb15c70db48c97969809f681d7521841d2dea13bd7be 0x3438d0e665fdaea72759ad3db4bab68674314cb50d902fb58a57ff8f61c89703 0x595063172c85b1e8ac2fe74fcb6b7dc26844cc2d 0x26c3de6bd2e155436e031928d2cec402853cf6797a4718cbcc89b48ed05d623c
|
||||
0 0xad3fd1fb3cf701e53cd5687926ca64b2fa978a062efdb1f6d78d15c7610ef5e5 0x33c82cf8f9cc1072307ac99ff833c76775e0a4c5cb0a177eb4b1b415cb96239c 0x8a89e016750479dc1d7ad32ecffcecd76e118697 0x548757e275d1152805810855b75dfbe12a421023aecab6da0cfa257156695d53
|
||||
1 0x95846057f4d5f4e8940f9f16b17d864b60f89a85257f5256988ce75748d24450 0x6a3accdf56960dcc8541971a12484022ab54d1359601dac5b93072e5c55e1f10 0x6da4980ab9a35ff025774203e721a4f63f78f953 0x8814c7e0039cb36f6050a9c5c72095f492bd50f156f3246c516be072f4a7b1b7
|
||||
1 0xa437b58f9d8dcb09593565cd607ebcc9ac72df40380d35332d1cc8e3e242e61e 0x6391ca50a4be1ccb9f7e46d4beae2196984f88ef0d3e9bd47a85cb2ad3d2aac5 0x19ff156cbeaabd04ffa2df84eb6eca93f266ba0a 0xe3ea3b265ff5bbf8746b3bd81c934ddcbfda502ca3047bc2fb41d6218c43c8f6
|
||||
0 0x912e235df87ed93dcfabb8646e4fbe7a5b5aac00a27b0c0795492df682311f01 0x4a08239f03720362976203222bd9a60536746a0717e951d20656149833ee8aee 0xdd0eddc7d2ac6fcc3a8bb54b4d329b71f96ec8ba 0x8e65adea948f96cdf3dbf74b65b0611455c6c8d8295715744af921a3d2b73fb5
|
||||
38 0x1c1f7fd0febe597836a8650dce0e8c72e1b506dfaac11aabb909821a77fe657a 0x23fc3c8b0e73eb6077a9e861cad7e38ea26920ccff72aa46616b241ae16eefa8 0x120051a72966950b8ce12eb5496b5d1eeec1541b 0xa2f59b3fb815c9d3d5ad410e793ec97962032e965f81ecb07bc8606821faaf7e
|
||||
38 0x88de71d84e271c4213391d1f78e47d2c7efb017b8b21fdebc97b8e2fc0d121f4 0x17a58f16c998f04e22577b88484ac1f7493a0473d2eb4dcdf5ccd659593712cb 0xe93381fb4c4f14bda253907b18fad305d799241a 0x2614f325a54ba5bcff2bb9221bda406e7ac17515a94abfc85e8764340f28f3c3
|
||||
38 0xda16a02577ac6d17701ad03320d1a1786320b7941680ae242d9faf5b117d5c2a 0xa475e4d3f36b7afa9af0e558f5ffb68377ff001d7f842b118416840cb7ed231 0x1062a747393198f70f71ec65a582423dba7e5ab3 0xe5bccf131464da99d721c610b1bda164418b645dfba3c98f01c5048e8dfb7934
|
||||
37 0xcefe9615f951106d5b52ff9f5e07c42319c998b70c3d291eb2218dd0c497ae18 0x52fca3109c234eac060b8daa57f673fb6b8b2c1278fd6a167f12deaee1071819 0xc55eddadeeb47fcde0b3b6f25bd47d745ba7e7fa 0x22cf2c4159f1fea8c78f1175b8c7f3743b31894525f5c272f027f8b20b56eba7
|
||||
37 0x8ec6fb0236f0a39bca70802551fab9d7258346399f6deb0bfab834af93beda56 0x6f273debd0a0e8e98ac63d6078d23fa93a7b5786a7456bb5cb3fecc19b1cebc7 0x75e89d5979e4f6fba9f97c104c2f0afb3f1dcb88 0xfafe13916c038b9b01e476ef5675341a75bd39f198500732b116221d92620781
|
||||
38 0xb244a0d2c66cf36f35455ecd8731f2960c64db35603ad2a76ffa34d22bdb821f 0x1a7038fceb3cbaa08fae08d5857192e44dae37666cf841b11c6e2bf84e655078 0x75e89d5979e4f6fba9f97c104c2f0afb3f1dcb88 0x17c8c48fb411df67de52aee98dc4a586f3725704199761f5bd23158437cb5872
|
||||
38 0x59ed90e66529f9b21ff820ab501e5ee0f18dde32c1debd66b5dc6e3342032b62 0x3f4b7b15b0af3339d791c8e73a7976d16bbd91316025d256d9161ff1ba894c69 0x75e89d5979e4f6fba9f97c104c2f0afb3f1dcb88 0x4a34d102022fa077a95899e102ef294cbd5941145fce1e29e2af39c6c831ce77
|
||||
38 0xd2bd67f5a2ff75cc124ebf944f7c26d87172d580cd92493d50002af32781c02 0x6536865fc12e5121a546458a45b480ca4a14b71d1cb899cf53c936044ad756f 0x75e89d5979e4f6fba9f97c104c2f0afb3f1dcb88 0x8d635892680e858fa7c2564751262f0ef074134ac6a46149b1ff02f16c0276f5
|
||||
37 0x274407742377dea657519cee052763f9f0247fb2fc8d6a587d3290b4056abd2e 0x1ab13a59094aaac36a7292c7cd6814d11119bd34363f313c993e46f4a4fe157c 0x97b9d2102a9a65a26e1ee82d59e42d1b73b68689 0x9d22cf1bda837de201fce2be661c2bcf5e6c3829fd75f58232a7200fe89abad1
|
||||
0 0x9613c1e52f935a04483aab79c0ef76f8d427f79feaa2543ba4c94a91cbff7f6 0x3d75a82cae83a3647c248f44752185b662055ef9f3f21abf2fe5260f6885002d 0x86e122e39d467eb13d82765881cdd944c94ba922 0xfe0f34ef96a36515135bff2c1fb7964a552c0bdfb88a1ad773414f2a05c77132
|
||||
37 0x37f09f9d9d034a9ea8892c3a7b4826de643778f59e217ded5199d5cd32b3237a 0x311f3b9d4f7d771015eaaa0a1c2cd5759ed798902ecc03632a18de47c078149a 0x9cbf099ff424979439dfba03f00b5961784c06ce 0x9d08d5163de3f8437d991d7fff25178eeb821ae6e272cbf42a86f4f1a22023b1
|
||||
37 0x28210d2f4b817744db46b71c7c993fd3318ad30a96975678f185cf5e8067b9dd 0x646aba390d36afcce34eeb928b92c8d0e12cfc5ad598569045de59d4b2de3526 0x41d9294128b6c8815dd92199700953220b1bd375 0xd4711cb46f4155bb887a2d978f2c4d877cf9bef8122ca0d30395d5815bc5a886
|
||||
0 0x4455fa740404acaec4e670be00843afe7cc6cfa379108ef02eb8368210791943 0x83f2557e17faf4951e9cb767b278f57487776927928cc53f5f1e4f028982cb1 0x0b5c4a7fcda49e0a8661419bb55b86161a86db2a 0xe676662e29b77af78c77311801b74666dc37ca016da761c164a3ddfe971502bf
|
||||
0 0xdfb1180544b6b942c23ddadbe4561c821dea1727735fb4442c2c0ad02185111 0x6524e1961d5357471ab6d7e4ff52fc434c88a962ac0a8f203dbf67cb4e971727 0xdcdf0feeede933ceafc6131b663f1ee210ac61ae 0x6f9cf3180ba5ffa60436b7539de12d8b11e0343810b0d3f85d6457745219b86c
|
||||
0 0xe3f04a7f4b367c274a018bf88c3e3929ace1ae203e6cbceb4809f4b6453b665 0x57da3d1b4b3e6adc031deeb9baf408b241d178e12577c105f97d15eb71945151 0xdc5432c573a1d4874d305a5cd7e62aed2b0bc522 0xd79be8888d4ac1d12398740b93f7cf5adbffa332356677973663b2580d45c7e2
|
||||
1 0xa29cc033a00f3efda65699bba97235eeede560f1adb51d307a168a2db841d8a8 0x6f761fa28ed8c0aa16773f7a11ab14c34dec9d31a085887a798dabcd00fb1905 0x19f494583c7c933be7b0ee58104ddafac1e8adfa 0x21f2778f84b87d28bd417f57a952fc3b86b86641717008fda61ebfc956dd7166
|
||||
0 0xa18dde11da20682e5d3904fce5591b2d499bea1980e113a6b851a786f9551415 0x7f29dab88a65cb3cef6b8fdd633e61f565ba385459998637b4e54de7a69c017b 0x4a3646402d1aed59cd97972474beb7d1c68b303d 0x889719b175613719e30dbdf7c59b0766ae3a642c0700fb43e6959b369796e218
|
||||
0 0x563776eb92b4ddecc85ceb07b5968ed78b47956554735cfc212db00e03fdaa04 0x28bac43c2efd049b4e9ab7c46d5961e216da1baab59c4e2930bf19ba146c5e21 0x8216874887415e2650d12d53ff53516f04a74fd7 0x4aa2be7cb95d651d91b8feb3d32c04f4abb1c8c36eb0b2c88a72b1a1630cdda3
|
||||
1 0x24dd078a4a604496c592fd0568c50e340c2df5d3343392b62f6669128c43777d 0x54a4e08b684ed36cdf20f132164ec18599b07763da289787ef4ecd21635e7bdf 0x64917e321c516a2dbdad48bef7e923873eb7854f 0x2335ef16b1d02b9e206f952b7d98bde5f453afd6e95391a6083fc4d6fc829e2b
|
||||
1 0x96942017e0365f7e059d8822e8bdb10f772e186e5f6dec136baac903f037863e 0xd94dc604b36c0b77740a4bbf70a051d239185611ee36f2a6224c8604b638016 0x0e7518b332f469a6a2f59e690f225cef5157cca9 0x62b0621f47ddb24e8581b2165cde8f4f883222c991fcb1ba2610d01948a5882e
|
||||
1 0x5e5f424b80fb1351a178d36348840d9bd5cf363c78550d829322f21b58a2adfb 0x41a2fb3e6fe3c5a4449106ba5fd2d0d5e9efc10e26e8c17e7133fecf6faf138d 0xa7fb5ca286fc3fd67525629048a4de3ba24cba2e 0x4a3adb07cc5bd5b0cd6dbdafb1d643e41e353c9ef1cf83ac1fda32815b09d461
|
||||
0 0x17216ef4d8539f74333914926d1fdec20b06ce4594d846af59bbb0995ad80bdc 0x5806f2eeef10c734ac9e577f3a7c73b338ef2553238b5543a1c2dcc35c3481b8 0x7f72687d4981e85d2d2746c17a0219d8054a2148 0x9a3fbe852ed1abfe59e63eca1d8e2453a1060fadc622360d4f6bc40cbb8e326d
|
||||
1 0xf765aa91e69fb3436969124c747b888e705d49e8150a63a545343ade5a425ac6 0x19235da122cf688b31101015a9f4c67ddd557f7139206641182187c308f608ed 0xb6e145b74eb1a016231483272fb622ffb68d3d7c 0x2537f24f5d73879d63799050aa0eaf5fce44bd670068aa2b1b997913859106b4
|
||||
1 0xa2c13c62165475ed08b64524b7c9a8c1e6f7d4fd041c579eca29306c0ccae15b 0x3fab181d182a0f0d9768d75bbb8461f2a9a6b3416212e8b91209680e29c5a31 0x24c09a812b6419ae0e929b95d562f635097d4590 0xf9113ed129138f590b498a572380efaa06b59e436689772534842d7837e092e8
|
||||
1 0x3dd17bdd0a94e61f79b21917b937bb45cac40ee88cb37a09c987ddd346ee551b 0x32017f92d89ed4ac0f4a235c5f6f41982faa4341076ac2dbfb29a7a8efd15e1b 0x41f0bbe07573e14944304c0a544c5dbe6f468cf9 0x7df3db64dad8bf775cd8e6e585a61065cc739ec914cde160b3aee6d0bcfeba72
|
||||
0 0x7ab5cbca681be515dce228b1fb30dd588e1fa9eaeee60a9c869a9e4d6a44da8e 0x6567506dacb0bdf3be1aa5ebd55bb97b159258d728d7f2e54034555648c434a8 0xf031dd3ef38f677b55e8c4a191c3b9e343c07758 0x76a21141c922911e735c493c8bac70d04c6c83af1793046cc74d417deb23c8ef
|
||||
0 0x541aad8b51542ac5f71abb002099c2107dc0a87da05751675deb23f683fd26a8 0x51b3820e49ba8cb365fcffb97269a30b826b509eaebc05b03c37be93ffba06ed 0x9079caa7968d77ca87967ced769bb4fef312a834 0xd570c731edcc02bf4f06f3631de76b4e2427fb64f315e9ea94080125d4478818
|
||||
1 0x896ac1bcf80a4a2c503f92bb030f0db43aa545e8f44693955b4f577bc6df260a 0x65c170a802c5b98a4567dbbeff8ec95d55434eaad260c12f37582334cbe013de 0x792eafab3593fd79f01c8dd5282965dec1bba51f 0x2c9a7a5e841d0a432a3d09a657c0a465604467f4ed0a8bf1d34583d2f49245b8
|
||||
0 0x9cd74d9898571e0af4e013337231472e033d7b95f70523a10f7122eb4a63497 0x4494e798d8905e9662b48b99c89835a2166b070be8581ede50bec94cfaac332e 0xaa9a1ec22aef4fd5119eafda899a72ffa0cae258 0x5c378afcde7290d00b044893da06469e9c2181a1558598a85830c3bae8de121f
|
||||
0 0xca04356a33bf7351027ecc535e3e08537abdd333f2907a98e7d16a2e4408997 0x6871c6fdd8152913909322eab21e55baa51ec4bddf161b0e7d71251da17e3b9e 0x4976a4a02f38326660d17bf34b431dc6e2eb2327 0xe814b149e4d1a7404f17678f8a845795364f99fb830b9db51a84421ae4891f17
|
||||
1 0xd390febaf6781e5ddaddc823f1791c133b6818588e4d071248e7c3418977c2b5 0xbd2a753d9c86388a052044df07193bdafce4d5dd36e4a4e3973ebbdf0a7bb91 0x4976a4a02f38326660d17bf34b431dc6e2eb2327 0xc20c2be74014e4d9032c422635038ec1ee0925b2e2da0b7922f5f3c0d2d3ce25
|
||||
1 0x54c0524f19276d1404c067e69f7288ee5eee955ad12226daec56d74b7894405a 0x4335aa0002e02ddabea351271f791f0a55f69119a88a5dd64048bd7c241c57ce 0x28c6c06298d514db089934071355e5743bf21d60 0x59c08d63ebe74a3ac3c3d2dd65e813ece338b4df7878d5842732a24b3bc886fb
|
||||
0 0x3f5bd3f07b802df407ac00f150b6b091f45a877c4dbb65c9d4ffacda8cadd858 0x4b02042d475f722e862608ebd4625dde1fe5b6c18a09025d61694e6e1a986ea6 0x28c6c06298d514db089934071355e5743bf21d60 0x2d81d7671ecfd4830d97fb7f2fad04440062a3cff4f10bfe7fb2f458fdc758fb
|
||||
0 0x4a704b00ae04e370b365d5d1f7d54f5b4554428bac0db7f24cb2d8e52b66a045 0x705197257bc2464a40381a5a6e062cce897e621013ea10c9647bafe1156ac2a2 0x28c6c06298d514db089934071355e5743bf21d60 0x368efdc35f07630059054c541f0cc8c259d57c2de9dd57fb3b72083f2fd1ca0b
|
||||
0 0xee6ee3b45d0bfb27c6c424bfe3e268b5c88c0c0a09863005e907f22cc9935aa6 0x5c5ff76d39ffc6483116642b4b9d4ce851fd9a30f3a6c7ab963c1e2e151d82f8 0x9696f59e4d72e237be84ffd425dcad154bf96976 0x9252f22653436777ec2df3e6f5d532d11cf7c4e1084bd4e86c0821cc2ebc719e
|
||||
1 0x81da46ac5a2c6a97e4c58a5e1081b6d68f97971bbd27a22cc3499c31fb557ded 0x140b455d2d09f1af1fea8777b828662b3b348265a5f9b336b4edc149434967dc 0x9696f59e4d72e237be84ffd425dcad154bf96976 0x2d03a34ba34a3ca1a8c8ba3cee10f0ca128c36f211b7e50b8728651fc8544d39
|
||||
0 0x60064f428d0d60a5bd28057f4b86e82c0d5592b3bdae2feea0d79881e5f72fb5 0x774b1055a8f27c9307bbe7eaaf9029bbb7e920acd9c0038b0646eb0538ef38fa 0x56eddb7aa87536c09ccc2793473599fd21a8b17f 0x0432c2c29c6bfa4242054e26254776f91678f21c99e672eddeccd3b9b2f92729
|
||||
1 0xc33b4f64a2183316ad21136cb72cf4f2260a864561cde658fd8a6ab5764a2f8b 0x59f25f6bcd7643bb349495b8816db070cad1776d6d6e18b0b119fbf9d8e4d001 0x56eddb7aa87536c09ccc2793473599fd21a8b17f 0x086ce311a8a9090542543571cab974bdfbc6c44abda76c8828b02672335da789
|
||||
0 0xa758e894173ce8be91f4d5544a7ba339744bfa95b535162a03acb61f5a9ea09a 0x39edb3cda1abb60a2ebd59636d9375ae08776745cb1a962eda45048fc1bd234e 0x56eddb7aa87536c09ccc2793473599fd21a8b17f 0xcf40ff9251650690129f50bc19a5a395ecb7d9b1bff94d16b14d759394f428e7
|
||||
1 0x50e249764da0ce92ad0e832b544d7526729eacfc43f3011fa6f555cbb6d394ce 0x52d85c3e2d5fc6505078b3200676e8efa8ef1626720938ec52ec3cac9f44ad33 0x21a31ee1afc51d94c2efccaa2092ad1028285549 0x584f942852d1ce266b8159c971f552e5b1692809b0fb98489e3605811b7f5de2
|
||||
0 0x673b134b030bc26cd02e4cea1ddd63effbdf0a178c9cacc932c2440042e1e18b 0x2aa60ee96d3dc050a0558fde204f482a85cb246ca431416b9ce9d18290a213af 0x21a31ee1afc51d94c2efccaa2092ad1028285549 0x978cbde7348b61241687919e376b531e1e9ab62eccd5c90c6fe2a8a0226e3689
|
||||
0 0xd626eabfbd7555bbbfde2f763b342a3145e85407efe2d2616f5138f816b73d11 0x217cb61fdf4d4a342cccfe81da91ed5fee89bd7e0d66218564c5cee47cbb6050 0xdfd5293d8e347dfe59e90efd55b2956a1343963d 0xe364db52cea6b264fd6f311bd700f91aa300194d4972f8f33cbd1dadcd5093af
|
||||
0 0xe311926be6a3abbf18ea2d8b71559b60679acba9026b6a2870e1bbac1467f91e 0x21c747f249093f5772501f380b56b42e96a8ddf77bb592f377b9bfea06d9e0e2 0xdfd5293d8e347dfe59e90efd55b2956a1343963d 0xb56f149f71adaaf2674917db32c1cd864214518c58cf5574703733f924e873a1
|
||||
1 0xd4b5e0226fe10e85df2ce70a16a1ca5422bcbf83a685e6da2be48bc388c932dd 0x256ca3b5e0f3c0b422f441bed3ae5f851347990adfb2d11cf79879f54bad2cf8 0xdfd5293d8e347dfe59e90efd55b2956a1343963d 0x1d5ffce90110bd94c5d7810642e8283e721e33aa987d570b1593b04ae17b8377
|
||||
0 0xd50421f2321a69714cd7a52ff57c4c3482ca01a94eee507afe06828c4e47898 0x27e919a35fdc99ceb109873286aaeeb3e90aee201211a14496192cb80e8906f9 0xe6ab9e371e39d1daf921f24cd83ae3c837d2cce5 0x785488a8196174e5efb61add20c39c19887fa1cbf6c2c4e6f2ff9db79b966c52
|
||||
1 0x71e9f2b77a94f63614bac8249564393fcf3b3531ccf23a232b3be77ccaf1f18a 0x445c4e2eba9856f71c6c7b6f5eb81e1b451c39086458ac88f931667a1705de5c 0x5804869f1e8a5b99f2eab8c6b1943bd0dd5b26f3 0x340b702ff1d5feb24988a865d19143b47854f8526c04bf427be42e7bafb37fc9
|
||||
0 0x742855759e28bd15e07562aa6f35ff93538daf448ada687416fed7844e793658 0x73fec36e58ada180a2bb4a8847142e8ed88047d485d926a226bb8fc2feb1c804 0x1d05754e9cd39e987a34343cc862a82370942e93 0x2b0b92eab8fff875b52a21071b2ce8dc23d56652ffad308a0ff14719e4dd81b9
|
||||
1 0xe05dc5b2eadf7292c2c3c14f97e08daef9dd1aa499ad11a235d77ef4d03956a3 0x119e1653354da4b22fb38cdb11fe3ad1d18d8d174812448a6f8dd412f7ebf812 0xe41ee97cfb75f1646d143aee40fcb4991450aad0 0x2dff8c6bbec665b3bcc66782635d9192025aa733a09e7c2dbe10008e15317c08
|
||||
1 0xb1d0d41adea5daf645b5e0600f2e451aae67b2eaa191d2208db210f6a6fc61a9 0x1dd9aee6dd6cfea5c8dea1b93f0cb55c97f036c0b91fd0b167a479c72a8e84d1 0x5e746b94aa1fbf9af9559c6e04a93ef0a7abd0de 0x95366c33a8a3012c6273656ed6954e28f790943c0fdb2fcdd58290b00e853af5
|
||||
1 0x76d1a4d73ed92b786f848998c7dc8643aed6d80700faedfdf1c7c54fb8af0775 0x59f7addf6dc96f924714bb1727513d2d546ed11913087be3240f7a91b87d1d4a 0x170b4cadf7deaa017b1f595de5ec7591f7a686ea 0xb69182c459c9e8d84abaec3af791abeec972544eb880845b361e43daf36aa66b
|
||||
0 0xb32e62641c4428e8d24e65ade6b2046b2deb890b887a89334ed8118f6f4f38d6 0x3b088d3fd2d2842f1a16da028cbff9d1f5014ee35f914e665538ac4c4936b548 0x285b3bc1f46d2bf1142966a5e1c4834b86b82aba 0xbc9b62e2e020145c9fe7933a0de0d6112fadab5f8a6bf701f5c360709668f743
|
||||
1 0x1dac69e7c23884811a95371d7b91e65ed6a364cbb5eee706bb560858759b1206 0x7a1b11dcc4f7219f8a8ed4d72357b66d9794fe4beab2902f5049e4e9ab64037b 0x5ae41ec3d27c0d14809be1786f35aaad447643af 0x9b21f4d49fd6e579933afb48b6535fd55ba2060a123bbd0263657622cbfe696f
|
||||
0 0x51a7b36b6d1b7fc9d2cf6eacc16aa98bfd9d36a40d06f390cc2887dd3b064c19 0xbe87f07c87c4ae834004a8dfd4ed9e3e08b7a639aebe4f3235f745a05071f74 0xc6d7425c44ed9ce936578f8c150b6e589f9b0b92 0x793900f4ac8f983513c4fdc6f8603fb8dec6a21965cd8c7f64771c167327976c
|
||||
1 0x5965e82f900e7f98922584a7aaab65615c69494054f9a0dcbbc50502c463d13f 0x23217a916260a082687453297be97454bc64e5d1617d9ff9973db5485f7fb235 0xeb2629a2734e272bcc07bda959863f316f4bd4cf 0x0386907e53874176bcc54754145fd0e8602730f9ac1ab6e680a4acd6ad584b65
|
||||
0 0x73b358681787d5541d791f3e97f851ccb6cf55b91e2c5640b52b4f3ebcf95666 0x1375414789a136c47ee9df880858d5f729b8da5b6776db925687ab58dad50880 0x95a9bd206ae52c4ba8eecfc93d18eacdd41c88cc 0x438abe80d5baf46affeca09ee17b6f85ffa3a8c438520c8a805ca95173d09fc1
|
||||
1 0xc42bea9052ad930f8041eaa138d9062a57ea4cfc53c109d429fa9fc10d01790c 0x758222e7ef5f17699e36737b1a1bd8d2870185cc80d42a7caf0b189238eebf34 0x95a9bd206ae52c4ba8eecfc93d18eacdd41c88cc 0xf8dcd114a2a0961f9614764ad17a1cc1b0d22106dd3275fa8d62a20a3cf6e0cd
|
||||
0 0x1b42517479fa75ee42fe8b1f26dea68fde5f0d8777d32ccf94357c94e4a2b90d 0x4f82ffafaadbba64bc338890ad1f24c278dfe6cc445efa4e7a55b6625f905056 0x95a9bd206ae52c4ba8eecfc93d18eacdd41c88cc 0x164372f5e578564fbe521627f408f8ebddc6310ef689dbbfdf4d7d3c7e65bd4b
|
||||
1 0xf4894537eabe5b3c19638fffa3416049469a3a216c8e5a97668c035cfc9e07d1 0x28b06efbe60e625e1be9cd81448a9b240b93a76657c1a18844d368c617ba882 0x2f043b4bb857a7f4b6831219184dac3105aca34d 0xdb1e4681868be2072d639150c9cff48b4e7883fa6c2c6665768389e5fa4f469d
|
||||
0 0x480de57d4582c3a33c16f1049e8261a0b27df1d9e34a77e41c9d45fef01e2142 0x4fb836362b300da267c0273193445df1ed68fe28327d87acc2a22e583e64749e 0x7830c87c02e56aff27fa8ab1241711331fa86f43 0xe967340f3203ff60407a16976795d14c3fce0447a68f4b98ba98d4176057afcd
|
||||
0 0xf80a9f48dfbcf60ffc4fba1c3a820bee256006608db5267fe8ea3d38949ecbfa 0x58ea47140e36a6754e2674bf5f13f444ebb9efcc076aafc9b925d531e14b456c 0x7830c87c02e56aff27fa8ab1241711331fa86f43 0xae9506abfb4b1aa41effa3510687329b80e824241e7e60e18c7bb3a2768f151e
|
||||
0 0x816e21a58cca55cb134caf496c8c7bcc247d63a74ceef9bcfc505cd4382fd20f 0x18e9867681a483785254bc2bc23c0a6ec5fe7ab98fffd7bab2ba2f69edc59ceb 0x7c195d981abfdc3ddecd2ca0fed0958430488e34 0x1c416922452e82a5c2910d7b481923a0d3fea94856707acdbbe88842401b7473
|
||||
1 0x99f8c14bf31ec945e4bdb7af86b1d584c3263e0304aaaca78a804d5db56fcbb5 0x2e2958ece32f5999aedcf12d20a16d52dafc4296744985fd171958d95d948bb7 0x7c195d981abfdc3ddecd2ca0fed0958430488e34 0x3cd70e64bba999d4c64ecfdca7257b59d3aa8c6f034bf6adfe8ee5088c17cdd0
|
||||
1 0x221b8aa1c94cef0192f7fe4499d18e2404d463e98d4840006c606b36cc5ab5db 0x3e26c8ee8ed31948c4fd1dde9721279647ad4e17238deb46fc668feb47582d6e 0x9396d062fef353765721fa3f700fe858703a4a48 0x03b4189ff4b99e8378f60d10e10ad47bdee0e9b56828162291c60ec3ff6b74bf
|
||||
1 0x28c8e1fff48f440d92b877725d28e5d31ddbefc59412caa2559d07fb74dbd4dc 0x32833c2b615db914646a55b3d16802901476fb2f1c78a73bb4d98dfc8521db63 0x760418292d007fd98e392ee3750876c27a6460fb 0xa3562fdde603f1da197b6824b951d8f4bb70b839129333b18b6f71897a67bf30
|
||||
0 0xc906182e3c40e1f5d259dbb4cea62d2ef3fec32efed97cd307a68e38bfc1761f 0x39e57fc10bbec73cc8521dd1d2db3b86d2e9b0f03cc73fc2ee0b5b6a3df28180 0x747197638a7af760e221636405c747aab7952cc6 0x7e689bb1704555c3dc0416989cfc372199b5dcf14819a66809c1a8e2dea8cec8
|
||||
1 0xed0248a764b72ccfb9549c1d17c855d8c810e25c829bc78f81bb22ff96f899d1 0x487912ba2a9979735b05ccdf0a777fba98923139e1a1b5cccc1068640b202a6 0x5b8972964bf9076eef6610e453a014516529a52b 0x778fb142afd5ef84a7ddb1f3d71b68d20e33b2e3243d7f4f47199897ab02c495
|
||||
1 0xf2b668b356cbdfc191da4079d9823b27dae5c1f3597a70d8bbf8db5256540539 0x2f5c858f4f81da7ed09f134fb95016e487cd2f4aa2a2da1f3076f46888981505 0xe6c6ba7ea35c1f200e72056f1467b188eb441ea5 0x5a34e826e965d0c9e7afa46f61ca73e97efb3f02d294a45e263be4029a2d3d65
|
||||
1 0xaa08c519409dfdbca88be959445ee38d7577c3de9674a6db64a8beec7449264c 0x4c85250f383d7ac2af72dc1f0d6ed5de9ada483eb896c49d32c2d56a8f0c84b1 0xff214c36ac0673bc49268ff1913b11e93534c86c 0xfee2ac113b09f4b1e9b33be3ebb4b227f2d2a0b6fde20b794aa834abb8348833
|
||||
1 0x98ffea8800969c9916a6214e763ade3d6d0cc30984d42330c8c131f9464fbd16 0x7a15dcfbddbf3c64817dbcd7d4e2c61d73d2ee4792f5e89103e9b27f4c36e7bb 0x0637d40e523c2dd75a9bee55967b7b18e2cc6ac8 0x520396bd99ef0e44ca80ec8ccd1c86a32d47f1c4fda146b0666475d5372af9a4
|
||||
1 0x611d611e426f6b2d4992dd556472bedab585481fd74f90081c40c5f18e16611a 0x2f32e37f67a5edd8e8a0da6675c13859d9944ea17f35e3e5815a997f06cce35b 0x68e0389f5678f1f15346a136d3e3096a84040c9c 0x4eee7476b26f9a3b565ad5f63edf4ed9f02c0463227c46a831a915584e4c2b6e
|
||||
0 0x893a0acacaa60ff5364228c38f5a555773c0aa819538a6c64e9684162b567263 0x4e43e2381e6829acc6e3f017899f2c0f9b82e0e6672dacc38e4399889796df46 0x18e7c0e8a28822b390b7e076eb712c0850409c41 0x39e094c665cecbb18a113d1ccfc64976f4cd9887ec5463d8403bafcc77b55fce
|
||||
1 0xeaa0f379c110a5ab9ccc71a5660230ba3be968a67de2d810efce78920da14066 0x699aa12379d9f2292bb619bfe2e713041bd49bfb02b85d67e05df54b76d66a2f 0xf795bc11cb62785c31f3e638aca0091b02b051fb 0xd632206bd8dffccc98d5a4b9ebbb612d63c2dbf05eff858324b931aca4c201bc
|
||||
0 0x3405d2887bf37cf4270a98517595c78c3100e158cdf262ef59a3c4c1017ede93 0x66ac9b238933dd3072333f178e5b292ed7e18e68646d064038849b91d7cb62c 0xd0702fd5da78f3ce9267753d77d0da9f17043c24 0x664d7d927bdefc8bd1151c907124bb817c257246747f703f3de8a7365caea912
|
||||
0 0x27915f3c65833e9e80794d5342d39ca391ee459f654c49d8e84fff9c831dc50 0x4f3472eba8a1a164b982b17a37906a3e89e4e97dac88d93e51b63aecb88ee7ba 0x8edaa40f4b511ced61d2006e591d2b165807c3f7 0x9bc40c99ca374fc638d17e7c82d3b0f2d04b8ae9fac6865437b5b0708bb8567b
|
||||
1 0xea0b758241ff151595d091982295c276316f47f17f871a2590a2628b2016c40b 0x23c56e6a0226e175d6751e36f2e2d59f3846c5fe17ddbc1d4a4b2f89676e1b43 0x4425abad97059fd35ae14c9e4d8ca8ccdfa16cd3 0x18f6e255eb1c86612447f6821769389df7f348829489a10f940b0c06fb30be2e
|
||||
0 0x3695c2a9ca1a52204a47a3576963990541cc402e1515b21c9835260e4f6954a7 0x797890b5905545293eb8428ec6e46cbcdc9da057c4e7791229f9188772c8d057 0x50525410d59beadf26d271f9d693d1f4191e5a04 0xc0e8063a935706d67cb5d9c9cb99daca1413d00c6248df3f04238fa4d4cf08eb
|
||||
0 0xba1400e2353ebfa00d5b24c1b41a16751d979e7442dfa163a25d6c4e9c6d51d8 0x6c38c1250a3394029822fa3cdb43e24fdb0bb4324d5bed1291170a348fd24955 0x4d29b7f953ba471fb650fc5842127b05e35949b5 0x17198f8a656bcc2511d33b20db5c6ad0c22c8a9d67ae7c5622096f779dd4abbb
|
||||
0 0xacc2bedb2fb80896b078301ad3b4cc677200fdcb5bf08674742c2a89c7e9dfde 0x630b75ca131a42236fd0fc94e1c1e69a8fdbc7cd93fe924aba6642791e4947c8 0xf959ff8366171a9e19d142340896cd94e1aa87ea 0xacd9925b4a9f9ee88ec57fc159881c18ea86e357b90c0240ab1d6bd5fe86e850
|
||||
0 0xb6179293816a9bd1889393b88c34d466d43ffc96771ecf0fe4ab7233446236fd 0x65b1acf754fa586c454495a479023b2d901b202044813a652ba664c5245acb2f 0xb8c26e86f38e22356d2d16c875d38289b6905021 0x0b97a1ed7e0d454011bcd52be2c016519ece9db2df56800acc626ce39cea9233
|
||||
1 0xcf67b4dd5b9d926004d1abf2fa23ed3f0e914423c231a4ae2dd08e19a3e9e4d5 0x24ee89ce5d32a50a4f890b44839b738feaaa59ac2508f6438b8aeeeb8be61363 0xc6554650ec0e3e48ea68b3bee277c552ae0debd7 0xcf807523ad7785086404c6a753d9aa332c761a36b89644f4caf9c465d348cdc7
|
||||
1 0x374aaca7f94e7e4d62b984b492a06df25968944ca9c250f10169a3628d05b0f9 0x15177b91e2404caf1bc42858b20e38e33bd99371f61814d01b686d6466d015be 0x6d0bce74c9375731d41d59ead889d5637bed4af0 0x97fb69fa87acc3c0b0950c22ff5d2adaa87f4d1d46026018938f266809c69a04
|
||||
0 0xeb8ff1cd76391a8ae07237568c08dac28d4e3bdc29575ad191bb8d335bbe2ed4 0x312ed03ddf43c67bacb693434da730d42b8929faf6c06a4204688f158f45dbea 0x68e3c86ba31081d59373df5f32dd0086939a36ed 0xcbd0757cbe0d6762392fbffcd0291d0c653f0470e3a28f30381c6d42ae594220
|
||||
0 0x2eab5ed09657a381c33b279b1670be03708b1e77ac91370087b426ee9aade920 0x5fc053a70338a0c868f11b2351b26d9be087172a77979fe0533c2053bd1df74c 0x8268d3d9bcd233db97641001e0a5f1c6785c3a1a 0xd4ab95a7d77b2859aaf8b8674608460c8e53732d2beba89d7fe76466292c4980
|
||||
1 0xabfe7fd3bfcef4f049c6a11e0717b22fba93a9bdf375132a3f2d4ecf82c999b4 0x52658fa3ca3d2a527ebf071c78051671545f0d987084b46460fabe57d9367404 0x3eafb74f0fb78383e4e4bcffff6ee4a9fc3f8c73 0x892d21e91838d7d29f4841129cf9a86539e9b2fece80cbde027070be1ded88ae
|
||||
0 0x2b4a7137d0b31a7ead72ed979ae69d1b4841334900194bc381dd5f71b6a2c337 0x4c393d7e881888cc50f195dba68cbc78f2ff55b3ae0a91e195b77f582cac3d2e 0x48a591f904d0266d32d3ae188504e2a7910b703e 0x97ccfaa3728c749711a1eb28fb888860cf38e67711dea979cf8b91cc1d999f35
|
||||
0 0xbd6f6a6af08d750e28f99357f0dfe768de9e8ed1772f9ed1e312980e1a830167 0x17e56aa8e9630383c197d6282404b659c10e2889ee50bf301e12629420484bba 0xd413fb3e1d268eb37eeb38de04734343ecf6c512 0x626eb6781f01e2a71fefb336122ff174e6f079b721bc47dfb6489a1eac87f35c
|
||||
0 0x7e42fb76826c7f00952ef47f200d5f5519fbc4c78e7f8b958f585306379a1a34 0x738cd052fc0152c03dac09f5b117ec6a1c21d92a2d2e636ac12a05536ecc44a9 0x261318280a2593780fc0b49463d2065bc4b9acea 0x2b6a207376c1f17c13d8e4da40ed4b2e60e1e8734125275ba89866a5abefdede
|
||||
1 0xad10c20fbaf33d13bb5fe184a340fb29f3d32a83c375adedc4d5178929472f4d 0x7f1c763ce7e89e090da9ec44153759833dfcbd2990e0beda598f0e041dbbba45 0x0109480dfabae54463568ce807b6818ee156f84a 0x457a1e31e350640cb9d4a8709d91a874fefbe6ed69984c87d72dad406f510ed1
|
||||
0 0x2aeae7d1d3bc76fd6f02f1234e5a4cd5a78f3f9ed2ca6f6664e0c6bd821f55c 0x19250127f033b2cf9783099f65801b3edce8bf6d26b32fbb5e44abba2d37e9e1 0x455ce87ee8207a3f8771cc3df3d80807e098ae9b 0x22f009e48382685fa1ed6ec3287b17fa144bee9c04c13c504101c9eb2cd1a1d7
|
||||
0 0x86d9311b4a2c1bce624d2a88e626614514fe3ba58dd656899f4fe5e6a170b37b 0x6dd4305274e769c830758afe3a56ee4745e4528501d635c48dfb3f80b3398214 0x6b1baa2a2343f50f422e9e7038826e703c584dc3 0xfd6b690eb2fd74672721123d5ae7cafc6cf053626e39f530571c74d0a5d7d666
|
||||
0 0x4f4e9705b7c7fdc08af4869b151154ea8f011ec61297ac1c419a2229985c7501 0x33fe5b95279c277bb2cb42dd9524453a8bf4c3600ccfceee3ba01557022e8514 0x5c7cf7b750b74b91212e97c4edb502b13ef7c603 0x8adebd9c90f7c9f54c9e28b17010732f84ecf9cad9c97d042c229572015cddd2
|
||||
0 0x3a105f1f5e1dcae92a1d5462222aaeabe96d71f02746692d946b2e092cb40292 0x724bea7cf27436bec762f4928cac3c738d0addc9e68a0ea1edb45a2fc7e99bb3 0xff90f956c9a7d52ac21c37fe7a34801849887f19 0x425245f8953a77bd17f6a99e85de70472a58fd712c2cd062661febfe4eef0f6b
|
||||
0 0xeb3165ba04a9df88da13aa967733573a9cdb76836b29e5565f4fdd1c10a555da 0x3387d1afba42b8659a13f020271deb5712b6c3146acf6f06e5fdfacaeafac00b 0xabfed9eaae37dbc55c03dbe890b64e59b965141d 0xc08a357bb6684da5fd835fec9b978f4b0d447492012ddfc5b02177f79362b432
|
||||
1 0x7ee780ccabdde306b172ff8e62ec05bcbc741e4fa8d5057bfc172d18b4121ece 0x3401ab66a0b0531b209239bf6ea6438aa5c0c7621d443c87f4ae50fc867c672b 0xbe7ab77ae4126496e193c97aaf83ab9cda87fc26 0xe557ee4e9aaf6a265f8572722719032b27a3dbf20519e7fd932db9310cf0ff4d
|
||||
0 0x282e2f0d2acbcbb5397705187713d73f3f320afc6e7e12992551ba2b844ba4ba 0x262117d4a997afd5f1e2bb8d2438e091e1f6e9f9e792e424e58bf98a3e438bf7 0x4a58bb7ec2b8064c4a03abc7c52d9d8a6b0116ab 0x4ee60a3d8de3688398227eab55b80b4ad52ee0429be1aaaec1075f07af01f26b
|
||||
0 0x35e88824f5d5e0019afb1dc818b338ef707fd32487126d089743a94e526a72dc 0x1f9a7cbe5ad46a1ba8d14ca47893b890ada28f4f69530b538d7535c9ca450fe1 0xa34df27ba953cdde360364eaa1b011e98a449174 0x3fe021424adf83aa8e582435a962724eaf11e264d463dffbbb1d5a7e96041da1
|
||||
1 0xe5437ebfd6f54a4580506a80e9baf1399546e270c1965daa1b317a3ae119c532 0xf486022026b018521fadf86ddbb73da9556fbce3e41ab6ac4982d23aba34732 0x59d9099ab334d4a3f19a6e125c427912c68fc32b 0xbed8dc0ed9fabdbd5168148daf1218f025a14ace2ffc3e8d8cc24a9a0f6e2643
|
||||
1 0x11378e51ed9404c97fa5c1a6d241a55c8cfb09202abd30380abeb8f7fd7c8f07 0x72867b97b9ce0562f5c6b0ee3a844e042fab36a56e36c35e040ff29122355b1f 0x4559ca770e7f95fce15bc54c8d09abdd3b5c660c 0x2224f14bcbc55c2a2de9a1c5a4daecb269745286056d28e61c10e5a745cc94f0
|
||||
0 0xacb3fa89cdea2bceef0f27eb974a4be19b33bce137d9e5b5efcc98ef67661726 0x515491ffd2a473f6d3323a318818f2c9df9cd553032922bfe9227daa2e303768 0xa838b09ae1b2223298d1dc43dce715d06aacd47f 0x7a345cb9dae9806b45d6b3067bae813643a5d455f5c20f2e475d6898e3f804fc
|
||||
0 0x35fab5e947d0fffab73351208b12ad003cb62172763113dd181016ab8297cbd8 0x3c6a548de3e59210c32f3d896fb149f18a7d6ca27a3d101a087e9ece3536d0a6 0x971e954dfc651a4b1743b7132fde87f6dcbe502e 0xa1c0b30b92991df606a0f37303ed0ecfbd3c23239cca4146e0aab00d907476c3
|
||||
0 0xbeb835e9af305824af71fef83f68da275750bda01bc9247f3f1ae946a35b0ed9 0x4f075ca8be453f38b035958699dac32d8370de3adb284a5d743253a6c8f1116a 0xf6926d15fc0ee0113ac4840e7d881d92cf193a7d 0xc5b5a0064d6b4e78407e1087a55d81456d914dd106d8bfb4d5d5791e30181a04
|
||||
1 0x257ca4a4fb774fa12d04ce2cbe4f7c2560a5d93bbd6b0dfae377907bb91d0b5a 0x541f5c5d044a15390ee23b9f4ae66810b38c3e7678f09ea8736709b4a05328b3 0x17be3026e13c693e72ba8cceb3adb589ed36f14e 0x612648064356c01dcc3dbcc6f8e8be1d80b1206ba4341003f2d122b0d673479a
|
||||
0 0x3bd7e74261648e61873edca54585ffc1b7dfc0ed11217bc032e3f5159bfb4817 0x79dd87b940b8552f48849cfa433223943faafe7aba5af8f778c645cace8fe409 0x5425324987996df91143b257c4e54a129fd6e85b 0xc533049e9303ccc8dd3b7e38c45db85ad01dfecc3784a1e1b59b54bd8c3c701a
|
||||
1 0x98c4a283642a6840580b138e65fdba451c87f9bd925329e83744263fd7be5048 0x69410c8d7f022f129f862f029083194c720a955b18970b5cd1a8a83ce172dff6 0x158d9cefd58c505021c54528feeb14ef73c9abff 0x15669ae7e934f1144b36117c84b02db899cffa206710ba72614820121fac67a9
|
||||
0 0xfae698f64c9b17dc1ea1c28055c28789fd5857c8dce25e46502e68694aae6c85 0x635303afde839cd5a566b6493a0d068f4796e57c238c35db7bfc64a9d950ebe4 0xfe52a5d0a116efce195baba279758964172e83ed 0x2526f94f656aea49757e6d11eca88a0f102752eebf43da5988b619959f9fde8e
|
||||
1 0x4982c820b96c2a6fb89724db1df3a0acfae4fd7bd5cfca1d88e40d77f6c5ae9e 0x4e4481b9cd42bb55fd00bebe0b6b90ad468cc02c29ed0ca1a84fe8738e2067fd 0x8d1f185fbf60bcacaf783d8f6436e117d1493658 0x3a14ca8d74432637ec0e4e5f24d0c61e54a82746fd12f146ebd9c7507ec08fef
|
||||
1 0xbf64b639128b416fbd70c247b7a8e33183f7cf186a1dcef142ae0c288d8a1e5a 0x64f71c1dd604e64c6881e8fb3783cab7b9c8f80db9307337b26429cc19096060 0xeb280aacafb6dc0b0f811f3e2c1291ddfaaff76e 0x93ffd8a9781f73bbf3d9849bf05b40571456d01e47fdc015a70ec6d0a53d8b7f
|
||||
1 0x7a0879264b7b0aaba53f632acd1c3dde1f03eab3b4adaf2086afbd4f1a26fdb9 0x4d2d10cfe5fd159c64bfdb72b9c39d576fe71ec7d1020741066d853138c896df 0xdec977d8d5f2c79018fc185ba5341f8cba15f0d6 0x97f1fe90d4298fd74c44458f70938a990ad00befce1fed9c9fde7334f8f2e59c
|
||||
0 0x3dd1e43bb8c1f5c634ab3b4c0c09da6fac71fc65ceebdcf825779ba9fa96dad7 0xe09348612309ac2f310bc0cd0d84f8fdbf67b3cedb93608792259257fe1af98 0xfeed5cf7d996ab0cacb4b0baf2450f6c51b1efde 0x5564e87cdfbd1d4d91051523f79d029604462b3c0a326c99ae2cf1920d3969be
|
||||
1 0xdf54d1d5e32037affe7401bebe5d24aec562c37b13bba5feaab5b77826c27c38 0x528086fb0042ec2e80aec346fa0b6f08a879c962208e6dd227303ae3c9abaafc 0x927940b4fe41d9fe519f9580a29a351e57203dc7 0xfec469c2a340cc83511598aceb236cb647bd3a47440ee7e8bd8d002ce3b3f6b8
|
||||
1 0x5077e7de2d1fd106ade42889ed4bfe3495da0768ce7db5ef58d0211a9458a646 0xaa9b688acd7b6ab5b4b1c089045ce03e22490cd2254278a38f61618bbae820d 0xfe512fa3651ff2289172b14fded9d6975ad9d96e 0xadd8c860fbb1dcb130d9398500809d625601123c8bdf0f9f37cdc04f5478eb77
|
||||
1 0xcc606a4b8339906e3aba6ca08c0eb4c0864ba8fe458cf34fc84a95293cba96e 0x22449b2384a73d51d3559f7d93034096727dfb8eb76623e8b10b1850f11414ea 0x120609da75cf68f9aacf4d7e8b627eb9186ba27b 0xbdc844e89608de09ec2b1bce2c8d370e17a394ed6a5148b38b6511fc62c630a2
|
||||
1 0xecf21e5f54d766a37377ddef3c805bad94e1de49486ee0a8267e36dffbd824ac 0xb61dd021b9fc6b7d39ccb56c66e48d1670b264169f9e68dd245ab1c50a62af4 0x6c0fc6ccd718f8d58c3033c13a5afa3adb10456f 0x3eb16ea21e33eb3fe986727dab3ad306cb27feaa6fb42aefbb00e66694154795
|
||||
0 0xc9f7eb02af669bb4b793edbaf3b0e7c8f131d459f94e71d7cf715991e67aa165 0x54b2deb2c57eeaed6c93a8313775cd55ba346ff11d89e91fa12c26f1cc45970e 0x8ec10af9662dc17432717d72ce8b62f4ac24f218 0x7303a277360590a8a25a495153748fcd4db789f9bcf4d73bc303b4ea02b1fee4
|
||||
1 0x226c7a8bebaaecd3304d01ca9df5a9b485fa31fbc44e5c9168d8eeff7cdbcdfc 0x6c170b6fcf4b8d2fdf17569d332f0a8cc52aceb4a7389458ed1606a7948d5e48 0x550d8a88ce3e8154d28233ad9a27945058b8bfe0 0xb04b8fc72c305357f84fb647136b5d85f0e2101d43e3e5bd0eea98519f5d1b9e
|
||||
0 0x8ab2815963748344b4aeaaac472c048145b4f5e1cc86093638300cae9bda1a23 0x83da77b10ffe076980296ed4276b1b81cd58a15f7c573cf83586e6139deb93e 0x945a21e3277e6aabda145da4cbabbf6d592fbce4 0x889dd7f6de4e9c49153c728d0b9d293bf27d69d2ba4463beee85ce75e4732edd
|
||||
1 0xea57e0ee8bc336c781a5ab966976188c16ef0fa5a8f36f858d11add5343c8ee 0x459d6f341d6231c1197f4af6c413c469d97d61425c0a17454ef6bb18db2ff703 0x599357d348a8fa302ced7d6b99d532d95457b543 0xed26da3f378bc480599b79a5fb45f054290abfd91cb463e193988aa78a133a86
|
||||
1 0xf0b422543404ad03d959f34c890d5de1e08e25ca7b7ab02159aebc6a0e83486f 0x4dfa3945f699962e264b18fae4da81bde6ba40091b952199f9f365b0bff00e3f 0x0b0669b9a9f43a2967a428f838191e8c5b84d3bc 0xb673f86a1928f94c69834fb94b522e18a9424022c0ca00d487a5a6af26a56d13
|
||||
0 0x84cba050dfb80413562659c50431c99eb10a345d87e555d092aa0a9bc911a37f 0x3bc0e3ca54d03b706d7ca51bd20590b4c020e1335865e8c945a8558cee5fc7e2 0xb223a6a0b9a4877429f984243c904325aaed59d7 0x40bfd52c11577ec77d87258121035b41aefeaa1da5e7752421d5cb51b640bddf
|
||||
0 0x1cd25acc3cc1aa3a47007f5442118baef3d61f6f30ba4672ad01f3fe2c389081 0x3149344942e7dd5525f676f9032e2d7a3bc3e154c3ca0469ed77df3639385307 0x1b56eb67f280add7cfe89727aca1134274443a39 0x6f534d1d9bf2218cf30617dd1e0293de6f84ef58390e73579f98bf7d5f947d44
|
||||
0 0xc308adac5cd7459f5aba700720966697f3b4ea36a4d9414e11d6e72e24571a6 0x74915e161c7b94d5844c22f3c6a34b3ad49a945180794ce94eb3d3410f45093a 0xab639feb2463513a9ee703cfa33f916bbe7408b7 0x2fffc85af8c55e07853ecc59522361f58eaa7063a10fd0f89205b62ac5cc7df5
|
||||
1 0xb55aeea98ea3bbef39431d8cc8a21309e288db69b9cb87685f82f9a3badf84e 0x740b80528ceb16bb4fa20ea0327fe93eb6a37580bfbd149981a7d00728ff1b36 0x7b28cc1860b9fb47cf7f3f000564bf6deacc953b 0xb51689bd8af058131fee38840f92da123b41d9dbc4b7ff43186a0c9368a4af2b
|
||||
1 0x95d2923d538780533d6db5fb1112fdb426f1d4f16399d2a732d4e140eff611a 0x37987b15715cfd43f44e4395b6f449bce0de642330a9785fb48b4f00c7f4ca7e 0xaa917265aa6903d94a63c1cbc38312e19c11a053 0x78205715444565c45daab6b0c0787ca35b5219e3e0ce0bd4445ca421ce407997
|
||||
0 0x1ed4e98c251bbcceaf2a0e967cc854cfe4d92fe978909891054042779c5461b0 0x556626dcb3e0081e9e7152af9a0da2aaab65fe584c718b2bb1fc8c78c52ec167 0xd59f6c5882f2279097e401938d4c6796c07c7b9e 0x23a88397f97ef6f4000c7a666e7a803c8733ed4d19a2156f0f3c6093321e5fe8
|
||||
1 0x6450a2b80accb717e3a9c219caa01c86177ebb8d4bb84b9529c1335eb74fceb4 0x31966d6ca31437a33710998adb1c1e0c3c0d5cbf7c1524ece60f3c404df70b5f 0xac10ca20fe0977ea9f448e73f6b670d9ffd42ebc 0x674136946178355f8ec71797957e066bd246cba36a6d8f7dd5a0ea56eaa509ce
|
||||
0 0xc10537417a178682e6e351a2eb7f1b971d37f7d9376ee2697c08b0e723079e67 0x4edc34693d7dff3adf57b018e87d929903e1eaea0f2500f52afed8b1e25efea2 0x32b53c2434f03884164f6cdc2dd7508b31f558d0 0xeccfc571b6b9a9a61f78e03bc5292971e96e542c1da09ab9d1a8af0cc4643413
|
||||
0 0xa0b659da4e9bebb27acb959197979e51cb56b63cf4324ef981d5bd01f815c0fb 0xb05f93b0cb57b04aff64501bc3ab1f84a7b25a1b4956b86729bf88964ed934 0xe33f06b81ddb8042a93648b4c13f9cbce8a04c42 0x76e03dd437fef2b02edf4a786afd1a24b06cbe73e7d21f85faeffdd26a4be022
|
||||
1 0x97341ea7db9c1541fdb2193bf0180e7515bf91215f4368ea17cd6e88358266be 0x3a4c5d0715f86221d1aeb7a0bec2a4fc5c0087a0e65c232149f8fdee7ab7bb93 0xcec616376b1da143d9f51738d4ca5ac96a5cecd8 0x12f61e7256fe5514b5139e8b6c24d5d2553555fd0a8fabf660da4305f9cefd76
|
||||
1 0xe0024310417f142d87d3b3443330c0b025aa927b307804f5db6a359cdbbfd478 0x3046a8a2c6ef41026d8dabb1d3804fe8b36338029df6de0b6fee303fb272b211 0x653f99f5cb0723e919b6dd7ca0bf9253b963b06d 0x4d2f79577e6e2cff93ebf1f0607039bebf0a24a88cc4a406dcdfb0f8c0216ef7
|
||||
1 0xfca536181c563f910b2593a75a68759a1cbe9e17add9e5350e5a9043bf2f6177 0x72967ecbebb5062aaae304aecefd33e585769c95785463f7494e0c685b22576b 0x7f9fa6f0fdf344c7176776febddc15d4740f5540 0x5cef49c7e6514cafec83cba5f7293e56fa077a92fa1164c60878e36579e70fe9
|
||||
0 0xd1169af593cf12684f1f1dc5ec0099210cf6eba379622ab27d54db6afeb0cbb2 0x7ea3c6458ce7d2f454d79f7a951872d4baf1236050c142f42448cca41c4dd65 0x50de7b9f1e46f80becbf9ccc1de9730c0fbb17ba 0x6b23f37c6bd54ed9304788fd2617d2775a21dfbd19bfb06177c9068194ab9608
|
||||
1 0x228682fd3644c4f2a2464fd9179b1489602485b84cac0cc434bb13be6f52e750 0x4443018948d31e38c24074103e882cf6628facdfbfc0f1bbbd3b73a7abd1b8c4 0x7a9adb31ec1623e463138dd4ce88df7e791c6f03 0x8a33ea11489e13b66d6fabbb2abfdc6f13273fbb9d95a4d936cc073f3b370473
|
||||
0 0x68b4d46ba8c97044fccabbcedc53bbf362f85dac7d5b6f20087909bf428cd977 0x1e6a77282107ca56253584a6577d937107c13c914fe96b00a49e66ac06a8a878 0xc17e64a2b177468f6d4c9b556b63d110499112f0 0x4782e3d06c981933650a9aeb4034d47557099cd5bb82cff7563837517982171d
|
||||
0 0xadeae9e3caefa9e5220a88447eeb24837f2e8d7d3b9f4b80f105cf8e055ad663 0x3728bf1007a5f106d50004df752b5bc611046734225bffa10d4553530c360b70 0x74dec05e5b894b0efec69cdf6316971802a2f9a1 0x27d57b0a0c8f8a6c784d860f42f7eee5bd459d7ef0e76676bfb41279bc59b4be
|
||||
0 0xe25df026f631d49fec33a23fba5c81e63b14b7255dfda8abd1faf24603460935 0x63e42f2844b2ed1a81738ccaa006b4c74465d360d529cd94df16774d8e38931b 0xe128efc01e4244ff423cfd6cd41e1cc56bd6866f 0x84013bea6d8f9df22d66fe7959145c0629e7367c1b951ce7ac198c2496a69c84
|
||||
0 0xa1784d0efa4a3075f07968e3c0969e064b986336a9c80a95cfbe4e314b13ddec 0x456bcd8e76c21c691658ed4c28158173c1f69b35178c2ed8c2a602b76cdfbede 0x983873529f95132bd1812a3b52c98fb271d2f679 0xac1c41d319b7e8f7aecd0d6130e8c94b9f748333bbfa03036aa69ba4376dfad5
|
||||
0 0x6526f92963f2338eb771ad90fb772d11904d4d4befa98b8c272c6a0abfab081e 0x5aec457455ba8d5aeadf17a688ca73754680ea1f6265c34ddf6718c85ff1e1b0 0x19e34d09c2664d4f0829b1431ea73dac1b2bea93 0xc61a5fc29b169a36e990142a63b49823dd06fabbbbf54a4f52dd25ff443ed640
|
||||
0 0xa026fb5c2ea92a4bced092ece32b06ad2664eca004ba355bfc9686b442131862 0x4dd3e552d74fb306c7e1a8f1c6c4f041d8bbe50fff482389e7959ebd90d67259 0xe697fa7a3f3165caae7458a7e7437fcf80a327b2 0xbc1705ec12a7475ace7e60c33bfa6a64fff88c538675d302ce603dd572f2f14d
|
||||
1 0xf2a1cf25ff00c08820ff9030f63ad96aa1e6d2f89ba9a270953610a7f5e9ac27 0x14c87ef1845068dc7d81686b4bf201676d48fe2359a05785c40bb674873673ab 0x6faea455ea5309259cdfb076caaf779488ddf8de 0xc7f21e2ddb3c14b1b29e355050dab2eddb82e1e8306ed184e277193a53256043
|
||||
0 0x9f97613b227a9f5c66d7c4c44897aef59bf482c72434dac864b48089906f4372 0xb35e44f4d594816de88c2e9c48662134b69892690ae7c844dfa35c73e6bb7a4 0xd6f440196f5060e81a943fa5110508c8430b31f2 0x8d6ad1adfadd98aaf2365632ff00dd9bd479b687f3ff43d16de4e0ce67c90bf2
|
||||
1 0xb34b1d4a28568a653ac8c1695dbb0f8da387fec9700985879beb2a0871eac428 0x7aa14d38f04dfd090c3d688f4847d0f55c2a8785719c63ca12702c3b2c755ed8 0xa6a688f107851131f0e1dce493ebbebfaf99203e 0x874c23e08d44be9a421c4c1131448c5877015d9ba1b76dbd94dabd6809ae0bdb
|
||||
0 0xc513f6281e4c95bca3e17a3ff8eaef844b09b17f7d7fd24a2637e81136aecd1d 0x75810f150e589d54765f58a44263fc7b26cc791bb88e771777aead7823327431 0xf61a659713d29221646b451d2c675f657e33c88c 0x1cf1502b1f131cf5eb85243f25aac443dbb2c8727c9e4d718ca614012da4f14d
|
||||
1 0xacb42d7d82bf160d188dda513982a48c9eb055c84a700bbe425b96ad5e1244e7 0x47cdb51f4a5b8fba9f4cdbd5b4ebcf42438fcd9f2ac996cefca27745140802c6 0x710bda329b2a6224e4b44833de30f38e7f81d564 0xdd0aa6a391179f21e01e5670e46b6664d1e23869a25b68e94bfc203148c8363c
|
||||
0 0x10077281c6b1283c4f8f7b3058aff92c72e5694d9cc53f1767d8977a50c4408c 0x3a02b1f7a35f12e0233f307489037fa3dbcb0aac33f23291a659068a0c15295d 0x22a98f59ded87c4143cf26323b0bd779580ead02 0xbd137a0fc25ca845d0863454dfbf05a78d8f364d821d569f27fc85dd7aaf6ff1
|
||||
1 0x58c87c54c33e54e868d9f6eaab464787256e5d46db9f7fa550ff6daa3f0d25e0 0x7b716d06c4163062b503e32650faaca47ee01f3ec269d62cbd9c9d6cd37f0968 0x9b2c4b8c833278b71789999a3d808b1bc0995fcb 0xfdc089847347bca14dd6a782cc102755a398f711f213d9b50548f1e33a66793f
|
||||
0 0x6c3f7f4cc50cb15e4d5b1454088e860fcf3484bea53979597056238bee8d2eca 0x354f75da6626ded0a649d6749a6e6f570a353504e4cf86878397771993397cc3 0x55fe002aeff02f77364de339a1292923a15844b8 0x9d1e9fda1dbec9bb273fdc32b4b3f93a478861d0e4a4f44f059efaccc4ca3aa2
|
||||
1 0xcbe9c14778b0b3204ba7a286bda1efd94eb79f00141fe807168954aaf2bc8887 0x7ddc9f6c4d6be095ad846a2d1e12196fbd31f144bbbdb672c7471e8a0c64ce3a 0x299c7265388216f6baf12c04bfaae0391c2b1be5 0x6a247771ba60f3e5b1ff3a95ca6ce256a75a7c8b4c2cc74fa02541458730bf39
|
||||
1 0xae6d5ee5e33792e97504b10f2a11e5e0945fe6e540ba0cb530ab49a3b0a6aed7 0xcf7f67a2f5a6a8297b80ad4214879ed6b8b6b0d5003afa6676bc62010aa152e 0x6dfc34609a05bc22319fa4cce1d1e2929548c0d7 0x33460c004ebe3b3c87b07a5228f1a6b163eb970181ad59ff11f8d03b729298e0
|
||||
1 0x77853702c849e381674e839ff6779d66ded67a7cfc325cec9dd8b93d577f1d5 0x7809c39b7692e2fa010a78ba9d521155cb6151b316daf15098684dcd3973cc72 0x4069d8a3de3a72eca86ca5e0a4b94619085e7362 0xb5e51e980067f75f75981e80b4b2d60da80dedf8fbcbadce9ae871ea02ea3c89
|
||||
1 0x7f8c8449f22a576d8868bf3e8bbe14dad8de838b4e45ff320fe4fc794051fe59 0x1ba41d48005b10b79602ee801ede56845ea5b700aef13dc2dfe93812672ef053 0x6887246668a3b87f54deb3b94ba47a6f63f32985 0xaad2bb9310cf9aea16caa84141dfcd3de424b7cbeba41d20a319b3c35342c2b1
|
||||
1048
evm/src/cpu/kernel/tests/ecc/glv_test_data
Normal file
1048
evm/src/cpu/kernel/tests/ecc/glv_test_data
Normal file
File diff suppressed because it is too large
Load Diff
2
evm/src/cpu/kernel/tests/ecc/mod.rs
Normal file
2
evm/src/cpu/kernel/tests/ecc/mod.rs
Normal file
@ -0,0 +1,2 @@
|
||||
mod curve_ops;
|
||||
mod ecrecover;
|
||||
@ -1,8 +1,7 @@
|
||||
mod account_code;
|
||||
mod balance;
|
||||
mod core;
|
||||
mod curve_ops;
|
||||
mod ecrecover;
|
||||
mod ecc;
|
||||
mod exp;
|
||||
mod fields;
|
||||
mod hash;
|
||||
|
||||
@ -39,10 +39,11 @@ pub(crate) enum Segment {
|
||||
/// instructions; initialised by `kernel/asm/shift.asm::init_shift_table()`.
|
||||
ShiftTable = 16,
|
||||
JumpdestBits = 17,
|
||||
EcdsaTable = 18,
|
||||
}
|
||||
|
||||
impl Segment {
|
||||
pub(crate) const COUNT: usize = 18;
|
||||
pub(crate) const COUNT: usize = 19;
|
||||
|
||||
pub(crate) fn all() -> [Self; Self::COUNT] {
|
||||
[
|
||||
@ -64,6 +65,7 @@ impl Segment {
|
||||
Self::TrieEncodedChildLen,
|
||||
Self::ShiftTable,
|
||||
Self::JumpdestBits,
|
||||
Self::EcdsaTable,
|
||||
]
|
||||
}
|
||||
|
||||
@ -88,6 +90,7 @@ impl Segment {
|
||||
Segment::TrieEncodedChildLen => "SEGMENT_TRIE_ENCODED_CHILD_LEN",
|
||||
Segment::ShiftTable => "SEGMENT_SHIFT_TABLE",
|
||||
Segment::JumpdestBits => "SEGMENT_JUMPDEST_BITS",
|
||||
Segment::EcdsaTable => "SEGMENT_KERNEL_ECDSA_TABLE",
|
||||
}
|
||||
}
|
||||
|
||||
@ -112,6 +115,7 @@ impl Segment {
|
||||
Segment::TrieEncodedChildLen => 6,
|
||||
Segment::ShiftTable => 256,
|
||||
Segment::JumpdestBits => 1,
|
||||
Segment::EcdsaTable => 256,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user