From 84c1954daf49008e6ccc9f6308c310b1fbddcc72 Mon Sep 17 00:00:00 2001 From: Dmitry Vagner Date: Fri, 18 Nov 2022 16:48:11 -0800 Subject: [PATCH] tate --- .../bn254/curve_arithmetic/tate_pairing.asm | 80 ++++++++++++++++--- .../curve/bn254/field_arithmetic/fp12_mul.asm | 31 ++++--- evm/src/cpu/kernel/tests/fields.rs | 2 +- 3 files changed, 82 insertions(+), 31 deletions(-) diff --git a/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/tate_pairing.asm b/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/tate_pairing.asm index 98167675..a109796c 100644 --- a/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/tate_pairing.asm +++ b/evm/src/cpu/kernel/asm/curve/bn254/curve_arithmetic/tate_pairing.asm @@ -1,30 +1,80 @@ /// def tate(P : [Fp; 2], Q: [Fp2; 2]) -> Fp12: -/// out = miller_loop(P) +/// out = miller_loop(P, Q) /// /// inv = inverse_fp12(out) /// out = frob_fp12_6(out) /// out = mul_fp12(out, inv) /// -/// acx = frob_fp12_2(out) -/// out = mul_fp12(acx, out) +/// acc = frob_fp12_2(out) +/// out = mul_fp12(out, acc) /// /// pow = fast_exp(out) -/// out = frob_fp12_3(out) -/// return mul_fp12(out, pow) +/// out = frob_fp12_3(out) +/// out = mul_fp12(out, pow) +/// +/// return out global tate: - // stack: ptr, out - PUSH 1 - // stack: 1, ptr, out + // stack: ptr, out, retdest + PUSH tate_mul3 SWAP2 + // stack: out, ptr, tate_mul3, retdest + PUSH tate_mul2 SWAP2 + // stack: ptr, out, tate_mul2, tate_mul3, retdest + PUSH tate_mul1 SWAP2 + // stack: out, ptr, tate_mul1, tate_mul2, tate_mul3, retdest + PUSH post_mllr SWAP2 + // stack: ptr, out, post_mllr, tate_mul1, tate_mul2, tate_mul3, retdest + %jump(miller_loop) +post_mllr: + // stack: out, tate_mul1, tate_mul2, tate_mul3, retdest + PUSH 100 + // stack: 100, out, tate_mul1, tate_mul2, tate_mul3, retdest + DUP2 + // stack: out, 100, out, tate_mul1, tate_mul2, tate_mul3, retdest + %inverse_fp12 + // stack: 100, out, tate_mul1, tate_mul2, tate_mul3, retdest {100: inv} + PUSH mul_fp12 + // stack: mul_fp12, 100, out, tate_mul1, tate_mul2, tate_mul3, retdest {100: inv} + DUP3 + // stack: out, mul_fp12, 100, out, tate_mul1, tate_mul2, tate_mul3, retdest {100: inv} + %jump(frob_fp12_6) +tate_mul1: + // stack: out, tate_mul2, tate_mul3, retdest {100: inv} + DUP1 + // stack: out, out, tate_mul2, tate_mul3, retdest {100: inv} + PUSH mul_fp12 + // stack: mul_fp12, out, out, tate_mul2, tate_mul3, retdest {100: inv} PUSH 100 - // stack: 100, 1, ptr, out - %mstore_kernel_general + // stack: 100, mul_fp12, out, out, tate_mul2, tate_mul3, retdest {100: inv} + DUP3 + // stack: out, 100, mul_fp12, out, out, tate_mul2, tate_mul3, retdest {100: inv} + %jump(frob_fp12_2) +tate_mul2: + // stack: out, tate_mul3, retdest {100: acc} + PUSH post_pow + // stack: post_pow, out, tate_mul3, retdest {100: acc} + PUSH 100 + // stack: 100, post_pow, out, tate_mul3, retdest {100: acc} + DUP1 + // stack: out, 100, post_pow, out, tate_mul3, retdest {100: acc} + %jump(power) +post_pow: + // stack: 100, out, tate_mul3, retdest {100: pow} + PUSH mul_fp12 + // stack: mul_fp12, 100, out, tate_mul3, retdest {100: pow} + DUP3 + // stack: out, mul_fp12, 100, out, tate_mul3, retdest {100: pow} + %jump(frob_fp12_3) +tate_mul3: + // stack: out, retdest {100: pow} + SWAP1 + JUMP -/// def miller_loop(P): +/// def miller_loop(P, Q): /// out = 1 /// O = P -/// for i in EXP[1:-1]: +/// for i in EXP: /// out = square_fp12(out) /// line = tangent(O, Q) /// out = mul_fp12_sparse(out, line) @@ -36,6 +86,10 @@ global tate: /// out = square_fp12(out) /// line = tangent(O, Q) /// return mul_fp12_sparse(out, line) +/// +/// EXP is the binary expansion of the BN254 prime +global miller_loop: + // stack: ptr, out, retdest - + // stack: out diff --git a/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/fp12_mul.asm b/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/fp12_mul.asm index b90f93d9..53e13153 100644 --- a/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/fp12_mul.asm +++ b/evm/src/cpu/kernel/asm/curve/bn254/field_arithmetic/fp12_mul.asm @@ -2,27 +2,27 @@ /// cost: 220 global test_mul_fp12: - // stack: f, inA , f', g, inB , g', inB, out, inA, out + // stack: f, inA , f', g, inB , g', inB, out, inA DUP7 - // stack: inA, f, inA , f', g, inB , g', inB, out, inA, out + // stack: inA, f, inA , f', g, inB , g', inB, out, inA %store_fp6 - // stack: inA , f', g, inB , g', inB, out, inA, out + // stack: inA , f', g, inB , g', inB, out, inA %offset_fp6 - // stack: inA', f', g, inB , g', inB, out, inA, out + // stack: inA', f', g, inB , g', inB, out, inA %store_fp6 - // stack: g, inB , g', inB, out, inA, out + // stack: g, inB , g', inB, out, inA DUP7 - // stack: inB, g, inB , g', inB, out, inA, out + // stack: inB, g, inB , g', inB, out, inA %store_fp6 - // stack: inB , g', inB, out, inA, out + // stack: inB , g', inB, out, inA %offset_fp6 - // stack: inB', g', inB, out, inA, out + // stack: inB', g', inB, out, inA %store_fp6 - // stack: inB, out, inA, out + // stack: inB, out, inA PUSH ret_stack - // stack: ret_stack, inB, out, inA, out + // stack: ret_stack, inB, out, inA SWAP3 - // stack: inA, inB, out, ret_stack, out + // stack: inA, inB, out, ret_stack %jump(square_fp12_test) ret_stack: // stack: out @@ -173,8 +173,7 @@ ret_3: // stack: out, sh(f'g') + fg, inB, out {0: sh(f'g'), 6: f'g', 12: fg} %store_fp6 // stack: inB, out {0: sh(f'g'), 6: f'g', 12: fg} - %pop2 - JUMP + POP SWAP1 JUMP ////////////////////////////////////// @@ -304,8 +303,7 @@ global mul_fp12_sparse: // stack: out', G1 * sh(f') + G2 * sh(f) + g0 * f', inA, inB, out %store_fp6 // stack: inA, inB, out - %pop3 - JUMP + %pop2 SWAP1 JUMP /// global mul_fp12_sparse_fast: /// // stack: inA, inB, out @@ -449,5 +447,4 @@ post_sq2: // stack: out, ff + sh(f'f'), inp, out %store_fp6 // stack: inp, out - %pop2 - JUMP + POP SWAP1 JUMP diff --git a/evm/src/cpu/kernel/tests/fields.rs b/evm/src/cpu/kernel/tests/fields.rs index 1eb61c16..8528f6c7 100644 --- a/evm/src/cpu/kernel/tests/fields.rs +++ b/evm/src/cpu/kernel/tests/fields.rs @@ -188,7 +188,7 @@ fn make_initial_stack( input.extend(g0); input.extend(vec![in2]); input.extend(g1); - input.extend(vec![in2, out, in1, out]); + input.extend(vec![in2, out, in1]); as_stack(input) }