diff --git a/evm/src/cpu/kernel/asm/helper_functions.asm b/evm/src/cpu/kernel/asm/helper_functions.asm index 8acbbe3f..c628916c 100644 --- a/evm/src/cpu/kernel/asm/helper_functions.asm +++ b/evm/src/cpu/kernel/asm/helper_functions.asm @@ -41,48 +41,63 @@ case1: case2: JUMPDEST swap2 + %jump(swapn_end) case3: JUMPDEST swap3 + %jump(swapn_end) case4: JUMPDEST swap4 + %jump(swapn_end) case5: JUMPDEST swap5 + %jump(swapn_end) case6: JUMPDEST swap6 + %jump(swapn_end) case7: JUMPDEST swap7 + %jump(swapn_end) case8: JUMPDEST swap8 + %jump(swapn_end) case9: JUMPDEST swap9 + %jump(swapn_end) case10: JUMPDEST swap10 + %jump(swapn_end) case11: JUMPDEST swap11 + %jump(swapn_end) case12: JUMPDEST swap12 + %jump(swapn_end) case13: JUMPDEST swap13 + %jump(swapn_end) case14: JUMPDEST swap14 + %jump(swapn_end) case15: JUMPDEST swap15 + %jump(swapn_end) case16: JUMPDEST swap16 + %jump(swapn_end) swapn_end: JUMPDEST diff --git a/evm/src/cpu/kernel/asm/sha2.asm b/evm/src/cpu/kernel/asm/sha2.asm index f33247dd..9f54e1bf 100644 --- a/evm/src/cpu/kernel/asm/sha2.asm +++ b/evm/src/cpu/kernel/asm/sha2.asm @@ -19,441 +19,90 @@ count_bits_loop: pop // stack: bits -// Appends a 1 to the end of the u256 at the top of the stack. -global append_1: - dup - count_bits - %eq(256) - %jumpi(append_if256) - %jump(append_else) -append_if256: - push 1 - swap1 - %jump(append_end) -append_else: - push 2 - mul - push 1 - add -append_end: - - -global sha2_append_1: +global sha2_store: // stack: num_u256s, x[0], x[1], x[2], ... , x[num_u256s-1] - // (assume num_u256s <= 16) - dup + dup1 // stack: num_u256s, num_u256s, x[0], x[1], x[2], ... , x[num_u256s-1] - dup - // stack: num_u256s, num_u256s, num_u256s, x[0], x[1], x[2], ... , x[num_u256s-1] - %increment - // stack: num_u256s+1, num_u256s, x[0], x[1], x[2], ... , x[num_u256s-1] - swapn - // stack: x[num_u256s-1], num_u256s, x[0], x[1], x[2], ... , x[num_u256s-2], num_u256s - dup - // stack: x[num_u256s-1], x[num_u256s-1], num_u256s, x[0], x[1], x[2], ... , x[num_u256s-2], num_u256s - %count_bits - // stack: num_bits, x[num_u256s-1], num_u256s, x[0], x[1], x[2], ... , x[num_u256s-2], num_u256s - %eq(256) - %jumpi(append_if256) - %jump(append_else) -append_if256: + // TODO: use kernel memory, and start address not at 0 + push 0 + // stack: addr=0, num_u256s, num_u256s, x[0], x[1], x[2], ... , x[num_u256s-1] + mstore + // stack: num_u256s, x[0], x[1], x[2], ... , x[num_u256s-1] push 1 - // stack: 1, x[num_u256s-1], num_u256s, x[0], x[1], x[2], ... , x[num_u256s-2], num_u256s - dup2 - // stack: num_u256s, 1, x[num_u256s-1], num_u256s, x[0], x[1], x[2], ... , x[num_u256s-2], num_u256s - push 3 - add - // stack: num_u256s+3, 1, x[num_u256s-1], num_u256s, x[0], x[1], x[2], ... , x[num_u256s-2], num_u256s, [] - swapn - // stack: [], x[num_u256s-1], num_u256s, x[0], x[1], x[2], ... , x[num_u256s-2], num_u256s, - %jump(append_continue) -append_else: -append_continue: - - dup + // stack: addr=1, counter=num_u256s, x[0], x[1], x[2], ... , x[num_u256s-1] +sha2_store_loop: + JUMPDEST + // stack: addr, counter, x[num_u256s-counter], ... , x[num_u256s-1] + dup1 + // stack: addr, addr, counter, x[num_u256s-counter], ... , x[num_u256s-1] + swap3 + // stack: x[num_u256s-counter], addr, counter, addr, ... , x[num_u256s-1] + swap1 + // stack: addr, x[num_u256s-counter], counter, addr, ... , x[num_u256s-1] + mstore + // stack: counter, addr, ... , x[num_u256s-1] + %decrement + // stack: counter-1, addr, ... , x[num_u256s-1] + iszero + %jumpi(sha2_store_end) + swap1 + // stack: addr, counter-1, ... , x[num_u256s-1] + %increment + // stack: addr+1, counter-1, ... , x[num_u256s-1] + %jump(sha2_store_loop) +sha2_store_end: + JUMPDEST global sha2_pad: - // stack: num_u256s, x[0], x[1], x[2], ... , x[num_u256s-1] - %jumpi() - - - append 1: - if length of last = 256 - increment length; add new value of 10000000..0 - - stick 1 on the end (last one:) - - if length even: - pad last one to - - if length odd: - - - // stack: num_blocks, block[0][0], block[0][1], ..., block[num_blocks-1][3] - - -// #define K0 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 - - -// BN254 elliptic curve addition. -// Uses the standard affine addition formula. -global ec_add: - // Uncomment for test inputs. - // PUSH 0xdeadbeef - // PUSH 2 - // PUSH 1 - // PUSH 0x1bf9384aa3f0b3ad763aee81940cacdde1af71617c06f46e11510f14f3d5d121 - // PUSH 0xe7313274bb29566ff0c8220eb9841de1d96c2923c6a4028f7dd3c6a14cee770 + // TODO: use kernel memory, and start address not at 0 + push 0 + mload + // stack: num_u256s + mload + // stack: x[num_u256s-1] + dup1 + // stack: x[num_u256s-1], x[num_u256s-1] + %count_bits + // stack: num_bits, x[num_u256s-1] + %eq(256) + %jumpi(pad_if256) + %jump(pad_else) +pad_if256: JUMPDEST - // stack: x0, y0, x1, y1, retdest - - // Check if points are valid BN254 points. - DUP2 - // stack: y0, x0, y0, x1, y1, retdest - DUP2 - // stack: x0, y0, x0, y0, x1, y1, retdest - %ec_check - // stack: isValid(x0, y0), x0, y0, x1, y1, retdest - DUP5 - // stack: x1, isValid(x0, y0), x0, y0, x1, y1, retdest - DUP5 - // stack: x1, y1, isValid(x0, y0), x0, y0, x1, y1, retdest - %ec_check - // stack: isValid(x1, y1), isValid(x0, y0), x0, y0, x1, y1, retdest - AND - // stack: isValid(x1, y1) & isValid(x0, y0), x0, y0, x1, y1, retdest - %jumpi(ec_add_valid_points) - // stack: x0, y0, x1, y1, retdest - - // Otherwise return - %pop4 - // stack: retdest - %ec_invalid_input - -// BN254 elliptic curve addition. -// Assumption: (x0,y0) and (x1,y1) are valid points. -global ec_add_valid_points: - JUMPDEST - // stack: x0, y0, x1, y1, retdest - - // Check if the first point is the identity. - DUP2 - // stack: y0, x0, y0, x1, y1, retdest - DUP2 - // stack: x0, y0, x0, y0, x1, y1, retdest - %ec_isidentity - // stack: (x0,y0)==(0,0), x0, y0, x1, y1, retdest - %jumpi(ec_add_first_zero) - // stack: x0, y0, x1, y1, retdest - - // Check if the first point is the identity. - DUP4 - // stack: y1, x0, y0, x1, y1, retdest - DUP4 - // stack: x1, y1, x0, y0, x1, y1, retdest - %ec_isidentity - // stack: (x1,y1)==(0,0), x0, y0, x1, y1, retdest - %jumpi(ec_add_snd_zero) - // stack: x0, y0, x1, y1, retdest - - // Check if both points have the same x-coordinate. - DUP3 - // stack: x1, x0, y0, x1, y1, retdest - DUP2 - // stack: x0, x1, x0, y0, x1, y1, retdest - EQ - // stack: x0 == x1, x0, y0, x1, y1, retdest - %jumpi(ec_add_equal_first_coord) - // 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 - DUP3 - // stack: y0, y1, x0, y0, x1, y1, retdest - %submod - // stack: y0 - y1, x0, y0, x1, y1, retdest - DUP4 - // stack: x1, y0 - y1, x0, y0, x1, y1, retdest - DUP3 - // stack: x0, x1, y0 - y1, x0, y0, x1, y1, retdest - %submod - // stack: x0 - x1, y0 - y1, x0, y0, x1, y1, retdest - %moddiv - // stack: lambda, x0, y0, x1, y1, retdest - %jump(ec_add_valid_points_with_lambda) - -// BN254 elliptic curve addition. -// Assumption: (x0,y0) == (0,0) -ec_add_first_zero: - JUMPDEST - // stack: x0, y0, x1, y1, retdest - - // Just return (x1,y1) + // stack: num_bits, x[num_u256s-1] %pop2 - // stack: x1, y1, retdest - SWAP1 - // stack: y1, x1, retdest - SWAP2 - // stack: retdest, x1, y1 - JUMP - -// BN254 elliptic curve addition. -// Assumption: (x1,y1) == (0,0) -ec_add_snd_zero: + push 0 + mload + // stack: num_u256s + %increment + // stack: num_u256s+1 + dup1 + // stack: num_u256s+1, num_u256s+1 + push 0 + mstore + // stack: num_u256s+1 + push 1 + // stack: 1, num_u256s+1 + swap1 + // stack: num_u256s+1, 1 + mstore + %jump(pad_end) +pad_else: JUMPDEST - // stack: x0, y0, x1, y1, retdest - - // Just return (x1,y1) - SWAP2 - // stack: x1, y0, x0, y1, retdest - POP - // stack: y0, x0, y1, retdest - SWAP2 - // stack: y1, x0, y0, retdest - POP - // stack: x0, y0, retdest - SWAP1 - // stack: y0, x0, retdest - SWAP2 - // stack: retdest, x0, y0 - JUMP - -// BN254 elliptic curve addition. -// Assumption: lambda = (y0 - y1)/(x0 - x1) -ec_add_valid_points_with_lambda: + // stack: num_bits, x[num_u256s-1] + pop + // stack: x[num_u256s-1] + push 2 + mul + // stack: 2*x[num_u256s-1] + %increment + // stack: 2*x[num_u256s-1]+1 + push 0 + mload + // stack: num_u256s, 2*x[num_u256s-1]+1 + mstore +pad_end: JUMPDEST - // stack: lambda, x0, y0, x1, y1, retdest - - // Compute x2 = lambda^2 - x1 - x0 - DUP2 - // stack: x0, lambda, x0, y0, x1, y1, retdest - DUP5 - // stack: x1, x0, lambda, x0, y0, x1, y1, retdest - %bn_base - // stack: N, x1, x0, lambda, x0, y0, x1, y1, retdest - DUP4 - // stack: lambda, N, x1, x0, lambda, x0, y0, x1, y1, retdest - DUP1 - // stack: lambda, lambda, N, x1, x0, lambda, x0, y0, x1, y1, retdest - MULMOD - // stack: lambda^2, x1, x0, lambda, x0, y0, x1, y1, retdest - %submod - // stack: lambda^2 - x1, x0, lambda, x0, y0, x1, y1, retdest - %submod - // stack: x2, lambda, x0, y0, x1, y1, retdest - - // Compute y2 = lambda*(x1 - x2) - y1 - %bn_base - // stack: N, x2, lambda, x0, y0, x1, y1, retdest - DUP2 - // stack: x2, N, x2, lambda, x0, y0, x1, y1, retdest - DUP7 - // stack: x1, x2, N, x2, lambda, x0, y0, x1, y1, retdest - %submod - // stack: x1 - x2, N, x2, lambda, x0, y0, x1, y1, retdest - DUP4 - // stack: lambda, x1 - x2, N, x2, lambda, x0, y0, x1, y1, retdest - MULMOD - // stack: lambda * (x1 - x2), x2, lambda, x0, y0, x1, y1, retdest - DUP7 - // stack: y1, lambda * (x1 - x2), x2, lambda, x0, y0, x1, y1, retdest - SWAP1 - // stack: lambda * (x1 - x2), y1, x2, lambda, x0, y0, x1, y1, retdest - %submod - // stack: y2, x2, lambda, x0, y0, x1, y1, retdest - - // Return x2,y2 - SWAP5 - // stack: x1, x2, lambda, x0, y0, y2, y1, retdest - POP - // stack: x2, lambda, x0, y0, y2, y1, retdest - SWAP5 - // stack: y1, lambda, x0, y0, y2, x2, retdest - %pop4 - // stack: y2, x2, retdest - SWAP2 - // stack: retdest, x2, y2 - JUMP - -// BN254 elliptic curve addition. -// Assumption: (x0,y0) and (x1,y1) are valid points and x0 == x1 -ec_add_equal_first_coord: - JUMPDEST - // stack: x0, y0, x1, y1, retdest with x0 == x1 - - // Check if the points are equal - DUP2 - // stack: y0, x0, y0, x1, y1, retdest - DUP5 - // stack: y1, y0, x0, y0, x1, y1, retdest - EQ - // stack: y1 == y0, x0, y0, x1, y1, retdest - %jumpi(ec_add_equal_points) - // stack: x0, y0, x1, y1, retdest - - // Otherwise, one is the negation of the other so we can return (0,0). - %pop4 - // stack: retdest - PUSH 0 - // stack: 0, retdest - PUSH 0 - // stack: 0, 0, retdest - SWAP2 - // stack: retdest, 0, 0 - JUMP - - -// BN254 elliptic curve addition. -// Assumption: x0 == x1 and y0 == y1 -// Standard doubling formula. -ec_add_equal_points: - JUMPDEST - // stack: x0, y0, x1, y1, retdest - - // Compute lambda = 3/2 * x0^2 / y0 - %bn_base - // stack: N, x0, y0, x1, y1, retdest - %bn_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 - MULMOD - // stack: x0^2, N, x0, y0, x1, y1, retdest with - PUSH 0x183227397098d014dc2822db40c0ac2ecbc0b548b438e5469e10460b6c3e7ea5 // 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 - // stack: lambda, x0, y0, x1, y1, retdest - %jump(ec_add_valid_points_with_lambda) - -// BN254 elliptic curve doubling. -// Assumption: (x0,y0) is a valid point. -// Standard doubling formula. -global ec_double: - JUMPDEST - // stack: x0, y0, retdest - DUP2 - // stack: y0, x0, y0, retdest - DUP2 - // stack: x0, y0, x0, y0, retdest - %jump(ec_add_equal_points) - -// Push the order of the BN254 base field. -%macro bn_base - PUSH 0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47 -%endmacro - -// Assumption: x, y < N and 2N < 2^256. -// Note: Doesn't hold for Secp256k1 base field. -%macro submod - // stack: x, y - %bn_base - // stack: N, x, y - ADD - // stack: N + x, y // Doesn't overflow since 2N < 2^256 - SUB - // stack: N + x - y // Doesn't underflow since y < N - %bn_base - // stack: N, N + x - y - SWAP1 - // stack: N + x - y, N - MOD - // stack: (N + x - y) % N = (x-y) % N -%endmacro - -// Check if (x,y) is a valid curve point. -// Puts y^2 % N == (x^3 + 3) % N & (x < N) & (y < N) || (x,y)==(0,0) on top of the stack. -%macro ec_check - // stack: x, y - %bn_base - // stack: N, x, y - DUP2 - // stack: x, N, x, y - LT - // stack: x < N, x, y - %bn_base - // stack: N, x < N, x, y - DUP4 - // stack: y, N, x < N, x, y - LT - // stack: y < N, x < N, x, y - AND - // stack: (y < N) & (x < N), x, y - SWAP2 - // stack: y, x, (y < N) & (x < N), x - SWAP1 - // stack: x, y, (y < N) & (x < N) - %bn_base - // stack: N, x, y, b - %bn_base - // stack: N, N, x, y, b - DUP3 - // stack: x, N, N, x, y, b - %bn_base - // stack: N, x, N, N, x, y, b - DUP2 - // stack: x, N, x, N, N, x, y, b - DUP1 - // stack: x, x, N, x, N, N, x, y, b - MULMOD - // stack: x^2 % N, x, N, N, x, y, b - MULMOD - // stack: x^3 % N, N, x, y, b - PUSH 3 - // stack: 3, x^3 % N, N, x, y, b - ADDMOD - // stack: (x^3 + 3) % N, x, y, b - DUP3 - // stack: y, (x^3 + 3) % N, x, y, b - %bn_base - // stack: N, y, (x^3 + 3) % N, x, y, b - SWAP1 - // stack: y, N, (x^3 + 3) % N, x, y, b - DUP1 - // stack: y, y, N, (x^3 + 3) % N, x, y, b - MULMOD - // stack: y^2 % N, (x^3 + 3) % N, x, y, b - EQ - // stack: y^2 % N == (x^3 + 3) % N, x, y, b - SWAP2 - // stack: y, x, y^2 % N == (x^3 + 3) % N, b - %ec_isidentity - // stack: (x,y)==(0,0), y^2 % N == (x^3 + 3) % N, b - SWAP2 - // stack: b, y^2 % N == (x^3 + 3) % N, (x,y)==(0,0) - AND - // stack: y^2 % N == (x^3 + 3) % N & (x < N) & (y < N), (x,y)==(0,0) - OR - // stack: y^2 % N == (x^3 + 3) % N & (x < N) & (y < N) || (x,y)==(0,0) -%endmacro - -// Check if (x,y)==(0,0) -%macro ec_isidentity - // stack: x, y - OR - // stack: x | y - ISZERO - // stack: (x,y) == (0,0) -%endmacro - -// Return (u256::MAX, u256::MAX) which is used to indicate the input was invalid. -%macro ec_invalid_input - // stack: retdest - PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - // stack: u256::MAX, retdest - PUSH 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff - // stack: u256::MAX, u256::MAX, retdest - SWAP2 - // stack: retdest, u256::MAX, u256::MAX - JUMP -%endmacro \ No newline at end of file